r358355 - [c++20] Enable driver and frontend support for building and using

Richard Smith via cfe-commits cfe-commits at lists.llvm.org
Sun Apr 14 04:11:37 PDT 2019


Author: rsmith
Date: Sun Apr 14 04:11:37 2019
New Revision: 358355

URL: http://llvm.org/viewvc/llvm-project?rev=358355&view=rev
Log:
[c++20] Enable driver and frontend support for building and using
modules when -std=c++2a is specified.

Added:
    cfe/trunk/test/CXX/module/module.unit/p8.cpp
    cfe/trunk/test/Driver/modules.cpp
Modified:
    cfe/trunk/include/clang/Basic/DiagnosticFrontendKinds.td
    cfe/trunk/lib/Driver/ToolChains/Clang.cpp
    cfe/trunk/lib/Frontend/FrontendActions.cpp
    cfe/trunk/lib/Parse/Parser.cpp

Modified: cfe/trunk/include/clang/Basic/DiagnosticFrontendKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticFrontendKinds.td?rev=358355&r1=358354&r2=358355&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticFrontendKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticFrontendKinds.td Sun Apr 14 04:11:37 2019
@@ -173,10 +173,11 @@ def note_incompatible_analyzer_plugin_ap
 
 def err_module_build_requires_fmodules : Error<
   "module compilation requires '-fmodules'">;
-def err_module_interface_requires_modules_ts : Error<
-  "module interface compilation requires '-fmodules-ts'">;
+def err_module_interface_requires_cpp_modules : Error<
+  "module interface compilation requires '-std=c++2a' or '-fmodules-ts'">;
 def err_header_module_requires_modules : Error<
-  "header module compilation requires '-fmodules' or '-fmodules-ts'">;
+  "header module compilation requires '-fmodules', '-std=c++2a', or "
+  "'-fmodules-ts'">;
 def warn_module_config_mismatch : Warning<
   "module file %0 cannot be loaded due to a configuration mismatch with the current "
   "compilation">, InGroup<DiagGroup<"module-file-config-mismatch">>, DefaultError;

Modified: cfe/trunk/lib/Driver/ToolChains/Clang.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Driver/ToolChains/Clang.cpp?rev=358355&r1=358354&r2=358355&view=diff
==============================================================================
--- cfe/trunk/lib/Driver/ToolChains/Clang.cpp (original)
+++ cfe/trunk/lib/Driver/ToolChains/Clang.cpp Sun Apr 14 04:11:37 2019
@@ -2721,7 +2721,7 @@ static void RenderModulesOptions(Compila
     }
   }
 
