|
|
1.1 root 1: /* Handle the hair of processing (but not expanding) inline functions.
2: Also manage function and variable name overloading.
1.1.1.2 ! root 3: Copyright (C) 1987, 89, 92, 93, 94, 1995 Free Software Foundation, Inc.
1.1 root 4: Contributed by Michael Tiemann ([email protected])
5:
6: This file is part of GNU CC.
7:
8: GNU CC is free software; you can redistribute it and/or modify
9: it under the terms of the GNU General Public License as published by
10: the Free Software Foundation; either version 2, or (at your option)
11: any later version.
12:
13: GNU CC is distributed in the hope that it will be useful,
14: but WITHOUT ANY WARRANTY; without even the implied warranty of
15: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16: GNU General Public License for more details.
17:
18: You should have received a copy of the GNU General Public License
19: along with GNU CC; see the file COPYING. If not, write to
1.1.1.2 ! root 20: the Free Software Foundation, 59 Temple Place - Suite 330,
! 21: Boston, MA 02111-1307, USA. */
1.1 root 22:
23:
24: #ifndef PARM_CAN_BE_ARRAY_TYPE
25: #define PARM_CAN_BE_ARRAY_TYPE 1
26: #endif
27:
28: /* Handle method declarations. */
29: #include <stdio.h>
30: #include "config.h"
31: #include "tree.h"
32: #include "cp-tree.h"
33: #include "class.h"
34: #include "obstack.h"
35: #include <ctype.h>
36: #include "rtl.h"
37: #include "expr.h"
38: #include "output.h"
39: #include "hard-reg-set.h"
40: #include "flags.h"
41:
42: /* TREE_LIST of the current inline functions that need to be
43: processed. */
44: struct pending_inline *pending_inlines;
45:
46: #define obstack_chunk_alloc xmalloc
47: #define obstack_chunk_free free
48:
49: /* Obstack where we build text strings for overloading, etc. */
50: static struct obstack scratch_obstack;
51: static char *scratch_firstobj;
52:
53: # define OB_INIT() (scratch_firstobj ? (obstack_free (&scratch_obstack, scratch_firstobj), 0) : 0)
54: # define OB_PUTC(C) (obstack_1grow (&scratch_obstack, (C)))
55: # define OB_PUTC2(C1,C2) \
56: (obstack_1grow (&scratch_obstack, (C1)), obstack_1grow (&scratch_obstack, (C2)))
57: # define OB_PUTS(S) (obstack_grow (&scratch_obstack, (S), sizeof (S) - 1))
58: # define OB_PUTID(ID) \
59: (obstack_grow (&scratch_obstack, IDENTIFIER_POINTER (ID), \
60: IDENTIFIER_LENGTH (ID)))
61: # define OB_PUTCP(S) (obstack_grow (&scratch_obstack, (S), strlen (S)))
62: # define OB_FINISH() (obstack_1grow (&scratch_obstack, '\0'))
1.1.1.2 ! root 63: # define OB_LAST() (obstack_next_free (&scratch_obstack)[-1])
1.1 root 64:
65: #ifdef NO_AUTO_OVERLOAD
66: int is_overloaded ();
67: #endif
68:
69: void
70: init_method ()
71: {
72: gcc_obstack_init (&scratch_obstack);
73: scratch_firstobj = (char *)obstack_alloc (&scratch_obstack, 0);
74: }
75:
76: /* This must be large enough to hold any printed integer or floating-point
77: value. */
78: static char digit_buffer[128];
79:
80: /* Move inline function definitions out of structure so that they
81: can be processed normally. CNAME is the name of the class
82: we are working from, METHOD_LIST is the list of method lists
83: of the structure. We delete friend methods here, after
84: saving away their inline function definitions (if any). */
85:
86: void
87: do_inline_function_hair (type, friend_list)
88: tree type, friend_list;
89: {
90: tree method = TYPE_METHODS (type);
91:
92: if (method && TREE_CODE (method) == TREE_VEC)
93: {
94: if (TREE_VEC_ELT (method, 0))
95: method = TREE_VEC_ELT (method, 0);
96: else
97: method = TREE_VEC_ELT (method, 1);
98: }
99:
100: while (method)
101: {
102: /* Do inline member functions. */
103: struct pending_inline *info = DECL_PENDING_INLINE_INFO (method);
104: if (info)
105: {
106: tree args;
107:
108: my_friendly_assert (info->fndecl == method, 238);
109: args = DECL_ARGUMENTS (method);
110: while (args)
111: {
112: DECL_CONTEXT (args) = method;
113: args = TREE_CHAIN (args);
114: }
115:
116: /* Allow this decl to be seen in global scope. Don't do this for
117: local class methods, though. */
118: if (! current_function_decl)
119: IDENTIFIER_GLOBAL_VALUE (DECL_ASSEMBLER_NAME (method)) = method;
120: }
121: method = TREE_CHAIN (method);
122: }
123: while (friend_list)
124: {
125: tree fndecl = TREE_VALUE (friend_list);
126: struct pending_inline *info = DECL_PENDING_INLINE_INFO (fndecl);
127: if (info)
128: {
129: tree args;
130:
131: my_friendly_assert (info->fndecl == fndecl, 239);
132: args = DECL_ARGUMENTS (fndecl);
133: while (args)
134: {
135: DECL_CONTEXT (args) = fndecl;
136: args = TREE_CHAIN (args);
137: }
138:
139: /* Allow this decl to be seen in global scope */
140: if (! current_function_decl)
141: IDENTIFIER_GLOBAL_VALUE (DECL_ASSEMBLER_NAME (fndecl)) = fndecl;
142: }
143:
144: friend_list = TREE_CHAIN (friend_list);
145: }
146: }
147:
148: /* Report an argument type mismatch between the best declared function
149: we could find and the current argument list that we have. */
150: void
151: report_type_mismatch (cp, parmtypes, name_kind)
152: struct candidate *cp;
153: tree parmtypes;
154: char *name_kind;
155: {
156: int i = cp->u.bad_arg;
157: tree ttf, tta;
158: char *tmp_firstobj;
159:
160: switch (i)
161: {
162: case -4:
163: my_friendly_assert (TREE_CODE (cp->function) == TEMPLATE_DECL, 240);
164: cp_error ("type unification failed for function template `%#D'",
165: cp->function);
166: return;
167:
168: case -2:
169: cp_error ("too few arguments for %s `%#D'", name_kind, cp->function);
170: return;
171: case -1:
172: cp_error ("too many arguments for %s `%#D'", name_kind, cp->function);
173: return;
174: case 0:
1.1.1.2 ! root 175: if (TREE_CODE (TREE_TYPE (cp->function)) != METHOD_TYPE)
! 176: break;
! 177: case -3:
! 178: /* Happens when the implicit object parameter is rejected. */
! 179: my_friendly_assert (! TYPE_READONLY (TREE_TYPE (TREE_VALUE (parmtypes))),
! 180: 241);
! 181: cp_error ("call to non-const %s `%#D' with const object",
! 182: name_kind, cp->function);
! 183: return;
1.1 root 184: }
185:
186: ttf = TYPE_ARG_TYPES (TREE_TYPE (cp->function));
187: tta = parmtypes;
188:
189: while (i-- > 0)
190: {
191: ttf = TREE_CHAIN (ttf);
192: tta = TREE_CHAIN (tta);
193: }
194:
195: OB_INIT ();
196: OB_PUTS ("bad argument ");
197: sprintf (digit_buffer, "%d", cp->u.bad_arg
198: - (TREE_CODE (TREE_TYPE (cp->function)) == METHOD_TYPE)
199: + 1);
200: OB_PUTCP (digit_buffer);
201:
202: OB_PUTS (" for function `");
203: OB_PUTCP (decl_as_string (cp->function, 1));
204: OB_PUTS ("' (type was ");
205:
206: /* Reset `i' so that type printing routines do the right thing. */
207: if (tta)
208: {
209: enum tree_code code = TREE_CODE (TREE_TYPE (TREE_VALUE (tta)));
210: if (code == ERROR_MARK)
211: OB_PUTS ("(failed type instantiation)");
212: else
213: {
214: i = (code == FUNCTION_TYPE || code == METHOD_TYPE);
215: OB_PUTCP (type_as_string (TREE_TYPE (TREE_VALUE (tta)), 1));
216: }
217: }
218: else OB_PUTS ("void");
219: OB_PUTC (')');
220: OB_FINISH ();
221:
222: tmp_firstobj = (char *)alloca (obstack_object_size (&scratch_obstack));
223: bcopy (obstack_base (&scratch_obstack), tmp_firstobj,
224: obstack_object_size (&scratch_obstack));
225: error (tmp_firstobj);
226: }
227:
228: /* Here is where overload code starts. */
229:
230: /* Array of types seen so far in top-level call to `build_overload_name'.
231: Allocated and deallocated by caller. */
232: static tree *typevec;
233:
234: /* Number of types interned by `build_overload_name' so far. */
235: static int maxtype;
236:
237: /* Number of occurrences of last type seen. */
238: static int nrepeats;
239:
240: /* Nonzero if we should not try folding parameter types. */
241: static int nofold;
242:
243: #define ALLOCATE_TYPEVEC(PARMTYPES) \
244: do { maxtype = 0, nrepeats = 0; \
245: typevec = (tree *)alloca (list_length (PARMTYPES) * sizeof (tree)); } while (0)
246:
247: #define DEALLOCATE_TYPEVEC(PARMTYPES) \
248: do { tree t = (PARMTYPES); \
249: while (t) { TREE_USED (TREE_VALUE (t)) = 0; t = TREE_CHAIN (t); } \
250: } while (0)
251:
252: /* Code to concatenate an asciified integer to a string. */
253: static
254: #ifdef __GNUC__
255: __inline
256: #endif
257: void
258: icat (i)
259: int i;
260: {
261: /* Handle this case first, to go really quickly. For many common values,
262: the result of i/10 below is 1. */
263: if (i == 1)
264: {
265: OB_PUTC ('1');
266: return;
267: }
268:
269: if (i < 0)
270: {
271: OB_PUTC ('m');
272: i = -i;
273: }
274: if (i < 10)
275: OB_PUTC ('0' + i);
276: else
277: {
278: icat (i / 10);
279: OB_PUTC ('0' + (i % 10));
280: }
281: }
282:
283: static
284: #ifdef __GNUC__
285: __inline
286: #endif
287: void
288: flush_repeats (type)
289: tree type;
290: {
291: int tindex = 0;
292:
293: while (typevec[tindex] != type)
294: tindex++;
295:
296: if (nrepeats > 1)
297: {
298: OB_PUTC ('N');
299: icat (nrepeats);
300: if (nrepeats > 9)
301: OB_PUTC ('_');
302: }
303: else
304: OB_PUTC ('T');
305: nrepeats = 0;
306: icat (tindex);
307: if (tindex > 9)
308: OB_PUTC ('_');
309: }
310:
1.1.1.2 ! root 311: static int numeric_output_need_bar;
1.1 root 312: static void build_overload_identifier ();
313:
314: static void
1.1.1.2 ! root 315: build_overload_nested_name (decl)
! 316: tree decl;
1.1 root 317: {
1.1.1.2 ! root 318: if (DECL_CONTEXT (decl))
1.1 root 319: {
1.1.1.2 ! root 320: tree context = DECL_CONTEXT (decl);
1.1 root 321: if (TREE_CODE_CLASS (TREE_CODE (context)) == 't')
1.1.1.2 ! root 322: context = TYPE_MAIN_DECL (context);
1.1 root 323: build_overload_nested_name (context);
324: }
1.1.1.2 ! root 325:
! 326: if (TREE_CODE (decl) == FUNCTION_DECL)
! 327: {
! 328: tree name = DECL_ASSEMBLER_NAME (decl);
! 329: char *label;
! 330: extern int var_labelno;
! 331:
! 332: ASM_FORMAT_PRIVATE_NAME (label, IDENTIFIER_POINTER (name), var_labelno);
! 333: var_labelno++;
! 334:
! 335: if (numeric_output_need_bar)
! 336: {
! 337: OB_PUTC ('_');
! 338: numeric_output_need_bar = 0;
! 339: }
! 340: icat (strlen (label));
! 341: OB_PUTCP (label);
! 342: }
! 343: else /* TYPE_DECL */
! 344: {
! 345: tree name = DECL_NAME (decl);
! 346: build_overload_identifier (name);
! 347: }
! 348: }
! 349:
! 350: /* Encoding for an INTEGER_CST value. */
! 351: static void
! 352: build_overload_int (value)
! 353: tree value;
! 354: {
! 355: my_friendly_assert (TREE_CODE (value) == INTEGER_CST, 243);
! 356: if (TYPE_PRECISION (value) == 2 * HOST_BITS_PER_WIDE_INT)
! 357: {
! 358: if (tree_int_cst_lt (value, integer_zero_node))
! 359: {
! 360: OB_PUTC ('m');
! 361: value = build_int_2 (~ TREE_INT_CST_LOW (value),
! 362: - TREE_INT_CST_HIGH (value));
! 363: }
! 364: if (TREE_INT_CST_HIGH (value)
! 365: != (TREE_INT_CST_LOW (value) >> (HOST_BITS_PER_WIDE_INT - 1)))
! 366: {
! 367: /* need to print a DImode value in decimal */
! 368: sorry ("conversion of long long as PT parameter");
! 369: }
! 370: /* else fall through to print in smaller mode */
! 371: }
! 372: /* Wordsize or smaller */
! 373: icat (TREE_INT_CST_LOW (value));
1.1 root 374: }
375:
376: static void
377: build_overload_value (type, value)
378: tree type, value;
379: {
380: while (TREE_CODE (value) == NON_LVALUE_EXPR
381: || TREE_CODE (value) == NOP_EXPR)
382: value = TREE_OPERAND (value, 0);
383: my_friendly_assert (TREE_CODE (type) == PARM_DECL, 242);
384: type = TREE_TYPE (type);
1.1.1.2 ! root 385:
! 386: if (numeric_output_need_bar)
! 387: {
! 388: OB_PUTC ('_');
! 389: numeric_output_need_bar = 0;
! 390: }
! 391:
! 392: if (TREE_CODE (type) == POINTER_TYPE
! 393: && TREE_CODE (TREE_TYPE (type)) == OFFSET_TYPE)
! 394: {
! 395: /* Handle a pointer to data member as a template instantiation
! 396: parameter, boy, what fun! */
! 397: type = integer_type_node;
! 398: if (TREE_CODE (value) != INTEGER_CST)
! 399: {
! 400: sorry ("unknown pointer to member constant");
! 401: return;
! 402: }
! 403: }
! 404:
! 405: if (TYPE_PTRMEMFUNC_P (type))
! 406: type = TYPE_PTRMEMFUNC_FN_TYPE (type);
! 407:
1.1 root 408: switch (TREE_CODE (type))
409: {
410: case INTEGER_TYPE:
411: case ENUMERAL_TYPE:
412: case BOOLEAN_TYPE:
413: {
1.1.1.2 ! root 414: build_overload_int (value);
! 415: numeric_output_need_bar = 1;
1.1 root 416: return;
417: }
418: #ifndef REAL_IS_NOT_DOUBLE
419: case REAL_TYPE:
420: {
421: REAL_VALUE_TYPE val;
422: char *bufp = digit_buffer;
423: extern char *index ();
424:
425: my_friendly_assert (TREE_CODE (value) == REAL_CST, 244);
426: val = TREE_REAL_CST (value);
427: if (val < 0)
428: {
429: val = -val;
430: *bufp++ = 'm';
431: }
432: sprintf (bufp, "%e", val);
433: bufp = (char *) index (bufp, 'e');
434: if (!bufp)
435: strcat (digit_buffer, "e0");
436: else
437: {
438: char *p;
439: bufp++;
440: if (*bufp == '-')
441: {
442: *bufp++ = 'm';
443: }
444: p = bufp;
445: if (*p == '+')
446: p++;
447: while (*p == '0')
448: p++;
449: if (*p == 0)
450: {
451: *bufp++ = '0';
452: *bufp = 0;
453: }
454: else if (p != bufp)
455: {
456: while (*p)
457: *bufp++ = *p++;
458: *bufp = 0;
459: }
460: }
461: OB_PUTCP (digit_buffer);
1.1.1.2 ! root 462: numeric_output_need_bar = 1;
1.1 root 463: return;
464: }
465: #endif
466: case POINTER_TYPE:
1.1.1.2 ! root 467: if (TREE_CODE (TREE_TYPE (type)) == METHOD_TYPE
! 468: && TREE_CODE (value) != ADDR_EXPR)
! 469: {
! 470: if (TREE_CODE (value) == CONSTRUCTOR)
! 471: {
! 472: /* This is dangerous code, crack built up pointer to members. */
! 473: tree args = CONSTRUCTOR_ELTS (value);
! 474: tree a1 = TREE_VALUE (args);
! 475: tree a2 = TREE_VALUE (TREE_CHAIN (args));
! 476: tree a3 = CONSTRUCTOR_ELTS (TREE_VALUE (TREE_CHAIN (TREE_CHAIN (args))));
! 477: a3 = TREE_VALUE (a3);
! 478: STRIP_NOPS (a3);
! 479: if (TREE_CODE (a1) == INTEGER_CST
! 480: && TREE_CODE (a2) == INTEGER_CST)
! 481: {
! 482: build_overload_int (a1);
! 483: OB_PUTC ('_');
! 484: build_overload_int (a2);
! 485: OB_PUTC ('_');
! 486: if (TREE_CODE (a3) == ADDR_EXPR)
! 487: {
! 488: a3 = TREE_OPERAND (a3, 0);
! 489: if (TREE_CODE (a3) == FUNCTION_DECL)
! 490: {
! 491: numeric_output_need_bar = 0;
! 492: build_overload_identifier (DECL_ASSEMBLER_NAME (a3));
! 493: return;
! 494: }
! 495: }
! 496: else if (TREE_CODE (a3) == INTEGER_CST)
! 497: {
! 498: OB_PUTC ('i');
! 499: build_overload_int (a3);
! 500: numeric_output_need_bar = 1;
! 501: return;
! 502: }
! 503: }
! 504: }
! 505: sorry ("template instantiation with pointer to method that is too complex");
! 506: return;
! 507: }
! 508: if (TREE_CODE (value) == INTEGER_CST)
! 509: {
! 510: build_overload_int (value);
! 511: numeric_output_need_bar = 1;
! 512: return;
! 513: }
1.1 root 514: value = TREE_OPERAND (value, 0);
515: if (TREE_CODE (value) == VAR_DECL)
516: {
517: my_friendly_assert (DECL_NAME (value) != 0, 245);
518: build_overload_identifier (DECL_NAME (value));
519: return;
520: }
521: else if (TREE_CODE (value) == FUNCTION_DECL)
522: {
523: my_friendly_assert (DECL_NAME (value) != 0, 246);
524: build_overload_identifier (DECL_NAME (value));
525: return;
526: }
527: else
528: my_friendly_abort (71);
529: break; /* not really needed */
530:
531: default:
532: sorry ("conversion of %s as template parameter",
533: tree_code_name [(int) TREE_CODE (type)]);
534: my_friendly_abort (72);
535: }
536: }
537:
538: static void
539: build_overload_identifier (name)
540: tree name;
541: {
542: if (IDENTIFIER_TEMPLATE (name))
543: {
544: tree template, parmlist, arglist, tname;
545: int i, nparms;
546: template = IDENTIFIER_TEMPLATE (name);
547: arglist = TREE_VALUE (template);
548: template = TREE_PURPOSE (template);
549: tname = DECL_NAME (template);
550: parmlist = DECL_ARGUMENTS (template);
551: nparms = TREE_VEC_LENGTH (parmlist);
552: OB_PUTC ('t');
553: icat (IDENTIFIER_LENGTH (tname));
554: OB_PUTID (tname);
555: icat (nparms);
556: for (i = 0; i < nparms; i++)
557: {
558: tree parm = TREE_VALUE (TREE_VEC_ELT (parmlist, i));
559: tree arg = TREE_VEC_ELT (arglist, i);
560: if (TREE_CODE (parm) == TYPE_DECL)
561: {
562: /* This parameter is a type. */
563: OB_PUTC ('Z');
564: build_overload_name (arg, 0, 0);
565: }
566: else
567: {
1.1.1.2 ! root 568: parm = tsubst (parm, &TREE_VEC_ELT (arglist, 0),
! 569: TREE_VEC_LENGTH (arglist), NULL_TREE);
1.1 root 570: /* It's a PARM_DECL. */
571: build_overload_name (TREE_TYPE (parm), 0, 0);
572: build_overload_value (parm, arg);
573: }
574: }
575: }
576: else
577: {
1.1.1.2 ! root 578: if (numeric_output_need_bar)
1.1 root 579: {
580: OB_PUTC ('_');
1.1.1.2 ! root 581: numeric_output_need_bar = 0;
1.1 root 582: }
583: icat (IDENTIFIER_LENGTH (name));
584: OB_PUTID (name);
585: }
586: }
587:
588: /* Given a list of parameters in PARMTYPES, create an unambiguous
589: overload string. Should distinguish any type that C (or C++) can
590: distinguish. I.e., pointers to functions are treated correctly.
591:
592: Caller must deal with whether a final `e' goes on the end or not.
593:
594: Any default conversions must take place before this function
595: is called.
596:
597: BEGIN and END control initialization and finalization of the
598: obstack where we build the string. */
599:
600: char *
601: build_overload_name (parmtypes, begin, end)
602: tree parmtypes;
603: int begin, end;
604: {
605: int just_one;
606: tree parmtype;
607:
608: if (begin) OB_INIT ();
1.1.1.2 ! root 609: numeric_output_need_bar = 0;
1.1 root 610:
611: if ((just_one = (TREE_CODE (parmtypes) != TREE_LIST)))
612: {
613: parmtype = parmtypes;
614: goto only_one;
615: }
616:
617: while (parmtypes)
618: {
619: parmtype = TREE_VALUE (parmtypes);
620:
621: only_one:
622:
1.1.1.2 ! root 623: if (! nofold && ! just_one)
1.1 root 624: {
1.1.1.2 ! root 625: /* Every argument gets counted. */
! 626: typevec[maxtype++] = parmtype;
1.1 root 627:
1.1.1.2 ! root 628: if (TREE_USED (parmtype) && parmtype == typevec[maxtype-2])
1.1 root 629: {
1.1.1.2 ! root 630: nrepeats++;
1.1 root 631: goto next;
632: }
1.1.1.2 ! root 633:
1.1 root 634: if (nrepeats)
635: flush_repeats (typevec[maxtype-2]);
1.1.1.2 ! root 636:
! 637: if (TREE_USED (parmtype))
! 638: {
! 639: flush_repeats (parmtype);
! 640: goto next;
! 641: }
! 642:
! 643: /* Only cache types which take more than one character. */
! 644: if (parmtype != TYPE_MAIN_VARIANT (parmtype)
! 645: || (TREE_CODE (parmtype) != INTEGER_TYPE
! 646: && TREE_CODE (parmtype) != REAL_TYPE))
1.1 root 647: TREE_USED (parmtype) = 1;
648: }
649:
650: if (TYPE_PTRMEMFUNC_P (parmtype))
651: parmtype = TYPE_PTRMEMFUNC_FN_TYPE (parmtype);
652:
653: if (TREE_READONLY (parmtype))
654: OB_PUTC ('C');
655: if (TREE_CODE (parmtype) == INTEGER_TYPE
656: && TYPE_MAIN_VARIANT (parmtype) == unsigned_type (TYPE_MAIN_VARIANT (parmtype)))
657: OB_PUTC ('U');
658: if (TYPE_VOLATILE (parmtype))
659: OB_PUTC ('V');
660:
661: switch (TREE_CODE (parmtype))
662: {
663: case OFFSET_TYPE:
664: OB_PUTC ('O');
665: build_overload_name (TYPE_OFFSET_BASETYPE (parmtype), 0, 0);
666: OB_PUTC ('_');
667: build_overload_name (TREE_TYPE (parmtype), 0, 0);
668: break;
669:
670: case REFERENCE_TYPE:
671: OB_PUTC ('R');
672: goto more;
673:
674: case ARRAY_TYPE:
675: #if PARM_CAN_BE_ARRAY_TYPE
676: {
677: tree length;
678:
679: OB_PUTC ('A');
680: if (TYPE_DOMAIN (parmtype) == NULL_TREE)
681: error ("pointer or reference to array of unknown bound in parm type");
682: else
683: {
684: length = array_type_nelts (parmtype);
685: if (TREE_CODE (length) == INTEGER_CST)
686: icat (TREE_INT_CST_LOW (length) + 1);
687: }
688: OB_PUTC ('_');
689: goto more;
690: }
691: #else
692: OB_PUTC ('P');
693: goto more;
694: #endif
695:
696: case POINTER_TYPE:
697: OB_PUTC ('P');
698: more:
699: build_overload_name (TREE_TYPE (parmtype), 0, 0);
700: break;
701:
702: case FUNCTION_TYPE:
703: case METHOD_TYPE:
704: {
705: tree firstarg = TYPE_ARG_TYPES (parmtype);
706: /* Otherwise have to implement reentrant typevecs,
707: unmark and remark types, etc. */
708: int old_nofold = nofold;
709: nofold = 1;
710:
711: if (nrepeats)
712: flush_repeats (typevec[maxtype-1]);
713:
714: /* @@ It may be possible to pass a function type in
715: which is not preceded by a 'P'. */
716: if (TREE_CODE (parmtype) == FUNCTION_TYPE)
717: {
718: OB_PUTC ('F');
719: if (firstarg == NULL_TREE)
720: OB_PUTC ('e');
721: else if (firstarg == void_list_node)
722: OB_PUTC ('v');
723: else
724: build_overload_name (firstarg, 0, 0);
725: }
726: else
727: {
728: int constp = TYPE_READONLY (TREE_TYPE (TREE_VALUE (firstarg)));
729: int volatilep = TYPE_VOLATILE (TREE_TYPE (TREE_VALUE (firstarg)));
730: OB_PUTC ('M');
731: firstarg = TREE_CHAIN (firstarg);
732:
733: build_overload_name (TYPE_METHOD_BASETYPE (parmtype), 0, 0);
734: if (constp)
735: OB_PUTC ('C');
736: if (volatilep)
737: OB_PUTC ('V');
738:
739: /* For cfront 2.0 compatibility. */
740: OB_PUTC ('F');
741:
742: if (firstarg == NULL_TREE)
743: OB_PUTC ('e');
744: else if (firstarg == void_list_node)
745: OB_PUTC ('v');
746: else
747: build_overload_name (firstarg, 0, 0);
748: }
749:
750: /* Separate args from return type. */
751: OB_PUTC ('_');
752: build_overload_name (TREE_TYPE (parmtype), 0, 0);
753: nofold = old_nofold;
754: break;
755: }
756:
757: case INTEGER_TYPE:
758: parmtype = TYPE_MAIN_VARIANT (parmtype);
759: if (parmtype == integer_type_node
760: || parmtype == unsigned_type_node)
761: OB_PUTC ('i');
762: else if (parmtype == long_integer_type_node
763: || parmtype == long_unsigned_type_node)
764: OB_PUTC ('l');
765: else if (parmtype == short_integer_type_node
766: || parmtype == short_unsigned_type_node)
767: OB_PUTC ('s');
768: else if (parmtype == signed_char_type_node)
769: {
770: OB_PUTC ('S');
771: OB_PUTC ('c');
772: }
773: else if (parmtype == char_type_node
774: || parmtype == unsigned_char_type_node)
775: OB_PUTC ('c');
776: else if (parmtype == wchar_type_node)
777: OB_PUTC ('w');
778: else if (parmtype == long_long_integer_type_node
779: || parmtype == long_long_unsigned_type_node)
780: OB_PUTC ('x');
781: #if 0
782: /* it would seem there is no way to enter these in source code,
783: yet. (mrs) */
784: else if (parmtype == long_long_long_integer_type_node
785: || parmtype == long_long_long_unsigned_type_node)
786: OB_PUTC ('q');
787: #endif
788: else
789: my_friendly_abort (73);
790: break;
791:
792: case BOOLEAN_TYPE:
793: OB_PUTC ('b');
794: break;
795:
796: case REAL_TYPE:
797: parmtype = TYPE_MAIN_VARIANT (parmtype);
798: if (parmtype == long_double_type_node)
799: OB_PUTC ('r');
800: else if (parmtype == double_type_node)
801: OB_PUTC ('d');
802: else if (parmtype == float_type_node)
803: OB_PUTC ('f');
804: else my_friendly_abort (74);
805: break;
806:
807: case VOID_TYPE:
808: if (! just_one)
809: {
810: #if 0
811: extern tree void_list_node;
812:
813: /* See if anybody is wasting memory. */
814: my_friendly_assert (parmtypes == void_list_node, 247);
815: #endif
816: /* This is the end of a parameter list. */
817: if (end) OB_FINISH ();
818: return (char *)obstack_base (&scratch_obstack);
819: }
820: OB_PUTC ('v');
821: break;
822:
823: case ERROR_MARK: /* not right, but nothing is anyway */
824: break;
825:
826: /* have to do these */
827: case UNION_TYPE:
828: case RECORD_TYPE:
829: if (! just_one)
830: /* Make this type signature look incompatible
831: with AT&T. */
832: OB_PUTC ('G');
833: goto common;
834: case ENUMERAL_TYPE:
835: common:
836: {
837: tree name = TYPE_NAME (parmtype);
838: int i = 1;
839:
840: if (TREE_CODE (name) == TYPE_DECL)
841: {
842: tree context = name;
1.1.1.2 ! root 843:
! 844: /* If DECL_ASSEMBLER_NAME has been set properly, use it. */
! 845: if (DECL_ASSEMBLER_NAME (context) != DECL_NAME (context))
! 846: {
! 847: OB_PUTID (DECL_ASSEMBLER_NAME (context));
! 848: break;
! 849: }
1.1 root 850: while (DECL_CONTEXT (context))
851: {
852: i += 1;
853: context = DECL_CONTEXT (context);
854: if (TREE_CODE_CLASS (TREE_CODE (context)) == 't')
855: context = TYPE_NAME (context);
856: }
857: name = DECL_NAME (name);
858: }
859: my_friendly_assert (TREE_CODE (name) == IDENTIFIER_NODE, 248);
860: if (i > 1)
861: {
862: OB_PUTC ('Q');
863: if (i > 9)
864: OB_PUTC ('_');
865: icat (i);
866: if (i > 9)
867: OB_PUTC ('_');
1.1.1.2 ! root 868: numeric_output_need_bar = 0;
! 869: build_overload_nested_name (TYPE_MAIN_DECL (parmtype));
1.1 root 870: }
871: else
872: build_overload_identifier (name);
873: break;
874: }
875:
876: case UNKNOWN_TYPE:
877: /* This will take some work. */
878: OB_PUTC ('?');
879: break;
880:
881: case TEMPLATE_TYPE_PARM:
882: case TEMPLATE_CONST_PARM:
883: case UNINSTANTIATED_P_TYPE:
884: /* We don't ever want this output, but it's inconvenient not to
885: be able to build the string. This should cause assembler
886: errors we'll notice. */
887: {
888: static int n;
889: sprintf (digit_buffer, " *%d", n++);
890: OB_PUTCP (digit_buffer);
891: }
892: break;
893:
894: default:
895: my_friendly_abort (75);
896: }
897:
898: next:
899: if (just_one) break;
900: parmtypes = TREE_CHAIN (parmtypes);
901: }
902: if (! just_one)
903: {
904: if (nrepeats)
905: flush_repeats (typevec[maxtype-1]);
906:
907: /* To get here, parms must end with `...'. */
908: OB_PUTC ('e');
909: }
910:
911: if (end) OB_FINISH ();
912: return (char *)obstack_base (&scratch_obstack);
913: }
914:
915: tree
916: build_static_name (basetype, name)
917: tree basetype, name;
918: {
919: char *basename = build_overload_name (basetype, 1, 1);
920: char *buf = (char *) alloca (IDENTIFIER_LENGTH (name)
921: + sizeof (STATIC_NAME_FORMAT)
922: + strlen (basename));
923: sprintf (buf, STATIC_NAME_FORMAT, basename, IDENTIFIER_POINTER (name));
924: return get_identifier (buf);
925: }
926:
927: /* Generate an identifier that encodes the (ANSI) exception TYPE. */
928:
929: /* This should be part of `ansi_opname', or at least be defined by the std. */
930: #define EXCEPTION_NAME_PREFIX "__ex"
931: #define EXCEPTION_NAME_LENGTH 4
932:
933: tree
934: cplus_exception_name (type)
935: tree type;
936: {
937: OB_INIT ();
938: OB_PUTS (EXCEPTION_NAME_PREFIX);
939: return get_identifier (build_overload_name (type, 0, 1));
940: }
941:
942: /* Change the name of a function definition so that it may be
943: overloaded. NAME is the name of the function to overload,
944: PARMS is the parameter list (which determines what name the
945: final function obtains).
946:
947: FOR_METHOD is 1 if this overload is being performed
948: for a method, rather than a function type. It is 2 if
949: this overload is being performed for a constructor. */
950: tree
951: build_decl_overload (dname, parms, for_method)
952: tree dname;
953: tree parms;
954: int for_method;
955: {
956: char *name = IDENTIFIER_POINTER (dname);
957:
958: /* member operators new and delete look like methods at this point. */
959: if (! for_method && parms != NULL_TREE && TREE_CODE (parms) == TREE_LIST)
960: {
961: if (dname == ansi_opname[(int) DELETE_EXPR])
962: return get_identifier ("__builtin_delete");
963: else if (dname == ansi_opname[(int) VEC_DELETE_EXPR])
964: return get_identifier ("__builtin_vec_delete");
965: else if (TREE_CHAIN (parms) == void_list_node)
966: {
967: if (dname == ansi_opname[(int) NEW_EXPR])
968: return get_identifier ("__builtin_new");
969: else if (dname == ansi_opname[(int) VEC_NEW_EXPR])
970: return get_identifier ("__builtin_vec_new");
971: }
972: }
973:
974: OB_INIT ();
975: if (for_method != 2)
976: OB_PUTCP (name);
977: /* Otherwise, we can divine that this is a constructor,
978: and figure out its name without any extra encoding. */
979:
980: OB_PUTC2 ('_', '_');
981: if (for_method)
982: {
983: #if 0
984: /* We can get away without doing this. */
985: OB_PUTC ('M');
986: #endif
987: {
988: tree this_type = TREE_VALUE (parms);
989:
990: if (TREE_CODE (this_type) == RECORD_TYPE) /* a signature pointer */
991: parms = temp_tree_cons (NULL_TREE, SIGNATURE_TYPE (this_type),
992: TREE_CHAIN (parms));
993: else
994: parms = temp_tree_cons (NULL_TREE, TREE_TYPE (this_type),
995: TREE_CHAIN (parms));
996: }
997: }
998: else
999: OB_PUTC ('F');
1000:
1001: if (parms == NULL_TREE)
1002: OB_PUTC2 ('e', '\0');
1003: else if (parms == void_list_node)
1004: OB_PUTC2 ('v', '\0');
1005: else
1006: {
1007: ALLOCATE_TYPEVEC (parms);
1008: nofold = 0;
1009: if (for_method)
1010: {
1011: build_overload_name (TREE_VALUE (parms), 0, 0);
1012:
1013: typevec[maxtype++] = TREE_VALUE (parms);
1014: TREE_USED (TREE_VALUE (parms)) = 1;
1015:
1016: if (TREE_CHAIN (parms))
1017: build_overload_name (TREE_CHAIN (parms), 0, 1);
1018: else
1019: OB_PUTC2 ('e', '\0');
1020: }
1021: else
1022: build_overload_name (parms, 0, 1);
1023: DEALLOCATE_TYPEVEC (parms);
1024: }
1025: {
1026: tree n = get_identifier (obstack_base (&scratch_obstack));
1027: if (IDENTIFIER_OPNAME_P (dname))
1028: IDENTIFIER_OPNAME_P (n) = 1;
1029: return n;
1030: }
1031: }
1032:
1033: /* Build an overload name for the type expression TYPE. */
1034: tree
1035: build_typename_overload (type)
1036: tree type;
1037: {
1038: tree id;
1039:
1040: OB_INIT ();
1041: OB_PUTID (ansi_opname[(int) TYPE_EXPR]);
1042: nofold = 1;
1043: build_overload_name (type, 0, 1);
1044: id = get_identifier (obstack_base (&scratch_obstack));
1045: IDENTIFIER_OPNAME_P (id) = 1;
1046: #if 0
1047: IDENTIFIER_GLOBAL_VALUE (id) = TYPE_NAME (type);
1048: #endif
1049: TREE_TYPE (id) = type;
1050: return id;
1051: }
1052:
1053: #ifndef NO_DOLLAR_IN_LABEL
1054: #define T_DESC_FORMAT "TD$"
1055: #define I_DESC_FORMAT "ID$"
1056: #define M_DESC_FORMAT "MD$"
1057: #else
1058: #if !defined(NO_DOT_IN_LABEL)
1059: #define T_DESC_FORMAT "TD."
1060: #define I_DESC_FORMAT "ID."
1061: #define M_DESC_FORMAT "MD."
1062: #else
1063: #define T_DESC_FORMAT "__t_desc_"
1064: #define I_DESC_FORMAT "__i_desc_"
1065: #define M_DESC_FORMAT "__m_desc_"
1066: #endif
1067: #endif
1068:
1069: /* Build an overload name for the type expression TYPE. */
1070: tree
1071: build_t_desc_overload (type)
1072: tree type;
1073: {
1074: OB_INIT ();
1075: OB_PUTS (T_DESC_FORMAT);
1076: nofold = 1;
1077:
1078: #if 0
1079: /* Use a different format if the type isn't defined yet. */
1080: if (TYPE_SIZE (type) == NULL_TREE)
1081: {
1082: char *p;
1083: int changed;
1084:
1085: for (p = tname; *p; p++)
1086: if (isupper (*p))
1087: {
1088: changed = 1;
1089: *p = tolower (*p);
1090: }
1091: /* If there's no change, we have an inappropriate T_DESC_FORMAT. */
1092: my_friendly_assert (changed != 0, 249);
1093: }
1094: #endif
1095:
1096: build_overload_name (type, 0, 1);
1097: return get_identifier (obstack_base (&scratch_obstack));
1098: }
1099:
1100: /* Top-level interface to explicit overload requests. Allow NAME
1101: to be overloaded. Error if NAME is already declared for the current
1102: scope. Warning if function is redundantly overloaded. */
1103:
1104: void
1105: declare_overloaded (name)
1106: tree name;
1107: {
1108: #ifdef NO_AUTO_OVERLOAD
1109: if (is_overloaded (name))
1110: warning ("function `%s' already declared overloaded",
1111: IDENTIFIER_POINTER (name));
1112: else if (IDENTIFIER_GLOBAL_VALUE (name))
1113: error ("overloading function `%s' that is already defined",
1114: IDENTIFIER_POINTER (name));
1115: else
1116: {
1117: TREE_OVERLOADED (name) = 1;
1118: IDENTIFIER_GLOBAL_VALUE (name) = build_tree_list (name, NULL_TREE);
1119: TREE_TYPE (IDENTIFIER_GLOBAL_VALUE (name)) = unknown_type_node;
1120: }
1121: #else
1122: if (current_lang_name == lang_name_cplusplus)
1123: {
1124: if (0)
1125: warning ("functions are implicitly overloaded in C++");
1126: }
1127: else if (current_lang_name == lang_name_c)
1128: error ("overloading function `%s' cannot be done in C language context");
1129: else
1130: my_friendly_abort (76);
1131: #endif
1132: }
1133:
1134: #ifdef NO_AUTO_OVERLOAD
1135: /* Check to see if NAME is overloaded. For first approximation,
1136: check to see if its TREE_OVERLOADED is set. This is used on
1137: IDENTIFIER nodes. */
1138: int
1139: is_overloaded (name)
1140: tree name;
1141: {
1142: /* @@ */
1143: return (TREE_OVERLOADED (name)
1144: && (! IDENTIFIER_CLASS_VALUE (name) || current_class_type == 0)
1145: && ! IDENTIFIER_LOCAL_VALUE (name));
1146: }
1147: #endif
1148:
1149: /* Given a tree_code CODE, and some arguments (at least one),
1150: attempt to use an overloaded operator on the arguments.
1151:
1152: For unary operators, only the first argument need be checked.
1153: For binary operators, both arguments may need to be checked.
1154:
1155: Member functions can convert class references to class pointers,
1156: for one-level deep indirection. More than that is not supported.
1157: Operators [](), ()(), and ->() must be member functions.
1158:
1159: We call function call building calls with LOOKUP_COMPLAIN if they
1160: are our only hope. This is true when we see a vanilla operator
1161: applied to something of aggregate type. If this fails, we are free
1162: to return `error_mark_node', because we will have reported the
1163: error.
1164:
1165: Operators NEW and DELETE overload in funny ways: operator new takes
1166: a single `size' parameter, and operator delete takes a pointer to the
1167: storage being deleted. When overloading these operators, success is
1168: assumed. If there is a failure, report an error message and return
1169: `error_mark_node'. */
1170:
1171: /* NOSTRICT */
1172: tree
1173: build_opfncall (code, flags, xarg1, xarg2, arg3)
1174: enum tree_code code;
1175: int flags;
1176: tree xarg1, xarg2, arg3;
1177: {
1178: tree rval = 0;
1179: tree arg1, arg2;
1180: tree type1, type2, fnname;
1181: tree fields1 = 0, parms = 0;
1182: tree global_fn;
1183: int try_second;
1184: int binary_is_unary;
1185:
1186: if (xarg1 == error_mark_node)
1187: return error_mark_node;
1188:
1189: if (code == COND_EXPR)
1190: {
1191: if (TREE_CODE (xarg2) == ERROR_MARK
1192: || TREE_CODE (arg3) == ERROR_MARK)
1193: return error_mark_node;
1194: }
1195: if (code == COMPONENT_REF)
1196: if (TREE_CODE (TREE_TYPE (xarg1)) == POINTER_TYPE)
1197: return rval;
1198:
1199: /* First, see if we can work with the first argument */
1200: type1 = TREE_TYPE (xarg1);
1201:
1202: /* Some tree codes have length > 1, but we really only want to
1203: overload them if their first argument has a user defined type. */
1204: switch (code)
1205: {
1206: case PREINCREMENT_EXPR:
1207: case PREDECREMENT_EXPR:
1208: case POSTINCREMENT_EXPR:
1209: case POSTDECREMENT_EXPR:
1210: case COMPONENT_REF:
1211: binary_is_unary = 1;
1212: try_second = 0;
1213: break;
1214:
1215: /* ARRAY_REFs and CALL_EXPRs must overload successfully.
1216: If they do not, return error_mark_node instead of NULL_TREE. */
1217: case ARRAY_REF:
1218: if (xarg2 == error_mark_node)
1219: return error_mark_node;
1220: case CALL_EXPR:
1221: rval = error_mark_node;
1222: binary_is_unary = 0;
1223: try_second = 0;
1224: break;
1225:
1226: case VEC_NEW_EXPR:
1227: case NEW_EXPR:
1228: {
1229: tree args = tree_cons (NULL_TREE, xarg2, arg3);
1230: fnname = ansi_opname[(int) code];
1231: if (flags & LOOKUP_GLOBAL)
1232: return build_overload_call (fnname, args, flags & LOOKUP_COMPLAIN,
1233: (struct candidate *)0);
1234:
1235: rval = build_method_call
1236: (build_indirect_ref (build1 (NOP_EXPR, xarg1, error_mark_node),
1237: "new"),
1238: fnname, args, NULL_TREE, flags);
1239: if (rval == error_mark_node)
1240: /* User might declare fancy operator new, but invoke it
1241: like standard one. */
1242: return rval;
1243:
1244: TREE_TYPE (rval) = xarg1;
1245: TREE_CALLS_NEW (rval) = 1;
1246: return rval;
1247: }
1248: break;
1249:
1250: case VEC_DELETE_EXPR:
1251: case DELETE_EXPR:
1252: {
1253: fnname = ansi_opname[(int) code];
1254: if (flags & LOOKUP_GLOBAL)
1255: return build_overload_call (fnname,
1256: build_tree_list (NULL_TREE, xarg1),
1257: flags & LOOKUP_COMPLAIN,
1258: (struct candidate *)0);
1259:
1260: rval = build_method_call
1261: (build_indirect_ref (build1 (NOP_EXPR, TREE_TYPE (xarg1),
1262: error_mark_node),
1263: NULL_PTR),
1264: fnname, tree_cons (NULL_TREE, xarg1,
1265: build_tree_list (NULL_TREE, xarg2)),
1266: NULL_TREE, flags);
1.1.1.2 ! root 1267: #if 0
! 1268: /* This can happen when operator delete is protected. */
1.1 root 1269: my_friendly_assert (rval != error_mark_node, 250);
1270: TREE_TYPE (rval) = void_type_node;
1.1.1.2 ! root 1271: #endif
1.1 root 1272: return rval;
1273: }
1274: break;
1275:
1276: default:
1277: binary_is_unary = 0;
1278: try_second = tree_code_length [(int) code] == 2;
1279: if (try_second && xarg2 == error_mark_node)
1280: return error_mark_node;
1281: break;
1282: }
1283:
1284: if (try_second && xarg2 == error_mark_node)
1285: return error_mark_node;
1286:
1287: /* What ever it was, we do not know how to deal with it. */
1288: if (type1 == NULL_TREE)
1289: return rval;
1290:
1291: if (TREE_CODE (type1) == OFFSET_TYPE)
1292: type1 = TREE_TYPE (type1);
1293:
1294: if (TREE_CODE (type1) == REFERENCE_TYPE)
1295: {
1296: arg1 = convert_from_reference (xarg1);
1297: type1 = TREE_TYPE (arg1);
1298: }
1299: else
1300: {
1301: arg1 = xarg1;
1302: }
1303:
1304: if (!IS_AGGR_TYPE (type1) || TYPE_PTRMEMFUNC_P (type1))
1305: {
1306: /* Try to fail. First, fail if unary */
1307: if (! try_second)
1308: return rval;
1309: /* Second, see if second argument is non-aggregate. */
1310: type2 = TREE_TYPE (xarg2);
1311: if (TREE_CODE (type2) == OFFSET_TYPE)
1312: type2 = TREE_TYPE (type2);
1313: if (TREE_CODE (type2) == REFERENCE_TYPE)
1314: {
1315: arg2 = convert_from_reference (xarg2);
1316: type2 = TREE_TYPE (arg2);
1317: }
1318: else
1319: {
1320: arg2 = xarg2;
1321: }
1322:
1323: if (!IS_AGGR_TYPE (type2))
1324: return rval;
1325: try_second = 0;
1326: }
1327:
1328: if (try_second)
1329: {
1330: /* First arg may succeed; see whether second should. */
1331: type2 = TREE_TYPE (xarg2);
1332: if (TREE_CODE (type2) == OFFSET_TYPE)
1333: type2 = TREE_TYPE (type2);
1334: if (TREE_CODE (type2) == REFERENCE_TYPE)
1335: {
1336: arg2 = convert_from_reference (xarg2);
1337: type2 = TREE_TYPE (arg2);
1338: }
1339: else
1340: {
1341: arg2 = xarg2;
1342: }
1343:
1344: if (! IS_AGGR_TYPE (type2))
1345: try_second = 0;
1346: }
1347:
1348: if (type1 == unknown_type_node
1349: || (try_second && TREE_TYPE (xarg2) == unknown_type_node))
1350: {
1351: /* This will not be implemented in the foreseeable future. */
1352: return rval;
1353: }
1354:
1355: if (code == MODIFY_EXPR)
1356: fnname = ansi_assopname[(int) TREE_CODE (arg3)];
1357: else
1358: fnname = ansi_opname[(int) code];
1359:
1360: global_fn = lookup_name_nonclass (fnname);
1361:
1362: /* This is the last point where we will accept failure. This
1363: may be too eager if we wish an overloaded operator not to match,
1364: but would rather a normal operator be called on a type-converted
1365: argument. */
1366:
1367: if (IS_AGGR_TYPE (type1))
1368: {
1369: fields1 = lookup_fnfields (TYPE_BINFO (type1), fnname, 0);
1370: /* ARM $13.4.7, prefix/postfix ++/--. */
1371: if (code == POSTINCREMENT_EXPR || code == POSTDECREMENT_EXPR)
1372: {
1373: xarg2 = integer_zero_node;
1374: binary_is_unary = 0;
1375:
1376: if (fields1)
1377: {
1378: tree t, t2;
1379: int have_postfix = 0;
1380:
1381: /* Look for an `operator++ (int)'. If they didn't have
1382: one, then we fall back to the old way of doing things. */
1.1.1.2 ! root 1383: for (t = TREE_VALUE (fields1); t ; t = DECL_CHAIN (t))
1.1 root 1384: {
1385: t2 = TYPE_ARG_TYPES (TREE_TYPE (t));
1386: if (TREE_CHAIN (t2) != NULL_TREE
1387: && TREE_VALUE (TREE_CHAIN (t2)) == integer_type_node)
1388: {
1389: have_postfix = 1;
1390: break;
1391: }
1392: }
1393:
1394: if (! have_postfix)
1395: {
1396: char *op = POSTINCREMENT_EXPR ? "++" : "--";
1397:
1398: /* There's probably a LOT of code in the world that
1.1.1.2 ! root 1399: relies upon this old behavior. */
! 1400: if (! flag_traditional)
! 1401: pedwarn ("no `operator%s (int)' declared for postfix `%s', using prefix operator instead",
1.1 root 1402: op, op);
1403: xarg2 = NULL_TREE;
1404: binary_is_unary = 1;
1405: }
1406: }
1407: }
1408: }
1409:
1410: if (fields1 == NULL_TREE && global_fn == NULL_TREE)
1411: return rval;
1412:
1413: /* If RVAL winds up being `error_mark_node', we will return
1414: that... There is no way that normal semantics of these
1415: operators will succeed. */
1416:
1417: /* This argument may be an uncommitted OFFSET_REF. This is
1418: the case for example when dealing with static class members
1419: which are referenced from their class name rather than
1420: from a class instance. */
1421: if (TREE_CODE (xarg1) == OFFSET_REF
1422: && TREE_CODE (TREE_OPERAND (xarg1, 1)) == VAR_DECL)
1423: xarg1 = TREE_OPERAND (xarg1, 1);
1424: if (try_second && xarg2 && TREE_CODE (xarg2) == OFFSET_REF
1425: && TREE_CODE (TREE_OPERAND (xarg2, 1)) == VAR_DECL)
1426: xarg2 = TREE_OPERAND (xarg2, 1);
1427:
1428: if (global_fn)
1429: flags |= LOOKUP_GLOBAL;
1430:
1431: if (code == CALL_EXPR)
1432: {
1433: /* This can only be a member function. */
1434: return build_method_call (xarg1, fnname, xarg2,
1435: NULL_TREE, LOOKUP_NORMAL);
1436: }
1437: else if (tree_code_length[(int) code] == 1 || binary_is_unary)
1438: {
1439: parms = NULL_TREE;
1440: rval = build_method_call (xarg1, fnname, NULL_TREE, NULL_TREE, flags);
1441: }
1442: else if (code == COND_EXPR)
1443: {
1444: parms = tree_cons (0, xarg2, build_tree_list (NULL_TREE, arg3));
1445: rval = build_method_call (xarg1, fnname, parms, NULL_TREE, flags);
1446: }
1447: else if (code == METHOD_CALL_EXPR)
1448: {
1449: /* must be a member function. */
1450: parms = tree_cons (NULL_TREE, xarg2, arg3);
1451: return build_method_call (xarg1, fnname, parms, NULL_TREE,
1452: LOOKUP_NORMAL);
1453: }
1454: else if (fields1)
1455: {
1456: parms = build_tree_list (NULL_TREE, xarg2);
1457: rval = build_method_call (xarg1, fnname, parms, NULL_TREE, flags);
1458: }
1459: else
1460: {
1461: parms = tree_cons (NULL_TREE, xarg1,
1462: build_tree_list (NULL_TREE, xarg2));
1463: rval = build_overload_call (fnname, parms, flags,
1464: (struct candidate *)0);
1465: }
1466:
1467: return rval;
1468: }
1469:
1470: /* This function takes an identifier, ID, and attempts to figure out what
1471: it means. There are a number of possible scenarios, presented in increasing
1472: order of hair:
1473:
1474: 1) not in a class's scope
1475: 2) in class's scope, member name of the class's method
1476: 3) in class's scope, but not a member name of the class
1477: 4) in class's scope, member name of a class's variable
1478:
1479: NAME is $1 from the bison rule. It is an IDENTIFIER_NODE.
1480: VALUE is $$ from the bison rule. It is the value returned by lookup_name ($1)
1481: yychar is the pending input character (suitably encoded :-).
1482:
1483: As a last ditch, try to look up the name as a label and return that
1484: address.
1485:
1486: Values which are declared as being of REFERENCE_TYPE are
1487: automatically dereferenced here (as a hack to make the
1488: compiler faster). */
1489:
1490: tree
1491: hack_identifier (value, name, yychar)
1492: tree value, name;
1493: int yychar;
1494: {
1495: tree type;
1496:
1497: if (TREE_CODE (value) == ERROR_MARK)
1498: {
1499: if (current_class_name)
1500: {
1501: tree fields = lookup_fnfields (TYPE_BINFO (current_class_type), name, 1);
1502: if (fields == error_mark_node)
1503: return error_mark_node;
1504: if (fields)
1505: {
1506: tree fndecl;
1507:
1508: fndecl = TREE_VALUE (fields);
1509: my_friendly_assert (TREE_CODE (fndecl) == FUNCTION_DECL, 251);
1510: if (DECL_CHAIN (fndecl) == NULL_TREE)
1511: {
1512: warning ("methods cannot be converted to function pointers");
1513: return fndecl;
1514: }
1515: else
1516: {
1517: error ("ambiguous request for method pointer `%s'",
1518: IDENTIFIER_POINTER (name));
1519: return error_mark_node;
1520: }
1521: }
1522: }
1523: if (flag_labels_ok && IDENTIFIER_LABEL_VALUE (name))
1524: {
1525: return IDENTIFIER_LABEL_VALUE (name);
1526: }
1527: return error_mark_node;
1528: }
1529:
1530: type = TREE_TYPE (value);
1531: if (TREE_CODE (value) == FIELD_DECL)
1532: {
1533: if (current_class_decl == NULL_TREE)
1534: {
1535: error ("request for member `%s' in static member function",
1536: IDENTIFIER_POINTER (DECL_NAME (value)));
1537: return error_mark_node;
1538: }
1539: TREE_USED (current_class_decl) = 1;
1.1.1.2 ! root 1540:
1.1 root 1541: /* Mark so that if we are in a constructor, and then find that
1542: this field was initialized by a base initializer,
1543: we can emit an error message. */
1544: TREE_USED (value) = 1;
1545: return build_component_ref (C_C_D, name, 0, 1);
1546: }
1547:
1548: if (really_overloaded_fn (value))
1549: {
1550: tree t = get_first_fn (value);
1551: for (; t; t = DECL_CHAIN (t))
1552: {
1553: if (TREE_CODE (t) == TEMPLATE_DECL)
1554: continue;
1555:
1556: assemble_external (t);
1557: TREE_USED (t) = 1;
1558: }
1559: }
1560: else if (TREE_CODE (value) == TREE_LIST)
1561: {
1562: tree t = value;
1563: while (t && TREE_CODE (t) == TREE_LIST)
1564: {
1565: assemble_external (TREE_VALUE (t));
1566: TREE_USED (t) = 1;
1567: t = TREE_CHAIN (t);
1568: }
1569: }
1570: else
1571: {
1572: assemble_external (value);
1573: TREE_USED (value) = 1;
1574: }
1575:
1576: if (TREE_CODE_CLASS (TREE_CODE (value)) == 'd' && DECL_NONLOCAL (value))
1577: {
1578: if (DECL_LANG_SPECIFIC (value)
1579: && DECL_CLASS_CONTEXT (value) != current_class_type)
1580: {
1581: tree path;
1582: enum access_type access;
1583: register tree context
1584: = (TREE_CODE (value) == FUNCTION_DECL && DECL_VIRTUAL_P (value))
1585: ? DECL_CLASS_CONTEXT (value)
1586: : DECL_CONTEXT (value);
1587:
1588: get_base_distance (context, current_class_type, 0, &path);
1589: if (path)
1590: {
1591: access = compute_access (path, value);
1592: if (access != access_public)
1593: {
1594: if (TREE_CODE (value) == VAR_DECL)
1595: error ("static member `%s' is %s",
1596: IDENTIFIER_POINTER (name),
1597: TREE_PRIVATE (value) ? "private" :
1598: "from a private base class");
1599: else
1600: error ("enum `%s' is from private base class",
1601: IDENTIFIER_POINTER (name));
1602: return error_mark_node;
1603: }
1604: }
1605: }
1606: return value;
1607: }
1608: if (TREE_CODE (value) == TREE_LIST && TREE_NONLOCAL_FLAG (value))
1609: {
1610: if (type == 0)
1611: {
1612: error ("request for member `%s' is ambiguous in multiple inheritance lattice",
1613: IDENTIFIER_POINTER (name));
1614: return error_mark_node;
1615: }
1616:
1617: return value;
1618: }
1619:
1620: if (TREE_CODE (type) == REFERENCE_TYPE)
1621: {
1622: my_friendly_assert (TREE_CODE (value) == VAR_DECL
1623: || TREE_CODE (value) == PARM_DECL
1624: || TREE_CODE (value) == RESULT_DECL, 252);
1.1.1.2 ! root 1625: return convert_from_reference (value);
1.1 root 1626: }
1627: return value;
1628: }
1629:
1630:
1631: #if 0
1632: /* Given an object OF, and a type conversion operator COMPONENT
1633: build a call to the conversion operator, if a call is requested,
1634: or return the address (as a pointer to member function) if one is not.
1635:
1636: OF can be a TYPE_DECL or any kind of datum that would normally
1637: be passed to `build_component_ref'. It may also be NULL_TREE,
1638: in which case `current_class_type' and `current_class_decl'
1639: provide default values.
1640:
1641: BASETYPE_PATH, if non-null, is the path of basetypes
1642: to go through before we get the the instance of interest.
1643:
1644: PROTECT says whether we apply C++ scoping rules or not. */
1645: tree
1646: build_component_type_expr (of, component, basetype_path, protect)
1647: tree of, component, basetype_path;
1648: int protect;
1649: {
1650: tree cname = NULL_TREE;
1651: tree tmp, last;
1652: tree name;
1653: int flags = protect ? LOOKUP_NORMAL : LOOKUP_COMPLAIN;
1654:
1655: if (of)
1656: my_friendly_assert (IS_AGGR_TYPE (TREE_TYPE (of)), 253);
1657: my_friendly_assert (TREE_CODE (component) == TYPE_EXPR, 254);
1658:
1659: tmp = TREE_OPERAND (component, 0);
1660: last = NULL_TREE;
1661:
1662: while (tmp)
1663: {
1664: switch (TREE_CODE (tmp))
1665: {
1666: case CALL_EXPR:
1667: if (last)
1668: TREE_OPERAND (last, 0) = TREE_OPERAND (tmp, 0);
1669: else
1670: TREE_OPERAND (component, 0) = TREE_OPERAND (tmp, 0);
1671:
1672: last = groktypename (build_tree_list (TREE_TYPE (component),
1673: TREE_OPERAND (component, 0)));
1674: name = build_typename_overload (last);
1675: TREE_TYPE (name) = last;
1676:
1677: if (TREE_OPERAND (tmp, 0)
1678: && TREE_OPERAND (tmp, 0) != void_list_node)
1679: {
1680: cp_error ("`operator %T' requires empty parameter list", last);
1681: TREE_OPERAND (tmp, 0) = NULL_TREE;
1682: }
1683:
1684: if (of && TREE_CODE (of) != TYPE_DECL)
1685: return build_method_call (of, name, NULL_TREE, NULL_TREE, flags);
1686: else if (of)
1687: {
1688: tree this_this;
1689:
1690: if (current_class_decl == NULL_TREE)
1691: {
1692: cp_error ("object required for `operator %T' call",
1693: TREE_TYPE (name));
1694: return error_mark_node;
1695: }
1696:
1697: this_this = convert_pointer_to (TREE_TYPE (of),
1698: current_class_decl);
1699: this_this = build_indirect_ref (this_this, NULL_PTR);
1700: return build_method_call (this_this, name, NULL_TREE,
1701: NULL_TREE, flags | LOOKUP_NONVIRTUAL);
1702: }
1703: else if (current_class_decl)
1704: return build_method_call (tmp, name, NULL_TREE, NULL_TREE, flags);
1705:
1706: cp_error ("object required for `operator %T' call",
1707: TREE_TYPE (name));
1708: return error_mark_node;
1709:
1710: case INDIRECT_REF:
1711: case ADDR_EXPR:
1712: case ARRAY_REF:
1713: break;
1714:
1715: case SCOPE_REF:
1716: my_friendly_assert (cname == 0, 255);
1717: cname = TREE_OPERAND (tmp, 0);
1718: tmp = TREE_OPERAND (tmp, 1);
1719: break;
1720:
1721: default:
1722: my_friendly_abort (77);
1723: }
1724: last = tmp;
1725: tmp = TREE_OPERAND (tmp, 0);
1726: }
1727:
1728: last = groktypename (build_tree_list (TREE_TYPE (component), TREE_OPERAND (component, 0)));
1729: name = build_typename_overload (last);
1730: TREE_TYPE (name) = last;
1731: if (of && TREE_CODE (of) == TYPE_DECL)
1732: {
1733: if (cname == NULL_TREE)
1734: {
1735: cname = DECL_NAME (of);
1736: of = NULL_TREE;
1737: }
1738: else my_friendly_assert (cname == DECL_NAME (of), 256);
1739: }
1740:
1741: if (of)
1742: {
1743: tree this_this;
1744:
1745: if (current_class_decl == NULL_TREE)
1746: {
1747: cp_error ("object required for `operator %T' call",
1748: TREE_TYPE (name));
1749: return error_mark_node;
1750: }
1751:
1752: this_this = convert_pointer_to (TREE_TYPE (of), current_class_decl);
1753: return build_component_ref (this_this, name, 0, protect);
1754: }
1755: else if (cname)
1756: return build_offset_ref (cname, name);
1757: else if (current_class_name)
1758: return build_offset_ref (current_class_name, name);
1759:
1760: cp_error ("object required for `operator %T' member reference",
1761: TREE_TYPE (name));
1762: return error_mark_node;
1763: }
1764: #endif
1765:
1766: static char *
1767: thunk_printable_name (decl)
1768: tree decl;
1769: {
1770: return "<thunk function>";
1771: }
1772:
1773: tree
1774: make_thunk (function, delta)
1775: tree function;
1776: int delta;
1777: {
1778: char buffer[250];
1779: tree thunk_fndecl, thunk_id;
1780: tree thunk;
1781: char *func_name;
1782: static int thunk_number = 0;
1783: tree func_decl;
1784: if (TREE_CODE (function) != ADDR_EXPR)
1785: abort ();
1786: func_decl = TREE_OPERAND (function, 0);
1787: if (TREE_CODE (func_decl) != FUNCTION_DECL)
1788: abort ();
1789: func_name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (func_decl));
1.1.1.2 ! root 1790: if (delta<=0)
! 1791: sprintf (buffer, "__thunk_%d_%s", -delta, func_name);
! 1792: else
! 1793: sprintf (buffer, "__thunk_n%d_%s", delta, func_name);
1.1 root 1794: thunk_id = get_identifier (buffer);
1795: thunk = IDENTIFIER_GLOBAL_VALUE (thunk_id);
1796: if (thunk && TREE_CODE (thunk) != THUNK_DECL)
1797: {
1798: error_with_decl ("implementation-reserved name `%s' used");
1799: IDENTIFIER_GLOBAL_VALUE (thunk_id) = thunk = NULL_TREE;
1800: }
1801: if (thunk == NULL_TREE)
1802: {
1803: thunk = build_decl (THUNK_DECL, thunk_id, TREE_TYPE (func_decl));
1804: DECL_RESULT (thunk)
1.1.1.2 ! root 1805: = build_decl (RESULT_DECL, 0, TYPE_MAIN_VARIANT (TREE_TYPE (vtable_entry_type)));
! 1806: TREE_READONLY (thunk) = TYPE_READONLY (TREE_TYPE (vtable_entry_type));
! 1807: TREE_THIS_VOLATILE (thunk) = TYPE_VOLATILE (TREE_TYPE (vtable_entry_type));
1.1 root 1808: make_function_rtl (thunk);
1809: DECL_INITIAL (thunk) = function;
1810: THUNK_DELTA (thunk) = delta;
1811: /* So that finish_file can write out any thunks that need to be: */
1812: pushdecl_top_level (thunk);
1813: }
1814: return thunk;
1815: }
1816:
1817: void
1818: emit_thunk (thunk_fndecl)
1819: tree thunk_fndecl;
1820: {
1821: rtx insns;
1822: char *fnname;
1823: char buffer[250];
1824: tree argp;
1825: struct args_size stack_args_size;
1826: tree function = TREE_OPERAND (DECL_INITIAL (thunk_fndecl), 0);
1827: int delta = THUNK_DELTA (thunk_fndecl);
1828: int tem;
1829: int failure = 0;
1830: int current_call_is_indirect = 0; /* needed for HPPA FUNCTION_ARG */
1831:
1832: /* Used to remember which regs we need to emit a USE rtx for. */
1833: rtx need_use[FIRST_PSEUDO_REGISTER];
1834: int need_use_count = 0;
1835:
1836: /* rtx for the 'this' parameter. */
1837: rtx this_rtx = 0, this_reg_rtx = 0, fixed_this_rtx;
1838:
1839: char *(*save_decl_printable_name) () = decl_printable_name;
1840: /* Data on reg parms scanned so far. */
1841: CUMULATIVE_ARGS args_so_far;
1842:
1843: if (TREE_ASM_WRITTEN (thunk_fndecl))
1844: return;
1845:
1846: TREE_ASM_WRITTEN (thunk_fndecl) = 1;
1847:
1848: if (TREE_PUBLIC (function))
1849: {
1850: TREE_PUBLIC (thunk_fndecl) = 1;
1851: if (DECL_EXTERNAL (function))
1852: {
1853: DECL_EXTERNAL (thunk_fndecl) = 1;
1854: assemble_external (thunk_fndecl);
1855: return;
1856: }
1857: }
1858:
1859: decl_printable_name = thunk_printable_name;
1860: if (current_function_decl)
1861: abort ();
1862: current_function_decl = thunk_fndecl;
1863: init_function_start (thunk_fndecl, input_filename, lineno);
1864: pushlevel (0);
1865: expand_start_bindings (1);
1866:
1867: /* Start updating where the next arg would go. */
1868: INIT_CUMULATIVE_ARGS (args_so_far, TREE_TYPE (function), NULL_RTX);
1869: stack_args_size.constant = 0;
1870: stack_args_size.var = 0;
1871: /* SETUP for possible structure return address FIXME */
1872:
1873: /* Now look through all the parameters, make sure that we
1874: don't clobber any registers used for parameters.
1875: Also, pick up an rtx for the first "this" parameter. */
1876: for (argp = TYPE_ARG_TYPES (TREE_TYPE (function));
1877: argp != NULL_TREE;
1878: argp = TREE_CHAIN (argp))
1879:
1880: {
1881: tree passed_type = TREE_VALUE (argp);
1882: register rtx entry_parm;
1883: int named = 1; /* FIXME */
1884: struct args_size stack_offset;
1885: struct args_size arg_size;
1886:
1887: if (passed_type == void_type_node)
1888: break;
1889:
1890: if ((TREE_CODE (TYPE_SIZE (passed_type)) != INTEGER_CST
1891: && contains_placeholder_p (TYPE_SIZE (passed_type)))
1892: #ifdef FUNCTION_ARG_PASS_BY_REFERENCE
1893: || FUNCTION_ARG_PASS_BY_REFERENCE (args_so_far,
1894: TYPE_MODE (passed_type),
1895: passed_type, named)
1896: #endif
1897: )
1898: passed_type = build_pointer_type (passed_type);
1899:
1900: entry_parm = FUNCTION_ARG (args_so_far,
1901: TYPE_MODE (passed_type),
1902: passed_type,
1903: named);
1904: if (entry_parm != 0)
1905: need_use[need_use_count++] = entry_parm;
1906:
1907: locate_and_pad_parm (TYPE_MODE (passed_type), passed_type,
1908: #ifdef STACK_PARMS_IN_REG_PARM_AREA
1909: 1,
1910: #else
1911: entry_parm != 0,
1912: #endif
1913: thunk_fndecl,
1914: &stack_args_size, &stack_offset, &arg_size);
1915:
1916: /* REGNO (entry_parm);*/
1917: if (this_rtx == 0)
1918: {
1919: this_reg_rtx = entry_parm;
1920: if (!entry_parm)
1921: {
1922: rtx offset_rtx = ARGS_SIZE_RTX (stack_offset);
1923:
1924: rtx internal_arg_pointer, stack_parm;
1925:
1926: if ((ARG_POINTER_REGNUM == STACK_POINTER_REGNUM
1927: || ! (fixed_regs[ARG_POINTER_REGNUM]
1928: || ARG_POINTER_REGNUM == FRAME_POINTER_REGNUM)))
1929: internal_arg_pointer = copy_to_reg (virtual_incoming_args_rtx);
1930: else
1931: internal_arg_pointer = virtual_incoming_args_rtx;
1932:
1933: if (offset_rtx == const0_rtx)
1934: entry_parm = gen_rtx (MEM, TYPE_MODE (passed_type),
1935: internal_arg_pointer);
1936: else
1937: entry_parm = gen_rtx (MEM, TYPE_MODE (passed_type),
1938: gen_rtx (PLUS, Pmode,
1939: internal_arg_pointer,
1940: offset_rtx));
1941: }
1942:
1943: this_rtx = entry_parm;
1944: }
1945:
1946: FUNCTION_ARG_ADVANCE (args_so_far,
1947: TYPE_MODE (passed_type),
1948: passed_type,
1949: named);
1950: }
1951:
1952: fixed_this_rtx = plus_constant (this_rtx, delta);
1953: if (this_rtx != fixed_this_rtx)
1954: emit_move_insn (this_rtx, fixed_this_rtx);
1955:
1956: if (this_reg_rtx)
1957: emit_insn (gen_rtx (USE, VOIDmode, this_reg_rtx));
1958:
1959: emit_indirect_jump (XEXP (DECL_RTL (function), 0));
1960:
1961: while (need_use_count > 0)
1962: emit_insn (gen_rtx (USE, VOIDmode, need_use[--need_use_count]));
1963:
1964: expand_end_bindings (NULL, 1, 0);
1.1.1.2 ! root 1965: poplevel (0, 0, 1);
1.1 root 1966:
1967: /* From now on, allocate rtl in current_obstack, not in saveable_obstack.
1968: Note that that may have been done above, in save_for_inline_copying.
1969: The call to resume_temporary_allocation near the end of this function
1970: goes back to the usual state of affairs. */
1971:
1972: rtl_in_current_obstack ();
1973:
1974: insns = get_insns ();
1975:
1976: /* Copy any shared structure that should not be shared. */
1977:
1978: unshare_all_rtl (insns);
1979:
1.1.1.2 ! root 1980: /* Instantiate all virtual registers. */
! 1981:
! 1982: instantiate_virtual_regs (current_function_decl, get_insns ());
! 1983:
1.1 root 1984: /* We are no longer anticipating cse in this function, at least. */
1985:
1986: cse_not_expected = 1;
1987:
1988: /* Now we choose between stupid (pcc-like) register allocation
1989: (if we got the -noreg switch and not -opt)
1990: and smart register allocation. */
1991:
1992: if (optimize > 0) /* Stupid allocation probably won't work */
1993: obey_regdecls = 0; /* if optimizations being done. */
1994:
1995: regclass_init ();
1996:
1997: regclass (insns, max_reg_num ());
1998: if (obey_regdecls)
1999: {
2000: stupid_life_analysis (insns, max_reg_num (), NULL);
2001: failure = reload (insns, 0, NULL);
2002: }
2003: else
2004: {
2005: /* Do control and data flow analysis,
2006: and write some of the results to dump file. */
2007:
2008: flow_analysis (insns, max_reg_num (), NULL);
2009: local_alloc ();
2010: failure = global_alloc (NULL);
2011: }
2012:
2013: reload_completed = 1;
2014:
2015: #ifdef LEAF_REGISTERS
2016: leaf_function = 0;
2017: if (optimize > 0 && only_leaf_regs_used () && leaf_function_p ())
2018: leaf_function = 1;
2019: #endif
2020:
2021: /* If a machine dependent reorganization is needed, call it. */
2022: #ifdef MACHINE_DEPENDENT_REORG
2023: MACHINE_DEPENDENT_REORG (insns);
2024: #endif
2025:
2026: /* Now turn the rtl into assembler code. */
2027:
2028: {
2029: char *fnname = XSTR (XEXP (DECL_RTL (thunk_fndecl), 0), 0);
2030: assemble_start_function (thunk_fndecl, fnname);
2031: final (insns, asm_out_file, optimize, 0);
2032: assemble_end_function (thunk_fndecl, fnname);
2033: };
2034:
2035: exit_rest_of_compilation:
2036:
2037: reload_completed = 0;
2038:
2039: /* Cancel the effect of rtl_in_current_obstack. */
2040:
2041: resume_temporary_allocation ();
2042:
2043: decl_printable_name = save_decl_printable_name;
2044: current_function_decl = 0;
2045: }
2046:
2047: /* Code for synthesizing methods which have default semantics defined. */
2048:
2049: /* For the anonymous union in TYPE, return the member that is at least as
2050: large as the rest of the members, so we can copy it. */
2051: static tree
2052: largest_union_member (type)
2053: tree type;
2054: {
2055: tree f, type_size = TYPE_SIZE (type);
2056:
2057: for (f = TYPE_FIELDS (type); f; f = TREE_CHAIN (f))
1.1.1.2 ! root 2058: if (simple_cst_equal (DECL_SIZE (f), type_size) == 1)
1.1 root 2059: return f;
2060:
2061: /* We should always find one. */
2062: my_friendly_abort (323);
2063: return NULL_TREE;
2064: }
2065:
2066: /* Generate code for default X(X&) constructor. */
2067: void
1.1.1.2 ! root 2068: do_build_copy_constructor (fndecl)
1.1 root 2069: tree fndecl;
2070: {
2071: tree parm = TREE_CHAIN (DECL_ARGUMENTS (fndecl));
2072: tree t;
2073:
2074: clear_last_expr ();
2075: push_momentary ();
2076:
2077: if (TYPE_USES_VIRTUAL_BASECLASSES (current_class_type))
2078: parm = TREE_CHAIN (parm);
2079: parm = convert_from_reference (parm);
2080:
1.1.1.2 ! root 2081: if (TYPE_HAS_TRIVIAL_INIT_REF (current_class_type))
1.1 root 2082: {
2083: t = build (INIT_EXPR, void_type_node, C_C_D, parm);
2084: TREE_SIDE_EFFECTS (t) = 1;
2085: cplus_expand_expr_stmt (t);
2086: }
2087: else
2088: {
2089: tree fields = TYPE_FIELDS (current_class_type);
2090: int n_bases = CLASSTYPE_N_BASECLASSES (current_class_type);
2091: tree binfos = TYPE_BINFO_BASETYPES (current_class_type);
2092: int i;
2093:
2094: for (t = CLASSTYPE_VBASECLASSES (current_class_type); t;
2095: t = TREE_CHAIN (t))
2096: {
2097: tree basetype = BINFO_TYPE (t);
1.1.1.2 ! root 2098: tree p = convert_to_reference
! 2099: (build_reference_type (basetype), parm,
! 2100: CONV_IMPLICIT|CONV_CONST, LOOKUP_COMPLAIN, NULL_TREE);
1.1 root 2101: p = convert_from_reference (p);
2102: current_base_init_list = tree_cons (TYPE_NESTED_NAME (basetype),
2103: p, current_base_init_list);
2104: }
2105:
2106: for (i = 0; i < n_bases; ++i)
2107: {
2108: tree p, basetype = TREE_VEC_ELT (binfos, i);
2109: if (TREE_VIA_VIRTUAL (basetype))
1.1.1.2 ! root 2110: continue;
1.1 root 2111:
2112: basetype = BINFO_TYPE (basetype);
1.1.1.2 ! root 2113: p = convert_to_reference
! 2114: (build_reference_type (basetype), parm,
! 2115: CONV_IMPLICIT|CONV_CONST, LOOKUP_COMPLAIN, NULL_TREE);
1.1 root 2116: p = convert_from_reference (p);
2117: current_base_init_list = tree_cons (TYPE_NESTED_NAME (basetype),
2118: p, current_base_init_list);
2119: }
2120: for (; fields; fields = TREE_CHAIN (fields))
2121: {
2122: tree name, init, t;
1.1.1.2 ! root 2123: tree field = fields;
! 2124:
! 2125: if (TREE_CODE (field) != FIELD_DECL)
1.1 root 2126: continue;
1.1.1.2 ! root 2127: if (DECL_NAME (field))
1.1 root 2128: {
1.1.1.2 ! root 2129: if (VFIELD_NAME_P (DECL_NAME (field)))
1.1 root 2130: continue;
1.1.1.2 ! root 2131: if (VBASE_NAME_P (DECL_NAME (field)))
1.1 root 2132: continue;
2133:
2134: /* True for duplicate members. */
1.1.1.2 ! root 2135: if (IDENTIFIER_CLASS_VALUE (DECL_NAME (field)) != field)
1.1 root 2136: continue;
2137: }
1.1.1.2 ! root 2138: else if ((t = TREE_TYPE (field)) != NULL_TREE
1.1 root 2139: && TREE_CODE (t) == UNION_TYPE
2140: && ANON_AGGRNAME_P (TYPE_IDENTIFIER (t))
2141: && TYPE_FIELDS (t) != NULL_TREE)
1.1.1.2 ! root 2142: field = largest_union_member (t);
1.1 root 2143: else
2144: continue;
2145:
1.1.1.2 ! root 2146: init = build (COMPONENT_REF, TREE_TYPE (field), parm, field);
1.1 root 2147: init = build_tree_list (NULL_TREE, init);
2148:
2149: current_member_init_list
1.1.1.2 ! root 2150: = tree_cons (DECL_NAME (field), init, current_member_init_list);
1.1 root 2151: }
2152: current_member_init_list = nreverse (current_member_init_list);
1.1.1.2 ! root 2153: current_base_init_list = nreverse (current_base_init_list);
1.1 root 2154: setup_vtbl_ptr ();
2155: }
2156:
2157: pop_momentary ();
2158: }
2159:
2160: void
1.1.1.2 ! root 2161: do_build_assign_ref (fndecl)
1.1 root 2162: tree fndecl;
2163: {
2164: tree parm = TREE_CHAIN (DECL_ARGUMENTS (fndecl));
2165:
1.1.1.2 ! root 2166: clear_last_expr ();
1.1 root 2167: push_momentary ();
2168:
2169: parm = convert_from_reference (parm);
2170:
1.1.1.2 ! root 2171: if (TYPE_HAS_TRIVIAL_ASSIGN_REF (current_class_type))
1.1 root 2172: {
2173: tree t = build (MODIFY_EXPR, void_type_node, C_C_D, parm);
2174: TREE_SIDE_EFFECTS (t) = 1;
2175: cplus_expand_expr_stmt (t);
2176: }
2177: else
2178: {
2179: tree fields = TYPE_FIELDS (current_class_type);
2180: int n_bases = CLASSTYPE_N_BASECLASSES (current_class_type);
2181: tree binfos = TYPE_BINFO_BASETYPES (current_class_type);
2182: int i;
2183:
2184: for (i = 0; i < n_bases; ++i)
2185: {
2186: tree basetype = BINFO_TYPE (TREE_VEC_ELT (binfos, i));
2187: if (TYPE_HAS_ASSIGN_REF (basetype))
2188: {
1.1.1.2 ! root 2189: tree p = convert_to_reference
! 2190: (build_reference_type (basetype), parm,
! 2191: CONV_IMPLICIT|CONV_CONST, LOOKUP_COMPLAIN, NULL_TREE);
1.1 root 2192: p = convert_from_reference (p);
2193: p = build_member_call (TYPE_NESTED_NAME (basetype),
2194: ansi_opname [MODIFY_EXPR],
2195: build_tree_list (NULL_TREE, p));
2196: expand_expr_stmt (p);
2197: }
2198: }
2199: for (; fields; fields = TREE_CHAIN (fields))
2200: {
2201: tree comp, init, t;
1.1.1.2 ! root 2202: tree field = fields;
! 2203:
! 2204: if (TREE_CODE (field) != FIELD_DECL)
1.1 root 2205: continue;
1.1.1.2 ! root 2206: if (DECL_NAME (field))
1.1 root 2207: {
1.1.1.2 ! root 2208: if (VFIELD_NAME_P (DECL_NAME (field)))
1.1 root 2209: continue;
1.1.1.2 ! root 2210: if (VBASE_NAME_P (DECL_NAME (field)))
1.1 root 2211: continue;
2212:
2213: /* True for duplicate members. */
1.1.1.2 ! root 2214: if (IDENTIFIER_CLASS_VALUE (DECL_NAME (field)) != field)
1.1 root 2215: continue;
2216: }
1.1.1.2 ! root 2217: else if ((t = TREE_TYPE (field)) != NULL_TREE
1.1 root 2218: && TREE_CODE (t) == UNION_TYPE
2219: && ANON_AGGRNAME_P (TYPE_IDENTIFIER (t))
2220: && TYPE_FIELDS (t) != NULL_TREE)
1.1.1.2 ! root 2221: field = largest_union_member (t);
1.1 root 2222: else
2223: continue;
2224:
1.1.1.2 ! root 2225: comp = build (COMPONENT_REF, TREE_TYPE (field), C_C_D, field);
! 2226: init = build (COMPONENT_REF, TREE_TYPE (field), parm, field);
1.1 root 2227:
2228: expand_expr_stmt (build_modify_expr (comp, NOP_EXPR, init));
2229: }
2230: }
2231: c_expand_return (C_C_D);
2232: pop_momentary ();
2233: }
2234:
1.1.1.2 ! root 2235: void push_cp_function_context ();
! 2236: void pop_cp_function_context ();
! 2237:
1.1 root 2238: void
1.1.1.2 ! root 2239: synthesize_method (fndecl)
1.1 root 2240: tree fndecl;
2241: {
1.1.1.2 ! root 2242: int nested = (current_function_decl != NULL_TREE);
! 2243: tree context = decl_function_context (fndecl);
! 2244: char *f = input_filename;
! 2245: tree base = DECL_CLASS_CONTEXT (fndecl);
! 2246:
! 2247: if (nested)
! 2248: push_cp_function_context (context);
! 2249:
! 2250: input_filename = DECL_SOURCE_FILE (fndecl);
! 2251: interface_unknown = CLASSTYPE_INTERFACE_UNKNOWN (base);
! 2252: interface_only = CLASSTYPE_INTERFACE_ONLY (base);
! 2253: start_function (NULL_TREE, fndecl, NULL_TREE, NULL_TREE, 1);
1.1 root 2254: store_parm_decls ();
1.1.1.2 ! root 2255:
! 2256: if (DECL_NAME (fndecl) == ansi_opname[MODIFY_EXPR])
! 2257: do_build_assign_ref (fndecl);
! 2258: else if (DESTRUCTOR_NAME_P (DECL_ASSEMBLER_NAME (fndecl)))
! 2259: ;
! 2260: else
! 2261: {
! 2262: tree arg_chain = FUNCTION_ARG_CHAIN (fndecl);
! 2263: if (DECL_CONSTRUCTOR_FOR_VBASE_P (fndecl))
! 2264: arg_chain = TREE_CHAIN (arg_chain);
! 2265: if (arg_chain != void_list_node)
! 2266: do_build_copy_constructor (fndecl);
! 2267: else if (TYPE_NEEDS_CONSTRUCTING (current_class_type))
! 2268: setup_vtbl_ptr ();
! 2269: }
! 2270:
! 2271: finish_function (lineno, 0, nested);
! 2272:
! 2273: /* Do we really *want* to inline this function? */
! 2274: if (DECL_INLINE (fndecl))
! 2275: {
! 2276: /* Turn off DECL_INLINE for the moment so function_cannot_inline_p
! 2277: will check our size. */
! 2278: DECL_INLINE (fndecl) = 0;
! 2279: if (function_cannot_inline_p (fndecl) == 0)
! 2280: DECL_INLINE (fndecl) = 1;
! 2281: }
! 2282:
! 2283: input_filename = f;
! 2284: extract_interface_info ();
! 2285: if (nested)
! 2286: pop_cp_function_context (context);
1.1 root 2287: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.