#include <varargs.h>
#endif
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+
+#ifdef NEED_DECLARATION_FREE
+extern void free PROTO((void *));
+#endif
+
extern void compiler_error ();
static tree get_identifier_list PROTO((tree));
case PREDECREMENT_EXPR:
case COMPONENT_REF:
case SAVE_EXPR:
+ case UNSAVE_EXPR:
+ case TRY_CATCH_EXPR:
+ case WITH_CLEANUP_EXPR:
return real_lvalue_p (TREE_OPERAND (ref, 0));
case STRING_CST:
case MIN_EXPR:
return (real_lvalue_p (TREE_OPERAND (ref, 0))
&& real_lvalue_p (TREE_OPERAND (ref, 1)));
+
+ default:
+ break;
}
return 0;
case IMAGPART_EXPR:
case COMPONENT_REF:
case SAVE_EXPR:
+ case UNSAVE_EXPR:
+ case TRY_CATCH_EXPR:
+ case WITH_CLEANUP_EXPR:
return lvalue_p (TREE_OPERAND (ref, 0));
case STRING_CST:
case MIN_EXPR:
return (lvalue_p (TREE_OPERAND (ref, 0))
&& lvalue_p (TREE_OPERAND (ref, 1)));
+
+ default:
+ break;
}
return 0;
tree slot;
tree rval;
- if (TREE_CODE (init) == TARGET_EXPR || init == error_mark_node)
+ if (TREE_CODE (init) != CALL_EXPR && TREE_CODE (init) != AGGR_INIT_EXPR)
return init;
slot = build (VAR_DECL, type);
+ DECL_ARTIFICIAL (slot) = 1;
layout_decl (slot, 0);
- rval = build (NEW_EXPR, type,
+ rval = build (AGGR_INIT_EXPR, type,
TREE_OPERAND (init, 0), TREE_OPERAND (init, 1), slot);
TREE_SIDE_EFFECTS (rval) = 1;
rval = build (TARGET_EXPR, type, slot, rval, NULL_TREE, NULL_TREE);
return rval;
}
+/* Encapsulate the expression INIT in a TARGET_EXPR. */
+
+tree
+get_target_expr (init)
+ tree init;
+{
+ tree slot;
+ tree rval;
+
+ slot = build (VAR_DECL, TREE_TYPE (init));
+ DECL_ARTIFICIAL (slot) = 1;
+ layout_decl (slot, 0);
+ rval = build (TARGET_EXPR, TREE_TYPE (init), slot, init,
+ NULL_TREE, NULL_TREE);
+ TREE_SIDE_EFFECTS (rval) = 1;
+
+ return rval;
+}
+
/* Recursively search EXP for CALL_EXPRs that need cleanups and replace
these CALL_EXPRs with tree nodes that will perform the cleanups. */
is_overloaded_fn (x)
tree x;
{
- if (TREE_CODE (x) == FUNCTION_DECL)
+ if (TREE_CODE (x) == FUNCTION_DECL
+ || TREE_CODE (x) == TEMPLATE_ID_EXPR
+ || DECL_FUNCTION_TEMPLATE_P (x))
return 1;
if (TREE_CODE (x) == TREE_LIST
&& (TREE_CODE (TREE_VALUE (x)) == FUNCTION_DECL
- || TREE_CODE (TREE_VALUE (x)) == TEMPLATE_DECL))
+ || DECL_FUNCTION_TEMPLATE_P (TREE_VALUE (x))))
return 1;
return 0;
really_overloaded_fn (x)
tree x;
{
- if (TREE_CODE (x) == TREE_LIST
- && (TREE_CODE (TREE_VALUE (x)) == FUNCTION_DECL
- || TREE_CODE (TREE_VALUE (x)) == TEMPLATE_DECL))
- return 1;
-
- return 0;
+ return TREE_CODE (x) != FUNCTION_DECL
+ && is_overloaded_fn (x);
}
tree
get_first_fn (from)
tree from;
{
- if (TREE_CODE (from) == FUNCTION_DECL)
+ if (TREE_CODE (from) == FUNCTION_DECL
+ || TREE_CODE (from) == TEMPLATE_ID_EXPR
+ || DECL_FUNCTION_TEMPLATE_P (from))
return from;
my_friendly_assert (TREE_CODE (from) == TREE_LIST, 9);
return v;
}
+/* Given a TEMPLATE_TEMPLATE_PARM node T, create a new one together with its
+ lang_specific field and its corresponding TEMPLATE_DECL node */
+
+tree
+copy_template_template_parm (t)
+ tree t;
+{
+ tree template = TYPE_NAME (t);
+ tree t2 = make_lang_type (TEMPLATE_TEMPLATE_PARM);
+ template = copy_node (template);
+ copy_lang_decl (template);
+ TREE_TYPE (template) = t2;
+ TYPE_NAME (t2) = template;
+ TYPE_STUB_DECL (t2) = template;
+
+ /* No need to copy these */
+ TYPE_FIELDS (t2) = TYPE_FIELDS (t);
+ CLASSTYPE_TEMPLATE_INFO (t2) = CLASSTYPE_TEMPLATE_INFO (t);
+ return t2;
+}
+
/* Subroutine of copy_to_permanent
Assuming T is a node build bottom-up, make it all exist on
case VAR_DECL:
case FUNCTION_DECL:
case CONST_DECL:
- break;
+ /* Rather than aborting, return error_mark_node. This allows us
+ to report a sensible error message on code like this:
+
+ void g() { int i; f<i>(7); } */
+ return error_mark_node;
case PARM_DECL:
{
case COND_EXPR:
case TARGET_EXPR:
- case NEW_EXPR:
+ case AGGR_INIT_EXPR:
t = copy_node (t);
TREE_OPERAND (t, 0) = mapcar (TREE_OPERAND (t, 0), func);
TREE_OPERAND (t, 1) = mapcar (TREE_OPERAND (t, 1), func);
case POSTINCREMENT_EXPR:
case ARRAY_REF:
case SCOPE_REF:
+ case TRY_CATCH_EXPR:
+ case WITH_CLEANUP_EXPR:
t = copy_node (t);
TREE_OPERAND (t, 0) = mapcar (TREE_OPERAND (t, 0), func);
TREE_OPERAND (t, 1) = mapcar (TREE_OPERAND (t, 1), func);
case TRUTH_NOT_EXPR:
case NOP_EXPR:
case COMPONENT_REF:
+ case CLEANUP_POINT_EXPR:
t = copy_node (t);
TREE_OPERAND (t, 0) = mapcar (TREE_OPERAND (t, 0), func);
return t;
CONSTRUCTOR_ELTS (t) = mapcar (CONSTRUCTOR_ELTS (t), func);
return t;
+ case TEMPLATE_TEMPLATE_PARM:
+ return copy_template_template_parm (t);
+
case RECORD_TYPE:
if (TYPE_PTRMEMFUNC_P (t))
return build_ptrmemfunc_type
void
print_lang_statistics ()
{
- extern struct obstack maybepermanent_obstack, decl_obstack;
+ extern struct 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
return t;
else if (TREE_CODE (t) == TARGET_EXPR)
{
- if (TREE_CODE (TREE_OPERAND (t, 1)) == NEW_EXPR)
+ if (TREE_CODE (TREE_OPERAND (t, 1)) == AGGR_INIT_EXPR)
{
mark_used (TREE_OPERAND (TREE_OPERAND (TREE_OPERAND (t, 1), 0), 0));
return build_cplus_new
/* 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. */
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')
&& TEMPLATE_CONST_LEVEL (t1) == TEMPLATE_CONST_LEVEL (t2);
case SIZEOF_EXPR:
+ case ALIGNOF_EXPR:
if (TREE_CODE (TREE_OPERAND (t1, 0)) != TREE_CODE (TREE_OPERAND (t2, 0)))
return 0;
if (TREE_CODE_CLASS (TREE_CODE (TREE_OPERAND (t1, 0))) == 't')
return comptypes (TREE_OPERAND (t1, 0), TREE_OPERAND (t2, 0), 1);
break;
+
+ default:
+ break;
}
switch (TREE_CODE_CLASS (code1))
int len;
{
register tree node;
- push_obstacks_nochange ();
- resume_temporary_allocation ();
+ register struct obstack *ambient_obstack = current_obstack;
+ current_obstack = expression_obstack;
node = make_tree_vec (len);
- pop_obstacks ();
+ current_obstack = ambient_obstack;
return node;
}
+void
+push_expression_obstack ()
+{
+ push_obstacks_nochange ();
+ current_obstack = expression_obstack;
+}
+
/* The type of ARG when used as an lvalue. */
tree