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
5712 // Writing all of the known namespaces.
5713 for (const auto &I : SemaRef.KnownNamespaces)
5714 if (!I.second)
5715 GetDeclRef(I.first);
5716
5717 // Writing all used, undefined objects that require definitions.
5718 SmallVector<std::pair<NamedDecl *, SourceLocation>, 16> Undefined;
5720 for (const auto &I : Undefined)
5721 GetDeclRef(I.first);
5722
5723 // Writing all delete-expressions that we would like to
5724 // analyze later in AST.
5725 if (!isModule)
5726 for (const auto &DeleteExprsInfo :
5728 GetDeclRef(DeleteExprsInfo.first);
5729
5730 // Make sure visible decls, added to DeclContexts previously loaded from
5731 // an AST file, are registered for serialization. Likewise for template
5732 // specializations added to imported templates.
5733 for (const auto *I : DeclsToEmitEvenIfUnreferenced)
5734 GetDeclRef(I);
5735 DeclsToEmitEvenIfUnreferenced.clear();
5736
5737 // Make sure all decls associated with an identifier are registered for
5738 // serialization, if we're storing decls with identifiers.
5739 if (!WritingModule || !getLangOpts().CPlusPlus) {
5740 llvm::SmallVector<const IdentifierInfo*, 256> IIs;
5741 for (const auto &ID : SemaRef.PP.getIdentifierTable()) {
5742 const IdentifierInfo *II = ID.second;
5743 if (!Chain || !II->isFromAST() || II->hasChangedSinceDeserialization() ||
5745 IIs.push_back(II);
5746 }
5747 // Sort the identifiers to visit based on their name.
5748 llvm::sort(IIs, llvm::deref<std::less<>>());
5749 const LangOptions &LangOpts = getLangOpts();
5750 for (const IdentifierInfo *II : IIs)
5751 for (NamedDecl *D : SemaRef.IdResolver.decls(II))
5752 GetDeclRef(getDeclForLocalLookup(LangOpts, D));
5753 }
5754
5755 // Write all of the DeclsToCheckForDeferredDiags.
5756 for (auto *D : SemaRef.DeclsToCheckForDeferredDiags)
5757 GetDeclRef(D);
5758
5759 // Write all classes that need to emit the vtable definitions if required.
5761 for (CXXRecordDecl *RD : PendingEmittingVTables)
5762 GetDeclRef(RD);
5763 else
5764 PendingEmittingVTables.clear();
5765}
5766
5767void ASTWriter::WriteSpecialDeclRecords(Sema &SemaRef) {
5768 ASTContext &Context = SemaRef.Context;
5769
5770 bool isModule = WritingModule != nullptr;
5771
5772 // Write the record containing external, unnamed definitions.
5773 if (!EagerlyDeserializedDecls.empty())
5774 Stream.EmitRecord(EAGERLY_DESERIALIZED_DECLS, EagerlyDeserializedDecls);
5775
5776 if (!ModularCodegenDecls.empty())
5777 Stream.EmitRecord(MODULAR_CODEGEN_DECLS, ModularCodegenDecls);
5778
5779 // Write the record containing tentative definitions.
5780 RecordData TentativeDefinitions;
5782 TentativeDefinitions);
5783 if (!TentativeDefinitions.empty())
5784 Stream.EmitRecord(TENTATIVE_DEFINITIONS, TentativeDefinitions);
5785
5786 // Write the record containing unused file scoped decls.
5787 RecordData UnusedFileScopedDecls;
5788 if (!isModule)
5790 UnusedFileScopedDecls);
5791 if (!UnusedFileScopedDecls.empty())
5792 Stream.EmitRecord(UNUSED_FILESCOPED_DECLS, UnusedFileScopedDecls);
5793
5794 // Write the record containing ext_vector type names.
5795 RecordData ExtVectorDecls;
5796 AddLazyVectorEmiitedDecls(*this, SemaRef.ExtVectorDecls, ExtVectorDecls);
5797 if (!ExtVectorDecls.empty())
5798 Stream.EmitRecord(EXT_VECTOR_DECLS, ExtVectorDecls);
5799
5800 // Write the record containing VTable uses information.
5801 RecordData VTableUses;
5802 if (!SemaRef.VTableUses.empty()) {
5803 for (unsigned I = 0, N = SemaRef.VTableUses.size(); I != N; ++I) {
5804 CXXRecordDecl *D = SemaRef.VTableUses[I].first;
5805 if (!wasDeclEmitted(D))
5806 continue;
5807
5808 AddDeclRef(D, VTableUses);
5809 AddSourceLocation(SemaRef.VTableUses[I].second, VTableUses);
5810 VTableUses.push_back(SemaRef.VTablesUsed[D]);
5811 }
5812 Stream.EmitRecord(VTABLE_USES, VTableUses);
5813 }
5814
5815 // Write the record containing potentially unused local typedefs.
5816 RecordData UnusedLocalTypedefNameCandidates;
5817 for (const TypedefNameDecl *TD : SemaRef.UnusedLocalTypedefNameCandidates)
5818 AddEmittedDeclRef(TD, UnusedLocalTypedefNameCandidates);
5819 if (!UnusedLocalTypedefNameCandidates.empty())
5820 Stream.EmitRecord(UNUSED_LOCAL_TYPEDEF_NAME_CANDIDATES,
5821 UnusedLocalTypedefNameCandidates);
5822
5823 if (!GeneratingReducedBMI) {
5824 // Write the record containing pending implicit instantiations.
5825 RecordData PendingInstantiations;
5826 for (const auto &I : SemaRef.PendingInstantiations) {
5827 if (!wasDeclEmitted(I.first))
5828 continue;
5829
5830 AddDeclRef(I.first, PendingInstantiations);
5831 AddSourceLocation(I.second, PendingInstantiations);
5832 }
5833 if (!PendingInstantiations.empty())
5834 Stream.EmitRecord(PENDING_IMPLICIT_INSTANTIATIONS, PendingInstantiations);
5835 }
5836
5837 // Write the record containing declaration references of Sema.
5838 RecordData SemaDeclRefs;
5839 if (SemaRef.StdNamespace || SemaRef.StdBadAlloc || SemaRef.StdAlignValT) {
5840 auto AddEmittedDeclRefOrZero = [this, &SemaDeclRefs](Decl *D) {
5841 if (!D || !wasDeclEmitted(D))
5842 SemaDeclRefs.push_back(0);
5843 else
5844 AddDeclRef(D, SemaDeclRefs);
5845 };
5846
5847 AddEmittedDeclRefOrZero(SemaRef.getStdNamespace());
5848 AddEmittedDeclRefOrZero(SemaRef.getStdBadAlloc());
5849 AddEmittedDeclRefOrZero(SemaRef.getStdAlignValT());
5850 }
5851 if (!SemaDeclRefs.empty())
5852 Stream.EmitRecord(SEMA_DECL_REFS, SemaDeclRefs);
5853
5854 // Write the record containing decls to be checked for deferred diags.
5855 RecordData DeclsToCheckForDeferredDiags;
5856 for (auto *D : SemaRef.DeclsToCheckForDeferredDiags)
5857 if (wasDeclEmitted(D))
5858 AddDeclRef(D, DeclsToCheckForDeferredDiags);
5859 if (!DeclsToCheckForDeferredDiags.empty())
5860 Stream.EmitRecord(DECLS_TO_CHECK_FOR_DEFERRED_DIAGS,
5861 DeclsToCheckForDeferredDiags);
5862
5863 // Write the record containing CUDA-specific declaration references.
5864 RecordData CUDASpecialDeclRefs;
5865 if (auto *CudaCallDecl = Context.getcudaConfigureCallDecl();
5866 CudaCallDecl && wasDeclEmitted(CudaCallDecl)) {
5867 AddDeclRef(CudaCallDecl, CUDASpecialDeclRefs);
5868 Stream.EmitRecord(CUDA_SPECIAL_DECL_REFS, CUDASpecialDeclRefs);
5869 }
5870
5871 // Write the delegating constructors.
5872 RecordData DelegatingCtorDecls;
5873 if (!isModule)
5875 DelegatingCtorDecls);
5876 if (!DelegatingCtorDecls.empty())
5877 Stream.EmitRecord(DELEGATING_CTORS, DelegatingCtorDecls);
5878
5879 // Write the known namespaces.
5880 RecordData KnownNamespaces;
5881 for (const auto &I : SemaRef.KnownNamespaces) {
5882 if (!I.second && wasDeclEmitted(I.first))
5883 AddDeclRef(I.first, KnownNamespaces);
5884 }
5885 if (!KnownNamespaces.empty())
5886 Stream.EmitRecord(KNOWN_NAMESPACES, KnownNamespaces);
5887
5888 // Write the undefined internal functions and variables, and inline functions.
5889 RecordData UndefinedButUsed;
5890 SmallVector<std::pair<NamedDecl *, SourceLocation>, 16> Undefined;
5892 for (const auto &I : Undefined) {
5893 if (!wasDeclEmitted(I.first))
5894 continue;
5895
5896 AddDeclRef(I.first, UndefinedButUsed);
5897 AddSourceLocation(I.second, UndefinedButUsed);
5898 }
5899 if (!UndefinedButUsed.empty())
5900 Stream.EmitRecord(UNDEFINED_BUT_USED, UndefinedButUsed);
5901
5902 // Write all delete-expressions that we would like to
5903 // analyze later in AST.
5904 RecordData DeleteExprsToAnalyze;
5905 if (!isModule) {
5906 for (const auto &DeleteExprsInfo :
5908 if (!wasDeclEmitted(DeleteExprsInfo.first))
5909 continue;
5910
5911 AddDeclRef(DeleteExprsInfo.first, DeleteExprsToAnalyze);
5912 DeleteExprsToAnalyze.push_back(DeleteExprsInfo.second.size());
5913 for (const auto &DeleteLoc : DeleteExprsInfo.second) {
5914 AddSourceLocation(DeleteLoc.first, DeleteExprsToAnalyze);
5915 DeleteExprsToAnalyze.push_back(DeleteLoc.second);
5916 }
5917 }
5918 }
5919 if (!DeleteExprsToAnalyze.empty())
5920 Stream.EmitRecord(DELETE_EXPRS_TO_ANALYZE, DeleteExprsToAnalyze);
5921
5922 RecordData VTablesToEmit;
5923 for (CXXRecordDecl *RD : PendingEmittingVTables) {
5924 if (!wasDeclEmitted(RD))
5925 continue;
5926
5927 AddDeclRef(RD, VTablesToEmit);
5928 }
5929
5930 if (!VTablesToEmit.empty())
5931 Stream.EmitRecord(VTABLES_TO_EMIT, VTablesToEmit);
5932}
5933
5934ASTFileSignature ASTWriter::WriteASTCore(Sema *SemaPtr, StringRef isysroot,
5935 Module *WritingModule) {
5936 using namespace llvm;
5937
5938 bool isModule = WritingModule != nullptr;
5939
5940 // Make sure that the AST reader knows to finalize itself.
5941 if (Chain)
5942 Chain->finalizeForWriting();
5943
5944 // This needs to be done very early, since everything that writes
5945 // SourceLocations or FileIDs depends on it.
5946 computeNonAffectingInputFiles();
5947
5948 writeUnhashedControlBlock(*PP);
5949
5950 // Don't reuse type ID and Identifier ID from readers for C++ standard named
5951 // modules since we want to support no-transitive-change model for named
5952 // modules. The theory for no-transitive-change model is,
5953 // for a user of a named module, the user can only access the indirectly
5954 // imported decls via the directly imported module. So that it is possible to
5955 // control what matters to the users when writing the module. It would be
5956 // problematic if the users can reuse the type IDs and identifier IDs from
5957 // indirectly imported modules arbitrarily. So we choose to clear these ID
5958 // here.
5960 TypeIdxs.clear();
5961 IdentifierIDs.clear();
5962 }
5963
5964 // Look for any identifiers that were named while processing the
5965 // headers, but are otherwise not needed. We add these to the hash
5966 // table to enable checking of the predefines buffer in the case
5967 // where the user adds new macro definitions when building the AST
5968 // file.
5969 //
5970 // We do this before emitting any Decl and Types to make sure the
5971 // Identifier ID is stable.
5972 SmallVector<const IdentifierInfo *, 128> IIs;
5973 for (const auto &ID : PP->getIdentifierTable())
5974 if (IsInterestingNonMacroIdentifier(ID.second, *this))
5975 IIs.push_back(ID.second);
5976 // Sort the identifiers lexicographically before getting the references so
5977 // that their order is stable.
5978 llvm::sort(IIs, llvm::deref<std::less<>>());
5979 for (const IdentifierInfo *II : IIs)
5980 getIdentifierRef(II);
5981
5982 // Write the set of weak, undeclared identifiers. We always write the
5983 // entire table, since later PCH files in a PCH chain are only interested in
5984 // the results at the end of the chain.
5985 RecordData WeakUndeclaredIdentifiers;
5986 if (SemaPtr) {
5987 for (const auto &WeakUndeclaredIdentifierList :
5988 SemaPtr->WeakUndeclaredIdentifiers) {
5989 const IdentifierInfo *const II = WeakUndeclaredIdentifierList.first;
5990 for (const auto &WI : WeakUndeclaredIdentifierList.second) {
5991 AddIdentifierRef(II, WeakUndeclaredIdentifiers);
5992 AddIdentifierRef(WI.getAlias(), WeakUndeclaredIdentifiers);
5993 AddSourceLocation(WI.getLocation(), WeakUndeclaredIdentifiers);
5994 }
5995 }
5996 }
5997
5998 // Form the record of special types.
5999 RecordData SpecialTypes;
6000 if (SemaPtr) {
6001 ASTContext &Context = SemaPtr->Context;
6002 AddTypeRef(Context, Context.getRawCFConstantStringType(), SpecialTypes);
6003 AddTypeRef(Context, Context.getFILEType(), SpecialTypes);
6004 AddTypeRef(Context, Context.getjmp_bufType(), SpecialTypes);
6005 AddTypeRef(Context, Context.getsigjmp_bufType(), SpecialTypes);
6006 AddTypeRef(Context, Context.ObjCIdRedefinitionType, SpecialTypes);
6007 AddTypeRef(Context, Context.ObjCClassRedefinitionType, SpecialTypes);
6008 AddTypeRef(Context, Context.ObjCSelRedefinitionType, SpecialTypes);
6009 AddTypeRef(Context, Context.getucontext_tType(), SpecialTypes);
6010 }
6011
6012 if (SemaPtr)
6013 PrepareWritingSpecialDecls(*SemaPtr);
6014
6015 // Write the control block
6016 WriteControlBlock(*PP, isysroot);
6017
6018 // Write the remaining AST contents.
6019 Stream.FlushToWord();
6020 ASTBlockRange.first = Stream.GetCurrentBitNo() >> 3;
6021 Stream.EnterSubblock(AST_BLOCK_ID, 5);
6022 ASTBlockStartOffset = Stream.GetCurrentBitNo();
6023
6024 // This is so that older clang versions, before the introduction
6025 // of the control block, can read and reject the newer PCH format.
6026 {
6028 Stream.EmitRecord(METADATA_OLD_FORMAT, Record);
6029 }
6030
6031 // For method pool in the module, if it contains an entry for a selector,
6032 // the entry should be complete, containing everything introduced by that
6033 // module and all modules it imports. It's possible that the entry is out of
6034 // date, so we need to pull in the new content here.
6035
6036 // It's possible that updateOutOfDateSelector can update SelectorIDs. To be
6037 // safe, we copy all selectors out.
6038 if (SemaPtr) {
6039 llvm::SmallVector<Selector, 256> AllSelectors;
6040 for (auto &SelectorAndID : SelectorIDs)
6041 AllSelectors.push_back(SelectorAndID.first);
6042 for (auto &Selector : AllSelectors)
6043 SemaPtr->ObjC().updateOutOfDateSelector(Selector);
6044 }
6045
6046 if (Chain) {
6047 // Write the mapping information describing our module dependencies and how
6048 // each of those modules were mapped into our own offset/ID space, so that
6049 // the reader can build the appropriate mapping to its own offset/ID space.
6050 // The map consists solely of a blob with the following format:
6051 // *(module-kind:i8
6052 // module-name-len:i16 module-name:len*i8
6053 // source-location-offset:i32
6054 // identifier-id:i32
6055 // preprocessed-entity-id:i32
6056 // macro-definition-id:i32
6057 // submodule-id:i32
6058 // selector-id:i32
6059 // declaration-id:i32
6060 // c++-base-specifiers-id:i32
6061 // type-id:i32)
6062 //
6063 // module-kind is the ModuleKind enum value. If it is MK_PrebuiltModule,
6064 // MK_ExplicitModule or MK_ImplicitModule, then the module-name is the
6065 // module name. Otherwise, it is the module file name.
6066 auto Abbrev = std::make_shared<BitCodeAbbrev>();
6067 Abbrev->Add(BitCodeAbbrevOp(MODULE_OFFSET_MAP));
6068 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob));
6069 unsigned ModuleOffsetMapAbbrev = Stream.EmitAbbrev(std::move(Abbrev));
6070 SmallString<2048> Buffer;
6071 {
6072 llvm::raw_svector_ostream Out(Buffer);
6073 for (ModuleFile &M : Chain->ModuleMgr) {
6074 using namespace llvm::support;
6075
6076 endian::Writer LE(Out, llvm::endianness::little);
6077 LE.write<uint8_t>(static_cast<uint8_t>(M.Kind));
6078 StringRef Name = M.isModule() ? M.ModuleName : M.FileName;
6079 LE.write<uint16_t>(Name.size());
6080 Out.write(Name.data(), Name.size());
6081
6082 // Note: if a base ID was uint max, it would not be possible to load
6083 // another module after it or have more than one entity inside it.
6084 uint32_t None = std::numeric_limits<uint32_t>::max();
6085
6086 auto writeBaseIDOrNone = [&](auto BaseID, bool ShouldWrite) {
6087 assert(BaseID < std::numeric_limits<uint32_t>::max() && "base id too high");
6088 if (ShouldWrite)
6089 LE.write<uint32_t>(BaseID);
6090 else
6091 LE.write<uint32_t>(None);
6092 };
6093
6094 // These values should be unique within a chain, since they will be read
6095 // as keys into ContinuousRangeMaps.
6096 writeBaseIDOrNone(M.BaseSubmoduleID, M.LocalNumSubmodules);
6097 writeBaseIDOrNone(M.BaseSelectorID, M.LocalNumSelectors);
6098 }
6099 }
6100 RecordData::value_type Record[] = {MODULE_OFFSET_MAP};
6101 Stream.EmitRecordWithBlob(ModuleOffsetMapAbbrev, Record,
6102 Buffer.data(), Buffer.size());
6103 }
6104
6105 if (SemaPtr)
6106 WriteDeclAndTypes(SemaPtr->Context);
6107
6108 WriteFileDeclIDsMap();
6109 WriteSourceManagerBlock(PP->getSourceManager());
6110 if (SemaPtr)
6111 WriteComments(SemaPtr->Context);
6112 WritePreprocessor(*PP, isModule);
6113 WriteHeaderSearch(PP->getHeaderSearchInfo());
6114 if (SemaPtr) {
6115 WriteSelectors(*SemaPtr);
6116 WriteReferencedSelectorsPool(*SemaPtr);
6117 WriteLateParsedTemplates(*SemaPtr);
6118 }
6119 WriteIdentifierTable(*PP, SemaPtr ? &SemaPtr->IdResolver : nullptr, isModule);
6120 if (SemaPtr) {
6121 WriteFPPragmaOptions(SemaPtr->CurFPFeatureOverrides());
6122 WriteOpenCLExtensions(*SemaPtr);
6123 WriteCUDAPragmas(*SemaPtr);
6124 }
6125
6126 // If we're emitting a module, write out the submodule information.
6127 if (WritingModule)
6128 WriteSubmodules(WritingModule, SemaPtr ? &SemaPtr->Context : nullptr);
6129
6130 Stream.EmitRecord(SPECIAL_TYPES, SpecialTypes);
6131
6132 if (SemaPtr)
6133 WriteSpecialDeclRecords(*SemaPtr);
6134
6135 // Write the record containing weak undeclared identifiers.
6136 if (!WeakUndeclaredIdentifiers.empty())
6137 Stream.EmitRecord(WEAK_UNDECLARED_IDENTIFIERS,
6138 WeakUndeclaredIdentifiers);
6139
6140 if (!WritingModule) {
6141 // Write the submodules that were imported, if any.
6142 struct ModuleInfo {
6143 uint64_t ID;
6144 Module *M;
6145 ModuleInfo(uint64_t ID, Module *M) : ID(ID), M(M) {}
6146 };
6147 llvm::SmallVector<ModuleInfo, 64> Imports;
6148 if (SemaPtr) {
6149 for (const auto *I : SemaPtr->Context.local_imports()) {
6150 assert(SubmoduleIDs.contains(I->getImportedModule()));
6151 Imports.push_back(ModuleInfo(SubmoduleIDs[I->getImportedModule()],
6152 I->getImportedModule()));
6153 }
6154 }
6155
6156 if (!Imports.empty()) {
6157 auto Cmp = [](const ModuleInfo &A, const ModuleInfo &B) {
6158 return A.ID < B.ID;
6159 };
6160 auto Eq = [](const ModuleInfo &A, const ModuleInfo &B) {
6161 return A.ID == B.ID;
6162 };
6163
6164 // Sort and deduplicate module IDs.
6165 llvm::sort(Imports, Cmp);
6166 Imports.erase(llvm::unique(Imports, Eq), Imports.end());
6167
6168 RecordData ImportedModules;
6169 for (const auto &Import : Imports) {
6170 ImportedModules.push_back(Import.ID);
6171 // FIXME: If the module has macros imported then later has declarations
6172 // imported, this location won't be the right one as a location for the
6173 // declaration imports.
6174 AddSourceLocation(PP->getModuleImportLoc(Import.M), ImportedModules);
6175 }
6176
6177 Stream.EmitRecord(IMPORTED_MODULES, ImportedModules);
6178 }
6179 }
6180
6181 WriteObjCCategories();
6182 if (SemaPtr) {
6183 if (!WritingModule) {
6184 WriteOptimizePragmaOptions(*SemaPtr);
6185 WriteMSStructPragmaOptions(*SemaPtr);
6186 WriteMSPointersToMembersPragmaOptions(*SemaPtr);
6187 }
6188 WritePackPragmaOptions(*SemaPtr);
6189 WriteFloatControlPragmaOptions(*SemaPtr);
6190 WriteDeclsWithEffectsToVerify(*SemaPtr);
6191 }
6192
6193 // Some simple statistics
6194 RecordData::value_type Record[] = {NumStatements,
6195 NumMacros,
6196 NumLexicalDeclContexts,
6197 NumVisibleDeclContexts,
6198 NumModuleLocalDeclContexts,
6199 NumTULocalDeclContexts};
6200 Stream.EmitRecord(STATISTICS, Record);
6201 Stream.ExitBlock();
6202 Stream.FlushToWord();
6203 ASTBlockRange.second = Stream.GetCurrentBitNo() >> 3;
6204
6205 // Write the module file extension blocks.
6206 if (SemaPtr)
6207 for (const auto &ExtWriter : ModuleFileExtensionWriters)
6208 WriteModuleFileExtension(*SemaPtr, *ExtWriter);
6209
6210 return backpatchSignature();
6211}
6212
6214 // In C++20 named modules, all entities before entering the module purview
6215 // lives in the GMF.
6216 if (GeneratingReducedBMI)
6217 DeclUpdatesFromGMF.swap(DeclUpdates);
6218}
6219
6220// Add update records for all mangling numbers and static local numbers.
6221// These aren't really update records, but this is a convenient way of
6222// tagging this rare extra data onto the declarations.
6223void ASTWriter::AddedManglingNumber(const Decl *D, unsigned Number) {
6224 if (D->isFromASTFile())
6225 return;
6226
6227 DeclUpdates[D].push_back(DeclUpdate(DeclUpdateKind::ManglingNumber, Number));
6228}
6229void ASTWriter::AddedStaticLocalNumbers(const Decl *D, unsigned Number) {
6230 if (D->isFromASTFile())
6231 return;
6232
6233 DeclUpdates[D].push_back(
6234 DeclUpdate(DeclUpdateKind::StaticLocalNumber, Number));
6235}
6236
6237void ASTWriter::AddedAnonymousNamespace(const TranslationUnitDecl *TU,
6238 NamespaceDecl *AnonNamespace) {
6239 // If the translation unit has an anonymous namespace, and we don't already
6240 // have an update block for it, write it as an update block.
6241 // FIXME: Why do we not do this if there's already an update block?
6242 if (NamespaceDecl *NS = TU->getAnonymousNamespace()) {
6243 ASTWriter::UpdateRecord &Record = DeclUpdates[TU];
6244 if (Record.empty())
6245 Record.push_back(
6246 DeclUpdate(DeclUpdateKind::CXXAddedAnonymousNamespace, NS));
6247 }
6248}
6249
6250void ASTWriter::WriteDeclAndTypes(ASTContext &Context) {
6251 // Keep writing types, declarations, and declaration update records
6252 // until we've emitted all of them.
6253 RecordData DeclUpdatesOffsetsRecord;
6254 Stream.EnterSubblock(DECLTYPES_BLOCK_ID, /*bits for abbreviations*/ 6);
6255 DeclTypesBlockStartOffset = Stream.GetCurrentBitNo();
6256 WriteTypeAbbrevs();
6257 WriteDeclAbbrevs();
6258 do {
6259 WriteDeclUpdatesBlocks(Context, DeclUpdatesOffsetsRecord);
6260 while (!DeclTypesToEmit.empty()) {
6261 DeclOrType DOT = DeclTypesToEmit.front();
6262 DeclTypesToEmit.pop();
6263 if (DOT.isType())
6264 WriteType(Context, DOT.getType());
6265 else
6266 WriteDecl(Context, DOT.getDecl());
6267 }
6268 } while (!DeclUpdates.empty());
6269
6270 DoneWritingDeclsAndTypes = true;
6271
6272 // DelayedNamespace is only meaningful in reduced BMI.
6273 // See the comments of DelayedNamespace for details.
6274 assert(DelayedNamespace.empty() || GeneratingReducedBMI);
6275 RecordData DelayedNamespaceRecord;
6276 for (NamespaceDecl *NS : DelayedNamespace) {
6277 LookupBlockOffsets Offsets;
6278
6279 Offsets.LexicalOffset = WriteDeclContextLexicalBlock(Context, NS);
6280 WriteDeclContextVisibleBlock(Context, NS, Offsets);
6281
6282 if (Offsets.LexicalOffset)
6283 Offsets.LexicalOffset -= DeclTypesBlockStartOffset;
6284
6285 // Write the offset relative to current block.
6286 if (Offsets.VisibleOffset)
6287 Offsets.VisibleOffset -= DeclTypesBlockStartOffset;
6288
6289 if (Offsets.ModuleLocalOffset)
6290 Offsets.ModuleLocalOffset -= DeclTypesBlockStartOffset;
6291
6292 if (Offsets.TULocalOffset)
6293 Offsets.TULocalOffset -= DeclTypesBlockStartOffset;
6294
6295 AddDeclRef(NS, DelayedNamespaceRecord);
6296 AddLookupOffsets(Offsets, DelayedNamespaceRecord);
6297 }
6298
6299 // The process of writing lexical and visible block for delayed namespace
6300 // shouldn't introduce any new decls, types or update to emit.
6301 assert(DeclTypesToEmit.empty());
6302 assert(DeclUpdates.empty());
6303
6304 Stream.ExitBlock();
6305
6306 // These things can only be done once we've written out decls and types.
6307 WriteTypeDeclOffsets();
6308 if (!DeclUpdatesOffsetsRecord.empty())
6309 Stream.EmitRecord(DECL_UPDATE_OFFSETS, DeclUpdatesOffsetsRecord);
6310
6311 if (!DelayedNamespaceRecord.empty())
6313 DelayedNamespaceRecord);
6314
6315 if (!RelatedDeclsMap.empty()) {
6316 // TODO: on disk hash table for related decls mapping might be more
6317 // efficent becuase it allows lazy deserialization.
6318 RecordData RelatedDeclsMapRecord;
6319 for (const auto &Pair : RelatedDeclsMap) {
6320 RelatedDeclsMapRecord.push_back(Pair.first.getRawValue());
6321 RelatedDeclsMapRecord.push_back(Pair.second.size());
6322 for (const auto &Lambda : Pair.second)
6323 RelatedDeclsMapRecord.push_back(Lambda.getRawValue());
6324 }
6325
6326 auto Abv = std::make_shared<llvm::BitCodeAbbrev>();
6327 Abv->Add(llvm::BitCodeAbbrevOp(RELATED_DECLS_MAP));
6328 Abv->Add(llvm::BitCodeAbbrevOp(llvm::BitCodeAbbrevOp::Array));
6329 Abv->Add(llvm::BitCodeAbbrevOp(llvm::BitCodeAbbrevOp::VBR, 6));
6330 unsigned FunctionToLambdaMapAbbrev = Stream.EmitAbbrev(std::move(Abv));
6331 Stream.EmitRecord(RELATED_DECLS_MAP, RelatedDeclsMapRecord,
6332 FunctionToLambdaMapAbbrev);
6333 }
6334
6335 if (!SpecializationsUpdates.empty()) {
6336 WriteSpecializationsUpdates(/*IsPartial=*/false);
6337 SpecializationsUpdates.clear();
6338 }
6339
6340 if (!PartialSpecializationsUpdates.empty()) {
6341 WriteSpecializationsUpdates(/*IsPartial=*/true);
6342 PartialSpecializationsUpdates.clear();
6343 }
6344
6345 const TranslationUnitDecl *TU = Context.getTranslationUnitDecl();
6346 // Create a lexical update block containing all of the declarations in the
6347 // translation unit that do not come from other AST files.
6348 SmallVector<DeclID, 128> NewGlobalKindDeclPairs;
6349 for (const auto *D : TU->noload_decls()) {
6350 if (D->isFromASTFile())
6351 continue;
6352
6353 // In reduced BMI, skip unreached declarations.
6354 if (!wasDeclEmitted(D))
6355 continue;
6356
6357 NewGlobalKindDeclPairs.push_back(D->getKind());
6358 NewGlobalKindDeclPairs.push_back(GetDeclRef(D).getRawValue());
6359 }
6360
6361 auto Abv = std::make_shared<llvm::BitCodeAbbrev>();
6362 Abv->Add(llvm::BitCodeAbbrevOp(TU_UPDATE_LEXICAL));
6363 Abv->Add(llvm::BitCodeAbbrevOp(llvm::BitCodeAbbrevOp::Blob));
6364 unsigned TuUpdateLexicalAbbrev = Stream.EmitAbbrev(std::move(Abv));
6365
6366 RecordData::value_type Record[] = {TU_UPDATE_LEXICAL};
6367 Stream.EmitRecordWithBlob(TuUpdateLexicalAbbrev, Record,
6368 bytes(NewGlobalKindDeclPairs));
6369
6370 Abv = std::make_shared<llvm::BitCodeAbbrev>();
6371 Abv->Add(llvm::BitCodeAbbrevOp(UPDATE_VISIBLE));
6372 Abv->Add(llvm::BitCodeAbbrevOp(llvm::BitCodeAbbrevOp::VBR, 6));
6373 Abv->Add(llvm::BitCodeAbbrevOp(llvm::BitCodeAbbrevOp::Blob));
6374 UpdateVisibleAbbrev = Stream.EmitAbbrev(std::move(Abv));
6375
6376 Abv = std::make_shared<llvm::BitCodeAbbrev>();
6377 Abv->Add(llvm::BitCodeAbbrevOp(UPDATE_MODULE_LOCAL_VISIBLE));
6378 Abv->Add(llvm::BitCodeAbbrevOp(llvm::BitCodeAbbrevOp::VBR, 6));
6379 Abv->Add(llvm::BitCodeAbbrevOp(llvm::BitCodeAbbrevOp::Blob));
6380 ModuleLocalUpdateVisibleAbbrev = Stream.EmitAbbrev(std::move(Abv));
6381
6382 Abv = std::make_shared<llvm::BitCodeAbbrev>();
6383 Abv->Add(llvm::BitCodeAbbrevOp(UPDATE_TU_LOCAL_VISIBLE));
6384 Abv->Add(llvm::BitCodeAbbrevOp(llvm::BitCodeAbbrevOp::VBR, 6));
6385 Abv->Add(llvm::BitCodeAbbrevOp(llvm::BitCodeAbbrevOp::Blob));
6386 TULocalUpdateVisibleAbbrev = Stream.EmitAbbrev(std::move(Abv));
6387
6388 // And a visible updates block for the translation unit.
6389 WriteDeclContextVisibleUpdate(Context, TU);
6390
6391 // If we have any extern "C" names, write out a visible update for them.
6392 if (Context.ExternCContext)
6393 WriteDeclContextVisibleUpdate(Context, Context.ExternCContext);
6394
6395 // Write the visible updates to DeclContexts.
6396 for (auto *DC : UpdatedDeclContexts)
6397 WriteDeclContextVisibleUpdate(Context, DC);
6398}
6399
6400void ASTWriter::WriteSpecializationsUpdates(bool IsPartial) {
6401 auto RecordType = IsPartial ? CXX_ADDED_TEMPLATE_PARTIAL_SPECIALIZATION
6403
6404 auto Abv = std::make_shared<llvm::BitCodeAbbrev>();
6405 Abv->Add(llvm::BitCodeAbbrevOp(RecordType));
6406 Abv->Add(llvm::BitCodeAbbrevOp(llvm::BitCodeAbbrevOp::VBR, 6));
6407 Abv->Add(llvm::BitCodeAbbrevOp(llvm::BitCodeAbbrevOp::Blob));
6408 auto UpdateSpecializationAbbrev = Stream.EmitAbbrev(std::move(Abv));
6409
6410 auto &SpecUpdates =
6411 IsPartial ? PartialSpecializationsUpdates : SpecializationsUpdates;
6412 for (auto &SpecializationUpdate : SpecUpdates) {
6413 const NamedDecl *D = SpecializationUpdate.first;
6414
6415 llvm::SmallString<4096> LookupTable;
6416 GenerateSpecializationInfoLookupTable(D, SpecializationUpdate.second,
6417 LookupTable, IsPartial);
6418
6419 // Write the lookup table
6420 RecordData::value_type Record[] = {
6421 static_cast<RecordData::value_type>(RecordType),
6422 getDeclID(D).getRawValue()};
6423 Stream.EmitRecordWithBlob(UpdateSpecializationAbbrev, Record, LookupTable);
6424 }
6425}
6426
6427void ASTWriter::WriteDeclUpdatesBlocks(ASTContext &Context,
6428 RecordDataImpl &OffsetsRecord) {
6429 if (DeclUpdates.empty())
6430 return;
6431
6432 DeclUpdateMap LocalUpdates;
6433 LocalUpdates.swap(DeclUpdates);
6434
6435 for (auto &DeclUpdate : LocalUpdates) {
6436 const Decl *D = DeclUpdate.first;
6437
6438 bool HasUpdatedBody = false;
6439 bool HasAddedVarDefinition = false;
6441 ASTRecordWriter Record(Context, *this, RecordData);
6442 for (auto &Update : DeclUpdate.second) {
6443 DeclUpdateKind Kind = Update.getKind();
6444
6445 // An updated body is emitted last, so that the reader doesn't need
6446 // to skip over the lazy body to reach statements for other records.
6447 if (Kind == DeclUpdateKind::CXXAddedFunctionDefinition)
6448 HasUpdatedBody = true;
6449 else if (Kind == DeclUpdateKind::CXXAddedVarDefinition)
6450 HasAddedVarDefinition = true;
6451 else
6452 Record.push_back(llvm::to_underlying(Kind));
6453
6454 switch (Kind) {
6455 case DeclUpdateKind::CXXAddedImplicitMember:
6456 case DeclUpdateKind::CXXAddedAnonymousNamespace:
6457 assert(Update.getDecl() && "no decl to add?");
6458 Record.AddDeclRef(Update.getDecl());
6459 break;
6460 case DeclUpdateKind::CXXAddedFunctionDefinition:
6461 case DeclUpdateKind::CXXAddedVarDefinition:
6462 break;
6463
6464 case DeclUpdateKind::CXXPointOfInstantiation:
6465 // FIXME: Do we need to also save the template specialization kind here?
6466 Record.AddSourceLocation(Update.getLoc());
6467 break;
6468
6469 case DeclUpdateKind::CXXInstantiatedDefaultArgument:
6470 Record.writeStmtRef(
6471 cast<ParmVarDecl>(Update.getDecl())->getDefaultArg());
6472 break;
6473
6474 case DeclUpdateKind::CXXInstantiatedDefaultMemberInitializer:
6475 Record.AddStmt(
6476 cast<FieldDecl>(Update.getDecl())->getInClassInitializer());
6477 break;
6478
6479 case DeclUpdateKind::CXXInstantiatedClassDefinition: {
6480 auto *RD = cast<CXXRecordDecl>(D);
6481 UpdatedDeclContexts.insert(RD->getPrimaryContext());
6482 Record.push_back(RD->isParamDestroyedInCallee());
6483 Record.push_back(llvm::to_underlying(RD->getArgPassingRestrictions()));
6484 Record.AddCXXDefinitionData(RD);
6485 Record.AddOffset(WriteDeclContextLexicalBlock(Context, RD));
6486
6487 // This state is sometimes updated by template instantiation, when we
6488 // switch from the specialization referring to the template declaration
6489 // to it referring to the template definition.
6490 if (auto *MSInfo = RD->getMemberSpecializationInfo()) {
6491 Record.push_back(MSInfo->getTemplateSpecializationKind());
6492 Record.AddSourceLocation(MSInfo->getPointOfInstantiation());
6493 } else {
6495 Record.push_back(Spec->getTemplateSpecializationKind());
6496 Record.AddSourceLocation(Spec->getPointOfInstantiation());
6497
6498 // The instantiation might have been resolved to a partial
6499 // specialization. If so, record which one.
6500 auto From = Spec->getInstantiatedFrom();
6501 if (auto PartialSpec =
6502 From.dyn_cast<ClassTemplatePartialSpecializationDecl*>()) {
6503 Record.push_back(true);
6504 Record.AddDeclRef(PartialSpec);
6505 Record.AddTemplateArgumentList(
6506 &Spec->getTemplateInstantiationArgs());
6507 } else {
6508 Record.push_back(false);
6509 }
6510 }
6511 Record.push_back(llvm::to_underlying(RD->getTagKind()));
6512 Record.AddSourceLocation(RD->getLocation());
6513 Record.AddSourceLocation(RD->getBeginLoc());
6514 Record.AddSourceRange(RD->getBraceRange());
6515
6516 // Instantiation may change attributes; write them all out afresh.
6517 Record.push_back(D->hasAttrs());
6518 if (D->hasAttrs())
6519 Record.AddAttributes(D->getAttrs());
6520
6521 // FIXME: Ensure we don't get here for explicit instantiations.
6522 break;
6523 }
6524
6525 case DeclUpdateKind::CXXResolvedDtorDelete:
6526 Record.AddDeclRef(Update.getDecl());
6527 Record.AddStmt(cast<CXXDestructorDecl>(D)->getOperatorDeleteThisArg());
6528 break;
6529
6530 case DeclUpdateKind::CXXResolvedDtorGlobDelete:
6531 Record.AddDeclRef(Update.getDecl());
6532 break;
6533
6534 case DeclUpdateKind::CXXResolvedDtorArrayDelete:
6535 Record.AddDeclRef(Update.getDecl());
6536 break;
6537
6538 case DeclUpdateKind::CXXResolvedDtorGlobArrayDelete:
6539 Record.AddDeclRef(Update.getDecl());
6540 break;
6541
6542 case DeclUpdateKind::CXXResolvedExceptionSpec: {
6543 auto prototype =
6544 cast<FunctionDecl>(D)->getType()->castAs<FunctionProtoType>();
6545 Record.writeExceptionSpecInfo(prototype->getExceptionSpecInfo());
6546 break;
6547 }
6548
6549 case DeclUpdateKind::CXXDeducedReturnType:
6550 Record.push_back(GetOrCreateTypeID(Context, Update.getType()));
6551 break;
6552
6553 case DeclUpdateKind::DeclMarkedUsed:
6554 break;
6555
6556 case DeclUpdateKind::ManglingNumber:
6557 case DeclUpdateKind::StaticLocalNumber:
6558 Record.push_back(Update.getNumber());
6559 break;
6560
6561 case DeclUpdateKind::DeclMarkedOpenMPThreadPrivate:
6562 Record.AddSourceRange(
6563 D->getAttr<OMPThreadPrivateDeclAttr>()->getRange());
6564 break;
6565
6566 case DeclUpdateKind::DeclMarkedOpenMPAllocate: {
6567 auto *A = D->getAttr<OMPAllocateDeclAttr>();
6568 Record.push_back(A->getAllocatorType());
6569 Record.AddStmt(A->getAllocator());
6570 Record.AddStmt(A->getAlignment());
6571 Record.AddSourceRange(A->getRange());
6572 break;
6573 }
6574
6575 case DeclUpdateKind::DeclMarkedOpenMPDeclareTarget:
6576 Record.push_back(D->getAttr<OMPDeclareTargetDeclAttr>()->getMapType());
6577 Record.AddSourceRange(
6578 D->getAttr<OMPDeclareTargetDeclAttr>()->getRange());
6579 break;
6580
6581 case DeclUpdateKind::DeclExported:
6582 Record.push_back(getSubmoduleID(Update.getModule()));
6583 break;
6584
6585 case DeclUpdateKind::AddedAttrToRecord:
6586 Record.AddAttributes(llvm::ArrayRef(Update.getAttr()));
6587 break;
6588 }
6589 }
6590
6591 // Add a trailing update record, if any. These must go last because we
6592 // lazily load their attached statement.
6593 if (!GeneratingReducedBMI || !CanElideDeclDef(D)) {
6594 if (HasUpdatedBody) {
6595 const auto *Def = cast<FunctionDecl>(D);
6596 Record.push_back(
6597 llvm::to_underlying(DeclUpdateKind::CXXAddedFunctionDefinition));
6598 Record.push_back(Def->isInlined());
6599 Record.AddSourceLocation(Def->getInnerLocStart());
6600 Record.AddFunctionDefinition(Def);
6601 } else if (HasAddedVarDefinition) {
6602 const auto *VD = cast<VarDecl>(D);
6603 Record.push_back(
6604 llvm::to_underlying(DeclUpdateKind::CXXAddedVarDefinition));
6605 Record.push_back(VD->isInline());
6606 Record.push_back(VD->isInlineSpecified());
6607 Record.AddVarDeclInit(VD);
6608 }
6609 }
6610
6611 AddDeclRef(D, OffsetsRecord);
6612 OffsetsRecord.push_back(Record.Emit(DECL_UPDATES));
6613 }
6614}
6615
6618 uint32_t Raw = Sema::AlignPackInfo::getRawEncoding(Info);
6619 Record.push_back(Raw);
6620}
6621
6622FileID ASTWriter::getAdjustedFileID(FileID FID) const {
6623 if (FID.isInvalid() || PP->getSourceManager().isLoadedFileID(FID) ||
6624 NonAffectingFileIDs.empty())
6625 return FID;
6626 auto It = llvm::lower_bound(NonAffectingFileIDs, FID);
6627 unsigned Idx = std::distance(NonAffectingFileIDs.begin(), It);
6628 unsigned Offset = NonAffectingFileIDAdjustments[Idx];
6629 return FileID::get(FID.getOpaqueValue() - Offset);
6630}
6631
6632unsigned ASTWriter::getAdjustedNumCreatedFIDs(FileID FID) const {
6633 unsigned NumCreatedFIDs = PP->getSourceManager()
6634 .getLocalSLocEntry(FID.ID)
6635 .getFile()
6636 .NumCreatedFIDs;
6637
6638 unsigned AdjustedNumCreatedFIDs = 0;
6639 for (unsigned I = FID.ID, N = I + NumCreatedFIDs; I != N; ++I)
6640 if (IsSLocAffecting[I])
6641 ++AdjustedNumCreatedFIDs;
6642 return AdjustedNumCreatedFIDs;
6643}
6644
6645SourceLocation ASTWriter::getAdjustedLocation(SourceLocation Loc) const {
6646 if (Loc.isInvalid())
6647 return Loc;
6648 return Loc.getLocWithOffset(-getAdjustment(Loc.getOffset()));
6649}
6650
6651SourceRange ASTWriter::getAdjustedRange(SourceRange Range) const {
6652 return SourceRange(getAdjustedLocation(Range.getBegin()),
6653 getAdjustedLocation(Range.getEnd()));
6654}
6655
6657ASTWriter::getAdjustedOffset(SourceLocation::UIntTy Offset) const {
6658 return Offset - getAdjustment(Offset);
6659}
6660
6662ASTWriter::getAdjustment(SourceLocation::UIntTy Offset) const {
6663 if (NonAffectingRanges.empty())
6664 return 0;
6665
6666 if (PP->getSourceManager().isLoadedOffset(Offset))
6667 return 0;
6668
6669 if (Offset > NonAffectingRanges.back().getEnd().getOffset())
6670 return NonAffectingOffsetAdjustments.back();
6671
6672 if (Offset < NonAffectingRanges.front().getBegin().getOffset())
6673 return 0;
6674
6675 auto Contains = [](const SourceRange &Range, SourceLocation::UIntTy Offset) {
6676 return Range.getEnd().getOffset() < Offset;
6677 };
6678
6679 auto It = llvm::lower_bound(NonAffectingRanges, Offset, Contains);
6680 unsigned Idx = std::distance(NonAffectingRanges.begin(), It);
6681 return NonAffectingOffsetAdjustments[Idx];
6682}
6683
6685 Record.push_back(getAdjustedFileID(FID).getOpaqueValue());
6686}
6687
6690 SourceLocation::UIntTy BaseOffset = 0;
6691 unsigned ModuleFileIndex = 0;
6692
6693 // See SourceLocationEncoding.h for the encoding details.
6694 if (PP->getSourceManager().isLoadedSourceLocation(Loc) && Loc.isValid()) {
6695 assert(getChain());
6696 auto SLocMapI = getChain()->GlobalSLocOffsetMap.find(
6697 SourceManager::MaxLoadedOffset - Loc.getOffset() - 1);
6698 assert(SLocMapI != getChain()->GlobalSLocOffsetMap.end() &&
6699 "Corrupted global sloc offset map");
6700 ModuleFile *F = SLocMapI->second;
6701 BaseOffset = F->SLocEntryBaseOffset - 2;
6702 // 0 means the location is not loaded. So we need to add 1 to the index to
6703 // make it clear.
6704 ModuleFileIndex = F->Index + 1;
6705 assert(&getChain()->getModuleManager()[F->Index] == F);
6706 }
6707
6708 return SourceLocationEncoding::encode(Loc, BaseOffset, ModuleFileIndex);
6709}
6710
6712 Loc = getAdjustedLocation(Loc);
6713 Record.push_back(getRawSourceLocationEncoding(Loc));
6714}
6715
6717 AddSourceLocation(Range.getBegin(), Record);
6718 AddSourceLocation(Range.getEnd(), Record);
6719}
6720
6721void ASTRecordWriter::AddAPFloat(const llvm::APFloat &Value) {
6722 AddAPInt(Value.bitcastToAPInt());
6723}
6724
6728
6730 if (!II)
6731 return 0;
6732
6733 IdentifierID &ID = IdentifierIDs[II];
6734 if (ID == 0)
6735 ID = NextIdentID++;
6736 return ID;
6737}
6738
6740 // Don't emit builtin macros like __LINE__ to the AST file unless they
6741 // have been redefined by the header (in which case they are not
6742 // isBuiltinMacro).
6743 if (!MI || MI->isBuiltinMacro())
6744 return 0;
6745
6746 MacroID &ID = MacroIDs[MI];
6747 if (ID == 0) {
6748 ID = NextMacroID++;
6749 MacroInfoToEmitData Info = { Name, MI, ID };
6750 MacroInfosToEmit.push_back(Info);
6751 }
6752 return ID;
6753}
6754
6756 return IdentMacroDirectivesOffsetMap.lookup(Name);
6757}
6758
6760 Record->push_back(Writer->getSelectorRef(SelRef));
6761}
6762
6764 if (Sel.getAsOpaquePtr() == nullptr) {
6765 return 0;
6766 }
6767
6768 SelectorID SID = SelectorIDs[Sel];
6769 if (SID == 0 && Chain) {
6770 // This might trigger a ReadSelector callback, which will set the ID for
6771 // this selector.
6772 Chain->LoadSelector(Sel);
6773 SID = SelectorIDs[Sel];
6774 }
6775 if (SID == 0) {
6776 SID = NextSelectorID++;
6777 SelectorIDs[Sel] = SID;
6778 }
6779 return SID;
6780}
6781
6785
6814
6817
6819 bool InfoHasSameExpr
6820 = Arg.getArgument().getAsExpr() == Arg.getLocInfo().getAsExpr();
6821 Record->push_back(InfoHasSameExpr);
6822 if (InfoHasSameExpr)
6823 return; // Avoid storing the same expr twice.
6824 }
6826}
6827
6829 if (!TInfo) {
6831 return;
6832 }
6833
6834 AddTypeRef(TInfo->getType());
6835 AddTypeLoc(TInfo->getTypeLoc());
6836}
6837
6839 TypeLocWriter TLW(*this);
6840 for (; !TL.isNull(); TL = TL.getNextTypeLoc())
6841 TLW.Visit(TL);
6842}
6843
6846 Record.push_back(GetOrCreateTypeID(Context, T));
6847}
6848
6849template <typename IdxForTypeTy>
6851 IdxForTypeTy IdxForType) {
6852 if (T.isNull())
6853 return PREDEF_TYPE_NULL_ID;
6854
6855 unsigned FastQuals = T.getLocalFastQualifiers();
6856 T.removeLocalFastQualifiers();
6857
6858 if (T.hasLocalNonFastQualifiers())
6859 return IdxForType(T).asTypeID(FastQuals);
6860
6861 assert(!T.hasLocalQualifiers());
6862
6863 if (const BuiltinType *BT = dyn_cast<BuiltinType>(T.getTypePtr()))
6864 return TypeIdxFromBuiltin(BT).asTypeID(FastQuals);
6865
6866 if (T == Context.AutoDeductTy)
6867 return TypeIdx(0, PREDEF_TYPE_AUTO_DEDUCT).asTypeID(FastQuals);
6868 if (T == Context.AutoRRefDeductTy)
6869 return TypeIdx(0, PREDEF_TYPE_AUTO_RREF_DEDUCT).asTypeID(FastQuals);
6870
6871 return IdxForType(T).asTypeID(FastQuals);
6872}
6873
6875 return MakeTypeID(Context, T, [&](QualType T) -> TypeIdx {
6876 if (T.isNull())
6877 return TypeIdx();
6878 assert(!T.getLocalFastQualifiers());
6879
6880 TypeIdx &Idx = TypeIdxs[T];
6881 if (Idx.getValue() == 0) {
6882 if (DoneWritingDeclsAndTypes) {
6883 assert(0 && "New type seen after serializing all the types to emit!");
6884 return TypeIdx();
6885 }
6886
6887 // We haven't seen this type before. Assign it a new ID and put it
6888 // into the queue of types to emit.
6889 Idx = TypeIdx(0, NextTypeID++);
6890 DeclTypesToEmit.push(T);
6891 }
6892 return Idx;
6893 });
6894}
6895
6898 Record.push_back(Offsets.LexicalOffset);
6899 Record.push_back(Offsets.VisibleOffset);
6900 Record.push_back(Offsets.ModuleLocalOffset);
6901 Record.push_back(Offsets.TULocalOffset);
6902}
6903
6906 MacroID MacroRef = getMacroRef(MI, Name);
6907 Record.push_back(MacroRef >> 32);
6908 Record.push_back(MacroRef & llvm::maskTrailingOnes<MacroID>(32));
6909}
6910
6912 if (!wasDeclEmitted(D))
6913 return;
6914
6915 AddDeclRef(D, Record);
6916}
6917
6919 Record.push_back(GetDeclRef(D).getRawValue());
6920}
6921
6923 assert(WritingAST && "Cannot request a declaration ID before AST writing");
6924
6925 if (!D) {
6926 return LocalDeclID();
6927 }
6928
6929 // If the DeclUpdate from the GMF gets touched, emit it.
6930 if (auto *Iter = DeclUpdatesFromGMF.find(D);
6931 Iter != DeclUpdatesFromGMF.end()) {
6932 for (DeclUpdate &Update : Iter->second)
6933 DeclUpdates[D].push_back(Update);
6934 DeclUpdatesFromGMF.erase(Iter);
6935 }
6936
6937 // If D comes from an AST file, its declaration ID is already known and
6938 // fixed.
6939 if (D->isFromASTFile()) {
6941 TouchedTopLevelModules.insert(D->getOwningModule()->getTopLevelModule());
6942
6943 return LocalDeclID(D->getGlobalID());
6944 }
6945
6946 assert(!(reinterpret_cast<uintptr_t>(D) & 0x01) && "Invalid decl pointer");
6947 LocalDeclID &ID = DeclIDs[D];
6948 if (ID.isInvalid()) {
6949 if (DoneWritingDeclsAndTypes) {
6950 assert(0 && "New decl seen after serializing all the decls to emit!");
6951 return LocalDeclID();
6952 }
6953
6954 // We haven't seen this declaration before. Give it a new ID and
6955 // enqueue it in the list of declarations to emit.
6956 ID = NextDeclID++;
6957 DeclTypesToEmit.push(const_cast<Decl *>(D));
6958 }
6959
6960 return ID;
6961}
6962
6964 if (!D)
6965 return LocalDeclID();
6966
6967 // If D comes from an AST file, its declaration ID is already known and
6968 // fixed.
6969 if (D->isFromASTFile())
6970 return LocalDeclID(D->getGlobalID());
6971
6972 assert(DeclIDs.contains(D) && "Declaration not emitted!");
6973 return DeclIDs[D];
6974}
6975
6976bool ASTWriter::wasDeclEmitted(const Decl *D) const {
6977 assert(D);
6978
6979 assert(DoneWritingDeclsAndTypes &&
6980 "wasDeclEmitted should only be called after writing declarations");
6981
6982 if (D->isFromASTFile())
6983 return true;
6984
6985 bool Emitted = DeclIDs.contains(D);
6986 assert((Emitted || (!D->getOwningModule() && isWritingStdCXXNamedModules()) ||
6987 GeneratingReducedBMI) &&
6988 "The declaration within modules can only be omitted in reduced BMI.");
6989 return Emitted;
6990}
6991
6992void ASTWriter::associateDeclWithFile(const Decl *D, LocalDeclID ID) {
6993 assert(ID.isValid());
6994 assert(D);
6995
6996 SourceLocation Loc = D->getLocation();
6997 if (Loc.isInvalid())
6998 return;
6999
7000 // We only keep track of the file-level declarations of each file.
7002 return;
7003 // FIXME: ParmVarDecls that are part of a function type of a parameter of
7004 // a function/objc method, should not have TU as lexical context.
7005 // TemplateTemplateParmDecls that are part of an alias template, should not
7006 // have TU as lexical context.
7008 return;
7009
7011 SourceLocation FileLoc = SM.getFileLoc(Loc);
7012 assert(SM.isLocalSourceLocation(FileLoc));
7013 auto [FID, Offset] = SM.getDecomposedLoc(FileLoc);
7014 if (FID.isInvalid())
7015 return;
7016 assert(SM.getSLocEntry(FID).isFile());
7017 assert(IsSLocAffecting[FID.ID]);
7018
7019 std::unique_ptr<DeclIDInFileInfo> &Info = FileDeclIDs[FID];
7020 if (!Info)
7021 Info = std::make_unique<DeclIDInFileInfo>();
7022
7023 std::pair<unsigned, LocalDeclID> LocDecl(Offset, ID);
7024 LocDeclIDsTy &Decls = Info->DeclIDs;
7025 Decls.push_back(LocDecl);
7026}
7027
7030 "expected an anonymous declaration");
7031
7032 // Number the anonymous declarations within this context, if we've not
7033 // already done so.
7034 auto It = AnonymousDeclarationNumbers.find(D);
7035 if (It == AnonymousDeclarationNumbers.end()) {
7036 auto *DC = D->getLexicalDeclContext();
7037 numberAnonymousDeclsWithin(DC, [&](const NamedDecl *ND, unsigned Number) {
7038 AnonymousDeclarationNumbers[ND] = Number;
7039 });
7040
7041 It = AnonymousDeclarationNumbers.find(D);
7042 assert(It != AnonymousDeclarationNumbers.end() &&
7043 "declaration not found within its lexical context");
7044 }
7045
7046 return It->second;
7047}
7048
7075
7077 const DeclarationNameInfo &NameInfo) {
7078 AddDeclarationName(NameInfo.getName());
7079 AddSourceLocation(NameInfo.getLoc());
7080 AddDeclarationNameLoc(NameInfo.getInfo(), NameInfo.getName());
7081}
7082
7085 Record->push_back(Info.NumTemplParamLists);
7086 for (unsigned i = 0, e = Info.NumTemplParamLists; i != e; ++i)
7088}
7089
7091 NestedNameSpecifierLoc QualifierLoc) {
7092 // Nested name specifiers usually aren't too long. I think that 8 would
7093 // typically accommodate the vast majority.
7095
7096 // Push each of the nested-name-specifiers's onto a stack for
7097 // serialization in reverse order.
7098 while (QualifierLoc) {
7099 NestedNames.push_back(QualifierLoc);
7100 QualifierLoc = QualifierLoc.getAsNamespaceAndPrefix().Prefix;
7101 }
7102
7103 Record->push_back(NestedNames.size());
7104 while(!NestedNames.empty()) {
7105 QualifierLoc = NestedNames.pop_back_val();
7106 NestedNameSpecifier Qualifier = QualifierLoc.getNestedNameSpecifier();
7107 NestedNameSpecifier::Kind Kind = Qualifier.getKind();
7108 Record->push_back(llvm::to_underlying(Kind));
7109 switch (Kind) {
7111 AddDeclRef(Qualifier.getAsNamespaceAndPrefix().Namespace);
7112 AddSourceRange(QualifierLoc.getLocalSourceRange());
7113 break;
7114
7116 TypeLoc TL = QualifierLoc.castAsTypeLoc();
7117 AddTypeRef(TL.getType());
7118 AddTypeLoc(TL);
7120 break;
7121 }
7122
7125 break;
7126
7128 AddDeclRef(Qualifier.getAsMicrosoftSuper());
7129 AddSourceRange(QualifierLoc.getLocalSourceRange());
7130 break;
7131
7133 llvm_unreachable("unexpected null nested name specifier");
7134 }
7135 }
7136}
7137
7139 const TemplateParameterList *TemplateParams) {
7140 assert(TemplateParams && "No TemplateParams!");
7141 AddSourceLocation(TemplateParams->getTemplateLoc());
7142 AddSourceLocation(TemplateParams->getLAngleLoc());
7143 AddSourceLocation(TemplateParams->getRAngleLoc());
7144
7145 Record->push_back(TemplateParams->size());
7146 for (const auto &P : *TemplateParams)
7147 AddDeclRef(P);
7148 if (const Expr *RequiresClause = TemplateParams->getRequiresClause()) {
7149 Record->push_back(true);
7150 writeStmtRef(RequiresClause);
7151 } else {
7152 Record->push_back(false);
7153 }
7154}
7155
7156/// Emit a template argument list.
7158 const TemplateArgumentList *TemplateArgs) {
7159 assert(TemplateArgs && "No TemplateArgs!");
7160 Record->push_back(TemplateArgs->size());
7161 for (int i = 0, e = TemplateArgs->size(); i != e; ++i)
7162 AddTemplateArgument(TemplateArgs->get(i));
7163}
7164
7166 const ASTTemplateArgumentListInfo *ASTTemplArgList) {
7167 assert(ASTTemplArgList && "No ASTTemplArgList!");
7168 AddSourceLocation(ASTTemplArgList->LAngleLoc);
7169 AddSourceLocation(ASTTemplArgList->RAngleLoc);
7170 Record->push_back(ASTTemplArgList->NumTemplateArgs);
7171 const TemplateArgumentLoc *TemplArgs = ASTTemplArgList->getTemplateArgs();
7172 for (int i = 0, e = ASTTemplArgList->NumTemplateArgs; i != e; ++i)
7173 AddTemplateArgumentLoc(TemplArgs[i]);
7174}
7175
7177 Record->push_back(Set.size());
7179 I = Set.begin(), E = Set.end(); I != E; ++I) {
7180 AddDeclRef(I.getDecl());
7181 Record->push_back(I.getAccess());
7182 }
7183}
7184
7185// FIXME: Move this out of the main ASTRecordWriter interface.
7187 Record->push_back(Base.isVirtual());
7188 Record->push_back(Base.isBaseOfClass());
7189 Record->push_back(Base.getAccessSpecifierAsWritten());
7190 Record->push_back(Base.getInheritConstructors());
7191 AddTypeSourceInfo(Base.getTypeSourceInfo());
7192 AddSourceRange(Base.getSourceRange());
7193 AddSourceLocation(Base.isPackExpansion()? Base.getEllipsisLoc()
7194 : SourceLocation());
7195}
7196
7197static uint64_t EmitCXXBaseSpecifiers(ASTContext &Context, ASTWriter &W,
7200 ASTRecordWriter Writer(Context, W, Record);
7201 Writer.push_back(Bases.size());
7202
7203 for (auto &Base : Bases)
7204 Writer.AddCXXBaseSpecifier(Base);
7205
7207}
7208
7209// FIXME: Move this out of the main ASTRecordWriter interface.
7213
7214static uint64_t
7218 ASTRecordWriter Writer(Context, W, Record);
7219 Writer.push_back(CtorInits.size());
7220
7221 for (auto *Init : CtorInits) {
7222 if (Init->isBaseInitializer()) {
7224 Writer.AddTypeSourceInfo(Init->getTypeSourceInfo());
7225 Writer.push_back(Init->isBaseVirtual());
7226 } else if (Init->isDelegatingInitializer()) {
7228 Writer.AddTypeSourceInfo(Init->getTypeSourceInfo());
7229 } else if (Init->isMemberInitializer()){
7231 Writer.AddDeclRef(Init->getMember());
7232 } else {
7234 Writer.AddDeclRef(Init->getIndirectMember());
7235 }
7236
7237 Writer.AddSourceLocation(Init->getMemberLocation());
7238 Writer.AddStmt(Init->getInit());
7239 Writer.AddSourceLocation(Init->getLParenLoc());
7240 Writer.AddSourceLocation(Init->getRParenLoc());
7241 Writer.push_back(Init->isWritten());
7242 if (Init->isWritten())
7243 Writer.push_back(Init->getSourceOrder());
7244 }
7245
7247}
7248
7249// FIXME: Move this out of the main ASTRecordWriter interface.
7252 AddOffset(EmitCXXCtorInitializers(getASTContext(), *Writer, CtorInits));
7253}
7254
7256 auto &Data = D->data();
7257
7258 Record->push_back(Data.IsLambda);
7259
7260 BitsPacker DefinitionBits;
7261
7262#define FIELD(Name, Width, Merge) \
7263 if (!DefinitionBits.canWriteNextNBits(Width)) { \
7264 Record->push_back(DefinitionBits); \
7265 DefinitionBits.reset(0); \
7266 } \
7267 DefinitionBits.addBits(Data.Name, Width);
7268
7269#include "clang/AST/CXXRecordDeclDefinitionBits.def"
7270#undef FIELD
7271
7272 Record->push_back(DefinitionBits);
7273
7274 // getODRHash will compute the ODRHash if it has not been previously
7275 // computed.
7276 Record->push_back(D->getODRHash());
7277
7278 bool ModulesCodegen =
7279 !D->isDependentType() &&
7282 (Writer->getLangOpts().ModulesDebugInfo || D->isInNamedModule());
7283 Record->push_back(ModulesCodegen);
7284 if (ModulesCodegen)
7285 Writer->AddDeclRef(D, Writer->ModularCodegenDecls);
7286
7287 // IsLambda bit is already saved.
7288
7289 AddUnresolvedSet(Data.Conversions.get(getASTContext()));
7290 Record->push_back(Data.ComputedVisibleConversions);
7291 if (Data.ComputedVisibleConversions)
7292 AddUnresolvedSet(Data.VisibleConversions.get(getASTContext()));
7293 // Data.Definition is the owning decl, no need to write it.
7294
7295 if (!Data.IsLambda) {
7296 Record->push_back(Data.NumBases);
7297 if (Data.NumBases > 0)
7298 AddCXXBaseSpecifiers(Data.bases());
7299
7300 // FIXME: Make VBases lazily computed when needed to avoid storing them.
7301 Record->push_back(Data.NumVBases);
7302 if (Data.NumVBases > 0)
7303 AddCXXBaseSpecifiers(Data.vbases());
7304
7305 AddDeclRef(D->getFirstFriend());
7306 } else {
7307 auto &Lambda = D->getLambdaData();
7308
7309 BitsPacker LambdaBits;
7310 LambdaBits.addBits(Lambda.DependencyKind, /*Width=*/2);
7311 LambdaBits.addBit(Lambda.IsGenericLambda);
7312 LambdaBits.addBits(Lambda.CaptureDefault, /*Width=*/2);
7313 LambdaBits.addBits(Lambda.NumCaptures, /*Width=*/15);
7314 LambdaBits.addBit(Lambda.HasKnownInternalLinkage);
7315 Record->push_back(LambdaBits);
7316
7317 Record->push_back(Lambda.NumExplicitCaptures);
7318 Record->push_back(Lambda.ManglingNumber);
7319 Record->push_back(D->getDeviceLambdaManglingNumber());
7320 // The lambda context declaration and index within the context are provided
7321 // separately, so that they can be used for merging.
7322 AddTypeSourceInfo(Lambda.MethodTyInfo);
7323 for (unsigned I = 0, N = Lambda.NumCaptures; I != N; ++I) {
7324 const LambdaCapture &Capture = Lambda.Captures.front()[I];
7326
7327 BitsPacker CaptureBits;
7328 CaptureBits.addBit(Capture.isImplicit());
7329 CaptureBits.addBits(Capture.getCaptureKind(), /*Width=*/3);
7330 Record->push_back(CaptureBits);
7331
7332 switch (Capture.getCaptureKind()) {
7333 case LCK_StarThis:
7334 case LCK_This:
7335 case LCK_VLAType:
7336 break;
7337 case LCK_ByCopy:
7338 case LCK_ByRef:
7339 ValueDecl *Var =
7340 Capture.capturesVariable() ? Capture.getCapturedVar() : nullptr;
7341 AddDeclRef(Var);
7342 AddSourceLocation(Capture.isPackExpansion() ? Capture.getEllipsisLoc()
7343 : SourceLocation());
7344 break;
7345 }
7346 }
7347 }
7348}
7349
7351 const Expr *Init = VD->getInit();
7352 if (!Init) {
7353 push_back(0);
7354 return;
7355 }
7356
7357 uint64_t Val = 1;
7358 if (EvaluatedStmt *ES = VD->getEvaluatedStmt()) {
7359 // This may trigger evaluation, so run it first
7360 if (VD->hasInitWithSideEffects())
7361 Val |= 16;
7362 assert(ES->CheckedForSideEffects);
7363 Val |= (ES->HasConstantInitialization ? 2 : 0);
7364 Val |= (ES->HasConstantDestruction ? 4 : 0);
7366 // If the evaluated result is constant, emit it.
7367 if (Evaluated && (Evaluated->isInt() || Evaluated->isFloat()))
7368 Val |= 8;
7369 }
7370 push_back(Val);
7371 if (Val & 8) {
7373 }
7374
7376}
7377
7378void ASTWriter::ReaderInitialized(ASTReader *Reader) {
7379 assert(Reader && "Cannot remove chain");
7380 assert((!Chain || Chain == Reader) && "Cannot replace chain");
7381 assert(FirstDeclID == NextDeclID &&
7382 FirstTypeID == NextTypeID &&
7383 FirstIdentID == NextIdentID &&
7384 FirstMacroID == NextMacroID &&
7385 FirstSubmoduleID == NextSubmoduleID &&
7386 FirstSelectorID == NextSelectorID &&
7387 "Setting chain after writing has started.");
7388
7389 Chain = Reader;
7390
7391 FirstSubmoduleID = NUM_PREDEF_SUBMODULE_IDS + Chain->getTotalNumSubmodules();
7392 FirstSelectorID = NUM_PREDEF_SELECTOR_IDS + Chain->getTotalNumSelectors();
7393 NextSelectorID = FirstSelectorID;
7394 NextSubmoduleID = FirstSubmoduleID;
7395}
7396
7397void ASTWriter::IdentifierRead(IdentifierID ID, IdentifierInfo *II) {
7398 // Don't reuse Type ID from external modules for named modules. See the
7399 // comments in WriteASTCore for details.
7401 return;
7402
7403 IdentifierID &StoredID = IdentifierIDs[II];
7404 unsigned OriginalModuleFileIndex = StoredID >> 32;
7405
7406 // Always keep the local identifier ID. See \p TypeRead() for more
7407 // information.
7408 if (OriginalModuleFileIndex == 0 && StoredID)
7409 return;
7410
7411 // Otherwise, keep the highest ID since the module file comes later has
7412 // higher module file indexes.
7413 if (ID > StoredID)
7414 StoredID = ID;
7415}
7416
7417void ASTWriter::MacroRead(serialization::MacroID ID, MacroInfo *MI) {
7418 // Always keep the highest ID. See \p TypeRead() for more information.
7419 MacroID &StoredID = MacroIDs[MI];
7420 unsigned OriginalModuleFileIndex = StoredID >> 32;
7421
7422 // Always keep the local macro ID. See \p TypeRead() for more information.
7423 if (OriginalModuleFileIndex == 0 && StoredID)
7424 return;
7425
7426 // Otherwise, keep the highest ID since the module file comes later has
7427 // higher module file indexes.
7428 if (ID > StoredID)
7429 StoredID = ID;
7430}
7431
7432void ASTWriter::TypeRead(TypeIdx Idx, QualType T) {
7433 // Don't reuse Type ID from external modules for named modules. See the
7434 // comments in WriteASTCore for details.
7436 return;
7437
7438 // Always take the type index that comes in later module files.
7439 // This copes with an interesting
7440 // case for chained AST writing where we schedule writing the type and then,
7441 // later, deserialize the type from another AST. In this case, we want to
7442 // keep the entry from a later module so that we can properly write it out to
7443 // the AST file.
7444 TypeIdx &StoredIdx = TypeIdxs[T];
7445
7446 // Ignore it if the type comes from the current being written module file.
7447 // Since the current module file being written logically has the highest
7448 // index.
7449 unsigned ModuleFileIndex = StoredIdx.getModuleFileIndex();
7450 if (ModuleFileIndex == 0 && StoredIdx.getValue())
7451 return;
7452
7453 // Otherwise, keep the highest ID since the module file comes later has
7454 // higher module file indexes.
7455 if (Idx.getModuleFileIndex() >= StoredIdx.getModuleFileIndex())
7456 StoredIdx = Idx;
7457}
7458
7459void ASTWriter::PredefinedDeclBuilt(PredefinedDeclIDs ID, const Decl *D) {
7460 assert(D->isCanonicalDecl() && "predefined decl is not canonical");
7461 DeclIDs[D] = LocalDeclID(ID);
7462 PredefinedDecls.insert(D);
7463}
7464
7465void ASTWriter::SelectorRead(SelectorID ID, Selector S) {
7466 // Always keep the highest ID. See \p TypeRead() for more information.
7467 SelectorID &StoredID = SelectorIDs[S];
7468 if (ID > StoredID)
7469 StoredID = ID;
7470}
7471
7472void ASTWriter::MacroDefinitionRead(serialization::PreprocessedEntityID ID,
7474 assert(!MacroDefinitions.contains(MD));
7475 MacroDefinitions[MD] = ID;
7476}
7477
7478void ASTWriter::ModuleRead(serialization::SubmoduleID ID, Module *Mod) {
7479 assert(!SubmoduleIDs.contains(Mod));
7480 SubmoduleIDs[Mod] = ID;
7481}
7482
7483void ASTWriter::CompletedTagDefinition(const TagDecl *D) {
7484 if (Chain && Chain->isProcessingUpdateRecords()) return;
7485 assert(D->isCompleteDefinition());
7486 assert(!WritingAST && "Already writing the AST!");
7487 if (auto *RD = dyn_cast<CXXRecordDecl>(D)) {
7488 // We are interested when a PCH decl is modified.
7489 if (RD->isFromASTFile()) {
7490 // A forward reference was mutated into a definition. Rewrite it.
7491 // FIXME: This happens during template instantiation, should we
7492 // have created a new definition decl instead ?
7493 assert(isTemplateInstantiation(RD->getTemplateSpecializationKind()) &&
7494 "completed a tag from another module but not by instantiation?");
7495 DeclUpdates[RD].push_back(
7496 DeclUpdate(DeclUpdateKind::CXXInstantiatedClassDefinition));
7497 }
7498 }
7499}
7500
7501static bool isImportedDeclContext(ASTReader *Chain, const Decl *D) {
7502 if (D->isFromASTFile())
7503 return true;
7504
7505 // The predefined __va_list_tag struct is imported if we imported any decls.
7506 // FIXME: This is a gross hack.
7507 return D == D->getASTContext().getVaListTagDecl();
7508}
7509
7510void ASTWriter::AddedVisibleDecl(const DeclContext *DC, const Decl *D) {
7511 if (Chain && Chain->isProcessingUpdateRecords()) return;
7512 assert(DC->isLookupContext() &&
7513 "Should not add lookup results to non-lookup contexts!");
7514
7515 // TU is handled elsewhere.
7517 return;
7518
7519 // Namespaces are handled elsewhere, except for template instantiations of
7520 // FunctionTemplateDecls in namespaces. We are interested in cases where the
7521 // local instantiations are added to an imported context. Only happens when
7522 // adding ADL lookup candidates, for example templated friends.
7525 return;
7526
7527 // We're only interested in cases where a local declaration is added to an
7528 // imported context.
7529 if (D->isFromASTFile() || !isImportedDeclContext(Chain, cast<Decl>(DC)))
7530 return;
7531
7532 assert(DC == DC->getPrimaryContext() && "added to non-primary context");
7533 assert(!getDefinitiveDeclContext(DC) && "DeclContext not definitive!");
7534 assert(!WritingAST && "Already writing the AST!");
7535 if (UpdatedDeclContexts.insert(DC) && !cast<Decl>(DC)->isFromASTFile()) {
7536 // We're adding a visible declaration to a predefined decl context. Ensure
7537 // that we write out all of its lookup results so we don't get a nasty
7538 // surprise when we try to emit its lookup table.
7539 llvm::append_range(DeclsToEmitEvenIfUnreferenced, DC->decls());
7540 }
7541 DeclsToEmitEvenIfUnreferenced.push_back(D);
7542}
7543
7544void ASTWriter::AddedCXXImplicitMember(const CXXRecordDecl *RD, const Decl *D) {
7545 if (Chain && Chain->isProcessingUpdateRecords()) return;
7546 assert(D->isImplicit());
7547
7548 // We're only interested in cases where a local declaration is added to an
7549 // imported context.
7550 if (D->isFromASTFile() || !isImportedDeclContext(Chain, RD))
7551 return;
7552
7553 if (!isa<CXXMethodDecl>(D))
7554 return;
7555
7556 // A decl coming from PCH was modified.
7557 assert(RD->isCompleteDefinition());
7558 assert(!WritingAST && "Already writing the AST!");
7559 DeclUpdates[RD].push_back(
7560 DeclUpdate(DeclUpdateKind::CXXAddedImplicitMember, D));
7561}
7562
7563void ASTWriter::ResolvedExceptionSpec(const FunctionDecl *FD) {
7564 if (Chain && Chain->isProcessingUpdateRecords()) return;
7565 assert(!DoneWritingDeclsAndTypes && "Already done writing updates!");
7566 if (!Chain) return;
7567 Chain->forEachImportedKeyDecl(FD, [&](const Decl *D) {
7568 // If we don't already know the exception specification for this redecl
7569 // chain, add an update record for it.
7571 ->getType()
7572 ->castAs<FunctionProtoType>()
7573 ->getExceptionSpecType()))
7574 DeclUpdates[D].push_back(DeclUpdateKind::CXXResolvedExceptionSpec);
7575 });
7576}
7577
7578void ASTWriter::DeducedReturnType(const FunctionDecl *FD, QualType ReturnType) {
7579 if (Chain && Chain->isProcessingUpdateRecords()) return;
7580 assert(!WritingAST && "Already writing the AST!");
7581 if (!Chain) return;
7582 Chain->forEachImportedKeyDecl(FD, [&](const Decl *D) {
7583 DeclUpdates[D].push_back(
7584 DeclUpdate(DeclUpdateKind::CXXDeducedReturnType, ReturnType));
7585 });
7586}
7587
7588void ASTWriter::ResolvedOperatorDelete(const CXXDestructorDecl *DD,
7589 const FunctionDecl *Delete,
7590 Expr *ThisArg) {
7591 if (Chain && Chain->isProcessingUpdateRecords()) return;
7592 assert(!WritingAST && "Already writing the AST!");
7593 assert(Delete && "Not given an operator delete");
7594 if (!Chain) return;
7595 Chain->forEachImportedKeyDecl(DD, [&](const Decl *D) {
7596 DeclUpdates[D].push_back(
7597 DeclUpdate(DeclUpdateKind::CXXResolvedDtorDelete, Delete));
7598 });
7599}
7600
7601void ASTWriter::ResolvedOperatorGlobDelete(const CXXDestructorDecl *DD,
7602 const FunctionDecl *GlobDelete) {
7603 if (Chain && Chain->isProcessingUpdateRecords())
7604 return;
7605 assert(!WritingAST && "Already writing the AST!");
7606 assert(GlobDelete && "Not given an operator delete");
7607 if (!Chain)
7608 return;
7609 Chain->forEachImportedKeyDecl(DD, [&](const Decl *D) {
7610 DeclUpdates[D].push_back(
7611 DeclUpdate(DeclUpdateKind::CXXResolvedDtorGlobDelete, GlobDelete));
7612 });
7613}
7614
7615void ASTWriter::ResolvedOperatorArrayDelete(const CXXDestructorDecl *DD,
7616 const FunctionDecl *ArrayDelete) {
7617 if (Chain && Chain->isProcessingUpdateRecords())
7618 return;
7619 assert(!WritingAST && "Already writing the AST!");
7620 assert(ArrayDelete && "Not given an operator delete");
7621 if (!Chain)
7622 return;
7623 Chain->forEachImportedKeyDecl(DD, [&](const Decl *D) {
7624 DeclUpdates[D].push_back(
7625 DeclUpdate(DeclUpdateKind::CXXResolvedDtorArrayDelete, ArrayDelete));
7626 });
7627}
7628
7629void ASTWriter::ResolvedOperatorGlobArrayDelete(
7630 const CXXDestructorDecl *DD, const FunctionDecl *GlobArrayDelete) {
7631 if (Chain && Chain->isProcessingUpdateRecords())
7632 return;
7633 assert(!WritingAST && "Already writing the AST!");
7634 assert(GlobArrayDelete && "Not given an operator delete");
7635 if (!Chain)
7636 return;
7637 Chain->forEachImportedKeyDecl(DD, [&](const Decl *D) {
7638 DeclUpdates[D].push_back(DeclUpdate(
7639 DeclUpdateKind::CXXResolvedDtorGlobArrayDelete, GlobArrayDelete));
7640 });
7641}
7642
7643void ASTWriter::CompletedImplicitDefinition(const FunctionDecl *D) {
7644 if (Chain && Chain->isProcessingUpdateRecords()) return;
7645 assert(!WritingAST && "Already writing the AST!");
7646 if (!D->isFromASTFile())
7647 return; // Declaration not imported from PCH.
7648
7649 // The function definition may not have a body due to parsing errors.
7651 return;
7652
7653 // Implicit function decl from a PCH was defined.
7654 DeclUpdates[D].push_back(
7655 DeclUpdate(DeclUpdateKind::CXXAddedFunctionDefinition));
7656}
7657
7658void ASTWriter::VariableDefinitionInstantiated(const VarDecl *D) {
7659 if (Chain && Chain->isProcessingUpdateRecords()) return;
7660 assert(!WritingAST && "Already writing the AST!");
7661 if (!D->isFromASTFile())
7662 return;
7663
7664 DeclUpdates[D].push_back(DeclUpdate(DeclUpdateKind::CXXAddedVarDefinition));
7665}
7666
7667void ASTWriter::FunctionDefinitionInstantiated(const FunctionDecl *D) {
7668 if (Chain && Chain->isProcessingUpdateRecords()) return;
7669 assert(!WritingAST && "Already writing the AST!");
7670 if (!D->isFromASTFile())
7671 return;
7672
7673 // The function definition may not have a body due to parsing errors.
7675 return;
7676
7677 DeclUpdates[D].push_back(
7678 DeclUpdate(DeclUpdateKind::CXXAddedFunctionDefinition));
7679}
7680
7681void ASTWriter::InstantiationRequested(const ValueDecl *D) {
7682 if (Chain && Chain->isProcessingUpdateRecords()) return;
7683 assert(!WritingAST && "Already writing the AST!");
7684 if (!D->isFromASTFile())
7685 return;
7686
7687 // Since the actual instantiation is delayed, this really means that we need
7688 // to update the instantiation location.
7689 SourceLocation POI;
7690 if (auto *VD = dyn_cast<VarDecl>(D))
7691 POI = VD->getPointOfInstantiation();
7692 else
7693 POI = cast<FunctionDecl>(D)->getPointOfInstantiation();
7694 DeclUpdates[D].push_back(
7695 DeclUpdate(DeclUpdateKind::CXXPointOfInstantiation, POI));
7696}
7697
7698void ASTWriter::DefaultArgumentInstantiated(const ParmVarDecl *D) {
7699 if (Chain && Chain->isProcessingUpdateRecords()) return;
7700 assert(!WritingAST && "Already writing the AST!");
7701 if (!D->isFromASTFile())
7702 return;
7703
7704 DeclUpdates[D].push_back(
7705 DeclUpdate(DeclUpdateKind::CXXInstantiatedDefaultArgument, D));
7706}
7707
7708void ASTWriter::DefaultMemberInitializerInstantiated(const FieldDecl *D) {
7709 assert(!WritingAST && "Already writing the AST!");
7710 if (!D->isFromASTFile())
7711 return;
7712
7713 DeclUpdates[D].push_back(
7714 DeclUpdate(DeclUpdateKind::CXXInstantiatedDefaultMemberInitializer, D));
7715}
7716
7717void ASTWriter::AddedObjCCategoryToInterface(const ObjCCategoryDecl *CatD,
7718 const ObjCInterfaceDecl *IFD) {
7719 if (Chain && Chain->isProcessingUpdateRecords()) return;
7720 assert(!WritingAST && "Already writing the AST!");
7721 if (!IFD->isFromASTFile())
7722 return; // Declaration not imported from PCH.
7723
7724 assert(IFD->getDefinition() && "Category on a class without a definition?");
7725 ObjCClassesWithCategories.insert(
7726 const_cast<ObjCInterfaceDecl *>(IFD->getDefinition()));
7727}
7728
7729void ASTWriter::DeclarationMarkedUsed(const Decl *D) {
7730 if (Chain && Chain->isProcessingUpdateRecords()) return;
7731 assert(!WritingAST && "Already writing the AST!");
7732
7733 // If there is *any* declaration of the entity that's not from an AST file,
7734 // we can skip writing the update record. We make sure that isUsed() triggers
7735 // completion of the redeclaration chain of the entity.
7736 for (auto Prev = D->getMostRecentDecl(); Prev; Prev = Prev->getPreviousDecl())
7737 if (IsLocalDecl(Prev))
7738 return;
7739
7740 DeclUpdates[D].push_back(DeclUpdate(DeclUpdateKind::DeclMarkedUsed));
7741}
7742
7743void ASTWriter::DeclarationMarkedOpenMPThreadPrivate(const Decl *D) {
7744 if (Chain && Chain->isProcessingUpdateRecords()) return;
7745 assert(!WritingAST && "Already writing the AST!");
7746 if (!D->isFromASTFile())
7747 return;
7748
7749 DeclUpdates[D].push_back(
7750 DeclUpdate(DeclUpdateKind::DeclMarkedOpenMPThreadPrivate));
7751}
7752
7753void ASTWriter::DeclarationMarkedOpenMPAllocate(const Decl *D, const Attr *A) {
7754 if (Chain && Chain->isProcessingUpdateRecords()) return;
7755 assert(!WritingAST && "Already writing the AST!");
7756 if (!D->isFromASTFile())
7757 return;
7758
7759 DeclUpdates[D].push_back(
7760 DeclUpdate(DeclUpdateKind::DeclMarkedOpenMPAllocate, A));
7761}
7762
7763void ASTWriter::DeclarationMarkedOpenMPDeclareTarget(const Decl *D,
7764 const Attr *Attr) {
7765 if (Chain && Chain->isProcessingUpdateRecords()) return;
7766 assert(!WritingAST && "Already writing the AST!");
7767 if (!D->isFromASTFile())
7768 return;
7769
7770 DeclUpdates[D].push_back(
7771 DeclUpdate(DeclUpdateKind::DeclMarkedOpenMPDeclareTarget, Attr));
7772}
7773
7774void ASTWriter::RedefinedHiddenDefinition(const NamedDecl *D, Module *M) {
7775 if (Chain && Chain->isProcessingUpdateRecords()) return;
7776 assert(!WritingAST && "Already writing the AST!");
7777 assert(!D->isUnconditionallyVisible() && "expected a hidden declaration");
7778 DeclUpdates[D].push_back(DeclUpdate(DeclUpdateKind::DeclExported, M));
7779}
7780
7781void ASTWriter::AddedAttributeToRecord(const Attr *Attr,
7782 const RecordDecl *Record) {
7783 if (Chain && Chain->isProcessingUpdateRecords()) return;
7784 assert(!WritingAST && "Already writing the AST!");
7785 if (!Record->isFromASTFile())
7786 return;
7787 DeclUpdates[Record].push_back(
7788 DeclUpdate(DeclUpdateKind::AddedAttrToRecord, Attr));
7789}
7790
7791void ASTWriter::AddedCXXTemplateSpecialization(
7793 assert(!WritingAST && "Already writing the AST!");
7794
7795 if (!TD->getFirstDecl()->isFromASTFile())
7796 return;
7797 if (Chain && Chain->isProcessingUpdateRecords())
7798 return;
7799
7800 DeclsToEmitEvenIfUnreferenced.push_back(D);
7801}
7802
7803void ASTWriter::AddedCXXTemplateSpecialization(
7804 const VarTemplateDecl *TD, const VarTemplateSpecializationDecl *D) {
7805 assert(!WritingAST && "Already writing the AST!");
7806
7807 if (!TD->getFirstDecl()->isFromASTFile())
7808 return;
7809 if (Chain && Chain->isProcessingUpdateRecords())
7810 return;
7811
7812 DeclsToEmitEvenIfUnreferenced.push_back(D);
7813}
7814
7815void ASTWriter::AddedCXXTemplateSpecialization(const FunctionTemplateDecl *TD,
7816 const FunctionDecl *D) {
7817 assert(!WritingAST && "Already writing the AST!");
7818
7819 if (!TD->getFirstDecl()->isFromASTFile())
7820 return;
7821 if (Chain && Chain->isProcessingUpdateRecords())
7822 return;
7823
7824 DeclsToEmitEvenIfUnreferenced.push_back(D);
7825}
7826
7827//===----------------------------------------------------------------------===//
7828//// OMPClause Serialization
7829////===----------------------------------------------------------------------===//
7830
7831namespace {
7832
7833class OMPClauseWriter : public OMPClauseVisitor<OMPClauseWriter> {
7834 ASTRecordWriter &Record;
7835
7836public:
7837 OMPClauseWriter(ASTRecordWriter &Record) : Record(Record) {}
7838#define GEN_CLANG_CLAUSE_CLASS
7839#define CLAUSE_CLASS(Enum, Str, Class) void Visit##Class(Class *S);
7840#include "llvm/Frontend/OpenMP/OMP.inc"
7841 void writeClause(OMPClause *C);
7842 void VisitOMPClauseWithPreInit(OMPClauseWithPreInit *C);
7843 void VisitOMPClauseWithPostUpdate(OMPClauseWithPostUpdate *C);
7844};
7845
7846}
7847
7849 OMPClauseWriter(*this).writeClause(C);
7850}
7851
7852void OMPClauseWriter::writeClause(OMPClause *C) {
7853 Record.push_back(unsigned(C->getClauseKind()));
7854 Visit(C);
7855 Record.AddSourceLocation(C->getBeginLoc());
7856 Record.AddSourceLocation(C->getEndLoc());
7857}
7858
7859void OMPClauseWriter::VisitOMPClauseWithPreInit(OMPClauseWithPreInit *C) {
7860 Record.push_back(uint64_t(C->getCaptureRegion()));
7861 Record.AddStmt(C->getPreInitStmt());
7862}
7863
7864void OMPClauseWriter::VisitOMPClauseWithPostUpdate(OMPClauseWithPostUpdate *C) {
7865 VisitOMPClauseWithPreInit(C);
7866 Record.AddStmt(C->getPostUpdateExpr());
7867}
7868
7869void OMPClauseWriter::VisitOMPIfClause(OMPIfClause *C) {
7870 VisitOMPClauseWithPreInit(C);
7871 Record.push_back(uint64_t(C->getNameModifier()));
7872 Record.AddSourceLocation(C->getNameModifierLoc());
7873 Record.AddSourceLocation(C->getColonLoc());
7874 Record.AddStmt(C->getCondition());
7875 Record.AddSourceLocation(C->getLParenLoc());
7876}
7877
7878void OMPClauseWriter::VisitOMPFinalClause(OMPFinalClause *C) {
7879 VisitOMPClauseWithPreInit(C);
7880 Record.AddStmt(C->getCondition());
7881 Record.AddSourceLocation(C->getLParenLoc());
7882}
7883
7884void OMPClauseWriter::VisitOMPNumThreadsClause(OMPNumThreadsClause *C) {
7885 VisitOMPClauseWithPreInit(C);
7886 Record.writeEnum(C->getModifier());
7887 Record.AddStmt(C->getNumThreads());
7888 Record.AddSourceLocation(C->getModifierLoc());
7889 Record.AddSourceLocation(C->getLParenLoc());
7890}
7891
7892void OMPClauseWriter::VisitOMPSafelenClause(OMPSafelenClause *C) {
7893 Record.AddStmt(C->getSafelen());
7894 Record.AddSourceLocation(C->getLParenLoc());
7895}
7896
7897void OMPClauseWriter::VisitOMPSimdlenClause(OMPSimdlenClause *C) {
7898 Record.AddStmt(C->getSimdlen());
7899 Record.AddSourceLocation(C->getLParenLoc());
7900}
7901
7902void OMPClauseWriter::VisitOMPSizesClause(OMPSizesClause *C) {
7903 Record.push_back(C->getNumSizes());
7904 for (Expr *Size : C->getSizesRefs())
7905 Record.AddStmt(Size);
7906 Record.AddSourceLocation(C->getLParenLoc());
7907}
7908
7909void OMPClauseWriter::VisitOMPPermutationClause(OMPPermutationClause *C) {
7910 Record.push_back(C->getNumLoops());
7911 for (Expr *Size : C->getArgsRefs())
7912 Record.AddStmt(Size);
7913 Record.AddSourceLocation(C->getLParenLoc());
7914}
7915
7916void OMPClauseWriter::VisitOMPFullClause(OMPFullClause *C) {}
7917
7918void OMPClauseWriter::VisitOMPPartialClause(OMPPartialClause *C) {
7919 Record.AddStmt(C->getFactor());
7920 Record.AddSourceLocation(C->getLParenLoc());
7921}
7922
7923void OMPClauseWriter::VisitOMPLoopRangeClause(OMPLoopRangeClause *C) {
7924 Record.AddStmt(C->getFirst());
7925 Record.AddStmt(C->getCount());
7926 Record.AddSourceLocation(C->getLParenLoc());
7927 Record.AddSourceLocation(C->getFirstLoc());
7928 Record.AddSourceLocation(C->getCountLoc());
7929}
7930
7931void OMPClauseWriter::VisitOMPAllocatorClause(OMPAllocatorClause *C) {
7932 Record.AddStmt(C->getAllocator());
7933 Record.AddSourceLocation(C->getLParenLoc());
7934}
7935
7936void OMPClauseWriter::VisitOMPCollapseClause(OMPCollapseClause *C) {
7937 Record.AddStmt(C->getNumForLoops());
7938 Record.AddSourceLocation(C->getLParenLoc());
7939}
7940
7941void OMPClauseWriter::VisitOMPDetachClause(OMPDetachClause *C) {
7942 Record.AddStmt(C->getEventHandler());
7943 Record.AddSourceLocation(C->getLParenLoc());
7944}
7945
7946void OMPClauseWriter::VisitOMPDefaultClause(OMPDefaultClause *C) {
7947 Record.push_back(unsigned(C->getDefaultKind()));
7948 Record.AddSourceLocation(C->getLParenLoc());
7949 Record.AddSourceLocation(C->getDefaultKindKwLoc());
7950 Record.push_back(unsigned(C->getDefaultVC()));
7951 Record.AddSourceLocation(C->getDefaultVCLoc());
7952}
7953
7954void OMPClauseWriter::VisitOMPThreadsetClause(OMPThreadsetClause *C) {
7955 Record.AddSourceLocation(C->getLParenLoc());
7956 Record.AddSourceLocation(C->getThreadsetKindLoc());
7957 Record.writeEnum(C->getThreadsetKind());
7958}
7959
7960void OMPClauseWriter::VisitOMPProcBindClause(OMPProcBindClause *C) {
7961 Record.push_back(unsigned(C->getProcBindKind()));
7962 Record.AddSourceLocation(C->getLParenLoc());
7963 Record.AddSourceLocation(C->getProcBindKindKwLoc());
7964}
7965
7966void OMPClauseWriter::VisitOMPScheduleClause(OMPScheduleClause *C) {
7967 VisitOMPClauseWithPreInit(C);
7968 Record.push_back(C->getScheduleKind());
7969 Record.push_back(C->getFirstScheduleModifier());
7970 Record.push_back(C->getSecondScheduleModifier());
7971 Record.AddStmt(C->getChunkSize());
7972 Record.AddSourceLocation(C->getLParenLoc());
7973 Record.AddSourceLocation(C->getFirstScheduleModifierLoc());
7974 Record.AddSourceLocation(C->getSecondScheduleModifierLoc());
7975 Record.AddSourceLocation(C->getScheduleKindLoc());
7976 Record.AddSourceLocation(C->getCommaLoc());
7977}
7978
7979void OMPClauseWriter::VisitOMPOrderedClause(OMPOrderedClause *C) {
7980 Record.push_back(C->getLoopNumIterations().size());
7981 Record.AddStmt(C->getNumForLoops());
7982 for (Expr *NumIter : C->getLoopNumIterations())
7983 Record.AddStmt(NumIter);
7984 for (unsigned I = 0, E = C->getLoopNumIterations().size(); I <E; ++I)
7985 Record.AddStmt(C->getLoopCounter(I));
7986 Record.AddSourceLocation(C->getLParenLoc());
7987}
7988
7989void OMPClauseWriter::VisitOMPNowaitClause(OMPNowaitClause *C) {
7990 Record.AddStmt(C->getCondition());
7991 Record.AddSourceLocation(C->getLParenLoc());
7992}
7993
7994void OMPClauseWriter::VisitOMPUntiedClause(OMPUntiedClause *) {}
7995
7996void OMPClauseWriter::VisitOMPMergeableClause(OMPMergeableClause *) {}
7997
7998void OMPClauseWriter::VisitOMPReadClause(OMPReadClause *) {}
7999
8000void OMPClauseWriter::VisitOMPWriteClause(OMPWriteClause *) {}
8001
8002void OMPClauseWriter::VisitOMPUpdateClause(OMPUpdateClause *C) {
8003 Record.push_back(C->isExtended() ? 1 : 0);
8004 if (C->isExtended()) {
8005 Record.AddSourceLocation(C->getLParenLoc());
8006 Record.AddSourceLocation(C->getArgumentLoc());
8007 Record.writeEnum(C->getDependencyKind());
8008 }
8009}
8010
8011void OMPClauseWriter::VisitOMPCaptureClause(OMPCaptureClause *) {}
8012
8013void OMPClauseWriter::VisitOMPCompareClause(OMPCompareClause *) {}
8014
8015// Save the parameter of fail clause.
8016void OMPClauseWriter::VisitOMPFailClause(OMPFailClause *C) {
8017 Record.AddSourceLocation(C->getLParenLoc());
8018 Record.AddSourceLocation(C->getFailParameterLoc());
8019 Record.writeEnum(C->getFailParameter());
8020}
8021
8022void OMPClauseWriter::VisitOMPSeqCstClause(OMPSeqCstClause *) {}
8023
8024void OMPClauseWriter::VisitOMPAcqRelClause(OMPAcqRelClause *) {}
8025
8026void OMPClauseWriter::VisitOMPAbsentClause(OMPAbsentClause *C) {
8027 Record.push_back(static_cast<uint64_t>(C->getDirectiveKinds().size()));
8028 Record.AddSourceLocation(C->getLParenLoc());
8029 for (auto K : C->getDirectiveKinds()) {
8030 Record.writeEnum(K);
8031 }
8032}
8033
8034void OMPClauseWriter::VisitOMPHoldsClause(OMPHoldsClause *C) {
8035 Record.AddStmt(C->getExpr());
8036 Record.AddSourceLocation(C->getLParenLoc());
8037}
8038
8039void OMPClauseWriter::VisitOMPContainsClause(OMPContainsClause *C) {
8040 Record.push_back(static_cast<uint64_t>(C->getDirectiveKinds().size()));
8041 Record.AddSourceLocation(C->getLParenLoc());
8042 for (auto K : C->getDirectiveKinds()) {
8043 Record.writeEnum(K);
8044 }
8045}
8046
8047void OMPClauseWriter::VisitOMPNoOpenMPClause(OMPNoOpenMPClause *) {}
8048
8049void OMPClauseWriter::VisitOMPNoOpenMPRoutinesClause(
8051
8052void OMPClauseWriter::VisitOMPNoOpenMPConstructsClause(
8054
8055void OMPClauseWriter::VisitOMPNoParallelismClause(OMPNoParallelismClause *) {}
8056
8057void OMPClauseWriter::VisitOMPAcquireClause(OMPAcquireClause *) {}
8058
8059void OMPClauseWriter::VisitOMPReleaseClause(OMPReleaseClause *) {}
8060
8061void OMPClauseWriter::VisitOMPRelaxedClause(OMPRelaxedClause *) {}
8062
8063void OMPClauseWriter::VisitOMPWeakClause(OMPWeakClause *) {}
8064
8065void OMPClauseWriter::VisitOMPThreadsClause(OMPThreadsClause *) {}
8066
8067void OMPClauseWriter::VisitOMPSIMDClause(OMPSIMDClause *) {}
8068
8069void OMPClauseWriter::VisitOMPNogroupClause(OMPNogroupClause *) {}
8070
8071void OMPClauseWriter::VisitOMPInitClause(OMPInitClause *C) {
8072 Record.push_back(C->varlist_size());
8073 for (Expr *VE : C->varlist())
8074 Record.AddStmt(VE);
8075 Record.writeBool(C->getIsTarget());
8076 Record.writeBool(C->getIsTargetSync());
8077 Record.AddSourceLocation(C->getLParenLoc());
8078 Record.AddSourceLocation(C->getVarLoc());
8079}
8080
8081void OMPClauseWriter::VisitOMPUseClause(OMPUseClause *C) {
8082 Record.AddStmt(C->getInteropVar());
8083 Record.AddSourceLocation(C->getLParenLoc());
8084 Record.AddSourceLocation(C->getVarLoc());
8085}
8086
8087void OMPClauseWriter::VisitOMPDestroyClause(OMPDestroyClause *C) {
8088 Record.AddStmt(C->getInteropVar());
8089 Record.AddSourceLocation(C->getLParenLoc());
8090 Record.AddSourceLocation(C->getVarLoc());
8091}
8092
8093void OMPClauseWriter::VisitOMPNovariantsClause(OMPNovariantsClause *C) {
8094 VisitOMPClauseWithPreInit(C);
8095 Record.AddStmt(C->getCondition());
8096 Record.AddSourceLocation(C->getLParenLoc());
8097}
8098
8099void OMPClauseWriter::VisitOMPNocontextClause(OMPNocontextClause *C) {
8100 VisitOMPClauseWithPreInit(C);
8101 Record.AddStmt(C->getCondition());
8102 Record.AddSourceLocation(C->getLParenLoc());
8103}
8104
8105void OMPClauseWriter::VisitOMPFilterClause(OMPFilterClause *C) {
8106 VisitOMPClauseWithPreInit(C);
8107 Record.AddStmt(C->getThreadID());
8108 Record.AddSourceLocation(C->getLParenLoc());
8109}
8110
8111void OMPClauseWriter::VisitOMPAlignClause(OMPAlignClause *C) {
8112 Record.AddStmt(C->getAlignment());
8113 Record.AddSourceLocation(C->getLParenLoc());
8114}
8115
8116void OMPClauseWriter::VisitOMPPrivateClause(OMPPrivateClause *C) {
8117 Record.push_back(C->varlist_size());
8118 Record.AddSourceLocation(C->getLParenLoc());
8119 for (auto *VE : C->varlist()) {
8120 Record.AddStmt(VE);
8121 }
8122 for (auto *VE : C->private_copies()) {
8123 Record.AddStmt(VE);
8124 }
8125}
8126
8127void OMPClauseWriter::VisitOMPFirstprivateClause(OMPFirstprivateClause *C) {
8128 Record.push_back(C->varlist_size());
8129 VisitOMPClauseWithPreInit(C);
8130 Record.AddSourceLocation(C->getLParenLoc());
8131 for (auto *VE : C->varlist()) {
8132 Record.AddStmt(VE);
8133 }
8134 for (auto *VE : C->private_copies()) {
8135 Record.AddStmt(VE);
8136 }
8137 for (auto *VE : C->inits()) {
8138 Record.AddStmt(VE);
8139 }
8140}
8141
8142void OMPClauseWriter::VisitOMPLastprivateClause(OMPLastprivateClause *C) {
8143 Record.push_back(C->varlist_size());
8144 VisitOMPClauseWithPostUpdate(C);
8145 Record.AddSourceLocation(C->getLParenLoc());
8146 Record.writeEnum(C->getKind());
8147 Record.AddSourceLocation(C->getKindLoc());
8148 Record.AddSourceLocation(C->getColonLoc());
8149 for (auto *VE : C->varlist())
8150 Record.AddStmt(VE);
8151 for (auto *E : C->private_copies())
8152 Record.AddStmt(E);
8153 for (auto *E : C->source_exprs())
8154 Record.AddStmt(E);
8155 for (auto *E : C->destination_exprs())
8156 Record.AddStmt(E);
8157 for (auto *E : C->assignment_ops())
8158 Record.AddStmt(E);
8159}
8160
8161void OMPClauseWriter::VisitOMPSharedClause(OMPSharedClause *C) {
8162 Record.push_back(C->varlist_size());
8163 Record.AddSourceLocation(C->getLParenLoc());
8164 for (auto *VE : C->varlist())
8165 Record.AddStmt(VE);
8166}
8167
8168void OMPClauseWriter::VisitOMPReductionClause(OMPReductionClause *C) {
8169 Record.push_back(C->varlist_size());
8170 Record.writeEnum(C->getModifier());
8171 VisitOMPClauseWithPostUpdate(C);
8172 Record.AddSourceLocation(C->getLParenLoc());
8173 Record.AddSourceLocation(C->getModifierLoc());
8174 Record.AddSourceLocation(C->getColonLoc());
8175 Record.AddNestedNameSpecifierLoc(C->getQualifierLoc());
8176 Record.AddDeclarationNameInfo(C->getNameInfo());
8177 for (auto *VE : C->varlist())
8178 Record.AddStmt(VE);
8179 for (auto *VE : C->privates())
8180 Record.AddStmt(VE);
8181 for (auto *E : C->lhs_exprs())
8182 Record.AddStmt(E);
8183 for (auto *E : C->rhs_exprs())
8184 Record.AddStmt(E);
8185 for (auto *E : C->reduction_ops())
8186 Record.AddStmt(E);
8187 if (C->getModifier() == clang::OMPC_REDUCTION_inscan) {
8188 for (auto *E : C->copy_ops())
8189 Record.AddStmt(E);
8190 for (auto *E : C->copy_array_temps())
8191 Record.AddStmt(E);
8192 for (auto *E : C->copy_array_elems())
8193 Record.AddStmt(E);
8194 }
8195 auto PrivateFlags = C->private_var_reduction_flags();
8196 Record.push_back(std::distance(PrivateFlags.begin(), PrivateFlags.end()));
8197 for (bool Flag : PrivateFlags)
8198 Record.push_back(Flag);
8199}
8200
8201void OMPClauseWriter::VisitOMPTaskReductionClause(OMPTaskReductionClause *C) {
8202 Record.push_back(C->varlist_size());
8203 VisitOMPClauseWithPostUpdate(C);
8204 Record.AddSourceLocation(C->getLParenLoc());
8205 Record.AddSourceLocation(C->getColonLoc());
8206 Record.AddNestedNameSpecifierLoc(C->getQualifierLoc());
8207 Record.AddDeclarationNameInfo(C->getNameInfo());
8208 for (auto *VE : C->varlist())
8209 Record.AddStmt(VE);
8210 for (auto *VE : C->privates())
8211 Record.AddStmt(VE);
8212 for (auto *E : C->lhs_exprs())
8213 Record.AddStmt(E);
8214 for (auto *E : C->rhs_exprs())
8215 Record.AddStmt(E);
8216 for (auto *E : C->reduction_ops())
8217 Record.AddStmt(E);
8218}
8219
8220void OMPClauseWriter::VisitOMPInReductionClause(OMPInReductionClause *C) {
8221 Record.push_back(C->varlist_size());
8222 VisitOMPClauseWithPostUpdate(C);
8223 Record.AddSourceLocation(C->getLParenLoc());
8224 Record.AddSourceLocation(C->getColonLoc());
8225 Record.AddNestedNameSpecifierLoc(C->getQualifierLoc());
8226 Record.AddDeclarationNameInfo(C->getNameInfo());
8227 for (auto *VE : C->varlist())
8228 Record.AddStmt(VE);
8229 for (auto *VE : C->privates())
8230 Record.AddStmt(VE);
8231 for (auto *E : C->lhs_exprs())
8232 Record.AddStmt(E);
8233 for (auto *E : C->rhs_exprs())
8234 Record.AddStmt(E);
8235 for (auto *E : C->reduction_ops())
8236 Record.AddStmt(E);
8237 for (auto *E : C->taskgroup_descriptors())
8238 Record.AddStmt(E);
8239}
8240
8241void OMPClauseWriter::VisitOMPLinearClause(OMPLinearClause *C) {
8242 Record.push_back(C->varlist_size());
8243 VisitOMPClauseWithPostUpdate(C);
8244 Record.AddSourceLocation(C->getLParenLoc());
8245 Record.AddSourceLocation(C->getColonLoc());
8246 Record.push_back(C->getModifier());
8247 Record.AddSourceLocation(C->getModifierLoc());
8248 for (auto *VE : C->varlist()) {
8249 Record.AddStmt(VE);
8250 }
8251 for (auto *VE : C->privates()) {
8252 Record.AddStmt(VE);
8253 }
8254 for (auto *VE : C->inits()) {
8255 Record.AddStmt(VE);
8256 }
8257 for (auto *VE : C->updates()) {
8258 Record.AddStmt(VE);
8259 }
8260 for (auto *VE : C->finals()) {
8261 Record.AddStmt(VE);
8262 }
8263 Record.AddStmt(C->getStep());
8264 Record.AddStmt(C->getCalcStep());
8265 for (auto *VE : C->used_expressions())
8266 Record.AddStmt(VE);
8267}
8268
8269void OMPClauseWriter::VisitOMPAlignedClause(OMPAlignedClause *C) {
8270 Record.push_back(C->varlist_size());
8271 Record.AddSourceLocation(C->getLParenLoc());
8272 Record.AddSourceLocation(C->getColonLoc());
8273 for (auto *VE : C->varlist())
8274 Record.AddStmt(VE);
8275 Record.AddStmt(C->getAlignment());
8276}
8277
8278void OMPClauseWriter::VisitOMPCopyinClause(OMPCopyinClause *C) {
8279 Record.push_back(C->varlist_size());
8280 Record.AddSourceLocation(C->getLParenLoc());
8281 for (auto *VE : C->varlist())
8282 Record.AddStmt(VE);
8283 for (auto *E : C->source_exprs())
8284 Record.AddStmt(E);
8285 for (auto *E : C->destination_exprs())
8286 Record.AddStmt(E);
8287 for (auto *E : C->assignment_ops())
8288 Record.AddStmt(E);
8289}
8290
8291void OMPClauseWriter::VisitOMPCopyprivateClause(OMPCopyprivateClause *C) {
8292 Record.push_back(C->varlist_size());
8293 Record.AddSourceLocation(C->getLParenLoc());
8294 for (auto *VE : C->varlist())
8295 Record.AddStmt(VE);
8296 for (auto *E : C->source_exprs())
8297 Record.AddStmt(E);
8298 for (auto *E : C->destination_exprs())
8299 Record.AddStmt(E);
8300 for (auto *E : C->assignment_ops())
8301 Record.AddStmt(E);
8302}
8303
8304void OMPClauseWriter::VisitOMPFlushClause(OMPFlushClause *C) {
8305 Record.push_back(C->varlist_size());
8306 Record.AddSourceLocation(C->getLParenLoc());
8307 for (auto *VE : C->varlist())
8308 Record.AddStmt(VE);
8309}
8310
8311void OMPClauseWriter::VisitOMPDepobjClause(OMPDepobjClause *C) {
8312 Record.AddStmt(C->getDepobj());
8313 Record.AddSourceLocation(C->getLParenLoc());
8314}
8315
8316void OMPClauseWriter::VisitOMPDependClause(OMPDependClause *C) {
8317 Record.push_back(C->varlist_size());
8318 Record.push_back(C->getNumLoops());
8319 Record.AddSourceLocation(C->getLParenLoc());
8320 Record.AddStmt(C->getModifier());
8321 Record.push_back(C->getDependencyKind());
8322 Record.AddSourceLocation(C->getDependencyLoc());
8323 Record.AddSourceLocation(C->getColonLoc());
8324 Record.AddSourceLocation(C->getOmpAllMemoryLoc());
8325 for (auto *VE : C->varlist())
8326 Record.AddStmt(VE);
8327 for (unsigned I = 0, E = C->getNumLoops(); I < E; ++I)
8328 Record.AddStmt(C->getLoopData(I));
8329}
8330
8331void OMPClauseWriter::VisitOMPDeviceClause(OMPDeviceClause *C) {
8332 VisitOMPClauseWithPreInit(C);
8333 Record.writeEnum(C->getModifier());
8334 Record.AddStmt(C->getDevice());
8335 Record.AddSourceLocation(C->getModifierLoc());
8336 Record.AddSourceLocation(C->getLParenLoc());
8337}
8338
8339void OMPClauseWriter::VisitOMPMapClause(OMPMapClause *C) {
8340 Record.push_back(C->varlist_size());
8341 Record.push_back(C->getUniqueDeclarationsNum());
8342 Record.push_back(C->getTotalComponentListNum());
8343 Record.push_back(C->getTotalComponentsNum());
8344 Record.AddSourceLocation(C->getLParenLoc());
8345 bool HasIteratorModifier = false;
8346 for (unsigned I = 0; I < NumberOfOMPMapClauseModifiers; ++I) {
8347 Record.push_back(C->getMapTypeModifier(I));
8348 Record.AddSourceLocation(C->getMapTypeModifierLoc(I));
8349 if (C->getMapTypeModifier(I) == OMPC_MAP_MODIFIER_iterator)
8350 HasIteratorModifier = true;
8351 }
8352 Record.AddNestedNameSpecifierLoc(C->getMapperQualifierLoc());
8353 Record.AddDeclarationNameInfo(C->getMapperIdInfo());
8354 Record.push_back(C->getMapType());
8355 Record.AddSourceLocation(C->getMapLoc());
8356 Record.AddSourceLocation(C->getColonLoc());
8357 for (auto *E : C->varlist())
8358 Record.AddStmt(E);
8359 for (auto *E : C->mapperlists())
8360 Record.AddStmt(E);
8361 if (HasIteratorModifier)
8362 Record.AddStmt(C->getIteratorModifier());
8363 for (auto *D : C->all_decls())
8364 Record.AddDeclRef(D);
8365 for (auto N : C->all_num_lists())
8366 Record.push_back(N);
8367 for (auto N : C->all_lists_sizes())
8368 Record.push_back(N);
8369 for (auto &M : C->all_components()) {
8370 Record.AddStmt(M.getAssociatedExpression());
8371 Record.AddDeclRef(M.getAssociatedDeclaration());
8372 }
8373}
8374
8375void OMPClauseWriter::VisitOMPAllocateClause(OMPAllocateClause *C) {
8376 Record.push_back(C->varlist_size());
8377 Record.writeEnum(C->getFirstAllocateModifier());
8378 Record.writeEnum(C->getSecondAllocateModifier());
8379 Record.AddSourceLocation(C->getLParenLoc());
8380 Record.AddSourceLocation(C->getColonLoc());
8381 Record.AddStmt(C->getAllocator());
8382 Record.AddStmt(C->getAlignment());
8383 for (auto *VE : C->varlist())
8384 Record.AddStmt(VE);
8385}
8386
8387void OMPClauseWriter::VisitOMPNumTeamsClause(OMPNumTeamsClause *C) {
8388 Record.push_back(C->varlist_size());
8389 VisitOMPClauseWithPreInit(C);
8390 Record.AddSourceLocation(C->getLParenLoc());
8391 for (auto *VE : C->varlist())
8392 Record.AddStmt(VE);
8393}
8394
8395void OMPClauseWriter::VisitOMPThreadLimitClause(OMPThreadLimitClause *C) {
8396 Record.push_back(C->varlist_size());
8397 VisitOMPClauseWithPreInit(C);
8398 Record.AddSourceLocation(C->getLParenLoc());
8399 for (auto *VE : C->varlist())
8400 Record.AddStmt(VE);
8401}
8402
8403void OMPClauseWriter::VisitOMPPriorityClause(OMPPriorityClause *C) {
8404 VisitOMPClauseWithPreInit(C);
8405 Record.AddStmt(C->getPriority());
8406 Record.AddSourceLocation(C->getLParenLoc());
8407}
8408
8409void OMPClauseWriter::VisitOMPGrainsizeClause(OMPGrainsizeClause *C) {
8410 VisitOMPClauseWithPreInit(C);
8411 Record.writeEnum(C->getModifier());
8412 Record.AddStmt(C->getGrainsize());
8413 Record.AddSourceLocation(C->getModifierLoc());
8414 Record.AddSourceLocation(C->getLParenLoc());
8415}
8416
8417void OMPClauseWriter::VisitOMPNumTasksClause(OMPNumTasksClause *C) {
8418 VisitOMPClauseWithPreInit(C);
8419 Record.writeEnum(C->getModifier());
8420 Record.AddStmt(C->getNumTasks());
8421 Record.AddSourceLocation(C->getModifierLoc());
8422 Record.AddSourceLocation(C->getLParenLoc());
8423}
8424
8425void OMPClauseWriter::VisitOMPHintClause(OMPHintClause *C) {
8426 Record.AddStmt(C->getHint());
8427 Record.AddSourceLocation(C->getLParenLoc());
8428}
8429
8430void OMPClauseWriter::VisitOMPDistScheduleClause(OMPDistScheduleClause *C) {
8431 VisitOMPClauseWithPreInit(C);
8432 Record.push_back(C->getDistScheduleKind());
8433 Record.AddStmt(C->getChunkSize());
8434 Record.AddSourceLocation(C->getLParenLoc());
8435 Record.AddSourceLocation(C->getDistScheduleKindLoc());
8436 Record.AddSourceLocation(C->getCommaLoc());
8437}
8438
8439void OMPClauseWriter::VisitOMPDefaultmapClause(OMPDefaultmapClause *C) {
8440 Record.push_back(C->getDefaultmapKind());
8441 Record.push_back(C->getDefaultmapModifier());
8442 Record.AddSourceLocation(C->getLParenLoc());
8443 Record.AddSourceLocation(C->getDefaultmapModifierLoc());
8444 Record.AddSourceLocation(C->getDefaultmapKindLoc());
8445}
8446
8447void OMPClauseWriter::VisitOMPToClause(OMPToClause *C) {
8448 Record.push_back(C->varlist_size());
8449 Record.push_back(C->getUniqueDeclarationsNum());
8450 Record.push_back(C->getTotalComponentListNum());
8451 Record.push_back(C->getTotalComponentsNum());
8452 Record.AddSourceLocation(C->getLParenLoc());
8453 for (unsigned I = 0; I < NumberOfOMPMotionModifiers; ++I) {
8454 Record.push_back(C->getMotionModifier(I));
8455 Record.AddSourceLocation(C->getMotionModifierLoc(I));
8456 }
8457 Record.AddNestedNameSpecifierLoc(C->getMapperQualifierLoc());
8458 Record.AddDeclarationNameInfo(C->getMapperIdInfo());
8459 Record.AddSourceLocation(C->getColonLoc());
8460 for (auto *E : C->varlist())
8461 Record.AddStmt(E);
8462 for (auto *E : C->mapperlists())
8463 Record.AddStmt(E);
8464 for (auto *D : C->all_decls())
8465 Record.AddDeclRef(D);
8466 for (auto N : C->all_num_lists())
8467 Record.push_back(N);
8468 for (auto N : C->all_lists_sizes())
8469 Record.push_back(N);
8470 for (auto &M : C->all_components()) {
8471 Record.AddStmt(M.getAssociatedExpression());
8472 Record.writeBool(M.isNonContiguous());
8473 Record.AddDeclRef(M.getAssociatedDeclaration());
8474 }
8475}
8476
8477void OMPClauseWriter::VisitOMPFromClause(OMPFromClause *C) {
8478 Record.push_back(C->varlist_size());
8479 Record.push_back(C->getUniqueDeclarationsNum());
8480 Record.push_back(C->getTotalComponentListNum());
8481 Record.push_back(C->getTotalComponentsNum());
8482 Record.AddSourceLocation(C->getLParenLoc());
8483 for (unsigned I = 0; I < NumberOfOMPMotionModifiers; ++I) {
8484 Record.push_back(C->getMotionModifier(I));
8485 Record.AddSourceLocation(C->getMotionModifierLoc(I));
8486 }
8487 Record.AddNestedNameSpecifierLoc(C->getMapperQualifierLoc());
8488 Record.AddDeclarationNameInfo(C->getMapperIdInfo());
8489 Record.AddSourceLocation(C->getColonLoc());
8490 for (auto *E : C->varlist())
8491 Record.AddStmt(E);
8492 for (auto *E : C->mapperlists())
8493 Record.AddStmt(E);
8494 for (auto *D : C->all_decls())
8495 Record.AddDeclRef(D);
8496 for (auto N : C->all_num_lists())
8497 Record.push_back(N);
8498 for (auto N : C->all_lists_sizes())
8499 Record.push_back(N);
8500 for (auto &M : C->all_components()) {
8501 Record.AddStmt(M.getAssociatedExpression());
8502 Record.writeBool(M.isNonContiguous());
8503 Record.AddDeclRef(M.getAssociatedDeclaration());
8504 }
8505}
8506
8507void OMPClauseWriter::VisitOMPUseDevicePtrClause(OMPUseDevicePtrClause *C) {
8508 Record.push_back(C->varlist_size());
8509 Record.push_back(C->getUniqueDeclarationsNum());
8510 Record.push_back(C->getTotalComponentListNum());
8511 Record.push_back(C->getTotalComponentsNum());
8512 Record.AddSourceLocation(C->getLParenLoc());
8513 for (auto *E : C->varlist())
8514 Record.AddStmt(E);
8515 for (auto *VE : C->private_copies())
8516 Record.AddStmt(VE);
8517 for (auto *VE : C->inits())
8518 Record.AddStmt(VE);
8519 for (auto *D : C->all_decls())
8520 Record.AddDeclRef(D);
8521 for (auto N : C->all_num_lists())
8522 Record.push_back(N);
8523 for (auto N : C->all_lists_sizes())
8524 Record.push_back(N);
8525 for (auto &M : C->all_components()) {
8526 Record.AddStmt(M.getAssociatedExpression());
8527 Record.AddDeclRef(M.getAssociatedDeclaration());
8528 }
8529}
8530
8531void OMPClauseWriter::VisitOMPUseDeviceAddrClause(OMPUseDeviceAddrClause *C) {
8532 Record.push_back(C->varlist_size());
8533 Record.push_back(C->getUniqueDeclarationsNum());
8534 Record.push_back(C->getTotalComponentListNum());
8535 Record.push_back(C->getTotalComponentsNum());
8536 Record.AddSourceLocation(C->getLParenLoc());
8537 for (auto *E : C->varlist())
8538 Record.AddStmt(E);
8539 for (auto *D : C->all_decls())
8540 Record.AddDeclRef(D);
8541 for (auto N : C->all_num_lists())
8542 Record.push_back(N);
8543 for (auto N : C->all_lists_sizes())
8544 Record.push_back(N);
8545 for (auto &M : C->all_components()) {
8546 Record.AddStmt(M.getAssociatedExpression());
8547 Record.AddDeclRef(M.getAssociatedDeclaration());
8548 }
8549}
8550
8551void OMPClauseWriter::VisitOMPIsDevicePtrClause(OMPIsDevicePtrClause *C) {
8552 Record.push_back(C->varlist_size());
8553 Record.push_back(C->getUniqueDeclarationsNum());
8554 Record.push_back(C->getTotalComponentListNum());
8555 Record.push_back(C->getTotalComponentsNum());
8556 Record.AddSourceLocation(C->getLParenLoc());
8557 for (auto *E : C->varlist())
8558 Record.AddStmt(E);
8559 for (auto *D : C->all_decls())
8560 Record.AddDeclRef(D);
8561 for (auto N : C->all_num_lists())
8562 Record.push_back(N);
8563 for (auto N : C->all_lists_sizes())
8564 Record.push_back(N);
8565 for (auto &M : C->all_components()) {
8566 Record.AddStmt(M.getAssociatedExpression());
8567 Record.AddDeclRef(M.getAssociatedDeclaration());
8568 }
8569}
8570
8571void OMPClauseWriter::VisitOMPHasDeviceAddrClause(OMPHasDeviceAddrClause *C) {
8572 Record.push_back(C->varlist_size());
8573 Record.push_back(C->getUniqueDeclarationsNum());
8574 Record.push_back(C->getTotalComponentListNum());
8575 Record.push_back(C->getTotalComponentsNum());
8576 Record.AddSourceLocation(C->getLParenLoc());
8577 for (auto *E : C->varlist())
8578 Record.AddStmt(E);
8579 for (auto *D : C->all_decls())
8580 Record.AddDeclRef(D);
8581 for (auto N : C->all_num_lists())
8582 Record.push_back(N);
8583 for (auto N : C->all_lists_sizes())
8584 Record.push_back(N);
8585 for (auto &M : C->all_components()) {
8586 Record.AddStmt(M.getAssociatedExpression());
8587 Record.AddDeclRef(M.getAssociatedDeclaration());
8588 }
8589}
8590
8591void OMPClauseWriter::VisitOMPUnifiedAddressClause(OMPUnifiedAddressClause *) {}
8592
8593void OMPClauseWriter::VisitOMPUnifiedSharedMemoryClause(
8595
8596void OMPClauseWriter::VisitOMPReverseOffloadClause(OMPReverseOffloadClause *) {}
8597
8598void
8599OMPClauseWriter::VisitOMPDynamicAllocatorsClause(OMPDynamicAllocatorsClause *) {
8600}
8601
8602void OMPClauseWriter::VisitOMPAtomicDefaultMemOrderClause(
8604 Record.push_back(C->getAtomicDefaultMemOrderKind());
8605 Record.AddSourceLocation(C->getLParenLoc());
8606 Record.AddSourceLocation(C->getAtomicDefaultMemOrderKindKwLoc());
8607}
8608
8609void OMPClauseWriter::VisitOMPSelfMapsClause(OMPSelfMapsClause *) {}
8610
8611void OMPClauseWriter::VisitOMPAtClause(OMPAtClause *C) {
8612 Record.push_back(C->getAtKind());
8613 Record.AddSourceLocation(C->getLParenLoc());
8614 Record.AddSourceLocation(C->getAtKindKwLoc());
8615}
8616
8617void OMPClauseWriter::VisitOMPSeverityClause(OMPSeverityClause *C) {
8618 Record.push_back(C->getSeverityKind());
8619 Record.AddSourceLocation(C->getLParenLoc());
8620 Record.AddSourceLocation(C->getSeverityKindKwLoc());
8621}
8622
8623void OMPClauseWriter::VisitOMPMessageClause(OMPMessageClause *C) {
8624 VisitOMPClauseWithPreInit(C);
8625 Record.AddStmt(C->getMessageString());
8626 Record.AddSourceLocation(C->getLParenLoc());
8627}
8628
8629void OMPClauseWriter::VisitOMPNontemporalClause(OMPNontemporalClause *C) {
8630 Record.push_back(C->varlist_size());
8631 Record.AddSourceLocation(C->getLParenLoc());
8632 for (auto *VE : C->varlist())
8633 Record.AddStmt(VE);
8634 for (auto *E : C->private_refs())
8635 Record.AddStmt(E);
8636}
8637
8638void OMPClauseWriter::VisitOMPInclusiveClause(OMPInclusiveClause *C) {
8639 Record.push_back(C->varlist_size());
8640 Record.AddSourceLocation(C->getLParenLoc());
8641 for (auto *VE : C->varlist())
8642 Record.AddStmt(VE);
8643}
8644
8645void OMPClauseWriter::VisitOMPExclusiveClause(OMPExclusiveClause *C) {
8646 Record.push_back(C->varlist_size());
8647 Record.AddSourceLocation(C->getLParenLoc());
8648 for (auto *VE : C->varlist())
8649 Record.AddStmt(VE);
8650}
8651
8652void OMPClauseWriter::VisitOMPOrderClause(OMPOrderClause *C) {
8653 Record.writeEnum(C->getKind());
8654 Record.writeEnum(C->getModifier());
8655 Record.AddSourceLocation(C->getLParenLoc());
8656 Record.AddSourceLocation(C->getKindKwLoc());
8657 Record.AddSourceLocation(C->getModifierKwLoc());
8658}
8659
8660void OMPClauseWriter::VisitOMPUsesAllocatorsClause(OMPUsesAllocatorsClause *C) {
8661 Record.push_back(C->getNumberOfAllocators());
8662 Record.AddSourceLocation(C->getLParenLoc());
8663 for (unsigned I = 0, E = C->getNumberOfAllocators(); I < E; ++I) {
8664 OMPUsesAllocatorsClause::Data Data = C->getAllocatorData(I);
8665 Record.AddStmt(Data.Allocator);
8666 Record.AddStmt(Data.AllocatorTraits);
8667 Record.AddSourceLocation(Data.LParenLoc);
8668 Record.AddSourceLocation(Data.RParenLoc);
8669 }
8670}
8671
8672void OMPClauseWriter::VisitOMPAffinityClause(OMPAffinityClause *C) {
8673 Record.push_back(C->varlist_size());
8674 Record.AddSourceLocation(C->getLParenLoc());
8675 Record.AddStmt(C->getModifier());
8676 Record.AddSourceLocation(C->getColonLoc());
8677 for (Expr *E : C->varlist())
8678 Record.AddStmt(E);
8679}
8680
8681void OMPClauseWriter::VisitOMPBindClause(OMPBindClause *C) {
8682 Record.writeEnum(C->getBindKind());
8683 Record.AddSourceLocation(C->getLParenLoc());
8684 Record.AddSourceLocation(C->getBindKindLoc());
8685}
8686
8687void OMPClauseWriter::VisitOMPXDynCGroupMemClause(OMPXDynCGroupMemClause *C) {
8688 VisitOMPClauseWithPreInit(C);
8689 Record.AddStmt(C->getSize());
8690 Record.AddSourceLocation(C->getLParenLoc());
8691}
8692
8693void OMPClauseWriter::VisitOMPDynGroupprivateClause(
8695 VisitOMPClauseWithPreInit(C);
8696 Record.push_back(C->getDynGroupprivateModifier());
8697 Record.push_back(C->getDynGroupprivateFallbackModifier());
8698 Record.AddStmt(C->getSize());
8699 Record.AddSourceLocation(C->getLParenLoc());
8700 Record.AddSourceLocation(C->getDynGroupprivateModifierLoc());
8701 Record.AddSourceLocation(C->getDynGroupprivateFallbackModifierLoc());
8702}
8703
8704void OMPClauseWriter::VisitOMPDoacrossClause(OMPDoacrossClause *C) {
8705 Record.push_back(C->varlist_size());
8706 Record.push_back(C->getNumLoops());
8707 Record.AddSourceLocation(C->getLParenLoc());
8708 Record.push_back(C->getDependenceType());
8709 Record.AddSourceLocation(C->getDependenceLoc());
8710 Record.AddSourceLocation(C->getColonLoc());
8711 for (auto *VE : C->varlist())
8712 Record.AddStmt(VE);
8713 for (unsigned I = 0, E = C->getNumLoops(); I < E; ++I)
8714 Record.AddStmt(C->getLoopData(I));
8715}
8716
8717void OMPClauseWriter::VisitOMPXAttributeClause(OMPXAttributeClause *C) {
8718 Record.AddAttributes(C->getAttrs());
8719 Record.AddSourceLocation(C->getBeginLoc());
8720 Record.AddSourceLocation(C->getLParenLoc());
8721 Record.AddSourceLocation(C->getEndLoc());
8722}
8723
8724void OMPClauseWriter::VisitOMPXBareClause(OMPXBareClause *C) {}
8725
8727 writeUInt32(TI->Sets.size());
8728 for (const auto &Set : TI->Sets) {
8729 writeEnum(Set.Kind);
8730 writeUInt32(Set.Selectors.size());
8731 for (const auto &Selector : Set.Selectors) {
8732 writeEnum(Selector.Kind);
8733 writeBool(Selector.ScoreOrCondition);
8734 if (Selector.ScoreOrCondition)
8735 writeExprRef(Selector.ScoreOrCondition);
8736 writeUInt32(Selector.Properties.size());
8737 for (const auto &Property : Selector.Properties)
8738 writeEnum(Property.Kind);
8739 }
8740 }
8741}
8742
8744 if (!Data)
8745 return;
8746 writeUInt32(Data->getNumClauses());
8747 writeUInt32(Data->getNumChildren());
8748 writeBool(Data->hasAssociatedStmt());
8749 for (unsigned I = 0, E = Data->getNumClauses(); I < E; ++I)
8750 writeOMPClause(Data->getClauses()[I]);
8751 if (Data->hasAssociatedStmt())
8752 AddStmt(Data->getAssociatedStmt());
8753 for (unsigned I = 0, E = Data->getNumChildren(); I < E; ++I)
8754 AddStmt(Data->getChildren()[I]);
8755}
8756
8758 writeUInt32(C->getVarList().size());
8759 for (Expr *E : C->getVarList())
8760 AddStmt(E);
8761}
8762
8764 writeUInt32(Exprs.size());
8765 for (Expr *E : Exprs)
8766 AddStmt(E);
8767}
8768
8770 writeEnum(C->getClauseKind());
8771 writeSourceLocation(C->getBeginLoc());
8772 writeSourceLocation(C->getEndLoc());
8773
8774 switch (C->getClauseKind()) {
8776 const auto *DC = cast<OpenACCDefaultClause>(C);
8777 writeSourceLocation(DC->getLParenLoc());
8778 writeEnum(DC->getDefaultClauseKind());
8779 return;
8780 }
8781 case OpenACCClauseKind::If: {
8782 const auto *IC = cast<OpenACCIfClause>(C);
8783 writeSourceLocation(IC->getLParenLoc());
8784 AddStmt(const_cast<Expr*>(IC->getConditionExpr()));
8785 return;
8786 }
8788 const auto *SC = cast<OpenACCSelfClause>(C);
8789 writeSourceLocation(SC->getLParenLoc());
8790 writeBool(SC->isConditionExprClause());
8791 if (SC->isConditionExprClause()) {
8792 writeBool(SC->hasConditionExpr());
8793 if (SC->hasConditionExpr())
8794 AddStmt(const_cast<Expr *>(SC->getConditionExpr()));
8795 } else {
8796 writeUInt32(SC->getVarList().size());
8797 for (Expr *E : SC->getVarList())
8798 AddStmt(E);
8799 }
8800 return;
8801 }
8803 const auto *NGC = cast<OpenACCNumGangsClause>(C);
8804 writeSourceLocation(NGC->getLParenLoc());
8805 writeUInt32(NGC->getIntExprs().size());
8806 for (Expr *E : NGC->getIntExprs())
8807 AddStmt(E);
8808 return;
8809 }
8811 const auto *DNC = cast<OpenACCDeviceNumClause>(C);
8812 writeSourceLocation(DNC->getLParenLoc());
8813 AddStmt(const_cast<Expr*>(DNC->getIntExpr()));
8814 return;
8815 }
8817 const auto *DAC = cast<OpenACCDefaultAsyncClause>(C);
8818 writeSourceLocation(DAC->getLParenLoc());
8819 AddStmt(const_cast<Expr *>(DAC->getIntExpr()));
8820 return;
8821 }
8823 const auto *NWC = cast<OpenACCNumWorkersClause>(C);
8824 writeSourceLocation(NWC->getLParenLoc());
8825 AddStmt(const_cast<Expr*>(NWC->getIntExpr()));
8826 return;
8827 }
8829 const auto *NWC = cast<OpenACCVectorLengthClause>(C);
8830 writeSourceLocation(NWC->getLParenLoc());
8831 AddStmt(const_cast<Expr*>(NWC->getIntExpr()));
8832 return;
8833 }
8835 const auto *PC = cast<OpenACCPrivateClause>(C);
8836 writeSourceLocation(PC->getLParenLoc());
8838
8839 for (const OpenACCPrivateRecipe &R : PC->getInitRecipes()) {
8840 static_assert(sizeof(R) == 1 * sizeof(int *));
8841 AddDeclRef(R.AllocaDecl);
8842 }
8843 return;
8844 }
8846 const auto *HC = cast<OpenACCHostClause>(C);
8847 writeSourceLocation(HC->getLParenLoc());
8849 return;
8850 }
8852 const auto *DC = cast<OpenACCDeviceClause>(C);
8853 writeSourceLocation(DC->getLParenLoc());
8855 return;
8856 }
8858 const auto *FPC = cast<OpenACCFirstPrivateClause>(C);
8859 writeSourceLocation(FPC->getLParenLoc());
8861
8862 for (const OpenACCFirstPrivateRecipe &R : FPC->getInitRecipes()) {
8863 static_assert(sizeof(R) == 2 * sizeof(int *));
8864 AddDeclRef(R.AllocaDecl);
8865 AddDeclRef(R.InitFromTemporary);
8866 }
8867 return;
8868 }
8870 const auto *AC = cast<OpenACCAttachClause>(C);
8871 writeSourceLocation(AC->getLParenLoc());
8873 return;
8874 }
8876 const auto *DC = cast<OpenACCDetachClause>(C);
8877 writeSourceLocation(DC->getLParenLoc());
8879 return;
8880 }
8882 const auto *DC = cast<OpenACCDeleteClause>(C);
8883 writeSourceLocation(DC->getLParenLoc());
8885 return;
8886 }
8888 const auto *UDC = cast<OpenACCUseDeviceClause>(C);
8889 writeSourceLocation(UDC->getLParenLoc());
8891 return;
8892 }
8894 const auto *DPC = cast<OpenACCDevicePtrClause>(C);
8895 writeSourceLocation(DPC->getLParenLoc());
8897 return;
8898 }
8900 const auto *NCC = cast<OpenACCNoCreateClause>(C);
8901 writeSourceLocation(NCC->getLParenLoc());
8903 return;
8904 }
8906 const auto *PC = cast<OpenACCPresentClause>(C);
8907 writeSourceLocation(PC->getLParenLoc());
8909 return;
8910 }
8914 const auto *CC = cast<OpenACCCopyClause>(C);
8915 writeSourceLocation(CC->getLParenLoc());
8916 writeEnum(CC->getModifierList());
8918 return;
8919 }
8923 const auto *CIC = cast<OpenACCCopyInClause>(C);
8924 writeSourceLocation(CIC->getLParenLoc());
8925 writeEnum(CIC->getModifierList());
8927 return;
8928 }
8932 const auto *COC = cast<OpenACCCopyOutClause>(C);
8933 writeSourceLocation(COC->getLParenLoc());
8934 writeEnum(COC->getModifierList());
8936 return;
8937 }
8941 const auto *CC = cast<OpenACCCreateClause>(C);
8942 writeSourceLocation(CC->getLParenLoc());
8943 writeEnum(CC->getModifierList());
8945 return;
8946 }
8948 const auto *AC = cast<OpenACCAsyncClause>(C);
8949 writeSourceLocation(AC->getLParenLoc());
8950 writeBool(AC->hasIntExpr());
8951 if (AC->hasIntExpr())
8952 AddStmt(const_cast<Expr*>(AC->getIntExpr()));
8953 return;
8954 }
8956 const auto *WC = cast<OpenACCWaitClause>(C);
8957 writeSourceLocation(WC->getLParenLoc());
8958 writeBool(WC->getDevNumExpr());
8959 if (Expr *DNE = WC->getDevNumExpr())
8960 AddStmt(DNE);
8961 writeSourceLocation(WC->getQueuesLoc());
8962
8963 writeOpenACCIntExprList(WC->getQueueIdExprs());
8964 return;
8965 }
8968 const auto *DTC = cast<OpenACCDeviceTypeClause>(C);
8969 writeSourceLocation(DTC->getLParenLoc());
8970 writeUInt32(DTC->getArchitectures().size());
8971 for (const DeviceTypeArgument &Arg : DTC->getArchitectures()) {
8972 writeBool(Arg.getIdentifierInfo());
8973 if (Arg.getIdentifierInfo())
8974 AddIdentifierRef(Arg.getIdentifierInfo());
8975 writeSourceLocation(Arg.getLoc());
8976 }
8977 return;
8978 }
8980 const auto *RC = cast<OpenACCReductionClause>(C);
8981 writeSourceLocation(RC->getLParenLoc());
8982 writeEnum(RC->getReductionOp());
8984
8985 for (const OpenACCReductionRecipe &R : RC->getRecipes()) {
8986 AddDeclRef(R.AllocaDecl);
8987
8988 static_assert(sizeof(OpenACCReductionRecipe::CombinerRecipe) ==
8989 3 * sizeof(int *));
8990 writeUInt32(R.CombinerRecipes.size());
8991
8992 for (auto &CombinerRecipe : R.CombinerRecipes) {
8993 AddDeclRef(CombinerRecipe.LHS);
8994 AddDeclRef(CombinerRecipe.RHS);
8995 AddStmt(CombinerRecipe.Op);
8996 }
8997 }
8998 return;
8999 }
9006 // Nothing to do here, there is no additional information beyond the
9007 // begin/end loc and clause kind.
9008 return;
9010 const auto *CC = cast<OpenACCCollapseClause>(C);
9011 writeSourceLocation(CC->getLParenLoc());
9012 writeBool(CC->hasForce());
9013 AddStmt(const_cast<Expr *>(CC->getLoopCount()));
9014 return;
9015 }
9017 const auto *TC = cast<OpenACCTileClause>(C);
9018 writeSourceLocation(TC->getLParenLoc());
9019 writeUInt32(TC->getSizeExprs().size());
9020 for (Expr *E : TC->getSizeExprs())
9021 AddStmt(E);
9022 return;
9023 }
9025 const auto *GC = cast<OpenACCGangClause>(C);
9026 writeSourceLocation(GC->getLParenLoc());
9027 writeUInt32(GC->getNumExprs());
9028 for (unsigned I = 0; I < GC->getNumExprs(); ++I) {
9029 writeEnum(GC->getExpr(I).first);
9030 AddStmt(const_cast<Expr *>(GC->getExpr(I).second));
9031 }
9032 return;
9033 }
9035 const auto *WC = cast<OpenACCWorkerClause>(C);
9036 writeSourceLocation(WC->getLParenLoc());
9037 writeBool(WC->hasIntExpr());
9038 if (WC->hasIntExpr())
9039 AddStmt(const_cast<Expr *>(WC->getIntExpr()));
9040 return;
9041 }
9043 const auto *VC = cast<OpenACCVectorClause>(C);
9044 writeSourceLocation(VC->getLParenLoc());
9045 writeBool(VC->hasIntExpr());
9046 if (VC->hasIntExpr())
9047 AddStmt(const_cast<Expr *>(VC->getIntExpr()));
9048 return;
9049 }
9051 const auto *LC = cast<OpenACCLinkClause>(C);
9052 writeSourceLocation(LC->getLParenLoc());
9054 return;
9055 }
9057 const auto *DRC = cast<OpenACCDeviceResidentClause>(C);
9058 writeSourceLocation(DRC->getLParenLoc());
9060 return;
9061 }
9062
9064 const auto *BC = cast<OpenACCBindClause>(C);
9065 writeSourceLocation(BC->getLParenLoc());
9066 writeBool(BC->isStringArgument());
9067 if (BC->isStringArgument())
9068 AddStmt(const_cast<StringLiteral *>(BC->getStringArgument()));
9069 else
9070 AddIdentifierRef(BC->getIdentifierArgument());
9071
9072 return;
9073 }
9076 llvm_unreachable("Clause serialization not yet implemented");
9077 }
9078 llvm_unreachable("Invalid Clause Kind");
9079}
9080
9083 for (const OpenACCClause *Clause : Clauses)
9084 writeOpenACCClause(Clause);
9085}
9087 const OpenACCRoutineDeclAttr *A) {
9088 // We have to write the size so that the reader can do a resize. Unlike the
9089 // Decl version of this, we can't count on trailing storage to get this right.
9090 writeUInt32(A->Clauses.size());
9091 writeOpenACCClauseList(A->Clauses);
9092}
#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.
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:938
RawCommentList Comments
All comments in this translation unit.
Definition ASTContext.h:971
TagDecl * MSTypeInfoTagDecl
QualType getjmp_bufType() const
Retrieve the C jmp_buf type.
QualType getsigjmp_bufType() const
Retrieve the C sigjmp_buf type.
TagDecl * MSGuidTagDecl
Decl * getVaListTagDecl() const
Retrieve the C type declaration corresponding to the predefined __va_list_tag type used to help defin...
FunctionDecl * getcudaConfigureCallDecl()
import_range local_imports() const
virtual void EnteringModulePurview()
The parser find the named module declaration.
Reads an AST files chain containing the contents of a translation unit.
Definition ASTReader.h:430
unsigned getTotalNumSubmodules() const
Returns the number of submodules known.
Definition ASTReader.h: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:1460
const CXXDestructorDecl * getDestructor() const
Definition ExprCXX.h:1471
Declaration of a class template.
Represents a class template specialization, which refers to a class template with a given set of temp...
CodeGenOptions - Track various options which control how the code is optimized and passed to the back...
A reference to a concept and its template args, as it appears in the code.
Definition ASTConcept.h: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:4312
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:6500
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:11337
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:15579
EnumDecl * getStdAlignValT() const
LazyDeclPtr StdBadAlloc
The C++ "std::bad_alloc" class, which is defined by the C++ standard library.
Definition Sema.h:8337
SmallVector< VTableUse, 16 > VTableUses
The list of vtables that are required but have not yet been materialized.
Definition Sema.h:5838
Preprocessor & PP
Definition Sema.h:1282
llvm::MapVector< const FunctionDecl *, std::unique_ptr< LateParsedTemplate > > LateParsedTemplateMapT
Definition Sema.h:11336
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:5844
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:13961
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:6503
std::deque< PendingImplicitInstantiation > PendingInstantiations
The queue of implicit template instantiations that are required but have not yet been performed.
Definition Sema.h:13944
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:2898
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:8341
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:324
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:2444
EvaluatedStmt * getEvaluatedStmt() const
Definition Decl.cpp:2571
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:2628
Declaration of a variable template.
Represents a variable template specialization, which refers to a variable template with a given set o...
SourceLocation getNameLoc() const
Definition TypeLoc.h: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:15630
Decl * D
The template function declaration to be late parsed.
Definition Sema.h:15628
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