diff options
Diffstat (limited to 'lib/Serialization')
-rw-r--r-- | lib/Serialization/ASTCommon.cpp | 10 | ||||
-rw-r--r-- | lib/Serialization/ASTCommon.h | 23 | ||||
-rw-r--r-- | lib/Serialization/ASTReader.cpp | 1030 | ||||
-rw-r--r-- | lib/Serialization/ASTReaderDecl.cpp | 189 | ||||
-rw-r--r-- | lib/Serialization/ASTReaderInternals.h | 7 | ||||
-rw-r--r-- | lib/Serialization/ASTReaderStmt.cpp | 220 | ||||
-rw-r--r-- | lib/Serialization/ASTWriter.cpp | 212 | ||||
-rw-r--r-- | lib/Serialization/ASTWriterDecl.cpp | 110 | ||||
-rw-r--r-- | lib/Serialization/ASTWriterStmt.cpp | 131 | ||||
-rw-r--r-- | lib/Serialization/GeneratePCH.cpp | 24 | ||||
-rw-r--r-- | lib/Serialization/GlobalModuleIndex.cpp | 166 | ||||
-rw-r--r-- | lib/Serialization/InMemoryModuleCache.cpp | 80 | ||||
-rw-r--r-- | lib/Serialization/Module.cpp | 7 | ||||
-rw-r--r-- | lib/Serialization/ModuleFileExtension.cpp | 7 | ||||
-rw-r--r-- | lib/Serialization/ModuleManager.cpp | 60 | ||||
-rw-r--r-- | lib/Serialization/MultiOnDiskHashTable.h | 7 | ||||
-rw-r--r-- | lib/Serialization/PCHContainerOperations.cpp | 9 |
17 files changed, 1723 insertions, 569 deletions
diff --git a/lib/Serialization/ASTCommon.cpp b/lib/Serialization/ASTCommon.cpp index ca826d83d471..aa3477a7d35e 100644 --- a/lib/Serialization/ASTCommon.cpp +++ b/lib/Serialization/ASTCommon.cpp @@ -1,9 +1,8 @@ //===--- ASTCommon.cpp - Common stuff for ASTReader/ASTWriter----*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -388,12 +387,15 @@ bool serialization::isRedeclarableDeclKind(unsigned Kind) { case Decl::ClassScopeFunctionSpecialization: case Decl::Import: case Decl::OMPThreadPrivate: + case Decl::OMPAllocate: case Decl::OMPRequires: case Decl::OMPCapturedExpr: case Decl::OMPDeclareReduction: + case Decl::OMPDeclareMapper: case Decl::BuiltinTemplate: case Decl::Decomposition: case Decl::Binding: + case Decl::Concept: return false; // These indirectly derive from Redeclarable<T> but are not actually diff --git a/lib/Serialization/ASTCommon.h b/lib/Serialization/ASTCommon.h index 12e26c1fc2b9..296642e3674a 100644 --- a/lib/Serialization/ASTCommon.h +++ b/lib/Serialization/ASTCommon.h @@ -1,9 +1,8 @@ //===- ASTCommon.h - Common stuff for ASTReader/ASTWriter -*- C++ -*-=========// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -39,6 +38,7 @@ enum DeclUpdateKind { UPD_MANGLING_NUMBER, UPD_STATIC_LOCAL_NUMBER, UPD_DECL_MARKED_OPENMP_THREADPRIVATE, + UPD_DECL_MARKED_OPENMP_ALLOCATE, UPD_DECL_MARKED_OPENMP_DECLARETARGET, UPD_DECL_EXPORTED, UPD_ADDED_ATTR_TO_RECORD @@ -109,6 +109,21 @@ template<typename Fn> void numberAnonymousDeclsWithin(const DeclContext *DC, } } +/// Determine whether the given declaration will be included in the per-module +/// initializer if it needs to be eagerly handed to the AST consumer. If so, we +/// should not hand it to the consumer when deserializing it, nor include it in +/// the list of eagerly deserialized declarations. +inline bool isPartOfPerModuleInitializer(const Decl *D) { + if (isa<ImportDecl>(D)) + return true; + // Template instantiations are notionally in an "instantiation unit" rather + // than in any particular translation unit, so they need not be part of any + // particular (sub)module's per-module initializer. + if (auto *VD = dyn_cast<VarDecl>(D)) + return !isTemplateInstantiation(VD->getTemplateSpecializationKind()); + return false; +} + } // namespace serialization } // namespace clang diff --git a/lib/Serialization/ASTReader.cpp b/lib/Serialization/ASTReader.cpp index e0b2b24a0d32..7f2c7f09e8a3 100644 --- a/lib/Serialization/ASTReader.cpp +++ b/lib/Serialization/ASTReader.cpp @@ -1,9 +1,8 @@ //===- ASTReader.cpp - AST File Reader ------------------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -47,7 +46,6 @@ #include "clang/Basic/IdentifierTable.h" #include "clang/Basic/LLVM.h" #include "clang/Basic/LangOptions.h" -#include "clang/Basic/MemoryBufferCache.h" #include "clang/Basic/Module.h" #include "clang/Basic/ObjCRuntime.h" #include "clang/Basic/OperatorKinds.h" @@ -77,6 +75,7 @@ #include "clang/Serialization/ASTDeserializationListener.h" #include "clang/Serialization/ContinuousRangeMap.h" #include "clang/Serialization/GlobalModuleIndex.h" +#include "clang/Serialization/InMemoryModuleCache.h" #include "clang/Serialization/Module.h" #include "clang/Serialization/ModuleFileExtension.h" #include "clang/Serialization/ModuleManager.h" @@ -93,6 +92,7 @@ #include "llvm/ADT/None.h" #include "llvm/ADT/Optional.h" #include "llvm/ADT/STLExtras.h" +#include "llvm/ADT/ScopeExit.h" #include "llvm/ADT/SmallPtrSet.h" #include "llvm/ADT/SmallString.h" #include "llvm/ADT/SmallVector.h" @@ -101,7 +101,7 @@ #include "llvm/ADT/StringRef.h" #include "llvm/ADT/Triple.h" #include "llvm/ADT/iterator_range.h" -#include "llvm/Bitcode/BitstreamReader.h" +#include "llvm/Bitstream/BitstreamReader.h" #include "llvm/Support/Casting.h" #include "llvm/Support/Compiler.h" #include "llvm/Support/Compression.h" @@ -1148,12 +1148,26 @@ bool ASTReader::ReadLexicalDeclContextStorage(ModuleFile &M, assert(Offset != 0); SavedStreamPosition SavedPosition(Cursor); - Cursor.JumpToBit(Offset); + if (llvm::Error Err = Cursor.JumpToBit(Offset)) { + Error(std::move(Err)); + return true; + } RecordData Record; StringRef Blob; - unsigned Code = Cursor.ReadCode(); - unsigned RecCode = Cursor.readRecord(Code, Record, &Blob); + Expected<unsigned> MaybeCode = Cursor.ReadCode(); + if (!MaybeCode) { + Error(MaybeCode.takeError()); + return true; + } + unsigned Code = MaybeCode.get(); + + Expected<unsigned> MaybeRecCode = Cursor.readRecord(Code, Record, &Blob); + if (!MaybeRecCode) { + Error(MaybeRecCode.takeError()); + return true; + } + unsigned RecCode = MaybeRecCode.get(); if (RecCode != DECL_CONTEXT_LEXICAL) { Error("Expected lexical block"); return true; @@ -1184,12 +1198,26 @@ bool ASTReader::ReadVisibleDeclContextStorage(ModuleFile &M, assert(Offset != 0); SavedStreamPosition SavedPosition(Cursor); - Cursor.JumpToBit(Offset); + if (llvm::Error Err = Cursor.JumpToBit(Offset)) { + Error(std::move(Err)); + return true; + } RecordData Record; StringRef Blob; - unsigned Code = Cursor.ReadCode(); - unsigned RecCode = Cursor.readRecord(Code, Record, &Blob); + Expected<unsigned> MaybeCode = Cursor.ReadCode(); + if (!MaybeCode) { + Error(MaybeCode.takeError()); + return true; + } + unsigned Code = MaybeCode.get(); + + Expected<unsigned> MaybeRecCode = Cursor.readRecord(Code, Record, &Blob); + if (!MaybeRecCode) { + Error(MaybeRecCode.takeError()); + return true; + } + unsigned RecCode = MaybeRecCode.get(); if (RecCode != DECL_CONTEXT_VISIBLE) { Error("Expected visible lookup table block"); return true; @@ -1219,6 +1247,10 @@ void ASTReader::Error(unsigned DiagID, Diag(DiagID) << Arg1 << Arg2; } +void ASTReader::Error(llvm::Error &&Err) const { + Error(toString(std::move(Err))); +} + //===----------------------------------------------------------------------===// // Source Manager Deserialization //===----------------------------------------------------------------------===// @@ -1282,20 +1314,27 @@ bool ASTReader::ReadSourceManagerBlock(ModuleFile &F) { SLocEntryCursor = F.Stream; // The stream itself is going to skip over the source manager block. - if (F.Stream.SkipBlock()) { - Error("malformed block record in AST file"); + if (llvm::Error Err = F.Stream.SkipBlock()) { + Error(std::move(Err)); return true; } // Enter the source manager block. - if (SLocEntryCursor.EnterSubBlock(SOURCE_MANAGER_BLOCK_ID)) { - Error("malformed source manager block record in AST file"); + if (llvm::Error Err = + SLocEntryCursor.EnterSubBlock(SOURCE_MANAGER_BLOCK_ID)) { + Error(std::move(Err)); return true; } RecordData Record; while (true) { - llvm::BitstreamEntry E = SLocEntryCursor.advanceSkippingSubblocks(); + Expected<llvm::BitstreamEntry> MaybeE = + SLocEntryCursor.advanceSkippingSubblocks(); + if (!MaybeE) { + Error(MaybeE.takeError()); + return true; + } + llvm::BitstreamEntry E = MaybeE.get(); switch (E.Kind) { case llvm::BitstreamEntry::SubBlock: // Handled for us already. @@ -1312,7 +1351,13 @@ bool ASTReader::ReadSourceManagerBlock(ModuleFile &F) { // Read a record. Record.clear(); StringRef Blob; - switch (SLocEntryCursor.readRecord(E.ID, Record, &Blob)) { + Expected<unsigned> MaybeRecord = + SLocEntryCursor.readRecord(E.ID, Record, &Blob); + if (!MaybeRecord) { + Error(MaybeRecord.takeError()); + return true; + } + switch (MaybeRecord.get()) { default: // Default behavior: ignore. break; @@ -1376,8 +1421,20 @@ bool ASTReader::ReadSLocEntry(int ID) { StringRef Name) -> std::unique_ptr<llvm::MemoryBuffer> { RecordData Record; StringRef Blob; - unsigned Code = SLocEntryCursor.ReadCode(); - unsigned RecCode = SLocEntryCursor.readRecord(Code, Record, &Blob); + Expected<unsigned> MaybeCode = SLocEntryCursor.ReadCode(); + if (!MaybeCode) { + Error(MaybeCode.takeError()); + return nullptr; + } + unsigned Code = MaybeCode.get(); + + Expected<unsigned> MaybeRecCode = + SLocEntryCursor.readRecord(Code, Record, &Blob); + if (!MaybeRecCode) { + Error(MaybeRecCode.takeError()); + return nullptr; + } + unsigned RecCode = MaybeRecCode.get(); if (RecCode == SM_SLOC_BUFFER_BLOB_COMPRESSED) { if (!llvm::zlib::isAvailable()) { @@ -1401,12 +1458,23 @@ bool ASTReader::ReadSLocEntry(int ID) { }; ModuleFile *F = GlobalSLocEntryMap.find(-ID)->second; - F->SLocEntryCursor.JumpToBit(F->SLocEntryOffsets[ID - F->SLocEntryBaseID]); + if (llvm::Error Err = F->SLocEntryCursor.JumpToBit( + F->SLocEntryOffsets[ID - F->SLocEntryBaseID])) { + Error(std::move(Err)); + return true; + } + BitstreamCursor &SLocEntryCursor = F->SLocEntryCursor; unsigned BaseOffset = F->SLocEntryBaseOffset; ++NumSLocEntriesRead; - llvm::BitstreamEntry Entry = SLocEntryCursor.advance(); + Expected<llvm::BitstreamEntry> MaybeEntry = SLocEntryCursor.advance(); + if (!MaybeEntry) { + Error(MaybeEntry.takeError()); + return true; + } + llvm::BitstreamEntry Entry = MaybeEntry.get(); + if (Entry.Kind != llvm::BitstreamEntry::Record) { Error("incorrectly-formatted source location entry in AST file"); return true; @@ -1414,7 +1482,13 @@ bool ASTReader::ReadSLocEntry(int ID) { RecordData Record; StringRef Blob; - switch (SLocEntryCursor.readRecord(Entry.ID, Record, &Blob)) { + Expected<unsigned> MaybeSLOC = + SLocEntryCursor.readRecord(Entry.ID, Record, &Blob); + if (!MaybeSLOC) { + Error(MaybeSLOC.takeError()); + return true; + } + switch (MaybeSLOC.get()) { default: Error("incorrectly-formatted source location entry in AST file"); return true; @@ -1538,23 +1612,40 @@ SourceLocation ASTReader::getImportLocation(ModuleFile *F) { return F->ImportedBy[0]->FirstLoc; } -/// ReadBlockAbbrevs - Enter a subblock of the specified BlockID with the -/// specified cursor. Read the abbreviations that are at the top of the block -/// and then leave the cursor pointing into the block. +/// Enter a subblock of the specified BlockID with the specified cursor. Read +/// the abbreviations that are at the top of the block and then leave the cursor +/// pointing into the block. bool ASTReader::ReadBlockAbbrevs(BitstreamCursor &Cursor, unsigned BlockID) { - if (Cursor.EnterSubBlock(BlockID)) + if (llvm::Error Err = Cursor.EnterSubBlock(BlockID)) { + // FIXME this drops errors on the floor. + consumeError(std::move(Err)); return true; + } while (true) { uint64_t Offset = Cursor.GetCurrentBitNo(); - unsigned Code = Cursor.ReadCode(); + Expected<unsigned> MaybeCode = Cursor.ReadCode(); + if (!MaybeCode) { + // FIXME this drops errors on the floor. + consumeError(MaybeCode.takeError()); + return true; + } + unsigned Code = MaybeCode.get(); // We expect all abbrevs to be at the start of the block. if (Code != llvm::bitc::DEFINE_ABBREV) { - Cursor.JumpToBit(Offset); + if (llvm::Error Err = Cursor.JumpToBit(Offset)) { + // FIXME this drops errors on the floor. + consumeError(std::move(Err)); + return true; + } return false; } - Cursor.ReadAbbrevRecord(); + if (llvm::Error Err = Cursor.ReadAbbrevRecord()) { + // FIXME this drops errors on the floor. + consumeError(std::move(Err)); + return true; + } } } @@ -1578,7 +1669,11 @@ MacroInfo *ASTReader::ReadMacroRecord(ModuleFile &F, uint64_t Offset) { // after reading this macro. SavedStreamPosition SavedPosition(Stream); - Stream.JumpToBit(Offset); + if (llvm::Error Err = Stream.JumpToBit(Offset)) { + // FIXME this drops errors on the floor. + consumeError(std::move(Err)); + return nullptr; + } RecordData Record; SmallVector<IdentifierInfo*, 16> MacroParams; MacroInfo *Macro = nullptr; @@ -1588,7 +1683,13 @@ MacroInfo *ASTReader::ReadMacroRecord(ModuleFile &F, uint64_t Offset) { // pop it (removing all the abbreviations from the cursor) since we want to // be able to reseek within the block and read entries. unsigned Flags = BitstreamCursor::AF_DontPopBlockAtEnd; - llvm::BitstreamEntry Entry = Stream.advanceSkippingSubblocks(Flags); + Expected<llvm::BitstreamEntry> MaybeEntry = + Stream.advanceSkippingSubblocks(Flags); + if (!MaybeEntry) { + Error(MaybeEntry.takeError()); + return Macro; + } + llvm::BitstreamEntry Entry = MaybeEntry.get(); switch (Entry.Kind) { case llvm::BitstreamEntry::SubBlock: // Handled for us already. @@ -1604,8 +1705,13 @@ MacroInfo *ASTReader::ReadMacroRecord(ModuleFile &F, uint64_t Offset) { // Read a record. Record.clear(); - PreprocessorRecordTypes RecType = - (PreprocessorRecordTypes)Stream.readRecord(Entry.ID, Record); + PreprocessorRecordTypes RecType; + if (Expected<unsigned> MaybeRecType = Stream.readRecord(Entry.ID, Record)) + RecType = (PreprocessorRecordTypes)MaybeRecType.get(); + else { + Error(MaybeRecType.takeError()); + return Macro; + } switch (RecType) { case PP_MODULE_MACRO: case PP_MACRO_DIRECTIVE_HISTORY: @@ -1828,11 +1934,19 @@ void ASTReader::ReadDefinedMacros() { continue; BitstreamCursor Cursor = MacroCursor; - Cursor.JumpToBit(I.MacroStartOffset); + if (llvm::Error Err = Cursor.JumpToBit(I.MacroStartOffset)) { + Error(std::move(Err)); + return; + } RecordData Record; while (true) { - llvm::BitstreamEntry E = Cursor.advanceSkippingSubblocks(); + Expected<llvm::BitstreamEntry> MaybeE = Cursor.advanceSkippingSubblocks(); + if (!MaybeE) { + Error(MaybeE.takeError()); + return; + } + llvm::BitstreamEntry E = MaybeE.get(); switch (E.Kind) { case llvm::BitstreamEntry::SubBlock: // Handled for us already. @@ -1842,9 +1956,14 @@ void ASTReader::ReadDefinedMacros() { case llvm::BitstreamEntry::EndBlock: goto NextCursor; - case llvm::BitstreamEntry::Record: + case llvm::BitstreamEntry::Record: { Record.clear(); - switch (Cursor.readRecord(E.ID, Record)) { + Expected<unsigned> MaybeRecord = Cursor.readRecord(E.ID, Record); + if (!MaybeRecord) { + Error(MaybeRecord.takeError()); + return; + } + switch (MaybeRecord.get()) { default: // Default behavior: ignore. break; @@ -1862,6 +1981,7 @@ void ASTReader::ReadDefinedMacros() { } break; } + } } NextCursor: ; } @@ -1962,7 +2082,10 @@ void ASTReader::resolvePendingMacro(IdentifierInfo *II, BitstreamCursor &Cursor = M.MacroCursor; SavedStreamPosition SavedPosition(Cursor); - Cursor.JumpToBit(PMInfo.MacroDirectivesOffset); + if (llvm::Error Err = Cursor.JumpToBit(PMInfo.MacroDirectivesOffset)) { + Error(std::move(Err)); + return; + } struct ModuleMacroRecord { SubmoduleID SubModID; @@ -1976,15 +2099,26 @@ void ASTReader::resolvePendingMacro(IdentifierInfo *II, // macro histroy. RecordData Record; while (true) { - llvm::BitstreamEntry Entry = + Expected<llvm::BitstreamEntry> MaybeEntry = Cursor.advance(BitstreamCursor::AF_DontPopBlockAtEnd); + if (!MaybeEntry) { + Error(MaybeEntry.takeError()); + return; + } + llvm::BitstreamEntry Entry = MaybeEntry.get(); + if (Entry.Kind != llvm::BitstreamEntry::Record) { Error("malformed block record in AST file"); return; } Record.clear(); - switch ((PreprocessorRecordTypes)Cursor.readRecord(Entry.ID, Record)) { + Expected<unsigned> MaybePP = Cursor.readRecord(Entry.ID, Record); + if (!MaybePP) { + Error(MaybePP.takeError()); + return; + } + switch ((PreprocessorRecordTypes)MaybePP.get()) { case PP_MACRO_DIRECTIVE_HISTORY: break; @@ -2070,16 +2204,27 @@ ASTReader::readInputFileInfo(ModuleFile &F, unsigned ID) { // Go find this input file. BitstreamCursor &Cursor = F.InputFilesCursor; SavedStreamPosition SavedPosition(Cursor); - Cursor.JumpToBit(F.InputFileOffsets[ID-1]); + if (llvm::Error Err = Cursor.JumpToBit(F.InputFileOffsets[ID - 1])) { + // FIXME this drops errors on the floor. + consumeError(std::move(Err)); + } - unsigned Code = Cursor.ReadCode(); + Expected<unsigned> MaybeCode = Cursor.ReadCode(); + if (!MaybeCode) { + // FIXME this drops errors on the floor. + consumeError(MaybeCode.takeError()); + } + unsigned Code = MaybeCode.get(); RecordData Record; StringRef Blob; - unsigned Result = Cursor.readRecord(Code, Record, &Blob); - assert(static_cast<InputFileRecordTypes>(Result) == INPUT_FILE && - "invalid record type for input file"); - (void)Result; + if (Expected<unsigned> Maybe = Cursor.readRecord(Code, Record, &Blob)) + assert(static_cast<InputFileRecordTypes>(Maybe.get()) == INPUT_FILE && + "invalid record type for input file"); + else { + // FIXME this drops errors on the floor. + consumeError(Maybe.takeError()); + } assert(Record[0] == ID && "Bogus stored ID or offset"); InputFileInfo R; @@ -2109,7 +2254,10 @@ InputFile ASTReader::getInputFile(ModuleFile &F, unsigned ID, bool Complain) { // Go find this input file. BitstreamCursor &Cursor = F.InputFilesCursor; SavedStreamPosition SavedPosition(Cursor); - Cursor.JumpToBit(F.InputFileOffsets[ID-1]); + if (llvm::Error Err = Cursor.JumpToBit(F.InputFileOffsets[ID - 1])) { + // FIXME this drops errors on the floor. + consumeError(std::move(Err)); + } InputFileInfo FI = readInputFileInfo(F, ID); off_t StoredSize = FI.StoredSize; @@ -2258,14 +2406,23 @@ ASTReader::ASTReadResult ASTReader::ReadOptionsBlock( BitstreamCursor &Stream, unsigned ClientLoadCapabilities, bool AllowCompatibleConfigurationMismatch, ASTReaderListener &Listener, std::string &SuggestedPredefines) { - if (Stream.EnterSubBlock(OPTIONS_BLOCK_ID)) + if (llvm::Error Err = Stream.EnterSubBlock(OPTIONS_BLOCK_ID)) { + // FIXME this drops errors on the floor. + consumeError(std::move(Err)); return Failure; + } // Read all of the records in the options block. RecordData Record; ASTReadResult Result = Success; while (true) { - llvm::BitstreamEntry Entry = Stream.advance(); + Expected<llvm::BitstreamEntry> MaybeEntry = Stream.advance(); + if (!MaybeEntry) { + // FIXME this drops errors on the floor. + consumeError(MaybeEntry.takeError()); + return Failure; + } + llvm::BitstreamEntry Entry = MaybeEntry.get(); switch (Entry.Kind) { case llvm::BitstreamEntry::Error: @@ -2282,7 +2439,13 @@ ASTReader::ASTReadResult ASTReader::ReadOptionsBlock( // Read and process a record. Record.clear(); - switch ((OptionsRecordTypes)Stream.readRecord(Entry.ID, Record)) { + Expected<unsigned> MaybeRecordType = Stream.readRecord(Entry.ID, Record); + if (!MaybeRecordType) { + // FIXME this drops errors on the floor. + consumeError(MaybeRecordType.takeError()); + return Failure; + } + switch ((OptionsRecordTypes)MaybeRecordType.get()) { case LANGUAGE_OPTIONS: { bool Complain = (ClientLoadCapabilities & ARR_ConfigurationMismatch) == 0; if (ParseLanguageOptions(Record, Complain, Listener, @@ -2334,8 +2497,8 @@ ASTReader::ReadControlBlock(ModuleFile &F, BitstreamCursor &Stream = F.Stream; ASTReadResult Result = Success; - if (Stream.EnterSubBlock(CONTROL_BLOCK_ID)) { - Error("malformed block record in AST file"); + if (llvm::Error Err = Stream.EnterSubBlock(CONTROL_BLOCK_ID)) { + Error(std::move(Err)); return Failure; } @@ -2360,8 +2523,14 @@ ASTReader::ReadControlBlock(ModuleFile &F, RecordData Record; unsigned NumInputs = 0; unsigned NumUserInputs = 0; + StringRef BaseDirectoryAsWritten; while (true) { - llvm::BitstreamEntry Entry = Stream.advance(); + Expected<llvm::BitstreamEntry> MaybeEntry = Stream.advance(); + if (!MaybeEntry) { + Error(MaybeEntry.takeError()); + return Failure; + } + llvm::BitstreamEntry Entry = MaybeEntry.get(); switch (Entry.Kind) { case llvm::BitstreamEntry::Error: @@ -2424,9 +2593,11 @@ ASTReader::ReadControlBlock(ModuleFile &F, switch (Entry.ID) { case INPUT_FILES_BLOCK_ID: F.InputFilesCursor = Stream; - if (Stream.SkipBlock() || // Skip with the main cursor - // Read the abbreviations - ReadBlockAbbrevs(F.InputFilesCursor, INPUT_FILES_BLOCK_ID)) { + if (llvm::Error Err = Stream.SkipBlock()) { + Error(std::move(Err)); + return Failure; + } + if (ReadBlockAbbrevs(F.InputFilesCursor, INPUT_FILES_BLOCK_ID)) { Error("malformed block record in AST file"); return Failure; } @@ -2462,15 +2633,15 @@ ASTReader::ReadControlBlock(ModuleFile &F, // middle of a block. if (Result != Success) return Result; - } else if (Stream.SkipBlock()) { - Error("malformed block record in AST file"); + } else if (llvm::Error Err = Stream.SkipBlock()) { + Error(std::move(Err)); return Failure; } continue; default: - if (Stream.SkipBlock()) { - Error("malformed block record in AST file"); + if (llvm::Error Err = Stream.SkipBlock()) { + Error(std::move(Err)); return Failure; } continue; @@ -2484,7 +2655,13 @@ ASTReader::ReadControlBlock(ModuleFile &F, // Read and process a record. Record.clear(); StringRef Blob; - switch ((ControlRecordTypes)Stream.readRecord(Entry.ID, Record, &Blob)) { + Expected<unsigned> MaybeRecordType = + Stream.readRecord(Entry.ID, Record, &Blob); + if (!MaybeRecordType) { + Error(MaybeRecordType.takeError()); + return Failure; + } + switch ((ControlRecordTypes)MaybeRecordType.get()) { case METADATA: { if (Record[0] != VERSION_MAJOR && !DisableValidation) { if ((ClientLoadCapabilities & ARR_VersionMismatch) == 0) @@ -2560,7 +2737,9 @@ ASTReader::ReadControlBlock(ModuleFile &F, ImportedName, /*FileMapOnly*/ true); if (ImportedFile.empty()) - ImportedFile = ReadPath(F, Record, Idx); + // Use BaseDirectoryAsWritten to ensure we use the same path in the + // ModuleCache as when writing. + ImportedFile = ReadPath(BaseDirectoryAsWritten, Record, Idx); else SkipPath(Record, Idx); @@ -2611,6 +2790,9 @@ ASTReader::ReadControlBlock(ModuleFile &F, case MODULE_NAME: F.ModuleName = Blob; + Diag(diag::remark_module_import) + << F.ModuleName << F.FileName << (ImportedBy ? true : false) + << (ImportedBy ? StringRef(ImportedBy->ModuleName) : StringRef()); if (Listener) Listener->ReadModuleName(F.ModuleName); @@ -2622,6 +2804,9 @@ ASTReader::ReadControlBlock(ModuleFile &F, break; case MODULE_DIRECTORY: { + // Save the BaseDirectory as written in the PCM for computing the module + // filename for the ModuleCache. + BaseDirectoryAsWritten = Blob; assert(!F.ModuleName.empty() && "MODULE_DIRECTORY found before MODULE_NAME"); // If we've already loaded a module map file covering this module, we may @@ -2673,15 +2858,20 @@ ASTReader::ASTReadResult ASTReader::ReadASTBlock(ModuleFile &F, unsigned ClientLoadCapabilities) { BitstreamCursor &Stream = F.Stream; - if (Stream.EnterSubBlock(AST_BLOCK_ID)) { - Error("malformed block record in AST file"); + if (llvm::Error Err = Stream.EnterSubBlock(AST_BLOCK_ID)) { + Error(std::move(Err)); return Failure; } // Read all of the records and blocks for the AST file. RecordData Record; while (true) { - llvm::BitstreamEntry Entry = Stream.advance(); + Expected<llvm::BitstreamEntry> MaybeEntry = Stream.advance(); + if (!MaybeEntry) { + Error(MaybeEntry.takeError()); + return Failure; + } + llvm::BitstreamEntry Entry = MaybeEntry.get(); switch (Entry.Kind) { case llvm::BitstreamEntry::Error: @@ -2708,9 +2898,11 @@ ASTReader::ReadASTBlock(ModuleFile &F, unsigned ClientLoadCapabilities) { // cursor to it, enter the block and read the abbrevs in that block. // With the main cursor, we just skip over it. F.DeclsCursor = Stream; - if (Stream.SkipBlock() || // Skip with the main cursor. - // Read the abbrevs. - ReadBlockAbbrevs(F.DeclsCursor, DECLTYPES_BLOCK_ID)) { + if (llvm::Error Err = Stream.SkipBlock()) { + Error(std::move(Err)); + return Failure; + } + if (ReadBlockAbbrevs(F.DeclsCursor, DECLTYPES_BLOCK_ID)) { Error("malformed block record in AST file"); return Failure; } @@ -2721,8 +2913,11 @@ ASTReader::ReadASTBlock(ModuleFile &F, unsigned ClientLoadCapabilities) { if (!PP.getExternalSource()) PP.setExternalSource(this); - if (Stream.SkipBlock() || - ReadBlockAbbrevs(F.MacroCursor, PREPROCESSOR_BLOCK_ID)) { + if (llvm::Error Err = Stream.SkipBlock()) { + Error(std::move(Err)); + return Failure; + } + if (ReadBlockAbbrevs(F.MacroCursor, PREPROCESSOR_BLOCK_ID)) { Error("malformed block record in AST file"); return Failure; } @@ -2731,12 +2926,16 @@ ASTReader::ReadASTBlock(ModuleFile &F, unsigned ClientLoadCapabilities) { case PREPROCESSOR_DETAIL_BLOCK_ID: F.PreprocessorDetailCursor = Stream; - if (Stream.SkipBlock() || - ReadBlockAbbrevs(F.PreprocessorDetailCursor, + + if (llvm::Error Err = Stream.SkipBlock()) { + Error(std::move(Err)); + return Failure; + } + if (ReadBlockAbbrevs(F.PreprocessorDetailCursor, PREPROCESSOR_DETAIL_BLOCK_ID)) { - Error("malformed preprocessor detail record in AST file"); - return Failure; - } + Error("malformed preprocessor detail record in AST file"); + return Failure; + } F.PreprocessorDetailStartOffset = F.PreprocessorDetailCursor.GetCurrentBitNo(); @@ -2759,8 +2958,12 @@ ASTReader::ReadASTBlock(ModuleFile &F, unsigned ClientLoadCapabilities) { case COMMENTS_BLOCK_ID: { BitstreamCursor C = Stream; - if (Stream.SkipBlock() || - ReadBlockAbbrevs(C, COMMENTS_BLOCK_ID)) { + + if (llvm::Error Err = Stream.SkipBlock()) { + Error(std::move(Err)); + return Failure; + } + if (ReadBlockAbbrevs(C, COMMENTS_BLOCK_ID)) { Error("malformed comments block in AST file"); return Failure; } @@ -2769,8 +2972,8 @@ ASTReader::ReadASTBlock(ModuleFile &F, unsigned ClientLoadCapabilities) { } default: - if (Stream.SkipBlock()) { - Error("malformed block record in AST file"); + if (llvm::Error Err = Stream.SkipBlock()) { + Error(std::move(Err)); return Failure; } break; @@ -2785,8 +2988,13 @@ ASTReader::ReadASTBlock(ModuleFile &F, unsigned ClientLoadCapabilities) { // Read and process a record. Record.clear(); StringRef Blob; - auto RecordType = - (ASTRecordTypes)Stream.readRecord(Entry.ID, Record, &Blob); + Expected<unsigned> MaybeRecordType = + Stream.readRecord(Entry.ID, Record, &Blob); + if (!MaybeRecordType) { + Error(MaybeRecordType.takeError()); + return Failure; + } + ASTRecordTypes RecordType = (ASTRecordTypes)MaybeRecordType.get(); // If we're not loading an AST context, we don't care about most records. if (!ContextObj) { @@ -3805,10 +4013,13 @@ bool ASTReader::loadGlobalIndex() { TriedLoadingGlobalIndex = true; StringRef ModuleCachePath = getPreprocessor().getHeaderSearchInfo().getModuleCachePath(); - std::pair<GlobalModuleIndex *, GlobalModuleIndex::ErrorCode> Result - = GlobalModuleIndex::readIndex(ModuleCachePath); - if (!Result.first) + std::pair<GlobalModuleIndex *, llvm::Error> Result = + GlobalModuleIndex::readIndex(ModuleCachePath); + if (llvm::Error Err = std::move(Result.second)) { + assert(!Result.first); + consumeError(std::move(Err)); // FIXME this drops errors on the floor. return true; + } GlobalIndex.reset(Result.first); ModuleMgr.setGlobalIndex(GlobalIndex.get()); @@ -3837,7 +4048,14 @@ static void updateModuleTimestamp(ModuleFile &MF) { /// true on failure. static bool SkipCursorToBlock(BitstreamCursor &Cursor, unsigned BlockID) { while (true) { - llvm::BitstreamEntry Entry = Cursor.advance(); + Expected<llvm::BitstreamEntry> MaybeEntry = Cursor.advance(); + if (!MaybeEntry) { + // FIXME this drops errors on the floor. + consumeError(MaybeEntry.takeError()); + return true; + } + llvm::BitstreamEntry Entry = MaybeEntry.get(); + switch (Entry.Kind) { case llvm::BitstreamEntry::Error: case llvm::BitstreamEntry::EndBlock: @@ -3845,19 +4063,30 @@ static bool SkipCursorToBlock(BitstreamCursor &Cursor, unsigned BlockID) { case llvm::BitstreamEntry::Record: // Ignore top-level records. - Cursor.skipRecord(Entry.ID); - break; + if (Expected<unsigned> Skipped = Cursor.skipRecord(Entry.ID)) + break; + else { + // FIXME this drops errors on the floor. + consumeError(Skipped.takeError()); + return true; + } case llvm::BitstreamEntry::SubBlock: if (Entry.ID == BlockID) { - if (Cursor.EnterSubBlock(BlockID)) + if (llvm::Error Err = Cursor.EnterSubBlock(BlockID)) { + // FIXME this drops the error on the floor. + consumeError(std::move(Err)); return true; + } // Found it! return false; } - if (Cursor.SkipBlock()) + if (llvm::Error Err = Cursor.SkipBlock()) { + // FIXME this drops the error on the floor. + consumeError(std::move(Err)); return true; + } } } } @@ -4099,13 +4328,23 @@ ASTReader::ASTReadResult ASTReader::ReadAST(StringRef FileName, static ASTFileSignature readASTFileSignature(StringRef PCH); -/// Whether \p Stream starts with the AST/PCH file magic number 'CPCH'. -static bool startsWithASTFileMagic(BitstreamCursor &Stream) { - return Stream.canSkipToPos(4) && - Stream.Read(8) == 'C' && - Stream.Read(8) == 'P' && - Stream.Read(8) == 'C' && - Stream.Read(8) == 'H'; +/// Whether \p Stream doesn't start with the AST/PCH file magic number 'CPCH'. +static llvm::Error doesntStartWithASTFileMagic(BitstreamCursor &Stream) { + // FIXME checking magic headers is done in other places such as + // SerializedDiagnosticReader and GlobalModuleIndex, but error handling isn't + // always done the same. Unify it all with a helper. + if (!Stream.canSkipToPos(4)) + return llvm::createStringError(std::errc::illegal_byte_sequence, + "file too small to contain AST file magic"); + for (unsigned C : {'C', 'P', 'C', 'H'}) + if (Expected<llvm::SimpleBitstreamCursor::word_t> Res = Stream.Read(8)) { + if (Res.get() != C) + return llvm::createStringError( + std::errc::illegal_byte_sequence, + "file doesn't start with AST file magic"); + } else + return Res.takeError(); + return llvm::Error::success(); } static unsigned moduleKindForDiagnostic(ModuleKind Kind) { @@ -4142,6 +4381,9 @@ ASTReader::ReadASTCore(StringRef FileName, switch (AddResult) { case ModuleManager::AlreadyLoaded: + Diag(diag::remark_module_import) + << M->ModuleName << M->FileName << (ImportedBy ? true : false) + << (ImportedBy ? StringRef(ImportedBy->ModuleName) : StringRef()); return Success; case ModuleManager::NewlyLoaded: @@ -4175,22 +4417,35 @@ ASTReader::ReadASTCore(StringRef FileName, assert(M && "Missing module file"); + bool ShouldFinalizePCM = false; + auto FinalizeOrDropPCM = llvm::make_scope_exit([&]() { + auto &MC = getModuleManager().getModuleCache(); + if (ShouldFinalizePCM) + MC.finalizePCM(FileName); + else + MC.tryToDropPCM(FileName); + }); ModuleFile &F = *M; BitstreamCursor &Stream = F.Stream; Stream = BitstreamCursor(PCHContainerRdr.ExtractPCH(*F.Buffer)); F.SizeInBits = F.Buffer->getBufferSize() * 8; // Sniff for the signature. - if (!startsWithASTFileMagic(Stream)) { - Diag(diag::err_module_file_invalid) << moduleKindForDiagnostic(Type) - << FileName; + if (llvm::Error Err = doesntStartWithASTFileMagic(Stream)) { + Diag(diag::err_module_file_invalid) + << moduleKindForDiagnostic(Type) << FileName << std::move(Err); return Failure; } // This is used for compatibility with older PCH formats. bool HaveReadControlBlock = false; while (true) { - llvm::BitstreamEntry Entry = Stream.advance(); + Expected<llvm::BitstreamEntry> MaybeEntry = Stream.advance(); + if (!MaybeEntry) { + Error(MaybeEntry.takeError()); + return Failure; + } + llvm::BitstreamEntry Entry = MaybeEntry.get(); switch (Entry.Kind) { case llvm::BitstreamEntry::Error: @@ -4241,6 +4496,7 @@ ASTReader::ReadASTCore(StringRef FileName, // Record that we've loaded this module. Loaded.push_back(ImportedModule(M, ImportedBy, ImportLoc)); + ShouldFinalizePCM = true; return Success; case UNHASHED_CONTROL_BLOCK_ID: @@ -4250,15 +4506,15 @@ ASTReader::ReadASTCore(StringRef FileName, return Failure; default: - if (Stream.SkipBlock()) { - Error("malformed block record in AST file"); + if (llvm::Error Err = Stream.SkipBlock()) { + Error(std::move(Err)); return Failure; } break; } } - return Success; + llvm_unreachable("unexpected break; expected return"); } ASTReader::ASTReadResult @@ -4286,7 +4542,7 @@ ASTReader::readUnhashedControlBlock(ModuleFile &F, bool WasImportedBy, } if (Result == OutOfDate && F.Kind == MK_ImplicitModule) { - // If this module has already been finalized in the PCMCache, we're stuck + // If this module has already been finalized in the ModuleCache, we're stuck // with it; we can only load a single version of each module. // // This can happen when a module is imported in two contexts: in one, as a @@ -4304,7 +4560,7 @@ ASTReader::readUnhashedControlBlock(ModuleFile &F, bool WasImportedBy, // validation will fail during the as-system import since the PCM on disk // doesn't guarantee that -Werror was respected. However, the -Werror // flags were checked during the initial as-user import. - if (PCMCache.isBufferFinal(F.FileName)) { + if (getModuleManager().getModuleCache().isPCMFinal(F.FileName)) { Diag(diag::warn_module_system_bit_conflict) << F.FileName; return Success; } @@ -4321,8 +4577,11 @@ ASTReader::ASTReadResult ASTReader::readUnhashedControlBlockImpl( BitstreamCursor Stream(StreamData); // Sniff for the signature. - if (!startsWithASTFileMagic(Stream)) + if (llvm::Error Err = doesntStartWithASTFileMagic(Stream)) { + // FIXME this drops the error on the floor. + consumeError(std::move(Err)); return Failure; + } // Scan for the UNHASHED_CONTROL_BLOCK_ID block. if (SkipCursorToBlock(Stream, UNHASHED_CONTROL_BLOCK_ID)) @@ -4332,7 +4591,13 @@ ASTReader::ASTReadResult ASTReader::readUnhashedControlBlockImpl( RecordData Record; ASTReadResult Result = Success; while (true) { - llvm::BitstreamEntry Entry = Stream.advance(); + Expected<llvm::BitstreamEntry> MaybeEntry = Stream.advance(); + if (!MaybeEntry) { + // FIXME this drops the error on the floor. + consumeError(MaybeEntry.takeError()); + return Failure; + } + llvm::BitstreamEntry Entry = MaybeEntry.get(); switch (Entry.Kind) { case llvm::BitstreamEntry::Error: @@ -4349,8 +4614,12 @@ ASTReader::ASTReadResult ASTReader::readUnhashedControlBlockImpl( // Read and process a record. Record.clear(); - switch ( - (UnhashedControlBlockRecordTypes)Stream.readRecord(Entry.ID, Record)) { + Expected<unsigned> MaybeRecordType = Stream.readRecord(Entry.ID, Record); + if (!MaybeRecordType) { + // FIXME this drops the error. + return Failure; + } + switch ((UnhashedControlBlockRecordTypes)MaybeRecordType.get()) { case SIGNATURE: if (F) std::copy(Record.begin(), Record.end(), F->Signature.data()); @@ -4402,12 +4671,19 @@ ASTReader::ASTReadResult ASTReader::ReadExtensionBlock(ModuleFile &F) { RecordData Record; while (true) { - llvm::BitstreamEntry Entry = Stream.advance(); + Expected<llvm::BitstreamEntry> MaybeEntry = Stream.advance(); + if (!MaybeEntry) { + Error(MaybeEntry.takeError()); + return Failure; + } + llvm::BitstreamEntry Entry = MaybeEntry.get(); + switch (Entry.Kind) { case llvm::BitstreamEntry::SubBlock: - if (Stream.SkipBlock()) + if (llvm::Error Err = Stream.SkipBlock()) { + Error(std::move(Err)); return Failure; - + } continue; case llvm::BitstreamEntry::EndBlock: @@ -4422,8 +4698,13 @@ ASTReader::ASTReadResult ASTReader::ReadExtensionBlock(ModuleFile &F) { Record.clear(); StringRef Blob; - unsigned RecCode = Stream.readRecord(Entry.ID, Record, &Blob); - switch (RecCode) { + Expected<unsigned> MaybeRecCode = + Stream.readRecord(Entry.ID, Record, &Blob); + if (!MaybeRecCode) { + Error(MaybeRecCode.takeError()); + return Failure; + } + switch (MaybeRecCode.get()) { case EXTENSION_METADATA: { ModuleFileExtensionMetadata Metadata; if (parseModuleFileExtensionMetadata(Record, Blob, Metadata)) @@ -4594,8 +4875,11 @@ void ASTReader::finalizeForWriting() { /// else returns 0. static ASTFileSignature readASTFileSignature(StringRef PCH) { BitstreamCursor Stream(PCH); - if (!startsWithASTFileMagic(Stream)) + if (llvm::Error Err = doesntStartWithASTFileMagic(Stream)) { + // FIXME this drops the error on the floor. + consumeError(std::move(Err)); return ASTFileSignature(); + } // Scan for the UNHASHED_CONTROL_BLOCK_ID block. if (SkipCursorToBlock(Stream, UNHASHED_CONTROL_BLOCK_ID)) @@ -4604,13 +4888,27 @@ static ASTFileSignature readASTFileSignature(StringRef PCH) { // Scan for SIGNATURE inside the diagnostic options block. ASTReader::RecordData Record; while (true) { - llvm::BitstreamEntry Entry = Stream.advanceSkippingSubblocks(); + Expected<llvm::BitstreamEntry> MaybeEntry = + Stream.advanceSkippingSubblocks(); + if (!MaybeEntry) { + // FIXME this drops the error on the floor. + consumeError(MaybeEntry.takeError()); + return ASTFileSignature(); + } + llvm::BitstreamEntry Entry = MaybeEntry.get(); + if (Entry.Kind != llvm::BitstreamEntry::Record) return ASTFileSignature(); Record.clear(); StringRef Blob; - if (SIGNATURE == Stream.readRecord(Entry.ID, Record, &Blob)) + Expected<unsigned> MaybeRecord = Stream.readRecord(Entry.ID, Record, &Blob); + if (!MaybeRecord) { + // FIXME this drops the error on the floor. + consumeError(MaybeRecord.takeError()); + return ASTFileSignature(); + } + if (SIGNATURE == MaybeRecord.get()) return {{{(uint32_t)Record[0], (uint32_t)Record[1], (uint32_t)Record[2], (uint32_t)Record[3], (uint32_t)Record[4]}}}; } @@ -4634,8 +4932,8 @@ std::string ASTReader::getOriginalSourceFile( BitstreamCursor Stream(PCHContainerRdr.ExtractPCH(**Buffer)); // Sniff for the signature. - if (!startsWithASTFileMagic(Stream)) { - Diags.Report(diag::err_fe_not_a_pch_file) << ASTFileName; + if (llvm::Error Err = doesntStartWithASTFileMagic(Stream)) { + Diags.Report(diag::err_fe_not_a_pch_file) << ASTFileName << std::move(Err); return std::string(); } @@ -4648,7 +4946,15 @@ std::string ASTReader::getOriginalSourceFile( // Scan for ORIGINAL_FILE inside the control block. RecordData Record; while (true) { - llvm::BitstreamEntry Entry = Stream.advanceSkippingSubblocks(); + Expected<llvm::BitstreamEntry> MaybeEntry = + Stream.advanceSkippingSubblocks(); + if (!MaybeEntry) { + // FIXME this drops errors on the floor. + consumeError(MaybeEntry.takeError()); + return std::string(); + } + llvm::BitstreamEntry Entry = MaybeEntry.get(); + if (Entry.Kind == llvm::BitstreamEntry::EndBlock) return std::string(); @@ -4659,7 +4965,13 @@ std::string ASTReader::getOriginalSourceFile( Record.clear(); StringRef Blob; - if (Stream.readRecord(Entry.ID, Record, &Blob) == ORIGINAL_FILE) + Expected<unsigned> MaybeRecord = Stream.readRecord(Entry.ID, Record, &Blob); + if (!MaybeRecord) { + // FIXME this drops the errors on the floor. + consumeError(MaybeRecord.takeError()); + return std::string(); + } + if (ORIGINAL_FILE == MaybeRecord.get()) return Blob.str(); } } @@ -4733,8 +5045,10 @@ bool ASTReader::readASTFileControlBlock( BitstreamCursor Stream(Bytes); // Sniff for the signature. - if (!startsWithASTFileMagic(Stream)) + if (llvm::Error Err = doesntStartWithASTFileMagic(Stream)) { + consumeError(std::move(Err)); // FIXME this drops errors on the floor. return true; + } // Scan for the CONTROL_BLOCK_ID block. if (SkipCursorToBlock(Stream, CONTROL_BLOCK_ID)) @@ -4749,7 +5063,13 @@ bool ASTReader::readASTFileControlBlock( std::string ModuleDir; bool DoneWithControlBlock = false; while (!DoneWithControlBlock) { - llvm::BitstreamEntry Entry = Stream.advance(); + Expected<llvm::BitstreamEntry> MaybeEntry = Stream.advance(); + if (!MaybeEntry) { + // FIXME this drops the error on the floor. + consumeError(MaybeEntry.takeError()); + return true; + } + llvm::BitstreamEntry Entry = MaybeEntry.get(); switch (Entry.Kind) { case llvm::BitstreamEntry::SubBlock: { @@ -4765,15 +5085,22 @@ bool ASTReader::readASTFileControlBlock( case INPUT_FILES_BLOCK_ID: InputFilesCursor = Stream; - if (Stream.SkipBlock() || - (NeedsInputFiles && - ReadBlockAbbrevs(InputFilesCursor, INPUT_FILES_BLOCK_ID))) + if (llvm::Error Err = Stream.SkipBlock()) { + // FIXME this drops the error on the floor. + consumeError(std::move(Err)); + return true; + } + if (NeedsInputFiles && + ReadBlockAbbrevs(InputFilesCursor, INPUT_FILES_BLOCK_ID)) return true; break; default: - if (Stream.SkipBlock()) + if (llvm::Error Err = Stream.SkipBlock()) { + // FIXME this drops the error on the floor. + consumeError(std::move(Err)); return true; + } break; } @@ -4795,8 +5122,13 @@ bool ASTReader::readASTFileControlBlock( Record.clear(); StringRef Blob; - unsigned RecCode = Stream.readRecord(Entry.ID, Record, &Blob); - switch ((ControlRecordTypes)RecCode) { + Expected<unsigned> MaybeRecCode = + Stream.readRecord(Entry.ID, Record, &Blob); + if (!MaybeRecCode) { + // FIXME this drops the error. + return Failure; + } + switch ((ControlRecordTypes)MaybeRecCode.get()) { case METADATA: if (Record[0] != VERSION_MAJOR) return true; @@ -4833,13 +5165,28 @@ bool ASTReader::readASTFileControlBlock( BitstreamCursor &Cursor = InputFilesCursor; SavedStreamPosition SavedPosition(Cursor); - Cursor.JumpToBit(InputFileOffs[I]); + if (llvm::Error Err = Cursor.JumpToBit(InputFileOffs[I])) { + // FIXME this drops errors on the floor. + consumeError(std::move(Err)); + } + + Expected<unsigned> MaybeCode = Cursor.ReadCode(); + if (!MaybeCode) { + // FIXME this drops errors on the floor. + consumeError(MaybeCode.takeError()); + } + unsigned Code = MaybeCode.get(); - unsigned Code = Cursor.ReadCode(); RecordData Record; StringRef Blob; bool shouldContinue = false; - switch ((InputFileRecordTypes)Cursor.readRecord(Code, Record, &Blob)) { + Expected<unsigned> MaybeRecordType = + Cursor.readRecord(Code, Record, &Blob); + if (!MaybeRecordType) { + // FIXME this drops errors on the floor. + consumeError(MaybeRecordType.takeError()); + } + switch ((InputFileRecordTypes)MaybeRecordType.get()) { case INPUT_FILE: bool Overridden = static_cast<bool>(Record[3]); std::string Filename = Blob; @@ -4882,30 +5229,42 @@ bool ASTReader::readASTFileControlBlock( while (!SkipCursorToBlock(Stream, EXTENSION_BLOCK_ID)) { bool DoneWithExtensionBlock = false; while (!DoneWithExtensionBlock) { - llvm::BitstreamEntry Entry = Stream.advance(); - - switch (Entry.Kind) { - case llvm::BitstreamEntry::SubBlock: - if (Stream.SkipBlock()) - return true; - - continue; + Expected<llvm::BitstreamEntry> MaybeEntry = Stream.advance(); + if (!MaybeEntry) { + // FIXME this drops the error. + return true; + } + llvm::BitstreamEntry Entry = MaybeEntry.get(); + + switch (Entry.Kind) { + case llvm::BitstreamEntry::SubBlock: + if (llvm::Error Err = Stream.SkipBlock()) { + // FIXME this drops the error on the floor. + consumeError(std::move(Err)); + return true; + } + continue; - case llvm::BitstreamEntry::EndBlock: - DoneWithExtensionBlock = true; - continue; + case llvm::BitstreamEntry::EndBlock: + DoneWithExtensionBlock = true; + continue; - case llvm::BitstreamEntry::Error: - return true; + case llvm::BitstreamEntry::Error: + return true; - case llvm::BitstreamEntry::Record: - break; - } + case llvm::BitstreamEntry::Record: + break; + } Record.clear(); StringRef Blob; - unsigned RecCode = Stream.readRecord(Entry.ID, Record, &Blob); - switch (RecCode) { + Expected<unsigned> MaybeRecCode = + Stream.readRecord(Entry.ID, Record, &Blob); + if (!MaybeRecCode) { + // FIXME this drops the error. + return true; + } + switch (MaybeRecCode.get()) { case EXTENSION_METADATA: { ModuleFileExtensionMetadata Metadata; if (parseModuleFileExtensionMetadata(Record, Blob, Metadata)) @@ -4947,8 +5306,8 @@ bool ASTReader::isAcceptableASTFile(StringRef Filename, FileManager &FileMgr, ASTReader::ASTReadResult ASTReader::ReadSubmoduleBlock(ModuleFile &F, unsigned ClientLoadCapabilities) { // Enter the submodule block. - if (F.Stream.EnterSubBlock(SUBMODULE_BLOCK_ID)) { - Error("malformed submodule block record in AST file"); + if (llvm::Error Err = F.Stream.EnterSubBlock(SUBMODULE_BLOCK_ID)) { + Error(std::move(Err)); return Failure; } @@ -4957,7 +5316,13 @@ ASTReader::ReadSubmoduleBlock(ModuleFile &F, unsigned ClientLoadCapabilities) { Module *CurrentModule = nullptr; RecordData Record; while (true) { - llvm::BitstreamEntry Entry = F.Stream.advanceSkippingSubblocks(); + Expected<llvm::BitstreamEntry> MaybeEntry = + F.Stream.advanceSkippingSubblocks(); + if (!MaybeEntry) { + Error(MaybeEntry.takeError()); + return Failure; + } + llvm::BitstreamEntry Entry = MaybeEntry.get(); switch (Entry.Kind) { case llvm::BitstreamEntry::SubBlock: // Handled for us already. @@ -4974,7 +5339,12 @@ ASTReader::ReadSubmoduleBlock(ModuleFile &F, unsigned ClientLoadCapabilities) { // Read a record. StringRef Blob; Record.clear(); - auto Kind = F.Stream.readRecord(Entry.ID, Record, &Blob); + Expected<unsigned> MaybeKind = F.Stream.readRecord(Entry.ID, Record, &Blob); + if (!MaybeKind) { + Error(MaybeKind.takeError()); + return Failure; + } + unsigned Kind = MaybeKind.get(); if ((Kind == SUBMODULE_METADATA) != First) { Error("submodule metadata record should be at beginning of block"); @@ -5451,10 +5821,20 @@ PreprocessedEntity *ASTReader::ReadPreprocessedEntity(unsigned Index) { } SavedStreamPosition SavedPosition(M.PreprocessorDetailCursor); - M.PreprocessorDetailCursor.JumpToBit(PPOffs.BitOffset); + if (llvm::Error Err = + M.PreprocessorDetailCursor.JumpToBit(PPOffs.BitOffset)) { + Error(std::move(Err)); + return nullptr; + } + + Expected<llvm::BitstreamEntry> MaybeEntry = + M.PreprocessorDetailCursor.advance(BitstreamCursor::AF_DontPopBlockAtEnd); + if (!MaybeEntry) { + Error(MaybeEntry.takeError()); + return nullptr; + } + llvm::BitstreamEntry Entry = MaybeEntry.get(); - llvm::BitstreamEntry Entry = - M.PreprocessorDetailCursor.advance(BitstreamCursor::AF_DontPopBlockAtEnd); if (Entry.Kind != llvm::BitstreamEntry::Record) return nullptr; @@ -5464,10 +5844,13 @@ PreprocessedEntity *ASTReader::ReadPreprocessedEntity(unsigned Index) { PreprocessingRecord &PPRec = *PP.getPreprocessingRecord(); StringRef Blob; RecordData Record; - PreprocessorDetailRecordTypes RecType = - (PreprocessorDetailRecordTypes)M.PreprocessorDetailCursor.readRecord( - Entry.ID, Record, &Blob); - switch (RecType) { + Expected<unsigned> MaybeRecType = + M.PreprocessorDetailCursor.readRecord(Entry.ID, Record, &Blob); + if (!MaybeRecType) { + Error(MaybeRecType.takeError()); + return nullptr; + } + switch ((PreprocessorDetailRecordTypes)MaybeRecType.get()) { case PPD_MACRO_EXPANSION: { bool isBuiltin = Record[0]; IdentifierInfo *Name = nullptr; @@ -5876,10 +6259,24 @@ QualType ASTReader::readTypeRecord(unsigned Index) { Deserializing AType(this); unsigned Idx = 0; - DeclsCursor.JumpToBit(Loc.Offset); + if (llvm::Error Err = DeclsCursor.JumpToBit(Loc.Offset)) { + Error(std::move(Err)); + return QualType(); + } RecordData Record; - unsigned Code = DeclsCursor.ReadCode(); - switch ((TypeCode)DeclsCursor.readRecord(Code, Record)) { + Expected<unsigned> MaybeCode = DeclsCursor.ReadCode(); + if (!MaybeCode) { + Error(MaybeCode.takeError()); + return QualType(); + } + unsigned Code = MaybeCode.get(); + + Expected<unsigned> MaybeTypeCode = DeclsCursor.readRecord(Code, Record); + if (!MaybeTypeCode) { + Error(MaybeTypeCode.takeError()); + return QualType(); + } + switch ((TypeCode)MaybeTypeCode.get()) { case TYPE_EXT_QUAL: { if (Record.size() != 2) { Error("Incorrect encoding of extended qualifier type"); @@ -6120,8 +6517,13 @@ QualType ASTReader::readTypeRecord(unsigned Index) { case TYPE_AUTO: { QualType Deduced = readType(*Loc.F, Record, Idx); AutoTypeKeyword Keyword = (AutoTypeKeyword)Record[Idx++]; - bool IsDependent = Deduced.isNull() ? Record[Idx++] : false; - return Context.getAutoType(Deduced, Keyword, IsDependent); + bool IsDependent = false, IsPack = false; + if (Deduced.isNull()) { + IsDependent = Record[Idx] > 0; + IsPack = Record[Idx] > 1; + ++Idx; + } + return Context.getAutoType(Deduced, Keyword, IsDependent, IsPack); } case TYPE_DEDUCED_TEMPLATE_SPECIALIZATION: { @@ -6179,6 +6581,16 @@ QualType ASTReader::readTypeRecord(unsigned Index) { return Context.getParenType(InnerType); } + case TYPE_MACRO_QUALIFIED: { + if (Record.size() != 2) { + Error("incorrect encoding of macro defined type"); + return QualType(); + } + QualType UnderlyingTy = readType(*Loc.F, Record, Idx); + IdentifierInfo *MacroII = GetIdentifierInfo(*Loc.F, Record, Idx); + return Context.getMacroQualifiedType(UnderlyingTy, MacroII); + } + case TYPE_PACK_EXPANSION: { if (Record.size() != 2) { Error("incorrect encoding of pack expansion type"); @@ -6500,6 +6912,10 @@ void TypeLocReader::VisitAdjustedTypeLoc(AdjustedTypeLoc TL) { // nothing to do } +void TypeLocReader::VisitMacroQualifiedTypeLoc(MacroQualifiedTypeLoc TL) { + TL.setExpansionLoc(ReadSourceLocation()); +} + void TypeLocReader::VisitBlockPointerTypeLoc(BlockPointerTypeLoc TL) { TL.setCaretLoc(ReadSourceLocation()); } @@ -7165,13 +7581,26 @@ ASTReader::GetExternalCXXCtorInitializers(uint64_t Offset) { RecordLocation Loc = getLocalBitOffset(Offset); BitstreamCursor &Cursor = Loc.F->DeclsCursor; SavedStreamPosition SavedPosition(Cursor); - Cursor.JumpToBit(Loc.Offset); + if (llvm::Error Err = Cursor.JumpToBit(Loc.Offset)) { + Error(std::move(Err)); + return nullptr; + } ReadingKindTracker ReadingKind(Read_Decl, *this); RecordData Record; - unsigned Code = Cursor.ReadCode(); - unsigned RecCode = Cursor.readRecord(Code, Record); - if (RecCode != DECL_CXX_CTOR_INITIALIZERS) { + Expected<unsigned> MaybeCode = Cursor.ReadCode(); + if (!MaybeCode) { + Error(MaybeCode.takeError()); + return nullptr; + } + unsigned Code = MaybeCode.get(); + + Expected<unsigned> MaybeRecCode = Cursor.readRecord(Code, Record); + if (!MaybeRecCode) { + Error(MaybeRecCode.takeError()); + return nullptr; + } + if (MaybeRecCode.get() != DECL_CXX_CTOR_INITIALIZERS) { Error("malformed AST file: missing C++ ctor initializers"); return nullptr; } @@ -7187,11 +7616,27 @@ CXXBaseSpecifier *ASTReader::GetExternalCXXBaseSpecifiers(uint64_t Offset) { RecordLocation Loc = getLocalBitOffset(Offset); BitstreamCursor &Cursor = Loc.F->DeclsCursor; SavedStreamPosition SavedPosition(Cursor); - Cursor.JumpToBit(Loc.Offset); + if (llvm::Error Err = Cursor.JumpToBit(Loc.Offset)) { + Error(std::move(Err)); + return nullptr; + } ReadingKindTracker ReadingKind(Read_Decl, *this); RecordData Record; - unsigned Code = Cursor.ReadCode(); - unsigned RecCode = Cursor.readRecord(Code, Record); + + Expected<unsigned> MaybeCode = Cursor.ReadCode(); + if (!MaybeCode) { + Error(MaybeCode.takeError()); + return nullptr; + } + unsigned Code = MaybeCode.get(); + + Expected<unsigned> MaybeRecCode = Cursor.readRecord(Code, Record); + if (!MaybeRecCode) { + Error(MaybeCode.takeError()); + return nullptr; + } + unsigned RecCode = MaybeRecCode.get(); + if (RecCode != DECL_CXX_BASE_SPECIFIERS) { Error("malformed AST file: missing C++ base specifiers"); return nullptr; @@ -7399,7 +7844,10 @@ Stmt *ASTReader::GetExternalDeclStmt(uint64_t Offset) { // Offset here is a global offset across the entire chain. RecordLocation Loc = getLocalBitOffset(Offset); - Loc.F->DeclsCursor.JumpToBit(Loc.Offset); + if (llvm::Error Err = Loc.F->DeclsCursor.JumpToBit(Loc.Offset)) { + Error(std::move(Err)); + return nullptr; + } assert(NumCurrentElementsDeserializing == 0 && "should not be called while already deserializing"); Deserializing D(this); @@ -7500,9 +7948,8 @@ void ASTReader::FindFileRegionDecls(FileID File, SourceLocation EndLoc = BeginLoc.getLocWithOffset(Length); DeclIDComp DIDComp(*this, *DInfo.Mod); - ArrayRef<serialization::LocalDeclID>::iterator - BeginIt = std::lower_bound(DInfo.Decls.begin(), DInfo.Decls.end(), - BeginLoc, DIDComp); + ArrayRef<serialization::LocalDeclID>::iterator BeginIt = + llvm::lower_bound(DInfo.Decls, BeginLoc, DIDComp); if (BeginIt != DInfo.Decls.begin()) --BeginIt; @@ -7514,9 +7961,8 @@ void ASTReader::FindFileRegionDecls(FileID File, ->isTopLevelDeclInObjCContainer()) --BeginIt; - ArrayRef<serialization::LocalDeclID>::iterator - EndIt = std::upper_bound(DInfo.Decls.begin(), DInfo.Decls.end(), - EndLoc, DIDComp); + ArrayRef<serialization::LocalDeclID>::iterator EndIt = + llvm::upper_bound(DInfo.Decls, EndLoc, DIDComp); if (EndIt != DInfo.Decls.end()) ++EndIt; @@ -7806,7 +8252,7 @@ void ASTReader::UpdateSema() { // Update the state of pragmas. Use the same API as if we had encountered the // pragma in the source. if(OptimizeOffPragmaLocation.isValid()) - SemaObj->ActOnPragmaOptimize(/* IsOn = */ false, OptimizeOffPragmaLocation); + SemaObj->ActOnPragmaOptimize(/* On = */ false, OptimizeOffPragmaLocation); if (PragmaMSStructState != -1) SemaObj->ActOnPragmaMSStruct((PragmaMSStructKind)PragmaMSStructState); if (PointersToMembersPragmaLocation.isValid()) { @@ -8507,7 +8953,7 @@ unsigned ASTReader::getModuleFileID(ModuleFile *F) { return ((F->BaseSubmoduleID + NUM_PREDEF_SUBMODULE_IDS) << 1) | 1; auto PCHModules = getModuleManager().pch_modules(); - auto I = std::find(PCHModules.begin(), PCHModules.end(), F); + auto I = llvm::find(PCHModules, F); assert(I != PCHModules.end() && "emitting reference to unknown file"); return (I - PCHModules.end()) << 1; } @@ -8710,6 +9156,11 @@ ASTReader::ReadTemplateName(ModuleFile &F, const RecordData &Record, return Context.getOverloadedTemplateName(Decls.begin(), Decls.end()); } + case TemplateName::AssumedTemplate: { + DeclarationName Name = ReadDeclarationName(F, Record, Idx); + return Context.getAssumedTemplateName(Name); + } + case TemplateName::QualifiedTemplate: { NestedNameSpecifier *NNS = ReadNestedNameSpecifier(F, Record, Idx); bool hasTemplKeyword = Record[Idx++]; @@ -9057,6 +9508,62 @@ ASTReader::ReadSourceRange(ModuleFile &F, const RecordData &Record, return SourceRange(beg, end); } +static FixedPointSemantics +ReadFixedPointSemantics(const SmallVectorImpl<uint64_t> &Record, + unsigned &Idx) { + unsigned Width = Record[Idx++]; + unsigned Scale = Record[Idx++]; + uint64_t Tmp = Record[Idx++]; + bool IsSigned = Tmp & 0x1; + bool IsSaturated = Tmp & 0x2; + bool HasUnsignedPadding = Tmp & 0x4; + return FixedPointSemantics(Width, Scale, IsSigned, IsSaturated, + HasUnsignedPadding); +} + +APValue ASTReader::ReadAPValue(const RecordData &Record, unsigned &Idx) { + unsigned Kind = Record[Idx++]; + switch (Kind) { + case APValue::None: + return APValue(); + case APValue::Indeterminate: + return APValue::IndeterminateValue(); + case APValue::Int: + return APValue(ReadAPSInt(Record, Idx)); + case APValue::Float: { + const llvm::fltSemantics &FloatSema = llvm::APFloatBase::EnumToSemantics( + static_cast<llvm::APFloatBase::Semantics>(Record[Idx++])); + return APValue(ReadAPFloat(Record, FloatSema, Idx)); + } + case APValue::FixedPoint: { + FixedPointSemantics FPSema = ReadFixedPointSemantics(Record, Idx); + return APValue(APFixedPoint(ReadAPInt(Record, Idx), FPSema)); + } + case APValue::ComplexInt: { + llvm::APSInt First = ReadAPSInt(Record, Idx); + return APValue(std::move(First), ReadAPSInt(Record, Idx)); + } + case APValue::ComplexFloat: { + const llvm::fltSemantics &FloatSema1 = llvm::APFloatBase::EnumToSemantics( + static_cast<llvm::APFloatBase::Semantics>(Record[Idx++])); + llvm::APFloat First = ReadAPFloat(Record, FloatSema1, Idx); + const llvm::fltSemantics &FloatSema2 = llvm::APFloatBase::EnumToSemantics( + static_cast<llvm::APFloatBase::Semantics>(Record[Idx++])); + return APValue(std::move(First), ReadAPFloat(Record, FloatSema2, Idx)); + } + case APValue::LValue: + case APValue::Vector: + case APValue::Array: + case APValue::Struct: + case APValue::Union: + case APValue::MemberPointer: + case APValue::AddrLabelDiff: + // TODO : Handle all these APValue::ValueKind. + return APValue(); + } + llvm_unreachable("Invalid APValue::ValueKind"); +} + /// Read an integral value llvm::APInt ASTReader::ReadAPInt(const RecordData &Record, unsigned &Idx) { unsigned BitWidth = Record[Idx++]; @@ -9094,6 +9601,14 @@ std::string ASTReader::ReadPath(ModuleFile &F, const RecordData &Record, return Filename; } +std::string ASTReader::ReadPath(StringRef BaseDirectory, + const RecordData &Record, unsigned &Idx) { + std::string Filename = ReadString(Record, Idx); + if (!BaseDirectory.empty()) + ResolveImportedPath(Filename, BaseDirectory); + return Filename; +} + VersionTuple ASTReader::ReadVersionTuple(const RecordData &Record, unsigned &Idx) { unsigned Major = Record[Idx++]; @@ -9160,8 +9675,14 @@ void ASTReader::ReadComments() { RecordData Record; while (true) { - llvm::BitstreamEntry Entry = - Cursor.advanceSkippingSubblocks(BitstreamCursor::AF_DontPopBlockAtEnd); + Expected<llvm::BitstreamEntry> MaybeEntry = + Cursor.advanceSkippingSubblocks( + BitstreamCursor::AF_DontPopBlockAtEnd); + if (!MaybeEntry) { + Error(MaybeEntry.takeError()); + return; + } + llvm::BitstreamEntry Entry = MaybeEntry.get(); switch (Entry.Kind) { case llvm::BitstreamEntry::SubBlock: // Handled for us already. @@ -9177,7 +9698,12 @@ void ASTReader::ReadComments() { // Read a record. Record.clear(); - switch ((CommentRecordTypes)Cursor.readRecord(Entry.ID, Record)) { + Expected<unsigned> MaybeComment = Cursor.readRecord(Entry.ID, Record); + if (!MaybeComment) { + Error(MaybeComment.takeError()); + return; + } + switch ((CommentRecordTypes)MaybeComment.get()) { case COMMENTS_RAW_COMMENT: { unsigned Idx = 0; SourceRange SR = ReadSourceRange(F, Record, Idx); @@ -11601,7 +12127,8 @@ void ASTReader::pushExternalDeclIntoScope(NamedDecl *D, DeclarationName Name) { } } -ASTReader::ASTReader(Preprocessor &PP, ASTContext *Context, +ASTReader::ASTReader(Preprocessor &PP, InMemoryModuleCache &ModuleCache, + ASTContext *Context, const PCHContainerReader &PCHContainerRdr, ArrayRef<std::shared_ptr<ModuleFileExtension>> Extensions, StringRef isysroot, bool DisableValidation, @@ -11614,11 +12141,9 @@ ASTReader::ASTReader(Preprocessor &PP, ASTContext *Context, : cast<ASTReaderListener>(new PCHValidator(PP, *this))), SourceMgr(PP.getSourceManager()), FileMgr(PP.getFileManager()), PCHContainerRdr(PCHContainerRdr), Diags(PP.getDiagnostics()), PP(PP), - ContextObj(Context), - ModuleMgr(PP.getFileManager(), PP.getPCMCache(), PCHContainerRdr, - PP.getHeaderSearchInfo()), - PCMCache(PP.getPCMCache()), DummyIdResolver(PP), - ReadTimer(std::move(ReadTimer)), isysroot(isysroot), + ContextObj(Context), ModuleMgr(PP.getFileManager(), ModuleCache, + PCHContainerRdr, PP.getHeaderSearchInfo()), + DummyIdResolver(PP), ReadTimer(std::move(ReadTimer)), isysroot(isysroot), DisableValidation(DisableValidation), AllowASTWithCompilerErrors(AllowASTWithCompilerErrors), AllowConfigurationMismatch(AllowConfigurationMismatch), @@ -11648,8 +12173,8 @@ IdentifierResolver &ASTReader::getIdResolver() { return SemaObj ? SemaObj->IdResolver : DummyIdResolver; } -unsigned ASTRecordReader::readRecord(llvm::BitstreamCursor &Cursor, - unsigned AbbrevID) { +Expected<unsigned> ASTRecordReader::readRecord(llvm::BitstreamCursor &Cursor, + unsigned AbbrevID) { Idx = 0; Record.clear(); return Cursor.readRecord(AbbrevID, Record); @@ -11676,6 +12201,9 @@ OMPClause *OMPClauseReader::readClause() { case OMPC_simdlen: C = new (Context) OMPSimdlenClause(); break; + case OMPC_allocator: + C = new (Context) OMPAllocatorClause(); + break; case OMPC_collapse: C = new (Context) OMPCollapseClause(); break; @@ -11785,12 +12313,12 @@ OMPClause *OMPClauseReader::readClause() { C = new (Context) OMPDeviceClause(); break; case OMPC_map: { - unsigned NumVars = Record.readInt(); - unsigned NumDeclarations = Record.readInt(); - unsigned NumLists = Record.readInt(); - unsigned NumComponents = Record.readInt(); - C = OMPMapClause::CreateEmpty(Context, NumVars, NumDeclarations, NumLists, - NumComponents); + OMPMappableExprListSizeTy Sizes; + Sizes.NumVars = Record.readInt(); + Sizes.NumUniqueDeclarations = Record.readInt(); + Sizes.NumComponentLists = Record.readInt(); + Sizes.NumComponents = Record.readInt(); + C = OMPMapClause::CreateEmpty(Context, Sizes); break; } case OMPC_num_teams: @@ -11818,41 +12346,44 @@ OMPClause *OMPClauseReader::readClause() { C = new (Context) OMPDefaultmapClause(); break; case OMPC_to: { - unsigned NumVars = Record.readInt(); - unsigned NumDeclarations = Record.readInt(); - unsigned NumLists = Record.readInt(); - unsigned NumComponents = Record.readInt(); - C = OMPToClause::CreateEmpty(Context, NumVars, NumDeclarations, NumLists, - NumComponents); + OMPMappableExprListSizeTy Sizes; + Sizes.NumVars = Record.readInt(); + Sizes.NumUniqueDeclarations = Record.readInt(); + Sizes.NumComponentLists = Record.readInt(); + Sizes.NumComponents = Record.readInt(); + C = OMPToClause::CreateEmpty(Context, Sizes); break; } case OMPC_from: { - unsigned NumVars = Record.readInt(); - unsigned NumDeclarations = Record.readInt(); - unsigned NumLists = Record.readInt(); - unsigned NumComponents = Record.readInt(); - C = OMPFromClause::CreateEmpty(Context, NumVars, NumDeclarations, NumLists, - NumComponents); + OMPMappableExprListSizeTy Sizes; + Sizes.NumVars = Record.readInt(); + Sizes.NumUniqueDeclarations = Record.readInt(); + Sizes.NumComponentLists = Record.readInt(); + Sizes.NumComponents = Record.readInt(); + C = OMPFromClause::CreateEmpty(Context, Sizes); break; } case OMPC_use_device_ptr: { - unsigned NumVars = Record.readInt(); - unsigned NumDeclarations = Record.readInt(); - unsigned NumLists = Record.readInt(); - unsigned NumComponents = Record.readInt(); - C = OMPUseDevicePtrClause::CreateEmpty(Context, NumVars, NumDeclarations, - NumLists, NumComponents); + OMPMappableExprListSizeTy Sizes; + Sizes.NumVars = Record.readInt(); + Sizes.NumUniqueDeclarations = Record.readInt(); + Sizes.NumComponentLists = Record.readInt(); + Sizes.NumComponents = Record.readInt(); + C = OMPUseDevicePtrClause::CreateEmpty(Context, Sizes); break; } case OMPC_is_device_ptr: { - unsigned NumVars = Record.readInt(); - unsigned NumDeclarations = Record.readInt(); - unsigned NumLists = Record.readInt(); - unsigned NumComponents = Record.readInt(); - C = OMPIsDevicePtrClause::CreateEmpty(Context, NumVars, NumDeclarations, - NumLists, NumComponents); + OMPMappableExprListSizeTy Sizes; + Sizes.NumVars = Record.readInt(); + Sizes.NumUniqueDeclarations = Record.readInt(); + Sizes.NumComponentLists = Record.readInt(); + Sizes.NumComponents = Record.readInt(); + C = OMPIsDevicePtrClause::CreateEmpty(Context, Sizes); break; } + case OMPC_allocate: + C = OMPAllocateClause::CreateEmpty(Context, Record.readInt()); + break; } Visit(C); C->setLocStart(Record.readSourceLocation()); @@ -11901,6 +12432,11 @@ void OMPClauseReader::VisitOMPSimdlenClause(OMPSimdlenClause *C) { C->setLParenLoc(Record.readSourceLocation()); } +void OMPClauseReader::VisitOMPAllocatorClause(OMPAllocatorClause *C) { + C->setAllocator(Record.readExpr()); + C->setLParenLoc(Record.readSourceLocation()); +} + void OMPClauseReader::VisitOMPCollapseClause(OMPCollapseClause *C) { C->setNumForLoops(Record.readSubExpr()); C->setLParenLoc(Record.readSourceLocation()); @@ -12289,6 +12825,10 @@ void OMPClauseReader::VisitOMPMapClause(OMPMapClause *C) { I, static_cast<OpenMPMapModifierKind>(Record.readInt())); C->setMapTypeModifierLoc(I, Record.readSourceLocation()); } + C->setMapperQualifierLoc(Record.readNestedNameSpecifierLoc()); + DeclarationNameInfo DNI; + Record.readDeclarationNameInfo(DNI); + C->setMapperIdInfo(DNI); C->setMapType( static_cast<OpenMPMapClauseKind>(Record.readInt())); C->setMapLoc(Record.readSourceLocation()); @@ -12301,9 +12841,15 @@ void OMPClauseReader::VisitOMPMapClause(OMPMapClause *C) { SmallVector<Expr *, 16> Vars; Vars.reserve(NumVars); for (unsigned i = 0; i != NumVars; ++i) - Vars.push_back(Record.readSubExpr()); + Vars.push_back(Record.readExpr()); C->setVarRefs(Vars); + SmallVector<Expr *, 16> UDMappers; + UDMappers.reserve(NumVars); + for (unsigned I = 0; I < NumVars; ++I) + UDMappers.push_back(Record.readExpr()); + C->setUDMapperRefs(UDMappers); + SmallVector<ValueDecl *, 16> Decls; Decls.reserve(UniqueDecls); for (unsigned i = 0; i < UniqueDecls; ++i) @@ -12325,7 +12871,7 @@ void OMPClauseReader::VisitOMPMapClause(OMPMapClause *C) { SmallVector<OMPClauseMappableExprCommon::MappableComponent, 32> Components; Components.reserve(TotalComponents); for (unsigned i = 0; i < TotalComponents; ++i) { - Expr *AssociatedExpr = Record.readSubExpr(); + Expr *AssociatedExpr = Record.readExpr(); auto *AssociatedDecl = Record.readDeclAs<ValueDecl>(); Components.push_back(OMPClauseMappableExprCommon::MappableComponent( AssociatedExpr, AssociatedDecl)); @@ -12333,6 +12879,18 @@ void OMPClauseReader::VisitOMPMapClause(OMPMapClause *C) { C->setComponents(Components, ListSizes); } +void OMPClauseReader::VisitOMPAllocateClause(OMPAllocateClause *C) { + C->setLParenLoc(Record.readSourceLocation()); + C->setColonLoc(Record.readSourceLocation()); + C->setAllocator(Record.readSubExpr()); + unsigned NumVars = C->varlist_size(); + SmallVector<Expr *, 16> Vars; + Vars.reserve(NumVars); + for (unsigned i = 0; i != NumVars; ++i) + Vars.push_back(Record.readSubExpr()); + C->setVarRefs(Vars); +} + void OMPClauseReader::VisitOMPNumTeamsClause(OMPNumTeamsClause *C) { VisitOMPClauseWithPreInit(C); C->setNumTeams(Record.readSubExpr()); @@ -12387,6 +12945,10 @@ void OMPClauseReader::VisitOMPDefaultmapClause(OMPDefaultmapClause *C) { void OMPClauseReader::VisitOMPToClause(OMPToClause *C) { C->setLParenLoc(Record.readSourceLocation()); + C->setMapperQualifierLoc(Record.readNestedNameSpecifierLoc()); + DeclarationNameInfo DNI; + Record.readDeclarationNameInfo(DNI); + C->setMapperIdInfo(DNI); auto NumVars = C->varlist_size(); auto UniqueDecls = C->getUniqueDeclarationsNum(); auto TotalLists = C->getTotalComponentListNum(); @@ -12398,6 +12960,12 @@ void OMPClauseReader::VisitOMPToClause(OMPToClause *C) { Vars.push_back(Record.readSubExpr()); C->setVarRefs(Vars); + SmallVector<Expr *, 16> UDMappers; + UDMappers.reserve(NumVars); + for (unsigned I = 0; I < NumVars; ++I) + UDMappers.push_back(Record.readSubExpr()); + C->setUDMapperRefs(UDMappers); + SmallVector<ValueDecl *, 16> Decls; Decls.reserve(UniqueDecls); for (unsigned i = 0; i < UniqueDecls; ++i) @@ -12429,6 +12997,10 @@ void OMPClauseReader::VisitOMPToClause(OMPToClause *C) { void OMPClauseReader::VisitOMPFromClause(OMPFromClause *C) { C->setLParenLoc(Record.readSourceLocation()); + C->setMapperQualifierLoc(Record.readNestedNameSpecifierLoc()); + DeclarationNameInfo DNI; + Record.readDeclarationNameInfo(DNI); + C->setMapperIdInfo(DNI); auto NumVars = C->varlist_size(); auto UniqueDecls = C->getUniqueDeclarationsNum(); auto TotalLists = C->getTotalComponentListNum(); @@ -12440,6 +13012,12 @@ void OMPClauseReader::VisitOMPFromClause(OMPFromClause *C) { Vars.push_back(Record.readSubExpr()); C->setVarRefs(Vars); + SmallVector<Expr *, 16> UDMappers; + UDMappers.reserve(NumVars); + for (unsigned I = 0; I < NumVars; ++I) + UDMappers.push_back(Record.readSubExpr()); + C->setUDMapperRefs(UDMappers); + SmallVector<ValueDecl *, 16> Decls; Decls.reserve(UniqueDecls); for (unsigned i = 0; i < UniqueDecls; ++i) diff --git a/lib/Serialization/ASTReaderDecl.cpp b/lib/Serialization/ASTReaderDecl.cpp index 763ab527570d..3cac82ad421c 100644 --- a/lib/Serialization/ASTReaderDecl.cpp +++ b/lib/Serialization/ASTReaderDecl.cpp @@ -1,9 +1,8 @@ //===- ASTReaderDecl.cpp - Decl Deserialization ---------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -58,7 +57,7 @@ #include "llvm/ADT/SmallPtrSet.h" #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/iterator_range.h" -#include "llvm/Bitcode/BitstreamReader.h" +#include "llvm/Bitstream/BitstreamReader.h" #include "llvm/Support/Casting.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/SaveAndRestore.h" @@ -383,6 +382,7 @@ namespace clang { void VisitBindingDecl(BindingDecl *BD); void VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D); DeclID VisitTemplateDecl(TemplateDecl *D); + void VisitConceptDecl(ConceptDecl *D); RedeclarableResult VisitRedeclarableTemplateDecl(RedeclarableTemplateDecl *D); void VisitClassTemplateDecl(ClassTemplateDecl *D); void VisitBuiltinTemplateDecl(BuiltinTemplateDecl *D); @@ -445,7 +445,9 @@ namespace clang { void VisitObjCPropertyDecl(ObjCPropertyDecl *D); void VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *D); void VisitOMPThreadPrivateDecl(OMPThreadPrivateDecl *D); + void VisitOMPAllocateDecl(OMPAllocateDecl *D); void VisitOMPDeclareReductionDecl(OMPDeclareReductionDecl *D); + void VisitOMPDeclareMapperDecl(OMPDeclareMapperDecl *D); void VisitOMPRequiresDecl(OMPRequiresDecl *D); void VisitOMPCapturedExprDecl(OMPCapturedExprDecl *D); }; @@ -792,6 +794,9 @@ ASTDeclReader::VisitRecordDeclImpl(RecordDecl *RD) { RD->setNonTrivialToPrimitiveDefaultInitialize(Record.readInt()); RD->setNonTrivialToPrimitiveCopy(Record.readInt()); RD->setNonTrivialToPrimitiveDestroy(Record.readInt()); + RD->setHasNonTrivialToPrimitiveDefaultInitializeCUnion(Record.readInt()); + RD->setHasNonTrivialToPrimitiveDestructCUnion(Record.readInt()); + RD->setHasNonTrivialToPrimitiveCopyCUnion(Record.readInt()); RD->setParamDestroyedInCallee(Record.readInt()); RD->setArgPassingRestrictions((RecordDecl::ArgPassingKind)Record.readInt()); return Redecl; @@ -857,7 +862,6 @@ void ASTDeclReader::VisitFunctionDecl(FunctionDecl *FD) { FD->setStorageClass(static_cast<StorageClass>(Record.readInt())); FD->setInlineSpecified(Record.readInt()); FD->setImplicitlyInline(Record.readInt()); - FD->setExplicitSpecified(Record.readInt()); FD->setVirtualAsWritten(Record.readInt()); FD->setPure(Record.readInt()); FD->setHasInheritedPrototype(Record.readInt()); @@ -868,7 +872,7 @@ void ASTDeclReader::VisitFunctionDecl(FunctionDecl *FD) { FD->setDefaulted(Record.readInt()); FD->setExplicitlyDefaulted(Record.readInt()); FD->setHasImplicitReturnZero(Record.readInt()); - FD->setConstexpr(Record.readInt()); + FD->setConstexprKind(static_cast<ConstexprSpecKind>(Record.readInt())); FD->setUsesSEHTry(Record.readInt()); FD->setHasSkippedBody(Record.readInt()); FD->setIsMultiVersion(Record.readInt()); @@ -927,12 +931,22 @@ void ASTDeclReader::VisitFunctionDecl(FunctionDecl *FD) { TemplateArgumentListInfo TemplArgsInfo(LAngleLoc, RAngleLoc); for (unsigned i = 0, e = TemplArgLocs.size(); i != e; ++i) TemplArgsInfo.addArgument(TemplArgLocs[i]); - FunctionTemplateSpecializationInfo *FTInfo - = FunctionTemplateSpecializationInfo::Create(C, FD, Template, TSK, - TemplArgList, - HasTemplateArgumentsAsWritten ? &TemplArgsInfo - : nullptr, - POI); + + MemberSpecializationInfo *MSInfo = nullptr; + if (Record.readInt()) { + auto *FD = ReadDeclAs<FunctionDecl>(); + auto TSK = (TemplateSpecializationKind)Record.readInt(); + SourceLocation POI = ReadSourceLocation(); + + MSInfo = new (C) MemberSpecializationInfo(FD, TSK); + MSInfo->setPointOfInstantiation(POI); + } + + FunctionTemplateSpecializationInfo *FTInfo = + FunctionTemplateSpecializationInfo::Create( + C, FD, Template, TSK, TemplArgList, + HasTemplateArgumentsAsWritten ? &TemplArgsInfo : nullptr, POI, + MSInfo); FD->TemplateOrSpecialization = FTInfo; if (FD->isCanonicalDecl()) { // if canonical add to template's set. @@ -955,7 +969,7 @@ void ASTDeclReader::VisitFunctionDecl(FunctionDecl *FD) { else { assert(Reader.getContext().getLangOpts().Modules && "already deserialized this template specialization"); - mergeRedeclarable(FD, ExistingInfo->Function, Redecl); + mergeRedeclarable(FD, ExistingInfo->getFunction(), Redecl); } } break; @@ -1449,8 +1463,10 @@ void ASTDeclReader::VisitParmVarDecl(ParmVarDecl *PD) { void ASTDeclReader::VisitDecompositionDecl(DecompositionDecl *DD) { VisitVarDecl(DD); auto **BDs = DD->getTrailingObjects<BindingDecl *>(); - for (unsigned I = 0; I != DD->NumBindings; ++I) + for (unsigned I = 0; I != DD->NumBindings; ++I) { BDs[I] = ReadDeclAs<BindingDecl>(); + BDs[I]->setDecomposedDecl(DD); + } } void ASTDeclReader::VisitBindingDecl(BindingDecl *BD) { @@ -1479,6 +1495,7 @@ void ASTDeclReader::VisitBlockDecl(BlockDecl *BD) { BD->setBlockMissingReturnType(Record.readInt()); BD->setIsConversionFromLambda(Record.readInt()); BD->setDoesNotEscape(Record.readInt()); + BD->setCanAvoidCopyToHeap(Record.readInt()); bool capturesCXXThis = Record.readInt(); unsigned numCaptures = Record.readInt(); @@ -1965,6 +1982,7 @@ ASTDeclReader::VisitCXXRecordDeclImpl(CXXRecordDecl *D) { } void ASTDeclReader::VisitCXXDeductionGuideDecl(CXXDeductionGuideDecl *D) { + D->setExplicitSpecifier(Record.readExplicitSpec()); VisitFunctionDecl(D); D->setIsCopyDeductionCandidate(Record.readInt()); } @@ -1990,6 +2008,7 @@ void ASTDeclReader::VisitCXXMethodDecl(CXXMethodDecl *D) { void ASTDeclReader::VisitCXXConstructorDecl(CXXConstructorDecl *D) { // We need the inherited constructor information to merge the declaration, // so we have to read it before we call VisitCXXMethodDecl. + D->setExplicitSpecifier(Record.readExplicitSpec()); if (D->isInheritingConstructor()) { auto *Shadow = ReadDeclAs<ConstructorUsingShadowDecl>(); auto *Ctor = ReadDeclAs<CXXConstructorDecl>(); @@ -2015,6 +2034,7 @@ void ASTDeclReader::VisitCXXDestructorDecl(CXXDestructorDecl *D) { } void ASTDeclReader::VisitCXXConversionDecl(CXXConversionDecl *D) { + D->setExplicitSpecifier(Record.readExplicitSpec()); VisitCXXMethodDecl(D); } @@ -2073,6 +2093,12 @@ DeclID ASTDeclReader::VisitTemplateDecl(TemplateDecl *D) { return PatternID; } +void ASTDeclReader::VisitConceptDecl(ConceptDecl *D) { + VisitTemplateDecl(D); + D->ConstraintExpr = Record.readExpr(); + mergeMergeable(D); +} + ASTDeclReader::RedeclarableResult ASTDeclReader::VisitRedeclarableTemplateDecl(RedeclarableTemplateDecl *D) { RedeclarableResult Redecl = VisitRedeclarable(D); @@ -2242,6 +2268,8 @@ void ASTDeclReader::VisitClassScopeFunctionSpecializationDecl( ClassScopeFunctionSpecializationDecl *D) { VisitDecl(D); D->Specialization = ReadDeclAs<CXXMethodDecl>(); + if (Record.readInt()) + D->TemplateArgs = Record.readASTTemplateArgumentListInfo(); } void ASTDeclReader::VisitFunctionTemplateDecl(FunctionTemplateDecl *D) { @@ -2632,6 +2660,24 @@ void ASTDeclReader::VisitOMPThreadPrivateDecl(OMPThreadPrivateDecl *D) { D->setVars(Vars); } +void ASTDeclReader::VisitOMPAllocateDecl(OMPAllocateDecl *D) { + VisitDecl(D); + unsigned NumVars = D->varlist_size(); + unsigned NumClauses = D->clauselist_size(); + SmallVector<Expr *, 16> Vars; + Vars.reserve(NumVars); + for (unsigned i = 0; i != NumVars; ++i) { + Vars.push_back(Record.readExpr()); + } + D->setVars(Vars); + SmallVector<OMPClause *, 8> Clauses; + Clauses.reserve(NumClauses); + OMPClauseReader ClauseReader(Record); + for (unsigned I = 0; I != NumClauses; ++I) + Clauses.push_back(ClauseReader.readClause()); + D->setClauses(Clauses); +} + void ASTDeclReader::VisitOMPRequiresDecl(OMPRequiresDecl * D) { VisitDecl(D); unsigned NumClauses = D->clauselist_size(); @@ -2660,6 +2706,22 @@ void ASTDeclReader::VisitOMPDeclareReductionDecl(OMPDeclareReductionDecl *D) { D->PrevDeclInScope = ReadDeclID(); } +void ASTDeclReader::VisitOMPDeclareMapperDecl(OMPDeclareMapperDecl *D) { + VisitValueDecl(D); + D->setLocation(ReadSourceLocation()); + Expr *MapperVarRefE = Record.readExpr(); + D->setMapperVarRef(MapperVarRefE); + D->VarName = Record.readDeclarationName(); + D->PrevDeclInScope = ReadDeclID(); + unsigned NumClauses = D->clauselist_size(); + SmallVector<OMPClause *, 8> Clauses; + Clauses.reserve(NumClauses); + OMPClauseReader ClauseReader(Record); + for (unsigned I = 0; I != NumClauses; ++I) + Clauses.push_back(ClauseReader.readClause()); + D->setClauses(Clauses); +} + void ASTDeclReader::VisitOMPCapturedExprDecl(OMPCapturedExprDecl *D) { VisitVarDecl(D); } @@ -2763,7 +2825,7 @@ static bool isConsumerInterestedIn(ASTContext &Ctx, Decl *D, bool HasBody) { // An ImportDecl or VarDecl imported from a module map module will get // emitted when we import the relevant module. - if (isa<ImportDecl>(D) || isa<VarDecl>(D)) { + if (isPartOfPerModuleInitializer(D)) { auto *M = D->getImportedOwningModule(); if (M && M->Kind == Module::ModuleMapModule && Ctx.DeclMustBeEmitted(D)) @@ -2777,7 +2839,8 @@ static bool isConsumerInterestedIn(ASTContext &Ctx, Decl *D, bool HasBody) { isa<PragmaCommentDecl>(D) || isa<PragmaDetectMismatchDecl>(D)) return true; - if (isa<OMPThreadPrivateDecl>(D) || isa<OMPDeclareReductionDecl>(D)) + if (isa<OMPThreadPrivateDecl>(D) || isa<OMPDeclareReductionDecl>(D) || + isa<OMPDeclareMapperDecl>(D) || isa<OMPAllocateDecl>(D)) return !D->getDeclContext()->isFunctionOrMethod(); if (const auto *Var = dyn_cast<VarDecl>(D)) return Var->isFileVarDecl() && @@ -3626,14 +3689,28 @@ Decl *ASTReader::ReadDeclRecord(DeclID ID) { // Note that we are loading a declaration record. Deserializing ADecl(this); - DeclsCursor.JumpToBit(Loc.Offset); + auto Fail = [](const char *what, llvm::Error &&Err) { + llvm::report_fatal_error(Twine("ASTReader::ReadDeclRecord failed ") + what + + ": " + toString(std::move(Err))); + }; + + if (llvm::Error JumpFailed = DeclsCursor.JumpToBit(Loc.Offset)) + Fail("jumping", std::move(JumpFailed)); ASTRecordReader Record(*this, *Loc.F); ASTDeclReader Reader(*this, Record, Loc, ID, DeclLoc); - unsigned Code = DeclsCursor.ReadCode(); + Expected<unsigned> MaybeCode = DeclsCursor.ReadCode(); + if (!MaybeCode) + Fail("reading code", MaybeCode.takeError()); + unsigned Code = MaybeCode.get(); ASTContext &Context = getContext(); Decl *D = nullptr; - switch ((DeclCode)Record.readRecord(DeclsCursor, Code)) { + Expected<unsigned> MaybeDeclCode = Record.readRecord(DeclsCursor, Code); + if (!MaybeDeclCode) + llvm::report_fatal_error( + "ASTReader::ReadDeclRecord failed reading decl code: " + + toString(MaybeDeclCode.takeError())); + switch ((DeclCode)MaybeDeclCode.get()) { case DECL_CONTEXT_LEXICAL: case DECL_CONTEXT_VISIBLE: llvm_unreachable("Record cannot be de-serialized with ReadDeclRecord"); @@ -3701,10 +3778,7 @@ Decl *ASTReader::ReadDeclRecord(DeclID ID) { D = CXXMethodDecl::CreateDeserialized(Context, ID); break; case DECL_CXX_CONSTRUCTOR: - D = CXXConstructorDecl::CreateDeserialized(Context, ID, false); - break; - case DECL_CXX_INHERITED_CONSTRUCTOR: - D = CXXConstructorDecl::CreateDeserialized(Context, ID, true); + D = CXXConstructorDecl::CreateDeserialized(Context, ID, Record.readInt()); break; case DECL_CXX_DESTRUCTOR: D = CXXDestructorDecl::CreateDeserialized(Context, ID); @@ -3765,6 +3839,9 @@ Decl *ASTReader::ReadDeclRecord(DeclID ID) { case DECL_TYPE_ALIAS_TEMPLATE: D = TypeAliasTemplateDecl::CreateDeserialized(Context, ID); break; + case DECL_CONCEPT: + D = ConceptDecl::CreateDeserialized(Context, ID); + break; case DECL_STATIC_ASSERT: D = StaticAssertDecl::CreateDeserialized(Context, ID); break; @@ -3848,12 +3925,21 @@ Decl *ASTReader::ReadDeclRecord(DeclID ID) { case DECL_OMP_THREADPRIVATE: D = OMPThreadPrivateDecl::CreateDeserialized(Context, ID, Record.readInt()); break; + case DECL_OMP_ALLOCATE: { + unsigned NumVars = Record.readInt(); + unsigned NumClauses = Record.readInt(); + D = OMPAllocateDecl::CreateDeserialized(Context, ID, NumVars, NumClauses); + break; + } case DECL_OMP_REQUIRES: D = OMPRequiresDecl::CreateDeserialized(Context, ID, Record.readInt()); break; case DECL_OMP_DECLARE_REDUCTION: D = OMPDeclareReductionDecl::CreateDeserialized(Context, ID); break; + case DECL_OMP_DECLARE_MAPPER: + D = OMPDeclareMapperDecl::CreateDeserialized(Context, ID, Record.readInt()); + break; case DECL_OMP_CAPTUREDEXPR: D = OMPCapturedExprDecl::CreateDeserialized(Context, ID); break; @@ -3966,12 +4052,25 @@ void ASTReader::loadDeclUpdateRecords(PendingUpdateRecord &Record) { uint64_t Offset = FileAndOffset.second; llvm::BitstreamCursor &Cursor = F->DeclsCursor; SavedStreamPosition SavedPosition(Cursor); - Cursor.JumpToBit(Offset); - unsigned Code = Cursor.ReadCode(); + if (llvm::Error JumpFailed = Cursor.JumpToBit(Offset)) + // FIXME don't do a fatal error. + llvm::report_fatal_error( + "ASTReader::loadDeclUpdateRecords failed jumping: " + + toString(std::move(JumpFailed))); + Expected<unsigned> MaybeCode = Cursor.ReadCode(); + if (!MaybeCode) + llvm::report_fatal_error( + "ASTReader::loadDeclUpdateRecords failed reading code: " + + toString(MaybeCode.takeError())); + unsigned Code = MaybeCode.get(); ASTRecordReader Record(*this, *F); - unsigned RecCode = Record.readRecord(Cursor, Code); - (void)RecCode; - assert(RecCode == DECL_UPDATES && "Expected DECL_UPDATES record!"); + if (Expected<unsigned> MaybeRecCode = Record.readRecord(Cursor, Code)) + assert(MaybeRecCode.get() == DECL_UPDATES && + "Expected DECL_UPDATES record!"); + else + llvm::report_fatal_error( + "ASTReader::loadDeclUpdateRecords failed reading rec code: " + + toString(MaybeCode.takeError())); ASTDeclReader Reader(*this, Record, RecordLocation(F, Offset), ID, SourceLocation()); @@ -4035,13 +4134,25 @@ void ASTReader::loadPendingDeclChain(Decl *FirstLocal, uint64_t LocalOffset) { llvm::BitstreamCursor &Cursor = M->DeclsCursor; SavedStreamPosition SavedPosition(Cursor); - Cursor.JumpToBit(LocalOffset); + if (llvm::Error JumpFailed = Cursor.JumpToBit(LocalOffset)) + llvm::report_fatal_error( + "ASTReader::loadPendingDeclChain failed jumping: " + + toString(std::move(JumpFailed))); RecordData Record; - unsigned Code = Cursor.ReadCode(); - unsigned RecCode = Cursor.readRecord(Code, Record); - (void)RecCode; - assert(RecCode == LOCAL_REDECLARATIONS && "expected LOCAL_REDECLARATIONS record!"); + Expected<unsigned> MaybeCode = Cursor.ReadCode(); + if (!MaybeCode) + llvm::report_fatal_error( + "ASTReader::loadPendingDeclChain failed reading code: " + + toString(MaybeCode.takeError())); + unsigned Code = MaybeCode.get(); + if (Expected<unsigned> MaybeRecCode = Cursor.readRecord(Code, Record)) + assert(MaybeRecCode.get() == LOCAL_REDECLARATIONS && + "expected LOCAL_REDECLARATIONS record!"); + else + llvm::report_fatal_error( + "ASTReader::loadPendingDeclChain failed reading rec code: " + + toString(MaybeCode.takeError())); // FIXME: We have several different dispatches on decl kind here; maybe // we should instead generate one loop per kind and dispatch up-front? @@ -4444,6 +4555,16 @@ void ASTDeclReader::UpdateDecl(Decl *D, ReadSourceRange())); break; + case UPD_DECL_MARKED_OPENMP_ALLOCATE: { + auto AllocatorKind = + static_cast<OMPAllocateDeclAttr::AllocatorTypeTy>(Record.readInt()); + Expr *Allocator = Record.readExpr(); + SourceRange SR = ReadSourceRange(); + D->addAttr(OMPAllocateDeclAttr::CreateImplicit( + Reader.getContext(), AllocatorKind, Allocator, SR)); + break; + } + case UPD_DECL_EXPORTED: { unsigned SubmoduleID = readSubmoduleID(); auto *Exported = cast<NamedDecl>(D); diff --git a/lib/Serialization/ASTReaderInternals.h b/lib/Serialization/ASTReaderInternals.h index 37a929907dca..265a77fdb215 100644 --- a/lib/Serialization/ASTReaderInternals.h +++ b/lib/Serialization/ASTReaderInternals.h @@ -1,9 +1,8 @@ //===- ASTReaderInternals.h - AST Reader Internals --------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/lib/Serialization/ASTReaderStmt.cpp b/lib/Serialization/ASTReaderStmt.cpp index 60abea95bfaf..afaaa543bb27 100644 --- a/lib/Serialization/ASTReaderStmt.cpp +++ b/lib/Serialization/ASTReaderStmt.cpp @@ -1,9 +1,8 @@ //===- ASTReaderStmt.cpp - Stmt/Expr Deserialization ----------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -53,7 +52,7 @@ #include "llvm/ADT/SmallString.h" #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/StringRef.h" -#include "llvm/Bitcode/BitstreamReader.h" +#include "llvm/Bitstream/BitstreamReader.h" #include "llvm/Support/Casting.h" #include "llvm/Support/ErrorHandling.h" #include <algorithm> @@ -112,7 +111,7 @@ namespace clang { /// The number of record fields required for the Stmt class /// itself. - static const unsigned NumStmtFields = 0; + static const unsigned NumStmtFields = 1; /// The number of record fields required for the Expr class /// itself. @@ -148,6 +147,7 @@ void ASTStmtReader::ReadTemplateKWAndArgsInfo(ASTTemplateKWAndArgsInfo &Args, } void ASTStmtReader::VisitStmt(Stmt *S) { + S->setIsOMPStructuredBlock(Record.readInt()); assert(Record.getIdx() == NumStmtFields && "Incorrect statement field count"); } @@ -370,12 +370,14 @@ void ASTStmtReader::VisitAsmStmt(AsmStmt *S) { void ASTStmtReader::VisitGCCAsmStmt(GCCAsmStmt *S) { VisitAsmStmt(S); + S->NumLabels = Record.readInt(); S->setRParenLoc(ReadSourceLocation()); S->setAsmString(cast_or_null<StringLiteral>(Record.readSubStmt())); unsigned NumOutputs = S->getNumOutputs(); unsigned NumInputs = S->getNumInputs(); unsigned NumClobbers = S->getNumClobbers(); + unsigned NumLabels = S->getNumLabels(); // Outputs and inputs SmallVector<IdentifierInfo *, 16> Names; @@ -392,9 +394,14 @@ void ASTStmtReader::VisitGCCAsmStmt(GCCAsmStmt *S) { for (unsigned I = 0; I != NumClobbers; ++I) Clobbers.push_back(cast_or_null<StringLiteral>(Record.readSubStmt())); + // Labels + for (unsigned I = 0, N = NumLabels; I != N; ++I) + Exprs.push_back(Record.readSubStmt()); + S->setOutputsAndInputsAndClobbers(Record.getContext(), Names.data(), Constraints.data(), Exprs.data(), NumOutputs, NumInputs, + NumLabels, Clobbers.data(), NumClobbers); } @@ -526,6 +533,18 @@ void ASTStmtReader::VisitExpr(Expr *E) { void ASTStmtReader::VisitConstantExpr(ConstantExpr *E) { VisitExpr(E); + E->ConstantExprBits.ResultKind = Record.readInt(); + switch (E->ConstantExprBits.ResultKind) { + case ConstantExpr::RSK_Int64: { + E->Int64Result() = Record.readInt(); + uint64_t tmp = Record.readInt(); + E->ConstantExprBits.IsUnsigned = tmp & 0x1; + E->ConstantExprBits.BitWidth = tmp >> 1; + break; + } + case ConstantExpr::RSK_APValue: + E->APValueResult() = Record.readAPValue(); + } E->setSubExpr(Record.readSubExpr()); } @@ -547,6 +566,7 @@ void ASTStmtReader::VisitDeclRefExpr(DeclRefExpr *E) { E->DeclRefExprBits.HasTemplateKWAndArgsInfo = Record.readInt(); E->DeclRefExprBits.HadMultipleCandidates = Record.readInt(); E->DeclRefExprBits.RefersToEnclosingVariableOrCapture = Record.readInt(); + E->DeclRefExprBits.NonOdrUseReason = Record.readInt(); unsigned NumTemplateArgs = 0; if (E->hasTemplateKWAndArgsInfo()) NumTemplateArgs = Record.readInt(); @@ -582,7 +602,8 @@ void ASTStmtReader::VisitFixedPointLiteral(FixedPointLiteral *E) { void ASTStmtReader::VisitFloatingLiteral(FloatingLiteral *E) { VisitExpr(E); - E->setRawSemantics(static_cast<Stmt::APFloatSemantics>(Record.readInt())); + E->setRawSemantics( + static_cast<llvm::APFloatBase::Semantics>(Record.readInt())); E->setExact(Record.readInt()); E->setValue(Record.getContext(), Record.readAPFloat(E->getSemantics())); E->setLocation(ReadSourceLocation()); @@ -745,9 +766,47 @@ void ASTStmtReader::VisitCXXMemberCallExpr(CXXMemberCallExpr *E) { } void ASTStmtReader::VisitMemberExpr(MemberExpr *E) { - // Don't call VisitExpr, this is fully initialized at creation. - assert(E->getStmtClass() == Stmt::MemberExprClass && - "It's a subclass, we must advance Idx!"); + VisitExpr(E); + + bool HasQualifier = Record.readInt(); + bool HasFoundDecl = Record.readInt(); + bool HasTemplateInfo = Record.readInt(); + unsigned NumTemplateArgs = Record.readInt(); + + E->Base = Record.readSubExpr(); + E->MemberDecl = Record.readDeclAs<ValueDecl>(); + Record.readDeclarationNameLoc(E->MemberDNLoc, E->MemberDecl->getDeclName()); + E->MemberLoc = Record.readSourceLocation(); + E->MemberExprBits.IsArrow = Record.readInt(); + E->MemberExprBits.HasQualifierOrFoundDecl = HasQualifier || HasFoundDecl; + E->MemberExprBits.HasTemplateKWAndArgsInfo = HasTemplateInfo; + E->MemberExprBits.HadMultipleCandidates = Record.readInt(); + E->MemberExprBits.NonOdrUseReason = Record.readInt(); + E->MemberExprBits.OperatorLoc = Record.readSourceLocation(); + + if (HasQualifier || HasFoundDecl) { + DeclAccessPair FoundDecl; + if (HasFoundDecl) { + auto *FoundD = Record.readDeclAs<NamedDecl>(); + auto AS = (AccessSpecifier)Record.readInt(); + FoundDecl = DeclAccessPair::make(FoundD, AS); + } else { + FoundDecl = DeclAccessPair::make(E->MemberDecl, + E->MemberDecl->getAccess()); + } + E->getTrailingObjects<MemberExprNameQualifier>()->FoundDecl = FoundDecl; + + NestedNameSpecifierLoc QualifierLoc; + if (HasQualifier) + QualifierLoc = Record.readNestedNameSpecifierLoc(); + E->getTrailingObjects<MemberExprNameQualifier>()->QualifierLoc = + QualifierLoc; + } + + if (HasTemplateInfo) + ReadTemplateKWAndArgsInfo( + *E->getTrailingObjects<ASTTemplateKWAndArgsInfo>(), + E->getTrailingObjects<TemplateArgumentLoc>(), NumTemplateArgs); } void ASTStmtReader::VisitObjCIsaExpr(ObjCIsaExpr *E) { @@ -968,6 +1027,15 @@ void ASTStmtReader::VisitVAArgExpr(VAArgExpr *E) { E->setIsMicrosoftABI(Record.readInt()); } +void ASTStmtReader::VisitSourceLocExpr(SourceLocExpr *E) { + VisitExpr(E); + E->ParentContext = ReadDeclAs<DeclContext>(); + E->BuiltinLoc = ReadSourceLocation(); + E->RParenLoc = ReadSourceLocation(); + E->SourceLocExprBits.Kind = + static_cast<SourceLocExpr::IdentKind>(Record.readInt()); +} + void ASTStmtReader::VisitAddrLabelExpr(AddrLabelExpr *E) { VisitExpr(E); E->setAmpAmpLoc(ReadSourceLocation()); @@ -1023,21 +1091,24 @@ void ASTStmtReader::VisitBlockExpr(BlockExpr *E) { void ASTStmtReader::VisitGenericSelectionExpr(GenericSelectionExpr *E) { VisitExpr(E); - E->NumAssocs = Record.readInt(); - E->AssocTypes = new (Record.getContext()) TypeSourceInfo*[E->NumAssocs]; - E->SubExprs = - new(Record.getContext()) Stmt*[GenericSelectionExpr::END_EXPR+E->NumAssocs]; - E->SubExprs[GenericSelectionExpr::CONTROLLING] = Record.readSubExpr(); - for (unsigned I = 0, N = E->getNumAssocs(); I != N; ++I) { - E->AssocTypes[I] = GetTypeSourceInfo(); - E->SubExprs[GenericSelectionExpr::END_EXPR+I] = Record.readSubExpr(); - } + unsigned NumAssocs = Record.readInt(); + assert(NumAssocs == E->getNumAssocs() && "Wrong NumAssocs!"); E->ResultIndex = Record.readInt(); - - E->GenericLoc = ReadSourceLocation(); + E->GenericSelectionExprBits.GenericLoc = ReadSourceLocation(); E->DefaultLoc = ReadSourceLocation(); E->RParenLoc = ReadSourceLocation(); + + Stmt **Stmts = E->getTrailingObjects<Stmt *>(); + // Add 1 to account for the controlling expression which is the first + // expression in the trailing array of Stmt *. This is not needed for + // the trailing array of TypeSourceInfo *. + for (unsigned I = 0, N = NumAssocs + 1; I < N; ++I) + Stmts[I] = Record.readSubExpr(); + + TypeSourceInfo **TSIs = E->getTrailingObjects<TypeSourceInfo *>(); + for (unsigned I = 0, N = NumAssocs; I < N; ++I) + TSIs[I] = GetTypeSourceInfo(); } void ASTStmtReader::VisitPseudoObjectExpr(PseudoObjectExpr *E) { @@ -1252,7 +1323,7 @@ void ASTStmtReader::VisitObjCAtFinallyStmt(ObjCAtFinallyStmt *S) { } void ASTStmtReader::VisitObjCAutoreleasePoolStmt(ObjCAutoreleasePoolStmt *S) { - VisitStmt(S); + VisitStmt(S); // FIXME: no test coverage. S->setSubStmt(Record.readSubStmt()); S->setAtLoc(ReadSourceLocation()); } @@ -1272,14 +1343,14 @@ void ASTStmtReader::VisitObjCAtTryStmt(ObjCAtTryStmt *S) { } void ASTStmtReader::VisitObjCAtSynchronizedStmt(ObjCAtSynchronizedStmt *S) { - VisitStmt(S); + VisitStmt(S); // FIXME: no test coverage. S->setSynchExpr(Record.readSubStmt()); S->setSynchBody(Record.readSubStmt()); S->setAtSynchronizedLoc(ReadSourceLocation()); } void ASTStmtReader::VisitObjCAtThrowStmt(ObjCAtThrowStmt *S) { - VisitStmt(S); + VisitStmt(S); // FIXME: no test coverage. S->setThrowExpr(Record.readSubStmt()); S->setThrowLoc(ReadSourceLocation()); } @@ -1439,6 +1510,12 @@ void ASTStmtReader::VisitCXXFunctionalCastExpr(CXXFunctionalCastExpr *E) { E->setRParenLoc(ReadSourceLocation()); } +void ASTStmtReader::VisitBuiltinBitCastExpr(BuiltinBitCastExpr *E) { + VisitExplicitCastExpr(E); + E->KWLoc = ReadSourceLocation(); + E->RParenLoc = ReadSourceLocation(); +} + void ASTStmtReader::VisitUserDefinedLiteral(UserDefinedLiteral *E) { VisitCallExpr(E); E->UDSuffixLoc = ReadSourceLocation(); @@ -1484,12 +1561,14 @@ void ASTStmtReader::VisitCXXThrowExpr(CXXThrowExpr *E) { void ASTStmtReader::VisitCXXDefaultArgExpr(CXXDefaultArgExpr *E) { VisitExpr(E); E->Param = ReadDeclAs<ParmVarDecl>(); + E->UsedContext = ReadDeclAs<DeclContext>(); E->CXXDefaultArgExprBits.Loc = ReadSourceLocation(); } void ASTStmtReader::VisitCXXDefaultInitExpr(CXXDefaultInitExpr *E) { VisitExpr(E); E->Field = ReadDeclAs<FieldDecl>(); + E->UsedContext = ReadDeclAs<DeclContext>(); E->CXXDefaultInitExprBits.Loc = ReadSourceLocation(); } @@ -1789,9 +1868,9 @@ void ASTStmtReader::VisitFunctionParmPackExpr(FunctionParmPackExpr *E) { E->NumParameters = Record.readInt(); E->ParamPack = ReadDeclAs<ParmVarDecl>(); E->NameLoc = ReadSourceLocation(); - auto **Parms = E->getTrailingObjects<ParmVarDecl *>(); + auto **Parms = E->getTrailingObjects<VarDecl *>(); for (unsigned i = 0, n = E->NumParameters; i != n; ++i) - Parms[i] = ReadDeclAs<ParmVarDecl>(); + Parms[i] = ReadDeclAs<VarDecl>(); } void ASTStmtReader::VisitMaterializeTemporaryExpr(MaterializeTemporaryExpr *E) { @@ -1807,6 +1886,7 @@ void ASTStmtReader::VisitCXXFoldExpr(CXXFoldExpr *E) { E->LParenLoc = ReadSourceLocation(); E->EllipsisLoc = ReadSourceLocation(); E->RParenLoc = ReadSourceLocation(); + E->NumExpansions = Record.readInt(); E->SubExprs[0] = Record.readSubExpr(); E->SubExprs[1] = Record.readSubExpr(); E->Opcode = (BinaryOperatorKind)Record.readInt(); @@ -1889,7 +1969,7 @@ void ASTStmtReader::VisitSEHTryStmt(SEHTryStmt *S) { void ASTStmtReader::VisitCUDAKernelCallExpr(CUDAKernelCallExpr *E) { VisitCallExpr(E); - E->setConfig(cast<CallExpr>(Record.readSubExpr())); + E->setPreArg(CUDAKernelCallExpr::CONFIG, Record.readSubExpr()); } //===----------------------------------------------------------------------===// @@ -2318,7 +2398,13 @@ Stmt *ASTReader::ReadStmtFromStream(ModuleFile &F) { Stmt::EmptyShell Empty; while (true) { - llvm::BitstreamEntry Entry = Cursor.advanceSkippingSubblocks(); + llvm::Expected<llvm::BitstreamEntry> MaybeEntry = + Cursor.advanceSkippingSubblocks(); + if (!MaybeEntry) { + Error(toString(MaybeEntry.takeError())); + return nullptr; + } + llvm::BitstreamEntry Entry = MaybeEntry.get(); switch (Entry.Kind) { case llvm::BitstreamEntry::SubBlock: // Handled for us already. @@ -2336,7 +2422,12 @@ Stmt *ASTReader::ReadStmtFromStream(ModuleFile &F) { Stmt *S = nullptr; bool Finished = false; bool IsStmtReference = false; - switch ((StmtCode)Record.readRecord(Cursor, Entry.ID)) { + Expected<unsigned> MaybeStmtCode = Record.readRecord(Cursor, Entry.ID); + if (!MaybeStmtCode) { + Error(toString(MaybeStmtCode.takeError())); + return nullptr; + } + switch ((StmtCode)MaybeStmtCode.get()) { case STMT_STOP: Finished = true; break; @@ -2449,7 +2540,11 @@ Stmt *ASTReader::ReadStmtFromStream(ModuleFile &F) { break; case EXPR_CONSTANT: - S = new (Context) ConstantExpr(Empty); + S = ConstantExpr::CreateEmpty( + Context, + static_cast<ConstantExpr::ResultStorageKind>( + Record[ASTStmtReader::NumExprFields]), + Empty); break; case EXPR_PREDEFINED: @@ -2465,7 +2560,7 @@ Stmt *ASTReader::ReadStmtFromStream(ModuleFile &F) { /*HasFoundDecl=*/Record[ASTStmtReader::NumExprFields + 1], /*HasTemplateKWAndArgsInfo=*/Record[ASTStmtReader::NumExprFields + 2], /*NumTemplateArgs=*/Record[ASTStmtReader::NumExprFields + 2] ? - Record[ASTStmtReader::NumExprFields + 5] : 0); + Record[ASTStmtReader::NumExprFields + 6] : 0); break; case EXPR_INTEGER_LITERAL: @@ -2529,55 +2624,12 @@ Stmt *ASTReader::ReadStmtFromStream(ModuleFile &F) { Context, /*NumArgs=*/Record[ASTStmtReader::NumExprFields], Empty); break; - case EXPR_MEMBER: { - // We load everything here and fully initialize it at creation. - // That way we can use MemberExpr::Create and don't have to duplicate its - // logic with a MemberExpr::CreateEmpty. - - assert(Record.getIdx() == 0); - NestedNameSpecifierLoc QualifierLoc; - if (Record.readInt()) { // HasQualifier. - QualifierLoc = Record.readNestedNameSpecifierLoc(); - } - - SourceLocation TemplateKWLoc; - TemplateArgumentListInfo ArgInfo; - bool HasTemplateKWAndArgsInfo = Record.readInt(); - if (HasTemplateKWAndArgsInfo) { - TemplateKWLoc = Record.readSourceLocation(); - unsigned NumTemplateArgs = Record.readInt(); - ArgInfo.setLAngleLoc(Record.readSourceLocation()); - ArgInfo.setRAngleLoc(Record.readSourceLocation()); - for (unsigned i = 0; i != NumTemplateArgs; ++i) - ArgInfo.addArgument(Record.readTemplateArgumentLoc()); - } - - bool HadMultipleCandidates = Record.readInt(); - - auto *FoundD = Record.readDeclAs<NamedDecl>(); - auto AS = (AccessSpecifier)Record.readInt(); - DeclAccessPair FoundDecl = DeclAccessPair::make(FoundD, AS); - - QualType T = Record.readType(); - auto VK = static_cast<ExprValueKind>(Record.readInt()); - auto OK = static_cast<ExprObjectKind>(Record.readInt()); - Expr *Base = ReadSubExpr(); - auto *MemberD = Record.readDeclAs<ValueDecl>(); - SourceLocation MemberLoc = Record.readSourceLocation(); - DeclarationNameInfo MemberNameInfo(MemberD->getDeclName(), MemberLoc); - bool IsArrow = Record.readInt(); - SourceLocation OperatorLoc = Record.readSourceLocation(); - - S = MemberExpr::Create(Context, Base, IsArrow, OperatorLoc, QualifierLoc, - TemplateKWLoc, MemberD, FoundDecl, MemberNameInfo, - HasTemplateKWAndArgsInfo ? &ArgInfo : nullptr, T, - VK, OK); - Record.readDeclarationNameLoc(cast<MemberExpr>(S)->MemberDNLoc, - MemberD->getDeclName()); - if (HadMultipleCandidates) - cast<MemberExpr>(S)->setHadMultipleCandidates(true); + case EXPR_MEMBER: + S = MemberExpr::CreateEmpty(Context, Record[ASTStmtReader::NumExprFields], + Record[ASTStmtReader::NumExprFields + 1], + Record[ASTStmtReader::NumExprFields + 2], + Record[ASTStmtReader::NumExprFields + 3]); break; - } case EXPR_BINARY_OPERATOR: S = new (Context) BinaryOperator(Empty); @@ -2647,6 +2699,10 @@ Stmt *ASTReader::ReadStmtFromStream(ModuleFile &F) { S = new (Context) VAArgExpr(Empty); break; + case EXPR_SOURCE_LOC: + S = new (Context) SourceLocExpr(Empty); + break; + case EXPR_ADDR_LABEL: S = new (Context) AddrLabelExpr(Empty); break; @@ -2676,7 +2732,9 @@ Stmt *ASTReader::ReadStmtFromStream(ModuleFile &F) { break; case EXPR_GENERIC_SELECTION: - S = new (Context) GenericSelectionExpr(Empty); + S = GenericSelectionExpr::CreateEmpty( + Context, + /*NumAssocs=*/Record[ASTStmtReader::NumExprFields]); break; case EXPR_OBJC_STRING_LITERAL: @@ -2803,7 +2861,7 @@ Stmt *ASTReader::ReadStmtFromStream(ModuleFile &F) { case STMT_CXX_TRY: S = CXXTryStmt::Create(Context, Empty, - /*NumHandlers=*/Record[ASTStmtReader::NumStmtFields]); + /*numHandlers=*/Record[ASTStmtReader::NumStmtFields]); break; case STMT_CXX_FOR_RANGE: diff --git a/lib/Serialization/ASTWriter.cpp b/lib/Serialization/ASTWriter.cpp index 37adcb70640d..10946f9b0d98 100644 --- a/lib/Serialization/ASTWriter.cpp +++ b/lib/Serialization/ASTWriter.cpp @@ -1,9 +1,8 @@ //===- ASTWriter.cpp - AST File Writer ------------------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -42,7 +41,6 @@ #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" @@ -66,6 +64,7 @@ #include "clang/Sema/Sema.h" #include "clang/Sema/Weak.h" #include "clang/Serialization/ASTReader.h" +#include "clang/Serialization/InMemoryModuleCache.h" #include "clang/Serialization/Module.h" #include "clang/Serialization/ModuleFileExtension.h" #include "clang/Serialization/SerializationDiagnostic.h" @@ -84,8 +83,8 @@ #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/StringMap.h" #include "llvm/ADT/StringRef.h" -#include "llvm/Bitcode/BitCodes.h" -#include "llvm/Bitcode/BitstreamWriter.h" +#include "llvm/Bitstream/BitCodes.h" +#include "llvm/Bitstream/BitstreamWriter.h" #include "llvm/Support/Casting.h" #include "llvm/Support/Compression.h" #include "llvm/Support/DJB.h" @@ -310,7 +309,7 @@ void ASTTypeWriter::VisitFunctionProtoType(const FunctionProtoType *T) { Record.push_back(T->isVariadic()); Record.push_back(T->hasTrailingReturn()); - Record.push_back(T->getTypeQuals().getAsOpaqueValue()); + Record.push_back(T->getMethodQuals().getAsOpaqueValue()); Record.push_back(static_cast<unsigned>(T->getRefQualifier())); addExceptionSpec(T, Record); @@ -323,7 +322,7 @@ void ASTTypeWriter::VisitFunctionProtoType(const FunctionProtoType *T) { Record.push_back(T->getExtParameterInfo(I).getOpaqueValue()); } - if (T->isVariadic() || T->hasTrailingReturn() || T->getTypeQuals() || + if (T->isVariadic() || T->hasTrailingReturn() || T->getMethodQuals() || T->getRefQualifier() || T->getExceptionSpecType() != EST_None || T->hasExtParameterInfos()) AbbrevToUse = 0; @@ -370,7 +369,8 @@ void ASTTypeWriter::VisitAutoType(const AutoType *T) { Record.AddTypeRef(T->getDeducedType()); Record.push_back((unsigned)T->getKeyword()); if (T->getDeducedType().isNull()) - Record.push_back(T->isDependentType()); + Record.push_back(T->containsUnexpandedParameterPack() ? 2 : + T->isDependentType() ? 1 : 0); Code = TYPE_AUTO; } @@ -517,6 +517,12 @@ void ASTTypeWriter::VisitParenType(const ParenType *T) { Code = TYPE_PAREN; } +void ASTTypeWriter::VisitMacroQualifiedType(const MacroQualifiedType *T) { + Record.AddTypeRef(T->getUnderlyingType()); + Record.AddIdentifierRef(T->getMacroIdentifier()); + Code = TYPE_MACRO_QUALIFIED; +} + void ASTTypeWriter::VisitElaboratedType(const ElaboratedType *T) { Record.push_back(T->getKeyword()); Record.AddNestedNameSpecifier(T->getQualifier()); @@ -803,6 +809,10 @@ void TypeLocWriter::VisitParenTypeLoc(ParenTypeLoc TL) { Record.AddSourceLocation(TL.getRParenLoc()); } +void TypeLocWriter::VisitMacroQualifiedTypeLoc(MacroQualifiedTypeLoc TL) { + Record.AddSourceLocation(TL.getExpansionLoc()); +} + void TypeLocWriter::VisitElaboratedTypeLoc(ElaboratedTypeLoc TL) { Record.AddSourceLocation(TL.getElaboratedKeywordLoc()); Record.AddNestedNameSpecifierLoc(TL.getQualifierLoc()); @@ -1220,6 +1230,7 @@ void ASTWriter::WriteBlockInfoBlock() { RECORD(TYPE_DEPENDENT_TEMPLATE_SPECIALIZATION); RECORD(TYPE_DEPENDENT_SIZED_ARRAY); RECORD(TYPE_PAREN); + RECORD(TYPE_MACRO_QUALIFIED); RECORD(TYPE_PACK_EXPANSION); RECORD(TYPE_ATTRIBUTED); RECORD(TYPE_SUBST_TEMPLATE_TYPE_PARM_PACK); @@ -1267,7 +1278,6 @@ void ASTWriter::WriteBlockInfoBlock() { RECORD(DECL_CXX_RECORD); RECORD(DECL_CXX_METHOD); RECORD(DECL_CXX_CONSTRUCTOR); - RECORD(DECL_CXX_INHERITED_CONSTRUCTOR); RECORD(DECL_CXX_DESTRUCTOR); RECORD(DECL_CXX_CONVERSION); RECORD(DECL_ACCESS_SPEC); @@ -1283,6 +1293,7 @@ void ASTWriter::WriteBlockInfoBlock() { RECORD(DECL_TEMPLATE_TYPE_PARM); RECORD(DECL_NON_TYPE_TEMPLATE_PARM); RECORD(DECL_TEMPLATE_TEMPLATE_PARM); + RECORD(DECL_CONCEPT); RECORD(DECL_TYPE_ALIAS_TEMPLATE); RECORD(DECL_STATIC_ASSERT); RECORD(DECL_CXX_BASE_SPECIFIERS); @@ -1299,6 +1310,7 @@ void ASTWriter::WriteBlockInfoBlock() { RECORD(DECL_PRAGMA_COMMENT); RECORD(DECL_PRAGMA_DETECT_MISMATCH); RECORD(DECL_OMP_DECLARE_REDUCTION); + RECORD(DECL_OMP_ALLOCATE); // Statements and Exprs can occur in the Decls and Types block. AddStmtsExprs(Stream, Record); @@ -1435,7 +1447,7 @@ ASTFileSignature ASTWriter::writeUnhashedControlBlock(Preprocessor &PP, Stream.EmitRecord(DIAGNOSTIC_OPTIONS, Record); // Write out the diagnostic/pragma mappings. - WritePragmaDiagnosticMappings(Diags, /* IsModule = */ WritingModule); + WritePragmaDiagnosticMappings(Diags, /* isModule = */ WritingModule); // Leave the options block. Stream.ExitBlock(); @@ -4278,14 +4290,32 @@ void ASTWriter::WriteOpenCLExtensionTypes(Sema &SemaRef) { if (!SemaRef.Context.getLangOpts().OpenCL) return; + // Sort the elements of the map OpenCLTypeExtMap by TypeIDs, + // without copying them. + const llvm::DenseMap<const Type *, std::set<std::string>> &OpenCLTypeExtMap = + SemaRef.OpenCLTypeExtMap; + using ElementTy = std::pair<TypeID, const std::set<std::string> *>; + llvm::SmallVector<ElementTy, 8> StableOpenCLTypeExtMap; + StableOpenCLTypeExtMap.reserve(OpenCLTypeExtMap.size()); + + for (const auto &I : OpenCLTypeExtMap) + StableOpenCLTypeExtMap.emplace_back( + getTypeID(I.first->getCanonicalTypeInternal()), &I.second); + + auto CompareByTypeID = [](const ElementTy &E1, const ElementTy &E2) -> bool { + return E1.first < E2.first; + }; + llvm::sort(StableOpenCLTypeExtMap, CompareByTypeID); + RecordData Record; - for (const auto &I : SemaRef.OpenCLTypeExtMap) { - Record.push_back( - static_cast<unsigned>(getTypeID(I.first->getCanonicalTypeInternal()))); - Record.push_back(I.second.size()); - for (auto Ext : I.second) + for (const ElementTy &E : StableOpenCLTypeExtMap) { + Record.push_back(E.first); // TypeID + const std::set<std::string> *ExtSet = E.second; + Record.push_back(static_cast<unsigned>(ExtSet->size())); + for (const std::string &Ext : *ExtSet) AddString(Ext, Record); } + Stream.EmitRecord(OPENCL_EXTENSION_TYPES, Record); } @@ -4293,13 +4323,31 @@ void ASTWriter::WriteOpenCLExtensionDecls(Sema &SemaRef) { if (!SemaRef.Context.getLangOpts().OpenCL) return; + // Sort the elements of the map OpenCLDeclExtMap by DeclIDs, + // without copying them. + const llvm::DenseMap<const Decl *, std::set<std::string>> &OpenCLDeclExtMap = + SemaRef.OpenCLDeclExtMap; + using ElementTy = std::pair<DeclID, const std::set<std::string> *>; + llvm::SmallVector<ElementTy, 8> StableOpenCLDeclExtMap; + StableOpenCLDeclExtMap.reserve(OpenCLDeclExtMap.size()); + + for (const auto &I : OpenCLDeclExtMap) + StableOpenCLDeclExtMap.emplace_back(getDeclID(I.first), &I.second); + + auto CompareByDeclID = [](const ElementTy &E1, const ElementTy &E2) -> bool { + return E1.first < E2.first; + }; + llvm::sort(StableOpenCLDeclExtMap, CompareByDeclID); + RecordData Record; - for (const auto &I : SemaRef.OpenCLDeclExtMap) { - Record.push_back(getDeclID(I.first)); - Record.push_back(static_cast<unsigned>(I.second.size())); - for (auto Ext : I.second) + for (const ElementTy &E : StableOpenCLDeclExtMap) { + Record.push_back(E.first); // DeclID + const std::set<std::string> *ExtSet = E.second; + Record.push_back(static_cast<unsigned>(ExtSet->size())); + for (const std::string &Ext : *ExtSet) AddString(Ext, Record); } + Stream.EmitRecord(OPENCL_EXTENSION_DECLS, Record); } @@ -4568,10 +4616,11 @@ void ASTWriter::SetSelectorOffset(Selector Sel, uint32_t Offset) { } ASTWriter::ASTWriter(llvm::BitstreamWriter &Stream, - SmallVectorImpl<char> &Buffer, MemoryBufferCache &PCMCache, + SmallVectorImpl<char> &Buffer, + InMemoryModuleCache &ModuleCache, ArrayRef<std::shared_ptr<ModuleFileExtension>> Extensions, bool IncludeTimestamps) - : Stream(Stream), Buffer(Buffer), PCMCache(PCMCache), + : Stream(Stream), Buffer(Buffer), ModuleCache(ModuleCache), IncludeTimestamps(IncludeTimestamps) { for (const auto &Ext : Extensions) { if (auto Writer = Ext->createExtensionWriter(*this)) @@ -4595,7 +4644,8 @@ time_t ASTWriter::getTimestampForOutput(const FileEntry *E) const { ASTFileSignature ASTWriter::WriteAST(Sema &SemaRef, const std::string &OutputFile, Module *WritingModule, StringRef isysroot, - bool hasErrors) { + bool hasErrors, + bool ShouldCacheASTInMemory) { WritingAST = true; ASTHasCompilerErrors = hasErrors; @@ -4619,11 +4669,11 @@ ASTFileSignature ASTWriter::WriteAST(Sema &SemaRef, this->BaseDirectory.clear(); WritingAST = false; - if (SemaRef.Context.getLangOpts().ImplicitModules && WritingModule) { + if (ShouldCacheASTInMemory) { // Construct MemoryBuffer and update buffer manager. - PCMCache.addBuffer(OutputFile, - llvm::MemoryBuffer::getMemBufferCopy( - StringRef(Buffer.begin(), Buffer.size()))); + ModuleCache.addBuiltPCM(OutputFile, + llvm::MemoryBuffer::getMemBufferCopy( + StringRef(Buffer.begin(), Buffer.size()))); } return Signature; } @@ -5288,6 +5338,14 @@ void ASTWriter::WriteDeclUpdatesBlocks(RecordDataImpl &OffsetsRecord) { D->getAttr<OMPThreadPrivateDeclAttr>()->getRange()); break; + case UPD_DECL_MARKED_OPENMP_ALLOCATE: { + auto *A = D->getAttr<OMPAllocateDeclAttr>(); + Record.push_back(A->getAllocatorType()); + Record.AddStmt(A->getAllocator()); + Record.AddSourceRange(A->getRange()); + break; + } + case UPD_DECL_MARKED_OPENMP_DECLARETARGET: Record.push_back(D->getAttr<OMPDeclareTargetDeclAttr>()->getMapType()); Record.AddSourceRange( @@ -5342,6 +5400,61 @@ void ASTRecordWriter::AddAPFloat(const llvm::APFloat &Value) { AddAPInt(Value.bitcastToAPInt()); } +static void WriteFixedPointSemantics(ASTRecordWriter &Record, + FixedPointSemantics FPSema) { + Record.push_back(FPSema.getWidth()); + Record.push_back(FPSema.getScale()); + Record.push_back(FPSema.isSigned() | FPSema.isSaturated() << 1 | + FPSema.hasUnsignedPadding() << 2); +} + +void ASTRecordWriter::AddAPValue(const APValue &Value) { + APValue::ValueKind Kind = Value.getKind(); + push_back(static_cast<uint64_t>(Kind)); + switch (Kind) { + case APValue::None: + case APValue::Indeterminate: + return; + case APValue::Int: + AddAPSInt(Value.getInt()); + return; + case APValue::Float: + push_back(static_cast<uint64_t>( + llvm::APFloatBase::SemanticsToEnum(Value.getFloat().getSemantics()))); + AddAPFloat(Value.getFloat()); + return; + case APValue::FixedPoint: { + WriteFixedPointSemantics(*this, Value.getFixedPoint().getSemantics()); + AddAPSInt(Value.getFixedPoint().getValue()); + return; + } + case APValue::ComplexInt: { + AddAPSInt(Value.getComplexIntReal()); + AddAPSInt(Value.getComplexIntImag()); + return; + } + case APValue::ComplexFloat: { + push_back(static_cast<uint64_t>(llvm::APFloatBase::SemanticsToEnum( + Value.getComplexFloatReal().getSemantics()))); + AddAPFloat(Value.getComplexFloatReal()); + push_back(static_cast<uint64_t>(llvm::APFloatBase::SemanticsToEnum( + Value.getComplexFloatImag().getSemantics()))); + AddAPFloat(Value.getComplexFloatImag()); + return; + } + case APValue::LValue: + case APValue::Vector: + case APValue::Array: + case APValue::Struct: + case APValue::Union: + case APValue::MemberPointer: + case APValue::AddrLabelDiff: + // TODO : Handle all these APValue::ValueKind. + return; + } + llvm_unreachable("Invalid APValue::ValueKind"); +} + void ASTWriter::AddIdentifierRef(const IdentifierInfo *II, RecordDataImpl &Record) { Record.push_back(getIdentifierRef(II)); } @@ -5595,7 +5708,7 @@ void ASTWriter::associateDeclWithFile(const Decl *D, DeclID ID) { } LocDeclIDsTy::iterator I = - std::upper_bound(Decls.begin(), Decls.end(), LocDecl, llvm::less_first()); + llvm::upper_bound(Decls, LocDecl, llvm::less_first()); Decls.insert(I, LocDecl); } @@ -5820,6 +5933,12 @@ void ASTRecordWriter::AddTemplateName(TemplateName Name) { break; } + case TemplateName::AssumedTemplate: { + AssumedTemplateStorage *ADLT = Name.getAsAssumedTemplateName(); + AddDeclarationName(ADLT->getDeclName()); + break; + } + case TemplateName::QualifiedTemplate: { QualifiedTemplateName *QualT = Name.getAsQualifiedTemplateName(); AddNestedNameSpecifier(QualT->getQualifier()); @@ -6405,6 +6524,15 @@ void ASTWriter::DeclarationMarkedOpenMPThreadPrivate(const Decl *D) { DeclUpdates[D].push_back(DeclUpdate(UPD_DECL_MARKED_OPENMP_THREADPRIVATE)); } +void ASTWriter::DeclarationMarkedOpenMPAllocate(const Decl *D, const Attr *A) { + if (Chain && Chain->isProcessingUpdateRecords()) return; + assert(!WritingAST && "Already writing the AST!"); + if (!D->isFromASTFile()) + return; + + DeclUpdates[D].push_back(DeclUpdate(UPD_DECL_MARKED_OPENMP_ALLOCATE, A)); +} + void ASTWriter::DeclarationMarkedOpenMPDeclareTarget(const Decl *D, const Attr *Attr) { if (Chain && Chain->isProcessingUpdateRecords()) return; @@ -6519,6 +6647,11 @@ void OMPClauseWriter::VisitOMPSimdlenClause(OMPSimdlenClause *C) { Record.AddSourceLocation(C->getLParenLoc()); } +void OMPClauseWriter::VisitOMPAllocatorClause(OMPAllocatorClause *C) { + Record.AddStmt(C->getAllocator()); + Record.AddSourceLocation(C->getLParenLoc()); +} + void OMPClauseWriter::VisitOMPCollapseClause(OMPCollapseClause *C) { Record.AddStmt(C->getNumForLoops()); Record.AddSourceLocation(C->getLParenLoc()); @@ -6786,11 +6919,15 @@ void OMPClauseWriter::VisitOMPMapClause(OMPMapClause *C) { Record.push_back(C->getMapTypeModifier(I)); Record.AddSourceLocation(C->getMapTypeModifierLoc(I)); } + Record.AddNestedNameSpecifierLoc(C->getMapperQualifierLoc()); + Record.AddDeclarationNameInfo(C->getMapperIdInfo()); Record.push_back(C->getMapType()); Record.AddSourceLocation(C->getMapLoc()); Record.AddSourceLocation(C->getColonLoc()); for (auto *E : C->varlists()) Record.AddStmt(E); + for (auto *E : C->mapperlists()) + Record.AddStmt(E); for (auto *D : C->all_decls()) Record.AddDeclRef(D); for (auto N : C->all_num_lists()) @@ -6803,6 +6940,15 @@ void OMPClauseWriter::VisitOMPMapClause(OMPMapClause *C) { } } +void OMPClauseWriter::VisitOMPAllocateClause(OMPAllocateClause *C) { + Record.push_back(C->varlist_size()); + Record.AddSourceLocation(C->getLParenLoc()); + Record.AddSourceLocation(C->getColonLoc()); + Record.AddStmt(C->getAllocator()); + for (auto *VE : C->varlists()) + Record.AddStmt(VE); +} + void OMPClauseWriter::VisitOMPNumTeamsClause(OMPNumTeamsClause *C) { VisitOMPClauseWithPreInit(C); Record.AddStmt(C->getNumTeams()); @@ -6858,8 +7004,12 @@ void OMPClauseWriter::VisitOMPToClause(OMPToClause *C) { Record.push_back(C->getTotalComponentListNum()); Record.push_back(C->getTotalComponentsNum()); Record.AddSourceLocation(C->getLParenLoc()); + Record.AddNestedNameSpecifierLoc(C->getMapperQualifierLoc()); + Record.AddDeclarationNameInfo(C->getMapperIdInfo()); for (auto *E : C->varlists()) Record.AddStmt(E); + for (auto *E : C->mapperlists()) + Record.AddStmt(E); for (auto *D : C->all_decls()) Record.AddDeclRef(D); for (auto N : C->all_num_lists()) @@ -6878,8 +7028,12 @@ void OMPClauseWriter::VisitOMPFromClause(OMPFromClause *C) { Record.push_back(C->getTotalComponentListNum()); Record.push_back(C->getTotalComponentsNum()); Record.AddSourceLocation(C->getLParenLoc()); + Record.AddNestedNameSpecifierLoc(C->getMapperQualifierLoc()); + Record.AddDeclarationNameInfo(C->getMapperIdInfo()); for (auto *E : C->varlists()) Record.AddStmt(E); + for (auto *E : C->mapperlists()) + Record.AddStmt(E); for (auto *D : C->all_decls()) Record.AddDeclRef(D); for (auto N : C->all_num_lists()) diff --git a/lib/Serialization/ASTWriterDecl.cpp b/lib/Serialization/ASTWriterDecl.cpp index 002b43f81121..b71315505de9 100644 --- a/lib/Serialization/ASTWriterDecl.cpp +++ b/lib/Serialization/ASTWriterDecl.cpp @@ -1,9 +1,8 @@ //===--- ASTWriterDecl.cpp - Declaration Serialization --------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -22,7 +21,7 @@ #include "clang/Basic/SourceManager.h" #include "clang/Serialization/ASTReader.h" #include "clang/Serialization/ASTWriter.h" -#include "llvm/Bitcode/BitstreamWriter.h" +#include "llvm/Bitstream/BitstreamWriter.h" #include "llvm/Support/ErrorHandling.h" using namespace clang; using namespace serialization; @@ -103,6 +102,7 @@ namespace clang { void VisitBindingDecl(BindingDecl *D); void VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D); void VisitTemplateDecl(TemplateDecl *D); + void VisitConceptDecl(ConceptDecl *D); void VisitRedeclarableTemplateDecl(RedeclarableTemplateDecl *D); void VisitClassTemplateDecl(ClassTemplateDecl *D); void VisitVarTemplateDecl(VarTemplateDecl *D); @@ -145,8 +145,10 @@ namespace clang { void VisitObjCPropertyDecl(ObjCPropertyDecl *D); void VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *D); void VisitOMPThreadPrivateDecl(OMPThreadPrivateDecl *D); + void VisitOMPAllocateDecl(OMPAllocateDecl *D); void VisitOMPRequiresDecl(OMPRequiresDecl *D); void VisitOMPDeclareReductionDecl(OMPDeclareReductionDecl *D); + void VisitOMPDeclareMapperDecl(OMPDeclareMapperDecl *D); void VisitOMPCapturedExprDecl(OMPCapturedExprDecl *D); /// Add an Objective-C type parameter list to the given record. @@ -474,6 +476,9 @@ void ASTDeclWriter::VisitRecordDecl(RecordDecl *D) { Record.push_back(D->isNonTrivialToPrimitiveDefaultInitialize()); Record.push_back(D->isNonTrivialToPrimitiveCopy()); Record.push_back(D->isNonTrivialToPrimitiveDestroy()); + Record.push_back(D->hasNonTrivialToPrimitiveDefaultInitializeCUnion()); + Record.push_back(D->hasNonTrivialToPrimitiveDestructCUnion()); + Record.push_back(D->hasNonTrivialToPrimitiveCopyCUnion()); Record.push_back(D->isParamDestroyedInCallee()); Record.push_back(D->getArgPassingRestrictions()); @@ -534,7 +539,6 @@ void ASTDeclWriter::VisitFunctionDecl(FunctionDecl *D) { Record.push_back(static_cast<int>(D->getStorageClass())); // FIXME: stable encoding Record.push_back(D->isInlineSpecified()); Record.push_back(D->isInlined()); - Record.push_back(D->isExplicitSpecified()); Record.push_back(D->isVirtualAsWritten()); Record.push_back(D->isPure()); Record.push_back(D->hasInheritedPrototype()); @@ -545,7 +549,7 @@ void ASTDeclWriter::VisitFunctionDecl(FunctionDecl *D) { Record.push_back(D->isDefaulted()); Record.push_back(D->isExplicitlyDefaulted()); Record.push_back(D->hasImplicitReturnZero()); - Record.push_back(D->isConstexpr()); + Record.push_back(D->getConstexprKind()); Record.push_back(D->usesSEHTry()); Record.push_back(D->hasSkippedBody()); Record.push_back(D->isMultiVersion()); @@ -595,6 +599,16 @@ void ASTDeclWriter::VisitFunctionDecl(FunctionDecl *D) { Record.AddSourceLocation(FTSInfo->getPointOfInstantiation()); + if (MemberSpecializationInfo *MemberInfo = + FTSInfo->getMemberSpecializationInfo()) { + Record.push_back(1); + Record.AddDeclRef(MemberInfo->getInstantiatedFrom()); + Record.push_back(MemberInfo->getTemplateSpecializationKind()); + Record.AddSourceLocation(MemberInfo->getPointOfInstantiation()); + } else { + Record.push_back(0); + } + if (D->isCanonicalDecl()) { // Write the template that contains the specializations set. We will // add a FunctionTemplateSpecializationInfo to it when reading. @@ -627,7 +641,18 @@ void ASTDeclWriter::VisitFunctionDecl(FunctionDecl *D) { Code = serialization::DECL_FUNCTION; } +static void addExplicitSpecifier(ExplicitSpecifier ES, + ASTRecordWriter &Record) { + uint64_t Kind = static_cast<uint64_t>(ES.getKind()); + Kind = Kind << 1 | static_cast<bool>(ES.getExpr()); + Record.push_back(Kind); + if (ES.getExpr()) { + Record.AddStmt(ES.getExpr()); + } +} + void ASTDeclWriter::VisitCXXDeductionGuideDecl(CXXDeductionGuideDecl *D) { + addExplicitSpecifier(D->getExplicitSpecifier(), Record); VisitFunctionDecl(D); Record.push_back(D->isCopyDeductionCandidate()); Code = serialization::DECL_CXX_DEDUCTION_GUIDE; @@ -1110,6 +1135,7 @@ void ASTDeclWriter::VisitBlockDecl(BlockDecl *D) { Record.push_back(D->blockMissingReturnType()); Record.push_back(D->isConversionFromLambda()); Record.push_back(D->doesNotEscape()); + Record.push_back(D->canAvoidCopyToHeap()); Record.push_back(D->capturesCXXThis()); Record.push_back(D->getNumCaptures()); for (const auto &capture : D->captures()) { @@ -1319,19 +1345,15 @@ void ASTDeclWriter::VisitCXXMethodDecl(CXXMethodDecl *D) { } void ASTDeclWriter::VisitCXXConstructorDecl(CXXConstructorDecl *D) { + Record.push_back(D->getTraillingAllocKind()); + addExplicitSpecifier(D->getExplicitSpecifier(), Record); if (auto Inherited = D->getInheritedConstructor()) { Record.AddDeclRef(Inherited.getShadowDecl()); Record.AddDeclRef(Inherited.getConstructor()); - Code = serialization::DECL_CXX_INHERITED_CONSTRUCTOR; - } else { - Code = serialization::DECL_CXX_CONSTRUCTOR; } VisitCXXMethodDecl(D); - - Code = D->isInheritingConstructor() - ? serialization::DECL_CXX_INHERITED_CONSTRUCTOR - : serialization::DECL_CXX_CONSTRUCTOR; + Code = serialization::DECL_CXX_CONSTRUCTOR; } void ASTDeclWriter::VisitCXXDestructorDecl(CXXDestructorDecl *D) { @@ -1345,6 +1367,7 @@ void ASTDeclWriter::VisitCXXDestructorDecl(CXXDestructorDecl *D) { } void ASTDeclWriter::VisitCXXConversionDecl(CXXConversionDecl *D) { + addExplicitSpecifier(D->getExplicitSpecifier(), Record); VisitCXXMethodDecl(D); Code = serialization::DECL_CXX_CONVERSION; } @@ -1413,6 +1436,12 @@ void ASTDeclWriter::VisitTemplateDecl(TemplateDecl *D) { Record.AddTemplateParameterList(D->getTemplateParameters()); } +void ASTDeclWriter::VisitConceptDecl(ConceptDecl *D) { + VisitTemplateDecl(D); + Record.AddStmt(D->getConstraintExpr()); + Code = serialization::DECL_CONCEPT; +} + void ASTDeclWriter::VisitRedeclarableTemplateDecl(RedeclarableTemplateDecl *D) { VisitRedeclarable(D); @@ -1553,6 +1582,9 @@ void ASTDeclWriter::VisitClassScopeFunctionSpecializationDecl( ClassScopeFunctionSpecializationDecl *D) { VisitDecl(D); Record.AddDeclRef(D->getSpecialization()); + Record.push_back(D->hasExplicitTemplateArgs()); + if (D->hasExplicitTemplateArgs()) + Record.AddASTTemplateArgumentListInfo(D->getTemplateArgsAsWritten()); Code = serialization::DECL_CLASS_SCOPE_FUNCTION_SPECIALIZATION; } @@ -1743,10 +1775,22 @@ void ASTDeclWriter::VisitOMPThreadPrivateDecl(OMPThreadPrivateDecl *D) { Code = serialization::DECL_OMP_THREADPRIVATE; } +void ASTDeclWriter::VisitOMPAllocateDecl(OMPAllocateDecl *D) { + Record.push_back(D->varlist_size()); + Record.push_back(D->clauselist_size()); + VisitDecl(D); + for (auto *I : D->varlists()) + Record.AddStmt(I); + OMPClauseWriter ClauseWriter(Record); + for (OMPClause *C : D->clauselists()) + ClauseWriter.writeClause(C); + Code = serialization::DECL_OMP_ALLOCATE; +} + void ASTDeclWriter::VisitOMPRequiresDecl(OMPRequiresDecl *D) { Record.push_back(D->clauselist_size()); VisitDecl(D); - OMPClauseWriter ClauseWriter(Record); + OMPClauseWriter ClauseWriter(Record); for (OMPClause *C : D->clauselists()) ClauseWriter.writeClause(C); Code = serialization::DECL_OMP_REQUIRES; @@ -1766,6 +1810,19 @@ void ASTDeclWriter::VisitOMPDeclareReductionDecl(OMPDeclareReductionDecl *D) { Code = serialization::DECL_OMP_DECLARE_REDUCTION; } +void ASTDeclWriter::VisitOMPDeclareMapperDecl(OMPDeclareMapperDecl *D) { + Record.push_back(D->clauselist_size()); + VisitValueDecl(D); + Record.AddSourceLocation(D->getBeginLoc()); + Record.AddStmt(D->getMapperVarRef()); + Record.AddDeclarationName(D->getVarName()); + Record.AddDeclRef(D->getPrevDeclInScope()); + OMPClauseWriter ClauseWriter(Record); + for (OMPClause *C : D->clauselists()) + ClauseWriter.writeClause(C); + Code = serialization::DECL_OMP_DECLARE_MAPPER; +} + void ASTDeclWriter::VisitOMPCapturedExprDecl(OMPCapturedExprDecl *D) { VisitVarDecl(D); Code = serialization::DECL_OMP_CAPTUREDEXPR; @@ -1945,6 +2002,12 @@ void ASTWriter::WriteDeclAbbrevs() { Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // isNonTrivialToPrimitiveDestroy Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); + // hasNonTrivialToPrimitiveDefaultInitializeCUnion + Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); + // hasNonTrivialToPrimitiveDestructCUnion + Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); + // hasNonTrivialToPrimitiveCopyCUnion + Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // isParamDestroyedInCallee Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // getArgPassingRestrictions @@ -2116,7 +2179,6 @@ void ASTWriter::WriteDeclAbbrevs() { Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 3)); // StorageClass Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // Inline Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // InlineSpecified - Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // ExplicitSpecified Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // VirtualAsWritten Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // Pure Abv->Add(BitCodeAbbrevOp(0)); // HasInheritedProto @@ -2152,7 +2214,8 @@ void ASTWriter::WriteDeclAbbrevs() { Abv = std::make_shared<BitCodeAbbrev>(); Abv->Add(BitCodeAbbrevOp(serialization::EXPR_DECL_REF)); //Stmt - //Expr + Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // IsOMPStructuredBlock + // Expr Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Type Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); //TypeDependent Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); //ValueDependent @@ -2165,8 +2228,8 @@ void ASTWriter::WriteDeclAbbrevs() { Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); //GetDeclFound Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); //ExplicitTemplateArgs Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); //HadMultipleCandidates - Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, - 1)); // RefersToEnclosingVariableOrCapture + Abv->Add(BitCodeAbbrevOp(0)); // RefersToEnclosingVariableOrCapture + Abv->Add(BitCodeAbbrevOp(0)); // NonOdrUseReason Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // DeclRef Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Location DeclRefExprAbbrev = Stream.EmitAbbrev(std::move(Abv)); @@ -2175,7 +2238,8 @@ void ASTWriter::WriteDeclAbbrevs() { Abv = std::make_shared<BitCodeAbbrev>(); Abv->Add(BitCodeAbbrevOp(serialization::EXPR_INTEGER_LITERAL)); //Stmt - //Expr + Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // IsOMPStructuredBlock + // Expr Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Type Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); //TypeDependent Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); //ValueDependent @@ -2193,7 +2257,8 @@ void ASTWriter::WriteDeclAbbrevs() { Abv = std::make_shared<BitCodeAbbrev>(); Abv->Add(BitCodeAbbrevOp(serialization::EXPR_CHARACTER_LITERAL)); //Stmt - //Expr + Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // IsOMPStructuredBlock + // Expr Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Type Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); //TypeDependent Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); //ValueDependent @@ -2211,6 +2276,7 @@ void ASTWriter::WriteDeclAbbrevs() { Abv = std::make_shared<BitCodeAbbrev>(); Abv->Add(BitCodeAbbrevOp(serialization::EXPR_IMPLICIT_CAST)); // Stmt + Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // IsOMPStructuredBlock // Expr Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Type Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); //TypeDependent @@ -2259,7 +2325,7 @@ static bool isRequiredDecl(const Decl *D, ASTContext &Context, if (isa<FileScopeAsmDecl>(D) || isa<ObjCImplDecl>(D)) return true; - if (WritingModule && (isa<VarDecl>(D) || isa<ImportDecl>(D))) { + if (WritingModule && isPartOfPerModuleInitializer(D)) { // These declarations are part of the module initializer, and are emitted // if and when the module is imported, rather than being emitted eagerly. return false; diff --git a/lib/Serialization/ASTWriterStmt.cpp b/lib/Serialization/ASTWriterStmt.cpp index 6f8b86edcdfc..4fbcbaabe74b 100644 --- a/lib/Serialization/ASTWriterStmt.cpp +++ b/lib/Serialization/ASTWriterStmt.cpp @@ -1,9 +1,8 @@ //===--- ASTWriterStmt.cpp - Statement and Expression Serialization -------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// /// @@ -19,7 +18,7 @@ #include "clang/AST/DeclTemplate.h" #include "clang/AST/StmtVisitor.h" #include "clang/Lex/Token.h" -#include "llvm/Bitcode/BitstreamWriter.h" +#include "llvm/Bitstream/BitstreamWriter.h" using namespace clang; //===----------------------------------------------------------------------===// @@ -68,6 +67,7 @@ void ASTStmtWriter::AddTemplateKWAndArgsInfo( } void ASTStmtWriter::VisitStmt(Stmt *S) { + Record.push_back(S->StmtBits.IsOMPStructuredBlock); } void ASTStmtWriter::VisitNullStmt(NullStmt *S) { @@ -283,6 +283,7 @@ void ASTStmtWriter::VisitAsmStmt(AsmStmt *S) { void ASTStmtWriter::VisitGCCAsmStmt(GCCAsmStmt *S) { VisitAsmStmt(S); + Record.push_back(S->getNumLabels()); Record.AddSourceLocation(S->getRParenLoc()); Record.AddStmt(S->getAsmString()); @@ -304,6 +305,9 @@ void ASTStmtWriter::VisitGCCAsmStmt(GCCAsmStmt *S) { for (unsigned I = 0, N = S->getNumClobbers(); I != N; ++I) Record.AddStmt(S->getClobberStringLiteral(I)); + // Labels + for (auto *E : S->labels()) Record.AddStmt(E); + Code = serialization::STMT_GCCASM; } @@ -428,6 +432,16 @@ void ASTStmtWriter::VisitExpr(Expr *E) { void ASTStmtWriter::VisitConstantExpr(ConstantExpr *E) { VisitExpr(E); + Record.push_back(static_cast<uint64_t>(E->ConstantExprBits.ResultKind)); + switch (E->ConstantExprBits.ResultKind) { + case ConstantExpr::RSK_Int64: + Record.push_back(E->Int64Result()); + Record.push_back(E->ConstantExprBits.IsUnsigned | + E->ConstantExprBits.BitWidth << 1); + break; + case ConstantExpr::RSK_APValue: + Record.AddAPValue(E->APValueResult()); + } Record.AddStmt(E->getSubExpr()); Code = serialization::EXPR_CONSTANT; } @@ -452,6 +466,7 @@ void ASTStmtWriter::VisitDeclRefExpr(DeclRefExpr *E) { Record.push_back(E->hasTemplateKWAndArgsInfo()); Record.push_back(E->hadMultipleCandidates()); Record.push_back(E->refersToEnclosingVariableOrCapture()); + Record.push_back(E->isNonOdrUse()); if (E->hasTemplateKWAndArgsInfo()) { unsigned NumTemplateArgs = E->getNumTemplateArgs(); @@ -462,7 +477,8 @@ void ASTStmtWriter::VisitDeclRefExpr(DeclRefExpr *E) { if ((!E->hasTemplateKWAndArgsInfo()) && (!E->hasQualifier()) && (E->getDecl() == E->getFoundDecl()) && - nk == DeclarationName::Identifier) { + nk == DeclarationName::Identifier && + !E->refersToEnclosingVariableOrCapture() && !E->isNonOdrUse()) { AbbrevToUse = Writer.getDeclRefExprAbbrev(); } @@ -656,39 +672,46 @@ void ASTStmtWriter::VisitCallExpr(CallExpr *E) { } void ASTStmtWriter::VisitMemberExpr(MemberExpr *E) { - // Don't call VisitExpr, we'll write everything here. - - Record.push_back(E->hasQualifier()); - if (E->hasQualifier()) - Record.AddNestedNameSpecifierLoc(E->getQualifierLoc()); - - Record.push_back(E->hasTemplateKWAndArgsInfo()); - if (E->hasTemplateKWAndArgsInfo()) { - Record.AddSourceLocation(E->getTemplateKeywordLoc()); - unsigned NumTemplateArgs = E->getNumTemplateArgs(); - Record.push_back(NumTemplateArgs); - Record.AddSourceLocation(E->getLAngleLoc()); - Record.AddSourceLocation(E->getRAngleLoc()); - for (unsigned i=0; i != NumTemplateArgs; ++i) - Record.AddTemplateArgumentLoc(E->getTemplateArgs()[i]); - } + VisitExpr(E); - Record.push_back(E->hadMultipleCandidates()); + bool HasQualifier = E->hasQualifier(); + bool HasFoundDecl = + E->hasQualifierOrFoundDecl() && + (E->getFoundDecl().getDecl() != E->getMemberDecl() || + E->getFoundDecl().getAccess() != E->getMemberDecl()->getAccess()); + bool HasTemplateInfo = E->hasTemplateKWAndArgsInfo(); + unsigned NumTemplateArgs = E->getNumTemplateArgs(); - DeclAccessPair FoundDecl = E->getFoundDecl(); - Record.AddDeclRef(FoundDecl.getDecl()); - Record.push_back(FoundDecl.getAccess()); + // Write these first for easy access when deserializing, as they affect the + // size of the MemberExpr. + Record.push_back(HasQualifier); + Record.push_back(HasFoundDecl); + Record.push_back(HasTemplateInfo); + Record.push_back(NumTemplateArgs); - Record.AddTypeRef(E->getType()); - Record.push_back(E->getValueKind()); - Record.push_back(E->getObjectKind()); Record.AddStmt(E->getBase()); Record.AddDeclRef(E->getMemberDecl()); + Record.AddDeclarationNameLoc(E->MemberDNLoc, + E->getMemberDecl()->getDeclName()); Record.AddSourceLocation(E->getMemberLoc()); Record.push_back(E->isArrow()); + Record.push_back(E->hadMultipleCandidates()); + Record.push_back(E->isNonOdrUse()); Record.AddSourceLocation(E->getOperatorLoc()); - Record.AddDeclarationNameLoc(E->MemberDNLoc, - E->getMemberDecl()->getDeclName()); + + if (HasFoundDecl) { + DeclAccessPair FoundDecl = E->getFoundDecl(); + Record.AddDeclRef(FoundDecl.getDecl()); + Record.push_back(FoundDecl.getAccess()); + } + + if (HasQualifier) + Record.AddNestedNameSpecifierLoc(E->getQualifierLoc()); + + if (HasTemplateInfo) + AddTemplateKWAndArgsInfo(*E->getTrailingObjects<ASTTemplateKWAndArgsInfo>(), + E->getTrailingObjects<TemplateArgumentLoc>()); + Code = serialization::EXPR_MEMBER; } @@ -909,6 +932,15 @@ void ASTStmtWriter::VisitVAArgExpr(VAArgExpr *E) { Code = serialization::EXPR_VA_ARG; } +void ASTStmtWriter::VisitSourceLocExpr(SourceLocExpr *E) { + VisitExpr(E); + Record.AddDeclRef(cast_or_null<Decl>(E->getParentContext())); + Record.AddSourceLocation(E->getBeginLoc()); + Record.AddSourceLocation(E->getEndLoc()); + Record.push_back(E->getIdentKind()); + Code = serialization::EXPR_SOURCE_LOC; +} + void ASTStmtWriter::VisitAddrLabelExpr(AddrLabelExpr *E) { VisitExpr(E); Record.AddSourceLocation(E->getAmpAmpLoc()); @@ -969,18 +1001,24 @@ void ASTStmtWriter::VisitBlockExpr(BlockExpr *E) { void ASTStmtWriter::VisitGenericSelectionExpr(GenericSelectionExpr *E) { VisitExpr(E); - Record.push_back(E->getNumAssocs()); - - Record.AddStmt(E->getControllingExpr()); - for (unsigned I = 0, N = E->getNumAssocs(); I != N; ++I) { - Record.AddTypeSourceInfo(E->getAssocTypeSourceInfo(I)); - Record.AddStmt(E->getAssocExpr(I)); - } - Record.push_back(E->isResultDependent() ? -1U : E->getResultIndex()); + Record.push_back(E->getNumAssocs()); + Record.push_back(E->ResultIndex); Record.AddSourceLocation(E->getGenericLoc()); Record.AddSourceLocation(E->getDefaultLoc()); Record.AddSourceLocation(E->getRParenLoc()); + + Stmt **Stmts = E->getTrailingObjects<Stmt *>(); + // Add 1 to account for the controlling expression which is the first + // expression in the trailing array of Stmt *. This is not needed for + // the trailing array of TypeSourceInfo *. + for (unsigned I = 0, N = E->getNumAssocs() + 1; I < N; ++I) + Record.AddStmt(Stmts[I]); + + TypeSourceInfo **TSIs = E->getTrailingObjects<TypeSourceInfo *>(); + for (unsigned I = 0, N = E->getNumAssocs(); I < N; ++I) + Record.AddTypeSourceInfo(TSIs[I]); + Code = serialization::EXPR_GENERIC_SELECTION; } @@ -1193,6 +1231,7 @@ void ASTStmtWriter::VisitObjCForCollectionStmt(ObjCForCollectionStmt *S) { } void ASTStmtWriter::VisitObjCAtCatchStmt(ObjCAtCatchStmt *S) { + VisitStmt(S); Record.AddStmt(S->getCatchBody()); Record.AddDeclRef(S->getCatchParamDecl()); Record.AddSourceLocation(S->getAtCatchLoc()); @@ -1201,18 +1240,21 @@ void ASTStmtWriter::VisitObjCAtCatchStmt(ObjCAtCatchStmt *S) { } void ASTStmtWriter::VisitObjCAtFinallyStmt(ObjCAtFinallyStmt *S) { + VisitStmt(S); Record.AddStmt(S->getFinallyBody()); Record.AddSourceLocation(S->getAtFinallyLoc()); Code = serialization::STMT_OBJC_FINALLY; } void ASTStmtWriter::VisitObjCAutoreleasePoolStmt(ObjCAutoreleasePoolStmt *S) { + VisitStmt(S); // FIXME: no test coverage. Record.AddStmt(S->getSubStmt()); Record.AddSourceLocation(S->getAtLoc()); Code = serialization::STMT_OBJC_AUTORELEASE_POOL; } void ASTStmtWriter::VisitObjCAtTryStmt(ObjCAtTryStmt *S) { + VisitStmt(S); Record.push_back(S->getNumCatchStmts()); Record.push_back(S->getFinallyStmt() != nullptr); Record.AddStmt(S->getTryBody()); @@ -1225,6 +1267,7 @@ void ASTStmtWriter::VisitObjCAtTryStmt(ObjCAtTryStmt *S) { } void ASTStmtWriter::VisitObjCAtSynchronizedStmt(ObjCAtSynchronizedStmt *S) { + VisitStmt(S); // FIXME: no test coverage. Record.AddStmt(S->getSynchExpr()); Record.AddStmt(S->getSynchBody()); Record.AddSourceLocation(S->getAtSynchronizedLoc()); @@ -1232,6 +1275,7 @@ void ASTStmtWriter::VisitObjCAtSynchronizedStmt(ObjCAtSynchronizedStmt *S) { } void ASTStmtWriter::VisitObjCAtThrowStmt(ObjCAtThrowStmt *S) { + VisitStmt(S); // FIXME: no test coverage. Record.AddStmt(S->getThrowExpr()); Record.AddSourceLocation(S->getThrowLoc()); Code = serialization::STMT_OBJC_AT_THROW; @@ -1407,6 +1451,12 @@ void ASTStmtWriter::VisitCXXFunctionalCastExpr(CXXFunctionalCastExpr *E) { Code = serialization::EXPR_CXX_FUNCTIONAL_CAST; } +void ASTStmtWriter::VisitBuiltinBitCastExpr(BuiltinBitCastExpr *E) { + VisitExplicitCastExpr(E); + Record.AddSourceLocation(E->getBeginLoc()); + Record.AddSourceLocation(E->getEndLoc()); +} + void ASTStmtWriter::VisitUserDefinedLiteral(UserDefinedLiteral *E) { VisitCallExpr(E); Record.AddSourceLocation(E->UDSuffixLoc); @@ -1456,6 +1506,7 @@ void ASTStmtWriter::VisitCXXThrowExpr(CXXThrowExpr *E) { void ASTStmtWriter::VisitCXXDefaultArgExpr(CXXDefaultArgExpr *E) { VisitExpr(E); Record.AddDeclRef(E->getParam()); + Record.AddDeclRef(cast_or_null<Decl>(E->getUsedContext())); Record.AddSourceLocation(E->getUsedLocation()); Code = serialization::EXPR_CXX_DEFAULT_ARG; } @@ -1463,6 +1514,7 @@ void ASTStmtWriter::VisitCXXDefaultArgExpr(CXXDefaultArgExpr *E) { void ASTStmtWriter::VisitCXXDefaultInitExpr(CXXDefaultInitExpr *E) { VisitExpr(E); Record.AddDeclRef(E->getField()); + Record.AddDeclRef(cast_or_null<Decl>(E->getUsedContext())); Record.AddSourceLocation(E->getExprLoc()); Code = serialization::EXPR_CXX_DEFAULT_INIT; } @@ -1768,6 +1820,7 @@ void ASTStmtWriter::VisitCXXFoldExpr(CXXFoldExpr *E) { Record.AddSourceLocation(E->LParenLoc); Record.AddSourceLocation(E->EllipsisLoc); Record.AddSourceLocation(E->RParenLoc); + Record.push_back(E->NumExpansions); Record.AddStmt(E->SubExprs[0]); Record.AddStmt(E->SubExprs[1]); Record.push_back(E->Opcode); diff --git a/lib/Serialization/GeneratePCH.cpp b/lib/Serialization/GeneratePCH.cpp index 2e0076521f9c..002233e49bb0 100644 --- a/lib/Serialization/GeneratePCH.cpp +++ b/lib/Serialization/GeneratePCH.cpp @@ -1,9 +1,8 @@ //===--- GeneratePCH.cpp - Sema Consumer for PCH Generation -----*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -17,20 +16,22 @@ #include "clang/Lex/Preprocessor.h" #include "clang/Sema/SemaConsumer.h" #include "clang/Serialization/ASTWriter.h" -#include "llvm/Bitcode/BitstreamWriter.h" +#include "llvm/Bitstream/BitstreamWriter.h" using namespace clang; PCHGenerator::PCHGenerator( - const Preprocessor &PP, StringRef OutputFile, StringRef isysroot, - std::shared_ptr<PCHBuffer> Buffer, + const Preprocessor &PP, InMemoryModuleCache &ModuleCache, + StringRef OutputFile, StringRef isysroot, std::shared_ptr<PCHBuffer> Buffer, ArrayRef<std::shared_ptr<ModuleFileExtension>> Extensions, - bool AllowASTWithErrors, bool IncludeTimestamps) + bool AllowASTWithErrors, bool IncludeTimestamps, + bool ShouldCacheASTInMemory) : PP(PP), OutputFile(OutputFile), isysroot(isysroot.str()), SemaPtr(nullptr), Buffer(std::move(Buffer)), Stream(this->Buffer->Data), - Writer(Stream, this->Buffer->Data, PP.getPCMCache(), Extensions, + Writer(Stream, this->Buffer->Data, ModuleCache, Extensions, IncludeTimestamps), - AllowASTWithErrors(AllowASTWithErrors) { + AllowASTWithErrors(AllowASTWithErrors), + ShouldCacheASTInMemory(ShouldCacheASTInMemory) { this->Buffer->IsComplete = false; } @@ -62,7 +63,8 @@ void PCHGenerator::HandleTranslationUnit(ASTContext &Ctx) { Writer.WriteAST(*SemaPtr, OutputFile, Module, isysroot, // For serialization we are lenient if the errors were // only warn-as-error kind. - PP.getDiagnostics().hasUncompilableErrorOccurred()); + PP.getDiagnostics().hasUncompilableErrorOccurred(), + ShouldCacheASTInMemory); Buffer->IsComplete = true; } diff --git a/lib/Serialization/GlobalModuleIndex.cpp b/lib/Serialization/GlobalModuleIndex.cpp index e7642a38924d..2db8f830c46d 100644 --- a/lib/Serialization/GlobalModuleIndex.cpp +++ b/lib/Serialization/GlobalModuleIndex.cpp @@ -1,9 +1,8 @@ //===--- GlobalModuleIndex.cpp - Global Module Index ------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -11,6 +10,7 @@ // //===----------------------------------------------------------------------===// + #include "ASTReaderInternals.h" #include "clang/Basic/FileManager.h" #include "clang/Lex/HeaderSearch.h" @@ -21,14 +21,15 @@ #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/MapVector.h" #include "llvm/ADT/SmallString.h" -#include "llvm/Bitcode/BitstreamReader.h" -#include "llvm/Bitcode/BitstreamWriter.h" +#include "llvm/Bitstream/BitstreamReader.h" +#include "llvm/Bitstream/BitstreamWriter.h" #include "llvm/Support/DJB.h" #include "llvm/Support/FileSystem.h" #include "llvm/Support/LockFileManager.h" #include "llvm/Support/MemoryBuffer.h" #include "llvm/Support/OnDiskHashTable.h" #include "llvm/Support/Path.h" +#include "llvm/Support/TimeProfiler.h" #include <cstdio> using namespace clang; using namespace serialization; @@ -127,11 +128,21 @@ GlobalModuleIndex::GlobalModuleIndex(std::unique_ptr<llvm::MemoryBuffer> Buffer, llvm::BitstreamCursor Cursor) : Buffer(std::move(Buffer)), IdentifierIndex(), NumIdentifierLookups(), NumIdentifierLookupHits() { + auto Fail = [&Buffer](llvm::Error &&Err) { + report_fatal_error("Module index '" + Buffer->getBufferIdentifier() + + "' failed: " + toString(std::move(Err))); + }; + + llvm::TimeTraceScope TimeScope("Module LoadIndex", StringRef("")); // Read the global index. bool InGlobalIndexBlock = false; bool Done = false; while (!Done) { - llvm::BitstreamEntry Entry = Cursor.advance(); + llvm::BitstreamEntry Entry; + if (Expected<llvm::BitstreamEntry> Res = Cursor.advance()) + Entry = Res.get(); + else + Fail(Res.takeError()); switch (Entry.Kind) { case llvm::BitstreamEntry::Error: @@ -155,19 +166,23 @@ GlobalModuleIndex::GlobalModuleIndex(std::unique_ptr<llvm::MemoryBuffer> Buffer, case llvm::BitstreamEntry::SubBlock: if (!InGlobalIndexBlock && Entry.ID == GLOBAL_INDEX_BLOCK_ID) { - if (Cursor.EnterSubBlock(GLOBAL_INDEX_BLOCK_ID)) - return; - + if (llvm::Error Err = Cursor.EnterSubBlock(GLOBAL_INDEX_BLOCK_ID)) + Fail(std::move(Err)); InGlobalIndexBlock = true; - } else if (Cursor.SkipBlock()) { - return; - } + } else if (llvm::Error Err = Cursor.SkipBlock()) + Fail(std::move(Err)); continue; } SmallVector<uint64_t, 64> Record; StringRef Blob; - switch ((IndexRecordTypes)Cursor.readRecord(Entry.ID, Record, &Blob)) { + Expected<unsigned> MaybeIndexRecord = + Cursor.readRecord(Entry.ID, Record, &Blob); + if (!MaybeIndexRecord) + Fail(MaybeIndexRecord.takeError()); + IndexRecordTypes IndexRecord = + static_cast<IndexRecordTypes>(MaybeIndexRecord.get()); + switch (IndexRecord) { case INDEX_METADATA: // Make sure that the version matches. if (Record.size() < 1 || Record[0] != CurrentVersion) @@ -232,7 +247,7 @@ GlobalModuleIndex::~GlobalModuleIndex() { delete static_cast<IdentifierIndexTable *>(IdentifierIndex); } -std::pair<GlobalModuleIndex *, GlobalModuleIndex::ErrorCode> +std::pair<GlobalModuleIndex *, llvm::Error> GlobalModuleIndex::readIndex(StringRef Path) { // Load the index file, if it's there. llvm::SmallString<128> IndexPath; @@ -242,22 +257,26 @@ GlobalModuleIndex::readIndex(StringRef Path) { llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> BufferOrErr = llvm::MemoryBuffer::getFile(IndexPath.c_str()); if (!BufferOrErr) - return std::make_pair(nullptr, EC_NotFound); + return std::make_pair(nullptr, + llvm::errorCodeToError(BufferOrErr.getError())); std::unique_ptr<llvm::MemoryBuffer> Buffer = std::move(BufferOrErr.get()); /// The main bitstream cursor for the main block. llvm::BitstreamCursor Cursor(*Buffer); // Sniff for the signature. - if (Cursor.Read(8) != 'B' || - Cursor.Read(8) != 'C' || - Cursor.Read(8) != 'G' || - Cursor.Read(8) != 'I') { - return std::make_pair(nullptr, EC_IOError); + for (unsigned char C : {'B', 'C', 'G', 'I'}) { + if (Expected<llvm::SimpleBitstreamCursor::word_t> Res = Cursor.Read(8)) { + if (Res.get() != C) + return std::make_pair( + nullptr, llvm::createStringError(std::errc::illegal_byte_sequence, + "expected signature BCGI")); + } else + return std::make_pair(nullptr, Res.takeError()); } return std::make_pair(new GlobalModuleIndex(std::move(Buffer), Cursor), - EC_None); + llvm::Error::success()); } void @@ -436,9 +455,7 @@ namespace { : FileMgr(FileMgr), PCHContainerRdr(PCHContainerRdr) {} /// Load the contents of the given module file into the builder. - /// - /// \returns true if an error occurred, false otherwise. - bool loadModuleFile(const FileEntry *File); + llvm::Error loadModuleFile(const FileEntry *File); /// Write the index to the given bitstream. /// \returns true if an error occurred, false otherwise. @@ -509,24 +526,25 @@ namespace { }; } -bool GlobalModuleIndexBuilder::loadModuleFile(const FileEntry *File) { +llvm::Error GlobalModuleIndexBuilder::loadModuleFile(const FileEntry *File) { // Open the module file. auto Buffer = FileMgr.getBufferForFile(File, /*isVolatile=*/true); - if (!Buffer) { - return true; - } + if (!Buffer) + return llvm::createStringError(Buffer.getError(), + "failed getting buffer for module file"); // Initialize the input stream llvm::BitstreamCursor InStream(PCHContainerRdr.ExtractPCH(**Buffer)); // Sniff for the signature. - if (InStream.Read(8) != 'C' || - InStream.Read(8) != 'P' || - InStream.Read(8) != 'C' || - InStream.Read(8) != 'H') { - return true; - } + for (unsigned char C : {'C', 'P', 'C', 'H'}) + if (Expected<llvm::SimpleBitstreamCursor::word_t> Res = InStream.Read(8)) { + if (Res.get() != C) + return llvm::createStringError(std::errc::illegal_byte_sequence, + "expected signature CPCH"); + } else + return Res.takeError(); // Record this module file and assign it a unique ID (if it doesn't have // one already). @@ -536,7 +554,11 @@ bool GlobalModuleIndexBuilder::loadModuleFile(const FileEntry *File) { enum { Other, ControlBlock, ASTBlock, DiagnosticOptionsBlock } State = Other; bool Done = false; while (!Done) { - llvm::BitstreamEntry Entry = InStream.advance(); + Expected<llvm::BitstreamEntry> MaybeEntry = InStream.advance(); + if (!MaybeEntry) + return MaybeEntry.takeError(); + llvm::BitstreamEntry Entry = MaybeEntry.get(); + switch (Entry.Kind) { case llvm::BitstreamEntry::Error: Done = true; @@ -545,8 +567,10 @@ bool GlobalModuleIndexBuilder::loadModuleFile(const FileEntry *File) { case llvm::BitstreamEntry::Record: // In the 'other' state, just skip the record. We don't care. if (State == Other) { - InStream.skipRecord(Entry.ID); - continue; + if (llvm::Expected<unsigned> Skipped = InStream.skipRecord(Entry.ID)) + continue; + else + return Skipped.takeError(); } // Handle potentially-interesting records below. @@ -554,8 +578,8 @@ bool GlobalModuleIndexBuilder::loadModuleFile(const FileEntry *File) { case llvm::BitstreamEntry::SubBlock: if (Entry.ID == CONTROL_BLOCK_ID) { - if (InStream.EnterSubBlock(CONTROL_BLOCK_ID)) - return true; + if (llvm::Error Err = InStream.EnterSubBlock(CONTROL_BLOCK_ID)) + return Err; // Found the control block. State = ControlBlock; @@ -563,8 +587,8 @@ bool GlobalModuleIndexBuilder::loadModuleFile(const FileEntry *File) { } if (Entry.ID == AST_BLOCK_ID) { - if (InStream.EnterSubBlock(AST_BLOCK_ID)) - return true; + if (llvm::Error Err = InStream.EnterSubBlock(AST_BLOCK_ID)) + return Err; // Found the AST block. State = ASTBlock; @@ -572,16 +596,16 @@ bool GlobalModuleIndexBuilder::loadModuleFile(const FileEntry *File) { } if (Entry.ID == UNHASHED_CONTROL_BLOCK_ID) { - if (InStream.EnterSubBlock(UNHASHED_CONTROL_BLOCK_ID)) - return true; + if (llvm::Error Err = InStream.EnterSubBlock(UNHASHED_CONTROL_BLOCK_ID)) + return Err; // Found the Diagnostic Options block. State = DiagnosticOptionsBlock; continue; } - if (InStream.SkipBlock()) - return true; + if (llvm::Error Err = InStream.SkipBlock()) + return Err; continue; @@ -593,7 +617,10 @@ bool GlobalModuleIndexBuilder::loadModuleFile(const FileEntry *File) { // Read the given record. SmallVector<uint64_t, 64> Record; StringRef Blob; - unsigned Code = InStream.readRecord(Entry.ID, Record, &Blob); + Expected<unsigned> MaybeCode = InStream.readRecord(Entry.ID, Record, &Blob); + if (!MaybeCode) + return MaybeCode.takeError(); + unsigned Code = MaybeCode.get(); // Handle module dependencies. if (State == ControlBlock && Code == IMPORTS) { @@ -631,11 +658,13 @@ bool GlobalModuleIndexBuilder::loadModuleFile(const FileEntry *File) { // Find the imported module file. const FileEntry *DependsOnFile - = FileMgr.getFile(ImportedFile, /*openFile=*/false, - /*cacheFailure=*/false); + = FileMgr.getFile(ImportedFile, /*OpenFile=*/false, + /*CacheFailure=*/false); if (!DependsOnFile) - return true; + return llvm::createStringError(std::errc::bad_file_descriptor, + "imported file \"%s\" not found", + ImportedFile.c_str()); // Save the information in ImportedModuleFileInfo so we can verify after // loading all pcms. @@ -680,7 +709,7 @@ bool GlobalModuleIndexBuilder::loadModuleFile(const FileEntry *File) { // We don't care about this record. } - return false; + return llvm::Error::success(); } namespace { @@ -740,6 +769,7 @@ bool GlobalModuleIndexBuilder::writeIndex(llvm::BitstreamWriter &Stream) { } using namespace llvm; + llvm::TimeTraceScope TimeScope("Module WriteIndex", StringRef("")); // Emit the file header. Stream.Emit((unsigned)'B', 8); @@ -817,7 +847,7 @@ bool GlobalModuleIndexBuilder::writeIndex(llvm::BitstreamWriter &Stream) { return false; } -GlobalModuleIndex::ErrorCode +llvm::Error GlobalModuleIndex::writeIndex(FileManager &FileMgr, const PCHContainerReader &PCHContainerRdr, StringRef Path) { @@ -830,7 +860,7 @@ GlobalModuleIndex::writeIndex(FileManager &FileMgr, llvm::LockFileManager Locked(IndexPath); switch (Locked) { case llvm::LockFileManager::LFS_Error: - return EC_IOError; + return llvm::createStringError(std::errc::io_error, "LFS error"); case llvm::LockFileManager::LFS_Owned: // We're responsible for building the index ourselves. Do so below. @@ -839,7 +869,8 @@ GlobalModuleIndex::writeIndex(FileManager &FileMgr, case llvm::LockFileManager::LFS_Shared: // Someone else is responsible for building the index. We don't care // when they finish, so we're done. - return EC_Building; + return llvm::createStringError(std::errc::device_or_resource_busy, + "someone else is building the index"); } // The module index builder. @@ -856,7 +887,8 @@ GlobalModuleIndex::writeIndex(FileManager &FileMgr, // in the process of rebuilding a module. They'll rebuild the index // at the end of that translation unit, so we don't have to. if (llvm::sys::path::extension(D->path()) == ".pcm.lock") - return EC_Building; + return llvm::createStringError(std::errc::device_or_resource_busy, + "someone else is building the index"); continue; } @@ -867,8 +899,8 @@ GlobalModuleIndex::writeIndex(FileManager &FileMgr, continue; // Load this module file. - if (Builder.loadModuleFile(ModuleFile)) - return EC_IOError; + if (llvm::Error Err = Builder.loadModuleFile(ModuleFile)) + return Err; } // The output buffer, into which the global index will be written. @@ -876,7 +908,8 @@ GlobalModuleIndex::writeIndex(FileManager &FileMgr, { llvm::BitstreamWriter OutputStream(OutputBuffer); if (Builder.writeIndex(OutputStream)) - return EC_IOError; + return llvm::createStringError(std::errc::io_error, + "failed writing index"); } // Write the global index file to a temporary file. @@ -884,31 +917,32 @@ GlobalModuleIndex::writeIndex(FileManager &FileMgr, int TmpFD; if (llvm::sys::fs::createUniqueFile(IndexPath + "-%%%%%%%%", TmpFD, IndexTmpPath)) - return EC_IOError; + return llvm::createStringError(std::errc::io_error, + "failed creating unique file"); // Open the temporary global index file for output. llvm::raw_fd_ostream Out(TmpFD, true); if (Out.has_error()) - return EC_IOError; + return llvm::createStringError(Out.error(), "failed outputting to stream"); // Write the index. Out.write(OutputBuffer.data(), OutputBuffer.size()); Out.close(); if (Out.has_error()) - return EC_IOError; + return llvm::createStringError(Out.error(), "failed writing to stream"); // Remove the old index file. It isn't relevant any more. llvm::sys::fs::remove(IndexPath); // Rename the newly-written index file to the proper name. - if (llvm::sys::fs::rename(IndexTmpPath, IndexPath)) { - // Rename failed; just remove the + if (std::error_code Err = llvm::sys::fs::rename(IndexTmpPath, IndexPath)) { + // Remove the file on failure, don't check whether removal succeeded. llvm::sys::fs::remove(IndexTmpPath); - return EC_IOError; + return llvm::createStringError(Err, "failed renaming file \"%s\" to \"%s\"", + IndexTmpPath.c_str(), IndexPath.c_str()); } - // We're done. - return EC_None; + return llvm::Error::success(); } namespace { diff --git a/lib/Serialization/InMemoryModuleCache.cpp b/lib/Serialization/InMemoryModuleCache.cpp new file mode 100644 index 000000000000..d35fa2a807f4 --- /dev/null +++ b/lib/Serialization/InMemoryModuleCache.cpp @@ -0,0 +1,80 @@ +//===- InMemoryModuleCache.cpp - Cache for loaded memory buffers ----------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "clang/Serialization/InMemoryModuleCache.h" +#include "llvm/Support/MemoryBuffer.h" + +using namespace clang; + +InMemoryModuleCache::State +InMemoryModuleCache::getPCMState(llvm::StringRef Filename) const { + auto I = PCMs.find(Filename); + if (I == PCMs.end()) + return Unknown; + if (I->second.IsFinal) + return Final; + return I->second.Buffer ? Tentative : ToBuild; +} + +llvm::MemoryBuffer & +InMemoryModuleCache::addPCM(llvm::StringRef Filename, + std::unique_ptr<llvm::MemoryBuffer> Buffer) { + auto Insertion = PCMs.insert(std::make_pair(Filename, std::move(Buffer))); + assert(Insertion.second && "Already has a PCM"); + return *Insertion.first->second.Buffer; +} + +llvm::MemoryBuffer & +InMemoryModuleCache::addBuiltPCM(llvm::StringRef Filename, + std::unique_ptr<llvm::MemoryBuffer> Buffer) { + auto &PCM = PCMs[Filename]; + assert(!PCM.IsFinal && "Trying to override finalized PCM?"); + assert(!PCM.Buffer && "Trying to override tentative PCM?"); + PCM.Buffer = std::move(Buffer); + PCM.IsFinal = true; + return *PCM.Buffer; +} + +llvm::MemoryBuffer * +InMemoryModuleCache::lookupPCM(llvm::StringRef Filename) const { + auto I = PCMs.find(Filename); + if (I == PCMs.end()) + return nullptr; + return I->second.Buffer.get(); +} + +bool InMemoryModuleCache::isPCMFinal(llvm::StringRef Filename) const { + return getPCMState(Filename) == Final; +} + +bool InMemoryModuleCache::shouldBuildPCM(llvm::StringRef Filename) const { + return getPCMState(Filename) == ToBuild; +} + +bool InMemoryModuleCache::tryToDropPCM(llvm::StringRef Filename) { + auto I = PCMs.find(Filename); + assert(I != PCMs.end() && "PCM to remove is unknown..."); + + auto &PCM = I->second; + assert(PCM.Buffer && "PCM to remove is scheduled to be built..."); + + if (PCM.IsFinal) + return true; + + PCM.Buffer.reset(); + return false; +} + +void InMemoryModuleCache::finalizePCM(llvm::StringRef Filename) { + auto I = PCMs.find(Filename); + assert(I != PCMs.end() && "PCM to finalize is unknown..."); + + auto &PCM = I->second; + assert(PCM.Buffer && "Trying to finalize a dropped PCM..."); + PCM.IsFinal = true; +} diff --git a/lib/Serialization/Module.cpp b/lib/Serialization/Module.cpp index 580e46e4f240..2b6c9211beaf 100644 --- a/lib/Serialization/Module.cpp +++ b/lib/Serialization/Module.cpp @@ -1,9 +1,8 @@ //===- Module.cpp - Module description ------------------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/lib/Serialization/ModuleFileExtension.cpp b/lib/Serialization/ModuleFileExtension.cpp index 5bd0a1ce660b..e1ae8a494ab1 100644 --- a/lib/Serialization/ModuleFileExtension.cpp +++ b/lib/Serialization/ModuleFileExtension.cpp @@ -1,9 +1,8 @@ //===-- ModuleFileExtension.cpp - Module File Extensions ------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// #include "clang/Serialization/ModuleFileExtension.h" diff --git a/lib/Serialization/ModuleManager.cpp b/lib/Serialization/ModuleManager.cpp index 54e0c08c5bc9..6ae0c4f57551 100644 --- a/lib/Serialization/ModuleManager.cpp +++ b/lib/Serialization/ModuleManager.cpp @@ -1,9 +1,8 @@ //===- ModuleManager.cpp - Module Manager ---------------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -15,10 +14,10 @@ #include "clang/Serialization/ModuleManager.h" #include "clang/Basic/FileManager.h" #include "clang/Basic/LLVM.h" -#include "clang/Basic/MemoryBufferCache.h" #include "clang/Lex/HeaderSearch.h" #include "clang/Lex/ModuleMap.h" #include "clang/Serialization/GlobalModuleIndex.h" +#include "clang/Serialization/InMemoryModuleCache.h" #include "clang/Serialization/Module.h" #include "clang/Serialization/PCHContainerOperations.h" #include "llvm/ADT/STLExtras.h" @@ -43,8 +42,8 @@ using namespace clang; using namespace serialization; ModuleFile *ModuleManager::lookupByFileName(StringRef Name) const { - const FileEntry *Entry = FileMgr.getFile(Name, /*openFile=*/false, - /*cacheFailure=*/false); + const FileEntry *Entry = FileMgr.getFile(Name, /*OpenFile=*/false, + /*CacheFailure=*/false); if (Entry) return lookup(Entry); @@ -69,8 +68,8 @@ ModuleFile *ModuleManager::lookup(const FileEntry *File) const { std::unique_ptr<llvm::MemoryBuffer> ModuleManager::lookupBuffer(StringRef Name) { - const FileEntry *Entry = FileMgr.getFile(Name, /*openFile=*/false, - /*cacheFailure=*/false); + const FileEntry *Entry = FileMgr.getFile(Name, /*OpenFile=*/false, + /*CacheFailure=*/false); return std::move(InMemoryBuffers[Entry]); } @@ -119,6 +118,8 @@ ModuleManager::addModule(StringRef FileName, ModuleKind Type, // contents, but we can't check that.) ExpectedModTime = 0; } + // Note: ExpectedSize and ExpectedModTime will be 0 for MK_ImplicitModule + // when using an ASTFileSignature. if (lookupModuleFile(FileName, ExpectedSize, ExpectedModTime, Entry)) { ErrorStr = "module file out of date"; return OutOfDate; @@ -160,15 +161,21 @@ ModuleManager::addModule(StringRef FileName, ModuleKind Type, // Load the contents of the module if (std::unique_ptr<llvm::MemoryBuffer> Buffer = lookupBuffer(FileName)) { // The buffer was already provided for us. - NewModule->Buffer = &PCMCache->addBuffer(FileName, std::move(Buffer)); + NewModule->Buffer = &ModuleCache->addBuiltPCM(FileName, std::move(Buffer)); // Since the cached buffer is reused, it is safe to close the file // descriptor that was opened while stat()ing the PCM in // lookupModuleFile() above, it won't be needed any longer. Entry->closeFile(); - } else if (llvm::MemoryBuffer *Buffer = PCMCache->lookupBuffer(FileName)) { + } else if (llvm::MemoryBuffer *Buffer = + getModuleCache().lookupPCM(FileName)) { NewModule->Buffer = Buffer; // As above, the file descriptor is no longer needed. Entry->closeFile(); + } else if (getModuleCache().shouldBuildPCM(FileName)) { + // Report that the module is out of date, since we tried (and failed) to + // import it earlier. + Entry->closeFile(); + return OutOfDate; } else { // Open the AST file. llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> Buf((std::error_code())); @@ -177,7 +184,7 @@ ModuleManager::addModule(StringRef FileName, ModuleKind Type, } else { // Get a buffer of the file and close the file descriptor when done. Buf = FileMgr.getBufferForFile(NewModule->File, - /*IsVolatile=*/false, + /*isVolatile=*/false, /*ShouldClose=*/true); } @@ -186,7 +193,7 @@ ModuleManager::addModule(StringRef FileName, ModuleKind Type, return Missing; } - NewModule->Buffer = &PCMCache->addBuffer(FileName, std::move(*Buf)); + NewModule->Buffer = &getModuleCache().addPCM(FileName, std::move(*Buf)); } // Initialize the stream. @@ -198,7 +205,7 @@ ModuleManager::addModule(StringRef FileName, ModuleKind Type, ExpectedSignature, ErrorStr)) { // Try to remove the buffer. If it can't be removed, then it was already // validated by this process. - if (!PCMCache->tryToRemoveBuffer(NewModule->FileName)) + if (!getModuleCache().tryToDropPCM(NewModule->FileName)) FileMgr.invalidateCache(NewModule->File); return OutOfDate; } @@ -247,8 +254,7 @@ void ModuleManager::removeModules( // Remove the modules from the PCH chain. for (auto I = First; I != Last; ++I) { if (!I->isModule()) { - PCHChain.erase(std::find(PCHChain.begin(), PCHChain.end(), &*I), - PCHChain.end()); + PCHChain.erase(llvm::find(PCHChain, &*I), PCHChain.end()); break; } } @@ -263,17 +269,6 @@ void ModuleManager::removeModules( mod->setASTFile(nullptr); } } - - // Files that didn't make it through ReadASTCore successfully will be - // rebuilt (or there was an error). Invalidate them so that we can load the - // new files that will be renamed over the old ones. - // - // The PCMCache tracks whether the module was successfully loaded in another - // thread/context; in that case, it won't need to be rebuilt (and we can't - // safely invalidate it anyway). - if (LoadedSuccessfully.count(&*victim) == 0 && - !PCMCache->tryToRemoveBuffer(victim->FileName)) - FileMgr.invalidateCache(victim->File); } // Delete the modules. @@ -328,11 +323,12 @@ void ModuleManager::moduleFileAccepted(ModuleFile *MF) { ModulesInCommonWithGlobalIndex.push_back(MF); } -ModuleManager::ModuleManager(FileManager &FileMgr, MemoryBufferCache &PCMCache, +ModuleManager::ModuleManager(FileManager &FileMgr, + InMemoryModuleCache &ModuleCache, const PCHContainerReader &PCHContainerRdr, - const HeaderSearch& HeaderSearchInfo) - : FileMgr(FileMgr), PCMCache(&PCMCache), PCHContainerRdr(PCHContainerRdr), - HeaderSearchInfo(HeaderSearchInfo) {} + const HeaderSearch &HeaderSearchInfo) + : FileMgr(FileMgr), ModuleCache(&ModuleCache), + PCHContainerRdr(PCHContainerRdr), HeaderSearchInfo(HeaderSearchInfo) {} ModuleManager::~ModuleManager() { delete FirstVisitState; } @@ -451,7 +447,7 @@ bool ModuleManager::lookupModuleFile(StringRef FileName, // Open the file immediately to ensure there is no race between stat'ing and // opening the file. - File = FileMgr.getFile(FileName, /*openFile=*/true, /*cacheFailure=*/false); + File = FileMgr.getFile(FileName, /*OpenFile=*/true, /*CacheFailure=*/false); if (!File) return false; diff --git a/lib/Serialization/MultiOnDiskHashTable.h b/lib/Serialization/MultiOnDiskHashTable.h index ded7cd146449..adc97d57e0ac 100644 --- a/lib/Serialization/MultiOnDiskHashTable.h +++ b/lib/Serialization/MultiOnDiskHashTable.h @@ -1,9 +1,8 @@ //===- MultiOnDiskHashTable.h - Merged set of hash tables -------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/lib/Serialization/PCHContainerOperations.cpp b/lib/Serialization/PCHContainerOperations.cpp index fbc613efeb63..00063d64f3f2 100644 --- a/lib/Serialization/PCHContainerOperations.cpp +++ b/lib/Serialization/PCHContainerOperations.cpp @@ -1,9 +1,8 @@ //=== Serialization/PCHContainerOperations.cpp - PCH Containers -*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -14,7 +13,7 @@ #include "clang/Serialization/PCHContainerOperations.h" #include "clang/AST/ASTConsumer.h" #include "clang/Lex/ModuleLoader.h" -#include "llvm/Bitcode/BitstreamReader.h" +#include "llvm/Bitstream/BitstreamReader.h" #include "llvm/Support/raw_ostream.h" #include <utility> |