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