-
Notifications
You must be signed in to change notification settings - Fork 14.9k
Description
Clang modules allow controlling the visibility of names using export
in module maps. This long predates standard C++ modules and so has somewhat ad hoc semantics. A major difference is that in C++ 20 modules, export
only controls the visibility of the name of an entity, while in Clang modules it also (kind of) controls if it is considered reachable.
Some examples:
module A {
header "A.h"
}
module B {
header "B.h"
}
/// A.h
struct A0 {};
/// B.h
#include "A.h"
struct B0 {
A0 a0{};
};
using B1 = A0;
struct B2 : A0 {};
/// test.cpp - clang++ -fmodules -fsyntax-only test.cpp
#include "B.h"
B0 b0{}; // ok, but needs A0
const auto sizeB0 = sizeof(B0); // ok, but needs A0
B1 b1{}; // error: missing '#include "A.h"'; 'A0' must be defined before it is used
B2 b2{}; // error: missing '#include "A.h"'; 'A0' must be defined before it is used
decltype(B0::a0) a0{}; // error: missing '#include "A.h"'; 'A0' must be defined before it is used
With C++20 named modules:
/// A.cppm
export module A;
export struct A0 {};
/// B.cppm
export module B;
import A;
export struct B0 {
A0 a0{};
};
export using B1 = A0;
export struct B2 : A0 {};
/// test.cpp
import B;
B0 b0{}; // ok
const auto sizeB0 = sizeof(B0); // ok
B1 b1{}; // ok
B2 b2{}; // ok
decltype(B0::a0) a0{}; // ok
We should model export in Clang modules the same way as it is in C++ named modules. Clang's current behavior allows a somewhat arbitrary set of things that require the definition of A0
to be reachable.
We should also allow macros to reference non-exported macros with a similar set of rules to templates. If the expansion chain contains a source location where such a macro is visible then it should be. For example:
// same module map as above
/// A.h
#define Anum 5
/// B.h
#include "A.h"
#define B(x) x##num
/// test.cpp
#include "B.h"
int i = B(A);