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