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