Skip to content

Commit 09e785f

Browse files
committed
[modules] Add a flag for TagDecl if it was a definition demoted to a declaration.
For redeclaration chains we maintain an invariant of having only a single definition in the chain. In a single translation unit we make sure not to create duplicates. But modules are separate translation units and they can contain definitions for the same symbol independently. When we load such modules together, we need to demote duplicate definitions to keep the AST invariants. Some AST clients are interested in distinguishing declaration-that-was-demoted-from-definition and declaration-that-was-never-a-definition. For that purpose introducing `IsThisDeclarationADemotedDefinition`. No functional change intended. rdar://80184238
1 parent f42dcac commit 09e785f

File tree

4 files changed

+24
-2
lines changed

4 files changed

+24
-2
lines changed

clang/include/clang/AST/Decl.h

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3483,6 +3483,23 @@ class TagDecl : public TypeDecl,
34833483
/// parameters.
34843484
bool isDependentType() const { return isDependentContext(); }
34853485

3486+
/// Whether this declaration was a definition in some module but was forced
3487+
/// to be a declaration.
3488+
///
3489+
/// Useful for clients checking if a module has a definition of a specific
3490+
/// symbol and not interested in the final AST with deduplicated definitions.
3491+
bool isThisDeclarationADemotedDefinition() const {
3492+
return TagDeclBits.IsThisDeclarationADemotedDefinition;
3493+
}
3494+
3495+
/// Mark a definition as a declaration and maintain information it _was_
3496+
/// a definition.
3497+
void demoteThisDefinitionToDeclaration() {
3498+
assert(isCompleteDefinition() && "Not a definition!");
3499+
setCompleteDefinition(false);
3500+
TagDeclBits.IsThisDeclarationADemotedDefinition = true;
3501+
}
3502+
34863503
/// Starts the definition of this tag declaration.
34873504
///
34883505
/// This method should be invoked at the beginning of the definition

clang/include/clang/AST/DeclBase.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1435,10 +1435,14 @@ class DeclContext {
14351435
/// Has the full definition of this type been required by a use somewhere in
14361436
/// the TU.
14371437
uint64_t IsCompleteDefinitionRequired : 1;
1438+
1439+
/// Whether this tag is a definition which was demoted due to
1440+
/// a module merge.
1441+
uint64_t IsThisDeclarationADemotedDefinition : 1;
14381442
};
14391443

14401444
/// Number of non-inherited bits in TagDeclBitfields.
1441-
enum { NumTagDeclBits = 9 };
1445+
enum { NumTagDeclBits = 10 };
14421446

14431447
/// Stores the bits used by EnumDecl.
14441448
/// If modified NumEnumDeclBit and the accessor

clang/lib/AST/Decl.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4293,6 +4293,7 @@ TagDecl::TagDecl(Kind DK, TagKind TK, const ASTContext &C, DeclContext *DC,
42934293
setEmbeddedInDeclarator(false);
42944294
setFreeStanding(false);
42954295
setCompleteDefinitionRequired(false);
4296+
TagDeclBits.IsThisDeclarationADemotedDefinition = false;
42964297
}
42974298

42984299
SourceLocation TagDecl::getOuterLocStart() const {

clang/lib/Serialization/ASTReaderDecl.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -773,7 +773,7 @@ void ASTDeclReader::VisitEnumDecl(EnumDecl *ED) {
773773
}
774774
if (OldDef) {
775775
Reader.MergedDeclContexts.insert(std::make_pair(ED, OldDef));
776-
ED->setCompleteDefinition(false);
776+
ED->demoteThisDefinitionToDeclaration();
777777
Reader.mergeDefinitionVisibility(OldDef, ED);
778778
if (OldDef->getODRHash() != ED->getODRHash())
779779
Reader.PendingEnumOdrMergeFailures[OldDef].push_back(ED);

0 commit comments

Comments
 (0)