aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/ChangeLog10
-rw-r--r--gcc/Makefile.in6
-rw-r--r--gcc/ada/ChangeLog4
-rw-r--r--gcc/ada/misc.c2
-rw-r--r--gcc/convert.c3
-rw-r--r--gcc/java/ChangeLog4
-rw-r--r--gcc/java/parse.y2
-rw-r--r--gcc/tree-inline.c2
-rw-r--r--gcc/tree.c311
-rw-r--r--gcc/tree.h19
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
diff --git a/gcc/tree.c b/gcc/tree.c
index c02b100..d2b79bc 100644
--- a/gcc/tree.c
+++ b/gcc/tree.c
@@ -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,
diff --git a/gcc/tree.h b/gcc/tree.h
index ee1f50c..25ba23a 100644
--- a/gcc/tree.h
+++ b/gcc/tree.h
@@ -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);