On Oct 22, 2012, at 5:58 PM, Sean Silva <[email protected]> wrote: > Hi Doug, is there any documentation about Clang's > serialization/deserialization capabilities? Maybe just a write-up of > "what you can do with it currently"?
There's some documentation here: http://clang.llvm.org/docs/PCHInternals.html What's it missing? - Doug > -- Sean Silva > > On Mon, Oct 22, 2012 at 7:51 PM, Douglas Gregor <[email protected]> wrote: >> Author: dgregor >> Date: Mon Oct 22 18:51:00 2012 >> New Revision: 166449 >> >> URL: http://llvm.org/viewvc/llvm-project?rev=166449&view=rev >> Log: >> 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. >> >> Modified: >> cfe/trunk/include/clang/Serialization/ASTReader.h >> cfe/trunk/lib/Frontend/ASTUnit.cpp >> cfe/trunk/lib/Frontend/ChainedIncludesSource.cpp >> cfe/trunk/lib/Frontend/CompilerInstance.cpp >> cfe/trunk/lib/Serialization/ASTReader.cpp >> >> Modified: cfe/trunk/include/clang/Serialization/ASTReader.h >> URL: >> http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Serialization/ASTReader.h?rev=166449&r1=166448&r2=166449&view=diff >> ============================================================================== >> --- cfe/trunk/include/clang/Serialization/ASTReader.h (original) >> +++ cfe/trunk/include/clang/Serialization/ASTReader.h Mon Oct 22 18:51:00 >> 2012 >> @@ -107,7 +107,8 @@ >> /// >> /// \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 @@ >> /// \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 @@ >> /// \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 @@ >> : 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 @@ >> >> /// \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 @@ >> >> ASTReadResult ReadASTCore(StringRef FileName, ModuleKind Type, >> ModuleFile *ImportedBy, >> - llvm::SmallVectorImpl<ModuleFile *> &Loaded); >> + llvm::SmallVectorImpl<ModuleFile *> &Loaded, >> + unsigned ClientLoadCapabilities); >> ASTReadResult ReadControlBlock(ModuleFile &F, >> - llvm::SmallVectorImpl<ModuleFile *> >> &Loaded); >> + llvm::SmallVectorImpl<ModuleFile *> >> &Loaded, >> + unsigned ClientLoadCapabilities); >> bool ReadASTBlock(ModuleFile &F); >> - bool CheckPredefinesBuffers(); >> + bool CheckPredefinesBuffers(bool Complain); >> bool ParseLineTable(ModuleFile &F, SmallVectorImpl<uint64_t> &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 @@ >> >> 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. >> >> Modified: cfe/trunk/lib/Frontend/ASTUnit.cpp >> URL: >> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/ASTUnit.cpp?rev=166449&r1=166448&r2=166449&view=diff >> ============================================================================== >> --- cfe/trunk/lib/Frontend/ASTUnit.cpp (original) >> +++ cfe/trunk/lib/Frontend/ASTUnit.cpp Mon Oct 22 18:51:00 2012 >> @@ -524,7 +524,8 @@ >> 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 @@ >> } >> >> 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 @@ >> 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 @@ >> 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; >> >> >> Modified: cfe/trunk/lib/Frontend/ChainedIncludesSource.cpp >> URL: >> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/ChainedIncludesSource.cpp?rev=166449&r1=166448&r2=166449&view=diff >> ============================================================================== >> --- cfe/trunk/lib/Frontend/ChainedIncludesSource.cpp (original) >> +++ cfe/trunk/lib/Frontend/ChainedIncludesSource.cpp Mon Oct 22 18:51:00 2012 >> @@ -39,7 +39,8 @@ >> 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()); >> >> Modified: cfe/trunk/lib/Frontend/CompilerInstance.cpp >> URL: >> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/CompilerInstance.cpp?rev=166449&r1=166448&r2=166449&view=diff >> ============================================================================== >> --- cfe/trunk/lib/Frontend/CompilerInstance.cpp (original) >> +++ cfe/trunk/lib/Frontend/CompilerInstance.cpp Mon Oct 22 18:51:00 2012 >> @@ -343,7 +343,8 @@ >> static_cast<ASTDeserializationListener >> *>(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 @@ >> >> // 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; >> >> >> Modified: cfe/trunk/lib/Serialization/ASTReader.cpp >> URL: >> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTReader.cpp?rev=166449&r1=166448&r2=166449&view=diff >> ============================================================================== >> --- cfe/trunk/lib/Serialization/ASTReader.cpp (original) >> +++ cfe/trunk/lib/Serialization/ASTReader.cpp Mon Oct 22 18:51:00 2012 >> @@ -65,27 +65,31 @@ >> >> 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 @@ >> #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 @@ >> } >> >> 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 @@ >> } >> >> 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 @@ >> 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 @@ >> 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 @@ >> 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 @@ >> } >> >> if (ConflictPos != CmdLineLines.end()) { >> + if (!Complain) >> + return true; >> + >> Reader.Diag(diag::warn_cmdline_conflicting_macro_def) >> << MacroName; >> >> @@ -398,10 +415,16 @@ >> 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<FileID, StringRef::size_type> MacroLoc = >> FindMacro(Buffers, Missing); >> @@ -426,7 +449,8 @@ >> 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 @@ >> // 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 @@ >> } >> >> /// \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 @@ >> } >> >> llvm::PointerIntPair<const FileEntry *, 1, bool> >> -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 @@ >> } >> >> 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 @@ >> || 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 @@ >> return Filename; >> } >> >> -ASTReader::ASTReadResult ASTReader::ReadControlBlock(ModuleFile &F, >> - llvm::SmallVectorImpl<ModuleFile *> &Loaded) { >> +ASTReader::ASTReadResult >> +ASTReader::ReadControlBlock(ModuleFile &F, >> + llvm::SmallVectorImpl<ModuleFile *> &Loaded, >> + unsigned ClientLoadCapabilities) { >> llvm::BitstreamCursor &Stream = F.Stream; >> >> if (Stream.EnterSubBlock(CONTROL_BLOCK_ID)) { >> @@ -1841,8 +1873,9 @@ >> >> // 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 @@ >> &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 @@ >> 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 @@ >> 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 @@ >> 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 @@ >> 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 @@ >> } >> >> 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<ModuleFile *, 4> 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 @@ >> } >> >> // 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 @@ >> return Success; >> } >> >> -ASTReader::ASTReadResult ASTReader::ReadASTCore(StringRef FileName, >> - ModuleKind Type, >> - ModuleFile *ImportedBy, >> - llvm::SmallVectorImpl<ModuleFile *> &Loaded) { >> +ASTReader::ASTReadResult >> +ASTReader::ReadASTCore(StringRef FileName, >> + ModuleKind Type, >> + ModuleFile *ImportedBy, >> + llvm::SmallVectorImpl<ModuleFile *> &Loaded, >> + unsigned ClientLoadCapabilities) { >> ModuleFile *M; >> bool NewModule; >> std::string ErrorStr; >> @@ -3042,7 +3087,7 @@ >> } >> break; >> case CONTROL_BLOCK_ID: >> - switch (ReadControlBlock(F, Loaded)) { >> + switch (ReadControlBlock(F, Loaded, ClientLoadCapabilities)) { >> case Success: >> break; >> >> @@ -3584,7 +3629,8 @@ >> /// >> /// \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 @@ >> 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; >> >> >> _______________________________________________ >> cfe-commits mailing list >> [email protected] >> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits _______________________________________________ cfe-commits mailing list [email protected] http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
