Add -fno-implicit-modules.

If this flag is set, we error out when a module build is required. This is
useful in environments where all required modules are passed via -fmodule-file.

llvm-svn: 230006
This commit is contained in:
Manuel Klimek 2015-02-20 11:44:41 +00:00
parent c95f7e2a7c
commit d2e8b04d61
10 changed files with 70 additions and 0 deletions

View File

@ -210,6 +210,12 @@ Command-line parameters
``-fno-modules-implicit-maps`` ``-fno-modules-implicit-maps``
Suppresses the implicit search for files called ``module.modulemap`` and similar. Instead, module files need to be explicitly specified via ``-fmodule-map-file`` or transitively used. Suppresses the implicit search for files called ``module.modulemap`` and similar. Instead, module files need to be explicitly specified via ``-fmodule-map-file`` or transitively used.
``-fno-implicit-modules``
All modules used by the build must be specified with ``-fmodule-file``.
``-fmodule-file=<file>``
Load the given precompiled module file.
Module Semantics Module Semantics
================ ================

View File

@ -81,6 +81,9 @@ def err_deleted_non_function : Error<
"only functions can have deleted definitions">; "only functions can have deleted definitions">;
def err_module_not_found : Error<"module '%0' not found">, DefaultFatal; def err_module_not_found : Error<"module '%0' not found">, DefaultFatal;
def err_module_not_built : Error<"could not build module '%0'">, DefaultFatal; def err_module_not_built : Error<"could not build module '%0'">, DefaultFatal;
def err_module_build_disabled: Error<
"module '%0' is needed but has not been provided, and implicit use of module "
"files is disabled">, DefaultFatal;
def err_module_lock_failure : Error< def err_module_lock_failure : Error<
"could not acquire lock file for module '%0'">, DefaultFatal; "could not acquire lock file for module '%0'">, DefaultFatal;
def err_module_lock_timeout : Error< def err_module_lock_timeout : Error<

View File

@ -128,6 +128,7 @@ LANGOPT(ModulesSearchAll , 1, 1, "search even non-imported modules to find unre
COMPATIBLE_LANGOPT(ModulesStrictDeclUse, 1, 0, "require declaration of module uses and all headers to be in modules") COMPATIBLE_LANGOPT(ModulesStrictDeclUse, 1, 0, "require declaration of module uses and all headers to be in modules")
LANGOPT(ModulesErrorRecovery, 1, 1, "automatically import modules as needed when performing error recovery") LANGOPT(ModulesErrorRecovery, 1, 1, "automatically import modules as needed when performing error recovery")
BENIGN_LANGOPT(ModulesImplicitMaps, 1, 1, "use files called module.modulemap implicitly as module maps") BENIGN_LANGOPT(ModulesImplicitMaps, 1, 1, "use files called module.modulemap implicitly as module maps")
BENIGN_LANGOPT(ImplicitModules, 1, 1, "build modules that are not specified via -fmodule-file")
COMPATIBLE_LANGOPT(Optimize , 1, 0, "__OPTIMIZE__ predefined macro") COMPATIBLE_LANGOPT(Optimize , 1, 0, "__OPTIMIZE__ predefined macro")
COMPATIBLE_LANGOPT(OptimizeSize , 1, 0, "__OPTIMIZE_SIZE__ predefined macro") COMPATIBLE_LANGOPT(OptimizeSize , 1, 0, "__OPTIMIZE_SIZE__ predefined macro")
LANGOPT(Static , 1, 0, "__STATIC__ predefined macro (as opposed to __DYNAMIC__)") LANGOPT(Static , 1, 0, "__STATIC__ predefined macro (as opposed to __DYNAMIC__)")

View File

@ -705,6 +705,9 @@ def fmodules_implicit_maps :
def fno_modules_implicit_maps : def fno_modules_implicit_maps :
Flag <["-"], "fno-modules-implicit-maps">, Flag <["-"], "fno-modules-implicit-maps">,
Group<f_Group>, Flags<[DriverOption, CC1Option]>; Group<f_Group>, Flags<[DriverOption, CC1Option]>;
def fno_implicit_modules :
Flag <["-"], "fno-implicit-modules">,
Group<f_Group>, Flags<[DriverOption, CC1Option]>;
def fretain_comments_from_system_headers : Flag<["-"], "fretain-comments-from-system-headers">, Group<f_Group>, Flags<[CC1Option]>; def fretain_comments_from_system_headers : Flag<["-"], "fretain-comments-from-system-headers">, Group<f_Group>, Flags<[CC1Option]>;
def fmudflapth : Flag<["-"], "fmudflapth">, Group<f_Group>; def fmudflapth : Flag<["-"], "fmudflapth">, Group<f_Group>;
@ -765,6 +768,8 @@ def fno_modules_decluse : Flag <["-"], "fno-modules-decluse">, Group<f_Group>,
Flags<[DriverOption]>; Flags<[DriverOption]>;
def fno_modules_strict_decluse : Flag <["-"], "fno-strict-modules-decluse">, Group<f_Group>, def fno_modules_strict_decluse : Flag <["-"], "fno-strict-modules-decluse">, Group<f_Group>,
Flags<[DriverOption]>; Flags<[DriverOption]>;
def fimplicit_modules : Flag <["-"], "fimplicit-modules">, Group<f_Group>,
Flags<[DriverOption]>;
def fno_ms_extensions : Flag<["-"], "fno-ms-extensions">, Group<f_Group>; def fno_ms_extensions : Flag<["-"], "fno-ms-extensions">, Group<f_Group>;
def fno_ms_compatibility : Flag<["-"], "fno-ms-compatibility">, Group<f_Group>; def fno_ms_compatibility : Flag<["-"], "fno-ms-compatibility">, Group<f_Group>;
def fno_delayed_template_parsing : Flag<["-"], "fno-delayed-template-parsing">, Group<f_Group>; def fno_delayed_template_parsing : Flag<["-"], "fno-delayed-template-parsing">, Group<f_Group>;

View File

@ -3925,6 +3925,12 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
CmdArgs.push_back("-fmodules-strict-decluse"); CmdArgs.push_back("-fmodules-strict-decluse");
} }
// -fno-implicit-modules turns off implicitly compiling modules on demand.
if (!Args.hasFlag(options::OPT_fimplicit_modules,
options::OPT_fno_implicit_modules)) {
CmdArgs.push_back("-fno-implicit-modules");
}
// -fmodule-name specifies the module that is currently being built (or // -fmodule-name specifies the module that is currently being built (or
// used for header checking by -fmodule-maps). // used for header checking by -fmodule-maps).
Args.AddLastArg(CmdArgs, options::OPT_fmodule_name); Args.AddLastArg(CmdArgs, options::OPT_fmodule_name);

