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