summaryrefslogtreecommitdiff
path: root/lib/Serialization
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Serialization')
-rw-r--r--lib/Serialization/ASTCommon.cpp10
-rw-r--r--lib/Serialization/ASTCommon.h23
-rw-r--r--lib/Serialization/ASTReader.cpp1030
-rw-r--r--lib/Serialization/ASTReaderDecl.cpp189
-rw-r--r--lib/Serialization/ASTReaderInternals.h7
-rw-r--r--lib/Serialization/ASTReaderStmt.cpp220
-rw-r--r--lib/Serialization/ASTWriter.cpp212
-rw-r--r--lib/Serialization/ASTWriterDecl.cpp110
-rw-r--r--lib/Serialization/ASTWriterStmt.cpp131
-rw-r--r--lib/Serialization/GeneratePCH.cpp24
-rw-r--r--lib/Serialization/GlobalModuleIndex.cpp166
-rw-r--r--lib/Serialization/InMemoryModuleCache.cpp80
-rw-r--r--lib/Serialization/Module.cpp7
-rw-r--r--lib/Serialization/ModuleFileExtension.cpp7
-rw-r--r--lib/Serialization/ModuleManager.cpp60
-rw-r--r--lib/Serialization/MultiOnDiskHashTable.h7
-rw-r--r--lib/Serialization/PCHContainerOperations.cpp9
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>