74#include "llvm/ADT/APFloat.h"
75#include "llvm/ADT/APInt.h"
76#include "llvm/ADT/APSInt.h"
77#include "llvm/ADT/ArrayRef.h"
78#include "llvm/ADT/DenseMap.h"
79#include "llvm/ADT/Hashing.h"
80#include "llvm/ADT/PointerIntPair.h"
81#include "llvm/ADT/STLExtras.h"
82#include "llvm/ADT/ScopeExit.h"
83#include "llvm/ADT/SmallPtrSet.h"
84#include "llvm/ADT/SmallString.h"
85#include "llvm/ADT/SmallVector.h"
86#include "llvm/ADT/StringMap.h"
87#include "llvm/ADT/StringRef.h"
88#include "llvm/Bitstream/BitCodes.h"
89#include "llvm/Bitstream/BitstreamWriter.h"
90#include "llvm/Support/Casting.h"
91#include "llvm/Support/Compression.h"
92#include "llvm/Support/DJB.h"
93#include "llvm/Support/Endian.h"
94#include "llvm/Support/EndianStream.h"
95#include "llvm/Support/Error.h"
96#include "llvm/Support/ErrorHandling.h"
97#include "llvm/Support/LEB128.h"
98#include "llvm/Support/MemoryBuffer.h"
99#include "llvm/Support/OnDiskHashTable.h"
100#include "llvm/Support/Path.h"
101#include "llvm/Support/SHA1.h"
102#include "llvm/Support/TimeProfiler.h"
103#include "llvm/Support/VersionTuple.h"
104#include "llvm/Support/raw_ostream.h"
119using namespace clang;
122template <
typename T,
typename Allocator>
123static StringRef
bytes(
const std::vector<T, Allocator> &
v) {
124 if (
v.empty())
return StringRef();
125 return StringRef(
reinterpret_cast<const char*
>(&
v[0]),
126 sizeof(T) *
v.size());
131 return StringRef(
reinterpret_cast<const char*
>(
v.data()),
132 sizeof(T) *
v.size());
135static std::string
bytes(
const std::vector<bool> &
V) {
137 Str.reserve(
V.size() / 8);
138 for (
unsigned I = 0, E =
V.size(); I < E;) {
140 for (
unsigned Bit = 0; Bit < 8 && I < E; ++Bit, ++I)
153#define TYPE_BIT_CODE(CLASS_ID, CODE_ID, CODE_VALUE) \
154 case Type::CLASS_ID: return TYPE_##CODE_ID;
155#include "clang/Serialization/TypeBitCodes.def"
157 llvm_unreachable(
"shouldn't be serializing a builtin type this way");
159 llvm_unreachable(
"bad type kind");
164std::set<const FileEntry *> GetAffectingModuleMaps(
const Preprocessor &PP,
176 for (
unsigned UID = 0, LastUID = FilesByUID.size(); UID != LastUID; ++UID) {
189 ModulesToProcess.push_back(KH.getModule());
196 std::set<const FileEntry *> ModuleMaps{};
198 if (!ModuleMaps.insert(F).second)
212 std::set<const Module *> ProcessedModules;
213 auto CollectIncludingMapsFromAncestors = [&](
const Module *M) {
215 if (!ProcessedModules.insert(Mod).second)
220 CollectIncludingModuleMaps(*ModuleMapFile);
225 CollectIncludingModuleMaps(*ModuleMapFile);
229 for (
const Module *CurrentModule : ModulesToProcess) {
230 CollectIncludingMapsFromAncestors(CurrentModule);
232 CollectIncludingMapsFromAncestors(ImportedModule);
234 CollectIncludingMapsFromAncestors(UndeclaredModule);
247 : Writer(Writer), BasicWriter(Writer,
Record) {}
272 Record.AddSourceLocation(Loc, Seq);
280#define ABSTRACT_TYPELOC(CLASS, PARENT)
281#define TYPELOC(CLASS, PARENT) \
282 void Visit##CLASS##TypeLoc(CLASS##TypeLoc TyLoc);
283#include "clang/AST/TypeLocNodes.def"
347 VisitArrayTypeLoc(TL);
351 VisitArrayTypeLoc(TL);
355 VisitArrayTypeLoc(TL);
358void TypeLocWriter::VisitDependentSizedArrayTypeLoc(
360 VisitArrayTypeLoc(TL);
363void TypeLocWriter::VisitDependentAddressSpaceTypeLoc(
367 addSourceLocation(
range.getBegin());
368 addSourceLocation(
range.getEnd());
372void TypeLocWriter::VisitDependentSizedExtVectorTypeLoc(
381void TypeLocWriter::VisitDependentVectorTypeLoc(
393 addSourceLocation(
range.getBegin());
394 addSourceLocation(
range.getEnd());
399void TypeLocWriter::VisitDependentSizedMatrixTypeLoc(
403 addSourceLocation(
range.getBegin());
404 addSourceLocation(
range.getEnd());
415 for (
unsigned i = 0, e = TL.
getNumParams(); i != e; ++i)
420 VisitFunctionTypeLoc(TL);
424 VisitFunctionTypeLoc(TL);
485void TypeLocWriter::VisitAutoTypeLoc(
AutoTypeLoc TL) {
490 Record.AddConceptReference(CR);
496void TypeLocWriter::VisitDeducedTemplateSpecializationTypeLoc(
505void TypeLocWriter::VisitEnumTypeLoc(
EnumTypeLoc TL) {
521void TypeLocWriter::VisitSubstTemplateTypeParmTypeLoc(
526void TypeLocWriter::VisitSubstTemplateTypeParmPackTypeLoc(
531void TypeLocWriter::VisitTemplateSpecializationTypeLoc(
537 for (
unsigned i = 0, e = TL.
getNumArgs(); i != e; ++i)
566void TypeLocWriter::VisitDependentTemplateSpecializationTypeLoc(
574 for (
unsigned I = 0, E = TL.
getNumArgs(); I != E; ++I)
610void TypeLocWriter::VisitPipeTypeLoc(
PipeTypeLoc TL) {
617void TypeLocWriter::VisitDependentBitIntTypeLoc(
622void ASTWriter::WriteTypeAbbrevs() {
623 using namespace llvm;
625 std::shared_ptr<BitCodeAbbrev> Abv;
628 Abv = std::make_shared<BitCodeAbbrev>();
630 Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6));
631 Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 3));
632 TypeExtQualAbbrev = Stream.EmitAbbrev(std::move(Abv));
640 llvm::BitstreamWriter &Stream,
643 Record.push_back(ID);
644 Stream.EmitRecord(llvm::bitc::BLOCKINFO_CODE_SETBID, Record);
647 if (!Name || Name[0] == 0)
651 Record.push_back(*Name++);
652 Stream.EmitRecord(llvm::bitc::BLOCKINFO_CODE_BLOCKNAME, Record);
656 llvm::BitstreamWriter &Stream,
659 Record.push_back(ID);
661 Record.push_back(*Name++);
662 Stream.EmitRecord(llvm::bitc::BLOCKINFO_CODE_SETRECORDNAME, Record);
667#define RECORD(X) EmitRecordID(X, #X, Stream, Record)
798void ASTWriter::WriteBlockInfoBlock() {
800 Stream.EnterBlockInfoBlock();
802#define BLOCK(X) EmitBlockID(X ## _ID, #X, Stream, Record)
803#define RECORD(X) EmitRecordID(X, #X, Stream, Record)
806 BLOCK(CONTROL_BLOCK);
816 BLOCK(OPTIONS_BLOCK);
823 BLOCK(INPUT_FILES_BLOCK);
885 BLOCK(SOURCE_MANAGER_BLOCK);
893 BLOCK(PREPROCESSOR_BLOCK);
901 BLOCK(SUBMODULE_BLOCK);
923 BLOCK(COMMENTS_BLOCK);
927 BLOCK(DECLTYPES_BLOCK);
931 RECORD(TYPE_BLOCK_POINTER);
932 RECORD(TYPE_LVALUE_REFERENCE);
933 RECORD(TYPE_RVALUE_REFERENCE);
934 RECORD(TYPE_MEMBER_POINTER);
935 RECORD(TYPE_CONSTANT_ARRAY);
936 RECORD(TYPE_INCOMPLETE_ARRAY);
937 RECORD(TYPE_VARIABLE_ARRAY);
940 RECORD(TYPE_FUNCTION_NO_PROTO);
941 RECORD(TYPE_FUNCTION_PROTO);
947 RECORD(TYPE_OBJC_INTERFACE);
948 RECORD(TYPE_OBJC_OBJECT_POINTER);
951 RECORD(TYPE_SUBST_TEMPLATE_TYPE_PARM);
952 RECORD(TYPE_UNRESOLVED_USING);
953 RECORD(TYPE_INJECTED_CLASS_NAME);
955 RECORD(TYPE_TEMPLATE_TYPE_PARM);
956 RECORD(TYPE_TEMPLATE_SPECIALIZATION);
957 RECORD(TYPE_DEPENDENT_NAME);
958 RECORD(TYPE_DEPENDENT_TEMPLATE_SPECIALIZATION);
959 RECORD(TYPE_DEPENDENT_SIZED_ARRAY);
961 RECORD(TYPE_MACRO_QUALIFIED);
962 RECORD(TYPE_PACK_EXPANSION);
964 RECORD(TYPE_SUBST_TEMPLATE_TYPE_PARM_PACK);
966 RECORD(TYPE_UNARY_TRANSFORM);
970 RECORD(TYPE_OBJC_TYPE_PARAM);
1048 BLOCK(PREPROCESSOR_DETAIL_BLOCK);
1054 BLOCK(EXTENSION_BLOCK);
1057 BLOCK(UNHASHED_CONTROL_BLOCK);
1076 return Changed | llvm::sys::path::remove_dots(Path);
1091 assert(
Filename &&
"No file name to adjust?");
1093 if (BaseDir.empty())
1098 for (;
Filename[Pos] && Pos < BaseDir.size(); ++Pos)
1108 if (!llvm::sys::path::is_separator(
Filename[Pos])) {
1109 if (!llvm::sys::path::is_separator(BaseDir.back()))
1126std::pair<ASTFileSignature, ASTFileSignature>
1127ASTWriter::createSignature()
const {
1128 StringRef AllBytes(Buffer.data(), Buffer.size());
1131 Hasher.update(AllBytes.slice(ASTBlockRange.first, ASTBlockRange.second));
1136 Hasher.update(AllBytes.slice(0, UnhashedControlBlockRange.first));
1139 AllBytes.slice(UnhashedControlBlockRange.second, ASTBlockRange.first));
1141 Hasher.update(AllBytes.slice(ASTBlockRange.second, StringRef::npos));
1144 return std::make_pair(ASTBlockHash, Signature);
1148 if (!WritingModule ||
1155 for (uint8_t Byte : S) {
1156 Stream.BackpatchByte(BitNo, Byte);
1163 std::tie(ASTBlockHash, Signature) = createSignature();
1165 BackpatchSignatureAt(ASTBlockHash, ASTBlockHashOffset);
1166 BackpatchSignatureAt(Signature, SignatureOffset);
1171void ASTWriter::writeUnhashedControlBlock(
Preprocessor &PP,
1173 using namespace llvm;
1176 Stream.FlushToWord();
1177 UnhashedControlBlockRange.first = Stream.GetCurrentBitNo() >> 3;
1184 if (WritingModule &&
1196 auto Abbrev = std::make_shared<BitCodeAbbrev>();
1198 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob));
1199 unsigned ASTBlockHashAbbrev = Stream.EmitAbbrev(std::move(Abbrev));
1201 Abbrev = std::make_shared<BitCodeAbbrev>();
1202 Abbrev->Add(BitCodeAbbrevOp(
SIGNATURE));
1203 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob));
1204 unsigned SignatureAbbrev = Stream.EmitAbbrev(std::move(Abbrev));
1207 Stream.EmitRecordWithBlob(ASTBlockHashAbbrev, Record, Blob);
1208 ASTBlockHashOffset = Stream.GetCurrentBitNo() - Blob.size() * 8;
1212 Stream.EmitRecordWithBlob(SignatureAbbrev, Record, Blob);
1213 SignatureOffset = Stream.GetCurrentBitNo() - Blob.size() * 8;
1220#define DIAGOPT(Name, Bits, Default) Record.push_back(DiagOpts.Name);
1221#define ENUM_DIAGOPT(Name, Type, Bits, Default) \
1222 Record.push_back(static_cast<unsigned>(DiagOpts.get##Name()));
1223#include "clang/Basic/DiagnosticOptions.def"
1225 for (
unsigned I = 0, N = DiagOpts.
Warnings.size(); I != N; ++I)
1228 for (
unsigned I = 0, N = DiagOpts.
Remarks.size(); I != N; ++I)
1242 for (
unsigned I = 0, N = HSOpts.
UserEntries.size(); I != N; ++I) {
1245 Record.push_back(
static_cast<unsigned>(Entry.
Group));
1265 WritePragmaDiagnosticMappings(Diags, WritingModule);
1269 auto Abbrev = std::make_shared<BitCodeAbbrev>();
1271 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32));
1272 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob));
1273 unsigned HSUsageAbbrevCode = Stream.EmitAbbrev(std::move(Abbrev));
1276 HSEntryUsage.size()};
1277 Stream.EmitRecordWithBlob(HSUsageAbbrevCode, Record,
bytes(HSEntryUsage));
1282 UnhashedControlBlockRange.second = Stream.GetCurrentBitNo() >> 3;
1287 StringRef isysroot) {
1288 using namespace llvm;
1294 auto MetadataAbbrev = std::make_shared<BitCodeAbbrev>();
1295 MetadataAbbrev->Add(BitCodeAbbrevOp(
METADATA));
1296 MetadataAbbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 16));
1297 MetadataAbbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 16));
1298 MetadataAbbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 16));
1299 MetadataAbbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 16));
1300 MetadataAbbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1));
1302 MetadataAbbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1));
1303 MetadataAbbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1));
1304 MetadataAbbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1));
1305 MetadataAbbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob));
1306 unsigned MetadataAbbrevCode = Stream.EmitAbbrev(std::move(MetadataAbbrev));
1307 assert((!WritingModule || isysroot.empty()) &&
1308 "writing module as a relocatable PCH?");
1313 CLANG_VERSION_MAJOR,
1314 CLANG_VERSION_MINOR,
1318 ASTHasCompilerErrors};
1319 Stream.EmitRecordWithBlob(MetadataAbbrevCode, Record,
1323 if (WritingModule) {
1325 auto Abbrev = std::make_shared<BitCodeAbbrev>();
1327 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob));
1328 unsigned AbbrevCode = Stream.EmitAbbrev(std::move(Abbrev));
1330 Stream.EmitRecordWithBlob(AbbrevCode, Record, WritingModule->
Name);
1333 if (WritingModule && WritingModule->
Directory) {
1340 BaseDir.assign(CWD->getName());
1342 BaseDir.assign(WritingModule->
Directory->getName());
1353 WritingModule->
Directory->getName() != StringRef(
"."))) {
1355 auto Abbrev = std::make_shared<BitCodeAbbrev>();
1357 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob));
1358 unsigned AbbrevCode = Stream.EmitAbbrev(std::move(Abbrev));
1361 Stream.EmitRecordWithBlob(AbbrevCode, Record, BaseDir);
1365 BaseDirectory.assign(BaseDir.begin(), BaseDir.end());
1366 }
else if (!isysroot.empty()) {
1368 BaseDirectory = std::string(isysroot);
1377 ? Map.getModuleMapFileForUniquing(WritingModule)
1378 ->getNameAsRequested()
1383 if (
auto *AdditionalModMaps =
1384 Map.getAdditionalModuleMapFiles(WritingModule)) {
1385 Record.push_back(AdditionalModMaps->size());
1387 AdditionalModMaps->end());
1392 AddPath(F->getName(), Record);
1407 if (!M.isDirectlyImported())
1410 Record.push_back((
unsigned)M.Kind);
1411 Record.push_back(M.StandardCXXModule);
1416 Record.push_back(M.Signature ? 0 : M.File->getSize());
1419 llvm::append_range(Record, M.Signature);
1424 Stream.EmitRecord(
IMPORTS, Record);
1433#define LANGOPT(Name, Bits, Default, Description) \
1434 Record.push_back(LangOpts.Name);
1435#define ENUM_LANGOPT(Name, Type, Bits, Default, Description) \
1436 Record.push_back(static_cast<unsigned>(LangOpts.get##Name()));
1437#include "clang/Basic/LangOptions.def"
1438#define SANITIZER(NAME, ID) \
1439 Record.push_back(LangOpts.Sanitize.has(SanitizerKind::ID));
1440#include "clang/Basic/Sanitizers.def"
1480 for (
unsigned I = 0, N = TargetOpts.
Features.size(); I != N; ++I) {
1521 bool WriteMacros = !SkipMacros;
1522 Record.push_back(WriteMacros);
1526 for (
unsigned I = 0, N = PPOpts.
Macros.size(); I != N; ++I) {
1534 for (
unsigned I = 0, N = PPOpts.
Includes.size(); I != N; ++I)
1539 for (
unsigned I = 0, N = PPOpts.
MacroIncludes.size(); I != N; ++I)
1554 if (
auto MainFile =
SM.getFileEntryRefForID(
SM.getMainFileID())) {
1555 auto FileAbbrev = std::make_shared<BitCodeAbbrev>();
1557 FileAbbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6));
1558 FileAbbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob));
1559 unsigned FileAbbrevCode = Stream.EmitAbbrev(std::move(FileAbbrev));
1571 WriteInputFiles(Context.SourceMgr,
1579struct InputFileEntry {
1583 bool BufferOverridden;
1586 uint32_t ContentHash[2];
1595 using namespace llvm;
1600 auto IFAbbrev = std::make_shared<BitCodeAbbrev>();
1602 IFAbbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6));
1603 IFAbbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 12));
1604 IFAbbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 32));
1605 IFAbbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1));
1606 IFAbbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1));
1607 IFAbbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1));
1608 IFAbbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1));
1609 IFAbbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 16));
1610 IFAbbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob));
1611 unsigned IFAbbrevCode = Stream.EmitAbbrev(std::move(IFAbbrev));
1614 auto IFHAbbrev = std::make_shared<BitCodeAbbrev>();
1616 IFHAbbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32));
1617 IFHAbbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32));
1618 unsigned IFHAbbrevCode = Stream.EmitAbbrev(std::move(IFHAbbrev));
1620 uint64_t InputFilesOffsetBase = Stream.GetCurrentBitNo();
1623 std::vector<InputFileEntry> UserFiles;
1624 std::vector<InputFileEntry> SystemFiles;
1628 assert(&SourceMgr.
getSLocEntry(FileID::get(I)) == SLoc);
1635 if (!
Cache->OrigEntry)
1639 if (!IsSLocAffecting[I])
1642 InputFileEntry Entry(*
Cache->OrigEntry);
1643 Entry.IsSystemFile =
isSystem(
File.getFileCharacteristic());
1644 Entry.IsTransient =
Cache->IsTransient;
1645 Entry.BufferOverridden =
Cache->BufferOverridden;
1646 Entry.IsTopLevel =
File.getIncludeLoc().isInvalid();
1649 auto ContentHash = hash_code(-1);
1653 auto MemBuff =
Cache->getBufferIfLoaded();
1655 ContentHash =
hash_value(MemBuff->getBuffer());
1658 << Entry.File.getName();
1660 auto CH = llvm::APInt(64, ContentHash);
1661 Entry.ContentHash[0] =
1662 static_cast<uint32_t
>(CH.getLoBits(32).getZExtValue());
1663 Entry.ContentHash[1] =
1664 static_cast<uint32_t
>(CH.getHiBits(32).getZExtValue());
1666 if (Entry.IsSystemFile)
1667 SystemFiles.push_back(Entry);
1669 UserFiles.push_back(Entry);
1673 auto SortedFiles = llvm::concat<InputFileEntry>(std::move(UserFiles),
1674 std::move(SystemFiles));
1676 unsigned UserFilesNum = 0;
1678 std::vector<uint64_t> InputFileOffsets;
1679 for (
const auto &Entry : SortedFiles) {
1680 uint32_t &InputFileID = InputFileIDs[Entry.File];
1681 if (InputFileID != 0)
1685 InputFileOffsets.push_back(Stream.GetCurrentBitNo() - InputFilesOffsetBase);
1687 InputFileID = InputFileOffsets.size();
1689 if (!Entry.IsSystemFile)
1701 if (Name == NameAsRequested)
1704 RecordData::value_type
Record[] = {
1706 InputFileOffsets.size(),
1709 Entry.BufferOverridden,
1713 NameAsRequested.size()};
1715 Stream.EmitRecordWithBlob(IFAbbrevCode, Record,
1716 (NameAsRequested + Name).str());
1722 Entry.ContentHash[1]};
1723 Stream.EmitRecordWithAbbrev(IFHAbbrevCode, Record);
1730 auto OffsetsAbbrev = std::make_shared<BitCodeAbbrev>();
1732 OffsetsAbbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6));
1733 OffsetsAbbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6));
1735 OffsetsAbbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob));
1736 unsigned OffsetsAbbrevCode = Stream.EmitAbbrev(std::move(OffsetsAbbrev));
1740 InputFileOffsets.size(), UserFilesNum};
1741 Stream.EmitRecordWithBlob(OffsetsAbbrevCode, Record,
bytes(InputFileOffsets));
1751 using namespace llvm;
1753 auto Abbrev = std::make_shared<BitCodeAbbrev>();
1755 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8));
1756 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8));
1757 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 3));
1758 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1));
1760 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6));
1761 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8));
1762 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 24));
1763 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8));
1764 return Stream.EmitAbbrev(std::move(Abbrev));
1770 using namespace llvm;
1772 auto Abbrev = std::make_shared<BitCodeAbbrev>();
1774 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8));
1775 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8));
1776 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 3));
1777 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1));
1778 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob));
1779 return Stream.EmitAbbrev(std::move(Abbrev));
1786 using namespace llvm;
1788 auto Abbrev = std::make_shared<BitCodeAbbrev>();
1792 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8));
1793 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob));
1794 return Stream.EmitAbbrev(std::move(Abbrev));
1800 using namespace llvm;
1802 auto Abbrev = std::make_shared<BitCodeAbbrev>();
1804 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8));
1805 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8));
1806 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6));
1807 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6));
1808 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1));
1809 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6));
1810 return Stream.EmitAbbrev(std::move(Abbrev));
1815static std::pair<unsigned, unsigned>
1817 llvm::encodeULEB128(KeyLen, Out);
1818 llvm::encodeULEB128(DataLen, Out);
1819 return std::make_pair(KeyLen, DataLen);
1825 class HeaderFileInfoTrait {
1830 llvm::StringMap<unsigned> FrameworkNameOffset;
1833 HeaderFileInfoTrait(
ASTWriter &Writer) : Writer(Writer) {}
1840 using key_type_ref =
const key_type &;
1842 using UnresolvedModule =
1843 llvm::PointerIntPair<Module *, 2, ModuleMap::ModuleHeaderRole>;
1847 bool AlreadyIncluded;
1851 using data_type_ref =
const data_type &;
1860 return llvm::hash_combine(key.Size, key.ModTime);
1863 std::pair<unsigned, unsigned>
1864 EmitKeyDataLength(raw_ostream& Out, key_type_ref key, data_type_ref
Data) {
1865 unsigned KeyLen = key.Filename.size() + 1 + 8 + 8;
1866 unsigned DataLen = 1 + 4 + 4;
1867 for (
auto ModInfo :
Data.KnownHeaders)
1870 if (
Data.Unresolved.getPointer())
1875 void EmitKey(raw_ostream& Out, key_type_ref key,
unsigned KeyLen) {
1876 using namespace llvm::support;
1878 endian::Writer
LE(Out, little);
1883 Out.write(key.Filename.data(), KeyLen);
1886 void EmitData(raw_ostream &Out, key_type_ref key,
1887 data_type_ref
Data,
unsigned DataLen) {
1888 using namespace llvm::support;
1890 endian::Writer
LE(Out, little);
1891 uint64_t Start = Out.tell(); (void)Start;
1893 unsigned char Flags = (
Data.AlreadyIncluded << 6)
1894 | (
Data.HFI.isImport << 5)
1895 | (
Data.HFI.isPragmaOnce << 4)
1896 | (
Data.HFI.DirInfo << 1)
1897 |
Data.HFI.IndexHeaderMapHeader;
1898 LE.write<uint8_t>(Flags);
1900 if (!
Data.HFI.ControllingMacro)
1901 LE.write<uint32_t>(
Data.HFI.ControllingMacroID);
1905 unsigned Offset = 0;
1906 if (!
Data.HFI.Framework.empty()) {
1908 llvm::StringMap<unsigned>::iterator Pos
1909 = FrameworkNameOffset.find(
Data.HFI.Framework);
1910 if (Pos == FrameworkNameOffset.end()) {
1911 Offset = FrameworkStringData.size() + 1;
1912 FrameworkStringData.append(
Data.HFI.Framework);
1913 FrameworkStringData.push_back(0);
1915 FrameworkNameOffset[
Data.HFI.Framework] = Offset;
1917 Offset = Pos->second;
1919 LE.write<uint32_t>(Offset);
1923 uint32_t
Value = (ModID << 3) | (
unsigned)Role;
1924 assert((
Value >> 3) == ModID &&
"overflow in header module info");
1929 for (
auto ModInfo :
Data.KnownHeaders)
1930 EmitModule(ModInfo.getModule(), ModInfo.getRole());
1931 if (
Data.Unresolved.getPointer())
1932 EmitModule(
Data.Unresolved.getPointer(),
Data.Unresolved.getInt());
1934 assert(Out.tell() - Start == DataLen &&
"Wrong data length");
1937 const char *strings_begin()
const {
return FrameworkStringData.begin(); }
1938 const char *strings_end()
const {
return FrameworkStringData.end(); }
1946void ASTWriter::WriteHeaderSearch(
const HeaderSearch &HS) {
1947 HeaderFileInfoTrait GeneratorTrait(*
this);
1948 llvm::OnDiskChainedHashTableGenerator<HeaderFileInfoTrait>
Generator;
1950 unsigned NumHeaderSearchEntries = 0;
1957 if (WritingModule) {
1959 while (!Worklist.empty()) {
1960 Module *M = Worklist.pop_back_val();
1977 if (!
U.Size || (!
U.ModTime && IncludeTimestamps)) {
1978 PP->
Diag(
U.FileNameLoc, diag::err_module_no_size_mtime_for_header)
1986 llvm::sys::path::append(
Filename,
U.FileName);
1989 StringRef FilenameDup = strdup(
Filename.c_str());
1990 SavedStrings.push_back(FilenameDup.data());
1992 HeaderFileInfoTrait::key_type Key = {
1993 FilenameDup, *
U.Size, IncludeTimestamps ? *
U.ModTime : 0};
1994 HeaderFileInfoTrait::data_type
Data = {
1999 ++NumHeaderSearchEntries;
2002 Worklist.append(SubmodulesRange.begin(), SubmodulesRange.end());
2012 for (
unsigned UID = 0, LastUID = FilesByUID.size(); UID != LastUID; ++UID) {
2034 Filename = StringRef(strdup(FilenameTmp.c_str()));
2035 SavedStrings.push_back(
Filename.data());
2040 HeaderFileInfoTrait::key_type Key = {
2043 HeaderFileInfoTrait::data_type
Data = {
2047 ++NumHeaderSearchEntries;
2052 uint32_t BucketOffset;
2054 using namespace llvm::support;
2056 llvm::raw_svector_ostream Out(TableData);
2058 endian::write<uint32_t>(Out, 0, little);
2059 BucketOffset =
Generator.Emit(Out, GeneratorTrait);
2063 using namespace llvm;
2065 auto Abbrev = std::make_shared<BitCodeAbbrev>();
2067 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32));
2068 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32));
2069 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32));
2070 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob));
2071 unsigned TableAbbrev = Stream.EmitAbbrev(std::move(Abbrev));
2075 NumHeaderSearchEntries, TableData.size()};
2076 TableData.append(GeneratorTrait.strings_begin(),GeneratorTrait.strings_end());
2077 Stream.EmitRecordWithBlob(TableAbbrev, Record, TableData);
2080 for (
unsigned I = 0, N = SavedStrings.size(); I != N; ++I)
2081 free(
const_cast<char *
>(SavedStrings[I]));
2084static void emitBlob(llvm::BitstreamWriter &Stream, StringRef Blob,
2085 unsigned SLocBufferBlobCompressedAbbrv,
2086 unsigned SLocBufferBlobAbbrv) {
2087 using RecordDataType = ASTWriter::RecordData::value_type;
2092 if (llvm::compression::zstd::isAvailable()) {
2093 llvm::compression::zstd::compress(
2094 llvm::arrayRefFromStringRef(Blob.drop_back(1)), CompressedBuffer, 9);
2096 Stream.EmitRecordWithBlob(SLocBufferBlobCompressedAbbrv, Record,
2097 llvm::toStringRef(CompressedBuffer));
2100 if (llvm::compression::zlib::isAvailable()) {
2101 llvm::compression::zlib::compress(
2102 llvm::arrayRefFromStringRef(Blob.drop_back(1)), CompressedBuffer);
2104 Stream.EmitRecordWithBlob(SLocBufferBlobCompressedAbbrv, Record,
2105 llvm::toStringRef(CompressedBuffer));
2110 Stream.EmitRecordWithBlob(SLocBufferBlobAbbrv, Record, Blob);
2121void ASTWriter::WriteSourceManagerBlock(
SourceManager &SourceMgr,
2127 const uint64_t SourceManagerBlockOffset = Stream.GetCurrentBitNo();
2133 unsigned SLocBufferBlobCompressedAbbrv =
2139 std::vector<uint32_t> SLocEntryOffsets;
2140 uint64_t SLocEntryOffsetsBase = Stream.GetCurrentBitNo();
2147 FileID FID = FileID::get(I);
2151 uint64_t Offset = Stream.GetCurrentBitNo() - SLocEntryOffsetsBase;
2152 assert((Offset >> 32) == 0 &&
"SLocEntry offset too large");
2158 if (
Cache->OrigEntry) {
2171 if (!IsSLocAffecting[I])
2173 SLocEntryOffsets.push_back(Offset);
2177 Record.push_back(
File.getFileCharacteristic());
2180 bool EmitBlob =
false;
2183 "Writing to AST an overridden file is not supported");
2186 assert(InputFileIDs[Content->
OrigEntry] != 0 &&
"Missed file entry");
2189 Record.push_back(getAdjustedNumCreatedFIDs(FID));
2191 FileDeclIDsTy::iterator FDI = FileDeclIDs.find(FID);
2192 if (FDI != FileDeclIDs.end()) {
2193 Record.push_back(FDI->second->FirstDeclIndex);
2194 Record.push_back(FDI->second->DeclIDs.size());
2200 Stream.EmitRecordWithAbbrev(SLocFileAbbrv, Record);
2211 std::optional<llvm::MemoryBufferRef> Buffer =
2213 StringRef Name = Buffer ? Buffer->getBufferIdentifier() :
"";
2214 Stream.EmitRecordWithBlob(SLocBufferAbbrv, Record,
2215 StringRef(Name.data(), Name.size() + 1));
2218 if (Name ==
"<built-in>")
2219 PreloadSLocs.push_back(SLocEntryOffsets.size());
2225 std::optional<llvm::MemoryBufferRef> Buffer =
2228 Buffer = llvm::MemoryBufferRef(
"<<<INVALID BUFFER>>>",
"");
2229 StringRef Blob(Buffer->getBufferStart(), Buffer->getBufferSize() + 1);
2230 emitBlob(Stream, Blob, SLocBufferBlobCompressedAbbrv,
2231 SLocBufferBlobAbbrv);
2236 SLocEntryOffsets.push_back(Offset);
2252 Record.push_back(getAdjustedOffset(NextOffset - SLoc->
getOffset()) - 1);
2253 Stream.EmitRecordWithAbbrev(SLocExpansionAbbrv, Record);
2259 if (SLocEntryOffsets.empty())
2264 using namespace llvm;
2266 auto Abbrev = std::make_shared<BitCodeAbbrev>();
2268 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 16));
2269 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 16));
2270 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 32));
2271 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob));
2272 unsigned SLocOffsetsAbbrev = Stream.EmitAbbrev(std::move(Abbrev));
2274 RecordData::value_type
Record[] = {
2277 SLocEntryOffsetsBase - SourceManagerBlockOffset};
2278 Stream.EmitRecordWithBlob(SLocOffsetsAbbrev, Record,
2279 bytes(SLocEntryOffsets));
2293 llvm::DenseMap<int, int> FilenameMap;
2294 FilenameMap[-1] = -1;
2295 for (
const auto &L : LineTable) {
2298 for (
auto &LE : L.second) {
2299 if (FilenameMap.insert(std::make_pair(
LE.FilenameID,
2300 FilenameMap.size() - 1)).second)
2301 AddPath(LineTable.getFilename(
LE.FilenameID), Record);
2307 for (
const auto &L : LineTable) {
2315 Record.push_back(L.second.size());
2316 for (
const auto &LE : L.second) {
2319 Record.push_back(FilenameMap[
LE.FilenameID]);
2320 Record.push_back((
unsigned)
LE.FileKind);
2321 Record.push_back(
LE.IncludeOffset);
2336 if (MI->isBuiltinMacro())
2352void ASTWriter::WritePreprocessor(
const Preprocessor &PP,
bool IsModule) {
2353 uint64_t MacroOffsetsBase = Stream.GetCurrentBitNo();
2357 WritePreprocessorDetail(*PPRec, MacroOffsetsBase);
2372 if (AssumeNonNullLoc.
isValid()) {
2386 Record.push_back(SkipInfo->FoundNonSkipPortion);
2387 Record.push_back(SkipInfo->FoundElse);
2394 Record.push_back(Cond.WasSkipping);
2395 Record.push_back(Cond.FoundNonSkip);
2396 Record.push_back(Cond.FoundElse);
2420 if (
Id.second->hadMacroDefinition() &&
2421 (!
Id.second->isFromAST() ||
2422 Id.second->hasChangedSinceDeserialization()))
2423 MacroIdentifiers.push_back(
Id.second);
2426 llvm::sort(MacroIdentifiers, llvm::deref<std::less<>>());
2432 uint64_t StartOffset = Stream.GetCurrentBitNo() - MacroOffsetsBase;
2433 assert((StartOffset >> 32) == 0 &&
"Macro identifiers offset too large");
2436 bool EmittedModuleMacros =
false;
2453 if (
auto *DefMD = dyn_cast<DefMacroDirective>(MD)) {
2455 }
else if (
auto *VisMD = dyn_cast<VisibilityMacroDirective>(MD)) {
2456 Record.push_back(VisMD->isPublic());
2458 ModuleMacroRecord.push_back(getSubmoduleID(WritingModule));
2461 ModuleMacroRecord.clear();
2462 EmittedModuleMacros =
true;
2472 if (
auto *DefMD = dyn_cast<DefMacroDirective>(MD)) {
2474 }
else if (
auto *VisMD = dyn_cast<VisibilityMacroDirective>(MD)) {
2475 Record.push_back(VisMD->isPublic());
2482 llvm::DenseMap<ModuleMacro *, unsigned> Visits;
2483 while (!Worklist.empty()) {
2484 auto *
Macro = Worklist.pop_back_val();
2487 ModuleMacroRecord.push_back(getSubmoduleID(
Macro->getOwningModule()));
2489 for (
auto *M :
Macro->overrides())
2490 ModuleMacroRecord.push_back(getSubmoduleID(M->getOwningModule()));
2493 ModuleMacroRecord.clear();
2496 for (
auto *M :
Macro->overrides())
2497 if (++Visits[M] == M->getNumOverridingMacros())
2498 Worklist.push_back(M);
2500 EmittedModuleMacros =
true;
2503 if (
Record.empty() && !EmittedModuleMacros)
2506 IdentMacroDirectivesOffsetMap[Name] = StartOffset;
2517 std::vector<uint32_t> MacroOffsets;
2519 for (
unsigned I = 0, N = MacroInfosToEmit.size(); I != N; ++I) {
2524 if (ID < FirstMacroID) {
2525 assert(0 &&
"Loaded MacroInfo entered MacroInfosToEmit ?");
2530 unsigned Index =
ID - FirstMacroID;
2531 if (Index >= MacroOffsets.size())
2532 MacroOffsets.resize(Index + 1);
2534 uint64_t Offset = Stream.GetCurrentBitNo() - MacroOffsetsBase;
2535 assert((Offset >> 32) == 0 &&
"Macro offset too large");
2536 MacroOffsets[Index] = Offset;
2563 Stream.EmitRecord(Code, Record);
2567 for (
unsigned TokNo = 0, e = MI->
getNumTokens(); TokNo != e; ++TokNo) {
2573 Stream.EmitRecord(
PP_TOKEN, Record);
2582 using namespace llvm;
2584 auto Abbrev = std::make_shared<BitCodeAbbrev>();
2586 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32));
2587 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32));
2588 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 32));
2589 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob));
2591 unsigned MacroOffsetAbbrev = Stream.EmitAbbrev(std::move(Abbrev));
2595 MacroOffsetsBase - ASTBlockStartOffset};
2596 Stream.EmitRecordWithBlob(MacroOffsetAbbrev, Record,
bytes(MacroOffsets));
2601 uint64_t MacroOffsetsBase) {
2611 unsigned NumPreprocessingRecords = 0;
2612 using namespace llvm;
2615 unsigned InclusionAbbrev = 0;
2617 auto Abbrev = std::make_shared<BitCodeAbbrev>();
2619 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32));
2620 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1));
2621 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 2));
2622 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1));
2623 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob));
2624 InclusionAbbrev = Stream.EmitAbbrev(std::move(Abbrev));
2627 unsigned FirstPreprocessorEntityID
2628 = (Chain ? PPRec.getNumLoadedPreprocessedEntities() : 0)
2630 unsigned NextPreprocessorEntityID = FirstPreprocessorEntityID;
2635 (void)++E, ++NumPreprocessingRecords, ++NextPreprocessorEntityID) {
2638 uint64_t Offset = Stream.GetCurrentBitNo() - MacroOffsetsBase;
2639 assert((Offset >> 32) == 0 &&
"Preprocessed entity offset too large");
2640 PreprocessedEntityOffsets.push_back(
2641 PPEntityOffset(getAdjustedRange((*E)->getSourceRange()), Offset));
2643 if (
auto *MD = dyn_cast<MacroDefinitionRecord>(*E)) {
2645 MacroDefinitions[MD] = NextPreprocessorEntityID;
2652 if (
auto *ME = dyn_cast<MacroExpansion>(*E)) {
2653 Record.push_back(ME->isBuiltinMacro());
2654 if (ME->isBuiltinMacro())
2657 Record.push_back(MacroDefinitions[ME->getDefinition()]);
2662 if (
auto *ID = dyn_cast<InclusionDirective>(*E)) {
2664 Record.push_back(
ID->getFileName().size());
2665 Record.push_back(
ID->wasInQuotes());
2666 Record.push_back(
static_cast<unsigned>(
ID->getKind()));
2667 Record.push_back(
ID->importedModule());
2669 Buffer +=
ID->getFileName();
2673 Buffer +=
ID->getFile()->getName();
2674 Stream.EmitRecordWithBlob(InclusionAbbrev, Record, Buffer);
2678 llvm_unreachable(
"Unhandled PreprocessedEntity in ASTWriter");
2683 if (NumPreprocessingRecords > 0) {
2684 assert(PreprocessedEntityOffsets.size() == NumPreprocessingRecords);
2687 using namespace llvm;
2689 auto Abbrev = std::make_shared<BitCodeAbbrev>();
2691 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32));
2692 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob));
2693 unsigned PPEOffsetAbbrev = Stream.EmitAbbrev(std::move(Abbrev));
2696 FirstPreprocessorEntityID -
2698 Stream.EmitRecordWithBlob(PPEOffsetAbbrev, Record,
2699 bytes(PreprocessedEntityOffsets));
2704 if (SkippedRanges.size() > 0) {
2705 std::vector<PPSkippedRange> SerializedSkippedRanges;
2706 SerializedSkippedRanges.reserve(SkippedRanges.size());
2707 for (
auto const& Range : SkippedRanges)
2708 SerializedSkippedRanges.emplace_back(Range);
2710 using namespace llvm;
2711 auto Abbrev = std::make_shared<BitCodeAbbrev>();
2713 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob));
2714 unsigned PPESkippedRangeAbbrev = Stream.EmitAbbrev(std::move(Abbrev));
2718 Stream.EmitRecordWithBlob(PPESkippedRangeAbbrev, Record,
2719 bytes(SerializedSkippedRanges));
2727 auto Known = SubmoduleIDs.find(Mod);
2728 if (Known != SubmoduleIDs.end())
2729 return Known->second;
2732 if (Top != WritingModule &&
2734 !Top->fullModuleNameIs(StringRef(
getLangOpts().CurrentModule))))
2737 return SubmoduleIDs[Mod] = NextSubmoduleID++;
2740unsigned ASTWriter::getSubmoduleID(
Module *Mod) {
2753 unsigned ChildModules = 0;
2757 return ChildModules + 1;
2760void ASTWriter::WriteSubmodules(
Module *WritingModule) {
2765 using namespace llvm;
2767 auto Abbrev = std::make_shared<BitCodeAbbrev>();
2769 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6));
2770 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6));
2771 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 4));
2772 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8));
2773 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1));
2774 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1));
2775 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1));
2776 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1));
2777 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1));
2778 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1));
2779 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1));
2780 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1));
2781 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1));
2782 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob));
2783 unsigned DefinitionAbbrev = Stream.EmitAbbrev(std::move(Abbrev));
2785 Abbrev = std::make_shared<BitCodeAbbrev>();
2787 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob));
2788 unsigned UmbrellaAbbrev = Stream.EmitAbbrev(std::move(Abbrev));
2790 Abbrev = std::make_shared<BitCodeAbbrev>();
2792 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob));
2793 unsigned HeaderAbbrev = Stream.EmitAbbrev(std::move(Abbrev));
2795 Abbrev = std::make_shared<BitCodeAbbrev>();
2797 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob));
2798 unsigned TopHeaderAbbrev = Stream.EmitAbbrev(std::move(Abbrev));
2800 Abbrev = std::make_shared<BitCodeAbbrev>();
2802 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob));
2803 unsigned UmbrellaDirAbbrev = Stream.EmitAbbrev(std::move(Abbrev));
2805 Abbrev = std::make_shared<BitCodeAbbrev>();
2807 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1));
2808 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob));
2809 unsigned RequiresAbbrev = Stream.EmitAbbrev(std::move(Abbrev));
2811 Abbrev = std::make_shared<BitCodeAbbrev>();
2813 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob));
2814 unsigned ExcludedHeaderAbbrev = Stream.EmitAbbrev(std::move(Abbrev));
2816 Abbrev = std::make_shared<BitCodeAbbrev>();
2818 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob));
2819 unsigned TextualHeaderAbbrev = Stream.EmitAbbrev(std::move(Abbrev));
2821 Abbrev = std::make_shared<BitCodeAbbrev>();
2823 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob));
2824 unsigned PrivateHeaderAbbrev = Stream.EmitAbbrev(std::move(Abbrev));
2826 Abbrev = std::make_shared<BitCodeAbbrev>();
2828 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob));
2829 unsigned PrivateTextualHeaderAbbrev = Stream.EmitAbbrev(std::move(Abbrev));
2831 Abbrev = std::make_shared<BitCodeAbbrev>();
2833 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1));
2834 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob));
2835 unsigned LinkLibraryAbbrev = Stream.EmitAbbrev(std::move(Abbrev));
2837 Abbrev = std::make_shared<BitCodeAbbrev>();
2839 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob));
2840 unsigned ConfigMacroAbbrev = Stream.EmitAbbrev(std::move(Abbrev));
2842 Abbrev = std::make_shared<BitCodeAbbrev>();
2844 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6));
2845 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob));
2846 unsigned ConflictAbbrev = Stream.EmitAbbrev(std::move(Abbrev));
2848 Abbrev = std::make_shared<BitCodeAbbrev>();
2850 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob));
2851 unsigned ExportAsAbbrev = Stream.EmitAbbrev(std::move(Abbrev));
2854 RecordData::value_type
Record[] = {
2860 std::queue<Module *> Q;
2861 Q.push(WritingModule);
2862 while (!Q.empty()) {
2865 unsigned ID = getSubmoduleID(Mod);
2869 assert(SubmoduleIDs[Mod->
Parent] &&
"Submodule parent not written?");
2870 ParentID = SubmoduleIDs[Mod->
Parent];
2881 (RecordData::value_type)Mod->
Kind,
2892 Stream.EmitRecordWithBlob(DefinitionAbbrev, Record, Mod->
Name);
2898 Stream.EmitRecordWithBlob(RequiresAbbrev, Record, R.first);
2902 if (std::optional<Module::Header> UmbrellaHeader =
2905 Stream.EmitRecordWithBlob(UmbrellaAbbrev, Record,
2906 UmbrellaHeader->NameAsWritten);
2907 }
else if (std::optional<Module::DirectoryName> UmbrellaDir =
2910 Stream.EmitRecordWithBlob(UmbrellaDirAbbrev, Record,
2911 UmbrellaDir->NameAsWritten);
2916 unsigned RecordKind;
2927 for (
auto &HL : HeaderLists) {
2928 RecordData::value_type
Record[] = {HL.RecordKind};
2929 for (
auto &H : Mod->
Headers[HL.HeaderKind])
2930 Stream.EmitRecordWithBlob(HL.Abbrev, Record, H.NameAsWritten);
2939 Stream.EmitRecordWithBlob(TopHeaderAbbrev, Record, HeaderName);
2947 Record.push_back(getSubmoduleID(I));
2955 Record.push_back(getSubmoduleID(I));
2962 for (
const auto &E : Mod->
Exports) {
2965 Record.push_back(getSubmoduleID(E.getPointer()));
2966 Record.push_back(E.getInt());
2981 Stream.EmitRecordWithBlob(LinkLibraryAbbrev, Record, LL.Library);
2989 getSubmoduleID(
C.Other)};
2990 Stream.EmitRecordWithBlob(ConflictAbbrev, Record,
C.Message);
2996 Stream.EmitRecordWithBlob(ConfigMacroAbbrev, Record, CM);
3009 Stream.EmitRecordWithBlob(ExportAsAbbrev, Record, Mod->
ExportAsModule);
3019 assert((NextSubmoduleID - FirstSubmoduleID ==
3021 "Wrong # of submodules; found a reference to a non-local, "
3022 "non-imported submodule?");
3027 llvm::SmallDenseMap<const DiagnosticsEngine::DiagState *, unsigned, 64>
3029 unsigned CurrID = 0;
3032 auto EncodeDiagStateFlags =
3033 [](
const DiagnosticsEngine::DiagState *DS) ->
unsigned {
3036 {(
unsigned)DS->IgnoreAllWarnings, (
unsigned)DS->EnableAllWarnings,
3037 (
unsigned)DS->WarningsAsErrors, (
unsigned)DS->ErrorsAsFatal,
3038 (
unsigned)DS->SuppressSystemWarnings})
3043 unsigned Flags = EncodeDiagStateFlags(
Diag.DiagStatesByLoc.FirstDiagState);
3046 auto AddDiagState = [&](
const DiagnosticsEngine::DiagState *State,
3047 bool IncludeNonPragmaStates) {
3050 assert(Flags == EncodeDiagStateFlags(State) &&
3051 "diag state flags vary in single AST file");
3055 assert(!IncludeNonPragmaStates ||
3056 State ==
Diag.DiagStatesByLoc.FirstDiagState);
3058 unsigned &DiagStateID = DiagStateIDMap[State];
3059 Record.push_back(DiagStateID);
3061 if (DiagStateID == 0) {
3062 DiagStateID = ++CurrID;
3066 auto SizeIdx =
Record.size();
3068 for (
const auto &I : *State) {
3070 if (!I.second.isPragma() && !IncludeNonPragmaStates)
3074 if (!I.second.isPragma() &&
3077 Mappings.push_back(I);
3081 llvm::sort(Mappings, [](
const auto &LHS,
const auto &RHS) {
3082 return LHS.first < RHS.first;
3085 for (
const auto &I : Mappings) {
3086 Record.push_back(I.first);
3087 Record.push_back(I.second.serialize());
3094 AddDiagState(
Diag.DiagStatesByLoc.FirstDiagState, isModule);
3097 auto NumLocationsIdx =
Record.size();
3101 unsigned NumLocations = 0;
3102 for (
auto &FileIDAndFile :
Diag.DiagStatesByLoc.Files) {
3103 if (!FileIDAndFile.first.isValid() ||
3104 !FileIDAndFile.second.HasLocalTransitions)
3109 assert(!Loc.
isInvalid() &&
"start loc for valid FileID is invalid");
3112 Record.push_back(FileIDAndFile.second.StateTransitions.size());
3113 for (
auto &StatePoint : FileIDAndFile.second.StateTransitions) {
3114 Record.push_back(getAdjustedOffset(StatePoint.Offset));
3115 AddDiagState(StatePoint.State,
false);
3120 Record[NumLocationsIdx] = NumLocations;
3129 AddDiagState(
Diag.DiagStatesByLoc.CurDiagState,
false);
3139void ASTWriter::WriteType(
QualType T) {
3140 TypeIdx &IdxRef = TypeIdxs[T];
3142 IdxRef =
TypeIdx(NextTypeID++);
3145 assert(Idx.
getIndex() >= FirstTypeID &&
"Re-writing a type from a prior AST");
3148 uint64_t Offset = ASTTypeWriter(*this).write(T) - DeclTypesBlockStartOffset;
3151 unsigned Index = Idx.
getIndex() - FirstTypeID;
3152 if (TypeOffsets.size() == Index)
3153 TypeOffsets.emplace_back(Offset);
3154 else if (TypeOffsets.size() < Index) {
3155 TypeOffsets.resize(Index + 1);
3156 TypeOffsets[Index].setBitOffset(Offset);
3158 llvm_unreachable(
"Types emitted in wrong order");
3176 uint64_t Offset = Stream.GetCurrentBitNo();
3178 for (
const auto *D : DC->
decls()) {
3179 KindDeclPairs.push_back(D->getKind());
3183 ++NumLexicalDeclContexts;
3185 Stream.EmitRecordWithBlob(DeclContextLexicalAbbrev, Record,
3186 bytes(KindDeclPairs));
3190void ASTWriter::WriteTypeDeclOffsets() {
3191 using namespace llvm;
3194 auto Abbrev = std::make_shared<BitCodeAbbrev>();
3196 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32));
3197 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32));
3198 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob));
3199 unsigned TypeOffsetAbbrev = Stream.EmitAbbrev(std::move(Abbrev));
3203 Stream.EmitRecordWithBlob(TypeOffsetAbbrev, Record,
bytes(TypeOffsets));
3207 Abbrev = std::make_shared<BitCodeAbbrev>();
3209 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32));
3210 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32));
3211 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob));
3212 unsigned DeclOffsetAbbrev = Stream.EmitAbbrev(std::move(Abbrev));
3216 Stream.EmitRecordWithBlob(DeclOffsetAbbrev, Record,
bytes(DeclOffsets));
3220void ASTWriter::WriteFileDeclIDsMap() {
3221 using namespace llvm;
3224 SortedFileDeclIDs.reserve(FileDeclIDs.size());
3225 for (
const auto &
P : FileDeclIDs)
3226 SortedFileDeclIDs.push_back(std::make_pair(
P.first,
P.second.get()));
3227 llvm::sort(SortedFileDeclIDs, llvm::less_first());
3231 for (
auto &FileDeclEntry : SortedFileDeclIDs) {
3232 DeclIDInFileInfo &Info = *FileDeclEntry.second;
3233 Info.FirstDeclIndex = FileGroupedDeclIDs.size();
3234 llvm::stable_sort(Info.DeclIDs);
3235 for (
auto &LocDeclEntry : Info.DeclIDs)
3236 FileGroupedDeclIDs.push_back(LocDeclEntry.second);
3239 auto Abbrev = std::make_shared<BitCodeAbbrev>();
3241 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32));
3242 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob));
3243 unsigned AbbrevCode = Stream.EmitAbbrev(std::move(Abbrev));
3245 FileGroupedDeclIDs.size()};
3246 Stream.EmitRecordWithBlob(AbbrevCode, Record,
bytes(FileGroupedDeclIDs));
3249void ASTWriter::WriteComments() {
3251 auto _ = llvm::make_scope_exit([
this] { Stream.ExitBlock(); });
3262 for (
const auto &FO : Context->
Comments.OrderedComments) {
3263 for (
const auto &OC : FO.second) {
3282class ASTMethodPoolTrait {
3287 using key_type_ref = key_type;
3293 using data_type_ref =
const data_type &;
3298 explicit ASTMethodPoolTrait(
ASTWriter &Writer) : Writer(Writer) {}
3304 std::pair<unsigned, unsigned>
3305 EmitKeyDataLength(raw_ostream& Out,
Selector Sel,
3306 data_type_ref Methods) {
3308 unsigned DataLen = 4 + 2 + 2;
3311 if (ShouldWriteMethodListNode(Method))
3315 if (ShouldWriteMethodListNode(Method))
3320 void EmitKey(raw_ostream& Out,
Selector Sel,
unsigned) {
3321 using namespace llvm::support;
3323 endian::Writer
LE(Out, little);
3325 assert((Start >> 32) == 0 &&
"Selector key offset too large");
3328 LE.write<uint16_t>(N);
3331 for (
unsigned I = 0; I != N; ++I)
3336 void EmitData(raw_ostream& Out, key_type_ref,
3337 data_type_ref Methods,
unsigned DataLen) {
3338 using namespace llvm::support;
3340 endian::Writer
LE(Out, little);
3341 uint64_t Start = Out.tell(); (void)Start;
3342 LE.write<uint32_t>(Methods.ID);
3343 unsigned NumInstanceMethods = 0;
3346 if (ShouldWriteMethodListNode(Method))
3347 ++NumInstanceMethods;
3349 unsigned NumFactoryMethods = 0;
3352 if (ShouldWriteMethodListNode(Method))
3353 ++NumFactoryMethods;
3355 unsigned InstanceBits = Methods.Instance.getBits();
3356 assert(InstanceBits < 4);
3357 unsigned InstanceHasMoreThanOneDeclBit =
3358 Methods.Instance.hasMoreThanOneDecl();
3359 unsigned FullInstanceBits = (NumInstanceMethods << 3) |
3360 (InstanceHasMoreThanOneDeclBit << 2) |
3362 unsigned FactoryBits = Methods.Factory.getBits();
3363 assert(FactoryBits < 4);
3364 unsigned FactoryHasMoreThanOneDeclBit =
3365 Methods.Factory.hasMoreThanOneDecl();
3366 unsigned FullFactoryBits = (NumFactoryMethods << 3) |
3367 (FactoryHasMoreThanOneDeclBit << 2) |
3369 LE.write<uint16_t>(FullInstanceBits);
3370 LE.write<uint16_t>(FullFactoryBits);
3373 if (ShouldWriteMethodListNode(Method))
3374 LE.write<uint32_t>(Writer.
getDeclID(Method->getMethod()));
3377 if (ShouldWriteMethodListNode(Method))
3378 LE.write<uint32_t>(Writer.
getDeclID(Method->getMethod()));
3380 assert(Out.tell() - Start == DataLen &&
"Data length is wrong");
3385 return (
Node->getMethod() && !
Node->getMethod()->isFromASTFile());
3396void ASTWriter::WriteSelectors(
Sema &SemaRef) {
3397 using namespace llvm;
3402 unsigned NumTableEntries = 0;
3405 llvm::OnDiskChainedHashTableGenerator<ASTMethodPoolTrait>
Generator;
3406 ASTMethodPoolTrait Trait(*
this);
3410 SelectorOffsets.resize(NextSelectorID - FirstSelectorID);
3411 for (
auto &SelectorAndID : SelectorIDs) {
3415 ASTMethodPoolTrait::data_type
Data = {
3421 Data.Instance = F->second.first;
3422 Data.Factory = F->second.second;
3426 if (Chain && ID < FirstSelectorID) {
3428 bool changed =
false;
3431 if (!M->getMethod()->isFromASTFile()) {
3439 if (!M->getMethod()->isFromASTFile()) {
3447 }
else if (
Data.Instance.getMethod() ||
Data.Factory.getMethod()) {
3456 uint32_t BucketOffset;
3458 using namespace llvm::support;
3460 ASTMethodPoolTrait Trait(*
this);
3461 llvm::raw_svector_ostream Out(MethodPool);
3463 endian::write<uint32_t>(Out, 0, little);
3464 BucketOffset =
Generator.Emit(Out, Trait);
3468 auto Abbrev = std::make_shared<BitCodeAbbrev>();
3470 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32));
3471 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32));
3472 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob));
3473 unsigned MethodPoolAbbrev = Stream.EmitAbbrev(std::move(Abbrev));
3479 Stream.EmitRecordWithBlob(MethodPoolAbbrev, Record, MethodPool);
3483 Abbrev = std::make_shared<BitCodeAbbrev>();
3485 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32));
3486 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32));
3487 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob));
3488 unsigned SelectorOffsetAbbrev = Stream.EmitAbbrev(std::move(Abbrev));
3492 RecordData::value_type
Record[] = {
3495 Stream.EmitRecordWithBlob(SelectorOffsetAbbrev, Record,
3496 bytes(SelectorOffsets));
3502void ASTWriter::WriteReferencedSelectorsPool(
Sema &SemaRef) {
3503 using namespace llvm;
3515 Selector Sel = SelectorAndLocation.first;
3517 Writer.AddSelectorRef(Sel);
3539 for (; Redecl; Redecl = Redecl->getPreviousDecl()) {
3541 if (!Redecl->isFromASTFile()) {
3545 if (!Redecl->getDeclContext()->getRedeclContext()->Equals(
3548 return cast<NamedDecl>(Redecl);
3553 if (Redecl->getOwningModuleID() == 0)
3558 if (!
First->isFromASTFile())
3559 return cast<NamedDecl>(
First);
3569class ASTIdentifierTableTrait {
3593 using key_type_ref = key_type;
3596 using data_type_ref = data_type;
3604 : Writer(Writer), PP(PP), IdResolver(IdResolver), IsModule(IsModule),
3605 NeedDecls(!IsModule || !Writer.getLangOpts().
CPlusPlus),
3606 InterestingIdentifierOffsets(InterestingIdentifierOffsets) {}
3608 bool needDecls()
const {
return NeedDecls; }
3611 return llvm::djbHash(II->
getName());
3623 std::pair<unsigned, unsigned>
3633 if (InterestingIdentifierOffsets &&
3635 InterestingIdentifierOffsets->push_back(Out.tell());
3638 unsigned DataLen = 4;
3646 DataLen += std::distance(IdResolver.
begin(II), IdResolver.
end()) * 4;
3658 using namespace llvm::support;
3660 endian::Writer
LE(Out, little);
3664 LE.write<uint32_t>(
ID << 1);
3668 LE.write<uint32_t>((
ID << 1) | 0x01);
3670 assert((Bits & 0xffff) == Bits &&
"ObjCOrBuiltinID too big for ASTReader.");
3671 LE.write<uint16_t>(Bits);
3673 bool HadMacroDefinition = MacroOffset != 0;
3674 Bits = (Bits << 1) |
unsigned(HadMacroDefinition);
3676 Bits = (Bits << 1) |
unsigned(II->
isPoisoned());
3679 LE.write<uint16_t>(Bits);
3681 if (HadMacroDefinition)
3682 LE.write<uint32_t>(MacroOffset);
3692 for (
NamedDecl *D : llvm::reverse(Decls))
3709 using namespace llvm;
3716 llvm::OnDiskChainedHashTableGenerator<ASTIdentifierTableTrait>
Generator;
3717 ASTIdentifierTableTrait Trait(*
this, PP, IdResolver, IsModule,
3718 IsModule ? &InterestingIdents :
nullptr);
3727 if (Trait.isInterestingNonMacroIdentifier(
ID.second))
3728 IIs.push_back(
ID.second);
3731 llvm::sort(IIs, llvm::deref<std::less<>>());
3737 IdentifierOffsets.resize(NextIdentID - FirstIdentID);
3738 for (
auto IdentIDPair : IdentifierIDs) {
3741 assert(II &&
"NULL identifier in identifier table");
3744 if (ID >= FirstIdentID || !Chain || !II->
isFromAST()
3746 (Trait.needDecls() &&
3753 uint32_t BucketOffset;
3755 using namespace llvm::support;
3759 endian::write<uint32_t>(Out, 0, little);
3760 BucketOffset =
Generator.Emit(Out, Trait);
3764 auto Abbrev = std::make_shared<BitCodeAbbrev>();
3766 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32));
3767 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob));
3768 unsigned IDTableAbbrev = Stream.EmitAbbrev(std::move(Abbrev));
3776 auto Abbrev = std::make_shared<BitCodeAbbrev>();
3778 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32));
3779 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32));
3780 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob));
3781 unsigned IdentifierOffsetAbbrev = Stream.EmitAbbrev(std::move(Abbrev));
3784 for (
unsigned I = 0, N = IdentifierOffsets.size(); I != N; ++I)
3785 assert(IdentifierOffsets[I] &&
"Missing identifier offset?");
3789 IdentifierOffsets.size(),
3791 Stream.EmitRecordWithBlob(IdentifierOffsetAbbrev, Record,
3792 bytes(IdentifierOffsets));
3796 if (!InterestingIdents.empty())
3807class ASTDeclContextNameLookupTrait {
3813 using key_type_ref = key_type;
3816 using data_type = std::pair<unsigned, unsigned>;
3817 using data_type_ref =
const data_type &;
3822 explicit ASTDeclContextNameLookupTrait(
ASTWriter &Writer) : Writer(Writer) {}
3824 template<
typename Coll>
3825 data_type getData(
const Coll &Decls) {
3826 unsigned Start = DeclIDs.size();
3831 return std::make_pair(Start, DeclIDs.size());
3835 unsigned Start = DeclIDs.size();
3836 llvm::append_range(DeclIDs, FromReader);
3837 return std::make_pair(Start, DeclIDs.size());
3840 static bool EqualKey(key_type_ref a, key_type_ref
b) {
3845 return Name.getHash();
3848 void EmitFileRef(raw_ostream &Out,
ModuleFile *F)
const {
3850 "have reference to loaded module file but no chain?");
3852 using namespace llvm::support;
3857 std::pair<unsigned, unsigned> EmitKeyDataLength(raw_ostream &Out,
3859 data_type_ref Lookup) {
3860 unsigned KeyLen = 1;
3861 switch (Name.getKind()) {
3881 unsigned DataLen = 4 * (Lookup.second - Lookup.first);
3887 using namespace llvm::support;
3889 endian::Writer
LE(Out, little);
3890 LE.write<uint8_t>(Name.getKind());
3891 switch (Name.getKind()) {
3904 "Invalid operator?");
3905 LE.write<uint8_t>(Name.getOperatorKind());
3914 llvm_unreachable(
"Invalid name kind?");
3917 void EmitData(raw_ostream &Out, key_type_ref, data_type Lookup,
3919 using namespace llvm::support;
3921 endian::Writer
LE(Out, little);
3922 uint64_t Start = Out.tell(); (void)Start;
3923 for (
unsigned I = Lookup.first, N = Lookup.second; I != N; ++I)
3924 LE.write<uint32_t>(DeclIDs[I]);
3925 assert(Out.tell() - Start == DataLen &&
"Data length is wrong");
3933 return Result.hasExternalDecls() &&
3934 DC->hasNeedToReconcileExternalVisibleStorage();
3939 for (
auto *D :
Result.getLookupResult())
3947ASTWriter::GenerateNameLookupTable(
const DeclContext *ConstDC,
3949 assert(!ConstDC->hasLazyLocalLexicalLookups() &&
3950 !ConstDC->hasLazyExternalLexicalLookups() &&
3951 "must call buildLookups first");
3959 ASTDeclContextNameLookupTrait>
Generator;
3960 ASTDeclContextNameLookupTrait Trait(*
this);
3972 auto &Name = Lookup.first;
3973 auto &
Result = Lookup.second;
3979 if (isLookupResultExternal(
Result, DC) &&
3980 isLookupResultEntirelyExternal(
Result, DC))
3997 if (Lookup.second.getLookupResult().empty())
4000 switch (Lookup.first.getNameKind()) {
4002 Names.push_back(Lookup.first);
4006 assert(isa<CXXRecordDecl>(DC) &&
4007 "Cannot have a constructor name outside of a class!");
4008 ConstructorNameSet.insert(Name);
4012 assert(isa<CXXRecordDecl>(DC) &&
4013 "Cannot have a conversion function name outside of a class!");
4014 ConversionNameSet.insert(Name);
4022 if (
auto *D = dyn_cast<CXXRecordDecl>(DC)) {
4036 if (ConstructorNameSet.erase(ImplicitCtorName))
4037 Names.push_back(ImplicitCtorName);
4042 if (!ConstructorNameSet.empty() || !ConversionNameSet.empty())
4043 for (
Decl *ChildD : cast<CXXRecordDecl>(DC)->decls())
4044 if (
auto *ChildND = dyn_cast<NamedDecl>(ChildD)) {
4045 auto Name = ChildND->getDeclName();
4046 switch (Name.getNameKind()) {
4051 if (ConstructorNameSet.erase(Name))
4052 Names.push_back(Name);
4056 if (ConversionNameSet.erase(Name))
4057 Names.push_back(Name);
4061 if (ConstructorNameSet.empty() && ConversionNameSet.empty())
4065 assert(ConstructorNameSet.empty() &&
"Failed to find all of the visible "
4066 "constructors by walking all the "
4067 "lexical members of the context.");
4068 assert(ConversionNameSet.empty() &&
"Failed to find all of the visible "
4069 "conversion functions by walking all "
4070 "the lexical members of the context.");
4077 for (
auto &Name : Names)
4089 for (
auto &Name : Names) {
4092 switch (Name.getNameKind()) {
4110 if (!ConstructorDecls.empty())
4111 Generator.insert(ConstructorDecls.front()->getDeclName(),
4112 Trait.getData(ConstructorDecls), Trait);
4113 if (!ConversionDecls.empty())
4114 Generator.insert(ConversionDecls.front()->getDeclName(),
4115 Trait.getData(ConversionDecls), Trait);
4120 Generator.emit(LookupTable, Trait, Lookups ? &Lookups->Table :
nullptr);
4133 if (isa<NamespaceDecl>(DC) && Chain &&
4136 for (
auto *Prev = cast<NamespaceDecl>(DC)->getPreviousDecl(); Prev;
4137 Prev = Prev->getPreviousDecl())
4138 if (!Prev->isFromASTFile())
4151 LookupResults.reserve(Map->size());
4152 for (
auto &Entry : *Map)
4153 LookupResults.push_back(
4154 std::make_pair(Entry.first, Entry.second.getLookupResult()));
4157 llvm::sort(LookupResults, llvm::less_first());
4158 for (
auto &NameAndResult : LookupResults) {
4166 assert(
Result.empty() &&
"Cannot have a constructor or conversion "
4167 "function name in a namespace!");
4172 if (!ND->isFromASTFile())
4196 uint64_t Offset = Stream.GetCurrentBitNo();
4198 if (!Map || Map->empty())
4203 GenerateNameLookupTable(DC, LookupTable);
4207 Stream.EmitRecordWithBlob(DeclContextVisibleLookupAbbrev, Record,
4209 ++NumVisibleDeclContexts;
4219void ASTWriter::WriteDeclContextVisibleUpdate(
const DeclContext *DC) {
4221 if (!Map || Map->empty())
4226 GenerateNameLookupTable(DC, LookupTable);
4230 if (isa<NamespaceDecl>(DC))
4235 Stream.EmitRecordWithBlob(UpdateVisibleAbbrev, Record, LookupTable);
4245void ASTWriter::WriteOpenCLExtensions(
Sema &SemaRef) {
4251 for (
const auto &I:Opts.OptMap) {
4253 auto V = I.getValue();
4254 Record.push_back(
V.Supported ? 1 : 0);
4255 Record.push_back(
V.Enabled ? 1 : 0);
4256 Record.push_back(
V.WithPragma ? 1 : 0);
4263void ASTWriter::WriteCUDAPragmas(
Sema &SemaRef) {
4264 if (SemaRef.ForceCUDAHostDeviceDepth > 0) {
4265 RecordData::value_type
Record[] = {SemaRef.ForceCUDAHostDeviceDepth};
4270void ASTWriter::WriteObjCCategories() {
4274 for (
unsigned I = 0, N = ObjCClassesWithCategories.size(); I != N; ++I) {
4276 unsigned StartIndex = Categories.size();
4281 Categories.push_back(0);
4285 Cat =
Class->known_categories_begin(),
4286 CatEnd =
Class->known_categories_end();
4287 Cat != CatEnd; ++Cat, ++Size) {
4288 assert(
getDeclID(*Cat) != 0 &&
"Bogus category");
4293 Categories[StartIndex] =
Size;
4297 CategoriesMap.push_back(CatInfo);
4302 llvm::array_pod_sort(CategoriesMap.begin(), CategoriesMap.end());
4305 using namespace llvm;
4307 auto Abbrev = std::make_shared<BitCodeAbbrev>();
4309 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6));
4310 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob));
4311 unsigned AbbrevID = Stream.EmitAbbrev(std::move(Abbrev));
4314 Stream.EmitRecordWithBlob(AbbrevID, Record,
4315 reinterpret_cast<char *
>(CategoriesMap.data()),
4322void ASTWriter::WriteLateParsedTemplates(
Sema &SemaRef) {
4329 for (
auto &LPTMapEntry : LPTMap) {
4337 for (
const auto &Tok : LPT.
Toks) {
4345void ASTWriter::WriteOptimizePragmaOptions(
Sema &SemaRef) {
4353void ASTWriter::WriteMSStructPragmaOptions(
Sema &SemaRef) {
4361void ASTWriter::WriteMSPointersToMembersPragmaOptions(
Sema &SemaRef) {
4369void ASTWriter::WritePackPragmaOptions(
Sema &SemaRef) {
4383 AddString(StackEntry.StackSlotLabel, Record);
4389void ASTWriter::WriteFloatControlPragmaOptions(
Sema &SemaRef) {
4399 for (
const auto &StackEntry : SemaRef.
FpPragmaStack.Stack) {
4400 Record.push_back(StackEntry.Value.getAsOpaqueInt());
4403 AddString(StackEntry.StackSlotLabel, Record);
4408void ASTWriter::WriteModuleFileExtension(
Sema &SemaRef,
4414 auto Abv = std::make_shared<llvm::BitCodeAbbrev>();
4416 Abv->Add(llvm::BitCodeAbbrevOp(llvm::BitCodeAbbrevOp::VBR, 6));
4417 Abv->Add(llvm::BitCodeAbbrevOp(llvm::BitCodeAbbrevOp::VBR, 6));
4418 Abv->Add(llvm::BitCodeAbbrevOp(llvm::BitCodeAbbrevOp::VBR, 6));
4419 Abv->Add(llvm::BitCodeAbbrevOp(llvm::BitCodeAbbrevOp::VBR, 6));
4420 Abv->Add(llvm::BitCodeAbbrevOp(llvm::BitCodeAbbrevOp::Blob));
4421 unsigned Abbrev = Stream.EmitAbbrev(std::move(Abv));
4427 Record.push_back(Metadata.MajorVersion);
4428 Record.push_back(Metadata.MinorVersion);
4429 Record.push_back(Metadata.BlockName.size());
4430 Record.push_back(Metadata.UserInfo.size());
4432 Buffer += Metadata.BlockName;
4433 Buffer += Metadata.UserInfo;
4434 Stream.EmitRecordWithBlob(Abbrev, Record, Buffer);
4448 auto &Record = *
this;
4452 if (!A || (isa<PreferredNameAttr>(A) &&
4453 Writer->isWritingStdCXXNamedModules()))
4454 return Record.push_back(0);
4456 Record.push_back(A->
getKind() + 1);
4460 Record.AddSourceRange(A->
getRange());
4464 Record.push_back(A->getAttributeSpellingListIndexRaw());
4467#include "clang/Serialization/AttrPCHWrite.inc"
4473 for (
const auto *A : Attrs)
4480 Record.push_back(Tok.
getKind());
4487 case tok::annot_pragma_loop_hint: {
4489 AddToken(Info->PragmaName, Record);
4491 Record.push_back(Info->Toks.size());
4492 for (
const auto &T : Info->Toks)
4496 case tok::annot_pragma_pack: {
4499 Record.push_back(
static_cast<unsigned>(Info->Action));
4505 case tok::annot_pragma_openmp:
4506 case tok::annot_pragma_openmp_end:
4507 case tok::annot_pragma_unused:
4510 llvm_unreachable(
"missing serialization code for annotation token");
4521 Record.push_back(Str.size());
4522 Record.insert(Record.end(), Str.begin(), Str.end());
4526 assert(Context &&
"should have context when outputting path");
4529 StringRef PathStr(Path.data(), Path.size());
4530 if (PathStr ==
"<built-in>" || PathStr ==
"<command line>")
4537 const char *PathBegin = Path.data();
4538 const char *PathPtr =
4540 if (PathPtr != PathBegin) {
4541 Path.erase(Path.begin(), Path.begin() + (PathPtr - PathBegin));
4558 Stream.EmitRecordWithBlob(Abbrev, Record, FilePath);
4563 Record.push_back(Version.getMajor());
4564 if (std::optional<unsigned> Minor = Version.getMinor())
4565 Record.push_back(*Minor + 1);
4567 Record.push_back(0);
4568 if (std::optional<unsigned> Subminor = Version.getSubminor())
4569 Record.push_back(*Subminor + 1);
4571 Record.push_back(0);
4577 IdentID ID = IdentifierIDs[II];
4580 if (ID >= FirstIdentID)
4581 IdentifierOffsets[ID - FirstIdentID] = Offset;
4587 unsigned ID = SelectorIDs[Sel];
4588 assert(ID &&
"Unknown selector");
4591 if (ID < FirstSelectorID)
4593 SelectorOffsets[ID - FirstSelectorID] = Offset;
4599 ArrayRef<std::shared_ptr<ModuleFileExtension>> Extensions,
4600 bool IncludeTimestamps,
bool BuildingImplicitModule)
4601 : Stream(Stream), Buffer(Buffer), ModuleCache(ModuleCache),
4602 IncludeTimestamps(IncludeTimestamps),
4603 BuildingImplicitModule(BuildingImplicitModule) {
4604 for (
const auto &Ext : Extensions) {
4605 if (
auto Writer = Ext->createExtensionWriter(*
this))
4606 ModuleFileExtensionWriters.push_back(std::move(Writer));
4613 assert(WritingAST &&
"can't determine lang opts when not writing AST");
4622 Module *WritingModule, StringRef isysroot,
4624 bool ShouldCacheASTInMemory) {
4625 llvm::TimeTraceScope scope(
"WriteAST", OutputFile);
4628 ASTHasCompilerErrors = hasErrors;
4631 Stream.Emit((
unsigned)
'C', 8);
4632 Stream.Emit((
unsigned)
'P', 8);
4633 Stream.Emit((
unsigned)
'C', 8);
4634 Stream.Emit((
unsigned)
'H', 8);
4636 WriteBlockInfoBlock();
4640 this->WritingModule = WritingModule;
4641 ASTFileSignature Signature = WriteASTCore(SemaRef, isysroot, WritingModule);
4644 this->WritingModule =
nullptr;
4645 this->BaseDirectory.clear();
4648 if (ShouldCacheASTInMemory) {
4651 llvm::MemoryBuffer::getMemBufferCopy(
4652 StringRef(Buffer.begin(), Buffer.size())));
4657template<
typename Vector>
4660 for (
typename Vector::iterator I = Vec.begin(
nullptr,
true), E = Vec.end();
4666void ASTWriter::collectNonAffectingInputFiles() {
4670 IsSLocAffecting.resize(N,
true);
4675 auto AffectingModuleMaps = GetAffectingModuleMaps(*PP, WritingModule);
4677 unsigned FileIDAdjustment = 0;
4678 unsigned OffsetAdjustment = 0;
4680 NonAffectingFileIDAdjustments.reserve(N);
4681 NonAffectingOffsetAdjustments.reserve(N);
4683 NonAffectingFileIDAdjustments.push_back(FileIDAdjustment);
4684 NonAffectingOffsetAdjustments.push_back(OffsetAdjustment);
4686 for (
unsigned I = 1; I != N; ++I) {
4688 FileID FID = FileID::get(I);
4695 if (!
Cache->OrigEntry)
4699 AffectingModuleMaps.empty() ||
4700 AffectingModuleMaps.find(
Cache->OrigEntry) != AffectingModuleMaps.end())
4703 IsSLocAffecting[I] =
false;
4705 FileIDAdjustment += 1;
4711 if (!NonAffectingFileIDs.empty() &&
4712 NonAffectingFileIDs.back().ID == FID.ID - 1) {
4713 NonAffectingFileIDs.back() = FID;
4715 NonAffectingFileIDAdjustments.back() = FileIDAdjustment;
4716 NonAffectingOffsetAdjustments.back() = OffsetAdjustment;
4720 NonAffectingFileIDs.push_back(FID);
4723 NonAffectingFileIDAdjustments.push_back(FileIDAdjustment);
4724 NonAffectingOffsetAdjustments.push_back(OffsetAdjustment);
4730 using namespace llvm;
4732 bool isModule = WritingModule !=
nullptr;
4743 collectNonAffectingInputFiles();
4745 writeUnhashedControlBlock(PP, Context);
4759 RegisterPredefDecl(Context.ObjCProtocolClassDecl,
4763 RegisterPredefDecl(Context.ObjCInstanceTypeDecl,
4767 RegisterPredefDecl(Context.BuiltinMSVaListDecl,
4772 RegisterPredefDecl(Context.MakeIntegerSeqDecl,
4774 RegisterPredefDecl(Context.CFConstantStringTypeDecl,
4776 RegisterPredefDecl(Context.CFConstantStringTagDecl,
4778 RegisterPredefDecl(Context.TypePackElementDecl,
4791 UnusedFileScopedDecls);
4803 for (
const auto &WeakUndeclaredIdentifierList :
4805 const IdentifierInfo *
const II = WeakUndeclaredIdentifierList.first;
4806 for (
const auto &WI : WeakUndeclaredIdentifierList.second) {
4820 for (
unsigned I = 0, N = SemaRef.
VTableUses.size(); I != N; ++I) {
4830 AddDeclRef(TD, UnusedLocalTypedefNameCandidates);
4839 "There are local ones at end of translation unit!");
4856 for (
const auto &I : SemaRef.KnownNamespaces) {
4866 for (
const auto &I : Undefined) {
4876 for (
const auto &DeleteExprsInfo :
4878 AddDeclRef(DeleteExprsInfo.first, DeleteExprsToAnalyze);
4879 DeleteExprsToAnalyze.push_back(DeleteExprsInfo.second.size());
4880 for (
const auto &DeleteLoc : DeleteExprsInfo.second) {
4882 DeleteExprsToAnalyze.push_back(DeleteLoc.second);
4888 WriteControlBlock(PP, Context, isysroot);
4891 Stream.FlushToWord();
4892 ASTBlockRange.first = Stream.GetCurrentBitNo() >> 3;
4894 ASTBlockStartOffset = Stream.GetCurrentBitNo();
4909 NewGlobalKindDeclPairs.push_back(D->
getKind());
4910 NewGlobalKindDeclPairs.push_back(
GetDeclRef(D));
4914 auto Abv = std::make_shared<BitCodeAbbrev>();
4916 Abv->Add(llvm::BitCodeAbbrevOp(llvm::BitCodeAbbrevOp::Blob));
4917 unsigned TuUpdateLexicalAbbrev = Stream.EmitAbbrev(std::move(Abv));
4920 Stream.EmitRecordWithBlob(TuUpdateLexicalAbbrev, Record,
4921 bytes(NewGlobalKindDeclPairs));
4925 Abv = std::make_shared<BitCodeAbbrev>();
4927 Abv->Add(llvm::BitCodeAbbrevOp(llvm::BitCodeAbbrevOp::VBR, 6));
4928 Abv->Add(llvm::BitCodeAbbrevOp(llvm::BitCodeAbbrevOp::Blob));
4929 UpdateVisibleAbbrev = Stream.EmitAbbrev(std::move(Abv));
4930 WriteDeclContextVisibleUpdate(TU);
4933 if (Context.ExternCContext)
4934 WriteDeclContextVisibleUpdate(Context.ExternCContext);
4948 for (
const auto &Number : Context.MangleNumbers)
4949 if (!Number.first->isFromASTFile())
4952 for (
const auto &Number : Context.StaticLocalNumbers)
4953 if (!Number.first->isFromASTFile())
4960 for (
const auto *I : DeclsToEmitEvenIfUnreferenced) {
4974 llvm::sort(IIs, llvm::deref<std::less<>>());
4988 for (
auto &SelectorAndID : SelectorIDs)
4989 AllSelectors.push_back(SelectorAndID.first);
4990 for (
auto &
Selector : AllSelectors)
4999 AddTypeRef(Context.ObjCIdRedefinitionType, SpecialTypes);
5000 AddTypeRef(Context.ObjCClassRedefinitionType, SpecialTypes);
5001 AddTypeRef(Context.ObjCSelRedefinitionType, SpecialTypes);
5024 auto Abbrev = std::make_shared<BitCodeAbbrev>();
5026 Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob));
5027 unsigned ModuleOffsetMapAbbrev = Stream.EmitAbbrev(std::move(Abbrev));
5030 llvm::raw_svector_ostream Out(Buffer);
5032 using namespace llvm::support;
5034 endian::Writer
LE(Out, little);
5035 LE.write<uint8_t>(
static_cast<uint8_t
>(M.
Kind));
5037 LE.write<uint16_t>(Name.size());
5038 Out.write(Name.data(), Name.size());
5042 uint32_t
None = std::numeric_limits<uint32_t>::max();
5044 auto writeBaseIDOrNone = [&](
auto BaseID,
bool ShouldWrite) {
5045 assert(BaseID < std::numeric_limits<uint32_t>::max() &&
"base id too high");
5047 LE.write<uint32_t>(BaseID);
5049 LE.write<uint32_t>(
None);
5066 Stream.EmitRecordWithBlob(ModuleOffsetMapAbbrev, Record,
5067 Buffer.data(), Buffer.size());
5072 for (
auto *D : SemaRef.DeclsToCheckForDeferredDiags)
5073 DeclsToCheckForDeferredDiags.push_back(
GetDeclRef(D));
5080 DeclTypesBlockStartOffset = Stream.GetCurrentBitNo();
5084 WriteDeclUpdatesBlocks(DeclUpdatesOffsetsRecord);
5085 while (!DeclTypesToEmit.empty()) {
5086 DeclOrType DOT = DeclTypesToEmit.front();
5087 DeclTypesToEmit.pop();