Skip to content

Commit 5757ac6

Browse files
committed
[lldb] Make TypeSystemClang work with redeclarations
This patch is a part of D101950 which makes LLDB use redeclarations in its internal clang ASTs. This patch does the following: Add an API that allows redeclaring a declaration inside a TypeSystemClang. Make the TypeSystemClang APIs work with redeclarations. Mainly making sure we look at redeclarations of DeclContext (see the added calls to getPrimaryContext which for example finds the definition of a class. See also the test for nested types) Removes code that assumes a 1-1 mapping between Type and Decl (which is no longer true for redeclarations). The biggest offender here are the APIs for creating classes/templates/etc. as they return all CompilerType (which doesn't identify a unique Decl, but only a redeclaration chain). Removed code that tries to eagerly create types for declarations. Types should be created via GetTypeForDecl so that existing types from forward declarations are reused. Otherwise we end up with The patch also makes that we store the TemplateParameterInfos for template specializations in the TypeSystemClang. The only reason for this is that Clang is using a different data structure for storing this info internally so we can't just reuse the information from the forward declaration when creating the redeclaration (see CreateRedeclaration). This can be removed once we updated the DWARF parser and the TypeSystemClang APIs to accept the information as we can find it in the Clang AST. This shouldn't affect LLDB's functionality on its own as the DWARF parser currently doesn't create redeclarations. That's why all the tests are unit tests. The added logic for looking for the right redeclaration should work as before in ASTs that only have single-decl redeclaration chains (which is what we currently do).
1 parent 61b1a13 commit 5757ac6

File tree

11 files changed

+597
-26
lines changed

11 files changed

+597
-26
lines changed

lldb/source/Plugins/ExpressionParser/Clang/ClangASTImporter.cpp

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -295,6 +295,7 @@ class CompleteTagDeclsScope : public ClangASTImporter::NewDeclListener {
295295
// Filter out decls that we can't complete later.
296296
if (!isa<TagDecl>(to) && !isa<ObjCInterfaceDecl>(to))
297297
return;
298+
298299
RecordDecl *from_record_decl = dyn_cast<RecordDecl>(from);
299300
// We don't need to complete injected class name decls.
300301
if (from_record_decl && from_record_decl->isInjectedClassName())
@@ -757,6 +758,9 @@ bool ClangASTImporter::LayoutRecordType(
757758
&base_offsets,
758759
llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits>
759760
&vbase_offsets) {
761+
762+
record_decl = llvm::cast<RecordDecl>(record_decl->getFirstDecl());
763+
760764
RecordDeclToLayoutMap::iterator pos =
761765
m_record_decl_to_layout_map.find(record_decl);
762766
base_offsets.clear();
@@ -788,6 +792,7 @@ bool ClangASTImporter::LayoutRecordType(
788792

789793
void ClangASTImporter::SetRecordLayout(clang::RecordDecl *decl,
790794
const LayoutInfo &layout) {
795+
decl = llvm::cast<RecordDecl>(decl->getFirstDecl());
791796
assert(!HasRecordLayout(decl) && "Trying to overwrite layout?");
792797
m_record_decl_to_layout_map.insert(std::make_pair(decl, layout));
793798
}
@@ -819,7 +824,10 @@ bool ClangASTImporter::CompleteTagDecl(clang::TagDecl *decl) {
819824

820825
bool ClangASTImporter::CompleteTagDeclWithOrigin(clang::TagDecl *decl,
821826
clang::TagDecl *origin_decl) {
822-
SetDeclOrigin(decl, origin_decl);
827+
if (!origin_decl->getDefinition())
828+
return false;
829+
830+
SetDeclOrigin(decl, origin_decl->getFirstDecl());
823831
return CompleteTagDecl(decl);
824832
}
825833

lldb/source/Plugins/ExpressionParser/Clang/ClangASTImporter.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -175,6 +175,8 @@ class ClangASTImporter {
175175

176176
bool CompleteTagDecl(clang::TagDecl *decl);
177177

178+
/// This function assumes origin has been completed (i.e., has a valid
179+
/// definition).
178180
bool CompleteTagDeclWithOrigin(clang::TagDecl *decl, clang::TagDecl *origin);
179181

180182
bool CompleteObjCInterfaceDecl(clang::ObjCInterfaceDecl *interface_decl);

lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -281,8 +281,11 @@ void ClangASTSource::CompleteType(TagDecl *tag_decl) {
281281
if (!m_ast_importer_sp->CompleteTagDecl(tag_decl)) {
282282
// We couldn't complete the type. Maybe there's a definition somewhere
283283
// else that can be completed.
284-
if (TagDecl *alternate = FindCompleteType(tag_decl))
284+
if (TagDecl *alternate = FindCompleteType(tag_decl)) {
285+
assert(alternate->getDefinition() != nullptr &&
286+
"Trying to complete a TagDecl from an incomplete origin");
285287
m_ast_importer_sp->CompleteTagDeclWithOrigin(tag_decl, alternate);
288+
}
286289
}
287290

288291
LLDB_LOG(log, " [CTD] After:\n{0}", ClangUtil::DumpDecl(tag_decl));

lldb/source/Plugins/ExpressionParser/Clang/ClangUtil.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010

1111
#include "Plugins/ExpressionParser/Clang/ClangUtil.h"
1212
#include "Plugins/TypeSystem/Clang/TypeSystemClang.h"
13+
#include "clang/AST/DeclObjC.h"
1314

1415
using namespace clang;
1516
using namespace lldb_private;
@@ -65,6 +66,16 @@ clang::TagDecl *ClangUtil::GetAsTagDecl(const CompilerType &type) {
6566
return qual_type->getAsTagDecl();
6667
}
6768

69+
clang::Decl *ClangUtil::GetFirstDecl(clang::Decl *d) {
70+
if (!d)
71+
return nullptr;
72+
if (auto *td = llvm::dyn_cast<clang::TagDecl>(d))
73+
return td->getFirstDecl();
74+
if (auto *od = llvm::dyn_cast<clang::ObjCInterfaceDecl>(d))
75+
return od->getFirstDecl();
76+
return d;
77+
}
78+
6879
std::string ClangUtil::DumpDecl(const clang::Decl *d) {
6980
if (!d)
7081
return "nullptr";

lldb/source/Plugins/ExpressionParser/Clang/ClangUtil.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,15 @@ struct ClangUtil {
3636

3737
static clang::TagDecl *GetAsTagDecl(const CompilerType &type);
3838

39+
/// If the given Decl is redeclarable, return the first declaration in its
40+
/// redeclaration chain. Otherwise return d itself.
41+
static clang::Decl *GetFirstDecl(clang::Decl *d);
42+
43+
/// \see ClangUtil::GetFirstDecl
44+
static const clang::Decl *GetFirstDecl(const clang::Decl *d) {
45+
return GetFirstDecl(const_cast<clang::Decl *>(d));
46+
}
47+
3948
/// Returns a textual representation of the given Decl's AST. Does not
4049
/// deserialize any child nodes.
4150
static std::string DumpDecl(const clang::Decl *d);

0 commit comments

Comments
 (0)