diff options
Diffstat (limited to 'lldb/source/Symbol/ClangASTContext.cpp')
-rw-r--r-- | lldb/source/Symbol/ClangASTContext.cpp | 5416 |
1 files changed, 367 insertions, 5049 deletions
diff --git a/lldb/source/Symbol/ClangASTContext.cpp b/lldb/source/Symbol/ClangASTContext.cpp index 00ebfaaed2f..b5c658dab86 100644 --- a/lldb/source/Symbol/ClangASTContext.cpp +++ b/lldb/source/Symbol/ClangASTContext.cpp @@ -62,6 +62,7 @@ #include "lldb/Core/Flags.h" #include "lldb/Core/Log.h" #include "lldb/Core/RegularExpression.h" +#include "lldb/Core/UniqueCStringMap.h" #include "lldb/Expression/ASTDumper.h" #include "lldb/Symbol/ClangExternalASTSourceCommon.h" #include "lldb/Symbol/VerifyDecl.h" @@ -77,111 +78,8 @@ using namespace lldb_private; using namespace llvm; using namespace clang; - -static bool -GetCompleteQualType (clang::ASTContext *ast, clang::QualType qual_type, bool allow_completion = true) -{ - const clang::Type::TypeClass type_class = qual_type->getTypeClass(); - switch (type_class) - { - case clang::Type::ConstantArray: - case clang::Type::IncompleteArray: - case clang::Type::VariableArray: - { - const clang::ArrayType *array_type = dyn_cast<clang::ArrayType>(qual_type.getTypePtr()); - - if (array_type) - return GetCompleteQualType (ast, array_type->getElementType(), allow_completion); - } - break; - - case clang::Type::Record: - case clang::Type::Enum: - { - const clang::TagType *tag_type = dyn_cast<clang::TagType>(qual_type.getTypePtr()); - if (tag_type) - { - clang::TagDecl *tag_decl = tag_type->getDecl(); - if (tag_decl) - { - if (tag_decl->isCompleteDefinition()) - return true; - - if (!allow_completion) - return false; - - if (tag_decl->hasExternalLexicalStorage()) - { - if (ast) - { - ExternalASTSource *external_ast_source = ast->getExternalSource(); - if (external_ast_source) - { - external_ast_source->CompleteType(tag_decl); - return !tag_type->isIncompleteType(); - } - } - } - return false; - } - } - - } - break; - - case clang::Type::ObjCObject: - case clang::Type::ObjCInterface: - { - const clang::ObjCObjectType *objc_class_type = dyn_cast<clang::ObjCObjectType>(qual_type); - if (objc_class_type) - { - clang::ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface(); - // We currently can't complete objective C types through the newly added ASTContext - // because it only supports TagDecl objects right now... - if (class_interface_decl) - { - if (class_interface_decl->getDefinition()) - return true; - - if (!allow_completion) - return false; - - if (class_interface_decl->hasExternalLexicalStorage()) - { - if (ast) - { - ExternalASTSource *external_ast_source = ast->getExternalSource(); - if (external_ast_source) - { - external_ast_source->CompleteType (class_interface_decl); - return !objc_class_type->isIncompleteType(); - } - } - } - return false; - } - } - } - break; - - case clang::Type::Typedef: - return GetCompleteQualType (ast, cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType(), allow_completion); - - case clang::Type::Elaborated: - return GetCompleteQualType (ast, cast<ElaboratedType>(qual_type)->getNamedType(), allow_completion); - - case clang::Type::Paren: - return GetCompleteQualType (ast, cast<ParenType>(qual_type)->desugar(), allow_completion); - - default: - break; - } - - return true; -} - -static AccessSpecifier -ConvertAccessTypeToAccessSpecifier (AccessType access) +clang::AccessSpecifier +ClangASTContext::ConvertAccessTypeToAccessSpecifier (AccessType access) { switch (access) { @@ -194,20 +92,6 @@ ConvertAccessTypeToAccessSpecifier (AccessType access) return AS_none; } -static ObjCIvarDecl::AccessControl -ConvertAccessTypeToObjCIvarAccessControl (AccessType access) -{ - switch (access) - { - case eAccessNone: return ObjCIvarDecl::None; - case eAccessPublic: return ObjCIvarDecl::Public; - case eAccessPrivate: return ObjCIvarDecl::Private; - case eAccessProtected: return ObjCIvarDecl::Protected; - case eAccessPackage: return ObjCIvarDecl::Package; - } - return ObjCIvarDecl::None; -} - static void ParseLangArgs @@ -393,7 +277,8 @@ ClangASTContext::ClangASTContext (const char *target_triple) : m_builtins_ap(), m_callback_tag_decl (NULL), m_callback_objc_decl (NULL), - m_callback_baton (NULL) + m_callback_baton (NULL), + m_pointer_byte_size (0) { if (target_triple && target_triple[0]) @@ -429,6 +314,7 @@ ClangASTContext::Clear() m_identifier_table_ap.reset(); m_selector_table_ap.reset(); m_builtins_ap.reset(); + m_pointer_byte_size = 0; } const char * @@ -646,80 +532,279 @@ QualTypeMatchesBitSize(const uint64_t bit_size, ASTContext *ast, QualType qual_t return true; return false; } - -clang_type_t +ClangASTType ClangASTContext::GetBuiltinTypeForEncodingAndBitSize (Encoding encoding, uint32_t bit_size) { - ASTContext *ast = getASTContext(); - - assert (ast != NULL); - - return GetBuiltinTypeForEncodingAndBitSize (ast, encoding, bit_size); + return ClangASTContext::GetBuiltinTypeForEncodingAndBitSize (getASTContext(), encoding, bit_size); } -clang_type_t +ClangASTType ClangASTContext::GetBuiltinTypeForEncodingAndBitSize (ASTContext *ast, Encoding encoding, uint32_t bit_size) { if (!ast) - return NULL; + return ClangASTType(); switch (encoding) { case eEncodingInvalid: if (QualTypeMatchesBitSize (bit_size, ast, ast->VoidPtrTy)) - return ast->VoidPtrTy.getAsOpaquePtr(); + return ClangASTType (ast, ast->VoidPtrTy.getAsOpaquePtr()); break; case eEncodingUint: if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedCharTy)) - return ast->UnsignedCharTy.getAsOpaquePtr(); + return ClangASTType (ast, ast->UnsignedCharTy.getAsOpaquePtr()); if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedShortTy)) - return ast->UnsignedShortTy.getAsOpaquePtr(); + return ClangASTType (ast, ast->UnsignedShortTy.getAsOpaquePtr()); if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedIntTy)) - return ast->UnsignedIntTy.getAsOpaquePtr(); + return ClangASTType (ast, ast->UnsignedIntTy.getAsOpaquePtr()); if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedLongTy)) - return ast->UnsignedLongTy.getAsOpaquePtr(); + return ClangASTType (ast, ast->UnsignedLongTy.getAsOpaquePtr()); if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedLongLongTy)) - return ast->UnsignedLongLongTy.getAsOpaquePtr(); + return ClangASTType (ast, ast->UnsignedLongLongTy.getAsOpaquePtr()); if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedInt128Ty)) - return ast->UnsignedInt128Ty.getAsOpaquePtr(); + return ClangASTType (ast, ast->UnsignedInt128Ty.getAsOpaquePtr()); break; case eEncodingSint: if (QualTypeMatchesBitSize (bit_size, ast, ast->CharTy)) - return ast->CharTy.getAsOpaquePtr(); + return ClangASTType (ast, ast->CharTy.getAsOpaquePtr()); if (QualTypeMatchesBitSize (bit_size, ast, ast->ShortTy)) - return ast->ShortTy.getAsOpaquePtr(); + return ClangASTType (ast, ast->ShortTy.getAsOpaquePtr()); if (QualTypeMatchesBitSize (bit_size, ast, ast->IntTy)) - return ast->IntTy.getAsOpaquePtr(); + return ClangASTType (ast, ast->IntTy.getAsOpaquePtr()); if (QualTypeMatchesBitSize (bit_size, ast, ast->LongTy)) - return ast->LongTy.getAsOpaquePtr(); + return ClangASTType (ast, ast->LongTy.getAsOpaquePtr()); if (QualTypeMatchesBitSize (bit_size, ast, ast->LongLongTy)) - return ast->LongLongTy.getAsOpaquePtr(); + return ClangASTType (ast, ast->LongLongTy.getAsOpaquePtr()); if (QualTypeMatchesBitSize (bit_size, ast, ast->Int128Ty)) - return ast->Int128Ty.getAsOpaquePtr(); + return ClangASTType (ast, ast->Int128Ty.getAsOpaquePtr()); break; case eEncodingIEEE754: if (QualTypeMatchesBitSize (bit_size, ast, ast->FloatTy)) - return ast->FloatTy.getAsOpaquePtr(); + return ClangASTType (ast, ast->FloatTy.getAsOpaquePtr()); if (QualTypeMatchesBitSize (bit_size, ast, ast->DoubleTy)) - return ast->DoubleTy.getAsOpaquePtr(); + return ClangASTType (ast, ast->DoubleTy.getAsOpaquePtr()); if (QualTypeMatchesBitSize (bit_size, ast, ast->LongDoubleTy)) - return ast->LongDoubleTy.getAsOpaquePtr(); + return ClangASTType (ast, ast->LongDoubleTy.getAsOpaquePtr()); break; case eEncodingVector: // Sanity check that bit_size is a multiple of 8's. if (bit_size && !(bit_size & 0x7u)) - return ast->getExtVectorType (ast->UnsignedCharTy, bit_size/8).getAsOpaquePtr(); + return ClangASTType (ast, ast->getExtVectorType (ast->UnsignedCharTy, bit_size/8).getAsOpaquePtr()); break; } - return NULL; + return ClangASTType(); +} + + + +lldb::BasicType +ClangASTContext::GetBasicTypeEnumeration (const ConstString &name) +{ + if (name) + { + typedef UniqueCStringMap<lldb::BasicType> TypeNameToBasicTypeMap; + static TypeNameToBasicTypeMap g_type_map; + static std::once_flag g_once_flag; + std::call_once(g_once_flag, [](){ + // "void" + g_type_map.Append(ConstString("void").GetCString(), eBasicTypeVoid); + + // "char" + g_type_map.Append(ConstString("char").GetCString(), eBasicTypeChar); + g_type_map.Append(ConstString("signed char").GetCString(), eBasicTypeSignedChar); + g_type_map.Append(ConstString("unsigned char").GetCString(), eBasicTypeUnsignedChar); + g_type_map.Append(ConstString("wchar_t").GetCString(), eBasicTypeWChar); + g_type_map.Append(ConstString("signed wchar_t").GetCString(), eBasicTypeSignedWChar); + g_type_map.Append(ConstString("unsigned wchar_t").GetCString(), eBasicTypeUnsignedWChar); + // "short" + g_type_map.Append(ConstString("short").GetCString(), eBasicTypeShort); + g_type_map.Append(ConstString("short int").GetCString(), eBasicTypeShort); + g_type_map.Append(ConstString("unsigned short").GetCString(), eBasicTypeUnsignedShort); + g_type_map.Append(ConstString("unsigned short int").GetCString(), eBasicTypeUnsignedShort); + + // "int" + g_type_map.Append(ConstString("int").GetCString(), eBasicTypeInt); + g_type_map.Append(ConstString("signed int").GetCString(), eBasicTypeInt); + g_type_map.Append(ConstString("unsigned int").GetCString(), eBasicTypeUnsignedInt); + g_type_map.Append(ConstString("unsigned").GetCString(), eBasicTypeUnsignedInt); + + // "long" + g_type_map.Append(ConstString("long").GetCString(), eBasicTypeLong); + g_type_map.Append(ConstString("long int").GetCString(), eBasicTypeLong); + g_type_map.Append(ConstString("unsigned long").GetCString(), eBasicTypeUnsignedLong); + g_type_map.Append(ConstString("unsigned long int").GetCString(), eBasicTypeUnsignedLong); + + // "long long" + g_type_map.Append(ConstString("long long").GetCString(), eBasicTypeLongLong); + g_type_map.Append(ConstString("long long int").GetCString(), eBasicTypeLongLong); + g_type_map.Append(ConstString("unsigned long long").GetCString(), eBasicTypeUnsignedLongLong); + g_type_map.Append(ConstString("unsigned long long int").GetCString(), eBasicTypeUnsignedLongLong); + + // "int128" + g_type_map.Append(ConstString("__int128_t").GetCString(), eBasicTypeInt128); + g_type_map.Append(ConstString("__uint128_t").GetCString(), eBasicTypeUnsignedInt128); + + // Miscelaneous + g_type_map.Append(ConstString("bool").GetCString(), eBasicTypeBool); + g_type_map.Append(ConstString("float").GetCString(), eBasicTypeFloat); + g_type_map.Append(ConstString("double").GetCString(), eBasicTypeDouble); + g_type_map.Append(ConstString("long double").GetCString(), eBasicTypeLongDouble); + g_type_map.Append(ConstString("id").GetCString(), eBasicTypeObjCID); + g_type_map.Append(ConstString("SEL").GetCString(), eBasicTypeObjCSel); + g_type_map.Append(ConstString("nullptr").GetCString(), eBasicTypeNullPtr); + g_type_map.Sort(); + }); + + return g_type_map.Find(name.GetCString(), eBasicTypeInvalid); + } + return eBasicTypeInvalid; +} + +ClangASTType +ClangASTContext::GetBasicType (ASTContext *ast, const ConstString &name) +{ + if (ast) + { + lldb::BasicType basic_type = ClangASTContext::GetBasicTypeEnumeration (name); + return ClangASTContext::GetBasicType (ast, basic_type); + } + return ClangASTType(); +} + +uint32_t +ClangASTContext::GetPointerByteSize () +{ + if (m_pointer_byte_size == 0) + m_pointer_byte_size = GetBasicType(lldb::eBasicTypeVoid).GetPointerType().GetByteSize(); + return m_pointer_byte_size; +} + +ClangASTType +ClangASTContext::GetBasicType (lldb::BasicType basic_type) +{ + return GetBasicType (getASTContext(), basic_type); +} + +ClangASTType +ClangASTContext::GetBasicType (ASTContext *ast, lldb::BasicType basic_type) +{ + if (ast) + { + clang_type_t clang_type = NULL; + + switch (basic_type) + { + case eBasicTypeInvalid: + case eBasicTypeOther: + break; + case eBasicTypeVoid: + clang_type = ast->VoidTy.getAsOpaquePtr(); + break; + case eBasicTypeChar: + clang_type = ast->CharTy.getAsOpaquePtr(); + break; + case eBasicTypeSignedChar: + clang_type = ast->SignedCharTy.getAsOpaquePtr(); + break; + case eBasicTypeUnsignedChar: + clang_type = ast->UnsignedCharTy.getAsOpaquePtr(); + break; + case eBasicTypeWChar: + clang_type = ast->getWCharType().getAsOpaquePtr(); + break; + case eBasicTypeSignedWChar: + clang_type = ast->getSignedWCharType().getAsOpaquePtr(); + break; + case eBasicTypeUnsignedWChar: + clang_type = ast->getUnsignedWCharType().getAsOpaquePtr(); + break; + case eBasicTypeChar16: + clang_type = ast->Char16Ty.getAsOpaquePtr(); + break; + case eBasicTypeChar32: + clang_type = ast->Char32Ty.getAsOpaquePtr(); + break; + case eBasicTypeShort: + clang_type = ast->ShortTy.getAsOpaquePtr(); + break; + case eBasicTypeUnsignedShort: + clang_type = ast->UnsignedShortTy.getAsOpaquePtr(); + break; + case eBasicTypeInt: + clang_type = ast->IntTy.getAsOpaquePtr(); + break; + case eBasicTypeUnsignedInt: + clang_type = ast->UnsignedIntTy.getAsOpaquePtr(); + break; + case eBasicTypeLong: + clang_type = ast->LongTy.getAsOpaquePtr(); + break; + case eBasicTypeUnsignedLong: + clang_type = ast->UnsignedLongTy.getAsOpaquePtr(); + break; + case eBasicTypeLongLong: + clang_type = ast->LongLongTy.getAsOpaquePtr(); + break; + case eBasicTypeUnsignedLongLong: + clang_type = ast->UnsignedLongLongTy.getAsOpaquePtr(); + break; + case eBasicTypeInt128: + clang_type = ast->Int128Ty.getAsOpaquePtr(); + break; + case eBasicTypeUnsignedInt128: + clang_type = ast->UnsignedInt128Ty.getAsOpaquePtr(); + break; + case eBasicTypeBool: + clang_type = ast->BoolTy.getAsOpaquePtr(); + break; + case eBasicTypeHalf: + clang_type = ast->HalfTy.getAsOpaquePtr(); + break; + case eBasicTypeFloat: + clang_type = ast->FloatTy.getAsOpaquePtr(); + break; + case eBasicTypeDouble: + clang_type = ast->DoubleTy.getAsOpaquePtr(); + break; + case eBasicTypeLongDouble: + clang_type = ast->LongDoubleTy.getAsOpaquePtr(); + break; + case eBasicTypeFloatComplex: + clang_type = ast->FloatComplexTy.getAsOpaquePtr(); + break; + case eBasicTypeDoubleComplex: + clang_type = ast->DoubleComplexTy.getAsOpaquePtr(); + break; + case eBasicTypeLongDoubleComplex: + clang_type = ast->LongDoubleComplexTy.getAsOpaquePtr(); + break; + case eBasicTypeObjCID: + clang_type = ast->getObjCIdType().getAsOpaquePtr(); + break; + case eBasicTypeObjCClass: + clang_type = ast->getObjCClassType().getAsOpaquePtr(); + break; + case eBasicTypeObjCSel: + clang_type = ast->getObjCSelType().getAsOpaquePtr(); + break; + case eBasicTypeNullPtr: + clang_type = ast->NullPtrTy.getAsOpaquePtr(); + break; + } + + if (clang_type) + return ClangASTType (ast, clang_type); + } + return ClangASTType(); } -clang_type_t + +ClangASTType ClangASTContext::GetBuiltinTypeForDWARFEncodingAndBitSize (const char *type_name, uint32_t dw_ate, uint32_t bit_size) { ASTContext *ast = getASTContext(); @@ -735,18 +820,18 @@ ClangASTContext::GetBuiltinTypeForDWARFEncodingAndBitSize (const char *type_name case DW_ATE_address: if (QualTypeMatchesBitSize (bit_size, ast, ast->VoidPtrTy)) - return ast->VoidPtrTy.getAsOpaquePtr(); + return ClangASTType (ast, ast->VoidPtrTy.getAsOpaquePtr()); break; case DW_ATE_boolean: if (QualTypeMatchesBitSize (bit_size, ast, ast->BoolTy)) - return ast->BoolTy.getAsOpaquePtr(); + return ClangASTType (ast, ast->BoolTy.getAsOpaquePtr()); if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedCharTy)) - return ast->UnsignedCharTy.getAsOpaquePtr(); + return ClangASTType (ast, ast->UnsignedCharTy.getAsOpaquePtr()); if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedShortTy)) - return ast->UnsignedShortTy.getAsOpaquePtr(); + return ClangASTType (ast, ast->UnsignedShortTy.getAsOpaquePtr()); if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedIntTy)) - return ast->UnsignedIntTy.getAsOpaquePtr(); + return ClangASTType (ast, ast->UnsignedIntTy.getAsOpaquePtr()); break; case DW_ATE_lo_user: @@ -755,33 +840,33 @@ ClangASTContext::GetBuiltinTypeForDWARFEncodingAndBitSize (const char *type_name { if (::strstr(type_name, "complex")) { - clang_type_t complex_int_clang_type = GetBuiltinTypeForDWARFEncodingAndBitSize ("int", DW_ATE_signed, bit_size/2); - return ast->getComplexType (QualType::getFromOpaquePtr(complex_int_clang_type)).getAsOpaquePtr(); + ClangASTType complex_int_clang_type = GetBuiltinTypeForDWARFEncodingAndBitSize ("int", DW_ATE_signed, bit_size/2); + return ClangASTType (ast, ast->getComplexType (complex_int_clang_type.GetQualType()).getAsOpaquePtr()); } } break; case DW_ATE_complex_float: if (QualTypeMatchesBitSize (bit_size, ast, ast->FloatComplexTy)) - return ast->FloatComplexTy.getAsOpaquePtr(); + return ClangASTType (ast, ast->FloatComplexTy.getAsOpaquePtr()); else if (QualTypeMatchesBitSize (bit_size, ast, ast->DoubleComplexTy)) - return ast->DoubleComplexTy.getAsOpaquePtr(); + return ClangASTType (ast, ast->DoubleComplexTy.getAsOpaquePtr()); else if (QualTypeMatchesBitSize (bit_size, ast, ast->LongDoubleComplexTy)) - return ast->LongDoubleComplexTy.getAsOpaquePtr(); + return ClangASTType (ast, ast->LongDoubleComplexTy.getAsOpaquePtr()); else { - clang_type_t complex_float_clang_type = GetBuiltinTypeForDWARFEncodingAndBitSize ("float", DW_ATE_float, bit_size/2); - return ast->getComplexType (QualType::getFromOpaquePtr(complex_float_clang_type)).getAsOpaquePtr(); + ClangASTType complex_float_clang_type = GetBuiltinTypeForDWARFEncodingAndBitSize ("float", DW_ATE_float, bit_size/2); + return ClangASTType (ast, ast->getComplexType (complex_float_clang_type.GetQualType()).getAsOpaquePtr()); } break; case DW_ATE_float: if (QualTypeMatchesBitSize (bit_size, ast, ast->FloatTy)) - return ast->FloatTy.getAsOpaquePtr(); + return ClangASTType (ast, ast->FloatTy.getAsOpaquePtr()); if (QualTypeMatchesBitSize (bit_size, ast, ast->DoubleTy)) - return ast->DoubleTy.getAsOpaquePtr(); + return ClangASTType (ast, ast->DoubleTy.getAsOpaquePtr()); if (QualTypeMatchesBitSize (bit_size, ast, ast->LongDoubleTy)) - return ast->LongDoubleTy.getAsOpaquePtr(); + return ClangASTType (ast, ast->LongDoubleTy.getAsOpaquePtr()); break; case DW_ATE_signed: @@ -789,47 +874,47 @@ ClangASTContext::GetBuiltinTypeForDWARFEncodingAndBitSize (const char *type_name { if (streq(type_name, "wchar_t") && QualTypeMatchesBitSize (bit_size, ast, ast->WCharTy)) - return ast->WCharTy.getAsOpaquePtr(); + return ClangASTType (ast, ast->WCharTy.getAsOpaquePtr()); if (streq(type_name, "void") && QualTypeMatchesBitSize (bit_size, ast, ast->VoidTy)) - return ast->VoidTy.getAsOpaquePtr(); + return ClangASTType (ast, ast->VoidTy.getAsOpaquePtr()); if (strstr(type_name, "long long") && QualTypeMatchesBitSize (bit_size, ast, ast->LongLongTy)) - return ast->LongLongTy.getAsOpaquePtr(); + return ClangASTType (ast, ast->LongLongTy.getAsOpaquePtr()); if (strstr(type_name, "long") && QualTypeMatchesBitSize (bit_size, ast, ast->LongTy)) - return ast->LongTy.getAsOpaquePtr(); + return ClangASTType (ast, ast->LongTy.getAsOpaquePtr()); if (strstr(type_name, "short") && QualTypeMatchesBitSize (bit_size, ast, ast->ShortTy)) - return ast->ShortTy.getAsOpaquePtr(); + return ClangASTType (ast, ast->ShortTy.getAsOpaquePtr()); if (strstr(type_name, "char")) { if (QualTypeMatchesBitSize (bit_size, ast, ast->CharTy)) - return ast->CharTy.getAsOpaquePtr(); + return ClangASTType (ast, ast->CharTy.getAsOpaquePtr()); if (QualTypeMatchesBitSize (bit_size, ast, ast->SignedCharTy)) - return ast->SignedCharTy.getAsOpaquePtr(); + return ClangASTType (ast, ast->SignedCharTy.getAsOpaquePtr()); } if (strstr(type_name, "int")) { if (QualTypeMatchesBitSize (bit_size, ast, ast->IntTy)) - return ast->IntTy.getAsOpaquePtr(); + return ClangASTType (ast, ast->IntTy.getAsOpaquePtr()); if (QualTypeMatchesBitSize (bit_size, ast, ast->Int128Ty)) - return ast->Int128Ty.getAsOpaquePtr(); + return ClangASTType (ast, ast->Int128Ty.getAsOpaquePtr()); } } // We weren't able to match up a type name, just search by size if (QualTypeMatchesBitSize (bit_size, ast, ast->CharTy)) - return ast->CharTy.getAsOpaquePtr(); + return ClangASTType (ast, ast->CharTy.getAsOpaquePtr()); if (QualTypeMatchesBitSize (bit_size, ast, ast->ShortTy)) - return ast->ShortTy.getAsOpaquePtr(); + return ClangASTType (ast, ast->ShortTy.getAsOpaquePtr()); if (QualTypeMatchesBitSize (bit_size, ast, ast->IntTy)) - return ast->IntTy.getAsOpaquePtr(); + return ClangASTType (ast, ast->IntTy.getAsOpaquePtr()); if (QualTypeMatchesBitSize (bit_size, ast, ast->LongTy)) - return ast->LongTy.getAsOpaquePtr(); + return ClangASTType (ast, ast->LongTy.getAsOpaquePtr()); if (QualTypeMatchesBitSize (bit_size, ast, ast->LongLongTy)) - return ast->LongLongTy.getAsOpaquePtr(); + return ClangASTType (ast, ast->LongLongTy.getAsOpaquePtr()); if (QualTypeMatchesBitSize (bit_size, ast, ast->Int128Ty)) - return ast->Int128Ty.getAsOpaquePtr(); + return ClangASTType (ast, ast->Int128Ty.getAsOpaquePtr()); break; case DW_ATE_signed_char: @@ -838,13 +923,13 @@ ClangASTContext::GetBuiltinTypeForDWARFEncodingAndBitSize (const char *type_name if (streq(type_name, "signed char")) { if (QualTypeMatchesBitSize (bit_size, ast, ast->SignedCharTy)) - return ast->SignedCharTy.getAsOpaquePtr(); + return ClangASTType (ast, ast->SignedCharTy.getAsOpaquePtr()); } } if (QualTypeMatchesBitSize (bit_size, ast, ast->CharTy)) - return ast->CharTy.getAsOpaquePtr(); + return ClangASTType (ast, ast->CharTy.getAsOpaquePtr()); if (QualTypeMatchesBitSize (bit_size, ast, ast->SignedCharTy)) - return ast->SignedCharTy.getAsOpaquePtr(); + return ClangASTType (ast, ast->SignedCharTy.getAsOpaquePtr()); break; case DW_ATE_unsigned: @@ -853,51 +938,51 @@ ClangASTContext::GetBuiltinTypeForDWARFEncodingAndBitSize (const char *type_name if (strstr(type_name, "long long")) { if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedLongLongTy)) - return ast->UnsignedLongLongTy.getAsOpaquePtr(); + return ClangASTType (ast, ast->UnsignedLongLongTy.getAsOpaquePtr()); } else if (strstr(type_name, "long")) { if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedLongTy)) - return ast->UnsignedLongTy.getAsOpaquePtr(); + return ClangASTType (ast, ast->UnsignedLongTy.getAsOpaquePtr()); } else if (strstr(type_name, "short")) { if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedShortTy)) - return ast->UnsignedShortTy.getAsOpaquePtr(); + return ClangASTType (ast, ast->UnsignedShortTy.getAsOpaquePtr()); } else if (strstr(type_name, "char")) { if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedCharTy)) - return ast->UnsignedCharTy.getAsOpaquePtr(); + return ClangASTType (ast, ast->UnsignedCharTy.getAsOpaquePtr()); } else if (strstr(type_name, "int")) { if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedIntTy)) - return ast->UnsignedIntTy.getAsOpaquePtr(); + return ClangASTType (ast, ast->UnsignedIntTy.getAsOpaquePtr()); if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedInt128Ty)) - return ast->UnsignedInt128Ty.getAsOpaquePtr(); + return ClangASTType (ast, ast->UnsignedInt128Ty.getAsOpaquePtr()); } } // We weren't able to match up a type name, just search by size if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedCharTy)) - return ast->UnsignedCharTy.getAsOpaquePtr(); + return ClangASTType (ast, ast->UnsignedCharTy.getAsOpaquePtr()); if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedShortTy)) - return ast->UnsignedShortTy.getAsOpaquePtr(); + return ClangASTType (ast, ast->UnsignedShortTy.getAsOpaquePtr()); if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedIntTy)) - return ast->UnsignedIntTy.getAsOpaquePtr(); + return ClangASTType (ast, ast->UnsignedIntTy.getAsOpaquePtr()); if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedLongTy)) - return ast->UnsignedLongTy.getAsOpaquePtr(); + return ClangASTType (ast, ast->UnsignedLongTy.getAsOpaquePtr()); if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedLongLongTy)) - return ast->UnsignedLongLongTy.getAsOpaquePtr(); + return ClangASTType (ast, ast->UnsignedLongLongTy.getAsOpaquePtr()); if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedInt128Ty)) - return ast->UnsignedInt128Ty.getAsOpaquePtr(); + return ClangASTType (ast, ast->UnsignedInt128Ty.getAsOpaquePtr()); break; case DW_ATE_unsigned_char: if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedCharTy)) - return ast->UnsignedCharTy.getAsOpaquePtr(); + return ClangASTType (ast, ast->UnsignedCharTy.getAsOpaquePtr()); if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedShortTy)) - return ast->UnsignedShortTy.getAsOpaquePtr(); + return ClangASTType (ast, ast->UnsignedShortTy.getAsOpaquePtr()); break; case DW_ATE_imaginary_float: @@ -908,11 +993,11 @@ ClangASTContext::GetBuiltinTypeForDWARFEncodingAndBitSize (const char *type_name { if (streq(type_name, "char16_t")) { - return ast->Char16Ty.getAsOpaquePtr(); + return ClangASTType (ast, ast->Char16Ty.getAsOpaquePtr()); } else if (streq(type_name, "char32_t")) { - return ast->Char32Ty.getAsOpaquePtr(); + return ClangASTType (ast, ast->Char32Ty.getAsOpaquePtr()); } } break; @@ -928,89 +1013,27 @@ ClangASTContext::GetBuiltinTypeForDWARFEncodingAndBitSize (const char *type_name { Host::SystemLog (Host::eSystemLogError, "error: need to add support for DW_TAG_base_type encoded with DW_ATE = 0x%x, bit_size = %u\n", dw_ate, bit_size); } - return NULL; -} - -clang_type_t -ClangASTContext::GetBuiltInType_void(ASTContext *ast) -{ - return ast->VoidTy.getAsOpaquePtr(); + return ClangASTType (); } -clang_type_t -ClangASTContext::GetBuiltInType_bool() -{ - return getASTContext()->BoolTy.getAsOpaquePtr(); -} - -clang_type_t -ClangASTContext::GetBuiltInType_objc_id() -{ - return getASTContext()->getObjCIdType().getAsOpaquePtr(); -} - -lldb::clang_type_t -ClangASTContext::GetBuiltInType_objc_id(clang::ASTContext *ast) -{ - return ast->getObjCIdType().getAsOpaquePtr(); -} - -clang_type_t -ClangASTContext::GetBuiltInType_objc_Class() -{ - return getASTContext()->getObjCClassType().getAsOpaquePtr(); -} - -clang_type_t -ClangASTContext::GetBuiltInType_objc_selector() -{ - return getASTContext()->getObjCSelType().getAsOpaquePtr(); -} - -clang_type_t +ClangASTType ClangASTContext::GetUnknownAnyType(clang::ASTContext *ast) { - return ast->UnknownAnyTy.getAsOpaquePtr(); + if (ast) + return ClangASTType (ast, ast->UnknownAnyTy.getAsOpaquePtr()); + return ClangASTType(); } -clang_type_t +ClangASTType ClangASTContext::GetCStringType (bool is_const) { - QualType char_type(getASTContext()->CharTy); + ASTContext *ast = getASTContext(); + QualType char_type(ast->CharTy); if (is_const) char_type.addConst(); - return getASTContext()->getPointerType(char_type).getAsOpaquePtr(); -} - -clang_type_t -ClangASTContext::GetVoidType() -{ - return GetVoidType(getASTContext()); -} - -clang_type_t -ClangASTContext::GetVoidType(ASTContext *ast) -{ - return ast->VoidTy.getAsOpaquePtr(); -} - -clang_type_t -ClangASTContext::GetVoidPtrType (bool is_const) -{ - return GetVoidPtrType(getASTContext(), is_const); -} - -clang_type_t -ClangASTContext::GetVoidPtrType (ASTContext *ast, bool is_const) -{ - QualType void_ptr_type(ast->VoidPtrTy); - - if (is_const) - void_ptr_type.addConst(); - - return void_ptr_type.getAsOpaquePtr(); + return ClangASTType (ast, ast->getPointerType(char_type).getAsOpaquePtr()); } clang::DeclContext * @@ -1019,21 +1042,20 @@ ClangASTContext::GetTranslationUnitDecl (clang::ASTContext *ast) return ast->getTranslationUnitDecl(); } -clang_type_t +ClangASTType ClangASTContext::CopyType (ASTContext *dst_ast, - ASTContext *src_ast, - clang_type_t clang_type) + ClangASTType src) { FileSystemOptions file_system_options; + ASTContext *src_ast = src.GetASTContext(); FileManager file_manager (file_system_options); ASTImporter importer(*dst_ast, file_manager, *src_ast, file_manager, false); - QualType src (QualType::getFromOpaquePtr(clang_type)); - QualType dst (importer.Import(src)); + QualType dst (importer.Import(src.GetQualType())); - return dst.getAsOpaquePtr(); + return ClangASTType (dst_ast, dst.getAsOpaquePtr()); } @@ -1052,16 +1074,19 @@ ClangASTContext::CopyDecl (ASTContext *dst_ast, } bool -ClangASTContext::AreTypesSame (ASTContext *ast, - clang_type_t type1, - clang_type_t type2, +ClangASTContext::AreTypesSame (ClangASTType type1, + ClangASTType type2, bool ignore_qualifiers) { - if (type1 == type2) + ASTContext *ast = type1.GetASTContext(); + if (ast != type2.GetASTContext()) + return false; + + if (type1.GetOpaqueQualType() == type2.GetOpaqueQualType()) return true; - QualType type1_qual = QualType::getFromOpaquePtr(type1); - QualType type2_qual = QualType::getFromOpaquePtr(type2); + QualType type1_qual = type1.GetQualType(); + QualType type2_qual = type2.GetQualType(); if (ignore_qualifiers) { @@ -1069,74 +1094,37 @@ ClangASTContext::AreTypesSame (ASTContext *ast, type2_qual = type2_qual.getUnqualifiedType(); } - return ast->hasSameType (type1_qual, - type2_qual); -} - -#pragma mark CVR modifiers - -clang_type_t -ClangASTContext::AddConstModifier (clang_type_t clang_type) -{ - if (clang_type) - { - QualType result(QualType::getFromOpaquePtr(clang_type)); - result.addConst(); - return result.getAsOpaquePtr(); - } - return NULL; -} - -clang_type_t -ClangASTContext::AddRestrictModifier (clang_type_t clang_type) -{ - if (clang_type) - { - QualType result(QualType::getFromOpaquePtr(clang_type)); - result.getQualifiers().setRestrict (true); - return result.getAsOpaquePtr(); - } - return NULL; -} - -clang_type_t -ClangASTContext::AddVolatileModifier (clang_type_t clang_type) -{ - if (clang_type) - { - QualType result(QualType::getFromOpaquePtr(clang_type)); - result.getQualifiers().setVolatile (true); - return result.getAsOpaquePtr(); - } - return NULL; + return ast->hasSameType (type1_qual, type2_qual); } -clang_type_t +ClangASTType ClangASTContext::GetTypeForDecl (TagDecl *decl) { // No need to call the getASTContext() accessor (which can create the AST // if it isn't created yet, because we can't have created a decl in this // AST if our AST didn't already exist... - if (m_ast_ap.get()) - return m_ast_ap->getTagDeclType(decl).getAsOpaquePtr(); - return NULL; + ASTContext *ast = m_ast_ap.get(); + if (ast) + return ClangASTType (ast, ast->getTagDeclType(decl).getAsOpaquePtr()); + return ClangASTType(); } -clang_type_t +ClangASTType ClangASTContext::GetTypeForDecl (ObjCInterfaceDecl *decl) { // No need to call the getASTContext() accessor (which can create the AST // if it isn't created yet, because we can't have created a decl in this // AST if our AST didn't already exist... - if (m_ast_ap.get()) - return m_ast_ap->getObjCInterfaceType(decl).getAsOpaquePtr(); - return NULL; + ASTContext *ast = m_ast_ap.get(); + if (ast) + return ClangASTType (ast, ast->getObjCInterfaceType(decl).getAsOpaquePtr()); + return ClangASTType(); } #pragma mark Structure, Unions, Classes -clang_type_t +ClangASTType ClangASTContext::CreateRecordType (DeclContext *decl_ctx, AccessType access_type, const char *name, @@ -1181,9 +1169,9 @@ ClangASTContext::CreateRecordType (DeclContext *decl_ctx, if (decl_ctx) decl_ctx->addDecl (decl); - return ast->getTagDeclType(decl).getAsOpaquePtr(); + return ClangASTType(ast, ast->getTagDeclType(decl).getAsOpaquePtr()); } - return NULL; + return ClangASTType(); } static TemplateParameterList * @@ -1385,85 +1373,16 @@ ClangASTContext::CreateClassTemplateSpecializationDecl (DeclContext *decl_ctx, return class_template_specialization_decl; } -lldb::clang_type_t +ClangASTType ClangASTContext::CreateClassTemplateSpecializationType (ClassTemplateSpecializationDecl *class_template_specialization_decl) { if (class_template_specialization_decl) { ASTContext *ast = getASTContext(); if (ast) - return ast->getTagDeclType(class_template_specialization_decl).getAsOpaquePtr(); - } - return NULL; -} - -bool -ClangASTContext::SetHasExternalStorage (clang_type_t clang_type, bool has_extern) -{ - if (clang_type == NULL) - return false; - - QualType qual_type (QualType::getFromOpaquePtr(clang_type)); - - const clang::Type::TypeClass type_class = qual_type->getTypeClass(); - switch (type_class) - { - case clang::Type::Record: - { - CXXRecordDecl *cxx_record_decl = qual_type->getAsCXXRecordDecl(); - if (cxx_record_decl) - { - cxx_record_decl->setHasExternalLexicalStorage (has_extern); - cxx_record_decl->setHasExternalVisibleStorage (has_extern); - return true; - } - } - break; - - case clang::Type::Enum: - { - EnumDecl *enum_decl = cast<EnumType>(qual_type)->getDecl(); - if (enum_decl) - { - enum_decl->setHasExternalLexicalStorage (has_extern); - enum_decl->setHasExternalVisibleStorage (has_extern); - return true; - } - } - break; - - case clang::Type::ObjCObject: - case clang::Type::ObjCInterface: - { - const ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(qual_type.getTypePtr()); - assert (objc_class_type); - if (objc_class_type) - { - ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface(); - - if (class_interface_decl) - { - class_interface_decl->setHasExternalLexicalStorage (has_extern); - class_interface_decl->setHasExternalVisibleStorage (has_extern); - return true; - } - } - } - break; - - case clang::Type::Typedef: - return ClangASTContext::SetHasExternalStorage (cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr(), has_extern); - - case clang::Type::Elaborated: - return ClangASTContext::SetHasExternalStorage (cast<ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr(), has_extern); - - case clang::Type::Paren: - return ClangASTContext::SetHasExternalStorage (cast<ParenType>(qual_type)->desugar().getAsOpaquePtr(), has_extern); - - default: - break; + return ClangASTType(ast, ast->getTagDeclType(class_template_specialization_decl).getAsOpaquePtr()); } - return false; + return ClangASTType(); } static bool @@ -1722,364 +1641,8 @@ ClangASTContext::CheckOverloadedOperatorKindParameterCount (uint32_t op_kind, ui return false; } -CXXMethodDecl * -ClangASTContext::AddMethodToCXXRecordType -( - ASTContext *ast, - clang_type_t record_opaque_type, - const char *name, - clang_type_t method_opaque_type, - lldb::AccessType access, - bool is_virtual, - bool is_static, - bool is_inline, - bool is_explicit, - bool is_attr_used, - bool is_artificial -) -{ - if (!record_opaque_type || !method_opaque_type || !name) - return NULL; - - assert(ast); - - IdentifierTable *identifier_table = &ast->Idents; - - assert(identifier_table); - - QualType record_qual_type(QualType::getFromOpaquePtr(record_opaque_type)); - - CXXRecordDecl *cxx_record_decl = record_qual_type->getAsCXXRecordDecl(); - - if (cxx_record_decl == NULL) - return NULL; - - QualType method_qual_type (QualType::getFromOpaquePtr (method_opaque_type)); - - CXXMethodDecl *cxx_method_decl = NULL; - - DeclarationName decl_name (&identifier_table->get(name)); - - const clang::FunctionType *function_Type = dyn_cast<FunctionType>(method_qual_type.getTypePtr()); - - if (function_Type == NULL) - return NULL; - - const FunctionProtoType *method_function_prototype (dyn_cast<FunctionProtoType>(function_Type)); - - if (!method_function_prototype) - return NULL; - - unsigned int num_params = method_function_prototype->getNumArgs(); - - CXXDestructorDecl *cxx_dtor_decl(NULL); - CXXConstructorDecl *cxx_ctor_decl(NULL); - - if (is_artificial) - return NULL; // skip everything artificial - - if (name[0] == '~') - { - cxx_dtor_decl = CXXDestructorDecl::Create (*ast, - cxx_record_decl, - SourceLocation(), - DeclarationNameInfo (ast->DeclarationNames.getCXXDestructorName (ast->getCanonicalType (record_qual_type)), SourceLocation()), - method_qual_type, - NULL, - is_inline, - is_artificial); - cxx_method_decl = cxx_dtor_decl; - } - else if (decl_name == cxx_record_decl->getDeclName()) - { - cxx_ctor_decl = CXXConstructorDecl::Create (*ast, - cxx_record_decl, - SourceLocation(), - DeclarationNameInfo (ast->DeclarationNames.getCXXConstructorName (ast->getCanonicalType (record_qual_type)), SourceLocation()), - method_qual_type, - NULL, // TypeSourceInfo * - is_explicit, - is_inline, - is_artificial, - false /*is_constexpr*/); - cxx_method_decl = cxx_ctor_decl; - } - else - { - clang::StorageClass SC = is_static ? SC_Static : SC_None; - OverloadedOperatorKind op_kind = NUM_OVERLOADED_OPERATORS; - - if (IsOperator (name, op_kind)) - { - if (op_kind != NUM_OVERLOADED_OPERATORS) - { - // Check the number of operator parameters. Sometimes we have - // seen bad DWARF that doesn't correctly describe operators and - // if we try to create a methed and add it to the class, clang - // will assert and crash, so we need to make sure things are - // acceptable. - if (!ClangASTContext::CheckOverloadedOperatorKindParameterCount (op_kind, num_params)) - return NULL; - cxx_method_decl = CXXMethodDecl::Create (*ast, - cxx_record_decl, - SourceLocation(), - DeclarationNameInfo (ast->DeclarationNames.getCXXOperatorName (op_kind), SourceLocation()), - method_qual_type, - NULL, // TypeSourceInfo * - SC, - is_inline, - false /*is_constexpr*/, - SourceLocation()); - } - else if (num_params == 0) - { - // Conversion operators don't take params... - cxx_method_decl = CXXConversionDecl::Create (*ast, - cxx_record_decl, - SourceLocation(), - DeclarationNameInfo (ast->DeclarationNames.getCXXConversionFunctionName (ast->getCanonicalType (function_Type->getResultType())), SourceLocation()), - method_qual_type, - NULL, // TypeSourceInfo * - is_inline, - is_explicit, - false /*is_constexpr*/, - SourceLocation()); - } - } - - if (cxx_method_decl == NULL) - { - cxx_method_decl = CXXMethodDecl::Create (*ast, - cxx_record_decl, - SourceLocation(), - DeclarationNameInfo (decl_name, SourceLocation()), - method_qual_type, - NULL, // TypeSourceInfo * - SC, - is_inline, - false /*is_constexpr*/, - SourceLocation()); - } - } - - AccessSpecifier access_specifier = ConvertAccessTypeToAccessSpecifier (access); - - cxx_method_decl->setAccess (access_specifier); - cxx_method_decl->setVirtualAsWritten (is_virtual); - - if (is_attr_used) - cxx_method_decl->addAttr(::new (*ast) UsedAttr(SourceRange(), *ast)); - - // Populate the method decl with parameter decls - - llvm::SmallVector<ParmVarDecl *, 12> params; - - for (unsigned param_index = 0; - param_index < num_params; - ++param_index) - { - params.push_back (ParmVarDecl::Create (*ast, - cxx_method_decl, - SourceLocation(), - SourceLocation(), - NULL, // anonymous - method_function_prototype->getArgType(param_index), - NULL, - SC_None, - NULL)); - } - - cxx_method_decl->setParams (ArrayRef<ParmVarDecl*>(params)); - - cxx_record_decl->addDecl (cxx_method_decl); - - // Sometimes the debug info will mention a constructor (default/copy/move), - // destructor, or assignment operator (copy/move) but there won't be any - // version of this in the code. So we check if the function was artificially - // generated and if it is trivial and this lets the compiler/backend know - // that it can inline the IR for these when it needs to and we can avoid a - // "missing function" error when running expressions. - - if (is_artificial) - { - if (cxx_ctor_decl && - ((cxx_ctor_decl->isDefaultConstructor() && cxx_record_decl->hasTrivialDefaultConstructor ()) || - (cxx_ctor_decl->isCopyConstructor() && cxx_record_decl->hasTrivialCopyConstructor ()) || - (cxx_ctor_decl->isMoveConstructor() && cxx_record_decl->hasTrivialMoveConstructor ()) )) - { - cxx_ctor_decl->setDefaulted(); - cxx_ctor_decl->setTrivial(true); - } - else if (cxx_dtor_decl) - { - if (cxx_record_decl->hasTrivialDestructor()) - { - cxx_dtor_decl->setDefaulted(); - cxx_dtor_decl->setTrivial(true); - } - } - else if ((cxx_method_decl->isCopyAssignmentOperator() && cxx_record_decl->hasTrivialCopyAssignment()) || - (cxx_method_decl->isMoveAssignmentOperator() && cxx_record_decl->hasTrivialMoveAssignment())) - { - cxx_method_decl->setDefaulted(); - cxx_method_decl->setTrivial(true); - } - } - -#ifdef LLDB_CONFIGURATION_DEBUG - VerifyDecl(cxx_method_decl); -#endif - -// printf ("decl->isPolymorphic() = %i\n", cxx_record_decl->isPolymorphic()); -// printf ("decl->isAggregate() = %i\n", cxx_record_decl->isAggregate()); -// printf ("decl->isPOD() = %i\n", cxx_record_decl->isPOD()); -// printf ("decl->isEmpty() = %i\n", cxx_record_decl->isEmpty()); -// printf ("decl->isAbstract() = %i\n", cxx_record_decl->isAbstract()); -// printf ("decl->hasTrivialConstructor() = %i\n", cxx_record_decl->hasTrivialConstructor()); -// printf ("decl->hasTrivialCopyConstructor() = %i\n", cxx_record_decl->hasTrivialCopyConstructor()); -// printf ("decl->hasTrivialCopyAssignment() = %i\n", cxx_record_decl->hasTrivialCopyAssignment()); -// printf ("decl->hasTrivialDestructor() = %i\n", cxx_record_decl->hasTrivialDestructor()); - return cxx_method_decl; -} - -clang::FieldDecl * -ClangASTContext::AddFieldToRecordType -( - ASTContext *ast, - clang_type_t record_clang_type, - const char *name, - clang_type_t field_type, - AccessType access, - uint32_t bitfield_bit_size -) -{ - if (record_clang_type == NULL || field_type == NULL) - return NULL; - - FieldDecl *field = NULL; - IdentifierTable *identifier_table = &ast->Idents; - - assert (ast != NULL); - assert (identifier_table != NULL); - - QualType record_qual_type(QualType::getFromOpaquePtr(record_clang_type)); - - const clang::Type *clang_type = record_qual_type.getTypePtr(); - if (clang_type) - { - const RecordType *record_type = dyn_cast<RecordType>(clang_type); - - if (record_type) - { - RecordDecl *record_decl = record_type->getDecl(); - - clang::Expr *bit_width = NULL; - if (bitfield_bit_size != 0) - { - APInt bitfield_bit_size_apint(ast->getTypeSize(ast->IntTy), bitfield_bit_size); - bit_width = new (*ast)IntegerLiteral (*ast, bitfield_bit_size_apint, ast->IntTy, SourceLocation()); - } - field = FieldDecl::Create (*ast, - record_decl, - SourceLocation(), - SourceLocation(), - name ? &identifier_table->get(name) : NULL, // Identifier - QualType::getFromOpaquePtr(field_type), // Field type - NULL, // TInfo * - bit_width, // BitWidth - false, // Mutable - ICIS_NoInit); // HasInit - - if (!name) { - // Determine whether this field corresponds to an anonymous - // struct or union. - if (const TagType *TagT = field->getType()->getAs<TagType>()) { - if (RecordDecl *Rec = dyn_cast<RecordDecl>(TagT->getDecl())) - if (!Rec->getDeclName()) { - Rec->setAnonymousStructOrUnion(true); - field->setImplicit(); - - } - } - } - - if (field) - { - field->setAccess (ConvertAccessTypeToAccessSpecifier (access)); - - record_decl->addDecl(field); - -#ifdef LLDB_CONFIGURATION_DEBUG - VerifyDecl(field); -#endif - } - } - else - { - const ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(clang_type); - if (objc_class_type) - { - bool is_synthesized = false; - field = ClangASTContext::AddObjCClassIVar (ast, - record_clang_type, - name, - field_type, - access, - bitfield_bit_size, - is_synthesized); - } - } - } - return field; -} - -clang::VarDecl * -ClangASTContext::AddVariableToRecordType (clang::ASTContext *ast, - lldb::clang_type_t record_opaque_type, - const char *name, - lldb::clang_type_t var_type, - AccessType access) -{ - clang::VarDecl *var_decl = NULL; - - if (record_opaque_type == NULL || var_type == NULL) - return NULL; - - IdentifierTable *identifier_table = &ast->Idents; - - assert (ast != NULL); - assert (identifier_table != NULL); - - const RecordType *record_type = dyn_cast<RecordType>(QualType::getFromOpaquePtr(record_opaque_type).getTypePtr()); - - if (record_type) - { - RecordDecl *record_decl = record_type->getDecl(); - - var_decl = VarDecl::Create (*ast, // ASTContext & - record_decl, // DeclContext * - SourceLocation(), // SourceLocation StartLoc - SourceLocation(), // SourceLocation IdLoc - name ? &identifier_table->get(name) : NULL, // IdentifierInfo * - QualType::getFromOpaquePtr(var_type), // Variable QualType - NULL, // TypeSourceInfo * - SC_Static); // StorageClass - if (var_decl) - { - var_decl->setAccess(ConvertAccessTypeToAccessSpecifier (access)); - record_decl->addDecl(var_decl); - -#ifdef LLDB_CONFIGURATION_DEBUG - VerifyDecl(var_decl); -#endif - } - } - return var_decl; -} - - -static clang::AccessSpecifier UnifyAccessSpecifiers (clang::AccessSpecifier lhs, - clang::AccessSpecifier rhs) +clang::AccessSpecifier +ClangASTContext::UnifyAccessSpecifiers (clang::AccessSpecifier lhs, clang::AccessSpecifier rhs) { clang::AccessSpecifier ret = lhs; @@ -2102,115 +1665,6 @@ static clang::AccessSpecifier UnifyAccessSpecifiers (clang::AccessSpecifier lhs, return ret; } -void -ClangASTContext::BuildIndirectFields (clang::ASTContext *ast, - lldb::clang_type_t record_clang_type) -{ - QualType record_qual_type(QualType::getFromOpaquePtr(record_clang_type)); - - const RecordType *record_type = record_qual_type->getAs<RecordType>(); - - if (!record_type) - return; - - RecordDecl *record_decl = record_type->getDecl(); - - if (!record_decl) - return; - - typedef llvm::SmallVector <IndirectFieldDecl *, 1> IndirectFieldVector; - - IndirectFieldVector indirect_fields; - RecordDecl::field_iterator field_pos; - RecordDecl::field_iterator field_end_pos = record_decl->field_end(); - RecordDecl::field_iterator last_field_pos = field_end_pos; - for (field_pos = record_decl->field_begin(); field_pos != field_end_pos; last_field_pos = field_pos++) - { - if (field_pos->isAnonymousStructOrUnion()) - { - QualType field_qual_type = field_pos->getType(); - - const RecordType *field_record_type = field_qual_type->getAs<RecordType>(); - - if (!field_record_type) - continue; - - RecordDecl *field_record_decl = field_record_type->getDecl(); - - if (!field_record_decl) - continue; - - for (RecordDecl::decl_iterator di = field_record_decl->decls_begin(), de = field_record_decl->decls_end(); - di != de; - ++di) - { - if (FieldDecl *nested_field_decl = dyn_cast<FieldDecl>(*di)) - { - NamedDecl **chain = new (*ast) NamedDecl*[2]; - chain[0] = *field_pos; - chain[1] = nested_field_decl; - IndirectFieldDecl *indirect_field = IndirectFieldDecl::Create(*ast, - record_decl, - SourceLocation(), - nested_field_decl->getIdentifier(), - nested_field_decl->getType(), - chain, - 2); - - indirect_field->setAccess(UnifyAccessSpecifiers(field_pos->getAccess(), - nested_field_decl->getAccess())); - - indirect_fields.push_back(indirect_field); - } - else if (IndirectFieldDecl *nested_indirect_field_decl = dyn_cast<IndirectFieldDecl>(*di)) - { - int nested_chain_size = nested_indirect_field_decl->getChainingSize(); - NamedDecl **chain = new (*ast) NamedDecl*[nested_chain_size + 1]; - chain[0] = *field_pos; - - int chain_index = 1; - for (IndirectFieldDecl::chain_iterator nci = nested_indirect_field_decl->chain_begin(), - nce = nested_indirect_field_decl->chain_end(); - nci < nce; - ++nci) - { - chain[chain_index] = *nci; - chain_index++; - } - - IndirectFieldDecl *indirect_field = IndirectFieldDecl::Create(*ast, - record_decl, - SourceLocation(), - nested_indirect_field_decl->getIdentifier(), - nested_indirect_field_decl->getType(), - chain, - nested_chain_size + 1); - - indirect_field->setAccess(UnifyAccessSpecifiers(field_pos->getAccess(), - nested_indirect_field_decl->getAccess())); - - indirect_fields.push_back(indirect_field); - } - } - } - } - - // Check the last field to see if it has an incomplete array type as its - // last member and if it does, the tell the record decl about it - if (last_field_pos != field_end_pos) - { - if (last_field_pos->getType()->isIncompleteArrayType()) - record_decl->hasFlexibleArrayMember(); - } - - for (IndirectFieldVector::iterator ifi = indirect_fields.begin(), ife = indirect_fields.end(); - ifi < ife; - ++ifi) - { - record_decl->addDecl(*ifi); - } -} - bool ClangASTContext::FieldIsBitfield (FieldDecl* field, uint32_t& bitfield_bit_size) { @@ -2270,76 +1724,9 @@ ClangASTContext::RecordHasFields (const RecordDecl *record_decl) return false; } -void -ClangASTContext::SetDefaultAccessForRecordFields (clang_type_t clang_type, int default_accessibility, int *assigned_accessibilities, size_t num_assigned_accessibilities) -{ - if (clang_type) - { - QualType qual_type(QualType::getFromOpaquePtr(clang_type)); - - const RecordType *record_type = dyn_cast<RecordType>(qual_type.getTypePtr()); - if (record_type) - { - RecordDecl *record_decl = record_type->getDecl(); - if (record_decl) - { - uint32_t field_idx; - RecordDecl::field_iterator field, field_end; - for (field = record_decl->field_begin(), field_end = record_decl->field_end(), field_idx = 0; - field != field_end; - ++field, ++field_idx) - { - // If no accessibility was assigned, assign the correct one - if (field_idx < num_assigned_accessibilities && assigned_accessibilities[field_idx] == clang::AS_none) - field->setAccess ((AccessSpecifier)default_accessibility); - } - } - } - } -} - -#pragma mark C++ Base Classes - -CXXBaseSpecifier * -ClangASTContext::CreateBaseClassSpecifier (clang_type_t base_class_type, AccessType access, bool is_virtual, bool base_of_class) -{ - if (base_class_type) - return new CXXBaseSpecifier (SourceRange(), - is_virtual, - base_of_class, - ConvertAccessTypeToAccessSpecifier (access), - getASTContext()->getTrivialTypeSourceInfo (QualType::getFromOpaquePtr(base_class_type)), - SourceLocation()); - return NULL; -} - -void -ClangASTContext::DeleteBaseClassSpecifiers (CXXBaseSpecifier **base_classes, unsigned num_base_classes) -{ - for (unsigned i=0; i<num_base_classes; ++i) - { - delete base_classes[i]; - base_classes[i] = NULL; - } -} - -bool -ClangASTContext::SetBaseClassesForClassType (clang_type_t class_clang_type, CXXBaseSpecifier const * const *base_classes, unsigned num_base_classes) -{ - if (class_clang_type) - { - CXXRecordDecl *cxx_record_decl = QualType::getFromOpaquePtr(class_clang_type)->getAsCXXRecordDecl(); - if (cxx_record_decl) - { - cxx_record_decl->setBases(base_classes, num_base_classes); - return true; - } - } - return false; -} #pragma mark Objective C Classes -clang_type_t +ClangASTType ClangASTContext::CreateObjCClass ( const char *name, @@ -2355,11 +1742,6 @@ ClangASTContext::CreateObjCClass if (decl_ctx == NULL) decl_ctx = ast->getTranslationUnitDecl(); - // NOTE: Eventually CXXRecordDecl will be merged back into RecordDecl and - // we will need to update this code. I was told to currently always use - // the CXXRecordDecl class since we often don't know from debug information - // if something is struct or a class, so we default to always use the more - // complete definition just in case. ObjCInterfaceDecl *decl = ObjCInterfaceDecl::Create (*ast, decl_ctx, SourceLocation(), @@ -2372,2286 +1754,7 @@ ClangASTContext::CreateObjCClass if (decl && metadata) SetMetadata(ast, decl, *metadata); - return ast->getObjCInterfaceType(decl).getAsOpaquePtr(); -} - -bool -ClangASTContext::SetObjCSuperClass (clang_type_t class_opaque_type, clang_type_t super_opaque_type) -{ - if (class_opaque_type && super_opaque_type) - { - QualType class_qual_type(QualType::getFromOpaquePtr(class_opaque_type)); - QualType super_qual_type(QualType::getFromOpaquePtr(super_opaque_type)); - const clang::Type *class_type = class_qual_type.getTypePtr(); - const clang::Type *super_type = super_qual_type.getTypePtr(); - if (class_type && super_type) - { - const ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(class_type); - const ObjCObjectType *objc_super_type = dyn_cast<ObjCObjectType>(super_type); - if (objc_class_type && objc_super_type) - { - ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface(); - ObjCInterfaceDecl *super_interface_decl = objc_super_type->getInterface(); - if (class_interface_decl && super_interface_decl) - { - class_interface_decl->setSuperClass(super_interface_decl); - return true; - } - } - } - } - return false; -} - - -FieldDecl * -ClangASTContext::AddObjCClassIVar -( - ASTContext *ast, - clang_type_t class_opaque_type, - const char *name, - clang_type_t ivar_opaque_type, - AccessType access, - uint32_t bitfield_bit_size, - bool is_synthesized -) -{ - if (class_opaque_type == NULL || ivar_opaque_type == NULL) - return NULL; - - ObjCIvarDecl *field = NULL; - - IdentifierTable *identifier_table = &ast->Idents; - - assert (ast != NULL); - assert (identifier_table != NULL); - - QualType class_qual_type(QualType::getFromOpaquePtr(class_opaque_type)); - - const clang::Type *class_type = class_qual_type.getTypePtr(); - if (class_type) - { - const ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(class_type); - - if (objc_class_type) - { - ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface(); - - if (class_interface_decl) - { - clang::Expr *bit_width = NULL; - if (bitfield_bit_size != 0) - { - APInt bitfield_bit_size_apint(ast->getTypeSize(ast->IntTy), bitfield_bit_size); - bit_width = new (*ast)IntegerLiteral (*ast, bitfield_bit_size_apint, ast->IntTy, SourceLocation()); - } - - field = ObjCIvarDecl::Create (*ast, - class_interface_decl, - SourceLocation(), - SourceLocation(), - name ? &identifier_table->get(name) : NULL, // Identifier - QualType::getFromOpaquePtr(ivar_opaque_type), // Field type - NULL, // TypeSourceInfo * - ConvertAccessTypeToObjCIvarAccessControl (access), - bit_width, - is_synthesized); - - if (field) - { - class_interface_decl->addDecl(field); - -#ifdef LLDB_CONFIGURATION_DEBUG - VerifyDecl(field); -#endif - - return field; - } - } - } - } - return NULL; -} - -bool -ClangASTContext::AddObjCClassProperty -( - ASTContext *ast, - clang_type_t class_opaque_type, - const char *property_name, - clang_type_t property_opaque_type, - ObjCIvarDecl *ivar_decl, - const char *property_setter_name, - const char *property_getter_name, - uint32_t property_attributes, - ClangASTMetadata *metadata -) -{ - if (class_opaque_type == NULL || property_name == NULL || property_name[0] == '\0') - return false; - - IdentifierTable *identifier_table = &ast->Idents; - - assert (ast != NULL); - assert (identifier_table != NULL); - - QualType class_qual_type(QualType::getFromOpaquePtr(class_opaque_type)); - const clang::Type *class_type = class_qual_type.getTypePtr(); - if (class_type) - { - const ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(class_type); - - if (objc_class_type) - { - ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface(); - - clang_type_t property_opaque_type_to_access = NULL; - - if (property_opaque_type) - property_opaque_type_to_access = property_opaque_type; - else if (ivar_decl) - property_opaque_type_to_access = ivar_decl->getType().getAsOpaquePtr(); - - if (class_interface_decl && property_opaque_type_to_access) - { - clang::TypeSourceInfo *prop_type_source; - if (ivar_decl) - prop_type_source = ast->getTrivialTypeSourceInfo (ivar_decl->getType()); - else - prop_type_source = ast->getTrivialTypeSourceInfo (QualType::getFromOpaquePtr(property_opaque_type)); - - ObjCPropertyDecl *property_decl = ObjCPropertyDecl::Create(*ast, - class_interface_decl, - SourceLocation(), // Source Location - &identifier_table->get(property_name), - SourceLocation(), //Source Location for AT - SourceLocation(), //Source location for ( - prop_type_source - ); - - if (property_decl) - { - if (metadata) - SetMetadata(ast, property_decl, *metadata); - - class_interface_decl->addDecl (property_decl); - - Selector setter_sel, getter_sel; - - if (property_setter_name != NULL) - { - std::string property_setter_no_colon(property_setter_name, strlen(property_setter_name) - 1); - clang::IdentifierInfo *setter_ident = &identifier_table->get(property_setter_no_colon.c_str()); - setter_sel = ast->Selectors.getSelector(1, &setter_ident); - } - else if (!(property_attributes & DW_APPLE_PROPERTY_readonly)) - { - std::string setter_sel_string("set"); - setter_sel_string.push_back(::toupper(property_name[0])); - setter_sel_string.append(&property_name[1]); - clang::IdentifierInfo *setter_ident = &identifier_table->get(setter_sel_string.c_str()); - setter_sel = ast->Selectors.getSelector(1, &setter_ident); - } - property_decl->setSetterName(setter_sel); - property_decl->setPropertyAttributes (clang::ObjCPropertyDecl::OBJC_PR_setter); - - if (property_getter_name != NULL) - { - clang::IdentifierInfo *getter_ident = &identifier_table->get(property_getter_name); - getter_sel = ast->Selectors.getSelector(0, &getter_ident); - } - else - { - clang::IdentifierInfo *getter_ident = &identifier_table->get(property_name); - getter_sel = ast->Selectors.getSelector(0, &getter_ident); - } - property_decl->setGetterName(getter_sel); - property_decl->setPropertyAttributes (clang::ObjCPropertyDecl::OBJC_PR_getter); - - if (ivar_decl) - property_decl->setPropertyIvarDecl (ivar_decl); - - if (property_attributes & DW_APPLE_PROPERTY_readonly) - property_decl->setPropertyAttributes (clang::ObjCPropertyDecl::OBJC_PR_readonly); - if (property_attributes & DW_APPLE_PROPERTY_readwrite) - property_decl->setPropertyAttributes (clang::ObjCPropertyDecl::OBJC_PR_readwrite); - if (property_attributes & DW_APPLE_PROPERTY_assign) - property_decl->setPropertyAttributes (clang::ObjCPropertyDecl::OBJC_PR_assign); - if (property_attributes & DW_APPLE_PROPERTY_retain) - property_decl->setPropertyAttributes (clang::ObjCPropertyDecl::OBJC_PR_retain); - if (property_attributes & DW_APPLE_PROPERTY_copy) - property_decl->setPropertyAttributes (clang::ObjCPropertyDecl::OBJC_PR_copy); - if (property_attributes & DW_APPLE_PROPERTY_nonatomic) - property_decl->setPropertyAttributes (clang::ObjCPropertyDecl::OBJC_PR_nonatomic); - - if (!getter_sel.isNull() && !class_interface_decl->lookupInstanceMethod(getter_sel)) - { - QualType result_type = QualType::getFromOpaquePtr(property_opaque_type_to_access); - - const bool isInstance = true; - const bool isVariadic = false; - const bool isSynthesized = false; - const bool isImplicitlyDeclared = true; - const bool isDefined = false; - const ObjCMethodDecl::ImplementationControl impControl = ObjCMethodDecl::None; - const bool HasRelatedResultType = false; - - ObjCMethodDecl *getter = ObjCMethodDecl::Create(*ast, - SourceLocation(), - SourceLocation(), - getter_sel, - result_type, - NULL, - class_interface_decl, - isInstance, - isVariadic, - isSynthesized, - isImplicitlyDeclared, - isDefined, - impControl, - HasRelatedResultType); - - if (getter && metadata) - SetMetadata(ast, getter, *metadata); - - getter->setMethodParams(*ast, ArrayRef<ParmVarDecl*>(), ArrayRef<SourceLocation>()); - - class_interface_decl->addDecl(getter); - } - - if (!setter_sel.isNull() && !class_interface_decl->lookupInstanceMethod(setter_sel)) - { - QualType result_type = ast->VoidTy; - - const bool isInstance = true; - const bool isVariadic = false; - const bool isSynthesized = false; - const bool isImplicitlyDeclared = true; - const bool isDefined = false; - const ObjCMethodDecl::ImplementationControl impControl = ObjCMethodDecl::None; - const bool HasRelatedResultType = false; - - ObjCMethodDecl *setter = ObjCMethodDecl::Create(*ast, - SourceLocation(), - SourceLocation(), - setter_sel, - result_type, - NULL, - class_interface_decl, - isInstance, - isVariadic, - isSynthesized, - isImplicitlyDeclared, - isDefined, - impControl, - HasRelatedResultType); - - if (setter && metadata) - SetMetadata(ast, setter, *metadata); - - llvm::SmallVector<ParmVarDecl *, 1> params; - - params.push_back (ParmVarDecl::Create (*ast, - setter, - SourceLocation(), - SourceLocation(), - NULL, // anonymous - QualType::getFromOpaquePtr(property_opaque_type_to_access), - NULL, - SC_Auto, - NULL)); - - setter->setMethodParams(*ast, ArrayRef<ParmVarDecl*>(params), ArrayRef<SourceLocation>()); - - class_interface_decl->addDecl(setter); - } - - return true; - } - } - } - } - return false; -} - -bool -ClangASTContext::ObjCTypeHasIVars (clang_type_t class_opaque_type, bool check_superclass) -{ - QualType class_qual_type(QualType::getFromOpaquePtr(class_opaque_type)); - - const clang::Type *class_type = class_qual_type.getTypePtr(); - if (class_type) - { - const ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(class_type); - - if (objc_class_type) - return ObjCDeclHasIVars (objc_class_type->getInterface(), check_superclass); - } - return false; -} - -bool -ClangASTContext::ObjCDeclHasIVars (ObjCInterfaceDecl *class_interface_decl, bool check_superclass) -{ - while (class_interface_decl) - { - if (class_interface_decl->ivar_size() > 0) - return true; - - if (check_superclass) - class_interface_decl = class_interface_decl->getSuperClass(); - else - break; - } - return false; -} - -ObjCMethodDecl * -ClangASTContext::AddMethodToObjCObjectType (ASTContext *ast, - clang_type_t class_opaque_type, - const char *name, // the full symbol name as seen in the symbol table ("-[NString stringWithCString:]") - clang_type_t method_opaque_type, - lldb::AccessType access, - bool is_artificial) -{ - if (class_opaque_type == NULL || method_opaque_type == NULL) - return NULL; - - IdentifierTable *identifier_table = &ast->Idents; - - assert (ast != NULL); - assert (identifier_table != NULL); - - QualType class_qual_type(QualType::getFromOpaquePtr(class_opaque_type)); - - const clang::Type *class_type = class_qual_type.getTypePtr(); - if (class_type == NULL) - return NULL; - - const ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(class_type); - - if (objc_class_type == NULL) - return NULL; - - ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface(); - - if (class_interface_decl == NULL) - return NULL; - - const char *selector_start = ::strchr (name, ' '); - if (selector_start == NULL) - return NULL; - - selector_start++; - llvm::SmallVector<IdentifierInfo *, 12> selector_idents; - - size_t len = 0; - const char *start; - //printf ("name = '%s'\n", name); - - unsigned num_selectors_with_args = 0; - for (start = selector_start; - start && *start != '\0' && *start != ']'; - start += len) - { - len = ::strcspn(start, ":]"); - bool has_arg = (start[len] == ':'); - if (has_arg) - ++num_selectors_with_args; - selector_idents.push_back (&identifier_table->get (StringRef (start, len))); - if (has_arg) - len += 1; - } - - - if (selector_idents.size() == 0) - return 0; - - clang::Selector method_selector = ast->Selectors.getSelector (num_selectors_with_args ? selector_idents.size() : 0, - selector_idents.data()); - - QualType method_qual_type (QualType::getFromOpaquePtr (method_opaque_type)); - - // Populate the method decl with parameter decls - const clang::Type *method_type(method_qual_type.getTypePtr()); - - if (method_type == NULL) - return NULL; - - const FunctionProtoType *method_function_prototype (dyn_cast<FunctionProtoType>(method_type)); - - if (!method_function_prototype) - return NULL; - - - bool is_variadic = false; - bool is_synthesized = false; - bool is_defined = false; - ObjCMethodDecl::ImplementationControl imp_control = ObjCMethodDecl::None; - - const unsigned num_args = method_function_prototype->getNumArgs(); - - if (num_args != num_selectors_with_args) - return NULL; // some debug information is corrupt. We are not going to deal with it. - - ObjCMethodDecl *objc_method_decl = ObjCMethodDecl::Create (*ast, - SourceLocation(), // beginLoc, - SourceLocation(), // endLoc, - method_selector, - method_function_prototype->getResultType(), - NULL, // TypeSourceInfo *ResultTInfo, - GetDeclContextForType (class_opaque_type), - name[0] == '-', - is_variadic, - is_synthesized, - true, // is_implicitly_declared; we force this to true because we don't have source locations - is_defined, - imp_control, - false /*has_related_result_type*/); - - - if (objc_method_decl == NULL) - return NULL; - - if (num_args > 0) - { - llvm::SmallVector<ParmVarDecl *, 12> params; - - for (unsigned param_index = 0; param_index < num_args; ++param_index) - { - params.push_back (ParmVarDecl::Create (*ast, - objc_method_decl, - SourceLocation(), - SourceLocation(), - NULL, // anonymous - method_function_prototype->getArgType(param_index), - NULL, - SC_Auto, - NULL)); - } - - objc_method_decl->setMethodParams(*ast, ArrayRef<ParmVarDecl*>(params), ArrayRef<SourceLocation>()); - } - - class_interface_decl->addDecl (objc_method_decl); - -#ifdef LLDB_CONFIGURATION_DEBUG - VerifyDecl(objc_method_decl); -#endif - - return objc_method_decl; -} - -size_t -ClangASTContext::GetNumTemplateArguments (clang::ASTContext *ast, clang_type_t clang_type) -{ - if (clang_type) - { - QualType qual_type (QualType::getFromOpaquePtr(clang_type)); - - const clang::Type::TypeClass type_class = qual_type->getTypeClass(); - switch (type_class) - { - case clang::Type::Record: - if (GetCompleteQualType (ast, qual_type)) - { - const CXXRecordDecl *cxx_record_decl = qual_type->getAsCXXRecordDecl(); - if (cxx_record_decl) - { - const ClassTemplateSpecializationDecl *template_decl = dyn_cast<ClassTemplateSpecializationDecl>(cxx_record_decl); - if (template_decl) - return template_decl->getTemplateArgs().size(); - } - } - break; - - case clang::Type::Typedef: - return ClangASTContext::GetNumTemplateArguments (ast, cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr()); - - case clang::Type::Elaborated: - return ClangASTContext::GetNumTemplateArguments (ast, cast<ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr()); - - case clang::Type::Paren: - return ClangASTContext::GetNumTemplateArguments(ast, cast<ParenType>(qual_type)->desugar().getAsOpaquePtr()); - - default: - break; - } - } - return 0; -} - -clang_type_t -ClangASTContext::GetTemplateArgument (clang::ASTContext *ast, clang_type_t clang_type, size_t arg_idx, lldb::TemplateArgumentKind &kind) -{ - if (clang_type) - { - QualType qual_type (QualType::getFromOpaquePtr(clang_type)); - - const clang::Type::TypeClass type_class = qual_type->getTypeClass(); - switch (type_class) - { - case clang::Type::Record: - if (GetCompleteQualType (ast, qual_type)) - { - const CXXRecordDecl *cxx_record_decl = qual_type->getAsCXXRecordDecl(); - if (cxx_record_decl) - { - const ClassTemplateSpecializationDecl *template_decl = dyn_cast<ClassTemplateSpecializationDecl>(cxx_record_decl); - if (template_decl && arg_idx < template_decl->getTemplateArgs().size()) - { - const TemplateArgument &template_arg = template_decl->getTemplateArgs()[arg_idx]; - switch (template_arg.getKind()) - { - case clang::TemplateArgument::Null: - kind = eTemplateArgumentKindNull; - return NULL; - - case clang::TemplateArgument::Type: - kind = eTemplateArgumentKindType; - return template_arg.getAsType().getAsOpaquePtr(); - - case clang::TemplateArgument::Declaration: - kind = eTemplateArgumentKindDeclaration; - return NULL; - - case clang::TemplateArgument::Integral: - kind = eTemplateArgumentKindIntegral; - return template_arg.getIntegralType().getAsOpaquePtr(); - - case clang::TemplateArgument::Template: - kind = eTemplateArgumentKindTemplate; - return NULL; - - case clang::TemplateArgument::TemplateExpansion: - kind = eTemplateArgumentKindTemplateExpansion; - return NULL; - - case clang::TemplateArgument::Expression: - kind = eTemplateArgumentKindExpression; - return NULL; - - case clang::TemplateArgument::Pack: - kind = eTemplateArgumentKindPack; - return NULL; - - default: - assert (!"Unhandled TemplateArgument::ArgKind"); - kind = eTemplateArgumentKindNull; - return NULL; - } - } - } - } - break; - - case clang::Type::Typedef: - return ClangASTContext::GetTemplateArgument (ast, cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr(), arg_idx, kind); - - case clang::Type::Elaborated: - return ClangASTContext::GetTemplateArgument (ast, cast<ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr(), arg_idx, kind); - - case clang::Type::Paren: - return ClangASTContext::GetTemplateArgument(ast, cast<ParenType>(qual_type)->desugar().getAsOpaquePtr(), arg_idx, kind); - - default: - break; - } - } - kind = eTemplateArgumentKindNull; - return NULL; -} - -uint32_t -ClangASTContext::GetTypeInfo -( - clang_type_t clang_type, - clang::ASTContext *ast, - clang_type_t *pointee_or_element_clang_type -) -{ - if (clang_type == NULL) - return 0; - - if (pointee_or_element_clang_type) - *pointee_or_element_clang_type = NULL; - - QualType qual_type (QualType::getFromOpaquePtr(clang_type)); - - const clang::Type::TypeClass type_class = qual_type->getTypeClass(); - switch (type_class) - { - case clang::Type::Builtin: - { - const BuiltinType *builtin_type = dyn_cast<BuiltinType>(qual_type->getCanonicalTypeInternal()); - - uint32_t builtin_type_flags = eTypeIsBuiltIn | eTypeHasValue; - switch (builtin_type->getKind()) - { - case clang::BuiltinType::ObjCId: - case clang::BuiltinType::ObjCClass: - if (ast && pointee_or_element_clang_type) - *pointee_or_element_clang_type = ast->ObjCBuiltinClassTy.getAsOpaquePtr(); - builtin_type_flags |= eTypeIsPointer | eTypeIsObjC; - break; - - case clang::BuiltinType::ObjCSel: - if (ast && pointee_or_element_clang_type) - *pointee_or_element_clang_type = ast->CharTy.getAsOpaquePtr(); - builtin_type_flags |= eTypeIsPointer | eTypeIsObjC; - break; - - case clang::BuiltinType::Bool: - case clang::BuiltinType::Char_U: - case clang::BuiltinType::UChar: - case clang::BuiltinType::WChar_U: - case clang::BuiltinType::Char16: - case clang::BuiltinType::Char32: - case clang::BuiltinType::UShort: - case clang::BuiltinType::UInt: - case clang::BuiltinType::ULong: - case clang::BuiltinType::ULongLong: - case clang::BuiltinType::UInt128: - case clang::BuiltinType::Char_S: - case clang::BuiltinType::SChar: - case clang::BuiltinType::WChar_S: - case clang::BuiltinType::Short: - case clang::BuiltinType::Int: - case clang::BuiltinType::Long: - case clang::BuiltinType::LongLong: - case clang::BuiltinType::Int128: - case clang::BuiltinType::Float: - case clang::BuiltinType::Double: - case clang::BuiltinType::LongDouble: - builtin_type_flags |= eTypeIsScalar; - if (builtin_type->isInteger()) - { - builtin_type_flags |= eTypeIsInteger; - if (builtin_type->isSignedInteger()) - builtin_type_flags |= eTypeIsSigned; - } - else if (builtin_type->isFloatingPoint()) - builtin_type_flags |= eTypeIsFloat; - break; - default: - break; - } - return builtin_type_flags; - } - - case clang::Type::BlockPointer: - if (pointee_or_element_clang_type) - *pointee_or_element_clang_type = qual_type->getPointeeType().getAsOpaquePtr(); - return eTypeIsPointer | eTypeHasChildren | eTypeIsBlock; - - case clang::Type::Complex: - { - uint32_t complex_type_flags = eTypeIsBuiltIn | eTypeHasValue | eTypeIsComplex; - const ComplexType *complex_type = dyn_cast<ComplexType>(qual_type->getCanonicalTypeInternal()); - if (complex_type) - { - QualType complex_element_type (complex_type->getElementType()); - if (complex_element_type->isIntegerType()) - complex_type_flags |= eTypeIsFloat; - else if (complex_element_type->isFloatingType()) - complex_type_flags |= eTypeIsInteger; - } - return complex_type_flags; - } - break; - - case clang::Type::ConstantArray: - case clang::Type::DependentSizedArray: - case clang::Type::IncompleteArray: - case clang::Type::VariableArray: - if (pointee_or_element_clang_type) - *pointee_or_element_clang_type = cast<ArrayType>(qual_type.getTypePtr())->getElementType().getAsOpaquePtr(); - return eTypeHasChildren | eTypeIsArray; - - case clang::Type::DependentName: return 0; - case clang::Type::DependentSizedExtVector: return eTypeHasChildren | eTypeIsVector; - case clang::Type::DependentTemplateSpecialization: return eTypeIsTemplate; - case clang::Type::Decltype: return 0; - - case clang::Type::Enum: - if (pointee_or_element_clang_type) - *pointee_or_element_clang_type = cast<EnumType>(qual_type)->getDecl()->getIntegerType().getAsOpaquePtr(); - return eTypeIsEnumeration | eTypeHasValue; - - case clang::Type::Elaborated: - return ClangASTContext::GetTypeInfo (cast<ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr(), - ast, - pointee_or_element_clang_type); - - case clang::Type::Paren: - return ClangASTContext::GetTypeInfo(llvm::cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr(), - ast, - pointee_or_element_clang_type); - - case clang::Type::FunctionProto: return eTypeIsFuncPrototype | eTypeHasValue; - case clang::Type::FunctionNoProto: return eTypeIsFuncPrototype | eTypeHasValue; - case clang::Type::InjectedClassName: return 0; - - case clang::Type::LValueReference: - case clang::Type::RValueReference: - if (pointee_or_element_clang_type) - *pointee_or_element_clang_type = cast<ReferenceType>(qual_type.getTypePtr())->getPointeeType().getAsOpaquePtr(); - return eTypeHasChildren | eTypeIsReference | eTypeHasValue; - - case clang::Type::MemberPointer: return eTypeIsPointer | eTypeIsMember | eTypeHasValue; - - case clang::Type::ObjCObjectPointer: - if (pointee_or_element_clang_type) - *pointee_or_element_clang_type = qual_type->getPointeeType().getAsOpaquePtr(); - return eTypeHasChildren | eTypeIsObjC | eTypeIsClass | eTypeIsPointer | eTypeHasValue; - - case clang::Type::ObjCObject: return eTypeHasChildren | eTypeIsObjC | eTypeIsClass; - case clang::Type::ObjCInterface: return eTypeHasChildren | eTypeIsObjC | eTypeIsClass; - - case clang::Type::Pointer: - if (pointee_or_element_clang_type) - *pointee_or_element_clang_type = qual_type->getPointeeType().getAsOpaquePtr(); - return eTypeHasChildren | eTypeIsPointer | eTypeHasValue; - - case clang::Type::Record: - if (qual_type->getAsCXXRecordDecl()) - return eTypeHasChildren | eTypeIsClass | eTypeIsCPlusPlus; - else - return eTypeHasChildren | eTypeIsStructUnion; - break; - case clang::Type::SubstTemplateTypeParm: return eTypeIsTemplate; - case clang::Type::TemplateTypeParm: return eTypeIsTemplate; - case clang::Type::TemplateSpecialization: return eTypeIsTemplate; - - case clang::Type::Typedef: - return eTypeIsTypedef | ClangASTContext::GetTypeInfo (cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr(), - ast, - pointee_or_element_clang_type); - - case clang::Type::TypeOfExpr: return 0; - case clang::Type::TypeOf: return 0; - case clang::Type::UnresolvedUsing: return 0; - - case clang::Type::ExtVector: - case clang::Type::Vector: - { - uint32_t vector_type_flags = eTypeHasChildren | eTypeIsVector; - const VectorType *vector_type = dyn_cast<VectorType>(qual_type->getCanonicalTypeInternal()); - if (vector_type) - { - if (vector_type->isIntegerType()) - vector_type_flags |= eTypeIsFloat; - else if (vector_type->isFloatingType()) - vector_type_flags |= eTypeIsInteger; - } - return vector_type_flags; - } - default: return 0; - } - return 0; -} - - -#pragma mark Aggregate Types - -bool -ClangASTContext::IsAggregateType (clang_type_t clang_type) -{ - if (clang_type == NULL) - return false; - - QualType qual_type (QualType::getFromOpaquePtr(clang_type)); - - const clang::Type::TypeClass type_class = qual_type->getTypeClass(); - switch (type_class) - { - case clang::Type::IncompleteArray: - case clang::Type::VariableArray: - case clang::Type::ConstantArray: - case clang::Type::ExtVector: - case clang::Type::Vector: - case clang::Type::Record: - case clang::Type::ObjCObject: - case clang::Type::ObjCInterface: - return true; - case clang::Type::Elaborated: - return ClangASTContext::IsAggregateType (cast<ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr()); - case clang::Type::Typedef: - return ClangASTContext::IsAggregateType (cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr()); - case clang::Type::Paren: - return ClangASTContext::IsAggregateType (cast<ParenType>(qual_type)->desugar().getAsOpaquePtr()); - default: - break; - } - // The clang type does have a value - return false; -} - -uint32_t -ClangASTContext::GetNumChildren (clang::ASTContext *ast, clang_type_t clang_type, bool omit_empty_base_classes) -{ - if (clang_type == NULL) - return 0; - - uint32_t num_children = 0; - QualType qual_type(QualType::getFromOpaquePtr(clang_type)); - const clang::Type::TypeClass type_class = qual_type->getTypeClass(); - switch (type_class) - { - case clang::Type::Builtin: - switch (cast<clang::BuiltinType>(qual_type)->getKind()) - { - case clang::BuiltinType::ObjCId: // child is Class - case clang::BuiltinType::ObjCClass: // child is Class - num_children = 1; - break; - - default: - break; - } - break; - - case clang::Type::Complex: return 0; - - case clang::Type::Record: - if (GetCompleteQualType (ast, qual_type)) - { - const RecordType *record_type = cast<RecordType>(qual_type.getTypePtr()); - const RecordDecl *record_decl = record_type->getDecl(); - assert(record_decl); - const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl); - if (cxx_record_decl) - { - if (omit_empty_base_classes) - { - // Check each base classes to see if it or any of its - // base classes contain any fields. This can help - // limit the noise in variable views by not having to - // show base classes that contain no members. - CXXRecordDecl::base_class_const_iterator base_class, base_class_end; - for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end(); - base_class != base_class_end; - ++base_class) - { - const CXXRecordDecl *base_class_decl = cast<CXXRecordDecl>(base_class->getType()->getAs<RecordType>()->getDecl()); - - // Skip empty base classes - if (RecordHasFields(base_class_decl) == false) - continue; - - num_children++; - } - } - else - { - // Include all base classes - num_children += cxx_record_decl->getNumBases(); - } - - } - RecordDecl::field_iterator field, field_end; - for (field = record_decl->field_begin(), field_end = record_decl->field_end(); field != field_end; ++field) - ++num_children; - } - break; - - case clang::Type::ObjCObject: - case clang::Type::ObjCInterface: - if (GetCompleteQualType (ast, qual_type)) - { - const ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(qual_type.getTypePtr()); - assert (objc_class_type); - if (objc_class_type) - { - ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface(); - - if (class_interface_decl) - { - - ObjCInterfaceDecl *superclass_interface_decl = class_interface_decl->getSuperClass(); - if (superclass_interface_decl) - { - if (omit_empty_base_classes) - { - if (ClangASTContext::ObjCDeclHasIVars (superclass_interface_decl, true)) - ++num_children; - } - else - ++num_children; - } - - num_children += class_interface_decl->ivar_size(); - } - } - } - break; - - case clang::Type::ObjCObjectPointer: - { - const ObjCObjectPointerType *pointer_type = cast<ObjCObjectPointerType>(qual_type.getTypePtr()); - QualType pointee_type = pointer_type->getPointeeType(); - uint32_t num_pointee_children = ClangASTContext::GetNumChildren (ast, - pointee_type.getAsOpaquePtr(), - omit_empty_base_classes); - // If this type points to a simple type, then it has 1 child - if (num_pointee_children == 0) - num_children = 1; - else - num_children = num_pointee_children; - } - break; - - case clang::Type::Vector: - case clang::Type::ExtVector: - num_children = cast<VectorType>(qual_type.getTypePtr())->getNumElements(); - break; - - case clang::Type::ConstantArray: - num_children = cast<ConstantArrayType>(qual_type.getTypePtr())->getSize().getLimitedValue(); - break; - - case clang::Type::Pointer: - { - const PointerType *pointer_type = cast<PointerType>(qual_type.getTypePtr()); - QualType pointee_type (pointer_type->getPointeeType()); - uint32_t num_pointee_children = ClangASTContext::GetNumChildren (ast, - pointee_type.getAsOpaquePtr(), - omit_empty_base_classes); - if (num_pointee_children == 0) - { - // We have a pointer to a pointee type that claims it has no children. - // We will want to look at - num_children = ClangASTContext::GetNumPointeeChildren (pointee_type.getAsOpaquePtr()); - } - else - num_children = num_pointee_children; - } - break; - - case clang::Type::LValueReference: - case clang::Type::RValueReference: - { - const ReferenceType *reference_type = cast<ReferenceType>(qual_type.getTypePtr()); - QualType pointee_type = reference_type->getPointeeType(); - uint32_t num_pointee_children = ClangASTContext::GetNumChildren (ast, - pointee_type.getAsOpaquePtr(), - omit_empty_base_classes); - // If this type points to a simple type, then it has 1 child - if (num_pointee_children == 0) - num_children = 1; - else - num_children = num_pointee_children; - } - break; - - - case clang::Type::Typedef: - num_children = ClangASTContext::GetNumChildren (ast, - cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr(), - omit_empty_base_classes); - break; - - case clang::Type::Elaborated: - num_children = ClangASTContext::GetNumChildren (ast, - cast<ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr(), - omit_empty_base_classes); - break; - - case clang::Type::Paren: - num_children = ClangASTContext::GetNumChildren(ast, - llvm::cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr(), - omit_empty_base_classes); - - break; - default: - break; - } - return num_children; -} - -uint32_t -ClangASTContext::GetNumDirectBaseClasses (clang::ASTContext *ast, clang_type_t clang_type) -{ - if (clang_type == NULL) - return 0; - - uint32_t count = 0; - QualType qual_type(QualType::getFromOpaquePtr(clang_type)); - const clang::Type::TypeClass type_class = qual_type->getTypeClass(); - switch (type_class) - { - case clang::Type::Record: - if (GetCompleteQualType (ast, qual_type)) - { - const CXXRecordDecl *cxx_record_decl = qual_type->getAsCXXRecordDecl(); - if (cxx_record_decl) - count = cxx_record_decl->getNumBases(); - } - break; - - case clang::Type::ObjCObjectPointer: - if (GetCompleteQualType (ast, qual_type)) - { - const ObjCObjectPointerType *objc_class_type = qual_type->getAsObjCInterfacePointerType(); - if (objc_class_type) - { - ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterfaceDecl(); - if (class_interface_decl && class_interface_decl->getSuperClass()) - count = 1; - } - } - break; - - case clang::Type::ObjCObject: - case clang::Type::ObjCInterface: - if (GetCompleteQualType (ast, qual_type)) - { - const ObjCObjectType *objc_class_type = qual_type->getAsObjCQualifiedInterfaceType(); - if (objc_class_type) - { - ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface(); - - if (class_interface_decl && class_interface_decl->getSuperClass()) - count = 1; - } - } - break; - - - case clang::Type::Typedef: - count = ClangASTContext::GetNumDirectBaseClasses (ast, cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr()); - break; - - case clang::Type::Elaborated: - count = ClangASTContext::GetNumDirectBaseClasses (ast, cast<ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr()); - break; - - case clang::Type::Paren: - return ClangASTContext::GetNumDirectBaseClasses(ast, cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr()); - - default: - break; - } - return count; -} - -uint32_t -ClangASTContext::GetNumVirtualBaseClasses (clang::ASTContext *ast, - clang_type_t clang_type) -{ - if (clang_type == NULL) - return 0; - - uint32_t count = 0; - QualType qual_type(QualType::getFromOpaquePtr(clang_type)); - const clang::Type::TypeClass type_class = qual_type->getTypeClass(); - switch (type_class) - { - case clang::Type::Record: - if (GetCompleteQualType (ast, qual_type)) - { - const CXXRecordDecl *cxx_record_decl = qual_type->getAsCXXRecordDecl(); - if (cxx_record_decl) - count = cxx_record_decl->getNumVBases(); - } - break; - - case clang::Type::Typedef: - count = ClangASTContext::GetNumVirtualBaseClasses (ast, cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr()); - break; - - case clang::Type::Elaborated: - count = ClangASTContext::GetNumVirtualBaseClasses (ast, cast<ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr()); - break; - - case clang::Type::Paren: - count = ClangASTContext::GetNumVirtualBaseClasses(ast, cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr()); - break; - - default: - break; - } - return count; -} - -uint32_t -ClangASTContext::GetNumFields (clang::ASTContext *ast, clang_type_t clang_type) -{ - if (clang_type == NULL) - return 0; - - uint32_t count = 0; - QualType qual_type(QualType::getFromOpaquePtr(clang_type)); - const clang::Type::TypeClass type_class = qual_type->getTypeClass(); - switch (type_class) - { - case clang::Type::Record: - if (GetCompleteQualType (ast, qual_type)) - { - const RecordType *record_type = dyn_cast<RecordType>(qual_type.getTypePtr()); - if (record_type) - { - RecordDecl *record_decl = record_type->getDecl(); - if (record_decl) - { - uint32_t field_idx = 0; - RecordDecl::field_iterator field, field_end; - for (field = record_decl->field_begin(), field_end = record_decl->field_end(); field != field_end; ++field) - ++field_idx; - count = field_idx; - } - } - } - break; - - case clang::Type::Typedef: - count = ClangASTContext::GetNumFields (ast, cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr()); - break; - - case clang::Type::Elaborated: - count = ClangASTContext::GetNumFields (ast, cast<ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr()); - break; - - case clang::Type::Paren: - count = ClangASTContext::GetNumFields(ast, cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr()); - break; - - case clang::Type::ObjCObjectPointer: - if (GetCompleteQualType (ast, qual_type)) - { - const ObjCObjectPointerType *objc_class_type = qual_type->getAsObjCInterfacePointerType(); - if (objc_class_type) - { - ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterfaceDecl(); - - if (class_interface_decl) - count = class_interface_decl->ivar_size(); - } - } - break; - - case clang::Type::ObjCObject: - case clang::Type::ObjCInterface: - if (GetCompleteQualType (ast, qual_type)) - { - const ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(qual_type.getTypePtr()); - if (objc_class_type) - { - ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface(); - - if (class_interface_decl) - count = class_interface_decl->ivar_size(); - } - } - break; - - default: - break; - } - return count; -} - -clang_type_t -ClangASTContext::GetDirectBaseClassAtIndex (clang::ASTContext *ast, - clang_type_t clang_type, - size_t idx, - uint32_t *bit_offset_ptr) -{ - if (clang_type == NULL) - return 0; - - QualType qual_type(QualType::getFromOpaquePtr(clang_type)); - const clang::Type::TypeClass type_class = qual_type->getTypeClass(); - switch (type_class) - { - case clang::Type::Record: - if (GetCompleteQualType (ast, qual_type)) - { - const CXXRecordDecl *cxx_record_decl = qual_type->getAsCXXRecordDecl(); - if (cxx_record_decl) - { - uint32_t curr_idx = 0; - CXXRecordDecl::base_class_const_iterator base_class, base_class_end; - for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end(); - base_class != base_class_end; - ++base_class, ++curr_idx) - { - if (curr_idx == idx) - { - if (bit_offset_ptr) - { - const ASTRecordLayout &record_layout = ast->getASTRecordLayout(cxx_record_decl); - const CXXRecordDecl *base_class_decl = cast<CXXRecordDecl>(base_class->getType()->getAs<RecordType>()->getDecl()); - if (base_class->isVirtual()) - *bit_offset_ptr = record_layout.getVBaseClassOffset(base_class_decl).getQuantity() * 8; - else - *bit_offset_ptr = record_layout.getBaseClassOffset(base_class_decl).getQuantity() * 8; - } - return base_class->getType().getAsOpaquePtr(); - } - } - } - } - break; - - case clang::Type::ObjCObjectPointer: - if (idx == 0 && GetCompleteQualType (ast, qual_type)) - { - const ObjCObjectPointerType *objc_class_type = qual_type->getAsObjCInterfacePointerType(); - if (objc_class_type) - { - ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterfaceDecl(); - if (class_interface_decl) - { - ObjCInterfaceDecl *superclass_interface_decl = class_interface_decl->getSuperClass(); - if (superclass_interface_decl) - { - if (bit_offset_ptr) - *bit_offset_ptr = 0; - return ast->getObjCInterfaceType(superclass_interface_decl).getAsOpaquePtr(); - } - } - } - } - break; - - case clang::Type::ObjCObject: - case clang::Type::ObjCInterface: - if (idx == 0 && GetCompleteQualType (ast, qual_type)) - { - const ObjCObjectType *objc_class_type = qual_type->getAsObjCQualifiedInterfaceType(); - if (objc_class_type) - { - ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface(); - - if (class_interface_decl) - { - ObjCInterfaceDecl *superclass_interface_decl = class_interface_decl->getSuperClass(); - if (superclass_interface_decl) - { - if (bit_offset_ptr) - *bit_offset_ptr = 0; - return ast->getObjCInterfaceType(superclass_interface_decl).getAsOpaquePtr(); - } - } - } - } - break; - - - case clang::Type::Typedef: - return ClangASTContext::GetDirectBaseClassAtIndex (ast, - cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr(), - idx, - bit_offset_ptr); - - case clang::Type::Elaborated: - return ClangASTContext::GetDirectBaseClassAtIndex (ast, - cast<ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr(), - idx, - bit_offset_ptr); - - case clang::Type::Paren: - return ClangASTContext::GetDirectBaseClassAtIndex (ast, - cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr(), - idx, - bit_offset_ptr); - - default: - break; - } - return NULL; -} - -clang_type_t -ClangASTContext::GetVirtualBaseClassAtIndex (clang::ASTContext *ast, - clang_type_t clang_type, - size_t idx, - uint32_t *bit_offset_ptr) -{ - if (clang_type == NULL) - return 0; - - QualType qual_type(QualType::getFromOpaquePtr(clang_type)); - const clang::Type::TypeClass type_class = qual_type->getTypeClass(); - switch (type_class) - { - case clang::Type::Record: - if (GetCompleteQualType (ast, qual_type)) - { - const CXXRecordDecl *cxx_record_decl = qual_type->getAsCXXRecordDecl(); - if (cxx_record_decl) - { - uint32_t curr_idx = 0; - CXXRecordDecl::base_class_const_iterator base_class, base_class_end; - for (base_class = cxx_record_decl->vbases_begin(), base_class_end = cxx_record_decl->vbases_end(); - base_class != base_class_end; - ++base_class, ++curr_idx) - { - if (curr_idx == idx) - { - if (bit_offset_ptr) - { - const ASTRecordLayout &record_layout = ast->getASTRecordLayout(cxx_record_decl); - const CXXRecordDecl *base_class_decl = cast<CXXRecordDecl>(base_class->getType()->getAs<RecordType>()->getDecl()); - *bit_offset_ptr = record_layout.getVBaseClassOffset(base_class_decl).getQuantity() * 8; - - } - return base_class->getType().getAsOpaquePtr(); - } - } - } - } - break; - - case clang::Type::Typedef: - return ClangASTContext::GetVirtualBaseClassAtIndex (ast, - cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr(), - idx, - bit_offset_ptr); - - case clang::Type::Elaborated: - return ClangASTContext::GetVirtualBaseClassAtIndex (ast, - cast<ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr(), - idx, - bit_offset_ptr); - - case clang::Type::Paren: - return ClangASTContext::GetVirtualBaseClassAtIndex (ast, - cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr(), - idx, - bit_offset_ptr); - - default: - break; - } - return NULL; -} - -static clang_type_t -GetObjCFieldAtIndex (clang::ASTContext *ast, - ObjCInterfaceDecl * class_interface_decl, - size_t idx, - std::string& name, - uint64_t *bit_offset_ptr, - uint32_t *bitfield_bit_size_ptr, - bool *is_bitfield_ptr) -{ - if (class_interface_decl) - { - if (idx < (class_interface_decl->ivar_size())) - { - ObjCInterfaceDecl::ivar_iterator ivar_pos, ivar_end = class_interface_decl->ivar_end(); - uint32_t ivar_idx = 0; - - for (ivar_pos = class_interface_decl->ivar_begin(); ivar_pos != ivar_end; ++ivar_pos, ++ivar_idx) - { - if (ivar_idx == idx) - { - const ObjCIvarDecl* ivar_decl = *ivar_pos; - - QualType ivar_qual_type(ivar_decl->getType()); - - name.assign(ivar_decl->getNameAsString()); - - if (bit_offset_ptr) - { - const ASTRecordLayout &interface_layout = ast->getASTObjCInterfaceLayout(class_interface_decl); - *bit_offset_ptr = interface_layout.getFieldOffset (ivar_idx); - } - - const bool is_bitfield = ivar_pos->isBitField(); - - if (bitfield_bit_size_ptr) - { - *bitfield_bit_size_ptr = 0; - - if (is_bitfield && ast) - { - Expr *bitfield_bit_size_expr = ivar_pos->getBitWidth(); - llvm::APSInt bitfield_apsint; - if (bitfield_bit_size_expr && bitfield_bit_size_expr->EvaluateAsInt(bitfield_apsint, *ast)) - { - *bitfield_bit_size_ptr = bitfield_apsint.getLimitedValue(); - } - } - } - if (is_bitfield_ptr) - *is_bitfield_ptr = is_bitfield; - - return ivar_qual_type.getAsOpaquePtr(); - } - } - } - } - return NULL; -} - -clang_type_t -ClangASTContext::GetFieldAtIndex (clang::ASTContext *ast, - clang_type_t clang_type, - size_t idx, - std::string& name, - uint64_t *bit_offset_ptr, - uint32_t *bitfield_bit_size_ptr, - bool *is_bitfield_ptr) -{ - if (clang_type == NULL) - return 0; - - QualType qual_type(QualType::getFromOpaquePtr(clang_type)); - const clang::Type::TypeClass type_class = qual_type->getTypeClass(); - switch (type_class) - { - case clang::Type::Record: - if (GetCompleteQualType (ast, qual_type)) - { - const RecordType *record_type = cast<RecordType>(qual_type.getTypePtr()); - const RecordDecl *record_decl = record_type->getDecl(); - uint32_t field_idx = 0; - RecordDecl::field_iterator field, field_end; - for (field = record_decl->field_begin(), field_end = record_decl->field_end(); field != field_end; ++field, ++field_idx) - { - if (idx == field_idx) - { - // Print the member type if requested - // Print the member name and equal sign - name.assign(field->getNameAsString()); - - // Figure out the type byte size (field_type_info.first) and - // alignment (field_type_info.second) from the AST context. - if (bit_offset_ptr) - { - const ASTRecordLayout &record_layout = ast->getASTRecordLayout(record_decl); - *bit_offset_ptr = record_layout.getFieldOffset (field_idx); - } - - const bool is_bitfield = field->isBitField(); - - if (bitfield_bit_size_ptr) - { - *bitfield_bit_size_ptr = 0; - - if (is_bitfield && ast) - { - Expr *bitfield_bit_size_expr = field->getBitWidth(); - llvm::APSInt bitfield_apsint; - if (bitfield_bit_size_expr && bitfield_bit_size_expr->EvaluateAsInt(bitfield_apsint, *ast)) - { - *bitfield_bit_size_ptr = bitfield_apsint.getLimitedValue(); - } - } - } - if (is_bitfield_ptr) - *is_bitfield_ptr = is_bitfield; - - return field->getType().getAsOpaquePtr(); - } - } - } - break; - - case clang::Type::ObjCObjectPointer: - if (GetCompleteQualType (ast, qual_type)) - { - const ObjCObjectPointerType *objc_class_type = qual_type->getAsObjCInterfacePointerType(); - if (objc_class_type) - { - ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterfaceDecl(); - return GetObjCFieldAtIndex(ast, class_interface_decl, idx, name, bit_offset_ptr, bitfield_bit_size_ptr, is_bitfield_ptr); - } - } - break; - - case clang::Type::ObjCObject: - case clang::Type::ObjCInterface: - if (GetCompleteQualType (ast, qual_type)) - { - const ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(qual_type.getTypePtr()); - assert (objc_class_type); - if (objc_class_type) - { - ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface(); - return GetObjCFieldAtIndex(ast, class_interface_decl, idx, name, bit_offset_ptr, bitfield_bit_size_ptr, is_bitfield_ptr); - } - } - break; - - - case clang::Type::Typedef: - return ClangASTContext::GetFieldAtIndex (ast, - cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr(), - idx, - name, - bit_offset_ptr, - bitfield_bit_size_ptr, - is_bitfield_ptr); - - case clang::Type::Elaborated: - return ClangASTContext::GetFieldAtIndex (ast, - cast<ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr(), - idx, - name, - bit_offset_ptr, - bitfield_bit_size_ptr, - is_bitfield_ptr); - - case clang::Type::Paren: - return ClangASTContext::GetFieldAtIndex (ast, - cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr(), - idx, - name, - bit_offset_ptr, - bitfield_bit_size_ptr, - is_bitfield_ptr); - - default: - break; - } - return NULL; -} - -size_t -ClangASTContext::GetIndexOfFieldWithName (clang::ASTContext *ast, - lldb::clang_type_t clang_type, - const char* name, - lldb::clang_type_t* field_clang_type, - uint64_t *bit_offset_ptr, - uint32_t *bitfield_bit_size_ptr, - bool *is_bitfield_ptr) -{ - unsigned count = ClangASTContext::GetNumFields(ast, clang_type); - lldb::clang_type_t field_clang_type_internal; - std::string field_name; - for (unsigned index = 0; index < count; index++) - { - field_clang_type_internal = ClangASTContext::GetFieldAtIndex(ast, clang_type, index, field_name, bit_offset_ptr, bitfield_bit_size_ptr, is_bitfield_ptr); - if ( strcmp(field_name.c_str(), name) == 0 ) - { - if (field_clang_type) - *field_clang_type = field_clang_type_internal; - return index; - } - } - return UINT32_MAX; -} - -lldb::BasicType -ClangASTContext::GetLLDBBasicTypeEnumeration (clang_type_t clang_type) -{ - if (clang_type) - { - QualType qual_type(QualType::getFromOpaquePtr(clang_type)); - const clang::Type::TypeClass type_class = qual_type->getTypeClass(); - if (type_class == clang::Type::Builtin) - { - switch (cast<clang::BuiltinType>(qual_type)->getKind()) - { - case clang::BuiltinType::Void: return eBasicTypeVoid; - case clang::BuiltinType::Bool: return eBasicTypeBool; - case clang::BuiltinType::Char_S: return eBasicTypeSignedChar; - case clang::BuiltinType::Char_U: return eBasicTypeUnsignedChar; - case clang::BuiltinType::Char16: return eBasicTypeChar16; - case clang::BuiltinType::Char32: return eBasicTypeChar32; - case clang::BuiltinType::UChar: return eBasicTypeUnsignedChar; - case clang::BuiltinType::SChar: return eBasicTypeSignedChar; - case clang::BuiltinType::WChar_S: return eBasicTypeSignedWChar; - case clang::BuiltinType::WChar_U: return eBasicTypeUnsignedWChar; - case clang::BuiltinType::Short: return eBasicTypeShort; - case clang::BuiltinType::UShort: return eBasicTypeUnsignedShort; - case clang::BuiltinType::Int: return eBasicTypeInt; - case clang::BuiltinType::UInt: return eBasicTypeUnsignedInt; - case clang::BuiltinType::Long: return eBasicTypeLong; - case clang::BuiltinType::ULong: return eBasicTypeUnsignedLong; - case clang::BuiltinType::LongLong: return eBasicTypeLongLong; - case clang::BuiltinType::ULongLong: return eBasicTypeUnsignedLongLong; - case clang::BuiltinType::Int128: return eBasicTypeInt128; - case clang::BuiltinType::UInt128: return eBasicTypeUnsignedInt128; - - case clang::BuiltinType::Half: return eBasicTypeHalf; - case clang::BuiltinType::Float: return eBasicTypeFloat; - case clang::BuiltinType::Double: return eBasicTypeDouble; - case clang::BuiltinType::LongDouble:return eBasicTypeLongDouble; - - case clang::BuiltinType::NullPtr: return eBasicTypeNullPtr; - case clang::BuiltinType::ObjCId: return eBasicTypeObjCID; - case clang::BuiltinType::ObjCClass: return eBasicTypeObjCClass; - case clang::BuiltinType::ObjCSel: return eBasicTypeObjCSel; - case clang::BuiltinType::Dependent: - case clang::BuiltinType::Overload: - case clang::BuiltinType::BoundMember: - case clang::BuiltinType::PseudoObject: - case clang::BuiltinType::UnknownAny: - case clang::BuiltinType::BuiltinFn: - case clang::BuiltinType::ARCUnbridgedCast: - case clang::BuiltinType::OCLEvent: - case clang::BuiltinType::OCLImage1d: - case clang::BuiltinType::OCLImage1dArray: - case clang::BuiltinType::OCLImage1dBuffer: - case clang::BuiltinType::OCLImage2d: - case clang::BuiltinType::OCLImage2dArray: - case clang::BuiltinType::OCLImage3d: - case clang::BuiltinType::OCLSampler: - return eBasicTypeOther; - } - } - } - - return eBasicTypeInvalid; -} - - - -// If a pointer to a pointee type (the clang_type arg) says that it has no -// children, then we either need to trust it, or override it and return a -// different result. For example, an "int *" has one child that is an integer, -// but a function pointer doesn't have any children. Likewise if a Record type -// claims it has no children, then there really is nothing to show. -uint32_t -ClangASTContext::GetNumPointeeChildren (clang_type_t clang_type) -{ - if (clang_type == NULL) - return 0; - - QualType qual_type(QualType::getFromOpaquePtr(clang_type)); - const clang::Type::TypeClass type_class = qual_type->getTypeClass(); - switch (type_class) - { - case clang::Type::Builtin: - switch (cast<clang::BuiltinType>(qual_type)->getKind()) - { - case clang::BuiltinType::UnknownAny: - case clang::BuiltinType::Void: - case clang::BuiltinType::NullPtr: - case clang::BuiltinType::OCLEvent: - case clang::BuiltinType::OCLImage1d: - case clang::BuiltinType::OCLImage1dArray: - case clang::BuiltinType::OCLImage1dBuffer: - case clang::BuiltinType::OCLImage2d: - case clang::BuiltinType::OCLImage2dArray: - case clang::BuiltinType::OCLImage3d: - case clang::BuiltinType::OCLSampler: - return 0; - case clang::BuiltinType::Bool: - case clang::BuiltinType::Char_U: - case clang::BuiltinType::UChar: - case clang::BuiltinType::WChar_U: - case clang::BuiltinType::Char16: - case clang::BuiltinType::Char32: - case clang::BuiltinType::UShort: - case clang::BuiltinType::UInt: - case clang::BuiltinType::ULong: - case clang::BuiltinType::ULongLong: - case clang::BuiltinType::UInt128: - case clang::BuiltinType::Char_S: - case clang::BuiltinType::SChar: - case clang::BuiltinType::WChar_S: - case clang::BuiltinType::Short: - case clang::BuiltinType::Int: - case clang::BuiltinType::Long: - case clang::BuiltinType::LongLong: - case clang::BuiltinType::Int128: - case clang::BuiltinType::Float: - case clang::BuiltinType::Double: - case clang::BuiltinType::LongDouble: - case clang::BuiltinType::Dependent: - case clang::BuiltinType::Overload: - case clang::BuiltinType::ObjCId: - case clang::BuiltinType::ObjCClass: - case clang::BuiltinType::ObjCSel: - case clang::BuiltinType::BoundMember: - case clang::BuiltinType::Half: - case clang::BuiltinType::ARCUnbridgedCast: - case clang::BuiltinType::PseudoObject: - case clang::BuiltinType::BuiltinFn: - return 1; - } - break; - - case clang::Type::Complex: return 1; - case clang::Type::Pointer: return 1; - case clang::Type::BlockPointer: return 0; // If block pointers don't have debug info, then no children for them - case clang::Type::LValueReference: return 1; - case clang::Type::RValueReference: return 1; - case clang::Type::MemberPointer: return 0; - case clang::Type::ConstantArray: return 0; - case clang::Type::IncompleteArray: return 0; - case clang::Type::VariableArray: return 0; - case clang::Type::DependentSizedArray: return 0; - case clang::Type::DependentSizedExtVector: return 0; - case clang::Type::Vector: return 0; - case clang::Type::ExtVector: return 0; - case clang::Type::FunctionProto: return 0; // When we function pointers, they have no children... - case clang::Type::FunctionNoProto: return 0; // When we function pointers, they have no children... - case clang::Type::UnresolvedUsing: return 0; - case clang::Type::Paren: return ClangASTContext::GetNumPointeeChildren (cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr()); - case clang::Type::Typedef: return ClangASTContext::GetNumPointeeChildren (cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr()); - case clang::Type::Elaborated: return ClangASTContext::GetNumPointeeChildren (cast<ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr()); - case clang::Type::TypeOfExpr: return 0; - case clang::Type::TypeOf: return 0; - case clang::Type::Decltype: return 0; - case clang::Type::Record: return 0; - case clang::Type::Enum: return 1; - case clang::Type::TemplateTypeParm: return 1; - case clang::Type::SubstTemplateTypeParm: return 1; - case clang::Type::TemplateSpecialization: return 1; - case clang::Type::InjectedClassName: return 0; - case clang::Type::DependentName: return 1; - case clang::Type::DependentTemplateSpecialization: return 1; - case clang::Type::ObjCObject: return 0; - case clang::Type::ObjCInterface: return 0; - case clang::Type::ObjCObjectPointer: return 1; - default: - break; - } - return 0; -} - -clang_type_t -ClangASTContext::GetChildClangTypeAtIndex -( - ExecutionContext *exe_ctx, - const char *parent_name, - clang_type_t parent_clang_type, - size_t idx, - bool transparent_pointers, - bool omit_empty_base_classes, - bool ignore_array_bounds, - std::string& child_name, - uint32_t &child_byte_size, - int32_t &child_byte_offset, - uint32_t &child_bitfield_bit_size, - uint32_t &child_bitfield_bit_offset, - bool &child_is_base_class, - bool &child_is_deref_of_parent -) -{ - if (parent_clang_type) - - return GetChildClangTypeAtIndex (exe_ctx, - getASTContext(), - parent_name, - parent_clang_type, - idx, - transparent_pointers, - omit_empty_base_classes, - ignore_array_bounds, - child_name, - child_byte_size, - child_byte_offset, - child_bitfield_bit_size, - child_bitfield_bit_offset, - child_is_base_class, - child_is_deref_of_parent); - return NULL; -} - -clang_type_t -ClangASTContext::GetChildClangTypeAtIndex -( - ExecutionContext *exe_ctx, - ASTContext *ast, - const char *parent_name, - clang_type_t parent_clang_type, - size_t idx, - bool transparent_pointers, - bool omit_empty_base_classes, - bool ignore_array_bounds, - std::string& child_name, - uint32_t &child_byte_size, - int32_t &child_byte_offset, - uint32_t &child_bitfield_bit_size, - uint32_t &child_bitfield_bit_offset, - bool &child_is_base_class, - bool &child_is_deref_of_parent -) -{ - if (parent_clang_type == NULL) - return NULL; - - QualType parent_qual_type(QualType::getFromOpaquePtr(parent_clang_type)); - const clang::Type::TypeClass parent_type_class = parent_qual_type->getTypeClass(); - child_bitfield_bit_size = 0; - child_bitfield_bit_offset = 0; - child_is_base_class = false; - - const bool idx_is_valid = idx < ClangASTContext::GetNumChildren (ast, parent_clang_type, omit_empty_base_classes); - uint32_t bit_offset; - switch (parent_type_class) - { - case clang::Type::Builtin: - if (idx_is_valid) - { - switch (cast<clang::BuiltinType>(parent_qual_type)->getKind()) - { - case clang::BuiltinType::ObjCId: - case clang::BuiltinType::ObjCClass: - child_name = "isa"; - child_byte_size = ast->getTypeSize(ast->ObjCBuiltinClassTy) / CHAR_BIT; - return ast->ObjCBuiltinClassTy.getAsOpaquePtr(); - - default: - break; - } - } - break; - - case clang::Type::Record: - if (idx_is_valid && GetCompleteQualType (ast, parent_qual_type)) - { - const RecordType *record_type = cast<RecordType>(parent_qual_type.getTypePtr()); - const RecordDecl *record_decl = record_type->getDecl(); - assert(record_decl); - const ASTRecordLayout &record_layout = ast->getASTRecordLayout(record_decl); - uint32_t child_idx = 0; - - const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl); - if (cxx_record_decl) - { - // We might have base classes to print out first - CXXRecordDecl::base_class_const_iterator base_class, base_class_end; - for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end(); - base_class != base_class_end; - ++base_class) - { - const CXXRecordDecl *base_class_decl = NULL; - - // Skip empty base classes - if (omit_empty_base_classes) - { - base_class_decl = cast<CXXRecordDecl>(base_class->getType()->getAs<RecordType>()->getDecl()); - if (RecordHasFields(base_class_decl) == false) - continue; - } - - if (idx == child_idx) - { - if (base_class_decl == NULL) - base_class_decl = cast<CXXRecordDecl>(base_class->getType()->getAs<RecordType>()->getDecl()); - - - if (base_class->isVirtual()) - bit_offset = record_layout.getVBaseClassOffset(base_class_decl).getQuantity() * 8; - else - bit_offset = record_layout.getBaseClassOffset(base_class_decl).getQuantity() * 8; - - // Base classes should be a multiple of 8 bits in size - child_byte_offset = bit_offset/8; - - child_name = ClangASTType::GetTypeNameForQualType(ast, base_class->getType()); - - uint64_t clang_type_info_bit_size = ast->getTypeSize(base_class->getType()); - - // Base classes bit sizes should be a multiple of 8 bits in size - assert (clang_type_info_bit_size % 8 == 0); - child_byte_size = clang_type_info_bit_size / 8; - child_is_base_class = true; - return base_class->getType().getAsOpaquePtr(); - } - // We don't increment the child index in the for loop since we might - // be skipping empty base classes - ++child_idx; - } - } - // Make sure index is in range... - uint32_t field_idx = 0; - RecordDecl::field_iterator field, field_end; - for (field = record_decl->field_begin(), field_end = record_decl->field_end(); field != field_end; ++field, ++field_idx, ++child_idx) - { - if (idx == child_idx) - { - // Print the member type if requested - // Print the member name and equal sign - child_name.assign(field->getNameAsString().c_str()); - - // Figure out the type byte size (field_type_info.first) and - // alignment (field_type_info.second) from the AST context. - std::pair<uint64_t, unsigned> field_type_info = ast->getTypeInfo(field->getType()); - assert(field_idx < record_layout.getFieldCount()); - - child_byte_size = field_type_info.first / 8; - - // Figure out the field offset within the current struct/union/class type - bit_offset = record_layout.getFieldOffset (field_idx); - child_byte_offset = bit_offset / 8; - if (ClangASTContext::FieldIsBitfield (ast, *field, child_bitfield_bit_size)) - child_bitfield_bit_offset = bit_offset % 8; - - return field->getType().getAsOpaquePtr(); - } - } - } - break; - - case clang::Type::ObjCObject: - case clang::Type::ObjCInterface: - if (idx_is_valid && GetCompleteQualType (ast, parent_qual_type)) - { - const ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(parent_qual_type.getTypePtr()); - assert (objc_class_type); - if (objc_class_type) - { - uint32_t child_idx = 0; - ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface(); - - if (class_interface_decl) - { - - const ASTRecordLayout &interface_layout = ast->getASTObjCInterfaceLayout(class_interface_decl); - ObjCInterfaceDecl *superclass_interface_decl = class_interface_decl->getSuperClass(); - if (superclass_interface_decl) - { - if (omit_empty_base_classes) - { - if (ClangASTContext::GetNumChildren(ast, ast->getObjCInterfaceType(superclass_interface_decl).getAsOpaquePtr(), omit_empty_base_classes) > 0) - { - if (idx == 0) - { - QualType ivar_qual_type(ast->getObjCInterfaceType(superclass_interface_decl)); - - - child_name.assign(superclass_interface_decl->getNameAsString().c_str()); - - std::pair<uint64_t, unsigned> ivar_type_info = ast->getTypeInfo(ivar_qual_type.getTypePtr()); - - child_byte_size = ivar_type_info.first / 8; - child_byte_offset = 0; - child_is_base_class = true; - - return ivar_qual_type.getAsOpaquePtr(); - } - - ++child_idx; - } - } - else - ++child_idx; - } - - const uint32_t superclass_idx = child_idx; - - if (idx < (child_idx + class_interface_decl->ivar_size())) - { - ObjCInterfaceDecl::ivar_iterator ivar_pos, ivar_end = class_interface_decl->ivar_end(); - - for (ivar_pos = class_interface_decl->ivar_begin(); ivar_pos != ivar_end; ++ivar_pos) - { - if (child_idx == idx) - { - ObjCIvarDecl* ivar_decl = *ivar_pos; - - QualType ivar_qual_type(ivar_decl->getType()); - - child_name.assign(ivar_decl->getNameAsString().c_str()); - - std::pair<uint64_t, unsigned> ivar_type_info = ast->getTypeInfo(ivar_qual_type.getTypePtr()); - - child_byte_size = ivar_type_info.first / 8; - - // Figure out the field offset within the current struct/union/class type - // For ObjC objects, we can't trust the bit offset we get from the Clang AST, since - // that doesn't account for the space taken up by unbacked properties, or from - // the changing size of base classes that are newer than this class. - // So if we have a process around that we can ask about this object, do so. - child_byte_offset = LLDB_INVALID_IVAR_OFFSET; - Process *process = NULL; - if (exe_ctx) - process = exe_ctx->GetProcessPtr(); - if (process) - { - ObjCLanguageRuntime *objc_runtime = process->GetObjCLanguageRuntime(); - if (objc_runtime != NULL) - { - ClangASTType parent_ast_type (ast, parent_qual_type.getAsOpaquePtr()); - child_byte_offset = objc_runtime->GetByteOffsetForIvar (parent_ast_type, ivar_decl->getNameAsString().c_str()); - } - } - - // Setting this to UINT32_MAX to make sure we don't compute it twice... - bit_offset = UINT32_MAX; - - if (child_byte_offset == LLDB_INVALID_IVAR_OFFSET) - { - bit_offset = interface_layout.getFieldOffset (child_idx - superclass_idx); - child_byte_offset = bit_offset / 8; - } - - // Note, the ObjC Ivar Byte offset is just that, it doesn't account for the bit offset - // of a bitfield within its containing object. So regardless of where we get the byte - // offset from, we still need to get the bit offset for bitfields from the layout. - - if (ClangASTContext::FieldIsBitfield (ast, ivar_decl, child_bitfield_bit_size)) - { - if (bit_offset == UINT32_MAX) - bit_offset = interface_layout.getFieldOffset (child_idx - superclass_idx); - - child_bitfield_bit_offset = bit_offset % 8; - } - return ivar_qual_type.getAsOpaquePtr(); - } - ++child_idx; - } - } - } - } - } - break; - - case clang::Type::ObjCObjectPointer: - if (idx_is_valid) - { - const ObjCObjectPointerType *pointer_type = cast<ObjCObjectPointerType>(parent_qual_type.getTypePtr()); - QualType pointee_type = pointer_type->getPointeeType(); - - if (transparent_pointers && ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr())) - { - child_is_deref_of_parent = false; - bool tmp_child_is_deref_of_parent = false; - return GetChildClangTypeAtIndex (exe_ctx, - ast, - parent_name, - pointer_type->getPointeeType().getAsOpaquePtr(), - idx, - transparent_pointers, - omit_empty_base_classes, - ignore_array_bounds, - child_name, - child_byte_size, - child_byte_offset, - child_bitfield_bit_size, - child_bitfield_bit_offset, - child_is_base_class, - tmp_child_is_deref_of_parent); - } - else - { - child_is_deref_of_parent = true; - if (parent_name) - { - child_name.assign(1, '*'); - child_name += parent_name; - } - - // We have a pointer to an simple type - if (idx == 0 && GetCompleteQualType(ast, pointee_type)) - { - std::pair<uint64_t, unsigned> clang_type_info = ast->getTypeInfo(pointee_type); - assert(clang_type_info.first % 8 == 0); - child_byte_size = clang_type_info.first / 8; - child_byte_offset = 0; - return pointee_type.getAsOpaquePtr(); - } - } - } - break; - - case clang::Type::Vector: - case clang::Type::ExtVector: - if (idx_is_valid) - { - const VectorType *array = cast<VectorType>(parent_qual_type.getTypePtr()); - if (array) - { - if (GetCompleteQualType (ast, array->getElementType())) - { - std::pair<uint64_t, unsigned> field_type_info = ast->getTypeInfo(array->getElementType()); - - char element_name[64]; - ::snprintf (element_name, sizeof (element_name), "[%zu]", idx); - - child_name.assign(element_name); - assert(field_type_info.first % 8 == 0); - child_byte_size = field_type_info.first / 8; - child_byte_offset = (int32_t)idx * (int32_t)child_byte_size; - return array->getElementType().getAsOpaquePtr(); - } - } - } - break; - - case clang::Type::ConstantArray: - case clang::Type::IncompleteArray: - if (ignore_array_bounds || idx_is_valid) - { - const ArrayType *array = cast<ArrayType>(parent_qual_type.getTypePtr()); - if (array) - { - if (GetCompleteQualType (ast, array->getElementType())) - { - std::pair<uint64_t, unsigned> field_type_info = ast->getTypeInfo(array->getElementType()); - - char element_name[64]; - ::snprintf (element_name, sizeof (element_name), "[%zu]", idx); - - child_name.assign(element_name); - assert(field_type_info.first % 8 == 0); - child_byte_size = field_type_info.first / 8; - child_byte_offset = (int32_t)idx * (int32_t)child_byte_size; - return array->getElementType().getAsOpaquePtr(); - } - } - } - break; - - - case clang::Type::Pointer: - if (idx_is_valid) - { - const PointerType *pointer_type = cast<PointerType>(parent_qual_type.getTypePtr()); - QualType pointee_type = pointer_type->getPointeeType(); - - // Don't dereference "void *" pointers - if (pointee_type->isVoidType()) - return NULL; - - if (transparent_pointers && ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr())) - { - child_is_deref_of_parent = false; - bool tmp_child_is_deref_of_parent = false; - return GetChildClangTypeAtIndex (exe_ctx, - ast, - parent_name, - pointer_type->getPointeeType().getAsOpaquePtr(), - idx, - transparent_pointers, - omit_empty_base_classes, - ignore_array_bounds, - child_name, - child_byte_size, - child_byte_offset, - child_bitfield_bit_size, - child_bitfield_bit_offset, - child_is_base_class, - tmp_child_is_deref_of_parent); - } - else - { - child_is_deref_of_parent = true; - - if (parent_name) - { - child_name.assign(1, '*'); - child_name += parent_name; - } - - // We have a pointer to an simple type - if (idx == 0) - { - std::pair<uint64_t, unsigned> clang_type_info = ast->getTypeInfo(pointee_type); - assert(clang_type_info.first % 8 == 0); - child_byte_size = clang_type_info.first / 8; - child_byte_offset = 0; - return pointee_type.getAsOpaquePtr(); - } - } - } - break; - - case clang::Type::LValueReference: - case clang::Type::RValueReference: - if (idx_is_valid) - { - const ReferenceType *reference_type = cast<ReferenceType>(parent_qual_type.getTypePtr()); - QualType pointee_type(reference_type->getPointeeType()); - clang_type_t pointee_clang_type = pointee_type.getAsOpaquePtr(); - if (transparent_pointers && ClangASTContext::IsAggregateType (pointee_clang_type)) - { - child_is_deref_of_parent = false; - bool tmp_child_is_deref_of_parent = false; - return GetChildClangTypeAtIndex (exe_ctx, - ast, - parent_name, - pointee_clang_type, - idx, - transparent_pointers, - omit_empty_base_classes, - ignore_array_bounds, - child_name, - child_byte_size, - child_byte_offset, - child_bitfield_bit_size, - child_bitfield_bit_offset, - child_is_base_class, - tmp_child_is_deref_of_parent); - } - else - { - if (parent_name) - { - child_name.assign(1, '&'); - child_name += parent_name; - } - - // We have a pointer to an simple type - if (idx == 0) - { - std::pair<uint64_t, unsigned> clang_type_info = ast->getTypeInfo(pointee_type); - assert(clang_type_info.first % 8 == 0); - child_byte_size = clang_type_info.first / 8; - child_byte_offset = 0; - return pointee_type.getAsOpaquePtr(); - } - } - } - break; - - case clang::Type::Typedef: - return GetChildClangTypeAtIndex (exe_ctx, - ast, - parent_name, - cast<TypedefType>(parent_qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr(), - idx, - transparent_pointers, - omit_empty_base_classes, - ignore_array_bounds, - child_name, - child_byte_size, - child_byte_offset, - child_bitfield_bit_size, - child_bitfield_bit_offset, - child_is_base_class, - child_is_deref_of_parent); - break; - - case clang::Type::Elaborated: - return GetChildClangTypeAtIndex (exe_ctx, - ast, - parent_name, - cast<ElaboratedType>(parent_qual_type)->getNamedType().getAsOpaquePtr(), - idx, - transparent_pointers, - omit_empty_base_classes, - ignore_array_bounds, - child_name, - child_byte_size, - child_byte_offset, - child_bitfield_bit_size, - child_bitfield_bit_offset, - child_is_base_class, - child_is_deref_of_parent); - - case clang::Type::Paren: - return GetChildClangTypeAtIndex (exe_ctx, - ast, - parent_name, - llvm::cast<clang::ParenType>(parent_qual_type)->desugar().getAsOpaquePtr(), - idx, - transparent_pointers, - omit_empty_base_classes, - ignore_array_bounds, - child_name, - child_byte_size, - child_byte_offset, - child_bitfield_bit_size, - child_bitfield_bit_offset, - child_is_base_class, - child_is_deref_of_parent); - - - default: - break; - } - return NULL; + return ClangASTType (ast, ast->getObjCInterfaceType(decl)); } static inline bool @@ -4660,8 +1763,8 @@ BaseSpecifierIsEmpty (const CXXBaseSpecifier *b) return ClangASTContext::RecordHasFields(b->getType()->getAsCXXRecordDecl()) == false; } -static uint32_t -GetNumBaseClasses (const CXXRecordDecl *cxx_record_decl, bool omit_empty_base_classes) +uint32_t +ClangASTContext::GetNumBaseClasses (const CXXRecordDecl *cxx_record_decl, bool omit_empty_base_classes) { uint32_t num_bases = 0; if (cxx_record_decl) @@ -4689,739 +1792,6 @@ GetNumBaseClasses (const CXXRecordDecl *cxx_record_decl, bool omit_empty_base_cl } -static uint32_t -GetIndexForRecordBase -( - const RecordDecl *record_decl, - const CXXBaseSpecifier *base_spec, - bool omit_empty_base_classes -) -{ - uint32_t child_idx = 0; - - const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl); - -// const char *super_name = record_decl->getNameAsCString(); -// const char *base_name = base_spec->getType()->getAs<RecordType>()->getDecl()->getNameAsCString(); -// printf ("GetIndexForRecordChild (%s, %s)\n", super_name, base_name); -// - if (cxx_record_decl) - { - CXXRecordDecl::base_class_const_iterator base_class, base_class_end; - for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end(); - base_class != base_class_end; - ++base_class) - { - if (omit_empty_base_classes) - { - if (BaseSpecifierIsEmpty (base_class)) - continue; - } - -// printf ("GetIndexForRecordChild (%s, %s) base[%u] = %s\n", super_name, base_name, -// child_idx, -// base_class->getType()->getAs<RecordType>()->getDecl()->getNameAsCString()); -// -// - if (base_class == base_spec) - return child_idx; - ++child_idx; - } - } - - return UINT32_MAX; -} - - -static uint32_t -GetIndexForRecordChild -( - const RecordDecl *record_decl, - NamedDecl *canonical_decl, - bool omit_empty_base_classes -) -{ - uint32_t child_idx = GetNumBaseClasses (dyn_cast<CXXRecordDecl>(record_decl), omit_empty_base_classes); - -// const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl); -// -//// printf ("GetIndexForRecordChild (%s, %s)\n", record_decl->getNameAsCString(), canonical_decl->getNameAsCString()); -// if (cxx_record_decl) -// { -// CXXRecordDecl::base_class_const_iterator base_class, base_class_end; -// for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end(); -// base_class != base_class_end; -// ++base_class) -// { -// if (omit_empty_base_classes) -// { -// if (BaseSpecifierIsEmpty (base_class)) -// continue; -// } -// -//// printf ("GetIndexForRecordChild (%s, %s) base[%u] = %s\n", -//// record_decl->getNameAsCString(), -//// canonical_decl->getNameAsCString(), -//// child_idx, -//// base_class->getType()->getAs<RecordType>()->getDecl()->getNameAsCString()); -// -// -// CXXRecordDecl *curr_base_class_decl = cast<CXXRecordDecl>(base_class->getType()->getAs<RecordType>()->getDecl()); -// if (curr_base_class_decl == canonical_decl) -// { -// return child_idx; -// } -// ++child_idx; -// } -// } -// -// const uint32_t num_bases = child_idx; - RecordDecl::field_iterator field, field_end; - for (field = record_decl->field_begin(), field_end = record_decl->field_end(); - field != field_end; - ++field, ++child_idx) - { -// printf ("GetIndexForRecordChild (%s, %s) field[%u] = %s\n", -// record_decl->getNameAsCString(), -// canonical_decl->getNameAsCString(), -// child_idx - num_bases, -// field->getNameAsCString()); - - if (field->getCanonicalDecl() == canonical_decl) - return child_idx; - } - - return UINT32_MAX; -} - -// Look for a child member (doesn't include base classes, but it does include -// their members) in the type hierarchy. Returns an index path into "clang_type" -// on how to reach the appropriate member. -// -// class A -// { -// public: -// int m_a; -// int m_b; -// }; -// -// class B -// { -// }; -// -// class C : -// public B, -// public A -// { -// }; -// -// If we have a clang type that describes "class C", and we wanted to looked -// "m_b" in it: -// -// With omit_empty_base_classes == false we would get an integer array back with: -// { 1, 1 } -// The first index 1 is the child index for "class A" within class C -// The second index 1 is the child index for "m_b" within class A -// -// With omit_empty_base_classes == true we would get an integer array back with: -// { 0, 1 } -// The first index 0 is the child index for "class A" within class C (since class B doesn't have any members it doesn't count) -// The second index 1 is the child index for "m_b" within class A - -size_t -ClangASTContext::GetIndexOfChildMemberWithName -( - ASTContext *ast, - clang_type_t clang_type, - const char *name, - bool omit_empty_base_classes, - std::vector<uint32_t>& child_indexes -) -{ - if (clang_type && name && name[0]) - { - QualType qual_type(QualType::getFromOpaquePtr(clang_type)); - const clang::Type::TypeClass type_class = qual_type->getTypeClass(); - switch (type_class) - { - case clang::Type::Record: - if (GetCompleteQualType (ast, qual_type)) - { - const RecordType *record_type = cast<RecordType>(qual_type.getTypePtr()); - const RecordDecl *record_decl = record_type->getDecl(); - - assert(record_decl); - uint32_t child_idx = 0; - - const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl); - - // Try and find a field that matches NAME - RecordDecl::field_iterator field, field_end; - StringRef name_sref(name); - for (field = record_decl->field_begin(), field_end = record_decl->field_end(); - field != field_end; - ++field, ++child_idx) - { - if (field->getName().equals (name_sref)) - { - // We have to add on the number of base classes to this index! - child_indexes.push_back (child_idx + GetNumBaseClasses (cxx_record_decl, omit_empty_base_classes)); - return child_indexes.size(); - } - } - - if (cxx_record_decl) - { - const RecordDecl *parent_record_decl = cxx_record_decl; - - //printf ("parent = %s\n", parent_record_decl->getNameAsCString()); - - //const Decl *root_cdecl = cxx_record_decl->getCanonicalDecl(); - // Didn't find things easily, lets let clang do its thang... - IdentifierInfo & ident_ref = ast->Idents.get(name_sref); - DeclarationName decl_name(&ident_ref); - - CXXBasePaths paths; - if (cxx_record_decl->lookupInBases(CXXRecordDecl::FindOrdinaryMember, - decl_name.getAsOpaquePtr(), - paths)) - { - CXXBasePaths::const_paths_iterator path, path_end = paths.end(); - for (path = paths.begin(); path != path_end; ++path) - { - const size_t num_path_elements = path->size(); - for (size_t e=0; e<num_path_elements; ++e) - { - CXXBasePathElement elem = (*path)[e]; - - child_idx = GetIndexForRecordBase (parent_record_decl, elem.Base, omit_empty_base_classes); - if (child_idx == UINT32_MAX) - { - child_indexes.clear(); - return 0; - } - else - { - child_indexes.push_back (child_idx); - parent_record_decl = cast<RecordDecl>(elem.Base->getType()->getAs<RecordType>()->getDecl()); - } - } - for (NamedDecl *path_decl : path->Decls) - { - child_idx = GetIndexForRecordChild (parent_record_decl, path_decl, omit_empty_base_classes); - if (child_idx == UINT32_MAX) - { - child_indexes.clear(); - return 0; - } - else - { - child_indexes.push_back (child_idx); - } - } - } - return child_indexes.size(); - } - } - - } - break; - - case clang::Type::ObjCObject: - case clang::Type::ObjCInterface: - if (GetCompleteQualType (ast, qual_type)) - { - StringRef name_sref(name); - const ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(qual_type.getTypePtr()); - assert (objc_class_type); - if (objc_class_type) - { - uint32_t child_idx = 0; - ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface(); - - if (class_interface_decl) - { - ObjCInterfaceDecl::ivar_iterator ivar_pos, ivar_end = class_interface_decl->ivar_end(); - ObjCInterfaceDecl *superclass_interface_decl = class_interface_decl->getSuperClass(); - - for (ivar_pos = class_interface_decl->ivar_begin(); ivar_pos != ivar_end; ++ivar_pos, ++child_idx) - { - const ObjCIvarDecl* ivar_decl = *ivar_pos; - - if (ivar_decl->getName().equals (name_sref)) - { - if ((!omit_empty_base_classes && superclass_interface_decl) || - ( omit_empty_base_classes && ObjCDeclHasIVars (superclass_interface_decl, true))) - ++child_idx; - - child_indexes.push_back (child_idx); - return child_indexes.size(); - } - } - - if (superclass_interface_decl) - { - // The super class index is always zero for ObjC classes, - // so we push it onto the child indexes in case we find - // an ivar in our superclass... - child_indexes.push_back (0); - - if (GetIndexOfChildMemberWithName (ast, - ast->getObjCInterfaceType(superclass_interface_decl).getAsOpaquePtr(), - name, - omit_empty_base_classes, - child_indexes)) - { - // We did find an ivar in a superclass so just - // return the results! - return child_indexes.size(); - } - - // We didn't find an ivar matching "name" in our - // superclass, pop the superclass zero index that - // we pushed on above. - child_indexes.pop_back(); - } - } - } - } - break; - - case clang::Type::ObjCObjectPointer: - { - return GetIndexOfChildMemberWithName (ast, - cast<ObjCObjectPointerType>(qual_type.getTypePtr())->getPointeeType().getAsOpaquePtr(), - name, - omit_empty_base_classes, - child_indexes); - } - break; - - - case clang::Type::ConstantArray: - { -// const ConstantArrayType *array = cast<ConstantArrayType>(parent_qual_type.getTypePtr()); -// const uint64_t element_count = array->getSize().getLimitedValue(); -// -// if (idx < element_count) -// { -// std::pair<uint64_t, unsigned> field_type_info = ast->getTypeInfo(array->getElementType()); -// -// char element_name[32]; -// ::snprintf (element_name, sizeof (element_name), "%s[%u]", parent_name ? parent_name : "", idx); -// -// child_name.assign(element_name); -// assert(field_type_info.first % 8 == 0); -// child_byte_size = field_type_info.first / 8; -// child_byte_offset = idx * child_byte_size; -// return array->getElementType().getAsOpaquePtr(); -// } - } - break; - -// case clang::Type::MemberPointerType: -// { -// MemberPointerType *mem_ptr_type = cast<MemberPointerType>(qual_type.getTypePtr()); -// QualType pointee_type = mem_ptr_type->getPointeeType(); -// -// if (ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr())) -// { -// return GetIndexOfChildWithName (ast, -// mem_ptr_type->getPointeeType().getAsOpaquePtr(), -// name); -// } -// } -// break; -// - case clang::Type::LValueReference: - case clang::Type::RValueReference: - { - const ReferenceType *reference_type = cast<ReferenceType>(qual_type.getTypePtr()); - QualType pointee_type = reference_type->getPointeeType(); - - if (ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr())) - { - return GetIndexOfChildMemberWithName (ast, - reference_type->getPointeeType().getAsOpaquePtr(), - name, - omit_empty_base_classes, - child_indexes); - } - } - break; - - case clang::Type::Pointer: - { - const PointerType *pointer_type = cast<PointerType>(qual_type.getTypePtr()); - QualType pointee_type = pointer_type->getPointeeType(); - - if (ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr())) - { - return GetIndexOfChildMemberWithName (ast, - pointer_type->getPointeeType().getAsOpaquePtr(), - name, - omit_empty_base_classes, - child_indexes); - } - else - { -// if (parent_name) -// { -// child_name.assign(1, '*'); -// child_name += parent_name; -// } -// -// // We have a pointer to an simple type -// if (idx == 0) -// { -// std::pair<uint64_t, unsigned> clang_type_info = ast->getTypeInfo(pointee_type); -// assert(clang_type_info.first % 8 == 0); -// child_byte_size = clang_type_info.first / 8; -// child_byte_offset = 0; -// return pointee_type.getAsOpaquePtr(); -// } - } - } - break; - - case clang::Type::Typedef: - return GetIndexOfChildMemberWithName (ast, - cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr(), - name, - omit_empty_base_classes, - child_indexes); - - case clang::Type::Elaborated: - return GetIndexOfChildMemberWithName (ast, - cast<ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr(), - name, - omit_empty_base_classes, - child_indexes); - - case clang::Type::Paren: - return GetIndexOfChildMemberWithName (ast, - cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr(), - name, - omit_empty_base_classes, - child_indexes); - - default: - break; - } - } - return 0; -} - - -// Get the index of the child of "clang_type" whose name matches. This function -// doesn't descend into the children, but only looks one level deep and name -// matches can include base class names. - -uint32_t -ClangASTContext::GetIndexOfChildWithName -( - ASTContext *ast, - clang_type_t clang_type, - const char *name, - bool omit_empty_base_classes -) -{ - if (clang_type && name && name[0]) - { - QualType qual_type(QualType::getFromOpaquePtr(clang_type)); - - const clang::Type::TypeClass type_class = qual_type->getTypeClass(); - - switch (type_class) - { - case clang::Type::Record: - if (GetCompleteQualType (ast, qual_type)) - { - const RecordType *record_type = cast<RecordType>(qual_type.getTypePtr()); - const RecordDecl *record_decl = record_type->getDecl(); - - assert(record_decl); - uint32_t child_idx = 0; - - const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl); - - if (cxx_record_decl) - { - CXXRecordDecl::base_class_const_iterator base_class, base_class_end; - for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end(); - base_class != base_class_end; - ++base_class) - { - // Skip empty base classes - CXXRecordDecl *base_class_decl = cast<CXXRecordDecl>(base_class->getType()->getAs<RecordType>()->getDecl()); - if (omit_empty_base_classes && RecordHasFields(base_class_decl) == false) - continue; - - std::string base_class_type_name (ClangASTType::GetTypeNameForQualType(ast, base_class->getType())); - if (base_class_type_name.compare (name) == 0) - return child_idx; - ++child_idx; - } - } - - // Try and find a field that matches NAME - RecordDecl::field_iterator field, field_end; - StringRef name_sref(name); - for (field = record_decl->field_begin(), field_end = record_decl->field_end(); - field != field_end; - ++field, ++child_idx) - { - if (field->getName().equals (name_sref)) - return child_idx; - } - - } - break; - - case clang::Type::ObjCObject: - case clang::Type::ObjCInterface: - if (GetCompleteQualType (ast, qual_type)) - { - StringRef name_sref(name); - const ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(qual_type.getTypePtr()); - assert (objc_class_type); - if (objc_class_type) - { - uint32_t child_idx = 0; - ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface(); - - if (class_interface_decl) - { - ObjCInterfaceDecl::ivar_iterator ivar_pos, ivar_end = class_interface_decl->ivar_end(); - ObjCInterfaceDecl *superclass_interface_decl = class_interface_decl->getSuperClass(); - - for (ivar_pos = class_interface_decl->ivar_begin(); ivar_pos != ivar_end; ++ivar_pos, ++child_idx) - { - const ObjCIvarDecl* ivar_decl = *ivar_pos; - - if (ivar_decl->getName().equals (name_sref)) - { - if ((!omit_empty_base_classes && superclass_interface_decl) || - ( omit_empty_base_classes && ObjCDeclHasIVars (superclass_interface_decl, true))) - ++child_idx; - - return child_idx; - } - } - - if (superclass_interface_decl) - { - if (superclass_interface_decl->getName().equals (name_sref)) - return 0; - } - } - } - } - break; - - case clang::Type::ObjCObjectPointer: - { - return GetIndexOfChildWithName (ast, - cast<ObjCObjectPointerType>(qual_type.getTypePtr())->getPointeeType().getAsOpaquePtr(), - name, - omit_empty_base_classes); - } - break; - - case clang::Type::ConstantArray: - { -// const ConstantArrayType *array = cast<ConstantArrayType>(parent_qual_type.getTypePtr()); -// const uint64_t element_count = array->getSize().getLimitedValue(); -// -// if (idx < element_count) -// { -// std::pair<uint64_t, unsigned> field_type_info = ast->getTypeInfo(array->getElementType()); -// -// char element_name[32]; -// ::snprintf (element_name, sizeof (element_name), "%s[%u]", parent_name ? parent_name : "", idx); -// -// child_name.assign(element_name); -// assert(field_type_info.first % 8 == 0); -// child_byte_size = field_type_info.first / 8; -// child_byte_offset = idx * child_byte_size; -// return array->getElementType().getAsOpaquePtr(); -// } - } - break; - -// case clang::Type::MemberPointerType: -// { -// MemberPointerType *mem_ptr_type = cast<MemberPointerType>(qual_type.getTypePtr()); -// QualType pointee_type = mem_ptr_type->getPointeeType(); -// -// if (ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr())) -// { -// return GetIndexOfChildWithName (ast, -// mem_ptr_type->getPointeeType().getAsOpaquePtr(), -// name); -// } -// } -// break; -// - case clang::Type::LValueReference: - case clang::Type::RValueReference: - { - const ReferenceType *reference_type = cast<ReferenceType>(qual_type.getTypePtr()); - QualType pointee_type = reference_type->getPointeeType(); - - if (ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr())) - { - return GetIndexOfChildWithName (ast, - reference_type->getPointeeType().getAsOpaquePtr(), - name, - omit_empty_base_classes); - } - } - break; - - case clang::Type::Pointer: - { - const PointerType *pointer_type = cast<PointerType>(qual_type.getTypePtr()); - QualType pointee_type = pointer_type->getPointeeType(); - - if (ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr())) - { - return GetIndexOfChildWithName (ast, - pointer_type->getPointeeType().getAsOpaquePtr(), - name, - omit_empty_base_classes); - } - else - { -// if (parent_name) -// { -// child_name.assign(1, '*'); -// child_name += parent_name; -// } -// -// // We have a pointer to an simple type -// if (idx == 0) -// { -// std::pair<uint64_t, unsigned> clang_type_info = ast->getTypeInfo(pointee_type); -// assert(clang_type_info.first % 8 == 0); -// child_byte_size = clang_type_info.first / 8; -// child_byte_offset = 0; -// return pointee_type.getAsOpaquePtr(); -// } - } - } - break; - - case clang::Type::Elaborated: - return GetIndexOfChildWithName (ast, - cast<ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr(), - name, - omit_empty_base_classes); - - case clang::Type::Paren: - return GetIndexOfChildWithName (ast, - cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr(), - name, - omit_empty_base_classes); - - case clang::Type::Typedef: - return GetIndexOfChildWithName (ast, - cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr(), - name, - omit_empty_base_classes); - - default: - break; - } - } - return UINT32_MAX; -} - -#pragma mark TagType - -bool -ClangASTContext::SetTagTypeKind (clang_type_t tag_clang_type, int kind) -{ - if (tag_clang_type) - { - QualType tag_qual_type(QualType::getFromOpaquePtr(tag_clang_type)); - const clang::Type *clang_type = tag_qual_type.getTypePtr(); - if (clang_type) - { - const TagType *tag_type = dyn_cast<TagType>(clang_type); - if (tag_type) - { - TagDecl *tag_decl = dyn_cast<TagDecl>(tag_type->getDecl()); - if (tag_decl) - { - tag_decl->setTagKind ((TagDecl::TagKind)kind); - return true; - } - } - } - } - return false; -} - - -#pragma mark DeclContext Functions - -DeclContext * -ClangASTContext::GetDeclContextForType (clang_type_t clang_type) -{ - if (clang_type == NULL) - return NULL; - - QualType qual_type(QualType::getFromOpaquePtr(clang_type)); - const clang::Type::TypeClass type_class = qual_type->getTypeClass(); - switch (type_class) - { - case clang::Type::UnaryTransform: break; - case clang::Type::FunctionNoProto: break; - case clang::Type::FunctionProto: break; - case clang::Type::IncompleteArray: break; - case clang::Type::VariableArray: break; - case clang::Type::ConstantArray: break; - case clang::Type::DependentSizedArray: break; - case clang::Type::ExtVector: break; - case clang::Type::DependentSizedExtVector: break; - case clang::Type::Vector: break; - case clang::Type::Builtin: break; - case clang::Type::BlockPointer: break; - case clang::Type::Pointer: break; - case clang::Type::LValueReference: break; - case clang::Type::RValueReference: break; - case clang::Type::MemberPointer: break; - case clang::Type::Complex: break; - case clang::Type::ObjCObject: break; - case clang::Type::ObjCInterface: return cast<ObjCObjectType>(qual_type.getTypePtr())->getInterface(); - case clang::Type::ObjCObjectPointer: return ClangASTContext::GetDeclContextForType (cast<ObjCObjectPointerType>(qual_type.getTypePtr())->getPointeeType().getAsOpaquePtr()); - case clang::Type::Record: return cast<RecordType>(qual_type)->getDecl(); - case clang::Type::Enum: return cast<EnumType>(qual_type)->getDecl(); - case clang::Type::Typedef: return ClangASTContext::GetDeclContextForType (cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr()); - case clang::Type::Elaborated: return ClangASTContext::GetDeclContextForType (cast<ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr()); - case clang::Type::Paren: return ClangASTContext::GetDeclContextForType (cast<ParenType>(qual_type)->desugar().getAsOpaquePtr()); - case clang::Type::TypeOfExpr: break; - case clang::Type::TypeOf: break; - case clang::Type::Decltype: break; - //case clang::Type::QualifiedName: break; - case clang::Type::TemplateSpecialization: break; - case clang::Type::DependentTemplateSpecialization: break; - case clang::Type::TemplateTypeParm: break; - case clang::Type::SubstTemplateTypeParm: break; - case clang::Type::SubstTemplateTypeParmPack:break; - case clang::Type::PackExpansion: break; - case clang::Type::UnresolvedUsing: break; - case clang::Type::Attributed: break; - case clang::Type::Auto: break; - case clang::Type::InjectedClassName: break; - case clang::Type::DependentName: break; - case clang::Type::Atomic: break; - } - // No DeclContext in this type... - return NULL; -} - #pragma mark Namespace Declarations NamespaceDecl * @@ -5527,7 +1897,11 @@ ClangASTContext::GetUniqueNamespaceDeclaration (const char *name, DeclContext *d #pragma mark Function Types FunctionDecl * -ClangASTContext::CreateFunctionDeclaration (DeclContext *decl_ctx, const char *name, clang_type_t function_clang_type, int storage, bool is_inline) +ClangASTContext::CreateFunctionDeclaration (DeclContext *decl_ctx, + const char *name, + const ClangASTType &function_clang_type, + int storage, + bool is_inline) { FunctionDecl *func_decl = NULL; ASTContext *ast = getASTContext(); @@ -5545,7 +1919,7 @@ ClangASTContext::CreateFunctionDeclaration (DeclContext *decl_ctx, const char *n SourceLocation(), SourceLocation(), DeclarationName (&ast->Idents.get(name)), - QualType::getFromOpaquePtr(function_clang_type), + function_clang_type.GetQualType(), NULL, (FunctionDecl::StorageClass)storage, is_inline, @@ -5559,7 +1933,7 @@ ClangASTContext::CreateFunctionDeclaration (DeclContext *decl_ctx, const char *n SourceLocation(), SourceLocation(), DeclarationName (), - QualType::getFromOpaquePtr(function_clang_type), + function_clang_type.GetQualType(), NULL, (FunctionDecl::StorageClass)storage, is_inline, @@ -5576,10 +1950,10 @@ ClangASTContext::CreateFunctionDeclaration (DeclContext *decl_ctx, const char *n return func_decl; } -clang_type_t +ClangASTType ClangASTContext::CreateFunctionType (ASTContext *ast, - clang_type_t result_type, - clang_type_t *args, + const ClangASTType& result_type, + const ClangASTType *args, unsigned num_args, bool is_variadic, unsigned type_quals) @@ -5587,7 +1961,7 @@ ClangASTContext::CreateFunctionType (ASTContext *ast, assert (ast != NULL); std::vector<QualType> qual_type_args; for (unsigned i=0; i<num_args; ++i) - qual_type_args.push_back (QualType::getFromOpaquePtr(args[i])); + qual_type_args.push_back (args[i].GetQualType()); // TODO: Detect calling convention in DWARF? FunctionProtoType::ExtProtoInfo proto_info; @@ -5598,13 +1972,13 @@ ClangASTContext::CreateFunctionType (ASTContext *ast, proto_info.NumExceptions = 0; proto_info.Exceptions = NULL; - return ast->getFunctionType (QualType::getFromOpaquePtr(result_type), - qual_type_args, - proto_info).getAsOpaquePtr(); + return ClangASTType (ast, ast->getFunctionType (result_type.GetQualType(), + qual_type_args, + proto_info).getAsOpaquePtr()); } ParmVarDecl * -ClangASTContext::CreateParameterDeclaration (const char *name, clang_type_t param_type, int storage) +ClangASTContext::CreateParameterDeclaration (const char *name, const ClangASTType ¶m_type, int storage) { ASTContext *ast = getASTContext(); assert (ast != NULL); @@ -5613,7 +1987,7 @@ ClangASTContext::CreateParameterDeclaration (const char *name, clang_type_t para SourceLocation(), SourceLocation(), name && name[0] ? &ast->Idents.get(name) : NULL, - QualType::getFromOpaquePtr(param_type), + param_type.GetQualType(), NULL, (VarDecl::StorageClass)storage, 0); @@ -5629,21 +2003,19 @@ ClangASTContext::SetFunctionParameters (FunctionDecl *function_decl, ParmVarDecl #pragma mark Array Types -clang_type_t -ClangASTContext::CreateArrayType (clang_type_t element_type, +ClangASTType +ClangASTContext::CreateArrayType (const ClangASTType &element_type, size_t element_count, bool is_vector) { - if (element_type) + if (element_type.IsValid()) { ASTContext *ast = getASTContext(); assert (ast != NULL); - QualType element_qual_type(QualType::getFromOpaquePtr(element_type)); - if (is_vector) { - return ast->getExtVectorType(element_qual_type, element_count).getAsOpaquePtr(); + return ClangASTType (ast, ast->getExtVectorType(element_type.GetQualType(), element_count).getAsOpaquePtr()); } else { @@ -5651,129 +2023,38 @@ ClangASTContext::CreateArrayType (clang_type_t element_type, llvm::APInt ap_element_count (64, element_count); if (element_count == 0) { - return ast->getIncompleteArrayType(element_qual_type, - ArrayType::Normal, - 0).getAsOpaquePtr(); - + return ClangASTType (ast, ast->getIncompleteArrayType (element_type.GetQualType(), + ArrayType::Normal, + 0).getAsOpaquePtr()); } else { - return ast->getConstantArrayType(element_qual_type, - ap_element_count, - ArrayType::Normal, - 0).getAsOpaquePtr(); // ElemQuals - } - } - } - return NULL; -} - - -#pragma mark TagDecl - -bool -ClangASTContext::StartTagDeclarationDefinition (clang_type_t clang_type) -{ - if (clang_type) - { - QualType qual_type (QualType::getFromOpaquePtr(clang_type)); - const clang::Type *t = qual_type.getTypePtr(); - if (t) - { - const TagType *tag_type = dyn_cast<TagType>(t); - if (tag_type) - { - TagDecl *tag_decl = tag_type->getDecl(); - if (tag_decl) - { - tag_decl->startDefinition(); - return true; - } - } - - const ObjCObjectType *object_type = dyn_cast<ObjCObjectType>(t); - if (object_type) - { - ObjCInterfaceDecl *interface_decl = object_type->getInterface(); - if (interface_decl) - { - interface_decl->startDefinition(); - return true; - } + return ClangASTType (ast, ast->getConstantArrayType (element_type.GetQualType(), + ap_element_count, + ArrayType::Normal, + 0).getAsOpaquePtr()); } } } - return false; + return ClangASTType(); } -bool -ClangASTContext::CompleteTagDeclarationDefinition (clang_type_t clang_type) -{ - if (clang_type) - { - QualType qual_type (QualType::getFromOpaquePtr(clang_type)); - - CXXRecordDecl *cxx_record_decl = qual_type->getAsCXXRecordDecl(); - - if (cxx_record_decl) - { - cxx_record_decl->completeDefinition(); - - return true; - } - - const EnumType *enum_type = dyn_cast<EnumType>(qual_type.getTypePtr()); - - if (enum_type) - { - EnumDecl *enum_decl = enum_type->getDecl(); - - if (enum_decl) - { - /// TODO This really needs to be fixed. - - unsigned NumPositiveBits = 1; - unsigned NumNegativeBits = 0; - - ASTContext *ast = getASTContext(); - - QualType promotion_qual_type; - // If the enum integer type is less than an integer in bit width, - // then we must promote it to an integer size. - if (ast->getTypeSize(enum_decl->getIntegerType()) < ast->getTypeSize(ast->IntTy)) - { - if (enum_decl->getIntegerType()->isSignedIntegerType()) - promotion_qual_type = ast->IntTy; - else - promotion_qual_type = ast->UnsignedIntTy; - } - else - promotion_qual_type = enum_decl->getIntegerType(); - - enum_decl->completeDefinition(enum_decl->getIntegerType(), promotion_qual_type, NumPositiveBits, NumNegativeBits); - return true; - } - } - } - return false; -} #pragma mark Enumeration Types -clang_type_t +ClangASTType ClangASTContext::CreateEnumerationType ( const char *name, DeclContext *decl_ctx, const Declaration &decl, - clang_type_t integer_qual_type + const ClangASTType &integer_clang_type ) { // TODO: Do something intelligent with the Declaration object passed in // like maybe filling in the SourceLocation with it... ASTContext *ast = getASTContext(); - assert (ast != NULL); // TODO: ask about these... // const bool IsScoped = false; @@ -5793,896 +2074,13 @@ ClangASTContext::CreateEnumerationType if (enum_decl) { // TODO: check if we should be setting the promotion type too? - enum_decl->setIntegerType(QualType::getFromOpaquePtr (integer_qual_type)); + enum_decl->setIntegerType(integer_clang_type.GetQualType()); enum_decl->setAccess(AS_public); // TODO respect what's in the debug info - return ast->getTagDeclType(enum_decl).getAsOpaquePtr(); - } - return NULL; -} - -clang_type_t -ClangASTContext::GetEnumerationIntegerType (clang_type_t enum_clang_type) -{ - QualType enum_qual_type (QualType::getFromOpaquePtr(enum_clang_type)); - - const clang::Type *clang_type = enum_qual_type.getTypePtr(); - if (clang_type) - { - const EnumType *enum_type = dyn_cast<EnumType>(clang_type); - if (enum_type) - { - EnumDecl *enum_decl = enum_type->getDecl(); - if (enum_decl) - return enum_decl->getIntegerType().getAsOpaquePtr(); - } - } - return NULL; -} -bool -ClangASTContext::AddEnumerationValueToEnumerationType -( - clang_type_t enum_clang_type, - clang_type_t enumerator_clang_type, - const Declaration &decl, - const char *name, - int64_t enum_value, - uint32_t enum_value_bit_size -) -{ - if (enum_clang_type && enumerator_clang_type && name) - { - // TODO: Do something intelligent with the Declaration object passed in - // like maybe filling in the SourceLocation with it... - ASTContext *ast = getASTContext(); - IdentifierTable *identifier_table = getIdentifierTable(); - - assert (ast != NULL); - assert (identifier_table != NULL); - QualType enum_qual_type (QualType::getFromOpaquePtr(enum_clang_type)); - - bool is_signed = false; - IsIntegerType (enumerator_clang_type, is_signed); - const clang::Type *clang_type = enum_qual_type.getTypePtr(); - if (clang_type) - { - const EnumType *enum_type = dyn_cast<EnumType>(clang_type); - - if (enum_type) - { - llvm::APSInt enum_llvm_apsint(enum_value_bit_size, is_signed); - enum_llvm_apsint = enum_value; - EnumConstantDecl *enumerator_decl = - EnumConstantDecl::Create (*ast, - enum_type->getDecl(), - SourceLocation(), - name ? &identifier_table->get(name) : NULL, // Identifier - QualType::getFromOpaquePtr(enumerator_clang_type), - NULL, - enum_llvm_apsint); - - if (enumerator_decl) - { - enum_type->getDecl()->addDecl(enumerator_decl); - -#ifdef LLDB_CONFIGURATION_DEBUG - VerifyDecl(enumerator_decl); -#endif - - return true; - } - } - } - } - return false; -} - -#pragma mark Pointers & References - -clang_type_t -ClangASTContext::CreatePointerType (clang_type_t clang_type) -{ - return CreatePointerType (getASTContext(), clang_type); -} - -clang_type_t -ClangASTContext::CreatePointerType (clang::ASTContext *ast, clang_type_t clang_type) -{ - if (ast && clang_type) - { - QualType qual_type (QualType::getFromOpaquePtr(clang_type)); - - const clang::Type::TypeClass type_class = qual_type->getTypeClass(); - switch (type_class) - { - case clang::Type::ObjCObject: - case clang::Type::ObjCInterface: - return ast->getObjCObjectPointerType(qual_type).getAsOpaquePtr(); - - default: - return ast->getPointerType(qual_type).getAsOpaquePtr(); - } - } - return NULL; -} - -clang_type_t -ClangASTContext::CreateLValueReferenceType (clang::ASTContext *ast, - clang_type_t clang_type) -{ - if (clang_type) - return ast->getLValueReferenceType (QualType::getFromOpaquePtr(clang_type)).getAsOpaquePtr(); - return NULL; -} - -clang_type_t -ClangASTContext::CreateRValueReferenceType (clang::ASTContext *ast, - clang_type_t clang_type) -{ - if (clang_type) - return ast->getRValueReferenceType (QualType::getFromOpaquePtr(clang_type)).getAsOpaquePtr(); - return NULL; -} - -clang_type_t -ClangASTContext::CreateMemberPointerType (clang_type_t clang_pointee_type, clang_type_t clang_class_type) -{ - if (clang_pointee_type && clang_pointee_type) - return getASTContext()->getMemberPointerType(QualType::getFromOpaquePtr(clang_pointee_type), - QualType::getFromOpaquePtr(clang_class_type).getTypePtr()).getAsOpaquePtr(); - return NULL; -} - -uint64_t -ClangASTContext::GetPointerBitSize () -{ - ASTContext *ast = getASTContext(); - return ast->getTypeSize(ast->VoidPtrTy); -} - -bool -ClangASTContext::IsPossibleDynamicType (clang::ASTContext *ast, - clang_type_t clang_type, - clang_type_t *dynamic_pointee_type, - bool check_cplusplus, - bool check_objc) -{ - QualType pointee_qual_type; - if (clang_type) - { - QualType qual_type (QualType::getFromOpaquePtr(clang_type).getCanonicalType()); - const clang::Type::TypeClass type_class = qual_type->getTypeClass(); - bool success = false; - switch (type_class) - { - case clang::Type::Builtin: - if (check_objc && cast<clang::BuiltinType>(qual_type)->getKind() == clang::BuiltinType::ObjCId) - { - if (dynamic_pointee_type) - *dynamic_pointee_type = clang_type; - return true; - } - break; - - case clang::Type::ObjCObjectPointer: - if (check_objc) - { - if (dynamic_pointee_type) - *dynamic_pointee_type = cast<ObjCObjectPointerType>(qual_type)->getPointeeType().getAsOpaquePtr(); - return true; - } - break; - - case clang::Type::Pointer: - pointee_qual_type = cast<PointerType>(qual_type)->getPointeeType(); - success = true; - break; - - case clang::Type::LValueReference: - case clang::Type::RValueReference: - pointee_qual_type = cast<ReferenceType>(qual_type)->getPointeeType(); - success = true; - break; - - case clang::Type::Typedef: - return ClangASTContext::IsPossibleDynamicType (ast, - cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr(), - dynamic_pointee_type, - check_cplusplus, - check_objc); - - case clang::Type::Elaborated: - return ClangASTContext::IsPossibleDynamicType (ast, - cast<ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr(), - dynamic_pointee_type, - check_cplusplus, - check_objc); - - case clang::Type::Paren: - return ClangASTContext::IsPossibleDynamicType (ast, - cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr(), - dynamic_pointee_type, - check_cplusplus, - check_objc); - default: - break; - } - - if (success) - { - // Check to make sure what we are pointing too is a possible dynamic C++ type - // We currently accept any "void *" (in case we have a class that has been - // watered down to an opaque pointer) and virtual C++ classes. - const clang::Type::TypeClass pointee_type_class = pointee_qual_type.getCanonicalType()->getTypeClass(); - switch (pointee_type_class) - { - case clang::Type::Builtin: - switch (cast<clang::BuiltinType>(pointee_qual_type)->getKind()) - { - case clang::BuiltinType::UnknownAny: - case clang::BuiltinType::Void: - if (dynamic_pointee_type) - *dynamic_pointee_type = pointee_qual_type.getAsOpaquePtr(); - return true; - - case clang::BuiltinType::NullPtr: - case clang::BuiltinType::Bool: - case clang::BuiltinType::Char_U: - case clang::BuiltinType::UChar: - case clang::BuiltinType::WChar_U: - case clang::BuiltinType::Char16: - case clang::BuiltinType::Char32: - case clang::BuiltinType::UShort: - case clang::BuiltinType::UInt: - case clang::BuiltinType::ULong: - case clang::BuiltinType::ULongLong: - case clang::BuiltinType::UInt128: - case clang::BuiltinType::Char_S: - case clang::BuiltinType::SChar: - case clang::BuiltinType::WChar_S: - case clang::BuiltinType::Short: - case clang::BuiltinType::Int: - case clang::BuiltinType::Long: - case clang::BuiltinType::LongLong: - case clang::BuiltinType::Int128: - case clang::BuiltinType::Float: - case clang::BuiltinType::Double: - case clang::BuiltinType::LongDouble: - case clang::BuiltinType::Dependent: - case clang::BuiltinType::Overload: - case clang::BuiltinType::ObjCId: - case clang::BuiltinType::ObjCClass: - case clang::BuiltinType::ObjCSel: - case clang::BuiltinType::BoundMember: - case clang::BuiltinType::Half: - case clang::BuiltinType::ARCUnbridgedCast: - case clang::BuiltinType::PseudoObject: - case clang::BuiltinType::BuiltinFn: - case clang::BuiltinType::OCLEvent: - case clang::BuiltinType::OCLImage1d: - case clang::BuiltinType::OCLImage1dArray: - case clang::BuiltinType::OCLImage1dBuffer: - case clang::BuiltinType::OCLImage2d: - case clang::BuiltinType::OCLImage2dArray: - case clang::BuiltinType::OCLImage3d: - case clang::BuiltinType::OCLSampler: - break; - } - break; - - case clang::Type::Record: - if (check_cplusplus) - { - CXXRecordDecl *cxx_record_decl = pointee_qual_type->getAsCXXRecordDecl(); - if (cxx_record_decl) - { - bool is_complete = cxx_record_decl->isCompleteDefinition(); - - if (is_complete) - success = cxx_record_decl->isDynamicClass(); - else - { - ClangASTMetadata *metadata = GetMetadata (ast, cxx_record_decl); - if (metadata) - success = metadata->GetIsDynamicCXXType(); - else - { - is_complete = ClangASTContext::GetCompleteType (ast, pointee_qual_type.getAsOpaquePtr()); - if (is_complete) - success = cxx_record_decl->isDynamicClass(); - else - success = false; - } - } - - if (success) - { - if (dynamic_pointee_type) - *dynamic_pointee_type = pointee_qual_type.getAsOpaquePtr(); - return true; - } - } - } - break; - - case clang::Type::ObjCObject: - case clang::Type::ObjCInterface: - if (check_objc) - { - if (dynamic_pointee_type) - *dynamic_pointee_type = pointee_qual_type.getAsOpaquePtr(); - return true; - } - break; - - default: - break; - } - } - } - if (dynamic_pointee_type) - *dynamic_pointee_type = NULL; - return false; -} - - -bool -ClangASTContext::IsPossibleCPlusPlusDynamicType (clang::ASTContext *ast, clang_type_t clang_type, clang_type_t *dynamic_pointee_type) -{ - return IsPossibleDynamicType (ast, - clang_type, - dynamic_pointee_type, - true, // Check for dynamic C++ types - false); // Check for dynamic ObjC types -} - -bool -ClangASTContext::IsReferenceType (clang_type_t clang_type, clang_type_t *target_type) -{ - if (clang_type == NULL) - return false; - - QualType qual_type (QualType::getFromOpaquePtr(clang_type)); - const clang::Type::TypeClass type_class = qual_type->getTypeClass(); - - switch (type_class) - { - case clang::Type::LValueReference: - if (target_type) - *target_type = cast<LValueReferenceType>(qual_type)->desugar().getAsOpaquePtr(); - return true; - case clang::Type::RValueReference: - if (target_type) - *target_type = cast<LValueReferenceType>(qual_type)->desugar().getAsOpaquePtr(); - return true; - case clang::Type::Typedef: - return ClangASTContext::IsReferenceType (cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr()); - case clang::Type::Elaborated: - return ClangASTContext::IsReferenceType (cast<ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr()); - case clang::Type::Paren: - return ClangASTContext::IsReferenceType (cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr()); - - default: - break; - } - - return false; -} - -bool -ClangASTContext::IsPointerOrReferenceType (clang_type_t clang_type, clang_type_t*target_type) -{ - if (clang_type == NULL) - return false; - - QualType qual_type (QualType::getFromOpaquePtr(clang_type)); - const clang::Type::TypeClass type_class = qual_type->getTypeClass(); - switch (type_class) - { - case clang::Type::Builtin: - switch (cast<clang::BuiltinType>(qual_type)->getKind()) - { - default: - break; - case clang::BuiltinType::ObjCId: - case clang::BuiltinType::ObjCClass: - return true; - } - return false; - case clang::Type::ObjCObjectPointer: - if (target_type) - *target_type = cast<ObjCObjectPointerType>(qual_type)->getPointeeType().getAsOpaquePtr(); - return true; - case clang::Type::BlockPointer: - if (target_type) - *target_type = cast<BlockPointerType>(qual_type)->getPointeeType().getAsOpaquePtr(); - return true; - case clang::Type::Pointer: - if (target_type) - *target_type = cast<PointerType>(qual_type)->getPointeeType().getAsOpaquePtr(); - return true; - case clang::Type::MemberPointer: - if (target_type) - *target_type = cast<MemberPointerType>(qual_type)->getPointeeType().getAsOpaquePtr(); - return true; - case clang::Type::LValueReference: - if (target_type) - *target_type = cast<LValueReferenceType>(qual_type)->desugar().getAsOpaquePtr(); - return true; - case clang::Type::RValueReference: - if (target_type) - *target_type = cast<LValueReferenceType>(qual_type)->desugar().getAsOpaquePtr(); - return true; - case clang::Type::Typedef: - return ClangASTContext::IsPointerOrReferenceType (cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr()); - case clang::Type::Elaborated: - return ClangASTContext::IsPointerOrReferenceType (cast<ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr()); - case clang::Type::Paren: - return ClangASTContext::IsPointerOrReferenceType (cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr()); - default: - break; - } - return false; -} - -bool -ClangASTContext::IsIntegerType (clang_type_t clang_type, bool &is_signed) -{ - if (!clang_type) - return false; - - QualType qual_type (QualType::getFromOpaquePtr(clang_type)); - const BuiltinType *builtin_type = dyn_cast<BuiltinType>(qual_type->getCanonicalTypeInternal()); - - if (builtin_type) - { - if (builtin_type->isInteger()) - { - is_signed = builtin_type->isSignedInteger(); - return true; - } - } - - return false; -} - -bool -ClangASTContext::IsPointerType (clang_type_t clang_type, clang_type_t *target_type) -{ - if (target_type) - *target_type = NULL; - - if (clang_type) - { - QualType qual_type (QualType::getFromOpaquePtr(clang_type)); - const clang::Type::TypeClass type_class = qual_type->getTypeClass(); - switch (type_class) - { - case clang::Type::Builtin: - switch (cast<clang::BuiltinType>(qual_type)->getKind()) - { - default: - break; - case clang::BuiltinType::ObjCId: - case clang::BuiltinType::ObjCClass: - return true; - } - return false; - case clang::Type::ObjCObjectPointer: - if (target_type) - *target_type = cast<ObjCObjectPointerType>(qual_type)->getPointeeType().getAsOpaquePtr(); - return true; - case clang::Type::BlockPointer: - if (target_type) - *target_type = cast<BlockPointerType>(qual_type)->getPointeeType().getAsOpaquePtr(); - return true; - case clang::Type::Pointer: - if (target_type) - *target_type = cast<PointerType>(qual_type)->getPointeeType().getAsOpaquePtr(); - return true; - case clang::Type::MemberPointer: - if (target_type) - *target_type = cast<MemberPointerType>(qual_type)->getPointeeType().getAsOpaquePtr(); - return true; - case clang::Type::Typedef: - return ClangASTContext::IsPointerType (cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr(), target_type); - case clang::Type::Elaborated: - return ClangASTContext::IsPointerType (cast<ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr(), target_type); - case clang::Type::Paren: - return ClangASTContext::IsPointerType (cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr(), target_type); - default: - break; - } - } - return false; -} - -bool -ClangASTContext::IsFloatingPointType (clang_type_t clang_type, uint32_t &count, bool &is_complex) -{ - if (clang_type) - { - QualType qual_type (QualType::getFromOpaquePtr(clang_type)); - - if (const BuiltinType *BT = dyn_cast<BuiltinType>(qual_type->getCanonicalTypeInternal())) - { - clang::BuiltinType::Kind kind = BT->getKind(); - if (kind >= BuiltinType::Float && kind <= BuiltinType::LongDouble) - { - count = 1; - is_complex = false; - return true; - } - } - else if (const ComplexType *CT = dyn_cast<ComplexType>(qual_type->getCanonicalTypeInternal())) - { - if (IsFloatingPointType(CT->getElementType().getAsOpaquePtr(), count, is_complex)) - { - count = 2; - is_complex = true; - return true; - } - } - else if (const VectorType *VT = dyn_cast<VectorType>(qual_type->getCanonicalTypeInternal())) - { - if (IsFloatingPointType(VT->getElementType().getAsOpaquePtr(), count, is_complex)) - { - count = VT->getNumElements(); - is_complex = false; - return true; - } - } - } - return false; -} - -bool -ClangASTContext::IsScalarType (lldb::clang_type_t clang_type) -{ - bool is_signed; - if (ClangASTContext::IsIntegerType(clang_type, is_signed)) - return true; - - uint32_t count; - bool is_complex; - return ClangASTContext::IsFloatingPointType(clang_type, count, is_complex) && !is_complex; -} - -bool -ClangASTContext::IsPointerToScalarType (lldb::clang_type_t clang_type) -{ - if (!IsPointerType(clang_type)) - return false; - - QualType qual_type (QualType::getFromOpaquePtr(clang_type)); - lldb::clang_type_t pointee_type = qual_type.getTypePtr()->getPointeeType().getAsOpaquePtr(); - return IsScalarType(pointee_type); -} - -bool -ClangASTContext::IsArrayOfScalarType (lldb::clang_type_t clang_type) -{ - clang_type = GetAsArrayType(clang_type, NULL, NULL, NULL); - - if (clang_type == 0) - return false; - - QualType qual_type (QualType::getFromOpaquePtr(clang_type)); - lldb::clang_type_t item_type = cast<ArrayType>(qual_type.getTypePtr())->getElementType().getAsOpaquePtr(); - return IsScalarType(item_type); -} - - -bool -ClangASTContext::GetCXXClassName (clang_type_t clang_type, std::string &class_name) -{ - if (clang_type) - { - QualType qual_type (QualType::getFromOpaquePtr(clang_type)); - - CXXRecordDecl *cxx_record_decl = qual_type->getAsCXXRecordDecl(); - if (cxx_record_decl) - { - class_name.assign (cxx_record_decl->getIdentifier()->getNameStart()); - return true; - } - } - class_name.clear(); - return false; -} - - -bool -ClangASTContext::IsCXXClassType (clang_type_t clang_type) -{ - if (clang_type) - { - QualType qual_type (QualType::getFromOpaquePtr(clang_type)); - if (qual_type->getAsCXXRecordDecl() != NULL) - return true; - } - return false; -} - -bool -ClangASTContext::IsBeingDefined (lldb::clang_type_t clang_type) -{ - if (clang_type) - { - QualType qual_type (QualType::getFromOpaquePtr(clang_type)); - const clang::TagType *tag_type = dyn_cast<clang::TagType>(qual_type); - if (tag_type) - return tag_type->isBeingDefined(); - } - return false; -} - -bool -ClangASTContext::IsObjCClassType (clang_type_t clang_type) -{ - if (clang_type) - { - QualType qual_type (QualType::getFromOpaquePtr(clang_type)); - if (qual_type->isObjCObjectOrInterfaceType()) - return true; - } - return false; -} - -bool -ClangASTContext::IsObjCObjectPointerType (lldb::clang_type_t clang_type, clang_type_t *class_type) -{ - if (clang_type) - { - QualType qual_type (QualType::getFromOpaquePtr(clang_type)); - if (qual_type->isObjCObjectPointerType()) - { - if (class_type) - { - *class_type = NULL; - - if (!qual_type->isObjCClassType() && - !qual_type->isObjCIdType()) - { - const ObjCObjectPointerType *obj_pointer_type = dyn_cast<ObjCObjectPointerType>(qual_type); - if (!obj_pointer_type) - *class_type = NULL; - else - *class_type = QualType(obj_pointer_type->getInterfaceType(), 0).getAsOpaquePtr(); - } - } - return true; - } - } - return false; -} - -bool -ClangASTContext::GetObjCClassName (lldb::clang_type_t clang_type, - std::string &class_name) -{ - if (!clang_type) - return false; - - const ObjCObjectType *object_type = dyn_cast<ObjCObjectType>(QualType::getFromOpaquePtr(clang_type)); - if (!object_type) - return false; - - const ObjCInterfaceDecl *interface = object_type->getInterface(); - if (!interface) - return false; - - class_name = interface->getNameAsString(); - return true; -} - -bool -ClangASTContext::IsCharType (clang_type_t clang_type) -{ - if (clang_type) - return QualType::getFromOpaquePtr(clang_type)->isCharType(); - return false; -} - -bool -ClangASTContext::IsCStringType (clang_type_t clang_type, uint32_t &length) -{ - clang_type_t pointee_or_element_clang_type = NULL; - Flags type_flags (ClangASTContext::GetTypeInfo (clang_type, NULL, &pointee_or_element_clang_type)); - - if (pointee_or_element_clang_type == NULL) - return false; - - if (type_flags.AnySet (eTypeIsArray | eTypeIsPointer)) - { - QualType pointee_or_element_qual_type (QualType::getFromOpaquePtr (pointee_or_element_clang_type)); - - if (pointee_or_element_qual_type.getUnqualifiedType()->isCharType()) - { - QualType qual_type (QualType::getFromOpaquePtr(clang_type)); - if (type_flags.Test (eTypeIsArray)) - { - // We know the size of the array and it could be a C string - // since it is an array of characters - length = cast<ConstantArrayType>(qual_type.getTypePtr())->getSize().getLimitedValue(); - return true; - } - else - { - length = 0; - return true; - } - - } - } - return false; -} - -bool -ClangASTContext::IsFunctionPointerType (clang_type_t clang_type) -{ - if (clang_type) - { - QualType qual_type (QualType::getFromOpaquePtr(clang_type)); - - if (qual_type->isFunctionPointerType()) - return true; - - const clang::Type::TypeClass type_class = qual_type->getTypeClass(); - switch (type_class) - { - default: - break; - case clang::Type::Typedef: - return ClangASTContext::IsFunctionPointerType (cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr()); - case clang::Type::Elaborated: - return ClangASTContext::IsFunctionPointerType (cast<ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr()); - case clang::Type::Paren: - return ClangASTContext::IsFunctionPointerType (cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr()); - - case clang::Type::LValueReference: - case clang::Type::RValueReference: - { - const ReferenceType *reference_type = cast<ReferenceType>(qual_type.getTypePtr()); - if (reference_type) - return ClangASTContext::IsFunctionPointerType (reference_type->getPointeeType().getAsOpaquePtr()); - } - break; - } - } - return false; -} - -size_t -ClangASTContext::GetArraySize (clang_type_t clang_type) -{ - if (clang_type) - { - QualType qual_type(QualType::getFromOpaquePtr(clang_type)); - const clang::Type::TypeClass type_class = qual_type->getTypeClass(); - switch (type_class) - { - case clang::Type::ConstantArray: - { - const ConstantArrayType *array = cast<ConstantArrayType>(QualType::getFromOpaquePtr(clang_type).getTypePtr()); - if (array) - return array->getSize().getLimitedValue(); - } - break; - - case clang::Type::Typedef: - return ClangASTContext::GetArraySize(cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr()); - - case clang::Type::Elaborated: - return ClangASTContext::GetArraySize(cast<ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr()); - - case clang::Type::Paren: - return ClangASTContext::GetArraySize(cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr()); - - default: - break; - } - } - return 0; -} - -clang_type_t -ClangASTContext::GetAsArrayType (clang_type_t clang_type, clang_type_t*member_type, uint64_t *size, bool *is_incomplete) -{ - if (is_incomplete) - *is_incomplete = false; - if (!clang_type) - return 0; - - QualType qual_type (QualType::getFromOpaquePtr(clang_type)); - - const clang::Type::TypeClass type_class = qual_type->getTypeClass(); - switch (type_class) - { - default: - break; - - case clang::Type::ConstantArray: - if (member_type) - *member_type = cast<ConstantArrayType>(qual_type)->getElementType().getAsOpaquePtr(); - if (size) - *size = cast<ConstantArrayType>(qual_type)->getSize().getLimitedValue(ULLONG_MAX); - return clang_type; - - case clang::Type::IncompleteArray: - if (member_type) - *member_type = cast<IncompleteArrayType>(qual_type)->getElementType().getAsOpaquePtr(); - if (size) - *size = 0; - if (is_incomplete) - *is_incomplete = true; - return clang_type; - - case clang::Type::VariableArray: - if (member_type) - *member_type = cast<VariableArrayType>(qual_type)->getElementType().getAsOpaquePtr(); - if (size) - *size = 0; - return clang_type; - - case clang::Type::DependentSizedArray: - if (member_type) - *member_type = cast<DependentSizedArrayType>(qual_type)->getElementType().getAsOpaquePtr(); - if (size) - *size = 0; - return clang_type; - - case clang::Type::Typedef: - return ClangASTContext::GetAsArrayType (cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr(), - member_type, - size, - is_incomplete); - - case clang::Type::Elaborated: - return ClangASTContext::GetAsArrayType (cast<ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr(), - member_type, - size, - is_incomplete); - case clang::Type::Paren: - return ClangASTContext::GetAsArrayType (cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr(), - member_type, - size, - is_incomplete); - } - return 0; -} - - -#pragma mark Typedefs - -clang_type_t -ClangASTContext::CreateTypedefType (const char *name, clang_type_t clang_type, DeclContext *decl_ctx) -{ - if (clang_type) - { - QualType qual_type (QualType::getFromOpaquePtr(clang_type)); - ASTContext *ast = getASTContext(); - IdentifierTable *identifier_table = getIdentifierTable(); - assert (ast != NULL); - assert (identifier_table != NULL); - if (decl_ctx == NULL) - decl_ctx = ast->getTranslationUnitDecl(); - TypedefDecl *decl = TypedefDecl::Create (*ast, - decl_ctx, - SourceLocation(), - SourceLocation(), - name ? &identifier_table->get(name) : NULL, // Identifier - ast->getTrivialTypeSourceInfo(qual_type)); - - //decl_ctx->addDecl (decl); - - decl->setAccess(AS_public); // TODO respect proper access specifier - - // Get a uniqued QualType for the typedef decl type - return ast->getTypedefType (decl).getAsOpaquePtr(); + return ClangASTType (ast, ast->getTagDeclType(enum_decl).getAsOpaquePtr()); } - return NULL; + return ClangASTType(); } // Disable this for now since I can't seem to get a nicely formatted float @@ -6726,103 +2124,23 @@ ClangASTContext::CreateTypedefType (const char *name, clang_type_t clang_type, D // return false; //} -size_t -ClangASTContext::ConvertStringToFloatValue (ASTContext *ast, clang_type_t clang_type, const char *s, uint8_t *dst, size_t dst_size) -{ - if (clang_type) - { - QualType qual_type (QualType::getFromOpaquePtr(clang_type)); - uint32_t count = 0; - bool is_complex = false; - if (ClangASTContext::IsFloatingPointType (clang_type, count, is_complex)) - { - // TODO: handle complex and vector types - if (count != 1) - return false; - StringRef s_sref(s); - APFloat ap_float(ast->getFloatTypeSemantics(qual_type), s_sref); - - const uint64_t bit_size = ast->getTypeSize (qual_type); - const uint64_t byte_size = bit_size / 8; - if (dst_size >= byte_size) - { - if (bit_size == sizeof(float)*8) - { - float float32 = ap_float.convertToFloat(); - ::memcpy (dst, &float32, byte_size); - return byte_size; - } - else if (bit_size >= 64) - { - llvm::APInt ap_int(ap_float.bitcastToAPInt()); - ::memcpy (dst, ap_int.getRawData(), byte_size); - return byte_size; - } - } - } - } - return 0; -} - -lldb::clang_type_t +ClangASTType ClangASTContext::GetFloatTypeFromBitSize (clang::ASTContext *ast, size_t bit_size) { if (ast) { if (bit_size == ast->getTypeSize(ast->FloatTy)) - return ast->FloatTy.getAsOpaquePtr(); + return ClangASTType(ast, ast->FloatTy.getAsOpaquePtr()); else if (bit_size == ast->getTypeSize(ast->DoubleTy)) - return ast->DoubleTy.getAsOpaquePtr(); + return ClangASTType(ast, ast->DoubleTy.getAsOpaquePtr()); else if (bit_size == ast->getTypeSize(ast->LongDoubleTy)) - return ast->LongDoubleTy.getAsOpaquePtr(); + return ClangASTType(ast, ast->LongDoubleTy.getAsOpaquePtr()); else if (bit_size == ast->getTypeSize(ast->HalfTy)) - return ast->HalfTy.getAsOpaquePtr(); + return ClangASTType(ast, ast->HalfTy.getAsOpaquePtr()); } - return NULL; -} - -unsigned -ClangASTContext::GetTypeQualifiers(clang_type_t clang_type) -{ - assert (clang_type); - - QualType qual_type (QualType::getFromOpaquePtr(clang_type)); - - return qual_type.getQualifiers().getCVRQualifiers(); -} - -bool -ClangASTContext::GetCompleteType (clang::ASTContext *ast, lldb::clang_type_t clang_type) -{ - if (clang_type == NULL) - return false; - - return GetCompleteQualType (ast, clang::QualType::getFromOpaquePtr(clang_type)); -} - - -bool -ClangASTContext::GetCompleteType (clang_type_t clang_type) -{ - return ClangASTContext::GetCompleteType (getASTContext(), clang_type); -} - -bool -ClangASTContext::IsCompleteType (clang::ASTContext *ast, lldb::clang_type_t clang_type) -{ - if (clang_type == NULL) - return false; - - return GetCompleteQualType (ast, clang::QualType::getFromOpaquePtr(clang_type), false); // just check but don't let it actually complete -} - - -bool -ClangASTContext::IsCompleteType (clang_type_t clang_type) -{ - return ClangASTContext::IsCompleteType (getASTContext(), clang_type); + return ClangASTType(); } bool |