diff options
author | Richard Henderson <rth@redhat.com> | 2004-02-19 14:39:55 -0800 |
---|---|---|
committer | Richard Henderson <rth@gcc.gnu.org> | 2004-02-19 14:39:55 -0800 |
commit | 4221057e8f2e0e6425b61952bc06b1904681bf69 (patch) | |
tree | 94df3d1c9f4ce657fd99d4dcc5822e2ca9695645 /gcc/tree.c | |
parent | e5b792193379be3beab505f1a72fb4fedaf62e6b (diff) | |
download | gcc-4221057e8f2e0e6425b61952bc06b1904681bf69.zip gcc-4221057e8f2e0e6425b61952bc06b1904681bf69.tar.gz gcc-4221057e8f2e0e6425b61952bc06b1904681bf69.tar.bz2 |
Makefile.in (STRICT2_WARN): Add -Wno-variadic-macros.
* Makefile.in (STRICT2_WARN): Add -Wno-variadic-macros.
* tree.c (build0, build1, build2, build3, build4): Split out from...
(build): ... here. Call them.
* tree.h (build, _buildN1, _buildN2, _buildC1, _buildC2): New.
* convert.c (convert_to_integer): Remove extra build argument.
* tree-inline.c (expand_call_inline): Likewise.
ada/
* misc.c (record_code_position): Add third build arg for RTL_EXPR.
java/
* parse.y (switch_label): Use make_node for DEFAULT_EXPR.
From-SVN: r78126
Diffstat (limited to 'gcc/tree.c')
-rw-r--r-- | gcc/tree.c | 311 |
1 files changed, 199 insertions, 112 deletions
@@ -2286,127 +2286,31 @@ stabilize_reference_1 (tree e) /* Low-level constructors for expressions. */ -/* Build an expression of code CODE, data type TYPE, - and operands as specified by the arguments ARG1 and following arguments. - Expressions and reference nodes can be created this way. - Constants, decls, types and misc nodes cannot be. */ +/* Build an expression of code CODE, data type TYPE, and operands as + specified. Expressions and reference nodes can be created this way. + Constants, decls, types and misc nodes cannot be. + + We define 5 non-variadic functions, from 0 to 4 arguments. This is + enough for all extant tree codes. These functions can be called + directly (preferably!), but can also be obtained via GCC preprocessor + magic within the build macro. */ tree -build (enum tree_code code, tree tt, ...) +build0 (enum tree_code code, tree tt) { tree t; - int length; - int i; - int fro; - int constant; - va_list p; - tree node; - va_start (p, tt); +#ifdef ENABLE_CHECKING + if (TREE_CODE_LENGTH (code) != 0) + abort (); +#endif t = make_node (code); - length = TREE_CODE_LENGTH (code); TREE_TYPE (t) = tt; - /* Below, we automatically set TREE_SIDE_EFFECTS and TREE_READONLY for the - result based on those same flags for the arguments. But if the - arguments aren't really even `tree' expressions, we shouldn't be trying - to do this. */ - fro = first_rtl_op (code); - - /* Expressions without side effects may be constant if their - arguments are as well. */ - constant = (TREE_CODE_CLASS (code) == '<' - || TREE_CODE_CLASS (code) == '1' - || TREE_CODE_CLASS (code) == '2' - || TREE_CODE_CLASS (code) == 'c'); - - if (length == 2) - { - /* This is equivalent to the loop below, but faster. */ - tree arg0 = va_arg (p, tree); - tree arg1 = va_arg (p, tree); - - TREE_OPERAND (t, 0) = arg0; - TREE_OPERAND (t, 1) = arg1; - TREE_READONLY (t) = 1; - if (arg0 && fro > 0) - { - if (TREE_SIDE_EFFECTS (arg0)) - TREE_SIDE_EFFECTS (t) = 1; - if (!TREE_READONLY (arg0)) - TREE_READONLY (t) = 0; - if (!TREE_CONSTANT (arg0)) - constant = 0; - } - - if (arg1 && fro > 1) - { - if (TREE_SIDE_EFFECTS (arg1)) - TREE_SIDE_EFFECTS (t) = 1; - if (!TREE_READONLY (arg1)) - TREE_READONLY (t) = 0; - if (!TREE_CONSTANT (arg1)) - constant = 0; - } - } - else if (length == 1) - { - tree arg0 = va_arg (p, tree); - - /* The only one-operand cases we handle here are those with side-effects. - Others are handled with build1. So don't bother checked if the - arg has side-effects since we'll already have set it. - - ??? This really should use build1 too. */ - if (TREE_CODE_CLASS (code) != 's') - abort (); - TREE_OPERAND (t, 0) = arg0; - } - else - { - for (i = 0; i < length; i++) - { - tree operand = va_arg (p, tree); - - TREE_OPERAND (t, i) = operand; - if (operand && fro > i) - { - if (TREE_SIDE_EFFECTS (operand)) - TREE_SIDE_EFFECTS (t) = 1; - if (!TREE_CONSTANT (operand)) - constant = 0; - } - } - } - va_end (p); - - TREE_CONSTANT (t) = constant; - - if (code == CALL_EXPR && !TREE_SIDE_EFFECTS (t)) - { - /* Calls have side-effects, except those to const or - pure functions. */ - i = call_expr_flags (t); - if (!(i & (ECF_CONST | ECF_PURE))) - TREE_SIDE_EFFECTS (t) = 1; - - /* And even those have side-effects if their arguments do. */ - else for (node = TREE_OPERAND (t, 1); node; node = TREE_CHAIN (node)) - if (TREE_SIDE_EFFECTS (TREE_VALUE (node))) - { - TREE_SIDE_EFFECTS (t) = 1; - break; - } - } - return t; } -/* Same as above, but only builds for unary operators. - Saves lions share of calls to `build'; cuts down use - of varargs, which is expensive for RISC machines. */ - tree build1 (enum tree_code code, tree type, tree node) { @@ -2435,9 +2339,7 @@ build1 (enum tree_code code, tree type, tree node) #endif #ifdef ENABLE_CHECKING - if (TREE_CODE_CLASS (code) == '2' - || TREE_CODE_CLASS (code) == '<' - || TREE_CODE_LENGTH (code) != 1) + if (TREE_CODE_LENGTH (code) != 1) abort (); #endif /* ENABLE_CHECKING */ @@ -2512,6 +2414,191 @@ build1 (enum tree_code code, tree type, tree node) return t; } +#define PROCESS_ARG(N) \ + do { \ + TREE_OPERAND (t, N) = arg##N; \ + if (arg##N && fro > N) \ + { \ + if (TREE_SIDE_EFFECTS (arg##N)) \ + side_effects = 1; \ + if (!TREE_READONLY (arg##N)) \ + read_only = 0; \ + if (!TREE_CONSTANT (arg##N)) \ + constant = 0; \ + } \ + } while (0) + +tree +build2 (enum tree_code code, tree tt, tree arg0, tree arg1) +{ + bool constant, read_only, side_effects; + tree t; + int fro; + +#ifdef ENABLE_CHECKING + if (TREE_CODE_LENGTH (code) != 2) + abort (); +#endif + + t = make_node (code); + TREE_TYPE (t) = tt; + + /* Below, we automatically set TREE_SIDE_EFFECTS and TREE_READONLY for the + result based on those same flags for the arguments. But if the + arguments aren't really even `tree' expressions, we shouldn't be trying + to do this. */ + fro = first_rtl_op (code); + + /* Expressions without side effects may be constant if their + arguments are as well. */ + constant = (TREE_CODE_CLASS (code) == '<' + || TREE_CODE_CLASS (code) == '2'); + read_only = 1; + side_effects = TREE_SIDE_EFFECTS (t); + + PROCESS_ARG(0); + PROCESS_ARG(1); + + if (code == CALL_EXPR && !side_effects) + { + tree node; + int i; + + /* Calls have side-effects, except those to const or + pure functions. */ + i = call_expr_flags (t); + if (!(i & (ECF_CONST | ECF_PURE))) + side_effects = 1; + + /* And even those have side-effects if their arguments do. */ + else for (node = TREE_OPERAND (t, 1); node; node = TREE_CHAIN (node)) + if (TREE_SIDE_EFFECTS (TREE_VALUE (node))) + { + side_effects = 1; + break; + } + } + + TREE_READONLY (t) = read_only; + TREE_CONSTANT (t) = constant; + TREE_SIDE_EFFECTS (t) = side_effects; + + return t; +} + +tree +build3 (enum tree_code code, tree tt, tree arg0, tree arg1, tree arg2) +{ + bool constant, read_only, side_effects; + tree t; + int fro; + + /* ??? Quite a lot of existing code passes one too many arguments to + CALL_EXPR. Not going to fix them, because CALL_EXPR is about to + grow a new argument, so it would just mean changing them back. */ + if (code == CALL_EXPR) + { + if (arg2 != NULL_TREE) + abort (); + return build2 (code, tt, arg0, arg1); + } + +#ifdef ENABLE_CHECKING + if (TREE_CODE_LENGTH (code) != 3) + abort (); +#endif + + t = make_node (code); + TREE_TYPE (t) = tt; + + fro = first_rtl_op (code); + + side_effects = TREE_SIDE_EFFECTS (t); + + PROCESS_ARG(0); + PROCESS_ARG(1); + PROCESS_ARG(2); + + TREE_SIDE_EFFECTS (t) = side_effects; + + return t; +} + +tree +build4 (enum tree_code code, tree tt, tree arg0, tree arg1, + tree arg2, tree arg3) +{ + bool constant, read_only, side_effects; + tree t; + int fro; + +#ifdef ENABLE_CHECKING + if (TREE_CODE_LENGTH (code) != 4) + abort (); +#endif + + t = make_node (code); + TREE_TYPE (t) = tt; + + fro = first_rtl_op (code); + + side_effects = TREE_SIDE_EFFECTS (t); + + PROCESS_ARG(0); + PROCESS_ARG(1); + PROCESS_ARG(2); + PROCESS_ARG(3); + + TREE_SIDE_EFFECTS (t) = side_effects; + + return t; +} + +/* Backup definition for non-gcc build compilers. */ + +tree +(build) (enum tree_code code, tree tt, ...) +{ + tree t, arg0, arg1, arg2, arg3; + int length = TREE_CODE_LENGTH (code); + va_list p; + + va_start (p, tt); + switch (length) + { + case 0: + t = build0 (code, tt); + break; + case 1: + arg0 = va_arg (p, tree); + t = build1 (code, tt, arg0); + break; + case 2: + arg0 = va_arg (p, tree); + arg1 = va_arg (p, tree); + t = build2 (code, tt, arg0, arg1); + break; + case 3: + arg0 = va_arg (p, tree); + arg1 = va_arg (p, tree); + arg2 = va_arg (p, tree); + t = build3 (code, tt, arg0, arg1, arg2); + break; + case 4: + arg0 = va_arg (p, tree); + arg1 = va_arg (p, tree); + arg2 = va_arg (p, tree); + arg3 = va_arg (p, tree); + t = build4 (code, tt, arg0, arg1, arg2, arg3); + break; + default: + abort (); + } + va_end (p); + + return t; +} + /* Similar except don't specify the TREE_TYPE and leave the TREE_SIDE_EFFECTS as 0. It is permissible for arguments to be null, |