aprantl created this revision.
aprantl added reviewers: teemperor, shafik, labath.
Types that came from a Clang module are nested in DW_TAG_module tags in DWARF.
This patch recreates the Clang module hierarchy in LLDB and sets the owning
module information accordingly. My primary motivation is to facilitate looking
up per-module APINotes for individual declarations, but this likely also has
other applications.
The fact that Clang modules are orthogonal to DeclContexts made the
implementation in LLDB challenging. In the end I extended
`lldb_private::CompilerDeclContext` to hold a pair of `clang::DeclContext *`
and `clang::Module *` and made sure to use CompilerDeclContext everywhere in
TypeSystemClang. To save memory for all non-Clang typesystems, the extra data
for the owning module ID is hidden in the CompilerDeclContext's opaque pointer:
If it isn't a raw clang::DeclContext pointer, it is an index into an array of
Module ID + DeclContexts.
https://reviews.llvm.org/D75488
Files:
clang/include/clang/AST/DeclBase.h
clang/include/clang/AST/ExternalASTSource.h
clang/lib/AST/ExternalASTSource.cpp
clang/lib/Serialization/ASTReader.cpp
lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp
lldb/source/Plugins/ExpressionParser/Clang/ClangExternalASTSourceCallbacks.cpp
lldb/source/Plugins/ExpressionParser/Clang/ClangExternalASTSourceCallbacks.h
lldb/source/Plugins/Language/ObjC/NSDictionary.cpp
lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTypeEncodingParser.cpp
lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h
lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.cpp
lldb/source/Plugins/SymbolFile/PDB/PDBASTParser.cpp
lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp
lldb/source/Plugins/SystemRuntime/MacOSX/SystemRuntimeMacOSX.cpp
lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp
lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.h
lldb/test/Shell/SymbolFile/DWARF/owning-module.test
lldb/unittests/Symbol/TestTypeSystemClang.cpp
lldb/unittests/SymbolFile/DWARF/DWARFASTParserClangTests.cpp
lldb/unittests/TestingSupport/Symbol/ClangTestUtils.h
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);
}
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<const clang::DeclContext *> GetDeclContextToDIEMapKeys() {
- std::vector<const clang::DeclContext *> keys;
+ std::vector<CompilerDeclContext> GetDeclContextToDIEMapKeys() {
+ std::vector<CompilerDeclContext> 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<DWARFDIE> dies = {
DWARFDIE(unit, die_child0), DWARFDIE(unit, die_child1),
DWARFDIE(unit, die_child2), DWARFDIE(unit, die_child3)};
- std::vector<clang::DeclContext *> decl_ctxs = {
- (clang::DeclContext *)1LL, (clang::DeclContext *)2LL,
- (clang::DeclContext *)2LL, (clang::DeclContext *)3LL};
+ std::vector<CompilerDeclContext> 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/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<clang::CXXBaseSpecifier> 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<CXXBaseSpecifier> non_empty_vbase_spec =
@@ -439,13 +440,15 @@
// template<typename T, int I> 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<int, 47>
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<int, 47> 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/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/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<CompilerDecl>
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<unsigned,
+ sizeof(unsigned) * CHAR_BIT - 8>;
+ using WrappedPointer = llvm::PointerUnion<clang::DeclContext *, IndexType>;
+ };
+
+ 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<clang::IdentifierTable> m_identifier_table_up;
std::unique_ptr<clang::SelectorTable> m_selector_table_up;
std::unique_ptr<clang::Builtin::Context> m_builtins_up;
+ std::unique_ptr<clang::HeaderSearch> m_header_search_up;
+ std::unique_ptr<clang::ModuleMap> m_module_map_up;
std::unique_ptr<DWARFASTParserClang> m_dwarf_ast_parser_up;
std::unique_ptr<PDBASTParser> m_pdb_ast_parser_up;
std::unique_ptr<clang::MangleContext> m_mangle_ctx_up;
@@ -989,6 +1042,7 @@
/// Useful for logging and debugging.
std::string m_display_name;
+ std::vector<ModuleDeclContext> m_decl_contexts;
typedef llvm::DenseMap<const clang::Decl *, ClangASTMetadata> 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<clang::ObjCInterfaceDecl>(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<ClangExternalASTSourceCallbacks>(
+ 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<clang::HeaderSearchOptions>();
+ m_header_search_up = std::make_unique<clang::HeaderSearch>(
+ 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<clang::ModuleMap>(
+ *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<CXXRecordDecl>(decl_ctx) && exports_symbols)
+ if (isa<CXXRecordDecl>(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<NamedDecl *, 8> 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<clang::ClassTemplateDecl>(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<TagDecl>(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<clang::TemplateArgument, 2> 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<clang::NamespaceDecl>(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<NamespaceDecl>(decl_ctx);
+ NamespaceDecl *parent_namespace_decl =
+ cast<NamespaceDecl>(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<clang::RecordType>())
- tdecl = rt->getDecl();
- if (const clang::EnumType *et = qual_type->getAs<clang::EnumType>())
- 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<clang::RecordType>())
+ tdecl = rt->getDecl();
+ if (const clang::EnumType *et = qual_type->getAs<clang::EnumType>())
+ 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<TypeSystemClang>(dc.GetTypeSystem())
+ ->GetClangDeclContext(dc);
return nullptr;
}
ObjCMethodDecl *
TypeSystemClang::DeclContextGetAsObjCMethodDecl(const CompilerDeclContext &dc) {
- if (IsClangDeclContext(dc))
- return llvm::dyn_cast<clang::ObjCMethodDecl>(
- (clang::DeclContext *)dc.GetOpaqueDeclContext());
- return nullptr;
+ return llvm::dyn_cast_or_null<clang::ObjCMethodDecl>(
+ DeclContextGetAsDeclContext(dc));
}
CXXMethodDecl *
TypeSystemClang::DeclContextGetAsCXXMethodDecl(const CompilerDeclContext &dc) {
- if (IsClangDeclContext(dc))
- return llvm::dyn_cast<clang::CXXMethodDecl>(
- (clang::DeclContext *)dc.GetOpaqueDeclContext());
- return nullptr;
+ return llvm::dyn_cast_or_null<clang::CXXMethodDecl>(
+ DeclContextGetAsDeclContext(dc));
}
clang::FunctionDecl *
TypeSystemClang::DeclContextGetAsFunctionDecl(const CompilerDeclContext &dc) {
- if (IsClangDeclContext(dc))
- return llvm::dyn_cast<clang::FunctionDecl>(
- (clang::DeclContext *)dc.GetOpaqueDeclContext());
- return nullptr;
+ return llvm::dyn_cast_or_null<clang::FunctionDecl>(
+ DeclContextGetAsDeclContext(dc));
}
clang::NamespaceDecl *
TypeSystemClang::DeclContextGetAsNamespaceDecl(const CompilerDeclContext &dc) {
- if (IsClangDeclContext(dc))
- return llvm::dyn_cast<clang::NamespaceDecl>(
- (clang::DeclContext *)dc.GetOpaqueDeclContext());
- return nullptr;
+ return llvm::dyn_cast_or_null<clang::NamespaceDecl>(
+ 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<clang::DeclContext *>()) {
+ auto *ctx = ptr.get<clang::DeclContext *>();
+ assert(!ctx || (&ctx->getParentASTContext() == &getASTContext()));
+ return {ctx, 0};
+ }
+
+ size_t idx = ptr.get<ModuleDeclContext::IndexType>();
+ 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<clang::DeclContext *>(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<clang::DeclContext *>());
+ } 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/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/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/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<clang::ParmVarDecl *> params;
if (std::unique_ptr<PDBSymbolTypeFunctionSig> 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/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/DWARF/DWARFASTParserClang.h
===================================================================
--- lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h
+++ lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h
@@ -74,10 +74,12 @@
typedef std::vector<DelayedAddObjCClassProperty> DelayedPropertyList;
typedef llvm::SmallPtrSet<const DWARFDebugInfoEntry *, 4> DIEPointerSet;
- typedef llvm::DenseMap<const DWARFDebugInfoEntry *, clang::DeclContext *>
+ typedef llvm::DenseMap<const DWARFDebugInfoEntry *,
+ lldb_private::CompilerDeclContext>
DIEToDeclContextMap;
- typedef std::multimap<const clang::DeclContext *, const DWARFDIE>
- DeclContextToDIEMap;
+ typedef llvm::DenseMap<const DWARFDebugInfoEntry *, unsigned>
+ DIEToModuleMap;
+ typedef std::multimap<void *, const DWARFDIE> DeclContextToDIEMap;
typedef llvm::DenseMap<const DWARFDebugInfoEntry *, clang::Decl *>
DIEToDeclMap;
typedef llvm::DenseMap<const clang::Decl *, DIEPointerSet> 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<lldb_private::ClangASTImporter> 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<DWARFDIE> &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<clang::TagDecl>(decl_ctx);
+ auto *tag_decl_ctx = clang::dyn_cast_or_null<clang::TagDecl>(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<void *>(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<Type>(
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<clang::FunctionDecl>(
- 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<Type>(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<CompilerType> &function_param_types,
std::vector<clang::ParmVarDecl *> &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::NamedDecl>(
(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<clang::BlockDecl>(m_die_to_decl_ctx[die.GetDIE()]);
+ clang::BlockDecl *decl = llvm::cast_or_null<clang::BlockDecl>(
+ 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<clang::NamespaceDecl *>(m_die_to_decl_ctx[die.GetDIE()]);
+ clang::NamespaceDecl *namespace_decl = static_cast<clang::NamespaceDecl *>(
+ 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<void *>(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<void *>(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<void *>(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<void *>(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<void *>(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/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/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/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<const clang::CXXRecordDecl *, clang::CharUnits>
&VirtualBaseOffsets) override;
+ unsigned registerModule(clang::Module *module);
+ unsigned getIDForModule(clang::Module *module);
+ TypeSystemClang &GetTypeSystem() const { return m_ast; }
+
+ llvm::Optional<clang::ExternalASTSource::ASTSourceDescriptor>
+ getSourceDescriptor(unsigned ID) override;
+ clang::Module *getModule(unsigned ID) override;
private:
TypeSystemClang &m_ast;
+ std::vector<clang::Module *> m_modules;
+ llvm::DenseMap<clang::Module *, unsigned> 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<clang::ExternalASTSource::ASTSourceDescriptor>
+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/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<clang::DeclContext *>(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: clang/lib/Serialization/ASTReader.cpp
===================================================================
--- clang/lib/Serialization/ASTReader.cpp
+++ clang/lib/Serialization/ASTReader.cpp
@@ -8493,7 +8493,7 @@
llvm::Optional<ExternalASTSource::ASTSourceDescriptor>
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: 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/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/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
_______________________________________________
lldb-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits