17faa2ec03a7ef120ac165bb45b6c70a8b20c9f1cSebastian Redl//===--- ASTWriter.h - AST File Writer --------------------------*- C++ -*-===//
22cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor//
32cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor//                     The LLVM Compiler Infrastructure
42cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor//
52cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor// This file is distributed under the University of Illinois Open Source
62cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor// License. See LICENSE.TXT for details.
72cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor//
82cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor//===----------------------------------------------------------------------===//
92cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor//
103397c5570369f19b2d6c52e898f708d75ceede1fSebastian Redl//  This file defines the ASTWriter class, which writes an AST file
113397c5570369f19b2d6c52e898f708d75ceede1fSebastian Redl//  containing a serialized representation of a translation unit.
122cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor//
132cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor//===----------------------------------------------------------------------===//
14c43b54cbc10654ed59de797898042e1a05265246Sebastian Redl#ifndef LLVM_CLANG_FRONTEND_AST_WRITER_H
15c43b54cbc10654ed59de797898042e1a05265246Sebastian Redl#define LLVM_CLANG_FRONTEND_AST_WRITER_H
162cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor
1730a2e16f6c27f888dd11eba6bbbae1e980078fcbChandler Carruth#include "clang/AST/ASTMutationListener.h"
182cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor#include "clang/AST/Decl.h"
192cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor#include "clang/AST/DeclarationName.h"
2044f8c37e378f716e8cbb600e3800f437cf58f9e5Argyrios Kyrtzidis#include "clang/AST/TemplateBase.h"
2130a2e16f6c27f888dd11eba6bbbae1e980078fcbChandler Carruth#include "clang/Sema/SemaConsumer.h"
2205a07605322dfef2b017781042043a261c5a89cdSebastian Redl#include "clang/Serialization/ASTBitCodes.h"
236ab7cd853e9c15cf986a8a7c3db1f8d20e275409Sebastian Redl#include "clang/Serialization/ASTDeserializationListener.h"
2489d9980bbc2e4a4ac86673e6ec16fb9f5babb63bDouglas Gregor#include "llvm/ADT/DenseMap.h"
25e6f0868a55aba2613e2d5dba3348aaf1064e6ddbArgyrios Kyrtzidis#include "llvm/ADT/DenseSet.h"
26a8235d6c4093cd38dcf742909651f867de62e55bDouglas Gregor#include "llvm/ADT/MapVector.h"
272171bf1caba4d4b9eeb6a91efac4300b41f38b07Douglas Gregor#include "llvm/ADT/SetVector.h"
2830a2e16f6c27f888dd11eba6bbbae1e980078fcbChandler Carruth#include "llvm/ADT/SmallPtrSet.h"
2930a2e16f6c27f888dd11eba6bbbae1e980078fcbChandler Carruth#include "llvm/ADT/SmallVector.h"
301d715ac14bf440664fb0d1425ea882274f994f57Douglas Gregor#include "llvm/Bitcode/BitstreamWriter.h"
31025452fa0eda63e150cfaeebe64f0a19c96b3a06Douglas Gregor#include <map>
322cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor#include <queue>
331d715ac14bf440664fb0d1425ea882274f994f57Douglas Gregor#include <vector>
342cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor
352cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregornamespace llvm {
3617fc223395d51be582fc666bb6ea21bd1dff26dcDouglas Gregor  class APFloat;
372cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor  class APInt;
382cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor  class BitstreamWriter;
392cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor}
402cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor
412cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregornamespace clang {
422cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor
430b1fb988012da21d996c43e36867787a7a07b889Chris Lattnerclass ASTContext;
446ad9ac097918fbdeb443ea7b99d4db9e49b28534Chris Lattnerclass NestedNameSpecifier;
456ad9ac097918fbdeb443ea7b99d4db9e49b28534Chris Lattnerclass CXXBaseSpecifier;
46cbb67480094b3bcb5b715acd827cbad55e2a204cSean Huntclass CXXCtorInitializer;
47a930dc9b46572cb6e5bb54f3d724e8fe23a6b66eDouglas Gregorclass FileEntry;
4884bccea1ad9fd8bc1f4ec3d1fc5dd8d15dabffbcPeter Collingbourneclass FPOptions;
49cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregorclass HeaderSearch;
504a18c3b25a2d7eb7f770ce91ee5e14433b2a1cb6Douglas Gregorclass HeaderSearchOptions;
51eee242ff426bf79149f221798966e58688383c1eDouglas Gregorclass IdentifierResolver;
526a5a23f8e7fb65e028c8092bc1d1a1d9dfe2e9bcDouglas Gregorclass MacroDefinition;
539317ab94bb68122ba6fc728eb73c1308fb913cd1Argyrios Kyrtzidisclass MacroDirective;
549317ab94bb68122ba6fc728eb73c1308fb913cd1Argyrios Kyrtzidisclass MacroInfo;
5556ca35d396d8692c384c785f9aeebcf22563fe1eJohn McCallclass OpaqueValueExpr;
5684bccea1ad9fd8bc1f4ec3d1fc5dd8d15dabffbcPeter Collingbourneclass OpenCLOptions;
57c43b54cbc10654ed59de797898042e1a05265246Sebastian Redlclass ASTReader;
581a4761edca58c6b559de825b9abfb66f7f1ba94aDouglas Gregorclass Module;
5989d9980bbc2e4a4ac86673e6ec16fb9f5babb63bDouglas Gregorclass PreprocessedEntity;
604800a5c79023271408af49797e09be32aca93232Douglas Gregorclass PreprocessingRecord;
612bec0410d268779f601bd509e0302a500af7ac6aDouglas Gregorclass Preprocessor;
62e7785040107266d01ebdcc066365f70b7ace371fDouglas Gregorclass Sema;
632bec0410d268779f601bd509e0302a500af7ac6aDouglas Gregorclass SourceManager;
64025452fa0eda63e150cfaeebe64f0a19c96b3a06Douglas Gregorclass SwitchCase;
652bec0410d268779f601bd509e0302a500af7ac6aDouglas Gregorclass TargetInfo;
66aeeacf725c9e0ddd64ea9764bd008e5b6873ce51John McCallclass Token;
670a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregorclass VersionTuple;
682a82ca255b0f99f6201a75ed52b91fc024f6e9cfArgyrios Kyrtzidisclass ASTUnresolvedSet;
692cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor
7010f3df54486385e6497c9e5f229ff816e5a6c511Argyrios Kyrtzidisnamespace SrcMgr { class SLocEntry; }
7110f3df54486385e6497c9e5f229ff816e5a6c511Argyrios Kyrtzidis
72a4232eb646d89e7d52424bb42eb87d9061f39e63Sebastian Redl/// \brief Writes an AST file containing the contents of a translation unit.
732cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor///
74a4232eb646d89e7d52424bb42eb87d9061f39e63Sebastian Redl/// The ASTWriter class produces a bitstream containing the serialized
752cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor/// representation of a given abstract syntax tree and its supporting
762cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor/// data structures. This bitstream can be de-serialized via an
77c43b54cbc10654ed59de797898042e1a05265246Sebastian Redl/// instance of the ASTReader class.
787b90340c9c7d07aef4e301e72b5e8a30d5f4f0c8Argyrios Kyrtzidisclass ASTWriter : public ASTDeserializationListener,
797b90340c9c7d07aef4e301e72b5e8a30d5f4f0c8Argyrios Kyrtzidis                  public ASTMutationListener {
800b7489194f9f89fac39d57211c1e7953ae50251fDouglas Gregorpublic:
81686775deca8b8685eb90801495880e3abdd844c2Chris Lattner  typedef SmallVector<uint64_t, 64> RecordData;
82686775deca8b8685eb90801495880e3abdd844c2Chris Lattner  typedef SmallVectorImpl<uint64_t> RecordDataImpl;
830b7489194f9f89fac39d57211c1e7953ae50251fDouglas Gregor
843397c5570369f19b2d6c52e898f708d75ceede1fSebastian Redl  friend class ASTDeclWriter;
85534986f2b21e6050bf00163cd6423fd92155a6edRichard Smith  friend class ASTStmtWriter;
860b7489194f9f89fac39d57211c1e7953ae50251fDouglas Gregorprivate:
87e36050111e2bdb7efc014af9dd7f0009b492ac36Douglas Gregor  /// \brief Map that provides the ID numbers of each type within the
88e36050111e2bdb7efc014af9dd7f0009b492ac36Douglas Gregor  /// output stream, plus those deserialized from a chained PCH.
89e36050111e2bdb7efc014af9dd7f0009b492ac36Douglas Gregor  ///
90e36050111e2bdb7efc014af9dd7f0009b492ac36Douglas Gregor  /// The ID numbers of types are consecutive (in order of discovery)
91e36050111e2bdb7efc014af9dd7f0009b492ac36Douglas Gregor  /// and start at 1. 0 is reserved for NULL. When types are actually
92e36050111e2bdb7efc014af9dd7f0009b492ac36Douglas Gregor  /// stored in the stream, the ID number is shifted by 2 bits to
93e36050111e2bdb7efc014af9dd7f0009b492ac36Douglas Gregor  /// allow for the const/volatile qualifiers.
94e36050111e2bdb7efc014af9dd7f0009b492ac36Douglas Gregor  ///
95e36050111e2bdb7efc014af9dd7f0009b492ac36Douglas Gregor  /// Keys in the map never have const/volatile qualifiers.
96ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie  typedef llvm::DenseMap<QualType, serialization::TypeIdx,
97e36050111e2bdb7efc014af9dd7f0009b492ac36Douglas Gregor                         serialization::UnsafeQualTypeDenseMapInfo>
98e36050111e2bdb7efc014af9dd7f0009b492ac36Douglas Gregor    TypeIdxMap;
99e36050111e2bdb7efc014af9dd7f0009b492ac36Douglas Gregor
1002cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor  /// \brief The bitstream writer used to emit this precompiled header.
101c9490c000f515c29f200a1215328d8ab9a0f3818Douglas Gregor  llvm::BitstreamWriter &Stream;
1022cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor
1033b8043b49aff6e5d70f29ef5684214ce2473763cDouglas Gregor  /// \brief The ASTContext we're writing.
1043b8043b49aff6e5d70f29ef5684214ce2473763cDouglas Gregor  ASTContext *Context;
105ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie
106185dbd7782a45d0f830218bfbc196c6b664ed8d9Douglas Gregor  /// \brief The preprocessor we're writing.
107185dbd7782a45d0f830218bfbc196c6b664ed8d9Douglas Gregor  Preprocessor *PP;
108185dbd7782a45d0f830218bfbc196c6b664ed8d9Douglas Gregor
109c43b54cbc10654ed59de797898042e1a05265246Sebastian Redl  /// \brief The reader of existing AST files, if we're chaining.
110c43b54cbc10654ed59de797898042e1a05265246Sebastian Redl  ASTReader *Chain;
111ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie
112e209e5026892cb07294f733c72bd51359c0f0e72Douglas Gregor  /// \brief The module we're currently writing, if any.
113e209e5026892cb07294f733c72bd51359c0f0e72Douglas Gregor  Module *WritingModule;
114e209e5026892cb07294f733c72bd51359c0f0e72Douglas Gregor
115ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie  /// \brief Indicates when the AST writing is actively performing
11661c5e340c26971d195bd27232e7f2e71be24bb52Douglas Gregor  /// serialization, rather than just queueing updates.
11761c5e340c26971d195bd27232e7f2e71be24bb52Douglas Gregor  bool WritingAST;
118ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie
1197518b3784ed2176aad8dcabe0685c6e02c5f1043Argyrios Kyrtzidis  /// \brief Indicates that we are done serializing the collection of decls
1207518b3784ed2176aad8dcabe0685c6e02c5f1043Argyrios Kyrtzidis  /// and types to emit.
1217518b3784ed2176aad8dcabe0685c6e02c5f1043Argyrios Kyrtzidis  bool DoneWritingDeclsAndTypes;
1227518b3784ed2176aad8dcabe0685c6e02c5f1043Argyrios Kyrtzidis
123bef35c91b594f66216f4aab303b71a6c5ab7abcfArgyrios Kyrtzidis  /// \brief Indicates that the AST contained compiler errors.
124bef35c91b594f66216f4aab303b71a6c5ab7abcfArgyrios Kyrtzidis  bool ASTHasCompilerErrors;
125bef35c91b594f66216f4aab303b71a6c5ab7abcfArgyrios Kyrtzidis
126a930dc9b46572cb6e5bb54f3d724e8fe23a6b66eDouglas Gregor  /// \brief Mapping from input file entries to the index into the
127a930dc9b46572cb6e5bb54f3d724e8fe23a6b66eDouglas Gregor  /// offset table where information about that input file is stored.
128a930dc9b46572cb6e5bb54f3d724e8fe23a6b66eDouglas Gregor  llvm::DenseMap<const FileEntry *, uint32_t> InputFileIDs;
129a930dc9b46572cb6e5bb54f3d724e8fe23a6b66eDouglas Gregor
1303397c5570369f19b2d6c52e898f708d75ceede1fSebastian Redl  /// \brief Stores a declaration or a type to be written to the AST file.
13161d60ee6aa0a5ded0ddcf48679673b37506a1895Douglas Gregor  class DeclOrType {
13261d60ee6aa0a5ded0ddcf48679673b37506a1895Douglas Gregor  public:
13361d60ee6aa0a5ded0ddcf48679673b37506a1895Douglas Gregor    DeclOrType(Decl *D) : Stored(D), IsType(false) { }
13461d60ee6aa0a5ded0ddcf48679673b37506a1895Douglas Gregor    DeclOrType(QualType T) : Stored(T.getAsOpaquePtr()), IsType(true) { }
135ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie
13661d60ee6aa0a5ded0ddcf48679673b37506a1895Douglas Gregor    bool isType() const { return IsType; }
13761d60ee6aa0a5ded0ddcf48679673b37506a1895Douglas Gregor    bool isDecl() const { return !IsType; }
138ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie
13961d60ee6aa0a5ded0ddcf48679673b37506a1895Douglas Gregor    QualType getType() const {
14061d60ee6aa0a5ded0ddcf48679673b37506a1895Douglas Gregor      assert(isType() && "Not a type!");
14161d60ee6aa0a5ded0ddcf48679673b37506a1895Douglas Gregor      return QualType::getFromOpaquePtr(Stored);
14261d60ee6aa0a5ded0ddcf48679673b37506a1895Douglas Gregor    }
143ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie
14461d60ee6aa0a5ded0ddcf48679673b37506a1895Douglas Gregor    Decl *getDecl() const {
14561d60ee6aa0a5ded0ddcf48679673b37506a1895Douglas Gregor      assert(isDecl() && "Not a decl!");
14661d60ee6aa0a5ded0ddcf48679673b37506a1895Douglas Gregor      return static_cast<Decl *>(Stored);
14761d60ee6aa0a5ded0ddcf48679673b37506a1895Douglas Gregor    }
148ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie
14961d60ee6aa0a5ded0ddcf48679673b37506a1895Douglas Gregor  private:
15061d60ee6aa0a5ded0ddcf48679673b37506a1895Douglas Gregor    void *Stored;
15161d60ee6aa0a5ded0ddcf48679673b37506a1895Douglas Gregor    bool IsType;
15261d60ee6aa0a5ded0ddcf48679673b37506a1895Douglas Gregor  };
1531476ed40ef6ef144937821da888c7e4d9ea0acd7Sebastian Redl
15461d60ee6aa0a5ded0ddcf48679673b37506a1895Douglas Gregor  /// \brief The declarations and types to emit.
15561d60ee6aa0a5ded0ddcf48679673b37506a1895Douglas Gregor  std::queue<DeclOrType> DeclTypesToEmit;
1561476ed40ef6ef144937821da888c7e4d9ea0acd7Sebastian Redl
1571476ed40ef6ef144937821da888c7e4d9ea0acd7Sebastian Redl  /// \brief The first ID number we can use for our own declarations.
1588538e8d43a3a9bd439c987c0de37bcbf035dd391Sebastian Redl  serialization::DeclID FirstDeclID;
1591476ed40ef6ef144937821da888c7e4d9ea0acd7Sebastian Redl
160f2f0f03d08c6143137a79a8edffc7d41823bc3c7Sebastian Redl  /// \brief The decl ID that will be assigned to the next new decl.
1618538e8d43a3a9bd439c987c0de37bcbf035dd391Sebastian Redl  serialization::DeclID NextDeclID;
162f2f0f03d08c6143137a79a8edffc7d41823bc3c7Sebastian Redl
1632cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor  /// \brief Map that provides the ID numbers of each declaration within
1641476ed40ef6ef144937821da888c7e4d9ea0acd7Sebastian Redl  /// the output stream, as well as those deserialized from a chained PCH.
1652cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor  ///
1662cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor  /// The ID numbers of declarations are consecutive (in order of
1672cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor  /// discovery) and start at 2. 1 is reserved for the translation
1682cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor  /// unit, while 0 is reserved for NULL.
1698538e8d43a3a9bd439c987c0de37bcbf035dd391Sebastian Redl  llvm::DenseMap<const Decl *, serialization::DeclID> DeclIDs;
1702cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor
1712cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor  /// \brief Offset of each declaration in the bitstream, indexed by
1722cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor  /// the declaration's ID.
1739d31fa75bc05fe4cb903a7701550f22cfb73ea8bArgyrios Kyrtzidis  std::vector<serialization::DeclOffset> DeclOffsets;
1742cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor
175fab8d5b478e6fb112b4414c4698a7cc2a350b0f0Argyrios Kyrtzidis  /// \brief Sorted (by file offset) vector of pairs of file offset/DeclID.
17610f3df54486385e6497c9e5f229ff816e5a6c511Argyrios Kyrtzidis  typedef SmallVector<std::pair<unsigned, serialization::DeclID>, 64>
17710f3df54486385e6497c9e5f229ff816e5a6c511Argyrios Kyrtzidis    LocDeclIDsTy;
17810f3df54486385e6497c9e5f229ff816e5a6c511Argyrios Kyrtzidis  struct DeclIDInFileInfo {
17910f3df54486385e6497c9e5f229ff816e5a6c511Argyrios Kyrtzidis    LocDeclIDsTy DeclIDs;
18010f3df54486385e6497c9e5f229ff816e5a6c511Argyrios Kyrtzidis    /// \brief Set when the DeclIDs vectors from all files are joined, this
18110f3df54486385e6497c9e5f229ff816e5a6c511Argyrios Kyrtzidis    /// indicates the index that this particular vector has in the global one.
18210f3df54486385e6497c9e5f229ff816e5a6c511Argyrios Kyrtzidis    unsigned FirstDeclIndex;
18310f3df54486385e6497c9e5f229ff816e5a6c511Argyrios Kyrtzidis  };
184a2ea4d94f2133aad0d864cf1327af142a47ffb09Argyrios Kyrtzidis  typedef llvm::DenseMap<FileID, DeclIDInFileInfo *> FileDeclIDsTy;
18510f3df54486385e6497c9e5f229ff816e5a6c511Argyrios Kyrtzidis
18610f3df54486385e6497c9e5f229ff816e5a6c511Argyrios Kyrtzidis  /// \brief Map from file SLocEntries to info about the file-level declarations
18710f3df54486385e6497c9e5f229ff816e5a6c511Argyrios Kyrtzidis  /// that it contains.
18810f3df54486385e6497c9e5f229ff816e5a6c511Argyrios Kyrtzidis  FileDeclIDsTy FileDeclIDs;
18910f3df54486385e6497c9e5f229ff816e5a6c511Argyrios Kyrtzidis
19019645d2ae928580b62f9feff91c5aa5e19f5f20dArgyrios Kyrtzidis  void associateDeclWithFile(const Decl *D, serialization::DeclID);
19110f3df54486385e6497c9e5f229ff816e5a6c511Argyrios Kyrtzidis
1921476ed40ef6ef144937821da888c7e4d9ea0acd7Sebastian Redl  /// \brief The first ID number we can use for our own types.
1938538e8d43a3a9bd439c987c0de37bcbf035dd391Sebastian Redl  serialization::TypeID FirstTypeID;
1941476ed40ef6ef144937821da888c7e4d9ea0acd7Sebastian Redl
195f2f0f03d08c6143137a79a8edffc7d41823bc3c7Sebastian Redl  /// \brief The type ID that will be assigned to the next new type.
1968538e8d43a3a9bd439c987c0de37bcbf035dd391Sebastian Redl  serialization::TypeID NextTypeID;
197f2f0f03d08c6143137a79a8edffc7d41823bc3c7Sebastian Redl
1982cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor  /// \brief Map that provides the ID numbers of each type within the
1991476ed40ef6ef144937821da888c7e4d9ea0acd7Sebastian Redl  /// output stream, plus those deserialized from a chained PCH.
2002cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor  ///
2012cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor  /// The ID numbers of types are consecutive (in order of discovery)
2022cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor  /// and start at 1. 0 is reserved for NULL. When types are actually
2030953e767ff7817f97b3ab20896b229891eeff45bJohn McCall  /// stored in the stream, the ID number is shifted by 2 bits to
2040953e767ff7817f97b3ab20896b229891eeff45bJohn McCall  /// allow for the const/volatile qualifiers.
2050953e767ff7817f97b3ab20896b229891eeff45bJohn McCall  ///
2060953e767ff7817f97b3ab20896b229891eeff45bJohn McCall  /// Keys in the map never have const/volatile qualifiers.
207e36050111e2bdb7efc014af9dd7f0009b492ac36Douglas Gregor  TypeIdxMap TypeIdxs;
2082cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor
2092cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor  /// \brief Offset of each type in the bitstream, indexed by
2102cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor  /// the type's ID.
211c732f5a4ae13a75b5dfa8f640a50f94db2d3092cChris Lattner  std::vector<uint32_t> TypeOffsets;
2122cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor
213f2f0f03d08c6143137a79a8edffc7d41823bc3c7Sebastian Redl  /// \brief The first ID number we can use for our own identifiers.
2148538e8d43a3a9bd439c987c0de37bcbf035dd391Sebastian Redl  serialization::IdentID FirstIdentID;
215f2f0f03d08c6143137a79a8edffc7d41823bc3c7Sebastian Redl
216f2f0f03d08c6143137a79a8edffc7d41823bc3c7Sebastian Redl  /// \brief The identifier ID that will be assigned to the next new identifier.
2178538e8d43a3a9bd439c987c0de37bcbf035dd391Sebastian Redl  serialization::IdentID NextIdentID;
2182cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor
219afaf308b779cd8e8fc8c42601b9f383423c15c2dDouglas Gregor  /// \brief Map that provides the ID numbers of each identifier in
220afaf308b779cd8e8fc8c42601b9f383423c15c2dDouglas Gregor  /// the output stream.
221afaf308b779cd8e8fc8c42601b9f383423c15c2dDouglas Gregor  ///
222afaf308b779cd8e8fc8c42601b9f383423c15c2dDouglas Gregor  /// The ID numbers for identifiers are consecutive (in order of
223afaf308b779cd8e8fc8c42601b9f383423c15c2dDouglas Gregor  /// discovery), starting at 1. An ID of zero refers to a NULL
224afaf308b779cd8e8fc8c42601b9f383423c15c2dDouglas Gregor  /// IdentifierInfo.
2258538e8d43a3a9bd439c987c0de37bcbf035dd391Sebastian Redl  llvm::DenseMap<const IdentifierInfo *, serialization::IdentID> IdentifierIDs;
2261eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
227a8235d6c4093cd38dcf742909651f867de62e55bDouglas Gregor  /// \brief The first ID number we can use for our own macros.
228a8235d6c4093cd38dcf742909651f867de62e55bDouglas Gregor  serialization::MacroID FirstMacroID;
229a8235d6c4093cd38dcf742909651f867de62e55bDouglas Gregor
230a8235d6c4093cd38dcf742909651f867de62e55bDouglas Gregor  /// \brief The identifier ID that will be assigned to the next new identifier.
231a8235d6c4093cd38dcf742909651f867de62e55bDouglas Gregor  serialization::MacroID NextMacroID;
232a8235d6c4093cd38dcf742909651f867de62e55bDouglas Gregor
233a8235d6c4093cd38dcf742909651f867de62e55bDouglas Gregor  /// \brief Map that provides the ID numbers of each macro.
2349317ab94bb68122ba6fc728eb73c1308fb913cd1Argyrios Kyrtzidis  llvm::DenseMap<MacroInfo *, serialization::MacroID> MacroIDs;
2359317ab94bb68122ba6fc728eb73c1308fb913cd1Argyrios Kyrtzidis
2369317ab94bb68122ba6fc728eb73c1308fb913cd1Argyrios Kyrtzidis  struct MacroInfoToEmitData {
2379317ab94bb68122ba6fc728eb73c1308fb913cd1Argyrios Kyrtzidis    const IdentifierInfo *Name;
2389317ab94bb68122ba6fc728eb73c1308fb913cd1Argyrios Kyrtzidis    MacroInfo *MI;
2399317ab94bb68122ba6fc728eb73c1308fb913cd1Argyrios Kyrtzidis    serialization::MacroID ID;
2409317ab94bb68122ba6fc728eb73c1308fb913cd1Argyrios Kyrtzidis  };
2419317ab94bb68122ba6fc728eb73c1308fb913cd1Argyrios Kyrtzidis  /// \brief The macro infos to emit.
2429317ab94bb68122ba6fc728eb73c1308fb913cd1Argyrios Kyrtzidis  std::vector<MacroInfoToEmitData> MacroInfosToEmit;
2439317ab94bb68122ba6fc728eb73c1308fb913cd1Argyrios Kyrtzidis
2449317ab94bb68122ba6fc728eb73c1308fb913cd1Argyrios Kyrtzidis  llvm::DenseMap<const IdentifierInfo *, uint64_t> IdentMacroDirectivesOffsetMap;
245a8235d6c4093cd38dcf742909651f867de62e55bDouglas Gregor
246c52d9057241b7857c8400ab6cfee0a1c554e0982Daniel Dunbar  /// @name FlushStmt Caches
247c52d9057241b7857c8400ab6cfee0a1c554e0982Daniel Dunbar  /// @{
248c52d9057241b7857c8400ab6cfee0a1c554e0982Daniel Dunbar
249651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  /// \brief Set of parent Stmts for the currently serializing sub-stmt.
250c52d9057241b7857c8400ab6cfee0a1c554e0982Daniel Dunbar  llvm::DenseSet<Stmt *> ParentStmts;
251c52d9057241b7857c8400ab6cfee0a1c554e0982Daniel Dunbar
252651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  /// \brief Offsets of sub-stmts already serialized. The offset points
253c52d9057241b7857c8400ab6cfee0a1c554e0982Daniel Dunbar  /// just after the stmt record.
254c52d9057241b7857c8400ab6cfee0a1c554e0982Daniel Dunbar  llvm::DenseMap<Stmt *, uint64_t> SubStmtEntries;
255c52d9057241b7857c8400ab6cfee0a1c554e0982Daniel Dunbar
256c52d9057241b7857c8400ab6cfee0a1c554e0982Daniel Dunbar  /// @}
257c52d9057241b7857c8400ab6cfee0a1c554e0982Daniel Dunbar
2583251ceb90b3fec68e86d6dcfa58836e20a7205c3Douglas Gregor  /// \brief Offsets of each of the identifier IDs into the identifier
2592b3a5a83ea30bde7fa8f9d8e9a0cb12623759bfbDouglas Gregor  /// table.
2602b3a5a83ea30bde7fa8f9d8e9a0cb12623759bfbDouglas Gregor  std::vector<uint32_t> IdentifierOffsets;
261e58aa890e8de55bb3146e6ea9fbbba3a58ce30c6Sebastian Redl
26226ced127b7d443fcf3472463c9f39c2376bd9d70Douglas Gregor  /// \brief The first ID number we can use for our own submodules.
26326ced127b7d443fcf3472463c9f39c2376bd9d70Douglas Gregor  serialization::SubmoduleID FirstSubmoduleID;
26426ced127b7d443fcf3472463c9f39c2376bd9d70Douglas Gregor
26526ced127b7d443fcf3472463c9f39c2376bd9d70Douglas Gregor  /// \brief The submodule ID that will be assigned to the next new submodule.
26626ced127b7d443fcf3472463c9f39c2376bd9d70Douglas Gregor  serialization::SubmoduleID NextSubmoduleID;
26726ced127b7d443fcf3472463c9f39c2376bd9d70Douglas Gregor
268e58aa890e8de55bb3146e6ea9fbbba3a58ce30c6Sebastian Redl  /// \brief The first ID number we can use for our own selectors.
2698538e8d43a3a9bd439c987c0de37bcbf035dd391Sebastian Redl  serialization::SelectorID FirstSelectorID;
270e58aa890e8de55bb3146e6ea9fbbba3a58ce30c6Sebastian Redl
27126ced127b7d443fcf3472463c9f39c2376bd9d70Douglas Gregor  /// \brief The selector ID that will be assigned to the next new selector.
2728538e8d43a3a9bd439c987c0de37bcbf035dd391Sebastian Redl  serialization::SelectorID NextSelectorID;
2733251ceb90b3fec68e86d6dcfa58836e20a7205c3Douglas Gregor
27490cd1bb1baac2a0221f3642de0cbea3244b116e5Steve Naroff  /// \brief Map that provides the ID numbers of each Selector.
2758538e8d43a3a9bd439c987c0de37bcbf035dd391Sebastian Redl  llvm::DenseMap<Selector, serialization::SelectorID> SelectorIDs;
2761eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
27783941df2745d69c05acee3174c7a265c206f70d9Douglas Gregor  /// \brief Offset of each selector within the method pool/selector
27883941df2745d69c05acee3174c7a265c206f70d9Douglas Gregor  /// table, indexed by the Selector ID (-1).
2792b3a5a83ea30bde7fa8f9d8e9a0cb12623759bfbDouglas Gregor  std::vector<uint32_t> SelectorOffsets;
280ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie
2816a5a23f8e7fb65e028c8092bc1d1a1d9dfe2e9bcDouglas Gregor  /// \brief Mapping from macro definitions (as they occur in the preprocessing
282f73c93fea0d4b447585bc7459499ba6b822e045cSebastian Redl  /// record) to the macro IDs.
283e24692b30adbe8144597678a0e3354912e99c747Argyrios Kyrtzidis  llvm::DenseMap<const MacroDefinition *, serialization::PreprocessedEntityID>
2848538e8d43a3a9bd439c987c0de37bcbf035dd391Sebastian Redl      MacroDefinitions;
285a865005c74019184e04f7fcdd4d61c31c095a4ffArgyrios Kyrtzidis
286651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  /// An update to a Decl.
287651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  class DeclUpdate {
288651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    /// A DeclUpdateKind.
289651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    unsigned Kind;
290651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    union {
291651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      const Decl *Dcl;
292651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      void *Type;
293651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      unsigned Loc;
294651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      unsigned Val;
295651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    };
296651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
297651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  public:
2986bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    DeclUpdate(unsigned Kind) : Kind(Kind), Dcl(nullptr) {}
299651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    DeclUpdate(unsigned Kind, const Decl *Dcl) : Kind(Kind), Dcl(Dcl) {}
300651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    DeclUpdate(unsigned Kind, QualType Type)
301651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines        : Kind(Kind), Type(Type.getAsOpaquePtr()) {}
302651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    DeclUpdate(unsigned Kind, SourceLocation Loc)
303651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines        : Kind(Kind), Loc(Loc.getRawEncoding()) {}
304651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    DeclUpdate(unsigned Kind, unsigned Val)
305651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines        : Kind(Kind), Val(Val) {}
306651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
307651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    unsigned getKind() const { return Kind; }
308651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    const Decl *getDecl() const { return Dcl; }
309651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    QualType getType() const { return QualType::getFromOpaquePtr(Type); }
310651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    SourceLocation getLoc() const {
311651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      return SourceLocation::getFromRawEncoding(Loc);
312651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    }
313651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    unsigned getNumber() const { return Val; }
314651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  };
315651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
316651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  typedef SmallVector<DeclUpdate, 1> UpdateRecord;
3177b90340c9c7d07aef4e301e72b5e8a30d5f4f0c8Argyrios Kyrtzidis  typedef llvm::DenseMap<const Decl *, UpdateRecord> DeclUpdateMap;
3187b90340c9c7d07aef4e301e72b5e8a30d5f4f0c8Argyrios Kyrtzidis  /// \brief Mapping from declarations that came from a chained PCH to the
3197b90340c9c7d07aef4e301e72b5e8a30d5f4f0c8Argyrios Kyrtzidis  /// record containing modifications to them.
3207b90340c9c7d07aef4e301e72b5e8a30d5f4f0c8Argyrios Kyrtzidis  DeclUpdateMap DeclUpdates;
3217b90340c9c7d07aef4e301e72b5e8a30d5f4f0c8Argyrios Kyrtzidis
322a865005c74019184e04f7fcdd4d61c31c095a4ffArgyrios Kyrtzidis  typedef llvm::DenseMap<Decl *, Decl *> FirstLatestDeclMap;
323a865005c74019184e04f7fcdd4d61c31c095a4ffArgyrios Kyrtzidis  /// \brief Map of first declarations from a chained PCH that point to the
324a865005c74019184e04f7fcdd4d61c31c095a4ffArgyrios Kyrtzidis  /// most recent declarations in another PCH.
325a865005c74019184e04f7fcdd4d61c31c095a4ffArgyrios Kyrtzidis  FirstLatestDeclMap FirstLatestDecls;
326ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie
327fdd0172ca1b3c837f8c2b37d69cc2085234e09faDouglas Gregor  /// \brief Declarations encountered that might be external
328fdd0172ca1b3c837f8c2b37d69cc2085234e09faDouglas Gregor  /// definitions.
329fdd0172ca1b3c837f8c2b37d69cc2085234e09faDouglas Gregor  ///
330651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  /// We keep track of external definitions and other 'interesting' declarations
331651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  /// as we are emitting declarations to the AST file. The AST file contains a
332651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  /// separate record for these declarations, which are provided to the AST
333651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  /// consumer by the AST reader. This is behavior is required to properly cope with,
334fdd0172ca1b3c837f8c2b37d69cc2085234e09faDouglas Gregor  /// e.g., tentative variable definitions that occur within
335fdd0172ca1b3c837f8c2b37d69cc2085234e09faDouglas Gregor  /// headers. The declarations themselves are stored as declaration
336651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  /// IDs, since they will be written out to an EAGERLY_DESERIALIZED_DECLS
337fdd0172ca1b3c837f8c2b37d69cc2085234e09faDouglas Gregor  /// record.
338651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  SmallVector<uint64_t, 16> EagerlyDeserializedDecls;
339fdd0172ca1b3c837f8c2b37d69cc2085234e09faDouglas Gregor
340100050bf643bcfe2d06bdcef491e387171249260Argyrios Kyrtzidis  /// \brief DeclContexts that have received extensions since their serialized
3413397c5570369f19b2d6c52e898f708d75ceede1fSebastian Redl  /// form.
342a7be5065edc93ab52a25b2588a23a41a4beba21eSebastian Redl  ///
343ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie  /// For namespaces, when we're chaining and encountering a namespace, we check
344ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie  /// if its primary namespace comes from the chain. If it does, we add the
345ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie  /// primary to this set, so that we can write out lexical content updates for
346ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie  /// it.
347100050bf643bcfe2d06bdcef491e387171249260Argyrios Kyrtzidis  llvm::SmallPtrSet<const DeclContext *, 16> UpdatedDeclContexts;
348a7be5065edc93ab52a25b2588a23a41a4beba21eSebastian Redl
3497518b3784ed2176aad8dcabe0685c6e02c5f1043Argyrios Kyrtzidis  /// \brief Keeps track of visible decls that were added in DeclContexts
3507518b3784ed2176aad8dcabe0685c6e02c5f1043Argyrios Kyrtzidis  /// coming from another AST file.
3517518b3784ed2176aad8dcabe0685c6e02c5f1043Argyrios Kyrtzidis  SmallVector<const Decl *, 16> UpdatingVisibleDecls;
3527518b3784ed2176aad8dcabe0685c6e02c5f1043Argyrios Kyrtzidis
353ba901b507fc36408fe6f8478e8ac90b554f1d230Argyrios Kyrtzidis  typedef llvm::SmallPtrSet<const Decl *, 16> DeclsToRewriteTy;
354ba901b507fc36408fe6f8478e8ac90b554f1d230Argyrios Kyrtzidis  /// \brief Decls that will be replaced in the current dependent AST file.
355ba901b507fc36408fe6f8478e8ac90b554f1d230Argyrios Kyrtzidis  DeclsToRewriteTy DeclsToRewrite;
356ba901b507fc36408fe6f8478e8ac90b554f1d230Argyrios Kyrtzidis
357cff9f26ce0ed76d555cd33b3dca84dd5cdf376afDouglas Gregor  /// \brief The set of Objective-C class that have categories we
358cff9f26ce0ed76d555cd33b3dca84dd5cdf376afDouglas Gregor  /// should serialize.
359cff9f26ce0ed76d555cd33b3dca84dd5cdf376afDouglas Gregor  llvm::SetVector<ObjCInterfaceDecl *> ObjCClassesWithCategories;
360cff9f26ce0ed76d555cd33b3dca84dd5cdf376afDouglas Gregor
361ef23b6001e8d9715246ca23bd8c3a6887d7844cbArgyrios Kyrtzidis  struct ReplacedDeclInfo {
362ef23b6001e8d9715246ca23bd8c3a6887d7844cbArgyrios Kyrtzidis    serialization::DeclID ID;
363ef23b6001e8d9715246ca23bd8c3a6887d7844cbArgyrios Kyrtzidis    uint64_t Offset;
364ef23b6001e8d9715246ca23bd8c3a6887d7844cbArgyrios Kyrtzidis    unsigned Loc;
365ef23b6001e8d9715246ca23bd8c3a6887d7844cbArgyrios Kyrtzidis
366ef23b6001e8d9715246ca23bd8c3a6887d7844cbArgyrios Kyrtzidis    ReplacedDeclInfo() : ID(0), Offset(0), Loc(0) {}
367ef23b6001e8d9715246ca23bd8c3a6887d7844cbArgyrios Kyrtzidis    ReplacedDeclInfo(serialization::DeclID ID, uint64_t Offset,
368ef23b6001e8d9715246ca23bd8c3a6887d7844cbArgyrios Kyrtzidis                     SourceLocation Loc)
369ef23b6001e8d9715246ca23bd8c3a6887d7844cbArgyrios Kyrtzidis      : ID(ID), Offset(Offset), Loc(Loc.getRawEncoding()) {}
370ef23b6001e8d9715246ca23bd8c3a6887d7844cbArgyrios Kyrtzidis  };
371ef23b6001e8d9715246ca23bd8c3a6887d7844cbArgyrios Kyrtzidis
3723397c5570369f19b2d6c52e898f708d75ceede1fSebastian Redl  /// \brief Decls that have been replaced in the current dependent AST file.
3730b17c61e8f143901ce11b4a6e5129ac63aaeee04Sebastian Redl  ///
3740b17c61e8f143901ce11b4a6e5129ac63aaeee04Sebastian Redl  /// When a decl changes fundamentally after being deserialized (this shouldn't
3750b17c61e8f143901ce11b4a6e5129ac63aaeee04Sebastian Redl  /// happen, but the ObjC AST nodes are designed this way), it will be
3760b17c61e8f143901ce11b4a6e5129ac63aaeee04Sebastian Redl  /// serialized again. In this case, it is registered here, so that the reader
3770b17c61e8f143901ce11b4a6e5129ac63aaeee04Sebastian Redl  /// knows to read the updated version.
378ef23b6001e8d9715246ca23bd8c3a6887d7844cbArgyrios Kyrtzidis  SmallVector<ReplacedDeclInfo, 16> ReplacedDecls;
3792171bf1caba4d4b9eeb6a91efac4300b41f38b07Douglas Gregor
3802171bf1caba4d4b9eeb6a91efac4300b41f38b07Douglas Gregor  /// \brief The set of declarations that may have redeclaration chains that
3812171bf1caba4d4b9eeb6a91efac4300b41f38b07Douglas Gregor  /// need to be serialized.
382cfa88f893915ceb8ae4ce2f17c46c24a4d67502fDmitri Gribenko  llvm::SetVector<Decl *, SmallVector<Decl *, 4>,
3832171bf1caba4d4b9eeb6a91efac4300b41f38b07Douglas Gregor                  llvm::SmallPtrSet<Decl *, 4> > Redeclarations;
3842171bf1caba4d4b9eeb6a91efac4300b41f38b07Douglas Gregor
385c9490c000f515c29f200a1215328d8ab9a0f3818Douglas Gregor  /// \brief Statements that we've encountered while serializing a
3860b7489194f9f89fac39d57211c1e7953ae50251fDouglas Gregor  /// declaration or type.
387686775deca8b8685eb90801495880e3abdd844c2Chris Lattner  SmallVector<Stmt *, 16> StmtsToEmit;
3880b17c61e8f143901ce11b4a6e5129ac63aaeee04Sebastian Redl
389a4232eb646d89e7d52424bb42eb87d9061f39e63Sebastian Redl  /// \brief Statements collection to use for ASTWriter::AddStmt().
390ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie  /// It will point to StmtsToEmit unless it is overriden.
391686775deca8b8685eb90801495880e3abdd844c2Chris Lattner  SmallVector<Stmt *, 16> *CollectedStmts;
3920b7489194f9f89fac39d57211c1e7953ae50251fDouglas Gregor
393025452fa0eda63e150cfaeebe64f0a19c96b3a06Douglas Gregor  /// \brief Mapping from SwitchCase statements to IDs.
39412dcc64eebf7aaffb71392fba74fcb69f35d3b2eArgyrios Kyrtzidis  llvm::DenseMap<SwitchCase *, unsigned> SwitchCaseIDs;
3951eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
3963397c5570369f19b2d6c52e898f708d75ceede1fSebastian Redl  /// \brief The number of statements written to the AST file.
3973e1af84bb0092a1aafb49deaa4ab6664c9a9071bDouglas Gregor  unsigned NumStatements;
3983e1af84bb0092a1aafb49deaa4ab6664c9a9071bDouglas Gregor
3993397c5570369f19b2d6c52e898f708d75ceede1fSebastian Redl  /// \brief The number of macros written to the AST file.
40037e2684abfe38207fdb90620da062bb18c23f29aDouglas Gregor  unsigned NumMacros;
40137e2684abfe38207fdb90620da062bb18c23f29aDouglas Gregor
4023397c5570369f19b2d6c52e898f708d75ceede1fSebastian Redl  /// \brief The number of lexical declcontexts written to the AST
4032512308525ff328aa992da0b5ee14a488d2ea93aDouglas Gregor  /// file.
4042512308525ff328aa992da0b5ee14a488d2ea93aDouglas Gregor  unsigned NumLexicalDeclContexts;
4052512308525ff328aa992da0b5ee14a488d2ea93aDouglas Gregor
4063397c5570369f19b2d6c52e898f708d75ceede1fSebastian Redl  /// \brief The number of visible declcontexts written to the AST
4072512308525ff328aa992da0b5ee14a488d2ea93aDouglas Gregor  /// file.
4082512308525ff328aa992da0b5ee14a488d2ea93aDouglas Gregor  unsigned NumVisibleDeclContexts;
4092512308525ff328aa992da0b5ee14a488d2ea93aDouglas Gregor
4107c789c1a3f77f24032aa0bed2afacdb9e094e952Douglas Gregor  /// \brief The offset of each CXXBaseSpecifier set within the AST.
411686775deca8b8685eb90801495880e3abdd844c2Chris Lattner  SmallVector<uint32_t, 4> CXXBaseSpecifiersOffsets;
412ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie
4137c789c1a3f77f24032aa0bed2afacdb9e094e952Douglas Gregor  /// \brief The first ID number we can use for our own base specifiers.
4147c789c1a3f77f24032aa0bed2afacdb9e094e952Douglas Gregor  serialization::CXXBaseSpecifiersID FirstCXXBaseSpecifiersID;
415ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie
416ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie  /// \brief The base specifiers ID that will be assigned to the next new
4177c789c1a3f77f24032aa0bed2afacdb9e094e952Douglas Gregor  /// set of C++ base specifiers.
4187c789c1a3f77f24032aa0bed2afacdb9e094e952Douglas Gregor  serialization::CXXBaseSpecifiersID NextCXXBaseSpecifiersID;
4197c789c1a3f77f24032aa0bed2afacdb9e094e952Douglas Gregor
420ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie  /// \brief A set of C++ base specifiers that is queued to be written into the
421ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie  /// AST file.
4227c789c1a3f77f24032aa0bed2afacdb9e094e952Douglas Gregor  struct QueuedCXXBaseSpecifiers {
4237c789c1a3f77f24032aa0bed2afacdb9e094e952Douglas Gregor    QueuedCXXBaseSpecifiers() : ID(), Bases(), BasesEnd() { }
424ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie
4257c789c1a3f77f24032aa0bed2afacdb9e094e952Douglas Gregor    QueuedCXXBaseSpecifiers(serialization::CXXBaseSpecifiersID ID,
4267c789c1a3f77f24032aa0bed2afacdb9e094e952Douglas Gregor                            CXXBaseSpecifier const *Bases,
4277c789c1a3f77f24032aa0bed2afacdb9e094e952Douglas Gregor                            CXXBaseSpecifier const *BasesEnd)
4287c789c1a3f77f24032aa0bed2afacdb9e094e952Douglas Gregor      : ID(ID), Bases(Bases), BasesEnd(BasesEnd) { }
429ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie
4307c789c1a3f77f24032aa0bed2afacdb9e094e952Douglas Gregor    serialization::CXXBaseSpecifiersID ID;
4317c789c1a3f77f24032aa0bed2afacdb9e094e952Douglas Gregor    CXXBaseSpecifier const * Bases;
4327c789c1a3f77f24032aa0bed2afacdb9e094e952Douglas Gregor    CXXBaseSpecifier const * BasesEnd;
4337c789c1a3f77f24032aa0bed2afacdb9e094e952Douglas Gregor  };
434ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie
4357c789c1a3f77f24032aa0bed2afacdb9e094e952Douglas Gregor  /// \brief Queue of C++ base specifiers to be written to the AST file,
4367c789c1a3f77f24032aa0bed2afacdb9e094e952Douglas Gregor  /// in the order they should be written.
437686775deca8b8685eb90801495880e3abdd844c2Chris Lattner  SmallVector<QueuedCXXBaseSpecifiers, 2> CXXBaseSpecifiersToWrite;
438ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie
439392ed2b717d86ebdd202cb9bb58d18d8b3b4cd87Douglas Gregor  /// \brief A mapping from each known submodule to its ID number, which will
440392ed2b717d86ebdd202cb9bb58d18d8b3b4cd87Douglas Gregor  /// be a positive integer.
4411a4761edca58c6b559de825b9abfb66f7f1ba94aDouglas Gregor  llvm::DenseMap<Module *, unsigned> SubmoduleIDs;
442e209e5026892cb07294f733c72bd51359c0f0e72Douglas Gregor
443e209e5026892cb07294f733c72bd51359c0f0e72Douglas Gregor  /// \brief Retrieve or create a submodule ID for this module.
444e209e5026892cb07294f733c72bd51359c0f0e72Douglas Gregor  unsigned getSubmoduleID(Module *Mod);
445392ed2b717d86ebdd202cb9bb58d18d8b3b4cd87Douglas Gregor
446919e693e80632d214c1f3110f6ee5d1c0b61f06bArgyrios Kyrtzidis  /// \brief Write the given subexpression to the bitstream.
447e6f0868a55aba2613e2d5dba3348aaf1064e6ddbArgyrios Kyrtzidis  void WriteSubStmt(Stmt *S,
448e6f0868a55aba2613e2d5dba3348aaf1064e6ddbArgyrios Kyrtzidis                    llvm::DenseMap<Stmt *, uint64_t> &SubStmtEntries,
449e6f0868a55aba2613e2d5dba3348aaf1064e6ddbArgyrios Kyrtzidis                    llvm::DenseSet<Stmt *> &ParentStmts);
45017cfdeda476aa8899f0ccedd9cb9cdb76e89b6b4Argyrios Kyrtzidis
451b145b1e9de866e79fb386e4a074dc0b41853acf3Chris Lattner  void WriteBlockInfoBlock();
452bbf38319edd4eddc55ec273934e990d7e84991deDouglas Gregor  void WriteControlBlock(Preprocessor &PP, ASTContext &Context,
453bbf38319edd4eddc55ec273934e990d7e84991deDouglas Gregor                         StringRef isysroot, const std::string &OutputFile);
4544a18c3b25a2d7eb7f770ce91ee5e14433b2a1cb6Douglas Gregor  void WriteInputFiles(SourceManager &SourceMgr,
4554a18c3b25a2d7eb7f770ce91ee5e14433b2a1cb6Douglas Gregor                       HeaderSearchOptions &HSOpts,
456b22d19493d479bf3ed6e5e60bfcf7047823da7fcDouglas Gregor                       StringRef isysroot,
457b22d19493d479bf3ed6e5e60bfcf7047823da7fcDouglas Gregor                       bool Modules);
4581eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  void WriteSourceManagerBlock(SourceManager &SourceMgr,
459e650c8c3bca2f58cad8ffa8aab63126d26e890cdDouglas Gregor                               const Preprocessor &PP,
460832d620b4ae0fc5fe28561b885b4cfc65cf5c9abDouglas Gregor                               StringRef isysroot);
4617143aab97c6e849a5a5005b7853b8c7d5af008edDouglas Gregor  void WritePreprocessor(const Preprocessor &PP, bool IsModule);
462590ad93bf59f4e5f6adcba0d78efc3a58cac15ceArgyrios Kyrtzidis  void WriteHeaderSearch(const HeaderSearch &HS, StringRef isysroot);
4634800a5c79023271408af49797e09be32aca93232Douglas Gregor  void WritePreprocessorDetail(PreprocessingRecord &PPRec);
4641a4761edca58c6b559de825b9abfb66f7f1ba94aDouglas Gregor  void WriteSubmodules(Module *WritingModule);
4651329264ce0922b3cec8c8c599108f082105fa0e1Douglas Gregor
466ea744ab5f39b8f45f802301841b77398166bce8fArgyrios Kyrtzidis  void WritePragmaDiagnosticMappings(const DiagnosticsEngine &Diag,
467ea744ab5f39b8f45f802301841b77398166bce8fArgyrios Kyrtzidis                                     bool isModule);
468c850578dbfa68cf2d2776f59a5cb0009134d970eAnders Carlsson  void WriteCXXBaseSpecifiersOffsets();
4690953e767ff7817f97b3ab20896b229891eeff45bJohn McCall  void WriteType(QualType T);
470651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  uint32_t GenerateNameLookupTable(const DeclContext *DC,
471651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                                   llvm::SmallVectorImpl<char> &LookupTable);
4722cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor  uint64_t WriteDeclContextLexicalBlock(ASTContext &Context, DeclContext *DC);
4732cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor  uint64_t WriteDeclContextVisibleBlock(ASTContext &Context, DeclContext *DC);
4741476ed40ef6ef144937821da888c7e4d9ea0acd7Sebastian Redl  void WriteTypeDeclOffsets();
47510f3df54486385e6497c9e5f229ff816e5a6c511Argyrios Kyrtzidis  void WriteFileDeclIDsMap();
476aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko  void WriteComments();
477059612dd3429cef2d61f11950f3d93a40182bf69Sebastian Redl  void WriteSelectors(Sema &SemaRef);
478320198303df7c16950d83ae79c3f702b84badcf7Fariborz Jahanian  void WriteReferencedSelectorsPool(Sema &SemaRef);
479eee242ff426bf79149f221798966e58688383c1eDouglas Gregor  void WriteIdentifierTable(Preprocessor &PP, IdentifierResolver &IdResolver,
480eee242ff426bf79149f221798966e58688383c1eDouglas Gregor                            bool IsModule);
4814990890fc9428f98bef90ba349203a648c592778Alexander Kornienko  void WriteAttributes(ArrayRef<const Attr*> Attrs, RecordDataImpl &Record);
482651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  void WriteDeclUpdatesBlocks(RecordDataImpl &OffsetsRecord);
483aacdd02e5865aa410c1418d7ef77f445b5bb5cbaArgyrios Kyrtzidis  void WriteDeclReplacementsBlock();
4841d1e42b17da6a53391d50b08068ecde04311e368Sebastian Redl  void WriteDeclContextVisibleUpdate(const DeclContext *DC);
48584bccea1ad9fd8bc1f4ec3d1fc5dd8d15dabffbcPeter Collingbourne  void WriteFPPragmaOptions(const FPOptions &Opts);
48684bccea1ad9fd8bc1f4ec3d1fc5dd8d15dabffbcPeter Collingbourne  void WriteOpenCLExtensions(Sema &SemaRef);
487cff9f26ce0ed76d555cd33b3dca84dd5cdf376afDouglas Gregor  void WriteObjCCategories();
4882171bf1caba4d4b9eeb6a91efac4300b41f38b07Douglas Gregor  void WriteRedeclarations();
489c3cfd2ab3338d47861ece597212f21b972ebe727Douglas Gregor  void WriteMergedDecls();
490ac32d9044b9c1e7492cef929a322d23ce899d276Richard Smith  void WriteLateParsedTemplates(Sema &SemaRef);
4916bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  void WriteOptimizePragmaOptions(Sema &SemaRef);
492ac32d9044b9c1e7492cef929a322d23ce899d276Richard Smith
493953c564288f2f376fed9c3540096bde3694bbb7aJonathan D. Turner  unsigned DeclParmVarAbbrev;
494681d7237e1014bf64dd5ead6bf74ae55cdd19e61Sebastian Redl  unsigned DeclContextLexicalAbbrev;
495074dcc8ef8c5df7a155c85648e8eae786bee6cabArgyrios Kyrtzidis  unsigned DeclContextVisibleLookupAbbrev;
4961d1e42b17da6a53391d50b08068ecde04311e368Sebastian Redl  unsigned UpdateVisibleAbbrev;
497a72d8c4556fbdfca2c9e101722812861fcbdde12Douglas Gregor  unsigned DeclRefExprAbbrev;
498a72d8c4556fbdfca2c9e101722812861fcbdde12Douglas Gregor  unsigned CharacterLiteralAbbrev;
499a72d8c4556fbdfca2c9e101722812861fcbdde12Douglas Gregor  unsigned DeclRecordAbbrev;
500a72d8c4556fbdfca2c9e101722812861fcbdde12Douglas Gregor  unsigned IntegerLiteralAbbrev;
501953c564288f2f376fed9c3540096bde3694bbb7aJonathan D. Turner  unsigned DeclTypedefAbbrev;
502953c564288f2f376fed9c3540096bde3694bbb7aJonathan D. Turner  unsigned DeclVarAbbrev;
503953c564288f2f376fed9c3540096bde3694bbb7aJonathan D. Turner  unsigned DeclFieldAbbrev;
504953c564288f2f376fed9c3540096bde3694bbb7aJonathan D. Turner  unsigned DeclEnumAbbrev;
505953c564288f2f376fed9c3540096bde3694bbb7aJonathan D. Turner  unsigned DeclObjCIvarAbbrev;
506a72d8c4556fbdfca2c9e101722812861fcbdde12Douglas Gregor
507ea5ce4705df0743093925585d8edc80e0d8fe3ffChris Lattner  void WriteDeclsBlockAbbrevs();
50861d60ee6aa0a5ded0ddcf48679673b37506a1895Douglas Gregor  void WriteDecl(ASTContext &Context, Decl *D);
509651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  void AddFunctionDefinition(const FunctionDecl *FD, RecordData &Record);
5101dc13a15e789a174e5e5855efe27036dd7a9d252Sebastian Redl
5114182ed686283b72736b287cbe28583cb641f8934Argyrios Kyrtzidis  void WriteASTCore(Sema &SemaRef,
5127143aab97c6e849a5a5005b7853b8c7d5af008edDouglas Gregor                    StringRef isysroot, const std::string &OutputFile,
5131a4761edca58c6b559de825b9abfb66f7f1ba94aDouglas Gregor                    Module *WritingModule);
514ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie
5152cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregorpublic:
5162cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor  /// \brief Create a new precompiled header writer that outputs to
5172cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor  /// the given bitstream.
518a4232eb646d89e7d52424bb42eb87d9061f39e63Sebastian Redl  ASTWriter(llvm::BitstreamWriter &Stream);
51910f3df54486385e6497c9e5f229ff816e5a6c511Argyrios Kyrtzidis  ~ASTWriter();
520ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie
521e7785040107266d01ebdcc066365f70b7ace371fDouglas Gregor  /// \brief Write a precompiled header for the given semantic analysis.
522e650c8c3bca2f58cad8ffa8aab63126d26e890cdDouglas Gregor  ///
523e650c8c3bca2f58cad8ffa8aab63126d26e890cdDouglas Gregor  /// \param SemaRef a reference to the semantic analysis object that processed
524e650c8c3bca2f58cad8ffa8aab63126d26e890cdDouglas Gregor  /// the AST to be written into the precompiled header.
525e650c8c3bca2f58cad8ffa8aab63126d26e890cdDouglas Gregor  ///
526a8cc6ce36e70e2afa22ab6b4340035cb3941c2ebDouglas Gregor  /// \param WritingModule The module that we are writing. If null, we are
527a8cc6ce36e70e2afa22ab6b4340035cb3941c2ebDouglas Gregor  /// writing a precompiled header.
5287143aab97c6e849a5a5005b7853b8c7d5af008edDouglas Gregor  ///
5297143aab97c6e849a5a5005b7853b8c7d5af008edDouglas Gregor  /// \param isysroot if non-empty, write a relocatable file whose headers
530e650c8c3bca2f58cad8ffa8aab63126d26e890cdDouglas Gregor  /// are relative to the given system root.
5314182ed686283b72736b287cbe28583cb641f8934Argyrios Kyrtzidis  void WriteAST(Sema &SemaRef,
5328e3df4d0864f0a966c20088ca1a29c3398b7639dArgyrios Kyrtzidis                const std::string &OutputFile,
533bef35c91b594f66216f4aab303b71a6c5ab7abcfArgyrios Kyrtzidis                Module *WritingModule, StringRef isysroot,
534bef35c91b594f66216f4aab303b71a6c5ab7abcfArgyrios Kyrtzidis                bool hasErrors = false);
5352cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor
536aeeacf725c9e0ddd64ea9764bd008e5b6873ce51John McCall  /// \brief Emit a token.
537aeeacf725c9e0ddd64ea9764bd008e5b6873ce51John McCall  void AddToken(const Token &Tok, RecordDataImpl &Record);
538aeeacf725c9e0ddd64ea9764bd008e5b6873ce51John McCall
5392cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor  /// \brief Emit a source location.
54089eaf3af92c72c0c1aae807644e39cabc461d685Argyrios Kyrtzidis  void AddSourceLocation(SourceLocation Loc, RecordDataImpl &Record);
5412cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor
5426ad9ac097918fbdeb443ea7b99d4db9e49b28534Chris Lattner  /// \brief Emit a source range.
54389eaf3af92c72c0c1aae807644e39cabc461d685Argyrios Kyrtzidis  void AddSourceRange(SourceRange Range, RecordDataImpl &Record);
544ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie
5452cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor  /// \brief Emit an integral value.
54689eaf3af92c72c0c1aae807644e39cabc461d685Argyrios Kyrtzidis  void AddAPInt(const llvm::APInt &Value, RecordDataImpl &Record);
5472cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor
5480a2b45e5885b6b8477b167042c0f6cd1d99a1f13Douglas Gregor  /// \brief Emit a signed integral value.
54989eaf3af92c72c0c1aae807644e39cabc461d685Argyrios Kyrtzidis  void AddAPSInt(const llvm::APSInt &Value, RecordDataImpl &Record);
5500a2b45e5885b6b8477b167042c0f6cd1d99a1f13Douglas Gregor
55117fc223395d51be582fc666bb6ea21bd1dff26dcDouglas Gregor  /// \brief Emit a floating-point value.
55289eaf3af92c72c0c1aae807644e39cabc461d685Argyrios Kyrtzidis  void AddAPFloat(const llvm::APFloat &Value, RecordDataImpl &Record);
55317fc223395d51be582fc666bb6ea21bd1dff26dcDouglas Gregor
554d2598368876cfe40bc8465540033bc5b5e58d8afChris Lattner  /// \brief Emit a reference to an identifier.
55589eaf3af92c72c0c1aae807644e39cabc461d685Argyrios Kyrtzidis  void AddIdentifierRef(const IdentifierInfo *II, RecordDataImpl &Record);
5562cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor
557d2598368876cfe40bc8465540033bc5b5e58d8afChris Lattner  /// \brief Emit a Selector (which is a smart pointer reference).
55889eaf3af92c72c0c1aae807644e39cabc461d685Argyrios Kyrtzidis  void AddSelectorRef(Selector, RecordDataImpl &Record);
5591eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
560d2598368876cfe40bc8465540033bc5b5e58d8afChris Lattner  /// \brief Emit a CXXTemporary.
56189eaf3af92c72c0c1aae807644e39cabc461d685Argyrios Kyrtzidis  void AddCXXTemporary(const CXXTemporary *Temp, RecordDataImpl &Record);
5625d05007b7a7883159154e3f65f338a2542d53913Sebastian Redl
5637c789c1a3f77f24032aa0bed2afacdb9e094e952Douglas Gregor  /// \brief Emit a set of C++ base specifiers to the record.
5647c789c1a3f77f24032aa0bed2afacdb9e094e952Douglas Gregor  void AddCXXBaseSpecifiersRef(CXXBaseSpecifier const *Bases,
5657c789c1a3f77f24032aa0bed2afacdb9e094e952Douglas Gregor                               CXXBaseSpecifier const *BasesEnd,
5667c789c1a3f77f24032aa0bed2afacdb9e094e952Douglas Gregor                               RecordDataImpl &Record);
567ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie
5685d05007b7a7883159154e3f65f338a2542d53913Sebastian Redl  /// \brief Get the unique number used to refer to the given selector.
5698538e8d43a3a9bd439c987c0de37bcbf035dd391Sebastian Redl  serialization::SelectorID getSelectorRef(Selector Sel);
570ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie
5715d05007b7a7883159154e3f65f338a2542d53913Sebastian Redl  /// \brief Get the unique number used to refer to the given identifier.
5728538e8d43a3a9bd439c987c0de37bcbf035dd391Sebastian Redl  serialization::IdentID getIdentifierRef(const IdentifierInfo *II);
5732deaea37a637dd01221d0cced343702a39d8132cDouglas Gregor
574a8235d6c4093cd38dcf742909651f867de62e55bDouglas Gregor  /// \brief Get the unique number used to refer to the given macro.
5759317ab94bb68122ba6fc728eb73c1308fb913cd1Argyrios Kyrtzidis  serialization::MacroID getMacroRef(MacroInfo *MI, const IdentifierInfo *Name);
5769317ab94bb68122ba6fc728eb73c1308fb913cd1Argyrios Kyrtzidis
5779317ab94bb68122ba6fc728eb73c1308fb913cd1Argyrios Kyrtzidis  /// \brief Determine the ID of an already-emitted macro.
5789317ab94bb68122ba6fc728eb73c1308fb913cd1Argyrios Kyrtzidis  serialization::MacroID getMacroID(MacroInfo *MI);
5799317ab94bb68122ba6fc728eb73c1308fb913cd1Argyrios Kyrtzidis
5809317ab94bb68122ba6fc728eb73c1308fb913cd1Argyrios Kyrtzidis  uint64_t getMacroDirectivesOffset(const IdentifierInfo *Name);
581ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie
5822cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor  /// \brief Emit a reference to a type.
58389eaf3af92c72c0c1aae807644e39cabc461d685Argyrios Kyrtzidis  void AddTypeRef(QualType T, RecordDataImpl &Record);
5842cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor
5857fb35182f43392cea4517c203bbabb22364a19fcArgyrios Kyrtzidis  /// \brief Force a type to be emitted and get its ID.
5867fb35182f43392cea4517c203bbabb22364a19fcArgyrios Kyrtzidis  serialization::TypeID GetOrCreateTypeID(QualType T);
5877fb35182f43392cea4517c203bbabb22364a19fcArgyrios Kyrtzidis
588eb3f04e60fa17dba27344ed89fd1b9134bb6839cArgyrios Kyrtzidis  /// \brief Determine the type ID of an already-emitted type.
5895d26768e2661faa7ce0b55ffff4be8b3969fbbf5Argyrios Kyrtzidis  serialization::TypeID getTypeID(QualType T) const;
590eb3f04e60fa17dba27344ed89fd1b9134bb6839cArgyrios Kyrtzidis
59126fca90786af17f97e1a5ecc310d4bf39b831595Argyrios Kyrtzidis  /// \brief Force a type to be emitted and get its index.
5923b8043b49aff6e5d70f29ef5684214ce2473763cDouglas Gregor  serialization::TypeIdx GetOrCreateTypeIdx( QualType T);
59326fca90786af17f97e1a5ecc310d4bf39b831595Argyrios Kyrtzidis
59426fca90786af17f97e1a5ecc310d4bf39b831595Argyrios Kyrtzidis  /// \brief Determine the type index of an already-emitted type.
5955d26768e2661faa7ce0b55ffff4be8b3969fbbf5Argyrios Kyrtzidis  serialization::TypeIdx getTypeIdx(QualType T) const;
59626fca90786af17f97e1a5ecc310d4bf39b831595Argyrios Kyrtzidis
597a1ee0c548b8aa4aaf93d1917e304e3da13171a08John McCall  /// \brief Emits a reference to a declarator info.
59889eaf3af92c72c0c1aae807644e39cabc461d685Argyrios Kyrtzidis  void AddTypeSourceInfo(TypeSourceInfo *TInfo, RecordDataImpl &Record);
599a1ee0c548b8aa4aaf93d1917e304e3da13171a08John McCall
600dc355713be51fcb4ee52d9fd6b4548ceff47fadfDouglas Gregor  /// \brief Emits a type with source-location information.
601dc355713be51fcb4ee52d9fd6b4548ceff47fadfDouglas Gregor  void AddTypeLoc(TypeLoc TL, RecordDataImpl &Record);
602dc355713be51fcb4ee52d9fd6b4548ceff47fadfDouglas Gregor
60344f8c37e378f716e8cbb600e3800f437cf58f9e5Argyrios Kyrtzidis  /// \brief Emits a template argument location info.
60444f8c37e378f716e8cbb600e3800f437cf58f9e5Argyrios Kyrtzidis  void AddTemplateArgumentLocInfo(TemplateArgument::ArgKind Kind,
60544f8c37e378f716e8cbb600e3800f437cf58f9e5Argyrios Kyrtzidis                                  const TemplateArgumentLocInfo &Arg,
60689eaf3af92c72c0c1aae807644e39cabc461d685Argyrios Kyrtzidis                                  RecordDataImpl &Record);
60744f8c37e378f716e8cbb600e3800f437cf58f9e5Argyrios Kyrtzidis
608833ca991c1bfc967f0995974ca86f66ba1f666b5John McCall  /// \brief Emits a template argument location.
609833ca991c1bfc967f0995974ca86f66ba1f666b5John McCall  void AddTemplateArgumentLoc(const TemplateArgumentLoc &Arg,
61089eaf3af92c72c0c1aae807644e39cabc461d685Argyrios Kyrtzidis                              RecordDataImpl &Record);
611833ca991c1bfc967f0995974ca86f66ba1f666b5John McCall
612c1cef0892e049fcd31084f02d1efdd9985d4dfa4Enea Zaffanella  /// \brief Emits an AST template argument list info.
613c1cef0892e049fcd31084f02d1efdd9985d4dfa4Enea Zaffanella  void AddASTTemplateArgumentListInfo(
614c1cef0892e049fcd31084f02d1efdd9985d4dfa4Enea Zaffanella                          const ASTTemplateArgumentListInfo *ASTTemplArgList,
615c1cef0892e049fcd31084f02d1efdd9985d4dfa4Enea Zaffanella                          RecordDataImpl &Record);
616c1cef0892e049fcd31084f02d1efdd9985d4dfa4Enea Zaffanella
6172cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor  /// \brief Emit a reference to a declaration.
6187b90340c9c7d07aef4e301e72b5e8a30d5f4f0c8Argyrios Kyrtzidis  void AddDeclRef(const Decl *D, RecordDataImpl &Record);
6192cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor
620ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie
621681d7237e1014bf64dd5ead6bf74ae55cdd19e61Sebastian Redl  /// \brief Force a declaration to be emitted and get its ID.
6228538e8d43a3a9bd439c987c0de37bcbf035dd391Sebastian Redl  serialization::DeclID GetDeclRef(const Decl *D);
623681d7237e1014bf64dd5ead6bf74ae55cdd19e61Sebastian Redl
6243251ceb90b3fec68e86d6dcfa58836e20a7205c3Douglas Gregor  /// \brief Determine the declaration ID of an already-emitted
6253251ceb90b3fec68e86d6dcfa58836e20a7205c3Douglas Gregor  /// declaration.
6268538e8d43a3a9bd439c987c0de37bcbf035dd391Sebastian Redl  serialization::DeclID getDeclID(const Decl *D);
6273251ceb90b3fec68e86d6dcfa58836e20a7205c3Douglas Gregor
6282cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor  /// \brief Emit a declaration name.
62989eaf3af92c72c0c1aae807644e39cabc461d685Argyrios Kyrtzidis  void AddDeclarationName(DeclarationName Name, RecordDataImpl &Record);
6304045107b7384fd68eed5e3e2f06fc2a47e7be0a6Argyrios Kyrtzidis  void AddDeclarationNameLoc(const DeclarationNameLoc &DNLoc,
63189eaf3af92c72c0c1aae807644e39cabc461d685Argyrios Kyrtzidis                             DeclarationName Name, RecordDataImpl &Record);
6324045107b7384fd68eed5e3e2f06fc2a47e7be0a6Argyrios Kyrtzidis  void AddDeclarationNameInfo(const DeclarationNameInfo &NameInfo,
63389eaf3af92c72c0c1aae807644e39cabc461d685Argyrios Kyrtzidis                              RecordDataImpl &Record);
6344045107b7384fd68eed5e3e2f06fc2a47e7be0a6Argyrios Kyrtzidis
63589eaf3af92c72c0c1aae807644e39cabc461d685Argyrios Kyrtzidis  void AddQualifierInfo(const QualifierInfo &Info, RecordDataImpl &Record);
6360b7489194f9f89fac39d57211c1e7953ae50251fDouglas Gregor
6376ad9ac097918fbdeb443ea7b99d4db9e49b28534Chris Lattner  /// \brief Emit a nested name specifier.
63889eaf3af92c72c0c1aae807644e39cabc461d685Argyrios Kyrtzidis  void AddNestedNameSpecifier(NestedNameSpecifier *NNS, RecordDataImpl &Record);
639dc355713be51fcb4ee52d9fd6b4548ceff47fadfDouglas Gregor
640dc355713be51fcb4ee52d9fd6b4548ceff47fadfDouglas Gregor  /// \brief Emit a nested name specifier with source-location information.
641ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie  void AddNestedNameSpecifierLoc(NestedNameSpecifierLoc NNS,
642dc355713be51fcb4ee52d9fd6b4548ceff47fadfDouglas Gregor                                 RecordDataImpl &Record);
643ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie
64490b715e0df34eae2b50b9b43ec60828ed31dcf94Argyrios Kyrtzidis  /// \brief Emit a template name.
64589eaf3af92c72c0c1aae807644e39cabc461d685Argyrios Kyrtzidis  void AddTemplateName(TemplateName Name, RecordDataImpl &Record);
64690b715e0df34eae2b50b9b43ec60828ed31dcf94Argyrios Kyrtzidis
64790b715e0df34eae2b50b9b43ec60828ed31dcf94Argyrios Kyrtzidis  /// \brief Emit a template argument.
64889eaf3af92c72c0c1aae807644e39cabc461d685Argyrios Kyrtzidis  void AddTemplateArgument(const TemplateArgument &Arg, RecordDataImpl &Record);
6496ad9ac097918fbdeb443ea7b99d4db9e49b28534Chris Lattner
650dd41c14bfd7686b556de2acf6952e21a4f80b7aaArgyrios Kyrtzidis  /// \brief Emit a template parameter list.
651dd41c14bfd7686b556de2acf6952e21a4f80b7aaArgyrios Kyrtzidis  void AddTemplateParameterList(const TemplateParameterList *TemplateParams,
65289eaf3af92c72c0c1aae807644e39cabc461d685Argyrios Kyrtzidis                                RecordDataImpl &Record);
653dd41c14bfd7686b556de2acf6952e21a4f80b7aaArgyrios Kyrtzidis
654dd41c14bfd7686b556de2acf6952e21a4f80b7aaArgyrios Kyrtzidis  /// \brief Emit a template argument list.
655dd41c14bfd7686b556de2acf6952e21a4f80b7aaArgyrios Kyrtzidis  void AddTemplateArgumentList(const TemplateArgumentList *TemplateArgs,
65689eaf3af92c72c0c1aae807644e39cabc461d685Argyrios Kyrtzidis                                RecordDataImpl &Record);
657dd41c14bfd7686b556de2acf6952e21a4f80b7aaArgyrios Kyrtzidis
65837ffed3b7f229844cae2463ff82b527506c86c74Argyrios Kyrtzidis  /// \brief Emit a UnresolvedSet structure.
6592a82ca255b0f99f6201a75ed52b91fc024f6e9cfArgyrios Kyrtzidis  void AddUnresolvedSet(const ASTUnresolvedSet &Set, RecordDataImpl &Record);
66037ffed3b7f229844cae2463ff82b527506c86c74Argyrios Kyrtzidis
661a7be5065edc93ab52a25b2588a23a41a4beba21eSebastian Redl  /// \brief Emit a C++ base specifier.
662ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie  void AddCXXBaseSpecifier(const CXXBaseSpecifier &Base,
663ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie                           RecordDataImpl &Record);
6640745d0a648b75bd304045309276c70a755adaafbArgyrios Kyrtzidis
665cbb67480094b3bcb5b715acd827cbad55e2a204cSean Hunt  /// \brief Emit a CXXCtorInitializer array.
666cbb67480094b3bcb5b715acd827cbad55e2a204cSean Hunt  void AddCXXCtorInitializers(
667cbb67480094b3bcb5b715acd827cbad55e2a204cSean Hunt                             const CXXCtorInitializer * const *CtorInitializers,
668cbb67480094b3bcb5b715acd827cbad55e2a204cSean Hunt                             unsigned NumCtorInitializers,
669cbb67480094b3bcb5b715acd827cbad55e2a204cSean Hunt                             RecordDataImpl &Record);
67089eaf3af92c72c0c1aae807644e39cabc461d685Argyrios Kyrtzidis
67189eaf3af92c72c0c1aae807644e39cabc461d685Argyrios Kyrtzidis  void AddCXXDefinitionData(const CXXRecordDecl *D, RecordDataImpl &Record);
6728e706f4b8da141612861e127610141b8d17a9667Argyrios Kyrtzidis
673cd7d5a9dc558178ed7a66032f888781b3c592e4fDouglas Gregor  /// \brief Add a string to the given record.
674686775deca8b8685eb90801495880e3abdd844c2Chris Lattner  void AddString(StringRef Str, RecordDataImpl &Record);
675cd7d5a9dc558178ed7a66032f888781b3c592e4fDouglas Gregor
6760a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  /// \brief Add a version tuple to the given record
6770a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor  void AddVersionTuple(const VersionTuple &Version, RecordDataImpl &Record);
6780a0d2b179085a52c10402feebeb6db8b4d96a140Douglas Gregor
679100050bf643bcfe2d06bdcef491e387171249260Argyrios Kyrtzidis  /// \brief Mark a declaration context as needing an update.
6806bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  void AddUpdatedDeclContext(const DeclContext *DC);
681a7be5065edc93ab52a25b2588a23a41a4beba21eSebastian Redl
682d3d0755a4220d3fa6c125eb3f8ce29fc1424eac3Argyrios Kyrtzidis  void RewriteDecl(const Decl *D) {
683d3d0755a4220d3fa6c125eb3f8ce29fc1424eac3Argyrios Kyrtzidis    DeclsToRewrite.insert(D);
684d3d0755a4220d3fa6c125eb3f8ce29fc1424eac3Argyrios Kyrtzidis  }
685d3d0755a4220d3fa6c125eb3f8ce29fc1424eac3Argyrios Kyrtzidis
686ad834d534e9a5db3d3baa09593775f83ceaff1f2Argyrios Kyrtzidis  bool isRewritten(const Decl *D) const {
687ad834d534e9a5db3d3baa09593775f83ceaff1f2Argyrios Kyrtzidis    return DeclsToRewrite.count(D);
688ad834d534e9a5db3d3baa09593775f83ceaff1f2Argyrios Kyrtzidis  }
689ad834d534e9a5db3d3baa09593775f83ceaff1f2Argyrios Kyrtzidis
6901329264ce0922b3cec8c8c599108f082105fa0e1Douglas Gregor  /// \brief Infer the submodule ID that contains an entity at the given
6911329264ce0922b3cec8c8c599108f082105fa0e1Douglas Gregor  /// source location.
6921329264ce0922b3cec8c8c599108f082105fa0e1Douglas Gregor  serialization::SubmoduleID inferSubmoduleIDFromLocation(SourceLocation Loc);
6931329264ce0922b3cec8c8c599108f082105fa0e1Douglas Gregor
69455ea75bf61a5d76f6453513d937944ce68181c6aArgyrios Kyrtzidis  /// \brief Retrieve a submodule ID for this module.
69555ea75bf61a5d76f6453513d937944ce68181c6aArgyrios Kyrtzidis  /// Returns 0 If no ID has been associated with the module.
69655ea75bf61a5d76f6453513d937944ce68181c6aArgyrios Kyrtzidis  unsigned getExistingSubmoduleID(Module *Mod) const;
69755ea75bf61a5d76f6453513d937944ce68181c6aArgyrios Kyrtzidis
6983251ceb90b3fec68e86d6dcfa58836e20a7205c3Douglas Gregor  /// \brief Note that the identifier II occurs at the given offset
6993251ceb90b3fec68e86d6dcfa58836e20a7205c3Douglas Gregor  /// within the identifier table.
7003251ceb90b3fec68e86d6dcfa58836e20a7205c3Douglas Gregor  void SetIdentifierOffset(const IdentifierInfo *II, uint32_t Offset);
7013251ceb90b3fec68e86d6dcfa58836e20a7205c3Douglas Gregor
70283941df2745d69c05acee3174c7a265c206f70d9Douglas Gregor  /// \brief Note that the selector Sel occurs at the given offset
70383941df2745d69c05acee3174c7a265c206f70d9Douglas Gregor  /// within the method pool/selector table.
70483941df2745d69c05acee3174c7a265c206f70d9Douglas Gregor  void SetSelectorOffset(Selector Sel, uint32_t Offset);
70583941df2745d69c05acee3174c7a265c206f70d9Douglas Gregor
7063251ceb90b3fec68e86d6dcfa58836e20a7205c3Douglas Gregor  /// \brief Add the given statement or expression to the queue of
7073251ceb90b3fec68e86d6dcfa58836e20a7205c3Douglas Gregor  /// statements to emit.
708087fd536809ebe754d91c641a98917e02dd7452dDouglas Gregor  ///
709087fd536809ebe754d91c641a98917e02dd7452dDouglas Gregor  /// This routine should be used when emitting types and declarations
710087fd536809ebe754d91c641a98917e02dd7452dDouglas Gregor  /// that have expressions as part of their formulation. Once the
711c9490c000f515c29f200a1215328d8ab9a0f3818Douglas Gregor  /// type or declaration has been written, call FlushStmts() to write
712c9490c000f515c29f200a1215328d8ab9a0f3818Douglas Gregor  /// the corresponding statements just after the type or
713087fd536809ebe754d91c641a98917e02dd7452dDouglas Gregor  /// declaration.
71417cfdeda476aa8899f0ccedd9cb9cdb76e89b6b4Argyrios Kyrtzidis  void AddStmt(Stmt *S) {
715919e693e80632d214c1f3110f6ee5d1c0b61f06bArgyrios Kyrtzidis      CollectedStmts->push_back(S);
71617cfdeda476aa8899f0ccedd9cb9cdb76e89b6b4Argyrios Kyrtzidis  }
717087fd536809ebe754d91c641a98917e02dd7452dDouglas Gregor
718c9490c000f515c29f200a1215328d8ab9a0f3818Douglas Gregor  /// \brief Flush all of the statements and expressions that have
719c9490c000f515c29f200a1215328d8ab9a0f3818Douglas Gregor  /// been added to the queue via AddStmt().
720c9490c000f515c29f200a1215328d8ab9a0f3818Douglas Gregor  void FlushStmts();
721025452fa0eda63e150cfaeebe64f0a19c96b3a06Douglas Gregor
722ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie  /// \brief Flush all of the C++ base specifier sets that have been added
7237c789c1a3f77f24032aa0bed2afacdb9e094e952Douglas Gregor  /// via \c AddCXXBaseSpecifiersRef().
7247c789c1a3f77f24032aa0bed2afacdb9e094e952Douglas Gregor  void FlushCXXBaseSpecifiers();
725ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie
726025452fa0eda63e150cfaeebe64f0a19c96b3a06Douglas Gregor  /// \brief Record an ID for the given switch-case statement.
727025452fa0eda63e150cfaeebe64f0a19c96b3a06Douglas Gregor  unsigned RecordSwitchCaseID(SwitchCase *S);
728025452fa0eda63e150cfaeebe64f0a19c96b3a06Douglas Gregor
729025452fa0eda63e150cfaeebe64f0a19c96b3a06Douglas Gregor  /// \brief Retrieve the ID for the given switch-case statement.
730025452fa0eda63e150cfaeebe64f0a19c96b3a06Douglas Gregor  unsigned getSwitchCaseID(SwitchCase *S);
731025452fa0eda63e150cfaeebe64f0a19c96b3a06Douglas Gregor
732e09a275444576deb2c8d9e2255554242f65d7c00Argyrios Kyrtzidis  void ClearSwitchCaseIDs();
733e09a275444576deb2c8d9e2255554242f65d7c00Argyrios Kyrtzidis
734953c564288f2f376fed9c3540096bde3694bbb7aJonathan D. Turner  unsigned getDeclParmVarAbbrev() const { return DeclParmVarAbbrev; }
735a72d8c4556fbdfca2c9e101722812861fcbdde12Douglas Gregor  unsigned getDeclRefExprAbbrev() const { return DeclRefExprAbbrev; }
736a72d8c4556fbdfca2c9e101722812861fcbdde12Douglas Gregor  unsigned getCharacterLiteralAbbrev() const { return CharacterLiteralAbbrev; }
737a72d8c4556fbdfca2c9e101722812861fcbdde12Douglas Gregor  unsigned getDeclRecordAbbrev() const { return DeclRecordAbbrev; }
738a72d8c4556fbdfca2c9e101722812861fcbdde12Douglas Gregor  unsigned getIntegerLiteralAbbrev() const { return IntegerLiteralAbbrev; }
739953c564288f2f376fed9c3540096bde3694bbb7aJonathan D. Turner  unsigned getDeclTypedefAbbrev() const { return DeclTypedefAbbrev; }
740953c564288f2f376fed9c3540096bde3694bbb7aJonathan D. Turner  unsigned getDeclVarAbbrev() const { return DeclVarAbbrev; }
741953c564288f2f376fed9c3540096bde3694bbb7aJonathan D. Turner  unsigned getDeclFieldAbbrev() const { return DeclFieldAbbrev; }
742953c564288f2f376fed9c3540096bde3694bbb7aJonathan D. Turner  unsigned getDeclEnumAbbrev() const { return DeclEnumAbbrev; }
743953c564288f2f376fed9c3540096bde3694bbb7aJonathan D. Turner  unsigned getDeclObjCIvarAbbrev() const { return DeclObjCIvarAbbrev; }
744953c564288f2f376fed9c3540096bde3694bbb7aJonathan D. Turner
745f2f0f03d08c6143137a79a8edffc7d41823bc3c7Sebastian Redl  bool hasChain() const { return Chain; }
746f2f0f03d08c6143137a79a8edffc7d41823bc3c7Sebastian Redl
747571db7f0cb31789737be92fce1c1b738e6dbe795Sebastian Redl  // ASTDeserializationListener implementation
748651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  void ReaderInitialized(ASTReader *Reader) override;
749651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  void IdentifierRead(serialization::IdentID ID, IdentifierInfo *II) override;
750651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  void MacroRead(serialization::MacroID ID, MacroInfo *MI) override;
751651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  void TypeRead(serialization::TypeIdx Idx, QualType T) override;
752651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  void SelectorRead(serialization::SelectorID ID, Selector Sel) override;
753e24692b30adbe8144597678a0e3354912e99c747Argyrios Kyrtzidis  void MacroDefinitionRead(serialization::PreprocessedEntityID ID,
754651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                           MacroDefinition *MD) override;
755651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  void ModuleRead(serialization::SubmoduleID ID, Module *Mod) override;
756a8235d6c4093cd38dcf742909651f867de62e55bDouglas Gregor
757565bf30bf5607b9740d288d8d9c45cf38ea75298Argyrios Kyrtzidis  // ASTMutationListener implementation.
758651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  void CompletedTagDefinition(const TagDecl *D) override;
759651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  void AddedVisibleDecl(const DeclContext *DC, const Decl *D) override;
760651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  void AddedCXXImplicitMember(const CXXRecordDecl *RD, const Decl *D) override;
761651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  void AddedCXXTemplateSpecialization(const ClassTemplateDecl *TD,
762651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                             const ClassTemplateSpecializationDecl *D) override;
763651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  void AddedCXXTemplateSpecialization(const VarTemplateDecl *TD,
764651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                               const VarTemplateSpecializationDecl *D) override;
765651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  void AddedCXXTemplateSpecialization(const FunctionTemplateDecl *TD,
766651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                                      const FunctionDecl *D) override;
767651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  void ResolvedExceptionSpec(const FunctionDecl *FD) override;
768651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  void DeducedReturnType(const FunctionDecl *FD, QualType ReturnType) override;
769651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  void CompletedImplicitDefinition(const FunctionDecl *D) override;
770651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  void StaticDataMemberInstantiated(const VarDecl *D) override;
771651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  void FunctionDefinitionInstantiated(const FunctionDecl *D) override;
772651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  void AddedObjCCategoryToInterface(const ObjCCategoryDecl *CatD,
773651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                                    const ObjCInterfaceDecl *IFD) override;
774651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  void AddedObjCPropertyInClassExtension(const ObjCPropertyDecl *Prop,
775651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                                    const ObjCPropertyDecl *OrigProp,
776651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                                    const ObjCCategoryDecl *ClassExt) override;
777651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  void DeclarationMarkedUsed(const Decl *D) override;
7782cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor};
7792cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor
7801d715ac14bf440664fb0d1425ea882274f994f57Douglas Gregor/// \brief AST and semantic-analysis consumer that generates a
7811d715ac14bf440664fb0d1425ea882274f994f57Douglas Gregor/// precompiled header from the parsed source code.
7821d715ac14bf440664fb0d1425ea882274f994f57Douglas Gregorclass PCHGenerator : public SemaConsumer {
7831d715ac14bf440664fb0d1425ea882274f994f57Douglas Gregor  const Preprocessor &PP;
7848e3df4d0864f0a966c20088ca1a29c3398b7639dArgyrios Kyrtzidis  std::string OutputFile;
7851a4761edca58c6b559de825b9abfb66f7f1ba94aDouglas Gregor  clang::Module *Module;
786832d620b4ae0fc5fe28561b885b4cfc65cf5c9abDouglas Gregor  std::string isysroot;
7878cc488fefb2fb04bc8d5398da29f0182f97934cfChris Lattner  raw_ostream *Out;
7881d715ac14bf440664fb0d1425ea882274f994f57Douglas Gregor  Sema *SemaPtr;
789cfa88f893915ceb8ae4ce2f17c46c24a4d67502fDmitri Gribenko  SmallVector<char, 128> Buffer;
7901d715ac14bf440664fb0d1425ea882274f994f57Douglas Gregor  llvm::BitstreamWriter Stream;
791a4232eb646d89e7d52424bb42eb87d9061f39e63Sebastian Redl  ASTWriter Writer;
7921f01f7c160c06f8290b4f1c203e36b242074c6b1Argyrios Kyrtzidis  bool AllowASTWithErrors;
7931f01f7c160c06f8290b4f1c203e36b242074c6b1Argyrios Kyrtzidis  bool HasEmittedPCH;
7941d715ac14bf440664fb0d1425ea882274f994f57Douglas Gregor
795eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregorprotected:
796a4232eb646d89e7d52424bb42eb87d9061f39e63Sebastian Redl  ASTWriter &getWriter() { return Writer; }
797a4232eb646d89e7d52424bb42eb87d9061f39e63Sebastian Redl  const ASTWriter &getWriter() const { return Writer; }
798eb8837b88c18631c69ac75f64ab1853762063180Douglas Gregor
7991d715ac14bf440664fb0d1425ea882274f994f57Douglas Gregorpublic:
800ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie  PCHGenerator(const Preprocessor &PP, StringRef OutputFile,
8011a4761edca58c6b559de825b9abfb66f7f1ba94aDouglas Gregor               clang::Module *Module,
8021f01f7c160c06f8290b4f1c203e36b242074c6b1Argyrios Kyrtzidis               StringRef isysroot, raw_ostream *Out,
8031f01f7c160c06f8290b4f1c203e36b242074c6b1Argyrios Kyrtzidis               bool AllowASTWithErrors = false);
8044947e25dd9f7ac1f2176d63262563ba3e96538feDouglas Gregor  ~PCHGenerator();
805651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  void InitializeSema(Sema &S) override { SemaPtr = &S; }
806651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  void HandleTranslationUnit(ASTContext &Ctx) override;
807651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  ASTMutationListener *GetASTMutationListener() override;
808651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  ASTDeserializationListener *GetASTDeserializationListener() override;
8091f01f7c160c06f8290b4f1c203e36b242074c6b1Argyrios Kyrtzidis
8101f01f7c160c06f8290b4f1c203e36b242074c6b1Argyrios Kyrtzidis  bool hasEmittedPCH() const { return HasEmittedPCH; }
8111d715ac14bf440664fb0d1425ea882274f994f57Douglas Gregor};
8121d715ac14bf440664fb0d1425ea882274f994f57Douglas Gregor
8132cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor} // end namespace clang
8142cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor
8152cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor#endif
816