|
|
1.1 root 1: /* Language-dependent node constructors for parse phase of GNU compiler.
2: Copyright (C) 1987, 1988, 1992, 1993 Free Software Foundation, Inc.
3: Hacked by Michael Tiemann ([email protected])
4:
5: This file is part of GNU CC.
6:
7: GNU CC is free software; you can redistribute it and/or modify
8: it under the terms of the GNU General Public License as published by
9: the Free Software Foundation; either version 2, or (at your option)
10: any later version.
11:
12: GNU CC is distributed in the hope that it will be useful,
13: but WITHOUT ANY WARRANTY; without even the implied warranty of
14: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15: GNU General Public License for more details.
16:
17: You should have received a copy of the GNU General Public License
18: along with GNU CC; see the file COPYING. If not, write to
19: the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
20:
21: #include "config.h"
22: #include <stdio.h>
23: #include "obstack.h"
24: #include "tree.h"
25: #include "cp-tree.h"
26: #include "flags.h"
27:
28: #define CEIL(x,y) (((x) + (y) - 1) / (y))
29:
30: /* Return nonzero if REF is an lvalue valid for this language.
31: Lvalues can be assigned, unless they have TREE_READONLY.
32: Lvalues can have their address taken, unless they have DECL_REGISTER. */
33:
34: int
35: lvalue_p (ref)
36: tree ref;
37: {
38: if (! language_lvalue_valid (ref))
39: return 0;
40:
41: if (TREE_CODE (TREE_TYPE (ref)) == REFERENCE_TYPE)
42: return 1;
43:
44: if (ref == current_class_decl && flag_this_is_variable <= 0)
45: return 0;
46:
47: switch (TREE_CODE (ref))
48: {
49: /* preincrements and predecrements are valid lvals, provided
50: what they refer to are valid lvals. */
51: case PREINCREMENT_EXPR:
52: case PREDECREMENT_EXPR:
53: case COMPONENT_REF:
54: case SAVE_EXPR:
55: return lvalue_p (TREE_OPERAND (ref, 0));
56:
57: case STRING_CST:
58: return 1;
59:
60: case VAR_DECL:
61: if (TREE_READONLY (ref) && ! TREE_STATIC (ref)
62: && DECL_LANG_SPECIFIC (ref)
63: && DECL_IN_AGGR_P (ref))
64: return 0;
65: case INDIRECT_REF:
66: case ARRAY_REF:
67: case PARM_DECL:
68: case RESULT_DECL:
69: case ERROR_MARK:
70: if (TREE_CODE (TREE_TYPE (ref)) != FUNCTION_TYPE
71: && TREE_CODE (TREE_TYPE (ref)) != METHOD_TYPE)
72: return 1;
73: break;
74:
75: case WITH_CLEANUP_EXPR:
76: return lvalue_p (TREE_OPERAND (ref, 0));
77:
78: case TARGET_EXPR:
79: return 1;
80:
81: case CALL_EXPR:
82: if (TREE_ADDRESSABLE (TREE_TYPE (ref)))
83: return 1;
84: break;
85:
86: /* A currently unresolved scope ref. */
87: case SCOPE_REF:
88: my_friendly_abort (103);
89: case OFFSET_REF:
90: if (TREE_CODE (TREE_OPERAND (ref, 1)) == FUNCTION_DECL)
91: return 1;
92: return lvalue_p (TREE_OPERAND (ref, 0))
93: && lvalue_p (TREE_OPERAND (ref, 1));
94: break;
95:
96: case COND_EXPR:
97: return (lvalue_p (TREE_OPERAND (ref, 1))
98: && lvalue_p (TREE_OPERAND (ref, 2)));
99:
100: case MODIFY_EXPR:
101: return 1;
102:
103: case COMPOUND_EXPR:
104: return lvalue_p (TREE_OPERAND (ref, 1));
105: }
106:
107: return 0;
108: }
109:
110: /* Return nonzero if REF is an lvalue valid for this language;
111: otherwise, print an error message and return zero. */
112:
113: int
114: lvalue_or_else (ref, string)
115: tree ref;
116: char *string;
117: {
118: int win = lvalue_p (ref);
119: if (! win)
120: error ("non-lvalue in %s", string);
121: return win;
122: }
123:
124: /* INIT is a CALL_EXPR which needs info about its target.
125: TYPE is the type that this initialization should appear to have.
126:
127: Build an encapsulation of the initialization to perform
128: and return it so that it can be processed by language-independent
129: and language-specific expression expanders.
130:
131: If WITH_CLEANUP_P is nonzero, we build a cleanup for this expression.
132: Otherwise, cleanups are not built here. For example, when building
133: an initialization for a stack slot, since the called function handles
134: the cleanup, we would not want to do it here. */
135: tree
136: build_cplus_new (type, init, with_cleanup_p)
137: tree type;
138: tree init;
139: int with_cleanup_p;
140: {
141: tree slot = build (VAR_DECL, type);
142: tree rval = build (NEW_EXPR, type,
143: TREE_OPERAND (init, 0), TREE_OPERAND (init, 1), slot);
144: TREE_SIDE_EFFECTS (rval) = 1;
145: TREE_ADDRESSABLE (rval) = 1;
146: rval = build (TARGET_EXPR, type, slot, rval, 0);
147: TREE_SIDE_EFFECTS (rval) = 1;
148: TREE_ADDRESSABLE (rval) = 1;
149:
150: #if 0
151: if (with_cleanup_p && TYPE_NEEDS_DESTRUCTOR (type))
152: {
153: TREE_OPERAND (rval, 2) = error_mark_node;
154: rval = build (WITH_CLEANUP_EXPR, type, rval, 0,
155: build_delete (TYPE_POINTER_TO (type),
156: build_unary_op (ADDR_EXPR, slot, 0),
157: integer_two_node,
158: LOOKUP_NORMAL|LOOKUP_DESTRUCTOR, 0));
159: TREE_SIDE_EFFECTS (rval) = 1;
160: TREE_ADDRESSABLE (rval) = 1;
161: }
162: #endif
163: return rval;
164: }
165:
166: /* Recursively search EXP for CALL_EXPRs that need cleanups and replace
167: these CALL_EXPRs with tree nodes that will perform the cleanups. */
168:
169: tree
170: break_out_cleanups (exp)
171: tree exp;
172: {
173: tree tmp = exp;
174:
175: if (TREE_CODE (tmp) == CALL_EXPR
176: && TYPE_NEEDS_DESTRUCTOR (TREE_TYPE (tmp)))
177: return build_cplus_new (TREE_TYPE (tmp), tmp, 1);
178:
179: while (TREE_CODE (tmp) == NOP_EXPR
180: || TREE_CODE (tmp) == CONVERT_EXPR
181: || TREE_CODE (tmp) == NON_LVALUE_EXPR)
182: {
183: if (TREE_CODE (TREE_OPERAND (tmp, 0)) == CALL_EXPR
184: && TYPE_NEEDS_DESTRUCTOR (TREE_TYPE (TREE_OPERAND (tmp, 0))))
185: {
186: TREE_OPERAND (tmp, 0)
187: = build_cplus_new (TREE_TYPE (TREE_OPERAND (tmp, 0)),
188: TREE_OPERAND (tmp, 0), 1);
189: break;
190: }
191: else
192: tmp = TREE_OPERAND (tmp, 0);
193: }
194: return exp;
195: }
196:
197: /* Recursively perform a preorder search EXP for CALL_EXPRs, making
198: copies where they are found. Returns a deep copy all nodes transitively
199: containing CALL_EXPRs. */
200:
201: tree
202: break_out_calls (exp)
203: tree exp;
204: {
205: register tree t1, t2;
206: register enum tree_code code;
207: register int changed = 0;
208: register int i;
209:
210: if (exp == NULL_TREE)
211: return exp;
212:
213: code = TREE_CODE (exp);
214:
215: if (code == CALL_EXPR)
216: return copy_node (exp);
217:
218: /* Don't try and defeat a save_expr, as it should only be done once. */
219: if (code == SAVE_EXPR)
220: return exp;
221:
222: switch (TREE_CODE_CLASS (code))
223: {
224: default:
225: abort ();
226:
227: case 'c': /* a constant */
228: case 't': /* a type node */
229: case 'x': /* something random, like an identifier or an ERROR_MARK. */
230: return exp;
231:
232: case 'd': /* A decl node */
233: #if 0 /* This is bogus. jason 9/21/94 */
234:
235: t1 = break_out_calls (DECL_INITIAL (exp));
236: if (t1 != DECL_INITIAL (exp))
237: {
238: exp = copy_node (exp);
239: DECL_INITIAL (exp) = t1;
240: }
241: #endif
242: return exp;
243:
244: case 'b': /* A block node */
245: {
246: /* Don't know how to handle these correctly yet. Must do a
247: break_out_calls on all DECL_INITIAL values for local variables,
248: and also break_out_calls on all sub-blocks and sub-statements. */
249: abort ();
250: }
251: return exp;
252:
253: case 'e': /* an expression */
254: case 'r': /* a reference */
255: case 's': /* an expression with side effects */
256: for (i = tree_code_length[(int) code] - 1; i >= 0; i--)
257: {
258: t1 = break_out_calls (TREE_OPERAND (exp, i));
259: if (t1 != TREE_OPERAND (exp, i))
260: {
261: exp = copy_node (exp);
262: TREE_OPERAND (exp, i) = t1;
263: }
264: }
265: return exp;
266:
267: case '<': /* a comparison expression */
268: case '2': /* a binary arithmetic expression */
269: t2 = break_out_calls (TREE_OPERAND (exp, 1));
270: if (t2 != TREE_OPERAND (exp, 1))
271: changed = 1;
272: case '1': /* a unary arithmetic expression */
273: t1 = break_out_calls (TREE_OPERAND (exp, 0));
274: if (t1 != TREE_OPERAND (exp, 0))
275: changed = 1;
276: if (changed)
277: {
278: if (tree_code_length[(int) code] == 1)
279: return build1 (code, TREE_TYPE (exp), t1);
280: else
281: return build (code, TREE_TYPE (exp), t1, t2);
282: }
283: return exp;
284: }
285:
286: }
287:
288: extern struct obstack *current_obstack;
289: extern struct obstack permanent_obstack, class_obstack;
290: extern struct obstack *saveable_obstack;
291:
292: /* Here is how primitive or already-canonicalized types' hash
293: codes are made. MUST BE CONSISTENT WITH tree.c !!! */
294: #define TYPE_HASH(TYPE) ((HOST_WIDE_INT) (TYPE) & 0777777)
295:
296: /* Construct, lay out and return the type of methods belonging to class
297: BASETYPE and whose arguments are described by ARGTYPES and whose values
298: are described by RETTYPE. If each type exists already, reuse it. */
299: tree
300: build_cplus_method_type (basetype, rettype, argtypes)
301: tree basetype, rettype, argtypes;
302: {
303: register tree t;
304: tree ptype;
305: int hashcode;
306:
307: /* Make a node of the sort we want. */
308: t = make_node (METHOD_TYPE);
309:
310: TYPE_METHOD_BASETYPE (t) = TYPE_MAIN_VARIANT (basetype);
311: TREE_TYPE (t) = rettype;
312: if (IS_SIGNATURE (basetype))
313: ptype = build_signature_pointer_type (TYPE_MAIN_VARIANT (basetype),
314: TYPE_READONLY (basetype),
315: TYPE_VOLATILE (basetype));
316: else
317: {
318: ptype = build_pointer_type (basetype);
319: ptype = build_type_variant (ptype, 1, 0);
320: }
321: /* The actual arglist for this function includes a "hidden" argument
322: which is "this". Put it into the list of argument types. */
323:
324: argtypes = tree_cons (NULL_TREE, ptype, argtypes);
325: TYPE_ARG_TYPES (t) = argtypes;
326: TREE_SIDE_EFFECTS (argtypes) = 1; /* Mark first argtype as "artificial". */
327:
328: /* If we already have such a type, use the old one and free this one.
329: Note that it also frees up the above cons cell if found. */
330: hashcode = TYPE_HASH (basetype) + TYPE_HASH (rettype) + type_hash_list (argtypes);
331: t = type_hash_canon (hashcode, t);
332:
333: if (TYPE_SIZE (t) == 0)
334: layout_type (t);
335:
336: return t;
337: }
338:
339: tree
340: build_cplus_staticfn_type (basetype, rettype, argtypes)
341: tree basetype, rettype, argtypes;
342: {
343: register tree t;
344: int hashcode;
345:
346: /* Make a node of the sort we want. */
347: t = make_node (FUNCTION_TYPE);
348:
349: TYPE_METHOD_BASETYPE (t) = TYPE_MAIN_VARIANT (basetype);
350: TREE_TYPE (t) = rettype;
351:
352: TYPE_ARG_TYPES (t) = argtypes;
353:
354: /* If we already have such a type, use the old one and free this one.
355: Note that it also frees up the above cons cell if found. */
356: hashcode = TYPE_HASH (basetype) + TYPE_HASH (rettype) + type_hash_list (argtypes);
357: t = type_hash_canon (hashcode, t);
358:
359: if (TYPE_SIZE (t) == 0)
360: layout_type (t);
361:
362: return t;
363: }
364:
365: tree
366: build_cplus_array_type (elt_type, index_type)
367: tree elt_type;
368: tree index_type;
369: {
370: register struct obstack *ambient_obstack = current_obstack;
371: register struct obstack *ambient_saveable_obstack = saveable_obstack;
372: tree t;
373:
374: /* We need a new one. If both ELT_TYPE and INDEX_TYPE are permanent,
375: make this permanent too. */
376: if (TREE_PERMANENT (elt_type)
377: && (index_type == 0 || TREE_PERMANENT (index_type)))
378: {
379: current_obstack = &permanent_obstack;
380: saveable_obstack = &permanent_obstack;
381: }
382:
383: t = build_array_type (elt_type, index_type);
384:
385: /* Push these needs up so that initialization takes place
386: more easily. */
387: TYPE_NEEDS_CONSTRUCTING (t) = TYPE_NEEDS_CONSTRUCTING (TYPE_MAIN_VARIANT (elt_type));
388: TYPE_NEEDS_DESTRUCTOR (t) = TYPE_NEEDS_DESTRUCTOR (TYPE_MAIN_VARIANT (elt_type));
389: current_obstack = ambient_obstack;
390: saveable_obstack = ambient_saveable_obstack;
391: return t;
392: }
393:
394: /* Make a variant type in the proper way for C/C++, propagating qualifiers
395: down to the element type of an array. */
396:
397: tree
398: cp_build_type_variant (type, constp, volatilep)
399: tree type;
400: int constp, volatilep;
401: {
402: if (TREE_CODE (type) == ARRAY_TYPE)
403: {
404: tree real_main_variant = TYPE_MAIN_VARIANT (type);
405:
406: push_obstacks (TYPE_OBSTACK (real_main_variant),
407: TYPE_OBSTACK (real_main_variant));
408: type = build_cplus_array_type (cp_build_type_variant (TREE_TYPE (type),
409: constp, volatilep),
410: TYPE_DOMAIN (type));
411:
412: /* TYPE must be on same obstack as REAL_MAIN_VARIANT. If not,
413: make a copy. (TYPE might have come from the hash table and
414: REAL_MAIN_VARIANT might be in some function's obstack.) */
415:
416: if (TYPE_OBSTACK (type) != TYPE_OBSTACK (real_main_variant))
417: {
418: type = copy_node (type);
419: TYPE_POINTER_TO (type) = TYPE_REFERENCE_TO (type) = 0;
420: }
421:
422: TYPE_MAIN_VARIANT (type) = real_main_variant;
423: pop_obstacks ();
424: }
425: return build_type_variant (type, constp, volatilep);
426: }
427:
428: /* Add OFFSET to all base types of T.
429:
430: OFFSET, which is a type offset, is number of bytes.
431:
432: Note that we don't have to worry about having two paths to the
433: same base type, since this type owns its association list. */
434: void
435: propagate_binfo_offsets (binfo, offset)
436: tree binfo;
437: tree offset;
438: {
439: tree binfos = BINFO_BASETYPES (binfo);
440: int i, n_baselinks = binfos ? TREE_VEC_LENGTH (binfos) : 0;
441:
442: for (i = 0; i < n_baselinks; /* note increment is done in the loop. */)
443: {
444: tree base_binfo = TREE_VEC_ELT (binfos, i);
445:
446: if (TREE_VIA_VIRTUAL (base_binfo))
447: i += 1;
448: else
449: {
450: int j;
451: tree base_binfos = BINFO_BASETYPES (base_binfo);
452: tree delta;
453:
454: for (j = i+1; j < n_baselinks; j++)
455: if (! TREE_VIA_VIRTUAL (TREE_VEC_ELT (binfos, j)))
456: {
457: /* The next basetype offset must take into account the space
458: between the classes, not just the size of each class. */
459: delta = size_binop (MINUS_EXPR,
460: BINFO_OFFSET (TREE_VEC_ELT (binfos, j)),
461: BINFO_OFFSET (base_binfo));
462: break;
463: }
464:
465: #if 0
466: if (BINFO_OFFSET_ZEROP (base_binfo))
467: BINFO_OFFSET (base_binfo) = offset;
468: else
469: BINFO_OFFSET (base_binfo)
470: = size_binop (PLUS_EXPR, BINFO_OFFSET (base_binfo), offset);
471: #else
472: BINFO_OFFSET (base_binfo) = offset;
473: #endif
474: if (base_binfos)
475: {
476: int k;
477: tree chain = NULL_TREE;
478:
479: /* Now unshare the structure beneath BASE_BINFO. */
480: for (k = TREE_VEC_LENGTH (base_binfos)-1;
481: k >= 0; k--)
482: {
483: tree base_base_binfo = TREE_VEC_ELT (base_binfos, k);
484: if (! TREE_VIA_VIRTUAL (base_base_binfo))
485: TREE_VEC_ELT (base_binfos, k)
486: = make_binfo (BINFO_OFFSET (base_base_binfo),
487: base_base_binfo,
488: BINFO_VTABLE (base_base_binfo),
489: BINFO_VIRTUALS (base_base_binfo),
490: chain);
491: chain = TREE_VEC_ELT (base_binfos, k);
492: TREE_VIA_PUBLIC (chain) = TREE_VIA_PUBLIC (base_base_binfo);
493: TREE_VIA_PROTECTED (chain) = TREE_VIA_PROTECTED (base_base_binfo);
494: }
495: /* Now propagate the offset to the base types. */
496: propagate_binfo_offsets (base_binfo, offset);
497: }
498:
499: /* Go to our next class that counts for offset propagation. */
500: i = j;
501: if (i < n_baselinks)
502: offset = size_binop (PLUS_EXPR, offset, delta);
503: }
504: }
505: }
506:
507: /* Compute the actual offsets that our virtual base classes
508: will have *for this type*. This must be performed after
509: the fields are laid out, since virtual baseclasses must
510: lay down at the end of the record.
511:
512: Returns the maximum number of virtual functions any of the virtual
513: baseclasses provide. */
514: int
515: layout_vbasetypes (rec, max)
516: tree rec;
517: int max;
518: {
519: /* Get all the virtual base types that this type uses.
520: The TREE_VALUE slot holds the virtual baseclass type. */
521: tree vbase_types = get_vbase_types (rec);
522:
523: #ifdef STRUCTURE_SIZE_BOUNDARY
524: unsigned record_align = MAX (STRUCTURE_SIZE_BOUNDARY, TYPE_ALIGN (rec));
525: #else
526: unsigned record_align = MAX (BITS_PER_UNIT, TYPE_ALIGN (rec));
527: #endif
528: int desired_align;
529:
530: /* Record size so far is CONST_SIZE + VAR_SIZE bits,
531: where CONST_SIZE is an integer
532: and VAR_SIZE is a tree expression.
533: If VAR_SIZE is null, the size is just CONST_SIZE.
534: Naturally we try to avoid using VAR_SIZE. */
535: register unsigned const_size = 0;
536: register tree var_size = 0;
537: int nonvirtual_const_size;
538: tree nonvirtual_var_size;
539:
540: CLASSTYPE_VBASECLASSES (rec) = vbase_types;
541:
542: if (TREE_CODE (TYPE_SIZE (rec)) == INTEGER_CST)
543: const_size = TREE_INT_CST_LOW (TYPE_SIZE (rec));
544: else
545: var_size = TYPE_SIZE (rec);
546:
547: nonvirtual_const_size = const_size;
548: nonvirtual_var_size = var_size;
549:
550: while (vbase_types)
551: {
552: tree basetype = BINFO_TYPE (vbase_types);
553: tree offset;
554:
555: desired_align = TYPE_ALIGN (basetype);
556: record_align = MAX (record_align, desired_align);
557:
558: if (const_size == 0)
559: offset = integer_zero_node;
560: else
561: {
562: /* Give each virtual base type the alignment it wants. */
563: const_size = CEIL (const_size, TYPE_ALIGN (basetype))
564: * TYPE_ALIGN (basetype);
565: offset = size_int (CEIL (const_size, BITS_PER_UNIT));
566: }
567:
568: if (CLASSTYPE_VSIZE (basetype) > max)
569: max = CLASSTYPE_VSIZE (basetype);
570: BINFO_OFFSET (vbase_types) = offset;
571:
572: if (TREE_CODE (TYPE_SIZE (basetype)) == INTEGER_CST)
573: const_size += MAX (BITS_PER_UNIT,
574: TREE_INT_CST_LOW (TYPE_SIZE (basetype))
575: - TREE_INT_CST_LOW (CLASSTYPE_VBASE_SIZE (basetype)));
576: else if (var_size == 0)
577: var_size = TYPE_SIZE (basetype);
578: else
579: var_size = size_binop (PLUS_EXPR, var_size, TYPE_SIZE (basetype));
580:
581: vbase_types = TREE_CHAIN (vbase_types);
582: }
583:
584: /* Set the alignment in the complete type. We don't set CLASSTYPE_ALIGN
585: here, as that is for this class, without any virtual base classes. */
586: TYPE_ALIGN (rec) = record_align;
587: if (const_size != nonvirtual_const_size)
588: {
589: CLASSTYPE_VBASE_SIZE (rec)
590: = size_int (const_size - nonvirtual_const_size);
591: TYPE_SIZE (rec) = size_int (const_size);
592: }
593:
594: /* Now propagate offset information throughout the lattice
595: under the vbase type. */
596: for (vbase_types = CLASSTYPE_VBASECLASSES (rec); vbase_types;
597: vbase_types = TREE_CHAIN (vbase_types))
598: {
599: tree base_binfos = BINFO_BASETYPES (vbase_types);
600:
601: if (base_binfos)
602: {
603: tree chain = NULL_TREE;
604: int j;
605: /* Now unshare the structure beneath BASE_BINFO. */
606:
607: for (j = TREE_VEC_LENGTH (base_binfos)-1;
608: j >= 0; j--)
609: {
610: tree base_base_binfo = TREE_VEC_ELT (base_binfos, j);
611: if (! TREE_VIA_VIRTUAL (base_base_binfo))
612: TREE_VEC_ELT (base_binfos, j)
613: = make_binfo (BINFO_OFFSET (base_base_binfo),
614: base_base_binfo,
615: BINFO_VTABLE (base_base_binfo),
616: BINFO_VIRTUALS (base_base_binfo),
617: chain);
618: chain = TREE_VEC_ELT (base_binfos, j);
619: TREE_VIA_PUBLIC (chain) = TREE_VIA_PUBLIC (base_base_binfo);
620: TREE_VIA_PROTECTED (chain) = TREE_VIA_PROTECTED (base_base_binfo);
621: }
622:
623: propagate_binfo_offsets (vbase_types, BINFO_OFFSET (vbase_types));
624: }
625: }
626:
627: return max;
628: }
629:
630: /* Lay out the base types of a record type, REC.
631: Tentatively set the size and alignment of REC
632: according to the base types alone.
633:
634: Offsets for immediate nonvirtual baseclasses are also computed here.
635:
636: TYPE_BINFO (REC) should be NULL_TREE on entry, and this routine
637: creates a list of base_binfos in TYPE_BINFO (REC) from BINFOS.
638:
639: Returns list of virtual base classes in a FIELD_DECL chain. */
640: tree
641: layout_basetypes (rec, binfos)
642: tree rec, binfos;
643: {
644: /* Chain to hold all the new FIELD_DECLs which point at virtual
645: base classes. */
646: tree vbase_decls = NULL_TREE;
647:
648: #ifdef STRUCTURE_SIZE_BOUNDARY
649: unsigned record_align = MAX (STRUCTURE_SIZE_BOUNDARY, TYPE_ALIGN (rec));
650: #else
651: unsigned record_align = MAX (BITS_PER_UNIT, TYPE_ALIGN (rec));
652: #endif
653:
654: /* Record size so far is CONST_SIZE + VAR_SIZE bits, where CONST_SIZE is
655: an integer and VAR_SIZE is a tree expression. If VAR_SIZE is null,
656: the size is just CONST_SIZE. Naturally we try to avoid using
657: VAR_SIZE. And so far, we've been sucessful. */
658: #if 0
659: register tree var_size = 0;
660: #endif
661:
662: register unsigned const_size = 0;
663: int i, n_baseclasses = binfos ? TREE_VEC_LENGTH (binfos) : 0;
664:
665: /* Handle basetypes almost like fields, but record their
666: offsets differently. */
667:
668: for (i = 0; i < n_baseclasses; i++)
669: {
670: int inc, desired_align, int_vbase_size;
671: register tree base_binfo = TREE_VEC_ELT (binfos, i);
672: register tree basetype = BINFO_TYPE (base_binfo);
673: tree decl, offset;
674:
675: if (TYPE_SIZE (basetype) == 0)
676: {
677: #if 0
678: /* This error is now reported in xref_tag, thus giving better
679: location information. */
680: error_with_aggr_type (base_binfo,
681: "base class `%s' has incomplete type");
682:
683: TREE_VIA_PUBLIC (base_binfo) = 1;
684: TREE_VIA_PROTECTED (base_binfo) = 0;
685: TREE_VIA_VIRTUAL (base_binfo) = 0;
686:
687: /* Should handle this better so that
688:
689: class A;
690: class B: private A { virtual void F(); };
691:
692: does not dump core when compiled. */
693: my_friendly_abort (121);
694: #endif
695: continue;
696: }
697:
698: /* All basetypes are recorded in the association list of the
699: derived type. */
700:
701: if (TREE_VIA_VIRTUAL (base_binfo))
702: {
703: int j;
704: char *name = (char *)alloca (TYPE_NAME_LENGTH (basetype)
705: + sizeof (VBASE_NAME) + 1);
706:
707: /* The offset for a virtual base class is only used in computing
708: virtual function tables and for initializing virtual base
709: pointers. It is built once `get_vbase_types' is called. */
710:
711: /* If this basetype can come from another vbase pointer
712: without an additional indirection, we will share
713: that pointer. If an indirection is involved, we
714: make our own pointer. */
715: for (j = 0; j < n_baseclasses; j++)
716: {
717: tree other_base_binfo = TREE_VEC_ELT (binfos, j);
718: if (! TREE_VIA_VIRTUAL (other_base_binfo)
719: && binfo_member (basetype,
720: CLASSTYPE_VBASECLASSES (BINFO_TYPE (other_base_binfo))))
721: goto got_it;
722: }
723: sprintf (name, VBASE_NAME_FORMAT, TYPE_NAME_STRING (basetype));
724: decl = build_lang_decl (FIELD_DECL, get_identifier (name),
725: build_pointer_type (basetype));
726: /* If you change any of the below, take a look at all the
727: other VFIELD_BASEs and VTABLE_BASEs in the code, and change
728: them too. */
729: DECL_ASSEMBLER_NAME (decl) = get_identifier (VTABLE_BASE);
730: DECL_VIRTUAL_P (decl) = 1;
731: DECL_FIELD_CONTEXT (decl) = rec;
732: DECL_CLASS_CONTEXT (decl) = rec;
733: DECL_FCONTEXT (decl) = basetype;
734: DECL_FIELD_SIZE (decl) = 0;
735: DECL_ALIGN (decl) = TYPE_ALIGN (ptr_type_node);
736: TREE_CHAIN (decl) = vbase_decls;
737: BINFO_VPTR_FIELD (base_binfo) = decl;
738: vbase_decls = decl;
739:
740: if (warn_nonvdtor && TYPE_HAS_DESTRUCTOR (basetype)
741: && DECL_VINDEX (TREE_VEC_ELT (CLASSTYPE_METHOD_VEC (basetype), 0)) == NULL_TREE)
742: {
743: warning_with_decl (TREE_VEC_ELT (CLASSTYPE_METHOD_VEC (basetype), 0),
744: "destructor `%s' non-virtual");
745: warning ("in inheritance relationship `%s: virtual %s'",
746: TYPE_NAME_STRING (rec),
747: TYPE_NAME_STRING (basetype));
748: }
749: got_it:
750: /* The space this decl occupies has already been accounted for. */
751: continue;
752: }
753:
754: if (const_size == 0)
755: offset = integer_zero_node;
756: else
757: {
758: /* Give each base type the alignment it wants. */
759: const_size = CEIL (const_size, TYPE_ALIGN (basetype))
760: * TYPE_ALIGN (basetype);
761: offset = size_int ((const_size + BITS_PER_UNIT - 1) / BITS_PER_UNIT);
762:
763: #if 0
764: /* bpk: Disabled this check until someone is willing to
765: claim it as theirs and explain exactly what circumstances
766: warrant the warning. */
767: if (warn_nonvdtor && TYPE_HAS_DESTRUCTOR (basetype)
768: && DECL_VINDEX (TREE_VEC_ELT (CLASSTYPE_METHOD_VEC (basetype), 0)) == NULL_TREE)
769: {
770: warning_with_decl (TREE_VEC_ELT (CLASSTYPE_METHOD_VEC (basetype), 0),
771: "destructor `%s' non-virtual");
772: warning ("in inheritance relationship `%s:%s %s'",
773: TYPE_NAME_STRING (rec),
774: TREE_VIA_VIRTUAL (base_binfo) ? " virtual" : "",
775: TYPE_NAME_STRING (basetype));
776: }
777: #endif
778: }
779: BINFO_OFFSET (base_binfo) = offset;
780: if (CLASSTYPE_VSIZE (basetype))
781: {
782: BINFO_VTABLE (base_binfo) = TYPE_BINFO_VTABLE (basetype);
783: BINFO_VIRTUALS (base_binfo) = TYPE_BINFO_VIRTUALS (basetype);
784: }
785: TREE_CHAIN (base_binfo) = TYPE_BINFO (rec);
786: TYPE_BINFO (rec) = base_binfo;
787:
788: /* Add only the amount of storage not present in
789: the virtual baseclasses. */
790:
791: int_vbase_size = TREE_INT_CST_LOW (CLASSTYPE_VBASE_SIZE (basetype));
792: if (TREE_INT_CST_LOW (TYPE_SIZE (basetype)) > int_vbase_size)
793: {
794: inc = MAX (record_align,
795: (TREE_INT_CST_LOW (TYPE_SIZE (basetype))
796: - int_vbase_size));
797:
798: /* Record must have at least as much alignment as any field. */
799: desired_align = TYPE_ALIGN (basetype);
800: record_align = MAX (record_align, desired_align);
801:
802: const_size += inc;
803: }
804: }
805:
806: if (const_size)
807: CLASSTYPE_SIZE (rec) = size_int (const_size);
808: else
809: CLASSTYPE_SIZE (rec) = integer_zero_node;
810: CLASSTYPE_ALIGN (rec) = record_align;
811:
812: return vbase_decls;
813: }
814:
815: /* Hashing of lists so that we don't make duplicates.
816: The entry point is `list_hash_canon'. */
817:
818: /* Each hash table slot is a bucket containing a chain
819: of these structures. */
820:
821: struct list_hash
822: {
823: struct list_hash *next; /* Next structure in the bucket. */
824: int hashcode; /* Hash code of this list. */
825: tree list; /* The list recorded here. */
826: };
827:
828: /* Now here is the hash table. When recording a list, it is added
829: to the slot whose index is the hash code mod the table size.
830: Note that the hash table is used for several kinds of lists.
831: While all these live in the same table, they are completely independent,
832: and the hash code is computed differently for each of these. */
833:
834: #define TYPE_HASH_SIZE 59
835: struct list_hash *list_hash_table[TYPE_HASH_SIZE];
836:
837: /* Compute a hash code for a list (chain of TREE_LIST nodes
838: with goodies in the TREE_PURPOSE, TREE_VALUE, and bits of the
839: TREE_COMMON slots), by adding the hash codes of the individual entries. */
840:
841: int
842: list_hash (list)
843: tree list;
844: {
845: register int hashcode = 0;
846:
847: if (TREE_CHAIN (list))
848: hashcode += TYPE_HASH (TREE_CHAIN (list));
849:
850: if (TREE_VALUE (list))
851: hashcode += TYPE_HASH (TREE_VALUE (list));
852: else
853: hashcode += 1007;
854: if (TREE_PURPOSE (list))
855: hashcode += TYPE_HASH (TREE_PURPOSE (list));
856: else
857: hashcode += 1009;
858: return hashcode;
859: }
860:
861: /* Look in the type hash table for a type isomorphic to TYPE.
862: If one is found, return it. Otherwise return 0. */
863:
864: tree
865: list_hash_lookup (hashcode, list)
866: int hashcode;
867: tree list;
868: {
869: register struct list_hash *h;
870: for (h = list_hash_table[hashcode % TYPE_HASH_SIZE]; h; h = h->next)
871: if (h->hashcode == hashcode
872: && TREE_VIA_VIRTUAL (h->list) == TREE_VIA_VIRTUAL (list)
873: && TREE_VIA_PUBLIC (h->list) == TREE_VIA_PUBLIC (list)
874: && TREE_VIA_PROTECTED (h->list) == TREE_VIA_PROTECTED (list)
875: && TREE_PURPOSE (h->list) == TREE_PURPOSE (list)
876: && TREE_VALUE (h->list) == TREE_VALUE (list)
877: && TREE_CHAIN (h->list) == TREE_CHAIN (list))
878: {
879: my_friendly_assert (TREE_TYPE (h->list) == TREE_TYPE (list), 299);
880: return h->list;
881: }
882: return 0;
883: }
884:
885: /* Add an entry to the list-hash-table
886: for a list TYPE whose hash code is HASHCODE. */
887:
888: void
889: list_hash_add (hashcode, list)
890: int hashcode;
891: tree list;
892: {
893: register struct list_hash *h;
894:
895: h = (struct list_hash *) obstack_alloc (&class_obstack, sizeof (struct list_hash));
896: h->hashcode = hashcode;
897: h->list = list;
898: h->next = list_hash_table[hashcode % TYPE_HASH_SIZE];
899: list_hash_table[hashcode % TYPE_HASH_SIZE] = h;
900: }
901:
902: /* Given TYPE, and HASHCODE its hash code, return the canonical
903: object for an identical list if one already exists.
904: Otherwise, return TYPE, and record it as the canonical object
905: if it is a permanent object.
906:
907: To use this function, first create a list of the sort you want.
908: Then compute its hash code from the fields of the list that
909: make it different from other similar lists.
910: Then call this function and use the value.
911: This function frees the list you pass in if it is a duplicate. */
912:
913: /* Set to 1 to debug without canonicalization. Never set by program. */
914: static int debug_no_list_hash = 0;
915:
916: tree
917: list_hash_canon (hashcode, list)
918: int hashcode;
919: tree list;
920: {
921: tree t1;
922:
923: if (debug_no_list_hash)
924: return list;
925:
926: t1 = list_hash_lookup (hashcode, list);
927: if (t1 != 0)
928: {
929: obstack_free (&class_obstack, list);
930: return t1;
931: }
932:
933: /* If this is a new list, record it for later reuse. */
934: list_hash_add (hashcode, list);
935:
936: return list;
937: }
938:
939: tree
940: hash_tree_cons (via_public, via_virtual, via_protected, purpose, value, chain)
941: int via_public, via_virtual, via_protected;
942: tree purpose, value, chain;
943: {
944: struct obstack *ambient_obstack = current_obstack;
945: tree t;
946: int hashcode;
947:
948: current_obstack = &class_obstack;
949: t = tree_cons (purpose, value, chain);
950: TREE_VIA_PUBLIC (t) = via_public;
951: TREE_VIA_PROTECTED (t) = via_protected;
952: TREE_VIA_VIRTUAL (t) = via_virtual;
953: hashcode = list_hash (t);
954: t = list_hash_canon (hashcode, t);
955: current_obstack = ambient_obstack;
956: return t;
957: }
958:
959: /* Constructor for hashed lists. */
960: tree
961: hash_tree_chain (value, chain)
962: tree value, chain;
963: {
964: struct obstack *ambient_obstack = current_obstack;
965: tree t;
966: int hashcode;
967:
968: current_obstack = &class_obstack;
969: t = tree_cons (NULL_TREE, value, chain);
970: hashcode = list_hash (t);
971: t = list_hash_canon (hashcode, t);
972: current_obstack = ambient_obstack;
973: return t;
974: }
975:
976: /* Similar, but used for concatenating two lists. */
977: tree
978: hash_chainon (list1, list2)
979: tree list1, list2;
980: {
981: if (list2 == 0)
982: return list1;
983: if (list1 == 0)
984: return list2;
985: if (TREE_CHAIN (list1) == NULL_TREE)
986: return hash_tree_chain (TREE_VALUE (list1), list2);
987: return hash_tree_chain (TREE_VALUE (list1),
988: hash_chainon (TREE_CHAIN (list1), list2));
989: }
990:
991: static tree
992: get_identifier_list (value)
993: tree value;
994: {
995: tree list = IDENTIFIER_AS_LIST (value);
996: if (list != NULL_TREE
997: && (TREE_CODE (list) != TREE_LIST
998: || TREE_VALUE (list) != value))
999: list = NULL_TREE;
1000: else if (IDENTIFIER_HAS_TYPE_VALUE (value)
1001: && TREE_CODE (IDENTIFIER_TYPE_VALUE (value)) == RECORD_TYPE
1002: && IDENTIFIER_TYPE_VALUE (value)
1003: == TYPE_MAIN_VARIANT (IDENTIFIER_TYPE_VALUE (value)))
1004: {
1005: tree type = IDENTIFIER_TYPE_VALUE (value);
1006:
1007: if (TYPE_PTRMEMFUNC_P (type))
1008: list = NULL_TREE;
1009: else if (type == current_class_type)
1010: /* Don't mess up the constructor name. */
1011: list = tree_cons (NULL_TREE, value, NULL_TREE);
1012: else
1013: {
1014: register tree id;
1015: /* This will return the correct thing for regular types,
1016: nested types, and templates. Yay! */
1017: if (TYPE_NESTED_NAME (type))
1018: id = TYPE_NESTED_NAME (type);
1019: else
1020: id = TYPE_IDENTIFIER (type);
1021:
1022: if (CLASSTYPE_ID_AS_LIST (type) == NULL_TREE)
1023: CLASSTYPE_ID_AS_LIST (type)
1024: = perm_tree_cons (NULL_TREE, id, NULL_TREE);
1025: list = CLASSTYPE_ID_AS_LIST (type);
1026: }
1027: }
1028: return list;
1029: }
1030:
1031: tree
1032: get_decl_list (value)
1033: tree value;
1034: {
1035: tree list = NULL_TREE;
1036:
1037: if (TREE_CODE (value) == IDENTIFIER_NODE)
1038: list = get_identifier_list (value);
1039: else if (TREE_CODE (value) == RECORD_TYPE
1040: && TYPE_LANG_SPECIFIC (value))
1041: list = CLASSTYPE_AS_LIST (value);
1042:
1043: if (list != NULL_TREE)
1044: {
1045: my_friendly_assert (TREE_CHAIN (list) == NULL_TREE, 301);
1046: return list;
1047: }
1048:
1049: return build_decl_list (NULL_TREE, value);
1050: }
1051:
1052: /* Look in the type hash table for a type isomorphic to
1053: `build_tree_list (NULL_TREE, VALUE)'.
1054: If one is found, return it. Otherwise return 0. */
1055:
1056: tree
1057: list_hash_lookup_or_cons (value)
1058: tree value;
1059: {
1060: register int hashcode = TYPE_HASH (value);
1061: register struct list_hash *h;
1062: struct obstack *ambient_obstack;
1063: tree list = NULL_TREE;
1064:
1065: if (TREE_CODE (value) == IDENTIFIER_NODE)
1066: list = get_identifier_list (value);
1067: else if (TREE_CODE (value) == TYPE_DECL
1068: && TREE_CODE (TREE_TYPE (value)) == RECORD_TYPE
1069: && TYPE_LANG_SPECIFIC (TREE_TYPE (value)))
1070: list = CLASSTYPE_ID_AS_LIST (TREE_TYPE (value));
1071: else if (TREE_CODE (value) == RECORD_TYPE
1072: && TYPE_LANG_SPECIFIC (value))
1073: list = CLASSTYPE_AS_LIST (value);
1074:
1075: if (list != NULL_TREE)
1076: {
1077: my_friendly_assert (TREE_CHAIN (list) == NULL_TREE, 302);
1078: return list;
1079: }
1080:
1081: if (debug_no_list_hash)
1082: return hash_tree_chain (value, NULL_TREE);
1083:
1084: for (h = list_hash_table[hashcode % TYPE_HASH_SIZE]; h; h = h->next)
1085: if (h->hashcode == hashcode
1086: && TREE_VIA_VIRTUAL (h->list) == 0
1087: && TREE_VIA_PUBLIC (h->list) == 0
1088: && TREE_VIA_PROTECTED (h->list) == 0
1089: && TREE_PURPOSE (h->list) == 0
1090: && TREE_VALUE (h->list) == value)
1091: {
1092: my_friendly_assert (TREE_TYPE (h->list) == 0, 303);
1093: my_friendly_assert (TREE_CHAIN (h->list) == 0, 304);
1094: return h->list;
1095: }
1096:
1097: ambient_obstack = current_obstack;
1098: current_obstack = &class_obstack;
1099: list = build_tree_list (NULL_TREE, value);
1100: list_hash_add (hashcode, list);
1101: current_obstack = ambient_obstack;
1102: return list;
1103: }
1104:
1105: /* Build an association between TYPE and some parameters:
1106:
1107: OFFSET is the offset added to `this' to convert it to a pointer
1108: of type `TYPE *'
1109:
1110: BINFO is the base binfo to use, if we are deriving from one. This
1111: is necessary, as we want specialized parent binfos from base
1112: classes, so that the VTABLE_NAMEs of bases are for the most derived
1113: type, instead of of the simple type.
1114:
1115: VTABLE is the virtual function table with which to initialize
1116: sub-objects of type TYPE.
1117:
1118: VIRTUALS are the virtual functions sitting in VTABLE.
1119:
1120: CHAIN are more associations we must retain. */
1121:
1122: tree
1123: make_binfo (offset, binfo, vtable, virtuals, chain)
1124: tree offset, binfo;
1125: tree vtable, virtuals;
1126: tree chain;
1127: {
1128: tree new_binfo = make_tree_vec (6);
1129: tree type;
1130:
1131: if (TREE_CODE (binfo) == TREE_VEC)
1132: type = BINFO_TYPE (binfo);
1133: else
1134: {
1135: type = binfo;
1136: binfo = TYPE_BINFO (binfo);
1137: }
1138:
1139: TREE_CHAIN (new_binfo) = chain;
1140: if (chain)
1141: TREE_USED (new_binfo) = TREE_USED (chain);
1142:
1143: TREE_TYPE (new_binfo) = TYPE_MAIN_VARIANT (type);
1144: BINFO_OFFSET (new_binfo) = offset;
1145: BINFO_VTABLE (new_binfo) = vtable;
1146: BINFO_VIRTUALS (new_binfo) = virtuals;
1147: BINFO_VPTR_FIELD (new_binfo) = NULL_TREE;
1148:
1149: if (binfo && BINFO_BASETYPES (binfo) != NULL_TREE)
1150: BINFO_BASETYPES (new_binfo) = copy_node (BINFO_BASETYPES (binfo));
1151: return new_binfo;
1152: }
1153:
1154: tree
1155: copy_binfo (list)
1156: tree list;
1157: {
1158: tree binfo = copy_list (list);
1159: tree rval = binfo;
1160: while (binfo)
1161: {
1162: TREE_USED (binfo) = 0;
1163: if (BINFO_BASETYPES (binfo))
1164: BINFO_BASETYPES (binfo) = copy_node (BINFO_BASETYPES (binfo));
1165: binfo = TREE_CHAIN (binfo);
1166: }
1167: return rval;
1168: }
1169:
1170: /* Return the binfo value for ELEM in TYPE. */
1171:
1172: tree
1173: binfo_value (elem, type)
1174: tree elem;
1175: tree type;
1176: {
1177: if (get_base_distance (elem, type, 0, (tree *)0) == -2)
1178: compiler_error ("base class `%s' ambiguous in binfo_value",
1179: TYPE_NAME_STRING (elem));
1180: if (elem == type)
1181: return TYPE_BINFO (type);
1182: if (TREE_CODE (elem) == RECORD_TYPE && TYPE_BINFO (elem) == type)
1183: return type;
1184: return get_binfo (elem, type, 0);
1185: }
1186:
1187: tree
1188: reverse_path (path)
1189: tree path;
1190: {
1191: register tree prev = 0, tmp, next;
1192: for (tmp = path; tmp; tmp = next)
1193: {
1194: next = BINFO_INHERITANCE_CHAIN (tmp);
1195: BINFO_INHERITANCE_CHAIN (tmp) = prev;
1196: prev = tmp;
1197: }
1198: return prev;
1199: }
1200:
1201: tree
1202: virtual_member (elem, list)
1203: tree elem;
1204: tree list;
1205: {
1206: tree t;
1207: tree rval, nval;
1208:
1209: for (t = list; t; t = TREE_CHAIN (t))
1210: if (elem == BINFO_TYPE (t))
1211: return t;
1212: rval = 0;
1213: for (t = list; t; t = TREE_CHAIN (t))
1214: {
1215: tree binfos = BINFO_BASETYPES (t);
1216: int i;
1217:
1218: if (binfos != NULL_TREE)
1219: for (i = TREE_VEC_LENGTH (binfos)-1; i >= 0; i--)
1220: {
1221: nval = binfo_value (elem, BINFO_TYPE (TREE_VEC_ELT (binfos, i)));
1222: if (nval)
1223: {
1224: if (rval && BINFO_OFFSET (nval) != BINFO_OFFSET (rval))
1225: my_friendly_abort (104);
1226: rval = nval;
1227: }
1228: }
1229: }
1230: return rval;
1231: }
1232:
1233: void
1234: debug_binfo (elem)
1235: tree elem;
1236: {
1237: int i;
1238: tree virtuals;
1239:
1240: fprintf (stderr, "type \"%s\"; offset = %d\n",
1241: TYPE_NAME_STRING (BINFO_TYPE (elem)),
1242: TREE_INT_CST_LOW (BINFO_OFFSET (elem)));
1243: fprintf (stderr, "vtable type:\n");
1244: debug_tree (BINFO_TYPE (elem));
1245: if (BINFO_VTABLE (elem))
1246: fprintf (stderr, "vtable decl \"%s\"\n", IDENTIFIER_POINTER (DECL_NAME (BINFO_VTABLE (elem))));
1247: else
1248: fprintf (stderr, "no vtable decl yet\n");
1249: fprintf (stderr, "virtuals:\n");
1250: virtuals = BINFO_VIRTUALS (elem);
1251: if (virtuals != 0)
1252: {
1253: virtuals = TREE_CHAIN (virtuals);
1254: if (flag_dossier)
1255: virtuals = TREE_CHAIN (virtuals);
1256: }
1257: i = 1;
1258: while (virtuals)
1259: {
1260: tree fndecl = TREE_OPERAND (FNADDR_FROM_VTABLE_ENTRY (TREE_VALUE (virtuals)), 0);
1261: fprintf (stderr, "%s [%d =? %d]\n",
1262: IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (fndecl)),
1263: i, TREE_INT_CST_LOW (DECL_VINDEX (fndecl)));
1264: virtuals = TREE_CHAIN (virtuals);
1265: i += 1;
1266: }
1267: }
1268:
1269: /* Return the length of a chain of nodes chained through DECL_CHAIN.
1270: We expect a null pointer to mark the end of the chain.
1271: This is the Lisp primitive `length'. */
1272:
1273: int
1274: decl_list_length (t)
1275: tree t;
1276: {
1277: register tree tail;
1278: register int len = 0;
1279:
1280: my_friendly_assert (TREE_CODE (t) == FUNCTION_DECL
1281: || TREE_CODE (t) == TEMPLATE_DECL, 300);
1282: for (tail = t; tail; tail = DECL_CHAIN (tail))
1283: len++;
1284:
1285: return len;
1286: }
1287:
1288: int
1289: count_functions (t)
1290: tree t;
1291: {
1292: if (TREE_CODE (t) == FUNCTION_DECL)
1293: return 1;
1294: else if (TREE_CODE (t) == TREE_LIST)
1295: return decl_list_length (TREE_VALUE (t));
1296:
1297: my_friendly_abort (359);
1298: return 0;
1299: }
1300:
1301: /* Like value_member, but for DECL_CHAINs. */
1302: tree
1303: decl_value_member (elem, list)
1304: tree elem, list;
1305: {
1306: while (list)
1307: {
1308: if (elem == list)
1309: return list;
1310: list = DECL_CHAIN (list);
1311: }
1312: return NULL_TREE;
1313: }
1314:
1315: int
1316: is_overloaded_fn (x)
1317: tree x;
1318: {
1319: if (TREE_CODE (x) == FUNCTION_DECL)
1320: return 1;
1321:
1322: if (TREE_CODE (x) == TREE_LIST
1323: && (TREE_CODE (TREE_VALUE (x)) == FUNCTION_DECL
1324: || TREE_CODE (TREE_VALUE (x)) == TEMPLATE_DECL))
1325: return 1;
1326:
1327: return 0;
1328: }
1329:
1330: int
1331: really_overloaded_fn (x)
1332: tree x;
1333: {
1334: if (TREE_CODE (x) == TREE_LIST
1335: && (TREE_CODE (TREE_VALUE (x)) == FUNCTION_DECL
1336: || TREE_CODE (TREE_VALUE (x)) == TEMPLATE_DECL))
1337: return 1;
1338:
1339: return 0;
1340: }
1341:
1342: tree
1343: get_first_fn (from)
1344: tree from;
1345: {
1346: if (TREE_CODE (from) == FUNCTION_DECL)
1347: return from;
1348:
1349: my_friendly_assert (TREE_CODE (from) == TREE_LIST, 9);
1350:
1351: return TREE_VALUE (from);
1352: }
1353:
1354: tree
1355: fnaddr_from_vtable_entry (entry)
1356: tree entry;
1357: {
1358: if (flag_vtable_thunks)
1359: {
1360: tree func = entry;
1361: if (TREE_CODE (func) == ADDR_EXPR)
1362: func = TREE_OPERAND (func, 0);
1363: if (TREE_CODE (func) == THUNK_DECL)
1364: return DECL_INITIAL (func);
1365: else
1366: return entry;
1367: }
1368: else
1369: return TREE_VALUE (TREE_CHAIN (TREE_CHAIN (CONSTRUCTOR_ELTS (entry))));
1370: }
1371:
1372: void
1373: set_fnaddr_from_vtable_entry (entry, value)
1374: tree entry, value;
1375: {
1376: if (flag_vtable_thunks)
1377: abort ();
1378: else
1379: TREE_VALUE (TREE_CHAIN (TREE_CHAIN (CONSTRUCTOR_ELTS (entry)))) = value;
1380: }
1381:
1382: tree
1383: function_arg_chain (t)
1384: tree t;
1385: {
1386: return TREE_CHAIN (TYPE_ARG_TYPES (TREE_TYPE (t)));
1387: }
1388:
1389: int
1390: promotes_to_aggr_type (t, code)
1391: tree t;
1392: enum tree_code code;
1393: {
1394: if (TREE_CODE (t) == code)
1395: t = TREE_TYPE (t);
1396: return IS_AGGR_TYPE (t);
1397: }
1398:
1399: int
1400: is_aggr_type_2 (t1, t2)
1401: tree t1, t2;
1402: {
1403: if (TREE_CODE (t1) != TREE_CODE (t2))
1404: return 0;
1405: return IS_AGGR_TYPE (t1) && IS_AGGR_TYPE (t2);
1406: }
1407:
1408: /* Give message using types TYPE1 and TYPE2 as arguments.
1409: PFN is the function which will print the message;
1410: S is the format string for PFN to use. */
1411: void
1412: message_2_types (pfn, s, type1, type2)
1413: void (*pfn) ();
1414: char *s;
1415: tree type1, type2;
1416: {
1417: tree name1 = TYPE_NAME (type1);
1418: tree name2 = TYPE_NAME (type2);
1419: if (TREE_CODE (name1) == TYPE_DECL)
1420: name1 = DECL_NAME (name1);
1421: if (TREE_CODE (name2) == TYPE_DECL)
1422: name2 = DECL_NAME (name2);
1423: (*pfn) (s, IDENTIFIER_POINTER (name1), IDENTIFIER_POINTER (name2));
1424: }
1425:
1426: #define PRINT_RING_SIZE 4
1427:
1428: char *
1429: lang_printable_name (decl)
1430: tree decl;
1431: {
1432: static tree decl_ring[PRINT_RING_SIZE];
1433: static char *print_ring[PRINT_RING_SIZE];
1434: static int ring_counter;
1435: int i;
1436:
1437: /* Only cache functions. */
1438: if (TREE_CODE (decl) != FUNCTION_DECL
1439: || DECL_LANG_SPECIFIC (decl) == 0)
1440: return decl_as_string (decl, 1);
1441:
1442: /* See if this print name is lying around. */
1443: for (i = 0; i < PRINT_RING_SIZE; i++)
1444: if (decl_ring[i] == decl)
1445: /* yes, so return it. */
1446: return print_ring[i];
1447:
1448: if (++ring_counter == PRINT_RING_SIZE)
1449: ring_counter = 0;
1450:
1451: if (current_function_decl != NULL_TREE)
1452: {
1453: if (decl_ring[ring_counter] == current_function_decl)
1454: ring_counter += 1;
1455: if (ring_counter == PRINT_RING_SIZE)
1456: ring_counter = 0;
1457: if (decl_ring[ring_counter] == current_function_decl)
1458: my_friendly_abort (106);
1459: }
1460:
1461: if (print_ring[ring_counter])
1462: free (print_ring[ring_counter]);
1463:
1464: {
1465: int print_ret_type_p
1466: = (!DECL_CONSTRUCTOR_P (decl)
1467: && !DESTRUCTOR_NAME_P (DECL_ASSEMBLER_NAME (decl)));
1468:
1469: char *name = (char *)decl_as_string (decl, print_ret_type_p);
1470: print_ring[ring_counter] = (char *)malloc (strlen (name) + 1);
1471: strcpy (print_ring[ring_counter], name);
1472: decl_ring[ring_counter] = decl;
1473: }
1474: return print_ring[ring_counter];
1475: }
1476:
1477: /* Comparison function for sorting identifiers in RAISES lists.
1478: Note that because IDENTIFIER_NODEs are unique, we can sort
1479: them by address, saving an indirection. */
1480: static int
1481: id_cmp (p1, p2)
1482: tree *p1, *p2;
1483: {
1484: return (HOST_WIDE_INT)TREE_VALUE (*p1) - (HOST_WIDE_INT)TREE_VALUE (*p2);
1485: }
1486:
1487: /* Build the FUNCTION_TYPE or METHOD_TYPE which may raise exceptions
1488: listed in RAISES. */
1489: tree
1490: build_exception_variant (ctype, type, raises)
1491: tree ctype, type;
1492: tree raises;
1493: {
1494: int i;
1495: tree v = TYPE_MAIN_VARIANT (type);
1496: tree t, t2, cname;
1497: tree *a = (tree *)alloca ((list_length (raises)+1) * sizeof (tree));
1498: int constp = TYPE_READONLY (type);
1499: int volatilep = TYPE_VOLATILE (type);
1500:
1501: for (v = TYPE_NEXT_VARIANT (v); v; v = TYPE_NEXT_VARIANT (v))
1502: {
1503: if (TYPE_READONLY (v) != constp
1504: || TYPE_VOLATILE (v) != volatilep)
1505: continue;
1506:
1507: t = raises;
1508: t2 = TYPE_RAISES_EXCEPTIONS (v);
1509: while (t && t2)
1510: {
1511: if (TREE_TYPE (t) == TREE_TYPE (t2))
1512: {
1513: t = TREE_CHAIN (t);
1514: t2 = TREE_CHAIN (t2);
1515: }
1516: else break;
1517: }
1518: if (t || t2)
1519: continue;
1520: /* List of exceptions raised matches previously found list.
1521:
1522: @@ Nice to free up storage used in consing up the
1523: @@ list of exceptions raised. */
1524: return v;
1525: }
1526:
1527: /* Need to build a new variant. */
1528: v = copy_node (type);
1529: TYPE_NEXT_VARIANT (v) = TYPE_NEXT_VARIANT (type);
1530: TYPE_NEXT_VARIANT (type) = v;
1531: if (raises && ! TREE_PERMANENT (raises))
1532: {
1533: push_obstacks_nochange ();
1534: end_temporary_allocation ();
1535: raises = copy_list (raises);
1536: pop_obstacks ();
1537: }
1538: TYPE_RAISES_EXCEPTIONS (v) = raises;
1539: return v;
1540: }
1541:
1542: /* Subroutine of copy_to_permanent
1543:
1544: Assuming T is a node build bottom-up, make it all exist on
1545: permanent obstack, if it is not permanent already. */
1546: static tree
1547: make_deep_copy (t)
1548: tree t;
1549: {
1550: enum tree_code code;
1551:
1552: if (t == NULL_TREE || TREE_PERMANENT (t))
1553: return t;
1554:
1555: switch (code = TREE_CODE (t))
1556: {
1557: case ERROR_MARK:
1558: return error_mark_node;
1559:
1560: case VAR_DECL:
1561: case FUNCTION_DECL:
1562: case CONST_DECL:
1563: break;
1564:
1565: case PARM_DECL:
1566: {
1567: tree chain = TREE_CHAIN (t);
1568: t = copy_node (t);
1569: TREE_CHAIN (t) = make_deep_copy (chain);
1570: TREE_TYPE (t) = make_deep_copy (TREE_TYPE (t));
1571: DECL_INITIAL (t) = make_deep_copy (DECL_INITIAL (t));
1572: DECL_SIZE (t) = make_deep_copy (DECL_SIZE (t));
1573: return t;
1574: }
1575:
1576: case TREE_LIST:
1577: {
1578: tree chain = TREE_CHAIN (t);
1579: t = copy_node (t);
1580: TREE_PURPOSE (t) = make_deep_copy (TREE_PURPOSE (t));
1581: TREE_VALUE (t) = make_deep_copy (TREE_VALUE (t));
1582: TREE_CHAIN (t) = make_deep_copy (chain);
1583: return t;
1584: }
1585:
1586: case TREE_VEC:
1587: {
1588: int len = TREE_VEC_LENGTH (t);
1589:
1590: t = copy_node (t);
1591: while (len--)
1592: TREE_VEC_ELT (t, len) = make_deep_copy (TREE_VEC_ELT (t, len));
1593: return t;
1594: }
1595:
1596: case INTEGER_CST:
1597: case REAL_CST:
1598: case STRING_CST:
1599: return copy_node (t);
1600:
1601: case COND_EXPR:
1602: case TARGET_EXPR:
1603: case NEW_EXPR:
1604: t = copy_node (t);
1605: TREE_OPERAND (t, 0) = make_deep_copy (TREE_OPERAND (t, 0));
1606: TREE_OPERAND (t, 1) = make_deep_copy (TREE_OPERAND (t, 1));
1607: TREE_OPERAND (t, 2) = make_deep_copy (TREE_OPERAND (t, 2));
1608: return t;
1609:
1610: case SAVE_EXPR:
1611: t = copy_node (t);
1612: TREE_OPERAND (t, 0) = make_deep_copy (TREE_OPERAND (t, 0));
1613: return t;
1614:
1615: case MODIFY_EXPR:
1616: case PLUS_EXPR:
1617: case MINUS_EXPR:
1618: case MULT_EXPR:
1619: case TRUNC_DIV_EXPR:
1620: case TRUNC_MOD_EXPR:
1621: case MIN_EXPR:
1622: case MAX_EXPR:
1623: case LSHIFT_EXPR:
1624: case RSHIFT_EXPR:
1625: case BIT_IOR_EXPR:
1626: case BIT_XOR_EXPR:
1627: case BIT_AND_EXPR:
1628: case BIT_ANDTC_EXPR:
1629: case TRUTH_ANDIF_EXPR:
1630: case TRUTH_ORIF_EXPR:
1631: case LT_EXPR:
1632: case LE_EXPR:
1633: case GT_EXPR:
1634: case GE_EXPR:
1635: case EQ_EXPR:
1636: case NE_EXPR:
1637: case CEIL_DIV_EXPR:
1638: case FLOOR_DIV_EXPR:
1639: case ROUND_DIV_EXPR:
1640: case CEIL_MOD_EXPR:
1641: case FLOOR_MOD_EXPR:
1642: case ROUND_MOD_EXPR:
1643: case COMPOUND_EXPR:
1644: case PREDECREMENT_EXPR:
1645: case PREINCREMENT_EXPR:
1646: case POSTDECREMENT_EXPR:
1647: case POSTINCREMENT_EXPR:
1648: case CALL_EXPR:
1649: t = copy_node (t);
1650: TREE_OPERAND (t, 0) = make_deep_copy (TREE_OPERAND (t, 0));
1651: TREE_OPERAND (t, 1) = make_deep_copy (TREE_OPERAND (t, 1));
1652: return t;
1653:
1654: case CONVERT_EXPR:
1655: case ADDR_EXPR:
1656: case INDIRECT_REF:
1657: case NEGATE_EXPR:
1658: case BIT_NOT_EXPR:
1659: case TRUTH_NOT_EXPR:
1660: case NOP_EXPR:
1661: case COMPONENT_REF:
1662: t = copy_node (t);
1663: TREE_OPERAND (t, 0) = make_deep_copy (TREE_OPERAND (t, 0));
1664: return t;
1665:
1666: case POINTER_TYPE:
1667: return build_pointer_type (make_deep_copy (TREE_TYPE (t)));
1668: case REFERENCE_TYPE:
1669: return build_reference_type (make_deep_copy (TREE_TYPE (t)));
1670: case FUNCTION_TYPE:
1671: return build_function_type (make_deep_copy (TREE_TYPE (t)),
1672: make_deep_copy (TYPE_ARG_TYPES (t)));
1673: case ARRAY_TYPE:
1674: return build_array_type (make_deep_copy (TREE_TYPE (t)),
1675: make_deep_copy (TYPE_DOMAIN (t)));
1676: case OFFSET_TYPE:
1677: return build_offset_type (make_deep_copy (TYPE_OFFSET_BASETYPE (t)),
1678: make_deep_copy (TREE_TYPE (t)));
1679: case METHOD_TYPE:
1680: return build_method_type
1681: (make_deep_copy (TYPE_METHOD_BASETYPE (t)),
1682: build_function_type
1683: (make_deep_copy (TREE_TYPE (t)),
1684: make_deep_copy (TREE_CHAIN (TYPE_ARG_TYPES (t)))));
1685: case RECORD_TYPE:
1686: if (TYPE_PTRMEMFUNC_P (t))
1687: return build_ptrmemfunc_type
1688: (make_deep_copy (TYPE_PTRMEMFUNC_FN_TYPE (t)));
1689: /* else fall through */
1690:
1691: /* This list is incomplete, but should suffice for now.
1692: It is very important that `sorry' does not call
1693: `report_error_function'. That could cause an infinite loop. */
1694: default:
1695: sorry ("initializer contains unrecognized tree code");
1696: return error_mark_node;
1697:
1698: }
1699: my_friendly_abort (107);
1700: /* NOTREACHED */
1701: return NULL_TREE;
1702: }
1703:
1704: /* Assuming T is a node built bottom-up, make it all exist on
1705: permanent obstack, if it is not permanent already. */
1706: tree
1707: copy_to_permanent (t)
1708: tree t;
1709: {
1710: register struct obstack *ambient_obstack = current_obstack;
1711: register struct obstack *ambient_saveable_obstack = saveable_obstack;
1712:
1713: if (t == NULL_TREE || TREE_PERMANENT (t))
1714: return t;
1715:
1716: saveable_obstack = &permanent_obstack;
1717: current_obstack = saveable_obstack;
1718:
1719: t = make_deep_copy (t);
1720:
1721: current_obstack = ambient_obstack;
1722: saveable_obstack = ambient_saveable_obstack;
1723:
1724: return t;
1725: }
1726:
1727: void
1728: print_lang_statistics ()
1729: {
1730: extern struct obstack maybepermanent_obstack;
1731: print_obstack_statistics ("class_obstack", &class_obstack);
1732: print_obstack_statistics ("permanent_obstack", &permanent_obstack);
1733: print_obstack_statistics ("maybepermanent_obstack", &maybepermanent_obstack);
1734: print_search_statistics ();
1735: print_class_statistics ();
1736: }
1737:
1738: /* This is used by the `assert' macro. It is provided in libgcc.a,
1739: which `cc' doesn't know how to link. Note that the C++ front-end
1740: no longer actually uses the `assert' macro (instead, it calls
1741: my_friendly_assert). But all of the back-end files still need this. */
1742: void
1743: __eprintf (string, expression, line, filename)
1744: #ifdef __STDC__
1745: const char *string;
1746: const char *expression;
1747: unsigned line;
1748: const char *filename;
1749: #else
1750: char *string;
1751: char *expression;
1752: unsigned line;
1753: char *filename;
1754: #endif
1755: {
1756: fprintf (stderr, string, expression, line, filename);
1757: fflush (stderr);
1758: abort ();
1759: }
1760:
1761: /* Return, as an INTEGER_CST node, the number of elements for
1762: TYPE (which is an ARRAY_TYPE). This counts only elements of the top array. */
1763:
1764: tree
1765: array_type_nelts_top (type)
1766: tree type;
1767: {
1768: return fold (build (PLUS_EXPR, sizetype,
1769: array_type_nelts (type),
1770: integer_one_node));
1771: }
1772:
1773: /* Return, as an INTEGER_CST node, the number of elements for
1774: TYPE (which is an ARRAY_TYPE). This one is a recursive count of all
1775: ARRAY_TYPEs that are clumped together. */
1776:
1777: tree
1778: array_type_nelts_total (type)
1779: tree type;
1780: {
1781: tree sz = array_type_nelts_top (type);
1782: type = TREE_TYPE (type);
1783: while (TREE_CODE (type) == ARRAY_TYPE)
1784: {
1785: tree n = array_type_nelts_top (type);
1786: sz = fold (build (MULT_EXPR, sizetype, sz, n));
1787: type = TREE_TYPE (type);
1788: }
1789: return sz;
1790: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.