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