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
This commit is contained in:
Richard Henderson 2004-02-19 14:39:55 -08:00 committed by Richard Henderson
parent e5b7921933
commit 4221057e8f
10 changed files with 243 additions and 120 deletions

View file

@ -1,3 +1,13 @@
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.

View file

@ -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.

View file

@ -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

View file

@ -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);
}

View file

@ -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))));
}
}
}

View file

@ -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.

View file

@ -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);
}

View file

@ -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

View file

@ -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,

View file

@ -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);