From 38295beb73db5f90bfcf31625fb81dbc3b96290a Mon Sep 17 00:00:00 2001 From: Douglas Gregor Date: Mon, 22 Oct 2012 23:51:00 +0000 Subject: [PATCH] Allow clients of the AST reader to specify what kinds of AST load failures they know how to tolerate, e.g., out-of-date input files or configuration/version mismatches. Suppress the corresponding diagnostics if the client can handle it. No clients actually use this functionality, yet. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@166449 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/clang/Serialization/ASTReader.h | 65 +++++++-- lib/Frontend/ASTUnit.cpp | 12 +- lib/Frontend/ChainedIncludesSource.cpp | 3 +- lib/Frontend/CompilerInstance.cpp | 6 +- lib/Serialization/ASTReader.cpp | 170 +++++++++++++++--------- 5 files changed, 175 insertions(+), 81 deletions(-) diff --git a/include/clang/Serialization/ASTReader.h b/include/clang/Serialization/ASTReader.h index 3b623dfe4f..e72e451749 100644 --- a/include/clang/Serialization/ASTReader.h +++ b/include/clang/Serialization/ASTReader.h @@ -107,7 +107,8 @@ public: /// /// \returns true to indicate the options are invalid or false otherwise. virtual bool ReadLanguageOptions(const serialization::ModuleFile &M, - const LangOptions &LangOpts) { + const LangOptions &LangOpts, + bool Complain) { return false; } @@ -116,7 +117,8 @@ public: /// \returns true to indicate the target options are invalid, or false /// otherwise. virtual bool ReadTargetOptions(const serialization::ModuleFile &M, - const TargetOptions &TargetOpts) { + const TargetOptions &TargetOpts, + bool Complain) { return false; } @@ -130,11 +132,14 @@ public: /// \param SuggestedPredefines If necessary, additional definitions are added /// here. /// + /// \param Complain Whether to complain about non-matching predefines buffers. + /// /// \returns true to indicate the predefines are invalid or false otherwise. virtual bool ReadPredefinesBuffer(const PCHPredefinesBlocks &Buffers, StringRef OriginalFileName, std::string &SuggestedPredefines, - FileManager &FileMgr) { + FileManager &FileMgr, + bool Complain) { return false; } @@ -159,13 +164,16 @@ public: : PP(PP), Reader(Reader), NumHeaderInfos(0) {} virtual bool ReadLanguageOptions(const serialization::ModuleFile &M, - const LangOptions &LangOpts); + const LangOptions &LangOpts, + bool Complain); virtual bool ReadTargetOptions(const serialization::ModuleFile &M, - const TargetOptions &TargetOpts); + const TargetOptions &TargetOpts, + bool Complain); virtual bool ReadPredefinesBuffer(const PCHPredefinesBlocks &Buffers, StringRef OriginalFileName, std::string &SuggestedPredefines, - FileManager &FileMgr); + FileManager &FileMgr, + bool Complain); virtual void ReadHeaderFileInfo(const HeaderFileInfo &HFI, unsigned ID); virtual void ReadCounter(const serialization::ModuleFile &M, unsigned Value); @@ -883,7 +891,7 @@ private: /// \brief Retrieve the file entry and 'overridden' bit for an input /// file in the given module file. - InputFile getInputFile(ModuleFile &F, unsigned ID); + InputFile getInputFile(ModuleFile &F, unsigned ID, bool Complain = true); /// \brief Get a FileEntry out of stored-in-PCH filename, making sure we take /// into account all the necessary relocations. @@ -893,17 +901,20 @@ private: ASTReadResult ReadASTCore(StringRef FileName, ModuleKind Type, ModuleFile *ImportedBy, - llvm::SmallVectorImpl &Loaded); + llvm::SmallVectorImpl &Loaded, + unsigned ClientLoadCapabilities); ASTReadResult ReadControlBlock(ModuleFile &F, - llvm::SmallVectorImpl &Loaded); + llvm::SmallVectorImpl &Loaded, + unsigned ClientLoadCapabilities); bool ReadASTBlock(ModuleFile &F); - bool CheckPredefinesBuffers(); + bool CheckPredefinesBuffers(bool Complain); bool ParseLineTable(ModuleFile &F, SmallVectorImpl &Record); bool ReadSourceManagerBlock(ModuleFile &F); llvm::BitstreamCursor &SLocCursorForID(int ID); SourceLocation getImportLocation(ModuleFile *F); bool ReadSubmoduleBlock(ModuleFile &F); - bool ParseLanguageOptions(const ModuleFile &M, const RecordData &Record); + bool ParseLanguageOptions(const ModuleFile &M, const RecordData &Record, + bool Complain); struct RecordLocation { RecordLocation(ModuleFile *M, uint64_t O) @@ -1062,8 +1073,38 @@ public: SourceManager &getSourceManager() const { return SourceMgr; } + /// \brief Flags that indicate what kind of AST loading failures the client + /// of the AST reader can directly handle. + /// + /// When a client states that it can handle a particular kind of failure, + /// the AST reader will not emit errors when producing that kind of failure. + enum LoadFailureCapabilities { + /// \brief The client can't handle any AST loading failures. + ARR_None = 0, + /// \brief The client can handle an AST file that cannot load because it + /// is out-of-date relative to its input files. + ARR_OutOfDate = 0x1, + /// \brief The client can handle an AST file that cannot load because it + /// was built with a different version of Clang. + ARR_VersionMismatch = 0x2, + /// \brief The client can handle an AST file that cannot load because it's + /// compiled configuration doesn't match that of the context it was + /// loaded into. + ARR_ConfigurationMismatch = 0x4 + }; + /// \brief Load the AST file designated by the given file name. - ASTReadResult ReadAST(const std::string &FileName, ModuleKind Type); + /// + /// \param FileName The name of the AST file to load. + /// + /// \param Type The kind of AST being loaded, e.g., PCH, module, main file, + /// or preamble. + /// + /// \param ClientLoadCapabilities The set of client load-failure + /// capabilities, represented as a bitset of the enumerators of + /// LoadFailureCapabilities. + ASTReadResult ReadAST(const std::string &FileName, ModuleKind Type, + unsigned ClientLoadCapabilities); /// \brief Make the entities in the given module and any of its (non-explicit) /// submodules visible to name lookup. diff --git a/lib/Frontend/ASTUnit.cpp b/lib/Frontend/ASTUnit.cpp index 11bd33ec41..a340d7db33 100644 --- a/lib/Frontend/ASTUnit.cpp +++ b/lib/Frontend/ASTUnit.cpp @@ -524,7 +524,8 @@ public: InitializedLanguage(false) {} virtual bool ReadLanguageOptions(const serialization::ModuleFile &M, - const LangOptions &LangOpts) { + const LangOptions &LangOpts, + bool Complain) { if (InitializedLanguage) return false; @@ -538,7 +539,8 @@ public: } virtual bool ReadTargetOptions(const serialization::ModuleFile &M, - const TargetOptions &TargetOpts) { + const TargetOptions &TargetOpts, + bool Complain) { // If we've already initialized the target, don't do it again. if (Target) return false; @@ -557,7 +559,8 @@ public: virtual bool ReadPredefinesBuffer(const PCHPredefinesBlocks &Buffers, StringRef OriginalFileName, std::string &SuggestedPredefines, - FileManager &FileMgr) { + FileManager &FileMgr, + bool Complain) { Predefines = Buffers[0].Data; for (unsigned I = 1, N = Buffers.size(); I != N; ++I) { Predefines += Buffers[I].Data; @@ -809,7 +812,8 @@ ASTUnit *ASTUnit::LoadFromASTFile(const std::string &Filename, AST->TargetOpts, AST->Target, Predefines, Counter)); - switch (Reader->ReadAST(Filename, serialization::MK_MainFile)) { + switch (Reader->ReadAST(Filename, serialization::MK_MainFile, + ASTReader::ARR_None)) { case ASTReader::Success: break; diff --git a/lib/Frontend/ChainedIncludesSource.cpp b/lib/Frontend/ChainedIncludesSource.cpp index bfe0693ad4..205cb51cb0 100644 --- a/lib/Frontend/ChainedIncludesSource.cpp +++ b/lib/Frontend/ChainedIncludesSource.cpp @@ -39,7 +39,8 @@ static ASTReader *createASTReader(CompilerInstance &CI, Reader->addInMemoryBuffer(sr, memBufs[ti]); } Reader->setDeserializationListener(deserialListener); - switch (Reader->ReadAST(pchFile, serialization::MK_PCH)) { + switch (Reader->ReadAST(pchFile, serialization::MK_PCH, + ASTReader::ARR_None)) { case ASTReader::Success: // Set the predefines buffer as suggested by the PCH reader. PP.setPredefines(Reader->getSuggestedPredefines()); diff --git a/lib/Frontend/CompilerInstance.cpp b/lib/Frontend/CompilerInstance.cpp index 225bc137fb..3806f57c94 100644 --- a/lib/Frontend/CompilerInstance.cpp +++ b/lib/Frontend/CompilerInstance.cpp @@ -343,7 +343,8 @@ CompilerInstance::createPCHExternalASTSource(StringRef Path, static_cast(DeserializationListener)); switch (Reader->ReadAST(Path, Preamble ? serialization::MK_Preamble - : serialization::MK_PCH)) { + : serialization::MK_PCH, + ASTReader::ARR_None)) { case ASTReader::Success: // Set the predefines buffer as suggested by the PCH reader. Typically, the // predefines buffer will be empty. @@ -965,7 +966,8 @@ Module *CompilerInstance::loadModule(SourceLocation ImportLoc, // Try to load the module we found. switch (ModuleManager->ReadAST(ModuleFile->getName(), - serialization::MK_Module)) { + serialization::MK_Module, + ASTReader::ARR_None)) { case ASTReader::Success: break; diff --git a/lib/Serialization/ASTReader.cpp b/lib/Serialization/ASTReader.cpp index 5a9eeceb46..a541e24141 100644 --- a/lib/Serialization/ASTReader.cpp +++ b/lib/Serialization/ASTReader.cpp @@ -65,27 +65,31 @@ ASTReaderListener::~ASTReaderListener() {} bool PCHValidator::ReadLanguageOptions(const ModuleFile &M, - const LangOptions &LangOpts) { + const LangOptions &LangOpts, + bool Complain) { const LangOptions &PPLangOpts = PP.getLangOpts(); -#define LANGOPT(Name, Bits, Default, Description) \ - if (PPLangOpts.Name != LangOpts.Name) { \ - Reader.Diag(diag::err_pch_langopt_mismatch) \ - << Description << LangOpts.Name << PPLangOpts.Name; \ - return true; \ +#define LANGOPT(Name, Bits, Default, Description) \ + if (PPLangOpts.Name != LangOpts.Name) { \ + if (Complain) \ + Reader.Diag(diag::err_pch_langopt_mismatch) \ + << Description << LangOpts.Name << PPLangOpts.Name; \ + return true; \ } #define VALUE_LANGOPT(Name, Bits, Default, Description) \ if (PPLangOpts.Name != LangOpts.Name) { \ - Reader.Diag(diag::err_pch_langopt_value_mismatch) \ - << Description; \ - return true; \ -} + if (Complain) \ + Reader.Diag(diag::err_pch_langopt_value_mismatch) \ + << Description; \ + return true; \ + } #define ENUM_LANGOPT(Name, Type, Bits, Default, Description) \ if (PPLangOpts.get##Name() != LangOpts.get##Name()) { \ - Reader.Diag(diag::err_pch_langopt_value_mismatch) \ - << Description; \ + if (Complain) \ + Reader.Diag(diag::err_pch_langopt_value_mismatch) \ + << Description; \ return true; \ } @@ -94,8 +98,9 @@ PCHValidator::ReadLanguageOptions(const ModuleFile &M, #include "clang/Basic/LangOptions.def" if (PPLangOpts.ObjCRuntime != LangOpts.ObjCRuntime) { - Reader.Diag(diag::err_pch_langopt_value_mismatch) - << "target Objective-C runtime"; + if (Complain) + Reader.Diag(diag::err_pch_langopt_value_mismatch) + << "target Objective-C runtime"; return true; } @@ -103,14 +108,16 @@ PCHValidator::ReadLanguageOptions(const ModuleFile &M, } bool PCHValidator::ReadTargetOptions(const ModuleFile &M, - const TargetOptions &TargetOpts) { + const TargetOptions &TargetOpts, + bool Complain) { const TargetOptions &ExistingTargetOpts = PP.getTargetInfo().getTargetOpts(); -#define CHECK_TARGET_OPT(Field, Name) \ - if (TargetOpts.Field != ExistingTargetOpts.Field) { \ - Reader.Diag(diag::err_pch_targetopt_mismatch) \ - << Name << TargetOpts.Field << ExistingTargetOpts.Field; \ - return true; \ +#define CHECK_TARGET_OPT(Field, Name) \ + if (TargetOpts.Field != ExistingTargetOpts.Field) { \ + if (Complain) \ + Reader.Diag(diag::err_pch_targetopt_mismatch) \ + << Name << TargetOpts.Field << ExistingTargetOpts.Field; \ + return true; \ } CHECK_TARGET_OPT(Triple, "target"); @@ -139,25 +146,29 @@ bool PCHValidator::ReadTargetOptions(const ModuleFile &M, } if (ReadFeatures[ReadIdx] < ExistingFeatures[ExistingIdx]) { - Reader.Diag(diag::err_pch_targetopt_feature_mismatch) - << false << ReadFeatures[ReadIdx]; + if (Complain) + Reader.Diag(diag::err_pch_targetopt_feature_mismatch) + << false << ReadFeatures[ReadIdx]; return true; } - Reader.Diag(diag::err_pch_targetopt_feature_mismatch) - << true << ExistingFeatures[ExistingIdx]; + if (Complain) + Reader.Diag(diag::err_pch_targetopt_feature_mismatch) + << true << ExistingFeatures[ExistingIdx]; return true; } if (ExistingIdx < ExistingN) { - Reader.Diag(diag::err_pch_targetopt_feature_mismatch) - << true << ExistingFeatures[ExistingIdx]; + if (Complain) + Reader.Diag(diag::err_pch_targetopt_feature_mismatch) + << true << ExistingFeatures[ExistingIdx]; return true; } if (ReadIdx < ReadN) { - Reader.Diag(diag::err_pch_targetopt_feature_mismatch) - << false << ReadFeatures[ReadIdx]; + if (Complain) + Reader.Diag(diag::err_pch_targetopt_feature_mismatch) + << false << ReadFeatures[ReadIdx]; return true; } @@ -249,7 +260,8 @@ FindMacro(const PCHPredefinesBlocks &Buffers, StringRef MacroDef) { bool PCHValidator::ReadPredefinesBuffer(const PCHPredefinesBlocks &Buffers, StringRef OriginalFileName, std::string &SuggestedPredefines, - FileManager &FileMgr) { + FileManager &FileMgr, + bool Complain) { // We are in the context of an implicit include, so the predefines buffer will // have a #include entry for the PCH file itself (as normalized by the // preprocessor initialization). Find it and skip over it in the checking @@ -263,7 +275,8 @@ bool PCHValidator::ReadPredefinesBuffer(const PCHPredefinesBlocks &Buffers, StringRef(PP.getPredefines()).split(PCHInclude.str()); StringRef Left = Split.first, Right = Split.second; if (Left == PP.getPredefines()) { - Error("Missing PCH include entry!"); + if (Complain) + Error("Missing PCH include entry!"); return true; } @@ -338,7 +351,8 @@ bool PCHValidator::ReadPredefinesBuffer(const PCHPredefinesBlocks &Buffers, continue; } if (!Missing.startswith("#define ")) { - Reader.Diag(diag::warn_pch_compiler_options_mismatch); + if (Complain) + Reader.Diag(diag::warn_pch_compiler_options_mismatch); return true; } @@ -376,6 +390,9 @@ bool PCHValidator::ReadPredefinesBuffer(const PCHPredefinesBlocks &Buffers, } if (ConflictPos != CmdLineLines.end()) { + if (!Complain) + return true; + Reader.Diag(diag::warn_cmdline_conflicting_macro_def) << MacroName; @@ -398,10 +415,16 @@ bool PCHValidator::ReadPredefinesBuffer(const PCHPredefinesBlocks &Buffers, continue; // Don't complain if there are already conflicting defs if (!MissingDefines) { + if (!Complain) + return true; + Reader.Diag(diag::warn_cmdline_missing_macro_defs); MissingDefines = true; } + if (!Complain) + return true; + // Show the definition of this macro within the PCH file. std::pair MacroLoc = FindMacro(Buffers, Missing); @@ -426,7 +449,8 @@ bool PCHValidator::ReadPredefinesBuffer(const PCHPredefinesBlocks &Buffers, for (unsigned I = 0, N = ExtraPredefines.size(); I != N; ++I) { StringRef &Extra = ExtraPredefines[I]; if (!Extra.startswith("#define ")) { - Reader.Diag(diag::warn_pch_compiler_options_mismatch); + if (Complain) + Reader.Diag(diag::warn_pch_compiler_options_mismatch); return true; } @@ -443,7 +467,8 @@ bool PCHValidator::ReadPredefinesBuffer(const PCHPredefinesBlocks &Buffers, // so, defining it as a macro could change behavior, so we reject // the PCH file. if (IdentifierInfo *II = Reader.get(MacroName)) { - Reader.Diag(diag::warn_macro_name_used_in_pch) << II; + if (Complain) + Reader.Diag(diag::warn_macro_name_used_in_pch) << II; return true; } @@ -818,14 +843,15 @@ void ASTReader::Error(unsigned DiagID, } /// \brief Tell the AST listener about the predefines buffers in the chain. -bool ASTReader::CheckPredefinesBuffers() { +bool ASTReader::CheckPredefinesBuffers(bool Complain) { if (Listener) { // We only care about the primary module. ModuleFile &M = ModuleMgr.getPrimaryModule(); return Listener->ReadPredefinesBuffer(PCHPredefinesBuffers, M.ActualOriginalSourceFileName, SuggestedPredefines, - FileMgr); + FileMgr, + Complain); } return false; } @@ -1665,7 +1691,7 @@ void ASTReader::markIdentifierUpToDate(IdentifierInfo *II) { } llvm::PointerIntPair -ASTReader::getInputFile(ModuleFile &F, unsigned ID) { +ASTReader::getInputFile(ModuleFile &F, unsigned ID, bool Complain) { // If this ID is bogus, just return an empty input file. if (ID == 0 || ID > F.InputFilesLoaded.size()) return InputFile(); @@ -1719,10 +1745,12 @@ ASTReader::getInputFile(ModuleFile &F, unsigned ID) { } if (File == 0) { - std::string ErrorStr = "could not find file '"; - ErrorStr += Filename; - ErrorStr += "' referenced by AST file"; - Error(ErrorStr.c_str()); + if (Complain) { + std::string ErrorStr = "could not find file '"; + ErrorStr += Filename; + ErrorStr += "' referenced by AST file"; + Error(ErrorStr.c_str()); + } return InputFile(); } @@ -1766,7 +1794,9 @@ ASTReader::getInputFile(ModuleFile &F, unsigned ID) { || StoredTime != StatBuf.st_mtime #endif )) { - Error(diag::err_fe_pch_file_modified, Filename); + if (Complain) + Error(diag::err_fe_pch_file_modified, Filename); + return InputFile(); } @@ -1820,8 +1850,10 @@ StringRef ASTReader::MaybeAddSystemRootToFilename(ModuleFile &M, return Filename; } -ASTReader::ASTReadResult ASTReader::ReadControlBlock(ModuleFile &F, - llvm::SmallVectorImpl &Loaded) { +ASTReader::ASTReadResult +ASTReader::ReadControlBlock(ModuleFile &F, + llvm::SmallVectorImpl &Loaded, + unsigned ClientLoadCapabilities) { llvm::BitstreamCursor &Stream = F.Stream; if (Stream.EnterSubBlock(CONTROL_BLOCK_ID)) { @@ -1841,8 +1873,9 @@ ASTReader::ASTReadResult ASTReader::ReadControlBlock(ModuleFile &F, // Validate all of the input files. if (!DisableValidation) { + bool Complain = (ClientLoadCapabilities & ARR_OutOfDate) == 0; for (unsigned I = 0, N = Record[0]; I < N; ++I) - if (!getInputFile(F, I+1).getPointer()) + if (!getInputFile(F, I+1, Complain).getPointer()) return OutOfDate; } @@ -1884,8 +1917,9 @@ ASTReader::ASTReadResult ASTReader::ReadControlBlock(ModuleFile &F, &BlobStart, &BlobLen)) { case METADATA: { if (Record[0] != VERSION_MAJOR && !DisableValidation) { - Diag(Record[0] < VERSION_MAJOR? diag::warn_pch_version_too_old - : diag::warn_pch_version_too_new); + if ((ClientLoadCapabilities & ARR_VersionMismatch) == 0) + Diag(Record[0] < VERSION_MAJOR? diag::warn_pch_version_too_old + : diag::warn_pch_version_too_new); return VersionMismatch; } @@ -1900,7 +1934,8 @@ ASTReader::ASTReadResult ASTReader::ReadControlBlock(ModuleFile &F, const std::string &CurBranch = getClangFullRepositoryVersion(); StringRef ASTBranch(BlobStart, BlobLen); if (StringRef(CurBranch) != ASTBranch && !DisableValidation) { - Diag(diag::warn_pch_different_branch) << ASTBranch << CurBranch; + if ((ClientLoadCapabilities & ARR_VersionMismatch) == 0) + Diag(diag::warn_pch_different_branch) << ASTBranch << CurBranch; return VersionMismatch; } break; @@ -1918,7 +1953,8 @@ ASTReader::ASTReadResult ASTReader::ReadControlBlock(ModuleFile &F, Idx += Length; // Load the AST file. - switch(ReadASTCore(ImportedFile, ImportedKind, &F, Loaded)) { + switch(ReadASTCore(ImportedFile, ImportedKind, &F, Loaded, + ClientLoadCapabilities)) { case Failure: return Failure; // If we have to ignore the dependency, we'll have to ignore this too. case OutOfDate: return OutOfDate; @@ -1931,11 +1967,13 @@ ASTReader::ASTReadResult ASTReader::ReadControlBlock(ModuleFile &F, break; } - case LANGUAGE_OPTIONS: - if (Listener && &F == *ModuleMgr.begin() && - ParseLanguageOptions(F, Record) && !DisableValidation) + case LANGUAGE_OPTIONS: { + bool Complain = (ClientLoadCapabilities & ARR_ConfigurationMismatch) == 0; + if (Listener && &F == *ModuleMgr.begin() && + ParseLanguageOptions(F, Record, Complain) && !DisableValidation) return ConfigurationMismatch; break; + } case TARGET_OPTIONS: { if (Listener && &F == *ModuleMgr.begin()) { @@ -1953,7 +1991,9 @@ ASTReader::ASTReadResult ASTReader::ReadControlBlock(ModuleFile &F, TargetOpts.Features.push_back(ReadString(Record, Idx)); } - if (Listener->ReadTargetOptions(F, TargetOpts) && !DisableValidation) + bool Complain = (ClientLoadCapabilities & ARR_ConfigurationMismatch)==0; + if (Listener->ReadTargetOptions(F, TargetOpts, Complain) && + !DisableValidation) return ConfigurationMismatch; } break; @@ -2869,13 +2909,15 @@ void ASTReader::makeModuleVisible(Module *Mod, } ASTReader::ASTReadResult ASTReader::ReadAST(const std::string &FileName, - ModuleKind Type) { + ModuleKind Type, + unsigned ClientLoadCapabilities) { // Bump the generation number. unsigned PreviousGeneration = CurrentGeneration++; // Load the core of the AST files. llvm::SmallVector Loaded; - switch(ReadASTCore(FileName, Type, /*ImportedBy=*/0, Loaded)) { + switch(ReadASTCore(FileName, Type, /*ImportedBy=*/0, Loaded, + ClientLoadCapabilities)) { case Failure: return Failure; case OutOfDate: return OutOfDate; case VersionMismatch: return VersionMismatch; @@ -2914,11 +2956,12 @@ ASTReader::ASTReadResult ASTReader::ReadAST(const std::string &FileName, } // Check the predefines buffers. + bool ConfigComplain = (ClientLoadCapabilities & ARR_ConfigurationMismatch)==0; if (!DisableValidation && Type == MK_PCH && // FIXME: CheckPredefinesBuffers also sets the SuggestedPredefines; // if DisableValidation is true, defines that were set on command-line // but not in the PCH file will not be added to SuggestedPredefines. - CheckPredefinesBuffers()) + CheckPredefinesBuffers(ConfigComplain)) return ConfigurationMismatch; // Mark all of the identifiers in the identifier table as being out of date, @@ -2979,10 +3022,12 @@ ASTReader::ASTReadResult ASTReader::ReadAST(const std::string &FileName, return Success; } -ASTReader::ASTReadResult ASTReader::ReadASTCore(StringRef FileName, - ModuleKind Type, - ModuleFile *ImportedBy, - llvm::SmallVectorImpl &Loaded) { +ASTReader::ASTReadResult +ASTReader::ReadASTCore(StringRef FileName, + ModuleKind Type, + ModuleFile *ImportedBy, + llvm::SmallVectorImpl &Loaded, + unsigned ClientLoadCapabilities) { ModuleFile *M; bool NewModule; std::string ErrorStr; @@ -3042,7 +3087,7 @@ ASTReader::ASTReadResult ASTReader::ReadASTCore(StringRef FileName, } break; case CONTROL_BLOCK_ID: - switch (ReadControlBlock(F, Loaded)) { + switch (ReadControlBlock(F, Loaded, ClientLoadCapabilities)) { case Success: break; @@ -3584,7 +3629,8 @@ bool ASTReader::ReadSubmoduleBlock(ModuleFile &F) { /// /// \returns true if the listener deems the file unacceptable, false otherwise. bool ASTReader::ParseLanguageOptions(const ModuleFile &M, - const RecordData &Record) { + const RecordData &Record, + bool Complain) { if (Listener) { LangOptions LangOpts; unsigned Idx = 0; @@ -3601,7 +3647,7 @@ bool ASTReader::ParseLanguageOptions(const ModuleFile &M, unsigned Length = Record[Idx++]; LangOpts.CurrentModule.assign(Record.begin() + Idx, Record.begin() + Idx + Length); - return Listener->ReadLanguageOptions(M, LangOpts); + return Listener->ReadLanguageOptions(M, LangOpts, Complain); } return false; -- 2.40.0