View File

@ -1378,6 +1378,12 @@ CompilerInstance::loadModule(SourceLocation ImportLoc,
auto Override = ModuleFileOverrides.find(ModuleName); auto Override = ModuleFileOverrides.find(ModuleName);
bool Explicit = Override != ModuleFileOverrides.end(); bool Explicit = Override != ModuleFileOverrides.end();
if (!Explicit && !getLangOpts().ImplicitModules) {
getDiagnostics().Report(ModuleNameLoc, diag::err_module_build_disabled)
<< ModuleName;
ModuleBuildFailed = true;
return ModuleLoadResult();
}
std::string ModuleFileName = std::string ModuleFileName =
Explicit ? Override->second Explicit ? Override->second

View File

@ -1513,6 +1513,7 @@ static void ParseLangArgs(LangOptions &Opts, ArgList &Args, InputKind IK,
Opts.ModulesErrorRecovery = !Args.hasArg(OPT_fno_modules_error_recovery); Opts.ModulesErrorRecovery = !Args.hasArg(OPT_fno_modules_error_recovery);
Opts.ModulesImplicitMaps = Args.hasFlag(OPT_fmodules_implicit_maps, Opts.ModulesImplicitMaps = Args.hasFlag(OPT_fmodules_implicit_maps,
OPT_fno_modules_implicit_maps, true); OPT_fno_modules_implicit_maps, true);
Opts.ImplicitModules = !Args.hasArg(OPT_fno_implicit_modules);
Opts.CharIsSigned = Opts.OpenCL || !Args.hasArg(OPT_fno_signed_char); Opts.CharIsSigned = Opts.OpenCL || !Args.hasArg(OPT_fno_signed_char);
Opts.WChar = Opts.CPlusPlus && !Args.hasArg(OPT_fno_wchar); Opts.WChar = Opts.CPlusPlus && !Args.hasArg(OPT_fno_wchar);
Opts.ShortWChar = Args.hasFlag(OPT_fshort_wchar, OPT_fno_short_wchar, false); Opts.ShortWChar = Args.hasFlag(OPT_fshort_wchar, OPT_fno_short_wchar, false);

View File

@ -0,0 +1,6 @@
#ifndef B_H
#define B_H
int b;
#endif

View File

@ -0,0 +1,3 @@
module "b" {
header "b.h"
}

View File

@ -0,0 +1,33 @@
// RUN: rm -rf %t
// Produce an error if a module is needed, but not found.
// RUN: %clang_cc1 -x c++ -std=c++11 -fmodules -fmodules-cache-path=%t \
// RUN: -fmodule-map-file=%S/Inputs/no-implicit-builds/b.modulemap \
// RUN: -fno-implicit-modules %s -verify
// Compile the module and put it into the cache.
// RUN: %clang_cc1 -x c++ -std=c++11 -fmodules -fmodules-cache-path=%t \
// RUN: -fmodule-map-file=%S/Inputs/no-implicit-builds/b.modulemap \
// RUN: %s -Rmodule-build 2>&1 | FileCheck --check-prefix=CHECK-CACHE-BUILD %s
// CHECK-CACHE-BUILD: {{building module 'b'}}
// Produce an error if a module is found in the cache but implicit modules is off.
// Note that the command line must match the command line for the first check, otherwise
// this check might not find the module in the cache and trivially succeed.
// RUN: %clang_cc1 -x c++ -std=c++11 -fmodules -fmodules-cache-path=%t \
// RUN: -fmodule-map-file=%S/Inputs/no-implicit-builds/b.modulemap \
// RUN: %s -Rmodule-build -fno-implicit-modules -verify
// Verify that we can still pass the module via -fmodule-file when implicit modules
// are switched off:
// - First, explicitly compile the module:
// RUN: %clang_cc1 -x c++ -std=c++11 -fmodules -fmodule-name=b -o %t/b.pcm \
// RUN: -emit-module %S/Inputs/no-implicit-builds/b.modulemap \
// RUN: -fno-implicit-modules
//
// - Next, verify that we can load it:
// RUN: %clang_cc1 -x c++ -std=c++11 -fmodules -fmodule-file=%t/b.pcm \
// RUN: -fmodule-map-file=%S/Inputs/no-implicit-builds/b.modulemap \
// RUN: -fno-implicit-modules %s
#include "Inputs/no-implicit-builds/b.h" // expected-error {{is needed but has not been provided}}