-  HaveModules = HaveClangModules;
+  HaveModules |= HaveClangModules;
   if (Args.hasArg(options::OPT_fmodules_ts)) {
     CmdArgs.push_back("-fmodules-ts");
     HaveModules = true;
@@ -4259,7 +4259,8 @@ void Clang::ConstructJob(Compilation &C,
   // If a std is supplied, only add -trigraphs if it follows the
   // option.
   bool ImplyVCPPCXXVer = false;
-  if (Arg *Std = Args.getLastArg(options::OPT_std_EQ, options::OPT_ansi)) {
+  const Arg *Std = Args.getLastArg(options::OPT_std_EQ, options::OPT_ansi);
+  if (Std) {
     if (Std->getOption().matches(options::OPT_ansi))
       if (types::isCXX(InputType))
         CmdArgs.push_back("-std=c++98");
@@ -4696,9 +4697,6 @@ void Clang::ConstructJob(Compilation &C,
   Args.AddLastArg(CmdArgs, options::OPT_fdouble_square_bracket_attributes,
                   options::OPT_fno_double_square_bracket_attributes);
 
-  bool HaveModules = false;
-  RenderModulesOptions(C, D, Args, Input, Output, CmdArgs, HaveModules);
-
   // -faccess-control is default.
   if (Args.hasFlag(options::OPT_fno_access_control,
                    options::OPT_faccess_control, false))
@@ -4765,6 +4763,7 @@ void Clang::ConstructJob(Compilation &C,
   if (ImplyVCPPCXXVer) {
     StringRef LanguageStandard;
     if (const Arg *StdArg = Args.getLastArg(options::OPT__SLASH_std)) {
+      Std = StdArg;
       LanguageStandard = llvm::StringSwitch<StringRef>(StdArg->getValue())
                              .Case("c++14", "-std=c++14")
                              .Case("c++17", "-std=c++17")
@@ -4830,6 +4829,12 @@ void Clang::ConstructJob(Compilation &C,
                                        options::OPT_fno_inline_functions))
     InlineArg->render(Args, CmdArgs);
 
+  // FIXME: Find a better way to determine whether the language has modules
+  // support by default, or just assume that all languages do.
+  bool HaveModules =
+      Std && (Std->containsValue("c++2a") || Std->containsValue("c++latest"));
+  RenderModulesOptions(C, D, Args, Input, Output, CmdArgs, HaveModules);
+
   Args.AddLastArg(CmdArgs, options::OPT_fexperimental_new_pass_manager,
                   options::OPT_fno_experimental_new_pass_manager);
 

Modified: cfe/trunk/lib/Frontend/FrontendActions.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/FrontendActions.cpp?rev=358355&r1=358354&r2=358355&view=diff
==============================================================================
--- cfe/trunk/lib/Frontend/FrontendActions.cpp (original)
+++ cfe/trunk/lib/Frontend/FrontendActions.cpp Sun Apr 14 04:11:37 2019
@@ -221,8 +221,8 @@ GenerateModuleFromModuleMapAction::Creat
 
 bool GenerateModuleInterfaceAction::BeginSourceFileAction(
     CompilerInstance &CI) {
-  if (!CI.getLangOpts().ModulesTS) {
-    CI.getDiagnostics().Report(diag::err_module_interface_requires_modules_ts);
+  if (!CI.getLangOpts().ModulesTS && !CI.getLangOpts().CPlusPlusModules) {
+    CI.getDiagnostics().Report(diag::err_module_interface_requires_cpp_modules);
     return false;
   }
 
@@ -239,7 +239,7 @@ GenerateModuleInterfaceAction::CreateOut
 
 bool GenerateHeaderModuleAction::PrepareToExecuteAction(
     CompilerInstance &CI) {
-  if (!CI.getLangOpts().Modules && !CI.getLangOpts().ModulesTS) {
+  if (!CI.getLangOpts().Modules) {
     CI.getDiagnostics().Report(diag::err_header_module_requires_modules);
     return false;
   }

Modified: cfe/trunk/lib/Parse/Parser.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/Parser.cpp?rev=358355&r1=358354&r2=358355&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/Parser.cpp (original)
+++ cfe/trunk/lib/Parse/Parser.cpp Sun Apr 14 04:11:37 2019
@@ -837,7 +837,7 @@ Parser::ParseExternalDeclaration(ParsedA
     SingleDecl = ParseModuleImport(SourceLocation());
     break;
   case tok::kw_export:
-    if (getLangOpts().ModulesTS) {
+    if (getLangOpts().CPlusPlusModules || getLangOpts().ModulesTS) {
       SingleDecl = ParseExportDeclaration();
       break;
     }

Added: cfe/trunk/test/CXX/module/module.unit/p8.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/module/module.unit/p8.cpp?rev=358355&view=auto
==============================================================================
--- cfe/trunk/test/CXX/module/module.unit/p8.cpp (added)
+++ cfe/trunk/test/CXX/module/module.unit/p8.cpp Sun Apr 14 04:11:37 2019
@@ -0,0 +1,40 @@
+// RUN: echo 'export module foo; export int n;' > %t.cppm
+// RUN: %clang_cc1 -std=c++2a %t.cppm -emit-module-interface -o %t.pcm
+// RUN: %clang_cc1 -std=c++2a -fmodule-file=%t.pcm -verify -DMODE=0 %s
+// RUN: %clang_cc1 -std=c++2a -fmodule-file=%t.pcm -verify -DMODE=1 %s
+// RUN: %clang_cc1 -std=c++2a -fmodule-file=%t.pcm -verify -DMODE=2 %s
+// RUN: %clang_cc1 -std=c++2a -fmodule-file=%t.pcm -verify -DMODE=3 %s
+// RUN: %clang_cc1 -std=c++2a -fmodule-file=%t.pcm -verify -DMODE=4 %s
+// RUN: %clang_cc1 -std=c++2a -fmodule-file=%t.pcm -verify -DMODE=5 %s
+
+#if MODE == 0
+// no module declaration
+
+#elif MODE == 1
+// expected-no-diagnostics
+module foo;
+#define IMPORTED
+
+#elif MODE == 2
+export module foo; // expected-error {{redefinition of module 'foo'}}
+// expected-note-re@* {{module loaded from '{{.*}}.pcm'}}
+#define IMPORTED
+
+#elif MODE == 3
+export module bar;
+
+#elif MODE == 4
+module foo:bar; // expected-error {{not yet supported}}
+#define IMPORTED // FIXME
+
+#elif MODE == 5
+export module foo:bar; // expected-error {{not yet supported}} expected-error {{redefinition}} expected-note@* {{loaded from}}
+#define IMPORTED // FIXME
+
+#endif
+
+int k = n;
+#ifndef IMPORTED
+// expected-error at -2 {{declaration of 'n' must be imported from module 'foo' before it is required}}
+// expected-note@* {{previous}}
+#endif

Added: cfe/trunk/test/Driver/modules.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Driver/modules.cpp?rev=358355&view=auto
==============================================================================
--- cfe/trunk/test/Driver/modules.cpp (added)
+++ cfe/trunk/test/Driver/modules.cpp Sun Apr 14 04:11:37 2019
@@ -0,0 +1,74 @@
+// RUN: rm -rf %t
+// RUN: mkdir %t
+
+// Check compiling a module interface to a .pcm file.
+//
+// RUN: %clang -std=c++2a -x c++-module --precompile %s -o %t/module.pcm -v 2>&1 | FileCheck %s --check-prefix=CHECK-PRECOMPILE
+//
+// CHECK-PRECOMPILE: -cc1 {{.*}} -emit-module-interface
+// CHECK-PRECOMPILE-SAME: -o {{.*}}.pcm
+// CHECK-PRECOMPILE-SAME: -x c++
+// CHECK-PRECOMPILE-SAME: modules.cpp
+
+// Check compiling a .pcm file to a .o file.
+//
+// RUN: %clang -std=c++2a %t/module.pcm -c -o %t/module.pcm.o -v 2>&1 | FileCheck %s --check-prefix=CHECK-COMPILE
+//
+// CHECK-COMPILE: -cc1 {{.*}} -emit-obj
+// CHECK-COMPILE-SAME: -o {{.*}}.pcm.o
+// CHECK-COMPILE-SAME: -x pcm
+// CHECK-COMPILE-SAME: {{.*}}.pcm
+
+// Check use of a .pcm file in another compilation.
+//
+// RUN: %clang -std=c++2a -fmodule-file=%t/module.pcm -Dexport= %s -c -o %t/module.o -v 2>&1 | FileCheck %s --check-prefix=CHECK-USE
+//
+// CHECK-USE: -cc1
+// CHECK-USE-SAME: -emit-obj
+// CHECK-USE-SAME: -fmodule-file={{.*}}.pcm
+// CHECK-USE-SAME: -o {{.*}}.o{{"?}} {{.*}}-x c++
+// CHECK-USE-SAME: modules.cpp
+
+// Check combining precompile and compile steps works.
+//
+// RUN: %clang -std=c++2a -x c++-module %s -c -o %t/module2.pcm.o -v 2>&1 | FileCheck %s --check-prefix=CHECK-PRECOMPILE --check-prefix=CHECK-COMPILE
+
+// Check that .cppm is treated as a module implicitly.
+//
+// RUN: cp %s %t/module.cppm
+// RUN: %clang -std=c++2a --precompile %t/module.cppm -o %t/module.pcm -v 2>&1 | FileCheck %s --check-prefix=CHECK-PRECOMPILE
+
+// Check compiling a header unit to a .pcm file.
+//
+// RUN: echo '#define FOO BAR' > %t/foo.h
+// RUN: %clang -std=c++2a --precompile -x c++-header %t/foo.h -fmodule-name=header -o %t/foo.pcm -v 2>&1 | FileCheck %s --check-prefix=CHECK-HEADER-UNIT
+//
+// CHECK-HEADER-UNIT: -cc1
+// CHECK-HEADER-UNIT-SAME: -emit-header-module
+// CHECK-HEADER-UNIT-SAME: -fmodule-name=header
+// CHECK-HEADER-UNIT-SAME: -o {{.*}}foo.pcm
+// CHECK-HEADER-UNIT-SAME: -x c++-header
+// CHECK-HEADER-UNIT-SAME: foo.h
+
+// Check use of header unit.
+//
+// RUN: %clang -std=c++2a -fmodule-file=%t/module.pcm -fmodule-file=%t/foo.pcm -I%t -DIMPORT -Dexport= %s -E -o - -v 2>&1 | FileCheck %s --check-prefix=CHECK-HEADER-UNIT-USE
+//
+// CHECK-HEADER-UNIT-USE: -cc1
+// CHECK-HEADER-UNIT-USE: -E
+// CHECK-HEADER-UNIT-USE: -fmodule-file={{.*}}module.pcm
+// CHECK-HEADER-UNIT-USE: -fmodule-file={{.*}}foo.pcm
+
+// Note, we use -Dexport= to make this a module implementation unit when building the implementation.
+export module foo;
+
+#ifdef IMPORT
+// CHECK-HEADER-UNIT-USE: FOO;
+FOO;
+
+// CHECK-HEADER-UNIT-USE: import header.{{.*}}foo.h{{.*}};
+import "foo.h";
+
+// CHECK-HEADER-UNIT-USE: BAR;
+FOO;
+#endif




More information about the cfe-commits mailing list