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