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