Thanks, I hadn't seen that excellent documentation :) -- Sean Silva
On Tue, Oct 23, 2012 at 1:57 PM, Douglas Gregor <[email protected]> wrote: > > 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
