Studying note of GCC-3.4.6 source (145)
2011-01-15 11:27
387 查看
5.13.
Stage after parsing
5.13.1.
Preliminaries - detail of conversion
5.13.1.1.
Determine appropriate conversion
C++ is a type-strong language. However, in practice, we always canwrite code like: “1 + 5.0f;”,
in which “1” is of
integer type, and “5.0f” is of
floating point type. We can even write more amazing code like: “a + b;”
assuming both “a” and “b” are instances of certain class. It dues to the
compiler will generate code for us to do the necessary and appropriate
conversions. In this section, we will see the conversions that compiler will
use behind and rules of these conversions enacted by the language standard.
We first begin with function can_convert_arg
, which is used to test if two
specified types agree with each other.
5996
bool
5997
can_convert_arg
(tree to, tree from,
tree arg)
in
call.c
5998
{
5999
tree t = implicit_conversion
(to, from, arg, LOOKUP_NORMAL);
6000
return
(t
&& ! ICS_BAD_FLAG (t));
6001
}
Indicated by
its name, conversions carried in below function, are those the compiler can be
used freely as it considers as appropriately. It is one of interesting and
powerful features of C++ language; and frequently confuses programmer even the
seniors. In [3], section 13.3.3.1
“Implicit conversion sequences” explains what implicit conversion is in detail:
1. An implicit conversion sequence is a sequence of conversions used to convert an argument in a function call to the type of the corresponding parameter of the function being called. The sequence of conversions is an implicit conversion as defined in clause 4, which means it is governed by the rules for initialization of an object or reference by a single expression (8.5, 8.5.3). 2. Implicit conversion sequences are concerned only with the type, cv-qualification, and lvalueness of the argument and how these are converted to match the corresponding properties of the parameter. Other properties, such as the lifetime, storage class, alignment, or accessibility of the argument and whether or not the argument is a bit-field are ignored. So, although an implicit conversion sequence can be defined for a given argument-parameter pair, the conversion from the argument to the parameter might still be ill-formed in the final analysis. 3. A well-formed implicit conversion sequence is one of the following forms: — a standard conversion sequence (13.3.3.1.1), — a user-defined conversion sequence (13.3.3.1.2), or — an ellipsis conversion sequence (13.3.3.1.3). 4. However, when considering the argument of a user-defined conversion function that is a candidate by 13.3.1.3 when invoked for the copying of the temporary in the second step of a class copy-initialization, or by 13.3.1.4, 13.3.1.5, or 13.3.1.6 in all cases, only standard conversion sequences and ellipsis conversion sequences are allowed. 5. For the case where the parameter type is a reference, see 13.3.3.1.4. (reference binding ) 6. When the parameter type is not a reference, the implicit conversion sequence models a copy-initialization of the parameter from the argument expression. The implicit conversion sequence is the one required to convert the argument expression to an rvalue of the type of the parameter. [Note: when the parameter has a class type, this is a conceptual conversion defined for the purposes of clause 13; the actual initialization is defined in terms of constructors and is not a conversion.] Any difference in top-level cv-qualification is subsumed by the initialization itself and does not constitute a conversion. [Example: a parameter of type A can be initialized from an argument of type const A. The implicit conversion sequence for that case is the identity sequence; it contains no “conversion” from const A to A.] When the parameter has a class type and the argument expression has the same type, the implicit conversion sequence is an identity conversion. When the parameter has a class type and the argument expression has a derived class type, the implicit conversion sequence is a derived-to-base Conversion from the derived class to the base class. [Note: there is no such standard conversion; this derived-to-base Conversion exists only in the description of implicit conversion sequences.] A derived-to-base Conversion has Conversion rank (13.3.3.1.1). 7. In all contexts, when converting to the implicit object parameter or when converting to the left operand of an assignment operation only standard conversion sequences that create no temporary object for the result are allowed. 8. If no conversions are required to match an argument to a parameter type, the implicit conversion sequence is the standard conversion sequence consisting of the identity conversion (13.3.3.1.1). 9. If no sequence of conversions can be found to convert an argument to a parameter type or the conversion is otherwise ill-formed, an implicit conversion sequence cannot be formed. 10. If several different sequences of conversions exist that each convert the argument to the parameter type, the implicit conversion sequence associated with the parameter is defined to be the unique conversion sequence designated the ambiguous conversion sequence. For the purpose of ranking implicit conversion sequences as described in 13.3.3.2, the ambiguous conversion sequence is treated as a user-defined sequence that is indistinguishable from any other user-defined conversion sequence (The ambiguous conversion sequence is ranked with user-defined conversion sequences because multiple conversion sequences for an argument can exist only if they involve different user-defined conversions. The ambiguous conversion sequence is indistinguishable from any other user-defined conversion sequence because it represents at least two user-defined conversion sequences, each with a different user-defined conversion, and any other user-defined conversion sequence must be indistinguishable from at least one of them. This rule prevents a function from becoming non-viable because of an ambiguous conversion sequence for one of its parameters. Consider this example, class B; class A { A (B&); }; class B { operator A (); }; class C { C (B&); }; void f(A) { } void f(C) { } B b; f(b); //ambiguous because b -> C via constructor and // b -> A via constructor or conversion function. If it were not for this rule, f(A) would be eliminated as a viable function for the call f(b) causing overload resolution to select f(C) as the function to call even though it is not clearly the best choice. On the other hand, if an f(B) were to be declared then f(b) would resolve to that f(B) because the exact match with f(B) is better than any of the sequences required to match f(A). If a function that uses the ambiguous conversion sequence is selected as the best viable function, the call will be ill-formed because the conversion of one of the arguments in the call is ambiguous. 11. The three forms of implicit conversion sequences mentioned above are defined in the following subclauses. |
the code, first we need clarify the concept of lvalue and rvalue. An lvalue
refers to an object or function. It must be an entity that is addressable; i.e.,
if it refers to object, it should be able to be placed on left-hand-side of an
assignment operation (that is why it called lvalue). And those that are
non-lvalue are called rvalue (which can’t be used on left-hand-side of
assginment operation).
1097
static
tree
1098
implicit_conversion
(tree to, tree from, tree expr, int flags)
in call.c
1099
{
1100
tree conv;
1101
1102
if (from == error_mark_node
|| to == error_mark_node
1103
|| expr ==
error_mark_node)
1104
return
NULL_TREE;
1105
1106
if (TREE_CODE (to) ==
REFERENCE_TYPE)
1107
conv = reference_binding
(to, from, expr, flags);
1108
else
1109
conv = standard_conversion
(to, from, expr, flags);
1110
1111
if (conv)
1112
return
conv;
1113
1114
if (expr != NULL_TREE
1115
&& (IS_AGGR_TYPE
(from)
1116
|| IS_AGGR_TYPE
(to))
1117
&& (flags &
LOOKUP_NO_CONVERSION) == 0)
1118
{
1119
struct
z_candidate
*cand;
1120
1121
cand = build_user_type_conversion_1
1122
(to, expr,
LOOKUP_ONLYCONVERTING);
1123
if (cand)
1124
conv =
cand->second_conv;
1125
1126
/*
We used to try to bind a reference to a temporary here, but that
1127
now
handled by the recursive call to this function at the end
1128
of
reference_binding.
*/
1129
return
conv;
1130
}
1131
1132
return
NULL_TREE;
1133
}
See the conversion processing routines may recurse each other, here
to handle reference type, the function invokes reference_binding
again.
However, as we are going forward within the tree of the expression, as long as
no loop back of dependence exists there will not be the infinite recursion. And
as C++ is the language requires declaration before using, mutual dependence is illegal;
the parser should be able to find out this ill form.
5.13.1.1.1.
Case
of standard conversion sequence
[3] section 13.3.3.1.1
“Standard conversion sequence” gives detail about the sequence.
1. Table 9 summarizes the conversions defined in clause 4 (“Standard conversions”, section 4 in [3]) and partitions them into four disjoint categories: Lvalue Transformation, Qualification Adjustment, Promotion, and Conversion. [Note: these categories are orthogonal with respect to lvalue-ness, cv-qualification, and data representation: the Lvalue Transformations do not change the cv-qualification or data representation of the type; the Qualification Adjustments do not change the lvalue -ness or data representation of the type; and the Promotions and Conversions do not change the lvalue-ness or cv-qualification of the type.] 2. [Note: As described in clause 4, a standard conversion sequence is either the Identity conversion by itself (that is, no conversion) or consists of one to three conversions from the other four categories. At most one conversion from each category is allowed in a single standard conversion sequence. If there are two or more conversions in the sequence, the conversions are applied in the canonical order: Lvalue Transformation , Promotion or Conversion , Qualification Adjustment . —end note ] 3. Each conversion in Table 9 also has an associated rank (Exact Match, Promotion, or Conversion). These are used to rank standard conversion sequences (13.3.3.2). The rank of a conversion sequence is determined by considering the rank of each conversion in the sequence and the rank of any reference binding (13.3.3.1.4). If any of those has Conversion rank, the sequence has Conversion rank; otherwise, if any of those has Promotion rank, the sequence has Promotion rank; otherwise, the sequence has Exact Match rank. Table 9: - conversions
|
resolving of overload from line 472 to 479 (it will be covered by section about
reference binding, remember type_unknown_p
returns true if expr
is
an overload). Always keep in mind that below standard_conversion
handles
implicit conversion, only conversions mentioned in above table are considered; never confuse it with
force conversion.
456
static
tree
457
standard_conversion
(tree to, tree from,
tree expr, int flags)
in
call.c
458
{
459
enum
tree_code fcode, tcode;
460
tree conv;
461
bool fromref = false;
462
463
to = v (to);
464
if (TREE_CODE (from) == REFERENCE_TYPE)
465
{
466
fromref = true;
467
from = TREE_TYPE (from);
468
}
469
to = strip_top_quals (to);
470
from = strip_top_quals (from);
471
472
if ((TYPE_PTRFN_P (to) || TYPE_PTRMEMFUNC_P
(to))
473
&& expr && type_unknown_p
(expr))
474
{
475
expr = instantiate_type (to, expr,
tf_conv);
476
if (expr == error_mark_node)
477
return
NULL_TREE;
478
from = TREE_TYPE (expr);
479
}
480
481
fcode = TREE_CODE (from);
482
tcode = TREE_CODE (to);
483
484
conv = build1
(IDENTITY_CONV, from, expr);
485
486
if (fcode == FUNCTION_TYPE)
487
{
488
from = build_pointer_type
(from);
489
fcode = TREE_CODE (from);
490
conv = build_conv
(LVALUE_CONV, from, conv);
491
}
492
else if (fcode == ARRAY_TYPE)
493
{
494
from = build_pointer_type
(TREE_TYPE (from));
495
fcode = TREE_CODE (from);
496
conv = build_conv
(LVALUE_CONV, from, conv);
497
}
498
else if (fromref || (expr
&& lvalue_p
(expr)))
499
conv = build_conv
(RVALUE_CONV, from, conv);
500
501
/* Allow conversion
between `__complex__' data types.
*/
502
if (tcode == COMPLEX_TYPE && fcode ==
COMPLEX_TYPE)
503
{
504
/* The standard
conversion sequence to convert FROM to TO is
505
the standard conversion
sequence to perform componentwise
506
conversion.
*/
507
tree part_conv = standard_conversion
508
(TREE_TYPE (to), TREE_TYPE (from),
NULL_TREE, flags);
509
510
if (part_conv)
511
{
512
conv = build_conv
(TREE_CODE (part_conv), to, conv);
513
ICS_STD_RANK (conv) = ICS_STD_RANK
(part_conv);
514
}
515
else
516
conv = NULL_TREE;
517
518
return
conv;
519
}
520
521
if (same_type_p (from, to))
522
return
conv;
Line 484 builds IDENTITY_COV for identity conversion. The type of *_CONV
node indicates the source type and its first operand is the expression to be
converted. So conversion sequence will be built with a big nested *_CONV node,
with the top *_CONV is the last conversion being done, and the innermost being the
first which always is IDENTITY_CONV.
In internal, the front-end defines following ranks for conversions
instead those shown by table-9 above. And note that the less value indicates more
preference.
343
#define
IDENTITY_RANK
0
in
call.c
344
#define
EXACT_RANK
1
345
#define
PROMO_RANK
2
346
#define
STD_RANK
3
347
#define
PBOOL_RANK
4
348
#define
USER_RANK
5
349
#define
ELLIPSIS_RANK
6
350
#define
BAD_RANK
7
Conversions that can be generated internally include: IDENTITY_CONV,
LVALUE_CONV, QUAL_CONV, STD_CONV, PTR_CONV, PMEM_CONV, BASE_CONV, REF_BIND, USER_CONV,
AMBIG_CONV, and RVALUE_CONV.
408
static
tree
409
build_conv
(enum
tree_code code, tree type, tree from)
in
call.c
410
{
411
tree t;
412
int rank = ICS_STD_RANK (from);
413
414
/* We can't use
buildl1 here because CODE could be USER_CONV, which
415
takes two
arguments. In that case, the caller is responsible for
416
filling in the
second argument.
*/
417
t
=
make_node
(code);
418
TREE_TYPE (t) = type;
419
TREE_OPERAND (t, 0) = from;
420
421
switch
(code)
422
{
423
case
PTR_CONV:
424
case
PMEM_CONV:
425
case
BASE_CONV:
426
case
STD_CONV:
427
if (rank < STD_RANK)
428
rank = STD_RANK;
429
break
;
430
431
case
QUAL_CONV:
432
if (rank < EXACT_RANK)
433
rank = EXACT_RANK;
434
435
default
:
436
break
;
437
}
438
ICS_STD_RANK (t) = rank;
439
ICS_USER_FLAG (t) = (code == USER_CONV || ICS_USER_FLAG (from));
440
ICS_BAD_FLAG (t) = ICS_BAD_FLAG (from);
441
return
t;
442
}
In above function, ICS_STD_RANK in fact will store the highest rank value
seen so far, whose usage we will see in later paragraphes.
Then above line 486 and 492 in standard_conversion
handle
function-to-pointer and array-to-point conversion, which is described by [3]
clause 4.2 “Array-to-pointer conversion and clause” 4.3 “Function-to-pointer
conversion” as below.
1. An lvalue or rvalue of type “array ofN T” or “array of unknown bound of T” can be converted to an rvalue of type “pointer to T.” The result is a pointer to the first element of the array. 2. A string literal (2.13.4) that is not a wide string literal can be converted to an rvalue of type “pointer to char”; a wide string literal can be converted to an rvalue of type “pointer to wchar_t”. In either case, the result is a pointer to the first element of the array. This conversion is considered only when there is an explicit appropriate pointer target type, and not when there is a general need to convert from an lvalue to an rvalue . [Note: this conversion is deprecated. See Annex D.] For the purpose of ranking in overload resolution (13.3.3.1.1), this conversion is considered an array-to-pointer conversion followed by a qualification conversion (4.4). [Example: "abc" is converted to “pointer to const char” as an array-to-pointer conversion, and then to “pointer to char” as a qualification conversion.] |
1. An lvalue of function type T can be converted to an rvalue of type “pointer to T.” The result is a pointer to the function. (This conversion never applies to nonstatic member functions because an lvalue that refers to a nonstatic member function cannot be obtained.) 2. [Note: See 13.4 for additional rules for the case where the function is overloaded.] |
both clauses, rvalue of type “pointer to T” just means the pointer itself can’t
be modified, but its content can be changed. For example:
char a[10];
char *p = …;
a = p;
// a is
converted to rvalue of char*, assignment not allowed
*(a+1) = *p;
// object pointed
by a+1 is lvalue, it is OK
Compared with below clause, these two clauses include creation of pointer
type, the front-end must tells out these two situations from other cases of
lvalue transformation. So the front-end uses LVALUE_CONV for them.
Then in standard_conversion
,
arriving at line 498, if the condition is satisified, terms 1 mentioned in [3]
clause 4.1 “Lvalue-to-rvalue conversion” will be implemented. The front-end
uses RVALUE_CONV for the case. One difference of LVALUE_CONV and RVALUE_CONV is
that when building LVALUE_CONV, we have known the rvalue (see the pointer type
built at line 488 and 494), while for RVALUE_CONV, the rvalue is unknown at
that point, and later the front-end needs invoke decay_conversion
to do the
real conversion.
1. An lvalue (3.10) of a non-function, non-array type T can be converted to an rvalue . If T is an incomplete type, a program that necessitates this conversion is ill-formed. If the object to which the lvalue refers is not an object of type T and is not an object of a type derived from T, or if the object is uninitialized, a program that necessitates this conversion has undefined behavior. If T is a non-class type, the type of the rvalue is the cv-unqualified version of T. Otherwise, the type of the rvalue is T. [In C++ class rvalues can have cv-qualified types (because they are objects). This differs from ISO C, in which non-lvalues never have cv-qualified types.] 2. The value contained in the object indicated by the lvalue is the rvalue result. When an lvalue-to-rvalue conversion occurs within the operand of sizeof (5.3.3) the value contained in the referenced object is not accessed, since that operator does not evaluate its operand. |
function, given expression ref
, it can tell if it is lvalue or not. And see
that pointer type built for LVALUE_CONV above is rvalue told by this function.
This function should be studied carefully.
211
int
212
lvalue_p
(tree ref)
in
tree.c
213
{
214
return
215
(lvalue_p_1
(ref,
/*class rvalue ok*/
1) != clk_none);
216
}
The various kinds of lvalues we distinguish are given in below.
2964
typedef
enum
cp_lvalue_kind {
in
cp-tree.h
2965
clk_none = 0,
/* Things that
are not an lvalue.
*/
2966
clk_ordinary = 1, /* An ordinary lvalue.
*/
2967
clk_class = 2,
/* An rvalue of
class-type.
*/
2968
clk_bitfield = 4, /* An lvalue for a bit-field.
*/
2969
clk_packed = 8
/* An lvalue for
a packed field.
*/
2970
} cp_lvalue_kind
;
In [3], clause
3.10 (lvalues and rvalues), gives the following explaination.
1. Every expression is either an lvalue or an rvalue . 2. An lvalue refers to an object or function. Some rvalue expressions—those of class or cv-qualified class type—also refer to objects (Expressions such as invocations of constructors and of functions that return a class type refer to objects, and the implementation can invoke a member function upon such objects, but the expressions are not lvalues ). 3. [Note: some built-in operators and function calls yield lvalues . [Example: if E is an expression of pointer type, then *E is an lvalue expression referring to the object or function to which E points. As another example, the function int& f(); yields an lvalue , so the call f() is an lvalue expression.]] 4. [Note: some builtin operators expect lvalue operands. [Example: built-in assignment operators all expect their left hand operands to be lvalues .] Other built-in operators yield rvalues , and some expect them. [Example: the unary and binary + operators expect rvalue arguments and yield rvalue results.] The discussion of each built-in operator in clause 5 indicates whether it expects lvalue operands and whether it yields an lvalue .] 5. The result of calling a function that does not return a reference is an rvalue . User defined operators are functions, and whether such operators expect or yield lvalues is determined by their parameter and return types. 6. An expression which holds a temporary object resulting from a cast to a nonreference type is an rvalue (this includes the explicit creation of an object using functional notation (5.2.3)). 7. Whenever an lvalue appears in a context where an rvalue is expected, the lvalue is converted to an rvalue ; see 4.1, 4.2, and 4.3. 8. The discussion of reference initialization in 8.5.3 and of temporaries in 12.2 indicates the behavior of lvalues and rvalues in other significant contexts. 9. Class rvalues can have cv-qualified types; non-class rvalues always have cv-unqualified types. Rvalues shall always have complete types or the void type; in addition to these types, lvalues can also have incomplete types. 10. An lvalue for an object is necessary in order to modify the object except that an rvalue of class type can also be used to modify its referent under certain circumstances. [Example: a member function called for an object (9.3) can modify the object.] 11. Functions cannot be modified, but pointers to functions can be modifiable. 12. A pointer to an incomplete type can be modifiable. At some point in the program when the pointed to type is complete, the object at which the pointer points can also be modified. 13. The referent of a const-qualified expression shall not be modified (through that expression), except that if it is of class type and has a mutable component, that component can be modified (7.1.5.1). 14. If an expression can be used to modify the object to which it refers, the expression is called modifiable. A program that attempts to modify an object through a nonmodifiable lvalue or rvalue expression is illformed. 15. If a program attempts to access the stored value of an object through an lvalue of other than one of the following types the behavior is undefined (The intent of this list is to specify those circumstances in which an object may or may not be aliased): — the dynamic type of the object, — a cv-qualified version of the dynamic type of the object, — a type that is the signed or unsigned type corresponding to the dynamic type of the object, — a type that is the signed or unsigned type corresponding to a cv-qualified version of the dynamic type of the object, — an aggregate or union type that includes one of the aforementioned types among its members (including, recursively, a member of a subaggregate or contained union), — a type that is a (possibly cv-qualified) base class type of the dynamic type of the object, — a char or unsigned char type. |
method processed below, as non-static method must be invoked as: “a.fa();” with
given object which may not addressable (for example, in statement “A().fa();”,
“A()” returns an rvalue), non-static method is just considered as rvalue. Further,
expression “A().fa();” can modify the object, so “A()” can be considered as
lvalue if not require strict lvalue (argument treat_class_rvalues_as_lvalues
is
1). Pay attention to TARGET_EXPR at line 156, it would wrapsthe temperary
object returned by “A()” ( see comment at line 161).
62
static
cp_lvalue_kind
63
lvalue_p_1
(tree ref,
in
tree.c
64
int treat_class_rvalues_as_lvalues)
65
{
66
cp_lvalue_kind op1_lvalue_kind = clk_none;
67
cp_lvalue_kind op2_lvalue_kind = clk_none;
68
69
if (TREE_CODE (TREE_TYPE (ref)) ==
REFERENCE_TYPE)
70
return
clk_ordinary;
71
72
if (ref == current_class_ptr
)
73
return
clk_none;
74
75
switch
(TREE_CODE (ref))
76
{
77
/* preincrements and predecrements are valid
lvals, provided
78
what they refer
to are valid lvals.
*/
79
case
PREINCREMENT_EXPR:
80
case
PREDECREMENT_EXPR:
81
case
SAVE_EXPR:
82
case
UNSAVE_EXPR:
83
case
TRY_CATCH_EXPR:
84
case
WITH_CLEANUP_EXPR:
85
case
REALPART_EXPR:
86
case
IMAGPART_EXPR:
87
return
lvalue_p_1 (TREE_OPERAND (ref, 0),
88
treat_class_rvalues_as_lvalues);
89
90
case
COMPONENT_REF:
91
op1_lvalue_kind = lvalue_p_1
(TREE_OPERAND (ref, 0),
92
treat_class_rvalues_as_lvalues);
93
/* In an
expression of the form "X.Y", the packed-ness of the
94
expression
does not depend on "X".
*/
95
op1_lvalue_kind &= ~clk_packed;
96
/* Look at the member designator.
*/
97
if (!op1_lvalue_kind
98
/* The
"field" can be a FUNCTION_DECL or an OVERLOAD in some
99
situations.
*/
100
|| TREE_CODE (TREE_OPERAND (ref, 1))
!= FIELD_DECL)
101
;
102
else if (DECL_C_BIT_FIELD (TREE_OPERAND
(ref, 1)))
103
{
104
/* Clear the
ordinary bit. If this object was a class
105
rvalue we
want to preserve that information.
*/
106
op1_lvalue_kind &= ~clk_ordinary;
107
/* The lvalue
is for a bitfield.
*/
108
op1_lvalue_kind |= clk_bitfield;
109
}
110
else if (DECL_PACKED (TREE_OPERAND (ref,
1)))
111
op1_lvalue_kind |= clk_packed;
112
113
return
op1_lvalue_kind;
114
115
case
STRING_CST:
116
return
clk_ordinary;
117
118
case
VAR_DECL:
119
if (TREE_READONLY (ref) && !
TREE_STATIC (ref)
120
&& DECL_LANG_SPECIFIC (ref)
121
&& DECL_IN_AGGR_P (ref))
122
return
clk_none;
123
case
INDIRECT_REF:
124
case
ARRAY_REF:
125
case
PARM_DECL:
126
case
RESULT_DECL:
127
if (TREE_CODE (TREE_TYPE (ref)) !=
METHOD_TYPE)
128
return
clk_ordinary;
129
break
;
130
131
/* A currently unresolved scope ref.
*/
132
case
SCOPE_REF:
133
abort ();
134
case
MAX_EXPR:
135
case
MIN_EXPR:
136
op1_lvalue_kind = lvalue_p_1
(TREE_OPERAND (ref, 0),
137
treat_class_rvalues_as_lvalues);
138
op2_lvalue_kind = lvalue_p_1
(TREE_OPERAND (ref, 1),
139
treat_class_rvalues_as_lvalues);
140
break
;
141
142
case
COND_EXPR:
143
op1_lvalue_kind = lvalue_p_1
(TREE_OPERAND (ref, 1),
144
treat_class_rvalues_as_lvalues);
145
op2_lvalue_kind = lvalue_p_1
(TREE_OPERAND (ref, 2),
146
treat_class_rvalues_as_lvalues);
147
break
;
148
149
case
MODIFY_EXPR:
150
return
clk_ordinary;
151
152
case
COMPOUND_EXPR:
153
return
lvalue_p_1 (TREE_OPERAND (ref, 1),
154
treat_class_rvalues_as_lvalues);
155
156
case
TARGET_EXPR:
157
return
treat_class_rvalues_as_lvalues ? clk_class : clk_none;
158
159
case
CALL_EXPR:
160
case
VA_ARG_EXPR:
161
/* Any class-valued
call would be wrapped in a TARGET_EXPR.
*/
162
return
clk_none;
163
164
case
FUNCTION_DECL:
165
/* All
functions (except non-static-member functions) are
166
lvalues.
*/
167
return
(DECL_NONSTATIC_MEMBER_FUNCTION_P (ref)
168
? clk_none : clk_ordinary);
169
170
case
NON_DEPENDENT_EXPR:
171
/* We must
consider NON_DEPENDENT_EXPRs to be lvalues so that
172
things like
"&E" where "E" is an expression with a
173
non-dependent
type work. It is safe to be lenient because an
174
error will be
issued when the template is instantiated if "E"
175
is not an
lvalue.
*/
176
return
clk_ordinary;
177
178
default
:
179
break
;
180
}
181
182
/* If one operand is
not an lvalue at all, then this expression is
183
not an
lvalue.
*/
184
if (!op1_lvalue_kind || !op2_lvalue_kind)
185
return
clk_none;
186
187
/* Otherwise, it's
an lvalue, and it has all the odd properties
188
contributed by
either operand.
*/
189
op1_lvalue_kind = op1_lvalue_kind |
op2_lvalue_kind;
190
/* It's not an
ordinary lvalue if it involves either a bit-field or
191
a class
rvalue.
*/
192
if ((op1_lvalue_kind & ~clk_ordinary) !=
clk_none)
193
op1_lvalue_kind &= ~clk_ordinary;
194
return
op1_lvalue_kind;
195
}
Above, NON_DEPENDENT_EXPR is a placeholder for an expression that is
not type-dependent, but does occur in a template. See INDIRECT_REF is lvalue
(however pointer is rvalue itself, it is the case described by terms 3 above);
and normal variable is also lvalue (line 118); further if an array is referred,
its reference is lvalue, otherwise the array would be decayed to pointer of
rvalue. Next note that MODIFY_EXPR at line 149, no doubt must be lvalue, and
COMPOUND_EXPR following depends on its second operand. And for expressions may
contains operand of lvalue, lvalue_p_1
recurs into the operand.
It is worth note that call expression “f();” of “int& f();” is
lvalue, but expression like “f() = 5;” is illegal; the only case this lvalue
can be used directly is using “f()” as parameter which is covered by PARM_DECL
at line 125; so CALL_EXPR not within PARM_DECL is just regarded as rvalue.
Further, being lvalue, PARM_DECL, RESULT_DECL, ARRAY_REF, and INDIRECT_REF can
be of type of non-static method of class.
standard_conversion (continue)
524
if ((tcode == POINTER_TYPE ||
TYPE_PTR_TO_MEMBER_P (to))
525
&& expr && null_ptr_cst_p
(expr))
526
conv = build_conv
(STD_CONV, to, conv);
527
else if (tcode == POINTER_TYPE &&
fcode == POINTER_TYPE
528
&& TREE_CODE (TREE_TYPE (to))
== VECTOR_TYPE
529
&& TREE_CODE (TREE_TYPE (from))
== VECTOR_TYPE
530
&& ((*targetm
.vector_opaque_p) (TREE_TYPE
(to))
531
|| (*targetm
.vector_opaque_p)
(TREE_TYPE (from))))
532
conv = build_conv
(STD_CONV, to, conv);
533
else
if ((tcode == INTEGER_TYPE && fcode == POINTER_TYPE)
534
|| (tcode == POINTER_TYPE && fcode == INTEGER_TYPE))
535
{
536
/* For backwards
brain damage compatibility, allow interconversion of
537
pointers and
integers with a pedwarn.
*/
538
conv = build_conv
(STD_CONV, to, conv);
539
ICS_BAD_FLAG (conv) = 1;
540
}
541
else if (tcode == ENUMERAL_TYPE &&
fcode == INTEGER_TYPE)
542
{
543
/* For backwards
brain damage compatibility, allow interconversion of
544
enums and
integers with a pedwarn.
*/
545
conv = build_conv
(STD_CONV, to, conv);
546
ICS_BAD_FLAG (conv) = 1;
547
}
Note above, converting between pointers and integers and between
integers and enums are both bad conversions in the context of C++ langauge (but
it just gives warning under C). So the conversion is recorded and given the
rank of lowest priority.
standard_conversion (continue)
548
else if ((tcode == POINTER_TYPE &&
fcode == POINTER_TYPE)
549
|| (TYPE_PTRMEM_P (to) &&
TYPE_PTRMEM_P (from)))
550
{
551
tree to_pointee;
552
tree from_pointee;
553
554
if (tcode == POINTER_TYPE
555
&&
same_type_ignoring_top_level_qualifiers_p (TREE_TYPE (from),
556
TREE_TYPE (to)))
557
;
558
else if (VOID_TYPE_P (TREE_TYPE (to))
559
&& !TYPE_PTRMEM_P (from)
560
&& TREE_CODE (TREE_TYPE
(from)) != FUNCTION_TYPE)
561
{
562
from = build_pointer_type
563
(cp_build_qualified_type (void_type_node,
564
cp_type_quals (TREE_TYPE (from))));
565
conv = build_conv
(PTR_CONV, from, conv);
566
}
567
else if (TYPE_PTRMEM_P (from))
568
{
569
tree fbase = TYPE_PTRMEM_CLASS_TYPE
(from);
570
tree tbase = TYPE_PTRMEM_CLASS_TYPE (to);
571
572
if (DERIVED_FROM_P (fbase, tbase)
573
&&
(same_type_ignoring_top_level_qualifiers_p
574
(TYPE_PTRMEM_POINTED_TO_TYPE (from),
575
TYPE_PTRMEM_POINTED_TO_TYPE
(to))))
576
{
577
from = build_ptrmem_type (tbase,
578
TYPE_PTRMEM_POINTED_TO_TYPE (from));
579
conv = build_conv
(PMEM_CONV, from, conv);
580
}
581
else if (!same_type_p (fbase, tbase))
582
return
NULL;
583
}
584
else if (IS_AGGR_TYPE (TREE_TYPE (from))
585
&& IS_AGGR_TYPE (TREE_TYPE
(to))
586
/* [conv.ptr]
587
588
An rvalue of
type "pointer to cv D," where D is a
589
class type,
can be converted to an rvalue of type
590
"pointer
to cv B," where B is a base class (clause
591
_class.derived_) of D. If B is an inaccessible
592
(clause
_class.access_) or ambiguous
593
(_class.member.lookup_) base class of D, a program
594
that
necessitates this conversion is ill-formed.
*/
595
/* Therefore,
we use DERIVED_FROM_P, and not
596
ACESSIBLY_UNIQUELY_DERIVED_FROM_P,
in this test.
*/
597
&& DERIVED_FROM_P (TREE_TYPE
(to), TREE_TYPE (from)))
598
{
599
from =
600
cp_build_qualified_type (TREE_TYPE
(to),
601
cp_type_quals
(TREE_TYPE (from)));
602
from = build_pointer_type
(from);
603
conv = build_conv
(PTR_CONV, from, conv);
604
}
605
606
if (tcode == POINTER_TYPE)
607
{
608
to_pointee = TREE_TYPE (to);
609
from_pointee = TREE_TYPE (from);
610
}
611
else
612
{
613
to_pointee = TYPE_PTRMEM_POINTED_TO_TYPE
(to);
614
from_pointee =
TYPE_PTRMEM_POINTED_TO_TYPE (from);
615
}
616
617
if (same_type_p (from, to))
618
/* OK */
;
619
else
if (comp_ptr_ttypes (to_pointee, from_pointee))
620
conv = build_conv
(QUAL_CONV, to, conv);
621
else if (expr && string_conv_p (to,
expr, 0))
622
/* converting
from string constant to char *.
*/
623
conv = build_conv
(QUAL_CONV, to, conv);
624
else if (ptr_reasonably_similar
(to_pointee, from_pointee))
625
{
626
conv = build_conv
(PTR_CONV, to, conv);
627
ICS_BAD_FLAG (conv) = 1;
628
}
629
else
630
return
0;
631
632
from = to;
633
}
Again in [3]
clause 4.10 “Pointer covnersions”, finds following paragraphes. And note that
code at line 499 in the function has converted lvalue into rvalue, conv
above
holds the conversion.
1. A null pointer constant is an integral constant expression (5.19) rvalue of integer type that evaluates to zero. A null pointer constant can be converted to a pointer type; the result is the null pointer value of that type and is distinguishable from every other value of pointer to object or pointer to function type. Two null pointer values of the same type shall compare equal. The conversion of a null pointer constant to a pointer to cv-qualified type is a single conversion, and not the sequence of a pointer conversion followed by a qualification conversion (4.4). 2. An rvalue of type “pointer to cv T,” where T is an object type, can be converted to an rvalue of type “pointer to cv void.” The result of converting a “pointer to cv T” to a “pointer to cv void” points to the start of the storage location where the object of type T resides, as if the object is a most derived object (1.8) of type T (that is, not a base class subobject). 3. An rvalue of type “pointer to cv D,” where D is a class type, can be converted to an rvalue of type “pointer to cv B,” where B is a base class (clause 10) of D. If B is an inaccessible (clause 11) or ambiguous (10.2) base class of D, a program that necessitates this conversion is ill-formed. The result of the conversion is a pointer to the base class sub-object of the derived class object. The null pointer value is converted to the null pointer value of the destination type. |
526 above. It is one step STD_CONV. And condition of terms 2 is tested by code
at line 558 ~ 560. Then condition in line 584 ~ 597 fullfils terms 3.
Further clause
4.11 “Pointer to member conversion” is shown in below.
1. A null pointer constant (4.10) can be converted to a pointer to member type; the result is the null member pointer value of that type and is distinguishable from any pointer to member not created from a null pointer constant. Two null member pointer values of the same type shall compare equal. The conversion of a null pointer constant to a pointer to member of cv-qualified type is a single conversion, and not the sequence of a pointer to member conversion followed by a qualification conversion (4.4). 2. An rvalue of type “pointer to member of B of type cv T,” where B is a class type, can be converted to an rvalue of type “pointer to member of D of type cv T,” where D is a derived class (clause 10) of B. If B is an inaccessible (clause 11), ambiguous (10.2) or virtual (10.1) base class of D, a program that necessitates this conversion is ill-formed. The result of the conversion refers to the same member as the pointer to member before the conversion took place, but it refers to the base class member as if it were a member of the derived class. The result refers to the member in D’s instance of B. Since the result has type “pointer to member of D of type cv T,” it can be dereferenced with a D object. The result is the same as if the pointer to member of B were dereferenced with the B sub-object of D. The null member pointer value is converted to the null member pointer value of the destination type. [The rule for conversion of pointers to members (from pointer to member of base to pointer to member of derived) appears inverted compared to the rule for pointers to objects (from pointer to derived to pointer to base) (4.10, clause 10). This inversion is necessary to ensure type safety. Note that a pointer to member is not a pointer to object or a pointer to function and the rules for conversions of such pointers do not apply to pointers to members. In particular, a pointer to member cannot be converted to a void*.] |
line 526 above. And terms 2 is handled by block at line 567. Arriving at line
617, with above conversion sequence, from
and to
should be either of same type, or just with
different cv-qualifiers; otherwise, no conversion sequence is applicable.
Below conversion between pointer-to-method is similar with that of
pointer-to-member. Note that fromfn
and tofn
are functions pointed respectively; fbase
and tbase
are the implicit this
pointer each. So conversion can be carried out is: “an rvalue of type “pointer
to method of B of type cv T,” where B is a class type, can be converted to an rvalue
of type “pointer to the same
method
of D of type cv T,” where D is a derived class of B.” And see that “same” here
is a little stricter than the that meaning among overloads.
standard_conversion (continue)
634
else if (TYPE_PTRMEMFUNC_P (to) &&
TYPE_PTRMEMFUNC_P (from))
635
{
636
tree fromfn = TREE_TYPE (TYPE_PTRMEMFUNC_FN_TYPE
(from));
637
tree tofn = TREE_TYPE
(TYPE_PTRMEMFUNC_FN_TYPE (to));
638
tree fbase = TREE_TYPE (TREE_VALUE
(TYPE_ARG_TYPES (fromfn)));
639
tree tbase = TREE_TYPE (TREE_VALUE
(TYPE_ARG_TYPES (tofn)));
640
641
if (!DERIVED_FROM_P (fbase, tbase)
642
|| !same_type_p (TREE_TYPE (fromfn),
TREE_TYPE (tofn))
643
|| !compparms (TREE_CHAIN
(TYPE_ARG_TYPES (fromfn)),
644
TREE_CHAIN (TYPE_ARG_TYPES
(tofn)))
645
|| cp_type_quals (fbase) != cp_type_quals
(tbase))
646
return
0;
647
648
from = cp_build_qualified_type (tbase,
cp_type_quals (fbase));
649
from = build_method_type_directly
(from,
650
TREE_TYPE (fromfn),
651
TREE_CHAIN
(TYPE_ARG_TYPES (fromfn)));
652
from = build_ptrmemfunc_type (build_pointer_type
(from));
653
conv = build_conv
(PMEM_CONV, from, conv);
654
}
[3], clause
4.12 “Boolean conversions” gives guideline how to do the conversion as below.
1. An rvalue of arithmetic, enumeration, pointer, or pointer to member type can be converted to an rvalue of type bool. A zero value, null pointer value, or null member pointer value is converted to false; any other value is converted to true. |
pointer to boolean is alittle bit inferior to those of integer types.
standard_conversion (continue)
655
else if (tcode == BOOLEAN_TYPE)
656
{
657
/* [conv.bool]
658
659
An rvalue of
arithmetic, enumeration, pointer, or pointer to
660
member type can
be converted to an rvalue of type bool.
*/
661
if (ARITHMETIC_TYPE_P (from)
662
|| fcode == ENUMERAL_TYPE
663
|| fcode == POINTER_TYPE
664
|| TYPE_PTR_TO_MEMBER_P (from))
665
{
666
conv = build_conv
(STD_CONV, to, conv);
667
if (fcode == POINTER_TYPE
668
|| TYPE_PTRMEM_P (from)
669
|| (TYPE_PTRMEMFUNC_P (from)
670
&& ICS_STD_RANK (conv) <
PBOOL_RANK))
671
ICS_STD_RANK (conv) = PBOOL_RANK;
672
return
conv;
673
}
674
675
return
NULL_TREE;
676
}
Then below
code handles coversions described by [3], clause 4.5 “Integeral promotions”,
4.6 “Floating point promotion”, 4.7 “Integral conversions”, 4.8 “Floating point
conversions”, and 4.9 “Floating-integral conversions”. And below paragraphes
give the detail.
1. An rvalue of type char , signed char , unsigned char , short int , or unsigned short int can be converted to an rvalue of type int if int can represent all the values of the source type; otherwise, the source rvalue can be converted to an rvalue of type unsigned int . 2. An rvalue of type wchar_t (3.9.1) or an enumeration type (7.2) can be converted to an rvalue of the first of the following types that can represent all the values of its underlying type: int , unsigned int , long , or unsigned long . 3. An rvalue for an integral bit-field (9.6) can be converted to an rvalue of type int if int can represent all the values of the bit-field; otherwise, it can be converted to unsigned int if unsigned int can represent all the values of the bit-field. If the bit-field is larger yet, no integral promotion applies to it. If the bit-field has an enumerated type, it is treated as any other value of that type for promotion purposes. 4. An rvalue of type bool can be converted to an rvalue of type int , with false becoming zero and true becoming one. 5. These conversions are called integral promotions. |
1. An rvalue of type float can be converted to an rvalue of type double . The value is unchanged. 2. This conversion is called floating point promotion. |
1. An rvalue of an integer type can be converted to an rvalue of another integer type. An rvalue of an enumeration type can be converted to an rvalue of an integer type. 2. If the destination type is unsigned, the resulting value is the least unsigned integer congruent to the source integer (modulo 2n where n is the number of bits used to represent the unsigned type). [Note: In a two’s complement representation, this conversion is conceptual and there is no change in the bit pattern (if there is no truncation).] 3. If the destination type is signed, the value is unchanged if it can be represented in the destination type (and bit-field width); otherwise, the value is implementation-defined. 4. If the destination type is bool , see 4.12. If the source type is bool , the value false is converted to zero and the value true is converted to one. 5. The conversions allowed as integral promotions are excluded from the set of integral conversions. |
1. An rvalue of floating point type can be converted to an rvalue of another floating point type. If the source value can be exactly represented in the destination type, the result of the conversion is that exact representation. If the source value is between two adjacent destination values, the result of the conversion is an implementation-defined choice of either of those values. Otherwise, the behavior is undefined. 2. The conversions allowed as floating point promotions are excluded from the set of floating point conversions. |
1. An rvalue of a floating point type can be converted to an rvalue of an integer type. The conversion truncates; that is, the fractional part is discarded. The behavior is undefined if the truncated value cannot be represented in the destination type. [Note:If the destination type is bool, see 4.12.] 2. An rvalue of an integer type or of an enumeration type can be converted to an rvalue of a floating point type. The result is exact if possible. Otherwise, it is an implementation-defined choice of either the next lower or higher representable value. [Note: loss of precision occurs if the integral value cannot be represented exactly as a value of the floating type.] If the source type is bool, the value false is converted to zero and the value true is converted to one. |
covers all cases mentioned above. As PROMO_RANK is preferred to STD_RANK, it
always uses PROMO_RANK as possible.
standard_conversion (continue)
677
/* We don't check
for ENUMERAL_TYPE here because there are no standard
678
conversions to
enum type.
*/
679
else if (tcode == INTEGER_TYPE || tcode ==
BOOLEAN_TYPE
680
|| tcode == REAL_TYPE)
681
{
682
if (! (INTEGRAL_CODE_P (fcode) || fcode ==
REAL_TYPE))
683
return
0;
684
conv = build_conv
(STD_CONV, to, conv);
685
686
/* Give this a better
rank if it's a promotion.
*/
687
if (same_type_p (to, type_promotes_to
(from))
688
&& ICS_STD_RANK (TREE_OPERAND
(conv, 0)) <= PROMO_RANK)
689
ICS_STD_RANK (conv) = PROMO_RANK;
690
}
691
else if (fcode == VECTOR_TYPE &&
tcode == VECTOR_TYPE
692
&& ((*targetm
.vector_opaque_p) (from)
693
|| (*targetm
.vector_opaque_p) (to)))
694
return
build_conv
(STD_CONV, to, conv);
695
else if (!(flags &
LOOKUP_CONSTRUCTOR_CALLABLE)
696
&& IS_AGGR_TYPE (to)
&& IS_AGGR_TYPE (from)
697
&& is_properly_derived_from
(from, to))
698
{
699
if (TREE_CODE (conv) == RVALUE_CONV)
700
conv = TREE_OPERAND (conv, 0);
701
conv = build_conv
(BASE_CONV, to, conv);
702
/* The
derived-to-base conversion indicates the initialization
703
of a parameter
with base type from an object of a derived
704
type. A
temporary object is created to hold the result of
705
the
conversion.
*/
706
NEED_TEMPORARY_P (conv) = 1;
707
}
708
else
709
return
0;
710
711
return
conv;
712
}
Code between line 695 to 707 handles the case of derived-to-base
conversion, which is defined by terms 6 of the clause “Implicit conversion
sequeunces”.
相关文章推荐
- Studying note of GCC-3.4.6 source (58)
- Studying note of GCC-3.4.6 source (63)
- Studying note of GCC-3.4.6 source (73)
- Studying note of GCC-3.4.6 source (106)
- Studying note of GCC-3.4.6 source (112)
- Studying note of GCC-3.4.6 source (116)
- Studying note of GCC-3.4.6 source (126)
- Studying note of GCC-3.4.6 source (6)
- Studying note of GCC-3.4.6 source (7)
- Studying note of GCC-3.4.6 source (9)
- Studying note of GCC-3.4.6 source (148 continue)
- Studying note of GCC-3.4.6 source (155)
- Studying note of GCC-3.4.6 source (31)
- Studying note of GCC-3.4.6 source (173)
- Studying note of GCC-3.4.6 source (42)
- Studying note of GCC-3.4.6 source (179)
- Studying note of GCC-3.4.6 source (52)
- Studying note of GCC-3.4.6 source (83)
- Studying note of GCC-3.4.6 source (88)
- Studying note of GCC-3.4.6 source (119)