Skip to content

Commit 27dcc80

Browse files
committed
[C++20][Modules] Refine the condition of in-place numbering of anonymous members.
1 parent 0e8b642 commit 27dcc80

File tree

3 files changed

+34
-1
lines changed

3 files changed

+34
-1
lines changed

clang/include/clang/AST/Decl.h

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4521,6 +4521,23 @@ class RecordDecl : public TagDecl {
45214521
return field_begin() == field_end();
45224522
}
45234523

4524+
/// noload_fields - Iterate over the fields stored in this record
4525+
/// that are currently loaded; don't attempt to retrieve anything
4526+
/// from an external source.
4527+
field_range noload_fields() const {
4528+
return field_range(noload_field_begin(), noload_field_end());
4529+
}
4530+
4531+
field_iterator noload_field_begin() const;
4532+
field_iterator noload_field_end() const {
4533+
return field_iterator(decl_iterator());
4534+
}
4535+
4536+
// Whether there are any fields (non-static data members) in this record.
4537+
bool noload_field_empty() const {
4538+
return noload_field_begin() == noload_field_end();
4539+
}
4540+
45244541
/// Note that the definition of this type is now complete.
45254542
virtual void completeDefinition();
45264543

clang/lib/AST/Decl.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5161,6 +5161,10 @@ RecordDecl::field_iterator RecordDecl::field_begin() const {
51615161
return field_iterator(decl_iterator(FirstDecl));
51625162
}
51635163

5164+
RecordDecl::field_iterator RecordDecl::noload_field_begin() const {
5165+
return field_iterator(decl_iterator(getDefinitionOrSelf()->FirstDecl));
5166+
}
5167+
51645168
/// completeDefinition - Notes that the definition of this type is now
51655169
/// complete.
51665170
void RecordDecl::completeDefinition() {

clang/lib/Serialization/ASTReaderDecl.cpp

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3432,7 +3432,19 @@ NamedDecl *ASTDeclReader::getAnonymousDeclForMerging(ASTReader &Reader,
34323432
// If this is the first time, but we have parsed a declaration of the context,
34333433
// build the anonymous declaration list from the parsed declaration.
34343434
auto *PrimaryDC = getPrimaryDCForAnonymousDecl(DC);
3435-
if (PrimaryDC && !cast<Decl>(PrimaryDC)->isFromASTFile()) {
3435+
auto needToNumberAnonymousDeclsWithin = [](Decl *D) {
3436+
if (!D->isFromASTFile())
3437+
return true;
3438+
// If this is a class template specialization from an AST file, has at least
3439+
// one field, but none of the fields have been loaded from external storage,
3440+
// this is a situation where the class template specialization decl
3441+
// was imported but the definition was instantiated within the source.
3442+
// In such a case, we still need to number the anonymous decls.
3443+
auto *CTSD = dyn_cast<ClassTemplateSpecializationDecl>(D);
3444+
return CTSD && !CTSD->noload_field_empty() &&
3445+
!CTSD->hasLoadedFieldsFromExternalStorage();
3446+
};
3447+
if (PrimaryDC && needToNumberAnonymousDeclsWithin(cast<Decl>(PrimaryDC))) {
34363448
numberAnonymousDeclsWithin(PrimaryDC, [&](NamedDecl *ND, unsigned Number) {
34373449
if (Previous.size() == Number)
34383450
Previous.push_back(cast<NamedDecl>(ND->getCanonicalDecl()));

0 commit comments

Comments
 (0)