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