Index: clang/include/clang/AST/DeclBase.h =================================================================== --- clang/include/clang/AST/DeclBase.h +++ clang/include/clang/AST/DeclBase.h @@ -626,13 +626,15 @@ setModuleOwnershipKind(ModuleOwnershipKind::ModulePrivate); } +public: + void setFromASTFile() { FromASTFile = true; } + /// Set the owning module ID. void setOwningModuleID(unsigned ID) { assert(isFromASTFile() && "Only works on a deserialized declaration"); *((unsigned*)this - 2) = ID; } -public: /// Determine the availability of the given declaration. /// /// This routine will determine the most restrictive availability of Index: clang/include/clang/AST/ExternalASTSource.h =================================================================== --- clang/include/clang/AST/ExternalASTSource.h +++ clang/include/clang/AST/ExternalASTSource.h @@ -173,7 +173,7 @@ StringRef Path; StringRef ASTFile; ASTFileSignature Signature; - const Module *ClangModule = nullptr; + Module *ClangModule = nullptr; public: ASTSourceDescriptor() = default; @@ -181,13 +181,13 @@ ASTFileSignature Signature) : PCHModuleName(std::move(Name)), Path(std::move(Path)), ASTFile(std::move(ASTFile)), Signature(Signature) {} - ASTSourceDescriptor(const Module &M); + ASTSourceDescriptor(Module &M); std::string getModuleName() const; StringRef getPath() const { return Path; } StringRef getASTFile() const { return ASTFile; } ASTFileSignature getSignature() const { return Signature; } - const Module *getModuleOrNull() const { return ClangModule; } + Module *getModuleOrNull() const { return ClangModule; } }; /// Return a descriptor for the corresponding module, if one exists. Index: clang/lib/AST/ExternalASTSource.cpp =================================================================== --- clang/lib/AST/ExternalASTSource.cpp +++ clang/lib/AST/ExternalASTSource.cpp @@ -39,7 +39,7 @@ return EK_ReplyHazy; } -ExternalASTSource::ASTSourceDescriptor::ASTSourceDescriptor(const Module &M) +ExternalASTSource::ASTSourceDescriptor::ASTSourceDescriptor(Module &M) : Signature(M.Signature), ClangModule(&M) { if (M.Directory) Path = M.Directory->getName(); Index: clang/lib/Serialization/ASTReader.cpp =================================================================== --- clang/lib/Serialization/ASTReader.cpp +++ clang/lib/Serialization/ASTReader.cpp @@ -8493,7 +8493,7 @@ llvm::Optional ASTReader::getSourceDescriptor(unsigned ID) { - if (const Module *M = getSubmodule(ID)) + if (Module *M = getSubmodule(ID)) return ExternalASTSource::ASTSourceDescriptor(*M); // If there is only a single PCH, return it instead. Index: lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp =================================================================== --- lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp +++ lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp @@ -661,7 +661,7 @@ if (namespace_context->getName().str() == std::string(g_lldb_local_vars_namespace_cstr)) { CompilerDeclContext compiler_decl_ctx = - m_clang_ast_context->CreateDeclContext( + m_clang_ast_context->GetAsCompilerDeclContext( const_cast(context.m_decl_context)); FindExternalVisibleDecls(context, lldb::ModuleSP(), compiler_decl_ctx); return; @@ -993,7 +993,7 @@ clang::NamespaceDecl *namespace_decl = m_clang_ast_context->GetUniqueNamespaceDeclaration( - g_lldb_local_vars_namespace_cstr, nullptr); + g_lldb_local_vars_namespace_cstr, {}); if (!namespace_decl) return; Index: lldb/source/Plugins/ExpressionParser/Clang/ClangExternalASTSourceCallbacks.h =================================================================== --- lldb/source/Plugins/ExpressionParser/Clang/ClangExternalASTSourceCallbacks.h +++ lldb/source/Plugins/ExpressionParser/Clang/ClangExternalASTSourceCallbacks.h @@ -17,7 +17,14 @@ class TypeSystemClang; class ClangExternalASTSourceCallbacks : public clang::ExternalASTSource { + /// LLVM RTTI support. + static char ID; + public: + /// LLVM RTTI support. + bool isA(const void *ClassID) const override { return ClassID == &ID; } + static bool classof(const clang::ExternalASTSource *s) { return s->isA(&ID); } + ClangExternalASTSourceCallbacks(TypeSystemClang &ast) : m_ast(ast) {} void FindExternalLexicalDecls( @@ -37,8 +44,17 @@ llvm::DenseMap &VirtualBaseOffsets) override; + unsigned registerModule(clang::Module *module); + unsigned getIDForModule(clang::Module *module); + TypeSystemClang &GetTypeSystem() const { return m_ast; } + + llvm::Optional + getSourceDescriptor(unsigned ID) override; + clang::Module *getModule(unsigned ID) override; private: TypeSystemClang &m_ast; + std::vector m_modules; + llvm::DenseMap m_ids; }; } // namespace lldb_private Index: lldb/source/Plugins/ExpressionParser/Clang/ClangExternalASTSourceCallbacks.cpp =================================================================== --- lldb/source/Plugins/ExpressionParser/Clang/ClangExternalASTSourceCallbacks.cpp +++ lldb/source/Plugins/ExpressionParser/Clang/ClangExternalASTSourceCallbacks.cpp @@ -13,6 +13,8 @@ using namespace lldb_private; +char ClangExternalASTSourceCallbacks::ID; + void ClangExternalASTSourceCallbacks::CompleteType(clang::TagDecl *tag_decl) { m_ast.CompleteTagDecl(tag_decl); } @@ -43,3 +45,27 @@ CompleteType(tag_decl); } } + +unsigned ClangExternalASTSourceCallbacks::registerModule(clang::Module *module) { + m_modules.push_back(module); + unsigned id = m_modules.size(); + m_ids.insert({module, id}); + return id; +} + +llvm::Optional +ClangExternalASTSourceCallbacks::getSourceDescriptor(unsigned id) { + if (clang::Module *module = getModule(id)) + return {*module}; + return {}; +} + +clang::Module *ClangExternalASTSourceCallbacks::getModule(unsigned id) { + if (id && id <= m_modules.size()) + return m_modules[id - 1]; + return nullptr; +} + +unsigned ClangExternalASTSourceCallbacks::getIDForModule(clang::Module *module) { + return m_ids[module]; +} Index: lldb/source/Plugins/Language/ObjC/NSDictionary.cpp =================================================================== --- lldb/source/Plugins/Language/ObjC/NSDictionary.cpp +++ lldb/source/Plugins/Language/ObjC/NSDictionary.cpp @@ -76,7 +76,7 @@ if (!compiler_type) { compiler_type = target_ast_context->CreateRecordType( - nullptr, lldb::eAccessPublic, g___lldb_autogen_nspair.GetCString(), + {}, lldb::eAccessPublic, g___lldb_autogen_nspair.GetCString(), clang::TTK_Struct, lldb::eLanguageTypeC); if (compiler_type) { Index: lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTypeEncodingParser.cpp =================================================================== --- lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTypeEncodingParser.cpp +++ lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTypeEncodingParser.cpp @@ -124,7 +124,7 @@ return clang::QualType(); // This is where we bail out. Sorry! CompilerType union_type(ast_ctx.CreateRecordType( - nullptr, lldb::eAccessPublic, name, kind, lldb::eLanguageTypeC)); + {}, lldb::eAccessPublic, name, kind, lldb::eLanguageTypeC)); if (union_type) { TypeSystemClang::StartTagDeclarationDefinition(union_type); Index: lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h =================================================================== --- lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h +++ lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h @@ -74,10 +74,12 @@ typedef std::vector DelayedPropertyList; typedef llvm::SmallPtrSet DIEPointerSet; - typedef llvm::DenseMap + typedef llvm::DenseMap DIEToDeclContextMap; - typedef std::multimap - DeclContextToDIEMap; + typedef llvm::DenseMap + DIEToModuleMap; + typedef std::multimap DeclContextToDIEMap; typedef llvm::DenseMap DIEToDeclMap; typedef llvm::DenseMap DeclToDIEMap; @@ -87,10 +89,12 @@ DeclToDIEMap m_decl_to_die; DIEToDeclContextMap m_die_to_decl_ctx; DeclContextToDIEMap m_decl_ctx_to_die; + DIEToModuleMap m_die_to_module; std::unique_ptr m_clang_ast_importer_up; /// @} - clang::DeclContext *GetDeclContextForBlock(const DWARFDIE &die); + lldb_private::CompilerDeclContext + GetDeclContextForBlock(const DWARFDIE &die, unsigned owning_module); clang::BlockDecl *ResolveBlockDIE(const DWARFDIE &die); @@ -115,7 +119,7 @@ lldb_private::ClangASTImporter::LayoutInfo &layout_info); size_t - ParseChildParameters(clang::DeclContext *containing_decl_ctx, + ParseChildParameters(lldb_private::CompilerDeclContext containing_decl_ctx, const DWARFDIE &parent_die, bool skip_artificial, bool &is_static, bool &is_variadic, bool &has_template_params, @@ -136,19 +140,23 @@ clang::Decl *GetClangDeclForDIE(const DWARFDIE &die); - clang::DeclContext *GetClangDeclContextForDIE(const DWARFDIE &die); + lldb_private::CompilerDeclContext + GetClangDeclContextForDIE(const DWARFDIE &die, unsigned owning_module); - clang::DeclContext *GetClangDeclContextContainingDIE(const DWARFDIE &die, - DWARFDIE *decl_ctx_die); + lldb_private::CompilerDeclContext + GetClangDeclContextContainingDIE(const DWARFDIE &die, DWARFDIE *decl_ctx_die); + unsigned GetOwningModuleID(const DWARFDIE &die); bool CopyUniqueClassMethodTypes(const DWARFDIE &src_class_die, const DWARFDIE &dst_class_die, lldb_private::Type *class_type, std::vector &failures); - clang::DeclContext *GetCachedClangDeclContextForDIE(const DWARFDIE &die); + lldb_private::CompilerDeclContext + GetCachedClangDeclContextForDIE(const DWARFDIE &die); - void LinkDeclContextToDIE(clang::DeclContext *decl_ctx, const DWARFDIE &die); + void LinkDeclContextToDIE(lldb_private::CompilerDeclContext decl_ctx, + const DWARFDIE &die); void LinkDeclToDIE(clang::Decl *decl, const DWARFDIE &die); Index: lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp =================================================================== --- lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp +++ lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp @@ -216,9 +216,10 @@ dwarf->GetDIEToType()[die.GetDIE()] = type_sp.get(); clang::TagDecl *tag_decl = TypeSystemClang::GetAsTagDecl(type); if (tag_decl) - LinkDeclContextToDIE(tag_decl, die); + LinkDeclContextToDIE( + m_ast.CreateDeclContext(tag_decl, tag_decl->getOwningModuleID()), die); else { - clang::DeclContext *defn_decl_ctx = GetCachedClangDeclContextForDIE(die); + CompilerDeclContext defn_decl_ctx = GetCachedClangDeclContextForDIE(die); if (defn_decl_ctx) LinkDeclContextToDIE(defn_decl_ctx, die); } @@ -231,7 +232,7 @@ clang::DeclContext *decl_ctx, DWARFDIE die, const char *type_name_cstr) { - auto *tag_decl_ctx = clang::dyn_cast(decl_ctx); + auto *tag_decl_ctx = clang::dyn_cast_or_null(decl_ctx); if (!tag_decl_ctx) return; @@ -401,15 +402,15 @@ SymbolFileDWARF *dwarf = die.GetDWARF(); if (log) { DWARFDIE context_die; - clang::DeclContext *context = + CompilerDeclContext context = GetClangDeclContextContainingDIE(die, &context_die); dwarf->GetObjectFile()->GetModule()->LogMessage( log, "DWARFASTParserClang::ParseTypeFromDWARF " "(die = 0x%8.8x, decl_ctx = %p (die 0x%8.8x)) %s name = '%s')", - die.GetOffset(), static_cast(context), context_die.GetOffset(), - die.GetTagAsCString(), die.GetName()); + die.GetOffset(), context.GetOpaqueDeclContext(), + context_die.GetOffset(), die.GetTagAsCString(), die.GetName()); } Type *type_ptr = dwarf->GetDIEToType().lookup(die.GetDIE()); @@ -426,7 +427,7 @@ if (TypeSP type_sp = ParseTypeFromDWARF(sc, signature_die, type_is_new_ptr)) { dwarf->GetDIEToType()[die.GetDIE()] = type_sp.get(); - if (clang::DeclContext *decl_ctx = + if (CompilerDeclContext decl_ctx = GetCachedClangDeclContextForDIE(signature_die)) LinkDeclContextToDIE(decl_ctx, die); return type_sp; @@ -755,7 +756,7 @@ // it and cache the fact that we found a complete type for this // die dwarf->GetDIEToType()[die.GetDIE()] = type_sp.get(); - clang::DeclContext *defn_decl_ctx = + CompilerDeclContext defn_decl_ctx = GetCachedClangDeclContextForDIE(dwarf->GetDIE(type_sp->GetID())); if (defn_decl_ctx) LinkDeclContextToDIE(defn_decl_ctx, die); @@ -793,7 +794,10 @@ enumerator_clang_type = m_ast.GetEnumerationIntegerType(clang_type); } - LinkDeclContextToDIE(TypeSystemClang::GetDeclContextForType(clang_type), die); + LinkDeclContextToDIE(m_ast.CreateDeclContext( + TypeSystemClang::GetDeclContextForType(clang_type), + GetOwningModuleID(die)), + die); type_sp = std::make_shared( die.GetID(), dwarf, attrs.name, attrs.byte_size, nullptr, @@ -859,10 +863,10 @@ // Parse the function children for the parameters DWARFDIE decl_ctx_die; - clang::DeclContext *containing_decl_ctx = + CompilerDeclContext containing_decl_ctx = GetClangDeclContextContainingDIE(die, &decl_ctx_die); const clang::Decl::Kind containing_decl_kind = - containing_decl_ctx->getDeclKind(); + m_ast.GetClangDeclContext(containing_decl_ctx)->getDeclKind(); bool is_cxx_method = DeclKindIsCXXClass(containing_decl_kind); // Start off static. This will be set to false in @@ -936,7 +940,9 @@ attrs.is_objc_direct_call); type_handled = objc_method_decl != NULL; if (type_handled) { - LinkDeclContextToDIE(objc_method_decl, die); + LinkDeclContextToDIE(m_ast.CreateDeclContext( + objc_method_decl, GetOwningModuleID(die)), + die); m_ast.SetMetadataAsUserID(objc_method_decl, die.GetID()); } else { dwarf->GetObjectFile()->GetModule()->ReportError( @@ -989,8 +995,8 @@ // have been made with the specification and not with this // die. DWARFDIE spec_die = attrs.specification.Reference(); - clang::DeclContext *spec_clang_decl_ctx = - GetClangDeclContextForDIE(spec_die); + CompilerDeclContext spec_clang_decl_ctx = + GetClangDeclContextForDIE(spec_die, GetOwningModuleID(die)); if (spec_clang_decl_ctx) { LinkDeclContextToDIE(spec_clang_decl_ctx, die); } else { @@ -1008,8 +1014,8 @@ class_type->GetForwardCompilerType(); DWARFDIE abs_die = attrs.abstract_origin.Reference(); - clang::DeclContext *abs_clang_decl_ctx = - GetClangDeclContextForDIE(abs_die); + CompilerDeclContext abs_clang_decl_ctx = + GetClangDeclContextForDIE(abs_die, GetOwningModuleID(die)); if (abs_clang_decl_ctx) { LinkDeclContextToDIE(abs_clang_decl_ctx, die); } else { @@ -1049,7 +1055,10 @@ if (method_decl->getType() == ClangUtil::GetQualType(clang_type)) { add_method = false; - LinkDeclContextToDIE(method_decl, die); + LinkDeclContextToDIE( + m_ast.CreateDeclContext(method_decl, + GetOwningModuleID(die)), + die); type_handled = true; break; @@ -1091,7 +1100,10 @@ type_handled |= attrs.is_artificial; if (cxx_method_decl) { - LinkDeclContextToDIE(cxx_method_decl, die); + LinkDeclContextToDIE( + m_ast.CreateDeclContext(cxx_method_decl, + GetOwningModuleID(die)), + die); ClangASTMetadata metadata; metadata.SetUserID(die.GetID()); @@ -1150,6 +1162,7 @@ } if (!type_handled) { + CompilerDeclContext ctx; clang::FunctionDecl *function_decl = nullptr; clang::FunctionDecl *template_function_decl = nullptr; @@ -1157,11 +1170,12 @@ DWARFDIE abs_die = attrs.abstract_origin.Reference(); if (dwarf->ResolveType(abs_die)) { + ctx = GetCachedClangDeclContextForDIE(abs_die); function_decl = llvm::dyn_cast_or_null( - GetCachedClangDeclContextForDIE(abs_die)); + m_ast.GetClangDeclContext(ctx)); if (function_decl) { - LinkDeclContextToDIE(function_decl, die); + LinkDeclContextToDIE(ctx, die); } } } @@ -1169,8 +1183,9 @@ if (!function_decl) { // We just have a function that isn't part of a class function_decl = m_ast.CreateFunctionDeclaration( - ignore_containing_context ? m_ast.GetTranslationUnitDecl() - : containing_decl_ctx, + ignore_containing_context + ? m_ast.CreateDeclContext(m_ast.GetTranslationUnitDecl(), 0) + : containing_decl_ctx, attrs.name.GetCString(), clang_type, attrs.storage, attrs.is_inline); @@ -1178,8 +1193,9 @@ TypeSystemClang::TemplateParameterInfos template_param_infos; ParseTemplateParameterInfos(die, template_param_infos); template_function_decl = m_ast.CreateFunctionDeclaration( - ignore_containing_context ? m_ast.GetTranslationUnitDecl() - : containing_decl_ctx, + ignore_containing_context + ? m_ast.CreateDeclContext(m_ast.GetTranslationUnitDecl(), 0) + : containing_decl_ctx, attrs.name.GetCString(), clang_type, attrs.storage, attrs.is_inline); clang::FunctionTemplateDecl *func_template_decl = @@ -1193,7 +1209,7 @@ lldbassert(function_decl); if (function_decl) { - LinkDeclContextToDIE(function_decl, die); + LinkDeclContextToDIE(ctx, die); if (!function_param_decls.empty()) { m_ast.SetFunctionParameters(function_decl, @@ -1543,7 +1559,7 @@ // We found a real definition for this type elsewhere so lets use // it and cache the fact that we found a complete type for this die dwarf->GetDIEToType()[die.GetDIE()] = type_sp.get(); - clang::DeclContext *defn_decl_ctx = + CompilerDeclContext defn_decl_ctx = GetCachedClangDeclContextForDIE(dwarf->GetDIE(type_sp->GetID())); if (defn_decl_ctx) LinkDeclContextToDIE(defn_decl_ctx, die); @@ -1554,22 +1570,27 @@ bool clang_type_was_created = false; clang_type.SetCompilerType( &m_ast, dwarf->GetForwardDeclDieToClangType().lookup(die.GetDIE())); - if (!clang_type) { - clang::DeclContext *decl_ctx = - GetClangDeclContextContainingDIE(die, nullptr); + CompilerDeclContext decl_ctx; + if (clang_type) { + // FIXME: This drops the owning module information. + decl_ctx = + m_ast.GetAsCompilerDeclContext(m_ast.GetDeclContextForType(clang_type)); + } else { + decl_ctx = GetClangDeclContextContainingDIE(die, nullptr); + clang::DeclContext *clang_decl_ctx = m_ast.GetClangDeclContext(decl_ctx); // If your decl context is a record that was imported from another // AST context (in the gmodules case), we need to make sure the type // backing the Decl is complete before adding children to it. This is // not an issue in the non-gmodules case because the debug info will // always contain a full definition of parent types in that case. - CompleteExternalTagDeclType(m_ast, GetClangASTImporter(), decl_ctx, die, + CompleteExternalTagDeclType(m_ast, GetClangASTImporter(), clang_decl_ctx, die, attrs.name.GetCString()); - if (attrs.accessibility == eAccessNone && decl_ctx) { + if (attrs.accessibility == eAccessNone && clang_decl_ctx) { // Check the decl context that contains this class/struct/union. If // it is a class we must give it an accessibility. - const clang::Decl::Kind containing_decl_kind = decl_ctx->getDeclKind(); + const clang::Decl::Kind containing_decl_kind = clang_decl_ctx->getDeclKind(); if (DeclKindIsCXXClass(containing_decl_kind)) attrs.accessibility = default_accessibility; } @@ -1621,7 +1642,7 @@ // Store a forward declaration to this class type in case any // parameters in any class methods need it for the clang types for // function prototypes. - LinkDeclContextToDIE(m_ast.GetDeclContextForType(clang_type), die); + LinkDeclContextToDIE(decl_ctx, die); type_sp = std::make_shared(die.GetID(), dwarf, attrs.name, attrs.byte_size, nullptr, LLDB_INVALID_UID, Type::eEncodingIsUID, &attrs.decl, @@ -2183,19 +2204,22 @@ CompilerDeclContext DWARFASTParserClang::GetDeclContextForUIDFromDWARF(const DWARFDIE &die) { - clang::DeclContext *clang_decl_ctx = GetClangDeclContextForDIE(die); - if (clang_decl_ctx) - return m_ast.CreateDeclContext(clang_decl_ctx); - return CompilerDeclContext(); + CompilerDeclContext clang_decl_ctx = + GetClangDeclContextForDIE(die, GetOwningModuleID(die)); + assert(&m_ast.GetClangDeclContext(clang_decl_ctx)->getParentASTContext() == + &m_ast.getASTContext() && + "decl context belongs to different typesystem"); + return clang_decl_ctx; } CompilerDeclContext DWARFASTParserClang::GetDeclContextContainingUIDFromDWARF(const DWARFDIE &die) { - clang::DeclContext *clang_decl_ctx = + CompilerDeclContext clang_decl_ctx = GetClangDeclContextContainingDIE(die, nullptr); - if (clang_decl_ctx) - return m_ast.CreateDeclContext(clang_decl_ctx); - return CompilerDeclContext(); + assert(&m_ast.GetClangDeclContext(clang_decl_ctx)->getParentASTContext() == + &m_ast.getASTContext() && + "decl context belongs to different typesystem"); + return clang_decl_ctx; } size_t DWARFASTParserClang::ParseChildEnumerators( @@ -2325,7 +2349,7 @@ DWARFDeclContext decl_ctx = SymbolFileDWARF::GetDWARFDeclContext(die); sstr << decl_ctx.GetQualifiedName(); - clang::DeclContext *containing_decl_ctx = + CompilerDeclContext containing_decl_ctx = GetClangDeclContextContainingDIE(die, nullptr); ParseChildParameters(containing_decl_ctx, die, true, is_static, is_variadic, has_template_params, param_types, @@ -2974,7 +2998,7 @@ } size_t DWARFASTParserClang::ParseChildParameters( - clang::DeclContext *containing_decl_ctx, const DWARFDIE &parent_die, + CompilerDeclContext containing_decl_ctx, const DWARFDIE &parent_die, bool skip_artificial, bool &is_static, bool &is_variadic, bool &has_template_params, std::vector &function_param_types, std::vector &function_param_decls, @@ -3033,7 +3057,8 @@ // In order to determine if a C++ member function is "const" we // have to look at the const-ness of "this"... if (arg_idx == 0 && - DeclKindIsCXXClass(containing_decl_ctx->getDeclKind()) && + DeclKindIsCXXClass(m_ast.GetClangDeclContext(containing_decl_ctx) + ->getDeclKind()) && // Often times compilers omit the "this" name for the // specification DIEs, so we can't rely upon the name being in // the formal parameter DIE... @@ -3256,12 +3281,8 @@ SymbolFileDWARF *dwarf = die.GetDWARF(); Type *type = GetTypeForDIE(die); if (dwarf && type) { - const char *name = die.GetName(); - clang::DeclContext *decl_context = - TypeSystemClang::DeclContextGetAsDeclContext( - dwarf->GetDeclContextContainingUID(die.GetID())); decl = m_ast.CreateVariableDeclaration( - decl_context, name, + dwarf->GetDeclContextContainingUID(die.GetID()), die.GetName(), ClangUtil::GetQualType(type->GetForwardCompilerType())); } break; @@ -3272,14 +3293,12 @@ if (imported_uid) { CompilerDecl imported_decl = SymbolFileDWARF::GetDecl(imported_uid); if (imported_decl) { - clang::DeclContext *decl_context = - TypeSystemClang::DeclContextGetAsDeclContext( - dwarf->GetDeclContextContainingUID(die.GetID())); if (clang::NamedDecl *clang_imported_decl = llvm::dyn_cast( (clang::Decl *)imported_decl.GetOpaqueDecl())) - decl = - m_ast.CreateUsingDeclaration(decl_context, clang_imported_decl); + decl = m_ast.CreateUsingDeclaration( + dwarf->GetDeclContextContainingUID(die.GetID()), + clang_imported_decl); } } break; @@ -3292,13 +3311,11 @@ CompilerDeclContext imported_decl_ctx = SymbolFileDWARF::GetDeclContext(imported_uid); if (imported_decl_ctx) { - clang::DeclContext *decl_context = - TypeSystemClang::DeclContextGetAsDeclContext( - dwarf->GetDeclContextContainingUID(die.GetID())); if (clang::NamespaceDecl *ns_decl = TypeSystemClang::DeclContextGetAsNamespaceDecl( imported_decl_ctx)) - decl = m_ast.CreateUsingDirectiveDeclaration(decl_context, ns_decl); + decl = m_ast.CreateUsingDirectiveDeclaration( + dwarf->GetDeclContextContainingUID(die.GetID()), ns_decl); } } break; @@ -3313,10 +3330,11 @@ return decl; } -clang::DeclContext * -DWARFASTParserClang::GetClangDeclContextForDIE(const DWARFDIE &die) { +CompilerDeclContext +DWARFASTParserClang::GetClangDeclContextForDIE(const DWARFDIE &die, + unsigned owning_module) { if (die) { - clang::DeclContext *decl_ctx = GetCachedClangDeclContextForDIE(die); + CompilerDeclContext decl_ctx = GetCachedClangDeclContextForDIE(die); if (decl_ctx) return decl_ctx; @@ -3324,17 +3342,17 @@ switch (die.Tag()) { case DW_TAG_compile_unit: case DW_TAG_partial_unit: - decl_ctx = m_ast.GetTranslationUnitDecl(); + decl_ctx = m_ast.CreateDeclContext(m_ast.GetTranslationUnitDecl(), owning_module); try_parsing_type = false; break; case DW_TAG_namespace: - decl_ctx = ResolveNamespaceDIE(die); + decl_ctx = m_ast.CreateDeclContext(ResolveNamespaceDIE(die), owning_module); try_parsing_type = false; break; case DW_TAG_lexical_block: - decl_ctx = GetDeclContextForBlock(die); + decl_ctx = GetDeclContextForBlock(die, owning_module); try_parsing_type = false; break; @@ -3342,7 +3360,7 @@ break; } - if (decl_ctx == nullptr && try_parsing_type) { + if (!decl_ctx && try_parsing_type) { Type *type = die.GetDWARF()->ResolveType(die); if (type) decl_ctx = GetCachedClangDeclContextForDIE(die); @@ -3353,7 +3371,32 @@ return decl_ctx; } } - return nullptr; + return {}; +} + +unsigned DWARFASTParserClang::GetOwningModuleID(const DWARFDIE &die) { + if (!die.IsValid()) + return 0; + + for (DWARFDIE parent = die.GetParent(); parent.IsValid(); + parent = parent.GetParent()) { + const dw_tag_t tag = parent.Tag(); + if (tag == DW_TAG_module) { + DWARFDIE module_die = parent; + auto it = m_die_to_module.find(module_die.GetDIE()); + if (it != m_die_to_module.end()) + return it->second; + const char *name = module_die.GetAttributeValueAsString(DW_AT_name, 0); + if (!name) + return 0; + + unsigned id = + m_ast.GetOrCreateClangModule(name, GetOwningModuleID(module_die)); + m_die_to_module.insert({module_die.GetDIE(), id}); + return id; + } + } + return 0; } static bool IsSubroutine(const DWARFDIE &die) { @@ -3404,34 +3447,40 @@ return DWARFDIE(); } -clang::DeclContext * -DWARFASTParserClang::GetDeclContextForBlock(const DWARFDIE &die) { +CompilerDeclContext +DWARFASTParserClang::GetDeclContextForBlock(const DWARFDIE &die, + unsigned owning_module) { assert(die.Tag() == DW_TAG_lexical_block); DWARFDIE containing_function_with_abstract_origin = GetContainingFunctionWithAbstractOrigin(die); if (!containing_function_with_abstract_origin) { - return (clang::DeclContext *)ResolveBlockDIE(die); + return m_ast.CreateDeclContext(ResolveBlockDIE(die), owning_module); } DWARFDIE child = FindFirstChildWithAbstractOrigin( die, containing_function_with_abstract_origin); CompilerDeclContext decl_context = GetDeclContextContainingUIDFromDWARF(child); - return (clang::DeclContext *)decl_context.GetOpaqueDeclContext(); + if (m_ast.GetModuleDeclContextFromCompilerDeclContext(decl_context) + .owning_module != owning_module) + return m_ast.CreateDeclContext(m_ast.GetClangDeclContext(decl_context), + owning_module); + return decl_context; } clang::BlockDecl *DWARFASTParserClang::ResolveBlockDIE(const DWARFDIE &die) { if (die && die.Tag() == DW_TAG_lexical_block) { - clang::BlockDecl *decl = - llvm::cast_or_null(m_die_to_decl_ctx[die.GetDIE()]); + clang::BlockDecl *decl = llvm::cast_or_null( + m_ast.GetClangDeclContext(m_die_to_decl_ctx[die.GetDIE()])); if (!decl) { DWARFDIE decl_context_die; - clang::DeclContext *decl_context = + CompilerDeclContext decl_context = GetClangDeclContextContainingDIE(die, &decl_context_die); decl = m_ast.CreateBlockDeclaration(decl_context); if (decl) - LinkDeclContextToDIE((clang::DeclContext *)decl, die); + LinkDeclContextToDIE( + m_ast.CreateDeclContext(decl, GetOwningModuleID(die)), die); } return decl; @@ -3444,13 +3493,13 @@ if (die && die.Tag() == DW_TAG_namespace) { // See if we already parsed this namespace DIE and associated it with a // uniqued namespace declaration - clang::NamespaceDecl *namespace_decl = - static_cast(m_die_to_decl_ctx[die.GetDIE()]); + clang::NamespaceDecl *namespace_decl = static_cast( + m_ast.GetClangDeclContext(m_die_to_decl_ctx[die.GetDIE()])); if (namespace_decl) return namespace_decl; else { const char *namespace_name = die.GetName(); - clang::DeclContext *containing_decl_ctx = + CompilerDeclContext containing_decl_ctx = GetClangDeclContextContainingDIE(die, nullptr); bool is_inline = die.GetAttributeValueAsUnsigned(DW_AT_export_symbols, 0) != 0; @@ -3483,47 +3532,50 @@ } if (namespace_decl) - LinkDeclContextToDIE((clang::DeclContext *)namespace_decl, die); + LinkDeclContextToDIE( + m_ast.CreateDeclContext(namespace_decl, GetOwningModuleID(die)), + die); return namespace_decl; } } return nullptr; } -clang::DeclContext *DWARFASTParserClang::GetClangDeclContextContainingDIE( +CompilerDeclContext DWARFASTParserClang::GetClangDeclContextContainingDIE( const DWARFDIE &die, DWARFDIE *decl_ctx_die_copy) { SymbolFileDWARF *dwarf = die.GetDWARF(); DWARFDIE decl_ctx_die = dwarf->GetDeclContextDIEContainingDIE(die); + unsigned owning_module = GetOwningModuleID(die); if (decl_ctx_die_copy) *decl_ctx_die_copy = decl_ctx_die; if (decl_ctx_die) { - clang::DeclContext *clang_decl_ctx = - GetClangDeclContextForDIE(decl_ctx_die); + CompilerDeclContext clang_decl_ctx = + GetClangDeclContextForDIE(decl_ctx_die, owning_module); if (clang_decl_ctx) return clang_decl_ctx; } - return m_ast.GetTranslationUnitDecl(); + return m_ast.CreateDeclContext(m_ast.GetTranslationUnitDecl(), owning_module); } -clang::DeclContext * +CompilerDeclContext DWARFASTParserClang::GetCachedClangDeclContextForDIE(const DWARFDIE &die) { if (die) { DIEToDeclContextMap::iterator pos = m_die_to_decl_ctx.find(die.GetDIE()); if (pos != m_die_to_decl_ctx.end()) return pos->second; } - return nullptr; + return {}; } -void DWARFASTParserClang::LinkDeclContextToDIE(clang::DeclContext *decl_ctx, +void DWARFASTParserClang::LinkDeclContextToDIE(CompilerDeclContext decl_ctx, const DWARFDIE &die) { m_die_to_decl_ctx[die.GetDIE()] = decl_ctx; // There can be many DIEs for a single decl context - // m_decl_ctx_to_die[decl_ctx].insert(die.GetDIE()); - m_decl_ctx_to_die.insert(std::make_pair(decl_ctx, die)); + m_decl_ctx_to_die.insert( + std::make_pair(decl_ctx.GetOpaqueDeclContext(), die)); } bool DWARFASTParserClang::CopyUniqueClassMethodTypes( @@ -3650,11 +3702,11 @@ src_die = src_name_to_die.GetValueAtIndexUnchecked(idx); dst_die = dst_name_to_die.GetValueAtIndexUnchecked(idx); - clang::DeclContext *src_decl_ctx = + CompilerDeclContext src_decl_ctx = src_dwarf_ast_parser->m_die_to_decl_ctx[src_die.GetDIE()]; if (src_decl_ctx) { LLDB_LOGF(log, "uniquing decl context %p from 0x%8.8x for 0x%8.8x", - static_cast(src_decl_ctx), src_die.GetOffset(), + src_decl_ctx.GetOpaqueDeclContext(), src_die.GetOffset(), dst_die.GetOffset()); dst_dwarf_ast_parser->LinkDeclContextToDIE(src_decl_ctx, dst_die); } else { @@ -3694,11 +3746,11 @@ src_die = src_name_to_die.Find(dst_name, DWARFDIE()); if (src_die && (src_die.Tag() == dst_die.Tag())) { - clang::DeclContext *src_decl_ctx = + CompilerDeclContext src_decl_ctx = src_dwarf_ast_parser->m_die_to_decl_ctx[src_die.GetDIE()]; if (src_decl_ctx) { LLDB_LOGF(log, "uniquing decl context %p from 0x%8.8x for 0x%8.8x", - static_cast(src_decl_ctx), src_die.GetOffset(), + src_decl_ctx.GetOpaqueDeclContext(), src_die.GetOffset(), dst_die.GetOffset()); dst_dwarf_ast_parser->LinkDeclContextToDIE(src_decl_ctx, dst_die); } else { @@ -3714,7 +3766,7 @@ LLDB_LOGF( log, "uniquing type %p (uid=0x%" PRIx64 ") from 0x%8.8x for 0x%8.8x", - static_cast(src_child_type), src_child_type->GetID(), + src_decl_ctx.GetOpaqueDeclContext(), src_child_type->GetID(), src_die.GetOffset(), dst_die.GetOffset()); dst_die.GetDWARF()->GetDIEToType()[dst_die.GetDIE()] = src_child_type; @@ -3749,11 +3801,11 @@ if (dst_die) { // Both classes have the artificial types, link them - clang::DeclContext *src_decl_ctx = + CompilerDeclContext src_decl_ctx = src_dwarf_ast_parser->m_die_to_decl_ctx[src_die.GetDIE()]; if (src_decl_ctx) { LLDB_LOGF(log, "uniquing decl context %p from 0x%8.8x for 0x%8.8x", - static_cast(src_decl_ctx), src_die.GetOffset(), + src_decl_ctx.GetOpaqueDeclContext(), src_die.GetOffset(), dst_die.GetOffset()); dst_dwarf_ast_parser->LinkDeclContextToDIE(src_decl_ctx, dst_die); } else { @@ -3769,7 +3821,7 @@ LLDB_LOGF( log, "uniquing type %p (uid=0x%" PRIx64 ") from 0x%8.8x for 0x%8.8x", - static_cast(src_child_type), src_child_type->GetID(), + src_decl_ctx.GetOpaqueDeclContext(), src_child_type->GetID(), src_die.GetOffset(), dst_die.GetOffset()); dst_die.GetDWARF()->GetDIEToType()[dst_die.GetDIE()] = src_child_type; } else { Index: lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.cpp =================================================================== --- lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.cpp +++ lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.cpp @@ -777,7 +777,8 @@ metadata.SetIsDynamicCXXType(false); CompilerType ct = m_clang.CreateRecordType( - context, access, uname, ttk, lldb::eLanguageTypeC_plus_plus, &metadata); + m_clang.GetAsCompilerDeclContext(context), access, uname, ttk, + lldb::eLanguageTypeC_plus_plus, &metadata); lldbassert(ct.IsValid()); @@ -804,7 +805,8 @@ PdbAstBuilder::GetOrCreateNamespaceDecl(const char *name, clang::DeclContext &context) { return m_clang.GetUniqueNamespaceDeclaration( - IsAnonymousNamespaceName(name) ? nullptr : name, &context); + IsAnonymousNamespaceName(name) ? nullptr : name, + m_clang.GetAsCompilerDeclContext(&context)); } clang::BlockDecl * @@ -814,7 +816,8 @@ clang::DeclContext *scope = GetParentDeclContext(block_id); - clang::BlockDecl *block_decl = m_clang.CreateBlockDeclaration(scope); + clang::BlockDecl *block_decl = + m_clang.CreateBlockDeclaration(m_clang.GetAsCompilerDeclContext(scope)); m_uid_to_decl.insert({toOpaqueUid(block_id), block_decl}); DeclStatus status; @@ -831,7 +834,8 @@ clang::QualType qt = GetOrCreateType(var_info.type); clang::VarDecl *var_decl = m_clang.CreateVariableDeclaration( - &scope, var_info.name.str().c_str(), qt); + m_clang.GetAsCompilerDeclContext(&scope), var_info.name.str().c_str(), + qt); m_uid_to_decl[toOpaqueUid(uid)] = var_decl; DeclStatus status; @@ -1012,7 +1016,8 @@ proc_name.consume_front("::"); clang::FunctionDecl *function_decl = m_clang.CreateFunctionDeclaration( - parent, proc_name.str().c_str(), func_ct, storage, false); + m_clang.GetAsCompilerDeclContext(parent), proc_name.str().c_str(), + func_ct, storage, false); lldbassert(m_uid_to_decl.count(toOpaqueUid(func_id)) == 0); m_uid_to_decl[toOpaqueUid(func_id)] = function_decl; @@ -1080,8 +1085,8 @@ CompilerType param_type_ct = m_clang.GetType(qt); clang::ParmVarDecl *param = m_clang.CreateParameterDeclaration( - &function_decl, param_name.str().c_str(), param_type_ct, - clang::SC_None, true); + m_clang.GetAsCompilerDeclContext(&function_decl), + param_name.str().c_str(), param_type_ct, clang::SC_None, true); lldbassert(m_uid_to_decl.count(toOpaqueUid(param_uid)) == 0); m_uid_to_decl[toOpaqueUid(param_uid)] = param; @@ -1102,8 +1107,8 @@ Declaration declaration; CompilerType enum_ct = m_clang.CreateEnumerationType( - uname.c_str(), decl_context, declaration, ToCompilerType(underlying_type), - er.isScoped()); + uname.c_str(), m_clang.GetAsCompilerDeclContext(decl_context), + declaration, ToCompilerType(underlying_type), er.isScoped()); TypeSystemClang::StartTagDeclarationDefinition(enum_ct); TypeSystemClang::SetHasExternalStorage(enum_ct.GetOpaqueQualType(), true); @@ -1343,7 +1348,7 @@ CompilerDeclContext PdbAstBuilder::ToCompilerDeclContext(clang::DeclContext &context) { - return m_clang.CreateDeclContext(&context); + return m_clang.GetAsCompilerDeclContext(&context); } clang::Decl * PdbAstBuilder::FromCompilerDecl(CompilerDecl decl) { Index: lldb/source/Plugins/SymbolFile/PDB/PDBASTParser.cpp =================================================================== --- lldb/source/Plugins/SymbolFile/PDB/PDBASTParser.cpp +++ lldb/source/Plugins/SymbolFile/PDB/PDBASTParser.cpp @@ -409,9 +409,9 @@ metadata.SetUserID(type.getSymIndexId()); metadata.SetIsDynamicCXXType(false); - clang_type = - m_ast.CreateRecordType(decl_context, access, name, tag_type_kind, - lldb::eLanguageTypeC_plus_plus, &metadata); + clang_type = m_ast.CreateRecordType( + m_ast.GetAsCompilerDeclContext(decl_context), access, name, + tag_type_kind, lldb::eLanguageTypeC_plus_plus, &metadata); assert(clang_type.IsValid()); auto record_decl = @@ -497,8 +497,9 @@ // Class). Set it false for now. bool isScoped = false; - ast_enum = m_ast.CreateEnumerationType(name.c_str(), decl_context, decl, - builtin_type, isScoped); + ast_enum = m_ast.CreateEnumerationType( + name.c_str(), m_ast.GetAsCompilerDeclContext(decl_context), decl, + builtin_type, isScoped); auto enum_decl = TypeSystemClang::GetAsEnumDecl(ast_enum); assert(enum_decl); @@ -550,7 +551,7 @@ CompilerType target_ast_type = target_type->GetFullCompilerType(); ast_typedef = m_ast.CreateTypedefType( - target_ast_type, name.c_str(), m_ast.CreateDeclContext(decl_ctx)); + target_ast_type, name.c_str(), m_ast.GetAsCompilerDeclContext(decl_ctx)); if (!ast_typedef) return nullptr; @@ -901,7 +902,7 @@ return nullptr; decl = m_ast.CreateVariableDeclaration( - decl_context, name.c_str(), + m_ast.GetAsCompilerDeclContext(decl_context), name.c_str(), ClangUtil::GetQualType(type->GetLayoutCompilerType())); } @@ -927,8 +928,8 @@ : clang::StorageClass::SC_None; auto decl = m_ast.CreateFunctionDeclaration( - decl_context, name.c_str(), type->GetForwardCompilerType(), storage, - func->hasInlineAttribute()); + m_ast.GetAsCompilerDeclContext(decl_context), name.c_str(), + type->GetForwardCompilerType(), storage, func->hasInlineAttribute()); std::vector params; if (std::unique_ptr sig = func->getSignature()) { @@ -941,8 +942,8 @@ continue; clang::ParmVarDecl *param = m_ast.CreateParameterDeclaration( - decl, nullptr, arg_type->GetForwardCompilerType(), - clang::SC_None, true); + m_ast.GetAsCompilerDeclContext(decl), nullptr, + arg_type->GetForwardCompilerType(), clang::SC_None, true); if (param) params.push_back(param); } @@ -1056,8 +1057,9 @@ IsAnonymousNamespaceName(namespace_name) ? nullptr : namespace_name.data(); clang::NamespaceDecl *namespace_decl = - m_ast.GetUniqueNamespaceDeclaration(namespace_name_c_str, - curr_context); + m_ast.GetUniqueNamespaceDeclaration( + namespace_name_c_str, + m_ast.GetAsCompilerDeclContext(curr_context)); m_parent_to_namespaces[curr_context].insert(namespace_decl); m_namespaces.insert(namespace_decl); Index: lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp =================================================================== --- lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp +++ lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp @@ -668,7 +668,7 @@ if (!decl_context) return GetDeclContextContainingUID(uid); - return clang_ast_ctx->CreateDeclContext(decl_context); + return clang_ast_ctx->CreateDeclContext(decl_context, 0); } lldb_private::CompilerDeclContext @@ -697,7 +697,7 @@ auto decl_context = pdb->GetDeclContextContainingSymbol(*symbol); assert(decl_context); - return clang_ast_ctx->CreateDeclContext(decl_context); + return clang_ast_ctx->CreateDeclContext(decl_context, 0); } void SymbolFilePDB::ParseDeclsForContext( @@ -1702,7 +1702,7 @@ if (!namespace_decl) return CompilerDeclContext(); - return clang_type_system->CreateDeclContext(namespace_decl); + return clang_type_system->CreateDeclContext(namespace_decl, 0); } lldb_private::ConstString SymbolFilePDB::GetPluginName() { Index: lldb/source/Plugins/SystemRuntime/MacOSX/SystemRuntimeMacOSX.cpp =================================================================== --- lldb/source/Plugins/SystemRuntime/MacOSX/SystemRuntimeMacOSX.cpp +++ lldb/source/Plugins/SystemRuntime/MacOSX/SystemRuntimeMacOSX.cpp @@ -419,7 +419,7 @@ CompilerType uint16 = ast_ctx->GetBuiltinTypeForEncodingAndBitSize(eEncodingUint, 16); CompilerType dispatch_tsd_indexes_s = ast_ctx->CreateRecordType( - nullptr, lldb::eAccessPublic, "__lldb_dispatch_tsd_indexes_s", + {}, lldb::eAccessPublic, "__lldb_dispatch_tsd_indexes_s", clang::TTK_Struct, lldb::eLanguageTypeC); TypeSystemClang::StartTagDeclarationDefinition(dispatch_tsd_indexes_s); Index: lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.h =================================================================== --- lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.h +++ lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.h @@ -25,6 +25,7 @@ #include "clang/AST/TemplateBase.h" #include "clang/Basic/TargetInfo.h" #include "llvm/ADT/APSInt.h" +#include "llvm/ADT/PointerEmbeddedInt.h" #include "llvm/ADT/SmallVector.h" #include "Plugins/ExpressionParser/Clang/ClangPersistentVariables.h" @@ -40,6 +41,11 @@ class DWARFASTParserClang; class PDBASTParser; +namespace clang { + class HeaderSearch; + class ModuleMap; +} + namespace lldb_private { class ClangASTMetadata; @@ -268,7 +274,12 @@ static uint32_t GetNumBaseClasses(const clang::CXXRecordDecl *cxx_record_decl, bool omit_empty_base_classes); - CompilerType CreateRecordType(clang::DeclContext *decl_ctx, + /// Synthesize a clang::Module and return its ID or 0. + unsigned GetOrCreateClangModule(llvm::StringRef name, unsigned parent, + bool is_framework = false, + bool is_explicit = false); + + CompilerType CreateRecordType(CompilerDeclContext decl_ctx, lldb::AccessType access_type, llvm::StringRef name, int kind, lldb::LanguageType language, @@ -293,7 +304,7 @@ }; clang::FunctionTemplateDecl * - CreateFunctionTemplateDecl(clang::DeclContext *decl_ctx, + CreateFunctionTemplateDecl(CompilerDeclContext decl_ctx, clang::FunctionDecl *func_decl, const char *name, const TemplateParameterInfos &infos); @@ -302,7 +313,7 @@ const TemplateParameterInfos &infos); clang::ClassTemplateDecl * - CreateClassTemplateDecl(clang::DeclContext *decl_ctx, + CreateClassTemplateDecl(CompilerDeclContext decl_ctx, lldb::AccessType access_type, const char *class_name, int kind, const TemplateParameterInfos &infos); @@ -310,7 +321,7 @@ CreateTemplateTemplateParmDecl(const char *template_name); clang::ClassTemplateSpecializationDecl *CreateClassTemplateSpecializationDecl( - clang::DeclContext *decl_ctx, + CompilerDeclContext decl_ctx, clang::ClassTemplateDecl *class_template_decl, int kind, const TemplateParameterInfos &infos); @@ -330,7 +341,7 @@ static bool RecordHasFields(const clang::RecordDecl *record_decl); CompilerType CreateObjCClass(llvm::StringRef name, - clang::DeclContext *decl_ctx, bool isForwardDecl, + CompilerDeclContext decl_ctx, bool isForwardDecl, bool isInternal, ClangASTMetadata *metadata = nullptr); @@ -347,13 +358,13 @@ // Namespace Declarations clang::NamespaceDecl * - GetUniqueNamespaceDeclaration(const char *name, clang::DeclContext *decl_ctx, + GetUniqueNamespaceDeclaration(const char *name, CompilerDeclContext decl_ctx, bool is_inline = false); // Function Types clang::FunctionDecl * - CreateFunctionDeclaration(clang::DeclContext *decl_ctx, const char *name, + CreateFunctionDeclaration(CompilerDeclContext decl_ctx, const char *name, const CompilerType &function_Type, int storage, bool is_inline); @@ -369,7 +380,7 @@ type_quals, clang::CC_C); } - clang::ParmVarDecl *CreateParameterDeclaration(clang::DeclContext *decl_ctx, + clang::ParmVarDecl *CreateParameterDeclaration(CompilerDeclContext decl_ctx, const char *name, const CompilerType ¶m_type, int storage, @@ -387,7 +398,7 @@ // Enumeration Types CompilerType CreateEnumerationType(const char *name, - clang::DeclContext *decl_ctx, + CompilerDeclContext decl_ctx, const Declaration &decl, const CompilerType &integer_qual_type, bool is_scoped); @@ -448,12 +459,6 @@ // CompilerDeclContext override functions - /// Creates a CompilerDeclContext from the given DeclContext - /// with the current TypeSystemClang instance as its typesystem. - /// The DeclContext has to come from the ASTContext of this - /// TypeSystemClang. - CompilerDeclContext CreateDeclContext(clang::DeclContext *ctx); - std::vector DeclContextFindDeclByName(void *opaque_decl_ctx, ConstString name, const bool ignore_using_decls) override; @@ -926,20 +931,20 @@ GetAsObjCInterfaceDecl(const CompilerType &type); clang::ClassTemplateDecl *ParseClassTemplateDecl( - clang::DeclContext *decl_ctx, lldb::AccessType access_type, + CompilerDeclContext decl_ctx, lldb::AccessType access_type, const char *parent_name, int tag_decl_kind, const TypeSystemClang::TemplateParameterInfos &template_param_infos); - clang::BlockDecl *CreateBlockDeclaration(clang::DeclContext *ctx); + clang::BlockDecl *CreateBlockDeclaration(CompilerDeclContext ctx); clang::UsingDirectiveDecl * - CreateUsingDirectiveDeclaration(clang::DeclContext *decl_ctx, + CreateUsingDirectiveDeclaration(CompilerDeclContext decl_ctx, clang::NamespaceDecl *ns_decl); - clang::UsingDecl *CreateUsingDeclaration(clang::DeclContext *current_decl_ctx, + clang::UsingDecl *CreateUsingDeclaration(CompilerDeclContext current_decl_ctx, clang::NamedDecl *target); - clang::VarDecl *CreateVariableDeclaration(clang::DeclContext *decl_context, + clang::VarDecl *CreateVariableDeclaration(CompilerDeclContext decl_context, const char *name, clang::QualType type); @@ -962,6 +967,52 @@ clang::DeclarationName GetDeclarationName(const char *name, const CompilerType &function_clang_type); + // BEGIN SWIFT + clang::LangOptions *GetLangOpts() const { + return m_language_options_up.get(); + } + clang::SourceManager *GetSourceMgr() const { + return m_source_manager_up.get(); + } + // END SWIFT + + /// To save memory in the general case, Clang DeclContexts are tagged + /// pointers that are either a straight (clang::DeclContext *) or + /// an index into m_decl_contexts which holds ModuleDeclContext structs. + struct ModuleDeclContext { + clang::DeclContext *decl_context = nullptr; + unsigned owning_module = 0; + + ModuleDeclContext(clang::DeclContext *dc, unsigned m) + : decl_context(dc), owning_module(m) {} + operator bool() const { return decl_context; } + + using IndexType = + llvm::PointerEmbeddedInt; + using WrappedPointer = llvm::PointerUnion; + }; + + ModuleDeclContext + GetModuleDeclContextFromCompilerDeclContext(CompilerDeclContext ctx); + + /// Extract the clang::DeclContext from a CompilerDeclContext. + clang::DeclContext *GetClangDeclContext(CompilerDeclContext ctx); + + /// Convert into a CompilerDeclContext without attaching module + /// information. This should only be used when we are sure that the + /// module information isn't needed. It's also used in the PDB + /// parser where module info isn't serialized at all. + CompilerDeclContext + GetAsCompilerDeclContext(const clang::DeclContext *decl_context); + + /// Creates a CompilerDeclContext from the given DeclContext + /// with the current TypeSystemClang instance as its typesystem. + /// The DeclContext has to come from the ASTContext of this + /// TypeSystemClang. + CompilerDeclContext CreateDeclContext(clang::DeclContext *decl_context, + unsigned owning_module); + private: const clang::ClassTemplateSpecializationDecl * GetAsTemplateSpecialization(lldb::opaque_compiler_type_t type); @@ -979,6 +1030,8 @@ std::unique_ptr m_identifier_table_up; std::unique_ptr m_selector_table_up; std::unique_ptr m_builtins_up; + std::unique_ptr m_header_search_up; + std::unique_ptr m_module_map_up; std::unique_ptr m_dwarf_ast_parser_up; std::unique_ptr m_pdb_ast_parser_up; std::unique_ptr m_mangle_ctx_up; @@ -989,6 +1042,7 @@ /// Useful for logging and debugging. std::string m_display_name; + std::vector m_decl_contexts; typedef llvm::DenseMap DeclMetadataMap; /// Maps Decls to their associated ClangASTMetadata. DeclMetadataMap m_decl_metadata; Index: lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp =================================================================== --- lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp +++ lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp @@ -34,6 +34,9 @@ #include "clang/Basic/TargetInfo.h" #include "clang/Basic/TargetOptions.h" #include "clang/Frontend/FrontendOptions.h" +#include "clang/Lex/HeaderSearch.h" +#include "clang/Lex/HeaderSearchOptions.h" +#include "clang/Lex/ModuleMap.h" #include "clang/Sema/Sema.h" #include "llvm/Support/Signals.h" @@ -1157,12 +1160,6 @@ return CompilerType(); } -CompilerDeclContext TypeSystemClang::CreateDeclContext(DeclContext *ctx) { - // Check that the DeclContext actually belongs to this ASTContext. - assert(&ctx->getParentASTContext() == &getASTContext()); - return CompilerDeclContext(this, ctx); -} - CompilerType TypeSystemClang::GetTypeForDecl(clang::NamedDecl *decl) { if (clang::ObjCInterfaceDecl *interface_decl = llvm::dyn_cast(decl)) @@ -1182,7 +1179,52 @@ #pragma mark Structure, Unions, Classes -CompilerType TypeSystemClang::CreateRecordType(DeclContext *decl_ctx, +unsigned TypeSystemClang::GetOrCreateClangModule(llvm::StringRef name, + unsigned parent, + bool is_framework, + bool is_explicit) { + // Get the external AST source which holds the modules. + auto *ast_source = llvm::dyn_cast_or_null( + getASTContext().getExternalSource()); + assert(ast_source && "external ast source was lost"); + if (!ast_source) + return 0; + + // Initialize the module map. + if (!m_header_search_up) { + auto HSOpts = std::make_shared(); + m_header_search_up = std::make_unique( + HSOpts, *m_source_manager_up, *m_diagnostics_engine_up, + *m_language_options_up, m_target_info_up.get()); + m_module_map_up = std::make_unique( + *m_source_manager_up, *m_diagnostics_engine_up, *m_language_options_up, + m_target_info_up.get(), *m_header_search_up); + } + + // Get or create the module context. + bool created; + clang::Module *module; + auto parent_desc = ast_source->getSourceDescriptor(parent); + std::tie(module, created) = m_module_map_up->findOrCreateModule( + name, parent_desc ? parent_desc->getModuleOrNull() : nullptr, + is_framework, is_explicit); + if (!created) + return ast_source->getIDForModule(module); + + module->Name = name.str(); + return ast_source->registerModule(module); +} + +static void SetOwningModule(clang::Decl *decl, + TypeSystemClang::ModuleDeclContext decl_ctx) { + if (decl && decl_ctx.owning_module) { + decl->setFromASTFile(); + decl->setOwningModuleID(decl_ctx.owning_module); + decl->setModuleOwnershipKind(clang::Decl::ModuleOwnershipKind::Visible); + } +} + +CompilerType TypeSystemClang::CreateRecordType(CompilerDeclContext decl_ctx, AccessType access_type, llvm::StringRef name, int kind, LanguageType language, @@ -1190,8 +1232,8 @@ bool exports_symbols) { ASTContext &ast = getASTContext(); - if (decl_ctx == nullptr) - decl_ctx = ast.getTranslationUnitDecl(); + if (!decl_ctx) + decl_ctx = GetAsCompilerDeclContext(ast.getTranslationUnitDecl()); if (language == eLanguageTypeObjC || language == eLanguageTypeObjC_plus_plus) { @@ -1207,10 +1249,11 @@ // complete definition just in case. bool has_name = !name.empty(); - + auto mod_ctx = GetModuleDeclContextFromCompilerDeclContext(decl_ctx); CXXRecordDecl *decl = CXXRecordDecl::Create( - ast, (TagDecl::TagKind)kind, decl_ctx, SourceLocation(), SourceLocation(), - has_name ? &ast.Idents.get(name) : nullptr); + ast, (TagDecl::TagKind)kind, mod_ctx.decl_context, SourceLocation(), + SourceLocation(), has_name ? &ast.Idents.get(name) : nullptr); + SetOwningModule(decl, mod_ctx); if (!has_name) { // In C++ a lambda is also represented as an unnamed class. This is @@ -1237,7 +1280,7 @@ // Anonymous classes is a GNU/MSVC extension that clang supports. It // requires the anonymous class be embedded within a class. So the new // heuristic verifies this condition. - if (isa(decl_ctx) && exports_symbols) + if (isa(mod_ctx.decl_context) && exports_symbols) decl->setAnonymousStructOrUnion(true); } @@ -1249,7 +1292,7 @@ decl->setAccess(ConvertAccessTypeToAccessSpecifier(access_type)); if (decl_ctx) - decl_ctx->addDecl(decl); + mod_ctx.decl_context->addDecl(decl); return GetType(ast.getTagDeclType(decl)); } @@ -1322,18 +1365,19 @@ } clang::FunctionTemplateDecl *TypeSystemClang::CreateFunctionTemplateDecl( - clang::DeclContext *decl_ctx, clang::FunctionDecl *func_decl, + CompilerDeclContext decl_ctx, clang::FunctionDecl *func_decl, const char *name, const TemplateParameterInfos &template_param_infos) { // /// Create a function template node. ASTContext &ast = getASTContext(); llvm::SmallVector template_param_decls; - + auto mod_ctx = GetModuleDeclContextFromCompilerDeclContext(decl_ctx); TemplateParameterList *template_param_list = CreateTemplateParameterList( ast, template_param_infos, template_param_decls); FunctionTemplateDecl *func_tmpl_decl = FunctionTemplateDecl::Create( - ast, decl_ctx, func_decl->getLocation(), func_decl->getDeclName(), - template_param_list, func_decl); + ast, mod_ctx.decl_context, func_decl->getLocation(), + func_decl->getDeclName(), template_param_list, func_decl); + SetOwningModule(func_tmpl_decl, mod_ctx); for (size_t i = 0, template_param_decl_count = template_param_decls.size(); i < template_param_decl_count; ++i) { @@ -1343,7 +1387,7 @@ // Function templates inside a record need to have an access specifier. // It doesn't matter what access specifier we give the template as LLDB // anyway allows accessing everything inside a record. - if (decl_ctx->isRecord()) + if (GetClangDeclContext(decl_ctx)->isRecord()) func_tmpl_decl->setAccess(clang::AccessSpecifier::AS_public); return func_tmpl_decl; @@ -1360,18 +1404,19 @@ } ClassTemplateDecl *TypeSystemClang::CreateClassTemplateDecl( - DeclContext *decl_ctx, lldb::AccessType access_type, const char *class_name, + CompilerDeclContext decl_ctx, lldb::AccessType access_type, const char *class_name, int kind, const TemplateParameterInfos &template_param_infos) { ASTContext &ast = getASTContext(); ClassTemplateDecl *class_template_decl = nullptr; - if (decl_ctx == nullptr) - decl_ctx = ast.getTranslationUnitDecl(); + if (!decl_ctx) + decl_ctx = CreateDeclContext(ast.getTranslationUnitDecl(), 0); IdentifierInfo &identifier_info = ast.Idents.get(class_name); DeclarationName decl_name(&identifier_info); - clang::DeclContext::lookup_result result = decl_ctx->lookup(decl_name); + clang::DeclContext::lookup_result result = + GetClangDeclContext(decl_ctx)->lookup(decl_name); for (NamedDecl *decl : result) { class_template_decl = dyn_cast(decl); @@ -1384,11 +1429,13 @@ TemplateParameterList *template_param_list = CreateTemplateParameterList( ast, template_param_infos, template_param_decls); + auto mod_ctx = GetModuleDeclContextFromCompilerDeclContext(decl_ctx); CXXRecordDecl *template_cxx_decl = CXXRecordDecl::Create( ast, (TagDecl::TagKind)kind, - decl_ctx, // What decl context do we use here? TU? The actual decl - // context? + mod_ctx.decl_context, // What decl context do we use here? TU? The actual + // decl context? SourceLocation(), SourceLocation(), &identifier_info); + SetOwningModule(template_cxx_decl, mod_ctx); for (size_t i = 0, template_param_decl_count = template_param_decls.size(); i < template_param_decl_count; ++i) { @@ -1402,10 +1449,11 @@ class_template_decl = ClassTemplateDecl::Create( ast, - decl_ctx, // What decl context do we use here? TU? The actual decl - // context? + mod_ctx.decl_context, // What decl context do we use here? TU? The actual + // decl context? SourceLocation(), decl_name, template_param_list, template_cxx_decl); template_cxx_decl->setDescribedClassTemplate(class_template_decl); + SetOwningModule(class_template_decl, mod_ctx); if (class_template_decl) { if (access_type != eAccessNone) @@ -1415,7 +1463,7 @@ // if (TagDecl *ctx_tag_decl = dyn_cast(decl_ctx)) // CompleteTagDeclarationDefinition(GetTypeForDecl(ctx_tag_decl)); - decl_ctx->addDecl(class_template_decl); + mod_ctx.decl_context->addDecl(class_template_decl); VerifyDecl(class_template_decl); } @@ -1448,8 +1496,8 @@ ClassTemplateSpecializationDecl * TypeSystemClang::CreateClassTemplateSpecializationDecl( - DeclContext *decl_ctx, ClassTemplateDecl *class_template_decl, int kind, - const TemplateParameterInfos &template_param_infos) { + CompilerDeclContext decl_ctx, ClassTemplateDecl *class_template_decl, + int kind, const TemplateParameterInfos &template_param_infos) { ASTContext &ast = getASTContext(); llvm::SmallVector args( template_param_infos.args.size() + @@ -1460,10 +1508,12 @@ args[args.size() - 1] = TemplateArgument::CreatePackCopy( ast, template_param_infos.packed_args->args); } + auto mod_ctx = GetModuleDeclContextFromCompilerDeclContext(decl_ctx); ClassTemplateSpecializationDecl *class_template_specialization_decl = ClassTemplateSpecializationDecl::Create( - ast, (TagDecl::TagKind)kind, decl_ctx, SourceLocation(), + ast, (TagDecl::TagKind)kind, mod_ctx.decl_context, SourceLocation(), SourceLocation(), class_template_decl, args, nullptr); + SetOwningModule(class_template_decl, mod_ctx); class_template_specialization_decl->setSpecializationKind( TSK_ExplicitSpecialization); @@ -1583,20 +1633,22 @@ #pragma mark Objective-C Classes CompilerType TypeSystemClang::CreateObjCClass(llvm::StringRef name, - DeclContext *decl_ctx, + CompilerDeclContext decl_ctx, bool isForwardDecl, bool isInternal, ClangASTMetadata *metadata) { ASTContext &ast = getASTContext(); assert(!name.empty()); - if (decl_ctx == nullptr) - decl_ctx = ast.getTranslationUnitDecl(); + if (!decl_ctx) + decl_ctx = CreateDeclContext(ast.getTranslationUnitDecl(), 0); + auto mod_ctx = GetModuleDeclContextFromCompilerDeclContext(decl_ctx); ObjCInterfaceDecl *decl = ObjCInterfaceDecl::Create( - ast, decl_ctx, SourceLocation(), &ast.Idents.get(name), nullptr, nullptr, + ast, mod_ctx.decl_context, SourceLocation(), &ast.Idents.get(name), nullptr, nullptr, SourceLocation(), /*isForwardDecl,*/ isInternal); + SetOwningModule(decl, mod_ctx); if (decl && metadata) SetMetadata(decl, *metadata); @@ -1634,17 +1686,20 @@ #pragma mark Namespace Declarations NamespaceDecl *TypeSystemClang::GetUniqueNamespaceDeclaration( - const char *name, DeclContext *decl_ctx, bool is_inline) { + const char *name, CompilerDeclContext decl_ctx, bool is_inline) { NamespaceDecl *namespace_decl = nullptr; ASTContext &ast = getASTContext(); TranslationUnitDecl *translation_unit_decl = ast.getTranslationUnitDecl(); - if (decl_ctx == nullptr) - decl_ctx = translation_unit_decl; + if (!decl_ctx) + decl_ctx = CreateDeclContext(translation_unit_decl, 0); + + auto mod_ctx = GetModuleDeclContextFromCompilerDeclContext(decl_ctx); if (name) { IdentifierInfo &identifier_info = ast.Idents.get(name); DeclarationName decl_name(&identifier_info); - clang::DeclContext::lookup_result result = decl_ctx->lookup(decl_name); + clang::DeclContext::lookup_result result = + GetClangDeclContext(decl_ctx)->lookup(decl_name); for (NamedDecl *decl : result) { namespace_decl = dyn_cast(decl); if (namespace_decl) @@ -1652,30 +1707,31 @@ } namespace_decl = - NamespaceDecl::Create(ast, decl_ctx, is_inline, SourceLocation(), + NamespaceDecl::Create(ast, mod_ctx.decl_context, is_inline, SourceLocation(), SourceLocation(), &identifier_info, nullptr); - decl_ctx->addDecl(namespace_decl); + mod_ctx.decl_context->addDecl(namespace_decl); } else { - if (decl_ctx == translation_unit_decl) { + if (GetClangDeclContext(decl_ctx) == translation_unit_decl) { namespace_decl = translation_unit_decl->getAnonymousNamespace(); if (namespace_decl) return namespace_decl; namespace_decl = - NamespaceDecl::Create(ast, decl_ctx, false, SourceLocation(), + NamespaceDecl::Create(ast, mod_ctx.decl_context, false, SourceLocation(), SourceLocation(), nullptr, nullptr); translation_unit_decl->setAnonymousNamespace(namespace_decl); translation_unit_decl->addDecl(namespace_decl); assert(namespace_decl == translation_unit_decl->getAnonymousNamespace()); } else { - NamespaceDecl *parent_namespace_decl = cast(decl_ctx); + NamespaceDecl *parent_namespace_decl = + cast(GetClangDeclContext(decl_ctx)); if (parent_namespace_decl) { namespace_decl = parent_namespace_decl->getAnonymousNamespace(); if (namespace_decl) return namespace_decl; namespace_decl = - NamespaceDecl::Create(ast, decl_ctx, false, SourceLocation(), + NamespaceDecl::Create(ast, mod_ctx.decl_context, false, SourceLocation(), SourceLocation(), nullptr, nullptr); parent_namespace_decl->setAnonymousNamespace(namespace_decl); parent_namespace_decl->addDecl(namespace_decl); @@ -1687,16 +1743,21 @@ } } } + // Note: namespaces can span multiple modules, so perhaps this isn't a good idea. + SetOwningModule(namespace_decl, mod_ctx); + VerifyDecl(namespace_decl); return namespace_decl; } clang::BlockDecl * -TypeSystemClang::CreateBlockDeclaration(clang::DeclContext *ctx) { - if (ctx != nullptr) { - clang::BlockDecl *decl = - clang::BlockDecl::Create(getASTContext(), ctx, clang::SourceLocation()); - ctx->addDecl(decl); +TypeSystemClang::CreateBlockDeclaration(CompilerDeclContext ctx) { + if (ctx) { + auto mod_ctx = GetModuleDeclContextFromCompilerDeclContext(ctx); + clang::BlockDecl *decl = clang::BlockDecl::Create( + getASTContext(), mod_ctx.decl_context, clang::SourceLocation()); + GetClangDeclContext(ctx)->addDecl(decl); + SetOwningModule(decl, mod_ctx); return decl; } return nullptr; @@ -1720,47 +1781,61 @@ } clang::UsingDirectiveDecl *TypeSystemClang::CreateUsingDirectiveDeclaration( - clang::DeclContext *decl_ctx, clang::NamespaceDecl *ns_decl) { - if (decl_ctx != nullptr && ns_decl != nullptr) { + CompilerDeclContext decl_ctx, clang::NamespaceDecl *ns_decl) { + if (decl_ctx && ns_decl) { auto *translation_unit = getASTContext().getTranslationUnitDecl(); - clang::UsingDirectiveDecl *using_decl = clang::UsingDirectiveDecl::Create( - getASTContext(), decl_ctx, clang::SourceLocation(), - clang::SourceLocation(), clang::NestedNameSpecifierLoc(), - clang::SourceLocation(), ns_decl, - FindLCABetweenDecls(decl_ctx, ns_decl, translation_unit)); - decl_ctx->addDecl(using_decl); - return using_decl; + auto mod_ctx = GetModuleDeclContextFromCompilerDeclContext(decl_ctx); + clang::UsingDirectiveDecl *using_decl = clang::UsingDirectiveDecl::Create( + getASTContext(), mod_ctx.decl_context, clang::SourceLocation(), + clang::SourceLocation(), clang::NestedNameSpecifierLoc(), + clang::SourceLocation(), ns_decl, + FindLCABetweenDecls(GetClangDeclContext(decl_ctx), ns_decl, + translation_unit)); + mod_ctx.decl_context->addDecl(using_decl); + SetOwningModule(using_decl, mod_ctx); + + return using_decl; } return nullptr; } clang::UsingDecl * -TypeSystemClang::CreateUsingDeclaration(clang::DeclContext *current_decl_ctx, +TypeSystemClang::CreateUsingDeclaration(CompilerDeclContext current_decl_ctx, clang::NamedDecl *target) { - if (current_decl_ctx != nullptr && target != nullptr) { + if (current_decl_ctx && target) { + auto mod_ctx = + GetModuleDeclContextFromCompilerDeclContext(current_decl_ctx); clang::UsingDecl *using_decl = clang::UsingDecl::Create( - getASTContext(), current_decl_ctx, clang::SourceLocation(), + getASTContext(), mod_ctx.decl_context, clang::SourceLocation(), clang::NestedNameSpecifierLoc(), clang::DeclarationNameInfo(), false); clang::UsingShadowDecl *shadow_decl = clang::UsingShadowDecl::Create( - getASTContext(), current_decl_ctx, clang::SourceLocation(), using_decl, + getASTContext(), mod_ctx.decl_context, clang::SourceLocation(), using_decl, target); + SetOwningModule(using_decl, mod_ctx); + SetOwningModule(shadow_decl, mod_ctx); using_decl->addShadowDecl(shadow_decl); - current_decl_ctx->addDecl(using_decl); + GetClangDeclContext(current_decl_ctx)->addDecl(using_decl); return using_decl; } return nullptr; } clang::VarDecl *TypeSystemClang::CreateVariableDeclaration( - clang::DeclContext *decl_context, const char *name, clang::QualType type) { - if (decl_context != nullptr) { + CompilerDeclContext decl_context, const char *name, clang::QualType type) { + if (decl_context) { + auto mod_ctx = GetModuleDeclContextFromCompilerDeclContext(decl_context); clang::VarDecl *var_decl = clang::VarDecl::Create( - getASTContext(), decl_context, clang::SourceLocation(), + getASTContext(), mod_ctx.decl_context, clang::SourceLocation(), clang::SourceLocation(), name && name[0] ? &getASTContext().Idents.getOwn(name) : nullptr, type, nullptr, clang::SC_None); + if (mod_ctx.owning_module) { + var_decl->setFromASTFile(); + var_decl->setOwningModuleID(mod_ctx.owning_module); + } + var_decl->setAccess(clang::AS_public); - decl_context->addDecl(var_decl); + GetClangDeclContext(decl_context)->addDecl(var_decl); return var_decl; } return nullptr; @@ -1870,25 +1945,28 @@ } FunctionDecl *TypeSystemClang::CreateFunctionDeclaration( - DeclContext *decl_ctx, const char *name, + CompilerDeclContext decl_ctx, const char *name, const CompilerType &function_clang_type, int storage, bool is_inline) { FunctionDecl *func_decl = nullptr; ASTContext &ast = getASTContext(); - if (decl_ctx == nullptr) - decl_ctx = ast.getTranslationUnitDecl(); + if (!decl_ctx) + decl_ctx = CreateDeclContext(ast.getTranslationUnitDecl(), 0); const bool hasWrittenPrototype = true; const bool isConstexprSpecified = false; clang::DeclarationName declarationName = GetDeclarationName(name, function_clang_type); + auto mod_ctx = GetModuleDeclContextFromCompilerDeclContext(decl_ctx); func_decl = FunctionDecl::Create( - ast, decl_ctx, SourceLocation(), SourceLocation(), declarationName, + ast, mod_ctx.decl_context, SourceLocation(), SourceLocation(), declarationName, ClangUtil::GetQualType(function_clang_type), nullptr, (clang::StorageClass)storage, is_inline, hasWrittenPrototype, isConstexprSpecified ? CSK_constexpr : CSK_unspecified); - if (func_decl) - decl_ctx->addDecl(func_decl); + if (func_decl) { + mod_ctx.decl_context->addDecl(func_decl); + SetOwningModule(func_decl, mod_ctx); + } VerifyDecl(func_decl); @@ -1935,16 +2013,19 @@ } ParmVarDecl *TypeSystemClang::CreateParameterDeclaration( - clang::DeclContext *decl_ctx, const char *name, + CompilerDeclContext decl_ctx, const char *name, const CompilerType ¶m_type, int storage, bool add_decl) { ASTContext &ast = getASTContext(); + auto mod_ctx = GetModuleDeclContextFromCompilerDeclContext(decl_ctx); auto *decl = - ParmVarDecl::Create(ast, decl_ctx, SourceLocation(), SourceLocation(), + ParmVarDecl::Create(ast, mod_ctx.decl_context, SourceLocation(), SourceLocation(), name && name[0] ? &ast.Idents.get(name) : nullptr, ClangUtil::GetQualType(param_type), nullptr, (clang::StorageClass)storage, nullptr); + SetOwningModule(decl, mod_ctx); + if (add_decl) - decl_ctx->addDecl(decl); + mod_ctx.decl_context->addDecl(decl); return decl; } @@ -2004,7 +2085,7 @@ return type; } - type = CreateRecordType(nullptr, lldb::eAccessPublic, type_name.GetCString(), + type = CreateRecordType({}, lldb::eAccessPublic, type_name.GetCString(), clang::TTK_Struct, lldb::eLanguageTypeC); StartTagDeclarationDefinition(type); for (const auto &field : type_fields) @@ -2030,28 +2111,27 @@ #pragma mark Enumeration Types -CompilerType -TypeSystemClang::CreateEnumerationType(const char *name, DeclContext *decl_ctx, - const Declaration &decl, - const CompilerType &integer_clang_type, - bool is_scoped) { +CompilerType TypeSystemClang::CreateEnumerationType( + const char *name, CompilerDeclContext decl_ctx, const Declaration &decl, + const CompilerType &integer_clang_type, bool is_scoped) { // TODO: Do something intelligent with the Declaration object passed in // like maybe filling in the SourceLocation with it... ASTContext &ast = getASTContext(); // TODO: ask about these... // const bool IsFixed = false; - + auto mod_ctx = GetModuleDeclContextFromCompilerDeclContext(decl_ctx); EnumDecl *enum_decl = EnumDecl::Create( - ast, decl_ctx, SourceLocation(), SourceLocation(), + ast, mod_ctx.decl_context, SourceLocation(), SourceLocation(), name && name[0] ? &ast.Idents.get(name) : nullptr, nullptr, is_scoped, // IsScoped is_scoped, // IsScopedUsingClassTag false); // IsFixed if (enum_decl) { + SetOwningModule(enum_decl, mod_ctx); if (decl_ctx) - decl_ctx->addDecl(enum_decl); + mod_ctx.decl_context->addDecl(enum_decl); // TODO: check if we should be setting the promotion type too? enum_decl->setIntegerType(ClangUtil::GetQualType(integer_clang_type)); @@ -4238,19 +4318,20 @@ clang::ASTContext &clang_ast = ast->getASTContext(); clang::QualType qual_type(ClangUtil::GetQualType(type)); - clang::DeclContext *decl_ctx = - TypeSystemClang::DeclContextGetAsDeclContext(compiler_decl_ctx); - if (decl_ctx == nullptr) - decl_ctx = ast->getASTContext().getTranslationUnitDecl(); + auto mod_ctx = + ast->GetModuleDeclContextFromCompilerDeclContext(compiler_decl_ctx); + if (!mod_ctx) + mod_ctx = {ast->getASTContext().getTranslationUnitDecl(), 0}; clang::TypedefDecl *decl = clang::TypedefDecl::Create( - clang_ast, decl_ctx, clang::SourceLocation(), clang::SourceLocation(), - &clang_ast.Idents.get(typedef_name), + clang_ast, mod_ctx.decl_context, clang::SourceLocation(), + clang::SourceLocation(), &clang_ast.Idents.get(typedef_name), clang_ast.getTrivialTypeSourceInfo(qual_type)); + SetOwningModule(decl, mod_ctx); decl->setAccess(clang::AS_public); // TODO respect proper access specifier - decl_ctx->addDecl(decl); + ast->GetClangDeclContext(compiler_decl_ctx)->addDecl(decl); // Get a uniqued clang::QualType for the typedef decl type return ast->GetType(clang_ast.getTypedefType(decl)); @@ -4344,22 +4425,26 @@ clang::ASTContext &clang_ast = getASTContext(); clang::QualType qual_type(GetQualType(type)); - clang::DeclContext *decl_ctx = TypeSystemClang::DeclContextGetAsDeclContext(compiler_decl_ctx); - if (decl_ctx == nullptr) - decl_ctx = getASTContext().getTranslationUnitDecl(); - - clang::TypedefDecl *decl = clang::TypedefDecl::Create( - clang_ast, decl_ctx, clang::SourceLocation(), clang::SourceLocation(), - &clang_ast.Idents.get(typedef_name), - clang_ast.getTrivialTypeSourceInfo(qual_type)); - - clang::TagDecl *tdecl = nullptr; - if (!qual_type.isNull()) { - if (const clang::RecordType *rt = qual_type->getAs()) - tdecl = rt->getDecl(); - if (const clang::EnumType *et = qual_type->getAs()) - tdecl = et->getDecl(); + auto mod_ctx = + GetModuleDeclContextFromCompilerDeclContext(compiler_decl_ctx); + clang::DeclContext *decl_ctx = mod_ctx.decl_context; + if (!decl_ctx) + decl_ctx = getASTContext().getTranslationUnitDecl(); + + clang::TypedefDecl *decl = clang::TypedefDecl::Create( + clang_ast, decl_ctx, clang::SourceLocation(), + clang::SourceLocation(), &clang_ast.Idents.get(typedef_name), + clang_ast.getTrivialTypeSourceInfo(qual_type)); + SetOwningModule(decl, mod_ctx); + + clang::TagDecl *tdecl = nullptr; + if (!qual_type.isNull()) { + if (const clang::RecordType *rt = + qual_type->getAs()) + tdecl = rt->getDecl(); + if (const clang::EnumType *et = qual_type->getAs()) + tdecl = et->getDecl(); } // Check whether this declaration is an anonymous struct, union, or enum, @@ -6875,6 +6960,15 @@ return nullptr; } +static void SetMemberOwningModule(clang::Decl *member, + const clang::Decl *parent) { + if (member && parent) + if (unsigned id = parent->getOwningModuleID()) { + member->setFromASTFile(); + member->setOwningModuleID(id); + } +} + clang::FieldDecl *TypeSystemClang::AddFieldToRecordType( const CompilerType &type, llvm::StringRef name, const CompilerType &field_clang_type, AccessType access, @@ -6912,6 +7006,7 @@ bit_width, // BitWidth false, // Mutable clang::ICIS_NoInit); // HasInit + SetMemberOwningModule(field, record_decl); if (name.empty()) { // Determine whether this field corresponds to an anonymous struct or @@ -6952,6 +7047,7 @@ nullptr, // TypeSourceInfo * ConvertAccessTypeToObjCIvarAccessControl(access), bit_width, is_synthesized); + SetMemberOwningModule(field, class_interface_decl); if (field) { class_interface_decl->addDecl(field); @@ -7013,6 +7109,7 @@ ast->getASTContext(), record_decl, clang::SourceLocation(), nested_field_decl->getIdentifier(), nested_field_decl->getType(), {chain, 2}); + SetMemberOwningModule(indirect_field, record_decl); indirect_field->setImplicit(); @@ -7043,7 +7140,8 @@ nested_indirect_field_decl->getIdentifier(), nested_indirect_field_decl->getType(), {chain, nested_chain_size + 1}); - + SetMemberOwningModule(indirect_field, record_decl); + indirect_field->setImplicit(); indirect_field->setAccess(TypeSystemClang::UnifyAccessSpecifiers( @@ -7113,6 +7211,7 @@ ClangUtil::GetQualType(var_type), // Variable clang::QualType nullptr, // TypeSourceInfo * clang::SC_Static); // StorageClass + SetMemberOwningModule(var_decl, record_decl); if (!var_decl) return nullptr; @@ -7238,6 +7337,7 @@ SC, is_inline, CSK_unspecified, clang::SourceLocation()); } } + SetMemberOwningModule(cxx_method_decl, cxx_record_decl); clang::AccessSpecifier access_specifier = TypeSystemClang::ConvertAccessTypeToAccessSpecifier(access); @@ -7413,6 +7513,7 @@ ivar_decl ? ivar_decl->getType() : ClangUtil::GetQualType(property_clang_type), prop_type_source); + SetMemberOwningModule(property_decl, class_interface_decl); if (!property_decl) return false; @@ -7498,6 +7599,7 @@ class_interface_decl, isInstance, isVariadic, isPropertyAccessor, isSynthesizedAccessorStub, isImplicitlyDeclared, isDefined, impControl, HasRelatedResultType); + SetMemberOwningModule(getter, class_interface_decl); if (getter) { if (metadata) @@ -7532,6 +7634,7 @@ result_type, nullptr, class_interface_decl, isInstance, isVariadic, isPropertyAccessor, isSynthesizedAccessorStub, isImplicitlyDeclared, isDefined, impControl, HasRelatedResultType); + SetMemberOwningModule(setter, class_interface_decl); if (setter) { if (metadata) @@ -7657,6 +7760,7 @@ lldb_ast->GetDeclContextForType(ClangUtil::GetQualType(type)), isInstance, isVariadic, isPropertyAccessor, isSynthesizedAccessorStub, isImplicitlyDeclared, isDefined, impControl, HasRelatedResultType); + SetMemberOwningModule(objc_method_decl, class_interface_decl); if (objc_method_decl == nullptr) return nullptr; @@ -7884,6 +7988,7 @@ getASTContext(), enutype->getDecl(), clang::SourceLocation(), name ? &getASTContext().Idents.get(name) : nullptr, // Identifier clang::QualType(enutype, 0), nullptr, value); + SetMemberOwningModule(enumerator_decl, enutype->getDecl()); if (!enumerator_decl) return nullptr; @@ -8778,7 +8883,7 @@ } clang::ClassTemplateDecl *TypeSystemClang::ParseClassTemplateDecl( - clang::DeclContext *decl_ctx, lldb::AccessType access_type, + CompilerDeclContext decl_ctx, lldb::AccessType access_type, const char *parent_name, int tag_decl_kind, const TypeSystemClang::TemplateParameterInfos &template_param_infos) { if (template_param_infos.IsValid()) { @@ -8882,8 +8987,9 @@ } CompilerDeclContext TypeSystemClang::DeclGetDeclContext(void *opaque_decl) { + // FIXME: This drops the module information. if (opaque_decl) - return CreateDeclContext(((clang::Decl *)opaque_decl)->getDeclContext()); + return GetAsCompilerDeclContext(((clang::Decl *)opaque_decl)->getDeclContext()); return CompilerDeclContext(); } @@ -8947,8 +9053,7 @@ it++) { if (!searched.insert(it->second).second) continue; - symbol_file->ParseDeclsForContext( - CreateDeclContext(it->second)); + symbol_file->ParseDeclsForContext(GetAsCompilerDeclContext(it->second)); for (clang::Decl *child : it->second->decls()) { if (clang::UsingDirectiveDecl *ud = @@ -9062,8 +9167,7 @@ continue; searched.insert(it->second); - symbol_file->ParseDeclsForContext( - CreateDeclContext(it->second)); + symbol_file->ParseDeclsForContext(GetAsCompilerDeclContext(it->second)); for (clang::Decl *child : it->second->decls()) { if (clang::UsingDirectiveDecl *ud = @@ -9194,40 +9298,33 @@ clang::DeclContext * TypeSystemClang::DeclContextGetAsDeclContext(const CompilerDeclContext &dc) { if (IsClangDeclContext(dc)) - return (clang::DeclContext *)dc.GetOpaqueDeclContext(); + return llvm::cast(dc.GetTypeSystem()) + ->GetClangDeclContext(dc); return nullptr; } ObjCMethodDecl * TypeSystemClang::DeclContextGetAsObjCMethodDecl(const CompilerDeclContext &dc) { - if (IsClangDeclContext(dc)) - return llvm::dyn_cast( - (clang::DeclContext *)dc.GetOpaqueDeclContext()); - return nullptr; + return llvm::dyn_cast_or_null( + DeclContextGetAsDeclContext(dc)); } CXXMethodDecl * TypeSystemClang::DeclContextGetAsCXXMethodDecl(const CompilerDeclContext &dc) { - if (IsClangDeclContext(dc)) - return llvm::dyn_cast( - (clang::DeclContext *)dc.GetOpaqueDeclContext()); - return nullptr; + return llvm::dyn_cast_or_null( + DeclContextGetAsDeclContext(dc)); } clang::FunctionDecl * TypeSystemClang::DeclContextGetAsFunctionDecl(const CompilerDeclContext &dc) { - if (IsClangDeclContext(dc)) - return llvm::dyn_cast( - (clang::DeclContext *)dc.GetOpaqueDeclContext()); - return nullptr; + return llvm::dyn_cast_or_null( + DeclContextGetAsDeclContext(dc)); } clang::NamespaceDecl * TypeSystemClang::DeclContextGetAsNamespaceDecl(const CompilerDeclContext &dc) { - if (IsClangDeclContext(dc)) - return llvm::dyn_cast( - (clang::DeclContext *)dc.GetOpaqueDeclContext()); - return nullptr; + return llvm::dyn_cast_or_null( + DeclContextGetAsDeclContext(dc)); } ClangASTMetadata * @@ -9246,6 +9343,52 @@ return nullptr; } +TypeSystemClang::ModuleDeclContext +TypeSystemClang::GetModuleDeclContextFromCompilerDeclContext( + CompilerDeclContext ctx) { + auto ptr = ModuleDeclContext::WrappedPointer::getFromOpaqueValue( + ctx.GetOpaqueDeclContext()); + if (ptr.is()) { + auto *ctx = ptr.get(); + assert(!ctx || (&ctx->getParentASTContext() == &getASTContext())); + return {ctx, 0}; + } + + size_t idx = ptr.get(); + assert(idx > 0); + return m_decl_contexts[idx - 1]; +} + +clang::DeclContext * +TypeSystemClang::GetClangDeclContext(CompilerDeclContext ctx) { + return GetModuleDeclContextFromCompilerDeclContext(ctx).decl_context; +} + +CompilerDeclContext TypeSystemClang::GetAsCompilerDeclContext( + const clang::DeclContext *decl_context) { + assert(&decl_context->getParentASTContext() == &getASTContext() && + "decl context belongs to different typesystem"); + ModuleDeclContext::WrappedPointer ptr = + const_cast(decl_context); + return {this, ptr.getOpaqueValue()}; +} + +CompilerDeclContext +TypeSystemClang::CreateDeclContext(clang::DeclContext *decl_context, + unsigned owning_module) { + // Check that the DeclContext actually belongs to this ASTContext. + assert(&decl_context->getParentASTContext() == &getASTContext()); + ModuleDeclContext::WrappedPointer ptr; + if (!owning_module) { + ptr = decl_context; + assert(ptr.is()); + } else { + m_decl_contexts.emplace_back(decl_context, owning_module); + ptr = ModuleDeclContext::IndexType(m_decl_contexts.size()); + } + return {this, ptr.getOpaqueValue()}; +} + TypeSystemClangForExpressions::TypeSystemClangForExpressions( Target &target, llvm::Triple triple) : TypeSystemClang("scratch ASTContext", triple), Index: lldb/test/Shell/SymbolFile/DWARF/owning-module.test =================================================================== --- /dev/null +++ lldb/test/Shell/SymbolFile/DWARF/owning-module.test @@ -0,0 +1,6 @@ +// RUN: llc %S/compilercontext.ll -filetype=obj -o %t.o +// RUN: %clang_host -g -c -o %t.o %s +// RUN: lldb-test symbols -dump-clang-ast %t.o | FileCheck %s +// Verify that the owning module information from DWARF is preserved in the AST. +// CHECK: CXXRecordDecl {{.*}} imported in CModule.SubModule struct FromSubmodule definition + Index: lldb/unittests/Symbol/TestTypeSystemClang.cpp =================================================================== --- lldb/unittests/Symbol/TestTypeSystemClang.cpp +++ lldb/unittests/Symbol/TestTypeSystemClang.cpp @@ -257,9 +257,10 @@ CompilerType basic_compiler_type = ast.GetBasicType(basic_type); EXPECT_TRUE(basic_compiler_type.IsValid()); - CompilerType enum_type = - ast.CreateEnumerationType("my_enum", ast.GetTranslationUnitDecl(), - Declaration(), basic_compiler_type, scoped); + CompilerType enum_type = ast.CreateEnumerationType( + "my_enum", + m_ast->GetAsCompilerDeclContext(ast.GetTranslationUnitDecl()), + Declaration(), basic_compiler_type, scoped); CompilerType t = ast.GetEnumerationIntegerType(enum_type); // Check that the type we put in at the start is found again. EXPECT_EQ(basic_compiler_type.GetTypeName(), t.GetTypeName()); @@ -273,7 +274,7 @@ TypeSystemClang::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::eAccessPublic, "FooRecord", clang::TTK_Struct, lldb::eLanguageTypeC_plus_plus, nullptr); // Clang builtin type and record type should pass EXPECT_TRUE(ClangUtil::IsClangType(bool_type)); @@ -285,7 +286,7 @@ TEST_F(TestTypeSystemClang, TestRemoveFastQualifiers) { CompilerType record_type = m_ast->CreateRecordType( - nullptr, lldb::eAccessPublic, "FooRecord", clang::TTK_Struct, + {}, lldb::eAccessPublic, "FooRecord", clang::TTK_Struct, lldb::eLanguageTypeC_plus_plus, nullptr); QualType qt; @@ -357,7 +358,7 @@ // Test that a record with no fields returns false CompilerType empty_base = m_ast->CreateRecordType( - nullptr, lldb::eAccessPublic, "EmptyBase", clang::TTK_Struct, + {}, lldb::eAccessPublic, "EmptyBase", clang::TTK_Struct, lldb::eLanguageTypeC_plus_plus, nullptr); TypeSystemClang::StartTagDeclarationDefinition(empty_base); TypeSystemClang::CompleteTagDeclarationDefinition(empty_base); @@ -368,7 +369,7 @@ // Test that a record with direct fields returns true CompilerType non_empty_base = m_ast->CreateRecordType( - nullptr, lldb::eAccessPublic, "NonEmptyBase", clang::TTK_Struct, + {}, lldb::eAccessPublic, "NonEmptyBase", clang::TTK_Struct, lldb::eLanguageTypeC_plus_plus, nullptr); TypeSystemClang::StartTagDeclarationDefinition(non_empty_base); FieldDecl *non_empty_base_field_decl = m_ast->AddFieldToRecordType( @@ -384,7 +385,7 @@ // Test that a record with no direct fields, but fields in a base returns true CompilerType empty_derived = m_ast->CreateRecordType( - nullptr, lldb::eAccessPublic, "EmptyDerived", clang::TTK_Struct, + {}, lldb::eAccessPublic, "EmptyDerived", clang::TTK_Struct, lldb::eLanguageTypeC_plus_plus, nullptr); TypeSystemClang::StartTagDeclarationDefinition(empty_derived); std::unique_ptr non_empty_base_spec = @@ -407,7 +408,7 @@ // Test that a record with no direct fields, but fields in a virtual base // returns true CompilerType empty_derived2 = m_ast->CreateRecordType( - nullptr, lldb::eAccessPublic, "EmptyDerived2", clang::TTK_Struct, + {}, lldb::eAccessPublic, "EmptyDerived2", clang::TTK_Struct, lldb::eLanguageTypeC_plus_plus, nullptr); TypeSystemClang::StartTagDeclarationDefinition(empty_derived2); std::unique_ptr non_empty_vbase_spec = @@ -439,13 +440,15 @@ // template struct foo; ClassTemplateDecl *decl = m_ast->CreateClassTemplateDecl( - m_ast->GetTranslationUnitDecl(), eAccessPublic, "foo", TTK_Struct, infos); + m_ast->GetAsCompilerDeclContext(m_ast->GetTranslationUnitDecl()), + eAccessPublic, "foo", TTK_Struct, infos); ASSERT_NE(decl, nullptr); // foo ClassTemplateSpecializationDecl *spec_decl = m_ast->CreateClassTemplateSpecializationDecl( - m_ast->GetTranslationUnitDecl(), decl, TTK_Struct, infos); + m_ast->GetAsCompilerDeclContext(m_ast->GetTranslationUnitDecl()), + decl, TTK_Struct, infos); ASSERT_NE(spec_decl, nullptr); CompilerType type = m_ast->CreateClassTemplateSpecializationType(spec_decl); ASSERT_TRUE(type); @@ -454,7 +457,8 @@ // typedef foo foo_def; CompilerType typedef_type = m_ast->CreateTypedefType( - type, "foo_def", m_ast->CreateDeclContext(m_ast->GetTranslationUnitDecl())); + type, "foo_def", + m_ast->GetAsCompilerDeclContext(m_ast->GetTranslationUnitDecl())); CompilerType auto_type( m_ast.get(), @@ -528,13 +532,14 @@ // Prepare the declarations/types we need for the template. CompilerType clang_type = m_ast->CreateFunctionType(int_type, nullptr, 0U, false, 0U); - FunctionDecl *func = - m_ast->CreateFunctionDeclaration(TU, "foo", clang_type, 0, false); + FunctionDecl *func = m_ast->CreateFunctionDeclaration( + m_ast->GetAsCompilerDeclContext(TU), "foo", clang_type, 0, false); TypeSystemClang::TemplateParameterInfos empty_params; // Create the actual function template. clang::FunctionTemplateDecl *func_template = - m_ast->CreateFunctionTemplateDecl(TU, func, "foo", empty_params); + m_ast->CreateFunctionTemplateDecl(m_ast->GetAsCompilerDeclContext(TU), + func, "foo", empty_params); EXPECT_EQ(TU, func_template->getDeclContext()); EXPECT_EQ("foo", func_template->getName()); @@ -559,12 +564,13 @@ // 1. FunctionDecls can't be in a Record (only CXXMethodDecls can). // 2. It is mirroring the behavior of DWARFASTParserClang::ParseSubroutine. FunctionDecl *func = - m_ast->CreateFunctionDeclaration(TU, "foo", clang_type, 0, false); + m_ast->CreateFunctionDeclaration(m_ast->GetAsCompilerDeclContext(TU), "foo", clang_type, 0, false); TypeSystemClang::TemplateParameterInfos empty_params; // Create the actual function template. clang::FunctionTemplateDecl *func_template = - m_ast->CreateFunctionTemplateDecl(record, func, "foo", empty_params); + m_ast->CreateFunctionTemplateDecl(m_ast->GetAsCompilerDeclContext(record), + func, "foo", empty_params); EXPECT_EQ(record, func_template->getDeclContext()); EXPECT_EQ("foo", func_template->getName()); Index: lldb/unittests/SymbolFile/DWARF/DWARFASTParserClangTests.cpp =================================================================== --- lldb/unittests/SymbolFile/DWARF/DWARFASTParserClangTests.cpp +++ lldb/unittests/SymbolFile/DWARF/DWARFASTParserClangTests.cpp @@ -23,10 +23,10 @@ using DWARFASTParserClang::DWARFASTParserClang; using DWARFASTParserClang::LinkDeclContextToDIE; - std::vector GetDeclContextToDIEMapKeys() { - std::vector keys; + std::vector GetDeclContextToDIEMapKeys() { + std::vector keys; for (const auto &it : m_decl_ctx_to_die) - keys.push_back(it.first); + keys.push_back({&m_ast, it.first}); return keys; } }; @@ -103,13 +103,14 @@ std::vector dies = { DWARFDIE(unit, die_child0), DWARFDIE(unit, die_child1), DWARFDIE(unit, die_child2), DWARFDIE(unit, die_child3)}; - std::vector decl_ctxs = { - (clang::DeclContext *)1LL, (clang::DeclContext *)2LL, - (clang::DeclContext *)2LL, (clang::DeclContext *)3LL}; + std::vector decl_ctxs = { + {&ast_ctx, (clang::DeclContext *)1LL}, + {&ast_ctx, (clang::DeclContext *)2LL}, + {&ast_ctx, (clang::DeclContext *)2LL}, + {&ast_ctx, (clang::DeclContext *)3LL}}; for (int i = 0; i < 4; ++i) ast_parser.LinkDeclContextToDIE(decl_ctxs[i], dies[i]); - ast_parser.EnsureAllDIEsInDeclContextHaveBeenParsed( - CompilerDeclContext(nullptr, decl_ctxs[1])); + ast_parser.EnsureAllDIEsInDeclContextHaveBeenParsed(decl_ctxs[1]); EXPECT_THAT(ast_parser.GetDeclContextToDIEMapKeys(), testing::UnorderedElementsAre(decl_ctxs[0], decl_ctxs[3])); Index: lldb/unittests/TestingSupport/Symbol/ClangTestUtils.h =================================================================== --- lldb/unittests/TestingSupport/Symbol/ClangTestUtils.h +++ lldb/unittests/TestingSupport/Symbol/ClangTestUtils.h @@ -27,7 +27,8 @@ } inline CompilerType createRecord(TypeSystemClang &ast, llvm::StringRef name) { - return ast.CreateRecordType(ast.getASTContext().getTranslationUnitDecl(), + return ast.CreateRecordType(ast.GetAsCompilerDeclContext( + ast.getASTContext().getTranslationUnitDecl()), lldb::AccessType::eAccessPublic, name, 0, lldb::LanguageType::eLanguageTypeC); }