summaryrefslogtreecommitdiff
path: root/lib/Serialization/ASTWriter.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Serialization/ASTWriter.cpp')
-rw-r--r--lib/Serialization/ASTWriter.cpp250
1 files changed, 183 insertions, 67 deletions
diff --git a/lib/Serialization/ASTWriter.cpp b/lib/Serialization/ASTWriter.cpp
index 128e53b91b1d1..1e72ced2ee364 100644
--- a/lib/Serialization/ASTWriter.cpp
+++ b/lib/Serialization/ASTWriter.cpp
@@ -1,4 +1,4 @@
-//===--- ASTWriter.cpp - AST File Writer ------------------------*- C++ -*-===//
+//===- ASTWriter.cpp - AST File Writer ------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
@@ -17,11 +17,15 @@
#include "MultiOnDiskHashTable.h"
#include "clang/AST/ASTContext.h"
#include "clang/AST/ASTUnresolvedSet.h"
+#include "clang/AST/Attr.h"
#include "clang/AST/Decl.h"
+#include "clang/AST/DeclBase.h"
#include "clang/AST/DeclCXX.h"
#include "clang/AST/DeclContextInternals.h"
#include "clang/AST/DeclFriend.h"
+#include "clang/AST/DeclObjC.h"
#include "clang/AST/DeclTemplate.h"
+#include "clang/AST/DeclarationName.h"
#include "clang/AST/Expr.h"
#include "clang/AST/ExprCXX.h"
#include "clang/AST/LambdaCapture.h"
@@ -30,16 +34,22 @@
#include "clang/AST/TemplateName.h"
#include "clang/AST/Type.h"
#include "clang/AST/TypeLocVisitor.h"
+#include "clang/Basic/Diagnostic.h"
#include "clang/Basic/DiagnosticOptions.h"
#include "clang/Basic/FileManager.h"
#include "clang/Basic/FileSystemOptions.h"
+#include "clang/Basic/IdentifierTable.h"
#include "clang/Basic/LLVM.h"
+#include "clang/Basic/Lambda.h"
#include "clang/Basic/LangOptions.h"
#include "clang/Basic/MemoryBufferCache.h"
#include "clang/Basic/Module.h"
#include "clang/Basic/ObjCRuntime.h"
+#include "clang/Basic/OpenCLOptions.h"
+#include "clang/Basic/SourceLocation.h"
#include "clang/Basic/SourceManager.h"
#include "clang/Basic/SourceManagerInternals.h"
+#include "clang/Basic/Specifiers.h"
#include "clang/Basic/TargetInfo.h"
#include "clang/Basic/TargetOptions.h"
#include "clang/Basic/Version.h"
@@ -62,24 +72,30 @@
#include "clang/Serialization/SerializationDiagnostic.h"
#include "llvm/ADT/APFloat.h"
#include "llvm/ADT/APInt.h"
+#include "llvm/ADT/APSInt.h"
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/Hashing.h"
-#include "llvm/ADT/IntrusiveRefCntPtr.h"
#include "llvm/ADT/Optional.h"
+#include "llvm/ADT/PointerIntPair.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallSet.h"
#include "llvm/ADT/SmallString.h"
+#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringExtras.h"
+#include "llvm/ADT/StringMap.h"
+#include "llvm/ADT/StringRef.h"
#include "llvm/Bitcode/BitCodes.h"
#include "llvm/Bitcode/BitstreamWriter.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/Compression.h"
+#include "llvm/Support/Endian.h"
#include "llvm/Support/EndianStream.h"
#include "llvm/Support/Error.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/OnDiskHashTable.h"
#include "llvm/Support/Path.h"
-#include "llvm/Support/Process.h"
#include "llvm/Support/SHA1.h"
#include "llvm/Support/raw_ostream.h"
#include <algorithm>
@@ -87,11 +103,14 @@
#include <cstdint>
#include <cstdlib>
#include <cstring>
+#include <ctime>
#include <deque>
#include <limits>
-#include <new>
+#include <memory>
+#include <queue>
#include <tuple>
#include <utility>
+#include <vector>
using namespace clang;
using namespace clang::serialization;
@@ -120,13 +139,14 @@ namespace clang {
ASTRecordWriter Record;
/// \brief Type code that corresponds to the record generated.
- TypeCode Code;
+ TypeCode Code = static_cast<TypeCode>(0);
+
/// \brief Abbreviation to use for the record, if any.
- unsigned AbbrevToUse;
+ unsigned AbbrevToUse = 0;
public:
ASTTypeWriter(ASTWriter &Writer, ASTWriter::RecordDataImpl &Record)
- : Writer(Writer), Record(Writer, Record), Code((TypeCode)0), AbbrevToUse(0) { }
+ : Writer(Writer), Record(Writer, Record) {}
uint64_t Emit() {
return Record.Emit(Code, AbbrevToUse);
@@ -160,7 +180,7 @@ namespace clang {
#include "clang/AST/TypeNodes.def"
};
-} // end namespace clang
+} // namespace clang
void ASTTypeWriter::VisitBuiltinType(const BuiltinType *T) {
llvm_unreachable("Built-in types are never serialized");
@@ -433,6 +453,15 @@ ASTTypeWriter::VisitDependentSizedExtVectorType(
Code = TYPE_DEPENDENT_SIZED_EXT_VECTOR;
}
+void
+ASTTypeWriter::VisitDependentAddressSpaceType(
+ const DependentAddressSpaceType *T) {
+ Record.AddTypeRef(T->getPointeeType());
+ Record.AddStmt(T->getAddrSpaceExpr());
+ Record.AddSourceLocation(T->getAttributeLoc());
+ Code = TYPE_DEPENDENT_ADDRESS_SPACE;
+}
+
void
ASTTypeWriter::VisitTemplateTypeParmType(const TemplateTypeParmType *T) {
Record.push_back(T->getDepth());
@@ -541,8 +570,7 @@ class TypeLocWriter : public TypeLocVisitor<TypeLocWriter> {
ASTRecordWriter &Record;
public:
- TypeLocWriter(ASTRecordWriter &Record)
- : Record(Record) { }
+ TypeLocWriter(ASTRecordWriter &Record) : Record(Record) {}
#define ABSTRACT_TYPELOC(CLASS, PARENT)
#define TYPELOC(CLASS, PARENT) \
@@ -553,7 +581,7 @@ public:
void VisitFunctionTypeLoc(FunctionTypeLoc TyLoc);
};
-} // end anonymous namespace
+} // namespace
void TypeLocWriter::VisitQualifiedTypeLoc(QualifiedTypeLoc TL) {
// nothing to do
@@ -627,6 +655,15 @@ void TypeLocWriter::VisitDependentSizedArrayTypeLoc(
VisitArrayTypeLoc(TL);
}
+void TypeLocWriter::VisitDependentAddressSpaceTypeLoc(
+ DependentAddressSpaceTypeLoc TL) {
+ Record.AddSourceLocation(TL.getAttrNameLoc());
+ SourceRange range = TL.getAttrOperandParensRange();
+ Record.AddSourceLocation(range.getBegin());
+ Record.AddSourceLocation(range.getEnd());
+ Record.AddStmt(TL.getAttrExprOperand());
+}
+
void TypeLocWriter::VisitDependentSizedExtVectorTypeLoc(
DependentSizedExtVectorTypeLoc TL) {
Record.AddSourceLocation(TL.getNameLoc());
@@ -649,18 +686,23 @@ void TypeLocWriter::VisitFunctionTypeLoc(FunctionTypeLoc TL) {
for (unsigned i = 0, e = TL.getNumParams(); i != e; ++i)
Record.AddDeclRef(TL.getParam(i));
}
+
void TypeLocWriter::VisitFunctionProtoTypeLoc(FunctionProtoTypeLoc TL) {
VisitFunctionTypeLoc(TL);
}
+
void TypeLocWriter::VisitFunctionNoProtoTypeLoc(FunctionNoProtoTypeLoc TL) {
VisitFunctionTypeLoc(TL);
}
+
void TypeLocWriter::VisitUnresolvedUsingTypeLoc(UnresolvedUsingTypeLoc TL) {
Record.AddSourceLocation(TL.getNameLoc());
}
+
void TypeLocWriter::VisitTypedefTypeLoc(TypedefTypeLoc TL) {
Record.AddSourceLocation(TL.getNameLoc());
}
+
void TypeLocWriter::VisitObjCTypeParamTypeLoc(ObjCTypeParamTypeLoc TL) {
if (TL.getNumProtocols()) {
Record.AddSourceLocation(TL.getProtocolLAngleLoc());
@@ -669,6 +711,7 @@ void TypeLocWriter::VisitObjCTypeParamTypeLoc(ObjCTypeParamTypeLoc TL) {
for (unsigned i = 0, e = TL.getNumProtocols(); i != e; ++i)
Record.AddSourceLocation(TL.getProtocolLoc(i));
}
+
void TypeLocWriter::VisitTypeOfExprTypeLoc(TypeOfExprTypeLoc TL) {
Record.AddSourceLocation(TL.getTypeofLoc());
Record.AddSourceLocation(TL.getLParenLoc());
@@ -1130,6 +1173,7 @@ void ASTWriter::WriteBlockInfoBlock() {
RECORD(SUBMODULE_TEXTUAL_HEADER);
RECORD(SUBMODULE_PRIVATE_TEXTUAL_HEADER);
RECORD(SUBMODULE_INITIALIZERS);
+ RECORD(SUBMODULE_EXPORT_AS);
// Comments Block.
BLOCK(COMMENTS_BLOCK);
@@ -1397,6 +1441,7 @@ void ASTWriter::WriteControlBlock(Preprocessor &PP, ASTContext &Context,
StringRef isysroot,
const std::string &OutputFile) {
using namespace llvm;
+
Stream.EnterSubblock(CONTROL_BLOCK_ID, 5);
RecordData Record;
@@ -1505,6 +1550,7 @@ void ASTWriter::WriteControlBlock(Preprocessor &PP, ASTContext &Context,
for (auto I : M.Signature)
Record.push_back(I);
+ AddString(M.ModuleName, Record);
AddPath(M.FileName, Record);
}
Stream.EmitRecord(IMPORTS, Record);
@@ -1686,21 +1732,22 @@ void ASTWriter::WriteControlBlock(Preprocessor &PP, ASTContext &Context,
namespace {
- /// \brief An input file.
- struct InputFileEntry {
- const FileEntry *File;
- bool IsSystemFile;
- bool IsTransient;
- bool BufferOverridden;
- bool IsTopLevelModuleMap;
- };
+/// \brief An input file.
+struct InputFileEntry {
+ const FileEntry *File;
+ bool IsSystemFile;
+ bool IsTransient;
+ bool BufferOverridden;
+ bool IsTopLevelModuleMap;
+};
-} // end anonymous namespace
+} // namespace
void ASTWriter::WriteInputFiles(SourceManager &SourceMgr,
HeaderSearchOptions &HSOpts,
bool Modules) {
using namespace llvm;
+
Stream.EnterSubblock(INPUT_FILES_BLOCK_ID, 4);
// Create input-file abbreviation.
@@ -1877,7 +1924,7 @@ namespace {
off_t Size;
time_t ModTime;
};
- typedef const key_type &key_type_ref;
+ using key_type_ref = const key_type &;
using UnresolvedModule =
llvm::PointerIntPair<Module *, 2, ModuleMap::ModuleHeaderRole>;
@@ -1887,10 +1934,10 @@ namespace {
ArrayRef<ModuleMap::KnownHeader> KnownHeaders;
UnresolvedModule Unresolved;
};
- typedef const data_type &data_type_ref;
+ using data_type_ref = const data_type &;
- typedef unsigned hash_value_type;
- typedef unsigned offset_type;
+ using hash_value_type = unsigned;
+ using offset_type = unsigned;
hash_value_type ComputeHash(key_type_ref key) {
// The hash is based only on size/time of the file, so that the reader can
@@ -1899,9 +1946,10 @@ namespace {
return llvm::hash_combine(key.Size, key.ModTime);
}
- std::pair<unsigned,unsigned>
+ std::pair<unsigned, unsigned>
EmitKeyDataLength(raw_ostream& Out, key_type_ref key, data_type_ref Data) {
using namespace llvm::support;
+
endian::Writer<little> LE(Out);
unsigned KeyLen = key.Filename.size() + 1 + 8 + 8;
LE.write<uint16_t>(KeyLen);
@@ -1917,6 +1965,7 @@ namespace {
void EmitKey(raw_ostream& Out, key_type_ref key, unsigned KeyLen) {
using namespace llvm::support;
+
endian::Writer<little> LE(Out);
LE.write<uint64_t>(key.Size);
KeyLen -= 8;
@@ -1928,6 +1977,7 @@ namespace {
void EmitData(raw_ostream &Out, key_type_ref key,
data_type_ref Data, unsigned DataLen) {
using namespace llvm::support;
+
endian::Writer<little> LE(Out);
uint64_t Start = Out.tell(); (void)Start;
@@ -1982,7 +2032,7 @@ namespace {
const char *strings_end() const { return FrameworkStringData.end(); }
};
-} // end anonymous namespace
+} // namespace
/// \brief Write the header search block for the list of files that
///
@@ -2095,6 +2145,7 @@ void ASTWriter::WriteHeaderSearch(const HeaderSearch &HS) {
uint32_t BucketOffset;
{
using namespace llvm::support;
+
llvm::raw_svector_ostream Out(TableData);
// Make sure that no bucket is at offset 0
endian::Writer<little>(Out).write<uint32_t>(0);
@@ -2126,7 +2177,7 @@ void ASTWriter::WriteHeaderSearch(const HeaderSearch &HS) {
static void emitBlob(llvm::BitstreamWriter &Stream, StringRef Blob,
unsigned SLocBufferBlobCompressedAbbrv,
unsigned SLocBufferBlobAbbrv) {
- typedef ASTWriter::RecordData::value_type RecordDataType;
+ using RecordDataType = ASTWriter::RecordData::value_type;
// Compress the buffer if possible. We expect that almost all PCM
// consumers will not want its contents.
@@ -2312,12 +2363,13 @@ void ASTWriter::WriteSourceManagerBlock(SourceManager &SourceMgr,
// Emit the needed file names.
llvm::DenseMap<int, int> FilenameMap;
+ FilenameMap[-1] = -1; // For unspecified filenames.
for (const auto &L : LineTable) {
if (L.first.ID < 0)
continue;
for (auto &LE : L.second) {
if (FilenameMap.insert(std::make_pair(LE.FilenameID,
- FilenameMap.size())).second)
+ FilenameMap.size() - 1)).second)
AddPath(LineTable.getFilename(LE.FilenameID), Record);
}
}
@@ -2370,7 +2422,6 @@ static bool shouldIgnoreMacro(MacroDirective *MD, bool IsModule,
/// \brief Writes the block containing the serialized form of the
/// preprocessor.
-///
void ASTWriter::WritePreprocessor(const Preprocessor &PP, bool IsModule) {
PreprocessingRecord *PPRec = PP.getPreprocessingRecord();
if (PPRec)
@@ -2387,6 +2438,17 @@ void ASTWriter::WritePreprocessor(const Preprocessor &PP, bool IsModule) {
if (PP.isRecordingPreamble() && PP.hasRecordedPreamble()) {
assert(!IsModule);
+ auto SkipInfo = PP.getPreambleSkipInfo();
+ if (SkipInfo.hasValue()) {
+ Record.push_back(true);
+ AddSourceLocation(SkipInfo->HashTokenLoc, Record);
+ AddSourceLocation(SkipInfo->IfTokenLoc, Record);
+ Record.push_back(SkipInfo->FoundNonSkipPortion);
+ Record.push_back(SkipInfo->FoundElse);
+ AddSourceLocation(SkipInfo->ElseLoc, Record);
+ } else {
+ Record.push_back(false);
+ }
for (const auto &Cond : PP.getPreambleConditionalStack()) {
AddSourceLocation(Cond.IfLoc, Record);
Record.push_back(Cond.WasSkipping);
@@ -2715,6 +2777,7 @@ void ASTWriter::WriteSubmodules(Module *WritingModule) {
Abbrev->Add(BitCodeAbbrevOp(SUBMODULE_DEFINITION));
Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // ID
Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Parent
+ Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 2)); // Kind
Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // IsFramework
Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // IsExplicit
Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // IsSystem
@@ -2789,11 +2852,15 @@ void ASTWriter::WriteSubmodules(Module *WritingModule) {
Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // Message
unsigned ConflictAbbrev = Stream.EmitAbbrev(std::move(Abbrev));
+ Abbrev = std::make_shared<BitCodeAbbrev>();
+ Abbrev->Add(BitCodeAbbrevOp(SUBMODULE_EXPORT_AS));
+ Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // Macro name
+ unsigned ExportAsAbbrev = Stream.EmitAbbrev(std::move(Abbrev));
+
// Write the submodule metadata block.
RecordData::value_type Record[] = {
getNumberOfModules(WritingModule),
- FirstSubmoduleID - NUM_PREDEF_SUBMODULE_IDS,
- (unsigned)WritingModule->Kind};
+ FirstSubmoduleID - NUM_PREDEF_SUBMODULE_IDS};
Stream.EmitRecord(SUBMODULE_METADATA, Record);
// Write all of the submodules.
@@ -2815,6 +2882,7 @@ void ASTWriter::WriteSubmodules(Module *WritingModule) {
RecordData::value_type Record[] = {SUBMODULE_DEFINITION,
ID,
ParentID,
+ (RecordData::value_type)Mod->Kind,
Mod->IsFramework,
Mod->IsExplicit,
Mod->IsSystem,
@@ -2923,6 +2991,12 @@ void ASTWriter::WriteSubmodules(Module *WritingModule) {
if (!Inits.empty())
Stream.EmitRecord(SUBMODULE_INITIALIZERS, Inits);
+ // Emit the name of the re-exported module, if any.
+ if (!Mod->ExportAsModule.empty()) {
+ RecordData::value_type Record[] = {SUBMODULE_EXPORT_AS};
+ Stream.EmitRecordWithBlob(ExportAsAbbrev, Record, Mod->ExportAsModule);
+ }
+
// Queue up the submodules of this module.
for (auto *M : Mod->submodules())
Q.push(M);
@@ -3164,28 +3238,29 @@ class ASTMethodPoolTrait {
ASTWriter &Writer;
public:
- typedef Selector key_type;
- typedef key_type key_type_ref;
+ using key_type = Selector;
+ using key_type_ref = key_type;
struct data_type {
SelectorID ID;
ObjCMethodList Instance, Factory;
};
- typedef const data_type& data_type_ref;
+ using data_type_ref = const data_type &;
- typedef unsigned hash_value_type;
- typedef unsigned offset_type;
+ using hash_value_type = unsigned;
+ using offset_type = unsigned;
- explicit ASTMethodPoolTrait(ASTWriter &Writer) : Writer(Writer) { }
+ explicit ASTMethodPoolTrait(ASTWriter &Writer) : Writer(Writer) {}
static hash_value_type ComputeHash(Selector Sel) {
return serialization::ComputeHash(Sel);
}
- std::pair<unsigned,unsigned>
+ std::pair<unsigned, unsigned>
EmitKeyDataLength(raw_ostream& Out, Selector Sel,
data_type_ref Methods) {
using namespace llvm::support;
+
endian::Writer<little> LE(Out);
unsigned KeyLen = 2 + (Sel.getNumArgs()? Sel.getNumArgs() * 4 : 4);
LE.write<uint16_t>(KeyLen);
@@ -3204,6 +3279,7 @@ public:
void EmitKey(raw_ostream& Out, Selector Sel, unsigned) {
using namespace llvm::support;
+
endian::Writer<little> LE(Out);
uint64_t Start = Out.tell();
assert((Start >> 32) == 0 && "Selector key offset too large");
@@ -3220,6 +3296,7 @@ public:
void EmitData(raw_ostream& Out, key_type_ref,
data_type_ref Methods, unsigned DataLen) {
using namespace llvm::support;
+
endian::Writer<little> LE(Out);
uint64_t Start = Out.tell(); (void)Start;
LE.write<uint32_t>(Methods.ID);
@@ -3264,7 +3341,7 @@ public:
}
};
-} // end anonymous namespace
+} // namespace
/// \brief Write ObjC data: selectors and the method pool.
///
@@ -3328,6 +3405,7 @@ void ASTWriter::WriteSelectors(Sema &SemaRef) {
uint32_t BucketOffset;
{
using namespace llvm::support;
+
ASTMethodPoolTrait Trait(*this);
llvm::raw_svector_ostream Out(MethodPool);
// Make sure that no bucket is at offset 0
@@ -3372,6 +3450,7 @@ void ASTWriter::WriteSelectors(Sema &SemaRef) {
/// \brief Write the selectors referenced in @selector expression into AST file.
void ASTWriter::WriteReferencedSelectorsPool(Sema &SemaRef) {
using namespace llvm;
+
if (SemaRef.ReferencedSelectors.empty())
return;
@@ -3460,14 +3539,14 @@ class ASTIdentifierTableTrait {
}
public:
- typedef IdentifierInfo* key_type;
- typedef key_type key_type_ref;
+ using key_type = IdentifierInfo *;
+ using key_type_ref = key_type;
- typedef IdentID data_type;
- typedef data_type data_type_ref;
+ using data_type = IdentID;
+ using data_type_ref = data_type;
- typedef unsigned hash_value_type;
- typedef unsigned offset_type;
+ using hash_value_type = unsigned;
+ using offset_type = unsigned;
ASTIdentifierTableTrait(ASTWriter &Writer, Preprocessor &PP,
IdentifierResolver &IdResolver, bool IsModule,
@@ -3491,7 +3570,7 @@ public:
return isInterestingIdentifier(II, 0);
}
- std::pair<unsigned,unsigned>
+ std::pair<unsigned, unsigned>
EmitKeyDataLength(raw_ostream& Out, IdentifierInfo* II, IdentID ID) {
unsigned KeyLen = II->getLength() + 1;
unsigned DataLen = 4; // 4 bytes for the persistent ID << 1
@@ -3509,7 +3588,9 @@ public:
DataLen += 4;
}
}
+
using namespace llvm::support;
+
endian::Writer<little> LE(Out);
assert((uint16_t)DataLen == DataLen && (uint16_t)KeyLen == KeyLen);
@@ -3538,6 +3619,7 @@ public:
void EmitData(raw_ostream& Out, IdentifierInfo* II,
IdentID ID, unsigned) {
using namespace llvm::support;
+
endian::Writer<little> LE(Out);
auto MacroOffset = Writer.getMacroDirectivesOffset(II);
@@ -3581,7 +3663,7 @@ public:
}
};
-} // end anonymous namespace
+} // namespace
/// \brief Write the identifier table into the AST file.
///
@@ -3639,6 +3721,7 @@ void ASTWriter::WriteIdentifierTable(Preprocessor &PP,
uint32_t BucketOffset;
{
using namespace llvm::support;
+
llvm::raw_svector_ostream Out(IdentifierTable);
// Make sure that no bucket is at offset 0
endian::Writer<little>(Out).write<uint32_t>(0);
@@ -3694,17 +3777,17 @@ class ASTDeclContextNameLookupTrait {
llvm::SmallVector<DeclID, 64> DeclIDs;
public:
- typedef DeclarationNameKey key_type;
- typedef key_type key_type_ref;
+ using key_type = DeclarationNameKey;
+ using key_type_ref = key_type;
/// A start and end index into DeclIDs, representing a sequence of decls.
- typedef std::pair<unsigned, unsigned> data_type;
- typedef const data_type& data_type_ref;
+ using data_type = std::pair<unsigned, unsigned>;
+ using data_type_ref = const data_type &;
- typedef unsigned hash_value_type;
- typedef unsigned offset_type;
+ using hash_value_type = unsigned;
+ using offset_type = unsigned;
- explicit ASTDeclContextNameLookupTrait(ASTWriter &Writer) : Writer(Writer) { }
+ explicit ASTDeclContextNameLookupTrait(ASTWriter &Writer) : Writer(Writer) {}
template<typename Coll>
data_type getData(const Coll &Decls) {
@@ -3736,6 +3819,7 @@ public:
"have reference to loaded module file but no chain?");
using namespace llvm::support;
+
endian::Writer<little>(Out)
.write<uint32_t>(Writer.getChain()->getModuleFileID(F));
}
@@ -3744,6 +3828,7 @@ public:
DeclarationNameKey Name,
data_type_ref Lookup) {
using namespace llvm::support;
+
endian::Writer<little> LE(Out);
unsigned KeyLen = 1;
switch (Name.getKind()) {
@@ -3777,6 +3862,7 @@ public:
void EmitKey(raw_ostream &Out, DeclarationNameKey Name, unsigned) {
using namespace llvm::support;
+
endian::Writer<little> LE(Out);
LE.write<uint8_t>(Name.getKind());
switch (Name.getKind()) {
@@ -3808,6 +3894,7 @@ public:
void EmitData(raw_ostream &Out, key_type_ref, data_type Lookup,
unsigned DataLen) {
using namespace llvm::support;
+
endian::Writer<little> LE(Out);
uint64_t Start = Out.tell(); (void)Start;
for (unsigned I = Lookup.first, N = Lookup.second; I != N; ++I)
@@ -3816,7 +3903,7 @@ public:
}
};
-} // end anonymous namespace
+} // namespace
bool ASTWriter::isLookupResultExternal(StoredDeclsList &Result,
DeclContext *DC) {
@@ -4295,6 +4382,7 @@ void ASTWriter::WritePackPragmaOptions(Sema &SemaRef) {
for (const auto &StackEntry : SemaRef.PackStack.Stack) {
Record.push_back(StackEntry.Value);
AddSourceLocation(StackEntry.PragmaLocation, Record);
+ AddSourceLocation(StackEntry.PragmaPushLocation, Record);
AddString(StackEntry.StackSlotLabel, Record);
}
Stream.EmitRecord(PACK_PRAGMA_OPTIONS, Record);
@@ -4348,7 +4436,6 @@ void ASTRecordWriter::AddAttributes(ArrayRef<const Attr *> Attrs) {
Record.AddSourceRange(A->getRange());
#include "clang/Serialization/AttrPCHWrite.inc"
-
}
}
@@ -4778,7 +4865,8 @@ ASTFileSignature ASTWriter::WriteASTCore(Sema &SemaRef, StringRef isysroot,
// each of those modules were mapped into our own offset/ID space, so that
// the reader can build the appropriate mapping to its own offset/ID space.
// The map consists solely of a blob with the following format:
- // *(module-name-len:i16 module-name:len*i8
+ // *(module-kind:i8
+ // module-name-len:i16 module-name:len*i8
// source-location-offset:i32
// identifier-id:i32
// preprocessed-entity-id:i32
@@ -4789,6 +4877,9 @@ ASTFileSignature ASTWriter::WriteASTCore(Sema &SemaRef, StringRef isysroot,
// c++-base-specifiers-id:i32
// type-id:i32)
//
+ // module-kind is the ModuleKind enum value. If it is MK_PrebuiltModule or
+ // MK_ExplicitModule, then the module-name is the module name. Otherwise,
+ // it is the module file name.
auto Abbrev = std::make_shared<BitCodeAbbrev>();
Abbrev->Add(BitCodeAbbrevOp(MODULE_OFFSET_MAP));
Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob));
@@ -4798,10 +4889,15 @@ ASTFileSignature ASTWriter::WriteASTCore(Sema &SemaRef, StringRef isysroot,
llvm::raw_svector_ostream Out(Buffer);
for (ModuleFile &M : Chain->ModuleMgr) {
using namespace llvm::support;
+
endian::Writer<little> LE(Out);
- StringRef FileName = M.FileName;
- LE.write<uint16_t>(FileName.size());
- Out.write(FileName.data(), FileName.size());
+ LE.write<uint8_t>(static_cast<uint8_t>(M.Kind));
+ StringRef Name =
+ M.Kind == MK_PrebuiltModule || M.Kind == MK_ExplicitModule
+ ? M.ModuleName
+ : M.FileName;
+ LE.write<uint16_t>(Name.size());
+ Out.write(Name.data(), Name.size());
// Note: if a base ID was uint max, it would not be possible to load
// another module after it or have more than one entity inside it.
@@ -5039,9 +5135,15 @@ void ASTWriter::WriteDeclUpdatesBlocks(RecordDataImpl &OffsetsRecord) {
case UPD_CXX_ADDED_FUNCTION_DEFINITION:
break;
- case UPD_CXX_INSTANTIATED_STATIC_DATA_MEMBER: {
- const VarDecl *VD = cast<VarDecl>(D);
+ case UPD_CXX_POINT_OF_INSTANTIATION:
+ // FIXME: Do we need to also save the template specialization kind here?
Record.AddSourceLocation(Update.getLoc());
+ break;
+
+ case UPD_CXX_ADDED_VAR_DEFINITION: {
+ const VarDecl *VD = cast<VarDecl>(D);
+ Record.push_back(VD->isInline());
+ Record.push_back(VD->isInlineSpecified());
if (VD->getInit()) {
Record.push_back(!VD->isInitKnownICE() ? 1
: (VD->isInitICE() ? 3 : 2));
@@ -5109,6 +5211,7 @@ void ASTWriter::WriteDeclUpdatesBlocks(RecordDataImpl &OffsetsRecord) {
case UPD_CXX_RESOLVED_DTOR_DELETE:
Record.AddDeclRef(Update.getDecl());
+ Record.AddStmt(cast<CXXDestructorDecl>(D)->getOperatorDeleteThisArg());
break;
case UPD_CXX_RESOLVED_EXCEPTION_SPEC:
@@ -6136,7 +6239,8 @@ void ASTWriter::DeducedReturnType(const FunctionDecl *FD, QualType ReturnType) {
}
void ASTWriter::ResolvedOperatorDelete(const CXXDestructorDecl *DD,
- const FunctionDecl *Delete) {
+ const FunctionDecl *Delete,
+ Expr *ThisArg) {
if (Chain && Chain->isProcessingUpdateRecords()) return;
assert(!WritingAST && "Already writing the AST!");
assert(Delete && "Not given an operator delete");
@@ -6156,6 +6260,15 @@ void ASTWriter::CompletedImplicitDefinition(const FunctionDecl *D) {
DeclUpdates[D].push_back(DeclUpdate(UPD_CXX_ADDED_FUNCTION_DEFINITION));
}
+void ASTWriter::VariableDefinitionInstantiated(const VarDecl *D) {
+ if (Chain && Chain->isProcessingUpdateRecords()) return;
+ assert(!WritingAST && "Already writing the AST!");
+ if (!D->isFromASTFile())
+ return;
+
+ DeclUpdates[D].push_back(DeclUpdate(UPD_CXX_ADDED_VAR_DEFINITION));
+}
+
void ASTWriter::FunctionDefinitionInstantiated(const FunctionDecl *D) {
if (Chain && Chain->isProcessingUpdateRecords()) return;
assert(!WritingAST && "Already writing the AST!");
@@ -6165,7 +6278,7 @@ void ASTWriter::FunctionDefinitionInstantiated(const FunctionDecl *D) {
DeclUpdates[D].push_back(DeclUpdate(UPD_CXX_ADDED_FUNCTION_DEFINITION));
}
-void ASTWriter::StaticDataMemberInstantiated(const VarDecl *D) {
+void ASTWriter::InstantiationRequested(const ValueDecl *D) {
if (Chain && Chain->isProcessingUpdateRecords()) return;
assert(!WritingAST && "Already writing the AST!");
if (!D->isFromASTFile())
@@ -6173,9 +6286,12 @@ void ASTWriter::StaticDataMemberInstantiated(const VarDecl *D) {
// Since the actual instantiation is delayed, this really means that we need
// to update the instantiation location.
- DeclUpdates[D].push_back(
- DeclUpdate(UPD_CXX_INSTANTIATED_STATIC_DATA_MEMBER,
- D->getMemberSpecializationInfo()->getPointOfInstantiation()));
+ SourceLocation POI;
+ if (auto *VD = dyn_cast<VarDecl>(D))
+ POI = VD->getPointOfInstantiation();
+ else
+ POI = cast<FunctionDecl>(D)->getPointOfInstantiation();
+ DeclUpdates[D].push_back(DeclUpdate(UPD_CXX_POINT_OF_INSTANTIATION, POI));
}
void ASTWriter::DefaultArgumentInstantiated(const ParmVarDecl *D) {