Skip to content

Commit 3c58b0f

Browse files
committed
Preserve the owning module information from DWARF in the synthesized AST
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 1;95;0csets 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. This reapplies the previously reverted commit, but without support for ClassTemplateSpecializations, which I'm going to look into separately. rdar://problem/59634380 Differential Revision: https://reviews.llvm.org/D75488 (cherry picked from commit 143d507)
1 parent 06f3f4b commit 3c58b0f

File tree

25 files changed

+576
-175
lines changed

25 files changed

+576
-175
lines changed

Diff for: lldb/include/lldb/Symbol/CompilerType.h

+6-4
Original file line numberDiff line numberDiff line change
@@ -237,11 +237,13 @@ class CompilerType {
237237
// an invalid type.
238238
CompilerType AddRestrictModifier() const;
239239

240-
// Create a typedef to this type using "name" as the name of the typedef this
241-
// type is valid and the type system supports typedefs, else return an
242-
// invalid type.
240+
/// Create a typedef to this type using "name" as the name of the typedef this
241+
/// type is valid and the type system supports typedefs, else return an
242+
/// invalid type.
243+
/// \param payload The typesystem-specific \p lldb::Type payload.
243244
CompilerType CreateTypedef(const char *name,
244-
const CompilerDeclContext &decl_ctx) const;
245+
const CompilerDeclContext &decl_ctx,
246+
uint32_t payload) const;
245247

246248
// If the current object represents a typedef type, get the underlying type
247249
CompilerType GetTypedefedType() const;

Diff for: lldb/include/lldb/Symbol/TypeSystem.h

+4-1
Original file line numberDiff line numberDiff line change
@@ -259,9 +259,12 @@ class TypeSystem : public PluginInterface {
259259

260260
virtual CompilerType AddRestrictModifier(lldb::opaque_compiler_type_t type);
261261

262+
/// \param opaque_payload The m_payload field of Type, which may
263+
/// carry TypeSystem-specific extra information.
262264
virtual CompilerType CreateTypedef(lldb::opaque_compiler_type_t type,
263265
const char *name,
264-
const CompilerDeclContext &decl_ctx);
266+
const CompilerDeclContext &decl_ctx,
267+
uint32_t opaque_payload);
265268

266269
// Exploring the type
267270

Diff for: lldb/source/Plugins/ExpressionParser/Clang/ClangASTImporter.cpp

+30
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818

1919
#include "Plugins/ExpressionParser/Clang/ClangASTImporter.h"
2020
#include "Plugins/ExpressionParser/Clang/ClangASTMetadata.h"
21+
#include "Plugins/ExpressionParser/Clang/ClangExternalASTSourceCallbacks.h"
2122
#include "Plugins/ExpressionParser/Clang/ClangUtil.h"
2223
#include "Plugins/TypeSystem/Clang/TypeSystemClang.h"
2324

@@ -1005,6 +1006,21 @@ void ClangASTImporter::ASTImporterDelegate::ImportDefinitionTo(
10051006
}
10061007
}
10071008

