Index: include/lldb/Symbol/ClangASTContext.h =================================================================== --- include/lldb/Symbol/ClangASTContext.h +++ include/lldb/Symbol/ClangASTContext.h @@ -150,25 +150,6 @@ void RemoveExternalSource (); - - bool - GetCompleteDecl (clang::Decl *decl) - { - return ClangASTContext::GetCompleteDecl(getASTContext(), decl); - } - - static void - DumpDeclHiearchy (clang::Decl *decl); - - static void - DumpDeclContextHiearchy (clang::DeclContext *decl_ctx); - - static bool - DeclsAreEquivalent (clang::Decl *lhs_decl, clang::Decl *rhs_decl); - - static bool - GetCompleteDecl (clang::ASTContext *ast, - clang::Decl *decl); void SetMetadataAsUserID (const void *object, lldb::user_id_t user_id); @@ -201,23 +182,9 @@ GetBuiltinTypeForEncodingAndBitSize (lldb::Encoding encoding, size_t bit_size) override; - static CompilerType - GetBuiltinTypeForEncodingAndBitSize (clang::ASTContext *ast, - lldb::Encoding encoding, - uint32_t bit_size); - CompilerType GetBasicType (lldb::BasicType type); - static CompilerType - GetBasicType (clang::ASTContext *ast, lldb::BasicType type); - - static CompilerType - GetBasicType (clang::ASTContext *ast, const ConstString &name); - - static lldb::BasicType - GetBasicTypeEnumeration (const ConstString &name); - CompilerType GetBuiltinTypeForDWARFEncodingAndBitSize ( const char *type_name, Index: include/lldb/Symbol/ClangUtil.h =================================================================== --- include/lldb/Symbol/ClangUtil.h +++ include/lldb/Symbol/ClangUtil.h @@ -12,6 +12,7 @@ #ifndef LLDB_SYMBOL_CLANGUTIL_H #define LLDB_SYMBOL_CLANGUTIL_H +#include "clang/AST/ASTContext.h" #include "clang/AST/Type.h" #include "lldb/Symbol/CompilerType.h" @@ -21,14 +22,44 @@ struct ClangUtil { static bool - IsClangType(const CompilerType &ct); + DeclsAreEquivalent(clang::Decl *lhs_decl, clang::Decl *rhs_decl); - static clang::QualType - GetQualType(const CompilerType &ct); + static void + DumpDeclContextHiearchy(clang::DeclContext *decl_ctx); + + static void + DumpDeclHiearchy(clang::Decl *decl); + + static CompilerType + GetBasicType(clang::ASTContext *ast, lldb::BasicType type); + + static CompilerType + GetBasicType(clang::ASTContext *ast, const ConstString &name); + + static lldb::BasicType + GetBasicTypeEnumeration(const ConstString &name); + + static CompilerType + GetBuiltinTypeForEncodingAndBitSize(clang::ASTContext *ast, lldb::Encoding encoding, uint32_t bit_size); static clang::QualType GetCanonicalQualType(const CompilerType &ct); + static bool + GetCompleteDecl(clang::ASTContext *ast, clang::Decl *decl); + + static lldb::opaque_compiler_type_t + GetOpaqueCompilerType(clang::ASTContext *ast, lldb::BasicType type); + + static clang::QualType + GetQualType(const CompilerType &ct); + + static bool + IsClangType(const CompilerType &ct); + + static bool + QualTypeMatchesBitSize(const uint64_t bit_size, clang::ASTContext *ast, clang::QualType qual_type); + static CompilerType RemoveFastQualifiers(const CompilerType &ct); }; Index: source/API/SBTarget.cpp =================================================================== --- source/API/SBTarget.cpp +++ source/API/SBTarget.cpp @@ -19,8 +19,8 @@ #include "lldb/API/SBListener.h" #include "lldb/API/SBModule.h" #include "lldb/API/SBModuleSpec.h" -#include "lldb/API/SBSourceManager.h" #include "lldb/API/SBProcess.h" +#include "lldb/API/SBSourceManager.h" #include "lldb/API/SBStream.h" #include "lldb/API/SBSymbolContextList.h" #include "lldb/Breakpoint/BreakpointID.h" @@ -37,9 +37,9 @@ #include "lldb/Core/Module.h" #include "lldb/Core/ModuleSpec.h" #include "lldb/Core/RegularExpression.h" +#include "lldb/Core/STLUtils.h" #include "lldb/Core/SearchFilter.h" #include "lldb/Core/Section.h" -#include "lldb/Core/STLUtils.h" #include "lldb/Core/ValueObjectConstResult.h" #include "lldb/Core/ValueObjectList.h" #include "lldb/Core/ValueObjectVariable.h" @@ -47,6 +47,7 @@ #include "lldb/Host/Host.h" #include "lldb/Interpreter/Args.h" #include "lldb/Symbol/ClangASTContext.h" +#include "lldb/Symbol/ClangUtil.h" #include "lldb/Symbol/DeclVendor.h" #include "lldb/Symbol/ObjectFile.h" #include "lldb/Symbol/SymbolFile.h" @@ -1894,7 +1895,7 @@ // No matches, search for basic typename matches ClangASTContext *clang_ast = target_sp->GetScratchClangASTContext(); if (clang_ast) - return SBType (ClangASTContext::GetBasicType (clang_ast->getASTContext(), const_typename)); + return SBType(ClangUtil::GetBasicType(clang_ast->getASTContext(), const_typename)); } return SBType(); } @@ -1907,7 +1908,7 @@ { ClangASTContext *clang_ast = target_sp->GetScratchClangASTContext(); if (clang_ast) - return SBType (ClangASTContext::GetBasicType (clang_ast->getASTContext(), type)); + return SBType(ClangUtil::GetBasicType(clang_ast->getASTContext(), type)); } return SBType(); } @@ -1978,7 +1979,7 @@ // No matches, search for basic typename matches ClangASTContext *clang_ast = target_sp->GetScratchClangASTContext(); if (clang_ast) - sb_type_list.Append (SBType (ClangASTContext::GetBasicType (clang_ast->getASTContext(), const_typename))); + sb_type_list.Append(SBType(ClangUtil::GetBasicType(clang_ast->getASTContext(), const_typename))); } } return sb_type_list; Index: source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp =================================================================== --- source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp +++ source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp @@ -327,7 +327,7 @@ // We have found a type by basename and we need to make sure the decl contexts // are the same before we can try to complete this type with another - if (!ClangASTContext::DeclsAreEquivalent (tag_decl, candidate_tag_decl)) + if (!ClangUtil::DeclsAreEquivalent(tag_decl, candidate_tag_decl)) continue; if (m_ast_importer_sp->CompleteTagDeclWithOrigin (tag_decl, candidate_tag_decl)) @@ -1002,9 +1002,9 @@ DeclarationName original_decl_name(original_selector); llvm::SmallVector methods; - - ClangASTContext::GetCompleteDecl(original_ctx, original_interface_decl); - + + ClangUtil::GetCompleteDecl(original_ctx, original_interface_decl); + if (ObjCMethodDecl *instance_method_decl = original_interface_decl->lookupInstanceMethod(original_selector)) { methods.push_back(instance_method_decl); @@ -1681,7 +1681,7 @@ BaseOffsetMap origin_base_offsets; BaseOffsetMap origin_virtual_base_offsets; - ClangASTContext::GetCompleteDecl(&origin_record->getASTContext(), const_cast(origin_record.decl)); + ClangUtil::GetCompleteDecl(&origin_record->getASTContext(), const_cast(origin_record.decl)); clang::RecordDecl* definition = origin_record.decl->getDefinition(); if (!definition || !definition->isCompleteDefinition()) Index: source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp =================================================================== --- source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp +++ source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp @@ -14,11 +14,6 @@ #include "ClangModulesDeclVendor.h" #include "ClangPersistentVariables.h" -#include "clang/AST/ASTConsumer.h" -#include "clang/AST/ASTContext.h" -#include "clang/AST/DeclarationName.h" -#include "clang/AST/Decl.h" -#include "lldb/lldb-private.h" #include "lldb/Core/Address.h" #include "lldb/Core/Error.h" #include "lldb/Core/Log.h" @@ -30,9 +25,10 @@ #include "lldb/Expression/Materializer.h" #include "lldb/Host/Endian.h" #include "lldb/Symbol/ClangASTContext.h" +#include "lldb/Symbol/ClangUtil.h" +#include "lldb/Symbol/CompileUnit.h" #include "lldb/Symbol/CompilerDecl.h" #include "lldb/Symbol/CompilerDeclContext.h" -#include "lldb/Symbol/CompileUnit.h" #include "lldb/Symbol/Function.h" #include "lldb/Symbol/ObjectFile.h" #include "lldb/Symbol/SymbolContext.h" @@ -50,6 +46,11 @@ #include "lldb/Target/StackFrame.h" #include "lldb/Target/Target.h" #include "lldb/Target/Thread.h" +#include "lldb/lldb-private.h" +#include "clang/AST/ASTConsumer.h" +#include "clang/AST/ASTContext.h" +#include "clang/AST/Decl.h" +#include "clang/AST/DeclarationName.h" #include "Plugins/Language/CPlusPlus/CPlusPlusLanguage.h" @@ -1880,8 +1881,10 @@ ASTContext *scratch_ast_context = target->GetScratchClangASTContext()->getASTContext(); - TypeFromUser user_type (ClangASTContext::GetBasicType(scratch_ast_context, eBasicTypeVoid).GetPointerType().GetLValueReferenceType()); - TypeFromParser parser_type (ClangASTContext::GetBasicType(m_ast_context, eBasicTypeVoid).GetPointerType().GetLValueReferenceType()); + TypeFromUser user_type( + ClangUtil::GetBasicType(scratch_ast_context, eBasicTypeVoid).GetPointerType().GetLValueReferenceType()); + TypeFromParser parser_type( + ClangUtil::GetBasicType(m_ast_context, eBasicTypeVoid).GetPointerType().GetLValueReferenceType()); NamedDecl *var_decl = context.AddVarDecl(parser_type); std::string decl_name(context.m_decl_name.getAsString()); @@ -1986,9 +1989,8 @@ { Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS)); - CompilerType clang_type = ClangASTContext::GetBuiltinTypeForEncodingAndBitSize (m_ast_context, - reg_info->encoding, - reg_info->byte_size * 8); + CompilerType clang_type = + ClangUtil::GetBuiltinTypeForEncodingAndBitSize(m_ast_context, reg_info->encoding, reg_info->byte_size * 8); if (!clang_type) { @@ -2224,7 +2226,7 @@ if (copied_clang_type.IsAggregateType() && copied_clang_type.GetCompleteType ()) { - CompilerType void_clang_type = ClangASTContext::GetBasicType(m_ast_context, eBasicTypeVoid); + CompilerType void_clang_type = ClangUtil::GetBasicType(m_ast_context, eBasicTypeVoid); CompilerType void_ptr_clang_type = void_clang_type.GetPointerType(); CompilerType method_type = ClangASTContext::CreateFunctionType (m_ast_context, Index: source/Symbol/ClangASTContext.cpp =================================================================== --- source/Symbol/ClangASTContext.cpp +++ source/Symbol/ClangASTContext.cpp @@ -74,7 +74,6 @@ #include "lldb/Core/RegularExpression.h" #include "lldb/Core/StreamFile.h" #include "lldb/Core/ThreadSafeDenseMap.h" -#include "lldb/Core/UniqueCStringMap.h" #include "lldb/Symbol/ClangASTContext.h" #include "lldb/Symbol/ClangASTImporter.h" #include "lldb/Symbol/ClangExternalASTSourceCallbacks.h" @@ -740,158 +739,10 @@ #pragma mark Basic Types -static inline bool -QualTypeMatchesBitSize(const uint64_t bit_size, ASTContext *ast, QualType qual_type) -{ - uint64_t qual_type_bit_size = ast->getTypeSize(qual_type); - if (qual_type_bit_size == bit_size) - return true; - return false; -} - CompilerType ClangASTContext::GetBuiltinTypeForEncodingAndBitSize (Encoding encoding, size_t bit_size) { - return ClangASTContext::GetBuiltinTypeForEncodingAndBitSize (getASTContext(), encoding, bit_size); -} - -CompilerType -ClangASTContext::GetBuiltinTypeForEncodingAndBitSize (ASTContext *ast, Encoding encoding, uint32_t bit_size) -{ - if (!ast) - return CompilerType(); - switch (encoding) - { - case eEncodingInvalid: - if (QualTypeMatchesBitSize (bit_size, ast, ast->VoidPtrTy)) - return CompilerType (ast, ast->VoidPtrTy); - break; - - case eEncodingUint: - if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedCharTy)) - return CompilerType (ast, ast->UnsignedCharTy); - if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedShortTy)) - return CompilerType (ast, ast->UnsignedShortTy); - if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedIntTy)) - return CompilerType (ast, ast->UnsignedIntTy); - if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedLongTy)) - return CompilerType (ast, ast->UnsignedLongTy); - if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedLongLongTy)) - return CompilerType (ast, ast->UnsignedLongLongTy); - if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedInt128Ty)) - return CompilerType (ast, ast->UnsignedInt128Ty); - break; - - case eEncodingSint: - if (QualTypeMatchesBitSize (bit_size, ast, ast->CharTy)) - return CompilerType (ast, ast->CharTy); - if (QualTypeMatchesBitSize (bit_size, ast, ast->ShortTy)) - return CompilerType (ast, ast->ShortTy); - if (QualTypeMatchesBitSize (bit_size, ast, ast->IntTy)) - return CompilerType (ast, ast->IntTy); - if (QualTypeMatchesBitSize (bit_size, ast, ast->LongTy)) - return CompilerType (ast, ast->LongTy); - if (QualTypeMatchesBitSize (bit_size, ast, ast->LongLongTy)) - return CompilerType (ast, ast->LongLongTy); - if (QualTypeMatchesBitSize (bit_size, ast, ast->Int128Ty)) - return CompilerType (ast, ast->Int128Ty); - break; - - case eEncodingIEEE754: - if (QualTypeMatchesBitSize (bit_size, ast, ast->FloatTy)) - return CompilerType (ast, ast->FloatTy); - if (QualTypeMatchesBitSize (bit_size, ast, ast->DoubleTy)) - return CompilerType (ast, ast->DoubleTy); - if (QualTypeMatchesBitSize (bit_size, ast, ast->LongDoubleTy)) - return CompilerType (ast, ast->LongDoubleTy); - if (QualTypeMatchesBitSize (bit_size, ast, ast->HalfTy)) - return CompilerType (ast, ast->HalfTy); - break; - - case eEncodingVector: - // Sanity check that bit_size is a multiple of 8's. - if (bit_size && !(bit_size & 0x7u)) - return CompilerType (ast, ast->getExtVectorType (ast->UnsignedCharTy, bit_size/8)); - break; - } - - return CompilerType(); -} - - - -lldb::BasicType -ClangASTContext::GetBasicTypeEnumeration (const ConstString &name) -{ - if (name) - { - typedef UniqueCStringMap 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); - - // Miscellaneous - 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; -} - -CompilerType -ClangASTContext::GetBasicType (ASTContext *ast, const ConstString &name) -{ - if (ast) - { - lldb::BasicType basic_type = ClangASTContext::GetBasicTypeEnumeration (name); - return ClangASTContext::GetBasicType (ast, basic_type); - } - return CompilerType(); + return ClangUtil::GetBuiltinTypeForEncodingAndBitSize(getASTContext(), encoding, bit_size); } uint32_t @@ -905,124 +756,10 @@ CompilerType ClangASTContext::GetBasicType (lldb::BasicType basic_type) { - return GetBasicType (getASTContext(), basic_type); + return ClangUtil::GetBasicType(getASTContext(), basic_type); } CompilerType -ClangASTContext::GetBasicType (ASTContext *ast, lldb::BasicType basic_type) -{ - if (ast) - { - lldb::opaque_compiler_type_t clang_type = nullptr; - - 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 CompilerType (GetASTContext(ast), clang_type); - } - return CompilerType(); -} - - -CompilerType ClangASTContext::GetBuiltinTypeForDWARFEncodingAndBitSize (const char *type_name, uint32_t dw_ate, uint32_t bit_size) { ASTContext *ast = getASTContext(); @@ -1037,18 +774,18 @@ break; case DW_ATE_address: - if (QualTypeMatchesBitSize (bit_size, ast, ast->VoidPtrTy)) + if (ClangUtil::QualTypeMatchesBitSize(bit_size, ast, ast->VoidPtrTy)) return CompilerType (ast, ast->VoidPtrTy); break; case DW_ATE_boolean: - if (QualTypeMatchesBitSize (bit_size, ast, ast->BoolTy)) + if (ClangUtil::QualTypeMatchesBitSize(bit_size, ast, ast->BoolTy)) return CompilerType (ast, ast->BoolTy); - if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedCharTy)) + if (ClangUtil::QualTypeMatchesBitSize(bit_size, ast, ast->UnsignedCharTy)) return CompilerType (ast, ast->UnsignedCharTy); - if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedShortTy)) + if (ClangUtil::QualTypeMatchesBitSize(bit_size, ast, ast->UnsignedShortTy)) return CompilerType (ast, ast->UnsignedShortTy); - if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedIntTy)) + if (ClangUtil::QualTypeMatchesBitSize(bit_size, ast, ast->UnsignedIntTy)) return CompilerType (ast, ast->UnsignedIntTy); break; @@ -1065,11 +802,11 @@ break; case DW_ATE_complex_float: - if (QualTypeMatchesBitSize (bit_size, ast, ast->FloatComplexTy)) + if (ClangUtil::QualTypeMatchesBitSize(bit_size, ast, ast->FloatComplexTy)) return CompilerType (ast, ast->FloatComplexTy); - else if (QualTypeMatchesBitSize (bit_size, ast, ast->DoubleComplexTy)) + else if (ClangUtil::QualTypeMatchesBitSize(bit_size, ast, ast->DoubleComplexTy)) return CompilerType (ast, ast->DoubleComplexTy); - else if (QualTypeMatchesBitSize (bit_size, ast, ast->LongDoubleComplexTy)) + else if (ClangUtil::QualTypeMatchesBitSize(bit_size, ast, ast->LongDoubleComplexTy)) return CompilerType (ast, ast->LongDoubleComplexTy); else { @@ -1079,79 +816,76 @@ break; case DW_ATE_float: - if (streq(type_name, "float") && QualTypeMatchesBitSize (bit_size, ast, ast->FloatTy)) + if (streq(type_name, "float") && ClangUtil::QualTypeMatchesBitSize(bit_size, ast, ast->FloatTy)) return CompilerType (ast, ast->FloatTy); - if (streq(type_name, "double") && QualTypeMatchesBitSize (bit_size, ast, ast->DoubleTy)) + if (streq(type_name, "double") && ClangUtil::QualTypeMatchesBitSize(bit_size, ast, ast->DoubleTy)) return CompilerType (ast, ast->DoubleTy); - if (streq(type_name, "long double") && QualTypeMatchesBitSize (bit_size, ast, ast->LongDoubleTy)) + if (streq(type_name, "long double") && + ClangUtil::QualTypeMatchesBitSize(bit_size, ast, ast->LongDoubleTy)) return CompilerType (ast, ast->LongDoubleTy); // Fall back to not requiring a name match - if (QualTypeMatchesBitSize (bit_size, ast, ast->FloatTy)) + if (ClangUtil::QualTypeMatchesBitSize(bit_size, ast, ast->FloatTy)) return CompilerType (ast, ast->FloatTy); - if (QualTypeMatchesBitSize (bit_size, ast, ast->DoubleTy)) + if (ClangUtil::QualTypeMatchesBitSize(bit_size, ast, ast->DoubleTy)) return CompilerType (ast, ast->DoubleTy); - if (QualTypeMatchesBitSize (bit_size, ast, ast->LongDoubleTy)) + if (ClangUtil::QualTypeMatchesBitSize(bit_size, ast, ast->LongDoubleTy)) return CompilerType (ast, ast->LongDoubleTy); - if (QualTypeMatchesBitSize (bit_size, ast, ast->HalfTy)) + if (ClangUtil::QualTypeMatchesBitSize(bit_size, ast, ast->HalfTy)) return CompilerType (ast, ast->HalfTy); break; case DW_ATE_signed: if (type_name) { - if (streq(type_name, "wchar_t") && - QualTypeMatchesBitSize (bit_size, ast, ast->WCharTy) && - (getTargetInfo() && TargetInfo::isTypeSigned (getTargetInfo()->getWCharType()))) + if (streq(type_name, "wchar_t") && ClangUtil::QualTypeMatchesBitSize(bit_size, ast, ast->WCharTy) && + (getTargetInfo() && TargetInfo::isTypeSigned(getTargetInfo()->getWCharType()))) return CompilerType (ast, ast->WCharTy); - if (streq(type_name, "void") && - QualTypeMatchesBitSize (bit_size, ast, ast->VoidTy)) + if (streq(type_name, "void") && ClangUtil::QualTypeMatchesBitSize(bit_size, ast, ast->VoidTy)) return CompilerType (ast, ast->VoidTy); if (strstr(type_name, "long long") && - QualTypeMatchesBitSize (bit_size, ast, ast->LongLongTy)) + ClangUtil::QualTypeMatchesBitSize(bit_size, ast, ast->LongLongTy)) return CompilerType (ast, ast->LongLongTy); - if (strstr(type_name, "long") && - QualTypeMatchesBitSize (bit_size, ast, ast->LongTy)) + if (strstr(type_name, "long") && ClangUtil::QualTypeMatchesBitSize(bit_size, ast, ast->LongTy)) return CompilerType (ast, ast->LongTy); - if (strstr(type_name, "short") && - QualTypeMatchesBitSize (bit_size, ast, ast->ShortTy)) + if (strstr(type_name, "short") && ClangUtil::QualTypeMatchesBitSize(bit_size, ast, ast->ShortTy)) return CompilerType (ast, ast->ShortTy); if (strstr(type_name, "char")) { - if (QualTypeMatchesBitSize (bit_size, ast, ast->CharTy)) + if (ClangUtil::QualTypeMatchesBitSize(bit_size, ast, ast->CharTy)) return CompilerType (ast, ast->CharTy); - if (QualTypeMatchesBitSize (bit_size, ast, ast->SignedCharTy)) + if (ClangUtil::QualTypeMatchesBitSize(bit_size, ast, ast->SignedCharTy)) return CompilerType (ast, ast->SignedCharTy); } if (strstr(type_name, "int")) { - if (QualTypeMatchesBitSize (bit_size, ast, ast->IntTy)) + if (ClangUtil::QualTypeMatchesBitSize(bit_size, ast, ast->IntTy)) return CompilerType (ast, ast->IntTy); - if (QualTypeMatchesBitSize (bit_size, ast, ast->Int128Ty)) + if (ClangUtil::QualTypeMatchesBitSize(bit_size, ast, ast->Int128Ty)) return CompilerType (ast, ast->Int128Ty); } } // We weren't able to match up a type name, just search by size - if (QualTypeMatchesBitSize (bit_size, ast, ast->CharTy)) + if (ClangUtil::QualTypeMatchesBitSize(bit_size, ast, ast->CharTy)) return CompilerType (ast, ast->CharTy); - if (QualTypeMatchesBitSize (bit_size, ast, ast->ShortTy)) + if (ClangUtil::QualTypeMatchesBitSize(bit_size, ast, ast->ShortTy)) return CompilerType (ast, ast->ShortTy); - if (QualTypeMatchesBitSize (bit_size, ast, ast->IntTy)) + if (ClangUtil::QualTypeMatchesBitSize(bit_size, ast, ast->IntTy)) return CompilerType (ast, ast->IntTy); - if (QualTypeMatchesBitSize (bit_size, ast, ast->LongTy)) + if (ClangUtil::QualTypeMatchesBitSize(bit_size, ast, ast->LongTy)) return CompilerType (ast, ast->LongTy); - if (QualTypeMatchesBitSize (bit_size, ast, ast->LongLongTy)) + if (ClangUtil::QualTypeMatchesBitSize(bit_size, ast, ast->LongLongTy)) return CompilerType (ast, ast->LongLongTy); - if (QualTypeMatchesBitSize (bit_size, ast, ast->Int128Ty)) + if (ClangUtil::QualTypeMatchesBitSize(bit_size, ast, ast->Int128Ty)) return CompilerType (ast, ast->Int128Ty); break; case DW_ATE_signed_char: if (ast->getLangOpts().CharIsSigned && type_name && streq(type_name, "char")) { - if (QualTypeMatchesBitSize (bit_size, ast, ast->CharTy)) + if (ClangUtil::QualTypeMatchesBitSize(bit_size, ast, ast->CharTy)) return CompilerType (ast, ast->CharTy); } - if (QualTypeMatchesBitSize (bit_size, ast, ast->SignedCharTy)) + if (ClangUtil::QualTypeMatchesBitSize(bit_size, ast, ast->SignedCharTy)) return CompilerType (ast, ast->SignedCharTy); break; @@ -1160,7 +894,7 @@ { if (streq(type_name, "wchar_t")) { - if (QualTypeMatchesBitSize (bit_size, ast, ast->WCharTy)) + if (ClangUtil::QualTypeMatchesBitSize(bit_size, ast, ast->WCharTy)) { if (!(getTargetInfo() && TargetInfo::isTypeSigned (getTargetInfo()->getWCharType()))) return CompilerType (ast, ast->WCharTy); @@ -1168,56 +902,56 @@ } if (strstr(type_name, "long long")) { - if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedLongLongTy)) + if (ClangUtil::QualTypeMatchesBitSize(bit_size, ast, ast->UnsignedLongLongTy)) return CompilerType (ast, ast->UnsignedLongLongTy); } else if (strstr(type_name, "long")) { - if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedLongTy)) + if (ClangUtil::QualTypeMatchesBitSize(bit_size, ast, ast->UnsignedLongTy)) return CompilerType (ast, ast->UnsignedLongTy); } else if (strstr(type_name, "short")) { - if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedShortTy)) + if (ClangUtil::QualTypeMatchesBitSize(bit_size, ast, ast->UnsignedShortTy)) return CompilerType (ast, ast->UnsignedShortTy); } else if (strstr(type_name, "char")) { - if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedCharTy)) + if (ClangUtil::QualTypeMatchesBitSize(bit_size, ast, ast->UnsignedCharTy)) return CompilerType (ast, ast->UnsignedCharTy); } else if (strstr(type_name, "int")) { - if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedIntTy)) + if (ClangUtil::QualTypeMatchesBitSize(bit_size, ast, ast->UnsignedIntTy)) return CompilerType (ast, ast->UnsignedIntTy); - if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedInt128Ty)) + if (ClangUtil::QualTypeMatchesBitSize(bit_size, ast, ast->UnsignedInt128Ty)) return CompilerType (ast, ast->UnsignedInt128Ty); } } // We weren't able to match up a type name, just search by size - if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedCharTy)) + if (ClangUtil::QualTypeMatchesBitSize(bit_size, ast, ast->UnsignedCharTy)) return CompilerType (ast, ast->UnsignedCharTy); - if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedShortTy)) + if (ClangUtil::QualTypeMatchesBitSize(bit_size, ast, ast->UnsignedShortTy)) return CompilerType (ast, ast->UnsignedShortTy); - if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedIntTy)) + if (ClangUtil::QualTypeMatchesBitSize(bit_size, ast, ast->UnsignedIntTy)) return CompilerType (ast, ast->UnsignedIntTy); - if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedLongTy)) + if (ClangUtil::QualTypeMatchesBitSize(bit_size, ast, ast->UnsignedLongTy)) return CompilerType (ast, ast->UnsignedLongTy); - if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedLongLongTy)) + if (ClangUtil::QualTypeMatchesBitSize(bit_size, ast, ast->UnsignedLongLongTy)) return CompilerType (ast, ast->UnsignedLongLongTy); - if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedInt128Ty)) + if (ClangUtil::QualTypeMatchesBitSize(bit_size, ast, ast->UnsignedInt128Ty)) return CompilerType (ast, ast->UnsignedInt128Ty); break; case DW_ATE_unsigned_char: if (!ast->getLangOpts().CharIsSigned && type_name && streq(type_name, "char")) { - if (QualTypeMatchesBitSize (bit_size, ast, ast->CharTy)) + if (ClangUtil::QualTypeMatchesBitSize(bit_size, ast, ast->CharTy)) return CompilerType (ast, ast->CharTy); } - if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedCharTy)) + if (ClangUtil::QualTypeMatchesBitSize(bit_size, ast, ast->UnsignedCharTy)) return CompilerType (ast, ast->UnsignedCharTy); - if (QualTypeMatchesBitSize (bit_size, ast, ast->UnsignedShortTy)) + if (ClangUtil::QualTypeMatchesBitSize(bit_size, ast, ast->UnsignedShortTy)) return CompilerType (ast, ast->UnsignedShortTy); break; @@ -2276,199 +2010,6 @@ } void -ClangASTContext::DumpDeclContextHiearchy (clang::DeclContext *decl_ctx) -{ - if (decl_ctx) - { - DumpDeclContextHiearchy (decl_ctx->getParent()); - - clang::NamedDecl *named_decl = llvm::dyn_cast(decl_ctx); - if (named_decl) - { - printf ("%20s: %s\n", decl_ctx->getDeclKindName(), named_decl->getDeclName().getAsString().c_str()); - } - else - { - printf ("%20s\n", decl_ctx->getDeclKindName()); - } - } -} - -void -ClangASTContext::DumpDeclHiearchy (clang::Decl *decl) -{ - if (decl == nullptr) - return; - DumpDeclContextHiearchy(decl->getDeclContext()); - - clang::RecordDecl *record_decl = llvm::dyn_cast(decl); - if (record_decl) - { - printf ("%20s: %s%s\n", decl->getDeclKindName(), record_decl->getDeclName().getAsString().c_str(), record_decl->isInjectedClassName() ? " (injected class name)" : ""); - - } - else - { - clang::NamedDecl *named_decl = llvm::dyn_cast(decl); - if (named_decl) - { - printf ("%20s: %s\n", decl->getDeclKindName(), named_decl->getDeclName().getAsString().c_str()); - } - else - { - printf ("%20s\n", decl->getDeclKindName()); - } - } -} - -bool -ClangASTContext::DeclsAreEquivalent (clang::Decl *lhs_decl, clang::Decl *rhs_decl) -{ - if (lhs_decl && rhs_decl) - { - //---------------------------------------------------------------------- - // Make sure the decl kinds match first - //---------------------------------------------------------------------- - const clang::Decl::Kind lhs_decl_kind = lhs_decl->getKind(); - const clang::Decl::Kind rhs_decl_kind = rhs_decl->getKind(); - - if (lhs_decl_kind == rhs_decl_kind) - { - //------------------------------------------------------------------ - // Now check that the decl contexts kinds are all equivalent - // before we have to check any names of the decl contexts... - //------------------------------------------------------------------ - clang::DeclContext *lhs_decl_ctx = lhs_decl->getDeclContext(); - clang::DeclContext *rhs_decl_ctx = rhs_decl->getDeclContext(); - if (lhs_decl_ctx && rhs_decl_ctx) - { - while (1) - { - if (lhs_decl_ctx && rhs_decl_ctx) - { - const clang::Decl::Kind lhs_decl_ctx_kind = lhs_decl_ctx->getDeclKind(); - const clang::Decl::Kind rhs_decl_ctx_kind = rhs_decl_ctx->getDeclKind(); - if (lhs_decl_ctx_kind == rhs_decl_ctx_kind) - { - lhs_decl_ctx = lhs_decl_ctx->getParent(); - rhs_decl_ctx = rhs_decl_ctx->getParent(); - - if (lhs_decl_ctx == nullptr && rhs_decl_ctx == nullptr) - break; - } - else - return false; - } - else - return false; - } - - //-------------------------------------------------------------- - // Now make sure the name of the decls match - //-------------------------------------------------------------- - clang::NamedDecl *lhs_named_decl = llvm::dyn_cast(lhs_decl); - clang::NamedDecl *rhs_named_decl = llvm::dyn_cast(rhs_decl); - if (lhs_named_decl && rhs_named_decl) - { - clang::DeclarationName lhs_decl_name = lhs_named_decl->getDeclName(); - clang::DeclarationName rhs_decl_name = rhs_named_decl->getDeclName(); - if (lhs_decl_name.getNameKind() == rhs_decl_name.getNameKind()) - { - if (lhs_decl_name.getAsString() != rhs_decl_name.getAsString()) - return false; - } - else - return false; - } - else - return false; - - //-------------------------------------------------------------- - // We know that the decl context kinds all match, so now we need - // to make sure the names match as well - //-------------------------------------------------------------- - lhs_decl_ctx = lhs_decl->getDeclContext(); - rhs_decl_ctx = rhs_decl->getDeclContext(); - while (1) - { - switch (lhs_decl_ctx->getDeclKind()) - { - case clang::Decl::TranslationUnit: - // We don't care about the translation unit names - return true; - default: - { - clang::NamedDecl *lhs_named_decl = llvm::dyn_cast(lhs_decl_ctx); - clang::NamedDecl *rhs_named_decl = llvm::dyn_cast(rhs_decl_ctx); - if (lhs_named_decl && rhs_named_decl) - { - clang::DeclarationName lhs_decl_name = lhs_named_decl->getDeclName(); - clang::DeclarationName rhs_decl_name = rhs_named_decl->getDeclName(); - if (lhs_decl_name.getNameKind() == rhs_decl_name.getNameKind()) - { - if (lhs_decl_name.getAsString() != rhs_decl_name.getAsString()) - return false; - } - else - return false; - } - else - return false; - } - break; - - } - lhs_decl_ctx = lhs_decl_ctx->getParent(); - rhs_decl_ctx = rhs_decl_ctx->getParent(); - } - } - } - } - return false; -} -bool -ClangASTContext::GetCompleteDecl (clang::ASTContext *ast, - clang::Decl *decl) -{ - if (!decl) - return false; - - ExternalASTSource *ast_source = ast->getExternalSource(); - - if (!ast_source) - return false; - - if (clang::TagDecl *tag_decl = llvm::dyn_cast(decl)) - { - if (tag_decl->isCompleteDefinition()) - return true; - - if (!tag_decl->hasExternalLexicalStorage()) - return false; - - ast_source->CompleteType(tag_decl); - - return !tag_decl->getTypeForDecl()->isIncompleteType(); - } - else if (clang::ObjCInterfaceDecl *objc_interface_decl = llvm::dyn_cast(decl)) - { - if (objc_interface_decl->getDefinition()) - return true; - - if (!objc_interface_decl->hasExternalLexicalStorage()) - return false; - - ast_source->CompleteType(objc_interface_decl); - - return !objc_interface_decl->getTypeForDecl()->isIncompleteType(); - } - else - { - return false; - } -} - -void ClangASTContext::SetMetadataAsUserID (const void *object, user_id_t user_id) { @@ -4662,7 +4203,7 @@ CompilerType ClangASTContext::GetBasicTypeFromAST (lldb::BasicType basic_type) { - return ClangASTContext::GetBasicType(getASTContext(), basic_type); + return ClangUtil::GetBasicType(getASTContext(), basic_type); } //---------------------------------------------------------------------- // Exploring the type @@ -5212,7 +4753,7 @@ CompilerType ClangASTContext::GetBuiltinTypeByName (const ConstString &name) { - return GetBasicType (GetBasicTypeEnumeration (name)); + return GetBasicType(ClangUtil::GetBasicTypeEnumeration(name)); } lldb::BasicType Index: source/Symbol/ClangASTImporter.cpp =================================================================== --- source/Symbol/ClangASTImporter.cpp +++ source/Symbol/ClangASTImporter.cpp @@ -599,8 +599,8 @@ if (!decl_origin.Valid()) return false; - - if (!ClangASTContext::GetCompleteDecl(decl_origin.ctx, decl_origin.decl)) + + if (!ClangUtil::GetCompleteDecl(decl_origin.ctx, decl_origin.decl)) return false; MinionSP minion_sp (GetMinion(&decl->getASTContext(), decl_origin.ctx)); @@ -617,8 +617,8 @@ ClangASTMetrics::RegisterDeclCompletion(); clang::ASTContext *origin_ast_ctx = &origin_decl->getASTContext(); - - if (!ClangASTContext::GetCompleteDecl(origin_ast_ctx, origin_decl)) + + if (!ClangUtil::GetCompleteDecl(origin_ast_ctx, origin_decl)) return false; MinionSP minion_sp (GetMinion(&decl->getASTContext(), origin_ast_ctx)); @@ -644,8 +644,8 @@ if (!decl_origin.Valid()) return false; - - if (!ClangASTContext::GetCompleteDecl(decl_origin.ctx, decl_origin.decl)) + + if (!ClangUtil::GetCompleteDecl(decl_origin.ctx, decl_origin.decl)) return false; MinionSP minion_sp (GetMinion(&interface_decl->getASTContext(), decl_origin.ctx)); @@ -929,9 +929,9 @@ // because it doesn't need to be deported Decl *original_decl = to_context_md->m_origins[decl].decl; - - ClangASTContext::GetCompleteDecl (m_source_ctx, original_decl); - + + ClangUtil::GetCompleteDecl(m_source_ctx, original_decl); + if (TagDecl *tag_decl = dyn_cast(decl)) { if (TagDecl *original_tag_decl = dyn_cast(original_decl)) Index: source/Symbol/ClangUtil.cpp =================================================================== --- source/Symbol/ClangUtil.cpp +++ source/Symbol/ClangUtil.cpp @@ -10,40 +10,449 @@ //===----------------------------------------------------------------------===// #include "lldb/Symbol/ClangUtil.h" + +#include "clang/AST/DeclObjC.h" + +#include "lldb/Core/ConstString.h" +#include "lldb/Core/UniqueCStringMap.h" #include "lldb/Symbol/ClangASTContext.h" +#include "llvm/Support/Dwarf.h" + +#include + using namespace clang; +using namespace lldb; using namespace lldb_private; bool -ClangUtil::IsClangType(const CompilerType &ct) +ClangUtil::DeclsAreEquivalent(clang::Decl *lhs_decl, clang::Decl *rhs_decl) { - if (llvm::dyn_cast_or_null(ct.GetTypeSystem()) == nullptr) + if (!lhs_decl || !rhs_decl) return false; - if (!ct.GetOpaqueQualType()) + //---------------------------------------------------------------------- + // Make sure the decl kinds match first + //---------------------------------------------------------------------- + const clang::Decl::Kind lhs_decl_kind = lhs_decl->getKind(); + const clang::Decl::Kind rhs_decl_kind = rhs_decl->getKind(); + + if (lhs_decl_kind != rhs_decl_kind) return false; - return true; + //------------------------------------------------------------------ + // Now check that the decl contexts kinds are all equivalent + // before we have to check any names of the decl contexts... + //------------------------------------------------------------------ + clang::DeclContext *lhs_decl_ctx = lhs_decl->getDeclContext(); + clang::DeclContext *rhs_decl_ctx = rhs_decl->getDeclContext(); + if (!lhs_decl_ctx || !rhs_decl_ctx) + return false; + + while (1) + { + if (!lhs_decl_ctx || !rhs_decl_ctx) + return false; + + const clang::Decl::Kind lhs_decl_ctx_kind = lhs_decl_ctx->getDeclKind(); + const clang::Decl::Kind rhs_decl_ctx_kind = rhs_decl_ctx->getDeclKind(); + if (lhs_decl_ctx_kind != rhs_decl_ctx_kind) + return false; + + lhs_decl_ctx = lhs_decl_ctx->getParent(); + rhs_decl_ctx = rhs_decl_ctx->getParent(); + + if (lhs_decl_ctx == nullptr && rhs_decl_ctx == nullptr) + break; + } + + //-------------------------------------------------------------- + // Now make sure the name of the decls match + //-------------------------------------------------------------- + clang::NamedDecl *lhs_named_decl = llvm::dyn_cast(lhs_decl); + clang::NamedDecl *rhs_named_decl = llvm::dyn_cast(rhs_decl); + if (!lhs_named_decl || !rhs_named_decl) + return false; + clang::DeclarationName lhs_decl_name = lhs_named_decl->getDeclName(); + clang::DeclarationName rhs_decl_name = rhs_named_decl->getDeclName(); + if (lhs_decl_name.getNameKind() != rhs_decl_name.getNameKind()) + return false; + if (lhs_decl_name.getAsString() != rhs_decl_name.getAsString()) + return false; + + //-------------------------------------------------------------- + // We know that the decl context kinds all match, so now we need + // to make sure the names match as well + //-------------------------------------------------------------- + lhs_decl_ctx = lhs_decl->getDeclContext(); + rhs_decl_ctx = rhs_decl->getDeclContext(); + while (1) + { + switch (lhs_decl_ctx->getDeclKind()) + { + case clang::Decl::TranslationUnit: + // We don't care about the translation unit names + return true; + default: + { + clang::NamedDecl *lhs_named_decl = llvm::dyn_cast(lhs_decl_ctx); + clang::NamedDecl *rhs_named_decl = llvm::dyn_cast(rhs_decl_ctx); + if (!lhs_named_decl || !rhs_named_decl) + return false; + clang::DeclarationName lhs_decl_name = lhs_named_decl->getDeclName(); + clang::DeclarationName rhs_decl_name = rhs_named_decl->getDeclName(); + if (lhs_decl_name.getNameKind() != rhs_decl_name.getNameKind()) + return false; + if (lhs_decl_name.getAsString() != rhs_decl_name.getAsString()) + return false; + } + break; + } + lhs_decl_ctx = lhs_decl_ctx->getParent(); + rhs_decl_ctx = rhs_decl_ctx->getParent(); + } + return false; +} + +void +ClangUtil::DumpDeclContextHiearchy(clang::DeclContext *decl_ctx) +{ + if (decl_ctx) + { + DumpDeclContextHiearchy(decl_ctx->getParent()); + + clang::NamedDecl *named_decl = llvm::dyn_cast(decl_ctx); + if (named_decl) + { + printf("%20s: %s\n", decl_ctx->getDeclKindName(), named_decl->getDeclName().getAsString().c_str()); + } + else + { + printf("%20s\n", decl_ctx->getDeclKindName()); + } + } +} + +void +ClangUtil::DumpDeclHiearchy(clang::Decl *decl) +{ + if (decl == nullptr) + return; + DumpDeclContextHiearchy(decl->getDeclContext()); + + clang::RecordDecl *record_decl = llvm::dyn_cast(decl); + if (record_decl) + { + printf("%20s: %s%s\n", decl->getDeclKindName(), record_decl->getDeclName().getAsString().c_str(), + record_decl->isInjectedClassName() ? " (injected class name)" : ""); + } + else + { + clang::NamedDecl *named_decl = llvm::dyn_cast(decl); + if (named_decl) + { + printf("%20s: %s\n", decl->getDeclKindName(), named_decl->getDeclName().getAsString().c_str()); + } + else + { + printf("%20s\n", decl->getDeclKindName()); + } + } +} + +CompilerType +ClangUtil::GetBasicType(clang::ASTContext *ast, BasicType type) +{ + lldb::opaque_compiler_type_t clang_type = GetOpaqueCompilerType(ast, type); + if (!clang_type) + return CompilerType(); + + return CompilerType(ast, clang::QualType::getFromOpaquePtr(clang_type)); +} + +CompilerType +ClangUtil::GetBasicType(clang::ASTContext *ast, const ConstString &name) +{ + if (!ast) + return CompilerType(); + + lldb::BasicType basic_type = GetBasicTypeEnumeration(name); + return GetBasicType(ast, basic_type); +} + +BasicType +ClangUtil::GetBasicTypeEnumeration(const ConstString &name) +{ + if (!name) + return eBasicTypeInvalid; + typedef UniqueCStringMap 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); + + // Miscellaneous + 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); +} + +CompilerType +ClangUtil::GetBuiltinTypeForEncodingAndBitSize(ASTContext *ast, Encoding encoding, uint32_t bit_size) +{ + if (!ast) + return CompilerType(); + switch (encoding) + { + case eEncodingInvalid: + if (QualTypeMatchesBitSize(bit_size, ast, ast->VoidPtrTy)) + return CompilerType(ast, ast->VoidPtrTy); + break; + + case eEncodingUint: + if (QualTypeMatchesBitSize(bit_size, ast, ast->UnsignedCharTy)) + return CompilerType(ast, ast->UnsignedCharTy); + if (QualTypeMatchesBitSize(bit_size, ast, ast->UnsignedShortTy)) + return CompilerType(ast, ast->UnsignedShortTy); + if (QualTypeMatchesBitSize(bit_size, ast, ast->UnsignedIntTy)) + return CompilerType(ast, ast->UnsignedIntTy); + if (QualTypeMatchesBitSize(bit_size, ast, ast->UnsignedLongTy)) + return CompilerType(ast, ast->UnsignedLongTy); + if (QualTypeMatchesBitSize(bit_size, ast, ast->UnsignedLongLongTy)) + return CompilerType(ast, ast->UnsignedLongLongTy); + if (QualTypeMatchesBitSize(bit_size, ast, ast->UnsignedInt128Ty)) + return CompilerType(ast, ast->UnsignedInt128Ty); + break; + + case eEncodingSint: + if (QualTypeMatchesBitSize(bit_size, ast, ast->CharTy)) + return CompilerType(ast, ast->CharTy); + if (QualTypeMatchesBitSize(bit_size, ast, ast->ShortTy)) + return CompilerType(ast, ast->ShortTy); + if (QualTypeMatchesBitSize(bit_size, ast, ast->IntTy)) + return CompilerType(ast, ast->IntTy); + if (QualTypeMatchesBitSize(bit_size, ast, ast->LongTy)) + return CompilerType(ast, ast->LongTy); + if (QualTypeMatchesBitSize(bit_size, ast, ast->LongLongTy)) + return CompilerType(ast, ast->LongLongTy); + if (QualTypeMatchesBitSize(bit_size, ast, ast->Int128Ty)) + return CompilerType(ast, ast->Int128Ty); + break; + + case eEncodingIEEE754: + if (QualTypeMatchesBitSize(bit_size, ast, ast->FloatTy)) + return CompilerType(ast, ast->FloatTy); + if (QualTypeMatchesBitSize(bit_size, ast, ast->DoubleTy)) + return CompilerType(ast, ast->DoubleTy); + if (QualTypeMatchesBitSize(bit_size, ast, ast->LongDoubleTy)) + return CompilerType(ast, ast->LongDoubleTy); + if (QualTypeMatchesBitSize(bit_size, ast, ast->HalfTy)) + return CompilerType(ast, ast->HalfTy); + break; + + case eEncodingVector: + // Sanity check that bit_size is a multiple of 8's. + if (bit_size && !(bit_size & 0x7u)) + return CompilerType(ast, ast->getExtVectorType(ast->UnsignedCharTy, bit_size / 8)); + break; + } + + return CompilerType(); } QualType -ClangUtil::GetQualType(const CompilerType &ct) +ClangUtil::GetCanonicalQualType(const CompilerType &ct) { - // Make sure we have a clang type before making a clang::QualType if (!IsClangType(ct)) return QualType(); - return QualType::getFromOpaquePtr(ct.GetOpaqueQualType()); + return GetQualType(ct).getCanonicalType(); +} + +bool +ClangUtil::GetCompleteDecl(clang::ASTContext *ast, clang::Decl *decl) +{ + if (!decl) + return false; + + ExternalASTSource *ast_source = ast->getExternalSource(); + + if (!ast_source) + return false; + + if (clang::TagDecl *tag_decl = llvm::dyn_cast(decl)) + { + if (tag_decl->isCompleteDefinition()) + return true; + + if (!tag_decl->hasExternalLexicalStorage()) + return false; + + ast_source->CompleteType(tag_decl); + + return !tag_decl->getTypeForDecl()->isIncompleteType(); + } + else if (clang::ObjCInterfaceDecl *objc_interface_decl = llvm::dyn_cast(decl)) + { + if (objc_interface_decl->getDefinition()) + return true; + + if (!objc_interface_decl->hasExternalLexicalStorage()) + return false; + + ast_source->CompleteType(objc_interface_decl); + + return !objc_interface_decl->getTypeForDecl()->isIncompleteType(); + } + return false; +} + +opaque_compiler_type_t +ClangUtil::GetOpaqueCompilerType(clang::ASTContext *ast, BasicType type) +{ + if (!ast) + return nullptr; + + switch (type) + { + case eBasicTypeVoid: + return ast->VoidTy.getAsOpaquePtr(); + case eBasicTypeChar: + return ast->CharTy.getAsOpaquePtr(); + case eBasicTypeSignedChar: + return ast->SignedCharTy.getAsOpaquePtr(); + case eBasicTypeUnsignedChar: + return ast->UnsignedCharTy.getAsOpaquePtr(); + case eBasicTypeWChar: + return ast->getWCharType().getAsOpaquePtr(); + case eBasicTypeSignedWChar: + return ast->getSignedWCharType().getAsOpaquePtr(); + case eBasicTypeUnsignedWChar: + return ast->getUnsignedWCharType().getAsOpaquePtr(); + case eBasicTypeChar16: + return ast->Char16Ty.getAsOpaquePtr(); + case eBasicTypeChar32: + return ast->Char32Ty.getAsOpaquePtr(); + case eBasicTypeShort: + return ast->ShortTy.getAsOpaquePtr(); + case eBasicTypeUnsignedShort: + return ast->UnsignedShortTy.getAsOpaquePtr(); + case eBasicTypeInt: + return ast->IntTy.getAsOpaquePtr(); + case eBasicTypeUnsignedInt: + return ast->UnsignedIntTy.getAsOpaquePtr(); + case eBasicTypeLong: + return ast->LongTy.getAsOpaquePtr(); + case eBasicTypeUnsignedLong: + return ast->UnsignedLongTy.getAsOpaquePtr(); + case eBasicTypeLongLong: + return ast->LongLongTy.getAsOpaquePtr(); + case eBasicTypeUnsignedLongLong: + return ast->UnsignedLongLongTy.getAsOpaquePtr(); + case eBasicTypeInt128: + return ast->Int128Ty.getAsOpaquePtr(); + case eBasicTypeUnsignedInt128: + return ast->UnsignedInt128Ty.getAsOpaquePtr(); + case eBasicTypeBool: + return ast->BoolTy.getAsOpaquePtr(); + case eBasicTypeHalf: + return ast->HalfTy.getAsOpaquePtr(); + case eBasicTypeFloat: + return ast->FloatTy.getAsOpaquePtr(); + case eBasicTypeDouble: + return ast->DoubleTy.getAsOpaquePtr(); + case eBasicTypeLongDouble: + return ast->LongDoubleTy.getAsOpaquePtr(); + case eBasicTypeFloatComplex: + return ast->FloatComplexTy.getAsOpaquePtr(); + case eBasicTypeDoubleComplex: + return ast->DoubleComplexTy.getAsOpaquePtr(); + case eBasicTypeLongDoubleComplex: + return ast->LongDoubleComplexTy.getAsOpaquePtr(); + case eBasicTypeObjCID: + return ast->getObjCIdType().getAsOpaquePtr(); + case eBasicTypeObjCClass: + return ast->getObjCClassType().getAsOpaquePtr(); + case eBasicTypeObjCSel: + return ast->getObjCSelType().getAsOpaquePtr(); + case eBasicTypeNullPtr: + return ast->NullPtrTy.getAsOpaquePtr(); + default: + return nullptr; + } } QualType -ClangUtil::GetCanonicalQualType(const CompilerType &ct) +ClangUtil::GetQualType(const CompilerType &ct) { + // Make sure we have a clang type before making a clang::QualType if (!IsClangType(ct)) return QualType(); - return GetQualType(ct).getCanonicalType(); + return QualType::getFromOpaquePtr(ct.GetOpaqueQualType()); +} + +bool +ClangUtil::IsClangType(const CompilerType &ct) +{ + if (llvm::dyn_cast_or_null(ct.GetTypeSystem()) == nullptr) + return false; + + if (!ct.GetOpaqueQualType()) + return false; + + return true; +} + +bool +ClangUtil::QualTypeMatchesBitSize(const uint64_t bit_size, ASTContext *ast, QualType qual_type) +{ + uint64_t qual_type_bit_size = ast->getTypeSize(qual_type); + return (qual_type_bit_size == bit_size); } CompilerType @@ -53,6 +462,6 @@ return ct; QualType qual_type(GetQualType(ct)); - qual_type.getQualifiers().removeFastQualifiers(); + qual_type.removeLocalFastQualifiers(); return CompilerType(ct.GetTypeSystem(), qual_type.getAsOpaquePtr()); } Index: unittests/CMakeLists.txt =================================================================== --- unittests/CMakeLists.txt +++ unittests/CMakeLists.txt @@ -44,5 +44,6 @@ add_subdirectory(Host) add_subdirectory(Interpreter) add_subdirectory(ScriptInterpreter) +add_subdirectory(Symbol) add_subdirectory(SymbolFile) add_subdirectory(Utility) Index: unittests/Symbol/CMakeLists.txt =================================================================== --- /dev/null +++ unittests/Symbol/CMakeLists.txt @@ -0,0 +1,3 @@ +add_lldb_unittest(SymbolTests + TestClangUtil.cpp + ) Index: unittests/Symbol/TestClangUtil.cpp =================================================================== --- /dev/null +++ unittests/Symbol/TestClangUtil.cpp @@ -0,0 +1,229 @@ +//===-- TestClangUtil.cpp ---------------------------------------*- C++ -*-===// + +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "gtest/gtest.h" + +#include "lldb/Host/HostInfo.h" +#include "lldb/Symbol/ClangASTContext.h" +#include "lldb/Symbol/ClangUtil.h" +#include "lldb/Symbol/GoASTContext.h" + +using namespace clang; +using namespace lldb; +using namespace lldb_private; + +class TestClangUtil : public testing::Test +{ +public: + static void + SetUpTestCase() + { + HostInfo::Initialize(); + } + + static void + TearDownTestCase() + { + HostInfo::Terminate(); + } + + virtual void + SetUp() override + { + std::string triple = HostInfo::GetTargetTriple(); + m_ast.reset(new ClangASTContext(triple.c_str())); + } + + virtual void + TearDown() override + { + m_ast.reset(); + } + +protected: + std::unique_ptr m_ast; + + QualType + GetQualType(BasicType type) const + { + clang::ASTContext *context = m_ast->getASTContext(); + + return ClangUtil::GetQualType(ClangUtil::GetBasicType(context, type)); + } + + QualType + GetQualType(const char *name) const + { + clang::ASTContext *context = m_ast->getASTContext(); + + return ClangUtil::GetQualType(ClangUtil::GetBasicType(context, ConstString(name))); + } +}; + +TEST_F(TestClangUtil, TestGetBasicTypeFromEnum) +{ + clang::ASTContext *context = m_ast->getASTContext(); + + EXPECT_TRUE(context->hasSameType(GetQualType(eBasicTypeBool), context->BoolTy)); + EXPECT_TRUE(context->hasSameType(GetQualType(eBasicTypeChar), context->CharTy)); + EXPECT_TRUE(context->hasSameType(GetQualType(eBasicTypeChar16), context->Char16Ty)); + EXPECT_TRUE(context->hasSameType(GetQualType(eBasicTypeChar32), context->Char32Ty)); + EXPECT_TRUE(context->hasSameType(GetQualType(eBasicTypeDouble), context->DoubleTy)); + EXPECT_TRUE(context->hasSameType(GetQualType(eBasicTypeDoubleComplex), context->DoubleComplexTy)); + EXPECT_TRUE(context->hasSameType(GetQualType(eBasicTypeFloat), context->FloatTy)); + EXPECT_TRUE(context->hasSameType(GetQualType(eBasicTypeFloatComplex), context->FloatComplexTy)); + EXPECT_TRUE(context->hasSameType(GetQualType(eBasicTypeHalf), context->HalfTy)); + EXPECT_TRUE(context->hasSameType(GetQualType(eBasicTypeInt), context->IntTy)); + EXPECT_TRUE(context->hasSameType(GetQualType(eBasicTypeInt128), context->Int128Ty)); + EXPECT_TRUE(context->hasSameType(GetQualType(eBasicTypeLong), context->LongTy)); + EXPECT_TRUE(context->hasSameType(GetQualType(eBasicTypeLongDouble), context->LongDoubleTy)); + EXPECT_TRUE(context->hasSameType(GetQualType(eBasicTypeLongDoubleComplex), context->LongDoubleComplexTy)); + EXPECT_TRUE(context->hasSameType(GetQualType(eBasicTypeLongLong), context->LongLongTy)); + EXPECT_TRUE(context->hasSameType(GetQualType(eBasicTypeNullPtr), context->NullPtrTy)); + EXPECT_TRUE(context->hasSameType(GetQualType(eBasicTypeObjCClass), context->getObjCClassType())); + EXPECT_TRUE(context->hasSameType(GetQualType(eBasicTypeObjCID), context->getObjCIdType())); + EXPECT_TRUE(context->hasSameType(GetQualType(eBasicTypeObjCSel), context->getObjCSelType())); + EXPECT_TRUE(context->hasSameType(GetQualType(eBasicTypeShort), context->ShortTy)); + EXPECT_TRUE(context->hasSameType(GetQualType(eBasicTypeSignedChar), context->SignedCharTy)); + EXPECT_TRUE(context->hasSameType(GetQualType(eBasicTypeUnsignedChar), context->UnsignedCharTy)); + EXPECT_TRUE(context->hasSameType(GetQualType(eBasicTypeUnsignedInt), context->UnsignedIntTy)); + EXPECT_TRUE(context->hasSameType(GetQualType(eBasicTypeUnsignedInt128), context->UnsignedInt128Ty)); + EXPECT_TRUE(context->hasSameType(GetQualType(eBasicTypeUnsignedLong), context->UnsignedLongTy)); + EXPECT_TRUE(context->hasSameType(GetQualType(eBasicTypeUnsignedLongLong), context->UnsignedLongLongTy)); + EXPECT_TRUE(context->hasSameType(GetQualType(eBasicTypeUnsignedShort), context->UnsignedShortTy)); + EXPECT_TRUE(context->hasSameType(GetQualType(eBasicTypeVoid), context->VoidTy)); + EXPECT_TRUE(context->hasSameType(GetQualType(eBasicTypeWChar), context->WCharTy)); +} + +TEST_F(TestClangUtil, TestGetBasicTypeFromName) +{ + EXPECT_EQ(GetQualType(eBasicTypeChar), GetQualType("char")); + EXPECT_EQ(GetQualType(eBasicTypeSignedChar), GetQualType("signed char")); + EXPECT_EQ(GetQualType(eBasicTypeUnsignedChar), GetQualType("unsigned char")); + EXPECT_EQ(GetQualType(eBasicTypeWChar), GetQualType("wchar_t")); + EXPECT_EQ(GetQualType(eBasicTypeSignedWChar), GetQualType("signed wchar_t")); + EXPECT_EQ(GetQualType(eBasicTypeUnsignedWChar), GetQualType("unsigned wchar_t")); + EXPECT_EQ(GetQualType(eBasicTypeShort), GetQualType("short")); + EXPECT_EQ(GetQualType(eBasicTypeShort), GetQualType("short int")); + EXPECT_EQ(GetQualType(eBasicTypeUnsignedShort), GetQualType("unsigned short")); + EXPECT_EQ(GetQualType(eBasicTypeUnsignedShort), GetQualType("unsigned short int")); + EXPECT_EQ(GetQualType(eBasicTypeInt), GetQualType("int")); + EXPECT_EQ(GetQualType(eBasicTypeInt), GetQualType("signed int")); + EXPECT_EQ(GetQualType(eBasicTypeUnsignedInt), GetQualType("unsigned int")); + EXPECT_EQ(GetQualType(eBasicTypeUnsignedInt), GetQualType("unsigned")); + EXPECT_EQ(GetQualType(eBasicTypeLong), GetQualType("long")); + EXPECT_EQ(GetQualType(eBasicTypeLong), GetQualType("long int")); + EXPECT_EQ(GetQualType(eBasicTypeUnsignedLong), GetQualType("unsigned long")); + EXPECT_EQ(GetQualType(eBasicTypeUnsignedLong), GetQualType("unsigned long int")); + EXPECT_EQ(GetQualType(eBasicTypeLongLong), GetQualType("long long")); + EXPECT_EQ(GetQualType(eBasicTypeLongLong), GetQualType("long long int")); + EXPECT_EQ(GetQualType(eBasicTypeUnsignedLongLong), GetQualType("unsigned long long")); + EXPECT_EQ(GetQualType(eBasicTypeUnsignedLongLong), GetQualType("unsigned long long int")); + EXPECT_EQ(GetQualType(eBasicTypeInt128), GetQualType("__int128_t")); + EXPECT_EQ(GetQualType(eBasicTypeUnsignedInt128), GetQualType("__uint128_t")); + EXPECT_EQ(GetQualType(eBasicTypeVoid), GetQualType("void")); + EXPECT_EQ(GetQualType(eBasicTypeBool), GetQualType("bool")); + EXPECT_EQ(GetQualType(eBasicTypeFloat), GetQualType("float")); + EXPECT_EQ(GetQualType(eBasicTypeDouble), GetQualType("double")); + EXPECT_EQ(GetQualType(eBasicTypeLongDouble), GetQualType("long double")); + EXPECT_EQ(GetQualType(eBasicTypeObjCID), GetQualType("id")); + EXPECT_EQ(GetQualType(eBasicTypeObjCSel), GetQualType("SEL")); + EXPECT_EQ(GetQualType(eBasicTypeNullPtr), GetQualType("nullptr")); +} + +void +VerifyEncodingAndBitSize(clang::ASTContext *context, lldb::Encoding encoding, int bit_size) +{ + CompilerType type = ClangUtil::GetBuiltinTypeForEncodingAndBitSize(context, encoding, bit_size); + EXPECT_TRUE(type.IsValid()); + + QualType qtype = ClangUtil::GetQualType(type); + EXPECT_FALSE(qtype.isNull()); + if (qtype.isNull()) + return; + + uint64_t actual_size = context->getTypeSize(qtype); + EXPECT_EQ(bit_size, actual_size); + + const clang::Type *type_ptr = qtype.getTypePtr(); + EXPECT_NE(nullptr, type_ptr); + if (!type_ptr) + return; + + EXPECT_TRUE(type_ptr->isBuiltinType()); + if (encoding == eEncodingSint) + EXPECT_TRUE(type_ptr->isSignedIntegerType()); + else if (encoding == eEncodingUint) + EXPECT_TRUE(type_ptr->isUnsignedIntegerType()); + else if (encoding == eEncodingIEEE754) + EXPECT_TRUE(type_ptr->isFloatingType()); +} + +TEST_F(TestClangUtil, TestBuiltinTypeForEncodingAndBitSize) +{ + clang::ASTContext *context = m_ast->getASTContext(); + + // Make sure we can get types of every possible size in every possible encoding. + // We can't make any guarantee about which specific type we get, because the standard + // isn't that specific. We only need to make sure the compiler hands us some type that + // is both a builtin type and matches the requested bit size. + VerifyEncodingAndBitSize(context, eEncodingSint, 8); + VerifyEncodingAndBitSize(context, eEncodingSint, 16); + VerifyEncodingAndBitSize(context, eEncodingSint, 32); + VerifyEncodingAndBitSize(context, eEncodingSint, 64); + VerifyEncodingAndBitSize(context, eEncodingSint, 128); + + VerifyEncodingAndBitSize(context, eEncodingUint, 8); + VerifyEncodingAndBitSize(context, eEncodingUint, 16); + VerifyEncodingAndBitSize(context, eEncodingUint, 32); + VerifyEncodingAndBitSize(context, eEncodingUint, 64); + VerifyEncodingAndBitSize(context, eEncodingUint, 128); + + VerifyEncodingAndBitSize(context, eEncodingIEEE754, 32); + VerifyEncodingAndBitSize(context, eEncodingIEEE754, 64); +} + +TEST_F(TestClangUtil, TestIsClangType) +{ + clang::ASTContext *context = m_ast->getASTContext(); + lldb::opaque_compiler_type_t bool_ctype = ClangUtil::GetOpaqueCompilerType(context, lldb::eBasicTypeBool); + CompilerType bool_type(m_ast.get(), bool_ctype); + CompilerType record_type = m_ast->CreateRecordType(nullptr, lldb::eAccessPublic, "FooRecord", clang::TTK_Struct, + lldb::eLanguageTypeC_plus_plus, nullptr); + // Clang builtin type and record type should pass + EXPECT_TRUE(ClangUtil::IsClangType(bool_type)); + EXPECT_TRUE(ClangUtil::IsClangType(record_type)); + + // Default constructed type should fail + EXPECT_FALSE(ClangUtil::IsClangType(CompilerType())); + + // Go type should fail + GoASTContext go_ast; + CompilerType go_type(&go_ast, bool_ctype); + EXPECT_FALSE(ClangUtil::IsClangType(go_type)); +} + +TEST_F(TestClangUtil, TestRemoveFastQualifiers) +{ + CompilerType record_type = m_ast->CreateRecordType(nullptr, lldb::eAccessPublic, "FooRecord", clang::TTK_Struct, + lldb::eLanguageTypeC_plus_plus, nullptr); + QualType qt; + + qt = ClangUtil::GetQualType(record_type); + EXPECT_EQ(0, qt.getLocalFastQualifiers()); + record_type = record_type.AddConstModifier(); + record_type = record_type.AddVolatileModifier(); + record_type = record_type.AddRestrictModifier(); + qt = ClangUtil::GetQualType(record_type); + EXPECT_NE(0, qt.getLocalFastQualifiers()); + record_type = ClangUtil::RemoveFastQualifiers(record_type); + qt = ClangUtil::GetQualType(record_type); + EXPECT_EQ(0, qt.getLocalFastQualifiers()); +}