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