From Jason Turner

[expr.prim.id.unqual]

Diff to HTML by rtfpessoa

Files changed (1) hide show
  1. tmp/tmpyy1f0fws/{from.md → to.md} +147 -53
tmp/tmpyy1f0fws/{from.md → to.md} RENAMED
@@ -5,27 +5,24 @@ unqualified-id:
5
  identifier
6
  operator-function-id
7
  conversion-function-id
8
  literal-operator-id
9
  '~' type-name
10
- '~' decltype-specifier
11
  template-id
12
  ```
13
 
14
  An *identifier* is only an *id-expression* if it has been suitably
15
- declared [[dcl.dcl]] or if it appears as part of a *declarator-id*
16
- [[dcl.decl]]. An *identifier* that names a coroutine parameter refers to
17
- the copy of the parameter [[dcl.fct.def.coroutine]].
18
 
19
  [*Note 1*: For *operator-function-id*s, see  [[over.oper]]; for
20
  *conversion-function-id*s, see  [[class.conv.fct]]; for
21
  *literal-operator-id*s, see  [[over.literal]]; for *template-id*s, see 
22
- [[temp.names]]. A *type-name* or *decltype-specifier* prefixed by `~`
23
- denotes the destructor of the type so named; see  [[expr.prim.id.dtor]].
24
- Within the definition of a non-static member function, an *identifier*
25
- that names a non-static member is transformed to a class member access
26
- expression [[class.mfct.non.static]]. — *end note*]
27
 
28
  A *component name* of an *unqualified-id* U is
29
 
30
  - U if it is a name or
31
  - the component name of the *template-id* or *type-name* of U, if any.
@@ -36,46 +33,147 @@ several component names
36
 
37
  The *terminal name* of a construct is the component name of that
38
  construct that appears lexically last.
39
 
40
  The result is the entity denoted by the *unqualified-id*
41
- [[basic.lookup.unqual]]. If the *unqualified-id* appears in a
42
- *lambda-expression* at program point P and the entity is a local entity
43
- [[basic.pre]] or a variable declared by an *init-capture*
44
- [[expr.prim.lambda.capture]], then let S be the *compound-statement* of
45
- the innermost enclosing *lambda-expression* of P. If naming the entity
46
- from outside of an unevaluated operand within S would refer to an entity
47
- captured by copy in some intervening *lambda-expression*, then let E be
48
- the innermost such *lambda-expression*.
49
-
50
- - If there is such a *lambda-expression* and if P is in E’s function
51
- parameter scope but not its *parameter-declaration-clause*, then the
52
- type of the expression is the type of a class member access expression
53
- [[expr.ref]] naming the non-static data member that would be declared
54
- for such a capture in the object parameter [[dcl.fct]] of the function
55
- call operator of E. \[*Note 3*: If E is not declared `mutable`, the
56
- type of such an identifier will typically be `const`
57
- qualified. *end note*]
58
- - Otherwise (if there is no such *lambda-expression* or if P either
59
- precedes E’s function parameter scope or is in E’s
60
- *parameter-declaration-clause*), the type of the expression is the
61
- type of the result.
62
-
63
- [*Note 4*: If the entity is a template parameter object for a template
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
64
  parameter of type `T` [[temp.param]], the type of the expression is
65
- `const T`. — *end note*]
66
 
67
- [*Note 5*: The type will be adjusted as described in [[expr.type]] if
 
 
 
68
  it is cv-qualified or is a reference type. — *end note*]
69
 
70
  The expression is an xvalue if it is move-eligible (see below); an
71
  lvalue if the entity is a function, variable, structured binding
72
- [[dcl.struct.bind]], data member, or template parameter object; and a
73
- prvalue otherwise [[basic.lval]]; it is a bit-field if the identifier
74
- designates a bit-field.
75
 
76
- [*Example 1*:
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
77
 
78
  ``` cpp
