Commit | Line | Data |
---|---|---|
a0f50fe0 C |
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 Free Software Foundation, Inc. | |
4 | Contributed by Michael Tiemann (tiemann@cygnus.com) | |
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 | { | |
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 | |
134 | if (DECL_LANG_SPECIFIC (name) && DECL_CLASS_CONTEXT (name)) | |
135 | context_string = TYPE_NAME_STRING (DECL_CLASS_CONTEXT (name)); | |
136 | #endif | |
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 | { | |
144 | obstack_grow (&scratch_obstack, context_string, strlen (context_string)); | |
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 "); | |
311 | OB_PUTID (TYPE_IDENTIFIER (t)); | |
312 | OB_PUTC (' '); | |
313 | break; | |
314 | ||
315 | default: | |
316 | my_friendly_abort (65); | |
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 | |
367 | my_friendly_abort (66); | |
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: | |
427 | my_friendly_abort (67); | |
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 | |
526 | OB_PUTID (TYPE_IDENTIFIER (t)); | |
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); | |
534 | OB_PUTID (TYPE_IDENTIFIER (t)); | |
535 | OB_PUTC (' '); | |
536 | break; | |
537 | ||
538 | case TEMPLATE_TYPE_PARM: | |
539 | OB_PUTS ("<template type parm "); | |
540 | OB_PUTID (TYPE_IDENTIFIER (t)); | |
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: | |
550 | my_friendly_abort (68); | |
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: | |
607 | my_friendly_abort (69); | |
608 | break; | |
609 | ||
610 | case IDENTIFIER_NODE: | |
611 | if (t == ansi_opname[(int) TYPE_EXPR]) | |
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: | |
654 | my_friendly_abort (70); | |
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: | |
791 | OB_PUTID (TYPE_IDENTIFIER (TREE_TYPE (t))); | |
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: | |
873 | if (TREE_HAS_CONSTRUCTOR (t)) | |
874 | { | |
875 | t = TREE_OPERAND (t, 0); | |
876 | my_friendly_assert (TREE_CODE (t) == CALL_EXPR, 237); | |
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); | |
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 | ||
984 | if (DECL_STATIC_FUNCTION_P (fndecl)) | |
985 | OB_PUTS ("static "); | |
986 | ||
987 | if (print_ret_type_p && ! IDENTIFIER_TYPENAME_P (name)) | |
988 | { | |
989 | dump_type_prefix (TREE_TYPE (fntype), &p); | |
990 | OB_PUTC (' '); | |
991 | } | |
992 | ||
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 | |
1041 | dump_decl (DECL_NAME (fndecl)); | |
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 * | |
1093 | type_as_string (typ) | |
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 | ||
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 | ||
1121 | /* Move inline function definitions out of structure so that they | |
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 | ||
1149 | my_friendly_assert (info->fndecl == method, 238); | |
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 | ||
1170 | my_friendly_assert (info->fndecl == fndecl, 239); | |
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 | \f | |
1186 | /* Report an argument type mismatch between the best declared function | |
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: | |
1201 | my_friendly_assert (TREE_CODE (cp->function) == TEMPLATE_DECL, 240); | |
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. */ | |
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); | |
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) | |
1258 | OB_PUTS ("(failed type instantiation)"); | |
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 | \f | |
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 | ||
1284 | /* Number of occurrences of last type seen. */ | |
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 | ||
1299 | /* Code to concatenate an asciified integer to a string. */ | |
1300 | static | |
1301 | #ifdef __GNUC__ | |
1302 | __inline | |
1303 | #endif | |
1304 | void | |
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 | { | |
1356 | /* We use DECL_NAME here, because pushtag now sets the DECL_ASSEMBLER_NAME. */ | |
1357 | tree name = DECL_NAME (context); | |
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); | |
1374 | my_friendly_assert (TREE_CODE (type) == PARM_DECL, 242); | |
1375 | type = TREE_TYPE (type); | |
1376 | switch (TREE_CODE (type)) | |
1377 | { | |
1378 | case INTEGER_TYPE: | |
1379 | case ENUMERAL_TYPE: | |
1380 | { | |
1381 | my_friendly_assert (TREE_CODE (value) == INTEGER_CST, 243); | |
1382 | if (TYPE_PRECISION (value) == 2 * HOST_BITS_PER_WIDE_INT) | |
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 | } | |
1390 | if (TREE_INT_CST_HIGH (value) | |
1391 | != (TREE_INT_CST_LOW (value) >> (HOST_BITS_PER_WIDE_INT - 1))) | |
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 | } | |
1398 | /* Wordsize or smaller */ | |
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; | |
1407 | extern char *index (); | |
1408 | ||
1409 | my_friendly_assert (TREE_CODE (value) == REAL_CST, 244); | |
1410 | val = TREE_REAL_CST (value); | |
1411 | if (val < 0) | |
1412 | { | |
1413 | val = -val; | |
1414 | *bufp++ = 'm'; | |
1415 | } | |
1416 | sprintf (bufp, "%e", val); | |
1417 | bufp = (char *) index (bufp, 'e'); | |
1418 | if (!bufp) | |
1419 | strcat (digit_buffer, "e0"); | |
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 | } | |
1445 | OB_PUTCP (digit_buffer); | |
1446 | return; | |
1447 | } | |
1448 | #endif | |
1449 | case POINTER_TYPE: | |
1450 | value = TREE_OPERAND (value, 0); | |
1451 | if (TREE_CODE (value) == VAR_DECL) | |
1452 | { | |
1453 | my_friendly_assert (DECL_NAME (value) != 0, 245); | |
1454 | build_overload_identifier (DECL_NAME (value)); | |
1455 | return; | |
1456 | } | |
1457 | else if (TREE_CODE (value) == FUNCTION_DECL) | |
1458 | { | |
1459 | my_friendly_assert (DECL_NAME (value) != 0, 246); | |
1460 | build_overload_identifier (DECL_NAME (value)); | |
1461 | return; | |
1462 | } | |
1463 | else | |
1464 | my_friendly_abort (71); | |
1465 | break; /* not really needed */ | |
1466 | ||
1467 | default: | |
1468 | sorry ("conversion of %s as PT parameter", | |
1469 | tree_code_name [(int) TREE_CODE (type)]); | |
1470 | my_friendly_abort (72); | |
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'); | |
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 | } | |
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 | ||
1681 | /* For cfront 2.0 compatibility. */ | |
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); | |
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) | |
1711 | { | |
1712 | OB_PUTC ('S'); | |
1713 | OB_PUTC ('c'); | |
1714 | } | |
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); | |
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'); | |
1742 | else my_friendly_abort (74); | |
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. */ | |
1752 | my_friendly_assert (parmtypes == void_list_node, 247); | |
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 | } | |
1790 | my_friendly_assert (TREE_CODE (name) == IDENTIFIER_NODE, 248); | |
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: | |
1821 | my_friendly_abort (75); | |
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 | \f | |
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 | \f | |
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 | |
1865 | build_decl_overload (dname, parms, for_method) | |
1866 | tree dname; | |
1867 | tree parms; | |
1868 | int for_method; | |
1869 | { | |
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"); | |
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"); | |
1893 | ||
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 (); | |
1945 | OB_PUTID (ansi_opname[(int) TYPE_EXPR]); | |
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 | } | |
1984 | /* If there's no change, we have an inappropriate T_DESC_FORMAT. */ | |
1985 | my_friendly_assert (changed != 0, 249); | |
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 | |
1995 | scope. Warning if function is redundantly overloaded. */ | |
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 | |
2023 | my_friendly_abort (76); | |
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 | \f | |
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; | |
2067 | int flags; | |
2068 | tree xarg1, xarg2, arg3; | |
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 | ||
2134 | fnname = ansi_opname[(int) NEW_EXPR]; | |
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 | ||
2161 | fnname = ansi_opname[(int) DELETE_EXPR]; | |
2162 | if (flags & LOOKUP_GLOBAL) | |
2163 | return build_overload_call (fnname, | |
2164 | tree_cons (NULL_TREE, xarg1, | |
2165 | build_tree_list (NULL_TREE, xarg2)), | |
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; | |
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)), | |
2176 | NULL_TREE, flags); | |
2177 | /* This happens when the user mis-declares `operator delete'. | |
2178 | Should now be impossible. */ | |
2179 | my_friendly_assert (rval != error_mark_node, 250); | |
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) | |
2265 | fnname = ansi_assopname[(int) TREE_CODE (arg3)]; | |
2266 | else | |
2267 | fnname = ansi_opname[(int) code]; | |
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 | ||
2286 | /* This argument may be an uncommitted OFFSET_REF. This is | |
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 | { | |
2313 | parms = tree_cons (0, xarg2, build_tree_list (NULL_TREE, arg3)); | |
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 | \f | |
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; | |
2368 | int yychar; | |
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); | |
2382 | my_friendly_assert (TREE_CODE (fndecl) == FUNCTION_DECL, 251); | |
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 | ||
2452 | if (TREE_CODE_CLASS (TREE_CODE (value)) == 'd' && DECL_NONLOCAL (value)) | |
2453 | { | |
2454 | if (DECL_CLASS_CONTEXT (value) != current_class_type) | |
2455 | { | |
2456 | tree path; | |
2457 | enum visibility_type visibility; | |
2458 | register tree context | |
2459 | = (TREE_CODE (value) == FUNCTION_DECL && DECL_VIRTUAL_P (value)) | |
2460 | ? DECL_CLASS_CONTEXT (value) | |
2461 | : DECL_CONTEXT (value); | |
2462 | ||
2463 | get_base_distance (context, current_class_type, 0, &path); | |
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 | { | |
2492 | my_friendly_assert (TREE_CODE (value) == VAR_DECL | |
2493 | || TREE_CODE (value) == PARM_DECL, 252); | |
2494 | if (DECL_REFERENCE_SLOT (value)) | |
2495 | return DECL_REFERENCE_SLOT (value); | |
2496 | } | |
2497 | return value; | |
2498 | } | |
2499 | ||
2500 | \f | |
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 | ||
2524 | if (of) | |
2525 | my_friendly_assert (IS_AGGR_TYPE (TREE_TYPE (of)), 253); | |
2526 | my_friendly_assert (TREE_CODE (component) == TYPE_EXPR, 254); | |
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: | |
2579 | my_friendly_assert (cname == 0, 255); | |
2580 | cname = TREE_OPERAND (tmp, 0); | |
2581 | tmp = TREE_OPERAND (tmp, 1); | |
2582 | break; | |
2583 | ||
2584 | default: | |
2585 | my_friendly_abort (77); | |
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 | } | |
2601 | else my_friendly_assert (cname == DECL_NAME (of), 256); | |
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 | } |