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