]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/cp/cvt.c
(update_flow_info): When add REG_DEAD notes for dest of
[thirdparty/gcc.git] / gcc / cp / cvt.c
CommitLineData
471086d6 1/* Language-level data type conversion for GNU C++.
50a72189 2 Copyright (C) 1987, 88, 92, 93, 94, 95, 1996 Free Software Foundation, Inc.
471086d6 3 Hacked by Michael Tiemann (tiemann@cygnus.com)
4
5This file is part of GNU CC.
6
7GNU CC is free software; you can redistribute it and/or modify
8it under the terms of the GNU General Public License as published by
9the Free Software Foundation; either version 2, or (at your option)
10any later version.
11
12GNU CC is distributed in the hope that it will be useful,
13but WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15GNU General Public License for more details.
16
17You should have received a copy of the GNU General Public License
18along with GNU CC; see the file COPYING. If not, write to
c58d4270 19the Free Software Foundation, 59 Temple Place - Suite 330,
20Boston, 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"
29#include "tree.h"
30#include "flags.h"
31#include "cp-tree.h"
32#include "class.h"
33#include "convert.h"
34
35#undef NULL
36#define NULL (char *)0
37
96624a9e 38tree build_user_type_conversion ();
39
471086d6 40/* Change of width--truncation and extension of integers or reals--
41 is represented with NOP_EXPR. Proper functioning of many things
42 assumes that no other conversions can be NOP_EXPRs.
43
44 Conversion between integer and pointer is represented with CONVERT_EXPR.
45 Converting integer to real uses FLOAT_EXPR
46 and real to integer uses FIX_TRUNC_EXPR.
47
48 Here is a list of all the functions that assume that widening and
49 narrowing is always done with a NOP_EXPR:
50 In convert.c, convert_to_integer.
51 In c-typeck.c, build_binary_op_nodefault (boolean ops),
52 and truthvalue_conversion.
53 In expr.c: expand_expr, for operands of a MULT_EXPR.
54 In fold-const.c: fold.
55 In tree.c: get_narrower and get_unwidened.
56
57 C++: in multiple-inheritance, converting between pointers may involve
58 adjusting them by a delta stored within the class definition. */
59\f
60/* Subroutines of `convert'. */
61
62/* Build a thunk. What it is, is an entry point that when called will
63 adjust the this pointer (the first argument) by offset, and then
64 goto the real address of the function given by REAL_ADDR that we
65 would like called. What we return is the address of the thunk. */
96624a9e 66
471086d6 67static tree
68build_thunk (offset, real_addr)
69 tree offset, real_addr;
70{
71 if (TREE_CODE (real_addr) != ADDR_EXPR
72 || TREE_CODE (TREE_OPERAND (real_addr, 0)) != FUNCTION_DECL)
73 {
74 sorry ("MI pointer to member conversion too complex");
75 return error_mark_node;
76 }
77 sorry ("MI pointer to member conversion too complex");
78 return error_mark_node;
79}
80
81/* Convert a `pointer to member' (POINTER_TYPE to METHOD_TYPE) into
82 another `pointer to method'. This may involved the creation of
83 a thunk to handle the this offset calculation. */
96624a9e 84
471086d6 85static tree
86convert_fn_ptr (type, expr)
87 tree type, expr;
88{
e1dcbf32 89#if 0 /* We don't use thunks for pmfs. */
74002e1d 90 if (flag_vtable_thunks)
471086d6 91 {
74002e1d 92 tree intype = TREE_TYPE (expr);
93 tree binfo = get_binfo (TYPE_METHOD_BASETYPE (TREE_TYPE (intype)),
94 TYPE_METHOD_BASETYPE (TREE_TYPE (type)), 1);
95 if (binfo == error_mark_node)
96 {
97 error (" in pointer to member conversion");
98 return error_mark_node;
99 }
100 if (binfo == NULL_TREE)
101 {
96624a9e 102 /* ARM 4.8 restriction. */
74002e1d 103 error ("invalid pointer to member conversion");
104 return error_mark_node;
105 }
106
107 if (BINFO_OFFSET_ZEROP (binfo))
108 return build1 (NOP_EXPR, type, expr);
109 return build1 (NOP_EXPR, type, build_thunk (BINFO_OFFSET (binfo), expr));
471086d6 110 }
74002e1d 111 else
e1dcbf32 112#endif
74002e1d 113 return build_ptrmemfunc (type, expr, 1);
471086d6 114}
115
116/* if converting pointer to pointer
117 if dealing with classes, check for derived->base or vice versa
118 else if dealing with method pointers, delegate
119 else convert blindly
120 else if converting class, pass off to build_type_conversion
121 else try C-style pointer conversion */
96624a9e 122
471086d6 123static tree
124cp_convert_to_pointer (type, expr)
125 tree type, expr;
126{
127 register tree intype = TREE_TYPE (expr);
74002e1d 128 register enum tree_code form;
129
96624a9e 130 if (IS_AGGR_TYPE (intype))
131 {
132 tree rval;
133
134 intype = complete_type (intype);
135 if (TYPE_SIZE (intype) == NULL_TREE)
136 {
137 cp_error ("can't convert from incomplete type `%T' to `%T'",
138 intype, type);
139 return error_mark_node;
140 }
141
142 rval = build_type_conversion (CONVERT_EXPR, type, expr, 1);
143 if (rval)
144 {
145 if (rval == error_mark_node)
146 cp_error ("conversion of `%E' from `%T' to `%T' is ambiguous",
147 expr, intype, type);
148 return rval;
149 }
150 }
151
74002e1d 152 if (TYPE_PTRMEMFUNC_P (type))
153 type = TYPE_PTRMEMFUNC_FN_TYPE (type);
154 if (TYPE_PTRMEMFUNC_P (intype))
155 intype = TYPE_PTRMEMFUNC_FN_TYPE (intype);
156
38281c46 157 /* Handle anachronistic conversions from (::*)() to void* or (*)(). */
158 if (TREE_CODE (type) == POINTER_TYPE
159 && (TREE_CODE (TREE_TYPE (type)) == FUNCTION_TYPE
160 || TREE_TYPE (type) == void_type_node))
161 {
162 /* Allow an implicit this pointer for pointer to member
163 functions. */
164 if (TREE_CODE (intype) == POINTER_TYPE
165 && TREE_CODE (TREE_TYPE (intype)) == METHOD_TYPE)
166 {
167 tree decl, basebinfo;
168 tree fntype = TREE_TYPE (intype);
169 tree t = TYPE_METHOD_BASETYPE (fntype);
170
171 if (current_class_type == 0
172 || get_base_distance (t, current_class_type, 0, &basebinfo)
173 == -1)
174 {
175 decl = build1 (NOP_EXPR, t, error_mark_node);
176 }
177 else if (current_class_ptr == 0)
178 decl = build1 (NOP_EXPR, t, error_mark_node);
179 else
180 decl = current_class_ref;
181
182 expr = build (OFFSET_REF, fntype, decl, expr);
183 }
184
185 if (TREE_CODE (expr) == OFFSET_REF
186 && TREE_CODE (TREE_TYPE (expr)) == METHOD_TYPE)
187 expr = resolve_offset_ref (expr);
188 if (TREE_CODE (TREE_TYPE (expr)) == METHOD_TYPE)
189 expr = build_addr_func (expr);
190 if (TREE_CODE (TREE_TYPE (expr)) == POINTER_TYPE)
191 {
192 if (TREE_CODE (TREE_TYPE (TREE_TYPE (expr))) == METHOD_TYPE)
193 if (pedantic || warn_pmf2ptr)
194 cp_pedwarn ("converting from `%T' to `%T'", TREE_TYPE (expr),
195 type);
196 return build1 (NOP_EXPR, type, expr);
197 }
198 intype = TREE_TYPE (expr);
199 }
200
74002e1d 201 form = TREE_CODE (intype);
202
1a3f833b 203 if (form == POINTER_TYPE || form == REFERENCE_TYPE)
471086d6 204 {
205 intype = TYPE_MAIN_VARIANT (intype);
206
207 if (TYPE_MAIN_VARIANT (type) != intype
208 && TREE_CODE (TREE_TYPE (type)) == RECORD_TYPE
bccffb3a 209 && IS_AGGR_TYPE (TREE_TYPE (type))
210 && IS_AGGR_TYPE (TREE_TYPE (intype))
471086d6 211 && TREE_CODE (TREE_TYPE (intype)) == RECORD_TYPE)
212 {
213 enum tree_code code = PLUS_EXPR;
214 tree binfo = get_binfo (TREE_TYPE (type), TREE_TYPE (intype), 1);
215 if (binfo == error_mark_node)
216 return error_mark_node;
217 if (binfo == NULL_TREE)
218 {
219 binfo = get_binfo (TREE_TYPE (intype), TREE_TYPE (type), 1);
220 if (binfo == error_mark_node)
221 return error_mark_node;
222 code = MINUS_EXPR;
223 }
224 if (binfo)
225 {
226 if (TYPE_USES_VIRTUAL_BASECLASSES (TREE_TYPE (type))
227 || TYPE_USES_VIRTUAL_BASECLASSES (TREE_TYPE (intype))
228 || ! BINFO_OFFSET_ZEROP (binfo))
229 {
230 /* Need to get the path we took. */
231 tree path;
232
233 if (code == PLUS_EXPR)
234 get_base_distance (TREE_TYPE (type), TREE_TYPE (intype), 0, &path);
235 else
236 get_base_distance (TREE_TYPE (intype), TREE_TYPE (type), 0, &path);
237 return build_vbase_path (code, type, expr, path, 0);
238 }
239 }
240 }
74002e1d 241 if (TREE_CODE (TREE_TYPE (intype)) == METHOD_TYPE
471086d6 242 && TREE_CODE (type) == POINTER_TYPE
74002e1d 243 && TREE_CODE (TREE_TYPE (type)) == METHOD_TYPE)
471086d6 244 return convert_fn_ptr (type, expr);
245
bea7d742 246 if (TREE_CODE (TREE_TYPE (type)) == OFFSET_TYPE
247 && TREE_CODE (TREE_TYPE (intype)) == OFFSET_TYPE)
248 {
249 tree b1 = TYPE_OFFSET_BASETYPE (TREE_TYPE (type));
250 tree b2 = TYPE_OFFSET_BASETYPE (TREE_TYPE (intype));
251 tree binfo = get_binfo (b1, b2, 1);
252 if (binfo == NULL_TREE)
253 binfo = get_binfo (b2, b1, 1);
254 if (binfo == error_mark_node)
255 return error_mark_node;
256 }
257
ce28ee2e 258 if (TREE_CODE (TREE_TYPE (intype)) == METHOD_TYPE
259 || (TREE_CODE (type) == POINTER_TYPE
260 && TREE_CODE (TREE_TYPE (type)) == METHOD_TYPE))
261 {
262 cp_error ("cannot convert `%E' from type `%T' to type `%T'",
263 expr, intype, type);
264 return error_mark_node;
265 }
266
471086d6 267 return build1 (NOP_EXPR, type, expr);
268 }
269
270 my_friendly_assert (form != OFFSET_TYPE, 186);
271
272 if (TYPE_LANG_SPECIFIC (intype)
273 && (IS_SIGNATURE_POINTER (intype) || IS_SIGNATURE_REFERENCE (intype)))
274 return convert_to_pointer (type, build_optr_ref (expr));
275
471086d6 276 if (integer_zerop (expr))
277 {
471086d6 278 expr = build_int_2 (0, 0);
279 TREE_TYPE (expr) = type;
280 return expr;
281 }
282
bb0726a1 283 if (INTEGRAL_CODE_P (form))
471086d6 284 {
285 if (type_precision (intype) == POINTER_SIZE)
286 return build1 (CONVERT_EXPR, type, expr);
287 expr = convert (type_for_size (POINTER_SIZE, 0), expr);
288 /* Modes may be different but sizes should be the same. */
289 if (GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (expr)))
290 != GET_MODE_SIZE (TYPE_MODE (type)))
291 /* There is supposed to be some integral type
292 that is the same width as a pointer. */
293 abort ();
294 return convert_to_pointer (type, expr);
295 }
296
297 cp_error ("cannot convert `%E' from type `%T' to type `%T'",
298 expr, intype, type);
299 return error_mark_node;
300}
301
302/* Like convert, except permit conversions to take place which
303 are not normally allowed due to access restrictions
304 (such as conversion from sub-type to private super-type). */
96624a9e 305
471086d6 306static tree
307convert_to_pointer_force (type, expr)
308 tree type, expr;
309{
310 register tree intype = TREE_TYPE (expr);
311 register enum tree_code form = TREE_CODE (intype);
312
313 if (integer_zerop (expr))
314 {
471086d6 315 expr = build_int_2 (0, 0);
316 TREE_TYPE (expr) = type;
317 return expr;
318 }
319
320 /* Convert signature pointer/reference to `void *' first. */
321 if (form == RECORD_TYPE
322 && (IS_SIGNATURE_POINTER (intype) || IS_SIGNATURE_REFERENCE (intype)))
323 {
324 expr = build_optr_ref (expr);
325 intype = TREE_TYPE (expr);
326 form = TREE_CODE (intype);
327 }
328
329 if (form == POINTER_TYPE)
330 {
331 intype = TYPE_MAIN_VARIANT (intype);
332
333 if (TYPE_MAIN_VARIANT (type) != intype
334 && TREE_CODE (TREE_TYPE (type)) == RECORD_TYPE
bccffb3a 335 && IS_AGGR_TYPE (TREE_TYPE (type))
336 && IS_AGGR_TYPE (TREE_TYPE (intype))
471086d6 337 && TREE_CODE (TREE_TYPE (intype)) == RECORD_TYPE)
338 {
339 enum tree_code code = PLUS_EXPR;
340 tree path;
341 int distance = get_base_distance (TREE_TYPE (type),
342 TREE_TYPE (intype), 0, &path);
343 if (distance == -2)
344 {
345 ambig:
346 cp_error ("type `%T' is ambiguous baseclass of `%s'", TREE_TYPE (type),
347 TYPE_NAME_STRING (TREE_TYPE (intype)));
348 return error_mark_node;
349 }
350 if (distance == -1)
351 {
352 distance = get_base_distance (TREE_TYPE (intype),
353 TREE_TYPE (type), 0, &path);
354 if (distance == -2)
355 goto ambig;
356 if (distance < 0)
357 /* Doesn't need any special help from us. */
358 return build1 (NOP_EXPR, type, expr);
359
360 code = MINUS_EXPR;
361 }
362 return build_vbase_path (code, type, expr, path, 0);
363 }
471086d6 364 }
365
366 return cp_convert_to_pointer (type, expr);
367}
368
369/* We are passing something to a function which requires a reference.
370 The type we are interested in is in TYPE. The initial
371 value we have to begin with is in ARG.
372
373 FLAGS controls how we manage access checking.
38281c46 374 DIRECT_BIND in FLAGS controls how any temporarys are generated.
471086d6 375 CHECKCONST controls if we report error messages on const subversion. */
96624a9e 376
471086d6 377static tree
378build_up_reference (type, arg, flags, checkconst)
379 tree type, arg;
380 int flags, checkconst;
381{
382 tree rval, targ;
383 int literal_flag = 0;
0543e7a9 384 tree argtype = TREE_TYPE (arg);
471086d6 385 tree target_type = TREE_TYPE (type);
386 tree binfo = NULL_TREE;
387
388 my_friendly_assert (TREE_CODE (type) == REFERENCE_TYPE, 187);
0543e7a9 389 if ((flags & LOOKUP_PROTECT)
471086d6 390 && TYPE_MAIN_VARIANT (argtype) != TYPE_MAIN_VARIANT (target_type)
391 && IS_AGGR_TYPE (argtype)
392 && IS_AGGR_TYPE (target_type))
393 {
394 binfo = get_binfo (target_type, argtype, 1);
0543e7a9 395 if (binfo == error_mark_node)
471086d6 396 return error_mark_node;
397 if (binfo == NULL_TREE)
398 return error_not_base_type (target_type, argtype);
471086d6 399 }
400
96624a9e 401 /* Pass along const and volatile down into the type. */
471086d6 402 if (TYPE_READONLY (type) || TYPE_VOLATILE (type))
c38086bd 403 target_type = cp_build_type_variant (target_type, TYPE_READONLY (type),
c07b1ad1 404 TYPE_VOLATILE (type));
471086d6 405 targ = arg;
406 if (TREE_CODE (targ) == SAVE_EXPR)
407 targ = TREE_OPERAND (targ, 0);
a74e8896 408 while (TREE_CODE (targ) == NOP_EXPR
409 && (TYPE_MAIN_VARIANT (argtype)
410 == TYPE_MAIN_VARIANT (TREE_TYPE (TREE_OPERAND (targ, 0)))))
411 targ = TREE_OPERAND (targ, 0);
471086d6 412
413 switch (TREE_CODE (targ))
414 {
415 case INDIRECT_REF:
416 /* This is a call to a constructor which did not know what it was
417 initializing until now: it needs to initialize a temporary. */
418 if (TREE_HAS_CONSTRUCTOR (targ))
419 {
e857e9c7 420 tree temp = build_cplus_new (argtype, TREE_OPERAND (targ, 0));
471086d6 421 TREE_HAS_CONSTRUCTOR (targ) = 0;
422 return build_up_reference (type, temp, flags, 1);
423 }
424 /* Let &* cancel out to simplify resulting code.
425 Also, throw away intervening NOP_EXPRs. */
426 arg = TREE_OPERAND (targ, 0);
427 if (TREE_CODE (arg) == NOP_EXPR || TREE_CODE (arg) == NON_LVALUE_EXPR
428 || (TREE_CODE (arg) == CONVERT_EXPR && TREE_REFERENCE_EXPR (arg)))
429 arg = TREE_OPERAND (arg, 0);
430
431 /* in doing a &*, we have to get rid of the const'ness on the pointer
432 value. Haven't thought about volatile here. Pointers come to mind
433 here. */
434 if (TREE_READONLY (arg))
435 {
436 arg = copy_node (arg);
437 TREE_READONLY (arg) = 0;
438 }
439
440 rval = build1 (CONVERT_EXPR, type, arg);
441 TREE_REFERENCE_EXPR (rval) = 1;
442
443 /* propagate the const flag on something like:
444
445 class Base {
446 public:
447 int foo;
448 };
449
450 class Derived : public Base {
451 public:
452 int bar;
453 };
454
455 void func(Base&);
456
457 void func2(const Derived& d) {
458 func(d);
459 }
460
461 on the d parameter. The below could have been avoided, if the flags
462 were down in the tree, not sure why they are not. (mrs) */
463 /* The below code may have to be propagated to other parts of this
464 switch. */
465 if (TREE_READONLY (targ) && !TREE_READONLY (arg)
466 && (TREE_CODE (arg) == PARM_DECL || TREE_CODE (arg) == VAR_DECL)
467 && TREE_CODE (TREE_TYPE (arg)) == REFERENCE_TYPE
468 && (TYPE_READONLY (target_type) && checkconst))
469 {
470 arg = copy_node (arg);
471 TREE_READONLY (arg) = TREE_READONLY (targ);
472 }
473 literal_flag = TREE_CONSTANT (arg);
474
ad91f3ed 475 goto done;
471086d6 476
477 /* Get this out of a register if we happened to be in one by accident.
478 Also, build up references to non-lvalues it we must. */
479 /* For &x[y], return (&) x+y */
480 case ARRAY_REF:
481 if (mark_addressable (TREE_OPERAND (targ, 0)) == 0)
482 return error_mark_node;
483 rval = build_binary_op (PLUS_EXPR, TREE_OPERAND (targ, 0),
484 TREE_OPERAND (targ, 1), 1);
485 TREE_TYPE (rval) = type;
486 if (TREE_CONSTANT (TREE_OPERAND (targ, 1))
487 && staticp (TREE_OPERAND (targ, 0)))
488 TREE_CONSTANT (rval) = 1;
489 goto done;
490
491 case SCOPE_REF:
492 /* Could be a reference to a static member. */
493 {
494 tree field = TREE_OPERAND (targ, 1);
495 if (TREE_STATIC (field))
496 {
497 rval = build1 (ADDR_EXPR, type, field);
498 literal_flag = 1;
499 goto done;
500 }
501 }
502
503 /* We should have farmed out member pointers above. */
504 my_friendly_abort (188);
505
506 case COMPONENT_REF:
507 rval = build_component_addr (targ, build_pointer_type (argtype),
508 "attempt to make a reference to bit-field structure member `%s'");
509 TREE_TYPE (rval) = type;
510 literal_flag = staticp (TREE_OPERAND (targ, 0));
511
ad91f3ed 512 goto done;
471086d6 513
514 /* Anything not already handled and not a true memory reference
515 needs to have a reference built up. Do so silently for
516 things like integers and return values from function,
517 but complain if we need a reference to something declared
518 as `register'. */
519
471086d6 520 case PARM_DECL:
38281c46 521 /* 'this' is not an lvalue. */
522 if (targ == current_class_ptr && ! flag_this_is_variable)
523 break;
524
525 case RESULT_DECL:
471086d6 526 case VAR_DECL:
527 case CONST_DECL:
38281c46 528 if (staticp (targ))
471086d6 529 literal_flag = 1;
530
38281c46 531 /* Fall through. */
532 case TARGET_EXPR:
533 mark_addressable (targ);
471086d6 534 break;
535
536 case COMPOUND_EXPR:
537 {
538 tree real_reference = build_up_reference (type, TREE_OPERAND (targ, 1),
ec10e4ad 539 flags, checkconst);
471086d6 540 rval = build (COMPOUND_EXPR, type, TREE_OPERAND (targ, 0), real_reference);
541 TREE_CONSTANT (rval) = staticp (TREE_OPERAND (targ, 1));
542 return rval;
543 }
544
c38086bd 545 case PREINCREMENT_EXPR:
546 case PREDECREMENT_EXPR:
471086d6 547 case MODIFY_EXPR:
548 case INIT_EXPR:
549 {
550 tree real_reference = build_up_reference (type, TREE_OPERAND (targ, 0),
ec10e4ad 551 flags, checkconst);
471086d6 552 rval = build (COMPOUND_EXPR, type, arg, real_reference);
553 TREE_CONSTANT (rval) = staticp (TREE_OPERAND (targ, 0));
554 return rval;
555 }
556
557 case COND_EXPR:
558 return build (COND_EXPR, type,
559 TREE_OPERAND (targ, 0),
560 build_up_reference (type, TREE_OPERAND (targ, 1),
ec10e4ad 561 flags, checkconst),
471086d6 562 build_up_reference (type, TREE_OPERAND (targ, 2),
ec10e4ad 563 flags, checkconst));
471086d6 564
96624a9e 565 /* Undo the folding... */
bcf789d7 566 case MIN_EXPR:
567 case MAX_EXPR:
568 return build (COND_EXPR, type,
569 build (TREE_CODE (targ) == MIN_EXPR ? LT_EXPR : GT_EXPR,
570 boolean_type_node, TREE_OPERAND (targ, 0),
571 TREE_OPERAND (targ, 1)),
572 build_up_reference (type, TREE_OPERAND (targ, 0),
ec10e4ad 573 flags, checkconst),
bcf789d7 574 build_up_reference (type, TREE_OPERAND (targ, 1),
ec10e4ad 575 flags, checkconst));
bcf789d7 576
471086d6 577 case BIND_EXPR:
578 arg = TREE_OPERAND (targ, 1);
579 if (arg == NULL_TREE)
580 {
581 compiler_error ("({ ... }) expression not expanded when needed for reference");
582 return error_mark_node;
583 }
584 rval = build1 (ADDR_EXPR, type, arg);
585 TREE_REFERENCE_EXPR (rval) = 1;
586 return rval;
587
588 default:
589 break;
590 }
591
38281c46 592 if ((flags&DIRECT_BIND)
593 && ! real_lvalue_p (targ))
471086d6 594 {
38281c46 595 if (toplevel_bindings_p ())
63b1d638 596 {
38281c46 597 arg = get_temp_name (argtype, 1);
598 literal_flag = 1;
63b1d638 599 }
471086d6 600 else
601 {
38281c46 602 arg = pushdecl (build_decl (VAR_DECL, NULL_TREE, argtype));
603 DECL_ARTIFICIAL (arg) = 1;
1ad432f2 604 }
38281c46 605 DECL_INITIAL (arg) = targ;
606 cp_finish_decl (arg, targ, NULL_TREE, 0, LOOKUP_ONLYCONVERTING);
1ad432f2 607 }
38281c46 608 else if (TREE_ADDRESSABLE (targ) == 0 && !(flags&DIRECT_BIND))
1ad432f2 609 {
38281c46 610 tree slot = build_decl (VAR_DECL, NULL_TREE, argtype);
611 arg = build (TARGET_EXPR, argtype, slot, arg, NULL_TREE, NULL_TREE);
471086d6 612 }
1ad432f2 613
614 rval = build1 (ADDR_EXPR, type, arg);
471086d6 615
471086d6 616 done:
c07b1ad1 617 if (TYPE_USES_COMPLEX_INHERITANCE (argtype)
618 || TYPE_USES_COMPLEX_INHERITANCE (target_type))
471086d6 619 {
bc3887cf 620 TREE_TYPE (rval) = build_pointer_type (argtype);
ac9386a0 621 if (flags & LOOKUP_PROTECT)
622 rval = convert_pointer_to (target_type, rval);
623 else
624 rval
625 = convert_to_pointer_force (build_pointer_type (target_type), rval);
471086d6 626 TREE_TYPE (rval) = type;
1da635b9 627 if (TREE_CODE (rval) == PLUS_EXPR || TREE_CODE (rval) == MINUS_EXPR)
628 TREE_TYPE (TREE_OPERAND (rval, 0))
629 = TREE_TYPE (TREE_OPERAND (rval, 1)) = type;
471086d6 630 }
631 TREE_CONSTANT (rval) = literal_flag;
632 return rval;
633}
634
635/* For C++: Only need to do one-level references, but cannot
636 get tripped up on signed/unsigned differences.
637
d81e00a4 638 DECL is either NULL_TREE or the _DECL node for a reference that is being
639 initialized. It can be error_mark_node if we don't know the _DECL but
640 we know it's an initialization. */
471086d6 641
471086d6 642tree
d81e00a4 643convert_to_reference (reftype, expr, convtype, flags, decl)
471086d6 644 tree reftype, expr;
d81e00a4 645 int convtype, flags;
646 tree decl;
471086d6 647{
648 register tree type = TYPE_MAIN_VARIANT (TREE_TYPE (reftype));
649 register tree intype = TREE_TYPE (expr);
471086d6 650 tree rval = NULL_TREE;
1a3f833b 651 tree rval_as_conversion = NULL_TREE;
652 int i;
653
654 if (TREE_CODE (intype) == REFERENCE_TYPE)
655 my_friendly_abort (364);
471086d6 656
471086d6 657 intype = TYPE_MAIN_VARIANT (intype);
658
1a3f833b 659 i = comp_target_types (type, intype, 0);
660
661 if (i <= 0 && (convtype & CONV_IMPLICIT) && IS_AGGR_TYPE (intype)
662 && ! (flags & LOOKUP_NO_CONVERSION))
663 {
664 /* Look for a user-defined conversion to lvalue that we can use. */
665
ec10e4ad 666 if (flag_ansi_overloading)
667 rval_as_conversion
668 = build_type_conversion (CONVERT_EXPR, reftype, expr, 1);
669 else
670 rval_as_conversion = build_type_conversion (CONVERT_EXPR, type, expr, 1);
1a3f833b 671
672 if (rval_as_conversion && rval_as_conversion != error_mark_node
673 && real_lvalue_p (rval_as_conversion))
674 {
675 expr = rval_as_conversion;
676 rval_as_conversion = NULL_TREE;
677 intype = type;
678 i = 1;
679 }
680 }
681
682 if (((convtype & CONV_STATIC) && i == -1)
683 || ((convtype & CONV_IMPLICIT) && i == 1))
471086d6 684 {
471086d6 685 if (flags & LOOKUP_COMPLAIN)
686 {
bc3887cf 687 tree ttl = TREE_TYPE (reftype);
688 tree ttr;
689
1a3f833b 690 {
691 int r = TREE_READONLY (expr);
692 int v = TREE_THIS_VOLATILE (expr);
693 ttr = cp_build_type_variant (TREE_TYPE (expr), r, v);
694 }
471086d6 695
f9670f72 696 if (! real_lvalue_p (expr) && ! TYPE_READONLY (ttl))
bc3887cf 697 {
d81e00a4 698 if (decl)
699 /* Ensure semantics of [dcl.init.ref] */
f9670f72 700 cp_pedwarn ("initialization of non-const reference `%#T' from rvalue `%T'",
d81e00a4 701 reftype, intype);
702 else
f9670f72 703 cp_pedwarn ("conversion to non-const `%T' from rvalue `%T'",
d81e00a4 704 reftype, intype);
bc3887cf 705 }
d81e00a4 706 else if (! (convtype & CONV_CONST))
471086d6 707 {
d81e00a4 708 if (! TYPE_READONLY (ttl) && TYPE_READONLY (ttr))
709 cp_pedwarn ("conversion from `%T' to `%T' discards const",
ad91f3ed 710 ttr, reftype);
d81e00a4 711 else if (! TYPE_VOLATILE (ttl) && TYPE_VOLATILE (ttr))
712 cp_pedwarn ("conversion from `%T' to `%T' discards volatile",
ad91f3ed 713 ttr, reftype);
471086d6 714 }
0543e7a9 715 }
716
d81e00a4 717 return build_up_reference (reftype, expr, flags,
718 ! (convtype & CONV_CONST));
471086d6 719 }
c07b1ad1 720 else if ((convtype & CONV_REINTERPRET) && lvalue_p (expr))
0543e7a9 721 {
722 /* When casting an lvalue to a reference type, just convert into
723 a pointer to the new type and deference it. This is allowed
e581f478 724 by San Diego WP section 5.2.9 paragraph 12, though perhaps it
0543e7a9 725 should be done directly (jason). (int &)ri ---> *(int*)&ri */
e581f478 726
3748625f 727 /* B* bp; A& ar = (A&)bp; is valid, but it's probably not what they
e581f478 728 meant. */
1a3f833b 729 if (TREE_CODE (intype) == POINTER_TYPE
d81e00a4 730 && (comptypes (TREE_TYPE (intype), type, -1)))
e581f478 731 cp_warning ("casting `%T' to `%T' does not dereference pointer",
732 intype, reftype);
733
0543e7a9 734 rval = build_unary_op (ADDR_EXPR, expr, 0);
735 if (rval != error_mark_node)
a74e8896 736 rval = convert_force (build_pointer_type (TREE_TYPE (reftype)), rval, 0);
0543e7a9 737 if (rval != error_mark_node)
b0722fac 738 rval = build1 (NOP_EXPR, reftype, rval);
0543e7a9 739 }
d81e00a4 740 else if (decl)
471086d6 741 {
471086d6 742 tree rval_as_ctor = NULL_TREE;
743
1a3f833b 744 if (rval_as_conversion)
471086d6 745 {
1a3f833b 746 if (rval_as_conversion == error_mark_node)
747 {
748 cp_error ("conversion from `%T' to `%T' is ambiguous",
749 intype, reftype);
750 return error_mark_node;
751 }
752 rval_as_conversion = build_up_reference (reftype, rval_as_conversion,
753 flags, 1);
471086d6 754 }
755
756 /* Definitely need to go through a constructor here. */
757 if (TYPE_HAS_CONSTRUCTOR (type)
e581f478 758 && ! CLASSTYPE_ABSTRACT_VIRTUALS (type)
471086d6 759 && (rval = build_method_call
d2a15a12 760 (NULL_TREE, ctor_identifier,
471086d6 761 build_tree_list (NULL_TREE, expr), TYPE_BINFO (type),
c25194fd 762 LOOKUP_NO_CONVERSION|LOOKUP_SPECULATIVELY
763 | LOOKUP_ONLYCONVERTING)))
471086d6 764 {
765 tree init;
766
d0622bdf 767 if (toplevel_bindings_p ())
471086d6 768 {
769 extern tree static_aggregates;
d0622bdf 770 tree t = get_temp_name (type, toplevel_bindings_p ());
d2a15a12 771 init = build_method_call (t, ctor_identifier,
471086d6 772 build_tree_list (NULL_TREE, expr),
d81e00a4 773 TYPE_BINFO (type),
c25194fd 774 LOOKUP_NORMAL|LOOKUP_NO_CONVERSION
775 | LOOKUP_ONLYCONVERTING);
471086d6 776
777 if (init == error_mark_node)
778 return error_mark_node;
779
d81e00a4 780 make_decl_rtl (t, NULL_PTR, 1);
781 static_aggregates = perm_tree_cons (expr, t, static_aggregates);
782 rval = build_unary_op (ADDR_EXPR, t, 0);
471086d6 783 }
784 else
785 {
d2a15a12 786 init = build_method_call (NULL_TREE, ctor_identifier,
471086d6 787 build_tree_list (NULL_TREE, expr),
d81e00a4 788 TYPE_BINFO (type),
c25194fd 789 LOOKUP_NORMAL|LOOKUP_NO_CONVERSION
790 |LOOKUP_ONLYCONVERTING);
471086d6 791
792 if (init == error_mark_node)
793 return error_mark_node;
794
e857e9c7 795 rval = build_cplus_new (type, init);
471086d6 796 rval = build_up_reference (reftype, rval, flags, 1);
797 }
798 rval_as_ctor = rval;
799 }
800
801 if (rval_as_ctor && rval_as_conversion)
802 {
803 cp_error ("ambiguous conversion from `%T' to `%T'; both user-defined conversion and constructor apply",
804 intype, reftype);
805 return error_mark_node;
806 }
807 else if (rval_as_ctor)
808 rval = rval_as_ctor;
809 else if (rval_as_conversion)
810 rval = rval_as_conversion;
811 else if (! IS_AGGR_TYPE (type) && ! IS_AGGR_TYPE (intype))
812 {
813 rval = convert (type, expr);
814 if (rval == error_mark_node)
815 return error_mark_node;
816
817 rval = build_up_reference (reftype, rval, flags, 1);
818 }
819
820 if (rval && ! TYPE_READONLY (TREE_TYPE (reftype)))
d81e00a4 821 cp_pedwarn ("initializing non-const `%T' with `%T' will use a temporary",
822 reftype, intype);
471086d6 823 }
824
825 if (rval)
826 {
96624a9e 827 /* If we found a way to convert earlier, then use it. */
471086d6 828 return rval;
829 }
830
1a3f833b 831 my_friendly_assert (TREE_CODE (intype) != OFFSET_TYPE, 189);
471086d6 832
b248d3f7 833 if (flags & LOOKUP_COMPLAIN)
834 cp_error ("cannot convert type `%T' to type `%T'", intype, reftype);
835
471086d6 836 if (flags & LOOKUP_SPECULATIVELY)
837 return NULL_TREE;
838
839 return error_mark_node;
840}
841
842/* We are using a reference VAL for its value. Bash that reference all the
96624a9e 843 way down to its lowest form. */
844
471086d6 845tree
846convert_from_reference (val)
847 tree val;
848{
849 tree type = TREE_TYPE (val);
850
851 if (TREE_CODE (type) == OFFSET_TYPE)
852 type = TREE_TYPE (type);
8c5c575d 853 if (TREE_CODE (type) == REFERENCE_TYPE)
854 return build_indirect_ref (val, NULL_PTR);
471086d6 855 return val;
856}
857\f
858/* See if there is a constructor of type TYPE which will convert
859 EXPR. The reference manual seems to suggest (8.5.6) that we need
860 not worry about finding constructors for base classes, then converting
861 to the derived class.
862
863 MSGP is a pointer to a message that would be an appropriate error
864 string. If MSGP is NULL, then we are not interested in reporting
865 errors. */
96624a9e 866
471086d6 867tree
868convert_to_aggr (type, expr, msgp, protect)
869 tree type, expr;
870 char **msgp;
871 int protect;
872{
873 tree basetype = type;
874 tree name = TYPE_IDENTIFIER (basetype);
875 tree function, fndecl, fntype, parmtypes, parmlist, result;
e857e9c7 876#if 0
877 /* See code below that used this. */
878 tree method_name;
879#endif
880 tree access;
471086d6 881 int can_be_private, can_be_protected;
882
883 if (! TYPE_HAS_CONSTRUCTOR (basetype))
884 {
885 if (msgp)
886 *msgp = "type `%s' does not have a constructor";
887 return error_mark_node;
888 }
889
652e1a2d 890 access = access_public_node;
471086d6 891 can_be_private = 0;
892 can_be_protected = IDENTIFIER_CLASS_VALUE (name) || name == current_class_name;
893
894 parmlist = build_tree_list (NULL_TREE, expr);
895 parmtypes = tree_cons (NULL_TREE, TREE_TYPE (expr), void_list_node);
896
897 if (TYPE_USES_VIRTUAL_BASECLASSES (basetype))
898 {
899 parmtypes = tree_cons (NULL_TREE, integer_type_node, parmtypes);
900 parmlist = tree_cons (NULL_TREE, integer_one_node, parmlist);
901 }
902
903 /* The type of the first argument will be filled in inside the loop. */
904 parmlist = tree_cons (NULL_TREE, integer_zero_node, parmlist);
ce28ee2e 905 parmtypes = tree_cons (NULL_TREE, build_pointer_type (basetype), parmtypes);
471086d6 906
471086d6 907 /* No exact conversion was found. See if an approximate
908 one will do. */
909 fndecl = TREE_VEC_ELT (CLASSTYPE_METHOD_VEC (basetype), 0);
471086d6 910
911 {
912 int saw_private = 0;
913 int saw_protected = 0;
914 struct candidate *candidates =
915 (struct candidate *) alloca ((decl_list_length (fndecl)+1) * sizeof (struct candidate));
916 struct candidate *cp = candidates;
917
918 while (fndecl)
919 {
920 function = fndecl;
921 cp->h_len = 2;
bb0726a1 922 cp->harshness = (struct harshness_code *)
923 alloca (3 * sizeof (struct harshness_code));
471086d6 924
925 compute_conversion_costs (fndecl, parmlist, cp, 2);
bb0726a1 926 if ((cp->h.code & EVIL_CODE) == 0)
471086d6 927 {
928 cp->u.field = fndecl;
929 if (protect)
930 {
931 if (TREE_PRIVATE (fndecl))
652e1a2d 932 access = access_private_node;
471086d6 933 else if (TREE_PROTECTED (fndecl))
652e1a2d 934 access = access_protected_node;
471086d6 935 else
652e1a2d 936 access = access_public_node;
471086d6 937 }
938 else
652e1a2d 939 access = access_public_node;
471086d6 940
652e1a2d 941 if (access == access_private_node
471086d6 942 ? (basetype == current_class_type
943 || is_friend (basetype, cp->function)
944 || purpose_member (basetype, DECL_ACCESS (fndecl)))
652e1a2d 945 : access == access_protected_node
471086d6 946 ? (can_be_protected
947 || purpose_member (basetype, DECL_ACCESS (fndecl)))
948 : 1)
949 {
bb0726a1 950 if (cp->h.code <= TRIVIAL_CODE)
471086d6 951 goto found_and_ok;
952 cp++;
953 }
954 else
955 {
652e1a2d 956 if (access == access_private_node)
471086d6 957 saw_private = 1;
958 else
959 saw_protected = 1;
960 }
961 }
962 fndecl = DECL_CHAIN (fndecl);
963 }
964 if (cp - candidates)
965 {
966 /* Rank from worst to best. Then cp will point to best one.
967 Private fields have their bits flipped. For unsigned
968 numbers, this should make them look very large.
969 If the best alternate has a (signed) negative value,
970 then all we ever saw were private members. */
971 if (cp - candidates > 1)
972 qsort (candidates, /* char *base */
973 cp - candidates, /* int nel */
974 sizeof (struct candidate), /* int width */
975 rank_for_overload); /* int (*compar)() */
976
977 --cp;
bb0726a1 978 if (cp->h.code & EVIL_CODE)
471086d6 979 {
980 if (msgp)
981 *msgp = "ambiguous type conversion possible for `%s'";
982 return error_mark_node;
983 }
984
985 function = cp->function;
986 fndecl = cp->u.field;
987 goto found_and_ok;
988 }
989 else if (msgp)
990 {
991 if (saw_private)
992 if (saw_protected)
993 *msgp = "only private and protected conversions apply";
994 else
995 *msgp = "only private conversions apply";
996 else if (saw_protected)
997 *msgp = "only protected conversions apply";
0543e7a9 998 else
999 *msgp = "no appropriate conversion to type `%s'";
471086d6 1000 }
1001 return error_mark_node;
1002 }
1003 /* NOTREACHED */
1004
471086d6 1005 found:
652e1a2d 1006 if (access == access_private_node)
471086d6 1007 if (! can_be_private)
1008 {
1009 if (msgp)
1010 *msgp = TREE_PRIVATE (fndecl)
1011 ? "conversion to type `%s' is private"
1012 : "conversion to type `%s' is from private base class";
1013 return error_mark_node;
1014 }
652e1a2d 1015 if (access == access_protected_node)
471086d6 1016 if (! can_be_protected)
1017 {
1018 if (msgp)
1019 *msgp = TREE_PRIVATE (fndecl)
1020 ? "conversion to type `%s' is protected"
1021 : "conversion to type `%s' is from protected base class";
1022 return error_mark_node;
1023 }
1024 function = fndecl;
1025 found_and_ok:
1026
1027 /* It will convert, but we don't do anything about it yet. */
1028 if (msgp == 0)
1029 return NULL_TREE;
1030
1031 fntype = TREE_TYPE (function);
e1dcbf32 1032
1033 parmlist = convert_arguments (NULL_TREE, TYPE_ARG_TYPES (fntype),
1034 parmlist, NULL_TREE, LOOKUP_NORMAL);
1035
1036 result = build_call (function, TREE_TYPE (fntype), parmlist);
471086d6 1037 return result;
1038}
1039
1040/* Call this when we know (for any reason) that expr is not, in fact,
1041 zero. This routine is like convert_pointer_to, but it pays
1042 attention to which specific instance of what type we want to
1043 convert to. This routine should eventually become
1044 convert_to_pointer after all references to convert_to_pointer
1045 are removed. */
96624a9e 1046
471086d6 1047tree
1048convert_pointer_to_real (binfo, expr)
1049 tree binfo, expr;
1050{
1051 register tree intype = TREE_TYPE (expr);
1052 tree ptr_type;
1053 tree type, rval;
1054
1055 if (TREE_CODE (binfo) == TREE_VEC)
1056 type = BINFO_TYPE (binfo);
1057 else if (IS_AGGR_TYPE (binfo))
1058 {
1059 type = binfo;
1060 }
1061 else
1062 {
1063 type = binfo;
1064 binfo = NULL_TREE;
1065 }
1066
d2a15a12 1067 ptr_type = cp_build_type_variant (type, TYPE_READONLY (TREE_TYPE (intype)),
1068 TYPE_VOLATILE (TREE_TYPE (intype)));
1069 ptr_type = build_pointer_type (ptr_type);
471086d6 1070 if (ptr_type == TYPE_MAIN_VARIANT (intype))
1071 return expr;
1072
1073 if (intype == error_mark_node)
1074 return error_mark_node;
1075
1076 my_friendly_assert (!integer_zerop (expr), 191);
1077
1078 if (TREE_CODE (type) == RECORD_TYPE
1079 && TREE_CODE (TREE_TYPE (intype)) == RECORD_TYPE
1080 && type != TYPE_MAIN_VARIANT (TREE_TYPE (intype)))
1081 {
1082 tree path;
1083 int distance
1084 = get_base_distance (binfo, TYPE_MAIN_VARIANT (TREE_TYPE (intype)),
1085 0, &path);
1086
1087 /* This function shouldn't be called with unqualified arguments
1088 but if it is, give them an error message that they can read. */
1089 if (distance < 0)
1090 {
b0722fac 1091 cp_error ("cannot convert a pointer of type `%T' to a pointer of type `%T'",
1092 TREE_TYPE (intype), type);
471086d6 1093
1094 if (distance == -2)
1095 cp_error ("because `%T' is an ambiguous base class", type);
1096 return error_mark_node;
1097 }
1098
1099 return build_vbase_path (PLUS_EXPR, ptr_type, expr, path, 1);
1100 }
1101 rval = build1 (NOP_EXPR, ptr_type,
1102 TREE_CODE (expr) == NOP_EXPR ? TREE_OPERAND (expr, 0) : expr);
1103 TREE_CONSTANT (rval) = TREE_CONSTANT (expr);
1104 return rval;
1105}
1106
1107/* Call this when we know (for any reason) that expr is
1108 not, in fact, zero. This routine gets a type out of the first
1109 argument and uses it to search for the type to convert to. If there
1110 is more than one instance of that type in the expr, the conversion is
1111 ambiguous. This routine should eventually go away, and all
1112 callers should use convert_to_pointer_real. */
96624a9e 1113
471086d6 1114tree
1115convert_pointer_to (binfo, expr)
1116 tree binfo, expr;
1117{
1118 tree type;
1119
1120 if (TREE_CODE (binfo) == TREE_VEC)
1121 type = BINFO_TYPE (binfo);
1122 else if (IS_AGGR_TYPE (binfo))
1123 type = binfo;
1124 else
1125 type = binfo;
1126 return convert_pointer_to_real (type, expr);
1127}
471086d6 1128\f
b248d3f7 1129/* Conversion...
1130
1131 FLAGS indicates how we should behave. */
1132
471086d6 1133tree
d81e00a4 1134cp_convert (type, expr, convtype, flags)
471086d6 1135 tree type, expr;
d81e00a4 1136 int convtype, flags;
471086d6 1137{
1138 register tree e = expr;
1139 register enum tree_code code = TREE_CODE (type);
1140
a74e8896 1141 if (TREE_CODE (e) == ERROR_MARK
1142 || TREE_CODE (TREE_TYPE (e)) == ERROR_MARK)
471086d6 1143 return error_mark_node;
d81e00a4 1144
1a3f833b 1145 if (IS_AGGR_TYPE (type) && (convtype & CONV_FORCE_TEMP))
1146 /* We need a new temporary; don't take this shortcut. */;
1147 else if (TYPE_MAIN_VARIANT (type) == TYPE_MAIN_VARIANT (TREE_TYPE (e)))
1148 /* Trivial conversion: cv-qualifiers do not matter on rvalues. */
617abf06 1149 return fold (build1 (NOP_EXPR, type, e));
d81e00a4 1150
1151 if (code == VOID_TYPE && (convtype & CONV_STATIC))
1152 return build1 (CONVERT_EXPR, type, e);
1153
471086d6 1154#if 0
1155 /* This is incorrect. A truncation can't be stripped this way.
1156 Extensions will be stripped by the use of get_unwidened. */
617abf06 1157 if (TREE_CODE (e) == NOP_EXPR)
1158 return convert (type, TREE_OPERAND (e, 0));
471086d6 1159#endif
1160
1161 /* Just convert to the type of the member. */
1162 if (code == OFFSET_TYPE)
1163 {
1164 type = TREE_TYPE (type);
1165 code = TREE_CODE (type);
1166 }
1167
1a3f833b 1168#if 0
471086d6 1169 if (code == REFERENCE_TYPE)
d81e00a4 1170 return fold (convert_to_reference (type, e, convtype, flags, NULL_TREE));
471086d6 1171 else if (TREE_CODE (TREE_TYPE (e)) == REFERENCE_TYPE)
1172 e = convert_from_reference (e);
1a3f833b 1173#endif
471086d6 1174
f3ba5c6a 1175 if (TREE_CODE (e) == OFFSET_REF)
1176 e = resolve_offset_ref (e);
1177
ddb9bca7 1178 if (TREE_READONLY_DECL_P (e))
1179 e = decl_constant_value (e);
1180
bb0726a1 1181 if (INTEGRAL_CODE_P (code))
471086d6 1182 {
617abf06 1183 tree intype = TREE_TYPE (e);
96624a9e 1184 /* enum = enum, enum = int, enum = float are all errors. */
471086d6 1185 if (flag_int_enum_equivalence == 0
1186 && TREE_CODE (type) == ENUMERAL_TYPE
a74e8896 1187 && ARITHMETIC_TYPE_P (intype)
1188 && ! (convtype & CONV_STATIC))
471086d6 1189 {
1190 cp_pedwarn ("conversion from `%#T' to `%#T'", intype, type);
1191
1192 if (flag_pedantic_errors)
1193 return error_mark_node;
1194 }
f3ba5c6a 1195 if (IS_AGGR_TYPE (intype))
471086d6 1196 {
1197 tree rval;
617abf06 1198 rval = build_type_conversion (CONVERT_EXPR, type, e, 1);
6495357a 1199 if (rval)
1200 return rval;
b248d3f7 1201 if (flags & LOOKUP_COMPLAIN)
1202 cp_error ("`%#T' used where a `%T' was expected", intype, type);
1203 if (flags & LOOKUP_SPECULATIVELY)
1204 return NULL_TREE;
471086d6 1205 return error_mark_node;
1206 }
bb0726a1 1207 if (code == BOOLEAN_TYPE)
e4ce2dc4 1208 {
1209 /* Common Ada/Pascal programmer's mistake. We always warn
1210 about this since it is so bad. */
1211 if (TREE_CODE (expr) == FUNCTION_DECL)
1212 cp_warning ("the address of `%D', will always be `true'", expr);
1213 return truthvalue_conversion (e);
1214 }
471086d6 1215 return fold (convert_to_integer (type, e));
1216 }
74002e1d 1217 if (code == POINTER_TYPE || code == REFERENCE_TYPE
1218 || TYPE_PTRMEMFUNC_P (type))
471086d6 1219 return fold (cp_convert_to_pointer (type, e));
1220 if (code == REAL_TYPE)
1221 {
1222 if (IS_AGGR_TYPE (TREE_TYPE (e)))
1223 {
1224 tree rval;
1225 rval = build_type_conversion (CONVERT_EXPR, type, e, 1);
1226 if (rval)
1227 return rval;
1228 else
b248d3f7 1229 if (flags & LOOKUP_COMPLAIN)
1230 cp_error ("`%#T' used where a floating point value was expected",
1231 TREE_TYPE (e));
471086d6 1232 }
1233 return fold (convert_to_real (type, e));
1234 }
1235
1236 /* New C++ semantics: since assignment is now based on
1237 memberwise copying, if the rhs type is derived from the
1238 lhs type, then we may still do a conversion. */
1239 if (IS_AGGR_TYPE_CODE (code))
1240 {
1241 tree dtype = TREE_TYPE (e);
c25194fd 1242 tree ctor = NULL_TREE;
1243 tree conversion = NULL_TREE;
471086d6 1244
471086d6 1245 dtype = TYPE_MAIN_VARIANT (dtype);
1246
1247 /* Conversion of object pointers or signature pointers/references
1248 to signature pointers/references. */
1249
1250 if (TYPE_LANG_SPECIFIC (type)
1251 && (IS_SIGNATURE_POINTER (type) || IS_SIGNATURE_REFERENCE (type)))
1252 {
1253 tree constructor = build_signature_pointer_constructor (type, expr);
1254 tree sig_ty = SIGNATURE_TYPE (type);
1255 tree sig_ptr;
1256
1257 if (constructor == error_mark_node)
1258 return error_mark_node;
1259
1260 sig_ptr = get_temp_name (type, 1);
1261 DECL_INITIAL (sig_ptr) = constructor;
1262 CLEAR_SIGNATURE (sig_ty);
6f553a8d 1263 cp_finish_decl (sig_ptr, constructor, NULL_TREE, 0, 0);
471086d6 1264 SET_SIGNATURE (sig_ty);
1265 TREE_READONLY (sig_ptr) = 1;
1266
1267 return sig_ptr;
1268 }
1269
1270 /* Conversion between aggregate types. New C++ semantics allow
1271 objects of derived type to be cast to objects of base type.
1272 Old semantics only allowed this between pointers.
1273
1274 There may be some ambiguity between using a constructor
1275 vs. using a type conversion operator when both apply. */
1276
c25194fd 1277 if (IS_AGGR_TYPE (dtype) && ! DERIVED_FROM_P (type, dtype)
1278 && TYPE_HAS_CONVERSION (dtype))
1279 conversion = build_type_conversion (CONVERT_EXPR, type, e, 1);
471086d6 1280
c25194fd 1281 if (conversion == error_mark_node)
1282 {
b248d3f7 1283 if (flags & LOOKUP_COMPLAIN)
1284 error ("ambiguous pointer conversion");
c25194fd 1285 return conversion;
1286 }
471086d6 1287
ec10e4ad 1288 if (TYPE_HAS_CONSTRUCTOR (complete_type (type))
1289 && (! flag_ansi_overloading || ! conversion))
d2a15a12 1290 ctor = build_method_call (NULL_TREE, ctor_identifier,
c25194fd 1291 build_tree_list (NULL_TREE, e),
1292 TYPE_BINFO (type),
b248d3f7 1293 (flags & LOOKUP_NORMAL) | LOOKUP_SPECULATIVELY
d2a15a12 1294 | (convtype & CONV_NONCONVERTING ? 0 : LOOKUP_ONLYCONVERTING)
1295 | (flags & LOOKUP_NO_CONVERSION)
c25194fd 1296 | (conversion ? LOOKUP_NO_CONVERSION : 0));
471086d6 1297
c25194fd 1298 if (ctor == error_mark_node)
1299 {
b248d3f7 1300 if (flags & LOOKUP_COMPLAIN)
1301 cp_error ("in conversion to type `%T'", type);
1302 if (flags & LOOKUP_SPECULATIVELY)
1303 return NULL_TREE;
471086d6 1304 return error_mark_node;
1305 }
c25194fd 1306
1307 if (conversion && ctor)
471086d6 1308 {
b248d3f7 1309 if (flags & LOOKUP_COMPLAIN)
1310 error ("both constructor and type conversion operator apply");
1311 if (flags & LOOKUP_SPECULATIVELY)
1312 return NULL_TREE;
c25194fd 1313 return error_mark_node;
1314 }
596c0ae6 1315 else if (conversion)
1316 return conversion;
c25194fd 1317 else if (ctor)
1318 {
e857e9c7 1319 ctor = build_cplus_new (type, ctor);
c25194fd 1320 return ctor;
471086d6 1321 }
1322 }
1323
617abf06 1324 /* If TYPE or TREE_TYPE (E) is not on the permanent_obstack,
471086d6 1325 then the it won't be hashed and hence compare as not equal,
1326 even when it is. */
1327 if (code == ARRAY_TYPE
617abf06 1328 && TREE_TYPE (TREE_TYPE (e)) == TREE_TYPE (type)
1329 && index_type_equal (TYPE_DOMAIN (TREE_TYPE (e)), TYPE_DOMAIN (type)))
1330 return e;
471086d6 1331
b248d3f7 1332 if (flags & LOOKUP_COMPLAIN)
1333 cp_error ("conversion from `%T' to non-scalar type `%T' requested",
1334 TREE_TYPE (expr), type);
1335 if (flags & LOOKUP_SPECULATIVELY)
1336 return NULL_TREE;
471086d6 1337 return error_mark_node;
1338}
1339
d81e00a4 1340/* Create an expression whose value is that of EXPR,
1341 converted to type TYPE. The TREE_TYPE of the value
1342 is always TYPE. This function implements all reasonable
1343 conversions; callers should filter out those that are
1344 not permitted by the language being compiled. */
1345
1346tree
1347convert (type, expr)
1348 tree type, expr;
1349{
b248d3f7 1350 return cp_convert (type, expr, CONV_OLD_CONVERT, LOOKUP_NORMAL);
d81e00a4 1351}
1352
471086d6 1353/* Like convert, except permit conversions to take place which
1354 are not normally allowed due to access restrictions
1355 (such as conversion from sub-type to private super-type). */
96624a9e 1356
471086d6 1357tree
a74e8896 1358convert_force (type, expr, convtype)
471086d6 1359 tree type;
1360 tree expr;
a74e8896 1361 int convtype;
471086d6 1362{
1363 register tree e = expr;
1364 register enum tree_code code = TREE_CODE (type);
1365
1366 if (code == REFERENCE_TYPE)
d81e00a4 1367 return fold (convert_to_reference (type, e, CONV_C_CAST, LOOKUP_COMPLAIN,
1368 NULL_TREE));
471086d6 1369 else if (TREE_CODE (TREE_TYPE (e)) == REFERENCE_TYPE)
1370 e = convert_from_reference (e);
1371
1372 if (code == POINTER_TYPE)
1373 return fold (convert_to_pointer_force (type, e));
1374
ac9386a0 1375 /* From typeck.c convert_for_assignment */
471086d6 1376 if (((TREE_CODE (TREE_TYPE (e)) == POINTER_TYPE && TREE_CODE (e) == ADDR_EXPR
1377 && TREE_CODE (TREE_TYPE (e)) == POINTER_TYPE
1378 && TREE_CODE (TREE_TYPE (TREE_TYPE (e))) == METHOD_TYPE)
ac9386a0 1379 || integer_zerop (e)
1380 || TYPE_PTRMEMFUNC_P (TREE_TYPE (e)))
471086d6 1381 && TYPE_PTRMEMFUNC_P (type))
1382 {
96624a9e 1383 /* compatible pointer to member functions. */
ac9386a0 1384 return build_ptrmemfunc (TYPE_PTRMEMFUNC_FN_TYPE (type), e, 1);
471086d6 1385 }
a74e8896 1386
b248d3f7 1387 return cp_convert (type, e, CONV_C_CAST|convtype, LOOKUP_NORMAL);
471086d6 1388}
1389
1390/* Subroutine of build_type_conversion. */
96624a9e 1391
471086d6 1392static tree
1393build_type_conversion_1 (xtype, basetype, expr, typename, for_sure)
1394 tree xtype, basetype;
1395 tree expr;
1396 tree typename;
1397 int for_sure;
1398{
471086d6 1399 tree rval;
1400 int flags;
1401
1402 if (for_sure == 0)
c25194fd 1403 flags = LOOKUP_PROTECT|LOOKUP_ONLYCONVERTING;
471086d6 1404 else
c25194fd 1405 flags = LOOKUP_NORMAL|LOOKUP_ONLYCONVERTING;
471086d6 1406
c07b1ad1 1407 rval = build_method_call (expr, typename, NULL_TREE, NULL_TREE, flags);
471086d6 1408 if (rval == error_mark_node)
1409 {
1410 if (for_sure == 0)
1411 return NULL_TREE;
1412 return error_mark_node;
1413 }
1a3f833b 1414
1415 if (IS_AGGR_TYPE (TREE_TYPE (rval)))
1416 return rval;
471086d6 1417
1418 if (warn_cast_qual
1419 && TREE_TYPE (xtype)
1420 && (TREE_READONLY (TREE_TYPE (TREE_TYPE (rval)))
1421 > TREE_READONLY (TREE_TYPE (xtype))))
1422 warning ("user-defined conversion casting away `const'");
d81e00a4 1423 return convert (xtype, rval);
471086d6 1424}
1425
1426/* Convert an aggregate EXPR to type XTYPE. If a conversion
1427 exists, return the attempted conversion. This may
1428 return ERROR_MARK_NODE if the conversion is not
1429 allowed (references private members, etc).
1430 If no conversion exists, NULL_TREE is returned.
1431
1432 If (FOR_SURE & 1) is non-zero, then we allow this type conversion
1433 to take place immediately. Otherwise, we build a SAVE_EXPR
ce28ee2e 1434 which can be evaluated if the results are ever needed.
1435
1436 Changes to this functions should be mirrored in user_harshness.
1437
1438 FIXME: Ambiguity checking is wrong. Should choose one by the implicit
1439 object parameter, or by the second standard conversion sequence if
1440 that doesn't do it. This will probably wait for an overloading rewrite.
1441 (jason 8/9/95) */
471086d6 1442
471086d6 1443tree
1444build_type_conversion (code, xtype, expr, for_sure)
1445 enum tree_code code;
1446 tree xtype, expr;
1447 int for_sure;
1448{
1449 /* C++: check to see if we can convert this aggregate type
bcf789d7 1450 into the required type. */
1451 tree basetype;
1452 tree conv;
1453 tree winner = NULL_TREE;
471086d6 1454
ec10e4ad 1455 if (flag_ansi_overloading)
1456 return build_user_type_conversion
1457 (xtype, expr, for_sure ? LOOKUP_NORMAL : 0);
1458
471086d6 1459 if (expr == error_mark_node)
1460 return error_mark_node;
1461
1462 basetype = TREE_TYPE (expr);
1463 if (TREE_CODE (basetype) == REFERENCE_TYPE)
1464 basetype = TREE_TYPE (basetype);
1465
1466 basetype = TYPE_MAIN_VARIANT (basetype);
1467 if (! TYPE_LANG_SPECIFIC (basetype) || ! TYPE_HAS_CONVERSION (basetype))
1468 return NULL_TREE;
1469
bcf789d7 1470 /* Do we have an exact match? */
1471 {
1472 tree typename = build_typename_overload (xtype);
1473 if (lookup_fnfields (TYPE_BINFO (basetype), typename, 0))
1474 return build_type_conversion_1 (xtype, basetype, expr, typename,
1475 for_sure);
1476 }
471086d6 1477
bcf789d7 1478 /* Nope; try looking for others. */
1479 for (conv = lookup_conversions (basetype); conv; conv = TREE_CHAIN (conv))
471086d6 1480 {
22f1c933 1481 tree cand = TREE_VALUE (conv);
1482
1483 if (winner && winner == cand)
bcf789d7 1484 continue;
471086d6 1485
22f1c933 1486 if (can_convert (xtype, TREE_TYPE (TREE_TYPE (cand))))
471086d6 1487 {
bcf789d7 1488 if (winner)
471086d6 1489 {
dd2b9e17 1490 if (for_sure)
1491 {
1492 cp_error ("ambiguous conversion from `%T' to `%T'", basetype,
1493 xtype);
22f1c933 1494 cp_error (" candidate conversions include `%D' and `%D'",
1495 winner, cand);
dd2b9e17 1496 }
bcf789d7 1497 return NULL_TREE;
471086d6 1498 }
1499 else
22f1c933 1500 winner = cand;
471086d6 1501 }
1502 }
1503
bcf789d7 1504 if (winner)
1505 return build_type_conversion_1 (xtype, basetype, expr,
22f1c933 1506 DECL_NAME (winner), for_sure);
471086d6 1507
1508 return NULL_TREE;
1509}
1510
1e66592c 1511/* Convert the given EXPR to one of a group of types suitable for use in an
1512 expression. DESIRES is a combination of various WANT_* flags (q.v.)
1513 which indicates which types are suitable. If COMPLAIN is 1, complain
1514 about ambiguity; otherwise, the caller will deal with it. */
471086d6 1515
1e66592c 1516tree
1517build_expr_type_conversion (desires, expr, complain)
1518 int desires;
1519 tree expr;
1520 int complain;
471086d6 1521{
1e66592c 1522 tree basetype = TREE_TYPE (expr);
1523 tree conv;
1524 tree winner = NULL_TREE;
471086d6 1525
1e66592c 1526 if (TREE_CODE (basetype) == OFFSET_TYPE)
ce28ee2e 1527 expr = resolve_offset_ref (expr);
1528 expr = convert_from_reference (expr);
1529 basetype = TREE_TYPE (expr);
471086d6 1530
1e66592c 1531 if (! IS_AGGR_TYPE (basetype))
1532 switch (TREE_CODE (basetype))
1533 {
1534 case INTEGER_TYPE:
1535 if ((desires & WANT_NULL) && TREE_CODE (expr) == INTEGER_CST
1536 && integer_zerop (expr))
1537 return expr;
96624a9e 1538 /* else fall through... */
1e66592c 1539
1540 case BOOLEAN_TYPE:
1541 return (desires & WANT_INT) ? expr : NULL_TREE;
1542 case ENUMERAL_TYPE:
1543 return (desires & WANT_ENUM) ? expr : NULL_TREE;
1544 case REAL_TYPE:
1545 return (desires & WANT_FLOAT) ? expr : NULL_TREE;
1546 case POINTER_TYPE:
1547 return (desires & WANT_POINTER) ? expr : NULL_TREE;
1548
1549 case FUNCTION_TYPE:
1550 case ARRAY_TYPE:
1551 return (desires & WANT_POINTER) ? default_conversion (expr)
1552 : NULL_TREE;
1553 default:
1554 return NULL_TREE;
1555 }
471086d6 1556
1e66592c 1557 if (! TYPE_HAS_CONVERSION (basetype))
1558 return NULL_TREE;
1559
1560 for (conv = lookup_conversions (basetype); conv; conv = TREE_CHAIN (conv))
471086d6 1561 {
1e66592c 1562 int win = 0;
ce28ee2e 1563 tree candidate;
22f1c933 1564 tree cand = TREE_VALUE (conv);
1e66592c 1565
22f1c933 1566 if (winner && winner == cand)
1e66592c 1567 continue;
1568
22f1c933 1569 candidate = TREE_TYPE (TREE_TYPE (cand));
ce28ee2e 1570 if (TREE_CODE (candidate) == REFERENCE_TYPE)
1571 candidate = TREE_TYPE (candidate);
1572
1573 switch (TREE_CODE (candidate))
1e66592c 1574 {
1575 case BOOLEAN_TYPE:
1576 case INTEGER_TYPE:
1577 win = (desires & WANT_INT); break;
1578 case ENUMERAL_TYPE:
1579 win = (desires & WANT_ENUM); break;
1580 case REAL_TYPE:
1581 win = (desires & WANT_FLOAT); break;
1582 case POINTER_TYPE:
1583 win = (desires & WANT_POINTER); break;
1584 }
1585
1586 if (win)
1587 {
1588 if (winner)
1589 {
1590 if (complain)
1591 {
1592 cp_error ("ambiguous default type conversion from `%T'",
1593 basetype);
22f1c933 1594 cp_error (" candidate conversions include `%D' and `%D'",
1595 winner, cand);
1e66592c 1596 }
1597 return error_mark_node;
1598 }
1599 else
22f1c933 1600 winner = cand;
1e66592c 1601 }
471086d6 1602 }
1e66592c 1603
1604 if (winner)
3d4e092a 1605 {
22f1c933 1606 tree type = TREE_TYPE (TREE_TYPE (winner));
3d4e092a 1607 if (TREE_CODE (type) == REFERENCE_TYPE)
1608 type = TREE_TYPE (type);
1609 return build_type_conversion_1 (type, basetype, expr,
22f1c933 1610 DECL_NAME (winner), 1);
3d4e092a 1611 }
1e66592c 1612
1613 return NULL_TREE;
471086d6 1614}
1615
1e66592c 1616/* Must convert two aggregate types to non-aggregate type.
471086d6 1617 Attempts to find a non-ambiguous, "best" type conversion.
1618
1619 Return 1 on success, 0 on failure.
1620
471086d6 1621 @@ What are the real semantics of this supposed to be??? */
96624a9e 1622
471086d6 1623int
1e66592c 1624build_default_binary_type_conversion (code, arg1, arg2)
471086d6 1625 enum tree_code code;
1e66592c 1626 tree *arg1, *arg2;
471086d6 1627{
1e66592c 1628 switch (code)
471086d6 1629 {
1e66592c 1630 case MULT_EXPR:
1631 case TRUNC_DIV_EXPR:
1632 case CEIL_DIV_EXPR:
1633 case FLOOR_DIV_EXPR:
1634 case ROUND_DIV_EXPR:
1635 case EXACT_DIV_EXPR:
1636 *arg1 = build_expr_type_conversion (WANT_ARITH | WANT_ENUM, *arg1, 0);
1637 *arg2 = build_expr_type_conversion (WANT_ARITH | WANT_ENUM, *arg2, 0);
1638 break;
471086d6 1639
1e66592c 1640 case TRUNC_MOD_EXPR:
1641 case FLOOR_MOD_EXPR:
1642 case LSHIFT_EXPR:
1643 case RSHIFT_EXPR:
1644 case BIT_AND_EXPR:
1645 case BIT_XOR_EXPR:
1646 case BIT_IOR_EXPR:
1647 *arg1 = build_expr_type_conversion (WANT_INT | WANT_ENUM, *arg1, 0);
1648 *arg2 = build_expr_type_conversion (WANT_INT | WANT_ENUM, *arg2, 0);
1649 break;
1650
1651 case PLUS_EXPR:
1652 {
1653 tree a1, a2, p1, p2;
1654 int wins;
1655
1656 a1 = build_expr_type_conversion (WANT_ARITH | WANT_ENUM, *arg1, 0);
1657 a2 = build_expr_type_conversion (WANT_ARITH | WANT_ENUM, *arg2, 0);
1658 p1 = build_expr_type_conversion (WANT_POINTER, *arg1, 0);
1659 p2 = build_expr_type_conversion (WANT_POINTER, *arg2, 0);
1660
1661 wins = (a1 && a2) + (a1 && p2) + (p1 && a2);
1662
1663 if (wins > 1)
1664 error ("ambiguous default type conversion for `operator +'");
1665
1666 if (a1 && a2)
1667 *arg1 = a1, *arg2 = a2;
1668 else if (a1 && p2)
1669 *arg1 = a1, *arg2 = p2;
1670 else
1671 *arg1 = p1, *arg2 = a2;
1672 break;
1673 }
1674
1675 case MINUS_EXPR:
1676 {
1677 tree a1, a2, p1, p2;
1678 int wins;
1679
1680 a1 = build_expr_type_conversion (WANT_ARITH | WANT_ENUM, *arg1, 0);
1681 a2 = build_expr_type_conversion (WANT_ARITH | WANT_ENUM, *arg2, 0);
1682 p1 = build_expr_type_conversion (WANT_POINTER, *arg1, 0);
1683 p2 = build_expr_type_conversion (WANT_POINTER, *arg2, 0);
1684
1685 wins = (a1 && a2) + (p1 && p2) + (p1 && a2);
1686
1687 if (wins > 1)
1688 error ("ambiguous default type conversion for `operator -'");
1689
1690 if (a1 && a2)
1691 *arg1 = a1, *arg2 = a2;
1692 else if (p1 && p2)
1693 *arg1 = p1, *arg2 = p2;
1694 else
1695 *arg1 = p1, *arg2 = a2;
1696 break;
1697 }
1698
1699 case GT_EXPR:
1700 case LT_EXPR:
1701 case GE_EXPR:
1702 case LE_EXPR:
1703 case EQ_EXPR:
1704 case NE_EXPR:
1705 {
1706 tree a1, a2, p1, p2;
1707 int wins;
1708
1709 a1 = build_expr_type_conversion (WANT_ARITH | WANT_ENUM, *arg1, 0);
1710 a2 = build_expr_type_conversion (WANT_ARITH | WANT_ENUM, *arg2, 0);
1711 p1 = build_expr_type_conversion (WANT_POINTER | WANT_NULL, *arg1, 0);
1712 p2 = build_expr_type_conversion (WANT_POINTER | WANT_NULL, *arg2, 0);
1713
1714 wins = (a1 && a2) + (p1 && p2);
1715
1716 if (wins > 1)
1717 cp_error ("ambiguous default type conversion for `%O'", code);
1718
1719 if (a1 && a2)
1720 *arg1 = a1, *arg2 = a2;
1721 else
1722 *arg1 = p1, *arg2 = p2;
1723 break;
1724 }
1725
1726 case TRUTH_ANDIF_EXPR:
1727 case TRUTH_ORIF_EXPR:
1728 *arg1 = convert (boolean_type_node, *arg1);
1729 *arg2 = convert (boolean_type_node, *arg2);
1730 break;
1731
1732 default:
1733 *arg1 = NULL_TREE;
1734 *arg2 = NULL_TREE;
471086d6 1735 }
1e66592c 1736
1737 if (*arg1 == error_mark_node || *arg2 == error_mark_node)
1738 cp_error ("ambiguous default type conversion for `%O'", code);
1739
1740 if (*arg1 && *arg2)
1741 return 1;
1742
1743 return 0;
471086d6 1744}
bc3887cf 1745
96624a9e 1746/* Implements integral promotion (4.1) and float->double promotion. */
1747
bc3887cf 1748tree
1749type_promotes_to (type)
1750 tree type;
1751{
ce28ee2e 1752 int constp, volatilep;
1753
1754 if (type == error_mark_node)
1755 return error_mark_node;
1756
1757 constp = TYPE_READONLY (type);
1758 volatilep = TYPE_VOLATILE (type);
bc3887cf 1759 type = TYPE_MAIN_VARIANT (type);
bb0726a1 1760
1761 /* bool always promotes to int (not unsigned), even if it's the same
1762 size. */
028ea8b4 1763 if (type == boolean_type_node)
bb0726a1 1764 type = integer_type_node;
1765
1766 /* Normally convert enums to int, but convert wide enums to something
1767 wider. */
1768 else if (TREE_CODE (type) == ENUMERAL_TYPE
1769 || type == wchar_type_node)
6c9497b1 1770 {
1771 int precision = MAX (TYPE_PRECISION (type),
1772 TYPE_PRECISION (integer_type_node));
1773 tree totype = type_for_size (precision, 0);
1774 if (TREE_UNSIGNED (type)
1775 && ! int_fits_type_p (TYPE_MAX_VALUE (type), totype))
1776 type = type_for_size (precision, 1);
1777 else
1778 type = totype;
1779 }
bc3887cf 1780 else if (C_PROMOTING_INTEGER_TYPE_P (type))
1781 {
d0acef9e 1782 /* Retain unsignedness if really not getting bigger. */
bc3887cf 1783 if (TREE_UNSIGNED (type)
d0acef9e 1784 && TYPE_PRECISION (type) == TYPE_PRECISION (integer_type_node))
bc3887cf 1785 type = unsigned_type_node;
1786 else
1787 type = integer_type_node;
1788 }
1789 else if (type == float_type_node)
1790 type = double_type_node;
1791
c38086bd 1792 return cp_build_type_variant (type, constp, volatilep);
bc3887cf 1793}