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

source code of clang/lib/Serialization/ASTWriter.cpp