diff options
Diffstat (limited to 'lib/Serialization/ASTWriter.cpp')
-rw-r--r-- | lib/Serialization/ASTWriter.cpp | 250 |
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) { |