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