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