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