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