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