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