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