79
  void f() {
80
  float x, &r = x;
81
 
@@ -102,23 +200,19 @@ void f() {
102
  }
103
  ```
104
 
105
  — *end example*]
106
 
107
- An *implicitly movable entity* is a variable of automatic storage
108
  duration that is either a non-volatile object or an rvalue reference to
109
- a non-volatile object type. In the following contexts, an
110
- *id-expression* is *move-eligible*:
111
 
112
- - If the *id-expression* (possibly parenthesized) is the operand of a
113
- `return` [[stmt.return]] or `co_return` [[stmt.return.coroutine]]
114
- statement, and names an implicitly movable entity declared in the body
115
- or *parameter-declaration-clause* of the innermost enclosing function
116
- or *lambda-expression*, or
117
- - if the *id-expression* (possibly parenthesized) is the operand of a
118
- *throw-expression* [[expr.throw]], and names an implicitly movable
119
- entity that belongs to a scope that does not contain the
120
- *compound-statement* of the innermost *lambda-expression*,
121
- *try-block*, or *function-try-block* (if any) whose
122
- *compound-statement* or *ctor-initializer* contains the
123
- *throw-expression*.
124
 
 
5
  identifier
6
  operator-function-id
7
  conversion-function-id
8
  literal-operator-id
9
  '~' type-name
10
+ '~' computed-type-specifier
11
  template-id
12
  ```
13
 
14
  An *identifier* is only an *id-expression* if it has been suitably
15
+ declared [[dcl]] or if it appears as part of a *declarator-id*
16
+ [[dcl.decl]].
 
17
 
18
  [*Note 1*: For *operator-function-id*s, see  [[over.oper]]; for
19
  *conversion-function-id*s, see  [[class.conv.fct]]; for
20
  *literal-operator-id*s, see  [[over.literal]]; for *template-id*s, see 
21
+ [[temp.names]]. A *type-name* or *computed-type-specifier* prefixed by
22
+ `~` denotes the destructor of the type so named; see 
23
+ [[expr.prim.id.dtor]]. *end note*]
 
 
24
 
25
  A *component name* of an *unqualified-id* U is
26
 
27
  - U if it is a name or
28
  - the component name of the *template-id* or *type-name* of U, if any.
 
33
 
34
  The *terminal name* of a construct is the component name of that
35
  construct that appears lexically last.
36
 
37
  The result is the entity denoted by the *unqualified-id*
38
+ [[basic.lookup.unqual]].
39
+
40
+ If
41
+
42
+ - the *unqualified-id* appears in a *lambda-expression* at program point
43
+ P,
44
+ - the entity is a local entity [[basic.pre]] or a variable declared by
45
+ an *init-capture* [[expr.prim.lambda.capture]],
46
+ - naming the entity within the *compound-statement* of the innermost
47
+ enclosing *lambda-expression* of P, but not in an unevaluated operand,
48
+ would refer to an entity captured by copy in some intervening
49
+ *lambda-expression*, and
50
+ - P is in the function parameter scope, but not the
51
+ *parameter-declaration-clause*, of the innermost such
52
+ *lambda-expression* E,
53
+
54
+ then the type of the expression is the type of a class member access
55
+ expression [[expr.ref]] naming the non-static data member that would be
56
+ declared for such a capture in the object parameter [[dcl.fct]] of the
57
+ function call operator of E.
58
+
59
+ [*Note 3*: If E is not declared `mutable`, the type of such an
60
+ identifier will typically be `const` qualified. *end note*]
61
+
62
+ Otherwise, if the *unqualified-id* names a coroutine parameter, the type
63
+ of the expression is that of the copy of the parameter
64
+ [[dcl.fct.def.coroutine]], and the result is that copy.
65
+
66
+ Otherwise, if the *unqualified-id* names a result binding
67
+ [[dcl.contract.res]] attached to a function with return type `U`,
68
+
69
+ - if `U` is “reference to `T`”, then the type of the expression is
70
+ `const T`;
71
+ - otherwise, the type of the expression is `const U`.
72
+
73
+ Otherwise, if the *unqualified-id* appears in the predicate of a
74
+ contract assertion C [[basic.contract]] and the entity is
75
+
76
+ - a variable declared outside of C of object type `T`,
77
+ - a variable or template parameter declared outside of C of type
78
+ “reference to `T`”, or
79
+ - a structured binding of type `T` whose corresponding variable is
80
+ declared outside of C,
81
+
82
+ then the type of the expression is `const` `T`.
83
+
84
+ [*Example 1*:
85
+
86
+ ``` cpp
87
+ int n = 0;
88
+ struct X { bool m(); };
89
+
90
+ struct Y {
91
+ int z = 0;
92
+
93
+ void f(int i, int* p, int& r, X x, X* px)
94
+ pre (++n) // error: attempting to modify const lvalue
95
+ pre (++i) // error: attempting to modify const lvalue
96
+ pre (++(*p)) // OK
97
+ pre (++r) // error: attempting to modify const lvalue
98
+ pre (x.m()) // error: calling non-const member function
99
+ pre (px->m()) // OK
100
+ pre ([=,&i,*this] mutable {
101
+ ++n; // error: attempting to modify const lvalue
102
+ ++i; // error: attempting to modify const lvalue
103
+ ++p; // OK, refers to member of closure type
104
+ ++r; // OK, refers to non-reference member of closure type
105
+ ++this->z; // OK, captured *this
106
+ ++z; // OK, captured *this
107
+ int j = 17;
108
+ [&]{
109
+ int k = 34;
110
+ ++i; // error: attempting to modify const lvalue
111
+ ++j; // OK
112
+ ++k; // OK
113
+ }();
114
+ return true;
115
+ }());
116
+
117
+ template <int N, int& R, int* P>
118
+ void g()
119
+ pre(++N) // error: attempting to modify prvalue
120
+ pre(++R) // error: attempting to modify const lvalue
121
+ pre(++(*P)); // OK
122
+
123
+ int h()
124
+ post(r : ++r) // error: attempting to modify const lvalue
125
+ post(r: [=] mutable {
126
+ ++r; // OK, refers to member of closure type
127
+ return true;
128
+ }());
129
+
130
+ int& k()
131
+ post(r : ++r); // error: attempting to modify const lvalue
132
+ };
133
+ ```
134
+
135
+ — *end example*]
136
+
137
+ Otherwise, if the entity is a template parameter object for a template
138
  parameter of type `T` [[temp.param]], the type of the expression is
139
+ `const T`.
140
 
141
+ In all other cases, the type of the expression is the type of the
142
+ entity.
143
+
144
+ [*Note 4*: The type will be adjusted as described in [[expr.type]] if
145
  it is cv-qualified or is a reference type. — *end note*]
146
 
147
  The expression is an xvalue if it is move-eligible (see below); an
148
  lvalue if the entity is a function, variable, structured binding
149
+ [[dcl.struct.bind]], result binding [[dcl.contract.res]], data member,
150
+ or template parameter object; and a prvalue otherwise [[basic.lval]]; it
151
+ is a bit-field if the identifier designates a bit-field.
152
 
153
+ If an *id-expression* E appears in the predicate of a function contract
154
+ assertion attached to a function *f* and denotes a function parameter of
155
+ *f* and the implementation introduces any temporary objects to hold the
156
+ value of that parameter as specified in [[class.temporary]],
157
+
158
+ - if the contract assertion is a precondition assertion and the
159
+ evaluation of the precondition assertion is sequenced before the
160
+ initialization of the parameter object, E refers to the most recently
161
+ initialized such temporary object, and
162
+ - if the contract assertion is a postcondition assertion, it is
163
+ unspecified whether E refers to one of the temporary objects or the
164
+ parameter object; the choice is consistent within a single evaluation
165
+ of a postcondition assertion.
166
+
167
+ If an *id-expression* E names a result binding in a postcondition
168
+ assertion and the implementation introduces any temporary objects to
169
+ hold the result object as specified in [[class.temporary]], and the
170
+ postcondition assertion is sequenced before the initialization of the
171
+ result object [[expr.call]], E refers to the most recently initialized
172
+ such temporary object.
173
+
174
+ [*Example 2*:
175
 
176
  ``` cpp
177
  void f() {
178
  float x, &r = x;
179
 
 
200
  }
201
  ```
202
 
203
  — *end example*]
204
 
205
+ An *implicitly movable entity* is a variable with automatic storage
206
  duration that is either a non-volatile object or an rvalue reference to
207
+ a non-volatile object type. An *id-expression* or *splice-expression*
208
+ [[expr.prim.splice]] is *move-eligible* if
209
 
210
+ - it designates an implicitly movable entity,
211
+ - it is the (possibly parenthesized) operand of a `return`
212
+ [[stmt.return]] or `co_return` [[stmt.return.coroutine]] statement or
213
+ of a *throw-expression* [[expr.throw]], and
214
+ - each intervening scope between the declaration of the entity and the
215
+ innermost enclosing scope of the expression is a block scope and, for
216
+ a *throw-expression*, is not the block scope of a *try-block* or
217
+ *function-try-block*.
 
 
 
 
218