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