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