summaryrefslogtreecommitdiff
path: root/clang/lib/Serialization/ASTWriterDecl.cpp
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2024-07-26 22:04:10 +0000
committerDimitry Andric <dim@FreeBSD.org>2024-07-26 22:04:10 +0000
commitac9a064cb179f3425b310fa2847f8764ac970a4d (patch)
tree6f945cdaa68c2b4c688dcf9fec4f922d35f4d1a4 /clang/lib/Serialization/ASTWriterDecl.cpp
parent4df029cc74e5ec124f14a5682e44999ce4f086df (diff)
Vendor import of llvm-project main llvmorg-19-init-18630-gf2ccf80136a0,vendor/llvm-project/llvmorg-19-init-18630-gf2ccf80136a0
the last commit before the upstream release/19.x branch was created.
Diffstat (limited to 'clang/lib/Serialization/ASTWriterDecl.cpp')
-rw-r--r--clang/lib/Serialization/ASTWriterDecl.cpp169
1 files changed, 129 insertions, 40 deletions
diff --git a/clang/lib/Serialization/ASTWriterDecl.cpp b/clang/lib/Serialization/ASTWriterDecl.cpp
index bb1f51786d28..17c774038571 100644
--- a/clang/lib/Serialization/ASTWriterDecl.cpp
+++ b/clang/lib/Serialization/ASTWriterDecl.cpp
@@ -40,11 +40,14 @@ namespace clang {
serialization::DeclCode Code;
unsigned AbbrevToUse;
+ bool GeneratingReducedBMI = false;
+
public:
ASTDeclWriter(ASTWriter &Writer, ASTContext &Context,
- ASTWriter::RecordDataImpl &Record)
+ ASTWriter::RecordDataImpl &Record, bool GeneratingReducedBMI)
: Writer(Writer), Context(Context), Record(Writer, Record),
- Code((serialization::DeclCode)0), AbbrevToUse(0) {}
+ Code((serialization::DeclCode)0), AbbrevToUse(0),
+ GeneratingReducedBMI(GeneratingReducedBMI) {}
uint64_t Emit(Decl *D) {
if (!Code)
@@ -220,9 +223,9 @@ namespace clang {
assert(!Common->LazySpecializations);
}
- ArrayRef<DeclID> LazySpecializations;
+ ArrayRef<GlobalDeclID> LazySpecializations;
if (auto *LS = Common->LazySpecializations)
- LazySpecializations = llvm::ArrayRef(LS + 1, LS[0]);
+ LazySpecializations = llvm::ArrayRef(LS + 1, LS[0].getRawValue());
// Add a slot to the record for the number of specializations.
unsigned I = Record.size();
@@ -240,7 +243,9 @@ namespace clang {
assert(D->isCanonicalDecl() && "non-canonical decl in set");
AddFirstDeclFromEachModule(D, /*IncludeLocal*/true);
}
- Record.append(LazySpecializations.begin(), LazySpecializations.end());
+ Record.append(
+ DeclIDIterator<GlobalDeclID, DeclID>(LazySpecializations.begin()),
+ DeclIDIterator<GlobalDeclID, DeclID>(LazySpecializations.end()));
// Update the size entry we added earlier.
Record[I] = Record.size() - I - 1;
@@ -270,6 +275,34 @@ namespace clang {
};
}
+bool clang::CanElideDeclDef(const Decl *D) {
+ if (auto *FD = dyn_cast<FunctionDecl>(D)) {
+ if (FD->isInlined() || FD->isConstexpr())
+ return false;
+
+ if (FD->isDependentContext())
+ return false;
+
+ if (FD->getTemplateSpecializationKind() == TSK_ImplicitInstantiation)
+ return false;
+ }
+
+ if (auto *VD = dyn_cast<VarDecl>(D)) {
+ if (!VD->getDeclContext()->getRedeclContext()->isFileContext() ||
+ VD->isInline() || VD->isConstexpr() || isa<ParmVarDecl>(VD) ||
+ // Constant initialized variable may not affect the ABI, but they
+ // may be used in constant evaluation in the frontend, so we have
+ // to remain them.
+ VD->hasConstantInitialization())
+ return false;
+
+ if (VD->getTemplateSpecializationKind() == TSK_ImplicitInstantiation)
+ return false;
+ }
+
+ return true;
+}
+
void ASTDeclWriter::Visit(Decl *D) {
DeclVisitor<ASTDeclWriter>::Visit(D);
@@ -285,9 +318,12 @@ void ASTDeclWriter::Visit(Decl *D) {
// have been written. We want it last because we will not read it back when
// retrieving it from the AST, we'll just lazily set the offset.
if (auto *FD = dyn_cast<FunctionDecl>(D)) {
- Record.push_back(FD->doesThisDeclarationHaveABody());
- if (FD->doesThisDeclarationHaveABody())
- Record.AddFunctionDefinition(FD);
+ if (!GeneratingReducedBMI || !CanElideDeclDef(FD)) {
+ Record.push_back(FD->doesThisDeclarationHaveABody());
+ if (FD->doesThisDeclarationHaveABody())
+ Record.AddFunctionDefinition(FD);
+ } else
+ Record.push_back(0);
}
// Similar to FunctionDecls, handle VarDecl's initializer here and write it
@@ -295,7 +331,10 @@ void ASTDeclWriter::Visit(Decl *D) {
// we have finished recursive deserialization, because it can recursively
// refer back to the variable.
if (auto *VD = dyn_cast<VarDecl>(D)) {
- Record.AddVarDeclInit(VD);
+ if (!GeneratingReducedBMI || !CanElideDeclDef(VD))
+ Record.AddVarDeclInit(VD);
+ else
+ Record.push_back(0);
}
// And similarly for FieldDecls. We already serialized whether there is a
@@ -703,8 +742,15 @@ void ASTDeclWriter::VisitFunctionDecl(FunctionDecl *D) {
Record.push_back(D->getODRHash());
- if (D->isDefaulted()) {
- if (auto *FDI = D->getDefaultedFunctionInfo()) {
+ if (D->isDefaulted() || D->isDeletedAsWritten()) {
+ if (auto *FDI = D->getDefalutedOrDeletedInfo()) {
+ // Store both that there is an DefaultedOrDeletedInfo and whether it
+ // contains a DeletedMessage.
+ StringLiteral *DeletedMessage = FDI->getDeletedMessage();
+ Record.push_back(1 | (DeletedMessage ? 2 : 0));
+ if (DeletedMessage)
+ Record.AddStmt(DeletedMessage);
+
Record.push_back(FDI->getUnqualifiedLookups().size());
for (DeclAccessPair P : FDI->getUnqualifiedLookups()) {
Record.AddDeclRef(P.getDecl());
@@ -1114,7 +1160,7 @@ void ASTDeclWriter::VisitVarDecl(VarDecl *D) {
Record.push_back(VarDeclBits);
if (ModulesCodegen)
- Writer.ModularCodegenDecls.push_back(Writer.GetDeclRef(D));
+ Writer.AddDeclRef(D, Writer.ModularCodegenDecls);
if (D->hasAttr<BlocksAttr>()) {
BlockVarCopyInit Init = Writer.Context->getBlockVarCopyInit(D);
@@ -1329,7 +1375,7 @@ void ASTDeclWriter::VisitNamespaceDecl(NamespaceDecl *D) {
Record.AddSourceLocation(D->getBeginLoc());
Record.AddSourceLocation(D->getRBraceLoc());
- if (D->isOriginalNamespace())
+ if (D->isFirstDecl())
Record.AddDeclRef(D->getAnonymousNamespace());
Code = serialization::DECL_NAMESPACE;
@@ -1672,6 +1718,15 @@ void ASTDeclWriter::VisitClassTemplateDecl(ClassTemplateDecl *D) {
if (D->isFirstDecl())
AddTemplateSpecializations(D);
+
+ // Force emitting the corresponding deduction guide in reduced BMI mode.
+ // Otherwise, the deduction guide may be optimized out incorrectly.
+ if (Writer.isGeneratingReducedBMI()) {
+ auto Name = Context.DeclarationNames.getCXXDeductionGuideName(D);
+ for (auto *DG : D->getDeclContext()->noload_lookup(Name))
+ Writer.GetDeclRef(DG->getCanonicalDecl());
+ }
+
Code = serialization::DECL_CLASS_TEMPLATE;
}
@@ -1701,20 +1756,28 @@ void ASTDeclWriter::VisitClassTemplateSpecializationDecl(
Record.AddDeclRef(D->getSpecializedTemplate()->getCanonicalDecl());
}
- // Explicit info.
- Record.AddTypeSourceInfo(D->getTypeAsWritten());
- if (D->getTypeAsWritten()) {
- Record.AddSourceLocation(D->getExternLoc());
+ bool ExplicitInstantiation =
+ D->getTemplateSpecializationKind() ==
+ TSK_ExplicitInstantiationDeclaration ||
+ D->getTemplateSpecializationKind() == TSK_ExplicitInstantiationDefinition;
+ Record.push_back(ExplicitInstantiation);
+ if (ExplicitInstantiation) {
+ Record.AddSourceLocation(D->getExternKeywordLoc());
Record.AddSourceLocation(D->getTemplateKeywordLoc());
}
+ const ASTTemplateArgumentListInfo *ArgsWritten =
+ D->getTemplateArgsAsWritten();
+ Record.push_back(!!ArgsWritten);
+ if (ArgsWritten)
+ Record.AddASTTemplateArgumentListInfo(ArgsWritten);
+
Code = serialization::DECL_CLASS_TEMPLATE_SPECIALIZATION;
}
void ASTDeclWriter::VisitClassTemplatePartialSpecializationDecl(
ClassTemplatePartialSpecializationDecl *D) {
Record.AddTemplateParameterList(D->getTemplateParameters());
- Record.AddASTTemplateArgumentListInfo(D->getTemplateArgsAsWritten());
VisitClassTemplateSpecializationDecl(D);
@@ -1748,13 +1811,22 @@ void ASTDeclWriter::VisitVarTemplateSpecializationDecl(
Record.AddTemplateArgumentList(&D->getTemplateInstantiationArgs());
}
- // Explicit info.
- Record.AddTypeSourceInfo(D->getTypeAsWritten());
- if (D->getTypeAsWritten()) {
- Record.AddSourceLocation(D->getExternLoc());
+ bool ExplicitInstantiation =
+ D->getTemplateSpecializationKind() ==
+ TSK_ExplicitInstantiationDeclaration ||
+ D->getTemplateSpecializationKind() == TSK_ExplicitInstantiationDefinition;
+ Record.push_back(ExplicitInstantiation);
+ if (ExplicitInstantiation) {
+ Record.AddSourceLocation(D->getExternKeywordLoc());
Record.AddSourceLocation(D->getTemplateKeywordLoc());
}
+ const ASTTemplateArgumentListInfo *ArgsWritten =
+ D->getTemplateArgsAsWritten();
+ Record.push_back(!!ArgsWritten);
+ if (ArgsWritten)
+ Record.AddASTTemplateArgumentListInfo(ArgsWritten);
+
Record.AddTemplateArgumentList(&D->getTemplateArgs());
Record.AddSourceLocation(D->getPointOfInstantiation());
Record.push_back(D->getSpecializationKind());
@@ -1775,7 +1847,6 @@ void ASTDeclWriter::VisitVarTemplateSpecializationDecl(
void ASTDeclWriter::VisitVarTemplatePartialSpecializationDecl(
VarTemplatePartialSpecializationDecl *D) {
Record.AddTemplateParameterList(D->getTemplateParameters());
- Record.AddASTTemplateArgumentListInfo(D->getTemplateArgsAsWritten());
VisitVarTemplateSpecializationDecl(D);
@@ -1819,7 +1890,7 @@ void ASTDeclWriter::VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D) {
!D->defaultArgumentWasInherited();
Record.push_back(OwnsDefaultArg);
if (OwnsDefaultArg)
- Record.AddTypeSourceInfo(D->getDefaultArgumentInfo());
+ Record.AddTemplateArgumentLoc(D->getDefaultArgument());
if (!TC && !OwnsDefaultArg &&
D->getDeclContext() == D->getLexicalDeclContext() &&
@@ -1861,7 +1932,7 @@ void ASTDeclWriter::VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D) {
!D->defaultArgumentWasInherited();
Record.push_back(OwnsDefaultArg);
if (OwnsDefaultArg)
- Record.AddStmt(D->getDefaultArgument());
+ Record.AddTemplateArgumentLoc(D->getDefaultArgument());
Code = serialization::DECL_NON_TYPE_TEMPLATE_PARM;
}
}
@@ -1874,6 +1945,7 @@ void ASTDeclWriter::VisitTemplateTemplateParmDecl(TemplateTemplateParmDecl *D) {
Record.push_back(D->getNumExpansionTemplateParameters());
VisitTemplateDecl(D);
+ Record.push_back(D->wasDeclaredWithTypename());
// TemplateParmPosition.
Record.push_back(D->getDepth());
Record.push_back(D->getPosition());
@@ -1915,8 +1987,22 @@ void ASTDeclWriter::VisitDeclContext(DeclContext *DC) {
"You need to update the serializer after you change the "
"DeclContextBits");
- Record.AddOffset(Writer.WriteDeclContextLexicalBlock(Context, DC));
- Record.AddOffset(Writer.WriteDeclContextVisibleBlock(Context, DC));
+ uint64_t LexicalOffset = 0;
+ uint64_t VisibleOffset = 0;
+
+ if (Writer.isGeneratingReducedBMI() && isa<NamespaceDecl>(DC) &&
+ cast<NamespaceDecl>(DC)->isFromExplicitGlobalModule()) {
+ // In reduced BMI, delay writing lexical and visible block for namespace
+ // in the global module fragment. See the comments of DelayedNamespace for
+ // details.
+ Writer.DelayedNamespace.push_back(cast<NamespaceDecl>(DC));
+ } else {
+ LexicalOffset = Writer.WriteDeclContextLexicalBlock(Context, DC);
+ VisibleOffset = Writer.WriteDeclContextVisibleBlock(Context, DC);
+ }
+
+ Record.AddOffset(LexicalOffset);
+ Record.AddOffset(VisibleOffset);
}
const Decl *ASTWriter::getFirstLocalDecl(const Decl *D) {
@@ -2132,12 +2218,13 @@ getFunctionDeclAbbrev(serialization::DeclCode Code) {
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 11)); // IDNS
Abv->Add(BitCodeAbbrevOp(
BitCodeAbbrevOp::Fixed,
- 27)); // Packed Function Bits: StorageClass, Inline, InlineSpecified,
+ 28)); // Packed Function Bits: StorageClass, Inline, InlineSpecified,
// VirtualAsWritten, Pure, HasInheritedProto, HasWrittenProto,
// Deleted, Trivial, TrivialForCall, Defaulted, ExplicitlyDefaulted,
// IsIneligibleOrNotSelected, ImplicitReturnZero, Constexpr,
// UsesSEHTry, SkippedBody, MultiVersion, LateParsed,
- // FriendConstraintRefersToEnclosingTemplate, Linkage
+ // FriendConstraintRefersToEnclosingTemplate, Linkage,
+ // ShouldSkipCheckingODR
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // LocEnd
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32)); // ODRHash
// This Array slurps the rest of the record. Fortunately we want to encode
@@ -2264,7 +2351,7 @@ void ASTWriter::WriteDeclAbbrevs() {
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // AddTypeRef
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // IntegerType
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // getPromotionType
- Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 19)); // Enum Decl Bits
+ Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 20)); // Enum Decl Bits
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32));// ODRHash
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // InstantiatedMembEnum
// DC
@@ -2708,10 +2795,10 @@ void ASTWriter::WriteDecl(ASTContext &Context, Decl *D) {
"serializing");
// Determine the ID for this declaration.
- serialization::DeclID ID;
+ LocalDeclID ID;
assert(!D->isFromASTFile() && "should not be emitting imported decl");
- serialization::DeclID &IDR = DeclIDs[D];
- if (IDR == 0)
+ LocalDeclID &IDR = DeclIDs[D];
+ if (IDR.isInvalid())
IDR = NextDeclID++;
ID = IDR;
@@ -2719,7 +2806,7 @@ void ASTWriter::WriteDecl(ASTContext &Context, Decl *D) {
assert(ID >= FirstDeclID && "invalid decl ID");
RecordData Record;
- ASTDeclWriter W(*this, Context, Record);
+ ASTDeclWriter W(*this, Context, Record, GeneratingReducedBMI);
// Build a record for this declaration
W.Visit(D);
@@ -2729,14 +2816,16 @@ void ASTWriter::WriteDecl(ASTContext &Context, Decl *D) {
// Record the offset for this declaration
SourceLocation Loc = D->getLocation();
- unsigned Index = ID - FirstDeclID;
+ SourceLocationEncoding::RawLocEncoding RawLoc =
+ getRawSourceLocationEncoding(getAdjustedLocation(Loc));
+
+ unsigned Index = ID.getRawValue() - FirstDeclID.getRawValue();
if (DeclOffsets.size() == Index)
- DeclOffsets.emplace_back(getAdjustedLocation(Loc), Offset,
- DeclTypesBlockStartOffset);
+ DeclOffsets.emplace_back(RawLoc, Offset, DeclTypesBlockStartOffset);
else if (DeclOffsets.size() < Index) {
// FIXME: Can/should this happen?
DeclOffsets.resize(Index+1);
- DeclOffsets[Index].setLocation(getAdjustedLocation(Loc));
+ DeclOffsets[Index].setRawLoc(RawLoc);
DeclOffsets[Index].setBitOffset(Offset, DeclTypesBlockStartOffset);
} else {
llvm_unreachable("declarations should be emitted in ID order");
@@ -2749,7 +2838,7 @@ void ASTWriter::WriteDecl(ASTContext &Context, Decl *D) {
// Note declarations that should be deserialized eagerly so that we can add
// them to a record in the AST file later.
if (isRequiredDecl(D, Context, WritingModule))
- EagerlyDeserializedDecls.push_back(ID);
+ AddDeclRef(D, EagerlyDeserializedDecls);
}
void ASTRecordWriter::AddFunctionDefinition(const FunctionDecl *FD) {
@@ -2785,7 +2874,7 @@ void ASTRecordWriter::AddFunctionDefinition(const FunctionDecl *FD) {
}
Record->push_back(ModulesCodegen);
if (ModulesCodegen)
- Writer->ModularCodegenDecls.push_back(Writer->GetDeclRef(FD));
+ Writer->AddDeclRef(FD, Writer->ModularCodegenDecls);
if (auto *CD = dyn_cast<CXXConstructorDecl>(FD)) {
Record->push_back(CD->getNumCtorInitializers());
if (CD->getNumCtorInitializers())