forked from OSchip/llvm-project
[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
This commit is contained in:
parent
bca13174bc
commit
fa4a0f1d31
|
@ -3486,6 +3486,24 @@ public:
|
|||
/// parameters.
|
||||
bool isDependentType() const { return isDependentContext(); }
|
||||
|
||||
/// Whether this declaration was a definition in some module but was forced
|
||||
/// to be a declaration.
|
||||
///
|
||||
/// Useful for clients checking if a module has a definition of a specific
|
||||
/// symbol and not interested in the final AST with deduplicated definitions.
|
||||
bool isThisDeclarationADemotedDefinition() const {
|
||||
return TagDeclBits.IsThisDeclarationADemotedDefinition;
|
||||
}
|
||||
|
||||
/// Mark a definition as a declaration and maintain information it _was_
|
||||
/// a definition.
|
||||
void demoteThisDefinitionToDeclaration() {
|
||||
assert(isCompleteDefinition() &&
|
||||
"Should demote definitions only, not forward declarations");
|
||||
setCompleteDefinition(false);
|
||||
TagDeclBits.IsThisDeclarationADemotedDefinition = true;
|
||||
}
|
||||
|
||||
/// Starts the definition of this tag declaration.
|
||||
///
|
||||
/// This method should be invoked at the beginning of the definition
|
||||
|
|
|
@ -1443,10 +1443,14 @@ class DeclContext {
|
|||
/// Has the full definition of this type been required by a use somewhere in
|
||||
/// the TU.
|
||||
uint64_t IsCompleteDefinitionRequired : 1;
|
||||
|
||||
/// Whether this tag is a definition which was demoted due to
|
||||
/// a module merge.
|
||||
uint64_t IsThisDeclarationADemotedDefinition : 1;
|
||||
};
|
||||
|
||||
/// Number of non-inherited bits in TagDeclBitfields.
|
||||
enum { NumTagDeclBits = 9 };
|
||||
enum { NumTagDeclBits = 10 };
|
||||
|
||||
/// Stores the bits used by EnumDecl.
|
||||
/// If modified NumEnumDeclBit and the accessor
|
||||
|
|
|
@ -4301,6 +4301,7 @@ TagDecl::TagDecl(Kind DK, TagKind TK, const ASTContext &C, DeclContext *DC,
|
|||
setEmbeddedInDeclarator(false);
|
||||
setFreeStanding(false);
|
||||
setCompleteDefinitionRequired(false);
|
||||
TagDeclBits.IsThisDeclarationADemotedDefinition = false;
|
||||
}
|
||||
|
||||
SourceLocation TagDecl::getOuterLocStart() const {
|
||||
|
|
|
@ -773,7 +773,7 @@ void ASTDeclReader::VisitEnumDecl(EnumDecl *ED) {
|
|||
}
|
||||
if (OldDef) {
|
||||
Reader.MergedDeclContexts.insert(std::make_pair(ED, OldDef));
|
||||
ED->setCompleteDefinition(false);
|
||||
ED->demoteThisDefinitionToDeclaration();
|
||||
Reader.mergeDefinitionVisibility(OldDef, ED);
|
||||
if (OldDef->getODRHash() != ED->getODRHash())
|
||||
Reader.PendingEnumOdrMergeFailures[OldDef].push_back(ED);
|
||||
|
@ -828,7 +828,7 @@ void ASTDeclReader::VisitRecordDecl(RecordDecl *RD) {
|
|||
}
|
||||
if (OldDef) {
|
||||
Reader.MergedDeclContexts.insert(std::make_pair(RD, OldDef));
|
||||
RD->setCompleteDefinition(false);
|
||||
RD->demoteThisDefinitionToDeclaration();
|
||||
Reader.mergeDefinitionVisibility(OldDef, RD);
|
||||
} else {
|
||||
OldDef = RD;
|
||||
|
|
Loading…
Reference in New Issue