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