diff options
-rw-r--r-- | gcc/ChangeLog | 10 | ||||
-rw-r--r-- | gcc/Makefile.in | 6 | ||||
-rw-r--r-- | gcc/ada/ChangeLog | 4 | ||||
-rw-r--r-- | gcc/ada/misc.c | 2 | ||||
-rw-r--r-- | gcc/convert.c | 3 | ||||
-rw-r--r-- | gcc/java/ChangeLog | 4 | ||||
-rw-r--r-- | gcc/java/parse.y | 2 | ||||
-rw-r--r-- | gcc/tree-inline.c | 2 | ||||
-rw-r--r-- | gcc/tree.c | 311 | ||||
-rw-r--r-- | gcc/tree.h | 19 |
10 files changed, 243 insertions, 120 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 6ab7b70..554829a 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,15 @@ 2004-02-19 Richard Henderson <rth@redhat.com> + * 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. + +2004-02-19 Richard Henderson <rth@redhat.com> + * c-opts.c (warn_variadic_macros): New. (c_common_handle_option): Set it. (sanitize_cpp_opts): Copy it to cpp_opts. diff --git a/gcc/Makefile.in b/gcc/Makefile.in index 8236efa..3f65e60 100644 --- a/gcc/Makefile.in +++ b/gcc/Makefile.in @@ -159,10 +159,12 @@ coverageexts = .{gcda,gcno} # STRICT_WARN and STRICT2_WARN are the additional warning flags to # apply to the back end and the C front end, which may be compiled # with other compilers. This is partially controlled by configure in -# stage1, as not all versions of gcc understand -Wno-long-long. +# stage1, as not all versions of gcc understand -Wno-long-long or +# -Wno-variadic-macros. LOOSE_WARN = -W -Wall -Wwrite-strings -Wstrict-prototypes -Wmissing-prototypes STRICT_WARN = @strict1_warn@ -STRICT2_WARN = -pedantic -Wno-long-long -Wold-style-definition @WERROR@ +STRICT2_WARN = -pedantic -Wno-long-long -Wold-style-definition \ + -Wno-variadic-macros @WERROR@ # This is set by --enable-checking. The idea is to catch forgotten # "extern" tags in header files. diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog index 1fa6259..59bed8f 100644 --- a/gcc/ada/ChangeLog +++ b/gcc/ada/ChangeLog @@ -1,3 +1,7 @@ +2004-02-19 Richard Henderson <rth@redhat.com> + + * misc.c (record_code_position): Add third build arg for RTL_EXPR. + 2004-02-18 Emmanuel Briot <briot@act-europe.fr> * ali.ads, ali.adb (First_Sdep_Entry): No longer a constant, so that diff --git a/gcc/ada/misc.c b/gcc/ada/misc.c index 6a40590..a87331d 100644 --- a/gcc/ada/misc.c +++ b/gcc/ada/misc.c @@ -804,7 +804,7 @@ record_code_position (Node_Id gnat_node) addressable needs some fixups and also for above reason. */ save_gnu_tree (gnat_node, build (RTL_EXPR, void_type_node, NULL_TREE, - (tree) emit_note (NOTE_INSN_DELETED)), + (tree) emit_note (NOTE_INSN_DELETED), NULL_TREE), 1); } diff --git a/gcc/convert.c b/gcc/convert.c index 9096541..8fca415 100644 --- a/gcc/convert.c +++ b/gcc/convert.c @@ -523,8 +523,7 @@ convert_to_integer (tree type, tree expr) return convert (type, fold (build (ex_form, typex, convert (typex, arg0), - convert (typex, arg1), - 0))); + convert (typex, arg1)))); } } } diff --git a/gcc/java/ChangeLog b/gcc/java/ChangeLog index 63d844b..a0568c7 100644 --- a/gcc/java/ChangeLog +++ b/gcc/java/ChangeLog @@ -1,3 +1,7 @@ +2004-02-19 Richard Henderson <rth@redhat.com> + + * parse.y (switch_label): Use make_node for DEFAULT_EXPR. + 2004-02-16 Geoffrey Keating <geoffk@apple.com> * Make-lang.in (java.install-man): Add extra dependencies. diff --git a/gcc/java/parse.y b/gcc/java/parse.y index 390b8cd..72cc9f3 100644 --- a/gcc/java/parse.y +++ b/gcc/java/parse.y @@ -1635,7 +1635,7 @@ switch_label: } | DEFAULT_TK REL_CL_TK { - tree lab = build (DEFAULT_EXPR, NULL_TREE, NULL_TREE); + tree lab = make_node (DEFAULT_EXPR); EXPR_WFL_LINECOL (lab) = $1.location; java_method_add_stmt (current_function_decl, lab); } diff --git a/gcc/tree-inline.c b/gcc/tree-inline.c index ce0b415..42da58b 100644 --- a/gcc/tree-inline.c +++ b/gcc/tree-inline.c @@ -1377,7 +1377,7 @@ expand_call_inline (tree *tp, int *walk_subtrees, void *data) statements within the function to jump to. The type of the statement expression is the return type of the function call. */ stmt = NULL; - expr = build (BLOCK, TREE_TYPE (TREE_TYPE (fn)), stmt); + expr = build (BLOCK, TREE_TYPE (TREE_TYPE (fn))); #endif /* INLINER_FOR_JAVA */ /* Local declarations will be replaced by their equivalents in this @@ -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, @@ -2112,13 +2112,30 @@ extern tree maybe_get_identifier (const char *); extern tree build (enum tree_code, tree, ...); extern tree build_nt (enum tree_code, ...); +#if GCC_VERSION >= 3000 || __STDC_VERSION__ >= 199901L +/* Use preprocessor trickery to map "build" to "buildN" where N is the + expected number of arguments. This is used for both efficiency (no + varargs), and checking (verifying number of passed arguments). */ +#define build(code, ...) \ + _buildN1(build, _buildC1(__VA_ARGS__))(code, __VA_ARGS__) +#define _buildN1(BASE, X) _buildN2(BASE, X) +#define _buildN2(BASE, X) BASE##X +#define _buildC1(...) _buildC2(__VA_ARGS__,9,8,7,6,5,4,3,2,1,0,0) +#define _buildC2(x,a1,a2,a3,a4,a5,a6,a7,a8,a9,c,...) c +#endif + +extern tree build0 (enum tree_code, tree); +extern tree build1 (enum tree_code, tree, tree); +extern tree build2 (enum tree_code, tree, tree, tree); +extern tree build3 (enum tree_code, tree, tree, tree, tree); +extern tree build4 (enum tree_code, tree, tree, tree, tree, tree); + extern tree build_int_2_wide (unsigned HOST_WIDE_INT, HOST_WIDE_INT); extern tree build_vector (tree, tree); extern tree build_constructor (tree, tree); extern tree build_real_from_int_cst (tree, tree); extern tree build_complex (tree, tree, tree); extern tree build_string (int, const char *); -extern tree build1 (enum tree_code, tree, tree); extern tree build_tree_list (tree, tree); extern tree build_decl (enum tree_code, tree, tree); extern tree build_block (tree, tree, tree, tree, tree); |