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