Skip to content

Commit fa4a0f1

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://84677782 Differential Revision: https://reviews.llvm.org/D118855
1 parent bca1317 commit fa4a0f1

File tree

4 files changed

+26
-3
lines changed

4 files changed

+26
-3
lines changed

clang/include/clang/AST/Decl.h

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3486,6 +3486,24 @@ class TagDecl : public TypeDecl,
34863486
/// parameters.
34873487
bool isDependentType() const { return isDependentContext(); }
34883488

3489+
/// Whether this declaration was a definition in some module but was forced
3490+
/// to be a declaration.
3491+
///
3492+
/// Useful for clients checking if a module has a definition of a specific
3493+
/// symbol and not interested in the final AST with deduplicated definitions.
3494+
bool isThisDeclarationADemotedDefinition() const {
3495+
return TagDeclBits.IsThisDeclarationADemotedDefinition;
3496+
}
3497+
3498+
/// Mark a definition as a declaration and maintain information it _was_
3499+
/// a definition.
3500+
void demoteThisDefinitionToDeclaration() {
3501+
assert(isCompleteDefinition() &&
3502+
"Should demote definitions only, not forward declarations");
3503+
setCompleteDefinition(false);
3504+
TagDeclBits.IsThisDeclarationADemotedDefinition = true;
3505+
}
3506+
34893507
/// Starts the definition of this tag declaration.
34903508
///
34913509
/// 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
@@ -1443,10 +1443,14 @@ class DeclContext {
14431443
/// Has the full definition of this type been required by a use somewhere in
14441444
/// the TU.
14451445
uint64_t IsCompleteDefinitionRequired : 1;
1446+
1447+
/// Whether this tag is a definition which was demoted due to
1448+
/// a module merge.
1449+
uint64_t IsThisDeclarationADemotedDefinition : 1;
14461450
};
14471451

14481452
/// Number of non-inherited bits in TagDeclBitfields.
1449-
enum { NumTagDeclBits = 9 };
1453+
enum { NumTagDeclBits = 10 };
14501454

14511455
/// Stores the bits used by EnumDecl.
14521456
/// 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
@@ -4301,6 +4301,7 @@ TagDecl::TagDecl(Kind DK, TagKind TK, const ASTContext &C, DeclContext *DC,
43014301
setEmbeddedInDeclarator(false);
43024302
setFreeStanding(false);
43034303
setCompleteDefinitionRequired(false);
4304+
TagDeclBits.IsThisDeclarationADemotedDefinition = false;
43044305
}
43054306

43064307
SourceLocation TagDecl::getOuterLocStart() const {

clang/lib/Serialization/ASTReaderDecl.cpp

Lines changed: 2 additions & 2 deletions
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);
@@ -828,7 +828,7 @@ void ASTDeclReader::VisitRecordDecl(RecordDecl *RD) {
828828
}
829829
if (OldDef) {
830830
Reader.MergedDeclContexts.insert(std::make_pair(RD, OldDef));
831-
RD->setCompleteDefinition(false);
831+
RD->demoteThisDefinitionToDeclaration();
832832
Reader.mergeDefinitionVisibility(OldDef, RD);
833833
} else {
834834
OldDef = RD;

0 commit comments

Comments
 (0)