[clang] [Serialization] Storing DeclID separately (PR #95897)

Chuanqi Xu via cfe-commits cfe-commits at lists.llvm.org
Sun Jun 23 23:21:27 PDT 2024


https://github.com/ChuanqiXu9 updated https://github.com/llvm/llvm-project/pull/95897

>From 0e6b0ee59605d28bb031d8c2fb70fb853d853605 Mon Sep 17 00:00:00 2001
From: Chuanqi Xu <yedeng.yd at linux.alibaba.com>
Date: Tue, 18 Jun 2024 11:28:03 +0800
Subject: [PATCH] [Serialization] Store DeclID in two slots to utilize VBR6
 format

---
 .../include/clang/Serialization/ASTBitCodes.h |   3 +
 clang/include/clang/Serialization/ASTReader.h |   5 +-
 .../clang/Serialization/ASTRecordReader.h     |  19 +++
 .../clang/Serialization/ASTRecordWriter.h     |  27 +++++
 clang/lib/Serialization/ASTReader.cpp         |  44 +++----
 clang/lib/Serialization/ASTReaderDecl.cpp     |  18 ++-
 clang/lib/Serialization/ASTReaderStmt.cpp     |   9 +-
 clang/lib/Serialization/ASTWriter.cpp         |  28 +++--
 clang/lib/Serialization/ASTWriterDecl.cpp     | 112 ++++++++++--------
 clang/test/Modules/codegen-nodep.test         |   2 +-
 clang/test/Modules/decl-params-determinisim.m |  16 +--
 11 files changed, 175 insertions(+), 108 deletions(-)

diff --git a/clang/include/clang/Serialization/ASTBitCodes.h b/clang/include/clang/Serialization/ASTBitCodes.h
index 38502a23f805e..977fa7359ef1b 100644
--- a/clang/include/clang/Serialization/ASTBitCodes.h
+++ b/clang/include/clang/Serialization/ASTBitCodes.h
@@ -285,6 +285,9 @@ using unaligned_decl_id_t =
         serialization::DeclID, llvm::endianness::native,
         llvm::support::unaligned>;
 
+/// The number of slots needed to record a DeclID in bitstreams.
+const unsigned int DeclIDSerialiazedSize = 2;
+
 /// The number of predefined preprocessed entity IDs.
 const unsigned int NUM_PREDEF_PP_ENTITY_IDS = 1;
 
diff --git a/clang/include/clang/Serialization/ASTReader.h b/clang/include/clang/Serialization/ASTReader.h
index f41c473c97cd9..ab257314e2c74 100644
--- a/clang/include/clang/Serialization/ASTReader.h
+++ b/clang/include/clang/Serialization/ASTReader.h
@@ -592,7 +592,7 @@ class ASTReader
 
   /// An array of lexical contents of a declaration context, as a sequence of
   /// Decl::Kind, DeclID pairs.
-  using LexicalContents = ArrayRef<serialization::unaligned_decl_id_t>;
+  using LexicalContents = ArrayRef<uint32_t>;
 
   /// Map from a DeclContext to its lexical contents.
   llvm::DenseMap<const DeclContext*, std::pair<ModuleFile*, LexicalContents>>
@@ -945,8 +945,7 @@ class ASTReader
   SmallVector<uint64_t, 8> DelayedDeleteExprs;
 
   // A list of late parsed template function data with their module files.
-  SmallVector<std::pair<ModuleFile *, SmallVector<uint64_t, 1>>, 4>
-      LateParsedTemplates;
+  SmallVector<std::pair<ModuleFile *, RecordData>, 4> LateParsedTemplates;
 
   /// The IDs of all decls to be checked for deferred diags.
   ///
diff --git a/clang/include/clang/Serialization/ASTRecordReader.h b/clang/include/clang/Serialization/ASTRecordReader.h
index 2561418b78ca7..ae0254214d0c9 100644
--- a/clang/include/clang/Serialization/ASTRecordReader.h
+++ b/clang/include/clang/Serialization/ASTRecordReader.h
@@ -86,6 +86,11 @@ class ASTRecordReader
   /// Skips the specified number of values.
   void skipInts(unsigned N) { Idx += N; }
 
+  /// Skips the specified number of DeclIDs.
+  void skipDeclRefs(unsigned N) {
+    Idx += N * serialization::DeclIDSerialiazedSize;
+  }
+
   /// Retrieve the global submodule ID its local ID number.
   serialization::SubmoduleID
   getGlobalSubmoduleID(unsigned LocalID) {
@@ -187,12 +192,26 @@ class ASTRecordReader
   /// Reads a declaration from the given position in a record in the
   /// given module, advancing Idx.
   Decl *readDecl() {
+#ifndef NDEBUG
+    unsigned OldIdx = Idx;
+    Decl *D = Reader->ReadDecl(*F, Record, Idx);
+    assert(Idx - OldIdx == serialization::DeclIDSerialiazedSize);
+    return D;
+#endif
     return Reader->ReadDecl(*F, Record, Idx);
   }
   Decl *readDeclRef() {
     return readDecl();
   }
 
+  template <class DeclKind, class Func> void readDeclArray(Func &&ConsumeFunc) {
+    unsigned LengthOfArray = readInt();
+    unsigned End = Idx + LengthOfArray;
+
+    while (Idx < End)
+      ConsumeFunc(readDeclAs<DeclKind>());
+  }
+
   /// Reads a declaration from the given position in the record,
   /// advancing Idx.
   ///
diff --git a/clang/include/clang/Serialization/ASTRecordWriter.h b/clang/include/clang/Serialization/ASTRecordWriter.h
index 0c8ac75fc40f4..30e786510ac14 100644
--- a/clang/include/clang/Serialization/ASTRecordWriter.h
+++ b/clang/include/clang/Serialization/ASTRecordWriter.h
@@ -234,12 +234,39 @@ class ASTRecordWriter
 
   /// Emit a reference to a declaration.
   void AddDeclRef(const Decl *D) {
+#ifndef NDEBUG
+    unsigned OldSize = size();
+    Writer->AddDeclRef(D, *Record);
+    assert(size() - OldSize == serialization::DeclIDSerialiazedSize);
+    return;
+#endif
     return Writer->AddDeclRef(D, *Record);
   }
   void writeDeclRef(const Decl *D) {
     AddDeclRef(D);
   }
 
+  void writeNullDeclRef() {
+#ifndef NDEBUG
+    unsigned OldSize = size();
+#endif
+
+    push_back(0);
+    push_back(0);
+
+#ifndef NDEBUG
+    assert(size() - OldSize == serialization::DeclIDSerialiazedSize);
+#endif
+  }
+
+  template <class DeclKind> void writeDeclArray(ArrayRef<DeclKind *> Array) {
+    unsigned ElementNum = Array.size();
+    push_back(ElementNum * serialization::DeclIDSerialiazedSize);
+
+    for (DeclKind *D : Array)
+      AddDeclRef(D);
+  }
+
   /// Emit a declaration name.
   void AddDeclarationName(DeclarationName Name) {
     writeDeclarationName(Name);
diff --git a/clang/lib/Serialization/ASTReader.cpp b/clang/lib/Serialization/ASTReader.cpp
index 079ac3f0e3545..b2bf0f3a46194 100644
--- a/clang/lib/Serialization/ASTReader.cpp
+++ b/clang/lib/Serialization/ASTReader.cpp
@@ -1306,9 +1306,8 @@ bool ASTReader::ReadLexicalDeclContextStorage(ModuleFile &M,
   auto &Lex = LexicalDecls[DC];
   if (!Lex.first) {
     Lex = std::make_pair(
-        &M, llvm::ArrayRef(
-                reinterpret_cast<const unaligned_decl_id_t *>(Blob.data()),
-                Blob.size() / sizeof(DeclID)));
+        &M, llvm::ArrayRef(reinterpret_cast<const uint32_t *>(Blob.data()),
+                           Blob.size() / sizeof(uint32_t)));
   }
   DC->setHasExternalLexicalStorage(true);
   return false;
@@ -3422,8 +3421,8 @@ llvm::Error ASTReader::ReadASTBlock(ModuleFile &F,
     case TU_UPDATE_LEXICAL: {
       DeclContext *TU = ContextObj->getTranslationUnitDecl();
       LexicalContents Contents(
-          reinterpret_cast<const unaligned_decl_id_t *>(Blob.data()),
-          static_cast<unsigned int>(Blob.size() / sizeof(DeclID)));
+          reinterpret_cast<const uint32_t *>(Blob.data()),
+          static_cast<unsigned int>(Blob.size() / sizeof(uint32_t)));
       TULexicalDecls.push_back(std::make_pair(&F, Contents));
       TU->setHasExternalLexicalStorage(true);
       break;
@@ -3696,7 +3695,7 @@ llvm::Error ASTReader::ReadASTBlock(ModuleFile &F,
       break;
 
     case VTABLE_USES:
-      if (Record.size() % 3 != 0)
+      if (Record.size() % (DeclIDSerialiazedSize + 1 + 1) != 0)
         return llvm::createStringError(std::errc::illegal_byte_sequence,
                                        "Invalid VTABLE_USES record");
 
@@ -3714,8 +3713,7 @@ llvm::Error ASTReader::ReadASTBlock(ModuleFile &F,
       break;
 
     case PENDING_IMPLICIT_INSTANTIATIONS:
-
-      if (Record.size() % 2 != 0)
+      if (Record.size() % (DeclIDSerialiazedSize + 1) != 0)
         return llvm::createStringError(
             std::errc::illegal_byte_sequence,
             "Invalid PENDING_IMPLICIT_INSTANTIATIONS block");
@@ -3728,7 +3726,7 @@ llvm::Error ASTReader::ReadASTBlock(ModuleFile &F,
       break;
 
     case SEMA_DECL_REFS:
-      if (Record.size() != 3)
+      if (Record.size() != 3 * serialization::DeclIDSerialiazedSize)
         return llvm::createStringError(std::errc::illegal_byte_sequence,
                                        "Invalid SEMA_DECL_REFS block");
       for (unsigned I = 0, N = Record.size(); I != N; /*in loop*/)
@@ -3786,7 +3784,7 @@ llvm::Error ASTReader::ReadASTBlock(ModuleFile &F,
     }
 
     case DECL_UPDATE_OFFSETS:
-      if (Record.size() % 2 != 0)
+      if (Record.size() % (DeclIDSerialiazedSize + 1) != 0)
         return llvm::createStringError(
             std::errc::illegal_byte_sequence,
             "invalid DECL_UPDATE_OFFSETS block in AST file");
@@ -3803,7 +3801,7 @@ llvm::Error ASTReader::ReadASTBlock(ModuleFile &F,
       break;
 
     case DELAYED_NAMESPACE_LEXICAL_VISIBLE_RECORD: {
-      if (Record.size() % 3 != 0)
+      if (Record.size() % (DeclIDSerialiazedSize + 2) != 0)
         return llvm::createStringError(
             std::errc::illegal_byte_sequence,
             "invalid DELAYED_NAMESPACE_LEXICAL_VISIBLE_RECORD block in AST "
@@ -3898,7 +3896,7 @@ llvm::Error ASTReader::ReadASTBlock(ModuleFile &F,
       break;
 
     case UNDEFINED_BUT_USED:
-      if (Record.size() % 2 != 0)
+      if (Record.size() % (DeclIDSerialiazedSize + 1) != 0)
         return llvm::createStringError(std::errc::illegal_byte_sequence,
                                        "invalid undefined-but-used record");
       for (unsigned I = 0, N = Record.size(); I != N; /* in loop */) {
@@ -7893,7 +7891,10 @@ GlobalDeclID ASTReader::ReadDeclID(ModuleFile &F, const RecordDataImpl &Record,
     return GlobalDeclID(0);
   }
 
-  return getGlobalDeclID(F, LocalDeclID::get(*this, F, Record[Idx++]));
+  uint32_t ModuleFileIndex = Record[Idx++];
+  uint32_t LocalDeclIndex = Record[Idx++];
+  return getGlobalDeclID(
+      F, LocalDeclID::get(*this, F, ModuleFileIndex, LocalDeclIndex));
 }
 
 /// Resolve the offset of a statement into a statement.
@@ -7922,25 +7923,26 @@ void ASTReader::FindExternalLexicalDecls(
     SmallVectorImpl<Decl *> &Decls) {
   bool PredefsVisited[NUM_PREDEF_DECL_IDS] = {};
 
-  auto Visit = [&] (ModuleFile *M, LexicalContents LexicalDecls) {
-    assert(LexicalDecls.size() % 2 == 0 && "expected an even number of entries");
-    for (int I = 0, N = LexicalDecls.size(); I != N; I += 2) {
+  auto Visit = [&](ModuleFile *M, LexicalContents LexicalDecls) {
+    assert(LexicalDecls.size() % 3 == 0 && "incorrect number of entries");
+    for (int I = 0, N = LexicalDecls.size(); I != N; I += 3) {
       auto K = (Decl::Kind)+LexicalDecls[I];
       if (!IsKindWeWant(K))
         continue;
 
-      auto ID = (DeclID) + LexicalDecls[I + 1];
+      LocalDeclID ID =
+          LocalDeclID::get(*this, *M, LexicalDecls[I + 1], LexicalDecls[I + 2]);
 
       // Don't add predefined declarations to the lexical context more
       // than once.
       if (ID < NUM_PREDEF_DECL_IDS) {
-        if (PredefsVisited[ID])
+        if (PredefsVisited[ID.getRawValue()])
           continue;
 
-        PredefsVisited[ID] = true;
+        PredefsVisited[ID.getRawValue()] = true;
       }
 
-      if (Decl *D = GetLocalDecl(*M, LocalDeclID::get(*this, *M, ID))) {
+      if (Decl *D = GetLocalDecl(*M, ID)) {
         assert(D->getKind() == K && "wrong kind for lexical decl");
         if (!DC->isDeclInLexicalTraversal(D))
           Decls.push_back(D);
@@ -8837,7 +8839,7 @@ void ASTReader::ReadLateParsedTemplates(
         &LPTMap) {
   for (auto &LPT : LateParsedTemplates) {
     ModuleFile *FMod = LPT.first;
-    RecordDataImpl &LateParsed = LPT.second;
+    RecordData &LateParsed = LPT.second;
     for (unsigned Idx = 0, N = LateParsed.size(); Idx < N;
          /* In loop */) {
       FunctionDecl *FD = ReadDeclAs<FunctionDecl>(*FMod, LateParsed, Idx);
diff --git a/clang/lib/Serialization/ASTReaderDecl.cpp b/clang/lib/Serialization/ASTReaderDecl.cpp
index 4b8b515c02c70..0e55c831ce34c 100644
--- a/clang/lib/Serialization/ASTReaderDecl.cpp
+++ b/clang/lib/Serialization/ASTReaderDecl.cpp
@@ -1020,9 +1020,8 @@ void ASTDeclReader::VisitFunctionDecl(FunctionDecl *FD) {
   case FunctionDecl::TK_DependentFunctionTemplateSpecialization: {
     // Templates.
     UnresolvedSet<8> Candidates;
-    unsigned NumCandidates = Record.readInt();
-    while (NumCandidates--)
-      Candidates.addDecl(readDeclAs<NamedDecl>());
+    Record.readDeclArray<NamedDecl>(
+        [&Candidates](NamedDecl *ND) { Candidates.addDecl(ND); });
 
     // Templates args.
     TemplateArgumentListInfo TemplArgsWritten;
@@ -1152,11 +1151,9 @@ void ASTDeclReader::VisitFunctionDecl(FunctionDecl *FD) {
   FD->setIsPureVirtual(Pure);
 
   // Read in the parameters.
-  unsigned NumParams = Record.readInt();
   SmallVector<ParmVarDecl *, 16> Params;
-  Params.reserve(NumParams);
-  for (unsigned I = 0; I != NumParams; ++I)
-    Params.push_back(readDeclAs<ParmVarDecl>());
+  Record.readDeclArray<ParmVarDecl>(
+      [&Params](ParmVarDecl *ParmD) { Params.push_back(ParmD); });
   FD->setParams(Reader.getContext(), Params);
 }
 
@@ -2309,7 +2306,7 @@ void ASTDeclReader::VisitCXXMethodDecl(CXXMethodDecl *D) {
   } else {
     // We don't care about which declarations this used to override; we get
     // the relevant information from the canonical declaration.
-    Record.skipInts(NumOverridenMethods);
+    Record.skipDeclRefs(NumOverridenMethods);
   }
 }
 
@@ -4354,8 +4351,9 @@ void ASTReader::loadPendingDeclChain(Decl *FirstLocal, uint64_t LocalOffset) {
   // FIXME: We have several different dispatches on decl kind here; maybe
   // we should instead generate one loop per kind and dispatch up-front?
   Decl *MostRecent = FirstLocal;
-  for (unsigned I = 0, N = Record.size(); I != N; ++I) {
-    unsigned Idx = N - I - 1;
+  for (unsigned I = 0, N = Record.size(); I != N;
+       I += serialization::DeclIDSerialiazedSize) {
+    unsigned Idx = N - I - serialization::DeclIDSerialiazedSize;
     auto *D = ReadDecl(*M, Record, Idx);
     ASTDeclReader::attachPreviousDecl(*this, D, MostRecent, CanonDecl);
     MostRecent = D;
diff --git a/clang/lib/Serialization/ASTReaderStmt.cpp b/clang/lib/Serialization/ASTReaderStmt.cpp
index e23ceffb10bfe..975f03391935f 100644
--- a/clang/lib/Serialization/ASTReaderStmt.cpp
+++ b/clang/lib/Serialization/ASTReaderStmt.cpp
@@ -351,14 +351,15 @@ void ASTStmtReader::VisitDeclStmt(DeclStmt *S) {
   S->setStartLoc(readSourceLocation());
   S->setEndLoc(readSourceLocation());
 
-  if (Record.size() - Record.getIdx() == 1) {
+  unsigned NumDecls =
+      (Record.size() - Record.getIdx()) / serialization::DeclIDSerialiazedSize;
+  if (NumDecls == 1) {
     // Single declaration
     S->setDeclGroup(DeclGroupRef(readDecl()));
   } else {
     SmallVector<Decl *, 16> Decls;
-    int N = Record.size() - Record.getIdx();
-    Decls.reserve(N);
-    for (int I = 0; I < N; ++I)
+    Decls.reserve(NumDecls);
+    for (unsigned I = 0; I < NumDecls; ++I)
       Decls.push_back(readDecl());
     S->setDeclGroup(DeclGroupRef(DeclGroup::Create(Record.getContext(),
                                                    Decls.data(),
diff --git a/clang/lib/Serialization/ASTWriter.cpp b/clang/lib/Serialization/ASTWriter.cpp
index 5b39055cf9f27..ef358ac9dca55 100644
--- a/clang/lib/Serialization/ASTWriter.cpp
+++ b/clang/lib/Serialization/ASTWriter.cpp
@@ -3321,7 +3321,7 @@ uint64_t ASTWriter::WriteDeclContextLexicalBlock(ASTContext &Context,
     return 0;
 
   uint64_t Offset = Stream.GetCurrentBitNo();
-  SmallVector<DeclID, 128> KindDeclPairs;
+  SmallVector<uint32_t, 128> KindDeclPairs;
   for (const auto *D : DC->decls()) {
     if (DoneWritingDeclsAndTypes && !wasDeclEmitted(D))
       continue;
@@ -3336,7 +3336,9 @@ uint64_t ASTWriter::WriteDeclContextLexicalBlock(ASTContext &Context,
       continue;
 
     KindDeclPairs.push_back(D->getKind());
-    KindDeclPairs.push_back(GetDeclRef(D).getRawValue());
+    LocalDeclID ID = GetDeclRef(D);
+    KindDeclPairs.push_back(ID.getModuleFileIndex());
+    KindDeclPairs.push_back(ID.getLocalDeclIndex());
   }
 
   ++NumLexicalDeclContexts;
@@ -4451,8 +4453,9 @@ void ASTWriter::WriteDeclContextVisibleUpdate(const DeclContext *DC) {
     DC = cast<DeclContext>(Chain->getKeyDeclaration(cast<Decl>(DC)));
 
   // Write the lookup table
-  RecordData::value_type Record[] = {UPDATE_VISIBLE,
-                                     getDeclID(cast<Decl>(DC)).getRawValue()};
+  LocalDeclID ID = getDeclID(cast<Decl>(DC));
+  RecordData::value_type Record[] = {UPDATE_VISIBLE, ID.getModuleFileIndex(),
+                                     ID.getLocalDeclIndex()};
   Stream.EmitRecordWithBlob(UpdateVisibleAbbrev, Record, LookupTable);
 }
 
@@ -5243,9 +5246,10 @@ void ASTWriter::WriteSpecialDeclRecords(Sema &SemaRef) {
   RecordData SemaDeclRefs;
   if (SemaRef.StdNamespace || SemaRef.StdBadAlloc || SemaRef.StdAlignValT) {
     auto AddEmittedDeclRefOrZero = [this, &SemaDeclRefs](Decl *D) {
-      if (!D || !wasDeclEmitted(D))
+      if (!D || !wasDeclEmitted(D)) {
         SemaDeclRefs.push_back(0);
-      else
+        SemaDeclRefs.push_back(0);
+      } else
         AddDeclRef(D, SemaDeclRefs);
     };
 
@@ -5679,7 +5683,7 @@ void ASTWriter::WriteDeclAndTypes(ASTContext &Context) {
   const TranslationUnitDecl *TU = Context.getTranslationUnitDecl();
   // Create a lexical update block containing all of the declarations in the
   // translation unit that do not come from other AST files.
-  SmallVector<DeclID, 128> NewGlobalKindDeclPairs;
+  SmallVector<uint32_t, 128> NewGlobalKindDeclPairs;
   for (const auto *D : TU->noload_decls()) {
     if (D->isFromASTFile())
       continue;
@@ -5689,7 +5693,9 @@ void ASTWriter::WriteDeclAndTypes(ASTContext &Context) {
       continue;
 
     NewGlobalKindDeclPairs.push_back(D->getKind());
-    NewGlobalKindDeclPairs.push_back(GetDeclRef(D).getRawValue());
+    LocalDeclID ID = GetDeclRef(D);
+    NewGlobalKindDeclPairs.push_back(ID.getModuleFileIndex());
+    NewGlobalKindDeclPairs.push_back(ID.getLocalDeclIndex());
   }
 
   auto Abv = std::make_shared<llvm::BitCodeAbbrev>();
@@ -5704,6 +5710,7 @@ void ASTWriter::WriteDeclAndTypes(ASTContext &Context) {
   Abv = std::make_shared<llvm::BitCodeAbbrev>();
   Abv->Add(llvm::BitCodeAbbrevOp(UPDATE_VISIBLE));
   Abv->Add(llvm::BitCodeAbbrevOp(llvm::BitCodeAbbrevOp::VBR, 6));
+  Abv->Add(llvm::BitCodeAbbrevOp(llvm::BitCodeAbbrevOp::VBR, 6));
   Abv->Add(llvm::BitCodeAbbrevOp(llvm::BitCodeAbbrevOp::Blob));
   UpdateVisibleAbbrev = Stream.EmitAbbrev(std::move(Abv));
 
@@ -6195,7 +6202,10 @@ void ASTWriter::AddEmittedDeclRef(const Decl *D, RecordDataImpl &Record) {
 }
 
 void ASTWriter::AddDeclRef(const Decl *D, RecordDataImpl &Record) {
-  Record.push_back(GetDeclRef(D).getRawValue());
+  LocalDeclID ID = GetDeclRef(D);
+
+  Record.push_back(ID.getModuleFileIndex());
+  Record.push_back(ID.getLocalDeclIndex());
 }
 
 LocalDeclID ASTWriter::GetDeclRef(const Decl *D) {
diff --git a/clang/lib/Serialization/ASTWriterDecl.cpp b/clang/lib/Serialization/ASTWriterDecl.cpp
index 59d94c3d79824..3a64f831755a4 100644
--- a/clang/lib/Serialization/ASTWriterDecl.cpp
+++ b/clang/lib/Serialization/ASTWriterDecl.cpp
@@ -243,12 +243,15 @@ namespace clang {
         assert(D->isCanonicalDecl() && "non-canonical decl in set");
         AddFirstDeclFromEachModule(D, /*IncludeLocal*/true);
       }
-      Record.append(
-          DeclIDIterator<GlobalDeclID, DeclID>(LazySpecializations.begin()),
-          DeclIDIterator<GlobalDeclID, DeclID>(LazySpecializations.end()));
+
+      for (GlobalDeclID LazyID : LazySpecializations) {
+        Record.push_back(LazyID.getModuleFileIndex());
+        Record.push_back(LazyID.getLocalDeclIndex());
+      }
 
       // Update the size entry we added earlier.
-      Record[I] = Record.size() - I - 1;
+      Record[I] =
+          (Record.size() - I - 1) / serialization::DeclIDSerialiazedSize;
     }
 
     /// Ensure that this template specialization is associated with the specified
@@ -695,9 +698,7 @@ void ASTDeclWriter::VisitFunctionDecl(FunctionDecl *D) {
       DFTSInfo = D->getDependentSpecializationInfo();
 
     // Candidates.
-    Record.push_back(DFTSInfo->getCandidates().size());
-    for (FunctionTemplateDecl *FTD : DFTSInfo->getCandidates())
-      Record.AddDeclRef(FTD);
+    Record.writeDeclArray(DFTSInfo->getCandidates());
 
     // Templates args.
     Record.push_back(DFTSInfo->TemplateArgumentsAsWritten != nullptr);
@@ -769,9 +770,7 @@ void ASTDeclWriter::VisitFunctionDecl(FunctionDecl *D) {
     }
   }
 
-  Record.push_back(D->param_size());
-  for (auto *P : D->parameters())
-    Record.AddDeclRef(P);
+  Record.writeDeclArray(D->parameters());
   Code = serialization::DECL_FUNCTION;
 }
 
@@ -1527,7 +1526,7 @@ void ASTDeclWriter::VisitCXXRecordDecl(CXXRecordDecl *D) {
       Record.AddDeclRef(Context);
       Record.push_back(D->getLambdaIndexInContext());
     } else {
-      Record.push_back(0);
+      Record.writeNullDeclRef();
     }
   } else {
     Record.push_back(CXXRecNotTemplate);
@@ -2060,7 +2059,8 @@ void ASTDeclWriter::VisitRedeclarable(Redeclarable<T> *D) {
       if (Writer.Chain)
         AddFirstDeclFromEachModule(DAsT, /*IncludeLocal*/false);
       // This is the number of imported first declarations + 1.
-      Record[I] = Record.size() - I;
+      Record[I] =
+          ((Record.size() - I - 1) / serialization::DeclIDSerialiazedSize) + 1;
 
       // Collect the set of local redeclarations of this declaration, from
       // newest to oldest.
@@ -2091,8 +2091,8 @@ void ASTDeclWriter::VisitRedeclarable(Redeclarable<T> *D) {
     (void)Writer.GetDeclRef(D->getPreviousDecl());
     (void)Writer.GetDeclRef(MostRecent);
   } else {
-    // We use the sentinel value 0 to indicate an only declaration.
-    Record.push_back(0);
+    // Use the null decl to indicate an only declaration.
+    Record.writeNullDeclRef();
   }
 }
 
@@ -2161,6 +2161,17 @@ void ASTDeclWriter::VisitOMPCapturedExprDecl(OMPCapturedExprDecl *D) {
 //===----------------------------------------------------------------------===//
 
 namespace {
+void AddNullDeclarationAbbrev(std::shared_ptr<llvm::BitCodeAbbrev> &Abv) {
+  using namespace llvm;
+  Abv->Add(BitCodeAbbrevOp(0));
+  Abv->Add(BitCodeAbbrevOp(0));
+}
+
+void AddDeclarationAbbrev(std::shared_ptr<llvm::BitCodeAbbrev> &Abv) {
+  using namespace llvm;
+  Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6));
+  Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6));
+}
 template <FunctionDecl::TemplatedKind Kind>
 std::shared_ptr<llvm::BitCodeAbbrev>
 getFunctionDeclAbbrev(serialization::DeclCode Code) {
@@ -2169,24 +2180,24 @@ getFunctionDeclAbbrev(serialization::DeclCode Code) {
   auto Abv = std::make_shared<BitCodeAbbrev>();
   Abv->Add(BitCodeAbbrevOp(Code));
   // RedeclarableDecl
-  Abv->Add(BitCodeAbbrevOp(0)); // CanonicalDecl
+  AddNullDeclarationAbbrev(Abv); // No Redeclaration
   Abv->Add(BitCodeAbbrevOp(Kind));
   if constexpr (Kind == FunctionDecl::TK_NonTemplate) {
 
   } else if constexpr (Kind == FunctionDecl::TK_FunctionTemplate) {
-    // DescribedFunctionTemplate
-    Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6));
+    AddDeclarationAbbrev(Abv); // DescribedFunctionTemplate
   } else if constexpr (Kind == FunctionDecl::TK_DependentNonTemplate) {
-    // Instantiated From Decl
-    Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6));
+    AddDeclarationAbbrev(Abv); // Instantiated From Decl
   } else if constexpr (Kind == FunctionDecl::TK_MemberSpecialization) {
-    Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // InstantiatedFrom
+    // InstantiatedFrom
+    AddDeclarationAbbrev(Abv);
     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
+    // Template
+    AddDeclarationAbbrev(Abv);
     Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed,
                              3)); // TemplateSpecializationKind
     Abv->Add(BitCodeAbbrevOp(1)); // Template Argument Size
@@ -2197,8 +2208,7 @@ getFunctionDeclAbbrev(serialization::DeclCode Code) {
     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
+    AddDeclarationAbbrev(Abv); // Canonical Decl of template
   } else if constexpr (Kind == FunctionDecl::
                                    TK_DependentFunctionTemplateSpecialization) {
     // Candidates of specialization
@@ -2217,7 +2227,7 @@ getFunctionDeclAbbrev(serialization::DeclCode Code) {
                                 // HasStandaloneLexicalDC, HasAttrs,
                                 // TopLevelDeclInObjCContainer,
                                 // isInvalidDecl
-  Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // DeclContext
+  AddDeclarationAbbrev(Abv);    // DeclContext
   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // SubmoduleID
   // NamedDecl
   Abv->Add(BitCodeAbbrevOp(DeclarationName::Identifier)); // NameKind
@@ -2278,7 +2288,7 @@ void ASTWriter::WriteDeclAbbrevs() {
                                 // isImplicit, HasStandaloneLexicalDC, HasAttrs,
                                 // TopLevelDeclInObjCContainer,
                                 // isInvalidDecl
-  Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // DeclContext
+  AddDeclarationAbbrev(Abv);    // DeclContext
   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // SubmoduleID
   // NamedDecl
   Abv->Add(BitCodeAbbrevOp(0));                       // NameKind = Identifier
@@ -2307,7 +2317,7 @@ void ASTWriter::WriteDeclAbbrevs() {
                                  // isInvalidDecl, HasAttrs, isImplicit, isUsed,
                                  // isReferenced, TopLevelDeclInObjCContainer,
                                  // AccessSpecifier, ModuleOwnershipKind
-  Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // DeclContext
+  AddDeclarationAbbrev(Abv);     // DeclContext
   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // SubmoduleID
   // NamedDecl
   Abv->Add(BitCodeAbbrevOp(0));                       // NameKind = Identifier
@@ -2333,8 +2343,8 @@ void ASTWriter::WriteDeclAbbrevs() {
   // Abbreviation for DECL_ENUM
   Abv = std::make_shared<BitCodeAbbrev>();
   Abv->Add(BitCodeAbbrevOp(serialization::DECL_ENUM));
-  // Redeclarable
-  Abv->Add(BitCodeAbbrevOp(0));                       // No redeclaration
+  // RedeclarableDecl
+  AddNullDeclarationAbbrev(Abv); // No Redeclaration
   // Decl
   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed,
                            7)); // Packed DeclBits: ModuleOwnershipKind,
@@ -2344,7 +2354,7 @@ void ASTWriter::WriteDeclAbbrevs() {
                                 // isImplicit, HasStandaloneLexicalDC, HasAttrs,
                                 // TopLevelDeclInObjCContainer,
                                 // isInvalidDecl
-  Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // DeclContext
+  AddDeclarationAbbrev(Abv);    // DeclContext
   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // SubmoduleID
   // NamedDecl
   Abv->Add(BitCodeAbbrevOp(0));                       // NameKind = Identifier
@@ -2368,7 +2378,7 @@ void ASTWriter::WriteDeclAbbrevs() {
   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6));   // getPromotionType
   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 20)); // Enum Decl Bits
   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32));// ODRHash
-  Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6));   // InstantiatedMembEnum
+  AddDeclarationAbbrev(Abv);                            // InstantiatedMembEnum
   // DC
   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6));   // LexicalOffset
   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6));   // VisibleOffset
@@ -2377,8 +2387,8 @@ void ASTWriter::WriteDeclAbbrevs() {
   // Abbreviation for DECL_RECORD
   Abv = std::make_shared<BitCodeAbbrev>();
   Abv->Add(BitCodeAbbrevOp(serialization::DECL_RECORD));
-  // Redeclarable
-  Abv->Add(BitCodeAbbrevOp(0));                       // No redeclaration
+  // RedeclarableDecl
+  AddNullDeclarationAbbrev(Abv); // No Redeclaration
   // Decl
   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed,
                            7)); // Packed DeclBits: ModuleOwnershipKind,
@@ -2388,7 +2398,7 @@ void ASTWriter::WriteDeclAbbrevs() {
                                 // isImplicit, HasStandaloneLexicalDC, HasAttrs,
                                 // TopLevelDeclInObjCContainer,
                                 // isInvalidDecl
-  Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // DeclContext
+  AddDeclarationAbbrev(Abv);    // DeclContext
   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // SubmoduleID
   // NamedDecl
   Abv->Add(BitCodeAbbrevOp(0));                       // NameKind = Identifier
@@ -2419,7 +2429,6 @@ void ASTWriter::WriteDeclAbbrevs() {
             // getArgPassingRestrictions
   // ODRHash
   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 26));
-
   // DC
   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6));   // LexicalOffset
   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6));   // VisibleOffset
@@ -2428,8 +2437,8 @@ void ASTWriter::WriteDeclAbbrevs() {
   // Abbreviation for DECL_PARM_VAR
   Abv = std::make_shared<BitCodeAbbrev>();
   Abv->Add(BitCodeAbbrevOp(serialization::DECL_PARM_VAR));
-  // Redeclarable
-  Abv->Add(BitCodeAbbrevOp(0));                       // No redeclaration
+  // RedeclarableDecl
+  AddNullDeclarationAbbrev(Abv); // No Redeclaration
   // Decl
   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed,
                            8)); // Packed DeclBits: ModuleOwnershipKind, isUsed,
@@ -2437,7 +2446,7 @@ void ASTWriter::WriteDeclAbbrevs() {
                                 // HasStandaloneLexicalDC, HasAttrs, isImplicit,
                                 // TopLevelDeclInObjCContainer,
                                 // isInvalidDecl,
-  Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // DeclContext
+  AddDeclarationAbbrev(Abv);    // DeclContext
   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // SubmoduleID
   // NamedDecl
   Abv->Add(BitCodeAbbrevOp(0));                       // NameKind = Identifier
@@ -2470,8 +2479,8 @@ void ASTWriter::WriteDeclAbbrevs() {
   // Abbreviation for DECL_TYPEDEF
   Abv = std::make_shared<BitCodeAbbrev>();
   Abv->Add(BitCodeAbbrevOp(serialization::DECL_TYPEDEF));
-  // Redeclarable
-  Abv->Add(BitCodeAbbrevOp(0));                       // No redeclaration
+  // RedeclarableDecl
+  AddNullDeclarationAbbrev(Abv); // No Redeclaration
   // Decl
   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed,
                            7)); // Packed DeclBits: ModuleOwnershipKind,
@@ -2479,7 +2488,7 @@ void ASTWriter::WriteDeclAbbrevs() {
                                 // higher bits should be 0: isImplicit,
                                 // HasStandaloneLexicalDC, HasAttrs,
                                 // TopLevelDeclInObjCContainer, isInvalidDecl
-  Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // DeclContext
+  AddDeclarationAbbrev(Abv);    // DeclContext
   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // SubmoduleID
   // NamedDecl
   Abv->Add(BitCodeAbbrevOp(0));                       // NameKind = Identifier
@@ -2496,15 +2505,15 @@ void ASTWriter::WriteDeclAbbrevs() {
   // Abbreviation for DECL_VAR
   Abv = std::make_shared<BitCodeAbbrev>();
   Abv->Add(BitCodeAbbrevOp(serialization::DECL_VAR));
-  // Redeclarable
-  Abv->Add(BitCodeAbbrevOp(0));                       // No redeclaration
+  // RedeclarableDecl
+  AddNullDeclarationAbbrev(Abv); // 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
+  AddDeclarationAbbrev(Abv);     // DeclContext
   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // SubmoduleID
   // NamedDecl
   Abv->Add(BitCodeAbbrevOp(0));                       // NameKind = Identifier
@@ -2558,7 +2567,7 @@ void ASTWriter::WriteDeclAbbrevs() {
                                 // higher bits should be 0: isImplicit,
                                 // HasStandaloneLexicalDC, HasAttrs,
                                 // TopLevelDeclInObjCContainer, isInvalidDecl
-  Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // DeclContext
+  AddDeclarationAbbrev(Abv);    // DeclContext
   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // SubmoduleID
   // NamedDecl
   Abv->Add(BitCodeAbbrevOp(0));                       // NameKind = Identifier
@@ -2576,26 +2585,25 @@ void ASTWriter::WriteDeclAbbrevs() {
   // Abbreviation for DECL_USING_SHADOW
   Abv = std::make_shared<BitCodeAbbrev>();
   Abv->Add(BitCodeAbbrevOp(serialization::DECL_USING_SHADOW));
-  // Redeclarable
-  Abv->Add(BitCodeAbbrevOp(0)); // No redeclaration
+  // RedeclarableDecl
+  AddNullDeclarationAbbrev(Abv); // 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
+  AddDeclarationAbbrev(Abv);     // 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
+  AddDeclarationAbbrev(Abv);                             // TargetDecl
   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 11)); // IDNS
-  Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6));    // UsingOrNextShadow
-  Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR,
-                           6)); // InstantiatedFromUsingShadowDecl
+  AddDeclarationAbbrev(Abv);                             // UsingOrNextShadow
+  AddDeclarationAbbrev(Abv); // InstantiatedFromUsingShadowDecl
   DeclUsingShadowAbbrev = Stream.EmitAbbrev(std::move(Abv));
 
   // Abbreviation for EXPR_DECL_REF
@@ -2611,7 +2619,7 @@ void ASTWriter::WriteDeclAbbrevs() {
   // IsImmediateEscalating, NonOdrUseReason.
   // GetDeclFound, HasQualifier and ExplicitTemplateArgs should be 0.
   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 5));
-  Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // DeclRef
+  AddDeclarationAbbrev(Abv);                          // DeclRef
   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Location
   DeclRefExprAbbrev = Stream.EmitAbbrev(std::move(Abv));
 
diff --git a/clang/test/Modules/codegen-nodep.test b/clang/test/Modules/codegen-nodep.test
index 9b718ca9a3cf0..c46874354c116 100644
--- a/clang/test/Modules/codegen-nodep.test
+++ b/clang/test/Modules/codegen-nodep.test
@@ -10,4 +10,4 @@ RUN:          | FileCheck %s
 Ensure there are only two modular codegen decls (one for the class, one for the
 function - none for the class and function templates).
 
-CHECK: <MODULAR_CODEGEN_DECLS op0={{[0-9]+}} op1={{[0-9]+}}/>
+CHECK: <MODULAR_CODEGEN_DECLS op0={{[0-9]+}} op1={{[0-9]+}} op2={{[0-9]+}} op3={{[0-9]+}}/>
diff --git a/clang/test/Modules/decl-params-determinisim.m b/clang/test/Modules/decl-params-determinisim.m
index db4ed33265388..acc34adb253f2 100644
--- a/clang/test/Modules/decl-params-determinisim.m
+++ b/clang/test/Modules/decl-params-determinisim.m
@@ -28,23 +28,23 @@
 
 // CHECK: <TYPE_FUNCTION_PROTO
 // CHECK-NEXT: <DECL_PARM_VAR
-// CHECK-SAME: op5=13
+// CHECK-SAME: op7=13
 // CHECK-NEXT: <DECL_PARM_VAR
-// CHECK-SAME: op5=14
+// CHECK-SAME: op7=14
 // CHECK-NEXT: <DECL_PARM_VAR
-// CHECK-SAME: op5=15
+// CHECK-SAME: op7=15
 // CHECK-NEXT: <DECL_PARM_VAR
-// CHECK-SAME: op5=16
+// CHECK-SAME: op7=16
 
 /// Decl records start at 43
 // CHECK: <DECL_RECORD
-// CHECK-SAME: op5=54
+// CHECK-SAME: op7=54
 // CHECK-NEXT: <DECL_RECORD
-// CHECK-SAME: op5=55
+// CHECK-SAME: op7=55
 // CHECK-NEXT: <DECL_RECORD
-// CHECK-SAME: op5=56
+// CHECK-SAME: op7=56
 // CHECK-NEXT: <DECL_RECORD
-// CHECK-SAME: op5=57
+// CHECK-SAME: op7=57
 
 //--- headers/a.h
 void f(struct A0 *a0,



More information about the cfe-commits mailing list