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/include/lldb/Symbol/CompilerType.h =================================================================== --- lldb/include/lldb/Symbol/CompilerType.h +++ lldb/include/lldb/Symbol/CompilerType.h @@ -233,9 +233,10 @@ // Create a typedef to this type using "name" as the name of the typedef this // type is valid and the type system supports typedefs, else return an - // invalid type. + // invalid type. The payload argument is the typesystem-specific Type payload. CompilerType CreateTypedef(const char *name, - const CompilerDeclContext &decl_ctx) const; + const CompilerDeclContext &decl_ctx, + uint32_t payload) const; // If the current object represents a typedef type, get the underlying type CompilerType GetTypedefedType() const; Index: lldb/include/lldb/Symbol/Type.h =================================================================== --- lldb/include/lldb/Symbol/Type.h +++ lldb/include/lldb/Symbol/Type.h @@ -195,12 +195,7 @@ void SetEncodingType(Type *encoding_type) { m_encoding_type = encoding_type; } uint32_t GetEncodingMask(); - - bool IsCompleteObjCClass() { return m_is_complete_objc_class; } - - void SetIsCompleteObjCClass(bool is_complete_objc_class) { - m_is_complete_objc_class = is_complete_objc_class; - } + uint32_t &GetPayload() { return m_payload; } protected: ConstString m_name; @@ -215,7 +210,8 @@ Declaration m_decl; CompilerType m_compiler_type; ResolveState m_compiler_type_resolve_state; - bool m_is_complete_objc_class; + /// Language-specific flags. + uint32_t m_payload = 0; Type *GetEncodingType(); Index: lldb/include/lldb/Symbol/TypeSystem.h =================================================================== --- lldb/include/lldb/Symbol/TypeSystem.h +++ lldb/include/lldb/Symbol/TypeSystem.h @@ -254,9 +254,12 @@ virtual CompilerType AddRestrictModifier(lldb::opaque_compiler_type_t type); + /// \param opaque_payload The m_payload field of Type, which may + /// carry TypeSystem-specific extra information. virtual CompilerType CreateTypedef(lldb::opaque_compiler_type_t type, const char *name, - const CompilerDeclContext &decl_ctx); + const CompilerDeclContext &decl_ctx, + uint32_t opaque_payload); // Exploring the type Index: lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp =================================================================== --- lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp +++ lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp @@ -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, nullptr, 0); 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(), + nullptr, 0, 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)); + nullptr, 0, lldb::eAccessPublic, name, kind, lldb::eLanguageTypeC)); if (union_type) { TypeSystemClang::StartTagDeclarationDefinition(union_type); Index: lldb/source/Plugins/LanguageRuntime/ObjC/ObjCLanguageRuntime.cpp =================================================================== --- lldb/source/Plugins/LanguageRuntime/ObjC/ObjCLanguageRuntime.cpp +++ lldb/source/Plugins/LanguageRuntime/ObjC/ObjCLanguageRuntime.cpp @@ -129,7 +129,7 @@ if (TypeSystemClang::IsObjCObjectOrInterfaceType( type_sp->GetForwardCompilerType())) { - if (type_sp->IsCompleteObjCClass()) { + if (TypePayloadClang(type_sp->GetPayload()).IsCompleteObjCClass()) { m_complete_class_cache[name] = type_sp; return type_sp; } Index: lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h =================================================================== --- lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h +++ lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h @@ -78,6 +78,7 @@ DIEToDeclContextMap; typedef std::multimap DeclContextToDIEMap; + typedef llvm::DenseMap DIEToModuleMap; typedef llvm::DenseMap DIEToDeclMap; typedef llvm::DenseMap DeclToDIEMap; @@ -87,6 +88,7 @@ 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; /// @} @@ -140,6 +142,7 @@ clang::DeclContext *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, Index: lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp =================================================================== --- lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp +++ lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp @@ -707,6 +707,7 @@ die.GetID(), dwarf, attrs.name, attrs.byte_size, nullptr, dwarf->GetUID(attrs.type.Reference()), encoding_data_type, &attrs.decl, clang_type, resolve_state); + TypePayloadClang(type_sp->GetPayload()).SetOwningModuleID(GetOwningModuleID(die)); dwarf->GetDIEToType()[die.GetDIE()] = type_sp.get(); return type_sp; @@ -788,7 +789,8 @@ clang_type = m_ast.CreateEnumerationType( attrs.name.GetCString(), GetClangDeclContextContainingDIE(die, nullptr), - attrs.decl, enumerator_clang_type, attrs.is_scoped_enum); + GetOwningModuleID(die), attrs.decl, enumerator_clang_type, + attrs.is_scoped_enum); } else { enumerator_clang_type = m_ast.GetEnumerationIntegerType(clang_type); } @@ -1171,6 +1173,7 @@ function_decl = m_ast.CreateFunctionDeclaration( ignore_containing_context ? m_ast.GetTranslationUnitDecl() : containing_decl_ctx, + GetOwningModuleID(die), attrs.name.GetCString(), clang_type, attrs.storage, attrs.is_inline); @@ -1180,12 +1183,14 @@ template_function_decl = m_ast.CreateFunctionDeclaration( ignore_containing_context ? m_ast.GetTranslationUnitDecl() : containing_decl_ctx, + GetOwningModuleID(die), attrs.name.GetCString(), clang_type, attrs.storage, attrs.is_inline); clang::FunctionTemplateDecl *func_template_decl = m_ast.CreateFunctionTemplateDecl( - containing_decl_ctx, template_function_decl, - attrs.name.GetCString(), template_param_infos); + containing_decl_ctx, GetOwningModuleID(die), + template_function_decl, attrs.name.GetCString(), + template_param_infos); m_ast.CreateFunctionTemplateSpecializationInfo( function_decl, func_template_decl, template_param_infos); } @@ -1582,9 +1587,9 @@ TypeSystemClang::TemplateParameterInfos template_param_infos; if (ParseTemplateParameterInfos(die, template_param_infos)) { clang::ClassTemplateDecl *class_template_decl = - m_ast.ParseClassTemplateDecl(decl_ctx, attrs.accessibility, - attrs.name.GetCString(), tag_decl_kind, - template_param_infos); + m_ast.ParseClassTemplateDecl( + decl_ctx, GetOwningModuleID(die), attrs.accessibility, + attrs.name.GetCString(), tag_decl_kind, template_param_infos); if (!class_template_decl) { if (log) { dwarf->GetObjectFile()->GetModule()->LogMessage( @@ -1599,8 +1604,8 @@ clang::ClassTemplateSpecializationDecl *class_specialization_decl = m_ast.CreateClassTemplateSpecializationDecl( - decl_ctx, class_template_decl, tag_decl_kind, - template_param_infos); + decl_ctx, GetOwningModuleID(die), class_template_decl, + tag_decl_kind, template_param_infos); clang_type = m_ast.CreateClassTemplateSpecializationType( class_specialization_decl); clang_type_was_created = true; @@ -1613,8 +1618,9 @@ if (!clang_type_was_created) { clang_type_was_created = true; clang_type = m_ast.CreateRecordType( - decl_ctx, attrs.accessibility, attrs.name.GetCString(), tag_decl_kind, - attrs.class_language, &metadata, attrs.exports_symbols); + decl_ctx, GetOwningModuleID(die), attrs.accessibility, + attrs.name.GetCString(), tag_decl_kind, attrs.class_language, + &metadata, attrs.exports_symbols); } } @@ -1627,7 +1633,8 @@ Type::eEncodingIsUID, &attrs.decl, clang_type, Type::ResolveState::Forward); - type_sp->SetIsCompleteObjCClass(attrs.is_complete_objc_class); + TypePayloadClang(type_sp->GetPayload()) + .SetIsCompleteObjCClass(attrs.is_complete_objc_class); // Add our type to the unique type map so we don't end up creating many // copies of the same type over and over in the ASTContext for our @@ -3061,9 +3068,9 @@ function_param_types.push_back(type->GetForwardCompilerType()); clang::ParmVarDecl *param_var_decl = - m_ast.CreateParameterDeclaration(containing_decl_ctx, name, - type->GetForwardCompilerType(), - storage); + m_ast.CreateParameterDeclaration( + containing_decl_ctx, GetOwningModuleID(die), name, + type->GetForwardCompilerType(), storage); assert(param_var_decl); function_param_decls.push_back(param_var_decl); @@ -3261,7 +3268,7 @@ TypeSystemClang::DeclContextGetAsDeclContext( dwarf->GetDeclContextContainingUID(die.GetID())); decl = m_ast.CreateVariableDeclaration( - decl_context, name, + decl_context, GetOwningModuleID(die), name, ClangUtil::GetQualType(type->GetForwardCompilerType())); } break; @@ -3278,8 +3285,8 @@ 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( + decl_context, GetOwningModuleID(die), clang_imported_decl); } } break; @@ -3298,7 +3305,8 @@ if (clang::NamespaceDecl *ns_decl = TypeSystemClang::DeclContextGetAsNamespaceDecl( imported_decl_ctx)) - decl = m_ast.CreateUsingDirectiveDeclaration(decl_context, ns_decl); + decl = m_ast.CreateUsingDirectiveDeclaration( + decl_context, GetOwningModuleID(die), ns_decl); } } break; @@ -3356,6 +3364,31 @@ return nullptr; } +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) { switch (die.Tag()) { case DW_TAG_subprogram: @@ -3428,7 +3461,7 @@ DWARFDIE decl_context_die; clang::DeclContext *decl_context = GetClangDeclContextContainingDIE(die, &decl_context_die); - decl = m_ast.CreateBlockDeclaration(decl_context); + decl = m_ast.CreateBlockDeclaration(decl_context, GetOwningModuleID(die)); if (decl) LinkDeclContextToDIE((clang::DeclContext *)decl, die); Index: lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.cpp =================================================================== --- lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.cpp +++ lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.cpp @@ -776,8 +776,9 @@ metadata.SetUserID(toOpaqueUid(id)); metadata.SetIsDynamicCXXType(false); - CompilerType ct = m_clang.CreateRecordType( - context, access, uname, ttk, lldb::eLanguageTypeC_plus_plus, &metadata); + CompilerType ct = + m_clang.CreateRecordType(context, 0, access, uname, ttk, + lldb::eLanguageTypeC_plus_plus, &metadata); lldbassert(ct.IsValid()); @@ -804,7 +805,7 @@ PdbAstBuilder::GetOrCreateNamespaceDecl(const char *name, clang::DeclContext &context) { return m_clang.GetUniqueNamespaceDeclaration( - IsAnonymousNamespaceName(name) ? nullptr : name, &context); + IsAnonymousNamespaceName(name) ? nullptr : name, &context, 0); } clang::BlockDecl * @@ -814,7 +815,7 @@ clang::DeclContext *scope = GetParentDeclContext(block_id); - clang::BlockDecl *block_decl = m_clang.CreateBlockDeclaration(scope); + clang::BlockDecl *block_decl = m_clang.CreateBlockDeclaration(scope, 0); m_uid_to_decl.insert({toOpaqueUid(block_id), block_decl}); DeclStatus status; @@ -831,7 +832,7 @@ clang::QualType qt = GetOrCreateType(var_info.type); clang::VarDecl *var_decl = m_clang.CreateVariableDeclaration( - &scope, var_info.name.str().c_str(), qt); + &scope, 0, var_info.name.str().c_str(), qt); m_uid_to_decl[toOpaqueUid(uid)] = var_decl; DeclStatus status; @@ -879,7 +880,7 @@ std::string uname = std::string(DropNameScope(udt.Name)); CompilerType ct = m_clang.CreateTypedefType(ToCompilerType(qt), uname.c_str(), - ToCompilerDeclContext(*scope)); + ToCompilerDeclContext(*scope), 0); clang::TypedefNameDecl *tnd = m_clang.GetAsTypedefDecl(ct); DeclStatus status; status.resolved = true; @@ -1012,7 +1013,7 @@ proc_name.consume_front("::"); clang::FunctionDecl *function_decl = m_clang.CreateFunctionDeclaration( - parent, proc_name.str().c_str(), func_ct, storage, false); + parent, 0, 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,7 +1081,7 @@ CompilerType param_type_ct = m_clang.GetType(qt); clang::ParmVarDecl *param = m_clang.CreateParameterDeclaration( - &function_decl, param_name.str().c_str(), param_type_ct, + &function_decl, 0, param_name.str().c_str(), param_type_ct, clang::SC_None, true); lldbassert(m_uid_to_decl.count(toOpaqueUid(param_uid)) == 0); @@ -1102,8 +1103,8 @@ Declaration declaration; CompilerType enum_ct = m_clang.CreateEnumerationType( - uname.c_str(), decl_context, declaration, ToCompilerType(underlying_type), - er.isScoped()); + uname.c_str(), decl_context, 0, declaration, + ToCompilerType(underlying_type), er.isScoped()); TypeSystemClang::StartTagDeclarationDefinition(enum_ct); TypeSystemClang::SetHasExternalStorage(enum_ct.GetOpaqueQualType(), true); Index: lldb/source/Plugins/SymbolFile/PDB/PDBASTParser.cpp =================================================================== --- lldb/source/Plugins/SymbolFile/PDB/PDBASTParser.cpp +++ lldb/source/Plugins/SymbolFile/PDB/PDBASTParser.cpp @@ -410,7 +410,7 @@ metadata.SetIsDynamicCXXType(false); clang_type = - m_ast.CreateRecordType(decl_context, access, name, tag_type_kind, + m_ast.CreateRecordType(decl_context, 0, access, name, tag_type_kind, lldb::eLanguageTypeC_plus_plus, &metadata); assert(clang_type.IsValid()); @@ -497,8 +497,8 @@ // 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(), decl_context, 0, + decl, builtin_type, isScoped); auto enum_decl = TypeSystemClang::GetAsEnumDecl(ast_enum); assert(enum_decl); @@ -550,7 +550,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.CreateDeclContext(decl_ctx), 0); if (!ast_typedef) return nullptr; @@ -901,7 +901,7 @@ return nullptr; decl = m_ast.CreateVariableDeclaration( - decl_context, name.c_str(), + decl_context, 0, name.c_str(), ClangUtil::GetQualType(type->GetLayoutCompilerType())); } @@ -927,7 +927,7 @@ : clang::StorageClass::SC_None; auto decl = m_ast.CreateFunctionDeclaration( - decl_context, name.c_str(), type->GetForwardCompilerType(), storage, + decl_context, 0, name.c_str(), type->GetForwardCompilerType(), storage, func->hasInlineAttribute()); std::vector params; @@ -941,7 +941,7 @@ continue; clang::ParmVarDecl *param = m_ast.CreateParameterDeclaration( - decl, nullptr, arg_type->GetForwardCompilerType(), + decl, 0, nullptr, arg_type->GetForwardCompilerType(), clang::SC_None, true); if (param) params.push_back(param); @@ -1057,7 +1057,7 @@ : namespace_name.data(); clang::NamespaceDecl *namespace_decl = m_ast.GetUniqueNamespaceDeclaration(namespace_name_c_str, - curr_context); + curr_context, 0); m_parent_to_namespaces[curr_context].insert(namespace_decl); m_namespaces.insert(namespace_decl); 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", + nullptr, 0, 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 @@ -33,6 +33,7 @@ #include "lldb/Symbol/TypeSystem.h" #include "lldb/Target/Target.h" #include "lldb/Utility/ConstString.h" +#include "lldb/Utility/Flags.h" #include "lldb/Utility/Log.h" #include "lldb/Utility/Logging.h" #include "lldb/lldb-enumerations.h" @@ -40,12 +41,41 @@ class DWARFASTParserClang; class PDBASTParser; +namespace clang { + class HeaderSearch; + class ModuleMap; +} + namespace lldb_private { class ClangASTMetadata; class ClangASTSource; class Declaration; +/// The implementation of lldb::Type's m_payload field for TypeSystemClang. +class TypePayloadClang { + uint32_t &m_payload; +public: + TypePayloadClang(uint32_t &opaque_payload) : m_payload(opaque_payload) {} + /// Clang-specific functions. As more of these get added we may want + /// to factor this into typesystem-specific subclasses. + /// \{ + static constexpr unsigned ObjCClassBit = 1 << 31; + bool IsCompleteObjCClass() { return Flags(m_payload).Test(ObjCClassBit); } + void SetIsCompleteObjCClass(bool is_complete_objc_class) { + m_payload = is_complete_objc_class ? Flags(m_payload).Set(ObjCClassBit) + : Flags(m_payload).Clear(ObjCClassBit); + } + unsigned GetOwningModuleID() { return Flags(m_payload).Clear(ObjCClassBit); } + void SetOwningModuleID(unsigned id) { + assert(id < ObjCClassBit); + bool is_complete = IsCompleteObjCClass(); + m_payload = id; + SetIsCompleteObjCClass(is_complete); + } + /// \} +}; + /// A TypeSystem implementation based on Clang. /// /// This class uses a single clang::ASTContext as the backend for storing @@ -268,7 +298,13 @@ static uint32_t GetNumBaseClasses(const clang::CXXRecordDecl *cxx_record_decl, bool omit_empty_base_classes); + /// 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(clang::DeclContext *decl_ctx, + unsigned owning_module, lldb::AccessType access_type, llvm::StringRef name, int kind, lldb::LanguageType language, @@ -294,6 +330,7 @@ clang::FunctionTemplateDecl * CreateFunctionTemplateDecl(clang::DeclContext *decl_ctx, + unsigned owning_module, clang::FunctionDecl *func_decl, const char *name, const TemplateParameterInfos &infos); @@ -302,7 +339,7 @@ const TemplateParameterInfos &infos); clang::ClassTemplateDecl * - CreateClassTemplateDecl(clang::DeclContext *decl_ctx, + CreateClassTemplateDecl(clang::DeclContext *decl_ctx, unsigned owning_module, lldb::AccessType access_type, const char *class_name, int kind, const TemplateParameterInfos &infos); @@ -310,7 +347,7 @@ CreateTemplateTemplateParmDecl(const char *template_name); clang::ClassTemplateSpecializationDecl *CreateClassTemplateSpecializationDecl( - clang::DeclContext *decl_ctx, + clang::DeclContext *decl_ctx, unsigned owning_module, clang::ClassTemplateDecl *class_template_decl, int kind, const TemplateParameterInfos &infos); @@ -330,7 +367,8 @@ static bool RecordHasFields(const clang::RecordDecl *record_decl); CompilerType CreateObjCClass(llvm::StringRef name, - clang::DeclContext *decl_ctx, bool isForwardDecl, + clang::DeclContext *decl_ctx, + unsigned owning_module, bool isForwardDecl, bool isInternal, ClangASTMetadata *metadata = nullptr); @@ -348,14 +386,13 @@ clang::NamespaceDecl * GetUniqueNamespaceDeclaration(const char *name, clang::DeclContext *decl_ctx, - bool is_inline = false); + unsigned owning_module, bool is_inline = false); // Function Types - clang::FunctionDecl * - CreateFunctionDeclaration(clang::DeclContext *decl_ctx, const char *name, - const CompilerType &function_Type, int storage, - bool is_inline); + clang::FunctionDecl *CreateFunctionDeclaration( + clang::DeclContext *decl_ctx, unsigned owning_module, const char *name, + const CompilerType &function_Type, int storage, bool is_inline); CompilerType CreateFunctionType(const CompilerType &result_type, const CompilerType *args, unsigned num_args, @@ -370,6 +407,7 @@ } clang::ParmVarDecl *CreateParameterDeclaration(clang::DeclContext *decl_ctx, + unsigned owning_module, const char *name, const CompilerType ¶m_type, int storage, @@ -388,6 +426,7 @@ // Enumeration Types CompilerType CreateEnumerationType(const char *name, clang::DeclContext *decl_ctx, + unsigned owning_module, const Declaration &decl, const CompilerType &integer_qual_type, bool is_scoped); @@ -612,11 +651,13 @@ // Creating related types - // Using the current type, create a new typedef to that type using - // "typedef_name" as the name and "decl_ctx" as the decl context. + /// Using the current type, create a new typedef to that type using + /// "typedef_name" as the name and "decl_ctx" as the decl context. + /// \param payload is an opaque TypePayloadClang. static CompilerType CreateTypedefType(const CompilerType &type, const char *typedef_name, - const CompilerDeclContext &compiler_decl_ctx); + const CompilerDeclContext &compiler_decl_ctx, + uint32_t opaque_payload); CompilerType GetArrayElementType(lldb::opaque_compiler_type_t type, uint64_t *stride) override; @@ -667,7 +708,8 @@ CompilerType CreateTypedef(lldb::opaque_compiler_type_t type, const char *name, - const CompilerDeclContext &decl_ctx) override; + const CompilerDeclContext &decl_ctx, + uint32_t opaque_payload) override; // If the current object represents a typedef type, get the underlying type CompilerType GetTypedefedType(lldb::opaque_compiler_type_t type) override; @@ -926,20 +968,24 @@ GetAsObjCInterfaceDecl(const CompilerType &type); clang::ClassTemplateDecl *ParseClassTemplateDecl( - clang::DeclContext *decl_ctx, lldb::AccessType access_type, - const char *parent_name, int tag_decl_kind, + clang::DeclContext *decl_ctx, unsigned owning_module, + 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(clang::DeclContext *ctx, + unsigned owning_module); clang::UsingDirectiveDecl * CreateUsingDirectiveDeclaration(clang::DeclContext *decl_ctx, + unsigned owning_module, clang::NamespaceDecl *ns_decl); clang::UsingDecl *CreateUsingDeclaration(clang::DeclContext *current_decl_ctx, + unsigned owning_module, clang::NamedDecl *target); clang::VarDecl *CreateVariableDeclaration(clang::DeclContext *decl_context, + unsigned owning_module, const char *name, clang::QualType type); @@ -962,6 +1008,13 @@ clang::DeclarationName GetDeclarationName(const char *name, const CompilerType &function_clang_type); + clang::LangOptions *GetLangOpts() const { + return m_language_options_up.get(); + } + clang::SourceManager *GetSourceMgr() const { + return m_source_manager_up.get(); + } + private: const clang::ClassTemplateSpecializationDecl * GetAsTemplateSpecialization(lldb::opaque_compiler_type_t type); @@ -979,6 +1032,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; 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" @@ -501,6 +504,10 @@ // // FIXME: This is affected by other options (-fno-inline). Opts.NoInlineDefine = !Opt; + + // This is needed to allocate the extra space for the owning module + // on each decl. + Opts.ModulesLocalVisibility = 1; } TypeSystemClang::TypeSystemClang(llvm::StringRef name, @@ -1182,7 +1189,53 @@ #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, unsigned owning_module) { + if (!decl || !owning_module) + return; + + decl->setFromASTFile(); + decl->setOwningModuleID(owning_module); + decl->setModuleOwnershipKind(clang::Decl::ModuleOwnershipKind::Visible); +} + +CompilerType TypeSystemClang::CreateRecordType(clang::DeclContext *decl_ctx, + unsigned owning_module, AccessType access_type, llvm::StringRef name, int kind, LanguageType language, @@ -1197,7 +1250,8 @@ language == eLanguageTypeObjC_plus_plus) { bool isForwardDecl = true; bool isInternal = false; - return CreateObjCClass(name, decl_ctx, isForwardDecl, isInternal, metadata); + return CreateObjCClass(name, decl_ctx, owning_module, isForwardDecl, + isInternal, metadata); } // NOTE: Eventually CXXRecordDecl will be merged back into RecordDecl and @@ -1207,10 +1261,10 @@ // complete definition just in case. bool has_name = !name.empty(); - CXXRecordDecl *decl = CXXRecordDecl::Create( - ast, (TagDecl::TagKind)kind, decl_ctx, SourceLocation(), SourceLocation(), - has_name ? &ast.Idents.get(name) : nullptr); + ast, (TagDecl::TagKind)kind, decl_ctx, SourceLocation(), + SourceLocation(), has_name ? &ast.Idents.get(name) : nullptr); + SetOwningModule(decl, owning_module); if (!has_name) { // In C++ a lambda is also represented as an unnamed class. This is @@ -1322,18 +1376,19 @@ } clang::FunctionTemplateDecl *TypeSystemClang::CreateFunctionTemplateDecl( - clang::DeclContext *decl_ctx, clang::FunctionDecl *func_decl, - const char *name, const TemplateParameterInfos &template_param_infos) { + clang::DeclContext *decl_ctx, unsigned owning_module, + 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; - 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); + SetOwningModule(func_tmpl_decl, owning_module); for (size_t i = 0, template_param_decl_count = template_param_decls.size(); i < template_param_decl_count; ++i) { @@ -1360,8 +1415,9 @@ } ClassTemplateDecl *TypeSystemClang::CreateClassTemplateDecl( - DeclContext *decl_ctx, lldb::AccessType access_type, const char *class_name, - int kind, const TemplateParameterInfos &template_param_infos) { + DeclContext *decl_ctx, unsigned owning_module, lldb::AccessType access_type, + const char *class_name, int kind, + const TemplateParameterInfos &template_param_infos) { ASTContext &ast = getASTContext(); ClassTemplateDecl *class_template_decl = nullptr; @@ -1386,9 +1442,10 @@ CXXRecordDecl *template_cxx_decl = CXXRecordDecl::Create( ast, (TagDecl::TagKind)kind, - decl_ctx, // What decl context do we use here? TU? The actual decl - // context? + decl_ctx, // What decl context do we use here? TU? The actual + // decl context? SourceLocation(), SourceLocation(), &identifier_info); + SetOwningModule(template_cxx_decl, owning_module); for (size_t i = 0, template_param_decl_count = template_param_decls.size(); i < template_param_decl_count; ++i) { @@ -1402,10 +1459,11 @@ class_template_decl = ClassTemplateDecl::Create( ast, - decl_ctx, // What decl context do we use here? TU? The actual decl - // context? + decl_ctx, // 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, owning_module); if (class_template_decl) { if (access_type != eAccessNone) @@ -1448,7 +1506,8 @@ ClassTemplateSpecializationDecl * TypeSystemClang::CreateClassTemplateSpecializationDecl( - DeclContext *decl_ctx, ClassTemplateDecl *class_template_decl, int kind, + DeclContext *decl_ctx, unsigned owning_module, + ClassTemplateDecl *class_template_decl, int kind, const TemplateParameterInfos &template_param_infos) { ASTContext &ast = getASTContext(); llvm::SmallVector args( @@ -1464,6 +1523,7 @@ ClassTemplateSpecializationDecl::Create( ast, (TagDecl::TagKind)kind, decl_ctx, SourceLocation(), SourceLocation(), class_template_decl, args, nullptr); + SetOwningModule(class_template_decl, owning_module); class_template_specialization_decl->setSpecializationKind( TSK_ExplicitSpecialization); @@ -1583,13 +1643,14 @@ #pragma mark Objective-C Classes CompilerType TypeSystemClang::CreateObjCClass(llvm::StringRef name, - DeclContext *decl_ctx, + clang::DeclContext *decl_ctx, + unsigned owning_module, bool isForwardDecl, bool isInternal, ClangASTMetadata *metadata) { ASTContext &ast = getASTContext(); assert(!name.empty()); - if (decl_ctx == nullptr) + if (!decl_ctx) decl_ctx = ast.getTranslationUnitDecl(); ObjCInterfaceDecl *decl = ObjCInterfaceDecl::Create( @@ -1597,6 +1658,7 @@ SourceLocation(), /*isForwardDecl,*/ isInternal); + SetOwningModule(decl, owning_module); if (decl && metadata) SetMetadata(decl, *metadata); @@ -1634,17 +1696,19 @@ #pragma mark Namespace Declarations NamespaceDecl *TypeSystemClang::GetUniqueNamespaceDeclaration( - const char *name, DeclContext *decl_ctx, bool is_inline) { + const char *name, clang::DeclContext *decl_ctx, unsigned owning_module, + bool is_inline) { NamespaceDecl *namespace_decl = nullptr; ASTContext &ast = getASTContext(); TranslationUnitDecl *translation_unit_decl = ast.getTranslationUnitDecl(); - if (decl_ctx == nullptr) + if (!decl_ctx) decl_ctx = translation_unit_decl; 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 = + decl_ctx->lookup(decl_name); for (NamedDecl *decl : result) { namespace_decl = dyn_cast(decl); if (namespace_decl) @@ -1687,16 +1751,21 @@ } } } + // Note: namespaces can span multiple modules, so perhaps this isn't a good idea. + SetOwningModule(namespace_decl, owning_module); + 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()); +TypeSystemClang::CreateBlockDeclaration(clang::DeclContext *ctx, + unsigned owning_module) { + if (ctx) { + clang::BlockDecl *decl = clang::BlockDecl::Create( + getASTContext(), ctx, clang::SourceLocation()); ctx->addDecl(decl); + SetOwningModule(decl, owning_module); return decl; } return nullptr; @@ -1720,30 +1789,37 @@ } clang::UsingDirectiveDecl *TypeSystemClang::CreateUsingDirectiveDeclaration( - clang::DeclContext *decl_ctx, clang::NamespaceDecl *ns_decl) { - if (decl_ctx != nullptr && ns_decl != nullptr) { + clang::DeclContext *decl_ctx, unsigned owning_module, + 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; + 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); + SetOwningModule(using_decl, owning_module); + + return using_decl; } return nullptr; } clang::UsingDecl * TypeSystemClang::CreateUsingDeclaration(clang::DeclContext *current_decl_ctx, + unsigned owning_module, clang::NamedDecl *target) { - if (current_decl_ctx != nullptr && target != nullptr) { + if (current_decl_ctx && target) { clang::UsingDecl *using_decl = clang::UsingDecl::Create( getASTContext(), current_decl_ctx, clang::SourceLocation(), clang::NestedNameSpecifierLoc(), clang::DeclarationNameInfo(), false); + SetOwningModule(using_decl, owning_module); clang::UsingShadowDecl *shadow_decl = clang::UsingShadowDecl::Create( getASTContext(), current_decl_ctx, clang::SourceLocation(), using_decl, target); + SetOwningModule(shadow_decl, owning_module); using_decl->addShadowDecl(shadow_decl); current_decl_ctx->addDecl(using_decl); return using_decl; @@ -1752,13 +1828,16 @@ } clang::VarDecl *TypeSystemClang::CreateVariableDeclaration( - clang::DeclContext *decl_context, const char *name, clang::QualType type) { - if (decl_context != nullptr) { + clang::DeclContext *decl_context, unsigned owning_module, const char *name, + clang::QualType type) { + if (decl_context) { clang::VarDecl *var_decl = clang::VarDecl::Create( getASTContext(), decl_context, clang::SourceLocation(), clang::SourceLocation(), name && name[0] ? &getASTContext().Idents.getOwn(name) : nullptr, type, nullptr, clang::SC_None); + SetOwningModule(var_decl, owning_module); + var_decl->setAccess(clang::AS_public); decl_context->addDecl(var_decl); return var_decl; @@ -1870,11 +1949,11 @@ } FunctionDecl *TypeSystemClang::CreateFunctionDeclaration( - DeclContext *decl_ctx, const char *name, + clang::DeclContext *decl_ctx, unsigned owning_module, const char *name, const CompilerType &function_clang_type, int storage, bool is_inline) { FunctionDecl *func_decl = nullptr; ASTContext &ast = getASTContext(); - if (decl_ctx == nullptr) + if (!decl_ctx) decl_ctx = ast.getTranslationUnitDecl(); const bool hasWrittenPrototype = true; @@ -1887,6 +1966,7 @@ ClangUtil::GetQualType(function_clang_type), nullptr, (clang::StorageClass)storage, is_inline, hasWrittenPrototype, isConstexprSpecified ? CSK_constexpr : CSK_unspecified); + SetOwningModule(func_decl, owning_module); if (func_decl) decl_ctx->addDecl(func_decl); @@ -1935,7 +2015,7 @@ } ParmVarDecl *TypeSystemClang::CreateParameterDeclaration( - clang::DeclContext *decl_ctx, const char *name, + clang::DeclContext *decl_ctx, unsigned owning_module, const char *name, const CompilerType ¶m_type, int storage, bool add_decl) { ASTContext &ast = getASTContext(); auto *decl = @@ -1943,6 +2023,8 @@ name && name[0] ? &ast.Idents.get(name) : nullptr, ClangUtil::GetQualType(param_type), nullptr, (clang::StorageClass)storage, nullptr); + SetOwningModule(decl, owning_module); + if (add_decl) decl_ctx->addDecl(decl); @@ -2004,8 +2086,9 @@ return type; } - type = CreateRecordType(nullptr, lldb::eAccessPublic, type_name.GetCString(), - clang::TTK_Struct, lldb::eLanguageTypeC); + type = + CreateRecordType(nullptr, 0, lldb::eAccessPublic, type_name.GetCString(), + clang::TTK_Struct, lldb::eLanguageTypeC); StartTagDeclarationDefinition(type); for (const auto &field : type_fields) AddFieldToRecordType(type, field.first, field.second, lldb::eAccessPublic, @@ -2030,25 +2113,23 @@ #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, clang::DeclContext *decl_ctx, unsigned owning_module, + 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; - EnumDecl *enum_decl = EnumDecl::Create( ast, decl_ctx, SourceLocation(), SourceLocation(), name && name[0] ? &ast.Idents.get(name) : nullptr, nullptr, is_scoped, // IsScoped is_scoped, // IsScopedUsingClassTag false); // IsFixed - + SetOwningModule(enum_decl, owning_module); if (enum_decl) { if (decl_ctx) decl_ctx->addDecl(enum_decl); @@ -4229,7 +4310,7 @@ CompilerType TypeSystemClang::CreateTypedefType( const CompilerType &type, const char *typedef_name, - const CompilerDeclContext &compiler_decl_ctx) { + const CompilerDeclContext &compiler_decl_ctx, uint32_t payload) { if (type && typedef_name && typedef_name[0]) { TypeSystemClang *ast = llvm::dyn_cast(type.GetTypeSystem()); @@ -4240,14 +4321,15 @@ clang::DeclContext *decl_ctx = TypeSystemClang::DeclContextGetAsDeclContext(compiler_decl_ctx); - if (decl_ctx == nullptr) + if (!decl_ctx) decl_ctx = ast->getASTContext().getTranslationUnitDecl(); clang::TypedefDecl *decl = clang::TypedefDecl::Create( - clang_ast, decl_ctx, clang::SourceLocation(), clang::SourceLocation(), - &clang_ast.Idents.get(typedef_name), + clang_ast, decl_ctx, clang::SourceLocation(), + clang::SourceLocation(), &clang_ast.Idents.get(typedef_name), clang_ast.getTrivialTypeSourceInfo(qual_type)); + SetOwningModule(decl, TypePayloadClang(payload).GetOwningModuleID()); decl->setAccess(clang::AS_public); // TODO respect proper access specifier decl_ctx->addDecl(decl); @@ -4336,23 +4418,23 @@ return CompilerType(); } -CompilerType -TypeSystemClang::CreateTypedef(lldb::opaque_compiler_type_t type, - const char *typedef_name, - const CompilerDeclContext &compiler_decl_ctx) { +CompilerType TypeSystemClang::CreateTypedef( + lldb::opaque_compiler_type_t type, const char *typedef_name, + const CompilerDeclContext &compiler_decl_ctx, uint32_t payload) { if (type) { clang::ASTContext &clang_ast = getASTContext(); clang::QualType qual_type(GetQualType(type)); clang::DeclContext *decl_ctx = TypeSystemClang::DeclContextGetAsDeclContext(compiler_decl_ctx); - if (decl_ctx == nullptr) + 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, TypePayloadClang(payload).GetOwningModuleID()); clang::TagDecl *tdecl = nullptr; if (!qual_type.isNull()) { @@ -6875,6 +6957,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 +7003,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 +7044,7 @@ nullptr, // TypeSourceInfo * ConvertAccessTypeToObjCIvarAccessControl(access), bit_width, is_synthesized); + SetMemberOwningModule(field, class_interface_decl); if (field) { class_interface_decl->addDecl(field); @@ -7013,6 +7106,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 +7137,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 +7208,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 +7334,7 @@ SC, is_inline, CSK_unspecified, clang::SourceLocation()); } } + SetMemberOwningModule(cxx_method_decl, cxx_record_decl); clang::AccessSpecifier access_specifier = TypeSystemClang::ConvertAccessTypeToAccessSpecifier(access); @@ -7413,6 +7510,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 +7596,7 @@ class_interface_decl, isInstance, isVariadic, isPropertyAccessor, isSynthesizedAccessorStub, isImplicitlyDeclared, isDefined, impControl, HasRelatedResultType); + SetMemberOwningModule(getter, class_interface_decl); if (getter) { if (metadata) @@ -7532,6 +7631,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 +7757,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 +7985,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,14 +8880,14 @@ } clang::ClassTemplateDecl *TypeSystemClang::ParseClassTemplateDecl( - clang::DeclContext *decl_ctx, lldb::AccessType access_type, - const char *parent_name, int tag_decl_kind, + clang::DeclContext *decl_ctx, unsigned owning_module, + lldb::AccessType access_type, const char *parent_name, int tag_decl_kind, const TypeSystemClang::TemplateParameterInfos &template_param_infos) { if (template_param_infos.IsValid()) { std::string template_basename(parent_name); template_basename.erase(template_basename.find('<')); - return CreateClassTemplateDecl(decl_ctx, access_type, + return CreateClassTemplateDecl(decl_ctx, owning_module, access_type, template_basename.c_str(), tag_decl_kind, template_param_infos); } Index: lldb/source/Symbol/CompilerType.cpp =================================================================== --- lldb/source/Symbol/CompilerType.cpp +++ lldb/source/Symbol/CompilerType.cpp @@ -439,11 +439,11 @@ return CompilerType(); } -CompilerType -CompilerType::CreateTypedef(const char *name, - const CompilerDeclContext &decl_ctx) const { +CompilerType CompilerType::CreateTypedef(const char *name, + const CompilerDeclContext &decl_ctx, + uint32_t payload) const { if (IsValid()) - return m_type_system->CreateTypedef(m_type, name, decl_ctx); + return m_type_system->CreateTypedef(m_type, name, decl_ctx, payload); else return CompilerType(); } Index: lldb/source/Symbol/Type.cpp =================================================================== --- lldb/source/Symbol/Type.cpp +++ lldb/source/Symbol/Type.cpp @@ -148,10 +148,8 @@ m_symbol_file(symbol_file), m_context(context), m_encoding_type(nullptr), m_encoding_uid(encoding_uid), m_encoding_uid_type(encoding_uid_type), m_decl(decl), m_compiler_type(compiler_type), - m_compiler_type_resolve_state( - compiler_type ? compiler_type_resolve_state - : ResolveState::Unresolved), - m_is_complete_objc_class(false) { + m_compiler_type_resolve_state(compiler_type ? compiler_type_resolve_state + : ResolveState::Unresolved) { if (byte_size) { m_byte_size = *byte_size; m_byte_size_has_value = true; @@ -506,7 +504,7 @@ case eEncodingIsTypedefUID: m_compiler_type = encoding_type->GetForwardCompilerType().CreateTypedef( m_name.AsCString("__lldb_invalid_typedef_name"), - GetSymbolFile()->GetDeclContextContainingUID(GetID())); + GetSymbolFile()->GetDeclContextContainingUID(GetID()), m_payload); m_name.Clear(); break; @@ -564,7 +562,7 @@ case eEncodingIsTypedefUID: m_compiler_type = void_compiler_type.CreateTypedef( m_name.AsCString("__lldb_invalid_typedef_name"), - GetSymbolFile()->GetDeclContextContainingUID(GetID())); + GetSymbolFile()->GetDeclContextContainingUID(GetID()), m_payload); break; case eEncodingIsPointerUID: Index: lldb/source/Symbol/TypeSystem.cpp =================================================================== --- lldb/source/Symbol/TypeSystem.cpp +++ lldb/source/Symbol/TypeSystem.cpp @@ -109,7 +109,8 @@ CompilerType TypeSystem::CreateTypedef(lldb::opaque_compiler_type_t type, const char *name, - const CompilerDeclContext &decl_ctx) { + const CompilerDeclContext &decl_ctx, + uint32_t opaque_payload) { return CompilerType(); } Index: lldb/unittests/Symbol/TestTypeSystemClang.cpp =================================================================== --- lldb/unittests/Symbol/TestTypeSystemClang.cpp +++ lldb/unittests/Symbol/TestTypeSystemClang.cpp @@ -258,7 +258,7 @@ EXPECT_TRUE(basic_compiler_type.IsValid()); CompilerType enum_type = - ast.CreateEnumerationType("my_enum", ast.GetTranslationUnitDecl(), + ast.CreateEnumerationType("my_enum", ast.GetTranslationUnitDecl(), 0, Declaration(), basic_compiler_type, scoped); CompilerType t = ast.GetEnumerationIntegerType(enum_type); // Check that the type we put in at the start is found again. @@ -273,7 +273,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, + nullptr, 0, 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 +285,7 @@ TEST_F(TestTypeSystemClang, TestRemoveFastQualifiers) { CompilerType record_type = m_ast->CreateRecordType( - nullptr, lldb::eAccessPublic, "FooRecord", clang::TTK_Struct, + nullptr, 0, lldb::eAccessPublic, "FooRecord", clang::TTK_Struct, lldb::eLanguageTypeC_plus_plus, nullptr); QualType qt; @@ -357,7 +357,7 @@ // Test that a record with no fields returns false CompilerType empty_base = m_ast->CreateRecordType( - nullptr, lldb::eAccessPublic, "EmptyBase", clang::TTK_Struct, + nullptr, 0, lldb::eAccessPublic, "EmptyBase", clang::TTK_Struct, lldb::eLanguageTypeC_plus_plus, nullptr); TypeSystemClang::StartTagDeclarationDefinition(empty_base); TypeSystemClang::CompleteTagDeclarationDefinition(empty_base); @@ -368,7 +368,7 @@ // Test that a record with direct fields returns true CompilerType non_empty_base = m_ast->CreateRecordType( - nullptr, lldb::eAccessPublic, "NonEmptyBase", clang::TTK_Struct, + nullptr, 0, 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 +384,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, + nullptr, 0, lldb::eAccessPublic, "EmptyDerived", clang::TTK_Struct, lldb::eLanguageTypeC_plus_plus, nullptr); TypeSystemClang::StartTagDeclarationDefinition(empty_derived); std::unique_ptr non_empty_base_spec = @@ -407,7 +407,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, + nullptr, 0, lldb::eAccessPublic, "EmptyDerived2", clang::TTK_Struct, lldb::eLanguageTypeC_plus_plus, nullptr); TypeSystemClang::StartTagDeclarationDefinition(empty_derived2); std::unique_ptr non_empty_vbase_spec = @@ -439,13 +439,14 @@ // template struct foo; ClassTemplateDecl *decl = m_ast->CreateClassTemplateDecl( - m_ast->GetTranslationUnitDecl(), eAccessPublic, "foo", TTK_Struct, infos); + m_ast->GetTranslationUnitDecl(), 0, 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->GetTranslationUnitDecl(), 0, decl, TTK_Struct, infos); ASSERT_NE(spec_decl, nullptr); CompilerType type = m_ast->CreateClassTemplateSpecializationType(spec_decl); ASSERT_TRUE(type); @@ -454,7 +455,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->CreateDeclContext(m_ast->GetTranslationUnitDecl()), 0); CompilerType auto_type( m_ast.get(), @@ -529,12 +531,12 @@ CompilerType clang_type = m_ast->CreateFunctionType(int_type, nullptr, 0U, false, 0U); FunctionDecl *func = - m_ast->CreateFunctionDeclaration(TU, "foo", clang_type, 0, false); + m_ast->CreateFunctionDeclaration(TU, 0, "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(TU, 0, func, "foo", empty_params); EXPECT_EQ(TU, func_template->getDeclContext()); EXPECT_EQ("foo", func_template->getName()); @@ -559,12 +561,12 @@ // 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(TU, 0, "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(record, 0, func, "foo", empty_params); EXPECT_EQ(record, func_template->getDeclContext()); EXPECT_EQ("foo", func_template->getName()); Index: lldb/unittests/TestingSupport/Symbol/ClangTestUtils.h =================================================================== --- lldb/unittests/TestingSupport/Symbol/ClangTestUtils.h +++ lldb/unittests/TestingSupport/Symbol/ClangTestUtils.h @@ -27,7 +27,7 @@ } inline CompilerType createRecord(TypeSystemClang &ast, llvm::StringRef name) { - return ast.CreateRecordType(ast.getASTContext().getTranslationUnitDecl(), + return ast.CreateRecordType(ast.getASTContext().getTranslationUnitDecl(), 0, lldb::AccessType::eAccessPublic, name, 0, lldb::LanguageType::eLanguageTypeC); }