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