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

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