aboutsummaryrefslogtreecommitdiff
path: root/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTypeEncodingParser.cpp
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2017-01-02 19:26:05 +0000
committerDimitry Andric <dim@FreeBSD.org>2017-01-02 19:26:05 +0000
commit14f1b3e8826ce43b978db93a62d1166055db5394 (patch)
tree0a00ad8d3498783fe0193f3b656bca17c4c8697d /source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTypeEncodingParser.cpp
parent4ee8c119c71a06dcad1e0fecc8c675e480e59337 (diff)
downloadsrc-14f1b3e8826ce43b978db93a62d1166055db5394.tar.gz
src-14f1b3e8826ce43b978db93a62d1166055db5394.zip
Vendor import of lldb trunk r290819:vendor/lldb/lldb-trunk-r290819
Notes
Notes: svn path=/vendor/lldb/dist/; revision=311128 svn path=/vendor/lldb/lldb-trunk-r290819/; revision=311129; tag=vendor/lldb/lldb-trunk-r290819
Diffstat (limited to 'source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTypeEncodingParser.cpp')
-rw-r--r--source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTypeEncodingParser.cpp659
1 files changed, 328 insertions, 331 deletions
diff --git a/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTypeEncodingParser.cpp b/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTypeEncodingParser.cpp
index d4adc094bc1b..316115b0dcb1 100644
--- a/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTypeEncodingParser.cpp
+++ b/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTypeEncodingParser.cpp
@@ -21,379 +21,376 @@
using namespace lldb_private;
using namespace lldb_utility;
-AppleObjCTypeEncodingParser::AppleObjCTypeEncodingParser (ObjCLanguageRuntime& runtime) :
- ObjCLanguageRuntime::EncodingToType(),
- m_runtime(runtime)
-{
- if (!m_scratch_ast_ctx_ap)
- m_scratch_ast_ctx_ap.reset(new ClangASTContext(runtime.GetProcess()->GetTarget().GetArchitecture().GetTriple().str().c_str()));
+AppleObjCTypeEncodingParser::AppleObjCTypeEncodingParser(
+ ObjCLanguageRuntime &runtime)
+ : ObjCLanguageRuntime::EncodingToType(), m_runtime(runtime) {
+ if (!m_scratch_ast_ctx_ap)
+ m_scratch_ast_ctx_ap.reset(new ClangASTContext(runtime.GetProcess()
+ ->GetTarget()
+ .GetArchitecture()
+ .GetTriple()
+ .str()
+ .c_str()));
}
std::string
-AppleObjCTypeEncodingParser::ReadStructName(lldb_utility::StringLexer& type)
-{
- StreamString buffer;
- while (type.HasAtLeast(1) && type.Peek() != '=')
- buffer.Printf("%c",type.Next());
- return buffer.GetString();
+AppleObjCTypeEncodingParser::ReadStructName(lldb_utility::StringLexer &type) {
+ StreamString buffer;
+ while (type.HasAtLeast(1) && type.Peek() != '=')
+ buffer.Printf("%c", type.Next());
+ return buffer.GetString();
}
std::string
-AppleObjCTypeEncodingParser::ReadQuotedString(lldb_utility::StringLexer& type)
-{
- StreamString buffer;
- while (type.HasAtLeast(1) && type.Peek() != '"')
- buffer.Printf("%c",type.Next());
- StringLexer::Character next = type.Next();
- UNUSED_IF_ASSERT_DISABLED(next);
- assert (next == '"');
- return buffer.GetString();
+AppleObjCTypeEncodingParser::ReadQuotedString(lldb_utility::StringLexer &type) {
+ StreamString buffer;
+ while (type.HasAtLeast(1) && type.Peek() != '"')
+ buffer.Printf("%c", type.Next());
+ StringLexer::Character next = type.Next();
+ UNUSED_IF_ASSERT_DISABLED(next);
+ assert(next == '"');
+ return buffer.GetString();
}
uint32_t
-AppleObjCTypeEncodingParser::ReadNumber (lldb_utility::StringLexer& type)
-{
- uint32_t total = 0;
- while (type.HasAtLeast(1) && isdigit(type.Peek()))
- total = 10*total + (type.Next() - '0');
- return total;
+AppleObjCTypeEncodingParser::ReadNumber(lldb_utility::StringLexer &type) {
+ uint32_t total = 0;
+ while (type.HasAtLeast(1) && isdigit(type.Peek()))
+ total = 10 * total + (type.Next() - '0');
+ return total;
}
-// as an extension to the published grammar recent runtimes emit structs like this:
+// as an extension to the published grammar recent runtimes emit structs like
+// this:
// "{CGRect=\"origin\"{CGPoint=\"x\"d\"y\"d}\"size\"{CGSize=\"width\"d\"height\"d}}"
-AppleObjCTypeEncodingParser::StructElement::StructElement() :
-name(""),
-type(clang::QualType()),
-bitfield(0)
-{}
+AppleObjCTypeEncodingParser::StructElement::StructElement()
+ : name(""), type(clang::QualType()), bitfield(0) {}
AppleObjCTypeEncodingParser::StructElement
-AppleObjCTypeEncodingParser::ReadStructElement (clang::ASTContext &ast_ctx, lldb_utility::StringLexer& type, bool for_expression)
-{
- StructElement retval;
- if (type.NextIf('"'))
- retval.name = ReadQuotedString(type);
- if (!type.NextIf('"'))
- return retval;
- uint32_t bitfield_size = 0;
- retval.type = BuildType(ast_ctx, type, for_expression, &bitfield_size);
- retval.bitfield = bitfield_size;
+AppleObjCTypeEncodingParser::ReadStructElement(clang::ASTContext &ast_ctx,
+ lldb_utility::StringLexer &type,
+ bool for_expression) {
+ StructElement retval;
+ if (type.NextIf('"'))
+ retval.name = ReadQuotedString(type);
+ if (!type.NextIf('"'))
return retval;
+ uint32_t bitfield_size = 0;
+ retval.type = BuildType(ast_ctx, type, for_expression, &bitfield_size);
+ retval.bitfield = bitfield_size;
+ return retval;
}
clang::QualType
-AppleObjCTypeEncodingParser::BuildStruct (clang::ASTContext &ast_ctx, lldb_utility::StringLexer& type, bool for_expression)
-{
- return BuildAggregate(ast_ctx, type, for_expression, '{', '}', clang::TTK_Struct);
+AppleObjCTypeEncodingParser::BuildStruct(clang::ASTContext &ast_ctx,
+ lldb_utility::StringLexer &type,
+ bool for_expression) {
+ return BuildAggregate(ast_ctx, type, for_expression, '{', '}',
+ clang::TTK_Struct);
}
clang::QualType
-AppleObjCTypeEncodingParser::BuildUnion (clang::ASTContext &ast_ctx, lldb_utility::StringLexer& type, bool for_expression)
-{
- return BuildAggregate(ast_ctx, type, for_expression, '(', ')', clang::TTK_Union);
+AppleObjCTypeEncodingParser::BuildUnion(clang::ASTContext &ast_ctx,
+ lldb_utility::StringLexer &type,
+ bool for_expression) {
+ return BuildAggregate(ast_ctx, type, for_expression, '(', ')',
+ clang::TTK_Union);
}
-clang::QualType
-AppleObjCTypeEncodingParser::BuildAggregate (clang::ASTContext &ast_ctx, lldb_utility::StringLexer& type, bool for_expression, char opener, char closer, uint32_t kind)
-{
- if (!type.NextIf(opener))
- return clang::QualType();
- std::string name(ReadStructName(type));
-
- // We do not handle templated classes/structs at the moment.
- // If the name has a < in it, we are going to abandon this.
- // We're still obliged to parse it, so we just set a flag that
- // means "Don't actually build anything."
-
- const bool is_templated = name.find('<') != std::string::npos;
-
- if (!type.NextIf('='))
- return clang::QualType();
- bool in_union = true;
- std::vector<StructElement> elements;
- while (in_union && type.HasAtLeast(1))
- {
- if (type.NextIf(closer))
- {
- in_union = false;
- break;
- }
- else
- {
- auto element = ReadStructElement(ast_ctx, type, for_expression);
- if (element.type.isNull())
- break;
- else
- elements.push_back(element);
- }
+clang::QualType AppleObjCTypeEncodingParser::BuildAggregate(
+ clang::ASTContext &ast_ctx, lldb_utility::StringLexer &type,
+ bool for_expression, char opener, char closer, uint32_t kind) {
+ if (!type.NextIf(opener))
+ return clang::QualType();
+ std::string name(ReadStructName(type));
+
+ // We do not handle templated classes/structs at the moment.
+ // If the name has a < in it, we are going to abandon this.
+ // We're still obliged to parse it, so we just set a flag that
+ // means "Don't actually build anything."
+
+ const bool is_templated = name.find('<') != std::string::npos;
+
+ if (!type.NextIf('='))
+ return clang::QualType();
+ bool in_union = true;
+ std::vector<StructElement> elements;
+ while (in_union && type.HasAtLeast(1)) {
+ if (type.NextIf(closer)) {
+ in_union = false;
+ break;
+ } else {
+ auto element = ReadStructElement(ast_ctx, type, for_expression);
+ if (element.type.isNull())
+ break;
+ else
+ elements.push_back(element);
}
- if (in_union)
- return clang::QualType();
-
- if (is_templated)
- return clang::QualType(); // This is where we bail out. Sorry!
-
- ClangASTContext *lldb_ctx = ClangASTContext::GetASTContext(&ast_ctx);
- if (!lldb_ctx)
- return clang::QualType();
- CompilerType union_type(lldb_ctx->CreateRecordType(nullptr, lldb::eAccessPublic, name.c_str(), kind, lldb::eLanguageTypeC));
- if (union_type)
- {
- ClangASTContext::StartTagDeclarationDefinition(union_type);
-
- unsigned int count = 0;
- for (auto element: elements)
- {
- if (element.name.empty())
- {
- StreamString elem_name;
- elem_name.Printf("__unnamed_%u",count);
- element.name = std::string(elem_name.GetData());
- }
- ClangASTContext::AddFieldToRecordType(union_type, element.name.c_str(), CompilerType(&ast_ctx, element.type), lldb::eAccessPublic, element.bitfield);
- ++count;
- }
- ClangASTContext::CompleteTagDeclarationDefinition(union_type);
+ }
+ if (in_union)
+ return clang::QualType();
+
+ if (is_templated)
+ return clang::QualType(); // This is where we bail out. Sorry!
+
+ ClangASTContext *lldb_ctx = ClangASTContext::GetASTContext(&ast_ctx);
+ if (!lldb_ctx)
+ return clang::QualType();
+ CompilerType union_type(lldb_ctx->CreateRecordType(
+ nullptr, lldb::eAccessPublic, name.c_str(), kind, lldb::eLanguageTypeC));
+ if (union_type) {
+ ClangASTContext::StartTagDeclarationDefinition(union_type);
+
+ unsigned int count = 0;
+ for (auto element : elements) {
+ if (element.name.empty()) {
+ StreamString elem_name;
+ elem_name.Printf("__unnamed_%u", count);
+ element.name = elem_name.GetString();
+ }
+ ClangASTContext::AddFieldToRecordType(
+ union_type, element.name.c_str(),
+ CompilerType(&ast_ctx, element.type), lldb::eAccessPublic,
+ element.bitfield);
+ ++count;
}
- return ClangUtil::GetQualType(union_type);
+ ClangASTContext::CompleteTagDeclarationDefinition(union_type);
+ }
+ return ClangUtil::GetQualType(union_type);
}
clang::QualType
-AppleObjCTypeEncodingParser::BuildArray (clang::ASTContext &ast_ctx, lldb_utility::StringLexer& type, bool for_expression)
-{
- if (!type.NextIf('['))
- return clang::QualType();
- uint32_t size = ReadNumber(type);
- clang::QualType element_type(BuildType(ast_ctx, type, for_expression));
- if (!type.NextIf(']'))
- return clang::QualType();
- ClangASTContext *lldb_ctx = ClangASTContext::GetASTContext(&ast_ctx);
- if (!lldb_ctx)
- return clang::QualType();
- CompilerType array_type(lldb_ctx->CreateArrayType(CompilerType(&ast_ctx, element_type), size, false));
- return ClangUtil::GetQualType(array_type);
+AppleObjCTypeEncodingParser::BuildArray(clang::ASTContext &ast_ctx,
+ lldb_utility::StringLexer &type,
+ bool for_expression) {
+ if (!type.NextIf('['))
+ return clang::QualType();
+ uint32_t size = ReadNumber(type);
+ clang::QualType element_type(BuildType(ast_ctx, type, for_expression));
+ if (!type.NextIf(']'))
+ return clang::QualType();
+ ClangASTContext *lldb_ctx = ClangASTContext::GetASTContext(&ast_ctx);
+ if (!lldb_ctx)
+ return clang::QualType();
+ CompilerType array_type(lldb_ctx->CreateArrayType(
+ CompilerType(&ast_ctx, element_type), size, false));
+ return ClangUtil::GetQualType(array_type);
}
// the runtime can emit these in the form of @"SomeType", giving more specifics
-// this would be interesting for expression parser interop, but since we actually try
-// to avoid exposing the ivar info to the expression evaluator, consume but ignore the type info
-// and always return an 'id'; if anything, dynamic typing will resolve things for us anyway
-clang::QualType
-AppleObjCTypeEncodingParser::BuildObjCObjectPointerType (clang::ASTContext &ast_ctx, lldb_utility::StringLexer& type, bool for_expression)
-{
- if (!type.NextIf('@'))
- return clang::QualType();
-
- std::string name;
-
- if (type.NextIf('"'))
- {
- // We have to be careful here. We're used to seeing
- // @"NSString"
- // but in records it is possible that the string following an @ is the name of the next field and @ means "id".
- // This is the case if anything unquoted except for "}", the end of the type, or another name follows the quoted string.
- //
- // E.g.
- // - @"NSString"@ means "id, followed by a field named NSString of type id"
- // - @"NSString"} means "a pointer to NSString and the end of the struct"
- // - @"NSString""nextField" means "a pointer to NSString and a field named nextField"
- // - @"NSString" followed by the end of the string means "a pointer to NSString"
- //
- // As a result, the rule is: If we see @ followed by a quoted string, we peek.
- // - If we see }, ), ], the end of the string, or a quote ("), the quoted string is a class name.
- // - If we see anything else, the quoted string is a field name and we push it back onto type.
-
- name = ReadQuotedString(type);
-
- if (type.HasAtLeast(1))
- {
- switch (type.Peek())
- {
- default:
- // roll back
- type.PutBack(name.length() + 2); // undo our consumption of the string and of the quotes
- name.clear();
- break;
- case '}':
- case ')':
- case ']':
- case '"':
- // the quoted string is a class name – see the rule
- break;
- }
- }
- else
- {
- // the quoted string is a class name – see the rule
- }
+// this would be interesting for expression parser interop, but since we
+// actually try
+// to avoid exposing the ivar info to the expression evaluator, consume but
+// ignore the type info
+// and always return an 'id'; if anything, dynamic typing will resolve things
+// for us anyway
+clang::QualType AppleObjCTypeEncodingParser::BuildObjCObjectPointerType(
+ clang::ASTContext &ast_ctx, lldb_utility::StringLexer &type,
+ bool for_expression) {
+ if (!type.NextIf('@'))
+ return clang::QualType();
+
+ std::string name;
+
+ if (type.NextIf('"')) {
+ // We have to be careful here. We're used to seeing
+ // @"NSString"
+ // but in records it is possible that the string following an @ is the name
+ // of the next field and @ means "id".
+ // This is the case if anything unquoted except for "}", the end of the
+ // type, or another name follows the quoted string.
+ //
+ // E.g.
+ // - @"NSString"@ means "id, followed by a field named NSString of type id"
+ // - @"NSString"} means "a pointer to NSString and the end of the struct"
+ // - @"NSString""nextField" means "a pointer to NSString and a field named
+ // nextField"
+ // - @"NSString" followed by the end of the string means "a pointer to
+ // NSString"
+ //
+ // As a result, the rule is: If we see @ followed by a quoted string, we
+ // peek.
+ // - If we see }, ), ], the end of the string, or a quote ("), the quoted
+ // string is a class name.
+ // - If we see anything else, the quoted string is a field name and we push
+ // it back onto type.
+
+ name = ReadQuotedString(type);
+
+ if (type.HasAtLeast(1)) {
+ switch (type.Peek()) {
+ default:
+ // roll back
+ type.PutBack(name.length() +
+ 2); // undo our consumption of the string and of the quotes
+ name.clear();
+ break;
+ case '}':
+ case ')':
+ case ']':
+ case '"':
+ // the quoted string is a class name – see the rule
+ break;
+ }
+ } else {
+ // the quoted string is a class name – see the rule
+ }
+ }
+
+ if (for_expression && !name.empty()) {
+ size_t less_than_pos = name.find('<');
+
+ if (less_than_pos != std::string::npos) {
+ if (less_than_pos == 0)
+ return ast_ctx.getObjCIdType();
+ else
+ name.erase(less_than_pos);
}
-
- if (for_expression && !name.empty())
- {
- size_t less_than_pos = name.find('<');
-
- if (less_than_pos != std::string::npos)
- {
- if (less_than_pos == 0)
- return ast_ctx.getObjCIdType();
- else
- name.erase(less_than_pos);
- }
-
- DeclVendor *decl_vendor = m_runtime.GetDeclVendor();
-
- assert (decl_vendor); // how are we parsing type encodings for expressions if a type vendor isn't in play?
-
- const bool append = false;
- const uint32_t max_matches = 1;
- std::vector<clang::NamedDecl *> decls;
-
- uint32_t num_types = decl_vendor->FindDecls(ConstString(name),
- append,
- max_matches,
- decls);
-
- // The user can forward-declare something that has no definition. The runtime doesn't prohibit this at all.
- // This is a rare and very weird case. We keep this assert in debug builds so we catch other weird cases.
+
+ DeclVendor *decl_vendor = m_runtime.GetDeclVendor();
+ if (!decl_vendor)
+ return clang::QualType();
+
+ const bool append = false;
+ const uint32_t max_matches = 1;
+ std::vector<clang::NamedDecl *> decls;
+
+ uint32_t num_types =
+ decl_vendor->FindDecls(ConstString(name), append, max_matches, decls);
+
+// The user can forward-declare something that has no definition. The runtime
+// doesn't prohibit this at all.
+// This is a rare and very weird case. We keep this assert in debug builds so
+// we catch other weird cases.
#ifdef LLDB_CONFIGURATION_DEBUG
- assert(num_types);
+ assert(num_types);
#else
- if (!num_types)
- return ast_ctx.getObjCIdType();
+ if (!num_types)
+ return ast_ctx.getObjCIdType();
#endif
- return ClangUtil::GetQualType(ClangASTContext::GetTypeForDecl(decls[0]).GetPointerType());
- }
- else
- {
- // We're going to resolve this dynamically anyway, so just smile and wave.
- return ast_ctx.getObjCIdType();
- }
+ return ClangUtil::GetQualType(
+ ClangASTContext::GetTypeForDecl(decls[0]).GetPointerType());
+ } else {
+ // We're going to resolve this dynamically anyway, so just smile and wave.
+ return ast_ctx.getObjCIdType();
+ }
}
clang::QualType
-AppleObjCTypeEncodingParser::BuildType (clang::ASTContext &ast_ctx, StringLexer& type, bool for_expression, uint32_t *bitfield_bit_size)
-{
- if (!type.HasAtLeast(1))
- return clang::QualType();
-
- switch (type.Peek())
- {
- default:
- break;
- case '{':
- return BuildStruct(ast_ctx, type, for_expression);
- case '[':
- return BuildArray(ast_ctx, type, for_expression);
- case '(':
- return BuildUnion(ast_ctx, type, for_expression);
- case '@':
- return BuildObjCObjectPointerType(ast_ctx, type, for_expression);
- }
-
- switch (type.Next())
- {
- default:
- type.PutBack(1);
+AppleObjCTypeEncodingParser::BuildType(clang::ASTContext &ast_ctx,
+ StringLexer &type, bool for_expression,
+ uint32_t *bitfield_bit_size) {
+ if (!type.HasAtLeast(1))
+ return clang::QualType();
+
+ switch (type.Peek()) {
+ default:
+ break;
+ case '{':
+ return BuildStruct(ast_ctx, type, for_expression);
+ case '[':
+ return BuildArray(ast_ctx, type, for_expression);
+ case '(':
+ return BuildUnion(ast_ctx, type, for_expression);
+ case '@':
+ return BuildObjCObjectPointerType(ast_ctx, type, for_expression);
+ }
+
+ switch (type.Next()) {
+ default:
+ type.PutBack(1);
+ return clang::QualType();
+ case 'c':
+ return ast_ctx.CharTy;
+ case 'i':
+ return ast_ctx.IntTy;
+ case 's':
+ return ast_ctx.ShortTy;
+ case 'l':
+ return ast_ctx.getIntTypeForBitwidth(32, true);
+ // this used to be done like this:
+ // ClangASTContext *lldb_ctx = ClangASTContext::GetASTContext(&ast_ctx);
+ // if (!lldb_ctx)
+ // return clang::QualType();
+ // return lldb_ctx->GetIntTypeFromBitSize(32, true).GetQualType();
+ // which uses one of the constants if one is available, but we don't think all
+ // this work is necessary.
+ case 'q':
+ return ast_ctx.LongLongTy;
+ case 'C':
+ return ast_ctx.UnsignedCharTy;
+ case 'I':
+ return ast_ctx.UnsignedIntTy;
+ case 'S':
+ return ast_ctx.UnsignedShortTy;
+ case 'L':
+ return ast_ctx.getIntTypeForBitwidth(32, false);
+ // see note for 'l'
+ case 'Q':
+ return ast_ctx.UnsignedLongLongTy;
+ case 'f':
+ return ast_ctx.FloatTy;
+ case 'd':
+ return ast_ctx.DoubleTy;
+ case 'B':
+ return ast_ctx.BoolTy;
+ case 'v':
+ return ast_ctx.VoidTy;
+ case '*':
+ return ast_ctx.getPointerType(ast_ctx.CharTy);
+ case '#':
+ return ast_ctx.getObjCClassType();
+ case ':':
+ return ast_ctx.getObjCSelType();
+ case 'b': {
+ uint32_t size = ReadNumber(type);
+ if (bitfield_bit_size) {
+ *bitfield_bit_size = size;
+ return ast_ctx.UnsignedIntTy; // FIXME: the spec is fairly vague here.
+ } else
+ return clang::QualType();
+ }
+ case 'r': {
+ clang::QualType target_type = BuildType(ast_ctx, type, for_expression);
+ if (target_type.isNull())
+ return clang::QualType();
+ else if (target_type == ast_ctx.UnknownAnyTy)
+ return ast_ctx.UnknownAnyTy;
+ else
+ return ast_ctx.getConstType(target_type);
+ }
+ case '^': {
+ if (!for_expression && type.NextIf('?')) {
+ // if we are not supporting the concept of unknownAny, but what is being
+ // created here is an unknownAny*, then
+ // we can just get away with a void*
+ // this is theoretically wrong (in the same sense as 'theoretically
+ // nothing exists') but is way better than outright failure
+ // in many practical cases
+ return ast_ctx.VoidPtrTy;
+ } else {
+ clang::QualType target_type = BuildType(ast_ctx, type, for_expression);
+ if (target_type.isNull())
return clang::QualType();
- case 'c':
- return ast_ctx.CharTy;
- case 'i':
- return ast_ctx.IntTy;
- case 's':
- return ast_ctx.ShortTy;
- case 'l':
- return ast_ctx.getIntTypeForBitwidth(32, true);
- // this used to be done like this:
- // ClangASTContext *lldb_ctx = ClangASTContext::GetASTContext(&ast_ctx);
- // if (!lldb_ctx)
- // return clang::QualType();
- // return lldb_ctx->GetIntTypeFromBitSize(32, true).GetQualType();
- // which uses one of the constants if one is available, but we don't think all this work is necessary.
- case 'q':
- return ast_ctx.LongLongTy;
- case 'C':
- return ast_ctx.UnsignedCharTy;
- case 'I':
- return ast_ctx.UnsignedIntTy;
- case 'S':
- return ast_ctx.UnsignedShortTy;
- case 'L':
- return ast_ctx.getIntTypeForBitwidth(32, false);
- // see note for 'l'
- case 'Q':
- return ast_ctx.UnsignedLongLongTy;
- case 'f':
- return ast_ctx.FloatTy;
- case 'd':
- return ast_ctx.DoubleTy;
- case 'B':
- return ast_ctx.BoolTy;
- case 'v':
- return ast_ctx.VoidTy;
- case '*':
- return ast_ctx.getPointerType(ast_ctx.CharTy);
- case '#':
- return ast_ctx.getObjCClassType();
- case ':':
- return ast_ctx.getObjCSelType();
- case 'b':
- {
- uint32_t size = ReadNumber(type);
- if (bitfield_bit_size)
- {
- *bitfield_bit_size = size;
- return ast_ctx.UnsignedIntTy; // FIXME: the spec is fairly vague here.
- }
- else
- return clang::QualType();
- }
- case 'r':
- {
- clang::QualType target_type = BuildType(ast_ctx, type, for_expression);
- if (target_type.isNull())
- return clang::QualType();
- else if (target_type == ast_ctx.UnknownAnyTy)
- return ast_ctx.UnknownAnyTy;
- else
- return ast_ctx.getConstType(target_type);
- }
- case '^':
- {
- if (!for_expression && type.NextIf('?'))
- {
- // if we are not supporting the concept of unknownAny, but what is being created here is an unknownAny*, then
- // we can just get away with a void*
- // this is theoretically wrong (in the same sense as 'theoretically nothing exists') but is way better than outright failure
- // in many practical cases
- return ast_ctx.VoidPtrTy;
- }
- else
- {
- clang::QualType target_type = BuildType(ast_ctx, type, for_expression);
- if (target_type.isNull())
- return clang::QualType();
- else if (target_type == ast_ctx.UnknownAnyTy)
- return ast_ctx.UnknownAnyTy;
- else
- return ast_ctx.getPointerType(target_type);
- }
- }
- case '?':
- return for_expression ? ast_ctx.UnknownAnyTy : clang::QualType();
+ else if (target_type == ast_ctx.UnknownAnyTy)
+ return ast_ctx.UnknownAnyTy;
+ else
+ return ast_ctx.getPointerType(target_type);
}
+ }
+ case '?':
+ return for_expression ? ast_ctx.UnknownAnyTy : clang::QualType();
+ }
}
-CompilerType
-AppleObjCTypeEncodingParser::RealizeType (clang::ASTContext &ast_ctx, const char* name, bool for_expression)
-{
- if (name && name[0])
- {
- StringLexer lexer(name);
- clang::QualType qual_type = BuildType(ast_ctx, lexer, for_expression);
- return CompilerType(&ast_ctx, qual_type);
- }
- return CompilerType();
+CompilerType AppleObjCTypeEncodingParser::RealizeType(
+ clang::ASTContext &ast_ctx, const char *name, bool for_expression) {
+ if (name && name[0]) {
+ StringLexer lexer(name);
+ clang::QualType qual_type = BuildType(ast_ctx, lexer, for_expression);
+ return CompilerType(&ast_ctx, qual_type);
+ }
+ return CompilerType();
}
-