Init
This commit is contained in:
147
cppdraft/module/context.md
Normal file
147
cppdraft/module/context.md
Normal file
@@ -0,0 +1,147 @@
|
||||
[module.context]
|
||||
|
||||
# 10 Modules [[module]](./#module)
|
||||
|
||||
## 10.6 Instantiation context [module.context]
|
||||
|
||||
[1](#1)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/modules.tex#L884)
|
||||
|
||||
The [*instantiation context*](#def:instantiation_context "10.6 Instantiation context [module.context]") is a set of points within the program
|
||||
that determines which declarations are found by
|
||||
argument-dependent name lookup ([[basic.lookup.argdep]](basic.lookup.argdep "6.5.4 Argument-dependent name lookup"))
|
||||
and which are reachable ([[module.reach]](module.reach "10.7 Reachability"))
|
||||
in the context of a particular declaration or template instantiation[.](#1.sentence-1)
|
||||
|
||||
[2](#2)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/modules.tex#L891)
|
||||
|
||||
During the implicit definition of
|
||||
a defaulted function ([[special]](special "11.4.4 Special member functions"), [[class.compare.default]](class.compare.default "11.10.1 Defaulted comparison operator functions")),
|
||||
the instantiation context contains each point in
|
||||
the instantiation context from the definition of the class and
|
||||
each point in
|
||||
the instantiation context of the program construct that
|
||||
resulted in the implicit definition of the defaulted function[.](#2.sentence-1)
|
||||
|
||||
[3](#3)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/modules.tex#L900)
|
||||
|
||||
During the implicit instantiation of a template
|
||||
whose point of instantiation is specified as
|
||||
that of an enclosing specialization ([[temp.point]](temp.point "13.8.4.1 Point of instantiation")),
|
||||
the instantiation context contains each point in
|
||||
the instantiation context of the enclosing specialization and,
|
||||
if the template is defined in a module interface unit of a module M and the point of instantiation is not in a module interface unit of M,
|
||||
the point at the end of the[*declaration-seq*](dcl.pre#nt:declaration-seq "9.1 Preamble [dcl.pre]") of the
|
||||
primary module interface unit of M (prior to the [*private-module-fragment*](module.private.frag#nt:private-module-fragment "10.5 Private module fragment [module.private.frag]"), if any)[.](#3.sentence-1)
|
||||
|
||||
[4](#4)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/modules.tex#L913)
|
||||
|
||||
During the implicit instantiation of a template
|
||||
that is implicitly instantiated because it is referenced
|
||||
from within the implicit definition of a defaulted function,
|
||||
the instantiation context contains each point in the instantiation context of
|
||||
the defaulted function[.](#4.sentence-1)
|
||||
|
||||
[5](#5)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/modules.tex#L920)
|
||||
|
||||
During the instantiation of any other template specialization,
|
||||
the instantiation context contains the point of instantiation
|
||||
of the template[.](#5.sentence-1)
|
||||
|
||||
[6](#6)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/modules.tex#L925)
|
||||
|
||||
During the implicit instantiation of any construct
|
||||
that resulted from the evaluation of an expression
|
||||
as a core constant expression,
|
||||
the instantiation context contains
|
||||
each point in the evaluation context ([[expr.const]](expr.const "7.7 Constant expressions"))[.](#6.sentence-1)
|
||||
|
||||
[*Note [1](#note-1)*:
|
||||
|
||||
Implicit instantiations can result
|
||||
from invocations of library functions ([[meta.reflection]](meta.reflection "21.4 Reflection"))[.](#6.sentence-2)
|
||||
|
||||
The evaluation context can include synthesized points
|
||||
associated with injected declarations
|
||||
produced by std::meta::define_aggregate ([[meta.reflection.define.aggregate]](meta.reflection.define.aggregate "21.4.16 Reflection class definition generation"))[.](#6.sentence-3)
|
||||
|
||||
â *end note*]
|
||||
|
||||
[7](#7)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/modules.tex#L939)
|
||||
|
||||
In any other case, the instantiation context
|
||||
at a point within the program
|
||||
contains that point[.](#7.sentence-1)
|
||||
|
||||
[8](#8)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/modules.tex#L944)
|
||||
|
||||
The instantiation context contains only the points specified above[.](#8.sentence-1)
|
||||
|
||||
[9](#9)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/modules.tex#L947)
|
||||
|
||||
[*Example [1](#example-1)*:
|
||||
|
||||
Translation unit #1:export module stuff;export template<typename T, typename U> void foo(T, U u) { auto v = u; }export template<typename T, typename U> void bar(T, U u) { auto v = *u; }
|
||||
|
||||
Translation unit #2:export module M1;import "defn.h"; // provides struct X {};import stuff;export template<typename T> void f(T t) { X x;
|
||||
foo(t, x);}
|
||||
|
||||
Translation unit #3:export module M2;import "decl.h"; // provides struct X; (not a definition)import stuff;export template<typename T> void g(T t) { X *x;
|
||||
bar(t, x);}
|
||||
|
||||
Translation unit #4:import M1;import M2;void test() { f(0);
|
||||
g(0);}
|
||||
|
||||
The call to f(0) is valid;
|
||||
the instantiation context of foo<int, X> comprises
|
||||
|
||||
- [(9.1)](#9.1)
|
||||
|
||||
the point at the end of translation unit #1,
|
||||
|
||||
- [(9.2)](#9.2)
|
||||
|
||||
the point at the end of translation unit #2, and
|
||||
|
||||
- [(9.3)](#9.3)
|
||||
|
||||
the point of the call to f(0),
|
||||
|
||||
so the definition of X is reachable ([[module.reach]](module.reach "10.7 Reachability"))[.](#9.sentence-1)
|
||||
|
||||
It is unspecified whether the call to g(0) is valid:
|
||||
the instantiation context of bar<int, X> comprises
|
||||
|
||||
- [(9.4)](#9.4)
|
||||
|
||||
the point at the end of translation unit #1,
|
||||
|
||||
- [(9.5)](#9.5)
|
||||
|
||||
the point at the end of translation unit #3, and
|
||||
|
||||
- [(9.6)](#9.6)
|
||||
|
||||
the point of the call to g(0),
|
||||
|
||||
so the definition of X need not be reachable,
|
||||
as described in [[module.reach]](module.reach "10.7 Reachability")[.](#9.sentence-2)
|
||||
|
||||
â *end example*]
|
||||
189
cppdraft/module/global/frag.md
Normal file
189
cppdraft/module/global/frag.md
Normal 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.4 Global module fragment [module.global.frag]")
|
||||
module-keyword ; [*declaration-seq*](dcl.pre#nt:declaration-seq "9.1 Preamble [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.1 Preamble [dcl.pre]") ([[cpp.pre]](cpp.pre "15.1 Preamble"))[.](#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.4 Global module fragment [module.global.frag]") specifies the contents of the[*global module fragment*](#def:global_module_fragment "10.4 Global 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.4 Global 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.1 General [expr.prim.id.general]"),[*namespace-name*](namespace.def.general#nt:namespace-name "9.9.2.1 General [namespace.def.general]"),[*type-name*](dcl.type.simple#nt:type-name "9.2.9.3 Simple type specifiers [dcl.type.simple]"),[*template-name*](temp.names#nt:template-name "13.3 Names of template specializations [temp.names]"), or[*concept-name*](temp.concept#nt:concept-name "13.7.9 Concept 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.3 One-definition rule"))
|
||||
appearing in S, or
|
||||
|
||||
- [(3.3)](#3.3)
|
||||
|
||||
S contains a dependent call E ([[temp.dep]](temp.dep "13.8.3 Dependent 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.3 Address 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.1 General [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.1 Preamble [dcl.pre]"),typedef declaration,[*using-declaration*](namespace.udecl#nt:using-declaration "9.10 The using declaration [namespace.udecl]"), or[*namespace-alias-definition*](namespace.alias#nt:namespace-alias-definition "9.9.3 Namespace 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.3 Names of template specializations [temp.names]") that does not denote a dependent type
|
||||
and whose [*template-name*](temp.names#nt:template-name "13.3 Names 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.6 Decltype 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.9 Expression splicing [expr.prim.splice]"),
|
||||
a [*splice-type-specifier*](dcl.type.splice#nt:splice-type-specifier "9.2.9.9 Type splicing [dcl.type.splice]"),
|
||||
a [*splice-scope-specifier*](expr.prim.id.qual#nt:splice-scope-specifier "7.5.5.3 Qualified names [expr.prim.id.qual]"), or
|
||||
any [*splice-specifier*](basic.splice#nt:splice-specifier "6.6 Splice specifiers [basic.splice]") or[*splice-specialization-specifier*](basic.splice#nt:splice-specialization-specifier "6.6 Splice 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.4 Global module fragment [module.global.frag]") if D is not decl-reachable from any [*declaration*](dcl.pre#nt:declaration "9.1 Preamble [dcl.pre]") in the [*declaration-seq*](dcl.pre#nt:declaration-seq "9.1 Preamble [dcl.pre]") of the [*translation-unit*](basic.link#nt:translation-unit "6.7 Program 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.1 Point of instantiation"))
|
||||
are outside the module unit,
|
||||
even when the instantiation context ([[module.context]](module.context "10.6 Instantiation 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.1 General [expr.prim.lambda.general]") in the initializer of a variable[.](#footnote-86.sentence-1)
|
||||
212
cppdraft/module/import.md
Normal file
212
cppdraft/module/import.md
Normal file
@@ -0,0 +1,212 @@
|
||||
[module.import]
|
||||
|
||||
# 10 Modules [[module]](./#module)
|
||||
|
||||
## 10.3 Import declaration [module.import]
|
||||
|
||||
[module-import-declaration:](#nt:module-import-declaration "10.3 Import declaration [module.import]")
|
||||
import-keyword [*module-name*](module.unit#nt:module-name "10.1 Module units and purviews [module.unit]") [*attribute-specifier-seq*](dcl.attr.grammar#nt:attribute-specifier-seq "9.13.1 Attribute syntax and semantics [dcl.attr.grammar]")opt ;
|
||||
import-keyword [*module-partition*](module.unit#nt:module-partition "10.1 Module units and purviews [module.unit]") [*attribute-specifier-seq*](dcl.attr.grammar#nt:attribute-specifier-seq "9.13.1 Attribute syntax and semantics [dcl.attr.grammar]")opt ;
|
||||
import-keyword [*header-name*](lex.header#nt:header-name "5.6 Header names [lex.header]") [*attribute-specifier-seq*](dcl.attr.grammar#nt:attribute-specifier-seq "9.13.1 Attribute syntax and semantics [dcl.attr.grammar]")opt ;
|
||||
|
||||
[1](#1)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/modules.tex#L412)
|
||||
|
||||
A [*module-import-declaration*](#nt:module-import-declaration "10.3 Import declaration [module.import]") shall inhabit the global namespace scope[.](#1.sentence-1)
|
||||
|
||||
In a module unit, all [*module-import-declaration*](#nt:module-import-declaration "10.3 Import declaration [module.import]")*s* and [*export-declaration*](module.interface#nt:export-declaration "10.2 Export declaration [module.interface]")*s* exporting[*module-import-declaration*](#nt:module-import-declaration "10.3 Import declaration [module.import]")*s* shall appear before all other [*declaration*](dcl.pre#nt:declaration "9.1 Preamble [dcl.pre]")*s* in
|
||||
the [*declaration-seq*](dcl.pre#nt:declaration-seq "9.1 Preamble [dcl.pre]") of the[*translation-unit*](basic.link#nt:translation-unit "6.7 Program and linkage [basic.link]") and of the [*private-module-fragment*](module.private.frag#nt:private-module-fragment "10.5 Private module fragment [module.private.frag]") (if any)[.](#1.sentence-2)
|
||||
|
||||
The optional [*attribute-specifier-seq*](dcl.attr.grammar#nt:attribute-specifier-seq "9.13.1 Attribute syntax and semantics [dcl.attr.grammar]") appertains to the [*module-import-declaration*](#nt:module-import-declaration "10.3 Import declaration [module.import]")[.](#1.sentence-3)
|
||||
|
||||
[2](#2)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/modules.tex#L425)
|
||||
|
||||
A [*module-import-declaration*](#nt:module-import-declaration "10.3 Import declaration [module.import]") [*imports*](#def:import "10.3 Import declaration [module.import]") a set of
|
||||
translation units determined as described below[.](#2.sentence-1)
|
||||
|
||||
[*Note [1](#note-1)*:
|
||||
|
||||
Namespace-scope declarations exported by the imported translation units
|
||||
can be found by name lookup ([[basic.lookup]](basic.lookup "6.5 Name lookup"))
|
||||
in the importing translation unit
|
||||
and declarations within the imported translation units
|
||||
become reachable ([[module.reach]](module.reach "10.7 Reachability"))
|
||||
in the importing translation unit
|
||||
after the import declaration[.](#2.sentence-2)
|
||||
|
||||
â *end note*]
|
||||
|
||||
[3](#3)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/modules.tex#L438)
|
||||
|
||||
A [*module-import-declaration*](#nt:module-import-declaration "10.3 Import declaration [module.import]") that specifies
|
||||
a [*module-name*](module.unit#nt:module-name "10.1 Module units and purviews [module.unit]") M imports all module interface units of M[.](#3.sentence-1)
|
||||
|
||||
[4](#4)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/modules.tex#L443)
|
||||
|
||||
A [*module-import-declaration*](#nt:module-import-declaration "10.3 Import declaration [module.import]") that specifies
|
||||
a [*module-partition*](module.unit#nt:module-partition "10.1 Module units and purviews [module.unit]") shall only appear after
|
||||
the [*module-declaration*](module.unit#nt:module-declaration "10.1 Module units and purviews [module.unit]") in a module unit of
|
||||
some module M[.](#4.sentence-1)
|
||||
|
||||
Such a declaration imports the so-named
|
||||
module partition of M[.](#4.sentence-2)
|
||||
|
||||
[5](#5)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/modules.tex#L451)
|
||||
|
||||
A [*module-import-declaration*](#nt:module-import-declaration "10.3 Import declaration [module.import]") that specifies
|
||||
a [*header-name*](lex.header#nt:header-name "5.6 Header names [lex.header]") H imports
|
||||
a synthesized [*header unit*](#def:header_unit "10.3 Import declaration [module.import]"),
|
||||
which is a translation unit formed by applying
|
||||
phases 1 to 7 of translation ([[lex.phases]](lex.phases "5.2 Phases of translation"))
|
||||
to the source file or header nominated by H,
|
||||
which shall not contain a [*module-declaration*](module.unit#nt:module-declaration "10.1 Module units and purviews [module.unit]")[.](#5.sentence-1)
|
||||
|
||||
[*Note [2](#note-2)*:
|
||||
|
||||
A header unit is a separate translation unit with
|
||||
an independent set of defined macros[.](#5.sentence-2)
|
||||
|
||||
All declarations within a header unit are implicitly
|
||||
exported ([[module.interface]](module.interface "10.2 Export declaration")),
|
||||
and are attached to the global module ([[module.unit]](module.unit "10.1 Module units and purviews"))[.](#5.sentence-3)
|
||||
|
||||
â *end note*]
|
||||
|
||||
An [*importable header*](#def:header,importable "10.3 Import declaration [module.import]") is a member of animplementation-defined
|
||||
set of headers that
|
||||
includes all importable C++ library headers ([[headers]](headers "16.4.2.3 Headers"))[.](#5.sentence-4)
|
||||
|
||||
H shall identify an importable header[.](#5.sentence-5)
|
||||
|
||||
Given two such [*module-import-declaration*](#nt:module-import-declaration "10.3 Import declaration [module.import]")*s*:
|
||||
|
||||
- [(5.1)](#5.1)
|
||||
|
||||
if their [*header-name*](lex.header#nt:header-name "5.6 Header names [lex.header]")*s* identify
|
||||
different headers or source files ([[cpp.include]](cpp.include "15.3 Source file inclusion")),
|
||||
they import distinct header units;
|
||||
|
||||
- [(5.2)](#5.2)
|
||||
|
||||
otherwise, if they appear in the same translation unit,
|
||||
they import the same header unit;
|
||||
|
||||
- [(5.3)](#5.3)
|
||||
|
||||
otherwise, it is unspecified whether they import the same header unit[.](#5.sentence-6)
|
||||
[*Note [3](#note-3)*:
|
||||
It is therefore possible that multiple copies exist of entities
|
||||
declared with internal linkage in an importable header[.](#5.3.sentence-2)
|
||||
â *end note*]
|
||||
|
||||
[*Note [4](#note-4)*:
|
||||
|
||||
A [*module-import-declaration*](#nt:module-import-declaration "10.3 Import declaration [module.import]") nominating
|
||||
a [*header-name*](lex.header#nt:header-name "5.6 Header names [lex.header]") is also recognized by the
|
||||
preprocessor, and results in macros defined at the
|
||||
end of phase 4 of translation of the header unit
|
||||
being made visible as described in [[cpp.import]](cpp.import "15.6 Header unit importation")[.](#5.sentence-7)
|
||||
|
||||
Any other [*module-import-declaration*](#nt:module-import-declaration "10.3 Import declaration [module.import]") does not make macros visible[.](#5.sentence-8)
|
||||
|
||||
â *end note*]
|
||||
|
||||
[6](#6)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/modules.tex#L497)
|
||||
|
||||
A declaration of a name with internal linkage is
|
||||
permitted within a header unit despite all
|
||||
declarations being implicitly exported ([[module.interface]](module.interface "10.2 Export declaration"))[.](#6.sentence-1)
|
||||
|
||||
[*Note [5](#note-5)*:
|
||||
|
||||
A definition that appears in multiple translation units
|
||||
cannot in general refer to such names ([[basic.def.odr]](basic.def.odr "6.3 One-definition rule"))[.](#6.sentence-2)
|
||||
|
||||
â *end note*]
|
||||
|
||||
A header unit shall not contain
|
||||
a definition of a non-inline function or variable
|
||||
whose name has external linkage[.](#6.sentence-3)
|
||||
|
||||
[7](#7)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/modules.tex#L509)
|
||||
|
||||
When a [*module-import-declaration*](#nt:module-import-declaration "10.3 Import declaration [module.import]") imports
|
||||
a translation unit T, it also imports
|
||||
all translation units imported by
|
||||
exported [*module-import-declaration*](#nt:module-import-declaration "10.3 Import declaration [module.import]")*s* in T; such translation units are
|
||||
said to be [*exported*](#def:module,exported "10.3 Import declaration [module.import]") by T[.](#7.sentence-1)
|
||||
|
||||
Additionally, when a [*module-import-declaration*](#nt:module-import-declaration "10.3 Import declaration [module.import]") in a module unit of some module M imports another module unit U of M,
|
||||
it also imports all translation units imported by
|
||||
non-exported [*module-import-declaration*](#nt:module-import-declaration "10.3 Import declaration [module.import]")*s* in the module unit purview of U[.](#7.sentence-2)[85](#footnote-85 "This is consistent with the lookup rules for imported names ([basic.lookup]).")
|
||||
|
||||
These rules can in turn lead to the importation of yet more
|
||||
translation units[.](#7.sentence-3)
|
||||
|
||||
[*Note [6](#note-6)*:
|
||||
|
||||
Such indirect importation does not make macros available,
|
||||
because a translation unit is
|
||||
a sequence of tokens in translation phase 7 ([[lex.phases]](lex.phases "5.2 Phases of translation"))[.](#7.sentence-4)
|
||||
|
||||
Macros can be made available by directly importing header units
|
||||
as described in [[cpp.import]](cpp.import "15.6 Header unit importation")[.](#7.sentence-5)
|
||||
|
||||
â *end note*]
|
||||
|
||||
[8](#8)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/modules.tex#L535)
|
||||
|
||||
A module implementation unit shall not be exported[.](#8.sentence-1)
|
||||
|
||||
[*Example [1](#example-1)*:
|
||||
|
||||
Translation unit #1:module M:Part;
|
||||
|
||||
Translation unit #2:export module M;export import :Part; // error: exported partition :Part is an implementation unit â *end example*]
|
||||
|
||||
[9](#9)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/modules.tex#L548)
|
||||
|
||||
A module implementation unit of a module M that is not a module partition
|
||||
shall not contain a [*module-import-declaration*](#nt:module-import-declaration "10.3 Import declaration [module.import]") nominating M[.](#9.sentence-1)
|
||||
|
||||
[*Example [2](#example-2)*: module M;import M; // error: cannot import M in its own unit â *end example*]
|
||||
|
||||
[10](#10)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/modules.tex#L560)
|
||||
|
||||
A translation unit has an [*interface dependency*](#def:interface_dependency "10.3 Import declaration [module.import]") on a translation unit U if it contains a declaration (possibly a [*module-declaration*](module.unit#nt:module-declaration "10.1 Module units and purviews [module.unit]"))
|
||||
that imports U or if it has
|
||||
an interface dependency on a translation unit that has an interface dependency on U[.](#10.sentence-1)
|
||||
|
||||
A translation unit shall not have an interface dependency on itself[.](#10.sentence-2)
|
||||
|
||||
[*Example [3](#example-3)*:
|
||||
|
||||
Interface unit of M1:export module M1;import M2;
|
||||
|
||||
Interface unit of M2:export module M2;import M3;
|
||||
|
||||
Interface unit of M3:export module M3;import M1; // error: cyclic interface dependency M3 âM1 âM2 âM3 â *end example*]
|
||||
|
||||
[85)](#footnote-85)[85)](#footnoteref-85)
|
||||
|
||||
This is consistent
|
||||
with the lookup rules for imported names ([[basic.lookup]](basic.lookup "6.5 Name lookup"))[.](#footnote-85.sentence-1)
|
||||
149
cppdraft/module/interface.md
Normal file
149
cppdraft/module/interface.md
Normal file
@@ -0,0 +1,149 @@
|
||||
[module.interface]
|
||||
|
||||
# 10 Modules [[module]](./#module)
|
||||
|
||||
## 10.2 Export declaration [module.interface]
|
||||
|
||||
[export-declaration:](#nt:export-declaration "10.2 Export declaration [module.interface]")
|
||||
export [*name-declaration*](dcl.pre#nt:name-declaration "9.1 Preamble [dcl.pre]")
|
||||
export { [*declaration-seq*](dcl.pre#nt:declaration-seq "9.1 Preamble [dcl.pre]")opt }
|
||||
export-keyword [*module-import-declaration*](module.import#nt:module-import-declaration "10.3 Import declaration [module.import]")
|
||||
|
||||
[1](#1)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/modules.tex#L206)
|
||||
|
||||
An [*export-declaration*](#nt:export-declaration "10.2 Export declaration [module.interface]") shall inhabit
|
||||
a namespace scope and appear in the purview of a module interface unit[.](#1.sentence-1)
|
||||
|
||||
An [*export-declaration*](#nt:export-declaration "10.2 Export declaration [module.interface]") shall not appear directly
|
||||
or indirectly within an unnamed namespace
|
||||
or a [*private-module-fragment*](module.private.frag#nt:private-module-fragment "10.5 Private module fragment [module.private.frag]")[.](#1.sentence-2)
|
||||
|
||||
An [*export-declaration*](#nt:export-declaration "10.2 Export declaration [module.interface]") has the declarative effects of its[*name-declaration*](dcl.pre#nt:name-declaration "9.1 Preamble [dcl.pre]"),[*declaration-seq*](dcl.pre#nt:declaration-seq "9.1 Preamble [dcl.pre]") (if any), or[*module-import-declaration*](module.import#nt:module-import-declaration "10.3 Import declaration [module.import]")[.](#1.sentence-3)
|
||||
|
||||
The [*name-declaration*](dcl.pre#nt:name-declaration "9.1 Preamble [dcl.pre]") of an [*export-declaration*](#nt:export-declaration "10.2 Export declaration [module.interface]") shall not declare a partial specialization ([[temp.decls.general]](temp.decls.general "13.7.1 General"))[.](#1.sentence-4)
|
||||
|
||||
The [*declaration-seq*](dcl.pre#nt:declaration-seq "9.1 Preamble [dcl.pre]") of
|
||||
an [*export-declaration*](#nt:export-declaration "10.2 Export declaration [module.interface]") shall not contain an [*export-declaration*](#nt:export-declaration "10.2 Export declaration [module.interface]") or[*module-import-declaration*](module.import#nt:module-import-declaration "10.3 Import declaration [module.import]")[.](#1.sentence-5)
|
||||
|
||||
[*Note [1](#note-1)*:
|
||||
|
||||
An [*export-declaration*](#nt:export-declaration "10.2 Export declaration [module.interface]") does not establish a scope[.](#1.sentence-6)
|
||||
|
||||
â *end note*]
|
||||
|
||||
[2](#2)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/modules.tex#L227)
|
||||
|
||||
A declaration is [*exported*](#def:declaration,exported "10.2 Export declaration [module.interface]") if it is
|
||||
declared within an [*export-declaration*](#nt:export-declaration "10.2 Export declaration [module.interface]") and
|
||||
inhabits a namespace scope or it is
|
||||
|
||||
- [(2.1)](#2.1)
|
||||
|
||||
a [*namespace-definition*](namespace.def.general#nt:namespace-definition "9.9.2.1 General [namespace.def.general]") that contains an
|
||||
exported declaration, or
|
||||
|
||||
- [(2.2)](#2.2)
|
||||
|
||||
a declaration within a header unit ([[module.import]](module.import "10.3 Import declaration"))
|
||||
that introduces at least one name[.](#2.sentence-1)
|
||||
|
||||
[3](#3)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/modules.tex#L238)
|
||||
|
||||
If an exported declaration is not within a header unit,
|
||||
it shall not declare a name with internal linkage[.](#3.sentence-1)
|
||||
|
||||
[4](#4)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/modules.tex#L242)
|
||||
|
||||
[*Example [1](#example-1)*:
|
||||
|
||||
Source file "a.h":export int x;
|
||||
|
||||
Translation unit #1:module;#include "a.h" // error: declaration of x is not in the// purview of a module interface unitexport module M;export namespace {} // error: namespace has internal linkagenamespace {export int a2; // error: export of name with internal linkage}export static int b; // error: b explicitly declared staticexport int f(); // OKexport namespace N { } // OKexport using namespace N; // OK â *end example*]
|
||||
|
||||
[5](#5)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/modules.tex#L264)
|
||||
|
||||
If an exported declaration is a [*using-declaration*](namespace.udecl#nt:using-declaration "9.10 The using declaration [namespace.udecl]") ([[namespace.udecl]](namespace.udecl "9.10 The using declaration"))
|
||||
and is not within a header unit,
|
||||
all entities named by the[*using-declarator*](namespace.udecl#nt:using-declarator "9.10 The using declaration [namespace.udecl]")*s* (if any)
|
||||
shall either be a type alias or
|
||||
have been introduced with a name having external linkage[.](#5.sentence-1)
|
||||
|
||||
[*Example [2](#example-2)*:
|
||||
|
||||
Source file "b.h":int f();
|
||||
|
||||
Importable header "c.h":int g();
|
||||
|
||||
Translation unit #1:export module X;export int h();
|
||||
|
||||
Translation unit #2:module;#include "b.h"export module M;import "c.h";import X;export using ::f, ::g, ::h; // OKstruct S;export using ::S; // error: S has module linkagenamespace N {export int h(); static int h(int); // #1}export using N::h; // error: #1 has internal linkage â *end example*]
|
||||
|
||||
[*Note [2](#note-2)*:
|
||||
|
||||
The underlying entity of an exported type alias
|
||||
need not have a name with external linkage[.](#5.sentence-2)
|
||||
|
||||
[*Example [3](#example-3)*: export module M;struct S;export using T = S; // OK, exports name T denoting type S â *end example*]
|
||||
|
||||
â *end note*]
|
||||
|
||||
[6](#6)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/modules.tex#L313)
|
||||
|
||||
A redeclaration of an entity X is implicitly exported
|
||||
if X was introduced by an exported declaration;
|
||||
otherwise it shall not be exported
|
||||
unless it is a type alias, a namespace, or a namespace alias[.](#6.sentence-1)
|
||||
|
||||
[*Example [4](#example-4)*: export module M;struct S { int n; };typedef S S;export typedef S S; // OKexport struct S; // error: exported declaration follows non-exported declarationnamespace N { // external linkage, attached to global module, not exportedvoid f();}namespace N { // OK, exported namespace redeclaring non-exported namespaceexport void g();} â *end example*]
|
||||
|
||||
[7](#7)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/modules.tex#L335)
|
||||
|
||||
[*Note [3](#note-3)*:
|
||||
|
||||
Names introduced by exported declarations
|
||||
have either external linkage or no linkage; see [[basic.link]](basic.link "6.7 Program and linkage")[.](#7.sentence-1)
|
||||
|
||||
Namespace-scope declarations exported by a module can be found by name lookup
|
||||
in any translation unit importing that module ([[basic.lookup]](basic.lookup "6.5 Name lookup"))[.](#7.sentence-2)
|
||||
|
||||
Class and enumeration member names can be found by name lookup in any
|
||||
context in which a definition of the type is reachable[.](#7.sentence-3)
|
||||
|
||||
â *end note*]
|
||||
|
||||
[*Example [5](#example-5)*:
|
||||
|
||||
Interface unit of M:export module M;export struct X {static void f(); struct Y { };};
|
||||
|
||||
namespace {struct S { };}export void f(S); // OKstruct T { };export T id(T); // OKexport struct A; // A exported as incompleteexport auto rootFinder(double a) {return [=](double x) { return (x + a/x)/2; };}export const int n = 5; // OK, n has external linkage
|
||||
|
||||
Implementation unit of M:module M;struct A {int value;};
|
||||
|
||||
Main program:import M;int main() { X::f(); // OK, X is exported and definition of X is reachable X::Y y; // OK, X::Y is exported as a complete typeauto f = rootFinder(2); // OKreturn A{45}.value; // error: A is incomplete} â *end example*]
|
||||
|
||||
[8](#8)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/modules.tex#L386)
|
||||
|
||||
[*Note [4](#note-4)*:
|
||||
|
||||
Declarations in an exported [*namespace-definition*](namespace.def.general#nt:namespace-definition "9.9.2.1 General [namespace.def.general]") or in an exported [*linkage-specification*](dcl.link#nt:linkage-specification "9.12 Linkage specifications [dcl.link]") ([[dcl.link]](dcl.link "9.12 Linkage specifications"))
|
||||
are exported and subject to the rules of exported declarations[.](#8.sentence-1)
|
||||
|
||||
[*Example [6](#example-6)*: export module M;int g;export namespace N {int x; // OKusing ::g; // error: ::g has module linkage} â *end example*]
|
||||
|
||||
â *end note*]
|
||||
72
cppdraft/module/private/frag.md
Normal file
72
cppdraft/module/private/frag.md
Normal file
@@ -0,0 +1,72 @@
|
||||
[module.private.frag]
|
||||
|
||||
# 10 Modules [[module]](./#module)
|
||||
|
||||
## 10.5 Private module fragment [module.private.frag]
|
||||
|
||||
[private-module-fragment:](#nt:private-module-fragment "10.5 Private module fragment [module.private.frag]")
|
||||
module-keyword : private ; [*declaration-seq*](dcl.pre#nt:declaration-seq "9.1 Preamble [dcl.pre]")opt
|
||||
|
||||
[1](#1)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/modules.tex#L814)
|
||||
|
||||
A [*private-module-fragment*](#nt:private-module-fragment "10.5 Private module fragment [module.private.frag]") shall appear only
|
||||
in a primary module interface unit ([[module.unit]](module.unit "10.1 Module units and purviews"))[.](#1.sentence-1)
|
||||
|
||||
A module unit with a [*private-module-fragment*](#nt:private-module-fragment "10.5 Private module fragment [module.private.frag]") shall be the only module unit of its module;
|
||||
no diagnostic is required[.](#1.sentence-2)
|
||||
|
||||
[2](#2)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/modules.tex#L821)
|
||||
|
||||
[*Note [1](#note-1)*:
|
||||
|
||||
A [*private-module-fragment*](#nt:private-module-fragment "10.5 Private module fragment [module.private.frag]") ends
|
||||
the portion of the module interface unit
|
||||
that can affect the behavior of other translation units[.](#2.sentence-1)
|
||||
|
||||
A [*private-module-fragment*](#nt:private-module-fragment "10.5 Private module fragment [module.private.frag]") allows a module
|
||||
to be represented as a single translation unit
|
||||
without making all of the contents of the module reachable to importers[.](#2.sentence-2)
|
||||
|
||||
The presence of a [*private-module-fragment*](#nt:private-module-fragment "10.5 Private module fragment [module.private.frag]") affects:
|
||||
|
||||
- [(2.1)](#2.1)
|
||||
|
||||
the point by which the definition of
|
||||
an inline function or variable
|
||||
is required ([[dcl.inline]](dcl.inline "9.2.8 The inline specifier")),
|
||||
|
||||
- [(2.2)](#2.2)
|
||||
|
||||
the point by which the definition of
|
||||
an exported function with a placeholder return type
|
||||
is required ([[dcl.spec.auto]](dcl.spec.auto "9.2.9.7 Placeholder type specifiers")),
|
||||
|
||||
- [(2.3)](#2.3)
|
||||
|
||||
whether a declaration is required not to be an exposure ([[basic.link]](basic.link "6.7 Program and linkage")),
|
||||
|
||||
- [(2.4)](#2.4)
|
||||
|
||||
where definitions for inline functions and templates
|
||||
must appear ([[basic.def.odr]](basic.def.odr "6.3 One-definition rule"), [[dcl.inline]](dcl.inline "9.2.8 The inline specifier"), [[temp.pre]](temp.pre "13.1 Preamble")),
|
||||
|
||||
- [(2.5)](#2.5)
|
||||
|
||||
the instantiation contexts of templates
|
||||
instantiated before it ([[module.context]](module.context "10.6 Instantiation context")), and
|
||||
|
||||
- [(2.6)](#2.6)
|
||||
|
||||
the reachability of declarations within it ([[module.reach]](module.reach "10.7 Reachability"))[.](#2.sentence-3)
|
||||
|
||||
â *end note*]
|
||||
|
||||
[3](#3)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/modules.tex#L857)
|
||||
|
||||
[*Example [1](#example-1)*: export module A;export inline void fn_e(); // error: exported inline function fn_e not defined// before private module fragmentinline void fn_m(); // error: non-exported inline function fn_m not definedstatic void fn_s();export struct X;export void g(X *x) { fn_s(); // OK, call to static function in same translation unit}export X *factory(); // OKmodule :private;struct X {}; // definition not reachable from importers of A X *factory() {return new X ();}void fn_e() {}void fn_m() {}void fn_s() {} â *end example*]
|
||||
154
cppdraft/module/reach.md
Normal file
154
cppdraft/module/reach.md
Normal file
@@ -0,0 +1,154 @@
|
||||
[module.reach]
|
||||
|
||||
# 10 Modules [[module]](./#module)
|
||||
|
||||
## 10.7 Reachability [module.reach]
|
||||
|
||||
[1](#1)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/modules.tex#L1006)
|
||||
|
||||
A translation unit U is[*necessarily reachable*](#def:reachable,necessarily,translation_unit "10.7 Reachability [module.reach]") from a point P ifU is a module interface unit on which the translation unit containing P has an interface dependency, or
|
||||
the translation unit containing P imports U,
|
||||
in either case prior to P ([[module.import]](module.import "10.3 Import declaration"))[.](#1.sentence-1)
|
||||
|
||||
[*Note [1](#note-1)*:
|
||||
|
||||
While module interface units are reachable even when they are only
|
||||
transitively imported via a non-exported import declaration,
|
||||
namespace-scope names from such module interface units are not found by
|
||||
name lookup ([[basic.lookup]](basic.lookup "6.5 Name lookup"))[.](#1.sentence-2)
|
||||
|
||||
â *end note*]
|
||||
|
||||
[2](#2)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/modules.tex#L1021)
|
||||
|
||||
All translation units that are necessarily reachable are[*reachable*](#def:reachable,translation_unit "10.7 Reachability [module.reach]")[.](#2.sentence-1)
|
||||
|
||||
Additional translation units on which the
|
||||
point within the program has an interface dependency may be considered reachable,
|
||||
but it is unspecified which are and under what circumstances[.](#2.sentence-2)[87](#footnote-87 "Implementations are therefore not required to prevent the semantic effects of additional translation units involved in the compilation from being observed.")
|
||||
|
||||
[*Note [2](#note-2)*:
|
||||
|
||||
It is advisable to avoid
|
||||
depending on the reachability of any additional translation units
|
||||
in programs intending to be portable[.](#2.sentence-3)
|
||||
|
||||
â *end note*]
|
||||
|
||||
[3](#3)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/modules.tex#L1038)
|
||||
|
||||
A declaration D is[*reachable from*](#def:reachable_from,declaration "10.7 Reachability [module.reach]") a point P if
|
||||
|
||||
- [(3.1)](#3.1)
|
||||
|
||||
P is a non-synthesized point and
|
||||
* [(3.1.1)](#3.1.1)
|
||||
|
||||
D appears prior to P in the same translation unit, or
|
||||
|
||||
* [(3.1.2)](#3.1.2)
|
||||
|
||||
D is not discarded ([[module.global.frag]](module.global.frag "10.4 Global module fragment")),
|
||||
appears in a translation unit that is
|
||||
reachable from P,
|
||||
and
|
||||
does not appear within a [*private-module-fragment*](module.private.frag#nt:private-module-fragment "10.5 Private module fragment [module.private.frag]"); or
|
||||
|
||||
- [(3.2)](#3.2)
|
||||
|
||||
D is the injected declaration
|
||||
for which P is the corresponding synthesized point[.](#3.sentence-1)
|
||||
|
||||
[*Example [1](#example-1)*: class Incomplete;
|
||||
|
||||
consteval {int n = nonstatic_data_members_of( define_aggregate(^^Incomplete, {data_member_spec(^^int, {.name="x"})}),
|
||||
std::meta::access_context::current()).size();
|
||||
|
||||
Incomplete y; // error: type of y is incomplete}/* P */
|
||||
|
||||
The value of n is 1[.](#3.sentence-2)
|
||||
|
||||
The member Incomplete::x members-of-precedes ([[meta.reflection.member.queries]](meta.reflection.member.queries "21.4.10 Reflection member queries"))
|
||||
the synthesized point P associated with the injected declaration
|
||||
produced by the call to define_aggregate[.](#3.sentence-3)
|
||||
|
||||
â *end example*]
|
||||
|
||||
[4](#4)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/modules.tex#L1077)
|
||||
|
||||
A declaration is [*reachable*](#def:reachable,declaration "10.7 Reachability [module.reach]") if it is reachable from
|
||||
any point in the instantiation context ([[module.context]](module.context "10.6 Instantiation context"))[.](#4.sentence-1)
|
||||
|
||||
[*Note [3](#note-3)*:
|
||||
|
||||
Whether a declaration is exported has no bearing on whether it is reachable[.](#4.sentence-2)
|
||||
|
||||
â *end note*]
|
||||
|
||||
[5](#5)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/modules.tex#L1085)
|
||||
|
||||
The accumulated properties of all reachable declarations of
|
||||
an entity within a context
|
||||
determine the behavior of the entity within that context[.](#5.sentence-1)
|
||||
|
||||
[*Note [4](#note-4)*:
|
||||
|
||||
These reachable semantic properties include type completeness,
|
||||
type definitions, initializers,
|
||||
default arguments of functions or template declarations, attributes,
|
||||
names bound, etc[.](#5.sentence-2)
|
||||
|
||||
Since default arguments are evaluated in the context of the call expression,
|
||||
the reachable semantic properties of the corresponding parameter types apply in
|
||||
that context[.](#5.sentence-3)
|
||||
|
||||
[*Example [2](#example-2)*:
|
||||
|
||||
Translation unit #1:export module M:A;export struct B;
|
||||
|
||||
Translation unit #2:module M:B;struct B {operator int();};
|
||||
|
||||
Translation unit #3:module M:C;import :A;
|
||||
B b1; // error: no reachable definition of struct B
|
||||
|
||||
Translation unit #4:export module M;export import :A;import :B;
|
||||
B b2;export void f(B b = B());
|
||||
|
||||
Translation unit #5:import M;
|
||||
B b3; // error: no reachable definition of struct Bvoid g() { f(); } // error: no reachable definition of struct B â *end example*]
|
||||
|
||||
â *end note*]
|
||||
|
||||
[6](#6)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/modules.tex#L1132)
|
||||
|
||||
[*Note [5](#note-5)*:
|
||||
|
||||
Declarations of an entity can be reachable
|
||||
even where they cannot be found by name lookup[.](#6.sentence-1)
|
||||
|
||||
â *end note*]
|
||||
|
||||
[*Example [3](#example-3)*:
|
||||
|
||||
Translation unit #1:export module A;struct X {};export using Y = X;
|
||||
|
||||
Translation unit #2:import A;
|
||||
Y y; // OK, definition of X is reachable X x; // error: X not visible to unqualified lookup â *end example*]
|
||||
|
||||
[87)](#footnote-87)[87)](#footnoteref-87)
|
||||
|
||||
Implementations are therefore not required to prevent the semantic
|
||||
effects of additional translation units involved in the compilation from being
|
||||
observed[.](#footnote-87.sentence-1)
|
||||
207
cppdraft/module/unit.md
Normal file
207
cppdraft/module/unit.md
Normal file
@@ -0,0 +1,207 @@
|
||||
[module.unit]
|
||||
|
||||
# 10 Modules [[module]](./#module)
|
||||
|
||||
## 10.1 Module units and purviews [module.unit]
|
||||
|
||||
[module-declaration:](#nt:module-declaration "10.1 Module units and purviews [module.unit]")
|
||||
export-keywordopt module-keyword [*module-name*](#nt:module-name "10.1 Module units and purviews [module.unit]") [*module-partition*](#nt:module-partition "10.1 Module units and purviews [module.unit]")opt [*attribute-specifier-seq*](dcl.attr.grammar#nt:attribute-specifier-seq "9.13.1 Attribute syntax and semantics [dcl.attr.grammar]")opt ;
|
||||
|
||||
[module-name:](#nt:module-name "10.1 Module units and purviews [module.unit]")
|
||||
[*module-name-qualifier*](#nt:module-name-qualifier "10.1 Module units and purviews [module.unit]")opt [*identifier*](lex.name#nt:identifier "5.11 Identifiers [lex.name]")
|
||||
|
||||
[module-partition:](#nt:module-partition "10.1 Module units and purviews [module.unit]")
|
||||
: [*module-name-qualifier*](#nt:module-name-qualifier "10.1 Module units and purviews [module.unit]")opt [*identifier*](lex.name#nt:identifier "5.11 Identifiers [lex.name]")
|
||||
|
||||
[module-name-qualifier:](#nt:module-name-qualifier "10.1 Module units and purviews [module.unit]")
|
||||
[*identifier*](lex.name#nt:identifier "5.11 Identifiers [lex.name]") .
|
||||
[*module-name-qualifier*](#nt:module-name-qualifier "10.1 Module units and purviews [module.unit]") [*identifier*](lex.name#nt:identifier "5.11 Identifiers [lex.name]") .
|
||||
|
||||
[1](#1)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/modules.tex#L29)
|
||||
|
||||
A [*module unit*](#def:module_unit "10.1 Module units and purviews [module.unit]") is a translation unit that contains
|
||||
a [*module-declaration*](#nt:module-declaration "10.1 Module units and purviews [module.unit]")[.](#1.sentence-1)
|
||||
|
||||
A [*named module*](#def:module,named "10.1 Module units and purviews [module.unit]") is the
|
||||
collection of module units with the same [*module-name*](#nt:module-name "10.1 Module units and purviews [module.unit]")[.](#1.sentence-2)
|
||||
|
||||
The identifiers module and import shall not appear as [*identifier*](lex.name#nt:identifier "5.11 Identifiers [lex.name]")*s* in a [*module-name*](#nt:module-name "10.1 Module units and purviews [module.unit]") or [*module-partition*](#nt:module-partition "10.1 Module units and purviews [module.unit]")[.](#1.sentence-3)
|
||||
|
||||
All [*module-name*](#nt:module-name "10.1 Module units and purviews [module.unit]")*s* either beginning with an [*identifier*](lex.name#nt:identifier "5.11 Identifiers [lex.name]") consisting of std followed by zero or more [*digit*](lex.name#nt:digit "5.11 Identifiers [lex.name]")*s* or
|
||||
containing a reserved identifier ([[lex.name]](lex.name "5.11 Identifiers"))
|
||||
are reserved and shall not be specified in a [*module-declaration*](#nt:module-declaration "10.1 Module units and purviews [module.unit]");
|
||||
no diagnostic is required[.](#1.sentence-4)
|
||||
|
||||
If any [*identifier*](lex.name#nt:identifier "5.11 Identifiers [lex.name]") in a reserved [*module-name*](#nt:module-name "10.1 Module units and purviews [module.unit]") is a reserved identifier,
|
||||
the module name is reserved for use by C++ implementations;
|
||||
otherwise it is reserved for future standardization[.](#1.sentence-5)
|
||||
|
||||
The optional [*attribute-specifier-seq*](dcl.attr.grammar#nt:attribute-specifier-seq "9.13.1 Attribute syntax and semantics [dcl.attr.grammar]") appertains to the [*module-declaration*](#nt:module-declaration "10.1 Module units and purviews [module.unit]")[.](#1.sentence-6)
|
||||
|
||||
[2](#2)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/modules.tex#L50)
|
||||
|
||||
A [*module interface unit*](#def:module_interface_unit "10.1 Module units and purviews [module.unit]") is a module unit whose[*module-declaration*](#nt:module-declaration "10.1 Module units and purviews [module.unit]") starts with *export-keyword*;
|
||||
any other module unit is a [*module implementation unit*](#def:module_implementation_unit "10.1 Module units and purviews [module.unit]")[.](#2.sentence-1)
|
||||
|
||||
A named module shall contain exactly one module interface unit
|
||||
with no [*module-partition*](#nt:module-partition "10.1 Module units and purviews [module.unit]"), known as the[*primary module interface unit*](#def:primary_module_interface_unit "10.1 Module units and purviews [module.unit]") of the module;
|
||||
no diagnostic is required[.](#2.sentence-2)
|
||||
|
||||
[3](#3)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/modules.tex#L59)
|
||||
|
||||
A [*module partition*](#def:module_partition "10.1 Module units and purviews [module.unit]") is
|
||||
a module unit whose [*module-declaration*](#nt:module-declaration "10.1 Module units and purviews [module.unit]") contains
|
||||
a [*module-partition*](#nt:module-partition "10.1 Module units and purviews [module.unit]")[.](#3.sentence-1)
|
||||
|
||||
A named module shall not contain multiple module partitions with
|
||||
the same [*module-partition*](#nt:module-partition "10.1 Module units and purviews [module.unit]")[.](#3.sentence-2)
|
||||
|
||||
All module partitions of a module
|
||||
that are module interface units
|
||||
shall be directly or indirectly exported
|
||||
by the primary module interface unit ([[module.import]](module.import "10.3 Import declaration"))[.](#3.sentence-3)
|
||||
|
||||
No diagnostic is required for a violation of these rules[.](#3.sentence-4)
|
||||
|
||||
[*Note [1](#note-1)*:
|
||||
|
||||
Module partitions can be imported only by
|
||||
other module units in the same module[.](#3.sentence-5)
|
||||
|
||||
The division of a module into module units
|
||||
is not visible outside the module[.](#3.sentence-6)
|
||||
|
||||
â *end note*]
|
||||
|
||||
[4](#4)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/modules.tex#L77)
|
||||
|
||||
[*Example [1](#example-1)*:
|
||||
|
||||
Translation unit #1:export module A;export import :Foo;export int baz();
|
||||
|
||||
Translation unit #2:export module A:Foo;import :Internals;export int foo() { return 2 * (bar() + 1); }
|
||||
|
||||
Translation unit #3:module A:Internals;int bar();
|
||||
|
||||
Translation unit #4:module A;import :Internals;int bar() { return baz() - 10; }int baz() { return 30; }
|
||||
|
||||
Module A contains four translation units:
|
||||
|
||||
- [(4.1)](#4.1)
|
||||
|
||||
a primary module interface unit,
|
||||
|
||||
- [(4.2)](#4.2)
|
||||
|
||||
a module partition A:Foo, which is a module interface unit
|
||||
forming part of the interface of module A,
|
||||
|
||||
- [(4.3)](#4.3)
|
||||
|
||||
a module partition A:Internals, which does not contribute
|
||||
to the external interface of module A, and
|
||||
|
||||
- [(4.4)](#4.4)
|
||||
|
||||
a module implementation unit providing
|
||||
a definition of bar and baz,
|
||||
which cannot be imported because
|
||||
it does not have a partition name[.](#4.sentence-1)
|
||||
|
||||
â *end example*]
|
||||
|
||||
[5](#5)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/modules.tex#L117)
|
||||
|
||||
A [*module unit purview*](#def:purview,module_unit "10.1 Module units and purviews [module.unit]") is
|
||||
the sequence of [*token*](lex.token#nt:token "5.10 Tokens [lex.token]")*s* starting at the [*module-declaration*](#nt:module-declaration "10.1 Module units and purviews [module.unit]") and extending to the end of the translation unit[.](#5.sentence-1)
|
||||
|
||||
The [*purview*](#def:purview,named_module "10.1 Module units and purviews [module.unit]") of a named module M is the set of module unit purviews
|
||||
of M's module units[.](#5.sentence-2)
|
||||
|
||||
[6](#6)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/modules.tex#L126)
|
||||
|
||||
The [*global module*](#def:module,global "10.1 Module units and purviews [module.unit]") is the collection of all[*global-module-fragment*](module.global.frag#nt:global-module-fragment "10.4 Global module fragment [module.global.frag]")*s* and all translation units that are not module units[.](#6.sentence-1)
|
||||
|
||||
Declarations appearing in such a context
|
||||
are said to be in the [*purview*](#def:purview,global_module "10.1 Module units and purviews [module.unit]") of the global module[.](#6.sentence-2)
|
||||
|
||||
[*Note [2](#note-2)*:
|
||||
|
||||
The global module has no name, no module interface unit, and is not
|
||||
introduced by any [*module-declaration*](#nt:module-declaration "10.1 Module units and purviews [module.unit]")[.](#6.sentence-3)
|
||||
|
||||
â *end note*]
|
||||
|
||||
[7](#7)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/modules.tex#L137)
|
||||
|
||||
A [*module*](#def:module "10.1 Module units and purviews [module.unit]") is either a named module or the global module[.](#7.sentence-1)
|
||||
|
||||
A declaration is [*attached*](#def:attached,declaration "10.1 Module units and purviews [module.unit]") to a module as follows:
|
||||
|
||||
- [(7.1)](#7.1)
|
||||
|
||||
If the declaration is a non-dependent friend declaration
|
||||
that nominates a function with a [*declarator-id*](dcl.decl.general#nt:declarator-id "9.3.1 General [dcl.decl.general]") that is a [*qualified-id*](expr.prim.id.qual#nt:qualified-id "7.5.5.3 Qualified names [expr.prim.id.qual]") or [*template-id*](temp.names#nt:template-id "13.3 Names of template specializations [temp.names]") or
|
||||
that nominates a class
|
||||
other than with an [*elaborated-type-specifier*](dcl.type.elab#nt:elaborated-type-specifier "9.2.9.5 Elaborated type specifiers [dcl.type.elab]") with neither
|
||||
a [*nested-name-specifier*](expr.prim.id.qual#nt:nested-name-specifier "7.5.5.3 Qualified names [expr.prim.id.qual]") nor a [*simple-template-id*](temp.names#nt:simple-template-id "13.3 Names of template specializations [temp.names]"),
|
||||
it is attached to the module to which the friend is attached ([[basic.link]](basic.link "6.7 Program and linkage"))[.](#7.1.sentence-1)
|
||||
|
||||
- [(7.2)](#7.2)
|
||||
|
||||
Otherwise, if the declaration
|
||||
* [(7.2.1)](#7.2.1)
|
||||
|
||||
declares a namespace whose name has external linkage,
|
||||
|
||||
* [(7.2.2)](#7.2.2)
|
||||
|
||||
declares a type alias,
|
||||
|
||||
* [(7.2.3)](#7.2.3)
|
||||
|
||||
declares a namespace alias, or
|
||||
|
||||
* [(7.2.4)](#7.2.4)
|
||||
|
||||
appears within a [*linkage-specification*](dcl.link#nt:linkage-specification "9.12 Linkage specifications [dcl.link]") ([[dcl.link]](dcl.link "9.12 Linkage specifications"))
|
||||
|
||||
it is attached to the global module[.](#7.2.sentence-1)
|
||||
|
||||
- [(7.3)](#7.3)
|
||||
|
||||
Otherwise, the declaration is
|
||||
attached to the module in whose purview it appears[.](#7.3.sentence-1)
|
||||
|
||||
[8](#8)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/modules.tex#L162)
|
||||
|
||||
A [*module-declaration*](#nt:module-declaration "10.1 Module units and purviews [module.unit]") that contains neither an *export-keyword* nor a [*module-partition*](#nt:module-partition "10.1 Module units and purviews [module.unit]") implicitly imports the primary module interface unit of the module
|
||||
as if by a [*module-import-declaration*](module.import#nt:module-import-declaration "10.3 Import declaration [module.import]")[.](#8.sentence-1)
|
||||
|
||||
[*Example [2](#example-2)*:
|
||||
|
||||
Translation unit #1:module B:Y; // does not implicitly import Bint y();
|
||||
|
||||
Translation unit #2:export module B;import :Y; // OK, does not create interface dependency cycleint n = y();
|
||||
|
||||
Translation unit #3:module B:X1; // does not implicitly import Bint &a = n; // error: n not visible here
|
||||
|
||||
Translation unit #4:module B:X2; // does not implicitly import Bimport B;int &b = n; // OK
|
||||
|
||||
Translation unit #5:module B; // implicitly imports Bint &c = n; // OK â *end example*]
|
||||
Reference in New Issue
Block a user