This commit is contained in:
2025-10-25 03:02:53 +03:00
commit 043225d523
3416 changed files with 681196 additions and 0 deletions

View File

@@ -0,0 +1,189 @@
[module.global.frag]
# 10 Modules [[module]](./#module)
## 10.4 Global module fragment [module.global.frag]
[global-module-fragment:](#nt:global-module-fragment "10.4Global module fragment[module.global.frag]")
module-keyword ; [*declaration-seq*](dcl.pre#nt:declaration-seq "9.1Preamble[dcl.pre]")opt
[1](#1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/modules.tex#L590)
[*Note [1](#note-1)*:
Prior to phase 4 of translation,
only preprocessing directives can appear
in the [*declaration-seq*](dcl.pre#nt:declaration-seq "9.1Preamble[dcl.pre]") ([[cpp.pre]](cpp.pre "15.1Preamble"))[.](#1.sentence-1)
— *end note*]
[2](#2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/modules.tex#L597)
A [*global-module-fragment*](#nt:global-module-fragment "10.4Global module fragment[module.global.frag]") specifies the contents of the[*global module fragment*](#def:global_module_fragment "10.4Global module fragment[module.global.frag]") for a module unit[.](#2.sentence-1)
The global module fragment can be used to provide declarations
that are attached to the global module and usable within the module unit[.](#2.sentence-2)
[3](#3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/modules.tex#L603)
A declaration D is [*decl-reachable*](#def:decl-reachable "10.4Global module fragment[module.global.frag]") from a declaration S in the same translation unit if
- [(3.1)](#3.1)
D does not declare a function or function template andS contains an[*id-expression*](expr.prim.id.general#nt:id-expression "7.5.5.1General[expr.prim.id.general]"),[*namespace-name*](namespace.def.general#nt:namespace-name "9.9.2.1General[namespace.def.general]"),[*type-name*](dcl.type.simple#nt:type-name "9.2.9.3Simple type specifiers[dcl.type.simple]"),[*template-name*](temp.names#nt:template-name "13.3Names of template specializations[temp.names]"), or[*concept-name*](temp.concept#nt:concept-name "13.7.9Concept definitions[temp.concept]") naming D, or
- [(3.2)](#3.2)
D declares a function or function template that
is named by an expression ([[basic.def.odr]](basic.def.odr "6.3One-definition rule"))
appearing in S, or
- [(3.3)](#3.3)
S contains a dependent call E ([[temp.dep]](temp.dep "13.8.3Dependent names"))
and D is found by any name lookup performed
for an expression synthesized from E by replacing each type-dependent argument or operand
with a value of a placeholder type
with no associated namespaces or entities, or
[*Note [2](#note-2)*:
This includes the lookup for operator== performed
when considering rewriting an != expression,
the lookup for operator<=> performed when considering rewriting a relational comparison, and
the lookup for operator!= when considering whether an operator== is a rewrite target[.](#3.3.sentence-1)
— *end note*]
- [(3.4)](#3.4)
S contains an expression that
takes the address of an overload set ([[over.over]](over.over "12.3Address of an overload set"))
that contains D and
for which the target type is dependent, or
- [(3.5)](#3.5)
there exists a declaration M that is not a [*namespace-definition*](namespace.def.general#nt:namespace-definition "9.9.2.1General[namespace.def.general]") for which M is decl-reachable from S and either
* [(3.5.1)](#3.5.1)
D is decl-reachable from M, or
* [(3.5.2)](#3.5.2)
D and M declare the same entity,
and D neither is a friend declaration
nor inhabits a block scope, or
* [(3.5.3)](#3.5.3)
D declares a namespace N and M is a member of N, or
* [(3.5.4)](#3.5.4)
one of D and M declares a class or class template C and the other declares a member or friend of C, or
* [(3.5.5)](#3.5.5)
one of D and M declares an enumeration E and the other declares an enumerator of E, or
* [(3.5.6)](#3.5.6)
D declares a function or variable and M is declared in D,[86](#footnote-86 "A declaration can appear within a lambda-expression in the initializer of a variable.") or
* [(3.5.7)](#3.5.7)
one of D and M declares a template and the other declares
a partial or explicit specialization or
an implicit or explicit instantiation of that template, or
* [(3.5.8)](#3.5.8)
M declares a class template
and D is a deduction guide for that template, or
* [(3.5.9)](#3.5.9)
one of D and M declares a class or enumeration type
and the other introduces a typedef name for linkage purposes for that type[.](#3.sentence-1)
In this determination, it is unspecified
- [(3.6)](#3.6)
whether a reference to an[*alias-declaration*](dcl.pre#nt:alias-declaration "9.1Preamble[dcl.pre]"),typedef declaration,[*using-declaration*](namespace.udecl#nt:using-declaration "9.10The using declaration[namespace.udecl]"), or[*namespace-alias-definition*](namespace.alias#nt:namespace-alias-definition "9.9.3Namespace alias[namespace.alias]") is replaced by the declarations they name
prior to this determination,
- [(3.7)](#3.7)
whether a [*simple-template-id*](temp.names#nt:simple-template-id "13.3Names of template specializations[temp.names]") that does not denote a dependent type
and whose [*template-name*](temp.names#nt:template-name "13.3Names of template specializations[temp.names]") names an alias template
is replaced by its denoted type
prior to this determination,
- [(3.8)](#3.8)
whether a [*decltype-specifier*](dcl.type.decltype#nt:decltype-specifier "9.2.9.6Decltype specifiers[dcl.type.decltype]") that does not denote a dependent type
is replaced by its denoted type
prior to this determination,
- [(3.9)](#3.9)
whether a non-value-dependent constant expression
is replaced by the result of constant evaluation
prior to this determination,
and
- [(3.10)](#3.10)
whether
a [*splice-expression*](expr.prim.splice#nt:splice-expression "7.5.9Expression splicing[expr.prim.splice]"),
a [*splice-type-specifier*](dcl.type.splice#nt:splice-type-specifier "9.2.9.9Type splicing[dcl.type.splice]"),
a [*splice-scope-specifier*](expr.prim.id.qual#nt:splice-scope-specifier "7.5.5.3Qualified names[expr.prim.id.qual]"), or
any [*splice-specifier*](basic.splice#nt:splice-specifier "6.6Splice specifiers[basic.splice]") or[*splice-specialization-specifier*](basic.splice#nt:splice-specialization-specifier "6.6Splice specifiers[basic.splice]") outside of the preceding is replaced in any non-dependent context
by the construct that it designates prior to this determination[.](#3.sentence-2)
[4](#4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/modules.tex#L722)
A declaration D in a global module fragment of a module unit
is [*discarded*](#def:discarded,declaration "10.4Global module fragment[module.global.frag]") if D is not decl-reachable from any [*declaration*](dcl.pre#nt:declaration "9.1Preamble[dcl.pre]") in the [*declaration-seq*](dcl.pre#nt:declaration-seq "9.1Preamble[dcl.pre]") of the [*translation-unit*](basic.link#nt:translation-unit "6.7Program and linkage[basic.link]")[.](#4.sentence-1)
[*Note [3](#note-3)*:
A discarded declaration is neither reachable
nor visible to name lookup outside the module unit,
nor in template instantiations whose points of instantiation ([[temp.point]](temp.point "13.8.4.1Point of instantiation"))
are outside the module unit,
even when the instantiation context ([[module.context]](module.context "10.6Instantiation context"))
includes the module unit[.](#4.sentence-2)
— *end note*]
[5](#5)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/modules.tex#L737)
[*Example [1](#example-1)*: const int size = 2;int ary1[size]; // unspecified whether size is decl-reachable from ary1constexpr int identity(int x) { return x; }int ary2[identity(2)]; // unspecified whether identity is decl-reachable from ary2template<typename> struct S;template<typename, int> struct S2;constexpr int g(int);
template<typename T, int N> S<S2<T, g(N)>> f(); // S, S2, g, and :: are decl-reachable from ftemplate<int N>void h() noexcept(g(N) == N); // g and :: are decl-reachable from h — *end example*]
[6](#6)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/modules.tex#L757)
[*Example [2](#example-2)*:
Source file "foo.h":namespace N {struct X {}; int d(); int e(); inline int f(X, int = d()) { return e(); }int g(X); int h(X);}
Module M interface:module;#include "foo.h"export module M;template<typename T> int use_f() { N::X x; // N::X, N, and :: are decl-reachable from use_freturn f(x, 123); // N::f is decl-reachable from use_f,// N::e is indirectly decl-reachable from use_f// because it is decl-reachable from N::f, and// N::d is decl-reachable from use_f// because it is decl-reachable from N::f// even though it is not used in this call}template<typename T> int use_g() { N::X x; // N::X, N, and :: are decl-reachable from use_greturn g((T(), x)); // N::g is not decl-reachable from use_g}template<typename T> int use_h() { N::X x; // N::X, N, and :: are decl-reachable from use_hreturn h((T(), x)); // N::h is not decl-reachable from use_h, but// N::h is decl-reachable from use_h<int>}int k = use_h<int>(); // use_h<int> is decl-reachable from k, so// N::h is decl-reachable from k
Module M implementation:module M;int a = use_f<int>(); // OKint b = use_g<int>(); // error: no viable function for call to g;// g is not decl-reachable from purview of// module M's interface, so is discardedint c = use_h<int>(); // OK — *end example*]
[86)](#footnote-86)[86)](#footnoteref-86)
A declaration can appear within a [*lambda-expression*](expr.prim.lambda.general#nt:lambda-expression "7.5.6.1General[expr.prim.lambda.general]") in the initializer of a variable[.](#footnote-86.sentence-1)