Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
14 | pmbaty | 1 | //===- ASTWriter.h - AST File Writer ----------------------------*- C++ -*-===// |
2 | // |
||
3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
||
4 | // See https://llvm.org/LICENSE.txt for license information. |
||
5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
||
6 | // |
||
7 | //===----------------------------------------------------------------------===// |
||
8 | // |
||
9 | // This file defines the ASTWriter class, which writes an AST file |
||
10 | // containing a serialized representation of a translation unit. |
||
11 | // |
||
12 | //===----------------------------------------------------------------------===// |
||
13 | |||
14 | #ifndef LLVM_CLANG_SERIALIZATION_ASTWRITER_H |
||
15 | #define LLVM_CLANG_SERIALIZATION_ASTWRITER_H |
||
16 | |||
17 | #include "clang/AST/ASTMutationListener.h" |
||
18 | #include "clang/AST/Decl.h" |
||
19 | #include "clang/AST/Type.h" |
||
20 | #include "clang/Basic/LLVM.h" |
||
21 | #include "clang/Basic/Module.h" |
||
22 | #include "clang/Basic/SourceLocation.h" |
||
23 | #include "clang/Sema/Sema.h" |
||
24 | #include "clang/Sema/SemaConsumer.h" |
||
25 | #include "clang/Serialization/ASTBitCodes.h" |
||
26 | #include "clang/Serialization/ASTDeserializationListener.h" |
||
27 | #include "clang/Serialization/PCHContainerOperations.h" |
||
28 | #include "clang/Serialization/SourceLocationEncoding.h" |
||
29 | #include "llvm/ADT/ArrayRef.h" |
||
30 | #include "llvm/ADT/DenseMap.h" |
||
31 | #include "llvm/ADT/DenseSet.h" |
||
32 | #include "llvm/ADT/MapVector.h" |
||
33 | #include "llvm/ADT/STLExtras.h" |
||
34 | #include "llvm/ADT/SetVector.h" |
||
35 | #include "llvm/ADT/SmallVector.h" |
||
36 | #include "llvm/ADT/StringRef.h" |
||
37 | #include "llvm/Bitstream/BitstreamWriter.h" |
||
38 | #include <cassert> |
||
39 | #include <cstddef> |
||
40 | #include <cstdint> |
||
41 | #include <ctime> |
||
42 | #include <memory> |
||
43 | #include <queue> |
||
44 | #include <string> |
||
45 | #include <utility> |
||
46 | #include <vector> |
||
47 | |||
48 | namespace clang { |
||
49 | |||
50 | class ASTContext; |
||
51 | class ASTReader; |
||
52 | class Attr; |
||
53 | class CXXRecordDecl; |
||
54 | class FileEntry; |
||
55 | class FPOptionsOverride; |
||
56 | class FunctionDecl; |
||
57 | class HeaderSearch; |
||
58 | class HeaderSearchOptions; |
||
59 | class IdentifierResolver; |
||
60 | class LangOptions; |
||
61 | class MacroDefinitionRecord; |
||
62 | class MacroInfo; |
||
63 | class Module; |
||
64 | class InMemoryModuleCache; |
||
65 | class ModuleFileExtension; |
||
66 | class ModuleFileExtensionWriter; |
||
67 | class NamedDecl; |
||
68 | class ObjCInterfaceDecl; |
||
69 | class PreprocessingRecord; |
||
70 | class Preprocessor; |
||
71 | class RecordDecl; |
||
72 | class Sema; |
||
73 | class SourceManager; |
||
74 | class Stmt; |
||
75 | class StoredDeclsList; |
||
76 | class SwitchCase; |
||
77 | class Token; |
||
78 | |||
79 | /// Writes an AST file containing the contents of a translation unit. |
||
80 | /// |
||
81 | /// The ASTWriter class produces a bitstream containing the serialized |
||
82 | /// representation of a given abstract syntax tree and its supporting |
||
83 | /// data structures. This bitstream can be de-serialized via an |
||
84 | /// instance of the ASTReader class. |
||
85 | class ASTWriter : public ASTDeserializationListener, |
||
86 | public ASTMutationListener { |
||
87 | public: |
||
88 | friend class ASTDeclWriter; |
||
89 | friend class ASTRecordWriter; |
||
90 | |||
91 | using RecordData = SmallVector<uint64_t, 64>; |
||
92 | using RecordDataImpl = SmallVectorImpl<uint64_t>; |
||
93 | using RecordDataRef = ArrayRef<uint64_t>; |
||
94 | |||
95 | private: |
||
96 | /// Map that provides the ID numbers of each type within the |
||
97 | /// output stream, plus those deserialized from a chained PCH. |
||
98 | /// |
||
99 | /// The ID numbers of types are consecutive (in order of discovery) |
||
100 | /// and start at 1. 0 is reserved for NULL. When types are actually |
||
101 | /// stored in the stream, the ID number is shifted by 2 bits to |
||
102 | /// allow for the const/volatile qualifiers. |
||
103 | /// |
||
104 | /// Keys in the map never have const/volatile qualifiers. |
||
105 | using TypeIdxMap = llvm::DenseMap<QualType, serialization::TypeIdx, |
||
106 | serialization::UnsafeQualTypeDenseMapInfo>; |
||
107 | |||
108 | using LocSeq = SourceLocationSequence; |
||
109 | |||
110 | /// The bitstream writer used to emit this precompiled header. |
||
111 | llvm::BitstreamWriter &Stream; |
||
112 | |||
113 | /// The buffer associated with the bitstream. |
||
114 | const SmallVectorImpl<char> &Buffer; |
||
115 | |||
116 | /// The PCM manager which manages memory buffers for pcm files. |
||
117 | InMemoryModuleCache &ModuleCache; |
||
118 | |||
119 | /// The ASTContext we're writing. |
||
120 | ASTContext *Context = nullptr; |
||
121 | |||
122 | /// The preprocessor we're writing. |
||
123 | Preprocessor *PP = nullptr; |
||
124 | |||
125 | /// The reader of existing AST files, if we're chaining. |
||
126 | ASTReader *Chain = nullptr; |
||
127 | |||
128 | /// The module we're currently writing, if any. |
||
129 | Module *WritingModule = nullptr; |
||
130 | |||
131 | /// The offset of the first bit inside the AST_BLOCK. |
||
132 | uint64_t ASTBlockStartOffset = 0; |
||
133 | |||
134 | /// The range representing all the AST_BLOCK. |
||
135 | std::pair<uint64_t, uint64_t> ASTBlockRange; |
||
136 | |||
137 | /// The base directory for any relative paths we emit. |
||
138 | std::string BaseDirectory; |
||
139 | |||
140 | /// Indicates whether timestamps should be written to the produced |
||
141 | /// module file. This is the case for files implicitly written to the |
||
142 | /// module cache, where we need the timestamps to determine if the module |
||
143 | /// file is up to date, but not otherwise. |
||
144 | bool IncludeTimestamps; |
||
145 | |||
146 | /// Indicates when the AST writing is actively performing |
||
147 | /// serialization, rather than just queueing updates. |
||
148 | bool WritingAST = false; |
||
149 | |||
150 | /// Indicates that we are done serializing the collection of decls |
||
151 | /// and types to emit. |
||
152 | bool DoneWritingDeclsAndTypes = false; |
||
153 | |||
154 | /// Indicates that the AST contained compiler errors. |
||
155 | bool ASTHasCompilerErrors = false; |
||
156 | |||
157 | /// Mapping from input file entries to the index into the |
||
158 | /// offset table where information about that input file is stored. |
||
159 | llvm::DenseMap<const FileEntry *, uint32_t> InputFileIDs; |
||
160 | |||
161 | /// Stores a declaration or a type to be written to the AST file. |
||
162 | class DeclOrType { |
||
163 | public: |
||
164 | DeclOrType(Decl *D) : Stored(D), IsType(false) {} |
||
165 | DeclOrType(QualType T) : Stored(T.getAsOpaquePtr()), IsType(true) {} |
||
166 | |||
167 | bool isType() const { return IsType; } |
||
168 | bool isDecl() const { return !IsType; } |
||
169 | |||
170 | QualType getType() const { |
||
171 | assert(isType() && "Not a type!"); |
||
172 | return QualType::getFromOpaquePtr(Stored); |
||
173 | } |
||
174 | |||
175 | Decl *getDecl() const { |
||
176 | assert(isDecl() && "Not a decl!"); |
||
177 | return static_cast<Decl *>(Stored); |
||
178 | } |
||
179 | |||
180 | private: |
||
181 | void *Stored; |
||
182 | bool IsType; |
||
183 | }; |
||
184 | |||
185 | /// The declarations and types to emit. |
||
186 | std::queue<DeclOrType> DeclTypesToEmit; |
||
187 | |||
188 | /// The first ID number we can use for our own declarations. |
||
189 | serialization::DeclID FirstDeclID = serialization::NUM_PREDEF_DECL_IDS; |
||
190 | |||
191 | /// The decl ID that will be assigned to the next new decl. |
||
192 | serialization::DeclID NextDeclID = FirstDeclID; |
||
193 | |||
194 | /// Map that provides the ID numbers of each declaration within |
||
195 | /// the output stream, as well as those deserialized from a chained PCH. |
||
196 | /// |
||
197 | /// The ID numbers of declarations are consecutive (in order of |
||
198 | /// discovery) and start at 2. 1 is reserved for the translation |
||
199 | /// unit, while 0 is reserved for NULL. |
||
200 | llvm::DenseMap<const Decl *, serialization::DeclID> DeclIDs; |
||
201 | |||
202 | /// Offset of each declaration in the bitstream, indexed by |
||
203 | /// the declaration's ID. |
||
204 | std::vector<serialization::DeclOffset> DeclOffsets; |
||
205 | |||
206 | /// The offset of the DECLTYPES_BLOCK. The offsets in DeclOffsets |
||
207 | /// are relative to this value. |
||
208 | uint64_t DeclTypesBlockStartOffset = 0; |
||
209 | |||
210 | /// Sorted (by file offset) vector of pairs of file offset/DeclID. |
||
211 | using LocDeclIDsTy = |
||
212 | SmallVector<std::pair<unsigned, serialization::DeclID>, 64>; |
||
213 | struct DeclIDInFileInfo { |
||
214 | LocDeclIDsTy DeclIDs; |
||
215 | |||
216 | /// Set when the DeclIDs vectors from all files are joined, this |
||
217 | /// indicates the index that this particular vector has in the global one. |
||
218 | unsigned FirstDeclIndex; |
||
219 | }; |
||
220 | using FileDeclIDsTy = |
||
221 | llvm::DenseMap<FileID, std::unique_ptr<DeclIDInFileInfo>>; |
||
222 | |||
223 | /// Map from file SLocEntries to info about the file-level declarations |
||
224 | /// that it contains. |
||
225 | FileDeclIDsTy FileDeclIDs; |
||
226 | |||
227 | void associateDeclWithFile(const Decl *D, serialization::DeclID); |
||
228 | |||
229 | /// The first ID number we can use for our own types. |
||
230 | serialization::TypeID FirstTypeID = serialization::NUM_PREDEF_TYPE_IDS; |
||
231 | |||
232 | /// The type ID that will be assigned to the next new type. |
||
233 | serialization::TypeID NextTypeID = FirstTypeID; |
||
234 | |||
235 | /// Map that provides the ID numbers of each type within the |
||
236 | /// output stream, plus those deserialized from a chained PCH. |
||
237 | /// |
||
238 | /// The ID numbers of types are consecutive (in order of discovery) |
||
239 | /// and start at 1. 0 is reserved for NULL. When types are actually |
||
240 | /// stored in the stream, the ID number is shifted by 2 bits to |
||
241 | /// allow for the const/volatile qualifiers. |
||
242 | /// |
||
243 | /// Keys in the map never have const/volatile qualifiers. |
||
244 | TypeIdxMap TypeIdxs; |
||
245 | |||
246 | /// Offset of each type in the bitstream, indexed by |
||
247 | /// the type's ID. |
||
248 | std::vector<serialization::UnderalignedInt64> TypeOffsets; |
||
249 | |||
250 | /// The first ID number we can use for our own identifiers. |
||
251 | serialization::IdentID FirstIdentID = serialization::NUM_PREDEF_IDENT_IDS; |
||
252 | |||
253 | /// The identifier ID that will be assigned to the next new identifier. |
||
254 | serialization::IdentID NextIdentID = FirstIdentID; |
||
255 | |||
256 | /// Map that provides the ID numbers of each identifier in |
||
257 | /// the output stream. |
||
258 | /// |
||
259 | /// The ID numbers for identifiers are consecutive (in order of |
||
260 | /// discovery), starting at 1. An ID of zero refers to a NULL |
||
261 | /// IdentifierInfo. |
||
262 | llvm::MapVector<const IdentifierInfo *, serialization::IdentID> IdentifierIDs; |
||
263 | |||
264 | /// The first ID number we can use for our own macros. |
||
265 | serialization::MacroID FirstMacroID = serialization::NUM_PREDEF_MACRO_IDS; |
||
266 | |||
267 | /// The identifier ID that will be assigned to the next new identifier. |
||
268 | serialization::MacroID NextMacroID = FirstMacroID; |
||
269 | |||
270 | /// Map that provides the ID numbers of each macro. |
||
271 | llvm::DenseMap<MacroInfo *, serialization::MacroID> MacroIDs; |
||
272 | |||
273 | struct MacroInfoToEmitData { |
||
274 | const IdentifierInfo *Name; |
||
275 | MacroInfo *MI; |
||
276 | serialization::MacroID ID; |
||
277 | }; |
||
278 | |||
279 | /// The macro infos to emit. |
||
280 | std::vector<MacroInfoToEmitData> MacroInfosToEmit; |
||
281 | |||
282 | llvm::DenseMap<const IdentifierInfo *, uint32_t> |
||
283 | IdentMacroDirectivesOffsetMap; |
||
284 | |||
285 | /// @name FlushStmt Caches |
||
286 | /// @{ |
||
287 | |||
288 | /// Set of parent Stmts for the currently serializing sub-stmt. |
||
289 | llvm::DenseSet<Stmt *> ParentStmts; |
||
290 | |||
291 | /// Offsets of sub-stmts already serialized. The offset points |
||
292 | /// just after the stmt record. |
||
293 | llvm::DenseMap<Stmt *, uint64_t> SubStmtEntries; |
||
294 | |||
295 | /// @} |
||
296 | |||
297 | /// Offsets of each of the identifier IDs into the identifier |
||
298 | /// table. |
||
299 | std::vector<uint32_t> IdentifierOffsets; |
||
300 | |||
301 | /// The first ID number we can use for our own submodules. |
||
302 | serialization::SubmoduleID FirstSubmoduleID = |
||
303 | serialization::NUM_PREDEF_SUBMODULE_IDS; |
||
304 | |||
305 | /// The submodule ID that will be assigned to the next new submodule. |
||
306 | serialization::SubmoduleID NextSubmoduleID = FirstSubmoduleID; |
||
307 | |||
308 | /// The first ID number we can use for our own selectors. |
||
309 | serialization::SelectorID FirstSelectorID = |
||
310 | serialization::NUM_PREDEF_SELECTOR_IDS; |
||
311 | |||
312 | /// The selector ID that will be assigned to the next new selector. |
||
313 | serialization::SelectorID NextSelectorID = FirstSelectorID; |
||
314 | |||
315 | /// Map that provides the ID numbers of each Selector. |
||
316 | llvm::MapVector<Selector, serialization::SelectorID> SelectorIDs; |
||
317 | |||
318 | /// Offset of each selector within the method pool/selector |
||
319 | /// table, indexed by the Selector ID (-1). |
||
320 | std::vector<uint32_t> SelectorOffsets; |
||
321 | |||
322 | /// Mapping from macro definitions (as they occur in the preprocessing |
||
323 | /// record) to the macro IDs. |
||
324 | llvm::DenseMap<const MacroDefinitionRecord *, |
||
325 | serialization::PreprocessedEntityID> MacroDefinitions; |
||
326 | |||
327 | /// Cache of indices of anonymous declarations within their lexical |
||
328 | /// contexts. |
||
329 | llvm::DenseMap<const Decl *, unsigned> AnonymousDeclarationNumbers; |
||
330 | |||
331 | /// An update to a Decl. |
||
332 | class DeclUpdate { |
||
333 | /// A DeclUpdateKind. |
||
334 | unsigned Kind; |
||
335 | union { |
||
336 | const Decl *Dcl; |
||
337 | void *Type; |
||
338 | SourceLocation::UIntTy Loc; |
||
339 | unsigned Val; |
||
340 | Module *Mod; |
||
341 | const Attr *Attribute; |
||
342 | }; |
||
343 | |||
344 | public: |
||
345 | DeclUpdate(unsigned Kind) : Kind(Kind), Dcl(nullptr) {} |
||
346 | DeclUpdate(unsigned Kind, const Decl *Dcl) : Kind(Kind), Dcl(Dcl) {} |
||
347 | DeclUpdate(unsigned Kind, QualType Type) |
||
348 | : Kind(Kind), Type(Type.getAsOpaquePtr()) {} |
||
349 | DeclUpdate(unsigned Kind, SourceLocation Loc) |
||
350 | : Kind(Kind), Loc(Loc.getRawEncoding()) {} |
||
351 | DeclUpdate(unsigned Kind, unsigned Val) : Kind(Kind), Val(Val) {} |
||
352 | DeclUpdate(unsigned Kind, Module *M) : Kind(Kind), Mod(M) {} |
||
353 | DeclUpdate(unsigned Kind, const Attr *Attribute) |
||
354 | : Kind(Kind), Attribute(Attribute) {} |
||
355 | |||
356 | unsigned getKind() const { return Kind; } |
||
357 | const Decl *getDecl() const { return Dcl; } |
||
358 | QualType getType() const { return QualType::getFromOpaquePtr(Type); } |
||
359 | |||
360 | SourceLocation getLoc() const { |
||
361 | return SourceLocation::getFromRawEncoding(Loc); |
||
362 | } |
||
363 | |||
364 | unsigned getNumber() const { return Val; } |
||
365 | Module *getModule() const { return Mod; } |
||
366 | const Attr *getAttr() const { return Attribute; } |
||
367 | }; |
||
368 | |||
369 | using UpdateRecord = SmallVector<DeclUpdate, 1>; |
||
370 | using DeclUpdateMap = llvm::MapVector<const Decl *, UpdateRecord>; |
||
371 | |||
372 | /// Mapping from declarations that came from a chained PCH to the |
||
373 | /// record containing modifications to them. |
||
374 | DeclUpdateMap DeclUpdates; |
||
375 | |||
376 | using FirstLatestDeclMap = llvm::DenseMap<Decl *, Decl *>; |
||
377 | |||
378 | /// Map of first declarations from a chained PCH that point to the |
||
379 | /// most recent declarations in another PCH. |
||
380 | FirstLatestDeclMap FirstLatestDecls; |
||
381 | |||
382 | /// Declarations encountered that might be external |
||
383 | /// definitions. |
||
384 | /// |
||
385 | /// We keep track of external definitions and other 'interesting' declarations |
||
386 | /// as we are emitting declarations to the AST file. The AST file contains a |
||
387 | /// separate record for these declarations, which are provided to the AST |
||
388 | /// consumer by the AST reader. This is behavior is required to properly cope with, |
||
389 | /// e.g., tentative variable definitions that occur within |
||
390 | /// headers. The declarations themselves are stored as declaration |
||
391 | /// IDs, since they will be written out to an EAGERLY_DESERIALIZED_DECLS |
||
392 | /// record. |
||
393 | SmallVector<serialization::DeclID, 16> EagerlyDeserializedDecls; |
||
394 | SmallVector<serialization::DeclID, 16> ModularCodegenDecls; |
||
395 | |||
396 | /// DeclContexts that have received extensions since their serialized |
||
397 | /// form. |
||
398 | /// |
||
399 | /// For namespaces, when we're chaining and encountering a namespace, we check |
||
400 | /// if its primary namespace comes from the chain. If it does, we add the |
||
401 | /// primary to this set, so that we can write out lexical content updates for |
||
402 | /// it. |
||
403 | llvm::SmallSetVector<const DeclContext *, 16> UpdatedDeclContexts; |
||
404 | |||
405 | /// Keeps track of declarations that we must emit, even though we're |
||
406 | /// not guaranteed to be able to find them by walking the AST starting at the |
||
407 | /// translation unit. |
||
408 | SmallVector<const Decl *, 16> DeclsToEmitEvenIfUnreferenced; |
||
409 | |||
410 | /// The set of Objective-C class that have categories we |
||
411 | /// should serialize. |
||
412 | llvm::SetVector<ObjCInterfaceDecl *> ObjCClassesWithCategories; |
||
413 | |||
414 | /// The set of declarations that may have redeclaration chains that |
||
415 | /// need to be serialized. |
||
416 | llvm::SmallVector<const Decl *, 16> Redeclarations; |
||
417 | |||
418 | /// A cache of the first local declaration for "interesting" |
||
419 | /// redeclaration chains. |
||
420 | llvm::DenseMap<const Decl *, const Decl *> FirstLocalDeclCache; |
||
421 | |||
422 | /// Mapping from SwitchCase statements to IDs. |
||
423 | llvm::DenseMap<SwitchCase *, unsigned> SwitchCaseIDs; |
||
424 | |||
425 | /// The number of statements written to the AST file. |
||
426 | unsigned NumStatements = 0; |
||
427 | |||
428 | /// The number of macros written to the AST file. |
||
429 | unsigned NumMacros = 0; |
||
430 | |||
431 | /// The number of lexical declcontexts written to the AST |
||
432 | /// file. |
||
433 | unsigned NumLexicalDeclContexts = 0; |
||
434 | |||
435 | /// The number of visible declcontexts written to the AST |
||
436 | /// file. |
||
437 | unsigned NumVisibleDeclContexts = 0; |
||
438 | |||
439 | /// A mapping from each known submodule to its ID number, which will |
||
440 | /// be a positive integer. |
||
441 | llvm::DenseMap<const Module *, unsigned> SubmoduleIDs; |
||
442 | |||
443 | /// A list of the module file extension writers. |
||
444 | std::vector<std::unique_ptr<ModuleFileExtensionWriter>> |
||
445 | ModuleFileExtensionWriters; |
||
446 | |||
447 | /// Mapping from a source location entry to whether it is affecting or not. |
||
448 | llvm::BitVector IsSLocAffecting; |
||
449 | |||
450 | /// Mapping from \c FileID to an index into the FileID adjustment table. |
||
451 | std::vector<FileID> NonAffectingFileIDs; |
||
452 | std::vector<unsigned> NonAffectingFileIDAdjustments; |
||
453 | |||
454 | /// Mapping from an offset to an index into the offset adjustment table. |
||
455 | std::vector<SourceRange> NonAffectingRanges; |
||
456 | std::vector<SourceLocation::UIntTy> NonAffectingOffsetAdjustments; |
||
457 | |||
458 | /// Collects input files that didn't affect compilation of the current module, |
||
459 | /// and initializes data structures necessary for leaving those files out |
||
460 | /// during \c SourceManager serialization. |
||
461 | void collectNonAffectingInputFiles(); |
||
462 | |||
463 | /// Returns an adjusted \c FileID, accounting for any non-affecting input |
||
464 | /// files. |
||
465 | FileID getAdjustedFileID(FileID FID) const; |
||
466 | /// Returns an adjusted number of \c FileIDs created within the specified \c |
||
467 | /// FileID, accounting for any non-affecting input files. |
||
468 | unsigned getAdjustedNumCreatedFIDs(FileID FID) const; |
||
469 | /// Returns an adjusted \c SourceLocation, accounting for any non-affecting |
||
470 | /// input files. |
||
471 | SourceLocation getAdjustedLocation(SourceLocation Loc) const; |
||
472 | /// Returns an adjusted \c SourceRange, accounting for any non-affecting input |
||
473 | /// files. |
||
474 | SourceRange getAdjustedRange(SourceRange Range) const; |
||
475 | /// Returns an adjusted \c SourceLocation offset, accounting for any |
||
476 | /// non-affecting input files. |
||
477 | SourceLocation::UIntTy getAdjustedOffset(SourceLocation::UIntTy Offset) const; |
||
478 | /// Returns an adjustment for offset into SourceManager, accounting for any |
||
479 | /// non-affecting input files. |
||
480 | SourceLocation::UIntTy getAdjustment(SourceLocation::UIntTy Offset) const; |
||
481 | |||
482 | /// Retrieve or create a submodule ID for this module. |
||
483 | unsigned getSubmoduleID(Module *Mod); |
||
484 | |||
485 | /// Write the given subexpression to the bitstream. |
||
486 | void WriteSubStmt(Stmt *S); |
||
487 | |||
488 | void WriteBlockInfoBlock(); |
||
489 | void WriteControlBlock(Preprocessor &PP, ASTContext &Context, |
||
490 | StringRef isysroot); |
||
491 | |||
492 | /// Write out the signature and diagnostic options, and return the signature. |
||
493 | ASTFileSignature writeUnhashedControlBlock(Preprocessor &PP, |
||
494 | ASTContext &Context); |
||
495 | |||
496 | /// Calculate hash of the pcm content. |
||
497 | static std::pair<ASTFileSignature, ASTFileSignature> |
||
498 | createSignature(StringRef AllBytes, StringRef ASTBlockBytes); |
||
499 | |||
500 | void WriteInputFiles(SourceManager &SourceMgr, HeaderSearchOptions &HSOpts); |
||
501 | void WriteSourceManagerBlock(SourceManager &SourceMgr, |
||
502 | const Preprocessor &PP); |
||
503 | void writeIncludedFiles(raw_ostream &Out, const Preprocessor &PP); |
||
504 | void WritePreprocessor(const Preprocessor &PP, bool IsModule); |
||
505 | void WriteHeaderSearch(const HeaderSearch &HS); |
||
506 | void WritePreprocessorDetail(PreprocessingRecord &PPRec, |
||
507 | uint64_t MacroOffsetsBase); |
||
508 | void WriteSubmodules(Module *WritingModule); |
||
509 | |||
510 | void WritePragmaDiagnosticMappings(const DiagnosticsEngine &Diag, |
||
511 | bool isModule); |
||
512 | |||
513 | unsigned TypeExtQualAbbrev = 0; |
||
514 | void WriteTypeAbbrevs(); |
||
515 | void WriteType(QualType T); |
||
516 | |||
517 | bool isLookupResultExternal(StoredDeclsList &Result, DeclContext *DC); |
||
518 | bool isLookupResultEntirelyExternal(StoredDeclsList &Result, DeclContext *DC); |
||
519 | |||
520 | void GenerateNameLookupTable(const DeclContext *DC, |
||
521 | llvm::SmallVectorImpl<char> &LookupTable); |
||
522 | uint64_t WriteDeclContextLexicalBlock(ASTContext &Context, DeclContext *DC); |
||
523 | uint64_t WriteDeclContextVisibleBlock(ASTContext &Context, DeclContext *DC); |
||
524 | void WriteTypeDeclOffsets(); |
||
525 | void WriteFileDeclIDsMap(); |
||
526 | void WriteComments(); |
||
527 | void WriteSelectors(Sema &SemaRef); |
||
528 | void WriteReferencedSelectorsPool(Sema &SemaRef); |
||
529 | void WriteIdentifierTable(Preprocessor &PP, IdentifierResolver &IdResolver, |
||
530 | bool IsModule); |
||
531 | void WriteDeclUpdatesBlocks(RecordDataImpl &OffsetsRecord); |
||
532 | void WriteDeclContextVisibleUpdate(const DeclContext *DC); |
||
533 | void WriteFPPragmaOptions(const FPOptionsOverride &Opts); |
||
534 | void WriteOpenCLExtensions(Sema &SemaRef); |
||
535 | void WriteCUDAPragmas(Sema &SemaRef); |
||
536 | void WriteObjCCategories(); |
||
537 | void WriteLateParsedTemplates(Sema &SemaRef); |
||
538 | void WriteOptimizePragmaOptions(Sema &SemaRef); |
||
539 | void WriteMSStructPragmaOptions(Sema &SemaRef); |
||
540 | void WriteMSPointersToMembersPragmaOptions(Sema &SemaRef); |
||
541 | void WritePackPragmaOptions(Sema &SemaRef); |
||
542 | void WriteFloatControlPragmaOptions(Sema &SemaRef); |
||
543 | void WriteModuleFileExtension(Sema &SemaRef, |
||
544 | ModuleFileExtensionWriter &Writer); |
||
545 | |||
546 | unsigned DeclParmVarAbbrev = 0; |
||
547 | unsigned DeclContextLexicalAbbrev = 0; |
||
548 | unsigned DeclContextVisibleLookupAbbrev = 0; |
||
549 | unsigned UpdateVisibleAbbrev = 0; |
||
550 | unsigned DeclRecordAbbrev = 0; |
||
551 | unsigned DeclTypedefAbbrev = 0; |
||
552 | unsigned DeclVarAbbrev = 0; |
||
553 | unsigned DeclFieldAbbrev = 0; |
||
554 | unsigned DeclEnumAbbrev = 0; |
||
555 | unsigned DeclObjCIvarAbbrev = 0; |
||
556 | unsigned DeclCXXMethodAbbrev = 0; |
||
557 | |||
558 | unsigned DeclRefExprAbbrev = 0; |
||
559 | unsigned CharacterLiteralAbbrev = 0; |
||
560 | unsigned IntegerLiteralAbbrev = 0; |
||
561 | unsigned ExprImplicitCastAbbrev = 0; |
||
562 | |||
563 | void WriteDeclAbbrevs(); |
||
564 | void WriteDecl(ASTContext &Context, Decl *D); |
||
565 | |||
566 | ASTFileSignature WriteASTCore(Sema &SemaRef, StringRef isysroot, |
||
567 | Module *WritingModule); |
||
568 | |||
569 | public: |
||
570 | /// Create a new precompiled header writer that outputs to |
||
571 | /// the given bitstream. |
||
572 | ASTWriter(llvm::BitstreamWriter &Stream, SmallVectorImpl<char> &Buffer, |
||
573 | InMemoryModuleCache &ModuleCache, |
||
574 | ArrayRef<std::shared_ptr<ModuleFileExtension>> Extensions, |
||
575 | bool IncludeTimestamps = true); |
||
576 | ~ASTWriter() override; |
||
577 | |||
578 | ASTContext &getASTContext() const { |
||
579 | assert(Context && "requested AST context when not writing AST"); |
||
580 | return *Context; |
||
581 | } |
||
582 | |||
583 | const LangOptions &getLangOpts() const; |
||
584 | |||
585 | /// Get a timestamp for output into the AST file. The actual timestamp |
||
586 | /// of the specified file may be ignored if we have been instructed to not |
||
587 | /// include timestamps in the output file. |
||
588 | time_t getTimestampForOutput(const FileEntry *E) const; |
||
589 | |||
590 | /// Write a precompiled header for the given semantic analysis. |
||
591 | /// |
||
592 | /// \param SemaRef a reference to the semantic analysis object that processed |
||
593 | /// the AST to be written into the precompiled header. |
||
594 | /// |
||
595 | /// \param WritingModule The module that we are writing. If null, we are |
||
596 | /// writing a precompiled header. |
||
597 | /// |
||
598 | /// \param isysroot if non-empty, write a relocatable file whose headers |
||
599 | /// are relative to the given system root. If we're writing a module, its |
||
600 | /// build directory will be used in preference to this if both are available. |
||
601 | /// |
||
602 | /// \return the module signature, which eventually will be a hash of |
||
603 | /// the module but currently is merely a random 32-bit number. |
||
604 | ASTFileSignature WriteAST(Sema &SemaRef, StringRef OutputFile, |
||
605 | Module *WritingModule, StringRef isysroot, |
||
606 | bool hasErrors = false, |
||
607 | bool ShouldCacheASTInMemory = false); |
||
608 | |||
609 | /// Emit a token. |
||
610 | void AddToken(const Token &Tok, RecordDataImpl &Record); |
||
611 | |||
612 | /// Emit a AlignPackInfo. |
||
613 | void AddAlignPackInfo(const Sema::AlignPackInfo &Info, |
||
614 | RecordDataImpl &Record); |
||
615 | |||
616 | /// Emit a FileID. |
||
617 | void AddFileID(FileID FID, RecordDataImpl &Record); |
||
618 | |||
619 | /// Emit a source location. |
||
620 | void AddSourceLocation(SourceLocation Loc, RecordDataImpl &Record, |
||
621 | LocSeq *Seq = nullptr); |
||
622 | |||
623 | /// Emit a source range. |
||
624 | void AddSourceRange(SourceRange Range, RecordDataImpl &Record, |
||
625 | LocSeq *Seq = nullptr); |
||
626 | |||
627 | /// Emit a reference to an identifier. |
||
628 | void AddIdentifierRef(const IdentifierInfo *II, RecordDataImpl &Record); |
||
629 | |||
630 | /// Get the unique number used to refer to the given selector. |
||
631 | serialization::SelectorID getSelectorRef(Selector Sel); |
||
632 | |||
633 | /// Get the unique number used to refer to the given identifier. |
||
634 | serialization::IdentID getIdentifierRef(const IdentifierInfo *II); |
||
635 | |||
636 | /// Get the unique number used to refer to the given macro. |
||
637 | serialization::MacroID getMacroRef(MacroInfo *MI, const IdentifierInfo *Name); |
||
638 | |||
639 | /// Determine the ID of an already-emitted macro. |
||
640 | serialization::MacroID getMacroID(MacroInfo *MI); |
||
641 | |||
642 | uint32_t getMacroDirectivesOffset(const IdentifierInfo *Name); |
||
643 | |||
644 | /// Emit a reference to a type. |
||
645 | void AddTypeRef(QualType T, RecordDataImpl &Record); |
||
646 | |||
647 | /// Force a type to be emitted and get its ID. |
||
648 | serialization::TypeID GetOrCreateTypeID(QualType T); |
||
649 | |||
650 | /// Determine the type ID of an already-emitted type. |
||
651 | serialization::TypeID getTypeID(QualType T) const; |
||
652 | |||
653 | /// Find the first local declaration of a given local redeclarable |
||
654 | /// decl. |
||
655 | const Decl *getFirstLocalDecl(const Decl *D); |
||
656 | |||
657 | /// Is this a local declaration (that is, one that will be written to |
||
658 | /// our AST file)? This is the case for declarations that are neither imported |
||
659 | /// from another AST file nor predefined. |
||
660 | bool IsLocalDecl(const Decl *D) { |
||
661 | if (D->isFromASTFile()) |
||
662 | return false; |
||
663 | auto I = DeclIDs.find(D); |
||
664 | return (I == DeclIDs.end() || |
||
665 | I->second >= serialization::NUM_PREDEF_DECL_IDS); |
||
666 | }; |
||
667 | |||
668 | /// Emit a reference to a declaration. |
||
669 | void AddDeclRef(const Decl *D, RecordDataImpl &Record); |
||
670 | |||
671 | /// Force a declaration to be emitted and get its ID. |
||
672 | serialization::DeclID GetDeclRef(const Decl *D); |
||
673 | |||
674 | /// Determine the declaration ID of an already-emitted |
||
675 | /// declaration. |
||
676 | serialization::DeclID getDeclID(const Decl *D); |
||
677 | |||
678 | unsigned getAnonymousDeclarationNumber(const NamedDecl *D); |
||
679 | |||
680 | /// Add a string to the given record. |
||
681 | void AddString(StringRef Str, RecordDataImpl &Record); |
||
682 | |||
683 | /// Convert a path from this build process into one that is appropriate |
||
684 | /// for emission in the module file. |
||
685 | bool PreparePathForOutput(SmallVectorImpl<char> &Path); |
||
686 | |||
687 | /// Add a path to the given record. |
||
688 | void AddPath(StringRef Path, RecordDataImpl &Record); |
||
689 | |||
690 | /// Emit the current record with the given path as a blob. |
||
691 | void EmitRecordWithPath(unsigned Abbrev, RecordDataRef Record, |
||
692 | StringRef Path); |
||
693 | |||
694 | /// Add a version tuple to the given record |
||
695 | void AddVersionTuple(const VersionTuple &Version, RecordDataImpl &Record); |
||
696 | |||
697 | /// Retrieve or create a submodule ID for this module, or return 0 if |
||
698 | /// the submodule is neither local (a submodle of the currently-written module) |
||
699 | /// nor from an imported module. |
||
700 | unsigned getLocalOrImportedSubmoduleID(const Module *Mod); |
||
701 | |||
702 | /// Note that the identifier II occurs at the given offset |
||
703 | /// within the identifier table. |
||
704 | void SetIdentifierOffset(const IdentifierInfo *II, uint32_t Offset); |
||
705 | |||
706 | /// Note that the selector Sel occurs at the given offset |
||
707 | /// within the method pool/selector table. |
||
708 | void SetSelectorOffset(Selector Sel, uint32_t Offset); |
||
709 | |||
710 | /// Record an ID for the given switch-case statement. |
||
711 | unsigned RecordSwitchCaseID(SwitchCase *S); |
||
712 | |||
713 | /// Retrieve the ID for the given switch-case statement. |
||
714 | unsigned getSwitchCaseID(SwitchCase *S); |
||
715 | |||
716 | void ClearSwitchCaseIDs(); |
||
717 | |||
718 | unsigned getTypeExtQualAbbrev() const { |
||
719 | return TypeExtQualAbbrev; |
||
720 | } |
||
721 | |||
722 | unsigned getDeclParmVarAbbrev() const { return DeclParmVarAbbrev; } |
||
723 | unsigned getDeclRecordAbbrev() const { return DeclRecordAbbrev; } |
||
724 | unsigned getDeclTypedefAbbrev() const { return DeclTypedefAbbrev; } |
||
725 | unsigned getDeclVarAbbrev() const { return DeclVarAbbrev; } |
||
726 | unsigned getDeclFieldAbbrev() const { return DeclFieldAbbrev; } |
||
727 | unsigned getDeclEnumAbbrev() const { return DeclEnumAbbrev; } |
||
728 | unsigned getDeclObjCIvarAbbrev() const { return DeclObjCIvarAbbrev; } |
||
729 | unsigned getDeclCXXMethodAbbrev() const { return DeclCXXMethodAbbrev; } |
||
730 | |||
731 | unsigned getDeclRefExprAbbrev() const { return DeclRefExprAbbrev; } |
||
732 | unsigned getCharacterLiteralAbbrev() const { return CharacterLiteralAbbrev; } |
||
733 | unsigned getIntegerLiteralAbbrev() const { return IntegerLiteralAbbrev; } |
||
734 | unsigned getExprImplicitCastAbbrev() const { return ExprImplicitCastAbbrev; } |
||
735 | |||
736 | bool hasChain() const { return Chain; } |
||
737 | ASTReader *getChain() const { return Chain; } |
||
738 | |||
739 | bool isWritingStdCXXNamedModules() const { |
||
740 | return WritingModule && WritingModule->isModulePurview(); |
||
741 | } |
||
742 | |||
743 | private: |
||
744 | // ASTDeserializationListener implementation |
||
745 | void ReaderInitialized(ASTReader *Reader) override; |
||
746 | void IdentifierRead(serialization::IdentID ID, IdentifierInfo *II) override; |
||
747 | void MacroRead(serialization::MacroID ID, MacroInfo *MI) override; |
||
748 | void TypeRead(serialization::TypeIdx Idx, QualType T) override; |
||
749 | void SelectorRead(serialization::SelectorID ID, Selector Sel) override; |
||
750 | void MacroDefinitionRead(serialization::PreprocessedEntityID ID, |
||
751 | MacroDefinitionRecord *MD) override; |
||
752 | void ModuleRead(serialization::SubmoduleID ID, Module *Mod) override; |
||
753 | |||
754 | // ASTMutationListener implementation. |
||
755 | void CompletedTagDefinition(const TagDecl *D) override; |
||
756 | void AddedVisibleDecl(const DeclContext *DC, const Decl *D) override; |
||
757 | void AddedCXXImplicitMember(const CXXRecordDecl *RD, const Decl *D) override; |
||
758 | void AddedCXXTemplateSpecialization( |
||
759 | const ClassTemplateDecl *TD, |
||
760 | const ClassTemplateSpecializationDecl *D) override; |
||
761 | void AddedCXXTemplateSpecialization( |
||
762 | const VarTemplateDecl *TD, |
||
763 | const VarTemplateSpecializationDecl *D) override; |
||
764 | void AddedCXXTemplateSpecialization(const FunctionTemplateDecl *TD, |
||
765 | const FunctionDecl *D) override; |
||
766 | void ResolvedExceptionSpec(const FunctionDecl *FD) override; |
||
767 | void DeducedReturnType(const FunctionDecl *FD, QualType ReturnType) override; |
||
768 | void ResolvedOperatorDelete(const CXXDestructorDecl *DD, |
||
769 | const FunctionDecl *Delete, |
||
770 | Expr *ThisArg) override; |
||
771 | void CompletedImplicitDefinition(const FunctionDecl *D) override; |
||
772 | void InstantiationRequested(const ValueDecl *D) override; |
||
773 | void VariableDefinitionInstantiated(const VarDecl *D) override; |
||
774 | void FunctionDefinitionInstantiated(const FunctionDecl *D) override; |
||
775 | void DefaultArgumentInstantiated(const ParmVarDecl *D) override; |
||
776 | void DefaultMemberInitializerInstantiated(const FieldDecl *D) override; |
||
777 | void AddedObjCCategoryToInterface(const ObjCCategoryDecl *CatD, |
||
778 | const ObjCInterfaceDecl *IFD) override; |
||
779 | void DeclarationMarkedUsed(const Decl *D) override; |
||
780 | void DeclarationMarkedOpenMPThreadPrivate(const Decl *D) override; |
||
781 | void DeclarationMarkedOpenMPDeclareTarget(const Decl *D, |
||
782 | const Attr *Attr) override; |
||
783 | void DeclarationMarkedOpenMPAllocate(const Decl *D, const Attr *A) override; |
||
784 | void RedefinedHiddenDefinition(const NamedDecl *D, Module *M) override; |
||
785 | void AddedAttributeToRecord(const Attr *Attr, |
||
786 | const RecordDecl *Record) override; |
||
787 | }; |
||
788 | |||
789 | /// AST and semantic-analysis consumer that generates a |
||
790 | /// precompiled header from the parsed source code. |
||
791 | class PCHGenerator : public SemaConsumer { |
||
792 | const Preprocessor &PP; |
||
793 | std::string OutputFile; |
||
794 | std::string isysroot; |
||
795 | Sema *SemaPtr; |
||
796 | std::shared_ptr<PCHBuffer> Buffer; |
||
797 | llvm::BitstreamWriter Stream; |
||
798 | ASTWriter Writer; |
||
799 | bool AllowASTWithErrors; |
||
800 | bool ShouldCacheASTInMemory; |
||
801 | |||
802 | protected: |
||
803 | ASTWriter &getWriter() { return Writer; } |
||
804 | const ASTWriter &getWriter() const { return Writer; } |
||
805 | SmallVectorImpl<char> &getPCH() const { return Buffer->Data; } |
||
806 | |||
807 | public: |
||
808 | PCHGenerator(const Preprocessor &PP, InMemoryModuleCache &ModuleCache, |
||
809 | StringRef OutputFile, StringRef isysroot, |
||
810 | std::shared_ptr<PCHBuffer> Buffer, |
||
811 | ArrayRef<std::shared_ptr<ModuleFileExtension>> Extensions, |
||
812 | bool AllowASTWithErrors = false, bool IncludeTimestamps = true, |
||
813 | bool ShouldCacheASTInMemory = false); |
||
814 | ~PCHGenerator() override; |
||
815 | |||
816 | void InitializeSema(Sema &S) override { SemaPtr = &S; } |
||
817 | void HandleTranslationUnit(ASTContext &Ctx) override; |
||
818 | ASTMutationListener *GetASTMutationListener() override; |
||
819 | ASTDeserializationListener *GetASTDeserializationListener() override; |
||
820 | bool hasEmittedPCH() const { return Buffer->IsComplete; } |
||
821 | }; |
||
822 | |||
823 | } // namespace clang |
||
824 | |||
825 | #endif // LLVM_CLANG_SERIALIZATION_ASTWRITER_H |