Author: rsmith Date: Wed Nov 4 18:54:55 2015 New Revision: 252114 URL: http://llvm.org/viewvc/llvm-project?rev=252114&view=rev Log: [modules] If we're given a module file, via -fmodule-file=, for a module, but we can't load that file due to a configuration mismatch, and implicit module building is disabled, and the user turns off the error-by-default warning for that situation, then fall back to textual inclusion for the module rather than giving an error if any of its headers are included.
Modified: cfe/trunk/include/clang/Basic/Module.h cfe/trunk/lib/Basic/Module.cpp cfe/trunk/lib/Frontend/CompilerInstance.cpp cfe/trunk/lib/Serialization/ASTReader.cpp cfe/trunk/test/Modules/merge-target-features.cpp Modified: cfe/trunk/include/clang/Basic/Module.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/Module.h?rev=252114&r1=252113&r2=252114&view=diff ============================================================================== --- cfe/trunk/include/clang/Basic/Module.h (original) +++ cfe/trunk/include/clang/Basic/Module.h Wed Nov 4 18:54:55 2015 @@ -152,6 +152,9 @@ public: /// \brief Whether this module is missing a feature from \c Requirements. unsigned IsMissingRequirement : 1; + /// \brief Whether we tried and failed to load a module file for this module. + unsigned HasIncompatibleModuleFile : 1; + /// \brief Whether this module is available in the current translation unit. /// /// If the module is missing headers or does not meet all requirements then Modified: cfe/trunk/lib/Basic/Module.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Basic/Module.cpp?rev=252114&r1=252113&r2=252114&view=diff ============================================================================== --- cfe/trunk/lib/Basic/Module.cpp (original) +++ cfe/trunk/lib/Basic/Module.cpp Wed Nov 4 18:54:55 2015 @@ -28,11 +28,12 @@ Module::Module(StringRef Name, SourceLoc bool IsFramework, bool IsExplicit, unsigned VisibilityID) : Name(Name), DefinitionLoc(DefinitionLoc), Parent(Parent), Directory(), Umbrella(), Signature(0), ASTFile(nullptr), VisibilityID(VisibilityID), - IsMissingRequirement(false), IsAvailable(true), IsFromModuleFile(false), - IsFramework(IsFramework), IsExplicit(IsExplicit), IsSystem(false), - IsExternC(false), IsInferred(false), InferSubmodules(false), - InferExplicitSubmodules(false), InferExportWildcard(false), - ConfigMacrosExhaustive(false), NameVisibility(Hidden) { + IsMissingRequirement(false), HasIncompatibleModuleFile(false), + IsAvailable(true), IsFromModuleFile(false), IsFramework(IsFramework), + IsExplicit(IsExplicit), IsSystem(false), IsExternC(false), + IsInferred(false), InferSubmodules(false), InferExplicitSubmodules(false), + InferExportWildcard(false), ConfigMacrosExhaustive(false), + NameVisibility(Hidden) { if (Parent) { if (!Parent->isAvailable()) IsAvailable = false; Modified: cfe/trunk/lib/Frontend/CompilerInstance.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/CompilerInstance.cpp?rev=252114&r1=252113&r2=252114&view=diff ============================================================================== --- cfe/trunk/lib/Frontend/CompilerInstance.cpp (original) +++ cfe/trunk/lib/Frontend/CompilerInstance.cpp Wed Nov 4 18:54:55 2015 @@ -1327,6 +1327,17 @@ bool CompilerInstance::loadModuleFile(St } LoadedModules.clear(); } + + void markAllUnavailable() { + for (auto *II : LoadedModules) { + if (Module *M = CI.getPreprocessor() + .getHeaderSearchInfo() + .getModuleMap() + .findModule(II->getName())) + M->HasIncompatibleModuleFile = true; + } + LoadedModules.clear(); + } }; // If we don't already have an ASTReader, create one now. @@ -1343,15 +1354,18 @@ bool CompilerInstance::loadModuleFile(St SourceLocation(), ASTReader::ARR_ConfigurationMismatch)) { case ASTReader::Success: - // We successfully loaded the module file; remember the set of provided - // modules so that we don't try to load implicit modules for them. - ListenerRef.registerAll(); - return true; + // We successfully loaded the module file; remember the set of provided + // modules so that we don't try to load implicit modules for them. + ListenerRef.registerAll(); + return true; case ASTReader::ConfigurationMismatch: // Ignore unusable module files. getDiagnostics().Report(SourceLocation(), diag::warn_module_config_mismatch) << FileName; + // All modules provided by any files we tried and failed to load are now + // unavailable; includes of those modules should now be handled textually. + ListenerRef.markAllUnavailable(); return true; default: @@ -1407,6 +1421,12 @@ CompilerInstance::loadModule(SourceLocat std::string ModuleFileName = PP->getHeaderSearchInfo().getModuleFileName(Module); if (ModuleFileName.empty()) { + if (Module->HasIncompatibleModuleFile) { + // We tried and failed to load a module file for this module. Fall + // back to textual inclusion for its headers. + return ModuleLoadResult(nullptr, /*missingExpected*/true); + } + getDiagnostics().Report(ModuleNameLoc, diag::err_module_build_disabled) << ModuleName; ModuleBuildFailed = true; Modified: cfe/trunk/lib/Serialization/ASTReader.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTReader.cpp?rev=252114&r1=252113&r2=252114&view=diff ============================================================================== --- cfe/trunk/lib/Serialization/ASTReader.cpp (original) +++ cfe/trunk/lib/Serialization/ASTReader.cpp Wed Nov 4 18:54:55 2015 @@ -2151,6 +2151,7 @@ ASTReader::ReadControlBlock(ModuleFile & const ModuleFile *ImportedBy, unsigned ClientLoadCapabilities) { BitstreamCursor &Stream = F.Stream; + ASTReadResult Result = Success; if (Stream.EnterSubBlock(CONTROL_BLOCK_ID)) { Error("malformed block record in AST file"); @@ -2211,7 +2212,7 @@ ASTReader::ReadControlBlock(ModuleFile & } } - return Success; + return Result; } case llvm::BitstreamEntry::SubBlock: @@ -2239,16 +2240,21 @@ ASTReader::ReadControlBlock(ModuleFile & bool AllowCompatibleConfigurationMismatch = F.Kind == MK_ExplicitModule; - auto Result = ReadOptionsBlock(Stream, ClientLoadCapabilities, - AllowCompatibleConfigurationMismatch, - *Listener, SuggestedPredefines); + Result = ReadOptionsBlock(Stream, ClientLoadCapabilities, + AllowCompatibleConfigurationMismatch, + *Listener, SuggestedPredefines); if (Result == Failure) { Error("malformed block record in AST file"); return Result; } - if (!DisableValidation && Result != Success && - (Result != ConfigurationMismatch || !AllowConfigurationMismatch)) + if (DisableValidation || + (AllowConfigurationMismatch && Result == ConfigurationMismatch)) + Result = Success; + + // If we've diagnosed a problem, we're done. + if (Result != Success && + isDiagnosedResult(Result, ClientLoadCapabilities)) return Result; } else if (Stream.SkipBlock()) { Error("malformed block record in AST file"); Modified: cfe/trunk/test/Modules/merge-target-features.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/merge-target-features.cpp?rev=252114&r1=252113&r2=252114&view=diff ============================================================================== --- cfe/trunk/test/Modules/merge-target-features.cpp (original) +++ cfe/trunk/test/Modules/merge-target-features.cpp Wed Nov 4 18:54:55 2015 @@ -20,7 +20,9 @@ // RUN: -target-cpu i386 \ // RUN: -fsyntax-only merge-target-features.cpp 2>&1 \ // RUN: | FileCheck --check-prefix=SUBSET %s +// SUBSET-NOT: error: // SUBSET: error: {{.*}} configuration mismatch +// SUBSET-NOT: error: // // RUN: %clang_cc1 -fmodules -x c++ -fmodules-cache-path=%t \ // RUN: -iquote Inputs/merge-target-features \ @@ -56,7 +58,9 @@ // RUN: -target-cpu i386 -target-feature +cx16 \ // RUN: -fsyntax-only merge-target-features.cpp 2>&1 \ // RUN: | FileCheck --check-prefix=MISMATCH %s +// MISMATCH-NOT: error: // MISMATCH: error: {{.*}} configuration mismatch +// MISMATCH-NOT: error: #include "foo.h" _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits