|
|
1.1 root 1: /* Handle the hair of processing (but not expanding) inline functions.
1.1.1.2 root 2: Also manage function and variable name overloading.
1.1 root 3: Copyright (C) 1987, 1989, 1992 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 "cp-class.h"
33: #include "obstack.h"
34:
35: #define obstack_chunk_alloc xmalloc
36: #define obstack_chunk_free free
37:
38: /* TREE_LIST of the current inline functions that need to be
39: processed. */
40: struct pending_inline *pending_inlines;
41:
42: /* Obstack where we build text strings for overloading, etc. */
43: static struct obstack scratch_obstack;
44: static char *scratch_firstobj;
45:
46: # define OB_INIT() (scratch_firstobj ? (obstack_free (&scratch_obstack, scratch_firstobj), 0) : 0)
47: # define OB_PUTC(C) (obstack_1grow (&scratch_obstack, (C)))
48: # define OB_PUTC2(C1,C2) \
49: (obstack_1grow (&scratch_obstack, (C1)), obstack_1grow (&scratch_obstack, (C2)))
50: # define OB_PUTS(S) (obstack_grow (&scratch_obstack, (S), sizeof (S) - 1))
51: # define OB_PUTID(ID) \
52: (obstack_grow (&scratch_obstack, IDENTIFIER_POINTER (ID), \
53: IDENTIFIER_LENGTH (ID)))
54: # define OB_PUTCP(S) (obstack_grow (&scratch_obstack, (S), strlen (S)))
55: # define OB_FINISH() (obstack_1grow (&scratch_obstack, '\0'))
56:
57: /* Counter to help build parameter names in case they were omitted. */
58: static int dummy_name;
59: static int in_parmlist;
60:
61: /* This points to a safe place to resume processing in case an expression
62: generates an error while we're trying to format it. */
63: static int scratch_error_offset;
64:
65: static void dump_type (), dump_decl ();
66: static void dump_init (), dump_unary_op (), dump_binary_op ();
67:
68: #ifdef NO_AUTO_OVERLOAD
69: int is_overloaded ();
70: #endif
71:
72: void
73: init_method ()
74: {
75: gcc_obstack_init (&scratch_obstack);
76: scratch_firstobj = (char *)obstack_alloc (&scratch_obstack, 0);
77: }
78:
79: tree
80: make_anon_parm_name ()
81: {
82: char buf[32];
83:
84: sprintf (buf, ANON_PARMNAME_FORMAT, dummy_name++);
85: return get_identifier (buf);
86: }
87:
88: void
89: clear_anon_parm_name ()
90: {
91: /* recycle these names. */
92: dummy_name = 0;
93: }
94:
95: static void
96: dump_readonly_or_volatile (t)
97: tree t;
98: {
99: if (TYPE_READONLY (t))
100: OB_PUTS ("const ");
101: if (TYPE_VOLATILE (t))
102: OB_PUTS ("volatile ");
103: }
104:
105: static void
106: dump_aggr_type (t)
107: tree t;
108: {
109: tree name;
110: char *aggr_string;
111: char *context_string = 0;
112:
113: if (TYPE_READONLY (t))
114: OB_PUTS ("const ");
115: if (TYPE_VOLATILE (t))
116: OB_PUTS ("volatile ");
117: if (TREE_CODE (t) == ENUMERAL_TYPE)
118: aggr_string = "enum";
119: else if (TREE_CODE (t) == UNION_TYPE)
120: aggr_string = "union";
121: else if (TYPE_LANG_SPECIFIC (t) && CLASSTYPE_DECLARED_CLASS (t))
122: aggr_string = "class";
123: else
124: aggr_string = "struct";
125:
126: name = TYPE_NAME (t);
127:
128: if (TREE_CODE (name) == TYPE_DECL)
129: {
1.1.1.2 root 130: #if 0 /* not yet, should get fixed properly later */
131: if (DECL_CONTEXT (name))
132: context_string = TYPE_NAME_STRING (DECL_CONTEXT (name));
133: #else
1.1 root 134: if (DECL_LANG_SPECIFIC (name) && DECL_CLASS_CONTEXT (name))
135: context_string = TYPE_NAME_STRING (DECL_CLASS_CONTEXT (name));
1.1.1.2 root 136: #endif
1.1 root 137: name = DECL_NAME (name);
138: }
139:
140: obstack_grow (&scratch_obstack, aggr_string, strlen (aggr_string));
141: OB_PUTC (' ');
142: if (context_string)
143: {
1.1.1.2 root 144: obstack_grow (&scratch_obstack, context_string, strlen (context_string));
1.1 root 145: OB_PUTC2 (':', ':');
146: }
147: OB_PUTID (name);
148: }
149:
150: /* This must be large enough to hold any anonymous parm name. */
151: static char anon_buffer[sizeof (ANON_PARMNAME_FORMAT) + 20];
152: /* This must be large enough to hold any printed integer or floatingpoint value. */
153: static char digit_buffer[128];
154:
155: static void
156: dump_type_prefix (t, p)
157: tree t;
158: int *p;
159: {
160: int old_p = 0;
161:
162: if (t == NULL_TREE)
163: return;
164:
165: switch (TREE_CODE (t))
166: {
167: case ERROR_MARK:
168: sprintf (anon_buffer, ANON_PARMNAME_FORMAT, dummy_name++);
169: OB_PUTCP (anon_buffer);
170: break;
171:
172: case UNKNOWN_TYPE:
173: OB_PUTS ("<unknown type>");
174: return;
175:
176: case TREE_LIST:
177: dump_type (TREE_VALUE (t), &old_p);
178: if (TREE_CHAIN (t))
179: {
180: if (TREE_CHAIN (t) != void_list_node)
181: {
182: OB_PUTC (',');
183: dump_type (TREE_CHAIN (t), &old_p);
184: }
185: }
186: else OB_PUTS ("...");
187: return;
188:
189: case POINTER_TYPE:
190: *p += 1;
191: dump_type_prefix (TREE_TYPE (t), p);
192: while (*p)
193: {
194: OB_PUTC ('*');
195: *p -= 1;
196: }
197: if (TYPE_READONLY (t))
198: OB_PUTS ("const ");
199: if (TYPE_VOLATILE (t))
200: OB_PUTS ("volatile ");
201: return;
202:
203: case OFFSET_TYPE:
204: {
205: tree type = TREE_TYPE (t);
206: if (TREE_CODE (type) == FUNCTION_TYPE)
207: {
208: type = TREE_TYPE (type);
209: if (in_parmlist)
210: OB_PUTS ("auto ");
211: }
212:
213: dump_type_prefix (type, &old_p);
214:
215: OB_PUTC ('(');
216: dump_type (TYPE_OFFSET_BASETYPE (t), &old_p);
217: OB_PUTC2 (':', ':');
218: while (*p)
219: {
220: OB_PUTC ('*');
221: *p -= 1;
222: }
223: if (TYPE_READONLY (t) | TYPE_VOLATILE (t))
224: dump_readonly_or_volatile (t);
225: return;
226: }
227:
228: case METHOD_TYPE:
229: {
230: tree type = TREE_TYPE (t);
231: if (in_parmlist)
232: OB_PUTS ("auto ");
233:
234: dump_type_prefix (type, &old_p);
235:
236: OB_PUTC ('(');
237: dump_type (TYPE_METHOD_BASETYPE (t), &old_p);
238: OB_PUTC2 (':', ':');
239: while (*p)
240: {
241: OB_PUTC ('*');
242: *p -= 1;
243: }
244: if (TYPE_READONLY (t) | TYPE_VOLATILE (t))
245: dump_readonly_or_volatile (t);
246: return;
247: }
248:
249: case REFERENCE_TYPE:
250: dump_type_prefix (TREE_TYPE (t), p);
251: OB_PUTC ('&');
252: if (TYPE_READONLY (t) | TYPE_VOLATILE (t))
253: dump_readonly_or_volatile (t);
254: return;
255:
256: case ARRAY_TYPE:
257: if (TYPE_READONLY (t) | TYPE_VOLATILE (t))
258: dump_readonly_or_volatile (t);
259: dump_type_prefix (TREE_TYPE (t), p);
260: return;
261:
262: case FUNCTION_TYPE:
263: if (in_parmlist)
264: OB_PUTS ("auto ");
265: dump_type_prefix (TREE_TYPE (t), &old_p);
266: OB_PUTC ('(');
267: while (*p)
268: {
269: OB_PUTC ('*');
270: *p -= 1;
271: }
272: if (TYPE_READONLY (t) | TYPE_VOLATILE (t))
273: dump_readonly_or_volatile (t);
274: return;
275:
276: case IDENTIFIER_NODE:
277: OB_PUTID (t);
278: OB_PUTC (' ');
279: break;
280:
281: case RECORD_TYPE:
282: case UNION_TYPE:
283: case ENUMERAL_TYPE:
284: dump_aggr_type (t);
285: break;
286:
287: case TYPE_DECL:
288: if (TYPE_READONLY (t))
289: OB_PUTS ("const ");
290: if (TYPE_VOLATILE (t))
291: OB_PUTS ("volatile ");
292: OB_PUTID (DECL_NAME (t));
293: OB_PUTC (' ');
294: break;
295:
296: case INTEGER_TYPE:
297: #if 0
298: /* Normally, `unsigned' is part of the deal. Not so if it comes
299: with `const' or `volatile'. */
300: if (TYPE_MAIN_VARIANT (t) == unsigned_type (TYPE_MAIN_VARIANT (t))
301: && (TYPE_READONLY (t) || TYPE_VOLATILE (t)))
302: OB_PUTS ("unsigned ");
303: #endif
304: /* fall through. */
305: case REAL_TYPE:
306: case VOID_TYPE:
307: if (TYPE_READONLY (t))
308: OB_PUTS ("const ");
309: if (TYPE_VOLATILE (t))
310: OB_PUTS ("volatile ");
1.1.1.3 root 311: OB_PUTID (TYPE_IDENTIFIER (t));
1.1 root 312: OB_PUTC (' ');
313: break;
314:
315: default:
1.1.1.3 root 316: my_friendly_abort (65);
1.1 root 317: }
318: }
319:
320: static void
321: dump_type_suffix (t, p)
322: tree t;
323: int *p;
324: {
325: int old_p = 0;
326:
327: if (t == NULL_TREE)
328: return;
329:
330: switch (TREE_CODE (t))
331: {
332: case ERROR_MARK:
333: sprintf (anon_buffer, ANON_PARMNAME_FORMAT, dummy_name++);
334: OB_PUTCP (anon_buffer);
335: break;
336:
337: case UNKNOWN_TYPE:
338: return;
339:
340: case POINTER_TYPE:
341: dump_type_suffix (TREE_TYPE (t), p);
342: return;
343:
344: case OFFSET_TYPE:
345: {
346: tree type = TREE_TYPE (t);
347:
348: OB_PUTC (')');
349: if (TREE_CODE (type) == FUNCTION_TYPE)
350: {
351: #if 0
352: tree next_arg = TREE_CHAIN (TYPE_ARG_TYPES (type));
353: OB_PUTC ('(');
354: if (next_arg)
355: {
356: if (next_arg != void_list_node)
357: {
358: in_parmlist++;
359: dump_type (next_arg, &old_p);
360: in_parmlist--;
361: }
362: }
363: else OB_PUTS ("...");
364: OB_PUTC (')');
365: dump_type_suffix (TREE_TYPE (type), p);
366: #else
1.1.1.3 root 367: my_friendly_abort (66);
1.1 root 368: #endif
369: }
370: return;
371: }
372:
373: case METHOD_TYPE:
374: {
375: tree next_arg;
376: OB_PUTC (')');
377: next_arg = TREE_CHAIN (TYPE_ARG_TYPES (t));
378: OB_PUTC ('(');
379: if (next_arg)
380: {
381: if (next_arg != void_list_node)
382: {
383: in_parmlist++;
384: dump_type (next_arg, &old_p);
385: in_parmlist--;
386: }
387: }
388: else OB_PUTS ("...");
389: OB_PUTC (')');
390: dump_readonly_or_volatile (TREE_TYPE (TREE_VALUE (TYPE_ARG_TYPES (t))));
391: dump_type_suffix (TREE_TYPE (t), p);
392: return;
393: }
394:
395: case REFERENCE_TYPE:
396: dump_type_suffix (TREE_TYPE (t), p);
397: return;
398:
399: case ARRAY_TYPE:
400: dump_type_suffix (TREE_TYPE (t), p);
401: OB_PUTC2 ('[', ']');
402: return;
403:
404: case FUNCTION_TYPE:
405: OB_PUTC2 (')', '(');
406: if (TYPE_ARG_TYPES (t) && TYPE_ARG_TYPES (t) != void_list_node)
407: {
408: in_parmlist++;
409: dump_type (TYPE_ARG_TYPES (t), &old_p);
410: in_parmlist--;
411: }
412: OB_PUTC (')');
413: dump_type_suffix (TREE_TYPE (t), p);
414: return;
415:
416: case IDENTIFIER_NODE:
417: case RECORD_TYPE:
418: case UNION_TYPE:
419: case ENUMERAL_TYPE:
420: case TYPE_DECL:
421: case INTEGER_TYPE:
422: case REAL_TYPE:
423: case VOID_TYPE:
424: return;
425:
426: default:
1.1.1.3 root 427: my_friendly_abort (67);
1.1 root 428: }
429: }
430:
431: static void
432: dump_type (t, p)
433: tree t;
434: int *p;
435: {
436: int old_p = 0;
437:
438: if (t == NULL_TREE)
439: return;
440:
441: switch (TREE_CODE (t))
442: {
443: case ERROR_MARK:
444: sprintf (anon_buffer, ANON_PARMNAME_FORMAT, dummy_name++);
445: OB_PUTCP (anon_buffer);
446: break;
447:
448: case UNKNOWN_TYPE:
449: OB_PUTS ("<unknown type>");
450: return;
451:
452: case TREE_LIST:
453: dump_type (TREE_VALUE (t), &old_p);
454: if (TREE_CHAIN (t))
455: {
456: if (TREE_CHAIN (t) != void_list_node)
457: {
458: OB_PUTC (',');
459: dump_type (TREE_CHAIN (t), &old_p);
460: }
461: }
462: else OB_PUTS ("...");
463: return;
464:
465: case POINTER_TYPE:
466: if (TYPE_READONLY (t) | TYPE_VOLATILE (t))
467: dump_readonly_or_volatile (t);
468: *p += 1;
469: dump_type (TREE_TYPE (t), p);
470: while (*p)
471: {
472: OB_PUTC ('*');
473: *p -= 1;
474: }
475: return;
476:
477: case REFERENCE_TYPE:
478: if (TYPE_READONLY (t) | TYPE_VOLATILE (t))
479: dump_readonly_or_volatile (t);
480: dump_type (TREE_TYPE (t), p);
481: OB_PUTC ('&');
482: return;
483:
484: case ARRAY_TYPE:
485: if (TYPE_READONLY (t) | TYPE_VOLATILE (t))
486: dump_readonly_or_volatile (t);
487: dump_type (TREE_TYPE (t), p);
488: OB_PUTC2 ('[', ']');
489: return;
490:
491: case OFFSET_TYPE:
492: case METHOD_TYPE:
493: case FUNCTION_TYPE:
494: dump_type_prefix (t, p);
495: dump_type_suffix (t, p);
496: return;
497:
498: case IDENTIFIER_NODE:
499: OB_PUTID (t);
500: OB_PUTC (' ');
501: break;
502:
503: case RECORD_TYPE:
504: case UNION_TYPE:
505: case ENUMERAL_TYPE:
506: dump_aggr_type (t);
507: break;
508:
509: case TYPE_DECL:
510: if (TYPE_READONLY (t) | TYPE_VOLATILE (t))
511: dump_readonly_or_volatile (t);
512: OB_PUTID (DECL_NAME (t));
513: OB_PUTC (' ');
514: break;
515:
516: case INTEGER_TYPE:
517: /* Normally, `unsigned' is part of the deal. Not so if it comes
518: with `const' or `volatile'. */
519: if (TYPE_READONLY (t) | TYPE_VOLATILE (t))
520: dump_readonly_or_volatile (t);
521: #if 0
522: if (TYPE_MAIN_VARIANT (t) == unsigned_type (TYPE_MAIN_VARIANT (t))
523: && (TYPE_READONLY (t) | TYPE_VOLATILE (t)))
524: OB_PUTS ("unsigned ");
525: #endif
1.1.1.3 root 526: OB_PUTID (TYPE_IDENTIFIER (t));
1.1 root 527: OB_PUTC (' ');
528: break;
529:
530: case REAL_TYPE:
531: case VOID_TYPE:
532: if (TYPE_READONLY (t) | TYPE_VOLATILE (t))
533: dump_readonly_or_volatile (t);
1.1.1.3 root 534: OB_PUTID (TYPE_IDENTIFIER (t));
1.1 root 535: OB_PUTC (' ');
536: break;
537:
538: case TEMPLATE_TYPE_PARM:
539: OB_PUTS ("<template type parm ");
1.1.1.3 root 540: OB_PUTID (TYPE_IDENTIFIER (t));
1.1 root 541: OB_PUTC ('>');
542: break;
543:
544: case UNINSTANTIATED_P_TYPE:
545: OB_PUTID (DECL_NAME (UPT_TEMPLATE (t)));
546: OB_PUTS ("<...>");
547: break;
548:
549: default:
1.1.1.3 root 550: my_friendly_abort (68);
1.1 root 551: }
552: }
553:
554: static void
555: dump_decl (t)
556: tree t;
557: {
558: int p = 0;
559:
560: if (t == NULL_TREE)
561: return;
562:
563: switch (TREE_CODE (t))
564: {
565: case ERROR_MARK:
566: OB_PUTS (" /* decl error */ ");
567: break;
568:
569: case PARM_DECL:
570: dump_type_prefix (TREE_TYPE (t), &p);
571: if (DECL_NAME (t))
572: dump_decl (DECL_NAME (t));
573: else
574: {
575: sprintf (anon_buffer, ANON_PARMNAME_FORMAT, dummy_name++);
576: OB_PUTCP (anon_buffer);
577: break;
578: }
579: dump_type_suffix (TREE_TYPE (t), &p);
580: return;
581:
582: case CALL_EXPR:
583: dump_decl (TREE_OPERAND (t, 0));
584: OB_PUTC ('(');
585: in_parmlist++;
586: dump_decl (TREE_OPERAND (t, 1));
587: in_parmlist--;
588: t = tree_last (TYPE_ARG_TYPES (TREE_TYPE (t)));
589: if (!t || t != void_list_node)
590: OB_PUTS ("...");
591: OB_PUTC (')');
592: return;
593:
594: case ARRAY_REF:
595: dump_decl (TREE_OPERAND (t, 0));
596: OB_PUTC ('[');
597: dump_decl (TREE_OPERAND (t, 1));
598: OB_PUTC (']');
599: return;
600:
601: case TYPE_DECL:
602: OB_PUTID (DECL_NAME (t));
603: OB_PUTC (' ');
604: break;
605:
606: case TYPE_EXPR:
1.1.1.3 root 607: my_friendly_abort (69);
1.1 root 608: break;
609:
610: case IDENTIFIER_NODE:
1.1.1.2 root 611: if (t == ansi_opname[(int) TYPE_EXPR])
1.1 root 612: {
613: OB_PUTS ("operator ");
614: /* Not exactly IDENTIFIER_TYPE_VALUE. */
615: dump_type (TREE_TYPE (t), &p);
616: return;
617: }
618: else if (IDENTIFIER_OPNAME_P (t))
619: {
620: char *name_string = operator_name_string (t);
621: OB_PUTS ("operator ");
622: OB_PUTCP (name_string);
623: OB_PUTC (' ');
624: }
625: else
626: {
627: OB_PUTID (t);
628: OB_PUTC (' ');
629: }
630: break;
631:
632: case BIT_NOT_EXPR:
633: OB_PUTC2 ('~', ' ');
634: dump_decl (TREE_OPERAND (t, 0));
635: return;
636:
637: case SCOPE_REF:
638: OB_PUTID (TREE_OPERAND (t, 0));
639: OB_PUTC2 (':', ':');
640: dump_decl (TREE_OPERAND (t, 1));
641: return;
642:
643: case INDIRECT_REF:
644: OB_PUTC ('*');
645: dump_decl (TREE_OPERAND (t, 0));
646: return;
647:
648: case ADDR_EXPR:
649: OB_PUTC ('&');
650: dump_decl (TREE_OPERAND (t, 0));
651: return;
652:
653: default:
1.1.1.3 root 654: my_friendly_abort (70);
1.1 root 655: }
656: }
657:
658: static void
659: dump_init_list (l)
660: tree l;
661: {
662: while (l)
663: {
664: dump_init (TREE_VALUE (l));
665: if (TREE_CHAIN (l))
666: OB_PUTC (',');
667: l = TREE_CHAIN (l);
668: }
669: }
670:
671: static void
672: dump_init (t)
673: tree t;
674: {
675: int dummy;
676:
677: switch (TREE_CODE (t))
678: {
679: case VAR_DECL:
680: case PARM_DECL:
681: OB_PUTC (' ');
682: OB_PUTID (DECL_NAME (t));
683: OB_PUTC (' ');
684: break;
685:
686: case FUNCTION_DECL:
687: {
688: tree name = DECL_ASSEMBLER_NAME (t);
689:
690: if (DESTRUCTOR_NAME_P (name))
691: {
692: OB_PUTC2 (' ', '~');
693: OB_PUTID (DECL_NAME (t));
694: }
695: else if (IDENTIFIER_TYPENAME_P (name))
696: {
697: dummy = 0;
698: OB_PUTS ("operator ");
699: dump_type (TREE_TYPE (name), &dummy);
700: }
701: else if (IDENTIFIER_OPNAME_P (name))
702: {
703: char *name_string = operator_name_string (name);
704: OB_PUTS ("operator ");
705: OB_PUTCP (name_string);
706: OB_PUTC (' ');
707: }
708: else
709: {
710: OB_PUTC (' ');
711: OB_PUTID (DECL_NAME (t));
712: }
713: OB_PUTC (' ');
714: }
715: break;
716:
717: case CONST_DECL:
718: dummy = 0;
719: OB_PUTC2 ('(', '(');
720: dump_type (TREE_TYPE (t), &dummy);
721: OB_PUTC (')');
722: dump_init (DECL_INITIAL (t));
723: OB_PUTC (')');
724: return;
725:
726: case INTEGER_CST:
727: sprintf (digit_buffer, " %d ", TREE_INT_CST_LOW (t));
728: OB_PUTCP (digit_buffer);
729: break;
730:
731: case REAL_CST:
732: sprintf (digit_buffer, " %g ", TREE_REAL_CST (t));
733: OB_PUTCP (digit_buffer);
734: break;
735:
736: case STRING_CST:
737: {
738: char *p = TREE_STRING_POINTER (t);
739: int len = TREE_STRING_LENGTH (t) - 1;
740: int i;
741:
742: OB_PUTC ('\"');
743: for (i = 0; i < len; i++)
744: {
745: register char c = p[i];
746: if (c == '\"' || c == '\\')
747: OB_PUTC ('\\');
748: if (c >= ' ' && c < 0177)
749: OB_PUTC (c);
750: else
751: {
752: sprintf (digit_buffer, "\\%03o", c);
753: OB_PUTCP (digit_buffer);
754: }
755: }
756: OB_PUTC ('\"');
757: }
758: return;
759:
760: case COMPOUND_EXPR:
761: dump_binary_op (",", t, 1);
762: break;
763:
764: case COND_EXPR:
765: OB_PUTC ('(');
766: dump_init (TREE_OPERAND (t, 0));
767: OB_PUTS (" ? ");
768: dump_init (TREE_OPERAND (t, 1));
769: OB_PUTS (" : ");
770: dump_init (TREE_OPERAND (t, 2));
771: OB_PUTC (')');
772: return;
773:
774: case SAVE_EXPR:
775: if (TREE_HAS_CONSTRUCTOR (t))
776: {
777: dummy = 0;
778: OB_PUTS ("new ");
779: dump_type (TREE_TYPE (TREE_TYPE (t)), &dummy);
780: PARM_DECL_EXPR (t) = 1;
781: }
782: else
783: {
784: sorry ("operand of SAVE_EXPR not understood");
785: scratch_obstack.next_free
786: = obstack_base (&scratch_obstack) + scratch_error_offset;
787: }
788: return;
789:
790: case NEW_EXPR:
1.1.1.3 root 791: OB_PUTID (TYPE_IDENTIFIER (TREE_TYPE (t)));
1.1 root 792: OB_PUTC ('(');
793: dump_init_list (TREE_CHAIN (TREE_OPERAND (t, 1)));
794: OB_PUTC (')');
795: return;
796:
797: case CALL_EXPR:
798: OB_PUTC ('(');
799: dump_init (TREE_OPERAND (t, 0));
800: dump_init_list (TREE_OPERAND (t, 1));
801: OB_PUTC (')');
802: return;
803:
804: case WITH_CLEANUP_EXPR:
805: /* Note that this only works for G++ cleanups. If somebody
806: builds a general cleanup, there's no way to represent it. */
807: dump_init (TREE_OPERAND (t, 0));
808: return;
809:
810: case TARGET_EXPR:
811: /* Note that this only works for G++ target exprs. If somebody
812: builds a general TARGET_EXPR, there's no way to represent that
813: it initializes anything other that the parameter slot for the
814: default argument. */
815: dump_init (TREE_OPERAND (t, 1));
816: return;
817:
818: case MODIFY_EXPR:
819: case PLUS_EXPR:
820: case MINUS_EXPR:
821: case MULT_EXPR:
822: case TRUNC_DIV_EXPR:
823: case TRUNC_MOD_EXPR:
824: case MIN_EXPR:
825: case MAX_EXPR:
826: case LSHIFT_EXPR:
827: case RSHIFT_EXPR:
828: case BIT_IOR_EXPR:
829: case BIT_XOR_EXPR:
830: case BIT_AND_EXPR:
831: case BIT_ANDTC_EXPR:
832: case TRUTH_ANDIF_EXPR:
833: case TRUTH_ORIF_EXPR:
834: case LT_EXPR:
835: case LE_EXPR:
836: case GT_EXPR:
837: case GE_EXPR:
838: case EQ_EXPR:
839: case NE_EXPR:
840: dump_binary_op (opname_tab[(int) TREE_CODE (t)], t,
841: strlen (opname_tab[(int) TREE_CODE (t)]));
842: return;
843:
844: case CEIL_DIV_EXPR:
845: case FLOOR_DIV_EXPR:
846: case ROUND_DIV_EXPR:
847: dump_binary_op ("/", t, 1);
848: return;
849:
850: case CEIL_MOD_EXPR:
851: case FLOOR_MOD_EXPR:
852: case ROUND_MOD_EXPR:
853: dump_binary_op ("%", t, 1);
854: return;
855:
856: case COMPONENT_REF:
857: dump_binary_op (".", t, 1);
858: return;
859:
860: case CONVERT_EXPR:
861: dump_unary_op ("+", t, 1);
862: return;
863:
864: case ADDR_EXPR:
865: if (TREE_CODE (TREE_OPERAND (t, 0)) == FUNCTION_DECL
866: || TREE_CODE (TREE_OPERAND (t, 0)) == STRING_CST)
867: dump_init (TREE_OPERAND (t, 0));
868: else
869: dump_unary_op ("&", t, 1);
870: return;
871:
872: case INDIRECT_REF:
1.1.1.2 root 873: if (TREE_HAS_CONSTRUCTOR (t))
874: {
875: t = TREE_OPERAND (t, 0);
1.1.1.4 ! root 876: my_friendly_assert (TREE_CODE (t) == CALL_EXPR, 237);
1.1.1.2 root 877: dump_init (TREE_OPERAND (t, 0));
878: OB_PUTC ('(');
879: dump_init_list (TREE_CHAIN (TREE_OPERAND (t, 1)));
880: OB_PUTC (')');
881: }
882: else
883: dump_unary_op ("*", t, 1);
1.1 root 884: return;
885:
886: case NEGATE_EXPR:
887: case BIT_NOT_EXPR:
888: case TRUTH_NOT_EXPR:
889: case PREDECREMENT_EXPR:
890: case PREINCREMENT_EXPR:
891: dump_unary_op (opname_tab [(int)TREE_CODE (t)], t,
892: strlen (opname_tab[(int) TREE_CODE (t)]));
893: return;
894:
895: case POSTDECREMENT_EXPR:
896: case POSTINCREMENT_EXPR:
897: OB_PUTC ('(');
898: dump_init (TREE_OPERAND (t, 0));
899: OB_PUTCP (opname_tab[(int)TREE_CODE (t)]);
900: OB_PUTC (')');
901: return;
902:
903: case NOP_EXPR:
904: dummy = 0;
905: OB_PUTC2 ('(', '(');
906: dump_type (TREE_TYPE (t), &dummy);
907: OB_PUTC (')');
908: dump_init (TREE_OPERAND (t, 0));
909: OB_PUTC (')');
910: return;
911:
912: case CONSTRUCTOR:
913: OB_PUTC ('{');
914: dump_init_list (CONSTRUCTOR_ELTS (t));
915: OB_PUTC ('}');
916: return;
917:
918: /* This list is incomplete, but should suffice for now.
919: It is very important that `sorry' does not call
920: `report_error_function'. That could cause an infinite loop. */
921: default:
922: sorry ("`%s' not supported for default parameters",
923: tree_code_name[(int) TREE_CODE (t)]);
924:
925: /* fall through to ERROR_MARK... */
926: case ERROR_MARK:
927: scratch_obstack.next_free
928: = obstack_base (&scratch_obstack) + scratch_error_offset;
929: return;
930: }
931: }
932:
933: static void
934: dump_binary_op (opstring, t, len)
935: char *opstring;
936: tree t;
937: int len;
938: {
939: OB_PUTC ('(');
940: dump_init (TREE_OPERAND (t, 0));
941: OB_PUTC (' ');
942: OB_PUTCP (opstring);
943: OB_PUTC (' ');
944: dump_init (TREE_OPERAND (t, 1));
945: OB_PUTC (')');
946: }
947:
948: static void
949: dump_unary_op (opstring, t, len)
950: char *opstring;
951: tree t;
952: int len;
953: {
954: OB_PUTC ('(');
955: OB_PUTC (' ');
956: OB_PUTCP (opstring);
957: OB_PUTC (' ');
958: dump_init (TREE_OPERAND (t, 0));
959: OB_PUTC (')');
960: }
961:
962: /* Pretty printing for announce_function. CNAME is the TYPE_DECL for
963: the class that FNDECL belongs to, if we could not figure that out
964: from FNDECL itself. FNDECL is the declaration of the function we
965: are interested in seeing. PRINT_RET_TYPE_P is non-zero if we
966: should print the type that this function returns. */
967:
968: char *
969: fndecl_as_string (cname, fndecl, print_ret_type_p)
970: tree cname, fndecl;
971: int print_ret_type_p;
972: {
973: tree name = DECL_ASSEMBLER_NAME (fndecl);
974: tree fntype = TREE_TYPE (fndecl);
975: tree parmtypes = TYPE_ARG_TYPES (fntype);
976: int p = 0;
977: int spaces = 0;
978:
979: OB_INIT ();
980:
981: if (DECL_CLASS_CONTEXT (fndecl))
982: cname = TYPE_NAME (DECL_CLASS_CONTEXT (fndecl));
983:
1.1.1.4 ! root 984: if (DECL_STATIC_FUNCTION_P (fndecl))
! 985: OB_PUTS ("static ");
! 986:
1.1 root 987: if (print_ret_type_p && ! IDENTIFIER_TYPENAME_P (name))
988: {
989: dump_type_prefix (TREE_TYPE (fntype), &p);
990: OB_PUTC (' ');
991: }
1.1.1.4 ! root 992:
1.1 root 993: if (cname)
994: {
995: dump_type (cname, &p);
996: *((char *) obstack_next_free (&scratch_obstack) - 1) = ':';
997: OB_PUTC (':');
998: if (TREE_CODE (fntype) == METHOD_TYPE && parmtypes)
999: parmtypes = TREE_CHAIN (parmtypes);
1000: if (DECL_CONSTRUCTOR_FOR_VBASE_P (fndecl))
1001: /* Skip past "in_charge" identifier. */
1002: parmtypes = TREE_CHAIN (parmtypes);
1003: }
1004:
1005: if (DESTRUCTOR_NAME_P (name))
1006: {
1007: OB_PUTC ('~');
1008: parmtypes = TREE_CHAIN (parmtypes);
1009: dump_decl (DECL_NAME (fndecl));
1010: }
1011: else if (IDENTIFIER_TYPENAME_P (name))
1012: {
1013: /* This cannot use the hack that the operator's return
1014: type is stashed off of its name because it may be
1015: used for error reporting. In the case of conflicting
1016: declarations, both will have the same name, yet
1017: the types will be different, hence the TREE_TYPE field
1018: of the first name will be clobbered by the second. */
1019: OB_PUTS ("operator ");
1020: dump_type (TREE_TYPE (TREE_TYPE (fndecl)), &p);
1021: }
1022: else if (IDENTIFIER_OPNAME_P (name))
1023: {
1024: char *name_string = operator_name_string (name);
1025: OB_PUTS ("operator ");
1026: OB_PUTCP (name_string);
1027: OB_PUTC (' ');
1028: }
1029: else if (DECL_CONSTRUCTOR_P (fndecl))
1030: {
1031: #ifdef SOS
1032: if (TYPE_DYNAMIC (IDENTIFIER_TYPE_VALUE (cname)))
1033: {
1034: OB_PUTS ("dynamic ");
1035: parmtypes = TREE_CHAIN (parmtypes);
1036: }
1037: #endif
1038: dump_decl (DECL_NAME (fndecl));
1039: }
1040: else
1.1.1.4 ! root 1041: dump_decl (DECL_NAME (fndecl));
1.1 root 1042:
1043: OB_PUTC ('(');
1044: if (parmtypes)
1045: {
1046: in_parmlist++;
1047: if (parmtypes != void_list_node)
1048: spaces = 2;
1049: while (parmtypes && parmtypes != void_list_node)
1050: {
1051: char *last_space;
1052: dump_type (TREE_VALUE (parmtypes), &p);
1053: last_space = (char *)obstack_next_free (&scratch_obstack);
1054: while (last_space[-1] == ' ')
1055: last_space--;
1056: scratch_obstack.next_free = last_space;
1057: if (TREE_PURPOSE (parmtypes))
1058: {
1059: scratch_error_offset = obstack_object_size (&scratch_obstack);
1060: OB_PUTS (" (= ");
1061: dump_init (TREE_PURPOSE (parmtypes));
1062: OB_PUTC (')');
1063: }
1064: OB_PUTC2 (',', ' ');
1065: parmtypes = TREE_CHAIN (parmtypes);
1066: }
1067: in_parmlist--;
1068: }
1069:
1070: if (parmtypes)
1071: {
1072: if (spaces)
1073: scratch_obstack.next_free = obstack_next_free (&scratch_obstack)-spaces;
1074: }
1075: else
1076: OB_PUTS ("...");
1077:
1078: OB_PUTC (')');
1079:
1080: if (print_ret_type_p && ! IDENTIFIER_TYPENAME_P (name))
1081: dump_type_suffix (TREE_TYPE (fntype), &p);
1082:
1083: if (TREE_CODE (fntype) == METHOD_TYPE)
1084: dump_readonly_or_volatile (TREE_TYPE (TREE_VALUE (TYPE_ARG_TYPES (fntype))));
1085:
1086: OB_FINISH ();
1087:
1088: return (char *)obstack_base (&scratch_obstack);
1089: }
1090:
1091: /* Same, but handtype a _TYPE. */
1092: char *
1.1.1.4 ! root 1093: type_as_string (typ)
1.1 root 1094: tree typ;
1095: {
1096: int p = 0;
1097:
1098: OB_INIT ();
1099:
1100: dump_type(typ,&p);
1101:
1102: OB_FINISH ();
1103:
1104: return (char *)obstack_base (&scratch_obstack);
1105: }
1106:
1.1.1.4 ! root 1107: /* A cross between type_as_string and fndecl_as_string. */
! 1108: char *
! 1109: decl_as_string (decl)
! 1110: tree decl;
! 1111: {
! 1112: OB_INIT ();
! 1113:
! 1114: dump_decl(decl);
! 1115:
! 1116: OB_FINISH ();
! 1117:
! 1118: return (char *)obstack_base (&scratch_obstack);
! 1119: }
! 1120:
1.1.1.2 root 1121: /* Move inline function definitions out of structure so that they
1.1 root 1122: can be processed normally. CNAME is the name of the class
1123: we are working from, METHOD_LIST is the list of method lists
1124: of the structure. We delete friend methods here, after
1125: saving away their inline function definitions (if any). */
1126:
1127: void
1128: do_inline_function_hair (type, friend_list)
1129: tree type, friend_list;
1130: {
1131: tree method = TYPE_METHODS (type);
1132:
1133: if (method && TREE_CODE (method) == TREE_VEC)
1134: {
1135: if (TREE_VEC_ELT (method, 0))
1136: method = TREE_VEC_ELT (method, 0);
1137: else
1138: method = TREE_VEC_ELT (method, 1);
1139: }
1140:
1141: while (method)
1142: {
1143: /* Do inline member functions. */
1144: struct pending_inline *info = DECL_PENDING_INLINE_INFO (method);
1145: if (info)
1146: {
1147: tree args;
1148:
1.1.1.4 ! root 1149: my_friendly_assert (info->fndecl == method, 238);
1.1 root 1150: args = DECL_ARGUMENTS (method);
1151: while (args)
1152: {
1153: DECL_CONTEXT (args) = method;
1154: args = TREE_CHAIN (args);
1155: }
1156:
1157: /* Allow this decl to be seen in global scope */
1158: IDENTIFIER_GLOBAL_VALUE (DECL_ASSEMBLER_NAME (method)) = method;
1159: }
1160: method = TREE_CHAIN (method);
1161: }
1162: while (friend_list)
1163: {
1164: tree fndecl = TREE_VALUE (friend_list);
1165: struct pending_inline *info = DECL_PENDING_INLINE_INFO (fndecl);
1166: if (info)
1167: {
1168: tree args;
1169:
1.1.1.4 ! root 1170: my_friendly_assert (info->fndecl == fndecl, 239);
1.1 root 1171: args = DECL_ARGUMENTS (fndecl);
1172: while (args)
1173: {
1174: DECL_CONTEXT (args) = fndecl;
1175: args = TREE_CHAIN (args);
1176: }
1177:
1178: /* Allow this decl to be seen in global scope */
1179: IDENTIFIER_GLOBAL_VALUE (DECL_ASSEMBLER_NAME (fndecl)) = fndecl;
1180: }
1181:
1182: friend_list = TREE_CHAIN (friend_list);
1183: }
1184: }
1185:
1.1.1.4 ! root 1186: /* Report an argument type mismatch between the best declared function
1.1 root 1187: we could find and the current argument list that we have. */
1188: void
1189: report_type_mismatch (cp, parmtypes, name_kind, err_name)
1190: struct candidate *cp;
1191: tree parmtypes;
1192: char *name_kind, *err_name;
1193: {
1194: int i = cp->u.bad_arg;
1195: tree ttf, tta;
1196: char *tmp_firstobj;
1197:
1198: switch (i)
1199: {
1200: case -4:
1.1.1.4 ! root 1201: my_friendly_assert (TREE_CODE (cp->function) == TEMPLATE_DECL, 240);
1.1 root 1202: error ("type unification failed for function template `%s'", err_name);
1203: return;
1204:
1205: case -3:
1206: if (TYPE_READONLY (TREE_TYPE (TREE_VALUE (parmtypes))))
1207: error ("call to const %s `%s' with non-const object", name_kind, err_name);
1208: else
1209: error ("call to non-const %s `%s' with const object", name_kind, err_name);
1210: return;
1211: case -2:
1212: error ("too few arguments for %s `%s'", name_kind, err_name);
1213: return;
1214: case -1:
1215: error ("too many arguments for %s `%s'", name_kind, err_name);
1216: return;
1217: case 0:
1218: if (TREE_CODE (TREE_TYPE (cp->function)) == METHOD_TYPE)
1219: {
1220: /* Happens when we have an ambiguous base class. */
1.1.1.4 ! root 1221: my_friendly_assert (get_binfo (DECL_CLASS_CONTEXT (cp->function),
! 1222: TREE_TYPE (TREE_TYPE (TREE_VALUE (parmtypes))), 1) == error_mark_node,
! 1223: 241);
1.1 root 1224: return;
1225: }
1226: }
1227:
1228: ttf = TYPE_ARG_TYPES (TREE_TYPE (cp->function));
1229: tta = parmtypes;
1230:
1231: while (i-- > 0)
1232: {
1233: ttf = TREE_CHAIN (ttf);
1234: tta = TREE_CHAIN (tta);
1235: }
1236:
1237: OB_INIT ();
1238: OB_PUTS ("bad argument ");
1239: sprintf (digit_buffer, "%d",
1240: cp->u.bad_arg - (TREE_CODE (TREE_TYPE (cp->function)) == METHOD_TYPE));
1241: OB_PUTCP (digit_buffer);
1242: OB_PUTS (" for function `");
1243:
1244: tmp_firstobj = scratch_firstobj;
1245: scratch_firstobj = 0;
1246: fndecl_as_string (0, cp->function, 0);
1247: scratch_firstobj = tmp_firstobj;
1248:
1249: /* We know that the last char written is next_free-1. */
1250: ((char *) obstack_next_free (&scratch_obstack))[-1] = '\'';
1251: OB_PUTS (" (type was ");
1252:
1253: /* Reset `i' so that type printing routines do the right thing. */
1254: if (tta)
1255: {
1256: enum tree_code code = TREE_CODE (TREE_TYPE (TREE_VALUE (tta)));
1257: if (code == ERROR_MARK)
1.1.1.2 root 1258: OB_PUTS ("(failed type instantiation)");
1.1 root 1259: else
1260: {
1261: i = (code == FUNCTION_TYPE || code == METHOD_TYPE);
1262: dump_type (TREE_TYPE (TREE_VALUE (tta)), &i);
1263: }
1264: }
1265: else OB_PUTS ("void");
1266: OB_PUTC (')');
1267: OB_FINISH ();
1268:
1269: tmp_firstobj = (char *)alloca (obstack_object_size (&scratch_obstack));
1270: bcopy (obstack_base (&scratch_obstack), tmp_firstobj,
1271: obstack_object_size (&scratch_obstack));
1272: error (tmp_firstobj);
1273: }
1274:
1275: /* Here is where overload code starts. */
1276:
1277: /* Array of types seen so far in top-level call to `build_overload_name'.
1278: Allocated and deallocated by caller. */
1279: static tree *typevec;
1280:
1281: /* Number of types interned by `build_overload_name' so far. */
1282: static int maxtype;
1283:
1.1.1.2 root 1284: /* Number of occurrences of last type seen. */
1.1 root 1285: static int nrepeats;
1286:
1287: /* Nonzero if we should not try folding parameter types. */
1288: static int nofold;
1289:
1290: #define ALLOCATE_TYPEVEC(PARMTYPES) \
1291: do { maxtype = 0, nrepeats = 0; \
1292: typevec = (tree *)alloca (list_length (PARMTYPES) * sizeof (tree)); } while (0)
1293:
1294: #define DEALLOCATE_TYPEVEC(PARMTYPES) \
1295: do { tree t = (PARMTYPES); \
1296: while (t) { TREE_USED (TREE_VALUE (t)) = 0; t = TREE_CHAIN (t); } \
1297: } while (0)
1298:
1.1.1.3 root 1299: /* Code to concatenate an asciified integer to a string. */
1.1 root 1300: static
1301: #ifdef __GNUC__
1302: __inline
1303: #endif
1.1.1.3 root 1304: void
1.1 root 1305: icat (i)
1306: int i;
1307: {
1308: if (i < 0)
1309: {
1310: OB_PUTC ('m');
1311: i = -i;
1312: }
1313: if (i < 10)
1314: OB_PUTC ('0' + i);
1315: else
1316: {
1317: icat (i / 10);
1318: OB_PUTC ('0' + (i % 10));
1319: }
1320: }
1321:
1322: static
1323: #ifdef __GNUC__
1324: __inline
1325: #endif
1326: void
1327: flush_repeats (type)
1328: tree type;
1329: {
1330: int tindex = 0;
1331:
1332: while (typevec[tindex] != type)
1333: tindex++;
1334:
1335: if (nrepeats > 1)
1336: {
1337: OB_PUTC ('N');
1338: icat (nrepeats);
1339: if (nrepeats > 9)
1340: OB_PUTC ('_');
1341: }
1342: else
1343: OB_PUTC ('T');
1344: nrepeats = 0;
1345: icat (tindex);
1346: if (tindex > 9)
1347: OB_PUTC ('_');
1348: }
1349:
1350: static void build_overload_identifier ();
1351:
1352: static void
1353: build_overload_nested_name (context)
1354: tree context;
1355: {
1.1.1.4 ! root 1356: /* We use DECL_NAME here, because pushtag now sets the DECL_ASSEMBLER_NAME. */
! 1357: tree name = DECL_NAME (context);
1.1 root 1358: if (DECL_CONTEXT (context))
1359: {
1360: context = DECL_CONTEXT (context);
1361: if (TREE_CODE_CLASS (TREE_CODE (context)) == 't')
1362: context = TYPE_NAME (context);
1363: build_overload_nested_name (context);
1364: }
1365: build_overload_identifier (name);
1366: }
1367:
1368: static void
1369: build_overload_value (type, value)
1370: tree type, value;
1371: {
1372: while (TREE_CODE (value) == NON_LVALUE_EXPR)
1373: value = TREE_OPERAND (value, 0);
1.1.1.4 ! root 1374: my_friendly_assert (TREE_CODE (type) == PARM_DECL, 242);
1.1 root 1375: type = TREE_TYPE (type);
1376: switch (TREE_CODE (type))
1377: {
1378: case INTEGER_TYPE:
1379: case ENUMERAL_TYPE:
1380: {
1.1.1.4 ! root 1381: my_friendly_assert (TREE_CODE (value) == INTEGER_CST, 243);
! 1382: if (TYPE_PRECISION (value) == 2 * HOST_BITS_PER_WIDE_INT)
1.1 root 1383: {
1384: if (tree_int_cst_lt (value, integer_zero_node))
1385: {
1386: OB_PUTC ('m');
1387: value = build_int_2 (~ TREE_INT_CST_LOW (value),
1388: - TREE_INT_CST_HIGH (value));
1389: }
1.1.1.4 ! root 1390: if (TREE_INT_CST_HIGH (value)
! 1391: != (TREE_INT_CST_LOW (value) >> (HOST_BITS_PER_WIDE_INT - 1)))
1.1 root 1392: {
1393: /* need to print a DImode value in decimal */
1394: sorry ("conversion of long long as PT parameter");
1395: }
1396: /* else fall through to print in smaller mode */
1397: }
1.1.1.4 ! root 1398: /* Wordsize or smaller */
1.1 root 1399: icat (TREE_INT_CST_LOW (value));
1400: return;
1401: }
1402: #ifndef REAL_IS_NOT_DOUBLE
1403: case REAL_TYPE:
1404: {
1405: REAL_VALUE_TYPE val;
1406: char *bufp = digit_buffer;
1.1.1.4 ! root 1407: extern char *index ();
1.1 root 1408:
1.1.1.4 ! root 1409: my_friendly_assert (TREE_CODE (value) == REAL_CST, 244);
1.1 root 1410: val = TREE_REAL_CST (value);
1411: if (val < 0)
1412: {
1413: val = -val;
1414: *bufp++ = 'm';
1415: }
1416: sprintf (bufp, "%e", val);
1.1.1.4 ! root 1417: bufp = (char *) index (bufp, 'e');
1.1 root 1418: if (!bufp)
1.1.1.3 root 1419: strcat (digit_buffer, "e0");
1.1 root 1420: else
1421: {
1422: char *p;
1423: bufp++;
1424: if (*bufp == '-')
1425: {
1426: *bufp++ = 'm';
1427: }
1428: p = bufp;
1429: if (*p == '+')
1430: p++;
1431: while (*p == '0')
1432: p++;
1433: if (*p == 0)
1434: {
1435: *bufp++ = '0';
1436: *bufp = 0;
1437: }
1438: else if (p != bufp)
1439: {
1440: while (*p)
1441: *bufp++ = *p++;
1442: *bufp = 0;
1443: }
1444: }
1.1.1.3 root 1445: OB_PUTCP (digit_buffer);
1.1 root 1446: return;
1447: }
1448: #endif
1449: case POINTER_TYPE:
1450: value = TREE_OPERAND (value, 0);
1451: if (TREE_CODE (value) == VAR_DECL)
1452: {
1.1.1.4 ! root 1453: my_friendly_assert (DECL_NAME (value) != 0, 245);
1.1 root 1454: build_overload_identifier (DECL_NAME (value));
1455: return;
1456: }
1.1.1.3 root 1457: else if (TREE_CODE (value) == FUNCTION_DECL)
1458: {
1.1.1.4 ! root 1459: my_friendly_assert (DECL_NAME (value) != 0, 246);
1.1.1.3 root 1460: build_overload_identifier (DECL_NAME (value));
1461: return;
1462: }
1.1 root 1463: else
1.1.1.4 ! root 1464: my_friendly_abort (71);
! 1465: break; /* not really needed */
! 1466:
1.1 root 1467: default:
1468: sorry ("conversion of %s as PT parameter",
1469: tree_code_name [(int) TREE_CODE (type)]);
1.1.1.3 root 1470: my_friendly_abort (72);
1.1 root 1471: }
1472: }
1473:
1474: static void
1475: build_overload_identifier (name)
1476: tree name;
1477: {
1478: if (IDENTIFIER_TEMPLATE (name))
1479: {
1480: tree template, parmlist, arglist, tname;
1481: int i, nparms;
1482: template = IDENTIFIER_TEMPLATE (name);
1483: arglist = TREE_VALUE (template);
1484: template = TREE_PURPOSE (template);
1485: tname = DECL_NAME (template);
1486: parmlist = DECL_ARGUMENTS (template);
1487: nparms = TREE_VEC_LENGTH (parmlist);
1488: OB_PUTC ('t');
1489: icat (IDENTIFIER_LENGTH (tname));
1490: OB_PUTID (tname);
1491: icat (nparms);
1492: for (i = 0; i < nparms; i++)
1493: {
1494: tree parm = TREE_VEC_ELT (parmlist, i);
1495: tree arg = TREE_VEC_ELT (arglist, i);
1496: if (TREE_CODE (parm) == IDENTIFIER_NODE)
1497: {
1498: /* This parameter is a type. */
1499: OB_PUTC ('Z');
1500: build_overload_name (arg, 0, 0);
1501: }
1502: else
1503: {
1504: /* It's a PARM_DECL. */
1505: build_overload_name (TREE_TYPE (parm), 0, 0);
1506: build_overload_value (parm, arg);
1507: }
1508: }
1509: }
1510: else
1511: {
1512: icat (IDENTIFIER_LENGTH (name));
1513: OB_PUTID (name);
1514: }
1515: }
1516:
1517: /* Given a list of parameters in PARMTYPES, create an unambiguous
1518: overload string. Should distinguish any type that C (or C++) can
1519: distinguish. I.e., pointers to functions are treated correctly.
1520:
1521: Caller must deal with whether a final `e' goes on the end or not.
1522:
1523: Any default conversions must take place before this function
1524: is called.
1525:
1526: BEGIN and END control initialization and finalization of the
1527: obstack where we build the string. */
1528:
1529: char *
1530: build_overload_name (parmtypes, begin, end)
1531: tree parmtypes;
1532: int begin, end;
1533: {
1534: int just_one;
1535: tree parmtype;
1536:
1537: if (begin) OB_INIT ();
1538:
1539: if (just_one = (TREE_CODE (parmtypes) != TREE_LIST))
1540: {
1541: parmtype = parmtypes;
1542: goto only_one;
1543: }
1544:
1545: while (parmtypes)
1546: {
1547: parmtype = TREE_VALUE (parmtypes);
1548:
1549: only_one:
1550:
1551: if (! nofold)
1552: {
1553: if (! just_one)
1554: /* Every argument gets counted. */
1555: typevec[maxtype++] = parmtype;
1556:
1557: if (TREE_USED (parmtype))
1558: {
1559: if (! just_one && parmtype == typevec[maxtype-2])
1560: nrepeats++;
1561: else
1562: {
1563: if (nrepeats)
1564: flush_repeats (parmtype);
1565: if (! just_one && TREE_CHAIN (parmtypes)
1566: && parmtype == TREE_VALUE (TREE_CHAIN (parmtypes)))
1567: nrepeats++;
1568: else
1569: {
1570: int tindex = 0;
1571:
1572: while (typevec[tindex] != parmtype)
1573: tindex++;
1574: OB_PUTC ('T');
1575: icat (tindex);
1576: if (tindex > 9)
1577: OB_PUTC ('_');
1578: }
1579: }
1580: goto next;
1581: }
1582: if (nrepeats)
1583: flush_repeats (typevec[maxtype-2]);
1584: if (! just_one
1585: /* Only cache types which take more than one character. */
1586: && (parmtype != TYPE_MAIN_VARIANT (parmtype)
1587: || (TREE_CODE (parmtype) != INTEGER_TYPE
1588: && TREE_CODE (parmtype) != REAL_TYPE)))
1589: TREE_USED (parmtype) = 1;
1590: }
1591:
1592: if (TREE_READONLY (parmtype))
1593: OB_PUTC ('C');
1594: if (TREE_CODE (parmtype) == INTEGER_TYPE
1595: && TYPE_MAIN_VARIANT (parmtype) == unsigned_type (TYPE_MAIN_VARIANT (parmtype)))
1596: OB_PUTC ('U');
1597: if (TYPE_VOLATILE (parmtype))
1598: OB_PUTC ('V');
1599:
1600: switch (TREE_CODE (parmtype))
1601: {
1602: case OFFSET_TYPE:
1603: OB_PUTC ('O');
1604: build_overload_name (TYPE_OFFSET_BASETYPE (parmtype), 0, 0);
1605: OB_PUTC ('_');
1606: build_overload_name (TREE_TYPE (parmtype), 0, 0);
1607: break;
1608:
1609: case REFERENCE_TYPE:
1610: OB_PUTC ('R');
1611: goto more;
1612:
1613: case ARRAY_TYPE:
1614: #if PARM_CAN_BE_ARRAY_TYPE
1615: {
1616: tree length;
1617:
1618: OB_PUTC ('A');
1.1.1.2 root 1619: if (TYPE_DOMAIN (parmtype) == NULL_TREE)
1620: {
1621: error ("parameter type with unspecified array bounds invalid");
1622: icat (1);
1623: }
1624: else
1625: {
1626: length = array_type_nelts (parmtype);
1627: if (TREE_CODE (length) == INTEGER_CST)
1628: icat (TREE_INT_CST_LOW (length) + 1);
1629: }
1.1 root 1630: OB_PUTC ('_');
1631: goto more;
1632: }
1633: #else
1634: OB_PUTC ('P');
1635: goto more;
1636: #endif
1637:
1638: case POINTER_TYPE:
1639: OB_PUTC ('P');
1640: more:
1641: build_overload_name (TREE_TYPE (parmtype), 0, 0);
1642: break;
1643:
1644: case FUNCTION_TYPE:
1645: case METHOD_TYPE:
1646: {
1647: tree firstarg = TYPE_ARG_TYPES (parmtype);
1648: /* Otherwise have to implement reentrant typevecs,
1649: unmark and remark types, etc. */
1650: int old_nofold = nofold;
1651: nofold = 1;
1652:
1653: if (nrepeats)
1654: flush_repeats (typevec[maxtype-1]);
1655:
1656: /* @@ It may be possible to pass a function type in
1657: which is not preceded by a 'P'. */
1658: if (TREE_CODE (parmtype) == FUNCTION_TYPE)
1659: {
1660: OB_PUTC ('F');
1661: if (firstarg == NULL_TREE)
1662: OB_PUTC ('e');
1663: else if (firstarg == void_list_node)
1664: OB_PUTC ('v');
1665: else
1666: build_overload_name (firstarg, 0, 0);
1667: }
1668: else
1669: {
1670: int constp = TYPE_READONLY (TREE_TYPE (TREE_VALUE (firstarg)));
1671: int volatilep = TYPE_VOLATILE (TREE_TYPE (TREE_VALUE (firstarg)));
1672: OB_PUTC ('M');
1673: firstarg = TREE_CHAIN (firstarg);
1674:
1675: build_overload_name (TYPE_METHOD_BASETYPE (parmtype), 0, 0);
1676: if (constp)
1677: OB_PUTC ('C');
1678: if (volatilep)
1679: OB_PUTC ('V');
1680:
1.1.1.2 root 1681: /* For cfront 2.0 compatibility. */
1.1 root 1682: OB_PUTC ('F');
1683:
1684: if (firstarg == NULL_TREE)
1685: OB_PUTC ('e');
1686: else if (firstarg == void_list_node)
1687: OB_PUTC ('v');
1688: else
1689: build_overload_name (firstarg, 0, 0);
1690: }
1691:
1692: /* Separate args from return type. */
1693: OB_PUTC ('_');
1694: build_overload_name (TREE_TYPE (parmtype), 0, 0);
1695: nofold = old_nofold;
1696: break;
1697: }
1698:
1699: case INTEGER_TYPE:
1700: parmtype = TYPE_MAIN_VARIANT (parmtype);
1.1.1.4 ! root 1701: if (parmtype == integer_type_node
! 1702: || parmtype == unsigned_type_node)
! 1703: OB_PUTC ('i');
! 1704: else if (parmtype == long_integer_type_node
! 1705: || parmtype == long_unsigned_type_node)
! 1706: OB_PUTC ('l');
! 1707: else if (parmtype == short_integer_type_node
! 1708: || parmtype == short_unsigned_type_node)
! 1709: OB_PUTC ('s');
! 1710: else if (parmtype == signed_char_type_node)
1.1 root 1711: {
1.1.1.4 ! root 1712: OB_PUTC ('S');
1.1 root 1713: OB_PUTC ('c');
1714: }
1.1.1.4 ! root 1715: else if (parmtype == char_type_node
! 1716: || parmtype == unsigned_char_type_node)
! 1717: OB_PUTC ('c');
! 1718: else if (parmtype == wchar_type_node)
! 1719: OB_PUTC ('w');
! 1720: else if (parmtype == long_long_integer_type_node
! 1721: || parmtype == long_long_unsigned_type_node)
! 1722: OB_PUTC ('x');
! 1723: #if 0
! 1724: /* it would seem there is no way to enter these in source code,
! 1725: yet. (mrs) */
! 1726: else if (parmtype == long_long_long_integer_type_node
! 1727: || parmtype == long_long_long_unsigned_type_node)
! 1728: OB_PUTC ('q');
! 1729: #endif
! 1730: else
! 1731: my_friendly_abort (73);
1.1 root 1732: break;
1733:
1734: case REAL_TYPE:
1735: parmtype = TYPE_MAIN_VARIANT (parmtype);
1736: if (parmtype == long_double_type_node)
1737: OB_PUTC ('r');
1738: else if (parmtype == double_type_node)
1739: OB_PUTC ('d');
1740: else if (parmtype == float_type_node)
1741: OB_PUTC ('f');
1.1.1.3 root 1742: else my_friendly_abort (74);
1.1 root 1743: break;
1744:
1745: case VOID_TYPE:
1746: if (! just_one)
1747: {
1748: #if 0
1749: extern tree void_list_node;
1750:
1751: /* See if anybody is wasting memory. */
1.1.1.4 ! root 1752: my_friendly_assert (parmtypes == void_list_node, 247);
1.1 root 1753: #endif
1754: /* This is the end of a parameter list. */
1755: if (end) OB_FINISH ();
1756: return (char *)obstack_base (&scratch_obstack);
1757: }
1758: OB_PUTC ('v');
1759: break;
1760:
1761: case ERROR_MARK: /* not right, but nothing is anyway */
1762: break;
1763:
1764: /* have to do these */
1765: case UNION_TYPE:
1766: case RECORD_TYPE:
1767: if (! just_one)
1768: /* Make this type signature look incompatible
1769: with AT&T. */
1770: OB_PUTC ('G');
1771: goto common;
1772: case ENUMERAL_TYPE:
1773: common:
1774: {
1775: tree name = TYPE_NAME (parmtype);
1776: int i = 1;
1777:
1778: if (TREE_CODE (name) == TYPE_DECL)
1779: {
1780: tree context = name;
1781: while (DECL_CONTEXT (context))
1782: {
1783: i += 1;
1784: context = DECL_CONTEXT (context);
1785: if (TREE_CODE_CLASS (TREE_CODE (context)) == 't')
1786: context = TYPE_NAME (context);
1787: }
1788: name = DECL_NAME (name);
1789: }
1.1.1.4 ! root 1790: my_friendly_assert (TREE_CODE (name) == IDENTIFIER_NODE, 248);
1.1 root 1791: if (i > 1)
1792: {
1793: OB_PUTC ('Q');
1794: icat (i);
1795: build_overload_nested_name (TYPE_NAME (parmtype));
1796: }
1797: else
1798: build_overload_identifier (name);
1799: break;
1800: }
1801:
1802: case UNKNOWN_TYPE:
1803: /* This will take some work. */
1804: OB_PUTC ('?');
1805: break;
1806:
1807: case TEMPLATE_TYPE_PARM:
1808: case TEMPLATE_CONST_PARM:
1809: case UNINSTANTIATED_P_TYPE:
1810: /* We don't ever want this output, but it's inconvenient not to
1811: be able to build the string. This should cause assembler
1812: errors we'll notice. */
1813: {
1814: static int n;
1815: sprintf (digit_buffer, " *%d", n++);
1816: OB_PUTCP (digit_buffer);
1817: }
1818: break;
1819:
1820: default:
1.1.1.3 root 1821: my_friendly_abort (75);
1.1 root 1822: }
1823:
1824: next:
1825: if (just_one) break;
1826: parmtypes = TREE_CHAIN (parmtypes);
1827: }
1828: if (! just_one)
1829: {
1830: if (nrepeats)
1831: flush_repeats (typevec[maxtype-1]);
1832:
1833: /* To get here, parms must end with `...'. */
1834: OB_PUTC ('e');
1835: }
1836:
1837: if (end) OB_FINISH ();
1838: return (char *)obstack_base (&scratch_obstack);
1839: }
1840:
1841: /* Generate an identifier that encodes the (ANSI) exception TYPE. */
1842:
1843: /* This should be part of `ansi_opname', or at least be defined by the std. */
1844: #define EXCEPTION_NAME_PREFIX "__ex"
1845: #define EXCEPTION_NAME_LENGTH 4
1846:
1847: tree
1848: cplus_exception_name (type)
1849: tree type;
1850: {
1851: OB_INIT ();
1852: OB_PUTS (EXCEPTION_NAME_PREFIX);
1853: return get_identifier (build_overload_name (type, 0, 1));
1854: }
1855:
1856: /* Change the name of a function definition so that it may be
1857: overloaded. NAME is the name of the function to overload,
1858: PARMS is the parameter list (which determines what name the
1859: final function obtains).
1860:
1861: FOR_METHOD is 1 if this overload is being performed
1862: for a method, rather than a function type. It is 2 if
1863: this overload is being performed for a constructor. */
1864: tree
1.1.1.2 root 1865: build_decl_overload (dname, parms, for_method)
1866: tree dname;
1.1 root 1867: tree parms;
1868: int for_method;
1869: {
1.1.1.2 root 1870: char *name = IDENTIFIER_POINTER (dname);
1871:
1872: if (dname == ansi_opname[(int) NEW_EXPR]
1873: && parms != NULL_TREE
1874: && TREE_CODE (parms) == TREE_LIST
1875: && TREE_VALUE (parms) == sizetype
1876: && TREE_CHAIN (parms) == void_list_node)
1877: return get_identifier ("__builtin_new");
1878: else if (dname == ansi_opname[(int) DELETE_EXPR]
1879: && parms != NULL_TREE
1880: && TREE_CODE (parms) == TREE_LIST
1881: && TREE_VALUE (parms) == ptr_type_node
1882: && TREE_CHAIN (parms) == void_list_node)
1883: return get_identifier ("__builtin_delete");
1.1.1.4 ! root 1884: else if (dname == ansi_opname[(int) DELETE_EXPR]
! 1885: && parms != NULL_TREE
! 1886: && TREE_CODE (parms) == TREE_LIST
! 1887: && TREE_VALUE (parms) == ptr_type_node
! 1888: && TREE_CHAIN (parms) != NULL_TREE
! 1889: && TREE_CODE (TREE_CHAIN (parms)) == TREE_LIST
! 1890: && TREE_VALUE (TREE_CHAIN (parms)) == sizetype
! 1891: && TREE_CHAIN (TREE_CHAIN (parms)) == void_list_node)
! 1892: return get_identifier ("__builtin_delete");
1.1.1.2 root 1893:
1.1 root 1894: OB_INIT ();
1895: if (for_method != 2)
1896: OB_PUTCP (name);
1897: /* Otherwise, we can divine that this is a constructor,
1898: and figure out its name without any extra encoding. */
1899:
1900: OB_PUTC2 ('_', '_');
1901: if (for_method)
1902: {
1903: #if 0
1904: /* We can get away without doing this. */
1905: OB_PUTC ('M');
1906: #endif
1907: parms = temp_tree_cons (NULL_TREE, TREE_TYPE (TREE_VALUE (parms)), TREE_CHAIN (parms));
1908: }
1909: else
1910: OB_PUTC ('F');
1911:
1912: if (parms == NULL_TREE)
1913: OB_PUTC2 ('e', '\0');
1914: else if (parms == void_list_node)
1915: OB_PUTC2 ('v', '\0');
1916: else
1917: {
1918: ALLOCATE_TYPEVEC (parms);
1919: nofold = 0;
1920: if (for_method)
1921: {
1922: build_overload_name (TREE_VALUE (parms), 0, 0);
1923:
1924: typevec[maxtype++] = TREE_VALUE (parms);
1925: TREE_USED (TREE_VALUE (parms)) = 1;
1926:
1927: if (TREE_CHAIN (parms))
1928: build_overload_name (TREE_CHAIN (parms), 0, 1);
1929: else
1930: OB_PUTC2 ('e', '\0');
1931: }
1932: else
1933: build_overload_name (parms, 0, 1);
1934: DEALLOCATE_TYPEVEC (parms);
1935: }
1936: return get_identifier (obstack_base (&scratch_obstack));
1937: }
1938:
1939: /* Build an overload name for the type expression TYPE. */
1940: tree
1941: build_typename_overload (type)
1942: tree type;
1943: {
1944: OB_INIT ();
1.1.1.2 root 1945: OB_PUTID (ansi_opname[(int) TYPE_EXPR]);
1.1 root 1946:
1947: #if 0
1948: /* We can get away without doing this--it really gets
1949: overloaded later. */
1950: OB_PUTC2 ('_', '_');
1951: OB_PUTC ('M');
1952: #endif
1953: nofold = 1;
1954: build_overload_name (type, 0, 1);
1955: return get_identifier (obstack_base (&scratch_obstack));
1956: }
1957:
1958: #define T_DESC_FORMAT "TD$"
1959: #define I_DESC_FORMAT "ID$"
1960: #define M_DESC_FORMAT "MD$"
1961:
1962: /* Build an overload name for the type expression TYPE. */
1963: tree
1964: build_t_desc_overload (type)
1965: tree type;
1966: {
1967: OB_INIT ();
1968: OB_PUTS (T_DESC_FORMAT);
1969: nofold = 1;
1970:
1971: #if 0
1972: /* Use a different format if the type isn't defined yet. */
1973: if (TYPE_SIZE (type) == NULL_TREE)
1974: {
1975: char *p;
1976: int changed;
1977:
1978: for (p = tname; *p; p++)
1979: if (isupper (*p))
1980: {
1981: changed = 1;
1982: *p = tolower (*p);
1983: }
1.1.1.2 root 1984: /* If there's no change, we have an inappropriate T_DESC_FORMAT. */
1.1.1.4 ! root 1985: my_friendly_assert (changed != 0, 249);
1.1 root 1986: }
1987: #endif
1988:
1989: build_overload_name (type, 0, 1);
1990: return get_identifier (obstack_base (&scratch_obstack));
1991: }
1992:
1993: /* Top-level interface to explicit overload requests. Allow NAME
1994: to be overloaded. Error if NAME is already declared for the current
1.1.1.2 root 1995: scope. Warning if function is redundantly overloaded. */
1.1 root 1996:
1997: void
1998: declare_overloaded (name)
1999: tree name;
2000: {
2001: #ifdef NO_AUTO_OVERLOAD
2002: if (is_overloaded (name))
2003: warning ("function `%s' already declared overloaded",
2004: IDENTIFIER_POINTER (name));
2005: else if (IDENTIFIER_GLOBAL_VALUE (name))
2006: error ("overloading function `%s' that is already defined",
2007: IDENTIFIER_POINTER (name));
2008: else
2009: {
2010: TREE_OVERLOADED (name) = 1;
2011: IDENTIFIER_GLOBAL_VALUE (name) = build_tree_list (name, NULL_TREE);
2012: TREE_TYPE (IDENTIFIER_GLOBAL_VALUE (name)) = unknown_type_node;
2013: }
2014: #else
2015: if (current_lang_name == lang_name_cplusplus)
2016: {
2017: if (0)
2018: warning ("functions are implicitly overloaded in C++");
2019: }
2020: else if (current_lang_name == lang_name_c)
2021: error ("overloading function `%s' cannot be done in C language context");
2022: else
1.1.1.3 root 2023: my_friendly_abort (76);
1.1 root 2024: #endif
2025: }
2026:
2027: #ifdef NO_AUTO_OVERLOAD
2028: /* Check to see if NAME is overloaded. For first approximation,
2029: check to see if its TREE_OVERLOADED is set. This is used on
2030: IDENTIFIER nodes. */
2031: int
2032: is_overloaded (name)
2033: tree name;
2034: {
2035: /* @@ */
2036: return (TREE_OVERLOADED (name)
2037: && (! IDENTIFIER_CLASS_VALUE (name) || current_class_type == 0)
2038: && ! IDENTIFIER_LOCAL_VALUE (name));
2039: }
2040: #endif
2041:
2042: /* Given a tree_code CODE, and some arguments (at least one),
2043: attempt to use an overloaded operator on the arguments.
2044:
2045: For unary operators, only the first argument need be checked.
2046: For binary operators, both arguments may need to be checked.
2047:
2048: Member functions can convert class references to class pointers,
2049: for one-level deep indirection. More than that is not supported.
2050: Operators [](), ()(), and ->() must be member functions.
2051:
2052: We call function call building calls with nonzero complain if
2053: they are our only hope. This is true when we see a vanilla operator
2054: applied to something of aggregate type. If this fails, we are free to
2055: return `error_mark_node', because we will have reported the error.
2056:
2057: Operators NEW and DELETE overload in funny ways: operator new takes
2058: a single `size' parameter, and operator delete takes a pointer to the
2059: storage being deleted. When overloading these operators, success is
2060: assumed. If there is a failure, report an error message and return
2061: `error_mark_node'. */
2062:
2063: /* NOSTRICT */
2064: tree
2065: build_opfncall (code, flags, xarg1, xarg2, arg3)
2066: enum tree_code code;
1.1.1.4 ! root 2067: int flags;
! 2068: tree xarg1, xarg2, arg3;
1.1 root 2069: {
2070: tree rval = 0;
2071: tree arg1, arg2;
2072: tree type1, type2, fnname;
2073: tree fields1 = 0, parms = 0;
2074: tree global_fn;
2075: int try_second;
2076: int binary_is_unary;
2077:
2078: if (xarg1 == error_mark_node)
2079: return error_mark_node;
2080:
2081: if (code == COND_EXPR)
2082: {
2083: if (TREE_CODE (xarg2) == ERROR_MARK
2084: || TREE_CODE (arg3) == ERROR_MARK)
2085: return error_mark_node;
2086: }
2087: if (code == COMPONENT_REF)
2088: if (TREE_CODE (TREE_TYPE (xarg1)) == POINTER_TYPE)
2089: return rval;
2090:
2091: /* First, see if we can work with the first argument */
2092: type1 = TREE_TYPE (xarg1);
2093:
2094: /* Some tree codes have length > 1, but we really only want to
2095: overload them if their first argument has a user defined type. */
2096: switch (code)
2097: {
2098: case PREINCREMENT_EXPR:
2099: code = POSTINCREMENT_EXPR;
2100: binary_is_unary = 1;
2101: try_second = 0;
2102: break;
2103:
2104: case POSTDECREMENT_EXPR:
2105: code = PREDECREMENT_EXPR;
2106: binary_is_unary = 1;
2107: try_second = 0;
2108: break;
2109:
2110: case PREDECREMENT_EXPR:
2111: case POSTINCREMENT_EXPR:
2112: case COMPONENT_REF:
2113: binary_is_unary = 1;
2114: try_second = 0;
2115: break;
2116:
2117: /* ARRAY_REFs and CALL_EXPRs must overload successfully.
2118: If they do not, return error_mark_node instead of NULL_TREE. */
2119: case ARRAY_REF:
2120: if (xarg2 == error_mark_node)
2121: return error_mark_node;
2122: case CALL_EXPR:
2123: rval = error_mark_node;
2124: binary_is_unary = 0;
2125: try_second = 0;
2126: break;
2127:
2128: case NEW_EXPR:
2129: {
2130: /* For operators `new' (`delete'), only check visibility
2131: if we are in a constructor (destructor), and we are
2132: allocating for that constructor's (destructor's) type. */
2133:
1.1.1.2 root 2134: fnname = ansi_opname[(int) NEW_EXPR];
1.1 root 2135: if (flags & LOOKUP_GLOBAL)
2136: return build_overload_call (fnname, tree_cons (NULL_TREE, xarg2, arg3),
2137: flags & LOOKUP_COMPLAIN, 0);
2138:
2139: if (current_function_decl == NULL_TREE
2140: || !DECL_CONSTRUCTOR_P (current_function_decl)
2141: || current_class_type != TYPE_MAIN_VARIANT (type1))
2142: flags = LOOKUP_COMPLAIN;
2143: rval = build_method_call (build1 (NOP_EXPR, xarg1, error_mark_node),
2144: fnname, tree_cons (NULL_TREE, xarg2, arg3),
2145: NULL_TREE, flags);
2146: if (rval == error_mark_node)
2147: /* User might declare fancy operator new, but invoke it
2148: like standard one. */
2149: return rval;
2150:
2151: TREE_TYPE (rval) = xarg1;
2152: TREE_CALLS_NEW (rval) = 1;
2153: return rval;
2154: }
2155: break;
2156:
2157: case DELETE_EXPR:
2158: {
2159: /* See comment above. */
2160:
1.1.1.2 root 2161: fnname = ansi_opname[(int) DELETE_EXPR];
1.1 root 2162: if (flags & LOOKUP_GLOBAL)
1.1.1.4 ! root 2163: return build_overload_call (fnname,
! 2164: tree_cons (NULL_TREE, xarg1,
! 2165: build_tree_list (NULL_TREE, xarg2)),
1.1 root 2166: flags & LOOKUP_COMPLAIN, 0);
2167:
2168: if (current_function_decl == NULL_TREE
2169: || !DESTRUCTOR_NAME_P (DECL_ASSEMBLER_NAME (current_function_decl))
2170: || current_class_type != TYPE_MAIN_VARIANT (type1))
2171: flags = LOOKUP_COMPLAIN;
1.1.1.4 ! root 2172: rval = build_method_call (build1 (NOP_EXPR, TREE_TYPE (xarg1),
! 2173: error_mark_node),
! 2174: fnname, tree_cons (NULL_TREE, xarg1,
! 2175: build_tree_list (NULL_TREE, xarg2)),
1.1 root 2176: NULL_TREE, flags);
2177: /* This happens when the user mis-declares `operator delete'.
2178: Should now be impossible. */
1.1.1.4 ! root 2179: my_friendly_assert (rval != error_mark_node, 250);
1.1 root 2180: TREE_TYPE (rval) = void_type_node;
2181: return rval;
2182: }
2183: break;
2184:
2185: default:
2186: binary_is_unary = 0;
2187: try_second = tree_code_length [(int) code] == 2;
2188: if (try_second && xarg2 == error_mark_node)
2189: return error_mark_node;
2190: break;
2191: }
2192:
2193: if (try_second && xarg2 == error_mark_node)
2194: return error_mark_node;
2195:
2196: /* What ever it was, we do not know how to deal with it. */
2197: if (type1 == NULL_TREE)
2198: return rval;
2199:
2200: if (TREE_CODE (type1) == OFFSET_TYPE)
2201: type1 = TREE_TYPE (type1);
2202:
2203: if (TREE_CODE (type1) == REFERENCE_TYPE)
2204: {
2205: arg1 = convert_from_reference (xarg1);
2206: type1 = TREE_TYPE (arg1);
2207: }
2208: else
2209: {
2210: arg1 = xarg1;
2211: }
2212:
2213: if (!IS_AGGR_TYPE (type1))
2214: {
2215: /* Try to fail. First, fail if unary */
2216: if (! try_second)
2217: return rval;
2218: /* Second, see if second argument is non-aggregate. */
2219: type2 = TREE_TYPE (xarg2);
2220: if (TREE_CODE (type2) == OFFSET_TYPE)
2221: type2 = TREE_TYPE (type2);
2222: if (TREE_CODE (type2) == REFERENCE_TYPE)
2223: {
2224: arg2 = convert_from_reference (xarg2);
2225: type2 = TREE_TYPE (arg2);
2226: }
2227: else
2228: {
2229: arg2 = xarg2;
2230: }
2231:
2232: if (!IS_AGGR_TYPE (type2))
2233: return rval;
2234: try_second = 0;
2235: }
2236:
2237: if (try_second)
2238: {
2239: /* First arg may succeed; see whether second should. */
2240: type2 = TREE_TYPE (xarg2);
2241: if (TREE_CODE (type2) == OFFSET_TYPE)
2242: type2 = TREE_TYPE (type2);
2243: if (TREE_CODE (type2) == REFERENCE_TYPE)
2244: {
2245: arg2 = convert_from_reference (xarg2);
2246: type2 = TREE_TYPE (arg2);
2247: }
2248: else
2249: {
2250: arg2 = xarg2;
2251: }
2252:
2253: if (! IS_AGGR_TYPE (type2))
2254: try_second = 0;
2255: }
2256:
2257: if (type1 == unknown_type_node
2258: || (try_second && TREE_TYPE (xarg2) == unknown_type_node))
2259: {
2260: /* This will not be implemented in the forseeable future. */
2261: return rval;
2262: }
2263:
2264: if (code == MODIFY_EXPR)
1.1.1.4 ! root 2265: fnname = ansi_assopname[(int) TREE_CODE (arg3)];
1.1 root 2266: else
1.1.1.2 root 2267: fnname = ansi_opname[(int) code];
1.1 root 2268:
2269: global_fn = IDENTIFIER_GLOBAL_VALUE (fnname);
2270:
2271: /* This is the last point where we will accept failure. This
2272: may be too eager if we wish an overloaded operator not to match,
2273: but would rather a normal operator be called on a type-converted
2274: argument. */
2275:
2276: if (IS_AGGR_TYPE (type1))
2277: fields1 = lookup_fnfields (TYPE_BINFO (type1), fnname, 0);
2278:
2279: if (fields1 == NULL_TREE && global_fn == NULL_TREE)
2280: return rval;
2281:
2282: /* If RVAL winds up being `error_mark_node', we will return
2283: that... There is no way that normal semantics of these
2284: operators will succeed. */
2285:
1.1.1.2 root 2286: /* This argument may be an uncommitted OFFSET_REF. This is
1.1 root 2287: the case for example when dealing with static class members
2288: which are referenced from their class name rather than
2289: from a class instance. */
2290: if (TREE_CODE (xarg1) == OFFSET_REF
2291: && TREE_CODE (TREE_OPERAND (xarg1, 1)) == VAR_DECL)
2292: xarg1 = TREE_OPERAND (xarg1, 1);
2293: if (try_second && xarg2 && TREE_CODE (xarg2) == OFFSET_REF
2294: && TREE_CODE (TREE_OPERAND (xarg2, 1)) == VAR_DECL)
2295: xarg2 = TREE_OPERAND (xarg2, 1);
2296:
2297: if (global_fn)
2298: flags |= LOOKUP_GLOBAL;
2299:
2300: if (code == CALL_EXPR)
2301: {
2302: /* This can only be a member function. */
2303: return build_method_call (xarg1, fnname, xarg2,
2304: NULL_TREE, LOOKUP_NORMAL);
2305: }
2306: else if (tree_code_length[(int) code] == 1 || binary_is_unary)
2307: {
2308: parms = NULL_TREE;
2309: rval = build_method_call (xarg1, fnname, NULL_TREE, NULL_TREE, flags);
2310: }
2311: else if (code == COND_EXPR)
2312: {
1.1.1.4 ! root 2313: parms = tree_cons (0, xarg2, build_tree_list (NULL_TREE, arg3));
1.1 root 2314: rval = build_method_call (xarg1, fnname, parms, NULL_TREE, flags);
2315: }
2316: else if (code == METHOD_CALL_EXPR)
2317: {
2318: /* must be a member function. */
2319: parms = tree_cons (NULL_TREE, xarg2, arg3);
2320: return build_method_call (xarg1, fnname, parms, NULL_TREE, LOOKUP_NORMAL);
2321: }
2322: else if (fields1)
2323: {
2324: parms = build_tree_list (NULL_TREE, xarg2);
2325: rval = build_method_call (xarg1, fnname, parms, NULL_TREE, flags);
2326: }
2327: else
2328: {
2329: parms = tree_cons (NULL_TREE, xarg1,
2330: build_tree_list (NULL_TREE, xarg2));
2331: rval = build_overload_call (fnname, parms, flags & LOOKUP_COMPLAIN, 0);
2332: }
2333:
2334: /* If we did not win, do not lose yet, since type conversion may work. */
2335: if (TREE_CODE (rval) == ERROR_MARK)
2336: {
2337: if (flags & LOOKUP_COMPLAIN)
2338: return rval;
2339: return 0;
2340: }
2341:
2342: return rval;
2343: }
2344:
2345: /* This function takes an identifier, ID, and attempts to figure out what
2346: it means. There are a number of possible scenarios, presented in increasing
2347: order of hair:
2348:
2349: 1) not in a class's scope
2350: 2) in class's scope, member name of the class's method
2351: 3) in class's scope, but not a member name of the class
2352: 4) in class's scope, member name of a class's variable
2353:
2354: NAME is $1 from the bison rule. It is an IDENTIFIER_NODE.
2355: VALUE is $$ from the bison rule. It is the value returned by lookup_name ($1)
2356: yychar is the pending input character (suitably encoded :-).
2357:
2358: As a last ditch, try to look up the name as a label and return that
2359: address.
2360:
2361: Values which are declared as being of REFERENCE_TYPE are
2362: automatically dereferenced here (as a hack to make the
2363: compiler faster). */
2364:
2365: tree
2366: hack_identifier (value, name, yychar)
2367: tree value, name;
1.1.1.4 ! root 2368: int yychar;
1.1 root 2369: {
2370: tree type;
2371:
2372: if (TREE_CODE (value) == ERROR_MARK)
2373: {
2374: if (current_class_name)
2375: {
2376: tree fields = lookup_fnfields (TYPE_BINFO (current_class_type), name, 0);
2377: if (fields)
2378: {
2379: tree fndecl;
2380:
2381: fndecl = TREE_VALUE (fields);
1.1.1.4 ! root 2382: my_friendly_assert (TREE_CODE (fndecl) == FUNCTION_DECL, 251);
1.1 root 2383: if (DECL_CHAIN (fndecl) == NULL_TREE)
2384: {
2385: warning ("methods cannot be converted to function pointers");
2386: return fndecl;
2387: }
2388: else
2389: {
2390: error ("ambiguous request for method pointer `%s'",
2391: IDENTIFIER_POINTER (name));
2392: return error_mark_node;
2393: }
2394: }
2395: }
2396: if (flag_labels_ok && IDENTIFIER_LABEL_VALUE (name))
2397: {
2398: return IDENTIFIER_LABEL_VALUE (name);
2399: }
2400: return error_mark_node;
2401: }
2402:
2403: type = TREE_TYPE (value);
2404: if (TREE_CODE (value) == FIELD_DECL)
2405: {
2406: if (current_class_decl == NULL_TREE)
2407: {
2408: error ("request for member `%s' in static member function",
2409: IDENTIFIER_POINTER (DECL_NAME (value)));
2410: return error_mark_node;
2411: }
2412: TREE_USED (current_class_decl) = 1;
2413: if (yychar == '(')
2414: if (! ((TYPE_LANG_SPECIFIC (type)
2415: && TYPE_OVERLOADS_CALL_EXPR (type))
2416: || (TREE_CODE (type) == REFERENCE_TYPE
2417: && TYPE_LANG_SPECIFIC (TREE_TYPE (type))
2418: && TYPE_OVERLOADS_CALL_EXPR (TREE_TYPE (type))))
2419: && TREE_CODE (type) != FUNCTION_TYPE
2420: && TREE_CODE (type) != METHOD_TYPE
2421: && (TREE_CODE (type) != POINTER_TYPE
2422: || (TREE_CODE (TREE_TYPE (type)) != FUNCTION_TYPE
2423: && TREE_CODE (TREE_TYPE (type)) != METHOD_TYPE)))
2424: {
2425: error ("component `%s' is not a method",
2426: IDENTIFIER_POINTER (name));
2427: return error_mark_node;
2428: }
2429: /* Mark so that if we are in a constructor, and then find that
2430: this field was initialized by a base initializer,
2431: we can emit an error message. */
2432: TREE_USED (value) = 1;
2433: return build_component_ref (C_C_D, name, 0, 1);
2434: }
2435:
2436: if (TREE_CODE (value) == TREE_LIST)
2437: {
2438: tree t = value;
2439: while (t && TREE_CODE (t) == TREE_LIST)
2440: {
2441: assemble_external (TREE_VALUE (t));
2442: TREE_USED (t) = 1;
2443: t = TREE_CHAIN (t);
2444: }
2445: }
2446: else
2447: {
2448: assemble_external (value);
2449: TREE_USED (value) = 1;
2450: }
2451:
1.1.1.4 ! root 2452: if (TREE_CODE_CLASS (TREE_CODE (value)) == 'd' && DECL_NONLOCAL (value))
1.1 root 2453: {
2454: if (DECL_CLASS_CONTEXT (value) != current_class_type)
2455: {
2456: tree path;
2457: enum visibility_type visibility;
1.1.1.4 ! root 2458: register tree context
! 2459: = (TREE_CODE (value) == FUNCTION_DECL && DECL_VIRTUAL_P (value))
! 2460: ? DECL_CLASS_CONTEXT (value)
! 2461: : DECL_CONTEXT (value);
1.1 root 2462:
1.1.1.4 ! root 2463: get_base_distance (context, current_class_type, 0, &path);
1.1 root 2464: visibility = compute_visibility (path, value);
2465: if (visibility != visibility_public)
2466: {
2467: if (TREE_CODE (value) == VAR_DECL)
2468: error ("static member `%s' is from private base class",
2469: IDENTIFIER_POINTER (name));
2470: else
2471: error ("enum `%s' is from private base class",
2472: IDENTIFIER_POINTER (name));
2473: return error_mark_node;
2474: }
2475: }
2476: return value;
2477: }
2478: if (TREE_CODE (value) == TREE_LIST && TREE_NONLOCAL_FLAG (value))
2479: {
2480: if (type == 0)
2481: {
2482: error ("request for member `%s' is ambiguous in multiple inheritance lattice",
2483: IDENTIFIER_POINTER (name));
2484: return error_mark_node;
2485: }
2486:
2487: return value;
2488: }
2489:
2490: if (TREE_CODE (type) == REFERENCE_TYPE)
2491: {
1.1.1.4 ! root 2492: my_friendly_assert (TREE_CODE (value) == VAR_DECL
! 2493: || TREE_CODE (value) == PARM_DECL, 252);
1.1 root 2494: if (DECL_REFERENCE_SLOT (value))
2495: return DECL_REFERENCE_SLOT (value);
2496: }
2497: return value;
2498: }
2499:
2500:
2501: /* Given an object OF, and a type conversion operator COMPONENT
2502: build a call to the conversion operator, if a call is requested,
2503: or return the address (as a pointer to member function) if one is not.
2504:
2505: OF can be a TYPE_DECL or any kind of datum that would normally
2506: be passed to `build_component_ref'. It may also be NULL_TREE,
2507: in which case `current_class_type' and `current_class_decl'
2508: provide default values.
2509:
2510: BASETYPE_PATH, if non-null, is the path of basetypes
2511: to go through before we get the the instance of interest.
2512:
2513: PROTECT says whether we apply C++ scoping rules or not. */
2514: tree
2515: build_component_type_expr (of, component, basetype_path, protect)
2516: tree of, component, basetype_path;
2517: int protect;
2518: {
2519: tree cname = NULL_TREE;
2520: tree tmp, last;
2521: tree name;
2522: int flags = protect ? LOOKUP_NORMAL : LOOKUP_COMPLAIN;
2523:
1.1.1.4 ! root 2524: if (of)
! 2525: my_friendly_assert (IS_AGGR_TYPE (TREE_TYPE (of)), 253);
! 2526: my_friendly_assert (TREE_CODE (component) == TYPE_EXPR, 254);
1.1 root 2527:
2528: tmp = TREE_OPERAND (component, 0);
2529: last = NULL_TREE;
2530:
2531: while (tmp)
2532: {
2533: switch (TREE_CODE (tmp))
2534: {
2535: case CALL_EXPR:
2536: if (last)
2537: TREE_OPERAND (last, 0) = TREE_OPERAND (tmp, 0);
2538: else
2539: TREE_OPERAND (component, 0) = TREE_OPERAND (tmp, 0);
2540: if (TREE_OPERAND (tmp, 0)
2541: && TREE_OPERAND (tmp, 0) != void_list_node)
2542: {
2543: error ("operator <typename> requires empty parameter list");
2544: TREE_OPERAND (tmp, 0) = NULL_TREE;
2545: }
2546: last = groktypename (build_tree_list (TREE_TYPE (component),
2547: TREE_OPERAND (component, 0)));
2548: name = build_typename_overload (last);
2549: TREE_TYPE (name) = last;
2550:
2551: if (of && TREE_CODE (of) != TYPE_DECL)
2552: return build_method_call (of, name, NULL_TREE, NULL_TREE, flags);
2553: else if (of)
2554: {
2555: tree this_this;
2556:
2557: if (current_class_decl == NULL_TREE)
2558: {
2559: error ("object required for `operator <typename>' call");
2560: return error_mark_node;
2561: }
2562:
2563: this_this = convert_pointer_to (TREE_TYPE (of), current_class_decl);
2564: return build_method_call (this_this, name, NULL_TREE,
2565: NULL_TREE, flags | LOOKUP_NONVIRTUAL);
2566: }
2567: else if (current_class_decl)
2568: return build_method_call (tmp, name, NULL_TREE, NULL_TREE, flags);
2569:
2570: error ("object required for `operator <typename>' call");
2571: return error_mark_node;
2572:
2573: case INDIRECT_REF:
2574: case ADDR_EXPR:
2575: case ARRAY_REF:
2576: break;
2577:
2578: case SCOPE_REF:
1.1.1.4 ! root 2579: my_friendly_assert (cname == 0, 255);
1.1 root 2580: cname = TREE_OPERAND (tmp, 0);
2581: tmp = TREE_OPERAND (tmp, 1);
2582: break;
2583:
2584: default:
1.1.1.3 root 2585: my_friendly_abort (77);
1.1 root 2586: }
2587: last = tmp;
2588: tmp = TREE_OPERAND (tmp, 0);
2589: }
2590:
2591: last = groktypename (build_tree_list (TREE_TYPE (component), TREE_OPERAND (component, 0)));
2592: name = build_typename_overload (last);
2593: TREE_TYPE (name) = last;
2594: if (of && TREE_CODE (of) == TYPE_DECL)
2595: {
2596: if (cname == NULL_TREE)
2597: {
2598: cname = DECL_NAME (of);
2599: of = NULL_TREE;
2600: }
1.1.1.4 ! root 2601: else my_friendly_assert (cname == DECL_NAME (of), 256);
1.1 root 2602: }
2603:
2604: if (of)
2605: {
2606: tree this_this;
2607:
2608: if (current_class_decl == NULL_TREE)
2609: {
2610: error ("object required for `operator <typename>' call");
2611: return error_mark_node;
2612: }
2613:
2614: this_this = convert_pointer_to (TREE_TYPE (of), current_class_decl);
2615: return build_component_ref (this_this, name, 0, protect);
2616: }
2617: else if (cname)
2618: return build_offset_ref (cname, name);
2619: else if (current_class_name)
2620: return build_offset_ref (current_class_name, name);
2621:
2622: error ("object required for `operator <typename>' member reference");
2623: return error_mark_node;
2624: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.