aboutsummaryrefslogtreecommitdiff
path: root/gcc/tree.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/tree.c')
-rw-r--r--gcc/tree.c241
1 files changed, 233 insertions, 8 deletions
diff --git a/gcc/tree.c b/gcc/tree.c
index 2d2ef08..68aa58f 100644
--- a/gcc/tree.c
+++ b/gcc/tree.c
@@ -98,7 +98,8 @@ static const char * const tree_node_kind_names[] = {
"random kinds",
"lang_decl kinds",
"lang_type kinds",
- "omp clauses"
+ "omp clauses",
+ "gimple statements"
};
#endif /* GATHER_STATISTICS */
@@ -356,6 +357,10 @@ tree_code_size (enum tree_code code)
return (sizeof (struct tree_exp)
+ (TREE_CODE_LENGTH (code) - 1) * sizeof (char *));
+ case tcc_gimple_stmt:
+ return (sizeof (struct gimple_stmt)
+ + (TREE_CODE_LENGTH (code) - 1) * sizeof (char *));
+
case tcc_constant: /* a constant */
switch (code)
{
@@ -476,6 +481,10 @@ make_node_stat (enum tree_code code MEM_STAT_DECL)
kind = c_kind;
break;
+ case tcc_gimple_stmt:
+ kind = gimple_stmt_kind;
+ break;
+
case tcc_exceptional: /* something random, like an identifier. */
switch (code)
{
@@ -591,6 +600,17 @@ make_node_stat (enum tree_code code MEM_STAT_DECL)
}
break;
+ case tcc_gimple_stmt:
+ switch (code)
+ {
+ case GIMPLE_MODIFY_STMT:
+ TREE_SIDE_EFFECTS (t) = 1;
+ break;
+
+ default:
+ break;
+ }
+
default:
/* Other classes need no special treatment. */
break;
@@ -615,10 +635,11 @@ copy_node_stat (tree node MEM_STAT_DECL)
t = ggc_alloc_zone_pass_stat (length, &tree_zone);
memcpy (t, node, length);
- TREE_CHAIN (t) = 0;
+ if (!GIMPLE_TUPLE_P (node))
+ TREE_CHAIN (t) = 0;
TREE_ASM_WRITTEN (t) = 0;
TREE_VISITED (t) = 0;
- t->common.ann = 0;
+ t->base.ann = 0;
if (TREE_CODE_CLASS (code) == tcc_declaration)
{
@@ -1872,7 +1893,14 @@ expr_align (tree t)
align1 = TYPE_ALIGN (TREE_TYPE (t));
return MAX (align0, align1);
- case SAVE_EXPR: case COMPOUND_EXPR: case MODIFY_EXPR:
+ case MODIFY_EXPR:
+ /* FIXME tuples: It is unclear to me if this function, which
+ is only called from ADA, is called on gimple or non gimple
+ trees. Let's assume it's from gimple trees unless we hit
+ this abort. */
+ gcc_unreachable ();
+
+ case SAVE_EXPR: case COMPOUND_EXPR: case GIMPLE_MODIFY_STMT:
case INIT_EXPR: case TARGET_EXPR: case WITH_CLEANUP_EXPR:
case CLEANUP_POINT_EXPR:
/* These don't change the alignment of an object. */
@@ -2141,6 +2169,8 @@ tree_node_structure (tree t)
case tcc_expression:
case tcc_statement:
return TS_EXP;
+ case tcc_gimple_stmt:
+ return TS_GIMPLE_STATEMENT;
default: /* tcc_constant and tcc_exceptional */
break;
}
@@ -2153,6 +2183,8 @@ tree_node_structure (tree t)
case VECTOR_CST: return TS_VECTOR;
case STRING_CST: return TS_STRING;
/* tcc_exceptional cases. */
+ /* FIXME tuples: eventually this should be TS_BASE. For now, nothing
+ returns TS_BASE. */
case ERROR_MARK: return TS_COMMON;
case IDENTIFIER_NODE: return TS_IDENTIFIER;
case TREE_LIST: return TS_LIST;
@@ -2967,6 +2999,17 @@ build2_stat (enum tree_code code, tree tt, tree arg0, tree arg1 MEM_STAT_DECL)
gcc_assert (TREE_CODE_LENGTH (code) == 2);
+ if (code == MODIFY_EXPR && cfun && cfun->gimplified)
+ {
+ /* We should be talking GIMPLE_MODIFY_STMT by now. */
+ gcc_unreachable ();
+ }
+
+ /* FIXME tuples: For now let's be lazy; later we must rewrite all
+ build2 calls to build2_gimple calls. */
+ if (TREE_CODE_CLASS (code) == tcc_gimple_stmt)
+ return build2_gimple (code, arg0, arg1);
+
t = make_node_stat (code PASS_MEM_STAT);
TREE_TYPE (t) = tt;
@@ -2997,6 +3040,35 @@ build2_stat (enum tree_code code, tree tt, tree arg0, tree arg1 MEM_STAT_DECL)
return t;
}
+
+/* Similar as build2_stat, but for GIMPLE tuples. For convenience's sake,
+ arguments and return type are trees. */
+
+tree
+build2_gimple_stat (enum tree_code code, tree arg0, tree arg1 MEM_STAT_DECL)
+{
+ bool side_effects;
+ tree t;
+
+ gcc_assert (TREE_CODE_LENGTH (code) == 2);
+
+ t = make_node_stat (code PASS_MEM_STAT);
+
+ side_effects = TREE_SIDE_EFFECTS (t);
+
+ /* ?? We don't care about setting flags for tuples... */
+ GIMPLE_STMT_OPERAND (t, 0) = arg0;
+ GIMPLE_STMT_OPERAND (t, 1) = arg1;
+
+ /* ...except perhaps side_effects and volatility. ?? */
+ TREE_SIDE_EFFECTS (t) = side_effects;
+ TREE_THIS_VOLATILE (t) = (TREE_CODE_CLASS (code) == tcc_reference
+ && arg0 && TREE_THIS_VOLATILE (arg0));
+
+
+ return t;
+}
+
tree
build3_stat (enum tree_code code, tree tt, tree arg0, tree arg1,
tree arg2 MEM_STAT_DECL)
@@ -3286,6 +3358,130 @@ annotate_with_locus (tree node, location_t locus)
}
#endif
+/* Source location accessor functions. */
+
+
+/* The source location of this expression. Non-tree_exp nodes such as
+ decls and constants can be shared among multiple locations, so
+ return nothing. */
+location_t
+expr_location (tree node)
+{
+#ifdef USE_MAPPED_LOCATION
+ if (GIMPLE_STMT_P (node))
+ return GIMPLE_STMT_LOCUS (node);
+ return EXPR_P (node) ? node->exp.locus : UNKNOWN_LOCATION;
+#else
+ if (GIMPLE_STMT_P (node))
+ return EXPR_HAS_LOCATION (node)
+ ? *GIMPLE_STMT_LOCUS (node) : UNKNOWN_LOCATION;
+ return EXPR_HAS_LOCATION (node) ? *node->exp.locus : UNKNOWN_LOCATION;
+#endif
+}
+
+void
+set_expr_location (tree node, location_t locus)
+{
+#ifdef USE_MAPPED_LOCATION
+ if (GIMPLE_STMT_P (node))
+ GIMPLE_STMT_LOCUS (node) = locus;
+ else
+ EXPR_CHECK (node)->exp.locus = locus;
+#else
+ annotate_with_locus (node, locus);
+#endif
+}
+
+bool
+expr_has_location (tree node)
+{
+#ifdef USE_MAPPED_LOCATION
+ return expr_location (node) != UNKNOWN_LOCATION;
+#else
+ return expr_locus (node) != NULL;
+#endif
+}
+
+#ifdef USE_MAPPED_LOCATION
+source_location *
+#else
+source_locus
+#endif
+expr_locus (tree node)
+{
+#ifdef USE_MAPPED_LOCATION
+ if (GIMPLE_STMT_P (node))
+ return &GIMPLE_STMT_LOCUS (node);
+ return EXPR_P (node) ? &node->exp.locus : (location_t *) NULL;
+#else
+ if (GIMPLE_STMT_P (node))
+ return GIMPLE_STMT_LOCUS (node);
+ /* ?? The cast below was originally "(location_t *)" in the macro,
+ but that makes no sense. ?? */
+ return EXPR_P (node) ? node->exp.locus : (source_locus) NULL;
+#endif
+}
+
+void
+set_expr_locus (tree node,
+#ifdef USE_MAPPED_LOCATION
+ source_location *loc
+#else
+ source_locus loc
+#endif
+ )
+{
+#ifdef USE_MAPPED_LOCATION
+ if (loc == NULL)
+ {
+ if (GIMPLE_STMT_P (node))
+ GIMPLE_STMT_LOCUS (node) = UNKNOWN_LOCATION;
+ else
+ EXPR_CHECK (node)->exp.locus = UNKNOWN_LOCATION;
+ }
+ else
+ {
+ if (GIMPLE_STMT_P (node))
+ GIMPLE_STMT_LOCUS (node) = *loc;
+ else
+ EXPR_CHECK (node)->exp.locus = *loc;
+ }
+#else
+ if (GIMPLE_STMT_P (node))
+ GIMPLE_STMT_LOCUS (node) = loc;
+ else
+ EXPR_CHECK (node)->exp.locus = loc;
+#endif
+}
+
+const char **
+expr_filename (tree node)
+{
+#ifdef USE_MAPPED_LOCATION
+ if (GIMPLE_STMT_P (node))
+ return &LOCATION_FILE (GIMPLE_STMT_LOCUS (node));
+ return &LOCATION_FILE (EXPR_CHECK (node)->exp.locus);
+#else
+ if (GIMPLE_STMT_P (node))
+ return &GIMPLE_STMT_LOCUS (node)->file;
+ return &(EXPR_CHECK (node)->exp.locus->file);
+#endif
+}
+
+int *
+expr_lineno (tree node)
+{
+#ifdef USE_MAPPED_LOCATION
+ if (GIMPLE_STMT_P (node))
+ return &LOCATION_LINE (GIMPLE_STMT_LOCUS (node));
+ return &LOCATION_LINE (EXPR_CHECK (node)->exp.locus);
+#else
+ if (GIMPLE_STMT_P (node))
+ return &GIMPLE_STMT_LOCUS (node)->line;
+ return &EXPR_CHECK (node)->exp.locus->line;
+#endif
+}
+
/* Return a declaration like DDECL except that its DECL_ATTRIBUTES
is ATTRIBUTE. */
@@ -7709,7 +7905,8 @@ walk_tree (tree *tp, walk_tree_fn func, void *data, struct pointer_set_t *pset)
/* FALLTHRU */
default:
- if (IS_EXPR_CODE_CLASS (TREE_CODE_CLASS (code)))
+ if (IS_EXPR_CODE_CLASS (TREE_CODE_CLASS (code))
+ || IS_GIMPLE_STMT_CODE_CLASS (TREE_CODE_CLASS (code)))
{
int i, len;
@@ -7721,11 +7918,10 @@ walk_tree (tree *tp, walk_tree_fn func, void *data, struct pointer_set_t *pset)
if (len)
{
for (i = 0; i < len - 1; ++i)
- WALK_SUBTREE (TREE_OPERAND (*tp, i));
- WALK_SUBTREE_TAIL (TREE_OPERAND (*tp, len - 1));
+ WALK_SUBTREE (GENERIC_TREE_OPERAND (*tp, i));
+ WALK_SUBTREE_TAIL (GENERIC_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);
@@ -7779,4 +7975,33 @@ empty_body_p (tree stmt)
return true;
}
+tree *
+tree_block (tree t)
+{
+ char const c = TREE_CODE_CLASS (TREE_CODE (t));
+
+ if (IS_EXPR_CODE_CLASS (c))
+ return &t->exp.block;
+ else if (IS_GIMPLE_STMT_CODE_CLASS (c))
+ return &GIMPLE_STMT_BLOCK (t);
+ gcc_unreachable ();
+ return NULL;
+}
+
+tree *
+generic_tree_operand (tree node, int i)
+{
+ if (GIMPLE_STMT_P (node))
+ return &GIMPLE_STMT_OPERAND (node, i);
+ return &TREE_OPERAND (node, i);
+}
+
+tree *
+generic_tree_type (tree node)
+{
+ if (GIMPLE_STMT_P (node))
+ return &void_type_node;
+ return &TREE_TYPE (node);
+}
+
#include "gt-tree.h"