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