1//===- ASTWriter.cpp - AST File Writer ------------------------------------===//
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 AST files.
10//
11//===----------------------------------------------------------------------===//
12
13#include "ASTCommon.h"
14#include "ASTReaderInternals.h"
15#include "MultiOnDiskHashTable.h"
16#include "TemplateArgumentHasher.h"
17#include "clang/AST/ASTContext.h"
18#include "clang/AST/ASTUnresolvedSet.h"
19#include "clang/AST/AbstractTypeWriter.h"
20#include "clang/AST/Attr.h"
21#include "clang/AST/Decl.h"
22#include "clang/AST/DeclBase.h"
23#include "clang/AST/DeclCXX.h"
24#include "clang/AST/DeclContextInternals.h"
25#include "clang/AST/DeclFriend.h"
26#include "clang/AST/DeclObjC.h"
27#include "clang/AST/DeclTemplate.h"
28#include "clang/AST/DeclarationName.h"
29#include "clang/AST/Expr.h"
30#include "clang/AST/ExprCXX.h"
31#include "clang/AST/LambdaCapture.h"
32#include "clang/AST/NestedNameSpecifier.h"
33#include "clang/AST/OpenACCClause.h"
34#include "clang/AST/OpenMPClause.h"
35#include "clang/AST/RawCommentList.h"
36#include "clang/AST/TemplateName.h"
37#include "clang/AST/Type.h"
38#include "clang/AST/TypeLoc.h"
39#include "clang/AST/TypeLocVisitor.h"
40#include "clang/Basic/Diagnostic.h"
41#include "clang/Basic/DiagnosticOptions.h"
42#include "clang/Basic/FileEntry.h"
43#include "clang/Basic/FileManager.h"
44#include "clang/Basic/FileSystemOptions.h"
45#include "clang/Basic/IdentifierTable.h"
46#include "clang/Basic/LLVM.h"
47#include "clang/Basic/Lambda.h"
48#include "clang/Basic/LangOptions.h"
49#include "clang/Basic/Module.h"
50#include "clang/Basic/ObjCRuntime.h"
51#include "clang/Basic/OpenACCKinds.h"
52#include "clang/Basic/OpenCLOptions.h"
53#include "clang/Basic/SourceLocation.h"
54#include "clang/Basic/SourceManager.h"
55#include "clang/Basic/SourceManagerInternals.h"
56#include "clang/Basic/Specifiers.h"
57#include "clang/Basic/TargetInfo.h"
58#include "clang/Basic/TargetOptions.h"
59#include "clang/Basic/Version.h"
60#include "clang/Lex/HeaderSearch.h"
61#include "clang/Lex/HeaderSearchOptions.h"
62#include "clang/Lex/MacroInfo.h"
63#include "clang/Lex/ModuleMap.h"
64#include "clang/Lex/PreprocessingRecord.h"
65#include "clang/Lex/Preprocessor.h"
66#include "clang/Lex/PreprocessorOptions.h"
67#include "clang/Lex/Token.h"
68#include "clang/Sema/IdentifierResolver.h"
69#include "clang/Sema/ObjCMethodList.h"
70#include "clang/Sema/Sema.h"
71#include "clang/Sema/SemaCUDA.h"
72#include "clang/Sema/SemaObjC.h"
73#include "clang/Sema/Weak.h"
74#include "clang/Serialization/ASTBitCodes.h"
75#include "clang/Serialization/ASTReader.h"
76#include "clang/Serialization/ASTRecordWriter.h"
77#include "clang/Serialization/InMemoryModuleCache.h"
78#include "clang/Serialization/ModuleCache.h"
79#include "clang/Serialization/ModuleFile.h"
80#include "clang/Serialization/ModuleFileExtension.h"
81#include "clang/Serialization/SerializationDiagnostic.h"
82#include "llvm/ADT/APFloat.h"
83#include "llvm/ADT/APInt.h"
84#include "llvm/ADT/ArrayRef.h"
85#include "llvm/ADT/DenseMap.h"
86#include "llvm/ADT/DenseSet.h"
87#include "llvm/ADT/PointerIntPair.h"
88#include "llvm/ADT/STLExtras.h"
89#include "llvm/ADT/ScopeExit.h"
90#include "llvm/ADT/SmallPtrSet.h"
91#include "llvm/ADT/SmallString.h"
92#include "llvm/ADT/SmallVector.h"
93#include "llvm/ADT/StringRef.h"
94#include "llvm/Bitstream/BitCodes.h"
95#include "llvm/Bitstream/BitstreamWriter.h"
96#include "llvm/Support/Compression.h"
97#include "llvm/Support/DJB.h"
98#include "llvm/Support/EndianStream.h"
99#include "llvm/Support/ErrorHandling.h"
100#include "llvm/Support/LEB128.h"
101#include "llvm/Support/MemoryBuffer.h"
102#include "llvm/Support/OnDiskHashTable.h"
103#include "llvm/Support/Path.h"
104#include "llvm/Support/SHA1.h"
105#include "llvm/Support/TimeProfiler.h"
106#include "llvm/Support/VersionTuple.h"
107#include "llvm/Support/raw_ostream.h"
108#include <algorithm>
109#include <cassert>
110#include <cstdint>
111#include <cstdlib>
112#include <cstring>
113#include <ctime>
114#include <limits>
115#include <memory>
116#include <optional>
117#include <queue>
118#include <tuple>
119#include <utility>
120#include <vector>
121
122using namespace clang;
123using namespace clang::serialization;
124
125template <typename T, typename Allocator>
126static StringRef bytes(const std::vector<T, Allocator> &v) {
127 if (v.empty()) return StringRef();
128 return StringRef(reinterpret_cast<const char*>(&v[0]),
129 sizeof(T) * v.size());
130}
131
132template <typename T>
133static StringRef bytes(const SmallVectorImpl<T> &v) {
134 return StringRef(reinterpret_cast<const char*>(v.data()),
135 sizeof(T) * v.size());
136}
137
138static std::string bytes(const std::vector<bool> &V) {
139 std::string Str;
140 Str.reserve(res_arg: V.size() / 8);
141 for (unsigned I = 0, E = V.size(); I < E;) {
142 char Byte = 0;
143 for (unsigned Bit = 0; Bit < 8 && I < E; ++Bit, ++I)
144 Byte |= V[I] << Bit;
145 Str += Byte;
146 }
147 return Str;
148}
149
150//===----------------------------------------------------------------------===//
151// Type serialization
152//===----------------------------------------------------------------------===//
153
154static TypeCode getTypeCodeForTypeClass(Type::TypeClass id) {
155 switch (id) {
156#define TYPE_BIT_CODE(CLASS_ID, CODE_ID, CODE_VALUE) \
157 case Type::CLASS_ID: return TYPE_##CODE_ID;
158#include "clang/Serialization/TypeBitCodes.def"
159 case Type::Builtin:
160 llvm_unreachable("shouldn't be serializing a builtin type this way");
161 }
162 llvm_unreachable("bad type kind");
163}
164
165namespace {
166
167struct AffectingModuleMaps {
168 llvm::DenseSet<FileID> DefinitionFileIDs;
169 llvm::DenseSet<const FileEntry *> DefinitionFiles;
170};
171
172std::optional<AffectingModuleMaps>
173GetAffectingModuleMaps(const Preprocessor &PP, Module *RootModule) {
174 if (!PP.getHeaderSearchInfo()
175 .getHeaderSearchOpts()
176 .ModulesPruneNonAffectingModuleMaps)
177 return std::nullopt;
178
179 const HeaderSearch &HS = PP.getHeaderSearchInfo();
180 const SourceManager &SM = PP.getSourceManager();
181 const ModuleMap &MM = HS.getModuleMap();
182
183 // Module maps used only by textual headers are special. Their FileID is
184 // non-affecting, but their FileEntry is (i.e. must be written as InputFile).
185 enum AffectedReason : bool {
186 AR_TextualHeader = 0,
187 AR_ImportOrTextualHeader = 1,
188 };
189 auto AssignMostImportant = [](AffectedReason &LHS, AffectedReason RHS) {
190 LHS = std::max(a: LHS, b: RHS);
191 };
192 llvm::DenseMap<FileID, AffectedReason> ModuleMaps;
193 llvm::DenseMap<const Module *, AffectedReason> ProcessedModules;
194 auto CollectModuleMapsForHierarchy = [&](const Module *M,
195 AffectedReason Reason) {
196 M = M->getTopLevelModule();
197
198 // We need to process the header either when it was not present or when we
199 // previously flagged module map as textual headers and now we found a
200 // proper import.
201 if (auto [It, Inserted] = ProcessedModules.insert(KV: {M, Reason});
202 !Inserted && Reason <= It->second) {
203 return;
204 } else {
205 It->second = Reason;
206 }
207
208 std::queue<const Module *> Q;
209 Q.push(x: M);
210 while (!Q.empty()) {
211 const Module *Mod = Q.front();
212 Q.pop();
213
214 // The containing module map is affecting, because it's being pointed
215 // into by Module::DefinitionLoc.
216 if (auto F = MM.getContainingModuleMapFileID(Module: Mod); F.isValid())
217 AssignMostImportant(ModuleMaps[F], Reason);
218 // For inferred modules, the module map that allowed inferring is not
219 // related to the virtual containing module map file. It did affect the
220 // compilation, though.
221 if (auto UniqF = MM.getModuleMapFileIDForUniquing(M: Mod); UniqF.isValid())
222 AssignMostImportant(ModuleMaps[UniqF], Reason);
223
224 for (auto *SubM : Mod->submodules())
225 Q.push(x: SubM);
226 }
227 };
228
229 // Handle all the affecting modules referenced from the root module.
230
231 CollectModuleMapsForHierarchy(RootModule, AR_ImportOrTextualHeader);
232
233 std::queue<const Module *> Q;
234 Q.push(x: RootModule);
235 while (!Q.empty()) {
236 const Module *CurrentModule = Q.front();
237 Q.pop();
238
239 for (const Module *ImportedModule : CurrentModule->Imports)
240 CollectModuleMapsForHierarchy(ImportedModule, AR_ImportOrTextualHeader);
241 for (const Module *UndeclaredModule : CurrentModule->UndeclaredUses)
242 CollectModuleMapsForHierarchy(UndeclaredModule, AR_ImportOrTextualHeader);
243
244 for (auto *M : CurrentModule->submodules())
245 Q.push(x: M);
246 }
247
248 // Handle textually-included headers that belong to other modules.
249
250 SmallVector<OptionalFileEntryRef, 16> FilesByUID;
251 HS.getFileMgr().GetUniqueIDMapping(UIDToFiles&: FilesByUID);
252
253 if (FilesByUID.size() > HS.header_file_size())
254 FilesByUID.resize(N: HS.header_file_size());
255
256 for (unsigned UID = 0, LastUID = FilesByUID.size(); UID != LastUID; ++UID) {
257 OptionalFileEntryRef File = FilesByUID[UID];
258 if (!File)
259 continue;
260
261 const HeaderFileInfo *HFI = HS.getExistingLocalFileInfo(FE: *File);
262 if (!HFI)
263 continue; // We have no information on this being a header file.
264 if (!HFI->isCompilingModuleHeader && HFI->isModuleHeader)
265 continue; // Modular header, handled in the above module-based loop.
266 if (!HFI->isCompilingModuleHeader && !HFI->IsLocallyIncluded)
267 continue; // Non-modular header not included locally is not affecting.
268
269 for (const auto &KH : HS.findResolvedModulesForHeader(File: *File))
270 if (const Module *M = KH.getModule())
271 CollectModuleMapsForHierarchy(M, AR_TextualHeader);
272 }
273
274 // FIXME: This algorithm is not correct for module map hierarchies where
275 // module map file defining a (sub)module of a top-level module X includes
276 // a module map file that defines a (sub)module of another top-level module Y.
277 // Whenever X is affecting and Y is not, "replaying" this PCM file will fail
278 // when parsing module map files for X due to not knowing about the `extern`
279 // module map for Y.
280 //
281 // We don't have a good way to fix it here. We could mark all children of
282 // affecting module map files as being affecting as well, but that's
283 // expensive. SourceManager does not model the edge from parent to child
284 // SLocEntries, so instead, we would need to iterate over leaf module map
285 // files, walk up their include hierarchy and check whether we arrive at an
286 // affecting module map.
287 //
288 // Instead of complicating and slowing down this function, we should probably
289 // just ban module map hierarchies where module map defining a (sub)module X
290 // includes a module map defining a module that's not a submodule of X.
291
292 llvm::DenseSet<const FileEntry *> ModuleFileEntries;
293 llvm::DenseSet<FileID> ModuleFileIDs;
294 for (auto [FID, Reason] : ModuleMaps) {
295 if (Reason == AR_ImportOrTextualHeader)
296 ModuleFileIDs.insert(V: FID);
297 if (auto *FE = SM.getFileEntryForID(FID))
298 ModuleFileEntries.insert(V: FE);
299 }
300
301 AffectingModuleMaps R;
302 R.DefinitionFileIDs = std::move(ModuleFileIDs);
303 R.DefinitionFiles = std::move(ModuleFileEntries);
304 return std::move(R);
305}
306
307class ASTTypeWriter {
308 ASTWriter &Writer;
309 ASTWriter::RecordData Record;
310 ASTRecordWriter BasicWriter;
311
312public:
313 ASTTypeWriter(ASTContext &Context, ASTWriter &Writer)
314 : Writer(Writer), BasicWriter(Context, Writer, Record) {}
315
316 uint64_t write(QualType T) {
317 if (T.hasLocalNonFastQualifiers()) {
318 Qualifiers Qs = T.getLocalQualifiers();
319 BasicWriter.writeQualType(T: T.getLocalUnqualifiedType());
320 BasicWriter.writeQualifiers(value: Qs);
321 return BasicWriter.Emit(Code: TYPE_EXT_QUAL, Abbrev: Writer.getTypeExtQualAbbrev());
322 }
323
324 const Type *typePtr = T.getTypePtr();
325 serialization::AbstractTypeWriter<ASTRecordWriter> atw(BasicWriter);
326 atw.write(node: typePtr);
327 return BasicWriter.Emit(Code: getTypeCodeForTypeClass(id: typePtr->getTypeClass()),
328 /*abbrev*/ Abbrev: 0);
329 }
330};
331
332class TypeLocWriter : public TypeLocVisitor<TypeLocWriter> {
333 ASTRecordWriter &Record;
334
335 void addSourceLocation(SourceLocation Loc) { Record.AddSourceLocation(Loc); }
336 void addSourceRange(SourceRange Range) { Record.AddSourceRange(Range); }
337
338public:
339 TypeLocWriter(ASTRecordWriter &Record) : Record(Record) {}
340
341#define ABSTRACT_TYPELOC(CLASS, PARENT)
342#define TYPELOC(CLASS, PARENT) \
343 void Visit##CLASS##TypeLoc(CLASS##TypeLoc TyLoc);
344#include "clang/AST/TypeLocNodes.def"
345
346 void VisitArrayTypeLoc(ArrayTypeLoc TyLoc);
347 void VisitFunctionTypeLoc(FunctionTypeLoc TyLoc);
348 void VisitTagTypeLoc(TagTypeLoc TL);
349};
350
351} // namespace
352
353void TypeLocWriter::VisitQualifiedTypeLoc(QualifiedTypeLoc TL) {
354 // nothing to do
355}
356
357void TypeLocWriter::VisitBuiltinTypeLoc(BuiltinTypeLoc TL) {
358 addSourceLocation(Loc: TL.getBuiltinLoc());
359 if (TL.needsExtraLocalData()) {
360 Record.push_back(N: TL.getWrittenTypeSpec());
361 Record.push_back(N: static_cast<uint64_t>(TL.getWrittenSignSpec()));
362 Record.push_back(N: static_cast<uint64_t>(TL.getWrittenWidthSpec()));
363 Record.push_back(N: TL.hasModeAttr());
364 }
365}
366
367void TypeLocWriter::VisitComplexTypeLoc(ComplexTypeLoc TL) {
368 addSourceLocation(Loc: TL.getNameLoc());
369}
370
371void TypeLocWriter::VisitPointerTypeLoc(PointerTypeLoc TL) {
372 addSourceLocation(Loc: TL.getStarLoc());
373}
374
375void TypeLocWriter::VisitDecayedTypeLoc(DecayedTypeLoc TL) {
376 // nothing to do
377}
378
379void TypeLocWriter::VisitAdjustedTypeLoc(AdjustedTypeLoc TL) {
380 // nothing to do
381}
382
383void TypeLocWriter::VisitArrayParameterTypeLoc(ArrayParameterTypeLoc TL) {
384 // nothing to do
385}
386
387void TypeLocWriter::VisitBlockPointerTypeLoc(BlockPointerTypeLoc TL) {
388 addSourceLocation(Loc: TL.getCaretLoc());
389}
390
391void TypeLocWriter::VisitLValueReferenceTypeLoc(LValueReferenceTypeLoc TL) {
392 addSourceLocation(Loc: TL.getAmpLoc());
393}
394
395void TypeLocWriter::VisitRValueReferenceTypeLoc(RValueReferenceTypeLoc TL) {
396 addSourceLocation(Loc: TL.getAmpAmpLoc());
397}
398
399void TypeLocWriter::VisitMemberPointerTypeLoc(MemberPointerTypeLoc TL) {
400 addSourceLocation(Loc: TL.getStarLoc());
401 Record.AddNestedNameSpecifierLoc(NNS: TL.getQualifierLoc());
402}
403
404void TypeLocWriter::VisitArrayTypeLoc(ArrayTypeLoc TL) {
405 addSourceLocation(Loc: TL.getLBracketLoc());
406 addSourceLocation(Loc: TL.getRBracketLoc());
407 Record.push_back(N: TL.getSizeExpr() ? 1 : 0);
408 if (TL.getSizeExpr())
409 Record.AddStmt(S: TL.getSizeExpr());
410}
411
412void TypeLocWriter::VisitConstantArrayTypeLoc(ConstantArrayTypeLoc TL) {
413 VisitArrayTypeLoc(TL);
414}
415
416void TypeLocWriter::VisitIncompleteArrayTypeLoc(IncompleteArrayTypeLoc TL) {
417 VisitArrayTypeLoc(TL);
418}
419
420void TypeLocWriter::VisitVariableArrayTypeLoc(VariableArrayTypeLoc TL) {
421 VisitArrayTypeLoc(TL);
422}
423
424void TypeLocWriter::VisitDependentSizedArrayTypeLoc(
425 DependentSizedArrayTypeLoc TL) {
426 VisitArrayTypeLoc(TL);
427}
428
429void TypeLocWriter::VisitDependentAddressSpaceTypeLoc(
430 DependentAddressSpaceTypeLoc TL) {
431 addSourceLocation(Loc: TL.getAttrNameLoc());
432 SourceRange range = TL.getAttrOperandParensRange();
433 addSourceLocation(Loc: range.getBegin());
434 addSourceLocation(Loc: range.getEnd());
435 Record.AddStmt(S: TL.getAttrExprOperand());
436}
437
438void TypeLocWriter::VisitDependentSizedExtVectorTypeLoc(
439 DependentSizedExtVectorTypeLoc TL) {
440 addSourceLocation(Loc: TL.getNameLoc());
441}
442
443void TypeLocWriter::VisitVectorTypeLoc(VectorTypeLoc TL) {
444 addSourceLocation(Loc: TL.getNameLoc());
445}
446
447void TypeLocWriter::VisitDependentVectorTypeLoc(
448 DependentVectorTypeLoc TL) {
449 addSourceLocation(Loc: TL.getNameLoc());
450}
451
452void TypeLocWriter::VisitExtVectorTypeLoc(ExtVectorTypeLoc TL) {
453 addSourceLocation(Loc: TL.getNameLoc());
454}
455
456void TypeLocWriter::VisitConstantMatrixTypeLoc(ConstantMatrixTypeLoc TL) {
457 addSourceLocation(Loc: TL.getAttrNameLoc());
458 SourceRange range = TL.getAttrOperandParensRange();
459 addSourceLocation(Loc: range.getBegin());
460 addSourceLocation(Loc: range.getEnd());
461 Record.AddStmt(S: TL.getAttrRowOperand());
462 Record.AddStmt(S: TL.getAttrColumnOperand());
463}
464
465void TypeLocWriter::VisitDependentSizedMatrixTypeLoc(
466 DependentSizedMatrixTypeLoc TL) {
467 addSourceLocation(Loc: TL.getAttrNameLoc());
468 SourceRange range = TL.getAttrOperandParensRange();
469 addSourceLocation(Loc: range.getBegin());
470 addSourceLocation(Loc: range.getEnd());
471 Record.AddStmt(S: TL.getAttrRowOperand());
472 Record.AddStmt(S: TL.getAttrColumnOperand());
473}
474
475void TypeLocWriter::VisitFunctionTypeLoc(FunctionTypeLoc TL) {
476 addSourceLocation(Loc: TL.getLocalRangeBegin());
477 addSourceLocation(Loc: TL.getLParenLoc());
478 addSourceLocation(Loc: TL.getRParenLoc());
479 addSourceRange(Range: TL.getExceptionSpecRange());
480 addSourceLocation(Loc: TL.getLocalRangeEnd());
481 for (unsigned i = 0, e = TL.getNumParams(); i != e; ++i)
482 Record.AddDeclRef(D: TL.getParam(i));
483}
484
485void TypeLocWriter::VisitFunctionProtoTypeLoc(FunctionProtoTypeLoc TL) {
486 VisitFunctionTypeLoc(TL);
487}
488
489void TypeLocWriter::VisitFunctionNoProtoTypeLoc(FunctionNoProtoTypeLoc TL) {
490 VisitFunctionTypeLoc(TL);
491}
492
493void TypeLocWriter::VisitUnresolvedUsingTypeLoc(UnresolvedUsingTypeLoc TL) {
494 addSourceLocation(Loc: TL.getElaboratedKeywordLoc());
495 Record.AddNestedNameSpecifierLoc(NNS: TL.getQualifierLoc());
496 addSourceLocation(Loc: TL.getNameLoc());
497}
498
499void TypeLocWriter::VisitUsingTypeLoc(UsingTypeLoc TL) {
500 addSourceLocation(Loc: TL.getElaboratedKeywordLoc());
501 Record.AddNestedNameSpecifierLoc(NNS: TL.getQualifierLoc());
502 addSourceLocation(Loc: TL.getNameLoc());
503}
504
505void TypeLocWriter::VisitTypedefTypeLoc(TypedefTypeLoc TL) {
506 addSourceLocation(Loc: TL.getElaboratedKeywordLoc());
507 Record.AddNestedNameSpecifierLoc(NNS: TL.getQualifierLoc());
508 addSourceLocation(Loc: TL.getNameLoc());
509}
510
511void TypeLocWriter::VisitObjCTypeParamTypeLoc(ObjCTypeParamTypeLoc TL) {
512 if (TL.getNumProtocols()) {
513 addSourceLocation(Loc: TL.getProtocolLAngleLoc());
514 addSourceLocation(Loc: TL.getProtocolRAngleLoc());
515 }
516 for (unsigned i = 0, e = TL.getNumProtocols(); i != e; ++i)
517 addSourceLocation(Loc: TL.getProtocolLoc(i));
518}
519
520void TypeLocWriter::VisitTypeOfExprTypeLoc(TypeOfExprTypeLoc TL) {
521 addSourceLocation(Loc: TL.getTypeofLoc());
522 addSourceLocation(Loc: TL.getLParenLoc());
523 addSourceLocation(Loc: TL.getRParenLoc());
524}
525
526void TypeLocWriter::VisitTypeOfTypeLoc(TypeOfTypeLoc TL) {
527 addSourceLocation(Loc: TL.getTypeofLoc());
528 addSourceLocation(Loc: TL.getLParenLoc());
529 addSourceLocation(Loc: TL.getRParenLoc());
530 Record.AddTypeSourceInfo(TInfo: TL.getUnmodifiedTInfo());
531}
532
533void TypeLocWriter::VisitDecltypeTypeLoc(DecltypeTypeLoc TL) {
534 addSourceLocation(Loc: TL.getDecltypeLoc());
535 addSourceLocation(Loc: TL.getRParenLoc());
536}
537
538void TypeLocWriter::VisitUnaryTransformTypeLoc(UnaryTransformTypeLoc TL) {
539 addSourceLocation(Loc: TL.getKWLoc());
540 addSourceLocation(Loc: TL.getLParenLoc());
541 addSourceLocation(Loc: TL.getRParenLoc());
542 Record.AddTypeSourceInfo(TInfo: TL.getUnderlyingTInfo());
543}
544
545void ASTRecordWriter::AddConceptReference(const ConceptReference *CR) {
546 assert(CR);
547 AddNestedNameSpecifierLoc(NNS: CR->getNestedNameSpecifierLoc());
548 AddSourceLocation(Loc: CR->getTemplateKWLoc());
549 AddDeclarationNameInfo(NameInfo: CR->getConceptNameInfo());
550 AddDeclRef(D: CR->getFoundDecl());
551 AddDeclRef(D: CR->getNamedConcept());
552 push_back(N: CR->getTemplateArgsAsWritten() != nullptr);
553 if (CR->getTemplateArgsAsWritten())
554 AddASTTemplateArgumentListInfo(ASTTemplArgList: CR->getTemplateArgsAsWritten());
555}
556
557void TypeLocWriter::VisitPackIndexingTypeLoc(PackIndexingTypeLoc TL) {
558 addSourceLocation(Loc: TL.getEllipsisLoc());
559}
560
561void TypeLocWriter::VisitAutoTypeLoc(AutoTypeLoc TL) {
562 addSourceLocation(Loc: TL.getNameLoc());
563 auto *CR = TL.getConceptReference();
564 Record.push_back(N: TL.isConstrained() && CR);
565 if (TL.isConstrained() && CR)
566 Record.AddConceptReference(CR);
567 Record.push_back(N: TL.isDecltypeAuto());
568 if (TL.isDecltypeAuto())
569 addSourceLocation(Loc: TL.getRParenLoc());
570}
571
572void TypeLocWriter::VisitDeducedTemplateSpecializationTypeLoc(
573 DeducedTemplateSpecializationTypeLoc TL) {
574 addSourceLocation(Loc: TL.getElaboratedKeywordLoc());
575 Record.AddNestedNameSpecifierLoc(NNS: TL.getQualifierLoc());
576 addSourceLocation(Loc: TL.getTemplateNameLoc());
577}
578
579void TypeLocWriter::VisitTagTypeLoc(TagTypeLoc TL) {
580 addSourceLocation(Loc: TL.getElaboratedKeywordLoc());
581 Record.AddNestedNameSpecifierLoc(NNS: TL.getQualifierLoc());
582 addSourceLocation(Loc: TL.getNameLoc());
583}
584
585void TypeLocWriter::VisitRecordTypeLoc(RecordTypeLoc TL) {
586 VisitTagTypeLoc(TL);
587}
588
589void TypeLocWriter::VisitInjectedClassNameTypeLoc(InjectedClassNameTypeLoc TL) {
590 VisitTagTypeLoc(TL);
591}
592
593void TypeLocWriter::VisitEnumTypeLoc(EnumTypeLoc TL) { VisitTagTypeLoc(TL); }
594
595void TypeLocWriter::VisitAttributedTypeLoc(AttributedTypeLoc TL) {
596 Record.AddAttr(A: TL.getAttr());
597}
598
599void TypeLocWriter::VisitCountAttributedTypeLoc(CountAttributedTypeLoc TL) {
600 // Nothing to do
601}
602
603void TypeLocWriter::VisitBTFTagAttributedTypeLoc(BTFTagAttributedTypeLoc TL) {
604 // Nothing to do.
605}
606
607void TypeLocWriter::VisitHLSLAttributedResourceTypeLoc(
608 HLSLAttributedResourceTypeLoc TL) {
609 // Nothing to do.
610}
611
612void TypeLocWriter::VisitHLSLInlineSpirvTypeLoc(HLSLInlineSpirvTypeLoc TL) {
613 // Nothing to do.
614}
615
616void TypeLocWriter::VisitTemplateTypeParmTypeLoc(TemplateTypeParmTypeLoc TL) {
617 addSourceLocation(Loc: TL.getNameLoc());
618}
619
620void TypeLocWriter::VisitSubstTemplateTypeParmTypeLoc(
621 SubstTemplateTypeParmTypeLoc TL) {
622 addSourceLocation(Loc: TL.getNameLoc());
623}
624
625void TypeLocWriter::VisitSubstTemplateTypeParmPackTypeLoc(
626 SubstTemplateTypeParmPackTypeLoc TL) {
627 addSourceLocation(Loc: TL.getNameLoc());
628}
629
630void TypeLocWriter::VisitSubstBuiltinTemplatePackTypeLoc(
631 SubstBuiltinTemplatePackTypeLoc TL) {
632 addSourceLocation(Loc: TL.getNameLoc());
633}
634
635void TypeLocWriter::VisitTemplateSpecializationTypeLoc(
636 TemplateSpecializationTypeLoc TL) {
637 addSourceLocation(Loc: TL.getElaboratedKeywordLoc());
638 Record.AddNestedNameSpecifierLoc(NNS: TL.getQualifierLoc());
639 addSourceLocation(Loc: TL.getTemplateKeywordLoc());
640 addSourceLocation(Loc: TL.getTemplateNameLoc());
641 addSourceLocation(Loc: TL.getLAngleLoc());
642 addSourceLocation(Loc: TL.getRAngleLoc());
643 for (unsigned i = 0, e = TL.getNumArgs(); i != e; ++i)
644 Record.AddTemplateArgumentLocInfo(Arg: TL.getArgLoc(i));
645}
646
647void TypeLocWriter::VisitParenTypeLoc(ParenTypeLoc TL) {
648 addSourceLocation(Loc: TL.getLParenLoc());
649 addSourceLocation(Loc: TL.getRParenLoc());
650}
651
652void TypeLocWriter::VisitMacroQualifiedTypeLoc(MacroQualifiedTypeLoc TL) {
653 addSourceLocation(Loc: TL.getExpansionLoc());
654}
655
656void TypeLocWriter::VisitDependentNameTypeLoc(DependentNameTypeLoc TL) {
657 addSourceLocation(Loc: TL.getElaboratedKeywordLoc());
658 Record.AddNestedNameSpecifierLoc(NNS: TL.getQualifierLoc());
659 addSourceLocation(Loc: TL.getNameLoc());
660}
661
662void TypeLocWriter::VisitPackExpansionTypeLoc(PackExpansionTypeLoc TL) {
663 addSourceLocation(Loc: TL.getEllipsisLoc());
664}
665
666void TypeLocWriter::VisitObjCInterfaceTypeLoc(ObjCInterfaceTypeLoc TL) {
667 addSourceLocation(Loc: TL.getNameLoc());
668 addSourceLocation(Loc: TL.getNameEndLoc());
669}
670
671void TypeLocWriter::VisitObjCObjectTypeLoc(ObjCObjectTypeLoc TL) {
672 Record.push_back(N: TL.hasBaseTypeAsWritten());
673 addSourceLocation(Loc: TL.getTypeArgsLAngleLoc());
674 addSourceLocation(Loc: TL.getTypeArgsRAngleLoc());
675 for (unsigned i = 0, e = TL.getNumTypeArgs(); i != e; ++i)
676 Record.AddTypeSourceInfo(TInfo: TL.getTypeArgTInfo(i));
677 addSourceLocation(Loc: TL.getProtocolLAngleLoc());
678 addSourceLocation(Loc: TL.getProtocolRAngleLoc());
679 for (unsigned i = 0, e = TL.getNumProtocols(); i != e; ++i)
680 addSourceLocation(Loc: TL.getProtocolLoc(i));
681}
682
683void TypeLocWriter::VisitObjCObjectPointerTypeLoc(ObjCObjectPointerTypeLoc TL) {
684 addSourceLocation(Loc: TL.getStarLoc());
685}
686
687void TypeLocWriter::VisitAtomicTypeLoc(AtomicTypeLoc TL) {
688 addSourceLocation(Loc: TL.getKWLoc());
689 addSourceLocation(Loc: TL.getLParenLoc());
690 addSourceLocation(Loc: TL.getRParenLoc());
691}
692
693void TypeLocWriter::VisitPipeTypeLoc(PipeTypeLoc TL) {
694 addSourceLocation(Loc: TL.getKWLoc());
695}
696void TypeLocWriter::VisitBitIntTypeLoc(clang::BitIntTypeLoc TL) {
697 addSourceLocation(Loc: TL.getNameLoc());
698}
699void TypeLocWriter::VisitDependentBitIntTypeLoc(
700 clang::DependentBitIntTypeLoc TL) {
701 addSourceLocation(Loc: TL.getNameLoc());
702}
703
704void TypeLocWriter::VisitPredefinedSugarTypeLoc(
705 clang::PredefinedSugarTypeLoc TL) {
706 // Nothing to do.
707}
708
709void ASTWriter::WriteTypeAbbrevs() {
710 using namespace llvm;
711
712 std::shared_ptr<BitCodeAbbrev> Abv;
713
714 // Abbreviation for TYPE_EXT_QUAL
715 Abv = std::make_shared<BitCodeAbbrev>();
716 Abv->Add(OpInfo: BitCodeAbbrevOp(serialization::TYPE_EXT_QUAL));
717 Abv->Add(OpInfo: BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Type
718 Abv->Add(OpInfo: BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 3)); // Quals
719 TypeExtQualAbbrev = Stream.EmitAbbrev(Abbv: std::move(Abv));
720}
721
722//===----------------------------------------------------------------------===//
723// ASTWriter Implementation
724//===----------------------------------------------------------------------===//
725
726static void EmitBlockID(unsigned ID, const char *Name,
727 llvm::BitstreamWriter &Stream,
728 ASTWriter::RecordDataImpl &Record) {
729 Record.clear();
730 Record.push_back(Elt: ID);
731 Stream.EmitRecord(Code: llvm::bitc::BLOCKINFO_CODE_SETBID, Vals: Record);
732
733 // Emit the block name if present.
734 if (!Name || Name[0] == 0)
735 return;
736 Record.clear();
737 while (*Name)
738 Record.push_back(Elt: *Name++);
739 Stream.EmitRecord(Code: llvm::bitc::BLOCKINFO_CODE_BLOCKNAME, Vals: Record);
740}
741
742static void EmitRecordID(unsigned ID, const char *Name,
743 llvm::BitstreamWriter &Stream,
744 ASTWriter::RecordDataImpl &Record) {
745 Record.clear();
746 Record.push_back(Elt: ID);
747 while (*Name)
748 Record.push_back(Elt: *Name++);
749 Stream.EmitRecord(Code: llvm::bitc::BLOCKINFO_CODE_SETRECORDNAME, Vals: Record);
750}
751
752static void AddStmtsExprs(llvm::BitstreamWriter &Stream,
753 ASTWriter::RecordDataImpl &Record) {
754#define RECORD(X) EmitRecordID(X, #X, Stream, Record)
755 RECORD(STMT_STOP);
756 RECORD(STMT_NULL_PTR);
757 RECORD(STMT_REF_PTR);
758 RECORD(STMT_NULL);
759 RECORD(STMT_COMPOUND);
760 RECORD(STMT_CASE);
761 RECORD(STMT_DEFAULT);
762 RECORD(STMT_LABEL);
763 RECORD(STMT_ATTRIBUTED);
764 RECORD(STMT_IF);
765 RECORD(STMT_SWITCH);
766 RECORD(STMT_WHILE);
767 RECORD(STMT_DO);
768 RECORD(STMT_FOR);
769 RECORD(STMT_GOTO);
770 RECORD(STMT_INDIRECT_GOTO);
771 RECORD(STMT_CONTINUE);
772 RECORD(STMT_BREAK);
773 RECORD(STMT_RETURN);
774 RECORD(STMT_DECL);
775 RECORD(STMT_GCCASM);
776 RECORD(STMT_MSASM);
777 RECORD(EXPR_PREDEFINED);
778 RECORD(EXPR_DECL_REF);
779 RECORD(EXPR_INTEGER_LITERAL);
780 RECORD(EXPR_FIXEDPOINT_LITERAL);
781 RECORD(EXPR_FLOATING_LITERAL);
782 RECORD(EXPR_IMAGINARY_LITERAL);
783 RECORD(EXPR_STRING_LITERAL);
784 RECORD(EXPR_CHARACTER_LITERAL);
785 RECORD(EXPR_PAREN);
786 RECORD(EXPR_PAREN_LIST);
787 RECORD(EXPR_UNARY_OPERATOR);
788 RECORD(EXPR_SIZEOF_ALIGN_OF);
789 RECORD(EXPR_ARRAY_SUBSCRIPT);
790 RECORD(EXPR_CALL);
791 RECORD(EXPR_MEMBER);
792 RECORD(EXPR_BINARY_OPERATOR);
793 RECORD(EXPR_COMPOUND_ASSIGN_OPERATOR);
794 RECORD(EXPR_CONDITIONAL_OPERATOR);
795 RECORD(EXPR_IMPLICIT_CAST);
796 RECORD(EXPR_CSTYLE_CAST);
797 RECORD(EXPR_COMPOUND_LITERAL);
798 RECORD(EXPR_EXT_VECTOR_ELEMENT);
799 RECORD(EXPR_INIT_LIST);
800 RECORD(EXPR_DESIGNATED_INIT);
801 RECORD(EXPR_DESIGNATED_INIT_UPDATE);
802 RECORD(EXPR_IMPLICIT_VALUE_INIT);
803 RECORD(EXPR_NO_INIT);
804 RECORD(EXPR_VA_ARG);
805 RECORD(EXPR_ADDR_LABEL);
806 RECORD(EXPR_STMT);
807 RECORD(EXPR_CHOOSE);
808 RECORD(EXPR_GNU_NULL);
809 RECORD(EXPR_SHUFFLE_VECTOR);
810 RECORD(EXPR_BLOCK);
811 RECORD(EXPR_GENERIC_SELECTION);
812 RECORD(EXPR_OBJC_STRING_LITERAL);
813 RECORD(EXPR_OBJC_BOXED_EXPRESSION);
814 RECORD(EXPR_OBJC_ARRAY_LITERAL);
815 RECORD(EXPR_OBJC_DICTIONARY_LITERAL);
816 RECORD(EXPR_OBJC_ENCODE);
817 RECORD(EXPR_OBJC_SELECTOR_EXPR);
818 RECORD(EXPR_OBJC_PROTOCOL_EXPR);
819 RECORD(EXPR_OBJC_IVAR_REF_EXPR);
820 RECORD(EXPR_OBJC_PROPERTY_REF_EXPR);
821 RECORD(EXPR_OBJC_KVC_REF_EXPR);
822 RECORD(EXPR_OBJC_MESSAGE_EXPR);
823 RECORD(STMT_OBJC_FOR_COLLECTION);
824 RECORD(STMT_OBJC_CATCH);
825 RECORD(STMT_OBJC_FINALLY);
826 RECORD(STMT_OBJC_AT_TRY);
827 RECORD(STMT_OBJC_AT_SYNCHRONIZED);
828 RECORD(STMT_OBJC_AT_THROW);
829 RECORD(EXPR_OBJC_BOOL_LITERAL);
830 RECORD(STMT_CXX_CATCH);
831 RECORD(STMT_CXX_TRY);
832 RECORD(STMT_CXX_FOR_RANGE);
833 RECORD(EXPR_CXX_OPERATOR_CALL);
834 RECORD(EXPR_CXX_MEMBER_CALL);
835 RECORD(EXPR_CXX_REWRITTEN_BINARY_OPERATOR);
836 RECORD(EXPR_CXX_CONSTRUCT);
837 RECORD(EXPR_CXX_TEMPORARY_OBJECT);
838 RECORD(EXPR_CXX_STATIC_CAST);
839 RECORD(EXPR_CXX_DYNAMIC_CAST);
840 RECORD(EXPR_CXX_REINTERPRET_CAST);
841 RECORD(EXPR_CXX_CONST_CAST);
842 RECORD(EXPR_CXX_ADDRSPACE_CAST);
843 RECORD(EXPR_CXX_FUNCTIONAL_CAST);
844 RECORD(EXPR_USER_DEFINED_LITERAL);
845 RECORD(EXPR_CXX_STD_INITIALIZER_LIST);
846 RECORD(EXPR_CXX_BOOL_LITERAL);
847 RECORD(EXPR_CXX_PAREN_LIST_INIT);
848 RECORD(EXPR_CXX_NULL_PTR_LITERAL);
849 RECORD(EXPR_CXX_TYPEID_EXPR);
850 RECORD(EXPR_CXX_TYPEID_TYPE);
851 RECORD(EXPR_CXX_THIS);
852 RECORD(EXPR_CXX_THROW);
853 RECORD(EXPR_CXX_DEFAULT_ARG);
854 RECORD(EXPR_CXX_DEFAULT_INIT);
855 RECORD(EXPR_CXX_BIND_TEMPORARY);
856 RECORD(EXPR_CXX_SCALAR_VALUE_INIT);
857 RECORD(EXPR_CXX_NEW);
858 RECORD(EXPR_CXX_DELETE);
859 RECORD(EXPR_CXX_PSEUDO_DESTRUCTOR);
860 RECORD(EXPR_EXPR_WITH_CLEANUPS);
861 RECORD(EXPR_CXX_DEPENDENT_SCOPE_MEMBER);
862 RECORD(EXPR_CXX_DEPENDENT_SCOPE_DECL_REF);
863 RECORD(EXPR_CXX_UNRESOLVED_CONSTRUCT);
864 RECORD(EXPR_CXX_UNRESOLVED_MEMBER);
865 RECORD(EXPR_CXX_UNRESOLVED_LOOKUP);
866 RECORD(EXPR_CXX_EXPRESSION_TRAIT);
867 RECORD(EXPR_CXX_NOEXCEPT);
868 RECORD(EXPR_OPAQUE_VALUE);
869 RECORD(EXPR_BINARY_CONDITIONAL_OPERATOR);
870 RECORD(EXPR_TYPE_TRAIT);
871 RECORD(EXPR_ARRAY_TYPE_TRAIT);
872 RECORD(EXPR_PACK_EXPANSION);
873 RECORD(EXPR_SIZEOF_PACK);
874 RECORD(EXPR_PACK_INDEXING);
875 RECORD(EXPR_SUBST_NON_TYPE_TEMPLATE_PARM);
876 RECORD(EXPR_SUBST_NON_TYPE_TEMPLATE_PARM_PACK);
877 RECORD(EXPR_FUNCTION_PARM_PACK);
878 RECORD(EXPR_MATERIALIZE_TEMPORARY);
879 RECORD(EXPR_CUDA_KERNEL_CALL);
880 RECORD(EXPR_CXX_UUIDOF_EXPR);
881 RECORD(EXPR_CXX_UUIDOF_TYPE);
882 RECORD(EXPR_LAMBDA);
883#undef RECORD
884}
885
886void ASTWriter::WriteBlockInfoBlock() {
887 RecordData Record;
888 Stream.EnterBlockInfoBlock();
889
890#define BLOCK(X) EmitBlockID(X ## _ID, #X, Stream, Record)
891#define RECORD(X) EmitRecordID(X, #X, Stream, Record)
892
893 // Control Block.
894 BLOCK(CONTROL_BLOCK);
895 RECORD(METADATA);
896 RECORD(MODULE_NAME);
897 RECORD(MODULE_DIRECTORY);
898 RECORD(MODULE_MAP_FILE);
899 RECORD(IMPORT);
900 RECORD(ORIGINAL_FILE);
901 RECORD(ORIGINAL_FILE_ID);
902 RECORD(INPUT_FILE_OFFSETS);
903
904 BLOCK(OPTIONS_BLOCK);
905 RECORD(LANGUAGE_OPTIONS);
906 RECORD(CODEGEN_OPTIONS);
907 RECORD(TARGET_OPTIONS);
908 RECORD(FILE_SYSTEM_OPTIONS);
909 RECORD(HEADER_SEARCH_OPTIONS);
910 RECORD(PREPROCESSOR_OPTIONS);
911
912 BLOCK(INPUT_FILES_BLOCK);
913 RECORD(INPUT_FILE);
914 RECORD(INPUT_FILE_HASH);
915
916 // AST Top-Level Block.
917 BLOCK(AST_BLOCK);
918 RECORD(TYPE_OFFSET);
919 RECORD(DECL_OFFSET);
920 RECORD(IDENTIFIER_OFFSET);
921 RECORD(IDENTIFIER_TABLE);
922 RECORD(EAGERLY_DESERIALIZED_DECLS);
923 RECORD(MODULAR_CODEGEN_DECLS);
924 RECORD(SPECIAL_TYPES);
925 RECORD(STATISTICS);
926 RECORD(TENTATIVE_DEFINITIONS);
927 RECORD(SELECTOR_OFFSETS);
928 RECORD(METHOD_POOL);
929 RECORD(PP_COUNTER_VALUE);
930 RECORD(SOURCE_LOCATION_OFFSETS);
931 RECORD(EXT_VECTOR_DECLS);
932 RECORD(UNUSED_FILESCOPED_DECLS);
933 RECORD(PPD_ENTITIES_OFFSETS);
934 RECORD(VTABLE_USES);
935 RECORD(PPD_SKIPPED_RANGES);
936 RECORD(REFERENCED_SELECTOR_POOL);
937 RECORD(TU_UPDATE_LEXICAL);
938 RECORD(SEMA_DECL_REFS);
939 RECORD(WEAK_UNDECLARED_IDENTIFIERS);
940 RECORD(PENDING_IMPLICIT_INSTANTIATIONS);
941 RECORD(UPDATE_VISIBLE);
942 RECORD(DELAYED_NAMESPACE_LEXICAL_VISIBLE_RECORD);
943 RECORD(RELATED_DECLS_MAP);
944 RECORD(DECL_UPDATE_OFFSETS);
945 RECORD(DECL_UPDATES);
946 RECORD(CUDA_SPECIAL_DECL_REFS);
947 RECORD(HEADER_SEARCH_TABLE);
948 RECORD(FP_PRAGMA_OPTIONS);
949 RECORD(OPENCL_EXTENSIONS);
950 RECORD(OPENCL_EXTENSION_TYPES);
951 RECORD(OPENCL_EXTENSION_DECLS);
952 RECORD(DELEGATING_CTORS);
953 RECORD(KNOWN_NAMESPACES);
954 RECORD(MODULE_OFFSET_MAP);
955 RECORD(SOURCE_MANAGER_LINE_TABLE);
956 RECORD(OBJC_CATEGORIES_MAP);
957 RECORD(FILE_SORTED_DECLS);
958 RECORD(IMPORTED_MODULES);
959 RECORD(OBJC_CATEGORIES);
960 RECORD(MACRO_OFFSET);
961 RECORD(INTERESTING_IDENTIFIERS);
962 RECORD(UNDEFINED_BUT_USED);
963 RECORD(LATE_PARSED_TEMPLATE);
964 RECORD(OPTIMIZE_PRAGMA_OPTIONS);
965 RECORD(MSSTRUCT_PRAGMA_OPTIONS);
966 RECORD(POINTERS_TO_MEMBERS_PRAGMA_OPTIONS);
967 RECORD(UNUSED_LOCAL_TYPEDEF_NAME_CANDIDATES);
968 RECORD(DELETE_EXPRS_TO_ANALYZE);
969 RECORD(CUDA_PRAGMA_FORCE_HOST_DEVICE_DEPTH);
970 RECORD(PP_CONDITIONAL_STACK);
971 RECORD(DECLS_TO_CHECK_FOR_DEFERRED_DIAGS);
972 RECORD(PP_ASSUME_NONNULL_LOC);
973 RECORD(PP_UNSAFE_BUFFER_USAGE);
974 RECORD(VTABLES_TO_EMIT);
975 RECORD(RISCV_VECTOR_INTRINSICS_PRAGMA);
976
977 // SourceManager Block.
978 BLOCK(SOURCE_MANAGER_BLOCK);
979 RECORD(SM_SLOC_FILE_ENTRY);
980 RECORD(SM_SLOC_BUFFER_ENTRY);
981 RECORD(SM_SLOC_BUFFER_BLOB);
982 RECORD(SM_SLOC_BUFFER_BLOB_COMPRESSED);
983 RECORD(SM_SLOC_EXPANSION_ENTRY);
984
985 // Preprocessor Block.
986 BLOCK(PREPROCESSOR_BLOCK);
987 RECORD(PP_MACRO_DIRECTIVE_HISTORY);
988 RECORD(PP_MACRO_FUNCTION_LIKE);
989 RECORD(PP_MACRO_OBJECT_LIKE);
990 RECORD(PP_MODULE_MACRO);
991 RECORD(PP_TOKEN);
992
993 // Submodule Block.
994 BLOCK(SUBMODULE_BLOCK);
995 RECORD(SUBMODULE_METADATA);
996 RECORD(SUBMODULE_DEFINITION);
997 RECORD(SUBMODULE_UMBRELLA_HEADER);
998 RECORD(SUBMODULE_HEADER);
999 RECORD(SUBMODULE_TOPHEADER);
1000 RECORD(SUBMODULE_UMBRELLA_DIR);
1001 RECORD(SUBMODULE_IMPORTS);
1002 RECORD(SUBMODULE_AFFECTING_MODULES);
1003 RECORD(SUBMODULE_EXPORTS);
1004 RECORD(SUBMODULE_REQUIRES);
1005 RECORD(SUBMODULE_EXCLUDED_HEADER);
1006 RECORD(SUBMODULE_LINK_LIBRARY);
1007 RECORD(SUBMODULE_CONFIG_MACRO);
1008 RECORD(SUBMODULE_CONFLICT);
1009 RECORD(SUBMODULE_PRIVATE_HEADER);
1010 RECORD(SUBMODULE_TEXTUAL_HEADER);
1011 RECORD(SUBMODULE_PRIVATE_TEXTUAL_HEADER);
1012 RECORD(SUBMODULE_INITIALIZERS);
1013 RECORD(SUBMODULE_EXPORT_AS);
1014
1015 // Comments Block.
1016 BLOCK(COMMENTS_BLOCK);
1017 RECORD(COMMENTS_RAW_COMMENT);
1018
1019 // Decls and Types block.
1020 BLOCK(DECLTYPES_BLOCK);
1021 RECORD(TYPE_EXT_QUAL);
1022 RECORD(TYPE_COMPLEX);
1023 RECORD(TYPE_POINTER);
1024 RECORD(TYPE_BLOCK_POINTER);
1025 RECORD(TYPE_LVALUE_REFERENCE);
1026 RECORD(TYPE_RVALUE_REFERENCE);
1027 RECORD(TYPE_MEMBER_POINTER);
1028 RECORD(TYPE_CONSTANT_ARRAY);
1029 RECORD(TYPE_INCOMPLETE_ARRAY);
1030 RECORD(TYPE_VARIABLE_ARRAY);
1031 RECORD(TYPE_VECTOR);
1032 RECORD(TYPE_EXT_VECTOR);
1033 RECORD(TYPE_FUNCTION_NO_PROTO);
1034 RECORD(TYPE_FUNCTION_PROTO);
1035 RECORD(TYPE_TYPEDEF);
1036 RECORD(TYPE_TYPEOF_EXPR);
1037 RECORD(TYPE_TYPEOF);
1038 RECORD(TYPE_RECORD);
1039 RECORD(TYPE_ENUM);
1040 RECORD(TYPE_OBJC_INTERFACE);
1041 RECORD(TYPE_OBJC_OBJECT_POINTER);
1042 RECORD(TYPE_DECLTYPE);
1043 RECORD(TYPE_SUBST_TEMPLATE_TYPE_PARM);
1044 RECORD(TYPE_UNRESOLVED_USING);
1045 RECORD(TYPE_INJECTED_CLASS_NAME);
1046 RECORD(TYPE_OBJC_OBJECT);
1047 RECORD(TYPE_TEMPLATE_TYPE_PARM);
1048 RECORD(TYPE_TEMPLATE_SPECIALIZATION);
1049 RECORD(TYPE_DEPENDENT_NAME);
1050 RECORD(TYPE_DEPENDENT_SIZED_ARRAY);
1051 RECORD(TYPE_PAREN);
1052 RECORD(TYPE_MACRO_QUALIFIED);
1053 RECORD(TYPE_PACK_EXPANSION);
1054 RECORD(TYPE_ATTRIBUTED);
1055 RECORD(TYPE_SUBST_TEMPLATE_TYPE_PARM_PACK);
1056 RECORD(TYPE_SUBST_BUILTIN_TEMPLATE_PACK);
1057 RECORD(TYPE_AUTO);
1058 RECORD(TYPE_UNARY_TRANSFORM);
1059 RECORD(TYPE_ATOMIC);
1060 RECORD(TYPE_DECAYED);
1061 RECORD(TYPE_ADJUSTED);
1062 RECORD(TYPE_OBJC_TYPE_PARAM);
1063 RECORD(LOCAL_REDECLARATIONS);
1064 RECORD(DECL_TYPEDEF);
1065 RECORD(DECL_TYPEALIAS);
1066 RECORD(DECL_ENUM);
1067 RECORD(DECL_RECORD);
1068 RECORD(DECL_ENUM_CONSTANT);
1069 RECORD(DECL_FUNCTION);
1070 RECORD(DECL_OBJC_METHOD);
1071 RECORD(DECL_OBJC_INTERFACE);
1072 RECORD(DECL_OBJC_PROTOCOL);
1073 RECORD(DECL_OBJC_IVAR);
1074 RECORD(DECL_OBJC_AT_DEFS_FIELD);
1075 RECORD(DECL_OBJC_CATEGORY);
1076 RECORD(DECL_OBJC_CATEGORY_IMPL);
1077 RECORD(DECL_OBJC_IMPLEMENTATION);
1078 RECORD(DECL_OBJC_COMPATIBLE_ALIAS);
1079 RECORD(DECL_OBJC_PROPERTY);
1080 RECORD(DECL_OBJC_PROPERTY_IMPL);
1081 RECORD(DECL_FIELD);
1082 RECORD(DECL_MS_PROPERTY);
1083 RECORD(DECL_VAR);
1084 RECORD(DECL_IMPLICIT_PARAM);
1085 RECORD(DECL_PARM_VAR);
1086 RECORD(DECL_FILE_SCOPE_ASM);
1087 RECORD(DECL_BLOCK);
1088 RECORD(DECL_CONTEXT_LEXICAL);
1089 RECORD(DECL_CONTEXT_VISIBLE);
1090 RECORD(DECL_CONTEXT_MODULE_LOCAL_VISIBLE);
1091 RECORD(DECL_NAMESPACE);
1092 RECORD(DECL_NAMESPACE_ALIAS);
1093 RECORD(DECL_USING);
1094 RECORD(DECL_USING_SHADOW);
1095 RECORD(DECL_USING_DIRECTIVE);
1096 RECORD(DECL_UNRESOLVED_USING_VALUE);
1097 RECORD(DECL_UNRESOLVED_USING_TYPENAME);
1098 RECORD(DECL_LINKAGE_SPEC);
1099 RECORD(DECL_EXPORT);
1100 RECORD(DECL_CXX_RECORD);
1101 RECORD(DECL_CXX_METHOD);
1102 RECORD(DECL_CXX_CONSTRUCTOR);
1103 RECORD(DECL_CXX_DESTRUCTOR);
1104 RECORD(DECL_CXX_CONVERSION);
1105 RECORD(DECL_ACCESS_SPEC);
1106 RECORD(DECL_FRIEND);
1107 RECORD(DECL_FRIEND_TEMPLATE);
1108 RECORD(DECL_CLASS_TEMPLATE);
1109 RECORD(DECL_CLASS_TEMPLATE_SPECIALIZATION);
1110 RECORD(DECL_CLASS_TEMPLATE_PARTIAL_SPECIALIZATION);
1111 RECORD(DECL_VAR_TEMPLATE);
1112 RECORD(DECL_VAR_TEMPLATE_SPECIALIZATION);
1113 RECORD(DECL_VAR_TEMPLATE_PARTIAL_SPECIALIZATION);
1114 RECORD(DECL_FUNCTION_TEMPLATE);
1115 RECORD(DECL_TEMPLATE_TYPE_PARM);
1116 RECORD(DECL_NON_TYPE_TEMPLATE_PARM);
1117 RECORD(DECL_TEMPLATE_TEMPLATE_PARM);
1118 RECORD(DECL_CONCEPT);
1119 RECORD(DECL_REQUIRES_EXPR_BODY);
1120 RECORD(DECL_TYPE_ALIAS_TEMPLATE);
1121 RECORD(DECL_STATIC_ASSERT);
1122 RECORD(DECL_CXX_BASE_SPECIFIERS);
1123 RECORD(DECL_CXX_CTOR_INITIALIZERS);
1124 RECORD(DECL_INDIRECTFIELD);
1125 RECORD(DECL_EXPANDED_NON_TYPE_TEMPLATE_PARM_PACK);
1126 RECORD(DECL_EXPANDED_TEMPLATE_TEMPLATE_PARM_PACK);
1127 RECORD(DECL_IMPORT);
1128 RECORD(DECL_OMP_THREADPRIVATE);
1129 RECORD(DECL_EMPTY);
1130 RECORD(DECL_OBJC_TYPE_PARAM);
1131 RECORD(DECL_OMP_CAPTUREDEXPR);
1132 RECORD(DECL_PRAGMA_COMMENT);
1133 RECORD(DECL_PRAGMA_DETECT_MISMATCH);
1134 RECORD(DECL_OMP_DECLARE_REDUCTION);
1135 RECORD(DECL_OMP_ALLOCATE);
1136 RECORD(DECL_HLSL_BUFFER);
1137 RECORD(DECL_OPENACC_DECLARE);
1138 RECORD(DECL_OPENACC_ROUTINE);
1139
1140 // Statements and Exprs can occur in the Decls and Types block.
1141 AddStmtsExprs(Stream, Record);
1142
1143 BLOCK(PREPROCESSOR_DETAIL_BLOCK);
1144 RECORD(PPD_MACRO_EXPANSION);
1145 RECORD(PPD_MACRO_DEFINITION);
1146 RECORD(PPD_INCLUSION_DIRECTIVE);
1147
1148 // Decls and Types block.
1149 BLOCK(EXTENSION_BLOCK);
1150 RECORD(EXTENSION_METADATA);
1151
1152 BLOCK(UNHASHED_CONTROL_BLOCK);
1153 RECORD(SIGNATURE);
1154 RECORD(AST_BLOCK_HASH);
1155 RECORD(DIAGNOSTIC_OPTIONS);
1156 RECORD(HEADER_SEARCH_PATHS);
1157 RECORD(DIAG_PRAGMA_MAPPINGS);
1158 RECORD(HEADER_SEARCH_ENTRY_USAGE);
1159 RECORD(VFS_USAGE);
1160
1161#undef RECORD
1162#undef BLOCK
1163 Stream.ExitBlock();
1164}
1165
1166/// Prepares a path for being written to an AST file by converting it
1167/// to an absolute path and removing nested './'s.
1168///
1169/// \return \c true if the path was changed.
1170static bool cleanPathForOutput(FileManager &FileMgr,
1171 SmallVectorImpl<char> &Path) {
1172 bool Changed = FileMgr.makeAbsolutePath(Path);
1173 return Changed | llvm::sys::path::remove_dots(path&: Path);
1174}
1175
1176/// Adjusts the given filename to only write out the portion of the
1177/// filename that is not part of the system root directory.
1178///
1179/// \param Filename the file name to adjust.
1180///
1181/// \param BaseDir When non-NULL, the PCH file is a relocatable AST file and
1182/// the returned filename will be adjusted by this root directory.
1183///
1184/// \returns either the original filename (if it needs no adjustment) or the
1185/// adjusted filename (which points into the @p Filename parameter).
1186static const char *
1187adjustFilenameForRelocatableAST(const char *Filename, StringRef BaseDir) {
1188 assert(Filename && "No file name to adjust?");
1189
1190 if (BaseDir.empty())
1191 return Filename;
1192
1193 // Verify that the filename and the system root have the same prefix.
1194 unsigned Pos = 0;
1195 for (; Filename[Pos] && Pos < BaseDir.size(); ++Pos)
1196 if (Filename[Pos] != BaseDir[Pos])
1197 return Filename; // Prefixes don't match.
1198
1199 // We hit the end of the filename before we hit the end of the system root.
1200 if (!Filename[Pos])
1201 return Filename;
1202
1203 // If there's not a path separator at the end of the base directory nor
1204 // immediately after it, then this isn't within the base directory.
1205 if (!llvm::sys::path::is_separator(value: Filename[Pos])) {
1206 if (!llvm::sys::path::is_separator(value: BaseDir.back()))
1207 return Filename;
1208 } else {
1209 // If the file name has a '/' at the current position, skip over the '/'.
1210 // We distinguish relative paths from absolute paths by the
1211 // absence of '/' at the beginning of relative paths.
1212 //
1213 // FIXME: This is wrong. We distinguish them by asking if the path is
1214 // absolute, which isn't the same thing. And there might be multiple '/'s
1215 // in a row. Use a better mechanism to indicate whether we have emitted an
1216 // absolute or relative path.
1217 ++Pos;
1218 }
1219
1220 return Filename + Pos;
1221}
1222
1223std::pair<ASTFileSignature, ASTFileSignature>
1224ASTWriter::createSignature() const {
1225 StringRef AllBytes(Buffer.data(), Buffer.size());
1226
1227 llvm::SHA1 Hasher;
1228 Hasher.update(Str: AllBytes.slice(Start: ASTBlockRange.first, End: ASTBlockRange.second));
1229 ASTFileSignature ASTBlockHash = ASTFileSignature::create(Bytes: Hasher.result());
1230
1231 // Add the remaining bytes:
1232 // 1. Before the unhashed control block.
1233 Hasher.update(Str: AllBytes.slice(Start: 0, End: UnhashedControlBlockRange.first));
1234 // 2. Between the unhashed control block and the AST block.
1235 Hasher.update(
1236 Str: AllBytes.slice(Start: UnhashedControlBlockRange.second, End: ASTBlockRange.first));
1237 // 3. After the AST block.
1238 Hasher.update(Str: AllBytes.substr(Start: ASTBlockRange.second));
1239 ASTFileSignature Signature = ASTFileSignature::create(Bytes: Hasher.result());
1240
1241 return std::make_pair(x&: ASTBlockHash, y&: Signature);
1242}
1243
1244ASTFileSignature ASTWriter::createSignatureForNamedModule() const {
1245 llvm::SHA1 Hasher;
1246 Hasher.update(Str: StringRef(Buffer.data(), Buffer.size()));
1247
1248 assert(WritingModule);
1249 assert(WritingModule->isNamedModule());
1250
1251 // We need to combine all the export imported modules no matter
1252 // we used it or not.
1253 for (auto [ExportImported, _] : WritingModule->Exports)
1254 Hasher.update(Data: ExportImported->Signature);
1255
1256 // We combine all the used modules to make sure the signature is precise.
1257 // Consider the case like:
1258 //
1259 // // a.cppm
1260 // export module a;
1261 // export inline int a() { ... }
1262 //
1263 // // b.cppm
1264 // export module b;
1265 // import a;
1266 // export inline int b() { return a(); }
1267 //
1268 // Since both `a()` and `b()` are inline, we need to make sure the BMI of
1269 // `b.pcm` will change after the implementation of `a()` changes. We can't
1270 // get that naturally since we won't record the body of `a()` during the
1271 // writing process. We can't reuse ODRHash here since ODRHash won't calculate
1272 // the called function recursively. So ODRHash will be problematic if `a()`
1273 // calls other inline functions.
1274 //
1275 // Probably we can solve this by a new hash mechanism. But the safety and
1276 // efficiency may a problem too. Here we just combine the hash value of the
1277 // used modules conservatively.
1278 for (Module *M : TouchedTopLevelModules)
1279 Hasher.update(Data: M->Signature);
1280
1281 return ASTFileSignature::create(Bytes: Hasher.result());
1282}
1283
1284static void BackpatchSignatureAt(llvm::BitstreamWriter &Stream,
1285 const ASTFileSignature &S, uint64_t BitNo) {
1286 for (uint8_t Byte : S) {
1287 Stream.BackpatchByte(BitNo, NewByte: Byte);
1288 BitNo += 8;
1289 }
1290}
1291
1292ASTFileSignature ASTWriter::backpatchSignature() {
1293 if (isWritingStdCXXNamedModules()) {
1294 ASTFileSignature Signature = createSignatureForNamedModule();
1295 BackpatchSignatureAt(Stream, S: Signature, BitNo: SignatureOffset);
1296 return Signature;
1297 }
1298
1299 if (!WritingModule ||
1300 !PP->getHeaderSearchInfo().getHeaderSearchOpts().ModulesHashContent)
1301 return {};
1302
1303 // For implicit modules, write the hash of the PCM as its signature.
1304 ASTFileSignature ASTBlockHash;
1305 ASTFileSignature Signature;
1306 std::tie(args&: ASTBlockHash, args&: Signature) = createSignature();
1307
1308 BackpatchSignatureAt(Stream, S: ASTBlockHash, BitNo: ASTBlockHashOffset);
1309 BackpatchSignatureAt(Stream, S: Signature, BitNo: SignatureOffset);
1310
1311 return Signature;
1312}
1313
1314void ASTWriter::writeUnhashedControlBlock(Preprocessor &PP) {
1315 using namespace llvm;
1316
1317 // Flush first to prepare the PCM hash (signature).
1318 Stream.FlushToWord();
1319 UnhashedControlBlockRange.first = Stream.GetCurrentBitNo() >> 3;
1320
1321 // Enter the block and prepare to write records.
1322 RecordData Record;
1323 Stream.EnterSubblock(BlockID: UNHASHED_CONTROL_BLOCK_ID, CodeLen: 5);
1324
1325 // For implicit modules and C++20 named modules, write the hash of the PCM as
1326 // its signature.
1327 if (isWritingStdCXXNamedModules() ||
1328 (WritingModule &&
1329 PP.getHeaderSearchInfo().getHeaderSearchOpts().ModulesHashContent)) {
1330 // At this point, we don't know the actual signature of the file or the AST
1331 // block - we're only able to compute those at the end of the serialization
1332 // process. Let's store dummy signatures for now, and replace them with the
1333 // real ones later on.
1334 // The bitstream VBR-encodes record elements, which makes backpatching them
1335 // really difficult. Let's store the signatures as blobs instead - they are
1336 // guaranteed to be word-aligned, and we control their format/encoding.
1337 auto Dummy = ASTFileSignature::createDummy();
1338 SmallString<128> Blob{Dummy.begin(), Dummy.end()};
1339
1340 // We don't need AST Block hash in named modules.
1341 if (!isWritingStdCXXNamedModules()) {
1342 auto Abbrev = std::make_shared<BitCodeAbbrev>();
1343 Abbrev->Add(OpInfo: BitCodeAbbrevOp(AST_BLOCK_HASH));
1344 Abbrev->Add(OpInfo: BitCodeAbbrevOp(BitCodeAbbrevOp::Blob));
1345 unsigned ASTBlockHashAbbrev = Stream.EmitAbbrev(Abbv: std::move(Abbrev));
1346
1347 Record.push_back(Elt: AST_BLOCK_HASH);
1348 Stream.EmitRecordWithBlob(Abbrev: ASTBlockHashAbbrev, Vals: Record, Blob);
1349 ASTBlockHashOffset = Stream.GetCurrentBitNo() - Blob.size() * 8;
1350 Record.clear();
1351 }
1352
1353 auto Abbrev = std::make_shared<BitCodeAbbrev>();
1354 Abbrev->Add(OpInfo: BitCodeAbbrevOp(SIGNATURE));
1355 Abbrev->Add(OpInfo: BitCodeAbbrevOp(BitCodeAbbrevOp::Blob));
1356 unsigned SignatureAbbrev = Stream.EmitAbbrev(Abbv: std::move(Abbrev));
1357
1358 Record.push_back(Elt: SIGNATURE);
1359 Stream.EmitRecordWithBlob(Abbrev: SignatureAbbrev, Vals: Record, Blob);
1360 SignatureOffset = Stream.GetCurrentBitNo() - Blob.size() * 8;
1361 Record.clear();
1362 }
1363
1364 const auto &HSOpts = PP.getHeaderSearchInfo().getHeaderSearchOpts();
1365
1366 // Diagnostic options.
1367 const auto &Diags = PP.getDiagnostics();
1368 const DiagnosticOptions &DiagOpts = Diags.getDiagnosticOptions();
1369 if (!HSOpts.ModulesSkipDiagnosticOptions) {
1370#define DIAGOPT(Name, Bits, Default) Record.push_back(DiagOpts.Name);
1371#define ENUM_DIAGOPT(Name, Type, Bits, Default) \
1372 Record.push_back(static_cast<unsigned>(DiagOpts.get##Name()));
1373#include "clang/Basic/DiagnosticOptions.def"
1374 Record.push_back(Elt: DiagOpts.Warnings.size());
1375 for (unsigned I = 0, N = DiagOpts.Warnings.size(); I != N; ++I)
1376 AddString(Str: DiagOpts.Warnings[I], Record);
1377 Record.push_back(Elt: DiagOpts.Remarks.size());
1378 for (unsigned I = 0, N = DiagOpts.Remarks.size(); I != N; ++I)
1379 AddString(Str: DiagOpts.Remarks[I], Record);
1380 // Note: we don't serialize the log or serialization file names, because
1381 // they are generally transient files and will almost always be overridden.
1382 Stream.EmitRecord(Code: DIAGNOSTIC_OPTIONS, Vals: Record);
1383 Record.clear();
1384 }
1385
1386 // Header search paths.
1387 if (!HSOpts.ModulesSkipHeaderSearchPaths) {
1388 // Include entries.
1389 Record.push_back(Elt: HSOpts.UserEntries.size());
1390 for (unsigned I = 0, N = HSOpts.UserEntries.size(); I != N; ++I) {
1391 const HeaderSearchOptions::Entry &Entry = HSOpts.UserEntries[I];
1392 AddString(Str: Entry.Path, Record);
1393 Record.push_back(Elt: static_cast<unsigned>(Entry.Group));
1394 Record.push_back(Elt: Entry.IsFramework);
1395 Record.push_back(Elt: Entry.IgnoreSysRoot);
1396 }
1397
1398 // System header prefixes.
1399 Record.push_back(Elt: HSOpts.SystemHeaderPrefixes.size());
1400 for (unsigned I = 0, N = HSOpts.SystemHeaderPrefixes.size(); I != N; ++I) {
1401 AddString(Str: HSOpts.SystemHeaderPrefixes[I].Prefix, Record);
1402 Record.push_back(Elt: HSOpts.SystemHeaderPrefixes[I].IsSystemHeader);
1403 }
1404
1405 // VFS overlay files.
1406 Record.push_back(Elt: HSOpts.VFSOverlayFiles.size());
1407 for (StringRef VFSOverlayFile : HSOpts.VFSOverlayFiles)
1408 AddString(Str: VFSOverlayFile, Record);
1409
1410 Stream.EmitRecord(Code: HEADER_SEARCH_PATHS, Vals: Record);
1411 }
1412
1413 if (!HSOpts.ModulesSkipPragmaDiagnosticMappings)
1414 WritePragmaDiagnosticMappings(Diag: Diags, /* isModule = */ WritingModule);
1415
1416 // Header search entry usage.
1417 {
1418 auto HSEntryUsage = PP.getHeaderSearchInfo().computeUserEntryUsage();
1419 auto Abbrev = std::make_shared<BitCodeAbbrev>();
1420 Abbrev->Add(OpInfo: BitCodeAbbrevOp(HEADER_SEARCH_ENTRY_USAGE));
1421 Abbrev->Add(OpInfo: BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32)); // Number of bits.
1422 Abbrev->Add(OpInfo: BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // Bit vector.
1423 unsigned HSUsageAbbrevCode = Stream.EmitAbbrev(Abbv: std::move(Abbrev));
1424 RecordData::value_type Record[] = {HEADER_SEARCH_ENTRY_USAGE,
1425 HSEntryUsage.size()};
1426 Stream.EmitRecordWithBlob(Abbrev: HSUsageAbbrevCode, Vals: Record, Blob: bytes(V: HSEntryUsage));
1427 }
1428
1429 // VFS usage.
1430 {
1431 auto VFSUsage = PP.getHeaderSearchInfo().collectVFSUsageAndClear();
1432 auto Abbrev = std::make_shared<BitCodeAbbrev>();
1433 Abbrev->Add(OpInfo: BitCodeAbbrevOp(VFS_USAGE));
1434 Abbrev->Add(OpInfo: BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32)); // Number of bits.
1435 Abbrev->Add(OpInfo: BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // Bit vector.
1436 unsigned VFSUsageAbbrevCode = Stream.EmitAbbrev(Abbv: std::move(Abbrev));
1437 RecordData::value_type Record[] = {VFS_USAGE, VFSUsage.size()};
1438 Stream.EmitRecordWithBlob(Abbrev: VFSUsageAbbrevCode, Vals: Record, Blob: bytes(V: VFSUsage));
1439 }
1440
1441 // Leave the options block.
1442 Stream.ExitBlock();
1443 UnhashedControlBlockRange.second = Stream.GetCurrentBitNo() >> 3;
1444}
1445
1446/// Write the control block.
1447void ASTWriter::WriteControlBlock(Preprocessor &PP, StringRef isysroot) {
1448 using namespace llvm;
1449
1450 SourceManager &SourceMgr = PP.getSourceManager();
1451 FileManager &FileMgr = PP.getFileManager();
1452
1453 Stream.EnterSubblock(BlockID: CONTROL_BLOCK_ID, CodeLen: 5);
1454 RecordData Record;
1455
1456 // Metadata
1457 auto MetadataAbbrev = std::make_shared<BitCodeAbbrev>();
1458 MetadataAbbrev->Add(OpInfo: BitCodeAbbrevOp(METADATA));
1459 MetadataAbbrev->Add(OpInfo: BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 16)); // Major
1460 MetadataAbbrev->Add(OpInfo: BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 16)); // Minor
1461 MetadataAbbrev->Add(OpInfo: BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 16)); // Clang maj.
1462 MetadataAbbrev->Add(OpInfo: BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 16)); // Clang min.
1463 MetadataAbbrev->Add(OpInfo: BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // Relocatable
1464 // Standard C++ module
1465 MetadataAbbrev->Add(OpInfo: BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1));
1466 MetadataAbbrev->Add(OpInfo: BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // Timestamps
1467 MetadataAbbrev->Add(OpInfo: BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // Errors
1468 MetadataAbbrev->Add(OpInfo: BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // SVN branch/tag
1469 unsigned MetadataAbbrevCode = Stream.EmitAbbrev(Abbv: std::move(MetadataAbbrev));
1470 assert((!WritingModule || isysroot.empty()) &&
1471 "writing module as a relocatable PCH?");
1472 {
1473 RecordData::value_type Record[] = {METADATA,
1474 VERSION_MAJOR,
1475 VERSION_MINOR,
1476 CLANG_VERSION_MAJOR,
1477 CLANG_VERSION_MINOR,
1478 !isysroot.empty(),
1479 isWritingStdCXXNamedModules(),
1480 IncludeTimestamps,
1481 ASTHasCompilerErrors};
1482 Stream.EmitRecordWithBlob(Abbrev: MetadataAbbrevCode, Vals: Record,
1483 Blob: getClangFullRepositoryVersion());
1484 }
1485
1486 if (WritingModule) {
1487 // Module name
1488 auto Abbrev = std::make_shared<BitCodeAbbrev>();
1489 Abbrev->Add(OpInfo: BitCodeAbbrevOp(MODULE_NAME));
1490 Abbrev->Add(OpInfo: BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // Name
1491 unsigned AbbrevCode = Stream.EmitAbbrev(Abbv: std::move(Abbrev));
1492 RecordData::value_type Record[] = {MODULE_NAME};
1493 Stream.EmitRecordWithBlob(Abbrev: AbbrevCode, Vals: Record, Blob: WritingModule->Name);
1494
1495 auto BaseDir = [&]() -> std::optional<SmallString<128>> {
1496 if (PP.getHeaderSearchInfo().getHeaderSearchOpts().ModuleFileHomeIsCwd) {
1497 // Use the current working directory as the base path for all inputs.
1498 auto CWD = FileMgr.getOptionalDirectoryRef(DirName: ".");
1499 return CWD->getName();
1500 }
1501 if (WritingModule->Directory) {
1502 return WritingModule->Directory->getName();
1503 }
1504 return std::nullopt;
1505 }();
1506 if (BaseDir) {
1507 cleanPathForOutput(FileMgr, Path&: *BaseDir);
1508
1509 // If the home of the module is the current working directory, then we
1510 // want to pick up the cwd of the build process loading the module, not
1511 // our cwd, when we load this module.
1512 if (!PP.getHeaderSearchInfo().getHeaderSearchOpts().ModuleFileHomeIsCwd &&
1513 (!PP.getHeaderSearchInfo()
1514 .getHeaderSearchOpts()
1515 .ModuleMapFileHomeIsCwd ||
1516 WritingModule->Directory->getName() != ".")) {
1517 // Module directory.
1518 auto Abbrev = std::make_shared<BitCodeAbbrev>();
1519 Abbrev->Add(OpInfo: BitCodeAbbrevOp(MODULE_DIRECTORY));
1520 Abbrev->Add(OpInfo: BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // Directory
1521 unsigned AbbrevCode = Stream.EmitAbbrev(Abbv: std::move(Abbrev));
1522
1523 RecordData::value_type Record[] = {MODULE_DIRECTORY};
1524 Stream.EmitRecordWithBlob(Abbrev: AbbrevCode, Vals: Record, Blob: *BaseDir);
1525 }
1526
1527 // Write out all other paths relative to the base directory if possible.
1528 BaseDirectory.assign(first: BaseDir->begin(), last: BaseDir->end());
1529 } else if (!isysroot.empty()) {
1530 // Write out paths relative to the sysroot if possible.
1531 BaseDirectory = std::string(isysroot);
1532 }
1533 }
1534
1535 // Module map file
1536 if (WritingModule && WritingModule->Kind == Module::ModuleMapModule) {
1537 Record.clear();
1538
1539 auto &Map = PP.getHeaderSearchInfo().getModuleMap();
1540 AddPath(Path: WritingModule->PresumedModuleMapFile.empty()
1541 ? Map.getModuleMapFileForUniquing(M: WritingModule)
1542 ->getNameAsRequested()
1543 : StringRef(WritingModule->PresumedModuleMapFile),
1544 Record);
1545
1546 // Additional module map files.
1547 if (auto *AdditionalModMaps =
1548 Map.getAdditionalModuleMapFiles(M: WritingModule)) {
1549 Record.push_back(Elt: AdditionalModMaps->size());
1550 SmallVector<FileEntryRef, 1> ModMaps(AdditionalModMaps->begin(),
1551 AdditionalModMaps->end());
1552 llvm::sort(C&: ModMaps, Comp: [](FileEntryRef A, FileEntryRef B) {
1553 return A.getName() < B.getName();
1554 });
1555 for (FileEntryRef F : ModMaps)
1556 AddPath(Path: F.getName(), Record);
1557 } else {
1558 Record.push_back(Elt: 0);
1559 }
1560
1561 Stream.EmitRecord(Code: MODULE_MAP_FILE, Vals: Record);
1562 }
1563
1564 // Imports
1565 if (Chain) {
1566 auto Abbrev = std::make_shared<BitCodeAbbrev>();
1567 Abbrev->Add(OpInfo: BitCodeAbbrevOp(IMPORT));
1568 Abbrev->Add(OpInfo: BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 3)); // Kind
1569 Abbrev->Add(OpInfo: BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // ImportLoc
1570 Abbrev->Add(OpInfo: BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Module name len
1571 Abbrev->Add(OpInfo: BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // Standard C++ mod
1572 Abbrev->Add(OpInfo: BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // File size
1573 Abbrev->Add(OpInfo: BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // File timestamp
1574 Abbrev->Add(OpInfo: BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // File name len
1575 Abbrev->Add(OpInfo: BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // Strings
1576 unsigned AbbrevCode = Stream.EmitAbbrev(Abbv: std::move(Abbrev));
1577
1578 SmallString<128> Blob;
1579
1580 for (ModuleFile &M : Chain->getModuleManager()) {
1581 // Skip modules that weren't directly imported.
1582 if (!M.isDirectlyImported())
1583 continue;
1584
1585 Record.clear();
1586 Blob.clear();
1587
1588 Record.push_back(Elt: IMPORT);
1589 Record.push_back(Elt: (unsigned)M.Kind); // FIXME: Stable encoding
1590 AddSourceLocation(Loc: M.ImportLoc, Record);
1591 AddStringBlob(Str: M.ModuleName, Record, Blob);
1592 Record.push_back(Elt: M.StandardCXXModule);
1593
1594 // We don't want to hard code the information about imported modules
1595 // in the C++20 named modules.
1596 if (M.StandardCXXModule) {
1597 Record.push_back(Elt: 0);
1598 Record.push_back(Elt: 0);
1599 Record.push_back(Elt: 0);
1600 } else {
1601 // If we have calculated signature, there is no need to store
1602 // the size or timestamp.
1603 Record.push_back(Elt: M.Signature ? 0 : M.File.getSize());
1604 Record.push_back(Elt: M.Signature ? 0 : getTimestampForOutput(E: M.File));
1605
1606 llvm::append_range(C&: Blob, R&: M.Signature);
1607
1608 AddPathBlob(Str: M.FileName, Record, Blob);
1609 }
1610
1611 Stream.EmitRecordWithBlob(Abbrev: AbbrevCode, Vals: Record, Blob);
1612 }
1613 }
1614
1615 // Write the options block.
1616 Stream.EnterSubblock(BlockID: OPTIONS_BLOCK_ID, CodeLen: 4);
1617
1618 // Language options.
1619 Record.clear();
1620 const LangOptions &LangOpts = PP.getLangOpts();
1621#define LANGOPT(Name, Bits, Default, Compatibility, Description) \
1622 Record.push_back(LangOpts.Name);
1623#define ENUM_LANGOPT(Name, Type, Bits, Default, Compatibility, Description) \
1624 Record.push_back(static_cast<unsigned>(LangOpts.get##Name()));
1625#include "clang/Basic/LangOptions.def"
1626#define SANITIZER(NAME, ID) \
1627 Record.push_back(LangOpts.Sanitize.has(SanitizerKind::ID));
1628#include "clang/Basic/Sanitizers.def"
1629
1630 Record.push_back(Elt: LangOpts.ModuleFeatures.size());
1631 for (StringRef Feature : LangOpts.ModuleFeatures)
1632 AddString(Str: Feature, Record);
1633
1634 Record.push_back(Elt: (unsigned) LangOpts.ObjCRuntime.getKind());
1635 AddVersionTuple(Version: LangOpts.ObjCRuntime.getVersion(), Record);
1636
1637 AddString(Str: LangOpts.CurrentModule, Record);
1638
1639 // Comment options.
1640 Record.push_back(Elt: LangOpts.CommentOpts.BlockCommandNames.size());
1641 for (const auto &I : LangOpts.CommentOpts.BlockCommandNames) {
1642 AddString(Str: I, Record);
1643 }
1644 Record.push_back(Elt: LangOpts.CommentOpts.ParseAllComments);
1645
1646 // OpenMP offloading options.
1647 Record.push_back(Elt: LangOpts.OMPTargetTriples.size());
1648 for (auto &T : LangOpts.OMPTargetTriples)
1649 AddString(Str: T.getTriple(), Record);
1650
1651 AddString(Str: LangOpts.OMPHostIRFile, Record);
1652
1653 Stream.EmitRecord(Code: LANGUAGE_OPTIONS, Vals: Record);
1654
1655 // Codegen options.
1656 // FIXME: Replace with C++20 `using enum CodeGenOptions::CompatibilityKind`.
1657 using CK = CodeGenOptions::CompatibilityKind;
1658 Record.clear();
1659 const CodeGenOptions &CGOpts = getCodeGenOpts();
1660#define CODEGENOPT(Name, Bits, Default, Compatibility) \
1661 if constexpr (CK::Compatibility != CK::Benign) \
1662 Record.push_back(static_cast<unsigned>(CGOpts.Name));
1663#define ENUM_CODEGENOPT(Name, Type, Bits, Default, Compatibility) \
1664 if constexpr (CK::Compatibility != CK::Benign) \
1665 Record.push_back(static_cast<unsigned>(CGOpts.get##Name()));
1666#define DEBUGOPT(Name, Bits, Default, Compatibility)
1667#define VALUE_DEBUGOPT(Name, Bits, Default, Compatibility)
1668#define ENUM_DEBUGOPT(Name, Type, Bits, Default, Compatibility)
1669#include "clang/Basic/CodeGenOptions.def"
1670 Stream.EmitRecord(Code: CODEGEN_OPTIONS, Vals: Record);
1671
1672 // Target options.
1673 Record.clear();
1674 const TargetInfo &Target = PP.getTargetInfo();
1675 const TargetOptions &TargetOpts = Target.getTargetOpts();
1676 AddString(Str: TargetOpts.Triple, Record);
1677 AddString(Str: TargetOpts.CPU, Record);
1678 AddString(Str: TargetOpts.TuneCPU, Record);
1679 AddString(Str: TargetOpts.ABI, Record);
1680 Record.push_back(Elt: TargetOpts.FeaturesAsWritten.size());
1681 for (unsigned I = 0, N = TargetOpts.FeaturesAsWritten.size(); I != N; ++I) {
1682 AddString(Str: TargetOpts.FeaturesAsWritten[I], Record);
1683 }
1684 Record.push_back(Elt: TargetOpts.Features.size());
1685 for (unsigned I = 0, N = TargetOpts.Features.size(); I != N; ++I) {
1686 AddString(Str: TargetOpts.Features[I], Record);
1687 }
1688 Stream.EmitRecord(Code: TARGET_OPTIONS, Vals: Record);
1689
1690 // File system options.
1691 Record.clear();
1692 const FileSystemOptions &FSOpts = FileMgr.getFileSystemOpts();
1693 AddString(Str: FSOpts.WorkingDir, Record);
1694 Stream.EmitRecord(Code: FILE_SYSTEM_OPTIONS, Vals: Record);
1695
1696 // Header search options.
1697 Record.clear();
1698 const HeaderSearchOptions &HSOpts =
1699 PP.getHeaderSearchInfo().getHeaderSearchOpts();
1700
1701 SmallString<256> HSOpts_ModuleCachePath;
1702 normalizeModuleCachePath(FileMgr&: PP.getFileManager(), Path: HSOpts.ModuleCachePath,
1703 NormalizedPath&: HSOpts_ModuleCachePath);
1704
1705 AddString(Str: HSOpts.Sysroot, Record);
1706 AddString(Str: HSOpts.ResourceDir, Record);
1707 AddString(Str: HSOpts_ModuleCachePath, Record);
1708 AddString(Str: HSOpts.ModuleUserBuildPath, Record);
1709 Record.push_back(Elt: HSOpts.DisableModuleHash);
1710 Record.push_back(Elt: HSOpts.ImplicitModuleMaps);
1711 Record.push_back(Elt: HSOpts.ModuleMapFileHomeIsCwd);
1712 Record.push_back(Elt: HSOpts.EnablePrebuiltImplicitModules);
1713 Record.push_back(Elt: HSOpts.UseBuiltinIncludes);
1714 Record.push_back(Elt: HSOpts.UseStandardSystemIncludes);
1715 Record.push_back(Elt: HSOpts.UseStandardCXXIncludes);
1716 Record.push_back(Elt: HSOpts.UseLibcxx);
1717 // Write out the specific module cache path that contains the module files.
1718 // FIXME: We already wrote out the normalized cache path. Just write the
1719 // context hash (unless suppressed).
1720 AddString(Str: PP.getHeaderSearchInfo().getSpecificModuleCachePath(), Record);
1721 Stream.EmitRecord(Code: HEADER_SEARCH_OPTIONS, Vals: Record);
1722
1723 // Preprocessor options.
1724 Record.clear();
1725 const PreprocessorOptions &PPOpts = PP.getPreprocessorOpts();
1726
1727 // If we're building an implicit module with a context hash, the importer is
1728 // guaranteed to have the same macros defined on the command line. Skip
1729 // writing them.
1730 bool SkipMacros = BuildingImplicitModule && !HSOpts.DisableModuleHash;
1731 bool WriteMacros = !SkipMacros;
1732 Record.push_back(Elt: WriteMacros);
1733 if (WriteMacros) {
1734 // Macro definitions.
1735 Record.push_back(Elt: PPOpts.Macros.size());
1736 for (unsigned I = 0, N = PPOpts.Macros.size(); I != N; ++I) {
1737 AddString(Str: PPOpts.Macros[I].first, Record);
1738 Record.push_back(Elt: PPOpts.Macros[I].second);
1739 }
1740 }
1741
1742 // Includes
1743 Record.push_back(Elt: PPOpts.Includes.size());
1744 for (unsigned I = 0, N = PPOpts.Includes.size(); I != N; ++I)
1745 AddString(Str: PPOpts.Includes[I], Record);
1746
1747 // Macro includes
1748 Record.push_back(Elt: PPOpts.MacroIncludes.size());
1749 for (unsigned I = 0, N = PPOpts.MacroIncludes.size(); I != N; ++I)
1750 AddString(Str: PPOpts.MacroIncludes[I], Record);
1751
1752 Record.push_back(Elt: PPOpts.UsePredefines);
1753 // Detailed record is important since it is used for the module cache hash.
1754 Record.push_back(Elt: PPOpts.DetailedRecord);
1755 AddString(Str: PPOpts.ImplicitPCHInclude, Record);
1756 Record.push_back(Elt: static_cast<unsigned>(PPOpts.ObjCXXARCStandardLibrary));
1757 Stream.EmitRecord(Code: PREPROCESSOR_OPTIONS, Vals: Record);
1758
1759 // Leave the options block.
1760 Stream.ExitBlock();
1761
1762 // Original file name and file ID
1763 if (auto MainFile =
1764 SourceMgr.getFileEntryRefForID(FID: SourceMgr.getMainFileID())) {
1765 auto FileAbbrev = std::make_shared<BitCodeAbbrev>();
1766 FileAbbrev->Add(OpInfo: BitCodeAbbrevOp(ORIGINAL_FILE));
1767 FileAbbrev->Add(OpInfo: BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // File ID
1768 FileAbbrev->Add(OpInfo: BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // File name
1769 unsigned FileAbbrevCode = Stream.EmitAbbrev(Abbv: std::move(FileAbbrev));
1770
1771 Record.clear();
1772 Record.push_back(Elt: ORIGINAL_FILE);
1773 AddFileID(FID: SourceMgr.getMainFileID(), Record);
1774 EmitRecordWithPath(Abbrev: FileAbbrevCode, Record, Path: MainFile->getName());
1775 }
1776
1777 Record.clear();
1778 AddFileID(FID: SourceMgr.getMainFileID(), Record);
1779 Stream.EmitRecord(Code: ORIGINAL_FILE_ID, Vals: Record);
1780
1781 WriteInputFiles(SourceMgr);
1782 Stream.ExitBlock();
1783}
1784
1785namespace {
1786
1787/// An input file.
1788struct InputFileEntry {
1789 FileEntryRef File;
1790 bool IsSystemFile;
1791 bool IsTransient;
1792 bool BufferOverridden;
1793 bool IsTopLevel;
1794 bool IsModuleMap;
1795 uint32_t ContentHash[2];
1796
1797 InputFileEntry(FileEntryRef File) : File(File) {}
1798
1799 void trySetContentHash(
1800 Preprocessor &PP,
1801 llvm::function_ref<std::optional<llvm::MemoryBufferRef>()> GetMemBuff) {
1802 ContentHash[0] = 0;
1803 ContentHash[1] = 0;
1804
1805 if (!PP.getHeaderSearchInfo()
1806 .getHeaderSearchOpts()
1807 .ValidateASTInputFilesContent)
1808 return;
1809
1810 auto MemBuff = GetMemBuff();
1811 if (!MemBuff) {
1812 PP.Diag(Loc: SourceLocation(), DiagID: diag::err_module_unable_to_hash_content)
1813 << File.getName();
1814 return;
1815 }
1816
1817 uint64_t Hash = xxh3_64bits(data: MemBuff->getBuffer());
1818 ContentHash[0] = uint32_t(Hash);
1819 ContentHash[1] = uint32_t(Hash >> 32);
1820 }
1821};
1822
1823} // namespace
1824
1825SourceLocation ASTWriter::getAffectingIncludeLoc(const SourceManager &SourceMgr,
1826 const SrcMgr::FileInfo &File) {
1827 SourceLocation IncludeLoc = File.getIncludeLoc();
1828 if (IncludeLoc.isValid()) {
1829 FileID IncludeFID = SourceMgr.getFileID(SpellingLoc: IncludeLoc);
1830 assert(IncludeFID.isValid() && "IncludeLoc in invalid file");
1831 if (!IsSLocAffecting[IncludeFID.ID])
1832 IncludeLoc = SourceLocation();
1833 }
1834 return IncludeLoc;
1835}
1836
1837void ASTWriter::WriteInputFiles(SourceManager &SourceMgr) {
1838 using namespace llvm;
1839
1840 Stream.EnterSubblock(BlockID: INPUT_FILES_BLOCK_ID, CodeLen: 4);
1841
1842 // Create input-file abbreviation.
1843 auto IFAbbrev = std::make_shared<BitCodeAbbrev>();
1844 IFAbbrev->Add(OpInfo: BitCodeAbbrevOp(INPUT_FILE));
1845 IFAbbrev->Add(OpInfo: BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // ID
1846 IFAbbrev->Add(OpInfo: BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 12)); // Size
1847 IFAbbrev->Add(OpInfo: BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 32)); // Modification time
1848 IFAbbrev->Add(OpInfo: BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // Overridden
1849 IFAbbrev->Add(OpInfo: BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // Transient
1850 IFAbbrev->Add(OpInfo: BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // Top-level
1851 IFAbbrev->Add(OpInfo: BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // Module map
1852 IFAbbrev->Add(OpInfo: BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 16)); // Name as req. len
1853 IFAbbrev->Add(OpInfo: BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // Name as req. + name
1854 unsigned IFAbbrevCode = Stream.EmitAbbrev(Abbv: std::move(IFAbbrev));
1855
1856 // Create input file hash abbreviation.
1857 auto IFHAbbrev = std::make_shared<BitCodeAbbrev>();
1858 IFHAbbrev->Add(OpInfo: BitCodeAbbrevOp(INPUT_FILE_HASH));
1859 IFHAbbrev->Add(OpInfo: BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32));
1860 IFHAbbrev->Add(OpInfo: BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32));
1861 unsigned IFHAbbrevCode = Stream.EmitAbbrev(Abbv: std::move(IFHAbbrev));
1862
1863 uint64_t InputFilesOffsetBase = Stream.GetCurrentBitNo();
1864
1865 // Get all ContentCache objects for files.
1866 std::vector<InputFileEntry> UserFiles;
1867 std::vector<InputFileEntry> SystemFiles;
1868 for (unsigned I = 1, N = SourceMgr.local_sloc_entry_size(); I != N; ++I) {
1869 // Get this source location entry.
1870 const SrcMgr::SLocEntry *SLoc = &SourceMgr.getLocalSLocEntry(Index: I);
1871 assert(&SourceMgr.getSLocEntry(FileID::get(I)) == SLoc);
1872
1873 // We only care about file entries that were not overridden.
1874 if (!SLoc->isFile())
1875 continue;
1876 const SrcMgr::FileInfo &File = SLoc->getFile();
1877 const SrcMgr::ContentCache *Cache = &File.getContentCache();
1878 if (!Cache->OrigEntry)
1879 continue;
1880
1881 // Do not emit input files that do not affect current module.
1882 if (!IsSLocFileEntryAffecting[I])
1883 continue;
1884
1885 InputFileEntry Entry(*Cache->OrigEntry);
1886 Entry.IsSystemFile = isSystem(CK: File.getFileCharacteristic());
1887 Entry.IsTransient = Cache->IsTransient;
1888 Entry.BufferOverridden = Cache->BufferOverridden;
1889
1890 FileID IncludeFileID = SourceMgr.getFileID(SpellingLoc: File.getIncludeLoc());
1891 Entry.IsTopLevel = IncludeFileID.isInvalid() || IncludeFileID.ID < 0 ||
1892 !IsSLocFileEntryAffecting[IncludeFileID.ID];
1893 Entry.IsModuleMap = isModuleMap(CK: File.getFileCharacteristic());
1894
1895 Entry.trySetContentHash(PP&: *PP, GetMemBuff: [&] { return Cache->getBufferIfLoaded(); });
1896
1897 if (Entry.IsSystemFile)
1898 SystemFiles.push_back(x: Entry);
1899 else
1900 UserFiles.push_back(x: Entry);
1901 }
1902
1903 // FIXME: Make providing input files not in the SourceManager more flexible.
1904 // The SDKSettings.json file is necessary for correct evaluation of
1905 // availability annotations.
1906 StringRef Sysroot = PP->getHeaderSearchInfo().getHeaderSearchOpts().Sysroot;
1907 if (!Sysroot.empty()) {
1908 SmallString<128> SDKSettingsJSON = Sysroot;
1909 llvm::sys::path::append(path&: SDKSettingsJSON, a: "SDKSettings.json");
1910 FileManager &FM = PP->getFileManager();
1911 if (auto FE = FM.getOptionalFileRef(Filename: SDKSettingsJSON)) {
1912 InputFileEntry Entry(*FE);
1913 Entry.IsSystemFile = true;
1914 Entry.IsTransient = false;
1915 Entry.BufferOverridden = false;
1916 Entry.IsTopLevel = true;
1917 Entry.IsModuleMap = false;
1918 std::unique_ptr<MemoryBuffer> MB;
1919 Entry.trySetContentHash(PP&: *PP, GetMemBuff: [&]() -> std::optional<MemoryBufferRef> {
1920 if (auto MBOrErr = FM.getBufferForFile(Entry: Entry.File)) {
1921 MB = std::move(*MBOrErr);
1922 return MB->getMemBufferRef();
1923 }
1924 return std::nullopt;
1925 });
1926 SystemFiles.push_back(x: Entry);
1927 }
1928 }
1929
1930 // User files go at the front, system files at the back.
1931 auto SortedFiles = llvm::concat<InputFileEntry>(Ranges: std::move(UserFiles),
1932 Ranges: std::move(SystemFiles));
1933
1934 unsigned UserFilesNum = 0;
1935 // Write out all of the input files.
1936 std::vector<uint64_t> InputFileOffsets;
1937 for (const auto &Entry : SortedFiles) {
1938 uint32_t &InputFileID = InputFileIDs[Entry.File];
1939 if (InputFileID != 0)
1940 continue; // already recorded this file.
1941
1942 // Record this entry's offset.
1943 InputFileOffsets.push_back(x: Stream.GetCurrentBitNo() - InputFilesOffsetBase);
1944
1945 InputFileID = InputFileOffsets.size();
1946
1947 if (!Entry.IsSystemFile)
1948 ++UserFilesNum;
1949
1950 // Emit size/modification time for this file.
1951 // And whether this file was overridden.
1952 {
1953 SmallString<128> NameAsRequested = Entry.File.getNameAsRequested();
1954 SmallString<128> Name = Entry.File.getName();
1955
1956 PreparePathForOutput(Path&: NameAsRequested);
1957 PreparePathForOutput(Path&: Name);
1958
1959 if (Name == NameAsRequested)
1960 Name.clear();
1961
1962 RecordData::value_type Record[] = {
1963 INPUT_FILE,
1964 InputFileOffsets.size(),
1965 (uint64_t)Entry.File.getSize(),
1966 (uint64_t)getTimestampForOutput(E: Entry.File),
1967 Entry.BufferOverridden,
1968 Entry.IsTransient,
1969 Entry.IsTopLevel,
1970 Entry.IsModuleMap,
1971 NameAsRequested.size()};
1972
1973 Stream.EmitRecordWithBlob(Abbrev: IFAbbrevCode, Vals: Record,
1974 Blob: (NameAsRequested + Name).str());
1975 }
1976
1977 // Emit content hash for this file.
1978 {
1979 RecordData::value_type Record[] = {INPUT_FILE_HASH, Entry.ContentHash[0],
1980 Entry.ContentHash[1]};
1981 Stream.EmitRecordWithAbbrev(Abbrev: IFHAbbrevCode, Vals: Record);
1982 }
1983 }
1984
1985 Stream.ExitBlock();
1986
1987 // Create input file offsets abbreviation.
1988 auto OffsetsAbbrev = std::make_shared<BitCodeAbbrev>();
1989 OffsetsAbbrev->Add(OpInfo: BitCodeAbbrevOp(INPUT_FILE_OFFSETS));
1990 OffsetsAbbrev->Add(OpInfo: BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // # input files
1991 OffsetsAbbrev->Add(OpInfo: BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // # non-system
1992 // input files
1993 OffsetsAbbrev->Add(OpInfo: BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // Array
1994 unsigned OffsetsAbbrevCode = Stream.EmitAbbrev(Abbv: std::move(OffsetsAbbrev));
1995
1996 // Write input file offsets.
1997 RecordData::value_type Record[] = {INPUT_FILE_OFFSETS,
1998 InputFileOffsets.size(), UserFilesNum};
1999 Stream.EmitRecordWithBlob(Abbrev: OffsetsAbbrevCode, Vals: Record, Blob: bytes(v: InputFileOffsets));
2000}
2001
2002//===----------------------------------------------------------------------===//
2003// Source Manager Serialization
2004//===----------------------------------------------------------------------===//
2005
2006/// Create an abbreviation for the SLocEntry that refers to a
2007/// file.
2008static unsigned CreateSLocFileAbbrev(llvm::BitstreamWriter &Stream) {
2009 using namespace llvm;
2010
2011 auto Abbrev = std::make_shared<BitCodeAbbrev>();
2012 Abbrev->Add(OpInfo: BitCodeAbbrevOp(SM_SLOC_FILE_ENTRY));
2013 Abbrev->Add(OpInfo: BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); // Offset
2014 Abbrev->Add(OpInfo: BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); // Include location
2015 Abbrev->Add(OpInfo: BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 3)); // Characteristic
2016 Abbrev->Add(OpInfo: BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // Line directives
2017 // FileEntry fields.
2018 Abbrev->Add(OpInfo: BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Input File ID
2019 Abbrev->Add(OpInfo: BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); // NumCreatedFIDs
2020 Abbrev->Add(OpInfo: BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 24)); // FirstDeclIndex
2021 Abbrev->Add(OpInfo: BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); // NumDecls
2022 return Stream.EmitAbbrev(Abbv: std::move(Abbrev));
2023}
2024
2025/// Create an abbreviation for the SLocEntry that refers to a
2026/// buffer.
2027static unsigned CreateSLocBufferAbbrev(llvm::BitstreamWriter &Stream) {
2028 using namespace llvm;
2029
2030 auto Abbrev = std::make_shared<BitCodeAbbrev>();
2031 Abbrev->Add(OpInfo: BitCodeAbbrevOp(SM_SLOC_BUFFER_ENTRY));
2032 Abbrev->Add(OpInfo: BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); // Offset
2033 Abbrev->Add(OpInfo: BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); // Include location
2034 Abbrev->Add(OpInfo: BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 3)); // Characteristic
2035 Abbrev->Add(OpInfo: BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // Line directives
2036 Abbrev->Add(OpInfo: BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // Buffer name blob
2037 return Stream.EmitAbbrev(Abbv: std::move(Abbrev));
2038}
2039
2040/// Create an abbreviation for the SLocEntry that refers to a
2041/// buffer's blob.
2042static unsigned CreateSLocBufferBlobAbbrev(llvm::BitstreamWriter &Stream,
2043 bool Compressed) {
2044 using namespace llvm;
2045
2046 auto Abbrev = std::make_shared<BitCodeAbbrev>();
2047 Abbrev->Add(OpInfo: BitCodeAbbrevOp(Compressed ? SM_SLOC_BUFFER_BLOB_COMPRESSED
2048 : SM_SLOC_BUFFER_BLOB));
2049 if (Compressed)
2050 Abbrev->Add(OpInfo: BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); // Uncompressed size
2051 Abbrev->Add(OpInfo: BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // Blob
2052 return Stream.EmitAbbrev(Abbv: std::move(Abbrev));
2053}
2054
2055/// Create an abbreviation for the SLocEntry that refers to a macro
2056/// expansion.
2057static unsigned CreateSLocExpansionAbbrev(llvm::BitstreamWriter &Stream) {
2058 using namespace llvm;
2059
2060 auto Abbrev = std::make_shared<BitCodeAbbrev>();
2061 Abbrev->Add(OpInfo: BitCodeAbbrevOp(SM_SLOC_EXPANSION_ENTRY));
2062 Abbrev->Add(OpInfo: BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); // Offset
2063 Abbrev->Add(OpInfo: BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); // Spelling location
2064 Abbrev->Add(OpInfo: BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Start location
2065 Abbrev->Add(OpInfo: BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // End location
2066 Abbrev->Add(OpInfo: BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // Is token range
2067 Abbrev->Add(OpInfo: BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Token length
2068 return Stream.EmitAbbrev(Abbv: std::move(Abbrev));
2069}
2070
2071/// Emit key length and data length as ULEB-encoded data, and return them as a
2072/// pair.
2073static std::pair<unsigned, unsigned>
2074emitULEBKeyDataLength(unsigned KeyLen, unsigned DataLen, raw_ostream &Out) {
2075 llvm::encodeULEB128(Value: KeyLen, OS&: Out);
2076 llvm::encodeULEB128(Value: DataLen, OS&: Out);
2077 return std::make_pair(x&: KeyLen, y&: DataLen);
2078}
2079
2080namespace {
2081
2082 // Trait used for the on-disk hash table of header search information.
2083 class HeaderFileInfoTrait {
2084 ASTWriter &Writer;
2085
2086 public:
2087 HeaderFileInfoTrait(ASTWriter &Writer) : Writer(Writer) {}
2088
2089 struct key_type {
2090 StringRef Filename;
2091 off_t Size;
2092 time_t ModTime;
2093 };
2094 using key_type_ref = const key_type &;
2095
2096 using UnresolvedModule =
2097 llvm::PointerIntPair<Module *, 2, ModuleMap::ModuleHeaderRole>;
2098
2099 struct data_type {
2100 data_type(const HeaderFileInfo &HFI, bool AlreadyIncluded,
2101 ArrayRef<ModuleMap::KnownHeader> KnownHeaders,
2102 UnresolvedModule Unresolved)
2103 : HFI(HFI), AlreadyIncluded(AlreadyIncluded),
2104 KnownHeaders(KnownHeaders), Unresolved(Unresolved) {}
2105
2106 HeaderFileInfo HFI;
2107 bool AlreadyIncluded;
2108 SmallVector<ModuleMap::KnownHeader, 1> KnownHeaders;
2109 UnresolvedModule Unresolved;
2110 };
2111 using data_type_ref = const data_type &;
2112
2113 using hash_value_type = unsigned;
2114 using offset_type = unsigned;
2115
2116 hash_value_type ComputeHash(key_type_ref key) {
2117 // The hash is based only on size/time of the file, so that the reader can
2118 // match even when symlinking or excess path elements ("foo/../", "../")
2119 // change the form of the name. However, complete path is still the key.
2120 uint8_t buf[sizeof(key.Size) + sizeof(key.ModTime)];
2121 memcpy(dest: buf, src: &key.Size, n: sizeof(key.Size));
2122 memcpy(dest: buf + sizeof(key.Size), src: &key.ModTime, n: sizeof(key.ModTime));
2123 return llvm::xxh3_64bits(data: buf);
2124 }
2125
2126 std::pair<unsigned, unsigned>
2127 EmitKeyDataLength(raw_ostream& Out, key_type_ref key, data_type_ref Data) {
2128 unsigned KeyLen = key.Filename.size() + 1 + 8 + 8;
2129 unsigned DataLen = 1 + sizeof(IdentifierID);
2130 for (auto ModInfo : Data.KnownHeaders)
2131 if (Writer.getLocalOrImportedSubmoduleID(Mod: ModInfo.getModule()))
2132 DataLen += 4;
2133 if (Data.Unresolved.getPointer())
2134 DataLen += 4;
2135 return emitULEBKeyDataLength(KeyLen, DataLen, Out);
2136 }
2137
2138 void EmitKey(raw_ostream& Out, key_type_ref key, unsigned KeyLen) {
2139 using namespace llvm::support;
2140
2141 endian::Writer LE(Out, llvm::endianness::little);
2142 LE.write<uint64_t>(Val: key.Size);
2143 KeyLen -= 8;
2144 LE.write<uint64_t>(Val: key.ModTime);
2145 KeyLen -= 8;
2146 Out.write(Ptr: key.Filename.data(), Size: KeyLen);
2147 }
2148
2149 void EmitData(raw_ostream &Out, key_type_ref key,
2150 data_type_ref Data, unsigned DataLen) {
2151 using namespace llvm::support;
2152
2153 endian::Writer LE(Out, llvm::endianness::little);
2154 uint64_t Start = Out.tell(); (void)Start;
2155
2156 unsigned char Flags = (Data.AlreadyIncluded << 6)
2157 | (Data.HFI.isImport << 5)
2158 | (Writer.isWritingStdCXXNamedModules() ? 0 :
2159 Data.HFI.isPragmaOnce << 4)
2160 | (Data.HFI.DirInfo << 1);
2161 LE.write<uint8_t>(Val: Flags);
2162
2163 if (Data.HFI.LazyControllingMacro.isID())
2164 LE.write<IdentifierID>(Val: Data.HFI.LazyControllingMacro.getID());
2165 else
2166 LE.write<IdentifierID>(
2167 Val: Writer.getIdentifierRef(II: Data.HFI.LazyControllingMacro.getPtr()));
2168
2169 auto EmitModule = [&](Module *M, ModuleMap::ModuleHeaderRole Role) {
2170 if (uint32_t ModID = Writer.getLocalOrImportedSubmoduleID(Mod: M)) {
2171 uint32_t Value = (ModID << 3) | (unsigned)Role;
2172 assert((Value >> 3) == ModID && "overflow in header module info");
2173 LE.write<uint32_t>(Val: Value);
2174 }
2175 };
2176
2177 for (auto ModInfo : Data.KnownHeaders)
2178 EmitModule(ModInfo.getModule(), ModInfo.getRole());
2179 if (Data.Unresolved.getPointer())
2180 EmitModule(Data.Unresolved.getPointer(), Data.Unresolved.getInt());
2181
2182 assert(Out.tell() - Start == DataLen && "Wrong data length");
2183 }
2184 };
2185
2186} // namespace
2187
2188/// Write the header search block for the list of files that
2189///
2190/// \param HS The header search structure to save.
2191void ASTWriter::WriteHeaderSearch(const HeaderSearch &HS) {
2192 HeaderFileInfoTrait GeneratorTrait(*this);
2193 llvm::OnDiskChainedHashTableGenerator<HeaderFileInfoTrait> Generator;
2194 SmallVector<const char *, 4> SavedStrings;
2195 unsigned NumHeaderSearchEntries = 0;
2196
2197 // Find all unresolved headers for the current module. We generally will
2198 // have resolved them before we get here, but not necessarily: we might be
2199 // compiling a preprocessed module, where there is no requirement for the
2200 // original files to exist any more.
2201 const HeaderFileInfo Empty; // So we can take a reference.
2202 if (WritingModule) {
2203 llvm::SmallVector<Module *, 16> Worklist(1, WritingModule);
2204 while (!Worklist.empty()) {
2205 Module *M = Worklist.pop_back_val();
2206 // We don't care about headers in unimportable submodules.
2207 if (M->isUnimportable())
2208 continue;
2209
2210 // Map to disk files where possible, to pick up any missing stat
2211 // information. This also means we don't need to check the unresolved
2212 // headers list when emitting resolved headers in the first loop below.
2213 // FIXME: It'd be preferable to avoid doing this if we were given
2214 // sufficient stat information in the module map.
2215 HS.getModuleMap().resolveHeaderDirectives(Mod: M, /*File=*/std::nullopt);
2216
2217 // If the file didn't exist, we can still create a module if we were given
2218 // enough information in the module map.
2219 for (const auto &U : M->MissingHeaders) {
2220 // Check that we were given enough information to build a module
2221 // without this file existing on disk.
2222 if (!U.Size || (!U.ModTime && IncludeTimestamps)) {
2223 PP->Diag(Loc: U.FileNameLoc, DiagID: diag::err_module_no_size_mtime_for_header)
2224 << WritingModule->getFullModuleName() << U.Size.has_value()
2225 << U.FileName;
2226 continue;
2227 }
2228
2229 // Form the effective relative pathname for the file.
2230 SmallString<128> Filename(M->Directory->getName());
2231 llvm::sys::path::append(path&: Filename, a: U.FileName);
2232 PreparePathForOutput(Path&: Filename);
2233
2234 StringRef FilenameDup = strdup(s: Filename.c_str());
2235 SavedStrings.push_back(Elt: FilenameDup.data());
2236
2237 HeaderFileInfoTrait::key_type Key = {
2238 .Filename: FilenameDup, .Size: *U.Size, .ModTime: IncludeTimestamps ? *U.ModTime : 0};
2239 HeaderFileInfoTrait::data_type Data = {
2240 Empty, false, {}, {M, ModuleMap::headerKindToRole(Kind: U.Kind)}};
2241 // FIXME: Deal with cases where there are multiple unresolved header
2242 // directives in different submodules for the same header.
2243 Generator.insert(Key, Data, InfoObj&: GeneratorTrait);
2244 ++NumHeaderSearchEntries;
2245 }
2246 auto SubmodulesRange = M->submodules();
2247 Worklist.append(in_start: SubmodulesRange.begin(), in_end: SubmodulesRange.end());
2248 }
2249 }
2250
2251 SmallVector<OptionalFileEntryRef, 16> FilesByUID;
2252 HS.getFileMgr().GetUniqueIDMapping(UIDToFiles&: FilesByUID);
2253
2254 if (FilesByUID.size() > HS.header_file_size())
2255 FilesByUID.resize(N: HS.header_file_size());
2256
2257 for (unsigned UID = 0, LastUID = FilesByUID.size(); UID != LastUID; ++UID) {
2258 OptionalFileEntryRef File = FilesByUID[UID];
2259 if (!File)
2260 continue;
2261
2262 const HeaderFileInfo *HFI = HS.getExistingLocalFileInfo(FE: *File);
2263 if (!HFI)
2264 continue; // We have no information on this being a header file.
2265 if (!HFI->isCompilingModuleHeader && HFI->isModuleHeader)
2266 continue; // Header file info is tracked by the owning module file.
2267 if (!HFI->isCompilingModuleHeader && !HFI->IsLocallyIncluded)
2268 continue; // Header file info is tracked by the including module file.
2269
2270 // Massage the file path into an appropriate form.
2271 StringRef Filename = File->getName();
2272 SmallString<128> FilenameTmp(Filename);
2273 if (PreparePathForOutput(Path&: FilenameTmp)) {
2274 // If we performed any translation on the file name at all, we need to
2275 // save this string, since the generator will refer to it later.
2276 Filename = StringRef(strdup(s: FilenameTmp.c_str()));
2277 SavedStrings.push_back(Elt: Filename.data());
2278 }
2279
2280 bool Included = HFI->IsLocallyIncluded || PP->alreadyIncluded(File: *File);
2281
2282 HeaderFileInfoTrait::key_type Key = {
2283 .Filename: Filename, .Size: File->getSize(), .ModTime: getTimestampForOutput(E: *File)
2284 };
2285 HeaderFileInfoTrait::data_type Data = {
2286 *HFI, Included, HS.getModuleMap().findResolvedModulesForHeader(File: *File), {}
2287 };
2288 Generator.insert(Key, Data, InfoObj&: GeneratorTrait);
2289 ++NumHeaderSearchEntries;
2290 }
2291
2292 // Create the on-disk hash table in a buffer.
2293 SmallString<4096> TableData;
2294 uint32_t BucketOffset;
2295 {
2296 using namespace llvm::support;
2297
2298 llvm::raw_svector_ostream Out(TableData);
2299 // Make sure that no bucket is at offset 0
2300 endian::write<uint32_t>(os&: Out, value: 0, endian: llvm::endianness::little);
2301 BucketOffset = Generator.Emit(Out, InfoObj&: GeneratorTrait);
2302 }
2303
2304 // Create a blob abbreviation
2305 using namespace llvm;
2306
2307 auto Abbrev = std::make_shared<BitCodeAbbrev>();
2308 Abbrev->Add(OpInfo: BitCodeAbbrevOp(HEADER_SEARCH_TABLE));
2309 Abbrev->Add(OpInfo: BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32));
2310 Abbrev->Add(OpInfo: BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32));
2311 Abbrev->Add(OpInfo: BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32));
2312 Abbrev->Add(OpInfo: BitCodeAbbrevOp(BitCodeAbbrevOp::Blob));
2313 unsigned TableAbbrev = Stream.EmitAbbrev(Abbv: std::move(Abbrev));
2314
2315 // Write the header search table
2316 RecordData::value_type Record[] = {HEADER_SEARCH_TABLE, BucketOffset,
2317 NumHeaderSearchEntries, TableData.size()};
2318 Stream.EmitRecordWithBlob(Abbrev: TableAbbrev, Vals: Record, Blob: TableData);
2319
2320 // Free all of the strings we had to duplicate.
2321 for (unsigned I = 0, N = SavedStrings.size(); I != N; ++I)
2322 free(ptr: const_cast<char *>(SavedStrings[I]));
2323}
2324
2325static void emitBlob(llvm::BitstreamWriter &Stream, StringRef Blob,
2326 unsigned SLocBufferBlobCompressedAbbrv,
2327 unsigned SLocBufferBlobAbbrv) {
2328 using RecordDataType = ASTWriter::RecordData::value_type;
2329
2330 // Compress the buffer if possible. We expect that almost all PCM
2331 // consumers will not want its contents.
2332 SmallVector<uint8_t, 0> CompressedBuffer;
2333 if (llvm::compression::zstd::isAvailable()) {
2334 llvm::compression::zstd::compress(
2335 Input: llvm::arrayRefFromStringRef(Input: Blob.drop_back(N: 1)), CompressedBuffer, Level: 9);
2336 RecordDataType Record[] = {SM_SLOC_BUFFER_BLOB_COMPRESSED, Blob.size() - 1};
2337 Stream.EmitRecordWithBlob(Abbrev: SLocBufferBlobCompressedAbbrv, Vals: Record,
2338 Blob: llvm::toStringRef(Input: CompressedBuffer));
2339 return;
2340 }
2341 if (llvm::compression::zlib::isAvailable()) {
2342 llvm::compression::zlib::compress(
2343 Input: llvm::arrayRefFromStringRef(Input: Blob.drop_back(N: 1)), CompressedBuffer);
2344 RecordDataType Record[] = {SM_SLOC_BUFFER_BLOB_COMPRESSED, Blob.size() - 1};
2345 Stream.EmitRecordWithBlob(Abbrev: SLocBufferBlobCompressedAbbrv, Vals: Record,
2346 Blob: llvm::toStringRef(Input: CompressedBuffer));
2347 return;
2348 }
2349
2350 RecordDataType Record[] = {SM_SLOC_BUFFER_BLOB};
2351 Stream.EmitRecordWithBlob(Abbrev: SLocBufferBlobAbbrv, Vals: Record, Blob);
2352}
2353
2354/// Writes the block containing the serialized form of the
2355/// source manager.
2356///
2357/// TODO: We should probably use an on-disk hash table (stored in a
2358/// blob), indexed based on the file name, so that we only create
2359/// entries for files that we actually need. In the common case (no
2360/// errors), we probably won't have to create file entries for any of
2361/// the files in the AST.
2362void ASTWriter::WriteSourceManagerBlock(SourceManager &SourceMgr) {
2363 RecordData Record;
2364
2365 // Enter the source manager block.
2366 Stream.EnterSubblock(BlockID: SOURCE_MANAGER_BLOCK_ID, CodeLen: 4);
2367 const uint64_t SourceManagerBlockOffset = Stream.GetCurrentBitNo();
2368
2369 // Abbreviations for the various kinds of source-location entries.
2370 unsigned SLocFileAbbrv = CreateSLocFileAbbrev(Stream);
2371 unsigned SLocBufferAbbrv = CreateSLocBufferAbbrev(Stream);
2372 unsigned SLocBufferBlobAbbrv = CreateSLocBufferBlobAbbrev(Stream, Compressed: false);
2373 unsigned SLocBufferBlobCompressedAbbrv =
2374 CreateSLocBufferBlobAbbrev(Stream, Compressed: true);
2375 unsigned SLocExpansionAbbrv = CreateSLocExpansionAbbrev(Stream);
2376
2377 // Write out the source location entry table. We skip the first
2378 // entry, which is always the same dummy entry.
2379 std::vector<uint32_t> SLocEntryOffsets;
2380 uint64_t SLocEntryOffsetsBase = Stream.GetCurrentBitNo();
2381 SLocEntryOffsets.reserve(n: SourceMgr.local_sloc_entry_size() - 1);
2382 for (unsigned I = 1, N = SourceMgr.local_sloc_entry_size();
2383 I != N; ++I) {
2384 // Get this source location entry.
2385 const SrcMgr::SLocEntry *SLoc = &SourceMgr.getLocalSLocEntry(Index: I);
2386 FileID FID = FileID::get(V: I);
2387 assert(&SourceMgr.getSLocEntry(FID) == SLoc);
2388
2389 // Record the offset of this source-location entry.
2390 uint64_t Offset = Stream.GetCurrentBitNo() - SLocEntryOffsetsBase;
2391 assert((Offset >> 32) == 0 && "SLocEntry offset too large");
2392
2393 // Figure out which record code to use.
2394 unsigned Code;
2395 if (SLoc->isFile()) {
2396 const SrcMgr::ContentCache *Cache = &SLoc->getFile().getContentCache();
2397 if (Cache->OrigEntry) {
2398 Code = SM_SLOC_FILE_ENTRY;
2399 } else
2400 Code = SM_SLOC_BUFFER_ENTRY;
2401 } else
2402 Code = SM_SLOC_EXPANSION_ENTRY;
2403 Record.clear();
2404 Record.push_back(Elt: Code);
2405
2406 if (SLoc->isFile()) {
2407 const SrcMgr::FileInfo &File = SLoc->getFile();
2408 const SrcMgr::ContentCache *Content = &File.getContentCache();
2409 // Do not emit files that were not listed as inputs.
2410 if (!IsSLocAffecting[I])
2411 continue;
2412 SLocEntryOffsets.push_back(x: Offset);
2413 // Starting offset of this entry within this module, so skip the dummy.
2414 Record.push_back(Elt: getAdjustedOffset(Offset: SLoc->getOffset()) - 2);
2415 AddSourceLocation(Loc: getAffectingIncludeLoc(SourceMgr, File), Record);
2416 Record.push_back(Elt: File.getFileCharacteristic()); // FIXME: stable encoding
2417 Record.push_back(Elt: File.hasLineDirectives());
2418
2419 bool EmitBlob = false;
2420 if (Content->OrigEntry) {
2421 assert(Content->OrigEntry == Content->ContentsEntry &&
2422 "Writing to AST an overridden file is not supported");
2423
2424 // The source location entry is a file. Emit input file ID.
2425 assert(InputFileIDs[*Content->OrigEntry] != 0 && "Missed file entry");
2426 Record.push_back(Elt: InputFileIDs[*Content->OrigEntry]);
2427
2428 Record.push_back(Elt: getAdjustedNumCreatedFIDs(FID));
2429
2430 FileDeclIDsTy::iterator FDI = FileDeclIDs.find(Val: FID);
2431 if (FDI != FileDeclIDs.end()) {
2432 Record.push_back(Elt: FDI->second->FirstDeclIndex);
2433 Record.push_back(Elt: FDI->second->DeclIDs.size());
2434 } else {
2435 Record.push_back(Elt: 0);
2436 Record.push_back(Elt: 0);
2437 }
2438
2439 Stream.EmitRecordWithAbbrev(Abbrev: SLocFileAbbrv, Vals: Record);
2440
2441 if (Content->BufferOverridden || Content->IsTransient)
2442 EmitBlob = true;
2443 } else {
2444 // The source location entry is a buffer. The blob associated
2445 // with this entry contains the contents of the buffer.
2446
2447 // We add one to the size so that we capture the trailing NULL
2448 // that is required by llvm::MemoryBuffer::getMemBuffer (on
2449 // the reader side).
2450 std::optional<llvm::MemoryBufferRef> Buffer = Content->getBufferOrNone(
2451 Diag&: SourceMgr.getDiagnostics(), FM&: SourceMgr.getFileManager());
2452 StringRef Name = Buffer ? Buffer->getBufferIdentifier() : "";
2453 Stream.EmitRecordWithBlob(Abbrev: SLocBufferAbbrv, Vals: Record,
2454 Blob: StringRef(Name.data(), Name.size() + 1));
2455 EmitBlob = true;
2456 }
2457
2458 if (EmitBlob) {
2459 // Include the implicit terminating null character in the on-disk buffer
2460 // if we're writing it uncompressed.
2461 std::optional<llvm::MemoryBufferRef> Buffer = Content->getBufferOrNone(
2462 Diag&: SourceMgr.getDiagnostics(), FM&: SourceMgr.getFileManager());
2463 if (!Buffer)
2464 Buffer = llvm::MemoryBufferRef("<<<INVALID BUFFER>>>", "");
2465 StringRef Blob(Buffer->getBufferStart(), Buffer->getBufferSize() + 1);
2466 emitBlob(Stream, Blob, SLocBufferBlobCompressedAbbrv,
2467 SLocBufferBlobAbbrv);
2468 }
2469 } else {
2470 // The source location entry is a macro expansion.
2471 const SrcMgr::ExpansionInfo &Expansion = SLoc->getExpansion();
2472 SLocEntryOffsets.push_back(x: Offset);
2473 // Starting offset of this entry within this module, so skip the dummy.
2474 Record.push_back(Elt: getAdjustedOffset(Offset: SLoc->getOffset()) - 2);
2475 AddSourceLocation(Loc: Expansion.getSpellingLoc(), Record);
2476 AddSourceLocation(Loc: Expansion.getExpansionLocStart(), Record);
2477 AddSourceLocation(Loc: Expansion.isMacroArgExpansion()
2478 ? SourceLocation()
2479 : Expansion.getExpansionLocEnd(),
2480 Record);
2481 Record.push_back(Elt: Expansion.isExpansionTokenRange());
2482
2483 // Compute the token length for this macro expansion.
2484 SourceLocation::UIntTy NextOffset = SourceMgr.getNextLocalOffset();
2485 if (I + 1 != N)
2486 NextOffset = SourceMgr.getLocalSLocEntry(Index: I + 1).getOffset();
2487 Record.push_back(Elt: getAdjustedOffset(Offset: NextOffset - SLoc->getOffset()) - 1);
2488 Stream.EmitRecordWithAbbrev(Abbrev: SLocExpansionAbbrv, Vals: Record);
2489 }
2490 }
2491
2492 Stream.ExitBlock();
2493
2494 if (SLocEntryOffsets.empty())
2495 return;
2496
2497 // Write the source-location offsets table into the AST block. This
2498 // table is used for lazily loading source-location information.
2499 using namespace llvm;
2500
2501 auto Abbrev = std::make_shared<BitCodeAbbrev>();
2502 Abbrev->Add(OpInfo: BitCodeAbbrevOp(SOURCE_LOCATION_OFFSETS));
2503 Abbrev->Add(OpInfo: BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 16)); // # of slocs
2504 Abbrev->Add(OpInfo: BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 16)); // total size
2505 Abbrev->Add(OpInfo: BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 32)); // base offset
2506 Abbrev->Add(OpInfo: BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // offsets
2507 unsigned SLocOffsetsAbbrev = Stream.EmitAbbrev(Abbv: std::move(Abbrev));
2508 {
2509 RecordData::value_type Record[] = {
2510 SOURCE_LOCATION_OFFSETS, SLocEntryOffsets.size(),
2511 getAdjustedOffset(Offset: SourceMgr.getNextLocalOffset()) - 1 /* skip dummy */,
2512 SLocEntryOffsetsBase - SourceManagerBlockOffset};
2513 Stream.EmitRecordWithBlob(Abbrev: SLocOffsetsAbbrev, Vals: Record,
2514 Blob: bytes(v: SLocEntryOffsets));
2515 }
2516
2517 // Write the line table. It depends on remapping working, so it must come
2518 // after the source location offsets.
2519 if (SourceMgr.hasLineTable()) {
2520 LineTableInfo &LineTable = SourceMgr.getLineTable();
2521
2522 Record.clear();
2523
2524 // Emit the needed file names.
2525 llvm::DenseMap<int, int> FilenameMap;
2526 FilenameMap[-1] = -1; // For unspecified filenames.
2527 for (const auto &L : LineTable) {
2528 if (L.first.ID < 0)
2529 continue;
2530 for (auto &LE : L.second) {
2531 if (FilenameMap.insert(KV: std::make_pair(x: LE.FilenameID,
2532 y: FilenameMap.size() - 1)).second)
2533 AddPath(Path: LineTable.getFilename(ID: LE.FilenameID), Record);
2534 }
2535 }
2536 Record.push_back(Elt: 0);
2537
2538 // Emit the line entries
2539 for (const auto &L : LineTable) {
2540 // Only emit entries for local files.
2541 if (L.first.ID < 0)
2542 continue;
2543
2544 AddFileID(FID: L.first, Record);
2545
2546 // Emit the line entries
2547 Record.push_back(Elt: L.second.size());
2548 for (const auto &LE : L.second) {
2549 Record.push_back(Elt: LE.FileOffset);
2550 Record.push_back(Elt: LE.LineNo);
2551 Record.push_back(Elt: FilenameMap[LE.FilenameID]);
2552 Record.push_back(Elt: (unsigned)LE.FileKind);
2553 Record.push_back(Elt: LE.IncludeOffset);
2554 }
2555 }
2556
2557 Stream.EmitRecord(Code: SOURCE_MANAGER_LINE_TABLE, Vals: Record);
2558 }
2559}
2560
2561//===----------------------------------------------------------------------===//
2562// Preprocessor Serialization
2563//===----------------------------------------------------------------------===//
2564
2565static bool shouldIgnoreMacro(MacroDirective *MD, bool IsModule,
2566 const Preprocessor &PP) {
2567 if (MacroInfo *MI = MD->getMacroInfo())
2568 if (MI->isBuiltinMacro())
2569 return true;
2570
2571 if (IsModule) {
2572 SourceLocation Loc = MD->getLocation();
2573 if (Loc.isInvalid())
2574 return true;
2575 if (PP.getSourceManager().getFileID(SpellingLoc: Loc) == PP.getPredefinesFileID())
2576 return true;
2577 }
2578
2579 return false;
2580}
2581
2582/// Writes the block containing the serialized form of the
2583/// preprocessor.
2584void ASTWriter::WritePreprocessor(const Preprocessor &PP, bool IsModule) {
2585 uint64_t MacroOffsetsBase = Stream.GetCurrentBitNo();
2586
2587 PreprocessingRecord *PPRec = PP.getPreprocessingRecord();
2588 if (PPRec)
2589 WritePreprocessorDetail(PPRec&: *PPRec, MacroOffsetsBase);
2590
2591 RecordData Record;
2592 RecordData ModuleMacroRecord;
2593
2594 // If the preprocessor __COUNTER__ value has been bumped, remember it.
2595 if (PP.getCounterValue() != 0) {
2596 RecordData::value_type Record[] = {PP.getCounterValue()};
2597 Stream.EmitRecord(Code: PP_COUNTER_VALUE, Vals: Record);
2598 }
2599
2600 // If we have a recorded #pragma assume_nonnull, remember it so it can be
2601 // replayed when the preamble terminates into the main file.
2602 SourceLocation AssumeNonNullLoc =
2603 PP.getPreambleRecordedPragmaAssumeNonNullLoc();
2604 if (AssumeNonNullLoc.isValid()) {
2605 assert(PP.isRecordingPreamble());
2606 AddSourceLocation(Loc: AssumeNonNullLoc, Record);
2607 Stream.EmitRecord(Code: PP_ASSUME_NONNULL_LOC, Vals: Record);
2608 Record.clear();
2609 }
2610
2611 if (PP.isRecordingPreamble() && PP.hasRecordedPreamble()) {
2612 assert(!IsModule);
2613 auto SkipInfo = PP.getPreambleSkipInfo();
2614 if (SkipInfo) {
2615 Record.push_back(Elt: true);
2616 AddSourceLocation(Loc: SkipInfo->HashTokenLoc, Record);
2617 AddSourceLocation(Loc: SkipInfo->IfTokenLoc, Record);
2618 Record.push_back(Elt: SkipInfo->FoundNonSkipPortion);
2619 Record.push_back(Elt: SkipInfo->FoundElse);
2620 AddSourceLocation(Loc: SkipInfo->ElseLoc, Record);
2621 } else {
2622 Record.push_back(Elt: false);
2623 }
2624 for (const auto &Cond : PP.getPreambleConditionalStack()) {
2625 AddSourceLocation(Loc: Cond.IfLoc, Record);
2626 Record.push_back(Elt: Cond.WasSkipping);
2627 Record.push_back(Elt: Cond.FoundNonSkip);
2628 Record.push_back(Elt: Cond.FoundElse);
2629 }
2630 Stream.EmitRecord(Code: PP_CONDITIONAL_STACK, Vals: Record);
2631 Record.clear();
2632 }
2633
2634 // Write the safe buffer opt-out region map in PP
2635 for (SourceLocation &S : PP.serializeSafeBufferOptOutMap())
2636 AddSourceLocation(Loc: S, Record);
2637 Stream.EmitRecord(Code: PP_UNSAFE_BUFFER_USAGE, Vals: Record);
2638 Record.clear();
2639
2640 // Enter the preprocessor block.
2641 Stream.EnterSubblock(BlockID: PREPROCESSOR_BLOCK_ID, CodeLen: 3);
2642
2643 // If the AST file contains __DATE__ or __TIME__ emit a warning about this.
2644 // FIXME: Include a location for the use, and say which one was used.
2645 if (PP.SawDateOrTime())
2646 PP.Diag(Loc: SourceLocation(), DiagID: diag::warn_module_uses_date_time) << IsModule;
2647
2648 // Loop over all the macro directives that are live at the end of the file,
2649 // emitting each to the PP section.
2650
2651 // Construct the list of identifiers with macro directives that need to be
2652 // serialized.
2653 SmallVector<const IdentifierInfo *, 128> MacroIdentifiers;
2654 // It is meaningless to emit macros for named modules. It only wastes times
2655 // and spaces.
2656 if (!isWritingStdCXXNamedModules())
2657 for (auto &Id : PP.getIdentifierTable())
2658 if (Id.second->hadMacroDefinition() &&
2659 (!Id.second->isFromAST() ||
2660 Id.second->hasChangedSinceDeserialization()))
2661 MacroIdentifiers.push_back(Elt: Id.second);
2662 // Sort the set of macro definitions that need to be serialized by the
2663 // name of the macro, to provide a stable ordering.
2664 llvm::sort(C&: MacroIdentifiers, Comp: llvm::deref<std::less<>>());
2665
2666 // Emit the macro directives as a list and associate the offset with the
2667 // identifier they belong to.
2668 for (const IdentifierInfo *Name : MacroIdentifiers) {
2669 MacroDirective *MD = PP.getLocalMacroDirectiveHistory(II: Name);
2670 uint64_t StartOffset = Stream.GetCurrentBitNo() - MacroOffsetsBase;
2671 assert((StartOffset >> 32) == 0 && "Macro identifiers offset too large");
2672
2673 // Write out any exported module macros.
2674 bool EmittedModuleMacros = false;
2675 // C+=20 Header Units are compiled module interfaces, but they preserve
2676 // macros that are live (i.e. have a defined value) at the end of the
2677 // compilation. So when writing a header unit, we preserve only the final
2678 // value of each macro (and discard any that are undefined). Header units
2679 // do not have sub-modules (although they might import other header units).
2680 // PCH files, conversely, retain the history of each macro's define/undef
2681 // and of leaf macros in sub modules.
2682 if (IsModule && WritingModule->isHeaderUnit()) {
2683 // This is for the main TU when it is a C++20 header unit.
2684 // We preserve the final state of defined macros, and we do not emit ones
2685 // that are undefined.
2686 if (!MD || shouldIgnoreMacro(MD, IsModule, PP) ||
2687 MD->getKind() == MacroDirective::MD_Undefine)
2688 continue;
2689 AddSourceLocation(Loc: MD->getLocation(), Record);
2690 Record.push_back(Elt: MD->getKind());
2691 if (auto *DefMD = dyn_cast<DefMacroDirective>(Val: MD)) {
2692 Record.push_back(Elt: getMacroRef(MI: DefMD->getInfo(), Name));
2693 } else if (auto *VisMD = dyn_cast<VisibilityMacroDirective>(Val: MD)) {
2694 Record.push_back(Elt: VisMD->isPublic());
2695 }
2696 ModuleMacroRecord.push_back(Elt: getSubmoduleID(Mod: WritingModule));
2697 AddMacroRef(MI: MD->getMacroInfo(), Name, Record&: ModuleMacroRecord);
2698 Stream.EmitRecord(Code: PP_MODULE_MACRO, Vals: ModuleMacroRecord);
2699 ModuleMacroRecord.clear();
2700 EmittedModuleMacros = true;
2701 } else {
2702 // Emit the macro directives in reverse source order.
2703 for (; MD; MD = MD->getPrevious()) {
2704 // Once we hit an ignored macro, we're done: the rest of the chain
2705 // will all be ignored macros.
2706 if (shouldIgnoreMacro(MD, IsModule, PP))
2707 break;
2708 AddSourceLocation(Loc: MD->getLocation(), Record);
2709 Record.push_back(Elt: MD->getKind());
2710 if (auto *DefMD = dyn_cast<DefMacroDirective>(Val: MD)) {
2711 Record.push_back(Elt: getMacroRef(MI: DefMD->getInfo(), Name));
2712 } else if (auto *VisMD = dyn_cast<VisibilityMacroDirective>(Val: MD)) {
2713 Record.push_back(Elt: VisMD->isPublic());
2714 }
2715 }
2716
2717 // We write out exported module macros for PCH as well.
2718 auto Leafs = PP.getLeafModuleMacros(II: Name);
2719 SmallVector<ModuleMacro *, 8> Worklist(Leafs);
2720 llvm::DenseMap<ModuleMacro *, unsigned> Visits;
2721 while (!Worklist.empty()) {
2722 auto *Macro = Worklist.pop_back_val();
2723
2724 // Emit a record indicating this submodule exports this macro.
2725 ModuleMacroRecord.push_back(Elt: getSubmoduleID(Mod: Macro->getOwningModule()));
2726 AddMacroRef(MI: Macro->getMacroInfo(), Name, Record&: ModuleMacroRecord);
2727 for (auto *M : Macro->overrides())
2728 ModuleMacroRecord.push_back(Elt: getSubmoduleID(Mod: M->getOwningModule()));
2729
2730 Stream.EmitRecord(Code: PP_MODULE_MACRO, Vals: ModuleMacroRecord);
2731 ModuleMacroRecord.clear();
2732
2733 // Enqueue overridden macros once we've visited all their ancestors.
2734 for (auto *M : Macro->overrides())
2735 if (++Visits[M] == M->getNumOverridingMacros())
2736 Worklist.push_back(Elt: M);
2737
2738 EmittedModuleMacros = true;
2739 }
2740 }
2741 if (Record.empty() && !EmittedModuleMacros)
2742 continue;
2743
2744 IdentMacroDirectivesOffsetMap[Name] = StartOffset;
2745 Stream.EmitRecord(Code: PP_MACRO_DIRECTIVE_HISTORY, Vals: Record);
2746 Record.clear();
2747 }
2748
2749 /// Offsets of each of the macros into the bitstream, indexed by
2750 /// the local macro ID
2751 ///
2752 /// For each identifier that is associated with a macro, this map
2753 /// provides the offset into the bitstream where that macro is
2754 /// defined.
2755 std::vector<uint32_t> MacroOffsets;
2756
2757 for (unsigned I = 0, N = MacroInfosToEmit.size(); I != N; ++I) {
2758 const IdentifierInfo *Name = MacroInfosToEmit[I].Name;
2759 MacroInfo *MI = MacroInfosToEmit[I].MI;
2760 MacroID ID = MacroInfosToEmit[I].ID;
2761
2762 if (ID < FirstMacroID) {
2763 assert(0 && "Loaded MacroInfo entered MacroInfosToEmit ?");
2764 continue;
2765 }
2766
2767 // Record the local offset of this macro.
2768 unsigned Index = ID - FirstMacroID;
2769 if (Index >= MacroOffsets.size())
2770 MacroOffsets.resize(new_size: Index + 1);
2771
2772 uint64_t Offset = Stream.GetCurrentBitNo() - MacroOffsetsBase;
2773 assert((Offset >> 32) == 0 && "Macro offset too large");
2774 MacroOffsets[Index] = Offset;
2775
2776 AddIdentifierRef(II: Name, Record);
2777 AddSourceLocation(Loc: MI->getDefinitionLoc(), Record);
2778 AddSourceLocation(Loc: MI->getDefinitionEndLoc(), Record);
2779 Record.push_back(Elt: MI->isUsed());
2780 Record.push_back(Elt: MI->isUsedForHeaderGuard());
2781 Record.push_back(Elt: MI->getNumTokens());
2782 unsigned Code;
2783 if (MI->isObjectLike()) {
2784 Code = PP_MACRO_OBJECT_LIKE;
2785 } else {
2786 Code = PP_MACRO_FUNCTION_LIKE;
2787
2788 Record.push_back(Elt: MI->isC99Varargs());
2789 Record.push_back(Elt: MI->isGNUVarargs());
2790 Record.push_back(Elt: MI->hasCommaPasting());
2791 Record.push_back(Elt: MI->getNumParams());
2792 for (const IdentifierInfo *Param : MI->params())
2793 AddIdentifierRef(II: Param, Record);
2794 }
2795
2796 // If we have a detailed preprocessing record, record the macro definition
2797 // ID that corresponds to this macro.
2798 if (PPRec)
2799 Record.push_back(Elt: MacroDefinitions[PPRec->findMacroDefinition(MI)]);
2800
2801 Stream.EmitRecord(Code, Vals: Record);
2802 Record.clear();
2803
2804 // Emit the tokens array.
2805 for (unsigned TokNo = 0, e = MI->getNumTokens(); TokNo != e; ++TokNo) {
2806 // Note that we know that the preprocessor does not have any annotation
2807 // tokens in it because they are created by the parser, and thus can't
2808 // be in a macro definition.
2809 const Token &Tok = MI->getReplacementToken(Tok: TokNo);
2810 AddToken(Tok, Record);
2811 Stream.EmitRecord(Code: PP_TOKEN, Vals: Record);
2812 Record.clear();
2813 }
2814 ++NumMacros;
2815 }
2816
2817 Stream.ExitBlock();
2818
2819 // Write the offsets table for macro IDs.
2820 using namespace llvm;
2821
2822 auto Abbrev = std::make_shared<BitCodeAbbrev>();
2823 Abbrev->Add(OpInfo: BitCodeAbbrevOp(MACRO_OFFSET));
2824 Abbrev->Add(OpInfo: BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32)); // # of macros
2825 Abbrev->Add(OpInfo: BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 32)); // base offset
2826 Abbrev->Add(OpInfo: BitCodeAbbrevOp(BitCodeAbbrevOp::Blob));
2827
2828 unsigned MacroOffsetAbbrev = Stream.EmitAbbrev(Abbv: std::move(Abbrev));
2829 {
2830 RecordData::value_type Record[] = {MACRO_OFFSET, MacroOffsets.size(),
2831 MacroOffsetsBase - ASTBlockStartOffset};
2832 Stream.EmitRecordWithBlob(Abbrev: MacroOffsetAbbrev, Vals: Record, Blob: bytes(v: MacroOffsets));
2833 }
2834}
2835
2836void ASTWriter::WritePreprocessorDetail(PreprocessingRecord &PPRec,
2837 uint64_t MacroOffsetsBase) {
2838 if (PPRec.local_begin() == PPRec.local_end())
2839 return;
2840
2841 SmallVector<PPEntityOffset, 64> PreprocessedEntityOffsets;
2842
2843 // Enter the preprocessor block.
2844 Stream.EnterSubblock(BlockID: PREPROCESSOR_DETAIL_BLOCK_ID, CodeLen: 3);
2845
2846 // If the preprocessor has a preprocessing record, emit it.
2847 unsigned NumPreprocessingRecords = 0;
2848 using namespace llvm;
2849
2850 // Set up the abbreviation for
2851 unsigned InclusionAbbrev = 0;
2852 {
2853 auto Abbrev = std::make_shared<BitCodeAbbrev>();
2854 Abbrev->Add(OpInfo: BitCodeAbbrevOp(PPD_INCLUSION_DIRECTIVE));
2855 Abbrev->Add(OpInfo: BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32)); // filename length
2856 Abbrev->Add(OpInfo: BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // in quotes
2857 Abbrev->Add(OpInfo: BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 2)); // kind
2858 Abbrev->Add(OpInfo: BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // imported module
2859 Abbrev->Add(OpInfo: BitCodeAbbrevOp(BitCodeAbbrevOp::Blob));
2860 InclusionAbbrev = Stream.EmitAbbrev(Abbv: std::move(Abbrev));
2861 }
2862
2863 unsigned FirstPreprocessorEntityID = NUM_PREDEF_PP_ENTITY_IDS;
2864 unsigned NextPreprocessorEntityID = FirstPreprocessorEntityID;
2865 RecordData Record;
2866 for (PreprocessingRecord::iterator E = PPRec.local_begin(),
2867 EEnd = PPRec.local_end();
2868 E != EEnd;
2869 (void)++E, ++NumPreprocessingRecords, ++NextPreprocessorEntityID) {
2870 Record.clear();
2871
2872 uint64_t Offset = Stream.GetCurrentBitNo() - MacroOffsetsBase;
2873 assert((Offset >> 32) == 0 && "Preprocessed entity offset too large");
2874 SourceRange R = getAdjustedRange(Range: (*E)->getSourceRange());
2875 PreprocessedEntityOffsets.emplace_back(
2876 Args: getRawSourceLocationEncoding(Loc: R.getBegin()),
2877 Args: getRawSourceLocationEncoding(Loc: R.getEnd()), Args&: Offset);
2878
2879 if (auto *MD = dyn_cast<MacroDefinitionRecord>(Val: *E)) {
2880 // Record this macro definition's ID.
2881 MacroDefinitions[MD] = NextPreprocessorEntityID;
2882
2883 AddIdentifierRef(II: MD->getName(), Record);
2884 Stream.EmitRecord(Code: PPD_MACRO_DEFINITION, Vals: Record);
2885 continue;
2886 }
2887
2888 if (auto *ME = dyn_cast<MacroExpansion>(Val: *E)) {
2889 Record.push_back(Elt: ME->isBuiltinMacro());
2890 if (ME->isBuiltinMacro())
2891 AddIdentifierRef(II: ME->getName(), Record);
2892 else
2893 Record.push_back(Elt: MacroDefinitions[ME->getDefinition()]);
2894 Stream.EmitRecord(Code: PPD_MACRO_EXPANSION, Vals: Record);
2895 continue;
2896 }
2897
2898 if (auto *ID = dyn_cast<InclusionDirective>(Val: *E)) {
2899 Record.push_back(Elt: PPD_INCLUSION_DIRECTIVE);
2900 Record.push_back(Elt: ID->getFileName().size());
2901 Record.push_back(Elt: ID->wasInQuotes());
2902 Record.push_back(Elt: static_cast<unsigned>(ID->getKind()));
2903 Record.push_back(Elt: ID->importedModule());
2904 SmallString<64> Buffer;
2905 Buffer += ID->getFileName();
2906 // Check that the FileEntry is not null because it was not resolved and
2907 // we create a PCH even with compiler errors.
2908 if (ID->getFile())
2909 Buffer += ID->getFile()->getName();
2910 Stream.EmitRecordWithBlob(Abbrev: InclusionAbbrev, Vals: Record, Blob: Buffer);
2911 continue;
2912 }
2913
2914 llvm_unreachable("Unhandled PreprocessedEntity in ASTWriter");
2915 }
2916 Stream.ExitBlock();
2917
2918 // Write the offsets table for the preprocessing record.
2919 if (NumPreprocessingRecords > 0) {
2920 assert(PreprocessedEntityOffsets.size() == NumPreprocessingRecords);
2921
2922 // Write the offsets table for identifier IDs.
2923 using namespace llvm;
2924
2925 auto Abbrev = std::make_shared<BitCodeAbbrev>();
2926 Abbrev->Add(OpInfo: BitCodeAbbrevOp(PPD_ENTITIES_OFFSETS));
2927 Abbrev->Add(OpInfo: BitCodeAbbrevOp(BitCodeAbbrevOp::Blob));
2928 unsigned PPEOffsetAbbrev = Stream.EmitAbbrev(Abbv: std::move(Abbrev));
2929
2930 RecordData::value_type Record[] = {PPD_ENTITIES_OFFSETS};
2931 Stream.EmitRecordWithBlob(Abbrev: PPEOffsetAbbrev, Vals: Record,
2932 Blob: bytes(v: PreprocessedEntityOffsets));
2933 }
2934
2935 // Write the skipped region table for the preprocessing record.
2936 ArrayRef<SourceRange> SkippedRanges = PPRec.getSkippedRanges();
2937 if (SkippedRanges.size() > 0) {
2938 std::vector<PPSkippedRange> SerializedSkippedRanges;
2939 SerializedSkippedRanges.reserve(n: SkippedRanges.size());
2940 for (auto const& Range : SkippedRanges)
2941 SerializedSkippedRanges.emplace_back(
2942 args: getRawSourceLocationEncoding(Loc: Range.getBegin()),
2943 args: getRawSourceLocationEncoding(Loc: Range.getEnd()));
2944
2945 using namespace llvm;
2946 auto Abbrev = std::make_shared<BitCodeAbbrev>();
2947 Abbrev->Add(OpInfo: BitCodeAbbrevOp(PPD_SKIPPED_RANGES));
2948 Abbrev->Add(OpInfo: BitCodeAbbrevOp(BitCodeAbbrevOp::Blob));
2949 unsigned PPESkippedRangeAbbrev = Stream.EmitAbbrev(Abbv: std::move(Abbrev));
2950
2951 Record.clear();
2952 Record.push_back(Elt: PPD_SKIPPED_RANGES);
2953 Stream.EmitRecordWithBlob(Abbrev: PPESkippedRangeAbbrev, Vals: Record,
2954 Blob: bytes(v: SerializedSkippedRanges));
2955 }
2956}
2957
2958unsigned ASTWriter::getLocalOrImportedSubmoduleID(const Module *Mod) {
2959 if (!Mod)
2960 return 0;
2961
2962 auto Known = SubmoduleIDs.find(Val: Mod);
2963 if (Known != SubmoduleIDs.end())
2964 return Known->second;
2965
2966 auto *Top = Mod->getTopLevelModule();
2967 if (Top != WritingModule &&
2968 (getLangOpts().CompilingPCH ||
2969 !Top->fullModuleNameIs(nameParts: StringRef(getLangOpts().CurrentModule))))
2970 return 0;
2971
2972 return SubmoduleIDs[Mod] = NextSubmoduleID++;
2973}
2974
2975unsigned ASTWriter::getSubmoduleID(Module *Mod) {
2976 unsigned ID = getLocalOrImportedSubmoduleID(Mod);
2977 // FIXME: This can easily happen, if we have a reference to a submodule that
2978 // did not result in us loading a module file for that submodule. For
2979 // instance, a cross-top-level-module 'conflict' declaration will hit this.
2980 // assert((ID || !Mod) &&
2981 // "asked for module ID for non-local, non-imported module");
2982 return ID;
2983}
2984
2985/// Compute the number of modules within the given tree (including the
2986/// given module).
2987static unsigned getNumberOfModules(Module *Mod) {
2988 unsigned ChildModules = 0;
2989 for (auto *Submodule : Mod->submodules())
2990 ChildModules += getNumberOfModules(Mod: Submodule);
2991
2992 return ChildModules + 1;
2993}
2994
2995void ASTWriter::WriteSubmodules(Module *WritingModule, ASTContext *Context) {
2996 // Enter the submodule description block.
2997 Stream.EnterSubblock(BlockID: SUBMODULE_BLOCK_ID, /*bits for abbreviations*/CodeLen: 5);
2998
2999 // Write the abbreviations needed for the submodules block.
3000 using namespace llvm;
3001
3002 auto Abbrev = std::make_shared<BitCodeAbbrev>();
3003 Abbrev->Add(OpInfo: BitCodeAbbrevOp(SUBMODULE_DEFINITION));
3004 Abbrev->Add(OpInfo: BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // ID
3005 Abbrev->Add(OpInfo: BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Parent
3006 Abbrev->Add(OpInfo: BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 4)); // Kind
3007 Abbrev->Add(OpInfo: BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); // Definition location
3008 Abbrev->Add(OpInfo: BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 4)); // Inferred allowed by
3009 Abbrev->Add(OpInfo: BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // IsFramework
3010 Abbrev->Add(OpInfo: BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // IsExplicit
3011 Abbrev->Add(OpInfo: BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // IsSystem
3012 Abbrev->Add(OpInfo: BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // IsExternC
3013 Abbrev->Add(OpInfo: BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // InferSubmodules...
3014 Abbrev->Add(OpInfo: BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // InferExplicit...
3015 Abbrev->Add(OpInfo: BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // InferExportWild...
3016 Abbrev->Add(OpInfo: BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // ConfigMacrosExh...
3017 Abbrev->Add(OpInfo: BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // ModuleMapIsPriv...
3018 Abbrev->Add(OpInfo: BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // NamedModuleHasN...
3019 Abbrev->Add(OpInfo: BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // Name
3020 unsigned DefinitionAbbrev = Stream.EmitAbbrev(Abbv: std::move(Abbrev));
3021
3022 Abbrev = std::make_shared<BitCodeAbbrev>();
3023 Abbrev->Add(OpInfo: BitCodeAbbrevOp(SUBMODULE_UMBRELLA_HEADER));
3024 Abbrev->Add(OpInfo: BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // Name
3025 unsigned UmbrellaAbbrev = Stream.EmitAbbrev(Abbv: std::move(Abbrev));
3026
3027 Abbrev = std::make_shared<BitCodeAbbrev>();
3028 Abbrev->Add(OpInfo: BitCodeAbbrevOp(SUBMODULE_HEADER));
3029 Abbrev->Add(OpInfo: BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // Name
3030 unsigned HeaderAbbrev = Stream.EmitAbbrev(Abbv: std::move(Abbrev));
3031
3032 Abbrev = std::make_shared<BitCodeAbbrev>();
3033 Abbrev->Add(OpInfo: BitCodeAbbrevOp(SUBMODULE_TOPHEADER));
3034 Abbrev->Add(OpInfo: BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // Name
3035 unsigned TopHeaderAbbrev = Stream.EmitAbbrev(Abbv: std::move(Abbrev));
3036
3037 Abbrev = std::make_shared<BitCodeAbbrev>();
3038 Abbrev->Add(OpInfo: BitCodeAbbrevOp(SUBMODULE_UMBRELLA_DIR));
3039 Abbrev->Add(OpInfo: BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // Name
3040 unsigned UmbrellaDirAbbrev = Stream.EmitAbbrev(Abbv: std::move(Abbrev));
3041
3042 Abbrev = std::make_shared<BitCodeAbbrev>();
3043 Abbrev->Add(OpInfo: BitCodeAbbrevOp(SUBMODULE_REQUIRES));
3044 Abbrev->Add(OpInfo: BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // State
3045 Abbrev->Add(OpInfo: BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // Feature
3046 unsigned RequiresAbbrev = Stream.EmitAbbrev(Abbv: std::move(Abbrev));
3047
3048 Abbrev = std::make_shared<BitCodeAbbrev>();
3049 Abbrev->Add(OpInfo: BitCodeAbbrevOp(SUBMODULE_EXCLUDED_HEADER));
3050 Abbrev->Add(OpInfo: BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // Name
3051 unsigned ExcludedHeaderAbbrev = Stream.EmitAbbrev(Abbv: std::move(Abbrev));
3052
3053 Abbrev = std::make_shared<BitCodeAbbrev>();
3054 Abbrev->Add(OpInfo: BitCodeAbbrevOp(SUBMODULE_TEXTUAL_HEADER));
3055 Abbrev->Add(OpInfo: BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // Name
3056 unsigned TextualHeaderAbbrev = Stream.EmitAbbrev(Abbv: std::move(Abbrev));
3057
3058 Abbrev = std::make_shared<BitCodeAbbrev>();
3059 Abbrev->Add(OpInfo: BitCodeAbbrevOp(SUBMODULE_PRIVATE_HEADER));
3060 Abbrev->Add(OpInfo: BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // Name
3061 unsigned PrivateHeaderAbbrev = Stream.EmitAbbrev(Abbv: std::move(Abbrev));
3062
3063 Abbrev = std::make_shared<BitCodeAbbrev>();
3064 Abbrev->Add(OpInfo: BitCodeAbbrevOp(SUBMODULE_PRIVATE_TEXTUAL_HEADER));
3065 Abbrev->Add(OpInfo: BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // Name
3066 unsigned PrivateTextualHeaderAbbrev = Stream.EmitAbbrev(Abbv: std::move(Abbrev));
3067
3068 Abbrev = std::make_shared<BitCodeAbbrev>();
3069 Abbrev->Add(OpInfo: BitCodeAbbrevOp(SUBMODULE_LINK_LIBRARY));
3070 Abbrev->Add(OpInfo: BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // IsFramework
3071 Abbrev->Add(OpInfo: BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // Name
3072 unsigned LinkLibraryAbbrev = Stream.EmitAbbrev(Abbv: std::move(Abbrev));
3073
3074 Abbrev = std::make_shared<BitCodeAbbrev>();
3075 Abbrev->Add(OpInfo: BitCodeAbbrevOp(SUBMODULE_CONFIG_MACRO));
3076 Abbrev->Add(OpInfo: BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // Macro name
3077 unsigned ConfigMacroAbbrev = Stream.EmitAbbrev(Abbv: std::move(Abbrev));
3078
3079 Abbrev = std::make_shared<BitCodeAbbrev>();
3080 Abbrev->Add(OpInfo: BitCodeAbbrevOp(SUBMODULE_CONFLICT));
3081 Abbrev->Add(OpInfo: BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Other module
3082 Abbrev->Add(OpInfo: BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // Message
3083 unsigned ConflictAbbrev = Stream.EmitAbbrev(Abbv: std::move(Abbrev));
3084
3085 Abbrev = std::make_shared<BitCodeAbbrev>();
3086 Abbrev->Add(OpInfo: BitCodeAbbrevOp(SUBMODULE_EXPORT_AS));
3087 Abbrev->Add(OpInfo: BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // Macro name
3088 unsigned ExportAsAbbrev = Stream.EmitAbbrev(Abbv: std::move(Abbrev));
3089
3090 // Write the submodule metadata block.
3091 RecordData::value_type Record[] = {
3092 getNumberOfModules(Mod: WritingModule),
3093 FirstSubmoduleID - NUM_PREDEF_SUBMODULE_IDS};
3094 Stream.EmitRecord(Code: SUBMODULE_METADATA, Vals: Record);
3095
3096 // Write all of the submodules.
3097 std::queue<Module *> Q;
3098 Q.push(x: WritingModule);
3099 while (!Q.empty()) {
3100 Module *Mod = Q.front();
3101 Q.pop();
3102 unsigned ID = getSubmoduleID(Mod);
3103
3104 uint64_t ParentID = 0;
3105 if (Mod->Parent) {
3106 assert(SubmoduleIDs[Mod->Parent] && "Submodule parent not written?");
3107 ParentID = SubmoduleIDs[Mod->Parent];
3108 }
3109
3110 SourceLocationEncoding::RawLocEncoding DefinitionLoc =
3111 getRawSourceLocationEncoding(Loc: getAdjustedLocation(Loc: Mod->DefinitionLoc));
3112
3113 ModuleMap &ModMap = PP->getHeaderSearchInfo().getModuleMap();
3114 FileID UnadjustedInferredFID;
3115 if (Mod->IsInferred)
3116 UnadjustedInferredFID = ModMap.getModuleMapFileIDForUniquing(M: Mod);
3117 int InferredFID = getAdjustedFileID(FID: UnadjustedInferredFID).getOpaqueValue();
3118
3119 // Emit the definition of the block.
3120 {
3121 RecordData::value_type Record[] = {SUBMODULE_DEFINITION,
3122 ID,
3123 ParentID,
3124 (RecordData::value_type)Mod->Kind,
3125 DefinitionLoc,
3126 (RecordData::value_type)InferredFID,
3127 Mod->IsFramework,
3128 Mod->IsExplicit,
3129 Mod->IsSystem,
3130 Mod->IsExternC,
3131 Mod->InferSubmodules,
3132 Mod->InferExplicitSubmodules,
3133 Mod->InferExportWildcard,
3134 Mod->ConfigMacrosExhaustive,
3135 Mod->ModuleMapIsPrivate,
3136 Mod->NamedModuleHasInit};
3137 Stream.EmitRecordWithBlob(Abbrev: DefinitionAbbrev, Vals: Record, Blob: Mod->Name);
3138 }
3139
3140 // Emit the requirements.
3141 for (const auto &R : Mod->Requirements) {
3142 RecordData::value_type Record[] = {SUBMODULE_REQUIRES, R.RequiredState};
3143 Stream.EmitRecordWithBlob(Abbrev: RequiresAbbrev, Vals: Record, Blob: R.FeatureName);
3144 }
3145
3146 // Emit the umbrella header, if there is one.
3147 if (std::optional<Module::Header> UmbrellaHeader =
3148 Mod->getUmbrellaHeaderAsWritten()) {
3149 RecordData::value_type Record[] = {SUBMODULE_UMBRELLA_HEADER};
3150 Stream.EmitRecordWithBlob(Abbrev: UmbrellaAbbrev, Vals: Record,
3151 Blob: UmbrellaHeader->NameAsWritten);
3152 } else if (std::optional<Module::DirectoryName> UmbrellaDir =
3153 Mod->getUmbrellaDirAsWritten()) {
3154 RecordData::value_type Record[] = {SUBMODULE_UMBRELLA_DIR};
3155 Stream.EmitRecordWithBlob(Abbrev: UmbrellaDirAbbrev, Vals: Record,
3156 Blob: UmbrellaDir->NameAsWritten);
3157 }
3158
3159 // Emit the headers.
3160 struct {
3161 unsigned RecordKind;
3162 unsigned Abbrev;
3163 Module::HeaderKind HeaderKind;
3164 } HeaderLists[] = {
3165 {.RecordKind: SUBMODULE_HEADER, .Abbrev: HeaderAbbrev, .HeaderKind: Module::HK_Normal},
3166 {.RecordKind: SUBMODULE_TEXTUAL_HEADER, .Abbrev: TextualHeaderAbbrev, .HeaderKind: Module::HK_Textual},
3167 {.RecordKind: SUBMODULE_PRIVATE_HEADER, .Abbrev: PrivateHeaderAbbrev, .HeaderKind: Module::HK_Private},
3168 {.RecordKind: SUBMODULE_PRIVATE_TEXTUAL_HEADER, .Abbrev: PrivateTextualHeaderAbbrev,
3169 .HeaderKind: Module::HK_PrivateTextual},
3170 {.RecordKind: SUBMODULE_EXCLUDED_HEADER, .Abbrev: ExcludedHeaderAbbrev, .HeaderKind: Module::HK_Excluded}
3171 };
3172 for (const auto &HL : HeaderLists) {
3173 RecordData::value_type Record[] = {HL.RecordKind};
3174 for (const auto &H : Mod->getHeaders(HK: HL.HeaderKind))
3175 Stream.EmitRecordWithBlob(Abbrev: HL.Abbrev, Vals: Record, Blob: H.NameAsWritten);
3176 }
3177
3178 // Emit the top headers.
3179 {
3180 RecordData::value_type Record[] = {SUBMODULE_TOPHEADER};
3181 for (FileEntryRef H : Mod->getTopHeaders(FileMgr&: PP->getFileManager())) {
3182 SmallString<128> HeaderName(H.getName());
3183 PreparePathForOutput(Path&: HeaderName);
3184 Stream.EmitRecordWithBlob(Abbrev: TopHeaderAbbrev, Vals: Record, Blob: HeaderName);
3185 }
3186 }
3187
3188 // Emit the imports.
3189 if (!Mod->Imports.empty()) {
3190 RecordData Record;
3191 for (auto *I : Mod->Imports)
3192 Record.push_back(Elt: getSubmoduleID(Mod: I));
3193 Stream.EmitRecord(Code: SUBMODULE_IMPORTS, Vals: Record);
3194 }
3195
3196 // Emit the modules affecting compilation that were not imported.
3197 if (!Mod->AffectingClangModules.empty()) {
3198 RecordData Record;
3199 for (auto *I : Mod->AffectingClangModules)
3200 Record.push_back(Elt: getSubmoduleID(Mod: I));
3201 Stream.EmitRecord(Code: SUBMODULE_AFFECTING_MODULES, Vals: Record);
3202 }
3203
3204 // Emit the exports.
3205 if (!Mod->Exports.empty()) {
3206 RecordData Record;
3207 for (const auto &E : Mod->Exports) {
3208 // FIXME: This may fail; we don't require that all exported modules
3209 // are local or imported.
3210 Record.push_back(Elt: getSubmoduleID(Mod: E.getPointer()));
3211 Record.push_back(Elt: E.getInt());
3212 }
3213 Stream.EmitRecord(Code: SUBMODULE_EXPORTS, Vals: Record);
3214 }
3215
3216 //FIXME: How do we emit the 'use'd modules? They may not be submodules.
3217 // Might be unnecessary as use declarations are only used to build the
3218 // module itself.
3219
3220 // TODO: Consider serializing undeclared uses of modules.
3221
3222 // Emit the link libraries.
3223 for (const auto &LL : Mod->LinkLibraries) {
3224 RecordData::value_type Record[] = {SUBMODULE_LINK_LIBRARY,
3225 LL.IsFramework};
3226 Stream.EmitRecordWithBlob(Abbrev: LinkLibraryAbbrev, Vals: Record, Blob: LL.Library);
3227 }
3228
3229 // Emit the conflicts.
3230 for (const auto &C : Mod->Conflicts) {
3231 // FIXME: This may fail; we don't require that all conflicting modules
3232 // are local or imported.
3233 RecordData::value_type Record[] = {SUBMODULE_CONFLICT,
3234 getSubmoduleID(Mod: C.Other)};
3235 Stream.EmitRecordWithBlob(Abbrev: ConflictAbbrev, Vals: Record, Blob: C.Message);
3236 }
3237
3238 // Emit the configuration macros.
3239 for (const auto &CM : Mod->ConfigMacros) {
3240 RecordData::value_type Record[] = {SUBMODULE_CONFIG_MACRO};
3241 Stream.EmitRecordWithBlob(Abbrev: ConfigMacroAbbrev, Vals: Record, Blob: CM);
3242 }
3243
3244 // Emit the reachable initializers.
3245 // The initializer may only be unreachable in reduced BMI.
3246 if (Context && !GeneratingReducedBMI) {
3247 RecordData Inits;
3248 for (Decl *D : Context->getModuleInitializers(M: Mod))
3249 if (wasDeclEmitted(D))
3250 AddDeclRef(D, Record&: Inits);
3251 if (!Inits.empty())
3252 Stream.EmitRecord(Code: SUBMODULE_INITIALIZERS, Vals: Inits);
3253 }
3254
3255 // Emit the name of the re-exported module, if any.
3256 if (!Mod->ExportAsModule.empty()) {
3257 RecordData::value_type Record[] = {SUBMODULE_EXPORT_AS};
3258 Stream.EmitRecordWithBlob(Abbrev: ExportAsAbbrev, Vals: Record, Blob: Mod->ExportAsModule);
3259 }
3260
3261 // Queue up the submodules of this module.
3262 for (auto *M : Mod->submodules())
3263 Q.push(x: M);
3264 }
3265
3266 Stream.ExitBlock();
3267
3268 assert((NextSubmoduleID - FirstSubmoduleID ==
3269 getNumberOfModules(WritingModule)) &&
3270 "Wrong # of submodules; found a reference to a non-local, "
3271 "non-imported submodule?");
3272}
3273
3274void ASTWriter::WritePragmaDiagnosticMappings(const DiagnosticsEngine &Diag,
3275 bool isModule) {
3276 llvm::SmallDenseMap<const DiagnosticsEngine::DiagState *, unsigned, 64>
3277 DiagStateIDMap;
3278 unsigned CurrID = 0;
3279 RecordData Record;
3280
3281 auto EncodeDiagStateFlags =
3282 [](const DiagnosticsEngine::DiagState *DS) -> unsigned {
3283 unsigned Result = (unsigned)DS->ExtBehavior;
3284 for (unsigned Val :
3285 {(unsigned)DS->IgnoreAllWarnings, (unsigned)DS->EnableAllWarnings,
3286 (unsigned)DS->WarningsAsErrors, (unsigned)DS->ErrorsAsFatal,
3287 (unsigned)DS->SuppressSystemWarnings})
3288 Result = (Result << 1) | Val;
3289 return Result;
3290 };
3291
3292 unsigned Flags = EncodeDiagStateFlags(Diag.DiagStatesByLoc.FirstDiagState);
3293 Record.push_back(Elt: Flags);
3294
3295 auto AddDiagState = [&](const DiagnosticsEngine::DiagState *State,
3296 bool IncludeNonPragmaStates) {
3297 // Ensure that the diagnostic state wasn't modified since it was created.
3298 // We will not correctly round-trip this information otherwise.
3299 assert(Flags == EncodeDiagStateFlags(State) &&
3300 "diag state flags vary in single AST file");
3301
3302 // If we ever serialize non-pragma mappings outside the initial state, the
3303 // code below will need to consider more than getDefaultMapping.
3304 assert(!IncludeNonPragmaStates ||
3305 State == Diag.DiagStatesByLoc.FirstDiagState);
3306
3307 unsigned &DiagStateID = DiagStateIDMap[State];
3308 Record.push_back(Elt: DiagStateID);
3309
3310 if (DiagStateID == 0) {
3311 DiagStateID = ++CurrID;
3312 SmallVector<std::pair<unsigned, DiagnosticMapping>> Mappings;
3313
3314 // Add a placeholder for the number of mappings.
3315 auto SizeIdx = Record.size();
3316 Record.emplace_back();
3317 for (const auto &I : *State) {
3318 // Maybe skip non-pragmas.
3319 if (!I.second.isPragma() && !IncludeNonPragmaStates)
3320 continue;
3321 // Skip default mappings. We have a mapping for every diagnostic ever
3322 // emitted, regardless of whether it was customized.
3323 if (!I.second.isPragma() &&
3324 I.second == Diag.getDiagnosticIDs()->getDefaultMapping(DiagID: I.first))
3325 continue;
3326 Mappings.push_back(Elt: I);
3327 }
3328
3329 // Sort by diag::kind for deterministic output.
3330 llvm::sort(C&: Mappings, Comp: llvm::less_first());
3331
3332 for (const auto &I : Mappings) {
3333 Record.push_back(Elt: I.first);
3334 Record.push_back(Elt: I.second.serialize());
3335 }
3336 // Update the placeholder.
3337 Record[SizeIdx] = (Record.size() - SizeIdx) / 2;
3338 }
3339 };
3340
3341 AddDiagState(Diag.DiagStatesByLoc.FirstDiagState, isModule);
3342
3343 // Reserve a spot for the number of locations with state transitions.
3344 auto NumLocationsIdx = Record.size();
3345 Record.emplace_back();
3346
3347 // Emit the state transitions.
3348 unsigned NumLocations = 0;
3349 for (auto &FileIDAndFile : Diag.DiagStatesByLoc.Files) {
3350 if (!FileIDAndFile.first.isValid() ||
3351 !FileIDAndFile.second.HasLocalTransitions)
3352 continue;
3353 ++NumLocations;
3354
3355 AddFileID(FID: FileIDAndFile.first, Record);
3356
3357 Record.push_back(Elt: FileIDAndFile.second.StateTransitions.size());
3358 for (auto &StatePoint : FileIDAndFile.second.StateTransitions) {
3359 Record.push_back(Elt: getAdjustedOffset(Offset: StatePoint.Offset));
3360 AddDiagState(StatePoint.State, false);
3361 }
3362 }
3363
3364 // Backpatch the number of locations.
3365 Record[NumLocationsIdx] = NumLocations;
3366
3367 // Emit CurDiagStateLoc. Do it last in order to match source order.
3368 //
3369 // This also protects against a hypothetical corner case with simulating
3370 // -Werror settings for implicit modules in the ASTReader, where reading
3371 // CurDiagState out of context could change whether warning pragmas are
3372 // treated as errors.
3373 AddSourceLocation(Loc: Diag.DiagStatesByLoc.CurDiagStateLoc, Record);
3374 AddDiagState(Diag.DiagStatesByLoc.CurDiagState, false);
3375
3376 Stream.EmitRecord(Code: DIAG_PRAGMA_MAPPINGS, Vals: Record);
3377}
3378
3379//===----------------------------------------------------------------------===//
3380// Type Serialization
3381//===----------------------------------------------------------------------===//
3382
3383/// Write the representation of a type to the AST stream.
3384void ASTWriter::WriteType(ASTContext &Context, QualType T) {
3385 TypeIdx &IdxRef = TypeIdxs[T];
3386 if (IdxRef.getValue() == 0) // we haven't seen this type before.
3387 IdxRef = TypeIdx(0, NextTypeID++);
3388 TypeIdx Idx = IdxRef;
3389
3390 assert(Idx.getModuleFileIndex() == 0 && "Re-writing a type from a prior AST");
3391 assert(Idx.getValue() >= FirstTypeID && "Writing predefined type");
3392
3393 // Emit the type's representation.
3394 uint64_t Offset =
3395 ASTTypeWriter(Context, *this).write(T) - DeclTypesBlockStartOffset;
3396
3397 // Record the offset for this type.
3398 uint64_t Index = Idx.getValue() - FirstTypeID;
3399 if (TypeOffsets.size() == Index)
3400 TypeOffsets.emplace_back(args&: Offset);
3401 else if (TypeOffsets.size() < Index) {
3402 TypeOffsets.resize(new_size: Index + 1);
3403 TypeOffsets[Index].set(Offset);
3404 } else {
3405 llvm_unreachable("Types emitted in wrong order");
3406 }
3407}
3408
3409//===----------------------------------------------------------------------===//
3410// Declaration Serialization
3411//===----------------------------------------------------------------------===//
3412
3413static bool IsInternalDeclFromFileContext(const Decl *D) {
3414 auto *ND = dyn_cast<NamedDecl>(Val: D);
3415 if (!ND)
3416 return false;
3417
3418 if (!D->getDeclContext()->getRedeclContext()->isFileContext())
3419 return false;
3420
3421 return ND->getFormalLinkage() == Linkage::Internal;
3422}
3423
3424/// Write the block containing all of the declaration IDs
3425/// lexically declared within the given DeclContext.
3426///
3427/// \returns the offset of the DECL_CONTEXT_LEXICAL block within the
3428/// bitstream, or 0 if no block was written.
3429uint64_t ASTWriter::WriteDeclContextLexicalBlock(ASTContext &Context,
3430 const DeclContext *DC) {
3431 if (DC->decls_empty())
3432 return 0;
3433
3434 // In reduced BMI, we don't care the declarations in functions.
3435 if (GeneratingReducedBMI && DC->isFunctionOrMethod())
3436 return 0;
3437
3438 uint64_t Offset = Stream.GetCurrentBitNo();
3439 SmallVector<DeclID, 128> KindDeclPairs;
3440 for (const auto *D : DC->decls()) {
3441 if (DoneWritingDeclsAndTypes && !wasDeclEmitted(D))
3442 continue;
3443
3444 // We don't need to write decls with internal linkage into reduced BMI.
3445 // If such decls gets emitted due to it get used from inline functions,
3446 // the program illegal. However, there are too many use of static inline
3447 // functions in the global module fragment and it will be breaking change
3448 // to forbid that. So we have to allow to emit such declarations from GMF.
3449 if (GeneratingReducedBMI && !D->isFromExplicitGlobalModule() &&
3450 IsInternalDeclFromFileContext(D))
3451 continue;
3452
3453 KindDeclPairs.push_back(Elt: D->getKind());
3454 KindDeclPairs.push_back(Elt: GetDeclRef(D).getRawValue());
3455 }
3456
3457 ++NumLexicalDeclContexts;
3458 RecordData::value_type Record[] = {DECL_CONTEXT_LEXICAL};
3459 Stream.EmitRecordWithBlob(Abbrev: DeclContextLexicalAbbrev, Vals: Record,
3460 Blob: bytes(v: KindDeclPairs));
3461 return Offset;
3462}
3463
3464void ASTWriter::WriteTypeDeclOffsets() {
3465 using namespace llvm;
3466
3467 // Write the type offsets array
3468 auto Abbrev = std::make_shared<BitCodeAbbrev>();
3469 Abbrev->Add(OpInfo: BitCodeAbbrevOp(TYPE_OFFSET));
3470 Abbrev->Add(OpInfo: BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32)); // # of types
3471 Abbrev->Add(OpInfo: BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // types block
3472 unsigned TypeOffsetAbbrev = Stream.EmitAbbrev(Abbv: std::move(Abbrev));
3473 {
3474 RecordData::value_type Record[] = {TYPE_OFFSET, TypeOffsets.size()};
3475 Stream.EmitRecordWithBlob(Abbrev: TypeOffsetAbbrev, Vals: Record, Blob: bytes(v: TypeOffsets));
3476 }
3477
3478 // Write the declaration offsets array
3479 Abbrev = std::make_shared<BitCodeAbbrev>();
3480 Abbrev->Add(OpInfo: BitCodeAbbrevOp(DECL_OFFSET));
3481 Abbrev->Add(OpInfo: BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32)); // # of declarations
3482 Abbrev->Add(OpInfo: BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // declarations block
3483 unsigned DeclOffsetAbbrev = Stream.EmitAbbrev(Abbv: std::move(Abbrev));
3484 {
3485 RecordData::value_type Record[] = {DECL_OFFSET, DeclOffsets.size()};
3486 Stream.EmitRecordWithBlob(Abbrev: DeclOffsetAbbrev, Vals: Record, Blob: bytes(v: DeclOffsets));
3487 }
3488}
3489
3490void ASTWriter::WriteFileDeclIDsMap() {
3491 using namespace llvm;
3492
3493 SmallVector<std::pair<FileID, DeclIDInFileInfo *>, 64> SortedFileDeclIDs;
3494 SortedFileDeclIDs.reserve(N: FileDeclIDs.size());
3495 for (const auto &P : FileDeclIDs)
3496 SortedFileDeclIDs.push_back(Elt: std::make_pair(x: P.first, y: P.second.get()));
3497 llvm::sort(C&: SortedFileDeclIDs, Comp: llvm::less_first());
3498
3499 // Join the vectors of DeclIDs from all files.
3500 SmallVector<DeclID, 256> FileGroupedDeclIDs;
3501 for (auto &FileDeclEntry : SortedFileDeclIDs) {
3502 DeclIDInFileInfo &Info = *FileDeclEntry.second;
3503 Info.FirstDeclIndex = FileGroupedDeclIDs.size();
3504 llvm::stable_sort(Range&: Info.DeclIDs);
3505 for (auto &LocDeclEntry : Info.DeclIDs)
3506 FileGroupedDeclIDs.push_back(Elt: LocDeclEntry.second.getRawValue());
3507 }
3508
3509 auto Abbrev = std::make_shared<BitCodeAbbrev>();
3510 Abbrev->Add(OpInfo: BitCodeAbbrevOp(FILE_SORTED_DECLS));
3511 Abbrev->Add(OpInfo: BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32));
3512 Abbrev->Add(OpInfo: BitCodeAbbrevOp(BitCodeAbbrevOp::Blob));
3513 unsigned AbbrevCode = Stream.EmitAbbrev(Abbv: std::move(Abbrev));
3514 RecordData::value_type Record[] = {FILE_SORTED_DECLS,
3515 FileGroupedDeclIDs.size()};
3516 Stream.EmitRecordWithBlob(Abbrev: AbbrevCode, Vals: Record, Blob: bytes(v: FileGroupedDeclIDs));
3517}
3518
3519void ASTWriter::WriteComments(ASTContext &Context) {
3520 Stream.EnterSubblock(BlockID: COMMENTS_BLOCK_ID, CodeLen: 3);
3521 llvm::scope_exit _([this] { Stream.ExitBlock(); });
3522 if (!PP->getPreprocessorOpts().WriteCommentListToPCH)
3523 return;
3524
3525 // Don't write comments to BMI to reduce the size of BMI.
3526 // If language services (e.g., clangd) want such abilities,
3527 // we can offer a special option then.
3528 if (isWritingStdCXXNamedModules())
3529 return;
3530
3531 RecordData Record;
3532 for (const auto &FO : Context.Comments.OrderedComments) {
3533 for (const auto &OC : FO.second) {
3534 const RawComment *I = OC.second;
3535 Record.clear();
3536 AddSourceRange(Range: I->getSourceRange(), Record);
3537 Record.push_back(Elt: I->getKind());
3538 Record.push_back(Elt: I->isTrailingComment());
3539 Record.push_back(Elt: I->isAlmostTrailingComment());
3540 Stream.EmitRecord(Code: COMMENTS_RAW_COMMENT, Vals: Record);
3541 }
3542 }
3543}
3544
3545//===----------------------------------------------------------------------===//
3546// Global Method Pool and Selector Serialization
3547//===----------------------------------------------------------------------===//
3548
3549namespace {
3550
3551// Trait used for the on-disk hash table used in the method pool.
3552class ASTMethodPoolTrait {
3553 ASTWriter &Writer;
3554
3555public:
3556 using key_type = Selector;
3557 using key_type_ref = key_type;
3558
3559 struct data_type {
3560 SelectorID ID;
3561 ObjCMethodList Instance, Factory;
3562 };
3563 using data_type_ref = const data_type &;
3564
3565 using hash_value_type = unsigned;
3566 using offset_type = unsigned;
3567
3568 explicit ASTMethodPoolTrait(ASTWriter &Writer) : Writer(Writer) {}
3569
3570 static hash_value_type ComputeHash(Selector Sel) {
3571 return serialization::ComputeHash(Sel);
3572 }
3573
3574 std::pair<unsigned, unsigned>
3575 EmitKeyDataLength(raw_ostream& Out, Selector Sel,
3576 data_type_ref Methods) {
3577 unsigned KeyLen =
3578 2 + (Sel.getNumArgs() ? Sel.getNumArgs() * sizeof(IdentifierID)
3579 : sizeof(IdentifierID));
3580 unsigned DataLen = 4 + 2 + 2; // 2 bytes for each of the method counts
3581 for (const ObjCMethodList *Method = &Methods.Instance; Method;
3582 Method = Method->getNext())
3583 if (ShouldWriteMethodListNode(Node: Method))
3584 DataLen += sizeof(DeclID);
3585 for (const ObjCMethodList *Method = &Methods.Factory; Method;
3586 Method = Method->getNext())
3587 if (ShouldWriteMethodListNode(Node: Method))
3588 DataLen += sizeof(DeclID);
3589 return emitULEBKeyDataLength(KeyLen, DataLen, Out);
3590 }
3591
3592 void EmitKey(raw_ostream& Out, Selector Sel, unsigned) {
3593 using namespace llvm::support;
3594
3595 endian::Writer LE(Out, llvm::endianness::little);
3596 uint64_t Start = Out.tell();
3597 assert((Start >> 32) == 0 && "Selector key offset too large");
3598 Writer.SetSelectorOffset(Sel, Offset: Start);
3599 unsigned N = Sel.getNumArgs();
3600 LE.write<uint16_t>(Val: N);
3601 if (N == 0)
3602 N = 1;
3603 for (unsigned I = 0; I != N; ++I)
3604 LE.write<IdentifierID>(
3605 Val: Writer.getIdentifierRef(II: Sel.getIdentifierInfoForSlot(argIndex: I)));
3606 }
3607
3608 void EmitData(raw_ostream& Out, key_type_ref,
3609 data_type_ref Methods, unsigned DataLen) {
3610 using namespace llvm::support;
3611
3612 endian::Writer LE(Out, llvm::endianness::little);
3613 uint64_t Start = Out.tell(); (void)Start;
3614 LE.write<uint32_t>(Val: Methods.ID);
3615 unsigned NumInstanceMethods = 0;
3616 for (const ObjCMethodList *Method = &Methods.Instance; Method;
3617 Method = Method->getNext())
3618 if (ShouldWriteMethodListNode(Node: Method))
3619 ++NumInstanceMethods;
3620
3621 unsigned NumFactoryMethods = 0;
3622 for (const ObjCMethodList *Method = &Methods.Factory; Method;
3623 Method = Method->getNext())
3624 if (ShouldWriteMethodListNode(Node: Method))
3625 ++NumFactoryMethods;
3626
3627 unsigned InstanceBits = Methods.Instance.getBits();
3628 assert(InstanceBits < 4);
3629 unsigned InstanceHasMoreThanOneDeclBit =
3630 Methods.Instance.hasMoreThanOneDecl();
3631 unsigned FullInstanceBits = (NumInstanceMethods << 3) |
3632 (InstanceHasMoreThanOneDeclBit << 2) |
3633 InstanceBits;
3634 unsigned FactoryBits = Methods.Factory.getBits();
3635 assert(FactoryBits < 4);
3636 unsigned FactoryHasMoreThanOneDeclBit =
3637 Methods.Factory.hasMoreThanOneDecl();
3638 unsigned FullFactoryBits = (NumFactoryMethods << 3) |
3639 (FactoryHasMoreThanOneDeclBit << 2) |
3640 FactoryBits;
3641 LE.write<uint16_t>(Val: FullInstanceBits);
3642 LE.write<uint16_t>(Val: FullFactoryBits);
3643 for (const ObjCMethodList *Method = &Methods.Instance; Method;
3644 Method = Method->getNext())
3645 if (ShouldWriteMethodListNode(Node: Method))
3646 LE.write<DeclID>(Val: (DeclID)Writer.getDeclID(D: Method->getMethod()));
3647 for (const ObjCMethodList *Method = &Methods.Factory; Method;
3648 Method = Method->getNext())
3649 if (ShouldWriteMethodListNode(Node: Method))
3650 LE.write<DeclID>(Val: (DeclID)Writer.getDeclID(D: Method->getMethod()));
3651
3652 assert(Out.tell() - Start == DataLen && "Data length is wrong");
3653 }
3654
3655private:
3656 static bool ShouldWriteMethodListNode(const ObjCMethodList *Node) {
3657 return (Node->getMethod() && !Node->getMethod()->isFromASTFile());
3658 }
3659};
3660
3661} // namespace
3662
3663/// Write ObjC data: selectors and the method pool.
3664///
3665/// The method pool contains both instance and factory methods, stored
3666/// in an on-disk hash table indexed by the selector. The hash table also
3667/// contains an empty entry for every other selector known to Sema.
3668void ASTWriter::WriteSelectors(Sema &SemaRef) {
3669 using namespace llvm;
3670
3671 // Do we have to do anything at all?
3672 if (SemaRef.ObjC().MethodPool.empty() && SelectorIDs.empty())
3673 return;
3674 unsigned NumTableEntries = 0;
3675 // Create and write out the blob that contains selectors and the method pool.
3676 {
3677 llvm::OnDiskChainedHashTableGenerator<ASTMethodPoolTrait> Generator;
3678 ASTMethodPoolTrait Trait(*this);
3679
3680 // Create the on-disk hash table representation. We walk through every
3681 // selector we've seen and look it up in the method pool.
3682 SelectorOffsets.resize(new_size: NextSelectorID - FirstSelectorID);
3683 for (auto &SelectorAndID : SelectorIDs) {
3684 Selector S = SelectorAndID.first;
3685 SelectorID ID = SelectorAndID.second;
3686 SemaObjC::GlobalMethodPool::iterator F =
3687 SemaRef.ObjC().MethodPool.find(Val: S);
3688 ASTMethodPoolTrait::data_type Data = {
3689 .ID: ID,
3690 .Instance: ObjCMethodList(),
3691 .Factory: ObjCMethodList()
3692 };
3693 if (F != SemaRef.ObjC().MethodPool.end()) {
3694 Data.Instance = F->second.first;
3695 Data.Factory = F->second.second;
3696 }
3697 // Only write this selector if it's not in an existing AST or something
3698 // changed.
3699 if (Chain && ID < FirstSelectorID) {
3700 // Selector already exists. Did it change?
3701 bool changed = false;
3702 for (ObjCMethodList *M = &Data.Instance; M && M->getMethod();
3703 M = M->getNext()) {
3704 if (!M->getMethod()->isFromASTFile()) {
3705 changed = true;
3706 Data.Instance = *M;
3707 break;
3708 }
3709 }
3710 for (ObjCMethodList *M = &Data.Factory; M && M->getMethod();
3711 M = M->getNext()) {
3712 if (!M->getMethod()->isFromASTFile()) {
3713 changed = true;
3714 Data.Factory = *M;
3715 break;
3716 }
3717 }
3718 if (!changed)
3719 continue;
3720 } else if (Data.Instance.getMethod() || Data.Factory.getMethod()) {
3721 // A new method pool entry.
3722 ++NumTableEntries;
3723 }
3724 Generator.insert(Key: S, Data, InfoObj&: Trait);
3725 }
3726
3727 // Create the on-disk hash table in a buffer.
3728 SmallString<4096> MethodPool;
3729 uint32_t BucketOffset;
3730 {
3731 using namespace llvm::support;
3732
3733 ASTMethodPoolTrait Trait(*this);
3734 llvm::raw_svector_ostream Out(MethodPool);
3735 // Make sure that no bucket is at offset 0
3736 endian::write<uint32_t>(os&: Out, value: 0, endian: llvm::endianness::little);
3737 BucketOffset = Generator.Emit(Out, InfoObj&: Trait);
3738 }
3739
3740 // Create a blob abbreviation
3741 auto Abbrev = std::make_shared<BitCodeAbbrev>();
3742 Abbrev->Add(OpInfo: BitCodeAbbrevOp(METHOD_POOL));
3743 Abbrev->Add(OpInfo: BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32));
3744 Abbrev->Add(OpInfo: BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32));
3745 Abbrev->Add(OpInfo: BitCodeAbbrevOp(BitCodeAbbrevOp::Blob));
3746 unsigned MethodPoolAbbrev = Stream.EmitAbbrev(Abbv: std::move(Abbrev));
3747
3748 // Write the method pool
3749 {
3750 RecordData::value_type Record[] = {METHOD_POOL, BucketOffset,
3751 NumTableEntries};
3752 Stream.EmitRecordWithBlob(Abbrev: MethodPoolAbbrev, Vals: Record, Blob: MethodPool);
3753 }
3754
3755 // Create a blob abbreviation for the selector table offsets.
3756 Abbrev = std::make_shared<BitCodeAbbrev>();
3757 Abbrev->Add(OpInfo: BitCodeAbbrevOp(SELECTOR_OFFSETS));
3758 Abbrev->Add(OpInfo: BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32)); // size
3759 Abbrev->Add(OpInfo: BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32)); // first ID
3760 Abbrev->Add(OpInfo: BitCodeAbbrevOp(BitCodeAbbrevOp::Blob));
3761 unsigned SelectorOffsetAbbrev = Stream.EmitAbbrev(Abbv: std::move(Abbrev));
3762
3763 // Write the selector offsets table.
3764 {
3765 RecordData::value_type Record[] = {
3766 SELECTOR_OFFSETS, SelectorOffsets.size(),
3767 FirstSelectorID - NUM_PREDEF_SELECTOR_IDS};
3768 Stream.EmitRecordWithBlob(Abbrev: SelectorOffsetAbbrev, Vals: Record,
3769 Blob: bytes(v: SelectorOffsets));
3770 }
3771 }
3772}
3773
3774/// Write the selectors referenced in @selector expression into AST file.
3775void ASTWriter::WriteReferencedSelectorsPool(Sema &SemaRef) {
3776 using namespace llvm;
3777
3778 if (SemaRef.ObjC().ReferencedSelectors.empty())
3779 return;
3780
3781 RecordData Record;
3782 ASTRecordWriter Writer(SemaRef.Context, *this, Record);
3783
3784 // Note: this writes out all references even for a dependent AST. But it is
3785 // very tricky to fix, and given that @selector shouldn't really appear in
3786 // headers, probably not worth it. It's not a correctness issue.
3787 for (auto &SelectorAndLocation : SemaRef.ObjC().ReferencedSelectors) {
3788 Selector Sel = SelectorAndLocation.first;
3789 SourceLocation Loc = SelectorAndLocation.second;
3790 Writer.AddSelectorRef(S: Sel);
3791 Writer.AddSourceLocation(Loc);
3792 }
3793 Writer.Emit(Code: REFERENCED_SELECTOR_POOL);
3794}
3795
3796//===----------------------------------------------------------------------===//
3797// Identifier Table Serialization
3798//===----------------------------------------------------------------------===//
3799
3800/// Determine the declaration that should be put into the name lookup table to
3801/// represent the given declaration in this module. This is usually D itself,
3802/// but if D was imported and merged into a local declaration, we want the most
3803/// recent local declaration instead. The chosen declaration will be the most
3804/// recent declaration in any module that imports this one.
3805static NamedDecl *getDeclForLocalLookup(const LangOptions &LangOpts,
3806 NamedDecl *D) {
3807 if (!LangOpts.Modules || !D->isFromASTFile())
3808 return D;
3809
3810 if (Decl *Redecl = D->getPreviousDecl()) {
3811 // For Redeclarable decls, a prior declaration might be local.
3812 for (; Redecl; Redecl = Redecl->getPreviousDecl()) {
3813 // If we find a local decl, we're done.
3814 if (!Redecl->isFromASTFile()) {
3815 // Exception: in very rare cases (for injected-class-names), not all
3816 // redeclarations are in the same semantic context. Skip ones in a
3817 // different context. They don't go in this lookup table at all.
3818 if (!Redecl->getDeclContext()->getRedeclContext()->Equals(
3819 DC: D->getDeclContext()->getRedeclContext()))
3820 continue;
3821 return cast<NamedDecl>(Val: Redecl);
3822 }
3823
3824 // If we find a decl from a (chained-)PCH stop since we won't find a
3825 // local one.
3826 if (Redecl->getOwningModuleID() == 0)
3827 break;
3828 }
3829 } else if (Decl *First = D->getCanonicalDecl()) {
3830 // For Mergeable decls, the first decl might be local.
3831 if (!First->isFromASTFile())
3832 return cast<NamedDecl>(Val: First);
3833 }
3834
3835 // All declarations are imported. Our most recent declaration will also be
3836 // the most recent one in anyone who imports us.
3837 return D;
3838}
3839
3840namespace {
3841
3842bool IsInterestingIdentifier(const IdentifierInfo *II, uint64_t MacroOffset,
3843 bool IsModule, bool IsCPlusPlus) {
3844 bool NeedDecls = !IsModule || !IsCPlusPlus;
3845
3846 bool IsInteresting =
3847 II->getNotableIdentifierID() != tok::NotableIdentifierKind::not_notable ||
3848 II->getBuiltinID() != Builtin::ID::NotBuiltin ||
3849 II->getObjCKeywordID() != tok::ObjCKeywordKind::objc_not_keyword;
3850 if (MacroOffset ||
3851 (II->hasMacroDefinition() &&
3852 II->hasFETokenInfoChangedSinceDeserialization()) ||
3853 II->isPoisoned() || (!IsModule && IsInteresting) ||
3854 II->hasRevertedTokenIDToIdentifier() ||
3855 (NeedDecls && II->getFETokenInfo()))
3856 return true;
3857
3858 return false;
3859}
3860
3861bool IsInterestingNonMacroIdentifier(const IdentifierInfo *II,
3862 ASTWriter &Writer) {
3863 bool IsModule = Writer.isWritingModule();
3864 bool IsCPlusPlus = Writer.getLangOpts().CPlusPlus;
3865 return IsInterestingIdentifier(II, /*MacroOffset=*/0, IsModule, IsCPlusPlus);
3866}
3867
3868class ASTIdentifierTableTrait {
3869 ASTWriter &Writer;
3870 Preprocessor &PP;
3871 IdentifierResolver *IdResolver;
3872 bool IsModule;
3873 bool NeedDecls;
3874 ASTWriter::RecordData *InterestingIdentifierOffsets;
3875
3876 /// Determines whether this is an "interesting" identifier that needs a
3877 /// full IdentifierInfo structure written into the hash table. Notably, this
3878 /// doesn't check whether the name has macros defined; use PublicMacroIterator
3879 /// to check that.
3880 bool isInterestingIdentifier(const IdentifierInfo *II, uint64_t MacroOffset) {
3881 return IsInterestingIdentifier(II, MacroOffset, IsModule,
3882 IsCPlusPlus: Writer.getLangOpts().CPlusPlus);
3883 }
3884
3885public:
3886 using key_type = const IdentifierInfo *;
3887 using key_type_ref = key_type;
3888
3889 using data_type = IdentifierID;
3890 using data_type_ref = data_type;
3891
3892 using hash_value_type = unsigned;
3893 using offset_type = unsigned;
3894
3895 ASTIdentifierTableTrait(ASTWriter &Writer, Preprocessor &PP,
3896 IdentifierResolver *IdResolver, bool IsModule,
3897 ASTWriter::RecordData *InterestingIdentifierOffsets)
3898 : Writer(Writer), PP(PP), IdResolver(IdResolver), IsModule(IsModule),
3899 NeedDecls(!IsModule || !Writer.getLangOpts().CPlusPlus),
3900 InterestingIdentifierOffsets(InterestingIdentifierOffsets) {}
3901
3902 bool needDecls() const { return NeedDecls; }
3903
3904 static hash_value_type ComputeHash(const IdentifierInfo* II) {
3905 return llvm::djbHash(Buffer: II->getName());
3906 }
3907
3908 bool isInterestingIdentifier(const IdentifierInfo *II) {
3909 auto MacroOffset = Writer.getMacroDirectivesOffset(Name: II);
3910 return isInterestingIdentifier(II, MacroOffset);
3911 }
3912
3913 std::pair<unsigned, unsigned>
3914 EmitKeyDataLength(raw_ostream &Out, const IdentifierInfo *II, IdentifierID ID) {
3915 // Record the location of the identifier data. This is used when generating
3916 // the mapping from persistent IDs to strings.
3917 Writer.SetIdentifierOffset(II, Offset: Out.tell());
3918
3919 auto MacroOffset = Writer.getMacroDirectivesOffset(Name: II);
3920
3921 // Emit the offset of the key/data length information to the interesting
3922 // identifiers table if necessary.
3923 if (InterestingIdentifierOffsets &&
3924 isInterestingIdentifier(II, MacroOffset))
3925 InterestingIdentifierOffsets->push_back(Elt: Out.tell());
3926
3927 unsigned KeyLen = II->getLength() + 1;
3928 unsigned DataLen = sizeof(IdentifierID); // bytes for the persistent ID << 1
3929 if (isInterestingIdentifier(II, MacroOffset)) {
3930 DataLen += 2; // 2 bytes for builtin ID
3931 DataLen += 2; // 2 bytes for flags
3932 if (MacroOffset || (II->hasMacroDefinition() &&
3933 II->hasFETokenInfoChangedSinceDeserialization()))
3934 DataLen += 4; // MacroDirectives offset.
3935
3936 if (NeedDecls && IdResolver)
3937 DataLen += std::distance(first: IdResolver->begin(Name: II), last: IdResolver->end()) *
3938 sizeof(DeclID);
3939 }
3940 return emitULEBKeyDataLength(KeyLen, DataLen, Out);
3941 }
3942
3943 void EmitKey(raw_ostream &Out, const IdentifierInfo *II, unsigned KeyLen) {
3944 Out.write(Ptr: II->getNameStart(), Size: KeyLen);
3945 }
3946
3947 void EmitData(raw_ostream &Out, const IdentifierInfo *II, IdentifierID ID,
3948 unsigned) {
3949 using namespace llvm::support;
3950
3951 endian::Writer LE(Out, llvm::endianness::little);
3952
3953 auto MacroOffset = Writer.getMacroDirectivesOffset(Name: II);
3954 if (!isInterestingIdentifier(II, MacroOffset)) {
3955 LE.write<IdentifierID>(Val: ID << 1);
3956 return;
3957 }
3958
3959 LE.write<IdentifierID>(Val: (ID << 1) | 0x01);
3960 uint32_t Bits = (uint32_t)II->getObjCOrBuiltinID();
3961 assert((Bits & 0xffff) == Bits && "ObjCOrBuiltinID too big for ASTReader.");
3962 LE.write<uint16_t>(Val: Bits);
3963 Bits = 0;
3964 bool HasMacroDefinition =
3965 (MacroOffset != 0) || (II->hasMacroDefinition() &&
3966 II->hasFETokenInfoChangedSinceDeserialization());
3967 Bits = (Bits << 1) | unsigned(HasMacroDefinition);
3968 Bits = (Bits << 1) | unsigned(II->isExtensionToken());
3969 Bits = (Bits << 1) | unsigned(II->isPoisoned());
3970 Bits = (Bits << 1) | unsigned(II->hasRevertedTokenIDToIdentifier());
3971 Bits = (Bits << 1) | unsigned(II->isCPlusPlusOperatorKeyword());
3972 LE.write<uint16_t>(Val: Bits);
3973
3974 if (HasMacroDefinition)
3975 LE.write<uint32_t>(Val: MacroOffset);
3976
3977 if (NeedDecls && IdResolver) {
3978 // Emit the declaration IDs in reverse order, because the
3979 // IdentifierResolver provides the declarations as they would be
3980 // visible (e.g., the function "stat" would come before the struct
3981 // "stat"), but the ASTReader adds declarations to the end of the list
3982 // (so we need to see the struct "stat" before the function "stat").
3983 // Only emit declarations that aren't from a chained PCH, though.
3984 SmallVector<NamedDecl *, 16> Decls(IdResolver->decls(Name: II));
3985 for (NamedDecl *D : llvm::reverse(C&: Decls))
3986 LE.write<DeclID>(Val: (DeclID)Writer.getDeclID(
3987 D: getDeclForLocalLookup(LangOpts: PP.getLangOpts(), D)));
3988 }
3989 }
3990};
3991
3992} // namespace
3993
3994/// If the \param IdentifierID ID is a local Identifier ID. If the higher
3995/// bits of ID is 0, it implies that the ID doesn't come from AST files.
3996static bool isLocalIdentifierID(IdentifierID ID) { return !(ID >> 32); }
3997
3998/// Write the identifier table into the AST file.
3999///
4000/// The identifier table consists of a blob containing string data
4001/// (the actual identifiers themselves) and a separate "offsets" index
4002/// that maps identifier IDs to locations within the blob.
4003void ASTWriter::WriteIdentifierTable(Preprocessor &PP,
4004 IdentifierResolver *IdResolver,
4005 bool IsModule) {
4006 using namespace llvm;
4007
4008 RecordData InterestingIdents;
4009
4010 // Create and write out the blob that contains the identifier
4011 // strings.
4012 {
4013 llvm::OnDiskChainedHashTableGenerator<ASTIdentifierTableTrait> Generator;
4014 ASTIdentifierTableTrait Trait(*this, PP, IdResolver, IsModule,
4015 IsModule ? &InterestingIdents : nullptr);
4016
4017 // Create the on-disk hash table representation. We only store offsets
4018 // for identifiers that appear here for the first time.
4019 IdentifierOffsets.resize(new_size: NextIdentID - FirstIdentID);
4020 for (auto IdentIDPair : IdentifierIDs) {
4021 const IdentifierInfo *II = IdentIDPair.first;
4022 IdentifierID ID = IdentIDPair.second;
4023 assert(II && "NULL identifier in identifier table");
4024
4025 // Write out identifiers if either the ID is local or the identifier has
4026 // changed since it was loaded.
4027 if (isLocalIdentifierID(ID) || II->hasChangedSinceDeserialization() ||
4028 (Trait.needDecls() &&
4029 II->hasFETokenInfoChangedSinceDeserialization()))
4030 Generator.insert(Key: II, Data: ID, InfoObj&: Trait);
4031 }
4032
4033 // Create the on-disk hash table in a buffer.
4034 SmallString<4096> IdentifierTable;
4035 uint32_t BucketOffset;
4036 {
4037 using namespace llvm::support;
4038
4039 llvm::raw_svector_ostream Out(IdentifierTable);
4040 // Make sure that no bucket is at offset 0
4041 endian::write<uint32_t>(os&: Out, value: 0, endian: llvm::endianness::little);
4042 BucketOffset = Generator.Emit(Out, InfoObj&: Trait);
4043 }
4044
4045 // Create a blob abbreviation
4046 auto Abbrev = std::make_shared<BitCodeAbbrev>();
4047 Abbrev->Add(OpInfo: BitCodeAbbrevOp(IDENTIFIER_TABLE));
4048 Abbrev->Add(OpInfo: BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32));
4049 Abbrev->Add(OpInfo: BitCodeAbbrevOp(BitCodeAbbrevOp::Blob));
4050 unsigned IDTableAbbrev = Stream.EmitAbbrev(Abbv: std::move(Abbrev));
4051
4052 // Write the identifier table
4053 RecordData::value_type Record[] = {IDENTIFIER_TABLE, BucketOffset};
4054 Stream.EmitRecordWithBlob(Abbrev: IDTableAbbrev, Vals: Record, Blob: IdentifierTable);
4055 }
4056
4057 // Write the offsets table for identifier IDs.
4058 auto Abbrev = std::make_shared<BitCodeAbbrev>();
4059 Abbrev->Add(OpInfo: BitCodeAbbrevOp(IDENTIFIER_OFFSET));
4060 Abbrev->Add(OpInfo: BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32)); // # of identifiers
4061 Abbrev->Add(OpInfo: BitCodeAbbrevOp(BitCodeAbbrevOp::Blob));
4062 unsigned IdentifierOffsetAbbrev = Stream.EmitAbbrev(Abbv: std::move(Abbrev));
4063
4064#ifndef NDEBUG
4065 for (unsigned I = 0, N = IdentifierOffsets.size(); I != N; ++I)
4066 assert(IdentifierOffsets[I] && "Missing identifier offset?");
4067#endif
4068
4069 RecordData::value_type Record[] = {IDENTIFIER_OFFSET,
4070 IdentifierOffsets.size()};
4071 Stream.EmitRecordWithBlob(Abbrev: IdentifierOffsetAbbrev, Vals: Record,
4072 Blob: bytes(v: IdentifierOffsets));
4073
4074 // In C++, write the list of interesting identifiers (those that are
4075 // defined as macros, poisoned, or similar unusual things).
4076 if (!InterestingIdents.empty())
4077 Stream.EmitRecord(Code: INTERESTING_IDENTIFIERS, Vals: InterestingIdents);
4078}
4079
4080void ASTWriter::handleVTable(CXXRecordDecl *RD) {
4081 if (!RD->isInNamedModule())
4082 return;
4083
4084 PendingEmittingVTables.push_back(Elt: RD);
4085}
4086
4087void ASTWriter::addTouchedModuleFile(serialization::ModuleFile *MF) {
4088 TouchedModuleFiles.insert(X: MF);
4089}
4090
4091//===----------------------------------------------------------------------===//
4092// DeclContext's Name Lookup Table Serialization
4093//===----------------------------------------------------------------------===//
4094
4095namespace {
4096
4097class ASTDeclContextNameLookupTraitBase {
4098protected:
4099 ASTWriter &Writer;
4100 using DeclIDsTy = llvm::SmallVector<LocalDeclID, 64>;
4101 DeclIDsTy DeclIDs;
4102
4103public:
4104 /// A start and end index into DeclIDs, representing a sequence of decls.
4105 using data_type = std::pair<unsigned, unsigned>;
4106 using data_type_ref = const data_type &;
4107
4108 using hash_value_type = unsigned;
4109 using offset_type = unsigned;
4110
4111 explicit ASTDeclContextNameLookupTraitBase(ASTWriter &Writer)
4112 : Writer(Writer) {}
4113
4114 data_type getData(const DeclIDsTy &LocalIDs) {
4115 unsigned Start = DeclIDs.size();
4116 for (auto ID : LocalIDs)
4117 DeclIDs.push_back(Elt: ID);
4118 return std::make_pair(x&: Start, y: DeclIDs.size());
4119 }
4120
4121 data_type ImportData(const reader::ASTDeclContextNameLookupTrait::data_type &FromReader) {
4122 unsigned Start = DeclIDs.size();
4123 DeclIDs.insert(
4124 I: DeclIDs.end(),
4125 From: DeclIDIterator<GlobalDeclID, LocalDeclID>(FromReader.begin()),
4126 To: DeclIDIterator<GlobalDeclID, LocalDeclID>(FromReader.end()));
4127 return std::make_pair(x&: Start, y: DeclIDs.size());
4128 }
4129
4130 void EmitFileRef(raw_ostream &Out, ModuleFile *F) const {
4131 assert(Writer.hasChain() &&
4132 "have reference to loaded module file but no chain?");
4133
4134 using namespace llvm::support;
4135 Writer.addTouchedModuleFile(MF: F);
4136 endian::write<uint32_t>(os&: Out, value: Writer.getChain()->getModuleFileID(M: F),
4137 endian: llvm::endianness::little);
4138 }
4139
4140 std::pair<unsigned, unsigned> EmitKeyDataLengthBase(raw_ostream &Out,
4141 DeclarationNameKey Name,
4142 data_type_ref Lookup) {
4143 unsigned KeyLen = 1;
4144 switch (Name.getKind()) {
4145 case DeclarationName::Identifier:
4146 case DeclarationName::CXXLiteralOperatorName:
4147 case DeclarationName::CXXDeductionGuideName:
4148 KeyLen += sizeof(IdentifierID);
4149 break;
4150 case DeclarationName::ObjCZeroArgSelector:
4151 case DeclarationName::ObjCOneArgSelector:
4152 case DeclarationName::ObjCMultiArgSelector:
4153 KeyLen += 4;
4154 break;
4155 case DeclarationName::CXXOperatorName:
4156 KeyLen += 1;
4157 break;
4158 case DeclarationName::CXXConstructorName:
4159 case DeclarationName::CXXDestructorName:
4160 case DeclarationName::CXXConversionFunctionName:
4161 case DeclarationName::CXXUsingDirective:
4162 break;
4163 }
4164
4165 // length of DeclIDs.
4166 unsigned DataLen = sizeof(DeclID) * (Lookup.second - Lookup.first);
4167
4168 return {KeyLen, DataLen};
4169 }
4170
4171 void EmitKeyBase(raw_ostream &Out, DeclarationNameKey Name) {
4172 using namespace llvm::support;
4173
4174 endian::Writer LE(Out, llvm::endianness::little);
4175 LE.write<uint8_t>(Val: Name.getKind());
4176 switch (Name.getKind()) {
4177 case DeclarationName::Identifier:
4178 case DeclarationName::CXXLiteralOperatorName:
4179 case DeclarationName::CXXDeductionGuideName:
4180 LE.write<IdentifierID>(Val: Writer.getIdentifierRef(II: Name.getIdentifier()));
4181 return;
4182 case DeclarationName::ObjCZeroArgSelector:
4183 case DeclarationName::ObjCOneArgSelector:
4184 case DeclarationName::ObjCMultiArgSelector:
4185 LE.write<uint32_t>(Val: Writer.getSelectorRef(Sel: Name.getSelector()));
4186 return;
4187 case DeclarationName::CXXOperatorName:
4188 assert(Name.getOperatorKind() < NUM_OVERLOADED_OPERATORS &&
4189 "Invalid operator?");
4190 LE.write<uint8_t>(Val: Name.getOperatorKind());
4191 return;
4192 case DeclarationName::CXXConstructorName:
4193 case DeclarationName::CXXDestructorName:
4194 case DeclarationName::CXXConversionFunctionName:
4195 case DeclarationName::CXXUsingDirective:
4196 return;
4197 }
4198
4199 llvm_unreachable("Invalid name kind?");
4200 }
4201
4202 void EmitDataBase(raw_ostream &Out, data_type Lookup, unsigned DataLen) {
4203 using namespace llvm::support;
4204
4205 endian::Writer LE(Out, llvm::endianness::little);
4206 uint64_t Start = Out.tell(); (void)Start;
4207 for (unsigned I = Lookup.first, N = Lookup.second; I != N; ++I)
4208 LE.write<DeclID>(Val: (DeclID)DeclIDs[I]);
4209 assert(Out.tell() - Start == DataLen && "Data length is wrong");
4210 }
4211};
4212
4213class ModuleLevelNameLookupTrait : public ASTDeclContextNameLookupTraitBase {
4214public:
4215 using primary_module_hash_type = unsigned;
4216
4217 using key_type = std::pair<DeclarationNameKey, primary_module_hash_type>;
4218 using key_type_ref = key_type;
4219
4220 explicit ModuleLevelNameLookupTrait(ASTWriter &Writer)
4221 : ASTDeclContextNameLookupTraitBase(Writer) {}
4222
4223 static bool EqualKey(key_type_ref a, key_type_ref b) { return a == b; }
4224
4225 hash_value_type ComputeHash(key_type Key) {
4226 llvm::FoldingSetNodeID ID;
4227 ID.AddInteger(I: Key.first.getHash());
4228 ID.AddInteger(I: Key.second);
4229 return ID.computeStableHash();
4230 }
4231
4232 std::pair<unsigned, unsigned>
4233 EmitKeyDataLength(raw_ostream &Out, key_type Key, data_type_ref Lookup) {
4234 auto [KeyLen, DataLen] = EmitKeyDataLengthBase(Out, Name: Key.first, Lookup);
4235 KeyLen += sizeof(Key.second);
4236 return emitULEBKeyDataLength(KeyLen, DataLen, Out);
4237 }
4238
4239 void EmitKey(raw_ostream &Out, key_type Key, unsigned) {
4240 EmitKeyBase(Out, Name: Key.first);
4241 llvm::support::endian::Writer LE(Out, llvm::endianness::little);
4242 LE.write<primary_module_hash_type>(Val: Key.second);
4243 }
4244
4245 void EmitData(raw_ostream &Out, key_type_ref, data_type Lookup,
4246 unsigned DataLen) {
4247 EmitDataBase(Out, Lookup, DataLen);
4248 }
4249};
4250
4251class ASTDeclContextNameTrivialLookupTrait
4252 : public ASTDeclContextNameLookupTraitBase {
4253public:
4254 using key_type = DeclarationNameKey;
4255 using key_type_ref = key_type;
4256
4257public:
4258 using ASTDeclContextNameLookupTraitBase::ASTDeclContextNameLookupTraitBase;
4259
4260 using ASTDeclContextNameLookupTraitBase::getData;
4261
4262 static bool EqualKey(key_type_ref a, key_type_ref b) { return a == b; }
4263
4264 hash_value_type ComputeHash(key_type Name) { return Name.getHash(); }
4265
4266 std::pair<unsigned, unsigned> EmitKeyDataLength(raw_ostream &Out,
4267 DeclarationNameKey Name,
4268 data_type_ref Lookup) {
4269 auto [KeyLen, DataLen] = EmitKeyDataLengthBase(Out, Name, Lookup);
4270 return emitULEBKeyDataLength(KeyLen, DataLen, Out);
4271 }
4272
4273 void EmitKey(raw_ostream &Out, DeclarationNameKey Name, unsigned) {
4274 return EmitKeyBase(Out, Name);
4275 }
4276
4277 void EmitData(raw_ostream &Out, key_type_ref, data_type Lookup,
4278 unsigned DataLen) {
4279 EmitDataBase(Out, Lookup, DataLen);
4280 }
4281};
4282
4283static bool isModuleLocalDecl(NamedDecl *D) {
4284 // For decls not in a file context, they should have the same visibility
4285 // with their parent.
4286 if (auto *Parent = dyn_cast<NamedDecl>(Val: D->getNonTransparentDeclContext());
4287 Parent && !D->getNonTransparentDeclContext()->isFileContext())
4288 return isModuleLocalDecl(D: Parent);
4289
4290 // Deduction Guide are special here. Since their logical parent context are
4291 // not their actual parent.
4292 if (auto *FTD = dyn_cast<FunctionTemplateDecl>(Val: D))
4293 if (auto *CDGD = dyn_cast<CXXDeductionGuideDecl>(Val: FTD->getTemplatedDecl()))
4294 return isModuleLocalDecl(D: CDGD->getDeducedTemplate());
4295
4296 if (D->getFormalLinkage() != Linkage::Module)
4297 return false;
4298
4299 // It is hard for the serializer to judge if the in-class friend declaration
4300 // is visible or not, so we just transfer the task to Sema. It should be a
4301 // safe decision since Sema is able to handle the lookup rules for in-class
4302 // friend declarations good enough already.
4303 if (D->getFriendObjectKind() &&
4304 isa<CXXRecordDecl>(Val: D->getLexicalDeclContext()))
4305 return false;
4306
4307 return true;
4308}
4309
4310static bool isTULocalInNamedModules(NamedDecl *D) {
4311 Module *NamedModule = D->getTopLevelOwningNamedModule();
4312 if (!NamedModule)
4313 return false;
4314
4315 // For none-top level decls, we choose to move it to the general visible
4316 // lookup table. Since the consumer may get its parent somehow and performs
4317 // a lookup in it (considering looking up the operator function in lambda).
4318 // The difference between module local lookup table and TU local lookup table
4319 // is, the consumers still have a chance to lookup in the module local lookup
4320 // table but **now** the consumers won't read the TU local lookup table if
4321 // the consumer is not the original TU.
4322 //
4323 // FIXME: It seems to be an optimization chance (and also a more correct
4324 // semantics) to remain the TULocal lookup table and performing similar lookup
4325 // with the module local lookup table except that we only allow the lookups
4326 // with the same module unit.
4327 if (!D->getNonTransparentDeclContext()->isFileContext())
4328 return false;
4329
4330 return D->getLinkageInternal() == Linkage::Internal;
4331}
4332
4333class ASTDeclContextNameLookupTrait
4334 : public ASTDeclContextNameTrivialLookupTrait {
4335public:
4336 using TULocalDeclsMapTy = llvm::DenseMap<key_type, DeclIDsTy>;
4337
4338 using ModuleLevelDeclsMapTy =
4339 llvm::DenseMap<ModuleLevelNameLookupTrait::key_type, DeclIDsTy>;
4340
4341private:
4342 enum class LookupVisibility {
4343 GenerallyVisibile,
4344 // The decls can only be found by other TU in the same module.
4345 // Note a clang::Module models a module unit instead of logical module
4346 // in C++20.
4347 ModuleLocalVisible,
4348 // The decls can only be found by the TU itself that defines it.
4349 TULocal,
4350 };
4351
4352 LookupVisibility getLookupVisibility(NamedDecl *D) const {
4353 // Only named modules have other lookup visibility.
4354 if (!Writer.isWritingStdCXXNamedModules())
4355 return LookupVisibility::GenerallyVisibile;
4356
4357 if (isModuleLocalDecl(D))
4358 return LookupVisibility::ModuleLocalVisible;
4359 if (isTULocalInNamedModules(D))
4360 return LookupVisibility::TULocal;
4361
4362 // A trick to handle enum constants. The enum constants is special since
4363 // they can be found directly without their parent context. This makes it
4364 // tricky to decide if an EnumConstantDecl is visible or not by their own
4365 // visibilities. E.g., for a class member, we can assume it is visible if
4366 // the user get its parent somehow. But for an enum constant, the users may
4367 // access if without its parent context. Although we can fix the problem in
4368 // Sema lookup process, it might be too complex, we just make a trick here.
4369 // Note that we only removes enum constant from the lookup table from its
4370 // parent of parent. We DON'T remove the enum constant from its parent. So
4371 // we don't need to care about merging problems here.
4372 if (auto *ECD = dyn_cast<EnumConstantDecl>(Val: D);
4373 ECD && DC.isFileContext() && ECD->getTopLevelOwningNamedModule()) {
4374 if (llvm::all_of(
4375 Range: DC.noload_lookup(
4376 Name: cast<EnumDecl>(Val: ECD->getDeclContext())->getDeclName()),
4377 P: [](auto *Found) {
4378 return Found->isInvisibleOutsideTheOwningModule();
4379 }))
4380 return ECD->isFromExplicitGlobalModule() ||
4381 ECD->isInAnonymousNamespace()
4382 ? LookupVisibility::TULocal
4383 : LookupVisibility::ModuleLocalVisible;
4384 }
4385
4386 return LookupVisibility::GenerallyVisibile;
4387 }
4388
4389 DeclContext &DC;
4390 ModuleLevelDeclsMapTy ModuleLocalDeclsMap;
4391 TULocalDeclsMapTy TULocalDeclsMap;
4392
4393public:
4394 using ASTDeclContextNameTrivialLookupTrait::
4395 ASTDeclContextNameTrivialLookupTrait;
4396
4397 ASTDeclContextNameLookupTrait(ASTWriter &Writer, DeclContext &DC)
4398 : ASTDeclContextNameTrivialLookupTrait(Writer), DC(DC) {}
4399
4400 template <typename Coll> data_type getData(const Coll &Decls) {
4401 unsigned Start = DeclIDs.size();
4402 auto AddDecl = [this](NamedDecl *D) {
4403 NamedDecl *DeclForLocalLookup =
4404 getDeclForLocalLookup(LangOpts: Writer.getLangOpts(), D);
4405
4406 if (Writer.getDoneWritingDeclsAndTypes() &&
4407 !Writer.wasDeclEmitted(D: DeclForLocalLookup))
4408 return;
4409
4410 // Try to avoid writing internal decls to reduced BMI.
4411 // See comments in ASTWriter::WriteDeclContextLexicalBlock for details.
4412 if (Writer.isGeneratingReducedBMI() &&
4413 !DeclForLocalLookup->isFromExplicitGlobalModule() &&
4414 IsInternalDeclFromFileContext(D: DeclForLocalLookup))
4415 return;
4416
4417 auto ID = Writer.GetDeclRef(D: DeclForLocalLookup);
4418
4419 switch (getLookupVisibility(D: DeclForLocalLookup)) {
4420 case LookupVisibility::ModuleLocalVisible:
4421 if (UnsignedOrNone PrimaryModuleHash =
4422 getPrimaryModuleHash(M: D->getOwningModule())) {
4423 auto Key = std::make_pair(x: D->getDeclName(), y: *PrimaryModuleHash);
4424 auto Iter = ModuleLocalDeclsMap.find(Val: Key);
4425 if (Iter == ModuleLocalDeclsMap.end())
4426 ModuleLocalDeclsMap.insert(KV: {Key, DeclIDsTy{ID}});
4427 else
4428 Iter->second.push_back(Elt: ID);
4429 return;
4430 }
4431 break;
4432 case LookupVisibility::TULocal: {
4433 auto Iter = TULocalDeclsMap.find(Val: D->getDeclName());
4434 if (Iter == TULocalDeclsMap.end())
4435 TULocalDeclsMap.insert(KV: {D->getDeclName(), DeclIDsTy{ID}});
4436 else
4437 Iter->second.push_back(Elt: ID);
4438 return;
4439 }
4440 case LookupVisibility::GenerallyVisibile:
4441 // Generally visible decls go into the general lookup table.
4442 break;
4443 }
4444
4445 DeclIDs.push_back(Elt: ID);
4446 };
4447 ASTReader *Chain = Writer.getChain();
4448 for (NamedDecl *D : Decls) {
4449 if (Chain && isa<NamespaceDecl>(Val: D) && D->isFromASTFile() &&
4450 D == Chain->getKeyDeclaration(D)) {
4451 // In ASTReader, we stored only the key declaration of a namespace decl
4452 // for this TU. If we have an external namespace decl, this is that
4453 // key declaration and we need to re-expand it to write out the first
4454 // decl from each module.
4455 //
4456 // See comment 'ASTReader::FindExternalVisibleDeclsByName' for details.
4457 auto Firsts =
4458 Writer.CollectFirstDeclFromEachModule(D, /*IncludeLocal=*/false);
4459 for (const auto &[_, First] : Firsts)
4460 AddDecl(cast<NamedDecl>(Val: const_cast<Decl *>(First)));
4461 } else {
4462 AddDecl(D);
4463 }
4464 }
4465 return std::make_pair(x&: Start, y: DeclIDs.size());
4466 }
4467
4468 const ModuleLevelDeclsMapTy &getModuleLocalDecls() {
4469 return ModuleLocalDeclsMap;
4470 }
4471
4472 const TULocalDeclsMapTy &getTULocalDecls() { return TULocalDeclsMap; }
4473};
4474
4475} // namespace
4476
4477namespace {
4478class LazySpecializationInfoLookupTrait {
4479 ASTWriter &Writer;
4480 llvm::SmallVector<serialization::reader::LazySpecializationInfo, 64> Specs;
4481
4482public:
4483 using key_type = unsigned;
4484 using key_type_ref = key_type;
4485
4486 /// A start and end index into Specs, representing a sequence of decls.
4487 using data_type = std::pair<unsigned, unsigned>;
4488 using data_type_ref = const data_type &;
4489
4490 using hash_value_type = unsigned;
4491 using offset_type = unsigned;
4492
4493 explicit LazySpecializationInfoLookupTrait(ASTWriter &Writer)
4494 : Writer(Writer) {}
4495
4496 template <typename Col, typename Col2>
4497 data_type getData(Col &&C, Col2 &ExistingInfo) {
4498 unsigned Start = Specs.size();
4499 for (auto *D : C) {
4500 NamedDecl *ND = getDeclForLocalLookup(LangOpts: Writer.getLangOpts(),
4501 D: const_cast<NamedDecl *>(D));
4502 Specs.push_back(Elt: GlobalDeclID(Writer.GetDeclRef(D: ND).getRawValue()));
4503 }
4504 for (const serialization::reader::LazySpecializationInfo &Info :
4505 ExistingInfo)
4506 Specs.push_back(Elt: Info);
4507 return std::make_pair(x&: Start, y: Specs.size());
4508 }
4509
4510 data_type ImportData(
4511 const reader::LazySpecializationInfoLookupTrait::data_type &FromReader) {
4512 unsigned Start = Specs.size();
4513 for (auto ID : FromReader)
4514 Specs.push_back(Elt: ID);
4515 return std::make_pair(x&: Start, y: Specs.size());
4516 }
4517
4518 static bool EqualKey(key_type_ref a, key_type_ref b) { return a == b; }
4519
4520 hash_value_type ComputeHash(key_type Name) { return Name; }
4521
4522 void EmitFileRef(raw_ostream &Out, ModuleFile *F) const {
4523 assert(Writer.hasChain() &&
4524 "have reference to loaded module file but no chain?");
4525
4526 using namespace llvm::support;
4527 Writer.addTouchedModuleFile(MF: F);
4528 endian::write<uint32_t>(os&: Out, value: Writer.getChain()->getModuleFileID(M: F),
4529 endian: llvm::endianness::little);
4530 }
4531
4532 std::pair<unsigned, unsigned> EmitKeyDataLength(raw_ostream &Out,
4533 key_type HashValue,
4534 data_type_ref Lookup) {
4535 // 4 bytes for each slot.
4536 unsigned KeyLen = 4;
4537 unsigned DataLen = sizeof(serialization::reader::LazySpecializationInfo) *
4538 (Lookup.second - Lookup.first);
4539
4540 return emitULEBKeyDataLength(KeyLen, DataLen, Out);
4541 }
4542
4543 void EmitKey(raw_ostream &Out, key_type HashValue, unsigned) {
4544 using namespace llvm::support;
4545
4546 endian::Writer LE(Out, llvm::endianness::little);
4547 LE.write<uint32_t>(Val: HashValue);
4548 }
4549
4550 void EmitData(raw_ostream &Out, key_type_ref, data_type Lookup,
4551 unsigned DataLen) {
4552 using namespace llvm::support;
4553
4554 endian::Writer LE(Out, llvm::endianness::little);
4555 uint64_t Start = Out.tell();
4556 (void)Start;
4557 for (unsigned I = Lookup.first, N = Lookup.second; I != N; ++I) {
4558 LE.write<DeclID>(Val: Specs[I].getRawValue());
4559 }
4560 assert(Out.tell() - Start == DataLen && "Data length is wrong");
4561 }
4562};
4563
4564unsigned CalculateODRHashForSpecs(const Decl *Spec) {
4565 ArrayRef<TemplateArgument> Args;
4566 if (auto *CTSD = dyn_cast<ClassTemplateSpecializationDecl>(Val: Spec))
4567 Args = CTSD->getTemplateArgs().asArray();
4568 else if (auto *VTSD = dyn_cast<VarTemplateSpecializationDecl>(Val: Spec))
4569 Args = VTSD->getTemplateArgs().asArray();
4570 else if (auto *FD = dyn_cast<FunctionDecl>(Val: Spec))
4571 Args = FD->getTemplateSpecializationArgs()->asArray();
4572 else
4573 llvm_unreachable("New Specialization Kind?");
4574
4575 return StableHashForTemplateArguments(Args);
4576}
4577} // namespace
4578
4579void ASTWriter::GenerateSpecializationInfoLookupTable(
4580 const NamedDecl *D, llvm::SmallVectorImpl<const Decl *> &Specializations,
4581 llvm::SmallVectorImpl<char> &LookupTable, bool IsPartial) {
4582 assert(D->isFirstDecl());
4583
4584 // Create the on-disk hash table representation.
4585 MultiOnDiskHashTableGenerator<reader::LazySpecializationInfoLookupTrait,
4586 LazySpecializationInfoLookupTrait>
4587 Generator;
4588 LazySpecializationInfoLookupTrait Trait(*this);
4589
4590 llvm::MapVector<unsigned, llvm::SmallVector<const NamedDecl *, 4>>
4591 SpecializationMaps;
4592
4593 for (auto *Specialization : Specializations) {
4594 unsigned HashedValue = CalculateODRHashForSpecs(Spec: Specialization);
4595
4596 auto Iter = SpecializationMaps.find(Key: HashedValue);
4597 if (Iter == SpecializationMaps.end())
4598 Iter = SpecializationMaps
4599 .try_emplace(Key: HashedValue,
4600 Args: llvm::SmallVector<const NamedDecl *, 4>())
4601 .first;
4602
4603 Iter->second.push_back(Elt: cast<NamedDecl>(Val: Specialization));
4604 }
4605
4606 auto *Lookups =
4607 Chain ? Chain->getLoadedSpecializationsLookupTables(D, IsPartial)
4608 : nullptr;
4609
4610 for (auto &[HashValue, Specs] : SpecializationMaps) {
4611 SmallVector<serialization::reader::LazySpecializationInfo, 16>
4612 ExisitingSpecs;
4613 // We have to merge the lookup table manually here. We can't depend on the
4614 // merge mechanism offered by
4615 // clang::serialization::MultiOnDiskHashTableGenerator since that generator
4616 // assumes the we'll get the same value with the same key.
4617 // And also underlying llvm::OnDiskChainedHashTableGenerator assumes that we
4618 // won't insert the values with the same key twice. So we have to merge the
4619 // lookup table here manually.
4620 if (Lookups)
4621 ExisitingSpecs = Lookups->Table.find(EKey: HashValue);
4622
4623 Generator.insert(Key: HashValue, Data: Trait.getData(C&: Specs, ExistingInfo&: ExisitingSpecs), Info&: Trait);
4624 }
4625
4626 Generator.emit(Out&: LookupTable, Info&: Trait, Base: Lookups ? &Lookups->Table : nullptr);
4627}
4628
4629uint64_t ASTWriter::WriteSpecializationInfoLookupTable(
4630 const NamedDecl *D, llvm::SmallVectorImpl<const Decl *> &Specializations,
4631 bool IsPartial) {
4632
4633 llvm::SmallString<4096> LookupTable;
4634 GenerateSpecializationInfoLookupTable(D, Specializations, LookupTable,
4635 IsPartial);
4636
4637 uint64_t Offset = Stream.GetCurrentBitNo();
4638 RecordData::value_type Record[] = {static_cast<RecordData::value_type>(
4639 IsPartial ? DECL_PARTIAL_SPECIALIZATIONS : DECL_SPECIALIZATIONS)};
4640 Stream.EmitRecordWithBlob(Abbrev: IsPartial ? DeclPartialSpecializationsAbbrev
4641 : DeclSpecializationsAbbrev,
4642 Vals: Record, Blob: LookupTable);
4643
4644 return Offset;
4645}
4646
4647/// Returns true if all of the lookup result are either external, not emitted or
4648/// predefined. In such cases, the lookup result is not interesting and we don't
4649/// need to record the result in the current being written module. Return false
4650/// otherwise.
4651static bool isLookupResultNotInteresting(ASTWriter &Writer,
4652 StoredDeclsList &Result) {
4653 for (auto *D : Result.getLookupResult()) {
4654 auto *LocalD = getDeclForLocalLookup(LangOpts: Writer.getLangOpts(), D);
4655 if (LocalD->isFromASTFile())
4656 continue;
4657
4658 // We can only be sure whether the local declaration is reachable
4659 // after we done writing the declarations and types.
4660 if (Writer.getDoneWritingDeclsAndTypes() && !Writer.wasDeclEmitted(D: LocalD))
4661 continue;
4662
4663 // We don't need to emit the predefined decls.
4664 if (Writer.isDeclPredefined(D: LocalD))
4665 continue;
4666
4667 return false;
4668 }
4669
4670 return true;
4671}
4672
4673void ASTWriter::GenerateNameLookupTable(
4674 ASTContext &Context, const DeclContext *ConstDC,
4675 llvm::SmallVectorImpl<char> &LookupTable,
4676 llvm::SmallVectorImpl<char> &ModuleLocalLookupTable,
4677 llvm::SmallVectorImpl<char> &TULookupTable) {
4678 assert(!ConstDC->hasLazyLocalLexicalLookups() &&
4679 !ConstDC->hasLazyExternalLexicalLookups() &&
4680 "must call buildLookups first");
4681
4682 // FIXME: We need to build the lookups table, which is logically const.
4683 auto *DC = const_cast<DeclContext*>(ConstDC);
4684 assert(DC == DC->getPrimaryContext() && "only primary DC has lookup table");
4685
4686 // Create the on-disk hash table representation.
4687 MultiOnDiskHashTableGenerator<reader::ASTDeclContextNameLookupTrait,
4688 ASTDeclContextNameLookupTrait>
4689 Generator;
4690 ASTDeclContextNameLookupTrait Trait(*this, *DC);
4691
4692 // The first step is to collect the declaration names which we need to
4693 // serialize into the name lookup table, and to collect them in a stable
4694 // order.
4695 SmallVector<DeclarationName, 16> Names;
4696
4697 // We also track whether we're writing out the DeclarationNameKey for
4698 // constructors or conversion functions.
4699 bool IncludeConstructorNames = false;
4700 bool IncludeConversionNames = false;
4701
4702 for (auto &[Name, Result] : *DC->buildLookup()) {
4703 // If there are no local declarations in our lookup result, we
4704 // don't need to write an entry for the name at all. If we can't
4705 // write out a lookup set without performing more deserialization,
4706 // just skip this entry.
4707 //
4708 // Also in reduced BMI, we'd like to avoid writing unreachable
4709 // declarations in GMF, so we need to avoid writing declarations
4710 // that entirely external or unreachable.
4711 if (GeneratingReducedBMI && isLookupResultNotInteresting(Writer&: *this, Result))
4712 continue;
4713 // We also skip empty results. If any of the results could be external and
4714 // the currently available results are empty, then all of the results are
4715 // external and we skip it above. So the only way we get here with an empty
4716 // results is when no results could have been external *and* we have
4717 // external results.
4718 //
4719 // FIXME: While we might want to start emitting on-disk entries for negative
4720 // lookups into a decl context as an optimization, today we *have* to skip
4721 // them because there are names with empty lookup results in decl contexts
4722 // which we can't emit in any stable ordering: we lookup constructors and
4723 // conversion functions in the enclosing namespace scope creating empty
4724 // results for them. This in almost certainly a bug in Clang's name lookup,
4725 // but that is likely to be hard or impossible to fix and so we tolerate it
4726 // here by omitting lookups with empty results.
4727 if (Result.getLookupResult().empty())
4728 continue;
4729
4730 switch (Name.getNameKind()) {
4731 default:
4732 Names.push_back(Elt: Name);
4733 break;
4734
4735 case DeclarationName::CXXConstructorName:
4736 IncludeConstructorNames = true;
4737 break;
4738
4739 case DeclarationName::CXXConversionFunctionName:
4740 IncludeConversionNames = true;
4741 break;
4742 }
4743 }
4744
4745 // Sort the names into a stable order.
4746 llvm::sort(C&: Names);
4747
4748 if (IncludeConstructorNames || IncludeConversionNames) {
4749 // We need to establish an ordering of constructor and conversion function
4750 // names, and they don't have an intrinsic ordering. We also need to write
4751 // out all constructor and conversion function results if we write out any
4752 // of them, because they're all tracked under the same lookup key.
4753 llvm::SmallPtrSet<DeclarationName, 8> AddedNames;
4754 for (Decl *ChildD : cast<CXXRecordDecl>(Val: DC)->decls()) {
4755 if (auto *ChildND = dyn_cast<NamedDecl>(Val: ChildD)) {
4756 auto Name = ChildND->getDeclName();
4757 switch (Name.getNameKind()) {
4758 default:
4759 continue;
4760
4761 case DeclarationName::CXXConstructorName:
4762 if (!IncludeConstructorNames)
4763 continue;
4764 break;
4765
4766 case DeclarationName::CXXConversionFunctionName:
4767 if (!IncludeConversionNames)
4768 continue;
4769 break;
4770 }
4771 if (AddedNames.insert(Ptr: Name).second)
4772 Names.push_back(Elt: Name);
4773 }
4774 }
4775 }
4776 // Next we need to do a lookup with each name into this decl context to fully
4777 // populate any results from external sources. We don't actually use the
4778 // results of these lookups because we only want to use the results after all
4779 // results have been loaded and the pointers into them will be stable.
4780 for (auto &Name : Names)
4781 DC->lookup(Name);
4782
4783 // Now we need to insert the results for each name into the hash table. For
4784 // constructor names and conversion function names, we actually need to merge
4785 // all of the results for them into one list of results each and insert
4786 // those.
4787 SmallVector<NamedDecl *, 8> ConstructorDecls;
4788 SmallVector<NamedDecl *, 8> ConversionDecls;
4789
4790 // Now loop over the names, either inserting them or appending for the two
4791 // special cases.
4792 for (auto &Name : Names) {
4793 DeclContext::lookup_result Result = DC->noload_lookup(Name);
4794
4795 switch (Name.getNameKind()) {
4796 default:
4797 Generator.insert(Key: Name, Data: Trait.getData(Decls: Result), Info&: Trait);
4798 break;
4799
4800 case DeclarationName::CXXConstructorName:
4801 ConstructorDecls.append(in_start: Result.begin(), in_end: Result.end());
4802 break;
4803
4804 case DeclarationName::CXXConversionFunctionName:
4805 ConversionDecls.append(in_start: Result.begin(), in_end: Result.end());
4806 break;
4807 }
4808 }
4809
4810 // Handle our two special cases if we ended up having any. We arbitrarily use
4811 // the first declaration's name here because the name itself isn't part of
4812 // the key, only the kind of name is used.
4813 if (!ConstructorDecls.empty())
4814 Generator.insert(Key: ConstructorDecls.front()->getDeclName(),
4815 Data: Trait.getData(Decls: ConstructorDecls), Info&: Trait);
4816 if (!ConversionDecls.empty())
4817 Generator.insert(Key: ConversionDecls.front()->getDeclName(),
4818 Data: Trait.getData(Decls: ConversionDecls), Info&: Trait);
4819
4820 // Create the on-disk hash table. Also emit the existing imported and
4821 // merged table if there is one.
4822 auto *Lookups = Chain ? Chain->getLoadedLookupTables(Primary: DC) : nullptr;
4823 Generator.emit(Out&: LookupTable, Info&: Trait, Base: Lookups ? &Lookups->Table : nullptr);
4824
4825 const auto &ModuleLocalDecls = Trait.getModuleLocalDecls();
4826 if (!ModuleLocalDecls.empty()) {
4827 MultiOnDiskHashTableGenerator<reader::ModuleLocalNameLookupTrait,
4828 ModuleLevelNameLookupTrait>
4829 ModuleLocalLookupGenerator;
4830 ModuleLevelNameLookupTrait ModuleLocalTrait(*this);
4831
4832 for (const auto &ModuleLocalIter : ModuleLocalDecls) {
4833 const auto &Key = ModuleLocalIter.first;
4834 const auto &IDs = ModuleLocalIter.second;
4835 ModuleLocalLookupGenerator.insert(Key, Data: ModuleLocalTrait.getData(LocalIDs: IDs),
4836 Info&: ModuleLocalTrait);
4837 }
4838
4839 auto *ModuleLocalLookups =
4840 Chain ? Chain->getModuleLocalLookupTables(Primary: DC) : nullptr;
4841 ModuleLocalLookupGenerator.emit(
4842 Out&: ModuleLocalLookupTable, Info&: ModuleLocalTrait,
4843 Base: ModuleLocalLookups ? &ModuleLocalLookups->Table : nullptr);
4844 }
4845
4846 const auto &TULocalDecls = Trait.getTULocalDecls();
4847 if (!TULocalDecls.empty() && !isGeneratingReducedBMI()) {
4848 MultiOnDiskHashTableGenerator<reader::ASTDeclContextNameLookupTrait,
4849 ASTDeclContextNameTrivialLookupTrait>
4850 TULookupGenerator;
4851 ASTDeclContextNameTrivialLookupTrait TULocalTrait(*this);
4852
4853 for (const auto &TULocalIter : TULocalDecls) {
4854 const auto &Key = TULocalIter.first;
4855 const auto &IDs = TULocalIter.second;
4856 TULookupGenerator.insert(Key, Data: TULocalTrait.getData(LocalIDs: IDs), Info&: TULocalTrait);
4857 }
4858
4859 auto *TULocalLookups = Chain ? Chain->getTULocalLookupTables(Primary: DC) : nullptr;
4860 TULookupGenerator.emit(Out&: TULookupTable, Info&: TULocalTrait,
4861 Base: TULocalLookups ? &TULocalLookups->Table : nullptr);
4862 }
4863}
4864
4865/// Write the block containing all of the declaration IDs
4866/// visible from the given DeclContext.
4867///
4868/// \returns the offset of the DECL_CONTEXT_VISIBLE block within the
4869/// bitstream, or 0 if no block was written.
4870void ASTWriter::WriteDeclContextVisibleBlock(
4871 ASTContext &Context, DeclContext *DC, VisibleLookupBlockOffsets &Offsets) {
4872 assert(!Offsets);
4873
4874 // If we imported a key declaration of this namespace, write the visible
4875 // lookup results as an update record for it rather than including them
4876 // on this declaration. We will only look at key declarations on reload.
4877 if (isa<NamespaceDecl>(Val: DC) && Chain &&
4878 Chain->getKeyDeclaration(D: cast<Decl>(Val: DC))->isFromASTFile()) {
4879 // Only do this once, for the first local declaration of the namespace.
4880 for (auto *Prev = cast<NamespaceDecl>(Val: DC)->getPreviousDecl(); Prev;
4881 Prev = Prev->getPreviousDecl())
4882 if (!Prev->isFromASTFile())
4883 return;
4884
4885 // Note that we need to emit an update record for the primary context.
4886 UpdatedDeclContexts.insert(X: DC->getPrimaryContext());
4887
4888 // Make sure all visible decls are written. They will be recorded later. We
4889 // do this using a side data structure so we can sort the names into
4890 // a deterministic order.
4891 StoredDeclsMap *Map = DC->getPrimaryContext()->buildLookup();
4892 SmallVector<std::pair<DeclarationName, DeclContext::lookup_result>, 16>
4893 LookupResults;
4894 if (Map) {
4895 LookupResults.reserve(N: Map->size());
4896 for (auto &Entry : *Map)
4897 LookupResults.push_back(
4898 Elt: std::make_pair(x&: Entry.first, y: Entry.second.getLookupResult()));
4899 }
4900
4901 llvm::sort(C&: LookupResults, Comp: llvm::less_first());
4902 for (auto &NameAndResult : LookupResults) {
4903 DeclarationName Name = NameAndResult.first;
4904 DeclContext::lookup_result Result = NameAndResult.second;
4905 if (Name.getNameKind() == DeclarationName::CXXConstructorName ||
4906 Name.getNameKind() == DeclarationName::CXXConversionFunctionName) {
4907 // We have to work around a name lookup bug here where negative lookup
4908 // results for these names get cached in namespace lookup tables (these
4909 // names should never be looked up in a namespace).
4910 assert(Result.empty() && "Cannot have a constructor or conversion "
4911 "function name in a namespace!");
4912 continue;
4913 }
4914
4915 for (NamedDecl *ND : Result) {
4916 if (ND->isFromASTFile())
4917 continue;
4918
4919 if (DoneWritingDeclsAndTypes && !wasDeclEmitted(D: ND))
4920 continue;
4921
4922 // We don't need to force emitting internal decls into reduced BMI.
4923 // See comments in ASTWriter::WriteDeclContextLexicalBlock for details.
4924 if (GeneratingReducedBMI && !ND->isFromExplicitGlobalModule() &&
4925 IsInternalDeclFromFileContext(D: ND))
4926 continue;
4927
4928 GetDeclRef(D: ND);
4929 }
4930 }
4931
4932 return;
4933 }
4934
4935 if (DC->getPrimaryContext() != DC)
4936 return;
4937
4938 // Skip contexts which don't support name lookup.
4939 if (!DC->isLookupContext())
4940 return;
4941
4942 // If not in C++, we perform name lookup for the translation unit via the
4943 // IdentifierInfo chains, don't bother to build a visible-declarations table.
4944 if (DC->isTranslationUnit() && !Context.getLangOpts().CPlusPlus)
4945 return;
4946
4947 // Serialize the contents of the mapping used for lookup. Note that,
4948 // although we have two very different code paths, the serialized
4949 // representation is the same for both cases: a declaration name,
4950 // followed by a size, followed by references to the visible
4951 // declarations that have that name.
4952 StoredDeclsMap *Map = DC->buildLookup();
4953 if (!Map || Map->empty())
4954 return;
4955
4956 Offsets.VisibleOffset = Stream.GetCurrentBitNo();
4957 // Create the on-disk hash table in a buffer.
4958 SmallString<4096> LookupTable;
4959 SmallString<4096> ModuleLocalLookupTable;
4960 SmallString<4096> TULookupTable;
4961 GenerateNameLookupTable(Context, ConstDC: DC, LookupTable, ModuleLocalLookupTable,
4962 TULookupTable);
4963
4964 // Write the lookup table
4965 RecordData::value_type Record[] = {DECL_CONTEXT_VISIBLE};
4966 Stream.EmitRecordWithBlob(Abbrev: DeclContextVisibleLookupAbbrev, Vals: Record,
4967 Blob: LookupTable);
4968 ++NumVisibleDeclContexts;
4969
4970 if (!ModuleLocalLookupTable.empty()) {
4971 Offsets.ModuleLocalOffset = Stream.GetCurrentBitNo();
4972 assert(Offsets.ModuleLocalOffset > Offsets.VisibleOffset);
4973 // Write the lookup table
4974 RecordData::value_type ModuleLocalRecord[] = {
4975 DECL_CONTEXT_MODULE_LOCAL_VISIBLE};
4976 Stream.EmitRecordWithBlob(Abbrev: DeclModuleLocalVisibleLookupAbbrev,
4977 Vals: ModuleLocalRecord, Blob: ModuleLocalLookupTable);
4978 ++NumModuleLocalDeclContexts;
4979 }
4980
4981 if (!TULookupTable.empty()) {
4982 Offsets.TULocalOffset = Stream.GetCurrentBitNo();
4983 // Write the lookup table
4984 RecordData::value_type TULocalDeclsRecord[] = {
4985 DECL_CONTEXT_TU_LOCAL_VISIBLE};
4986 Stream.EmitRecordWithBlob(Abbrev: DeclTULocalLookupAbbrev, Vals: TULocalDeclsRecord,
4987 Blob: TULookupTable);
4988 ++NumTULocalDeclContexts;
4989 }
4990}
4991
4992/// Write an UPDATE_VISIBLE block for the given context.
4993///
4994/// UPDATE_VISIBLE blocks contain the declarations that are added to an existing
4995/// DeclContext in a dependent AST file. As such, they only exist for the TU
4996/// (in C++), for namespaces, and for classes with forward-declared unscoped
4997/// enumeration members (in C++11).
4998void ASTWriter::WriteDeclContextVisibleUpdate(ASTContext &Context,
4999 const DeclContext *DC) {
5000 StoredDeclsMap *Map = DC->getLookupPtr();
5001 if (!Map || Map->empty())
5002 return;
5003
5004 // Create the on-disk hash table in a buffer.
5005 SmallString<4096> LookupTable;
5006 SmallString<4096> ModuleLocalLookupTable;
5007 SmallString<4096> TULookupTable;
5008 GenerateNameLookupTable(Context, ConstDC: DC, LookupTable, ModuleLocalLookupTable,
5009 TULookupTable);
5010
5011 // If we're updating a namespace, select a key declaration as the key for the
5012 // update record; those are the only ones that will be checked on reload.
5013 if (isa<NamespaceDecl>(Val: DC))
5014 DC = cast<DeclContext>(Val: Chain->getKeyDeclaration(D: cast<Decl>(Val: DC)));
5015
5016 // Write the lookup table
5017 RecordData::value_type Record[] = {UPDATE_VISIBLE,
5018 getDeclID(D: cast<Decl>(Val: DC)).getRawValue()};
5019 Stream.EmitRecordWithBlob(Abbrev: UpdateVisibleAbbrev, Vals: Record, Blob: LookupTable);
5020
5021 if (!ModuleLocalLookupTable.empty()) {
5022 // Write the module local lookup table
5023 RecordData::value_type ModuleLocalRecord[] = {
5024 UPDATE_MODULE_LOCAL_VISIBLE, getDeclID(D: cast<Decl>(Val: DC)).getRawValue()};
5025 Stream.EmitRecordWithBlob(Abbrev: ModuleLocalUpdateVisibleAbbrev, Vals: ModuleLocalRecord,
5026 Blob: ModuleLocalLookupTable);
5027 }
5028
5029 if (!TULookupTable.empty()) {
5030 RecordData::value_type GMFRecord[] = {
5031 UPDATE_TU_LOCAL_VISIBLE, getDeclID(D: cast<Decl>(Val: DC)).getRawValue()};
5032 Stream.EmitRecordWithBlob(Abbrev: TULocalUpdateVisibleAbbrev, Vals: GMFRecord,
5033 Blob: TULookupTable);
5034 }
5035}
5036
5037/// Write an FP_PRAGMA_OPTIONS block for the given FPOptions.
5038void ASTWriter::WriteFPPragmaOptions(const FPOptionsOverride &Opts) {
5039 RecordData::value_type Record[] = {Opts.getAsOpaqueInt()};
5040 Stream.EmitRecord(Code: FP_PRAGMA_OPTIONS, Vals: Record);
5041}
5042
5043/// Write an OPENCL_EXTENSIONS block for the given OpenCLOptions.
5044void ASTWriter::WriteOpenCLExtensions(Sema &SemaRef) {
5045 if (!SemaRef.Context.getLangOpts().OpenCL)
5046 return;
5047
5048 const OpenCLOptions &Opts = SemaRef.getOpenCLOptions();
5049 RecordData Record;
5050 for (const auto &I:Opts.OptMap) {
5051 AddString(Str: I.getKey(), Record);
5052 auto V = I.getValue();
5053 Record.push_back(Elt: V.Supported ? 1 : 0);
5054 Record.push_back(Elt: V.Enabled ? 1 : 0);
5055 Record.push_back(Elt: V.WithPragma ? 1 : 0);
5056 Record.push_back(Elt: V.Avail);
5057 Record.push_back(Elt: V.Core);
5058 Record.push_back(Elt: V.Opt);
5059 }
5060 Stream.EmitRecord(Code: OPENCL_EXTENSIONS, Vals: Record);
5061}
5062void ASTWriter::WriteCUDAPragmas(Sema &SemaRef) {
5063 if (SemaRef.CUDA().ForceHostDeviceDepth > 0) {
5064 RecordData::value_type Record[] = {SemaRef.CUDA().ForceHostDeviceDepth};
5065 Stream.EmitRecord(Code: CUDA_PRAGMA_FORCE_HOST_DEVICE_DEPTH, Vals: Record);
5066 }
5067}
5068
5069void ASTWriter::WriteObjCCategories() {
5070 if (ObjCClassesWithCategories.empty())
5071 return;
5072
5073 SmallVector<ObjCCategoriesInfo, 2> CategoriesMap;
5074 RecordData Categories;
5075
5076 for (unsigned I = 0, N = ObjCClassesWithCategories.size(); I != N; ++I) {
5077 unsigned Size = 0;
5078 unsigned StartIndex = Categories.size();
5079
5080 ObjCInterfaceDecl *Class = ObjCClassesWithCategories[I];
5081
5082 // Allocate space for the size.
5083 Categories.push_back(Elt: 0);
5084
5085 // Add the categories.
5086 for (ObjCInterfaceDecl::known_categories_iterator
5087 Cat = Class->known_categories_begin(),
5088 CatEnd = Class->known_categories_end();
5089 Cat != CatEnd; ++Cat, ++Size) {
5090 assert(getDeclID(*Cat).isValid() && "Bogus category");
5091 AddDeclRef(D: *Cat, Record&: Categories);
5092 }
5093
5094 // Update the size.
5095 Categories[StartIndex] = Size;
5096
5097 // Record this interface -> category map.
5098 ObjCCategoriesInfo CatInfo = { getDeclID(D: Class), StartIndex };
5099 CategoriesMap.push_back(Elt: CatInfo);
5100 }
5101
5102 // Sort the categories map by the definition ID, since the reader will be
5103 // performing binary searches on this information.
5104 llvm::array_pod_sort(Start: CategoriesMap.begin(), End: CategoriesMap.end());
5105
5106 // Emit the categories map.
5107 using namespace llvm;
5108
5109 auto Abbrev = std::make_shared<BitCodeAbbrev>();
5110 Abbrev->Add(OpInfo: BitCodeAbbrevOp(OBJC_CATEGORIES_MAP));
5111 Abbrev->Add(OpInfo: BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // # of entries
5112 Abbrev->Add(OpInfo: BitCodeAbbrevOp(BitCodeAbbrevOp::Blob));
5113 unsigned AbbrevID = Stream.EmitAbbrev(Abbv: std::move(Abbrev));
5114
5115 RecordData::value_type Record[] = {OBJC_CATEGORIES_MAP, CategoriesMap.size()};
5116 Stream.EmitRecordWithBlob(Abbrev: AbbrevID, Vals: Record,
5117 BlobData: reinterpret_cast<char *>(CategoriesMap.data()),
5118 BlobLen: CategoriesMap.size() * sizeof(ObjCCategoriesInfo));
5119
5120 // Emit the category lists.
5121 Stream.EmitRecord(Code: OBJC_CATEGORIES, Vals: Categories);
5122}
5123
5124void ASTWriter::WriteLateParsedTemplates(Sema &SemaRef) {
5125 Sema::LateParsedTemplateMapT &LPTMap = SemaRef.LateParsedTemplateMap;
5126
5127 if (LPTMap.empty())
5128 return;
5129
5130 RecordData Record;
5131 for (auto &LPTMapEntry : LPTMap) {
5132 const FunctionDecl *FD = LPTMapEntry.first;
5133 LateParsedTemplate &LPT = *LPTMapEntry.second;
5134 AddDeclRef(D: FD, Record);
5135 AddDeclRef(D: LPT.D, Record);
5136 Record.push_back(Elt: LPT.FPO.getAsOpaqueInt());
5137 Record.push_back(Elt: LPT.Toks.size());
5138
5139 for (const auto &Tok : LPT.Toks) {
5140 AddToken(Tok, Record);
5141 }
5142 }
5143 Stream.EmitRecord(Code: LATE_PARSED_TEMPLATE, Vals: Record);
5144}
5145
5146/// Write the state of 'pragma clang optimize' at the end of the module.
5147void ASTWriter::WriteOptimizePragmaOptions(Sema &SemaRef) {
5148 RecordData Record;
5149 SourceLocation PragmaLoc = SemaRef.getOptimizeOffPragmaLocation();
5150 AddSourceLocation(Loc: PragmaLoc, Record);
5151 Stream.EmitRecord(Code: OPTIMIZE_PRAGMA_OPTIONS, Vals: Record);
5152}
5153
5154/// Write the state of 'pragma ms_struct' at the end of the module.
5155void ASTWriter::WriteMSStructPragmaOptions(Sema &SemaRef) {
5156 RecordData Record;
5157 Record.push_back(Elt: SemaRef.MSStructPragmaOn ? PMSST_ON : PMSST_OFF);
5158 Stream.EmitRecord(Code: MSSTRUCT_PRAGMA_OPTIONS, Vals: Record);
5159}
5160
5161/// Write the state of 'pragma pointers_to_members' at the end of the
5162//module.
5163void ASTWriter::WriteMSPointersToMembersPragmaOptions(Sema &SemaRef) {
5164 RecordData Record;
5165 Record.push_back(Elt: SemaRef.MSPointerToMemberRepresentationMethod);
5166 AddSourceLocation(Loc: SemaRef.ImplicitMSInheritanceAttrLoc, Record);
5167 Stream.EmitRecord(Code: POINTERS_TO_MEMBERS_PRAGMA_OPTIONS, Vals: Record);
5168}
5169
5170/// Write the state of 'pragma align/pack' at the end of the module.
5171void ASTWriter::WritePackPragmaOptions(Sema &SemaRef) {
5172 // Don't serialize pragma align/pack state for modules, since it should only
5173 // take effect on a per-submodule basis.
5174 if (WritingModule)
5175 return;
5176
5177 RecordData Record;
5178 AddAlignPackInfo(Info: SemaRef.AlignPackStack.CurrentValue, Record);
5179 AddSourceLocation(Loc: SemaRef.AlignPackStack.CurrentPragmaLocation, Record);
5180 Record.push_back(Elt: SemaRef.AlignPackStack.Stack.size());
5181 for (const auto &StackEntry : SemaRef.AlignPackStack.Stack) {
5182 AddAlignPackInfo(Info: StackEntry.Value, Record);
5183 AddSourceLocation(Loc: StackEntry.PragmaLocation, Record);
5184 AddSourceLocation(Loc: StackEntry.PragmaPushLocation, Record);
5185 AddString(Str: StackEntry.StackSlotLabel, Record);
5186 }
5187 Stream.EmitRecord(Code: ALIGN_PACK_PRAGMA_OPTIONS, Vals: Record);
5188}
5189
5190/// Write the state of 'pragma float_control' at the end of the module.
5191void ASTWriter::WriteFloatControlPragmaOptions(Sema &SemaRef) {
5192 // Don't serialize pragma float_control state for modules,
5193 // since it should only take effect on a per-submodule basis.
5194 if (WritingModule)
5195 return;
5196
5197 RecordData Record;
5198 Record.push_back(Elt: SemaRef.FpPragmaStack.CurrentValue.getAsOpaqueInt());
5199 AddSourceLocation(Loc: SemaRef.FpPragmaStack.CurrentPragmaLocation, Record);
5200 Record.push_back(Elt: SemaRef.FpPragmaStack.Stack.size());
5201 for (const auto &StackEntry : SemaRef.FpPragmaStack.Stack) {
5202 Record.push_back(Elt: StackEntry.Value.getAsOpaqueInt());
5203 AddSourceLocation(Loc: StackEntry.PragmaLocation, Record);
5204 AddSourceLocation(Loc: StackEntry.PragmaPushLocation, Record);
5205 AddString(Str: StackEntry.StackSlotLabel, Record);
5206 }
5207 Stream.EmitRecord(Code: FLOAT_CONTROL_PRAGMA_OPTIONS, Vals: Record);
5208}
5209
5210/// Write Sema's collected list of declarations with unverified effects.
5211void ASTWriter::WriteDeclsWithEffectsToVerify(Sema &SemaRef) {
5212 if (SemaRef.DeclsWithEffectsToVerify.empty())
5213 return;
5214 RecordData Record;
5215 for (const auto *D : SemaRef.DeclsWithEffectsToVerify) {
5216 AddDeclRef(D, Record);
5217 }
5218 Stream.EmitRecord(Code: DECLS_WITH_EFFECTS_TO_VERIFY, Vals: Record);
5219}
5220
5221void ASTWriter::WriteModuleFileExtension(Sema &SemaRef,
5222 ModuleFileExtensionWriter &Writer) {
5223 // Enter the extension block.
5224 Stream.EnterSubblock(BlockID: EXTENSION_BLOCK_ID, CodeLen: 4);
5225
5226 // Emit the metadata record abbreviation.
5227 auto Abv = std::make_shared<llvm::BitCodeAbbrev>();
5228 Abv->Add(OpInfo: llvm::BitCodeAbbrevOp(EXTENSION_METADATA));
5229 Abv->Add(OpInfo: llvm::BitCodeAbbrevOp(llvm::BitCodeAbbrevOp::VBR, 6));
5230 Abv->Add(OpInfo: llvm::BitCodeAbbrevOp(llvm::BitCodeAbbrevOp::VBR, 6));
5231 Abv->Add(OpInfo: llvm::BitCodeAbbrevOp(llvm::BitCodeAbbrevOp::VBR, 6));
5232 Abv->Add(OpInfo: llvm::BitCodeAbbrevOp(llvm::BitCodeAbbrevOp::VBR, 6));
5233 Abv->Add(OpInfo: llvm::BitCodeAbbrevOp(llvm::BitCodeAbbrevOp::Blob));
5234 unsigned Abbrev = Stream.EmitAbbrev(Abbv: std::move(Abv));
5235
5236 // Emit the metadata record.
5237 RecordData Record;
5238 auto Metadata = Writer.getExtension()->getExtensionMetadata();
5239 Record.push_back(Elt: EXTENSION_METADATA);
5240 Record.push_back(Elt: Metadata.MajorVersion);
5241 Record.push_back(Elt: Metadata.MinorVersion);
5242 Record.push_back(Elt: Metadata.BlockName.size());
5243 Record.push_back(Elt: Metadata.UserInfo.size());
5244 SmallString<64> Buffer;
5245 Buffer += Metadata.BlockName;
5246 Buffer += Metadata.UserInfo;
5247 Stream.EmitRecordWithBlob(Abbrev, Vals: Record, Blob: Buffer);
5248
5249 // Emit the contents of the extension block.
5250 Writer.writeExtensionContents(SemaRef, Stream);
5251
5252 // Exit the extension block.
5253 Stream.ExitBlock();
5254}
5255
5256void ASTWriter::WriteRISCVIntrinsicPragmas(Sema &SemaRef) {
5257 RecordData Record;
5258 // Need to update this when new intrinsic class is added.
5259 Record.push_back(/*size*/ Elt: 3);
5260 Record.push_back(Elt: SemaRef.RISCV().DeclareRVVBuiltins);
5261 Record.push_back(Elt: SemaRef.RISCV().DeclareSiFiveVectorBuiltins);
5262 Record.push_back(Elt: SemaRef.RISCV().DeclareAndesVectorBuiltins);
5263 Stream.EmitRecord(Code: RISCV_VECTOR_INTRINSICS_PRAGMA, Vals: Record);
5264}
5265
5266//===----------------------------------------------------------------------===//
5267// General Serialization Routines
5268//===----------------------------------------------------------------------===//
5269
5270void ASTRecordWriter::AddAttr(const Attr *A) {
5271 auto &Record = *this;
5272 // FIXME: Clang can't handle the serialization/deserialization of
5273 // preferred_name properly now. See
5274 // https://github.com/llvm/llvm-project/issues/56490 for example.
5275 if (!A ||
5276 (isa<PreferredNameAttr>(Val: A) && (Writer->isWritingStdCXXNamedModules() ||
5277 Writer->isWritingStdCXXHeaderUnit())))
5278 return Record.push_back(N: 0);
5279
5280 Record.push_back(N: A->getKind() + 1); // FIXME: stable encoding, target attrs
5281
5282 Record.AddIdentifierRef(II: A->getAttrName());
5283 Record.AddIdentifierRef(II: A->getScopeName());
5284 Record.AddSourceRange(Range: A->getRange());
5285 Record.AddSourceLocation(Loc: A->getScopeLoc());
5286 Record.push_back(N: A->getParsedKind());
5287 Record.push_back(N: A->getSyntax());
5288 Record.push_back(N: A->getAttributeSpellingListIndexRaw());
5289 Record.push_back(N: A->isRegularKeywordAttribute());
5290
5291#include "clang/Serialization/AttrPCHWrite.inc"
5292}
5293
5294/// Emit the list of attributes to the specified record.
5295void ASTRecordWriter::AddAttributes(ArrayRef<const Attr *> Attrs) {
5296 push_back(N: Attrs.size());
5297 for (const auto *A : Attrs)
5298 AddAttr(A);
5299}
5300
5301void ASTWriter::AddToken(const Token &Tok, RecordDataImpl &Record) {
5302 AddSourceLocation(Loc: Tok.getLocation(), Record);
5303 // FIXME: Should translate token kind to a stable encoding.
5304 Record.push_back(Elt: Tok.getKind());
5305 // FIXME: Should translate token flags to a stable encoding.
5306 Record.push_back(Elt: Tok.getFlags());
5307
5308 if (Tok.isAnnotation()) {
5309 AddSourceLocation(Loc: Tok.getAnnotationEndLoc(), Record);
5310 switch (Tok.getKind()) {
5311 case tok::annot_pragma_loop_hint: {
5312 auto *Info = static_cast<PragmaLoopHintInfo *>(Tok.getAnnotationValue());
5313 AddToken(Tok: Info->PragmaName, Record);
5314 AddToken(Tok: Info->Option, Record);
5315 Record.push_back(Elt: Info->Toks.size());
5316 for (const auto &T : Info->Toks)
5317 AddToken(Tok: T, Record);
5318 break;
5319 }
5320 case tok::annot_pragma_pack: {
5321 auto *Info =
5322 static_cast<Sema::PragmaPackInfo *>(Tok.getAnnotationValue());
5323 Record.push_back(Elt: static_cast<unsigned>(Info->Action));
5324 AddString(Str: Info->SlotLabel, Record);
5325 AddToken(Tok: Info->Alignment, Record);
5326 break;
5327 }
5328 // Some annotation tokens do not use the PtrData field.
5329 case tok::annot_pragma_openmp:
5330 case tok::annot_pragma_openmp_end:
5331 case tok::annot_pragma_unused:
5332 case tok::annot_pragma_openacc:
5333 case tok::annot_pragma_openacc_end:
5334 case tok::annot_repl_input_end:
5335 break;
5336 default:
5337 llvm_unreachable("missing serialization code for annotation token");
5338 }
5339 } else {
5340 Record.push_back(Elt: Tok.getLength());
5341 // FIXME: When reading literal tokens, reconstruct the literal pointer if it
5342 // is needed.
5343 AddIdentifierRef(II: Tok.getIdentifierInfo(), Record);
5344 }
5345}
5346
5347void ASTWriter::AddString(StringRef Str, RecordDataImpl &Record) {
5348 Record.push_back(Elt: Str.size());
5349 llvm::append_range(C&: Record, R&: Str);
5350}
5351
5352void ASTWriter::AddStringBlob(StringRef Str, RecordDataImpl &Record,
5353 SmallVectorImpl<char> &Blob) {
5354 Record.push_back(Elt: Str.size());
5355 llvm::append_range(C&: Blob, R&: Str);
5356}
5357
5358bool ASTWriter::PreparePathForOutput(SmallVectorImpl<char> &Path) {
5359 assert(WritingAST && "can't prepare path for output when not writing AST");
5360
5361 // Leave special file names as they are.
5362 StringRef PathStr(Path.data(), Path.size());
5363 if (PathStr == "<built-in>" || PathStr == "<command line>")
5364 return false;
5365
5366 bool Changed = cleanPathForOutput(FileMgr&: PP->getFileManager(), Path);
5367
5368 // Remove a prefix to make the path relative, if relevant.
5369 const char *PathBegin = Path.data();
5370 const char *PathPtr =
5371 adjustFilenameForRelocatableAST(Filename: PathBegin, BaseDir: BaseDirectory);
5372 if (PathPtr != PathBegin) {
5373 Path.erase(CS: Path.begin(), CE: Path.begin() + (PathPtr - PathBegin));
5374 Changed = true;
5375 }
5376
5377 return Changed;
5378}
5379
5380void ASTWriter::AddPath(StringRef Path, RecordDataImpl &Record) {
5381 SmallString<128> FilePath(Path);
5382 PreparePathForOutput(Path&: FilePath);
5383 AddString(Str: FilePath, Record);
5384}
5385
5386void ASTWriter::AddPathBlob(StringRef Path, RecordDataImpl &Record,
5387 SmallVectorImpl<char> &Blob) {
5388 SmallString<128> FilePath(Path);
5389 PreparePathForOutput(Path&: FilePath);
5390 AddStringBlob(Str: FilePath, Record, Blob);
5391}
5392
5393void ASTWriter::EmitRecordWithPath(unsigned Abbrev, RecordDataRef Record,
5394 StringRef Path) {
5395 SmallString<128> FilePath(Path);
5396 PreparePathForOutput(Path&: FilePath);
5397 Stream.EmitRecordWithBlob(Abbrev, Vals: Record, Blob: FilePath);
5398}
5399
5400void ASTWriter::AddVersionTuple(const VersionTuple &Version,
5401 RecordDataImpl &Record) {
5402 Record.push_back(Elt: Version.getMajor());
5403 if (std::optional<unsigned> Minor = Version.getMinor())
5404 Record.push_back(Elt: *Minor + 1);
5405 else
5406 Record.push_back(Elt: 0);
5407 if (std::optional<unsigned> Subminor = Version.getSubminor())
5408 Record.push_back(Elt: *Subminor + 1);
5409 else
5410 Record.push_back(Elt: 0);
5411}
5412
5413/// Note that the identifier II occurs at the given offset
5414/// within the identifier table.
5415void ASTWriter::SetIdentifierOffset(const IdentifierInfo *II, uint32_t Offset) {
5416 IdentifierID ID = IdentifierIDs[II];
5417 // Only store offsets new to this AST file. Other identifier names are looked
5418 // up earlier in the chain and thus don't need an offset.
5419 if (!isLocalIdentifierID(ID))
5420 return;
5421
5422 // For local identifiers, the module file index must be 0.
5423
5424 assert(ID != 0);
5425 ID -= NUM_PREDEF_IDENT_IDS;
5426 assert(ID < IdentifierOffsets.size());
5427 IdentifierOffsets[ID] = Offset;
5428}
5429
5430/// Note that the selector Sel occurs at the given offset
5431/// within the method pool/selector table.
5432void ASTWriter::SetSelectorOffset(Selector Sel, uint32_t Offset) {
5433 unsigned ID = SelectorIDs[Sel];
5434 assert(ID && "Unknown selector");
5435 // Don't record offsets for selectors that are also available in a different
5436 // file.
5437 if (ID < FirstSelectorID)
5438 return;
5439 SelectorOffsets[ID - FirstSelectorID] = Offset;
5440}
5441
5442ASTWriter::ASTWriter(llvm::BitstreamWriter &Stream,
5443 SmallVectorImpl<char> &Buffer, ModuleCache &ModCache,
5444 const CodeGenOptions &CodeGenOpts,
5445 ArrayRef<std::shared_ptr<ModuleFileExtension>> Extensions,
5446 bool IncludeTimestamps, bool BuildingImplicitModule,
5447 bool GeneratingReducedBMI)
5448 : Stream(Stream), Buffer(Buffer), ModCache(ModCache),
5449 CodeGenOpts(CodeGenOpts), IncludeTimestamps(IncludeTimestamps),
5450 BuildingImplicitModule(BuildingImplicitModule),
5451 GeneratingReducedBMI(GeneratingReducedBMI) {
5452 for (const auto &Ext : Extensions) {
5453 if (auto Writer = Ext->createExtensionWriter(Writer&: *this))
5454 ModuleFileExtensionWriters.push_back(x: std::move(Writer));
5455 }
5456}
5457
5458ASTWriter::~ASTWriter() = default;
5459
5460const LangOptions &ASTWriter::getLangOpts() const {
5461 assert(WritingAST && "can't determine lang opts when not writing AST");
5462 return PP->getLangOpts();
5463}
5464
5465time_t ASTWriter::getTimestampForOutput(const FileEntry *E) const {
5466 return IncludeTimestamps ? E->getModificationTime() : 0;
5467}
5468
5469ASTFileSignature
5470ASTWriter::WriteAST(llvm::PointerUnion<Sema *, Preprocessor *> Subject,
5471 StringRef OutputFile, Module *WritingModule,
5472 StringRef isysroot, bool ShouldCacheASTInMemory) {
5473 llvm::TimeTraceScope scope("WriteAST", OutputFile);
5474 WritingAST = true;
5475
5476 Sema *SemaPtr = dyn_cast<Sema *>(Val&: Subject);
5477 Preprocessor &PPRef =
5478 SemaPtr ? SemaPtr->getPreprocessor() : *cast<Preprocessor *>(Val&: Subject);
5479
5480 ASTHasCompilerErrors = PPRef.getDiagnostics().hasUncompilableErrorOccurred();
5481
5482 // Emit the file header.
5483 Stream.Emit(Val: (unsigned)'C', NumBits: 8);
5484 Stream.Emit(Val: (unsigned)'P', NumBits: 8);
5485 Stream.Emit(Val: (unsigned)'C', NumBits: 8);
5486 Stream.Emit(Val: (unsigned)'H', NumBits: 8);
5487
5488 WriteBlockInfoBlock();
5489
5490 PP = &PPRef;
5491 this->WritingModule = WritingModule;
5492 ASTFileSignature Signature = WriteASTCore(SemaPtr, isysroot, WritingModule);
5493 PP = nullptr;
5494 this->WritingModule = nullptr;
5495 this->BaseDirectory.clear();
5496
5497 WritingAST = false;
5498
5499 if (ShouldCacheASTInMemory) {
5500 // Construct MemoryBuffer and update buffer manager.
5501 ModCache.getInMemoryModuleCache().addBuiltPCM(
5502 Filename: OutputFile, Buffer: llvm::MemoryBuffer::getMemBufferCopy(
5503 InputData: StringRef(Buffer.begin(), Buffer.size())));
5504 }
5505 return Signature;
5506}
5507
5508template<typename Vector>
5509static void AddLazyVectorDecls(ASTWriter &Writer, Vector &Vec) {
5510 for (typename Vector::iterator I = Vec.begin(nullptr, true), E = Vec.end();
5511 I != E; ++I) {
5512 Writer.GetDeclRef(D: *I);
5513 }
5514}
5515
5516template <typename Vector>
5517static void AddLazyVectorEmiitedDecls(ASTWriter &Writer, Vector &Vec,
5518 ASTWriter::RecordData &Record) {
5519 for (typename Vector::iterator I = Vec.begin(nullptr, true), E = Vec.end();
5520 I != E; ++I) {
5521 Writer.AddEmittedDeclRef(D: *I, Record);
5522 }
5523}
5524
5525void ASTWriter::computeNonAffectingInputFiles() {
5526 SourceManager &SrcMgr = PP->getSourceManager();
5527 unsigned N = SrcMgr.local_sloc_entry_size();
5528
5529 IsSLocAffecting.resize(N, t: true);
5530 IsSLocFileEntryAffecting.resize(N, t: true);
5531
5532 if (!WritingModule)
5533 return;
5534
5535 auto AffectingModuleMaps = GetAffectingModuleMaps(PP: *PP, RootModule: WritingModule);
5536
5537 unsigned FileIDAdjustment = 0;
5538 unsigned OffsetAdjustment = 0;
5539
5540 NonAffectingFileIDAdjustments.reserve(n: N);
5541 NonAffectingOffsetAdjustments.reserve(n: N);
5542
5543 NonAffectingFileIDAdjustments.push_back(x: FileIDAdjustment);
5544 NonAffectingOffsetAdjustments.push_back(x: OffsetAdjustment);
5545
5546 for (unsigned I = 1; I != N; ++I) {
5547 const SrcMgr::SLocEntry *SLoc = &SrcMgr.getLocalSLocEntry(Index: I);
5548 FileID FID = FileID::get(V: I);
5549 assert(&SrcMgr.getSLocEntry(FID) == SLoc);
5550
5551 if (!SLoc->isFile())
5552 continue;
5553 const SrcMgr::FileInfo &File = SLoc->getFile();
5554 const SrcMgr::ContentCache *Cache = &File.getContentCache();
5555 if (!Cache->OrigEntry)
5556 continue;
5557
5558 // Don't prune anything other than module maps.
5559 if (!isModuleMap(CK: File.getFileCharacteristic()))
5560 continue;
5561
5562 // Don't prune module maps if all are guaranteed to be affecting.
5563 if (!AffectingModuleMaps)
5564 continue;
5565
5566 // Don't prune module maps that are affecting.
5567 if (AffectingModuleMaps->DefinitionFileIDs.contains(V: FID))
5568 continue;
5569
5570 IsSLocAffecting[I] = false;
5571 IsSLocFileEntryAffecting[I] =
5572 AffectingModuleMaps->DefinitionFiles.contains(V: *Cache->OrigEntry);
5573
5574 FileIDAdjustment += 1;
5575 // Even empty files take up one element in the offset table.
5576 OffsetAdjustment += SrcMgr.getFileIDSize(FID) + 1;
5577
5578 // If the previous file was non-affecting as well, just extend its entry
5579 // with our information.
5580 if (!NonAffectingFileIDs.empty() &&
5581 NonAffectingFileIDs.back().ID == FID.ID - 1) {
5582 NonAffectingFileIDs.back() = FID;
5583 NonAffectingRanges.back().setEnd(SrcMgr.getLocForEndOfFile(FID));
5584 NonAffectingFileIDAdjustments.back() = FileIDAdjustment;
5585 NonAffectingOffsetAdjustments.back() = OffsetAdjustment;
5586 continue;
5587 }
5588
5589 NonAffectingFileIDs.push_back(x: FID);
5590 NonAffectingRanges.emplace_back(args: SrcMgr.getLocForStartOfFile(FID),
5591 args: SrcMgr.getLocForEndOfFile(FID));
5592 NonAffectingFileIDAdjustments.push_back(x: FileIDAdjustment);
5593 NonAffectingOffsetAdjustments.push_back(x: OffsetAdjustment);
5594 }
5595
5596 if (!PP->getHeaderSearchInfo().getHeaderSearchOpts().ModulesIncludeVFSUsage)
5597 return;
5598
5599 FileManager &FileMgr = PP->getFileManager();
5600 FileMgr.trackVFSUsage(Active: true);
5601 // Lookup the paths in the VFS to trigger `-ivfsoverlay` usage tracking.
5602 for (StringRef Path :
5603 PP->getHeaderSearchInfo().getHeaderSearchOpts().VFSOverlayFiles)
5604 FileMgr.getVirtualFileSystem().exists(Path);
5605 for (unsigned I = 1; I != N; ++I) {
5606 if (IsSLocAffecting[I]) {
5607 const SrcMgr::SLocEntry *SLoc = &SrcMgr.getLocalSLocEntry(Index: I);
5608 if (!SLoc->isFile())
5609 continue;
5610 const SrcMgr::FileInfo &File = SLoc->getFile();
5611 const SrcMgr::ContentCache *Cache = &File.getContentCache();
5612 if (!Cache->OrigEntry)
5613 continue;
5614 FileMgr.getVirtualFileSystem().exists(
5615 Path: Cache->OrigEntry->getNameAsRequested());
5616 }
5617 }
5618 FileMgr.trackVFSUsage(Active: false);
5619}
5620
5621void ASTWriter::PrepareWritingSpecialDecls(Sema &SemaRef) {
5622 ASTContext &Context = SemaRef.Context;
5623
5624 bool isModule = WritingModule != nullptr;
5625
5626 // Set up predefined declaration IDs.
5627 auto RegisterPredefDecl = [&] (Decl *D, PredefinedDeclIDs ID) {
5628 if (D) {
5629 assert(D->isCanonicalDecl() && "predefined decl is not canonical");
5630 DeclIDs[D] = ID;
5631 PredefinedDecls.insert(Ptr: D);
5632 }
5633 };
5634 RegisterPredefDecl(Context.getTranslationUnitDecl(),
5635 PREDEF_DECL_TRANSLATION_UNIT_ID);
5636 RegisterPredefDecl(Context.ObjCIdDecl, PREDEF_DECL_OBJC_ID_ID);
5637 RegisterPredefDecl(Context.ObjCSelDecl, PREDEF_DECL_OBJC_SEL_ID);
5638 RegisterPredefDecl(Context.ObjCClassDecl, PREDEF_DECL_OBJC_CLASS_ID);
5639 RegisterPredefDecl(Context.ObjCProtocolClassDecl,
5640 PREDEF_DECL_OBJC_PROTOCOL_ID);
5641 RegisterPredefDecl(Context.Int128Decl, PREDEF_DECL_INT_128_ID);
5642 RegisterPredefDecl(Context.UInt128Decl, PREDEF_DECL_UNSIGNED_INT_128_ID);
5643 RegisterPredefDecl(Context.ObjCInstanceTypeDecl,
5644 PREDEF_DECL_OBJC_INSTANCETYPE_ID);
5645 RegisterPredefDecl(Context.BuiltinVaListDecl, PREDEF_DECL_BUILTIN_VA_LIST_ID);
5646 RegisterPredefDecl(Context.VaListTagDecl, PREDEF_DECL_VA_LIST_TAG);
5647 RegisterPredefDecl(Context.BuiltinMSVaListDecl,
5648 PREDEF_DECL_BUILTIN_MS_VA_LIST_ID);
5649 RegisterPredefDecl(Context.MSGuidTagDecl,
5650 PREDEF_DECL_BUILTIN_MS_GUID_ID);
5651 RegisterPredefDecl(Context.MSTypeInfoTagDecl,
5652 PREDEF_DECL_BUILTIN_MS_TYPE_INFO_TAG_ID);
5653 RegisterPredefDecl(Context.ExternCContext, PREDEF_DECL_EXTERN_C_CONTEXT_ID);
5654 RegisterPredefDecl(Context.CFConstantStringTypeDecl,
5655 PREDEF_DECL_CF_CONSTANT_STRING_ID);
5656 RegisterPredefDecl(Context.CFConstantStringTagDecl,
5657 PREDEF_DECL_CF_CONSTANT_STRING_TAG_ID);
5658#define BuiltinTemplate(BTName) \
5659 RegisterPredefDecl(Context.Decl##BTName, PREDEF_DECL##BTName##_ID);
5660#include "clang/Basic/BuiltinTemplates.inc"
5661
5662 const TranslationUnitDecl *TU = Context.getTranslationUnitDecl();
5663
5664 // Force all top level declarations to be emitted.
5665 //
5666 // We start emitting top level declarations from the module purview to
5667 // implement the eliding unreachable declaration feature.
5668 for (const auto *D : TU->noload_decls()) {
5669 if (D->isFromASTFile())
5670 continue;
5671
5672 if (GeneratingReducedBMI) {
5673 if (D->isFromExplicitGlobalModule())
5674 continue;
5675
5676 // Don't force emitting static entities.
5677 //
5678 // Technically, all static entities shouldn't be in reduced BMI. The
5679 // language also specifies that the program exposes TU-local entities
5680 // is ill-formed. However, in practice, there are a lot of projects
5681 // uses `static inline` in the headers. So we can't get rid of all
5682 // static entities in reduced BMI now.
5683 if (IsInternalDeclFromFileContext(D))
5684 continue;
5685 }
5686
5687 // If we're writing C++ named modules, don't emit declarations which are
5688 // not from modules by default. They may be built in declarations (be
5689 // handled above) or implcit declarations (see the implementation of
5690 // `Sema::Initialize()` for example).
5691 if (isWritingStdCXXNamedModules() && !D->getOwningModule() &&
5692 D->isImplicit())
5693 continue;
5694
5695 GetDeclRef(D);
5696 }
5697
5698 if (GeneratingReducedBMI)
5699 return;
5700
5701 // Writing all of the tentative definitions in this file, in
5702 // TentativeDefinitions order. Generally, this record will be empty for
5703 // headers.
5704 AddLazyVectorDecls(Writer&: *this, Vec&: SemaRef.TentativeDefinitions);
5705
5706 // Writing all of the file scoped decls in this file.
5707 if (!isModule)
5708 AddLazyVectorDecls(Writer&: *this, Vec&: SemaRef.UnusedFileScopedDecls);
5709
5710 // Writing all of the delegating constructors we still need
5711 // to resolve.
5712 if (!isModule)
5713 AddLazyVectorDecls(Writer&: *this, Vec&: SemaRef.DelegatingCtorDecls);
5714
5715 // Writing all of the ext_vector declarations.
5716 AddLazyVectorDecls(Writer&: *this, Vec&: SemaRef.ExtVectorDecls);
5717
5718 // Writing all of the VTable uses information.
5719 if (!SemaRef.VTableUses.empty())
5720 for (unsigned I = 0, N = SemaRef.VTableUses.size(); I != N; ++I)
5721 GetDeclRef(D: SemaRef.VTableUses[I].first);
5722
5723 // Writing all of the UnusedLocalTypedefNameCandidates.
5724 for (const TypedefNameDecl *TD : SemaRef.UnusedLocalTypedefNameCandidates)
5725 GetDeclRef(D: TD);
5726
5727 // Writing all of pending implicit instantiations.
5728 for (const auto &I : SemaRef.PendingInstantiations)
5729 GetDeclRef(D: I.first);
5730 assert(SemaRef.PendingLocalImplicitInstantiations.empty() &&
5731 "There are local ones at end of translation unit!");
5732
5733 // Writing some declaration references.
5734 if (SemaRef.StdNamespace || SemaRef.StdBadAlloc || SemaRef.StdAlignValT) {
5735 GetDeclRef(D: SemaRef.getStdNamespace());
5736 GetDeclRef(D: SemaRef.getStdBadAlloc());
5737 GetDeclRef(D: SemaRef.getStdAlignValT());
5738 }
5739
5740 if (Context.getcudaConfigureCallDecl() ||
5741 Context.getcudaGetParameterBufferDecl() ||
5742 Context.getcudaLaunchDeviceDecl()) {
5743 GetDeclRef(D: Context.getcudaConfigureCallDecl());
5744 GetDeclRef(D: Context.getcudaGetParameterBufferDecl());
5745 GetDeclRef(D: Context.getcudaLaunchDeviceDecl());
5746 }
5747
5748 // Writing all of the known namespaces.
5749 for (const auto &I : SemaRef.KnownNamespaces)
5750 if (!I.second)
5751 GetDeclRef(D: I.first);
5752
5753 // Writing all used, undefined objects that require definitions.
5754 SmallVector<std::pair<NamedDecl *, SourceLocation>, 16> Undefined;
5755 SemaRef.getUndefinedButUsed(Undefined);
5756 for (const auto &I : Undefined)
5757 GetDeclRef(D: I.first);
5758
5759 // Writing all delete-expressions that we would like to
5760 // analyze later in AST.
5761 if (!isModule)
5762 for (const auto &DeleteExprsInfo :
5763 SemaRef.getMismatchingDeleteExpressions())
5764 GetDeclRef(D: DeleteExprsInfo.first);
5765
5766 // Make sure visible decls, added to DeclContexts previously loaded from
5767 // an AST file, are registered for serialization. Likewise for template
5768 // specializations added to imported templates.
5769 for (const auto *I : DeclsToEmitEvenIfUnreferenced)
5770 GetDeclRef(D: I);
5771 DeclsToEmitEvenIfUnreferenced.clear();
5772
5773 // Make sure all decls associated with an identifier are registered for
5774 // serialization, if we're storing decls with identifiers.
5775 if (!WritingModule || !getLangOpts().CPlusPlus) {
5776 llvm::SmallVector<const IdentifierInfo*, 256> IIs;
5777 for (const auto &ID : SemaRef.PP.getIdentifierTable()) {
5778 const IdentifierInfo *II = ID.second;
5779 if (!Chain || !II->isFromAST() || II->hasChangedSinceDeserialization() ||
5780 II->hasFETokenInfoChangedSinceDeserialization())
5781 IIs.push_back(Elt: II);
5782 }
5783 // Sort the identifiers to visit based on their name.
5784 llvm::sort(C&: IIs, Comp: llvm::deref<std::less<>>());
5785 const LangOptions &LangOpts = getLangOpts();
5786 for (const IdentifierInfo *II : IIs)
5787 for (NamedDecl *D : SemaRef.IdResolver.decls(Name: II))
5788 GetDeclRef(D: getDeclForLocalLookup(LangOpts, D));
5789 }
5790
5791 // Write all of the DeclsToCheckForDeferredDiags.
5792 for (auto *D : SemaRef.DeclsToCheckForDeferredDiags)
5793 GetDeclRef(D);
5794
5795 // Write all classes that need to emit the vtable definitions if required.
5796 if (isWritingStdCXXNamedModules())
5797 for (CXXRecordDecl *RD : PendingEmittingVTables)
5798 GetDeclRef(D: RD);
5799 else
5800 PendingEmittingVTables.clear();
5801}
5802
5803void ASTWriter::WriteSpecialDeclRecords(Sema &SemaRef) {
5804 ASTContext &Context = SemaRef.Context;
5805
5806 bool isModule = WritingModule != nullptr;
5807
5808 // Write the record containing external, unnamed definitions.
5809 if (!EagerlyDeserializedDecls.empty())
5810 Stream.EmitRecord(Code: EAGERLY_DESERIALIZED_DECLS, Vals: EagerlyDeserializedDecls);
5811
5812 if (!ModularCodegenDecls.empty())
5813 Stream.EmitRecord(Code: MODULAR_CODEGEN_DECLS, Vals: ModularCodegenDecls);
5814
5815 // Write the record containing tentative definitions.
5816 RecordData TentativeDefinitions;
5817 AddLazyVectorEmiitedDecls(Writer&: *this, Vec&: SemaRef.TentativeDefinitions,
5818 Record&: TentativeDefinitions);
5819 if (!TentativeDefinitions.empty())
5820 Stream.EmitRecord(Code: TENTATIVE_DEFINITIONS, Vals: TentativeDefinitions);
5821
5822 // Write the record containing unused file scoped decls.
5823 RecordData UnusedFileScopedDecls;
5824 if (!isModule)
5825 AddLazyVectorEmiitedDecls(Writer&: *this, Vec&: SemaRef.UnusedFileScopedDecls,
5826 Record&: UnusedFileScopedDecls);
5827 if (!UnusedFileScopedDecls.empty())
5828 Stream.EmitRecord(Code: UNUSED_FILESCOPED_DECLS, Vals: UnusedFileScopedDecls);
5829
5830 // Write the record containing ext_vector type names.
5831 RecordData ExtVectorDecls;
5832 AddLazyVectorEmiitedDecls(Writer&: *this, Vec&: SemaRef.ExtVectorDecls, Record&: ExtVectorDecls);
5833 if (!ExtVectorDecls.empty())
5834 Stream.EmitRecord(Code: EXT_VECTOR_DECLS, Vals: ExtVectorDecls);
5835
5836 // Write the record containing VTable uses information.
5837 RecordData VTableUses;
5838 if (!SemaRef.VTableUses.empty()) {
5839 for (unsigned I = 0, N = SemaRef.VTableUses.size(); I != N; ++I) {
5840 CXXRecordDecl *D = SemaRef.VTableUses[I].first;
5841 if (!wasDeclEmitted(D))
5842 continue;
5843
5844 AddDeclRef(D, Record&: VTableUses);
5845 AddSourceLocation(Loc: SemaRef.VTableUses[I].second, Record&: VTableUses);
5846 VTableUses.push_back(Elt: SemaRef.VTablesUsed[D]);
5847 }
5848 Stream.EmitRecord(Code: VTABLE_USES, Vals: VTableUses);
5849 }
5850
5851 // Write the record containing potentially unused local typedefs.
5852 RecordData UnusedLocalTypedefNameCandidates;
5853 for (const TypedefNameDecl *TD : SemaRef.UnusedLocalTypedefNameCandidates)
5854 AddEmittedDeclRef(D: TD, Record&: UnusedLocalTypedefNameCandidates);
5855 if (!UnusedLocalTypedefNameCandidates.empty())
5856 Stream.EmitRecord(Code: UNUSED_LOCAL_TYPEDEF_NAME_CANDIDATES,
5857 Vals: UnusedLocalTypedefNameCandidates);
5858
5859 if (!GeneratingReducedBMI) {
5860 // Write the record containing pending implicit instantiations.
5861 RecordData PendingInstantiations;
5862 for (const auto &I : SemaRef.PendingInstantiations) {
5863 if (!wasDeclEmitted(D: I.first))
5864 continue;
5865
5866 AddDeclRef(D: I.first, Record&: PendingInstantiations);
5867 AddSourceLocation(Loc: I.second, Record&: PendingInstantiations);
5868 }
5869 if (!PendingInstantiations.empty())
5870 Stream.EmitRecord(Code: PENDING_IMPLICIT_INSTANTIATIONS, Vals: PendingInstantiations);
5871 }
5872
5873 auto AddEmittedDeclRefOrZero = [this](RecordData &Refs, Decl *D) {
5874 if (!D || !wasDeclEmitted(D))
5875 Refs.push_back(Elt: 0);
5876 else
5877 AddDeclRef(D, Record&: Refs);
5878 };
5879
5880 // Write the record containing declaration references of Sema.
5881 RecordData SemaDeclRefs;
5882 if (SemaRef.StdNamespace || SemaRef.StdBadAlloc || SemaRef.StdAlignValT) {
5883 AddEmittedDeclRefOrZero(SemaDeclRefs, SemaRef.getStdNamespace());
5884 AddEmittedDeclRefOrZero(SemaDeclRefs, SemaRef.getStdBadAlloc());
5885 AddEmittedDeclRefOrZero(SemaDeclRefs, SemaRef.getStdAlignValT());
5886 }
5887 if (!SemaDeclRefs.empty())
5888 Stream.EmitRecord(Code: SEMA_DECL_REFS, Vals: SemaDeclRefs);
5889
5890 // Write the record containing decls to be checked for deferred diags.
5891 RecordData DeclsToCheckForDeferredDiags;
5892 for (auto *D : SemaRef.DeclsToCheckForDeferredDiags)
5893 if (wasDeclEmitted(D))
5894 AddDeclRef(D, Record&: DeclsToCheckForDeferredDiags);
5895 if (!DeclsToCheckForDeferredDiags.empty())
5896 Stream.EmitRecord(Code: DECLS_TO_CHECK_FOR_DEFERRED_DIAGS,
5897 Vals: DeclsToCheckForDeferredDiags);
5898
5899 // Write the record containing CUDA-specific declaration references.
5900 RecordData CUDASpecialDeclRefs;
5901 if (auto *CudaCallDecl = Context.getcudaConfigureCallDecl(),
5902 *CudaGetParamDecl = Context.getcudaGetParameterBufferDecl(),
5903 *CudaLaunchDecl = Context.getcudaLaunchDeviceDecl();
5904 CudaCallDecl || CudaGetParamDecl || CudaLaunchDecl) {
5905 AddEmittedDeclRefOrZero(CUDASpecialDeclRefs, CudaCallDecl);
5906 AddEmittedDeclRefOrZero(CUDASpecialDeclRefs, CudaGetParamDecl);
5907 AddEmittedDeclRefOrZero(CUDASpecialDeclRefs, CudaLaunchDecl);
5908 Stream.EmitRecord(Code: CUDA_SPECIAL_DECL_REFS, Vals: CUDASpecialDeclRefs);
5909 }
5910
5911 // Write the delegating constructors.
5912 RecordData DelegatingCtorDecls;
5913 if (!isModule)
5914 AddLazyVectorEmiitedDecls(Writer&: *this, Vec&: SemaRef.DelegatingCtorDecls,
5915 Record&: DelegatingCtorDecls);
5916 if (!DelegatingCtorDecls.empty())
5917 Stream.EmitRecord(Code: DELEGATING_CTORS, Vals: DelegatingCtorDecls);
5918
5919 // Write the known namespaces.
5920 RecordData KnownNamespaces;
5921 for (const auto &I : SemaRef.KnownNamespaces) {
5922 if (!I.second && wasDeclEmitted(D: I.first))
5923 AddDeclRef(D: I.first, Record&: KnownNamespaces);
5924 }
5925 if (!KnownNamespaces.empty())
5926 Stream.EmitRecord(Code: KNOWN_NAMESPACES, Vals: KnownNamespaces);
5927
5928 // Write the undefined internal functions and variables, and inline functions.
5929 RecordData UndefinedButUsed;
5930 SmallVector<std::pair<NamedDecl *, SourceLocation>, 16> Undefined;
5931 SemaRef.getUndefinedButUsed(Undefined);
5932 for (const auto &I : Undefined) {
5933 if (!wasDeclEmitted(D: I.first))
5934 continue;
5935
5936 AddDeclRef(D: I.first, Record&: UndefinedButUsed);
5937 AddSourceLocation(Loc: I.second, Record&: UndefinedButUsed);
5938 }
5939 if (!UndefinedButUsed.empty())
5940 Stream.EmitRecord(Code: UNDEFINED_BUT_USED, Vals: UndefinedButUsed);
5941
5942 // Write all delete-expressions that we would like to
5943 // analyze later in AST.
5944 RecordData DeleteExprsToAnalyze;
5945 if (!isModule) {
5946 for (const auto &DeleteExprsInfo :
5947 SemaRef.getMismatchingDeleteExpressions()) {
5948 if (!wasDeclEmitted(D: DeleteExprsInfo.first))
5949 continue;
5950
5951 AddDeclRef(D: DeleteExprsInfo.first, Record&: DeleteExprsToAnalyze);
5952 DeleteExprsToAnalyze.push_back(Elt: DeleteExprsInfo.second.size());
5953 for (const auto &DeleteLoc : DeleteExprsInfo.second) {
5954 AddSourceLocation(Loc: DeleteLoc.first, Record&: DeleteExprsToAnalyze);
5955 DeleteExprsToAnalyze.push_back(Elt: DeleteLoc.second);
5956 }
5957 }
5958 }
5959 if (!DeleteExprsToAnalyze.empty())
5960 Stream.EmitRecord(Code: DELETE_EXPRS_TO_ANALYZE, Vals: DeleteExprsToAnalyze);
5961
5962 RecordData VTablesToEmit;
5963 for (CXXRecordDecl *RD : PendingEmittingVTables) {
5964 if (!wasDeclEmitted(D: RD))
5965 continue;
5966
5967 AddDeclRef(D: RD, Record&: VTablesToEmit);
5968 }
5969
5970 if (!VTablesToEmit.empty())
5971 Stream.EmitRecord(Code: VTABLES_TO_EMIT, Vals: VTablesToEmit);
5972}
5973
5974ASTFileSignature ASTWriter::WriteASTCore(Sema *SemaPtr, StringRef isysroot,
5975 Module *WritingModule) {
5976 using namespace llvm;
5977
5978 bool isModule = WritingModule != nullptr;
5979
5980 // Make sure that the AST reader knows to finalize itself.
5981 if (Chain)
5982 Chain->finalizeForWriting();
5983
5984 // This needs to be done very early, since everything that writes
5985 // SourceLocations or FileIDs depends on it.
5986 computeNonAffectingInputFiles();
5987
5988 writeUnhashedControlBlock(PP&: *PP);
5989
5990 // Don't reuse type ID and Identifier ID from readers for C++ standard named
5991 // modules since we want to support no-transitive-change model for named
5992 // modules. The theory for no-transitive-change model is,
5993 // for a user of a named module, the user can only access the indirectly
5994 // imported decls via the directly imported module. So that it is possible to
5995 // control what matters to the users when writing the module. It would be
5996 // problematic if the users can reuse the type IDs and identifier IDs from
5997 // indirectly imported modules arbitrarily. So we choose to clear these ID
5998 // here.
5999 if (isWritingStdCXXNamedModules()) {
6000 TypeIdxs.clear();
6001 IdentifierIDs.clear();
6002 }
6003
6004 // Look for any identifiers that were named while processing the
6005 // headers, but are otherwise not needed. We add these to the hash
6006 // table to enable checking of the predefines buffer in the case
6007 // where the user adds new macro definitions when building the AST
6008 // file.
6009 //
6010 // We do this before emitting any Decl and Types to make sure the
6011 // Identifier ID is stable.
6012 SmallVector<const IdentifierInfo *, 128> IIs;
6013 for (const auto &ID : PP->getIdentifierTable())
6014 if (IsInterestingNonMacroIdentifier(II: ID.second, Writer&: *this))
6015 IIs.push_back(Elt: ID.second);
6016 // Sort the identifiers lexicographically before getting the references so
6017 // that their order is stable.
6018 llvm::sort(C&: IIs, Comp: llvm::deref<std::less<>>());
6019 for (const IdentifierInfo *II : IIs)
6020 getIdentifierRef(II);
6021
6022 // Write the set of weak, undeclared identifiers. We always write the
6023 // entire table, since later PCH files in a PCH chain are only interested in
6024 // the results at the end of the chain.
6025 RecordData WeakUndeclaredIdentifiers;
6026 if (SemaPtr) {
6027 for (const auto &WeakUndeclaredIdentifierList :
6028 SemaPtr->WeakUndeclaredIdentifiers) {
6029 const IdentifierInfo *const II = WeakUndeclaredIdentifierList.first;
6030 for (const auto &WI : WeakUndeclaredIdentifierList.second) {
6031 AddIdentifierRef(II, Record&: WeakUndeclaredIdentifiers);
6032 AddIdentifierRef(II: WI.getAlias(), Record&: WeakUndeclaredIdentifiers);
6033 AddSourceLocation(Loc: WI.getLocation(), Record&: WeakUndeclaredIdentifiers);
6034 }
6035 }
6036 }
6037
6038 // Form the record of special types.
6039 RecordData SpecialTypes;
6040 if (SemaPtr) {
6041 ASTContext &Context = SemaPtr->Context;
6042 AddTypeRef(Context, T: Context.getRawCFConstantStringType(), Record&: SpecialTypes);
6043 AddTypeRef(Context, T: Context.getFILEType(), Record&: SpecialTypes);
6044 AddTypeRef(Context, T: Context.getjmp_bufType(), Record&: SpecialTypes);
6045 AddTypeRef(Context, T: Context.getsigjmp_bufType(), Record&: SpecialTypes);
6046 AddTypeRef(Context, T: Context.ObjCIdRedefinitionType, Record&: SpecialTypes);
6047 AddTypeRef(Context, T: Context.ObjCClassRedefinitionType, Record&: SpecialTypes);
6048 AddTypeRef(Context, T: Context.ObjCSelRedefinitionType, Record&: SpecialTypes);
6049 AddTypeRef(Context, T: Context.getucontext_tType(), Record&: SpecialTypes);
6050 }
6051
6052 if (SemaPtr)
6053 PrepareWritingSpecialDecls(SemaRef&: *SemaPtr);
6054
6055 // Write the control block
6056 WriteControlBlock(PP&: *PP, isysroot);
6057
6058 // Write the remaining AST contents.
6059 Stream.FlushToWord();
6060 ASTBlockRange.first = Stream.GetCurrentBitNo() >> 3;
6061 Stream.EnterSubblock(BlockID: AST_BLOCK_ID, CodeLen: 5);
6062 ASTBlockStartOffset = Stream.GetCurrentBitNo();
6063
6064 // This is so that older clang versions, before the introduction
6065 // of the control block, can read and reject the newer PCH format.
6066 {
6067 RecordData Record = {VERSION_MAJOR};
6068 Stream.EmitRecord(Code: METADATA_OLD_FORMAT, Vals: Record);
6069 }
6070
6071 // For method pool in the module, if it contains an entry for a selector,
6072 // the entry should be complete, containing everything introduced by that
6073 // module and all modules it imports. It's possible that the entry is out of
6074 // date, so we need to pull in the new content here.
6075
6076 // It's possible that updateOutOfDateSelector can update SelectorIDs. To be
6077 // safe, we copy all selectors out.
6078 if (SemaPtr) {
6079 llvm::SmallVector<Selector, 256> AllSelectors;
6080 for (auto &SelectorAndID : SelectorIDs)
6081 AllSelectors.push_back(Elt: SelectorAndID.first);
6082 for (auto &Selector : AllSelectors)
6083 SemaPtr->ObjC().updateOutOfDateSelector(Sel: Selector);
6084 }
6085
6086 if (Chain) {
6087 // Write the mapping information describing our module dependencies and how
6088 // each of those modules were mapped into our own offset/ID space, so that
6089 // the reader can build the appropriate mapping to its own offset/ID space.
6090 // The map consists solely of a blob with the following format:
6091 // *(module-kind:i8
6092 // module-name-len:i16 module-name:len*i8
6093 // source-location-offset:i32
6094 // identifier-id:i32
6095 // preprocessed-entity-id:i32
6096 // macro-definition-id:i32
6097 // submodule-id:i32
6098 // selector-id:i32
6099 // declaration-id:i32
6100 // c++-base-specifiers-id:i32
6101 // type-id:i32)
6102 //
6103 // module-kind is the ModuleKind enum value. If it is MK_PrebuiltModule,
6104 // MK_ExplicitModule or MK_ImplicitModule, then the module-name is the
6105 // module name. Otherwise, it is the module file name.
6106 auto Abbrev = std::make_shared<BitCodeAbbrev>();
6107 Abbrev->Add(OpInfo: BitCodeAbbrevOp(MODULE_OFFSET_MAP));
6108 Abbrev->Add(OpInfo: BitCodeAbbrevOp(BitCodeAbbrevOp::Blob));
6109 unsigned ModuleOffsetMapAbbrev = Stream.EmitAbbrev(Abbv: std::move(Abbrev));
6110 SmallString<2048> Buffer;
6111 {
6112 llvm::raw_svector_ostream Out(Buffer);
6113 for (ModuleFile &M : Chain->ModuleMgr) {
6114 using namespace llvm::support;
6115
6116 endian::Writer LE(Out, llvm::endianness::little);
6117 LE.write<uint8_t>(Val: static_cast<uint8_t>(M.Kind));
6118 StringRef Name = M.isModule() ? M.ModuleName : M.FileName;
6119 LE.write<uint16_t>(Val: Name.size());
6120 Out.write(Ptr: Name.data(), Size: Name.size());
6121
6122 // Note: if a base ID was uint max, it would not be possible to load
6123 // another module after it or have more than one entity inside it.
6124 uint32_t None = std::numeric_limits<uint32_t>::max();
6125
6126 auto writeBaseIDOrNone = [&](auto BaseID, bool ShouldWrite) {
6127 assert(BaseID < std::numeric_limits<uint32_t>::max() && "base id too high");
6128 if (ShouldWrite)
6129 LE.write<uint32_t>(BaseID);
6130 else
6131 LE.write<uint32_t>(Val: None);
6132 };
6133
6134 // These values should be unique within a chain, since they will be read
6135 // as keys into ContinuousRangeMaps.
6136 writeBaseIDOrNone(M.BaseSubmoduleID, M.LocalNumSubmodules);
6137 writeBaseIDOrNone(M.BaseSelectorID, M.LocalNumSelectors);
6138 }
6139 }
6140 RecordData::value_type Record[] = {MODULE_OFFSET_MAP};
6141 Stream.EmitRecordWithBlob(Abbrev: ModuleOffsetMapAbbrev, Vals: Record,
6142 BlobData: Buffer.data(), BlobLen: Buffer.size());
6143 }
6144
6145 if (SemaPtr)
6146 WriteDeclAndTypes(Context&: SemaPtr->Context);
6147
6148 WriteFileDeclIDsMap();
6149 WriteSourceManagerBlock(SourceMgr&: PP->getSourceManager());
6150 if (SemaPtr)
6151 WriteComments(Context&: SemaPtr->Context);
6152 WritePreprocessor(PP: *PP, IsModule: isModule);
6153 WriteHeaderSearch(HS: PP->getHeaderSearchInfo());
6154 if (SemaPtr) {
6155 WriteSelectors(SemaRef&: *SemaPtr);
6156 WriteReferencedSelectorsPool(SemaRef&: *SemaPtr);
6157 WriteLateParsedTemplates(SemaRef&: *SemaPtr);
6158 }
6159 WriteIdentifierTable(PP&: *PP, IdResolver: SemaPtr ? &SemaPtr->IdResolver : nullptr, IsModule: isModule);
6160 if (SemaPtr) {
6161 WriteFPPragmaOptions(Opts: SemaPtr->CurFPFeatureOverrides());
6162 WriteOpenCLExtensions(SemaRef&: *SemaPtr);
6163 WriteCUDAPragmas(SemaRef&: *SemaPtr);
6164 WriteRISCVIntrinsicPragmas(SemaRef&: *SemaPtr);
6165 }
6166
6167 // If we're emitting a module, write out the submodule information.
6168 if (WritingModule)
6169 WriteSubmodules(WritingModule, Context: SemaPtr ? &SemaPtr->Context : nullptr);
6170
6171 Stream.EmitRecord(Code: SPECIAL_TYPES, Vals: SpecialTypes);
6172
6173 if (SemaPtr)
6174 WriteSpecialDeclRecords(SemaRef&: *SemaPtr);
6175
6176 // Write the record containing weak undeclared identifiers.
6177 if (!WeakUndeclaredIdentifiers.empty())
6178 Stream.EmitRecord(Code: WEAK_UNDECLARED_IDENTIFIERS,
6179 Vals: WeakUndeclaredIdentifiers);
6180
6181 if (!WritingModule) {
6182 // Write the submodules that were imported, if any.
6183 struct ModuleInfo {
6184 uint64_t ID;
6185 Module *M;
6186 ModuleInfo(uint64_t ID, Module *M) : ID(ID), M(M) {}
6187 };
6188 llvm::SmallVector<ModuleInfo, 64> Imports;
6189 if (SemaPtr) {
6190 for (const auto *I : SemaPtr->Context.local_imports()) {
6191 assert(SubmoduleIDs.contains(I->getImportedModule()));
6192 Imports.push_back(Elt: ModuleInfo(SubmoduleIDs[I->getImportedModule()],
6193 I->getImportedModule()));
6194 }
6195 }
6196
6197 if (!Imports.empty()) {
6198 auto Cmp = [](const ModuleInfo &A, const ModuleInfo &B) {
6199 return A.ID < B.ID;
6200 };
6201 auto Eq = [](const ModuleInfo &A, const ModuleInfo &B) {
6202 return A.ID == B.ID;
6203 };
6204
6205 // Sort and deduplicate module IDs.
6206 llvm::sort(C&: Imports, Comp: Cmp);
6207 Imports.erase(CS: llvm::unique(R&: Imports, P: Eq), CE: Imports.end());
6208
6209 RecordData ImportedModules;
6210 for (const auto &Import : Imports) {
6211 ImportedModules.push_back(Elt: Import.ID);
6212 // FIXME: If the module has macros imported then later has declarations
6213 // imported, this location won't be the right one as a location for the
6214 // declaration imports.
6215 AddSourceLocation(Loc: PP->getModuleImportLoc(M: Import.M), Record&: ImportedModules);
6216 }
6217
6218 Stream.EmitRecord(Code: IMPORTED_MODULES, Vals: ImportedModules);
6219 }
6220 }
6221
6222 WriteObjCCategories();
6223 if (SemaPtr) {
6224 if (!WritingModule) {
6225 WriteOptimizePragmaOptions(SemaRef&: *SemaPtr);
6226 WriteMSStructPragmaOptions(SemaRef&: *SemaPtr);
6227 WriteMSPointersToMembersPragmaOptions(SemaRef&: *SemaPtr);
6228 }
6229 WritePackPragmaOptions(SemaRef&: *SemaPtr);
6230 WriteFloatControlPragmaOptions(SemaRef&: *SemaPtr);
6231 WriteDeclsWithEffectsToVerify(SemaRef&: *SemaPtr);
6232 }
6233
6234 // Some simple statistics
6235 RecordData::value_type Record[] = {NumStatements,
6236 NumMacros,
6237 NumLexicalDeclContexts,
6238 NumVisibleDeclContexts,
6239 NumModuleLocalDeclContexts,
6240 NumTULocalDeclContexts};
6241 Stream.EmitRecord(Code: STATISTICS, Vals: Record);
6242 Stream.ExitBlock();
6243 Stream.FlushToWord();
6244 ASTBlockRange.second = Stream.GetCurrentBitNo() >> 3;
6245
6246 // Write the module file extension blocks.
6247 if (SemaPtr)
6248 for (const auto &ExtWriter : ModuleFileExtensionWriters)
6249 WriteModuleFileExtension(SemaRef&: *SemaPtr, Writer&: *ExtWriter);
6250
6251 return backpatchSignature();
6252}
6253
6254void ASTWriter::EnteringModulePurview() {
6255 // In C++20 named modules, all entities before entering the module purview
6256 // lives in the GMF.
6257 if (GeneratingReducedBMI)
6258 DeclUpdatesFromGMF.swap(RHS&: DeclUpdates);
6259}
6260
6261// Add update records for all mangling numbers and static local numbers.
6262// These aren't really update records, but this is a convenient way of
6263// tagging this rare extra data onto the declarations.
6264void ASTWriter::AddedManglingNumber(const Decl *D, unsigned Number) {
6265 if (D->isFromASTFile())
6266 return;
6267
6268 DeclUpdates[D].push_back(Elt: DeclUpdate(DeclUpdateKind::ManglingNumber, Number));
6269}
6270void ASTWriter::AddedStaticLocalNumbers(const Decl *D, unsigned Number) {
6271 if (D->isFromASTFile())
6272 return;
6273
6274 DeclUpdates[D].push_back(
6275 Elt: DeclUpdate(DeclUpdateKind::StaticLocalNumber, Number));
6276}
6277
6278void ASTWriter::AddedAnonymousNamespace(const TranslationUnitDecl *TU,
6279 NamespaceDecl *AnonNamespace) {
6280 // If the translation unit has an anonymous namespace, and we don't already
6281 // have an update block for it, write it as an update block.
6282 // FIXME: Why do we not do this if there's already an update block?
6283 if (NamespaceDecl *NS = TU->getAnonymousNamespace()) {
6284 ASTWriter::UpdateRecord &Record = DeclUpdates[TU];
6285 if (Record.empty())
6286 Record.push_back(
6287 Elt: DeclUpdate(DeclUpdateKind::CXXAddedAnonymousNamespace, NS));
6288 }
6289}
6290
6291void ASTWriter::WriteDeclAndTypes(ASTContext &Context) {
6292 // Keep writing types, declarations, and declaration update records
6293 // until we've emitted all of them.
6294 RecordData DeclUpdatesOffsetsRecord;
6295 Stream.EnterSubblock(BlockID: DECLTYPES_BLOCK_ID, /*bits for abbreviations*/ CodeLen: 6);
6296 DeclTypesBlockStartOffset = Stream.GetCurrentBitNo();
6297 WriteTypeAbbrevs();
6298 WriteDeclAbbrevs();
6299 do {
6300 WriteDeclUpdatesBlocks(Context, OffsetsRecord&: DeclUpdatesOffsetsRecord);
6301 while (!DeclTypesToEmit.empty()) {
6302 DeclOrType DOT = DeclTypesToEmit.front();
6303 DeclTypesToEmit.pop();
6304 if (DOT.isType())
6305 WriteType(Context, T: DOT.getType());
6306 else
6307 WriteDecl(Context, D: DOT.getDecl());
6308 }
6309 } while (!DeclUpdates.empty());
6310
6311 DoneWritingDeclsAndTypes = true;
6312
6313 // DelayedNamespace is only meaningful in reduced BMI.
6314 // See the comments of DelayedNamespace for details.
6315 assert(DelayedNamespace.empty() || GeneratingReducedBMI);
6316 RecordData DelayedNamespaceRecord;
6317 for (NamespaceDecl *NS : DelayedNamespace) {
6318 LookupBlockOffsets Offsets;
6319
6320 Offsets.LexicalOffset = WriteDeclContextLexicalBlock(Context, DC: NS);
6321 WriteDeclContextVisibleBlock(Context, DC: NS, Offsets);
6322
6323 if (Offsets.LexicalOffset)
6324 Offsets.LexicalOffset -= DeclTypesBlockStartOffset;
6325
6326 // Write the offset relative to current block.
6327 if (Offsets.VisibleOffset)
6328 Offsets.VisibleOffset -= DeclTypesBlockStartOffset;
6329
6330 if (Offsets.ModuleLocalOffset)
6331 Offsets.ModuleLocalOffset -= DeclTypesBlockStartOffset;
6332
6333 if (Offsets.TULocalOffset)
6334 Offsets.TULocalOffset -= DeclTypesBlockStartOffset;
6335
6336 AddDeclRef(D: NS, Record&: DelayedNamespaceRecord);
6337 AddLookupOffsets(Offsets, Record&: DelayedNamespaceRecord);
6338 }
6339
6340 // The process of writing lexical and visible block for delayed namespace
6341 // shouldn't introduce any new decls, types or update to emit.
6342 assert(DeclTypesToEmit.empty());
6343 assert(DeclUpdates.empty());
6344
6345 Stream.ExitBlock();
6346
6347 // These things can only be done once we've written out decls and types.
6348 WriteTypeDeclOffsets();
6349 if (!DeclUpdatesOffsetsRecord.empty())
6350 Stream.EmitRecord(Code: DECL_UPDATE_OFFSETS, Vals: DeclUpdatesOffsetsRecord);
6351
6352 if (!DelayedNamespaceRecord.empty())
6353 Stream.EmitRecord(Code: DELAYED_NAMESPACE_LEXICAL_VISIBLE_RECORD,
6354 Vals: DelayedNamespaceRecord);
6355
6356 if (!RelatedDeclsMap.empty()) {
6357 // TODO: on disk hash table for related decls mapping might be more
6358 // efficent becuase it allows lazy deserialization.
6359 RecordData RelatedDeclsMapRecord;
6360 for (const auto &Pair : RelatedDeclsMap) {
6361 RelatedDeclsMapRecord.push_back(Elt: Pair.first.getRawValue());
6362 RelatedDeclsMapRecord.push_back(Elt: Pair.second.size());
6363 for (const auto &Lambda : Pair.second)
6364 RelatedDeclsMapRecord.push_back(Elt: Lambda.getRawValue());
6365 }
6366
6367 auto Abv = std::make_shared<llvm::BitCodeAbbrev>();
6368 Abv->Add(OpInfo: llvm::BitCodeAbbrevOp(RELATED_DECLS_MAP));
6369 Abv->Add(OpInfo: llvm::BitCodeAbbrevOp(llvm::BitCodeAbbrevOp::Array));
6370 Abv->Add(OpInfo: llvm::BitCodeAbbrevOp(llvm::BitCodeAbbrevOp::VBR, 6));
6371 unsigned FunctionToLambdaMapAbbrev = Stream.EmitAbbrev(Abbv: std::move(Abv));
6372 Stream.EmitRecord(Code: RELATED_DECLS_MAP, Vals: RelatedDeclsMapRecord,
6373 Abbrev: FunctionToLambdaMapAbbrev);
6374 }
6375
6376 if (!SpecializationsUpdates.empty()) {
6377 WriteSpecializationsUpdates(/*IsPartial=*/false);
6378 SpecializationsUpdates.clear();
6379 }
6380
6381 if (!PartialSpecializationsUpdates.empty()) {
6382 WriteSpecializationsUpdates(/*IsPartial=*/true);
6383 PartialSpecializationsUpdates.clear();
6384 }
6385
6386 const TranslationUnitDecl *TU = Context.getTranslationUnitDecl();
6387 // Create a lexical update block containing all of the declarations in the
6388 // translation unit that do not come from other AST files.
6389 SmallVector<DeclID, 128> NewGlobalKindDeclPairs;
6390 for (const auto *D : TU->noload_decls()) {
6391 if (D->isFromASTFile())
6392 continue;
6393
6394 // In reduced BMI, skip unreached declarations.
6395 if (!wasDeclEmitted(D))
6396 continue;
6397
6398 NewGlobalKindDeclPairs.push_back(Elt: D->getKind());
6399 NewGlobalKindDeclPairs.push_back(Elt: GetDeclRef(D).getRawValue());
6400 }
6401
6402 auto Abv = std::make_shared<llvm::BitCodeAbbrev>();
6403 Abv->Add(OpInfo: llvm::BitCodeAbbrevOp(TU_UPDATE_LEXICAL));
6404 Abv->Add(OpInfo: llvm::BitCodeAbbrevOp(llvm::BitCodeAbbrevOp::Blob));
6405 unsigned TuUpdateLexicalAbbrev = Stream.EmitAbbrev(Abbv: std::move(Abv));
6406
6407 RecordData::value_type Record[] = {TU_UPDATE_LEXICAL};
6408 Stream.EmitRecordWithBlob(Abbrev: TuUpdateLexicalAbbrev, Vals: Record,
6409 Blob: bytes(v: NewGlobalKindDeclPairs));
6410
6411 Abv = std::make_shared<llvm::BitCodeAbbrev>();
6412 Abv->Add(OpInfo: llvm::BitCodeAbbrevOp(UPDATE_VISIBLE));
6413 Abv->Add(OpInfo: llvm::BitCodeAbbrevOp(llvm::BitCodeAbbrevOp::VBR, 6));
6414 Abv->Add(OpInfo: llvm::BitCodeAbbrevOp(llvm::BitCodeAbbrevOp::Blob));
6415 UpdateVisibleAbbrev = Stream.EmitAbbrev(Abbv: std::move(Abv));
6416
6417 Abv = std::make_shared<llvm::BitCodeAbbrev>();
6418 Abv->Add(OpInfo: llvm::BitCodeAbbrevOp(UPDATE_MODULE_LOCAL_VISIBLE));
6419 Abv->Add(OpInfo: llvm::BitCodeAbbrevOp(llvm::BitCodeAbbrevOp::VBR, 6));
6420 Abv->Add(OpInfo: llvm::BitCodeAbbrevOp(llvm::BitCodeAbbrevOp::Blob));
6421 ModuleLocalUpdateVisibleAbbrev = Stream.EmitAbbrev(Abbv: std::move(Abv));
6422
6423 Abv = std::make_shared<llvm::BitCodeAbbrev>();
6424 Abv->Add(OpInfo: llvm::BitCodeAbbrevOp(UPDATE_TU_LOCAL_VISIBLE));
6425 Abv->Add(OpInfo: llvm::BitCodeAbbrevOp(llvm::BitCodeAbbrevOp::VBR, 6));
6426 Abv->Add(OpInfo: llvm::BitCodeAbbrevOp(llvm::BitCodeAbbrevOp::Blob));
6427 TULocalUpdateVisibleAbbrev = Stream.EmitAbbrev(Abbv: std::move(Abv));
6428
6429 // And a visible updates block for the translation unit.
6430 WriteDeclContextVisibleUpdate(Context, DC: TU);
6431
6432 // If we have any extern "C" names, write out a visible update for them.
6433 if (Context.ExternCContext)
6434 WriteDeclContextVisibleUpdate(Context, DC: Context.ExternCContext);
6435
6436 // Write the visible updates to DeclContexts.
6437 for (auto *DC : UpdatedDeclContexts)
6438 WriteDeclContextVisibleUpdate(Context, DC);
6439}
6440
6441void ASTWriter::WriteSpecializationsUpdates(bool IsPartial) {
6442 auto RecordType = IsPartial ? CXX_ADDED_TEMPLATE_PARTIAL_SPECIALIZATION
6443 : CXX_ADDED_TEMPLATE_SPECIALIZATION;
6444
6445 auto Abv = std::make_shared<llvm::BitCodeAbbrev>();
6446 Abv->Add(OpInfo: llvm::BitCodeAbbrevOp(RecordType));
6447 Abv->Add(OpInfo: llvm::BitCodeAbbrevOp(llvm::BitCodeAbbrevOp::VBR, 6));
6448 Abv->Add(OpInfo: llvm::BitCodeAbbrevOp(llvm::BitCodeAbbrevOp::Blob));
6449 auto UpdateSpecializationAbbrev = Stream.EmitAbbrev(Abbv: std::move(Abv));
6450
6451 auto &SpecUpdates =
6452 IsPartial ? PartialSpecializationsUpdates : SpecializationsUpdates;
6453 for (auto &SpecializationUpdate : SpecUpdates) {
6454 const NamedDecl *D = SpecializationUpdate.first;
6455
6456 llvm::SmallString<4096> LookupTable;
6457 GenerateSpecializationInfoLookupTable(D, Specializations&: SpecializationUpdate.second,
6458 LookupTable, IsPartial);
6459
6460 // Write the lookup table
6461 RecordData::value_type Record[] = {
6462 static_cast<RecordData::value_type>(RecordType),
6463 getDeclID(D).getRawValue()};
6464 Stream.EmitRecordWithBlob(Abbrev: UpdateSpecializationAbbrev, Vals: Record, Blob: LookupTable);
6465 }
6466}
6467
6468void ASTWriter::WriteDeclUpdatesBlocks(ASTContext &Context,
6469 RecordDataImpl &OffsetsRecord) {
6470 if (DeclUpdates.empty())
6471 return;
6472
6473 DeclUpdateMap LocalUpdates;
6474 LocalUpdates.swap(RHS&: DeclUpdates);
6475
6476 for (auto &DeclUpdate : LocalUpdates) {
6477 const Decl *D = DeclUpdate.first;
6478
6479 bool HasUpdatedBody = false;
6480 bool HasAddedVarDefinition = false;
6481 RecordData RecordData;
6482 ASTRecordWriter Record(Context, *this, RecordData);
6483 for (auto &Update : DeclUpdate.second) {
6484 DeclUpdateKind Kind = Update.getKind();
6485
6486 // An updated body is emitted last, so that the reader doesn't need
6487 // to skip over the lazy body to reach statements for other records.
6488 if (Kind == DeclUpdateKind::CXXAddedFunctionDefinition)
6489 HasUpdatedBody = true;
6490 else if (Kind == DeclUpdateKind::CXXAddedVarDefinition)
6491 HasAddedVarDefinition = true;
6492 else
6493 Record.push_back(N: llvm::to_underlying(E: Kind));
6494
6495 switch (Kind) {
6496 case DeclUpdateKind::CXXAddedImplicitMember:
6497 case DeclUpdateKind::CXXAddedAnonymousNamespace:
6498 assert(Update.getDecl() && "no decl to add?");
6499 Record.AddDeclRef(D: Update.getDecl());
6500 break;
6501 case DeclUpdateKind::CXXAddedFunctionDefinition:
6502 case DeclUpdateKind::CXXAddedVarDefinition:
6503 break;
6504
6505 case DeclUpdateKind::CXXPointOfInstantiation:
6506 // FIXME: Do we need to also save the template specialization kind here?
6507 Record.AddSourceLocation(Loc: Update.getLoc());
6508 break;
6509
6510 case DeclUpdateKind::CXXInstantiatedDefaultArgument:
6511 Record.writeStmtRef(
6512 S: cast<ParmVarDecl>(Val: Update.getDecl())->getDefaultArg());
6513 break;
6514
6515 case DeclUpdateKind::CXXInstantiatedDefaultMemberInitializer:
6516 Record.AddStmt(
6517 S: cast<FieldDecl>(Val: Update.getDecl())->getInClassInitializer());
6518 break;
6519
6520 case DeclUpdateKind::CXXInstantiatedClassDefinition: {
6521 auto *RD = cast<CXXRecordDecl>(Val: D);
6522 UpdatedDeclContexts.insert(X: RD->getPrimaryContext());
6523 Record.push_back(N: RD->isParamDestroyedInCallee());
6524 Record.push_back(N: llvm::to_underlying(E: RD->getArgPassingRestrictions()));
6525 Record.AddCXXDefinitionData(D: RD);
6526 Record.AddOffset(BitOffset: WriteDeclContextLexicalBlock(Context, DC: RD));
6527
6528 // This state is sometimes updated by template instantiation, when we
6529 // switch from the specialization referring to the template declaration
6530 // to it referring to the template definition.
6531 if (auto *MSInfo = RD->getMemberSpecializationInfo()) {
6532 Record.push_back(N: MSInfo->getTemplateSpecializationKind());
6533 Record.AddSourceLocation(Loc: MSInfo->getPointOfInstantiation());
6534 } else {
6535 auto *Spec = cast<ClassTemplateSpecializationDecl>(Val: RD);
6536 Record.push_back(N: Spec->getTemplateSpecializationKind());
6537 Record.AddSourceLocation(Loc: Spec->getPointOfInstantiation());
6538
6539 // The instantiation might have been resolved to a partial
6540 // specialization. If so, record which one.
6541 auto From = Spec->getInstantiatedFrom();
6542 if (auto PartialSpec =
6543 From.dyn_cast<ClassTemplatePartialSpecializationDecl*>()) {
6544 Record.push_back(N: true);
6545 Record.AddDeclRef(D: PartialSpec);
6546 Record.AddTemplateArgumentList(
6547 TemplateArgs: &Spec->getTemplateInstantiationArgs());
6548 } else {
6549 Record.push_back(N: false);
6550 }
6551 }
6552 Record.push_back(N: llvm::to_underlying(E: RD->getTagKind()));
6553 Record.AddSourceLocation(Loc: RD->getLocation());
6554 Record.AddSourceLocation(Loc: RD->getBeginLoc());
6555 Record.AddSourceRange(Range: RD->getBraceRange());
6556
6557 // Instantiation may change attributes; write them all out afresh.
6558 Record.push_back(N: D->hasAttrs());
6559 if (D->hasAttrs())
6560 Record.AddAttributes(Attrs: D->getAttrs());
6561
6562 // FIXME: Ensure we don't get here for explicit instantiations.
6563 break;
6564 }
6565
6566 case DeclUpdateKind::CXXResolvedDtorDelete:
6567 Record.AddDeclRef(D: Update.getDecl());
6568 Record.AddStmt(S: cast<CXXDestructorDecl>(Val: D)->getOperatorDeleteThisArg());
6569 break;
6570
6571 case DeclUpdateKind::CXXResolvedDtorGlobDelete:
6572 Record.AddDeclRef(D: Update.getDecl());
6573 break;
6574
6575 case DeclUpdateKind::CXXResolvedDtorArrayDelete:
6576 Record.AddDeclRef(D: Update.getDecl());
6577 break;
6578
6579 case DeclUpdateKind::CXXResolvedDtorGlobArrayDelete:
6580 Record.AddDeclRef(D: Update.getDecl());
6581 break;
6582
6583 case DeclUpdateKind::CXXResolvedExceptionSpec: {
6584 auto prototype =
6585 cast<FunctionDecl>(Val: D)->getType()->castAs<FunctionProtoType>();
6586 Record.writeExceptionSpecInfo(esi: prototype->getExceptionSpecInfo());
6587 break;
6588 }
6589
6590 case DeclUpdateKind::CXXDeducedReturnType:
6591 Record.push_back(N: GetOrCreateTypeID(Context, T: Update.getType()));
6592 break;
6593
6594 case DeclUpdateKind::DeclMarkedUsed:
6595 break;
6596
6597 case DeclUpdateKind::ManglingNumber:
6598 case DeclUpdateKind::StaticLocalNumber:
6599 Record.push_back(N: Update.getNumber());
6600 break;
6601
6602 case DeclUpdateKind::DeclMarkedOpenMPThreadPrivate:
6603 Record.AddSourceRange(
6604 Range: D->getAttr<OMPThreadPrivateDeclAttr>()->getRange());
6605 break;
6606
6607 case DeclUpdateKind::DeclMarkedOpenMPAllocate: {
6608 auto *A = D->getAttr<OMPAllocateDeclAttr>();
6609 Record.push_back(N: A->getAllocatorType());
6610 Record.AddStmt(S: A->getAllocator());
6611 Record.AddStmt(S: A->getAlignment());
6612 Record.AddSourceRange(Range: A->getRange());
6613 break;
6614 }
6615
6616 case DeclUpdateKind::DeclMarkedOpenMPDeclareTarget:
6617 Record.push_back(N: D->getAttr<OMPDeclareTargetDeclAttr>()->getMapType());
6618 Record.AddSourceRange(
6619 Range: D->getAttr<OMPDeclareTargetDeclAttr>()->getRange());
6620 break;
6621
6622 case DeclUpdateKind::DeclExported:
6623 Record.push_back(N: getSubmoduleID(Mod: Update.getModule()));
6624 break;
6625
6626 case DeclUpdateKind::AddedAttrToRecord:
6627 Record.AddAttributes(Attrs: llvm::ArrayRef(Update.getAttr()));
6628 break;
6629 }
6630 }
6631
6632 // Add a trailing update record, if any. These must go last because we
6633 // lazily load their attached statement.
6634 if (!GeneratingReducedBMI || !CanElideDeclDef(D)) {
6635 if (HasUpdatedBody) {
6636 const auto *Def = cast<FunctionDecl>(Val: D);
6637 Record.push_back(
6638 N: llvm::to_underlying(E: DeclUpdateKind::CXXAddedFunctionDefinition));
6639 Record.push_back(N: Def->isInlined());
6640 Record.AddSourceLocation(Loc: Def->getInnerLocStart());
6641 Record.AddFunctionDefinition(FD: Def);
6642 } else if (HasAddedVarDefinition) {
6643 const auto *VD = cast<VarDecl>(Val: D);
6644 Record.push_back(
6645 N: llvm::to_underlying(E: DeclUpdateKind::CXXAddedVarDefinition));
6646 Record.push_back(N: VD->isInline());
6647 Record.push_back(N: VD->isInlineSpecified());
6648 Record.AddVarDeclInit(VD);
6649 }
6650 }
6651
6652 AddDeclRef(D, Record&: OffsetsRecord);
6653 OffsetsRecord.push_back(Elt: Record.Emit(Code: DECL_UPDATES));
6654 }
6655}
6656
6657void ASTWriter::AddAlignPackInfo(const Sema::AlignPackInfo &Info,
6658 RecordDataImpl &Record) {
6659 uint32_t Raw = Sema::AlignPackInfo::getRawEncoding(Info);
6660 Record.push_back(Elt: Raw);
6661}
6662
6663FileID ASTWriter::getAdjustedFileID(FileID FID) const {
6664 if (FID.isInvalid() || PP->getSourceManager().isLoadedFileID(FID) ||
6665 NonAffectingFileIDs.empty())
6666 return FID;
6667 auto It = llvm::lower_bound(Range: NonAffectingFileIDs, Value&: FID);
6668 unsigned Idx = std::distance(first: NonAffectingFileIDs.begin(), last: It);
6669 unsigned Offset = NonAffectingFileIDAdjustments[Idx];
6670 return FileID::get(V: FID.getOpaqueValue() - Offset);
6671}
6672
6673unsigned ASTWriter::getAdjustedNumCreatedFIDs(FileID FID) const {
6674 unsigned NumCreatedFIDs = PP->getSourceManager()
6675 .getLocalSLocEntry(Index: FID.ID)
6676 .getFile()
6677 .NumCreatedFIDs;
6678
6679 unsigned AdjustedNumCreatedFIDs = 0;
6680 for (unsigned I = FID.ID, N = I + NumCreatedFIDs; I != N; ++I)
6681 if (IsSLocAffecting[I])
6682 ++AdjustedNumCreatedFIDs;
6683 return AdjustedNumCreatedFIDs;
6684}
6685
6686SourceLocation ASTWriter::getAdjustedLocation(SourceLocation Loc) const {
6687 if (Loc.isInvalid())
6688 return Loc;
6689 return Loc.getLocWithOffset(Offset: -getAdjustment(Offset: Loc.getOffset()));
6690}
6691
6692SourceRange ASTWriter::getAdjustedRange(SourceRange Range) const {
6693 return SourceRange(getAdjustedLocation(Loc: Range.getBegin()),
6694 getAdjustedLocation(Loc: Range.getEnd()));
6695}
6696
6697SourceLocation::UIntTy
6698ASTWriter::getAdjustedOffset(SourceLocation::UIntTy Offset) const {
6699 return Offset - getAdjustment(Offset);
6700}
6701
6702SourceLocation::UIntTy
6703ASTWriter::getAdjustment(SourceLocation::UIntTy Offset) const {
6704 if (NonAffectingRanges.empty())
6705 return 0;
6706
6707 if (PP->getSourceManager().isLoadedOffset(SLocOffset: Offset))
6708 return 0;
6709
6710 if (Offset > NonAffectingRanges.back().getEnd().getOffset())
6711 return NonAffectingOffsetAdjustments.back();
6712
6713 if (Offset < NonAffectingRanges.front().getBegin().getOffset())
6714 return 0;
6715
6716 auto Contains = [](const SourceRange &Range, SourceLocation::UIntTy Offset) {
6717 return Range.getEnd().getOffset() < Offset;
6718 };
6719
6720 auto It = llvm::lower_bound(Range: NonAffectingRanges, Value&: Offset, C: Contains);
6721 unsigned Idx = std::distance(first: NonAffectingRanges.begin(), last: It);
6722 return NonAffectingOffsetAdjustments[Idx];
6723}
6724
6725void ASTWriter::AddFileID(FileID FID, RecordDataImpl &Record) {
6726 Record.push_back(Elt: getAdjustedFileID(FID).getOpaqueValue());
6727}
6728
6729SourceLocationEncoding::RawLocEncoding
6730ASTWriter::getRawSourceLocationEncoding(SourceLocation Loc) {
6731 SourceLocation::UIntTy BaseOffset = 0;
6732 unsigned ModuleFileIndex = 0;
6733
6734 // See SourceLocationEncoding.h for the encoding details.
6735 if (PP->getSourceManager().isLoadedSourceLocation(Loc) && Loc.isValid()) {
6736 assert(getChain());
6737 auto SLocMapI = getChain()->GlobalSLocOffsetMap.find(
6738 K: SourceManager::MaxLoadedOffset - Loc.getOffset() - 1);
6739 assert(SLocMapI != getChain()->GlobalSLocOffsetMap.end() &&
6740 "Corrupted global sloc offset map");
6741 ModuleFile *F = SLocMapI->second;
6742 BaseOffset = F->SLocEntryBaseOffset - 2;
6743 // 0 means the location is not loaded. So we need to add 1 to the index to
6744 // make it clear.
6745 ModuleFileIndex = F->Index + 1;
6746 assert(&getChain()->getModuleManager()[F->Index] == F);
6747 }
6748
6749 return SourceLocationEncoding::encode(Loc, BaseOffset, BaseModuleFileIndex: ModuleFileIndex);
6750}
6751
6752void ASTWriter::AddSourceLocation(SourceLocation Loc, RecordDataImpl &Record) {
6753 Loc = getAdjustedLocation(Loc);
6754 Record.push_back(Elt: getRawSourceLocationEncoding(Loc));
6755}
6756
6757void ASTWriter::AddSourceRange(SourceRange Range, RecordDataImpl &Record) {
6758 AddSourceLocation(Loc: Range.getBegin(), Record);
6759 AddSourceLocation(Loc: Range.getEnd(), Record);
6760}
6761
6762void ASTRecordWriter::AddAPFloat(const llvm::APFloat &Value) {
6763 AddAPInt(Value: Value.bitcastToAPInt());
6764}
6765
6766void ASTWriter::AddIdentifierRef(const IdentifierInfo *II, RecordDataImpl &Record) {
6767 Record.push_back(Elt: getIdentifierRef(II));
6768}
6769
6770IdentifierID ASTWriter::getIdentifierRef(const IdentifierInfo *II) {
6771 if (!II)
6772 return 0;
6773
6774 IdentifierID &ID = IdentifierIDs[II];
6775 if (ID == 0)
6776 ID = NextIdentID++;
6777 return ID;
6778}
6779
6780MacroID ASTWriter::getMacroRef(MacroInfo *MI, const IdentifierInfo *Name) {
6781 // Don't emit builtin macros like __LINE__ to the AST file unless they
6782 // have been redefined by the header (in which case they are not
6783 // isBuiltinMacro).
6784 if (!MI || MI->isBuiltinMacro())
6785 return 0;
6786
6787 MacroID &ID = MacroIDs[MI];
6788 if (ID == 0) {
6789 ID = NextMacroID++;
6790 MacroInfoToEmitData Info = { .Name: Name, .MI: MI, .ID: ID };
6791 MacroInfosToEmit.push_back(x: Info);
6792 }
6793 return ID;
6794}
6795
6796uint32_t ASTWriter::getMacroDirectivesOffset(const IdentifierInfo *Name) {
6797 return IdentMacroDirectivesOffsetMap.lookup(Val: Name);
6798}
6799
6800void ASTRecordWriter::AddSelectorRef(const Selector SelRef) {
6801 Record->push_back(Elt: Writer->getSelectorRef(Sel: SelRef));
6802}
6803
6804SelectorID ASTWriter::getSelectorRef(Selector Sel) {
6805 if (Sel.getAsOpaquePtr() == nullptr) {
6806 return 0;
6807 }
6808
6809 SelectorID SID = SelectorIDs[Sel];
6810 if (SID == 0 && Chain) {
6811 // This might trigger a ReadSelector callback, which will set the ID for
6812 // this selector.
6813 Chain->LoadSelector(Sel);
6814 SID = SelectorIDs[Sel];
6815 }
6816 if (SID == 0) {
6817 SID = NextSelectorID++;
6818 SelectorIDs[Sel] = SID;
6819 }
6820 return SID;
6821}
6822
6823void ASTRecordWriter::AddCXXTemporary(const CXXTemporary *Temp) {
6824 AddDeclRef(D: Temp->getDestructor());
6825}
6826
6827void ASTRecordWriter::AddTemplateArgumentLocInfo(
6828 const TemplateArgumentLoc &Arg) {
6829 const TemplateArgumentLocInfo &Info = Arg.getLocInfo();
6830 switch (auto K = Arg.getArgument().getKind()) {
6831 case TemplateArgument::Expression:
6832 AddStmt(S: Info.getAsExpr());
6833 break;
6834 case TemplateArgument::Type:
6835 AddTypeSourceInfo(TInfo: Info.getAsTypeSourceInfo());
6836 break;
6837 case TemplateArgument::Template:
6838 case TemplateArgument::TemplateExpansion:
6839 AddSourceLocation(Loc: Arg.getTemplateKWLoc());
6840 AddNestedNameSpecifierLoc(NNS: Arg.getTemplateQualifierLoc());
6841 AddSourceLocation(Loc: Arg.getTemplateNameLoc());
6842 if (K == TemplateArgument::TemplateExpansion)
6843 AddSourceLocation(Loc: Arg.getTemplateEllipsisLoc());
6844 break;
6845 case TemplateArgument::Null:
6846 case TemplateArgument::Integral:
6847 case TemplateArgument::Declaration:
6848 case TemplateArgument::NullPtr:
6849 case TemplateArgument::StructuralValue:
6850 case TemplateArgument::Pack:
6851 // FIXME: Is this right?
6852 break;
6853 }
6854}
6855
6856void ASTRecordWriter::AddTemplateArgumentLoc(const TemplateArgumentLoc &Arg) {
6857 AddTemplateArgument(Arg: Arg.getArgument());
6858
6859 if (Arg.getArgument().getKind() == TemplateArgument::Expression) {
6860 bool InfoHasSameExpr
6861 = Arg.getArgument().getAsExpr() == Arg.getLocInfo().getAsExpr();
6862 Record->push_back(Elt: InfoHasSameExpr);
6863 if (InfoHasSameExpr)
6864 return; // Avoid storing the same expr twice.
6865 }
6866 AddTemplateArgumentLocInfo(Arg);
6867}
6868
6869void ASTRecordWriter::AddTypeSourceInfo(TypeSourceInfo *TInfo) {
6870 if (!TInfo) {
6871 AddTypeRef(T: QualType());
6872 return;
6873 }
6874
6875 AddTypeRef(T: TInfo->getType());
6876 AddTypeLoc(TL: TInfo->getTypeLoc());
6877}
6878
6879void ASTRecordWriter::AddTypeLoc(TypeLoc TL) {
6880 TypeLocWriter TLW(*this);
6881 for (; !TL.isNull(); TL = TL.getNextTypeLoc())
6882 TLW.Visit(TyLoc: TL);
6883}
6884
6885void ASTWriter::AddTypeRef(ASTContext &Context, QualType T,
6886 RecordDataImpl &Record) {
6887 Record.push_back(Elt: GetOrCreateTypeID(Context, T));
6888}
6889
6890template <typename IdxForTypeTy>
6891static TypeID MakeTypeID(ASTContext &Context, QualType T,
6892 IdxForTypeTy IdxForType) {
6893 if (T.isNull())
6894 return PREDEF_TYPE_NULL_ID;
6895
6896 unsigned FastQuals = T.getLocalFastQualifiers();
6897 T.removeLocalFastQualifiers();
6898
6899 if (T.hasLocalNonFastQualifiers())
6900 return IdxForType(T).asTypeID(FastQuals);
6901
6902 assert(!T.hasLocalQualifiers());
6903
6904 if (const BuiltinType *BT = dyn_cast<BuiltinType>(Val: T.getTypePtr()))
6905 return TypeIdxFromBuiltin(BT).asTypeID(FastQuals);
6906
6907 if (T == Context.AutoDeductTy)
6908 return TypeIdx(0, PREDEF_TYPE_AUTO_DEDUCT).asTypeID(FastQuals);
6909 if (T == Context.AutoRRefDeductTy)
6910 return TypeIdx(0, PREDEF_TYPE_AUTO_RREF_DEDUCT).asTypeID(FastQuals);
6911
6912 return IdxForType(T).asTypeID(FastQuals);
6913}
6914
6915TypeID ASTWriter::GetOrCreateTypeID(ASTContext &Context, QualType T) {
6916 return MakeTypeID(Context, T, IdxForType: [&](QualType T) -> TypeIdx {
6917 if (T.isNull())
6918 return TypeIdx();
6919 assert(!T.getLocalFastQualifiers());
6920
6921 TypeIdx &Idx = TypeIdxs[T];
6922 if (Idx.getValue() == 0) {
6923 if (DoneWritingDeclsAndTypes) {
6924 assert(0 && "New type seen after serializing all the types to emit!");
6925 return TypeIdx();
6926 }
6927
6928 // We haven't seen this type before. Assign it a new ID and put it
6929 // into the queue of types to emit.
6930 Idx = TypeIdx(0, NextTypeID++);
6931 DeclTypesToEmit.push(x: T);
6932 }
6933 return Idx;
6934 });
6935}
6936
6937llvm::MapVector<ModuleFile *, const Decl *>
6938ASTWriter::CollectFirstDeclFromEachModule(const Decl *D, bool IncludeLocal) {
6939 llvm::MapVector<ModuleFile *, const Decl *> Firsts;
6940 // FIXME: We can skip entries that we know are implied by others.
6941 for (const Decl *R = D->getMostRecentDecl(); R; R = R->getPreviousDecl()) {
6942 if (R->isFromASTFile())
6943 Firsts[Chain->getOwningModuleFile(D: R)] = R;
6944 else if (IncludeLocal)
6945 Firsts[nullptr] = R;
6946 }
6947 return Firsts;
6948}
6949
6950void ASTWriter::AddLookupOffsets(const LookupBlockOffsets &Offsets,
6951 RecordDataImpl &Record) {
6952 Record.push_back(Elt: Offsets.LexicalOffset);
6953 Record.push_back(Elt: Offsets.VisibleOffset);
6954 Record.push_back(Elt: Offsets.ModuleLocalOffset);
6955 Record.push_back(Elt: Offsets.TULocalOffset);
6956}
6957
6958void ASTWriter::AddMacroRef(MacroInfo *MI, const IdentifierInfo *Name,
6959 RecordDataImpl &Record) {
6960 MacroID MacroRef = getMacroRef(MI, Name);
6961 Record.push_back(Elt: MacroRef >> 32);
6962 Record.push_back(Elt: MacroRef & llvm::maskTrailingOnes<MacroID>(N: 32));
6963}
6964
6965void ASTWriter::AddEmittedDeclRef(const Decl *D, RecordDataImpl &Record) {
6966 if (!wasDeclEmitted(D))
6967 return;
6968
6969 AddDeclRef(D, Record);
6970}
6971
6972void ASTWriter::AddDeclRef(const Decl *D, RecordDataImpl &Record) {
6973 Record.push_back(Elt: GetDeclRef(D).getRawValue());
6974}
6975
6976LocalDeclID ASTWriter::GetDeclRef(const Decl *D) {
6977 assert(WritingAST && "Cannot request a declaration ID before AST writing");
6978
6979 if (!D) {
6980 return LocalDeclID();
6981 }
6982
6983 // If the DeclUpdate from the GMF gets touched, emit it.
6984 if (auto *Iter = DeclUpdatesFromGMF.find(Key: D);
6985 Iter != DeclUpdatesFromGMF.end()) {
6986 for (DeclUpdate &Update : Iter->second)
6987 DeclUpdates[D].push_back(Elt: Update);
6988 DeclUpdatesFromGMF.erase(Iterator: Iter);
6989 }
6990
6991 // If D comes from an AST file, its declaration ID is already known and
6992 // fixed.
6993 if (D->isFromASTFile()) {
6994 if (isWritingStdCXXNamedModules() && D->getOwningModule())
6995 TouchedTopLevelModules.insert(X: D->getOwningModule()->getTopLevelModule());
6996
6997 return LocalDeclID(D->getGlobalID());
6998 }
6999
7000 assert(!(reinterpret_cast<uintptr_t>(D) & 0x01) && "Invalid decl pointer");
7001 LocalDeclID &ID = DeclIDs[D];
7002 if (ID.isInvalid()) {
7003 if (DoneWritingDeclsAndTypes) {
7004 assert(0 && "New decl seen after serializing all the decls to emit!");
7005 return LocalDeclID();
7006 }
7007
7008 // We haven't seen this declaration before. Give it a new ID and
7009 // enqueue it in the list of declarations to emit.
7010 ID = NextDeclID++;
7011 DeclTypesToEmit.push(x: const_cast<Decl *>(D));
7012 }
7013
7014 return ID;
7015}
7016
7017LocalDeclID ASTWriter::getDeclID(const Decl *D) {
7018 if (!D)
7019 return LocalDeclID();
7020
7021 // If D comes from an AST file, its declaration ID is already known and
7022 // fixed.
7023 if (D->isFromASTFile())
7024 return LocalDeclID(D->getGlobalID());
7025
7026 assert(DeclIDs.contains(D) && "Declaration not emitted!");
7027 return DeclIDs[D];
7028}
7029
7030bool ASTWriter::wasDeclEmitted(const Decl *D) const {
7031 assert(D);
7032
7033 assert(DoneWritingDeclsAndTypes &&
7034 "wasDeclEmitted should only be called after writing declarations");
7035
7036 if (D->isFromASTFile())
7037 return true;
7038
7039 bool Emitted = DeclIDs.contains(Val: D);
7040 assert((Emitted || (!D->getOwningModule() && isWritingStdCXXNamedModules()) ||
7041 GeneratingReducedBMI) &&
7042 "The declaration within modules can only be omitted in reduced BMI.");
7043 return Emitted;
7044}
7045
7046void ASTWriter::associateDeclWithFile(const Decl *D, LocalDeclID ID) {
7047 assert(ID.isValid());
7048 assert(D);
7049
7050 SourceLocation Loc = D->getLocation();
7051 if (Loc.isInvalid())
7052 return;
7053
7054 // We only keep track of the file-level declarations of each file.
7055 if (!D->getLexicalDeclContext()->isFileContext())
7056 return;
7057 // FIXME: ParmVarDecls that are part of a function type of a parameter of
7058 // a function/objc method, should not have TU as lexical context.
7059 // TemplateTemplateParmDecls that are part of an alias template, should not
7060 // have TU as lexical context.
7061 if (isa<ParmVarDecl, TemplateTemplateParmDecl>(Val: D))
7062 return;
7063
7064 SourceManager &SM = PP->getSourceManager();
7065 SourceLocation FileLoc = SM.getFileLoc(Loc);
7066 assert(SM.isLocalSourceLocation(FileLoc));
7067 auto [FID, Offset] = SM.getDecomposedLoc(Loc: FileLoc);
7068 if (FID.isInvalid())
7069 return;
7070 assert(SM.getSLocEntry(FID).isFile());
7071 assert(IsSLocAffecting[FID.ID]);
7072
7073 std::unique_ptr<DeclIDInFileInfo> &Info = FileDeclIDs[FID];
7074 if (!Info)
7075 Info = std::make_unique<DeclIDInFileInfo>();
7076
7077 std::pair<unsigned, LocalDeclID> LocDecl(Offset, ID);
7078 LocDeclIDsTy &Decls = Info->DeclIDs;
7079 Decls.push_back(Elt: LocDecl);
7080}
7081
7082unsigned ASTWriter::getAnonymousDeclarationNumber(const NamedDecl *D) {
7083 assert(needsAnonymousDeclarationNumber(D) &&
7084 "expected an anonymous declaration");
7085
7086 // Number the anonymous declarations within this context, if we've not
7087 // already done so.
7088 auto It = AnonymousDeclarationNumbers.find(Val: D);
7089 if (It == AnonymousDeclarationNumbers.end()) {
7090 auto *DC = D->getLexicalDeclContext();
7091 numberAnonymousDeclsWithin(DC, Visit: [&](const NamedDecl *ND, unsigned Number) {
7092 AnonymousDeclarationNumbers[ND] = Number;
7093 });
7094
7095 It = AnonymousDeclarationNumbers.find(Val: D);
7096 assert(It != AnonymousDeclarationNumbers.end() &&
7097 "declaration not found within its lexical context");
7098 }
7099
7100 return It->second;
7101}
7102
7103void ASTRecordWriter::AddDeclarationNameLoc(const DeclarationNameLoc &DNLoc,
7104 DeclarationName Name) {
7105 switch (Name.getNameKind()) {
7106 case DeclarationName::CXXConstructorName:
7107 case DeclarationName::CXXDestructorName:
7108 case DeclarationName::CXXConversionFunctionName:
7109 AddTypeSourceInfo(TInfo: DNLoc.getNamedTypeInfo());
7110 break;
7111
7112 case DeclarationName::CXXOperatorName:
7113 AddSourceRange(Range: DNLoc.getCXXOperatorNameRange());
7114 break;
7115
7116 case DeclarationName::CXXLiteralOperatorName:
7117 AddSourceLocation(Loc: DNLoc.getCXXLiteralOperatorNameLoc());
7118 break;
7119
7120 case DeclarationName::Identifier:
7121 case DeclarationName::ObjCZeroArgSelector:
7122 case DeclarationName::ObjCOneArgSelector:
7123 case DeclarationName::ObjCMultiArgSelector:
7124 case DeclarationName::CXXUsingDirective:
7125 case DeclarationName::CXXDeductionGuideName:
7126 break;
7127 }
7128}
7129
7130void ASTRecordWriter::AddDeclarationNameInfo(
7131 const DeclarationNameInfo &NameInfo) {
7132 AddDeclarationName(Name: NameInfo.getName());
7133 AddSourceLocation(Loc: NameInfo.getLoc());
7134 AddDeclarationNameLoc(DNLoc: NameInfo.getInfo(), Name: NameInfo.getName());
7135}
7136
7137void ASTRecordWriter::AddQualifierInfo(const QualifierInfo &Info) {
7138 AddNestedNameSpecifierLoc(NNS: Info.QualifierLoc);
7139 Record->push_back(Elt: Info.NumTemplParamLists);
7140 for (unsigned i = 0, e = Info.NumTemplParamLists; i != e; ++i)
7141 AddTemplateParameterList(TemplateParams: Info.TemplParamLists[i]);
7142}
7143
7144void ASTRecordWriter::AddNestedNameSpecifierLoc(
7145 NestedNameSpecifierLoc QualifierLoc) {
7146 // Nested name specifiers usually aren't too long. I think that 8 would
7147 // typically accommodate the vast majority.
7148 SmallVector<NestedNameSpecifierLoc , 8> NestedNames;
7149
7150 // Push each of the nested-name-specifiers's onto a stack for
7151 // serialization in reverse order.
7152 while (QualifierLoc) {
7153 NestedNames.push_back(Elt: QualifierLoc);
7154 QualifierLoc = QualifierLoc.getAsNamespaceAndPrefix().Prefix;
7155 }
7156
7157 Record->push_back(Elt: NestedNames.size());
7158 while(!NestedNames.empty()) {
7159 QualifierLoc = NestedNames.pop_back_val();
7160 NestedNameSpecifier Qualifier = QualifierLoc.getNestedNameSpecifier();
7161 NestedNameSpecifier::Kind Kind = Qualifier.getKind();
7162 Record->push_back(Elt: llvm::to_underlying(E: Kind));
7163 switch (Kind) {
7164 case NestedNameSpecifier::Kind::Namespace:
7165 AddDeclRef(D: Qualifier.getAsNamespaceAndPrefix().Namespace);
7166 AddSourceRange(Range: QualifierLoc.getLocalSourceRange());
7167 break;
7168
7169 case NestedNameSpecifier::Kind::Type: {
7170 TypeLoc TL = QualifierLoc.castAsTypeLoc();
7171 AddTypeRef(T: TL.getType());
7172 AddTypeLoc(TL);
7173 AddSourceLocation(Loc: QualifierLoc.getLocalSourceRange().getEnd());
7174 break;
7175 }
7176
7177 case NestedNameSpecifier::Kind::Global:
7178 AddSourceLocation(Loc: QualifierLoc.getLocalSourceRange().getEnd());
7179 break;
7180
7181 case NestedNameSpecifier::Kind::MicrosoftSuper:
7182 AddDeclRef(D: Qualifier.getAsMicrosoftSuper());
7183 AddSourceRange(Range: QualifierLoc.getLocalSourceRange());
7184 break;
7185
7186 case NestedNameSpecifier::Kind::Null:
7187 llvm_unreachable("unexpected null nested name specifier");
7188 }
7189 }
7190}
7191
7192void ASTRecordWriter::AddTemplateParameterList(
7193 const TemplateParameterList *TemplateParams) {
7194 assert(TemplateParams && "No TemplateParams!");
7195 AddSourceLocation(Loc: TemplateParams->getTemplateLoc());
7196 AddSourceLocation(Loc: TemplateParams->getLAngleLoc());
7197 AddSourceLocation(Loc: TemplateParams->getRAngleLoc());
7198
7199 Record->push_back(Elt: TemplateParams->size());
7200 for (const auto &P : *TemplateParams)
7201 AddDeclRef(D: P);
7202 if (const Expr *RequiresClause = TemplateParams->getRequiresClause()) {
7203 Record->push_back(Elt: true);
7204 writeStmtRef(S: RequiresClause);
7205 } else {
7206 Record->push_back(Elt: false);
7207 }
7208}
7209
7210/// Emit a template argument list.
7211void ASTRecordWriter::AddTemplateArgumentList(
7212 const TemplateArgumentList *TemplateArgs) {
7213 assert(TemplateArgs && "No TemplateArgs!");
7214 Record->push_back(Elt: TemplateArgs->size());
7215 for (int i = 0, e = TemplateArgs->size(); i != e; ++i)
7216 AddTemplateArgument(Arg: TemplateArgs->get(Idx: i));
7217}
7218
7219void ASTRecordWriter::AddASTTemplateArgumentListInfo(
7220 const ASTTemplateArgumentListInfo *ASTTemplArgList) {
7221 assert(ASTTemplArgList && "No ASTTemplArgList!");
7222 AddSourceLocation(Loc: ASTTemplArgList->LAngleLoc);
7223 AddSourceLocation(Loc: ASTTemplArgList->RAngleLoc);
7224 Record->push_back(Elt: ASTTemplArgList->NumTemplateArgs);
7225 const TemplateArgumentLoc *TemplArgs = ASTTemplArgList->getTemplateArgs();
7226 for (int i = 0, e = ASTTemplArgList->NumTemplateArgs; i != e; ++i)
7227 AddTemplateArgumentLoc(Arg: TemplArgs[i]);
7228}
7229
7230void ASTRecordWriter::AddUnresolvedSet(const ASTUnresolvedSet &Set) {
7231 Record->push_back(Elt: Set.size());
7232 for (ASTUnresolvedSet::const_iterator
7233 I = Set.begin(), E = Set.end(); I != E; ++I) {
7234 AddDeclRef(D: I.getDecl());
7235 Record->push_back(Elt: I.getAccess());
7236 }
7237}
7238
7239// FIXME: Move this out of the main ASTRecordWriter interface.
7240void ASTRecordWriter::AddCXXBaseSpecifier(const CXXBaseSpecifier &Base) {
7241 Record->push_back(Elt: Base.isVirtual());
7242 Record->push_back(Elt: Base.isBaseOfClass());
7243 Record->push_back(Elt: Base.getAccessSpecifierAsWritten());
7244 Record->push_back(Elt: Base.getInheritConstructors());
7245 AddTypeSourceInfo(TInfo: Base.getTypeSourceInfo());
7246 AddSourceRange(Range: Base.getSourceRange());
7247 AddSourceLocation(Loc: Base.isPackExpansion()? Base.getEllipsisLoc()
7248 : SourceLocation());
7249}
7250
7251static uint64_t EmitCXXBaseSpecifiers(ASTContext &Context, ASTWriter &W,
7252 ArrayRef<CXXBaseSpecifier> Bases) {
7253 ASTWriter::RecordData Record;
7254 ASTRecordWriter Writer(Context, W, Record);
7255 Writer.push_back(N: Bases.size());
7256
7257 for (auto &Base : Bases)
7258 Writer.AddCXXBaseSpecifier(Base);
7259
7260 return Writer.Emit(Code: serialization::DECL_CXX_BASE_SPECIFIERS);
7261}
7262
7263// FIXME: Move this out of the main ASTRecordWriter interface.
7264void ASTRecordWriter::AddCXXBaseSpecifiers(ArrayRef<CXXBaseSpecifier> Bases) {
7265 AddOffset(BitOffset: EmitCXXBaseSpecifiers(Context&: getASTContext(), W&: *Writer, Bases));
7266}
7267
7268static uint64_t
7269EmitCXXCtorInitializers(ASTContext &Context, ASTWriter &W,
7270 ArrayRef<CXXCtorInitializer *> CtorInits) {
7271 ASTWriter::RecordData Record;
7272 ASTRecordWriter Writer(Context, W, Record);
7273 Writer.push_back(N: CtorInits.size());
7274
7275 for (auto *Init : CtorInits) {
7276 if (Init->isBaseInitializer()) {
7277 Writer.push_back(N: CTOR_INITIALIZER_BASE);
7278 Writer.AddTypeSourceInfo(TInfo: Init->getTypeSourceInfo());
7279 Writer.push_back(N: Init->isBaseVirtual());
7280 } else if (Init->isDelegatingInitializer()) {
7281 Writer.push_back(N: CTOR_INITIALIZER_DELEGATING);
7282 Writer.AddTypeSourceInfo(TInfo: Init->getTypeSourceInfo());
7283 } else if (Init->isMemberInitializer()){
7284 Writer.push_back(N: CTOR_INITIALIZER_MEMBER);
7285 Writer.AddDeclRef(D: Init->getMember());
7286 } else {
7287 Writer.push_back(N: CTOR_INITIALIZER_INDIRECT_MEMBER);
7288 Writer.AddDeclRef(D: Init->getIndirectMember());
7289 }
7290
7291 Writer.AddSourceLocation(Loc: Init->getMemberLocation());
7292 Writer.AddStmt(S: Init->getInit());
7293 Writer.AddSourceLocation(Loc: Init->getLParenLoc());
7294 Writer.AddSourceLocation(Loc: Init->getRParenLoc());
7295 Writer.push_back(N: Init->isWritten());
7296 if (Init->isWritten())
7297 Writer.push_back(N: Init->getSourceOrder());
7298 }
7299
7300 return Writer.Emit(Code: serialization::DECL_CXX_CTOR_INITIALIZERS);
7301}
7302
7303// FIXME: Move this out of the main ASTRecordWriter interface.
7304void ASTRecordWriter::AddCXXCtorInitializers(
7305 ArrayRef<CXXCtorInitializer *> CtorInits) {
7306 AddOffset(BitOffset: EmitCXXCtorInitializers(Context&: getASTContext(), W&: *Writer, CtorInits));
7307}
7308
7309void ASTRecordWriter::AddCXXDefinitionData(const CXXRecordDecl *D) {
7310 auto &Data = D->data();
7311
7312 Record->push_back(Elt: Data.IsLambda);
7313
7314 BitsPacker DefinitionBits;
7315
7316#define FIELD(Name, Width, Merge) \
7317 if (!DefinitionBits.canWriteNextNBits(Width)) { \
7318 Record->push_back(DefinitionBits); \
7319 DefinitionBits.reset(0); \
7320 } \
7321 DefinitionBits.addBits(Data.Name, Width);
7322
7323#include "clang/AST/CXXRecordDeclDefinitionBits.def"
7324#undef FIELD
7325
7326 Record->push_back(Elt: DefinitionBits);
7327
7328 // getODRHash will compute the ODRHash if it has not been previously
7329 // computed.
7330 Record->push_back(Elt: D->getODRHash());
7331
7332 bool ModulesCodegen =
7333 !D->isDependentType() &&
7334 D->getTemplateSpecializationKind() !=
7335 TSK_ExplicitInstantiationDeclaration &&
7336 (Writer->getLangOpts().ModulesDebugInfo || D->isInNamedModule());
7337 Record->push_back(Elt: ModulesCodegen);
7338 if (ModulesCodegen)
7339 Writer->AddDeclRef(D, Record&: Writer->ModularCodegenDecls);
7340
7341 // IsLambda bit is already saved.
7342
7343 AddUnresolvedSet(Set: Data.Conversions.get(C&: getASTContext()));
7344 Record->push_back(Elt: Data.ComputedVisibleConversions);
7345 if (Data.ComputedVisibleConversions)
7346 AddUnresolvedSet(Set: Data.VisibleConversions.get(C&: getASTContext()));
7347 // Data.Definition is the owning decl, no need to write it.
7348
7349 if (!Data.IsLambda) {
7350 Record->push_back(Elt: Data.NumBases);
7351 if (Data.NumBases > 0)
7352 AddCXXBaseSpecifiers(Bases: Data.bases());
7353
7354 // FIXME: Make VBases lazily computed when needed to avoid storing them.
7355 Record->push_back(Elt: Data.NumVBases);
7356 if (Data.NumVBases > 0)
7357 AddCXXBaseSpecifiers(Bases: Data.vbases());
7358
7359 AddDeclRef(D: D->getFirstFriend());
7360 } else {
7361 auto &Lambda = D->getLambdaData();
7362
7363 BitsPacker LambdaBits;
7364 LambdaBits.addBits(Value: Lambda.DependencyKind, /*Width=*/BitsWidth: 2);
7365 LambdaBits.addBit(Value: Lambda.IsGenericLambda);
7366 LambdaBits.addBits(Value: Lambda.CaptureDefault, /*Width=*/BitsWidth: 2);
7367 LambdaBits.addBits(Value: Lambda.NumCaptures, /*Width=*/BitsWidth: 15);
7368 LambdaBits.addBit(Value: Lambda.HasKnownInternalLinkage);
7369 Record->push_back(Elt: LambdaBits);
7370
7371 Record->push_back(Elt: Lambda.NumExplicitCaptures);
7372 Record->push_back(Elt: Lambda.ManglingNumber);
7373 Record->push_back(Elt: D->getDeviceLambdaManglingNumber());
7374 // The lambda context declaration and index within the context are provided
7375 // separately, so that they can be used for merging.
7376 AddTypeSourceInfo(TInfo: Lambda.MethodTyInfo);
7377 for (unsigned I = 0, N = Lambda.NumCaptures; I != N; ++I) {
7378 const LambdaCapture &Capture = Lambda.Captures.front()[I];
7379 AddSourceLocation(Loc: Capture.getLocation());
7380
7381 BitsPacker CaptureBits;
7382 CaptureBits.addBit(Value: Capture.isImplicit());
7383 CaptureBits.addBits(Value: Capture.getCaptureKind(), /*Width=*/BitsWidth: 3);
7384 Record->push_back(Elt: CaptureBits);
7385
7386 switch (Capture.getCaptureKind()) {
7387 case LCK_StarThis:
7388 case LCK_This:
7389 case LCK_VLAType:
7390 break;
7391 case LCK_ByCopy:
7392 case LCK_ByRef:
7393 ValueDecl *Var =
7394 Capture.capturesVariable() ? Capture.getCapturedVar() : nullptr;
7395 AddDeclRef(D: Var);
7396 AddSourceLocation(Loc: Capture.isPackExpansion() ? Capture.getEllipsisLoc()
7397 : SourceLocation());
7398 break;
7399 }
7400 }
7401 }
7402}
7403
7404void ASTRecordWriter::AddVarDeclInit(const VarDecl *VD) {
7405 const Expr *Init = VD->getInit();
7406 if (!Init) {
7407 push_back(N: 0);
7408 return;
7409 }
7410
7411 uint64_t Val = 1;
7412 if (EvaluatedStmt *ES = VD->getEvaluatedStmt()) {
7413 // This may trigger evaluation, so run it first
7414 if (VD->hasInitWithSideEffects())
7415 Val |= 16;
7416 assert(ES->CheckedForSideEffects);
7417 Val |= (ES->HasConstantInitialization ? 2 : 0);
7418 Val |= (ES->HasConstantDestruction ? 4 : 0);
7419 APValue *Evaluated = VD->getEvaluatedValue();
7420 // If the evaluated result is constant, emit it.
7421 if (Evaluated && (Evaluated->isInt() || Evaluated->isFloat()))
7422 Val |= 8;
7423 }
7424 push_back(N: Val);
7425 if (Val & 8) {
7426 AddAPValue(Value: *VD->getEvaluatedValue());
7427 }
7428
7429 writeStmtRef(S: Init);
7430}
7431
7432void ASTWriter::ReaderInitialized(ASTReader *Reader) {
7433 assert(Reader && "Cannot remove chain");
7434 assert((!Chain || Chain == Reader) && "Cannot replace chain");
7435 assert(FirstDeclID == NextDeclID &&
7436 FirstTypeID == NextTypeID &&
7437 FirstIdentID == NextIdentID &&
7438 FirstMacroID == NextMacroID &&
7439 FirstSubmoduleID == NextSubmoduleID &&
7440 FirstSelectorID == NextSelectorID &&
7441 "Setting chain after writing has started.");
7442
7443 Chain = Reader;
7444
7445 FirstSubmoduleID = NUM_PREDEF_SUBMODULE_IDS + Chain->getTotalNumSubmodules();
7446 FirstSelectorID = NUM_PREDEF_SELECTOR_IDS + Chain->getTotalNumSelectors();
7447 NextSelectorID = FirstSelectorID;
7448 NextSubmoduleID = FirstSubmoduleID;
7449}
7450
7451void ASTWriter::IdentifierRead(IdentifierID ID, IdentifierInfo *II) {
7452 // Don't reuse Type ID from external modules for named modules. See the
7453 // comments in WriteASTCore for details.
7454 if (isWritingStdCXXNamedModules())
7455 return;
7456
7457 IdentifierID &StoredID = IdentifierIDs[II];
7458 unsigned OriginalModuleFileIndex = StoredID >> 32;
7459
7460 // Always keep the local identifier ID. See \p TypeRead() for more
7461 // information.
7462 if (OriginalModuleFileIndex == 0 && StoredID)
7463 return;
7464
7465 // Otherwise, keep the highest ID since the module file comes later has
7466 // higher module file indexes.
7467 if (ID > StoredID)
7468 StoredID = ID;
7469}
7470
7471void ASTWriter::MacroRead(serialization::MacroID ID, MacroInfo *MI) {
7472 // Always keep the highest ID. See \p TypeRead() for more information.
7473 MacroID &StoredID = MacroIDs[MI];
7474 unsigned OriginalModuleFileIndex = StoredID >> 32;
7475
7476 // Always keep the local macro ID. See \p TypeRead() for more information.
7477 if (OriginalModuleFileIndex == 0 && StoredID)
7478 return;
7479
7480 // Otherwise, keep the highest ID since the module file comes later has
7481 // higher module file indexes.
7482 if (ID > StoredID)
7483 StoredID = ID;
7484}
7485
7486void ASTWriter::TypeRead(TypeIdx Idx, QualType T) {
7487 // Don't reuse Type ID from external modules for named modules. See the
7488 // comments in WriteASTCore for details.
7489 if (isWritingStdCXXNamedModules())
7490 return;
7491
7492 // Always take the type index that comes in later module files.
7493 // This copes with an interesting
7494 // case for chained AST writing where we schedule writing the type and then,
7495 // later, deserialize the type from another AST. In this case, we want to
7496 // keep the entry from a later module so that we can properly write it out to
7497 // the AST file.
7498 TypeIdx &StoredIdx = TypeIdxs[T];
7499
7500 // Ignore it if the type comes from the current being written module file.
7501 // Since the current module file being written logically has the highest
7502 // index.
7503 unsigned ModuleFileIndex = StoredIdx.getModuleFileIndex();
7504 if (ModuleFileIndex == 0 && StoredIdx.getValue())
7505 return;
7506
7507 // Otherwise, keep the highest ID since the module file comes later has
7508 // higher module file indexes.
7509 if (Idx.getModuleFileIndex() >= StoredIdx.getModuleFileIndex())
7510 StoredIdx = Idx;
7511}
7512
7513void ASTWriter::PredefinedDeclBuilt(PredefinedDeclIDs ID, const Decl *D) {
7514 assert(D->isCanonicalDecl() && "predefined decl is not canonical");
7515 DeclIDs[D] = LocalDeclID(ID);
7516 PredefinedDecls.insert(Ptr: D);
7517}
7518
7519void ASTWriter::SelectorRead(SelectorID ID, Selector S) {
7520 // Always keep the highest ID. See \p TypeRead() for more information.
7521 SelectorID &StoredID = SelectorIDs[S];
7522 if (ID > StoredID)
7523 StoredID = ID;
7524}
7525
7526void ASTWriter::MacroDefinitionRead(serialization::PreprocessedEntityID ID,
7527 MacroDefinitionRecord *MD) {
7528 assert(!MacroDefinitions.contains(MD));
7529 MacroDefinitions[MD] = ID;
7530}
7531
7532void ASTWriter::ModuleRead(serialization::SubmoduleID ID, Module *Mod) {
7533 assert(!SubmoduleIDs.contains(Mod));
7534 SubmoduleIDs[Mod] = ID;
7535}
7536
7537void ASTWriter::CompletedTagDefinition(const TagDecl *D) {
7538 if (Chain && Chain->isProcessingUpdateRecords()) return;
7539 assert(D->isCompleteDefinition());
7540 assert(!WritingAST && "Already writing the AST!");
7541 if (auto *RD = dyn_cast<CXXRecordDecl>(Val: D)) {
7542 // We are interested when a PCH decl is modified.
7543 if (RD->isFromASTFile()) {
7544 // A forward reference was mutated into a definition. Rewrite it.
7545 // FIXME: This happens during template instantiation, should we
7546 // have created a new definition decl instead ?
7547 assert(isTemplateInstantiation(RD->getTemplateSpecializationKind()) &&
7548 "completed a tag from another module but not by instantiation?");
7549 DeclUpdates[RD].push_back(
7550 Elt: DeclUpdate(DeclUpdateKind::CXXInstantiatedClassDefinition));
7551 }
7552 }
7553}
7554
7555static bool isImportedDeclContext(ASTReader *Chain, const Decl *D) {
7556 if (D->isFromASTFile())
7557 return true;
7558
7559 // The predefined __va_list_tag struct is imported if we imported any decls.
7560 // FIXME: This is a gross hack.
7561 return D == D->getASTContext().getVaListTagDecl();
7562}
7563
7564void ASTWriter::AddedVisibleDecl(const DeclContext *DC, const Decl *D) {
7565 if (Chain && Chain->isProcessingUpdateRecords()) return;
7566 assert(DC->isLookupContext() &&
7567 "Should not add lookup results to non-lookup contexts!");
7568
7569 // TU is handled elsewhere.
7570 if (isa<TranslationUnitDecl>(Val: DC))
7571 return;
7572
7573 // Namespaces are handled elsewhere, except for template instantiations of
7574 // FunctionTemplateDecls in namespaces. We are interested in cases where the
7575 // local instantiations are added to an imported context. Only happens when
7576 // adding ADL lookup candidates, for example templated friends.
7577 if (isa<NamespaceDecl>(Val: DC) && D->getFriendObjectKind() == Decl::FOK_None &&
7578 !isa<FunctionTemplateDecl>(Val: D))
7579 return;
7580
7581 // We're only interested in cases where a local declaration is added to an
7582 // imported context.
7583 if (D->isFromASTFile() || !isImportedDeclContext(Chain, D: cast<Decl>(Val: DC)))
7584 return;
7585
7586 assert(DC == DC->getPrimaryContext() && "added to non-primary context");
7587 assert(!getDefinitiveDeclContext(DC) && "DeclContext not definitive!");
7588 assert(!WritingAST && "Already writing the AST!");
7589 if (UpdatedDeclContexts.insert(X: DC) && !cast<Decl>(Val: DC)->isFromASTFile()) {
7590 // We're adding a visible declaration to a predefined decl context. Ensure
7591 // that we write out all of its lookup results so we don't get a nasty
7592 // surprise when we try to emit its lookup table.
7593 llvm::append_range(C&: DeclsToEmitEvenIfUnreferenced, R: DC->decls());
7594 }
7595 DeclsToEmitEvenIfUnreferenced.push_back(Elt: D);
7596}
7597
7598void ASTWriter::AddedCXXImplicitMember(const CXXRecordDecl *RD, const Decl *D) {
7599 if (Chain && Chain->isProcessingUpdateRecords()) return;
7600 assert(D->isImplicit());
7601
7602 // We're only interested in cases where a local declaration is added to an
7603 // imported context.
7604 if (D->isFromASTFile() || !isImportedDeclContext(Chain, D: RD))
7605 return;
7606
7607 if (!isa<CXXMethodDecl>(Val: D))
7608 return;
7609
7610 // A decl coming from PCH was modified.
7611 assert(RD->isCompleteDefinition());
7612 assert(!WritingAST && "Already writing the AST!");
7613 DeclUpdates[RD].push_back(
7614 Elt: DeclUpdate(DeclUpdateKind::CXXAddedImplicitMember, D));
7615}
7616
7617void ASTWriter::ResolvedExceptionSpec(const FunctionDecl *FD) {
7618 if (Chain && Chain->isProcessingUpdateRecords()) return;
7619 assert(!DoneWritingDeclsAndTypes && "Already done writing updates!");
7620 if (!Chain) return;
7621 Chain->forEachImportedKeyDecl(D: FD, Visit: [&](const Decl *D) {
7622 // If we don't already know the exception specification for this redecl
7623 // chain, add an update record for it.
7624 if (isUnresolvedExceptionSpec(ESpecType: cast<FunctionDecl>(Val: D)
7625 ->getType()
7626 ->castAs<FunctionProtoType>()
7627 ->getExceptionSpecType()))
7628 DeclUpdates[D].push_back(Elt: DeclUpdateKind::CXXResolvedExceptionSpec);
7629 });
7630}
7631
7632void ASTWriter::DeducedReturnType(const FunctionDecl *FD, QualType ReturnType) {
7633 if (Chain && Chain->isProcessingUpdateRecords()) return;
7634 assert(!WritingAST && "Already writing the AST!");
7635 if (!Chain) return;
7636 Chain->forEachImportedKeyDecl(D: FD, Visit: [&](const Decl *D) {
7637 DeclUpdates[D].push_back(
7638 Elt: DeclUpdate(DeclUpdateKind::CXXDeducedReturnType, ReturnType));
7639 });
7640}
7641
7642void ASTWriter::ResolvedOperatorDelete(const CXXDestructorDecl *DD,
7643 const FunctionDecl *Delete,
7644 Expr *ThisArg) {
7645 if (Chain && Chain->isProcessingUpdateRecords()) return;
7646 assert(!WritingAST && "Already writing the AST!");
7647 assert(Delete && "Not given an operator delete");
7648 if (!Chain) return;
7649 Chain->forEachImportedKeyDecl(D: DD, Visit: [&](const Decl *D) {
7650 DeclUpdates[D].push_back(
7651 Elt: DeclUpdate(DeclUpdateKind::CXXResolvedDtorDelete, Delete));
7652 });
7653}
7654
7655void ASTWriter::ResolvedOperatorGlobDelete(const CXXDestructorDecl *DD,
7656 const FunctionDecl *GlobDelete) {
7657 if (Chain && Chain->isProcessingUpdateRecords())
7658 return;
7659 assert(!WritingAST && "Already writing the AST!");
7660 assert(GlobDelete && "Not given an operator delete");
7661 if (!Chain)
7662 return;
7663 Chain->forEachImportedKeyDecl(D: DD, Visit: [&](const Decl *D) {
7664 DeclUpdates[D].push_back(
7665 Elt: DeclUpdate(DeclUpdateKind::CXXResolvedDtorGlobDelete, GlobDelete));
7666 });
7667}
7668
7669void ASTWriter::ResolvedOperatorArrayDelete(const CXXDestructorDecl *DD,
7670 const FunctionDecl *ArrayDelete) {
7671 if (Chain && Chain->isProcessingUpdateRecords())
7672 return;
7673 assert(!WritingAST && "Already writing the AST!");
7674 assert(ArrayDelete && "Not given an operator delete");
7675 if (!Chain)
7676 return;
7677 Chain->forEachImportedKeyDecl(D: DD, Visit: [&](const Decl *D) {
7678 DeclUpdates[D].push_back(
7679 Elt: DeclUpdate(DeclUpdateKind::CXXResolvedDtorArrayDelete, ArrayDelete));
7680 });
7681}
7682
7683void ASTWriter::ResolvedOperatorGlobArrayDelete(
7684 const CXXDestructorDecl *DD, const FunctionDecl *GlobArrayDelete) {
7685 if (Chain && Chain->isProcessingUpdateRecords())
7686 return;
7687 assert(!WritingAST && "Already writing the AST!");
7688 assert(GlobArrayDelete && "Not given an operator delete");
7689 if (!Chain)
7690 return;
7691 Chain->forEachImportedKeyDecl(D: DD, Visit: [&](const Decl *D) {
7692 DeclUpdates[D].push_back(Elt: DeclUpdate(
7693 DeclUpdateKind::CXXResolvedDtorGlobArrayDelete, GlobArrayDelete));
7694 });
7695}
7696
7697void ASTWriter::CompletedImplicitDefinition(const FunctionDecl *D) {
7698 if (Chain && Chain->isProcessingUpdateRecords()) return;
7699 assert(!WritingAST && "Already writing the AST!");
7700 if (!D->isFromASTFile())
7701 return; // Declaration not imported from PCH.
7702
7703 // The function definition may not have a body due to parsing errors.
7704 if (!D->doesThisDeclarationHaveABody())
7705 return;
7706
7707 // Implicit function decl from a PCH was defined.
7708 DeclUpdates[D].push_back(
7709 Elt: DeclUpdate(DeclUpdateKind::CXXAddedFunctionDefinition));
7710}
7711
7712void ASTWriter::VariableDefinitionInstantiated(const VarDecl *D) {
7713 if (Chain && Chain->isProcessingUpdateRecords()) return;
7714 assert(!WritingAST && "Already writing the AST!");
7715 if (!D->isFromASTFile())
7716 return;
7717
7718 DeclUpdates[D].push_back(Elt: DeclUpdate(DeclUpdateKind::CXXAddedVarDefinition));
7719}
7720
7721void ASTWriter::FunctionDefinitionInstantiated(const FunctionDecl *D) {
7722 if (Chain && Chain->isProcessingUpdateRecords()) return;
7723 assert(!WritingAST && "Already writing the AST!");
7724 if (!D->isFromASTFile())
7725 return;
7726
7727 // The function definition may not have a body due to parsing errors.
7728 if (!D->doesThisDeclarationHaveABody())
7729 return;
7730
7731 DeclUpdates[D].push_back(
7732 Elt: DeclUpdate(DeclUpdateKind::CXXAddedFunctionDefinition));
7733}
7734
7735void ASTWriter::InstantiationRequested(const ValueDecl *D) {
7736 if (Chain && Chain->isProcessingUpdateRecords()) return;
7737 assert(!WritingAST && "Already writing the AST!");
7738 if (!D->isFromASTFile())
7739 return;
7740
7741 // Since the actual instantiation is delayed, this really means that we need
7742 // to update the instantiation location.
7743 SourceLocation POI;
7744 if (auto *VD = dyn_cast<VarDecl>(Val: D))
7745 POI = VD->getPointOfInstantiation();
7746 else
7747 POI = cast<FunctionDecl>(Val: D)->getPointOfInstantiation();
7748 DeclUpdates[D].push_back(
7749 Elt: DeclUpdate(DeclUpdateKind::CXXPointOfInstantiation, POI));
7750}
7751
7752void ASTWriter::DefaultArgumentInstantiated(const ParmVarDecl *D) {
7753 if (Chain && Chain->isProcessingUpdateRecords()) return;
7754 assert(!WritingAST && "Already writing the AST!");
7755 if (!D->isFromASTFile())
7756 return;
7757
7758 DeclUpdates[D].push_back(
7759 Elt: DeclUpdate(DeclUpdateKind::CXXInstantiatedDefaultArgument, D));
7760}
7761
7762void ASTWriter::DefaultMemberInitializerInstantiated(const FieldDecl *D) {
7763 assert(!WritingAST && "Already writing the AST!");
7764 if (!D->isFromASTFile())
7765 return;
7766
7767 DeclUpdates[D].push_back(
7768 Elt: DeclUpdate(DeclUpdateKind::CXXInstantiatedDefaultMemberInitializer, D));
7769}
7770
7771void ASTWriter::AddedObjCCategoryToInterface(const ObjCCategoryDecl *CatD,
7772 const ObjCInterfaceDecl *IFD) {
7773 if (Chain && Chain->isProcessingUpdateRecords()) return;
7774 assert(!WritingAST && "Already writing the AST!");
7775 if (!IFD->isFromASTFile())
7776 return; // Declaration not imported from PCH.
7777
7778 assert(IFD->getDefinition() && "Category on a class without a definition?");
7779 ObjCClassesWithCategories.insert(
7780 X: const_cast<ObjCInterfaceDecl *>(IFD->getDefinition()));
7781}
7782
7783void ASTWriter::DeclarationMarkedUsed(const Decl *D) {
7784 if (Chain && Chain->isProcessingUpdateRecords()) return;
7785 assert(!WritingAST && "Already writing the AST!");
7786
7787 // If there is *any* declaration of the entity that's not from an AST file,
7788 // we can skip writing the update record. We make sure that isUsed() triggers
7789 // completion of the redeclaration chain of the entity.
7790 for (auto Prev = D->getMostRecentDecl(); Prev; Prev = Prev->getPreviousDecl())
7791 if (IsLocalDecl(D: Prev))
7792 return;
7793
7794 DeclUpdates[D].push_back(Elt: DeclUpdate(DeclUpdateKind::DeclMarkedUsed));
7795}
7796
7797void ASTWriter::DeclarationMarkedOpenMPThreadPrivate(const Decl *D) {
7798 if (Chain && Chain->isProcessingUpdateRecords()) return;
7799 assert(!WritingAST && "Already writing the AST!");
7800 if (!D->isFromASTFile())
7801 return;
7802
7803 DeclUpdates[D].push_back(
7804 Elt: DeclUpdate(DeclUpdateKind::DeclMarkedOpenMPThreadPrivate));
7805}
7806
7807void ASTWriter::DeclarationMarkedOpenMPAllocate(const Decl *D, const Attr *A) {
7808 if (Chain && Chain->isProcessingUpdateRecords()) return;
7809 assert(!WritingAST && "Already writing the AST!");
7810 if (!D->isFromASTFile())
7811 return;
7812
7813 DeclUpdates[D].push_back(
7814 Elt: DeclUpdate(DeclUpdateKind::DeclMarkedOpenMPAllocate, A));
7815}
7816
7817void ASTWriter::DeclarationMarkedOpenMPDeclareTarget(const Decl *D,
7818 const Attr *Attr) {
7819 if (Chain && Chain->isProcessingUpdateRecords()) return;
7820 assert(!WritingAST && "Already writing the AST!");
7821 if (!D->isFromASTFile())
7822 return;
7823
7824 DeclUpdates[D].push_back(
7825 Elt: DeclUpdate(DeclUpdateKind::DeclMarkedOpenMPDeclareTarget, Attr));
7826}
7827
7828void ASTWriter::RedefinedHiddenDefinition(const NamedDecl *D, Module *M) {
7829 if (Chain && Chain->isProcessingUpdateRecords()) return;
7830 assert(!WritingAST && "Already writing the AST!");
7831 assert(!D->isUnconditionallyVisible() && "expected a hidden declaration");
7832 DeclUpdates[D].push_back(Elt: DeclUpdate(DeclUpdateKind::DeclExported, M));
7833}
7834
7835void ASTWriter::AddedAttributeToRecord(const Attr *Attr,
7836 const RecordDecl *Record) {
7837 if (Chain && Chain->isProcessingUpdateRecords()) return;
7838 assert(!WritingAST && "Already writing the AST!");
7839 if (!Record->isFromASTFile())
7840 return;
7841 DeclUpdates[Record].push_back(
7842 Elt: DeclUpdate(DeclUpdateKind::AddedAttrToRecord, Attr));
7843}
7844
7845void ASTWriter::AddedCXXTemplateSpecialization(
7846 const ClassTemplateDecl *TD, const ClassTemplateSpecializationDecl *D) {
7847 assert(!WritingAST && "Already writing the AST!");
7848
7849 if (!TD->getFirstDecl()->isFromASTFile())
7850 return;
7851 if (Chain && Chain->isProcessingUpdateRecords())
7852 return;
7853
7854 DeclsToEmitEvenIfUnreferenced.push_back(Elt: D);
7855}
7856
7857void ASTWriter::AddedCXXTemplateSpecialization(
7858 const VarTemplateDecl *TD, const VarTemplateSpecializationDecl *D) {
7859 assert(!WritingAST && "Already writing the AST!");
7860
7861 if (!TD->getFirstDecl()->isFromASTFile())
7862 return;
7863 if (Chain && Chain->isProcessingUpdateRecords())
7864 return;
7865
7866 DeclsToEmitEvenIfUnreferenced.push_back(Elt: D);
7867}
7868
7869void ASTWriter::AddedCXXTemplateSpecialization(const FunctionTemplateDecl *TD,
7870 const FunctionDecl *D) {
7871 assert(!WritingAST && "Already writing the AST!");
7872
7873 if (!TD->getFirstDecl()->isFromASTFile())
7874 return;
7875 if (Chain && Chain->isProcessingUpdateRecords())
7876 return;
7877
7878 DeclsToEmitEvenIfUnreferenced.push_back(Elt: D);
7879}
7880
7881//===----------------------------------------------------------------------===//
7882//// OMPClause Serialization
7883////===----------------------------------------------------------------------===//
7884
7885namespace {
7886
7887class OMPClauseWriter : public OMPClauseVisitor<OMPClauseWriter> {
7888 ASTRecordWriter &Record;
7889
7890public:
7891 OMPClauseWriter(ASTRecordWriter &Record) : Record(Record) {}
7892#define GEN_CLANG_CLAUSE_CLASS
7893#define CLAUSE_CLASS(Enum, Str, Class) void Visit##Class(Class *S);
7894#include "llvm/Frontend/OpenMP/OMP.inc"
7895 void writeClause(OMPClause *C);
7896 void VisitOMPClauseWithPreInit(OMPClauseWithPreInit *C);
7897 void VisitOMPClauseWithPostUpdate(OMPClauseWithPostUpdate *C);
7898};
7899
7900}
7901
7902void ASTRecordWriter::writeOMPClause(OMPClause *C) {
7903 OMPClauseWriter(*this).writeClause(C);
7904}
7905
7906void OMPClauseWriter::writeClause(OMPClause *C) {
7907 Record.push_back(N: unsigned(C->getClauseKind()));
7908 Visit(S: C);
7909 Record.AddSourceLocation(Loc: C->getBeginLoc());
7910 Record.AddSourceLocation(Loc: C->getEndLoc());
7911}
7912
7913void OMPClauseWriter::VisitOMPClauseWithPreInit(OMPClauseWithPreInit *C) {
7914 Record.push_back(N: uint64_t(C->getCaptureRegion()));
7915 Record.AddStmt(S: C->getPreInitStmt());
7916}
7917
7918void OMPClauseWriter::VisitOMPClauseWithPostUpdate(OMPClauseWithPostUpdate *C) {
7919 VisitOMPClauseWithPreInit(C);
7920 Record.AddStmt(S: C->getPostUpdateExpr());
7921}
7922
7923void OMPClauseWriter::VisitOMPIfClause(OMPIfClause *C) {
7924 VisitOMPClauseWithPreInit(C);
7925 Record.push_back(N: uint64_t(C->getNameModifier()));
7926 Record.AddSourceLocation(Loc: C->getNameModifierLoc());
7927 Record.AddSourceLocation(Loc: C->getColonLoc());
7928 Record.AddStmt(S: C->getCondition());
7929 Record.AddSourceLocation(Loc: C->getLParenLoc());
7930}
7931
7932void OMPClauseWriter::VisitOMPFinalClause(OMPFinalClause *C) {
7933 VisitOMPClauseWithPreInit(C);
7934 Record.AddStmt(S: C->getCondition());
7935 Record.AddSourceLocation(Loc: C->getLParenLoc());
7936}
7937
7938void OMPClauseWriter::VisitOMPNumThreadsClause(OMPNumThreadsClause *C) {
7939 VisitOMPClauseWithPreInit(C);
7940 Record.writeEnum(value: C->getModifier());
7941 Record.AddStmt(S: C->getNumThreads());
7942 Record.AddSourceLocation(Loc: C->getModifierLoc());
7943 Record.AddSourceLocation(Loc: C->getLParenLoc());
7944}
7945
7946void OMPClauseWriter::VisitOMPSafelenClause(OMPSafelenClause *C) {
7947 Record.AddStmt(S: C->getSafelen());
7948 Record.AddSourceLocation(Loc: C->getLParenLoc());
7949}
7950
7951void OMPClauseWriter::VisitOMPSimdlenClause(OMPSimdlenClause *C) {
7952 Record.AddStmt(S: C->getSimdlen());
7953 Record.AddSourceLocation(Loc: C->getLParenLoc());
7954}
7955
7956void OMPClauseWriter::VisitOMPSizesClause(OMPSizesClause *C) {
7957 Record.push_back(N: C->getNumSizes());
7958 for (Expr *Size : C->getSizesRefs())
7959 Record.AddStmt(S: Size);
7960 Record.AddSourceLocation(Loc: C->getLParenLoc());
7961}
7962
7963void OMPClauseWriter::VisitOMPPermutationClause(OMPPermutationClause *C) {
7964 Record.push_back(N: C->getNumLoops());
7965 for (Expr *Size : C->getArgsRefs())
7966 Record.AddStmt(S: Size);
7967 Record.AddSourceLocation(Loc: C->getLParenLoc());
7968}
7969
7970void OMPClauseWriter::VisitOMPFullClause(OMPFullClause *C) {}
7971
7972void OMPClauseWriter::VisitOMPPartialClause(OMPPartialClause *C) {
7973 Record.AddStmt(S: C->getFactor());
7974 Record.AddSourceLocation(Loc: C->getLParenLoc());
7975}
7976
7977void OMPClauseWriter::VisitOMPLoopRangeClause(OMPLoopRangeClause *C) {
7978 Record.AddStmt(S: C->getFirst());
7979 Record.AddStmt(S: C->getCount());
7980 Record.AddSourceLocation(Loc: C->getLParenLoc());
7981 Record.AddSourceLocation(Loc: C->getFirstLoc());
7982 Record.AddSourceLocation(Loc: C->getCountLoc());
7983}
7984
7985void OMPClauseWriter::VisitOMPAllocatorClause(OMPAllocatorClause *C) {
7986 Record.AddStmt(S: C->getAllocator());
7987 Record.AddSourceLocation(Loc: C->getLParenLoc());
7988}
7989
7990void OMPClauseWriter::VisitOMPCollapseClause(OMPCollapseClause *C) {
7991 Record.AddStmt(S: C->getNumForLoops());
7992 Record.AddSourceLocation(Loc: C->getLParenLoc());
7993}
7994
7995void OMPClauseWriter::VisitOMPDetachClause(OMPDetachClause *C) {
7996 Record.AddStmt(S: C->getEventHandler());
7997 Record.AddSourceLocation(Loc: C->getLParenLoc());
7998}
7999
8000void OMPClauseWriter::VisitOMPDefaultClause(OMPDefaultClause *C) {
8001 Record.push_back(N: unsigned(C->getDefaultKind()));
8002 Record.AddSourceLocation(Loc: C->getLParenLoc());
8003 Record.AddSourceLocation(Loc: C->getDefaultKindKwLoc());
8004 Record.push_back(N: unsigned(C->getDefaultVC()));
8005 Record.AddSourceLocation(Loc: C->getDefaultVCLoc());
8006}
8007
8008void OMPClauseWriter::VisitOMPThreadsetClause(OMPThreadsetClause *C) {
8009 Record.AddSourceLocation(Loc: C->getLParenLoc());
8010 Record.AddSourceLocation(Loc: C->getThreadsetKindLoc());
8011 Record.writeEnum(value: C->getThreadsetKind());
8012}
8013
8014void OMPClauseWriter::VisitOMPTransparentClause(OMPTransparentClause *C) {
8015 Record.AddSourceLocation(Loc: C->getLParenLoc());
8016 Record.AddStmt(S: C->getImpexType());
8017}
8018
8019void OMPClauseWriter::VisitOMPProcBindClause(OMPProcBindClause *C) {
8020 Record.push_back(N: unsigned(C->getProcBindKind()));
8021 Record.AddSourceLocation(Loc: C->getLParenLoc());
8022 Record.AddSourceLocation(Loc: C->getProcBindKindKwLoc());
8023}
8024
8025void OMPClauseWriter::VisitOMPScheduleClause(OMPScheduleClause *C) {
8026 VisitOMPClauseWithPreInit(C);
8027 Record.push_back(N: C->getScheduleKind());
8028 Record.push_back(N: C->getFirstScheduleModifier());
8029 Record.push_back(N: C->getSecondScheduleModifier());
8030 Record.AddStmt(S: C->getChunkSize());
8031 Record.AddSourceLocation(Loc: C->getLParenLoc());
8032 Record.AddSourceLocation(Loc: C->getFirstScheduleModifierLoc());
8033 Record.AddSourceLocation(Loc: C->getSecondScheduleModifierLoc());
8034 Record.AddSourceLocation(Loc: C->getScheduleKindLoc());
8035 Record.AddSourceLocation(Loc: C->getCommaLoc());
8036}
8037
8038void OMPClauseWriter::VisitOMPOrderedClause(OMPOrderedClause *C) {
8039 Record.push_back(N: C->getLoopNumIterations().size());
8040 Record.AddStmt(S: C->getNumForLoops());
8041 for (Expr *NumIter : C->getLoopNumIterations())
8042 Record.AddStmt(S: NumIter);
8043 for (unsigned I = 0, E = C->getLoopNumIterations().size(); I <E; ++I)
8044 Record.AddStmt(S: C->getLoopCounter(NumLoop: I));
8045 Record.AddSourceLocation(Loc: C->getLParenLoc());
8046}
8047
8048void OMPClauseWriter::VisitOMPNowaitClause(OMPNowaitClause *C) {
8049 Record.AddStmt(S: C->getCondition());
8050 Record.AddSourceLocation(Loc: C->getLParenLoc());
8051}
8052
8053void OMPClauseWriter::VisitOMPUntiedClause(OMPUntiedClause *) {}
8054
8055void OMPClauseWriter::VisitOMPMergeableClause(OMPMergeableClause *) {}
8056
8057void OMPClauseWriter::VisitOMPReadClause(OMPReadClause *) {}
8058
8059void OMPClauseWriter::VisitOMPWriteClause(OMPWriteClause *) {}
8060
8061void OMPClauseWriter::VisitOMPUpdateClause(OMPUpdateClause *C) {
8062 Record.push_back(N: C->isExtended() ? 1 : 0);
8063 if (C->isExtended()) {
8064 Record.AddSourceLocation(Loc: C->getLParenLoc());
8065 Record.AddSourceLocation(Loc: C->getArgumentLoc());
8066 Record.writeEnum(value: C->getDependencyKind());
8067 }
8068}
8069
8070void OMPClauseWriter::VisitOMPCaptureClause(OMPCaptureClause *) {}
8071
8072void OMPClauseWriter::VisitOMPCompareClause(OMPCompareClause *) {}
8073
8074// Save the parameter of fail clause.
8075void OMPClauseWriter::VisitOMPFailClause(OMPFailClause *C) {
8076 Record.AddSourceLocation(Loc: C->getLParenLoc());
8077 Record.AddSourceLocation(Loc: C->getFailParameterLoc());
8078 Record.writeEnum(value: C->getFailParameter());
8079}
8080
8081void OMPClauseWriter::VisitOMPSeqCstClause(OMPSeqCstClause *) {}
8082
8083void OMPClauseWriter::VisitOMPAcqRelClause(OMPAcqRelClause *) {}
8084
8085void OMPClauseWriter::VisitOMPAbsentClause(OMPAbsentClause *C) {
8086 Record.push_back(N: static_cast<uint64_t>(C->getDirectiveKinds().size()));
8087 Record.AddSourceLocation(Loc: C->getLParenLoc());
8088 for (auto K : C->getDirectiveKinds()) {
8089 Record.writeEnum(value: K);
8090 }
8091}
8092
8093void OMPClauseWriter::VisitOMPHoldsClause(OMPHoldsClause *C) {
8094 Record.AddStmt(S: C->getExpr());
8095 Record.AddSourceLocation(Loc: C->getLParenLoc());
8096}
8097
8098void OMPClauseWriter::VisitOMPContainsClause(OMPContainsClause *C) {
8099 Record.push_back(N: static_cast<uint64_t>(C->getDirectiveKinds().size()));
8100 Record.AddSourceLocation(Loc: C->getLParenLoc());
8101 for (auto K : C->getDirectiveKinds()) {
8102 Record.writeEnum(value: K);
8103 }
8104}
8105
8106void OMPClauseWriter::VisitOMPNoOpenMPClause(OMPNoOpenMPClause *) {}
8107
8108void OMPClauseWriter::VisitOMPNoOpenMPRoutinesClause(
8109 OMPNoOpenMPRoutinesClause *) {}
8110
8111void OMPClauseWriter::VisitOMPNoOpenMPConstructsClause(
8112 OMPNoOpenMPConstructsClause *) {}
8113
8114void OMPClauseWriter::VisitOMPNoParallelismClause(OMPNoParallelismClause *) {}
8115
8116void OMPClauseWriter::VisitOMPAcquireClause(OMPAcquireClause *) {}
8117
8118void OMPClauseWriter::VisitOMPReleaseClause(OMPReleaseClause *) {}
8119
8120void OMPClauseWriter::VisitOMPRelaxedClause(OMPRelaxedClause *) {}
8121
8122void OMPClauseWriter::VisitOMPWeakClause(OMPWeakClause *) {}
8123
8124void OMPClauseWriter::VisitOMPThreadsClause(OMPThreadsClause *) {}
8125
8126void OMPClauseWriter::VisitOMPSIMDClause(OMPSIMDClause *) {}
8127
8128void OMPClauseWriter::VisitOMPNogroupClause(OMPNogroupClause *) {}
8129
8130void OMPClauseWriter::VisitOMPInitClause(OMPInitClause *C) {
8131 Record.push_back(N: C->varlist_size());
8132 for (Expr *VE : C->varlist())
8133 Record.AddStmt(S: VE);
8134 Record.writeBool(Value: C->getIsTarget());
8135 Record.writeBool(Value: C->getIsTargetSync());
8136 Record.AddSourceLocation(Loc: C->getLParenLoc());
8137 Record.AddSourceLocation(Loc: C->getVarLoc());
8138}
8139
8140void OMPClauseWriter::VisitOMPUseClause(OMPUseClause *C) {
8141 Record.AddStmt(S: C->getInteropVar());
8142 Record.AddSourceLocation(Loc: C->getLParenLoc());
8143 Record.AddSourceLocation(Loc: C->getVarLoc());
8144}
8145
8146void OMPClauseWriter::VisitOMPDestroyClause(OMPDestroyClause *C) {
8147 Record.AddStmt(S: C->getInteropVar());
8148 Record.AddSourceLocation(Loc: C->getLParenLoc());
8149 Record.AddSourceLocation(Loc: C->getVarLoc());
8150}
8151
8152void OMPClauseWriter::VisitOMPNovariantsClause(OMPNovariantsClause *C) {
8153 VisitOMPClauseWithPreInit(C);
8154 Record.AddStmt(S: C->getCondition());
8155 Record.AddSourceLocation(Loc: C->getLParenLoc());
8156}
8157
8158void OMPClauseWriter::VisitOMPNocontextClause(OMPNocontextClause *C) {
8159 VisitOMPClauseWithPreInit(C);
8160 Record.AddStmt(S: C->getCondition());
8161 Record.AddSourceLocation(Loc: C->getLParenLoc());
8162}
8163
8164void OMPClauseWriter::VisitOMPFilterClause(OMPFilterClause *C) {
8165 VisitOMPClauseWithPreInit(C);
8166 Record.AddStmt(S: C->getThreadID());
8167 Record.AddSourceLocation(Loc: C->getLParenLoc());
8168}
8169
8170void OMPClauseWriter::VisitOMPAlignClause(OMPAlignClause *C) {
8171 Record.AddStmt(S: C->getAlignment());
8172 Record.AddSourceLocation(Loc: C->getLParenLoc());
8173}
8174
8175void OMPClauseWriter::VisitOMPPrivateClause(OMPPrivateClause *C) {
8176 Record.push_back(N: C->varlist_size());
8177 Record.AddSourceLocation(Loc: C->getLParenLoc());
8178 for (auto *VE : C->varlist()) {
8179 Record.AddStmt(S: VE);
8180 }
8181 for (auto *VE : C->private_copies()) {
8182 Record.AddStmt(S: VE);
8183 }
8184}
8185
8186void OMPClauseWriter::VisitOMPFirstprivateClause(OMPFirstprivateClause *C) {
8187 Record.push_back(N: C->varlist_size());
8188 VisitOMPClauseWithPreInit(C);
8189 Record.AddSourceLocation(Loc: C->getLParenLoc());
8190 for (auto *VE : C->varlist()) {
8191 Record.AddStmt(S: VE);
8192 }
8193 for (auto *VE : C->private_copies()) {
8194 Record.AddStmt(S: VE);
8195 }
8196 for (auto *VE : C->inits()) {
8197 Record.AddStmt(S: VE);
8198 }
8199}
8200
8201void OMPClauseWriter::VisitOMPLastprivateClause(OMPLastprivateClause *C) {
8202 Record.push_back(N: C->varlist_size());
8203 VisitOMPClauseWithPostUpdate(C);
8204 Record.AddSourceLocation(Loc: C->getLParenLoc());
8205 Record.writeEnum(value: C->getKind());
8206 Record.AddSourceLocation(Loc: C->getKindLoc());
8207 Record.AddSourceLocation(Loc: C->getColonLoc());
8208 for (auto *VE : C->varlist())
8209 Record.AddStmt(S: VE);
8210 for (auto *E : C->private_copies())
8211 Record.AddStmt(S: E);
8212 for (auto *E : C->source_exprs())
8213 Record.AddStmt(S: E);
8214 for (auto *E : C->destination_exprs())
8215 Record.AddStmt(S: E);
8216 for (auto *E : C->assignment_ops())
8217 Record.AddStmt(S: E);
8218}
8219
8220void OMPClauseWriter::VisitOMPSharedClause(OMPSharedClause *C) {
8221 Record.push_back(N: C->varlist_size());
8222 Record.AddSourceLocation(Loc: C->getLParenLoc());
8223 for (auto *VE : C->varlist())
8224 Record.AddStmt(S: VE);
8225}
8226
8227void OMPClauseWriter::VisitOMPReductionClause(OMPReductionClause *C) {
8228 Record.push_back(N: C->varlist_size());
8229 Record.writeEnum(value: C->getModifier());
8230 VisitOMPClauseWithPostUpdate(C);
8231 Record.AddSourceLocation(Loc: C->getLParenLoc());
8232 Record.AddSourceLocation(Loc: C->getModifierLoc());
8233 Record.AddSourceLocation(Loc: C->getColonLoc());
8234 Record.AddNestedNameSpecifierLoc(QualifierLoc: C->getQualifierLoc());
8235 Record.AddDeclarationNameInfo(NameInfo: C->getNameInfo());
8236 for (auto *VE : C->varlist())
8237 Record.AddStmt(S: VE);
8238 for (auto *VE : C->privates())
8239 Record.AddStmt(S: VE);
8240 for (auto *E : C->lhs_exprs())
8241 Record.AddStmt(S: E);
8242 for (auto *E : C->rhs_exprs())
8243 Record.AddStmt(S: E);
8244 for (auto *E : C->reduction_ops())
8245 Record.AddStmt(S: E);
8246 if (C->getModifier() == clang::OMPC_REDUCTION_inscan) {
8247 for (auto *E : C->copy_ops())
8248 Record.AddStmt(S: E);
8249 for (auto *E : C->copy_array_temps())
8250 Record.AddStmt(S: E);
8251 for (auto *E : C->copy_array_elems())
8252 Record.AddStmt(S: E);
8253 }
8254 auto PrivateFlags = C->private_var_reduction_flags();
8255 Record.push_back(N: std::distance(first: PrivateFlags.begin(), last: PrivateFlags.end()));
8256 for (bool Flag : PrivateFlags)
8257 Record.push_back(N: Flag);
8258}
8259
8260void OMPClauseWriter::VisitOMPTaskReductionClause(OMPTaskReductionClause *C) {
8261 Record.push_back(N: C->varlist_size());
8262 VisitOMPClauseWithPostUpdate(C);
8263 Record.AddSourceLocation(Loc: C->getLParenLoc());
8264 Record.AddSourceLocation(Loc: C->getColonLoc());
8265 Record.AddNestedNameSpecifierLoc(QualifierLoc: C->getQualifierLoc());
8266 Record.AddDeclarationNameInfo(NameInfo: C->getNameInfo());
8267 for (auto *VE : C->varlist())
8268 Record.AddStmt(S: VE);
8269 for (auto *VE : C->privates())
8270 Record.AddStmt(S: VE);
8271 for (auto *E : C->lhs_exprs())
8272 Record.AddStmt(S: E);
8273 for (auto *E : C->rhs_exprs())
8274 Record.AddStmt(S: E);
8275 for (auto *E : C->reduction_ops())
8276 Record.AddStmt(S: E);
8277}
8278
8279void OMPClauseWriter::VisitOMPInReductionClause(OMPInReductionClause *C) {
8280 Record.push_back(N: C->varlist_size());
8281 VisitOMPClauseWithPostUpdate(C);
8282 Record.AddSourceLocation(Loc: C->getLParenLoc());
8283 Record.AddSourceLocation(Loc: C->getColonLoc());
8284 Record.AddNestedNameSpecifierLoc(QualifierLoc: C->getQualifierLoc());
8285 Record.AddDeclarationNameInfo(NameInfo: C->getNameInfo());
8286 for (auto *VE : C->varlist())
8287 Record.AddStmt(S: VE);
8288 for (auto *VE : C->privates())
8289 Record.AddStmt(S: VE);
8290 for (auto *E : C->lhs_exprs())
8291 Record.AddStmt(S: E);
8292 for (auto *E : C->rhs_exprs())
8293 Record.AddStmt(S: E);
8294 for (auto *E : C->reduction_ops())
8295 Record.AddStmt(S: E);
8296 for (auto *E : C->taskgroup_descriptors())
8297 Record.AddStmt(S: E);
8298}
8299
8300void OMPClauseWriter::VisitOMPLinearClause(OMPLinearClause *C) {
8301 Record.push_back(N: C->varlist_size());
8302 VisitOMPClauseWithPostUpdate(C);
8303 Record.AddSourceLocation(Loc: C->getLParenLoc());
8304 Record.AddSourceLocation(Loc: C->getColonLoc());
8305 Record.push_back(N: C->getModifier());
8306 Record.AddSourceLocation(Loc: C->getModifierLoc());
8307 for (auto *VE : C->varlist()) {
8308 Record.AddStmt(S: VE);
8309 }
8310 for (auto *VE : C->privates()) {
8311 Record.AddStmt(S: VE);
8312 }
8313 for (auto *VE : C->inits()) {
8314 Record.AddStmt(S: VE);
8315 }
8316 for (auto *VE : C->updates()) {
8317 Record.AddStmt(S: VE);
8318 }
8319 for (auto *VE : C->finals()) {
8320 Record.AddStmt(S: VE);
8321 }
8322 Record.AddStmt(S: C->getStep());
8323 Record.AddStmt(S: C->getCalcStep());
8324 for (auto *VE : C->used_expressions())
8325 Record.AddStmt(S: VE);
8326}
8327
8328void OMPClauseWriter::VisitOMPAlignedClause(OMPAlignedClause *C) {
8329 Record.push_back(N: C->varlist_size());
8330 Record.AddSourceLocation(Loc: C->getLParenLoc());
8331 Record.AddSourceLocation(Loc: C->getColonLoc());
8332 for (auto *VE : C->varlist())
8333 Record.AddStmt(S: VE);
8334 Record.AddStmt(S: C->getAlignment());
8335}
8336
8337void OMPClauseWriter::VisitOMPCopyinClause(OMPCopyinClause *C) {
8338 Record.push_back(N: C->varlist_size());
8339 Record.AddSourceLocation(Loc: C->getLParenLoc());
8340 for (auto *VE : C->varlist())
8341 Record.AddStmt(S: VE);
8342 for (auto *E : C->source_exprs())
8343 Record.AddStmt(S: E);
8344 for (auto *E : C->destination_exprs())
8345 Record.AddStmt(S: E);
8346 for (auto *E : C->assignment_ops())
8347 Record.AddStmt(S: E);
8348}
8349
8350void OMPClauseWriter::VisitOMPCopyprivateClause(OMPCopyprivateClause *C) {
8351 Record.push_back(N: C->varlist_size());
8352 Record.AddSourceLocation(Loc: C->getLParenLoc());
8353 for (auto *VE : C->varlist())
8354 Record.AddStmt(S: VE);
8355 for (auto *E : C->source_exprs())
8356 Record.AddStmt(S: E);
8357 for (auto *E : C->destination_exprs())
8358 Record.AddStmt(S: E);
8359 for (auto *E : C->assignment_ops())
8360 Record.AddStmt(S: E);
8361}
8362
8363void OMPClauseWriter::VisitOMPFlushClause(OMPFlushClause *C) {
8364 Record.push_back(N: C->varlist_size());
8365 Record.AddSourceLocation(Loc: C->getLParenLoc());
8366 for (auto *VE : C->varlist())
8367 Record.AddStmt(S: VE);
8368}
8369
8370void OMPClauseWriter::VisitOMPDepobjClause(OMPDepobjClause *C) {
8371 Record.AddStmt(S: C->getDepobj());
8372 Record.AddSourceLocation(Loc: C->getLParenLoc());
8373}
8374
8375void OMPClauseWriter::VisitOMPDependClause(OMPDependClause *C) {
8376 Record.push_back(N: C->varlist_size());
8377 Record.push_back(N: C->getNumLoops());
8378 Record.AddSourceLocation(Loc: C->getLParenLoc());
8379 Record.AddStmt(S: C->getModifier());
8380 Record.push_back(N: C->getDependencyKind());
8381 Record.AddSourceLocation(Loc: C->getDependencyLoc());
8382 Record.AddSourceLocation(Loc: C->getColonLoc());
8383 Record.AddSourceLocation(Loc: C->getOmpAllMemoryLoc());
8384 for (auto *VE : C->varlist())
8385 Record.AddStmt(S: VE);
8386 for (unsigned I = 0, E = C->getNumLoops(); I < E; ++I)
8387 Record.AddStmt(S: C->getLoopData(NumLoop: I));
8388}
8389
8390void OMPClauseWriter::VisitOMPDeviceClause(OMPDeviceClause *C) {
8391 VisitOMPClauseWithPreInit(C);
8392 Record.writeEnum(value: C->getModifier());
8393 Record.AddStmt(S: C->getDevice());
8394 Record.AddSourceLocation(Loc: C->getModifierLoc());
8395 Record.AddSourceLocation(Loc: C->getLParenLoc());
8396}
8397
8398void OMPClauseWriter::VisitOMPMapClause(OMPMapClause *C) {
8399 Record.push_back(N: C->varlist_size());
8400 Record.push_back(N: C->getUniqueDeclarationsNum());
8401 Record.push_back(N: C->getTotalComponentListNum());
8402 Record.push_back(N: C->getTotalComponentsNum());
8403 Record.AddSourceLocation(Loc: C->getLParenLoc());
8404 bool HasIteratorModifier = false;
8405 for (unsigned I = 0; I < NumberOfOMPMapClauseModifiers; ++I) {
8406 Record.push_back(N: C->getMapTypeModifier(Cnt: I));
8407 Record.AddSourceLocation(Loc: C->getMapTypeModifierLoc(Cnt: I));
8408 if (C->getMapTypeModifier(Cnt: I) == OMPC_MAP_MODIFIER_iterator)
8409 HasIteratorModifier = true;
8410 }
8411 Record.AddNestedNameSpecifierLoc(QualifierLoc: C->getMapperQualifierLoc());
8412 Record.AddDeclarationNameInfo(NameInfo: C->getMapperIdInfo());
8413 Record.push_back(N: C->getMapType());
8414 Record.AddSourceLocation(Loc: C->getMapLoc());
8415 Record.AddSourceLocation(Loc: C->getColonLoc());
8416 for (auto *E : C->varlist())
8417 Record.AddStmt(S: E);
8418 for (auto *E : C->mapperlists())
8419 Record.AddStmt(S: E);
8420 if (HasIteratorModifier)
8421 Record.AddStmt(S: C->getIteratorModifier());
8422 for (auto *D : C->all_decls())
8423 Record.AddDeclRef(D);
8424 for (auto N : C->all_num_lists())
8425 Record.push_back(N);
8426 for (auto N : C->all_lists_sizes())
8427 Record.push_back(N);
8428 for (auto &M : C->all_components()) {
8429 Record.AddStmt(S: M.getAssociatedExpression());
8430 Record.AddDeclRef(D: M.getAssociatedDeclaration());
8431 }
8432}
8433
8434void OMPClauseWriter::VisitOMPAllocateClause(OMPAllocateClause *C) {
8435 Record.push_back(N: C->varlist_size());
8436 Record.writeEnum(value: C->getFirstAllocateModifier());
8437 Record.writeEnum(value: C->getSecondAllocateModifier());
8438 Record.AddSourceLocation(Loc: C->getLParenLoc());
8439 Record.AddSourceLocation(Loc: C->getColonLoc());
8440 Record.AddStmt(S: C->getAllocator());
8441 Record.AddStmt(S: C->getAlignment());
8442 for (auto *VE : C->varlist())
8443 Record.AddStmt(S: VE);
8444}
8445
8446void OMPClauseWriter::VisitOMPNumTeamsClause(OMPNumTeamsClause *C) {
8447 Record.push_back(N: C->varlist_size());
8448 VisitOMPClauseWithPreInit(C);
8449 Record.AddSourceLocation(Loc: C->getLParenLoc());
8450 for (auto *VE : C->varlist())
8451 Record.AddStmt(S: VE);
8452}
8453
8454void OMPClauseWriter::VisitOMPThreadLimitClause(OMPThreadLimitClause *C) {
8455 Record.push_back(N: C->varlist_size());
8456 VisitOMPClauseWithPreInit(C);
8457 Record.AddSourceLocation(Loc: C->getLParenLoc());
8458 for (auto *VE : C->varlist())
8459 Record.AddStmt(S: VE);
8460}
8461
8462void OMPClauseWriter::VisitOMPPriorityClause(OMPPriorityClause *C) {
8463 VisitOMPClauseWithPreInit(C);
8464 Record.AddStmt(S: C->getPriority());
8465 Record.AddSourceLocation(Loc: C->getLParenLoc());
8466}
8467
8468void OMPClauseWriter::VisitOMPGrainsizeClause(OMPGrainsizeClause *C) {
8469 VisitOMPClauseWithPreInit(C);
8470 Record.writeEnum(value: C->getModifier());
8471 Record.AddStmt(S: C->getGrainsize());
8472 Record.AddSourceLocation(Loc: C->getModifierLoc());
8473 Record.AddSourceLocation(Loc: C->getLParenLoc());
8474}
8475
8476void OMPClauseWriter::VisitOMPNumTasksClause(OMPNumTasksClause *C) {
8477 VisitOMPClauseWithPreInit(C);
8478 Record.writeEnum(value: C->getModifier());
8479 Record.AddStmt(S: C->getNumTasks());
8480 Record.AddSourceLocation(Loc: C->getModifierLoc());
8481 Record.AddSourceLocation(Loc: C->getLParenLoc());
8482}
8483
8484void OMPClauseWriter::VisitOMPHintClause(OMPHintClause *C) {
8485 Record.AddStmt(S: C->getHint());
8486 Record.AddSourceLocation(Loc: C->getLParenLoc());
8487}
8488
8489void OMPClauseWriter::VisitOMPDistScheduleClause(OMPDistScheduleClause *C) {
8490 VisitOMPClauseWithPreInit(C);
8491 Record.push_back(N: C->getDistScheduleKind());
8492 Record.AddStmt(S: C->getChunkSize());
8493 Record.AddSourceLocation(Loc: C->getLParenLoc());
8494 Record.AddSourceLocation(Loc: C->getDistScheduleKindLoc());
8495 Record.AddSourceLocation(Loc: C->getCommaLoc());
8496}
8497
8498void OMPClauseWriter::VisitOMPDefaultmapClause(OMPDefaultmapClause *C) {
8499 Record.push_back(N: C->getDefaultmapKind());
8500 Record.push_back(N: C->getDefaultmapModifier());
8501 Record.AddSourceLocation(Loc: C->getLParenLoc());
8502 Record.AddSourceLocation(Loc: C->getDefaultmapModifierLoc());
8503 Record.AddSourceLocation(Loc: C->getDefaultmapKindLoc());
8504}
8505
8506void OMPClauseWriter::VisitOMPToClause(OMPToClause *C) {
8507 Record.push_back(N: C->varlist_size());
8508 Record.push_back(N: C->getUniqueDeclarationsNum());
8509 Record.push_back(N: C->getTotalComponentListNum());
8510 Record.push_back(N: C->getTotalComponentsNum());
8511 Record.AddSourceLocation(Loc: C->getLParenLoc());
8512 for (unsigned I = 0; I < NumberOfOMPMotionModifiers; ++I) {
8513 Record.push_back(N: C->getMotionModifier(Cnt: I));
8514 Record.AddSourceLocation(Loc: C->getMotionModifierLoc(Cnt: I));
8515 if (C->getMotionModifier(Cnt: I) == OMPC_MOTION_MODIFIER_iterator)
8516 Record.AddStmt(S: C->getIteratorModifier());
8517 }
8518 Record.AddNestedNameSpecifierLoc(QualifierLoc: C->getMapperQualifierLoc());
8519 Record.AddDeclarationNameInfo(NameInfo: C->getMapperIdInfo());
8520 Record.AddSourceLocation(Loc: C->getColonLoc());
8521 for (auto *E : C->varlist())
8522 Record.AddStmt(S: E);
8523 for (auto *E : C->mapperlists())
8524 Record.AddStmt(S: E);
8525 for (auto *D : C->all_decls())
8526 Record.AddDeclRef(D);
8527 for (auto N : C->all_num_lists())
8528 Record.push_back(N);
8529 for (auto N : C->all_lists_sizes())
8530 Record.push_back(N);
8531 for (auto &M : C->all_components()) {
8532 Record.AddStmt(S: M.getAssociatedExpression());
8533 Record.writeBool(Value: M.isNonContiguous());
8534 Record.AddDeclRef(D: M.getAssociatedDeclaration());
8535 }
8536}
8537
8538void OMPClauseWriter::VisitOMPFromClause(OMPFromClause *C) {
8539 Record.push_back(N: C->varlist_size());
8540 Record.push_back(N: C->getUniqueDeclarationsNum());
8541 Record.push_back(N: C->getTotalComponentListNum());
8542 Record.push_back(N: C->getTotalComponentsNum());
8543 Record.AddSourceLocation(Loc: C->getLParenLoc());
8544 for (unsigned I = 0; I < NumberOfOMPMotionModifiers; ++I) {
8545 Record.push_back(N: C->getMotionModifier(Cnt: I));
8546 Record.AddSourceLocation(Loc: C->getMotionModifierLoc(Cnt: I));
8547 if (C->getMotionModifier(Cnt: I) == OMPC_MOTION_MODIFIER_iterator)
8548 Record.AddStmt(S: C->getIteratorModifier());
8549 }
8550 Record.AddNestedNameSpecifierLoc(QualifierLoc: C->getMapperQualifierLoc());
8551 Record.AddDeclarationNameInfo(NameInfo: C->getMapperIdInfo());
8552 Record.AddSourceLocation(Loc: C->getColonLoc());
8553 for (auto *E : C->varlist())
8554 Record.AddStmt(S: E);
8555 for (auto *E : C->mapperlists())
8556 Record.AddStmt(S: E);
8557 for (auto *D : C->all_decls())
8558 Record.AddDeclRef(D);
8559 for (auto N : C->all_num_lists())
8560 Record.push_back(N);
8561 for (auto N : C->all_lists_sizes())
8562 Record.push_back(N);
8563 for (auto &M : C->all_components()) {
8564 Record.AddStmt(S: M.getAssociatedExpression());
8565 Record.writeBool(Value: M.isNonContiguous());
8566 Record.AddDeclRef(D: M.getAssociatedDeclaration());
8567 }
8568}
8569
8570void OMPClauseWriter::VisitOMPUseDevicePtrClause(OMPUseDevicePtrClause *C) {
8571 Record.push_back(N: C->varlist_size());
8572 Record.push_back(N: C->getUniqueDeclarationsNum());
8573 Record.push_back(N: C->getTotalComponentListNum());
8574 Record.push_back(N: C->getTotalComponentsNum());
8575 Record.AddSourceLocation(Loc: C->getLParenLoc());
8576 Record.writeEnum(value: C->getFallbackModifier());
8577 Record.AddSourceLocation(Loc: C->getFallbackModifierLoc());
8578 for (auto *E : C->varlist())
8579 Record.AddStmt(S: E);
8580 for (auto *VE : C->private_copies())
8581 Record.AddStmt(S: VE);
8582 for (auto *VE : C->inits())
8583 Record.AddStmt(S: VE);
8584 for (auto *D : C->all_decls())
8585 Record.AddDeclRef(D);
8586 for (auto N : C->all_num_lists())
8587 Record.push_back(N);
8588 for (auto N : C->all_lists_sizes())
8589 Record.push_back(N);
8590 for (auto &M : C->all_components()) {
8591 Record.AddStmt(S: M.getAssociatedExpression());
8592 Record.AddDeclRef(D: M.getAssociatedDeclaration());
8593 }
8594}
8595
8596void OMPClauseWriter::VisitOMPUseDeviceAddrClause(OMPUseDeviceAddrClause *C) {
8597 Record.push_back(N: C->varlist_size());
8598 Record.push_back(N: C->getUniqueDeclarationsNum());
8599 Record.push_back(N: C->getTotalComponentListNum());
8600 Record.push_back(N: C->getTotalComponentsNum());
8601 Record.AddSourceLocation(Loc: C->getLParenLoc());
8602 for (auto *E : C->varlist())
8603 Record.AddStmt(S: E);
8604 for (auto *D : C->all_decls())
8605 Record.AddDeclRef(D);
8606 for (auto N : C->all_num_lists())
8607 Record.push_back(N);
8608 for (auto N : C->all_lists_sizes())
8609 Record.push_back(N);
8610 for (auto &M : C->all_components()) {
8611 Record.AddStmt(S: M.getAssociatedExpression());
8612 Record.AddDeclRef(D: M.getAssociatedDeclaration());
8613 }
8614}
8615
8616void OMPClauseWriter::VisitOMPIsDevicePtrClause(OMPIsDevicePtrClause *C) {
8617 Record.push_back(N: C->varlist_size());
8618 Record.push_back(N: C->getUniqueDeclarationsNum());
8619 Record.push_back(N: C->getTotalComponentListNum());
8620 Record.push_back(N: C->getTotalComponentsNum());
8621 Record.AddSourceLocation(Loc: C->getLParenLoc());
8622 for (auto *E : C->varlist())
8623 Record.AddStmt(S: E);
8624 for (auto *D : C->all_decls())
8625 Record.AddDeclRef(D);
8626 for (auto N : C->all_num_lists())
8627 Record.push_back(N);
8628 for (auto N : C->all_lists_sizes())
8629 Record.push_back(N);
8630 for (auto &M : C->all_components()) {
8631 Record.AddStmt(S: M.getAssociatedExpression());
8632 Record.AddDeclRef(D: M.getAssociatedDeclaration());
8633 }
8634}
8635
8636void OMPClauseWriter::VisitOMPHasDeviceAddrClause(OMPHasDeviceAddrClause *C) {
8637 Record.push_back(N: C->varlist_size());
8638 Record.push_back(N: C->getUniqueDeclarationsNum());
8639 Record.push_back(N: C->getTotalComponentListNum());
8640 Record.push_back(N: C->getTotalComponentsNum());
8641 Record.AddSourceLocation(Loc: C->getLParenLoc());
8642 for (auto *E : C->varlist())
8643 Record.AddStmt(S: E);
8644 for (auto *D : C->all_decls())
8645 Record.AddDeclRef(D);
8646 for (auto N : C->all_num_lists())
8647 Record.push_back(N);
8648 for (auto N : C->all_lists_sizes())
8649 Record.push_back(N);
8650 for (auto &M : C->all_components()) {
8651 Record.AddStmt(S: M.getAssociatedExpression());
8652 Record.AddDeclRef(D: M.getAssociatedDeclaration());
8653 }
8654}
8655
8656void OMPClauseWriter::VisitOMPUnifiedAddressClause(OMPUnifiedAddressClause *) {}
8657
8658void OMPClauseWriter::VisitOMPUnifiedSharedMemoryClause(
8659 OMPUnifiedSharedMemoryClause *) {}
8660
8661void OMPClauseWriter::VisitOMPReverseOffloadClause(OMPReverseOffloadClause *) {}
8662
8663void
8664OMPClauseWriter::VisitOMPDynamicAllocatorsClause(OMPDynamicAllocatorsClause *) {
8665}
8666
8667void OMPClauseWriter::VisitOMPAtomicDefaultMemOrderClause(
8668 OMPAtomicDefaultMemOrderClause *C) {
8669 Record.push_back(N: C->getAtomicDefaultMemOrderKind());
8670 Record.AddSourceLocation(Loc: C->getLParenLoc());
8671 Record.AddSourceLocation(Loc: C->getAtomicDefaultMemOrderKindKwLoc());
8672}
8673
8674void OMPClauseWriter::VisitOMPSelfMapsClause(OMPSelfMapsClause *) {}
8675
8676void OMPClauseWriter::VisitOMPAtClause(OMPAtClause *C) {
8677 Record.push_back(N: C->getAtKind());
8678 Record.AddSourceLocation(Loc: C->getLParenLoc());
8679 Record.AddSourceLocation(Loc: C->getAtKindKwLoc());
8680}
8681
8682void OMPClauseWriter::VisitOMPSeverityClause(OMPSeverityClause *C) {
8683 Record.push_back(N: C->getSeverityKind());
8684 Record.AddSourceLocation(Loc: C->getLParenLoc());
8685 Record.AddSourceLocation(Loc: C->getSeverityKindKwLoc());
8686}
8687
8688void OMPClauseWriter::VisitOMPMessageClause(OMPMessageClause *C) {
8689 VisitOMPClauseWithPreInit(C);
8690 Record.AddStmt(S: C->getMessageString());
8691 Record.AddSourceLocation(Loc: C->getLParenLoc());
8692}
8693
8694void OMPClauseWriter::VisitOMPNontemporalClause(OMPNontemporalClause *C) {
8695 Record.push_back(N: C->varlist_size());
8696 Record.AddSourceLocation(Loc: C->getLParenLoc());
8697 for (auto *VE : C->varlist())
8698 Record.AddStmt(S: VE);
8699 for (auto *E : C->private_refs())
8700 Record.AddStmt(S: E);
8701}
8702
8703void OMPClauseWriter::VisitOMPInclusiveClause(OMPInclusiveClause *C) {
8704 Record.push_back(N: C->varlist_size());
8705 Record.AddSourceLocation(Loc: C->getLParenLoc());
8706 for (auto *VE : C->varlist())
8707 Record.AddStmt(S: VE);
8708}
8709
8710void OMPClauseWriter::VisitOMPExclusiveClause(OMPExclusiveClause *C) {
8711 Record.push_back(N: C->varlist_size());
8712 Record.AddSourceLocation(Loc: C->getLParenLoc());
8713 for (auto *VE : C->varlist())
8714 Record.AddStmt(S: VE);
8715}
8716
8717void OMPClauseWriter::VisitOMPOrderClause(OMPOrderClause *C) {
8718 Record.writeEnum(value: C->getKind());
8719 Record.writeEnum(value: C->getModifier());
8720 Record.AddSourceLocation(Loc: C->getLParenLoc());
8721 Record.AddSourceLocation(Loc: C->getKindKwLoc());
8722 Record.AddSourceLocation(Loc: C->getModifierKwLoc());
8723}
8724
8725void OMPClauseWriter::VisitOMPUsesAllocatorsClause(OMPUsesAllocatorsClause *C) {
8726 Record.push_back(N: C->getNumberOfAllocators());
8727 Record.AddSourceLocation(Loc: C->getLParenLoc());
8728 for (unsigned I = 0, E = C->getNumberOfAllocators(); I < E; ++I) {
8729 OMPUsesAllocatorsClause::Data Data = C->getAllocatorData(I);
8730 Record.AddStmt(S: Data.Allocator);
8731 Record.AddStmt(S: Data.AllocatorTraits);
8732 Record.AddSourceLocation(Loc: Data.LParenLoc);
8733 Record.AddSourceLocation(Loc: Data.RParenLoc);
8734 }
8735}
8736
8737void OMPClauseWriter::VisitOMPAffinityClause(OMPAffinityClause *C) {
8738 Record.push_back(N: C->varlist_size());
8739 Record.AddSourceLocation(Loc: C->getLParenLoc());
8740 Record.AddStmt(S: C->getModifier());
8741 Record.AddSourceLocation(Loc: C->getColonLoc());
8742 for (Expr *E : C->varlist())
8743 Record.AddStmt(S: E);
8744}
8745
8746void OMPClauseWriter::VisitOMPBindClause(OMPBindClause *C) {
8747 Record.writeEnum(value: C->getBindKind());
8748 Record.AddSourceLocation(Loc: C->getLParenLoc());
8749 Record.AddSourceLocation(Loc: C->getBindKindLoc());
8750}
8751
8752void OMPClauseWriter::VisitOMPXDynCGroupMemClause(OMPXDynCGroupMemClause *C) {
8753 VisitOMPClauseWithPreInit(C);
8754 Record.AddStmt(S: C->getSize());
8755 Record.AddSourceLocation(Loc: C->getLParenLoc());
8756}
8757
8758void OMPClauseWriter::VisitOMPDynGroupprivateClause(
8759 OMPDynGroupprivateClause *C) {
8760 VisitOMPClauseWithPreInit(C);
8761 Record.push_back(N: C->getDynGroupprivateModifier());
8762 Record.push_back(N: C->getDynGroupprivateFallbackModifier());
8763 Record.AddStmt(S: C->getSize());
8764 Record.AddSourceLocation(Loc: C->getLParenLoc());
8765 Record.AddSourceLocation(Loc: C->getDynGroupprivateModifierLoc());
8766 Record.AddSourceLocation(Loc: C->getDynGroupprivateFallbackModifierLoc());
8767}
8768
8769void OMPClauseWriter::VisitOMPDoacrossClause(OMPDoacrossClause *C) {
8770 Record.push_back(N: C->varlist_size());
8771 Record.push_back(N: C->getNumLoops());
8772 Record.AddSourceLocation(Loc: C->getLParenLoc());
8773 Record.push_back(N: C->getDependenceType());
8774 Record.AddSourceLocation(Loc: C->getDependenceLoc());
8775 Record.AddSourceLocation(Loc: C->getColonLoc());
8776 for (auto *VE : C->varlist())
8777 Record.AddStmt(S: VE);
8778 for (unsigned I = 0, E = C->getNumLoops(); I < E; ++I)
8779 Record.AddStmt(S: C->getLoopData(NumLoop: I));
8780}
8781
8782void OMPClauseWriter::VisitOMPXAttributeClause(OMPXAttributeClause *C) {
8783 Record.AddAttributes(Attrs: C->getAttrs());
8784 Record.AddSourceLocation(Loc: C->getBeginLoc());
8785 Record.AddSourceLocation(Loc: C->getLParenLoc());
8786 Record.AddSourceLocation(Loc: C->getEndLoc());
8787}
8788
8789void OMPClauseWriter::VisitOMPXBareClause(OMPXBareClause *C) {}
8790
8791void ASTRecordWriter::writeOMPTraitInfo(const OMPTraitInfo *TI) {
8792 writeUInt32(Value: TI->Sets.size());
8793 for (const auto &Set : TI->Sets) {
8794 writeEnum(value: Set.Kind);
8795 writeUInt32(Value: Set.Selectors.size());
8796 for (const auto &Selector : Set.Selectors) {
8797 writeEnum(value: Selector.Kind);
8798 writeBool(Value: Selector.ScoreOrCondition);
8799 if (Selector.ScoreOrCondition)
8800 writeExprRef(value: Selector.ScoreOrCondition);
8801 writeUInt32(Value: Selector.Properties.size());
8802 for (const auto &Property : Selector.Properties)
8803 writeEnum(value: Property.Kind);
8804 }
8805 }
8806}
8807
8808void ASTRecordWriter::writeOMPChildren(OMPChildren *Data) {
8809 if (!Data)
8810 return;
8811 writeUInt32(Value: Data->getNumClauses());
8812 writeUInt32(Value: Data->getNumChildren());
8813 writeBool(Value: Data->hasAssociatedStmt());
8814 for (unsigned I = 0, E = Data->getNumClauses(); I < E; ++I)
8815 writeOMPClause(C: Data->getClauses()[I]);
8816 if (Data->hasAssociatedStmt())
8817 AddStmt(S: Data->getAssociatedStmt());
8818 for (unsigned I = 0, E = Data->getNumChildren(); I < E; ++I)
8819 AddStmt(S: Data->getChildren()[I]);
8820}
8821
8822void ASTRecordWriter::writeOpenACCVarList(const OpenACCClauseWithVarList *C) {
8823 writeUInt32(Value: C->getVarList().size());
8824 for (Expr *E : C->getVarList())
8825 AddStmt(S: E);
8826}
8827
8828void ASTRecordWriter::writeOpenACCIntExprList(ArrayRef<Expr *> Exprs) {
8829 writeUInt32(Value: Exprs.size());
8830 for (Expr *E : Exprs)
8831 AddStmt(S: E);
8832}
8833
8834void ASTRecordWriter::writeOpenACCClause(const OpenACCClause *C) {
8835 writeEnum(value: C->getClauseKind());
8836 writeSourceLocation(Loc: C->getBeginLoc());
8837 writeSourceLocation(Loc: C->getEndLoc());
8838
8839 switch (C->getClauseKind()) {
8840 case OpenACCClauseKind::Default: {
8841 const auto *DC = cast<OpenACCDefaultClause>(Val: C);
8842 writeSourceLocation(Loc: DC->getLParenLoc());
8843 writeEnum(value: DC->getDefaultClauseKind());
8844 return;
8845 }
8846 case OpenACCClauseKind::If: {
8847 const auto *IC = cast<OpenACCIfClause>(Val: C);
8848 writeSourceLocation(Loc: IC->getLParenLoc());
8849 AddStmt(S: const_cast<Expr*>(IC->getConditionExpr()));
8850 return;
8851 }
8852 case OpenACCClauseKind::Self: {
8853 const auto *SC = cast<OpenACCSelfClause>(Val: C);
8854 writeSourceLocation(Loc: SC->getLParenLoc());
8855 writeBool(Value: SC->isConditionExprClause());
8856 if (SC->isConditionExprClause()) {
8857 writeBool(Value: SC->hasConditionExpr());
8858 if (SC->hasConditionExpr())
8859 AddStmt(S: const_cast<Expr *>(SC->getConditionExpr()));
8860 } else {
8861 writeUInt32(Value: SC->getVarList().size());
8862 for (Expr *E : SC->getVarList())
8863 AddStmt(S: E);
8864 }
8865 return;
8866 }
8867 case OpenACCClauseKind::NumGangs: {
8868 const auto *NGC = cast<OpenACCNumGangsClause>(Val: C);
8869 writeSourceLocation(Loc: NGC->getLParenLoc());
8870 writeUInt32(Value: NGC->getIntExprs().size());
8871 for (Expr *E : NGC->getIntExprs())
8872 AddStmt(S: E);
8873 return;
8874 }
8875 case OpenACCClauseKind::DeviceNum: {
8876 const auto *DNC = cast<OpenACCDeviceNumClause>(Val: C);
8877 writeSourceLocation(Loc: DNC->getLParenLoc());
8878 AddStmt(S: const_cast<Expr*>(DNC->getIntExpr()));
8879 return;
8880 }
8881 case OpenACCClauseKind::DefaultAsync: {
8882 const auto *DAC = cast<OpenACCDefaultAsyncClause>(Val: C);
8883 writeSourceLocation(Loc: DAC->getLParenLoc());
8884 AddStmt(S: const_cast<Expr *>(DAC->getIntExpr()));
8885 return;
8886 }
8887 case OpenACCClauseKind::NumWorkers: {
8888 const auto *NWC = cast<OpenACCNumWorkersClause>(Val: C);
8889 writeSourceLocation(Loc: NWC->getLParenLoc());
8890 AddStmt(S: const_cast<Expr*>(NWC->getIntExpr()));
8891 return;
8892 }
8893 case OpenACCClauseKind::VectorLength: {
8894 const auto *NWC = cast<OpenACCVectorLengthClause>(Val: C);
8895 writeSourceLocation(Loc: NWC->getLParenLoc());
8896 AddStmt(S: const_cast<Expr*>(NWC->getIntExpr()));
8897 return;
8898 }
8899 case OpenACCClauseKind::Private: {
8900 const auto *PC = cast<OpenACCPrivateClause>(Val: C);
8901 writeSourceLocation(Loc: PC->getLParenLoc());
8902 writeOpenACCVarList(C: PC);
8903
8904 for (const OpenACCPrivateRecipe &R : PC->getInitRecipes()) {
8905 static_assert(sizeof(R) == 1 * sizeof(int *));
8906 AddDeclRef(D: R.AllocaDecl);
8907 }
8908 return;
8909 }
8910 case OpenACCClauseKind::Host: {
8911 const auto *HC = cast<OpenACCHostClause>(Val: C);
8912 writeSourceLocation(Loc: HC->getLParenLoc());
8913 writeOpenACCVarList(C: HC);
8914 return;
8915 }
8916 case OpenACCClauseKind::Device: {
8917 const auto *DC = cast<OpenACCDeviceClause>(Val: C);
8918 writeSourceLocation(Loc: DC->getLParenLoc());
8919 writeOpenACCVarList(C: DC);
8920 return;
8921 }
8922 case OpenACCClauseKind::FirstPrivate: {
8923 const auto *FPC = cast<OpenACCFirstPrivateClause>(Val: C);
8924 writeSourceLocation(Loc: FPC->getLParenLoc());
8925 writeOpenACCVarList(C: FPC);
8926
8927 for (const OpenACCFirstPrivateRecipe &R : FPC->getInitRecipes()) {
8928 static_assert(sizeof(R) == 2 * sizeof(int *));
8929 AddDeclRef(D: R.AllocaDecl);
8930 AddDeclRef(D: R.InitFromTemporary);
8931 }
8932 return;
8933 }
8934 case OpenACCClauseKind::Attach: {
8935 const auto *AC = cast<OpenACCAttachClause>(Val: C);
8936 writeSourceLocation(Loc: AC->getLParenLoc());
8937 writeOpenACCVarList(C: AC);
8938 return;
8939 }
8940 case OpenACCClauseKind::Detach: {
8941 const auto *DC = cast<OpenACCDetachClause>(Val: C);
8942 writeSourceLocation(Loc: DC->getLParenLoc());
8943 writeOpenACCVarList(C: DC);
8944 return;
8945 }
8946 case OpenACCClauseKind::Delete: {
8947 const auto *DC = cast<OpenACCDeleteClause>(Val: C);
8948 writeSourceLocation(Loc: DC->getLParenLoc());
8949 writeOpenACCVarList(C: DC);
8950 return;
8951 }
8952 case OpenACCClauseKind::UseDevice: {
8953 const auto *UDC = cast<OpenACCUseDeviceClause>(Val: C);
8954 writeSourceLocation(Loc: UDC->getLParenLoc());
8955 writeOpenACCVarList(C: UDC);
8956 return;
8957 }
8958 case OpenACCClauseKind::DevicePtr: {
8959 const auto *DPC = cast<OpenACCDevicePtrClause>(Val: C);
8960 writeSourceLocation(Loc: DPC->getLParenLoc());
8961 writeOpenACCVarList(C: DPC);
8962 return;
8963 }
8964 case OpenACCClauseKind::NoCreate: {
8965 const auto *NCC = cast<OpenACCNoCreateClause>(Val: C);
8966 writeSourceLocation(Loc: NCC->getLParenLoc());
8967 writeOpenACCVarList(C: NCC);
8968 return;
8969 }
8970 case OpenACCClauseKind::Present: {
8971 const auto *PC = cast<OpenACCPresentClause>(Val: C);
8972 writeSourceLocation(Loc: PC->getLParenLoc());
8973 writeOpenACCVarList(C: PC);
8974 return;
8975 }
8976 case OpenACCClauseKind::Copy:
8977 case OpenACCClauseKind::PCopy:
8978 case OpenACCClauseKind::PresentOrCopy: {
8979 const auto *CC = cast<OpenACCCopyClause>(Val: C);
8980 writeSourceLocation(Loc: CC->getLParenLoc());
8981 writeEnum(value: CC->getModifierList());
8982 writeOpenACCVarList(C: CC);
8983 return;
8984 }
8985 case OpenACCClauseKind::CopyIn:
8986 case OpenACCClauseKind::PCopyIn:
8987 case OpenACCClauseKind::PresentOrCopyIn: {
8988 const auto *CIC = cast<OpenACCCopyInClause>(Val: C);
8989 writeSourceLocation(Loc: CIC->getLParenLoc());
8990 writeEnum(value: CIC->getModifierList());
8991 writeOpenACCVarList(C: CIC);
8992 return;
8993 }
8994 case OpenACCClauseKind::CopyOut:
8995 case OpenACCClauseKind::PCopyOut:
8996 case OpenACCClauseKind::PresentOrCopyOut: {
8997 const auto *COC = cast<OpenACCCopyOutClause>(Val: C);
8998 writeSourceLocation(Loc: COC->getLParenLoc());
8999 writeEnum(value: COC->getModifierList());
9000 writeOpenACCVarList(C: COC);
9001 return;
9002 }
9003 case OpenACCClauseKind::Create:
9004 case OpenACCClauseKind::PCreate:
9005 case OpenACCClauseKind::PresentOrCreate: {
9006 const auto *CC = cast<OpenACCCreateClause>(Val: C);
9007 writeSourceLocation(Loc: CC->getLParenLoc());
9008 writeEnum(value: CC->getModifierList());
9009 writeOpenACCVarList(C: CC);
9010 return;
9011 }
9012 case OpenACCClauseKind::Async: {
9013 const auto *AC = cast<OpenACCAsyncClause>(Val: C);
9014 writeSourceLocation(Loc: AC->getLParenLoc());
9015 writeBool(Value: AC->hasIntExpr());
9016 if (AC->hasIntExpr())
9017 AddStmt(S: const_cast<Expr*>(AC->getIntExpr()));
9018 return;
9019 }
9020 case OpenACCClauseKind::Wait: {
9021 const auto *WC = cast<OpenACCWaitClause>(Val: C);
9022 writeSourceLocation(Loc: WC->getLParenLoc());
9023 writeBool(Value: WC->getDevNumExpr());
9024 if (Expr *DNE = WC->getDevNumExpr())
9025 AddStmt(S: DNE);
9026 writeSourceLocation(Loc: WC->getQueuesLoc());
9027
9028 writeOpenACCIntExprList(Exprs: WC->getQueueIdExprs());
9029 return;
9030 }
9031 case OpenACCClauseKind::DeviceType:
9032 case OpenACCClauseKind::DType: {
9033 const auto *DTC = cast<OpenACCDeviceTypeClause>(Val: C);
9034 writeSourceLocation(Loc: DTC->getLParenLoc());
9035 writeUInt32(Value: DTC->getArchitectures().size());
9036 for (const DeviceTypeArgument &Arg : DTC->getArchitectures()) {
9037 writeBool(Value: Arg.getIdentifierInfo());
9038 if (Arg.getIdentifierInfo())
9039 AddIdentifierRef(II: Arg.getIdentifierInfo());
9040 writeSourceLocation(Loc: Arg.getLoc());
9041 }
9042 return;
9043 }
9044 case OpenACCClauseKind::Reduction: {
9045 const auto *RC = cast<OpenACCReductionClause>(Val: C);
9046 writeSourceLocation(Loc: RC->getLParenLoc());
9047 writeEnum(value: RC->getReductionOp());
9048 writeOpenACCVarList(C: RC);
9049
9050 for (const OpenACCReductionRecipe &R : RC->getRecipes()) {
9051 AddDeclRef(D: R.AllocaDecl);
9052
9053 static_assert(sizeof(OpenACCReductionRecipe::CombinerRecipe) ==
9054 3 * sizeof(int *));
9055 writeUInt32(Value: R.CombinerRecipes.size());
9056
9057 for (auto &CombinerRecipe : R.CombinerRecipes) {
9058 AddDeclRef(D: CombinerRecipe.LHS);
9059 AddDeclRef(D: CombinerRecipe.RHS);
9060 AddStmt(S: CombinerRecipe.Op);
9061 }
9062 }
9063 return;
9064 }
9065 case OpenACCClauseKind::Seq:
9066 case OpenACCClauseKind::Independent:
9067 case OpenACCClauseKind::NoHost:
9068 case OpenACCClauseKind::Auto:
9069 case OpenACCClauseKind::Finalize:
9070 case OpenACCClauseKind::IfPresent:
9071 // Nothing to do here, there is no additional information beyond the
9072 // begin/end loc and clause kind.
9073 return;
9074 case OpenACCClauseKind::Collapse: {
9075 const auto *CC = cast<OpenACCCollapseClause>(Val: C);
9076 writeSourceLocation(Loc: CC->getLParenLoc());
9077 writeBool(Value: CC->hasForce());
9078 AddStmt(S: const_cast<Expr *>(CC->getLoopCount()));
9079 return;
9080 }
9081 case OpenACCClauseKind::Tile: {
9082 const auto *TC = cast<OpenACCTileClause>(Val: C);
9083 writeSourceLocation(Loc: TC->getLParenLoc());
9084 writeUInt32(Value: TC->getSizeExprs().size());
9085 for (Expr *E : TC->getSizeExprs())
9086 AddStmt(S: E);
9087 return;
9088 }
9089 case OpenACCClauseKind::Gang: {
9090 const auto *GC = cast<OpenACCGangClause>(Val: C);
9091 writeSourceLocation(Loc: GC->getLParenLoc());
9092 writeUInt32(Value: GC->getNumExprs());
9093 for (unsigned I = 0; I < GC->getNumExprs(); ++I) {
9094 writeEnum(value: GC->getExpr(I).first);
9095 AddStmt(S: const_cast<Expr *>(GC->getExpr(I).second));
9096 }
9097 return;
9098 }
9099 case OpenACCClauseKind::Worker: {
9100 const auto *WC = cast<OpenACCWorkerClause>(Val: C);
9101 writeSourceLocation(Loc: WC->getLParenLoc());
9102 writeBool(Value: WC->hasIntExpr());
9103 if (WC->hasIntExpr())
9104 AddStmt(S: const_cast<Expr *>(WC->getIntExpr()));
9105 return;
9106 }
9107 case OpenACCClauseKind::Vector: {
9108 const auto *VC = cast<OpenACCVectorClause>(Val: C);
9109 writeSourceLocation(Loc: VC->getLParenLoc());
9110 writeBool(Value: VC->hasIntExpr());
9111 if (VC->hasIntExpr())
9112 AddStmt(S: const_cast<Expr *>(VC->getIntExpr()));
9113 return;
9114 }
9115 case OpenACCClauseKind::Link: {
9116 const auto *LC = cast<OpenACCLinkClause>(Val: C);
9117 writeSourceLocation(Loc: LC->getLParenLoc());
9118 writeOpenACCVarList(C: LC);
9119 return;
9120 }
9121 case OpenACCClauseKind::DeviceResident: {
9122 const auto *DRC = cast<OpenACCDeviceResidentClause>(Val: C);
9123 writeSourceLocation(Loc: DRC->getLParenLoc());
9124 writeOpenACCVarList(C: DRC);
9125 return;
9126 }
9127
9128 case OpenACCClauseKind::Bind: {
9129 const auto *BC = cast<OpenACCBindClause>(Val: C);
9130 writeSourceLocation(Loc: BC->getLParenLoc());
9131 writeBool(Value: BC->isStringArgument());
9132 if (BC->isStringArgument())
9133 AddStmt(S: const_cast<StringLiteral *>(BC->getStringArgument()));
9134 else
9135 AddIdentifierRef(II: BC->getIdentifierArgument());
9136
9137 return;
9138 }
9139 case OpenACCClauseKind::Invalid:
9140 case OpenACCClauseKind::Shortloop:
9141 llvm_unreachable("Clause serialization not yet implemented");
9142 }
9143 llvm_unreachable("Invalid Clause Kind");
9144}
9145
9146void ASTRecordWriter::writeOpenACCClauseList(
9147 ArrayRef<const OpenACCClause *> Clauses) {
9148 for (const OpenACCClause *Clause : Clauses)
9149 writeOpenACCClause(C: Clause);
9150}
9151void ASTRecordWriter::AddOpenACCRoutineDeclAttr(
9152 const OpenACCRoutineDeclAttr *A) {
9153 // We have to write the size so that the reader can do a resize. Unlike the
9154 // Decl version of this, we can't count on trailing storage to get this right.
9155 writeUInt32(Value: A->Clauses.size());
9156 writeOpenACCClauseList(Clauses: A->Clauses);
9157}
9158