Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-05-10 08:37:06

0001 //===- ASTWriter.h - AST File Writer ----------------------------*- C++ -*-===//
0002 //
0003 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
0004 // See https://llvm.org/LICENSE.txt for license information.
0005 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
0006 //
0007 //===----------------------------------------------------------------------===//
0008 //
0009 //  This file defines the ASTWriter class, which writes an AST file
0010 //  containing a serialized representation of a translation unit.
0011 //
0012 //===----------------------------------------------------------------------===//
0013 
0014 #ifndef LLVM_CLANG_SERIALIZATION_ASTWRITER_H
0015 #define LLVM_CLANG_SERIALIZATION_ASTWRITER_H
0016 
0017 #include "clang/AST/ASTMutationListener.h"
0018 #include "clang/AST/Decl.h"
0019 #include "clang/AST/Type.h"
0020 #include "clang/Basic/LLVM.h"
0021 #include "clang/Basic/SourceLocation.h"
0022 #include "clang/Sema/Sema.h"
0023 #include "clang/Sema/SemaConsumer.h"
0024 #include "clang/Serialization/ASTBitCodes.h"
0025 #include "clang/Serialization/ASTDeserializationListener.h"
0026 #include "clang/Serialization/PCHContainerOperations.h"
0027 #include "clang/Serialization/SourceLocationEncoding.h"
0028 #include "llvm/ADT/ArrayRef.h"
0029 #include "llvm/ADT/DenseMap.h"
0030 #include "llvm/ADT/DenseSet.h"
0031 #include "llvm/ADT/MapVector.h"
0032 #include "llvm/ADT/STLExtras.h"
0033 #include "llvm/ADT/SetVector.h"
0034 #include "llvm/ADT/SmallVector.h"
0035 #include "llvm/ADT/StringRef.h"
0036 #include "llvm/Bitstream/BitstreamWriter.h"
0037 #include <cassert>
0038 #include <cstddef>
0039 #include <cstdint>
0040 #include <ctime>
0041 #include <memory>
0042 #include <queue>
0043 #include <string>
0044 #include <utility>
0045 #include <vector>
0046 
0047 namespace clang {
0048 
0049 class ASTContext;
0050 class ASTReader;
0051 class Attr;
0052 class CXXRecordDecl;
0053 class FileEntry;
0054 class FPOptionsOverride;
0055 class FunctionDecl;
0056 class HeaderSearch;
0057 class HeaderSearchOptions;
0058 class IdentifierResolver;
0059 class LangOptions;
0060 class MacroDefinitionRecord;
0061 class MacroInfo;
0062 class Module;
0063 class InMemoryModuleCache;
0064 class ModuleFileExtension;
0065 class ModuleFileExtensionWriter;
0066 class NamedDecl;
0067 class ObjCInterfaceDecl;
0068 class PreprocessingRecord;
0069 class Preprocessor;
0070 class RecordDecl;
0071 class Sema;
0072 class SourceManager;
0073 class Stmt;
0074 class StoredDeclsList;
0075 class SwitchCase;
0076 class Token;
0077 
0078 namespace SrcMgr {
0079 class FileInfo;
0080 } // namespace SrcMgr
0081 
0082 /// Writes an AST file containing the contents of a translation unit.
0083 ///
0084 /// The ASTWriter class produces a bitstream containing the serialized
0085 /// representation of a given abstract syntax tree and its supporting
0086 /// data structures. This bitstream can be de-serialized via an
0087 /// instance of the ASTReader class.
0088 class ASTWriter : public ASTDeserializationListener,
0089                   public ASTMutationListener {
0090 public:
0091   friend class ASTDeclWriter;
0092   friend class ASTRecordWriter;
0093 
0094   using RecordData = SmallVector<uint64_t, 64>;
0095   using RecordDataImpl = SmallVectorImpl<uint64_t>;
0096   using RecordDataRef = ArrayRef<uint64_t>;
0097 
0098 private:
0099   /// Map that provides the ID numbers of each type within the
0100   /// output stream, plus those deserialized from a chained PCH.
0101   ///
0102   /// The ID numbers of types are consecutive (in order of discovery)
0103   /// and start at 1. 0 is reserved for NULL. When types are actually
0104   /// stored in the stream, the ID number is shifted by 2 bits to
0105   /// allow for the const/volatile qualifiers.
0106   ///
0107   /// Keys in the map never have const/volatile qualifiers.
0108   using TypeIdxMap = llvm::DenseMap<QualType, serialization::TypeIdx,
0109                                     serialization::UnsafeQualTypeDenseMapInfo>;
0110 
0111   using LocSeq = SourceLocationSequence;
0112 
0113   /// The bitstream writer used to emit this precompiled header.
0114   llvm::BitstreamWriter &Stream;
0115 
0116   /// The buffer associated with the bitstream.
0117   const SmallVectorImpl<char> &Buffer;
0118 
0119   /// The PCM manager which manages memory buffers for pcm files.
0120   InMemoryModuleCache &ModuleCache;
0121 
0122   /// The preprocessor we're writing.
0123   Preprocessor *PP = nullptr;
0124 
0125   /// The reader of existing AST files, if we're chaining.
0126   ASTReader *Chain = nullptr;
0127 
0128   /// The module we're currently writing, if any.
0129   Module *WritingModule = nullptr;
0130 
0131   /// The byte range representing all the UNHASHED_CONTROL_BLOCK.
0132   std::pair<uint64_t, uint64_t> UnhashedControlBlockRange;
0133   /// The bit offset of the AST block hash blob.
0134   uint64_t ASTBlockHashOffset = 0;
0135   /// The bit offset of the signature blob.
0136   uint64_t SignatureOffset = 0;
0137 
0138   /// The bit offset of the first bit inside the AST_BLOCK.
0139   uint64_t ASTBlockStartOffset = 0;
0140 
0141   /// The byte range representing all the AST_BLOCK.
0142   std::pair<uint64_t, uint64_t> ASTBlockRange;
0143 
0144   /// The base directory for any relative paths we emit.
0145   std::string BaseDirectory;
0146 
0147   /// Indicates whether timestamps should be written to the produced
0148   /// module file. This is the case for files implicitly written to the
0149   /// module cache, where we need the timestamps to determine if the module
0150   /// file is up to date, but not otherwise.
0151   bool IncludeTimestamps;
0152 
0153   /// Indicates whether the AST file being written is an implicit module.
0154   /// If that's the case, we may be able to skip writing some information that
0155   /// are guaranteed to be the same in the importer by the context hash.
0156   bool BuildingImplicitModule = false;
0157 
0158   /// Indicates when the AST writing is actively performing
0159   /// serialization, rather than just queueing updates.
0160   bool WritingAST = false;
0161 
0162   /// Indicates that we are done serializing the collection of decls
0163   /// and types to emit.
0164   bool DoneWritingDeclsAndTypes = false;
0165 
0166   /// Indicates that the AST contained compiler errors.
0167   bool ASTHasCompilerErrors = false;
0168 
0169   /// Indicates that we're going to generate the reduced BMI for C++20
0170   /// named modules.
0171   bool GeneratingReducedBMI = false;
0172 
0173   /// Mapping from input file entries to the index into the
0174   /// offset table where information about that input file is stored.
0175   llvm::DenseMap<const FileEntry *, uint32_t> InputFileIDs;
0176 
0177   /// Stores a declaration or a type to be written to the AST file.
0178   class DeclOrType {
0179   public:
0180     DeclOrType(Decl *D) : Stored(D), IsType(false) {}
0181     DeclOrType(QualType T) : Stored(T.getAsOpaquePtr()), IsType(true) {}
0182 
0183     bool isType() const { return IsType; }
0184     bool isDecl() const { return !IsType; }
0185 
0186     QualType getType() const {
0187       assert(isType() && "Not a type!");
0188       return QualType::getFromOpaquePtr(Stored);
0189     }
0190 
0191     Decl *getDecl() const {
0192       assert(isDecl() && "Not a decl!");
0193       return static_cast<Decl *>(Stored);
0194     }
0195 
0196   private:
0197     void *Stored;
0198     bool IsType;
0199   };
0200 
0201   /// The declarations and types to emit.
0202   std::queue<DeclOrType> DeclTypesToEmit;
0203 
0204   /// The delayed namespace to emit. Only meaningful for reduced BMI.
0205   ///
0206   /// In reduced BMI, we want to elide the unreachable declarations in
0207   /// the global module fragment. However, in ASTWriterDecl, when we see
0208   /// a namespace, all the declarations in the namespace would be emitted.
0209   /// So the optimization become meaningless. To solve the issue, we
0210   /// delay recording all the declarations until we emit all the declarations.
0211   /// Then we can safely record the reached declarations only.
0212   llvm::SmallVector<NamespaceDecl *, 16> DelayedNamespace;
0213 
0214   /// The first ID number we can use for our own declarations.
0215   LocalDeclID FirstDeclID = LocalDeclID(clang::NUM_PREDEF_DECL_IDS);
0216 
0217   /// The decl ID that will be assigned to the next new decl.
0218   LocalDeclID NextDeclID = FirstDeclID;
0219 
0220   /// Map that provides the ID numbers of each declaration within
0221   /// the output stream, as well as those deserialized from a chained PCH.
0222   ///
0223   /// The ID numbers of declarations are consecutive (in order of
0224   /// discovery) and start at 2. 1 is reserved for the translation
0225   /// unit, while 0 is reserved for NULL.
0226   llvm::DenseMap<const Decl *, LocalDeclID> DeclIDs;
0227 
0228   /// Set of predefined decls. This is a helper data to determine if a decl
0229   /// is predefined. It should be more clear and safer to query the set
0230   /// instead of comparing the result of `getDeclID()` or `GetDeclRef()`.
0231   llvm::SmallPtrSet<const Decl *, 32> PredefinedDecls;
0232 
0233   /// Mapping from the main decl to related decls inside the main decls.
0234   ///
0235   /// These related decls have to be loaded right after the main decl they
0236   /// belong to. In order to have canonical declaration for related decls from
0237   /// the same module as the main decl during deserialization.
0238   llvm::DenseMap<LocalDeclID, SmallVector<LocalDeclID, 4>> RelatedDeclsMap;
0239 
0240   /// Offset of each declaration in the bitstream, indexed by
0241   /// the declaration's ID.
0242   std::vector<serialization::DeclOffset> DeclOffsets;
0243 
0244   /// The offset of the DECLTYPES_BLOCK. The offsets in DeclOffsets
0245   /// are relative to this value.
0246   uint64_t DeclTypesBlockStartOffset = 0;
0247 
0248   /// Sorted (by file offset) vector of pairs of file offset/LocalDeclID.
0249   using LocDeclIDsTy = SmallVector<std::pair<unsigned, LocalDeclID>, 64>;
0250   struct DeclIDInFileInfo {
0251     LocDeclIDsTy DeclIDs;
0252 
0253     /// Set when the DeclIDs vectors from all files are joined, this
0254     /// indicates the index that this particular vector has in the global one.
0255     unsigned FirstDeclIndex;
0256   };
0257   using FileDeclIDsTy =
0258       llvm::DenseMap<FileID, std::unique_ptr<DeclIDInFileInfo>>;
0259 
0260   /// Map from file SLocEntries to info about the file-level declarations
0261   /// that it contains.
0262   FileDeclIDsTy FileDeclIDs;
0263 
0264   void associateDeclWithFile(const Decl *D, LocalDeclID);
0265 
0266   /// The first ID number we can use for our own types.
0267   serialization::TypeID FirstTypeID = serialization::NUM_PREDEF_TYPE_IDS;
0268 
0269   /// The type ID that will be assigned to the next new type.
0270   serialization::TypeID NextTypeID = FirstTypeID;
0271 
0272   /// Map that provides the ID numbers of each type within the
0273   /// output stream, plus those deserialized from a chained PCH.
0274   ///
0275   /// The ID numbers of types are consecutive (in order of discovery)
0276   /// and start at 1. 0 is reserved for NULL. When types are actually
0277   /// stored in the stream, the ID number is shifted by 2 bits to
0278   /// allow for the const/volatile qualifiers.
0279   ///
0280   /// Keys in the map never have const/volatile qualifiers.
0281   TypeIdxMap TypeIdxs;
0282 
0283   /// Offset of each type in the bitstream, indexed by
0284   /// the type's ID.
0285   std::vector<serialization::UnalignedUInt64> TypeOffsets;
0286 
0287   /// The first ID number we can use for our own identifiers.
0288   serialization::IdentifierID FirstIdentID = serialization::NUM_PREDEF_IDENT_IDS;
0289 
0290   /// The identifier ID that will be assigned to the next new identifier.
0291   serialization::IdentifierID NextIdentID = FirstIdentID;
0292 
0293   /// Map that provides the ID numbers of each identifier in
0294   /// the output stream.
0295   ///
0296   /// The ID numbers for identifiers are consecutive (in order of
0297   /// discovery), starting at 1. An ID of zero refers to a NULL
0298   /// IdentifierInfo.
0299   llvm::MapVector<const IdentifierInfo *, serialization::IdentifierID> IdentifierIDs;
0300 
0301   /// The first ID number we can use for our own macros.
0302   serialization::MacroID FirstMacroID = serialization::NUM_PREDEF_MACRO_IDS;
0303 
0304   /// The identifier ID that will be assigned to the next new identifier.
0305   serialization::MacroID NextMacroID = FirstMacroID;
0306 
0307   /// Map that provides the ID numbers of each macro.
0308   llvm::DenseMap<MacroInfo *, serialization::MacroID> MacroIDs;
0309 
0310   struct MacroInfoToEmitData {
0311     const IdentifierInfo *Name;
0312     MacroInfo *MI;
0313     serialization::MacroID ID;
0314   };
0315 
0316   /// The macro infos to emit.
0317   std::vector<MacroInfoToEmitData> MacroInfosToEmit;
0318 
0319   llvm::DenseMap<const IdentifierInfo *, uint32_t>
0320       IdentMacroDirectivesOffsetMap;
0321 
0322   /// @name FlushStmt Caches
0323   /// @{
0324 
0325   /// Set of parent Stmts for the currently serializing sub-stmt.
0326   llvm::DenseSet<Stmt *> ParentStmts;
0327 
0328   /// Offsets of sub-stmts already serialized. The offset points
0329   /// just after the stmt record.
0330   llvm::DenseMap<Stmt *, uint64_t> SubStmtEntries;
0331 
0332   /// @}
0333 
0334   /// Offsets of each of the identifier IDs into the identifier
0335   /// table.
0336   std::vector<uint32_t> IdentifierOffsets;
0337 
0338   /// The first ID number we can use for our own submodules.
0339   serialization::SubmoduleID FirstSubmoduleID =
0340       serialization::NUM_PREDEF_SUBMODULE_IDS;
0341 
0342   /// The submodule ID that will be assigned to the next new submodule.
0343   serialization::SubmoduleID NextSubmoduleID = FirstSubmoduleID;
0344 
0345   /// The first ID number we can use for our own selectors.
0346   serialization::SelectorID FirstSelectorID =
0347       serialization::NUM_PREDEF_SELECTOR_IDS;
0348 
0349   /// The selector ID that will be assigned to the next new selector.
0350   serialization::SelectorID NextSelectorID = FirstSelectorID;
0351 
0352   /// Map that provides the ID numbers of each Selector.
0353   llvm::MapVector<Selector, serialization::SelectorID> SelectorIDs;
0354 
0355   /// Offset of each selector within the method pool/selector
0356   /// table, indexed by the Selector ID (-1).
0357   std::vector<uint32_t> SelectorOffsets;
0358 
0359   /// Mapping from macro definitions (as they occur in the preprocessing
0360   /// record) to the macro IDs.
0361   llvm::DenseMap<const MacroDefinitionRecord *,
0362                  serialization::PreprocessedEntityID> MacroDefinitions;
0363 
0364   /// Cache of indices of anonymous declarations within their lexical
0365   /// contexts.
0366   llvm::DenseMap<const Decl *, unsigned> AnonymousDeclarationNumbers;
0367 
0368   /// The external top level module during the writing process. Used to
0369   /// generate signature for the module file being written.
0370   ///
0371   /// Only meaningful for standard C++ named modules. See the comments in
0372   /// createSignatureForNamedModule() for details.
0373   llvm::DenseSet<Module *> TouchedTopLevelModules;
0374 
0375   /// An update to a Decl.
0376   class DeclUpdate {
0377     /// A DeclUpdateKind.
0378     unsigned Kind;
0379     union {
0380       const Decl *Dcl;
0381       void *Type;
0382       SourceLocation::UIntTy Loc;
0383       unsigned Val;
0384       Module *Mod;
0385       const Attr *Attribute;
0386     };
0387 
0388   public:
0389     DeclUpdate(unsigned Kind) : Kind(Kind), Dcl(nullptr) {}
0390     DeclUpdate(unsigned Kind, const Decl *Dcl) : Kind(Kind), Dcl(Dcl) {}
0391     DeclUpdate(unsigned Kind, QualType Type)
0392         : Kind(Kind), Type(Type.getAsOpaquePtr()) {}
0393     DeclUpdate(unsigned Kind, SourceLocation Loc)
0394         : Kind(Kind), Loc(Loc.getRawEncoding()) {}
0395     DeclUpdate(unsigned Kind, unsigned Val) : Kind(Kind), Val(Val) {}
0396     DeclUpdate(unsigned Kind, Module *M) : Kind(Kind), Mod(M) {}
0397     DeclUpdate(unsigned Kind, const Attr *Attribute)
0398           : Kind(Kind), Attribute(Attribute) {}
0399 
0400     unsigned getKind() const { return Kind; }
0401     const Decl *getDecl() const { return Dcl; }
0402     QualType getType() const { return QualType::getFromOpaquePtr(Type); }
0403 
0404     SourceLocation getLoc() const {
0405       return SourceLocation::getFromRawEncoding(Loc);
0406     }
0407 
0408     unsigned getNumber() const { return Val; }
0409     Module *getModule() const { return Mod; }
0410     const Attr *getAttr() const { return Attribute; }
0411   };
0412 
0413   using UpdateRecord = SmallVector<DeclUpdate, 1>;
0414   using DeclUpdateMap = llvm::MapVector<const Decl *, UpdateRecord>;
0415 
0416   /// Mapping from declarations that came from a chained PCH to the
0417   /// record containing modifications to them.
0418   DeclUpdateMap DeclUpdates;
0419 
0420   /// DeclUpdates added during parsing the GMF. We split these from
0421   /// DeclUpdates since we want to add these updates in GMF on need.
0422   /// Only meaningful for reduced BMI.
0423   DeclUpdateMap DeclUpdatesFromGMF;
0424 
0425   /// Mapping from decl templates and its new specialization in the
0426   /// current TU.
0427   using SpecializationUpdateMap =
0428       llvm::MapVector<const NamedDecl *, SmallVector<const Decl *>>;
0429   SpecializationUpdateMap SpecializationsUpdates;
0430   SpecializationUpdateMap PartialSpecializationsUpdates;
0431 
0432   using FirstLatestDeclMap = llvm::DenseMap<Decl *, Decl *>;
0433 
0434   /// Map of first declarations from a chained PCH that point to the
0435   /// most recent declarations in another PCH.
0436   FirstLatestDeclMap FirstLatestDecls;
0437 
0438   /// Declarations encountered that might be external
0439   /// definitions.
0440   ///
0441   /// We keep track of external definitions and other 'interesting' declarations
0442   /// as we are emitting declarations to the AST file. The AST file contains a
0443   /// separate record for these declarations, which are provided to the AST
0444   /// consumer by the AST reader. This is behavior is required to properly cope with,
0445   /// e.g., tentative variable definitions that occur within
0446   /// headers. The declarations themselves are stored as declaration
0447   /// IDs, since they will be written out to an EAGERLY_DESERIALIZED_DECLS
0448   /// record.
0449   RecordData EagerlyDeserializedDecls;
0450   RecordData ModularCodegenDecls;
0451 
0452   /// DeclContexts that have received extensions since their serialized
0453   /// form.
0454   ///
0455   /// For namespaces, when we're chaining and encountering a namespace, we check
0456   /// if its primary namespace comes from the chain. If it does, we add the
0457   /// primary to this set, so that we can write out lexical content updates for
0458   /// it.
0459   llvm::SmallSetVector<const DeclContext *, 16> UpdatedDeclContexts;
0460 
0461   /// Keeps track of declarations that we must emit, even though we're
0462   /// not guaranteed to be able to find them by walking the AST starting at the
0463   /// translation unit.
0464   SmallVector<const Decl *, 16> DeclsToEmitEvenIfUnreferenced;
0465 
0466   /// The set of Objective-C class that have categories we
0467   /// should serialize.
0468   llvm::SetVector<ObjCInterfaceDecl *> ObjCClassesWithCategories;
0469 
0470   /// The set of declarations that may have redeclaration chains that
0471   /// need to be serialized.
0472   llvm::SmallVector<const Decl *, 16> Redeclarations;
0473 
0474   /// A cache of the first local declaration for "interesting"
0475   /// redeclaration chains.
0476   llvm::DenseMap<const Decl *, const Decl *> FirstLocalDeclCache;
0477 
0478   /// Mapping from SwitchCase statements to IDs.
0479   llvm::DenseMap<SwitchCase *, unsigned> SwitchCaseIDs;
0480 
0481   /// The number of statements written to the AST file.
0482   unsigned NumStatements = 0;
0483 
0484   /// The number of macros written to the AST file.
0485   unsigned NumMacros = 0;
0486 
0487   /// The number of lexical declcontexts written to the AST
0488   /// file.
0489   unsigned NumLexicalDeclContexts = 0;
0490 
0491   /// The number of visible declcontexts written to the AST
0492   /// file.
0493   unsigned NumVisibleDeclContexts = 0;
0494 
0495   /// The number of module local visible declcontexts written to the AST
0496   /// file.
0497   unsigned NumModuleLocalDeclContexts = 0;
0498 
0499   /// The number of TULocal declcontexts written to the AST file.
0500   unsigned NumTULocalDeclContexts = 0;
0501 
0502   /// A mapping from each known submodule to its ID number, which will
0503   /// be a positive integer.
0504   llvm::DenseMap<const Module *, unsigned> SubmoduleIDs;
0505 
0506   /// A list of the module file extension writers.
0507   std::vector<std::unique_ptr<ModuleFileExtensionWriter>>
0508       ModuleFileExtensionWriters;
0509 
0510   /// Mapping from a source location entry to whether it is affecting or not.
0511   llvm::BitVector IsSLocAffecting;
0512   /// Mapping from a source location entry to whether it must be included as
0513   /// input file.
0514   llvm::BitVector IsSLocFileEntryAffecting;
0515 
0516   /// Mapping from \c FileID to an index into the FileID adjustment table.
0517   std::vector<FileID> NonAffectingFileIDs;
0518   std::vector<unsigned> NonAffectingFileIDAdjustments;
0519 
0520   /// Mapping from an offset to an index into the offset adjustment table.
0521   std::vector<SourceRange> NonAffectingRanges;
0522   std::vector<SourceLocation::UIntTy> NonAffectingOffsetAdjustments;
0523 
0524   /// A list of classes in named modules which need to emit the VTable in
0525   /// the corresponding object file.
0526   llvm::SmallVector<CXXRecordDecl *> PendingEmittingVTables;
0527 
0528   /// Computes input files that didn't affect compilation of the current module,
0529   /// and initializes data structures necessary for leaving those files out
0530   /// during \c SourceManager serialization.
0531   void computeNonAffectingInputFiles();
0532 
0533   /// Some affecting files can be included from files that are not affecting.
0534   /// This function erases source locations pointing into such files.
0535   SourceLocation getAffectingIncludeLoc(const SourceManager &SourceMgr,
0536                                         const SrcMgr::FileInfo &File);
0537 
0538   /// Returns an adjusted \c FileID, accounting for any non-affecting input
0539   /// files.
0540   FileID getAdjustedFileID(FileID FID) const;
0541   /// Returns an adjusted number of \c FileIDs created within the specified \c
0542   /// FileID, accounting for any non-affecting input files.
0543   unsigned getAdjustedNumCreatedFIDs(FileID FID) const;
0544   /// Returns an adjusted \c SourceLocation, accounting for any non-affecting
0545   /// input files.
0546   SourceLocation getAdjustedLocation(SourceLocation Loc) const;
0547   /// Returns an adjusted \c SourceRange, accounting for any non-affecting input
0548   /// files.
0549   SourceRange getAdjustedRange(SourceRange Range) const;
0550   /// Returns an adjusted \c SourceLocation offset, accounting for any
0551   /// non-affecting input files.
0552   SourceLocation::UIntTy getAdjustedOffset(SourceLocation::UIntTy Offset) const;
0553   /// Returns an adjustment for offset into SourceManager, accounting for any
0554   /// non-affecting input files.
0555   SourceLocation::UIntTy getAdjustment(SourceLocation::UIntTy Offset) const;
0556 
0557   /// Retrieve or create a submodule ID for this module.
0558   unsigned getSubmoduleID(Module *Mod);
0559 
0560   /// Write the given subexpression to the bitstream.
0561   void WriteSubStmt(ASTContext &Context, Stmt *S);
0562 
0563   void WriteBlockInfoBlock();
0564   void WriteControlBlock(Preprocessor &PP, StringRef isysroot);
0565 
0566   /// Write out the signature and diagnostic options, and return the signature.
0567   void writeUnhashedControlBlock(Preprocessor &PP);
0568   ASTFileSignature backpatchSignature();
0569 
0570   /// Calculate hash of the pcm content.
0571   std::pair<ASTFileSignature, ASTFileSignature> createSignature() const;
0572   ASTFileSignature createSignatureForNamedModule() const;
0573 
0574   void WriteInputFiles(SourceManager &SourceMgr, HeaderSearchOptions &HSOpts);
0575   void WriteSourceManagerBlock(SourceManager &SourceMgr);
0576   void WritePreprocessor(const Preprocessor &PP, bool IsModule);
0577   void WriteHeaderSearch(const HeaderSearch &HS);
0578   void WritePreprocessorDetail(PreprocessingRecord &PPRec,
0579                                uint64_t MacroOffsetsBase);
0580   void WriteSubmodules(Module *WritingModule, ASTContext *Context);
0581 
0582   void WritePragmaDiagnosticMappings(const DiagnosticsEngine &Diag,
0583                                      bool isModule);
0584 
0585   unsigned TypeExtQualAbbrev = 0;
0586   void WriteTypeAbbrevs();
0587   void WriteType(ASTContext &Context, QualType T);
0588 
0589   bool isLookupResultExternal(StoredDeclsList &Result, DeclContext *DC);
0590 
0591   void GenerateSpecializationInfoLookupTable(
0592       const NamedDecl *D, llvm::SmallVectorImpl<const Decl *> &Specializations,
0593       llvm::SmallVectorImpl<char> &LookupTable, bool IsPartial);
0594   uint64_t WriteSpecializationInfoLookupTable(
0595       const NamedDecl *D, llvm::SmallVectorImpl<const Decl *> &Specializations,
0596       bool IsPartial);
0597   void
0598   GenerateNameLookupTable(ASTContext &Context, const DeclContext *DC,
0599                           llvm::SmallVectorImpl<char> &LookupTable,
0600                           llvm::SmallVectorImpl<char> &ModuleLocalLookupTable,
0601                           llvm::SmallVectorImpl<char> &TULocalLookupTable);
0602   uint64_t WriteDeclContextLexicalBlock(ASTContext &Context,
0603                                         const DeclContext *DC);
0604   void WriteDeclContextVisibleBlock(ASTContext &Context, DeclContext *DC,
0605                                     uint64_t &VisibleBlockOffset,
0606                                     uint64_t &ModuleLocalBlockOffset,
0607                                     uint64_t &TULocalBlockOffset);
0608   void WriteTypeDeclOffsets();
0609   void WriteFileDeclIDsMap();
0610   void WriteComments(ASTContext &Context);
0611   void WriteSelectors(Sema &SemaRef);
0612   void WriteReferencedSelectorsPool(Sema &SemaRef);
0613   void WriteIdentifierTable(Preprocessor &PP, IdentifierResolver *IdResolver,
0614                             bool IsModule);
0615   void WriteDeclAndTypes(ASTContext &Context);
0616   void PrepareWritingSpecialDecls(Sema &SemaRef);
0617   void WriteSpecialDeclRecords(Sema &SemaRef);
0618   void WriteSpecializationsUpdates(bool IsPartial);
0619   void WriteDeclUpdatesBlocks(ASTContext &Context,
0620                               RecordDataImpl &OffsetsRecord);
0621   void WriteDeclContextVisibleUpdate(ASTContext &Context,
0622                                      const DeclContext *DC);
0623   void WriteFPPragmaOptions(const FPOptionsOverride &Opts);
0624   void WriteOpenCLExtensions(Sema &SemaRef);
0625   void WriteCUDAPragmas(Sema &SemaRef);
0626   void WriteObjCCategories();
0627   void WriteLateParsedTemplates(Sema &SemaRef);
0628   void WriteOptimizePragmaOptions(Sema &SemaRef);
0629   void WriteMSStructPragmaOptions(Sema &SemaRef);
0630   void WriteMSPointersToMembersPragmaOptions(Sema &SemaRef);
0631   void WritePackPragmaOptions(Sema &SemaRef);
0632   void WriteFloatControlPragmaOptions(Sema &SemaRef);
0633   void WriteDeclsWithEffectsToVerify(Sema &SemaRef);
0634   void WriteModuleFileExtension(Sema &SemaRef,
0635                                 ModuleFileExtensionWriter &Writer);
0636 
0637   unsigned DeclParmVarAbbrev = 0;
0638   unsigned DeclContextLexicalAbbrev = 0;
0639   unsigned DeclContextVisibleLookupAbbrev = 0;
0640   unsigned DeclModuleLocalVisibleLookupAbbrev = 0;
0641   unsigned DeclTULocalLookupAbbrev = 0;
0642   unsigned UpdateVisibleAbbrev = 0;
0643   unsigned ModuleLocalUpdateVisibleAbbrev = 0;
0644   unsigned TULocalUpdateVisibleAbbrev = 0;
0645   unsigned DeclRecordAbbrev = 0;
0646   unsigned DeclTypedefAbbrev = 0;
0647   unsigned DeclVarAbbrev = 0;
0648   unsigned DeclFieldAbbrev = 0;
0649   unsigned DeclEnumAbbrev = 0;
0650   unsigned DeclObjCIvarAbbrev = 0;
0651   unsigned DeclCXXMethodAbbrev = 0;
0652   unsigned DeclSpecializationsAbbrev = 0;
0653   unsigned DeclPartialSpecializationsAbbrev = 0;
0654 
0655   unsigned DeclDependentNonTemplateCXXMethodAbbrev = 0;
0656   unsigned DeclTemplateCXXMethodAbbrev = 0;
0657   unsigned DeclMemberSpecializedCXXMethodAbbrev = 0;
0658   unsigned DeclTemplateSpecializedCXXMethodAbbrev = 0;
0659   unsigned DeclDependentSpecializationCXXMethodAbbrev = 0;
0660   unsigned DeclTemplateTypeParmAbbrev = 0;
0661   unsigned DeclUsingShadowAbbrev = 0;
0662 
0663   unsigned DeclRefExprAbbrev = 0;
0664   unsigned CharacterLiteralAbbrev = 0;
0665   unsigned IntegerLiteralAbbrev = 0;
0666   unsigned ExprImplicitCastAbbrev = 0;
0667   unsigned BinaryOperatorAbbrev = 0;
0668   unsigned CompoundAssignOperatorAbbrev = 0;
0669   unsigned CallExprAbbrev = 0;
0670   unsigned CXXOperatorCallExprAbbrev = 0;
0671   unsigned CXXMemberCallExprAbbrev = 0;
0672 
0673   unsigned CompoundStmtAbbrev = 0;
0674 
0675   void WriteDeclAbbrevs();
0676   void WriteDecl(ASTContext &Context, Decl *D);
0677 
0678   ASTFileSignature WriteASTCore(Sema *SemaPtr, StringRef isysroot,
0679                                 Module *WritingModule);
0680 
0681 public:
0682   /// Create a new precompiled header writer that outputs to
0683   /// the given bitstream.
0684   ASTWriter(llvm::BitstreamWriter &Stream, SmallVectorImpl<char> &Buffer,
0685             InMemoryModuleCache &ModuleCache,
0686             ArrayRef<std::shared_ptr<ModuleFileExtension>> Extensions,
0687             bool IncludeTimestamps = true, bool BuildingImplicitModule = false,
0688             bool GeneratingReducedBMI = false);
0689   ~ASTWriter() override;
0690 
0691   const LangOptions &getLangOpts() const;
0692 
0693   /// Get a timestamp for output into the AST file. The actual timestamp
0694   /// of the specified file may be ignored if we have been instructed to not
0695   /// include timestamps in the output file.
0696   time_t getTimestampForOutput(const FileEntry *E) const;
0697 
0698   /// Write a precompiled header or a module with the AST produced by the
0699   /// \c Sema object, or a dependency scanner module with the preprocessor state
0700   /// produced by the \c Preprocessor object.
0701   ///
0702   /// \param Subject The \c Sema object that processed the AST to be written, or
0703   /// in the case of a dependency scanner module the \c Preprocessor that holds
0704   /// the state.
0705   ///
0706   /// \param WritingModule The module that we are writing. If null, we are
0707   /// writing a precompiled header.
0708   ///
0709   /// \param isysroot if non-empty, write a relocatable file whose headers
0710   /// are relative to the given system root. If we're writing a module, its
0711   /// build directory will be used in preference to this if both are available.
0712   ///
0713   /// \return the module signature, which eventually will be a hash of
0714   /// the module but currently is merely a random 32-bit number.
0715   ASTFileSignature WriteAST(llvm::PointerUnion<Sema *, Preprocessor *> Subject,
0716                             StringRef OutputFile, Module *WritingModule,
0717                             StringRef isysroot,
0718                             bool ShouldCacheASTInMemory = false);
0719 
0720   /// Emit a token.
0721   void AddToken(const Token &Tok, RecordDataImpl &Record);
0722 
0723   /// Emit a AlignPackInfo.
0724   void AddAlignPackInfo(const Sema::AlignPackInfo &Info,
0725                         RecordDataImpl &Record);
0726 
0727   /// Emit a FileID.
0728   void AddFileID(FileID FID, RecordDataImpl &Record);
0729 
0730   /// Emit a source location.
0731   void AddSourceLocation(SourceLocation Loc, RecordDataImpl &Record,
0732                          LocSeq *Seq = nullptr);
0733 
0734   /// Return the raw encodings for source locations.
0735   SourceLocationEncoding::RawLocEncoding
0736   getRawSourceLocationEncoding(SourceLocation Loc, LocSeq *Seq = nullptr);
0737 
0738   /// Emit a source range.
0739   void AddSourceRange(SourceRange Range, RecordDataImpl &Record,
0740                       LocSeq *Seq = nullptr);
0741 
0742   /// Emit a reference to an identifier.
0743   void AddIdentifierRef(const IdentifierInfo *II, RecordDataImpl &Record);
0744 
0745   /// Get the unique number used to refer to the given selector.
0746   serialization::SelectorID getSelectorRef(Selector Sel);
0747 
0748   /// Get the unique number used to refer to the given identifier.
0749   serialization::IdentifierID getIdentifierRef(const IdentifierInfo *II);
0750 
0751   /// Get the unique number used to refer to the given macro.
0752   serialization::MacroID getMacroRef(MacroInfo *MI, const IdentifierInfo *Name);
0753 
0754   /// Determine the ID of an already-emitted macro.
0755   serialization::MacroID getMacroID(MacroInfo *MI);
0756 
0757   uint32_t getMacroDirectivesOffset(const IdentifierInfo *Name);
0758 
0759   /// Emit a reference to a type.
0760   void AddTypeRef(ASTContext &Context, QualType T, RecordDataImpl &Record);
0761 
0762   /// Force a type to be emitted and get its ID.
0763   serialization::TypeID GetOrCreateTypeID(ASTContext &Context, QualType T);
0764 
0765   /// Find the first local declaration of a given local redeclarable
0766   /// decl.
0767   const Decl *getFirstLocalDecl(const Decl *D);
0768 
0769   /// Is this a local declaration (that is, one that will be written to
0770   /// our AST file)? This is the case for declarations that are neither imported
0771   /// from another AST file nor predefined.
0772   bool IsLocalDecl(const Decl *D) {
0773     if (D->isFromASTFile())
0774       return false;
0775     auto I = DeclIDs.find(D);
0776     return (I == DeclIDs.end() || I->second >= clang::NUM_PREDEF_DECL_IDS);
0777   };
0778 
0779   /// Emit a reference to a declaration.
0780   void AddDeclRef(const Decl *D, RecordDataImpl &Record);
0781   // Emit a reference to a declaration if the declaration was emitted.
0782   void AddEmittedDeclRef(const Decl *D, RecordDataImpl &Record);
0783 
0784   /// Force a declaration to be emitted and get its local ID to the module file
0785   /// been writing.
0786   LocalDeclID GetDeclRef(const Decl *D);
0787 
0788   /// Determine the local declaration ID of an already-emitted
0789   /// declaration.
0790   LocalDeclID getDeclID(const Decl *D);
0791 
0792   /// Whether or not the declaration got emitted. If not, it wouldn't be
0793   /// emitted.
0794   ///
0795   /// This may only be called after we've done the job to write the
0796   /// declarations (marked by DoneWritingDeclsAndTypes).
0797   ///
0798   /// A declaration may only be omitted in reduced BMI.
0799   bool wasDeclEmitted(const Decl *D) const;
0800 
0801   unsigned getAnonymousDeclarationNumber(const NamedDecl *D);
0802 
0803   /// Add a string to the given record.
0804   void AddString(StringRef Str, RecordDataImpl &Record);
0805   void AddStringBlob(StringRef Str, RecordDataImpl &Record,
0806                      SmallVectorImpl<char> &Blob);
0807 
0808   /// Convert a path from this build process into one that is appropriate
0809   /// for emission in the module file.
0810   bool PreparePathForOutput(SmallVectorImpl<char> &Path);
0811 
0812   /// Add a path to the given record.
0813   void AddPath(StringRef Path, RecordDataImpl &Record);
0814   void AddPathBlob(StringRef Str, RecordDataImpl &Record,
0815                    SmallVectorImpl<char> &Blob);
0816 
0817   /// Emit the current record with the given path as a blob.
0818   void EmitRecordWithPath(unsigned Abbrev, RecordDataRef Record,
0819                           StringRef Path);
0820 
0821   /// Add a version tuple to the given record
0822   void AddVersionTuple(const VersionTuple &Version, RecordDataImpl &Record);
0823 
0824   /// Retrieve or create a submodule ID for this module, or return 0 if
0825   /// the submodule is neither local (a submodle of the currently-written module)
0826   /// nor from an imported module.
0827   unsigned getLocalOrImportedSubmoduleID(const Module *Mod);
0828 
0829   /// Note that the identifier II occurs at the given offset
0830   /// within the identifier table.
0831   void SetIdentifierOffset(const IdentifierInfo *II, uint32_t Offset);
0832 
0833   /// Note that the selector Sel occurs at the given offset
0834   /// within the method pool/selector table.
0835   void SetSelectorOffset(Selector Sel, uint32_t Offset);
0836 
0837   /// Record an ID for the given switch-case statement.
0838   unsigned RecordSwitchCaseID(SwitchCase *S);
0839 
0840   /// Retrieve the ID for the given switch-case statement.
0841   unsigned getSwitchCaseID(SwitchCase *S);
0842 
0843   void ClearSwitchCaseIDs();
0844 
0845   unsigned getTypeExtQualAbbrev() const {
0846     return TypeExtQualAbbrev;
0847   }
0848 
0849   unsigned getDeclParmVarAbbrev() const { return DeclParmVarAbbrev; }
0850   unsigned getDeclRecordAbbrev() const { return DeclRecordAbbrev; }
0851   unsigned getDeclTypedefAbbrev() const { return DeclTypedefAbbrev; }
0852   unsigned getDeclVarAbbrev() const { return DeclVarAbbrev; }
0853   unsigned getDeclFieldAbbrev() const { return DeclFieldAbbrev; }
0854   unsigned getDeclEnumAbbrev() const { return DeclEnumAbbrev; }
0855   unsigned getDeclObjCIvarAbbrev() const { return DeclObjCIvarAbbrev; }
0856   unsigned getDeclCXXMethodAbbrev(FunctionDecl::TemplatedKind Kind) const {
0857     switch (Kind) {
0858     case FunctionDecl::TK_NonTemplate:
0859       return DeclCXXMethodAbbrev;
0860     case FunctionDecl::TK_FunctionTemplate:
0861       return DeclTemplateCXXMethodAbbrev;
0862     case FunctionDecl::TK_MemberSpecialization:
0863       return DeclMemberSpecializedCXXMethodAbbrev;
0864     case FunctionDecl::TK_FunctionTemplateSpecialization:
0865       return DeclTemplateSpecializedCXXMethodAbbrev;
0866     case FunctionDecl::TK_DependentNonTemplate:
0867       return DeclDependentNonTemplateCXXMethodAbbrev;
0868     case FunctionDecl::TK_DependentFunctionTemplateSpecialization:
0869       return DeclDependentSpecializationCXXMethodAbbrev;
0870     }
0871     llvm_unreachable("Unknwon Template Kind!");
0872   }
0873   unsigned getDeclTemplateTypeParmAbbrev() const {
0874     return DeclTemplateTypeParmAbbrev;
0875   }
0876   unsigned getDeclUsingShadowAbbrev() const { return DeclUsingShadowAbbrev; }
0877 
0878   unsigned getDeclRefExprAbbrev() const { return DeclRefExprAbbrev; }
0879   unsigned getCharacterLiteralAbbrev() const { return CharacterLiteralAbbrev; }
0880   unsigned getIntegerLiteralAbbrev() const { return IntegerLiteralAbbrev; }
0881   unsigned getExprImplicitCastAbbrev() const { return ExprImplicitCastAbbrev; }
0882   unsigned getBinaryOperatorAbbrev() const { return BinaryOperatorAbbrev; }
0883   unsigned getCompoundAssignOperatorAbbrev() const {
0884     return CompoundAssignOperatorAbbrev;
0885   }
0886   unsigned getCallExprAbbrev() const { return CallExprAbbrev; }
0887   unsigned getCXXOperatorCallExprAbbrev() { return CXXOperatorCallExprAbbrev; }
0888   unsigned getCXXMemberCallExprAbbrev() { return CXXMemberCallExprAbbrev; }
0889 
0890   unsigned getCompoundStmtAbbrev() const { return CompoundStmtAbbrev; }
0891 
0892   bool hasChain() const { return Chain; }
0893   ASTReader *getChain() const { return Chain; }
0894 
0895   bool isWritingModule() const { return WritingModule; }
0896 
0897   bool isWritingStdCXXNamedModules() const {
0898     return WritingModule && WritingModule->isNamedModule();
0899   }
0900 
0901   bool isGeneratingReducedBMI() const { return GeneratingReducedBMI; }
0902 
0903   bool getDoneWritingDeclsAndTypes() const { return DoneWritingDeclsAndTypes; }
0904 
0905   bool isDeclPredefined(const Decl *D) const {
0906     return PredefinedDecls.count(D);
0907   }
0908 
0909   void handleVTable(CXXRecordDecl *RD);
0910 
0911 private:
0912   // ASTDeserializationListener implementation
0913   void ReaderInitialized(ASTReader *Reader) override;
0914   void IdentifierRead(serialization::IdentifierID ID, IdentifierInfo *II) override;
0915   void MacroRead(serialization::MacroID ID, MacroInfo *MI) override;
0916   void TypeRead(serialization::TypeIdx Idx, QualType T) override;
0917   void PredefinedDeclBuilt(PredefinedDeclIDs ID, const Decl *D) override;
0918   void SelectorRead(serialization::SelectorID ID, Selector Sel) override;
0919   void MacroDefinitionRead(serialization::PreprocessedEntityID ID,
0920                            MacroDefinitionRecord *MD) override;
0921   void ModuleRead(serialization::SubmoduleID ID, Module *Mod) override;
0922 
0923   // ASTMutationListener implementation.
0924   void CompletedTagDefinition(const TagDecl *D) override;
0925   void AddedVisibleDecl(const DeclContext *DC, const Decl *D) override;
0926   void AddedCXXImplicitMember(const CXXRecordDecl *RD, const Decl *D) override;
0927   void AddedCXXTemplateSpecialization(
0928       const ClassTemplateDecl *TD,
0929       const ClassTemplateSpecializationDecl *D) override;
0930   void AddedCXXTemplateSpecialization(
0931       const VarTemplateDecl *TD,
0932       const VarTemplateSpecializationDecl *D) override;
0933   void AddedCXXTemplateSpecialization(const FunctionTemplateDecl *TD,
0934                                       const FunctionDecl *D) override;
0935   void ResolvedExceptionSpec(const FunctionDecl *FD) override;
0936   void DeducedReturnType(const FunctionDecl *FD, QualType ReturnType) override;
0937   void ResolvedOperatorDelete(const CXXDestructorDecl *DD,
0938                               const FunctionDecl *Delete,
0939                               Expr *ThisArg) override;
0940   void CompletedImplicitDefinition(const FunctionDecl *D) override;
0941   void InstantiationRequested(const ValueDecl *D) override;
0942   void VariableDefinitionInstantiated(const VarDecl *D) override;
0943   void FunctionDefinitionInstantiated(const FunctionDecl *D) override;
0944   void DefaultArgumentInstantiated(const ParmVarDecl *D) override;
0945   void DefaultMemberInitializerInstantiated(const FieldDecl *D) override;
0946   void AddedObjCCategoryToInterface(const ObjCCategoryDecl *CatD,
0947                                     const ObjCInterfaceDecl *IFD) override;
0948   void DeclarationMarkedUsed(const Decl *D) override;
0949   void DeclarationMarkedOpenMPThreadPrivate(const Decl *D) override;
0950   void DeclarationMarkedOpenMPDeclareTarget(const Decl *D,
0951                                             const Attr *Attr) override;
0952   void DeclarationMarkedOpenMPAllocate(const Decl *D, const Attr *A) override;
0953   void RedefinedHiddenDefinition(const NamedDecl *D, Module *M) override;
0954   void AddedAttributeToRecord(const Attr *Attr,
0955                               const RecordDecl *Record) override;
0956   void EnteringModulePurview() override;
0957   void AddedManglingNumber(const Decl *D, unsigned) override;
0958   void AddedStaticLocalNumbers(const Decl *D, unsigned) override;
0959   void AddedAnonymousNamespace(const TranslationUnitDecl *,
0960                                NamespaceDecl *AnonNamespace) override;
0961 };
0962 
0963 /// AST and semantic-analysis consumer that generates a
0964 /// precompiled header from the parsed source code.
0965 class PCHGenerator : public SemaConsumer {
0966   void anchor() override;
0967 
0968   Preprocessor &PP;
0969   llvm::PointerUnion<Sema *, Preprocessor *> Subject;
0970   std::string OutputFile;
0971   std::string isysroot;
0972   std::shared_ptr<PCHBuffer> Buffer;
0973   llvm::BitstreamWriter Stream;
0974   ASTWriter Writer;
0975   bool AllowASTWithErrors;
0976   bool ShouldCacheASTInMemory;
0977 
0978 protected:
0979   ASTWriter &getWriter() { return Writer; }
0980   const ASTWriter &getWriter() const { return Writer; }
0981   SmallVectorImpl<char> &getPCH() const { return Buffer->Data; }
0982 
0983   bool isComplete() const { return Buffer->IsComplete; }
0984   PCHBuffer *getBufferPtr() { return Buffer.get(); }
0985   StringRef getOutputFile() const { return OutputFile; }
0986   DiagnosticsEngine &getDiagnostics() const;
0987   Preprocessor &getPreprocessor() { return PP; }
0988 
0989   virtual Module *getEmittingModule(ASTContext &Ctx);
0990 
0991 public:
0992   PCHGenerator(Preprocessor &PP, InMemoryModuleCache &ModuleCache,
0993                StringRef OutputFile, StringRef isysroot,
0994                std::shared_ptr<PCHBuffer> Buffer,
0995                ArrayRef<std::shared_ptr<ModuleFileExtension>> Extensions,
0996                bool AllowASTWithErrors = false, bool IncludeTimestamps = true,
0997                bool BuildingImplicitModule = false,
0998                bool ShouldCacheASTInMemory = false,
0999                bool GeneratingReducedBMI = false);
1000   ~PCHGenerator() override;
1001 
1002   void InitializeSema(Sema &S) override;
1003   void HandleTranslationUnit(ASTContext &Ctx) override;
1004   void HandleVTable(CXXRecordDecl *RD) override { Writer.handleVTable(RD); }
1005   ASTMutationListener *GetASTMutationListener() override;
1006   ASTDeserializationListener *GetASTDeserializationListener() override;
1007   bool hasEmittedPCH() const { return Buffer->IsComplete; }
1008 };
1009 
1010 class CXX20ModulesGenerator : public PCHGenerator {
1011   void anchor() override;
1012 
1013 protected:
1014   virtual Module *getEmittingModule(ASTContext &Ctx) override;
1015 
1016   CXX20ModulesGenerator(Preprocessor &PP, InMemoryModuleCache &ModuleCache,
1017                         StringRef OutputFile, bool GeneratingReducedBMI,
1018                         bool AllowASTWithErrors);
1019 
1020 public:
1021   CXX20ModulesGenerator(Preprocessor &PP, InMemoryModuleCache &ModuleCache,
1022                         StringRef OutputFile, bool AllowASTWithErrors = false)
1023       : CXX20ModulesGenerator(PP, ModuleCache, OutputFile,
1024                               /*GeneratingReducedBMI=*/false,
1025                               AllowASTWithErrors) {}
1026 
1027   void HandleTranslationUnit(ASTContext &Ctx) override;
1028 };
1029 
1030 class ReducedBMIGenerator : public CXX20ModulesGenerator {
1031   void anchor() override;
1032 
1033 public:
1034   ReducedBMIGenerator(Preprocessor &PP, InMemoryModuleCache &ModuleCache,
1035                       StringRef OutputFile, bool AllowASTWithErrors = false)
1036       : CXX20ModulesGenerator(PP, ModuleCache, OutputFile,
1037                               /*GeneratingReducedBMI=*/true,
1038                               AllowASTWithErrors) {}
1039 };
1040 
1041 /// If we can elide the definition of \param D in reduced BMI.
1042 ///
1043 /// Generally, we can elide the definition of a declaration if it won't affect
1044 /// the ABI. e.g., the non-inline function bodies.
1045 bool CanElideDeclDef(const Decl *D);
1046 
1047 /// A simple helper class to pack several bits in order into (a) 32 bit
1048 /// integer(s).
1049 class BitsPacker {
1050   constexpr static uint32_t BitIndexUpbound = 32u;
1051 
1052 public:
1053   BitsPacker() = default;
1054   BitsPacker(const BitsPacker &) = delete;
1055   BitsPacker(BitsPacker &&) = delete;
1056   BitsPacker operator=(const BitsPacker &) = delete;
1057   BitsPacker operator=(BitsPacker &&) = delete;
1058   ~BitsPacker() = default;
1059 
1060   bool canWriteNextNBits(uint32_t BitsWidth) const {
1061     return CurrentBitIndex + BitsWidth < BitIndexUpbound;
1062   }
1063 
1064   void reset(uint32_t Value) {
1065     UnderlyingValue = Value;
1066     CurrentBitIndex = 0;
1067   }
1068 
1069   void addBit(bool Value) { addBits(Value, 1); }
1070   void addBits(uint32_t Value, uint32_t BitsWidth) {
1071     assert(BitsWidth < BitIndexUpbound);
1072     assert((Value < (1u << BitsWidth)) && "Passing narrower bit width!");
1073     assert(canWriteNextNBits(BitsWidth) &&
1074            "Inserting too much bits into a value!");
1075 
1076     UnderlyingValue |= Value << CurrentBitIndex;
1077     CurrentBitIndex += BitsWidth;
1078   }
1079 
1080   operator uint32_t() { return UnderlyingValue; }
1081 
1082 private:
1083   uint32_t UnderlyingValue = 0;
1084   uint32_t CurrentBitIndex = 0;
1085 };
1086 
1087 } // namespace clang
1088 
1089 #endif // LLVM_CLANG_SERIALIZATION_ASTWRITER_H