[clang] eccc1cc - Revert "[NFC] [Serialization] Packing more bits and refactor AbbrevToUse"

Augusto Noronha via cfe-commits cfe-commits at lists.llvm.org
Fri Dec 15 14:46:24 PST 2023


Author: Augusto Noronha
Date: 2023-12-15T14:43:25-08:00
New Revision: eccc1cca71bb704e4dcaabccc993d08fd15b46a2

URL: https://github.com/llvm/llvm-project/commit/eccc1cca71bb704e4dcaabccc993d08fd15b46a2
DIFF: https://github.com/llvm/llvm-project/commit/eccc1cca71bb704e4dcaabccc993d08fd15b46a2.diff

LOG: Revert "[NFC] [Serialization] Packing more bits and refactor AbbrevToUse"

This reverts commit 9cdb825a4f1bf9e75829d03879620c6144d0b7bc.

Added: 
    

Modified: 
    clang/include/clang/Serialization/ASTReader.h
    clang/include/clang/Serialization/ASTWriter.h
    clang/lib/Serialization/ASTReaderDecl.cpp
    clang/lib/Serialization/ASTReaderStmt.cpp
    clang/lib/Serialization/ASTWriter.cpp
    clang/lib/Serialization/ASTWriterDecl.cpp
    clang/lib/Serialization/ASTWriterStmt.cpp

Removed: 
    


################################################################################
diff  --git a/clang/include/clang/Serialization/ASTReader.h b/clang/include/clang/Serialization/ASTReader.h
index a6dd779386dc16..9bb89ec9410911 100644
--- a/clang/include/clang/Serialization/ASTReader.h
+++ b/clang/include/clang/Serialization/ASTReader.h
@@ -2422,8 +2422,6 @@ 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 16ab9583f8ed8e..a56929ef0245ee 100644
--- a/clang/include/clang/Serialization/ASTWriter.h
+++ b/clang/include/clang/Serialization/ASTWriter.h
@@ -564,25 +564,11 @@ 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);
@@ -749,42 +735,12 @@ class ASTWriter : public ASTDeserializationListener,
   unsigned getDeclFieldAbbrev() const { return DeclFieldAbbrev; }
   unsigned getDeclEnumAbbrev() const { return DeclEnumAbbrev; }
   unsigned getDeclObjCIvarAbbrev() const { return DeclObjCIvarAbbrev; }
-  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 getDeclCXXMethodAbbrev() const { return DeclCXXMethodAbbrev; }
 
   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; }
@@ -885,33 +841,46 @@ class BitsPacker {
   BitsPacker(BitsPacker &&) = delete;
   BitsPacker operator=(const BitsPacker &) = delete;
   BitsPacker operator=(BitsPacker &&) = delete;
-  ~BitsPacker() = default;
-
-  bool canWriteNextNBits(uint32_t BitsWidth) const {
-    return CurrentBitIndex + BitsWidth < BitIndexUpbound;
-  }
-
-  void reset(uint32_t Value) {
-    UnderlyingValue = Value;
-    CurrentBitIndex = 0;
+  ~BitsPacker() {
+    assert(!hasUnconsumedValues() && "There are unprocessed bits!");
   }
 
   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!");
 
-    UnderlyingValue |= Value << CurrentBitIndex;
+    if (CurrentBitIndex + BitsWidth >= BitIndexUpbound) {
+      Values.push_back(0);
+      CurrentBitIndex = 0;
+    }
+
+    assert(CurrentBitIndex < BitIndexUpbound);
+    Values.back() |= Value << CurrentBitIndex;
     CurrentBitIndex += BitsWidth;
   }
 
-  operator uint32_t() { return UnderlyingValue; }
+  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();
+  }
 
 private:
-  uint32_t UnderlyingValue = 0;
-  uint32_t CurrentBitIndex = 0;
+  SmallVector<uint64_t, 4> 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;
 };
 
 } // namespace clang

