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 guides are not found by name lookup. Keep them in the general
4321 // lookup table so that Sema can consider all reachable deduction guides,
4322 // including when instantiating an exported template that uses a
4323 // non-exported class template.
4325 return false;
4326
4327 if (auto *FTD = dyn_cast<FunctionTemplateDecl>(D))
4328 if (isa<CXXDeductionGuideDecl>(FTD->getTemplatedDecl()))
4329 return false;
4330
4331 if (D->getFormalLinkage() != Linkage::Module)
4332 return false;
4333
4334 // It is hard for the serializer to judge if the in-class friend declaration
4335 // is visible or not, so we just transfer the task to Sema. It should be a
4336 // safe decision since Sema is able to handle the lookup rules for in-class
4337 // friend declarations good enough already.
4338 if (D->getFriendObjectKind() &&
4340 return false;
4341
4342 return true;
4343}
4344
4345static bool isTULocalInNamedModules(NamedDecl *D) {
4346 Module *NamedModule = D->getTopLevelOwningNamedModule();
4347 if (!NamedModule)
4348 return false;
4349
4350 // For none-top level decls, we choose to move it to the general visible
4351 // lookup table. Since the consumer may get its parent somehow and performs
4352 // a lookup in it (considering looking up the operator function in lambda).
4353 // The difference between module local lookup table and TU local lookup table
4354 // is, the consumers still have a chance to lookup in the module local lookup
4355 // table but **now** the consumers won't read the TU local lookup table if
4356 // the consumer is not the original TU.
4357 //
4358 // FIXME: It seems to be an optimization chance (and also a more correct
4359 // semantics) to remain the TULocal lookup table and performing similar lookup
4360 // with the module local lookup table except that we only allow the lookups
4361 // with the same module unit.
4363 return false;
4364
4365 return D->getLinkageInternal() == Linkage::Internal;
4366}
4367
4368class ASTDeclContextNameLookupTrait
4369 : public ASTDeclContextNameTrivialLookupTrait {
4370public:
4371 using TULocalDeclsMapTy = llvm::DenseMap<key_type, DeclIDsTy>;
4372
4373 using ModuleLevelDeclsMapTy =
4374 llvm::DenseMap<ModuleLevelNameLookupTrait::key_type, DeclIDsTy>;
4375
4376private:
4377 enum class LookupVisibility {
4378 GenerallyVisibile,
4379 // The decls can only be found by other TU in the same module.
4380 // Note a clang::Module models a module unit instead of logical module
4381 // in C++20.
4382 ModuleLocalVisible,
4383 // The decls can only be found by the TU itself that defines it.
4384 TULocal,
4385 };
4386
4387 LookupVisibility getLookupVisibility(NamedDecl *D) const {
4388 // Only named modules have other lookup visibility.
4389 if (!Writer.isWritingStdCXXNamedModules())
4390 return LookupVisibility::GenerallyVisibile;
4391
4392 if (isModuleLocalDecl(D))
4393 return LookupVisibility::ModuleLocalVisible;
4394 if (isTULocalInNamedModules(D))
4395 return LookupVisibility::TULocal;
4396
4397 // A trick to handle enum constants. The enum constants is special since
4398 // they can be found directly without their parent context. This makes it
4399 // tricky to decide if an EnumConstantDecl is visible or not by their own
4400 // visibilities. E.g., for a class member, we can assume it is visible if
4401 // the user get its parent somehow. But for an enum constant, the users may
4402 // access if without its parent context. Although we can fix the problem in
4403 // Sema lookup process, it might be too complex, we just make a trick here.
4404 // Note that we only removes enum constant from the lookup table from its
4405 // parent of parent. We DON'T remove the enum constant from its parent. So
4406 // we don't need to care about merging problems here.
4407 if (auto *ECD = dyn_cast<EnumConstantDecl>(D);
4408 ECD && DC.isFileContext() && ECD->getTopLevelOwningNamedModule()) {
4409 if (llvm::all_of(
4410 DC.noload_lookup(
4411 cast<EnumDecl>(ECD->getDeclContext())->getDeclName()),
4412 [](auto *Found) {
4413 return Found->isInvisibleOutsideTheOwningModule();
4414 }))
4415 return ECD->isFromExplicitGlobalModule() ||
4416 ECD->isInAnonymousNamespace()
4417 ? LookupVisibility::TULocal
4418 : LookupVisibility::ModuleLocalVisible;
4419 }
4420
4421 return LookupVisibility::GenerallyVisibile;
4422 }
4423
4424 DeclContext &DC;
4425 ModuleLevelDeclsMapTy ModuleLocalDeclsMap;
4426 TULocalDeclsMapTy TULocalDeclsMap;
4427
4428public:
4429 using ASTDeclContextNameTrivialLookupTrait::
4430 ASTDeclContextNameTrivialLookupTrait;
4431
4432 ASTDeclContextNameLookupTrait(ASTWriter &Writer, DeclContext &DC)
4433 : ASTDeclContextNameTrivialLookupTrait(Writer), DC(DC) {}
4434
4435 template <typename Coll> data_type getData(const Coll &Decls) {
4436 unsigned Start = DeclIDs.size();
4437 auto AddDecl = [this](NamedDecl *D) {
4438 NamedDecl *DeclForLocalLookup =
4440
4441 if (Writer.getDoneWritingDeclsAndTypes() &&
4442 !Writer.wasDeclEmitted(DeclForLocalLookup))
4443 return;
4444
4445 // Try to avoid writing internal decls to reduced BMI.
4446 // See comments in ASTWriter::WriteDeclContextLexicalBlock for details.
4447 if (Writer.isGeneratingReducedBMI() &&
4448 !DeclForLocalLookup->isFromExplicitGlobalModule() &&
4449 IsInternalDeclFromFileContext(DeclForLocalLookup))
4450 return;
4451
4452 auto ID = Writer.GetDeclRef(DeclForLocalLookup);
4453
4454 switch (getLookupVisibility(DeclForLocalLookup)) {
4455 case LookupVisibility::ModuleLocalVisible:
4456 if (UnsignedOrNone PrimaryModuleHash =
4458 auto Key = std::make_pair(D->getDeclName(), *PrimaryModuleHash);
4459 auto Iter = ModuleLocalDeclsMap.find(Key);
4460 if (Iter == ModuleLocalDeclsMap.end())
4461 ModuleLocalDeclsMap.insert({Key, DeclIDsTy{ID}});
4462 else
4463 Iter->second.push_back(ID);
4464 return;
4465 }
4466 break;
4467 case LookupVisibility::TULocal: {
4468 auto Iter = TULocalDeclsMap.find(D->getDeclName());
4469 if (Iter == TULocalDeclsMap.end())
4470 TULocalDeclsMap.insert({D->getDeclName(), DeclIDsTy{ID}});
4471 else
4472 Iter->second.push_back(ID);
4473 return;
4474 }
4475 case LookupVisibility::GenerallyVisibile:
4476 // Generally visible decls go into the general lookup table.
4477 break;
4478 }
4479
4480 DeclIDs.push_back(ID);
4481 };
4482 ASTReader *Chain = Writer.getChain();
4483 for (NamedDecl *D : Decls) {
4484 if (Chain && isa<NamespaceDecl>(D) && D->isFromASTFile() &&
4485 D == Chain->getKeyDeclaration(D)) {
4486 // In ASTReader, we stored only the key declaration of a namespace decl
4487 // for this TU. If we have an external namespace decl, this is that
4488 // key declaration and we need to re-expand it to write out the first
4489 // decl from each module.
4490 //
4491 // See comment 'ASTReader::FindExternalVisibleDeclsByName' for details.
4492 auto Firsts =
4493 Writer.CollectFirstDeclFromEachModule(D, /*IncludeLocal=*/false);
4494 for (const auto &[_, First] : Firsts)
4495 AddDecl(cast<NamedDecl>(const_cast<Decl *>(First)));
4496 } else {
4497 AddDecl(D);
4498 }
4499 }
4500 return std::make_pair(Start, DeclIDs.size());
4501 }
4502
4503 const ModuleLevelDeclsMapTy &getModuleLocalDecls() {
4504 return ModuleLocalDeclsMap;
4505 }
4506
4507 const TULocalDeclsMapTy &getTULocalDecls() { return TULocalDeclsMap; }
4508};
4509
4510} // namespace
4511
4512namespace {
4513class LazySpecializationInfoLookupTrait {
4514 ASTWriter &Writer;
4515 llvm::SmallVector<serialization::reader::LazySpecializationInfo, 64> Specs;
4516
4517public:
4518 using key_type = unsigned;
4519 using key_type_ref = key_type;
4520
4521 /// A start and end index into Specs, representing a sequence of decls.
4522 using data_type = std::pair<unsigned, unsigned>;
4523 using data_type_ref = const data_type &;
4524
4525 using hash_value_type = unsigned;
4526 using offset_type = unsigned;
4527
4528 explicit LazySpecializationInfoLookupTrait(ASTWriter &Writer)
4529 : Writer(Writer) {}
4530
4531 template <typename Col, typename Col2>
4532 data_type getData(Col &&C, Col2 &ExistingInfo) {
4533 unsigned Start = Specs.size();
4534 for (auto *D : C) {
4535 NamedDecl *ND = getDeclForLocalLookup(Writer.getLangOpts(),
4536 const_cast<NamedDecl *>(D));
4537 Specs.push_back(GlobalDeclID(Writer.GetDeclRef(ND).getRawValue()));
4538 }
4540 ExistingInfo)
4541 Specs.push_back(Info);
4542 return std::make_pair(Start, Specs.size());
4543 }
4544
4545 data_type ImportData(
4547 unsigned Start = Specs.size();
4548 for (auto ID : FromReader)
4549 Specs.push_back(ID);
4550 return std::make_pair(Start, Specs.size());
4551 }
4552
4553 static bool EqualKey(key_type_ref a, key_type_ref b) { return a == b; }
4554
4555 hash_value_type ComputeHash(key_type Name) { return Name; }
4556
4557 void EmitFileRef(raw_ostream &Out, ModuleFile *F) const {
4558 assert(Writer.hasChain() &&
4559 "have reference to loaded module file but no chain?");
4560
4561 using namespace llvm::support;
4562 Writer.addTouchedModuleFile(F);
4563 endian::write<uint32_t>(Out, Writer.getChain()->getModuleFileID(F),
4564 llvm::endianness::little);
4565 }
4566
4567 std::pair<unsigned, unsigned> EmitKeyDataLength(raw_ostream &Out,
4568 key_type HashValue,
4569 data_type_ref Lookup) {
4570 // 4 bytes for each slot.
4571 unsigned KeyLen = 4;
4572 unsigned DataLen = sizeof(serialization::reader::LazySpecializationInfo) *
4573 (Lookup.second - Lookup.first);
4574
4575 return emitULEBKeyDataLength(KeyLen, DataLen, Out);
4576 }
4577
4578 void EmitKey(raw_ostream &Out, key_type HashValue, unsigned) {
4579 using namespace llvm::support;
4580
4581 endian::Writer LE(Out, llvm::endianness::little);
4582 LE.write<uint32_t>(HashValue);
4583 }
4584
4585 void EmitData(raw_ostream &Out, key_type_ref, data_type Lookup,
4586 unsigned DataLen) {
4587 using namespace llvm::support;
4588
4589 endian::Writer LE(Out, llvm::endianness::little);
4590 uint64_t Start = Out.tell();
4591 (void)Start;
4592 for (unsigned I = Lookup.first, N = Lookup.second; I != N; ++I) {
4593 LE.write<DeclID>(Specs[I].getRawValue());
4594 }
4595 assert(Out.tell() - Start == DataLen && "Data length is wrong");
4596 }
4597};
4598
4599unsigned CalculateODRHashForSpecs(const Decl *Spec) {
4600 ArrayRef<TemplateArgument> Args;
4601 if (auto *CTSD = dyn_cast<ClassTemplateSpecializationDecl>(Spec))
4602 Args = CTSD->getTemplateArgs().asArray();
4603 else if (auto *VTSD = dyn_cast<VarTemplateSpecializationDecl>(Spec))
4604 Args = VTSD->getTemplateArgs().asArray();
4605 else if (auto *FD = dyn_cast<FunctionDecl>(Spec))
4606 Args = FD->getTemplateSpecializationArgs()->asArray();
4607 else
4608 llvm_unreachable("New Specialization Kind?");
4609
4610 return StableHashForTemplateArguments(Args);
4611}
4612} // namespace
4613
4614void ASTWriter::GenerateSpecializationInfoLookupTable(
4615 const NamedDecl *D, llvm::SmallVectorImpl<const Decl *> &Specializations,
4616 llvm::SmallVectorImpl<char> &LookupTable, bool IsPartial) {
4617 assert(D->isFirstDecl());
4618
4619 // Create the on-disk hash table representation.
4620 MultiOnDiskHashTableGenerator<reader::LazySpecializationInfoLookupTrait,
4621 LazySpecializationInfoLookupTrait>
4622 Generator;
4623 LazySpecializationInfoLookupTrait Trait(*this);
4624
4625 llvm::MapVector<unsigned, llvm::SmallVector<const NamedDecl *, 4>>
4626 SpecializationMaps;
4627
4628 for (auto *Specialization : Specializations) {
4629 unsigned HashedValue = CalculateODRHashForSpecs(Specialization);
4630
4631 auto Iter = SpecializationMaps.find(HashedValue);
4632 if (Iter == SpecializationMaps.end())
4633 Iter = SpecializationMaps
4634 .try_emplace(HashedValue,
4635 llvm::SmallVector<const NamedDecl *, 4>())
4636 .first;
4637
4638 Iter->second.push_back(cast<NamedDecl>(Specialization));
4639 }
4640
4641 auto *Lookups =
4642 Chain ? Chain->getLoadedSpecializationsLookupTables(D, IsPartial)
4643 : nullptr;
4644
4645 for (auto &[HashValue, Specs] : SpecializationMaps) {
4646 SmallVector<serialization::reader::LazySpecializationInfo, 16>
4647 ExisitingSpecs;
4648 // We have to merge the lookup table manually here. We can't depend on the
4649 // merge mechanism offered by
4650 // clang::serialization::MultiOnDiskHashTableGenerator since that generator
4651 // assumes the we'll get the same value with the same key.
4652 // And also underlying llvm::OnDiskChainedHashTableGenerator assumes that we
4653 // won't insert the values with the same key twice. So we have to merge the
4654 // lookup table here manually.
4655 if (Lookups)
4656 ExisitingSpecs = Lookups->Table.find(HashValue);
4657
4658 Generator.insert(HashValue, Trait.getData(Specs, ExisitingSpecs), Trait);
4659 }
4660
4661 // Reduced BMI may not emit everything in the lookup table,
4662 // If Reduced BMI **partially** emits some decls,
4663 // then the generator may not emit the corresponding entry for the
4664 // corresponding name is already there. See
4665 // MultiOnDiskHashTableGenerator::insert and
4666 // MultiOnDiskHashTableGenerator::emit for details.
4667 // So we won't emit the lookup table if we're generating reduced BMI.
4668 auto *ToEmitMaybeMergedLookupTable =
4669 (!isGeneratingReducedBMI() && Lookups) ? &Lookups->Table : nullptr;
4670 Generator.emit(LookupTable, Trait, ToEmitMaybeMergedLookupTable);
4671}
4672
4673uint64_t ASTWriter::WriteSpecializationInfoLookupTable(
4674 const NamedDecl *D, llvm::SmallVectorImpl<const Decl *> &Specializations,
4675 bool IsPartial) {
4676
4677 llvm::SmallString<4096> LookupTable;
4678 GenerateSpecializationInfoLookupTable(D, Specializations, LookupTable,
4679 IsPartial);
4680
4681 uint64_t Offset = Stream.GetCurrentBitNo();
4682 RecordData::value_type Record[] = {static_cast<RecordData::value_type>(
4684 Stream.EmitRecordWithBlob(IsPartial ? DeclPartialSpecializationsAbbrev
4685 : DeclSpecializationsAbbrev,
4686 Record, LookupTable);
4687
4688 return Offset;
4689}
4690
4691/// Returns true if all of the lookup result are either external, not emitted or
4692/// predefined. In such cases, the lookup result is not interesting and we don't
4693/// need to record the result in the current being written module. Return false
4694/// otherwise.
4697 for (auto *D : Result.getLookupResult()) {
4698 auto *LocalD = getDeclForLocalLookup(Writer.getLangOpts(), D);
4699 if (LocalD->isFromASTFile())
4700 continue;
4701
4702 // We can only be sure whether the local declaration is reachable
4703 // after we done writing the declarations and types.
4704 if (Writer.getDoneWritingDeclsAndTypes() && !Writer.wasDeclEmitted(LocalD))
4705 continue;
4706
4707 // We don't need to emit the predefined decls.
4708 if (Writer.isDeclPredefined(LocalD))
4709 continue;
4710
4711 return false;
4712 }
4713
4714 return true;
4715}
4716
4717void ASTWriter::GenerateNameLookupTable(
4718 ASTContext &Context, const DeclContext *ConstDC,
4719 llvm::SmallVectorImpl<char> &LookupTable,
4720 llvm::SmallVectorImpl<char> &ModuleLocalLookupTable,
4721 llvm::SmallVectorImpl<char> &TULookupTable) {
4722 assert(!ConstDC->hasLazyLocalLexicalLookups() &&
4723 !ConstDC->hasLazyExternalLexicalLookups() &&
4724 "must call buildLookups first");
4725
4726 // FIXME: We need to build the lookups table, which is logically const.
4727 auto *DC = const_cast<DeclContext*>(ConstDC);
4728 assert(DC == DC->getPrimaryContext() && "only primary DC has lookup table");
4729
4730 // Create the on-disk hash table representation.
4731 MultiOnDiskHashTableGenerator<reader::ASTDeclContextNameLookupTrait,
4732 ASTDeclContextNameLookupTrait>
4733 Generator;
4734 ASTDeclContextNameLookupTrait Trait(*this, *DC);
4735
4736 // The first step is to collect the declaration names which we need to
4737 // serialize into the name lookup table, and to collect them in a stable
4738 // order.
4739 SmallVector<DeclarationName, 16> Names;
4740
4741 // We also track whether we're writing out the DeclarationNameKey for
4742 // constructors or conversion functions.
4743 bool IncludeConstructorNames = false;
4744 bool IncludeConversionNames = false;
4745
4746 for (auto &[Name, Result] : *DC->buildLookup()) {
4747 // If there are no local declarations in our lookup result, we
4748 // don't need to write an entry for the name at all. If we can't
4749 // write out a lookup set without performing more deserialization,
4750 // just skip this entry.
4751 //
4752 // Also in reduced BMI, we'd like to avoid writing unreachable
4753 // declarations in GMF, so we need to avoid writing declarations
4754 // that entirely external or unreachable.
4755 if (GeneratingReducedBMI && isLookupResultNotInteresting(*this, Result))
4756 continue;
4757 // We also skip empty results. If any of the results could be external and
4758 // the currently available results are empty, then all of the results are
4759 // external and we skip it above. So the only way we get here with an empty
4760 // results is when no results could have been external *and* we have
4761 // external results.
4762 //
4763 // FIXME: While we might want to start emitting on-disk entries for negative
4764 // lookups into a decl context as an optimization, today we *have* to skip
4765 // them because there are names with empty lookup results in decl contexts
4766 // which we can't emit in any stable ordering: we lookup constructors and
4767 // conversion functions in the enclosing namespace scope creating empty
4768 // results for them. This in almost certainly a bug in Clang's name lookup,
4769 // but that is likely to be hard or impossible to fix and so we tolerate it
4770 // here by omitting lookups with empty results.
4771 if (Result.getLookupResult().empty())
4772 continue;
4773
4774 switch (Name.getNameKind()) {
4775 default:
4776 Names.push_back(Name);
4777 break;
4778
4780 IncludeConstructorNames = true;
4781 break;
4782
4784 IncludeConversionNames = true;
4785 break;
4786 }
4787 }
4788
4789 // Sort the names into a stable order.
4790 llvm::sort(Names);
4791
4792 if (IncludeConstructorNames || IncludeConversionNames) {
4793 // We need to establish an ordering of constructor and conversion function
4794 // names, and they don't have an intrinsic ordering. We also need to write
4795 // out all constructor and conversion function results if we write out any
4796 // of them, because they're all tracked under the same lookup key.
4797 llvm::SmallPtrSet<DeclarationName, 8> AddedNames;
4798 for (Decl *ChildD : cast<CXXRecordDecl>(DC)->decls()) {
4799 if (auto *ChildND = dyn_cast<NamedDecl>(ChildD)) {
4800 auto Name = ChildND->getDeclName();
4801 switch (Name.getNameKind()) {
4802 default:
4803 continue;
4804
4806 if (!IncludeConstructorNames)
4807 continue;
4808 break;
4809
4811 if (!IncludeConversionNames)
4812 continue;
4813 break;
4814 }
4815 if (AddedNames.insert(Name).second)
4816 Names.push_back(Name);
4817 }
4818 }
4819 }
4820 // Next we need to do a lookup with each name into this decl context to fully
4821 // populate any results from external sources. We don't actually use the
4822 // results of these lookups because we only want to use the results after all
4823 // results have been loaded and the pointers into them will be stable.
4824 for (auto &Name : Names)
4825 DC->lookup(Name);
4826
4827 // Now we need to insert the results for each name into the hash table. For
4828 // constructor names and conversion function names, we actually need to merge
4829 // all of the results for them into one list of results each and insert
4830 // those.
4831 SmallVector<NamedDecl *, 8> ConstructorDecls;
4832 SmallVector<NamedDecl *, 8> ConversionDecls;
4833
4834 // Now loop over the names, either inserting them or appending for the two
4835 // special cases.
4836 for (auto &Name : Names) {
4838
4839 switch (Name.getNameKind()) {
4840 default:
4841 Generator.insert(Name, Trait.getData(Result), Trait);
4842 break;
4843
4845 ConstructorDecls.append(Result.begin(), Result.end());
4846 break;
4847
4849 ConversionDecls.append(Result.begin(), Result.end());
4850 break;
4851 }
4852 }
4853
4854 // Handle our two special cases if we ended up having any. We arbitrarily use
4855 // the first declaration's name here because the name itself isn't part of
4856 // the key, only the kind of name is used.
4857 if (!ConstructorDecls.empty())
4858 Generator.insert(ConstructorDecls.front()->getDeclName(),
4859 Trait.getData(ConstructorDecls), Trait);
4860 if (!ConversionDecls.empty())
4861 Generator.insert(ConversionDecls.front()->getDeclName(),
4862 Trait.getData(ConversionDecls), Trait);
4863
4864 // Create the on-disk hash table. Also emit the existing imported and
4865 // merged table if there is one.
4866 auto *Lookups = Chain ? Chain->getLoadedLookupTables(DC) : nullptr;
4867 // Reduced BMI may not emit everything in the lookup table,
4868 // If Reduced BMI **partially** emits some decls,
4869 // then the generator may not emit the corresponding entry for the
4870 // corresponding name is already there. See
4871 // MultiOnDiskHashTableGenerator::insert and
4872 // MultiOnDiskHashTableGenerator::emit for details.
4873 // So we won't emit the lookup table if we're generating reduced BMI.
4874 auto *ToEmitMaybeMergedLookupTable =
4875 (!isGeneratingReducedBMI() && Lookups) ? &Lookups->Table : nullptr;
4876 Generator.emit(LookupTable, Trait, ToEmitMaybeMergedLookupTable);
4877
4878 const auto &ModuleLocalDecls = Trait.getModuleLocalDecls();
4879 if (!ModuleLocalDecls.empty()) {
4880 MultiOnDiskHashTableGenerator<reader::ModuleLocalNameLookupTrait,
4881 ModuleLevelNameLookupTrait>
4882 ModuleLocalLookupGenerator;
4883 ModuleLevelNameLookupTrait ModuleLocalTrait(*this);
4884
4885 for (const auto &ModuleLocalIter : ModuleLocalDecls) {
4886 const auto &Key = ModuleLocalIter.first;
4887 const auto &IDs = ModuleLocalIter.second;
4888 ModuleLocalLookupGenerator.insert(Key, ModuleLocalTrait.getData(IDs),
4889 ModuleLocalTrait);
4890 }
4891
4892 // See the above comment. We won't emit the merged table if we're generating
4893 // reduced BMI.
4894 auto *ModuleLocalLookups =
4895 (isGeneratingReducedBMI() && Chain &&
4896 Chain->getModuleLocalLookupTables(DC))
4897 ? &Chain->getModuleLocalLookupTables(DC)->Table
4898 : nullptr;
4899 ModuleLocalLookupGenerator.emit(ModuleLocalLookupTable, ModuleLocalTrait,
4900 ModuleLocalLookups);
4901 }
4902
4903 const auto &TULocalDecls = Trait.getTULocalDecls();
4904 if (!TULocalDecls.empty() && !isGeneratingReducedBMI()) {
4905 MultiOnDiskHashTableGenerator<reader::ASTDeclContextNameLookupTrait,
4906 ASTDeclContextNameTrivialLookupTrait>
4907 TULookupGenerator;
4908 ASTDeclContextNameTrivialLookupTrait TULocalTrait(*this);
4909
4910 for (const auto &TULocalIter : TULocalDecls) {
4911 const auto &Key = TULocalIter.first;
4912 const auto &IDs = TULocalIter.second;
4913 TULookupGenerator.insert(Key, TULocalTrait.getData(IDs), TULocalTrait);
4914 }
4915
4916 // See the above comment. We won't emit the merged table if we're generating
4917 // reduced BMI.
4918 auto *TULocalLookups =
4919 (isGeneratingReducedBMI() && Chain && Chain->getTULocalLookupTables(DC))
4920 ? &Chain->getTULocalLookupTables(DC)->Table
4921 : nullptr;
4922 TULookupGenerator.emit(TULookupTable, TULocalTrait, TULocalLookups);
4923 }
4924}
4925
4926/// Write the block containing all of the declaration IDs
4927/// visible from the given DeclContext.
4928///
4929/// \returns the offset of the DECL_CONTEXT_VISIBLE block within the
4930/// bitstream, or 0 if no block was written.
4931void ASTWriter::WriteDeclContextVisibleBlock(
4932 ASTContext &Context, DeclContext *DC, VisibleLookupBlockOffsets &Offsets) {
4933 assert(!Offsets);
4934
4935 // If we imported a key declaration of this namespace, write the visible
4936 // lookup results as an update record for it rather than including them
4937 // on this declaration. We will only look at key declarations on reload.
4938 if (isa<NamespaceDecl>(DC) && Chain &&
4940 // Only do this once, for the first local declaration of the namespace.
4941 for (auto *Prev = cast<NamespaceDecl>(DC)->getPreviousDecl(); Prev;
4942 Prev = Prev->getPreviousDecl())
4943 if (!Prev->isFromASTFile())
4944 return;
4945
4946 // Note that we need to emit an update record for the primary context.
4947 UpdatedDeclContexts.insert(DC->getPrimaryContext());
4948
4949 // Make sure all visible decls are written. They will be recorded later. We
4950 // do this using a side data structure so we can sort the names into
4951 // a deterministic order.
4952 StoredDeclsMap *Map = DC->getPrimaryContext()->buildLookup();
4953 SmallVector<std::pair<DeclarationName, DeclContext::lookup_result>, 16>
4954 LookupResults;
4955 if (Map) {
4956 LookupResults.reserve(Map->size());
4957 for (auto &Entry : *Map)
4958 LookupResults.push_back(
4959 std::make_pair(Entry.first, Entry.second.getLookupResult()));
4960 }
4961
4962 llvm::sort(LookupResults, llvm::less_first());
4963 for (auto &NameAndResult : LookupResults) {
4964 DeclarationName Name = NameAndResult.first;
4965 DeclContext::lookup_result Result = NameAndResult.second;
4968 // We have to work around a name lookup bug here where negative lookup
4969 // results for these names get cached in namespace lookup tables (these
4970 // names should never be looked up in a namespace).
4971 assert(Result.empty() && "Cannot have a constructor or conversion "
4972 "function name in a namespace!");
4973 continue;
4974 }
4975
4976 for (NamedDecl *ND : Result) {
4977 if (ND->isFromASTFile())
4978 continue;
4979
4980 if (DoneWritingDeclsAndTypes && !wasDeclEmitted(ND))
4981 continue;
4982
4983 // We don't need to force emitting internal decls into reduced BMI.
4984 // See comments in ASTWriter::WriteDeclContextLexicalBlock for details.
4985 if (GeneratingReducedBMI && !ND->isFromExplicitGlobalModule() &&
4987 continue;
4988
4989 GetDeclRef(ND);
4990 }
4991 }
4992
4993 return;
4994 }
4995
4996 if (DC->getPrimaryContext() != DC)
4997 return;
4998
4999 // Skip contexts which don't support name lookup.
5000 if (!DC->isLookupContext())
5001 return;
5002
5003 // If not in C++, we perform name lookup for the translation unit via the
5004 // IdentifierInfo chains, don't bother to build a visible-declarations table.
5005 if (DC->isTranslationUnit() && !Context.getLangOpts().CPlusPlus)
5006 return;
5007
5008 // Serialize the contents of the mapping used for lookup. Note that,
5009 // although we have two very different code paths, the serialized
5010 // representation is the same for both cases: a declaration name,
5011 // followed by a size, followed by references to the visible
5012 // declarations that have that name.
5013 StoredDeclsMap *Map = DC->buildLookup();
5014 if (!Map || Map->empty())
5015 return;
5016
5017 Offsets.VisibleOffset = Stream.GetCurrentBitNo();
5018 // Create the on-disk hash table in a buffer.
5019 SmallString<4096> LookupTable;
5020 SmallString<4096> ModuleLocalLookupTable;
5021 SmallString<4096> TULookupTable;
5022 GenerateNameLookupTable(Context, DC, LookupTable, ModuleLocalLookupTable,
5023 TULookupTable);
5024
5025 // Write the lookup table
5026 RecordData::value_type Record[] = {DECL_CONTEXT_VISIBLE};
5027 Stream.EmitRecordWithBlob(DeclContextVisibleLookupAbbrev, Record,
5028 LookupTable);
5029 ++NumVisibleDeclContexts;
5030
5031 if (!ModuleLocalLookupTable.empty()) {
5032 Offsets.ModuleLocalOffset = Stream.GetCurrentBitNo();
5033 assert(Offsets.ModuleLocalOffset > Offsets.VisibleOffset);
5034 // Write the lookup table
5035 RecordData::value_type ModuleLocalRecord[] = {
5037 Stream.EmitRecordWithBlob(DeclModuleLocalVisibleLookupAbbrev,
5038 ModuleLocalRecord, ModuleLocalLookupTable);
5039 ++NumModuleLocalDeclContexts;
5040 }
5041
5042 if (!TULookupTable.empty()) {
5043 Offsets.TULocalOffset = Stream.GetCurrentBitNo();
5044 // Write the lookup table
5045 RecordData::value_type TULocalDeclsRecord[] = {
5047 Stream.EmitRecordWithBlob(DeclTULocalLookupAbbrev, TULocalDeclsRecord,
5048 TULookupTable);
5049 ++NumTULocalDeclContexts;
5050 }
5051}
5052
5053/// Write an UPDATE_VISIBLE block for the given context.
5054///
5055/// UPDATE_VISIBLE blocks contain the declarations that are added to an existing
5056/// DeclContext in a dependent AST file. As such, they only exist for the TU
5057/// (in C++), for namespaces, and for classes with forward-declared unscoped
5058/// enumeration members (in C++11).
5059void ASTWriter::WriteDeclContextVisibleUpdate(ASTContext &Context,
5060 const DeclContext *DC) {
5061 StoredDeclsMap *Map = DC->getLookupPtr();
5062 if (!Map || Map->empty())
5063 return;
5064
5065 // Create the on-disk hash table in a buffer.
5066 SmallString<4096> LookupTable;
5067 SmallString<4096> ModuleLocalLookupTable;
5068 SmallString<4096> TULookupTable;
5069 GenerateNameLookupTable(Context, DC, LookupTable, ModuleLocalLookupTable,
5070 TULookupTable);
5071
5072 // If we're updating a namespace, select a key declaration as the key for the
5073 // update record; those are the only ones that will be checked on reload.
5074 if (isa<NamespaceDecl>(DC))
5076
5077 // Write the lookup table
5078 RecordData::value_type Record[] = {UPDATE_VISIBLE,
5079 getDeclID(cast<Decl>(DC)).getRawValue()};
5080 Stream.EmitRecordWithBlob(UpdateVisibleAbbrev, Record, LookupTable);
5081
5082 if (!ModuleLocalLookupTable.empty()) {
5083 // Write the module local lookup table
5084 RecordData::value_type ModuleLocalRecord[] = {
5085 UPDATE_MODULE_LOCAL_VISIBLE, getDeclID(cast<Decl>(DC)).getRawValue()};
5086 Stream.EmitRecordWithBlob(ModuleLocalUpdateVisibleAbbrev, ModuleLocalRecord,
5087 ModuleLocalLookupTable);
5088 }
5089
5090 if (!TULookupTable.empty()) {
5091 RecordData::value_type GMFRecord[] = {
5092 UPDATE_TU_LOCAL_VISIBLE, getDeclID(cast<Decl>(DC)).getRawValue()};
5093 Stream.EmitRecordWithBlob(TULocalUpdateVisibleAbbrev, GMFRecord,
5094 TULookupTable);
5095 }
5096}
5097
5098/// Write an FP_PRAGMA_OPTIONS block for the given FPOptions.
5099void ASTWriter::WriteFPPragmaOptions(const FPOptionsOverride &Opts) {
5100 RecordData::value_type Record[] = {Opts.getAsOpaqueInt()};
5101 Stream.EmitRecord(FP_PRAGMA_OPTIONS, Record);
5102}
5103
5104/// Write an OPENCL_EXTENSIONS block for the given OpenCLOptions.
5105void ASTWriter::WriteOpenCLExtensions(Sema &SemaRef) {
5106 if (!SemaRef.Context.getLangOpts().OpenCL)
5107 return;
5108
5109 const OpenCLOptions &Opts = SemaRef.getOpenCLOptions();
5110 RecordData Record;
5111 for (const auto &I:Opts.OptMap) {
5112 AddString(I.getKey(), Record);
5113 auto V = I.getValue();
5114 Record.push_back(V.Supported ? 1 : 0);
5115 Record.push_back(V.Enabled ? 1 : 0);
5116 Record.push_back(V.WithPragma ? 1 : 0);
5117 Record.push_back(V.Avail);
5118 Record.push_back(V.Core);
5119 Record.push_back(V.Opt);
5120 }
5121 Stream.EmitRecord(OPENCL_EXTENSIONS, Record);
5122}
5123void ASTWriter::WriteCUDAPragmas(Sema &SemaRef) {
5124 if (SemaRef.CUDA().ForceHostDeviceDepth > 0) {
5125 RecordData::value_type Record[] = {SemaRef.CUDA().ForceHostDeviceDepth};
5126 Stream.EmitRecord(CUDA_PRAGMA_FORCE_HOST_DEVICE_DEPTH, Record);
5127 }
5128}
5129
5130void ASTWriter::WriteObjCCategories() {
5131 if (ObjCClassesWithCategories.empty())
5132 return;
5133
5134 SmallVector<ObjCCategoriesInfo, 2> CategoriesMap;
5135 RecordData Categories;
5136
5137 for (unsigned I = 0, N = ObjCClassesWithCategories.size(); I != N; ++I) {
5138 unsigned Size = 0;
5139 unsigned StartIndex = Categories.size();
5140
5141 ObjCInterfaceDecl *Class = ObjCClassesWithCategories[I];
5142
5143 // Allocate space for the size.
5144 Categories.push_back(0);
5145
5146 // Add the categories.
5148 Cat = Class->known_categories_begin(),
5149 CatEnd = Class->known_categories_end();
5150 Cat != CatEnd; ++Cat, ++Size) {
5151 assert(getDeclID(*Cat).isValid() && "Bogus category");
5152 AddDeclRef(*Cat, Categories);
5153 }
5154
5155 // Update the size.
5156 Categories[StartIndex] = Size;
5157
5158 // Record this interface -> category map.
5159 ObjCCategoriesInfo CatInfo = { getDeclID(Class), StartIndex };
5160 CategoriesMap.push_back(CatInfo);
5161 }
5162
5163 // Sort the categories map by the definition ID, since the reader will be
5164 // performing binary searches on this information.
5165 llvm::array_pod_sort(CategoriesMap.begin(), CategoriesMap.end());
5166
5167 // Emit the categories map.
5168 using namespace llvm;
5169
5170 auto Abbrev = std::make_shared<BitCodeAbbrev>();
5171 Abbrev->Add(BitCodeAbbrevOp(OBJC_CATEGORIES_MAP));
5172 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // # of entries
5173 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob));
5174 unsigned AbbrevID = Stream.EmitAbbrev(std::move(Abbrev));
5175
5176 RecordData::value_type Record[] = {OBJC_CATEGORIES_MAP, CategoriesMap.size()};
5177 Stream.EmitRecordWithBlob(AbbrevID, Record,
5178 reinterpret_cast<char *>(CategoriesMap.data()),
5179 CategoriesMap.size() * sizeof(ObjCCategoriesInfo));
5180
5181 // Emit the category lists.
5182 Stream.EmitRecord(OBJC_CATEGORIES, Categories);
5183}
5184
5185void ASTWriter::WriteLateParsedTemplates(Sema &SemaRef) {
5187
5188 if (LPTMap.empty())
5189 return;
5190
5191 RecordData Record;
5192 for (auto &LPTMapEntry : LPTMap) {
5193 const FunctionDecl *FD = LPTMapEntry.first;
5194 LateParsedTemplate &LPT = *LPTMapEntry.second;
5195 AddDeclRef(FD, Record);
5196 AddDeclRef(LPT.D, Record);
5197 Record.push_back(LPT.FPO.getAsOpaqueInt());
5198 Record.push_back(LPT.Toks.size());
5199
5200 for (const auto &Tok : LPT.Toks) {
5201 AddToken(Tok, Record);
5202 }
5203 }
5204 Stream.EmitRecord(LATE_PARSED_TEMPLATE, Record);
5205}
5206
5207/// Write the state of 'pragma clang optimize' at the end of the module.
5208void ASTWriter::WriteOptimizePragmaOptions(Sema &SemaRef) {
5209 RecordData Record;
5210 SourceLocation PragmaLoc = SemaRef.getOptimizeOffPragmaLocation();
5211 AddSourceLocation(PragmaLoc, Record);
5212 Stream.EmitRecord(OPTIMIZE_PRAGMA_OPTIONS, Record);
5213}
5214
5215/// Write the state of 'pragma ms_struct' at the end of the module.
5216void ASTWriter::WriteMSStructPragmaOptions(Sema &SemaRef) {
5217 RecordData Record;
5218 Record.push_back(SemaRef.MSStructPragmaOn ? PMSST_ON : PMSST_OFF);
5219 Stream.EmitRecord(MSSTRUCT_PRAGMA_OPTIONS, Record);
5220}
5221
5222/// Write the state of 'pragma pointers_to_members' at the end of the
5223//module.
5224void ASTWriter::WriteMSPointersToMembersPragmaOptions(Sema &SemaRef) {
5225 RecordData Record;
5227 AddSourceLocation(SemaRef.ImplicitMSInheritanceAttrLoc, Record);
5228 Stream.EmitRecord(POINTERS_TO_MEMBERS_PRAGMA_OPTIONS, Record);
5229}
5230
5231/// Write the state of 'pragma align/pack' at the end of the module.
5232void ASTWriter::WritePackPragmaOptions(Sema &SemaRef) {
5233 // Don't serialize pragma align/pack state for modules, since it should only
5234 // take effect on a per-submodule basis.
5235 if (WritingModule)
5236 return;
5237
5238 RecordData Record;
5239 AddAlignPackInfo(SemaRef.AlignPackStack.CurrentValue, Record);
5240 AddSourceLocation(SemaRef.AlignPackStack.CurrentPragmaLocation, Record);
5241 Record.push_back(SemaRef.AlignPackStack.Stack.size());
5242 for (const auto &StackEntry : SemaRef.AlignPackStack.Stack) {
5243 AddAlignPackInfo(StackEntry.Value, Record);
5244 AddSourceLocation(StackEntry.PragmaLocation, Record);
5245 AddSourceLocation(StackEntry.PragmaPushLocation, Record);
5246 AddString(StackEntry.StackSlotLabel, Record);
5247 }
5248 Stream.EmitRecord(ALIGN_PACK_PRAGMA_OPTIONS, Record);
5249}
5250
5251/// Write the state of 'pragma float_control' at the end of the module.
5252void ASTWriter::WriteFloatControlPragmaOptions(Sema &SemaRef) {
5253 // Don't serialize pragma float_control state for modules,
5254 // since it should only take effect on a per-submodule basis.
5255 if (WritingModule)
5256 return;
5257
5258 RecordData Record;
5259 Record.push_back(SemaRef.FpPragmaStack.CurrentValue.getAsOpaqueInt());
5260 AddSourceLocation(SemaRef.FpPragmaStack.CurrentPragmaLocation, Record);
5261 Record.push_back(SemaRef.FpPragmaStack.Stack.size());
5262 for (const auto &StackEntry : SemaRef.FpPragmaStack.Stack) {
5263 Record.push_back(StackEntry.Value.getAsOpaqueInt());
5264 AddSourceLocation(StackEntry.PragmaLocation, Record);
5265 AddSourceLocation(StackEntry.PragmaPushLocation, Record);
5266 AddString(StackEntry.StackSlotLabel, Record);
5267 }
5268 Stream.EmitRecord(FLOAT_CONTROL_PRAGMA_OPTIONS, Record);
5269}
5270
5271/// Write Sema's collected list of declarations with unverified effects.
5272void ASTWriter::WriteDeclsWithEffectsToVerify(Sema &SemaRef) {
5273 if (SemaRef.DeclsWithEffectsToVerify.empty())
5274 return;
5275 RecordData Record;
5276 for (const auto *D : SemaRef.DeclsWithEffectsToVerify) {
5277 AddDeclRef(D, Record);
5278 }
5279 Stream.EmitRecord(DECLS_WITH_EFFECTS_TO_VERIFY, Record);
5280}
5281
5282void ASTWriter::WriteModuleFileExtension(Sema &SemaRef,
5283 ModuleFileExtensionWriter &Writer) {
5284 // Enter the extension block.
5285 Stream.EnterSubblock(EXTENSION_BLOCK_ID, 4);
5286
5287 // Emit the metadata record abbreviation.
5288 auto Abv = std::make_shared<llvm::BitCodeAbbrev>();
5289 Abv->Add(llvm::BitCodeAbbrevOp(EXTENSION_METADATA));
5290 Abv->Add(llvm::BitCodeAbbrevOp(llvm::BitCodeAbbrevOp::VBR, 6));
5291 Abv->Add(llvm::BitCodeAbbrevOp(llvm::BitCodeAbbrevOp::VBR, 6));
5292 Abv->Add(llvm::BitCodeAbbrevOp(llvm::BitCodeAbbrevOp::VBR, 6));
5293 Abv->Add(llvm::BitCodeAbbrevOp(llvm::BitCodeAbbrevOp::VBR, 6));
5294 Abv->Add(llvm::BitCodeAbbrevOp(llvm::BitCodeAbbrevOp::Blob));
5295 unsigned Abbrev = Stream.EmitAbbrev(std::move(Abv));
5296
5297 // Emit the metadata record.
5298 RecordData Record;
5299 auto Metadata = Writer.getExtension()->getExtensionMetadata();
5300 Record.push_back(EXTENSION_METADATA);
5301 Record.push_back(Metadata.MajorVersion);
5302 Record.push_back(Metadata.MinorVersion);
5303 Record.push_back(Metadata.BlockName.size());
5304 Record.push_back(Metadata.UserInfo.size());
5305 SmallString<64> Buffer;
5306 Buffer += Metadata.BlockName;
5307 Buffer += Metadata.UserInfo;
5308 Stream.EmitRecordWithBlob(Abbrev, Record, Buffer);
5309
5310 // Emit the contents of the extension block.
5311 Writer.writeExtensionContents(SemaRef, Stream);
5312
5313 // Exit the extension block.
5314 Stream.ExitBlock();
5315}
5316
5317void ASTWriter::WriteRISCVIntrinsicPragmas(Sema &SemaRef) {
5318 RecordData Record;
5319 // Need to update this when new intrinsic class is added.
5320 Record.push_back(/*size*/ 3);
5321 Record.push_back(SemaRef.RISCV().DeclareRVVBuiltins);
5322 Record.push_back(SemaRef.RISCV().DeclareSiFiveVectorBuiltins);
5323 Record.push_back(SemaRef.RISCV().DeclareAndesVectorBuiltins);
5324 Stream.EmitRecord(RISCV_VECTOR_INTRINSICS_PRAGMA, Record);
5325}
5326
5327//===----------------------------------------------------------------------===//
5328// General Serialization Routines
5329//===----------------------------------------------------------------------===//
5330
5332 auto &Record = *this;
5333 // FIXME: Clang can't handle the serialization/deserialization of
5334 // preferred_name properly now. See
5335 // https://github.com/llvm/llvm-project/issues/56490 for example.
5336 if (!A ||
5337 (isa<PreferredNameAttr>(A) && (Writer->isWritingStdCXXNamedModules() ||
5338 Writer->isWritingStdCXXHeaderUnit())))
5339 return Record.push_back(0);
5340
5341 Record.push_back(A->getKind() + 1); // FIXME: stable encoding, target attrs
5342
5343 Record.AddIdentifierRef(A->getAttrName());
5344 Record.AddIdentifierRef(A->getScopeName());
5345 Record.AddSourceRange(A->getRange());
5346 Record.AddSourceLocation(A->getScopeLoc());
5347 Record.push_back(A->getParsedKind());
5348 Record.push_back(A->getSyntax());
5349 Record.push_back(A->getAttributeSpellingListIndexRaw());
5350 Record.push_back(A->isRegularKeywordAttribute());
5351
5352#include "clang/Serialization/AttrPCHWrite.inc"
5353}
5354
5355/// Emit the list of attributes to the specified record.
5357 push_back(Attrs.size());
5358 for (const auto *A : Attrs)
5359 AddAttr(A);
5360}
5361
5363 AddSourceLocation(Tok.getLocation(), Record);
5364 // FIXME: Should translate token kind to a stable encoding.
5365 Record.push_back(Tok.getKind());
5366 // FIXME: Should translate token flags to a stable encoding.
5367 Record.push_back(Tok.getFlags());
5368
5369 if (Tok.isAnnotation()) {
5370 AddSourceLocation(Tok.getAnnotationEndLoc(), Record);
5371 switch (Tok.getKind()) {
5372 case tok::annot_pragma_loop_hint: {
5373 auto *Info = static_cast<PragmaLoopHintInfo *>(Tok.getAnnotationValue());
5374 AddToken(Info->PragmaName, Record);
5375 AddToken(Info->Option, Record);
5376 Record.push_back(Info->Toks.size());
5377 for (const auto &T : Info->Toks)
5378 AddToken(T, Record);
5379 break;
5380 }
5381 case tok::annot_pragma_pack: {
5382 auto *Info =
5383 static_cast<Sema::PragmaPackInfo *>(Tok.getAnnotationValue());
5384 Record.push_back(static_cast<unsigned>(Info->Action));
5385 AddString(Info->SlotLabel, Record);
5386 AddToken(Info->Alignment, Record);
5387 break;
5388 }
5389 // Some annotation tokens do not use the PtrData field.
5390 case tok::annot_pragma_openmp:
5391 case tok::annot_pragma_openmp_end:
5392 case tok::annot_pragma_unused:
5393 case tok::annot_pragma_openacc:
5394 case tok::annot_pragma_openacc_end:
5395 case tok::annot_repl_input_end:
5396 break;
5397 default:
5398 llvm_unreachable("missing serialization code for annotation token");
5399 }
5400 } else {
5401 Record.push_back(Tok.getLength());
5402 // FIXME: When reading literal tokens, reconstruct the literal pointer if it
5403 // is needed.
5404 AddIdentifierRef(Tok.getIdentifierInfo(), Record);
5405 }
5406}
5407
5409 Record.push_back(Str.size());
5410 llvm::append_range(Record, Str);
5411}
5412
5414 SmallVectorImpl<char> &Blob) {
5415 Record.push_back(Str.size());
5416 llvm::append_range(Blob, Str);
5417}
5418
5420 assert(WritingAST && "can't prepare path for output when not writing AST");
5421
5422 // Leave special file names as they are.
5423 StringRef PathStr(Path.data(), Path.size());
5424 if (PathStr == "<built-in>" || PathStr == "<command line>")
5425 return false;
5426
5427 bool Changed =
5428 PP->getFileManager().makeAbsolutePath(Path, /*Canonicalize=*/true);
5429 // Remove a prefix to make the path relative, if relevant.
5430 const char *PathBegin = Path.data();
5431 const char *PathPtr =
5432 adjustFilenameForRelocatableAST(PathBegin, BaseDirectory);
5433 if (PathPtr != PathBegin) {
5434 Path.erase(Path.begin(), Path.begin() + (PathPtr - PathBegin));
5435 Changed = true;
5436 }
5437
5438 return Changed;
5439}
5440
5442 SmallString<128> FilePath(Path);
5443 PreparePathForOutput(FilePath);
5444 AddString(FilePath, Record);
5445}
5446
5448 SmallVectorImpl<char> &Blob) {
5449 SmallString<128> FilePath(Path);
5450 PreparePathForOutput(FilePath);
5451 AddStringBlob(FilePath, Record, Blob);
5452}
5453
5455 StringRef Path) {
5456 SmallString<128> FilePath(Path);
5457 PreparePathForOutput(FilePath);
5458 Stream.EmitRecordWithBlob(Abbrev, Record, FilePath);
5459}
5460
5461void ASTWriter::AddVersionTuple(const VersionTuple &Version,
5463 Record.push_back(Version.getMajor());
5464 if (std::optional<unsigned> Minor = Version.getMinor())
5465 Record.push_back(*Minor + 1);
5466 else
5467 Record.push_back(0);
5468 if (std::optional<unsigned> Subminor = Version.getSubminor())
5469 Record.push_back(*Subminor + 1);
5470 else
5471 Record.push_back(0);
5472}
5473
5474/// Note that the identifier II occurs at the given offset
5475/// within the identifier table.
5476void ASTWriter::SetIdentifierOffset(const IdentifierInfo *II, uint32_t Offset) {
5477 IdentifierID ID = IdentifierIDs[II];
5478 // Only store offsets new to this AST file. Other identifier names are looked
5479 // up earlier in the chain and thus don't need an offset.
5480 if (!isLocalIdentifierID(ID))
5481 return;
5482
5483 // For local identifiers, the module file index must be 0.
5484
5485 assert(ID != 0);
5487 assert(ID < IdentifierOffsets.size());
5488 IdentifierOffsets[ID] = Offset;
5489}
5490
5491/// Note that the selector Sel occurs at the given offset
5492/// within the method pool/selector table.
5493void ASTWriter::SetSelectorOffset(Selector Sel, uint32_t Offset) {
5494 unsigned ID = SelectorIDs[Sel];
5495 assert(ID && "Unknown selector");
5496 // Don't record offsets for selectors that are also available in a different
5497 // file.
5498 if (ID < FirstSelectorID)
5499 return;
5500 SelectorOffsets[ID - FirstSelectorID] = Offset;
5501}
5502
5503ASTWriter::ASTWriter(llvm::BitstreamWriter &Stream,
5504 SmallVectorImpl<char> &Buffer, ModuleCache &ModCache,
5505 const CodeGenOptions &CodeGenOpts,
5506 ArrayRef<std::shared_ptr<ModuleFileExtension>> Extensions,
5507 bool IncludeTimestamps, bool BuildingImplicitModule,
5508 bool GeneratingReducedBMI)
5509 : Stream(Stream), Buffer(Buffer), ModCache(ModCache),
5510 CodeGenOpts(CodeGenOpts), IncludeTimestamps(IncludeTimestamps),
5511 BuildingImplicitModule(BuildingImplicitModule),
5512 GeneratingReducedBMI(GeneratingReducedBMI) {
5513 for (const auto &Ext : Extensions) {
5514 if (auto Writer = Ext->createExtensionWriter(*this))
5515 ModuleFileExtensionWriters.push_back(std::move(Writer));
5516 }
5517}
5518
5519ASTWriter::~ASTWriter() = default;
5520
5522 assert(WritingAST && "can't determine lang opts when not writing AST");
5523 return PP->getLangOpts();
5524}
5525
5526time_t ASTWriter::getTimestampForOutput(time_t ModTime) const {
5527 return IncludeTimestamps ? ModTime : 0;
5528}
5529
5531ASTWriter::WriteAST(llvm::PointerUnion<Sema *, Preprocessor *> Subject,
5532 StringRef OutputFile, Module *WritingModule,
5533 StringRef isysroot) {
5534 llvm::TimeTraceScope scope("WriteAST", OutputFile);
5535 WritingAST = true;
5536
5537 Sema *SemaPtr = dyn_cast<Sema *>(Subject);
5538 Preprocessor &PPRef =
5539 SemaPtr ? SemaPtr->getPreprocessor() : *cast<Preprocessor *>(Subject);
5540
5541 ASTHasCompilerErrors = PPRef.getDiagnostics().hasUncompilableErrorOccurred();
5542
5543 // Emit the file header.
5544 Stream.Emit((unsigned)'C', 8);
5545 Stream.Emit((unsigned)'P', 8);
5546 Stream.Emit((unsigned)'C', 8);
5547 Stream.Emit((unsigned)'H', 8);
5548
5549 WriteBlockInfoBlock();
5550
5551 PP = &PPRef;
5552 this->WritingModule = WritingModule;
5553 ASTFileSignature Signature = WriteASTCore(SemaPtr, isysroot, WritingModule);
5554 PP = nullptr;
5555 this->WritingModule = nullptr;
5556 this->BaseDirectory.clear();
5557
5558 WritingAST = false;
5559
5560 return Signature;
5561}
5562
5563template<typename Vector>
5564static void AddLazyVectorDecls(ASTWriter &Writer, Vector &Vec) {
5565 for (typename Vector::iterator I = Vec.begin(nullptr, true), E = Vec.end();
5566 I != E; ++I) {
5567 Writer.GetDeclRef(*I);
5568 }
5569}
5570
5571template <typename Vector>
5574 for (typename Vector::iterator I = Vec.begin(nullptr, true), E = Vec.end();
5575 I != E; ++I) {
5576 Writer.AddEmittedDeclRef(*I, Record);
5577 }
5578}
5579
5580void ASTWriter::computeNonAffectingInputFiles() {
5581 SourceManager &SrcMgr = PP->getSourceManager();
5582 unsigned N = SrcMgr.local_sloc_entry_size();
5583
5584 IsSLocAffecting.resize(N, true);
5585 IsSLocFileEntryAffecting.resize(N, true);
5586
5587 if (!WritingModule)
5588 return;
5589
5590 auto AffectingModuleMaps = GetAffectingModuleMaps(*PP, WritingModule);
5591
5592 unsigned FileIDAdjustment = 0;
5593 unsigned OffsetAdjustment = 0;
5594
5595 NonAffectingFileIDAdjustments.reserve(N);
5596 NonAffectingOffsetAdjustments.reserve(N);
5597
5598 NonAffectingFileIDAdjustments.push_back(FileIDAdjustment);
5599 NonAffectingOffsetAdjustments.push_back(OffsetAdjustment);
5600
5601 for (unsigned I = 1; I != N; ++I) {
5602 const SrcMgr::SLocEntry *SLoc = &SrcMgr.getLocalSLocEntry(I);
5603 FileID FID = FileID::get(I);
5604 assert(&SrcMgr.getSLocEntry(FID) == SLoc);
5605
5606 if (!SLoc->isFile())
5607 continue;
5608 const SrcMgr::FileInfo &File = SLoc->getFile();
5609 const SrcMgr::ContentCache *Cache = &File.getContentCache();
5610 if (!Cache->OrigEntry)
5611 continue;
5612
5613 // Don't prune anything other than module maps.
5614 if (!isModuleMap(File.getFileCharacteristic()))
5615 continue;
5616
5617 // Don't prune module maps if all are guaranteed to be affecting.
5618 if (!AffectingModuleMaps)
5619 continue;
5620
5621 // Don't prune module maps that are affecting.
5622 if (AffectingModuleMaps->DefinitionFileIDs.contains(FID))
5623 continue;
5624
5625 IsSLocAffecting[I] = false;
5626 IsSLocFileEntryAffecting[I] =
5627 AffectingModuleMaps->DefinitionFiles.contains(*Cache->OrigEntry);
5628
5629 FileIDAdjustment += 1;
5630 // Even empty files take up one element in the offset table.
5631 OffsetAdjustment += SrcMgr.getFileIDSize(FID) + 1;
5632
5633 // If the previous file was non-affecting as well, just extend its entry
5634 // with our information.
5635 if (!NonAffectingFileIDs.empty() &&
5636 NonAffectingFileIDs.back().ID == FID.ID - 1) {
5637 NonAffectingFileIDs.back() = FID;
5638 NonAffectingRanges.back().setEnd(SrcMgr.getLocForEndOfFile(FID));
5639 NonAffectingFileIDAdjustments.back() = FileIDAdjustment;
5640 NonAffectingOffsetAdjustments.back() = OffsetAdjustment;
5641 continue;
5642 }
5643
5644 NonAffectingFileIDs.push_back(FID);
5645 NonAffectingRanges.emplace_back(SrcMgr.getLocForStartOfFile(FID),
5646 SrcMgr.getLocForEndOfFile(FID));
5647 NonAffectingFileIDAdjustments.push_back(FileIDAdjustment);
5648 NonAffectingOffsetAdjustments.push_back(OffsetAdjustment);
5649 }
5650
5651 if (!PP->getHeaderSearchInfo().getHeaderSearchOpts().ModulesIncludeVFSUsage)
5652 return;
5653
5654 FileManager &FileMgr = PP->getFileManager();
5655 FileMgr.trackVFSUsage(true);
5656 // Lookup the paths in the VFS to trigger `-ivfsoverlay` usage tracking.
5657 for (StringRef Path :
5658 PP->getHeaderSearchInfo().getHeaderSearchOpts().VFSOverlayFiles)
5659 FileMgr.getVirtualFileSystem().exists(Path);
5660 for (unsigned I = 1; I != N; ++I) {
5661 if (IsSLocAffecting[I]) {
5662 const SrcMgr::SLocEntry *SLoc = &SrcMgr.getLocalSLocEntry(I);
5663 if (!SLoc->isFile())
5664 continue;
5665 const SrcMgr::FileInfo &File = SLoc->getFile();
5666 const SrcMgr::ContentCache *Cache = &File.getContentCache();
5667 if (!Cache->OrigEntry)
5668 continue;
5669 FileMgr.getVirtualFileSystem().exists(
5670 Cache->OrigEntry->getNameAsRequested());
5671 }
5672 }
5673 FileMgr.trackVFSUsage(false);
5674}
5675
5676void ASTWriter::prepareLazyUpdates() {
5677 // In C++20 named modules with reduced BMI, we only apply the update
5678 // if these updates are touched.
5679 if (!GeneratingReducedBMI)
5680 return;
5681
5682 DeclUpdateMap DeclUpdatesTmp;
5683 // Move updates to DeclUpdatesLazy but leave CXXAddedFunctionDefinition as is.
5684 // Since added function definition is critical to the AST. If we don't take
5685 // care of it, user might meet missing definition error at linking time.
5686 // Here we leave all CXXAddedFunctionDefinition unconditionally to avoid
5687 // potential issues.
5688 // TODO: Try to refine the strategy to handle CXXAddedFunctionDefinition
5689 // precisely.
5690 for (auto &DeclUpdate : DeclUpdates) {
5691 const Decl *D = DeclUpdate.first;
5692
5693 for (auto &Update : DeclUpdate.second) {
5694 DeclUpdateKind Kind = Update.getKind();
5695
5696 if (Kind == DeclUpdateKind::CXXAddedFunctionDefinition)
5697 DeclUpdatesTmp[D].push_back(
5698 ASTWriter::DeclUpdate(DeclUpdateKind::CXXAddedFunctionDefinition));
5699 else
5700 DeclUpdatesLazy[D].push_back(Update);
5701 }
5702 }
5703 DeclUpdates.swap(DeclUpdatesTmp);
5704
5705 UpdatedDeclContextsLazy.swap(UpdatedDeclContexts);
5706 // In reduced BMI, we don't have decls have to emit even if unreferenced.
5707 DeclsToEmitEvenIfUnreferenced.clear();
5708}
5709
5710void ASTWriter::PrepareWritingSpecialDecls(Sema &SemaRef) {
5711 ASTContext &Context = SemaRef.Context;
5712
5713 bool isModule = WritingModule != nullptr;
5714
5715 prepareLazyUpdates();
5716
5717 // Set up predefined declaration IDs.
5718 auto RegisterPredefDecl = [&] (Decl *D, PredefinedDeclIDs ID) {
5719 if (D) {
5720 assert(D->isCanonicalDecl() && "predefined decl is not canonical");
5721 DeclIDs[D] = ID;
5722 PredefinedDecls.insert(D);
5723 }
5724 };
5725 RegisterPredefDecl(Context.getTranslationUnitDecl(),
5727 RegisterPredefDecl(Context.ObjCIdDecl, PREDEF_DECL_OBJC_ID_ID);
5728 RegisterPredefDecl(Context.ObjCSelDecl, PREDEF_DECL_OBJC_SEL_ID);
5729 RegisterPredefDecl(Context.ObjCClassDecl, PREDEF_DECL_OBJC_CLASS_ID);
5730 RegisterPredefDecl(Context.ObjCProtocolClassDecl,
5732 RegisterPredefDecl(Context.Int128Decl, PREDEF_DECL_INT_128_ID);
5733 RegisterPredefDecl(Context.UInt128Decl, PREDEF_DECL_UNSIGNED_INT_128_ID);
5734 RegisterPredefDecl(Context.ObjCInstanceTypeDecl,
5736 RegisterPredefDecl(Context.BuiltinVaListDecl, PREDEF_DECL_BUILTIN_VA_LIST_ID);
5737 RegisterPredefDecl(Context.VaListTagDecl, PREDEF_DECL_VA_LIST_TAG);
5738 RegisterPredefDecl(Context.BuiltinMSVaListDecl,
5740 RegisterPredefDecl(Context.BuiltinZOSVaListDecl,
5742 RegisterPredefDecl(Context.MSGuidTagDecl,
5744 RegisterPredefDecl(Context.MSTypeInfoTagDecl,
5746 RegisterPredefDecl(Context.ExternCContext, PREDEF_DECL_EXTERN_C_CONTEXT_ID);
5747 RegisterPredefDecl(Context.CFConstantStringTypeDecl,
5749 RegisterPredefDecl(Context.CFConstantStringTagDecl,
5751#define BuiltinTemplate(BTName) \
5752 RegisterPredefDecl(Context.Decl##BTName, PREDEF_DECL##BTName##_ID);
5753#include "clang/Basic/BuiltinTemplates.inc"
5754
5755 const TranslationUnitDecl *TU = Context.getTranslationUnitDecl();
5756
5757 // Force all top level declarations to be emitted.
5758 //
5759 // We start emitting top level declarations from the module purview to
5760 // implement the eliding unreachable declaration feature.
5761 for (const auto *D : TU->noload_decls()) {
5762 if (D->isFromASTFile())
5763 continue;
5764
5765 if (GeneratingReducedBMI) {
5767 continue;
5768
5769 // Don't force emitting static entities.
5770 //
5771 // Technically, all static entities shouldn't be in reduced BMI. The
5772 // language also specifies that the program exposes TU-local entities
5773 // is ill-formed. However, in practice, there are a lot of projects
5774 // uses `static inline` in the headers. So we can't get rid of all
5775 // static entities in reduced BMI now.
5777 continue;
5778 }
5779
5780 // If we're writing C++ named modules, don't emit declarations which are
5781 // not from modules by default. They may be built in declarations (be
5782 // handled above) or implcit declarations (see the implementation of
5783 // `Sema::Initialize()` for example).
5785 D->isImplicit())
5786 continue;
5787
5788 GetDeclRef(D);
5789 }
5790
5791 if (GeneratingReducedBMI)
5792 return;
5793
5794 // Writing all of the tentative definitions in this file, in
5795 // TentativeDefinitions order. Generally, this record will be empty for
5796 // headers.
5798
5799 // Writing all of the file scoped decls in this file.
5800 if (!isModule)
5802
5803 // Writing all of the delegating constructors we still need
5804 // to resolve.
5805 if (!isModule)
5807
5808 // Writing all of the ext_vector declarations.
5809 AddLazyVectorDecls(*this, SemaRef.ExtVectorDecls);
5810
5811 // Writing all of the VTable uses information.
5812 if (!SemaRef.VTableUses.empty())
5813 for (unsigned I = 0, N = SemaRef.VTableUses.size(); I != N; ++I)
5814 GetDeclRef(SemaRef.VTableUses[I].first);
5815
5816 // Writing all of the UnusedLocalTypedefNameCandidates in a deterministic
5817 // order.
5818 SmallVector<const TypedefNameDecl *, 4> UnusedLocalTypedefs;
5819 SemaRef.getSortedUnusedLocalTypedefNameCandidates(UnusedLocalTypedefs);
5820 for (const TypedefNameDecl *TD : UnusedLocalTypedefs)
5821 GetDeclRef(TD);
5822
5823 // Writing all of pending implicit instantiations.
5824 for (const auto &I : SemaRef.PendingInstantiations)
5825 GetDeclRef(I.first);
5826 assert(SemaRef.PendingLocalImplicitInstantiations.empty() &&
5827 "There are local ones at end of translation unit!");
5828
5829 // Writing some declaration references.
5830 if (SemaRef.StdNamespace || SemaRef.StdBadAlloc || SemaRef.StdAlignValT) {
5831 GetDeclRef(SemaRef.getStdNamespace());
5832 GetDeclRef(SemaRef.getStdBadAlloc());
5833 GetDeclRef(SemaRef.getStdAlignValT());
5834 }
5835
5836 if (Context.getcudaConfigureCallDecl() ||
5838 Context.getcudaLaunchDeviceDecl()) {
5842 }
5843
5844 // Writing all of the known namespaces.
5845 for (const auto &I : SemaRef.KnownNamespaces)
5846 if (!I.second)
5847 GetDeclRef(I.first);
5848
5849 // Writing all used, undefined objects that require definitions.
5850 SmallVector<std::pair<NamedDecl *, SourceLocation>, 16> Undefined;
5852 for (const auto &I : Undefined)
5853 GetDeclRef(I.first);
5854
5855 // Writing all delete-expressions that we would like to
5856 // analyze later in AST.
5857 if (!isModule)
5858 for (const auto &DeleteExprsInfo :
5860 GetDeclRef(DeleteExprsInfo.first);
5861
5862 // Make sure visible decls, added to DeclContexts previously loaded from
5863 // an AST file, are registered for serialization. Likewise for template
5864 // specializations added to imported templates.
5865 for (const auto *I : DeclsToEmitEvenIfUnreferenced)
5866 GetDeclRef(I);
5867 DeclsToEmitEvenIfUnreferenced.clear();
5868
5869 // Make sure all decls associated with an identifier are registered for
5870 // serialization, if we're storing decls with identifiers.
5871 if (!WritingModule || !getLangOpts().CPlusPlus) {
5872 llvm::SmallVector<const IdentifierInfo*, 256> IIs;
5873 for (const auto &ID : SemaRef.PP.getIdentifierTable()) {
5874 const IdentifierInfo *II = ID.second;
5875 if (!Chain || !II->isFromAST() || II->hasChangedSinceDeserialization() ||
5877 IIs.push_back(II);
5878 }
5879 // Sort the identifiers to visit based on their name.
5880 llvm::sort(IIs, llvm::deref<std::less<>>());
5881 const LangOptions &LangOpts = getLangOpts();
5882 for (const IdentifierInfo *II : IIs)
5883 for (NamedDecl *D : SemaRef.IdResolver.decls(II))
5884 GetDeclRef(getDeclForLocalLookup(LangOpts, D));
5885 }
5886
5887 // Write all of the DeclsToCheckForDeferredDiags.
5888 for (auto *D : SemaRef.DeclsToCheckForDeferredDiags)
5889 GetDeclRef(D);
5890
5891 // Write all classes that need to emit the vtable definitions if required.
5893 for (CXXRecordDecl *RD : PendingEmittingVTables)
5894 GetDeclRef(RD);
5895 else
5896 PendingEmittingVTables.clear();
5897}
5898
5899void ASTWriter::WriteSpecialDeclRecords(Sema &SemaRef) {
5900 ASTContext &Context = SemaRef.Context;
5901
5902 bool isModule = WritingModule != nullptr;
5903
5904 // Write the record containing external, unnamed definitions.
5905 if (!EagerlyDeserializedDecls.empty())
5906 Stream.EmitRecord(EAGERLY_DESERIALIZED_DECLS, EagerlyDeserializedDecls);
5907
5908 if (!ModularCodegenDecls.empty())
5909 Stream.EmitRecord(MODULAR_CODEGEN_DECLS, ModularCodegenDecls);
5910
5911 // Write the record containing tentative definitions.
5912 RecordData TentativeDefinitions;
5914 TentativeDefinitions);
5915 if (!TentativeDefinitions.empty())
5916 Stream.EmitRecord(TENTATIVE_DEFINITIONS, TentativeDefinitions);
5917
5918 // Write the record containing unused file scoped decls.
5919 RecordData UnusedFileScopedDecls;
5920 if (!isModule)
5922 UnusedFileScopedDecls);
5923 if (!UnusedFileScopedDecls.empty())
5924 Stream.EmitRecord(UNUSED_FILESCOPED_DECLS, UnusedFileScopedDecls);
5925
5926 // Write the record containing ext_vector type names.
5927 RecordData ExtVectorDecls;
5928 AddLazyVectorEmiitedDecls(*this, SemaRef.ExtVectorDecls, ExtVectorDecls);
5929 if (!ExtVectorDecls.empty())
5930 Stream.EmitRecord(EXT_VECTOR_DECLS, ExtVectorDecls);
5931
5932 // Write the record containing VTable uses information.
5933 RecordData VTableUses;
5934 if (!SemaRef.VTableUses.empty()) {
5935 for (unsigned I = 0, N = SemaRef.VTableUses.size(); I != N; ++I) {
5936 CXXRecordDecl *D = SemaRef.VTableUses[I].first;
5937 if (!wasDeclEmitted(D))
5938 continue;
5939
5940 AddDeclRef(D, VTableUses);
5941 AddSourceLocation(SemaRef.VTableUses[I].second, VTableUses);
5942 VTableUses.push_back(SemaRef.VTablesUsed[D]);
5943 }
5944 Stream.EmitRecord(VTABLE_USES, VTableUses);
5945 }
5946
5947 // Write the record containing potentially unused local typedefs, in a
5948 // deterministic order.
5949 RecordData UnusedLocalTypedefNameCandidates;
5950 SmallVector<const TypedefNameDecl *, 4> SortedCandidates;
5951 SemaRef.getSortedUnusedLocalTypedefNameCandidates(SortedCandidates);
5952 for (const TypedefNameDecl *TD : SortedCandidates)
5953 AddEmittedDeclRef(TD, UnusedLocalTypedefNameCandidates);
5954 if (!UnusedLocalTypedefNameCandidates.empty())
5955 Stream.EmitRecord(UNUSED_LOCAL_TYPEDEF_NAME_CANDIDATES,
5956 UnusedLocalTypedefNameCandidates);
5957
5958 if (!GeneratingReducedBMI) {
5959 // Write the record containing pending implicit instantiations.
5960 RecordData PendingInstantiations;
5961 for (const auto &I : SemaRef.PendingInstantiations) {
5962 if (!wasDeclEmitted(I.first))
5963 continue;
5964
5965 AddDeclRef(I.first, PendingInstantiations);
5966 AddSourceLocation(I.second, PendingInstantiations);
5967 }
5968 if (!PendingInstantiations.empty())
5969 Stream.EmitRecord(PENDING_IMPLICIT_INSTANTIATIONS, PendingInstantiations);
5970 }
5971
5972 auto AddEmittedDeclRefOrZero = [this](RecordData &Refs, Decl *D) {
5973 if (!D || !wasDeclEmitted(D))
5974 Refs.push_back(0);
5975 else
5976 AddDeclRef(D, Refs);
5977 };
5978
5979 // Write the record containing declaration references of Sema.
5980 RecordData SemaDeclRefs;
5981 if (SemaRef.StdNamespace || SemaRef.StdBadAlloc || SemaRef.StdAlignValT) {
5982 AddEmittedDeclRefOrZero(SemaDeclRefs, SemaRef.getStdNamespace());
5983 AddEmittedDeclRefOrZero(SemaDeclRefs, SemaRef.getStdBadAlloc());
5984 AddEmittedDeclRefOrZero(SemaDeclRefs, SemaRef.getStdAlignValT());
5985 }
5986 if (!SemaDeclRefs.empty())
5987 Stream.EmitRecord(SEMA_DECL_REFS, SemaDeclRefs);
5988
5989 // Write the record containing decls to be checked for deferred diags.
5990 RecordData DeclsToCheckForDeferredDiags;
5991 for (auto *D : SemaRef.DeclsToCheckForDeferredDiags)
5992 if (wasDeclEmitted(D))
5993 AddDeclRef(D, DeclsToCheckForDeferredDiags);
5994 if (!DeclsToCheckForDeferredDiags.empty())
5995 Stream.EmitRecord(DECLS_TO_CHECK_FOR_DEFERRED_DIAGS,
5996 DeclsToCheckForDeferredDiags);
5997
5998 // Write the record containing CUDA-specific declaration references.
5999 RecordData CUDASpecialDeclRefs;
6000 if (auto *CudaCallDecl = Context.getcudaConfigureCallDecl(),
6001 *CudaGetParamDecl = Context.getcudaGetParameterBufferDecl(),
6002 *CudaLaunchDecl = Context.getcudaLaunchDeviceDecl();
6003 CudaCallDecl || CudaGetParamDecl || CudaLaunchDecl) {
6004 AddEmittedDeclRefOrZero(CUDASpecialDeclRefs, CudaCallDecl);
6005 AddEmittedDeclRefOrZero(CUDASpecialDeclRefs, CudaGetParamDecl);
6006 AddEmittedDeclRefOrZero(CUDASpecialDeclRefs, CudaLaunchDecl);
6007 Stream.EmitRecord(CUDA_SPECIAL_DECL_REFS, CUDASpecialDeclRefs);
6008 }
6009
6010 // Write the delegating constructors.
6011 RecordData DelegatingCtorDecls;
6012 if (!isModule)
6014 DelegatingCtorDecls);
6015 if (!DelegatingCtorDecls.empty())
6016 Stream.EmitRecord(DELEGATING_CTORS, DelegatingCtorDecls);
6017
6018 // Write the known namespaces.
6019 RecordData KnownNamespaces;
6020 for (const auto &I : SemaRef.KnownNamespaces) {
6021 if (!I.second && wasDeclEmitted(I.first))
6022 AddDeclRef(I.first, KnownNamespaces);
6023 }
6024 if (!KnownNamespaces.empty())
6025 Stream.EmitRecord(KNOWN_NAMESPACES, KnownNamespaces);
6026
6027 // Write the undefined internal functions and variables, and inline functions.
6028 RecordData UndefinedButUsed;
6029 SmallVector<std::pair<NamedDecl *, SourceLocation>, 16> Undefined;
6031 for (const auto &I : Undefined) {
6032 if (!wasDeclEmitted(I.first))
6033 continue;
6034
6035 AddDeclRef(I.first, UndefinedButUsed);
6036 AddSourceLocation(I.second, UndefinedButUsed);
6037 }
6038 if (!UndefinedButUsed.empty())
6039 Stream.EmitRecord(UNDEFINED_BUT_USED, UndefinedButUsed);
6040
6041 // Write all delete-expressions that we would like to
6042 // analyze later in AST.
6043 RecordData DeleteExprsToAnalyze;
6044 if (!isModule) {
6045 for (const auto &DeleteExprsInfo :
6047 if (!wasDeclEmitted(DeleteExprsInfo.first))
6048 continue;
6049
6050 AddDeclRef(DeleteExprsInfo.first, DeleteExprsToAnalyze);
6051 DeleteExprsToAnalyze.push_back(DeleteExprsInfo.second.size());
6052 for (const auto &DeleteLoc : DeleteExprsInfo.second) {
6053 AddSourceLocation(DeleteLoc.first, DeleteExprsToAnalyze);
6054 DeleteExprsToAnalyze.push_back(DeleteLoc.second);
6055 }
6056 }
6057 }
6058 if (!DeleteExprsToAnalyze.empty())
6059 Stream.EmitRecord(DELETE_EXPRS_TO_ANALYZE, DeleteExprsToAnalyze);
6060
6061 RecordData VTablesToEmit;
6062 for (CXXRecordDecl *RD : PendingEmittingVTables) {
6063 if (!wasDeclEmitted(RD))
6064 continue;
6065
6066 AddDeclRef(RD, VTablesToEmit);
6067 }
6068
6069 if (!VTablesToEmit.empty())
6070 Stream.EmitRecord(VTABLES_TO_EMIT, VTablesToEmit);
6071}
6072
6073ASTFileSignature ASTWriter::WriteASTCore(Sema *SemaPtr, StringRef isysroot,
6074 Module *WritingModule) {
6075 using namespace llvm;
6076
6077 bool isModule = WritingModule != nullptr;
6078
6079 // Make sure that the AST reader knows to finalize itself.
6080 if (Chain)
6081 Chain->finalizeForWriting();
6082
6083 // This needs to be done very early, since everything that writes
6084 // SourceLocations or FileIDs depends on it.
6085 computeNonAffectingInputFiles();
6086
6087 writeUnhashedControlBlock(*PP);
6088
6089 // Don't reuse type ID and Identifier ID from readers for C++ standard named
6090 // modules since we want to support no-transitive-change model for named
6091 // modules. The theory for no-transitive-change model is,
6092 // for a user of a named module, the user can only access the indirectly
6093 // imported decls via the directly imported module. So that it is possible to
6094 // control what matters to the users when writing the module. It would be
6095 // problematic if the users can reuse the type IDs and identifier IDs from
6096 // indirectly imported modules arbitrarily. So we choose to clear these ID
6097 // here.
6099 TypeIdxs.clear();
6100 IdentifierIDs.clear();
6101 }
6102
6103 // Look for any identifiers that were named while processing the
6104 // headers, but are otherwise not needed. We add these to the hash
6105 // table to enable checking of the predefines buffer in the case
6106 // where the user adds new macro definitions when building the AST
6107 // file.
6108 //
6109 // We do this before emitting any Decl and Types to make sure the
6110 // Identifier ID is stable.
6111 SmallVector<const IdentifierInfo *, 128> IIs;
6112 for (const auto &ID : PP->getIdentifierTable())
6113 if (IsInterestingNonMacroIdentifier(ID.second, *this))
6114 IIs.push_back(ID.second);
6115 // Sort the identifiers lexicographically before getting the references so
6116 // that their order is stable.
6117 llvm::sort(IIs, llvm::deref<std::less<>>());
6118 for (const IdentifierInfo *II : IIs)
6119 getIdentifierRef(II);
6120
6121 // Write the set of weak, undeclared identifiers. We always write the
6122 // entire table, since later PCH files in a PCH chain are only interested in
6123 // the results at the end of the chain.
6124 RecordData WeakUndeclaredIdentifiers;
6125 if (SemaPtr) {
6126 for (const auto &WeakUndeclaredIdentifierList :
6127 SemaPtr->WeakUndeclaredIdentifiers) {
6128 const IdentifierInfo *const II = WeakUndeclaredIdentifierList.first;
6129 for (const auto &WI : WeakUndeclaredIdentifierList.second) {
6130 AddIdentifierRef(II, WeakUndeclaredIdentifiers);
6131 AddIdentifierRef(WI.getAlias(), WeakUndeclaredIdentifiers);
6132 AddSourceLocation(WI.getLocation(), WeakUndeclaredIdentifiers);
6133 }
6134 }
6135 }
6136
6137 // Write the set of #pragma redefine_extname'd, undeclared identifiers. We
6138 // always write the entire table, since later PCH files in a PCH chain are
6139 // only interested in the results at the end of the chain.
6140 RecordData ExtnameUndeclaredIdentifiers;
6141 if (SemaPtr && !isWritingStdCXXNamedModules()) {
6142 ASTContext &Context = SemaPtr->Context;
6143 ASTRecordWriter ExtnameUndeclaredIdentifiersWriter(
6144 Context, *this, ExtnameUndeclaredIdentifiers);
6145 for (const auto &[II, AL] : SemaPtr->ExtnameUndeclaredIdentifiers) {
6146 ExtnameUndeclaredIdentifiersWriter.AddIdentifierRef(II);
6147 ExtnameUndeclaredIdentifiersWriter.AddIdentifierRef(
6148 &Context.Idents.get(AL->getLabel()));
6149 ExtnameUndeclaredIdentifiersWriter.AddSourceLocation(AL->getLocation());
6150 }
6151 }
6152
6153 // Form the record of special types.
6154 RecordData SpecialTypes;
6155 if (SemaPtr) {
6156 ASTContext &Context = SemaPtr->Context;
6157 AddTypeRef(Context, Context.getRawCFConstantStringType(), SpecialTypes);
6158 AddTypeRef(Context, Context.getFILEType(), SpecialTypes);
6159 AddTypeRef(Context, Context.getjmp_bufType(), SpecialTypes);
6160 AddTypeRef(Context, Context.getsigjmp_bufType(), SpecialTypes);
6161 AddTypeRef(Context, Context.ObjCIdRedefinitionType, SpecialTypes);
6162 AddTypeRef(Context, Context.ObjCClassRedefinitionType, SpecialTypes);
6163 AddTypeRef(Context, Context.ObjCSelRedefinitionType, SpecialTypes);
6164 AddTypeRef(Context, Context.getucontext_tType(), SpecialTypes);
6165 }
6166
6167 if (SemaPtr)
6168 PrepareWritingSpecialDecls(*SemaPtr);
6169
6170 // Write the control block
6171 WriteControlBlock(*PP, isysroot);
6172
6173 // Write the remaining AST contents.
6174 Stream.FlushToWord();
6175 ASTBlockRange.first = Stream.GetCurrentBitNo() >> 3;
6176 Stream.EnterSubblock(AST_BLOCK_ID, 5);
6177 ASTBlockStartOffset = Stream.GetCurrentBitNo();
6178
6179 // This is so that older clang versions, before the introduction
6180 // of the control block, can read and reject the newer PCH format.
6181 {
6183 Stream.EmitRecord(METADATA_OLD_FORMAT, Record);
6184 }
6185
6186 // For method pool in the module, if it contains an entry for a selector,
6187 // the entry should be complete, containing everything introduced by that
6188 // module and all modules it imports. It's possible that the entry is out of
6189 // date, so we need to pull in the new content here.
6190
6191 // It's possible that updateOutOfDateSelector can update SelectorIDs. To be
6192 // safe, we copy all selectors out.
6193 if (SemaPtr) {
6194 llvm::SmallVector<Selector, 256> AllSelectors;
6195 for (auto &SelectorAndID : SelectorIDs)
6196 AllSelectors.push_back(SelectorAndID.first);
6197 for (auto &Selector : AllSelectors)
6198 SemaPtr->ObjC().updateOutOfDateSelector(Selector);
6199 }
6200
6201 if (Chain) {
6202 // Write the mapping information describing our module dependencies and how
6203 // each of those modules were mapped into our own offset/ID space, so that
6204 // the reader can build the appropriate mapping to its own offset/ID space.
6205 // The map consists solely of a blob with the following format:
6206 // *(module-kind:i8
6207 // module-name-len:i16 module-name:len*i8
6208 // source-location-offset:i32
6209 // identifier-id:i32
6210 // preprocessed-entity-id:i32
6211 // macro-definition-id:i32
6212 // submodule-id:i32
6213 // selector-id:i32
6214 // declaration-id:i32
6215 // c++-base-specifiers-id:i32
6216 // type-id:i32)
6217 //
6218 // module-kind is the ModuleKind enum value. If it is MK_PrebuiltModule,
6219 // MK_ExplicitModule or MK_ImplicitModule, then the module-name is the
6220 // module name. Otherwise, it is the module file name.
6221 auto Abbrev = std::make_shared<BitCodeAbbrev>();
6222 Abbrev->Add(BitCodeAbbrevOp(MODULE_OFFSET_MAP));
6223 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob));
6224 unsigned ModuleOffsetMapAbbrev = Stream.EmitAbbrev(std::move(Abbrev));
6225 SmallString<2048> Buffer;
6226 {
6227 llvm::raw_svector_ostream Out(Buffer);
6228 for (ModuleFile &M : Chain->ModuleMgr) {
6229 using namespace llvm::support;
6230
6231 endian::Writer LE(Out, llvm::endianness::little);
6232 LE.write<uint8_t>(static_cast<uint8_t>(M.Kind));
6233 // FIXME: Storing a PCH's name (M.FileName) as a string does not handle
6234 // relocatable files. We probably should call
6235 // `PreparePathForOutput(M.FileName)` to properly support relocatable
6236 // PCHs.
6237 StringRef Name = M.isModule() ? M.ModuleName : M.FileName.str();
6238 LE.write<uint16_t>(Name.size());
6239 Out.write(Name.data(), Name.size());
6240
6241 // Note: if a base ID was uint max, it would not be possible to load
6242 // another module after it or have more than one entity inside it.
6243 uint32_t None = std::numeric_limits<uint32_t>::max();
6244
6245 auto writeBaseIDOrNone = [&](auto BaseID, bool ShouldWrite) {
6246 assert(BaseID < std::numeric_limits<uint32_t>::max() && "base id too high");
6247 if (ShouldWrite)
6248 LE.write<uint32_t>(BaseID);
6249 else
6250 LE.write<uint32_t>(None);
6251 };
6252
6253 // These values should be unique within a chain, since they will be read
6254 // as keys into ContinuousRangeMaps.
6255 writeBaseIDOrNone(M.BaseSubmoduleID, M.LocalNumSubmodules);
6256 writeBaseIDOrNone(M.BaseSelectorID, M.LocalNumSelectors);
6257 }
6258 }
6259 RecordData::value_type Record[] = {MODULE_OFFSET_MAP};
6260 Stream.EmitRecordWithBlob(ModuleOffsetMapAbbrev, Record,
6261 Buffer.data(), Buffer.size());
6262 }
6263
6264 if (SemaPtr)
6265 WriteDeclAndTypes(SemaPtr->Context);
6266
6267 WriteFileDeclIDsMap();
6268 WriteSourceManagerBlock(PP->getSourceManager());
6269 if (SemaPtr)
6270 WriteComments(SemaPtr->Context);
6271 WritePreprocessor(*PP, isModule);
6272 WriteHeaderSearch(PP->getHeaderSearchInfo());
6273 if (SemaPtr) {
6274 WriteSelectors(*SemaPtr);
6275 WriteReferencedSelectorsPool(*SemaPtr);
6276 WriteLateParsedTemplates(*SemaPtr);
6277 }
6278 WriteIdentifierTable(*PP, SemaPtr ? &SemaPtr->IdResolver : nullptr, isModule);
6279 if (SemaPtr) {
6280 WriteFPPragmaOptions(SemaPtr->CurFPFeatureOverrides());
6281 WriteOpenCLExtensions(*SemaPtr);
6282 WriteCUDAPragmas(*SemaPtr);
6283 WriteRISCVIntrinsicPragmas(*SemaPtr);
6284 }
6285
6286 // If we're emitting a module, write out the submodule information.
6287 if (WritingModule)
6288 WriteSubmodules(WritingModule, SemaPtr ? &SemaPtr->Context : nullptr);
6289
6290 Stream.EmitRecord(SPECIAL_TYPES, SpecialTypes);
6291
6292 if (SemaPtr)
6293 WriteSpecialDeclRecords(*SemaPtr);
6294
6295 // Write the record containing weak undeclared identifiers.
6296 if (!WeakUndeclaredIdentifiers.empty())
6297 Stream.EmitRecord(WEAK_UNDECLARED_IDENTIFIERS,
6298 WeakUndeclaredIdentifiers);
6299
6300 // Write the record containing #pragma redefine_extname'd undeclared
6301 // identifiers.
6302 if (!ExtnameUndeclaredIdentifiers.empty())
6303 Stream.EmitRecord(EXTNAME_UNDECLARED_IDENTIFIERS,
6304 ExtnameUndeclaredIdentifiers);
6305
6306 if (!WritingModule) {
6307 // Write the submodules that were imported, if any.
6308 struct ModuleInfo {
6309 uint64_t ID;
6310 Module *M;
6311 ModuleInfo(uint64_t ID, Module *M) : ID(ID), M(M) {}
6312 };
6313 llvm::SmallVector<ModuleInfo, 64> Imports;
6314 if (SemaPtr) {
6315 for (const auto *I : SemaPtr->Context.local_imports()) {
6316 assert(SubmoduleIDs.contains(I->getImportedModule()));
6317 Imports.push_back(ModuleInfo(SubmoduleIDs[I->getImportedModule()],
6318 I->getImportedModule()));
6319 }
6320 }
6321
6322 if (!Imports.empty()) {
6323 auto Cmp = [](const ModuleInfo &A, const ModuleInfo &B) {
6324 return A.ID < B.ID;
6325 };
6326 auto Eq = [](const ModuleInfo &A, const ModuleInfo &B) {
6327 return A.ID == B.ID;
6328 };
6329
6330 // Sort and deduplicate module IDs.
6331 llvm::sort(Imports, Cmp);
6332 Imports.erase(llvm::unique(Imports, Eq), Imports.end());
6333
6334 RecordData ImportedModules;
6335 for (const auto &Import : Imports) {
6336 ImportedModules.push_back(Import.ID);
6337 // FIXME: If the module has macros imported then later has declarations
6338 // imported, this location won't be the right one as a location for the
6339 // declaration imports.
6340 AddSourceLocation(PP->getModuleImportLoc(Import.M), ImportedModules);
6341 }
6342
6343 Stream.EmitRecord(IMPORTED_MODULES, ImportedModules);
6344 }
6345 }
6346
6347 WriteObjCCategories();
6348 if (SemaPtr) {
6349 if (!WritingModule) {
6350 WriteOptimizePragmaOptions(*SemaPtr);
6351 WriteMSStructPragmaOptions(*SemaPtr);
6352 WriteMSPointersToMembersPragmaOptions(*SemaPtr);
6353 }
6354 WritePackPragmaOptions(*SemaPtr);
6355 WriteFloatControlPragmaOptions(*SemaPtr);
6356 WriteDeclsWithEffectsToVerify(*SemaPtr);
6357 }
6358
6359 // Some simple statistics
6360 RecordData::value_type Record[] = {NumStatements,
6361 NumMacros,
6362 NumLexicalDeclContexts,
6363 NumVisibleDeclContexts,
6364 NumModuleLocalDeclContexts,
6365 NumTULocalDeclContexts};
6366 Stream.EmitRecord(STATISTICS, Record);
6367 Stream.ExitBlock();
6368 Stream.FlushToWord();
6369 ASTBlockRange.second = Stream.GetCurrentBitNo() >> 3;
6370
6371 // Write the module file extension blocks.
6372 if (SemaPtr)
6373 for (const auto &ExtWriter : ModuleFileExtensionWriters)
6374 WriteModuleFileExtension(*SemaPtr, *ExtWriter);
6375
6376 return backpatchSignature();
6377}
6378
6379// Add update records for all mangling numbers and static local numbers.
6380// These aren't really update records, but this is a convenient way of
6381// tagging this rare extra data onto the declarations.
6382void ASTWriter::AddedManglingNumber(const Decl *D, unsigned Number) {
6383 if (D->isFromASTFile())
6384 return;
6385
6386 DeclUpdates[D].push_back(DeclUpdate(DeclUpdateKind::ManglingNumber, Number));
6387}
6388void ASTWriter::AddedStaticLocalNumbers(const Decl *D, unsigned Number) {
6389 if (D->isFromASTFile())
6390 return;
6391
6392 DeclUpdates[D].push_back(
6393 DeclUpdate(DeclUpdateKind::StaticLocalNumber, Number));
6394}
6395
6396void ASTWriter::AddedAnonymousNamespace(const TranslationUnitDecl *TU,
6397 NamespaceDecl *AnonNamespace) {
6398 // If the translation unit has an anonymous namespace, and we don't already
6399 // have an update block for it, write it as an update block.
6400 // FIXME: Why do we not do this if there's already an update block?
6401 if (NamespaceDecl *NS = TU->getAnonymousNamespace()) {
6402 ASTWriter::UpdateRecord &Record = DeclUpdates[TU];
6403 if (Record.empty())
6404 Record.push_back(
6405 DeclUpdate(DeclUpdateKind::CXXAddedAnonymousNamespace, NS));
6406 }
6407}
6408
6409void ASTWriter::WriteDeclAndTypes(ASTContext &Context) {
6410 // Keep writing types, declarations, and declaration update records
6411 // until we've emitted all of them.
6412 RecordData DeclUpdatesOffsetsRecord;
6413 Stream.EnterSubblock(DECLTYPES_BLOCK_ID, /*bits for abbreviations*/ 6);
6414 DeclTypesBlockStartOffset = Stream.GetCurrentBitNo();
6415 WriteTypeAbbrevs();
6416 WriteDeclAbbrevs();
6417 do {
6418 WriteDeclUpdatesBlocks(Context, DeclUpdatesOffsetsRecord);
6419 while (!DeclTypesToEmit.empty()) {
6420 DeclOrType DOT = DeclTypesToEmit.front();
6421 DeclTypesToEmit.pop();
6422 if (DOT.isType())
6423 WriteType(Context, DOT.getType());
6424 else
6425 WriteDecl(Context, DOT.getDecl());
6426 }
6427 } while (!DeclUpdates.empty());
6428
6429 DoneWritingDeclsAndTypes = true;
6430
6431 // DelayedNamespace is only meaningful in reduced BMI.
6432 // See the comments of DelayedNamespace for details.
6433 assert(DelayedNamespace.empty() || GeneratingReducedBMI);
6434 RecordData DelayedNamespaceRecord;
6435 for (NamespaceDecl *NS : DelayedNamespace) {
6436 LookupBlockOffsets Offsets;
6437
6438 Offsets.LexicalOffset = WriteDeclContextLexicalBlock(Context, NS);
6439 WriteDeclContextVisibleBlock(Context, NS, Offsets);
6440
6441 if (Offsets.LexicalOffset)
6442 Offsets.LexicalOffset -= DeclTypesBlockStartOffset;
6443
6444 // Write the offset relative to current block.
6445 if (Offsets.VisibleOffset)
6446 Offsets.VisibleOffset -= DeclTypesBlockStartOffset;
6447
6448 if (Offsets.ModuleLocalOffset)
6449 Offsets.ModuleLocalOffset -= DeclTypesBlockStartOffset;
6450
6451 if (Offsets.TULocalOffset)
6452 Offsets.TULocalOffset -= DeclTypesBlockStartOffset;
6453
6454 AddDeclRef(NS, DelayedNamespaceRecord);
6455 AddLookupOffsets(Offsets, DelayedNamespaceRecord);
6456 }
6457
6458 // The process of writing lexical and visible block for delayed namespace
6459 // shouldn't introduce any new decls, types or update to emit.
6460 assert(DeclTypesToEmit.empty());
6461 assert(DeclUpdates.empty());
6462
6463 Stream.ExitBlock();
6464
6465 // These things can only be done once we've written out decls and types.
6466 WriteTypeDeclOffsets();
6467 if (!DeclUpdatesOffsetsRecord.empty())
6468 Stream.EmitRecord(DECL_UPDATE_OFFSETS, DeclUpdatesOffsetsRecord);
6469
6470 if (!DelayedNamespaceRecord.empty())
6472 DelayedNamespaceRecord);
6473
6474 if (!RelatedDeclsMap.empty()) {
6475 // TODO: on disk hash table for related decls mapping might be more
6476 // efficent becuase it allows lazy deserialization.
6477 RecordData RelatedDeclsMapRecord;
6478 for (const auto &Pair : RelatedDeclsMap) {
6479 RelatedDeclsMapRecord.push_back(Pair.first.getRawValue());
6480 RelatedDeclsMapRecord.push_back(Pair.second.size());
6481 for (const auto &Lambda : Pair.second)
6482 RelatedDeclsMapRecord.push_back(Lambda.getRawValue());
6483 }
6484
6485 auto Abv = std::make_shared<llvm::BitCodeAbbrev>();
6486 Abv->Add(llvm::BitCodeAbbrevOp(RELATED_DECLS_MAP));
6487 Abv->Add(llvm::BitCodeAbbrevOp(llvm::BitCodeAbbrevOp::Array));
6488 Abv->Add(llvm::BitCodeAbbrevOp(llvm::BitCodeAbbrevOp::VBR, 6));
6489 unsigned FunctionToLambdaMapAbbrev = Stream.EmitAbbrev(std::move(Abv));
6490 Stream.EmitRecord(RELATED_DECLS_MAP, RelatedDeclsMapRecord,
6491 FunctionToLambdaMapAbbrev);
6492 }
6493
6494 if (!SpecializationsUpdates.empty()) {
6495 WriteSpecializationsUpdates(/*IsPartial=*/false);
6496 SpecializationsUpdates.clear();
6497 }
6498
6499 if (!PartialSpecializationsUpdates.empty()) {
6500 WriteSpecializationsUpdates(/*IsPartial=*/true);
6501 PartialSpecializationsUpdates.clear();
6502 }
6503
6504 const TranslationUnitDecl *TU = Context.getTranslationUnitDecl();
6505 // Create a lexical update block containing all of the declarations in the
6506 // translation unit that do not come from other AST files.
6507 SmallVector<DeclID, 128> NewGlobalKindDeclPairs;
6508 for (const auto *D : TU->noload_decls()) {
6509 if (D->isFromASTFile())
6510 continue;
6511
6512 // In reduced BMI, skip unreached declarations.
6513 if (!wasDeclEmitted(D))
6514 continue;
6515
6516 NewGlobalKindDeclPairs.push_back(D->getKind());
6517 NewGlobalKindDeclPairs.push_back(GetDeclRef(D).getRawValue());
6518 }
6519
6520 auto Abv = std::make_shared<llvm::BitCodeAbbrev>();
6521 Abv->Add(llvm::BitCodeAbbrevOp(TU_UPDATE_LEXICAL));
6522 Abv->Add(llvm::BitCodeAbbrevOp(llvm::BitCodeAbbrevOp::Blob));
6523 unsigned TuUpdateLexicalAbbrev = Stream.EmitAbbrev(std::move(Abv));
6524
6525 RecordData::value_type Record[] = {TU_UPDATE_LEXICAL};
6526 Stream.EmitRecordWithBlob(TuUpdateLexicalAbbrev, Record,
6527 bytes(NewGlobalKindDeclPairs));
6528
6529 Abv = std::make_shared<llvm::BitCodeAbbrev>();
6530 Abv->Add(llvm::BitCodeAbbrevOp(UPDATE_VISIBLE));
6531 Abv->Add(llvm::BitCodeAbbrevOp(llvm::BitCodeAbbrevOp::VBR, 6));
6532 Abv->Add(llvm::BitCodeAbbrevOp(llvm::BitCodeAbbrevOp::Blob));
6533 UpdateVisibleAbbrev = Stream.EmitAbbrev(std::move(Abv));
6534
6535 Abv = std::make_shared<llvm::BitCodeAbbrev>();
6536 Abv->Add(llvm::BitCodeAbbrevOp(UPDATE_MODULE_LOCAL_VISIBLE));
6537 Abv->Add(llvm::BitCodeAbbrevOp(llvm::BitCodeAbbrevOp::VBR, 6));
6538 Abv->Add(llvm::BitCodeAbbrevOp(llvm::BitCodeAbbrevOp::Blob));
6539 ModuleLocalUpdateVisibleAbbrev = Stream.EmitAbbrev(std::move(Abv));
6540
6541 Abv = std::make_shared<llvm::BitCodeAbbrev>();
6542 Abv->Add(llvm::BitCodeAbbrevOp(UPDATE_TU_LOCAL_VISIBLE));
6543 Abv->Add(llvm::BitCodeAbbrevOp(llvm::BitCodeAbbrevOp::VBR, 6));
6544 Abv->Add(llvm::BitCodeAbbrevOp(llvm::BitCodeAbbrevOp::Blob));
6545 TULocalUpdateVisibleAbbrev = Stream.EmitAbbrev(std::move(Abv));
6546
6547 // And a visible updates block for the translation unit.
6548 WriteDeclContextVisibleUpdate(Context, TU);
6549
6550 // If we have any extern "C" names, write out a visible update for them.
6551 if (Context.ExternCContext)
6552 WriteDeclContextVisibleUpdate(Context, Context.ExternCContext);
6553
6554 // Write the visible updates to DeclContexts.
6555 for (auto *DC : UpdatedDeclContexts)
6556 WriteDeclContextVisibleUpdate(Context, DC);
6557}
6558
6559void ASTWriter::WriteSpecializationsUpdates(bool IsPartial) {
6560 auto RecordType = IsPartial ? CXX_ADDED_TEMPLATE_PARTIAL_SPECIALIZATION
6562
6563 auto Abv = std::make_shared<llvm::BitCodeAbbrev>();
6564 Abv->Add(llvm::BitCodeAbbrevOp(RecordType));
6565 Abv->Add(llvm::BitCodeAbbrevOp(llvm::BitCodeAbbrevOp::VBR, 6));
6566 Abv->Add(llvm::BitCodeAbbrevOp(llvm::BitCodeAbbrevOp::Blob));
6567 auto UpdateSpecializationAbbrev = Stream.EmitAbbrev(std::move(Abv));
6568
6569 auto &SpecUpdates =
6570 IsPartial ? PartialSpecializationsUpdates : SpecializationsUpdates;
6571 for (auto &SpecializationUpdate : SpecUpdates) {
6572 const NamedDecl *D = SpecializationUpdate.first;
6573
6574 llvm::SmallString<4096> LookupTable;
6575 GenerateSpecializationInfoLookupTable(D, SpecializationUpdate.second,
6576 LookupTable, IsPartial);
6577
6578 // Write the lookup table
6579 RecordData::value_type Record[] = {
6580 static_cast<RecordData::value_type>(RecordType),
6581 getDeclID(D).getRawValue()};
6582 Stream.EmitRecordWithBlob(UpdateSpecializationAbbrev, Record, LookupTable);
6583 }
6584}
6585
6586void ASTWriter::WriteDeclUpdatesBlocks(ASTContext &Context,
6587 RecordDataImpl &OffsetsRecord) {
6588 if (DeclUpdates.empty())
6589 return;
6590
6591 DeclUpdateMap LocalUpdates;
6592 LocalUpdates.swap(DeclUpdates);
6593
6594 for (auto &DeclUpdate : LocalUpdates) {
6595 const Decl *D = DeclUpdate.first;
6596
6597 bool HasUpdatedBody = false;
6598 bool HasAddedVarDefinition = false;
6600 ASTRecordWriter Record(Context, *this, RecordData);
6601 for (auto &Update : DeclUpdate.second) {
6602 DeclUpdateKind Kind = Update.getKind();
6603
6604 // An updated body is emitted last, so that the reader doesn't need
6605 // to skip over the lazy body to reach statements for other records.
6606 if (Kind == DeclUpdateKind::CXXAddedFunctionDefinition)
6607 HasUpdatedBody = true;
6608 else if (Kind == DeclUpdateKind::CXXAddedVarDefinition)
6609 HasAddedVarDefinition = true;
6610 else
6611 Record.push_back(llvm::to_underlying(Kind));
6612
6613 switch (Kind) {
6614 case DeclUpdateKind::CXXAddedImplicitMember:
6615 case DeclUpdateKind::CXXAddedAnonymousNamespace:
6616 assert(Update.getDecl() && "no decl to add?");
6617 Record.AddDeclRef(Update.getDecl());
6618 break;
6619 case DeclUpdateKind::CXXAddedFunctionDefinition:
6620 case DeclUpdateKind::CXXAddedVarDefinition:
6621 break;
6622
6623 case DeclUpdateKind::CXXPointOfInstantiation:
6624 // FIXME: Do we need to also save the template specialization kind here?
6625 Record.AddSourceLocation(Update.getLoc());
6626 break;
6627
6628 case DeclUpdateKind::CXXInstantiatedDefaultArgument:
6629 Record.writeStmtRef(
6630 cast<ParmVarDecl>(Update.getDecl())->getDefaultArg());
6631 break;
6632
6633 case DeclUpdateKind::CXXInstantiatedDefaultMemberInitializer:
6634 Record.AddStmt(
6635 cast<FieldDecl>(Update.getDecl())->getInClassInitializer());
6636 break;
6637
6638 case DeclUpdateKind::CXXInstantiatedClassDefinition: {
6639 auto *RD = cast<CXXRecordDecl>(D);
6640 UpdatedDeclContexts.insert(RD->getPrimaryContext());
6641 Record.push_back(RD->isParamDestroyedInCallee());
6642 Record.push_back(llvm::to_underlying(RD->getArgPassingRestrictions()));
6643 Record.AddCXXDefinitionData(RD);
6644 Record.AddOffset(WriteDeclContextLexicalBlock(Context, RD));
6645
6646 // This state is sometimes updated by template instantiation, when we
6647 // switch from the specialization referring to the template declaration
6648 // to it referring to the template definition.
6649 if (auto *MSInfo = RD->getMemberSpecializationInfo()) {
6650 Record.push_back(MSInfo->getTemplateSpecializationKind());
6651 Record.AddSourceLocation(MSInfo->getPointOfInstantiation());
6652 } else {
6654 Record.push_back(Spec->getTemplateSpecializationKind());
6655 Record.AddSourceLocation(Spec->getPointOfInstantiation());
6656
6657 // The instantiation might have been resolved to a partial
6658 // specialization. If so, record which one.
6659 auto From = Spec->getInstantiatedFrom();
6660 if (auto PartialSpec =
6661 From.dyn_cast<ClassTemplatePartialSpecializationDecl*>()) {
6662 Record.push_back(true);
6663 Record.AddDeclRef(PartialSpec);
6664 Record.AddTemplateArgumentList(
6665 &Spec->getTemplateInstantiationArgs());
6666 } else {
6667 Record.push_back(false);
6668 }
6669 }
6670 Record.push_back(llvm::to_underlying(RD->getTagKind()));
6671 Record.AddSourceLocation(RD->getLocation());
6672 Record.AddSourceLocation(RD->getBeginLoc());
6673 Record.AddSourceRange(RD->getBraceRange());
6674
6675 // Instantiation may change attributes; write them all out afresh.
6676 Record.push_back(D->hasAttrs());
6677 if (D->hasAttrs())
6678 Record.AddAttributes(D->getAttrs());
6679
6680 // FIXME: Ensure we don't get here for explicit instantiations.
6681 break;
6682 }
6683
6684 case DeclUpdateKind::CXXResolvedDtorDelete:
6685 Record.AddDeclRef(Update.getDecl());
6686 Record.AddStmt(cast<CXXDestructorDecl>(D)->getOperatorDeleteThisArg());
6687 break;
6688
6689 case DeclUpdateKind::CXXResolvedDtorGlobDelete:
6690 Record.AddDeclRef(Update.getDecl());
6691 break;
6692
6693 case DeclUpdateKind::CXXResolvedDtorArrayDelete:
6694 Record.AddDeclRef(Update.getDecl());
6695 break;
6696
6697 case DeclUpdateKind::CXXResolvedDtorGlobArrayDelete:
6698 Record.AddDeclRef(Update.getDecl());
6699 break;
6700
6701 case DeclUpdateKind::CXXResolvedExceptionSpec: {
6702 auto prototype =
6703 cast<FunctionDecl>(D)->getType()->castAs<FunctionProtoType>();
6704 Record.writeExceptionSpecInfo(prototype->getExceptionSpecInfo());
6705 break;
6706 }
6707
6708 case DeclUpdateKind::CXXDeducedReturnType:
6709 Record.push_back(GetOrCreateTypeID(Context, Update.getType()));
6710 break;
6711
6712 case DeclUpdateKind::DeclMarkedUsed:
6713 break;
6714
6715 case DeclUpdateKind::ManglingNumber:
6716 case DeclUpdateKind::StaticLocalNumber:
6717 Record.push_back(Update.getNumber());
6718 break;
6719
6720 case DeclUpdateKind::DeclMarkedOpenMPThreadPrivate:
6721 Record.AddSourceRange(
6722 D->getAttr<OMPThreadPrivateDeclAttr>()->getRange());
6723 break;
6724
6725 case DeclUpdateKind::DeclMarkedOpenMPAllocate: {
6726 auto *A = D->getAttr<OMPAllocateDeclAttr>();
6727 Record.push_back(A->getAllocatorType());
6728 Record.AddStmt(A->getAllocator());
6729 Record.AddStmt(A->getAlignment());
6730 Record.AddSourceRange(A->getRange());
6731 break;
6732 }
6733
6734 case DeclUpdateKind::DeclMarkedOpenMPIndirectCall:
6735 Record.AddSourceRange(
6736 D->getAttr<OMPTargetIndirectCallAttr>()->getRange());
6737 break;
6738
6739 case DeclUpdateKind::DeclMarkedOpenMPDeclareTarget:
6740 Record.push_back(D->getAttr<OMPDeclareTargetDeclAttr>()->getMapType());
6741 Record.AddSourceRange(
6742 D->getAttr<OMPDeclareTargetDeclAttr>()->getRange());
6743 break;
6744
6745 case DeclUpdateKind::DeclExported:
6746 Record.push_back(getSubmoduleID(Update.getModule()));
6747 break;
6748
6749 case DeclUpdateKind::AddedAttrToRecord:
6750 Record.AddAttributes(llvm::ArrayRef(Update.getAttr()));
6751 break;
6752 }
6753 }
6754
6755 // Add a trailing update record, if any. These must go last because we
6756 // lazily load their attached statement.
6757 if (!GeneratingReducedBMI || !CanElideDeclDef(D)) {
6758 if (HasUpdatedBody) {
6759 const auto *Def = cast<FunctionDecl>(D);
6760 Record.push_back(
6761 llvm::to_underlying(DeclUpdateKind::CXXAddedFunctionDefinition));
6762 Record.push_back(Def->isInlined());
6763 Record.AddSourceLocation(Def->getInnerLocStart());
6764 Record.AddFunctionDefinition(Def);
6765 } else if (HasAddedVarDefinition) {
6766 const auto *VD = cast<VarDecl>(D);
6767 Record.push_back(
6768 llvm::to_underlying(DeclUpdateKind::CXXAddedVarDefinition));
6769 Record.push_back(VD->isInline());
6770 Record.push_back(VD->isInlineSpecified());
6771 Record.AddVarDeclInit(VD);
6772 }
6773 }
6774
6775 AddDeclRef(D, OffsetsRecord);
6776 OffsetsRecord.push_back(Record.Emit(DECL_UPDATES));
6777 }
6778}
6779
6782 uint32_t Raw = Sema::AlignPackInfo::getRawEncoding(Info);
6783 Record.push_back(Raw);
6784}
6785
6786FileID ASTWriter::getAdjustedFileID(FileID FID) const {
6787 if (FID.isInvalid() || PP->getSourceManager().isLoadedFileID(FID) ||
6788 NonAffectingFileIDs.empty())
6789 return FID;
6790 auto It = llvm::lower_bound(NonAffectingFileIDs, FID);
6791 unsigned Idx = std::distance(NonAffectingFileIDs.begin(), It);
6792 unsigned Offset = NonAffectingFileIDAdjustments[Idx];
6793 return FileID::get(FID.getOpaqueValue() - Offset);
6794}
6795
6796unsigned ASTWriter::getAdjustedNumCreatedFIDs(FileID FID) const {
6797 unsigned NumCreatedFIDs = PP->getSourceManager()
6798 .getLocalSLocEntry(FID.ID)
6799 .getFile()
6800 .NumCreatedFIDs;
6801
6802 unsigned AdjustedNumCreatedFIDs = 0;
6803 for (unsigned I = FID.ID, N = I + NumCreatedFIDs; I != N; ++I)
6804 if (IsSLocAffecting[I])
6805 ++AdjustedNumCreatedFIDs;
6806 return AdjustedNumCreatedFIDs;
6807}
6808
6809SourceLocation ASTWriter::getAdjustedLocation(SourceLocation Loc) const {
6810 if (Loc.isInvalid())
6811 return Loc;
6812 return Loc.getLocWithOffset(-getAdjustment(Loc.getOffset()));
6813}
6814
6815SourceRange ASTWriter::getAdjustedRange(SourceRange Range) const {
6816 return SourceRange(getAdjustedLocation(Range.getBegin()),
6817 getAdjustedLocation(Range.getEnd()));
6818}
6819
6821ASTWriter::getAdjustedOffset(SourceLocation::UIntTy Offset) const {
6822 return Offset - getAdjustment(Offset);
6823}
6824
6826ASTWriter::getAdjustment(SourceLocation::UIntTy Offset) const {
6827 if (NonAffectingRanges.empty())
6828 return 0;
6829
6830 if (PP->getSourceManager().isLoadedOffset(Offset))
6831 return 0;
6832
6833 if (Offset > NonAffectingRanges.back().getEnd().getOffset())
6834 return NonAffectingOffsetAdjustments.back();
6835
6836 if (Offset < NonAffectingRanges.front().getBegin().getOffset())
6837 return 0;
6838
6839 auto Contains = [](const SourceRange &Range, SourceLocation::UIntTy Offset) {
6840 return Range.getEnd().getOffset() < Offset;
6841 };
6842
6843 auto It = llvm::lower_bound(NonAffectingRanges, Offset, Contains);
6844 unsigned Idx = std::distance(NonAffectingRanges.begin(), It);
6845 return NonAffectingOffsetAdjustments[Idx];
6846}
6847
6849 Record.push_back(getAdjustedFileID(FID).getOpaqueValue());
6850}
6851
6854 SourceLocation::UIntTy BaseOffset = 0;
6855 unsigned ModuleFileIndex = 0;
6856
6857 // See SourceLocationEncoding.h for the encoding details.
6858 if (PP->getSourceManager().isLoadedSourceLocation(Loc) && Loc.isValid()) {
6859 assert(getChain());
6860 auto SLocMapI = getChain()->GlobalSLocOffsetMap.find(
6861 SourceManager::MaxLoadedOffset - Loc.getOffset() - 1);
6862 assert(SLocMapI != getChain()->GlobalSLocOffsetMap.end() &&
6863 "Corrupted global sloc offset map");
6864 ModuleFile *F = SLocMapI->second;
6865 BaseOffset = F->SLocEntryBaseOffset - 2;
6866 // 0 means the location is not loaded. So we need to add 1 to the index to
6867 // make it clear.
6868 ModuleFileIndex = F->Index + 1;
6869 assert(&getChain()->getModuleManager()[F->Index] == F);
6870 }
6871
6872 return SourceLocationEncoding::encode(Loc, BaseOffset, ModuleFileIndex);
6873}
6874
6876 Loc = getAdjustedLocation(Loc);
6877 Record.push_back(getRawSourceLocationEncoding(Loc));
6878}
6879
6881 AddSourceLocation(Range.getBegin(), Record);
6882 AddSourceLocation(Range.getEnd(), Record);
6883}
6884
6885void ASTRecordWriter::AddAPFloat(const llvm::APFloat &Value) {
6886 AddAPInt(Value.bitcastToAPInt());
6887}
6888
6892
6894 if (!II)
6895 return 0;
6896
6897 IdentifierID &ID = IdentifierIDs[II];
6898 if (ID == 0)
6899 ID = NextIdentID++;
6900 return ID;
6901}
6902
6904 // Don't emit builtin macros like __LINE__ to the AST file unless they
6905 // have been redefined by the header (in which case they are not
6906 // isBuiltinMacro).
6907 if (!MI || MI->isBuiltinMacro())
6908 return 0;
6909
6910 MacroID &ID = MacroIDs[MI];
6911 if (ID == 0) {
6912 ID = NextMacroID++;
6913 MacroInfoToEmitData Info = { Name, MI, ID };
6914 MacroInfosToEmit.push_back(Info);
6915 }
6916 return ID;
6917}
6918
6920 return IdentMacroDirectivesOffsetMap.lookup(Name);
6921}
6922
6924 Record->push_back(Writer->getSelectorRef(SelRef));
6925}
6926
6928 if (Sel.getAsOpaquePtr() == nullptr) {
6929 return 0;
6930 }
6931
6932 SelectorID SID = SelectorIDs[Sel];
6933 if (SID == 0 && Chain) {
6934 // This might trigger a ReadSelector callback, which will set the ID for
6935 // this selector.
6936 Chain->LoadSelector(Sel);
6937 SID = SelectorIDs[Sel];
6938 }
6939 if (SID == 0) {
6940 SID = NextSelectorID++;
6941 SelectorIDs[Sel] = SID;
6942 }
6943 return SID;
6944}
6945
6949
6978
6981
6983 bool InfoHasSameExpr
6984 = Arg.getArgument().getAsExpr() == Arg.getLocInfo().getAsExpr();
6985 Record->push_back(InfoHasSameExpr);
6986 if (InfoHasSameExpr)
6987 return; // Avoid storing the same expr twice.
6988 }
6990}
6991
6993 if (!TInfo) {
6995 return;
6996 }
6997
6998 AddTypeRef(TInfo->getType());
6999 AddTypeLoc(TInfo->getTypeLoc());
7000}
7001
7003 TypeLocWriter TLW(*this);
7004 for (; !TL.isNull(); TL = TL.getNextTypeLoc())
7005 TLW.Visit(TL);
7006}
7007
7010 Record.push_back(GetOrCreateTypeID(Context, T));
7011}
7012
7013template <typename IdxForTypeTy>
7015 IdxForTypeTy IdxForType) {
7016 if (T.isNull())
7017 return PREDEF_TYPE_NULL_ID;
7018
7019 unsigned FastQuals = T.getLocalFastQualifiers();
7020 T.removeLocalFastQualifiers();
7021
7022 if (T.hasLocalNonFastQualifiers())
7023 return IdxForType(T).asTypeID(FastQuals);
7024
7025 assert(!T.hasLocalQualifiers());
7026
7027 if (const BuiltinType *BT = dyn_cast<BuiltinType>(T.getTypePtr()))
7028 return TypeIdxFromBuiltin(BT).asTypeID(FastQuals);
7029
7030 if (T == Context.AutoDeductTy)
7031 return TypeIdx(0, PREDEF_TYPE_AUTO_DEDUCT).asTypeID(FastQuals);
7032 if (T == Context.AutoRRefDeductTy)
7033 return TypeIdx(0, PREDEF_TYPE_AUTO_RREF_DEDUCT).asTypeID(FastQuals);
7034
7035 return IdxForType(T).asTypeID(FastQuals);
7036}
7037
7039 return MakeTypeID(Context, T, [&](QualType T) -> TypeIdx {
7040 if (T.isNull())
7041 return TypeIdx();
7042 assert(!T.getLocalFastQualifiers());
7043
7044 TypeIdx &Idx = TypeIdxs[T];
7045 if (Idx.getValue() == 0) {
7046 if (DoneWritingDeclsAndTypes) {
7047 assert(0 && "New type seen after serializing all the types to emit!");
7048 return TypeIdx();
7049 }
7050
7051 // We haven't seen this type before. Assign it a new ID and put it
7052 // into the queue of types to emit.
7053 Idx = TypeIdx(0, NextTypeID++);
7054 DeclTypesToEmit.push(T);
7055 }
7056 return Idx;
7057 });
7058}
7059
7060llvm::MapVector<ModuleFile *, const Decl *>
7062 llvm::MapVector<ModuleFile *, const Decl *> Firsts;
7063 // FIXME: We can skip entries that we know are implied by others.
7064 for (const Decl *R = D->getMostRecentDecl(); R; R = R->getPreviousDecl()) {
7065 if (R->isFromASTFile())
7066 Firsts[Chain->getOwningModuleFile(R)] = R;
7067 else if (IncludeLocal)
7068 Firsts[nullptr] = R;
7069 }
7070 return Firsts;
7071}
7072
7075 Record.push_back(Offsets.LexicalOffset);
7076 Record.push_back(Offsets.VisibleOffset);
7077 Record.push_back(Offsets.ModuleLocalOffset);
7078 Record.push_back(Offsets.TULocalOffset);
7079}
7080
7083 MacroID MacroRef = getMacroRef(MI, Name);
7084 Record.push_back(MacroRef >> 32);
7085 Record.push_back(MacroRef & llvm::maskTrailingOnes<MacroID>(32));
7086}
7087
7089 if (!wasDeclEmitted(D))
7090 return;
7091
7092 AddDeclRef(D, Record);
7093}
7094
7096 Record.push_back(GetDeclRef(D).getRawValue());
7097}
7098
7100 assert(WritingAST && "Cannot request a declaration ID before AST writing");
7101
7102 if (!D) {
7103 return LocalDeclID();
7104 }
7105
7106 getLazyUpdates(D);
7107
7108 // If D comes from an AST file, its declaration ID is already known and
7109 // fixed.
7110 if (D->isFromASTFile()) {
7112 TouchedTopLevelModules.insert(D->getOwningModule()->getTopLevelModule());
7113
7114 return LocalDeclID(D->getGlobalID());
7115 }
7116
7117 assert(!(reinterpret_cast<uintptr_t>(D) & 0x01) && "Invalid decl pointer");
7118 LocalDeclID &ID = DeclIDs[D];
7119 if (ID.isInvalid()) {
7120 if (DoneWritingDeclsAndTypes) {
7121 assert(0 && "New decl seen after serializing all the decls to emit!");
7122 return LocalDeclID();
7123 }
7124
7125 // We haven't seen this declaration before. Give it a new ID and
7126 // enqueue it in the list of declarations to emit.
7127 ID = NextDeclID++;
7128 DeclTypesToEmit.push(const_cast<Decl *>(D));
7129 }
7130
7131 return ID;
7132}
7133
7135 if (!D)
7136 return LocalDeclID();
7137
7138 // If D comes from an AST file, its declaration ID is already known and
7139 // fixed.
7140 if (D->isFromASTFile())
7141 return LocalDeclID(D->getGlobalID());
7142
7143 assert(DeclIDs.contains(D) && "Declaration not emitted!");
7144 return DeclIDs[D];
7145}
7146
7147bool ASTWriter::wasDeclEmitted(const Decl *D) const {
7148 assert(D);
7149
7150 assert(DoneWritingDeclsAndTypes &&
7151 "wasDeclEmitted should only be called after writing declarations");
7152
7153 if (D->isFromASTFile())
7154 return true;
7155
7156 bool Emitted = DeclIDs.contains(D);
7157 assert((Emitted || (!D->getOwningModule() && isWritingStdCXXNamedModules()) ||
7158 GeneratingReducedBMI) &&
7159 "The declaration within modules can only be omitted in reduced BMI.");
7160 return Emitted;
7161}
7162
7163void ASTWriter::getLazyUpdates(const Decl *D) {
7164 if (!GeneratingReducedBMI)
7165 return;
7166
7167 if (auto *Iter = DeclUpdatesLazy.find(D); Iter != DeclUpdatesLazy.end()) {
7168 for (DeclUpdate &Update : Iter->second)
7169 DeclUpdates[D].push_back(Update);
7170 DeclUpdatesLazy.erase(Iter);
7171 }
7172
7173 // If the Decl in DeclUpdatesLazy gets touched, emit the update.
7174 if (auto *DC = dyn_cast<DeclContext>(D);
7175 DC && UpdatedDeclContextsLazy.count(DC)) {
7176 UpdatedDeclContexts.insert(DC);
7177 UpdatedDeclContextsLazy.remove(DC);
7178 }
7179}
7180
7181void ASTWriter::associateDeclWithFile(const Decl *D, LocalDeclID ID) {
7182 assert(ID.isValid());
7183 assert(D);
7184
7185 SourceLocation Loc = D->getLocation();
7186 if (Loc.isInvalid())
7187 return;
7188
7189 // We only keep track of the file-level declarations of each file.
7191 return;
7192 // FIXME: ParmVarDecls that are part of a function type of a parameter of
7193 // a function/objc method, should not have TU as lexical context.
7194 // TemplateTemplateParmDecls that are part of an alias template, should not
7195 // have TU as lexical context.
7197 return;
7198
7199 SourceManager &SM = PP->getSourceManager();
7200 SourceLocation FileLoc = SM.getFileLoc(Loc);
7201 assert(SM.isLocalSourceLocation(FileLoc));
7202 auto [FID, Offset] = SM.getDecomposedLoc(FileLoc);
7203 if (FID.isInvalid())
7204 return;
7205 assert(SM.getSLocEntry(FID).isFile());
7206 assert(IsSLocAffecting[FID.ID]);
7207
7208 std::unique_ptr<DeclIDInFileInfo> &Info = FileDeclIDs[FID];
7209 if (!Info)
7210 Info = std::make_unique<DeclIDInFileInfo>();
7211
7212 std::pair<unsigned, LocalDeclID> LocDecl(Offset, ID);
7213 LocDeclIDsTy &Decls = Info->DeclIDs;
7214 Decls.push_back(LocDecl);
7215}
7216
7219 "expected an anonymous declaration");
7220
7221 // Number the anonymous declarations within this context, if we've not
7222 // already done so.
7223 auto It = AnonymousDeclarationNumbers.find(D);
7224 if (It == AnonymousDeclarationNumbers.end()) {
7225 auto *DC = D->getLexicalDeclContext();
7226 numberAnonymousDeclsWithin(DC, [&](const NamedDecl *ND, unsigned Number) {
7227 AnonymousDeclarationNumbers[ND] = Number;
7228 });
7229
7230 It = AnonymousDeclarationNumbers.find(D);
7231 assert(It != AnonymousDeclarationNumbers.end() &&
7232 "declaration not found within its lexical context");
7233 }
7234
7235 return It->second;
7236}
7237
7264
7266 const DeclarationNameInfo &NameInfo) {
7267 AddDeclarationName(NameInfo.getName());
7268 AddSourceLocation(NameInfo.getLoc());
7269 AddDeclarationNameLoc(NameInfo.getInfo(), NameInfo.getName());
7270}
7271
7274 Record->push_back(Info.NumTemplParamLists);
7275 for (unsigned i = 0, e = Info.NumTemplParamLists; i != e; ++i)
7277}
7278
7280 NestedNameSpecifierLoc QualifierLoc) {
7281 // Nested name specifiers usually aren't too long. I think that 8 would
7282 // typically accommodate the vast majority.
7284
7285 // Push each of the nested-name-specifiers's onto a stack for
7286 // serialization in reverse order.
7287 while (QualifierLoc) {
7288 NestedNames.push_back(QualifierLoc);
7289 QualifierLoc = QualifierLoc.getAsNamespaceAndPrefix().Prefix;
7290 }
7291
7292 Record->push_back(NestedNames.size());
7293 while(!NestedNames.empty()) {
7294 QualifierLoc = NestedNames.pop_back_val();
7295 NestedNameSpecifier Qualifier = QualifierLoc.getNestedNameSpecifier();
7296 NestedNameSpecifier::Kind Kind = Qualifier.getKind();
7297 Record->push_back(llvm::to_underlying(Kind));
7298 switch (Kind) {
7300 AddDeclRef(Qualifier.getAsNamespaceAndPrefix().Namespace);
7301 AddSourceRange(QualifierLoc.getLocalSourceRange());
7302 break;
7303
7305 TypeLoc TL = QualifierLoc.castAsTypeLoc();
7306 AddTypeRef(TL.getType());
7307 AddTypeLoc(TL);
7309 break;
7310 }
7311
7314 break;
7315
7317 AddDeclRef(Qualifier.getAsMicrosoftSuper());
7318 AddSourceRange(QualifierLoc.getLocalSourceRange());
7319 break;
7320
7322 llvm_unreachable("unexpected null nested name specifier");
7323 }
7324 }
7325}
7326
7328 const TemplateParameterList *TemplateParams) {
7329 assert(TemplateParams && "No TemplateParams!");
7330 AddSourceLocation(TemplateParams->getTemplateLoc());
7331 AddSourceLocation(TemplateParams->getLAngleLoc());
7332 AddSourceLocation(TemplateParams->getRAngleLoc());
7333
7334 Record->push_back(TemplateParams->size());
7335 for (const auto &P : *TemplateParams)
7336 AddDeclRef(P);
7337 if (const Expr *RequiresClause = TemplateParams->getRequiresClause()) {
7338 Record->push_back(true);
7339 writeStmtRef(RequiresClause);
7340 } else {
7341 Record->push_back(false);
7342 }
7343}
7344
7345/// Emit a template argument list.
7347 const TemplateArgumentList *TemplateArgs) {
7348 assert(TemplateArgs && "No TemplateArgs!");
7349 Record->push_back(TemplateArgs->size());
7350 for (int i = 0, e = TemplateArgs->size(); i != e; ++i)
7351 AddTemplateArgument(TemplateArgs->get(i));
7352}
7353
7355 const ASTTemplateArgumentListInfo *ASTTemplArgList) {
7356 assert(ASTTemplArgList && "No ASTTemplArgList!");
7357 AddSourceLocation(ASTTemplArgList->LAngleLoc);
7358 AddSourceLocation(ASTTemplArgList->RAngleLoc);
7359 Record->push_back(ASTTemplArgList->NumTemplateArgs);
7360 const TemplateArgumentLoc *TemplArgs = ASTTemplArgList->getTemplateArgs();
7361 for (int i = 0, e = ASTTemplArgList->NumTemplateArgs; i != e; ++i)
7362 AddTemplateArgumentLoc(TemplArgs[i]);
7363}
7364
7366 Record->push_back(Set.size());
7368 I = Set.begin(), E = Set.end(); I != E; ++I) {
7369 AddDeclRef(I.getDecl());
7370 Record->push_back(I.getAccess());
7371 }
7372}
7373
7374// FIXME: Move this out of the main ASTRecordWriter interface.
7376 Record->push_back(Base.isVirtual());
7377 Record->push_back(Base.isBaseOfClass());
7378 Record->push_back(Base.getAccessSpecifierAsWritten());
7379 Record->push_back(Base.getInheritConstructors());
7380 AddTypeSourceInfo(Base.getTypeSourceInfo());
7381 AddSourceRange(Base.getSourceRange());
7382 AddSourceLocation(Base.isPackExpansion()? Base.getEllipsisLoc()
7383 : SourceLocation());
7384}
7385
7386static uint64_t EmitCXXBaseSpecifiers(ASTContext &Context, ASTWriter &W,
7389 ASTRecordWriter Writer(Context, W, Record);
7390 Writer.push_back(Bases.size());
7391
7392 for (auto &Base : Bases)
7393 Writer.AddCXXBaseSpecifier(Base);
7394
7396}
7397
7398// FIXME: Move this out of the main ASTRecordWriter interface.
7402
7403static uint64_t
7407 ASTRecordWriter Writer(Context, W, Record);
7408 Writer.push_back(CtorInits.size());
7409
7410 for (auto *Init : CtorInits) {
7411 if (Init->isBaseInitializer()) {
7413 Writer.AddTypeSourceInfo(Init->getTypeSourceInfo());
7414 Writer.push_back(Init->isBaseVirtual());
7415 } else if (Init->isDelegatingInitializer()) {
7417 Writer.AddTypeSourceInfo(Init->getTypeSourceInfo());
7418 } else if (Init->isMemberInitializer()){
7420 Writer.AddDeclRef(Init->getMember());
7421 } else {
7423 Writer.AddDeclRef(Init->getIndirectMember());
7424 }
7425
7426 Writer.AddSourceLocation(Init->getMemberLocation());
7427 Writer.AddStmt(Init->getInit());
7428 Writer.AddSourceLocation(Init->getLParenLoc());
7429 Writer.AddSourceLocation(Init->getRParenLoc());
7430 Writer.push_back(Init->isWritten());
7431 if (Init->isWritten())
7432 Writer.push_back(Init->getSourceOrder());
7433 }
7434
7436}
7437
7438// FIXME: Move this out of the main ASTRecordWriter interface.
7441 AddOffset(EmitCXXCtorInitializers(getASTContext(), *Writer, CtorInits));
7442}
7443
7445 auto &Data = D->data();
7446
7447 Record->push_back(Data.IsLambda);
7448
7449 BitsPacker DefinitionBits;
7450
7451#define FIELD(Name, Width, Merge) \
7452 if (!DefinitionBits.canWriteNextNBits(Width)) { \
7453 Record->push_back(DefinitionBits); \
7454 DefinitionBits.reset(0); \
7455 } \
7456 DefinitionBits.addBits(Data.Name, Width);
7457
7458#include "clang/AST/CXXRecordDeclDefinitionBits.def"
7459#undef FIELD
7460
7461 Record->push_back(DefinitionBits);
7462
7463 // getODRHash will compute the ODRHash if it has not been previously
7464 // computed.
7465 Record->push_back(D->getODRHash());
7466
7467 bool ModulesCodegen =
7468 !D->isDependentType() &&
7471 (Writer->getLangOpts().ModulesDebugInfo || D->isInNamedModule());
7472 Record->push_back(ModulesCodegen);
7473 if (ModulesCodegen)
7474 Writer->AddDeclRef(D, Writer->ModularCodegenDecls);
7475
7476 // IsLambda bit is already saved.
7477
7478 AddUnresolvedSet(Data.Conversions.get(getASTContext()));
7479 Record->push_back(Data.ComputedVisibleConversions);
7480 if (Data.ComputedVisibleConversions)
7481 AddUnresolvedSet(Data.VisibleConversions.get(getASTContext()));
7482 // Data.Definition is the owning decl, no need to write it.
7483
7484 if (!Data.IsLambda) {
7485 Record->push_back(Data.NumBases);
7486 if (Data.NumBases > 0)
7487 AddCXXBaseSpecifiers(Data.bases());
7488
7489 // FIXME: Make VBases lazily computed when needed to avoid storing them.
7490 Record->push_back(Data.NumVBases);
7491 if (Data.NumVBases > 0)
7492 AddCXXBaseSpecifiers(Data.vbases());
7493
7494 AddDeclRef(D->getFirstFriend());
7495 } else {
7496 auto &Lambda = D->getLambdaData();
7497
7498 BitsPacker LambdaBits;
7499 LambdaBits.addBits(Lambda.DependencyKind, /*Width=*/2);
7500 LambdaBits.addBit(Lambda.IsGenericLambda);
7501 LambdaBits.addBits(Lambda.CaptureDefault, /*Width=*/2);
7502 LambdaBits.addBits(Lambda.NumCaptures, /*Width=*/15);
7503 LambdaBits.addBit(Lambda.HasKnownInternalLinkage);
7504 Record->push_back(LambdaBits);
7505
7506 Record->push_back(Lambda.NumExplicitCaptures);
7507 Record->push_back(Lambda.ManglingNumber);
7508 Record->push_back(D->getDeviceLambdaManglingNumber());
7509 // The lambda context declaration and index within the context are provided
7510 // separately, so that they can be used for merging.
7511 AddTypeSourceInfo(Lambda.MethodTyInfo);
7512 for (unsigned I = 0, N = Lambda.NumCaptures; I != N; ++I) {
7513 const LambdaCapture &Capture = Lambda.Captures.front()[I];
7515
7516 BitsPacker CaptureBits;
7517 CaptureBits.addBit(Capture.isImplicit());
7518 CaptureBits.addBits(Capture.getCaptureKind(), /*Width=*/3);
7519 Record->push_back(CaptureBits);
7520
7521 switch (Capture.getCaptureKind()) {
7522 case LCK_StarThis:
7523 case LCK_This:
7524 case LCK_VLAType:
7525 break;
7526 case LCK_ByCopy:
7527 case LCK_ByRef:
7528 ValueDecl *Var =
7529 Capture.capturesVariable() ? Capture.getCapturedVar() : nullptr;
7530 AddDeclRef(Var);
7531 AddSourceLocation(Capture.isPackExpansion() ? Capture.getEllipsisLoc()
7532 : SourceLocation());
7533 break;
7534 }
7535 }
7536 }
7537}
7538
7540 const Expr *Init = VD->getInit();
7541 if (!Init) {
7542 push_back(0);
7543 return;
7544 }
7545
7546 uint64_t Val = 1;
7547 if (EvaluatedStmt *ES = VD->getEvaluatedStmt()) {
7548 // This may trigger evaluation, so run it first
7549 if (VD->hasInitWithSideEffects())
7550 Val |= 16;
7551 assert(ES->CheckedForSideEffects);
7552 Val |= (ES->HasConstantInitialization ? 2 : 0);
7553 Val |= (ES->HasConstantDestruction ? 4 : 0);
7554 const APValue *Evaluated = VD->getEvaluatedValue();
7555 // If the evaluated result is constant, emit it.
7556 if (Evaluated && (Evaluated->isInt() || Evaluated->isFloat()))
7557 Val |= 8;
7558 }
7559 push_back(Val);
7560 if (Val & 8) {
7562 }
7563
7565}
7566
7567void ASTWriter::ReaderInitialized(ASTReader *Reader) {
7568 assert(Reader && "Cannot remove chain");
7569 assert((!Chain || Chain == Reader) && "Cannot replace chain");
7570 assert(FirstDeclID == NextDeclID &&
7571 FirstTypeID == NextTypeID &&
7572 FirstIdentID == NextIdentID &&
7573 FirstMacroID == NextMacroID &&
7574 FirstSubmoduleID == NextSubmoduleID &&
7575 FirstSelectorID == NextSelectorID &&
7576 "Setting chain after writing has started.");
7577
7578 Chain = Reader;
7579
7580 FirstSubmoduleID = NUM_PREDEF_SUBMODULE_IDS + Chain->getTotalNumSubmodules();
7581 FirstSelectorID = NUM_PREDEF_SELECTOR_IDS + Chain->getTotalNumSelectors();
7582 NextSelectorID = FirstSelectorID;
7583 NextSubmoduleID = FirstSubmoduleID;
7584}
7585
7586void ASTWriter::IdentifierRead(IdentifierID ID, IdentifierInfo *II) {
7587 // Don't reuse Type ID from external modules for named modules. See the
7588 // comments in WriteASTCore for details.
7590 return;
7591
7592 IdentifierID &StoredID = IdentifierIDs[II];
7593 unsigned OriginalModuleFileIndex = StoredID >> 32;
7594
7595 // Always keep the local identifier ID. See \p TypeRead() for more
7596 // information.
7597 if (OriginalModuleFileIndex == 0 && StoredID)
7598 return;
7599
7600 // Otherwise, keep the highest ID since the module file comes later has
7601 // higher module file indexes.
7602 if (ID > StoredID)
7603 StoredID = ID;
7604}
7605
7606void ASTWriter::MacroRead(serialization::MacroID ID, MacroInfo *MI) {
7607 // Always keep the highest ID. See \p TypeRead() for more information.
7608 MacroID &StoredID = MacroIDs[MI];
7609 unsigned OriginalModuleFileIndex = StoredID >> 32;
7610
7611 // Always keep the local macro ID. See \p TypeRead() for more information.
7612 if (OriginalModuleFileIndex == 0 && StoredID)
7613 return;
7614
7615 // Otherwise, keep the highest ID since the module file comes later has
7616 // higher module file indexes.
7617 if (ID > StoredID)
7618 StoredID = ID;
7619}
7620
7621void ASTWriter::TypeRead(TypeIdx Idx, QualType T) {
7622 // Don't reuse Type ID from external modules for named modules. See the
7623 // comments in WriteASTCore for details.
7625 return;
7626
7627 // Always take the type index that comes in later module files.
7628 // This copes with an interesting
7629 // case for chained AST writing where we schedule writing the type and then,
7630 // later, deserialize the type from another AST. In this case, we want to
7631 // keep the entry from a later module so that we can properly write it out to
7632 // the AST file.
7633 TypeIdx &StoredIdx = TypeIdxs[T];
7634
7635 // Ignore it if the type comes from the current being written module file.
7636 // Since the current module file being written logically has the highest
7637 // index.
7638 unsigned ModuleFileIndex = StoredIdx.getModuleFileIndex();
7639 if (ModuleFileIndex == 0 && StoredIdx.getValue())
7640 return;
7641
7642 // Otherwise, keep the highest ID since the module file comes later has
7643 // higher module file indexes.
7644 if (Idx.getModuleFileIndex() >= StoredIdx.getModuleFileIndex())
7645 StoredIdx = Idx;
7646}
7647
7648void ASTWriter::PredefinedDeclBuilt(PredefinedDeclIDs ID, const Decl *D) {
7649 assert(D->isCanonicalDecl() && "predefined decl is not canonical");
7650 DeclIDs[D] = LocalDeclID(ID);
7651 PredefinedDecls.insert(D);
7652}
7653
7654void ASTWriter::SelectorRead(SelectorID ID, Selector S) {
7655 // Always keep the highest ID. See \p TypeRead() for more information.
7656 SelectorID &StoredID = SelectorIDs[S];
7657 if (ID > StoredID)
7658 StoredID = ID;
7659}
7660
7661void ASTWriter::MacroDefinitionRead(serialization::PreprocessedEntityID ID,
7663 assert(!MacroDefinitions.contains(MD));
7664 MacroDefinitions[MD] = ID;
7665}
7666
7667void ASTWriter::ModuleRead(serialization::SubmoduleID ID, Module *Mod) {
7668 assert(!SubmoduleIDs.contains(Mod));
7669 SubmoduleIDs[Mod] = ID;
7670}
7671
7672void ASTWriter::CompletedTagDefinition(const TagDecl *D) {
7673 if (Chain && Chain->isProcessingUpdateRecords()) return;
7674 assert(D->isCompleteDefinition());
7675 assert(!WritingAST && "Already writing the AST!");
7676 if (auto *RD = dyn_cast<CXXRecordDecl>(D)) {
7677 // We are interested when a PCH decl is modified.
7678 if (RD->isFromASTFile()) {
7679 // A forward reference was mutated into a definition. Rewrite it.
7680 // FIXME: This happens during template instantiation, should we
7681 // have created a new definition decl instead ?
7682 assert(isTemplateInstantiation(RD->getTemplateSpecializationKind()) &&
7683 "completed a tag from another module but not by instantiation?");
7684 DeclUpdates[RD].push_back(
7685 DeclUpdate(DeclUpdateKind::CXXInstantiatedClassDefinition));
7686 }
7687 }
7688}
7689
7690static bool isImportedDeclContext(ASTReader *Chain, const Decl *D) {
7691 if (D->isFromASTFile())
7692 return true;
7693
7694 // The predefined __va_list_tag struct is imported if we imported any decls.
7695 // FIXME: This is a gross hack.
7696 return D == D->getASTContext().getVaListTagDecl();
7697}
7698
7699void ASTWriter::AddedVisibleDecl(const DeclContext *DC, const Decl *D) {
7700 if (Chain && Chain->isProcessingUpdateRecords()) return;
7701 assert(DC->isLookupContext() &&
7702 "Should not add lookup results to non-lookup contexts!");
7703
7704 // TU is handled elsewhere.
7706 return;
7707
7708 // Namespaces are handled elsewhere, except for template instantiations of
7709 // FunctionTemplateDecls in namespaces. We are interested in cases where the
7710 // local instantiations are added to an imported context. Only happens when
7711 // adding ADL lookup candidates, for example templated friends.
7714 return;
7715
7716 // We're only interested in cases where a local declaration is added to an
7717 // imported context.
7718 if (D->isFromASTFile() || !isImportedDeclContext(Chain, cast<Decl>(DC)))
7719 return;
7720
7721 assert(DC == DC->getPrimaryContext() && "added to non-primary context");
7722 assert(!getDefinitiveDeclContext(DC) && "DeclContext not definitive!");
7723 assert(!WritingAST && "Already writing the AST!");
7724 if (UpdatedDeclContexts.insert(DC) && !cast<Decl>(DC)->isFromASTFile()) {
7725 // We're adding a visible declaration to a predefined decl context. Ensure
7726 // that we write out all of its lookup results so we don't get a nasty
7727 // surprise when we try to emit its lookup table.
7728 llvm::append_range(DeclsToEmitEvenIfUnreferenced, DC->decls());
7729 }
7730 DeclsToEmitEvenIfUnreferenced.push_back(D);
7731}
7732
7733void ASTWriter::AddedCXXImplicitMember(const CXXRecordDecl *RD, const Decl *D) {
7734 if (Chain && Chain->isProcessingUpdateRecords()) return;
7735 assert(D->isImplicit());
7736
7737 // We're only interested in cases where a local declaration is added to an
7738 // imported context.
7739 if (D->isFromASTFile() || !isImportedDeclContext(Chain, RD))
7740 return;
7741
7742 if (!isa<CXXMethodDecl>(D))
7743 return;
7744
7745 // A decl coming from PCH was modified.
7746 assert(RD->isCompleteDefinition());
7747 assert(!WritingAST && "Already writing the AST!");
7748 DeclUpdates[RD].push_back(
7749 DeclUpdate(DeclUpdateKind::CXXAddedImplicitMember, D));
7750}
7751
7752void ASTWriter::ResolvedExceptionSpec(const FunctionDecl *FD) {
7753 if (Chain && Chain->isProcessingUpdateRecords()) return;
7754 assert(!DoneWritingDeclsAndTypes && "Already done writing updates!");
7755 if (!Chain) return;
7756 Chain->forEachImportedKeyDecl(FD, [&](const Decl *D) {
7757 // If we don't already know the exception specification for this redecl
7758 // chain, add an update record for it.
7760 ->getType()
7761 ->castAs<FunctionProtoType>()
7762 ->getExceptionSpecType()))
7763 DeclUpdates[D].push_back(DeclUpdateKind::CXXResolvedExceptionSpec);
7764 });
7765}
7766
7767void ASTWriter::DeducedReturnType(const FunctionDecl *FD, QualType ReturnType) {
7768 if (Chain && Chain->isProcessingUpdateRecords()) return;
7769 assert(!WritingAST && "Already writing the AST!");
7770 if (!Chain) return;
7771 Chain->forEachImportedKeyDecl(FD, [&](const Decl *D) {
7772 DeclUpdates[D].push_back(
7773 DeclUpdate(DeclUpdateKind::CXXDeducedReturnType, ReturnType));
7774 });
7775}
7776
7777void ASTWriter::ResolvedOperatorDelete(const CXXDestructorDecl *DD,
7778 const FunctionDecl *Delete,
7779 Expr *ThisArg) {
7780 if (Chain && Chain->isProcessingUpdateRecords()) return;
7781 assert(!WritingAST && "Already writing the AST!");
7782 assert(Delete && "Not given an operator delete");
7783 if (!Chain) return;
7784 Chain->forEachImportedKeyDecl(DD, [&](const Decl *D) {
7785 DeclUpdates[D].push_back(
7786 DeclUpdate(DeclUpdateKind::CXXResolvedDtorDelete, Delete));
7787 });
7788}
7789
7790void ASTWriter::ResolvedOperatorGlobDelete(const CXXDestructorDecl *DD,
7791 const FunctionDecl *GlobDelete) {
7792 if (Chain && Chain->isProcessingUpdateRecords())
7793 return;
7794 assert(!WritingAST && "Already writing the AST!");
7795 assert(GlobDelete && "Not given an operator delete");
7796 if (!Chain)
7797 return;
7798 Chain->forEachImportedKeyDecl(DD, [&](const Decl *D) {
7799 DeclUpdates[D].push_back(
7800 DeclUpdate(DeclUpdateKind::CXXResolvedDtorGlobDelete, GlobDelete));
7801 });
7802}
7803
7804void ASTWriter::ResolvedOperatorArrayDelete(const CXXDestructorDecl *DD,
7805 const FunctionDecl *ArrayDelete) {
7806 if (Chain && Chain->isProcessingUpdateRecords())
7807 return;
7808 assert(!WritingAST && "Already writing the AST!");
7809 assert(ArrayDelete && "Not given an operator delete");
7810 if (!Chain)
7811 return;
7812 Chain->forEachImportedKeyDecl(DD, [&](const Decl *D) {
7813 DeclUpdates[D].push_back(
7814 DeclUpdate(DeclUpdateKind::CXXResolvedDtorArrayDelete, ArrayDelete));
7815 });
7816}
7817
7818void ASTWriter::ResolvedOperatorGlobArrayDelete(
7819 const CXXDestructorDecl *DD, const FunctionDecl *GlobArrayDelete) {
7820 if (Chain && Chain->isProcessingUpdateRecords())
7821 return;
7822 assert(!WritingAST && "Already writing the AST!");
7823 assert(GlobArrayDelete && "Not given an operator delete");
7824 if (!Chain)
7825 return;
7826 Chain->forEachImportedKeyDecl(DD, [&](const Decl *D) {
7827 DeclUpdates[D].push_back(DeclUpdate(
7828 DeclUpdateKind::CXXResolvedDtorGlobArrayDelete, GlobArrayDelete));
7829 });
7830}
7831
7832void ASTWriter::CompletedImplicitDefinition(const FunctionDecl *D) {
7833 if (Chain && Chain->isProcessingUpdateRecords()) return;
7834 assert(!WritingAST && "Already writing the AST!");
7835 if (!D->isFromASTFile())
7836 return; // Declaration not imported from PCH.
7837
7838 // The function definition may not have a body due to parsing errors.
7840 return;
7841
7842 // Implicit function decl from a PCH was defined.
7843 DeclUpdates[D].push_back(
7844 DeclUpdate(DeclUpdateKind::CXXAddedFunctionDefinition));
7845}
7846
7847void ASTWriter::VariableDefinitionInstantiated(const VarDecl *D) {
7848 if (Chain && Chain->isProcessingUpdateRecords()) return;
7849 assert(!WritingAST && "Already writing the AST!");
7850 if (!D->isFromASTFile())
7851 return;
7852
7853 DeclUpdates[D].push_back(DeclUpdate(DeclUpdateKind::CXXAddedVarDefinition));
7854}
7855
7856void ASTWriter::FunctionDefinitionInstantiated(const FunctionDecl *D) {
7857 if (Chain && Chain->isProcessingUpdateRecords()) return;
7858 assert(!WritingAST && "Already writing the AST!");
7859 if (!D->isFromASTFile())
7860 return;
7861
7862 // The function definition may not have a body due to parsing errors.
7864 return;
7865
7866 DeclUpdates[D].push_back(
7867 DeclUpdate(DeclUpdateKind::CXXAddedFunctionDefinition));
7868}
7869
7870void ASTWriter::InstantiationRequested(const ValueDecl *D) {
7871 if (Chain && Chain->isProcessingUpdateRecords()) return;
7872 assert(!WritingAST && "Already writing the AST!");
7873 if (!D->isFromASTFile())
7874 return;
7875
7876 // Since the actual instantiation is delayed, this really means that we need
7877 // to update the instantiation location.
7878 SourceLocation POI;
7879 if (auto *VD = dyn_cast<VarDecl>(D))
7880 POI = VD->getPointOfInstantiation();
7881 else
7882 POI = cast<FunctionDecl>(D)->getPointOfInstantiation();
7883 DeclUpdates[D].push_back(
7884 DeclUpdate(DeclUpdateKind::CXXPointOfInstantiation, POI));
7885}
7886
7887void ASTWriter::DefaultArgumentInstantiated(const ParmVarDecl *D) {
7888 if (Chain && Chain->isProcessingUpdateRecords()) return;
7889 assert(!WritingAST && "Already writing the AST!");
7890 if (!D->isFromASTFile())
7891 return;
7892
7893 DeclUpdates[D].push_back(
7894 DeclUpdate(DeclUpdateKind::CXXInstantiatedDefaultArgument, D));
7895}
7896
7897void ASTWriter::DefaultMemberInitializerInstantiated(const FieldDecl *D) {
7898 assert(!WritingAST && "Already writing the AST!");
7899 if (!D->isFromASTFile())
7900 return;
7901
7902 DeclUpdates[D].push_back(
7903 DeclUpdate(DeclUpdateKind::CXXInstantiatedDefaultMemberInitializer, D));
7904}
7905
7906void ASTWriter::AddedObjCCategoryToInterface(const ObjCCategoryDecl *CatD,
7907 const ObjCInterfaceDecl *IFD) {
7908 if (Chain && Chain->isProcessingUpdateRecords()) return;
7909 assert(!WritingAST && "Already writing the AST!");
7910 if (!IFD->isFromASTFile())
7911 return; // Declaration not imported from PCH.
7912
7913 assert(IFD->getDefinition() && "Category on a class without a definition?");
7914 ObjCClassesWithCategories.insert(
7915 const_cast<ObjCInterfaceDecl *>(IFD->getDefinition()));
7916}
7917
7918void ASTWriter::DeclarationMarkedUsed(const Decl *D) {
7919 if (Chain && Chain->isProcessingUpdateRecords()) return;
7920 assert(!WritingAST && "Already writing the AST!");
7921
7922 // If there is *any* declaration of the entity that's not from an AST file,
7923 // we can skip writing the update record. We make sure that isUsed() triggers
7924 // completion of the redeclaration chain of the entity.
7925 for (auto Prev = D->getMostRecentDecl(); Prev; Prev = Prev->getPreviousDecl())
7926 if (IsLocalDecl(Prev))
7927 return;
7928
7929 DeclUpdates[D].push_back(DeclUpdate(DeclUpdateKind::DeclMarkedUsed));
7930}
7931
7932void ASTWriter::DeclarationMarkedOpenMPThreadPrivate(const Decl *D) {
7933 if (Chain && Chain->isProcessingUpdateRecords()) return;
7934 assert(!WritingAST && "Already writing the AST!");
7935 if (!D->isFromASTFile())
7936 return;
7937
7938 DeclUpdates[D].push_back(
7939 DeclUpdate(DeclUpdateKind::DeclMarkedOpenMPThreadPrivate));
7940}
7941
7942void ASTWriter::DeclarationMarkedOpenMPAllocate(const Decl *D, const Attr *A) {
7943 if (Chain && Chain->isProcessingUpdateRecords()) return;
7944 assert(!WritingAST && "Already writing the AST!");
7945 if (!D->isFromASTFile())
7946 return;
7947
7948 DeclUpdates[D].push_back(
7949 DeclUpdate(DeclUpdateKind::DeclMarkedOpenMPAllocate, A));
7950}
7951
7952void ASTWriter::DeclarationMarkedOpenMPIndirectCall(const Decl *D) {
7953 if (Chain && Chain->isProcessingUpdateRecords())
7954 return;
7955 assert(!WritingAST && "Already writing the AST!");
7956 if (!D->isFromASTFile())
7957 return;
7958
7959 DeclUpdates[D].push_back(
7960 DeclUpdate(DeclUpdateKind::DeclMarkedOpenMPIndirectCall));
7961}
7962
7963void ASTWriter::DeclarationMarkedOpenMPDeclareTarget(const Decl *D,
7964 const Attr *Attr) {
7965 if (Chain && Chain->isProcessingUpdateRecords()) return;
7966 assert(!WritingAST && "Already writing the AST!");
7967 if (!D->isFromASTFile())
7968 return;
7969
7970 DeclUpdates[D].push_back(
7971 DeclUpdate(DeclUpdateKind::DeclMarkedOpenMPDeclareTarget, Attr));
7972}
7973
7974void ASTWriter::RedefinedHiddenDefinition(const NamedDecl *D, Module *M) {
7975 if (Chain && Chain->isProcessingUpdateRecords()) return;
7976 assert(!WritingAST && "Already writing the AST!");
7977 assert(!D->isUnconditionallyVisible() && "expected a hidden declaration");
7978 DeclUpdates[D].push_back(DeclUpdate(DeclUpdateKind::DeclExported, M));
7979}
7980
7981void ASTWriter::AddedAttributeToRecord(const Attr *Attr,
7982 const RecordDecl *Record) {
7983 if (Chain && Chain->isProcessingUpdateRecords()) return;
7984 assert(!WritingAST && "Already writing the AST!");
7985 if (!Record->isFromASTFile())
7986 return;
7987 DeclUpdates[Record].push_back(
7988 DeclUpdate(DeclUpdateKind::AddedAttrToRecord, Attr));
7989}
7990
7991void ASTWriter::AddedCXXTemplateSpecialization(
7993 assert(!WritingAST && "Already writing the AST!");
7994
7995 if (!TD->getFirstDecl()->isFromASTFile())
7996 return;
7997 if (Chain && Chain->isProcessingUpdateRecords())
7998 return;
7999
8000 DeclsToEmitEvenIfUnreferenced.push_back(D);
8001}
8002
8003void ASTWriter::AddedCXXTemplateSpecialization(
8004 const VarTemplateDecl *TD, const VarTemplateSpecializationDecl *D) {
8005 assert(!WritingAST && "Already writing the AST!");
8006
8007 if (!TD->getFirstDecl()->isFromASTFile())
8008 return;
8009 if (Chain && Chain->isProcessingUpdateRecords())
8010 return;
8011
8012 DeclsToEmitEvenIfUnreferenced.push_back(D);
8013}
8014
8015void ASTWriter::AddedCXXTemplateSpecialization(const FunctionTemplateDecl *TD,
8016 const FunctionDecl *D) {
8017 assert(!WritingAST && "Already writing the AST!");
8018
8019 if (!TD->getFirstDecl()->isFromASTFile())
8020 return;
8021 if (Chain && Chain->isProcessingUpdateRecords())
8022 return;
8023
8024 DeclsToEmitEvenIfUnreferenced.push_back(D);
8025}
8026
8027//===----------------------------------------------------------------------===//
8028//// OMPClause Serialization
8029////===----------------------------------------------------------------------===//
8030
8031namespace {
8032
8033class OMPClauseWriter : public OMPClauseVisitor<OMPClauseWriter> {
8034 ASTRecordWriter &Record;
8035
8036public:
8037 OMPClauseWriter(ASTRecordWriter &Record) : Record(Record) {}
8038#define GEN_CLANG_CLAUSE_CLASS
8039#define CLAUSE_CLASS(Enum, Str, Class) void Visit##Class(Class *S);
8040#include "llvm/Frontend/OpenMP/OMP.inc"
8041 void writeClause(OMPClause *C);
8042 void VisitOMPClauseWithPreInit(OMPClauseWithPreInit *C);
8043 void VisitOMPClauseWithPostUpdate(OMPClauseWithPostUpdate *C);
8044};
8045
8046}
8047
8049 OMPClauseWriter(*this).writeClause(C);
8050}
8051
8052void OMPClauseWriter::writeClause(OMPClause *C) {
8053 Record.push_back(unsigned(C->getClauseKind()));
8054 Visit(C);
8055 Record.AddSourceLocation(C->getBeginLoc());
8056 Record.AddSourceLocation(C->getEndLoc());
8057}
8058
8059void OMPClauseWriter::VisitOMPClauseWithPreInit(OMPClauseWithPreInit *C) {
8060 Record.push_back(uint64_t(C->getCaptureRegion()));
8061 Record.AddStmt(C->getPreInitStmt());
8062}
8063
8064void OMPClauseWriter::VisitOMPClauseWithPostUpdate(OMPClauseWithPostUpdate *C) {
8065 VisitOMPClauseWithPreInit(C);
8066 Record.AddStmt(C->getPostUpdateExpr());
8067}
8068
8069void OMPClauseWriter::VisitOMPIfClause(OMPIfClause *C) {
8070 VisitOMPClauseWithPreInit(C);
8071 Record.push_back(uint64_t(C->getNameModifier()));
8072 Record.AddSourceLocation(C->getNameModifierLoc());
8073 Record.AddSourceLocation(C->getColonLoc());
8074 Record.AddStmt(C->getCondition());
8075 Record.AddSourceLocation(C->getLParenLoc());
8076}
8077
8078void OMPClauseWriter::VisitOMPFinalClause(OMPFinalClause *C) {
8079 VisitOMPClauseWithPreInit(C);
8080 Record.AddStmt(C->getCondition());
8081 Record.AddSourceLocation(C->getLParenLoc());
8082}
8083
8084void OMPClauseWriter::VisitOMPNumThreadsClause(OMPNumThreadsClause *C) {
8085 Record.push_back(C->varlist_size());
8086 Record.writeEnum(C->getPrescriptivenessModifier());
8087 Record.AddSourceLocation(C->getPrescriptivenessModifierLoc());
8088 Record.writeEnum(C->getDimsModifier());
8089 Record.AddSourceLocation(C->getDimsModifierLoc());
8090 Record.AddStmt(C->getDimsModifierExpr());
8091 VisitOMPClauseWithPreInit(C);
8092 Record.AddSourceLocation(C->getLParenLoc());
8093 for (auto *VE : C->varlist())
8094 Record.AddStmt(VE);
8095}
8096
8097void OMPClauseWriter::VisitOMPSafelenClause(OMPSafelenClause *C) {
8098 Record.AddStmt(C->getSafelen());
8099 Record.AddSourceLocation(C->getLParenLoc());
8100}
8101
8102void OMPClauseWriter::VisitOMPSimdlenClause(OMPSimdlenClause *C) {
8103 Record.AddStmt(C->getSimdlen());
8104 Record.AddSourceLocation(C->getLParenLoc());
8105}
8106
8107void OMPClauseWriter::VisitOMPSizesClause(OMPSizesClause *C) {
8108 Record.push_back(C->getNumSizes());
8109 for (Expr *Size : C->getSizesRefs())
8110 Record.AddStmt(Size);
8111 Record.AddSourceLocation(C->getLParenLoc());
8112}
8113
8114void OMPClauseWriter::VisitOMPCountsClause(OMPCountsClause *C) {
8115 Record.push_back(C->getNumCounts());
8116 Record.push_back(C->hasOmpFill());
8117 if (C->hasOmpFill())
8118 Record.push_back(*C->getOmpFillIndex());
8119 Record.AddSourceLocation(C->getOmpFillLoc());
8120 for (Expr *Count : C->getCountsRefs())
8121 Record.AddStmt(Count);
8122 Record.AddSourceLocation(C->getLParenLoc());
8123}
8124
8125void OMPClauseWriter::VisitOMPPermutationClause(OMPPermutationClause *C) {
8126 Record.push_back(C->getNumLoops());
8127 for (Expr *Size : C->getArgsRefs())
8128 Record.AddStmt(Size);
8129 Record.AddSourceLocation(C->getLParenLoc());
8130}
8131
8132void OMPClauseWriter::VisitOMPFullClause(OMPFullClause *C) {}
8133
8134void OMPClauseWriter::VisitOMPPartialClause(OMPPartialClause *C) {
8135 Record.AddStmt(C->getFactor());
8136 Record.AddSourceLocation(C->getLParenLoc());
8137}
8138
8139void OMPClauseWriter::VisitOMPDepthClause(OMPDepthClause *C) {
8140 Record.AddStmt(C->getDepth());
8141 Record.AddSourceLocation(C->getLParenLoc());
8142}
8143
8144void OMPClauseWriter::VisitOMPLoopRangeClause(OMPLoopRangeClause *C) {
8145 Record.AddStmt(C->getFirst());
8146 Record.AddStmt(C->getCount());
8147 Record.AddSourceLocation(C->getLParenLoc());
8148 Record.AddSourceLocation(C->getFirstLoc());
8149 Record.AddSourceLocation(C->getCountLoc());
8150}
8151
8152void OMPClauseWriter::VisitOMPAllocatorClause(OMPAllocatorClause *C) {
8153 Record.AddStmt(C->getAllocator());
8154 Record.AddSourceLocation(C->getLParenLoc());
8155}
8156
8157void OMPClauseWriter::VisitOMPCollapseClause(OMPCollapseClause *C) {
8158 Record.AddStmt(C->getNumForLoops());
8159 Record.AddSourceLocation(C->getLParenLoc());
8160}
8161
8162void OMPClauseWriter::VisitOMPDetachClause(OMPDetachClause *C) {
8163 Record.AddStmt(C->getEventHandler());
8164 Record.AddSourceLocation(C->getLParenLoc());
8165}
8166
8167void OMPClauseWriter::VisitOMPDefaultClause(OMPDefaultClause *C) {
8168 Record.push_back(unsigned(C->getDefaultKind()));
8169 Record.AddSourceLocation(C->getLParenLoc());
8170 Record.AddSourceLocation(C->getDefaultKindKwLoc());
8171 Record.push_back(unsigned(C->getDefaultVC()));
8172 Record.AddSourceLocation(C->getDefaultVCLoc());
8173}
8174
8175void OMPClauseWriter::VisitOMPThreadsetClause(OMPThreadsetClause *C) {
8176 Record.AddSourceLocation(C->getLParenLoc());
8177 Record.AddSourceLocation(C->getThreadsetKindLoc());
8178 Record.writeEnum(C->getThreadsetKind());
8179}
8180
8181void OMPClauseWriter::VisitOMPTransparentClause(OMPTransparentClause *C) {
8182 Record.AddSourceLocation(C->getLParenLoc());
8183 Record.AddStmt(C->getImpexType());
8184}
8185
8186void OMPClauseWriter::VisitOMPProcBindClause(OMPProcBindClause *C) {
8187 Record.push_back(unsigned(C->getProcBindKind()));
8188 Record.AddSourceLocation(C->getLParenLoc());
8189 Record.AddSourceLocation(C->getProcBindKindKwLoc());
8190}
8191
8192void OMPClauseWriter::VisitOMPScheduleClause(OMPScheduleClause *C) {
8193 VisitOMPClauseWithPreInit(C);
8194 Record.push_back(C->getScheduleKind());
8195 Record.push_back(C->getFirstScheduleModifier());
8196 Record.push_back(C->getSecondScheduleModifier());
8197 Record.AddStmt(C->getChunkSize());
8198 Record.AddSourceLocation(C->getLParenLoc());
8199 Record.AddSourceLocation(C->getFirstScheduleModifierLoc());
8200 Record.AddSourceLocation(C->getSecondScheduleModifierLoc());
8201 Record.AddSourceLocation(C->getScheduleKindLoc());
8202 Record.AddSourceLocation(C->getCommaLoc());
8203}
8204
8205void OMPClauseWriter::VisitOMPOrderedClause(OMPOrderedClause *C) {
8206 Record.push_back(C->getLoopNumIterations().size());
8207 Record.AddStmt(C->getNumForLoops());
8208 for (Expr *NumIter : C->getLoopNumIterations())
8209 Record.AddStmt(NumIter);
8210 for (unsigned I = 0, E = C->getLoopNumIterations().size(); I <E; ++I)
8211 Record.AddStmt(C->getLoopCounter(I));
8212 Record.AddSourceLocation(C->getLParenLoc());
8213}
8214
8215void OMPClauseWriter::VisitOMPNowaitClause(OMPNowaitClause *C) {
8216 Record.AddStmt(C->getCondition());
8217 Record.AddSourceLocation(C->getLParenLoc());
8218}
8219
8220void OMPClauseWriter::VisitOMPUntiedClause(OMPUntiedClause *) {}
8221
8222void OMPClauseWriter::VisitOMPMergeableClause(OMPMergeableClause *) {}
8223
8224void OMPClauseWriter::VisitOMPReadClause(OMPReadClause *) {}
8225
8226void OMPClauseWriter::VisitOMPWriteClause(OMPWriteClause *) {}
8227
8228void OMPClauseWriter::VisitOMPUpdateClause(OMPUpdateClause *) {}
8229
8230void OMPClauseWriter::VisitOMPUpdateDependObjectsClause(
8231 OMPUpdateDependObjectsClause *C) {
8232 Record.AddSourceLocation(C->getLParenLoc());
8233 Record.AddSourceLocation(C->getArgumentLoc());
8234 Record.writeEnum(C->getDependencyKind());
8235}
8236
8237void OMPClauseWriter::VisitOMPCaptureClause(OMPCaptureClause *) {}
8238
8239void OMPClauseWriter::VisitOMPCompareClause(OMPCompareClause *) {}
8240
8241// Save the parameter of fail clause.
8242void OMPClauseWriter::VisitOMPFailClause(OMPFailClause *C) {
8243 Record.AddSourceLocation(C->getLParenLoc());
8244 Record.AddSourceLocation(C->getFailParameterLoc());
8245 Record.writeEnum(C->getFailParameter());
8246}
8247
8248void OMPClauseWriter::VisitOMPSeqCstClause(OMPSeqCstClause *) {}
8249
8250void OMPClauseWriter::VisitOMPAcqRelClause(OMPAcqRelClause *) {}
8251
8252void OMPClauseWriter::VisitOMPAbsentClause(OMPAbsentClause *C) {
8253 Record.push_back(static_cast<uint64_t>(C->getDirectiveKinds().size()));
8254 Record.AddSourceLocation(C->getLParenLoc());
8255 for (auto K : C->getDirectiveKinds()) {
8256 Record.writeEnum(K);
8257 }
8258}
8259
8260void OMPClauseWriter::VisitOMPHoldsClause(OMPHoldsClause *C) {
8261 Record.AddStmt(C->getExpr());
8262 Record.AddSourceLocation(C->getLParenLoc());
8263}
8264
8265void OMPClauseWriter::VisitOMPContainsClause(OMPContainsClause *C) {
8266 Record.push_back(static_cast<uint64_t>(C->getDirectiveKinds().size()));
8267 Record.AddSourceLocation(C->getLParenLoc());
8268 for (auto K : C->getDirectiveKinds()) {
8269 Record.writeEnum(K);
8270 }
8271}
8272
8273void OMPClauseWriter::VisitOMPNoOpenMPClause(OMPNoOpenMPClause *) {}
8274
8275void OMPClauseWriter::VisitOMPNoOpenMPRoutinesClause(
8276 OMPNoOpenMPRoutinesClause *) {}
8277
8278void OMPClauseWriter::VisitOMPNoOpenMPConstructsClause(
8279 OMPNoOpenMPConstructsClause *) {}
8280
8281void OMPClauseWriter::VisitOMPNoParallelismClause(OMPNoParallelismClause *) {}
8282
8283void OMPClauseWriter::VisitOMPAcquireClause(OMPAcquireClause *) {}
8284
8285void OMPClauseWriter::VisitOMPReleaseClause(OMPReleaseClause *) {}
8286
8287void OMPClauseWriter::VisitOMPRelaxedClause(OMPRelaxedClause *) {}
8288
8289void OMPClauseWriter::VisitOMPWeakClause(OMPWeakClause *) {}
8290
8291void OMPClauseWriter::VisitOMPThreadsClause(OMPThreadsClause *) {}
8292
8293void OMPClauseWriter::VisitOMPSIMDClause(OMPSIMDClause *) {}
8294
8295void OMPClauseWriter::VisitOMPNogroupClause(OMPNogroupClause *) {}
8296
8297void OMPClauseWriter::VisitOMPInitClause(OMPInitClause *C) {
8298 // Sizes for CreateEmpty on the read side: varlist_size = 1 + NumPrefs, then
8299 // NumAttrs (total attrs across all pref-specs).
8300 Record.push_back(C->varlist_size());
8301 Record.push_back(C->attrs().size());
8302 // Varlist (interop var + Fr block).
8303 for (Expr *VE : C->varlist())
8304 Record.AddStmt(VE);
8305 Record.writeBool(C->getIsTarget());
8306 Record.writeBool(C->getIsTargetSync());
8307 Record.writeBool(C->hasPreferAttrs());
8308 // Per-pref-spec: attr count + that many attr exprs, in order.
8309 for (OMPInitClause::PrefView P : C->prefs()) {
8310 Record.push_back(P.Attrs.size());
8311 for (Expr *A : P.Attrs)
8312 Record.AddStmt(A);
8313 }
8314 Record.AddSourceLocation(C->getLParenLoc());
8315 Record.AddSourceLocation(C->getVarLoc());
8316}
8317
8318void OMPClauseWriter::VisitOMPUseClause(OMPUseClause *C) {
8319 Record.AddStmt(C->getInteropVar());
8320 Record.AddSourceLocation(C->getLParenLoc());
8321 Record.AddSourceLocation(C->getVarLoc());
8322}
8323
8324void OMPClauseWriter::VisitOMPDestroyClause(OMPDestroyClause *C) {
8325 Record.AddStmt(C->getInteropVar());
8326 Record.AddSourceLocation(C->getLParenLoc());
8327 Record.AddSourceLocation(C->getVarLoc());
8328}
8329
8330void OMPClauseWriter::VisitOMPNovariantsClause(OMPNovariantsClause *C) {
8331 VisitOMPClauseWithPreInit(C);
8332 Record.AddStmt(C->getCondition());
8333 Record.AddSourceLocation(C->getLParenLoc());
8334}
8335
8336void OMPClauseWriter::VisitOMPNocontextClause(OMPNocontextClause *C) {
8337 VisitOMPClauseWithPreInit(C);
8338 Record.AddStmt(C->getCondition());
8339 Record.AddSourceLocation(C->getLParenLoc());
8340}
8341
8342void OMPClauseWriter::VisitOMPFilterClause(OMPFilterClause *C) {
8343 VisitOMPClauseWithPreInit(C);
8344 Record.AddStmt(C->getThreadID());
8345 Record.AddSourceLocation(C->getLParenLoc());
8346}
8347
8348void OMPClauseWriter::VisitOMPAlignClause(OMPAlignClause *C) {
8349 Record.AddStmt(C->getAlignment());
8350 Record.AddSourceLocation(C->getLParenLoc());
8351}
8352
8353void OMPClauseWriter::VisitOMPPrivateClause(OMPPrivateClause *C) {
8354 Record.push_back(C->varlist_size());
8355 Record.AddSourceLocation(C->getLParenLoc());
8356 for (auto *VE : C->varlist()) {
8357 Record.AddStmt(VE);
8358 }
8359 for (auto *VE : C->private_copies()) {
8360 Record.AddStmt(VE);
8361 }
8362}
8363
8364void OMPClauseWriter::VisitOMPFirstprivateClause(OMPFirstprivateClause *C) {
8365 Record.push_back(C->varlist_size());
8366 VisitOMPClauseWithPreInit(C);
8367 Record.AddSourceLocation(C->getLParenLoc());
8368 for (auto *VE : C->varlist()) {
8369 Record.AddStmt(VE);
8370 }
8371 for (auto *VE : C->private_copies()) {
8372 Record.AddStmt(VE);
8373 }
8374 for (auto *VE : C->inits()) {
8375 Record.AddStmt(VE);
8376 }
8377}
8378
8379void OMPClauseWriter::VisitOMPLastprivateClause(OMPLastprivateClause *C) {
8380 Record.push_back(C->varlist_size());
8381 VisitOMPClauseWithPostUpdate(C);
8382 Record.AddSourceLocation(C->getLParenLoc());
8383 Record.writeEnum(C->getKind());
8384 Record.AddSourceLocation(C->getKindLoc());
8385 Record.AddSourceLocation(C->getColonLoc());
8386 for (auto *VE : C->varlist())
8387 Record.AddStmt(VE);
8388 for (auto *E : C->private_copies())
8389 Record.AddStmt(E);
8390 for (auto *E : C->source_exprs())
8391 Record.AddStmt(E);
8392 for (auto *E : C->destination_exprs())
8393 Record.AddStmt(E);
8394 for (auto *E : C->assignment_ops())
8395 Record.AddStmt(E);
8396}
8397
8398void OMPClauseWriter::VisitOMPSharedClause(OMPSharedClause *C) {
8399 Record.push_back(C->varlist_size());
8400 Record.AddSourceLocation(C->getLParenLoc());
8401 for (auto *VE : C->varlist())
8402 Record.AddStmt(VE);
8403}
8404
8405void OMPClauseWriter::VisitOMPReductionClause(OMPReductionClause *C) {
8406 Record.push_back(C->varlist_size());
8407 Record.writeEnum(C->getModifier());
8408 VisitOMPClauseWithPostUpdate(C);
8409 Record.AddSourceLocation(C->getLParenLoc());
8410 Record.AddSourceLocation(C->getModifierLoc());
8411 Record.AddSourceLocation(C->getColonLoc());
8412 Record.AddNestedNameSpecifierLoc(C->getQualifierLoc());
8413 Record.AddDeclarationNameInfo(C->getNameInfo());
8414 for (auto *VE : C->varlist())
8415 Record.AddStmt(VE);
8416 for (auto *VE : C->privates())
8417 Record.AddStmt(VE);
8418 for (auto *E : C->lhs_exprs())
8419 Record.AddStmt(E);
8420 for (auto *E : C->rhs_exprs())
8421 Record.AddStmt(E);
8422 for (auto *E : C->reduction_ops())
8423 Record.AddStmt(E);
8424 if (C->getModifier() == clang::OMPC_REDUCTION_inscan) {
8425 for (auto *E : C->copy_ops())
8426 Record.AddStmt(E);
8427 for (auto *E : C->copy_array_temps())
8428 Record.AddStmt(E);
8429 for (auto *E : C->copy_array_elems())
8430 Record.AddStmt(E);
8431 }
8432 auto PrivateFlags = C->private_var_reduction_flags();
8433 Record.push_back(std::distance(PrivateFlags.begin(), PrivateFlags.end()));
8434 for (bool Flag : PrivateFlags)
8435 Record.push_back(Flag);
8436}
8437
8438void OMPClauseWriter::VisitOMPTaskReductionClause(OMPTaskReductionClause *C) {
8439 Record.push_back(C->varlist_size());
8440 VisitOMPClauseWithPostUpdate(C);
8441 Record.AddSourceLocation(C->getLParenLoc());
8442 Record.AddSourceLocation(C->getColonLoc());
8443 Record.AddNestedNameSpecifierLoc(C->getQualifierLoc());
8444 Record.AddDeclarationNameInfo(C->getNameInfo());
8445 for (auto *VE : C->varlist())
8446 Record.AddStmt(VE);
8447 for (auto *VE : C->privates())
8448 Record.AddStmt(VE);
8449 for (auto *E : C->lhs_exprs())
8450 Record.AddStmt(E);
8451 for (auto *E : C->rhs_exprs())
8452 Record.AddStmt(E);
8453 for (auto *E : C->reduction_ops())
8454 Record.AddStmt(E);
8455}
8456
8457void OMPClauseWriter::VisitOMPInReductionClause(OMPInReductionClause *C) {
8458 Record.push_back(C->varlist_size());
8459 VisitOMPClauseWithPostUpdate(C);
8460 Record.AddSourceLocation(C->getLParenLoc());
8461 Record.AddSourceLocation(C->getColonLoc());
8462 Record.AddNestedNameSpecifierLoc(C->getQualifierLoc());
8463 Record.AddDeclarationNameInfo(C->getNameInfo());
8464 for (auto *VE : C->varlist())
8465 Record.AddStmt(VE);
8466 for (auto *VE : C->privates())
8467 Record.AddStmt(VE);
8468 for (auto *E : C->lhs_exprs())
8469 Record.AddStmt(E);
8470 for (auto *E : C->rhs_exprs())
8471 Record.AddStmt(E);
8472 for (auto *E : C->reduction_ops())
8473 Record.AddStmt(E);
8474 for (auto *E : C->taskgroup_descriptors())
8475 Record.AddStmt(E);
8476}
8477
8478void OMPClauseWriter::VisitOMPLinearClause(OMPLinearClause *C) {
8479 Record.push_back(C->varlist_size());
8480 VisitOMPClauseWithPostUpdate(C);
8481 Record.AddSourceLocation(C->getLParenLoc());
8482 Record.AddSourceLocation(C->getColonLoc());
8483 Record.push_back(C->getModifier());
8484 Record.AddSourceLocation(C->getModifierLoc());
8485 for (auto *VE : C->varlist()) {
8486 Record.AddStmt(VE);
8487 }
8488 for (auto *VE : C->privates()) {
8489 Record.AddStmt(VE);
8490 }
8491 for (auto *VE : C->inits()) {
8492 Record.AddStmt(VE);
8493 }
8494 for (auto *VE : C->updates()) {
8495 Record.AddStmt(VE);
8496 }
8497 for (auto *VE : C->finals()) {
8498 Record.AddStmt(VE);
8499 }
8500 Record.AddStmt(C->getStep());
8501 Record.AddStmt(C->getCalcStep());
8502 for (auto *VE : C->used_expressions())
8503 Record.AddStmt(VE);
8504}
8505
8506void OMPClauseWriter::VisitOMPAlignedClause(OMPAlignedClause *C) {
8507 Record.push_back(C->varlist_size());
8508 Record.AddSourceLocation(C->getLParenLoc());
8509 Record.AddSourceLocation(C->getColonLoc());
8510 for (auto *VE : C->varlist())
8511 Record.AddStmt(VE);
8512 Record.AddStmt(C->getAlignment());
8513}
8514
8515void OMPClauseWriter::VisitOMPCopyinClause(OMPCopyinClause *C) {
8516 Record.push_back(C->varlist_size());
8517 Record.AddSourceLocation(C->getLParenLoc());
8518 for (auto *VE : C->varlist())
8519 Record.AddStmt(VE);
8520 for (auto *E : C->source_exprs())
8521 Record.AddStmt(E);
8522 for (auto *E : C->destination_exprs())
8523 Record.AddStmt(E);
8524 for (auto *E : C->assignment_ops())
8525 Record.AddStmt(E);
8526}
8527
8528void OMPClauseWriter::VisitOMPCopyprivateClause(OMPCopyprivateClause *C) {
8529 Record.push_back(C->varlist_size());
8530 Record.AddSourceLocation(C->getLParenLoc());
8531 for (auto *VE : C->varlist())
8532 Record.AddStmt(VE);
8533 for (auto *E : C->source_exprs())
8534 Record.AddStmt(E);
8535 for (auto *E : C->destination_exprs())
8536 Record.AddStmt(E);
8537 for (auto *E : C->assignment_ops())
8538 Record.AddStmt(E);
8539}
8540
8541void OMPClauseWriter::VisitOMPFlushClause(OMPFlushClause *C) {
8542 Record.push_back(C->varlist_size());
8543 Record.AddSourceLocation(C->getLParenLoc());
8544 for (auto *VE : C->varlist())
8545 Record.AddStmt(VE);
8546}
8547
8548void OMPClauseWriter::VisitOMPDepobjClause(OMPDepobjClause *C) {
8549 Record.AddStmt(C->getDepobj());
8550 Record.AddSourceLocation(C->getLParenLoc());
8551}
8552
8553void OMPClauseWriter::VisitOMPDependClause(OMPDependClause *C) {
8554 Record.push_back(C->varlist_size());
8555 Record.push_back(C->getNumLoops());
8556 Record.AddSourceLocation(C->getLParenLoc());
8557 Record.AddStmt(C->getModifier());
8558 Record.push_back(C->getDependencyKind());
8559 Record.AddSourceLocation(C->getDependencyLoc());
8560 Record.AddSourceLocation(C->getColonLoc());
8561 Record.AddSourceLocation(C->getOmpAllMemoryLoc());
8562 for (auto *VE : C->varlist())
8563 Record.AddStmt(VE);
8564 for (unsigned I = 0, E = C->getNumLoops(); I < E; ++I)
8565 Record.AddStmt(C->getLoopData(I));
8566}
8567
8568void OMPClauseWriter::VisitOMPDeviceClause(OMPDeviceClause *C) {
8569 VisitOMPClauseWithPreInit(C);
8570 Record.writeEnum(C->getModifier());
8571 Record.AddStmt(C->getDevice());
8572 Record.AddSourceLocation(C->getModifierLoc());
8573 Record.AddSourceLocation(C->getLParenLoc());
8574}
8575
8576void OMPClauseWriter::VisitOMPMapClause(OMPMapClause *C) {
8577 Record.push_back(C->varlist_size());
8578 Record.push_back(C->getUniqueDeclarationsNum());
8579 Record.push_back(C->getTotalComponentListNum());
8580 Record.push_back(C->getTotalComponentsNum());
8581 Record.AddSourceLocation(C->getLParenLoc());
8582 bool HasIteratorModifier = false;
8583 for (unsigned I = 0; I < NumberOfOMPMapClauseModifiers; ++I) {
8584 Record.push_back(C->getMapTypeModifier(I));
8585 Record.AddSourceLocation(C->getMapTypeModifierLoc(I));
8586 if (C->getMapTypeModifier(I) == OMPC_MAP_MODIFIER_iterator)
8587 HasIteratorModifier = true;
8588 }
8589 Record.AddNestedNameSpecifierLoc(C->getMapperQualifierLoc());
8590 Record.AddDeclarationNameInfo(C->getMapperIdInfo());
8591 Record.push_back(C->getMapType());
8592 Record.AddSourceLocation(C->getMapLoc());
8593 Record.AddSourceLocation(C->getColonLoc());
8594 for (auto *E : C->varlist())
8595 Record.AddStmt(E);
8596 for (auto *E : C->mapperlists())
8597 Record.AddStmt(E);
8598 if (HasIteratorModifier)
8599 Record.AddStmt(C->getIteratorModifier());
8600 for (auto *D : C->all_decls())
8601 Record.AddDeclRef(D);
8602 for (auto N : C->all_num_lists())
8603 Record.push_back(N);
8604 for (auto N : C->all_lists_sizes())
8605 Record.push_back(N);
8606 for (auto &M : C->all_components()) {
8607 Record.AddStmt(M.getAssociatedExpression());
8608 Record.AddDeclRef(M.getAssociatedDeclaration());
8609 }
8610}
8611
8612void OMPClauseWriter::VisitOMPAllocateClause(OMPAllocateClause *C) {
8613 Record.push_back(C->varlist_size());
8614 Record.writeEnum(C->getFirstAllocateModifier());
8615 Record.writeEnum(C->getSecondAllocateModifier());
8616 Record.AddSourceLocation(C->getLParenLoc());
8617 Record.AddSourceLocation(C->getColonLoc());
8618 Record.AddStmt(C->getAllocator());
8619 Record.AddStmt(C->getAlignment());
8620 for (auto *VE : C->varlist())
8621 Record.AddStmt(VE);
8622}
8623
8624void OMPClauseWriter::VisitOMPNumTeamsClause(OMPNumTeamsClause *C) {
8625 Record.push_back(C->varlist_size());
8626 Record.writeEnum(C->getModifier());
8627 Record.AddSourceLocation(C->getModifierLoc());
8628 Record.AddStmt(C->getModifierExpr());
8629 VisitOMPClauseWithPreInit(C);
8630 Record.AddSourceLocation(C->getLParenLoc());
8631 for (auto *VE : C->varlist())
8632 Record.AddStmt(VE);
8633}
8634
8635void OMPClauseWriter::VisitOMPThreadLimitClause(OMPThreadLimitClause *C) {
8636 Record.push_back(C->varlist_size());
8637 Record.writeEnum(C->getModifier());
8638 Record.AddSourceLocation(C->getModifierLoc());
8639 Record.AddStmt(C->getModifierExpr());
8640 VisitOMPClauseWithPreInit(C);
8641 Record.AddSourceLocation(C->getLParenLoc());
8642 for (auto *VE : C->varlist())
8643 Record.AddStmt(VE);
8644}
8645
8646void OMPClauseWriter::VisitOMPPriorityClause(OMPPriorityClause *C) {
8647 VisitOMPClauseWithPreInit(C);
8648 Record.AddStmt(C->getPriority());
8649 Record.AddSourceLocation(C->getLParenLoc());
8650}
8651
8652void OMPClauseWriter::VisitOMPGrainsizeClause(OMPGrainsizeClause *C) {
8653 VisitOMPClauseWithPreInit(C);
8654 Record.writeEnum(C->getModifier());
8655 Record.AddStmt(C->getGrainsize());
8656 Record.AddSourceLocation(C->getModifierLoc());
8657 Record.AddSourceLocation(C->getLParenLoc());
8658}
8659
8660void OMPClauseWriter::VisitOMPNumTasksClause(OMPNumTasksClause *C) {
8661 VisitOMPClauseWithPreInit(C);
8662 Record.writeEnum(C->getModifier());
8663 Record.AddStmt(C->getNumTasks());
8664 Record.AddSourceLocation(C->getModifierLoc());
8665 Record.AddSourceLocation(C->getLParenLoc());
8666}
8667
8668void OMPClauseWriter::VisitOMPHintClause(OMPHintClause *C) {
8669 Record.AddStmt(C->getHint());
8670 Record.AddSourceLocation(C->getLParenLoc());
8671}
8672
8673void OMPClauseWriter::VisitOMPDistScheduleClause(OMPDistScheduleClause *C) {
8674 VisitOMPClauseWithPreInit(C);
8675 Record.push_back(C->getDistScheduleKind());
8676 Record.AddStmt(C->getChunkSize());
8677 Record.AddSourceLocation(C->getLParenLoc());
8678 Record.AddSourceLocation(C->getDistScheduleKindLoc());
8679 Record.AddSourceLocation(C->getCommaLoc());
8680}
8681
8682void OMPClauseWriter::VisitOMPDefaultmapClause(OMPDefaultmapClause *C) {
8683 Record.push_back(C->getDefaultmapKind());
8684 Record.push_back(C->getDefaultmapModifier());
8685 Record.AddSourceLocation(C->getLParenLoc());
8686 Record.AddSourceLocation(C->getDefaultmapModifierLoc());
8687 Record.AddSourceLocation(C->getDefaultmapKindLoc());
8688}
8689
8690void OMPClauseWriter::VisitOMPToClause(OMPToClause *C) {
8691 Record.push_back(C->varlist_size());
8692 Record.push_back(C->getUniqueDeclarationsNum());
8693 Record.push_back(C->getTotalComponentListNum());
8694 Record.push_back(C->getTotalComponentsNum());
8695 Record.AddSourceLocation(C->getLParenLoc());
8696 for (unsigned I = 0; I < NumberOfOMPMotionModifiers; ++I) {
8697 Record.push_back(C->getMotionModifier(I));
8698 Record.AddSourceLocation(C->getMotionModifierLoc(I));
8699 if (C->getMotionModifier(I) == OMPC_MOTION_MODIFIER_iterator)
8700 Record.AddStmt(C->getIteratorModifier());
8701 }
8702 Record.AddNestedNameSpecifierLoc(C->getMapperQualifierLoc());
8703 Record.AddDeclarationNameInfo(C->getMapperIdInfo());
8704 Record.AddSourceLocation(C->getColonLoc());
8705 for (auto *E : C->varlist())
8706 Record.AddStmt(E);
8707 for (auto *E : C->mapperlists())
8708 Record.AddStmt(E);
8709 for (auto *D : C->all_decls())
8710 Record.AddDeclRef(D);
8711 for (auto N : C->all_num_lists())
8712 Record.push_back(N);
8713 for (auto N : C->all_lists_sizes())
8714 Record.push_back(N);
8715 for (auto &M : C->all_components()) {
8716 Record.AddStmt(M.getAssociatedExpression());
8717 Record.writeBool(M.isNonContiguous());
8718 Record.AddDeclRef(M.getAssociatedDeclaration());
8719 }
8720}
8721
8722void OMPClauseWriter::VisitOMPFromClause(OMPFromClause *C) {
8723 Record.push_back(C->varlist_size());
8724 Record.push_back(C->getUniqueDeclarationsNum());
8725 Record.push_back(C->getTotalComponentListNum());
8726 Record.push_back(C->getTotalComponentsNum());
8727 Record.AddSourceLocation(C->getLParenLoc());
8728 for (unsigned I = 0; I < NumberOfOMPMotionModifiers; ++I) {
8729 Record.push_back(C->getMotionModifier(I));
8730 Record.AddSourceLocation(C->getMotionModifierLoc(I));
8731 if (C->getMotionModifier(I) == OMPC_MOTION_MODIFIER_iterator)
8732 Record.AddStmt(C->getIteratorModifier());
8733 }
8734 Record.AddNestedNameSpecifierLoc(C->getMapperQualifierLoc());
8735 Record.AddDeclarationNameInfo(C->getMapperIdInfo());
8736 Record.AddSourceLocation(C->getColonLoc());
8737 for (auto *E : C->varlist())
8738 Record.AddStmt(E);
8739 for (auto *E : C->mapperlists())
8740 Record.AddStmt(E);
8741 for (auto *D : C->all_decls())
8742 Record.AddDeclRef(D);
8743 for (auto N : C->all_num_lists())
8744 Record.push_back(N);
8745 for (auto N : C->all_lists_sizes())
8746 Record.push_back(N);
8747 for (auto &M : C->all_components()) {
8748 Record.AddStmt(M.getAssociatedExpression());
8749 Record.writeBool(M.isNonContiguous());
8750 Record.AddDeclRef(M.getAssociatedDeclaration());
8751 }
8752}
8753
8754void OMPClauseWriter::VisitOMPUseDevicePtrClause(OMPUseDevicePtrClause *C) {
8755 Record.push_back(C->varlist_size());
8756 Record.push_back(C->getUniqueDeclarationsNum());
8757 Record.push_back(C->getTotalComponentListNum());
8758 Record.push_back(C->getTotalComponentsNum());
8759 Record.AddSourceLocation(C->getLParenLoc());
8760 Record.writeEnum(C->getFallbackModifier());
8761 Record.AddSourceLocation(C->getFallbackModifierLoc());
8762 for (auto *E : C->varlist())
8763 Record.AddStmt(E);
8764 for (auto *VE : C->private_copies())
8765 Record.AddStmt(VE);
8766 for (auto *VE : C->inits())
8767 Record.AddStmt(VE);
8768 for (auto *D : C->all_decls())
8769 Record.AddDeclRef(D);
8770 for (auto N : C->all_num_lists())
8771 Record.push_back(N);
8772 for (auto N : C->all_lists_sizes())
8773 Record.push_back(N);
8774 for (auto &M : C->all_components()) {
8775 Record.AddStmt(M.getAssociatedExpression());
8776 Record.AddDeclRef(M.getAssociatedDeclaration());
8777 }
8778}
8779
8780void OMPClauseWriter::VisitOMPUseDeviceAddrClause(OMPUseDeviceAddrClause *C) {
8781 Record.push_back(C->varlist_size());
8782 Record.push_back(C->getUniqueDeclarationsNum());
8783 Record.push_back(C->getTotalComponentListNum());
8784 Record.push_back(C->getTotalComponentsNum());
8785 Record.AddSourceLocation(C->getLParenLoc());
8786 for (auto *E : C->varlist())
8787 Record.AddStmt(E);
8788 for (auto *D : C->all_decls())
8789 Record.AddDeclRef(D);
8790 for (auto N : C->all_num_lists())
8791 Record.push_back(N);
8792 for (auto N : C->all_lists_sizes())
8793 Record.push_back(N);
8794 for (auto &M : C->all_components()) {
8795 Record.AddStmt(M.getAssociatedExpression());
8796 Record.AddDeclRef(M.getAssociatedDeclaration());
8797 }
8798}
8799
8800void OMPClauseWriter::VisitOMPIsDevicePtrClause(OMPIsDevicePtrClause *C) {
8801 Record.push_back(C->varlist_size());
8802 Record.push_back(C->getUniqueDeclarationsNum());
8803 Record.push_back(C->getTotalComponentListNum());
8804 Record.push_back(C->getTotalComponentsNum());
8805 Record.AddSourceLocation(C->getLParenLoc());
8806 for (auto *E : C->varlist())
8807 Record.AddStmt(E);
8808 for (auto *D : C->all_decls())
8809 Record.AddDeclRef(D);
8810 for (auto N : C->all_num_lists())
8811 Record.push_back(N);
8812 for (auto N : C->all_lists_sizes())
8813 Record.push_back(N);
8814 for (auto &M : C->all_components()) {
8815 Record.AddStmt(M.getAssociatedExpression());
8816 Record.AddDeclRef(M.getAssociatedDeclaration());
8817 }
8818}
8819
8820void OMPClauseWriter::VisitOMPHasDeviceAddrClause(OMPHasDeviceAddrClause *C) {
8821 Record.push_back(C->varlist_size());
8822 Record.push_back(C->getUniqueDeclarationsNum());
8823 Record.push_back(C->getTotalComponentListNum());
8824 Record.push_back(C->getTotalComponentsNum());
8825 Record.AddSourceLocation(C->getLParenLoc());
8826 for (auto *E : C->varlist())
8827 Record.AddStmt(E);
8828 for (auto *D : C->all_decls())
8829 Record.AddDeclRef(D);
8830 for (auto N : C->all_num_lists())
8831 Record.push_back(N);
8832 for (auto N : C->all_lists_sizes())
8833 Record.push_back(N);
8834 for (auto &M : C->all_components()) {
8835 Record.AddStmt(M.getAssociatedExpression());
8836 Record.AddDeclRef(M.getAssociatedDeclaration());
8837 }
8838}
8839
8840void OMPClauseWriter::VisitOMPUnifiedAddressClause(OMPUnifiedAddressClause *) {}
8841
8842void OMPClauseWriter::VisitOMPUnifiedSharedMemoryClause(
8843 OMPUnifiedSharedMemoryClause *) {}
8844
8845void OMPClauseWriter::VisitOMPReverseOffloadClause(OMPReverseOffloadClause *) {}
8846
8847void
8848OMPClauseWriter::VisitOMPDynamicAllocatorsClause(OMPDynamicAllocatorsClause *) {
8849}
8850
8851void OMPClauseWriter::VisitOMPAtomicDefaultMemOrderClause(
8852 OMPAtomicDefaultMemOrderClause *C) {
8853 Record.push_back(C->getAtomicDefaultMemOrderKind());
8854 Record.AddSourceLocation(C->getLParenLoc());
8855 Record.AddSourceLocation(C->getAtomicDefaultMemOrderKindKwLoc());
8856}
8857
8858void OMPClauseWriter::VisitOMPSelfMapsClause(OMPSelfMapsClause *) {}
8859
8860void OMPClauseWriter::VisitOMPAtClause(OMPAtClause *C) {
8861 Record.push_back(C->getAtKind());
8862 Record.AddSourceLocation(C->getLParenLoc());
8863 Record.AddSourceLocation(C->getAtKindKwLoc());
8864}
8865
8866void OMPClauseWriter::VisitOMPSeverityClause(OMPSeverityClause *C) {
8867 Record.push_back(C->getSeverityKind());
8868 Record.AddSourceLocation(C->getLParenLoc());
8869 Record.AddSourceLocation(C->getSeverityKindKwLoc());
8870}
8871
8872void OMPClauseWriter::VisitOMPMessageClause(OMPMessageClause *C) {
8873 VisitOMPClauseWithPreInit(C);
8874 Record.AddStmt(C->getMessageString());
8875 Record.AddSourceLocation(C->getLParenLoc());
8876}
8877
8878void OMPClauseWriter::VisitOMPNontemporalClause(OMPNontemporalClause *C) {
8879 Record.push_back(C->varlist_size());
8880 Record.AddSourceLocation(C->getLParenLoc());
8881 for (auto *VE : C->varlist())
8882 Record.AddStmt(VE);
8883 for (auto *E : C->private_refs())
8884 Record.AddStmt(E);
8885}
8886
8887void OMPClauseWriter::VisitOMPInclusiveClause(OMPInclusiveClause *C) {
8888 Record.push_back(C->varlist_size());
8889 Record.AddSourceLocation(C->getLParenLoc());
8890 for (auto *VE : C->varlist())
8891 Record.AddStmt(VE);
8892}
8893
8894void OMPClauseWriter::VisitOMPExclusiveClause(OMPExclusiveClause *C) {
8895 Record.push_back(C->varlist_size());
8896 Record.AddSourceLocation(C->getLParenLoc());
8897 for (auto *VE : C->varlist())
8898 Record.AddStmt(VE);
8899}
8900
8901void OMPClauseWriter::VisitOMPOrderClause(OMPOrderClause *C) {
8902 Record.writeEnum(C->getKind());
8903 Record.writeEnum(C->getModifier());
8904 Record.AddSourceLocation(C->getLParenLoc());
8905 Record.AddSourceLocation(C->getKindKwLoc());
8906 Record.AddSourceLocation(C->getModifierKwLoc());
8907}
8908
8909void OMPClauseWriter::VisitOMPUsesAllocatorsClause(OMPUsesAllocatorsClause *C) {
8910 Record.push_back(C->getNumberOfAllocators());
8911 Record.AddSourceLocation(C->getLParenLoc());
8912 for (unsigned I = 0, E = C->getNumberOfAllocators(); I < E; ++I) {
8913 OMPUsesAllocatorsClause::Data Data = C->getAllocatorData(I);
8914 Record.AddStmt(Data.Allocator);
8915 Record.AddStmt(Data.AllocatorTraits);
8916 Record.AddSourceLocation(Data.LParenLoc);
8917 Record.AddSourceLocation(Data.RParenLoc);
8918 }
8919}
8920
8921void OMPClauseWriter::VisitOMPAffinityClause(OMPAffinityClause *C) {
8922 Record.push_back(C->varlist_size());
8923 Record.AddSourceLocation(C->getLParenLoc());
8924 Record.AddStmt(C->getModifier());
8925 Record.AddSourceLocation(C->getColonLoc());
8926 for (Expr *E : C->varlist())
8927 Record.AddStmt(E);
8928}
8929
8930void OMPClauseWriter::VisitOMPBindClause(OMPBindClause *C) {
8931 Record.writeEnum(C->getBindKind());
8932 Record.AddSourceLocation(C->getLParenLoc());
8933 Record.AddSourceLocation(C->getBindKindLoc());
8934}
8935
8936void OMPClauseWriter::VisitOMPXDynCGroupMemClause(OMPXDynCGroupMemClause *C) {
8937 VisitOMPClauseWithPreInit(C);
8938 Record.AddStmt(C->getSize());
8939 Record.AddSourceLocation(C->getLParenLoc());
8940}
8941
8942void OMPClauseWriter::VisitOMPDynGroupprivateClause(
8943 OMPDynGroupprivateClause *C) {
8944 VisitOMPClauseWithPreInit(C);
8945 Record.push_back(C->getDynGroupprivateModifier());
8946 Record.push_back(C->getDynGroupprivateFallbackModifier());
8947 Record.AddStmt(C->getSize());
8948 Record.AddSourceLocation(C->getLParenLoc());
8949 Record.AddSourceLocation(C->getDynGroupprivateModifierLoc());
8950 Record.AddSourceLocation(C->getDynGroupprivateFallbackModifierLoc());
8951}
8952
8953void OMPClauseWriter::VisitOMPDoacrossClause(OMPDoacrossClause *C) {
8954 Record.push_back(C->varlist_size());
8955 Record.push_back(C->getNumLoops());
8956 Record.AddSourceLocation(C->getLParenLoc());
8957 Record.push_back(C->getDependenceType());
8958 Record.AddSourceLocation(C->getDependenceLoc());
8959 Record.AddSourceLocation(C->getColonLoc());
8960 for (auto *VE : C->varlist())
8961 Record.AddStmt(VE);
8962 for (unsigned I = 0, E = C->getNumLoops(); I < E; ++I)
8963 Record.AddStmt(C->getLoopData(I));
8964}
8965
8966void OMPClauseWriter::VisitOMPXAttributeClause(OMPXAttributeClause *C) {
8967 Record.AddAttributes(C->getAttrs());
8968 Record.AddSourceLocation(C->getBeginLoc());
8969 Record.AddSourceLocation(C->getLParenLoc());
8970 Record.AddSourceLocation(C->getEndLoc());
8971}
8972
8973void OMPClauseWriter::VisitOMPXBareClause(OMPXBareClause *C) {}
8974
8976 writeUInt32(TI->Sets.size());
8977 for (const auto &Set : TI->Sets) {
8978 writeEnum(Set.Kind);
8979 writeUInt32(Set.Selectors.size());
8980 for (const auto &Selector : Set.Selectors) {
8981 writeEnum(Selector.Kind);
8982 writeBool(Selector.ScoreOrCondition);
8983 if (Selector.ScoreOrCondition)
8984 writeExprRef(Selector.ScoreOrCondition);
8985 writeUInt32(Selector.Properties.size());
8986 for (const auto &Property : Selector.Properties)
8987 writeEnum(Property.Kind);
8988 }
8989 }
8990}
8991
8993 if (!Data)
8994 return;
8995 writeUInt32(Data->getNumClauses());
8996 writeUInt32(Data->getNumChildren());
8997 writeBool(Data->hasAssociatedStmt());
8998 for (unsigned I = 0, E = Data->getNumClauses(); I < E; ++I)
8999 writeOMPClause(Data->getClauses()[I]);
9000 if (Data->hasAssociatedStmt())
9001 AddStmt(Data->getAssociatedStmt());
9002 for (unsigned I = 0, E = Data->getNumChildren(); I < E; ++I)
9003 AddStmt(Data->getChildren()[I]);
9004}
9005
9007 writeUInt32(C->getVarList().size());
9008 for (Expr *E : C->getVarList())
9009 AddStmt(E);
9010}
9011
9013 writeUInt32(Exprs.size());
9014 for (Expr *E : Exprs)
9015 AddStmt(E);
9016}
9017
9019 writeEnum(C->getClauseKind());
9020 writeSourceLocation(C->getBeginLoc());
9021 writeSourceLocation(C->getEndLoc());
9022
9023 switch (C->getClauseKind()) {
9025 const auto *DC = cast<OpenACCDefaultClause>(C);
9026 writeSourceLocation(DC->getLParenLoc());
9027 writeEnum(DC->getDefaultClauseKind());
9028 return;
9029 }
9030 case OpenACCClauseKind::If: {
9031 const auto *IC = cast<OpenACCIfClause>(C);
9032 writeSourceLocation(IC->getLParenLoc());
9033 AddStmt(const_cast<Expr*>(IC->getConditionExpr()));
9034 return;
9035 }
9037 const auto *SC = cast<OpenACCSelfClause>(C);
9038 writeSourceLocation(SC->getLParenLoc());
9039 writeBool(SC->isConditionExprClause());
9040 if (SC->isConditionExprClause()) {
9041 writeBool(SC->hasConditionExpr());
9042 if (SC->hasConditionExpr())
9043 AddStmt(const_cast<Expr *>(SC->getConditionExpr()));
9044 } else {
9045 writeUInt32(SC->getVarList().size());
9046 for (Expr *E : SC->getVarList())
9047 AddStmt(E);
9048 }
9049 return;
9050 }
9052 const auto *NGC = cast<OpenACCNumGangsClause>(C);
9053 writeSourceLocation(NGC->getLParenLoc());
9054 writeUInt32(NGC->getIntExprs().size());
9055 for (Expr *E : NGC->getIntExprs())
9056 AddStmt(E);
9057 return;
9058 }
9060 const auto *DNC = cast<OpenACCDeviceNumClause>(C);
9061 writeSourceLocation(DNC->getLParenLoc());
9062 AddStmt(const_cast<Expr*>(DNC->getIntExpr()));
9063 return;
9064 }
9066 const auto *DAC = cast<OpenACCDefaultAsyncClause>(C);
9067 writeSourceLocation(DAC->getLParenLoc());
9068 AddStmt(const_cast<Expr *>(DAC->getIntExpr()));
9069 return;
9070 }
9072 const auto *NWC = cast<OpenACCNumWorkersClause>(C);
9073 writeSourceLocation(NWC->getLParenLoc());
9074 AddStmt(const_cast<Expr*>(NWC->getIntExpr()));
9075 return;
9076 }
9078 const auto *NWC = cast<OpenACCVectorLengthClause>(C);
9079 writeSourceLocation(NWC->getLParenLoc());
9080 AddStmt(const_cast<Expr*>(NWC->getIntExpr()));
9081 return;
9082 }
9084 const auto *PC = cast<OpenACCPrivateClause>(C);
9085 writeSourceLocation(PC->getLParenLoc());
9087
9088 for (const OpenACCPrivateRecipe &R : PC->getInitRecipes()) {
9089 static_assert(sizeof(R) == 1 * sizeof(int *));
9090 AddDeclRef(R.AllocaDecl);
9091 }
9092 return;
9093 }
9095 const auto *HC = cast<OpenACCHostClause>(C);
9096 writeSourceLocation(HC->getLParenLoc());
9098 return;
9099 }
9101 const auto *DC = cast<OpenACCDeviceClause>(C);
9102 writeSourceLocation(DC->getLParenLoc());
9104 return;
9105 }
9107 const auto *FPC = cast<OpenACCFirstPrivateClause>(C);
9108 writeSourceLocation(FPC->getLParenLoc());
9110
9111 for (const OpenACCFirstPrivateRecipe &R : FPC->getInitRecipes()) {
9112 static_assert(sizeof(R) == 2 * sizeof(int *));
9113 AddDeclRef(R.AllocaDecl);
9114 AddDeclRef(R.InitFromTemporary);
9115 }
9116 return;
9117 }
9119 const auto *AC = cast<OpenACCAttachClause>(C);
9120 writeSourceLocation(AC->getLParenLoc());
9122 return;
9123 }
9125 const auto *DC = cast<OpenACCDetachClause>(C);
9126 writeSourceLocation(DC->getLParenLoc());
9128 return;
9129 }
9131 const auto *DC = cast<OpenACCDeleteClause>(C);
9132 writeSourceLocation(DC->getLParenLoc());
9134 return;
9135 }
9137 const auto *UDC = cast<OpenACCUseDeviceClause>(C);
9138 writeSourceLocation(UDC->getLParenLoc());
9140 return;
9141 }
9143 const auto *DPC = cast<OpenACCDevicePtrClause>(C);
9144 writeSourceLocation(DPC->getLParenLoc());
9146 return;
9147 }
9149 const auto *NCC = cast<OpenACCNoCreateClause>(C);
9150 writeSourceLocation(NCC->getLParenLoc());
9152 return;
9153 }
9155 const auto *PC = cast<OpenACCPresentClause>(C);
9156 writeSourceLocation(PC->getLParenLoc());
9158 return;
9159 }
9163 const auto *CC = cast<OpenACCCopyClause>(C);
9164 writeSourceLocation(CC->getLParenLoc());
9165 writeEnum(CC->getModifierList());
9167 return;
9168 }
9172 const auto *CIC = cast<OpenACCCopyInClause>(C);
9173 writeSourceLocation(CIC->getLParenLoc());
9174 writeEnum(CIC->getModifierList());
9176 return;
9177 }
9181 const auto *COC = cast<OpenACCCopyOutClause>(C);
9182 writeSourceLocation(COC->getLParenLoc());
9183 writeEnum(COC->getModifierList());
9185 return;
9186 }
9190 const auto *CC = cast<OpenACCCreateClause>(C);
9191 writeSourceLocation(CC->getLParenLoc());
9192 writeEnum(CC->getModifierList());
9194 return;
9195 }
9197 const auto *AC = cast<OpenACCAsyncClause>(C);
9198 writeSourceLocation(AC->getLParenLoc());
9199 writeBool(AC->hasIntExpr());
9200 if (AC->hasIntExpr())
9201 AddStmt(const_cast<Expr*>(AC->getIntExpr()));
9202 return;
9203 }
9205 const auto *WC = cast<OpenACCWaitClause>(C);
9206 writeSourceLocation(WC->getLParenLoc());
9207 writeBool(WC->getDevNumExpr());
9208 if (Expr *DNE = WC->getDevNumExpr())
9209 AddStmt(DNE);
9210 writeSourceLocation(WC->getQueuesLoc());
9211
9212 writeOpenACCIntExprList(WC->getQueueIdExprs());
9213 return;
9214 }
9217 const auto *DTC = cast<OpenACCDeviceTypeClause>(C);
9218 writeSourceLocation(DTC->getLParenLoc());
9219 writeUInt32(DTC->getArchitectures().size());
9220 for (const DeviceTypeArgument &Arg : DTC->getArchitectures()) {
9221 writeBool(Arg.getIdentifierInfo());
9222 if (Arg.getIdentifierInfo())
9223 AddIdentifierRef(Arg.getIdentifierInfo());
9224 writeSourceLocation(Arg.getLoc());
9225 }
9226 return;
9227 }
9229 const auto *RC = cast<OpenACCReductionClause>(C);
9230 writeSourceLocation(RC->getLParenLoc());
9231 writeEnum(RC->getReductionOp());
9233
9234 for (const OpenACCReductionRecipe &R : RC->getRecipes()) {
9235 AddDeclRef(R.AllocaDecl);
9236
9237 static_assert(sizeof(OpenACCReductionRecipe::CombinerRecipe) ==
9238 3 * sizeof(int *));
9239 writeUInt32(R.CombinerRecipes.size());
9240
9241 for (auto &CombinerRecipe : R.CombinerRecipes) {
9242 AddDeclRef(CombinerRecipe.LHS);
9243 AddDeclRef(CombinerRecipe.RHS);
9244 AddStmt(CombinerRecipe.Op);
9245 }
9246 }
9247 return;
9248 }
9255 // Nothing to do here, there is no additional information beyond the
9256 // begin/end loc and clause kind.
9257 return;
9259 const auto *CC = cast<OpenACCCollapseClause>(C);
9260 writeSourceLocation(CC->getLParenLoc());
9261 writeBool(CC->hasForce());
9262 AddStmt(const_cast<Expr *>(CC->getLoopCount()));
9263 return;
9264 }
9266 const auto *TC = cast<OpenACCTileClause>(C);
9267 writeSourceLocation(TC->getLParenLoc());
9268 writeUInt32(TC->getSizeExprs().size());
9269 for (Expr *E : TC->getSizeExprs())
9270 AddStmt(E);
9271 return;
9272 }
9274 const auto *GC = cast<OpenACCGangClause>(C);
9275 writeSourceLocation(GC->getLParenLoc());
9276 writeUInt32(GC->getNumExprs());
9277 for (unsigned I = 0; I < GC->getNumExprs(); ++I) {
9278 writeEnum(GC->getExpr(I).first);
9279 AddStmt(const_cast<Expr *>(GC->getExpr(I).second));
9280 }
9281 return;
9282 }
9284 const auto *WC = cast<OpenACCWorkerClause>(C);
9285 writeSourceLocation(WC->getLParenLoc());
9286 writeBool(WC->hasIntExpr());
9287 if (WC->hasIntExpr())
9288 AddStmt(const_cast<Expr *>(WC->getIntExpr()));
9289 return;
9290 }
9292 const auto *VC = cast<OpenACCVectorClause>(C);
9293 writeSourceLocation(VC->getLParenLoc());
9294 writeBool(VC->hasIntExpr());
9295 if (VC->hasIntExpr())
9296 AddStmt(const_cast<Expr *>(VC->getIntExpr()));
9297 return;
9298 }
9300 const auto *LC = cast<OpenACCLinkClause>(C);
9301 writeSourceLocation(LC->getLParenLoc());
9303 return;
9304 }
9306 const auto *DRC = cast<OpenACCDeviceResidentClause>(C);
9307 writeSourceLocation(DRC->getLParenLoc());
9309 return;
9310 }
9311
9313 const auto *BC = cast<OpenACCBindClause>(C);
9314 writeSourceLocation(BC->getLParenLoc());
9315 writeBool(BC->isStringArgument());
9316 if (BC->isStringArgument())
9317 AddStmt(const_cast<StringLiteral *>(BC->getStringArgument()));
9318 else
9319 AddIdentifierRef(BC->getIdentifierArgument());
9320
9321 return;
9322 }
9325 llvm_unreachable("Clause serialization not yet implemented");
9326 }
9327 llvm_unreachable("Invalid Clause Kind");
9328}
9329
9332 for (const OpenACCClause *Clause : Clauses)
9333 writeOpenACCClause(Clause);
9334}
9336 const OpenACCRoutineDeclAttr *A) {
9337 // We have to write the size so that the reader can do a resize. Unlike the
9338 // Decl version of this, we can't count on trailing storage to get this right.
9339 writeUInt32(A->Clauses.size());
9340 writeOpenACCClauseList(A->Clauses);
9341}
#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:5077
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:123
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Definition ASTContext.h:239
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:846
const LangOptions & getLangOpts() const
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:2907
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:2217
DeclContextLookupResult lookup_result
Definition DeclBase.h:2627
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:2212
bool isTranslationUnit() const
Definition DeclBase.h:2222
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:2431
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:2423
bool isFunctionOrMethod() const
Returns true if this DeclContext is a function, Objective-C method, or block, or a DeclContext that c...
Definition DeclBase.h:2181
StoredDeclsMap * getLookupPtr() const
Retrieve the internal representation of the lookup structure.
Definition DeclBase.h:2731
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:613
bool hasUncompilableErrorOccurred() const
Errors that actually prevent compilation, not those that are upgraded from a warning by -Werror.
Definition Diagnostic.h:895
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
int getOpaqueValue() const
Returns the raw integer representation of this FileID.
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 the 'depth' clause on the 'pragma omp flatten' (and 'pragma omp fuse') loop-transform...
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:6559
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:4979
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:11486
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:3628
SmallVector< const Decl * > DeclsWithEffectsToVerify
All functions/lambdas/blocks which have bodies and which have a non-empty FunctionEffectsRef to be ve...
Definition Sema.h:15837
EnumDecl * getStdAlignValT() const
LazyDeclPtr StdBadAlloc
The C++ "std::bad_alloc" class, which is defined by the C++ standard library.
Definition Sema.h:8413
SmallVector< VTableUse, 16 > VTableUses
The list of vtables that are required but have not yet been materialized.
Definition Sema.h:5968
Preprocessor & PP
Definition Sema.h:1303
llvm::MapVector< const FunctionDecl *, std::unique_ptr< LateParsedTemplate > > LateParsedTemplateMapT
Definition Sema.h:11485
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:5974
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:4836
llvm::MapVector< IdentifierInfo *, AsmLabelAttr * > ExtnameUndeclaredIdentifiers
ExtnameUndeclaredIdentifiers - Identifiers contained in #pragma redefine_extname before declared.
Definition Sema.h:3611
std::deque< PendingImplicitInstantiation > PendingLocalImplicitInstantiations
The queue of implicit template instantiations that are required and must be performed within the curr...
Definition Sema.h:14144
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:6562
std::deque< PendingImplicitInstantiation > PendingInstantiations
The queue of implicit template instantiations that are required but have not yet been performed.
Definition Sema.h:14127
TentativeDefinitionsType TentativeDefinitions
All the tentative definitions encountered in the TU.
Definition Sema.h:3635
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:3604
LazyDeclPtr StdAlignValT
The C++ "std::align_val_t" enum class, which is defined by the C++ standard library.
Definition Sema.h:8417
void getSortedUnusedLocalTypedefNameCandidates(SmallVectorImpl< const TypedefNameDecl * > &Sorted) const
Store UnusedLocalTypedefNameCandidates in Sorted in a deterministic order.
Definition Sema.cpp:1203
IdentifierResolver IdResolver
Definition Sema.h:3527
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:8399
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:8410
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:2619
bool hasInitWithSideEffects() const
Checks whether this declaration has an initializer with side effects.
Definition Decl.cpp:2424
EvaluatedStmt * getEvaluatedStmt() const
Definition Decl.cpp:2551
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:1532
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:6007
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...
__builtin_elementwise_add_sat __builtin_elementwise_sub_sat uint32_t __packed_splat4 __packed_splat2 __packed_splat8 __packed_splat4 __packed_splat2 uint8_t
__builtin_elementwise_add_sat __builtin_elementwise_sub_sat uint32_t __packed_splat4 __packed_splat2 __packed_splat8 __packed_splat4 __packed_splat2 __packed_splat4 uint16_t
__builtin_elementwise_add_sat __builtin_elementwise_sub_sat uint32_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:15935
Decl * D
The template function declaration to be late parsed.
Definition Sema.h:15933
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