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