diff options
Diffstat (limited to 'clang/lib/Frontend')
-rw-r--r-- | clang/lib/Frontend/ASTUnit.cpp | 1 | ||||
-rw-r--r-- | clang/lib/Frontend/CompilerInstance.cpp | 69 | ||||
-rw-r--r-- | clang/lib/Frontend/CompilerInvocation.cpp | 2 | ||||
-rw-r--r-- | clang/lib/Frontend/FrontendActions.cpp | 3 |
4 files changed, 65 insertions, 10 deletions
diff --git a/clang/lib/Frontend/ASTUnit.cpp b/clang/lib/Frontend/ASTUnit.cpp index aafbb481f0e..3a34f852d89 100644 --- a/clang/lib/Frontend/ASTUnit.cpp +++ b/clang/lib/Frontend/ASTUnit.cpp @@ -2805,6 +2805,7 @@ const FileEntry *ASTUnit::getPCHFile() { switch (M.Kind) { case serialization::MK_ImplicitModule: case serialization::MK_ExplicitModule: + case serialization::MK_PrebuiltModule: return true; // skip dependencies. case serialization::MK_PCH: Mod = &M; diff --git a/clang/lib/Frontend/CompilerInstance.cpp b/clang/lib/Frontend/CompilerInstance.cpp index 3d37a829000..89907f11719 100644 --- a/clang/lib/Frontend/CompilerInstance.cpp +++ b/clang/lib/Frontend/CompilerInstance.cpp @@ -1436,7 +1436,25 @@ CompilerInstance::loadModule(SourceLocation ImportLoc, } else { // Search for a module with the given name. Module = PP->getHeaderSearchInfo().lookupModule(ModuleName); - if (!Module) { + HeaderSearchOptions &HSOpts = + PP->getHeaderSearchInfo().getHeaderSearchOpts(); + + std::string ModuleFileName; + bool LoadFromPrebuiltModulePath = false; + // We try to load the module from the prebuilt module paths. If not + // successful, we then try to find it in the module cache. + if (!HSOpts.PrebuiltModulePaths.empty()) { + // Load the module from the prebuilt module path. + ModuleFileName = PP->getHeaderSearchInfo().getModuleFileName( + ModuleName, "", /*UsePrebuiltPath*/ true); + if (!ModuleFileName.empty()) + LoadFromPrebuiltModulePath = true; + } + if (!LoadFromPrebuiltModulePath && Module) { + // Load the module from the module cache. + ModuleFileName = PP->getHeaderSearchInfo().getModuleFileName(Module); + } else if (!LoadFromPrebuiltModulePath) { + // We can't find a module, error out here. getDiagnostics().Report(ModuleNameLoc, diag::err_module_not_found) << ModuleName << SourceRange(ImportLoc, ModuleNameLoc); @@ -1444,10 +1462,8 @@ CompilerInstance::loadModule(SourceLocation ImportLoc, return ModuleLoadResult(); } - std::string ModuleFileName = - PP->getHeaderSearchInfo().getModuleFileName(Module); if (ModuleFileName.empty()) { - if (Module->HasIncompatibleModuleFile) { + if (Module && 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); @@ -1468,16 +1484,46 @@ CompilerInstance::loadModule(SourceLocation ImportLoc, Timer.init("Loading " + ModuleFileName, *FrontendTimerGroup); llvm::TimeRegion TimeLoading(FrontendTimerGroup ? &Timer : nullptr); - // Try to load the module file. - unsigned ARRFlags = ASTReader::ARR_OutOfDate | ASTReader::ARR_Missing; + // Try to load the module file. If we are trying to load from the prebuilt + // module path, we don't have the module map files and don't know how to + // rebuild modules. + unsigned ARRFlags = LoadFromPrebuiltModulePath ? + ASTReader::ARR_ConfigurationMismatch : + ASTReader::ARR_OutOfDate | ASTReader::ARR_Missing; switch (ModuleManager->ReadAST(ModuleFileName, + LoadFromPrebuiltModulePath ? + serialization::MK_PrebuiltModule : serialization::MK_ImplicitModule, - ImportLoc, ARRFlags)) { - case ASTReader::Success: + ImportLoc, + ARRFlags)) { + case ASTReader::Success: { + if (LoadFromPrebuiltModulePath && !Module) { + Module = PP->getHeaderSearchInfo().lookupModule(ModuleName); + if (!Module || !Module->getASTFile() || + FileMgr->getFile(ModuleFileName) != Module->getASTFile()) { + // Error out if Module does not refer to the file in the prebuilt + // module path. + getDiagnostics().Report(ModuleNameLoc, diag::err_module_prebuilt) + << ModuleName; + ModuleBuildFailed = true; + KnownModules[Path[0].first] = nullptr; + return ModuleLoadResult(); + } + } break; + } case ASTReader::OutOfDate: case ASTReader::Missing: { + if (LoadFromPrebuiltModulePath) { + // We can't rebuild the module without a module map. Since ReadAST + // already produces diagnostics for these two cases, we simply + // error out here. + ModuleBuildFailed = true; + KnownModules[Path[0].first] = nullptr; + return ModuleLoadResult(); + } + // The module file is missing or out-of-date. Build it. assert(Module && "missing module file"); // Check whether there is a cycle in the module graph. @@ -1528,8 +1574,13 @@ CompilerInstance::loadModule(SourceLocation ImportLoc, break; } - case ASTReader::VersionMismatch: case ASTReader::ConfigurationMismatch: + if (LoadFromPrebuiltModulePath) + getDiagnostics().Report(SourceLocation(), + diag::warn_module_config_mismatch) + << ModuleFileName; + // Fall through to error out. + case ASTReader::VersionMismatch: case ASTReader::HadErrors: ModuleLoader::HadFatalFailure = true; // FIXME: The ASTReader will already have complained, but can we shoehorn diff --git a/clang/lib/Frontend/CompilerInvocation.cpp b/clang/lib/Frontend/CompilerInvocation.cpp index b1e985f077e..69c4593d5f5 100644 --- a/clang/lib/Frontend/CompilerInvocation.cpp +++ b/clang/lib/Frontend/CompilerInvocation.cpp @@ -1368,6 +1368,8 @@ static void ParseHeaderSearchArgs(HeaderSearchOptions &Opts, ArgList &Args) { Opts.ResourceDir = Args.getLastArgValue(OPT_resource_dir); Opts.ModuleCachePath = Args.getLastArgValue(OPT_fmodules_cache_path); Opts.ModuleUserBuildPath = Args.getLastArgValue(OPT_fmodules_user_build_path); + for (const Arg *A : Args.filtered(OPT_fprebuilt_module_path)) + Opts.AddPrebuiltModulePath(A->getValue()); Opts.DisableModuleHash = Args.hasArg(OPT_fdisable_module_hash); Opts.ModulesValidateDiagnosticOptions = !Args.hasArg(OPT_fmodules_disable_diagnostic_validation); diff --git a/clang/lib/Frontend/FrontendActions.cpp b/clang/lib/Frontend/FrontendActions.cpp index d83e98fc31a..706ccea59b8 100644 --- a/clang/lib/Frontend/FrontendActions.cpp +++ b/clang/lib/Frontend/FrontendActions.cpp @@ -391,7 +391,8 @@ GenerateModuleAction::ComputeASTConsumerArguments(CompilerInstance &CI, HeaderSearch &HS = CI.getPreprocessor().getHeaderSearchInfo(); CI.getFrontendOpts().OutputFile = HS.getModuleFileName(CI.getLangOpts().CurrentModule, - ModuleMapForUniquing->getName()); + ModuleMapForUniquing->getName(), + /*UsePrebuiltPath=*/false); } // We use createOutputFile here because this is exposed via libclang, and we |