]>
Commit | Line | Data |
---|---|---|
471086d6 | 1 | /* Language-level data type conversion for GNU C++. |
7045d67a | 2 | Copyright (C) 1987-1988, 1992-1999 Free Software Foundation, Inc. |
471086d6 | 3 | Hacked by Michael Tiemann (tiemann@cygnus.com) |
4 | ||
5 | This file is part of GNU CC. | |
6 | ||
7 | GNU CC is free software; you can redistribute it and/or modify | |
8 | it under the terms of the GNU General Public License as published by | |
9 | the Free Software Foundation; either version 2, or (at your option) | |
10 | any later version. | |
11 | ||
12 | GNU CC is distributed in the hope that it will be useful, | |
13 | but WITHOUT ANY WARRANTY; without even the implied warranty of | |
14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
15 | GNU General Public License for more details. | |
16 | ||
17 | You should have received a copy of the GNU General Public License | |
18 | along with GNU CC; see the file COPYING. If not, write to | |
c58d4270 | 19 | the Free Software Foundation, 59 Temple Place - Suite 330, |
20 | Boston, MA 02111-1307, USA. */ | |
471086d6 | 21 | |
22 | ||
23 | /* This file contains the functions for converting C expressions | |
24 | to different data types. The only entry point is `convert'. | |
25 | Every language front end must have a `convert' function | |
26 | but what kind of conversions it does will depend on the language. */ | |
27 | ||
28 | #include "config.h" | |
b3ef7553 | 29 | #include "system.h" |
471086d6 | 30 | #include "tree.h" |
31 | #include "flags.h" | |
32 | #include "cp-tree.h" | |
471086d6 | 33 | #include "convert.h" |
f0eaeecd | 34 | #include "toplev.h" |
2e8226f7 | 35 | #include "decl.h" |
96624a9e | 36 | |
71ccdfff | 37 | static tree cp_convert_to_pointer PROTO((tree, tree)); |
38 | static tree convert_to_pointer_force PROTO((tree, tree)); | |
6a44e72e | 39 | static tree build_up_reference PROTO((tree, tree, int)); |
71ccdfff | 40 | |
471086d6 | 41 | /* Change of width--truncation and extension of integers or reals-- |
42 | is represented with NOP_EXPR. Proper functioning of many things | |
43 | assumes that no other conversions can be NOP_EXPRs. | |
44 | ||
45 | Conversion between integer and pointer is represented with CONVERT_EXPR. | |
46 | Converting integer to real uses FLOAT_EXPR | |
47 | and real to integer uses FIX_TRUNC_EXPR. | |
48 | ||
49 | Here is a list of all the functions that assume that widening and | |
50 | narrowing is always done with a NOP_EXPR: | |
51 | In convert.c, convert_to_integer. | |
52 | In c-typeck.c, build_binary_op_nodefault (boolean ops), | |
53 | and truthvalue_conversion. | |
54 | In expr.c: expand_expr, for operands of a MULT_EXPR. | |
55 | In fold-const.c: fold. | |
56 | In tree.c: get_narrower and get_unwidened. | |
57 | ||
58 | C++: in multiple-inheritance, converting between pointers may involve | |
59 | adjusting them by a delta stored within the class definition. */ | |
60 | \f | |
61 | /* Subroutines of `convert'. */ | |
62 | ||
471086d6 | 63 | /* if converting pointer to pointer |
64 | if dealing with classes, check for derived->base or vice versa | |
65 | else if dealing with method pointers, delegate | |
66 | else convert blindly | |
67 | else if converting class, pass off to build_type_conversion | |
68 | else try C-style pointer conversion */ | |
96624a9e | 69 | |
471086d6 | 70 | static tree |
71 | cp_convert_to_pointer (type, expr) | |
72 | tree type, expr; | |
73 | { | |
74 | register tree intype = TREE_TYPE (expr); | |
74002e1d | 75 | register enum tree_code form; |
f82eeb87 | 76 | tree rval; |
74002e1d | 77 | |
96624a9e | 78 | if (IS_AGGR_TYPE (intype)) |
79 | { | |
96624a9e | 80 | intype = complete_type (intype); |
81 | if (TYPE_SIZE (intype) == NULL_TREE) | |
82 | { | |
905d4035 | 83 | cp_error ("can't convert from incomplete type `%T' to `%T'", |
96624a9e | 84 | intype, type); |
85 | return error_mark_node; | |
86 | } | |
87 | ||
1c16607c | 88 | rval = build_type_conversion (type, expr, 1); |
96624a9e | 89 | if (rval) |
90 | { | |
91 | if (rval == error_mark_node) | |
905d4035 | 92 | cp_error ("conversion of `%E' from `%T' to `%T' is ambiguous", |
96624a9e | 93 | expr, intype, type); |
94 | return rval; | |
95 | } | |
96 | } | |
97 | ||
860740a7 | 98 | /* Handle anachronistic conversions from (::*)() to cv void* or (*)(). */ |
38281c46 | 99 | if (TREE_CODE (type) == POINTER_TYPE |
100 | && (TREE_CODE (TREE_TYPE (type)) == FUNCTION_TYPE | |
860740a7 | 101 | || TYPE_MAIN_VARIANT (TREE_TYPE (type)) == void_type_node)) |
38281c46 | 102 | { |
103 | /* Allow an implicit this pointer for pointer to member | |
104 | functions. */ | |
860740a7 | 105 | if (TYPE_PTRMEMFUNC_P (intype)) |
38281c46 | 106 | { |
860740a7 | 107 | tree fntype = TREE_TYPE (TYPE_PTRMEMFUNC_FN_TYPE (intype)); |
2917b86f | 108 | tree decl = maybe_dummy_object (TYPE_METHOD_BASETYPE (fntype), 0); |
38281c46 | 109 | expr = build (OFFSET_REF, fntype, decl, expr); |
110 | } | |
111 | ||
112 | if (TREE_CODE (expr) == OFFSET_REF | |
113 | && TREE_CODE (TREE_TYPE (expr)) == METHOD_TYPE) | |
114 | expr = resolve_offset_ref (expr); | |
115 | if (TREE_CODE (TREE_TYPE (expr)) == METHOD_TYPE) | |
116 | expr = build_addr_func (expr); | |
117 | if (TREE_CODE (TREE_TYPE (expr)) == POINTER_TYPE) | |
118 | { | |
119 | if (TREE_CODE (TREE_TYPE (TREE_TYPE (expr))) == METHOD_TYPE) | |
120 | if (pedantic || warn_pmf2ptr) | |
905d4035 | 121 | cp_pedwarn ("converting from `%T' to `%T'", TREE_TYPE (expr), |
38281c46 | 122 | type); |
123 | return build1 (NOP_EXPR, type, expr); | |
124 | } | |
125 | intype = TREE_TYPE (expr); | |
126 | } | |
127 | ||
74002e1d | 128 | form = TREE_CODE (intype); |
129 | ||
2b77484d | 130 | if (POINTER_TYPE_P (intype)) |
471086d6 | 131 | { |
132 | intype = TYPE_MAIN_VARIANT (intype); | |
133 | ||
134 | if (TYPE_MAIN_VARIANT (type) != intype | |
2b77484d | 135 | && TREE_CODE (type) == POINTER_TYPE |
471086d6 | 136 | && TREE_CODE (TREE_TYPE (type)) == RECORD_TYPE |
bccffb3a | 137 | && IS_AGGR_TYPE (TREE_TYPE (type)) |
138 | && IS_AGGR_TYPE (TREE_TYPE (intype)) | |
2edf445e | 139 | && TREE_CODE (TREE_TYPE (intype)) == RECORD_TYPE |
140 | /* If EXPR is NULL, then we don't need to do any arithmetic | |
141 | to convert it: | |
142 | ||
143 | [conv.ptr] | |
144 | ||
145 | The null pointer value is converted to the null pointer | |
146 | value of the destination type. */ | |
147 | && !integer_zerop (expr)) | |
471086d6 | 148 | { |
149 | enum tree_code code = PLUS_EXPR; | |
150 | tree binfo = get_binfo (TREE_TYPE (type), TREE_TYPE (intype), 1); | |
151 | if (binfo == error_mark_node) | |
152 | return error_mark_node; | |
153 | if (binfo == NULL_TREE) | |
154 | { | |
155 | binfo = get_binfo (TREE_TYPE (intype), TREE_TYPE (type), 1); | |
156 | if (binfo == error_mark_node) | |
157 | return error_mark_node; | |
158 | code = MINUS_EXPR; | |
159 | } | |
160 | if (binfo) | |
161 | { | |
162 | if (TYPE_USES_VIRTUAL_BASECLASSES (TREE_TYPE (type)) | |
163 | || TYPE_USES_VIRTUAL_BASECLASSES (TREE_TYPE (intype)) | |
164 | || ! BINFO_OFFSET_ZEROP (binfo)) | |
165 | { | |
166 | /* Need to get the path we took. */ | |
167 | tree path; | |
168 | ||
169 | if (code == PLUS_EXPR) | |
985e9ee0 | 170 | get_base_distance (TREE_TYPE (type), TREE_TYPE (intype), |
171 | 0, &path); | |
471086d6 | 172 | else |
985e9ee0 | 173 | get_base_distance (TREE_TYPE (intype), TREE_TYPE (type), |
174 | 0, &path); | |
471086d6 | 175 | return build_vbase_path (code, type, expr, path, 0); |
176 | } | |
177 | } | |
178 | } | |
471086d6 | 179 | |
1c16607c | 180 | if (TYPE_PTRMEM_P (type) && TYPE_PTRMEM_P (intype)) |
bea7d742 | 181 | { |
a17aefa2 | 182 | tree b1; |
183 | tree b2; | |
184 | tree binfo; | |
185 | enum tree_code code; | |
186 | ||
187 | b1 = TYPE_OFFSET_BASETYPE (TREE_TYPE (type)); | |
188 | b2 = TYPE_OFFSET_BASETYPE (TREE_TYPE (intype)); | |
189 | binfo = get_binfo (b2, b1, 1); | |
fc9fc8d8 | 190 | |
bea7d742 | 191 | if (binfo == NULL_TREE) |
fc9fc8d8 | 192 | { |
193 | binfo = get_binfo (b1, b2, 1); | |
194 | code = MINUS_EXPR; | |
195 | } | |
a17aefa2 | 196 | else |
197 | code = PLUS_EXPR; | |
fc9fc8d8 | 198 | |
bea7d742 | 199 | if (binfo == error_mark_node) |
200 | return error_mark_node; | |
a17aefa2 | 201 | |
7045d67a | 202 | if (binfo_from_vbase (binfo)) |
203 | { | |
204 | cp_error ("conversion to `%T' from pointer to member of virtual base `%T'", | |
205 | type, intype); | |
206 | return error_mark_node; | |
207 | } | |
208 | ||
a17aefa2 | 209 | if (TREE_CODE (expr) == PTRMEM_CST) |
210 | expr = cplus_expand_constant (expr); | |
211 | ||
fc9fc8d8 | 212 | if (binfo && ! TREE_VIA_VIRTUAL (binfo)) |
213 | expr = size_binop (code, expr, BINFO_OFFSET (binfo)); | |
bea7d742 | 214 | } |
2b77484d | 215 | else if (TYPE_PTRMEMFUNC_P (type)) |
ce28ee2e | 216 | { |
905d4035 | 217 | cp_error ("cannot convert `%E' from type `%T' to type `%T'", |
ce28ee2e | 218 | expr, intype, type); |
219 | return error_mark_node; | |
220 | } | |
221 | ||
f82eeb87 | 222 | rval = build1 (NOP_EXPR, type, expr); |
223 | TREE_CONSTANT (rval) = TREE_CONSTANT (expr); | |
224 | return rval; | |
471086d6 | 225 | } |
2b77484d | 226 | else if (TYPE_PTRMEMFUNC_P (type) && TYPE_PTRMEMFUNC_P (intype)) |
7045d67a | 227 | return build_ptrmemfunc (TYPE_PTRMEMFUNC_FN_TYPE (type), expr, 0); |
2b77484d | 228 | else if (TYPE_PTRMEMFUNC_P (intype)) |
229 | { | |
230 | cp_error ("cannot convert `%E' from type `%T' to type `%T'", | |
231 | expr, intype, type); | |
232 | return error_mark_node; | |
233 | } | |
471086d6 | 234 | |
235 | my_friendly_assert (form != OFFSET_TYPE, 186); | |
236 | ||
471086d6 | 237 | if (integer_zerop (expr)) |
238 | { | |
2b77484d | 239 | if (TYPE_PTRMEMFUNC_P (type)) |
f05d5d03 | 240 | return build_ptrmemfunc (TYPE_PTRMEMFUNC_FN_TYPE (type), expr, 0); |
471086d6 | 241 | expr = build_int_2 (0, 0); |
242 | TREE_TYPE (expr) = type; | |
243 | return expr; | |
244 | } | |
245 | ||
bb0726a1 | 246 | if (INTEGRAL_CODE_P (form)) |
471086d6 | 247 | { |
c5aa1e92 | 248 | if (TYPE_PRECISION (intype) == POINTER_SIZE) |
471086d6 | 249 | return build1 (CONVERT_EXPR, type, expr); |
c4a8ac95 | 250 | expr = cp_convert (type_for_size (POINTER_SIZE, 0), expr); |
471086d6 | 251 | /* Modes may be different but sizes should be the same. */ |
252 | if (GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (expr))) | |
253 | != GET_MODE_SIZE (TYPE_MODE (type))) | |
254 | /* There is supposed to be some integral type | |
255 | that is the same width as a pointer. */ | |
256 | abort (); | |
257 | return convert_to_pointer (type, expr); | |
258 | } | |
259 | ||
cc4d0855 | 260 | if (type_unknown_p (expr)) |
261 | return instantiate_type (type, expr, 1); | |
262 | ||
905d4035 | 263 | cp_error ("cannot convert `%E' from type `%T' to type `%T'", |
471086d6 | 264 | expr, intype, type); |
265 | return error_mark_node; | |
266 | } | |
267 | ||
268 | /* Like convert, except permit conversions to take place which | |
269 | are not normally allowed due to access restrictions | |
270 | (such as conversion from sub-type to private super-type). */ | |
96624a9e | 271 | |
471086d6 | 272 | static tree |
273 | convert_to_pointer_force (type, expr) | |
274 | tree type, expr; | |
275 | { | |
276 | register tree intype = TREE_TYPE (expr); | |
277 | register enum tree_code form = TREE_CODE (intype); | |
278 | ||
279 | if (integer_zerop (expr)) | |
280 | { | |
471086d6 | 281 | expr = build_int_2 (0, 0); |
282 | TREE_TYPE (expr) = type; | |
283 | return expr; | |
284 | } | |
285 | ||
471086d6 | 286 | if (form == POINTER_TYPE) |
287 | { | |
288 | intype = TYPE_MAIN_VARIANT (intype); | |
289 | ||
290 | if (TYPE_MAIN_VARIANT (type) != intype | |
291 | && TREE_CODE (TREE_TYPE (type)) == RECORD_TYPE | |
bccffb3a | 292 | && IS_AGGR_TYPE (TREE_TYPE (type)) |
293 | && IS_AGGR_TYPE (TREE_TYPE (intype)) | |
471086d6 | 294 | && TREE_CODE (TREE_TYPE (intype)) == RECORD_TYPE) |
295 | { | |
296 | enum tree_code code = PLUS_EXPR; | |
297 | tree path; | |
298 | int distance = get_base_distance (TREE_TYPE (type), | |
299 | TREE_TYPE (intype), 0, &path); | |
300 | if (distance == -2) | |
301 | { | |
302 | ambig: | |
905d4035 | 303 | cp_error ("type `%T' is ambiguous baseclass of `%s'", |
b0df6589 | 304 | TREE_TYPE (type), |
305 | TYPE_NAME_STRING (TREE_TYPE (intype))); | |
471086d6 | 306 | return error_mark_node; |
307 | } | |
308 | if (distance == -1) | |
309 | { | |
310 | distance = get_base_distance (TREE_TYPE (intype), | |
311 | TREE_TYPE (type), 0, &path); | |
312 | if (distance == -2) | |
313 | goto ambig; | |
314 | if (distance < 0) | |
315 | /* Doesn't need any special help from us. */ | |
316 | return build1 (NOP_EXPR, type, expr); | |
317 | ||
318 | code = MINUS_EXPR; | |
319 | } | |
320 | return build_vbase_path (code, type, expr, path, 0); | |
321 | } | |
471086d6 | 322 | } |
323 | ||
324 | return cp_convert_to_pointer (type, expr); | |
325 | } | |
326 | ||
327 | /* We are passing something to a function which requires a reference. | |
328 | The type we are interested in is in TYPE. The initial | |
329 | value we have to begin with is in ARG. | |
330 | ||
331 | FLAGS controls how we manage access checking. | |
c76251c1 | 332 | DIRECT_BIND in FLAGS controls how any temporaries are generated. */ |
96624a9e | 333 | |
471086d6 | 334 | static tree |
6a44e72e | 335 | build_up_reference (type, arg, flags) |
471086d6 | 336 | tree type, arg; |
6a44e72e | 337 | int flags; |
471086d6 | 338 | { |
c76251c1 | 339 | tree rval; |
0543e7a9 | 340 | tree argtype = TREE_TYPE (arg); |
471086d6 | 341 | tree target_type = TREE_TYPE (type); |
471086d6 | 342 | |
343 | my_friendly_assert (TREE_CODE (type) == REFERENCE_TYPE, 187); | |
471086d6 | 344 | |
c76251c1 | 345 | if ((flags & DIRECT_BIND) && ! real_lvalue_p (arg)) |
471086d6 | 346 | { |
c76251c1 | 347 | tree targ = arg; |
38281c46 | 348 | if (toplevel_bindings_p ()) |
c76251c1 | 349 | arg = get_temp_name (argtype, 1); |
471086d6 | 350 | else |
351 | { | |
38281c46 | 352 | arg = pushdecl (build_decl (VAR_DECL, NULL_TREE, argtype)); |
353 | DECL_ARTIFICIAL (arg) = 1; | |
1ad432f2 | 354 | } |
38281c46 | 355 | DECL_INITIAL (arg) = targ; |
011310f7 | 356 | cp_finish_decl (arg, targ, NULL_TREE, 0, |
357 | LOOKUP_ONLYCONVERTING|DIRECT_BIND); | |
1ad432f2 | 358 | } |
c76251c1 | 359 | else if (!(flags & DIRECT_BIND) && ! lvalue_p (arg)) |
1ad432f2 | 360 | { |
38281c46 | 361 | tree slot = build_decl (VAR_DECL, NULL_TREE, argtype); |
011310f7 | 362 | DECL_ARTIFICIAL (slot) = 1; |
38281c46 | 363 | arg = build (TARGET_EXPR, argtype, slot, arg, NULL_TREE, NULL_TREE); |
0f76a66d | 364 | TREE_SIDE_EFFECTS (arg) = 1; |
471086d6 | 365 | } |
1ad432f2 | 366 | |
b0df6589 | 367 | /* If we had a way to wrap this up, and say, if we ever needed it's |
368 | address, transform all occurrences of the register, into a memory | |
369 | reference we could win better. */ | |
c76251c1 | 370 | rval = build_unary_op (ADDR_EXPR, arg, 1); |
15e55420 | 371 | if (rval == error_mark_node) |
372 | return error_mark_node; | |
373 | ||
6686e84d | 374 | if ((flags & LOOKUP_PROTECT) |
375 | && TYPE_MAIN_VARIANT (argtype) != TYPE_MAIN_VARIANT (target_type) | |
376 | && IS_AGGR_TYPE (argtype) | |
377 | && IS_AGGR_TYPE (target_type)) | |
378 | { | |
379 | /* We go through get_binfo for the access control. */ | |
380 | tree binfo = get_binfo (target_type, argtype, 1); | |
381 | if (binfo == error_mark_node) | |
382 | return error_mark_node; | |
383 | if (binfo == NULL_TREE) | |
384 | return error_not_base_type (target_type, argtype); | |
385 | rval = convert_pointer_to_real (binfo, rval); | |
386 | } | |
c76251c1 | 387 | else |
388 | rval | |
389 | = convert_to_pointer_force (build_pointer_type (target_type), rval); | |
6686e84d | 390 | rval = build1 (NOP_EXPR, type, rval); |
c76251c1 | 391 | TREE_CONSTANT (rval) = TREE_CONSTANT (TREE_OPERAND (rval, 0)); |
471086d6 | 392 | return rval; |
393 | } | |
394 | ||
395 | /* For C++: Only need to do one-level references, but cannot | |
396 | get tripped up on signed/unsigned differences. | |
397 | ||
d81e00a4 | 398 | DECL is either NULL_TREE or the _DECL node for a reference that is being |
399 | initialized. It can be error_mark_node if we don't know the _DECL but | |
400 | we know it's an initialization. */ | |
471086d6 | 401 | |
471086d6 | 402 | tree |
d81e00a4 | 403 | convert_to_reference (reftype, expr, convtype, flags, decl) |
471086d6 | 404 | tree reftype, expr; |
d81e00a4 | 405 | int convtype, flags; |
406 | tree decl; | |
471086d6 | 407 | { |
408 | register tree type = TYPE_MAIN_VARIANT (TREE_TYPE (reftype)); | |
409 | register tree intype = TREE_TYPE (expr); | |
471086d6 | 410 | tree rval = NULL_TREE; |
1a3f833b | 411 | tree rval_as_conversion = NULL_TREE; |
412 | int i; | |
413 | ||
cc4d0855 | 414 | if (TREE_CODE (type) == FUNCTION_TYPE && intype == unknown_type_node) |
415 | { | |
3effa7a7 | 416 | expr = instantiate_type (type, expr, |
417 | (flags & LOOKUP_COMPLAIN) != 0); | |
418 | if (expr == error_mark_node) | |
419 | return error_mark_node; | |
420 | ||
cc4d0855 | 421 | intype = TREE_TYPE (expr); |
422 | } | |
423 | ||
1a3f833b | 424 | if (TREE_CODE (intype) == REFERENCE_TYPE) |
425 | my_friendly_abort (364); | |
471086d6 | 426 | |
471086d6 | 427 | intype = TYPE_MAIN_VARIANT (intype); |
428 | ||
1a3f833b | 429 | i = comp_target_types (type, intype, 0); |
430 | ||
431 | if (i <= 0 && (convtype & CONV_IMPLICIT) && IS_AGGR_TYPE (intype) | |
432 | && ! (flags & LOOKUP_NO_CONVERSION)) | |
433 | { | |
434 | /* Look for a user-defined conversion to lvalue that we can use. */ | |
435 | ||
0a4be248 | 436 | rval_as_conversion |
1c16607c | 437 | = build_type_conversion (reftype, expr, 1); |
1a3f833b | 438 | |
439 | if (rval_as_conversion && rval_as_conversion != error_mark_node | |
440 | && real_lvalue_p (rval_as_conversion)) | |
441 | { | |
442 | expr = rval_as_conversion; | |
443 | rval_as_conversion = NULL_TREE; | |
444 | intype = type; | |
445 | i = 1; | |
446 | } | |
447 | } | |
448 | ||
449 | if (((convtype & CONV_STATIC) && i == -1) | |
450 | || ((convtype & CONV_IMPLICIT) && i == 1)) | |
471086d6 | 451 | { |
471086d6 | 452 | if (flags & LOOKUP_COMPLAIN) |
453 | { | |
bc3887cf | 454 | tree ttl = TREE_TYPE (reftype); |
cb0ba4ec | 455 | tree ttr = lvalue_type (expr); |
471086d6 | 456 | |
21a6dc86 | 457 | /* [dcl.init.ref] says that if an rvalue is used to |
458 | initialize a reference, then the reference must be to a | |
459 | non-volatile const type. */ | |
460 | if (! real_lvalue_p (expr) | |
3e04bd45 | 461 | && !CP_TYPE_CONST_NON_VOLATILE_P (ttl)) |
bc3887cf | 462 | { |
e1721763 | 463 | const char *msg; |
21a6dc86 | 464 | |
3e04bd45 | 465 | if (CP_TYPE_VOLATILE_P (ttl) && decl) |
21a6dc86 | 466 | msg = "initialization of volatile reference type `%#T'"; |
3e04bd45 | 467 | else if (CP_TYPE_VOLATILE_P (ttl)) |
21a6dc86 | 468 | msg = "conversion to volatile reference type `%#T'"; |
469 | else if (decl) | |
470 | msg = "initialization of non-const reference type `%#T'"; | |
d81e00a4 | 471 | else |
21a6dc86 | 472 | msg = "conversion to non-const reference type `%#T'"; |
473 | ||
caa99b15 | 474 | cp_pedwarn (msg, reftype); |
475 | cp_pedwarn ("from rvalue of type `%T'", intype); | |
bc3887cf | 476 | } |
3e04bd45 | 477 | else if (! (convtype & CONV_CONST) |
478 | && !at_least_as_qualified_p (ttl, ttr)) | |
caa99b15 | 479 | cp_pedwarn ("conversion from `%T' to `%T' discards qualifiers", |
480 | ttr, reftype); | |
0543e7a9 | 481 | } |
482 | ||
6a44e72e | 483 | return build_up_reference (reftype, expr, flags); |
471086d6 | 484 | } |
c07b1ad1 | 485 | else if ((convtype & CONV_REINTERPRET) && lvalue_p (expr)) |
0543e7a9 | 486 | { |
487 | /* When casting an lvalue to a reference type, just convert into | |
488 | a pointer to the new type and deference it. This is allowed | |
e581f478 | 489 | by San Diego WP section 5.2.9 paragraph 12, though perhaps it |
0543e7a9 | 490 | should be done directly (jason). (int &)ri ---> *(int*)&ri */ |
e581f478 | 491 | |
3748625f | 492 | /* B* bp; A& ar = (A&)bp; is valid, but it's probably not what they |
e581f478 | 493 | meant. */ |
1a3f833b | 494 | if (TREE_CODE (intype) == POINTER_TYPE |
daf9ff67 | 495 | && (comptypes (TREE_TYPE (intype), type, |
496 | COMPARE_BASE | COMPARE_RELAXED ))) | |
905d4035 | 497 | cp_warning ("casting `%T' to `%T' does not dereference pointer", |
e581f478 | 498 | intype, reftype); |
499 | ||
0543e7a9 | 500 | rval = build_unary_op (ADDR_EXPR, expr, 0); |
501 | if (rval != error_mark_node) | |
985e9ee0 | 502 | rval = convert_force (build_pointer_type (TREE_TYPE (reftype)), |
503 | rval, 0); | |
0543e7a9 | 504 | if (rval != error_mark_node) |
b0722fac | 505 | rval = build1 (NOP_EXPR, reftype, rval); |
0543e7a9 | 506 | } |
0a4be248 | 507 | else |
860740a7 | 508 | { |
509 | rval = convert_for_initialization (NULL_TREE, type, expr, flags, | |
510 | "converting", 0, 0); | |
a66fe4cb | 511 | if (rval == NULL_TREE || rval == error_mark_node) |
512 | return rval; | |
6a44e72e | 513 | rval = build_up_reference (reftype, rval, flags); |
860740a7 | 514 | |
3e04bd45 | 515 | if (rval && ! CP_TYPE_CONST_P (TREE_TYPE (reftype))) |
905d4035 | 516 | cp_pedwarn ("initializing non-const `%T' with `%T' will use a temporary", |
860740a7 | 517 | reftype, intype); |
518 | } | |
471086d6 | 519 | |
520 | if (rval) | |
521 | { | |
96624a9e | 522 | /* If we found a way to convert earlier, then use it. */ |
471086d6 | 523 | return rval; |
524 | } | |
525 | ||
1a3f833b | 526 | my_friendly_assert (TREE_CODE (intype) != OFFSET_TYPE, 189); |
471086d6 | 527 | |
b248d3f7 | 528 | if (flags & LOOKUP_COMPLAIN) |
905d4035 | 529 | cp_error ("cannot convert type `%T' to type `%T'", intype, reftype); |
b248d3f7 | 530 | |
471086d6 | 531 | if (flags & LOOKUP_SPECULATIVELY) |
532 | return NULL_TREE; | |
533 | ||
534 | return error_mark_node; | |
535 | } | |
536 | ||
537 | /* We are using a reference VAL for its value. Bash that reference all the | |
96624a9e | 538 | way down to its lowest form. */ |
539 | ||
471086d6 | 540 | tree |
541 | convert_from_reference (val) | |
542 | tree val; | |
543 | { | |
544 | tree type = TREE_TYPE (val); | |
545 | ||
546 | if (TREE_CODE (type) == OFFSET_TYPE) | |
547 | type = TREE_TYPE (type); | |
8c5c575d | 548 | if (TREE_CODE (type) == REFERENCE_TYPE) |
549 | return build_indirect_ref (val, NULL_PTR); | |
471086d6 | 550 | return val; |
551 | } | |
552 | \f | |
471086d6 | 553 | /* Call this when we know (for any reason) that expr is not, in fact, |
554 | zero. This routine is like convert_pointer_to, but it pays | |
555 | attention to which specific instance of what type we want to | |
556 | convert to. This routine should eventually become | |
557 | convert_to_pointer after all references to convert_to_pointer | |
558 | are removed. */ | |
96624a9e | 559 | |
471086d6 | 560 | tree |
561 | convert_pointer_to_real (binfo, expr) | |
562 | tree binfo, expr; | |
563 | { | |
564 | register tree intype = TREE_TYPE (expr); | |
565 | tree ptr_type; | |
566 | tree type, rval; | |
567 | ||
00d2b1b9 | 568 | if (intype == error_mark_node) |
569 | return error_mark_node; | |
570 | ||
471086d6 | 571 | if (TREE_CODE (binfo) == TREE_VEC) |
572 | type = BINFO_TYPE (binfo); | |
573 | else if (IS_AGGR_TYPE (binfo)) | |
574 | { | |
575 | type = binfo; | |
576 | } | |
577 | else | |
578 | { | |
579 | type = binfo; | |
580 | binfo = NULL_TREE; | |
581 | } | |
582 | ||
3e04bd45 | 583 | ptr_type = cp_build_qualified_type (type, |
584 | CP_TYPE_QUALS (TREE_TYPE (intype))); | |
d2a15a12 | 585 | ptr_type = build_pointer_type (ptr_type); |
cf90626c | 586 | if (same_type_p (ptr_type, TYPE_MAIN_VARIANT (intype))) |
471086d6 | 587 | return expr; |
588 | ||
471086d6 | 589 | my_friendly_assert (!integer_zerop (expr), 191); |
590 | ||
0df40fee | 591 | intype = TYPE_MAIN_VARIANT (TREE_TYPE (intype)); |
471086d6 | 592 | if (TREE_CODE (type) == RECORD_TYPE |
0df40fee | 593 | && TREE_CODE (intype) == RECORD_TYPE |
594 | && type != intype) | |
471086d6 | 595 | { |
596 | tree path; | |
597 | int distance | |
0df40fee | 598 | = get_base_distance (binfo, intype, 0, &path); |
471086d6 | 599 | |
600 | /* This function shouldn't be called with unqualified arguments | |
601 | but if it is, give them an error message that they can read. */ | |
602 | if (distance < 0) | |
603 | { | |
905d4035 | 604 | cp_error ("cannot convert a pointer of type `%T' to a pointer of type `%T'", |
0df40fee | 605 | intype, type); |
471086d6 | 606 | |
607 | if (distance == -2) | |
905d4035 | 608 | cp_error ("because `%T' is an ambiguous base class", type); |
471086d6 | 609 | return error_mark_node; |
610 | } | |
611 | ||
612 | return build_vbase_path (PLUS_EXPR, ptr_type, expr, path, 1); | |
613 | } | |
614 | rval = build1 (NOP_EXPR, ptr_type, | |
615 | TREE_CODE (expr) == NOP_EXPR ? TREE_OPERAND (expr, 0) : expr); | |
616 | TREE_CONSTANT (rval) = TREE_CONSTANT (expr); | |
617 | return rval; | |
618 | } | |
619 | ||
620 | /* Call this when we know (for any reason) that expr is | |
621 | not, in fact, zero. This routine gets a type out of the first | |
622 | argument and uses it to search for the type to convert to. If there | |
623 | is more than one instance of that type in the expr, the conversion is | |
624 | ambiguous. This routine should eventually go away, and all | |
625 | callers should use convert_to_pointer_real. */ | |
96624a9e | 626 | |
471086d6 | 627 | tree |
628 | convert_pointer_to (binfo, expr) | |
629 | tree binfo, expr; | |
630 | { | |
631 | tree type; | |
632 | ||
633 | if (TREE_CODE (binfo) == TREE_VEC) | |
634 | type = BINFO_TYPE (binfo); | |
635 | else if (IS_AGGR_TYPE (binfo)) | |
144715aa | 636 | type = binfo; |
471086d6 | 637 | else |
144715aa | 638 | type = binfo; |
471086d6 | 639 | return convert_pointer_to_real (type, expr); |
640 | } | |
471086d6 | 641 | \f |
c4a8ac95 | 642 | /* C++ conversions, preference to static cast conversions. */ |
643 | ||
644 | tree | |
645 | cp_convert (type, expr) | |
646 | tree type, expr; | |
647 | { | |
648 | return ocp_convert (type, expr, CONV_OLD_CONVERT, LOOKUP_NORMAL); | |
649 | } | |
650 | ||
b248d3f7 | 651 | /* Conversion... |
652 | ||
653 | FLAGS indicates how we should behave. */ | |
654 | ||
471086d6 | 655 | tree |
c4a8ac95 | 656 | ocp_convert (type, expr, convtype, flags) |
471086d6 | 657 | tree type, expr; |
d81e00a4 | 658 | int convtype, flags; |
471086d6 | 659 | { |
660 | register tree e = expr; | |
661 | register enum tree_code code = TREE_CODE (type); | |
662 | ||
b465397d | 663 | if (e == error_mark_node |
664 | || TREE_TYPE (e) == error_mark_node) | |
471086d6 | 665 | return error_mark_node; |
d81e00a4 | 666 | |
7745052b | 667 | if (TREE_READONLY_DECL_P (e)) |
668 | e = decl_constant_value (e); | |
669 | ||
2133b374 | 670 | if (IS_AGGR_TYPE (type) && (convtype & CONV_FORCE_TEMP) |
671 | /* Some internal structures (vtable_entry_type, sigtbl_ptr_type) | |
672 | don't go through finish_struct, so they don't have the synthesized | |
673 | constructors. So don't force a temporary. */ | |
674 | && TYPE_HAS_CONSTRUCTOR (type)) | |
1a3f833b | 675 | /* We need a new temporary; don't take this shortcut. */; |
676 | else if (TYPE_MAIN_VARIANT (type) == TYPE_MAIN_VARIANT (TREE_TYPE (e))) | |
ca23ec64 | 677 | { |
daf9ff67 | 678 | if (same_type_p (type, TREE_TYPE (e))) |
ca23ec64 | 679 | /* The call to fold will not always remove the NOP_EXPR as |
680 | might be expected, since if one of the types is a typedef; | |
681 | the comparsion in fold is just equality of pointers, not a | |
f699c174 | 682 | call to comptypes. We don't call fold in this case because |
683 | that can result in infinite recursion; fold will call | |
684 | convert, which will call ocp_convert, etc. */ | |
685 | return e; | |
ca23ec64 | 686 | else |
f699c174 | 687 | return fold (build1 (NOP_EXPR, type, e)); |
ca23ec64 | 688 | } |
689 | ||
d81e00a4 | 690 | if (code == VOID_TYPE && (convtype & CONV_STATIC)) |
95b2ac55 | 691 | { |
aeef2be5 | 692 | e = require_complete_type_in_void (e); |
693 | if (e != error_mark_node) | |
694 | e = build1 (CONVERT_EXPR, void_type_node, e); | |
95b2ac55 | 695 | |
aeef2be5 | 696 | return e; |
95b2ac55 | 697 | } |
d81e00a4 | 698 | |
471086d6 | 699 | #if 0 |
700 | /* This is incorrect. A truncation can't be stripped this way. | |
701 | Extensions will be stripped by the use of get_unwidened. */ | |
617abf06 | 702 | if (TREE_CODE (e) == NOP_EXPR) |
c4a8ac95 | 703 | return cp_convert (type, TREE_OPERAND (e, 0)); |
471086d6 | 704 | #endif |
705 | ||
706 | /* Just convert to the type of the member. */ | |
707 | if (code == OFFSET_TYPE) | |
708 | { | |
709 | type = TREE_TYPE (type); | |
710 | code = TREE_CODE (type); | |
711 | } | |
712 | ||
1a3f833b | 713 | #if 0 |
471086d6 | 714 | if (code == REFERENCE_TYPE) |
d81e00a4 | 715 | return fold (convert_to_reference (type, e, convtype, flags, NULL_TREE)); |
471086d6 | 716 | else if (TREE_CODE (TREE_TYPE (e)) == REFERENCE_TYPE) |
717 | e = convert_from_reference (e); | |
1a3f833b | 718 | #endif |
471086d6 | 719 | |
f3ba5c6a | 720 | if (TREE_CODE (e) == OFFSET_REF) |
721 | e = resolve_offset_ref (e); | |
722 | ||
bb0726a1 | 723 | if (INTEGRAL_CODE_P (code)) |
471086d6 | 724 | { |
617abf06 | 725 | tree intype = TREE_TYPE (e); |
02d7f858 | 726 | /* enum = enum, enum = int, enum = float, (enum)pointer are all |
727 | errors. */ | |
723d9ad3 | 728 | if (TREE_CODE (type) == ENUMERAL_TYPE |
02d7f858 | 729 | && ((ARITHMETIC_TYPE_P (intype) && ! (convtype & CONV_STATIC)) |
730 | || (TREE_CODE (intype) == POINTER_TYPE))) | |
471086d6 | 731 | { |
905d4035 | 732 | cp_pedwarn ("conversion from `%#T' to `%#T'", intype, type); |
471086d6 | 733 | |
734 | if (flag_pedantic_errors) | |
735 | return error_mark_node; | |
736 | } | |
f3ba5c6a | 737 | if (IS_AGGR_TYPE (intype)) |
471086d6 | 738 | { |
739 | tree rval; | |
1c16607c | 740 | rval = build_type_conversion (type, e, 1); |
6495357a | 741 | if (rval) |
742 | return rval; | |
b248d3f7 | 743 | if (flags & LOOKUP_COMPLAIN) |
905d4035 | 744 | cp_error ("`%#T' used where a `%T' was expected", intype, type); |
b248d3f7 | 745 | if (flags & LOOKUP_SPECULATIVELY) |
746 | return NULL_TREE; | |
471086d6 | 747 | return error_mark_node; |
748 | } | |
bb0726a1 | 749 | if (code == BOOLEAN_TYPE) |
e4ce2dc4 | 750 | { |
751 | /* Common Ada/Pascal programmer's mistake. We always warn | |
752 | about this since it is so bad. */ | |
753 | if (TREE_CODE (expr) == FUNCTION_DECL) | |
905d4035 | 754 | cp_warning ("the address of `%D', will always be `true'", expr); |
e4ce2dc4 | 755 | return truthvalue_conversion (e); |
756 | } | |
471086d6 | 757 | return fold (convert_to_integer (type, e)); |
758 | } | |
74002e1d | 759 | if (code == POINTER_TYPE || code == REFERENCE_TYPE |
760 | || TYPE_PTRMEMFUNC_P (type)) | |
471086d6 | 761 | return fold (cp_convert_to_pointer (type, e)); |
c4a8ac95 | 762 | if (code == REAL_TYPE || code == COMPLEX_TYPE) |
471086d6 | 763 | { |
764 | if (IS_AGGR_TYPE (TREE_TYPE (e))) | |
765 | { | |
766 | tree rval; | |
1c16607c | 767 | rval = build_type_conversion (type, e, 1); |
471086d6 | 768 | if (rval) |
769 | return rval; | |
770 | else | |
b248d3f7 | 771 | if (flags & LOOKUP_COMPLAIN) |
905d4035 | 772 | cp_error ("`%#T' used where a floating point value was expected", |
b248d3f7 | 773 | TREE_TYPE (e)); |
471086d6 | 774 | } |
c4a8ac95 | 775 | if (code == REAL_TYPE) |
776 | return fold (convert_to_real (type, e)); | |
777 | else if (code == COMPLEX_TYPE) | |
778 | return fold (convert_to_complex (type, e)); | |
471086d6 | 779 | } |
780 | ||
781 | /* New C++ semantics: since assignment is now based on | |
782 | memberwise copying, if the rhs type is derived from the | |
783 | lhs type, then we may still do a conversion. */ | |
784 | if (IS_AGGR_TYPE_CODE (code)) | |
785 | { | |
786 | tree dtype = TREE_TYPE (e); | |
c25194fd | 787 | tree ctor = NULL_TREE; |
471086d6 | 788 | |
471086d6 | 789 | dtype = TYPE_MAIN_VARIANT (dtype); |
790 | ||
471086d6 | 791 | /* Conversion between aggregate types. New C++ semantics allow |
792 | objects of derived type to be cast to objects of base type. | |
793 | Old semantics only allowed this between pointers. | |
794 | ||
795 | There may be some ambiguity between using a constructor | |
796 | vs. using a type conversion operator when both apply. */ | |
797 | ||
0a4be248 | 798 | ctor = e; |
860740a7 | 799 | |
8c18e707 | 800 | if (abstract_virtuals_error (NULL_TREE, type)) |
801 | return error_mark_node; | |
6cbb4197 | 802 | |
0a4be248 | 803 | if ((flags & LOOKUP_ONLYCONVERTING) |
804 | && ! (IS_AGGR_TYPE (dtype) && DERIVED_FROM_P (type, dtype))) | |
fce73460 | 805 | /* For copy-initialization, first we create a temp of the proper type |
806 | with a user-defined conversion sequence, then we direct-initialize | |
807 | the target with the temp (see [dcl.init]). */ | |
808 | ctor = build_user_type_conversion (type, ctor, flags); | |
0a4be248 | 809 | if (ctor) |
810 | ctor = build_method_call (NULL_TREE, ctor_identifier, | |
811 | build_expr_list (NULL_TREE, ctor), | |
812 | TYPE_BINFO (type), flags); | |
813 | if (ctor) | |
814 | return build_cplus_new (type, ctor); | |
471086d6 | 815 | } |
816 | ||
617abf06 | 817 | /* If TYPE or TREE_TYPE (E) is not on the permanent_obstack, |
7745052b | 818 | then it won't be hashed and hence compare as not equal, |
471086d6 | 819 | even when it is. */ |
820 | if (code == ARRAY_TYPE | |
617abf06 | 821 | && TREE_TYPE (TREE_TYPE (e)) == TREE_TYPE (type) |
822 | && index_type_equal (TYPE_DOMAIN (TREE_TYPE (e)), TYPE_DOMAIN (type))) | |
823 | return e; | |
471086d6 | 824 | |
b248d3f7 | 825 | if (flags & LOOKUP_COMPLAIN) |
905d4035 | 826 | cp_error ("conversion from `%T' to non-scalar type `%T' requested", |
b248d3f7 | 827 | TREE_TYPE (expr), type); |
828 | if (flags & LOOKUP_SPECULATIVELY) | |
829 | return NULL_TREE; | |
471086d6 | 830 | return error_mark_node; |
831 | } | |
832 | ||
d81e00a4 | 833 | /* Create an expression whose value is that of EXPR, |
834 | converted to type TYPE. The TREE_TYPE of the value | |
835 | is always TYPE. This function implements all reasonable | |
836 | conversions; callers should filter out those that are | |
c4a8ac95 | 837 | not permitted by the language being compiled. |
838 | ||
839 | Most of this routine is from build_reinterpret_cast. | |
840 | ||
841 | The backend cannot call cp_convert (what was convert) because | |
842 | conversions to/from basetypes may involve memory references | |
843 | (vbases) and adding or subtracting small values (multiple | |
844 | inheritance), but it calls convert from the constant folding code | |
845 | on subtrees of already build trees after it has ripped them apart. | |
846 | ||
847 | Also, if we ever support range variables, we'll probably also have to | |
848 | do a little bit more work. */ | |
d81e00a4 | 849 | |
850 | tree | |
851 | convert (type, expr) | |
852 | tree type, expr; | |
853 | { | |
c4a8ac95 | 854 | tree intype; |
855 | ||
856 | if (type == error_mark_node || expr == error_mark_node) | |
857 | return error_mark_node; | |
858 | ||
c4a8ac95 | 859 | intype = TREE_TYPE (expr); |
860 | ||
6686e84d | 861 | if (POINTER_TYPE_P (type) && POINTER_TYPE_P (intype)) |
c4a8ac95 | 862 | { |
863 | if (TREE_READONLY_DECL_P (expr)) | |
864 | expr = decl_constant_value (expr); | |
865 | return fold (build1 (NOP_EXPR, type, expr)); | |
866 | } | |
867 | ||
868 | return ocp_convert (type, expr, CONV_OLD_CONVERT, | |
869 | LOOKUP_NORMAL|LOOKUP_NO_CONVERSION); | |
d81e00a4 | 870 | } |
871 | ||
c4a8ac95 | 872 | /* Like cp_convert, except permit conversions to take place which |
471086d6 | 873 | are not normally allowed due to access restrictions |
874 | (such as conversion from sub-type to private super-type). */ | |
96624a9e | 875 | |
471086d6 | 876 | tree |
a74e8896 | 877 | convert_force (type, expr, convtype) |
471086d6 | 878 | tree type; |
879 | tree expr; | |
a74e8896 | 880 | int convtype; |
471086d6 | 881 | { |
882 | register tree e = expr; | |
883 | register enum tree_code code = TREE_CODE (type); | |
884 | ||
885 | if (code == REFERENCE_TYPE) | |
d81e00a4 | 886 | return fold (convert_to_reference (type, e, CONV_C_CAST, LOOKUP_COMPLAIN, |
887 | NULL_TREE)); | |
471086d6 | 888 | else if (TREE_CODE (TREE_TYPE (e)) == REFERENCE_TYPE) |
889 | e = convert_from_reference (e); | |
890 | ||
891 | if (code == POINTER_TYPE) | |
892 | return fold (convert_to_pointer_force (type, e)); | |
893 | ||
ac9386a0 | 894 | /* From typeck.c convert_for_assignment */ |
471086d6 | 895 | if (((TREE_CODE (TREE_TYPE (e)) == POINTER_TYPE && TREE_CODE (e) == ADDR_EXPR |
896 | && TREE_CODE (TREE_TYPE (e)) == POINTER_TYPE | |
897 | && TREE_CODE (TREE_TYPE (TREE_TYPE (e))) == METHOD_TYPE) | |
ac9386a0 | 898 | || integer_zerop (e) |
899 | || TYPE_PTRMEMFUNC_P (TREE_TYPE (e))) | |
471086d6 | 900 | && TYPE_PTRMEMFUNC_P (type)) |
901 | { | |
96624a9e | 902 | /* compatible pointer to member functions. */ |
ac9386a0 | 903 | return build_ptrmemfunc (TYPE_PTRMEMFUNC_FN_TYPE (type), e, 1); |
471086d6 | 904 | } |
a74e8896 | 905 | |
c4a8ac95 | 906 | return ocp_convert (type, e, CONV_C_CAST|convtype, LOOKUP_NORMAL); |
471086d6 | 907 | } |
908 | ||
471086d6 | 909 | /* Convert an aggregate EXPR to type XTYPE. If a conversion |
910 | exists, return the attempted conversion. This may | |
911 | return ERROR_MARK_NODE if the conversion is not | |
912 | allowed (references private members, etc). | |
913 | If no conversion exists, NULL_TREE is returned. | |
914 | ||
915 | If (FOR_SURE & 1) is non-zero, then we allow this type conversion | |
916 | to take place immediately. Otherwise, we build a SAVE_EXPR | |
ce28ee2e | 917 | which can be evaluated if the results are ever needed. |
918 | ||
919 | Changes to this functions should be mirrored in user_harshness. | |
920 | ||
921 | FIXME: Ambiguity checking is wrong. Should choose one by the implicit | |
922 | object parameter, or by the second standard conversion sequence if | |
923 | that doesn't do it. This will probably wait for an overloading rewrite. | |
924 | (jason 8/9/95) */ | |
471086d6 | 925 | |
471086d6 | 926 | tree |
1c16607c | 927 | build_type_conversion (xtype, expr, for_sure) |
471086d6 | 928 | tree xtype, expr; |
929 | int for_sure; | |
930 | { | |
931 | /* C++: check to see if we can convert this aggregate type | |
bcf789d7 | 932 | into the required type. */ |
0a4be248 | 933 | return build_user_type_conversion |
934 | (xtype, expr, for_sure ? LOOKUP_NORMAL : 0); | |
471086d6 | 935 | } |
936 | ||
1e66592c | 937 | /* Convert the given EXPR to one of a group of types suitable for use in an |
938 | expression. DESIRES is a combination of various WANT_* flags (q.v.) | |
939 | which indicates which types are suitable. If COMPLAIN is 1, complain | |
940 | about ambiguity; otherwise, the caller will deal with it. */ | |
471086d6 | 941 | |
1e66592c | 942 | tree |
943 | build_expr_type_conversion (desires, expr, complain) | |
944 | int desires; | |
945 | tree expr; | |
946 | int complain; | |
471086d6 | 947 | { |
1e66592c | 948 | tree basetype = TREE_TYPE (expr); |
6a44e72e | 949 | tree conv = NULL_TREE; |
bdd152ce | 950 | tree winner = NULL_TREE; |
471086d6 | 951 | |
954885ed | 952 | if (expr == null_node |
953 | && (desires & WANT_INT) | |
954 | && !(desires & WANT_NULL)) | |
905d4035 | 955 | cp_warning ("converting NULL to non-pointer type"); |
954885ed | 956 | |
42b9ec6a | 957 | if (TREE_CODE (expr) == OFFSET_REF) |
ce28ee2e | 958 | expr = resolve_offset_ref (expr); |
959 | expr = convert_from_reference (expr); | |
960 | basetype = TREE_TYPE (expr); | |
471086d6 | 961 | |
bdd152ce | 962 | if (! IS_AGGR_TYPE (basetype)) |
963 | switch (TREE_CODE (basetype)) | |
964 | { | |
965 | case INTEGER_TYPE: | |
954885ed | 966 | if ((desires & WANT_NULL) && null_ptr_cst_p (expr)) |
bdd152ce | 967 | return expr; |
968 | /* else fall through... */ | |
969 | ||
970 | case BOOLEAN_TYPE: | |
971 | return (desires & WANT_INT) ? expr : NULL_TREE; | |
972 | case ENUMERAL_TYPE: | |
973 | return (desires & WANT_ENUM) ? expr : NULL_TREE; | |
974 | case REAL_TYPE: | |
975 | return (desires & WANT_FLOAT) ? expr : NULL_TREE; | |
976 | case POINTER_TYPE: | |
977 | return (desires & WANT_POINTER) ? expr : NULL_TREE; | |
985e9ee0 | 978 | |
bdd152ce | 979 | case FUNCTION_TYPE: |
980 | case ARRAY_TYPE: | |
981 | return (desires & WANT_POINTER) ? default_conversion (expr) | |
982 | : NULL_TREE; | |
983 | default: | |
984 | return NULL_TREE; | |
985 | } | |
986 | ||
987 | /* The code for conversions from class type is currently only used for | |
988 | delete expressions. Other expressions are handled by build_new_op. */ | |
989 | ||
990 | if (! TYPE_HAS_CONVERSION (basetype)) | |
991 | return NULL_TREE; | |
992 | ||
993 | for (conv = lookup_conversions (basetype); conv; conv = TREE_CHAIN (conv)) | |
994 | { | |
995 | int win = 0; | |
996 | tree candidate; | |
997 | tree cand = TREE_VALUE (conv); | |
998 | ||
999 | if (winner && winner == cand) | |
1000 | continue; | |
1001 | ||
1002 | candidate = TREE_TYPE (TREE_TYPE (cand)); | |
1003 | if (TREE_CODE (candidate) == REFERENCE_TYPE) | |
1004 | candidate = TREE_TYPE (candidate); | |
1005 | ||
1006 | switch (TREE_CODE (candidate)) | |
1007 | { | |
1008 | case BOOLEAN_TYPE: | |
1009 | case INTEGER_TYPE: | |
1010 | win = (desires & WANT_INT); break; | |
1011 | case ENUMERAL_TYPE: | |
1012 | win = (desires & WANT_ENUM); break; | |
1013 | case REAL_TYPE: | |
1014 | win = (desires & WANT_FLOAT); break; | |
1015 | case POINTER_TYPE: | |
1016 | win = (desires & WANT_POINTER); break; | |
1017 | ||
1018 | default: | |
1019 | break; | |
1020 | } | |
1021 | ||
1022 | if (win) | |
1023 | { | |
1024 | if (winner) | |
1025 | { | |
1026 | if (complain) | |
1027 | { | |
905d4035 | 1028 | cp_error ("ambiguous default type conversion from `%T'", |
bdd152ce | 1029 | basetype); |
905d4035 | 1030 | cp_error (" candidate conversions include `%D' and `%D'", |
bdd152ce | 1031 | winner, cand); |
1032 | } | |
1033 | return error_mark_node; | |
1034 | } | |
1035 | else | |
1036 | winner = cand; | |
1037 | } | |
1038 | } | |
1e66592c | 1039 | |
bdd152ce | 1040 | if (winner) |
1041 | { | |
1042 | tree type = TREE_TYPE (TREE_TYPE (winner)); | |
1043 | if (TREE_CODE (type) == REFERENCE_TYPE) | |
1044 | type = TREE_TYPE (type); | |
1045 | return build_user_type_conversion (type, expr, LOOKUP_NORMAL); | |
471086d6 | 1046 | } |
1e66592c | 1047 | |
985e9ee0 | 1048 | return NULL_TREE; |
471086d6 | 1049 | } |
bc3887cf | 1050 | |
96624a9e | 1051 | /* Implements integral promotion (4.1) and float->double promotion. */ |
1052 | ||
bc3887cf | 1053 | tree |
1054 | type_promotes_to (type) | |
1055 | tree type; | |
1056 | { | |
3e04bd45 | 1057 | int type_quals; |
ce28ee2e | 1058 | |
1059 | if (type == error_mark_node) | |
1060 | return error_mark_node; | |
1061 | ||
3e04bd45 | 1062 | type_quals = CP_TYPE_QUALS (type); |
bc3887cf | 1063 | type = TYPE_MAIN_VARIANT (type); |
bb0726a1 | 1064 | |
1065 | /* bool always promotes to int (not unsigned), even if it's the same | |
1066 | size. */ | |
028ea8b4 | 1067 | if (type == boolean_type_node) |
bb0726a1 | 1068 | type = integer_type_node; |
1069 | ||
1070 | /* Normally convert enums to int, but convert wide enums to something | |
1071 | wider. */ | |
1072 | else if (TREE_CODE (type) == ENUMERAL_TYPE | |
1073 | || type == wchar_type_node) | |
6c9497b1 | 1074 | { |
1075 | int precision = MAX (TYPE_PRECISION (type), | |
1076 | TYPE_PRECISION (integer_type_node)); | |
1077 | tree totype = type_for_size (precision, 0); | |
1078 | if (TREE_UNSIGNED (type) | |
1079 | && ! int_fits_type_p (TYPE_MAX_VALUE (type), totype)) | |
1080 | type = type_for_size (precision, 1); | |
1081 | else | |
1082 | type = totype; | |
1083 | } | |
bc3887cf | 1084 | else if (C_PROMOTING_INTEGER_TYPE_P (type)) |
1085 | { | |
d0acef9e | 1086 | /* Retain unsignedness if really not getting bigger. */ |
bc3887cf | 1087 | if (TREE_UNSIGNED (type) |
d0acef9e | 1088 | && TYPE_PRECISION (type) == TYPE_PRECISION (integer_type_node)) |
bc3887cf | 1089 | type = unsigned_type_node; |
1090 | else | |
1091 | type = integer_type_node; | |
1092 | } | |
1093 | else if (type == float_type_node) | |
1094 | type = double_type_node; | |
1095 | ||
3e04bd45 | 1096 | return cp_build_qualified_type (type, type_quals); |
bc3887cf | 1097 | } |
668ae905 | 1098 | |
668ae905 | 1099 | /* The routines below this point are carefully written to conform to |
1100 | the standard. They use the same terminology, and follow the rules | |
1101 | closely. Although they are used only in pt.c at the moment, they | |
1102 | should presumably be used everywhere in the future. */ | |
1103 | ||
1146f179 | 1104 | /* Attempt to perform qualification conversions on EXPR to convert it |
1105 | to TYPE. Return the resulting expression, or error_mark_node if | |
1106 | the conversion was impossible. */ | |
1107 | ||
668ae905 | 1108 | tree |
1109 | perform_qualification_conversions (type, expr) | |
1110 | tree type; | |
1111 | tree expr; | |
1112 | { | |
213d2076 | 1113 | if (TREE_CODE (type) == POINTER_TYPE |
1114 | && TREE_CODE (TREE_TYPE (expr)) == POINTER_TYPE | |
1115 | && comp_ptr_ttypes (TREE_TYPE (type), TREE_TYPE (TREE_TYPE (expr)))) | |
1146f179 | 1116 | return build1 (NOP_EXPR, type, expr); |
1117 | else | |
1118 | return error_mark_node; | |
668ae905 | 1119 | } |