summaryrefslogtreecommitdiff
path: root/gcc/tree.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/tree.c')
-rw-r--r--gcc/tree.c424
1 files changed, 262 insertions, 162 deletions
diff --git a/gcc/tree.c b/gcc/tree.c
index 9aaba7e4c26..140676b6bd8 100644
--- a/gcc/tree.c
+++ b/gcc/tree.c
@@ -2945,6 +2945,34 @@ build4_stat (enum tree_code code, tree tt, tree arg0, tree arg1,
}
tree
+build5_stat (enum tree_code code, tree tt, tree arg0, tree arg1,
+ tree arg2, tree arg3, tree arg4 MEM_STAT_DECL)
+{
+ bool constant, read_only, side_effects, invariant;
+ tree t;
+
+ gcc_assert (TREE_CODE_LENGTH (code) == 5);
+
+ t = make_node_stat (code PASS_MEM_STAT);
+ TREE_TYPE (t) = tt;
+
+ side_effects = TREE_SIDE_EFFECTS (t);
+
+ PROCESS_ARG(0);
+ PROCESS_ARG(1);
+ PROCESS_ARG(2);
+ PROCESS_ARG(3);
+ PROCESS_ARG(4);
+
+ TREE_SIDE_EFFECTS (t) = side_effects;
+ TREE_THIS_VOLATILE (t)
+ = (TREE_CODE_CLASS (code) == tcc_reference
+ && arg0 && TREE_THIS_VOLATILE (arg0));
+
+ return t;
+}
+
+tree
build7_stat (enum tree_code code, tree tt, tree arg0, tree arg1,
tree arg2, tree arg3, tree arg4, tree arg5,
tree arg6 MEM_STAT_DECL)
@@ -6032,6 +6060,41 @@ tree_class_check_failed (const tree node, const enum tree_code_class cl,
tree_code_name[TREE_CODE (node)], function, trim_filename (file), line);
}
+/* Similar to tree_check_failed, except that instead of specifying a
+ dozen codes, use the knowledge that they're all sequential. */
+
+void
+tree_range_check_failed (const tree node, const char *file, int line,
+ const char *function, enum tree_code c1,
+ enum tree_code c2)
+{
+ char *buffer;
+ unsigned length = 0;
+ enum tree_code c;
+
+ for (c = c1; c <= c2; ++c)
+ length += 4 + strlen (tree_code_name[c]);
+
+ length += strlen ("expected ");
+ buffer = alloca (length);
+ length = 0;
+
+ for (c = c1; c <= c2; ++c)
+ {
+ const char *prefix = length ? " or " : "expected ";
+
+ strcpy (buffer + length, prefix);
+ length += strlen (prefix);
+ strcpy (buffer + length, tree_code_name[c]);
+ length += strlen (tree_code_name[c]);
+ }
+
+ internal_error ("tree check: %s, have %s in %s, at %s:%d",
+ buffer, tree_code_name[TREE_CODE (node)],
+ function, trim_filename (file), line);
+}
+
+
/* Similar to tree_check_failed, except that we check that a tree does
not have the specified code, given in CL. */
@@ -7145,9 +7208,11 @@ walk_tree (tree *tp, walk_tree_fn func, void *data, struct pointer_set_t *pset)
interesting below this point in the tree. */
if (!walk_subtrees)
{
+ /* But we still need to check our siblings. */
if (code == TREE_LIST)
- /* But we still need to check our siblings. */
WALK_SUBTREE_TAIL (TREE_CHAIN (*tp));
+ else if (code >= OMP_CLAUSE_PRIVATE && code <= OMP_CLAUSE_DEFAULT)
+ WALK_SUBTREE_TAIL (OMP_CLAUSE_CHAIN (*tp));
else
return NULL_TREE;
}
@@ -7157,190 +7222,199 @@ walk_tree (tree *tp, walk_tree_fn func, void *data, struct pointer_set_t *pset)
if (result || ! walk_subtrees)
return result;
- /* If this is a DECL_EXPR, walk into various fields of the type that it's
- defining. We only want to walk into these fields of a type in this
- case. Note that decls get walked as part of the processing of a
- BIND_EXPR.
-
- ??? Precisely which fields of types that we are supposed to walk in
- this case vs. the normal case aren't well defined. */
- if (code == DECL_EXPR
- && TREE_CODE (DECL_EXPR_DECL (*tp)) == TYPE_DECL
- && TREE_CODE (TREE_TYPE (DECL_EXPR_DECL (*tp))) != ERROR_MARK)
+ switch (code)
{
- tree *type_p = &TREE_TYPE (DECL_EXPR_DECL (*tp));
+ case ERROR_MARK:
+ case IDENTIFIER_NODE:
+ case INTEGER_CST:
+ case REAL_CST:
+ case VECTOR_CST:
+ case STRING_CST:
+ case BLOCK:
+ case PLACEHOLDER_EXPR:
+ case SSA_NAME:
+ case FIELD_DECL:
+ case RESULT_DECL:
+ /* None of these have subtrees other than those already walked
+ above. */
+ break;
- /* Call the function for the type. See if it returns anything or
- doesn't want us to continue. If we are to continue, walk both
- the normal fields and those for the declaration case. */
- result = (*func) (type_p, &walk_subtrees, data);
- if (result || !walk_subtrees)
- return NULL_TREE;
+ case TREE_LIST:
+ WALK_SUBTREE (TREE_VALUE (*tp));
+ WALK_SUBTREE_TAIL (TREE_CHAIN (*tp));
+ break;
- result = walk_type_fields (*type_p, func, data, pset);
- if (result)
- return result;
+ case TREE_VEC:
+ {
+ int len = TREE_VEC_LENGTH (*tp);
- WALK_SUBTREE (TYPE_SIZE (*type_p));
- WALK_SUBTREE (TYPE_SIZE_UNIT (*type_p));
+ if (len == 0)
+ break;
- /* If this is a record type, also walk the fields. */
- if (TREE_CODE (*type_p) == RECORD_TYPE
- || TREE_CODE (*type_p) == UNION_TYPE
- || TREE_CODE (*type_p) == QUAL_UNION_TYPE)
- {
- tree field;
+ /* Walk all elements but the first. */
+ while (--len)
+ WALK_SUBTREE (TREE_VEC_ELT (*tp, len));
- for (field = TYPE_FIELDS (*type_p); field;
- field = TREE_CHAIN (field))
- {
- /* We'd like to look at the type of the field, but we can easily
- get infinite recursion. So assume it's pointed to elsewhere
- in the tree. Also, ignore things that aren't fields. */
- if (TREE_CODE (field) != FIELD_DECL)
- continue;
-
- WALK_SUBTREE (DECL_FIELD_OFFSET (field));
- WALK_SUBTREE (DECL_SIZE (field));
- WALK_SUBTREE (DECL_SIZE_UNIT (field));
- if (TREE_CODE (*type_p) == QUAL_UNION_TYPE)
- WALK_SUBTREE (DECL_QUALIFIER (field));
- }
- }
- }
+ /* Now walk the first one as a tail call. */
+ WALK_SUBTREE_TAIL (TREE_VEC_ELT (*tp, 0));
+ }
- else if (code != SAVE_EXPR
- && code != BIND_EXPR
- && IS_EXPR_CODE_CLASS (TREE_CODE_CLASS (code)))
- {
- int i, len;
-
- /* Walk over all the sub-trees of this operand. */
- len = TREE_CODE_LENGTH (code);
- /* TARGET_EXPRs are peculiar: operands 1 and 3 can be the same.
- But, we only want to walk once. */
- if (code == TARGET_EXPR
- && TREE_OPERAND (*tp, 3) == TREE_OPERAND (*tp, 1))
- --len;
-
- /* Go through the subtrees. We need to do this in forward order so
- that the scope of a FOR_EXPR is handled properly. */
-#ifdef DEBUG_WALK_TREE
- for (i = 0; i < len; ++i)
- WALK_SUBTREE (TREE_OPERAND (*tp, i));
-#else
- for (i = 0; i < len - 1; ++i)
- WALK_SUBTREE (TREE_OPERAND (*tp, i));
+ case COMPLEX_CST:
+ WALK_SUBTREE (TREE_REALPART (*tp));
+ WALK_SUBTREE_TAIL (TREE_IMAGPART (*tp));
- if (len)
- {
- /* The common case is that we may tail recurse here. */
- if (code != BIND_EXPR
- && !TREE_CHAIN (*tp))
- WALK_SUBTREE_TAIL (TREE_OPERAND (*tp, len - 1));
- else
- WALK_SUBTREE (TREE_OPERAND (*tp, len - 1));
- }
-#endif
- }
+ case CONSTRUCTOR:
+ {
+ unsigned HOST_WIDE_INT idx;
+ constructor_elt *ce;
- /* If this is a type, walk the needed fields in the type. */
- else if (TYPE_P (*tp))
- {
- result = walk_type_fields (*tp, func, data, pset);
- if (result)
- return result;
- }
- else
- {
- /* Not one of the easy cases. We must explicitly go through the
- children. */
- switch (code)
- {
- case ERROR_MARK:
- case IDENTIFIER_NODE:
- case INTEGER_CST:
- case REAL_CST:
- case VECTOR_CST:
- case STRING_CST:
- case BLOCK:
- case PLACEHOLDER_EXPR:
- case SSA_NAME:
- case FIELD_DECL:
- case RESULT_DECL:
- /* None of these have subtrees other than those already walked
- above. */
- break;
+ for (idx = 0;
+ VEC_iterate(constructor_elt, CONSTRUCTOR_ELTS (*tp), idx, ce);
+ idx++)
+ WALK_SUBTREE (ce->value);
+ }
+ break;
- case TREE_LIST:
- WALK_SUBTREE (TREE_VALUE (*tp));
- WALK_SUBTREE_TAIL (TREE_CHAIN (*tp));
- break;
+ case SAVE_EXPR:
+ WALK_SUBTREE_TAIL (TREE_OPERAND (*tp, 0));
- case TREE_VEC:
+ case BIND_EXPR:
+ {
+ tree decl;
+ for (decl = BIND_EXPR_VARS (*tp); decl; decl = TREE_CHAIN (decl))
{
- int len = TREE_VEC_LENGTH (*tp);
+ /* Walk the DECL_INITIAL and DECL_SIZE. We don't want to walk
+ into declarations that are just mentioned, rather than
+ declared; they don't really belong to this part of the tree.
+ And, we can see cycles: the initializer for a declaration
+ can refer to the declaration itself. */
+ WALK_SUBTREE (DECL_INITIAL (decl));
+ WALK_SUBTREE (DECL_SIZE (decl));
+ WALK_SUBTREE (DECL_SIZE_UNIT (decl));
+ }
+ WALK_SUBTREE_TAIL (BIND_EXPR_BODY (*tp));
+ }
- if (len == 0)
- break;
+ case STATEMENT_LIST:
+ {
+ tree_stmt_iterator i;
+ for (i = tsi_start (*tp); !tsi_end_p (i); tsi_next (&i))
+ WALK_SUBTREE (*tsi_stmt_ptr (i));
+ }
+ break;
- /* Walk all elements but the first. */
- while (--len)
- WALK_SUBTREE (TREE_VEC_ELT (*tp, len));
+ case OMP_CLAUSE_PRIVATE:
+ case OMP_CLAUSE_SHARED:
+ case OMP_CLAUSE_FIRSTPRIVATE:
+ case OMP_CLAUSE_LASTPRIVATE:
+ case OMP_CLAUSE_COPYIN:
+ case OMP_CLAUSE_COPYPRIVATE:
+ case OMP_CLAUSE_IF:
+ case OMP_CLAUSE_NUM_THREADS:
+ case OMP_CLAUSE_SCHEDULE:
+ WALK_SUBTREE (TREE_OPERAND (*tp, 0));
+ /* FALLTHRU */
+
+ case OMP_CLAUSE_NOWAIT:
+ case OMP_CLAUSE_ORDERED:
+ case OMP_CLAUSE_DEFAULT:
+ WALK_SUBTREE_TAIL (OMP_CLAUSE_CHAIN (*tp));
+
+ case OMP_CLAUSE_REDUCTION:
+ {
+ int i;
+ for (i = 0; i < 4; i++)
+ WALK_SUBTREE (TREE_OPERAND (*tp, i));
+ WALK_SUBTREE_TAIL (OMP_CLAUSE_CHAIN (*tp));
+ }
- /* Now walk the first one as a tail call. */
- WALK_SUBTREE_TAIL (TREE_VEC_ELT (*tp, 0));
- }
+ case TARGET_EXPR:
+ {
+ int i, len;
+
+ /* TARGET_EXPRs are peculiar: operands 1 and 3 can be the same.
+ But, we only want to walk once. */
+ len = (TREE_OPERAND (*tp, 3) == TREE_OPERAND (*tp, 1)) ? 2 : 3;
+ for (i = 0; i < len; ++i)
+ WALK_SUBTREE (TREE_OPERAND (*tp, i));
+ WALK_SUBTREE_TAIL (TREE_OPERAND (*tp, len));
+ }
- case COMPLEX_CST:
- WALK_SUBTREE (TREE_REALPART (*tp));
- WALK_SUBTREE_TAIL (TREE_IMAGPART (*tp));
+ case DECL_EXPR:
+ /* Walk into various fields of the type that it's defining. We only
+ want to walk into these fields of a type in this case. Note that
+ decls get walked as part of the processing of a BIND_EXPR.
- case CONSTRUCTOR:
- {
- unsigned HOST_WIDE_INT idx;
- constructor_elt *ce;
+ ??? Precisely which fields of types that we are supposed to walk in
+ this case vs. the normal case aren't well defined. */
+ if (TREE_CODE (DECL_EXPR_DECL (*tp)) == TYPE_DECL
+ && TREE_CODE (TREE_TYPE (DECL_EXPR_DECL (*tp))) != ERROR_MARK)
+ {
+ tree *type_p = &TREE_TYPE (DECL_EXPR_DECL (*tp));
- for (idx = 0;
- VEC_iterate(constructor_elt, CONSTRUCTOR_ELTS (*tp), idx, ce);
- idx++)
- WALK_SUBTREE (ce->value);
- }
- break;
+ /* Call the function for the type. See if it returns anything or
+ doesn't want us to continue. If we are to continue, walk both
+ the normal fields and those for the declaration case. */
+ result = (*func) (type_p, &walk_subtrees, data);
+ if (result || !walk_subtrees)
+ return NULL_TREE;
- case SAVE_EXPR:
- WALK_SUBTREE_TAIL (TREE_OPERAND (*tp, 0));
+ result = walk_type_fields (*type_p, func, data, pset);
+ if (result)
+ return result;
- case BIND_EXPR:
- {
- tree decl;
- for (decl = BIND_EXPR_VARS (*tp); decl; decl = TREE_CHAIN (decl))
- {
- /* Walk the DECL_INITIAL and DECL_SIZE. We don't want to walk
- into declarations that are just mentioned, rather than
- declared; they don't really belong to this part of the tree.
- And, we can see cycles: the initializer for a declaration
- can refer to the declaration itself. */
- WALK_SUBTREE (DECL_INITIAL (decl));
- WALK_SUBTREE (DECL_SIZE (decl));
- WALK_SUBTREE (DECL_SIZE_UNIT (decl));
- }
- WALK_SUBTREE_TAIL (BIND_EXPR_BODY (*tp));
- }
+ /* If this is a record type, also walk the fields. */
+ if (TREE_CODE (*type_p) == RECORD_TYPE
+ || TREE_CODE (*type_p) == UNION_TYPE
+ || TREE_CODE (*type_p) == QUAL_UNION_TYPE)
+ {
+ tree field;
- case STATEMENT_LIST:
- {
- tree_stmt_iterator i;
- for (i = tsi_start (*tp); !tsi_end_p (i); tsi_next (&i))
- WALK_SUBTREE (*tsi_stmt_ptr (i));
- }
- break;
+ for (field = TYPE_FIELDS (*type_p); field;
+ field = TREE_CHAIN (field))
+ {
+ /* We'd like to look at the type of the field, but we can
+ easily get infinite recursion. So assume it's pointed
+ to elsewhere in the tree. Also, ignore things that
+ aren't fields. */
+ if (TREE_CODE (field) != FIELD_DECL)
+ continue;
+
+ WALK_SUBTREE (DECL_FIELD_OFFSET (field));
+ WALK_SUBTREE (DECL_SIZE (field));
+ WALK_SUBTREE (DECL_SIZE_UNIT (field));
+ if (TREE_CODE (*type_p) == QUAL_UNION_TYPE)
+ WALK_SUBTREE (DECL_QUALIFIER (field));
+ }
+ }
- default:
- /* ??? This could be a language-defined node. We really should make
- a hook for it, but right now just ignore it. */
- break;
+ WALK_SUBTREE (TYPE_SIZE (*type_p));
+ WALK_SUBTREE_TAIL (TYPE_SIZE_UNIT (*type_p));
}
+ /* FALLTHRU */
+
+ default:
+ if (IS_EXPR_CODE_CLASS (TREE_CODE_CLASS (code)))
+ {
+ int i, len;
+
+ /* Walk over all the sub-trees of this operand. */
+ len = TREE_CODE_LENGTH (code);
+
+ /* Go through the subtrees. We need to do this in forward order so
+ that the scope of a FOR_EXPR is handled properly. */
+ if (len)
+ {
+ for (i = 0; i < len - 1; ++i)
+ WALK_SUBTREE (TREE_OPERAND (*tp, i));
+ WALK_SUBTREE_TAIL (TREE_OPERAND (*tp, len - 1));
+ }
+ }
+
+ /* If this is a type, walk the needed fields in the type. */
+ else if (TYPE_P (*tp))
+ return walk_type_fields (*tp, func, data, pset);
+ break;
}
/* We didn't find what we were looking for. */
@@ -7364,4 +7438,30 @@ walk_tree_without_duplicates (tree *tp, walk_tree_fn func, void *data)
return result;
}
+
+/* Return true if STMT is an empty statement or contains nothing but
+ empty statements. */
+
+bool
+empty_body_p (tree stmt)
+{
+ tree_stmt_iterator i;
+ tree body;
+
+ if (IS_EMPTY_STMT (stmt))
+ return true;
+ else if (TREE_CODE (stmt) == BIND_EXPR)
+ body = BIND_EXPR_BODY (stmt);
+ else if (TREE_CODE (stmt) == STATEMENT_LIST)
+ body = stmt;
+ else
+ return false;
+
+ for (i = tsi_start (body); !tsi_end_p (i); tsi_next (&i))
+ if (!empty_body_p (tsi_stmt (i)))
+ return false;
+
+ return true;
+}
+
#include "gt-tree.h"