aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMark Mitchell <mark@codesourcery.com>1999-11-05 09:26:11 +0000
committerMark Mitchell <mmitchel@gcc.gnu.org>1999-11-05 09:26:11 +0000
commit8dfaeb6384f2630d761cd174c9ed1048f2d70ff9 (patch)
tree2bcac642768c7fd2d983046a13ba0c097ac83b2e
parent71144a650c7723a6548f4795eb7c09304c242a03 (diff)
downloadgcc-8dfaeb6384f2630d761cd174c9ed1048f2d70ff9.zip
gcc-8dfaeb6384f2630d761cd174c9ed1048f2d70ff9.tar.gz
gcc-8dfaeb6384f2630d761cd174c9ed1048f2d70ff9.tar.bz2
Makefile.in (typeck2.o): Depend on output.h.
* Makefile.in (typeck2.o): Depend on output.h. * typeck2.c: Include output.h. * decl.c (flag_ansi): Remove declaration. * pt.c (tinst_level_tick): Make it static. (last_template_error_tick): Likewise. * cp-tree.h (mapcar): Remove declaration. (search_tree): Likewise. (walk_tree_fn): New typedef. (walk_tree): New function. * tree.c (bot_manip): Change prototype. Adjust to be called via walk_tree. (bot_replace): Likewise. (no_linkage_helper): Likewise. (copy_tree_r): New function. (search_tree): Rename, and adjust, to become ... (walk_tree): New function. (mapcar): Remove. (target_remap): Remove. (target_remap_count): Likewise. (break_out_target_exprs): Use walk_tree. * decl.c (local_variable_p): Change prototype. (check_default_argument): Use walk_tree. * pt.c (for_each_template_parm_r): New function, split out from ... (for_each_template_parm): Here. Use it, via walk_tree. From-SVN: r30412
-rw-r--r--gcc/cp/ChangeLog2
-rw-r--r--gcc/cp/cp-tree.h4
-rw-r--r--gcc/cp/decl.c13
-rw-r--r--gcc/cp/pt.c290
-rw-r--r--gcc/cp/tree.c604
5 files changed, 294 insertions, 619 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 19e5c97..1882c28 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -19,7 +19,7 @@
(copy_tree_r): New function.
(search_tree): Rename, and adjust, to become ...
(walk_tree): New function.
- (mapcar): Rtemove.
+ (mapcar): Remove.
(target_remap): Remove.
(target_remap_count): Likewise.
(break_out_target_exprs): Use walk_tree.
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index 882ca04..6f8f1b7 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -3986,7 +3986,6 @@ extern int varargs_function_p PROTO((tree));
extern int really_overloaded_fn PROTO((tree));
extern int cp_tree_equal PROTO((tree, tree));
extern int can_free PROTO((struct obstack *, tree));
-extern tree mapcar PROTO((tree, tree (*) (tree)));
extern tree no_linkage_check PROTO((tree));
extern void debug_binfo PROTO((tree));
extern void push_expression_obstack PROTO((void));
@@ -3994,7 +3993,8 @@ extern void push_permanent_obstack PROTO((void));
extern tree build_dummy_object PROTO((tree));
extern tree maybe_dummy_object PROTO((tree, tree *));
extern int is_dummy_object PROTO((tree));
-extern tree search_tree PROTO((tree *, tree (*)(tree *)));
+typedef tree (*walk_tree_fn) PROTO((tree *, int *, void *));
+extern tree walk_tree PROTO((tree *, walk_tree_fn, void *));
extern int cp_valid_lang_attribute PROTO((tree, tree, tree, tree));
extern tree make_ptrmem_cst PROTO((tree, tree));
extern tree cp_build_qualified_type_real PROTO((tree, int, int));
diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index 40d1396..80aec15 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -141,7 +141,7 @@ static boolean typename_compare PROTO((hash_table_key, hash_table_key));
static void push_binding PROTO((tree, tree, struct binding_level*));
static int add_binding PROTO((tree, tree));
static void pop_binding PROTO((tree, tree));
-static tree local_variable_p PROTO((tree *));
+static tree local_variable_p PROTO((tree *, int *, void *));
static tree find_binding PROTO((tree, tree));
static tree select_decl PROTO((tree, int));
static int lookup_flags PROTO((int, int));
@@ -349,11 +349,6 @@ extern int flag_no_builtin;
extern int flag_no_nonansi_builtin;
-/* Nonzero means enable obscure ANSI features and disable GNU extensions
- that might cause ANSI-compliant code to be miscompiled. */
-
-extern int flag_ansi;
-
/* Nonzero if we want to support huge (> 2^(sizeof(short)*8-1) bytes)
objects. */
extern int flag_huge_objects;
@@ -11189,8 +11184,10 @@ require_complete_types_for_parms (parms)
NULL_TREE otherwise. */
static tree
-local_variable_p (tp)
+local_variable_p (tp, walk_subtrees, data)
tree *tp;
+ int *walk_subtrees ATTRIBUTE_UNUSED;
+ void *data ATTRIBUTE_UNUSED;
{
tree t = *tp;
@@ -11272,7 +11269,7 @@ check_default_argument (decl, arg)
The keyword `this' shall not be used in a default argument of a
member function. */
- var = search_tree (&arg, local_variable_p);
+ var = walk_tree (&arg, local_variable_p, NULL);
if (var)
{
cp_error ("default argument `%E' uses local variable `%D'",
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index c96d032..c70147d 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -4032,83 +4032,56 @@ lookup_template_class (d1, arglist, in_decl, context, entering_scope)
}
}
-/* For each TEMPLATE_TYPE_PARM, TEMPLATE_TEMPLATE_PARM, or
- TEMPLATE_PARM_INDEX in T, call FN with the parameter and the DATA.
- If FN returns non-zero, the iteration is terminated, and
- for_each_template_parm returns 1. Otherwise, the iteration
- continues. If FN never returns a non-zero value, the value
- returned by for_each_template_parm is 0. If FN is NULL, it is
- considered to be the function which always returns 1. */
-
-static int
-for_each_template_parm (t, fn, data)
- tree t;
- tree_fn_t fn;
- void* data;
+struct pair_fn_data
{
- if (!t)
- return 0;
+ tree_fn_t fn;
+ void *data;
+};
+
+/* Called from for_each_template_parm via walk_tree. */
+static tree
+for_each_template_parm_r (tp, walk_subtrees, d)
+ tree *tp;
+ int *walk_subtrees;
+ void *d;
+{
+ tree t = *tp;
+ struct pair_fn_data *pfd = (struct pair_fn_data *) d;
+ tree_fn_t fn = pfd->fn;
+ void *data = pfd->data;
+
if (TREE_CODE_CLASS (TREE_CODE (t)) == 't'
&& for_each_template_parm (TYPE_CONTEXT (t), fn, data))
- return 1;
+ return error_mark_node;
switch (TREE_CODE (t))
{
- case ARRAY_REF:
- case OFFSET_REF:
- return (for_each_template_parm (TREE_OPERAND (t, 0), fn, data)
- || for_each_template_parm (TREE_OPERAND (t, 1), fn, data));
-
- case IDENTIFIER_NODE:
- if (!IDENTIFIER_TEMPLATE (t))
- return 0;
- my_friendly_abort (42);
-
- /* aggregates of tree nodes */
- case TREE_VEC:
- {
- int i = TREE_VEC_LENGTH (t);
- while (i--)
- if (for_each_template_parm (TREE_VEC_ELT (t, i), fn, data))
- return 1;
- return 0;
- }
- case TREE_LIST:
- if (for_each_template_parm (TREE_PURPOSE (t), fn, data)
- || for_each_template_parm (TREE_VALUE (t), fn, data))
- return 1;
- return for_each_template_parm (TREE_CHAIN (t), fn, data);
-
- case OVERLOAD:
- if (for_each_template_parm (OVL_FUNCTION (t), fn, data))
- return 1;
- return for_each_template_parm (OVL_CHAIN (t), fn, data);
-
- /* constructed type nodes */
- case POINTER_TYPE:
- case REFERENCE_TYPE:
- return for_each_template_parm (TREE_TYPE (t), fn, data);
-
case RECORD_TYPE:
if (TYPE_PTRMEMFUNC_FLAG (t))
- return for_each_template_parm (TYPE_PTRMEMFUNC_FN_TYPE (t),
- fn, data);
+ break;
/* Fall through. */
case UNION_TYPE:
case ENUMERAL_TYPE:
- if (! TYPE_TEMPLATE_INFO (t))
- return 0;
- return for_each_template_parm (TREE_VALUE
- (TYPE_TEMPLATE_INFO (t)),
- fn, data);
+ if (!TYPE_TEMPLATE_INFO (t))
+ *walk_subtrees = 0;
+ else if (for_each_template_parm (TREE_VALUE (TYPE_TEMPLATE_INFO (t)),
+ fn, data))
+ return error_mark_node;
+ break;
+
case METHOD_TYPE:
+ /* Since we're not going to walk subtrees, we have to do this
+ explicitly here. */
if (for_each_template_parm (TYPE_METHOD_BASETYPE (t), fn, data))
- return 1;
- /* Fall through. */
+ return error_mark_node;
case FUNCTION_TYPE:
+ /* Check the return type. */
+ if (for_each_template_parm (TREE_TYPE (t), fn, data))
+ return error_mark_node;
+
/* Check the parameter types. Since default arguments are not
instantiated until they are needed, the TYPE_ARG_TYPES may
contain expressions that involve template parameters. But,
@@ -4120,132 +4093,72 @@ for_each_template_parm (t, fn, data)
for (parm = TYPE_ARG_TYPES (t); parm; parm = TREE_CHAIN (parm))
if (for_each_template_parm (TREE_VALUE (parm), fn, data))
- return 1;
- }
-
- /* Check the return type, too. */
- return for_each_template_parm (TREE_TYPE (t), fn, data);
-
- case ARRAY_TYPE:
- if (for_each_template_parm (TYPE_DOMAIN (t), fn, data))
- return 1;
- return for_each_template_parm (TREE_TYPE (t), fn, data);
- case OFFSET_TYPE:
- if (for_each_template_parm (TYPE_OFFSET_BASETYPE (t), fn, data))
- return 1;
- return for_each_template_parm (TREE_TYPE (t), fn, data);
-
- /* decl nodes */
- case TYPE_DECL:
- return for_each_template_parm (TREE_TYPE (t), fn, data);
+ return error_mark_node;
- case TEMPLATE_DECL:
- /* A template template parameter is encountered */
- if (DECL_TEMPLATE_TEMPLATE_PARM_P (t))
- return for_each_template_parm (TREE_TYPE (t), fn, data);
- /* Already substituted template template parameter */
- return 0;
-
- case CONST_DECL:
- if (for_each_template_parm (DECL_INITIAL (t), fn, data))
- return 1;
- goto check_type_and_context;
+ /* Since we've already handled the TYPE_ARG_TYPES, we don't
+ want walk_tree walking into them itself. */
+ *walk_subtrees = 0;
+ }
+ break;
case FUNCTION_DECL:
case VAR_DECL:
if (DECL_LANG_SPECIFIC (t) && DECL_TEMPLATE_INFO (t)
&& for_each_template_parm (DECL_TI_ARGS (t), fn, data))
- return 1;
- /* fall through */
+ return error_mark_node;
+ /* Fall through. */
+
+ case CONST_DECL:
case PARM_DECL:
- check_type_and_context:
- if (for_each_template_parm (TREE_TYPE (t), fn, data))
- return 1;
if (DECL_CONTEXT (t)
&& for_each_template_parm (DECL_CONTEXT (t), fn, data))
- return 1;
- return 0;
-
- case CALL_EXPR:
- return (for_each_template_parm (TREE_OPERAND (t, 0), fn, data)
- || for_each_template_parm (TREE_OPERAND (t, 1), fn, data));
-
- case ADDR_EXPR:
- return for_each_template_parm (TREE_OPERAND (t, 0), fn, data);
+ return error_mark_node;
+ break;
- /* template parm nodes */
case TEMPLATE_TEMPLATE_PARM:
/* Record template parameters such as `T' inside `TT<T>'. */
if (TEMPLATE_TEMPLATE_PARM_TEMPLATE_INFO (t)
&& for_each_template_parm (TYPE_TI_ARGS (t), fn, data))
- return 1;
+ return error_mark_node;
+ /* Fall through. */
+
case TEMPLATE_TYPE_PARM:
case TEMPLATE_PARM_INDEX:
- if (fn)
- return (*fn)(t, data);
- else
- return 1;
-
- /* simple type nodes */
- case INTEGER_TYPE:
- if (for_each_template_parm (TYPE_MIN_VALUE (t), fn, data))
- return 1;
- return for_each_template_parm (TYPE_MAX_VALUE (t), fn, data);
-
- case REAL_TYPE:
- case COMPLEX_TYPE:
- case VOID_TYPE:
- case BOOLEAN_TYPE:
- case NAMESPACE_DECL:
- case FIELD_DECL:
- return 0;
-
- /* constants */
- case INTEGER_CST:
- case REAL_CST:
- case STRING_CST:
- return 0;
-
- case ERROR_MARK:
- /* Non-error_mark_node ERROR_MARKs are bad things. */
- my_friendly_assert (t == error_mark_node, 274);
- /* NOTREACHED */
- return 0;
-
- case PTRMEM_CST:
- return for_each_template_parm (TREE_TYPE (t), fn, data);
-
- case SCOPE_REF:
- return for_each_template_parm (TREE_OPERAND (t, 0), fn, data);
+ if (fn && (*fn)(t, data))
+ return error_mark_node;
+ else if (!fn)
+ return error_mark_node;
+ break;
- case CONSTRUCTOR:
- if (TREE_TYPE (t) && TYPE_PTRMEMFUNC_P (TREE_TYPE (t)))
- return for_each_template_parm (TYPE_PTRMEMFUNC_FN_TYPE
- (TREE_TYPE (t)), fn, data);
- return for_each_template_parm (TREE_OPERAND (t, 1), fn, data);
+ case TEMPLATE_DECL:
+ /* A template template parameter is encountered */
+ if (DECL_TEMPLATE_TEMPLATE_PARM_P (t)
+ && for_each_template_parm (TREE_TYPE (t), fn, data))
+ return error_mark_node;
- case SIZEOF_EXPR:
- case ALIGNOF_EXPR:
- return for_each_template_parm (TREE_OPERAND (t, 0), fn, data);
+ /* Already substituted template template parameter */
+ *walk_subtrees = 0;
+ break;
case TYPENAME_TYPE:
- if (!fn)
- return 1;
- return (for_each_template_parm (TYPE_CONTEXT (t), fn, data)
- || for_each_template_parm (TYPENAME_TYPE_FULLNAME (t),
- fn, data));
+ if (!fn || for_each_template_parm (TYPENAME_TYPE_FULLNAME (t), fn, data))
+ return error_mark_node;
+ break;
+ case CONSTRUCTOR:
+ if (TREE_TYPE (t) && TYPE_PTRMEMFUNC_P (TREE_TYPE (t))
+ && for_each_template_parm (TYPE_PTRMEMFUNC_FN_TYPE
+ (TREE_TYPE (t)), fn, data))
+ return error_mark_node;
+ break;
+
case INDIRECT_REF:
case COMPONENT_REF:
/* If there's no type, then this thing must be some expression
involving template parameters. */
if (!fn && !TREE_TYPE (t))
- return 1;
- if (TREE_CODE (t) == COMPONENT_REF)
- return (for_each_template_parm (TREE_OPERAND (t, 0), fn, data)
- || for_each_template_parm (TREE_OPERAND (t, 1), fn, data));
- else
- return for_each_template_parm (TREE_OPERAND (t, 0), fn, data);
+ return error_mark_node;
+ break;
case MODOP_EXPR:
case CAST_EXPR:
@@ -4259,32 +4172,39 @@ for_each_template_parm (t, fn, data)
case LOOKUP_EXPR:
case PSEUDO_DTOR_EXPR:
if (!fn)
- return 1;
- /* Fall through. */
+ return error_mark_node;
+ break;
default:
- switch (TREE_CODE_CLASS (TREE_CODE (t)))
- {
- case '1':
- case '2':
- case 'e':
- case '<':
- {
- int i;
- for (i = first_rtl_op (TREE_CODE (t)); --i >= 0;)
- if (for_each_template_parm (TREE_OPERAND (t, i), fn, data))
- return 1;
- return 0;
- }
- default:
- break;
- }
- sorry ("testing %s for template parms",
- tree_code_name [(int) TREE_CODE (t)]);
- my_friendly_abort (82);
- /* NOTREACHED */
- return 0;
+ break;
}
+
+ /* We didn't find any template parameters we liked. */
+ return NULL_TREE;
+}
+
+/* For each TEMPLATE_TYPE_PARM, TEMPLATE_TEMPLATE_PARM, or
+ TEMPLATE_PARM_INDEX in T, call FN with the parameter and the DATA.
+ If FN returns non-zero, the iteration is terminated, and
+ for_each_template_parm returns 1. Otherwise, the iteration
+ continues. If FN never returns a non-zero value, the value
+ returned by for_each_template_parm is 0. If FN is NULL, it is
+ considered to be the function which always returns 1. */
+
+static int
+for_each_template_parm (t, fn, data)
+ tree t;
+ tree_fn_t fn;
+ void* data;
+{
+ struct pair_fn_data pfd;
+
+ /* Set up. */
+ pfd.fn = fn;
+ pfd.data = data;
+
+ /* Walk the tree. */
+ return walk_tree (&t, for_each_template_parm_r, &pfd) != NULL_TREE;
}
int
@@ -4301,8 +4221,8 @@ extern int max_tinst_depth;
#ifdef GATHER_STATISTICS
int depth_reached;
#endif
-int tinst_level_tick;
-int last_template_error_tick;
+static int tinst_level_tick;
+static int last_template_error_tick;
/* Print out all the template instantiations that we are currently
working on. If ERR, we are being called from cp_thing, so do
diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c
index 0dbc539..d1b725b 100644
--- a/gcc/cp/tree.c
+++ b/gcc/cp/tree.c
@@ -30,8 +30,8 @@ Boston, MA 02111-1307, USA. */
#include "ggc.h"
#include "splay-tree.h"
-static tree bot_manip PROTO((tree));
-static tree bot_replace PROTO((tree *));
+static tree bot_manip PROTO((tree *, int *, void *));
+static tree bot_replace PROTO((tree *, int *, void *));
static tree build_cplus_array_type_1 PROTO((tree, tree));
static void list_hash_add PROTO((int, tree));
static int list_hash PROTO((tree, tree, tree));
@@ -39,9 +39,10 @@ static tree list_hash_lookup PROTO((int, tree, tree, tree));
static void propagate_binfo_offsets PROTO((tree, tree));
static int avoid_overlap PROTO((tree, tree));
static cp_lvalue_kind lvalue_p_1 PROTO((tree, int));
-static tree no_linkage_helper PROTO((tree *));
+static tree no_linkage_helper PROTO((tree *, int *, void *));
static tree build_srcloc PROTO((char *, int));
static void mark_list_hash PROTO ((void *));
+static tree copy_tree_r PROTO ((tree *, int *, void *));
#define CEIL(x,y) (((x) + (y) - 1) / (y))
@@ -1524,221 +1525,181 @@ copy_template_template_parm (t)
return t2;
}
-/* Walk through the tree structure T, applying func. If func ever returns
- non-null, return that value. */
+/* Apply FUNC to all the sub-trees of TP in a pre-order traversal.
+ FUNC is called with the DATA and the address of each sub-tree. If
+ FUNC returns a non-NULL value, the traversal is aborted, and the
+ value returned by FUNC is returned. */
-tree
-search_tree (tp, func)
+tree
+walk_tree (tp, func, data)
tree *tp;
- tree (*func) PROTO((tree *));
+ walk_tree_fn func;
+ void *data;
{
-#define TRY(ARG) if (tmp=search_tree (&ARG, func), tmp != NULL_TREE) return tmp
-
- tree t = *tp;
- tree tmp;
- enum tree_code code;
+ enum tree_code code;
+ int walk_subtrees;
+ tree result;
- if (t == NULL_TREE)
+#define WALK_SUBTREE(NODE) \
+ do \
+ { \
+ result = walk_tree (&(NODE), func, data); \
+ if (result) \
+ return result; \
+ } \
+ while (0)
+
+ /* Skip empty subtrees. */
+ if (!*tp)
return NULL_TREE;
-
- tmp = func (tp);
- if (tmp)
- return tmp;
- /* Handle some common cases up front. */
- code = TREE_CODE (t);
- if (TREE_CODE_CLASS (code) == '1')
+ /* Call the function. */
+ walk_subtrees = 1;
+ result = (*func) (tp, &walk_subtrees, data);
+
+ /* If we found something, return it. */
+ if (result)
+ return result;
+
+ /* Even if we didn't, FUNC may have decided that there was nothing
+ interesting below this point in the tree. */
+ if (!walk_subtrees)
+ return NULL_TREE;
+
+ code = TREE_CODE (*tp);
+
+ /* Handle commmon cases up front. */
+ if (IS_EXPR_CODE_CLASS (TREE_CODE_CLASS (code))
+ || TREE_CODE_CLASS (code) == 'r')
{
- TRY (TREE_OPERAND (t, 0));
+ int i;
+
+ /* Walk over all the sub-trees of this operand. */
+ for (i = first_rtl_op (code) - 1; i >= 0; --i)
+ WALK_SUBTREE (TREE_OPERAND (*tp, i));
+
+ /* We didn't find what we were looking for. */
return NULL_TREE;
}
- else if (TREE_CODE_CLASS (code) == '2' || TREE_CODE_CLASS (code) == '<')
+ else if (TREE_CODE_CLASS (code) == 'd')
{
- TRY (TREE_OPERAND (t, 0));
- TRY (TREE_OPERAND (t, 1));
+ WALK_SUBTREE (TREE_TYPE (*tp));
+ WALK_SUBTREE (DECL_INITIAL (*tp));
+ WALK_SUBTREE (DECL_SIZE (*tp));
+
+ /* We didn't find what we were looking for. */
return NULL_TREE;
}
+ /* Not one of the easy cases. We must explicitly go through the
+ children. */
switch (code)
{
case ERROR_MARK:
- break;
-
case IDENTIFIER_NODE:
+ case INTEGER_CST:
+ case REAL_CST:
+ case STRING_CST:
+ case DEFAULT_ARG:
+ case TEMPLATE_TEMPLATE_PARM:
+ case TEMPLATE_PARM_INDEX:
+ case TEMPLATE_TYPE_PARM:
+ case REAL_TYPE:
+ case COMPLEX_TYPE:
+ case VOID_TYPE:
+ case BOOLEAN_TYPE:
+ case TYPENAME_TYPE:
+ case UNION_TYPE:
+ case ENUMERAL_TYPE:
+ case TYPEOF_TYPE:
+ case BLOCK:
+ /* None of thse have subtrees other than those already walked
+ above. */
break;
- case VAR_DECL:
- case FUNCTION_DECL:
- case CONST_DECL:
- case TEMPLATE_DECL:
- case NAMESPACE_DECL:
- break;
-
- case TYPE_DECL:
- TRY (TREE_TYPE (t));
+ case PTRMEM_CST:
+ WALK_SUBTREE (TREE_TYPE (*tp));
break;
- case PARM_DECL:
- TRY (TREE_TYPE (t));
- TRY (TREE_CHAIN (t));
+ case POINTER_TYPE:
+ case REFERENCE_TYPE:
+ WALK_SUBTREE (TREE_TYPE (*tp));
break;
case TREE_LIST:
- TRY (TREE_PURPOSE (t));
- TRY (TREE_VALUE (t));
- TRY (TREE_CHAIN (t));
+ WALK_SUBTREE (TREE_PURPOSE (*tp));
+ WALK_SUBTREE (TREE_VALUE (*tp));
+ WALK_SUBTREE (TREE_CHAIN (*tp));
break;
case OVERLOAD:
- TRY (OVL_FUNCTION (t));
- TRY (OVL_CHAIN (t));
+ WALK_SUBTREE (OVL_FUNCTION (*tp));
+ WALK_SUBTREE (OVL_CHAIN (*tp));
break;
case TREE_VEC:
{
- int len = TREE_VEC_LENGTH (t);
-
- t = copy_node (t);
+ int len = TREE_VEC_LENGTH (*tp);
while (len--)
- TRY (TREE_VEC_ELT (t, len));
+ WALK_SUBTREE (TREE_VEC_ELT (*tp, len));
}
break;
- case INTEGER_CST:
- case REAL_CST:
- case STRING_CST:
- case DEFAULT_ARG:
- break;
-
- case PTRMEM_CST:
- TRY (TREE_TYPE (t));
- break;
-
- case COND_EXPR:
- case TARGET_EXPR:
- case AGGR_INIT_EXPR:
- case NEW_EXPR:
- TRY (TREE_OPERAND (t, 0));
- TRY (TREE_OPERAND (t, 1));
- TRY (TREE_OPERAND (t, 2));
- break;
-
- case TRUTH_AND_EXPR:
- case TRUTH_OR_EXPR:
- case TRUTH_XOR_EXPR:
- case TRUTH_ANDIF_EXPR:
- case TRUTH_ORIF_EXPR:
- case PREDECREMENT_EXPR:
- case PREINCREMENT_EXPR:
- case POSTDECREMENT_EXPR:
- case POSTINCREMENT_EXPR:
- case ARRAY_REF:
- case SCOPE_REF:
- case TRY_CATCH_EXPR:
- case WITH_CLEANUP_EXPR:
- case CALL_EXPR:
- case COMPOUND_EXPR:
- case MODIFY_EXPR:
- case INIT_EXPR:
- case OFFSET_REF:
- TRY (TREE_OPERAND (t, 0));
- TRY (TREE_OPERAND (t, 1));
- break;
-
- case SAVE_EXPR:
- case ADDR_EXPR:
- case INDIRECT_REF:
- case TRUTH_NOT_EXPR:
- case COMPONENT_REF:
- case CLEANUP_POINT_EXPR:
- case LOOKUP_EXPR:
- case THROW_EXPR:
- case EXIT_EXPR:
- case LOOP_EXPR:
- case BIT_FIELD_REF:
- case VA_ARG_EXPR:
- TRY (TREE_OPERAND (t, 0));
- break;
-
- case MODOP_EXPR:
- case ARROW_EXPR:
- case DOTSTAR_EXPR:
- case TYPEID_EXPR:
- case PSEUDO_DTOR_EXPR:
- break;
-
case COMPLEX_CST:
- TRY (TREE_REALPART (t));
- TRY (TREE_IMAGPART (t));
+ WALK_SUBTREE (TREE_REALPART (*tp));
+ WALK_SUBTREE (TREE_IMAGPART (*tp));
break;
case CONSTRUCTOR:
- TRY (CONSTRUCTOR_ELTS (t));
- break;
-
- case TEMPLATE_TEMPLATE_PARM:
- case TEMPLATE_PARM_INDEX:
- case TEMPLATE_TYPE_PARM:
- break;
-
- case BIND_EXPR:
- case STMT_EXPR:
- break;
-
- case REAL_TYPE:
- case COMPLEX_TYPE:
- case VOID_TYPE:
- case BOOLEAN_TYPE:
- case TYPENAME_TYPE:
- case UNION_TYPE:
- case ENUMERAL_TYPE:
- case TYPEOF_TYPE:
+ WALK_SUBTREE (CONSTRUCTOR_ELTS (*tp));
break;
- case POINTER_TYPE:
- case REFERENCE_TYPE:
- TRY (TREE_TYPE (t));
- break;
+ case METHOD_TYPE:
+ WALK_SUBTREE (TYPE_METHOD_BASETYPE (*tp));
+ /* Fall through. */
case FUNCTION_TYPE:
- case METHOD_TYPE:
- TRY (TREE_TYPE (t));
- TRY (TYPE_ARG_TYPES (t));
+ WALK_SUBTREE (TREE_TYPE (*tp));
+ WALK_SUBTREE (TYPE_ARG_TYPES (*tp));
break;
case ARRAY_TYPE:
- TRY (TREE_TYPE (t));
- TRY (TYPE_DOMAIN (t));
+ WALK_SUBTREE (TREE_TYPE (*tp));
+ WALK_SUBTREE (TYPE_DOMAIN (*tp));
break;
case INTEGER_TYPE:
- TRY (TYPE_MAX_VALUE (t));
+ WALK_SUBTREE (TYPE_MIN_VALUE (*tp));
+ WALK_SUBTREE (TYPE_MAX_VALUE (*tp));
break;
case OFFSET_TYPE:
- TRY (TREE_TYPE (t));
- TRY (TYPE_OFFSET_BASETYPE (t));
+ WALK_SUBTREE (TREE_TYPE (*tp));
+ WALK_SUBTREE (TYPE_OFFSET_BASETYPE (*tp));
break;
case RECORD_TYPE:
- if (TYPE_PTRMEMFUNC_P (t))
- TRY (TYPE_PTRMEMFUNC_FN_TYPE (t));
+ if (TYPE_PTRMEMFUNC_P (*tp))
+ WALK_SUBTREE (TYPE_PTRMEMFUNC_FN_TYPE (*tp));
break;
default:
my_friendly_abort (19990803);
}
+ /* We didn't find what we were looking for. */
return NULL_TREE;
-#undef TRY
+#undef WALK_SUBTREE
}
-/* Passed to search_tree. Checks for the use of types with no linkage. */
+/* Passed to walk_tree. Checks for the use of types with no linkage. */
static tree
-no_linkage_helper (tp)
+no_linkage_helper (tp, walk_subtrees, data)
tree *tp;
+ int *walk_subtrees ATTRIBUTE_UNUSED;
+ void *data ATTRIBUTE_UNUSED;
{
tree t = *tp;
@@ -1762,269 +1723,47 @@ no_linkage_check (t)
if (processing_template_decl)
return NULL_TREE;
- t = search_tree (&t, no_linkage_helper);
+ t = walk_tree (&t, no_linkage_helper, NULL);
if (t != error_mark_node)
return t;
return NULL_TREE;
}
+/* Passed to walk_tree. Copies the node pointed to, if appropriate. */
-/* Make copies of all the nodes below T. If FUNC is non-NULL, call it
- for each node. */
-
-tree
-mapcar (t, func)
- tree t;
- tree (*func) PROTO((tree));
-{
- tree tmp;
- enum tree_code code;
-
- if (t == NULL_TREE)
- return t;
-
- if (func)
- {
- tmp = func (t);
- if (tmp)
- return tmp;
- }
-
- /* Handle some common cases up front. */
- code = TREE_CODE (t);
- if (TREE_CODE_CLASS (code) == '1')
- {
- t = copy_node (t);
- TREE_TYPE (t) = mapcar (TREE_TYPE (t), func);
- TREE_OPERAND (t, 0) = mapcar (TREE_OPERAND (t, 0), func);
- return t;
- }
- else if (TREE_CODE_CLASS (code) == '2' || TREE_CODE_CLASS (code) == '<')
- {
- t = copy_node (t);
- TREE_TYPE (t) = mapcar (TREE_TYPE (t), func);
- TREE_OPERAND (t, 0) = mapcar (TREE_OPERAND (t, 0), func);
- TREE_OPERAND (t, 1) = mapcar (TREE_OPERAND (t, 1), func);
- return t;
- }
-
- switch (TREE_CODE (t))
+static tree
+copy_tree_r (tp, walk_subtrees, data)
+ tree *tp;
+ int *walk_subtrees ATTRIBUTE_UNUSED;
+ void *data ATTRIBUTE_UNUSED;
+{
+ enum tree_code code = TREE_CODE (*tp);
+
+ /* We make copies of most nodes. */
+ if (IS_EXPR_CODE_CLASS (TREE_CODE_CLASS (code))
+ || TREE_CODE_CLASS (code) == 'r'
+ || TREE_CODE_CLASS (code) == 'c'
+ || code == PARM_DECL
+ || code == TREE_LIST
+ || code == TREE_VEC
+ || code == OVERLOAD)
{
- case ERROR_MARK:
- return error_mark_node;
-
- case VAR_DECL:
- case FUNCTION_DECL:
- case CONST_DECL:
- /* 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); }
-
- In a case like:
-
- void g() { const int i = 7; f<i>(7); }
-
- however, we must actually return the constant initializer. */
- if (TREE_READONLY_DECL_P (t))
- {
- tmp = decl_constant_value (t);
- if (tmp != t)
- return mapcar (tmp, func);
- }
- return error_mark_node;
-
- case PARM_DECL:
- {
- tree chain = TREE_CHAIN (t);
- t = copy_node (t);
- TREE_CHAIN (t) = mapcar (chain, func);
- TREE_TYPE (t) = mapcar (TREE_TYPE (t), func);
- DECL_INITIAL (t) = mapcar (DECL_INITIAL (t), func);
- DECL_SIZE (t) = mapcar (DECL_SIZE (t), func);
- return t;
- }
-
- case TREE_LIST:
- {
- tree chain = TREE_CHAIN (t);
- t = copy_node (t);
- TREE_PURPOSE (t) = mapcar (TREE_PURPOSE (t), func);
- TREE_VALUE (t) = mapcar (TREE_VALUE (t), func);
- TREE_CHAIN (t) = mapcar (chain, func);
- return t;
- }
-
- case OVERLOAD:
- {
- tree chain = OVL_CHAIN (t);
- t = copy_node (t);
- OVL_FUNCTION (t) = mapcar (OVL_FUNCTION (t), func);
- OVL_CHAIN (t) = mapcar (chain, func);
- return t;
- }
-
- case TREE_VEC:
- {
- int len = TREE_VEC_LENGTH (t);
-
- t = copy_node (t);
- while (len--)
- TREE_VEC_ELT (t, len) = mapcar (TREE_VEC_ELT (t, len), func);
- return t;
- }
+ /* Because the chain gets clobbered when we make a copy, we save it
+ here. */
+ tree chain = TREE_CHAIN (*tp);
- case INTEGER_CST:
- case REAL_CST:
- case STRING_CST:
- return copy_node (t);
-
- case PTRMEM_CST:
- t = copy_node (t);
- TREE_TYPE (t) = mapcar (TREE_TYPE (t), func);
- PTRMEM_CST_MEMBER (t) = mapcar (PTRMEM_CST_MEMBER (t), func);
- return t;
-
- case COND_EXPR:
- case TARGET_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);
- TREE_OPERAND (t, 2) = mapcar (TREE_OPERAND (t, 2), func);
- return t;
-
- case TRUTH_AND_EXPR:
- case TRUTH_OR_EXPR:
- case TRUTH_XOR_EXPR:
- case TRUTH_ANDIF_EXPR:
- case TRUTH_ORIF_EXPR:
- case PREDECREMENT_EXPR:
- case PREINCREMENT_EXPR:
- case POSTDECREMENT_EXPR:
- case POSTINCREMENT_EXPR:
- case ARRAY_REF:
- case SCOPE_REF:
- case TRY_CATCH_EXPR:
- case WITH_CLEANUP_EXPR:
- case COMPOUND_EXPR:
- case MODIFY_EXPR:
- case INIT_EXPR:
- case OFFSET_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);
- return t;
-
- case CALL_EXPR:
- t = copy_node (t);
- TREE_TYPE (t) = mapcar (TREE_TYPE (t), func);
- TREE_OPERAND (t, 0) = mapcar (TREE_OPERAND (t, 0), func);
- TREE_OPERAND (t, 1) = mapcar (TREE_OPERAND (t, 1), func);
- TREE_OPERAND (t, 2) = NULL_TREE;
- return t;
+ /* Copy the node. */
+ *tp = copy_node (*tp);
- case SAVE_EXPR:
- case ADDR_EXPR:
- case INDIRECT_REF:
- case TRUTH_NOT_EXPR:
- case COMPONENT_REF:
- case CLEANUP_POINT_EXPR:
- case THROW_EXPR:
- case STMT_EXPR:
- case VA_ARG_EXPR:
- t = copy_node (t);
- TREE_TYPE (t) = mapcar (TREE_TYPE (t), func);
- TREE_OPERAND (t, 0) = mapcar (TREE_OPERAND (t, 0), func);
- return t;
-
- case POINTER_TYPE:
- tmp = build_pointer_type (mapcar (TREE_TYPE (t), func));
- return cp_build_qualified_type (tmp, TYPE_QUALS (t));
- case REFERENCE_TYPE:
- tmp = build_reference_type (mapcar (TREE_TYPE (t), func));
- return cp_build_qualified_type (tmp, TYPE_QUALS (t));
- case FUNCTION_TYPE:
- tmp = build_function_type (mapcar (TREE_TYPE (t), func),
- mapcar (TYPE_ARG_TYPES (t), func));
- return cp_build_qualified_type (tmp, TYPE_QUALS (t));
- case ARRAY_TYPE:
- tmp = build_cplus_array_type (mapcar (TREE_TYPE (t), func),
- mapcar (TYPE_DOMAIN (t), func));
- return cp_build_qualified_type (tmp, CP_TYPE_QUALS (t));
- case INTEGER_TYPE:
- tmp = build_index_type (mapcar (TYPE_MAX_VALUE (t), func));
- return cp_build_qualified_type (tmp, TYPE_QUALS (t));
- case OFFSET_TYPE:
- tmp = build_offset_type (mapcar (TYPE_OFFSET_BASETYPE (t), func),
- mapcar (TREE_TYPE (t), func));
- return cp_build_qualified_type (tmp, TYPE_QUALS (t));
- case METHOD_TYPE:
- tmp = build_cplus_method_type
- (mapcar (TREE_TYPE (TREE_VALUE (TYPE_ARG_TYPES (t))), func),
- mapcar (TREE_TYPE (t), func),
- mapcar (TREE_CHAIN (TYPE_ARG_TYPES (t)), func));
- return cp_build_qualified_type (tmp, TYPE_QUALS (t));
-
- case COMPLEX_CST:
- t = copy_node (t);
- TREE_REALPART (t) = mapcar (TREE_REALPART (t), func);
- TREE_IMAGPART (t) = mapcar (TREE_REALPART (t), func);
- return t;
-
- case CONSTRUCTOR:
- t = copy_node (t);
- CONSTRUCTOR_ELTS (t) = mapcar (CONSTRUCTOR_ELTS (t), func);
- return t;
-
- case TEMPLATE_TEMPLATE_PARM:
- return copy_template_template_parm (t);
-
- case BIND_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);
- TREE_OPERAND (t, 2) = NULL_TREE;
- return t;
-
- case NEW_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);
- TREE_OPERAND (t, 2) = mapcar (TREE_OPERAND (t, 2), func);
- return t;
-
- case BIT_FIELD_REF:
- t = copy_node (t);
- TREE_TYPE (t) = mapcar (TREE_TYPE (t), func);
- TREE_OPERAND (t, 0) = mapcar (TREE_OPERAND (t, 0), func);
- TREE_OPERAND (t, 1) = mapcar (TREE_OPERAND (t, 1), func);
- TREE_OPERAND (t, 2) = mapcar (TREE_OPERAND (t, 2), func);
- return t;
-
- case LOOKUP_EXPR:
- case EXIT_EXPR:
- case LOOP_EXPR:
- t = copy_node (t);
- TREE_OPERAND (t, 0) = mapcar (TREE_OPERAND (t, 0), func);
- return t;
-
- case RTL_EXPR:
- t = copy_node (t);
- TREE_TYPE (t) = mapcar (TREE_TYPE (t), func);
- return t;
-
- case RECORD_TYPE:
- if (TYPE_PTRMEMFUNC_P (t))
- return build_ptrmemfunc_type
- (mapcar (TYPE_PTRMEMFUNC_FN_TYPE (t), func));
- /* else fall through */
-
- default:
- my_friendly_abort (19990815);
+ /* Now, restore the chain, if appropriate. That will cause
+ walk_tree to walk into the chain as well. */
+ if (code == PARM_DECL || code == TREE_LIST || code == OVERLOAD)
+ TREE_CHAIN (*tp) = chain;
}
- my_friendly_abort (107);
- /* NOTREACHED */
+ else if (code == TEMPLATE_TEMPLATE_PARM)
+ /* These must be copied specially. */
+ *tp = copy_template_template_parm (*tp);
+
return NULL_TREE;
}
@@ -2092,24 +1831,23 @@ array_type_nelts_total (type)
return sz;
}
-/* When we parse a default argument expression, we may create
- temporary variables via TARGET_EXPRs. When we actually use the
- default-argument expression, we make a copy of the expression, but
- we must relpace the temporaries with appropriate local versions. */
-
-/* A map from VAR_DECLs declared in TARGET_EXPRs in a default argument
- to corresponding "instantiations" of those variables. */
-static splay_tree target_remap;
-static int target_remap_count;
-
/* Called from break_out_target_exprs via mapcar. */
static tree
-bot_manip (t)
- tree t;
+bot_manip (tp, walk_subtrees, data)
+ tree *tp;
+ int *walk_subtrees;
+ void *data;
{
+ splay_tree target_remap = ((splay_tree) data);
+ tree t = *tp;
+
if (TREE_CODE (t) != TREE_LIST && ! TREE_SIDE_EFFECTS (t))
- return t;
+ {
+ /* There can't be any TARGET_EXPRs below this point. */
+ *walk_subtrees = 0;
+ return NULL_TREE;
+ }
else if (TREE_CODE (t) == TARGET_EXPR)
{
tree u;
@@ -2131,20 +1869,34 @@ bot_manip (t)
splay_tree_insert (target_remap,
(splay_tree_key) TREE_OPERAND (t, 0),
(splay_tree_value) TREE_OPERAND (u, 0));
- return u;
+
+ /* Replace the old expression with the new version. */
+ *tp = u;
+ /* We don't have to go below this point; the recursive call to
+ break_out_target_exprs will have handled anything below this
+ point. */
+ *walk_subtrees = 0;
+ return NULL_TREE;
}
else if (TREE_CODE (t) == CALL_EXPR)
mark_used (TREE_OPERAND (TREE_OPERAND (t, 0), 0));
- return NULL_TREE;
+ /* Make a copy of this node. */
+ return copy_tree_r (tp, walk_subtrees, NULL);
}
-/* Replace all remapped VAR_DECLs in T with their new equivalents. */
+/* Replace all remapped VAR_DECLs in T with their new equivalents.
+ DATA is really a splay-tree mapping old variables to new
+ variables. */
static tree
-bot_replace (t)
+bot_replace (t, walk_subtrees, data)
tree *t;
+ int *walk_subtrees ATTRIBUTE_UNUSED;
+ void *data;
{
+ splay_tree target_remap = ((splay_tree) data);
+
if (TREE_CODE (*t) == VAR_DECL)
{
splay_tree_node n = splay_tree_lookup (target_remap,
@@ -2156,18 +1908,24 @@ bot_replace (t)
return NULL_TREE;
}
-/* Actually, we'll just clean out the target exprs for the moment. */
+/* When we parse a default argument expression, we may create
+ temporary variables via TARGET_EXPRs. When we actually use the
+ default-argument expression, we make a copy of the expression, but
+ we must replace the temporaries with appropriate local versions. */
tree
break_out_target_exprs (t)
tree t;
{
+ static int target_remap_count;
+ static splay_tree target_remap;
+
if (!target_remap_count++)
target_remap = splay_tree_new (splay_tree_compare_pointers,
/*splay_tree_delete_key_fn=*/NULL,
/*splay_tree_delete_value_fn=*/NULL);
- t = mapcar (t, bot_manip);
- search_tree (&t, bot_replace);
+ walk_tree (&t, bot_manip, target_remap);
+ walk_tree (&t, bot_replace, target_remap);
if (!--target_remap_count)
{