aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorMark Mitchell <mark@codesourcery.com>1999-11-24 01:19:04 +0000
committerMark Mitchell <mmitchel@gcc.gnu.org>1999-11-24 01:19:04 +0000
commit582db8e43021e33373aafbb03eafe6985fc4a0e8 (patch)
tree4c2d383db592a8c376ae9fdeeabe92711772da13 /gcc
parent87d35858fcc210973b63d09665d9677be6f4ec6a (diff)
downloadgcc-582db8e43021e33373aafbb03eafe6985fc4a0e8.zip
gcc-582db8e43021e33373aafbb03eafe6985fc4a0e8.tar.gz
gcc-582db8e43021e33373aafbb03eafe6985fc4a0e8.tar.bz2
tree.h (unsave_expr_1): New function.
* tree.h (unsave_expr_1): New function. (lang_unsave): New variable. (get_callee_fndecl): New function. * tree.c (unsave_expr_now_r): New function. (lang_unsave): Define. (unsave_expr_1): Likewise. (unsave_expr_now_r): Split out from unsave_expr_now. (unsave_expr_now): Call lang_unsave if it is non-NULL. Otherwise, call unsave_expr_now_r. (get_callee_fndecl): Define. From-SVN: r30646
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog11
-rw-r--r--gcc/tree.c125
-rw-r--r--gcc/tree.h21
3 files changed, 116 insertions, 41 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 5de70f5..03f507f 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,5 +1,16 @@
1999-11-23 Mark Mitchell <mark@codesourcery.com>
+ * tree.h (unsave_expr_1): New function.
+ (lang_unsave): New variable.
+ (get_callee_fndecl): New function.
+ * tree.c (unsave_expr_now_r): New function.
+ (lang_unsave): Define.
+ (unsave_expr_1): Likewise.
+ (unsave_expr_now_r): Split out from unsave_expr_now.
+ (unsave_expr_now): Call lang_unsave if it is non-NULL. Otherwise,
+ call unsave_expr_now_r.
+ (get_callee_fndecl): Define.
+
* Makefile.in (gencheck): Don't depend on lang_tree_files.
(gencheck.o): Do depend on lang_tree_files.
diff --git a/gcc/tree.c b/gcc/tree.c
index a96d5c3..82b00e7 100644
--- a/gcc/tree.c
+++ b/gcc/tree.c
@@ -48,6 +48,8 @@ Boston, MA 02111-1307, USA. */
/* obstack.[ch] explicitly declined to prototype this. */
extern int _obstack_allocated_p PROTO ((struct obstack *h, PTR obj));
+static void unsave_expr_now_r PROTO ((tree));
+
/* Tree nodes of permanent duration are allocated in this obstack.
They are the identifier nodes, and everything outside of
the bodies and parameters of function definitions. */
@@ -275,8 +277,12 @@ static void build_real_from_int_cst_1 PROTO((PTR));
static void mark_type_hash PROTO ((void *));
static void fix_sizetype PROTO ((tree));
-/* If non-null, a language specific helper for unsave_expr_now. */
-
+/* If non-null, these are language-specific helper functions for
+ unsave_expr_now. If present, LANG_UNSAVE is called before its
+ argument (an UNSAVE_EXPR) is to be unsaved, and all other
+ processing in unsave_expr_now is aborted. LANG_UNSAVE_EXPR_NOW is
+ called from unsave_expr_1 for language-specific tree codes. */
+void (*lang_unsave) PROTO((tree *));
void (*lang_unsave_expr_now) PROTO((tree));
/* The string used as a placeholder instead of a source file name for
@@ -2419,27 +2425,14 @@ first_rtl_op (code)
}
}
-/* Modify a tree in place so that all the evaluate only once things
- are cleared out. Return the EXPR given.
-
- LANG_UNSAVE_EXPR_NOW, if set, is a pointer to a function to handle
- language specific nodes.
-*/
+/* Perform any modifications to EXPR required when it is unsaved. Does
+ not recurse into EXPR's subtrees. */
-tree
-unsave_expr_now (expr)
+void
+unsave_expr_1 (expr)
tree expr;
{
- enum tree_code code;
- register int i;
- int first_rtl;
-
- if (expr == NULL_TREE)
- return expr;
-
- code = TREE_CODE (expr);
- first_rtl = first_rtl_op (code);
- switch (code)
+ switch (TREE_CODE (expr))
{
case SAVE_EXPR:
if (!SAVE_EXPR_PERSISTENT_P (expr))
@@ -2453,22 +2446,12 @@ unsave_expr_now (expr)
case RTL_EXPR:
/* I don't yet know how to emit a sequence multiple times. */
- if (RTL_EXPR_SEQUENCE (expr) != 0)
+ if (RTL_EXPR_SEQUENCE (expr))
abort ();
break;
case CALL_EXPR:
CALL_EXPR_RTL (expr) = 0;
- if (TREE_OPERAND (expr, 1)
- && TREE_CODE (TREE_OPERAND (expr, 1)) == TREE_LIST)
- {
- tree exp = TREE_OPERAND (expr, 1);
- while (exp)
- {
- unsave_expr_now (TREE_VALUE (exp));
- exp = TREE_CHAIN (exp);
- }
- }
break;
default:
@@ -2476,7 +2459,31 @@ unsave_expr_now (expr)
(*lang_unsave_expr_now) (expr);
break;
}
+}
+
+/* Helper function for unsave_expr_now. */
+
+static void
+unsave_expr_now_r (expr)
+ tree expr;
+{
+ enum tree_code code;
+
+ unsave_expr_1 (expr);
+ code = TREE_CODE (expr);
+ if (code == CALL_EXPR
+ && TREE_OPERAND (expr, 1)
+ && TREE_CODE (TREE_OPERAND (expr, 1)) == TREE_LIST)
+ {
+ tree exp = TREE_OPERAND (expr, 1);
+ while (exp)
+ {
+ unsave_expr_now_r (TREE_VALUE (exp));
+ exp = TREE_CHAIN (exp);
+ }
+ }
+
switch (TREE_CODE_CLASS (code))
{
case 'c': /* a constant */
@@ -2484,7 +2491,7 @@ unsave_expr_now (expr)
case 'x': /* something random, like an identifier or an ERROR_MARK. */
case 'd': /* A decl node */
case 'b': /* A block node */
- return expr;
+ break;
case 'e': /* an expression */
case 'r': /* a reference */
@@ -2492,14 +2499,33 @@ unsave_expr_now (expr)
case '<': /* a comparison expression */
case '2': /* a binary arithmetic expression */
case '1': /* a unary arithmetic expression */
- for (i = first_rtl - 1; i >= 0; i--)
- unsave_expr_now (TREE_OPERAND (expr, i));
- return expr;
+ {
+ int i;
+
+ for (i = first_rtl_op (code) - 1; i >= 0; i--)
+ unsave_expr_now_r (TREE_OPERAND (expr, i));
+ }
+ break;
default:
abort ();
}
}
+
+/* Modify a tree in place so that all the evaluate only once things
+ are cleared out. Return the EXPR given. */
+
+tree
+unsave_expr_now (expr)
+ tree expr;
+{
+ if (lang_unsave)
+ (*lang_unsave) (&expr);
+ else
+ unsave_expr_now_r (expr);
+
+ return expr;
+}
/* Return 1 if EXP contains a PLACEHOLDER_EXPR; i.e., if it represents a size
or offset that depends on a field within a record. */
@@ -4816,6 +4842,35 @@ decl_type_context (decl)
return NULL_TREE;
}
+/* CALL is a CALL_EXPR. Return the declaration for the function
+ called, or NULL_TREE if the called function cannot be
+ determined. */
+
+tree
+get_callee_fndecl (call)
+ tree call;
+{
+ tree addr;
+
+ /* It's invalid to call this function with anything but a
+ CALL_EXPR. */
+ if (TREE_CODE (call) != CALL_EXPR)
+ abort ();
+
+ /* The first operand to the CALL is the address of the function
+ called. */
+ addr = TREE_OPERAND (call, 0);
+
+ /* If the address is just `&f' for some function `f', then we know
+ that `f' is being called. */
+ if (TREE_CODE (addr) == ADDR_EXPR
+ && TREE_CODE (TREE_OPERAND (addr, 0)) == FUNCTION_DECL)
+ return TREE_OPERAND (addr, 0);
+
+ /* We couldn't figure out what was being called. */
+ return NULL_TREE;
+}
+
/* Print debugging information about the obstack O, named STR. */
void
diff --git a/gcc/tree.h b/gcc/tree.h
index 1aa72d7..d805689 100644
--- a/gcc/tree.h
+++ b/gcc/tree.h
@@ -1845,20 +1845,28 @@ extern tree save_expr PROTO((tree));
extern int first_rtl_op PROTO((enum tree_code));
/* unsave_expr (EXP) returns an expression equivalent to EXP but it
- can be used multiple times and will evaluate EXP, in its entirety
+ can be used multiple times and will evaluate EXP in its entirety
each time. */
extern tree unsave_expr PROTO((tree));
-/* unsave_expr_now (EXP) resets EXP in place, so that it can be
- expanded again. */
+/* Reset EXP in place so that it can be expaned again. Does not
+ recurse into subtrees. */
+
+extern void unsave_expr_1 PROTO((tree));
+
+/* Like unsave_expr_1, but recurses into all subtrees. */
extern tree unsave_expr_now PROTO((tree));
-/* If non-null, a language specific helper for unsave_expr_now. */
+/* If non-null, these are language-specific helper functions for
+ unsave_expr_now. If present, LANG_UNSAVE is called before its
+ argument (an UNSAVE_EXPR) is to be unsaved, and all other
+ processing in unsave_expr_now is aborted. LANG_UNSAVE_EXPR_NOW is
+ called from unsave_expr_1 for language-specific tree codes. */
+extern void (*lang_unsave) PROTO((tree *));
+extern void (*lang_unsave_expr_now) PROTO((tree));
-extern void (*lang_unsave_expr_now) PROTO((tree));
-
/* Return 1 if EXP contains a PLACEHOLDER_EXPR; i.e., if it represents a size
or offset that depends on a field within a record.
@@ -2045,6 +2053,7 @@ extern tree get_set_constructor_bytes PROTO((tree,
extern int get_alias_set PROTO((tree));
extern int new_alias_set PROTO((void));
extern int (*lang_get_alias_set) PROTO((tree));
+extern tree get_callee_fndecl PROTO((tree));
/* In stmt.c */