Skip to content

Commit 5d0b831

Browse files
committed
[lldb][ExpressionParser][NFC] Implement CompleteRedeclChain APIs
1 parent ac938b4 commit 5d0b831

File tree

5 files changed

+86
-0
lines changed

5 files changed

+86
-0
lines changed

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

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -326,6 +326,45 @@ void ClangASTSource::CompleteType(clang::ObjCInterfaceDecl *interface_decl) {
326326
LLDB_LOG(log, " [COID] {0}", ClangUtil::DumpDecl(interface_decl));
327327
}
328328

329+
void ClangASTSource::CompleteRedeclChain(const Decl *d) {
330+
if (!TypeSystemClang::UseRedeclCompletion())
331+
return;
332+
333+
if (const clang::TagDecl *td = llvm::dyn_cast<TagDecl>(d)) {
334+
if (td->isBeingDefined())
335+
return;
336+
337+
if (td->getDefinition())
338+
return;
339+
340+
m_ast_importer_sp->CompleteTagDecl(const_cast<clang::TagDecl *>(td));
341+
if (!td->getDefinition() && m_ast_importer_sp->GetDeclOrigin(td).Valid()) {
342+
if (TagDecl *alternate = FindCompleteType(td))
343+
m_ast_importer_sp->CompleteTagDeclWithOrigin(
344+
const_cast<clang::TagDecl *>(td), alternate);
345+
}
346+
}
347+
if (const auto *od = llvm::dyn_cast<ObjCInterfaceDecl>(d)) {
348+
ClangASTImporter::DeclOrigin original =
349+
m_ast_importer_sp->GetDeclOrigin(od);
350+
if (ObjCInterfaceDecl *orig =
351+
dyn_cast_or_null<ObjCInterfaceDecl>(original.decl)) {
352+
if (ObjCInterfaceDecl *i = GetCompleteObjCInterface(orig)) {
353+
if (i != orig) {
354+
m_ast_importer_sp->SetDeclOrigin(d, i);
355+
m_ast_importer_sp->CompleteObjCInterfaceDecl(
356+
const_cast<clang::ObjCInterfaceDecl *>(od));
357+
return;
358+
}
359+
}
360+
}
361+
if (od->getDefinition())
362+
return;
363+
m_ast_importer_sp->CompleteObjCInterfaceDecl(
364+
const_cast<clang::ObjCInterfaceDecl *>(od));
365+
}
366+
}
367+
329368
clang::ObjCInterfaceDecl *ClangASTSource::GetCompleteObjCInterface(
330369
const clang::ObjCInterfaceDecl *interface_decl) {
331370
lldb::ProcessSP process(m_target->GetProcessSP());

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

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,19 @@ class ClangASTSource : public ImporterBackedASTSource,
154154
/// The Decl to be completed in place.
155155
void CompleteType(clang::ObjCInterfaceDecl *Class) override;
156156

157+
/// Implements ExternalASTSource::CompleteRedeclChain.
158+
///
159+
/// This function will simply complete \ref D, using
160+
/// its origin to copy the definition if necessary.
161+
/// If the definition for \ref D is on a different
162+
/// Decl, this function will link the two into a
163+
/// declaration chain (this can happen if we found
164+
/// the definition on the origin).
165+
///
166+
/// \param[in] D
167+
/// The Decl to complete.
168+
void CompleteRedeclChain(clang::Decl const *D) override;
169+
157170
/// Called on entering a translation unit. Tells Clang by calling
158171
/// setHasExternalVisibleStorage() and setHasExternalLexicalStorage() that
159172
/// this object has something to say about undefined names.
@@ -232,6 +245,10 @@ class ClangASTSource : public ImporterBackedASTSource,
232245
return m_original.CompleteType(Class);
233246
}
234247

248+
void CompleteRedeclChain(clang::Decl const *D) override {
249+
return m_original.CompleteRedeclChain(D);
250+
}
251+
235252
bool layoutRecordType(
236253
const clang::RecordDecl *Record, uint64_t &Size, uint64_t &Alignment,
237254
llvm::DenseMap<const clang::FieldDecl *, uint64_t> &FieldOffsets,

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

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,25 @@ void ClangExternalASTSourceCallbacks::CompleteType(
2727
m_ast.CompleteObjCInterfaceDecl(objc_decl);
2828
}
2929

30+
void ClangExternalASTSourceCallbacks::CompleteRedeclChain(
31+
const clang::Decl *d) {
32+
if (!TypeSystemClang::UseRedeclCompletion())
33+
return;
34+
35+
if (const clang::TagDecl *td = llvm::dyn_cast<clang::TagDecl>(d)) {
36+
if (td->isBeingDefined())
37+
return;
38+
if (td->getDefinition())
39+
return;
40+
m_ast.CompleteTagDecl(const_cast<clang::TagDecl *>(td));
41+
}
42+
if (const auto *od = llvm::dyn_cast<clang::ObjCInterfaceDecl>(d)) {
43+
if (od->getDefinition())
44+
return;
45+
m_ast.CompleteObjCInterfaceDecl(const_cast<clang::ObjCInterfaceDecl *>(od));
46+
}
47+
}
48+
3049
bool ClangExternalASTSourceCallbacks::layoutRecordType(
3150
const clang::RecordDecl *Record, uint64_t &Size, uint64_t &Alignment,
3251
llvm::DenseMap<const clang::FieldDecl *, uint64_t> &FieldOffsets,

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,8 @@ class ClangExternalASTSourceCallbacks : public ImporterBackedASTSource {
4747

4848
void CompleteType(clang::ObjCInterfaceDecl *objc_decl) override;
4949

50+
void CompleteRedeclChain(clang::Decl const *D) override;
51+
5052
bool layoutRecordType(
5153
const clang::RecordDecl *Record, uint64_t &Size, uint64_t &Alignment,
5254
llvm::DenseMap<const clang::FieldDecl *, uint64_t> &FieldOffsets,

lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCDeclVendor.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,15 @@ class lldb_private::AppleObjCExternalASTSource
109109
}
110110
}
111111

112+
void CompleteRedeclChain(const clang::Decl *d) override {
113+
using namespace clang;
114+
auto *const_interface = llvm::dyn_cast<ObjCInterfaceDecl>(d);
115+
if (!const_interface)
116+
return;
117+
auto *interface = const_cast<ObjCInterfaceDecl *>(const_interface);
118+
m_decl_vendor.FinishDecl(interface);
119+
}
120+
112121
bool layoutRecordType(
113122
const clang::RecordDecl *Record, uint64_t &Size, uint64_t &Alignment,
114123
llvm::DenseMap<const clang::FieldDecl *, uint64_t> &FieldOffsets,

0 commit comments

Comments
 (0)