From Jason Turner

[module.global.frag]

Diff to HTML by rtfpessoa

Files changed (1) hide show
  1. tmp/tmpfr9xzuqd/{from.md → to.md} +157 -0
tmp/tmpfr9xzuqd/{from.md → to.md} RENAMED
@@ -0,0 +1,157 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ## Global module fragment <a id="module.global.frag">[[module.global.frag]]</a>
2
+
3
+ ``` bnf
4
+ global-module-fragment:
5
+ module-keyword ';' declaration-seqₒₚₜ
6
+ ```
7
+
8
+ [*Note 1*: Prior to phase 4 of translation, only preprocessing
9
+ directives can appear in the *declaration-seq*
10
+ [[cpp.pre]]. — *end note*]
11
+
12
+ A *global-module-fragment* specifies the contents of the *global module
13
+ fragment* for a module unit. The global module fragment can be used to
14
+ provide declarations that are attached to the global module and usable
15
+ within the module unit.
16
+
17
+ A declaration D is *decl-reachable* from a declaration S in the same
18
+ translation unit if:
19
+
20
+ - D does not declare a function or function template and S contains an
21
+ *id-expression*, *namespace-name*, *type-name*, *template-name*, or
22
+ *concept-name* naming D, or
23
+ - D declares a function or function template that is named by an
24
+ expression [[basic.def.odr]] appearing in S, or
25
+ - S contains an expression `E` of the form
26
+ ``` bnf
27
+ postfix-expression '(' expression-listₒₚₜ ')'
28
+ ```
29
+
30
+ whose *postfix-expression* denotes a dependent name, or for an
31
+ operator expression whose operator denotes a dependent name, and D is
32
+ found by name lookup for the corresponding name in an expression
33
+ synthesized from `E` by replacing each type-dependent argument or
34
+ operand with a value of a placeholder type with no associated
35
+ namespaces or entities, or
36
+ - S contains an expression that takes the address of an overloaded
37
+ function [[over.over]] whose set of overloads contains D and for which
38
+ the target type is dependent, or
39
+ - there exists a declaration M that is not a *namespace-definition* for
40
+ which M is decl-reachable from S and either
41
+ - D is decl-reachable from M, or
42
+ - D redeclares the entity declared by M or M redeclares the entity
43
+ declared by D, and D is neither a friend declaration nor a
44
+ block-scope declaration, or
45
+ - D declares a namespace N and M is a member of N, or
46
+ - one of M and D declares a class or class template C and the other
47
+ declares a member or friend of C, or
48
+ - one of D and M declares an enumeration E and the other declares an
49
+ enumerator of E, or
50
+ - D declares a function or variable and M is declared in D, [^2] or
51
+ - one of M and D declares a template and the other declares a partial
52
+ or explicit specialization or an implicit or explicit instantiation
53
+ of that template, or
54
+ - one of M and D declares a class or enumeration type and the other
55
+ introduces a typedef name for linkage purposes for that type.
56
+
57
+ In this determination, it is unspecified
58
+
59
+ - whether a reference to an *alias-declaration*, `typedef` declaration,
60
+ *using-declaration*, or *namespace-alias-declaration* is replaced by
61
+ the declarations they name prior to this determination,
62
+ - whether a *simple-template-id* that does not denote a dependent type
63
+ and whose *template-name* names an alias template is replaced by its
64
+ denoted type prior to this determination,
65
+ - whether a *decltype-specifier* that does not denote a dependent type
66
+ is replaced by its denoted type prior to this determination, and
67
+ - whether a non-value-dependent constant expression is replaced by the
68
+ result of constant evaluation prior to this determination.
69
+
70
+ A declaration `D` in a global module fragment of a module unit is
71
+ *discarded* if `D` is not decl-reachable from any *declaration* in the
72
+ *declaration-seq* of the *translation-unit*.
73
+
74
+ [*Note 2*: A discarded declaration is neither reachable nor visible to
75
+ name lookup outside the module unit, nor in template instantiations
76
+ whose points of instantiation [[temp.point]] are outside the module
77
+ unit, even when the instantiation context [[module.context]] includes
78
+ the module unit. — *end note*]
79
+
80
+ [*Example 1*:
81
+
82
+ ``` cpp
83
+ const int size = 2;
84
+ int ary1[size]; // unspecified whether size is decl-reachable from ary1
85
+ constexpr int identity(int x) { return x; }
86
+ int ary2[identity(2)]; // unspecified whether identity is decl-reachable from ary2
87
+
88
+ template<typename> struct S;
89
+ template<typename, int> struct S2;
90
+ constexpr int g(int);
91
+
92
+ template<typename T, int N>
93
+ S<S2<T, g(N)>> f(); // S, S2, g, and :: are decl-reachable from f
94
+
95
+ template<int N>
96
+ void h() noexcept(g(N) == N); // g and :: are decl-reachable from h
97
+ ```
98
+
99
+ — *end example*]
100
+
101
+ [*Example 2*:
102
+
103
+ Source file \`"foo.h"\`
104
+
105
+ ``` cpp
106
+ namespace N {
107
+ struct X {};
108
+ int d();
109
+ int e();
110
+ inline int f(X, int = d()) { return e(); }
111
+ int g(X);
112
+ int h(X);
113
+ }
114
+ ```
115
+
116
+ Module \`M\` interface
117
+
118
+ ``` cpp
119
+ module;
120
+ #include "foo.h"
121
+ export module M;
122
+ template<typename T> int use_f() {
123
+ N::X x; // N::X, N, and :: are decl-reachable from use_f
124
+ return f(x, 123); // N::f is decl-reachable from use_f,
125
+ // N::e is indirectly decl-reachable from use_f
126
+ // because it is decl-reachable from N::f, and
127
+ // N::d is decl-reachable from use_f
128
+ // because it is decl-reachable from N::f
129
+ // even though it is not used in this call
130
+ }
131
+ template<typename T> int use_g() {
132
+ N::X x; // N::X, N, and :: are decl-reachable from use_g
133
+ return g((T(), x)); // N::g is not decl-reachable from use_g
134
+ }
135
+ template<typename T> int use_h() {
136
+ N::X x; // N::X, N, and :: are decl-reachable from use_h
137
+ return h((T(), x)); // N::h is not decl-reachable from use_h, but
138
+ // N::h is decl-reachable from use_h<int>
139
+ }
140
+ int k = use_h<int>();
141
+ // use_h<int> is decl-reachable from k, so
142
+ // N::h is decl-reachable from k
143
+ ```
144
+
145
+ Module \`M\` implementation
146
+
147
+ ``` cpp
148
+ module M;
149
+ int a = use_f<int>(); // OK
150
+ int b = use_g<int>(); // error: no viable function for call to g;
151
+ // g is not decl-reachable from purview of
152
+ // module M's interface, so is discarded
153
+ int c = use_h<int>(); // OK
154
+ ```
155
+
156
+ — *end example*]
157
+