1009+
/// Recreate a module with its parents in \p to_source and return its id.
1010+
static OptionalClangModuleID
1011+
RemapModule(OptionalClangModuleID from_id,
1012+
ClangExternalASTSourceCallbacks &from_source,
1013+
ClangExternalASTSourceCallbacks &to_source) {
1014+
if (!from_id.HasValue())
1015+
return {};
1016+
clang::Module *module = from_source.getModule(from_id.GetValue());
1017+
OptionalClangModuleID parent = RemapModule(
1018+
from_source.GetIDForModule(module->Parent), from_source, to_source);
1019+
TypeSystemClang &to_ts = to_source.GetTypeSystem();
1020+
return to_ts.GetOrCreateClangModule(module->Name, parent, module->IsFramework,
1021+
module->IsExplicit);
1022+
}
1023+
10081024
void ClangASTImporter::ASTImporterDelegate::Imported(clang::Decl *from,
10091025
clang::Decl *to) {
10101026
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
@@ -1014,6 +1030,20 @@ void ClangASTImporter::ASTImporterDelegate::Imported(clang::Decl *from,
10141030
if (m_decls_to_ignore.find(to) != m_decls_to_ignore.end())
10151031
return clang::ASTImporter::Imported(from, to);
10161032

1033+
// Transfer module ownership information.
1034+
auto *from_source = llvm::dyn_cast_or_null<ClangExternalASTSourceCallbacks>(
1035+
getFromContext().getExternalSource());
1036+
// Can also be a ClangASTSourceProxy.
1037+
auto *to_source = llvm::dyn_cast_or_null<ClangExternalASTSourceCallbacks>(
1038+
getToContext().getExternalSource());
1039+
if (from_source && to_source) {
1040+
OptionalClangModuleID from_id(from->getOwningModuleID());
1041+
OptionalClangModuleID to_id =
1042+
RemapModule(from_id, *from_source, *to_source);
1043+
TypeSystemClang &to_ts = to_source->GetTypeSystem();
1044+
to_ts.SetOwningModule(to, to_id);
1045+
}
1046+
10171047
lldb::user_id_t user_id = LLDB_INVALID_UID;
10181048
ClangASTMetadata *metadata = m_master.GetDeclMetadata(from);
10191049
if (metadata)

Diff for: lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -1017,7 +1017,7 @@ void ClangExpressionDeclMap::LookupLocalVarNamespace(
10171017

10181018
clang::NamespaceDecl *namespace_decl =
10191019
m_clang_ast_context->GetUniqueNamespaceDeclaration(
1020-
g_lldb_local_vars_namespace_cstr, nullptr);
1020+
g_lldb_local_vars_namespace_cstr, nullptr, OptionalClangModuleID());
10211021
if (!namespace_decl)
10221022
return;
10231023

Diff for: lldb/source/Plugins/ExpressionParser/Clang/ClangExternalASTSourceCallbacks.cpp

+28
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@
1313

1414
using namespace lldb_private;
1515

16+
char ClangExternalASTSourceCallbacks::ID;
17+
1618
void ClangExternalASTSourceCallbacks::CompleteType(clang::TagDecl *tag_decl) {
1719
m_ast.CompleteTagDecl(tag_decl);
1820
}
@@ -43,3 +45,29 @@ void ClangExternalASTSourceCallbacks::FindExternalLexicalDecls(
4345
CompleteType(tag_decl);
4446
}
4547
}
48+
49+
OptionalClangModuleID
50+
ClangExternalASTSourceCallbacks::RegisterModule(clang::Module *module) {
51+
m_modules.push_back(module);
52+
unsigned id = m_modules.size();
53+
m_ids.insert({module, id});
54+
return OptionalClangModuleID(id);
55+
}
56+
57+
llvm::Optional<clang::ExternalASTSource::ASTSourceDescriptor>
58+
ClangExternalASTSourceCallbacks::getSourceDescriptor(unsigned id) {
59+
if (clang::Module *module = getModule(id))
60+
return {*module};
61+
return {};
62+
}
63+
64+
clang::Module *ClangExternalASTSourceCallbacks::getModule(unsigned id) {
65+
if (id && id <= m_modules.size())
66+
return m_modules[id - 1];
67+
return nullptr;
68+
}
69+
70+
OptionalClangModuleID
71+
ClangExternalASTSourceCallbacks::GetIDForModule(clang::Module *module) {
72+
return OptionalClangModuleID(m_ids[module]);
73+
}

Diff for: lldb/source/Plugins/ExpressionParser/Clang/ClangExternalASTSourceCallbacks.h

+20-3
Original file line numberDiff line numberDiff line change
@@ -10,14 +10,19 @@
1010
#define liblldb_ClangExternalASTSourceCallbacks_h_
1111

1212
#include "Plugins/TypeSystem/Clang/TypeSystemClang.h"
13-
#include "clang/AST/ExternalASTSource.h"
13+
#include "clang/Basic/Module.h"
1414

1515
namespace lldb_private {
1616

17-
class TypeSystemClang;
18-
1917
class ClangExternalASTSourceCallbacks : public clang::ExternalASTSource {
18+
/// LLVM RTTI support.
19+
static char ID;
20+
2021
public:
22+
/// LLVM RTTI support.
23+
bool isA(const void *ClassID) const override { return ClassID == &ID; }
24+
static bool classof(const clang::ExternalASTSource *s) { return s->isA(&ID); }
25+
2126
ClangExternalASTSourceCallbacks(TypeSystemClang &ast) : m_ast(ast) {}
2227

2328
void FindExternalLexicalDecls(
@@ -37,8 +42,20 @@ class ClangExternalASTSourceCallbacks : public clang::ExternalASTSource {
3742
llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits>
3843
&VirtualBaseOffsets) override;
3944

45+
TypeSystemClang &GetTypeSystem() const { return m_ast; }
46+
47+
/// Module-related methods.
48+
/// \{
49+
llvm::Optional<clang::ExternalASTSource::ASTSourceDescriptor>
50+
getSourceDescriptor(unsigned ID) override;
51+
clang::Module *getModule(unsigned ID) override;
52+
OptionalClangModuleID RegisterModule(clang::Module *module);
53+
OptionalClangModuleID GetIDForModule(clang::Module *module);
54+
/// \}
4055
private:
4156
TypeSystemClang &m_ast;
57+
std::vector<clang::Module *> m_modules;
58+
llvm::DenseMap<clang::Module *, unsigned> m_ids;
4259
};
4360

4461
} // namespace lldb_private

Diff for: lldb/source/Plugins/Language/ObjC/NSDictionary.cpp

+3-2
Original file line numberDiff line numberDiff line change
@@ -76,8 +76,9 @@ static CompilerType GetLLDBNSPairType(TargetSP target_sp) {
7676

7777
if (!compiler_type) {
7878
compiler_type = target_ast_context->CreateRecordType(
79-
nullptr, lldb::eAccessPublic, g___lldb_autogen_nspair.GetCString(),
80-
clang::TTK_Struct, lldb::eLanguageTypeC);
79+
nullptr, OptionalClangModuleID(), lldb::eAccessPublic,
80+
g___lldb_autogen_nspair.GetCString(), clang::TTK_Struct,
81+
lldb::eLanguageTypeC);
8182

8283
if (compiler_type) {
8384
TypeSystemClang::StartTagDeclarationDefinition(compiler_type);

Diff for: lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTypeEncodingParser.cpp

+2-1
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,8 @@ clang::QualType AppleObjCTypeEncodingParser::BuildAggregate(
123123
return clang::QualType(); // This is where we bail out. Sorry!
124124

125125
CompilerType union_type(ast_ctx.CreateRecordType(
126-
nullptr, lldb::eAccessPublic, name, kind, lldb::eLanguageTypeC));
126+
nullptr, OptionalClangModuleID(), lldb::eAccessPublic, name, kind,
127+
lldb::eLanguageTypeC));
127128
if (union_type) {
128129
TypeSystemClang::StartTagDeclarationDefinition(union_type);
129130

0 commit comments

Comments
 (0)