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