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