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