diff  --git a/clang/lib/Serialization/ASTReaderDecl.cpp b/clang/lib/Serialization/ASTReaderDecl.cpp
index 209fb043420881..7140a14aefbf9b 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 (D->hasTypeConstraint()) {
+  if (Record.readBool()) {
     ConceptReference *CR = nullptr;
     if (Record.readBool())
       CR = Record.readConceptReference();

diff  --git a/clang/lib/Serialization/ASTReaderStmt.cpp b/clang/lib/Serialization/ASTReaderStmt.cpp
index a43b1b9c0216b9..b3a6f619372b4a 100644
--- a/clang/lib/Serialization/ASTReaderStmt.cpp
+++ b/clang/lib/Serialization/ASTReaderStmt.cpp
@@ -73,8 +73,6 @@ namespace clang {
     ASTRecordReader &Record;
     llvm::BitstreamCursor &DeclsCursor;
 
-    std::optional<BitsUnpacker> CurrentUnpackingBits;
-
     SourceLocation readSourceLocation() {
       return Record.readSourceLocation();
     }
@@ -112,9 +110,6 @@ 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,
@@ -152,10 +147,9 @@ void ASTStmtReader::VisitNullStmt(NullStmt *S) {
 
 void ASTStmtReader::VisitCompoundStmt(CompoundStmt *S) {
   VisitStmt(S);
-  CurrentUnpackingBits.emplace(Record.readInt());
   SmallVector<Stmt *, 16> Stmts;
-  unsigned NumStmts = CurrentUnpackingBits->getNextBits(/*Width=*/20);
-  unsigned HasFPFeatures = CurrentUnpackingBits->getNextBit();
+  unsigned NumStmts = Record.readInt();
+  unsigned HasFPFeatures = Record.readInt();
   assert(S->hasStoredFPFeatures() == HasFPFeatures);
   while (NumStmts--)
     Stmts.push_back(Record.readSubStmt());
@@ -220,11 +214,9 @@ void ASTStmtReader::VisitAttributedStmt(AttributedStmt *S) {
 void ASTStmtReader::VisitIfStmt(IfStmt *S) {
   VisitStmt(S);
 
-  CurrentUnpackingBits.emplace(Record.readInt());
-
-  bool HasElse = CurrentUnpackingBits->getNextBit();
-  bool HasVar = CurrentUnpackingBits->getNextBit();
-  bool HasInit = CurrentUnpackingBits->getNextBit();
+  bool HasElse = Record.readInt();
+  bool HasVar = Record.readInt();
+  bool HasInit = Record.readInt();
 
   S->setStatementKind(static_cast<IfStatementKind>(Record.readInt()));
   S->setCond(Record.readSubExpr());
@@ -531,15 +523,14 @@ void ASTStmtReader::VisitCapturedStmt(CapturedStmt *S) {
 
 void ASTStmtReader::VisitExpr(Expr *E) {
   VisitStmt(E);
-  CurrentUnpackingBits.emplace(Record.readInt());
-  E->setDependence(static_cast<ExprDependence>(
-      CurrentUnpackingBits->getNextBits(/*Width=*/5)));
-  E->setValueKind(static_cast<ExprValueKind>(
-      CurrentUnpackingBits->getNextBits(/*Width=*/2)));
-  E->setObjectKind(static_cast<ExprObjectKind>(
-      CurrentUnpackingBits->getNextBits(/*Width=*/3)));
-
   E->setType(Record.readType());
+  BitsUnpacker ExprBits(Record.readInt());
+  E->setDependence(
+      static_cast<ExprDependence>(ExprBits.getNextBits(/*Width=*/5)));
+  E->setValueKind(
+      static_cast<ExprValueKind>(ExprBits.getNextBits(/*Width=*/2)));
+  E->setObjectKind(
+      static_cast<ExprObjectKind>(ExprBits.getNextBits(/*Width=*/3)));
   assert(Record.getIdx() == NumExprFields &&
          "Incorrect expression field count");
 }
@@ -600,20 +591,17 @@ void ASTStmtReader::VisitPredefinedExpr(PredefinedExpr *E) {
 void ASTStmtReader::VisitDeclRefExpr(DeclRefExpr *E) {
   VisitExpr(E);
 
-  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.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.CapturedByCopyInLambdaWithExplicitObjectParameter = false;
   unsigned NumTemplateArgs = 0;
   if (E->hasTemplateKWAndArgsInfo())
-    NumTemplateArgs = CurrentUnpackingBits->getNextBits(/*Width=*/12);
+    NumTemplateArgs = Record.readInt();
 
   if (E->hasQualifier())
     new (E->getTrailingObjects<NestedNameSpecifierLoc>())
@@ -718,13 +706,12 @@ void ASTStmtReader::VisitParenListExpr(ParenListExpr *E) {
 
 void ASTStmtReader::VisitUnaryOperator(UnaryOperator *E) {
   VisitExpr(E);
-  bool hasFP_Features = CurrentUnpackingBits->getNextBit();
+  bool hasFP_Features = Record.readInt();
   assert(hasFP_Features == E->hasStoredFPFeatures());
   E->setSubExpr(Record.readSubExpr());
-  E->setOpcode(
-      (UnaryOperator::Opcode)CurrentUnpackingBits->getNextBits(/*Width=*/5));
+  E->setOpcode((UnaryOperator::Opcode)Record.readInt());
   E->setOperatorLoc(readSourceLocation());
-  E->setCanOverflow(CurrentUnpackingBits->getNextBit());
+  E->setCanOverflow(Record.readInt());
   if (hasFP_Features)
     E->setStoredFPFeatures(
         FPOptionsOverride::getFromOpaqueInt(Record.readInt()));
@@ -1013,10 +1000,12 @@ void ASTStmtReader::VisitOMPIteratorExpr(OMPIteratorExpr *E) {
 void ASTStmtReader::VisitCallExpr(CallExpr *E) {
   VisitExpr(E);
 
-  unsigned NumArgs = CurrentUnpackingBits->getNextBits(/*Width=*/13);
-  bool HasFPFeatures = CurrentUnpackingBits->getNextBit();
+  BitsUnpacker CallExprBits = Record.readInt();
+
+  unsigned NumArgs = CallExprBits.getNextBits(/*Width=*/16);
+  bool HasFPFeatures = CallExprBits.getNextBit();
   E->setADLCallKind(
-      static_cast<CallExpr::ADLCallKind>(CurrentUnpackingBits->getNextBit()));
+      static_cast<CallExpr::ADLCallKind>(CallExprBits.getNextBit()));
   assert((NumArgs == E->getNumArgs()) && "Wrong NumArgs!");
   E->setRParenLoc(readSourceLocation());
   E->setCallee(Record.readSubExpr());
@@ -1035,28 +1024,27 @@ void ASTStmtReader::VisitCXXMemberCallExpr(CXXMemberCallExpr *E) {
 void ASTStmtReader::VisitMemberExpr(MemberExpr *E) {
   VisitExpr(E);
 
-  bool HasQualifier = CurrentUnpackingBits->getNextBit();
-  bool HasFoundDecl = CurrentUnpackingBits->getNextBit();
-  bool HasTemplateInfo = CurrentUnpackingBits->getNextBit();
-  unsigned NumTemplateArgs = CurrentUnpackingBits->getNextBits(/*Width=*/12);
+  bool HasQualifier = Record.readInt();
+  bool HasFoundDecl = Record.readInt();
+  bool HasTemplateInfo = Record.readInt();
+  unsigned NumTemplateArgs = Record.readInt();
 
   E->Base = Record.readSubExpr();
   E->MemberDecl = Record.readDeclAs<ValueDecl>();
   E->MemberDNLoc = Record.readDeclarationNameLoc(E->MemberDecl->getDeclName());
   E->MemberLoc = Record.readSourceLocation();
-  E->MemberExprBits.IsArrow = CurrentUnpackingBits->getNextBit();
+  E->MemberExprBits.IsArrow = Record.readInt();
   E->MemberExprBits.HasQualifierOrFoundDecl = HasQualifier || HasFoundDecl;
   E->MemberExprBits.HasTemplateKWAndArgsInfo = HasTemplateInfo;
-  E->MemberExprBits.HadMultipleCandidates = CurrentUnpackingBits->getNextBit();
-  E->MemberExprBits.NonOdrUseReason =
-      CurrentUnpackingBits->getNextBits(/*Width=*/2);
+  E->MemberExprBits.HadMultipleCandidates = Record.readInt();
+  E->MemberExprBits.NonOdrUseReason = Record.readInt();
   E->MemberExprBits.OperatorLoc = Record.readSourceLocation();
 
   if (HasQualifier || HasFoundDecl) {
     DeclAccessPair FoundDecl;
     if (HasFoundDecl) {
       auto *FoundD = Record.readDeclAs<NamedDecl>();
-      auto AS = (AccessSpecifier)CurrentUnpackingBits->getNextBits(/*Width=*/2);
+      auto AS = (AccessSpecifier)Record.readInt();
       FoundDecl = DeclAccessPair::make(FoundD, AS);
     } else {
       FoundDecl = DeclAccessPair::make(E->MemberDecl,
@@ -1103,10 +1091,10 @@ void ASTStmtReader::VisitCastExpr(CastExpr *E) {
   VisitExpr(E);
   unsigned NumBaseSpecs = Record.readInt();
   assert(NumBaseSpecs == E->path_size());
-  unsigned HasFPFeatures = CurrentUnpackingBits->getNextBit();
+  unsigned HasFPFeatures = Record.readInt();
   assert(E->hasStoredFPFeatures() == HasFPFeatures);
   E->setSubExpr(Record.readSubExpr());
-  E->setCastKind((CastKind)CurrentUnpackingBits->getNextBits(/*Width=*/7));
+  E->setCastKind((CastKind)Record.readInt());
   CastExpr::path_iterator BaseI = E->path_begin();
   while (NumBaseSpecs--) {
     auto *BaseSpec = new (Record.getContext()) CXXBaseSpecifier;
@@ -1119,12 +1107,10 @@ void ASTStmtReader::VisitCastExpr(CastExpr *E) {
 }
 
 void ASTStmtReader::VisitBinaryOperator(BinaryOperator *E) {
-
+  bool hasFP_Features;
   VisitExpr(E);
-  bool hasFP_Features = CurrentUnpackingBits->getNextBit();
-  E->setHasStoredFPFeatures(hasFP_Features);
-  E->setOpcode(
-      (BinaryOperator::Opcode)CurrentUnpackingBits->getNextBits(/*Width=*/6));
+  E->setHasStoredFPFeatures(hasFP_Features = Record.readInt());
+  E->setOpcode((BinaryOperator::Opcode)Record.readInt());
   E->setLHS(Record.readSubExpr());
   E->setRHS(Record.readSubExpr());
   E->setOperatorLoc(readSourceLocation());
@@ -1162,7 +1148,7 @@ ASTStmtReader::VisitBinaryConditionalOperator(BinaryConditionalOperator *E) {
 
 void ASTStmtReader::VisitImplicitCastExpr(ImplicitCastExpr *E) {
   VisitCastExpr(E);
-  E->setIsPartOfExplicitCast(CurrentUnpackingBits->getNextBit());
+  E->setIsPartOfExplicitCast(Record.readInt());
 }
 
 void ASTStmtReader::VisitExplicitCastExpr(ExplicitCastExpr *E) {
@@ -1700,8 +1686,7 @@ void ASTStmtReader::VisitMSDependentExistsStmt(MSDependentExistsStmt *S) {
 
 void ASTStmtReader::VisitCXXOperatorCallExpr(CXXOperatorCallExpr *E) {
   VisitCallExpr(E);
-  E->CXXOperatorCallExprBits.OperatorKind =
-      CurrentUnpackingBits->getNextBits(/*Width=*/6);
+  E->CXXOperatorCallExprBits.OperatorKind = Record.readInt();
   E->Range = Record.readSourceRange();
 }
 
@@ -1779,8 +1764,8 @@ void ASTStmtReader::VisitCXXNamedCastExpr(CXXNamedCastExpr *E) {
   SourceRange R = readSourceRange();
   E->Loc = R.getBegin();
   E->RParenLoc = R.getEnd();
-  if (CurrentUnpackingBits->getNextBit())
-    E->AngleBrackets = readSourceRange();
+  R = readSourceRange();
+  E->AngleBrackets = R;
 }
 
 void ASTStmtReader::VisitCXXStaticCastExpr(CXXStaticCastExpr *E) {
@@ -1976,9 +1961,9 @@ void ASTStmtReader::VisitCXXDependentScopeMemberExpr(
     CXXDependentScopeMemberExpr *E) {
   VisitExpr(E);
 
-  bool HasTemplateKWAndArgsInfo = CurrentUnpackingBits->getNextBit();
-  unsigned NumTemplateArgs = CurrentUnpackingBits->getNextBits(/*Width=*/16);
-  bool HasFirstQualifierFoundInScope = CurrentUnpackingBits->getNextBit();
+  bool HasTemplateKWAndArgsInfo = Record.readInt();
+  unsigned NumTemplateArgs = Record.readInt();
+  bool HasFirstQualifierFoundInScope = Record.readInt();
 
   assert((HasTemplateKWAndArgsInfo == E->hasTemplateKWAndArgsInfo()) &&
          "Wrong HasTemplateKWAndArgsInfo!");
@@ -1994,17 +1979,11 @@ void ASTStmtReader::VisitCXXDependentScopeMemberExpr(
   assert((NumTemplateArgs == E->getNumTemplateArgs()) &&
          "Wrong NumTemplateArgs!");
 
-  E->CXXDependentScopeMemberExprBits.IsArrow =
-      CurrentUnpackingBits->getNextBit();
-
+  E->CXXDependentScopeMemberExprBits.IsArrow = Record.readInt();
+  E->CXXDependentScopeMemberExprBits.OperatorLoc = readSourceLocation();
   E->BaseType = Record.readType();
   E->QualifierLoc = Record.readNestedNameSpecifierLoc();
-  // not ImplicitAccess
-  if (CurrentUnpackingBits->getNextBit()) {
-    E->Base = Record.readSubExpr();
-    E->CXXDependentScopeMemberExprBits.OperatorLoc = readSourceLocation();
-  } else
-    E->Base = nullptr;
+  E->Base = Record.readSubExpr();
 
   if (HasFirstQualifierFoundInScope)
     *E->getTrailingObjects<NamedDecl *>() = readDeclAs<NamedDecl>();
@@ -2016,11 +1995,11 @@ void
 ASTStmtReader::VisitDependentScopeDeclRefExpr(DependentScopeDeclRefExpr *E) {
   VisitExpr(E);
 
-  if (CurrentUnpackingBits->getNextBit()) // HasTemplateKWAndArgsInfo
+  if (Record.readInt()) // HasTemplateKWAndArgsInfo
     ReadTemplateKWAndArgsInfo(
         *E->getTrailingObjects<ASTTemplateKWAndArgsInfo>(),
         E->getTrailingObjects<TemplateArgumentLoc>(),
-        /*NumTemplateArgs=*/CurrentUnpackingBits->getNextBits(/*Width=*/16));
+        /*NumTemplateArgs=*/Record.readInt());
 
   E->QualifierLoc = Record.readNestedNameSpecifierLoc();
   E->NameInfo = Record.readDeclarationNameInfo();
@@ -2043,15 +2022,15 @@ ASTStmtReader::VisitCXXUnresolvedConstructExpr(CXXUnresolvedConstructExpr *E) {
 void ASTStmtReader::VisitOverloadExpr(OverloadExpr *E) {
   VisitExpr(E);
 
-  CurrentUnpackingBits.emplace(Record.readInt());
-  unsigned NumResults = CurrentUnpackingBits->getNextBits(/*Width=*/12);
-  bool HasTemplateKWAndArgsInfo = CurrentUnpackingBits->getNextBit();
+  BitsUnpacker OverloadExprBits = Record.readInt();
+  unsigned NumResults = OverloadExprBits.getNextBits(/*Width=*/14);
+  bool HasTemplateKWAndArgsInfo = OverloadExprBits.getNextBit();
   assert((E->getNumDecls() == NumResults) && "Wrong NumResults!");
   assert((E->hasTemplateKWAndArgsInfo() == HasTemplateKWAndArgsInfo) &&
          "Wrong HasTemplateKWAndArgsInfo!");
 
   if (HasTemplateKWAndArgsInfo) {
-    unsigned NumTemplateArgs = CurrentUnpackingBits->getNextBits(/*Width=*/12);
+    unsigned NumTemplateArgs = OverloadExprBits.getNextBits(/*Width=*/14);
     ReadTemplateKWAndArgsInfo(*E->getTrailingASTTemplateKWAndArgsInfo(),
                               E->getTrailingTemplateArgumentLoc(),
                               NumTemplateArgs);
@@ -2078,25 +2057,17 @@ void ASTStmtReader::VisitOverloadExpr(OverloadExpr *E) {
 
 void ASTStmtReader::VisitUnresolvedMemberExpr(UnresolvedMemberExpr *E) {
   VisitOverloadExpr(E);
-  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->UnresolvedMemberExprBits.IsArrow = Record.readInt();
+  E->UnresolvedMemberExprBits.HasUnresolvedUsing = Record.readInt();
+  E->Base = Record.readSubExpr();
   E->BaseType = Record.readType();
+  E->OperatorLoc = readSourceLocation();
 }
 
 void ASTStmtReader::VisitUnresolvedLookupExpr(UnresolvedLookupExpr *E) {
   VisitOverloadExpr(E);
-  E->UnresolvedLookupExprBits.RequiresADL = CurrentUnpackingBits->getNextBit();
-  E->UnresolvedLookupExprBits.Overloaded = CurrentUnpackingBits->getNextBit();
+  E->UnresolvedLookupExprBits.RequiresADL = Record.readInt();
+  E->UnresolvedLookupExprBits.Overloaded = Record.readInt();
   E->NamingClass = readDeclAs<CXXRecordDecl>();
 }
 
@@ -2171,12 +2142,9 @@ void ASTStmtReader::VisitSubstNonTypeTemplateParmExpr(
                                               SubstNonTypeTemplateParmExpr *E) {
   VisitExpr(E);
   E->AssociatedDeclAndRef.setPointer(readDeclAs<Decl>());
-  E->AssociatedDeclAndRef.setInt(CurrentUnpackingBits->getNextBit());
-  E->Index = CurrentUnpackingBits->getNextBits(/*Width=*/12);
-  if (CurrentUnpackingBits->getNextBit())
-    E->PackIndex = Record.readInt();
-  else
-    E->PackIndex = 0;
+  E->AssociatedDeclAndRef.setInt(Record.readInt());
+  E->Index = Record.readInt();
+  E->PackIndex = Record.readInt();
   E->SubstNonTypeTemplateParmExprBits.NameLoc = readSourceLocation();
   E->Replacement = Record.readSubExpr();
 }
@@ -2868,13 +2836,11 @@ Stmt *ASTReader::ReadStmtFromStream(ModuleFile &F) {
       S = new (Context) NullStmt(Empty);
       break;
 
-    case STMT_COMPOUND: {
-      BitsUnpacker StmtCompoundBits(Record[ASTStmtReader::NumStmtFields]);
-      unsigned NumStmts = StmtCompoundBits.getNextBits(/*Width=*/20);
-      bool HasFPFeatures = StmtCompoundBits.getNextBit();
-      S = CompoundStmt::CreateEmpty(Context, NumStmts, HasFPFeatures);
+    case STMT_COMPOUND:
+      S = CompoundStmt::CreateEmpty(
+          Context, /*NumStmts=*/Record[ASTStmtReader::NumStmtFields],
+          /*HasFPFeatures=*/Record[ASTStmtReader::NumStmtFields + 1]);
       break;
-    }
 
     case STMT_CASE:
       S = CaseStmt::CreateEmpty(
@@ -2896,14 +2862,13 @@ Stmt *ASTReader::ReadStmtFromStream(ModuleFile &F) {
         /*NumAttrs*/Record[ASTStmtReader::NumStmtFields]);
       break;
 
-    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);
+    case STMT_IF:
+      S = IfStmt::CreateEmpty(
+          Context,
+          /* HasElse=*/Record[ASTStmtReader::NumStmtFields],
+          /* HasVar=*/Record[ASTStmtReader::NumStmtFields + 1],
+          /* HasInit=*/Record[ASTStmtReader::NumStmtFields + 2]);
       break;
-    }
 
     case STMT_SWITCH:
       S = SwitchStmt::CreateEmpty(
@@ -2980,20 +2945,17 @@ Stmt *ASTReader::ReadStmtFromStream(ModuleFile &F) {
           /*HasFunctionName*/ Record[ASTStmtReader::NumExprFields]);
       break;
 
-    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);
+    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);
       break;
-    }
 
     case EXPR_INTEGER_LITERAL:
       S = IntegerLiteral::Create(Context, Empty);
@@ -3033,13 +2995,10 @@ Stmt *ASTReader::ReadStmtFromStream(ModuleFile &F) {
           /* NumExprs=*/Record[ASTStmtReader::NumExprFields]);
       break;
 
-    case EXPR_UNARY_OPERATOR: {
-      BitsUnpacker UnaryOperatorBits(Record[ASTStmtReader::NumStmtFields]);
-      UnaryOperatorBits.advance(ASTStmtReader::NumExprBits);
-      bool HasFPFeatures = UnaryOperatorBits.getNextBit();
-      S = UnaryOperator::CreateEmpty(Context, HasFPFeatures);
+    case EXPR_UNARY_OPERATOR:
+      S = UnaryOperator::CreateEmpty(Context,
+                                     Record[ASTStmtReader::NumExprFields]);
       break;
-    }
 
     case EXPR_OFFSETOF:
       S = OffsetOfExpr::CreateEmpty(Context,
@@ -3074,9 +3033,8 @@ Stmt *ASTReader::ReadStmtFromStream(ModuleFile &F) {
       break;
 
     case EXPR_CALL: {
-      BitsUnpacker CallExprBits(Record[ASTStmtReader::NumStmtFields]);
-      CallExprBits.advance(ASTStmtReader::NumExprBits);
-      auto NumArgs = CallExprBits.getNextBits(/*Width=*/13);
+      BitsUnpacker CallExprBits(Record[ASTStmtReader::NumExprFields]);
+      auto NumArgs = CallExprBits.getNextBits(/*Width=*/16);
       auto HasFPFeatures = CallExprBits.getNextBit();
       S = CallExpr::CreateEmpty(Context, NumArgs, HasFPFeatures, Empty);
       break;
@@ -3087,33 +3045,22 @@ Stmt *ASTReader::ReadStmtFromStream(ModuleFile &F) {
           Context, /*NumArgs=*/Record[ASTStmtReader::NumExprFields]);
       break;
 
-    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);
+    case EXPR_MEMBER:
+      S = MemberExpr::CreateEmpty(Context, Record[ASTStmtReader::NumExprFields],
+                                  Record[ASTStmtReader::NumExprFields + 1],
+                                  Record[ASTStmtReader::NumExprFields + 2],
+                                  Record[ASTStmtReader::NumExprFields + 3]);
       break;
-    }
 
-    case EXPR_BINARY_OPERATOR: {
-      BitsUnpacker BinaryOperatorBits(Record[ASTStmtReader::NumStmtFields]);
-      BinaryOperatorBits.advance(ASTStmtReader::NumExprBits);
-      bool HasFPFeatures = BinaryOperatorBits.getNextBit();
-      S = BinaryOperator::CreateEmpty(Context, HasFPFeatures);
+    case EXPR_BINARY_OPERATOR:
+      S = BinaryOperator::CreateEmpty(Context,
+                                      Record[ASTStmtReader::NumExprFields]);
       break;
-    }
 
-    case EXPR_COMPOUND_ASSIGN_OPERATOR: {
-      BitsUnpacker BinaryOperatorBits(Record[ASTStmtReader::NumStmtFields]);
-      BinaryOperatorBits.advance(ASTStmtReader::NumExprBits);
-      bool HasFPFeatures = BinaryOperatorBits.getNextBit();
-      S = CompoundAssignOperator::CreateEmpty(Context, HasFPFeatures);
+    case EXPR_COMPOUND_ASSIGN_OPERATOR:
+      S = CompoundAssignOperator::CreateEmpty(
+          Context, Record[ASTStmtReader::NumExprFields]);
       break;
-    }
 
     case EXPR_CONDITIONAL_OPERATOR:
       S = new (Context) ConditionalOperator(Empty);
@@ -3123,23 +3070,19 @@ Stmt *ASTReader::ReadStmtFromStream(ModuleFile &F) {
       S = new (Context) BinaryConditionalOperator(Empty);
       break;
 
-    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);
+    case EXPR_IMPLICIT_CAST:
+      S = ImplicitCastExpr::CreateEmpty(
+          Context,
+          /*PathSize*/ Record[ASTStmtReader::NumExprFields],
+          /*HasFPFeatures*/ Record[ASTStmtReader::NumExprFields + 1]);
       break;
-    }
 
-    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);
+    case EXPR_CSTYLE_CAST:
+      S = CStyleCastExpr::CreateEmpty(
+          Context,
+          /*PathSize*/ Record[ASTStmtReader::NumExprFields],
+          /*HasFPFeatures*/ Record[ASTStmtReader::NumExprFields + 1]);
       break;
-    }
 
     case EXPR_COMPOUND_LITERAL:
       S = new (Context) CompoundLiteralExpr(Empty);
@@ -3834,9 +3777,8 @@ Stmt *ASTReader::ReadStmtFromStream(ModuleFile &F) {
     }
 
     case EXPR_CXX_OPERATOR_CALL: {
-      BitsUnpacker CallExprBits(Record[ASTStmtReader::NumStmtFields]);
-      CallExprBits.advance(ASTStmtReader::NumExprBits);
-      auto NumArgs = CallExprBits.getNextBits(/*Width=*/13);
+      BitsUnpacker CallExprBits(Record[ASTStmtReader::NumExprFields]);
+      auto NumArgs = CallExprBits.getNextBits(/*Width=*/16);
       auto HasFPFeatures = CallExprBits.getNextBit();
       S = CXXOperatorCallExpr::CreateEmpty(Context, NumArgs, HasFPFeatures,
                                            Empty);
@@ -3844,9 +3786,8 @@ Stmt *ASTReader::ReadStmtFromStream(ModuleFile &F) {
     }
 
     case EXPR_CXX_MEMBER_CALL: {
-      BitsUnpacker CallExprBits(Record[ASTStmtReader::NumStmtFields]);
-      CallExprBits.advance(ASTStmtReader::NumExprBits);
-      auto NumArgs = CallExprBits.getNextBits(/*Width=*/13);
+      BitsUnpacker CallExprBits(Record[ASTStmtReader::NumExprFields]);
+      auto NumArgs = CallExprBits.getNextBits(/*Width=*/16);
       auto HasFPFeatures = CallExprBits.getNextBit();
       S = CXXMemberCallExpr::CreateEmpty(Context, NumArgs, HasFPFeatures,
                                          Empty);
@@ -3873,26 +3814,22 @@ Stmt *ASTReader::ReadStmtFromStream(ModuleFile &F) {
           /* NumArgs=*/Record[ASTStmtReader::NumExprFields]);
       break;
 
-    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);
+    case EXPR_CXX_STATIC_CAST:
+      S = CXXStaticCastExpr::CreateEmpty(
+          Context,
+          /*PathSize*/ Record[ASTStmtReader::NumExprFields],
+          /*HasFPFeatures*/ Record[ASTStmtReader::NumExprFields + 1]);
       break;
-    }
 
-    case EXPR_CXX_DYNAMIC_CAST: {
-      unsigned PathSize = Record[ASTStmtReader::NumExprFields];
-      S = CXXDynamicCastExpr::CreateEmpty(Context, PathSize);
+    case EXPR_CXX_DYNAMIC_CAST:
+      S = CXXDynamicCastExpr::CreateEmpty(Context,
+                       /*PathSize*/ Record[ASTStmtReader::NumExprFields]);
       break;
-    }
 
-    case EXPR_CXX_REINTERPRET_CAST: {
-      unsigned PathSize = Record[ASTStmtReader::NumExprFields];
-      S = CXXReinterpretCastExpr::CreateEmpty(Context, PathSize);
+    case EXPR_CXX_REINTERPRET_CAST:
+      S = CXXReinterpretCastExpr::CreateEmpty(Context,
+                       /*PathSize*/ Record[ASTStmtReader::NumExprFields]);
       break;
-    }
 
     case EXPR_CXX_CONST_CAST:
       S = CXXConstCastExpr::CreateEmpty(Context);
@@ -3902,28 +3839,21 @@ Stmt *ASTReader::ReadStmtFromStream(ModuleFile &F) {
       S = CXXAddrspaceCastExpr::CreateEmpty(Context);
       break;
 
-    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);
+    case EXPR_CXX_FUNCTIONAL_CAST:
+      S = CXXFunctionalCastExpr::CreateEmpty(
+          Context,
+          /*PathSize*/ Record[ASTStmtReader::NumExprFields],
+          /*HasFPFeatures*/ Record[ASTStmtReader::NumExprFields + 1]);
       break;
-    }
 
-    case EXPR_BUILTIN_BIT_CAST: {
-#ifndef NDEBUG
-      unsigned PathSize = Record[ASTStmtReader::NumExprFields];
-      assert(PathSize == 0 && "Wrong PathSize!");
-#endif
+    case EXPR_BUILTIN_BIT_CAST:
+      assert(Record[ASTStmtReader::NumExprFields] == 0 && "Wrong PathSize!");
       S = new (Context) BuiltinBitCastExpr(Empty);
       break;
-    }
 
     case EXPR_USER_DEFINED_LITERAL: {
-      BitsUnpacker CallExprBits(Record[ASTStmtReader::NumStmtFields]);
-      CallExprBits.advance(ASTStmtReader::NumExprBits);
-      auto NumArgs = CallExprBits.getNextBits(/*Width=*/13);
+      BitsUnpacker CallExprBits(Record[ASTStmtReader::NumExprFields]);
+      auto NumArgs = CallExprBits.getNextBits(/*Width=*/16);
       auto HasFPFeatures = CallExprBits.getNextBit();
       S = UserDefinedLiteral::CreateEmpty(Context, NumArgs, HasFPFeatures,
                                           Empty);
@@ -4014,63 +3944,47 @@ Stmt *ASTReader::ReadStmtFromStream(ModuleFile &F) {
                                    Record[ASTStmtReader::NumExprFields]);
       break;
 
-    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();
+    case EXPR_CXX_DEPENDENT_SCOPE_MEMBER:
       S = CXXDependentScopeMemberExpr::CreateEmpty(
-          Context, HasTemplateKWAndArgsInfo, NumTemplateArgs,
-          HasFirstQualifierFoundInScope);
+          Context,
+          /*HasTemplateKWAndArgsInfo=*/Record[ASTStmtReader::NumExprFields],
+          /*NumTemplateArgs=*/Record[ASTStmtReader::NumExprFields + 1],
+          /*HasFirstQualifierFoundInScope=*/
+          Record[ASTStmtReader::NumExprFields + 2]);
       break;
-    }
 
-    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);
+    case EXPR_CXX_DEPENDENT_SCOPE_DECL_REF:
+      S = DependentScopeDeclRefExpr::CreateEmpty(Context,
+         /*HasTemplateKWAndArgsInfo=*/Record[ASTStmtReader::NumExprFields],
+                  /*NumTemplateArgs=*/Record[ASTStmtReader::NumExprFields]
+                                   ? Record[ASTStmtReader::NumExprFields + 1]
+                                   : 0);
       break;
-    }
 
     case EXPR_CXX_UNRESOLVED_CONSTRUCT:
       S = CXXUnresolvedConstructExpr::CreateEmpty(Context,
                               /*NumArgs=*/Record[ASTStmtReader::NumExprFields]);
       break;
 
-    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;
+    case EXPR_CXX_UNRESOLVED_MEMBER:
       S = UnresolvedMemberExpr::CreateEmpty(
-          Context, NumResults, HasTemplateKWAndArgsInfo, NumTemplateArgs);
+          Context,
+          /*NumResults=*/Record[ASTStmtReader::NumExprFields] & ((1 << 14) - 1),
+          /*HasTemplateKWAndArgsInfo=*/
+          (Record[ASTStmtReader::NumExprFields] >> 14) & (0x1),
+          /*NumTemplateArgs=*/Record[ASTStmtReader::NumExprFields] >> 14 &
+              ((1 << 14) - 1));
       break;
-    }
 
-    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;
+    case EXPR_CXX_UNRESOLVED_LOOKUP:
       S = UnresolvedLookupExpr::CreateEmpty(
-          Context, NumResults, HasTemplateKWAndArgsInfo, NumTemplateArgs);
+          Context,
+          /*NumResults=*/Record[ASTStmtReader::NumExprFields] & ((1 << 14) - 1),
+          /*HasTemplateKWAndArgsInfo=*/
+          (Record[ASTStmtReader::NumExprFields] >> 14) & (0x1),
+          /*NumTemplateArgs=*/Record[ASTStmtReader::NumExprFields] >> 14 &
+              ((1 << 14) - 1));
       break;
-    }
 
     case EXPR_TYPE_TRAIT:
       S = TypeTraitExpr::CreateDeserialized(Context,
@@ -4130,9 +4044,8 @@ Stmt *ASTReader::ReadStmtFromStream(ModuleFile &F) {
       break;
 
     case EXPR_CUDA_KERNEL_CALL: {
-      BitsUnpacker CallExprBits(Record[ASTStmtReader::NumStmtFields]);
-      CallExprBits.advance(ASTStmtReader::NumExprBits);
-      auto NumArgs = CallExprBits.getNextBits(/*Width=*/13);
+      BitsUnpacker CallExprBits(Record[ASTStmtReader::NumExprFields]);
+      auto NumArgs = CallExprBits.getNextBits(/*Width=*/16);
       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 78939bfd533ffa..91eb2af8f8ad6a 100644
--- a/clang/lib/Serialization/ASTWriter.cpp
+++ b/clang/lib/Serialization/ASTWriter.cpp
@@ -6003,17 +6003,12 @@ void ASTRecordWriter::AddCXXDefinitionData(const CXXRecordDecl *D) {
 
   BitsPacker DefinitionBits;
 
-#define FIELD(Name, Width, Merge)                                              \
-  if (!DefinitionBits.canWriteNextNBits(Width)) {                              \
-    Record->push_back(DefinitionBits);                                         \
-    DefinitionBits.reset(0);                                                   \
-  }                                                                            \
-  DefinitionBits.addBits(Data.Name, Width);
-
+#define FIELD(Name, Width, Merge) DefinitionBits.addBits(Data.Name, Width);
 #include "clang/AST/CXXRecordDeclDefinitionBits.def"
 #undef FIELD
 
-  Record->push_back(DefinitionBits);
+  while (DefinitionBits.hasUnconsumedValues())
+    Record->push_back(DefinitionBits.getNextValue());
 
   // getODRHash will compute the ODRHash if it has not been previously computed.
   Record->push_back(D->getODRHash());
@@ -6052,7 +6047,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);
+    Record->push_back(LambdaBits.getNextValue());
 
     Record->push_back(Lambda.NumExplicitCaptures);
     Record->push_back(Lambda.ManglingNumber);
@@ -6063,12 +6058,10 @@ 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 cc32b3ffa2627a..43169b2befc687 100644
--- a/clang/lib/Serialization/ASTWriterDecl.cpp
+++ b/clang/lib/Serialization/ASTWriterDecl.cpp
@@ -496,10 +496,15 @@ 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() &&
@@ -539,10 +544,16 @@ 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)
@@ -1126,7 +1137,13 @@ 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() &&
@@ -1176,9 +1193,14 @@ 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->getStorageClass() == 0 &&
+      !D->hasExtInfo() && !D->isImplicit() && !D->isUsed(false) &&
+      !D->isInvalidDecl() && !D->isReferenced() && D->getAccess() == AS_none &&
+      !D->isModulePrivate() && D->getStorageClass() == 0 &&
       D->getInitStyle() == VarDecl::CInit && // Can params have anything else?
-      D->getInit() == nullptr)               // No default expr.
+      D->getFunctionScopeDepth() == 0 && D->getObjCDeclQualifier() == 0 &&
+      !D->isKNRPromoted() && !D->isExplicitObjectParameter() &&
+      !D->hasInheritedDefaultArg() && D->getInit() == nullptr &&
+      !D->hasUninstantiatedDefaultArg()) // No default expr.
     AbbrevToUse = Writer.getDeclParmVarAbbrev();
 
   // Check things we know are true of *every* PARM_VAR_DECL, which is more than
@@ -1381,13 +1403,6 @@ 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;
 }
 
@@ -1492,32 +1507,10 @@ void ASTDeclWriter::VisitCXXMethodDecl(CXXMethodDecl *D) {
       D->getFirstDecl() == D->getMostRecentDecl() && !D->isInvalidDecl() &&
       !D->hasAttrs() && !D->isTopLevelDeclInObjCContainer() &&
       D->getDeclName().getNameKind() == DeclarationName::Identifier &&
-      !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());
-    }
-  }
+      !D->hasExtInfo() && !D->hasInheritedPrototype() &&
+      D->hasWrittenPrototype() &&
+      D->getTemplatedKind() == FunctionDecl::TK_NonTemplate)
+    AbbrevToUse = Writer.getDeclCXXMethodAbbrev();
 
   Code = serialization::DECL_CXX_METHOD;
 }
@@ -1789,7 +1782,7 @@ void ASTDeclWriter::VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D) {
   Record.push_back(D->wasDeclaredWithTypename());
 
   const TypeConstraint *TC = D->getTypeConstraint();
-  assert((bool)TC == D->hasTypeConstraint());
+  Record.push_back(TC != nullptr);
   if (TC) {
     auto *CR = TC->getConceptReference();
     Record.push_back(CR != nullptr);
@@ -1807,13 +1800,6 @@ 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;
 }
 
@@ -2045,104 +2031,6 @@ void ASTDeclWriter::VisitOMPCapturedExprDecl(OMPCapturedExprDecl *D) {
 // ASTWriter Implementation
 //===----------------------------------------------------------------------===//
 
-namespace {
-template <FunctionDecl::TemplatedKind Kind>
-std::shared_ptr<llvm::BitCodeAbbrev>
-getFunctionDeclAbbrev(serialization::DeclCode Code) {
-  using namespace llvm;
-
-  auto Abv = std::make_shared<BitCodeAbbrev>();
-  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 Abv;
-}
-
-template <FunctionDecl::TemplatedKind Kind>
-std::shared_ptr<llvm::BitCodeAbbrev> getCXXMethodAbbrev() {
-  using namespace llvm;
-  auto Abv = getFunctionDeclAbbrev<Kind>(serialization::DECL_CXX_METHOD);
-  Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6));
-  return std::move(Abv);
-}
-} // namespace
-
 void ASTWriter::WriteDeclAbbrevs() {
   using namespace llvm;
 
@@ -2402,81 +2290,71 @@ void ASTWriter::WriteDeclAbbrevs() {
   DeclVarAbbrev = Stream.EmitAbbrev(std::move(Abv));
 
   // Abbreviation for DECL_CXX_METHOD
-  DeclCXXMethodAbbrev =
-      Stream.EmitAbbrev(getCXXMethodAbbrev<FunctionDecl::TK_NonTemplate>());
-  DeclTemplateCXXMethodAbbrev = Stream.EmitAbbrev(
-      getCXXMethodAbbrev<FunctionDecl::TK_FunctionTemplate>());
-  DeclDependentNonTemplateCXXMethodAbbrev = Stream.EmitAbbrev(
-      getCXXMethodAbbrev<FunctionDecl::TK_DependentNonTemplate>());
-  DeclMemberSpecializedCXXMethodAbbrev = Stream.EmitAbbrev(
-      getCXXMethodAbbrev<FunctionDecl::TK_MemberSpecialization>());
-  DeclTemplateSpecializedCXXMethodAbbrev = Stream.EmitAbbrev(
-      getCXXMethodAbbrev<FunctionDecl::TK_FunctionTemplateSpecialization>());
-  DeclDependentSpecializationCXXMethodAbbrev = Stream.EmitAbbrev(
-      getCXXMethodAbbrev<
-          FunctionDecl::TK_DependentFunctionTemplateSpecialization>());
-
-  // Abbreviation for DECL_TEMPLATE_TYPE_PARM
-  Abv = std::make_shared<BitCodeAbbrev>();
-  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
-  // NamedDecl
-  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<BitCodeAbbrev>();
-  Abv->Add(BitCodeAbbrevOp(serialization::DECL_USING_SHADOW));
-  // Redeclarable
-  Abv->Add(BitCodeAbbrevOp(0)); // No redeclaration
+  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
   // 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(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(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::VBR, 6));    // UsingOrNextShadow
-  Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR,
-                           6)); // InstantiatedFromUsingShadowDecl
-  DeclUsingShadowAbbrev = Stream.EmitAbbrev(std::move(Abv));
+  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));
 
   // Abbreviation for EXPR_DECL_REF
   Abv = std::make_shared<BitCodeAbbrev>();
   Abv->Add(BitCodeAbbrevOp(serialization::EXPR_DECL_REF));
-  // Stmt
-  //  Expr
-  //  PackingBits: DependenceKind, ValueKind, ObjectKind, HasQualifier,
-  //  GetDeclFound, ExplicitTemplateArgs, HadMultipleCandidates,
-  //  NonOdrUseReason, RefersToEnclosingVariableOrCapture, IsImmediateEscalating
-  Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 18));
+  //Stmt
+  // Expr
   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Type
-  // DeclRefExpr
+  // 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
   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // DeclRef
   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Location
   DeclRefExprAbbrev = Stream.EmitAbbrev(std::move(Abv));
@@ -2486,10 +2364,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));
-  Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Type
-  // Integer Literal
+  //Integer Literal
   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Location
   Abv->Add(BitCodeAbbrevOp(32));                      // Bit Width
   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Value
@@ -2500,10 +2378,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));
-  Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Type
-  // Character Literal
+  //Character Literal
   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // getValue
   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Location
   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 3)); // getKind
@@ -2514,98 +2392,17 @@ 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<BitCodeAbbrev>();
-  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<BitCodeAbbrev>();
-  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<BitCodeAbbrev>();
-  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<BitCodeAbbrev>();
-  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<BitCodeAbbrev>();
-  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<BitCodeAbbrev>();
-  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<BitCodeAbbrev>();
   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 10139f1dc96aef..8524484ea8a0b9 100644
--- a/clang/lib/Serialization/ASTWriterStmt.cpp
+++ b/clang/lib/Serialization/ASTWriterStmt.cpp
@@ -37,70 +37,15 @@ 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),
-          CurrentPackingBits(this->Record) {}
+          Code(serialization::STMT_NULL_PTR), AbbrevToUse(0) {}
 
     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);
@@ -137,22 +82,14 @@ void ASTStmtWriter::VisitNullStmt(NullStmt *S) {
 
 void ASTStmtWriter::VisitCompoundStmt(CompoundStmt *S) {
   VisitStmt(S);
-
-  CurrentPackingBits.updateBits();
-  // 20 bits should be enough to store the size of stmts.
-  CurrentPackingBits.addBits(S->size(), /*Width=*/20);
-  CurrentPackingBits.addBit(S->hasStoredFPFeatures());
-
+  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;
 }
 
@@ -206,11 +143,9 @@ void ASTStmtWriter::VisitIfStmt(IfStmt *S) {
   bool HasVar = S->getConditionVariableDeclStmt() != nullptr;
   bool HasInit = S->getInit() != nullptr;
 
-  CurrentPackingBits.updateBits();
-
-  CurrentPackingBits.addBit(HasElse);
-  CurrentPackingBits.addBit(HasVar);
-  CurrentPackingBits.addBit(HasInit);
+  Record.push_back(HasElse);
+  Record.push_back(HasVar);
+  Record.push_back(HasInit);
   Record.push_back(static_cast<uint64_t>(S->getStatementKind()));
   Record.AddStmt(S->getCond());
   Record.AddStmt(S->getThen());
@@ -613,13 +548,15 @@ void ASTStmtWriter::VisitCapturedStmt(CapturedStmt *S) {
 
 void ASTStmtWriter::VisitExpr(Expr *E) {
   VisitStmt(E);
+  Record.AddTypeRef(E->getType());
 
-  CurrentPackingBits.updateBits();
-  CurrentPackingBits.addBits(E->getDependence(), /*BitsWidth=*/5);
-  CurrentPackingBits.addBits(E->getValueKind(), /*BitsWidth=*/2);
-  CurrentPackingBits.addBits(E->getObjectKind(), /*BitsWidth=*/3);
+  BitsPacker ExprBits;
 
-  Record.AddTypeRef(E->getType());
+  ExprBits.addBits(E->getDependence(), /*BitsWidth=*/5);
+  ExprBits.addBits(E->getValueKind(), /*BitsWidth=*/2);
+  ExprBits.addBits(E->getObjectKind(), /*BitsWidth=*/3);
+
+  Record.push_back(ExprBits);
 }
 
 void ASTStmtWriter::VisitConstantExpr(ConstantExpr *E) {
@@ -675,25 +612,26 @@ void ASTStmtWriter::VisitPredefinedExpr(PredefinedExpr *E) {
 void ASTStmtWriter::VisitDeclRefExpr(DeclRefExpr *E) {
   VisitExpr(E);
 
-  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());
+  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());
 
   if (E->hasTemplateKWAndArgsInfo()) {
     unsigned NumTemplateArgs = E->getNumTemplateArgs();
-    // 12 bits should be sufficient to store the number of template args.
-    CurrentPackingBits.addBits(NumTemplateArgs, /*Width=*/12);
+    Record.push_back(NumTemplateArgs);
   }
 
   DeclarationName::NameKind nk = (E->getDecl()->getDeclName().getNameKind());
 
   if ((!E->hasTemplateKWAndArgsInfo()) && (!E->hasQualifier()) &&
       (E->getDecl() == E->getFoundDecl()) &&
-      nk == DeclarationName::Identifier) {
+      nk == DeclarationName::Identifier &&
+      !E->refersToEnclosingVariableOrCapture() && !E->isNonOdrUse() &&
+      !E->isImmediateEscalating()) {
     AbbrevToUse = Writer.getDeclRefExprAbbrev();
   }
 
@@ -804,13 +742,11 @@ 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.
-  CurrentPackingBits.addBit(HasFPFeatures);
+  Record.push_back(HasFPFeatures);
   Record.AddStmt(E->getSubExpr());
-  CurrentPackingBits.addBits(E->getOpcode(),
-                             /*Width=*/5); // FIXME: stable encoding
+  Record.push_back(E->getOpcode()); // FIXME: stable encoding
   Record.AddSourceLocation(E->getOperatorLoc());
-  CurrentPackingBits.addBit(E->canOverflow());
-
+  Record.push_back(E->canOverflow());
   if (HasFPFeatures)
     Record.push_back(E->getStoredFPFeatures().getAsOpaqueInt());
   Code = serialization::EXPR_UNARY_OPERATOR;
@@ -936,10 +872,12 @@ void ASTStmtWriter::VisitOMPIteratorExpr(OMPIteratorExpr *E) {
 void ASTStmtWriter::VisitCallExpr(CallExpr *E) {
   VisitExpr(E);
 
-  // 13 bits should be sufficient to store the number args;
-  CurrentPackingBits.addBits(E->getNumArgs(), /*BitsWidth=*/13);
-  CurrentPackingBits.addBit(E->hasStoredFPFeatures());
-  CurrentPackingBits.addBit(static_cast<bool>(E->getADLCallKind()));
+  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.AddSourceLocation(E->getRParenLoc());
   Record.AddStmt(E->getCallee());
@@ -949,10 +887,6 @@ 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;
 }
 
@@ -979,27 +913,25 @@ void ASTStmtWriter::VisitMemberExpr(MemberExpr *E) {
 
   // Write these first for easy access when deserializing, as they affect the
   // size of the MemberExpr.
-
-  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.push_back(HasQualifier);
+  Record.push_back(HasFoundDecl);
+  Record.push_back(HasTemplateInfo);
+  Record.push_back(NumTemplateArgs);
 
   Record.AddStmt(E->getBase());
   Record.AddDeclRef(E->getMemberDecl());
   Record.AddDeclarationNameLoc(E->MemberDNLoc,
                                E->getMemberDecl()->getDeclName());
   Record.AddSourceLocation(E->getMemberLoc());
-  CurrentPackingBits.addBit(E->isArrow());
-  CurrentPackingBits.addBit(E->hadMultipleCandidates());
-  CurrentPackingBits.addBits(E->isNonOdrUse(), /*Width=*/2);
+  Record.push_back(E->isArrow());
+  Record.push_back(E->hadMultipleCandidates());
+  Record.push_back(E->isNonOdrUse());
   Record.AddSourceLocation(E->getOperatorLoc());
 
   if (HasFoundDecl) {
     DeclAccessPair FoundDecl = E->getFoundDecl();
     Record.AddDeclRef(FoundDecl.getDecl());
-    CurrentPackingBits.addBits(FoundDecl.getAccess(), /*BitWidth=*/2);
+    Record.push_back(FoundDecl.getAccess());
   }
 
   if (HasQualifier)
@@ -1039,12 +971,10 @@ void ASTStmtWriter::VisitObjCBridgedCastExpr(ObjCBridgedCastExpr *E) {
 
 void ASTStmtWriter::VisitCastExpr(CastExpr *E) {
   VisitExpr(E);
-
   Record.push_back(E->path_size());
-  CurrentPackingBits.addBit(E->hasStoredFPFeatures());
-  // 7 bits should be enough to store the casting kinds.
-  CurrentPackingBits.addBits(E->getCastKind(), /*Width=*/7);
+  Record.push_back(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)
@@ -1059,17 +989,13 @@ 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.
-  CurrentPackingBits.addBit(HasFPFeatures);
-  CurrentPackingBits.addBits(E->getOpcode(), /*Width=*/6);
+  Record.push_back(HasFPFeatures);
+  Record.push_back(E->getOpcode()); // FIXME: stable encoding
   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;
 }
 
@@ -1077,10 +1003,6 @@ 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;
 }
 
@@ -1109,7 +1031,7 @@ ASTStmtWriter::VisitBinaryConditionalOperator(BinaryConditionalOperator *E) {
 
 void ASTStmtWriter::VisitImplicitCastExpr(ImplicitCastExpr *E) {
   VisitCastExpr(E);
-  CurrentPackingBits.addBit(E->isPartOfExplicitCast());
+  Record.push_back(E->isPartOfExplicitCast());
 
   if (E->path_size() == 0 && !E->hasStoredFPFeatures())
     AbbrevToUse = Writer.getExprImplicitCastAbbrev();
@@ -1664,21 +1586,13 @@ void ASTStmtWriter::VisitMSDependentExistsStmt(MSDependentExistsStmt *S) {
 
 void ASTStmtWriter::VisitCXXOperatorCallExpr(CXXOperatorCallExpr *E) {
   VisitCallExpr(E);
-  CurrentPackingBits.addBits(E->getOperator(), /*Width=*/6);
+  Record.push_back(E->getOperator());
   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;
 }
 
@@ -1759,9 +1673,7 @@ void ASTStmtWriter::VisitCXXStdInitializerListExpr(CXXStdInitializerListExpr *E)
 void ASTStmtWriter::VisitCXXNamedCastExpr(CXXNamedCastExpr *E) {
   VisitExplicitCastExpr(E);
   Record.AddSourceRange(SourceRange(E->getOperatorLoc(), E->getRParenLoc()));
-  CurrentPackingBits.addBit(E->getAngleBrackets().isValid());
-  if (E->getAngleBrackets().isValid())
-    Record.AddSourceRange(E->getAngleBrackets());
+  Record.AddSourceRange(E->getAngleBrackets());
 }
 
 void ASTStmtWriter::VisitCXXStaticCastExpr(CXXStaticCastExpr *E) {
@@ -1972,10 +1884,9 @@ void ASTStmtWriter::VisitCXXDependentScopeMemberExpr(
   // Don't emit anything here (or if you do you will have to update
   // the corresponding deserialization function).
 
-  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());
+  Record.push_back(E->hasTemplateKWAndArgsInfo());
+  Record.push_back(E->getNumTemplateArgs());
+  Record.push_back(E->hasFirstQualifierFoundInScope());
 
   if (E->hasTemplateKWAndArgsInfo()) {
     const ASTTemplateKWAndArgsInfo &ArgInfo =
@@ -1984,15 +1895,14 @@ void ASTStmtWriter::VisitCXXDependentScopeMemberExpr(
                              E->getTrailingObjects<TemplateArgumentLoc>());
   }
 
-  CurrentPackingBits.addBit(E->isArrow());
-
+  Record.push_back(E->isArrow());
+  Record.AddSourceLocation(E->getOperatorLoc());
   Record.AddTypeRef(E->getBaseType());
   Record.AddNestedNameSpecifierLoc(E->getQualifierLoc());
-  CurrentPackingBits.addBit(!E->isImplicitAccess());
-  if (!E->isImplicitAccess()) {
+  if (!E->isImplicitAccess())
     Record.AddStmt(E->getBase());
-    Record.AddSourceLocation(E->getOperatorLoc());
-  }
+  else
+    Record.AddStmt(nullptr);
 
   if (E->hasFirstQualifierFoundInScope())
     Record.AddDeclRef(E->getFirstQualifierFoundInScope());
@@ -2007,14 +1917,12 @@ 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>();
-    // 16 bits should be enought to store the number of args
-    CurrentPackingBits.addBits(ArgInfo.NumTemplateArgs, /*Width=*/16);
+    Record.push_back(ArgInfo.NumTemplateArgs);
     AddTemplateKWAndArgsInfo(ArgInfo,
                              E->getTrailingObjects<TemplateArgumentLoc>());
   }
@@ -2041,17 +1949,19 @@ ASTStmtWriter::VisitCXXUnresolvedConstructExpr(CXXUnresolvedConstructExpr *E) {
 void ASTStmtWriter::VisitOverloadExpr(OverloadExpr *E) {
   VisitExpr(E);
 
-  CurrentPackingBits.updateBits();
-  // 12 Bits should enough to store the number of decls.
-  CurrentPackingBits.addBits(E->getNumDecls(), /*BitWidth=*/12);
-  CurrentPackingBits.addBit(E->hasTemplateKWAndArgsInfo());
+  BitsPacker OverloadExprBits;
+  // 14 Bits should enough to store the number of decls.
+  OverloadExprBits.addBits(E->getNumDecls(), /*BitWidth=*/14);
+  OverloadExprBits.addBit(E->hasTemplateKWAndArgsInfo());
   if (E->hasTemplateKWAndArgsInfo()) {
     const ASTTemplateKWAndArgsInfo &ArgInfo =
         *E->getTrailingASTTemplateKWAndArgsInfo();
-    // 12 Bits should enough to store the number of template args.
-    CurrentPackingBits.addBits(ArgInfo.NumTemplateArgs, /*BitWidth=*/12);
+    // 14 Bits should enough to store the number of template args.
+    OverloadExprBits.addBits(ArgInfo.NumTemplateArgs, /*BitWidth=*/14);
+    Record.push_back(OverloadExprBits);
     AddTemplateKWAndArgsInfo(ArgInfo, E->getTrailingTemplateArgumentLoc());
-  }
+  } else
+    Record.push_back(OverloadExprBits);
 
   for (OverloadExpr::decls_iterator OvI = E->decls_begin(),
                                     OvE = E->decls_end();
@@ -2066,22 +1976,18 @@ void ASTStmtWriter::VisitOverloadExpr(OverloadExpr *E) {
 
 void ASTStmtWriter::VisitUnresolvedMemberExpr(UnresolvedMemberExpr *E) {
   VisitOverloadExpr(E);
-  CurrentPackingBits.addBit(E->isArrow());
-  CurrentPackingBits.addBit(E->hasUnresolvedUsing());
-  CurrentPackingBits.addBit(!E->isImplicitAccess());
-  if (!E->isImplicitAccess()) {
-    Record.AddStmt(E->getBase());
-    Record.AddSourceLocation(E->getOperatorLoc());
-  }
-
+  Record.push_back(E->isArrow());
+  Record.push_back(E->hasUnresolvedUsing());
+  Record.AddStmt(!E->isImplicitAccess() ? E->getBase() : nullptr);
   Record.AddTypeRef(E->getBaseType());
+  Record.AddSourceLocation(E->getOperatorLoc());
   Code = serialization::EXPR_CXX_UNRESOLVED_MEMBER;
 }
 
 void ASTStmtWriter::VisitUnresolvedLookupExpr(UnresolvedLookupExpr *E) {
   VisitOverloadExpr(E);
-  CurrentPackingBits.addBit(E->requiresADL());
-  CurrentPackingBits.addBit(E->isOverloaded());
+  Record.push_back(E->requiresADL());
+  Record.push_back(E->isOverloaded());
   Record.AddDeclRef(E->getNamingClass());
   Code = serialization::EXPR_CXX_UNRESOLVED_LOOKUP;
 }
@@ -2153,12 +2059,12 @@ void ASTStmtWriter::VisitSubstNonTypeTemplateParmExpr(
                                               SubstNonTypeTemplateParmExpr *E) {
   VisitExpr(E);
   Record.AddDeclRef(E->getAssociatedDecl());
-  CurrentPackingBits.addBit(E->isReferenceParameter());
-  CurrentPackingBits.addBits(E->getIndex(), /*Width=*/12);
-  CurrentPackingBits.addBit((bool)E->getPackIndex());
+  Record.push_back(E->isReferenceParameter());
+  Record.push_back(E->getIndex());
   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;


        


More information about the cfe-commits mailing list