summaryrefslogtreecommitdiff
path: root/clang/lib/Serialization/ASTWriterStmt.cpp
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2023-12-25 13:49:57 +0000
committerDimitry Andric <dim@FreeBSD.org>2023-12-25 13:49:57 +0000
commit99aabd70801bd4bc72c4942747f6d62c675112f5 (patch)
tree02bf056e9098f5ecddc7f18a99db9c79f4404b02 /clang/lib/Serialization/ASTWriterStmt.cpp
parent312c0ed19cc5276a17bacf2120097bec4515b0f1 (diff)
Diffstat (limited to 'clang/lib/Serialization/ASTWriterStmt.cpp')
-rw-r--r--clang/lib/Serialization/ASTWriterStmt.cpp241
1 files changed, 169 insertions, 72 deletions
diff --git a/clang/lib/Serialization/ASTWriterStmt.cpp b/clang/lib/Serialization/ASTWriterStmt.cpp
index 8524484ea8a0..7f888e44dde1 100644
--- a/clang/lib/Serialization/ASTWriterStmt.cpp
+++ b/clang/lib/Serialization/ASTWriterStmt.cpp
@@ -37,15 +37,70 @@ namespace clang {
serialization::StmtCode Code;
unsigned AbbrevToUse;
+ /// A helper that can help us to write a packed bit across function
+ /// calls. For example, we may write seperate bits in seperate functions:
+ ///
+ /// void VisitA(A* a) {
+ /// Record.push_back(a->isSomething());
+ /// }
+ ///
+ /// void Visitb(B *b) {
+ /// VisitA(b);
+ /// Record.push_back(b->isAnother());
+ /// }
+ ///
+ /// In such cases, it'll be better if we can pack these 2 bits. We achieve
+ /// this by writing a zero value in `VisitA` and recorded that first and add
+ /// the new bit to the recorded value.
+ class PakedBitsWriter {
+ public:
+ PakedBitsWriter(ASTRecordWriter &Record) : RecordRef(Record) {}
+ ~PakedBitsWriter() { assert(!CurrentIndex); }
+
+ void addBit(bool Value) {
+ assert(CurrentIndex && "Writing Bits without recording first!");
+ PackingBits.addBit(Value);
+ }
+ void addBits(uint32_t Value, uint32_t BitsWidth) {
+ assert(CurrentIndex && "Writing Bits without recording first!");
+ PackingBits.addBits(Value, BitsWidth);
+ }
+
+ void writeBits() {
+ if (!CurrentIndex)
+ return;
+
+ RecordRef[*CurrentIndex] = (uint32_t)PackingBits;
+ CurrentIndex = std::nullopt;
+ PackingBits.reset(0);
+ }
+
+ void updateBits() {
+ writeBits();
+
+ CurrentIndex = RecordRef.size();
+ RecordRef.push_back(0);
+ }
+
+ private:
+ BitsPacker PackingBits;
+ ASTRecordWriter &RecordRef;
+ std::optional<unsigned> CurrentIndex;
+ };
+
+ PakedBitsWriter CurrentPackingBits;
+
public:
ASTStmtWriter(ASTWriter &Writer, ASTWriter::RecordData &Record)
: Writer(Writer), Record(Writer, Record),
- Code(serialization::STMT_NULL_PTR), AbbrevToUse(0) {}
+ Code(serialization::STMT_NULL_PTR), AbbrevToUse(0),
+ CurrentPackingBits(this->Record) {}
ASTStmtWriter(const ASTStmtWriter&) = delete;
ASTStmtWriter &operator=(const ASTStmtWriter &) = delete;
uint64_t Emit() {
+ CurrentPackingBits.writeBits();
assert(Code != serialization::STMT_NULL_PTR &&
"unhandled sub-statement writing AST file");
return Record.EmitStmt(Code, AbbrevToUse);
@@ -82,14 +137,20 @@ void ASTStmtWriter::VisitNullStmt(NullStmt *S) {
void ASTStmtWriter::VisitCompoundStmt(CompoundStmt *S) {
VisitStmt(S);
+
Record.push_back(S->size());
Record.push_back(S->hasStoredFPFeatures());
+
for (auto *CS : S->body())
Record.AddStmt(CS);
if (S->hasStoredFPFeatures())
Record.push_back(S->getStoredFPFeatures().getAsOpaqueInt());
Record.AddSourceLocation(S->getLBracLoc());
Record.AddSourceLocation(S->getRBracLoc());
+
+ if (!S->hasStoredFPFeatures())
+ AbbrevToUse = Writer.getCompoundStmtAbbrev();
+
Code = serialization::STMT_COMPOUND;
}
@@ -143,9 +204,11 @@ void ASTStmtWriter::VisitIfStmt(IfStmt *S) {
bool HasVar = S->getConditionVariableDeclStmt() != nullptr;
bool HasInit = S->getInit() != nullptr;
- Record.push_back(HasElse);
- Record.push_back(HasVar);
- Record.push_back(HasInit);
+ CurrentPackingBits.updateBits();
+
+ CurrentPackingBits.addBit(HasElse);
+ CurrentPackingBits.addBit(HasVar);
+ CurrentPackingBits.addBit(HasInit);
Record.push_back(static_cast<uint64_t>(S->getStatementKind()));
Record.AddStmt(S->getCond());
Record.AddStmt(S->getThen());
@@ -548,15 +611,13 @@ void ASTStmtWriter::VisitCapturedStmt(CapturedStmt *S) {
void ASTStmtWriter::VisitExpr(Expr *E) {
VisitStmt(E);
- Record.AddTypeRef(E->getType());
-
- BitsPacker ExprBits;
- ExprBits.addBits(E->getDependence(), /*BitsWidth=*/5);
- ExprBits.addBits(E->getValueKind(), /*BitsWidth=*/2);
- ExprBits.addBits(E->getObjectKind(), /*BitsWidth=*/3);
+ CurrentPackingBits.updateBits();
+ CurrentPackingBits.addBits(E->getDependence(), /*BitsWidth=*/5);
+ CurrentPackingBits.addBits(E->getValueKind(), /*BitsWidth=*/2);
+ CurrentPackingBits.addBits(E->getObjectKind(), /*BitsWidth=*/3);
- Record.push_back(ExprBits);
+ Record.AddTypeRef(E->getType());
}
void ASTStmtWriter::VisitConstantExpr(ConstantExpr *E) {
@@ -612,13 +673,15 @@ void ASTStmtWriter::VisitPredefinedExpr(PredefinedExpr *E) {
void ASTStmtWriter::VisitDeclRefExpr(DeclRefExpr *E) {
VisitExpr(E);
- Record.push_back(E->hasQualifier());
- Record.push_back(E->getDecl() != E->getFoundDecl());
- Record.push_back(E->hasTemplateKWAndArgsInfo());
- Record.push_back(E->hadMultipleCandidates());
- Record.push_back(E->refersToEnclosingVariableOrCapture());
- Record.push_back(E->isNonOdrUse());
- Record.push_back(E->isImmediateEscalating());
+ CurrentPackingBits.updateBits();
+
+ CurrentPackingBits.addBit(E->hadMultipleCandidates());
+ CurrentPackingBits.addBit(E->refersToEnclosingVariableOrCapture());
+ CurrentPackingBits.addBits(E->isNonOdrUse(), /*Width=*/2);
+ CurrentPackingBits.addBit(E->isImmediateEscalating());
+ CurrentPackingBits.addBit(E->getDecl() != E->getFoundDecl());
+ CurrentPackingBits.addBit(E->hasQualifier());
+ CurrentPackingBits.addBit(E->hasTemplateKWAndArgsInfo());
if (E->hasTemplateKWAndArgsInfo()) {
unsigned NumTemplateArgs = E->getNumTemplateArgs();
@@ -629,9 +692,7 @@ void ASTStmtWriter::VisitDeclRefExpr(DeclRefExpr *E) {
if ((!E->hasTemplateKWAndArgsInfo()) && (!E->hasQualifier()) &&
(E->getDecl() == E->getFoundDecl()) &&
- nk == DeclarationName::Identifier &&
- !E->refersToEnclosingVariableOrCapture() && !E->isNonOdrUse() &&
- !E->isImmediateEscalating()) {
+ nk == DeclarationName::Identifier && E->getObjectKind() == OK_Ordinary) {
AbbrevToUse = Writer.getDeclRefExprAbbrev();
}
@@ -742,11 +803,13 @@ void ASTStmtWriter::VisitUnaryOperator(UnaryOperator *E) {
bool HasFPFeatures = E->hasStoredFPFeatures();
// Write this first for easy access when deserializing, as they affect the
// size of the UnaryOperator.
- Record.push_back(HasFPFeatures);
+ CurrentPackingBits.addBit(HasFPFeatures);
Record.AddStmt(E->getSubExpr());
- Record.push_back(E->getOpcode()); // FIXME: stable encoding
+ CurrentPackingBits.addBits(E->getOpcode(),
+ /*Width=*/5); // FIXME: stable encoding
Record.AddSourceLocation(E->getOperatorLoc());
- Record.push_back(E->canOverflow());
+ CurrentPackingBits.addBit(E->canOverflow());
+
if (HasFPFeatures)
Record.push_back(E->getStoredFPFeatures().getAsOpaqueInt());
Code = serialization::EXPR_UNARY_OPERATOR;
@@ -872,12 +935,10 @@ void ASTStmtWriter::VisitOMPIteratorExpr(OMPIteratorExpr *E) {
void ASTStmtWriter::VisitCallExpr(CallExpr *E) {
VisitExpr(E);
- BitsPacker CallExprBits;
- // 16 bits should be sufficient to store the number args;
- CallExprBits.addBits(E->getNumArgs(), /*BitsWidth=*/16);
- CallExprBits.addBit(E->hasStoredFPFeatures());
- CallExprBits.addBit(static_cast<bool>(E->getADLCallKind()));
- Record.push_back(CallExprBits);
+ Record.push_back(E->getNumArgs());
+ CurrentPackingBits.updateBits();
+ CurrentPackingBits.addBit(static_cast<bool>(E->getADLCallKind()));
+ CurrentPackingBits.addBit(E->hasStoredFPFeatures());
Record.AddSourceLocation(E->getRParenLoc());
Record.AddStmt(E->getCallee());
@@ -887,6 +948,11 @@ void ASTStmtWriter::VisitCallExpr(CallExpr *E) {
if (E->hasStoredFPFeatures())
Record.push_back(E->getFPFeatures().getAsOpaqueInt());
+
+ if (!E->hasStoredFPFeatures() && !static_cast<bool>(E->getADLCallKind()) &&
+ E->getStmtClass() == Stmt::CallExprClass)
+ AbbrevToUse = Writer.getCallExprAbbrev();
+
Code = serialization::EXPR_CALL;
}
@@ -913,9 +979,10 @@ void ASTStmtWriter::VisitMemberExpr(MemberExpr *E) {
// Write these first for easy access when deserializing, as they affect the
// size of the MemberExpr.
- Record.push_back(HasQualifier);
- Record.push_back(HasFoundDecl);
- Record.push_back(HasTemplateInfo);
+ CurrentPackingBits.updateBits();
+ CurrentPackingBits.addBit(HasQualifier);
+ CurrentPackingBits.addBit(HasFoundDecl);
+ CurrentPackingBits.addBit(HasTemplateInfo);
Record.push_back(NumTemplateArgs);
Record.AddStmt(E->getBase());
@@ -923,15 +990,15 @@ void ASTStmtWriter::VisitMemberExpr(MemberExpr *E) {
Record.AddDeclarationNameLoc(E->MemberDNLoc,
E->getMemberDecl()->getDeclName());
Record.AddSourceLocation(E->getMemberLoc());
- Record.push_back(E->isArrow());
- Record.push_back(E->hadMultipleCandidates());
- Record.push_back(E->isNonOdrUse());
+ CurrentPackingBits.addBit(E->isArrow());
+ CurrentPackingBits.addBit(E->hadMultipleCandidates());
+ CurrentPackingBits.addBits(E->isNonOdrUse(), /*Width=*/2);
Record.AddSourceLocation(E->getOperatorLoc());
if (HasFoundDecl) {
DeclAccessPair FoundDecl = E->getFoundDecl();
Record.AddDeclRef(FoundDecl.getDecl());
- Record.push_back(FoundDecl.getAccess());
+ CurrentPackingBits.addBits(FoundDecl.getAccess(), /*BitWidth=*/2);
}
if (HasQualifier)
@@ -971,10 +1038,13 @@ void ASTStmtWriter::VisitObjCBridgedCastExpr(ObjCBridgedCastExpr *E) {
void ASTStmtWriter::VisitCastExpr(CastExpr *E) {
VisitExpr(E);
+
Record.push_back(E->path_size());
- Record.push_back(E->hasStoredFPFeatures());
+ CurrentPackingBits.updateBits();
+ // 7 bits should be enough to store the casting kinds.
+ CurrentPackingBits.addBits(E->getCastKind(), /*Width=*/7);
+ CurrentPackingBits.addBit(E->hasStoredFPFeatures());
Record.AddStmt(E->getSubExpr());
- Record.push_back(E->getCastKind()); // FIXME: stable encoding
for (CastExpr::path_iterator
PI = E->path_begin(), PE = E->path_end(); PI != PE; ++PI)
@@ -986,16 +1056,23 @@ void ASTStmtWriter::VisitCastExpr(CastExpr *E) {
void ASTStmtWriter::VisitBinaryOperator(BinaryOperator *E) {
VisitExpr(E);
- bool HasFPFeatures = E->hasStoredFPFeatures();
+
// Write this first for easy access when deserializing, as they affect the
// size of the UnaryOperator.
- Record.push_back(HasFPFeatures);
- Record.push_back(E->getOpcode()); // FIXME: stable encoding
+ CurrentPackingBits.updateBits();
+ CurrentPackingBits.addBits(E->getOpcode(), /*Width=*/6);
+ bool HasFPFeatures = E->hasStoredFPFeatures();
+ CurrentPackingBits.addBit(HasFPFeatures);
Record.AddStmt(E->getLHS());
Record.AddStmt(E->getRHS());
Record.AddSourceLocation(E->getOperatorLoc());
if (HasFPFeatures)
Record.push_back(E->getStoredFPFeatures().getAsOpaqueInt());
+
+ if (!HasFPFeatures && E->getValueKind() == VK_PRValue &&
+ E->getObjectKind() == OK_Ordinary)
+ AbbrevToUse = Writer.getBinaryOperatorAbbrev();
+
Code = serialization::EXPR_BINARY_OPERATOR;
}
@@ -1003,6 +1080,11 @@ void ASTStmtWriter::VisitCompoundAssignOperator(CompoundAssignOperator *E) {
VisitBinaryOperator(E);
Record.AddTypeRef(E->getComputationLHSType());
Record.AddTypeRef(E->getComputationResultType());
+
+ if (!E->hasStoredFPFeatures() && E->getValueKind() == VK_PRValue &&
+ E->getObjectKind() == OK_Ordinary)
+ AbbrevToUse = Writer.getCompoundAssignOperatorAbbrev();
+
Code = serialization::EXPR_COMPOUND_ASSIGN_OPERATOR;
}
@@ -1031,7 +1113,7 @@ ASTStmtWriter::VisitBinaryConditionalOperator(BinaryConditionalOperator *E) {
void ASTStmtWriter::VisitImplicitCastExpr(ImplicitCastExpr *E) {
VisitCastExpr(E);
- Record.push_back(E->isPartOfExplicitCast());
+ CurrentPackingBits.addBit(E->isPartOfExplicitCast());
if (E->path_size() == 0 && !E->hasStoredFPFeatures())
AbbrevToUse = Writer.getExprImplicitCastAbbrev();
@@ -1588,11 +1670,19 @@ void ASTStmtWriter::VisitCXXOperatorCallExpr(CXXOperatorCallExpr *E) {
VisitCallExpr(E);
Record.push_back(E->getOperator());
Record.AddSourceRange(E->Range);
+
+ if (!E->hasStoredFPFeatures() && !static_cast<bool>(E->getADLCallKind()))
+ AbbrevToUse = Writer.getCXXOperatorCallExprAbbrev();
+
Code = serialization::EXPR_CXX_OPERATOR_CALL;
}
void ASTStmtWriter::VisitCXXMemberCallExpr(CXXMemberCallExpr *E) {
VisitCallExpr(E);
+
+ if (!E->hasStoredFPFeatures() && !static_cast<bool>(E->getADLCallKind()))
+ AbbrevToUse = Writer.getCXXMemberCallExprAbbrev();
+
Code = serialization::EXPR_CXX_MEMBER_CALL;
}
@@ -1673,7 +1763,9 @@ void ASTStmtWriter::VisitCXXStdInitializerListExpr(CXXStdInitializerListExpr *E)
void ASTStmtWriter::VisitCXXNamedCastExpr(CXXNamedCastExpr *E) {
VisitExplicitCastExpr(E);
Record.AddSourceRange(SourceRange(E->getOperatorLoc(), E->getRParenLoc()));
- Record.AddSourceRange(E->getAngleBrackets());
+ CurrentPackingBits.addBit(E->getAngleBrackets().isValid());
+ if (E->getAngleBrackets().isValid())
+ Record.AddSourceRange(E->getAngleBrackets());
}
void ASTStmtWriter::VisitCXXStaticCastExpr(CXXStaticCastExpr *E) {
@@ -1750,6 +1842,7 @@ void ASTStmtWriter::VisitCXXThisExpr(CXXThisExpr *E) {
VisitExpr(E);
Record.AddSourceLocation(E->getLocation());
Record.push_back(E->isImplicit());
+
Code = serialization::EXPR_CXX_THIS;
}
@@ -1883,10 +1976,10 @@ void ASTStmtWriter::VisitCXXDependentScopeMemberExpr(
// Don't emit anything here (or if you do you will have to update
// the corresponding deserialization function).
-
- Record.push_back(E->hasTemplateKWAndArgsInfo());
Record.push_back(E->getNumTemplateArgs());
- Record.push_back(E->hasFirstQualifierFoundInScope());
+ CurrentPackingBits.updateBits();
+ CurrentPackingBits.addBit(E->hasTemplateKWAndArgsInfo());
+ CurrentPackingBits.addBit(E->hasFirstQualifierFoundInScope());
if (E->hasTemplateKWAndArgsInfo()) {
const ASTTemplateKWAndArgsInfo &ArgInfo =
@@ -1895,14 +1988,15 @@ void ASTStmtWriter::VisitCXXDependentScopeMemberExpr(
E->getTrailingObjects<TemplateArgumentLoc>());
}
- Record.push_back(E->isArrow());
- Record.AddSourceLocation(E->getOperatorLoc());
+ CurrentPackingBits.addBit(E->isArrow());
+
Record.AddTypeRef(E->getBaseType());
Record.AddNestedNameSpecifierLoc(E->getQualifierLoc());
+ CurrentPackingBits.addBit(!E->isImplicitAccess());
if (!E->isImplicitAccess())
Record.AddStmt(E->getBase());
- else
- Record.AddStmt(nullptr);
+
+ Record.AddSourceLocation(E->getOperatorLoc());
if (E->hasFirstQualifierFoundInScope())
Record.AddDeclRef(E->getFirstQualifierFoundInScope());
@@ -1917,12 +2011,14 @@ ASTStmtWriter::VisitDependentScopeDeclRefExpr(DependentScopeDeclRefExpr *E) {
// Don't emit anything here, HasTemplateKWAndArgsInfo must be
// emitted first.
+ CurrentPackingBits.addBit(
+ E->DependentScopeDeclRefExprBits.HasTemplateKWAndArgsInfo);
- Record.push_back(E->DependentScopeDeclRefExprBits.HasTemplateKWAndArgsInfo);
if (E->DependentScopeDeclRefExprBits.HasTemplateKWAndArgsInfo) {
const ASTTemplateKWAndArgsInfo &ArgInfo =
*E->getTrailingObjects<ASTTemplateKWAndArgsInfo>();
- Record.push_back(ArgInfo.NumTemplateArgs);
+ // 16 bits should be enought to store the number of args
+ CurrentPackingBits.addBits(ArgInfo.NumTemplateArgs, /*Width=*/16);
AddTemplateKWAndArgsInfo(ArgInfo,
E->getTrailingObjects<TemplateArgumentLoc>());
}
@@ -1949,19 +2045,16 @@ ASTStmtWriter::VisitCXXUnresolvedConstructExpr(CXXUnresolvedConstructExpr *E) {
void ASTStmtWriter::VisitOverloadExpr(OverloadExpr *E) {
VisitExpr(E);
- BitsPacker OverloadExprBits;
- // 14 Bits should enough to store the number of decls.
- OverloadExprBits.addBits(E->getNumDecls(), /*BitWidth=*/14);
- OverloadExprBits.addBit(E->hasTemplateKWAndArgsInfo());
+ Record.push_back(E->getNumDecls());
+
+ CurrentPackingBits.updateBits();
+ CurrentPackingBits.addBit(E->hasTemplateKWAndArgsInfo());
if (E->hasTemplateKWAndArgsInfo()) {
const ASTTemplateKWAndArgsInfo &ArgInfo =
*E->getTrailingASTTemplateKWAndArgsInfo();
- // 14 Bits should enough to store the number of template args.
- OverloadExprBits.addBits(ArgInfo.NumTemplateArgs, /*BitWidth=*/14);
- Record.push_back(OverloadExprBits);
+ Record.push_back(ArgInfo.NumTemplateArgs);
AddTemplateKWAndArgsInfo(ArgInfo, E->getTrailingTemplateArgumentLoc());
- } else
- Record.push_back(OverloadExprBits);
+ }
for (OverloadExpr::decls_iterator OvI = E->decls_begin(),
OvE = E->decls_end();
@@ -1976,18 +2069,22 @@ void ASTStmtWriter::VisitOverloadExpr(OverloadExpr *E) {
void ASTStmtWriter::VisitUnresolvedMemberExpr(UnresolvedMemberExpr *E) {
VisitOverloadExpr(E);
- Record.push_back(E->isArrow());
- Record.push_back(E->hasUnresolvedUsing());
- Record.AddStmt(!E->isImplicitAccess() ? E->getBase() : nullptr);
- Record.AddTypeRef(E->getBaseType());
+ CurrentPackingBits.addBit(E->isArrow());
+ CurrentPackingBits.addBit(E->hasUnresolvedUsing());
+ CurrentPackingBits.addBit(!E->isImplicitAccess());
+ if (!E->isImplicitAccess())
+ Record.AddStmt(E->getBase());
+
Record.AddSourceLocation(E->getOperatorLoc());
+
+ Record.AddTypeRef(E->getBaseType());
Code = serialization::EXPR_CXX_UNRESOLVED_MEMBER;
}
void ASTStmtWriter::VisitUnresolvedLookupExpr(UnresolvedLookupExpr *E) {
VisitOverloadExpr(E);
- Record.push_back(E->requiresADL());
- Record.push_back(E->isOverloaded());
+ CurrentPackingBits.addBit(E->requiresADL());
+ CurrentPackingBits.addBit(E->isOverloaded());
Record.AddDeclRef(E->getNamingClass());
Code = serialization::EXPR_CXX_UNRESOLVED_LOOKUP;
}
@@ -2059,12 +2156,12 @@ void ASTStmtWriter::VisitSubstNonTypeTemplateParmExpr(
SubstNonTypeTemplateParmExpr *E) {
VisitExpr(E);
Record.AddDeclRef(E->getAssociatedDecl());
- Record.push_back(E->isReferenceParameter());
- Record.push_back(E->getIndex());
+ CurrentPackingBits.addBit(E->isReferenceParameter());
+ CurrentPackingBits.addBits(E->getIndex(), /*Width=*/12);
+ CurrentPackingBits.addBit((bool)E->getPackIndex());
if (auto PackIndex = E->getPackIndex())
Record.push_back(*PackIndex + 1);
- else
- Record.push_back(0);
+
Record.AddSourceLocation(E->getNameLoc());
Record.AddStmt(E->getReplacement());
Code = serialization::EXPR_SUBST_NON_TYPE_TEMPLATE_PARM;