diff --git a/clang/include/clang/Serialization/ASTReader.h b/clang/include/clang/Serialization/ASTReader.h index 9bb89ec941091..a6dd779386dc1 100644 --- a/clang/include/clang/Serialization/ASTReader.h +++ b/clang/include/clang/Serialization/ASTReader.h @@ -2422,6 +2422,8 @@ class BitsUnpacker { CurrentBitsIndex = 0; } + void advance(uint32_t BitsWidth) { CurrentBitsIndex += BitsWidth; } + bool getNextBit() { assert(isValid()); return Value & (1 << CurrentBitsIndex++); diff --git a/clang/include/clang/Serialization/ASTWriter.h b/clang/include/clang/Serialization/ASTWriter.h index a56929ef0245e..16ab9583f8ed8 100644 --- a/clang/include/clang/Serialization/ASTWriter.h +++ b/clang/include/clang/Serialization/ASTWriter.h @@ -564,11 +564,25 @@ class ASTWriter : public ASTDeserializationListener, unsigned DeclEnumAbbrev = 0; unsigned DeclObjCIvarAbbrev = 0; unsigned DeclCXXMethodAbbrev = 0; + unsigned DeclDependentNonTemplateCXXMethodAbbrev = 0; + unsigned DeclTemplateCXXMethodAbbrev = 0; + unsigned DeclMemberSpecializedCXXMethodAbbrev = 0; + unsigned DeclTemplateSpecializedCXXMethodAbbrev = 0; + unsigned DeclDependentSpecializationCXXMethodAbbrev = 0; + unsigned DeclTemplateTypeParmAbbrev = 0; + unsigned DeclUsingShadowAbbrev = 0; unsigned DeclRefExprAbbrev = 0; unsigned CharacterLiteralAbbrev = 0; unsigned IntegerLiteralAbbrev = 0; unsigned ExprImplicitCastAbbrev = 0; + unsigned BinaryOperatorAbbrev = 0; + unsigned CompoundAssignOperatorAbbrev = 0; + unsigned CallExprAbbrev = 0; + unsigned CXXOperatorCallExprAbbrev = 0; + unsigned CXXMemberCallExprAbbrev = 0; + + unsigned CompoundStmtAbbrev = 0; void WriteDeclAbbrevs(); void WriteDecl(ASTContext &Context, Decl *D); @@ -735,12 +749,42 @@ class ASTWriter : public ASTDeserializationListener, unsigned getDeclFieldAbbrev() const { return DeclFieldAbbrev; } unsigned getDeclEnumAbbrev() const { return DeclEnumAbbrev; } unsigned getDeclObjCIvarAbbrev() const { return DeclObjCIvarAbbrev; } - unsigned getDeclCXXMethodAbbrev() const { return DeclCXXMethodAbbrev; } + unsigned getDeclCXXMethodAbbrev(FunctionDecl::TemplatedKind Kind) const { + switch (Kind) { + case FunctionDecl::TK_NonTemplate: + return DeclCXXMethodAbbrev; + case FunctionDecl::TK_FunctionTemplate: + return DeclTemplateCXXMethodAbbrev; + case FunctionDecl::TK_MemberSpecialization: + return DeclMemberSpecializedCXXMethodAbbrev; + case FunctionDecl::TK_FunctionTemplateSpecialization: + return DeclTemplateSpecializedCXXMethodAbbrev; + case FunctionDecl::TK_DependentNonTemplate: + return DeclDependentNonTemplateCXXMethodAbbrev; + case FunctionDecl::TK_DependentFunctionTemplateSpecialization: + return DeclDependentSpecializationCXXMethodAbbrev; + default: + llvm_unreachable("Unknwon Template Kind!"); + } + } + unsigned getDeclTemplateTypeParmAbbrev() const { + return DeclTemplateTypeParmAbbrev; + } + unsigned getDeclUsingShadowAbbrev() const { return DeclUsingShadowAbbrev; } unsigned getDeclRefExprAbbrev() const { return DeclRefExprAbbrev; } unsigned getCharacterLiteralAbbrev() const { return CharacterLiteralAbbrev; } unsigned getIntegerLiteralAbbrev() const { return IntegerLiteralAbbrev; } unsigned getExprImplicitCastAbbrev() const { return ExprImplicitCastAbbrev; } + unsigned getBinaryOperatorAbbrev() const { return BinaryOperatorAbbrev; } + unsigned getCompoundAssignOperatorAbbrev() const { + return CompoundAssignOperatorAbbrev; + } + unsigned getCallExprAbbrev() const { return CallExprAbbrev; } + unsigned getCXXOperatorCallExprAbbrev() { return CXXOperatorCallExprAbbrev; } + unsigned getCXXMemberCallExprAbbrev() { return CXXMemberCallExprAbbrev; } + + unsigned getCompoundStmtAbbrev() const { return CompoundStmtAbbrev; } bool hasChain() const { return Chain; } ASTReader *getChain() const { return Chain; } @@ -841,46 +885,33 @@ class BitsPacker { BitsPacker(BitsPacker &&) = delete; BitsPacker operator=(const BitsPacker &) = delete; BitsPacker operator=(BitsPacker &&) = delete; - ~BitsPacker() { - assert(!hasUnconsumedValues() && "There are unprocessed bits!"); + ~BitsPacker() = default; + + bool canWriteNextNBits(uint32_t BitsWidth) const { + return CurrentBitIndex + BitsWidth < BitIndexUpbound; + } + + void reset(uint32_t Value) { + UnderlyingValue = Value; + CurrentBitIndex = 0; } void addBit(bool Value) { addBits(Value, 1); } void addBits(uint32_t Value, uint32_t BitsWidth) { assert(BitsWidth < BitIndexUpbound); assert((Value < (1u << BitsWidth)) && "Passing narrower bit width!"); + assert(canWriteNextNBits(BitsWidth) && + "Inserting too much bits into a value!"); - if (CurrentBitIndex + BitsWidth >= BitIndexUpbound) { - Values.push_back(0); - CurrentBitIndex = 0; - } - - assert(CurrentBitIndex < BitIndexUpbound); - Values.back() |= Value << CurrentBitIndex; + UnderlyingValue |= Value << CurrentBitIndex; CurrentBitIndex += BitsWidth; } - bool hasUnconsumedValues() const { - return ConsumingValueIndex < Values.size(); - } - uint32_t getNextValue() { - assert(hasUnconsumedValues()); - return Values[ConsumingValueIndex++]; - } - - // We can convert the packer to an uint32_t if there is only one values. - operator uint32_t() { - assert(Values.size() == 1); - return getNextValue(); - } + operator uint32_t() { return UnderlyingValue; } private: - SmallVector Values; - uint16_t ConsumingValueIndex = 0; - // Initialize CurrentBitIndex with an invalid value - // to make it easier to update Values. See the implementation - // of `addBits` to see the details. - uint16_t CurrentBitIndex = BitIndexUpbound; + uint32_t UnderlyingValue = 0; + uint32_t CurrentBitIndex = 0; }; } // namespace clang diff --git a/clang/lib/Serialization/ASTReaderDecl.cpp b/clang/lib/Serialization/ASTReaderDecl.cpp index 7140a14aefbf9..209fb04342088 100644 --- a/clang/lib/Serialization/ASTReaderDecl.cpp +++ b/clang/lib/Serialization/ASTReaderDecl.cpp @@ -2660,7 +2660,7 @@ void ASTDeclReader::VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D) { D->setDeclaredWithTypename(Record.readInt()); - if (Record.readBool()) { + if (D->hasTypeConstraint()) { ConceptReference *CR = nullptr; if (Record.readBool()) CR = Record.readConceptReference(); diff --git a/clang/lib/Serialization/ASTReaderStmt.cpp b/clang/lib/Serialization/ASTReaderStmt.cpp index b3a6f619372b4..a43b1b9c0216b 100644 --- a/clang/lib/Serialization/ASTReaderStmt.cpp +++ b/clang/lib/Serialization/ASTReaderStmt.cpp @@ -73,6 +73,8 @@ namespace clang { ASTRecordReader &Record; llvm::BitstreamCursor &DeclsCursor; + std::optional CurrentUnpackingBits; + SourceLocation readSourceLocation() { return Record.readSourceLocation(); } @@ -110,6 +112,9 @@ namespace clang { /// itself. static const unsigned NumExprFields = NumStmtFields + 2; + /// The number of bits required for the packing bits for the Expr class. + static const unsigned NumExprBits = 10; + /// Read and initialize a ExplicitTemplateArgumentList structure. void ReadTemplateKWAndArgsInfo(ASTTemplateKWAndArgsInfo &Args, TemplateArgumentLoc *ArgsLocArray, @@ -147,9 +152,10 @@ void ASTStmtReader::VisitNullStmt(NullStmt *S) { void ASTStmtReader::VisitCompoundStmt(CompoundStmt *S) { VisitStmt(S); + CurrentUnpackingBits.emplace(Record.readInt()); SmallVector Stmts; - unsigned NumStmts = Record.readInt(); - unsigned HasFPFeatures = Record.readInt(); + unsigned NumStmts = CurrentUnpackingBits->getNextBits(/*Width=*/20); + unsigned HasFPFeatures = CurrentUnpackingBits->getNextBit(); assert(S->hasStoredFPFeatures() == HasFPFeatures); while (NumStmts--) Stmts.push_back(Record.readSubStmt()); @@ -214,9 +220,11 @@ void ASTStmtReader::VisitAttributedStmt(AttributedStmt *S) { void ASTStmtReader::VisitIfStmt(IfStmt *S) { VisitStmt(S); - bool HasElse = Record.readInt(); - bool HasVar = Record.readInt(); - bool HasInit = Record.readInt(); + CurrentUnpackingBits.emplace(Record.readInt()); + + bool HasElse = CurrentUnpackingBits->getNextBit(); + bool HasVar = CurrentUnpackingBits->getNextBit(); + bool HasInit = CurrentUnpackingBits->getNextBit(); S->setStatementKind(static_cast(Record.readInt())); S->setCond(Record.readSubExpr()); @@ -523,14 +531,15 @@ void ASTStmtReader::VisitCapturedStmt(CapturedStmt *S) { void ASTStmtReader::VisitExpr(Expr *E) { VisitStmt(E); + CurrentUnpackingBits.emplace(Record.readInt()); + E->setDependence(static_cast( + CurrentUnpackingBits->getNextBits(/*Width=*/5))); + E->setValueKind(static_cast( + CurrentUnpackingBits->getNextBits(/*Width=*/2))); + E->setObjectKind(static_cast( + CurrentUnpackingBits->getNextBits(/*Width=*/3))); + E->setType(Record.readType()); - BitsUnpacker ExprBits(Record.readInt()); - E->setDependence( - static_cast(ExprBits.getNextBits(/*Width=*/5))); - E->setValueKind( - static_cast(ExprBits.getNextBits(/*Width=*/2))); - E->setObjectKind( - static_cast(ExprBits.getNextBits(/*Width=*/3))); assert(Record.getIdx() == NumExprFields && "Incorrect expression field count"); } @@ -591,17 +600,20 @@ void ASTStmtReader::VisitPredefinedExpr(PredefinedExpr *E) { void ASTStmtReader::VisitDeclRefExpr(DeclRefExpr *E) { VisitExpr(E); - E->DeclRefExprBits.HasQualifier = Record.readInt(); - E->DeclRefExprBits.HasFoundDecl = Record.readInt(); - E->DeclRefExprBits.HasTemplateKWAndArgsInfo = Record.readInt(); - E->DeclRefExprBits.HadMultipleCandidates = Record.readInt(); - E->DeclRefExprBits.RefersToEnclosingVariableOrCapture = Record.readInt(); - E->DeclRefExprBits.NonOdrUseReason = Record.readInt(); - E->DeclRefExprBits.IsImmediateEscalating = Record.readInt(); + E->DeclRefExprBits.HasQualifier = CurrentUnpackingBits->getNextBit(); + E->DeclRefExprBits.HasFoundDecl = CurrentUnpackingBits->getNextBit(); + E->DeclRefExprBits.HasTemplateKWAndArgsInfo = + CurrentUnpackingBits->getNextBit(); + E->DeclRefExprBits.HadMultipleCandidates = CurrentUnpackingBits->getNextBit(); + E->DeclRefExprBits.RefersToEnclosingVariableOrCapture = + CurrentUnpackingBits->getNextBit(); + E->DeclRefExprBits.NonOdrUseReason = + CurrentUnpackingBits->getNextBits(/*Width=*/2); + E->DeclRefExprBits.IsImmediateEscalating = CurrentUnpackingBits->getNextBit(); E->DeclRefExprBits.CapturedByCopyInLambdaWithExplicitObjectParameter = false; unsigned NumTemplateArgs = 0; if (E->hasTemplateKWAndArgsInfo()) - NumTemplateArgs = Record.readInt(); + NumTemplateArgs = CurrentUnpackingBits->getNextBits(/*Width=*/12); if (E->hasQualifier()) new (E->getTrailingObjects()) @@ -706,12 +718,13 @@ void ASTStmtReader::VisitParenListExpr(ParenListExpr *E) { void ASTStmtReader::VisitUnaryOperator(UnaryOperator *E) { VisitExpr(E); - bool hasFP_Features = Record.readInt(); + bool hasFP_Features = CurrentUnpackingBits->getNextBit(); assert(hasFP_Features == E->hasStoredFPFeatures()); E->setSubExpr(Record.readSubExpr()); - E->setOpcode((UnaryOperator::Opcode)Record.readInt()); + E->setOpcode( + (UnaryOperator::Opcode)CurrentUnpackingBits->getNextBits(/*Width=*/5)); E->setOperatorLoc(readSourceLocation()); - E->setCanOverflow(Record.readInt()); + E->setCanOverflow(CurrentUnpackingBits->getNextBit()); if (hasFP_Features) E->setStoredFPFeatures( FPOptionsOverride::getFromOpaqueInt(Record.readInt())); @@ -1000,12 +1013,10 @@ void ASTStmtReader::VisitOMPIteratorExpr(OMPIteratorExpr *E) { void ASTStmtReader::VisitCallExpr(CallExpr *E) { VisitExpr(E); - BitsUnpacker CallExprBits = Record.readInt(); - - unsigned NumArgs = CallExprBits.getNextBits(/*Width=*/16); - bool HasFPFeatures = CallExprBits.getNextBit(); + unsigned NumArgs = CurrentUnpackingBits->getNextBits(/*Width=*/13); + bool HasFPFeatures = CurrentUnpackingBits->getNextBit(); E->setADLCallKind( - static_cast(CallExprBits.getNextBit())); + static_cast(CurrentUnpackingBits->getNextBit())); assert((NumArgs == E->getNumArgs()) && "Wrong NumArgs!"); E->setRParenLoc(readSourceLocation()); E->setCallee(Record.readSubExpr()); @@ -1024,27 +1035,28 @@ void ASTStmtReader::VisitCXXMemberCallExpr(CXXMemberCallExpr *E) { void ASTStmtReader::VisitMemberExpr(MemberExpr *E) { VisitExpr(E); - bool HasQualifier = Record.readInt(); - bool HasFoundDecl = Record.readInt(); - bool HasTemplateInfo = Record.readInt(); - unsigned NumTemplateArgs = Record.readInt(); + bool HasQualifier = CurrentUnpackingBits->getNextBit(); + bool HasFoundDecl = CurrentUnpackingBits->getNextBit(); + bool HasTemplateInfo = CurrentUnpackingBits->getNextBit(); + unsigned NumTemplateArgs = CurrentUnpackingBits->getNextBits(/*Width=*/12); E->Base = Record.readSubExpr(); E->MemberDecl = Record.readDeclAs(); E->MemberDNLoc = Record.readDeclarationNameLoc(E->MemberDecl->getDeclName()); E->MemberLoc = Record.readSourceLocation(); - E->MemberExprBits.IsArrow = Record.readInt(); + E->MemberExprBits.IsArrow = CurrentUnpackingBits->getNextBit(); E->MemberExprBits.HasQualifierOrFoundDecl = HasQualifier || HasFoundDecl; E->MemberExprBits.HasTemplateKWAndArgsInfo = HasTemplateInfo; - E->MemberExprBits.HadMultipleCandidates = Record.readInt(); - E->MemberExprBits.NonOdrUseReason = Record.readInt(); + E->MemberExprBits.HadMultipleCandidates = CurrentUnpackingBits->getNextBit(); + E->MemberExprBits.NonOdrUseReason = + CurrentUnpackingBits->getNextBits(/*Width=*/2); E->MemberExprBits.OperatorLoc = Record.readSourceLocation(); if (HasQualifier || HasFoundDecl) { DeclAccessPair FoundDecl; if (HasFoundDecl) { auto *FoundD = Record.readDeclAs(); - auto AS = (AccessSpecifier)Record.readInt(); + auto AS = (AccessSpecifier)CurrentUnpackingBits->getNextBits(/*Width=*/2); FoundDecl = DeclAccessPair::make(FoundD, AS); } else { FoundDecl = DeclAccessPair::make(E->MemberDecl, @@ -1091,10 +1103,10 @@ void ASTStmtReader::VisitCastExpr(CastExpr *E) { VisitExpr(E); unsigned NumBaseSpecs = Record.readInt(); assert(NumBaseSpecs == E->path_size()); - unsigned HasFPFeatures = Record.readInt(); + unsigned HasFPFeatures = CurrentUnpackingBits->getNextBit(); assert(E->hasStoredFPFeatures() == HasFPFeatures); E->setSubExpr(Record.readSubExpr()); - E->setCastKind((CastKind)Record.readInt()); + E->setCastKind((CastKind)CurrentUnpackingBits->getNextBits(/*Width=*/7)); CastExpr::path_iterator BaseI = E->path_begin(); while (NumBaseSpecs--) { auto *BaseSpec = new (Record.getContext()) CXXBaseSpecifier; @@ -1107,10 +1119,12 @@ void ASTStmtReader::VisitCastExpr(CastExpr *E) { } void ASTStmtReader::VisitBinaryOperator(BinaryOperator *E) { - bool hasFP_Features; + VisitExpr(E); - E->setHasStoredFPFeatures(hasFP_Features = Record.readInt()); - E->setOpcode((BinaryOperator::Opcode)Record.readInt()); + bool hasFP_Features = CurrentUnpackingBits->getNextBit(); + E->setHasStoredFPFeatures(hasFP_Features); + E->setOpcode( + (BinaryOperator::Opcode)CurrentUnpackingBits->getNextBits(/*Width=*/6)); E->setLHS(Record.readSubExpr()); E->setRHS(Record.readSubExpr()); E->setOperatorLoc(readSourceLocation()); @@ -1148,7 +1162,7 @@ ASTStmtReader::VisitBinaryConditionalOperator(BinaryConditionalOperator *E) { void ASTStmtReader::VisitImplicitCastExpr(ImplicitCastExpr *E) { VisitCastExpr(E); - E->setIsPartOfExplicitCast(Record.readInt()); + E->setIsPartOfExplicitCast(CurrentUnpackingBits->getNextBit()); } void ASTStmtReader::VisitExplicitCastExpr(ExplicitCastExpr *E) { @@ -1686,7 +1700,8 @@ void ASTStmtReader::VisitMSDependentExistsStmt(MSDependentExistsStmt *S) { void ASTStmtReader::VisitCXXOperatorCallExpr(CXXOperatorCallExpr *E) { VisitCallExpr(E); - E->CXXOperatorCallExprBits.OperatorKind = Record.readInt(); + E->CXXOperatorCallExprBits.OperatorKind = + CurrentUnpackingBits->getNextBits(/*Width=*/6); E->Range = Record.readSourceRange(); } @@ -1764,8 +1779,8 @@ void ASTStmtReader::VisitCXXNamedCastExpr(CXXNamedCastExpr *E) { SourceRange R = readSourceRange(); E->Loc = R.getBegin(); E->RParenLoc = R.getEnd(); - R = readSourceRange(); - E->AngleBrackets = R; + if (CurrentUnpackingBits->getNextBit()) + E->AngleBrackets = readSourceRange(); } void ASTStmtReader::VisitCXXStaticCastExpr(CXXStaticCastExpr *E) { @@ -1961,9 +1976,9 @@ void ASTStmtReader::VisitCXXDependentScopeMemberExpr( CXXDependentScopeMemberExpr *E) { VisitExpr(E); - bool HasTemplateKWAndArgsInfo = Record.readInt(); - unsigned NumTemplateArgs = Record.readInt(); - bool HasFirstQualifierFoundInScope = Record.readInt(); + bool HasTemplateKWAndArgsInfo = CurrentUnpackingBits->getNextBit(); + unsigned NumTemplateArgs = CurrentUnpackingBits->getNextBits(/*Width=*/16); + bool HasFirstQualifierFoundInScope = CurrentUnpackingBits->getNextBit(); assert((HasTemplateKWAndArgsInfo == E->hasTemplateKWAndArgsInfo()) && "Wrong HasTemplateKWAndArgsInfo!"); @@ -1979,11 +1994,17 @@ void ASTStmtReader::VisitCXXDependentScopeMemberExpr( assert((NumTemplateArgs == E->getNumTemplateArgs()) && "Wrong NumTemplateArgs!"); - E->CXXDependentScopeMemberExprBits.IsArrow = Record.readInt(); - E->CXXDependentScopeMemberExprBits.OperatorLoc = readSourceLocation(); + E->CXXDependentScopeMemberExprBits.IsArrow = + CurrentUnpackingBits->getNextBit(); + E->BaseType = Record.readType(); E->QualifierLoc = Record.readNestedNameSpecifierLoc(); - E->Base = Record.readSubExpr(); + // not ImplicitAccess + if (CurrentUnpackingBits->getNextBit()) { + E->Base = Record.readSubExpr(); + E->CXXDependentScopeMemberExprBits.OperatorLoc = readSourceLocation(); + } else + E->Base = nullptr; if (HasFirstQualifierFoundInScope) *E->getTrailingObjects() = readDeclAs(); @@ -1995,11 +2016,11 @@ void ASTStmtReader::VisitDependentScopeDeclRefExpr(DependentScopeDeclRefExpr *E) { VisitExpr(E); - if (Record.readInt()) // HasTemplateKWAndArgsInfo + if (CurrentUnpackingBits->getNextBit()) // HasTemplateKWAndArgsInfo ReadTemplateKWAndArgsInfo( *E->getTrailingObjects(), E->getTrailingObjects(), - /*NumTemplateArgs=*/Record.readInt()); + /*NumTemplateArgs=*/CurrentUnpackingBits->getNextBits(/*Width=*/16)); E->QualifierLoc = Record.readNestedNameSpecifierLoc(); E->NameInfo = Record.readDeclarationNameInfo(); @@ -2022,15 +2043,15 @@ ASTStmtReader::VisitCXXUnresolvedConstructExpr(CXXUnresolvedConstructExpr *E) { void ASTStmtReader::VisitOverloadExpr(OverloadExpr *E) { VisitExpr(E); - BitsUnpacker OverloadExprBits = Record.readInt(); - unsigned NumResults = OverloadExprBits.getNextBits(/*Width=*/14); - bool HasTemplateKWAndArgsInfo = OverloadExprBits.getNextBit(); + CurrentUnpackingBits.emplace(Record.readInt()); + unsigned NumResults = CurrentUnpackingBits->getNextBits(/*Width=*/12); + bool HasTemplateKWAndArgsInfo = CurrentUnpackingBits->getNextBit(); assert((E->getNumDecls() == NumResults) && "Wrong NumResults!"); assert((E->hasTemplateKWAndArgsInfo() == HasTemplateKWAndArgsInfo) && "Wrong HasTemplateKWAndArgsInfo!"); if (HasTemplateKWAndArgsInfo) { - unsigned NumTemplateArgs = OverloadExprBits.getNextBits(/*Width=*/14); + unsigned NumTemplateArgs = CurrentUnpackingBits->getNextBits(/*Width=*/12); ReadTemplateKWAndArgsInfo(*E->getTrailingASTTemplateKWAndArgsInfo(), E->getTrailingTemplateArgumentLoc(), NumTemplateArgs); @@ -2057,17 +2078,25 @@ void ASTStmtReader::VisitOverloadExpr(OverloadExpr *E) { void ASTStmtReader::VisitUnresolvedMemberExpr(UnresolvedMemberExpr *E) { VisitOverloadExpr(E); - E->UnresolvedMemberExprBits.IsArrow = Record.readInt(); - E->UnresolvedMemberExprBits.HasUnresolvedUsing = Record.readInt(); - E->Base = Record.readSubExpr(); + E->UnresolvedMemberExprBits.IsArrow = CurrentUnpackingBits->getNextBit(); + E->UnresolvedMemberExprBits.HasUnresolvedUsing = + CurrentUnpackingBits->getNextBit(); + + if (/*!isImplicitAccess=*/CurrentUnpackingBits->getNextBit()) { + E->Base = Record.readSubExpr(); + E->OperatorLoc = readSourceLocation(); + } else { + E->Base = nullptr; + E->OperatorLoc = SourceLocation(); + } + E->BaseType = Record.readType(); - E->OperatorLoc = readSourceLocation(); } void ASTStmtReader::VisitUnresolvedLookupExpr(UnresolvedLookupExpr *E) { VisitOverloadExpr(E); - E->UnresolvedLookupExprBits.RequiresADL = Record.readInt(); - E->UnresolvedLookupExprBits.Overloaded = Record.readInt(); + E->UnresolvedLookupExprBits.RequiresADL = CurrentUnpackingBits->getNextBit(); + E->UnresolvedLookupExprBits.Overloaded = CurrentUnpackingBits->getNextBit(); E->NamingClass = readDeclAs(); } @@ -2142,9 +2171,12 @@ void ASTStmtReader::VisitSubstNonTypeTemplateParmExpr( SubstNonTypeTemplateParmExpr *E) { VisitExpr(E); E->AssociatedDeclAndRef.setPointer(readDeclAs()); - E->AssociatedDeclAndRef.setInt(Record.readInt()); - E->Index = Record.readInt(); - E->PackIndex = Record.readInt(); + E->AssociatedDeclAndRef.setInt(CurrentUnpackingBits->getNextBit()); + E->Index = CurrentUnpackingBits->getNextBits(/*Width=*/12); + if (CurrentUnpackingBits->getNextBit()) + E->PackIndex = Record.readInt(); + else + E->PackIndex = 0; E->SubstNonTypeTemplateParmExprBits.NameLoc = readSourceLocation(); E->Replacement = Record.readSubExpr(); } @@ -2836,11 +2868,13 @@ Stmt *ASTReader::ReadStmtFromStream(ModuleFile &F) { S = new (Context) NullStmt(Empty); break; - case STMT_COMPOUND: - S = CompoundStmt::CreateEmpty( - Context, /*NumStmts=*/Record[ASTStmtReader::NumStmtFields], - /*HasFPFeatures=*/Record[ASTStmtReader::NumStmtFields + 1]); + case STMT_COMPOUND: { + BitsUnpacker StmtCompoundBits(Record[ASTStmtReader::NumStmtFields]); + unsigned NumStmts = StmtCompoundBits.getNextBits(/*Width=*/20); + bool HasFPFeatures = StmtCompoundBits.getNextBit(); + S = CompoundStmt::CreateEmpty(Context, NumStmts, HasFPFeatures); break; + } case STMT_CASE: S = CaseStmt::CreateEmpty( @@ -2862,13 +2896,14 @@ Stmt *ASTReader::ReadStmtFromStream(ModuleFile &F) { /*NumAttrs*/Record[ASTStmtReader::NumStmtFields]); break; - case STMT_IF: - S = IfStmt::CreateEmpty( - Context, - /* HasElse=*/Record[ASTStmtReader::NumStmtFields], - /* HasVar=*/Record[ASTStmtReader::NumStmtFields + 1], - /* HasInit=*/Record[ASTStmtReader::NumStmtFields + 2]); + case STMT_IF: { + BitsUnpacker IfStmtBits(Record[ASTStmtReader::NumStmtFields]); + bool HasElse = IfStmtBits.getNextBit(); + bool HasVar = IfStmtBits.getNextBit(); + bool HasInit = IfStmtBits.getNextBit(); + S = IfStmt::CreateEmpty(Context, HasElse, HasVar, HasInit); break; + } case STMT_SWITCH: S = SwitchStmt::CreateEmpty( @@ -2945,17 +2980,20 @@ Stmt *ASTReader::ReadStmtFromStream(ModuleFile &F) { /*HasFunctionName*/ Record[ASTStmtReader::NumExprFields]); break; - case EXPR_DECL_REF: - S = DeclRefExpr::CreateEmpty( - Context, - /*HasQualifier=*/Record[ASTStmtReader::NumExprFields], - /*HasFoundDecl=*/Record[ASTStmtReader::NumExprFields + 1], - /*HasTemplateKWAndArgsInfo=*/Record[ASTStmtReader::NumExprFields + 2], - /*NumTemplateArgs=*/ - Record[ASTStmtReader::NumExprFields + 2] - ? Record[ASTStmtReader::NumExprFields + 7] - : 0); + case EXPR_DECL_REF: { + BitsUnpacker DeclRefExprBits(Record[ASTStmtReader::NumStmtFields]); + DeclRefExprBits.advance(ASTStmtReader::NumExprBits); + bool HasQualifier = DeclRefExprBits.getNextBit(); + bool HasFoundDecl = DeclRefExprBits.getNextBit(); + bool HasTemplateKWAndArgsInfo = DeclRefExprBits.getNextBit(); + DeclRefExprBits.advance(5); + unsigned NumTemplateArgs = HasTemplateKWAndArgsInfo + ? DeclRefExprBits.getNextBits(/*Width=*/12) + : 0; + S = DeclRefExpr::CreateEmpty(Context, HasQualifier, HasFoundDecl, + HasTemplateKWAndArgsInfo, NumTemplateArgs); break; + } case EXPR_INTEGER_LITERAL: S = IntegerLiteral::Create(Context, Empty); @@ -2995,10 +3033,13 @@ Stmt *ASTReader::ReadStmtFromStream(ModuleFile &F) { /* NumExprs=*/Record[ASTStmtReader::NumExprFields]); break; - case EXPR_UNARY_OPERATOR: - S = UnaryOperator::CreateEmpty(Context, - Record[ASTStmtReader::NumExprFields]); + case EXPR_UNARY_OPERATOR: { + BitsUnpacker UnaryOperatorBits(Record[ASTStmtReader::NumStmtFields]); + UnaryOperatorBits.advance(ASTStmtReader::NumExprBits); + bool HasFPFeatures = UnaryOperatorBits.getNextBit(); + S = UnaryOperator::CreateEmpty(Context, HasFPFeatures); break; + } case EXPR_OFFSETOF: S = OffsetOfExpr::CreateEmpty(Context, @@ -3033,8 +3074,9 @@ Stmt *ASTReader::ReadStmtFromStream(ModuleFile &F) { break; case EXPR_CALL: { - BitsUnpacker CallExprBits(Record[ASTStmtReader::NumExprFields]); - auto NumArgs = CallExprBits.getNextBits(/*Width=*/16); + BitsUnpacker CallExprBits(Record[ASTStmtReader::NumStmtFields]); + CallExprBits.advance(ASTStmtReader::NumExprBits); + auto NumArgs = CallExprBits.getNextBits(/*Width=*/13); auto HasFPFeatures = CallExprBits.getNextBit(); S = CallExpr::CreateEmpty(Context, NumArgs, HasFPFeatures, Empty); break; @@ -3045,22 +3087,33 @@ Stmt *ASTReader::ReadStmtFromStream(ModuleFile &F) { Context, /*NumArgs=*/Record[ASTStmtReader::NumExprFields]); break; - case EXPR_MEMBER: - S = MemberExpr::CreateEmpty(Context, Record[ASTStmtReader::NumExprFields], - Record[ASTStmtReader::NumExprFields + 1], - Record[ASTStmtReader::NumExprFields + 2], - Record[ASTStmtReader::NumExprFields + 3]); + case EXPR_MEMBER: { + BitsUnpacker ExprMemberBits(Record[ASTStmtReader::NumStmtFields]); + ExprMemberBits.advance(ASTStmtReader::NumExprBits); + bool HasQualifier = ExprMemberBits.getNextBit(); + bool HasFoundDecl = ExprMemberBits.getNextBit(); + bool HasTemplateInfo = ExprMemberBits.getNextBit(); + unsigned NumTemplateArgs = ExprMemberBits.getNextBits(/*Width=*/12); + S = MemberExpr::CreateEmpty(Context, HasQualifier, HasFoundDecl, + HasTemplateInfo, NumTemplateArgs); break; + } - case EXPR_BINARY_OPERATOR: - S = BinaryOperator::CreateEmpty(Context, - Record[ASTStmtReader::NumExprFields]); + case EXPR_BINARY_OPERATOR: { + BitsUnpacker BinaryOperatorBits(Record[ASTStmtReader::NumStmtFields]); + BinaryOperatorBits.advance(ASTStmtReader::NumExprBits); + bool HasFPFeatures = BinaryOperatorBits.getNextBit(); + S = BinaryOperator::CreateEmpty(Context, HasFPFeatures); break; + } - case EXPR_COMPOUND_ASSIGN_OPERATOR: - S = CompoundAssignOperator::CreateEmpty( - Context, Record[ASTStmtReader::NumExprFields]); + case EXPR_COMPOUND_ASSIGN_OPERATOR: { + BitsUnpacker BinaryOperatorBits(Record[ASTStmtReader::NumStmtFields]); + BinaryOperatorBits.advance(ASTStmtReader::NumExprBits); + bool HasFPFeatures = BinaryOperatorBits.getNextBit(); + S = CompoundAssignOperator::CreateEmpty(Context, HasFPFeatures); break; + } case EXPR_CONDITIONAL_OPERATOR: S = new (Context) ConditionalOperator(Empty); @@ -3070,19 +3123,23 @@ Stmt *ASTReader::ReadStmtFromStream(ModuleFile &F) { S = new (Context) BinaryConditionalOperator(Empty); break; - case EXPR_IMPLICIT_CAST: - S = ImplicitCastExpr::CreateEmpty( - Context, - /*PathSize*/ Record[ASTStmtReader::NumExprFields], - /*HasFPFeatures*/ Record[ASTStmtReader::NumExprFields + 1]); + case EXPR_IMPLICIT_CAST: { + BitsUnpacker CastExprBits(Record[ASTStmtReader::NumStmtFields]); + CastExprBits.advance(ASTStmtReader::NumExprBits); + unsigned PathSize = Record[ASTStmtReader::NumExprFields]; + bool HasFPFeatures = CastExprBits.getNextBit(); + S = ImplicitCastExpr::CreateEmpty(Context, PathSize, HasFPFeatures); break; + } - case EXPR_CSTYLE_CAST: - S = CStyleCastExpr::CreateEmpty( - Context, - /*PathSize*/ Record[ASTStmtReader::NumExprFields], - /*HasFPFeatures*/ Record[ASTStmtReader::NumExprFields + 1]); + case EXPR_CSTYLE_CAST: { + BitsUnpacker CastExprBits(Record[ASTStmtReader::NumStmtFields]); + CastExprBits.advance(ASTStmtReader::NumExprBits); + unsigned PathSize = Record[ASTStmtReader::NumExprFields]; + bool HasFPFeatures = CastExprBits.getNextBit(); + S = CStyleCastExpr::CreateEmpty(Context, PathSize, HasFPFeatures); break; + } case EXPR_COMPOUND_LITERAL: S = new (Context) CompoundLiteralExpr(Empty); @@ -3777,8 +3834,9 @@ Stmt *ASTReader::ReadStmtFromStream(ModuleFile &F) { } case EXPR_CXX_OPERATOR_CALL: { - BitsUnpacker CallExprBits(Record[ASTStmtReader::NumExprFields]); - auto NumArgs = CallExprBits.getNextBits(/*Width=*/16); + BitsUnpacker CallExprBits(Record[ASTStmtReader::NumStmtFields]); + CallExprBits.advance(ASTStmtReader::NumExprBits); + auto NumArgs = CallExprBits.getNextBits(/*Width=*/13); auto HasFPFeatures = CallExprBits.getNextBit(); S = CXXOperatorCallExpr::CreateEmpty(Context, NumArgs, HasFPFeatures, Empty); @@ -3786,8 +3844,9 @@ Stmt *ASTReader::ReadStmtFromStream(ModuleFile &F) { } case EXPR_CXX_MEMBER_CALL: { - BitsUnpacker CallExprBits(Record[ASTStmtReader::NumExprFields]); - auto NumArgs = CallExprBits.getNextBits(/*Width=*/16); + BitsUnpacker CallExprBits(Record[ASTStmtReader::NumStmtFields]); + CallExprBits.advance(ASTStmtReader::NumExprBits); + auto NumArgs = CallExprBits.getNextBits(/*Width=*/13); auto HasFPFeatures = CallExprBits.getNextBit(); S = CXXMemberCallExpr::CreateEmpty(Context, NumArgs, HasFPFeatures, Empty); @@ -3814,22 +3873,26 @@ Stmt *ASTReader::ReadStmtFromStream(ModuleFile &F) { /* NumArgs=*/Record[ASTStmtReader::NumExprFields]); break; - case EXPR_CXX_STATIC_CAST: - S = CXXStaticCastExpr::CreateEmpty( - Context, - /*PathSize*/ Record[ASTStmtReader::NumExprFields], - /*HasFPFeatures*/ Record[ASTStmtReader::NumExprFields + 1]); + case EXPR_CXX_STATIC_CAST: { + BitsUnpacker CastExprBits(Record[ASTStmtReader::NumStmtFields]); + CastExprBits.advance(ASTStmtReader::NumExprBits); + unsigned PathSize = Record[ASTStmtReader::NumExprFields]; + bool HasFPFeatures = CastExprBits.getNextBit(); + S = CXXStaticCastExpr::CreateEmpty(Context, PathSize, HasFPFeatures); break; + } - case EXPR_CXX_DYNAMIC_CAST: - S = CXXDynamicCastExpr::CreateEmpty(Context, - /*PathSize*/ Record[ASTStmtReader::NumExprFields]); + case EXPR_CXX_DYNAMIC_CAST: { + unsigned PathSize = Record[ASTStmtReader::NumExprFields]; + S = CXXDynamicCastExpr::CreateEmpty(Context, PathSize); break; + } - case EXPR_CXX_REINTERPRET_CAST: - S = CXXReinterpretCastExpr::CreateEmpty(Context, - /*PathSize*/ Record[ASTStmtReader::NumExprFields]); + case EXPR_CXX_REINTERPRET_CAST: { + unsigned PathSize = Record[ASTStmtReader::NumExprFields]; + S = CXXReinterpretCastExpr::CreateEmpty(Context, PathSize); break; + } case EXPR_CXX_CONST_CAST: S = CXXConstCastExpr::CreateEmpty(Context); @@ -3839,21 +3902,28 @@ Stmt *ASTReader::ReadStmtFromStream(ModuleFile &F) { S = CXXAddrspaceCastExpr::CreateEmpty(Context); break; - case EXPR_CXX_FUNCTIONAL_CAST: - S = CXXFunctionalCastExpr::CreateEmpty( - Context, - /*PathSize*/ Record[ASTStmtReader::NumExprFields], - /*HasFPFeatures*/ Record[ASTStmtReader::NumExprFields + 1]); + case EXPR_CXX_FUNCTIONAL_CAST: { + BitsUnpacker CastExprBits(Record[ASTStmtReader::NumStmtFields]); + CastExprBits.advance(ASTStmtReader::NumExprBits); + unsigned PathSize = Record[ASTStmtReader::NumExprFields]; + bool HasFPFeatures = CastExprBits.getNextBit(); + S = CXXFunctionalCastExpr::CreateEmpty(Context, PathSize, HasFPFeatures); break; + } - case EXPR_BUILTIN_BIT_CAST: - assert(Record[ASTStmtReader::NumExprFields] == 0 && "Wrong PathSize!"); + case EXPR_BUILTIN_BIT_CAST: { +#ifndef NDEBUG + unsigned PathSize = Record[ASTStmtReader::NumExprFields]; + assert(PathSize == 0 && "Wrong PathSize!"); +#endif S = new (Context) BuiltinBitCastExpr(Empty); break; + } case EXPR_USER_DEFINED_LITERAL: { - BitsUnpacker CallExprBits(Record[ASTStmtReader::NumExprFields]); - auto NumArgs = CallExprBits.getNextBits(/*Width=*/16); + BitsUnpacker CallExprBits(Record[ASTStmtReader::NumStmtFields]); + CallExprBits.advance(ASTStmtReader::NumExprBits); + auto NumArgs = CallExprBits.getNextBits(/*Width=*/13); auto HasFPFeatures = CallExprBits.getNextBit(); S = UserDefinedLiteral::CreateEmpty(Context, NumArgs, HasFPFeatures, Empty); @@ -3944,47 +4014,63 @@ Stmt *ASTReader::ReadStmtFromStream(ModuleFile &F) { Record[ASTStmtReader::NumExprFields]); break; - case EXPR_CXX_DEPENDENT_SCOPE_MEMBER: + case EXPR_CXX_DEPENDENT_SCOPE_MEMBER: { + BitsUnpacker DependentScopeMemberBits( + Record[ASTStmtReader::NumStmtFields]); + DependentScopeMemberBits.advance(ASTStmtReader::NumExprBits); + bool HasTemplateKWAndArgsInfo = DependentScopeMemberBits.getNextBit(); + unsigned NumTemplateArgs = + DependentScopeMemberBits.getNextBits(/*Width=*/16); + bool HasFirstQualifierFoundInScope = + DependentScopeMemberBits.getNextBit(); S = CXXDependentScopeMemberExpr::CreateEmpty( - Context, - /*HasTemplateKWAndArgsInfo=*/Record[ASTStmtReader::NumExprFields], - /*NumTemplateArgs=*/Record[ASTStmtReader::NumExprFields + 1], - /*HasFirstQualifierFoundInScope=*/ - Record[ASTStmtReader::NumExprFields + 2]); + Context, HasTemplateKWAndArgsInfo, NumTemplateArgs, + HasFirstQualifierFoundInScope); break; + } - case EXPR_CXX_DEPENDENT_SCOPE_DECL_REF: - S = DependentScopeDeclRefExpr::CreateEmpty(Context, - /*HasTemplateKWAndArgsInfo=*/Record[ASTStmtReader::NumExprFields], - /*NumTemplateArgs=*/Record[ASTStmtReader::NumExprFields] - ? Record[ASTStmtReader::NumExprFields + 1] - : 0); + case EXPR_CXX_DEPENDENT_SCOPE_DECL_REF: { + BitsUnpacker DependentScopeDeclRefBits( + Record[ASTStmtReader::NumStmtFields]); + DependentScopeDeclRefBits.advance(ASTStmtReader::NumExprBits); + bool HasTemplateKWAndArgsInfo = DependentScopeDeclRefBits.getNextBit(); + unsigned NumTemplateArgs = + HasTemplateKWAndArgsInfo + ? DependentScopeDeclRefBits.getNextBits(/*Width=*/16) + : 0; + S = DependentScopeDeclRefExpr::CreateEmpty( + Context, HasTemplateKWAndArgsInfo, NumTemplateArgs); break; + } case EXPR_CXX_UNRESOLVED_CONSTRUCT: S = CXXUnresolvedConstructExpr::CreateEmpty(Context, /*NumArgs=*/Record[ASTStmtReader::NumExprFields]); break; - case EXPR_CXX_UNRESOLVED_MEMBER: + case EXPR_CXX_UNRESOLVED_MEMBER: { + BitsUnpacker OverloadExprBits(Record[ASTStmtReader::NumExprFields]); + auto NumResults = OverloadExprBits.getNextBits(/*Width=*/12); + auto HasTemplateKWAndArgsInfo = OverloadExprBits.getNextBit(); + auto NumTemplateArgs = HasTemplateKWAndArgsInfo + ? OverloadExprBits.getNextBits(/*Width=*/12) + : 0; S = UnresolvedMemberExpr::CreateEmpty( - Context, - /*NumResults=*/Record[ASTStmtReader::NumExprFields] & ((1 << 14) - 1), - /*HasTemplateKWAndArgsInfo=*/ - (Record[ASTStmtReader::NumExprFields] >> 14) & (0x1), - /*NumTemplateArgs=*/Record[ASTStmtReader::NumExprFields] >> 14 & - ((1 << 14) - 1)); + Context, NumResults, HasTemplateKWAndArgsInfo, NumTemplateArgs); break; + } - case EXPR_CXX_UNRESOLVED_LOOKUP: + case EXPR_CXX_UNRESOLVED_LOOKUP: { + BitsUnpacker OverloadExprBits(Record[ASTStmtReader::NumExprFields]); + auto NumResults = OverloadExprBits.getNextBits(/*Width=*/12); + auto HasTemplateKWAndArgsInfo = OverloadExprBits.getNextBit(); + auto NumTemplateArgs = HasTemplateKWAndArgsInfo + ? OverloadExprBits.getNextBits(/*Width=*/12) + : 0; S = UnresolvedLookupExpr::CreateEmpty( - Context, - /*NumResults=*/Record[ASTStmtReader::NumExprFields] & ((1 << 14) - 1), - /*HasTemplateKWAndArgsInfo=*/ - (Record[ASTStmtReader::NumExprFields] >> 14) & (0x1), - /*NumTemplateArgs=*/Record[ASTStmtReader::NumExprFields] >> 14 & - ((1 << 14) - 1)); + Context, NumResults, HasTemplateKWAndArgsInfo, NumTemplateArgs); break; + } case EXPR_TYPE_TRAIT: S = TypeTraitExpr::CreateDeserialized(Context, @@ -4044,8 +4130,9 @@ Stmt *ASTReader::ReadStmtFromStream(ModuleFile &F) { break; case EXPR_CUDA_KERNEL_CALL: { - BitsUnpacker CallExprBits(Record[ASTStmtReader::NumExprFields]); - auto NumArgs = CallExprBits.getNextBits(/*Width=*/16); + BitsUnpacker CallExprBits(Record[ASTStmtReader::NumStmtFields]); + CallExprBits.advance(ASTStmtReader::NumExprBits); + auto NumArgs = CallExprBits.getNextBits(/*Width=*/13); auto HasFPFeatures = CallExprBits.getNextBit(); S = CUDAKernelCallExpr::CreateEmpty(Context, NumArgs, HasFPFeatures, Empty); diff --git a/clang/lib/Serialization/ASTWriter.cpp b/clang/lib/Serialization/ASTWriter.cpp index 91eb2af8f8ad6..78939bfd533ff 100644 --- a/clang/lib/Serialization/ASTWriter.cpp +++ b/clang/lib/Serialization/ASTWriter.cpp @@ -6003,12 +6003,17 @@ void ASTRecordWriter::AddCXXDefinitionData(const CXXRecordDecl *D) { BitsPacker DefinitionBits; -#define FIELD(Name, Width, Merge) DefinitionBits.addBits(Data.Name, Width); +#define FIELD(Name, Width, Merge) \ + if (!DefinitionBits.canWriteNextNBits(Width)) { \ + Record->push_back(DefinitionBits); \ + DefinitionBits.reset(0); \ + } \ + DefinitionBits.addBits(Data.Name, Width); + #include "clang/AST/CXXRecordDeclDefinitionBits.def" #undef FIELD - while (DefinitionBits.hasUnconsumedValues()) - Record->push_back(DefinitionBits.getNextValue()); + Record->push_back(DefinitionBits); // getODRHash will compute the ODRHash if it has not been previously computed. Record->push_back(D->getODRHash()); @@ -6047,7 +6052,7 @@ void ASTRecordWriter::AddCXXDefinitionData(const CXXRecordDecl *D) { LambdaBits.addBits(Lambda.CaptureDefault, /*Width=*/2); LambdaBits.addBits(Lambda.NumCaptures, /*Width=*/15); LambdaBits.addBit(Lambda.HasKnownInternalLinkage); - Record->push_back(LambdaBits.getNextValue()); + Record->push_back(LambdaBits); Record->push_back(Lambda.NumExplicitCaptures); Record->push_back(Lambda.ManglingNumber); @@ -6058,10 +6063,12 @@ void ASTRecordWriter::AddCXXDefinitionData(const CXXRecordDecl *D) { for (unsigned I = 0, N = Lambda.NumCaptures; I != N; ++I) { const LambdaCapture &Capture = Lambda.Captures.front()[I]; AddSourceLocation(Capture.getLocation()); + BitsPacker CaptureBits; CaptureBits.addBit(Capture.isImplicit()); CaptureBits.addBits(Capture.getCaptureKind(), /*Width=*/3); Record->push_back(CaptureBits); + switch (Capture.getCaptureKind()) { case LCK_StarThis: case LCK_This: diff --git a/clang/lib/Serialization/ASTWriterDecl.cpp b/clang/lib/Serialization/ASTWriterDecl.cpp index 43169b2befc68..dae45aeb52e96 100644 --- a/clang/lib/Serialization/ASTWriterDecl.cpp +++ b/clang/lib/Serialization/ASTWriterDecl.cpp @@ -496,15 +496,10 @@ void ASTDeclWriter::VisitEnumDecl(EnumDecl *D) { if (D->getDeclContext() == D->getLexicalDeclContext() && !D->hasAttrs() && !D->isImplicit() && - !D->isUsed(false) && !D->hasExtInfo() && !D->getTypedefNameForAnonDecl() && D->getFirstDecl() == D->getMostRecentDecl() && - !D->isInvalidDecl() && - !D->isReferenced() && !D->isTopLevelDeclInObjCContainer() && - D->getAccess() == AS_none && - !D->isModulePrivate() && !CXXRecordDecl::classofKind(D->getKind()) && !D->getIntegerTypeSourceInfo() && !D->getMemberSpecializationInfo() && @@ -544,16 +539,10 @@ void ASTDeclWriter::VisitRecordDecl(RecordDecl *D) { if (D->getDeclContext() == D->getLexicalDeclContext() && !D->hasAttrs() && - !D->isImplicit() && - !D->isUsed(false) && !D->hasExtInfo() && !D->getTypedefNameForAnonDecl() && D->getFirstDecl() == D->getMostRecentDecl() && - !D->isInvalidDecl() && - !D->isReferenced() && !D->isTopLevelDeclInObjCContainer() && - D->getAccess() == AS_none && - !D->isModulePrivate() && !CXXRecordDecl::classofKind(D->getKind()) && !needsAnonymousDeclarationNumber(D) && D->getDeclName().getNameKind() == DeclarationName::Identifier) @@ -1137,13 +1126,7 @@ void ASTDeclWriter::VisitVarDecl(VarDecl *D) { if (D->getDeclContext() == D->getLexicalDeclContext() && !D->hasAttrs() && - !D->isImplicit() && - !D->isUsed(false) && - !D->isInvalidDecl() && - !D->isReferenced() && !D->isTopLevelDeclInObjCContainer() && - D->getAccess() == AS_none && - !D->isModulePrivate() && !needsAnonymousDeclarationNumber(D) && D->getDeclName().getNameKind() == DeclarationName::Identifier && !D->hasExtInfo() && @@ -1193,14 +1176,9 @@ void ASTDeclWriter::VisitParmVarDecl(ParmVarDecl *D) { // we dynamically check for the properties that we optimize for, but don't // know are true of all PARM_VAR_DECLs. if (D->getDeclContext() == D->getLexicalDeclContext() && !D->hasAttrs() && - !D->hasExtInfo() && !D->isImplicit() && !D->isUsed(false) && - !D->isInvalidDecl() && !D->isReferenced() && D->getAccess() == AS_none && - !D->isModulePrivate() && D->getStorageClass() == 0 && + !D->hasExtInfo() && D->getStorageClass() == 0 && D->getInitStyle() == VarDecl::CInit && // Can params have anything else? - D->getFunctionScopeDepth() == 0 && D->getObjCDeclQualifier() == 0 && - !D->isKNRPromoted() && !D->isExplicitObjectParameter() && - !D->hasInheritedDefaultArg() && D->getInit() == nullptr && - !D->hasUninstantiatedDefaultArg()) // No default expr. + D->getInit() == nullptr) // No default expr. AbbrevToUse = Writer.getDeclParmVarAbbrev(); // Check things we know are true of *every* PARM_VAR_DECL, which is more than @@ -1403,6 +1381,13 @@ void ASTDeclWriter::VisitUsingShadowDecl(UsingShadowDecl *D) { Record.push_back(D->getIdentifierNamespace()); Record.AddDeclRef(D->UsingOrNextShadow); Record.AddDeclRef(Context.getInstantiatedFromUsingShadowDecl(D)); + + if (D->getDeclContext() == D->getLexicalDeclContext() && + D->getFirstDecl() == D->getMostRecentDecl() && !D->hasAttrs() && + !needsAnonymousDeclarationNumber(D) && + D->getDeclName().getNameKind() == DeclarationName::Identifier) + AbbrevToUse = Writer.getDeclUsingShadowAbbrev(); + Code = serialization::DECL_USING_SHADOW; } @@ -1507,10 +1492,32 @@ void ASTDeclWriter::VisitCXXMethodDecl(CXXMethodDecl *D) { D->getFirstDecl() == D->getMostRecentDecl() && !D->isInvalidDecl() && !D->hasAttrs() && !D->isTopLevelDeclInObjCContainer() && D->getDeclName().getNameKind() == DeclarationName::Identifier && - !D->hasExtInfo() && !D->hasInheritedPrototype() && - D->hasWrittenPrototype() && - D->getTemplatedKind() == FunctionDecl::TK_NonTemplate) - AbbrevToUse = Writer.getDeclCXXMethodAbbrev(); + !D->hasExtInfo() && !D->isExplicitlyDefaulted()) { + if (D->getTemplatedKind() == FunctionDecl::TK_NonTemplate || + D->getTemplatedKind() == FunctionDecl::TK_FunctionTemplate || + D->getTemplatedKind() == FunctionDecl::TK_MemberSpecialization || + D->getTemplatedKind() == FunctionDecl::TK_DependentNonTemplate) + AbbrevToUse = Writer.getDeclCXXMethodAbbrev(D->getTemplatedKind()); + else if (D->getTemplatedKind() == + FunctionDecl::TK_FunctionTemplateSpecialization) { + FunctionTemplateSpecializationInfo *FTSInfo = + D->getTemplateSpecializationInfo(); + + if (FTSInfo->TemplateArguments->size() == 1) { + const TemplateArgument &TA = FTSInfo->TemplateArguments->get(0); + if (TA.getKind() == TemplateArgument::Type && + !FTSInfo->TemplateArgumentsAsWritten && + !FTSInfo->getMemberSpecializationInfo()) + AbbrevToUse = Writer.getDeclCXXMethodAbbrev(D->getTemplatedKind()); + } + } else if (D->getTemplatedKind() == + FunctionDecl::TK_DependentFunctionTemplateSpecialization) { + DependentFunctionTemplateSpecializationInfo *DFTSInfo = + D->getDependentSpecializationInfo(); + if (!DFTSInfo->TemplateArgumentsAsWritten) + AbbrevToUse = Writer.getDeclCXXMethodAbbrev(D->getTemplatedKind()); + } + } Code = serialization::DECL_CXX_METHOD; } @@ -1782,7 +1789,7 @@ void ASTDeclWriter::VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D) { Record.push_back(D->wasDeclaredWithTypename()); const TypeConstraint *TC = D->getTypeConstraint(); - Record.push_back(TC != nullptr); + assert((bool)TC == D->hasTypeConstraint()); if (TC) { auto *CR = TC->getConceptReference(); Record.push_back(CR != nullptr); @@ -1800,6 +1807,13 @@ void ASTDeclWriter::VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D) { if (OwnsDefaultArg) Record.AddTypeSourceInfo(D->getDefaultArgumentInfo()); + if (!TC && !OwnsDefaultArg && + D->getDeclContext() == D->getLexicalDeclContext() && + !D->isInvalidDecl() && !D->hasAttrs() && + !D->isTopLevelDeclInObjCContainer() && + D->getDeclName().getNameKind() == DeclarationName::Identifier) + AbbrevToUse = Writer.getDeclTemplateTypeParmAbbrev(); + Code = serialization::DECL_TEMPLATE_TYPE_PARM; } @@ -2031,6 +2045,104 @@ void ASTDeclWriter::VisitOMPCapturedExprDecl(OMPCapturedExprDecl *D) { // ASTWriter Implementation //===----------------------------------------------------------------------===// +namespace { +template +std::shared_ptr +getFunctionDeclAbbrev(serialization::DeclCode Code) { + using namespace llvm; + + auto Abv = std::make_shared(); + Abv->Add(BitCodeAbbrevOp(Code)); + // RedeclarableDecl + Abv->Add(BitCodeAbbrevOp(0)); // CanonicalDecl + Abv->Add(BitCodeAbbrevOp(Kind)); + if constexpr (Kind == FunctionDecl::TK_NonTemplate) { + + } else if constexpr (Kind == FunctionDecl::TK_FunctionTemplate) { + // DescribedFunctionTemplate + Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); + } else if constexpr (Kind == FunctionDecl::TK_DependentNonTemplate) { + // Instantiated From Decl + Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); + } else if constexpr (Kind == FunctionDecl::TK_MemberSpecialization) { + Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // InstantiatedFrom + Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, + 3)); // TemplateSpecializationKind + Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Specialized Location + } else if constexpr (Kind == + FunctionDecl::TK_FunctionTemplateSpecialization) { + Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Template + Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, + 3)); // TemplateSpecializationKind + Abv->Add(BitCodeAbbrevOp(1)); // Template Argument Size + Abv->Add(BitCodeAbbrevOp(TemplateArgument::Type)); // Template Argument Kind + Abv->Add( + BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Template Argument Type + Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // Is Defaulted + Abv->Add(BitCodeAbbrevOp(0)); // TemplateArgumentsAsWritten + Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // SourceLocation + Abv->Add(BitCodeAbbrevOp(0)); + Abv->Add( + BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Canonical Decl of template + } else if constexpr (Kind == FunctionDecl:: + TK_DependentFunctionTemplateSpecialization) { + // Candidates of specialization + Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Array)); + Abv->Add(BitCodeAbbrevOp(0)); // TemplateArgumentsAsWritten + } else { + llvm_unreachable("Unknown templated kind?"); + } + // Decl + Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, + 12)); // Packed DeclBits: HasStandaloneLexicalDC, + // isInvalidDecl, HasAttrs, isImplicit, isUsed, + // isReferenced, TopLevelDeclInObjCContainer, + // AccessSpecifier, ModuleOwnershipKind + Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // DeclContext + Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // SubmoduleID + // NamedDecl + Abv->Add(BitCodeAbbrevOp(DeclarationName::Identifier)); // NameKind + Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Identifier + Abv->Add(BitCodeAbbrevOp(0)); // AnonDeclNumber + // ValueDecl + Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Type + // DeclaratorDecl + Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // InnerLocStart + Abv->Add(BitCodeAbbrevOp(0)); // HasExtInfo + Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // TSIType + // FunctionDecl + Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 11)); // IDNS + Abv->Add(BitCodeAbbrevOp( + BitCodeAbbrevOp::Fixed, + 27)); // Packed Function Bits: StorageClass, Inline, InlineSpecified, + // VirtualAsWritten, Pure, HasInheritedProto, HasWrittenProto, + // Deleted, Trivial, TrivialForCall, Defaulted, ExplicitlyDefaulted, + // IsIneligibleOrNotSelected, ImplicitReturnZero, Constexpr, + // UsesSEHTry, SkippedBody, MultiVersion, LateParsed, + // FriendConstraintRefersToEnclosingTemplate, Linkage + 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 + // (nearly) all the remaining (variable number of) fields in the same way. + // + // This is: + // NumParams and Params[] from FunctionDecl, and + // NumOverriddenMethods, OverriddenMethods[] from CXXMethodDecl. + // + // Add an AbbrevOp for 'size then elements' and use it here. + Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Array)); + return std::move(Abv); +} + +template +std::shared_ptr getCXXMethodAbbrev() { + using namespace llvm; + auto Abv = getFunctionDeclAbbrev(serialization::DECL_CXX_METHOD); + Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); + return std::move(Abv); +} +} // namespace + void ASTWriter::WriteDeclAbbrevs() { using namespace llvm; @@ -2290,71 +2402,81 @@ void ASTWriter::WriteDeclAbbrevs() { DeclVarAbbrev = Stream.EmitAbbrev(std::move(Abv)); // Abbreviation for DECL_CXX_METHOD + DeclCXXMethodAbbrev = + Stream.EmitAbbrev(getCXXMethodAbbrev()); + DeclTemplateCXXMethodAbbrev = Stream.EmitAbbrev( + getCXXMethodAbbrev()); + DeclDependentNonTemplateCXXMethodAbbrev = Stream.EmitAbbrev( + getCXXMethodAbbrev()); + DeclMemberSpecializedCXXMethodAbbrev = Stream.EmitAbbrev( + getCXXMethodAbbrev()); + DeclTemplateSpecializedCXXMethodAbbrev = Stream.EmitAbbrev( + getCXXMethodAbbrev()); + DeclDependentSpecializationCXXMethodAbbrev = Stream.EmitAbbrev( + getCXXMethodAbbrev< + FunctionDecl::TK_DependentFunctionTemplateSpecialization>()); + + // Abbreviation for DECL_TEMPLATE_TYPE_PARM Abv = std::make_shared(); - Abv->Add(BitCodeAbbrevOp(serialization::DECL_CXX_METHOD)); - // RedeclarableDecl - Abv->Add(BitCodeAbbrevOp(0)); // CanonicalDecl - // FIXME: Implement abbreviation for other template kinds. - Abv->Add(BitCodeAbbrevOp(FunctionDecl::TK_NonTemplate)); // TemplateKind + Abv->Add(BitCodeAbbrevOp(serialization::DECL_TEMPLATE_TYPE_PARM)); + Abv->Add(BitCodeAbbrevOp(0)); // hasTypeConstraint // Decl Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 12)); // Packed DeclBits: HasStandaloneLexicalDC, // isInvalidDecl, HasAttrs, isImplicit, isUsed, // isReferenced, TopLevelDeclInObjCContainer, // AccessSpecifier, ModuleOwnershipKind - Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // DeclContext - Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // SubmoduleID + Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // DeclContext + Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // SubmoduleID // NamedDecl - Abv->Add(BitCodeAbbrevOp(DeclarationName::Identifier)); // NameKind - Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Identifier - Abv->Add(BitCodeAbbrevOp(0)); // AnonDeclNumber - // ValueDecl - Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Type - // DeclaratorDecl - Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // InnerLocStart - Abv->Add(BitCodeAbbrevOp(0)); // HasExtInfo - Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // TSIType - // FunctionDecl + Abv->Add(BitCodeAbbrevOp(0)); // NameKind = Identifier + Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Name + Abv->Add(BitCodeAbbrevOp(0)); + // TypeDecl + Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Source Location + Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Type Ref + // TemplateTypeParmDecl + Abv->Add( + BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // wasDeclaredWithTypename + Abv->Add(BitCodeAbbrevOp(0)); // OwnsDefaultArg + DeclTemplateTypeParmAbbrev = Stream.EmitAbbrev(std::move(Abv)); + + // Abbreviation for DECL_USING_SHADOW + Abv = std::make_shared(); + Abv->Add(BitCodeAbbrevOp(serialization::DECL_USING_SHADOW)); + // Redeclarable + Abv->Add(BitCodeAbbrevOp(0)); // No redeclaration + // Decl + Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, + 12)); // Packed DeclBits: HasStandaloneLexicalDC, + // isInvalidDecl, HasAttrs, isImplicit, isUsed, + // isReferenced, TopLevelDeclInObjCContainer, + // AccessSpecifier, ModuleOwnershipKind + Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // DeclContext + Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // SubmoduleID + // NamedDecl + Abv->Add(BitCodeAbbrevOp(0)); // NameKind = Identifier + Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Name + Abv->Add(BitCodeAbbrevOp(0)); + // UsingShadowDecl + Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // TargetDecl Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 11)); // IDNS - Abv->Add(BitCodeAbbrevOp( - BitCodeAbbrevOp::Fixed, - 27)); // Packed Function Bits: StorageClass, Inline, InlineSpecified, - // VirtualAsWritten, Pure, HasInheritedProto, HasWrittenProto, - // Deleted, Trivial, TrivialForCall, Defaulted, ExplicitlyDefaulted, - // IsIneligibleOrNotSelected, ImplicitReturnZero, Constexpr, - // UsesSEHTry, SkippedBody, MultiVersion, LateParsed, - // FriendConstraintRefersToEnclosingTemplate, Linkage - Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // LocEnd - Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Default - Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32)); // ODRHash - // This Array slurps the rest of the record. Fortunately we want to encode - // (nearly) all the remaining (variable number of) fields in the same way. - // - // This is: - // NumParams and Params[] from FunctionDecl, and - // NumOverriddenMethods, OverriddenMethods[] from CXXMethodDecl. - // - // Add an AbbrevOp for 'size then elements' and use it here. - Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Array)); - Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); - DeclCXXMethodAbbrev = Stream.EmitAbbrev(std::move(Abv)); + Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // UsingOrNextShadow + Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, + 6)); // InstantiatedFromUsingShadowDecl + DeclUsingShadowAbbrev = Stream.EmitAbbrev(std::move(Abv)); // Abbreviation for EXPR_DECL_REF Abv = std::make_shared(); Abv->Add(BitCodeAbbrevOp(serialization::EXPR_DECL_REF)); - //Stmt - // Expr + // Stmt + // Expr + // PackingBits: DependenceKind, ValueKind, ObjectKind, HasQualifier, + // GetDeclFound, ExplicitTemplateArgs, HadMultipleCandidates, + // NonOdrUseReason, RefersToEnclosingVariableOrCapture, IsImmediateEscalating + Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 18)); Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Type - // DependenceKind, ValueKind, ObjectKind - Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 10)); - //DeclRefExpr - Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); //HasQualifier - Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); //GetDeclFound - Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); //ExplicitTemplateArgs - Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); //HadMultipleCandidates - Abv->Add(BitCodeAbbrevOp(0)); // RefersToEnclosingVariableOrCapture - Abv->Add(BitCodeAbbrevOp(0)); // NonOdrUseReason - Abv->Add(BitCodeAbbrevOp(0)); // IsImmediateEscalating + // DeclRefExpr Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // DeclRef Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Location DeclRefExprAbbrev = Stream.EmitAbbrev(std::move(Abv)); @@ -2364,10 +2486,10 @@ void ASTWriter::WriteDeclAbbrevs() { Abv->Add(BitCodeAbbrevOp(serialization::EXPR_INTEGER_LITERAL)); //Stmt // Expr - Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Type // DependenceKind, ValueKind, ObjectKind Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 10)); - //Integer Literal + Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Type + // Integer Literal Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Location Abv->Add(BitCodeAbbrevOp(32)); // Bit Width Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Value @@ -2378,10 +2500,10 @@ void ASTWriter::WriteDeclAbbrevs() { Abv->Add(BitCodeAbbrevOp(serialization::EXPR_CHARACTER_LITERAL)); //Stmt // Expr - Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Type // DependenceKind, ValueKind, ObjectKind Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 10)); - //Character Literal + Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Type + // Character Literal Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // getValue Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Location Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 3)); // getKind @@ -2392,17 +2514,98 @@ void ASTWriter::WriteDeclAbbrevs() { Abv->Add(BitCodeAbbrevOp(serialization::EXPR_IMPLICIT_CAST)); // Stmt // Expr + // Packing Bits: DependenceKind, ValueKind, ObjectKind, + // HasFPFeatures, CastKind, PartOfExplicitCast + Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 19)); Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Type - // DependenceKind, ValueKind, ObjectKind - Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 10)); // CastExpr Abv->Add(BitCodeAbbrevOp(0)); // PathSize - Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // HasFPFeatures - Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 6)); // CastKind - Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // PartOfExplicitCast // ImplicitCastExpr ExprImplicitCastAbbrev = Stream.EmitAbbrev(std::move(Abv)); + // Abbreviation for EXPR_BINARY_OPERATOR + Abv = std::make_shared(); + Abv->Add(BitCodeAbbrevOp(serialization::EXPR_BINARY_OPERATOR)); + // Stmt + // Expr + // Packing Bits: DependenceKind, ValueKind, ObjectKind, + // HasFPFeatures, OpKind + Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 17)); + Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Type + // BinaryOperator + Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Source Location + BinaryOperatorAbbrev = Stream.EmitAbbrev(std::move(Abv)); + + // Abbreviation for EXPR_COMPOUND_ASSIGN_OPERATOR + Abv = std::make_shared(); + Abv->Add(BitCodeAbbrevOp(serialization::EXPR_COMPOUND_ASSIGN_OPERATOR)); + // Stmt + // Expr + // Packing Bits: DependenceKind, ValueKind, ObjectKind, + // HasFPFeatures, OpKind + Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 17)); + Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Type + // BinaryOperator + Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Source Location + // CompoundAssignOperator + Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // LHSType + Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Result Type + CompoundAssignOperatorAbbrev = Stream.EmitAbbrev(std::move(Abv)); + + // Abbreviation for EXPR_CALL + Abv = std::make_shared(); + Abv->Add(BitCodeAbbrevOp(serialization::EXPR_CALL)); + // Stmt + // Expr + // Packing Bits: DependenceKind, ValueKind, ObjectKind, + // NumArgs, hasStoredFPFeatures, ADLCallKind + Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 25)); + Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Type + // CallExpr + Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Source Location + CallExprAbbrev = Stream.EmitAbbrev(std::move(Abv)); + + // Abbreviation for EXPR_CXX_OPERATOR_CALL + Abv = std::make_shared(); + Abv->Add(BitCodeAbbrevOp(serialization::EXPR_CXX_OPERATOR_CALL)); + // Stmt + // Expr + // Packing Bits: DependenceKind, ValueKind, ObjectKind, + // NumArgs, hasStoredFPFeatures, ADLCallKind, OperatorKind + Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 31)); + Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Type + // CallExpr + Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Source Location + // CXXOperatorCallExpr + Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Source Location + Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Source Location + CXXOperatorCallExprAbbrev = Stream.EmitAbbrev(std::move(Abv)); + + // Abbreviation for EXPR_CXX_MEMBER_CALL + Abv = std::make_shared(); + Abv->Add(BitCodeAbbrevOp(serialization::EXPR_CXX_MEMBER_CALL)); + // Stmt + // Expr + // Packing Bits: DependenceKind, ValueKind, ObjectKind, + // NumArgs, hasStoredFPFeatures, ADLCallKind + Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 25)); + Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Type + // CallExpr + Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Source Location + // CXXMemberCallExpr + CXXMemberCallExprAbbrev = Stream.EmitAbbrev(std::move(Abv)); + + // Abbreviation for STMT_COMPOUND + Abv = std::make_shared(); + Abv->Add(BitCodeAbbrevOp(serialization::STMT_COMPOUND)); + // Stmt + // CompoundStmt + // Packing Bits: Num Stmts, hasStoredFPFeatures + Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 21)); + Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Source Location + Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Source Location + CompoundStmtAbbrev = Stream.EmitAbbrev(std::move(Abv)); + Abv = std::make_shared(); Abv->Add(BitCodeAbbrevOp(serialization::DECL_CONTEXT_LEXICAL)); Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); diff --git a/clang/lib/Serialization/ASTWriterStmt.cpp b/clang/lib/Serialization/ASTWriterStmt.cpp index 8524484ea8a0b..10139f1dc96ae 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 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,22 @@ void ASTStmtWriter::VisitNullStmt(NullStmt *S) { void ASTStmtWriter::VisitCompoundStmt(CompoundStmt *S) { VisitStmt(S); - Record.push_back(S->size()); - Record.push_back(S->hasStoredFPFeatures()); + + CurrentPackingBits.updateBits(); + // 20 bits should be enough to store the size of stmts. + CurrentPackingBits.addBits(S->size(), /*Width=*/20); + CurrentPackingBits.addBit(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 +206,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(S->getStatementKind())); Record.AddStmt(S->getCond()); Record.AddStmt(S->getThen()); @@ -548,15 +613,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,26 +675,25 @@ 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.addBit(E->hasQualifier()); + CurrentPackingBits.addBit(E->getDecl() != E->getFoundDecl()); + CurrentPackingBits.addBit(E->hasTemplateKWAndArgsInfo()); + CurrentPackingBits.addBit(E->hadMultipleCandidates()); + CurrentPackingBits.addBit(E->refersToEnclosingVariableOrCapture()); + CurrentPackingBits.addBits(E->isNonOdrUse(), /*Width=*/2); + CurrentPackingBits.addBit(E->isImmediateEscalating()); if (E->hasTemplateKWAndArgsInfo()) { unsigned NumTemplateArgs = E->getNumTemplateArgs(); - Record.push_back(NumTemplateArgs); + // 12 bits should be sufficient to store the number of template args. + CurrentPackingBits.addBits(NumTemplateArgs, /*Width=*/12); } DeclarationName::NameKind nk = (E->getDecl()->getDeclName().getNameKind()); if ((!E->hasTemplateKWAndArgsInfo()) && (!E->hasQualifier()) && (E->getDecl() == E->getFoundDecl()) && - nk == DeclarationName::Identifier && - !E->refersToEnclosingVariableOrCapture() && !E->isNonOdrUse() && - !E->isImmediateEscalating()) { + nk == DeclarationName::Identifier) { AbbrevToUse = Writer.getDeclRefExprAbbrev(); } @@ -742,11 +804,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 +936,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(E->getADLCallKind())); - Record.push_back(CallExprBits); + // 13 bits should be sufficient to store the number args; + CurrentPackingBits.addBits(E->getNumArgs(), /*BitsWidth=*/13); + CurrentPackingBits.addBit(E->hasStoredFPFeatures()); + CurrentPackingBits.addBit(static_cast(E->getADLCallKind())); Record.AddSourceLocation(E->getRParenLoc()); Record.AddStmt(E->getCallee()); @@ -887,6 +949,10 @@ void ASTStmtWriter::VisitCallExpr(CallExpr *E) { if (E->hasStoredFPFeatures()) Record.push_back(E->getFPFeatures().getAsOpaqueInt()); + + if (!E->hasStoredFPFeatures() && E->getStmtClass() == Stmt::CallExprClass) + AbbrevToUse = Writer.getCallExprAbbrev(); + Code = serialization::EXPR_CALL; } @@ -913,25 +979,27 @@ 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); - Record.push_back(NumTemplateArgs); + + CurrentPackingBits.addBit(HasQualifier); + CurrentPackingBits.addBit(HasFoundDecl); + CurrentPackingBits.addBit(HasTemplateInfo); + // 12 bits should be enough to store the number of args + CurrentPackingBits.addBits(NumTemplateArgs, /*Width=*/12); Record.AddStmt(E->getBase()); Record.AddDeclRef(E->getMemberDecl()); 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 +1039,12 @@ void ASTStmtWriter::VisitObjCBridgedCastExpr(ObjCBridgedCastExpr *E) { void ASTStmtWriter::VisitCastExpr(CastExpr *E) { VisitExpr(E); + Record.push_back(E->path_size()); - Record.push_back(E->hasStoredFPFeatures()); + CurrentPackingBits.addBit(E->hasStoredFPFeatures()); + // 7 bits should be enough to store the casting kinds. + CurrentPackingBits.addBits(E->getCastKind(), /*Width=*/7); 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) @@ -989,13 +1059,17 @@ void ASTStmtWriter::VisitBinaryOperator(BinaryOperator *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.addBit(HasFPFeatures); + CurrentPackingBits.addBits(E->getOpcode(), /*Width=*/6); Record.AddStmt(E->getLHS()); Record.AddStmt(E->getRHS()); Record.AddSourceLocation(E->getOperatorLoc()); if (HasFPFeatures) Record.push_back(E->getStoredFPFeatures().getAsOpaqueInt()); + + if (!HasFPFeatures) + AbbrevToUse = Writer.getBinaryOperatorAbbrev(); + Code = serialization::EXPR_BINARY_OPERATOR; } @@ -1003,6 +1077,10 @@ void ASTStmtWriter::VisitCompoundAssignOperator(CompoundAssignOperator *E) { VisitBinaryOperator(E); Record.AddTypeRef(E->getComputationLHSType()); Record.AddTypeRef(E->getComputationResultType()); + + if (!E->hasStoredFPFeatures()) + AbbrevToUse = Writer.getCompoundAssignOperatorAbbrev(); + Code = serialization::EXPR_COMPOUND_ASSIGN_OPERATOR; } @@ -1031,7 +1109,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(); @@ -1586,13 +1664,21 @@ void ASTStmtWriter::VisitMSDependentExistsStmt(MSDependentExistsStmt *S) { void ASTStmtWriter::VisitCXXOperatorCallExpr(CXXOperatorCallExpr *E) { VisitCallExpr(E); - Record.push_back(E->getOperator()); + CurrentPackingBits.addBits(E->getOperator(), /*Width=*/6); Record.AddSourceRange(E->Range); + + if (!E->hasStoredFPFeatures()) + AbbrevToUse = Writer.getCXXOperatorCallExprAbbrev(); + Code = serialization::EXPR_CXX_OPERATOR_CALL; } void ASTStmtWriter::VisitCXXMemberCallExpr(CXXMemberCallExpr *E) { VisitCallExpr(E); + + if (!E->hasStoredFPFeatures()) + AbbrevToUse = Writer.getCXXMemberCallExprAbbrev(); + Code = serialization::EXPR_CXX_MEMBER_CALL; } @@ -1673,7 +1759,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) { @@ -1884,9 +1972,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.addBit(E->hasTemplateKWAndArgsInfo()); + // 16 bits should be enough to store the number of template args. + CurrentPackingBits.addBits(E->getNumTemplateArgs(), /*Width=*/16); + CurrentPackingBits.addBit(E->hasFirstQualifierFoundInScope()); if (E->hasTemplateKWAndArgsInfo()) { const ASTTemplateKWAndArgsInfo &ArgInfo = @@ -1895,14 +1984,15 @@ void ASTStmtWriter::VisitCXXDependentScopeMemberExpr( E->getTrailingObjects()); } - Record.push_back(E->isArrow()); - Record.AddSourceLocation(E->getOperatorLoc()); + CurrentPackingBits.addBit(E->isArrow()); + Record.AddTypeRef(E->getBaseType()); Record.AddNestedNameSpecifierLoc(E->getQualifierLoc()); - if (!E->isImplicitAccess()) + 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 +2007,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(); - 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()); } @@ -1949,19 +2041,17 @@ 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()); + CurrentPackingBits.updateBits(); + // 12 Bits should enough to store the number of decls. + CurrentPackingBits.addBits(E->getNumDecls(), /*BitWidth=*/12); + 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); + // 12 Bits should enough to store the number of template args. + CurrentPackingBits.addBits(ArgInfo.NumTemplateArgs, /*BitWidth=*/12); AddTemplateKWAndArgsInfo(ArgInfo, E->getTrailingTemplateArgumentLoc()); - } else - Record.push_back(OverloadExprBits); + } for (OverloadExpr::decls_iterator OvI = E->decls_begin(), OvE = E->decls_end(); @@ -1976,18 +2066,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); + 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()); - Record.AddSourceLocation(E->getOperatorLoc()); 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 +2153,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;