This commit was generated by cvs2svn to compensate for changes in r102780,
which included commits to RCS files with non-trunk default branches.
This commit is contained in:
commit
6be6d6640a
File diff suppressed because it is too large
Load Diff
@ -564,6 +564,14 @@ get_alias_set (t)
|
||||
and references to functions, but that's different.) */
|
||||
else if (TREE_CODE (t) == FUNCTION_TYPE)
|
||||
set = 0;
|
||||
|
||||
/* Unless the language specifies otherwise, let vector types alias
|
||||
their components. This avoids some nasty type punning issues in
|
||||
normal usage. And indeed lets vectors be treated more like an
|
||||
array slice. */
|
||||
else if (TREE_CODE (t) == VECTOR_TYPE)
|
||||
set = get_alias_set (TREE_TYPE (t));
|
||||
|
||||
else
|
||||
/* Otherwise make a new alias set for this type. */
|
||||
set = new_alias_set ();
|
||||
|
@ -1050,7 +1050,6 @@ handle_alias_attribute (node, name, args, flags, no_add_attrs)
|
||||
DECL_INITIAL (decl) = error_mark_node;
|
||||
else
|
||||
DECL_EXTERNAL (decl) = 0;
|
||||
assemble_alias (decl, id);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -211,17 +211,21 @@ make_reorder_chain_1 (bb, prev)
|
||||
/* In the absence of a prediction, disturb things as little as possible
|
||||
by selecting the old "next" block from the list of successors. If
|
||||
there had been a fallthru edge, that will be the one. */
|
||||
/* Note that the fallthru block may not be next any time we eliminate
|
||||
forwarder blocks. */
|
||||
if (! next)
|
||||
{
|
||||
for (e = bb->succ; e ; e = e->succ_next)
|
||||
if (e->dest->index == bb->index + 1)
|
||||
if (e->flags & EDGE_FALLTHRU)
|
||||
{
|
||||
if ((e->flags & EDGE_FALLTHRU)
|
||||
|| (e->dest->succ
|
||||
&& ! (e->flags & (EDGE_ABNORMAL_CALL | EDGE_EH))))
|
||||
next = e->dest;
|
||||
next = e->dest;
|
||||
break;
|
||||
}
|
||||
else if (e->dest->index == bb->index + 1)
|
||||
{
|
||||
if (! (e->flags & (EDGE_ABNORMAL_CALL | EDGE_EH)))
|
||||
next = e->dest;
|
||||
}
|
||||
}
|
||||
|
||||
/* Make sure we didn't select a silly next block. */
|
||||
|
@ -300,8 +300,9 @@ bitmap_find_bit (head, bit)
|
||||
bitmap_element *element;
|
||||
unsigned HOST_WIDE_INT indx = bit / BITMAP_ELEMENT_ALL_BITS;
|
||||
|
||||
if (head->current == 0)
|
||||
return 0;
|
||||
if (head->current == 0
|
||||
|| head->indx == indx)
|
||||
return head->current;
|
||||
|
||||
if (head->indx > indx)
|
||||
for (element = head->current;
|
||||
|
@ -29,7 +29,6 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
|
||||
|
||||
static const char *c_init PARAMS ((const char *));
|
||||
static void c_init_options PARAMS ((void));
|
||||
static void c_post_options PARAMS ((void));
|
||||
|
||||
/* ### When changing hooks, consider if ObjC needs changing too!! ### */
|
||||
|
||||
@ -44,7 +43,7 @@ static void c_post_options PARAMS ((void));
|
||||
#undef LANG_HOOKS_DECODE_OPTION
|
||||
#define LANG_HOOKS_DECODE_OPTION c_decode_option
|
||||
#undef LANG_HOOKS_POST_OPTIONS
|
||||
#define LANG_HOOKS_POST_OPTIONS c_post_options
|
||||
#define LANG_HOOKS_POST_OPTIONS c_common_post_options
|
||||
#undef LANG_HOOKS_GET_ALIAS_SET
|
||||
#define LANG_HOOKS_GET_ALIAS_SET c_common_get_alias_set
|
||||
#undef LANG_HOOKS_SAFE_FROM_P
|
||||
@ -74,13 +73,6 @@ static void c_post_options PARAMS ((void));
|
||||
/* Each front end provides its own. */
|
||||
const struct lang_hooks lang_hooks = LANG_HOOKS_INITIALIZER;
|
||||
|
||||
/* Post-switch processing. */
|
||||
static void
|
||||
c_post_options ()
|
||||
{
|
||||
c_common_post_options ();
|
||||
}
|
||||
|
||||
static void
|
||||
c_init_options ()
|
||||
{
|
||||
|
@ -284,9 +284,14 @@ apply_pragma_weak (decl, value)
|
||||
tree decl, value;
|
||||
{
|
||||
if (value)
|
||||
decl_attributes (&decl, build_tree_list (get_identifier ("alias"),
|
||||
build_tree_list (NULL, value)),
|
||||
0);
|
||||
{
|
||||
value = build_string (IDENTIFIER_LENGTH (value),
|
||||
IDENTIFIER_POINTER (value));
|
||||
decl_attributes (&decl, build_tree_list (get_identifier ("alias"),
|
||||
build_tree_list (NULL, value)),
|
||||
0);
|
||||
}
|
||||
|
||||
if (SUPPORTS_WEAK && DECL_EXTERNAL (decl) && TREE_USED (decl)
|
||||
&& TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl)))
|
||||
warning_with_decl (decl, "applying #pragma weak `%s' after first use results in unspecified behavior");
|
||||
@ -343,7 +348,11 @@ handle_pragma_weak (dummy)
|
||||
|
||||
decl = identifier_global_value (name);
|
||||
if (decl && TREE_CODE_CLASS (TREE_CODE (decl)) == 'd')
|
||||
apply_pragma_weak (decl, value);
|
||||
{
|
||||
apply_pragma_weak (decl, value);
|
||||
if (value)
|
||||
assemble_alias (decl, value);
|
||||
}
|
||||
else
|
||||
pending_weaks = tree_cons (name, value, pending_weaks);
|
||||
}
|
||||
|
@ -1634,6 +1634,7 @@ try_optimize_cfg (mode)
|
||||
&& !(s->flags & EDGE_COMPLEX)
|
||||
&& (c = s->dest) != EXIT_BLOCK_PTR
|
||||
&& c->pred->pred_next == NULL
|
||||
&& b != c
|
||||
/* If the jump insn has side effects,
|
||||
we can't kill the edge. */
|
||||
&& (GET_CODE (b->end) != JUMP_INSN
|
||||
|
@ -953,9 +953,21 @@ force_nonfallthru_and_redirect (e, target)
|
||||
if (e->src->succ->succ_next)
|
||||
{
|
||||
/* Create the new structures. */
|
||||
|
||||
/* Position the new block correctly relative to loop notes. */
|
||||
note = last_loop_beg_note (e->src->end);
|
||||
jump_block
|
||||
= create_basic_block (e->src->index + 1, NEXT_INSN (note), NULL);
|
||||
note = NEXT_INSN (note);
|
||||
|
||||
/* ... and ADDR_VECs. */
|
||||
if (note != NULL
|
||||
&& GET_CODE (note) == CODE_LABEL
|
||||
&& NEXT_INSN (note)
|
||||
&& GET_CODE (NEXT_INSN (note)) == JUMP_INSN
|
||||
&& (GET_CODE (PATTERN (NEXT_INSN (note))) == ADDR_DIFF_VEC
|
||||
|| GET_CODE (PATTERN (NEXT_INSN (note))) == ADDR_VEC))
|
||||
note = NEXT_INSN (NEXT_INSN (note));
|
||||
|
||||
jump_block = create_basic_block (e->src->index + 1, note, NULL);
|
||||
jump_block->count = e->count;
|
||||
jump_block->frequency = EDGE_FREQUENCY (e);
|
||||
jump_block->loop_depth = target->loop_depth;
|
||||
@ -1954,17 +1966,26 @@ purge_dead_edges (bb)
|
||||
|
||||
e->flags &= ~EDGE_ABNORMAL;
|
||||
|
||||
/* Check purposes we can have edge. */
|
||||
if ((e->flags & EDGE_FALLTHRU)
|
||||
&& any_condjump_p (insn))
|
||||
/* See if this edge is one we should keep. */
|
||||
if ((e->flags & EDGE_FALLTHRU) && any_condjump_p (insn))
|
||||
/* A conditional jump can fall through into the next
|
||||
block, so we should keep the edge. */
|
||||
continue;
|
||||
else if (e->dest != EXIT_BLOCK_PTR
|
||||
&& e->dest->head == JUMP_LABEL (insn))
|
||||
/* If the destination block is the target of the jump,
|
||||
keep the edge. */
|
||||
continue;
|
||||
else if (e->dest == EXIT_BLOCK_PTR
|
||||
&& returnjump_p (insn))
|
||||
else if (e->dest == EXIT_BLOCK_PTR && returnjump_p (insn))
|
||||
/* If the destination block is the exit block, and this
|
||||
instruction is a return, then keep the edge. */
|
||||
continue;
|
||||
else if ((e->flags & EDGE_EH) && can_throw_internal (insn))
|
||||
/* Keep the edges that correspond to exceptions thrown by
|
||||
this instruction. */
|
||||
continue;
|
||||
|
||||
/* We do not need this edge. */
|
||||
purged = true;
|
||||
remove_edge (e);
|
||||
}
|
||||
|
@ -577,6 +577,15 @@ is_ctor_dtor (s)
|
||||
const char *orig_s = s;
|
||||
|
||||
static const struct names special[] = {
|
||||
#ifndef NO_DOLLAR_IN_LABEL
|
||||
{ "GLOBAL__I$", sizeof ("GLOBAL__I$")-1, 1, 0 },
|
||||
{ "GLOBAL__D$", sizeof ("GLOBAL__D$")-1, 2, 0 },
|
||||
#else
|
||||
#ifndef NO_DOT_IN_LABEL
|
||||
{ "GLOBAL__I.", sizeof ("GLOBAL__I.")-1, 1, 0 },
|
||||
{ "GLOBAL__D.", sizeof ("GLOBAL__D.")-1, 2, 0 },
|
||||
#endif /* NO_DOT_IN_LABEL */
|
||||
#endif /* NO_DOLLAR_IN_LABEL */
|
||||
{ "GLOBAL__I_", sizeof ("GLOBAL__I_")-1, 1, 0 },
|
||||
{ "GLOBAL__D_", sizeof ("GLOBAL__D_")-1, 2, 0 },
|
||||
{ "GLOBAL__F_", sizeof ("GLOBAL__F_")-1, 5, 0 },
|
||||
|
@ -3539,11 +3539,12 @@ subst (x, from, to, in_dest, unique_copy)
|
||||
|
||||
if (GET_CODE (new) == CONST_INT && GET_CODE (x) == SUBREG)
|
||||
{
|
||||
x = simplify_subreg (GET_MODE (x), new,
|
||||
enum machine_mode mode = GET_MODE (x);
|
||||
x = simplify_subreg (mode, new,
|
||||
GET_MODE (SUBREG_REG (x)),
|
||||
SUBREG_BYTE (x));
|
||||
if (! x)
|
||||
abort ();
|
||||
x = gen_rtx_CLOBBER (mode, const0_rtx);
|
||||
}
|
||||
else if (GET_CODE (new) == CONST_INT
|
||||
&& GET_CODE (x) == ZERO_EXTEND)
|
||||
@ -6697,18 +6698,7 @@ force_to_mode (x, mode, mask, reg, just_select)
|
||||
/* If X is a CONST_INT, return a new one. Do this here since the
|
||||
test below will fail. */
|
||||
if (GET_CODE (x) == CONST_INT)
|
||||
{
|
||||
HOST_WIDE_INT cval = INTVAL (x) & mask;
|
||||
int width = GET_MODE_BITSIZE (mode);
|
||||
|
||||
/* If MODE is narrower that HOST_WIDE_INT and CVAL is a negative
|
||||
number, sign extend it. */
|
||||
if (width > 0 && width < HOST_BITS_PER_WIDE_INT
|
||||
&& (cval & ((HOST_WIDE_INT) 1 << (width - 1))) != 0)
|
||||
cval |= (HOST_WIDE_INT) -1 << width;
|
||||
|
||||
return GEN_INT (cval);
|
||||
}
|
||||
return gen_int_mode (INTVAL (x) & mask, mode);
|
||||
|
||||
/* If X is narrower than MODE and we want all the bits in X's mode, just
|
||||
get X in the proper mode. */
|
||||
@ -6914,14 +6904,6 @@ force_to_mode (x, mode, mask, reg, just_select)
|
||||
force_to_mode (XEXP (x, 1), mode, mask,
|
||||
reg, next_select));
|
||||
|
||||
/* If OP1 is a CONST_INT and X is an IOR or XOR, clear bits outside
|
||||
MASK since OP1 might have been sign-extended but we never want
|
||||
to turn on extra bits, since combine might have previously relied
|
||||
on them being off. */
|
||||
if (GET_CODE (op1) == CONST_INT && (code == IOR || code == XOR)
|
||||
&& (INTVAL (op1) & mask) != 0)
|
||||
op1 = GEN_INT (INTVAL (op1) & mask);
|
||||
|
||||
if (op_mode != GET_MODE (x) || op0 != XEXP (x, 0) || op1 != XEXP (x, 1))
|
||||
x = gen_binary (code, op_mode, op0, op1);
|
||||
break;
|
||||
@ -9865,6 +9847,12 @@ gen_lowpart_for_combine (mode, x)
|
||||
int offset = 0;
|
||||
rtx res;
|
||||
|
||||
/* We can't handle VOIDmodes. We can get here when generating vector
|
||||
modes since these, unlike integral and floating point modes are not
|
||||
handled earlier. */
|
||||
if (GET_MODE (x) == VOIDmode)
|
||||
return gen_rtx_CLOBBER (GET_MODE (x), const0_rtx);
|
||||
|
||||
offset = subreg_lowpart_offset (mode, GET_MODE (x));
|
||||
res = simplify_gen_subreg (mode, x, GET_MODE (x), offset);
|
||||
if (res)
|
||||
|
@ -365,6 +365,16 @@ esac
|
||||
case $machine in
|
||||
*-*-linux*)
|
||||
xm_defines=POSIX
|
||||
case $machine in
|
||||
*-*-linux*ecoff* | *-*-linux*libc1* | *-*-linux*oldld* | *-*-linux*aout*)
|
||||
;;
|
||||
*)
|
||||
case x${enable_threads} in
|
||||
x | xyes | xposix) thread_file='posix'
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
*-*-gnu*)
|
||||
# On the Hurd, the setup is just about the same on
|
||||
@ -558,9 +568,6 @@ alpha*-*-linux*)
|
||||
tmake_file="t-slibgcc-elf-ver t-linux alpha/t-crtfm alpha/t-alpha alpha/t-ieee"
|
||||
extra_parts="crtbegin.o crtend.o crtbeginS.o crtendS.o crtbeginT.o"
|
||||
gas=yes gnu_ld=yes
|
||||
if test x$enable_threads = xyes; then
|
||||
thread_file='posix'
|
||||
fi
|
||||
;;
|
||||
alpha*-*-freebsd*)
|
||||
tm_file="${tm_file} ${fbsd_tm_file} alpha/elf.h alpha/freebsd.h"
|
||||
@ -572,7 +579,6 @@ alpha*-*-netbsd*)
|
||||
tm_file="${tm_file} netbsd.h alpha/elf.h netbsd-elf.h alpha/netbsd.h"
|
||||
target_cpu_default="MASK_GAS"
|
||||
tmake_file="${tmake_file} alpha/t-alpha alpha/t-ieee"
|
||||
extra_parts="crtbegin.o crtend.o crtbeginS.o crtendS.o crtbeginT.o"
|
||||
;;
|
||||
|
||||
alpha*-*-openbsd*)
|
||||
@ -872,9 +878,6 @@ hppa*-*-linux* | parisc*-*-linux*)
|
||||
tmake_file="t-slibgcc-elf-ver t-linux pa/t-linux"
|
||||
extra_parts="crtbegin.o crtbeginS.o crtbeginT.o crtend.o crtendS.o"
|
||||
gas=yes gnu_ld=yes
|
||||
if test x$enable_threads = xyes; then
|
||||
thread_file='posix'
|
||||
fi
|
||||
;;
|
||||
hppa*-*-openbsd*)
|
||||
target_cpu_default="MASK_PA_11"
|
||||
@ -1118,9 +1121,6 @@ i370-*-linux*)
|
||||
gnu_ld=yes
|
||||
gas=yes
|
||||
elf=yes
|
||||
if test x$enable_threads = xyes; then
|
||||
thread_file='posix'
|
||||
fi
|
||||
;;
|
||||
i[34567]86-*-chorusos*)
|
||||
xm_defines=POSIX
|
||||
@ -1317,9 +1317,6 @@ i[34567]86-*-linux*) # Intel 80386's running GNU/Linux
|
||||
extra_parts="crtbegin.o crtbeginS.o crtbeginT.o crtend.o crtendS.o"
|
||||
gnu_ld=yes
|
||||
float_format=i386
|
||||
if test x$enable_threads = xyes; then
|
||||
thread_file='posix'
|
||||
fi
|
||||
;;
|
||||
x86_64-*-linux*)
|
||||
tm_file="${tm_file} i386/att.h dbxelf.h elfos.h svr4.h linux.h \
|
||||
@ -1328,9 +1325,6 @@ x86_64-*-linux*)
|
||||
extra_parts="crtbegin.o crtbeginS.o crtbeginT.o crtend.o crtendS.o"
|
||||
gnu_ld=yes
|
||||
float_format=i386
|
||||
if test x$enable_threads = xyes; then
|
||||
thread_file='posix'
|
||||
fi
|
||||
;;
|
||||
i[34567]86-*-gnu*)
|
||||
float_format=i386
|
||||
@ -1706,9 +1700,6 @@ ia64*-*-linux*)
|
||||
tm_file="${tm_file} dbxelf.h elfos.h svr4.h linux.h ia64/sysv4.h ia64/linux.h"
|
||||
tmake_file="t-slibgcc-elf-ver t-linux ia64/t-ia64 ia64/t-glibc"
|
||||
target_cpu_default="MASK_GNU_AS|MASK_GNU_LD"
|
||||
if test x$enable_threads = xyes; then
|
||||
thread_file='posix'
|
||||
fi
|
||||
float_format=i386
|
||||
;;
|
||||
ia64*-*-hpux*)
|
||||
@ -2099,9 +2090,6 @@ m68k-*-linux*) # Motorola m68k's running GNU/Linux
|
||||
extra_parts="crtbegin.o crtbeginS.o crtend.o crtendS.o"
|
||||
float_format=m68k
|
||||
gnu_ld=yes
|
||||
if test x$enable_threads = xyes; then
|
||||
thread_file='posix'
|
||||
fi
|
||||
;;
|
||||
m68k-*-psos*)
|
||||
tmake_file=m68k/t-m68kbare
|
||||
@ -2379,6 +2367,7 @@ mips*-*-netbsd*) # NetBSD/mips, either endian.
|
||||
tm_file="mips/little.h $tm_file"
|
||||
;;
|
||||
esac
|
||||
tmake_file="${tmake_file} mips/t-netbsd"
|
||||
;;
|
||||
mips*-*-linux*) # Linux MIPS, either endian.
|
||||
tm_file="dbxelf.h elfos.h svr4.h linux.h mips/linux.h"
|
||||
@ -2397,9 +2386,6 @@ mips*-*-linux*) # Linux MIPS, either endian.
|
||||
extra_parts="crtbegin.o crtbeginS.o crtbeginT.o crtend.o crtendS.o"
|
||||
gnu_ld=yes
|
||||
gas=yes
|
||||
if test x$enable_threads = xyes; then
|
||||
thread_file='posix'
|
||||
fi
|
||||
;;
|
||||
mips*el-*-openbsd*) # mips little endian
|
||||
target_cpu_default="MASK_GAS|MASK_ABICALLS"
|
||||
@ -2867,17 +2853,11 @@ powerpc-*-linux-gnualtivec*)
|
||||
tm_file="${tm_file} dbxelf.h elfos.h svr4.h freebsd-spec.h rs6000/sysv4.h rs6000/linux.h rs6000/linuxaltivec.h"
|
||||
out_file=rs6000/rs6000.c
|
||||
tmake_file="rs6000/t-ppcos t-slibgcc-elf-ver t-linux rs6000/t-ppccomm"
|
||||
if test x$enable_threads = xyes; then
|
||||
thread_file='posix'
|
||||
fi
|
||||
;;
|
||||
powerpc-*-linux*)
|
||||
tm_file="${tm_file} dbxelf.h elfos.h svr4.h freebsd-spec.h rs6000/sysv4.h rs6000/linux.h"
|
||||
out_file=rs6000/rs6000.c
|
||||
tmake_file="rs6000/t-ppcos t-slibgcc-elf-ver t-linux rs6000/t-ppccomm"
|
||||
if test x$enable_threads = xyes; then
|
||||
thread_file='posix'
|
||||
fi
|
||||
;;
|
||||
powerpc-*-gnu-gnualtivec*)
|
||||
tm_file="${cpu_type}/${cpu_type}.h elfos.h svr4.h freebsd-spec.h gnu.h rs6000/sysv4.h rs6000/linux.h rs6000/linuxaltivec.h rs6000/gnu.h"
|
||||
@ -2993,9 +2973,6 @@ s390-*-linux*)
|
||||
tm_file="s390/s390.h dbxelf.h elfos.h svr4.h linux.h s390/linux.h"
|
||||
tmake_file="t-slibgcc-elf-ver t-linux s390/t-linux"
|
||||
extra_parts="crtbegin.o crtend.o crtbeginS.o crtendS.o crtbeginT.o"
|
||||
if test x$enable_threads = xyes; then
|
||||
thread_file='posix'
|
||||
fi
|
||||
;;
|
||||
s390x-*-linux*)
|
||||
tm_file="s390/s390x.h s390/s390.h dbxelf.h elfos.h svr4.h linux.h s390/linux.h"
|
||||
@ -3004,9 +2981,6 @@ s390x-*-linux*)
|
||||
out_file=s390/s390.c
|
||||
tmake_file="t-slibgcc-elf-ver t-linux s390/t-linux s390/t-linux64"
|
||||
extra_parts="crtbegin.o crtend.o crtbeginS.o crtendS.o crtbeginT.o"
|
||||
if test x$enable_threads = xyes; then
|
||||
thread_file='posix'
|
||||
fi
|
||||
;;
|
||||
sh-*-elf*)
|
||||
tmake_file="sh/t-sh sh/t-elf"
|
||||
@ -3045,9 +3019,6 @@ sh-*-linux*)
|
||||
tm_file="${tm_file} sh/elf.h sh/linux.h"
|
||||
tmake_file="sh/t-sh sh/t-elf sh/t-linux"
|
||||
gas=yes gnu_ld=yes
|
||||
if test x$enable_threads = xyes; then
|
||||
thread_file='posix'
|
||||
fi
|
||||
float_format=sh
|
||||
;;
|
||||
sh-*-*)
|
||||
@ -3087,6 +3058,13 @@ sparc-*-openbsd*)
|
||||
# we need collect2 until our bug is fixed...
|
||||
use_collect2=yes
|
||||
;;
|
||||
sparc64-*-openbsd*)
|
||||
tm_file="sparc/openbsd1-64.h sparc/sparc.h elfos.h svr4.h sparc/sysv4.h sparc/sol2.h sparc/sp64-elf.h openbsd.h sparc/openbsd64.h"
|
||||
xm_file=sparc/xm-sp64.h
|
||||
gas=yes gnu_ld=yes
|
||||
with_cpu=ultrasparc
|
||||
float_format=i128
|
||||
;;
|
||||
sparc-*-bsd*)
|
||||
tm_file="${tm_file} sparc/bsd.h"
|
||||
;;
|
||||
@ -3124,9 +3102,6 @@ sparc-*-linux*) # Sparc's running GNU/Linux, libc6
|
||||
tmake_file="t-slibgcc-elf-ver t-linux sparc/t-crtfm"
|
||||
extra_parts="crtbegin.o crtbeginS.o crtbeginT.o crtend.o crtendS.o"
|
||||
gnu_ld=yes
|
||||
if test x$enable_threads = xyes; then
|
||||
thread_file='posix'
|
||||
fi
|
||||
float_format=sparc
|
||||
;;
|
||||
sparc-*-lynxos*)
|
||||
@ -3325,9 +3300,6 @@ sparc64-*-linux*) # 64-bit Sparc's running GNU/Linux
|
||||
tm_file="sparc/biarch64.h ${tm_file} dbxelf.h elfos.h svr4.h sparc/sysv4.h sparc/linux64.h"
|
||||
extra_parts="crtbegin.o crtbeginS.o crtbeginT.o crtend.o crtendS.o"
|
||||
gnu_ld=yes
|
||||
if test x$enable_threads = xyes; then
|
||||
thread_file='posix'
|
||||
fi
|
||||
float_format=sparc
|
||||
;;
|
||||
sparc64-*-netbsd*)
|
||||
@ -3457,9 +3429,6 @@ xtensa-*-linux*)
|
||||
tmake_file="t-linux xtensa/t-xtensa"
|
||||
extra_parts="crtbegin.o crtbeginS.o crtbeginT.o crtend.o crtendS.o"
|
||||
gas=yes gnu_ld=yes
|
||||
if test x$enable_threads = xyes; then
|
||||
thread_file='posix'
|
||||
fi
|
||||
;;
|
||||
*)
|
||||
echo "Configuration $machine not supported" 1>&2
|
||||
|
@ -296,6 +296,12 @@
|
||||
every opportunity. This is extremely expensive. */
|
||||
#undef ENABLE_GC_ALWAYS_COLLECT
|
||||
|
||||
/* Define if you want to use __cxa_atexit, rather than atexit, to
|
||||
register C++ destructors for local statics and global objects.
|
||||
This is essential for fully standards-compliant handling of
|
||||
destructors, but requires __cxa_atexit in libc. */
|
||||
#undef DEFAULT_USE_CXA_ATEXIT
|
||||
|
||||
/* Define if you want the C and C++ compilers to support multibyte
|
||||
character sets for source code. */
|
||||
#undef MULTIBYTE_CHARS
|
||||
|
@ -1224,42 +1224,6 @@ extern struct alpha_compare alpha_compare;
|
||||
|
||||
#define FUNCTION_PROFILER(FILE, LABELNO)
|
||||
|
||||
/* Output assembler code to FILE to initialize this source file's
|
||||
basic block profiling info, if that has not already been done.
|
||||
This assumes that __bb_init_func doesn't garble a1-a5. */
|
||||
|
||||
#define FUNCTION_BLOCK_PROFILER(FILE, LABELNO) \
|
||||
do { \
|
||||
ASM_OUTPUT_REG_PUSH (FILE, 16); \
|
||||
fputs ("\tlda $16,$PBX32\n", (FILE)); \
|
||||
fputs ("\tldq $26,0($16)\n", (FILE)); \
|
||||
fputs ("\tbne $26,1f\n", (FILE)); \
|
||||
fputs ("\tlda $27,__bb_init_func\n", (FILE)); \
|
||||
fputs ("\tjsr $26,($27),__bb_init_func\n", (FILE)); \
|
||||
fputs ("\tldgp $29,0($26)\n", (FILE)); \
|
||||
fputs ("1:\n", (FILE)); \
|
||||
ASM_OUTPUT_REG_POP (FILE, 16); \
|
||||
} while (0);
|
||||
|
||||
/* Output assembler code to FILE to increment the entry-count for
|
||||
the BLOCKNO'th basic block in this source file. */
|
||||
|
||||
#define BLOCK_PROFILER(FILE, BLOCKNO) \
|
||||
do { \
|
||||
int blockn = (BLOCKNO); \
|
||||
fputs ("\tsubq $30,16,$30\n", (FILE)); \
|
||||
fputs ("\tstq $26,0($30)\n", (FILE)); \
|
||||
fputs ("\tstq $27,8($30)\n", (FILE)); \
|
||||
fputs ("\tlda $26,$PBX34\n", (FILE)); \
|
||||
fprintf ((FILE), "\tldq $27,%d($26)\n", 8*blockn); \
|
||||
fputs ("\taddq $27,1,$27\n", (FILE)); \
|
||||
fprintf ((FILE), "\tstq $27,%d($26)\n", 8*blockn); \
|
||||
fputs ("\tldq $26,0($30)\n", (FILE)); \
|
||||
fputs ("\tldq $27,8($30)\n", (FILE)); \
|
||||
fputs ("\taddq $30,16,$30\n", (FILE)); \
|
||||
} while (0)
|
||||
|
||||
|
||||
/* EXIT_IGNORE_STACK should be nonzero if, when returning from a function,
|
||||
the stack pointer does not matter. The value is tested only in
|
||||
functions that have frame pointers.
|
||||
|
@ -24,7 +24,7 @@ Boston, MA 02111-1307, USA. */
|
||||
|
||||
#undef CPP_PREDEFINES
|
||||
#define CPP_PREDEFINES \
|
||||
"-D__NetBSD__ -D__ELF__ -Asystem=unix -Asystem=NetBSD"
|
||||
"-D__NetBSD__ -D__ELF__ -D_LP64 -Asystem=unix -Asystem=NetBSD"
|
||||
|
||||
|
||||
/* Show that we need a GP when profiling. */
|
||||
|
@ -574,6 +574,30 @@ ssib_section () \
|
||||
#ifndef REAL_ARITHMETIC
|
||||
#define REAL_VALUE_ATOF(x,s) atof(x)
|
||||
#define REAL_VALUE_HTOF(x,s) atof(x)
|
||||
|
||||
#define REAL_VALUE_TO_TARGET_SINGLE(IN, OUT) \
|
||||
do { \
|
||||
union { \
|
||||
float f; \
|
||||
HOST_WIDE_INT l; \
|
||||
} u; \
|
||||
\
|
||||
u.f = (IN); \
|
||||
(OUT) = (u.l >> 32) & 0xFFFFFFFF; \
|
||||
} while (0)
|
||||
|
||||
#define REAL_VALUE_TO_TARGET_DOUBLE(IN, OUT) \
|
||||
do { \
|
||||
union { \
|
||||
REAL_VALUE_TYPE f; \
|
||||
HOST_WIDE_INT l; \
|
||||
} u; \
|
||||
\
|
||||
u.f = (IN); \
|
||||
(OUT)[0] = (u.l >> 32) & 0xFFFFFFFF; \
|
||||
(OUT)[1] = (u.l & 0xFFFFFFFF); \
|
||||
} while (0)
|
||||
|
||||
#endif
|
||||
|
||||
#undef NM_FLAGS
|
||||
|
@ -4544,8 +4544,8 @@ arm_gen_movstrqi (operands)
|
||||
RTX_UNCHANGING_P (mem) = dst_unchanging_p;
|
||||
MEM_IN_STRUCT_P (mem) = dst_in_struct_p;
|
||||
MEM_SCALAR_P (mem) = dst_scalar_p;
|
||||
emit_move_insn (mem, gen_rtx_SUBREG (QImode, part_bytes_reg, 0));
|
||||
|
||||
emit_move_insn (mem, gen_lowpart (QImode, part_bytes_reg));
|
||||
|
||||
if (--last_bytes)
|
||||
{
|
||||
tmp = gen_reg_rtx (SImode);
|
||||
@ -4563,7 +4563,7 @@ arm_gen_movstrqi (operands)
|
||||
RTX_UNCHANGING_P (mem) = dst_unchanging_p;
|
||||
MEM_IN_STRUCT_P (mem) = dst_in_struct_p;
|
||||
MEM_SCALAR_P (mem) = dst_scalar_p;
|
||||
emit_move_insn (mem, gen_rtx_SUBREG (HImode, part_bytes_reg, 0));
|
||||
emit_move_insn (mem, gen_lowpart (HImode, part_bytes_reg));
|
||||
last_bytes -= 2;
|
||||
if (last_bytes)
|
||||
{
|
||||
@ -4581,7 +4581,7 @@ arm_gen_movstrqi (operands)
|
||||
RTX_UNCHANGING_P (mem) = dst_unchanging_p;
|
||||
MEM_IN_STRUCT_P (mem) = dst_in_struct_p;
|
||||
MEM_SCALAR_P (mem) = dst_scalar_p;
|
||||
emit_move_insn (mem, gen_rtx_SUBREG (QImode, part_bytes_reg, 0));
|
||||
emit_move_insn (mem, gen_lowpart (QImode, part_bytes_reg));
|
||||
}
|
||||
}
|
||||
|
||||
@ -5119,23 +5119,23 @@ arm_reload_out_hi (operands)
|
||||
{
|
||||
emit_insn (gen_movqi (gen_rtx_MEM (QImode,
|
||||
plus_constant (base, offset + 1)),
|
||||
gen_rtx_SUBREG (QImode, outval, 0)));
|
||||
gen_lowpart (QImode, outval)));
|
||||
emit_insn (gen_lshrsi3 (scratch,
|
||||
gen_rtx_SUBREG (SImode, outval, 0),
|
||||
GEN_INT (8)));
|
||||
emit_insn (gen_movqi (gen_rtx_MEM (QImode, plus_constant (base, offset)),
|
||||
gen_rtx_SUBREG (QImode, scratch, 0)));
|
||||
gen_lowpart (QImode, scratch)));
|
||||
}
|
||||
else
|
||||
{
|
||||
emit_insn (gen_movqi (gen_rtx_MEM (QImode, plus_constant (base, offset)),
|
||||
gen_rtx_SUBREG (QImode, outval, 0)));
|
||||
gen_lowpart (QImode, outval)));
|
||||
emit_insn (gen_lshrsi3 (scratch,
|
||||
gen_rtx_SUBREG (SImode, outval, 0),
|
||||
GEN_INT (8)));
|
||||
emit_insn (gen_movqi (gen_rtx_MEM (QImode,
|
||||
plus_constant (base, offset + 1)),
|
||||
gen_rtx_SUBREG (QImode, scratch, 0)));
|
||||
gen_lowpart (QImode, scratch)));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3390,7 +3390,7 @@
|
||||
[(set (match_operand:SI 0 "s_register_operand" "")
|
||||
(zero_extend:SI (subreg:QI (match_operand:SI 1 "" "") 0)))
|
||||
(clobber (match_operand:SI 2 "s_register_operand" ""))]
|
||||
"TARGET_ARM && (GET_CODE (operands[1]) != MEM)"
|
||||
"TARGET_ARM && (GET_CODE (operands[1]) != MEM) && ! BYTES_BIG_ENDIAN"
|
||||
[(set (match_dup 2) (match_dup 1))
|
||||
(set (match_dup 0) (and:SI (match_dup 2) (const_int 255)))]
|
||||
""
|
||||
@ -4288,7 +4288,7 @@
|
||||
[(set (match_dup 4) (match_dup 3))
|
||||
(set (match_dup 2)
|
||||
(ashiftrt:SI (match_operand 0 "" "") (const_int 8)))
|
||||
(set (match_operand 1 "" "") (subreg:QI (match_dup 2) 0))]
|
||||
(set (match_operand 1 "" "") (subreg:QI (match_dup 2) 3))]
|
||||
"TARGET_ARM"
|
||||
"
|
||||
{
|
||||
@ -4312,7 +4312,7 @@
|
||||
(define_expand "storeinthi"
|
||||
[(set (match_operand 0 "" "")
|
||||
(subreg:QI (match_operand 1 "" "") 0))
|
||||
(set (match_dup 3) (subreg:QI (match_dup 2) 0))]
|
||||
(set (match_dup 3) (match_dup 2))]
|
||||
"TARGET_ARM"
|
||||
"
|
||||
{
|
||||
@ -4351,6 +4351,7 @@
|
||||
|
||||
operands[3] = adjust_address (op0, QImode, 1);
|
||||
operands[0] = adjust_address (operands[0], QImode, 0);
|
||||
operands[2] = gen_lowpart (QImode, operands[2]);
|
||||
}"
|
||||
)
|
||||
|
||||
@ -4413,7 +4414,7 @@
|
||||
}
|
||||
|
||||
emit_insn (gen_movsi (reg, GEN_INT (val)));
|
||||
operands[1] = gen_rtx_SUBREG (HImode, reg, 0);
|
||||
operands[1] = gen_lowpart (HImode, reg);
|
||||
}
|
||||
else if (!arm_arch4)
|
||||
{
|
||||
@ -4810,7 +4811,7 @@
|
||||
rtx reg = gen_reg_rtx (SImode);
|
||||
|
||||
emit_insn (gen_movsi (reg, operands[1]));
|
||||
operands[1] = gen_rtx_SUBREG (QImode, reg, 0);
|
||||
operands[1] = gen_lowpart (QImode, reg);
|
||||
}
|
||||
if (GET_CODE (operands[0]) == MEM)
|
||||
operands[1] = force_reg (QImode, operands[1]);
|
||||
@ -4853,7 +4854,7 @@
|
||||
if (GET_CODE (operands[0]) != REG)
|
||||
abort ();
|
||||
|
||||
operands[0] = gen_rtx (SUBREG, SImode, operands[0], 0);
|
||||
operands[0] = gen_rtx_SUBREG (SImode, operands[0], 0);
|
||||
emit_insn (gen_movsi (operands[0], operands[1]));
|
||||
DONE;
|
||||
}
|
||||
|
@ -33,9 +33,6 @@ extern HOST_WIDE_INT ix86_initial_elimination_offset PARAMS((int, int));
|
||||
extern void ix86_expand_prologue PARAMS ((void));
|
||||
extern void ix86_expand_epilogue PARAMS ((int));
|
||||
|
||||
extern void ix86_output_function_block_profiler PARAMS ((FILE *, int));
|
||||
extern void ix86_output_block_profiler PARAMS ((FILE *, int));
|
||||
|
||||
extern void ix86_output_addr_vec_elt PARAMS ((FILE *, int));
|
||||
extern void ix86_output_addr_diff_elt PARAMS ((FILE *, int, int));
|
||||
|
||||
@ -197,4 +194,6 @@ extern tree ix86_handle_shared_attribute PARAMS ((tree *, tree, tree, int, bool
|
||||
extern unsigned int i386_pe_section_type_flags PARAMS ((tree, const char *,
|
||||
int));
|
||||
extern void i386_pe_asm_named_section PARAMS ((const char *, unsigned int));
|
||||
extern void x86_output_mi_thunk PARAMS ((FILE *, int, tree));
|
||||
extern int x86_field_alignment PARAMS ((tree, int));
|
||||
#endif
|
||||
|
@ -69,13 +69,16 @@ Boston, MA 02111-1307, USA. */
|
||||
#define MULTILIB_DEFAULTS { "m64" }
|
||||
|
||||
/* Do code reading to identify a signal frame, and set the frame
|
||||
state data appropriately. See unwind-dw2.c for the structs. */
|
||||
state data appropriately. See unwind-dw2.c for the structs.
|
||||
Don't use this at all if inhibit_libc is used. */
|
||||
|
||||
#ifndef inhibit_libc
|
||||
#ifdef IN_LIBGCC2
|
||||
#include <signal.h>
|
||||
#include <sys/ucontext.h>
|
||||
#endif
|
||||
|
||||
#ifdef __x86_64__
|
||||
#define MD_FALLBACK_FRAME_STATE_FOR(CONTEXT, FS, SUCCESS) \
|
||||
do { \
|
||||
unsigned char *pc_ = (CONTEXT)->ra; \
|
||||
@ -132,3 +135,59 @@ Boston, MA 02111-1307, USA. */
|
||||
(FS)->retaddr_column = 16; \
|
||||
goto SUCCESS; \
|
||||
} while (0)
|
||||
#else /* ifdef __x86_64__ */
|
||||
#define MD_FALLBACK_FRAME_STATE_FOR(CONTEXT, FS, SUCCESS) \
|
||||
do { \
|
||||
unsigned char *pc_ = (CONTEXT)->ra; \
|
||||
struct sigcontext *sc_; \
|
||||
long new_cfa_; \
|
||||
\
|
||||
/* popl %eax ; movl $__NR_sigreturn,%eax ; int $0x80 */ \
|
||||
if (*(unsigned short *)(pc_+0) == 0xb858 \
|
||||
&& *(unsigned int *)(pc_+2) == 119 \
|
||||
&& *(unsigned short *)(pc_+6) == 0x80cd) \
|
||||
sc_ = (CONTEXT)->cfa + 4; \
|
||||
/* movl $__NR_rt_sigreturn,%eax ; int $0x80 */ \
|
||||
else if (*(unsigned char *)(pc_+0) == 0xb8 \
|
||||
&& *(unsigned int *)(pc_+1) == 173 \
|
||||
&& *(unsigned short *)(pc_+5) == 0x80cd) \
|
||||
{ \
|
||||
struct rt_sigframe { \
|
||||
int sig; \
|
||||
struct siginfo *pinfo; \
|
||||
void *puc; \
|
||||
struct siginfo info; \
|
||||
struct ucontext uc; \
|
||||
} *rt_ = (CONTEXT)->cfa; \
|
||||
sc_ = (struct sigcontext *) &rt_->uc.uc_mcontext; \
|
||||
} \
|
||||
else \
|
||||
break; \
|
||||
\
|
||||
new_cfa_ = sc_->esp; \
|
||||
(FS)->cfa_how = CFA_REG_OFFSET; \
|
||||
(FS)->cfa_reg = 4; \
|
||||
(FS)->cfa_offset = new_cfa_ - (long) (CONTEXT)->cfa; \
|
||||
\
|
||||
/* The SVR4 register numbering macros aren't usable in libgcc. */ \
|
||||
(FS)->regs.reg[0].how = REG_SAVED_OFFSET; \
|
||||
(FS)->regs.reg[0].loc.offset = (long)&sc_->eax - new_cfa_; \
|
||||
(FS)->regs.reg[3].how = REG_SAVED_OFFSET; \
|
||||
(FS)->regs.reg[3].loc.offset = (long)&sc_->ebx - new_cfa_; \
|
||||
(FS)->regs.reg[1].how = REG_SAVED_OFFSET; \
|
||||
(FS)->regs.reg[1].loc.offset = (long)&sc_->ecx - new_cfa_; \
|
||||
(FS)->regs.reg[2].how = REG_SAVED_OFFSET; \
|
||||
(FS)->regs.reg[2].loc.offset = (long)&sc_->edx - new_cfa_; \
|
||||
(FS)->regs.reg[6].how = REG_SAVED_OFFSET; \
|
||||
(FS)->regs.reg[6].loc.offset = (long)&sc_->esi - new_cfa_; \
|
||||
(FS)->regs.reg[7].how = REG_SAVED_OFFSET; \
|
||||
(FS)->regs.reg[7].loc.offset = (long)&sc_->edi - new_cfa_; \
|
||||
(FS)->regs.reg[5].how = REG_SAVED_OFFSET; \
|
||||
(FS)->regs.reg[5].loc.offset = (long)&sc_->ebp - new_cfa_; \
|
||||
(FS)->regs.reg[8].how = REG_SAVED_OFFSET; \
|
||||
(FS)->regs.reg[8].loc.offset = (long)&sc_->eip - new_cfa_; \
|
||||
(FS)->retaddr_column = 8; \
|
||||
goto SUCCESS; \
|
||||
} while (0)
|
||||
#endif /* ifdef __x86_64__ */
|
||||
#endif /* ifdef inhibit_libc */
|
||||
|
@ -31,7 +31,7 @@
|
||||
#define _MMINTRIN_H_INCLUDED
|
||||
|
||||
/* The data type intended for user use. */
|
||||
typedef unsigned long long __m64;
|
||||
typedef unsigned long long __m64 __attribute__ ((__aligned__ (8)));
|
||||
|
||||
/* Internal data types for implementing the intrinsics. */
|
||||
typedef int __v2si __attribute__ ((__mode__ (__V2SI__)));
|
||||
|
@ -48,6 +48,24 @@ Boston, MA 02111-1307, USA. */
|
||||
"-D__NetBSD__ -D__ELF__ -Asystem=unix -Asystem=NetBSD"
|
||||
|
||||
|
||||
/* Provide some extra CPP specs needed by NetBSD/x86_64. */
|
||||
#define CPP_LP64_SPEC "%{!m32:-D_LP64}"
|
||||
|
||||
#define CPP_SUBTARGET_SPEC "%(cpp_lp64)"
|
||||
|
||||
#undef SUBTARGET_EXTRA_SPECS
|
||||
#define SUBTARGET_EXTRA_SPECS \
|
||||
{ "cpp_lp64", CPP_LP64_SPEC }, \
|
||||
{ "cpp_subtarget", CPP_SUBTARGET_SPEC },
|
||||
|
||||
|
||||
/* Provide a CPP_SPEC appropriate for NetBSD. Currently we deal with
|
||||
our subtarget specs and the GCC option `-posix'. */
|
||||
|
||||
#undef CPP_SPEC
|
||||
#define CPP_SPEC "%(cpp_cpu) %(cpp_subtarget) %{posix:-D_POSIX_SOURCE}"
|
||||
|
||||
|
||||
/* Output assembler code to FILE to call the profiler. */
|
||||
|
||||
#undef FUNCTION_PROFILER
|
||||
|
@ -95,26 +95,11 @@ Boston, MA 02111-1307, USA. */
|
||||
|
||||
#undef ASM_PREFERRED_EH_DATA_FORMAT
|
||||
|
||||
/* Assembler format: alignment output. */
|
||||
|
||||
/* A C statement to output to the stdio stream FILE an assembler
|
||||
command to advance the location counter to a multiple of 1<<LOG
|
||||
bytes if it is within MAX_SKIP bytes.
|
||||
|
||||
This will be used to align code labels according to Intel
|
||||
recommendations, in prevision of binutils upgrade. */
|
||||
#ifdef HAVE_GAS_MAX_SKIP_P2ALIGN
|
||||
#define ASM_OUTPUT_MAX_SKIP_ALIGN(FILE,LOG,MAX_SKIP) \
|
||||
do { \
|
||||
if ((LOG) != 0) { \
|
||||
if ((MAX_SKIP) == 0) fprintf ((FILE), "\t.p2align %d\n", (LOG)); \
|
||||
else fprintf ((FILE), "\t.p2align %d,,%d\n", (LOG), (MAX_SKIP)); \
|
||||
} \
|
||||
} while (0)
|
||||
#endif
|
||||
|
||||
/* Note that we pick up ASM_OUTPUT_MI_THUNK from unix.h. */
|
||||
|
||||
#undef ASM_COMMENT_START
|
||||
#define ASM_COMMENT_START ";#"
|
||||
|
||||
/* OpenBSD gas currently does not support quad, so do not use it. */
|
||||
#undef ASM_QUAD
|
||||
|
@ -79,57 +79,5 @@ Boston, MA 02111-1307, USA. */
|
||||
|
||||
/* Output code to add DELTA to the first argument, and then jump to FUNCTION.
|
||||
Used for C++ multiple inheritance. */
|
||||
#define ASM_OUTPUT_MI_THUNK(FILE, THUNK_FNDECL, DELTA, FUNCTION) \
|
||||
do { \
|
||||
tree parm; \
|
||||
rtx xops[3]; \
|
||||
\
|
||||
if (ix86_regparm > 0) \
|
||||
parm = TYPE_ARG_TYPES (TREE_TYPE (function)); \
|
||||
else \
|
||||
parm = NULL_TREE; \
|
||||
for (; parm; parm = TREE_CHAIN (parm)) \
|
||||
if (TREE_VALUE (parm) == void_type_node) \
|
||||
break; \
|
||||
\
|
||||
xops[0] = GEN_INT (DELTA); \
|
||||
if (parm) \
|
||||
xops[1] = gen_rtx_REG (SImode, 0); \
|
||||
else if (aggregate_value_p (TREE_TYPE (TREE_TYPE (FUNCTION)))) \
|
||||
xops[1] = gen_rtx_MEM (SImode, plus_constant (stack_pointer_rtx, 8)); \
|
||||
else \
|
||||
xops[1] = gen_rtx_MEM (SImode, plus_constant (stack_pointer_rtx, 4)); \
|
||||
output_asm_insn ("add{l} {%0, %1|%1, %0}", xops); \
|
||||
\
|
||||
if (flag_pic && !TARGET_64BIT) \
|
||||
{ \
|
||||
xops[0] = pic_offset_table_rtx; \
|
||||
xops[1] = gen_label_rtx (); \
|
||||
xops[2] = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_"); \
|
||||
\
|
||||
if (ix86_regparm > 2) \
|
||||
abort (); \
|
||||
output_asm_insn ("push{l}\t%0", xops); \
|
||||
output_asm_insn ("call\t%P1", xops); \
|
||||
ASM_OUTPUT_INTERNAL_LABEL (FILE, "L", CODE_LABEL_NUMBER (xops[1])); \
|
||||
output_asm_insn ("pop{l}\t%0", xops); \
|
||||
output_asm_insn ("add{l}\t{%2+[.-%P1], %0|%0, OFFSET FLAT: %2+[.-%P1]}", xops); \
|
||||
xops[0] = gen_rtx_MEM (SImode, XEXP (DECL_RTL (FUNCTION), 0)); \
|
||||
output_asm_insn ("mov{l}\t{%0@GOT(%%ebx), %%ecx|%%ecx, %0@GOT[%%ebx]}",\
|
||||
xops); \
|
||||
asm_fprintf (FILE, "\tpop{l\t%%ebx|\t%%ebx}\n"); \
|
||||
asm_fprintf (FILE, "\tjmp\t{*%%ecx|%%ecx}\n"); \
|
||||
} \
|
||||
else if (flag_pic && TARGET_64BIT) \
|
||||
{ \
|
||||
fprintf (FILE, "\tjmp *"); \
|
||||
assemble_name (FILE, XSTR (XEXP (DECL_RTL (FUNCTION), 0), 0)); \
|
||||
fprintf (FILE, "@GOTPCREL(%%rip)\n"); \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
fprintf (FILE, "\tjmp "); \
|
||||
assemble_name (FILE, XSTR (XEXP (DECL_RTL (FUNCTION), 0), 0)); \
|
||||
fprintf (FILE, "\n"); \
|
||||
} \
|
||||
} while (0)
|
||||
#define ASM_OUTPUT_MI_THUNK(FILE, THUNK_FNDECL, DELTA, FUNCTION) \
|
||||
x86_output_mi_thunk (FILE, DELTA, FUNCTION);
|
||||
|
@ -58,7 +58,7 @@
|
||||
#include <sys/ucontext.h>
|
||||
|
||||
#define IA64_GATE_AREA_START 0xa000000000000100LL
|
||||
#define IA64_GATE_AREA_END 0xa000000000010000LL
|
||||
#define IA64_GATE_AREA_END 0xa000000000020000LL
|
||||
|
||||
#define MD_FALLBACK_FRAME_STATE_FOR(CONTEXT, FS, SUCCESS) \
|
||||
if ((CONTEXT)->rp >= IA64_GATE_AREA_START \
|
||||
|
@ -140,45 +140,136 @@ do { \
|
||||
emit_safe_across_calls (STREAM); \
|
||||
} while (0)
|
||||
|
||||
/* A C statement or statements to switch to the appropriate
|
||||
section for output of DECL. DECL is either a `VAR_DECL' node
|
||||
or a constant of some sort. RELOC indicates whether forming
|
||||
the initial value of DECL requires link-time relocations.
|
||||
|
||||
Set SECNUM to:
|
||||
0 .text
|
||||
1 .rodata
|
||||
2 .data
|
||||
3 .sdata
|
||||
4 .bss
|
||||
5 .sbss
|
||||
*/
|
||||
#define DO_SELECT_SECTION(SECNUM, DECL, RELOC) \
|
||||
do \
|
||||
{ \
|
||||
if (TREE_CODE (DECL) == FUNCTION_DECL) \
|
||||
SECNUM = 0; \
|
||||
else if (TREE_CODE (DECL) == STRING_CST) \
|
||||
{ \
|
||||
if (! flag_writable_strings) \
|
||||
SECNUM = 0x101; \
|
||||
else \
|
||||
SECNUM = 2; \
|
||||
} \
|
||||
else if (TREE_CODE (DECL) == VAR_DECL) \
|
||||
{ \
|
||||
if (XSTR (XEXP (DECL_RTL (DECL), 0), 0)[0] \
|
||||
== SDATA_NAME_FLAG_CHAR) \
|
||||
SECNUM = 3; \
|
||||
/* ??? We need the extra RELOC check, because the default \
|
||||
is to only check RELOC if flag_pic is set, and we don't \
|
||||
set flag_pic (yet?). */ \
|
||||
else if (!DECL_READONLY_SECTION (DECL, RELOC) || (RELOC)) \
|
||||
SECNUM = 2; \
|
||||
else if (flag_merge_constants < 2) \
|
||||
/* C and C++ don't allow different variables to share \
|
||||
the same location. -fmerge-all-constants allows \
|
||||
even that (at the expense of not conforming). */ \
|
||||
SECNUM = 1; \
|
||||
else if (TREE_CODE (DECL_INITIAL (DECL)) == STRING_CST) \
|
||||
SECNUM = 0x201; \
|
||||
else \
|
||||
SECNUM = 0x301; \
|
||||
} \
|
||||
/* This could be a CONSTRUCTOR containing ADDR_EXPR of a VAR_DECL, \
|
||||
in which case we can't put it in a shared library rodata. */ \
|
||||
else if (flag_pic && (RELOC)) \
|
||||
SECNUM = 3; \
|
||||
else \
|
||||
SECNUM = 2; \
|
||||
} \
|
||||
while (0)
|
||||
|
||||
/* We override svr4.h so that we can support the sdata section. */
|
||||
|
||||
#undef SELECT_SECTION
|
||||
#define SELECT_SECTION(DECL,RELOC,ALIGN) \
|
||||
{ \
|
||||
if (TREE_CODE (DECL) == STRING_CST) \
|
||||
do \
|
||||
{ \
|
||||
if (! flag_writable_strings) \
|
||||
mergeable_string_section ((DECL), (ALIGN), 0); \
|
||||
else \
|
||||
data_section (); \
|
||||
typedef void (*sec_fn) PARAMS ((void)); \
|
||||
static sec_fn const sec_functions[6] = \
|
||||
{ \
|
||||
text_section, \
|
||||
const_section, \
|
||||
data_section, \
|
||||
sdata_section, \
|
||||
bss_section, \
|
||||
sbss_section \
|
||||
}; \
|
||||
\
|
||||
int sec; \
|
||||
\
|
||||
DO_SELECT_SECTION (sec, DECL, RELOC); \
|
||||
\
|
||||
switch (sec) \
|
||||
{ \
|
||||
case 0x101: \
|
||||
mergeable_string_section (DECL, ALIGN, 0); \
|
||||
break; \
|
||||
case 0x201: \
|
||||
mergeable_string_section (DECL_INITIAL (DECL), \
|
||||
ALIGN, 0); \
|
||||
break; \
|
||||
case 0x301: \
|
||||
mergeable_constant_section (DECL_MODE (DECL), \
|
||||
ALIGN, 0); \
|
||||
break; \
|
||||
default: \
|
||||
(*sec_functions[sec]) (); \
|
||||
break; \
|
||||
} \
|
||||
} \
|
||||
else if (TREE_CODE (DECL) == VAR_DECL) \
|
||||
while (0)
|
||||
|
||||
#undef UNIQUE_SECTION
|
||||
#define UNIQUE_SECTION(DECL, RELOC) \
|
||||
do \
|
||||
{ \
|
||||
if (XSTR (XEXP (DECL_RTL (DECL), 0), 0)[0] \
|
||||
== SDATA_NAME_FLAG_CHAR) \
|
||||
sdata_section (); \
|
||||
/* ??? We need the extra RELOC check, because the default is to \
|
||||
only check RELOC if flag_pic is set, and we don't set flag_pic \
|
||||
(yet?). */ \
|
||||
else if (!DECL_READONLY_SECTION (DECL, RELOC) || (RELOC)) \
|
||||
data_section (); \
|
||||
else if (flag_merge_constants < 2) \
|
||||
/* C and C++ don't allow different variables to share \
|
||||
the same location. -fmerge-all-constants allows \
|
||||
even that (at the expense of not conforming). */ \
|
||||
const_section (); \
|
||||
else if (TREE_CODE (DECL_INITIAL (DECL)) == STRING_CST) \
|
||||
mergeable_string_section (DECL_INITIAL (DECL), (ALIGN), 0); \
|
||||
else \
|
||||
mergeable_constant_section (DECL_MODE (DECL), (ALIGN), 0); \
|
||||
static const char * const prefixes[6][2] = \
|
||||
{ \
|
||||
{ ".text.", ".gnu.linkonce.t." }, \
|
||||
{ ".rodata.", ".gnu.linkonce.r." }, \
|
||||
{ ".data.", ".gnu.linkonce.d." }, \
|
||||
{ ".sdata.", ".gnu.linkonce.s." }, \
|
||||
{ ".bss.", ".gnu.linkonce.b." }, \
|
||||
{ ".sbss.", ".gnu.linkonce.sb." } \
|
||||
}; \
|
||||
\
|
||||
int nlen, plen, sec; \
|
||||
const char *name, *prefix; \
|
||||
char *string; \
|
||||
\
|
||||
DO_SELECT_SECTION (sec, DECL, RELOC); \
|
||||
\
|
||||
name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (DECL)); \
|
||||
STRIP_NAME_ENCODING (name, name); \
|
||||
nlen = strlen (name); \
|
||||
\
|
||||
prefix = prefixes[sec & 0xff][DECL_ONE_ONLY(DECL)]; \
|
||||
plen = strlen (prefix); \
|
||||
\
|
||||
string = alloca (nlen + plen + 1); \
|
||||
\
|
||||
memcpy (string, prefix, plen); \
|
||||
memcpy (string + plen, name, nlen + 1); \
|
||||
\
|
||||
DECL_SECTION_NAME (DECL) = build_string (nlen + plen, string); \
|
||||
} \
|
||||
/* This could be a CONSTRUCTOR containing ADDR_EXPR of a VAR_DECL, \
|
||||
in which case we can't put it in a shared library rodata. */ \
|
||||
else if (flag_pic && (RELOC)) \
|
||||
data_section (); \
|
||||
else \
|
||||
const_section (); \
|
||||
}
|
||||
while (0)
|
||||
|
||||
/* Similarly for constant pool data. */
|
||||
|
||||
|
@ -186,18 +186,15 @@ do { \
|
||||
#undef LINK_SPEC
|
||||
#define LINK_SPEC "-bpT:0x10000000 -bpD:0x20000000 %{!r:-btextro} -bnodelcsect\
|
||||
%{static:-bnso %(link_syscalls) } %{shared:-bM:SRE %{!e:-bnoentry}}\
|
||||
%{!maix64:%{!shared:%{g*: %(link_libg) }}} %{maix64:-b64}"
|
||||
%{!maix64:%{!shared:%{g*: %(link_libg) }}} %{maix64:-b64}\
|
||||
%{mpe:-binitfini:poe_remote_main}"
|
||||
|
||||
#undef STARTFILE_SPEC
|
||||
#define STARTFILE_SPEC "%{!shared:\
|
||||
%{mpe:%{pg:/usr/lpp/ppe.poe/lib/gcrt0.o}\
|
||||
%{!pg:%{p:/usr/lpp/ppe.poe/lib/mcrt0.o}\
|
||||
%{!p:/usr/lpp/ppe.poe/lib/crt0.o}}}\
|
||||
%{!mpe:\
|
||||
%{maix64:%{pg:gcrt0_64%O%s}%{!pg:%{p:mcrt0_64%O%s}%{!p:crt0_64%O%s}}}\
|
||||
%{!maix64:\
|
||||
%{pthread:%{pg:gcrt0_r%O%s}%{!pg:%{p:mcrt0_r%O%s}%{!p:crt0_r%O%s}}}\
|
||||
%{!pthread:%{pg:gcrt0%O%s}%{!pg:%{p:mcrt0%O%s}%{!p:crt0%O%s}}}}}}"
|
||||
%{maix64:%{pg:gcrt0_64%O%s}%{!pg:%{p:mcrt0_64%O%s}%{!p:crt0_64%O%s}}}\
|
||||
%{!maix64:\
|
||||
%{pthread:%{pg:gcrt0_r%O%s}%{!pg:%{p:mcrt0_r%O%s}%{!p:crt0_r%O%s}}}\
|
||||
%{!pthread:%{pg:gcrt0%O%s}%{!pg:%{p:mcrt0%O%s}%{!p:crt0%O%s}}}}}"
|
||||
|
||||
/* AIX 4.3 typedefs ptrdiff_t as "long" while earlier releases used "int". */
|
||||
|
||||
|
@ -189,18 +189,15 @@ do { \
|
||||
#undef LINK_SPEC
|
||||
#define LINK_SPEC "-bpT:0x10000000 -bpD:0x20000000 %{!r:-btextro} -bnodelcsect\
|
||||
%{static:-bnso %(link_syscalls) } %{shared:-bM:SRE %{!e:-bnoentry}}\
|
||||
%{!maix64:%{!shared:%{g*: %(link_libg) }}} %{maix64:-b64}"
|
||||
%{!maix64:%{!shared:%{g*: %(link_libg) }}} %{maix64:-b64}\
|
||||
%{mpe:-binitfini:poe_remote_main}"
|
||||
|
||||
#undef STARTFILE_SPEC
|
||||
#define STARTFILE_SPEC "%{!shared:\
|
||||
%{mpe:%{pg:/usr/lpp/ppe.poe/lib/gcrt0.o}\
|
||||
%{!pg:%{p:/usr/lpp/ppe.poe/lib/mcrt0.o}\
|
||||
%{!p:/usr/lpp/ppe.poe/lib/crt0.o}}}\
|
||||
%{!mpe:\
|
||||
%{maix64:%{pg:gcrt0_64%O%s}%{!pg:%{p:mcrt0_64%O%s}%{!p:crt0_64%O%s}}}\
|
||||
%{!maix64:\
|
||||
%{pthread:%{pg:gcrt0_r%O%s}%{!pg:%{p:mcrt0_r%O%s}%{!p:crt0_r%O%s}}}\
|
||||
%{!pthread:%{pg:gcrt0%O%s}%{!pg:%{p:mcrt0%O%s}%{!p:crt0%O%s}}}}}}"
|
||||
%{maix64:%{pg:gcrt0_64%O%s}%{!pg:%{p:mcrt0_64%O%s}%{!p:crt0_64%O%s}}}\
|
||||
%{!maix64:\
|
||||
%{pthread:%{pg:gcrt0_r%O%s}%{!pg:%{p:mcrt0_r%O%s}%{!p:crt0_r%O%s}}}\
|
||||
%{!pthread:%{pg:gcrt0%O%s}%{!pg:%{p:mcrt0%O%s}%{!p:crt0%O%s}}}}}"
|
||||
|
||||
/* AIX V5 typedefs ptrdiff_t as "long" while earlier releases used "int". */
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -308,3 +308,22 @@ do { \
|
||||
|| (GET_MODE_CLASS (GET_MODE (X)) == MODE_FLOAT \
|
||||
&& ! TARGET_NO_FP_IN_TOC)))))
|
||||
|
||||
/* This is the same as the dbxelf.h version, except that we need to
|
||||
use the function code label, not the function descriptor. */
|
||||
#undef ASM_OUTPUT_SOURCE_LINE
|
||||
#define ASM_OUTPUT_SOURCE_LINE(FILE, LINE) \
|
||||
do \
|
||||
{ \
|
||||
static int sym_lineno = 1; \
|
||||
char temp[256]; \
|
||||
ASM_GENERATE_INTERNAL_LABEL (temp, "LM", sym_lineno); \
|
||||
fprintf (FILE, "\t.stabn 68,0,%d,", LINE); \
|
||||
assemble_name (FILE, temp); \
|
||||
fputs ("-.", FILE); \
|
||||
assemble_name (FILE, \
|
||||
XSTR (XEXP (DECL_RTL (current_function_decl), 0), 0));\
|
||||
putc ('\n', FILE); \
|
||||
ASM_OUTPUT_INTERNAL_LABEL (FILE, "LM", sym_lineno); \
|
||||
sym_lineno += 1; \
|
||||
} \
|
||||
while (0)
|
||||
|
@ -60,11 +60,6 @@ Boston, MA 02111-1307, USA. */
|
||||
#undef TARGET_VERSION
|
||||
#define TARGET_VERSION fprintf (stderr, " (PowerPC NetBSD/ELF)");
|
||||
|
||||
/* For backward compatibility, we must continue to use the AIX
|
||||
structure return convention. */
|
||||
#undef DRAFT_V4_STRUCT_RET
|
||||
#define DRAFT_V4_STRUCT_RET 1
|
||||
|
||||
/* Use STABS debugging information by default. DWARF2 makes a mess of
|
||||
the 1.5.2 linker. */
|
||||
#undef PREFERRED_DEBUGGING_TYPE
|
||||
|
@ -9735,23 +9735,22 @@ output_mi_thunk (file, thunk_fndecl, delta, function)
|
||||
fprintf (file, "\taddi %s,%s,%d\n", this_reg, this_reg, delta);
|
||||
}
|
||||
|
||||
/* 64-bit constants. If "int" is 32 bits, we'll never hit this abort. */
|
||||
else if (TARGET_64BIT && (delta < -2147483647 - 1 || delta > 2147483647))
|
||||
abort ();
|
||||
|
||||
/* Large constants that can be done by one addis instruction. */
|
||||
else if ((delta & 0xffff) == 0 && num_insns_constant_wide (delta) == 1)
|
||||
else if ((delta & 0xffff) == 0)
|
||||
asm_fprintf (file, "\t{cau|addis} %s,%s,%d\n", this_reg, this_reg,
|
||||
delta >> 16);
|
||||
|
||||
/* 32-bit constants that can be done by an add and addis instruction. */
|
||||
else if (TARGET_32BIT || num_insns_constant_wide (delta) == 1)
|
||||
else
|
||||
{
|
||||
/* Break into two pieces, propagating the sign bit from the low
|
||||
word to the upper word. */
|
||||
int delta_high = delta >> 16;
|
||||
int delta_low = delta & 0xffff;
|
||||
if ((delta_low & 0x8000) != 0)
|
||||
{
|
||||
delta_high++;
|
||||
delta_low = (delta_low ^ 0x8000) - 0x8000; /* sign extend */
|
||||
}
|
||||
int delta_low = ((delta & 0xffff) ^ 0x8000) - 0x8000;
|
||||
int delta_high = (delta - delta_low) >> 16;
|
||||
|
||||
asm_fprintf (file, "\t{cau|addis} %s,%s,%d\n", this_reg, this_reg,
|
||||
delta_high);
|
||||
@ -9762,10 +9761,6 @@ output_mi_thunk (file, thunk_fndecl, delta, function)
|
||||
fprintf (file, "\taddi %s,%s,%d\n", this_reg, this_reg, delta_low);
|
||||
}
|
||||
|
||||
/* 64-bit constants, fixme */
|
||||
else
|
||||
abort ();
|
||||
|
||||
/* Get the prefix in front of the names. */
|
||||
switch (DEFAULT_ABI)
|
||||
{
|
||||
@ -9821,7 +9816,10 @@ output_mi_thunk (file, thunk_fndecl, delta, function)
|
||||
}
|
||||
assemble_name (file, fname);
|
||||
putc ('\n', file);
|
||||
text_section ();
|
||||
if (TARGET_ELF)
|
||||
function_section (current_function_decl);
|
||||
else
|
||||
text_section ();
|
||||
if (TARGET_MINIMAL_TOC)
|
||||
asm_fprintf (file, (TARGET_32BIT)
|
||||
? "\t{l|lwz} %s,%s(%s)\n" : "\tld %s,%s(%s)\n", r12,
|
||||
@ -10157,8 +10155,10 @@ output_toc (file, x, labelno, mode)
|
||||
if (TARGET_MINIMAL_TOC)
|
||||
fputs (DOUBLE_INT_ASM_OP, file);
|
||||
else
|
||||
fprintf (file, "\t.tc FD_%lx_%lx[TC],", k[0], k[1]);
|
||||
fprintf (file, "0x%lx%08lx\n", k[0], k[1]);
|
||||
fprintf (file, "\t.tc FD_%lx_%lx[TC],",
|
||||
k[0] & 0xffffffff, k[1] & 0xffffffff);
|
||||
fprintf (file, "0x%lx%08lx\n",
|
||||
k[0] & 0xffffffff, k[1] & 0xffffffff);
|
||||
return;
|
||||
}
|
||||
else
|
||||
@ -10166,8 +10166,10 @@ output_toc (file, x, labelno, mode)
|
||||
if (TARGET_MINIMAL_TOC)
|
||||
fputs ("\t.long ", file);
|
||||
else
|
||||
fprintf (file, "\t.tc FD_%lx_%lx[TC],", k[0], k[1]);
|
||||
fprintf (file, "0x%lx,0x%lx\n", k[0], k[1]);
|
||||
fprintf (file, "\t.tc FD_%lx_%lx[TC],",
|
||||
k[0] & 0xffffffff, k[1] & 0xffffffff);
|
||||
fprintf (file, "0x%lx,0x%lx\n",
|
||||
k[0] & 0xffffffff, k[1] & 0xffffffff);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -10184,8 +10186,8 @@ output_toc (file, x, labelno, mode)
|
||||
if (TARGET_MINIMAL_TOC)
|
||||
fputs (DOUBLE_INT_ASM_OP, file);
|
||||
else
|
||||
fprintf (file, "\t.tc FS_%lx[TC],", l);
|
||||
fprintf (file, "0x%lx00000000\n", l);
|
||||
fprintf (file, "\t.tc FS_%lx[TC],", l & 0xffffffff);
|
||||
fprintf (file, "0x%lx00000000\n", l & 0xffffffff);
|
||||
return;
|
||||
}
|
||||
else
|
||||
@ -10193,8 +10195,8 @@ output_toc (file, x, labelno, mode)
|
||||
if (TARGET_MINIMAL_TOC)
|
||||
fputs ("\t.long ", file);
|
||||
else
|
||||
fprintf (file, "\t.tc FS_%lx[TC],", l);
|
||||
fprintf (file, "0x%lx\n", l);
|
||||
fprintf (file, "\t.tc FS_%lx[TC],", l & 0xffffffff);
|
||||
fprintf (file, "0x%lx\n", l & 0xffffffff);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -10244,8 +10246,10 @@ output_toc (file, x, labelno, mode)
|
||||
if (TARGET_MINIMAL_TOC)
|
||||
fputs (DOUBLE_INT_ASM_OP, file);
|
||||
else
|
||||
fprintf (file, "\t.tc ID_%lx_%lx[TC],", (long) high, (long) low);
|
||||
fprintf (file, "0x%lx%08lx\n", (long) high, (long) low);
|
||||
fprintf (file, "\t.tc ID_%lx_%lx[TC],",
|
||||
(long) high & 0xffffffff, (long) low & 0xffffffff);
|
||||
fprintf (file, "0x%lx%08lx\n",
|
||||
(long) high & 0xffffffff, (long) low & 0xffffffff);
|
||||
return;
|
||||
}
|
||||
else
|
||||
@ -10256,16 +10260,17 @@ output_toc (file, x, labelno, mode)
|
||||
fputs ("\t.long ", file);
|
||||
else
|
||||
fprintf (file, "\t.tc ID_%lx_%lx[TC],",
|
||||
(long) high, (long) low);
|
||||
fprintf (file, "0x%lx,0x%lx\n", (long) high, (long) low);
|
||||
(long) high & 0xffffffff, (long) low & 0xffffffff);
|
||||
fprintf (file, "0x%lx,0x%lx\n",
|
||||
(long) high & 0xffffffff, (long) low & 0xffffffff);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (TARGET_MINIMAL_TOC)
|
||||
fputs ("\t.long ", file);
|
||||
else
|
||||
fprintf (file, "\t.tc IS_%lx[TC],", (long) low);
|
||||
fprintf (file, "0x%lx\n", (long) low);
|
||||
fprintf (file, "\t.tc IS_%lx[TC],", (long) low & 0xffffffff);
|
||||
fprintf (file, "0x%lx\n", (long) low & 0xffffffff);
|
||||
}
|
||||
return;
|
||||
}
|
||||
@ -10879,18 +10884,19 @@ rs6000_select_section (decl, reloc)
|
||||
if (TREE_CODE (decl) == STRING_CST)
|
||||
readonly = ! flag_writable_strings;
|
||||
else if (TREE_CODE (decl) == VAR_DECL)
|
||||
readonly = (! (flag_pic && reloc)
|
||||
readonly = (! ((flag_pic || DEFAULT_ABI == ABI_AIX) && reloc)
|
||||
&& TREE_READONLY (decl)
|
||||
&& ! TREE_SIDE_EFFECTS (decl)
|
||||
&& DECL_INITIAL (decl)
|
||||
&& DECL_INITIAL (decl) != error_mark_node
|
||||
&& TREE_CONSTANT (DECL_INITIAL (decl)));
|
||||
else if (TREE_CODE (decl) == CONSTRUCTOR)
|
||||
readonly = (! (flag_pic && reloc)
|
||||
readonly = (! ((flag_pic || DEFAULT_ABI == ABI_AIX) && reloc)
|
||||
&& ! TREE_SIDE_EFFECTS (decl)
|
||||
&& TREE_CONSTANT (decl));
|
||||
else
|
||||
readonly = 1;
|
||||
readonly = ! ((flag_pic || DEFAULT_ABI == ABI_AIX) && reloc);
|
||||
|
||||
if (needs_sdata && rs6000_sdata != SDATA_EABI)
|
||||
readonly = 0;
|
||||
|
||||
@ -10935,14 +10941,15 @@ rs6000_unique_section (decl, reloc)
|
||||
int needs_sdata;
|
||||
int size;
|
||||
|
||||
readonly = 1;
|
||||
if (TREE_CODE (decl) == STRING_CST)
|
||||
readonly = ! flag_writable_strings;
|
||||
else if (TREE_CODE (decl) == VAR_DECL)
|
||||
readonly = (! (flag_pic && reloc)
|
||||
readonly = (! ((flag_pic || DEFAULT_ABI == ABI_AIX) && reloc)
|
||||
&& TREE_READONLY (decl)
|
||||
&& ! TREE_SIDE_EFFECTS (decl)
|
||||
&& TREE_CONSTANT (DECL_INITIAL (decl)));
|
||||
else
|
||||
readonly = ! ((flag_pic || DEFAULT_ABI == ABI_AIX) && reloc);
|
||||
|
||||
size = int_size_in_bytes (TREE_TYPE (decl));
|
||||
needs_sdata = (size > 0
|
||||
|
@ -105,8 +105,8 @@ Boston, MA 02111-1307, USA. */
|
||||
%{mcpu=rsc: -mpwr} \
|
||||
%{mcpu=rsc1: -mpwr} \
|
||||
%{mcpu=401: -mppc} \
|
||||
%{mcpu=403: -mppc} \
|
||||
%{mcpu=405: -mppc} \
|
||||
%{mcpu=403: -m403} \
|
||||
%{mcpu=405: -m405} \
|
||||
%{mcpu=505: -mppc} \
|
||||
%{mcpu=601: -m601} \
|
||||
%{mcpu=602: -mppc} \
|
||||
@ -2439,12 +2439,14 @@ extern int toc_initialized;
|
||||
do \
|
||||
{ \
|
||||
fputs ("\t.weak\t", (FILE)); \
|
||||
assemble_name ((FILE), (NAME)); \
|
||||
RS6000_OUTPUT_BASENAME ((FILE), (NAME)); \
|
||||
if ((DECL) && TREE_CODE (DECL) == FUNCTION_DECL \
|
||||
&& DEFAULT_ABI == ABI_AIX) \
|
||||
{ \
|
||||
if (TARGET_XCOFF) \
|
||||
fputs ("[DS]", (FILE)); \
|
||||
fputs ("\n\t.weak\t.", (FILE)); \
|
||||
assemble_name ((FILE), (NAME)); \
|
||||
RS6000_OUTPUT_BASENAME ((FILE), (NAME)); \
|
||||
} \
|
||||
fputc ('\n', (FILE)); \
|
||||
if (VAL) \
|
||||
@ -2454,9 +2456,9 @@ extern int toc_initialized;
|
||||
&& DEFAULT_ABI == ABI_AIX) \
|
||||
{ \
|
||||
fputs ("\t.set\t.", (FILE)); \
|
||||
assemble_name ((FILE), (NAME)); \
|
||||
RS6000_OUTPUT_BASENAME ((FILE), (NAME)); \
|
||||
fputs (",.", (FILE)); \
|
||||
assemble_name ((FILE), (VAL)); \
|
||||
RS6000_OUTPUT_BASENAME ((FILE), (VAL)); \
|
||||
fputc ('\n', (FILE)); \
|
||||
} \
|
||||
} \
|
||||
@ -2479,20 +2481,20 @@ extern int toc_initialized;
|
||||
if (!RS6000_WEAK || !DECL_WEAK (DECL)) \
|
||||
{ \
|
||||
fputs ("\t.globl\t.", FILE); \
|
||||
assemble_name (FILE, alias); \
|
||||
RS6000_OUTPUT_BASENAME (FILE, alias); \
|
||||
putc ('\n', FILE); \
|
||||
} \
|
||||
} \
|
||||
else if (TARGET_XCOFF) \
|
||||
{ \
|
||||
fputs ("\t.lglobl\t.", FILE); \
|
||||
assemble_name (FILE, alias); \
|
||||
RS6000_OUTPUT_BASENAME (FILE, alias); \
|
||||
putc ('\n', FILE); \
|
||||
} \
|
||||
fputs ("\t.set\t.", FILE); \
|
||||
assemble_name (FILE, alias); \
|
||||
RS6000_OUTPUT_BASENAME (FILE, alias); \
|
||||
fputs (",.", FILE); \
|
||||
assemble_name (FILE, name); \
|
||||
RS6000_OUTPUT_BASENAME (FILE, name); \
|
||||
fputc ('\n', FILE); \
|
||||
} \
|
||||
ASM_OUTPUT_DEF (FILE, alias, name); \
|
||||
|
@ -5271,9 +5271,18 @@
|
||||
(clobber (match_dup 4))
|
||||
(clobber (match_dup 5))
|
||||
(clobber (match_dup 6))])]
|
||||
"! TARGET_POWERPC64 && TARGET_HARD_FLOAT"
|
||||
"TARGET_HARD_FLOAT"
|
||||
"
|
||||
{
|
||||
if (TARGET_POWERPC64)
|
||||
{
|
||||
rtx mem = assign_stack_temp (DImode, GET_MODE_SIZE (DImode), 0);
|
||||
rtx t1 = gen_reg_rtx (DImode);
|
||||
rtx t2 = gen_reg_rtx (DImode);
|
||||
emit_insn (gen_floatsidf_ppc64 (operands[0], operands[1], mem, t1, t2));
|
||||
DONE;
|
||||
}
|
||||
|
||||
operands[2] = force_reg (SImode, GEN_INT (0x43300000));
|
||||
operands[3] = force_reg (DFmode, rs6000_float_const (\"4503601774854144\", DFmode));
|
||||
operands[4] = assign_stack_temp (DFmode, GET_MODE_SIZE (DFmode), 0);
|
||||
@ -5338,9 +5347,19 @@
|
||||
(use (match_dup 3))
|
||||
(clobber (match_dup 4))
|
||||
(clobber (match_dup 5))])]
|
||||
"! TARGET_POWERPC64 && TARGET_HARD_FLOAT"
|
||||
"TARGET_HARD_FLOAT"
|
||||
"
|
||||
{
|
||||
if (TARGET_POWERPC64)
|
||||
{
|
||||
rtx mem = assign_stack_temp (DImode, GET_MODE_SIZE (DImode), 0);
|
||||
rtx t1 = gen_reg_rtx (DImode);
|
||||
rtx t2 = gen_reg_rtx (DImode);
|
||||
emit_insn (gen_floatunssidf_ppc64 (operands[0], operands[1], mem,
|
||||
t1, t2));
|
||||
DONE;
|
||||
}
|
||||
|
||||
operands[2] = force_reg (SImode, GEN_INT (0x43300000));
|
||||
operands[3] = force_reg (DFmode, rs6000_float_const (\"4503599627370496\", DFmode));
|
||||
operands[4] = assign_stack_temp (DFmode, GET_MODE_SIZE (DFmode), 0);
|
||||
@ -5407,7 +5426,7 @@
|
||||
(define_insn "*fix_truncdfsi2_internal"
|
||||
[(set (match_operand:SI 0 "gpc_reg_operand" "=r")
|
||||
(fix:SI (match_operand:DF 1 "gpc_reg_operand" "f")))
|
||||
(clobber (match_operand:DI 2 "gpc_reg_operand" "=f"))
|
||||
(clobber (match_operand:DI 2 "gpc_reg_operand" "=*f"))
|
||||
(clobber (match_operand:DI 3 "memory_operand" "=o"))]
|
||||
"(TARGET_POWER2 || TARGET_POWERPC) && TARGET_HARD_FLOAT"
|
||||
"#"
|
||||
@ -5443,7 +5462,7 @@
|
||||
; because the first makes it clear that operand 0 is not live
|
||||
; before the instruction.
|
||||
(define_insn "fctiwz"
|
||||
[(set (match_operand:DI 0 "gpc_reg_operand" "=f")
|
||||
[(set (match_operand:DI 0 "gpc_reg_operand" "=*f")
|
||||
(unspec:DI [(fix:SI (match_operand:DF 1 "gpc_reg_operand" "f"))] 10))]
|
||||
"(TARGET_POWER2 || TARGET_POWERPC) && TARGET_HARD_FLOAT"
|
||||
"{fcirz|fctiwz} %0,%1"
|
||||
@ -5451,13 +5470,43 @@
|
||||
|
||||
(define_insn "floatdidf2"
|
||||
[(set (match_operand:DF 0 "gpc_reg_operand" "=f")
|
||||
(float:DF (match_operand:DI 1 "gpc_reg_operand" "f")))]
|
||||
(float:DF (match_operand:DI 1 "gpc_reg_operand" "*f")))]
|
||||
"TARGET_POWERPC64 && TARGET_HARD_FLOAT"
|
||||
"fcfid %0,%1"
|
||||
[(set_attr "type" "fp")])
|
||||
|
||||
(define_insn_and_split "floatsidf_ppc64"
|
||||
[(set (match_operand:DF 0 "gpc_reg_operand" "=f")
|
||||
(float:DF (match_operand:SI 1 "gpc_reg_operand" "r")))
|
||||
(clobber (match_operand:DI 2 "memory_operand" "=o"))
|
||||
(clobber (match_operand:DI 3 "gpc_reg_operand" "=r"))
|
||||
(clobber (match_operand:DI 4 "gpc_reg_operand" "=f"))]
|
||||
"TARGET_POWERPC64 && TARGET_HARD_FLOAT"
|
||||
"#"
|
||||
""
|
||||
[(set (match_dup 3) (sign_extend:DI (match_dup 1)))
|
||||
(set (match_dup 2) (match_dup 3))
|
||||
(set (match_dup 4) (match_dup 2))
|
||||
(set (match_dup 0) (float:DF (match_dup 4)))]
|
||||
"")
|
||||
|
||||
(define_insn_and_split "floatunssidf_ppc64"
|
||||
[(set (match_operand:DF 0 "gpc_reg_operand" "=f")
|
||||
(unsigned_float:DF (match_operand:SI 1 "gpc_reg_operand" "r")))
|
||||
(clobber (match_operand:DI 2 "memory_operand" "=o"))
|
||||
(clobber (match_operand:DI 3 "gpc_reg_operand" "=r"))
|
||||
(clobber (match_operand:DI 4 "gpc_reg_operand" "=f"))]
|
||||
"TARGET_POWERPC64 && TARGET_HARD_FLOAT"
|
||||
"#"
|
||||
""
|
||||
[(set (match_dup 3) (zero_extend:DI (match_dup 1)))
|
||||
(set (match_dup 2) (match_dup 3))
|
||||
(set (match_dup 4) (match_dup 2))
|
||||
(set (match_dup 0) (float:DF (match_dup 4)))]
|
||||
"")
|
||||
|
||||
(define_insn "fix_truncdfdi2"
|
||||
[(set (match_operand:DI 0 "gpc_reg_operand" "=f")
|
||||
[(set (match_operand:DI 0 "gpc_reg_operand" "=*f")
|
||||
(fix:DI (match_operand:DF 1 "gpc_reg_operand" "f")))]
|
||||
"TARGET_POWERPC64 && TARGET_HARD_FLOAT"
|
||||
"fctidz %0,%1"
|
||||
@ -13255,15 +13304,15 @@
|
||||
|
||||
(define_insn "*ctrdi_internal1"
|
||||
[(set (pc)
|
||||
(if_then_else (ne (match_operand:DI 1 "register_operand" "c,*r,*r,!*f")
|
||||
(if_then_else (ne (match_operand:DI 1 "register_operand" "c,*r,*r")
|
||||
(const_int 1))
|
||||
(label_ref (match_operand 0 "" ""))
|
||||
(pc)))
|
||||
(set (match_operand:DI 2 "register_operand" "=1,*r,m*c*l,!*f")
|
||||
(set (match_operand:DI 2 "register_operand" "=1,*r,m*c*l")
|
||||
(plus:DI (match_dup 1)
|
||||
(const_int -1)))
|
||||
(clobber (match_scratch:CC 3 "=X,&x,&x,&x"))
|
||||
(clobber (match_scratch:DI 4 "=X,X,r,r"))]
|
||||
(clobber (match_scratch:CC 3 "=X,&x,&x"))
|
||||
(clobber (match_scratch:DI 4 "=X,X,r"))]
|
||||
"TARGET_POWERPC64"
|
||||
"*
|
||||
{
|
||||
@ -13275,19 +13324,19 @@
|
||||
return \"bdz $+8\;b %l0\";
|
||||
}"
|
||||
[(set_attr "type" "branch")
|
||||
(set_attr "length" "*,12,16,24")])
|
||||
(set_attr "length" "*,12,16")])
|
||||
|
||||
(define_insn "*ctrdi_internal2"
|
||||
[(set (pc)
|
||||
(if_then_else (ne (match_operand:DI 1 "register_operand" "c,*r,*r,!*f")
|
||||
(if_then_else (ne (match_operand:DI 1 "register_operand" "c,*r,*r")
|
||||
(const_int 1))
|
||||
(pc)
|
||||
(label_ref (match_operand 0 "" ""))))
|
||||
(set (match_operand:DI 2 "register_operand" "=1,*r,m*c*l,!*f")
|
||||
(set (match_operand:DI 2 "register_operand" "=1,*r,m*c*l")
|
||||
(plus:DI (match_dup 1)
|
||||
(const_int -1)))
|
||||
(clobber (match_scratch:CC 3 "=X,&x,&x,&x"))
|
||||
(clobber (match_scratch:DI 4 "=X,X,r,r"))]
|
||||
(clobber (match_scratch:CC 3 "=X,&x,&x"))
|
||||
(clobber (match_scratch:DI 4 "=X,X,r"))]
|
||||
"TARGET_POWERPC64"
|
||||
"*
|
||||
{
|
||||
@ -13299,7 +13348,7 @@
|
||||
return \"{bdn|bdnz} $+8\;b %l0\";
|
||||
}"
|
||||
[(set_attr "type" "branch")
|
||||
(set_attr "length" "*,12,16,24")])
|
||||
(set_attr "length" "*,12,16")])
|
||||
|
||||
;; Similar, but we can use GE since we have a REG_NONNEG.
|
||||
|
||||
@ -13353,15 +13402,15 @@
|
||||
|
||||
(define_insn "*ctrdi_internal3"
|
||||
[(set (pc)
|
||||
(if_then_else (ge (match_operand:DI 1 "register_operand" "c,*r,*r,!*f")
|
||||
(if_then_else (ge (match_operand:DI 1 "register_operand" "c,*r,*r")
|
||||
(const_int 0))
|
||||
(label_ref (match_operand 0 "" ""))
|
||||
(pc)))
|
||||
(set (match_operand:DI 2 "register_operand" "=1,*r,m*c*l,!*f")
|
||||
(set (match_operand:DI 2 "register_operand" "=1,*r,m*c*l")
|
||||
(plus:DI (match_dup 1)
|
||||
(const_int -1)))
|
||||
(clobber (match_scratch:CC 3 "=X,&x,&x,&x"))
|
||||
(clobber (match_scratch:DI 4 "=X,X,r,r"))]
|
||||
(clobber (match_scratch:CC 3 "=X,&x,&x"))
|
||||
(clobber (match_scratch:DI 4 "=X,X,r"))]
|
||||
"TARGET_POWERPC64 && find_reg_note (insn, REG_NONNEG, 0)"
|
||||
"*
|
||||
{
|
||||
@ -13373,19 +13422,19 @@
|
||||
return \"bdz $+8\;b %l0\";
|
||||
}"
|
||||
[(set_attr "type" "branch")
|
||||
(set_attr "length" "*,12,16,24")])
|
||||
(set_attr "length" "*,12,16")])
|
||||
|
||||
(define_insn "*ctrdi_internal4"
|
||||
[(set (pc)
|
||||
(if_then_else (ge (match_operand:DI 1 "register_operand" "c,*r,*r,!*f")
|
||||
(if_then_else (ge (match_operand:DI 1 "register_operand" "c,*r,*r")
|
||||
(const_int 0))
|
||||
(pc)
|
||||
(label_ref (match_operand 0 "" ""))))
|
||||
(set (match_operand:DI 2 "register_operand" "=1,*r,m*c*l,!*f")
|
||||
(set (match_operand:DI 2 "register_operand" "=1,*r,m*c*l")
|
||||
(plus:DI (match_dup 1)
|
||||
(const_int -1)))
|
||||
(clobber (match_scratch:CC 3 "=X,&x,&x,&x"))
|
||||
(clobber (match_scratch:DI 4 "=X,X,r,r"))]
|
||||
(clobber (match_scratch:CC 3 "=X,&x,&x"))
|
||||
(clobber (match_scratch:DI 4 "=X,X,r"))]
|
||||
"TARGET_POWERPC64 && find_reg_note (insn, REG_NONNEG, 0)"
|
||||
"*
|
||||
{
|
||||
@ -13397,7 +13446,7 @@
|
||||
return \"{bdn|bdnz} $+8\;b %l0\";
|
||||
}"
|
||||
[(set_attr "type" "branch")
|
||||
(set_attr "length" "*,12,16,24")])
|
||||
(set_attr "length" "*,12,16")])
|
||||
|
||||
;; Similar but use EQ
|
||||
|
||||
@ -13451,15 +13500,15 @@
|
||||
|
||||
(define_insn "*ctrdi_internal5"
|
||||
[(set (pc)
|
||||
(if_then_else (eq (match_operand:DI 1 "register_operand" "c,*r,*r,!*f")
|
||||
(if_then_else (eq (match_operand:DI 1 "register_operand" "c,*r,*r")
|
||||
(const_int 1))
|
||||
(label_ref (match_operand 0 "" ""))
|
||||
(pc)))
|
||||
(set (match_operand:DI 2 "register_operand" "=1,*r,m*c*l,!*f")
|
||||
(set (match_operand:DI 2 "register_operand" "=1,*r,m*c*l")
|
||||
(plus:DI (match_dup 1)
|
||||
(const_int -1)))
|
||||
(clobber (match_scratch:CC 3 "=X,&x,&x,&x"))
|
||||
(clobber (match_scratch:DI 4 "=X,X,r,r"))]
|
||||
(clobber (match_scratch:CC 3 "=X,&x,&x"))
|
||||
(clobber (match_scratch:DI 4 "=X,X,r"))]
|
||||
"TARGET_POWERPC64"
|
||||
"*
|
||||
{
|
||||
@ -13471,19 +13520,19 @@
|
||||
return \"{bdn|bdnz} $+8\;b %l0\";
|
||||
}"
|
||||
[(set_attr "type" "branch")
|
||||
(set_attr "length" "*,12,16,24")])
|
||||
(set_attr "length" "*,12,16")])
|
||||
|
||||
(define_insn "*ctrdi_internal6"
|
||||
[(set (pc)
|
||||
(if_then_else (eq (match_operand:DI 1 "register_operand" "c,*r,*r,!*f")
|
||||
(if_then_else (eq (match_operand:DI 1 "register_operand" "c,*r,*r")
|
||||
(const_int 1))
|
||||
(pc)
|
||||
(label_ref (match_operand 0 "" ""))))
|
||||
(set (match_operand:DI 2 "register_operand" "=1,*r,m*c*l,!*f")
|
||||
(set (match_operand:DI 2 "register_operand" "=1,*r,m*c*l")
|
||||
(plus:DI (match_dup 1)
|
||||
(const_int -1)))
|
||||
(clobber (match_scratch:CC 3 "=X,&x,&x,&x"))
|
||||
(clobber (match_scratch:DI 4 "=X,X,r,r"))]
|
||||
(clobber (match_scratch:CC 3 "=X,&x,&x"))
|
||||
(clobber (match_scratch:DI 4 "=X,X,r"))]
|
||||
"TARGET_POWERPC64"
|
||||
"*
|
||||
{
|
||||
@ -13495,7 +13544,7 @@
|
||||
return \"bdz $+8\;b %l0\";
|
||||
}"
|
||||
[(set_attr "type" "branch")
|
||||
(set_attr "length" "*,12,16,24")])
|
||||
(set_attr "length" "*,12,16")])
|
||||
|
||||
;; Now the splitters if we could not allocate the CTR register
|
||||
|
||||
@ -13566,7 +13615,7 @@
|
||||
(const_int -1)))
|
||||
(clobber (match_scratch:CC 3 ""))
|
||||
(clobber (match_scratch:DI 4 ""))]
|
||||
"TARGET_POWERPC64 && reload_completed && INT_REGNO_P (REGNO (operands[0]))"
|
||||
"TARGET_POWERPC64 && reload_completed"
|
||||
[(parallel [(set (match_dup 3)
|
||||
(compare:CC (plus:DI (match_dup 1)
|
||||
(const_int -1))
|
||||
@ -13610,44 +13659,6 @@
|
||||
{ operands[7] = gen_rtx (GET_CODE (operands[2]), VOIDmode, operands[3],
|
||||
const0_rtx); }")
|
||||
|
||||
(define_split
|
||||
[(set (pc)
|
||||
(if_then_else (match_operator 2 "comparison_operator"
|
||||
[(match_operand:DI 1 "gpc_reg_operand" "")
|
||||
(const_int 1)])
|
||||
(match_operand 5 "" "")
|
||||
(match_operand 6 "" "")))
|
||||
(set (match_operand:DI 0 "gpc_reg_operand" "")
|
||||
(plus:DI (match_dup 1)
|
||||
(const_int -1)))
|
||||
(clobber (match_scratch:CC 3 ""))
|
||||
(clobber (match_scratch:DI 4 ""))]
|
||||
"TARGET_POWERPC64 && reload_completed && FP_REGNO_P (REGNO (operands[0]))"
|
||||
[(set (match_dup 8)
|
||||
(match_dup 1))
|
||||
(set (match_dup 4)
|
||||
(match_dup 8))
|
||||
(parallel [(set (match_dup 3)
|
||||
(compare:CC (plus:DI (match_dup 4)
|
||||
(const_int -1))
|
||||
(const_int 0)))
|
||||
(set (match_dup 4)
|
||||
(plus:DI (match_dup 4)
|
||||
(const_int -1)))])
|
||||
(set (match_dup 8)
|
||||
(match_dup 4))
|
||||
(set (match_dup 0)
|
||||
(match_dup 8))
|
||||
(set (pc) (if_then_else (match_dup 7)
|
||||
(match_dup 5)
|
||||
(match_dup 6)))]
|
||||
"
|
||||
{
|
||||
operands[7] = gen_rtx (GET_CODE (operands[2]), VOIDmode, operands[3],
|
||||
const0_rtx);
|
||||
operands[8] = assign_stack_temp (DImode, GET_MODE_SIZE (DImode), 0);
|
||||
}")
|
||||
|
||||
|
||||
(define_insn "trap"
|
||||
[(trap_if (const_int 1) (const_int 0))]
|
||||
|
@ -403,7 +403,6 @@ do { \
|
||||
: MAX (COMPUTED, SPECIFIED))
|
||||
|
||||
#undef BIGGEST_FIELD_ALIGNMENT
|
||||
#undef ADJUST_FIELD_ALIGN
|
||||
|
||||
/* Use ELF style section commands. */
|
||||
|
||||
|
@ -457,6 +457,15 @@ toc_section () \
|
||||
/* This is how we tell the assembler that two symbols have the same value. */
|
||||
#define SET_ASM_OP "\t.set "
|
||||
|
||||
/* This is how we tell the assembler to equate two values. */
|
||||
#define ASM_OUTPUT_DEF(FILE,LABEL1,LABEL2) \
|
||||
do { fprintf ((FILE), "%s", SET_ASM_OP); \
|
||||
RS6000_OUTPUT_BASENAME (FILE, LABEL1); \
|
||||
fprintf (FILE, ","); \
|
||||
RS6000_OUTPUT_BASENAME (FILE, LABEL2); \
|
||||
fprintf (FILE, "\n"); \
|
||||
} while (0)
|
||||
|
||||
/* Used by rs6000_assemble_integer, among others. */
|
||||
#define DOUBLE_INT_ASM_OP "\t.llong\t"
|
||||
|
||||
|
@ -31,12 +31,28 @@ Boston, MA 02111-1307, USA. */
|
||||
/* CPP defines used for 64 bit code. */
|
||||
#undef CPP_SUBTARGET_SPEC64
|
||||
#define CPP_SUBTARGET_SPEC64 \
|
||||
"-D__sparc64__ -D__arch64__ -D__sparc_v9__ %{posix:-D_POSIX_SOURCE}"
|
||||
"-D__sparc64__ -D__sparc_v9__ -D_LP64 %{posix:-D_POSIX_SOURCE}"
|
||||
|
||||
/* CPP defines used for 32 bit code. */
|
||||
#undef CPP_SUBTARGET_SPEC32
|
||||
#define CPP_SUBTARGET_SPEC32 "-D__sparc %{posix:-D_POSIX_SOURCE}"
|
||||
|
||||
/* CPP_ARCH32_SPEC and CPP_ARCH64_SPEC are wrong from sparc/sparc.h; we
|
||||
always want the non-SPARC_BI_ARCH versions, since the SPARC_BI_ARCH
|
||||
versions define __SIZE_TYPE__ and __PTRDIFF_TYPE__ incorrectly for
|
||||
NetBSD. */
|
||||
#undef CPP_ARCH32_SPEC
|
||||
#define CPP_ARCH32_SPEC "-D__GCC_NEW_VARARGS__ -Acpu=sparc -Amachine=sparc"
|
||||
|
||||
#undef CPP_ARCH64_SPEC
|
||||
#define CPP_ARCH64_SPEC "-D__arch64__ -Acpu=sparc64 -Amachine=sparc64"
|
||||
|
||||
/* sparc/sparc.h defines NO_BUILTIN_SIZE_TYPE and NO_BUILTIN_PTRDIFF_TYPE
|
||||
if SPARC_BI_ARCH is defined. This is wrong for NetBSD; size_t and
|
||||
ptrdiff_t do not change for 32-bit vs. 64-bit. */
|
||||
#undef NO_BUILTIN_PTRDIFF_TYPE
|
||||
#undef NO_BUILTIN_SIZE_TYPE
|
||||
|
||||
/* SIZE_TYPE and PTRDIFF_TYPE are wrong from sparc/sparc.h. */
|
||||
#undef SIZE_TYPE
|
||||
#define SIZE_TYPE "long unsigned int"
|
||||
@ -99,9 +115,6 @@ Boston, MA 02111-1307, USA. */
|
||||
* Clean up afterwards generic SPARC ELF configuration.
|
||||
*/
|
||||
|
||||
#undef TRANSFER_FROM_TRAMPOLINE
|
||||
#define TRANSFER_FROM_TRAMPOLINE
|
||||
|
||||
/* FIXME: Aren't these supposed to be available for SPARC ELF? */
|
||||
#undef MULDI3_LIBCALL
|
||||
#undef DIVDI3_LIBCALL
|
||||
|
24
contrib/gcc/config/sparc/openbsd1-64.h
Normal file
24
contrib/gcc/config/sparc/openbsd1-64.h
Normal file
@ -0,0 +1,24 @@
|
||||
/* Configuration file for sparc64 OpenBSD target.
|
||||
Copyright (C) 1999 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GCC.
|
||||
|
||||
GCC is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
GCC is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GCC; see the file COPYING. If not, write to
|
||||
the Free Software Foundation, 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
#define OBSD_HAS_DECLARE_FUNCTION_NAME
|
||||
#define OBSD_HAS_DECLARE_FUNCTION_SIZE
|
||||
#define OBSD_HAS_DECLARE_OBJECT
|
||||
|
75
contrib/gcc/config/sparc/openbsd64.h
Normal file
75
contrib/gcc/config/sparc/openbsd64.h
Normal file
@ -0,0 +1,75 @@
|
||||
/* Configuration file for sparc64 OpenBSD target.
|
||||
Copyright (C) 1999 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GCC.
|
||||
|
||||
GCC is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
GCC is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GCC; see the file COPYING. If not, write to
|
||||
the Free Software Foundation, 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
#undef TARGET_VERSION
|
||||
#define TARGET_VERSION fprintf (stderr, " (sparc64 OpenBSD ELF)")
|
||||
|
||||
/* XXX - do we really want HARD_QUAD? */
|
||||
#undef TARGET_DEFAULT
|
||||
#define TARGET_DEFAULT \
|
||||
(MASK_V9 + MASK_PTR64 + MASK_64BIT + MASK_HARD_QUAD \
|
||||
+ MASK_APP_REGS + MASK_FPU + MASK_STACK_BIAS + MASK_LONG_DOUBLE_128)
|
||||
|
||||
#undef SPARC_DEFAULT_CMODEL
|
||||
#define SPARC_DEFAULT_CMODEL CM_MEDMID
|
||||
|
||||
/* Run-time target specifications. */
|
||||
#undef CPP_PREDEFINES
|
||||
#define CPP_PREDEFINES "-D__unix__ -D__sparc__ -D__sparc64__ -D__sparcv9__ -D__sparc_v9__ -D__arch64__ -D__ELF__ -D__OpenBSD__ -Asystem(unix) -Asystem(OpenBSD) -Acpu(sparc) -Amachine(sparc)"
|
||||
|
||||
#undef CPP_SUBTARGET_SPEC
|
||||
#define CPP_SUBTARGET_SPEC ""
|
||||
|
||||
#undef MD_EXEC_PREFIX
|
||||
#undef MD_STARTFILE_PREFIX
|
||||
|
||||
#undef ASM_SPEC
|
||||
#define ASM_SPEC "\
|
||||
%{v:-V} -s %{fpic:-K PIC} %{fPIC:-K PIC} \
|
||||
%{mlittle-endian:-EL} \
|
||||
%(asm_cpu) %(asm_arch) \
|
||||
"
|
||||
|
||||
/* Layout of source language data types. */
|
||||
#undef WCHAR_TYPE
|
||||
#define WCHAR_TYPE "int"
|
||||
|
||||
#undef WCHAR_TYPE_SIZE
|
||||
#define WCHAR_TYPE_SIZE 32
|
||||
|
||||
#undef LONG_DOUBLE_TYPE_SIZE
|
||||
#define LONG_DOUBLE_TYPE_SIZE 128
|
||||
|
||||
#undef LINK_SPEC
|
||||
#define LINK_SPEC \
|
||||
"%{!shared:%{!nostdlib:%{!r*:%{!e*:-e __start}}}} \
|
||||
%{shared:-shared} %{R*} \
|
||||
%{static:-Bstatic} \
|
||||
%{!static:-Bdynamic} \
|
||||
%{assert*} \
|
||||
%{!dynamic-linker:-dynamic-linker /usr/libexec/ld.so}"
|
||||
|
||||
/* As an elf system, we need crtbegin/crtend stuff. */
|
||||
#undef STARTFILE_SPEC
|
||||
#define STARTFILE_SPEC "\
|
||||
%{!shared: %{pg:gcrt0%O%s} %{!pg:%{p:gcrt0%O%s} %{!p:crt0%O%s}} \
|
||||
crtbegin%O%s} %{shared:crtbeginS%O%s}"
|
||||
#undef ENDFILE_SPEC
|
||||
#define ENDFILE_SPEC "%{!shared:crtend%O%s} %{shared:crtendS%O%s}"
|
@ -71,17 +71,21 @@ Boston, MA 02111-1307, USA. */
|
||||
|
||||
/* This is here rather than in sparc.h because it's not known what
|
||||
other assemblers will accept. */
|
||||
|
||||
#if TARGET_CPU_DEFAULT == TARGET_CPU_v9
|
||||
#undef ASM_CPU_DEFAULT_SPEC
|
||||
#define ASM_CPU_DEFAULT_SPEC "-xarch=v8plus"
|
||||
#endif
|
||||
|
||||
#if TARGET_CPU_DEFAULT == TARGET_CPU_ultrasparc
|
||||
#undef ASM_CPU_DEFAULT_SPEC
|
||||
#define ASM_CPU_DEFAULT_SPEC "-xarch=v8plusa"
|
||||
#endif
|
||||
|
||||
#undef ASM_CPU_SPEC
|
||||
#define ASM_CPU_SPEC "\
|
||||
%{mcpu=v8plus:-xarch=v8plus} \
|
||||
%{mcpu=v9:-xarch=v8plus} \
|
||||
%{mcpu=ultrasparc:-xarch=v8plusa} \
|
||||
%{!mcpu*:%(asm_cpu_default)} \
|
||||
"
|
||||
@ -227,6 +231,12 @@ Boston, MA 02111-1307, USA. */
|
||||
#define MODDI3_LIBCALL "__rem64"
|
||||
#define UMODDI3_LIBCALL "__urem64"
|
||||
|
||||
/* Solaris's _Qp_* library routine implementation clobbers the output
|
||||
memory before the inputs are fully consumed. */
|
||||
|
||||
#undef TARGET_BUGGY_QP_LIB
|
||||
#define TARGET_BUGGY_QP_LIB 1
|
||||
|
||||
#undef INIT_SUBTARGET_OPTABS
|
||||
#define INIT_SUBTARGET_OPTABS \
|
||||
fixsfdi_libfunc \
|
||||
|
@ -123,4 +123,6 @@ extern rtx gen_df_reg PARAMS ((rtx, int));
|
||||
extern int sparc_extra_constraint_check PARAMS ((rtx, int, int));
|
||||
#endif /* RTX_CODE */
|
||||
|
||||
extern void sparc_output_mi_thunk PARAMS ((FILE *, tree, HOST_WIDE_INT, tree));
|
||||
|
||||
#endif /* __SPARC_PROTOS_H__ */
|
||||
|
@ -2489,9 +2489,17 @@ emit_soft_tfmode_libcall (func_name, nargs, operands)
|
||||
/* TFmode arguments and return values are passed by reference. */
|
||||
if (GET_MODE (this_arg) == TFmode)
|
||||
{
|
||||
if (GET_CODE (this_arg) == MEM)
|
||||
int force_stack_temp;
|
||||
|
||||
force_stack_temp = 0;
|
||||
if (TARGET_BUGGY_QP_LIB && i == 0)
|
||||
force_stack_temp = 1;
|
||||
|
||||
if (GET_CODE (this_arg) == MEM
|
||||
&& ! force_stack_temp)
|
||||
this_arg = XEXP (this_arg, 0);
|
||||
else if (CONSTANT_P (this_arg))
|
||||
else if (CONSTANT_P (this_arg)
|
||||
&& ! force_stack_temp)
|
||||
{
|
||||
this_slot = force_const_mem (TFmode, this_arg);
|
||||
this_arg = XEXP (this_slot, 0);
|
||||
@ -8993,3 +9001,70 @@ sparc_extra_constraint_check (op, c, strict)
|
||||
|
||||
return reload_ok_mem;
|
||||
}
|
||||
|
||||
/* Output code to add DELTA to the first argument, and then jump to FUNCTION.
|
||||
Used for C++ multiple inheritance. */
|
||||
|
||||
void
|
||||
sparc_output_mi_thunk (file, thunk_fndecl, delta, function)
|
||||
FILE *file;
|
||||
tree thunk_fndecl ATTRIBUTE_UNUSED;
|
||||
HOST_WIDE_INT delta;
|
||||
tree function;
|
||||
{
|
||||
rtx this, insn, funexp, delta_rtx, tmp;
|
||||
|
||||
reload_completed = 1;
|
||||
no_new_pseudos = 1;
|
||||
current_function_uses_only_leaf_regs = 1;
|
||||
|
||||
emit_note (NULL, NOTE_INSN_PROLOGUE_END);
|
||||
|
||||
/* Find the "this" pointer. Normally in %o0, but in ARCH64 if the function
|
||||
returns a structure, the structure return pointer is there instead. */
|
||||
if (TARGET_ARCH64 && aggregate_value_p (TREE_TYPE (TREE_TYPE (function))))
|
||||
this = gen_rtx_REG (Pmode, SPARC_INCOMING_INT_ARG_FIRST + 1);
|
||||
else
|
||||
this = gen_rtx_REG (Pmode, SPARC_INCOMING_INT_ARG_FIRST);
|
||||
|
||||
/* Add DELTA. When possible use a plain add, otherwise load it into
|
||||
a register first. */
|
||||
delta_rtx = GEN_INT (delta);
|
||||
if (!SPARC_SIMM13_P (delta))
|
||||
{
|
||||
rtx scratch = gen_rtx_REG (Pmode, 1);
|
||||
if (TARGET_ARCH64)
|
||||
sparc_emit_set_const64 (scratch, delta_rtx);
|
||||
else
|
||||
sparc_emit_set_const32 (scratch, delta_rtx);
|
||||
delta_rtx = scratch;
|
||||
}
|
||||
|
||||
tmp = gen_rtx_PLUS (Pmode, this, delta_rtx);
|
||||
emit_insn (gen_rtx_SET (VOIDmode, this, tmp));
|
||||
|
||||
/* Generate a tail call to the target function. */
|
||||
if (! TREE_USED (function))
|
||||
{
|
||||
assemble_external (function);
|
||||
TREE_USED (function) = 1;
|
||||
}
|
||||
funexp = XEXP (DECL_RTL (function), 0);
|
||||
funexp = gen_rtx_MEM (FUNCTION_MODE, funexp);
|
||||
insn = emit_call_insn (gen_sibcall (funexp));
|
||||
SIBLING_CALL_P (insn) = 1;
|
||||
emit_barrier ();
|
||||
|
||||
/* Run just enough of rest_of_compilation to get the insns emitted.
|
||||
There's not really enough bulk here to make other passes such as
|
||||
instruction scheduling worth while. Note that use_thunk calls
|
||||
assemble_start_function and assemble_end_function. */
|
||||
insn = get_insns ();
|
||||
shorten_branches (insn);
|
||||
final_start_function (insn, file, 1);
|
||||
final (insn, file, 1, 0);
|
||||
final_end_function ();
|
||||
|
||||
reload_completed = 0;
|
||||
no_new_pseudos = 0;
|
||||
}
|
||||
|
@ -1414,6 +1414,8 @@ extern char leaf_reg_remap[];
|
||||
#define PREFERRED_RELOAD_CLASS(X,CLASS) \
|
||||
(CONSTANT_P (X) \
|
||||
? ((FP_REG_CLASS_P (CLASS) \
|
||||
|| (CLASS) == GENERAL_OR_FP_REGS \
|
||||
|| (CLASS) == GENERAL_OR_EXTRA_FP_REGS \
|
||||
|| (GET_MODE_CLASS (GET_MODE (X)) == MODE_FLOAT \
|
||||
&& ! TARGET_FPU) \
|
||||
|| (GET_MODE (X) == TFmode \
|
||||
@ -1958,7 +1960,8 @@ do { \
|
||||
return an rtx for the address of the word in the frame
|
||||
that holds the dynamic chain--the previous frame's address.
|
||||
??? -mflat support? */
|
||||
#define DYNAMIC_CHAIN_ADDRESS(frame) plus_constant (frame, 14 * UNITS_PER_WORD)
|
||||
#define DYNAMIC_CHAIN_ADDRESS(frame) \
|
||||
plus_constant (frame, 14 * UNITS_PER_WORD + SPARC_STACK_BIAS)
|
||||
|
||||
/* The return address isn't on the stack, it is in a register, so we can't
|
||||
access it from the current frame pointer. We can access it from the
|
||||
@ -2568,6 +2571,11 @@ do { \
|
||||
#define LTTF2_LIBCALL "_Q_flt"
|
||||
#define LETF2_LIBCALL "_Q_fle"
|
||||
|
||||
/* Assume by default that the _Qp_* 64-bit libcalls are implemented such
|
||||
that the inputs are fully consumed before the output memory is clobbered. */
|
||||
|
||||
#define TARGET_BUGGY_QP_LIB 0
|
||||
|
||||
/* We can define the TFmode sqrt optab only if TARGET_FPU. This is because
|
||||
with soft-float, the SFmode and DFmode sqrt instructions will be absent,
|
||||
and the compiler will notice and try to use the TFmode sqrt instruction
|
||||
@ -2604,6 +2612,17 @@ do { \
|
||||
sqrt_optab->handlers[(int) TFmode].libfunc \
|
||||
= init_one_libfunc ("_Q_sqrt"); \
|
||||
} \
|
||||
if (TARGET_ARCH64) \
|
||||
{ \
|
||||
/* In the SPARC 64bit ABI, these libfuncs do not exist in the \
|
||||
library. Make sure the compiler does not emit calls to them \
|
||||
by accident. */ \
|
||||
sdiv_optab->handlers[(int) SImode].libfunc = NULL; \
|
||||
udiv_optab->handlers[(int) SImode].libfunc = NULL; \
|
||||
smod_optab->handlers[(int) SImode].libfunc = NULL; \
|
||||
umod_optab->handlers[(int) SImode].libfunc = NULL; \
|
||||
smul_optab->handlers[(int) SImode].libfunc = NULL; \
|
||||
} \
|
||||
INIT_SUBTARGET_OPTABS; \
|
||||
} while (0)
|
||||
|
||||
@ -2903,24 +2922,8 @@ do { \
|
||||
|
||||
/* Output code to add DELTA to the first argument, and then jump to FUNCTION.
|
||||
Used for C++ multiple inheritance. */
|
||||
#define ASM_OUTPUT_MI_THUNK(FILE, THUNK_FNDECL, DELTA, FUNCTION) \
|
||||
do { \
|
||||
int reg = 0; \
|
||||
\
|
||||
if (TARGET_ARCH64 \
|
||||
&& aggregate_value_p (TREE_TYPE (TREE_TYPE (FUNCTION)))) \
|
||||
reg = 1; \
|
||||
if ((DELTA) >= 4096 || (DELTA) < -4096) \
|
||||
fprintf (FILE, "\tset\t%d, %%g1\n\tadd\t%%o%d, %%g1, %%o%d\n", \
|
||||
(int)(DELTA), reg, reg); \
|
||||
else \
|
||||
fprintf (FILE, "\tadd\t%%o%d, %d, %%o%d\n", reg, (int)(DELTA), reg);\
|
||||
fprintf (FILE, "\tor\t%%o7, %%g0, %%g1\n"); \
|
||||
fprintf (FILE, "\tcall\t"); \
|
||||
assemble_name (FILE, XSTR (XEXP (DECL_RTL (FUNCTION), 0), 0)); \
|
||||
fprintf (FILE, ", 0\n"); \
|
||||
fprintf (FILE, "\t or\t%%g1, %%g0, %%o7\n"); \
|
||||
} while (0)
|
||||
#define ASM_OUTPUT_MI_THUNK(FILE, THUNK_FNDECL, DELTA, FUNCTION) \
|
||||
sparc_output_mi_thunk (FILE, THUNK_FNDECL, DELTA, FUNCTION)
|
||||
|
||||
#define PRINT_OPERAND_PUNCT_VALID_P(CHAR) \
|
||||
((CHAR) == '#' || (CHAR) == '*' || (CHAR) == '^' || (CHAR) == '(' || (CHAR) == '_')
|
||||
|
@ -1,4 +1,4 @@
|
||||
EXTRA_PARTS += crtfastmath.o
|
||||
|
||||
crtfastmath.o: $(srcdir)/config/sparc/crtfastmath.c $(GCC_PASSES)
|
||||
$(GCC_FOR_TARGET) $(LIBGCC2_CFLAGS) -c -o crtfastmath.o $(srcdir)/config/sparc/crtfastmath.c
|
||||
$(T)crtfastmath.o: $(srcdir)/config/sparc/crtfastmath.c $(GCC_PASSES)
|
||||
$(GCC_FOR_TARGET) $(MULTILIB_CFLAGS) $(LIBGCC2_CFLAGS) -c -o $(T)crtfastmath.o $(srcdir)/config/sparc/crtfastmath.c
|
||||
|
@ -7,7 +7,8 @@ MULTILIB_EXCLUSIONS = m32/!m64/mno-app-regs m32/!m64/mcmodel=medany
|
||||
LIBGCC = stmp-multilib
|
||||
INSTALL_LIBGCC = install-multilib
|
||||
|
||||
EXTRA_MULTILIB_PARTS=crtbegin.o crtend.o crtbeginS.o crtendS.o crtbeginT.o
|
||||
EXTRA_MULTILIB_PARTS=crtbegin.o crtend.o crtbeginS.o crtendS.o crtbeginT.o \
|
||||
crtfastmath.o
|
||||
|
||||
SHLIB_SLIBDIR_SUFFIXES = 64:64 32:
|
||||
|
||||
|
@ -5,6 +5,7 @@ MULTILIB_MATCHES =
|
||||
LIBGCC = stmp-multilib
|
||||
INSTALL_LIBGCC = install-multilib
|
||||
|
||||
EXTRA_MULTILIB_PARTS=crtbegin.o crtend.o gmon.o crt1.o crti.o crtn.o gcrt1.o
|
||||
EXTRA_MULTILIB_PARTS=crtbegin.o crtend.o gmon.o crt1.o crti.o crtn.o gcrt1.o \
|
||||
crtfastmath.o
|
||||
|
||||
SHLIB_SLIBDIR_SUFFIXES = sparcv9:/sparcv9 sparcv7:
|
||||
|
@ -167,7 +167,7 @@ esac])
|
||||
|
||||
if test x${gcc_gxx_include_dir} = x; then
|
||||
if test x${enable_version_specific_runtime_libs} = xyes; then
|
||||
gcc_gxx_include_dir='${libsubdir}/include/g++'
|
||||
gcc_gxx_include_dir='${libsubdir}/include/c++'
|
||||
else
|
||||
topsrcdir=${srcdir}/.. . ${srcdir}/../config.if
|
||||
changequote(<<, >>)dnl
|
||||
@ -259,6 +259,18 @@ elif test x$withval != xno; then
|
||||
cpp_install_dir=$withval
|
||||
fi])
|
||||
|
||||
# Enable __cxa_atexit for C++.
|
||||
AC_ARG_ENABLE(__cxa_atexit,
|
||||
[ --enable-__cxa_atexit enable __cxa_atexit for C++],
|
||||
[], [])
|
||||
if test x$enable___cxa_atexit = xyes; then
|
||||
AC_DEFINE(DEFAULT_USE_CXA_ATEXIT, 1,
|
||||
[Define if you want to use __cxa_atexit, rather than atexit, to
|
||||
register C++ destructors for local statics and global objects.
|
||||
This is essential for fully standards-compliant handling of
|
||||
destructors, but requires __cxa_atexit in libc.])
|
||||
fi
|
||||
|
||||
# Enable Multibyte Characters for C/C++
|
||||
AC_ARG_ENABLE(c-mbchar,
|
||||
[ --enable-c-mbchar enable multibyte characters for C and C++],
|
||||
@ -1525,11 +1537,31 @@ elif test x$gcc_cv_as != x; then
|
||||
ld_ver=`$gcc_cv_ld --version 2>/dev/null | head -1`
|
||||
if echo "$ld_ver" | grep GNU > /dev/null; then
|
||||
changequote(,)dnl
|
||||
ld_vers=`echo $ld_ver | sed -n 's,^.*[ ]\([0-9][0-9]*\.[0-9][0-9]*\(\|\.[0-9][0-9]*\)\)\([ ].*\|\)$,\1,p'`
|
||||
ld_date=`echo $ld_ver | sed -n 's,^.*\([2-9][0-9][0-9][0-9]\)[-]*\([01][0-9]\)[-]*\([0-3][0-9]\).*$,\1\2\3,p'`
|
||||
changequote([,])dnl
|
||||
if test 0"$ld_date" -lt 20020404; then
|
||||
gcc_cv_as_hidden="no"
|
||||
if test -n "$ld_date"; then
|
||||
# If there was date string, but was earlier than 2002-04-04, fail
|
||||
gcc_cv_as_hidden="no"
|
||||
elif test -z "$ld_vers"; then
|
||||
# If there was no date string nor ld version number, something is wrong
|
||||
gcc_cv_as_hidden="no"
|
||||
else
|
||||
ld_vers_major=`expr "$ld_vers" : '\([0-9]*\)'`
|
||||
ld_vers_minor=`expr "$ld_vers" : '[0-9]*\.\([0-9]*\)'`
|
||||
ld_vers_patch=`expr "$ld_vers" : '[0-9]*\.[0-9]*\.\([0-9]*\)'`
|
||||
test -z "$ld_vers_patch" && ld_vers_patch=0
|
||||
if test "$ld_vers_major" -lt 2; then
|
||||
gcc_cv_as_hidden="no"
|
||||
elif test "$ld_vers_major" -eq 2 -a "$ld_vers_minor" -lt 12; then
|
||||
gcc_cv_as_hidden="no"
|
||||
elif test "$ld_vers_major" -eq 2 -a "$ld_vers_minor" -eq 12 \
|
||||
-a "$ld_vers_patch" -eq 0; then
|
||||
gcc_cv_as_hidden="no"
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
changequote([,])dnl
|
||||
fi
|
||||
fi
|
||||
|
||||
|
@ -227,9 +227,11 @@ convert_to_integer (type, expr)
|
||||
|
||||
case LSHIFT_EXPR:
|
||||
/* We can pass truncation down through left shifting
|
||||
when the shift count is a nonnegative constant. */
|
||||
when the shift count is a nonnegative constant and
|
||||
the target type is unsigned. */
|
||||
if (TREE_CODE (TREE_OPERAND (expr, 1)) == INTEGER_CST
|
||||
&& tree_int_cst_sgn (TREE_OPERAND (expr, 1)) >= 0
|
||||
&& TREE_UNSIGNED (type)
|
||||
&& TREE_CODE (TYPE_SIZE (type)) == INTEGER_CST)
|
||||
{
|
||||
/* If shift count is less than the width of the truncated type,
|
||||
@ -311,12 +313,15 @@ convert_to_integer (type, expr)
|
||||
/* Don't do unsigned arithmetic where signed was wanted,
|
||||
or vice versa.
|
||||
Exception: if both of the original operands were
|
||||
unsigned then can safely do the work as unsigned.
|
||||
unsigned then we can safely do the work as unsigned;
|
||||
if we are distributing through a LSHIFT_EXPR, we must
|
||||
do the work as unsigned to avoid a signed overflow.
|
||||
And we may need to do it as unsigned
|
||||
if we truncate to the original size. */
|
||||
typex = ((TREE_UNSIGNED (TREE_TYPE (expr))
|
||||
|| (TREE_UNSIGNED (TREE_TYPE (arg0))
|
||||
&& TREE_UNSIGNED (TREE_TYPE (arg1))))
|
||||
&& TREE_UNSIGNED (TREE_TYPE (arg1)))
|
||||
|| ex_form == LSHIFT_EXPR)
|
||||
? unsigned_type (typex) : signed_type (typex));
|
||||
return convert (type,
|
||||
fold (build (ex_form, typex,
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* Demangler for IA64 / g++ V3 ABI.
|
||||
Copyright (C) 2000, 2001 Free Software Foundation, Inc.
|
||||
Copyright (C) 2000, 2001, 2002 Free Software Foundation, Inc.
|
||||
Written by Alex Samuel <samuel@codesourcery.com>.
|
||||
|
||||
This file is part of GNU CC.
|
||||
@ -898,7 +898,7 @@ static status_t demangle_number_literally
|
||||
static status_t demangle_identifier
|
||||
PARAMS ((demangling_t, int, dyn_string_t));
|
||||
static status_t demangle_operator_name
|
||||
PARAMS ((demangling_t, int, int *));
|
||||
PARAMS ((demangling_t, int, int *, int *));
|
||||
static status_t demangle_nv_offset
|
||||
PARAMS ((demangling_t));
|
||||
static status_t demangle_v_offset
|
||||
@ -1325,7 +1325,7 @@ demangle_unqualified_name (dm, suppress_return_type)
|
||||
if (peek == 'c' && peek_char_next (dm) == 'v')
|
||||
*suppress_return_type = 1;
|
||||
|
||||
RETURN_IF_ERROR (demangle_operator_name (dm, 0, &num_args));
|
||||
RETURN_IF_ERROR (demangle_operator_name (dm, 0, &num_args, NULL));
|
||||
}
|
||||
else if (peek == 'C' || peek == 'D')
|
||||
{
|
||||
@ -1501,7 +1501,9 @@ demangle_identifier (dm, length, identifier)
|
||||
/* Demangles and emits an <operator-name>. If SHORT_NAME is non-zero,
|
||||
the short form is emitted; otherwise the full source form
|
||||
(`operator +' etc.) is emitted. *NUM_ARGS is set to the number of
|
||||
operands that the operator takes.
|
||||
operands that the operator takes. If TYPE_ARG is non-NULL,
|
||||
*TYPE_ARG is set to 1 if the first argument is a type and 0
|
||||
otherwise.
|
||||
|
||||
<operator-name>
|
||||
::= nw # new
|
||||
@ -1551,15 +1553,17 @@ demangle_identifier (dm, length, identifier)
|
||||
::= cl # ()
|
||||
::= ix # []
|
||||
::= qu # ?
|
||||
::= sz # sizeof
|
||||
::= st # sizeof (a type)
|
||||
::= sz # sizeof (an expression)
|
||||
::= cv <type> # cast
|
||||
::= v [0-9] <source-name> # vendor extended operator */
|
||||
|
||||
static status_t
|
||||
demangle_operator_name (dm, short_name, num_args)
|
||||
demangle_operator_name (dm, short_name, num_args, type_arg)
|
||||
demangling_t dm;
|
||||
int short_name;
|
||||
int *num_args;
|
||||
int *type_arg;
|
||||
{
|
||||
struct operator_code
|
||||
{
|
||||
@ -1633,6 +1637,10 @@ demangle_operator_name (dm, short_name, num_args)
|
||||
|
||||
DEMANGLE_TRACE ("operator-name", dm);
|
||||
|
||||
/* Assume the first argument is not a type. */
|
||||
if (type_arg)
|
||||
*type_arg = 0;
|
||||
|
||||
/* Is this a vendor-extended operator? */
|
||||
if (c0 == 'v' && IS_DIGIT (c1))
|
||||
{
|
||||
@ -1652,6 +1660,16 @@ demangle_operator_name (dm, short_name, num_args)
|
||||
return STATUS_OK;
|
||||
}
|
||||
|
||||
/* Is it the sizeof variant that takes a type? */
|
||||
if (c0 == 's' && c1 == 't')
|
||||
{
|
||||
RETURN_IF_ERROR (result_add (dm, " sizeof"));
|
||||
*num_args = 1;
|
||||
if (type_arg)
|
||||
*type_arg = 1;
|
||||
return STATUS_OK;
|
||||
}
|
||||
|
||||
/* Perform a binary search for the operator code. */
|
||||
while (1)
|
||||
{
|
||||
@ -3154,6 +3172,7 @@ demangle_expression (dm)
|
||||
/* An operator expression. */
|
||||
{
|
||||
int num_args;
|
||||
int type_arg;
|
||||
status_t status = STATUS_OK;
|
||||
dyn_string_t operator_name;
|
||||
|
||||
@ -3161,7 +3180,8 @@ demangle_expression (dm)
|
||||
operations in infix notation, capture the operator name
|
||||
first. */
|
||||
RETURN_IF_ERROR (result_push (dm));
|
||||
RETURN_IF_ERROR (demangle_operator_name (dm, 1, &num_args));
|
||||
RETURN_IF_ERROR (demangle_operator_name (dm, 1, &num_args,
|
||||
&type_arg));
|
||||
operator_name = (dyn_string_t) result_pop (dm);
|
||||
|
||||
/* If it's binary, do an operand first. */
|
||||
@ -3182,7 +3202,10 @@ demangle_expression (dm)
|
||||
|
||||
/* Emit its second (if binary) or only (if unary) operand. */
|
||||
RETURN_IF_ERROR (result_add_char (dm, '('));
|
||||
RETURN_IF_ERROR (demangle_expression (dm));
|
||||
if (type_arg)
|
||||
RETURN_IF_ERROR (demangle_type (dm));
|
||||
else
|
||||
RETURN_IF_ERROR (demangle_expression (dm));
|
||||
RETURN_IF_ERROR (result_add_char (dm, ')'));
|
||||
|
||||
/* The ternary operator takes a third operand. */
|
||||
|
@ -1,3 +1,269 @@
|
||||
2002-08-27 Mark Mitchell <mark@codesourcery.com>
|
||||
|
||||
* cp-tree.h (warn_abi): Declare it.
|
||||
* decl.c (warn_abi): Define it.
|
||||
(cxx_decode_option): Set it.
|
||||
* class.c (layout_virtual_bases): Warn about bugs in G++ that
|
||||
result in incorrect object layouts.
|
||||
(layout_class_type): Likewise.
|
||||
|
||||
2002-08-22 Jason Merrill <jason@redhat.com>
|
||||
|
||||
PR c++/5607
|
||||
* search.c (check_final_overrider): No longer static.
|
||||
* class.c (update_vtable_entry_for_fn): Call it.
|
||||
* cp-tree.h: Adjust.
|
||||
|
||||
* cp-lang.c (LANG_HOOKS_EXPR_SIZE): Define.
|
||||
(cp_expr_size): New fn.
|
||||
* call.c (convert_arg_to_ellipsis): Promote non-POD warning to error.
|
||||
* typeck.c (build_modify_expr): Don't use save_expr on an lvalue.
|
||||
|
||||
2002-08-14 Release Manager
|
||||
|
||||
* GCC 3.2 Released.
|
||||
|
||||
2002-08-03 Nathan Sidwell <nathan@codesourcery.com>
|
||||
|
||||
PR 7470.
|
||||
C++ ABI change - vfunc ordering.
|
||||
* class.c (add_virtual_function): Remove.
|
||||
(dfs_modify_all_vtables): Take list of all declared
|
||||
virtuals. Assign all that are not in primary base.
|
||||
(check_for_override): Adjust comments.
|
||||
(create_vtable_ptr): Take single list of virtuals. Build chain
|
||||
of declared virtuals here.
|
||||
(layout_class_type): Take single list of virtuals. Adjust.
|
||||
(finish_struct_1): Keep virtuals on single list. Adjust.
|
||||
|
||||
2002-07-30 Franz Sirl <Franz.Sirl-kernel@lauterbach.com>
|
||||
|
||||
* lang-specs.h: Remove __GXX_ABI_VERSION, moved to gcc.c.
|
||||
|
||||
2002-07-17 Scott Snyder <snyder@fnal.gov>
|
||||
|
||||
PR c++/7320
|
||||
* rtti.c (get_tinfo_decl): Set DECL_COMDAT.
|
||||
|
||||
2002-07-05 Nathan Sidwell <nathan@codesourcery.com>
|
||||
|
||||
Repair damage on weak-impared targets caused by my previous patch.
|
||||
* cp-tree.h (import_export_tinfo): Add parameter.
|
||||
* decl2.c (import_export_tinfo): Add parameter, post adjust
|
||||
DECL_COMDAT.
|
||||
* rtti.c (emit_tinfo_decl): DECL_COMDAT is (nearly) always setup by
|
||||
import_export_tinfo.
|
||||
|
||||
2002-06-30 Nathan Sidwell <nathan@codesourcery.com>
|
||||
|
||||
* cp-tree.h (CPTI_TINFO_DECL_TYPE): Replace with ...
|
||||
(CPTI_TYPE_INFO_PTR_TYPE): ... this.
|
||||
(tinfo_decl_type): Replace with ...
|
||||
(type_info_ptr_type): ... this.
|
||||
(import_export_tinfo): Declare.
|
||||
(tinfo_decl_p): Rename to ...
|
||||
(unemitted_tinfo_decl_p): ... this.
|
||||
* decl2.c (import_export_decl): Break out tinfo handling into ...
|
||||
(import_export_tinfo): ... here. New function.
|
||||
(finish_file): Adjust.
|
||||
* rtti.c (TINFO_REAL_NAME): New macro.
|
||||
(init_rtti_processing): Create the tinfo types.
|
||||
(get_tinfo_decl_dynamic): Use type_info_ptr_type, get_tinfo_ptr.
|
||||
(get_tinfo_decl): Adjust.
|
||||
(get_tinfo_ptr): New function.
|
||||
(get_type_id): Use it.
|
||||
(tinfo_base_init): Create vtable decl here, if it doesn't exist.
|
||||
(ptr_initializer): Use get_tinfo_ptr.
|
||||
(ptm_initializer): Likewise.
|
||||
(synthesize_tinfo_var): Break into ...
|
||||
(get_pseudo_ti_init): ... this. Just create the initializer.
|
||||
(get_pseudo_ti_desc): .. and this.
|
||||
(create_real_tinfo_var): Remove.
|
||||
(create_pseudo_type_info): Don't create the vtable decl here.
|
||||
(get_vmi_pseudo_type_info): Remove.
|
||||
(create_tinfo_types): Adjust.
|
||||
(tinfo_decl_p): Rename to ...
|
||||
(unemitted_tinfo_decl_p): ... here. Adjust.
|
||||
(emit_tinfo_decl): Adjust. Create the initializer.
|
||||
|
||||
2002-06-14 Jason Merrill <jason@redhat.com>
|
||||
|
||||
C++ ABI changes.
|
||||
* class.c (build_base_field): Set DECL_PACKED.
|
||||
(layout_class_type): Don't use tail padding of PODs.
|
||||
* mangle.c (write_unqualified_name): Fix template conversion op
|
||||
mangling.
|
||||
|
||||
2002-05-18 Jason Merrill <jason@redhat.com>
|
||||
|
||||
PR c++/6611
|
||||
* decl2.c (import_export_decl): If we clear
|
||||
DECL_NOT_REALLY_EXTERN, make sure DECL_EXTERNAL is set.
|
||||
|
||||
2002-05-14 Jason Merrill <jason@redhat.com>
|
||||
|
||||
* rtti.c (get_tinfo_decl): Don't call comdat_linkage.
|
||||
Do set DECL_COMDAT.
|
||||
(synthesize_tinfo_var): Take the public decl.
|
||||
(create_real_tinfo_var): Likewise. Check DECL_COMDAT.
|
||||
(emit_tinfo_decl): Adjust. Call import_export_decl.
|
||||
* decl2.c (import_export_decl): Simplify tinfo decl handling.
|
||||
|
||||
2002-07-25 Release Manager
|
||||
|
||||
* GCC 3.1.1 Released.
|
||||
|
||||
2002-07-12 Mark Mitchell <mark@codesourcery.com>
|
||||
|
||||
* class.c (add_method): Correct handling of conversion operators.
|
||||
|
||||
2002-07-11 Mark Mitchell <mark@codesourcery.com>
|
||||
|
||||
PR c++/7224
|
||||
* class.c (add_method): Simplify.
|
||||
|
||||
2002-07-11 Jason Merrill <jason@redhat.com>
|
||||
|
||||
PR c++/7279
|
||||
* tree.c (cp_copy_res_decl_for_inlining): Also copy
|
||||
TREE_ADDRESSABLE.
|
||||
|
||||
2002-07-10 Jason Merrill <jason@redhat.com>
|
||||
|
||||
PR c++/6255
|
||||
* decl.c (lookup_name_real): Build a new TYPENAME_TYPE rather than
|
||||
modifying the old one.
|
||||
|
||||
2002-07-08 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
|
||||
|
||||
* pt.c (can_complete_type_without_circularity): Add static to
|
||||
function definition.
|
||||
|
||||
2002-07-05 Jim Wilson <wilson@redhat.com>
|
||||
|
||||
* decl.c (mark_named_label_lists): Add missing & in call to
|
||||
mark_binding_level.
|
||||
|
||||
2002-07-05 Jason Merrill <jason@redhat.com>
|
||||
|
||||
* cvt.c (cp_convert_to_pointer): Call force_fit_type for null
|
||||
pointers.
|
||||
|
||||
PR optimization/7145
|
||||
* tree.c (cp_copy_res_decl_for_inlining): Also copy DECL_INITIAL.
|
||||
|
||||
2002-05-18 Jason Merrill <jason@redhat.com>
|
||||
|
||||
PR c++/6611
|
||||
* decl2.c (import_export_decl): If we clear
|
||||
DECL_NOT_REALLY_EXTERN, make sure DECL_EXTERNAL is set.
|
||||
|
||||
2002-07-03 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
|
||||
|
||||
PR c++/6944
|
||||
* init.c (build_aggr_init): Remove qualifiers of init before calling
|
||||
build_vec_init.
|
||||
(build_vec_init): Flatten multi-dimensional array during cleanup.
|
||||
(build_vec_delete_1): Abort if the type of each element is array.
|
||||
|
||||
2002-07-02 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
|
||||
|
||||
PR c++/6716
|
||||
* pt.c (can_complete_type_without_circularity): New function.
|
||||
(instantiate_class_template): Use it.
|
||||
* typeck2.c (incomplete_type_error): Improve error message
|
||||
due to incomplete fields.
|
||||
|
||||
2002-07-01 Mark Mitchell <mark@codesourcery.com>
|
||||
|
||||
PR c++/7112
|
||||
* mangle.c (write_expression): Add mangling for sizeof when
|
||||
applied to a type.
|
||||
* operators.def: Remove stale comment.
|
||||
|
||||
2002-06-27 Mark Mitchell <mark@codesourcery.com>
|
||||
|
||||
PR c++/6695
|
||||
* pt.c (tsubst_friend_class): Substitute into the context of the
|
||||
friend before using it.
|
||||
|
||||
2002-06-23 Matt Thomas <matt@3am-software.com>
|
||||
|
||||
* decl.c (finish_function): Change "#ifdef VMS_TARGET" to
|
||||
"#if VMS_TARGET".
|
||||
|
||||
2002-06-20 Richard Henderson <rth@redhat.com>
|
||||
|
||||
PR c++/6747
|
||||
* typeck.c (mark_addressable): Don't test TREE_ADDRESSABLE early.
|
||||
Call put_var_into_stack.
|
||||
|
||||
2002-06-20 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
|
||||
|
||||
PR c++/6892
|
||||
* pt.c (tsubst_expr): Handle FILE_STMT.
|
||||
|
||||
2002-06-20 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
|
||||
|
||||
PR c++/6723
|
||||
* pt.c (lookup_template_class): Don't build complete argument of
|
||||
BOUND_TEMPLATE_TEMPLATE_PARM if appeared as a default template
|
||||
argument.
|
||||
|
||||
2002-06-16 Richard Henderson <rth@redhat.com>
|
||||
|
||||
PR opt/6793
|
||||
* tree.c (cp_cannot_inline_tree_fn): Don't short-circuit test
|
||||
after template instantiation.
|
||||
|
||||
2002-06-07 H.J. Lu (hjl@gnu.org)
|
||||
|
||||
* decl2.c (flag_use_cxa_atexit): Set to DEFAULT_USE_CXA_ATEXIT.
|
||||
|
||||
2002-05-23 Neil Booth <neil@daikokuya.demon.co.uk>
|
||||
|
||||
* cp-lang.c (LANG_HOOKS_POST_OPTIONS): Use c_common_post_options.
|
||||
* cp-tree.h (cxx_post_options): Kill.
|
||||
* cp-lex.c (cxx_post_options): Kill.
|
||||
|
||||
2002-05-19 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
|
||||
|
||||
* error.c (dump_type) [TYPEOF_TYPE]: Fix parenthesis printing.
|
||||
|
||||
2002-05-19 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
|
||||
|
||||
PR c++/186, DR 259
|
||||
* pt.c (do_decl_instantiation): Don't complain explicit
|
||||
instantiation after explicit specialization.
|
||||
(do_type_instantiation): Likewise.
|
||||
|
||||
2002-05-09 Jason Merrill <jason@redhat.com>
|
||||
|
||||
* pt.c (tsubst_expr) [ASM_STMT]: Copy ASM_INPUT_P.
|
||||
|
||||
2002-05-15 Alexandre Oliva <aoliva@redhat.com>
|
||||
|
||||
* cp-tree.h (struct lang_type): Added non_zero_init.
|
||||
(CLASSTYPE_NON_ZERO_INIT_P): New macro.
|
||||
(zero_init_p, force_store_init_value, build_forced_zero_init): Declare.
|
||||
* class.c (check_field_decls): Test non_zero_init.
|
||||
* cvt.c (convert_to_pointer_force): Use cp_convert_to_pointer for
|
||||
zero-to-NULL conversions.
|
||||
* decl.c (obscure_complex_init): Don't reset DECL_INITIAL of a
|
||||
type that needs zero-initialization without zeros.
|
||||
(check_initializer_decl): Compute zero-initializer for types
|
||||
that require a non-trivial one.
|
||||
* init.c (build_forced_zero_init): New function.
|
||||
(build_default_init): Use it.
|
||||
* tree.c (zero_init_p): New function.
|
||||
* typeck2.c (force_store_init_value): New function.
|
||||
(process_init_constructor): Create non-trivial zero-initializers
|
||||
for array members and class fields.
|
||||
|
||||
2002-05-14 Release Manager
|
||||
|
||||
* GCC 3.1 Released.
|
||||
|
||||
2002-05-03 Jason Merrill <jason@redhat.com>
|
||||
|
||||
* decl.c (BOOL_TYPE_SIZE): Move default to defaults.h.
|
||||
@ -26,6 +292,7 @@
|
||||
|
||||
2002-04-30 Jason Merrill <jason@redhat.com>
|
||||
|
||||
PR debug/6436
|
||||
* decl.c (grokdeclarator): Don't override TYPE_NAME of an
|
||||
anonymous class with a typedef if there are attributes.
|
||||
|
||||
@ -163,12 +430,12 @@
|
||||
|
||||
2002-04-11 Andrew Haley <aph@redhat.com>
|
||||
|
||||
* typeck.c (type_after_usual_arithmetic_conversions):
|
||||
If two types have the same variant, return immediately.
|
||||
When two floating-point operands are the same precision:
|
||||
convert to float if one of the operands is float;
|
||||
if neither operand is one of the standard types, return the type
|
||||
of the first operand.
|
||||
* typeck.c (type_after_usual_arithmetic_conversions):
|
||||
If two types have the same variant, return immediately.
|
||||
When two floating-point operands are the same precision:
|
||||
convert to float if one of the operands is float;
|
||||
if neither operand is one of the standard types, return the type
|
||||
of the first operand.
|
||||
|
||||
2002-04-12 Richard Sandiford <rsandifo@redhat.com>
|
||||
|
||||
|
@ -251,7 +251,7 @@ cp/spew.o: cp/spew.c $(CXX_TREE_H) cp/parse.h flags.h cp/lex.h toplev.h
|
||||
cp/lex.o: cp/lex.c $(CXX_TREE_H) cp/parse.h flags.h cp/lex.h c-pragma.h \
|
||||
toplev.h output.h mbchar.h $(GGC_H) input.h diagnostic.h cp/operators.def \
|
||||
$(TM_P_H)
|
||||
cp/cp-lang.o: cp/cp-lang.c $(CXX_TREE_H) toplev.h langhooks.h langhooks-def.h \
|
||||
cp/cp-lang.o: cp/cp-lang.c $(CXX_TREE_H) toplev.h langhooks.h $(LANGHOOKS_DEF_H) \
|
||||
c-common.h
|
||||
cp/decl.o: cp/decl.c $(CXX_TREE_H) flags.h cp/lex.h cp/decl.h stack.h \
|
||||
output.h $(EXPR_H) except.h toplev.h hash.h $(GGC_H) $(RTL_H) \
|
||||
|
@ -4022,9 +4022,12 @@ convert_arg_to_ellipsis (arg)
|
||||
|
||||
if (arg != error_mark_node && ! pod_type_p (TREE_TYPE (arg)))
|
||||
{
|
||||
/* Undefined behaviour [expr.call] 5.2.2/7. */
|
||||
warning ("cannot pass objects of non-POD type `%#T' through `...'",
|
||||
TREE_TYPE (arg));
|
||||
/* Undefined behaviour [expr.call] 5.2.2/7. We used to just warn
|
||||
here and do a bitwise copy, but now cp_expr_size will abort if we
|
||||
try to do that. */
|
||||
error ("cannot pass objects of non-POD type `%#T' through `...'",
|
||||
TREE_TYPE (arg));
|
||||
arg = error_mark_node;
|
||||
}
|
||||
|
||||
return arg;
|
||||
|
@ -114,7 +114,6 @@ static int build_primary_vtable PARAMS ((tree, tree));
|
||||
static int build_secondary_vtable PARAMS ((tree, tree));
|
||||
static void finish_vtbls PARAMS ((tree));
|
||||
static void modify_vtable_entry PARAMS ((tree, tree, tree, tree, tree *));
|
||||
static void add_virtual_function PARAMS ((tree *, tree *, int *, tree, tree));
|
||||
static tree delete_duplicate_fields_1 PARAMS ((tree, tree));
|
||||
static void delete_duplicate_fields PARAMS ((tree));
|
||||
static void finish_struct_bits PARAMS ((tree));
|
||||
@ -150,8 +149,8 @@ static void check_methods PARAMS ((tree));
|
||||
static void remove_zero_width_bit_fields PARAMS ((tree));
|
||||
static void check_bases PARAMS ((tree, int *, int *, int *));
|
||||
static void check_bases_and_members PARAMS ((tree, int *));
|
||||
static tree create_vtable_ptr PARAMS ((tree, int *, int *, tree *, tree *));
|
||||
static void layout_class_type PARAMS ((tree, int *, int *, tree *, tree *));
|
||||
static tree create_vtable_ptr PARAMS ((tree, int *, int *, tree *));
|
||||
static void layout_class_type PARAMS ((tree, int *, int *, tree *));
|
||||
static void fixup_pending_inline PARAMS ((tree));
|
||||
static void fixup_inline_methods PARAMS ((tree));
|
||||
static void set_primary_base PARAMS ((tree, tree, int *));
|
||||
@ -792,61 +791,6 @@ set_vindex (decl, vfuns_p)
|
||||
? TARGET_VTABLE_USES_DESCRIPTORS : 1);
|
||||
DECL_VINDEX (decl) = build_shared_int_cst (vindex);
|
||||
}
|
||||
|
||||
/* Add a virtual function to all the appropriate vtables for the class
|
||||
T. DECL_VINDEX(X) should be error_mark_node, if we want to
|
||||
allocate a new slot in our table. If it is error_mark_node, we
|
||||
know that no other function from another vtable is overridden by X.
|
||||
VFUNS_P keeps track of how many virtuals there are in our
|
||||
main vtable for the type, and we build upon the NEW_VIRTUALS list
|
||||
and return it. */
|
||||
|
||||
static void
|
||||
add_virtual_function (new_virtuals_p, overridden_virtuals_p,
|
||||
vfuns_p, fndecl, t)
|
||||
tree *new_virtuals_p;
|
||||
tree *overridden_virtuals_p;
|
||||
int *vfuns_p;
|
||||
tree fndecl;
|
||||
tree t; /* Structure type. */
|
||||
{
|
||||
tree new_virtual;
|
||||
|
||||
/* If this function doesn't override anything from a base class, we
|
||||
can just assign it a new DECL_VINDEX now. Otherwise, if it does
|
||||
override something, we keep it around and assign its DECL_VINDEX
|
||||
later, in modify_all_vtables. */
|
||||
if (TREE_CODE (DECL_VINDEX (fndecl)) == INTEGER_CST)
|
||||
/* We've already dealt with this function. */
|
||||
return;
|
||||
|
||||
new_virtual = make_node (TREE_LIST);
|
||||
BV_FN (new_virtual) = fndecl;
|
||||
BV_DELTA (new_virtual) = integer_zero_node;
|
||||
|
||||
if (DECL_VINDEX (fndecl) == error_mark_node)
|
||||
{
|
||||
/* FNDECL is a new virtual function; it doesn't override any
|
||||
virtual function in a base class. */
|
||||
|
||||
/* We remember that this was the base sub-object for rtti. */
|
||||
CLASSTYPE_RTTI (t) = t;
|
||||
|
||||
/* Now assign virtual dispatch information. */
|
||||
set_vindex (fndecl, vfuns_p);
|
||||
DECL_VIRTUAL_CONTEXT (fndecl) = t;
|
||||
|
||||
/* Save the state we've computed on the NEW_VIRTUALS list. */
|
||||
TREE_CHAIN (new_virtual) = *new_virtuals_p;
|
||||
*new_virtuals_p = new_virtual;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* FNDECL overrides a function from a base class. */
|
||||
TREE_CHAIN (new_virtual) = *overridden_virtuals_p;
|
||||
*overridden_virtuals_p = new_virtual;
|
||||
}
|
||||
}
|
||||
|
||||
/* Add method METHOD to class TYPE. If ERROR_P is true, we are adding
|
||||
the method after the class has already been defined because a
|
||||
@ -973,69 +917,60 @@ add_method (type, method, error_p)
|
||||
fns = OVL_NEXT (fns))
|
||||
{
|
||||
tree fn = OVL_CURRENT (fns);
|
||||
|
||||
tree parms1;
|
||||
tree parms2;
|
||||
bool same = 1;
|
||||
|
||||
if (TREE_CODE (fn) != TREE_CODE (method))
|
||||
continue;
|
||||
|
||||
if (TREE_CODE (method) != TEMPLATE_DECL)
|
||||
/* [over.load] Member function declarations with the
|
||||
same name and the same parameter types cannot be
|
||||
overloaded if any of them is a static member
|
||||
function declaration.
|
||||
|
||||
[namespace.udecl] When a using-declaration brings names
|
||||
from a base class into a derived class scope, member
|
||||
functions in the derived class override and/or hide member
|
||||
functions with the same name and parameter types in a base
|
||||
class (rather than conflicting). */
|
||||
parms1 = TYPE_ARG_TYPES (TREE_TYPE (fn));
|
||||
parms2 = TYPE_ARG_TYPES (TREE_TYPE (method));
|
||||
|
||||
/* Compare the quals on the 'this' parm. Don't compare
|
||||
the whole types, as used functions are treated as
|
||||
coming from the using class in overload resolution. */
|
||||
if (! DECL_STATIC_FUNCTION_P (fn)
|
||||
&& ! DECL_STATIC_FUNCTION_P (method)
|
||||
&& (TYPE_QUALS (TREE_TYPE (TREE_VALUE (parms1)))
|
||||
!= TYPE_QUALS (TREE_TYPE (TREE_VALUE (parms2)))))
|
||||
same = 0;
|
||||
if (! DECL_STATIC_FUNCTION_P (fn))
|
||||
parms1 = TREE_CHAIN (parms1);
|
||||
if (! DECL_STATIC_FUNCTION_P (method))
|
||||
parms2 = TREE_CHAIN (parms2);
|
||||
|
||||
if (same && compparms (parms1, parms2)
|
||||
&& (!DECL_CONV_FN_P (fn)
|
||||
|| same_type_p (TREE_TYPE (TREE_TYPE (fn)),
|
||||
TREE_TYPE (TREE_TYPE (method)))))
|
||||
{
|
||||
/* [over.load] Member function declarations with the
|
||||
same name and the same parameter types cannot be
|
||||
overloaded if any of them is a static member
|
||||
function declaration.
|
||||
|
||||
[namespace.udecl] When a using-declaration brings names
|
||||
from a base class into a derived class scope, member
|
||||
functions in the derived class override and/or hide member
|
||||
functions with the same name and parameter types in a base
|
||||
class (rather than conflicting). */
|
||||
if ((DECL_STATIC_FUNCTION_P (fn)
|
||||
!= DECL_STATIC_FUNCTION_P (method))
|
||||
|| using)
|
||||
if (using && DECL_CONTEXT (fn) == type)
|
||||
/* Defer to the local function. */
|
||||
return;
|
||||
else
|
||||
{
|
||||
tree parms1 = TYPE_ARG_TYPES (TREE_TYPE (fn));
|
||||
tree parms2 = TYPE_ARG_TYPES (TREE_TYPE (method));
|
||||
int same = 1;
|
||||
cp_error_at ("`%#D' and `%#D' cannot be overloaded",
|
||||
method, fn, method);
|
||||
|
||||
/* Compare the quals on the 'this' parm. Don't compare
|
||||
the whole types, as used functions are treated as
|
||||
coming from the using class in overload resolution. */
|
||||
if (using
|
||||
&& ! DECL_STATIC_FUNCTION_P (fn)
|
||||
&& ! DECL_STATIC_FUNCTION_P (method)
|
||||
&& (TYPE_QUALS (TREE_TYPE (TREE_VALUE (parms1)))
|
||||
!= TYPE_QUALS (TREE_TYPE (TREE_VALUE (parms2)))))
|
||||
same = 0;
|
||||
if (! DECL_STATIC_FUNCTION_P (fn))
|
||||
parms1 = TREE_CHAIN (parms1);
|
||||
if (! DECL_STATIC_FUNCTION_P (method))
|
||||
parms2 = TREE_CHAIN (parms2);
|
||||
|
||||
if (same && compparms (parms1, parms2))
|
||||
{
|
||||
if (using && DECL_CONTEXT (fn) == type)
|
||||
/* Defer to the local function. */
|
||||
return;
|
||||
else
|
||||
error ("`%#D' and `%#D' cannot be overloaded",
|
||||
fn, method);
|
||||
}
|
||||
/* We don't call duplicate_decls here to merge
|
||||
the declarations because that will confuse
|
||||
things if the methods have inline
|
||||
definitions. In particular, we will crash
|
||||
while processing the definitions. */
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (!decls_match (fn, method))
|
||||
continue;
|
||||
|
||||
/* There has already been a declaration of this method
|
||||
or member template. */
|
||||
cp_error_at ("`%D' has already been declared in `%T'",
|
||||
method, type);
|
||||
|
||||
/* We don't call duplicate_decls here to merge the
|
||||
declarations because that will confuse things if the
|
||||
methods have inline definitions. In particular, we
|
||||
will crash while processing the definitions. */
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
@ -2519,6 +2454,10 @@ update_vtable_entry_for_fn (t, binfo, fn, virtuals)
|
||||
if (overrider == error_mark_node)
|
||||
return;
|
||||
|
||||
/* Check for unsupported covariant returns again now that we've
|
||||
calculated the base offsets. */
|
||||
check_final_overrider (TREE_PURPOSE (overrider), fn);
|
||||
|
||||
/* Assume that we will produce a thunk that convert all the way to
|
||||
the final overrider, and not to an intermediate virtual base. */
|
||||
virtual_base = NULL_TREE;
|
||||
@ -2641,18 +2580,18 @@ dfs_modify_vtables (binfo, data)
|
||||
|
||||
/* Update all of the primary and secondary vtables for T. Create new
|
||||
vtables as required, and initialize their RTTI information. Each
|
||||
of the functions in OVERRIDDEN_VIRTUALS overrides a virtual
|
||||
function from a base class; find and modify the appropriate entries
|
||||
to point to the overriding functions. Returns a list, in
|
||||
declaration order, of the functions that are overridden in this
|
||||
class, but do not appear in the primary base class vtable, and
|
||||
which should therefore be appended to the end of the vtable for T. */
|
||||
of the functions in VIRTUALS is declared in T and may override a
|
||||
virtual function from a base class; find and modify the appropriate
|
||||
entries to point to the overriding functions. Returns a list, in
|
||||
declaration order, of the virtual functions that are declared in T,
|
||||
but do not appear in the primary base class vtable, and which
|
||||
should therefore be appended to the end of the vtable for T. */
|
||||
|
||||
static tree
|
||||
modify_all_vtables (t, vfuns_p, overridden_virtuals)
|
||||
modify_all_vtables (t, vfuns_p, virtuals)
|
||||
tree t;
|
||||
int *vfuns_p;
|
||||
tree overridden_virtuals;
|
||||
tree virtuals;
|
||||
{
|
||||
tree binfo = TYPE_BINFO (t);
|
||||
tree *fnsp;
|
||||
@ -2664,14 +2603,16 @@ modify_all_vtables (t, vfuns_p, overridden_virtuals)
|
||||
t);
|
||||
dfs_walk (binfo, dfs_unmark, dfs_marked_real_bases_queue_p, t);
|
||||
|
||||
/* Include overriding functions for secondary vtables in our primary
|
||||
vtable. */
|
||||
for (fnsp = &overridden_virtuals; *fnsp; )
|
||||
/* Add virtual functions not already in our primary vtable. These
|
||||
will be both those introduced by this class, and those overridden
|
||||
from secondary bases. It does not include virtuals merely
|
||||
inherited from secondary bases. */
|
||||
for (fnsp = &virtuals; *fnsp; )
|
||||
{
|
||||
tree fn = TREE_VALUE (*fnsp);
|
||||
|
||||
if (!BINFO_VIRTUALS (binfo)
|
||||
|| !value_member (fn, BINFO_VIRTUALS (binfo)))
|
||||
if (!value_member (fn, BINFO_VIRTUALS (binfo))
|
||||
|| DECL_VINDEX (fn) == error_mark_node)
|
||||
{
|
||||
/* Set the vtable index. */
|
||||
set_vindex (fn, vfuns_p);
|
||||
@ -2684,8 +2625,7 @@ modify_all_vtables (t, vfuns_p, overridden_virtuals)
|
||||
BV_DELTA (*fnsp) = integer_zero_node;
|
||||
BV_VCALL_INDEX (*fnsp) = NULL_TREE;
|
||||
|
||||
/* This is an overridden function not already in our
|
||||
vtable. Keep it. */
|
||||
/* This is a function not already in our vtable. Keep it. */
|
||||
fnsp = &TREE_CHAIN (*fnsp);
|
||||
}
|
||||
else
|
||||
@ -2693,7 +2633,7 @@ modify_all_vtables (t, vfuns_p, overridden_virtuals)
|
||||
*fnsp = TREE_CHAIN (*fnsp);
|
||||
}
|
||||
|
||||
return overridden_virtuals;
|
||||
return virtuals;
|
||||
}
|
||||
|
||||
/* Here, we already know that they match in every respect.
|
||||
@ -2763,16 +2703,14 @@ check_for_override (decl, ctype)
|
||||
|| IDENTIFIER_VIRTUAL_P (DECL_NAME (decl)))
|
||||
&& look_for_overrides (ctype, decl)
|
||||
&& !DECL_STATIC_FUNCTION_P (decl))
|
||||
{
|
||||
/* Set DECL_VINDEX to a value that is neither an
|
||||
INTEGER_CST nor the error_mark_node so that
|
||||
add_virtual_function will realize this is an
|
||||
overriding function. */
|
||||
DECL_VINDEX (decl) = decl;
|
||||
}
|
||||
/* Set DECL_VINDEX to a value that is neither an INTEGER_CST nor
|
||||
the error_mark_node so that we know it is an overriding
|
||||
function. */
|
||||
DECL_VINDEX (decl) = decl;
|
||||
|
||||
if (DECL_VIRTUAL_P (decl))
|
||||
{
|
||||
if (DECL_VINDEX (decl) == NULL_TREE)
|
||||
if (!DECL_VINDEX (decl))
|
||||
DECL_VINDEX (decl) = error_mark_node;
|
||||
IDENTIFIER_VIRTUAL_P (DECL_NAME (decl)) = 1;
|
||||
}
|
||||
@ -3410,6 +3348,9 @@ check_field_decls (t, access_decls, empty_p,
|
||||
to be allowed in POD structs. */
|
||||
CLASSTYPE_NON_POD_P (t) = 1;
|
||||
|
||||
if (! zero_init_p (type))
|
||||
CLASSTYPE_NON_ZERO_INIT_P (t) = 1;
|
||||
|
||||
/* If any field is const, the structure type is pseudo-const. */
|
||||
if (CP_TYPE_CONST_P (type))
|
||||
{
|
||||
@ -3836,6 +3777,8 @@ build_base_field (rli, binfo, empty_p, offsets, t)
|
||||
DECL_SIZE_UNIT (decl) = CLASSTYPE_SIZE_UNIT (basetype);
|
||||
DECL_ALIGN (decl) = CLASSTYPE_ALIGN (basetype);
|
||||
DECL_USER_ALIGN (decl) = CLASSTYPE_USER_ALIGN (basetype);
|
||||
/* Tell the backend not to round up to TYPE_ALIGN. */
|
||||
DECL_PACKED (decl) = 1;
|
||||
|
||||
if (!integer_zerop (DECL_SIZE (decl)))
|
||||
{
|
||||
@ -4389,31 +4332,37 @@ check_bases_and_members (t, empty_p)
|
||||
accordingly. If a new vfield was created (because T doesn't have a
|
||||
primary base class), then the newly created field is returned. It
|
||||
is not added to the TYPE_FIELDS list; it is the caller's
|
||||
responsibility to do that. */
|
||||
responsibility to do that. Accumulate declared virtual functions
|
||||
on VIRTUALS_P. */
|
||||
|
||||
static tree
|
||||
create_vtable_ptr (t, empty_p, vfuns_p,
|
||||
new_virtuals_p, overridden_virtuals_p)
|
||||
create_vtable_ptr (t, empty_p, vfuns_p, virtuals_p)
|
||||
tree t;
|
||||
int *empty_p;
|
||||
int *vfuns_p;
|
||||
tree *new_virtuals_p;
|
||||
tree *overridden_virtuals_p;
|
||||
tree *virtuals_p;
|
||||
{
|
||||
tree fn;
|
||||
|
||||
/* Loop over the virtual functions, adding them to our various
|
||||
vtables. */
|
||||
/* Collect the virtual functions declared in T. */
|
||||
for (fn = TYPE_METHODS (t); fn; fn = TREE_CHAIN (fn))
|
||||
if (DECL_VINDEX (fn) && !DECL_MAYBE_IN_CHARGE_DESTRUCTOR_P (fn))
|
||||
add_virtual_function (new_virtuals_p, overridden_virtuals_p,
|
||||
vfuns_p, fn, t);
|
||||
if (DECL_VINDEX (fn) && !DECL_MAYBE_IN_CHARGE_DESTRUCTOR_P (fn)
|
||||
&& TREE_CODE (DECL_VINDEX (fn)) != INTEGER_CST)
|
||||
{
|
||||
tree new_virtual = make_node (TREE_LIST);
|
||||
|
||||
BV_FN (new_virtual) = fn;
|
||||
BV_DELTA (new_virtual) = integer_zero_node;
|
||||
|
||||
TREE_CHAIN (new_virtual) = *virtuals_p;
|
||||
*virtuals_p = new_virtual;
|
||||
}
|
||||
|
||||
/* If we couldn't find an appropriate base class, create a new field
|
||||
here. Even if there weren't any new virtual functions, we might need a
|
||||
new virtual function table if we're supposed to include vptrs in
|
||||
all classes that need them. */
|
||||
if (!TYPE_VFIELD (t) && (*vfuns_p || TYPE_CONTAINS_VPTR_P (t)))
|
||||
if (!TYPE_VFIELD (t) && (*virtuals_p || TYPE_CONTAINS_VPTR_P (t)))
|
||||
{
|
||||
/* We build this decl with vtbl_ptr_type_node, which is a
|
||||
`vtable_entry_type*'. It might seem more precise to use
|
||||
@ -4608,6 +4557,7 @@ layout_virtual_bases (t, offsets)
|
||||
{
|
||||
tree vbases, dsize;
|
||||
unsigned HOST_WIDE_INT eoc;
|
||||
bool first_vbase = true;
|
||||
|
||||
if (CLASSTYPE_N_BASECLASSES (t) == 0)
|
||||
return;
|
||||
@ -4635,6 +4585,7 @@ layout_virtual_bases (t, offsets)
|
||||
|
||||
if (!TREE_VIA_VIRTUAL (vbases))
|
||||
continue;
|
||||
|
||||
vbase = binfo_for_vbase (BINFO_TYPE (vbases), t);
|
||||
|
||||
if (!BINFO_PRIMARY_P (vbase))
|
||||
@ -4652,7 +4603,6 @@ layout_virtual_bases (t, offsets)
|
||||
/* Add padding so that we can put the virtual base class at an
|
||||
appropriately aligned offset. */
|
||||
dsize = round_up (dsize, desired_align);
|
||||
|
||||
usize = size_binop (CEIL_DIV_EXPR, dsize, bitsize_unit_node);
|
||||
|
||||
/* We try to squish empty virtual bases in just like
|
||||
@ -4680,11 +4630,30 @@ layout_virtual_bases (t, offsets)
|
||||
CLASSTYPE_SIZE (basetype)));
|
||||
}
|
||||
|
||||
/* If the first virtual base might have been placed at a
|
||||
lower address, had we started from CLASSTYPE_SIZE, rather
|
||||
than TYPE_SIZE, issue a warning. There can be both false
|
||||
positives and false negatives from this warning in rare
|
||||
cases; to deal with all the possibilities would probably
|
||||
require performing both layout algorithms and comparing
|
||||
the results which is not particularly tractable. */
|
||||
if (warn_abi
|
||||
&& first_vbase
|
||||
&& tree_int_cst_lt (size_binop (CEIL_DIV_EXPR,
|
||||
round_up (CLASSTYPE_SIZE (t),
|
||||
desired_align),
|
||||
bitsize_unit_node),
|
||||
BINFO_OFFSET (vbase)))
|
||||
warning ("offset of virtual base `%T' is not ABI-compliant and may change in a future version of GCC",
|
||||
basetype);
|
||||
|
||||
/* Keep track of the offsets assigned to this virtual base. */
|
||||
record_subobject_offsets (BINFO_TYPE (vbase),
|
||||
BINFO_OFFSET (vbase),
|
||||
offsets,
|
||||
/*vbases_p=*/0);
|
||||
|
||||
first_vbase = false;
|
||||
}
|
||||
}
|
||||
|
||||
@ -4805,16 +4774,14 @@ splay_tree_compare_integer_csts (k1, k2)
|
||||
|
||||
/* Calculate the TYPE_SIZE, TYPE_ALIGN, etc for T. Calculate
|
||||
BINFO_OFFSETs for all of the base-classes. Position the vtable
|
||||
pointer. */
|
||||
pointer. Accumulate declared virtual functions on VIRTUALS_P. */
|
||||
|
||||
static void
|
||||
layout_class_type (t, empty_p, vfuns_p,
|
||||
new_virtuals_p, overridden_virtuals_p)
|
||||
layout_class_type (t, empty_p, vfuns_p, virtuals_p)
|
||||
tree t;
|
||||
int *empty_p;
|
||||
int *vfuns_p;
|
||||
tree *new_virtuals_p;
|
||||
tree *overridden_virtuals_p;
|
||||
tree *virtuals_p;
|
||||
{
|
||||
tree non_static_data_members;
|
||||
tree field;
|
||||
@ -4824,6 +4791,8 @@ layout_class_type (t, empty_p, vfuns_p,
|
||||
/* Maps offsets (represented as INTEGER_CSTs) to a TREE_LIST of
|
||||
types that appear at that offset. */
|
||||
splay_tree empty_base_offsets;
|
||||
/* True if the last field layed out was a bit-field. */
|
||||
bool last_field_was_bitfield = false;
|
||||
|
||||
/* Keep track of the first non-static data member. */
|
||||
non_static_data_members = TYPE_FIELDS (t);
|
||||
@ -4836,8 +4805,7 @@ layout_class_type (t, empty_p, vfuns_p,
|
||||
determine_primary_base (t, vfuns_p);
|
||||
|
||||
/* Create a pointer to our virtual function table. */
|
||||
vptr = create_vtable_ptr (t, empty_p, vfuns_p,
|
||||
new_virtuals_p, overridden_virtuals_p);
|
||||
vptr = create_vtable_ptr (t, empty_p, vfuns_p, virtuals_p);
|
||||
|
||||
/* The vptr is always the first thing in the class. */
|
||||
if (vptr)
|
||||
@ -4914,6 +4882,18 @@ layout_class_type (t, empty_p, vfuns_p,
|
||||
layout_nonempty_base_or_field (rli, field, NULL_TREE,
|
||||
empty_base_offsets, t);
|
||||
|
||||
/* If a bit-field does not immediately follow another bit-field,
|
||||
and yet it starts in the middle of a byte, we have failed to
|
||||
comply with the ABI. */
|
||||
if (warn_abi
|
||||
&& DECL_C_BIT_FIELD (field)
|
||||
&& !last_field_was_bitfield
|
||||
&& !integer_zerop (size_binop (TRUNC_MOD_EXPR,
|
||||
DECL_FIELD_BIT_OFFSET (field),
|
||||
bitsize_unit_node)))
|
||||
cp_warning_at ("offset of `%D' is not ABI-compliant and may change in a future version of GCC",
|
||||
field);
|
||||
|
||||
/* If we needed additional padding after this field, add it
|
||||
now. */
|
||||
if (padding)
|
||||
@ -4931,6 +4911,8 @@ layout_class_type (t, empty_p, vfuns_p,
|
||||
NULL_TREE,
|
||||
empty_base_offsets, t);
|
||||
}
|
||||
|
||||
last_field_was_bitfield = DECL_C_BIT_FIELD (field);
|
||||
}
|
||||
|
||||
/* It might be the case that we grew the class to allocate a
|
||||
@ -4977,6 +4959,12 @@ layout_class_type (t, empty_p, vfuns_p,
|
||||
CLASSTYPE_SIZE (t) = bitsize_zero_node;
|
||||
CLASSTYPE_SIZE_UNIT (t) = size_zero_node;
|
||||
}
|
||||
/* If this is a POD, we can't reuse its tail padding. */
|
||||
else if (!CLASSTYPE_NON_POD_P (t))
|
||||
{
|
||||
CLASSTYPE_SIZE (t) = TYPE_SIZE (t);
|
||||
CLASSTYPE_SIZE_UNIT (t) = TYPE_SIZE_UNIT (t);
|
||||
}
|
||||
else
|
||||
{
|
||||
CLASSTYPE_SIZE (t) = TYPE_BINFO_SIZE (t);
|
||||
@ -5038,15 +5026,8 @@ finish_struct_1 (t)
|
||||
{
|
||||
tree x;
|
||||
int vfuns;
|
||||
/* The NEW_VIRTUALS is a TREE_LIST. The TREE_VALUE of each node is
|
||||
a FUNCTION_DECL. Each of these functions is a virtual function
|
||||
declared in T that does not override any virtual function from a
|
||||
base class. */
|
||||
tree new_virtuals = NULL_TREE;
|
||||
/* The OVERRIDDEN_VIRTUALS list is like the NEW_VIRTUALS list,
|
||||
except that each declaration here overrides the declaration from
|
||||
a base class. */
|
||||
tree overridden_virtuals = NULL_TREE;
|
||||
/* A TREE_LIST. The TREE_VALUE of each node is a FUNCTION_DECL. */
|
||||
tree virtuals = NULL_TREE;
|
||||
int n_fields = 0;
|
||||
tree vfield;
|
||||
int empty = 1;
|
||||
@ -5076,8 +5057,7 @@ finish_struct_1 (t)
|
||||
check_bases_and_members (t, &empty);
|
||||
|
||||
/* Layout the class itself. */
|
||||
layout_class_type (t, &empty, &vfuns,
|
||||
&new_virtuals, &overridden_virtuals);
|
||||
layout_class_type (t, &empty, &vfuns, &virtuals);
|
||||
|
||||
/* Make sure that we get our own copy of the vfield FIELD_DECL. */
|
||||
vfield = TYPE_VFIELD (t);
|
||||
@ -5101,8 +5081,7 @@ finish_struct_1 (t)
|
||||
else
|
||||
my_friendly_assert (!vfield || DECL_FIELD_CONTEXT (vfield) == t, 20010726);
|
||||
|
||||
overridden_virtuals
|
||||
= modify_all_vtables (t, &vfuns, nreverse (overridden_virtuals));
|
||||
virtuals = modify_all_vtables (t, &vfuns, nreverse (virtuals));
|
||||
|
||||
/* If we created a new vtbl pointer for this class, add it to the
|
||||
list. */
|
||||
@ -5111,9 +5090,8 @@ finish_struct_1 (t)
|
||||
= chainon (CLASSTYPE_VFIELDS (t), build_tree_list (NULL_TREE, t));
|
||||
|
||||
/* If necessary, create the primary vtable for this class. */
|
||||
if (new_virtuals || overridden_virtuals || TYPE_CONTAINS_VPTR_P (t))
|
||||
if (virtuals || TYPE_CONTAINS_VPTR_P (t))
|
||||
{
|
||||
new_virtuals = nreverse (new_virtuals);
|
||||
/* We must enter these virtuals into the table. */
|
||||
if (!CLASSTYPE_HAS_PRIMARY_BASE_P (t))
|
||||
build_primary_vtable (NULL_TREE, t);
|
||||
@ -5126,7 +5104,6 @@ finish_struct_1 (t)
|
||||
constructors might clobber the virtual function table. But
|
||||
they don't if the derived class shares the exact vtable of the base
|
||||
class. */
|
||||
|
||||
CLASSTYPE_NEEDS_VIRTUAL_REINIT (t) = 1;
|
||||
}
|
||||
/* If we didn't need a new vtable, see if we should copy one from
|
||||
@ -5152,14 +5129,8 @@ finish_struct_1 (t)
|
||||
20000116);
|
||||
|
||||
CLASSTYPE_VSIZE (t) = vfuns;
|
||||
/* Entries for virtual functions defined in the primary base are
|
||||
followed by entries for new functions unique to this class. */
|
||||
TYPE_BINFO_VIRTUALS (t)
|
||||
= chainon (TYPE_BINFO_VIRTUALS (t), new_virtuals);
|
||||
/* Finally, add entries for functions that override virtuals
|
||||
from non-primary bases. */
|
||||
TYPE_BINFO_VIRTUALS (t)
|
||||
= chainon (TYPE_BINFO_VIRTUALS (t), overridden_virtuals);
|
||||
/* Add entries for virtual functions introduced by this class. */
|
||||
TYPE_BINFO_VIRTUALS (t) = chainon (TYPE_BINFO_VIRTUALS (t), virtuals);
|
||||
}
|
||||
|
||||
finish_struct_bits (t);
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* Language-dependent hooks for C++.
|
||||
Copyright 2001 Free Software Foundation, Inc.
|
||||
Copyright 2001, 2002 Free Software Foundation, Inc.
|
||||
Contributed by Alexandre Oliva <aoliva@redhat.com>
|
||||
|
||||
This file is part of GNU CC.
|
||||
@ -28,7 +28,8 @@ Boston, MA 02111-1307, USA. */
|
||||
#include "langhooks.h"
|
||||
#include "langhooks-def.h"
|
||||
|
||||
static HOST_WIDE_INT cxx_get_alias_set PARAMS ((tree));
|
||||
static HOST_WIDE_INT cxx_get_alias_set PARAMS ((tree));
|
||||
static tree cp_expr_size PARAMS ((tree));
|
||||
|
||||
#undef LANG_HOOKS_NAME
|
||||
#define LANG_HOOKS_NAME "GNU C++"
|
||||
@ -43,7 +44,7 @@ static HOST_WIDE_INT cxx_get_alias_set PARAMS ((tree));
|
||||
#undef LANG_HOOKS_DECODE_OPTION
|
||||
#define LANG_HOOKS_DECODE_OPTION cxx_decode_option
|
||||
#undef LANG_HOOKS_POST_OPTIONS
|
||||
#define LANG_HOOKS_POST_OPTIONS cxx_post_options
|
||||
#define LANG_HOOKS_POST_OPTIONS c_common_post_options
|
||||
#undef LANG_HOOKS_GET_ALIAS_SET
|
||||
#define LANG_HOOKS_GET_ALIAS_SET cxx_get_alias_set
|
||||
#undef LANG_HOOKS_EXPAND_CONSTANT
|
||||
@ -91,6 +92,8 @@ static HOST_WIDE_INT cxx_get_alias_set PARAMS ((tree));
|
||||
#define LANG_HOOKS_TREE_DUMP_DUMP_TREE_FN cp_dump_tree
|
||||
#undef LANG_HOOKS_TREE_DUMP_TYPE_QUALS_FN
|
||||
#define LANG_HOOKS_TREE_DUMP_TYPE_QUALS_FN cp_type_quals
|
||||
#undef LANG_HOOKS_EXPR_SIZE
|
||||
#define LANG_HOOKS_EXPR_SIZE cp_expr_size
|
||||
|
||||
/* Each front end provides its own hooks, for toplev.c. */
|
||||
const struct lang_hooks lang_hooks = LANG_HOOKS_INITIALIZER;
|
||||
@ -108,3 +111,28 @@ cxx_get_alias_set (t)
|
||||
|
||||
return c_common_get_alias_set (t);
|
||||
}
|
||||
|
||||
/* Langhook for expr_size: Tell the backend that the value of an expression
|
||||
of non-POD class type does not include any tail padding; a derived class
|
||||
might have allocated something there. */
|
||||
|
||||
static tree
|
||||
cp_expr_size (exp)
|
||||
tree exp;
|
||||
{
|
||||
if (CLASS_TYPE_P (TREE_TYPE (exp)))
|
||||
{
|
||||
/* The backend should not be interested in the size of an expression
|
||||
of a type with both of these set; all copies of such types must go
|
||||
through a constructor or assignment op. */
|
||||
if (TYPE_HAS_COMPLEX_INIT_REF (TREE_TYPE (exp))
|
||||
&& TYPE_HAS_COMPLEX_ASSIGN_REF (TREE_TYPE (exp)))
|
||||
abort ();
|
||||
/* This would be wrong for a type with virtual bases, but they are
|
||||
caught by the abort above. */
|
||||
return CLASSTYPE_SIZE_UNIT (TREE_TYPE (exp));
|
||||
}
|
||||
else
|
||||
/* Use the default code. */
|
||||
return lhd_expr_size (exp);
|
||||
}
|
||||
|
@ -539,7 +539,7 @@ enum cp_tree_index
|
||||
CPTI_STD,
|
||||
CPTI_ABI,
|
||||
CPTI_TYPE_INFO_TYPE,
|
||||
CPTI_TINFO_DECL_TYPE,
|
||||
CPTI_TYPE_INFO_PTR_TYPE,
|
||||
CPTI_ABORT_FNDECL,
|
||||
CPTI_GLOBAL_DELETE_FNDECL,
|
||||
CPTI_AGGR_TAG,
|
||||
@ -626,7 +626,7 @@ extern tree cp_global_trees[CPTI_MAX];
|
||||
#define std_node cp_global_trees[CPTI_STD]
|
||||
#define abi_node cp_global_trees[CPTI_ABI]
|
||||
#define type_info_type_node cp_global_trees[CPTI_TYPE_INFO_TYPE]
|
||||
#define tinfo_decl_type cp_global_trees[CPTI_TINFO_DECL_TYPE]
|
||||
#define type_info_ptr_type cp_global_trees[CPTI_TYPE_INFO_PTR_TYPE]
|
||||
#define abort_fndecl cp_global_trees[CPTI_ABORT_FNDECL]
|
||||
#define global_delete_fndecl cp_global_trees[CPTI_GLOBAL_DELETE_FNDECL]
|
||||
#define current_aggr cp_global_trees[CPTI_AGGR_TAG]
|
||||
@ -934,6 +934,11 @@ extern int flag_operator_names;
|
||||
|
||||
extern int flag_gnu_binutils;
|
||||
|
||||
/* Nonzero means warn about things that will change when compiling
|
||||
with an ABI-compliant compiler. */
|
||||
|
||||
extern int warn_abi;
|
||||
|
||||
/* Nonzero means warn about implicit declarations. */
|
||||
|
||||
extern int warn_implicit;
|
||||
@ -1245,6 +1250,8 @@ struct lang_type
|
||||
unsigned is_partial_instantiation : 1;
|
||||
unsigned java_interface : 1;
|
||||
|
||||
unsigned non_zero_init : 1;
|
||||
|
||||
/* When adding a flag here, consider whether or not it ought to
|
||||
apply to a template instance if it applies to the template. If
|
||||
so, make sure to copy it in instantiate_class_template! */
|
||||
@ -1252,7 +1259,7 @@ struct lang_type
|
||||
/* There are some bits left to fill out a 32-bit word. Keep track
|
||||
of this by updating the size of this bitfield whenever you add or
|
||||
remove a flag. */
|
||||
unsigned dummy : 8;
|
||||
unsigned dummy : 7;
|
||||
|
||||
int vsize;
|
||||
|
||||
@ -1500,9 +1507,14 @@ struct lang_type
|
||||
#define CLASSTYPE_HAS_MUTABLE(NODE) (TYPE_LANG_SPECIFIC (NODE)->has_mutable)
|
||||
#define TYPE_HAS_MUTABLE_P(NODE) (cp_has_mutable_p (NODE))
|
||||
|
||||
/* Nonzero means that this class type is a non-POD class. */
|
||||
/* Nonzero means that this class type is a non-POD class. */
|
||||
#define CLASSTYPE_NON_POD_P(NODE) (TYPE_LANG_SPECIFIC (NODE)->non_pod_class)
|
||||
|
||||
/* Nonzero means that this class contains pod types whose default
|
||||
initialization is not a zero initialization (namely, pointers to
|
||||
data members). */
|
||||
#define CLASSTYPE_NON_ZERO_INIT_P(NODE) (TYPE_LANG_SPECIFIC (NODE)->non_zero_init)
|
||||
|
||||
/* Nonzero if this class is "nearly empty", i.e., contains only a
|
||||
virtual function table pointer. */
|
||||
#define CLASSTYPE_NEARLY_EMPTY_P(NODE) \
|
||||
@ -3812,6 +3824,7 @@ extern tree coerce_delete_type PARAMS ((tree));
|
||||
extern void comdat_linkage PARAMS ((tree));
|
||||
extern void import_export_vtable PARAMS ((tree, tree, int));
|
||||
extern void import_export_decl PARAMS ((tree));
|
||||
extern void import_export_tinfo PARAMS ((tree, tree, int));
|
||||
extern tree build_cleanup PARAMS ((tree));
|
||||
extern void finish_file PARAMS ((void));
|
||||
extern tree reparse_absdcl_as_expr PARAMS ((tree, tree));
|
||||
@ -3900,6 +3913,7 @@ extern tree build_aggr_init PARAMS ((tree, tree, int));
|
||||
extern int is_aggr_type PARAMS ((tree, int));
|
||||
extern tree get_aggr_from_typedef PARAMS ((tree, int));
|
||||
extern tree get_type_value PARAMS ((tree));
|
||||
extern tree build_forced_zero_init PARAMS ((tree));
|
||||
extern tree build_member_call PARAMS ((tree, tree, tree));
|
||||
extern tree build_offset_ref PARAMS ((tree, tree));
|
||||
extern tree resolve_offset_ref PARAMS ((tree));
|
||||
@ -3953,7 +3967,6 @@ extern int cp_type_qual_from_rid PARAMS ((tree));
|
||||
extern const char *cxx_init PARAMS ((const char *));
|
||||
extern void cxx_finish PARAMS ((void));
|
||||
extern void cxx_init_options PARAMS ((void));
|
||||
extern void cxx_post_options PARAMS ((void));
|
||||
|
||||
/* in method.c */
|
||||
extern void init_method PARAMS ((void));
|
||||
@ -4044,7 +4057,7 @@ extern tree get_tinfo_decl PARAMS((tree));
|
||||
extern tree get_typeid PARAMS((tree));
|
||||
extern tree build_dynamic_cast PARAMS((tree, tree));
|
||||
extern void emit_support_tinfos PARAMS((void));
|
||||
extern int tinfo_decl_p PARAMS((tree, void *));
|
||||
extern int unemitted_tinfo_decl_p PARAMS((tree, void *));
|
||||
extern int emit_tinfo_decl PARAMS((tree *, void *));
|
||||
|
||||
/* in search.c */
|
||||
@ -4076,6 +4089,7 @@ extern tree lookup_conversions PARAMS ((tree));
|
||||
extern tree binfo_for_vtable PARAMS ((tree));
|
||||
extern tree binfo_from_vbase PARAMS ((tree));
|
||||
extern tree look_for_overrides_here PARAMS ((tree, tree));
|
||||
extern int check_final_overrider PARAMS ((tree, tree));
|
||||
extern tree dfs_walk PARAMS ((tree,
|
||||
tree (*) (tree, void *),
|
||||
tree (*) (tree, void *),
|
||||
@ -4212,6 +4226,7 @@ extern void end_input PARAMS ((void));
|
||||
/* in tree.c */
|
||||
extern void init_tree PARAMS ((void));
|
||||
extern int pod_type_p PARAMS ((tree));
|
||||
extern int zero_init_p PARAMS ((tree));
|
||||
extern tree canonical_type_variant PARAMS ((tree));
|
||||
extern void unshare_base_binfos PARAMS ((tree));
|
||||
extern int member_p PARAMS ((tree));
|
||||
@ -4357,6 +4372,7 @@ extern int abstract_virtuals_error PARAMS ((tree, tree));
|
||||
#define my_friendly_assert(EXP, N) (void) \
|
||||
(((EXP) == 0) ? (fancy_abort (__FILE__, __LINE__, __FUNCTION__), 0) : 0)
|
||||
|
||||
extern tree force_store_init_value PARAMS ((tree, tree));
|
||||
extern tree store_init_value PARAMS ((tree, tree));
|
||||
extern tree digest_init PARAMS ((tree, tree, tree *));
|
||||
extern tree build_scoped_ref PARAMS ((tree, tree));
|
||||
|
@ -1,6 +1,6 @@
|
||||
/* Language-level data type conversion for GNU C++.
|
||||
Copyright (C) 1987, 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
|
||||
1999, 2000 Free Software Foundation, Inc.
|
||||
1999, 2000, 2001, 2002 Free Software Foundation, Inc.
|
||||
Hacked by Michael Tiemann (tiemann@cygnus.com)
|
||||
|
||||
This file is part of GNU CC.
|
||||
@ -249,6 +249,8 @@ cp_convert_to_pointer (type, expr, force)
|
||||
else
|
||||
expr = build_int_2 (0, 0);
|
||||
TREE_TYPE (expr) = type;
|
||||
/* Fix up the representation of -1 if appropriate. */
|
||||
force_fit_type (expr, 0);
|
||||
return expr;
|
||||
}
|
||||
|
||||
@ -285,13 +287,6 @@ convert_to_pointer_force (type, expr)
|
||||
register tree intype = TREE_TYPE (expr);
|
||||
register enum tree_code form = TREE_CODE (intype);
|
||||
|
||||
if (integer_zerop (expr))
|
||||
{
|
||||
expr = build_int_2 (0, 0);
|
||||
TREE_TYPE (expr) = type;
|
||||
return expr;
|
||||
}
|
||||
|
||||
if (form == POINTER_TYPE)
|
||||
{
|
||||
intype = TYPE_MAIN_VARIANT (intype);
|
||||
|
@ -172,6 +172,11 @@ int flag_implicit_templates = 1;
|
||||
|
||||
int flag_implicit_inline_templates = 1;
|
||||
|
||||
/* Nonzero means warn about things that will change when compiling
|
||||
with an ABI-compliant compiler. */
|
||||
|
||||
int warn_abi = 0;
|
||||
|
||||
/* Nonzero means warn about implicit declarations. */
|
||||
|
||||
int warn_implicit = 1;
|
||||
@ -376,7 +381,7 @@ int flag_weak = 1;
|
||||
/* Nonzero to use __cxa_atexit, rather than atexit, to register
|
||||
destructors for local statics and global objects. */
|
||||
|
||||
int flag_use_cxa_atexit;
|
||||
int flag_use_cxa_atexit = DEFAULT_USE_CXA_ATEXIT;
|
||||
|
||||
/* Maximum template instantiation depth. This limit is rather
|
||||
arbitrary, but it exists to limit the time it takes to notice
|
||||
@ -600,7 +605,9 @@ cxx_decode_option (argc, argv)
|
||||
if (p[0] == 'n' && p[1] == 'o' && p[2] == '-')
|
||||
setting = 0, p += 3;
|
||||
|
||||
if (!strcmp (p, "implicit"))
|
||||
if (!strcmp (p, "abi"))
|
||||
warn_abi = setting;
|
||||
else if (!strcmp (p, "implicit"))
|
||||
warn_implicit = setting;
|
||||
else if (!strcmp (p, "long-long"))
|
||||
warn_long_long = setting;
|
||||
@ -2497,7 +2504,10 @@ import_export_decl (decl)
|
||||
comdat_linkage (decl);
|
||||
}
|
||||
else
|
||||
DECL_NOT_REALLY_EXTERN (decl) = 0;
|
||||
{
|
||||
DECL_EXTERNAL (decl) = 1;
|
||||
DECL_NOT_REALLY_EXTERN (decl) = 0;
|
||||
}
|
||||
}
|
||||
else if (DECL_FUNCTION_MEMBER_P (decl))
|
||||
{
|
||||
@ -2513,6 +2523,9 @@ import_export_decl (decl)
|
||||
&& ! flag_implement_inlines
|
||||
&& !DECL_VINDEX (decl)));
|
||||
|
||||
if (!DECL_NOT_REALLY_EXTERN (decl))
|
||||
DECL_EXTERNAL (decl) = 1;
|
||||
|
||||
/* Always make artificials weak. */
|
||||
if (DECL_ARTIFICIAL (decl) && flag_weak)
|
||||
comdat_linkage (decl);
|
||||
@ -2523,48 +2536,53 @@ import_export_decl (decl)
|
||||
else
|
||||
comdat_linkage (decl);
|
||||
}
|
||||
else if (tinfo_decl_p (decl, 0))
|
||||
{
|
||||
tree ctype = TREE_TYPE (DECL_NAME (decl));
|
||||
|
||||
if (IS_AGGR_TYPE (ctype))
|
||||
import_export_class (ctype);
|
||||
|
||||
if (IS_AGGR_TYPE (ctype) && CLASSTYPE_INTERFACE_KNOWN (ctype)
|
||||
&& TYPE_POLYMORPHIC_P (ctype)
|
||||
/* If -fno-rtti, we're not necessarily emitting this stuff with
|
||||
the class, so go ahead and emit it now. This can happen
|
||||
when a class is used in exception handling. */
|
||||
&& flag_rtti
|
||||
/* If the type is a cv-qualified variant of a type, then we
|
||||
must emit the tinfo function in this translation unit
|
||||
since it will not be emitted when the vtable for the type
|
||||
is output (which is when the unqualified version is
|
||||
generated). */
|
||||
&& same_type_p (ctype, TYPE_MAIN_VARIANT (ctype)))
|
||||
{
|
||||
DECL_NOT_REALLY_EXTERN (decl)
|
||||
= ! (CLASSTYPE_INTERFACE_ONLY (ctype)
|
||||
|| (DECL_DECLARED_INLINE_P (decl)
|
||||
&& ! flag_implement_inlines
|
||||
&& !DECL_VINDEX (decl)));
|
||||
|
||||
/* Always make artificials weak. */
|
||||
if (flag_weak)
|
||||
comdat_linkage (decl);
|
||||
}
|
||||
else if (TYPE_BUILT_IN (ctype)
|
||||
&& same_type_p (ctype, TYPE_MAIN_VARIANT (ctype)))
|
||||
DECL_NOT_REALLY_EXTERN (decl) = 0;
|
||||
else
|
||||
comdat_linkage (decl);
|
||||
}
|
||||
else
|
||||
comdat_linkage (decl);
|
||||
|
||||
DECL_INTERFACE_KNOWN (decl) = 1;
|
||||
}
|
||||
|
||||
/* Here, we only decide whether or not the tinfo node should be
|
||||
emitted with the vtable. IS_IN_LIBRARY is non-zero iff the
|
||||
typeinfo for TYPE should be in the runtime library. */
|
||||
|
||||
void
|
||||
import_export_tinfo (decl, type, is_in_library)
|
||||
tree decl;
|
||||
tree type;
|
||||
int is_in_library;
|
||||
{
|
||||
if (DECL_INTERFACE_KNOWN (decl))
|
||||
return;
|
||||
|
||||
if (IS_AGGR_TYPE (type))
|
||||
import_export_class (type);
|
||||
|
||||
if (IS_AGGR_TYPE (type) && CLASSTYPE_INTERFACE_KNOWN (type)
|
||||
&& TYPE_POLYMORPHIC_P (type)
|
||||
/* If -fno-rtti, we're not necessarily emitting this stuff with
|
||||
the class, so go ahead and emit it now. This can happen when
|
||||
a class is used in exception handling. */
|
||||
&& flag_rtti)
|
||||
{
|
||||
DECL_NOT_REALLY_EXTERN (decl) = !CLASSTYPE_INTERFACE_ONLY (type);
|
||||
DECL_COMDAT (decl) = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
DECL_NOT_REALLY_EXTERN (decl) = 1;
|
||||
DECL_COMDAT (decl) = 1;
|
||||
}
|
||||
|
||||
/* Now override some cases. */
|
||||
if (flag_weak)
|
||||
DECL_COMDAT (decl) = 1;
|
||||
else if (is_in_library)
|
||||
DECL_COMDAT (decl) = 0;
|
||||
|
||||
DECL_INTERFACE_KNOWN (decl) = 1;
|
||||
}
|
||||
|
||||
tree
|
||||
build_cleanup (decl)
|
||||
tree decl;
|
||||
@ -3358,7 +3376,7 @@ finish_file ()
|
||||
|
||||
/* Write out needed type info variables. Writing out one variable
|
||||
might cause others to be needed. */
|
||||
if (walk_globals (tinfo_decl_p, emit_tinfo_decl, /*data=*/0))
|
||||
if (walk_globals (unemitted_tinfo_decl_p, emit_tinfo_decl, /*data=*/0))
|
||||
reconsider = 1;
|
||||
|
||||
/* The list of objects with static storage duration is built up
|
||||
|
@ -474,7 +474,7 @@ dump_type (t, flags)
|
||||
case TYPEOF_TYPE:
|
||||
output_add_string (scratch_buffer, "__typeof (");
|
||||
dump_expr (TYPE_FIELDS (t), flags & ~TFF_EXPR_IN_PARENS);
|
||||
print_left_paren (scratch_buffer);
|
||||
print_right_paren (scratch_buffer);
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -1,6 +1,6 @@
|
||||
/* Handle initialization things in C++.
|
||||
Copyright (C) 1987, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
|
||||
1999, 2000, 2001 Free Software Foundation, Inc.
|
||||
1999, 2000, 2001, 2002 Free Software Foundation, Inc.
|
||||
Contributed by Michael Tiemann (tiemann@cygnus.com)
|
||||
|
||||
This file is part of GNU CC.
|
||||
@ -176,6 +176,44 @@ initialize_vtbl_ptrs (addr)
|
||||
dfs_marked_real_bases_queue_p, type);
|
||||
}
|
||||
|
||||
/* Types containing pointers to data members cannot be
|
||||
zero-initialized with zeros, because the NULL value for such
|
||||
pointers is -1.
|
||||
|
||||
TYPE is a type that requires such zero initialization. The
|
||||
returned value is the initializer. */
|
||||
|
||||
tree
|
||||
build_forced_zero_init (type)
|
||||
tree type;
|
||||
{
|
||||
tree init = NULL;
|
||||
|
||||
if (AGGREGATE_TYPE_P (type) && !TYPE_PTRMEMFUNC_P (type))
|
||||
{
|
||||
/* This is a default initialization of an aggregate, but not one of
|
||||
non-POD class type. We cleverly notice that the initialization
|
||||
rules in such a case are the same as for initialization with an
|
||||
empty brace-initialization list. */
|
||||
init = build (CONSTRUCTOR, NULL_TREE, NULL_TREE, NULL_TREE);
|
||||
}
|
||||
else if (TREE_CODE (type) == REFERENCE_TYPE)
|
||||
/* --if T is a reference type, no initialization is performed. */
|
||||
return NULL_TREE;
|
||||
else
|
||||
{
|
||||
init = integer_zero_node;
|
||||
|
||||
if (TREE_CODE (type) == ENUMERAL_TYPE)
|
||||
/* We must make enumeral types the right type. */
|
||||
init = fold (build1 (NOP_EXPR, type, init));
|
||||
}
|
||||
|
||||
init = digest_init (type, init, 0);
|
||||
|
||||
return init;
|
||||
}
|
||||
|
||||
/* [dcl.init]:
|
||||
|
||||
To default-initialize an object of type T means:
|
||||
@ -202,28 +240,8 @@ build_default_init (type)
|
||||
anything with a CONSTRUCTOR for arrays here, as that would imply
|
||||
copy-initialization. */
|
||||
return NULL_TREE;
|
||||
else if (AGGREGATE_TYPE_P (type) && !TYPE_PTRMEMFUNC_P (type))
|
||||
{
|
||||
/* This is a default initialization of an aggregate, but not one of
|
||||
non-POD class type. We cleverly notice that the initialization
|
||||
rules in such a case are the same as for initialization with an
|
||||
empty brace-initialization list. */
|
||||
init = build (CONSTRUCTOR, NULL_TREE, NULL_TREE, NULL_TREE);
|
||||
}
|
||||
else if (TREE_CODE (type) == REFERENCE_TYPE)
|
||||
/* --if T is a reference type, no initialization is performed. */
|
||||
return NULL_TREE;
|
||||
else
|
||||
{
|
||||
init = integer_zero_node;
|
||||
|
||||
if (TREE_CODE (type) == ENUMERAL_TYPE)
|
||||
/* We must make enumeral types the right type. */
|
||||
init = fold (build1 (NOP_EXPR, type, init));
|
||||
}
|
||||
|
||||
init = digest_init (type, init, 0);
|
||||
return init;
|
||||
return build_forced_zero_init (type);
|
||||
}
|
||||
|
||||
/* Subroutine of emit_base_init. */
|
||||
@ -1165,11 +1183,9 @@ build_aggr_init (exp, init, flags)
|
||||
return error_mark_node;
|
||||
}
|
||||
if (cp_type_quals (type) != TYPE_UNQUALIFIED)
|
||||
{
|
||||
TREE_TYPE (exp) = TYPE_MAIN_VARIANT (type);
|
||||
if (init)
|
||||
TREE_TYPE (init) = TYPE_MAIN_VARIANT (itype);
|
||||
}
|
||||
TREE_TYPE (exp) = TYPE_MAIN_VARIANT (type);
|
||||
if (itype && cp_type_quals (itype) != TYPE_UNQUALIFIED)
|
||||
TREE_TYPE (init) = TYPE_MAIN_VARIANT (itype);
|
||||
stmt_expr = build_vec_init (exp, init,
|
||||
init && same_type_p (TREE_TYPE (init),
|
||||
TREE_TYPE (exp)));
|
||||
@ -2575,6 +2591,10 @@ build_vec_delete_1 (base, maxindex, type, auto_delete_vec, use_global_delete)
|
||||
This is also the containing expression returned by this function. */
|
||||
tree controller = NULL_TREE;
|
||||
|
||||
/* We should only have 1-D arrays here. */
|
||||
if (TREE_CODE (type) == ARRAY_TYPE)
|
||||
abort ();
|
||||
|
||||
if (! IS_AGGR_TYPE (type) || TYPE_HAS_TRIVIAL_DESTRUCTOR (type))
|
||||
{
|
||||
loop = integer_zero_node;
|
||||
@ -2988,12 +3008,20 @@ build_vec_init (base, init, from_array)
|
||||
&& from_array != 2)
|
||||
{
|
||||
tree e;
|
||||
tree m = cp_build_binary_op (MINUS_EXPR, maxindex, iterator);
|
||||
|
||||
/* Flatten multi-dimensional array since build_vec_delete only
|
||||
expects one-dimensional array. */
|
||||
if (TREE_CODE (type) == ARRAY_TYPE)
|
||||
{
|
||||
m = cp_build_binary_op (MULT_EXPR, m,
|
||||
array_type_nelts_total (type));
|
||||
type = strip_array_types (type);
|
||||
}
|
||||
|
||||
finish_compound_stmt (/*has_no_scope=*/1, try_body);
|
||||
finish_cleanup_try_block (try_block);
|
||||
e = build_vec_delete_1 (rval,
|
||||
cp_build_binary_op (MINUS_EXPR, maxindex,
|
||||
iterator),
|
||||
e = build_vec_delete_1 (rval, m,
|
||||
type,
|
||||
sfk_base_destructor,
|
||||
/*use_global_delete=*/0);
|
||||
|
@ -38,14 +38,12 @@ Boston, MA 02111-1307, USA. */
|
||||
"%{E|M|MM:cpp0 -lang-c++ %{!no-gcc:-D__GNUG__=%v1}\
|
||||
%{!Wno-deprecated:-D__DEPRECATED}\
|
||||
%{!fno-exceptions:-D__EXCEPTIONS}\
|
||||
-D__GXX_ABI_VERSION=100\
|
||||
%{ansi:-D__STRICT_ANSI__ -trigraphs -$} %(cpp_options)}\
|
||||
%{!E:%{!M:%{!MM:\
|
||||
%{save-temps|no-integrated-cpp:cpp0 -lang-c++ \
|
||||
%{!no-gcc:-D__GNUG__=%v1}\
|
||||
%{!Wno-deprecated:-D__DEPRECATED}\
|
||||
%{!fno-exceptions:-D__EXCEPTIONS}\
|
||||
-D__GXX_ABI_VERSION=100\
|
||||
%{ansi:-D__STRICT_ANSI__ -trigraphs -$}\
|
||||
%(cpp_options) %{save-temps:%b.ii} %{!save-temps:%g.ii} \n}\
|
||||
cc1plus %{save-temps|no-integrated-cpp:-fpreprocessed %{save-temps:%b.ii} %{!save-temps:%g.ii}}\
|
||||
@ -53,7 +51,6 @@ Boston, MA 02111-1307, USA. */
|
||||
%{!no-gcc:-D__GNUG__=%v1} \
|
||||
%{!Wno-deprecated:-D__DEPRECATED}\
|
||||
%{!fno-exceptions:-D__EXCEPTIONS}\
|
||||
-D__GXX_ABI_VERSION=100\
|
||||
%{ansi:-D__STRICT_ANSI__}}}\
|
||||
%{ansi:-trigraphs -$}\
|
||||
%(cc1_options) %2 %{+e1*}\
|
||||
|
@ -1,6 +1,6 @@
|
||||
/* Separate lexical analyzer for GNU C++.
|
||||
Copyright (C) 1987, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
|
||||
1999, 2000, 2001 Free Software Foundation, Inc.
|
||||
1999, 2000, 2001, 2002 Free Software Foundation, Inc.
|
||||
Hacked by Michael Tiemann (tiemann@cygnus.com)
|
||||
|
||||
This file is part of GNU CC.
|
||||
@ -237,13 +237,6 @@ static const char *const cplus_tree_code_name[] = {
|
||||
};
|
||||
#undef DEFTREECODE
|
||||
|
||||
/* Post-switch processing. */
|
||||
void
|
||||
cxx_post_options ()
|
||||
{
|
||||
c_common_post_options ();
|
||||
}
|
||||
|
||||
/* Initialization before switch parsing. */
|
||||
void
|
||||
cxx_init_options ()
|
||||
|
@ -982,8 +982,17 @@ write_unqualified_name (decl)
|
||||
{
|
||||
/* Conversion operator. Handle it right here.
|
||||
<operator> ::= cv <type> */
|
||||
tree type;
|
||||
if (decl_is_template_id (decl, NULL))
|
||||
{
|
||||
tree fn_type = get_mostly_instantiated_function_type (decl, NULL,
|
||||
NULL);
|
||||
type = TREE_TYPE (fn_type);
|
||||
}
|
||||
else
|
||||
type = TREE_TYPE (DECL_NAME (decl));
|
||||
write_string ("cv");
|
||||
write_type (TREE_TYPE (DECL_NAME (decl)));
|
||||
write_type (type);
|
||||
}
|
||||
else if (DECL_OVERLOADED_OPERATOR_P (decl))
|
||||
{
|
||||
@ -1818,6 +1827,12 @@ write_expression (expr)
|
||||
write_mangled_name (expr);
|
||||
write_char ('E');
|
||||
}
|
||||
else if (TREE_CODE (expr) == SIZEOF_EXPR
|
||||
&& TYPE_P (TREE_OPERAND (expr, 0)))
|
||||
{
|
||||
write_string ("st");
|
||||
write_type (TREE_OPERAND (expr, 0));
|
||||
}
|
||||
else
|
||||
{
|
||||
int i;
|
||||
@ -1856,6 +1871,7 @@ write_expression (expr)
|
||||
write_expression (TREE_OPERAND (expr, 0));
|
||||
break;
|
||||
|
||||
|
||||
/* Handle pointers-to-members specially. */
|
||||
case SCOPE_REF:
|
||||
write_type (TREE_OPERAND (expr, 0));
|
||||
|
@ -5,7 +5,7 @@
|
||||
non-overloadable operators (like the `?:' ternary operator).
|
||||
Writtey by Mark Mitchell <mark@codesourcery.com>
|
||||
|
||||
Copyright (C) 2000, 2001 Free Software Foundation, Inc.
|
||||
Copyright (C) 2000, 2001, 2002 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU CC.
|
||||
|
||||
@ -46,10 +46,6 @@ Boston, MA 02111-1307, USA. */
|
||||
mangled under the new ABI. For `operator +', for example, this
|
||||
would be "pl".
|
||||
|
||||
OLD_MANGLING
|
||||
|
||||
Analogous, but for the old ABI.
|
||||
|
||||
ARITY
|
||||
|
||||
The arity of the operator, or -1 if any arity is allowed. (As
|
||||
|
@ -134,6 +134,7 @@ static tree build_template_decl PARAMS ((tree, tree));
|
||||
static int mark_template_parm PARAMS ((tree, void *));
|
||||
static tree tsubst_friend_function PARAMS ((tree, tree));
|
||||
static tree tsubst_friend_class PARAMS ((tree, tree));
|
||||
static int can_complete_type_without_circularity PARAMS ((tree));
|
||||
static tree get_bindings_real PARAMS ((tree, tree, tree, int, int, int));
|
||||
static int template_decl_level PARAMS ((tree));
|
||||
static tree maybe_get_template_decl_from_type_decl PARAMS ((tree));
|
||||
@ -3942,10 +3943,16 @@ lookup_template_class (d1, arglist, in_decl, context, entering_scope, complain)
|
||||
The template parameter level of T and U are one level larger than
|
||||
of TT. To proper process the default argument of U, say when an
|
||||
instantiation `TT<int>' is seen, we need to build the full
|
||||
arguments containing {int} as the innermost level. Outer levels
|
||||
can be obtained from `current_template_args ()'. */
|
||||
arguments containing {int} as the innermost level. Outer levels,
|
||||
available when not appearing as default template argument, can be
|
||||
obtained from `current_template_args ()'.
|
||||
|
||||
if (processing_template_decl)
|
||||
Suppose that TT is later substituted with std::vector. The above
|
||||
instantiation is `TT<int, std::allocator<T> >' with TT at
|
||||
level 1, and T at level 2, while the template arguments at level 1
|
||||
becomes {std::vector} and the inner level 2 is {int}. */
|
||||
|
||||
if (current_template_parms)
|
||||
arglist = add_to_template_args (current_template_args (), arglist);
|
||||
|
||||
arglist2 = coerce_template_parms (parmlist, arglist, template,
|
||||
@ -4805,7 +4812,7 @@ tsubst_friend_class (friend_tmpl, args)
|
||||
if (TREE_CODE (context) == NAMESPACE_DECL)
|
||||
push_nested_namespace (context);
|
||||
else
|
||||
push_nested_class (context, 2);
|
||||
push_nested_class (tsubst (context, args, tf_none, NULL_TREE), 2);
|
||||
}
|
||||
|
||||
/* First, we look for a class template. */
|
||||
@ -4877,6 +4884,25 @@ tsubst_friend_class (friend_tmpl, args)
|
||||
return friend_type;
|
||||
}
|
||||
|
||||
/* Returns zero if TYPE cannot be completed later due to circularity.
|
||||
Otherwise returns one. */
|
||||
|
||||
static int
|
||||
can_complete_type_without_circularity (type)
|
||||
tree type;
|
||||
{
|
||||
if (type == NULL_TREE || type == error_mark_node)
|
||||
return 0;
|
||||
else if (COMPLETE_TYPE_P (type))
|
||||
return 1;
|
||||
else if (TREE_CODE (type) == ARRAY_TYPE && TYPE_DOMAIN (type))
|
||||
return can_complete_type_without_circularity (TREE_TYPE (type));
|
||||
else if (CLASS_TYPE_P (type) && TYPE_BEING_DEFINED (TYPE_MAIN_VARIANT (type)))
|
||||
return 0;
|
||||
else
|
||||
return 1;
|
||||
}
|
||||
|
||||
tree
|
||||
instantiate_class_template (type)
|
||||
tree type;
|
||||
@ -5197,7 +5223,20 @@ instantiate_class_template (type)
|
||||
if (DECL_INITIALIZED_IN_CLASS_P (r))
|
||||
check_static_variable_definition (r, TREE_TYPE (r));
|
||||
}
|
||||
|
||||
else if (TREE_CODE (r) == FIELD_DECL)
|
||||
{
|
||||
/* Determine whether R has a valid type and can be
|
||||
completed later. If R is invalid, then it is replaced
|
||||
by error_mark_node so that it will not be added to
|
||||
TYPE_FIELDS. */
|
||||
tree rtype = TREE_TYPE (r);
|
||||
if (!can_complete_type_without_circularity (rtype))
|
||||
{
|
||||
incomplete_type_error (r, rtype);
|
||||
r = error_mark_node;
|
||||
}
|
||||
}
|
||||
|
||||
/* R will have a TREE_CHAIN if and only if it has already been
|
||||
processed by finish_member_declaration. This can happen
|
||||
if, for example, it is a TYPE_DECL for a class-scoped
|
||||
@ -5278,6 +5317,8 @@ instantiate_class_template (type)
|
||||
--processing_template_decl;
|
||||
}
|
||||
|
||||
/* Now that TYPE_FIELDS and TYPE_METHODS are set up. We can
|
||||
instantiate templates used by this class. */
|
||||
for (t = TYPE_FIELDS (type); t; t = TREE_CHAIN (t))
|
||||
if (TREE_CODE (t) == FIELD_DECL)
|
||||
{
|
||||
@ -7487,6 +7528,11 @@ tsubst_expr (t, args, complain, in_decl)
|
||||
finish_label_stmt (DECL_NAME (LABEL_STMT_LABEL (t)));
|
||||
break;
|
||||
|
||||
case FILE_STMT:
|
||||
input_filename = FILE_STMT_FILENAME (t);
|
||||
add_stmt (build_nt (FILE_STMT, FILE_STMT_FILENAME_NODE (t)));
|
||||
break;
|
||||
|
||||
case GOTO_STMT:
|
||||
prep_stmt (t);
|
||||
tmp = GOTO_DESTINATION (t);
|
||||
@ -7502,12 +7548,13 @@ tsubst_expr (t, args, complain, in_decl)
|
||||
|
||||
case ASM_STMT:
|
||||
prep_stmt (t);
|
||||
finish_asm_stmt (ASM_CV_QUAL (t),
|
||||
tsubst_expr (ASM_STRING (t), args, complain, in_decl),
|
||||
tsubst_expr (ASM_OUTPUTS (t), args, complain, in_decl),
|
||||
tsubst_expr (ASM_INPUTS (t), args, complain, in_decl),
|
||||
tsubst_expr (ASM_CLOBBERS (t), args, complain,
|
||||
in_decl));
|
||||
tmp = finish_asm_stmt
|
||||
(ASM_CV_QUAL (t),
|
||||
tsubst_expr (ASM_STRING (t), args, complain, in_decl),
|
||||
tsubst_expr (ASM_OUTPUTS (t), args, complain, in_decl),
|
||||
tsubst_expr (ASM_INPUTS (t), args, complain, in_decl),
|
||||
tsubst_expr (ASM_CLOBBERS (t), args, complain, in_decl));
|
||||
ASM_INPUT_P (tmp) = ASM_INPUT_P (t);
|
||||
break;
|
||||
|
||||
case TRY_BLOCK:
|
||||
@ -9501,12 +9548,16 @@ do_decl_instantiation (declspecs, declarator, storage)
|
||||
|
||||
if (DECL_TEMPLATE_SPECIALIZATION (result))
|
||||
{
|
||||
/* [temp.spec]
|
||||
/* DR 259 [temp.spec].
|
||||
|
||||
No program shall both explicitly instantiate and explicitly
|
||||
specialize a template. */
|
||||
pedwarn ("explicit instantiation of `%#D' after", result);
|
||||
cp_pedwarn_at ("explicit specialization here", result);
|
||||
Both an explicit instantiation and a declaration of an explicit
|
||||
specialization shall not appear in a program unless the explicit
|
||||
instantiation follows a declaration of the explicit specialization.
|
||||
|
||||
For a given set of template parameters, if an explicit
|
||||
instantiation of a template appears after a declaration of an
|
||||
explicit specialization for that template, the explicit
|
||||
instantiation has no effect. */
|
||||
return;
|
||||
}
|
||||
else if (DECL_EXPLICIT_INSTANTIATION (result))
|
||||
@ -9636,15 +9687,16 @@ do_type_instantiation (t, storage, complain)
|
||||
|
||||
if (CLASSTYPE_TEMPLATE_SPECIALIZATION (t))
|
||||
{
|
||||
/* [temp.spec]
|
||||
/* DR 259 [temp.spec].
|
||||
|
||||
No program shall both explicitly instantiate and explicitly
|
||||
specialize a template. */
|
||||
if (complain & tf_error)
|
||||
{
|
||||
error ("explicit instantiation of `%#T' after", t);
|
||||
cp_error_at ("explicit specialization here", t);
|
||||
}
|
||||
Both an explicit instantiation and a declaration of an explicit
|
||||
specialization shall not appear in a program unless the explicit
|
||||
instantiation follows a declaration of the explicit specialization.
|
||||
|
||||
For a given set of template parameters, if an explicit
|
||||
instantiation of a template appears after a declaration of an
|
||||
explicit specialization for that template, the explicit
|
||||
instantiation has no effect. */
|
||||
return;
|
||||
}
|
||||
else if (CLASSTYPE_EXPLICIT_INSTANTIATION (t))
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* RunTime Type Identification
|
||||
Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2001
|
||||
Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002
|
||||
Free Software Foundation, Inc.
|
||||
Mostly written by Jason Merrill (jason@cygnus.com).
|
||||
|
||||
@ -30,16 +30,46 @@ Boston, MA 02111-1307, USA. */
|
||||
#include "assert.h"
|
||||
#include "toplev.h"
|
||||
|
||||
/* C++ returns type information to the user in struct type_info
|
||||
objects. We also use type information to implement dynamic_cast and
|
||||
exception handlers. Type information for a particular type is
|
||||
indicated with an ABI defined structure derived from type_info.
|
||||
This would all be very straight forward, but for the fact that the
|
||||
runtime library provides the definitions of the type_info structure
|
||||
and the ABI defined derived classes. We cannot build declarations
|
||||
of them directly in the compiler, but we need to layout objects of
|
||||
their type. Somewhere we have to lie.
|
||||
|
||||
We define layout compatible POD-structs with compiler-defined names
|
||||
and generate the appropriate initializations for them (complete
|
||||
with explicit mention of their vtable). When we have to provide a
|
||||
type_info to the user we reinterpret_cast the internal compiler
|
||||
type to type_info. A well formed program can only explicitly refer
|
||||
to the type_infos of complete types (& cv void). However, we chain
|
||||
pointer type_infos to the pointed-to-type, and that can be
|
||||
incomplete. We only need the addresses of such incomplete
|
||||
type_info objects for static initialization.
|
||||
|
||||
The type information VAR_DECL of a type is held on the
|
||||
IDENTIFIER_GLOBAL_VALUE of the type's mangled name. That VAR_DECL
|
||||
will be the internal type. It will usually have the correct
|
||||
internal type reflecting the kind of type it represents (pointer,
|
||||
array, function, class, inherited class, etc). When the type it
|
||||
represents is incomplete, it will have the internal type
|
||||
corresponding to type_info. That will only happen at the end of
|
||||
translation, when we are emitting the type info objects. */
|
||||
|
||||
/* Accessors for the type_info objects. We need to remember several things
|
||||
about each of the type_info types. The global tree nodes such as
|
||||
bltn_desc_type_node are TREE_LISTs, and these macros are used to access
|
||||
the required information. */
|
||||
/* The RECORD_TYPE of a type_info derived class. */
|
||||
#define TINFO_PSEUDO_TYPE(NODE) TREE_TYPE (NODE)
|
||||
/* The VAR_DECL of the vtable for the type_info derived class. */
|
||||
/* The VAR_DECL of the vtable for the type_info derived class.
|
||||
This is only filled in at the end of the translation. */
|
||||
#define TINFO_VTABLE_DECL(NODE) TREE_VALUE (NODE)
|
||||
|
||||
extern struct obstack permanent_obstack;
|
||||
/* The IDENTIFIER_NODE naming the real class. */
|
||||
#define TINFO_REAL_NAME(NODE) TREE_PURPOSE (NODE)
|
||||
|
||||
static tree build_headof PARAMS((tree));
|
||||
static tree ifnonnull PARAMS((tree, tree));
|
||||
@ -48,7 +78,8 @@ static tree build_dynamic_cast_1 PARAMS((tree, tree));
|
||||
static tree throw_bad_cast PARAMS((void));
|
||||
static tree throw_bad_typeid PARAMS((void));
|
||||
static tree get_tinfo_decl_dynamic PARAMS((tree));
|
||||
static bool typeid_ok_p PARAMS ((void));
|
||||
static tree get_tinfo_ptr PARAMS((tree));
|
||||
static bool typeid_ok_p PARAMS((void));
|
||||
static int qualifier_flags PARAMS((tree));
|
||||
static int target_incomplete_p PARAMS((tree));
|
||||
static tree tinfo_base_init PARAMS((tree, tree));
|
||||
@ -59,15 +90,21 @@ static tree dfs_class_hint_mark PARAMS ((tree, void *));
|
||||
static tree dfs_class_hint_unmark PARAMS ((tree, void *));
|
||||
static int class_hint_flags PARAMS((tree));
|
||||
static tree class_initializer PARAMS((tree, tree, tree));
|
||||
static tree synthesize_tinfo_var PARAMS((tree, tree));
|
||||
static tree create_real_tinfo_var PARAMS((tree, tree, tree, tree, int));
|
||||
static tree create_pseudo_type_info PARAMS((const char *, int, ...));
|
||||
static tree get_vmi_pseudo_type_info PARAMS((int));
|
||||
static tree get_pseudo_ti_init PARAMS ((tree, tree, int *));
|
||||
static tree get_pseudo_ti_desc PARAMS((tree));
|
||||
static void create_tinfo_types PARAMS((void));
|
||||
static int typeinfo_in_lib_p PARAMS((tree));
|
||||
|
||||
static int doing_runtime = 0;
|
||||
|
||||
|
||||
/* Declare language defined type_info type and a pointer to const
|
||||
type_info. This is incomplete here, and will be completed when
|
||||
the user #includes <typeinfo>. There are language defined
|
||||
restrictions on what can be done until that is included. Create
|
||||
the internal versions of the ABI types. */
|
||||
|
||||
void
|
||||
init_rtti_processing ()
|
||||
{
|
||||
@ -75,8 +112,11 @@ init_rtti_processing ()
|
||||
type_info_type_node = xref_tag
|
||||
(class_type_node, get_identifier ("type_info"), 1);
|
||||
pop_namespace ();
|
||||
tinfo_decl_type =
|
||||
build_qualified_type (type_info_type_node, TYPE_QUAL_CONST);
|
||||
type_info_ptr_type =
|
||||
build_pointer_type
|
||||
(build_qualified_type (type_info_type_node, TYPE_QUAL_CONST));
|
||||
|
||||
create_tinfo_types ();
|
||||
}
|
||||
|
||||
/* Given the expression EXP of type `class *', return the head of the
|
||||
@ -183,13 +223,12 @@ get_tinfo_decl_dynamic (exp)
|
||||
/* The RTTI information is at index -1. */
|
||||
index = integer_minus_one_node;
|
||||
t = build_vtbl_ref (exp, index);
|
||||
TREE_TYPE (t) = build_pointer_type (tinfo_decl_type);
|
||||
TREE_TYPE (t) = type_info_ptr_type;
|
||||
return t;
|
||||
}
|
||||
|
||||
/* otherwise return the type_info for the static type of the expr. */
|
||||
exp = get_tinfo_decl (TYPE_MAIN_VARIANT (type));
|
||||
return build_unary_op (ADDR_EXPR, exp, 0);
|
||||
/* Otherwise return the type_info for the static type of the expr. */
|
||||
return get_tinfo_ptr (TYPE_MAIN_VARIANT (type));
|
||||
}
|
||||
|
||||
static bool
|
||||
@ -263,9 +302,9 @@ tinfo_name (type)
|
||||
return name_string;
|
||||
}
|
||||
|
||||
/* Returns a decl for the type_info variable for TYPE. You must
|
||||
arrange that the decl is mark_used, if actually use it --- decls in
|
||||
vtables are only used if the vtable is output. */
|
||||
/* Return a VAR_DECL for the internal ABI defined type_info object for
|
||||
TYPE. You must arrange that the decl is mark_used, if actually use
|
||||
it --- decls in vtables are only used if the vtable is output. */
|
||||
|
||||
tree
|
||||
get_tinfo_decl (type)
|
||||
@ -278,7 +317,7 @@ get_tinfo_decl (type)
|
||||
&& TREE_CODE (TYPE_SIZE (type)) != INTEGER_CST)
|
||||
{
|
||||
error ("cannot create type information for type `%T' because its size is variable",
|
||||
type);
|
||||
type);
|
||||
return error_mark_node;
|
||||
}
|
||||
|
||||
@ -291,37 +330,45 @@ get_tinfo_decl (type)
|
||||
name = mangle_typeinfo_for_type (type);
|
||||
|
||||
d = IDENTIFIER_GLOBAL_VALUE (name);
|
||||
if (d)
|
||||
/* OK */;
|
||||
else
|
||||
if (!d)
|
||||
{
|
||||
/* The tinfo decl is the type_info object itself. We make all
|
||||
tinfo objects look as type_info, even though they will end up
|
||||
being a subclass of that when emitted. This means that we'll
|
||||
erroneously think we know the dynamic type -- be careful in the
|
||||
runtime. */
|
||||
d = build_lang_decl (VAR_DECL, name, tinfo_decl_type);
|
||||
tree var_desc = get_pseudo_ti_desc (type);
|
||||
|
||||
d = build_lang_decl (VAR_DECL, name, TINFO_PSEUDO_TYPE (var_desc));
|
||||
|
||||
DECL_ARTIFICIAL (d) = 1;
|
||||
DECL_ALIGN (d) = TYPE_ALIGN (ptr_type_node);
|
||||
DECL_USER_ALIGN (d) = 0;
|
||||
TREE_READONLY (d) = 1;
|
||||
TREE_STATIC (d) = 1;
|
||||
DECL_EXTERNAL (d) = 1;
|
||||
TREE_PUBLIC (d) = 1;
|
||||
if (flag_weak || !typeinfo_in_lib_p (type))
|
||||
comdat_linkage (d);
|
||||
SET_DECL_ASSEMBLER_NAME (d, name);
|
||||
DECL_COMDAT (d) = 1;
|
||||
cp_finish_decl (d, NULL_TREE, NULL_TREE, 0);
|
||||
|
||||
pushdecl_top_level (d);
|
||||
|
||||
/* Remember the type it is for. */
|
||||
TREE_TYPE (name) = type;
|
||||
TREE_USED (name) = 1;
|
||||
}
|
||||
|
||||
return d;
|
||||
}
|
||||
|
||||
/* Return a pointer to a type_info object describing TYPE, suitably
|
||||
cast to the language defined type. */
|
||||
|
||||
static tree
|
||||
get_tinfo_ptr (type)
|
||||
tree type;
|
||||
{
|
||||
tree exp = get_tinfo_decl (type);
|
||||
|
||||
/* Convert to type_info type. */
|
||||
exp = build_unary_op (ADDR_EXPR, exp, 0);
|
||||
exp = ocp_convert (type_info_ptr_type, exp, CONV_REINTERPRET, 0);
|
||||
|
||||
return exp;
|
||||
}
|
||||
|
||||
/* Return the type_info object for TYPE. */
|
||||
|
||||
tree
|
||||
@ -350,7 +397,7 @@ get_typeid (type)
|
||||
if (!type)
|
||||
return error_mark_node;
|
||||
|
||||
return get_tinfo_decl (type);
|
||||
return build_indirect_ref (get_tinfo_ptr (type), NULL);
|
||||
}
|
||||
|
||||
/* Check whether TEST is null before returning RESULT. If TEST is used in
|
||||
@ -683,6 +730,7 @@ tinfo_base_init (desc, target)
|
||||
{
|
||||
tree init = NULL_TREE;
|
||||
tree name_decl;
|
||||
tree vtable_ptr;
|
||||
|
||||
{
|
||||
tree name_name;
|
||||
@ -710,12 +758,40 @@ tinfo_base_init (desc, target)
|
||||
cp_finish_decl (name_decl, name_string, NULL_TREE, 0);
|
||||
pushdecl_top_level (name_decl);
|
||||
}
|
||||
|
||||
if (TINFO_VTABLE_DECL (desc))
|
||||
|
||||
vtable_ptr = TINFO_VTABLE_DECL (desc);
|
||||
if (!vtable_ptr)
|
||||
{
|
||||
tree vtbl_ptr = TINFO_VTABLE_DECL (desc);
|
||||
init = tree_cons (NULL_TREE, vtbl_ptr, init);
|
||||
tree real_type;
|
||||
|
||||
push_nested_namespace (abi_node);
|
||||
real_type = xref_tag (class_type_node, TINFO_REAL_NAME (desc), 1);
|
||||
pop_nested_namespace (abi_node);
|
||||
|
||||
if (!COMPLETE_TYPE_P (real_type))
|
||||
{
|
||||
/* We never saw a definition of this type, so we need to
|
||||
tell the compiler that this is an exported class, as
|
||||
indeed all of the __*_type_info classes are. */
|
||||
SET_CLASSTYPE_INTERFACE_KNOWN (real_type);
|
||||
CLASSTYPE_INTERFACE_ONLY (real_type) = 1;
|
||||
}
|
||||
|
||||
vtable_ptr = get_vtable_decl (real_type, /*complete=*/1);
|
||||
vtable_ptr = build_unary_op (ADDR_EXPR, vtable_ptr, 0);
|
||||
|
||||
/* We need to point into the middle of the vtable. */
|
||||
vtable_ptr = build
|
||||
(PLUS_EXPR, TREE_TYPE (vtable_ptr), vtable_ptr,
|
||||
size_binop (MULT_EXPR,
|
||||
size_int (2),
|
||||
TYPE_SIZE_UNIT (vtable_entry_type)));
|
||||
TREE_CONSTANT (vtable_ptr) = 1;
|
||||
|
||||
TINFO_VTABLE_DECL (desc) = vtable_ptr;
|
||||
}
|
||||
|
||||
init = tree_cons (NULL_TREE, vtable_ptr, init);
|
||||
|
||||
init = tree_cons (NULL_TREE, decay_conversion (name_decl), init);
|
||||
|
||||
@ -764,8 +840,7 @@ ptr_initializer (desc, target, non_public_ptr)
|
||||
}
|
||||
init = tree_cons (NULL_TREE, build_int_2 (flags, 0), init);
|
||||
init = tree_cons (NULL_TREE,
|
||||
build_unary_op (ADDR_EXPR,
|
||||
get_tinfo_decl (TYPE_MAIN_VARIANT (to)), 0),
|
||||
get_tinfo_ptr (TYPE_MAIN_VARIANT (to)),
|
||||
init);
|
||||
|
||||
init = build (CONSTRUCTOR, NULL_TREE, NULL_TREE, nreverse (init));
|
||||
@ -802,12 +877,11 @@ ptm_initializer (desc, target, non_public_ptr)
|
||||
}
|
||||
init = tree_cons (NULL_TREE, build_int_2 (flags, 0), init);
|
||||
init = tree_cons (NULL_TREE,
|
||||
build_unary_op (ADDR_EXPR,
|
||||
get_tinfo_decl (TYPE_MAIN_VARIANT (to)), 0),
|
||||
get_tinfo_ptr (TYPE_MAIN_VARIANT (to)),
|
||||
init);
|
||||
init = tree_cons (NULL_TREE,
|
||||
build_unary_op (ADDR_EXPR, get_tinfo_decl (klass), 0),
|
||||
init);
|
||||
get_tinfo_ptr (klass),
|
||||
init);
|
||||
|
||||
init = build (CONSTRUCTOR, NULL_TREE, NULL_TREE, nreverse (init));
|
||||
TREE_HAS_CONSTRUCTOR (init) = TREE_CONSTANT (init) = TREE_STATIC (init) = 1;
|
||||
@ -928,77 +1002,63 @@ typeinfo_in_lib_p (type)
|
||||
}
|
||||
}
|
||||
|
||||
/* Generate a pseudo_type_info VAR_DECL suitable for the supplied
|
||||
TARGET_TYPE and given the REAL_NAME. This is the structure expected by
|
||||
the runtime, and therefore has additional fields. If we need not emit a
|
||||
definition (because the runtime must contain it), return NULL_TREE,
|
||||
otherwise return the VAR_DECL. */
|
||||
/* Generate the initializer for the type info describing
|
||||
TYPE. VAR_DESC is a . NON_PUBLIC_P is set non-zero, if the VAR_DECL
|
||||
should not be exported from this object file. This should only be
|
||||
called at the end of translation, when we know that no further
|
||||
types will be completed. */
|
||||
|
||||
static tree
|
||||
synthesize_tinfo_var (target_type, real_name)
|
||||
tree target_type;
|
||||
tree real_name;
|
||||
get_pseudo_ti_init (type, var_desc, non_public_p)
|
||||
tree type;
|
||||
tree var_desc;
|
||||
int *non_public_p;
|
||||
{
|
||||
tree var_init = NULL_TREE;
|
||||
tree var_type = NULL_TREE;
|
||||
int non_public = 0;
|
||||
|
||||
switch (TREE_CODE (target_type))
|
||||
my_friendly_assert (at_eof, 20021120);
|
||||
switch (TREE_CODE (type))
|
||||
{
|
||||
case POINTER_TYPE:
|
||||
if (TYPE_PTRMEM_P (target_type))
|
||||
{
|
||||
var_type = ptm_desc_type_node;
|
||||
var_init = ptm_initializer (var_type, target_type, &non_public);
|
||||
}
|
||||
if (TYPE_PTRMEM_P (type))
|
||||
return ptm_initializer (var_desc, type, non_public_p);
|
||||
else
|
||||
{
|
||||
if (typeinfo_in_lib_p (target_type) && !doing_runtime)
|
||||
/* These are in the runtime. */
|
||||
return NULL_TREE;
|
||||
var_type = ptr_desc_type_node;
|
||||
var_init = ptr_initializer (var_type, target_type, &non_public);
|
||||
}
|
||||
return ptr_initializer (var_desc, type, non_public_p);
|
||||
break;
|
||||
case ENUMERAL_TYPE:
|
||||
var_type = enum_desc_type_node;
|
||||
var_init = generic_initializer (var_type, target_type);
|
||||
return generic_initializer (var_desc, type);
|
||||
break;
|
||||
case FUNCTION_TYPE:
|
||||
var_type = func_desc_type_node;
|
||||
var_init = generic_initializer (var_type, target_type);
|
||||
return generic_initializer (var_desc, type);
|
||||
break;
|
||||
case ARRAY_TYPE:
|
||||
var_type = ary_desc_type_node;
|
||||
var_init = generic_initializer (var_type, target_type);
|
||||
return generic_initializer (var_desc, type);
|
||||
break;
|
||||
case UNION_TYPE:
|
||||
case RECORD_TYPE:
|
||||
if (TYPE_PTRMEMFUNC_P (target_type))
|
||||
if (TYPE_PTRMEMFUNC_P (type))
|
||||
return ptm_initializer (var_desc, type, non_public_p);
|
||||
else if (var_desc == class_desc_type_node)
|
||||
{
|
||||
var_type = ptm_desc_type_node;
|
||||
var_init = ptm_initializer (var_type, target_type, &non_public);
|
||||
}
|
||||
else if (!COMPLETE_TYPE_P (target_type))
|
||||
{
|
||||
/* Emit a non-public class_type_info. */
|
||||
non_public = 1;
|
||||
var_type = class_desc_type_node;
|
||||
var_init = class_initializer (var_type, target_type, NULL_TREE);
|
||||
}
|
||||
else if (!CLASSTYPE_N_BASECLASSES (target_type))
|
||||
{
|
||||
var_type = class_desc_type_node;
|
||||
var_init = class_initializer (var_type, target_type, NULL_TREE);
|
||||
if (!COMPLETE_TYPE_P (type))
|
||||
/* Emit a non-public class_type_info. */
|
||||
*non_public_p = 1;
|
||||
return class_initializer (var_desc, type, NULL_TREE);
|
||||
}
|
||||
else if (var_desc == si_class_desc_type_node)
|
||||
{
|
||||
tree base_binfos = BINFO_BASETYPES (TYPE_BINFO (type));
|
||||
tree base_binfo = TREE_VEC_ELT (base_binfos, 0);
|
||||
tree tinfo = get_tinfo_ptr (BINFO_TYPE (base_binfo));
|
||||
tree base_inits = tree_cons (NULL_TREE, tinfo, NULL_TREE);
|
||||
|
||||
return class_initializer (var_desc, type, base_inits);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* if this has a single public non-virtual base, it's easier */
|
||||
tree binfo = TYPE_BINFO (target_type);
|
||||
int hint = class_hint_flags (type);
|
||||
tree binfo = TYPE_BINFO (type);
|
||||
int nbases = BINFO_N_BASETYPES (binfo);
|
||||
tree base_binfos = BINFO_BASETYPES (binfo);
|
||||
tree base_inits = NULL_TREE;
|
||||
int is_simple = nbases == 1;
|
||||
int ix;
|
||||
|
||||
/* Generate the base information initializer. */
|
||||
@ -1012,28 +1072,19 @@ synthesize_tinfo_var (target_type, real_name)
|
||||
|
||||
if (TREE_PUBLIC (base_binfo))
|
||||
flags |= 2;
|
||||
tinfo = get_tinfo_decl (BINFO_TYPE (base_binfo));
|
||||
tinfo = build_unary_op (ADDR_EXPR, tinfo, 0);
|
||||
tinfo = get_tinfo_ptr (BINFO_TYPE (base_binfo));
|
||||
if (TREE_VIA_VIRTUAL (base_binfo))
|
||||
{
|
||||
/* We store the vtable offset at which the virtual
|
||||
base offset can be found. */
|
||||
offset = BINFO_VPTR_FIELD (binfo_for_vbase (BINFO_TYPE (base_binfo),
|
||||
target_type));
|
||||
offset = BINFO_VPTR_FIELD
|
||||
(binfo_for_vbase (BINFO_TYPE (base_binfo), type));
|
||||
offset = convert (sizetype, offset);
|
||||
flags |= 1;
|
||||
}
|
||||
else
|
||||
offset = BINFO_OFFSET (base_binfo);
|
||||
|
||||
/* is it a single public inheritance? */
|
||||
if (is_simple && flags == 2 && integer_zerop (offset))
|
||||
{
|
||||
base_inits = tree_cons (NULL_TREE, tinfo, NULL_TREE);
|
||||
break;
|
||||
}
|
||||
is_simple = 0;
|
||||
|
||||
/* combine offset and flags into one field */
|
||||
offset = cp_build_binary_op (LSHIFT_EXPR, offset,
|
||||
build_int_2 (8, 0));
|
||||
@ -1044,86 +1095,23 @@ synthesize_tinfo_var (target_type, real_name)
|
||||
base_init = build (CONSTRUCTOR, NULL_TREE, NULL_TREE, base_init);
|
||||
base_inits = tree_cons (NULL_TREE, base_init, base_inits);
|
||||
}
|
||||
|
||||
if (is_simple)
|
||||
var_type = si_class_desc_type_node;
|
||||
else
|
||||
{
|
||||
int hint = class_hint_flags (target_type);
|
||||
|
||||
base_inits = build (CONSTRUCTOR, NULL_TREE, NULL_TREE, base_inits);
|
||||
base_inits = tree_cons (NULL_TREE, base_inits, NULL_TREE);
|
||||
/* Prepend the number of bases. */
|
||||
base_inits = tree_cons (NULL_TREE,
|
||||
build_int_2 (nbases, 0), base_inits);
|
||||
/* Prepend the hint flags. */
|
||||
base_inits = tree_cons (NULL_TREE,
|
||||
build_int_2 (hint, 0), base_inits);
|
||||
var_type = get_vmi_pseudo_type_info (nbases);
|
||||
}
|
||||
var_init = class_initializer (var_type, target_type, base_inits);
|
||||
base_inits = build (CONSTRUCTOR,
|
||||
NULL_TREE, NULL_TREE, base_inits);
|
||||
base_inits = tree_cons (NULL_TREE, base_inits, NULL_TREE);
|
||||
/* Prepend the number of bases. */
|
||||
base_inits = tree_cons (NULL_TREE,
|
||||
build_int_2 (nbases, 0), base_inits);
|
||||
/* Prepend the hint flags. */
|
||||
base_inits = tree_cons (NULL_TREE,
|
||||
build_int_2 (hint, 0), base_inits);
|
||||
|
||||
return class_initializer (var_desc, type, base_inits);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
if (typeinfo_in_lib_p (target_type))
|
||||
{
|
||||
if (!doing_runtime)
|
||||
/* These are guaranteed to be in the runtime. */
|
||||
return NULL_TREE;
|
||||
var_type = bltn_desc_type_node;
|
||||
var_init = generic_initializer (var_type, target_type);
|
||||
break;
|
||||
}
|
||||
abort ();
|
||||
return generic_initializer (var_desc, type);
|
||||
}
|
||||
|
||||
return create_real_tinfo_var (target_type,
|
||||
real_name, TINFO_PSEUDO_TYPE (var_type),
|
||||
var_init, non_public);
|
||||
}
|
||||
|
||||
/* Create the real typeinfo variable. NON_PUBLIC indicates that we cannot
|
||||
make this variable public (comdat). */
|
||||
|
||||
static tree
|
||||
create_real_tinfo_var (target_type, name, type, init, non_public)
|
||||
tree target_type;
|
||||
tree name;
|
||||
tree type;
|
||||
tree init;
|
||||
int non_public;
|
||||
{
|
||||
static int count = 0;
|
||||
tree decl;
|
||||
tree hidden_name;
|
||||
char hidden[30];
|
||||
|
||||
/* We cannot give this the name NAME, as that already is globally
|
||||
bound to the tinfo_decl we originally created for this type in
|
||||
get_tinfo_decl. */
|
||||
sprintf (hidden, "__ti_%d", count++);
|
||||
hidden_name = get_identifier (hidden);
|
||||
|
||||
decl = build_lang_decl (VAR_DECL, hidden_name,
|
||||
build_qualified_type (type, TYPE_QUAL_CONST));
|
||||
DECL_ARTIFICIAL (decl) = 1;
|
||||
TREE_READONLY (decl) = 1;
|
||||
TREE_STATIC (decl) = 1;
|
||||
DECL_EXTERNAL (decl) = 0;
|
||||
|
||||
if (!non_public)
|
||||
{
|
||||
TREE_PUBLIC (decl) = 1;
|
||||
if (flag_weak || !typeinfo_in_lib_p (target_type))
|
||||
comdat_linkage (decl);
|
||||
}
|
||||
SET_DECL_ASSEMBLER_NAME (decl, name);
|
||||
DECL_INITIAL (decl) = init;
|
||||
cp_finish_decl (decl, init, NULL_TREE, 0);
|
||||
pushdecl_top_level (decl);
|
||||
TREE_USED (decl) = 1;
|
||||
return decl;
|
||||
}
|
||||
|
||||
/* Generate the RECORD_TYPE containing the data layout of a type_info
|
||||
@ -1132,7 +1120,10 @@ create_real_tinfo_var (target_type, name, type, init, non_public)
|
||||
type's vtable. We explicitly manage the vtable member, and name it for
|
||||
real type as used in the runtime. The RECORD type has a different name,
|
||||
to avoid collisions. Return a TREE_LIST who's TINFO_PSEUDO_TYPE
|
||||
is the generated type and TINFO_VTABLE_DECL is the vtable decl.
|
||||
is the generated type and TINFO_VTABLE_NAME is the name of the
|
||||
vtable. We have to delay generating the VAR_DECL of the vtable
|
||||
until the end of the translation, when we'll have seen the library
|
||||
definition, if there was one.
|
||||
|
||||
REAL_NAME is the runtime's name of the type. Trailing arguments are
|
||||
additional FIELD_DECL's for the structure. The final argument must be
|
||||
@ -1141,9 +1132,8 @@ create_real_tinfo_var (target_type, name, type, init, non_public)
|
||||
static tree
|
||||
create_pseudo_type_info VPARAMS((const char *real_name, int ident, ...))
|
||||
{
|
||||
tree real_type, pseudo_type;
|
||||
tree pseudo_type;
|
||||
char *pseudo_name;
|
||||
tree vtable_decl;
|
||||
int ix;
|
||||
tree fields[10];
|
||||
tree field_decl;
|
||||
@ -1160,29 +1150,6 @@ create_pseudo_type_info VPARAMS((const char *real_name, int ident, ...))
|
||||
if (ident)
|
||||
sprintf (pseudo_name + strlen (pseudo_name), "%d", ident);
|
||||
|
||||
/* Get the vtable decl. */
|
||||
real_type = xref_tag (class_type_node, get_identifier (real_name), 1);
|
||||
if (! TYPE_SIZE (real_type))
|
||||
{
|
||||
/* We never saw a definition of this type, so we need to tell the
|
||||
compiler that this is an exported class, as indeed all of the
|
||||
__*_type_info classes are. */
|
||||
SET_CLASSTYPE_INTERFACE_KNOWN (real_type);
|
||||
CLASSTYPE_INTERFACE_ONLY (real_type) = 1;
|
||||
}
|
||||
|
||||
vtable_decl = get_vtable_decl (real_type, /*complete=*/1);
|
||||
vtable_decl = build_unary_op (ADDR_EXPR, vtable_decl, 0);
|
||||
|
||||
/* We need to point into the middle of the vtable. */
|
||||
vtable_decl = build (PLUS_EXPR,
|
||||
TREE_TYPE (vtable_decl),
|
||||
vtable_decl,
|
||||
size_binop (MULT_EXPR,
|
||||
size_int (2),
|
||||
TYPE_SIZE_UNIT (vtable_entry_type)));
|
||||
TREE_CONSTANT (vtable_decl) = 1;
|
||||
|
||||
/* First field is the pseudo type_info base class. */
|
||||
fields[0] = build_decl (FIELD_DECL, NULL_TREE, ti_desc_type_node);
|
||||
|
||||
@ -1196,53 +1163,96 @@ create_pseudo_type_info VPARAMS((const char *real_name, int ident, ...))
|
||||
TYPE_HAS_CONSTRUCTOR (pseudo_type) = 1;
|
||||
|
||||
result = tree_cons (NULL_TREE, NULL_TREE, NULL_TREE);
|
||||
TINFO_VTABLE_DECL (result) = vtable_decl;
|
||||
TINFO_PSEUDO_TYPE (result) = pseudo_type;
|
||||
TINFO_REAL_NAME (result) = get_identifier (real_name);
|
||||
TINFO_PSEUDO_TYPE (result) =
|
||||
cp_build_qualified_type (pseudo_type, TYPE_QUAL_CONST);
|
||||
|
||||
VA_CLOSE (ap);
|
||||
return result;
|
||||
}
|
||||
|
||||
/* Return a descriptor for a vmi type with NUM_BASES bases. */
|
||||
/* Return a pseudo type info type node used to describe TYPE. TYPE
|
||||
must be a complete type (or cv void), except at the end of the
|
||||
translation unit. */
|
||||
|
||||
static tree
|
||||
get_vmi_pseudo_type_info (num_bases)
|
||||
int num_bases;
|
||||
get_pseudo_ti_desc (type)
|
||||
tree type;
|
||||
{
|
||||
tree desc;
|
||||
tree array_domain, base_array;
|
||||
|
||||
if (TREE_VEC_LENGTH (vmi_class_desc_type_node) <= num_bases)
|
||||
switch (TREE_CODE (type))
|
||||
{
|
||||
int ix;
|
||||
tree extend = make_tree_vec (num_bases + 5);
|
||||
|
||||
for (ix = TREE_VEC_LENGTH (vmi_class_desc_type_node); ix--;)
|
||||
TREE_VEC_ELT (extend, ix) = TREE_VEC_ELT (vmi_class_desc_type_node, ix);
|
||||
vmi_class_desc_type_node = extend;
|
||||
case POINTER_TYPE:
|
||||
return TYPE_PTRMEM_P (type) ? ptm_desc_type_node : ptr_desc_type_node;
|
||||
case ENUMERAL_TYPE:
|
||||
return enum_desc_type_node;
|
||||
case FUNCTION_TYPE:
|
||||
return func_desc_type_node;
|
||||
case ARRAY_TYPE:
|
||||
return ary_desc_type_node;
|
||||
case UNION_TYPE:
|
||||
case RECORD_TYPE:
|
||||
if (TYPE_PTRMEMFUNC_P (type))
|
||||
return ptm_desc_type_node;
|
||||
else if (!COMPLETE_TYPE_P (type))
|
||||
{
|
||||
my_friendly_assert (at_eof, 20020609);
|
||||
return class_desc_type_node;
|
||||
}
|
||||
else if (!CLASSTYPE_N_BASECLASSES (type))
|
||||
return class_desc_type_node;
|
||||
else
|
||||
{
|
||||
tree base_binfo =
|
||||
TREE_VEC_ELT (BINFO_BASETYPES (TYPE_BINFO (type)), 0);
|
||||
int num_bases = BINFO_N_BASETYPES (TYPE_BINFO (type));
|
||||
|
||||
if (num_bases == 1
|
||||
&& TREE_PUBLIC (base_binfo)
|
||||
&& !TREE_VIA_VIRTUAL (base_binfo)
|
||||
&& integer_zerop (BINFO_OFFSET (base_binfo)))
|
||||
/* single non-virtual public. */
|
||||
return si_class_desc_type_node;
|
||||
else
|
||||
{
|
||||
tree var_desc;
|
||||
tree array_domain, base_array;
|
||||
|
||||
if (TREE_VEC_LENGTH (vmi_class_desc_type_node) <= num_bases)
|
||||
{
|
||||
int ix;
|
||||
tree extend = make_tree_vec (num_bases + 5);
|
||||
|
||||
for (ix = TREE_VEC_LENGTH (vmi_class_desc_type_node); ix--;)
|
||||
TREE_VEC_ELT (extend, ix)
|
||||
= TREE_VEC_ELT (vmi_class_desc_type_node, ix);
|
||||
vmi_class_desc_type_node = extend;
|
||||
}
|
||||
var_desc = TREE_VEC_ELT (vmi_class_desc_type_node, num_bases);
|
||||
if (var_desc)
|
||||
return var_desc;
|
||||
|
||||
/* Add number of bases and trailing array of
|
||||
base_class_type_info. */
|
||||
array_domain = build_index_type (size_int (num_bases));
|
||||
base_array =
|
||||
build_array_type (base_desc_type_node, array_domain);
|
||||
|
||||
push_nested_namespace (abi_node);
|
||||
var_desc = create_pseudo_type_info
|
||||
("__vmi_class_type_info", num_bases,
|
||||
build_decl (FIELD_DECL, NULL_TREE, integer_type_node),
|
||||
build_decl (FIELD_DECL, NULL_TREE, integer_type_node),
|
||||
build_decl (FIELD_DECL, NULL_TREE, base_array),
|
||||
NULL);
|
||||
pop_nested_namespace (abi_node);
|
||||
|
||||
TREE_VEC_ELT (vmi_class_desc_type_node, num_bases) = var_desc;
|
||||
return var_desc;
|
||||
}
|
||||
}
|
||||
default:
|
||||
return bltn_desc_type_node;
|
||||
}
|
||||
desc = TREE_VEC_ELT (vmi_class_desc_type_node, num_bases);
|
||||
|
||||
if (desc)
|
||||
return desc;
|
||||
|
||||
/* Add number of bases and trailing array of base_class_type_info. */
|
||||
array_domain = build_index_type (size_int (num_bases));
|
||||
base_array = build_array_type (base_desc_type_node, array_domain);
|
||||
|
||||
push_nested_namespace (abi_node);
|
||||
|
||||
desc = create_pseudo_type_info
|
||||
("__vmi_class_type_info", num_bases,
|
||||
build_decl (FIELD_DECL, NULL_TREE, integer_type_node),
|
||||
build_decl (FIELD_DECL, NULL_TREE, integer_type_node),
|
||||
build_decl (FIELD_DECL, NULL_TREE, base_array),
|
||||
NULL);
|
||||
|
||||
pop_nested_namespace (abi_node);
|
||||
|
||||
TREE_VEC_ELT (vmi_class_desc_type_node, num_bases) = desc;
|
||||
return desc;
|
||||
}
|
||||
|
||||
/* Make sure the required builtin types exist for generating the type_info
|
||||
@ -1251,15 +1261,9 @@ get_vmi_pseudo_type_info (num_bases)
|
||||
static void
|
||||
create_tinfo_types ()
|
||||
{
|
||||
tree ptr_type_info;
|
||||
|
||||
if (bltn_desc_type_node)
|
||||
return;
|
||||
push_nested_namespace (abi_node);
|
||||
my_friendly_assert (!ti_desc_type_node, 20020609);
|
||||
|
||||
ptr_type_info = build_pointer_type
|
||||
(build_qualified_type
|
||||
(type_info_type_node, TYPE_QUAL_CONST));
|
||||
push_nested_namespace (abi_node);
|
||||
|
||||
/* Create the internal type_info structure. This is used as a base for
|
||||
the other structures. */
|
||||
@ -1299,7 +1303,7 @@ create_tinfo_types ()
|
||||
This is really a descendant of __class_type_info. */
|
||||
si_class_desc_type_node = create_pseudo_type_info
|
||||
("__si_class_type_info", 0,
|
||||
build_decl (FIELD_DECL, NULL_TREE, ptr_type_info),
|
||||
build_decl (FIELD_DECL, NULL_TREE, type_info_ptr_type),
|
||||
NULL);
|
||||
|
||||
/* Base class internal helper. Pointer to base type, offset to base,
|
||||
@ -1307,7 +1311,7 @@ create_tinfo_types ()
|
||||
{
|
||||
tree fields[2];
|
||||
|
||||
fields[0] = build_decl (FIELD_DECL, NULL_TREE, ptr_type_info);
|
||||
fields[0] = build_decl (FIELD_DECL, NULL_TREE, type_info_ptr_type);
|
||||
fields[1] = build_decl (FIELD_DECL, NULL_TREE, integer_types[itk_long]);
|
||||
base_desc_type_node = make_aggr_type (RECORD_TYPE);
|
||||
finish_builtin_type (base_desc_type_node, "__base_class_type_info_pseudo",
|
||||
@ -1324,7 +1328,7 @@ create_tinfo_types ()
|
||||
ptr_desc_type_node = create_pseudo_type_info
|
||||
("__pointer_type_info", 0,
|
||||
build_decl (FIELD_DECL, NULL_TREE, integer_type_node),
|
||||
build_decl (FIELD_DECL, NULL_TREE, ptr_type_info),
|
||||
build_decl (FIELD_DECL, NULL_TREE, type_info_ptr_type),
|
||||
NULL);
|
||||
|
||||
/* Pointer to member data type_info. Add qualifications flags,
|
||||
@ -1333,8 +1337,8 @@ create_tinfo_types ()
|
||||
ptm_desc_type_node = create_pseudo_type_info
|
||||
("__pointer_to_member_type_info", 0,
|
||||
build_decl (FIELD_DECL, NULL_TREE, integer_type_node),
|
||||
build_decl (FIELD_DECL, NULL_TREE, ptr_type_info),
|
||||
build_decl (FIELD_DECL, NULL_TREE, ptr_type_info),
|
||||
build_decl (FIELD_DECL, NULL_TREE, type_info_ptr_type),
|
||||
build_decl (FIELD_DECL, NULL_TREE, type_info_ptr_type),
|
||||
NULL);
|
||||
|
||||
pop_nested_namespace (abi_node);
|
||||
@ -1401,75 +1405,61 @@ emit_support_tinfos ()
|
||||
definition emitted for it. */
|
||||
|
||||
int
|
||||
tinfo_decl_p (t, data)
|
||||
unemitted_tinfo_decl_p (t, data)
|
||||
tree t;
|
||||
void *data ATTRIBUTE_UNUSED;
|
||||
{
|
||||
return TREE_CODE (t) == VAR_DECL
|
||||
&& IDENTIFIER_GLOBAL_VALUE (DECL_NAME (t)) == (t)
|
||||
&& TREE_TYPE (t) == tinfo_decl_type
|
||||
&& TREE_TYPE (DECL_NAME (t));
|
||||
if (/* It's a var decl */
|
||||
TREE_CODE (t) == VAR_DECL
|
||||
/* whos name points back to itself */
|
||||
&& IDENTIFIER_GLOBAL_VALUE (DECL_NAME (t)) == t
|
||||
/* whos name's type is non-null */
|
||||
&& TREE_TYPE (DECL_NAME (t))
|
||||
/* and whos type is a struct */
|
||||
&& TREE_CODE (TREE_TYPE (t)) == RECORD_TYPE
|
||||
/* with a first field of our pseudo type info */
|
||||
&& TREE_TYPE (TYPE_FIELDS (TREE_TYPE (t))) == ti_desc_type_node)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Emit a suitable type_info definition for the type_info decl pointed to by
|
||||
DECL_PTR. We emit a completely new variable, of the correct type for the
|
||||
actual type this is describing. The DECL_ASSEMBLER_NAME of the generated
|
||||
definition is set to that of the supplied decl, so that they can be tied
|
||||
up. Mark the supplied decl as having been dealt with. Emitting one
|
||||
definition might cause other definitions to be required.
|
||||
|
||||
We need to do things this way, because we're trying to do something like
|
||||
|
||||
struct B : A {
|
||||
...
|
||||
};
|
||||
|
||||
extern const A tinfo_var;
|
||||
|
||||
const B tinfo_var = {...};
|
||||
|
||||
which is not permitted. Also, we've not necessarily seen the definition of B.
|
||||
So we do something like the following,
|
||||
|
||||
extern const A tinfo_var;
|
||||
|
||||
struct pseudo_A {
|
||||
const void *vtable_ptr;
|
||||
const char *name;
|
||||
};
|
||||
struct pseudo_B {
|
||||
pseudo_A base;
|
||||
...
|
||||
};
|
||||
|
||||
const pseudo_B proxy_tinfo_var attribute((assembler_name="tinfo_var")) =
|
||||
{
|
||||
{&B::vtable, "..."},
|
||||
...
|
||||
};
|
||||
|
||||
pseudo_A and pseudo_B must be layout equivalent to the real definitions in
|
||||
the runtime. */
|
||||
/* Finish a type info decl. DECL_PTR is a pointer to an unemitted
|
||||
tinfo decl. Determine whether it needs emitting, and if so
|
||||
generate the initializer. */
|
||||
|
||||
int
|
||||
emit_tinfo_decl (decl_ptr, data)
|
||||
tree *decl_ptr;
|
||||
void *data ATTRIBUTE_UNUSED;
|
||||
{
|
||||
tree tinfo_decl = *decl_ptr;
|
||||
tree tinfo_type, decl;
|
||||
tree decl = *decl_ptr;
|
||||
tree type = TREE_TYPE (DECL_NAME (decl));
|
||||
int non_public;
|
||||
int in_library = typeinfo_in_lib_p (type);
|
||||
tree var_desc, var_init;
|
||||
|
||||
my_friendly_assert (TREE_TYPE (tinfo_decl) == tinfo_decl_type, 20000121);
|
||||
tinfo_type = TREE_TYPE (DECL_NAME (tinfo_decl));
|
||||
my_friendly_assert (tinfo_type != NULL_TREE, 20000120);
|
||||
|
||||
if (!DECL_NEEDED_P (tinfo_decl))
|
||||
import_export_tinfo (decl, type, in_library);
|
||||
if (DECL_REALLY_EXTERN (decl) || !DECL_NEEDED_P (decl))
|
||||
return 0;
|
||||
|
||||
if (!doing_runtime && in_library)
|
||||
return 0;
|
||||
|
||||
non_public = 0;
|
||||
var_desc = get_pseudo_ti_desc (type);
|
||||
var_init = get_pseudo_ti_init (type, var_desc, &non_public);
|
||||
|
||||
DECL_EXTERNAL (decl) = 0;
|
||||
TREE_PUBLIC (decl) = !non_public;
|
||||
if (non_public)
|
||||
DECL_COMDAT (decl) = 0;
|
||||
|
||||
DECL_INITIAL (decl) = var_init;
|
||||
cp_finish_decl (decl, var_init, NULL_TREE, 0);
|
||||
/* cp_finish_decl will have dealt with linkage. */
|
||||
|
||||
/* Say we've dealt with it. */
|
||||
TREE_TYPE (DECL_NAME (tinfo_decl)) = NULL_TREE;
|
||||
|
||||
create_tinfo_types ();
|
||||
decl = synthesize_tinfo_var (tinfo_type, DECL_ASSEMBLER_NAME (tinfo_decl));
|
||||
|
||||
return decl != 0;
|
||||
TREE_TYPE (DECL_NAME (decl)) = NULL_TREE;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
@ -100,7 +100,6 @@ static tree dfs_push_decls PARAMS ((tree, void *));
|
||||
static tree dfs_unuse_fields PARAMS ((tree, void *));
|
||||
static tree add_conversions PARAMS ((tree, void *));
|
||||
static int covariant_return_p PARAMS ((tree, tree));
|
||||
static int check_final_overrider PARAMS ((tree, tree));
|
||||
static int look_for_overrides_r PARAMS ((tree, tree));
|
||||
static struct search_level *push_search_level
|
||||
PARAMS ((struct stack_level *, struct obstack *));
|
||||
@ -1800,7 +1799,7 @@ covariant_return_p (brettype, drettype)
|
||||
/* Check that virtual overrider OVERRIDER is acceptable for base function
|
||||
BASEFN. Issue diagnostic, and return zero, if unacceptable. */
|
||||
|
||||
static int
|
||||
int
|
||||
check_final_overrider (overrider, basefn)
|
||||
tree overrider, basefn;
|
||||
{
|
||||
|
@ -1,6 +1,6 @@
|
||||
/* Language-dependent node constructors for parse phase of GNU compiler.
|
||||
Copyright (C) 1987, 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
|
||||
1999, 2000, 2001 Free Software Foundation, Inc.
|
||||
1999, 2000, 2001, 2002 Free Software Foundation, Inc.
|
||||
Hacked by Michael Tiemann (tiemann@cygnus.com)
|
||||
|
||||
This file is part of GNU CC.
|
||||
@ -1898,6 +1898,27 @@ pod_type_p (t)
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Returns 1 iff zero initialization of type T means actually storing
|
||||
zeros in it. */
|
||||
|
||||
int
|
||||
zero_init_p (t)
|
||||
tree t;
|
||||
{
|
||||
t = strip_array_types (t);
|
||||
|
||||
/* NULL pointers to data members are initialized with -1. */
|
||||
if (TYPE_PTRMEM_P (t))
|
||||
return 0;
|
||||
|
||||
/* Classes that contain types that can't be zero-initialized, cannot
|
||||
be zero-initialized themselves. */
|
||||
if (CLASS_TYPE_P (t) && CLASSTYPE_NON_ZERO_INIT_P (t))
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Table of valid C++ attributes. */
|
||||
const struct attribute_spec cp_attribute_table[] =
|
||||
{
|
||||
@ -2147,7 +2168,8 @@ cp_cannot_inline_tree_fn (fnp)
|
||||
&& TI_PENDING_TEMPLATE_FLAG (DECL_TEMPLATE_INFO (fn)))
|
||||
{
|
||||
fn = *fnp = instantiate_decl (fn, /*defer_ok=*/0);
|
||||
return TI_PENDING_TEMPLATE_FLAG (DECL_TEMPLATE_INFO (fn));
|
||||
if (TI_PENDING_TEMPLATE_FLAG (DECL_TEMPLATE_INFO (fn)))
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (varargs_function_p (fn))
|
||||
@ -2262,6 +2284,11 @@ cp_copy_res_decl_for_inlining (result, fn, caller, decl_map_,
|
||||
DECL_SOURCE_FILE (var) = DECL_SOURCE_FILE (nrv);
|
||||
DECL_SOURCE_LINE (var) = DECL_SOURCE_LINE (nrv);
|
||||
DECL_ABSTRACT_ORIGIN (var) = DECL_ORIGIN (nrv);
|
||||
/* Don't lose initialization info. */
|
||||
DECL_INITIAL (var) = DECL_INITIAL (nrv);
|
||||
/* Don't forget that it needs to go in the stack. */
|
||||
TREE_ADDRESSABLE (var) = TREE_ADDRESSABLE (nrv);
|
||||
|
||||
splay_tree_insert (decl_map,
|
||||
(splay_tree_key) nrv,
|
||||
(splay_tree_value) var);
|
||||
|
@ -4806,9 +4806,6 @@ mark_addressable (exp)
|
||||
{
|
||||
register tree x = exp;
|
||||
|
||||
if (TREE_ADDRESSABLE (x) == 1)
|
||||
return 1;
|
||||
|
||||
while (1)
|
||||
switch (TREE_CODE (x))
|
||||
{
|
||||
@ -4827,6 +4824,8 @@ mark_addressable (exp)
|
||||
TREE_ADDRESSABLE (x) = 1; /* so compiler doesn't die later */
|
||||
return 1;
|
||||
}
|
||||
/* FALLTHRU */
|
||||
|
||||
case VAR_DECL:
|
||||
/* Caller should not be trying to mark initialized
|
||||
constant fields addressable. */
|
||||
@ -4834,6 +4833,7 @@ mark_addressable (exp)
|
||||
|| DECL_IN_AGGR_P (x) == 0
|
||||
|| TREE_STATIC (x)
|
||||
|| DECL_EXTERNAL (x), 314);
|
||||
/* FALLTHRU */
|
||||
|
||||
case CONST_DECL:
|
||||
case RESULT_DECL:
|
||||
@ -4842,6 +4842,7 @@ mark_addressable (exp)
|
||||
warning ("address requested for `%D', which is declared `register'",
|
||||
x);
|
||||
TREE_ADDRESSABLE (x) = 1;
|
||||
put_var_into_stack (x);
|
||||
return 1;
|
||||
|
||||
case FUNCTION_DECL:
|
||||
@ -5449,7 +5450,10 @@ build_modify_expr (lhs, modifycode, rhs)
|
||||
so the code to compute it is only emitted once. */
|
||||
tree cond;
|
||||
|
||||
rhs = save_expr (rhs);
|
||||
if (lvalue_p (rhs))
|
||||
rhs = stabilize_reference (rhs);
|
||||
else
|
||||
rhs = save_expr (rhs);
|
||||
|
||||
/* Check this here to avoid odd errors when trying to convert
|
||||
a throw to the type of the COND_EXPR. */
|
||||
|
@ -1,7 +1,7 @@
|
||||
/* Report error messages, build initializers, and perform
|
||||
some front-end optimizations for C++ compiler.
|
||||
Copyright (C) 1987, 1988, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
|
||||
1999, 2000 Free Software Foundation, Inc.
|
||||
1999, 2000, 2001, 2002 Free Software Foundation, Inc.
|
||||
Hacked by Michael Tiemann (tiemann@cygnus.com)
|
||||
|
||||
This file is part of GNU CC.
|
||||
@ -196,7 +196,8 @@ incomplete_type_error (value, type)
|
||||
return;
|
||||
|
||||
if (value != 0 && (TREE_CODE (value) == VAR_DECL
|
||||
|| TREE_CODE (value) == PARM_DECL))
|
||||
|| TREE_CODE (value) == PARM_DECL
|
||||
|| TREE_CODE (value) == FIELD_DECL))
|
||||
{
|
||||
cp_error_at ("`%D' has incomplete type", value);
|
||||
decl = 1;
|
||||
@ -211,7 +212,10 @@ retry:
|
||||
case ENUMERAL_TYPE:
|
||||
if (!decl)
|
||||
error ("invalid use of undefined type `%#T'", type);
|
||||
cp_error_at ("forward declaration of `%#T'", type);
|
||||
if (!TYPE_TEMPLATE_INFO (type))
|
||||
cp_error_at ("forward declaration of `%#T'", type);
|
||||
else
|
||||
cp_error_at ("declaration of `%#T'", type);
|
||||
break;
|
||||
|
||||
case VOID_TYPE:
|
||||
@ -420,6 +424,28 @@ store_init_value (decl, init)
|
||||
DECL_INITIAL (decl) = value;
|
||||
return NULL_TREE;
|
||||
}
|
||||
|
||||
/* Same as store_init_value, but used for known-to-be-valid static
|
||||
initializers. Used to introduce a static initializer even in data
|
||||
structures that may require dynamic initialization. */
|
||||
|
||||
tree
|
||||
force_store_init_value (decl, init)
|
||||
tree decl, init;
|
||||
{
|
||||
tree type = TREE_TYPE (decl);
|
||||
int needs_constructing = TYPE_NEEDS_CONSTRUCTING (type);
|
||||
|
||||
TYPE_NEEDS_CONSTRUCTING (type) = 0;
|
||||
|
||||
init = store_init_value (decl, init);
|
||||
if (init)
|
||||
abort ();
|
||||
|
||||
TYPE_NEEDS_CONSTRUCTING (type) = needs_constructing;
|
||||
|
||||
return init;
|
||||
}
|
||||
|
||||
/* Digest the parser output INIT as an initializer for type TYPE.
|
||||
Return a C expression of type TYPE to represent the initial value.
|
||||
@ -732,6 +758,8 @@ process_init_constructor (type, init, elts)
|
||||
next1 = build (CONSTRUCTOR, NULL_TREE, NULL_TREE, NULL_TREE);
|
||||
next1 = digest_init (TREE_TYPE (type), next1, 0);
|
||||
}
|
||||
else if (! zero_init_p (TREE_TYPE (type)))
|
||||
next1 = build_forced_zero_init (TREE_TYPE (type));
|
||||
else
|
||||
/* The default zero-initialization is fine for us; don't
|
||||
add anything to the CONSTRUCTOR. */
|
||||
@ -848,9 +876,12 @@ process_init_constructor (type, init, elts)
|
||||
&& (!init || TREE_HAS_CONSTRUCTOR (init)))
|
||||
warning ("missing initializer for member `%D'", field);
|
||||
|
||||
/* The default zero-initialization is fine for us; don't
|
||||
add anything to the CONSTRUCTOR. */
|
||||
continue;
|
||||
if (! zero_init_p (TREE_TYPE (field)))
|
||||
next1 = build_forced_zero_init (TREE_TYPE (field));
|
||||
else
|
||||
/* The default zero-initialization is fine for us; don't
|
||||
add anything to the CONSTRUCTOR. */
|
||||
continue;
|
||||
}
|
||||
|
||||
if (next1 == error_mark_node)
|
||||
|
@ -310,9 +310,12 @@ stack_include_file (pfile, inc)
|
||||
sysp = MAX ((pfile->map ? pfile->map->sysp : 0),
|
||||
(inc->foundhere ? inc->foundhere->sysp : 0));
|
||||
|
||||
/* For -M, add the file to the dependencies on its first inclusion. */
|
||||
if (CPP_OPTION (pfile, print_deps) > sysp && !inc->include_count)
|
||||
deps_add_dep (pfile->deps, inc->name);
|
||||
/* Add the file to the dependencies on its first inclusion. */
|
||||
if (CPP_OPTION (pfile, print_deps) > !!sysp && !inc->include_count)
|
||||
{
|
||||
if (pfile->buffer || CPP_OPTION (pfile, deps_ignore_main_file) == 0)
|
||||
deps_add_dep (pfile->deps, inc->name);
|
||||
}
|
||||
|
||||
/* Not in cache? */
|
||||
if (! inc->buffer)
|
||||
|
@ -406,12 +406,17 @@ run_directive (pfile, dir_no, buf, count)
|
||||
{
|
||||
cpp_push_buffer (pfile, (const U_CHAR *) buf, count,
|
||||
/* from_stage3 */ true, 1);
|
||||
/* Disgusting hack. */
|
||||
if (dir_no == T_PRAGMA)
|
||||
pfile->buffer->inc = pfile->buffer->prev->inc;
|
||||
start_directive (pfile);
|
||||
/* We don't want a leading # to be interpreted as a directive. */
|
||||
pfile->buffer->saved_flags = 0;
|
||||
pfile->directive = &dtable[dir_no];
|
||||
(void) (*pfile->directive->handler) (pfile);
|
||||
end_directive (pfile, 1);
|
||||
if (dir_no == T_PRAGMA)
|
||||
pfile->buffer->inc = NULL;
|
||||
_cpp_pop_buffer (pfile);
|
||||
}
|
||||
|
||||
|
@ -279,6 +279,9 @@ struct cpp_options
|
||||
/* If true, fopen (deps_file, "a") else fopen (deps_file, "w"). */
|
||||
unsigned char print_deps_append;
|
||||
|
||||
/* If true, no dependency is generated on the main file. */
|
||||
unsigned char deps_ignore_main_file;
|
||||
|
||||
/* Nonzero means print names of header files (-H). */
|
||||
unsigned char print_include_names;
|
||||
|
||||
@ -335,6 +338,9 @@ struct cpp_options
|
||||
/* Nonzero for the 1999 C Standard, including corrigenda and amendments. */
|
||||
unsigned char c99;
|
||||
|
||||
/* Nonzero if conforming to some particular standard. */
|
||||
unsigned char std;
|
||||
|
||||
/* Nonzero means give all the error messages the ANSI standard requires. */
|
||||
unsigned char pedantic;
|
||||
|
||||
|
@ -613,7 +613,20 @@ collect_args (pfile, node)
|
||||
}
|
||||
|
||||
if (!error)
|
||||
return base_buff;
|
||||
{
|
||||
/* GCC has special semantics for , ## b where b is a varargs
|
||||
parameter: we remove the comma if b was omitted entirely.
|
||||
If b was merely an empty argument, the comma is retained.
|
||||
If the macro takes just one (varargs) parameter, then we
|
||||
retain the comma only if we are standards conforming.
|
||||
|
||||
If FIRST is NULL replace_args () swallows the comma. */
|
||||
if (macro->variadic && (argc < macro->paramc
|
||||
|| (argc == 1 && args[0].count == 0
|
||||
&& !CPP_OPTION (pfile, std))))
|
||||
args[macro->paramc - 1].first = NULL;
|
||||
return base_buff;
|
||||
}
|
||||
|
||||
_cpp_release_buff (pfile, base_buff);
|
||||
return NULL;
|
||||
@ -673,6 +686,8 @@ enter_macro_context (pfile, node)
|
||||
/* The presence of a macro invalidates a file's controlling macro. */
|
||||
pfile->mi_valid = false;
|
||||
|
||||
pfile->state.angled_headers = false;
|
||||
|
||||
/* Handle standard macros. */
|
||||
if (! (node->flags & NODE_BUILTIN))
|
||||
{
|
||||
@ -797,15 +812,13 @@ replace_args (pfile, node, args)
|
||||
count = arg->count, from = arg->first;
|
||||
if (dest != first)
|
||||
{
|
||||
/* GCC has special semantics for , ## b where b is a
|
||||
varargs parameter: the comma disappears if b was
|
||||
given no actual arguments (not merely if b is an
|
||||
empty argument); otherwise the paste flag is removed. */
|
||||
if (dest[-1]->type == CPP_COMMA
|
||||
&& macro->variadic
|
||||
&& src->val.arg_no == macro->paramc)
|
||||
{
|
||||
if (count == 0)
|
||||
/* Swallow a pasted comma if from == NULL, otherwise
|
||||
drop the paste flag. */
|
||||
if (from == NULL)
|
||||
dest--;
|
||||
else
|
||||
paste_flag = dest - 1;
|
||||
@ -1529,7 +1542,7 @@ cpp_macro_definition (pfile, node)
|
||||
}
|
||||
|
||||
/* Calculate length. */
|
||||
len = NODE_LEN (node) + 1; /* ' ' */
|
||||
len = NODE_LEN (node) + 2; /* ' ' and NUL. */
|
||||
if (macro->fun_like)
|
||||
{
|
||||
len += 4; /* "()" plus possible final ".." of named
|
||||
|
@ -2254,10 +2254,11 @@ canon_hash (x, mode)
|
||||
case REG:
|
||||
{
|
||||
unsigned int regno = REGNO (x);
|
||||
bool record;
|
||||
|
||||
/* On some machines, we can't record any non-fixed hard register,
|
||||
because extending its life will cause reload problems. We
|
||||
consider ap, fp, and sp to be fixed for this purpose.
|
||||
consider ap, fp, sp, gp to be fixed for this purpose.
|
||||
|
||||
We also consider CCmode registers to be fixed for this purpose;
|
||||
failure to do so leads to failure to simplify 0<100 type of
|
||||
@ -2267,16 +2268,28 @@ canon_hash (x, mode)
|
||||
Nor should we record any register that is in a small
|
||||
class, as defined by CLASS_LIKELY_SPILLED_P. */
|
||||
|
||||
if (regno < FIRST_PSEUDO_REGISTER
|
||||
&& (global_regs[regno]
|
||||
|| CLASS_LIKELY_SPILLED_P (REGNO_REG_CLASS (regno))
|
||||
|| (SMALL_REGISTER_CLASSES
|
||||
&& ! fixed_regs[regno]
|
||||
&& x != frame_pointer_rtx
|
||||
&& x != hard_frame_pointer_rtx
|
||||
&& x != arg_pointer_rtx
|
||||
&& x != stack_pointer_rtx
|
||||
&& GET_MODE_CLASS (GET_MODE (x)) != MODE_CC)))
|
||||
if (regno >= FIRST_PSEUDO_REGISTER)
|
||||
record = true;
|
||||
else if (x == frame_pointer_rtx
|
||||
|| x == hard_frame_pointer_rtx
|
||||
|| x == arg_pointer_rtx
|
||||
|| x == stack_pointer_rtx
|
||||
|| x == pic_offset_table_rtx)
|
||||
record = true;
|
||||
else if (global_regs[regno])
|
||||
record = false;
|
||||
else if (fixed_regs[regno])
|
||||
record = true;
|
||||
else if (GET_MODE_CLASS (GET_MODE (x)) == MODE_CC)
|
||||
record = true;
|
||||
else if (SMALL_REGISTER_CLASSES)
|
||||
record = false;
|
||||
else if (CLASS_LIKELY_SPILLED_P (REGNO_REG_CLASS (regno)))
|
||||
record = false;
|
||||
else
|
||||
record = true;
|
||||
|
||||
if (!record)
|
||||
{
|
||||
do_not_record = 1;
|
||||
return 0;
|
||||
@ -3464,7 +3477,9 @@ fold_rtx (x, insn)
|
||||
&& GET_CODE (elt->exp) != SIGN_EXTEND
|
||||
&& GET_CODE (elt->exp) != ZERO_EXTEND
|
||||
&& GET_CODE (XEXP (elt->exp, 0)) == SUBREG
|
||||
&& GET_MODE (SUBREG_REG (XEXP (elt->exp, 0))) == mode)
|
||||
&& GET_MODE (SUBREG_REG (XEXP (elt->exp, 0))) == mode
|
||||
&& (GET_MODE_CLASS (mode)
|
||||
== GET_MODE_CLASS (GET_MODE (XEXP (elt->exp, 0)))))
|
||||
{
|
||||
rtx op0 = SUBREG_REG (XEXP (elt->exp, 0));
|
||||
|
||||
@ -4906,7 +4921,10 @@ cse_insn (insn, libcall_insn)
|
||||
&& (tem = find_reg_note (insn, REG_EQUAL, NULL_RTX)) != 0
|
||||
&& (! rtx_equal_p (XEXP (tem, 0), SET_SRC (sets[0].rtl))
|
||||
|| GET_CODE (SET_DEST (sets[0].rtl)) == STRICT_LOW_PART))
|
||||
src_eqv = canon_reg (XEXP (tem, 0), NULL_RTX);
|
||||
{
|
||||
src_eqv = fold_rtx (canon_reg (XEXP (tem, 0), NULL_RTX), insn);
|
||||
XEXP (tem, 0) = src_eqv;
|
||||
}
|
||||
|
||||
/* Canonicalize sources and addresses of destinations.
|
||||
We do this in a separate pass to avoid problems when a MATCH_DUP is
|
||||
@ -5010,7 +5028,6 @@ cse_insn (insn, libcall_insn)
|
||||
eqvmode = GET_MODE (SUBREG_REG (XEXP (dest, 0)));
|
||||
do_not_record = 0;
|
||||
hash_arg_in_memory = 0;
|
||||
src_eqv = fold_rtx (src_eqv, insn);
|
||||
src_eqv_hash = HASH (src_eqv, eqvmode);
|
||||
|
||||
/* Find the equivalence class for the equivalent expression. */
|
||||
|
@ -104,6 +104,10 @@ static int n_useless_values;
|
||||
static varray_type reg_values;
|
||||
#define REG_VALUES(I) VARRAY_ELT_LIST (reg_values, (I))
|
||||
|
||||
/* The largest number of hard regs used by any entry added to the
|
||||
REG_VALUES table. Cleared on each clear_table() invocation. */
|
||||
static unsigned int max_value_regs;
|
||||
|
||||
/* Here the set of indices I with REG_VALUES(I) != 0 is saved. This is used
|
||||
in clear_table() for fast emptying. */
|
||||
static varray_type used_regs;
|
||||
@ -227,6 +231,8 @@ clear_table (clear_all)
|
||||
for (i = 0; i < VARRAY_ACTIVE_SIZE (used_regs); i++)
|
||||
REG_VALUES (VARRAY_UINT (used_regs, i)) = 0;
|
||||
|
||||
max_value_regs = 0;
|
||||
|
||||
VARRAY_POP_ALL (used_regs);
|
||||
|
||||
htab_empty (hash_table);
|
||||
@ -897,6 +903,14 @@ cselib_lookup (x, mode, create)
|
||||
if (! create)
|
||||
return 0;
|
||||
|
||||
if (i < FIRST_PSEUDO_REGISTER)
|
||||
{
|
||||
unsigned int n = HARD_REGNO_NREGS (i, mode);
|
||||
|
||||
if (n > max_value_regs)
|
||||
max_value_regs = n;
|
||||
}
|
||||
|
||||
e = new_cselib_val (++next_unknown_value, GET_MODE (x));
|
||||
e->locs = new_elt_loc_list (e->locs, x);
|
||||
if (REG_VALUES (i) == 0)
|
||||
@ -957,11 +971,22 @@ cselib_invalidate_regno (regno, mode)
|
||||
pseudos, only REGNO is affected. For hard regs, we must take MODE
|
||||
into account, and we must also invalidate lower register numbers
|
||||
if they contain values that overlap REGNO. */
|
||||
endregno = regno + 1;
|
||||
if (regno < FIRST_PSEUDO_REGISTER && mode != VOIDmode)
|
||||
endregno = regno + HARD_REGNO_NREGS (regno, mode);
|
||||
{
|
||||
if (regno < max_value_regs)
|
||||
i = 0;
|
||||
else
|
||||
i = regno - max_value_regs;
|
||||
|
||||
for (i = 0; i < endregno; i++)
|
||||
endregno = regno + HARD_REGNO_NREGS (regno, mode);
|
||||
}
|
||||
else
|
||||
{
|
||||
i = regno;
|
||||
endregno = regno + 1;
|
||||
}
|
||||
|
||||
for (; i < endregno; i++)
|
||||
{
|
||||
struct elt_list **l = ®_VALUES (i);
|
||||
|
||||
@ -1171,6 +1196,14 @@ cselib_record_set (dest, src_elt, dest_addr_elt)
|
||||
if (REG_VALUES (dreg) == 0)
|
||||
VARRAY_PUSH_UINT (used_regs, dreg);
|
||||
|
||||
if (dreg < FIRST_PSEUDO_REGISTER)
|
||||
{
|
||||
unsigned int n = HARD_REGNO_NREGS (dreg, GET_MODE (dest));
|
||||
|
||||
if (n > max_value_regs)
|
||||
max_value_regs = n;
|
||||
}
|
||||
|
||||
REG_VALUES (dreg) = new_elt_list (REG_VALUES (dreg), src_elt);
|
||||
if (src_elt->locs == 0)
|
||||
n_useless_values--;
|
||||
|
@ -462,4 +462,10 @@ You Lose! You must define PREFERRED_DEBUGGING_TYPE!
|
||||
#define MODE_BASE_REG_CLASS(MODE) BASE_REG_CLASS
|
||||
#endif
|
||||
|
||||
/* Determine whether __cxa_atexit, rather than atexit, is used to
|
||||
register C++ destructors for local statics and global objects. */
|
||||
#ifndef DEFAULT_USE_CXA_ATEXIT
|
||||
#define DEFAULT_USE_CXA_ATEXIT 0
|
||||
#endif
|
||||
|
||||
#endif /* ! GCC_DEFAULTS_H */
|
||||
|
@ -38,7 +38,8 @@ Alasdair Baird for various bugfixes.
|
||||
Gerald Baumgartner added the signature extension to the C++ front end.
|
||||
|
||||
@item
|
||||
Neil Booth for various work on cpplib.
|
||||
Neil Booth for work on cpplib, lang hooks, debug hooks and other
|
||||
miscellaneous clean-ups.
|
||||
|
||||
@item
|
||||
Per Bothner for his direction via the steering committee and various
|
||||
|
@ -1676,6 +1676,15 @@ eprintf ("success!\n")
|
||||
@expansion{} fprintf(stderr, "success!\n");
|
||||
@end example
|
||||
|
||||
@noindent
|
||||
The above explanation is ambiguous about the case where the only macro
|
||||
parameter is a variable arguments parameter, as it is meaningless to
|
||||
try to distinguish whether no argument at all is an empty argument or
|
||||
a missing argument. In this case the C99 standard is clear that the
|
||||
comma must remain, however the existing GCC extension used to swallow
|
||||
the comma. So CPP retains the comma when conforming to a specific C
|
||||
standard, and drops it otherwise.
|
||||
|
||||
C99 mandates that the only place the identifier @code{@w{__VA_ARGS__}}
|
||||
can appear is in the replacement list of a variadic macro. It may not
|
||||
be used as a macro name, macro argument name, or within a different type
|
||||
|
@ -66,7 +66,8 @@ with an optional @option{-MT} switch too.
|
||||
This variable is the same as the environment variable
|
||||
@env{DEPENDENCIES_OUTPUT} (@pxref{DEPENDENCIES_OUTPUT}), except that
|
||||
system header files are not ignored, so it implies @option{-M} rather
|
||||
than @option{-MM}.
|
||||
than @option{-MM}. However, the dependence on the main input file is
|
||||
omitted.
|
||||
@ifset cppmanual
|
||||
@xref{Invocation}.
|
||||
@end ifset
|
||||
|
@ -4,7 +4,7 @@
|
||||
|
||||
@c Common values used in the GCC manuals:
|
||||
|
||||
@set version-GCC 3.1
|
||||
@set version-GCC 3.2
|
||||
|
||||
@c Common macros to support generating man pages:
|
||||
|
||||
|
@ -187,7 +187,7 @@ in the following sections.
|
||||
-fno-optional-diags -fpermissive @gol
|
||||
-frepo -fno-rtti -fstats -ftemplate-depth-@var{n} @gol
|
||||
-fuse-cxa-atexit -fvtable-gc -fno-weak -nostdinc++ @gol
|
||||
-fno-default-inline -Wctor-dtor-privacy @gol
|
||||
-fno-default-inline -Wabi -Wctor-dtor-privacy @gol
|
||||
-Wnon-virtual-dtor -Wreorder @gol
|
||||
-Weffc++ -Wno-deprecated @gol
|
||||
-Wno-non-template-friend -Wold-style-cast @gol
|
||||
@ -211,7 +211,7 @@ in the following sections.
|
||||
@xref{Warning Options,,Options to Request or Suppress Warnings}.
|
||||
@gccoptlist{
|
||||
-fsyntax-only -pedantic -pedantic-errors @gol
|
||||
-w -W -Wall -Waggregate-return @gol
|
||||
-w -W -Wall -Waggregate-return @gol
|
||||
-Wcast-align -Wcast-qual -Wchar-subscripts -Wcomment @gol
|
||||
-Wconversion -Wno-deprecated-declarations @gol
|
||||
-Wdisabled-optimization -Wdiv-by-zero -Werror @gol
|
||||
@ -486,6 +486,7 @@ in the following sections.
|
||||
-mpush-args -maccumulate-outgoing-args -m128bit-long-double @gol
|
||||
-m96bit-long-double -mregparm=@var{num} -momit-leaf-frame-pointer @gol
|
||||
-mno-red-zone@gol
|
||||
-mcmodel=@var{code-model} @gol
|
||||
-m32 -m64}
|
||||
|
||||
@emph{HPPA Options}
|
||||
@ -1550,6 +1551,58 @@ Do not assume @samp{inline} for functions defined inside a class scope.
|
||||
functions will have linkage like inline functions; they just won't be
|
||||
inlined by default.
|
||||
|
||||
@item -Wabi @r{(C++ only)}
|
||||
@opindex Wabi
|
||||
Warn when G++ generates code that is probably not compatible with the
|
||||
vendor-neutral C++ ABI. Although an effort has been made to warn about
|
||||
all such cases, there are probably some cases that are not warned about,
|
||||
even though G++ is generating incompatible code. There may also be
|
||||
cases where warnings are emitted even though the code that is generated
|
||||
will be compatible.
|
||||
|
||||
You should rewrite your code to avoid these warnings if you are
|
||||
concerned about the fact that code generated by G++ may not be binary
|
||||
compatible with code generated by other compilers.
|
||||
|
||||
The known incompatibilites at this point include:
|
||||
|
||||
@itemize @bullet
|
||||
|
||||
@item
|
||||
Incorrect handling of tail-padding for bit-fields. G++ may attempt to
|
||||
pack data into the same byte as a base class. For example:
|
||||
|
||||
@smallexample
|
||||
struct A @{ virtual void f(); int f1 : 1; @};
|
||||
struct B : public A @{ int f2 : 1; @};
|
||||
@end smallexample
|
||||
|
||||
@noindent
|
||||
In this case, G++ will place @code{B::f2} into the same byte
|
||||
as@code{A::f1}; other compilers will not. You can avoid this problem
|
||||
by explicitly padding @code{A} so that its size is a multiple of the
|
||||
byte size on your platform; that will cause G++ and other compilers to
|
||||
layout @code{B} identically.
|
||||
|
||||
@item
|
||||
Incorrect handling of tail-padding for virtual bases. G++ does not use
|
||||
tail padding when laying out virtual bases. For example:
|
||||
|
||||
@smallexample
|
||||
struct A @{ virtual void f(); char c1; @};
|
||||
struct B @{ B(); char c2; @};
|
||||
struct C : public A, public virtual B @{@};
|
||||
@end smallexample
|
||||
|
||||
@noindent
|
||||
In this case, G++ will not place @code{B} into the tail-padding for
|
||||
@code{A}; other compilers will. You can avoid this problem by
|
||||
explicitly padding @code{A} so that its size is a multiple of its
|
||||
alignment (ignoring virtual base classes); that will cause G++ and other
|
||||
compilers to layout @code{C} identically.
|
||||
|
||||
@end itemize
|
||||
|
||||
@item -Wctor-dtor-privacy @r{(C++ only)}
|
||||
@opindex Wctor-dtor-privacy
|
||||
Warn when a class seems unusable, because all the constructors or
|
||||
@ -7415,6 +7468,10 @@ boundary. Aligning @code{double} variables on a two word boundary will
|
||||
produce code that runs somewhat faster on a @samp{Pentium} at the
|
||||
expense of more memory.
|
||||
|
||||
@strong{Warning:} if you use the @samp{-malign-double} switch,
|
||||
structures containing the above types will be aligned differently than
|
||||
the published application binary interface specifications for the 386.
|
||||
|
||||
@item -m128bit-long-double
|
||||
@opindex m128bit-long-double
|
||||
Control the size of @code{long double} type. i386 application binary interface
|
||||
@ -7594,6 +7651,32 @@ by the x86-64 ABI, it is a 128-byte area beyond the location of the
|
||||
stack pointer that will not be modified by signal or interrupt handlers
|
||||
and therefore can be used for temporary data without adjusting the stack
|
||||
pointer. The flag @option{-mno-red-zone} disables this red zone.
|
||||
|
||||
@item -mcmodel=small
|
||||
@opindex mcmodel=small
|
||||
Generate code for the small code model: the program and its symbols must
|
||||
be linked in the lower 2 GB of the address space. Pointers are 64 bits.
|
||||
Programs can be statically or dynamically linked. This is the default
|
||||
code model.
|
||||
|
||||
@item -mcmodel=kernel
|
||||
@opindex mcmodel=kernel
|
||||
Generate code for the kernel code model. The kernel runs in the
|
||||
negative 2 GB of the address space.
|
||||
This model has to be used for Linux kernel code.
|
||||
|
||||
@item -mcmodel=medium
|
||||
@opindex mcmodel=medium
|
||||
Generate code for the medium model: The program is linked in the lower 2
|
||||
GB of the address space but symbols can be located anywhere in the
|
||||
address space. Programs can be statically or dynamically linked, but
|
||||
building of shared libraries are not supported with the medium model.
|
||||
|
||||
@item -mcmodel=large
|
||||
@opindex mcmodel=large
|
||||
Generate code for the large model: This model makes no assumptions
|
||||
about addresses and sizes of sections. Currently GCC does not implement
|
||||
this model.
|
||||
@end table
|
||||
|
||||
@node HPPA Options
|
||||
|
@ -158,7 +158,9 @@ available in a particular run.
|
||||
For nameless patterns, the condition is applied only when matching an
|
||||
individual insn, and only after the insn has matched the pattern's
|
||||
recognition template. The insn's operands may be found in the vector
|
||||
@code{operands}.
|
||||
@code{operands}. For an insn where the condition has once matched, it
|
||||
can't be used to control register allocation, for example by excluding
|
||||
certain hard registers or hard register combinations.
|
||||
|
||||
@item
|
||||
The @dfn{output template}: a string that says how to output matching
|
||||
@ -1867,7 +1869,7 @@ A constant in the range supported by @code{movrcc} instructions
|
||||
|
||||
@item N
|
||||
Same as @samp{K}, except that it verifies that bits that are not in the
|
||||
lower 32-bits range are all zero. Must be used instead of @samp{K} for
|
||||
lower 32-bit range are all zero. Must be used instead of @samp{K} for
|
||||
modes wider than @code{SImode}
|
||||
|
||||
@item G
|
||||
|
@ -1072,9 +1072,11 @@ by the @code{__attribute__ ((aligned (@var{n})))} construct.
|
||||
@findex ADJUST_FIELD_ALIGN
|
||||
@item ADJUST_FIELD_ALIGN (@var{field}, @var{computed})
|
||||
An expression for the alignment of a structure field @var{field} if the
|
||||
alignment computed in the usual way is @var{computed}. GCC uses
|
||||
this value instead of the value in @code{BIGGEST_ALIGNMENT} or
|
||||
@code{BIGGEST_FIELD_ALIGNMENT}, if defined.
|
||||
alignment computed in the usual way (including applying of
|
||||
@code{BIGGEST_ALIGNMENT} and @code{BIGGEST_FIELD_ALIGNMENT} to the
|
||||
alignment) is @var{computed}. It overrides alignment only if the
|
||||
field alignment has not been set by the
|
||||
@code{__attribute__ ((aligned (@var{n})))} construct.
|
||||
|
||||
@findex MAX_OFILE_ALIGNMENT
|
||||
@item MAX_OFILE_ALIGNMENT
|
||||
@ -2454,14 +2456,14 @@ A C expression that is true if, for a register in
|
||||
@code{CLASS_CANNOT_CHANGE_MODE}, the requested mode punning is invalid.
|
||||
|
||||
For the example, loading 32-bit integer or floating-point objects into
|
||||
floating-point registers on the Alpha extends them to 64-bits.
|
||||
floating-point registers on the Alpha extends them to 64 bits.
|
||||
Therefore loading a 64-bit object and then storing it as a 32-bit object
|
||||
does not store the low-order 32-bits, as would be the case for a normal
|
||||
does not store the low-order 32 bits, as would be the case for a normal
|
||||
register. Therefore, @file{alpha.h} defines @code{CLASS_CANNOT_CHANGE_MODE}
|
||||
as @code{FLOAT_REGS} and @code{CLASS_CANNOT_CHANGE_MODE_P} restricts
|
||||
mode changes to same-size modes.
|
||||
|
||||
Compare this to IA-64, which extends floating-point values to 82-bits,
|
||||
Compare this to IA-64, which extends floating-point values to 82 bits,
|
||||
and stores 64-bit integers in a different format than 64-bit doubles.
|
||||
Therefore @code{CLASS_CANNOT_CHANGE_MODE_P} is always true.
|
||||
@end table
|
||||
|
@ -417,16 +417,17 @@ expand_builtin_init_dwarf_reg_sizes (address)
|
||||
rtx addr = expand_expr (address, NULL_RTX, VOIDmode, 0);
|
||||
rtx mem = gen_rtx_MEM (BLKmode, addr);
|
||||
|
||||
for (i = 0; i < DWARF_FRAME_REGISTERS; i++)
|
||||
{
|
||||
HOST_WIDE_INT offset = DWARF_FRAME_REGNUM (i) * GET_MODE_SIZE (mode);
|
||||
HOST_WIDE_INT size = GET_MODE_SIZE (reg_raw_mode[i]);
|
||||
for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
|
||||
if (DWARF_FRAME_REGNUM (i) < DWARF_FRAME_REGISTERS)
|
||||
{
|
||||
HOST_WIDE_INT offset = DWARF_FRAME_REGNUM (i) * GET_MODE_SIZE (mode);
|
||||
HOST_WIDE_INT size = GET_MODE_SIZE (reg_raw_mode[i]);
|
||||
|
||||
if (offset < 0)
|
||||
continue;
|
||||
if (offset < 0)
|
||||
continue;
|
||||
|
||||
emit_move_insn (adjust_address (mem, mode, offset), GEN_INT (size));
|
||||
}
|
||||
emit_move_insn (adjust_address (mem, mode, offset), GEN_INT (size));
|
||||
}
|
||||
}
|
||||
|
||||
/* Convert a DWARF call frame info. operation to its string name */
|
||||
@ -1943,7 +1944,8 @@ output_call_frame_info (for_eh)
|
||||
fde = &fde_table[i];
|
||||
|
||||
/* Don't emit EH unwind info for leaf functions that don't need it. */
|
||||
if (for_eh && fde->nothrow && ! fde->uses_eh_lsda)
|
||||
if (!flag_asynchronous_unwind_tables && for_eh && fde->nothrow
|
||||
&& ! fde->uses_eh_lsda)
|
||||
continue;
|
||||
|
||||
ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, FDE_LABEL, for_eh + i * 2);
|
||||
@ -7571,11 +7573,11 @@ modified_type_die (type, is_const_type, is_volatile_type, context_die)
|
||||
}
|
||||
|
||||
/* We want to equate the qualified type to the die below. */
|
||||
if (qualified_type)
|
||||
type = qualified_type;
|
||||
type = qualified_type;
|
||||
}
|
||||
|
||||
equate_type_number_to_die (type, mod_type_die);
|
||||
if (type)
|
||||
equate_type_number_to_die (type, mod_type_die);
|
||||
if (item_type)
|
||||
/* We must do this after the equate_type_number_to_die call, in case
|
||||
this is a recursive type. This ensures that the modified_type_die
|
||||
@ -8941,21 +8943,18 @@ rtl_for_decl_location (decl)
|
||||
== strlen (TREE_STRING_POINTER (init)) + 1))
|
||||
rtl = gen_rtx_CONST_STRING (VOIDmode, TREE_STRING_POINTER (init));
|
||||
}
|
||||
|
||||
#if 0
|
||||
/* We mustn't actually emit anything here, as we might not get a
|
||||
chance to emit any symbols we refer to. For the release, don't
|
||||
try to get this right. */
|
||||
if (rtl == NULL)
|
||||
/* If the initializer is something that we know will expand into an
|
||||
immediate RTL constant, expand it now. Expanding anything else
|
||||
tends to produce unresolved symbols; see debug/5770 and c++/6381. */
|
||||
else if (TREE_CODE (DECL_INITIAL (decl)) == INTEGER_CST
|
||||
|| TREE_CODE (DECL_INITIAL (decl)) == REAL_CST)
|
||||
{
|
||||
rtl = expand_expr (DECL_INITIAL (decl), NULL_RTX, VOIDmode,
|
||||
EXPAND_INITIALIZER);
|
||||
/* If expand_expr returned a MEM, we cannot use it, since
|
||||
it won't be output, leading to unresolved symbol. */
|
||||
/* If expand_expr returns a MEM, it wasn't immediate. */
|
||||
if (rtl && GET_CODE (rtl) == MEM)
|
||||
rtl = NULL;
|
||||
abort ();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef ASM_SIMPLIFY_DWARF_ADDR
|
||||
|
@ -34,6 +34,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
|
||||
#include "insn-config.h"
|
||||
#include "ggc.h"
|
||||
#include "recog.h"
|
||||
#include "langhooks.h"
|
||||
|
||||
static rtx break_out_memory_refs PARAMS ((rtx));
|
||||
static void emit_stack_probe PARAMS ((rtx));
|
||||
@ -285,20 +286,33 @@ rtx
|
||||
expr_size (exp)
|
||||
tree exp;
|
||||
{
|
||||
tree size;
|
||||
|
||||
if (TREE_CODE_CLASS (TREE_CODE (exp)) == 'd'
|
||||
&& DECL_SIZE_UNIT (exp) != 0)
|
||||
size = DECL_SIZE_UNIT (exp);
|
||||
else
|
||||
size = size_in_bytes (TREE_TYPE (exp));
|
||||
tree size = (*lang_hooks.expr_size) (exp);
|
||||
|
||||
if (TREE_CODE (size) != INTEGER_CST
|
||||
&& contains_placeholder_p (size))
|
||||
size = build (WITH_RECORD_EXPR, sizetype, size, exp);
|
||||
|
||||
return expand_expr (size, NULL_RTX, TYPE_MODE (sizetype), 0);
|
||||
}
|
||||
|
||||
/* Return a wide integer for the size in bytes of the value of EXP, or -1
|
||||
if the size can vary or is larger than an integer. */
|
||||
|
||||
HOST_WIDE_INT
|
||||
int_expr_size (exp)
|
||||
tree exp;
|
||||
{
|
||||
tree t = (*lang_hooks.expr_size) (exp);
|
||||
|
||||
if (t == 0
|
||||
|| TREE_CODE (t) != INTEGER_CST
|
||||
|| TREE_OVERFLOW (t)
|
||||
|| TREE_INT_CST_HIGH (t) != 0
|
||||
/* If the result would appear negative, it's too big to represent. */
|
||||
|| (HOST_WIDE_INT) TREE_INT_CST_LOW (t) < 0)
|
||||
return -1;
|
||||
|
||||
return TREE_INT_CST_LOW (t);
|
||||
}
|
||||
|
||||
/* Return a copy of X in which all memory references
|
||||
|
@ -3049,9 +3049,12 @@ expand_divmod (rem_flag, code, mode, op0, op1, target, unsignedp)
|
||||
not straightforward to generalize this. Maybe we should make an array
|
||||
of possible modes in init_expmed? Save this for GCC 2.7. */
|
||||
|
||||
optab1 = (op1_is_pow2 ? (unsignedp ? lshr_optab : ashr_optab)
|
||||
optab1 = ((op1_is_pow2 && op1 != const0_rtx)
|
||||
? (unsignedp ? lshr_optab : ashr_optab)
|
||||
: (unsignedp ? udiv_optab : sdiv_optab));
|
||||
optab2 = (op1_is_pow2 ? optab1 : (unsignedp ? udivmod_optab : sdivmod_optab));
|
||||
optab2 = ((op1_is_pow2 && op1 != const0_rtx)
|
||||
? optab1
|
||||
: (unsignedp ? udivmod_optab : sdivmod_optab));
|
||||
|
||||
for (compute_mode = mode; compute_mode != VOIDmode;
|
||||
compute_mode = GET_MODE_WIDER_MODE (compute_mode))
|
||||
@ -4136,6 +4139,12 @@ make_tree (type, x)
|
||||
build (TRUNC_DIV_EXPR, t,
|
||||
make_tree (t, XEXP (x, 0)),
|
||||
make_tree (t, XEXP (x, 1)))));
|
||||
|
||||
case SIGN_EXTEND:
|
||||
case ZERO_EXTEND:
|
||||
t = type_for_mode (GET_MODE (XEXP (x, 0)), GET_CODE (x) == ZERO_EXTEND);
|
||||
return fold (convert (type, make_tree (t, XEXP (x, 0))));
|
||||
|
||||
default:
|
||||
t = make_node (RTL_EXPR);
|
||||
TREE_TYPE (t) = type;
|
||||
|
@ -6661,8 +6661,7 @@ expand_expr (exp, target, tmode, modifier)
|
||||
* TYPE_QUAL_CONST))),
|
||||
0, TREE_ADDRESSABLE (exp), 1);
|
||||
|
||||
store_constructor (exp, target, 0,
|
||||
int_size_in_bytes (TREE_TYPE (exp)));
|
||||
store_constructor (exp, target, 0, int_expr_size (exp));
|
||||
return target;
|
||||
}
|
||||
|
||||
|
@ -548,6 +548,10 @@ extern unsigned int case_values_threshold PARAMS ((void));
|
||||
/* Return an rtx for the size in bytes of the value of an expr. */
|
||||
extern rtx expr_size PARAMS ((tree));
|
||||
|
||||
/* Return a wide integer for the size in bytes of the value of EXP, or -1
|
||||
if the size can vary or is larger than an integer. */
|
||||
extern HOST_WIDE_INT int_expr_size PARAMS ((tree));
|
||||
|
||||
extern rtx lookup_static_chain PARAMS ((tree));
|
||||
|
||||
/* Convert a stack slot address ADDR valid in function FNDECL
|
||||
|
@ -1,3 +1,42 @@
|
||||
2002-08-30 Alan Modra <amodra@bigpond.net.au>
|
||||
|
||||
* target.h (FFETARGET_32bit_longs): Don't define for powerpc64 or
|
||||
mmix.
|
||||
|
||||
2002-08-28 Joseph S. Myers <jsm@polyomino.org.uk>
|
||||
|
||||
* bugs.texi, news.texi: Update URLs for online news and bugs
|
||||
lists.
|
||||
|
||||
2002-08-14 Release Manager
|
||||
|
||||
* GCC 3.2 Released.
|
||||
|
||||
2002-08-04 Toon Moene <toon@moene.indiv.nluug.nl>
|
||||
|
||||
* news.texi: Mention nothing changed for 3.2.
|
||||
|
||||
Sun Aug 4 16:48:53 2002 Joseph S. Myers <jsm@polyomino.org.uk>
|
||||
|
||||
* root.texi (version-gcc): Increase to 3.2.
|
||||
|
||||
2002-07-25 Release Manager
|
||||
|
||||
* GCC 3.1.1 Released.
|
||||
|
||||
2002-06-30 Toon Moene <toon@moene.indiv.nluug.nl>
|
||||
|
||||
* news.texi: Mention 2 Gbyte limit on 32-bit targets
|
||||
for arrays explicitly in news on g77-3.1.
|
||||
|
||||
2002-05-14 Release Manager
|
||||
|
||||
* GCC 3.1 Released.
|
||||
|
||||
2002-05-14 Release Manager
|
||||
|
||||
* GCC 3.1 Released.
|
||||
|
||||
2002-04-29 Joseph S. Myers <jsm28@cam.ac.uk>
|
||||
|
||||
* invoke.texi: Use @gol at ends of lines inside @gccoptlist.
|
||||
|
@ -79,7 +79,7 @@ An online, ``live'' version of this document
|
||||
(derived directly from the mainline, development version
|
||||
of @code{g77} within @code{gcc})
|
||||
is available via
|
||||
@uref{http://www.gnu.org/software/gcc/onlinedocs/g77_bugs.html}.
|
||||
@uref{http://www.gnu.org/software/gcc/onlinedocs/g77/Trouble.html}.
|
||||
Follow the ``Known Bugs'' link.
|
||||
|
||||
The following information was last updated on @value{last-update-bugs}:
|
||||
|
@ -10,7 +10,7 @@
|
||||
@c in the standalone derivations of this file (e.g. NEWS).
|
||||
@set copyrights-news 1995,1996,1997,1998,1999,2000,2001,2002
|
||||
|
||||
@set last-update-news 2002-04-13
|
||||
@set last-update-news 2002-08-05
|
||||
|
||||
@include root.texi
|
||||
|
||||
@ -148,11 +148,17 @@ An online, ``live'' version of this document
|
||||
(derived directly from the mainline, development version
|
||||
of @command{g77} within @command{gcc})
|
||||
is available at
|
||||
@uref{http://www.gnu.org/software/gcc/onlinedocs/g77_news.html}.
|
||||
@uref{http://www.gnu.org/software/gcc/onlinedocs/g77/News.html}.
|
||||
@end ifclear
|
||||
|
||||
The following information was last updated on @value{last-update-news}:
|
||||
|
||||
@heading In @code{GCC} 3.2 versus @code{GCC} 3.1:
|
||||
@itemize @bullet
|
||||
@item
|
||||
Nothing.
|
||||
@end itemize
|
||||
|
||||
@heading In @code{GCC} 3.1 (formerly known as g77-0.5.27) versus @code{GCC} 3.0:
|
||||
@itemize @bullet
|
||||
@item
|
||||
@ -203,9 +209,10 @@ prog.f:2:
|
||||
^
|
||||
Array `a' at (^) is too large to handle
|
||||
@end smallexample
|
||||
because 140 000 000 reals is larger than the largest bit-extent that can be
|
||||
because 140 000 000 REALs is larger than the largest bit-extent that can be
|
||||
expressed in 32 bits. However, bit-sizes never play a role after offsets
|
||||
have been converted to byte addresses. Therefore this check has been removed.
|
||||
have been converted to byte addresses. Therefore this check has been removed,
|
||||
and the limit is now 2 Gbyte of memory (around 530 000 000 REALs).
|
||||
Note: On GNU/Linux systems one has to compile programs that occupy more
|
||||
than 1 Gbyte statically, i.e.@: @code{g77 -static ...}.
|
||||
|
||||
|
@ -3,7 +3,7 @@
|
||||
@c (e.g. a release branch in the CVS repository for gcc),
|
||||
@c clear this and set the version information correctly.
|
||||
@clear DEVELOPMENT
|
||||
@set version-gcc 3.1
|
||||
@set version-gcc 3.2
|
||||
|
||||
@set email-general gcc@@gcc.gnu.org
|
||||
@set email-help gcc-help@@gcc.gnu.org
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* target.h -- Public #include File (module.h template V1.0)
|
||||
Copyright (C) 1995, 1996 Free Software Foundation, Inc.
|
||||
Copyright (C) 1995, 1996, 2002 Free Software Foundation, Inc.
|
||||
Contributed by James Craig Burley.
|
||||
|
||||
This file is part of GNU Fortran.
|
||||
@ -234,7 +234,15 @@ the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
|
||||
#define FFETARGET_f2cTYLOGICAL2 13
|
||||
#define FFETARGET_f2cTYQUAD 14
|
||||
|
||||
#if !defined(__alpha__) && (!defined (_ARCH_PPC) || !defined (__64BIT__)) && (!defined(__sparc__) || (!defined(__sparcv9) && !defined(__arch64__))) && (!defined(__ia64__) || !defined(__LP64__)) && (!defined(__hppa__) || !defined(__LP64__)) && !defined(__s390x__) && !defined(__x86_64__)
|
||||
#if (!defined(__alpha__) \
|
||||
&& (!defined(__hppa__) || !defined(__LP64__)) \
|
||||
&& (!defined(__ia64__) || !defined(__LP64__)) \
|
||||
&& !defined(__MMIX__) \
|
||||
&& (!defined (_ARCH_PPC) || !defined (__64BIT__)) \
|
||||
&& !defined(__powerpc64__) \
|
||||
&& !defined(__s390x__) \
|
||||
&& (!defined(__sparc__) || (!defined(__sparcv9) && !defined(__arch64__)))\
|
||||
&& !defined(__x86_64__))
|
||||
#define FFETARGET_32bit_longs
|
||||
#endif
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
#include "ansidecl.h"
|
||||
#include "f/version.h"
|
||||
|
||||
const char *const ffe_version_string = "3.1 20020509 (prerelease)";
|
||||
const char *const ffe_version_string = "3.2.1 20020831 (prerelease)";
|
||||
|
@ -1626,7 +1626,42 @@ propagate_one_insn (pbi, insn)
|
||||
if (libcall_is_dead)
|
||||
prev = propagate_block_delete_libcall ( insn, note);
|
||||
else
|
||||
propagate_block_delete_insn (pbi->bb, insn);
|
||||
{
|
||||
|
||||
/* If INSN contains a RETVAL note and is dead, but the libcall
|
||||
as a whole is not dead, then we want to remove INSN, but
|
||||
not the whole libcall sequence.
|
||||
|
||||
However, we need to also remove the dangling REG_LIBCALL
|
||||
note so that we do not have mis-matched LIBCALL/RETVAL
|
||||
notes. In theory we could find a new location for the
|
||||
REG_RETVAL note, but it hardly seems worth the effort.
|
||||
|
||||
NOTE at this point will be the RETVAL note if it exists. */
|
||||
if (note)
|
||||
{
|
||||
rtx libcall_note;
|
||||
|
||||
libcall_note
|
||||
= find_reg_note (XEXP (note, 0), REG_LIBCALL, NULL_RTX);
|
||||
remove_note (XEXP (note, 0), libcall_note);
|
||||
}
|
||||
|
||||
/* Similarly if INSN contains a LIBCALL note, remove the
|
||||
dangling REG_RETVAL note. */
|
||||
note = find_reg_note (insn, REG_LIBCALL, NULL_RTX);
|
||||
if (note)
|
||||
{
|
||||
rtx retval_note;
|
||||
|
||||
retval_note
|
||||
= find_reg_note (XEXP (note, 0), REG_RETVAL, NULL_RTX);
|
||||
remove_note (XEXP (note, 0), retval_note);
|
||||
}
|
||||
|
||||
/* Now delete INSN. */
|
||||
propagate_block_delete_insn (pbi->bb, insn);
|
||||
}
|
||||
|
||||
return prev;
|
||||
}
|
||||
|
@ -4515,17 +4515,22 @@ extract_muldiv (t, c, code, wide_type)
|
||||
break;
|
||||
|
||||
case CONVERT_EXPR: case NON_LVALUE_EXPR: case NOP_EXPR:
|
||||
/* If op0 is an expression, and is unsigned, and the type is
|
||||
smaller than ctype, then we cannot widen the expression. */
|
||||
/* If op0 is an expression... */
|
||||
if ((TREE_CODE_CLASS (TREE_CODE (op0)) == '<'
|
||||
|| TREE_CODE_CLASS (TREE_CODE (op0)) == '1'
|
||||
|| TREE_CODE_CLASS (TREE_CODE (op0)) == '2'
|
||||
|| TREE_CODE_CLASS (TREE_CODE (op0)) == 'e')
|
||||
&& TREE_UNSIGNED (TREE_TYPE (op0))
|
||||
&& ! (TREE_CODE (TREE_TYPE (op0)) == INTEGER_TYPE
|
||||
&& TYPE_IS_SIZETYPE (TREE_TYPE (op0)))
|
||||
&& (GET_MODE_SIZE (TYPE_MODE (ctype))
|
||||
> GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (op0)))))
|
||||
/* ...and is unsigned, and its type is smaller than ctype,
|
||||
then we cannot pass through this widening. */
|
||||
&& ((TREE_UNSIGNED (TREE_TYPE (op0))
|
||||
&& ! (TREE_CODE (TREE_TYPE (op0)) == INTEGER_TYPE
|
||||
&& TYPE_IS_SIZETYPE (TREE_TYPE (op0)))
|
||||
&& (GET_MODE_SIZE (TYPE_MODE (ctype))
|
||||
> GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (op0)))))
|
||||
/* ...and its type is larger than ctype,
|
||||
then we cannot pass through this truncation. */
|
||||
|| (GET_MODE_SIZE (TYPE_MODE (ctype))
|
||||
< GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (op0))))))
|
||||
break;
|
||||
|
||||
/* Pass the constant down and see if we can make a simplification. If
|
||||
@ -6490,7 +6495,125 @@ fold (expr)
|
||||
}
|
||||
}
|
||||
|
||||
/* Change X >= CST to X > (CST - 1) if CST is positive. */
|
||||
/* Comparisons with the highest or lowest possible integer of
|
||||
the specified size will have known values and an unsigned
|
||||
<= 0x7fffffff can be simplified. */
|
||||
{
|
||||
int width = GET_MODE_BITSIZE (TYPE_MODE (TREE_TYPE (arg1)));
|
||||
|
||||
if (TREE_CODE (arg1) == INTEGER_CST
|
||||
&& ! TREE_CONSTANT_OVERFLOW (arg1)
|
||||
&& width <= HOST_BITS_PER_WIDE_INT
|
||||
&& (INTEGRAL_TYPE_P (TREE_TYPE (arg1))
|
||||
|| POINTER_TYPE_P (TREE_TYPE (arg1))))
|
||||
{
|
||||
if (TREE_INT_CST_HIGH (arg1) == 0
|
||||
&& (TREE_INT_CST_LOW (arg1)
|
||||
== ((unsigned HOST_WIDE_INT) 1 << (width - 1)) - 1)
|
||||
&& ! TREE_UNSIGNED (TREE_TYPE (arg1)))
|
||||
switch (TREE_CODE (t))
|
||||
{
|
||||
case GT_EXPR:
|
||||
return omit_one_operand (type,
|
||||
convert (type, integer_zero_node),
|
||||
arg0);
|
||||
case GE_EXPR:
|
||||
TREE_SET_CODE (t, EQ_EXPR);
|
||||
break;
|
||||
|
||||
case LE_EXPR:
|
||||
return omit_one_operand (type,
|
||||
convert (type, integer_one_node),
|
||||
arg0);
|
||||
case LT_EXPR:
|
||||
TREE_SET_CODE (t, NE_EXPR);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
else if (TREE_INT_CST_HIGH (arg1) == -1
|
||||
&& (TREE_INT_CST_LOW (arg1)
|
||||
== ((unsigned HOST_WIDE_INT) 1 << (width - 1)))
|
||||
&& ! TREE_UNSIGNED (TREE_TYPE (arg1)))
|
||||
switch (TREE_CODE (t))
|
||||
{
|
||||
case LT_EXPR:
|
||||
return omit_one_operand (type,
|
||||
convert (type, integer_zero_node),
|
||||
arg0);
|
||||
case LE_EXPR:
|
||||
TREE_SET_CODE (t, EQ_EXPR);
|
||||
break;
|
||||
|
||||
case GE_EXPR:
|
||||
return omit_one_operand (type,
|
||||
convert (type, integer_one_node),
|
||||
arg0);
|
||||
case GT_EXPR:
|
||||
TREE_SET_CODE (t, NE_EXPR);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
else if (TREE_INT_CST_HIGH (arg1) == 0
|
||||
&& (TREE_INT_CST_LOW (arg1)
|
||||
== ((unsigned HOST_WIDE_INT) 1 << (width - 1)) - 1)
|
||||
&& TREE_UNSIGNED (TREE_TYPE (arg1))
|
||||
/* signed_type does not work on pointer types. */
|
||||
&& INTEGRAL_TYPE_P (TREE_TYPE (arg1)))
|
||||
switch (TREE_CODE (t))
|
||||
{
|
||||
case LE_EXPR:
|
||||
return fold (build (GE_EXPR, type,
|
||||
convert (signed_type (TREE_TYPE (arg0)),
|
||||
arg0),
|
||||
convert (signed_type (TREE_TYPE (arg1)),
|
||||
integer_zero_node)));
|
||||
case GT_EXPR:
|
||||
return fold (build (LT_EXPR, type,
|
||||
convert (signed_type (TREE_TYPE (arg0)),
|
||||
arg0),
|
||||
convert (signed_type (TREE_TYPE (arg1)),
|
||||
integer_zero_node)));
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
else if (TREE_INT_CST_HIGH (arg1) == 0
|
||||
&& (TREE_INT_CST_LOW (arg1)
|
||||
== ((unsigned HOST_WIDE_INT) 2 << (width - 1)) - 1)
|
||||
&& TREE_UNSIGNED (TREE_TYPE (arg1)))
|
||||
switch (TREE_CODE (t))
|
||||
{
|
||||
case GT_EXPR:
|
||||
return omit_one_operand (type,
|
||||
convert (type, integer_zero_node),
|
||||
arg0);
|
||||
case GE_EXPR:
|
||||
TREE_SET_CODE (t, EQ_EXPR);
|
||||
break;
|
||||
|
||||
case LE_EXPR:
|
||||
return omit_one_operand (type,
|
||||
convert (type, integer_one_node),
|
||||
arg0);
|
||||
case LT_EXPR:
|
||||
TREE_SET_CODE (t, NE_EXPR);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Change X >= CST to X > (CST - 1) and X < CST to X <= (CST - 1)
|
||||
if CST is positive. */
|
||||
if (TREE_CODE (arg1) == INTEGER_CST
|
||||
&& TREE_CODE (arg0) != INTEGER_CST
|
||||
&& tree_int_cst_sgn (arg1) > 0)
|
||||
@ -6514,6 +6637,35 @@ fold (expr)
|
||||
}
|
||||
}
|
||||
|
||||
/* An unsigned comparison against 0 can be simplified. */
|
||||
if (integer_zerop (arg1)
|
||||
&& (INTEGRAL_TYPE_P (TREE_TYPE (arg1))
|
||||
|| POINTER_TYPE_P (TREE_TYPE (arg1)))
|
||||
&& TREE_UNSIGNED (TREE_TYPE (arg1)))
|
||||
{
|
||||
switch (TREE_CODE (t))
|
||||
{
|
||||
case GT_EXPR:
|
||||
code = NE_EXPR;
|
||||
TREE_SET_CODE (t, NE_EXPR);
|
||||
break;
|
||||
case LE_EXPR:
|
||||
code = EQ_EXPR;
|
||||
TREE_SET_CODE (t, EQ_EXPR);
|
||||
break;
|
||||
case GE_EXPR:
|
||||
return omit_one_operand (type,
|
||||
convert (type, integer_one_node),
|
||||
arg0);
|
||||
case LT_EXPR:
|
||||
return omit_one_operand (type,
|
||||
convert (type, integer_zero_node),
|
||||
arg0);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* If this is an EQ or NE comparison of a constant with a PLUS_EXPR or
|
||||
a MINUS_EXPR of a constant, we can convert it into a comparison with
|
||||
a revised constant as long as no overflow occurs. */
|
||||
@ -6702,152 +6854,6 @@ fold (expr)
|
||||
}
|
||||
}
|
||||
|
||||
/* An unsigned comparison against 0 can be simplified. */
|
||||
if (integer_zerop (arg1)
|
||||
&& (INTEGRAL_TYPE_P (TREE_TYPE (arg1))
|
||||
|| POINTER_TYPE_P (TREE_TYPE (arg1)))
|
||||
&& TREE_UNSIGNED (TREE_TYPE (arg1)))
|
||||
{
|
||||
switch (TREE_CODE (t))
|
||||
{
|
||||
case GT_EXPR:
|
||||
code = NE_EXPR;
|
||||
TREE_SET_CODE (t, NE_EXPR);
|
||||
break;
|
||||
case LE_EXPR:
|
||||
code = EQ_EXPR;
|
||||
TREE_SET_CODE (t, EQ_EXPR);
|
||||
break;
|
||||
case GE_EXPR:
|
||||
return omit_one_operand (type,
|
||||
convert (type, integer_one_node),
|
||||
arg0);
|
||||
case LT_EXPR:
|
||||
return omit_one_operand (type,
|
||||
convert (type, integer_zero_node),
|
||||
arg0);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Comparisons with the highest or lowest possible integer of
|
||||
the specified size will have known values and an unsigned
|
||||
<= 0x7fffffff can be simplified. */
|
||||
{
|
||||
int width = GET_MODE_BITSIZE (TYPE_MODE (TREE_TYPE (arg1)));
|
||||
|
||||
if (TREE_CODE (arg1) == INTEGER_CST
|
||||
&& ! TREE_CONSTANT_OVERFLOW (arg1)
|
||||
&& width <= HOST_BITS_PER_WIDE_INT
|
||||
&& (INTEGRAL_TYPE_P (TREE_TYPE (arg1))
|
||||
|| POINTER_TYPE_P (TREE_TYPE (arg1))))
|
||||
{
|
||||
if (TREE_INT_CST_HIGH (arg1) == 0
|
||||
&& (TREE_INT_CST_LOW (arg1)
|
||||
== ((unsigned HOST_WIDE_INT) 1 << (width - 1)) - 1)
|
||||
&& ! TREE_UNSIGNED (TREE_TYPE (arg1)))
|
||||
switch (TREE_CODE (t))
|
||||
{
|
||||
case GT_EXPR:
|
||||
return omit_one_operand (type,
|
||||
convert (type, integer_zero_node),
|
||||
arg0);
|
||||
case GE_EXPR:
|
||||
TREE_SET_CODE (t, EQ_EXPR);
|
||||
break;
|
||||
|
||||
case LE_EXPR:
|
||||
return omit_one_operand (type,
|
||||
convert (type, integer_one_node),
|
||||
arg0);
|
||||
case LT_EXPR:
|
||||
TREE_SET_CODE (t, NE_EXPR);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
else if (TREE_INT_CST_HIGH (arg1) == -1
|
||||
&& (TREE_INT_CST_LOW (arg1)
|
||||
== ((unsigned HOST_WIDE_INT) 1 << (width - 1)))
|
||||
&& ! TREE_UNSIGNED (TREE_TYPE (arg1)))
|
||||
switch (TREE_CODE (t))
|
||||
{
|
||||
case LT_EXPR:
|
||||
return omit_one_operand (type,
|
||||
convert (type, integer_zero_node),
|
||||
arg0);
|
||||
case LE_EXPR:
|
||||
TREE_SET_CODE (t, EQ_EXPR);
|
||||
break;
|
||||
|
||||
case GE_EXPR:
|
||||
return omit_one_operand (type,
|
||||
convert (type, integer_one_node),
|
||||
arg0);
|
||||
case GT_EXPR:
|
||||
TREE_SET_CODE (t, NE_EXPR);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
else if (TREE_INT_CST_HIGH (arg1) == 0
|
||||
&& (TREE_INT_CST_LOW (arg1)
|
||||
== ((unsigned HOST_WIDE_INT) 1 << (width - 1)) - 1)
|
||||
&& TREE_UNSIGNED (TREE_TYPE (arg1))
|
||||
/* signed_type does not work on pointer types. */
|
||||
&& INTEGRAL_TYPE_P (TREE_TYPE (arg1)))
|
||||
switch (TREE_CODE (t))
|
||||
{
|
||||
case LE_EXPR:
|
||||
return fold (build (GE_EXPR, type,
|
||||
convert (signed_type (TREE_TYPE (arg0)),
|
||||
arg0),
|
||||
convert (signed_type (TREE_TYPE (arg1)),
|
||||
integer_zero_node)));
|
||||
case GT_EXPR:
|
||||
return fold (build (LT_EXPR, type,
|
||||
convert (signed_type (TREE_TYPE (arg0)),
|
||||
arg0),
|
||||
convert (signed_type (TREE_TYPE (arg1)),
|
||||
integer_zero_node)));
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
else if (TREE_INT_CST_HIGH (arg1) == 0
|
||||
&& (TREE_INT_CST_LOW (arg1)
|
||||
== ((unsigned HOST_WIDE_INT) 2 << (width - 1)) - 1)
|
||||
&& TREE_UNSIGNED (TREE_TYPE (arg1)))
|
||||
switch (TREE_CODE (t))
|
||||
{
|
||||
case GT_EXPR:
|
||||
return omit_one_operand (type,
|
||||
convert (type, integer_zero_node),
|
||||
arg0);
|
||||
case GE_EXPR:
|
||||
TREE_SET_CODE (t, EQ_EXPR);
|
||||
break;
|
||||
|
||||
case LE_EXPR:
|
||||
return omit_one_operand (type,
|
||||
convert (type, integer_one_node),
|
||||
arg0);
|
||||
case LT_EXPR:
|
||||
TREE_SET_CODE (t, NE_EXPR);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* If we are comparing an expression that just has comparisons
|
||||
of two integer values, arithmetic expressions of those comparisons,
|
||||
and constants, we can simplify it. There are only three cases
|
||||
|
@ -1601,6 +1601,8 @@ move_insn (insn, last)
|
||||
retval = reemit_notes (insn, insn);
|
||||
else
|
||||
reemit_notes (insn, insn);
|
||||
/* Consume SCHED_GROUP_P flag. */
|
||||
SCHED_GROUP_P (insn) = 0;
|
||||
insn = prev;
|
||||
}
|
||||
|
||||
@ -1764,7 +1766,10 @@ schedule_block (b, rgn_n_insns)
|
||||
can_issue_more =
|
||||
(*targetm.sched.variable_issue) (sched_dump, sched_verbose,
|
||||
insn, can_issue_more);
|
||||
else
|
||||
/* A naked CLOBBER or USE generates no instruction, so do
|
||||
not count them against the issue rate. */
|
||||
else if (GET_CODE (PATTERN (insn)) != USE
|
||||
&& GET_CODE (PATTERN (insn)) != CLOBBER)
|
||||
can_issue_more--;
|
||||
|
||||
schedule_insn (insn, &ready, clock_var);
|
||||
|
@ -26,6 +26,12 @@ Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
#include "system.h"
|
||||
#include "hooks.h"
|
||||
|
||||
/* Generic hook that does absolutely zappo. */
|
||||
void
|
||||
hook_void_void ()
|
||||
{
|
||||
}
|
||||
|
||||
/* Generic hook that takes no arguments and returns false. */
|
||||
bool
|
||||
hook_void_bool_false ()
|
||||
|
@ -19,4 +19,10 @@ Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
You are forbidden to forbid anyone else to use, share and improve
|
||||
what you give them. Help stamp out software-hoarding! */
|
||||
|
||||
#ifndef GCC_HOOKS_H
|
||||
#define GCC_HOOKS_H
|
||||
|
||||
bool hook_void_bool_false PARAMS ((void));
|
||||
void hook_void_void PARAMS ((void));
|
||||
|
||||
#endif
|
||||
|
@ -1504,45 +1504,73 @@ noce_try_abs (if_info)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* Look for the condition for the jump first. We'd prefer to avoid
|
||||
get_condition if we can -- it tries to look back for the contents
|
||||
of an original compare. On targets that use normal integers for
|
||||
comparisons, e.g. alpha, this is wasteful. */
|
||||
/* Similar to get_condition, only the resulting condition must be
|
||||
valid at JUMP, instead of at EARLIEST. */
|
||||
|
||||
static rtx
|
||||
noce_get_condition (jump, earliest)
|
||||
rtx jump;
|
||||
rtx *earliest;
|
||||
{
|
||||
rtx cond;
|
||||
rtx set;
|
||||
|
||||
/* If the condition variable is a register and is MODE_INT, accept it.
|
||||
Otherwise, fall back on get_condition. */
|
||||
rtx cond, set, tmp, insn;
|
||||
bool reverse;
|
||||
|
||||
if (! any_condjump_p (jump))
|
||||
return NULL_RTX;
|
||||
|
||||
set = pc_set (jump);
|
||||
|
||||
/* If this branches to JUMP_LABEL when the condition is false,
|
||||
reverse the condition. */
|
||||
reverse = (GET_CODE (XEXP (SET_SRC (set), 2)) == LABEL_REF
|
||||
&& XEXP (XEXP (SET_SRC (set), 2), 0) == JUMP_LABEL (jump));
|
||||
|
||||
/* If the condition variable is a register and is MODE_INT, accept it. */
|
||||
|
||||
cond = XEXP (SET_SRC (set), 0);
|
||||
if (GET_CODE (XEXP (cond, 0)) == REG
|
||||
&& GET_MODE_CLASS (GET_MODE (XEXP (cond, 0))) == MODE_INT)
|
||||
tmp = XEXP (cond, 0);
|
||||
if (REG_P (tmp) && GET_MODE_CLASS (GET_MODE (tmp)) == MODE_INT)
|
||||
{
|
||||
*earliest = jump;
|
||||
|
||||
/* If this branches to JUMP_LABEL when the condition is false,
|
||||
reverse the condition. */
|
||||
if (GET_CODE (XEXP (SET_SRC (set), 2)) == LABEL_REF
|
||||
&& XEXP (XEXP (SET_SRC (set), 2), 0) == JUMP_LABEL (jump))
|
||||
if (reverse)
|
||||
cond = gen_rtx_fmt_ee (reverse_condition (GET_CODE (cond)),
|
||||
GET_MODE (cond), XEXP (cond, 0),
|
||||
XEXP (cond, 1));
|
||||
GET_MODE (cond), tmp, XEXP (cond, 1));
|
||||
return cond;
|
||||
}
|
||||
else
|
||||
cond = get_condition (jump, earliest);
|
||||
|
||||
return cond;
|
||||
/* Otherwise, fall back on canonicalize_condition to do the dirty
|
||||
work of manipulating MODE_CC values and COMPARE rtx codes. */
|
||||
|
||||
tmp = canonicalize_condition (jump, cond, reverse, earliest, NULL_RTX);
|
||||
if (!tmp)
|
||||
return NULL_RTX;
|
||||
|
||||
/* We are going to insert code before JUMP, not before EARLIEST.
|
||||
We must therefore be certain that the given condition is valid
|
||||
at JUMP by virtue of not having been modified since. */
|
||||
for (insn = *earliest; insn != jump; insn = NEXT_INSN (insn))
|
||||
if (INSN_P (insn) && modified_in_p (tmp, insn))
|
||||
break;
|
||||
if (insn == jump)
|
||||
return tmp;
|
||||
|
||||
/* The condition was modified. See if we can get a partial result
|
||||
that doesn't follow all the reversals. Perhaps combine can fold
|
||||
them together later. */
|
||||
tmp = XEXP (tmp, 0);
|
||||
if (!REG_P (tmp) || GET_MODE_CLASS (GET_MODE (tmp)) != MODE_INT)
|
||||
return NULL_RTX;
|
||||
tmp = canonicalize_condition (jump, cond, reverse, earliest, tmp);
|
||||
if (!tmp)
|
||||
return NULL_RTX;
|
||||
|
||||
/* For sanity's sake, re-validate the new result. */
|
||||
for (insn = *earliest; insn != jump; insn = NEXT_INSN (insn))
|
||||
if (INSN_P (insn) && modified_in_p (tmp, insn))
|
||||
return NULL_RTX;
|
||||
|
||||
return tmp;
|
||||
}
|
||||
|
||||
/* Return true if OP is ok for if-then-else processing. */
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user