Skip to content

Clang modules does not handle visibility vs. reachability the same way as C++ named modules. #163652

@Bigcheese

Description

@Bigcheese

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);

Metadata

Metadata

Assignees

No one assigned

    Labels

    clang:modulesC++20 modules and Clang Header Modules

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions