81#include "llvm/ADT/APFloat.h"
82#include "llvm/ADT/APInt.h"
83#include "llvm/ADT/APSInt.h"
84#include "llvm/ADT/ArrayRef.h"
85#include "llvm/ADT/DenseMap.h"
86#include "llvm/ADT/DenseSet.h"
87#include "llvm/ADT/Hashing.h"
88#include "llvm/ADT/PointerIntPair.h"
89#include "llvm/ADT/STLExtras.h"
90#include "llvm/ADT/ScopeExit.h"
91#include "llvm/ADT/SmallPtrSet.h"
92#include "llvm/ADT/SmallString.h"
93#include "llvm/ADT/SmallVector.h"
94#include "llvm/ADT/StringMap.h"
95#include "llvm/ADT/StringRef.h"
96#include "llvm/Bitstream/BitCodes.h"
97#include "llvm/Bitstream/BitstreamWriter.h"
98#include "llvm/Support/Casting.h"
99#include "llvm/Support/Compression.h"
100#include "llvm/Support/DJB.h"
101#include "llvm/Support/Endian.h"
102#include "llvm/Support/EndianStream.h"
103#include "llvm/Support/Error.h"
104#include "llvm/Support/ErrorHandling.h"
105#include "llvm/Support/LEB128.h"
106#include "llvm/Support/MemoryBuffer.h"
107#include "llvm/Support/OnDiskHashTable.h"
108#include "llvm/Support/Path.h"
109#include "llvm/Support/SHA1.h"
110#include "llvm/Support/TimeProfiler.h"
111#include "llvm/Support/VersionTuple.h"
112#include "llvm/Support/raw_ostream.h"
127using namespace clang;
130template <
typename T,
typename Allocator>
131static StringRef
bytes(
const std::vector<T, Allocator> &
v) {
132 if (
v.empty())
return StringRef();
133 return StringRef(
reinterpret_cast<const char*
>(&
v[0]),
134 sizeof(
T) *
v.size());
139 return StringRef(
reinterpret_cast<const char*
>(
v.data()),
140 sizeof(
T) *
v.size());
143static std::string
bytes(
const std::vector<bool> &
V) {
145 Str.reserve(
V.size() / 8);
146 for (
unsigned I = 0,
E =
V.size(); I <
E;) {
148 for (
unsigned Bit = 0; Bit < 8 && I <
E; ++Bit, ++I)
161#define TYPE_BIT_CODE(CLASS_ID, CODE_ID, CODE_VALUE) \
162 case Type::CLASS_ID: return TYPE_##CODE_ID;
163#include "clang/Serialization/TypeBitCodes.def"
165 llvm_unreachable(
"shouldn't be serializing a builtin type this way");
167 llvm_unreachable(
"bad type kind");
172struct AffectingModuleMaps {
173 llvm::DenseSet<FileID> DefinitionFileIDs;
174 llvm::DenseSet<const FileEntry *> DefinitionFiles;
177std::optional<AffectingModuleMaps>
190 enum AffectedReason :
bool {
191 AR_TextualHeader = 0,
192 AR_ImportOrTextualHeader = 1,
194 auto AssignMostImportant = [](AffectedReason &LHS, AffectedReason RHS) {
195 LHS = std::max(LHS, RHS);
197 llvm::DenseMap<FileID, AffectedReason> ModuleMaps;
198 llvm::DenseMap<const Module *, AffectedReason> ProcessedModules;
199 auto CollectModuleMapsForHierarchy = [&](
const Module *M,
200 AffectedReason Reason) {
206 if (
auto [It, Inserted] = ProcessedModules.insert({M, Reason});
207 !Inserted && Reason <= It->second) {
213 std::queue<const Module *> Q;
216 const Module *Mod = Q.front();
222 AssignMostImportant(ModuleMaps[F], Reason);
227 AssignMostImportant(ModuleMaps[UniqF], Reason);
236 CollectModuleMapsForHierarchy(RootModule, AR_ImportOrTextualHeader);
238 std::queue<const Module *> Q;
241 const Module *CurrentModule = Q.front();
245 CollectModuleMapsForHierarchy(ImportedModule, AR_ImportOrTextualHeader);
247 CollectModuleMapsForHierarchy(UndeclaredModule, AR_ImportOrTextualHeader);
261 for (
unsigned UID = 0, LastUID = FilesByUID.size(); UID != LastUID; ++UID) {
275 if (
const Module *M = KH.getModule())
276 CollectModuleMapsForHierarchy(M, AR_TextualHeader);
297 llvm::DenseSet<const FileEntry *> ModuleFileEntries;
298 llvm::DenseSet<FileID> ModuleFileIDs;
299 for (
auto [FID, Reason] : ModuleMaps) {
300 if (Reason == AR_ImportOrTextualHeader)
301 ModuleFileIDs.insert(FID);
302 if (
auto *FE =
SM.getFileEntryForID(FID))
303 ModuleFileEntries.insert(FE);
306 AffectingModuleMaps R;
307 R.DefinitionFileIDs = std::move(ModuleFileIDs);
308 R.DefinitionFiles = std::move(ModuleFileEntries);
319 : Writer(Writer), BasicWriter(Context, Writer,
Record) {}
322 if (
T.hasLocalNonFastQualifiers()) {
329 const Type *typePtr =
T.getTypePtr();
352#define ABSTRACT_TYPELOC(CLASS, PARENT)
353#define TYPELOC(CLASS, PARENT) \
354 void Visit##CLASS##TypeLoc(CLASS##TypeLoc TyLoc);
355#include "clang/AST/TypeLocNodes.def"
423 VisitArrayTypeLoc(TL);
427 VisitArrayTypeLoc(TL);
431 VisitArrayTypeLoc(TL);
434void TypeLocWriter::VisitDependentSizedArrayTypeLoc(
436 VisitArrayTypeLoc(TL);
439void TypeLocWriter::VisitDependentAddressSpaceTypeLoc(
443 addSourceLocation(
range.getBegin());
444 addSourceLocation(
range.getEnd());
448void TypeLocWriter::VisitDependentSizedExtVectorTypeLoc(
457void TypeLocWriter::VisitDependentVectorTypeLoc(
469 addSourceLocation(
range.getBegin());
470 addSourceLocation(
range.getEnd());
475void TypeLocWriter::VisitDependentSizedMatrixTypeLoc(
479 addSourceLocation(
range.getBegin());
480 addSourceLocation(
range.getEnd());
491 for (
unsigned i = 0, e = TL.
getNumParams(); i != e; ++i)
496 VisitFunctionTypeLoc(TL);
500 VisitFunctionTypeLoc(TL);
565void TypeLocWriter::VisitAutoTypeLoc(
AutoTypeLoc TL) {
570 Record.AddConceptReference(CR);
576void TypeLocWriter::VisitDeducedTemplateSpecializationTypeLoc(
585void TypeLocWriter::VisitEnumTypeLoc(
EnumTypeLoc TL) {
601void TypeLocWriter::VisitHLSLAttributedResourceTypeLoc(
610void TypeLocWriter::VisitSubstTemplateTypeParmTypeLoc(
615void TypeLocWriter::VisitSubstTemplateTypeParmPackTypeLoc(
620void TypeLocWriter::VisitTemplateSpecializationTypeLoc(
626 for (
unsigned i = 0, e = TL.
getNumArgs(); i != e; ++i)
655void TypeLocWriter::VisitDependentTemplateSpecializationTypeLoc(
699void TypeLocWriter::VisitPipeTypeLoc(
PipeTypeLoc TL) {
706void TypeLocWriter::VisitDependentBitIntTypeLoc(
711void ASTWriter::WriteTypeAbbrevs() {
712 using namespace llvm;
714 std::shared_ptr<BitCodeAbbrev> Abv;
717 Abv = std::make_shared<BitCodeAbbrev>();
719 Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6));
720 Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 3));
721 TypeExtQualAbbrev = Stream.EmitAbbrev(std::move(Abv));
729 llvm::BitstreamWriter &Stream,
733 Stream.EmitRecord(llvm::bitc::BLOCKINFO_CODE_SETBID,
Record);
736 if (!Name || Name[0] == 0)
740 Record.push_back(*Name++);
741 Stream.EmitRecord(llvm::bitc::BLOCKINFO_CODE_BLOCKNAME,
Record);
745 llvm::BitstreamWriter &Stream,
750 Record.push_back(*Name++);
751 Stream.EmitRecord(llvm::bitc::BLOCKINFO_CODE_SETRECORDNAME,
Record);
756#define RECORD(X) EmitRecordID(X, #X, Stream, Record)
888void ASTWriter::WriteBlockInfoBlock() {
890 Stream.EnterBlockInfoBlock();
892#define BLOCK(X) EmitBlockID(X ## _ID, #X, Stream, Record)
893#define RECORD(X) EmitRecordID(X, #X, Stream, Record)
896 BLOCK(CONTROL_BLOCK);
906 BLOCK(OPTIONS_BLOCK);
913 BLOCK(INPUT_FILES_BLOCK);
978 BLOCK(SOURCE_MANAGER_BLOCK);
986 BLOCK(PREPROCESSOR_BLOCK);
994 BLOCK(SUBMODULE_BLOCK);
1016 BLOCK(COMMENTS_BLOCK);
1020 BLOCK(DECLTYPES_BLOCK);
1024 RECORD(TYPE_BLOCK_POINTER);
1025 RECORD(TYPE_LVALUE_REFERENCE);
1026 RECORD(TYPE_RVALUE_REFERENCE);
1027 RECORD(TYPE_MEMBER_POINTER);
1028 RECORD(TYPE_CONSTANT_ARRAY);
1029 RECORD(TYPE_INCOMPLETE_ARRAY);
1030 RECORD(TYPE_VARIABLE_ARRAY);
1033 RECORD(TYPE_FUNCTION_NO_PROTO);
1034 RECORD(TYPE_FUNCTION_PROTO);
1036 RECORD(TYPE_TYPEOF_EXPR);
1040 RECORD(TYPE_OBJC_INTERFACE);
1041 RECORD(TYPE_OBJC_OBJECT_POINTER);
1044 RECORD(TYPE_SUBST_TEMPLATE_TYPE_PARM);
1045 RECORD(TYPE_UNRESOLVED_USING);
1046 RECORD(TYPE_INJECTED_CLASS_NAME);
1047 RECORD(TYPE_OBJC_OBJECT);
1048 RECORD(TYPE_TEMPLATE_TYPE_PARM);
1049 RECORD(TYPE_TEMPLATE_SPECIALIZATION);
1050 RECORD(TYPE_DEPENDENT_NAME);
1051 RECORD(TYPE_DEPENDENT_TEMPLATE_SPECIALIZATION);
1052 RECORD(TYPE_DEPENDENT_SIZED_ARRAY);
1054 RECORD(TYPE_MACRO_QUALIFIED);
1055 RECORD(TYPE_PACK_EXPANSION);
1057 RECORD(TYPE_SUBST_TEMPLATE_TYPE_PARM_PACK);
1059 RECORD(TYPE_UNARY_TRANSFORM);
1063 RECORD(TYPE_OBJC_TYPE_PARAM);
1141 BLOCK(PREPROCESSOR_DETAIL_BLOCK);
1147 BLOCK(EXTENSION_BLOCK);
1150 BLOCK(UNHASHED_CONTROL_BLOCK);
1169 return Changed | llvm::sys::path::remove_dots(
Path);
1184 assert(
Filename &&
"No file name to adjust?");
1186 if (BaseDir.empty())
1191 for (;
Filename[Pos] && Pos < BaseDir.size(); ++Pos)
1201 if (!llvm::sys::path::is_separator(
Filename[Pos])) {
1202 if (!llvm::sys::path::is_separator(BaseDir.back()))
1219std::pair<ASTFileSignature, ASTFileSignature>
1220ASTWriter::createSignature()
const {
1221 StringRef AllBytes(Buffer.data(), Buffer.size());
1224 Hasher.update(AllBytes.slice(ASTBlockRange.first, ASTBlockRange.second));
1229 Hasher.update(AllBytes.slice(0, UnhashedControlBlockRange.first));
1232 AllBytes.slice(UnhashedControlBlockRange.second, ASTBlockRange.first));
1234 Hasher.update(AllBytes.slice(ASTBlockRange.second, StringRef::npos));
1237 return std::make_pair(ASTBlockHash, Signature);
1242 Hasher.update(StringRef(Buffer.data(), Buffer.size()));
1244 assert(WritingModule);
1249 for (
auto [ExportImported, _] : WritingModule->
Exports)
1250 Hasher.update(ExportImported->Signature);
1274 for (
Module *M : TouchedTopLevelModules)
1282 for (uint8_t Byte : S) {
1283 Stream.BackpatchByte(BitNo, Byte);
1295 if (!WritingModule ||
1302 std::tie(ASTBlockHash, Signature) = createSignature();
1310void ASTWriter::writeUnhashedControlBlock(
Preprocessor &PP) {
1311 using namespace llvm;
1314 Stream.FlushToWord();
1315 UnhashedControlBlockRange.first = Stream.GetCurrentBitNo() >> 3;
1338 auto Abbrev = std::make_shared<BitCodeAbbrev>();
1340 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob));
1341 unsigned ASTBlockHashAbbrev = Stream.EmitAbbrev(std::move(Abbrev));
1344 Stream.EmitRecordWithBlob(ASTBlockHashAbbrev,
Record, Blob);
1345 ASTBlockHashOffset = Stream.GetCurrentBitNo() - Blob.size() * 8;
1349 auto Abbrev = std::make_shared<BitCodeAbbrev>();
1350 Abbrev->Add(BitCodeAbbrevOp(
SIGNATURE));
1351 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob));
1352 unsigned SignatureAbbrev = Stream.EmitAbbrev(std::move(Abbrev));
1355 Stream.EmitRecordWithBlob(SignatureAbbrev,
Record, Blob);
1356 SignatureOffset = Stream.GetCurrentBitNo() - Blob.size() * 8;
1365 if (!HSOpts.ModulesSkipDiagnosticOptions) {
1366#define DIAGOPT(Name, Bits, Default) Record.push_back(DiagOpts.Name);
1367#define ENUM_DIAGOPT(Name, Type, Bits, Default) \
1368 Record.push_back(static_cast<unsigned>(DiagOpts.get##Name()));
1369#include "clang/Basic/DiagnosticOptions.def"
1371 for (
unsigned I = 0, N = DiagOpts.
Warnings.size(); I != N; ++I)
1374 for (
unsigned I = 0, N = DiagOpts.
Remarks.size(); I != N; ++I)
1383 if (!HSOpts.ModulesSkipHeaderSearchPaths) {
1385 Record.push_back(HSOpts.UserEntries.size());
1386 for (
unsigned I = 0, N = HSOpts.UserEntries.size(); I != N; ++I) {
1389 Record.push_back(
static_cast<unsigned>(Entry.
Group));
1395 Record.push_back(HSOpts.SystemHeaderPrefixes.size());
1396 for (
unsigned I = 0, N = HSOpts.SystemHeaderPrefixes.size(); I != N; ++I) {
1398 Record.push_back(HSOpts.SystemHeaderPrefixes[I].IsSystemHeader);
1402 Record.push_back(HSOpts.VFSOverlayFiles.size());
1403 for (StringRef VFSOverlayFile : HSOpts.VFSOverlayFiles)
1409 if (!HSOpts.ModulesSkipPragmaDiagnosticMappings)
1410 WritePragmaDiagnosticMappings(Diags, WritingModule);
1415 auto Abbrev = std::make_shared<BitCodeAbbrev>();
1417 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32));
1418 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob));
1419 unsigned HSUsageAbbrevCode = Stream.EmitAbbrev(std::move(Abbrev));
1421 HSEntryUsage.size()};
1422 Stream.EmitRecordWithBlob(HSUsageAbbrevCode,
Record,
bytes(HSEntryUsage));
1428 auto Abbrev = std::make_shared<BitCodeAbbrev>();
1429 Abbrev->Add(BitCodeAbbrevOp(
VFS_USAGE));
1430 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32));
1431 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob));
1432 unsigned VFSUsageAbbrevCode = Stream.EmitAbbrev(std::move(Abbrev));
1434 Stream.EmitRecordWithBlob(VFSUsageAbbrevCode,
Record,
bytes(VFSUsage));
1439 UnhashedControlBlockRange.second = Stream.GetCurrentBitNo() >> 3;
1443void ASTWriter::WriteControlBlock(
Preprocessor &PP, StringRef isysroot) {
1444 using namespace llvm;
1453 auto MetadataAbbrev = std::make_shared<BitCodeAbbrev>();
1454 MetadataAbbrev->Add(BitCodeAbbrevOp(
METADATA));
1455 MetadataAbbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 16));
1456 MetadataAbbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 16));
1457 MetadataAbbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 16));
1458 MetadataAbbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 16));
1459 MetadataAbbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1));
1461 MetadataAbbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1));
1462 MetadataAbbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1));
1463 MetadataAbbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1));
1464 MetadataAbbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob));
1465 unsigned MetadataAbbrevCode = Stream.EmitAbbrev(std::move(MetadataAbbrev));
1466 assert((!WritingModule || isysroot.empty()) &&
1467 "writing module as a relocatable PCH?");
1472 CLANG_VERSION_MAJOR,
1473 CLANG_VERSION_MINOR,
1477 ASTHasCompilerErrors};
1478 Stream.EmitRecordWithBlob(MetadataAbbrevCode,
Record,
1482 if (WritingModule) {
1484 auto Abbrev = std::make_shared<BitCodeAbbrev>();
1486 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob));
1487 unsigned AbbrevCode = Stream.EmitAbbrev(std::move(Abbrev));
1489 Stream.EmitRecordWithBlob(AbbrevCode,
Record, WritingModule->
Name);
1492 if (WritingModule && WritingModule->
Directory) {
1497 BaseDir.assign(CWD->getName());
1512 auto Abbrev = std::make_shared<BitCodeAbbrev>();
1514 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob));
1515 unsigned AbbrevCode = Stream.EmitAbbrev(std::move(Abbrev));
1518 Stream.EmitRecordWithBlob(AbbrevCode,
Record, BaseDir);
1522 BaseDirectory.assign(BaseDir.begin(), BaseDir.end());
1523 }
else if (!isysroot.empty()) {
1525 BaseDirectory = std::string(isysroot);
1534 ? Map.getModuleMapFileForUniquing(WritingModule)
1535 ->getNameAsRequested()
1540 if (
auto *AdditionalModMaps =
1541 Map.getAdditionalModuleMapFiles(WritingModule)) {
1542 Record.push_back(AdditionalModMaps->size());
1544 AdditionalModMaps->end());
1559 auto Abbrev = std::make_shared<BitCodeAbbrev>();
1560 Abbrev->Add(BitCodeAbbrevOp(
IMPORT));
1561 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 3));
1562 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6));
1563 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6));
1564 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1));
1565 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6));
1566 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6));
1567 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6));
1568 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob));
1569 unsigned AbbrevCode = Stream.EmitAbbrev(std::move(Abbrev));
1575 if (!M.isDirectlyImported())
1585 Record.push_back(M.StandardCXXModule);
1589 if (M.StandardCXXModule) {
1604 Stream.EmitRecordWithBlob(AbbrevCode,
Record, Blob);
1614#define LANGOPT(Name, Bits, Default, Description) \
1615 Record.push_back(LangOpts.Name);
1616#define ENUM_LANGOPT(Name, Type, Bits, Default, Description) \
1617 Record.push_back(static_cast<unsigned>(LangOpts.get##Name()));
1618#include "clang/Basic/LangOptions.def"
1619#define SANITIZER(NAME, ID) \
1620 Record.push_back(LangOpts.Sanitize.has(SanitizerKind::ID));
1621#include "clang/Basic/Sanitizers.def"
1661 for (
unsigned I = 0, N = TargetOpts.
Features.size(); I != N; ++I) {
1701 bool WriteMacros = !SkipMacros;
1702 Record.push_back(WriteMacros);
1706 for (
unsigned I = 0, N = PPOpts.
Macros.size(); I != N; ++I) {
1714 for (
unsigned I = 0, N = PPOpts.
Includes.size(); I != N; ++I)
1719 for (
unsigned I = 0, N = PPOpts.
MacroIncludes.size(); I != N; ++I)
1735 auto FileAbbrev = std::make_shared<BitCodeAbbrev>();
1737 FileAbbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6));
1738 FileAbbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob));
1739 unsigned FileAbbrevCode = Stream.EmitAbbrev(std::move(FileAbbrev));
1758struct InputFileEntry {
1762 bool BufferOverridden;
1777 assert(IncludeFID.
isValid() &&
"IncludeLoc in invalid file");
1778 if (!IsSLocAffecting[IncludeFID.ID])
1786 using namespace llvm;
1791 auto IFAbbrev = std::make_shared<BitCodeAbbrev>();
1793 IFAbbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6));
1794 IFAbbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 12));
1795 IFAbbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 32));
1796 IFAbbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1));
1797 IFAbbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1));
1798 IFAbbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1));
1799 IFAbbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1));
1800 IFAbbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 16));
1801 IFAbbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob));
1802 unsigned IFAbbrevCode = Stream.EmitAbbrev(std::move(IFAbbrev));
1805 auto IFHAbbrev = std::make_shared<BitCodeAbbrev>();
1807 IFHAbbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32));
1808 IFHAbbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32));
1809 unsigned IFHAbbrevCode = Stream.EmitAbbrev(std::move(IFHAbbrev));
1811 uint64_t InputFilesOffsetBase = Stream.GetCurrentBitNo();
1814 std::vector<InputFileEntry> UserFiles;
1815 std::vector<InputFileEntry> SystemFiles;
1819 assert(&SourceMgr.
getSLocEntry(FileID::get(I)) == SLoc);
1826 if (!
Cache->OrigEntry)
1830 if (!IsSLocFileEntryAffecting[I])
1833 InputFileEntry Entry(*
Cache->OrigEntry);
1834 Entry.IsSystemFile =
isSystem(
File.getFileCharacteristic());
1835 Entry.IsTransient =
Cache->IsTransient;
1836 Entry.BufferOverridden =
Cache->BufferOverridden;
1839 Entry.IsTopLevel = IncludeFileID.
isInvalid() || IncludeFileID.ID < 0 ||
1840 !IsSLocFileEntryAffecting[IncludeFileID.ID];
1847 auto MemBuff =
Cache->getBufferIfLoaded();
1849 ContentHash = xxh3_64bits(MemBuff->getBuffer());
1852 << Entry.File.getName();
1854 Entry.ContentHash[0] =
uint32_t(ContentHash);
1855 Entry.ContentHash[1] =
uint32_t(ContentHash >> 32);
1856 if (Entry.IsSystemFile)
1857 SystemFiles.push_back(Entry);
1859 UserFiles.push_back(Entry);
1863 auto SortedFiles = llvm::concat<InputFileEntry>(std::move(UserFiles),
1864 std::move(SystemFiles));
1866 unsigned UserFilesNum = 0;
1868 std::vector<uint64_t> InputFileOffsets;
1869 for (
const auto &Entry : SortedFiles) {
1870 uint32_t &InputFileID = InputFileIDs[Entry.File];
1871 if (InputFileID != 0)
1875 InputFileOffsets.push_back(Stream.GetCurrentBitNo() - InputFilesOffsetBase);
1877 InputFileID = InputFileOffsets.size();
1879 if (!Entry.IsSystemFile)
1891 if (Name == NameAsRequested)
1894 RecordData::value_type
Record[] = {
1896 InputFileOffsets.size(),
1899 Entry.BufferOverridden,
1903 NameAsRequested.size()};
1905 Stream.EmitRecordWithBlob(IFAbbrevCode,
Record,
1906 (NameAsRequested + Name).str());
1912 Entry.ContentHash[1]};
1913 Stream.EmitRecordWithAbbrev(IFHAbbrevCode,
Record);
1920 auto OffsetsAbbrev = std::make_shared<BitCodeAbbrev>();
1922 OffsetsAbbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6));
1923 OffsetsAbbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6));
1925 OffsetsAbbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob));
1926 unsigned OffsetsAbbrevCode = Stream.EmitAbbrev(std::move(OffsetsAbbrev));
1930 InputFileOffsets.size(), UserFilesNum};
1931 Stream.EmitRecordWithBlob(OffsetsAbbrevCode,
Record,
bytes(InputFileOffsets));
1941 using namespace llvm;
1943 auto Abbrev = std::make_shared<BitCodeAbbrev>();
1945 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8));
1946 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8));
1947 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 3));
1948 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1));
1950 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6));
1951 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8));
1952 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 24));
1953 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8));
1954 return Stream.EmitAbbrev(std::move(Abbrev));
1960 using namespace llvm;
1962 auto Abbrev = std::make_shared<BitCodeAbbrev>();
1964 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8));
1965 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8));
1966 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 3));
1967 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1));
1968 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob));
1969 return Stream.EmitAbbrev(std::move(Abbrev));
1976 using namespace llvm;
1978 auto Abbrev = std::make_shared<BitCodeAbbrev>();
1982 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8));
1983 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob));
1984 return Stream.EmitAbbrev(std::move(Abbrev));
1990 using namespace llvm;
1992 auto Abbrev = std::make_shared<BitCodeAbbrev>();
1994 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8));
1995 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8));
1996 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6));
1997 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6));
1998 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1));
1999 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6));
2000 return Stream.EmitAbbrev(std::move(Abbrev));
2005static std::pair<unsigned, unsigned>
2007 llvm::encodeULEB128(KeyLen, Out);
2008 llvm::encodeULEB128(DataLen, Out);
2009 return std::make_pair(KeyLen, DataLen);
2015 class HeaderFileInfoTrait {
2019 HeaderFileInfoTrait(
ASTWriter &Writer) : Writer(Writer) {}
2026 using key_type_ref =
const key_type &;
2028 using UnresolvedModule =
2029 llvm::PointerIntPair<Module *, 2, ModuleMap::ModuleHeaderRole>;
2035 : HFI(HFI), AlreadyIncluded(AlreadyIncluded),
2039 bool AlreadyIncluded;
2043 using data_type_ref =
const data_type &;
2052 uint8_t buf[
sizeof(key.Size) +
sizeof(key.ModTime)];
2053 memcpy(buf, &key.Size,
sizeof(key.Size));
2054 memcpy(buf +
sizeof(key.Size), &key.ModTime,
sizeof(key.ModTime));
2055 return llvm::xxh3_64bits(buf);
2058 std::pair<unsigned, unsigned>
2059 EmitKeyDataLength(raw_ostream& Out, key_type_ref key, data_type_ref
Data) {
2060 unsigned KeyLen = key.Filename.size() + 1 + 8 + 8;
2062 for (
auto ModInfo :
Data.KnownHeaders)
2065 if (
Data.Unresolved.getPointer())
2070 void EmitKey(raw_ostream& Out, key_type_ref key,
unsigned KeyLen) {
2071 using namespace llvm::support;
2073 endian::Writer
LE(Out, llvm::endianness::little);
2078 Out.write(key.Filename.data(), KeyLen);
2081 void EmitData(raw_ostream &Out, key_type_ref key,
2082 data_type_ref
Data,
unsigned DataLen) {
2083 using namespace llvm::support;
2085 endian::Writer
LE(Out, llvm::endianness::little);
2086 uint64_t Start = Out.tell(); (void)Start;
2088 unsigned char Flags = (
Data.AlreadyIncluded << 6)
2089 | (
Data.HFI.isImport << 5)
2091 Data.HFI.isPragmaOnce << 4)
2092 | (
Data.HFI.DirInfo << 1);
2093 LE.write<uint8_t>(Flags);
2095 if (
Data.HFI.LazyControllingMacro.isID())
2104 assert((
Value >> 3) == ModID &&
"overflow in header module info");
2109 for (
auto ModInfo :
Data.KnownHeaders)
2110 EmitModule(ModInfo.getModule(), ModInfo.getRole());
2111 if (
Data.Unresolved.getPointer())
2112 EmitModule(
Data.Unresolved.getPointer(),
Data.Unresolved.getInt());
2114 assert(Out.tell() - Start == DataLen &&
"Wrong data length");
2123void ASTWriter::WriteHeaderSearch(
const HeaderSearch &HS) {
2124 HeaderFileInfoTrait GeneratorTrait(*
this);
2125 llvm::OnDiskChainedHashTableGenerator<HeaderFileInfoTrait>
Generator;
2127 unsigned NumHeaderSearchEntries = 0;
2134 if (WritingModule) {
2136 while (!Worklist.empty()) {
2137 Module *M = Worklist.pop_back_val();
2154 if (!
U.Size || (!
U.ModTime && IncludeTimestamps)) {
2155 PP->
Diag(
U.FileNameLoc, diag::err_module_no_size_mtime_for_header)
2163 llvm::sys::path::append(
Filename,
U.FileName);
2166 StringRef FilenameDup = strdup(
Filename.c_str());
2167 SavedStrings.push_back(FilenameDup.data());
2169 HeaderFileInfoTrait::key_type Key = {
2170 FilenameDup, *
U.Size, IncludeTimestamps ? *
U.ModTime : 0};
2171 HeaderFileInfoTrait::data_type
Data = {
2176 ++NumHeaderSearchEntries;
2179 Worklist.append(SubmodulesRange.begin(), SubmodulesRange.end());
2189 for (
unsigned UID = 0, LastUID = FilesByUID.size(); UID != LastUID; ++UID) {
2208 Filename = StringRef(strdup(FilenameTmp.c_str()));
2209 SavedStrings.push_back(
Filename.data());
2214 HeaderFileInfoTrait::key_type Key = {
2217 HeaderFileInfoTrait::data_type
Data = {
2221 ++NumHeaderSearchEntries;
2228 using namespace llvm::support;
2230 llvm::raw_svector_ostream Out(TableData);
2232 endian::write<uint32_t>(Out, 0, llvm::endianness::little);
2233 BucketOffset =
Generator.Emit(Out, GeneratorTrait);
2237 using namespace llvm;
2239 auto Abbrev = std::make_shared<BitCodeAbbrev>();
2241 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32));
2242 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32));
2243 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32));
2244 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob));
2245 unsigned TableAbbrev = Stream.EmitAbbrev(std::move(Abbrev));
2249 NumHeaderSearchEntries, TableData.size()};
2250 Stream.EmitRecordWithBlob(TableAbbrev,
Record, TableData);
2253 for (
unsigned I = 0, N = SavedStrings.size(); I != N; ++I)
2254 free(
const_cast<char *
>(SavedStrings[I]));
2257static void emitBlob(llvm::BitstreamWriter &Stream, StringRef Blob,
2258 unsigned SLocBufferBlobCompressedAbbrv,
2259 unsigned SLocBufferBlobAbbrv) {
2260 using RecordDataType = ASTWriter::RecordData::value_type;
2265 if (llvm::compression::zstd::isAvailable()) {
2266 llvm::compression::zstd::compress(
2267 llvm::arrayRefFromStringRef(Blob.drop_back(1)), CompressedBuffer, 9);
2269 Stream.EmitRecordWithBlob(SLocBufferBlobCompressedAbbrv,
Record,
2270 llvm::toStringRef(CompressedBuffer));
2273 if (llvm::compression::zlib::isAvailable()) {
2274 llvm::compression::zlib::compress(
2275 llvm::arrayRefFromStringRef(Blob.drop_back(1)), CompressedBuffer);
2277 Stream.EmitRecordWithBlob(SLocBufferBlobCompressedAbbrv,
Record,
2278 llvm::toStringRef(CompressedBuffer));
2283 Stream.EmitRecordWithBlob(SLocBufferBlobAbbrv,
Record, Blob);
2294void ASTWriter::WriteSourceManagerBlock(
SourceManager &SourceMgr) {
2299 const uint64_t SourceManagerBlockOffset = Stream.GetCurrentBitNo();
2305 unsigned SLocBufferBlobCompressedAbbrv =
2311 std::vector<uint32_t> SLocEntryOffsets;
2312 uint64_t SLocEntryOffsetsBase = Stream.GetCurrentBitNo();
2318 FileID FID = FileID::get(I);
2322 uint64_t Offset = Stream.GetCurrentBitNo() - SLocEntryOffsetsBase;
2323 assert((Offset >> 32) == 0 &&
"SLocEntry offset too large");
2329 if (
Cache->OrigEntry) {
2342 if (!IsSLocAffecting[I])
2344 SLocEntryOffsets.push_back(Offset);
2348 Record.push_back(
File.getFileCharacteristic());
2351 bool EmitBlob =
false;
2354 "Writing to AST an overridden file is not supported");
2357 assert(InputFileIDs[*Content->
OrigEntry] != 0 &&
"Missed file entry");
2360 Record.push_back(getAdjustedNumCreatedFIDs(FID));
2362 FileDeclIDsTy::iterator FDI = FileDeclIDs.find(FID);
2363 if (FDI != FileDeclIDs.end()) {
2364 Record.push_back(FDI->second->FirstDeclIndex);
2365 Record.push_back(FDI->second->DeclIDs.size());
2371 Stream.EmitRecordWithAbbrev(SLocFileAbbrv,
Record);
2382 std::optional<llvm::MemoryBufferRef> Buffer = Content->
getBufferOrNone(
2384 StringRef Name = Buffer ? Buffer->getBufferIdentifier() :
"";
2385 Stream.EmitRecordWithBlob(SLocBufferAbbrv,
Record,
2386 StringRef(Name.data(), Name.size() + 1));
2393 std::optional<llvm::MemoryBufferRef> Buffer = Content->
getBufferOrNone(
2396 Buffer = llvm::MemoryBufferRef(
"<<<INVALID BUFFER>>>",
"");
2397 StringRef Blob(Buffer->getBufferStart(), Buffer->getBufferSize() + 1);
2398 emitBlob(Stream, Blob, SLocBufferBlobCompressedAbbrv,
2399 SLocBufferBlobAbbrv);
2404 SLocEntryOffsets.push_back(Offset);
2420 Record.push_back(getAdjustedOffset(NextOffset - SLoc->
getOffset()) - 1);
2421 Stream.EmitRecordWithAbbrev(SLocExpansionAbbrv,
Record);
2427 if (SLocEntryOffsets.empty())
2432 using namespace llvm;
2434 auto Abbrev = std::make_shared<BitCodeAbbrev>();
2436 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 16));
2437 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 16));
2438 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 32));
2439 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob));
2440 unsigned SLocOffsetsAbbrev = Stream.EmitAbbrev(std::move(Abbrev));
2442 RecordData::value_type
Record[] = {
2445 SLocEntryOffsetsBase - SourceManagerBlockOffset};
2446 Stream.EmitRecordWithBlob(SLocOffsetsAbbrev,
Record,
2447 bytes(SLocEntryOffsets));
2458 llvm::DenseMap<int, int> FilenameMap;
2459 FilenameMap[-1] = -1;
2460 for (
const auto &L : LineTable) {
2463 for (
auto &LE : L.second) {
2464 if (FilenameMap.insert(std::make_pair(
LE.FilenameID,
2465 FilenameMap.size() - 1)).second)
2472 for (
const auto &L : LineTable) {
2480 Record.push_back(L.second.size());
2481 for (
const auto &LE : L.second) {
2484 Record.push_back(FilenameMap[
LE.FilenameID]);
2485 Record.push_back((
unsigned)
LE.FileKind);
2486 Record.push_back(
LE.IncludeOffset);
2501 if (MI->isBuiltinMacro())
2517void ASTWriter::WritePreprocessor(
const Preprocessor &PP,
bool IsModule) {
2518 uint64_t MacroOffsetsBase = Stream.GetCurrentBitNo();
2522 WritePreprocessorDetail(*PPRec, MacroOffsetsBase);
2537 if (AssumeNonNullLoc.
isValid()) {
2551 Record.push_back(SkipInfo->FoundNonSkipPortion);
2552 Record.push_back(SkipInfo->FoundElse);
2559 Record.push_back(Cond.WasSkipping);
2560 Record.push_back(Cond.FoundNonSkip);
2561 Record.push_back(Cond.FoundElse);
2591 if (
Id.second->hadMacroDefinition() &&
2592 (!
Id.second->isFromAST() ||
2593 Id.second->hasChangedSinceDeserialization()))
2594 MacroIdentifiers.push_back(
Id.second);
2597 llvm::sort(MacroIdentifiers, llvm::deref<std::less<>>());
2603 uint64_t StartOffset = Stream.GetCurrentBitNo() - MacroOffsetsBase;
2604 assert((StartOffset >> 32) == 0 &&
"Macro identifiers offset too large");
2607 bool EmittedModuleMacros =
false;
2624 if (
auto *DefMD = dyn_cast<DefMacroDirective>(MD)) {
2626 }
else if (
auto *VisMD = dyn_cast<VisibilityMacroDirective>(MD)) {
2627 Record.push_back(VisMD->isPublic());
2629 ModuleMacroRecord.push_back(getSubmoduleID(WritingModule));
2632 ModuleMacroRecord.clear();
2633 EmittedModuleMacros =
true;
2643 if (
auto *DefMD = dyn_cast<DefMacroDirective>(MD)) {
2645 }
else if (
auto *VisMD = dyn_cast<VisibilityMacroDirective>(MD)) {
2646 Record.push_back(VisMD->isPublic());
2653 llvm::DenseMap<ModuleMacro *, unsigned> Visits;
2654 while (!Worklist.empty()) {
2655 auto *
Macro = Worklist.pop_back_val();
2658 ModuleMacroRecord.push_back(getSubmoduleID(
Macro->getOwningModule()));
2660 for (
auto *M :
Macro->overrides())
2661 ModuleMacroRecord.push_back(getSubmoduleID(M->getOwningModule()));
2664 ModuleMacroRecord.clear();
2667 for (
auto *M :
Macro->overrides())
2668 if (++Visits[M] == M->getNumOverridingMacros())
2669 Worklist.push_back(M);
2671 EmittedModuleMacros =
true;
2674 if (
Record.empty() && !EmittedModuleMacros)
2677 IdentMacroDirectivesOffsetMap[Name] = StartOffset;
2688 std::vector<uint32_t> MacroOffsets;
2690 for (
unsigned I = 0, N = MacroInfosToEmit.size(); I != N; ++I) {
2695 if (ID < FirstMacroID) {
2696 assert(0 &&
"Loaded MacroInfo entered MacroInfosToEmit ?");
2701 unsigned Index =
ID - FirstMacroID;
2702 if (Index >= MacroOffsets.size())
2703 MacroOffsets.resize(Index + 1);
2705 uint64_t Offset = Stream.GetCurrentBitNo() - MacroOffsetsBase;
2706 assert((Offset >> 32) == 0 &&
"Macro offset too large");
2707 MacroOffsets[Index] = Offset;
2734 Stream.EmitRecord(Code,
Record);
2738 for (
unsigned TokNo = 0, e = MI->
getNumTokens(); TokNo != e; ++TokNo) {
2753 using namespace llvm;
2755 auto Abbrev = std::make_shared<BitCodeAbbrev>();
2757 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32));
2758 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32));
2759 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 32));
2760 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob));
2762 unsigned MacroOffsetAbbrev = Stream.EmitAbbrev(std::move(Abbrev));
2766 MacroOffsetsBase - ASTBlockStartOffset};
2767 Stream.EmitRecordWithBlob(MacroOffsetAbbrev,
Record,
bytes(MacroOffsets));
2772 uint64_t MacroOffsetsBase) {
2782 unsigned NumPreprocessingRecords = 0;
2783 using namespace llvm;
2786 unsigned InclusionAbbrev = 0;
2788 auto Abbrev = std::make_shared<BitCodeAbbrev>();
2790 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32));
2791 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1));
2792 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 2));
2793 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1));
2794 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob));
2795 InclusionAbbrev = Stream.EmitAbbrev(std::move(Abbrev));
2798 unsigned FirstPreprocessorEntityID
2799 = (Chain ? PPRec.getNumLoadedPreprocessedEntities() : 0)
2801 unsigned NextPreprocessorEntityID = FirstPreprocessorEntityID;
2806 (void)++
E, ++NumPreprocessingRecords, ++NextPreprocessorEntityID) {
2809 uint64_t Offset = Stream.GetCurrentBitNo() - MacroOffsetsBase;
2810 assert((Offset >> 32) == 0 &&
"Preprocessed entity offset too large");
2811 SourceRange R = getAdjustedRange((*E)->getSourceRange());
2812 PreprocessedEntityOffsets.emplace_back(
2816 if (
auto *MD = dyn_cast<MacroDefinitionRecord>(*
E)) {
2818 MacroDefinitions[MD] = NextPreprocessorEntityID;
2825 if (
auto *ME = dyn_cast<MacroExpansion>(*
E)) {
2826 Record.push_back(ME->isBuiltinMacro());
2827 if (ME->isBuiltinMacro())
2830 Record.push_back(MacroDefinitions[ME->getDefinition()]);
2835 if (
auto *ID = dyn_cast<InclusionDirective>(*
E)) {
2837 Record.push_back(
ID->getFileName().size());
2838 Record.push_back(
ID->wasInQuotes());
2839 Record.push_back(
static_cast<unsigned>(
ID->getKind()));
2840 Record.push_back(
ID->importedModule());
2842 Buffer +=
ID->getFileName();
2846 Buffer +=
ID->getFile()->getName();
2847 Stream.EmitRecordWithBlob(InclusionAbbrev,
Record, Buffer);
2851 llvm_unreachable(
"Unhandled PreprocessedEntity in ASTWriter");
2856 if (NumPreprocessingRecords > 0) {
2857 assert(PreprocessedEntityOffsets.size() == NumPreprocessingRecords);
2860 using namespace llvm;
2862 auto Abbrev = std::make_shared<BitCodeAbbrev>();
2864 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32));
2865 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob));
2866 unsigned PPEOffsetAbbrev = Stream.EmitAbbrev(std::move(Abbrev));
2869 FirstPreprocessorEntityID -
2871 Stream.EmitRecordWithBlob(PPEOffsetAbbrev,
Record,
2872 bytes(PreprocessedEntityOffsets));
2877 if (SkippedRanges.size() > 0) {
2878 std::vector<PPSkippedRange> SerializedSkippedRanges;
2879 SerializedSkippedRanges.reserve(SkippedRanges.size());
2880 for (
auto const&
Range : SkippedRanges)
2881 SerializedSkippedRanges.emplace_back(
2885 using namespace llvm;
2886 auto Abbrev = std::make_shared<BitCodeAbbrev>();
2888 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob));
2889 unsigned PPESkippedRangeAbbrev = Stream.EmitAbbrev(std::move(Abbrev));
2893 Stream.EmitRecordWithBlob(PPESkippedRangeAbbrev,
Record,
2894 bytes(SerializedSkippedRanges));
2902 auto Known = SubmoduleIDs.find(Mod);
2903 if (Known != SubmoduleIDs.end())
2904 return Known->second;
2907 if (Top != WritingModule &&
2909 !Top->fullModuleNameIs(StringRef(
getLangOpts().CurrentModule))))
2912 return SubmoduleIDs[Mod] = NextSubmoduleID++;
2915unsigned ASTWriter::getSubmoduleID(
Module *Mod) {
2928 unsigned ChildModules = 0;
2932 return ChildModules + 1;
2935void ASTWriter::WriteSubmodules(
Module *WritingModule,
ASTContext *Context) {
2940 using namespace llvm;
2942 auto Abbrev = std::make_shared<BitCodeAbbrev>();
2944 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6));
2945 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6));
2946 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 4));
2947 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8));
2948 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 4));
2949 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1));
2950 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1));
2951 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1));
2952 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1));
2953 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1));
2954 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1));
2955 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1));
2956 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1));
2957 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1));
2958 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1));
2959 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob));
2960 unsigned DefinitionAbbrev = Stream.EmitAbbrev(std::move(Abbrev));
2962 Abbrev = std::make_shared<BitCodeAbbrev>();
2964 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob));
2965 unsigned UmbrellaAbbrev = Stream.EmitAbbrev(std::move(Abbrev));
2967 Abbrev = std::make_shared<BitCodeAbbrev>();
2969 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob));
2970 unsigned HeaderAbbrev = Stream.EmitAbbrev(std::move(Abbrev));
2972 Abbrev = std::make_shared<BitCodeAbbrev>();
2974 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob));
2975 unsigned TopHeaderAbbrev = Stream.EmitAbbrev(std::move(Abbrev));
2977 Abbrev = std::make_shared<BitCodeAbbrev>();
2979 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob));
2980 unsigned UmbrellaDirAbbrev = Stream.EmitAbbrev(std::move(Abbrev));
2982 Abbrev = std::make_shared<BitCodeAbbrev>();
2984 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1));
2985 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob));
2986 unsigned RequiresAbbrev = Stream.EmitAbbrev(std::move(Abbrev));
2988 Abbrev = std::make_shared<BitCodeAbbrev>();
2990 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob));
2991 unsigned ExcludedHeaderAbbrev = Stream.EmitAbbrev(std::move(Abbrev));
2993 Abbrev = std::make_shared<BitCodeAbbrev>();
2995 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob));
2996 unsigned TextualHeaderAbbrev = Stream.EmitAbbrev(std::move(Abbrev));
2998 Abbrev = std::make_shared<BitCodeAbbrev>();
3000 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob));
3001 unsigned PrivateHeaderAbbrev = Stream.EmitAbbrev(std::move(Abbrev));
3003 Abbrev = std::make_shared<BitCodeAbbrev>();
3005 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob));
3006 unsigned PrivateTextualHeaderAbbrev = Stream.EmitAbbrev(std::move(Abbrev));
3008 Abbrev = std::make_shared<BitCodeAbbrev>();
3010 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1));
3011 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob));
3012 unsigned LinkLibraryAbbrev = Stream.EmitAbbrev(std::move(Abbrev));
3014 Abbrev = std::make_shared<BitCodeAbbrev>();
3016 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob));
3017 unsigned ConfigMacroAbbrev = Stream.EmitAbbrev(std::move(Abbrev));
3019 Abbrev = std::make_shared<BitCodeAbbrev>();
3021 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6));
3022 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob));
3023 unsigned ConflictAbbrev = Stream.EmitAbbrev(std::move(Abbrev));
3025 Abbrev = std::make_shared<BitCodeAbbrev>();
3027 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob));
3028 unsigned ExportAsAbbrev = Stream.EmitAbbrev(std::move(Abbrev));
3031 RecordData::value_type
Record[] = {
3037 std::queue<Module *> Q;
3038 Q.push(WritingModule);
3039 while (!Q.empty()) {
3042 unsigned ID = getSubmoduleID(Mod);
3046 assert(SubmoduleIDs[Mod->
Parent] &&
"Submodule parent not written?");
3047 ParentID = SubmoduleIDs[Mod->
Parent];
3054 FileID UnadjustedInferredFID;
3057 int InferredFID = getAdjustedFileID(UnadjustedInferredFID).getOpaqueValue();
3064 (RecordData::value_type)Mod->
Kind,
3066 (RecordData::value_type)InferredFID,
3077 Stream.EmitRecordWithBlob(DefinitionAbbrev,
Record, Mod->
Name);
3083 Stream.EmitRecordWithBlob(RequiresAbbrev,
Record, R.FeatureName);
3087 if (std::optional<Module::Header> UmbrellaHeader =
3090 Stream.EmitRecordWithBlob(UmbrellaAbbrev,
Record,
3091 UmbrellaHeader->NameAsWritten);
3092 }
else if (std::optional<Module::DirectoryName> UmbrellaDir =
3095 Stream.EmitRecordWithBlob(UmbrellaDirAbbrev,
Record,
3096 UmbrellaDir->NameAsWritten);
3101 unsigned RecordKind;
3112 for (
const auto &HL : HeaderLists) {
3113 RecordData::value_type
Record[] = {HL.RecordKind};
3114 for (
const auto &H : Mod->
getHeaders(HL.HeaderKind))
3115 Stream.EmitRecordWithBlob(HL.Abbrev,
Record, H.NameAsWritten);
3124 Stream.EmitRecordWithBlob(TopHeaderAbbrev,
Record, HeaderName);
3132 Record.push_back(getSubmoduleID(I));
3140 Record.push_back(getSubmoduleID(I));
3147 for (
const auto &
E : Mod->
Exports) {
3150 Record.push_back(getSubmoduleID(
E.getPointer()));
3166 Stream.EmitRecordWithBlob(LinkLibraryAbbrev,
Record, LL.Library);
3174 getSubmoduleID(
C.Other)};
3175 Stream.EmitRecordWithBlob(ConflictAbbrev,
Record,
C.Message);
3181 Stream.EmitRecordWithBlob(ConfigMacroAbbrev,
Record, CM);
3208 assert((NextSubmoduleID - FirstSubmoduleID ==
3210 "Wrong # of submodules; found a reference to a non-local, "
3211 "non-imported submodule?");
3216 llvm::SmallDenseMap<const DiagnosticsEngine::DiagState *, unsigned, 64>
3218 unsigned CurrID = 0;
3221 auto EncodeDiagStateFlags =
3222 [](
const DiagnosticsEngine::DiagState *DS) ->
unsigned {
3225 {(
unsigned)DS->IgnoreAllWarnings, (
unsigned)DS->EnableAllWarnings,
3226 (
unsigned)DS->WarningsAsErrors, (
unsigned)DS->ErrorsAsFatal,
3227 (
unsigned)DS->SuppressSystemWarnings})
3232 unsigned Flags = EncodeDiagStateFlags(
Diag.DiagStatesByLoc.FirstDiagState);
3235 auto AddDiagState = [&](
const DiagnosticsEngine::DiagState *State,
3236 bool IncludeNonPragmaStates) {
3239 assert(Flags == EncodeDiagStateFlags(State) &&
3240 "diag state flags vary in single AST file");
3244 assert(!IncludeNonPragmaStates ||
3245 State ==
Diag.DiagStatesByLoc.FirstDiagState);
3247 unsigned &DiagStateID = DiagStateIDMap[State];
3248 Record.push_back(DiagStateID);
3250 if (DiagStateID == 0) {
3251 DiagStateID = ++CurrID;
3255 auto SizeIdx =
Record.size();
3257 for (
const auto &I : *State) {
3259 if (!I.second.isPragma() && !IncludeNonPragmaStates)
3263 if (!I.second.isPragma() &&
3266 Mappings.push_back(I);
3270 llvm::sort(Mappings, llvm::less_first());
3272 for (
const auto &I : Mappings) {
3273 Record.push_back(I.first);
3274 Record.push_back(I.second.serialize());
3281 AddDiagState(
Diag.DiagStatesByLoc.FirstDiagState, isModule);
3284 auto NumLocationsIdx =
Record.size();
3288 unsigned NumLocations = 0;
3289 for (
auto &FileIDAndFile :
Diag.DiagStatesByLoc.Files) {
3290 if (!FileIDAndFile.first.isValid() ||
3291 !FileIDAndFile.second.HasLocalTransitions)
3297 Record.push_back(FileIDAndFile.second.StateTransitions.size());
3298 for (
auto &StatePoint : FileIDAndFile.second.StateTransitions) {
3299 Record.push_back(getAdjustedOffset(StatePoint.Offset));
3300 AddDiagState(StatePoint.State,
false);
3305 Record[NumLocationsIdx] = NumLocations;
3314 AddDiagState(
Diag.DiagStatesByLoc.CurDiagState,
false);
3327 IdxRef =
TypeIdx(0, NextTypeID++);
3331 assert(Idx.
getValue() >= FirstTypeID &&
"Writing predefined type");
3335 ASTTypeWriter(Context, *
this).write(
T) - DeclTypesBlockStartOffset;
3339 if (TypeOffsets.size() == Index)
3340 TypeOffsets.emplace_back(Offset);
3341 else if (TypeOffsets.size() < Index) {
3342 TypeOffsets.resize(Index + 1);
3343 TypeOffsets[Index].set(Offset);
3345 llvm_unreachable(
"Types emitted in wrong order");
3354 auto *ND = dyn_cast<NamedDecl>(
D);
3378 uint64_t Offset = Stream.GetCurrentBitNo();
3380 for (
const auto *
D : DC->
decls()) {
3393 KindDeclPairs.push_back(
D->
getKind());
3394 KindDeclPairs.push_back(
GetDeclRef(
D).getRawValue());
3397 ++NumLexicalDeclContexts;
3399 Stream.EmitRecordWithBlob(DeclContextLexicalAbbrev,
Record,
3400 bytes(KindDeclPairs));
3404void ASTWriter::WriteTypeDeclOffsets() {
3405 using namespace llvm;
3408 auto Abbrev = std::make_shared<BitCodeAbbrev>();
3410 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32));
3411 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob));
3412 unsigned TypeOffsetAbbrev = Stream.EmitAbbrev(std::move(Abbrev));
3415 Stream.EmitRecordWithBlob(TypeOffsetAbbrev,
Record,
bytes(TypeOffsets));
3419 Abbrev = std::make_shared<BitCodeAbbrev>();
3421 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32));
3422 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob));
3423 unsigned DeclOffsetAbbrev = Stream.EmitAbbrev(std::move(Abbrev));
3426 Stream.EmitRecordWithBlob(DeclOffsetAbbrev,
Record,
bytes(DeclOffsets));
3430void ASTWriter::WriteFileDeclIDsMap() {
3431 using namespace llvm;
3434 SortedFileDeclIDs.reserve(FileDeclIDs.size());
3435 for (
const auto &
P : FileDeclIDs)
3436 SortedFileDeclIDs.push_back(std::make_pair(
P.first,
P.second.get()));
3437 llvm::sort(SortedFileDeclIDs, llvm::less_first());
3441 for (
auto &FileDeclEntry : SortedFileDeclIDs) {
3442 DeclIDInFileInfo &Info = *FileDeclEntry.second;
3443 Info.FirstDeclIndex = FileGroupedDeclIDs.size();
3444 llvm::stable_sort(Info.DeclIDs);
3445 for (
auto &LocDeclEntry : Info.DeclIDs)
3446 FileGroupedDeclIDs.push_back(LocDeclEntry.second.getRawValue());
3449 auto Abbrev = std::make_shared<BitCodeAbbrev>();
3451 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32));
3452 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob));
3453 unsigned AbbrevCode = Stream.EmitAbbrev(std::move(Abbrev));
3455 FileGroupedDeclIDs.size()};
3456 Stream.EmitRecordWithBlob(AbbrevCode,
Record,
bytes(FileGroupedDeclIDs));
3459void ASTWriter::WriteComments(
ASTContext &Context) {
3461 auto _ = llvm::make_scope_exit([
this] { Stream.ExitBlock(); });
3472 for (
const auto &FO : Context.
Comments.OrderedComments) {
3473 for (
const auto &OC : FO.second) {
3492class ASTMethodPoolTrait {
3497 using key_type_ref = key_type;
3503 using data_type_ref =
const data_type &;
3508 explicit ASTMethodPoolTrait(
ASTWriter &Writer) : Writer(Writer) {}
3514 std::pair<unsigned, unsigned>
3515 EmitKeyDataLength(raw_ostream& Out,
Selector Sel,
3516 data_type_ref Methods) {
3520 unsigned DataLen = 4 + 2 + 2;
3523 if (ShouldWriteMethodListNode(Method))
3524 DataLen +=
sizeof(
DeclID);
3527 if (ShouldWriteMethodListNode(Method))
3528 DataLen +=
sizeof(
DeclID);
3532 void EmitKey(raw_ostream& Out,
Selector Sel,
unsigned) {
3533 using namespace llvm::support;
3535 endian::Writer
LE(Out, llvm::endianness::little);
3537 assert((Start >> 32) == 0 &&
"Selector key offset too large");
3540 LE.write<uint16_t>(N);
3543 for (
unsigned I = 0; I != N; ++I)
3548 void EmitData(raw_ostream& Out, key_type_ref,
3549 data_type_ref Methods,
unsigned DataLen) {
3550 using namespace llvm::support;
3552 endian::Writer
LE(Out, llvm::endianness::little);
3553 uint64_t Start = Out.tell(); (void)Start;
3555 unsigned NumInstanceMethods = 0;
3558 if (ShouldWriteMethodListNode(Method))
3559 ++NumInstanceMethods;
3561 unsigned NumFactoryMethods = 0;
3564 if (ShouldWriteMethodListNode(Method))
3565 ++NumFactoryMethods;
3567 unsigned InstanceBits = Methods.Instance.getBits();
3568 assert(InstanceBits < 4);
3569 unsigned InstanceHasMoreThanOneDeclBit =
3570 Methods.Instance.hasMoreThanOneDecl();
3571 unsigned FullInstanceBits = (NumInstanceMethods << 3) |
3572 (InstanceHasMoreThanOneDeclBit << 2) |
3574 unsigned FactoryBits = Methods.Factory.getBits();
3575 assert(FactoryBits < 4);
3576 unsigned FactoryHasMoreThanOneDeclBit =
3577 Methods.Factory.hasMoreThanOneDecl();
3578 unsigned FullFactoryBits = (NumFactoryMethods << 3) |
3579 (FactoryHasMoreThanOneDeclBit << 2) |
3581 LE.write<uint16_t>(FullInstanceBits);
3582 LE.write<uint16_t>(FullFactoryBits);
3585 if (ShouldWriteMethodListNode(Method))
3589 if (ShouldWriteMethodListNode(Method))
3592 assert(Out.tell() - Start == DataLen &&
"Data length is wrong");
3597 return (
Node->getMethod() && !
Node->getMethod()->isFromASTFile());
3608void ASTWriter::WriteSelectors(
Sema &SemaRef) {
3609 using namespace llvm;
3614 unsigned NumTableEntries = 0;
3617 llvm::OnDiskChainedHashTableGenerator<ASTMethodPoolTrait>
Generator;
3618 ASTMethodPoolTrait Trait(*
this);
3622 SelectorOffsets.resize(NextSelectorID - FirstSelectorID);
3623 for (
auto &SelectorAndID : SelectorIDs) {
3626 SemaObjC::GlobalMethodPool::iterator F =
3628 ASTMethodPoolTrait::data_type
Data = {
3634 Data.Instance = F->second.first;
3635 Data.Factory = F->second.second;
3639 if (Chain && ID < FirstSelectorID) {
3641 bool changed =
false;
3644 if (!M->getMethod()->isFromASTFile()) {
3652 if (!M->getMethod()->isFromASTFile()) {
3660 }
else if (
Data.Instance.getMethod() ||
Data.Factory.getMethod()) {
3671 using namespace llvm::support;
3673 ASTMethodPoolTrait Trait(*
this);
3674 llvm::raw_svector_ostream Out(MethodPool);
3676 endian::write<uint32_t>(Out, 0, llvm::endianness::little);
3677 BucketOffset =
Generator.Emit(Out, Trait);
3681 auto Abbrev = std::make_shared<BitCodeAbbrev>();
3683 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32));
3684 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32));
3685 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob));
3686 unsigned MethodPoolAbbrev = Stream.EmitAbbrev(std::move(Abbrev));
3692 Stream.EmitRecordWithBlob(MethodPoolAbbrev,
Record, MethodPool);
3696 Abbrev = std::make_shared<BitCodeAbbrev>();
3698 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32));
3699 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32));
3700 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob));
3701 unsigned SelectorOffsetAbbrev = Stream.EmitAbbrev(std::move(Abbrev));
3705 RecordData::value_type
Record[] = {
3708 Stream.EmitRecordWithBlob(SelectorOffsetAbbrev,
Record,
3709 bytes(SelectorOffsets));
3715void ASTWriter::WriteReferencedSelectorsPool(
Sema &SemaRef) {
3716 using namespace llvm;
3728 Selector Sel = SelectorAndLocation.first;
3730 Writer.AddSelectorRef(Sel);
3752 for (; Redecl; Redecl = Redecl->getPreviousDecl()) {
3754 if (!Redecl->isFromASTFile()) {
3758 if (!Redecl->getDeclContext()->getRedeclContext()->Equals(
3761 return cast<NamedDecl>(Redecl);
3766 if (Redecl->getOwningModuleID() == 0)
3771 if (!
First->isFromASTFile())
3772 return cast<NamedDecl>(
First);
3782bool IsInterestingIdentifier(
const IdentifierInfo *II, uint64_t MacroOffset,
3783 bool IsModule,
bool IsCPlusPlus) {
3784 bool NeedDecls = !IsModule || !IsCPlusPlus;
3786 bool IsInteresting =
3790 if (MacroOffset || II->
isPoisoned() || (!IsModule && IsInteresting) ||
3801 bool IsCPlusPlus = Writer.
getLangOpts().CPlusPlus;
3802 return IsInterestingIdentifier(II, 0, IsModule, IsCPlusPlus);
3805class ASTIdentifierTableTrait {
3818 return IsInterestingIdentifier(II, MacroOffset, IsModule,
3824 using key_type_ref = key_type;
3827 using data_type_ref = data_type;
3835 : Writer(Writer), PP(PP), IdResolver(IdResolver), IsModule(IsModule),
3836 NeedDecls(!IsModule || !Writer.getLangOpts().
CPlusPlus),
3837 InterestingIdentifierOffsets(InterestingIdentifierOffsets) {}
3839 bool needDecls()
const {
return NeedDecls; }
3842 return llvm::djbHash(II->
getName());
3850 std::pair<unsigned, unsigned>
3860 if (InterestingIdentifierOffsets &&
3862 InterestingIdentifierOffsets->push_back(Out.tell());
3872 if (NeedDecls && IdResolver)
3873 DataLen += std::distance(IdResolver->
begin(II), IdResolver->
end()) *
3879 void EmitKey(raw_ostream &Out,
const IdentifierInfo *II,
unsigned KeyLen) {
3885 using namespace llvm::support;
3887 endian::Writer
LE(Out, llvm::endianness::little);
3897 assert((Bits & 0xffff) == Bits &&
"ObjCOrBuiltinID too big for ASTReader.");
3898 LE.write<uint16_t>(Bits);
3900 bool HadMacroDefinition = MacroOffset != 0;
3901 Bits = (Bits << 1) |
unsigned(HadMacroDefinition);
3903 Bits = (Bits << 1) |
unsigned(II->
isPoisoned());
3906 LE.write<uint16_t>(Bits);
3908 if (HadMacroDefinition)
3911 if (NeedDecls && IdResolver) {
3940 using namespace llvm;
3947 llvm::OnDiskChainedHashTableGenerator<ASTIdentifierTableTrait>
Generator;
3948 ASTIdentifierTableTrait Trait(*
this, PP, IdResolver, IsModule,
3949 IsModule ? &InterestingIdents :
nullptr);
3953 IdentifierOffsets.resize(NextIdentID - FirstIdentID);
3954 for (
auto IdentIDPair : IdentifierIDs) {
3957 assert(II &&
"NULL identifier in identifier table");
3962 (Trait.needDecls() &&
3971 using namespace llvm::support;
3975 endian::write<uint32_t>(Out, 0, llvm::endianness::little);
3976 BucketOffset =
Generator.Emit(Out, Trait);
3980 auto Abbrev = std::make_shared<BitCodeAbbrev>();
3982 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32));
3983 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob));
3984 unsigned IDTableAbbrev = Stream.EmitAbbrev(std::move(Abbrev));
3992 auto Abbrev = std::make_shared<BitCodeAbbrev>();
3994 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32));
3995 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob));
3996 unsigned IdentifierOffsetAbbrev = Stream.EmitAbbrev(std::move(Abbrev));
3999 for (
unsigned I = 0, N = IdentifierOffsets.size(); I != N; ++I)
4000 assert(IdentifierOffsets[I] &&
"Missing identifier offset?");
4004 IdentifierOffsets.size()};
4005 Stream.EmitRecordWithBlob(IdentifierOffsetAbbrev,
Record,
4006 bytes(IdentifierOffsets));
4010 if (!InterestingIdents.empty())
4018 PendingEmittingVTables.push_back(RD);
4028class ASTDeclContextNameLookupTrait {
4034 using key_type_ref = key_type;
4037 using data_type = std::pair<unsigned, unsigned>;
4038 using data_type_ref =
const data_type &;
4043 explicit ASTDeclContextNameLookupTrait(
ASTWriter &Writer) : Writer(Writer) {}
4045 template<
typename Coll>
4046 data_type getData(
const Coll &Decls) {
4047 unsigned Start = DeclIDs.size();
4063 DeclIDs.push_back(Writer.
GetDeclRef(DeclForLocalLookup));
4065 return std::make_pair(Start, DeclIDs.size());
4069 unsigned Start = DeclIDs.size();
4074 return std::make_pair(Start, DeclIDs.size());
4077 static bool EqualKey(key_type_ref a, key_type_ref
b) {
4082 return Name.getHash();
4085 void EmitFileRef(raw_ostream &Out,
ModuleFile *F)
const {
4087 "have reference to loaded module file but no chain?");
4089 using namespace llvm::support;
4092 llvm::endianness::little);
4095 std::pair<unsigned, unsigned> EmitKeyDataLength(raw_ostream &Out,
4097 data_type_ref Lookup) {
4098 unsigned KeyLen = 1;
4099 switch (Name.getKind()) {
4121 unsigned DataLen =
sizeof(
DeclID) * (Lookup.second - Lookup.first);
4127 using namespace llvm::support;
4129 endian::Writer
LE(Out, llvm::endianness::little);
4130 LE.write<uint8_t>(Name.getKind());
4131 switch (Name.getKind()) {
4144 "Invalid operator?");
4145 LE.write<uint8_t>(Name.getOperatorKind());
4154 llvm_unreachable(
"Invalid name kind?");
4157 void EmitData(raw_ostream &Out, key_type_ref, data_type Lookup,
4159 using namespace llvm::support;
4161 endian::Writer
LE(Out, llvm::endianness::little);
4162 uint64_t Start = Out.tell(); (void)Start;
4163 for (
unsigned I = Lookup.first, N = Lookup.second; I != N; ++I)
4165 assert(Out.tell() - Start == DataLen &&
"Data length is wrong");
4172class LazySpecializationInfoLookupTrait {
4178 using key_type_ref = key_type;
4181 using data_type = std::pair<unsigned, unsigned>;
4182 using data_type_ref =
const data_type &;
4187 explicit LazySpecializationInfoLookupTrait(
ASTWriter &Writer)
4190 template <
typename Col,
typename Col2>
4191 data_type getData(Col &&
C, Col2 &ExistingInfo) {
4192 unsigned Start = Specs.size();
4200 Specs.push_back(Info);
4201 return std::make_pair(Start, Specs.size());
4204 data_type ImportData(
4206 unsigned Start = Specs.size();
4207 for (
auto ID : FromReader)
4208 Specs.push_back(
ID);
4209 return std::make_pair(Start, Specs.size());
4212 static bool EqualKey(key_type_ref a, key_type_ref
b) {
return a ==
b; }
4214 hash_value_type
ComputeHash(key_type Name) {
return Name; }
4216 void EmitFileRef(raw_ostream &Out,
ModuleFile *F)
const {
4218 "have reference to loaded module file but no chain?");
4220 using namespace llvm::support;
4222 llvm::endianness::little);
4225 std::pair<unsigned, unsigned> EmitKeyDataLength(raw_ostream &Out,
4227 data_type_ref Lookup) {
4229 unsigned KeyLen = 4;
4231 (Lookup.second - Lookup.first);
4236 void EmitKey(raw_ostream &Out, key_type HashValue,
unsigned) {
4237 using namespace llvm::support;
4239 endian::Writer
LE(Out, llvm::endianness::little);
4243 void EmitData(raw_ostream &Out, key_type_ref, data_type Lookup,
4245 using namespace llvm::support;
4247 endian::Writer
LE(Out, llvm::endianness::little);
4250 for (
unsigned I = Lookup.first, N = Lookup.second; I != N; ++I) {
4251 LE.write<
DeclID>(Specs[I].getRawValue());
4253 assert(Out.tell() - Start == DataLen &&
"Data length is wrong");
4257unsigned CalculateODRHashForSpecs(
const Decl *Spec) {
4259 if (
auto *CTSD = dyn_cast<ClassTemplateSpecializationDecl>(Spec))
4260 Args = CTSD->getTemplateArgs().asArray();
4261 else if (
auto *VTSD = dyn_cast<VarTemplateSpecializationDecl>(Spec))
4262 Args = VTSD->getTemplateArgs().asArray();
4263 else if (
auto *FD = dyn_cast<FunctionDecl>(Spec))
4264 Args = FD->getTemplateSpecializationArgs()->asArray();
4266 llvm_unreachable(
"New Specialization Kind?");
4272void ASTWriter::GenerateSpecializationInfoLookupTable(
4279 LazySpecializationInfoLookupTrait>
4281 LazySpecializationInfoLookupTrait Trait(*
this);
4283 llvm::DenseMap<unsigned, llvm::SmallVector<const NamedDecl *, 4>>
4289 auto Iter = SpecializationMaps.find(HashedValue);
4290 if (
Iter == SpecializationMaps.end())
4291 Iter = SpecializationMaps
4292 .try_emplace(HashedValue,
4303 for (
auto &[HashValue, Specs] : SpecializationMaps) {
4314 ExisitingSpecs = Lookups->Table.find(HashValue);
4316 Generator.insert(HashValue, Trait.getData(Specs, ExisitingSpecs), Trait);
4319 Generator.emit(LookupTable, Trait, Lookups ? &Lookups->Table :
nullptr);
4322uint64_t ASTWriter::WriteSpecializationInfoLookupTable(
4327 GenerateSpecializationInfoLookupTable(
D, Specializations, LookupTable,
4330 uint64_t Offset = Stream.GetCurrentBitNo();
4331 RecordData::value_type
Record[] = {
static_cast<RecordData::value_type
>(
4333 Stream.EmitRecordWithBlob(IsPartial ? DeclPartialSpecializationsAbbrev
4334 : DeclSpecializationsAbbrev,
4342 return Result.hasExternalDecls() &&
4343 DC->hasNeedToReconcileExternalVisibleStorage();
4352 for (
auto *
D :
Result.getLookupResult()) {
4354 if (LocalD->isFromASTFile())
4372void ASTWriter::GenerateNameLookupTable(
4375 assert(!ConstDC->hasLazyLocalLexicalLookups() &&
4376 !ConstDC->hasLazyExternalLexicalLookups() &&
4377 "must call buildLookups first");
4385 ASTDeclContextNameLookupTrait>
Generator;
4386 ASTDeclContextNameLookupTrait Trait(*
this);
4398 auto &Name = Lookup.first;
4399 auto &
Result = Lookup.second;
4414 if ((GeneratingReducedBMI || isLookupResultExternal(
Result, DC)) &&
4432 if (Lookup.second.getLookupResult().empty())
4435 switch (Lookup.first.getNameKind()) {
4437 Names.push_back(Lookup.first);
4441 assert(isa<CXXRecordDecl>(DC) &&
4442 "Cannot have a constructor name outside of a class!");
4443 ConstructorNameSet.insert(Name);
4447 assert(isa<CXXRecordDecl>(DC) &&
4448 "Cannot have a conversion function name outside of a class!");
4449 ConversionNameSet.insert(Name);
4457 if (
auto *
D = dyn_cast<CXXRecordDecl>(DC)) {
4471 if (ConstructorNameSet.erase(ImplicitCtorName))
4472 Names.push_back(ImplicitCtorName);
4477 if (!ConstructorNameSet.empty() || !ConversionNameSet.empty())
4478 for (
Decl *ChildD : cast<CXXRecordDecl>(DC)->decls())
4479 if (
auto *ChildND = dyn_cast<NamedDecl>(ChildD)) {
4480 auto Name = ChildND->getDeclName();
4481 switch (Name.getNameKind()) {
4486 if (ConstructorNameSet.erase(Name))
4487 Names.push_back(Name);
4491 if (ConversionNameSet.erase(Name))
4492 Names.push_back(Name);
4496 if (ConstructorNameSet.empty() && ConversionNameSet.empty())
4500 assert(ConstructorNameSet.empty() &&
"Failed to find all of the visible "
4501 "constructors by walking all the "
4502 "lexical members of the context.");
4503 assert(ConversionNameSet.empty() &&
"Failed to find all of the visible "
4504 "conversion functions by walking all "
4505 "the lexical members of the context.");
4512 for (
auto &Name : Names)
4524 for (
auto &Name : Names) {
4527 switch (Name.getNameKind()) {
4545 if (!ConstructorDecls.empty())
4546 Generator.insert(ConstructorDecls.front()->getDeclName(),
4547 Trait.getData(ConstructorDecls), Trait);
4548 if (!ConversionDecls.empty())
4549 Generator.insert(ConversionDecls.front()->getDeclName(),
4550 Trait.getData(ConversionDecls), Trait);
4555 Generator.emit(LookupTable, Trait, Lookups ? &Lookups->Table :
nullptr);
4568 if (isa<NamespaceDecl>(DC) && Chain &&
4571 for (
auto *Prev = cast<NamespaceDecl>(DC)->getPreviousDecl(); Prev;
4572 Prev = Prev->getPreviousDecl())
4573 if (!Prev->isFromASTFile())
4586 LookupResults.reserve(Map->size());
4587 for (
auto &Entry : *Map)
4588 LookupResults.push_back(
4589 std::make_pair(Entry.first, Entry.second.getLookupResult()));
4592 llvm::sort(LookupResults, llvm::less_first());
4593 for (
auto &NameAndResult : LookupResults) {
4601 assert(
Result.empty() &&
"Cannot have a constructor or conversion "
4602 "function name in a namespace!");
4643 uint64_t Offset = Stream.GetCurrentBitNo();
4645 if (!Map || Map->empty())
4650 GenerateNameLookupTable(Context, DC, LookupTable);
4654 Stream.EmitRecordWithBlob(DeclContextVisibleLookupAbbrev,
Record,
4656 ++NumVisibleDeclContexts;
4666void ASTWriter::WriteDeclContextVisibleUpdate(
ASTContext &Context,
4669 if (!Map || Map->empty())
4674 GenerateNameLookupTable(Context, DC, LookupTable);
4678 if (isa<NamespaceDecl>(DC))
4684 Stream.EmitRecordWithBlob(UpdateVisibleAbbrev,
Record, LookupTable);
4694void ASTWriter::WriteOpenCLExtensions(
Sema &SemaRef) {
4700 for (
const auto &I:Opts.OptMap) {
4702 auto V = I.getValue();
4703 Record.push_back(
V.Supported ? 1 : 0);
4704 Record.push_back(
V.Enabled ? 1 : 0);
4705 Record.push_back(
V.WithPragma ? 1 : 0);
4712void ASTWriter::WriteCUDAPragmas(
Sema &SemaRef) {
4713 if (SemaRef.
CUDA().ForceHostDeviceDepth > 0) {
4714 RecordData::value_type
Record[] = {SemaRef.
CUDA().ForceHostDeviceDepth};
4719void ASTWriter::WriteObjCCategories() {
4723 for (
unsigned I = 0, N = ObjCClassesWithCategories.size(); I != N; ++I) {
4725 unsigned StartIndex = Categories.size();
4730 Categories.push_back(0);
4734 Cat =
Class->known_categories_begin(),
4735 CatEnd =
Class->known_categories_end();
4736 Cat != CatEnd; ++Cat, ++Size) {
4742 Categories[StartIndex] =
Size;
4746 CategoriesMap.push_back(CatInfo);
4751 llvm::array_pod_sort(CategoriesMap.begin(), CategoriesMap.end());
4754 using namespace llvm;
4756 auto Abbrev = std::make_shared<BitCodeAbbrev>();
4758 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6));
4759 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob));
4760 unsigned AbbrevID = Stream.EmitAbbrev(std::move(Abbrev));
4763 Stream.EmitRecordWithBlob(AbbrevID,
Record,
4764 reinterpret_cast<char *
>(CategoriesMap.data()),
4771void ASTWriter::WriteLateParsedTemplates(
Sema &SemaRef) {
4778 for (
auto &LPTMapEntry : LPTMap) {
4786 for (
const auto &Tok : LPT.
Toks) {
4794void ASTWriter::WriteOptimizePragmaOptions(
Sema &SemaRef) {
4802void ASTWriter::WriteMSStructPragmaOptions(
Sema &SemaRef) {
4810void ASTWriter::WriteMSPointersToMembersPragmaOptions(
Sema &SemaRef) {
4818void ASTWriter::WritePackPragmaOptions(
Sema &SemaRef) {
4838void ASTWriter::WriteFloatControlPragmaOptions(
Sema &SemaRef) {
4848 for (
const auto &StackEntry : SemaRef.
FpPragmaStack.Stack) {
4849 Record.push_back(StackEntry.Value.getAsOpaqueInt());
4858void ASTWriter::WriteDeclsWithEffectsToVerify(
Sema &SemaRef) {
4868void ASTWriter::WriteModuleFileExtension(
Sema &SemaRef,
4874 auto Abv = std::make_shared<llvm::BitCodeAbbrev>();
4876 Abv->Add(llvm::BitCodeAbbrevOp(llvm::BitCodeAbbrevOp::VBR, 6));
4877 Abv->Add(llvm::BitCodeAbbrevOp(llvm::BitCodeAbbrevOp::VBR, 6));
4878 Abv->Add(llvm::BitCodeAbbrevOp(llvm::BitCodeAbbrevOp::VBR, 6));
4879 Abv->Add(llvm::BitCodeAbbrevOp(llvm::BitCodeAbbrevOp::VBR, 6));
4880 Abv->Add(llvm::BitCodeAbbrevOp(llvm::BitCodeAbbrevOp::Blob));
4881 unsigned Abbrev = Stream.EmitAbbrev(std::move(Abv));
4887 Record.push_back(Metadata.MajorVersion);
4888 Record.push_back(Metadata.MinorVersion);
4889 Record.push_back(Metadata.BlockName.size());
4890 Record.push_back(Metadata.UserInfo.size());
4892 Buffer += Metadata.BlockName;
4893 Buffer += Metadata.UserInfo;
4894 Stream.EmitRecordWithBlob(Abbrev,
Record, Buffer);
4912 if (!A || (isa<PreferredNameAttr>(A) &&
4913 Writer->isWritingStdCXXNamedModules()))
4914 return Record.push_back(0);
4924 Record.push_back(A->getAttributeSpellingListIndexRaw());
4927#include "clang/Serialization/AttrPCHWrite.inc"
4933 for (
const auto *A : Attrs)
4947 case tok::annot_pragma_loop_hint: {
4951 Record.push_back(Info->Toks.size());
4952 for (
const auto &
T : Info->Toks)
4956 case tok::annot_pragma_pack: {
4959 Record.push_back(
static_cast<unsigned>(Info->Action));
4965 case tok::annot_pragma_openmp:
4966 case tok::annot_pragma_openmp_end:
4967 case tok::annot_pragma_unused:
4968 case tok::annot_pragma_openacc:
4969 case tok::annot_pragma_openacc_end:
4970 case tok::annot_repl_input_end:
4973 llvm_unreachable(
"missing serialization code for annotation token");
4984 Record.push_back(Str.size());
4990 Record.push_back(Str.size());
4991 Blob.insert(Blob.end(), Str.begin(), Str.end());
4995 assert(WritingAST &&
"can't prepare path for output when not writing AST");
4998 StringRef PathStr(
Path.data(),
Path.size());
4999 if (PathStr ==
"<built-in>" || PathStr ==
"<command line>")
5005 const char *PathBegin =
Path.data();
5006 const char *PathPtr =
5008 if (PathPtr != PathBegin) {
5009 Path.erase(
Path.begin(),
Path.begin() + (PathPtr - PathBegin));