Unrevert r280035 now that the clang-cl bug it exposed has been fixed by
r280133. Original commit message:
C++ Modules TS: driver support for building modules.
This works as follows: we add --precompile to the existing gamut of options for
specifying how far to go when compiling an input (-E, -c, -S, etc.). This flag
specifies that an input is taken to the precompilation step and no further, and
this can be specified when building a .pcm from a module interface or when
building a .pch from a header file.
The .cppm extension (and some related extensions) are implicitly recognized as
C++ module interface files. If --precompile is /not/ specified, the file is
compiled (via a .pcm) to a .o file containing the code for the module (and then
potentially also assembled and linked, if -S, -c, etc. are not specified). We
do not yet suppress the emission of object code for other users of the module
interface, so for now this will only work if everything in the .cppm file has
vague linkage.
As with the existing support for module-map modules, prebuilt modules can be
provided as compiler inputs either via the -fmodule-file= command-line argument
or via files named ModuleName.pcm in one of the directories specified via
-fprebuilt-module-path=.
This also exposes the -fmodules-ts cc1 flag in the driver. This is still
experimental, and in particular, the concrete syntax is subject to change as
the Modules TS evolves in the C++ committee. Unlike -fmodules, this flag does
not enable support for implicitly loading module maps nor building modules via
the module cache, but those features can be turned on separately and used in
conjunction with the Modules TS support.
llvm-svn: 280134
diff --git a/clang/lib/Driver/Driver.cpp b/clang/lib/Driver/Driver.cpp
index a1adb67..b2cd4f7 100644
--- a/clang/lib/Driver/Driver.cpp
+++ b/clang/lib/Driver/Driver.cpp
@@ -177,6 +177,10 @@
(PhaseArg = DAL.getLastArg(options::OPT__SLASH_P))) {
FinalPhase = phases::Preprocess;
+ // --precompile only runs up to precompilation.
+ } else if ((PhaseArg = DAL.getLastArg(options::OPT__precompile))) {
+ FinalPhase = phases::Precompile;
+
// -{fsyntax-only,-analyze,emit-ast} only run up to the compiler.
} else if ((PhaseArg = DAL.getLastArg(options::OPT_fsyntax_only)) ||
(PhaseArg = DAL.getLastArg(options::OPT_module_file_info)) ||
@@ -1814,9 +1818,9 @@
return C.MakeAction<PreprocessJobAction>(Input, OutputTy);
}
case phases::Precompile: {
- assert(onlyPrecompileType(Input->getType()) &&
- "asked to precompile non-precompilable type");
- types::ID OutputTy = types::TY_PCH;
+ types::ID OutputTy = getPrecompiledType(Input->getType());
+ assert(OutputTy != types::TY_INVALID &&
+ "Cannot precompile this input type!");
if (Args.hasArg(options::OPT_fsyntax_only)) {
// Syntax checks should not emit a PCH file
OutputTy = types::TY_Nothing;
diff --git a/clang/lib/Driver/Tools.cpp b/clang/lib/Driver/Tools.cpp
index f4dd61a..129b25c 100644
--- a/clang/lib/Driver/Tools.cpp
+++ b/clang/lib/Driver/Tools.cpp
@@ -3970,6 +3970,8 @@
if (JA.getType() == types::TY_Nothing)
CmdArgs.push_back("-fsyntax-only");
+ else if (JA.getType() == types::TY_ModuleFile)
+ CmdArgs.push_back("-emit-module-interface");
else if (UsePCH)
CmdArgs.push_back("-emit-pch");
else
@@ -5380,20 +5382,26 @@
// -fmodules enables the use of precompiled modules (off by default).
// Users can pass -fno-cxx-modules to turn off modules support for
// C++/Objective-C++ programs.
- bool HaveModules = false;
+ bool HaveClangModules = false;
if (Args.hasFlag(options::OPT_fmodules, options::OPT_fno_modules, false)) {
bool AllowedInCXX = Args.hasFlag(options::OPT_fcxx_modules,
options::OPT_fno_cxx_modules, true);
if (AllowedInCXX || !types::isCXX(InputType)) {
CmdArgs.push_back("-fmodules");
- HaveModules = true;
+ HaveClangModules = true;
}
}
+ bool HaveAnyModules = HaveClangModules;
+ if (Args.hasArg(options::OPT_fmodules_ts)) {
+ CmdArgs.push_back("-fmodules-ts");
+ HaveAnyModules = true;
+ }
+
// -fmodule-maps enables implicit reading of module map files. By default,
- // this is enabled if we are using precompiled modules.
+ // this is enabled if we are using Clang's flavor of precompiled modules.
if (Args.hasFlag(options::OPT_fimplicit_module_maps,
- options::OPT_fno_implicit_module_maps, HaveModules)) {
+ options::OPT_fno_implicit_module_maps, HaveClangModules)) {
CmdArgs.push_back("-fimplicit-module-maps");
}
@@ -5413,9 +5421,10 @@
// -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");
- } else if (HaveModules) {
+ options::OPT_fno_implicit_modules, HaveClangModules)) {
+ if (HaveAnyModules)
+ CmdArgs.push_back("-fno-implicit-modules");
+ } else if (HaveAnyModules) {
// -fmodule-cache-path specifies where our implicitly-built module files
// should be written.
SmallString<128> Path;
@@ -5439,7 +5448,7 @@
CmdArgs.push_back(Args.MakeArgString(Path));
}
- if (HaveModules) {
+ if (HaveAnyModules) {
// -fprebuilt-module-path specifies where to load the prebuilt module files.
for (const Arg *A : Args.filtered(options::OPT_fprebuilt_module_path))
CmdArgs.push_back(Args.MakeArgString(
@@ -5455,14 +5464,14 @@
Args.AddAllArgs(CmdArgs, options::OPT_fmodule_map_file);
// -fmodule-file can be used to specify files containing precompiled modules.
- if (HaveModules)
+ if (HaveAnyModules)
Args.AddAllArgs(CmdArgs, options::OPT_fmodule_file);
else
Args.ClaimAllArgs(options::OPT_fmodule_file);
// When building modules and generating crashdumps, we need to dump a module
// dependency VFS alongside the output.
- if (HaveModules && C.isForDiagnostics()) {
+ if (HaveClangModules && C.isForDiagnostics()) {
SmallString<128> VFSDir(Output.getFilename());
llvm::sys::path::replace_extension(VFSDir, ".cache");
// Add the cache directory as a temp so the crash diagnostics pick it up.
@@ -5473,7 +5482,7 @@
CmdArgs.push_back(Args.MakeArgString(VFSDir));
}
- if (HaveModules)
+ if (HaveClangModules)
Args.AddLastArg(CmdArgs, options::OPT_fmodules_user_build_path);
// Pass through all -fmodules-ignore-macro arguments.
@@ -6014,7 +6023,7 @@
// nice to enable this when doing a crashdump for modules as well.
if (Args.hasFlag(options::OPT_frewrite_includes,
options::OPT_fno_rewrite_includes, false) ||
- (C.isForDiagnostics() && !HaveModules))
+ (C.isForDiagnostics() && !HaveAnyModules))
CmdArgs.push_back("-frewrite-includes");
// Only allow -traditional or -traditional-cpp outside in preprocessing modes.
diff --git a/clang/lib/Driver/Types.cpp b/clang/lib/Driver/Types.cpp
index 1588c94..4140381 100644
--- a/clang/lib/Driver/Types.cpp
+++ b/clang/lib/Driver/Types.cpp
@@ -44,6 +44,14 @@
return getInfo(Id).PreprocessedType;
}
+types::ID types::getPrecompiledType(ID Id) {
+ if (strchr(getInfo(Id).Flags, 'm'))
+ return TY_ModuleFile;
+ if (onlyPrecompileType(Id))
+ return TY_PCH;
+ return TY_INVALID;
+}
+
const char *types::getTypeTempSuffix(ID Id, bool CLMode) {
if (Id == TY_Object && CLMode)
return "obj";
@@ -95,6 +103,7 @@
case TY_ObjCHeader: case TY_PP_ObjCHeader:
case TY_CXXHeader: case TY_PP_CXXHeader:
case TY_ObjCXXHeader: case TY_PP_ObjCXXHeader:
+ case TY_CXXModule: case TY_PP_CXXModule:
case TY_AST: case TY_ModuleFile:
case TY_LLVM_IR: case TY_LLVM_BC:
return true;
@@ -123,6 +132,7 @@
case TY_ObjCXX: case TY_PP_ObjCXX: case TY_PP_ObjCXX_Alias:
case TY_CXXHeader: case TY_PP_CXXHeader:
case TY_ObjCXXHeader: case TY_PP_ObjCXXHeader:
+ case TY_CXXModule: case TY_PP_CXXModule:
case TY_CUDA: case TY_PP_CUDA: case TY_CUDA_DEVICE:
return true;
}
@@ -183,6 +193,7 @@
.Case("ads", TY_Ada)
.Case("asm", TY_PP_Asm)
.Case("ast", TY_AST)
+ .Case("ccm", TY_CXXModule)
.Case("cpp", TY_CXX)
.Case("CPP", TY_CXX)
.Case("c++", TY_CXX)
@@ -200,11 +211,15 @@
.Case("FPP", TY_Fortran)
.Case("gch", TY_PCH)
.Case("hpp", TY_CXXHeader)
+ .Case("iim", TY_PP_CXXModule)
.Case("lib", TY_Object)
.Case("mii", TY_PP_ObjCXX)
.Case("obj", TY_Object)
.Case("pch", TY_PCH)
.Case("pcm", TY_ModuleFile)
+ .Case("c++m", TY_CXXModule)
+ .Case("cppm", TY_CXXModule)
+ .Case("cxxm", TY_CXXModule)
.Default(TY_INVALID);
}
@@ -226,9 +241,11 @@
P.push_back(phases::Preprocess);
}
- if (onlyPrecompileType(Id)) {
+ if (getPrecompiledType(Id) != TY_INVALID) {
P.push_back(phases::Precompile);
- } else {
+ }
+
+ if (!onlyPrecompileType(Id)) {
if (!onlyAssembleType(Id)) {
P.push_back(phases::Compile);
P.push_back(phases::Backend);