diff options
| author | Dimitry Andric <dim@FreeBSD.org> | 2019-08-20 20:50:49 +0000 | 
|---|---|---|
| committer | Dimitry Andric <dim@FreeBSD.org> | 2019-08-20 20:50:49 +0000 | 
| commit | 2298981669bf3bd63335a4be179bc0f96823a8f4 (patch) | |
| tree | 1cbe2eb27f030d2d70b80ee5ca3c86bee7326a9f /lib/Serialization | |
| parent | 9a83721404652cea39e9f02ae3e3b5c964602a5c (diff) | |
Diffstat (limited to 'lib/Serialization')
| -rw-r--r-- | lib/Serialization/ASTCommon.cpp | 10 | ||||
| -rw-r--r-- | lib/Serialization/ASTCommon.h | 23 | ||||
| -rw-r--r-- | lib/Serialization/ASTReader.cpp | 1030 | ||||
| -rw-r--r-- | lib/Serialization/ASTReaderDecl.cpp | 189 | ||||
| -rw-r--r-- | lib/Serialization/ASTReaderInternals.h | 7 | ||||
| -rw-r--r-- | lib/Serialization/ASTReaderStmt.cpp | 220 | ||||
| -rw-r--r-- | lib/Serialization/ASTWriter.cpp | 212 | ||||
| -rw-r--r-- | lib/Serialization/ASTWriterDecl.cpp | 110 | ||||
| -rw-r--r-- | lib/Serialization/ASTWriterStmt.cpp | 131 | ||||
| -rw-r--r-- | lib/Serialization/GeneratePCH.cpp | 24 | ||||
| -rw-r--r-- | lib/Serialization/GlobalModuleIndex.cpp | 166 | ||||
| -rw-r--r-- | lib/Serialization/InMemoryModuleCache.cpp | 80 | ||||
| -rw-r--r-- | lib/Serialization/Module.cpp | 7 | ||||
| -rw-r--r-- | lib/Serialization/ModuleFileExtension.cpp | 7 | ||||
| -rw-r--r-- | lib/Serialization/ModuleManager.cpp | 60 | ||||
| -rw-r--r-- | lib/Serialization/MultiOnDiskHashTable.h | 7 | ||||
| -rw-r--r-- | lib/Serialization/PCHContainerOperations.cpp | 9 | 
17 files changed, 1723 insertions, 569 deletions
diff --git a/lib/Serialization/ASTCommon.cpp b/lib/Serialization/ASTCommon.cpp index ca826d83d4716..aa3477a7d35e6 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 12e26c1fc2b93..296642e3674a4 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 e0b2b24a0d32a..7f2c7f09e8a3e 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 763ab527570d7..3cac82ad421c0 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 37a929907dcad..265a77fdb215a 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 60abea95bfaf1..afaaa543bb27f 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 37adcb70640d4..10946f9b0d985 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 002b43f811215..b71315505de90 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 6f8b86edcdfc6..4fbcbaabe74bb 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 2e0076521f9c0..002233e49bb06 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 e7642a38924d3..2db8f830c46de 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 0000000000000..d35fa2a807f4d --- /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 580e46e4f2400..2b6c9211beaf5 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 5bd0a1ce660b6..e1ae8a494ab1c 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 54e0c08c5bc96..6ae0c4f575519 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 ded7cd1464492..adc97d57e0ac7 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 fbc613efeb632..00063d64f3f28 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>  | 
