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