diff options
Diffstat (limited to 'lib/Serialization/ASTWriter.cpp')
-rw-r--r-- | lib/Serialization/ASTWriter.cpp | 348 |
1 files changed, 205 insertions, 143 deletions
diff --git a/lib/Serialization/ASTWriter.cpp b/lib/Serialization/ASTWriter.cpp index 1e72ced2ee36..1a8d806e9d24 100644 --- a/lib/Serialization/ASTWriter.cpp +++ b/lib/Serialization/ASTWriter.cpp @@ -53,7 +53,6 @@ #include "clang/Basic/TargetInfo.h" #include "clang/Basic/TargetOptions.h" #include "clang/Basic/Version.h" -#include "clang/Basic/VersionTuple.h" #include "clang/Lex/HeaderSearch.h" #include "clang/Lex/HeaderSearchOptions.h" #include "clang/Lex/MacroInfo.h" @@ -79,16 +78,17 @@ #include "llvm/ADT/Optional.h" #include "llvm/ADT/PointerIntPair.h" #include "llvm/ADT/STLExtras.h" +#include "llvm/ADT/ScopeExit.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/DJB.h" #include "llvm/Support/Endian.h" #include "llvm/Support/EndianStream.h" #include "llvm/Support/Error.h" @@ -97,6 +97,7 @@ #include "llvm/Support/OnDiskHashTable.h" #include "llvm/Support/Path.h" #include "llvm/Support/SHA1.h" +#include "llvm/Support/VersionTuple.h" #include "llvm/Support/raw_ostream.h" #include <algorithm> #include <cassert> @@ -138,10 +139,10 @@ namespace clang { ASTWriter &Writer; ASTRecordWriter Record; - /// \brief Type code that corresponds to the record generated. + /// Type code that corresponds to the record generated. TypeCode Code = static_cast<TypeCode>(0); - /// \brief Abbreviation to use for the record, if any. + /// Abbreviation to use for the record, if any. unsigned AbbrevToUse = 0; public: @@ -276,6 +277,7 @@ void ASTTypeWriter::VisitFunctionType(const FunctionType *T) { Record.push_back(C.getCC()); Record.push_back(C.getProducesResult()); Record.push_back(C.getNoCallerSavedRegs()); + Record.push_back(C.getNoCfCheck()); if (C.getHasRegParm() || C.getRegParm() || C.getProducesResult()) AbbrevToUse = 0; @@ -293,7 +295,7 @@ static void addExceptionSpec(const FunctionProtoType *T, Record.push_back(T->getNumExceptions()); for (unsigned I = 0, N = T->getNumExceptions(); I != N; ++I) Record.AddTypeRef(T->getExceptionType(I)); - } else if (T->getExceptionSpecType() == EST_ComputedNoexcept) { + } else if (isComputedNoexcept(T->getExceptionSpecType())) { Record.AddStmt(T->getNoexceptExpr()); } else if (T->getExceptionSpecType() == EST_Uninstantiated) { Record.AddDeclRef(T->getExceptionSpecDecl()); @@ -453,7 +455,15 @@ ASTTypeWriter::VisitDependentSizedExtVectorType( Code = TYPE_DEPENDENT_SIZED_EXT_VECTOR; } -void +void ASTTypeWriter::VisitDependentVectorType(const DependentVectorType *T) { + Record.AddTypeRef(T->getElementType()); + Record.AddStmt(const_cast<Expr*>(T->getSizeExpr())); + Record.AddSourceLocation(T->getAttributeLoc()); + Record.push_back(T->getVectorKind()); + Code = TYPE_DEPENDENT_SIZED_VECTOR; +} + +void ASTTypeWriter::VisitDependentAddressSpaceType( const DependentAddressSpaceType *T) { Record.AddTypeRef(T->getPointeeType()); @@ -511,6 +521,7 @@ void ASTTypeWriter::VisitElaboratedType(const ElaboratedType *T) { Record.push_back(T->getKeyword()); Record.AddNestedNameSpecifier(T->getQualifier()); Record.AddTypeRef(T->getNamedType()); + Record.AddDeclRef(T->getOwnedTagDecl()); Code = TYPE_ELABORATED; } @@ -661,7 +672,7 @@ void TypeLocWriter::VisitDependentAddressSpaceTypeLoc( SourceRange range = TL.getAttrOperandParensRange(); Record.AddSourceLocation(range.getBegin()); Record.AddSourceLocation(range.getEnd()); - Record.AddStmt(TL.getAttrExprOperand()); + Record.AddStmt(TL.getAttrExprOperand()); } void TypeLocWriter::VisitDependentSizedExtVectorTypeLoc( @@ -673,6 +684,11 @@ void TypeLocWriter::VisitVectorTypeLoc(VectorTypeLoc TL) { Record.AddSourceLocation(TL.getNameLoc()); } +void TypeLocWriter::VisitDependentVectorTypeLoc( + DependentVectorTypeLoc TL) { + Record.AddSourceLocation(TL.getNameLoc()); +} + void TypeLocWriter::VisitExtVectorTypeLoc(ExtVectorTypeLoc TL) { Record.AddSourceLocation(TL.getNameLoc()); } @@ -884,6 +900,7 @@ void ASTWriter::WriteTypeAbbrevs() { Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 4)); // CC Abv->Add(BitCodeAbbrevOp(0)); // ProducesResult Abv->Add(BitCodeAbbrevOp(0)); // NoCallerSavedRegs + Abv->Add(BitCodeAbbrevOp(0)); // NoCfCheck // FunctionProtoType Abv->Add(BitCodeAbbrevOp(0)); // IsVariadic Abv->Add(BitCodeAbbrevOp(0)); // HasTrailingReturn @@ -1104,6 +1121,7 @@ void ASTWriter::WriteBlockInfoBlock() { RECORD(UNUSED_FILESCOPED_DECLS); RECORD(PPD_ENTITIES_OFFSETS); RECORD(VTABLE_USES); + RECORD(PPD_SKIPPED_RANGES); RECORD(REFERENCED_SELECTOR_POOL); RECORD(TU_UPDATE_LEXICAL); RECORD(SEMA_DECL_REFS); @@ -1293,7 +1311,7 @@ void ASTWriter::WriteBlockInfoBlock() { RECORD(DECL_PRAGMA_COMMENT); RECORD(DECL_PRAGMA_DETECT_MISMATCH); RECORD(DECL_OMP_DECLARE_REDUCTION); - + // Statements and Exprs can occur in the Decls and Types block. AddStmtsExprs(Stream, Record); @@ -1316,7 +1334,7 @@ void ASTWriter::WriteBlockInfoBlock() { Stream.ExitBlock(); } -/// \brief Prepares a path for being written to an AST file by converting it +/// Prepares a path for being written to an AST file by converting it /// to an absolute path and removing nested './'s. /// /// \return \c true if the path was changed. @@ -1326,7 +1344,7 @@ static bool cleanPathForOutput(FileManager &FileMgr, return Changed | llvm::sys::path::remove_dots(Path); } -/// \brief Adjusts the given filename to only write out the portion of the +/// Adjusts the given filename to only write out the portion of the /// filename that is not part of the system root directory. /// /// \param Filename the file name to adjust. @@ -1436,7 +1454,7 @@ ASTFileSignature ASTWriter::writeUnhashedControlBlock(Preprocessor &PP, return Signature; } -/// \brief Write the control block. +/// Write the control block. void ASTWriter::WriteControlBlock(Preprocessor &PP, ASTContext &Context, StringRef isysroot, const std::string &OutputFile) { @@ -1444,7 +1462,7 @@ void ASTWriter::WriteControlBlock(Preprocessor &PP, ASTContext &Context, Stream.EnterSubblock(CONTROL_BLOCK_ID, 5); RecordData Record; - + // Metadata auto MetadataAbbrev = std::make_shared<BitCodeAbbrev>(); MetadataAbbrev->Add(BitCodeAbbrevOp(METADATA)); @@ -1454,16 +1472,23 @@ void ASTWriter::WriteControlBlock(Preprocessor &PP, ASTContext &Context, MetadataAbbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 16)); // Clang min. MetadataAbbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // Relocatable MetadataAbbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // Timestamps + MetadataAbbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // PCHHasObjectFile MetadataAbbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // Errors MetadataAbbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // SVN branch/tag unsigned MetadataAbbrevCode = Stream.EmitAbbrev(std::move(MetadataAbbrev)); assert((!WritingModule || isysroot.empty()) && "writing module as a relocatable PCH?"); { - RecordData::value_type Record[] = {METADATA, VERSION_MAJOR, VERSION_MINOR, - CLANG_VERSION_MAJOR, CLANG_VERSION_MINOR, - !isysroot.empty(), IncludeTimestamps, - ASTHasCompilerErrors}; + RecordData::value_type Record[] = { + METADATA, + VERSION_MAJOR, + VERSION_MINOR, + CLANG_VERSION_MAJOR, + CLANG_VERSION_MINOR, + !isysroot.empty(), + IncludeTimestamps, + Context.getLangOpts().BuildingPCHWithObjectFile, + ASTHasCompilerErrors}; Stream.EmitRecordWithBlob(MetadataAbbrevCode, Record, getClangFullRepositoryVersion()); } @@ -1732,7 +1757,7 @@ void ASTWriter::WriteControlBlock(Preprocessor &PP, ASTContext &Context, namespace { -/// \brief An input file. +/// An input file. struct InputFileEntry { const FileEntry *File; bool IsSystemFile; @@ -1842,7 +1867,7 @@ void ASTWriter::WriteInputFiles(SourceManager &SourceMgr, // Source Manager Serialization //===----------------------------------------------------------------------===// -/// \brief Create an abbreviation for the SLocEntry that refers to a +/// Create an abbreviation for the SLocEntry that refers to a /// file. static unsigned CreateSLocFileAbbrev(llvm::BitstreamWriter &Stream) { using namespace llvm; @@ -1861,7 +1886,7 @@ static unsigned CreateSLocFileAbbrev(llvm::BitstreamWriter &Stream) { return Stream.EmitAbbrev(std::move(Abbrev)); } -/// \brief Create an abbreviation for the SLocEntry that refers to a +/// Create an abbreviation for the SLocEntry that refers to a /// buffer. static unsigned CreateSLocBufferAbbrev(llvm::BitstreamWriter &Stream) { using namespace llvm; @@ -1876,7 +1901,7 @@ static unsigned CreateSLocBufferAbbrev(llvm::BitstreamWriter &Stream) { return Stream.EmitAbbrev(std::move(Abbrev)); } -/// \brief Create an abbreviation for the SLocEntry that refers to a +/// Create an abbreviation for the SLocEntry that refers to a /// buffer's blob. static unsigned CreateSLocBufferBlobAbbrev(llvm::BitstreamWriter &Stream, bool Compressed) { @@ -1891,7 +1916,7 @@ static unsigned CreateSLocBufferBlobAbbrev(llvm::BitstreamWriter &Stream, return Stream.EmitAbbrev(std::move(Abbrev)); } -/// \brief Create an abbreviation for the SLocEntry that refers to a macro +/// Create an abbreviation for the SLocEntry that refers to a macro /// expansion. static unsigned CreateSLocExpansionAbbrev(llvm::BitstreamWriter &Stream) { using namespace llvm; @@ -1902,6 +1927,7 @@ static unsigned CreateSLocExpansionAbbrev(llvm::BitstreamWriter &Stream) { Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); // Spelling location Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); // Start location Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); // End location + Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // Is token range Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Token length return Stream.EmitAbbrev(std::move(Abbrev)); } @@ -1911,11 +1937,11 @@ namespace { // Trait used for the on-disk hash table of header search information. class HeaderFileInfoTrait { ASTWriter &Writer; - + // Keep track of the framework names we've used during serialization. SmallVector<char, 128> FrameworkStringData; llvm::StringMap<unsigned> FrameworkNameOffset; - + public: HeaderFileInfoTrait(ASTWriter &Writer) : Writer(Writer) {} @@ -1928,7 +1954,7 @@ namespace { using UnresolvedModule = llvm::PointerIntPair<Module *, 2, ModuleMap::ModuleHeaderRole>; - + struct data_type { const HeaderFileInfo &HFI; ArrayRef<ModuleMap::KnownHeader> KnownHeaders; @@ -1938,19 +1964,19 @@ namespace { 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 // match even when symlinking or excess path elements ("foo/../", "../") // change the form of the name. However, complete path is still the key. return llvm::hash_combine(key.Size, key.ModTime); } - + 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); + endian::Writer LE(Out, little); unsigned KeyLen = key.Filename.size() + 1 + 8 + 8; LE.write<uint16_t>(KeyLen); unsigned DataLen = 1 + 2 + 4 + 4; @@ -1966,7 +1992,7 @@ namespace { void EmitKey(raw_ostream& Out, key_type_ref key, unsigned KeyLen) { using namespace llvm::support; - endian::Writer<little> LE(Out); + endian::Writer LE(Out, little); LE.write<uint64_t>(key.Size); KeyLen -= 8; LE.write<uint64_t>(key.ModTime); @@ -1978,16 +2004,16 @@ namespace { data_type_ref Data, unsigned DataLen) { using namespace llvm::support; - endian::Writer<little> LE(Out); + endian::Writer LE(Out, little); uint64_t Start = Out.tell(); (void)Start; - + unsigned char Flags = (Data.HFI.isImport << 5) | (Data.HFI.isPragmaOnce << 4) | (Data.HFI.DirInfo << 1) | Data.HFI.IndexHeaderMapHeader; LE.write<uint8_t>(Flags); LE.write<uint16_t>(Data.HFI.NumIncludes); - + if (!Data.HFI.ControllingMacro) LE.write<uint32_t>(Data.HFI.ControllingMacroID); else @@ -2000,10 +2026,10 @@ namespace { = FrameworkNameOffset.find(Data.HFI.Framework); if (Pos == FrameworkNameOffset.end()) { Offset = FrameworkStringData.size() + 1; - FrameworkStringData.append(Data.HFI.Framework.begin(), + FrameworkStringData.append(Data.HFI.Framework.begin(), Data.HFI.Framework.end()); FrameworkStringData.push_back(0); - + FrameworkNameOffset[Data.HFI.Framework] = Offset; } else Offset = Pos->second; @@ -2027,14 +2053,14 @@ namespace { assert(Out.tell() - Start == DataLen && "Wrong data length"); } - + const char *strings_begin() const { return FrameworkStringData.begin(); } const char *strings_end() const { return FrameworkStringData.end(); } }; } // namespace -/// \brief Write the header search block for the list of files that +/// Write the header search block for the list of files that /// /// \param HS The header search structure to save. void ASTWriter::WriteHeaderSearch(const HeaderSearch &HS) { @@ -2100,7 +2126,7 @@ void ASTWriter::WriteHeaderSearch(const HeaderSearch &HS) { SmallVector<const FileEntry *, 16> FilesByUID; HS.getFileMgr().GetUniqueIDMapping(FilesByUID); - + if (FilesByUID.size() > HS.header_file_size()) FilesByUID.resize(HS.header_file_size()); @@ -2148,7 +2174,7 @@ void ASTWriter::WriteHeaderSearch(const HeaderSearch &HS) { llvm::raw_svector_ostream Out(TableData); // Make sure that no bucket is at offset 0 - endian::Writer<little>(Out).write<uint32_t>(0); + endian::write<uint32_t>(Out, 0, little); BucketOffset = Generator.Emit(Out, GeneratorTrait); } @@ -2162,13 +2188,13 @@ void ASTWriter::WriteHeaderSearch(const HeaderSearch &HS) { Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32)); Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); unsigned TableAbbrev = Stream.EmitAbbrev(std::move(Abbrev)); - + // Write the header search table RecordData::value_type Record[] = {HEADER_SEARCH_TABLE, BucketOffset, NumHeaderSearchEntries, TableData.size()}; TableData.append(GeneratorTrait.strings_begin(),GeneratorTrait.strings_end()); Stream.EmitRecordWithBlob(TableAbbrev, Record, TableData); - + // Free all of the strings we had to duplicate. for (unsigned I = 0, N = SavedStrings.size(); I != N; ++I) free(const_cast<char *>(SavedStrings[I])); @@ -2198,7 +2224,7 @@ static void emitBlob(llvm::BitstreamWriter &Stream, StringRef Blob, Stream.EmitRecordWithBlob(SLocBufferBlobAbbrv, Record, Blob); } -/// \brief Writes the block containing the serialized form of the +/// Writes the block containing the serialized form of the /// source manager. /// /// TODO: We should probably use an on-disk hash table (stored in a @@ -2268,7 +2294,7 @@ void ASTWriter::WriteSourceManagerBlock(SourceManager &SourceMgr, Record.push_back(InputFileIDs[Content->OrigEntry]); Record.push_back(File.NumCreatedFIDs); - + FileDeclIDsTy::iterator FDI = FileDeclIDs.find(FID); if (FDI != FileDeclIDs.end()) { Record.push_back(FDI->second->FirstDeclIndex); @@ -2277,9 +2303,9 @@ void ASTWriter::WriteSourceManagerBlock(SourceManager &SourceMgr, Record.push_back(0); Record.push_back(0); } - + Stream.EmitRecordWithAbbrev(SLocFileAbbrv, Record); - + if (Content->BufferOverridden || Content->IsTransient) EmitBlob = true; } else { @@ -2318,6 +2344,7 @@ void ASTWriter::WriteSourceManagerBlock(SourceManager &SourceMgr, ? SourceLocation() : Expansion.getExpansionLocEnd(), Record); + Record.push_back(Expansion.isExpansionTokenRange()); // Compute the token length for this macro expansion. unsigned NextOffset = SourceMgr.getNextLocalOffset(); @@ -2420,7 +2447,7 @@ static bool shouldIgnoreMacro(MacroDirective *MD, bool IsModule, return false; } -/// \brief Writes the block containing the serialized form of the +/// Writes the block containing the serialized form of the /// preprocessor. void ASTWriter::WritePreprocessor(const Preprocessor &PP, bool IsModule) { PreprocessingRecord *PPRec = PP.getPreprocessingRecord(); @@ -2480,8 +2507,8 @@ void ASTWriter::WritePreprocessor(const Preprocessor &PP, bool IsModule) { MacroIdentifiers.push_back(Id.second); // Sort the set of macro definitions that need to be serialized by the // name of the macro, to provide a stable ordering. - std::sort(MacroIdentifiers.begin(), MacroIdentifiers.end(), - llvm::less_ptr<IdentifierInfo>()); + llvm::sort(MacroIdentifiers.begin(), MacroIdentifiers.end(), + llvm::less_ptr<IdentifierInfo>()); // Emit the macro directives as a list and associate the offset with the // identifier they belong to. @@ -2540,7 +2567,7 @@ void ASTWriter::WritePreprocessor(const Preprocessor &PP, bool IsModule) { Record.clear(); } - /// \brief Offsets of each of the macros into the bitstream, indexed by + /// Offsets of each of the macros into the bitstream, indexed by /// the local macro ID /// /// For each identifier that is associated with a macro, this map @@ -2640,8 +2667,8 @@ void ASTWriter::WritePreprocessorDetail(PreprocessingRecord &PPRec) { // If the preprocessor has a preprocessing record, emit it. unsigned NumPreprocessingRecords = 0; using namespace llvm; - - // Set up the abbreviation for + + // Set up the abbreviation for unsigned InclusionAbbrev = 0; { auto Abbrev = std::make_shared<BitCodeAbbrev>(); @@ -2653,15 +2680,15 @@ void ASTWriter::WritePreprocessorDetail(PreprocessingRecord &PPRec) { Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); InclusionAbbrev = Stream.EmitAbbrev(std::move(Abbrev)); } - - unsigned FirstPreprocessorEntityID - = (Chain ? PPRec.getNumLoadedPreprocessedEntities() : 0) + + unsigned FirstPreprocessorEntityID + = (Chain ? PPRec.getNumLoadedPreprocessedEntities() : 0) + NUM_PREDEF_PP_ENTITY_IDS; unsigned NextPreprocessorEntityID = FirstPreprocessorEntityID; RecordData Record; for (PreprocessingRecord::iterator E = PPRec.local_begin(), EEnd = PPRec.local_end(); - E != EEnd; + E != EEnd; (void)++E, ++NumPreprocessingRecords, ++NextPreprocessorEntityID) { Record.clear(); @@ -2702,7 +2729,7 @@ void ASTWriter::WritePreprocessorDetail(PreprocessingRecord &PPRec) { Stream.EmitRecordWithBlob(InclusionAbbrev, Record, Buffer); continue; } - + llvm_unreachable("Unhandled PreprocessedEntity in ASTWriter"); } Stream.ExitBlock(); @@ -2726,6 +2753,26 @@ void ASTWriter::WritePreprocessorDetail(PreprocessingRecord &PPRec) { Stream.EmitRecordWithBlob(PPEOffsetAbbrev, Record, bytes(PreprocessedEntityOffsets)); } + + // Write the skipped region table for the preprocessing record. + ArrayRef<SourceRange> SkippedRanges = PPRec.getSkippedRanges(); + if (SkippedRanges.size() > 0) { + std::vector<PPSkippedRange> SerializedSkippedRanges; + SerializedSkippedRanges.reserve(SkippedRanges.size()); + for (auto const& Range : SkippedRanges) + SerializedSkippedRanges.emplace_back(Range); + + using namespace llvm; + auto Abbrev = std::make_shared<BitCodeAbbrev>(); + Abbrev->Add(BitCodeAbbrevOp(PPD_SKIPPED_RANGES)); + Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); + unsigned PPESkippedRangeAbbrev = Stream.EmitAbbrev(std::move(Abbrev)); + + Record.clear(); + Record.push_back(PPD_SKIPPED_RANGES); + Stream.EmitRecordWithBlob(PPESkippedRangeAbbrev, Record, + bytes(SerializedSkippedRanges)); + } } unsigned ASTWriter::getLocalOrImportedSubmoduleID(Module *Mod) { @@ -2755,21 +2802,21 @@ unsigned ASTWriter::getSubmoduleID(Module *Mod) { return ID; } -/// \brief Compute the number of modules within the given tree (including the +/// Compute the number of modules within the given tree (including the /// given module). static unsigned getNumberOfModules(Module *Mod) { unsigned ChildModules = 0; for (auto Sub = Mod->submodule_begin(), SubEnd = Mod->submodule_end(); Sub != SubEnd; ++Sub) ChildModules += getNumberOfModules(*Sub); - + return ChildModules + 1; } void ASTWriter::WriteSubmodules(Module *WritingModule) { // Enter the submodule description block. Stream.EnterSubblock(SUBMODULE_BLOCK_ID, /*bits for abbreviations*/5); - + // Write the abbreviations needed for the submodules block. using namespace llvm; @@ -2786,6 +2833,7 @@ void ASTWriter::WriteSubmodules(Module *WritingModule) { Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // InferExplicit... Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // InferExportWild... Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // ConfigMacrosExh... + Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // ModuleMapIsPriv... Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // Name unsigned DefinitionAbbrev = Stream.EmitAbbrev(std::move(Abbrev)); @@ -2862,7 +2910,7 @@ void ASTWriter::WriteSubmodules(Module *WritingModule) { getNumberOfModules(WritingModule), FirstSubmoduleID - NUM_PREDEF_SUBMODULE_IDS}; Stream.EmitRecord(SUBMODULE_METADATA, Record); - + // Write all of the submodules. std::queue<Module *> Q; Q.push(WritingModule); @@ -2890,7 +2938,8 @@ void ASTWriter::WriteSubmodules(Module *WritingModule) { Mod->InferSubmodules, Mod->InferExplicitSubmodules, Mod->InferExportWildcard, - Mod->ConfigMacrosExhaustive}; + Mod->ConfigMacrosExhaustive, + Mod->ModuleMapIsPrivate}; Stream.EmitRecordWithBlob(DefinitionAbbrev, Record, Mod->Name); } @@ -2938,7 +2987,7 @@ void ASTWriter::WriteSubmodules(Module *WritingModule) { Stream.EmitRecordWithBlob(TopHeaderAbbrev, Record, H->getName()); } - // Emit the imports. + // Emit the imports. if (!Mod->Imports.empty()) { RecordData Record; for (auto *I : Mod->Imports) @@ -2946,7 +2995,7 @@ void ASTWriter::WriteSubmodules(Module *WritingModule) { Stream.EmitRecord(SUBMODULE_IMPORTS, Record); } - // Emit the exports. + // Emit the exports. if (!Mod->Exports.empty()) { RecordData Record; for (const auto &E : Mod->Exports) { @@ -2996,12 +3045,12 @@ void ASTWriter::WriteSubmodules(Module *WritingModule) { 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); } - + Stream.ExitBlock(); assert((NextSubmoduleID - FirstSubmoduleID == @@ -3040,7 +3089,7 @@ void ASTWriter::WritePragmaDiagnosticMappings(const DiagnosticsEngine &Diag, unsigned &DiagStateID = DiagStateIDMap[State]; Record.push_back(DiagStateID); - + if (DiagStateID == 0) { DiagStateID = ++CurrID; @@ -3071,8 +3120,11 @@ void ASTWriter::WritePragmaDiagnosticMappings(const DiagnosticsEngine &Diag, !FileIDAndFile.second.HasLocalTransitions) continue; ++NumLocations; - AddSourceLocation(Diag.SourceMgr->getLocForStartOfFile(FileIDAndFile.first), - Record); + + SourceLocation Loc = Diag.SourceMgr->getComposedLoc(FileIDAndFile.first, 0); + assert(!Loc.isInvalid() && "start loc for valid FileID is invalid"); + AddSourceLocation(Loc, Record); + Record.push_back(FileIDAndFile.second.StateTransitions.size()); for (auto &StatePoint : FileIDAndFile.second.StateTransitions) { Record.push_back(StatePoint.Offset); @@ -3099,7 +3151,7 @@ void ASTWriter::WritePragmaDiagnosticMappings(const DiagnosticsEngine &Diag, // Type Serialization //===----------------------------------------------------------------------===// -/// \brief Write the representation of a type to the AST stream. +/// Write the representation of a type to the AST stream. void ASTWriter::WriteType(QualType T) { TypeIdx &IdxRef = TypeIdxs[T]; if (IdxRef.getIndex() == 0) // we haven't seen this type before. @@ -3131,11 +3183,11 @@ void ASTWriter::WriteType(QualType T) { // Declaration Serialization //===----------------------------------------------------------------------===// -/// \brief Write the block containing all of the declaration IDs +/// Write the block containing all of the declaration IDs /// lexically declared within the given DeclContext. /// /// \returns the offset of the DECL_CONTEXT_LEXICAL block within the -/// bistream, or 0 if no block was written. +/// bitstream, or 0 if no block was written. uint64_t ASTWriter::WriteDeclContextLexicalBlock(ASTContext &Context, DeclContext *DC) { if (DC->decls_empty()) @@ -3190,8 +3242,8 @@ void ASTWriter::WriteFileDeclIDsMap() { SmallVector<std::pair<FileID, DeclIDInFileInfo *>, 64> SortedFileDeclIDs( FileDeclIDs.begin(), FileDeclIDs.end()); - std::sort(SortedFileDeclIDs.begin(), SortedFileDeclIDs.end(), - llvm::less_first()); + llvm::sort(SortedFileDeclIDs.begin(), SortedFileDeclIDs.end(), + llvm::less_first()); // Join the vectors of DeclIDs from all files. SmallVector<DeclID, 256> FileGroupedDeclIDs; @@ -3214,6 +3266,9 @@ void ASTWriter::WriteFileDeclIDsMap() { void ASTWriter::WriteComments() { Stream.EnterSubblock(COMMENTS_BLOCK_ID, 3); + auto _ = llvm::make_scope_exit([this] { Stream.ExitBlock(); }); + if (!PP->getPreprocessorOpts().WriteCommentListToPCH) + return; ArrayRef<RawComment *> RawComments = Context->Comments.getComments(); RecordData Record; for (const auto *I : RawComments) { @@ -3224,7 +3279,6 @@ void ASTWriter::WriteComments() { Record.push_back(I->isAlmostTrailingComment()); Stream.EmitRecord(COMMENTS_RAW_COMMENT, Record); } - Stream.ExitBlock(); } //===----------------------------------------------------------------------===// @@ -3261,7 +3315,7 @@ public: data_type_ref Methods) { using namespace llvm::support; - endian::Writer<little> LE(Out); + endian::Writer LE(Out, little); unsigned KeyLen = 2 + (Sel.getNumArgs()? Sel.getNumArgs() * 4 : 4); LE.write<uint16_t>(KeyLen); unsigned DataLen = 4 + 2 + 2; // 2 bytes for each of the method counts @@ -3280,7 +3334,7 @@ public: void EmitKey(raw_ostream& Out, Selector Sel, unsigned) { using namespace llvm::support; - endian::Writer<little> LE(Out); + endian::Writer LE(Out, little); uint64_t Start = Out.tell(); assert((Start >> 32) == 0 && "Selector key offset too large"); Writer.SetSelectorOffset(Sel, Start); @@ -3297,7 +3351,7 @@ public: data_type_ref Methods, unsigned DataLen) { using namespace llvm::support; - endian::Writer<little> LE(Out); + endian::Writer LE(Out, little); uint64_t Start = Out.tell(); (void)Start; LE.write<uint32_t>(Methods.ID); unsigned NumInstanceMethods = 0; @@ -3343,7 +3397,7 @@ public: } // namespace -/// \brief Write ObjC data: selectors and the method pool. +/// Write ObjC data: selectors and the method pool. /// /// The method pool contains both instance and factory methods, stored /// in an on-disk hash table indexed by the selector. The hash table also @@ -3409,7 +3463,7 @@ void ASTWriter::WriteSelectors(Sema &SemaRef) { ASTMethodPoolTrait Trait(*this); llvm::raw_svector_ostream Out(MethodPool); // Make sure that no bucket is at offset 0 - endian::Writer<little>(Out).write<uint32_t>(0); + endian::write<uint32_t>(Out, 0, little); BucketOffset = Generator.Emit(Out, Trait); } @@ -3447,7 +3501,7 @@ void ASTWriter::WriteSelectors(Sema &SemaRef) { } } -/// \brief Write the selectors referenced in @selector expression into AST file. +/// Write the selectors referenced in @selector expression into AST file. void ASTWriter::WriteReferencedSelectorsPool(Sema &SemaRef) { using namespace llvm; @@ -3522,8 +3576,8 @@ class ASTIdentifierTableTrait { bool IsModule; bool NeedDecls; ASTWriter::RecordData *InterestingIdentifierOffsets; - - /// \brief Determines whether this is an "interesting" identifier that needs a + + /// Determines whether this is an "interesting" identifier that needs a /// full IdentifierInfo structure written into the hash table. Notably, this /// doesn't check whether the name has macros defined; use PublicMacroIterator /// to check that. @@ -3558,7 +3612,7 @@ public: bool needDecls() const { return NeedDecls; } static hash_value_type ComputeHash(const IdentifierInfo* II) { - return llvm::HashString(II->getName()); + return llvm::djbHash(II->getName()); } bool isInterestingIdentifier(const IdentifierInfo *II) { @@ -3591,7 +3645,7 @@ public: using namespace llvm::support; - endian::Writer<little> LE(Out); + endian::Writer LE(Out, little); assert((uint16_t)DataLen == DataLen && (uint16_t)KeyLen == KeyLen); LE.write<uint16_t>(DataLen); @@ -3620,7 +3674,7 @@ public: IdentID ID, unsigned) { using namespace llvm::support; - endian::Writer<little> LE(Out); + endian::Writer LE(Out, little); auto MacroOffset = Writer.getMacroDirectivesOffset(II); if (!isInterestingIdentifier(II, MacroOffset)) { @@ -3665,12 +3719,12 @@ public: } // namespace -/// \brief Write the identifier table into the AST file. +/// Write the identifier table into the AST file. /// /// The identifier table consists of a blob containing string data /// (the actual identifiers themselves) and a separate "offsets" index /// that maps identifier IDs to locations within the blob. -void ASTWriter::WriteIdentifierTable(Preprocessor &PP, +void ASTWriter::WriteIdentifierTable(Preprocessor &PP, IdentifierResolver &IdResolver, bool IsModule) { using namespace llvm; @@ -3695,7 +3749,7 @@ void ASTWriter::WriteIdentifierTable(Preprocessor &PP, IIs.push_back(ID.second); // Sort the identifiers lexicographically before getting them references so // that their order is stable. - std::sort(IIs.begin(), IIs.end(), llvm::less_ptr<IdentifierInfo>()); + llvm::sort(IIs.begin(), IIs.end(), llvm::less_ptr<IdentifierInfo>()); for (const IdentifierInfo *II : IIs) if (Trait.isInterestingNonMacroIdentifier(II)) getIdentifierRef(II); @@ -3724,7 +3778,7 @@ void ASTWriter::WriteIdentifierTable(Preprocessor &PP, llvm::raw_svector_ostream Out(IdentifierTable); // Make sure that no bucket is at offset 0 - endian::Writer<little>(Out).write<uint32_t>(0); + endian::write<uint32_t>(Out, 0, little); BucketOffset = Generator.Emit(Out, Trait); } @@ -3820,8 +3874,7 @@ public: using namespace llvm::support; - endian::Writer<little>(Out) - .write<uint32_t>(Writer.getChain()->getModuleFileID(F)); + endian::write<uint32_t>(Out, Writer.getChain()->getModuleFileID(F), little); } std::pair<unsigned, unsigned> EmitKeyDataLength(raw_ostream &Out, @@ -3829,7 +3882,7 @@ public: data_type_ref Lookup) { using namespace llvm::support; - endian::Writer<little> LE(Out); + endian::Writer LE(Out, little); unsigned KeyLen = 1; switch (Name.getKind()) { case DeclarationName::Identifier: @@ -3863,7 +3916,7 @@ public: void EmitKey(raw_ostream &Out, DeclarationNameKey Name, unsigned) { using namespace llvm::support; - endian::Writer<little> LE(Out); + endian::Writer LE(Out, little); LE.write<uint8_t>(Name.getKind()); switch (Name.getKind()) { case DeclarationName::Identifier: @@ -3895,7 +3948,7 @@ public: unsigned DataLen) { using namespace llvm::support; - endian::Writer<little> LE(Out); + endian::Writer LE(Out, little); uint64_t Start = Out.tell(); (void)Start; for (unsigned I = Lookup.first, N = Lookup.second; I != N; ++I) LE.write<uint32_t>(DeclIDs[I]); @@ -3993,7 +4046,7 @@ ASTWriter::GenerateNameLookupTable(const DeclContext *ConstDC, } // Sort the names into a stable order. - std::sort(Names.begin(), Names.end()); + llvm::sort(Names.begin(), Names.end()); if (auto *D = dyn_cast<CXXRecordDecl>(DC)) { // We need to establish an ordering of constructor and conversion function @@ -4096,7 +4149,7 @@ ASTWriter::GenerateNameLookupTable(const DeclContext *ConstDC, Generator.emit(LookupTable, Trait, Lookups ? &Lookups->Table : nullptr); } -/// \brief Write the block containing all of the declaration IDs +/// Write the block containing all of the declaration IDs /// visible from the given DeclContext. /// /// \returns the offset of the DECL_CONTEXT_VISIBLE block within the @@ -4130,7 +4183,7 @@ uint64_t ASTWriter::WriteDeclContextVisibleBlock(ASTContext &Context, std::make_pair(Entry.first, Entry.second.getLookupResult())); } - std::sort(LookupResults.begin(), LookupResults.end(), llvm::less_first()); + llvm::sort(LookupResults.begin(), LookupResults.end(), llvm::less_first()); for (auto &NameAndResult : LookupResults) { DeclarationName Name = NameAndResult.first; DeclContext::lookup_result Result = NameAndResult.second; @@ -4186,7 +4239,7 @@ uint64_t ASTWriter::WriteDeclContextVisibleBlock(ASTContext &Context, return Offset; } -/// \brief Write an UPDATE_VISIBLE block for the given context. +/// Write an UPDATE_VISIBLE block for the given context. /// /// UPDATE_VISIBLE blocks contain the declarations that are added to an existing /// DeclContext in a dependent AST file. As such, they only exist for the TU @@ -4211,13 +4264,13 @@ void ASTWriter::WriteDeclContextVisibleUpdate(const DeclContext *DC) { Stream.EmitRecordWithBlob(UpdateVisibleAbbrev, Record, LookupTable); } -/// \brief Write an FP_PRAGMA_OPTIONS block for the given FPOptions. +/// Write an FP_PRAGMA_OPTIONS block for the given FPOptions. void ASTWriter::WriteFPPragmaOptions(const FPOptions &Opts) { RecordData::value_type Record[] = {Opts.getInt()}; Stream.EmitRecord(FP_PRAGMA_OPTIONS, Record); } -/// \brief Write an OPENCL_EXTENSIONS block for the given OpenCLOptions. +/// Write an OPENCL_EXTENSIONS block for the given OpenCLOptions. void ASTWriter::WriteOpenCLExtensions(Sema &SemaRef) { if (!SemaRef.Context.getLangOpts().OpenCL) return; @@ -4274,16 +4327,16 @@ void ASTWriter::WriteCUDAPragmas(Sema &SemaRef) { void ASTWriter::WriteObjCCategories() { SmallVector<ObjCCategoriesInfo, 2> CategoriesMap; RecordData Categories; - + for (unsigned I = 0, N = ObjCClassesWithCategories.size(); I != N; ++I) { unsigned Size = 0; unsigned StartIndex = Categories.size(); - + ObjCInterfaceDecl *Class = ObjCClassesWithCategories[I]; - + // Allocate space for the size. Categories.push_back(0); - + // Add the categories. for (ObjCInterfaceDecl::known_categories_iterator Cat = Class->known_categories_begin(), @@ -4292,10 +4345,10 @@ void ASTWriter::WriteObjCCategories() { assert(getDeclID(*Cat) != 0 && "Bogus category"); AddDeclRef(*Cat, Categories); } - + // Update the size. Categories[StartIndex] = Size; - + // Record this interface -> category map. ObjCCategoriesInfo CatInfo = { getDeclID(Class), StartIndex }; CategoriesMap.push_back(CatInfo); @@ -4344,7 +4397,7 @@ void ASTWriter::WriteLateParsedTemplates(Sema &SemaRef) { Stream.EmitRecord(LATE_PARSED_TEMPLATE, Record); } -/// \brief Write the state of 'pragma clang optimize' at the end of the module. +/// Write the state of 'pragma clang optimize' at the end of the module. void ASTWriter::WriteOptimizePragmaOptions(Sema &SemaRef) { RecordData Record; SourceLocation PragmaLoc = SemaRef.getOptimizeOffPragmaLocation(); @@ -4352,14 +4405,14 @@ void ASTWriter::WriteOptimizePragmaOptions(Sema &SemaRef) { Stream.EmitRecord(OPTIMIZE_PRAGMA_OPTIONS, Record); } -/// \brief Write the state of 'pragma ms_struct' at the end of the module. +/// Write the state of 'pragma ms_struct' at the end of the module. void ASTWriter::WriteMSStructPragmaOptions(Sema &SemaRef) { RecordData Record; Record.push_back(SemaRef.MSStructPragmaOn ? PMSST_ON : PMSST_OFF); Stream.EmitRecord(MSSTRUCT_PRAGMA_OPTIONS, Record); } -/// \brief Write the state of 'pragma pointers_to_members' at the end of the +/// Write the state of 'pragma pointers_to_members' at the end of the //module. void ASTWriter::WriteMSPointersToMembersPragmaOptions(Sema &SemaRef) { RecordData Record; @@ -4368,7 +4421,7 @@ void ASTWriter::WriteMSPointersToMembersPragmaOptions(Sema &SemaRef) { Stream.EmitRecord(POINTERS_TO_MEMBERS_PRAGMA_OPTIONS, Record); } -/// \brief Write the state of 'pragma pack' at the end of the module. +/// Write the state of 'pragma pack' at the end of the module. void ASTWriter::WritePackPragmaOptions(Sema &SemaRef) { // Don't serialize pragma pack state for modules, since it should only take // effect on a per-submodule basis. @@ -4427,7 +4480,7 @@ void ASTWriter::WriteModuleFileExtension(Sema &SemaRef, // General Serialization Routines //===----------------------------------------------------------------------===// -/// \brief Emit the list of attributes to the specified record. +/// Emit the list of attributes to the specified record. void ASTRecordWriter::AddAttributes(ArrayRef<const Attr *> Attrs) { auto &Record = *this; Record.push_back(Attrs.size()); @@ -4501,7 +4554,7 @@ void ASTWriter::AddVersionTuple(const VersionTuple &Version, Record.push_back(0); } -/// \brief Note that the identifier II occurs at the given offset +/// Note that the identifier II occurs at the given offset /// within the identifier table. void ASTWriter::SetIdentifierOffset(const IdentifierInfo *II, uint32_t Offset) { IdentID ID = IdentifierIDs[II]; @@ -4511,7 +4564,7 @@ void ASTWriter::SetIdentifierOffset(const IdentifierInfo *II, uint32_t Offset) { IdentifierOffsets[ID - FirstIdentID] = Offset; } -/// \brief Note that the selector Sel occurs at the given offset +/// Note that the selector Sel occurs at the given offset /// within the method pool/selector table. void ASTWriter::SetSelectorOffset(Selector Sel, uint32_t Offset) { unsigned ID = SelectorIDs[Sel]; @@ -4555,7 +4608,7 @@ ASTFileSignature ASTWriter::WriteAST(Sema &SemaRef, WritingAST = true; ASTHasCompilerErrors = hasErrors; - + // Emit the file header. Stream.Emit((unsigned)'C', 8); Stream.Emit((unsigned)'P', 8); @@ -4603,7 +4656,7 @@ ASTFileSignature ASTWriter::WriteASTCore(Sema &SemaRef, StringRef isysroot, // Make sure that the AST reader knows to finalize itself. if (Chain) Chain->finalizeForWriting(); - + ASTContext &Context = SemaRef.Context; Preprocessor &PP = SemaRef.PP; @@ -4644,7 +4697,7 @@ ASTFileSignature ASTWriter::WriteASTCore(Sema &SemaRef, StringRef isysroot, // headers. RecordData TentativeDefinitions; AddLazyVectorDecls(*this, SemaRef.TentativeDefinitions, TentativeDefinitions); - + // Build a record containing all of the file scoped decls in this file. RecordData UnusedFileScopedDecls; if (!isModule) @@ -4732,13 +4785,15 @@ ASTFileSignature ASTWriter::WriteASTCore(Sema &SemaRef, StringRef isysroot, // analyze later in AST. RecordData DeleteExprsToAnalyze; - for (const auto &DeleteExprsInfo : - SemaRef.getMismatchingDeleteExpressions()) { - AddDeclRef(DeleteExprsInfo.first, DeleteExprsToAnalyze); - DeleteExprsToAnalyze.push_back(DeleteExprsInfo.second.size()); - for (const auto &DeleteLoc : DeleteExprsInfo.second) { - AddSourceLocation(DeleteLoc.first, DeleteExprsToAnalyze); - DeleteExprsToAnalyze.push_back(DeleteLoc.second); + if (!isModule) { + for (const auto &DeleteExprsInfo : + SemaRef.getMismatchingDeleteExpressions()) { + AddDeclRef(DeleteExprsInfo.first, DeleteExprsToAnalyze); + DeleteExprsToAnalyze.push_back(DeleteExprsInfo.second.size()); + for (const auto &DeleteLoc : DeleteExprsInfo.second) { + AddSourceLocation(DeleteLoc.first, DeleteExprsToAnalyze); + DeleteExprsToAnalyze.push_back(DeleteLoc.second); + } } } @@ -4765,7 +4820,7 @@ ASTFileSignature ASTWriter::WriteASTCore(Sema &SemaRef, StringRef isysroot, NewGlobalKindDeclPairs.push_back(GetDeclRef(D)); } } - + auto Abv = std::make_shared<BitCodeAbbrev>(); Abv->Add(llvm::BitCodeAbbrevOp(TU_UPDATE_LEXICAL)); Abv->Add(llvm::BitCodeAbbrevOp(llvm::BitCodeAbbrevOp::Blob)); @@ -4787,7 +4842,7 @@ ASTFileSignature ASTWriter::WriteASTCore(Sema &SemaRef, StringRef isysroot, // If we have any extern "C" names, write out a visible update for them. if (Context.ExternCContext) WriteDeclContextVisibleUpdate(Context.ExternCContext); - + // If the translation unit has an anonymous namespace, and we don't already // have an update block for it, write it as an update block. // FIXME: Why do we not do this if there's already an update block? @@ -4826,7 +4881,7 @@ ASTFileSignature ASTWriter::WriteASTCore(Sema &SemaRef, StringRef isysroot, IIs.push_back(II); } // Sort the identifiers to visit based on their name. - std::sort(IIs.begin(), IIs.end(), llvm::less_ptr<IdentifierInfo>()); + llvm::sort(IIs.begin(), IIs.end(), llvm::less_ptr<IdentifierInfo>()); for (const IdentifierInfo *II : IIs) { for (IdentifierResolver::iterator D = SemaRef.IdResolver.begin(II), DEnd = SemaRef.IdResolver.end(); @@ -4876,7 +4931,7 @@ ASTFileSignature ASTWriter::WriteASTCore(Sema &SemaRef, StringRef isysroot, // declaration-id:i32 // 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. @@ -4890,7 +4945,7 @@ ASTFileSignature ASTWriter::WriteASTCore(Sema &SemaRef, StringRef isysroot, for (ModuleFile &M : Chain->ModuleMgr) { using namespace llvm::support; - endian::Writer<little> LE(Out); + endian::Writer LE(Out, little); LE.write<uint8_t>(static_cast<uint8_t>(M.Kind)); StringRef Name = M.Kind == MK_PrebuiltModule || M.Kind == MK_ExplicitModule @@ -4970,7 +5025,7 @@ ASTFileSignature ASTWriter::WriteASTCore(Sema &SemaRef, StringRef isysroot, WriteOpenCLExtensionDecls(SemaRef); WriteCUDAPragmas(SemaRef); - // If we're emitting a module, write out the submodule information. + // If we're emitting a module, write out the submodule information. if (WritingModule) WriteSubmodules(WritingModule); @@ -5020,7 +5075,7 @@ ASTFileSignature ASTWriter::WriteASTCore(Sema &SemaRef, StringRef isysroot, // Write the record containing CUDA-specific declaration references. if (!CUDASpecialDeclRefs.empty()) Stream.EmitRecord(CUDA_SPECIAL_DECL_REFS, CUDASpecialDeclRefs); - + // Write the delegating constructors. if (!DelegatingCtorDecls.empty()) Stream.EmitRecord(DELEGATING_CTORS, DelegatingCtorDecls); @@ -5063,7 +5118,7 @@ ASTFileSignature ASTWriter::WriteASTCore(Sema &SemaRef, StringRef isysroot, }; // Sort and deduplicate module IDs. - std::sort(Imports.begin(), Imports.end(), Cmp); + llvm::sort(Imports.begin(), Imports.end(), Cmp); Imports.erase(std::unique(Imports.begin(), Imports.end(), Eq), Imports.end()); @@ -5167,6 +5222,8 @@ void ASTWriter::WriteDeclUpdatesBlocks(RecordDataImpl &OffsetsRecord) { case UPD_CXX_INSTANTIATED_CLASS_DEFINITION: { auto *RD = cast<CXXRecordDecl>(D); UpdatedDeclContexts.insert(RD->getPrimaryContext()); + Record.push_back(RD->isParamDestroyedInCallee()); + Record.push_back(RD->getArgPassingRestrictions()); Record.AddCXXDefinitionData(RD); Record.AddOffset(WriteDeclContextLexicalBlock( *Context, const_cast<CXXRecordDecl *>(RD))); @@ -5323,7 +5380,7 @@ MacroID ASTWriter::getMacroRef(MacroInfo *MI, const IdentifierInfo *Name) { MacroID ASTWriter::getMacroID(MacroInfo *MI) { if (!MI || MI->isBuiltinMacro()) return 0; - + assert(MacroIDs.find(MI) != MacroIDs.end() && "Macro not emitted!"); return MacroIDs[MI]; } @@ -5406,12 +5463,11 @@ void ASTRecordWriter::AddTypeSourceInfo(TypeSourceInfo *TInfo) { return; } + AddTypeRef(TInfo->getType()); AddTypeLoc(TInfo->getTypeLoc()); } void ASTRecordWriter::AddTypeLoc(TypeLoc TL) { - AddTypeRef(TL.getType()); - TypeLocWriter TLW(*this); for (; !TL.isNull(); TL = TL.getNextTypeLoc()) TLW.Visit(TL); @@ -5467,12 +5523,12 @@ DeclID ASTWriter::GetDeclRef(const Decl *D) { if (!D) { return 0; } - + // If D comes from an AST file, its declaration ID is already known and // fixed. if (D->isFromASTFile()) return D->getGlobalID(); - + assert(!(reinterpret_cast<uintptr_t>(D) & 0x01) && "Invalid decl pointer"); DeclID &ID = DeclIDs[D]; if (ID == 0) { @@ -5516,7 +5572,9 @@ void ASTWriter::associateDeclWithFile(const Decl *D, DeclID ID) { return; // FIXME: ParmVarDecls that are part of a function type of a parameter of // a function/objc method, should not have TU as lexical context. - if (isa<ParmVarDecl>(D)) + // TemplateTemplateParmDecls that are part of an alias template, should not + // have TU as lexical context. + if (isa<ParmVarDecl>(D) || isa<TemplateTemplateParmDecl>(D)) return; SourceManager &SM = Context->getSourceManager(); @@ -5734,6 +5792,7 @@ void ASTRecordWriter::AddNestedNameSpecifierLoc(NestedNameSpecifierLoc NNS) { case NestedNameSpecifier::TypeSpec: case NestedNameSpecifier::TypeSpecWithTemplate: Record->push_back(Kind == NestedNameSpecifier::TypeSpecWithTemplate); + AddTypeRef(NNS.getTypeLoc().getType()); AddTypeLoc(NNS.getTypeLoc()); AddSourceLocation(NNS.getLocalSourceRange().getEnd()); break; @@ -5792,7 +5851,7 @@ void ASTRecordWriter::AddTemplateName(TemplateName Name) { AddTemplateName(subst->getReplacement()); break; } - + case TemplateName::SubstTemplateTemplateParmPack: { SubstTemplateTemplateParmPackStorage *SubstPack = Name.getAsSubstTemplateTemplateParmPack(); @@ -5855,7 +5914,7 @@ void ASTRecordWriter::AddTemplateParameterList( AddDeclRef(P); } -/// \brief Emit a template argument list. +/// Emit a template argument list. void ASTRecordWriter::AddTemplateArgumentList( const TemplateArgumentList *TemplateArgs) { assert(TemplateArgs && "No TemplateArgs!"); @@ -5892,7 +5951,7 @@ void ASTRecordWriter::AddCXXBaseSpecifier(const CXXBaseSpecifier &Base) { Record->push_back(Base.getInheritConstructors()); AddTypeSourceInfo(Base.getTypeSourceInfo()); AddSourceRange(Base.getSourceRange()); - AddSourceLocation(Base.isPackExpansion()? Base.getEllipsisLoc() + AddSourceLocation(Base.isPackExpansion()? Base.getEllipsisLoc() : SourceLocation()); } @@ -5965,7 +6024,9 @@ void ASTRecordWriter::AddCXXDefinitionData(const CXXRecordDecl *D) { Record->push_back(Data.Polymorphic); Record->push_back(Data.Abstract); Record->push_back(Data.IsStandardLayout); - Record->push_back(Data.HasNoNonEmptyBases); + Record->push_back(Data.IsCXX11StandardLayout); + Record->push_back(Data.HasBasesWithFields); + Record->push_back(Data.HasBasesWithNonStaticDataMembers); Record->push_back(Data.HasPrivateFields); Record->push_back(Data.HasProtectedFields); Record->push_back(Data.HasPublicFields); @@ -5986,11 +6047,12 @@ void ASTRecordWriter::AddCXXDefinitionData(const CXXRecordDecl *D) { Record->push_back(Data.DefaultedMoveAssignmentIsDeleted); Record->push_back(Data.DefaultedDestructorIsDeleted); Record->push_back(Data.HasTrivialSpecialMembers); + Record->push_back(Data.HasTrivialSpecialMembersForCall); Record->push_back(Data.DeclaredNonTrivialSpecialMembers); + Record->push_back(Data.DeclaredNonTrivialSpecialMembersForCall); Record->push_back(Data.HasIrrelevantDestructor); Record->push_back(Data.HasConstexprNonCopyMoveConstructor); Record->push_back(Data.HasDefaultedDefaultConstructor); - Record->push_back(Data.CanPassInRegisters); Record->push_back(Data.DefaultedDefaultConstructorIsConstexpr); Record->push_back(Data.HasConstexprDefaultConstructor); Record->push_back(Data.HasNonLiteralTypeFieldsOrBases); @@ -6024,9 +6086,9 @@ void ASTRecordWriter::AddCXXDefinitionData(const CXXRecordDecl *D) { AddUnresolvedSet(Data.Conversions.get(*Writer->Context)); AddUnresolvedSet(Data.VisibleConversions.get(*Writer->Context)); - // Data.Definition is the owning decl, no need to write it. + // Data.Definition is the owning decl, no need to write it. AddDeclRef(D->getFirstFriend()); - + // Add lambda-specific data. if (Data.IsLambda) { auto &Lambda = D->getLambdaData(); @@ -6319,7 +6381,7 @@ void ASTWriter::AddedObjCCategoryToInterface(const ObjCCategoryDecl *CatD, assert(!WritingAST && "Already writing the AST!"); if (!IFD->isFromASTFile()) return; // Declaration not imported from PCH. - + assert(IFD->getDefinition() && "Category on a class without a definition?"); ObjCClassesWithCategories.insert( const_cast<ObjCInterfaceDecl *>(IFD->getDefinition())); |