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