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