ilya-biryukov created this revision.
ilya-biryukov added a reviewer: sammccall.
Herald added a project: All.
ilya-biryukov requested review of this revision.
Herald added a subscriber: MaskRay.
Herald added a project: clang.
This only shows up if one passes module maps to Clang in `-std=c++20`
modes, e.g. for layering checks.
Repository:
rG LLVM Github Monorepo
https://reviews.llvm.org/D125773
Files:
clang/include/clang/Basic/LangOptions.def
clang/include/clang/Driver/Options.td
clang/lib/Driver/ToolChains/Clang.cpp
clang/lib/Lex/PPDirectives.cpp
clang/test/Driver/cpp20-header-module.cpp
clang/test/Modules/Inputs/cxx20-and-header-modules/a.h
clang/test/Modules/Inputs/cxx20-and-header-modules/a.map
clang/test/Modules/cxx20-and-header-modules.cpp
Index: clang/test/Modules/cxx20-and-header-modules.cpp
===================================================================
--- /dev/null
+++ clang/test/Modules/cxx20-and-header-modules.cpp
@@ -0,0 +1,16 @@
+// RUN: rm -rf %t
+//
+// Check header modules are disabled by default in C++20 mode.
+// RUN: %clang -std=c++20 -fsyntax-only -fno-implicit-modules -fmodules-cache-path=%t -I%S/Inputs/cxx20-and-header-modules -fmodule-map-file=%S/Inputs/cxx20-and-header-modules/a.map %s
+// RUN: %clang -std=gnu++20 -fsyntax-only -fno-implicit-modules -fmodules-cache-path=%t -I%S/Inputs/cxx20-and-header-modules -fmodule-map-file=%S/Inputs/cxx20-and-header-modules/a.map %s
+//
+// Also run in the header modules mode.
+// RUN: %clang -std=c++20 -DBUILDING_MODULE -fmodules -fimplicit-modules -fmodules-cache-path=%t -I%S/Inputs/cxx20-and-header-modules -fmodule-map-file=%S/Inputs/cxx20-and-header-modules/a.map %s
+// RUN: %clang -std=gnu++20 -DBUILDING_MODULE -fmodules -fimplicit-modules -fmodules-cache-path=%t -I%S/Inputs/cxx20-and-header-modules -fmodule-map-file=%S/Inputs/cxx20-and-header-modules/a.map %s
+
+#define INCLUDING 1
+#include "a.h"
+
+int main() {
+ return X().foo();
+}
Index: clang/test/Modules/Inputs/cxx20-and-header-modules/a.map
===================================================================
--- /dev/null
+++ clang/test/Modules/Inputs/cxx20-and-header-modules/a.map
@@ -0,0 +1,4 @@
+module A {
+ header "a.h"
+ export *
+}
Index: clang/test/Modules/Inputs/cxx20-and-header-modules/a.h
===================================================================
--- /dev/null
+++ clang/test/Modules/Inputs/cxx20-and-header-modules/a.h
@@ -0,0 +1,12 @@
+#ifndef A_HEADER
+#define A_HEADER
+
+#if INCLUDING && BUILDING_MODULE
+#error "invalid context"
+#endif
+
+struct X {
+ int foo() { return 10; }
+};
+
+#endif
Index: clang/test/Driver/cpp20-header-module.cpp
===================================================================
--- /dev/null
+++ clang/test/Driver/cpp20-header-module.cpp
@@ -0,0 +1,24 @@
+// Check header modules are not enabled with C++20 standard and -fmodules-ts.
+//
+// RUN: %clang -fmodules-ts -std=c++20 -fsyntax-only -v %s 2>&1 | FileCheck %s --check-prefix=NO_HEADER_MODULES
+// RUN: %clang -std=c++20 -fsyntax-only -v %s 2>&1 | FileCheck %s --check-prefix=NO_HEADER_MODULES
+// RUN: %clang -std=c++2a -fsyntax-only -v %s 2>&1 | FileCheck %s --check-prefix=NO_HEADER_MODULES
+// RUN: %clang -std=c++2b -fsyntax-only -v %s 2>&1 | FileCheck %s --check-prefix=NO_HEADER_MODULES
+// RUN: %clang_cl /std:c++latest /Zs -v %s 2>&1 | FileCheck %s --check-prefix=NO_HEADER_MODULES
+// RUN: %clang -std=gnu++20 -fsyntax-only -v %s 2>&1 | FileCheck %s --check-prefix=NO_HEADER_MODULES
+// RUN: %clang -std=gnu++2a -fsyntax-only -v %s 2>&1 | FileCheck %s --check-prefix=NO_HEADER_MODULES
+// RUN: %clang -std=gnu++2b -fsyntax-only -v %s 2>&1 | FileCheck %s --check-prefix=NO_HEADER_MODULES
+//
+// NO_HEADER_MODULES: -cc1
+// NO_HEADER_MODULES-SAME: -fno-header-modules
+//
+// RUN: %clang -fmodules -fmodules-ts -fsyntax-only -v %s 2>&1 | FileCheck %s --check-prefix=HAS_HEADER_MODULES
+// RUN: %clang -fmodules -fmodules-ts -fsyntax-only -v %s 2>&1 | FileCheck %s --check-prefix=HAS_HEADER_MODULES
+// RUN: %clang -fmodules -std=c++20 -fsyntax-only -v %s 2>&1 | FileCheck %s --check-prefix=HAS_HEADER_MODULES
+// RUN: %clang -fmodules -std=c++2a -fsyntax-only -v %s 2>&1 | FileCheck %s --check-prefix=HAS_HEADER_MODULES
+// RUN: %clang -fmodules -std=c++2b -fsyntax-only -v %s 2>&1 | FileCheck %s --check-prefix=HAS_HEADER_MODULES
+// RUN: %clang -fmodules -std=gnu++20 -fsyntax-only -v %s 2>&1 | FileCheck %s --check-prefix=HAS_HEADER_MODULES
+// RUN: %clang -fmodules -std=gnu++2a -fsyntax-only -v %s 2>&1 | FileCheck %s --check-prefix=HAS_HEADER_MODULES
+// RUN: %clang -fmodules -std=gnu++2b -fsyntax-only -v %s 2>&1 | FileCheck %s --check-prefix=HAS_HEADER_MODULES
+//
+// HAS_HEADER_MODULES-NOT: -fno-header-modules
Index: clang/lib/Lex/PPDirectives.cpp
===================================================================
--- clang/lib/Lex/PPDirectives.cpp
+++ clang/lib/Lex/PPDirectives.cpp
@@ -2159,7 +2159,8 @@
// Determine whether we should try to import the module for this #include, if
// there is one. Don't do so if precompiled module support is disabled or we
// are processing this module textually (because we're building the module).
- if (Action == Enter && File && SuggestedModule && getLangOpts().Modules &&
+ if (Action == Enter && File && SuggestedModule &&
+ getLangOpts().HeaderModules &&
!isForModuleBuilding(SuggestedModule.getModule(),
getLangOpts().CurrentModule,
getLangOpts().ModuleName)) {
Index: clang/lib/Driver/ToolChains/Clang.cpp
===================================================================
--- clang/lib/Driver/ToolChains/Clang.cpp
+++ clang/lib/Driver/ToolChains/Clang.cpp
@@ -38,6 +38,7 @@
#include "clang/Driver/SanitizerArgs.h"
#include "clang/Driver/Types.h"
#include "clang/Driver/XRayArgs.h"
+#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/Config/llvm-config.h"
#include "llvm/Option/ArgList.h"
@@ -3625,6 +3626,12 @@
HaveModules = true;
}
+ // Disable header modules in C++20 mode, they are not in the C++ standard.
+ // Unless '-fmodules' was specified explicitly.
+ if (!HaveClangModules && HaveModules) {
+ CmdArgs.push_back("-fno-header-modules");
+ }
+
// -fmodule-maps enables implicit reading of module map files. By default,
// this is enabled if we are using Clang's flavor of precompiled modules.
if (Args.hasFlag(options::OPT_fimplicit_module_maps,
@@ -6527,9 +6534,12 @@
// 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++20") ||
- Std->containsValue("c++latest"));
+ bool HaveModules = Std && llvm::any_of(Std->getValues(), [](const char *S) {
+ constexpr llvm::StringRef CPP_MODULES_STD[] = {
+ "c++2a", "c++20", "c++2b", "c++latest",
+ "gnu++2a", "gnu++20", "gnu++2b", "gnu++latest"};
+ return llvm::is_contained(CPP_MODULES_STD, S);
+ });
RenderModulesOptions(C, D, Args, Input, Output, CmdArgs, HaveModules);
if (Args.hasFlag(options::OPT_fpch_validate_input_files_content,
Index: clang/include/clang/Driver/Options.td
===================================================================
--- clang/include/clang/Driver/Options.td
+++ clang/include/clang/Driver/Options.td
@@ -2261,6 +2261,10 @@
LangOpts<"Modules">, Default<!strconcat(fmodules_ts.KeyPath, "||", fcxx_modules.KeyPath)>,
PosFlag<SetTrue, [CC1Option], "Enable the 'modules' language feature">,
NegFlag<SetFalse>, BothFlags<[NoXarchOption, CoreOption]>>;
+defm header_modules : BoolFOption<"header-modules",
+ LangOpts<"HeaderModules">, Default<fmodules.KeyPath>,
+ PosFlag<SetTrue, [], "Enable header modules (Clang extension)">,
+ NegFlag<SetFalse>, BothFlags<[CC1Option, NoDriverOption]>>;
def fmodule_maps : Flag <["-"], "fmodule-maps">, Flags<[CoreOption]>, Alias<fimplicit_module_maps>;
def fmodule_name_EQ : Joined<["-"], "fmodule-name=">, Group<f_Group>,
Flags<[NoXarchOption,CC1Option,CoreOption]>, MetaVarName<"<name>">,
Index: clang/include/clang/Basic/LangOptions.def
===================================================================
--- clang/include/clang/Basic/LangOptions.def
+++ clang/include/clang/Basic/LangOptions.def
@@ -170,6 +170,7 @@
LANGOPT(Modules , 1, 0, "modules semantics")
COMPATIBLE_LANGOPT(ModulesTS , 1, 0, "C++ Modules TS syntax")
COMPATIBLE_LANGOPT(CPlusPlusModules, 1, 0, "C++ modules syntax")
+COMPATIBLE_LANGOPT(HeaderModules, 1, 0, "Clang header modules")
BENIGN_ENUM_LANGOPT(CompilingModule, CompilingModuleKind, 3, CMK_None,
"compiling a module interface")
BENIGN_LANGOPT(CompilingPCH, 1, 0, "building a pch")
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits