Currently, the header units are rarely used and it is not well tested.
To avoid further misunderstandings, let's mark it as experimental and
emit a warning when users wants to import it.
This is discussed in modules developers meeting.
def err_extern_def_in_header_unit : Error<
"non-inline external definitions are not permitted in C++ header units">;
+def warn_experimental_header_unit : Warning<
+ "the implementation of header units is in an experimental phase">,
+ InGroup<DiagGroup<"experimental-header-units">>;
+
def ext_equivalent_internal_linkage_decl_in_modules : ExtWarn<
"ambiguous use of internal linkage declaration %0 defined in multiple modules">,
InGroup<DiagGroup<"modules-ambiguous-internal-linkage">>;
SourceLocation ExportLoc,
SourceLocation ImportLoc, Module *Mod,
ModuleIdPath Path) {
+ if (Mod->isHeaderUnit())
+ Diag(ImportLoc, diag::warn_experimental_header_unit);
+
VisibleModules.setVisible(Mod, ImportLoc);
checkModuleImportContext(*this, Mod, ImportLoc, CurContext);
// RUN: %clang_cc1 -std=c++20 %s -DY_INTERFACE -emit-module-interface -o %t/y.pcm
// RUN: %clang_cc1 -std=c++20 %s -DINTERFACE -fmodule-file=X=%t/x.pcm -fmodule-file=Y=%t/y.pcm -emit-module-interface -o %t/m.pcm
// RUN: %clang_cc1 -std=c++20 %s -DIMPLEMENTATION -I%S/Inputs -fmodule-file=%t/h.pcm \
-// RUN: -fmodule-file=X=%t/x.pcm -fmodule-file=Y=%t/y.pcm -fmodule-file=p2=%t/m.pcm -verify
+// RUN: -fmodule-file=X=%t/x.pcm -fmodule-file=Y=%t/y.pcm -fmodule-file=p2=%t/m.pcm -verify \
+// RUN: -Wno-experimental-header-units
// RUN: %clang_cc1 -std=c++20 %s -DUSER -I%S/Inputs -fmodule-file=%t/h.pcm -fmodule-file=p2=%t/m.pcm \
-// RUN: -fmodule-file=X=%t/x.pcm -fmodule-file=Y=%t/y.pcm -verify
+// RUN: -fmodule-file=X=%t/x.pcm -fmodule-file=Y=%t/y.pcm -Wno-experimental-header-units -verify
#if defined(X_INTERFACE)
export module X;
#include "std-10-2-ex2-b.h"
export module M;
-import "std-10-2-ex2-c.h";
+import "std-10-2-ex2-c.h"; // expected-warning {{the implementation of header units is in an experimental phase}}
import X;
export using ::f, ::g, ::h; // OK
struct S; // expected-note {{target of using declaration}}
// CHECK-HU-NEXT: Header Unit './hu-01.h' is the Primary Module at index #1
//--- hu-02.h
-export import "hu-01.h";
+export import "hu-01.h"; // expected-warning {{the implementation of header units is in an experimental phase}}
#if !defined(FORTYTWO) || FORTYTWO != 42
#error FORTYTWO missing in hu-02
#endif
//--- importer-01.cpp
export module B;
-import "hu-02.h";
+import "hu-02.h"; // expected-warning {{the implementation of header units is in an experimental phase}}
int success(int x) {
return foo(FORTYTWO + x + KAP);
//--- importer-02.cpp
export module C;
-import "hu-02.h";
+import "hu-02.h"; // expected-warning {{the implementation of header units is in an experimental phase}}
int success(int x) {
return foo(FORTYTWO + x + KAP);
module /*nothing here*/;
// This should be include-translated, when the header unit for h1 is available.
+ // expected-warning@+1 {{the implementation of header units is in an experimental phase}}
#include "h1.h" // expected-remark {{treating #include as an import of module './h1.h'}}
// Import of a header unit is allowed, named modules are not.
-import "h2.h";
+import "h2.h"; // expected-warning {{the implementation of header units is in an experimental phase}}
// A regular, untranslated, header
#include "h5.h"
export module Xlate;
// This is OK, the import immediately follows the module decl.
-import "h3.h";
+import "h3.h"; // expected-warning {{the implementation of header units is in an experimental phase}}
// This should *not* be include-translated, even if header unit for h4 is
// available.
// expected-note@* 1+{{previous definition is here}}
//--- Use5.cpp
-// expected-no-diagnostics
-import "foo.h";
+import "foo.h"; // expected-warning {{the implementation of header units is in an experimental phase}}
import A;
template <class T> void foo()
{}
//--- Use6.cpp
-// expected-no-diagnostics
import A;
-import "foo.h";
+import "foo.h"; // expected-warning {{the implementation of header units is in an experimental phase}}
template <class T> void foo()
requires same_as<T, int>