summaryrefslogtreecommitdiffstats
path: root/gcc/cp/tree.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/cp/tree.c')
-rw-r--r--gcc/cp/tree.c193
1 files changed, 179 insertions, 14 deletions
diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c
index e34cf5bab94..e5eb64749e5 100644
--- a/gcc/cp/tree.c
+++ b/gcc/cp/tree.c
@@ -26,6 +26,11 @@ Boston, MA 02111-1307, USA. */
#include "cp-tree.h"
#include "flags.h"
#include "rtl.h"
+#ifdef __STDC__
+#include <stdarg.h>
+#else
+#include <varargs.h>
+#endif
#define CEIL(x,y) (((x) + (y) - 1) / (y))
@@ -202,10 +207,9 @@ lvalue_or_else (ref, string)
and return it so that it can be processed by language-independent
and language-specific expression expanders. */
tree
-build_cplus_new (type, init, with_cleanup_p)
+build_cplus_new (type, init)
tree type;
tree init;
- int with_cleanup_p;
{
tree slot;
tree rval;
@@ -234,7 +238,7 @@ break_out_cleanups (exp)
if (TREE_CODE (tmp) == CALL_EXPR
&& TYPE_NEEDS_DESTRUCTOR (TREE_TYPE (tmp)))
- return build_cplus_new (TREE_TYPE (tmp), tmp, 1);
+ return build_cplus_new (TREE_TYPE (tmp), tmp);
while (TREE_CODE (tmp) == NOP_EXPR
|| TREE_CODE (tmp) == CONVERT_EXPR
@@ -245,7 +249,7 @@ break_out_cleanups (exp)
{
TREE_OPERAND (tmp, 0)
= build_cplus_new (TREE_TYPE (TREE_OPERAND (tmp, 0)),
- TREE_OPERAND (tmp, 0), 1);
+ TREE_OPERAND (tmp, 0));
break;
}
else
@@ -412,7 +416,14 @@ build_cplus_array_type (elt_type, index_type)
saveable_obstack = &permanent_obstack;
}
- t = build_array_type (elt_type, index_type);
+ if (current_template_parms)
+ {
+ t = make_node (ARRAY_TYPE);
+ TREE_TYPE (t) = elt_type;
+ TYPE_DOMAIN (t) = index_type;
+ }
+ else
+ t = build_array_type (elt_type, index_type);
/* Push these needs up so that initialization takes place
more easily. */
@@ -568,7 +579,6 @@ layout_vbasetypes (rec, max)
register unsigned const_size = 0;
register tree var_size = 0;
int nonvirtual_const_size;
- tree nonvirtual_var_size;
CLASSTYPE_VBASECLASSES (rec) = vbase_types;
@@ -578,7 +588,6 @@ layout_vbasetypes (rec, max)
var_size = TYPE_SIZE (rec);
nonvirtual_const_size = const_size;
- nonvirtual_var_size = var_size;
while (vbase_types)
{
@@ -1403,10 +1412,7 @@ build_exception_variant (type, raises)
tree type;
tree raises;
{
- int i;
tree v = TYPE_MAIN_VARIANT (type);
- tree t, t2, cname;
- tree *a = (tree *)alloca ((list_length (raises)+1) * sizeof (tree));
int constp = TYPE_READONLY (type);
int volatilep = TYPE_VOLATILE (type);
@@ -1435,6 +1441,7 @@ build_exception_variant (type, raises)
raises = copy_list (raises);
pop_obstacks ();
}
+
TYPE_RAISES_EXCEPTIONS (v) = raises;
return v;
}
@@ -1449,7 +1456,6 @@ mapcar (t, func)
tree t;
tree (*func)();
{
- enum tree_code code;
tree tmp;
if (t == NULL_TREE)
@@ -1458,7 +1464,7 @@ mapcar (t, func)
if (tmp = func (t), tmp != NULL_TREE)
return tmp;
- switch (code = TREE_CODE (t))
+ switch (TREE_CODE (t))
{
case ERROR_MARK:
return error_mark_node;
@@ -1552,6 +1558,8 @@ mapcar (t, func)
case POSTDECREMENT_EXPR:
case POSTINCREMENT_EXPR:
case CALL_EXPR:
+ case ARRAY_REF:
+ case SCOPE_REF:
t = copy_node (t);
TREE_OPERAND (t, 0) = mapcar (TREE_OPERAND (t, 0), func);
TREE_OPERAND (t, 1) = mapcar (TREE_OPERAND (t, 1), func);
@@ -1646,15 +1654,24 @@ copy_to_permanent (t)
return t;
}
+#ifdef GATHER_STATISTICS
+extern int depth_reached;
+#endif
+
void
print_lang_statistics ()
{
- extern struct obstack maybepermanent_obstack;
+ extern struct obstack maybepermanent_obstack, decl_obstack;
print_obstack_statistics ("class_obstack", &class_obstack);
+ print_obstack_statistics ("decl_obstack", &decl_obstack);
print_obstack_statistics ("permanent_obstack", &permanent_obstack);
print_obstack_statistics ("maybepermanent_obstack", &maybepermanent_obstack);
print_search_statistics ();
print_class_statistics ();
+#ifdef GATHER_STATISTICS
+ fprintf (stderr, "maximum template instantiation depth reached: %d\n",
+ depth_reached);
+#endif
}
/* This is used by the `assert' macro. It is provided in libgcc.a,
@@ -1720,7 +1737,7 @@ bot_manip (t)
return t;
else if (TREE_CODE (t) == TARGET_EXPR)
return build_cplus_new (TREE_TYPE (t),
- break_out_target_exprs (TREE_OPERAND (t, 1)), 0);
+ break_out_target_exprs (TREE_OPERAND (t, 1)));
return NULL_TREE;
}
@@ -1819,3 +1836,151 @@ cp_expand_decl_cleanup (decl, cleanup)
{
return expand_decl_cleanup (decl, unsave_expr (cleanup));
}
+
+/* Obstack used for allocating nodes in template function and variable
+ definitions. */
+
+extern struct obstack *expression_obstack;
+
+/* Similar to `build_nt', except we build
+ on the permanent_obstack, regardless. */
+
+tree
+build_min_nt VPROTO((enum tree_code code, ...))
+{
+#ifndef __STDC__
+ enum tree_code code;
+#endif
+ register struct obstack *ambient_obstack = expression_obstack;
+ va_list p;
+ register tree t;
+ register int length;
+ register int i;
+
+ VA_START (p, code);
+
+#ifndef __STDC__
+ code = va_arg (p, enum tree_code);
+#endif
+
+ expression_obstack = &permanent_obstack;
+
+ t = make_node (code);
+ length = tree_code_length[(int) code];
+ TREE_COMPLEXITY (t) = lineno;
+
+ for (i = 0; i < length; i++)
+ {
+ tree x = va_arg (p, tree);
+ TREE_OPERAND (t, i) = copy_to_permanent (x);
+ }
+
+ va_end (p);
+ expression_obstack = ambient_obstack;
+ return t;
+}
+
+/* Similar to `build', except we build
+ on the permanent_obstack, regardless. */
+
+tree
+build_min VPROTO((enum tree_code code, tree tt, ...))
+{
+#ifndef __STDC__
+ enum tree_code code;
+ tree tt;
+#endif
+ register struct obstack *ambient_obstack = expression_obstack;
+ va_list p;
+ register tree t;
+ register int length;
+ register int i;
+
+ VA_START (p, tt);
+
+#ifndef __STDC__
+ code = va_arg (p, enum tree_code);
+ tt = va_arg (p, tree);
+#endif
+
+ expression_obstack = &permanent_obstack;
+
+ t = make_node (code);
+ length = tree_code_length[(int) code];
+ TREE_TYPE (t) = tt;
+ TREE_COMPLEXITY (t) = lineno;
+
+ for (i = 0; i < length; i++)
+ {
+ tree x = va_arg (p, tree);
+ TREE_OPERAND (t, i) = copy_to_permanent (x);
+ }
+
+ va_end (p);
+ expression_obstack = ambient_obstack;
+ return t;
+}
+
+/* Same as `tree_cons' but make a permanent object. */
+
+tree
+min_tree_cons (purpose, value, chain)
+ tree purpose, value, chain;
+{
+ register tree node;
+ register struct obstack *ambient_obstack = current_obstack;
+ current_obstack = &permanent_obstack;
+
+ node = tree_cons (purpose, value, chain);
+ current_obstack = ambient_obstack;
+ return node;
+}
+
+tree
+get_type_decl (t)
+ tree t;
+{
+ if (TREE_CODE (t) == IDENTIFIER_NODE)
+ return identifier_typedecl_value (t);
+ if (TREE_CODE (t) == TYPE_DECL)
+ return t;
+ if (TREE_CODE_CLASS (TREE_CODE (t)) == 't')
+ return TYPE_STUB_DECL (t);
+
+ my_friendly_abort (42);
+}
+
+int
+can_free (obstack, t)
+ struct obstack *obstack;
+ tree t;
+{
+ int size;
+
+ if (TREE_CODE (t) == TREE_VEC)
+ size = (TREE_VEC_LENGTH (t)-1) * sizeof (tree) + sizeof (struct tree_vec);
+ else
+ my_friendly_abort (42);
+
+#define ROUND(x) ((x + obstack_alignment_mask (obstack)) \
+ & ~ obstack_alignment_mask (obstack))
+ if ((char *)t + ROUND (size) == obstack_next_free (obstack))
+ return 1;
+#undef ROUND
+
+ return 0;
+}
+
+/* Return first vector element whose BINFO_TYPE is ELEM.
+ Return 0 if ELEM is not in VEC. */
+
+tree
+vec_binfo_member (elem, vec)
+ tree elem, vec;
+{
+ int i;
+ for (i = 0; i < TREE_VEC_LENGTH (vec); ++i)
+ if (elem == BINFO_TYPE (TREE_VEC_ELT (vec, i)))
+ return TREE_VEC_ELT (vec, i);
+ return NULL_TREE;
+}
OpenPOWER on IntegriCloud