This commit was generated by cvs2svn to compensate for changes in r146895,
which included commits to RCS files with non-trunk default branches.
This commit is contained in:
commit
4101e78861
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=146896
File diff suppressed because it is too large
Load Diff
@ -266,6 +266,8 @@ decl_attributes (tree *node, tree attributes, int flags)
|
||||
/* Force a recalculation of mode and size. */
|
||||
DECL_MODE (*node) = VOIDmode;
|
||||
DECL_SIZE (*node) = 0;
|
||||
if (!DECL_USER_ALIGN (*node))
|
||||
DECL_ALIGN (*node) = 0;
|
||||
|
||||
layout_decl (*node, 0);
|
||||
}
|
||||
|
@ -2149,7 +2149,7 @@ compstmt_contents_nonempty:
|
||||
|
||||
compstmt_primary_start:
|
||||
'(' '{'
|
||||
{ if (current_function_decl == 0)
|
||||
{ if (last_tree == NULL)
|
||||
{
|
||||
error ("braced-group within expression allowed only inside a function");
|
||||
YYERROR;
|
||||
|
@ -359,7 +359,7 @@ pp_file_change (const struct line_map *map)
|
||||
{
|
||||
const char *flags = "";
|
||||
|
||||
if (flag_no_line_commands || flag_no_output)
|
||||
if (flag_no_line_commands)
|
||||
return;
|
||||
|
||||
if (map != NULL)
|
||||
|
@ -937,6 +937,9 @@ expand_unreachable_if_stmt (tree t)
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Account for declarations as conditions. */
|
||||
expand_cond (IF_COND (t));
|
||||
|
||||
if (THEN_CLAUSE (t) && ELSE_CLAUSE (t))
|
||||
{
|
||||
n = expand_unreachable_stmt (THEN_CLAUSE (t), 0);
|
||||
@ -969,7 +972,9 @@ expand_unreachable_if_stmt (tree t)
|
||||
/* Expand an unreachable statement list. This function skips all
|
||||
statements preceding the first potentially reachable label and
|
||||
then returns the label (or, in same cases, the statement after
|
||||
one containing the label). */
|
||||
one containing the label). This function returns NULL_TREE if
|
||||
the end of the given statement list is unreachable, and a
|
||||
non-NULL value, possibly error_mark_node, otherwise. */
|
||||
static tree
|
||||
expand_unreachable_stmt (tree t, int warn)
|
||||
{
|
||||
@ -1019,7 +1024,7 @@ expand_unreachable_stmt (tree t, int warn)
|
||||
|
||||
case IF_STMT:
|
||||
if (expand_unreachable_if_stmt (t))
|
||||
return TREE_CHAIN (t);
|
||||
return TREE_CHAIN (t) ? TREE_CHAIN (t) : error_mark_node;
|
||||
break;
|
||||
|
||||
case WHILE_STMT:
|
||||
@ -1027,7 +1032,7 @@ expand_unreachable_stmt (tree t, int warn)
|
||||
no need to rotate the loop, instead the WHILE_STMT can be
|
||||
expanded like a DO_STMT. */
|
||||
genrtl_do_stmt_1 (WHILE_COND (t), WHILE_BODY (t));
|
||||
return TREE_CHAIN (t);
|
||||
return TREE_CHAIN (t) ? TREE_CHAIN (t) : error_mark_node;
|
||||
|
||||
case COMPOUND_STMT:
|
||||
{
|
||||
@ -1036,7 +1041,7 @@ expand_unreachable_stmt (tree t, int warn)
|
||||
if (n != NULL_TREE)
|
||||
{
|
||||
expand_stmt (n);
|
||||
return TREE_CHAIN (t);
|
||||
return TREE_CHAIN (t) ? TREE_CHAIN (t) : error_mark_node;
|
||||
}
|
||||
warn = false;
|
||||
break;
|
||||
|
@ -647,7 +647,7 @@ same_translation_unit_p (tree t1, tree t2)
|
||||
while (t2 && TREE_CODE (t2) != TRANSLATION_UNIT_DECL)
|
||||
switch (TREE_CODE_CLASS (TREE_CODE (t2)))
|
||||
{
|
||||
case 'd': t2 = DECL_CONTEXT (t1); break;
|
||||
case 'd': t2 = DECL_CONTEXT (t2); break;
|
||||
case 't': t2 = TYPE_CONTEXT (t2); break;
|
||||
case 'b': t2 = BLOCK_SUPERCONTEXT (t2); break;
|
||||
default: abort ();
|
||||
@ -1320,26 +1320,6 @@ build_component_ref (tree datum, tree component)
|
||||
tree field = NULL;
|
||||
tree ref;
|
||||
|
||||
/* If DATUM is a COMPOUND_EXPR, move our reference inside it.
|
||||
If pedantic ensure that the arguments are not lvalues; otherwise,
|
||||
if the component is an array, it would wrongly decay to a pointer in
|
||||
C89 mode.
|
||||
We cannot do this with a COND_EXPR, because in a conditional expression
|
||||
the default promotions are applied to both sides, and this would yield
|
||||
the wrong type of the result; for example, if the components have
|
||||
type "char". */
|
||||
switch (TREE_CODE (datum))
|
||||
{
|
||||
case COMPOUND_EXPR:
|
||||
{
|
||||
tree value = build_component_ref (TREE_OPERAND (datum, 1), component);
|
||||
return build (COMPOUND_EXPR, TREE_TYPE (value),
|
||||
TREE_OPERAND (datum, 0), pedantic_non_lvalue (value));
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
/* See if there is a field or component with name COMPONENT. */
|
||||
|
||||
if (code == RECORD_TYPE || code == UNION_TYPE)
|
||||
@ -4117,18 +4097,32 @@ digest_init (tree type, tree init, int require_constant)
|
||||
/* Build a VECTOR_CST from a *constant* vector constructor. If the
|
||||
vector constructor is not constant (e.g. {1,2,3,foo()}) then punt
|
||||
below and handle as a constructor. */
|
||||
if (code == VECTOR_TYPE
|
||||
&& comptypes (TREE_TYPE (inside_init), type, COMPARE_STRICT)
|
||||
&& TREE_CONSTANT (inside_init))
|
||||
{
|
||||
if (TREE_CODE (inside_init) == VECTOR_CST
|
||||
&& comptypes (TYPE_MAIN_VARIANT (TREE_TYPE (inside_init)),
|
||||
TYPE_MAIN_VARIANT (type),
|
||||
COMPARE_STRICT))
|
||||
return inside_init;
|
||||
else
|
||||
return build_vector (type, CONSTRUCTOR_ELTS (inside_init));
|
||||
}
|
||||
if (code == VECTOR_TYPE
|
||||
&& comptypes (TREE_TYPE (inside_init), type, COMPARE_STRICT)
|
||||
&& TREE_CONSTANT (inside_init))
|
||||
{
|
||||
if (TREE_CODE (inside_init) == VECTOR_CST
|
||||
&& comptypes (TYPE_MAIN_VARIANT (TREE_TYPE (inside_init)),
|
||||
TYPE_MAIN_VARIANT (type),
|
||||
COMPARE_STRICT))
|
||||
return inside_init;
|
||||
|
||||
if (TREE_CODE (inside_init) == CONSTRUCTOR)
|
||||
{
|
||||
tree link;
|
||||
|
||||
/* Iterate through elements and check if all constructor
|
||||
elements are *_CSTs. */
|
||||
for (link = CONSTRUCTOR_ELTS (inside_init);
|
||||
link;
|
||||
link = TREE_CHAIN (link))
|
||||
if (TREE_CODE_CLASS (TREE_CODE (TREE_VALUE (link))) != 'c')
|
||||
break;
|
||||
|
||||
if (link == NULL)
|
||||
return build_vector (type, CONSTRUCTOR_ELTS (inside_init));
|
||||
}
|
||||
}
|
||||
|
||||
/* Any type can be initialized
|
||||
from an expression of the same type, optionally with braces. */
|
||||
@ -6571,6 +6565,14 @@ c_finish_case (void)
|
||||
{
|
||||
struct c_switch *cs = switch_stack;
|
||||
|
||||
/* If we've not seen any case labels (or a default), we may still
|
||||
need to chain any statements that were seen as the SWITCH_BODY. */
|
||||
if (SWITCH_BODY (cs->switch_stmt) == NULL)
|
||||
{
|
||||
SWITCH_BODY (cs->switch_stmt) = TREE_CHAIN (cs->switch_stmt);
|
||||
TREE_CHAIN (cs->switch_stmt) = NULL_TREE;
|
||||
}
|
||||
|
||||
/* Rechain the next statements to the SWITCH_STMT. */
|
||||
last_tree = cs->switch_stmt;
|
||||
|
||||
|
@ -1719,8 +1719,8 @@ load_register_parameters (struct arg_data *args, int num_actuals,
|
||||
use_group_regs (call_fusage, reg);
|
||||
else if (nregs == -1)
|
||||
use_reg (call_fusage, reg);
|
||||
else
|
||||
use_regs (call_fusage, REGNO (reg), nregs == 0 ? 1 : nregs);
|
||||
else if (nregs > 0)
|
||||
use_regs (call_fusage, REGNO (reg), nregs);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2730,10 +2730,14 @@ expand_call (tree exp, rtx target, int ignore)
|
||||
Also, do all pending adjustments now if there is any chance
|
||||
this might be a call to alloca or if we are expanding a sibling
|
||||
call sequence or if we are calling a function that is to return
|
||||
with stack pointer depressed. */
|
||||
with stack pointer depressed.
|
||||
Also do the adjustments before a throwing call, otherwise
|
||||
exception handling can fail; PR 19225. */
|
||||
if (pending_stack_adjust >= 32
|
||||
|| (pending_stack_adjust > 0
|
||||
&& (flags & (ECF_MAY_BE_ALLOCA | ECF_SP_DEPRESSED)))
|
||||
|| (pending_stack_adjust > 0
|
||||
&& flag_exceptions && !(flags & ECF_NOTHROW))
|
||||
|| pass == 0)
|
||||
do_pending_stack_adjust ();
|
||||
|
||||
|
@ -865,6 +865,18 @@ fixup_fallthru_exit_predecessor (void)
|
||||
{
|
||||
basic_block c = ENTRY_BLOCK_PTR->next_bb;
|
||||
|
||||
/* If the very first block is the one with the fall-through exit
|
||||
edge, we have to split that block. */
|
||||
if (c == bb)
|
||||
{
|
||||
bb = split_block (bb, NULL)->dest;
|
||||
cfg_layout_initialize_rbi (bb);
|
||||
bb->rbi->next = c->rbi->next;
|
||||
c->rbi->next = bb;
|
||||
bb->rbi->footer = c->rbi->footer;
|
||||
c->rbi->footer = NULL;
|
||||
}
|
||||
|
||||
while (c->rbi->next != bb)
|
||||
c = c->rbi->next;
|
||||
|
||||
|
@ -483,9 +483,21 @@ rtl_split_block (basic_block bb, void *insnp)
|
||||
edge e;
|
||||
rtx insn = insnp;
|
||||
|
||||
/* There is no point splitting the block after its end. */
|
||||
if (BB_END (bb) == insn)
|
||||
return 0;
|
||||
if (!insn)
|
||||
{
|
||||
insn = first_insn_after_basic_block_note (bb);
|
||||
|
||||
if (insn)
|
||||
insn = PREV_INSN (insn);
|
||||
else
|
||||
insn = get_last_insn ();
|
||||
}
|
||||
|
||||
/* We probably should check type of the insn so that we do not create
|
||||
inconsistent cfg. It is checked in verify_flow_info anyway, so do not
|
||||
bother. */
|
||||
if (insn == BB_END (bb))
|
||||
emit_note_after (NOTE_INSN_DELETED, insn);
|
||||
|
||||
/* Create the new basic block. */
|
||||
new_bb = create_basic_block (NEXT_INSN (insn), BB_END (bb), bb);
|
||||
@ -2711,6 +2723,18 @@ cfg_layout_split_edge (edge e)
|
||||
new_bb->count = e->count;
|
||||
new_bb->frequency = EDGE_FREQUENCY (e);
|
||||
|
||||
/* ??? This info is likely going to be out of date very soon, but we must
|
||||
create it to avoid getting an ICE later. */
|
||||
if (e->dest->global_live_at_start)
|
||||
{
|
||||
new_bb->global_live_at_start = OBSTACK_ALLOC_REG_SET (&flow_obstack);
|
||||
new_bb->global_live_at_end = OBSTACK_ALLOC_REG_SET (&flow_obstack);
|
||||
COPY_REG_SET (new_bb->global_live_at_start,
|
||||
e->dest->global_live_at_start);
|
||||
COPY_REG_SET (new_bb->global_live_at_end,
|
||||
e->dest->global_live_at_start);
|
||||
}
|
||||
|
||||
new_e = make_edge (new_bb, e->dest, EDGE_FALLTHRU);
|
||||
new_e->probability = REG_BR_PROB_BASE;
|
||||
new_e->count = e->count;
|
||||
|
@ -189,6 +189,7 @@ static int strip_flag; /* true if -s */
|
||||
#ifdef COLLECT_EXPORT_LIST
|
||||
static int export_flag; /* true if -bE */
|
||||
static int aix64_flag; /* true if -b64 */
|
||||
static int aixrtl_flag; /* true if -brtl */
|
||||
#endif
|
||||
|
||||
int debug; /* true if -debug */
|
||||
@ -246,7 +247,6 @@ static struct path_prefix cmdline_lib_dirs; /* directories specified with -L */
|
||||
static struct path_prefix libpath_lib_dirs; /* directories in LIBPATH */
|
||||
static struct path_prefix *libpaths[3] = {&cmdline_lib_dirs,
|
||||
&libpath_lib_dirs, NULL};
|
||||
static const char *const libexts[3] = {"a", "so", NULL}; /* possible library extensions */
|
||||
#endif
|
||||
|
||||
static void handler (int);
|
||||
@ -1080,6 +1080,8 @@ main (int argc, char **argv)
|
||||
export_flag = 1;
|
||||
else if (arg[2] == '6' && arg[3] == '4')
|
||||
aix64_flag = 1;
|
||||
else if (arg[2] == 'r' && arg[3] == 't' && arg[4] == 'l')
|
||||
aixrtl_flag = 1;
|
||||
break;
|
||||
#endif
|
||||
|
||||
@ -2823,6 +2825,8 @@ resolve_lib_name (const char *name)
|
||||
{
|
||||
char *lib_buf;
|
||||
int i, j, l = 0;
|
||||
/* Library extensions for AIX dynamic linking. */
|
||||
const char * const libexts[2] = {"a", "so"};
|
||||
|
||||
for (i = 0; libpaths[i]; i++)
|
||||
if (libpaths[i]->max_len > l)
|
||||
@ -2841,14 +2845,15 @@ resolve_lib_name (const char *name)
|
||||
const char *p = "";
|
||||
if (list->prefix[strlen(list->prefix)-1] != '/')
|
||||
p = "/";
|
||||
for (j = 0; libexts[j]; j++)
|
||||
for (j = 0; j < 2; j++)
|
||||
{
|
||||
sprintf (lib_buf, "%s%slib%s.%s",
|
||||
list->prefix, p, name, libexts[j]);
|
||||
if (debug) fprintf (stderr, "searching for: %s\n", lib_buf);
|
||||
list->prefix, p, name,
|
||||
libexts[(j + aixrtl_flag) % 2]);
|
||||
if (debug) fprintf (stderr, "searching for: %s\n", lib_buf);
|
||||
if (file_exists (lib_buf))
|
||||
{
|
||||
if (debug) fprintf (stderr, "found: %s\n", lib_buf);
|
||||
if (debug) fprintf (stderr, "found: %s\n", lib_buf);
|
||||
return (lib_buf);
|
||||
}
|
||||
}
|
||||
|
@ -90,6 +90,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
|
||||
#include "real.h"
|
||||
#include "toplev.h"
|
||||
#include "target.h"
|
||||
#include "params.h"
|
||||
|
||||
#ifndef SHIFT_COUNT_TRUNCATED
|
||||
#define SHIFT_COUNT_TRUNCATED 0
|
||||
@ -3417,10 +3418,10 @@ subst (rtx x, rtx from, rtx to, int in_dest, int unique_copy)
|
||||
/* If this is a register being set, ignore it. */
|
||||
new = XEXP (x, i);
|
||||
if (in_dest
|
||||
&& (code == SUBREG || code == STRICT_LOW_PART
|
||||
|| code == ZERO_EXTRACT)
|
||||
&& i == 0
|
||||
&& GET_CODE (new) == REG)
|
||||
&& (((code == SUBREG || code == ZERO_EXTRACT)
|
||||
&& GET_CODE (new) == REG)
|
||||
|| code == STRICT_LOW_PART))
|
||||
;
|
||||
|
||||
else if (COMBINE_RTX_EQUAL_P (XEXP (x, i), from))
|
||||
@ -3715,27 +3716,28 @@ combine_simplify_rtx (rtx x, enum machine_mode op0_mode, int last,
|
||||
temp = simplify_unary_operation (code, mode, XEXP (x, 0), op0_mode);
|
||||
break;
|
||||
case '<':
|
||||
{
|
||||
enum machine_mode cmp_mode = GET_MODE (XEXP (x, 0));
|
||||
if (cmp_mode == VOIDmode)
|
||||
{
|
||||
cmp_mode = GET_MODE (XEXP (x, 1));
|
||||
if (cmp_mode == VOIDmode)
|
||||
cmp_mode = op0_mode;
|
||||
}
|
||||
temp = simplify_relational_operation (code, cmp_mode,
|
||||
XEXP (x, 0), XEXP (x, 1));
|
||||
}
|
||||
#ifdef FLOAT_STORE_FLAG_VALUE
|
||||
if (temp != 0 && GET_MODE_CLASS (mode) == MODE_FLOAT)
|
||||
if (! VECTOR_MODE_P (mode))
|
||||
{
|
||||
if (temp == const0_rtx)
|
||||
temp = CONST0_RTX (mode);
|
||||
else
|
||||
temp = CONST_DOUBLE_FROM_REAL_VALUE (FLOAT_STORE_FLAG_VALUE (mode),
|
||||
mode);
|
||||
}
|
||||
enum machine_mode cmp_mode = GET_MODE (XEXP (x, 0));
|
||||
if (cmp_mode == VOIDmode)
|
||||
{
|
||||
cmp_mode = GET_MODE (XEXP (x, 1));
|
||||
if (cmp_mode == VOIDmode)
|
||||
cmp_mode = op0_mode;
|
||||
}
|
||||
temp = simplify_relational_operation (code, cmp_mode,
|
||||
XEXP (x, 0), XEXP (x, 1));
|
||||
#ifdef FLOAT_STORE_FLAG_VALUE
|
||||
if (temp != 0 && GET_MODE_CLASS (mode) == MODE_FLOAT)
|
||||
{
|
||||
if (temp == const0_rtx)
|
||||
temp = CONST0_RTX (mode);
|
||||
else
|
||||
temp = CONST_DOUBLE_FROM_REAL_VALUE
|
||||
(FLOAT_STORE_FLAG_VALUE (mode), mode);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
case 'c':
|
||||
case '2':
|
||||
@ -10019,13 +10021,8 @@ gen_lowpart_for_combine (enum machine_mode mode, rtx x)
|
||||
|
||||
result = gen_lowpart_common (mode, x);
|
||||
#ifdef CANNOT_CHANGE_MODE_CLASS
|
||||
if (result != 0
|
||||
&& GET_CODE (result) == SUBREG
|
||||
&& GET_CODE (SUBREG_REG (result)) == REG
|
||||
&& REGNO (SUBREG_REG (result)) >= FIRST_PSEUDO_REGISTER)
|
||||
bitmap_set_bit (&subregs_of_mode, REGNO (SUBREG_REG (result))
|
||||
* MAX_MACHINE_MODE
|
||||
+ GET_MODE (result));
|
||||
if (result != 0 && GET_CODE (result) == SUBREG)
|
||||
record_subregs_of_mode (result);
|
||||
#endif
|
||||
|
||||
if (result)
|
||||
@ -10692,34 +10689,61 @@ simplify_comparison (enum rtx_code code, rtx *pop0, rtx *pop1)
|
||||
break;
|
||||
|
||||
case SUBREG:
|
||||
/* Check for the case where we are comparing A - C1 with C2,
|
||||
both constants are smaller than 1/2 the maximum positive
|
||||
value in MODE, and the comparison is equality or unsigned.
|
||||
In that case, if A is either zero-extended to MODE or has
|
||||
sufficient sign bits so that the high-order bit in MODE
|
||||
is a copy of the sign in the inner mode, we can prove that it is
|
||||
safe to do the operation in the wider mode. This simplifies
|
||||
many range checks. */
|
||||
/* Check for the case where we are comparing A - C1 with C2, that is
|
||||
|
||||
(subreg:MODE (plus (A) (-C1))) op (C2)
|
||||
|
||||
with C1 a constant, and try to lift the SUBREG, i.e. to do the
|
||||
comparison in the wider mode. One of the following two conditions
|
||||
must be true in order for this to be valid:
|
||||
|
||||
1. The mode extension results in the same bit pattern being added
|
||||
on both sides and the comparison is equality or unsigned. As
|
||||
C2 has been truncated to fit in MODE, the pattern can only be
|
||||
all 0s or all 1s.
|
||||
|
||||
2. The mode extension results in the sign bit being copied on
|
||||
each side.
|
||||
|
||||
The difficulty here is that we have predicates for A but not for
|
||||
(A - C1) so we need to check that C1 is within proper bounds so
|
||||
as to perturbate A as little as possible. */
|
||||
|
||||
if (mode_width <= HOST_BITS_PER_WIDE_INT
|
||||
&& subreg_lowpart_p (op0)
|
||||
&& GET_MODE_BITSIZE (GET_MODE (SUBREG_REG (op0))) > mode_width
|
||||
&& GET_CODE (SUBREG_REG (op0)) == PLUS
|
||||
&& GET_CODE (XEXP (SUBREG_REG (op0), 1)) == CONST_INT
|
||||
&& INTVAL (XEXP (SUBREG_REG (op0), 1)) < 0
|
||||
&& (-INTVAL (XEXP (SUBREG_REG (op0), 1))
|
||||
< (HOST_WIDE_INT) (GET_MODE_MASK (mode) / 2))
|
||||
&& (unsigned HOST_WIDE_INT) const_op < GET_MODE_MASK (mode) / 2
|
||||
&& (0 == (nonzero_bits (XEXP (SUBREG_REG (op0), 0),
|
||||
GET_MODE (SUBREG_REG (op0)))
|
||||
& ~GET_MODE_MASK (mode))
|
||||
|| (num_sign_bit_copies (XEXP (SUBREG_REG (op0), 0),
|
||||
GET_MODE (SUBREG_REG (op0)))
|
||||
> (unsigned int)
|
||||
(GET_MODE_BITSIZE (GET_MODE (SUBREG_REG (op0)))
|
||||
- GET_MODE_BITSIZE (mode)))))
|
||||
&& GET_CODE (XEXP (SUBREG_REG (op0), 1)) == CONST_INT)
|
||||
{
|
||||
op0 = SUBREG_REG (op0);
|
||||
continue;
|
||||
enum machine_mode inner_mode = GET_MODE (SUBREG_REG (op0));
|
||||
rtx a = XEXP (SUBREG_REG (op0), 0);
|
||||
HOST_WIDE_INT c1 = -INTVAL (XEXP (SUBREG_REG (op0), 1));
|
||||
|
||||
if ((c1 > 0
|
||||
&& (unsigned HOST_WIDE_INT) c1
|
||||
< (unsigned HOST_WIDE_INT) 1 << (mode_width - 1)
|
||||
&& (equality_comparison_p || unsigned_comparison_p)
|
||||
/* (A - C1) zero-extends if it is positive and sign-extends
|
||||
if it is negative, C2 both zero- and sign-extends. */
|
||||
&& ((0 == (nonzero_bits (a, inner_mode)
|
||||
& ~GET_MODE_MASK (mode))
|
||||
&& const_op >= 0)
|
||||
/* (A - C1) sign-extends if it is positive and 1-extends
|
||||
if it is negative, C2 both sign- and 1-extends. */
|
||||
|| (num_sign_bit_copies (a, inner_mode)
|
||||
> (unsigned int) (GET_MODE_BITSIZE (inner_mode)
|
||||
- mode_width)
|
||||
&& const_op < 0)))
|
||||
|| ((unsigned HOST_WIDE_INT) c1
|
||||
< (unsigned HOST_WIDE_INT) 1 << (mode_width - 2)
|
||||
/* (A - C1) always sign-extends, like C2. */
|
||||
&& num_sign_bit_copies (a, inner_mode)
|
||||
> (unsigned int) (GET_MODE_BITSIZE (inner_mode)
|
||||
- mode_width - 1)))
|
||||
{
|
||||
op0 = SUBREG_REG (op0);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
/* If the inner mode is narrower and we are extracting the low part,
|
||||
@ -11357,6 +11381,47 @@ reversed_comparison (rtx exp, enum machine_mode mode, rtx op0, rtx op1)
|
||||
return gen_binary (reversed_code, mode, op0, op1);
|
||||
}
|
||||
|
||||
/* Utility function for record_value_for_reg. Count number of
|
||||
rtxs in X. */
|
||||
static int
|
||||
count_rtxs (rtx x)
|
||||
{
|
||||
enum rtx_code code = GET_CODE (x);
|
||||
const char *fmt;
|
||||
int i, ret = 1;
|
||||
|
||||
if (GET_RTX_CLASS (code) == '2'
|
||||
|| GET_RTX_CLASS (code) == 'c')
|
||||
{
|
||||
rtx x0 = XEXP (x, 0);
|
||||
rtx x1 = XEXP (x, 1);
|
||||
|
||||
if (x0 == x1)
|
||||
return 1 + 2 * count_rtxs (x0);
|
||||
|
||||
if ((GET_RTX_CLASS (GET_CODE (x1)) == '2'
|
||||
|| GET_RTX_CLASS (GET_CODE (x1)) == 'c')
|
||||
&& (x0 == XEXP (x1, 0) || x0 == XEXP (x1, 1)))
|
||||
return 2 + 2 * count_rtxs (x0)
|
||||
+ count_rtxs (x == XEXP (x1, 0)
|
||||
? XEXP (x1, 1) : XEXP (x1, 0));
|
||||
|
||||
if ((GET_RTX_CLASS (GET_CODE (x0)) == '2'
|
||||
|| GET_RTX_CLASS (GET_CODE (x0)) == 'c')
|
||||
&& (x1 == XEXP (x0, 0) || x1 == XEXP (x0, 1)))
|
||||
return 2 + 2 * count_rtxs (x1)
|
||||
+ count_rtxs (x == XEXP (x0, 0)
|
||||
? XEXP (x0, 1) : XEXP (x0, 0));
|
||||
}
|
||||
|
||||
fmt = GET_RTX_FORMAT (code);
|
||||
for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
|
||||
if (fmt[i] == 'e')
|
||||
ret += count_rtxs (XEXP (x, i));
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Utility function for following routine. Called when X is part of a value
|
||||
being stored into reg_last_set_value. Sets reg_last_set_table_tick
|
||||
for each register mentioned. Similar to mention_regs in cse.c */
|
||||
@ -11463,6 +11528,13 @@ record_value_for_reg (rtx reg, rtx insn, rtx value)
|
||||
&& GET_CODE (XEXP (tem, 0)) == CLOBBER
|
||||
&& GET_CODE (XEXP (tem, 1)) == CLOBBER)
|
||||
tem = XEXP (tem, 0);
|
||||
else if (count_occurrences (value, reg, 1) >= 2)
|
||||
{
|
||||
/* If there are two or more occurrences of REG in VALUE,
|
||||
prevent the value from growing too much. */
|
||||
if (count_rtxs (tem) > MAX_LAST_VALUE_RTL)
|
||||
tem = gen_rtx_CLOBBER (GET_MODE (tem), const0_rtx);
|
||||
}
|
||||
|
||||
value = replace_rtx (copy_rtx (value), reg, tem);
|
||||
}
|
||||
|
@ -28,7 +28,7 @@ Display this information
|
||||
|
||||
-param
|
||||
Common Separate
|
||||
--param <param>=<value> Set paramter <param> to value. See below for a complete list of parameters
|
||||
--param <param>=<value> Set parameter <param> to value. See below for a complete list of parameters
|
||||
|
||||
-target-help
|
||||
Common
|
||||
|
@ -244,6 +244,7 @@ esac
|
||||
# machines.
|
||||
tm_p_file=
|
||||
cpu_type=`echo ${target} | sed 's/-.*$//'`
|
||||
cpu_is_64bit=
|
||||
case ${target} in
|
||||
alpha*-*-*)
|
||||
cpu_type=alpha
|
||||
@ -300,6 +301,11 @@ powerpc*-*-*)
|
||||
cpu_type=rs6000
|
||||
extra_headers="ppc-asm.h altivec.h spe.h"
|
||||
need_64bit_hwint=yes
|
||||
case x$with_cpu in
|
||||
xpowerpc64|xdefault64|x6[23]0|x970|xG5|xpower[345]|xrs64a)
|
||||
cpu_is_64bit=yes
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
rs6000*-*-*)
|
||||
need_64bit_hwint=yes
|
||||
@ -680,7 +686,7 @@ arm*-*-ecos-elf)
|
||||
;;
|
||||
arm*-*-rtems*)
|
||||
tm_file="dbxelf.h elfos.h arm/unknown-elf.h arm/elf.h arm/aout.h arm/arm.h arm/rtems-elf.h rtems.h"
|
||||
tmake_file="arm/t-arm-elf t-rtems"
|
||||
tmake_file="arm/t-arm-elf t-rtems arm/t-rtems"
|
||||
;;
|
||||
arm*-*-elf | ep9312-*-elf)
|
||||
tm_file="dbxelf.h elfos.h arm/unknown-elf.h arm/elf.h arm/aout.h arm/arm.h"
|
||||
@ -700,12 +706,16 @@ arm*-*-kaos*)
|
||||
tm_file="dbxelf.h elfos.h arm/unknown-elf.h arm/elf.h arm/aout.h arm/arm.h kaos.h arm/kaos-arm.h"
|
||||
tmake_file=arm/t-arm-elf
|
||||
;;
|
||||
avr-*-rtems*)
|
||||
tm_file="avr/avr.h dbxelf.h avr/rtems.h rtems.h"
|
||||
tmake_file="avr/t-avr t-rtems avr/t-rtems"
|
||||
;;
|
||||
avr-*-*)
|
||||
tm_file="avr/avr.h dbxelf.h"
|
||||
use_fixproto=yes
|
||||
;;
|
||||
c4x-*-rtems* | tic4x-*-rtems*)
|
||||
tmake_file="c4x/t-c4x t-rtems"
|
||||
tmake_file="c4x/t-c4x t-rtems c4x/t-rtems"
|
||||
tm_file="c4x/c4x.h c4x/rtems.h rtems.h"
|
||||
c_target_objs="c4x-c.o"
|
||||
cxx_target_objs="c4x-c.o"
|
||||
@ -1257,12 +1267,12 @@ ia64*-*-freebsd*)
|
||||
;;
|
||||
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"
|
||||
tmake_file="t-slibgcc-elf-ver t-linux ia64/t-ia64 t-libunwind ia64/t-glibc"
|
||||
if test x$with_system_libunwind != xyes ; then
|
||||
tmake_file="${tmake_file} t-libunwind-elf ia64/t-glibc-libunwind"
|
||||
fi
|
||||
target_cpu_default="MASK_GNU_AS|MASK_GNU_LD"
|
||||
extra_parts="crtbegin.o crtend.o crtbeginS.o crtendS.o crtfastmath.o"
|
||||
if test x"$use_libunwind_exceptions" = xyes; then
|
||||
tmake_file="$tmake_file t-libunwind"
|
||||
fi
|
||||
;;
|
||||
ia64*-*-hpux*)
|
||||
tm_file="${tm_file} dbxelf.h elfos.h svr4.h ia64/sysv4.h ia64/hpux.h"
|
||||
@ -1678,20 +1688,16 @@ pdp11-*-bsd)
|
||||
pdp11-*-*)
|
||||
use_fixproto=yes
|
||||
;;
|
||||
avr-*-*)
|
||||
use_fixproto=yes
|
||||
;;
|
||||
# port not yet contributed
|
||||
#powerpc-*-openbsd*)
|
||||
# tmake_file="${tmake_file} rs6000/t-fprules "
|
||||
# extra_headers=
|
||||
# ;;
|
||||
powerpc64-*-linux*)
|
||||
tm_file="rs6000/biarch64.h ${tm_file} dbxelf.h elfos.h svr4.h freebsd-spec.h rs6000/sysv4.h"
|
||||
case x$with_cpu in
|
||||
x|xpowerpc64|xdefault64) tm_file="${tm_file} rs6000/default64.h";;
|
||||
esac
|
||||
tm_file="${tm_file} rs6000/linux64.h"
|
||||
tm_file="${tm_file} dbxelf.h elfos.h svr4.h freebsd-spec.h rs6000/sysv4.h"
|
||||
test x$with_cpu != x || cpu_is_64bit=yes
|
||||
test x$cpu_is_64bit != xyes || tm_file="${tm_file} rs6000/default64.h"
|
||||
tm_file="rs6000/biarch64.h ${tm_file} rs6000/linux64.h"
|
||||
tmake_file="rs6000/t-fprules t-slibgcc-elf-ver t-linux rs6000/t-ppccomm rs6000/t-linux64"
|
||||
;;
|
||||
powerpc64-*-gnu*)
|
||||
@ -1765,8 +1771,20 @@ powerpc-*-linux*spe*)
|
||||
tmake_file="rs6000/t-fprules rs6000/t-ppcos t-slibgcc-elf-ver t-linux rs6000/t-ppccomm"
|
||||
;;
|
||||
powerpc-*-linux*)
|
||||
tm_file="${tm_file} dbxelf.h elfos.h svr4.h freebsd-spec.h rs6000/sysv4.h rs6000/linux.h"
|
||||
tm_file="${tm_file} dbxelf.h elfos.h svr4.h freebsd-spec.h rs6000/sysv4.h"
|
||||
tmake_file="rs6000/t-fprules rs6000/t-ppcos t-slibgcc-elf-ver t-linux rs6000/t-ppccomm"
|
||||
case ${enable_targets}:${cpu_is_64bit} in
|
||||
*powerpc64* | all:* | *:yes)
|
||||
if test x$cpu_is_64bit = xyes; then
|
||||
tm_file="${tm_file} rs6000/default64.h"
|
||||
fi
|
||||
tm_file="rs6000/biarch64.h ${tm_file} rs6000/linux64.h"
|
||||
tmake_file="$tmake_file rs6000/t-linux64"
|
||||
;;
|
||||
*)
|
||||
tm_file="${tm_file} rs6000/linux.h"
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
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"
|
||||
@ -2007,7 +2025,7 @@ sparc64-*-openbsd*)
|
||||
with_cpu=ultrasparc
|
||||
;;
|
||||
sparc-*-elf*)
|
||||
tm_file="${tm_file} dbxelf.h elfos.h svr4.h sparc/sysv4.h sol2.h sparc/sol2.h sparc/elf.h"
|
||||
tm_file="${tm_file} dbxelf.h elfos.h svr4.h sparc/sysv4.h sol2.h sparc/sol2.h sparc/sol2-gld.h sparc/elf.h"
|
||||
tmake_file="sparc/t-elf sparc/t-crtfm"
|
||||
extra_parts="crti.o crtn.o crtbegin.o crtend.o"
|
||||
use_fixproto=yes
|
||||
@ -2017,7 +2035,7 @@ sparc-*-linux*) # SPARC's running GNU/Linux, libc6
|
||||
tmake_file="t-slibgcc-elf-ver t-linux sparc/t-crtfm"
|
||||
;;
|
||||
sparc-*-rtems*)
|
||||
tm_file="${tm_file} dbxelf.h elfos.h svr4.h sparc/sysv4.h sol2.h sparc/sol2.h sparc/elf.h sparc/rtemself.h rtems.h"
|
||||
tm_file="${tm_file} dbxelf.h elfos.h svr4.h sparc/sysv4.h sol2.h sparc/sol2.h sparc/sol2-gld.h sparc/elf.h sparc/rtemself.h rtems.h"
|
||||
tmake_file="sparc/t-elf sparc/t-crtfm t-rtems"
|
||||
extra_parts="crti.o crtn.o crtbegin.o crtend.o"
|
||||
;;
|
||||
@ -2106,13 +2124,13 @@ sparclite-*-coff*)
|
||||
tmake_file=sparc/t-sparclite
|
||||
;;
|
||||
sparclite-*-elf*)
|
||||
tm_file="${tm_file} dbxelf.h elfos.h svr4.h sparc/sysv4.h sol2.h sparc/sol2.h sparc/elf.h sparc/liteelf.h"
|
||||
tm_file="${tm_file} dbxelf.h elfos.h svr4.h sparc/sysv4.h sol2.h sparc/sol2.h sparc/sol2-gld.h sparc/elf.h sparc/liteelf.h"
|
||||
tmake_file="sparc/t-sparclite sparc/t-crtfm"
|
||||
extra_parts="crtbegin.o crtend.o"
|
||||
use_fixproto=yes
|
||||
;;
|
||||
sparc86x-*-elf*)
|
||||
tm_file="${tm_file} dbxelf.h elfos.h svr4.h sparc/sysv4.h sol2.h sparc/sol2.h sparc/elf.h sparc/sp86x-elf.h"
|
||||
tm_file="${tm_file} dbxelf.h elfos.h svr4.h sparc/sysv4.h sol2.h sparc/sol2.h sparc/sol2-gld.h sparc/elf.h sparc/sp86x-elf.h"
|
||||
tmake_file="sparc/t-sp86x sparc/t-crtfm"
|
||||
extra_parts="crtbegin.o crtend.o"
|
||||
use_fixproto=yes
|
||||
@ -2122,7 +2140,7 @@ sparc64-*-aout*)
|
||||
use_fixproto=yes
|
||||
;;
|
||||
sparc64-*-elf*)
|
||||
tm_file="${tm_file} dbxelf.h elfos.h svr4.h sparc/sysv4.h sol2.h sparc/sol2.h sparc/sp64-elf.h"
|
||||
tm_file="${tm_file} dbxelf.h elfos.h svr4.h sparc/sysv4.h sol2.h sparc/sol2.h sparc/sol2-gld.h sparc/sp64-elf.h"
|
||||
tmake_file="${tmake_file} sparc/t-crtfm"
|
||||
extra_parts="crtbegin.o crtend.o"
|
||||
use_fixproto=yes
|
||||
@ -2398,24 +2416,24 @@ if test x$with_cpu = x ; then
|
||||
esac
|
||||
fi
|
||||
|
||||
# Similarly for --with-schedule.
|
||||
if test x$with_schedule = x; then
|
||||
case ${target} in
|
||||
hppa1* | parisc1*)
|
||||
# Override default PA8000 scheduling model.
|
||||
with_schedule=7100LC
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
# Similarly for --with-schedule.
|
||||
if test x$with_schedule = x; then
|
||||
case ${target} in
|
||||
hppa1* | parisc1*)
|
||||
# Override default PA8000 scheduling model.
|
||||
with_schedule=7100LC
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
|
||||
# Validate and mark as valid any --with options supported
|
||||
# by this target. In order to use a particular --with option
|
||||
# you must list it in supported_defaults; validating the value
|
||||
# is optional. This case statement should set nothing besides
|
||||
# supported_defaults.
|
||||
# Validate and mark as valid any --with options supported
|
||||
# by this target. In order to use a particular --with option
|
||||
# you must list it in supported_defaults; validating the value
|
||||
# is optional. This case statement should set nothing besides
|
||||
# supported_defaults.
|
||||
|
||||
supported_defaults=
|
||||
case "${target}" in
|
||||
supported_defaults=
|
||||
case "${target}" in
|
||||
alpha*-*-*)
|
||||
supported_defaults="cpu tune"
|
||||
for which in cpu tune; do
|
||||
@ -2569,8 +2587,7 @@ fi
|
||||
eval $with_which=
|
||||
;;
|
||||
"" | common \
|
||||
| power | power2 | power3 | power4 \
|
||||
| powerpc | powerpc64 \
|
||||
| power | power[2345] | powerpc | powerpc64 \
|
||||
| rios | rios1 | rios2 | rsc | rsc1 | rs64a \
|
||||
| 401 | 403 | 405 | 405fp | 440 | 440fp | 505 \
|
||||
| 601 | 602 | 603 | 603e | ec603e | 604 \
|
||||
@ -2655,11 +2672,11 @@ fi
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
esac
|
||||
esac
|
||||
|
||||
# Set some miscellaneous flags for particular targets.
|
||||
target_cpu_default2=
|
||||
case ${target} in
|
||||
# Set some miscellaneous flags for particular targets.
|
||||
target_cpu_default2=
|
||||
case ${target} in
|
||||
alpha*-*-*)
|
||||
if test x$gas = xyes
|
||||
then
|
||||
@ -2771,44 +2788,45 @@ fi
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
esac
|
||||
esac
|
||||
|
||||
t=
|
||||
all_defaults="abi cpu arch tune schedule float mode"
|
||||
for option in $all_defaults
|
||||
do
|
||||
eval "val=\$with_$option"
|
||||
if test -n "$val"; then
|
||||
case " $supported_defaults " in
|
||||
*" $option "*)
|
||||
;;
|
||||
*)
|
||||
echo "This target does not support --with-$option." 2>&1
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
t=
|
||||
all_defaults="abi cpu arch tune schedule float mode"
|
||||
for option in $all_defaults
|
||||
do
|
||||
eval "val=\$with_$option"
|
||||
if test -n "$val"; then
|
||||
case " $supported_defaults " in
|
||||
*" $option "*)
|
||||
;;
|
||||
*)
|
||||
echo "This target does not support --with-$option." 2>&1
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
if test "x$t" = x
|
||||
then
|
||||
t="{ \"$option\", \"$val\" }"
|
||||
else
|
||||
t="${t}, { \"$option\", \"$val\" }"
|
||||
fi
|
||||
fi
|
||||
done
|
||||
if test "x$t" = x
|
||||
then
|
||||
configure_default_options="{ { NULL, NULL} }"
|
||||
else
|
||||
configure_default_options="{ ${t} }"
|
||||
fi
|
||||
|
||||
if test "$target_cpu_default2" != ""
|
||||
then
|
||||
if test "$target_cpu_default" != ""
|
||||
if test "x$t" = x
|
||||
then
|
||||
target_cpu_default="(${target_cpu_default}|${target_cpu_default2})"
|
||||
t="{ \"$option\", \"$val\" }"
|
||||
else
|
||||
target_cpu_default=$target_cpu_default2
|
||||
t="${t}, { \"$option\", \"$val\" }"
|
||||
fi
|
||||
fi
|
||||
done
|
||||
|
||||
if test "x$t" = x
|
||||
then
|
||||
configure_default_options="{ { NULL, NULL} }"
|
||||
else
|
||||
configure_default_options="{ ${t} }"
|
||||
fi
|
||||
|
||||
if test "$target_cpu_default2" != ""
|
||||
then
|
||||
if test "$target_cpu_default" != ""
|
||||
then
|
||||
target_cpu_default="(${target_cpu_default}|${target_cpu_default2})"
|
||||
else
|
||||
target_cpu_default=$target_cpu_default2
|
||||
fi
|
||||
fi
|
||||
|
@ -262,6 +262,9 @@
|
||||
skip when using the GAS .p2align command. */
|
||||
#undef HAVE_GAS_MAX_SKIP_P2ALIGN
|
||||
|
||||
/* Define if your assembler supports .nsubspa comdat option. */
|
||||
#undef HAVE_GAS_NSUBSPA_COMDAT
|
||||
|
||||
/* Define 0/1 if your assembler supports marking sections with SHF_MERGE flag.
|
||||
*/
|
||||
#undef HAVE_GAS_SHF_MERGE
|
||||
@ -319,6 +322,9 @@
|
||||
a read-write section. */
|
||||
#undef HAVE_LD_RO_RW_SECTION_MIXING
|
||||
|
||||
/* Define if your linker supports -Bstatic/-Bdynamic option. */
|
||||
#undef HAVE_LD_STATIC_DYNAMIC
|
||||
|
||||
/* Define to 1 if you have the <limits.h> header file. */
|
||||
#undef HAVE_LIMITS_H
|
||||
|
||||
@ -534,9 +540,6 @@
|
||||
/* Define if your assembler mis-optimizes .eh_frame data. */
|
||||
#undef USE_AS_TRADITIONAL_FORMAT
|
||||
|
||||
/* Define if gcc should use -lunwind. */
|
||||
#undef USE_LIBUNWIND_EXCEPTIONS
|
||||
|
||||
/* Define to be the last portion of registry key on windows hosts. */
|
||||
#undef WIN32_REGISTRY_KEY
|
||||
|
||||
@ -549,9 +552,11 @@
|
||||
/* Define to `int' if <sys/types.h> doesn't define. */
|
||||
#undef gid_t
|
||||
|
||||
/* Define as `__inline' if that's what the C compiler calls it, or to nothing
|
||||
if it is not supported. */
|
||||
/* Define to `__inline__' or `__inline' if that's what the C compiler
|
||||
calls it, or to nothing if 'inline' is not supported under any name. */
|
||||
#ifndef __cplusplus
|
||||
#undef inline
|
||||
#endif
|
||||
|
||||
/* Define to `int' if <sys/types.h> does not define. */
|
||||
#undef pid_t
|
||||
|
@ -641,6 +641,7 @@ extern const char *alpha_tls_size_string; /* For -mtls-size= */
|
||||
#define HARD_REGNO_MODE_OK(REGNO, MODE) \
|
||||
((REGNO) >= 32 && (REGNO) <= 62 \
|
||||
? (MODE) == SFmode || (MODE) == DFmode || (MODE) == DImode \
|
||||
|| (MODE) == SCmode || (MODE) == DCmode \
|
||||
: 1)
|
||||
|
||||
/* Value is 1 if MODE is a supported vector mode. */
|
||||
@ -1189,6 +1190,7 @@ do { \
|
||||
#define INCOMING_RETURN_ADDR_RTX gen_rtx_REG (Pmode, 26)
|
||||
#define DWARF_FRAME_RETURN_COLUMN DWARF_FRAME_REGNUM (26)
|
||||
#define DWARF_ALT_FRAME_RETURN_COLUMN DWARF_FRAME_REGNUM (64)
|
||||
#define DWARF_ZERO_REG 31
|
||||
|
||||
/* Describe how we implement __builtin_eh_return. */
|
||||
#define EH_RETURN_DATA_REGNO(N) ((N) < 4 ? (N) + 16 : INVALID_REGNUM)
|
||||
|
@ -77,6 +77,7 @@
|
||||
(UNSPECV_PLDGP2 11) ; prologue ldgp
|
||||
(UNSPECV_SET_TP 12)
|
||||
(UNSPECV_RPCC 13)
|
||||
(UNSPECV_SETJMPR_ER 14) ; builtin_setjmp_receiver fragment
|
||||
])
|
||||
|
||||
;; Where necessary, the suffixes _le and _be are used to distinguish between
|
||||
@ -438,9 +439,9 @@
|
||||
;; and if we split before reload, we will require additional instructions.
|
||||
|
||||
(define_insn "*adddi_fp_hack"
|
||||
[(set (match_operand:DI 0 "register_operand" "=r")
|
||||
(plus:DI (match_operand:DI 1 "reg_no_subreg_operand" "r")
|
||||
(match_operand:DI 2 "const_int_operand" "n")))]
|
||||
[(set (match_operand:DI 0 "register_operand" "=r,r,r")
|
||||
(plus:DI (match_operand:DI 1 "reg_no_subreg_operand" "r,r,r")
|
||||
(match_operand:DI 2 "const_int_operand" "K,L,n")))]
|
||||
"NONSTRICT_REG_OK_FP_BASE_P (operands[1])
|
||||
&& INTVAL (operands[2]) >= 0
|
||||
/* This is the largest constant an lda+ldah pair can add, minus
|
||||
@ -454,7 +455,10 @@
|
||||
+ max_reg_num () * UNITS_PER_WORD
|
||||
+ current_function_pretend_args_size)
|
||||
- current_function_pretend_args_size))"
|
||||
"#")
|
||||
"@
|
||||
lda %0,%2(%1)
|
||||
ldah %0,%h2(%1)
|
||||
#")
|
||||
|
||||
;; Don't do this if we are adjusting SP since we don't want to do it
|
||||
;; in two steps. Don't split FP sources for the reason listed above.
|
||||
@ -6897,70 +6901,44 @@
|
||||
"jmp $31,(%0),0"
|
||||
[(set_attr "type" "ibr")])
|
||||
|
||||
(define_insn "*builtin_setjmp_receiver_er_sl_1"
|
||||
[(unspec_volatile [(label_ref (match_operand 0 "" ""))] UNSPECV_SETJMPR)]
|
||||
"TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF && TARGET_AS_CAN_SUBTRACT_LABELS"
|
||||
"lda $27,$LSJ%=-%l0($27)\n$LSJ%=:")
|
||||
|
||||
(define_insn "*builtin_setjmp_receiver_er_1"
|
||||
[(unspec_volatile [(label_ref (match_operand 0 "" ""))] UNSPECV_SETJMPR)]
|
||||
"TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF"
|
||||
"br $27,$LSJ%=\n$LSJ%=:"
|
||||
[(set_attr "type" "ibr")])
|
||||
|
||||
(define_split
|
||||
[(unspec_volatile [(label_ref (match_operand 0 "" ""))] UNSPECV_SETJMPR)]
|
||||
"TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF
|
||||
&& prev_nonnote_insn (insn) == operands[0]"
|
||||
[(const_int 0)]
|
||||
"
|
||||
{
|
||||
emit_note (NOTE_INSN_DELETED);
|
||||
DONE;
|
||||
}")
|
||||
|
||||
(define_insn "*builtin_setjmp_receiver_1"
|
||||
(define_expand "builtin_setjmp_receiver"
|
||||
[(unspec_volatile [(label_ref (match_operand 0 "" ""))] UNSPECV_SETJMPR)]
|
||||
"TARGET_ABI_OSF"
|
||||
"br $27,$LSJ%=\n$LSJ%=:\;ldgp $29,0($27)"
|
||||
[(set_attr "length" "12")
|
||||
(set_attr "type" "multi")])
|
||||
"")
|
||||
|
||||
(define_expand "builtin_setjmp_receiver_er"
|
||||
[(unspec_volatile [(label_ref (match_operand 0 "" ""))] UNSPECV_SETJMPR)
|
||||
(define_insn_and_split "*builtin_setjmp_receiver_1"
|
||||
[(unspec_volatile [(match_operand 0 "" "")] UNSPECV_SETJMPR)]
|
||||
"TARGET_ABI_OSF"
|
||||
{
|
||||
if (TARGET_EXPLICIT_RELOCS)
|
||||
return "#";
|
||||
else
|
||||
return "br $27,$LSJ%=\n$LSJ%=:\;ldgp $29,0($27)";
|
||||
}
|
||||
"&& TARGET_EXPLICIT_RELOCS && reload_completed"
|
||||
[(unspec_volatile [(match_dup 0)] UNSPECV_SETJMPR_ER)
|
||||
(set (match_dup 1)
|
||||
(unspec_volatile:DI [(match_dup 2) (match_dup 3)] UNSPECV_LDGP1))
|
||||
(set (match_dup 1)
|
||||
(unspec:DI [(match_dup 1) (match_dup 3)] UNSPEC_LDGP2))]
|
||||
""
|
||||
{
|
||||
operands[1] = pic_offset_table_rtx;
|
||||
operands[2] = gen_rtx_REG (Pmode, 27);
|
||||
operands[3] = GEN_INT (alpha_next_sequence_number++);
|
||||
})
|
||||
}
|
||||
[(set_attr "length" "12")
|
||||
(set_attr "type" "multi")])
|
||||
|
||||
(define_expand "builtin_setjmp_receiver"
|
||||
[(unspec_volatile [(label_ref (match_operand 0 "" ""))] UNSPECV_SETJMPR)]
|
||||
"TARGET_ABI_OSF"
|
||||
{
|
||||
if (TARGET_EXPLICIT_RELOCS)
|
||||
{
|
||||
emit_insn (gen_builtin_setjmp_receiver_er (operands[0]));
|
||||
DONE;
|
||||
}
|
||||
})
|
||||
(define_insn "*builtin_setjmp_receiver_er_sl_1"
|
||||
[(unspec_volatile [(match_operand 0 "" "")] UNSPECV_SETJMPR_ER)]
|
||||
"TARGET_ABI_OSF && TARGET_EXPLICIT_RELOCS && TARGET_AS_CAN_SUBTRACT_LABELS"
|
||||
"lda $27,$LSJ%=-%l0($27)\n$LSJ%=:")
|
||||
|
||||
(define_expand "exception_receiver_er"
|
||||
[(set (match_dup 0)
|
||||
(unspec_volatile:DI [(match_dup 1) (match_dup 2)] UNSPECV_LDGP1))
|
||||
(set (match_dup 0)
|
||||
(unspec:DI [(match_dup 0) (match_dup 2)] UNSPEC_LDGP2))]
|
||||
""
|
||||
{
|
||||
operands[0] = pic_offset_table_rtx;
|
||||
operands[1] = gen_rtx_REG (Pmode, 26);
|
||||
operands[2] = GEN_INT (alpha_next_sequence_number++);
|
||||
})
|
||||
(define_insn "*builtin_setjmp_receiver_er_1"
|
||||
[(unspec_volatile [(match_operand 0 "" "")] UNSPECV_SETJMPR_ER)]
|
||||
"TARGET_ABI_OSF && TARGET_EXPLICIT_RELOCS"
|
||||
"br $27,$LSJ%=\n$LSJ%=:"
|
||||
[(set_attr "type" "ibr")])
|
||||
|
||||
(define_expand "exception_receiver"
|
||||
[(unspec_volatile [(match_dup 0)] UNSPECV_EHR)]
|
||||
@ -6968,28 +6946,38 @@
|
||||
{
|
||||
if (TARGET_LD_BUGGY_LDGP)
|
||||
operands[0] = alpha_gp_save_rtx ();
|
||||
else if (TARGET_EXPLICIT_RELOCS)
|
||||
{
|
||||
emit_insn (gen_exception_receiver_er ());
|
||||
DONE;
|
||||
}
|
||||
else
|
||||
operands[0] = const0_rtx;
|
||||
})
|
||||
|
||||
(define_insn "*exception_receiver_1"
|
||||
[(unspec_volatile [(const_int 0)] UNSPECV_EHR)]
|
||||
"! TARGET_LD_BUGGY_LDGP"
|
||||
"ldgp $29,0($26)"
|
||||
[(set_attr "length" "8")
|
||||
(set_attr "type" "multi")])
|
||||
|
||||
(define_insn "*exception_receiver_2"
|
||||
[(unspec_volatile [(match_operand:DI 0 "memory_operand" "m")] UNSPECV_EHR)]
|
||||
"TARGET_LD_BUGGY_LDGP"
|
||||
"TARGET_ABI_OSF && TARGET_LD_BUGGY_LDGP"
|
||||
"ldq $29,%0"
|
||||
[(set_attr "type" "ild")])
|
||||
|
||||
(define_insn_and_split "*exception_receiver_1"
|
||||
[(unspec_volatile [(const_int 0)] UNSPECV_EHR)]
|
||||
"TARGET_ABI_OSF"
|
||||
{
|
||||
if (TARGET_EXPLICIT_RELOCS)
|
||||
return "ldah $29,0($26)\t\t!gpdisp!%*\;lda $29,0($29)\t\t!gpdisp!%*";
|
||||
else
|
||||
return "ldgp $29,0($26)";
|
||||
}
|
||||
"&& TARGET_EXPLICIT_RELOCS && reload_completed"
|
||||
[(set (match_dup 0)
|
||||
(unspec_volatile:DI [(match_dup 1) (match_dup 2)] UNSPECV_LDGP1))
|
||||
(set (match_dup 0)
|
||||
(unspec:DI [(match_dup 0) (match_dup 2)] UNSPEC_LDGP2))]
|
||||
{
|
||||
operands[0] = pic_offset_table_rtx;
|
||||
operands[1] = gen_rtx_REG (Pmode, 26);
|
||||
operands[2] = GEN_INT (alpha_next_sequence_number++);
|
||||
}
|
||||
[(set_attr "length" "8")
|
||||
(set_attr "type" "multi")])
|
||||
|
||||
(define_expand "nonlocal_goto_receiver"
|
||||
[(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
|
||||
(set (reg:DI 27) (mem:DI (reg:DI 29)))
|
||||
|
@ -26,6 +26,10 @@
|
||||
# Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
|
||||
# MA 02111-1307, USA.
|
||||
|
||||
#ifdef __ELF__
|
||||
.section .note.GNU-stack,""
|
||||
#endif
|
||||
|
||||
.set noreorder
|
||||
.set noat
|
||||
|
||||
|
@ -16,8 +16,12 @@ SHLIB_LINK = $(GCC_FOR_TARGET) $(LIBGCC2_CFLAGS) -shared -nodefaultlibs \
|
||||
-Wl,-hidden_symbol,pthread\* -Wl,-hidden_symbol,__pthread\* \
|
||||
-Wl,-hidden_symbol,sched_get_\* -Wl,-hidden_symbol,sched_yield \
|
||||
-Wl,-msym -Wl,-set_version,gcc.1 -Wl,-soname,$(SHLIB_SONAME) \
|
||||
-o $(SHLIB_NAME) @multilib_flags@ $(SHLIB_OBJS) -lc && \
|
||||
-o $(SHLIB_NAME).tmp @multilib_flags@ $(SHLIB_OBJS) -lc && \
|
||||
rm -f $(SHLIB_SONAME) && \
|
||||
if [ -f $(SHLIB_NAME) ]; then \
|
||||
mv -f $(SHLIB_NAME) $(SHLIB_NAME).backup; \
|
||||
else true; fi && \
|
||||
mv $(SHLIB_NAME).tmp $(SHLIB_NAME) && \
|
||||
$(LN_S) $(SHLIB_NAME) $(SHLIB_SONAME)
|
||||
# $(slibdir) double quoted to protect it from expansion while building
|
||||
# libgcc.mk. We want this delayed until actual install time.
|
||||
|
@ -1,5 +1,6 @@
|
||||
/* Prototypes for exported functions defined in arm.c and pe.c
|
||||
Copyright (C) 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
|
||||
Copyright (C) 1999, 2000, 2001, 2002, 2003, 2005
|
||||
Free Software Foundation, Inc.
|
||||
Contributed by Richard Earnshaw (rearnsha@arm.com)
|
||||
Minor hacks by Nick Clifton (nickc@cygnus.com)
|
||||
|
||||
@ -138,6 +139,7 @@ extern int arm_debugger_arg_offset (int, rtx);
|
||||
extern int arm_is_longcall_p (rtx, int, int);
|
||||
extern int arm_emit_vector_const (FILE *, rtx);
|
||||
extern const char * arm_output_load_gr (rtx *);
|
||||
extern int arm_eliminable_register (rtx);
|
||||
|
||||
#if defined TREE_CODE
|
||||
extern rtx arm_function_arg (CUMULATIVE_ARGS *, enum machine_mode, tree, int);
|
||||
|
@ -1,6 +1,6 @@
|
||||
/* Output routines for GCC for ARM.
|
||||
Copyright (C) 1991, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
|
||||
2002, 2003, 2004 Free Software Foundation, Inc.
|
||||
2002, 2003, 2004, 2005 Free Software Foundation, Inc.
|
||||
Contributed by Pieter `Tiggr' Schoenmakers (rcpieter@win.tue.nl)
|
||||
and Martin Simmons (@harleqn.co.uk).
|
||||
More major hacks by Richard Earnshaw (rearnsha@arm.com).
|
||||
@ -4056,6 +4056,16 @@ cirrus_shift_const (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
|
||||
&& INTVAL (op) < 64);
|
||||
}
|
||||
|
||||
/* Return true if X is a register that will be eliminated later on. */
|
||||
int
|
||||
arm_eliminable_register (rtx x)
|
||||
{
|
||||
return REG_P (x) && (REGNO (x) == FRAME_POINTER_REGNUM
|
||||
|| REGNO (x) == ARG_POINTER_REGNUM
|
||||
|| (REGNO (x) >= FIRST_VIRTUAL_REGISTER
|
||||
&& REGNO (x) <= LAST_VIRTUAL_REGISTER));
|
||||
}
|
||||
|
||||
/* Returns TRUE if INSN is an "LDR REG, ADDR" instruction.
|
||||
Use by the Cirrus Maverick code which has to workaround
|
||||
a hardware bug triggered by such instructions. */
|
||||
@ -4569,33 +4579,42 @@ adjacent_mem_locations (rtx a, rtx b)
|
||||
|| (GET_CODE (XEXP (b, 0)) == PLUS
|
||||
&& GET_CODE (XEXP (XEXP (b, 0), 1)) == CONST_INT)))
|
||||
{
|
||||
int val0 = 0, val1 = 0;
|
||||
int reg0, reg1;
|
||||
|
||||
HOST_WIDE_INT val0 = 0, val1 = 0;
|
||||
rtx reg0, reg1;
|
||||
int val_diff;
|
||||
|
||||
if (GET_CODE (XEXP (a, 0)) == PLUS)
|
||||
{
|
||||
reg0 = REGNO (XEXP (XEXP (a, 0), 0));
|
||||
reg0 = XEXP (XEXP (a, 0), 0);
|
||||
val0 = INTVAL (XEXP (XEXP (a, 0), 1));
|
||||
}
|
||||
else
|
||||
reg0 = REGNO (XEXP (a, 0));
|
||||
reg0 = XEXP (a, 0);
|
||||
|
||||
if (GET_CODE (XEXP (b, 0)) == PLUS)
|
||||
{
|
||||
reg1 = REGNO (XEXP (XEXP (b, 0), 0));
|
||||
reg1 = XEXP (XEXP (b, 0), 0);
|
||||
val1 = INTVAL (XEXP (XEXP (b, 0), 1));
|
||||
}
|
||||
else
|
||||
reg1 = REGNO (XEXP (b, 0));
|
||||
reg1 = XEXP (b, 0);
|
||||
|
||||
/* Don't accept any offset that will require multiple
|
||||
instructions to handle, since this would cause the
|
||||
arith_adjacentmem pattern to output an overlong sequence. */
|
||||
if (!const_ok_for_op (PLUS, val0) || !const_ok_for_op (PLUS, val1))
|
||||
return 0;
|
||||
|
||||
return (reg0 == reg1) && ((val1 - val0) == 4 || (val0 - val1) == 4);
|
||||
|
||||
/* Don't allow an eliminable register: register elimination can make
|
||||
the offset too large. */
|
||||
if (arm_eliminable_register (reg0))
|
||||
return 0;
|
||||
|
||||
val_diff = val1 - val0;
|
||||
return ((REGNO (reg0) == REGNO (reg1))
|
||||
&& (val_diff == 4 || val_diff == -4));
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -7301,7 +7320,6 @@ output_call_mem (rtx *operands)
|
||||
return "";
|
||||
}
|
||||
|
||||
|
||||
/* Output a move from arm registers to an fpa registers.
|
||||
OPERANDS[0] is an fpa register.
|
||||
OPERANDS[1] is the first registers of an arm register pair. */
|
||||
|
@ -1396,7 +1396,7 @@ enum reg_class
|
||||
: NO_REGS)
|
||||
|
||||
#define THUMB_SECONDARY_OUTPUT_RELOAD_CLASS(CLASS, MODE, X) \
|
||||
((CLASS) != LO_REGS \
|
||||
((CLASS) != LO_REGS && (CLASS) != BASE_REGS \
|
||||
? ((true_regnum (X) == -1 ? LO_REGS \
|
||||
: (true_regnum (X) + HARD_REGNO_NREGS (0, MODE) > 8) ? LO_REGS \
|
||||
: NO_REGS)) \
|
||||
|
@ -5960,22 +5960,24 @@
|
||||
[(set (pc)
|
||||
(if_then_else
|
||||
(match_operator 5 "equality_operator"
|
||||
[(and:SI (not:SI (match_operand:SI 3 "s_register_operand" "l,l,l,l"))
|
||||
(match_operand:SI 2 "s_register_operand" "0,1,1,1"))
|
||||
[(and:SI (not:SI (match_operand:SI 3 "s_register_operand" "l,l,l,l,l"))
|
||||
(match_operand:SI 2 "s_register_operand" "0,1,1,1,1"))
|
||||
(const_int 0)])
|
||||
(label_ref (match_operand 4 "" ""))
|
||||
(pc)))
|
||||
(set (match_operand:SI 0 "thumb_cbrch_target_operand" "=l,*?h,*?m,*?m")
|
||||
(set (match_operand:SI 0 "thumb_cbrch_target_operand" "=!l,l,*?h,*?m,*?m")
|
||||
(and:SI (not:SI (match_dup 3)) (match_dup 2)))
|
||||
(clobber (match_scratch:SI 1 "=X,l,&l,&l"))]
|
||||
(clobber (match_scratch:SI 1 "=X,l,l,&l,&l"))]
|
||||
"TARGET_THUMB"
|
||||
"*
|
||||
{
|
||||
if (which_alternative == 0)
|
||||
output_asm_insn (\"bic\\t%0, %3\", operands);
|
||||
else if (which_alternative == 1)
|
||||
else if (which_alternative <= 2)
|
||||
{
|
||||
output_asm_insn (\"bic\\t%1, %3\", operands);
|
||||
/* It's ok if OP0 is a lo-reg, even though the mov will set the
|
||||
conditions again, since we're only testing for equality. */
|
||||
output_asm_insn (\"mov\\t%0, %1\", operands);
|
||||
}
|
||||
else
|
||||
@ -6234,10 +6236,10 @@
|
||||
case 1:
|
||||
output_asm_insn (\"cmn\t%1, %2\", operands);
|
||||
break;
|
||||
case 3:
|
||||
case 2:
|
||||
output_asm_insn (\"add\t%0, %1, %2\", operands);
|
||||
break;
|
||||
case 4:
|
||||
case 3:
|
||||
output_asm_insn (\"add\t%0, %0, %2\", operands);
|
||||
break;
|
||||
}
|
||||
@ -7128,8 +7130,8 @@
|
||||
(const_string "no")))
|
||||
(set (attr "length")
|
||||
(if_then_else
|
||||
(and (ge (minus (match_dup 0) (pc)) (const_int -2048))
|
||||
(le (minus (match_dup 0) (pc)) (const_int 2044)))
|
||||
(and (ge (minus (match_dup 0) (pc)) (const_int -2044))
|
||||
(le (minus (match_dup 0) (pc)) (const_int 2048)))
|
||||
(const_int 2)
|
||||
(const_int 4)))]
|
||||
)
|
||||
|
@ -11,8 +11,12 @@ SHLIB_OBJS = @shlib_objs@
|
||||
|
||||
SHLIB_LINK = $(GCC_FOR_TARGET) $(LIBGCC2_CFLAGS) -shared -nodefaultlibs \
|
||||
-Wl,-soname,$(SHLIB_SONAME) \
|
||||
-o $(SHLIB_NAME) @multilib_flags@ $(SHLIB_OBJS) -lc && \
|
||||
-o $(SHLIB_NAME).tmp @multilib_flags@ $(SHLIB_OBJS) -lc && \
|
||||
rm -f $(SHLIB_SONAME) && \
|
||||
if [ -f $(SHLIB_NAME) ]; then \
|
||||
mv -f $(SHLIB_NAME) $(SHLIB_NAME).backup; \
|
||||
else true; fi && \
|
||||
mv $(SHLIB_NAME).tmp $(SHLIB_NAME) && \
|
||||
$(LN_S) $(SHLIB_NAME) $(SHLIB_SONAME)
|
||||
# $(slibdir) double quoted to protect it from expansion while building
|
||||
# libgcc.mk. We want this delayed until actual install time.
|
||||
|
10
contrib/gcc/config/arm/t-rtems
Normal file
10
contrib/gcc/config/arm/t-rtems
Normal file
@ -0,0 +1,10 @@
|
||||
# Custom rtems multilibs
|
||||
|
||||
MULTILIB_OPTIONS = marm/mthumb
|
||||
MULTILIB_DIRNAMES = arm thumb
|
||||
MULTILIB_EXCEPTIONS =
|
||||
MULTILIB_MATCHES = marm=mno-thumb
|
||||
|
||||
MULTILIB_OPTIONS += msoft-float/mhard-float
|
||||
MULTILIB_DIRNAMES += soft fpu
|
||||
MULTILIB_EXCEPTIONS += *mthumb/*mhard-float*
|
@ -65,8 +65,6 @@ extern const char *darwin_strip_name_encoding (const char *);
|
||||
|
||||
extern void machopic_finish (FILE *);
|
||||
|
||||
extern void machopic_output_possible_stub_label (FILE *, const char*);
|
||||
|
||||
extern void darwin_exception_section (void);
|
||||
extern void darwin_eh_frame_section (void);
|
||||
extern void machopic_select_section (tree, int, unsigned HOST_WIDE_INT);
|
||||
|
@ -900,10 +900,6 @@ machopic_finish (FILE *asm_out_file)
|
||||
if (! TREE_USED (temp))
|
||||
continue;
|
||||
|
||||
/* If the symbol is actually defined, we don't need a stub. */
|
||||
if (sym_name[0] == '!' && sym_name[1] == 'T')
|
||||
continue;
|
||||
|
||||
sym_name = darwin_strip_name_encoding (sym_name);
|
||||
|
||||
sym = alloca (strlen (sym_name) + 2);
|
||||
@ -1096,37 +1092,6 @@ update_non_lazy_ptrs (const char *name)
|
||||
}
|
||||
}
|
||||
|
||||
/* Function NAME is being defined, and its label has just been output.
|
||||
If there's already a reference to a stub for this function, we can
|
||||
just emit the stub label now and we don't bother emitting the stub later. */
|
||||
|
||||
void
|
||||
machopic_output_possible_stub_label (FILE *file, const char *name)
|
||||
{
|
||||
tree temp;
|
||||
|
||||
/* Ensure we're looking at a section-encoded name. */
|
||||
if (name[0] != '!' || (name[1] != 't' && name[1] != 'T'))
|
||||
return;
|
||||
|
||||
for (temp = machopic_stubs;
|
||||
temp != NULL_TREE;
|
||||
temp = TREE_CHAIN (temp))
|
||||
{
|
||||
const char *sym_name;
|
||||
|
||||
sym_name = IDENTIFIER_POINTER (TREE_VALUE (temp));
|
||||
if (sym_name[0] == '!' && (sym_name[1] == 'T' || sym_name[1] == 't')
|
||||
&& ! strcmp (name+2, sym_name+2))
|
||||
{
|
||||
ASM_OUTPUT_LABEL (file, IDENTIFIER_POINTER (TREE_PURPOSE (temp)));
|
||||
/* Avoid generating a stub for this. */
|
||||
TREE_USED (temp) = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Scan the list of stubs and update any recorded names whose
|
||||
stripped name matches the argument. */
|
||||
|
||||
|
@ -99,7 +99,13 @@ Boston, MA 02111-1307, USA. */
|
||||
Note that an option name with a prefix that matches another option
|
||||
name, that also takes an argument, needs to be modified so the
|
||||
prefix is different, otherwise a '*' after the shorter option will
|
||||
match with the longer one. */
|
||||
match with the longer one.
|
||||
|
||||
The SUBTARGET_OPTION_TRANSLATE_TABLE macro, which _must_ be defined
|
||||
in gcc/config/{i386,rs6000}/darwin.h, should contain any additional
|
||||
command-line option translations specific to the particular target
|
||||
architecture. */
|
||||
|
||||
#define TARGET_OPTION_TRANSLATE_TABLE \
|
||||
{ "-all_load", "-Zall_load" }, \
|
||||
{ "-allowable_client", "-Zallowable_client" }, \
|
||||
@ -126,7 +132,8 @@ Boston, MA 02111-1307, USA. */
|
||||
{ "-multi_module", "-Zmulti_module" }, \
|
||||
{ "-static", "-static -Wa,-static" }, \
|
||||
{ "-single_module", "-Zsingle_module" }, \
|
||||
{ "-unexported_symbols_list", "-Zunexported_symbols_list" }
|
||||
{ "-unexported_symbols_list", "-Zunexported_symbols_list" }, \
|
||||
SUBTARGET_OPTION_TRANSLATE_TABLE
|
||||
|
||||
/* These compiler options take n arguments. */
|
||||
|
||||
@ -390,9 +397,6 @@ do { text_section (); \
|
||||
|| DECL_INITIAL (DECL)) \
|
||||
(* targetm.encode_section_info) (DECL, DECL_RTL (DECL), false); \
|
||||
ASM_OUTPUT_LABEL (FILE, xname); \
|
||||
/* Avoid generating stubs for functions we've just defined by \
|
||||
outputting any required stub name label now. */ \
|
||||
machopic_output_possible_stub_label (FILE, xname); \
|
||||
} while (0)
|
||||
|
||||
#define ASM_DECLARE_CONSTANT_NAME(FILE, NAME, EXP, SIZE) \
|
||||
|
@ -30,13 +30,13 @@ mingw_scan (int argc ATTRIBUTE_UNUSED,
|
||||
const char *const *argv,
|
||||
char **spec_machine)
|
||||
{
|
||||
putenv ("GCC_CYGWIN_MINGW=0");
|
||||
putenv (xstrdup ("GCC_CYGWIN_MINGW=0"));
|
||||
|
||||
while (*++argv)
|
||||
if (strcmp (*argv, "-mno-win32") == 0)
|
||||
putenv ("GCC_CYGWIN_WIN32=0");
|
||||
putenv (xstrdup ("GCC_CYGWIN_WIN32=0"));
|
||||
else if (strcmp (*argv, "-mwin32") == 0)
|
||||
putenv ("GCC_CYGWIN_WIN32=1");
|
||||
putenv (xstrdup ("GCC_CYGWIN_WIN32=1"));
|
||||
else if (strcmp (*argv, "-mno-cygwin") == 0)
|
||||
{
|
||||
char *p = strstr (*spec_machine, "-cygwin");
|
||||
@ -48,7 +48,7 @@ mingw_scan (int argc ATTRIBUTE_UNUSED,
|
||||
strcpy (s + len, "-mingw32");
|
||||
*spec_machine = s;
|
||||
}
|
||||
putenv ("GCC_CYGWIN_MINGW=1");
|
||||
putenv (xstrdup ("GCC_CYGWIN_MINGW=1"));
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
@ -41,6 +41,10 @@ Boston, MA 02111-1307, USA. */
|
||||
#undef CC1_SPEC
|
||||
#define CC1_SPEC "%{!static:-fPIC}"
|
||||
|
||||
/* Use the following macro for any Darwin/x86-specific command-line option
|
||||
translation. */
|
||||
#define SUBTARGET_OPTION_TRANSLATE_TABLE
|
||||
|
||||
#define ASM_SPEC "-arch i386 \
|
||||
%{Zforce_cpusubtype_ALL:-force_cpusubtype_ALL} \
|
||||
%{!Zforce_cpusubtype_ALL:%{mmmx:-force_cpusubtype_ALL}\
|
||||
|
@ -34,7 +34,7 @@
|
||||
#include <xmmintrin.h>
|
||||
|
||||
/* SSE2 */
|
||||
typedef int __v2df __attribute__ ((mode (V2DF)));
|
||||
typedef double __v2df __attribute__ ((mode (V2DF)));
|
||||
typedef int __v2di __attribute__ ((mode (V2DI)));
|
||||
typedef int __v4si __attribute__ ((mode (V4SI)));
|
||||
typedef int __v8hi __attribute__ ((mode (V8HI)));
|
||||
|
@ -31,11 +31,13 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
|
||||
the executable file might be covered by the GNU General Public License. */
|
||||
|
||||
|
||||
#include <windows.h>
|
||||
#ifndef __GTHREAD_HIDE_WIN32API
|
||||
# define __GTHREAD_HIDE_WIN32API 1
|
||||
#endif
|
||||
#undef __GTHREAD_I486_INLINE_LOCK_PRIMITIVES
|
||||
#define __GTHREAD_I486_INLINE_LOCK_PRIMITIVES
|
||||
#include <gthr-win32.h>
|
||||
#include <windows.h>
|
||||
|
||||
/* Windows32 threads specific definitions. The windows32 threading model
|
||||
does not map well into pthread-inspired gcc's threading model, and so
|
||||
@ -61,10 +63,9 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
|
||||
This may cause incorrect error return due to truncation values on
|
||||
hw where sizeof (DWORD) > sizeof (int).
|
||||
|
||||
3. We might consider using Critical Sections instead of Windows32
|
||||
mutexes for better performance, but emulating __gthread_mutex_trylock
|
||||
interface becomes more complicated (Win9x does not support
|
||||
TryEnterCriticalSectioni, while NT does).
|
||||
3. We are currently using a special mutex instead of the Critical
|
||||
Sections, since Win9x does not support TryEnterCriticalSection
|
||||
(while NT does).
|
||||
|
||||
The basic framework should work well enough. In the long term, GCC
|
||||
needs to use Structured Exception Handling on Windows32. */
|
||||
@ -145,23 +146,29 @@ __gthr_win32_setspecific (__gthread_key_t key, const void *ptr)
|
||||
void
|
||||
__gthr_win32_mutex_init_function (__gthread_mutex_t *mutex)
|
||||
{
|
||||
/* Create unnamed mutex with default security attr and no initial owner. */
|
||||
*mutex = CreateMutex (NULL, 0, NULL);
|
||||
mutex->counter = -1;
|
||||
mutex->sema = CreateSemaphore (NULL, 0, 65535, NULL);
|
||||
}
|
||||
|
||||
int
|
||||
__gthr_win32_mutex_lock (__gthread_mutex_t *mutex)
|
||||
{
|
||||
if (WaitForSingleObject (*mutex, INFINITE) == WAIT_OBJECT_0)
|
||||
if (InterlockedIncrement (&mutex->counter) == 0 ||
|
||||
WaitForSingleObject (mutex->sema, INFINITE) == WAIT_OBJECT_0)
|
||||
return 0;
|
||||
else
|
||||
return 1;
|
||||
{
|
||||
/* WaitForSingleObject returns WAIT_FAILED, and we can only do
|
||||
some best-effort cleanup here. */
|
||||
InterlockedDecrement (&mutex->counter);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
__gthr_win32_mutex_trylock (__gthread_mutex_t *mutex)
|
||||
{
|
||||
if (WaitForSingleObject (*mutex, 0) == WAIT_OBJECT_0)
|
||||
if (__GTHR_W32_InterlockedCompareExchange (&mutex->counter, 0, -1) < 0)
|
||||
return 0;
|
||||
else
|
||||
return 1;
|
||||
@ -170,5 +177,8 @@ __gthr_win32_mutex_trylock (__gthread_mutex_t *mutex)
|
||||
int
|
||||
__gthr_win32_mutex_unlock (__gthread_mutex_t *mutex)
|
||||
{
|
||||
return (ReleaseMutex (*mutex) != 0) ? 0 : 1;
|
||||
if (InterlockedDecrement (&mutex->counter) >= 0)
|
||||
return ReleaseSemaphore (mutex->sema, 1, NULL) ? 0 : 1;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
@ -29,6 +29,8 @@ Boston, MA 02111-1307, USA. */
|
||||
FLOAT_MODE (XF, 12, ieee_extended_intel_96_format);
|
||||
ADJUST_FLOAT_FORMAT (XF, (TARGET_128BIT_LONG_DOUBLE
|
||||
? &ieee_extended_intel_128_format
|
||||
: TARGET_96_ROUND_53_LONG_DOUBLE
|
||||
? &ieee_extended_intel_96_round_53_format
|
||||
: &ieee_extended_intel_96_format));
|
||||
ADJUST_BYTESIZE (XF, TARGET_128BIT_LONG_DOUBLE ? 16 : 12);
|
||||
ADJUST_ALIGNMENT (XF, TARGET_128BIT_LONG_DOUBLE ? 16 : 4);
|
||||
|
@ -93,6 +93,7 @@ extern int memory_displacement_operand (rtx, enum machine_mode);
|
||||
extern int cmpsi_operand (rtx, enum machine_mode);
|
||||
extern int long_memory_operand (rtx, enum machine_mode);
|
||||
extern int aligned_operand (rtx, enum machine_mode);
|
||||
extern int compare_operator (rtx, enum machine_mode);
|
||||
extern enum machine_mode ix86_cc_mode (enum rtx_code, rtx, rtx);
|
||||
|
||||
extern int ix86_expand_movstr (rtx, rtx, rtx, rtx);
|
||||
|
@ -36,17 +36,17 @@ xp-bit.c: $(srcdir)/config/fp-bit.c
|
||||
echo '#define EXTENDED_FLOAT_STUBS' > xp-bit.c
|
||||
cat $(srcdir)/config/fp-bit.c >> xp-bit.c
|
||||
|
||||
MULTILIB_OPTIONS = mcpu=i486/mcpu=pentium/mcpu=pentiumpro/mcpu=k6/mcpu=athlon \
|
||||
MULTILIB_OPTIONS = mtune=i486/mtune=pentium/mtune=pentiumpro/mtune=k6/mtune=athlon \
|
||||
msoft-float mno-fp-ret-in-387
|
||||
MULTILIB_DIRNAMES= m486 mpentium mpentiumpro k6 athlon soft-float nofp
|
||||
MULTILIB_MATCHES = msoft-float=mno-m80387
|
||||
MULTILIB_EXCEPTIONS = \
|
||||
mno-fp-ret-in-387 \
|
||||
mcpu=i486/*mno-fp-ret-in-387* \
|
||||
mcpu=pentium/*msoft-float* mcpu=pentium/*mno-fp-ret-in-387* \
|
||||
mcpu=pentiumpro/*msoft-float* mcpu=pentiumpro/*mno-fp-ret-in-387* \
|
||||
mcpu=k6/*msoft-float* mcpu=k6/*mno-fp-ret-in-387* \
|
||||
mcpu=athlon/*msoft-float* mcpu=athlon/*mno-fp-ret-in-387*
|
||||
mtune=i486/*mno-fp-ret-in-387* \
|
||||
mtune=pentium/*msoft-float* mtune=pentium/*mno-fp-ret-in-387* \
|
||||
mtune=pentiumpro/*msoft-float* mtune=pentiumpro/*mno-fp-ret-in-387* \
|
||||
mtune=k6/*msoft-float* mtune=k6/*mno-fp-ret-in-387* \
|
||||
mtune=athlon/*msoft-float* mtune=athlon/*mno-fp-ret-in-387*
|
||||
|
||||
EXTRA_MULTILIB_PARTS = crtbegin.o crtend.o
|
||||
|
||||
|
@ -38,10 +38,10 @@
|
||||
#include <mmintrin.h>
|
||||
|
||||
/* The data type intended for user use. */
|
||||
typedef int __m128 __attribute__ ((__mode__(__V4SF__)));
|
||||
typedef float __m128 __attribute__ ((__mode__(__V4SF__)));
|
||||
|
||||
/* Internal data types for implementing the intrinsics. */
|
||||
typedef int __v4sf __attribute__ ((__mode__(__V4SF__)));
|
||||
typedef float __v4sf __attribute__ ((__mode__(__V4SF__)));
|
||||
|
||||
/* Create a selector for use with the SHUFPS instruction. */
|
||||
#define _MM_SHUFFLE(fp3,fp2,fp1,fp0) \
|
||||
|
@ -390,20 +390,55 @@ call_operand (rtx op, enum machine_mode mode)
|
||||
int
|
||||
sdata_symbolic_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
|
||||
{
|
||||
HOST_WIDE_INT offset = 0, size = 0;
|
||||
|
||||
switch (GET_CODE (op))
|
||||
{
|
||||
case CONST:
|
||||
if (GET_CODE (XEXP (op, 0)) != PLUS
|
||||
|| GET_CODE (XEXP (XEXP (op, 0), 0)) != SYMBOL_REF)
|
||||
op = XEXP (op, 0);
|
||||
if (GET_CODE (op) != PLUS
|
||||
|| GET_CODE (XEXP (op, 0)) != SYMBOL_REF
|
||||
|| GET_CODE (XEXP (op, 1)) != CONST_INT)
|
||||
break;
|
||||
op = XEXP (XEXP (op, 0), 0);
|
||||
offset = INTVAL (XEXP (op, 1));
|
||||
op = XEXP (op, 0);
|
||||
/* FALLTHRU */
|
||||
|
||||
case SYMBOL_REF:
|
||||
if (CONSTANT_POOL_ADDRESS_P (op))
|
||||
return GET_MODE_SIZE (get_pool_mode (op)) <= ia64_section_threshold;
|
||||
{
|
||||
size = GET_MODE_SIZE (get_pool_mode (op));
|
||||
if (size > ia64_section_threshold)
|
||||
return false;
|
||||
}
|
||||
else
|
||||
return SYMBOL_REF_LOCAL_P (op) && SYMBOL_REF_SMALL_P (op);
|
||||
{
|
||||
tree t;
|
||||
|
||||
if (!SYMBOL_REF_LOCAL_P (op) || !SYMBOL_REF_SMALL_P (op))
|
||||
return false;
|
||||
|
||||
/* Note that in addition to DECLs, we can get various forms
|
||||
of constants here. */
|
||||
t = SYMBOL_REF_DECL (op);
|
||||
if (DECL_P (t))
|
||||
t = DECL_SIZE_UNIT (t);
|
||||
else
|
||||
t = TYPE_SIZE_UNIT (TREE_TYPE (t));
|
||||
if (t && host_integerp (t, 0))
|
||||
{
|
||||
size = tree_low_cst (t, 0);
|
||||
if (size < 0)
|
||||
size = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* Deny the stupid user trick of addressing outside the object. Such
|
||||
things quickly result in GPREL22 relocation overflows. Of course,
|
||||
they're also highly undefined. From a pure pedant's point of view
|
||||
they deserve a slap on the wrist (such as provided by a relocation
|
||||
overflow), but that just leads to bugzilla noise. */
|
||||
return (offset >= 0 && offset <= size);
|
||||
|
||||
default:
|
||||
break;
|
||||
@ -3154,10 +3189,13 @@ ia64_expand_epilogue (int sibcall_p)
|
||||
preserve those input registers used as arguments to the sibling call.
|
||||
It is unclear how to compute that number here. */
|
||||
if (current_frame_info.n_input_regs != 0)
|
||||
emit_insn (gen_alloc (gen_rtx_REG (DImode, fp),
|
||||
GEN_INT (0), GEN_INT (0),
|
||||
GEN_INT (current_frame_info.n_input_regs),
|
||||
GEN_INT (0)));
|
||||
{
|
||||
rtx n_inputs = GEN_INT (current_frame_info.n_input_regs);
|
||||
insn = emit_insn (gen_alloc (gen_rtx_REG (DImode, fp),
|
||||
const0_rtx, const0_rtx,
|
||||
n_inputs, const0_rtx));
|
||||
RTX_FRAME_RELATED_P (insn) = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -3283,15 +3321,16 @@ static bool
|
||||
ia64_assemble_integer (rtx x, unsigned int size, int aligned_p)
|
||||
{
|
||||
if (size == POINTER_SIZE / BITS_PER_UNIT
|
||||
&& aligned_p
|
||||
&& !(TARGET_NO_PIC || TARGET_AUTO_PIC)
|
||||
&& GET_CODE (x) == SYMBOL_REF
|
||||
&& SYMBOL_REF_FUNCTION_P (x))
|
||||
{
|
||||
if (POINTER_SIZE == 32)
|
||||
fputs ("\tdata4\t@fptr(", asm_out_file);
|
||||
else
|
||||
fputs ("\tdata8\t@fptr(", asm_out_file);
|
||||
static const char * const directive[2][2] = {
|
||||
/* 64-bit pointer */ /* 32-bit pointer */
|
||||
{ "\tdata8.ua\t@fptr(", "\tdata4.ua\t@fptr("}, /* unaligned */
|
||||
{ "\tdata8\t@fptr(", "\tdata4\t@fptr("} /* aligned */
|
||||
};
|
||||
fputs (directive[(aligned_p != 0)][POINTER_SIZE == 32], asm_out_file);
|
||||
output_addr_const (asm_out_file, x);
|
||||
fputs (")\n", asm_out_file);
|
||||
return true;
|
||||
@ -3917,6 +3956,12 @@ ia64_function_arg_pass_by_reference (CUMULATIVE_ARGS *cum ATTRIBUTE_UNUSED,
|
||||
static bool
|
||||
ia64_function_ok_for_sibcall (tree decl, tree exp ATTRIBUTE_UNUSED)
|
||||
{
|
||||
/* We can't perform a sibcall if the current function has the syscall_linkage
|
||||
attribute. */
|
||||
if (lookup_attribute ("syscall_linkage",
|
||||
TYPE_ATTRIBUTES (TREE_TYPE (current_function_decl))))
|
||||
return false;
|
||||
|
||||
/* We must always return with our current GP. This means we can
|
||||
only sibcall to functions defined in the current module. */
|
||||
return decl && (*targetm.binds_local_p) (decl);
|
||||
@ -7782,13 +7827,24 @@ process_set (FILE *asm_out_file, rtx pat)
|
||||
{
|
||||
dest_regno = REGNO (dest);
|
||||
|
||||
/* If this isn't the final destination for ar.pfs, the alloc
|
||||
shouldn't have been marked frame related. */
|
||||
if (dest_regno != current_frame_info.reg_save_ar_pfs)
|
||||
abort ();
|
||||
|
||||
fprintf (asm_out_file, "\t.save ar.pfs, r%d\n",
|
||||
ia64_dbx_register_number (dest_regno));
|
||||
/* If this is the final destination for ar.pfs, then this must
|
||||
be the alloc in the prologue. */
|
||||
if (dest_regno == current_frame_info.reg_save_ar_pfs)
|
||||
fprintf (asm_out_file, "\t.save ar.pfs, r%d\n",
|
||||
ia64_dbx_register_number (dest_regno));
|
||||
else
|
||||
{
|
||||
/* This must be an alloc before a sibcall. We must drop the
|
||||
old frame info. The easiest way to drop the old frame
|
||||
info is to ensure we had a ".restore sp" directive
|
||||
followed by a new prologue. If the procedure doesn't
|
||||
have a memory-stack frame, we'll issue a dummy ".restore
|
||||
sp" now. */
|
||||
if (current_frame_info.total_size == 0 && !frame_pointer_needed)
|
||||
/* if haven't done process_epilogue() yet, do it now */
|
||||
process_epilogue ();
|
||||
fprintf (asm_out_file, "\t.prologue\n");
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -1 +1,3 @@
|
||||
LIB2ADDEH += $(srcdir)/config/ia64/fde-glibc.c
|
||||
# Use system libunwind library on IA-64 GLIBC based system.
|
||||
LIB2ADDEH = $(srcdir)/unwind-sjlj.c $(srcdir)/unwind-c.c \
|
||||
$(srcdir)/unwind-compat.c
|
||||
|
4
contrib/gcc/config/ia64/t-glibc-libunwind
Normal file
4
contrib/gcc/config/ia64/t-glibc-libunwind
Normal file
@ -0,0 +1,4 @@
|
||||
# Build libunwind for IA-64 GLIBC based system.
|
||||
LIBUNWIND = $(srcdir)/config/ia64/fde-glibc.c \
|
||||
$(srcdir)/config/ia64/unwind-ia64.c
|
||||
LIBUNWINDDEP = unwind.inc
|
@ -23,6 +23,8 @@ LIBGCC1_TEST =
|
||||
# We do not want to include the EH stuff that linux uses, we want to use
|
||||
# the HP-UX libunwind library.
|
||||
|
||||
T_CFLAGS += -DUSE_LIBUNWIND_EXCEPTIONS
|
||||
|
||||
LIB2ADDEH =
|
||||
|
||||
SHLIB_EXT = .so
|
||||
|
@ -37,6 +37,7 @@
|
||||
#include "tm.h"
|
||||
#include "unwind.h"
|
||||
#include "unwind-ia64.h"
|
||||
#include "unwind-compat.h"
|
||||
#include "ia64intrin.h"
|
||||
|
||||
/* This isn't thread safe, but nice for occasional tests. */
|
||||
@ -2274,6 +2275,8 @@ uw_install_context (struct _Unwind_Context *current __attribute__((unused)),
|
||||
"(p6) ldf.fill f22 = [r28] \n\t"
|
||||
"cmp.ne p7, p0 = r0, r29 \n\t"
|
||||
";; \n\t"
|
||||
"ld8 r27 = [r20], 8 \n\t"
|
||||
";; \n\t"
|
||||
"ld8 r28 = [r20], 8 \n\t"
|
||||
"(p7) ldf.fill f23 = [r29] \n\t"
|
||||
"cmp.ne p6, p0 = r0, r22 \n\t"
|
||||
@ -2381,4 +2384,24 @@ uw_identify_context (struct _Unwind_Context *context)
|
||||
}
|
||||
|
||||
#include "unwind.inc"
|
||||
|
||||
#if defined (USE_GAS_SYMVER) && defined (SHARED) && defined (USE_LIBUNWIND_EXCEPTIONS)
|
||||
alias (_Unwind_Backtrace);
|
||||
alias (_Unwind_DeleteException);
|
||||
alias (_Unwind_FindEnclosingFunction);
|
||||
alias (_Unwind_FindTableEntry);
|
||||
alias (_Unwind_ForcedUnwind);
|
||||
alias (_Unwind_GetBSP);
|
||||
alias (_Unwind_GetCFA);
|
||||
alias (_Unwind_GetGR);
|
||||
alias (_Unwind_GetIP);
|
||||
alias (_Unwind_GetLanguageSpecificData);
|
||||
alias (_Unwind_GetRegionStart);
|
||||
alias (_Unwind_RaiseException);
|
||||
alias (_Unwind_Resume);
|
||||
alias (_Unwind_Resume_or_Rethrow);
|
||||
alias (_Unwind_SetGR);
|
||||
alias (_Unwind_SetIP);
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
@ -28,4 +28,5 @@ struct unw_table_entry
|
||||
|
||||
extern struct unw_table_entry *
|
||||
_Unwind_FindTableEntry (void *pc, unsigned long *segment_base,
|
||||
unsigned long *gp);
|
||||
unsigned long *gp)
|
||||
__attribute__ ((__visibility__ ("hidden")));
|
||||
|
@ -1,6 +1,6 @@
|
||||
/* Definitions of target machine for GNU compiler,
|
||||
for IBM RS/6000 POWER running AIX.
|
||||
Copyright (C) 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
|
||||
Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GCC.
|
||||
|
||||
@ -175,15 +175,15 @@
|
||||
#define JUMP_TABLES_IN_TEXT_SECTION 1
|
||||
|
||||
/* Enable AIX XL compiler calling convention breakage compatibility. */
|
||||
#undef TARGET_XL_CALL
|
||||
#define MASK_XL_CALL 0x40000000
|
||||
#define TARGET_XL_CALL (target_flags & MASK_XL_CALL)
|
||||
#undef TARGET_XL_COMPAT
|
||||
#define MASK_XL_COMPAT 0x40000000
|
||||
#define TARGET_XL_COMPAT (target_flags & MASK_XL_COMPAT)
|
||||
#undef SUBTARGET_SWITCHES
|
||||
#define SUBTARGET_SWITCHES \
|
||||
{"xl-call", MASK_XL_CALL, \
|
||||
N_("Always pass floating-point arguments in memory") }, \
|
||||
{"no-xl-call", - MASK_XL_CALL, \
|
||||
N_("Don't always pass floating-point arguments in memory") }, \
|
||||
{"xl-compat", MASK_XL_COMPAT, \
|
||||
N_("Conform more closely to IBM XLC semantics") }, \
|
||||
{"no-xl-compat", - MASK_XL_COMPAT, \
|
||||
N_("Default GCC semantics that differ from IBM XLC") }, \
|
||||
SUBSUBTARGET_SWITCHES
|
||||
#define SUBSUBTARGET_SWITCHES
|
||||
|
||||
@ -209,7 +209,7 @@
|
||||
code that does the save/restore is generated by the linker, so
|
||||
we have no good way to determine at compile time what to do. */
|
||||
|
||||
#ifdef __powerpc64__
|
||||
#ifdef __64BIT__
|
||||
#define MD_FROB_UPDATE_CONTEXT(CTX, FS) \
|
||||
do { \
|
||||
if ((FS)->regs.reg[2].how == REG_UNSAVED) \
|
||||
|
@ -98,3 +98,7 @@
|
||||
#undef RS6000_CALL_GLUE
|
||||
#define RS6000_CALL_GLUE "{cror 31,31,31|nop}"
|
||||
|
||||
/* The IBM AIX 4.x assembler doesn't support forward references in
|
||||
.set directives. We handle this by deferring the output of .set
|
||||
directives to the end of the compilation unit. */
|
||||
#define TARGET_DEFERRED_OUTPUT_DEFS(DECL,TARGET) true
|
||||
|
@ -187,3 +187,8 @@ do { \
|
||||
|
||||
#undef LD_INIT_SWITCH
|
||||
#define LD_INIT_SWITCH "-binitfini"
|
||||
|
||||
/* The IBM AIX 4.x assembler doesn't support forward references in
|
||||
.set directives. We handle this by deferring the output of .set
|
||||
directives to the end of the compilation unit. */
|
||||
#define TARGET_DEFERRED_OUTPUT_DEFS(DECL,TARGET) true
|
||||
|
@ -193,3 +193,7 @@ do { \
|
||||
#undef TARGET_C99_FUNCTIONS
|
||||
#define TARGET_C99_FUNCTIONS 1
|
||||
|
||||
#ifndef _AIX52
|
||||
extern long long int atoll(const char *);
|
||||
#endif
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -594,9 +594,9 @@
|
||||
;; Fused multiply subtract
|
||||
(define_insn "altivec_vnmsubfp"
|
||||
[(set (match_operand:V4SF 0 "register_operand" "=v")
|
||||
(minus:V4SF (mult:V4SF (match_operand:V4SF 1 "register_operand" "v")
|
||||
(neg:V4SF (minus:V4SF (mult:V4SF (match_operand:V4SF 1 "register_operand" "v")
|
||||
(match_operand:V4SF 2 "register_operand" "v"))
|
||||
(match_operand:V4SF 3 "register_operand" "v")))]
|
||||
(match_operand:V4SF 3 "register_operand" "v"))))]
|
||||
"TARGET_ALTIVEC"
|
||||
"vnmsubfp %0,%1,%2,%3"
|
||||
[(set_attr "type" "vecfloat")])
|
||||
|
@ -23,18 +23,6 @@
|
||||
#undef TARGET_VERSION
|
||||
#define TARGET_VERSION fprintf (stderr, " (BeOS/PowerPC)");
|
||||
|
||||
/* Enable AIX XL compiler calling convention breakage compatibility. */
|
||||
#define MASK_XL_CALL 0x40000000
|
||||
#define TARGET_XL_CALL (target_flags & MASK_XL_CALL)
|
||||
#undef SUBTARGET_SWITCHES
|
||||
#define SUBTARGET_SWITCHES \
|
||||
{"xl-call", MASK_XL_CALL, \
|
||||
N_("Always pass floating-point arguments in memory") }, \
|
||||
{"no-xl-call", - MASK_XL_CALL, \
|
||||
N_("Don't always pass floating-point arguments in memory") }, \
|
||||
{"threads", 0}, \
|
||||
{"pe", 0},
|
||||
|
||||
#undef ASM_SPEC
|
||||
#define ASM_SPEC "-u %(asm_cpu)"
|
||||
|
||||
|
2
contrib/gcc/config/rs6000/darwin-ldouble-shared.c
Normal file
2
contrib/gcc/config/rs6000/darwin-ldouble-shared.c
Normal file
@ -0,0 +1,2 @@
|
||||
#define IN_LIBGCC2_S 1
|
||||
#include "darwin-ldouble.c"
|
@ -1,5 +1,5 @@
|
||||
/* 128-bit long double support routines for Darwin.
|
||||
Copyright (C) 1993, 2003, 2004 Free Software Foundation, Inc.
|
||||
Copyright (C) 1993, 2003, 2004, 2005 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GCC.
|
||||
|
||||
@ -48,7 +48,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
|
||||
|
||||
This code currently assumes big-endian. */
|
||||
|
||||
#if !_SOFT_FLOAT && (defined (__MACH__) || defined (__powerpc64__))
|
||||
#if !_SOFT_FLOAT && (defined (__MACH__) || defined (__powerpc64__) || defined (_AIX))
|
||||
|
||||
#define fabs(x) __builtin_fabs(x)
|
||||
|
||||
@ -58,10 +58,27 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
|
||||
but GCC currently generates poor code when a union is used to turn
|
||||
a long double into a pair of doubles. */
|
||||
|
||||
extern long double _xlqadd (double, double, double, double);
|
||||
extern long double _xlqsub (double, double, double, double);
|
||||
extern long double _xlqmul (double, double, double, double);
|
||||
extern long double _xlqdiv (double, double, double, double);
|
||||
extern long double __gcc_qadd (double, double, double, double);
|
||||
extern long double __gcc_qsub (double, double, double, double);
|
||||
extern long double __gcc_qmul (double, double, double, double);
|
||||
extern long double __gcc_qdiv (double, double, double, double);
|
||||
|
||||
#if defined __ELF__ && defined IN_LIBGCC2_S
|
||||
/* Provide definitions of the old symbol names to statisfy apps and
|
||||
shared libs built against an older libgcc. To access the _xlq
|
||||
symbols an explicit version reference is needed, so these won't
|
||||
satisfy an unadorned reference like _xlqadd. If dot symbols are
|
||||
not needed, the assembler will remove the aliases from the symbol
|
||||
table. */
|
||||
__asm__ (".symver __gcc_qadd,_xlqadd@GCC_3.4\n\t"
|
||||
".symver __gcc_qsub,_xlqsub@GCC_3.4\n\t"
|
||||
".symver __gcc_qmul,_xlqmul@GCC_3.4\n\t"
|
||||
".symver __gcc_qdiv,_xlqdiv@GCC_3.4\n\t"
|
||||
".symver .__gcc_qadd,._xlqadd@GCC_3.4\n\t"
|
||||
".symver .__gcc_qsub,._xlqsub@GCC_3.4\n\t"
|
||||
".symver .__gcc_qmul,._xlqmul@GCC_3.4\n\t"
|
||||
".symver .__gcc_qdiv,._xlqdiv@GCC_3.4");
|
||||
#endif
|
||||
|
||||
typedef union
|
||||
{
|
||||
@ -73,7 +90,7 @@ static const double FPKINF = 1.0/0.0;
|
||||
|
||||
/* Add two 'long double' values and return the result. */
|
||||
long double
|
||||
_xlqadd (double a, double b, double c, double d)
|
||||
__gcc_qadd (double a, double b, double c, double d)
|
||||
{
|
||||
longDblUnion z;
|
||||
double t, tau, u, FPR_zero, FPR_PosInf;
|
||||
@ -132,13 +149,13 @@ _xlqadd (double a, double b, double c, double d)
|
||||
}
|
||||
|
||||
long double
|
||||
_xlqsub (double a, double b, double c, double d)
|
||||
__gcc_qsub (double a, double b, double c, double d)
|
||||
{
|
||||
return _xlqadd (a, b, -c, -d);
|
||||
return __gcc_qadd (a, b, -c, -d);
|
||||
}
|
||||
|
||||
long double
|
||||
_xlqmul (double a, double b, double c, double d)
|
||||
__gcc_qmul (double a, double b, double c, double d)
|
||||
{
|
||||
longDblUnion z;
|
||||
double t, tau, u, v, w, FPR_zero, FPR_PosInf;
|
||||
@ -169,7 +186,7 @@ _xlqmul (double a, double b, double c, double d)
|
||||
}
|
||||
|
||||
long double
|
||||
_xlqdiv (double a, double b, double c, double d)
|
||||
__gcc_qdiv (double a, double b, double c, double d)
|
||||
{
|
||||
longDblUnion z;
|
||||
double s, sigma, t, tau, u, v, w, FPR_zero, FPR_PosInf;
|
||||
|
@ -111,6 +111,13 @@ do { \
|
||||
#define SUBTARGET_EXTRA_SPECS \
|
||||
{ "darwin_arch", "ppc" },
|
||||
|
||||
/* The "-faltivec" option should have been called "-maltivec" all along. */
|
||||
#define SUBTARGET_OPTION_TRANSLATE_TABLE \
|
||||
{ "-faltivec", "-maltivec -include altivec.h" }, \
|
||||
{ "-fno-altivec", "-mno-altivec" }, \
|
||||
{ "-Waltivec-long-deprecated", "-mwarn-altivec-long" }, \
|
||||
{ "-Wno-altivec-long-deprecated", "-mno-warn-altivec-long" }
|
||||
|
||||
/* Make both r2 and r3 available for allocation. */
|
||||
#define FIXED_R2 0
|
||||
#define FIXED_R13 0
|
||||
|
@ -252,7 +252,7 @@ FUNC_START(__eabi_convert)
|
||||
|
||||
.Lcvt:
|
||||
lwzu 6,4(3) /* pointer to convert */
|
||||
cmpi 0,6,0
|
||||
cmpwi 0,6,0
|
||||
beq- .Lcvt2 /* if pointer is null, don't convert */
|
||||
|
||||
add 6,6,12 /* convert pointer */
|
||||
|
@ -1,7 +1,7 @@
|
||||
GCC_3.4 {
|
||||
GCC_3.4.4 {
|
||||
# long double support
|
||||
_xlqadd
|
||||
_xlqsub
|
||||
_xlqmul
|
||||
_xlqdiv
|
||||
__gcc_qadd
|
||||
__gcc_qsub
|
||||
__gcc_qmul
|
||||
__gcc_qdiv
|
||||
}
|
||||
|
322
contrib/gcc/config/rs6000/linux-unwind.h
Normal file
322
contrib/gcc/config/rs6000/linux-unwind.h
Normal file
@ -0,0 +1,322 @@
|
||||
/* DWARF2 EH unwinding support for PowerPC and PowerPC64 Linux.
|
||||
Copyright (C) 2004, 2005 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.
|
||||
|
||||
In addition to the permissions in the GNU General Public License,
|
||||
the Free Software Foundation gives you unlimited permission to link
|
||||
the compiled version of this file with other programs, and to
|
||||
distribute those programs without any restriction coming from the
|
||||
use of this file. (The General Public License restrictions do
|
||||
apply in other respects; for example, they cover modification of
|
||||
the file, and distribution when not linked into another program.)
|
||||
|
||||
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. */
|
||||
|
||||
/* This file defines our own versions of various kernel and user
|
||||
structs, so that system headers are not needed, which otherwise
|
||||
can make bootstrapping a new toolchain difficult. Do not use
|
||||
these structs elsewhere; Many fields are missing, particularly
|
||||
from the end of the structures. */
|
||||
|
||||
struct gcc_vregs
|
||||
{
|
||||
__attribute__ ((vector_size (16))) int vr[32];
|
||||
#ifdef __powerpc64__
|
||||
unsigned int pad1[3];
|
||||
unsigned int vscr;
|
||||
unsigned int vsave;
|
||||
unsigned int pad2[3];
|
||||
#else
|
||||
unsigned int vsave;
|
||||
unsigned int pad[2];
|
||||
unsigned int vscr;
|
||||
#endif
|
||||
};
|
||||
|
||||
struct gcc_regs
|
||||
{
|
||||
unsigned long gpr[32];
|
||||
unsigned long nip;
|
||||
unsigned long msr;
|
||||
unsigned long orig_gpr3;
|
||||
unsigned long ctr;
|
||||
unsigned long link;
|
||||
unsigned long xer;
|
||||
unsigned long ccr;
|
||||
unsigned long softe;
|
||||
unsigned long trap;
|
||||
unsigned long dar;
|
||||
unsigned long dsisr;
|
||||
unsigned long result;
|
||||
unsigned long pad1[4];
|
||||
double fpr[32];
|
||||
unsigned int pad2;
|
||||
unsigned int fpscr;
|
||||
#ifdef __powerpc64__
|
||||
struct gcc_vregs *vp;
|
||||
#else
|
||||
unsigned int pad3[2];
|
||||
#endif
|
||||
struct gcc_vregs vregs;
|
||||
};
|
||||
|
||||
struct gcc_ucontext
|
||||
{
|
||||
#ifdef __powerpc64__
|
||||
unsigned long pad[28];
|
||||
#else
|
||||
unsigned long pad[12];
|
||||
#endif
|
||||
struct gcc_regs *regs;
|
||||
struct gcc_regs rsave;
|
||||
};
|
||||
|
||||
#ifdef __powerpc64__
|
||||
|
||||
enum { SIGNAL_FRAMESIZE = 128 };
|
||||
|
||||
/* If the current unwind info (FS) does not contain explicit info
|
||||
saving R2, then we have to do a minor amount of code reading to
|
||||
figure out if it was saved. The big problem here is that the
|
||||
code that does the save/restore is generated by the linker, so
|
||||
we have no good way to determine at compile time what to do. */
|
||||
|
||||
#define MD_FROB_UPDATE_CONTEXT(CTX, FS) \
|
||||
do { \
|
||||
if ((FS)->regs.reg[2].how == REG_UNSAVED) \
|
||||
{ \
|
||||
unsigned int *insn \
|
||||
= (unsigned int *) \
|
||||
_Unwind_GetGR ((CTX), LINK_REGISTER_REGNUM); \
|
||||
if (*insn == 0xE8410028) \
|
||||
_Unwind_SetGRPtr ((CTX), 2, (CTX)->cfa + 40); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
/* If PC is at a sigreturn trampoline, return a pointer to the
|
||||
regs. Otherwise return NULL. */
|
||||
|
||||
#define PPC_LINUX_GET_REGS(CONTEXT) \
|
||||
({ \
|
||||
const unsigned char *pc = (CONTEXT)->ra; \
|
||||
struct gcc_regs *regs = NULL; \
|
||||
\
|
||||
/* addi r1, r1, 128; li r0, 0x0077; sc (sigreturn) */ \
|
||||
/* addi r1, r1, 128; li r0, 0x00AC; sc (rt_sigreturn) */ \
|
||||
if (*(unsigned int *) (pc + 0) != 0x38210000 + SIGNAL_FRAMESIZE \
|
||||
|| *(unsigned int *) (pc + 8) != 0x44000002) \
|
||||
; \
|
||||
else if (*(unsigned int *) (pc + 4) == 0x38000077) \
|
||||
{ \
|
||||
struct sigframe { \
|
||||
char gap[SIGNAL_FRAMESIZE]; \
|
||||
unsigned long pad[7]; \
|
||||
struct gcc_regs *regs; \
|
||||
} *frame = (struct sigframe *) (CONTEXT)->cfa; \
|
||||
regs = frame->regs; \
|
||||
} \
|
||||
else if (*(unsigned int *) (pc + 4) == 0x380000AC) \
|
||||
{ \
|
||||
/* This works for 2.4 kernels, but not for 2.6 kernels with vdso \
|
||||
because pc isn't pointing into the stack. Can be removed when \
|
||||
no one is running 2.4.19 or 2.4.20, the first two ppc64 \
|
||||
kernels released. */ \
|
||||
struct rt_sigframe_24 { \
|
||||
int tramp[6]; \
|
||||
void *pinfo; \
|
||||
struct gcc_ucontext *puc; \
|
||||
} *frame24 = (struct rt_sigframe_24 *) pc; \
|
||||
\
|
||||
/* Test for magic value in *puc of vdso. */ \
|
||||
if ((long) frame24->puc != -21 * 8) \
|
||||
regs = frame24->puc->regs; \
|
||||
else \
|
||||
{ \
|
||||
/* This works for 2.4.21 and later kernels. */ \
|
||||
struct rt_sigframe { \
|
||||
char gap[SIGNAL_FRAMESIZE]; \
|
||||
struct gcc_ucontext uc; \
|
||||
unsigned long pad[2]; \
|
||||
int tramp[6]; \
|
||||
void *pinfo; \
|
||||
struct gcc_ucontext *puc; \
|
||||
} *frame = (struct rt_sigframe *) (CONTEXT)->cfa; \
|
||||
regs = frame->uc.regs; \
|
||||
} \
|
||||
} \
|
||||
regs; \
|
||||
})
|
||||
|
||||
#define LINUX_HWCAP_DEFAULT 0xc0000000
|
||||
|
||||
#define PPC_LINUX_VREGS(REGS) (REGS)->vp
|
||||
|
||||
#else /* !__powerpc64__ */
|
||||
|
||||
enum { SIGNAL_FRAMESIZE = 64 };
|
||||
|
||||
#define PPC_LINUX_GET_REGS(CONTEXT) \
|
||||
({ \
|
||||
const unsigned char *pc = (CONTEXT)->ra; \
|
||||
struct gcc_regs *regs = NULL; \
|
||||
\
|
||||
/* li r0, 0x7777; sc (sigreturn old) */ \
|
||||
/* li r0, 0x0077; sc (sigreturn new) */ \
|
||||
/* li r0, 0x6666; sc (rt_sigreturn old) */ \
|
||||
/* li r0, 0x00AC; sc (rt_sigreturn new) */ \
|
||||
if (*(unsigned int *) (pc + 4) != 0x44000002) \
|
||||
; \
|
||||
else if (*(unsigned int *) (pc + 0) == 0x38007777 \
|
||||
|| *(unsigned int *) (pc + 0) == 0x38000077) \
|
||||
{ \
|
||||
struct sigframe { \
|
||||
char gap[SIGNAL_FRAMESIZE]; \
|
||||
unsigned long pad[7]; \
|
||||
struct gcc_regs *regs; \
|
||||
} *frame = (struct sigframe *) (CONTEXT)->cfa; \
|
||||
regs = frame->regs; \
|
||||
} \
|
||||
else if (*(unsigned int *) (pc + 0) == 0x38006666 \
|
||||
|| *(unsigned int *) (pc + 0) == 0x380000AC) \
|
||||
{ \
|
||||
struct rt_sigframe { \
|
||||
char gap[SIGNAL_FRAMESIZE + 16]; \
|
||||
char siginfo[128]; \
|
||||
struct gcc_ucontext uc; \
|
||||
} *frame = (struct rt_sigframe *) (CONTEXT)->cfa; \
|
||||
regs = frame->uc.regs; \
|
||||
} \
|
||||
regs; \
|
||||
})
|
||||
|
||||
#define LINUX_HWCAP_DEFAULT 0x80000000
|
||||
|
||||
#define PPC_LINUX_VREGS(REGS) &(REGS)->vregs
|
||||
|
||||
#endif
|
||||
|
||||
/* Do code reading to identify a signal frame, and set the frame
|
||||
state data appropriately. See unwind-dw2.c for the structs. */
|
||||
|
||||
#define MD_FALLBACK_FRAME_STATE_FOR(CONTEXT, FS, SUCCESS) \
|
||||
do { \
|
||||
static long hwcap = 0; \
|
||||
struct gcc_regs *regs = PPC_LINUX_GET_REGS (CONTEXT); \
|
||||
long new_cfa; \
|
||||
int i; \
|
||||
\
|
||||
if (regs == NULL) \
|
||||
break; \
|
||||
\
|
||||
new_cfa = regs->gpr[STACK_POINTER_REGNUM]; \
|
||||
(FS)->cfa_how = CFA_REG_OFFSET; \
|
||||
(FS)->cfa_reg = STACK_POINTER_REGNUM; \
|
||||
(FS)->cfa_offset = new_cfa - (long) (CONTEXT)->cfa; \
|
||||
\
|
||||
for (i = 0; i < 32; i++) \
|
||||
if (i != STACK_POINTER_REGNUM) \
|
||||
{ \
|
||||
(FS)->regs.reg[i].how = REG_SAVED_OFFSET; \
|
||||
(FS)->regs.reg[i].loc.offset \
|
||||
= (long) ®s->gpr[i] - new_cfa; \
|
||||
} \
|
||||
\
|
||||
(FS)->regs.reg[CR2_REGNO].how = REG_SAVED_OFFSET; \
|
||||
(FS)->regs.reg[CR2_REGNO].loc.offset \
|
||||
= (long) ®s->ccr - new_cfa; \
|
||||
\
|
||||
(FS)->regs.reg[LINK_REGISTER_REGNUM].how = REG_SAVED_OFFSET; \
|
||||
(FS)->regs.reg[LINK_REGISTER_REGNUM].loc.offset \
|
||||
= (long) ®s->link - new_cfa; \
|
||||
\
|
||||
(FS)->regs.reg[ARG_POINTER_REGNUM].how = REG_SAVED_OFFSET; \
|
||||
(FS)->regs.reg[ARG_POINTER_REGNUM].loc.offset \
|
||||
= (long) ®s->nip - new_cfa; \
|
||||
(FS)->retaddr_column = ARG_POINTER_REGNUM; \
|
||||
\
|
||||
if (hwcap == 0) \
|
||||
{ \
|
||||
/* __libc_stack_end holds the original stack passed to a \
|
||||
process. */ \
|
||||
extern long *__libc_stack_end; \
|
||||
long argc; \
|
||||
char **argv; \
|
||||
char **envp; \
|
||||
struct auxv \
|
||||
{ \
|
||||
long a_type; \
|
||||
long a_val; \
|
||||
} *auxp; \
|
||||
\
|
||||
/* The Linux kernel puts argc first on the stack. */ \
|
||||
argc = __libc_stack_end[0]; \
|
||||
/* Followed by argv, NULL terminated. */ \
|
||||
argv = (char **) __libc_stack_end + 1; \
|
||||
/* Followed by environment string pointers, NULL terminated. */ \
|
||||
envp = argv + argc + 1; \
|
||||
while (*envp++) \
|
||||
continue; \
|
||||
/* Followed by the aux vector, zero terminated. */ \
|
||||
for (auxp = (struct auxv *) envp; auxp->a_type != 0; ++auxp) \
|
||||
if (auxp->a_type == 16) \
|
||||
{ \
|
||||
hwcap = auxp->a_val; \
|
||||
break; \
|
||||
} \
|
||||
\
|
||||
/* These will already be set if we found AT_HWCAP. A non-zero \
|
||||
value stops us looking again if for some reason we couldn't \
|
||||
find AT_HWCAP. */ \
|
||||
hwcap |= LINUX_HWCAP_DEFAULT; \
|
||||
} \
|
||||
\
|
||||
/* If we have a FPU... */ \
|
||||
if (hwcap & 0x08000000) \
|
||||
for (i = 0; i < 32; i++) \
|
||||
{ \
|
||||
(FS)->regs.reg[i + 32].how = REG_SAVED_OFFSET; \
|
||||
(FS)->regs.reg[i + 32].loc.offset \
|
||||
= (long) ®s->fpr[i] - new_cfa; \
|
||||
} \
|
||||
\
|
||||
/* If we have a VMX unit... */ \
|
||||
if (hwcap & 0x10000000) \
|
||||
{ \
|
||||
struct gcc_vregs *vregs; \
|
||||
vregs = PPC_LINUX_VREGS (regs); \
|
||||
if (regs->msr & (1 << 25)) \
|
||||
{ \
|
||||
for (i = 0; i < 32; i++) \
|
||||
{ \
|
||||
(FS)->regs.reg[i + FIRST_ALTIVEC_REGNO].how \
|
||||
= REG_SAVED_OFFSET; \
|
||||
(FS)->regs.reg[i + FIRST_ALTIVEC_REGNO].loc.offset \
|
||||
= (long) &vregs[i] - new_cfa; \
|
||||
} \
|
||||
\
|
||||
(FS)->regs.reg[VSCR_REGNO].how = REG_SAVED_OFFSET; \
|
||||
(FS)->regs.reg[VSCR_REGNO].loc.offset \
|
||||
= (long) &vregs->vscr - new_cfa; \
|
||||
} \
|
||||
\
|
||||
(FS)->regs.reg[VRSAVE_REGNO].how = REG_SAVED_OFFSET; \
|
||||
(FS)->regs.reg[VRSAVE_REGNO].loc.offset \
|
||||
= (long) &vregs->vsave - new_cfa; \
|
||||
} \
|
||||
\
|
||||
goto SUCCESS; \
|
||||
} while (0)
|
@ -1,6 +1,6 @@
|
||||
/* Definitions of target machine for GNU compiler,
|
||||
for PowerPC machines running Linux.
|
||||
Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
|
||||
Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005
|
||||
Free Software Foundation, Inc.
|
||||
Contributed by Michael Meissner (meissner@cygnus.com).
|
||||
|
||||
@ -24,6 +24,14 @@
|
||||
#undef MD_EXEC_PREFIX
|
||||
#undef MD_STARTFILE_PREFIX
|
||||
|
||||
/* Linux doesn't support saving and restoring 64-bit regs in a 32-bit
|
||||
process. */
|
||||
#define OS_MISSING_POWERPC64 1
|
||||
|
||||
/* glibc has float and long double forms of math functions. */
|
||||
#undef TARGET_C99_FUNCTIONS
|
||||
#define TARGET_C99_FUNCTIONS 1
|
||||
|
||||
#undef TARGET_OS_CPP_BUILTINS
|
||||
#define TARGET_OS_CPP_BUILTINS() \
|
||||
do \
|
||||
@ -86,94 +94,16 @@
|
||||
#undef TARGET_64BIT
|
||||
#define TARGET_64BIT 0
|
||||
|
||||
/* We don't need to generate entries in .fixup. */
|
||||
/* We don't need to generate entries in .fixup, except when
|
||||
-mrelocatable or -mrelocatable-lib is given. */
|
||||
#undef RELOCATABLE_NEEDS_FIXUP
|
||||
#define RELOCATABLE_NEEDS_FIXUP \
|
||||
(target_flags & target_flags_explicit & MASK_RELOCATABLE)
|
||||
|
||||
#define TARGET_ASM_FILE_END file_end_indicate_exec_stack
|
||||
|
||||
#define TARGET_HAS_F_SETLKW
|
||||
|
||||
/* Do code reading to identify a signal frame, and set the frame
|
||||
state data appropriately. See unwind-dw2.c for the structs. */
|
||||
|
||||
#ifdef IN_LIBGCC2
|
||||
#include <signal.h>
|
||||
|
||||
/* During the 2.5 kernel series the kernel ucontext was changed, but
|
||||
the new layout is compatible with the old one, so we just define
|
||||
and use the old one here for simplicity and compatibility. */
|
||||
|
||||
struct kernel_old_ucontext {
|
||||
unsigned long uc_flags;
|
||||
struct ucontext *uc_link;
|
||||
stack_t uc_stack;
|
||||
struct sigcontext_struct uc_mcontext;
|
||||
sigset_t uc_sigmask;
|
||||
};
|
||||
|
||||
enum { SIGNAL_FRAMESIZE = 64 };
|
||||
#include "config/rs6000/linux-unwind.h"
|
||||
#endif
|
||||
|
||||
#define MD_FALLBACK_FRAME_STATE_FOR(CONTEXT, FS, SUCCESS) \
|
||||
do { \
|
||||
unsigned char *pc_ = (CONTEXT)->ra; \
|
||||
struct sigcontext *sc_; \
|
||||
long new_cfa_; \
|
||||
int i_; \
|
||||
\
|
||||
/* li r0, 0x7777; sc (sigreturn old) */ \
|
||||
/* li r0, 0x0077; sc (sigreturn new) */ \
|
||||
/* li r0, 0x6666; sc (rt_sigreturn old) */ \
|
||||
/* li r0, 0x00AC; sc (rt_sigreturn new) */ \
|
||||
if (*(unsigned int *) (pc_+4) != 0x44000002) \
|
||||
break; \
|
||||
if (*(unsigned int *) (pc_+0) == 0x38007777 \
|
||||
|| *(unsigned int *) (pc_+0) == 0x38000077) \
|
||||
{ \
|
||||
struct sigframe { \
|
||||
char gap[SIGNAL_FRAMESIZE]; \
|
||||
struct sigcontext sigctx; \
|
||||
} *rt_ = (CONTEXT)->cfa; \
|
||||
sc_ = &rt_->sigctx; \
|
||||
} \
|
||||
else if (*(unsigned int *) (pc_+0) == 0x38006666 \
|
||||
|| *(unsigned int *) (pc_+0) == 0x380000AC) \
|
||||
{ \
|
||||
struct rt_sigframe { \
|
||||
char gap[SIGNAL_FRAMESIZE]; \
|
||||
unsigned long _unused[2]; \
|
||||
struct siginfo *pinfo; \
|
||||
void *puc; \
|
||||
struct siginfo info; \
|
||||
struct kernel_old_ucontext uc; \
|
||||
} *rt_ = (CONTEXT)->cfa; \
|
||||
sc_ = &rt_->uc.uc_mcontext; \
|
||||
} \
|
||||
else \
|
||||
break; \
|
||||
\
|
||||
new_cfa_ = sc_->regs->gpr[STACK_POINTER_REGNUM]; \
|
||||
(FS)->cfa_how = CFA_REG_OFFSET; \
|
||||
(FS)->cfa_reg = STACK_POINTER_REGNUM; \
|
||||
(FS)->cfa_offset = new_cfa_ - (long) (CONTEXT)->cfa; \
|
||||
\
|
||||
for (i_ = 0; i_ < 32; i_++) \
|
||||
if (i_ != STACK_POINTER_REGNUM) \
|
||||
{ \
|
||||
(FS)->regs.reg[i_].how = REG_SAVED_OFFSET; \
|
||||
(FS)->regs.reg[i_].loc.offset \
|
||||
= (long)&(sc_->regs->gpr[i_]) - new_cfa_; \
|
||||
} \
|
||||
\
|
||||
(FS)->regs.reg[LINK_REGISTER_REGNUM].how = REG_SAVED_OFFSET; \
|
||||
(FS)->regs.reg[LINK_REGISTER_REGNUM].loc.offset \
|
||||
= (long)&(sc_->regs->link) - new_cfa_; \
|
||||
\
|
||||
(FS)->regs.reg[CR0_REGNO].how = REG_SAVED_OFFSET; \
|
||||
(FS)->regs.reg[CR0_REGNO].loc.offset \
|
||||
= (long)&(sc_->regs->nip) - new_cfa_; \
|
||||
(FS)->retaddr_column = CR0_REGNO; \
|
||||
goto SUCCESS; \
|
||||
} while (0)
|
||||
|
||||
#define OS_MISSING_POWERPC64 1
|
||||
|
@ -1,6 +1,6 @@
|
||||
/* Definitions of target machine for GNU compiler,
|
||||
for 64 bit PowerPC linux.
|
||||
Copyright (C) 2000, 2001, 2002, 2003, 2004
|
||||
Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005
|
||||
Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GCC.
|
||||
@ -53,8 +53,11 @@
|
||||
#undef PROCESSOR_DEFAULT64
|
||||
#define PROCESSOR_DEFAULT64 PROCESSOR_PPC630
|
||||
|
||||
#undef TARGET_RELOCATABLE
|
||||
#define TARGET_RELOCATABLE (!TARGET_64BIT && (target_flags & MASK_RELOCATABLE))
|
||||
/* We don't need to generate entries in .fixup, except when
|
||||
-mrelocatable or -mrelocatable-lib is given. */
|
||||
#undef RELOCATABLE_NEEDS_FIXUP
|
||||
#define RELOCATABLE_NEEDS_FIXUP \
|
||||
(target_flags & target_flags_explicit & MASK_RELOCATABLE)
|
||||
|
||||
#undef RS6000_ABI_NAME
|
||||
#define RS6000_ABI_NAME (TARGET_64BIT ? "aixdesc" : "sysv")
|
||||
@ -188,6 +191,8 @@
|
||||
#define TARGET_EABI 0
|
||||
#undef TARGET_PROTOTYPE
|
||||
#define TARGET_PROTOTYPE 0
|
||||
#undef RELOCATABLE_NEEDS_FIXUP
|
||||
#define RELOCATABLE_NEEDS_FIXUP 0
|
||||
|
||||
#endif
|
||||
|
||||
@ -212,9 +217,6 @@
|
||||
#define PROFILE_HOOK(LABEL) \
|
||||
do { if (TARGET_64BIT) output_profile_hook (LABEL); } while (0)
|
||||
|
||||
/* We don't need to generate entries in .fixup. */
|
||||
#undef RELOCATABLE_NEEDS_FIXUP
|
||||
|
||||
/* PowerPC64 Linux word-aligns FP doubles when -malign-power is given. */
|
||||
#undef ADJUST_FIELD_ALIGN
|
||||
#define ADJUST_FIELD_ALIGN(FIELD, COMPUTED) \
|
||||
@ -287,6 +289,14 @@
|
||||
#undef MD_EXEC_PREFIX
|
||||
#undef MD_STARTFILE_PREFIX
|
||||
|
||||
/* Linux doesn't support saving and restoring 64-bit regs in a 32-bit
|
||||
process. */
|
||||
#define OS_MISSING_POWERPC64 !TARGET_64BIT
|
||||
|
||||
/* glibc has float and long double forms of math functions. */
|
||||
#undef TARGET_C99_FUNCTIONS
|
||||
#define TARGET_C99_FUNCTIONS 1
|
||||
|
||||
#undef TARGET_OS_CPP_BUILTINS
|
||||
#define TARGET_OS_CPP_BUILTINS() \
|
||||
do \
|
||||
@ -541,182 +551,13 @@ while (0)
|
||||
#undef DRAFT_V4_STRUCT_RET
|
||||
#define DRAFT_V4_STRUCT_RET (!TARGET_64BIT)
|
||||
|
||||
#define TARGET_ASM_FILE_END file_end_indicate_exec_stack
|
||||
#define TARGET_ASM_FILE_END rs6000_elf_end_indicate_exec_stack
|
||||
|
||||
#define TARGET_HAS_F_SETLKW
|
||||
|
||||
#define LINK_GCC_C_SEQUENCE_SPEC \
|
||||
"%{static:--start-group} %G %L %{static:--end-group}%{!static:%G}"
|
||||
|
||||
/* Do code reading to identify a signal frame, and set the frame
|
||||
state data appropriately. See unwind-dw2.c for the structs. */
|
||||
|
||||
#ifdef IN_LIBGCC2
|
||||
#include <signal.h>
|
||||
#ifdef __powerpc64__
|
||||
#include <sys/ucontext.h>
|
||||
|
||||
enum { SIGNAL_FRAMESIZE = 128 };
|
||||
|
||||
#else
|
||||
|
||||
/* During the 2.5 kernel series the kernel ucontext was changed, but
|
||||
the new layout is compatible with the old one, so we just define
|
||||
and use the old one here for simplicity and compatibility. */
|
||||
|
||||
struct kernel_old_ucontext {
|
||||
unsigned long uc_flags;
|
||||
struct ucontext *uc_link;
|
||||
stack_t uc_stack;
|
||||
struct sigcontext_struct uc_mcontext;
|
||||
sigset_t uc_sigmask;
|
||||
};
|
||||
enum { SIGNAL_FRAMESIZE = 64 };
|
||||
#include "config/rs6000/linux-unwind.h"
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef __powerpc64__
|
||||
|
||||
/* If the current unwind info (FS) does not contain explicit info
|
||||
saving R2, then we have to do a minor amount of code reading to
|
||||
figure out if it was saved. The big problem here is that the
|
||||
code that does the save/restore is generated by the linker, so
|
||||
we have no good way to determine at compile time what to do. */
|
||||
|
||||
#define MD_FROB_UPDATE_CONTEXT(CTX, FS) \
|
||||
do { \
|
||||
if ((FS)->regs.reg[2].how == REG_UNSAVED) \
|
||||
{ \
|
||||
unsigned int *insn \
|
||||
= (unsigned int *) \
|
||||
_Unwind_GetGR ((CTX), LINK_REGISTER_REGNUM); \
|
||||
if (*insn == 0xE8410028) \
|
||||
_Unwind_SetGRPtr ((CTX), 2, (CTX)->cfa + 40); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define MD_FALLBACK_FRAME_STATE_FOR(CONTEXT, FS, SUCCESS) \
|
||||
do { \
|
||||
unsigned char *pc_ = (CONTEXT)->ra; \
|
||||
struct sigcontext *sc_; \
|
||||
long new_cfa_; \
|
||||
int i_; \
|
||||
\
|
||||
/* addi r1, r1, 128; li r0, 0x0077; sc (sigreturn) */ \
|
||||
/* addi r1, r1, 128; li r0, 0x00AC; sc (rt_sigreturn) */ \
|
||||
if (*(unsigned int *) (pc_+0) != 0x38210000 + SIGNAL_FRAMESIZE \
|
||||
|| *(unsigned int *) (pc_+8) != 0x44000002) \
|
||||
break; \
|
||||
if (*(unsigned int *) (pc_+4) == 0x38000077) \
|
||||
{ \
|
||||
struct sigframe { \
|
||||
char gap[SIGNAL_FRAMESIZE]; \
|
||||
struct sigcontext sigctx; \
|
||||
} *rt_ = (CONTEXT)->cfa; \
|
||||
sc_ = &rt_->sigctx; \
|
||||
} \
|
||||
else if (*(unsigned int *) (pc_+4) == 0x380000AC) \
|
||||
{ \
|
||||
struct rt_sigframe { \
|
||||
int tramp[6]; \
|
||||
struct siginfo *pinfo; \
|
||||
struct ucontext *puc; \
|
||||
} *rt_ = (struct rt_sigframe *) pc_; \
|
||||
sc_ = &rt_->puc->uc_mcontext; \
|
||||
} \
|
||||
else \
|
||||
break; \
|
||||
\
|
||||
new_cfa_ = sc_->regs->gpr[STACK_POINTER_REGNUM]; \
|
||||
(FS)->cfa_how = CFA_REG_OFFSET; \
|
||||
(FS)->cfa_reg = STACK_POINTER_REGNUM; \
|
||||
(FS)->cfa_offset = new_cfa_ - (long) (CONTEXT)->cfa; \
|
||||
\
|
||||
for (i_ = 0; i_ < 32; i_++) \
|
||||
if (i_ != STACK_POINTER_REGNUM) \
|
||||
{ \
|
||||
(FS)->regs.reg[i_].how = REG_SAVED_OFFSET; \
|
||||
(FS)->regs.reg[i_].loc.offset \
|
||||
= (long)&(sc_->regs->gpr[i_]) - new_cfa_; \
|
||||
} \
|
||||
\
|
||||
(FS)->regs.reg[LINK_REGISTER_REGNUM].how = REG_SAVED_OFFSET; \
|
||||
(FS)->regs.reg[LINK_REGISTER_REGNUM].loc.offset \
|
||||
= (long)&(sc_->regs->link) - new_cfa_; \
|
||||
\
|
||||
(FS)->regs.reg[ARG_POINTER_REGNUM].how = REG_SAVED_OFFSET; \
|
||||
(FS)->regs.reg[ARG_POINTER_REGNUM].loc.offset \
|
||||
= (long)&(sc_->regs->nip) - new_cfa_; \
|
||||
(FS)->retaddr_column = ARG_POINTER_REGNUM; \
|
||||
goto SUCCESS; \
|
||||
} while (0)
|
||||
|
||||
#else
|
||||
|
||||
#define MD_FALLBACK_FRAME_STATE_FOR(CONTEXT, FS, SUCCESS) \
|
||||
do { \
|
||||
unsigned char *pc_ = (CONTEXT)->ra; \
|
||||
struct sigcontext *sc_; \
|
||||
long new_cfa_; \
|
||||
int i_; \
|
||||
\
|
||||
/* li r0, 0x7777; sc (sigreturn old) */ \
|
||||
/* li r0, 0x0077; sc (sigreturn new) */ \
|
||||
/* li r0, 0x6666; sc (rt_sigreturn old) */ \
|
||||
/* li r0, 0x00AC; sc (rt_sigreturn new) */ \
|
||||
if (*(unsigned int *) (pc_+4) != 0x44000002) \
|
||||
break; \
|
||||
if (*(unsigned int *) (pc_+0) == 0x38007777 \
|
||||
|| *(unsigned int *) (pc_+0) == 0x38000077) \
|
||||
{ \
|
||||
struct sigframe { \
|
||||
char gap[SIGNAL_FRAMESIZE]; \
|
||||
struct sigcontext sigctx; \
|
||||
} *rt_ = (CONTEXT)->cfa; \
|
||||
sc_ = &rt_->sigctx; \
|
||||
} \
|
||||
else if (*(unsigned int *) (pc_+0) == 0x38006666 \
|
||||
|| *(unsigned int *) (pc_+0) == 0x380000AC) \
|
||||
{ \
|
||||
struct rt_sigframe { \
|
||||
char gap[SIGNAL_FRAMESIZE]; \
|
||||
unsigned long _unused[2]; \
|
||||
struct siginfo *pinfo; \
|
||||
void *puc; \
|
||||
struct siginfo info; \
|
||||
struct kernel_old_ucontext uc; \
|
||||
} *rt_ = (CONTEXT)->cfa; \
|
||||
sc_ = &rt_->uc.uc_mcontext; \
|
||||
} \
|
||||
else \
|
||||
break; \
|
||||
\
|
||||
new_cfa_ = sc_->regs->gpr[STACK_POINTER_REGNUM]; \
|
||||
(FS)->cfa_how = CFA_REG_OFFSET; \
|
||||
(FS)->cfa_reg = STACK_POINTER_REGNUM; \
|
||||
(FS)->cfa_offset = new_cfa_ - (long) (CONTEXT)->cfa; \
|
||||
\
|
||||
for (i_ = 0; i_ < 32; i_++) \
|
||||
if (i_ != STACK_POINTER_REGNUM) \
|
||||
{ \
|
||||
(FS)->regs.reg[i_].how = REG_SAVED_OFFSET; \
|
||||
(FS)->regs.reg[i_].loc.offset \
|
||||
= (long)&(sc_->regs->gpr[i_]) - new_cfa_; \
|
||||
} \
|
||||
\
|
||||
(FS)->regs.reg[LINK_REGISTER_REGNUM].how = REG_SAVED_OFFSET; \
|
||||
(FS)->regs.reg[LINK_REGISTER_REGNUM].loc.offset \
|
||||
= (long)&(sc_->regs->link) - new_cfa_; \
|
||||
\
|
||||
(FS)->regs.reg[CR0_REGNO].how = REG_SAVED_OFFSET; \
|
||||
(FS)->regs.reg[CR0_REGNO].loc.offset \
|
||||
= (long)&(sc_->regs->nip) - new_cfa_; \
|
||||
(FS)->retaddr_column = CR0_REGNO; \
|
||||
goto SUCCESS; \
|
||||
} while (0)
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#define OS_MISSING_POWERPC64 !TARGET_64BIT
|
||||
|
@ -62,13 +62,13 @@ rs6000_pragma_longcall (cpp_reader *pfile ATTRIBUTE_UNUSED)
|
||||
if (c_lex (&x) != CPP_CLOSE_PAREN)
|
||||
SYNTAX_ERROR ("missing close paren");
|
||||
|
||||
if (n != integer_zero_node && n != integer_one_node)
|
||||
if (!integer_zerop (n) && !integer_onep (n))
|
||||
SYNTAX_ERROR ("number must be 0 or 1");
|
||||
|
||||
if (c_lex (&x) != CPP_EOF)
|
||||
warning ("junk at end of #pragma longcall");
|
||||
|
||||
rs6000_default_long_calls = (n == integer_one_node);
|
||||
rs6000_default_long_calls = integer_onep (n);
|
||||
}
|
||||
|
||||
/* Handle defining many CPP flags based on TARGET_xxx. As a general
|
||||
@ -92,7 +92,15 @@ rs6000_cpu_cpp_builtins (cpp_reader *pfile)
|
||||
if (! TARGET_POWER && ! TARGET_POWER2 && ! TARGET_POWERPC)
|
||||
builtin_define ("_ARCH_COM");
|
||||
if (TARGET_ALTIVEC)
|
||||
builtin_define ("__ALTIVEC__");
|
||||
{
|
||||
builtin_define ("__ALTIVEC__");
|
||||
builtin_define ("__VEC__=10206");
|
||||
|
||||
/* Define the AltiVec syntactic elements. */
|
||||
builtin_define ("__vector=__attribute__((altivec(vector__)))");
|
||||
builtin_define ("__pixel=__attribute__((altivec(pixel__))) unsigned short");
|
||||
builtin_define ("__bool=__attribute__((altivec(bool__))) unsigned");
|
||||
}
|
||||
if (TARGET_SPE)
|
||||
builtin_define ("__SPE__");
|
||||
if (TARGET_SOFT_FLOAT)
|
||||
|
@ -116,7 +116,7 @@ extern enum rtx_code rs6000_reverse_condition (enum machine_mode,
|
||||
extern void rs6000_emit_sCOND (enum rtx_code, rtx);
|
||||
extern void rs6000_emit_cbranch (enum rtx_code, rtx);
|
||||
extern char * output_cbranch (rtx, const char *, int, rtx);
|
||||
extern char * output_e500_flip_gt_bit (rtx, rtx);
|
||||
extern char * output_e500_flip_eq_bit (rtx, rtx);
|
||||
extern rtx rs6000_emit_set_const (rtx, enum machine_mode, rtx, int);
|
||||
extern int rs6000_emit_cmove (rtx, rtx, rtx, rtx);
|
||||
extern void rs6000_emit_minmax (rtx, enum rtx_code, rtx, rtx);
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -258,7 +258,7 @@ extern int target_flags;
|
||||
#define TARGET_POWERPC64 (target_flags & MASK_POWERPC64)
|
||||
#endif
|
||||
|
||||
#define TARGET_XL_CALL 0
|
||||
#define TARGET_XL_COMPAT 0
|
||||
|
||||
/* Run-time compilation parameters selecting different hardware subsets.
|
||||
|
||||
@ -464,6 +464,9 @@ enum group_termination
|
||||
{"longcall", &rs6000_longcall_switch, \
|
||||
N_("Avoid all range limits on call instructions"), 0}, \
|
||||
{"no-longcall", &rs6000_longcall_switch, "", 0}, \
|
||||
{"warn-altivec-long", &rs6000_warn_altivec_long_switch, \
|
||||
N_("Warn about deprecated 'vector long ...' AltiVec type usage"), 0}, \
|
||||
{"no-warn-altivec-long", &rs6000_warn_altivec_long_switch, "", 0}, \
|
||||
{"sched-costly-dep=", &rs6000_sched_costly_dep_str, \
|
||||
N_("Determine which dependences between insns are considered costly"), 0}, \
|
||||
{"insert-sched-nops=", &rs6000_sched_insert_nops_str, \
|
||||
@ -532,6 +535,9 @@ extern enum rs6000_dependence_cost rs6000_sched_costly_dep;
|
||||
extern const char *rs6000_sched_insert_nops_str;
|
||||
extern enum rs6000_nop_insertion rs6000_sched_insert_nops;
|
||||
|
||||
extern int rs6000_warn_altivec_long;
|
||||
extern const char *rs6000_warn_altivec_long_switch;
|
||||
|
||||
/* Alignment options for fields in structures for sub-targets following
|
||||
AIX-like ABI.
|
||||
ALIGN_POWER word-aligns FP doubles (default AIX ABI).
|
||||
@ -1165,6 +1171,9 @@ extern enum rs6000_nop_insertion rs6000_sched_insert_nops;
|
||||
= fixed_regs[RS6000_PIC_OFFSET_TABLE_REGNUM] \
|
||||
= call_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM] \
|
||||
= call_really_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM] = 1; \
|
||||
if (TARGET_TOC && TARGET_MINIMAL_TOC) \
|
||||
fixed_regs[RS6000_PIC_OFFSET_TABLE_REGNUM] \
|
||||
= call_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM] = 1; \
|
||||
if (TARGET_ALTIVEC) \
|
||||
global_regs[VSCR_REGNO] = 1; \
|
||||
if (TARGET_SPE) \
|
||||
@ -2918,9 +2927,10 @@ enum rs6000_builtins
|
||||
ALTIVEC_BUILTIN_ABS_V4SI,
|
||||
ALTIVEC_BUILTIN_ABS_V4SF,
|
||||
ALTIVEC_BUILTIN_ABS_V8HI,
|
||||
ALTIVEC_BUILTIN_ABS_V16QI
|
||||
ALTIVEC_BUILTIN_ABS_V16QI,
|
||||
ALTIVEC_BUILTIN_COMPILETIME_ERROR,
|
||||
/* SPE builtins. */
|
||||
, SPE_BUILTIN_EVADDW,
|
||||
SPE_BUILTIN_EVADDW,
|
||||
SPE_BUILTIN_EVAND,
|
||||
SPE_BUILTIN_EVANDC,
|
||||
SPE_BUILTIN_EVDIVWS,
|
||||
|
@ -1,6 +1,6 @@
|
||||
;; Machine description for IBM RISC System 6000 (POWER) for GNU C compiler
|
||||
;; Copyright (C) 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
|
||||
;; 1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
|
||||
;; 1999, 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
|
||||
;; Contributed by Richard Kenner (kenner@vlsi1.ultra.nyu.edu)
|
||||
|
||||
;; This file is part of GCC.
|
||||
@ -50,7 +50,7 @@
|
||||
(UNSPEC_TLSGOTTPREL 28)
|
||||
(UNSPEC_TLSTLS 29)
|
||||
(UNSPEC_FIX_TRUNC_TF 30) ; fadd, rounding towards zero
|
||||
(UNSPEC_MV_CR_GT 31) ; move_from_CR_gt_bit
|
||||
(UNSPEC_MV_CR_EQ 31) ; move_from_CR_eq_bit
|
||||
])
|
||||
|
||||
;;
|
||||
@ -2404,61 +2404,6 @@
|
||||
}"
|
||||
[(set_attr "length" "8")])
|
||||
|
||||
(define_insn_and_split "*andsi3_internal7"
|
||||
[(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
|
||||
(compare:CC (and:SI (match_operand:SI 0 "gpc_reg_operand" "r,r")
|
||||
(match_operand:SI 1 "mask_operand_wrap" "i,i"))
|
||||
(const_int 0)))
|
||||
(clobber (match_scratch:SI 3 "=r,r"))]
|
||||
"TARGET_POWERPC64"
|
||||
"#"
|
||||
"TARGET_POWERPC64"
|
||||
[(parallel [(set (match_dup 2)
|
||||
(compare:CC (and:SI (rotate:SI (match_dup 0) (match_dup 4))
|
||||
(match_dup 5))
|
||||
(const_int 0)))
|
||||
(clobber (match_dup 3))])]
|
||||
"
|
||||
{
|
||||
int mb = extract_MB (operands[1]);
|
||||
int me = extract_ME (operands[1]);
|
||||
operands[4] = GEN_INT (me + 1);
|
||||
operands[5] = GEN_INT (~((HOST_WIDE_INT) -1 << (33 + me - mb)));
|
||||
}"
|
||||
[(set_attr "type" "delayed_compare,compare")
|
||||
(set_attr "length" "4,8")])
|
||||
|
||||
(define_insn_and_split "*andsi3_internal8"
|
||||
[(set (match_operand:CC 3 "cc_reg_operand" "=x,??y")
|
||||
(compare:CC (and:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
|
||||
(match_operand:SI 2 "mask_operand_wrap" "i,i"))
|
||||
(const_int 0)))
|
||||
(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
|
||||
(and:SI (match_dup 1)
|
||||
(match_dup 2)))]
|
||||
"TARGET_POWERPC64"
|
||||
"#"
|
||||
"TARGET_POWERPC64"
|
||||
[(parallel [(set (match_dup 3)
|
||||
(compare:CC (and:SI (rotate:SI (match_dup 1) (match_dup 4))
|
||||
(match_dup 5))
|
||||
(const_int 0)))
|
||||
(set (match_dup 0)
|
||||
(and:SI (rotate:SI (match_dup 1) (match_dup 4))
|
||||
(match_dup 5)))])
|
||||
(set (match_dup 0)
|
||||
(rotate:SI (match_dup 0) (match_dup 6)))]
|
||||
"
|
||||
{
|
||||
int mb = extract_MB (operands[2]);
|
||||
int me = extract_ME (operands[2]);
|
||||
operands[4] = GEN_INT (me + 1);
|
||||
operands[6] = GEN_INT (32 - (me + 1));
|
||||
operands[5] = GEN_INT (~((HOST_WIDE_INT) -1 << (33 + me - mb)));
|
||||
}"
|
||||
[(set_attr "type" "delayed_compare,compare")
|
||||
(set_attr "length" "8,12")])
|
||||
|
||||
(define_expand "iorsi3"
|
||||
[(set (match_operand:SI 0 "gpc_reg_operand" "")
|
||||
(ior:SI (match_operand:SI 1 "gpc_reg_operand" "")
|
||||
@ -5245,16 +5190,18 @@
|
||||
(define_expand "floatdisf2"
|
||||
[(set (match_operand:SF 0 "gpc_reg_operand" "")
|
||||
(float:SF (match_operand:DI 1 "gpc_reg_operand" "")))]
|
||||
"TARGET_64BIT && TARGET_HARD_FLOAT && TARGET_FPRS"
|
||||
"TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS"
|
||||
"
|
||||
{
|
||||
rtx val = operands[1];
|
||||
if (!flag_unsafe_math_optimizations)
|
||||
{
|
||||
rtx label = gen_label_rtx ();
|
||||
emit_insn (gen_floatdisf2_internal2 (operands[1], label));
|
||||
val = gen_reg_rtx (DImode);
|
||||
emit_insn (gen_floatdisf2_internal2 (val, operands[1], label));
|
||||
emit_label (label);
|
||||
}
|
||||
emit_insn (gen_floatdisf2_internal1 (operands[0], operands[1]));
|
||||
emit_insn (gen_floatdisf2_internal1 (operands[0], val));
|
||||
DONE;
|
||||
}")
|
||||
|
||||
@ -5279,30 +5226,31 @@
|
||||
;; by a bit that won't be lost at that stage, but is below the SFmode
|
||||
;; rounding position.
|
||||
(define_expand "floatdisf2_internal2"
|
||||
[(parallel [(set (match_dup 4)
|
||||
(compare:CC (and:DI (match_operand:DI 0 "" "")
|
||||
(const_int 2047))
|
||||
(const_int 0)))
|
||||
(set (match_dup 2) (and:DI (match_dup 0) (const_int 2047)))
|
||||
(clobber (match_scratch:CC 7 ""))])
|
||||
(set (match_dup 3) (ashiftrt:DI (match_dup 0) (const_int 53)))
|
||||
(set (match_dup 3) (plus:DI (match_dup 3) (const_int 1)))
|
||||
(set (pc) (if_then_else (eq (match_dup 4) (const_int 0))
|
||||
(label_ref (match_operand:DI 1 "" ""))
|
||||
[(set (match_dup 3) (ashiftrt:DI (match_operand:DI 1 "" "")
|
||||
(const_int 53)))
|
||||
(parallel [(set (match_operand:DI 0 "" "") (and:DI (match_dup 1)
|
||||
(const_int 2047)))
|
||||
(clobber (scratch:CC))])
|
||||
(set (match_dup 3) (plus:DI (match_dup 3)
|
||||
(const_int 1)))
|
||||
(set (match_dup 0) (plus:DI (match_dup 0)
|
||||
(const_int 2047)))
|
||||
(set (match_dup 4) (compare:CCUNS (match_dup 3)
|
||||
(const_int 3)))
|
||||
(set (match_dup 0) (ior:DI (match_dup 0)
|
||||
(match_dup 1)))
|
||||
(parallel [(set (match_dup 0) (and:DI (match_dup 0)
|
||||
(const_int -2048)))
|
||||
(clobber (scratch:CC))])
|
||||
(set (pc) (if_then_else (geu (match_dup 4) (const_int 0))
|
||||
(label_ref (match_operand:DI 2 "" ""))
|
||||
(pc)))
|
||||
(set (match_dup 5) (compare:CCUNS (match_dup 3) (const_int 2)))
|
||||
(set (pc) (if_then_else (ltu (match_dup 5) (const_int 0))
|
||||
(label_ref (match_dup 1))
|
||||
(pc)))
|
||||
(set (match_dup 0) (xor:DI (match_dup 0) (match_dup 2)))
|
||||
(set (match_dup 0) (ior:DI (match_dup 0) (const_int 2048)))]
|
||||
"TARGET_64BIT && TARGET_HARD_FLOAT && TARGET_FPRS"
|
||||
(set (match_dup 0) (match_dup 1))]
|
||||
"TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS"
|
||||
"
|
||||
{
|
||||
operands[2] = gen_reg_rtx (DImode);
|
||||
operands[3] = gen_reg_rtx (DImode);
|
||||
operands[4] = gen_reg_rtx (CCmode);
|
||||
operands[5] = gen_reg_rtx (CCUNSmode);
|
||||
operands[4] = gen_reg_rtx (CCUNSmode);
|
||||
}")
|
||||
|
||||
;; Define the DImode operations that can be done in a small number
|
||||
@ -8311,14 +8259,36 @@
|
||||
DONE;
|
||||
})
|
||||
|
||||
(define_insn "trunctfdf2"
|
||||
[(set (match_operand:DF 0 "gpc_reg_operand" "=f")
|
||||
(float_truncate:DF (match_operand:TF 1 "gpc_reg_operand" "f")))]
|
||||
(define_expand "trunctfdf2"
|
||||
[(set (match_operand:DF 0 "gpc_reg_operand" "")
|
||||
(float_truncate:DF (match_operand:TF 1 "gpc_reg_operand" "")))]
|
||||
"(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_DARWIN)
|
||||
&& TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128"
|
||||
"")
|
||||
|
||||
(define_insn_and_split "trunctfdf2_internal1"
|
||||
[(set (match_operand:DF 0 "gpc_reg_operand" "=f,?f")
|
||||
(float_truncate:DF (match_operand:TF 1 "gpc_reg_operand" "0,f")))]
|
||||
"(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_DARWIN) && !TARGET_XL_COMPAT
|
||||
&& TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128"
|
||||
"@
|
||||
#
|
||||
fmr %0,%1"
|
||||
"&& reload_completed && REGNO (operands[0]) == REGNO (operands[1])"
|
||||
[(const_int 0)]
|
||||
{
|
||||
emit_note (NOTE_INSN_DELETED);
|
||||
DONE;
|
||||
}
|
||||
[(set_attr "type" "fp")])
|
||||
|
||||
(define_insn "trunctfdf2_internal2"
|
||||
[(set (match_operand:DF 0 "gpc_reg_operand" "=f")
|
||||
(float_truncate:DF (match_operand:TF 1 "gpc_reg_operand" "f")))]
|
||||
"(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_DARWIN) && TARGET_XL_COMPAT
|
||||
&& TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128"
|
||||
"fadd %0,%1,%L1"
|
||||
[(set_attr "type" "fp")
|
||||
(set_attr "length" "4")])
|
||||
[(set_attr "type" "fp")])
|
||||
|
||||
(define_insn_and_split "trunctfsf2"
|
||||
[(set (match_operand:SF 0 "gpc_reg_operand" "=f")
|
||||
@ -10081,11 +10051,10 @@
|
||||
|
||||
(define_insn "load_toc_v4_PIC_1b"
|
||||
[(set (match_operand:SI 0 "register_operand" "=l")
|
||||
(match_operand:SI 1 "immediate_operand" "s"))
|
||||
(use (unspec [(match_dup 1) (match_operand 2 "immediate_operand" "s")]
|
||||
(unspec:SI [(match_operand:SI 1 "immediate_operand" "s")]
|
||||
UNSPEC_TOCPTR))]
|
||||
"TARGET_ELF && DEFAULT_ABI != ABI_AIX && flag_pic == 2"
|
||||
"bcl 20,31,%1+4\\n%1:\\n\\t.long %2-%1"
|
||||
"bcl 20,31,$+8\\n\\t.long %1-$"
|
||||
[(set_attr "type" "branch")
|
||||
(set_attr "length" "8")])
|
||||
|
||||
@ -11349,11 +11318,72 @@
|
||||
[(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
|
||||
(compare:CCFP (match_operand:TF 1 "gpc_reg_operand" "f")
|
||||
(match_operand:TF 2 "gpc_reg_operand" "f")))]
|
||||
"(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_DARWIN)
|
||||
"(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_DARWIN) && !TARGET_XL_COMPAT
|
||||
&& TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128"
|
||||
"fcmpu %0,%1,%2\;bne %0,$+8\;fcmpu %0,%L1,%L2"
|
||||
[(set_attr "type" "fpcompare")
|
||||
(set_attr "length" "12")])
|
||||
|
||||
(define_insn_and_split "*cmptf_internal2"
|
||||
[(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
|
||||
(compare:CCFP (match_operand:TF 1 "gpc_reg_operand" "f")
|
||||
(match_operand:TF 2 "gpc_reg_operand" "f")))
|
||||
(clobber (match_scratch:DF 3 "=f"))
|
||||
(clobber (match_scratch:DF 4 "=f"))
|
||||
(clobber (match_scratch:DF 5 "=f"))
|
||||
(clobber (match_scratch:DF 6 "=f"))
|
||||
(clobber (match_scratch:DF 7 "=f"))
|
||||
(clobber (match_scratch:DF 8 "=f"))
|
||||
(clobber (match_scratch:DF 9 "=f"))
|
||||
(clobber (match_scratch:DF 10 "=f"))]
|
||||
"(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_DARWIN) && TARGET_XL_COMPAT
|
||||
&& TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128"
|
||||
"#"
|
||||
"&& reload_completed"
|
||||
[(set (match_dup 3) (match_dup 13))
|
||||
(set (match_dup 4) (match_dup 14))
|
||||
(set (match_dup 9) (abs:DF (match_dup 5)))
|
||||
(set (match_dup 0) (compare:CCFP (match_dup 9) (match_dup 3)))
|
||||
(set (pc) (if_then_else (ne (match_dup 0) (const_int 0))
|
||||
(label_ref (match_dup 11))
|
||||
(pc)))
|
||||
(set (match_dup 0) (compare:CCFP (match_dup 5) (match_dup 7)))
|
||||
(set (pc) (label_ref (match_dup 12)))
|
||||
(match_dup 11)
|
||||
(set (match_dup 10) (minus:DF (match_dup 5) (match_dup 7)))
|
||||
(set (match_dup 9) (minus:DF (match_dup 6) (match_dup 8)))
|
||||
(set (match_dup 9) (plus:DF (match_dup 10) (match_dup 9)))
|
||||
(set (match_dup 0) (compare:CCFP (match_dup 7) (match_dup 4)))
|
||||
(match_dup 12)]
|
||||
{
|
||||
REAL_VALUE_TYPE rv;
|
||||
const int lo_word = FLOAT_WORDS_BIG_ENDIAN ? GET_MODE_SIZE (DFmode) : 0;
|
||||
const int hi_word = FLOAT_WORDS_BIG_ENDIAN ? 0 : GET_MODE_SIZE (DFmode);
|
||||
|
||||
operands[5] = simplify_gen_subreg (DFmode, operands[1], TFmode, hi_word);
|
||||
operands[6] = simplify_gen_subreg (DFmode, operands[1], TFmode, lo_word);
|
||||
operands[7] = simplify_gen_subreg (DFmode, operands[2], TFmode, hi_word);
|
||||
operands[8] = simplify_gen_subreg (DFmode, operands[2], TFmode, lo_word);
|
||||
operands[11] = gen_label_rtx ();
|
||||
operands[12] = gen_label_rtx ();
|
||||
real_inf (&rv);
|
||||
operands[13] = force_const_mem (DFmode,
|
||||
CONST_DOUBLE_FROM_REAL_VALUE (rv, DFmode));
|
||||
operands[14] = force_const_mem (DFmode,
|
||||
CONST_DOUBLE_FROM_REAL_VALUE (dconst0,
|
||||
DFmode));
|
||||
if (TARGET_TOC)
|
||||
{
|
||||
operands[13] = gen_rtx_MEM (DFmode,
|
||||
create_TOC_reference (XEXP (operands[13], 0)));
|
||||
operands[14] = gen_rtx_MEM (DFmode,
|
||||
create_TOC_reference (XEXP (operands[14], 0)));
|
||||
set_mem_alias_set (operands[13], get_TOC_alias_set ());
|
||||
set_mem_alias_set (operands[14], get_TOC_alias_set ());
|
||||
RTX_UNCHANGING_P (operands[13]) = 1;
|
||||
RTX_UNCHANGING_P (operands[14]) = 1;
|
||||
}
|
||||
})
|
||||
|
||||
;; Now we have the scc insns. We can do some combinations because of the
|
||||
;; way the machine works.
|
||||
@ -11376,10 +11406,10 @@
|
||||
(const_string "mfcr")))
|
||||
(set_attr "length" "12")])
|
||||
|
||||
;; Same as above, but get the GT bit.
|
||||
(define_insn "move_from_CR_gt_bit"
|
||||
;; Same as above, but get the EQ bit.
|
||||
(define_insn "move_from_CR_eq_bit"
|
||||
[(set (match_operand:SI 0 "gpc_reg_operand" "=r")
|
||||
(unspec:SI [(match_operand 1 "cc_reg_operand" "y")] UNSPEC_MV_CR_GT))]
|
||||
(unspec:SI [(match_operand 1 "cc_reg_operand" "y")] UNSPEC_MV_CR_EQ))]
|
||||
"TARGET_E500"
|
||||
"mfcr %0\;{rlinm|rlwinm} %0,%0,%D1,1"
|
||||
[(set_attr "type" "mfcr")
|
||||
|
@ -1,5 +1,6 @@
|
||||
/* Definitions for rtems targeting a PowerPC using elf.
|
||||
Copyright (C) 1996, 1997, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
|
||||
Copyright (C) 1996, 1997, 2000, 2001, 2002, 2003, 2005
|
||||
Free Software Foundation, Inc.
|
||||
Contributed by Joel Sherrill (joel@OARcorp.com).
|
||||
|
||||
This file is part of GCC.
|
||||
@ -27,6 +28,7 @@
|
||||
{ \
|
||||
builtin_define_std ("PPC"); \
|
||||
builtin_define ("__rtems__"); \
|
||||
builtin_define ("__USE_INIT_FINI__"); \
|
||||
builtin_assert ("system=rtems"); \
|
||||
builtin_assert ("cpu=powerpc"); \
|
||||
builtin_assert ("machine=powerpc"); \
|
||||
@ -36,3 +38,20 @@
|
||||
|
||||
#undef CPP_OS_DEFAULT_SPEC
|
||||
#define CPP_OS_DEFAULT_SPEC "%(cpp_os_rtems)"
|
||||
|
||||
#define CPP_OS_RTEMS_SPEC "\
|
||||
%{!mcpu*: %{!Dppc*: %{!Dmpc*: -Dmpc750} } }\
|
||||
%{mcpu=403: %{!Dppc*: %{!Dmpc*: -Dppc403} } } \
|
||||
%{mcpu=505: %{!Dppc*: %{!Dmpc*: -Dmpc505} } } \
|
||||
%{mcpu=601: %{!Dppc*: %{!Dmpc*: -Dppc601} } } \
|
||||
%{mcpu=602: %{!Dppc*: %{!Dmpc*: -Dppc602} } } \
|
||||
%{mcpu=603: %{!Dppc*: %{!Dmpc*: -Dppc603} } } \
|
||||
%{mcpu=603e: %{!Dppc*: %{!Dmpc*: -Dppc603e} } } \
|
||||
%{mcpu=604: %{!Dppc*: %{!Dmpc*: -Dmpc604} } } \
|
||||
%{mcpu=750: %{!Dppc*: %{!Dmpc*: -Dmpc750} } } \
|
||||
%{mcpu=821: %{!Dppc*: %{!Dmpc*: -Dmpc821} } } \
|
||||
%{mcpu=860: %{!Dppc*: %{!Dmpc*: -Dmpc860} } }"
|
||||
|
||||
#undef SUBSUBTARGET_EXTRA_SPECS
|
||||
#define SUBSUBTARGET_EXTRA_SPECS \
|
||||
{ "cpp_os_rtems", CPP_OS_RTEMS_SPEC }
|
||||
|
@ -1088,4 +1088,23 @@ __ev_set_spefscr_frmc (int rnd)
|
||||
__builtin_spe_mtspefscr (i);
|
||||
}
|
||||
|
||||
/* The SPE PIM says these are declared in <spe.h>, although they are
|
||||
not provided by GCC: they must be taken from a separate
|
||||
library. */
|
||||
extern short int atosfix16 (const char *);
|
||||
extern int atosfix32 (const char *);
|
||||
extern long long atosfix64 (const char *);
|
||||
|
||||
extern unsigned short atoufix16 (const char *);
|
||||
extern unsigned int atoufix32 (const char *);
|
||||
extern unsigned long long atoufix64 (const char *);
|
||||
|
||||
extern short int strtosfix16 (const char *, char **);
|
||||
extern int strtosfix32 (const char *, char **);
|
||||
extern long long strtosfix64 (const char *, char **);
|
||||
|
||||
extern unsigned short int strtoufix16 (const char *, char **);
|
||||
extern unsigned int strtoufix32 (const char *, char **);
|
||||
extern unsigned long long strtoufix64 (const char *, char **);
|
||||
|
||||
#endif /* _SPE_H */
|
||||
|
@ -2458,14 +2458,14 @@
|
||||
;; FP comparison stuff.
|
||||
|
||||
;; Flip the GT bit.
|
||||
(define_insn "e500_flip_gt_bit"
|
||||
(define_insn "e500_flip_eq_bit"
|
||||
[(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
|
||||
(unspec:CCFP
|
||||
[(match_operand:CCFP 1 "cc_reg_operand" "y")] 999))]
|
||||
"!TARGET_FPRS && TARGET_HARD_FLOAT"
|
||||
"*
|
||||
{
|
||||
return output_e500_flip_gt_bit (operands[0], operands[1]);
|
||||
return output_e500_flip_eq_bit (operands[0], operands[1]);
|
||||
}"
|
||||
[(set_attr "type" "cr_logical")])
|
||||
|
||||
|
@ -1086,7 +1086,7 @@ extern int fixuplabelno;
|
||||
#define LINK_START_FREEBSD_SPEC ""
|
||||
|
||||
#define LINK_OS_FREEBSD_SPEC "\
|
||||
%{p:%e`-p' not supported; use `-pg' and gprof(1)} \
|
||||
%{p:%nconsider using `-pg' instead of `-p' with gprof(1)} \
|
||||
%{Wl,*:%*} \
|
||||
%{v:-V} \
|
||||
%{assert*} %{R*} %{rpath*} %{defsym*} \
|
||||
@ -1115,8 +1115,9 @@ extern int fixuplabelno;
|
||||
%{static:crtbeginT.o%s;shared|pie:crtbeginS.o%s;:crtbegin.o%s}"
|
||||
#endif
|
||||
|
||||
#define ENDFILE_LINUX_SPEC "%{!shared:crtend.o%s} %{shared:crtendS.o%s} \
|
||||
%{mnewlib: ecrtn.o%s} %{!mnewlib: crtn.o%s}"
|
||||
#define ENDFILE_LINUX_SPEC "\
|
||||
%{shared|pie:crtendS.o%s;:crtend.o%s} \
|
||||
%{mnewlib:ecrtn.o%s;:crtn.o%s}"
|
||||
|
||||
#define LINK_START_LINUX_SPEC ""
|
||||
|
||||
@ -1358,4 +1359,4 @@ ncrtn.o%s"
|
||||
#define DOUBLE_INT_ASM_OP "\t.quad\t"
|
||||
|
||||
/* Generate entries in .fixup for relocatable addresses. */
|
||||
#define RELOCATABLE_NEEDS_FIXUP
|
||||
#define RELOCATABLE_NEEDS_FIXUP 1
|
||||
|
@ -58,9 +58,12 @@ SHLIB_LINK = $(GCC_FOR_TARGET) $(LIBGCC2_CFLAGS) -shared -nodefaultlibs \
|
||||
SHLIB_INSTALL = $(INSTALL_DATA) @shlib_base_name@.a $$(DESTDIR)$$(slibdir)/
|
||||
SHLIB_LIBS = -lc `case @shlib_base_name@ in *pthread*) echo -lpthread ;; esac`
|
||||
SHLIB_MKMAP = $(srcdir)/mkmap-flat.awk
|
||||
SHLIB_MAPFILES = $(srcdir)/libgcc-std.ver
|
||||
SHLIB_MAPFILES = $(srcdir)/libgcc-std.ver $(srcdir)/config/rs6000/libgcc-ppc64.ver
|
||||
SHLIB_NM_FLAGS = -Bpg -X32_64
|
||||
|
||||
# GCC 128-bit long double support routines.
|
||||
LIB2FUNCS_EXTRA = $(srcdir)/config/rs6000/darwin-ldouble.c
|
||||
|
||||
# Either 32-bit and 64-bit objects in archives.
|
||||
AR_FLAGS_FOR_TARGET = -X32_64
|
||||
|
||||
|
@ -39,9 +39,12 @@ SHLIB_LINK = $(GCC_FOR_TARGET) $(LIBGCC2_CFLAGS) -shared -nodefaultlibs \
|
||||
SHLIB_INSTALL = $(INSTALL_DATA) @shlib_base_name@.a $$(DESTDIR)$$(slibdir)/
|
||||
SHLIB_LIBS = -lc `case @shlib_base_name@ in *pthread*) echo -lpthread ;; esac`
|
||||
SHLIB_MKMAP = $(srcdir)/mkmap-flat.awk
|
||||
SHLIB_MAPFILES = $(srcdir)/libgcc-std.ver
|
||||
SHLIB_MAPFILES = $(srcdir)/libgcc-std.ver $(srcdir)/config/rs6000/libgcc-ppc64.ver
|
||||
SHLIB_NM_FLAGS = -Bpg -X32_64
|
||||
|
||||
# GCC 128-bit long double support routines.
|
||||
LIB2FUNCS_EXTRA = $(srcdir)/config/rs6000/darwin-ldouble.c
|
||||
|
||||
# Either 32-bit and 64-bit objects in archives.
|
||||
AR_FLAGS_FOR_TARGET = -X32_64
|
||||
|
||||
|
@ -1,8 +1,9 @@
|
||||
|
||||
#rs6000/t-linux64
|
||||
|
||||
LIB2FUNCS_EXTRA = tramp.S $(srcdir)/config/rs6000/ppc64-fp.c \
|
||||
$(srcdir)/config/rs6000/darwin-ldouble.c
|
||||
LIB2FUNCS_EXTRA = tramp.S $(srcdir)/config/rs6000/ppc64-fp.c
|
||||
LIB2FUNCS_STATIC_EXTRA = eabi.S $(srcdir)/config/rs6000/darwin-ldouble.c
|
||||
LIB2FUNCS_SHARED_EXTRA = $(srcdir)/config/rs6000/darwin-ldouble-shared.c
|
||||
|
||||
TARGET_LIBGCC2_CFLAGS = -mno-minimal-toc -fPIC -specs=bispecs
|
||||
|
||||
|
@ -27,6 +27,9 @@ MULTILIB_MATCHES = $(MULTILIB_MATCHES_FLOAT) \
|
||||
mcpu?powerpc=mpowerpc-gpopt \
|
||||
mcpu?powerpc=mpowerpc-gfxopt
|
||||
|
||||
# GCC 128-bit long double support routines.
|
||||
LIB2FUNCS_EXTRA = $(srcdir)/config/rs6000/darwin-ldouble.c
|
||||
|
||||
# Aix 3.2.x needs milli.exp for -mcpu=common
|
||||
EXTRA_PARTS = milli.exp
|
||||
milli.exp: $(srcdir)/config/rs6000/milli.exp
|
||||
|
@ -33,6 +33,7 @@ MULTILIB_MATCHES = ${MULTILIB_MATCHES_ENDIAN} \
|
||||
|
||||
# Cpu-variants supporting new exception processing only
|
||||
MULTILIB_NEW_EXCEPTIONS_ONLY = \
|
||||
*mcpu=505*/*D_OLD_EXCEPTIONS* \
|
||||
*mcpu=604*/*D_OLD_EXCEPTIONS* \
|
||||
*mcpu=750*/*D_OLD_EXCEPTIONS* \
|
||||
*mcpu=821*/*D_OLD_EXCEPTIONS* \
|
||||
|
@ -1039,11 +1039,13 @@
|
||||
})
|
||||
|
||||
(define_expand "reload_outti"
|
||||
[(parallel [(match_operand:TI 0 "memory_operand" "")
|
||||
[(parallel [(match_operand:TI 0 "" "")
|
||||
(match_operand:TI 1 "register_operand" "d")
|
||||
(match_operand:DI 2 "register_operand" "=&a")])]
|
||||
"TARGET_64BIT"
|
||||
{
|
||||
if (GET_CODE (operands[0]) != MEM)
|
||||
abort ();
|
||||
s390_load_address (operands[2], XEXP (operands[0], 0));
|
||||
operands[0] = replace_equiv_address (operands[0], operands[2]);
|
||||
emit_move_insn (operands[0], operands[1]);
|
||||
@ -1167,11 +1169,13 @@
|
||||
})
|
||||
|
||||
(define_expand "reload_outdi"
|
||||
[(parallel [(match_operand:DI 0 "memory_operand" "")
|
||||
[(parallel [(match_operand:DI 0 "" "")
|
||||
(match_operand:DI 1 "register_operand" "d")
|
||||
(match_operand:SI 2 "register_operand" "=&a")])]
|
||||
"!TARGET_64BIT"
|
||||
{
|
||||
if (GET_CODE (operands[0]) != MEM)
|
||||
abort ();
|
||||
s390_load_address (operands[2], XEXP (operands[0], 0));
|
||||
operands[0] = replace_equiv_address (operands[0], operands[2]);
|
||||
emit_move_insn (operands[0], operands[1]);
|
||||
@ -1647,11 +1651,13 @@
|
||||
})
|
||||
|
||||
(define_expand "reload_outdf"
|
||||
[(parallel [(match_operand:DF 0 "memory_operand" "")
|
||||
[(parallel [(match_operand:DF 0 "" "")
|
||||
(match_operand:DF 1 "register_operand" "d")
|
||||
(match_operand:SI 2 "register_operand" "=&a")])]
|
||||
"!TARGET_64BIT"
|
||||
{
|
||||
if (GET_CODE (operands[0]) != MEM)
|
||||
abort ();
|
||||
s390_load_address (operands[2], XEXP (operands[0], 0));
|
||||
operands[0] = replace_equiv_address (operands[0], operands[2]);
|
||||
emit_move_insn (operands[0], operands[1]);
|
||||
@ -4117,7 +4123,7 @@
|
||||
(match_operand:DF 2 "general_operand" "f,R"))
|
||||
(match_operand:DF 3 "const0_operand" "")))
|
||||
(set (match_operand:DF 0 "register_operand" "=f,f")
|
||||
(plus:DF (match_dup 1) (match_dup 2)))]
|
||||
(minus:DF (match_dup 1) (match_dup 2)))]
|
||||
"s390_match_ccmode (insn, CCSmode) && TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
|
||||
"@
|
||||
sdbr\t%0,%2
|
||||
|
@ -92,6 +92,9 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
|
||||
#undef CPLUSPLUS_CPP_SPEC
|
||||
#define CPLUSPLUS_CPP_SPEC "-D_GNU_SOURCE %(cpp)"
|
||||
|
||||
#undef ASM_SPEC
|
||||
#define ASM_SPEC "%{m31&m64}%{mesa&mzarch}%{march=*}"
|
||||
|
||||
#undef LIB_SPEC
|
||||
#define LIB_SPEC "%{pthread:-lpthread} -lc"
|
||||
|
||||
|
@ -187,6 +187,8 @@ static bool sparc_function_ok_for_sibcall (tree, tree);
|
||||
static void sparc_init_libfuncs (void);
|
||||
static void sparc_output_mi_thunk (FILE *, tree, HOST_WIDE_INT,
|
||||
HOST_WIDE_INT, tree);
|
||||
static bool sparc_can_output_mi_thunk (tree, HOST_WIDE_INT,
|
||||
HOST_WIDE_INT, tree);
|
||||
static struct machine_function * sparc_init_machine_status (void);
|
||||
static bool sparc_cannot_force_const_mem (rtx);
|
||||
static rtx sparc_tls_get_addr (void);
|
||||
@ -270,7 +272,7 @@ enum processor_type sparc_cpu;
|
||||
#undef TARGET_ASM_OUTPUT_MI_THUNK
|
||||
#define TARGET_ASM_OUTPUT_MI_THUNK sparc_output_mi_thunk
|
||||
#undef TARGET_ASM_CAN_OUTPUT_MI_THUNK
|
||||
#define TARGET_ASM_CAN_OUTPUT_MI_THUNK default_can_output_mi_thunk_no_vcall
|
||||
#define TARGET_ASM_CAN_OUTPUT_MI_THUNK sparc_can_output_mi_thunk
|
||||
|
||||
#undef TARGET_RTX_COSTS
|
||||
#define TARGET_RTX_COSTS sparc_rtx_costs
|
||||
@ -1315,23 +1317,7 @@ input_operand (rtx op, enum machine_mode mode)
|
||||
|
||||
/* Check for valid MEM forms. */
|
||||
if (GET_CODE (op) == MEM)
|
||||
{
|
||||
rtx inside = XEXP (op, 0);
|
||||
|
||||
if (GET_CODE (inside) == LO_SUM)
|
||||
{
|
||||
/* We can't allow these because all of the splits
|
||||
(eventually as they trickle down into DFmode
|
||||
splits) require offsettable memory references. */
|
||||
if (! TARGET_V9
|
||||
&& GET_MODE (op) == TFmode)
|
||||
return 0;
|
||||
|
||||
return (register_operand (XEXP (inside, 0), Pmode)
|
||||
&& CONSTANT_P (XEXP (inside, 1)));
|
||||
}
|
||||
return memory_address_p (mode, inside);
|
||||
}
|
||||
return memory_address_p (mode, XEXP (op, 0));
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -3334,7 +3320,7 @@ legitimate_pic_operand_p (rtx x)
|
||||
int
|
||||
legitimate_address_p (enum machine_mode mode, rtx addr, int strict)
|
||||
{
|
||||
rtx rs1 = NULL, rs2 = NULL, imm1 = NULL, imm2;
|
||||
rtx rs1 = NULL, rs2 = NULL, imm1 = NULL;
|
||||
|
||||
if (REG_P (addr) || GET_CODE (addr) == SUBREG)
|
||||
rs1 = addr;
|
||||
@ -3374,15 +3360,14 @@ legitimate_address_p (enum machine_mode mode, rtx addr, int strict)
|
||||
else if ((REG_P (rs1) || GET_CODE (rs1) == SUBREG)
|
||||
&& (REG_P (rs2) || GET_CODE (rs2) == SUBREG))
|
||||
{
|
||||
/* We prohibit REG + REG for TFmode when there are no instructions
|
||||
which accept REG+REG instructions. We do this because REG+REG
|
||||
is not an offsetable address. If we get the situation in reload
|
||||
/* We prohibit REG + REG for TFmode when there are no quad move insns
|
||||
and we consequently need to split. We do this because REG+REG
|
||||
is not an offsettable address. If we get the situation in reload
|
||||
where source and destination of a movtf pattern are both MEMs with
|
||||
REG+REG address, then only one of them gets converted to an
|
||||
offsetable address. */
|
||||
offsettable address. */
|
||||
if (mode == TFmode
|
||||
&& !(TARGET_FPU && TARGET_ARCH64 && TARGET_V9
|
||||
&& TARGET_HARD_QUAD))
|
||||
&& ! (TARGET_FPU && TARGET_ARCH64 && TARGET_HARD_QUAD))
|
||||
return 0;
|
||||
|
||||
/* We prohibit REG + REG on ARCH32 if not optimizing for
|
||||
@ -3399,7 +3384,6 @@ legitimate_address_p (enum machine_mode mode, rtx addr, int strict)
|
||||
&& ! TARGET_CM_MEDMID
|
||||
&& RTX_OK_FOR_OLO10_P (rs2))
|
||||
{
|
||||
imm2 = rs2;
|
||||
rs2 = NULL;
|
||||
imm1 = XEXP (rs1, 1);
|
||||
rs1 = XEXP (rs1, 0);
|
||||
@ -3415,9 +3399,9 @@ legitimate_address_p (enum machine_mode mode, rtx addr, int strict)
|
||||
if (! CONSTANT_P (imm1) || tls_symbolic_operand (rs1))
|
||||
return 0;
|
||||
|
||||
/* We can't allow TFmode, because an offset greater than or equal to the
|
||||
alignment (8) may cause the LO_SUM to overflow if !v9. */
|
||||
if (mode == TFmode && !TARGET_V9)
|
||||
/* We can't allow TFmode in 32-bit mode, because an offset greater
|
||||
than the alignment (8) may cause the LO_SUM to overflow. */
|
||||
if (mode == TFmode && TARGET_ARCH32)
|
||||
return 0;
|
||||
}
|
||||
else if (GET_CODE (addr) == CONST_INT && SMALL_INT (addr))
|
||||
@ -5101,7 +5085,7 @@ static void function_arg_record_value_2
|
||||
static void function_arg_record_value_1
|
||||
(tree, HOST_WIDE_INT, struct function_arg_record_value_parms *, bool);
|
||||
static rtx function_arg_record_value (tree, enum machine_mode, int, int, int);
|
||||
static rtx function_arg_union_value (int, enum machine_mode, int);
|
||||
static rtx function_arg_union_value (int, enum machine_mode, int, int);
|
||||
|
||||
/* A subroutine of function_arg_record_value. Traverse the structure
|
||||
recursively and determine how many registers will be required. */
|
||||
@ -5445,11 +5429,19 @@ function_arg_record_value (tree type, enum machine_mode mode,
|
||||
REGNO is the hard register the union will be passed in. */
|
||||
|
||||
static rtx
|
||||
function_arg_union_value (int size, enum machine_mode mode, int regno)
|
||||
function_arg_union_value (int size, enum machine_mode mode, int slotno,
|
||||
int regno)
|
||||
{
|
||||
int nwords = ROUND_ADVANCE (size), i;
|
||||
rtx regs;
|
||||
|
||||
/* See comment in previous function for empty structures. */
|
||||
if (nwords == 0)
|
||||
return gen_rtx_REG (mode, regno);
|
||||
|
||||
if (slotno == SPARC_INT_ARG_MAX - 1)
|
||||
nwords = 1;
|
||||
|
||||
/* Unions are passed left-justified. */
|
||||
regs = gen_rtx_PARALLEL (mode, rtvec_alloc (nwords));
|
||||
|
||||
@ -5516,7 +5508,7 @@ function_arg (const struct sparc_args *cum, enum machine_mode mode,
|
||||
if (size > 16)
|
||||
abort (); /* shouldn't get here */
|
||||
|
||||
return function_arg_union_value (size, mode, regno);
|
||||
return function_arg_union_value (size, mode, slotno, regno);
|
||||
}
|
||||
/* v9 fp args in reg slots beyond the int reg slots get passed in regs
|
||||
but also have the slot allocated for them.
|
||||
@ -5796,7 +5788,7 @@ function_value (tree type, enum machine_mode mode, int incoming_p)
|
||||
if (size > 32)
|
||||
abort (); /* shouldn't get here */
|
||||
|
||||
return function_arg_union_value (size, mode, regbase);
|
||||
return function_arg_union_value (size, mode, 0, regbase);
|
||||
}
|
||||
else if (AGGREGATE_TYPE_P (type))
|
||||
{
|
||||
@ -5819,7 +5811,7 @@ function_value (tree type, enum machine_mode mode, int incoming_p)
|
||||
try to be unduly clever, and simply follow the ABI
|
||||
for unions in that case. */
|
||||
if (mode == BLKmode)
|
||||
return function_arg_union_value (bytes, mode, regbase);
|
||||
return function_arg_union_value (bytes, mode, 0, regbase);
|
||||
}
|
||||
else if (GET_MODE_CLASS (mode) == MODE_INT
|
||||
&& GET_MODE_SIZE (mode) < UNITS_PER_WORD)
|
||||
@ -9288,16 +9280,18 @@ sparc_rtx_costs (rtx x, int code, int outer_code, int *total)
|
||||
}
|
||||
}
|
||||
|
||||
/* Output code to add DELTA to the first argument, and then jump to FUNCTION.
|
||||
Used for C++ multiple inheritance. */
|
||||
/* Output the assembler code for a thunk function. THUNK_DECL is the
|
||||
declaration for the thunk function itself, FUNCTION is the decl for
|
||||
the target function. DELTA is an immediate constant offset to be
|
||||
added to THIS. If VCALL_OFFSET is nonzero, the word at address
|
||||
(*THIS + VCALL_OFFSET) should be additionally added to THIS. */
|
||||
|
||||
static void
|
||||
sparc_output_mi_thunk (FILE *file, tree thunk_fndecl ATTRIBUTE_UNUSED,
|
||||
HOST_WIDE_INT delta,
|
||||
HOST_WIDE_INT vcall_offset ATTRIBUTE_UNUSED,
|
||||
HOST_WIDE_INT delta, HOST_WIDE_INT vcall_offset,
|
||||
tree function)
|
||||
{
|
||||
rtx this, insn, funexp, delta_rtx, tmp;
|
||||
rtx this, insn, funexp;
|
||||
|
||||
reload_completed = 1;
|
||||
epilogue_completed = 1;
|
||||
@ -9315,26 +9309,73 @@ sparc_output_mi_thunk (FILE *file, tree thunk_fndecl ATTRIBUTE_UNUSED,
|
||||
|
||||
/* 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))
|
||||
if (delta)
|
||||
{
|
||||
rtx scratch = gen_rtx_REG (Pmode, 1);
|
||||
rtx delta_rtx = GEN_INT (delta);
|
||||
|
||||
if (input_operand (delta_rtx, GET_MODE (scratch)))
|
||||
emit_insn (gen_rtx_SET (VOIDmode, scratch, delta_rtx));
|
||||
else
|
||||
if (! SPARC_SIMM13_P (delta))
|
||||
{
|
||||
if (TARGET_ARCH64)
|
||||
sparc_emit_set_const64 (scratch, delta_rtx);
|
||||
else
|
||||
sparc_emit_set_const32 (scratch, delta_rtx);
|
||||
rtx scratch = gen_rtx_REG (Pmode, 1);
|
||||
emit_move_insn (scratch, delta_rtx);
|
||||
delta_rtx = scratch;
|
||||
}
|
||||
|
||||
delta_rtx = scratch;
|
||||
/* THIS += DELTA. */
|
||||
emit_insn (gen_add2_insn (this, delta_rtx));
|
||||
}
|
||||
|
||||
tmp = gen_rtx_PLUS (Pmode, this, delta_rtx);
|
||||
emit_insn (gen_rtx_SET (VOIDmode, this, tmp));
|
||||
/* Add the word at address (*THIS + VCALL_OFFSET). */
|
||||
if (vcall_offset)
|
||||
{
|
||||
rtx vcall_offset_rtx = GEN_INT (vcall_offset);
|
||||
rtx scratch = gen_rtx_REG (Pmode, 1);
|
||||
|
||||
if (vcall_offset >= 0)
|
||||
abort ();
|
||||
|
||||
/* SCRATCH = *THIS. */
|
||||
emit_move_insn (scratch, gen_rtx_MEM (Pmode, this));
|
||||
|
||||
/* Prepare for adding VCALL_OFFSET. The difficulty is that we
|
||||
may not have any available scratch register at this point. */
|
||||
if (SPARC_SIMM13_P (vcall_offset))
|
||||
;
|
||||
/* This is the case if ARCH64 (unless -ffixed-g5 is passed). */
|
||||
else if (! fixed_regs[5]
|
||||
/* The below sequence is made up of at least 2 insns,
|
||||
while the default method may need only one. */
|
||||
&& vcall_offset < -8192)
|
||||
{
|
||||
rtx scratch2 = gen_rtx_REG (Pmode, 5);
|
||||
emit_move_insn (scratch2, vcall_offset_rtx);
|
||||
vcall_offset_rtx = scratch2;
|
||||
}
|
||||
else
|
||||
{
|
||||
rtx increment = GEN_INT (-4096);
|
||||
|
||||
/* VCALL_OFFSET is a negative number whose typical range can be
|
||||
estimated as -32768..0 in 32-bit mode. In almost all cases
|
||||
it is therefore cheaper to emit multiple add insns than
|
||||
spilling and loading the constant into a register (at least
|
||||
6 insns). */
|
||||
while (! SPARC_SIMM13_P (vcall_offset))
|
||||
{
|
||||
emit_insn (gen_add2_insn (scratch, increment));
|
||||
vcall_offset += 4096;
|
||||
}
|
||||
vcall_offset_rtx = GEN_INT (vcall_offset); /* cannot be 0 */
|
||||
}
|
||||
|
||||
/* SCRATCH = *(*THIS + VCALL_OFFSET). */
|
||||
emit_move_insn (scratch, gen_rtx_MEM (Pmode,
|
||||
gen_rtx_PLUS (Pmode,
|
||||
scratch,
|
||||
vcall_offset_rtx)));
|
||||
|
||||
/* THIS += *(*THIS + VCALL_OFFSET). */
|
||||
emit_insn (gen_add2_insn (this, scratch));
|
||||
}
|
||||
|
||||
/* Generate a tail call to the target function. */
|
||||
if (! TREE_USED (function))
|
||||
@ -9364,6 +9405,19 @@ sparc_output_mi_thunk (FILE *file, tree thunk_fndecl ATTRIBUTE_UNUSED,
|
||||
no_new_pseudos = 0;
|
||||
}
|
||||
|
||||
/* Return true if sparc_output_mi_thunk would be able to output the
|
||||
assembler code for the thunk function specified by the arguments
|
||||
it is passed, and false otherwise. */
|
||||
static bool
|
||||
sparc_can_output_mi_thunk (tree thunk_fndecl ATTRIBUTE_UNUSED,
|
||||
HOST_WIDE_INT delta ATTRIBUTE_UNUSED,
|
||||
HOST_WIDE_INT vcall_offset,
|
||||
tree function ATTRIBUTE_UNUSED)
|
||||
{
|
||||
/* Bound the loop used in the default method above. */
|
||||
return (vcall_offset >= -32768 || ! fixed_regs[5]);
|
||||
}
|
||||
|
||||
/* How to allocate a 'struct machine_function'. */
|
||||
|
||||
static struct machine_function *
|
||||
|
@ -2076,7 +2076,6 @@
|
||||
if (! CONSTANT_P (operands[1]) || input_operand (operands[1], DImode))
|
||||
;
|
||||
else if (TARGET_ARCH64
|
||||
&& CONSTANT_P (operands[1])
|
||||
&& GET_CODE (operands[1]) != HIGH
|
||||
&& GET_CODE (operands[1]) != LO_SUM)
|
||||
{
|
||||
|
@ -24,6 +24,6 @@ INSTALL_LIBGCC = install-multilib
|
||||
|
||||
# Assemble startup files.
|
||||
crti.o: $(srcdir)/config/sparc/sol2-ci.asm $(GCC_PASSES)
|
||||
$(GCC_FOR_TARGET) -c -o crti.o -x assembler $(srcdir)/config/sparc/sol2-ci.asm
|
||||
$(GCC_FOR_TARGET) -c -o crti.o -x assembler-with-cpp $(srcdir)/config/sparc/sol2-ci.asm
|
||||
crtn.o: $(srcdir)/config/sparc/sol2-cn.asm $(GCC_PASSES)
|
||||
$(GCC_FOR_TARGET) -c -o crtn.o -x assembler $(srcdir)/config/sparc/sol2-cn.asm
|
||||
$(GCC_FOR_TARGET) -c -o crtn.o -x assembler-with-cpp $(srcdir)/config/sparc/sol2-cn.asm
|
||||
|
@ -1,5 +1,12 @@
|
||||
# Use the system libunwind library.
|
||||
#
|
||||
# Override the default value from t-slibgcc-elf-ver and mention -lunwind
|
||||
# so that the resulting libgcc_s.so has the necessary DT_NEEDED entry for
|
||||
# libunwind.
|
||||
SHLIB_LC = -lunwind -lc
|
||||
LIB2ADDEH = $(srcdir)/unwind-sjlj.c $(srcdir)/unwind-c.c
|
||||
LIB2ADDEH = $(srcdir)/unwind-sjlj.c $(srcdir)/unwind-c.c \
|
||||
$(srcdir)/unwind-compat.c $(srcdir)/unwind-dw2-fde-compat.c
|
||||
LIB2ADDEHSTATIC = $(srcdir)/unwind-sjlj.c $(srcdir)/unwind-c.c
|
||||
|
||||
T_CFLAGS += -DUSE_LIBUNWIND_EXCEPTIONS
|
||||
TARGET_LIBGCC2_CFLAGS += -DUSE_GAS_SYMVER
|
||||
|
30
contrib/gcc/config/t-libunwind-elf
Normal file
30
contrib/gcc/config/t-libunwind-elf
Normal file
@ -0,0 +1,30 @@
|
||||
# Build libunwind for ELF with the GNU linker.
|
||||
|
||||
# Use unwind-dw2-fde-glibc
|
||||
LIBUNWIND = $(srcdir)/unwind-dw2.c $(srcdir)/unwind-dw2-fde-glibc.c
|
||||
LIBUNWINDDEP = unwind.inc unwind-dw2-fde.h unwind-dw2-fde.c
|
||||
|
||||
SHLIBUNWIND_SOVERSION = 7
|
||||
SHLIBUNWIND_SONAME = @shlib_so_name@.so.$(SHLIBUNWIND_SOVERSION)
|
||||
SHLIBUNWIND_NAME = @shlib_dir@@shlib_so_name@.so.$(SHLIBUNWIND_SOVERSION)
|
||||
|
||||
SHLIBUNWIND_LINK = $(GCC_FOR_TARGET) $(LIBGCC2_CFLAGS) -shared \
|
||||
-nodefaultlibs -Wl,-h,$(SHLIBUNWIND_SONAME) \
|
||||
-Wl,-z,text -Wl,-z,defs -o $(SHLIBUNWIND_NAME).tmp \
|
||||
@multilib_flags@ $(SHLIB_OBJS) -lc && \
|
||||
rm -f $(SHLIB_SOLINK) && \
|
||||
if [ -f $(SHLIBUNWIND_NAME) ]; then \
|
||||
mv -f $(SHLIBUNWIND_NAME) $(SHLIBUNWIND_NAME).backup; \
|
||||
else true; fi && \
|
||||
mv $(SHLIBUNWIND_NAME).tmp $(SHLIBUNWIND_NAME) && \
|
||||
$(LN_S) $(SHLIBUNWIND_NAME) $(SHLIB_SOLINK)
|
||||
|
||||
# $(slibdir) double quoted to protect it from expansion while building
|
||||
# libgcc.mk. We want this delayed until actual install time.
|
||||
SHLIBUNWIND_INSTALL = \
|
||||
$$(SHELL) $$(srcdir)/mkinstalldirs $$(DESTDIR)$$(slibdir)$(SHLIB_SLIBDIR_QUAL); \
|
||||
$(INSTALL_DATA) $(SHLIBUNWIND_NAME) \
|
||||
$$(DESTDIR)$$(slibdir)$(SHLIB_SLIBDIR_QUAL)/$(SHLIBUNWIND_SONAME); \
|
||||
rm -f $$(DESTDIR)$$(slibdir)$(SHLIB_SLIBDIR_QUAL)/$(SHLIB_SOLINK); \
|
||||
$(LN_S) $(SHLIBUNWIND_SONAME) \
|
||||
$$(DESTDIR)$$(slibdir)$(SHLIB_SLIBDIR_QUAL)/$(SHLIB_SOLINK)
|
@ -12,10 +12,14 @@ SHLIB_SLIBDIR_QUAL = @shlib_slibdir_qual@
|
||||
|
||||
SHLIB_LINK = $(GCC_FOR_TARGET) $(LIBGCC2_CFLAGS) -dynamiclib -nodefaultlibs \
|
||||
-Wl,-install_name,$(slibdir)$(SHLIB_SLIBDIR_QUAL)/$(SHLIB_SONAME) \
|
||||
-Wl,-flat_namespace -o $(SHLIB_NAME) \
|
||||
-Wl,-flat_namespace -o $(SHLIB_NAME).tmp \
|
||||
$(SHLIB_VERSTRING) \
|
||||
@multilib_flags@ $(SHLIB_OBJS) -lc && \
|
||||
rm -f $(SHLIB_SOLINK) && \
|
||||
if [ -f $(SHLIB_NAME) ]; then \
|
||||
mv -f $(SHLIB_NAME) $(SHLIB_NAME).backup; \
|
||||
else true; fi && \
|
||||
mv $(SHLIB_NAME).tmp $(SHLIB_NAME) && \
|
||||
$(LN_S) $(SHLIB_NAME) $(SHLIB_SOLINK)
|
||||
# $(slibdir) double quoted to protect it from expansion while building
|
||||
# libgcc.mk. We want this delayed until actual install time.
|
||||
|
@ -14,8 +14,12 @@ SHLIB_LC = -lc
|
||||
SHLIB_LINK = $(GCC_FOR_TARGET) $(LIBGCC2_CFLAGS) -shared -nodefaultlibs \
|
||||
-Wl,--soname=$(SHLIB_SONAME) \
|
||||
-Wl,--version-script=$(SHLIB_MAP) \
|
||||
-o $(SHLIB_NAME) @multilib_flags@ $(SHLIB_OBJS) $(SHLIB_LC) && \
|
||||
-o $(SHLIB_NAME).tmp @multilib_flags@ $(SHLIB_OBJS) $(SHLIB_LC) && \
|
||||
rm -f $(SHLIB_SOLINK) && \
|
||||
if [ -f $(SHLIB_NAME) ]; then \
|
||||
mv -f $(SHLIB_NAME) $(SHLIB_NAME).backup; \
|
||||
else true; fi && \
|
||||
mv $(SHLIB_NAME).tmp $(SHLIB_NAME) && \
|
||||
$(LN_S) $(SHLIB_NAME) $(SHLIB_SOLINK)
|
||||
# $(slibdir) double quoted to protect it from expansion while building
|
||||
# libgcc.mk. We want this delayed until actual install time.
|
||||
|
@ -10,9 +10,13 @@ SHLIB_SLIBDIR_QUAL = @shlib_slibdir_qual@
|
||||
|
||||
SHLIB_LINK = $(GCC_FOR_TARGET) $(LIBGCC2_CFLAGS) -shared -nodefaultlibs \
|
||||
-Wl,-h,$(SHLIB_SONAME) -Wl,-z,text -Wl,-z,defs \
|
||||
-Wl,-M,$(SHLIB_MAP) -o $(SHLIB_NAME) \
|
||||
-Wl,-M,$(SHLIB_MAP) -o $(SHLIB_NAME).tmp \
|
||||
@multilib_flags@ $(SHLIB_OBJS) -lc && \
|
||||
rm -f $(SHLIB_SOLINK) && \
|
||||
if [ -f $(SHLIB_NAME) ]; then \
|
||||
mv -f $(SHLIB_NAME) $(SHLIB_NAME).backup; \
|
||||
else true; fi && \
|
||||
mv $(SHLIB_NAME).tmp $(SHLIB_NAME) && \
|
||||
$(LN_S) $(SHLIB_NAME) $(SHLIB_SOLINK)
|
||||
# $(slibdir) double quoted to protect it from expansion while building
|
||||
# libgcc.mk. We want this delayed until actual install time.
|
||||
|
@ -979,20 +979,10 @@ AC_ARG_ENABLE(sjlj-exceptions,
|
||||
AC_DEFINE_UNQUOTED(CONFIG_SJLJ_EXCEPTIONS, $sjlj,
|
||||
[Define 0/1 to force the choice for exception handling model.])])
|
||||
|
||||
if test x$host = x$target; then
|
||||
AC_CHECK_LIB(unwind, main, use_libunwind_default=yes, use_libunwind_default=no)
|
||||
else
|
||||
use_libunwind_default=no
|
||||
fi
|
||||
# Use libunwind based exception handling.
|
||||
AC_ARG_ENABLE(libunwind-exceptions,
|
||||
[ --enable-libunwind-exceptions force use libunwind for exceptions],
|
||||
use_libunwind_exceptions=$enableval,
|
||||
use_libunwind_exceptions=$use_libunwind_default)
|
||||
if test x"$use_libunwind_exceptions" = xyes; then
|
||||
AC_DEFINE(USE_LIBUNWIND_EXCEPTIONS, 1,
|
||||
[Define if gcc should use -lunwind.])
|
||||
fi
|
||||
# For platforms with the unwind ABI which includes an unwind library,
|
||||
# libunwind, we can choose to use the system libunwind.
|
||||
AC_ARG_WITH(system-libunwind,
|
||||
[ --with-system-libunwind use installed libunwind])
|
||||
|
||||
# --------------------------------------------------------
|
||||
# Build, host, and target specific configuration fragments
|
||||
@ -1865,6 +1855,12 @@ gcc_GAS_CHECK_FEATURE([.weak], gcc_cv_as_weak,
|
||||
[ .weak foobar],,
|
||||
[AC_DEFINE(HAVE_GAS_WEAK, 1, [Define if your assembler supports .weak.])])
|
||||
|
||||
gcc_GAS_CHECK_FEATURE([.nsubspa comdat], gcc_cv_as_nsubspa_comdat,
|
||||
[2,15,91],,
|
||||
[ .SPACE $TEXT$
|
||||
.NSUBSPA $CODE$,COMDAT],,
|
||||
[AC_DEFINE(HAVE_GAS_NSUBSPA_COMDAT, 1, [Define if your assembler supports .nsubspa comdat option.])])
|
||||
|
||||
# .hidden needs to be supported in both the assembler and the linker,
|
||||
# because GNU LD versions before 2.12.1 have buggy support for STV_HIDDEN.
|
||||
# This is irritatingly difficult to feature test for; we have to check the
|
||||
@ -2407,7 +2403,7 @@ foo:
|
||||
[if test x$gcc_cv_objdump != x \
|
||||
&& $gcc_cv_objdump -s -j .text conftest.o 2> /dev/null \
|
||||
| grep ' 82106000 82106000' > /dev/null 2>&1; then
|
||||
gcc_cv_as_offsetable_lo10=yes
|
||||
gcc_cv_as_sparc_offsetable_lo10=yes
|
||||
fi],
|
||||
[AC_DEFINE(HAVE_AS_OFFSETABLE_LO10, 1,
|
||||
[Define if your assembler supports offsetable %lo().])])
|
||||
@ -2627,6 +2623,25 @@ if test x"$gcc_cv_ld_pie" = xyes; then
|
||||
fi
|
||||
AC_MSG_RESULT($gcc_cv_ld_pie)
|
||||
|
||||
AC_MSG_CHECKING(linker -Bstatic/-Bdynamic option)
|
||||
gcc_cv_ld_static_dynamic=no
|
||||
if test $in_tree_ld = yes ; then
|
||||
if test "$gcc_cv_gld_major_version" -eq 2 -a "$gcc_cv_gld_minor_version" -ge 10; then
|
||||
gcc_cv_ld_static_dynamic=yes
|
||||
fi
|
||||
elif test x$gcc_cv_ld != x; then
|
||||
# Check if linker supports -Bstatic/-Bdynamic option
|
||||
if $gcc_cv_ld --help 2>/dev/null | grep -- -Bstatic > /dev/null \
|
||||
&& $gcc_cv_ld --help 2>/dev/null | grep -- -Bdynamic > /dev/null; then
|
||||
gcc_cv_ld_static_dynamic=yes
|
||||
fi
|
||||
fi
|
||||
if test x"$gcc_cv_ld_static_dynamic" = xyes; then
|
||||
AC_DEFINE(HAVE_LD_STATIC_DYNAMIC, 1,
|
||||
[Define if your linker supports -Bstatic/-Bdynamic option.])
|
||||
fi
|
||||
AC_MSG_RESULT($gcc_cv_ld_static_dynamic)
|
||||
|
||||
case "$target" in
|
||||
*-*-linux*)
|
||||
AC_CACHE_CHECK(linker --as-needed support,
|
||||
@ -3100,6 +3115,9 @@ AC_SUBST(target_cpu_default)
|
||||
|
||||
AC_SUBST_FILE(language_hooks)
|
||||
|
||||
sinclude(../config/gcc-lib-path.m4)
|
||||
TL_AC_GNU_MAKE_GCC_LIB_PATH
|
||||
|
||||
# If it doesn't already exist, create document directory
|
||||
echo "checking for the document directory." 1>&2
|
||||
if test -d doc ; then
|
||||
|
@ -4048,21 +4048,6 @@ __cxa_demangle (mangled_name, output_buffer, length, status)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* The specification for __cxa_demangle() is that if the mangled
|
||||
name could be either an extern "C" identifier, or an internal
|
||||
built-in type name, then we resolve it as the identifier. All
|
||||
internal built-in type names are a single lower case character.
|
||||
Frankly, this simplistic disambiguation doesn't make sense to me,
|
||||
but it is documented, so we implement it here. */
|
||||
if (IS_LOWER (mangled_name[0])
|
||||
&& mangled_name[1] == '\0'
|
||||
&& cplus_demangle_builtin_types[mangled_name[0] - 'a'].name != NULL)
|
||||
{
|
||||
if (status != NULL)
|
||||
*status = -2;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
demangled = d_demangle (mangled_name, DMGL_PARAMS | DMGL_TYPES, &alc);
|
||||
|
||||
if (demangled == NULL)
|
||||
|
@ -1,3 +1,623 @@
|
||||
2005-05-19 Release Manager
|
||||
|
||||
* GCC 3.4.4 released.
|
||||
|
||||
2005-05-08 Nathan Sidwell <nathan@codesourcery.com>
|
||||
|
||||
PR c++/21427
|
||||
Backport 2005-03-01 Nathan Sidwell <nathan@codesourcery.com>
|
||||
* class.c (update_vtable_entry_for_fn): Don't crash on invalid
|
||||
covariancy.
|
||||
|
||||
* cp-tree.h (THUNK_TARGET): Expand comment.
|
||||
* method.c (use_thunk): Make sure we also use the target, if that
|
||||
is a thunk.
|
||||
|
||||
Backport 2005-02-11 Nathan Sidwell <nathan@codesourcery.com>
|
||||
* class.c (update_vtable_entry_for_fn): Walk the covariant's binfo
|
||||
chain rather than using lookup_base.
|
||||
|
||||
2005-05-04 Mark Mitchell <mark@codesourcery.com>
|
||||
|
||||
Backport:
|
||||
2004-12-21 Mark Mitchell <mark@codesourcery.com>
|
||||
PR c++/19034
|
||||
* tree.c (cp_tree_equal): Handle OVERLOAD.
|
||||
|
||||
2005-05-02 Mark Mitchell <mark@codesourcery.com>
|
||||
|
||||
Revert:
|
||||
2005-05-01 Mark Mitchell <mark@codesourcery.com>
|
||||
* typeck.c (unary_complex_lvalue): In a template, always refuse
|
||||
simplifications.
|
||||
|
||||
2005-05-01 Mark Mitchell <mark@codesourcery.com>
|
||||
|
||||
Backport:
|
||||
2005-02-22 Mark Mitchell <mark@codesourcery.com>
|
||||
PR c++/19991
|
||||
* init.c (decl_constant_value): Iterate if the value of a decl
|
||||
is itself a constant.
|
||||
|
||||
2005-05-01 Mark Mitchell <mark@codesourcery.com>
|
||||
|
||||
Backport:
|
||||
2004-12-22 Mark Mitchell <mark@codesourcery.com>
|
||||
PR c++/18464
|
||||
* call.c (build_this): In templates, do not bother with
|
||||
build_unary_op.
|
||||
* typeck.c (unary_complex_lvalue): In a template, always refuse
|
||||
simplifications.
|
||||
|
||||
2005-04-25 Roger Sayle <roger@eyesopen.com>
|
||||
Mark Mitchell <mark@codesourcery.com>
|
||||
|
||||
PR c++/20995
|
||||
Partial backport from mainline.
|
||||
2004-09-27 Mark Mitchell <mark@codesourcery.com>
|
||||
* tree.c (fold_if_not_in_template): New function.
|
||||
* cp-tree.h (fold_if_not_in_template): Prototype here.
|
||||
* call.c (build_conditional_expr): Use fold_if_not_in_template.
|
||||
* typeck.c (build_binary_op): Likewise.
|
||||
|
||||
2005-04-16 Mark Mitchell <mark@codesourcery.com>
|
||||
|
||||
PR c++/21025
|
||||
* typeck.c (cxx_sizeof_or_alignof_type): Check whether the type to
|
||||
which sizeof/alignof is dependent, rather than just whether we are
|
||||
processing_template_decl.
|
||||
|
||||
2005-04-06 Jason Merrill <jason@redhat.com>
|
||||
|
||||
PR c++/19312
|
||||
* tree.c (stabilize_init): Don't bother trying to stabilize
|
||||
something with no side-effects.
|
||||
|
||||
2005-04-04 Mark Mitchell <mark@codesourcery.com>
|
||||
|
||||
PR c++/20679
|
||||
* parser.c (cp_parser_template_name): Fix thinko.
|
||||
|
||||
2005-04-03 Gabriel Dos Reis <gdr@integrable-solutions.net>
|
||||
|
||||
PR c++/18644
|
||||
* call.c (build_new_op): Remove check for -Wsynth.
|
||||
|
||||
2005-03-21 Paolo Carlini <pcarlini@suse.de>
|
||||
|
||||
PR c++/20147
|
||||
* semantics.c (finish_stmt_expr_expr): Return immediately
|
||||
if error_operand_p (expr).
|
||||
|
||||
2005-03-19 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
|
||||
|
||||
PR c++/20240
|
||||
* decl.c (decls_match): Compare context of VAR_DECL.
|
||||
|
||||
2005-03-19 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
|
||||
|
||||
PR c++/20333
|
||||
* parser.c (cp_parser_postfix_expression) <case RID_TYPENAME>:
|
||||
Check the return value of cp_parser_nested_name_specifier.
|
||||
|
||||
2005-03-08 Mark Mitchell <mark@codesourcery.com>
|
||||
|
||||
PR c++/20142
|
||||
* init.c (build_vec_init): When determining whether or not the
|
||||
element type has an asignment operator, look through all array
|
||||
dimensions.
|
||||
|
||||
2005-03-06 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
|
||||
|
||||
PR c++/19311
|
||||
* init.c (build_offset_ref): Don't build non-dependent SCOPE_REF.
|
||||
* pt.c (build_non_dependent_expr): Don't build NON_DEPENDENT_EXPR
|
||||
for OFFSET_TYPE.
|
||||
* typeck.c (build_x_unary_op): Don't build non-dependent SCOPE_REF.
|
||||
Also set PTRMEM_OK_P for NON_DEPENDENT_EXPR.
|
||||
(build_unary_op): Handle building ADDR_EXPR of OFFSET_REF inside
|
||||
template.
|
||||
|
||||
2005-03-02 Alexandre Oliva <aoliva@redhat.com>
|
||||
|
||||
* name-lookup.c (push_overloaded_decl): Don't error if the new
|
||||
decl matches the old one.
|
||||
* decl.c (redeclaration_error_message): Likewise.
|
||||
|
||||
2005-02-24 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
PR c++/20175
|
||||
* decl.c (reshape_init): Don't warn about missing braces if STRING_CST
|
||||
initializes a char/wchar_t array.
|
||||
|
||||
2005-02-21 Alexandre Oliva <aoliva@redhat.com>
|
||||
|
||||
PR c++/20028
|
||||
* class.c (finish_struct): Initialize TYPE_SIZE_UNIT of a
|
||||
template along with TYPE_SIZE.
|
||||
|
||||
2005-02-14 Mark Mitchell <mark@codesourcery.com>
|
||||
|
||||
* decl.c (reshape_init): Use explicit quotes in error message
|
||||
instead of %q.
|
||||
|
||||
2005-02-12 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
|
||||
|
||||
PR c++/14479
|
||||
PR c++/19487
|
||||
* pt.c (maybe_check_template_type): Remove.
|
||||
* cp-tree.h (maybe_check_template_type): Remove prototype.
|
||||
* name-lookup.c (maybe_process_template_type_declaration): Don't
|
||||
use maybe_check_template_type.
|
||||
|
||||
2005-02-10 Mark Mitchell <mark@codesourcery.com>
|
||||
|
||||
PR c++/19755
|
||||
* decl.c (reshape_init): Issue warnings about missing braces.
|
||||
|
||||
2005-02-09 Mark Mitchell <mark@codesourcery.com>
|
||||
|
||||
* parser.c (cp_parser_unqualified_id): Initialize type_decl.
|
||||
|
||||
PR c++/19787
|
||||
* call.c (initialize_reference): Robustify.
|
||||
|
||||
PR c++/19762
|
||||
* parser.c (cp_parser_unqualified_id): Avoid creating destructor
|
||||
names with invalid types.
|
||||
|
||||
PR c++/19739
|
||||
* parser.c (cp_parser_attributes_list): Allow empty lists.
|
||||
|
||||
2005-02-08 Mark Mitchell <mark@codesourcery.com>
|
||||
|
||||
PR c++/19733
|
||||
* cvt.c (convert_to_void): Issue errors about pseudo-destructor
|
||||
expressions.
|
||||
|
||||
2005-02-01 Alexandre Oliva <aoliva@redhat.com>
|
||||
|
||||
PR c++/18757
|
||||
PR c++/19366
|
||||
PR c++/19499
|
||||
* parser.c (cp_parser_template_id): Revert 2004-12-09's patch.
|
||||
Issue an error when creating the template id.
|
||||
* pt.c (fn_type_unification): Return early if the explicit
|
||||
template arg list is an error_mark_node.
|
||||
|
||||
2005-01-27 J"orn Rennecke <joern.rennecke@st.com>
|
||||
|
||||
PR c++/18370
|
||||
* parser.c (cp_parser_initializer_clause): Initialize *non_constant_p.
|
||||
|
||||
2005-01-19 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
|
||||
|
||||
PR c++/19375
|
||||
* semantics.c (finish_id_expression): Disable access checking for
|
||||
already lookuped FIELD_DECL.
|
||||
|
||||
2005-01-19 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
|
||||
|
||||
PR c++/19258
|
||||
* parser.c (cp_parser_late_parsing_default_args): Handle friend
|
||||
defined in class.
|
||||
* pt.c (push_access_scope, pop_access_scope): Likewise.
|
||||
|
||||
2005-01-15 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
PR c++/19263
|
||||
* typeck2.c (split_nonconstant_init_1) <case VECTOR_TYPE>: Put a copy
|
||||
of CONSTRUCTOR's node into MODIFY_EXPR, as the original is modified.
|
||||
Store code to *pcode.
|
||||
|
||||
2004-12-28 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
PR c++/18384, c++/18327
|
||||
* decl.c (reshape_init_array): Use UHWI type for max_index_cst
|
||||
and index. Convert max_index to size_type_node if it isn't
|
||||
host_integerp (, 1).
|
||||
|
||||
2004-12-23 Alexandre Oliva <aoliva@redhat.com>
|
||||
|
||||
PR c++/18962
|
||||
* pt.c (check_explicit_specialization): Use the argument list from
|
||||
the definition in a template function specialization definition.
|
||||
|
||||
2004-12-23 Alexandre Oliva <aoliva@redhat.com>
|
||||
|
||||
PR c++/18757
|
||||
* parser.c (cp_parser_template_id): Don't create a CPP_TEMPLATE_ID
|
||||
if parsing failed.
|
||||
|
||||
2004-12-17 Nathan Sidwell <nathan@codesourcery.com>
|
||||
|
||||
PR c++/18975
|
||||
* method.c (do_build_copy_constructor): Refactor. Don't const
|
||||
qualify a mutable field.
|
||||
(do_build_assign_ref): Likewise.
|
||||
|
||||
2004-12-10 Volker Reichelt <reichelt@igpm.rwth-aachen.de>
|
||||
|
||||
PR c++/18731
|
||||
* parser.c (cp_parser_class_head): Reject typedef-name in class head.
|
||||
|
||||
2004-12-09 Nathan Sidwell <nathan@codesourcery.com>
|
||||
|
||||
PR c++/16681
|
||||
* init.c (build_zero_init): Build a RANGE_EXPR for an array
|
||||
initializer.
|
||||
|
||||
2004-12-08 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
|
||||
|
||||
PR c++/18100
|
||||
* name-lookup.c (push_class_level_binding): Diagnose nested
|
||||
class template with the same name as enclosing class.
|
||||
|
||||
2004-12-04 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
|
||||
|
||||
PR c++/17011, c++/17971
|
||||
* pt.c (tsubst_copy) <FIELD_DECL case>: Check and diagnose
|
||||
invalid field.
|
||||
(tsubst_copy_and_build) <COMPONENT_REF case>: Check
|
||||
error_mark_node after member substitution.
|
||||
* semantics.c (finish_id_expression): Call
|
||||
finish_non_static_data_member for dependent FIELD_DECL.
|
||||
|
||||
2004-12-02 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
|
||||
|
||||
PR c++/18123
|
||||
* parser.c (cp_parser_type_specifier): Don't create new enum
|
||||
type if it is not in the form 'enum [identifier] { [...] };'.
|
||||
Catch template declaration of enum.
|
||||
|
||||
2004-12-01 Nathan Sidwell <nathan@codesourcery.com>
|
||||
|
||||
PR c++/17431
|
||||
* call.c (standard_conversion): Add FLAGS parameter. Do not allow
|
||||
derived to base conversion when checking constructor
|
||||
accessibility.
|
||||
(implicit_conversion): Pass FLAGS to standard_conversion.
|
||||
(check_constructir_callable): Disallow conversion functions.
|
||||
|
||||
2004-11-12 Mark Mitchell <mark@codesourcery.com>
|
||||
|
||||
PR c++/18389
|
||||
* decl.c (start_decl): Make sure to set *pop_scope_p. Return
|
||||
error_mark_node to indicate errors.
|
||||
|
||||
PR c++/18436
|
||||
* pt.c (tsubst_copy_and_build): Do not do Koenig lookup when an
|
||||
unqualified name resolves to a member function.
|
||||
|
||||
PR c++/18407
|
||||
* pt.c (tsubst_copy_and_build): Handle qualified names used from a
|
||||
derived class correctly.
|
||||
|
||||
2004-11-04 Release Manager
|
||||
|
||||
* GCC 3.4.3 released.
|
||||
|
||||
2004-10-31 Mark Mitchell <mark@codesourcery.com>
|
||||
|
||||
PR c++/15172
|
||||
* typeck2.c (store_init_value): Use split_nonconstant_init even
|
||||
for types that require construction.
|
||||
|
||||
2004-10-28 Mark Mitchell <mark@codesourcery.com>
|
||||
|
||||
PR c++/17132
|
||||
* pt.c (instantiate_class_template): Increment
|
||||
processing_template_decl when substituting into a member class
|
||||
template.
|
||||
|
||||
2004-10-27 Mark Mitchell <mark@codesourcery.com>
|
||||
|
||||
PR c++/18140
|
||||
* parser.c (cp_parser_next_token_ends_template_argument_p): Do not
|
||||
include ">>".
|
||||
|
||||
2004-10-27 Andrew Pinski <pinskia@physics.uc.edu>
|
||||
|
||||
PR c++/13560
|
||||
* error.c (cp_error_at): Output the context as it might be
|
||||
different file as the other location.
|
||||
|
||||
2004-10-26 Mark Mitchell <mark@codesourcery.com>
|
||||
|
||||
PR c++/18093
|
||||
* search.c (current_scope): Return the innermost non-block scope,
|
||||
not the innermost non-block, non-namespace scope.
|
||||
(at_namespace_scope_p): Adjust accordingly.
|
||||
(dfs_accessible_post): Do not pass namespaces to is_friend.
|
||||
(dfs_walk_once_accessible_r): Likewise.
|
||||
* decl.c (grokvardecl): Adjust call to current_scope.
|
||||
(build_enumerator): Likewise.
|
||||
* parser.c (cp_parser_using_declaration): Likewise.
|
||||
(cp_parser_direct_declarator): Use at_namespace_scope_p instead of
|
||||
current_scope.
|
||||
(cp_parser_class_head): Adjust call to current_scope.
|
||||
* name-lookup.c (do_namespace_alias): Set the DECL_CONTEXT for the
|
||||
alias.
|
||||
|
||||
PR c++/18020
|
||||
* pt.c (tusbst_copy_and_build): Resolve enumeration constants to
|
||||
their underlying values.
|
||||
|
||||
2004-10-17 Andrew Pinski <pinskia@physics.uc.edu>
|
||||
|
||||
PR c++/16301
|
||||
* name-lookup.c (parse_using_directive): If we have a
|
||||
error_mark_node, do not set the decl namespace associations
|
||||
on it.
|
||||
|
||||
2004-10-14 Mark Mitchell <mark@codesourcery.com>
|
||||
|
||||
PR c++/17976
|
||||
* decl.c (cp_finish_decl): Do not call expand_static_init more
|
||||
than once for a single variable.
|
||||
|
||||
2004-10-11 Mark Mitchell <mark@codesourcery.com>
|
||||
|
||||
PR c++/15786
|
||||
* parser.c (cp_parser_declarator): Add member_p parameter.
|
||||
(cp_parser_condition): Adjust calls to cp_parser_declarator.
|
||||
(cp_parser_explicit_instantiation): Likewise.
|
||||
(cp_parser_init_declarator): Likewise.
|
||||
(cp_parser_direct_declarator): Add member_p parameter. Do not
|
||||
parse tentatively when parsing the parameters to a member.
|
||||
(cp_parser_type_id): Adjust calls to cp_parser_declarator.
|
||||
(cp_parser_parameter_declaration): Likewise.
|
||||
(cp_parser_member_declaration): Likewise.
|
||||
(cp_parser_exception_declaration): Likewise.
|
||||
|
||||
2004-10-11 Mark Mitchell <mark@codesourcery.com>
|
||||
|
||||
* decl2.c (finish_anon_union): Robustify.
|
||||
|
||||
2004-10-10 Mark Mitchell <mark@codesourcery.com>
|
||||
|
||||
PR c++/17393
|
||||
* decl.c (grokdeclarator): Robustify error-recovery on invalid
|
||||
declarations.
|
||||
|
||||
2004-10-09 Mark Mitchell <mark@codesourcery.com>
|
||||
|
||||
PR c++/17821
|
||||
* parser.c (cp_parser_postfix_dot_deref_expression): If the
|
||||
pseduo-destructor-name production does not work, fall back to the
|
||||
ordinary production.
|
||||
|
||||
PR c++/17826
|
||||
* tree.c (cp_tree_equal): Handle a BASELINK.
|
||||
|
||||
2004-10-09 Mark Mitchell <mark@codesourcery.com>
|
||||
|
||||
PR c++/17524
|
||||
* cp-tree.h (check_var_type): New function.
|
||||
* decl.c (check_var_type): New function, split out from ...
|
||||
(grokdeclarator): ... here.
|
||||
* pt.c (tsubst_decl): Use check_var_type.
|
||||
|
||||
PR c++/17685
|
||||
* decl.c (grokdeclarator): Disallow declarations of operators as
|
||||
non-functions.
|
||||
|
||||
2004-10-08 Volker Reichelt <reichelt@igpm.rwth-aachen.de>
|
||||
|
||||
PR c++/17868
|
||||
* error.c (dump_expr): Add missing case for RDIV_EXPR.
|
||||
|
||||
2004-10-08 Nathan Sidwell <nathan@codesourcery.com>
|
||||
|
||||
PR c++/17829
|
||||
* parser.c (cp_parser_postfix_expression): Inhibit Koenig when
|
||||
unqualified lookup finds a member function.
|
||||
|
||||
2004-09-28 Roger Sayle <roger@eyesopen.com>
|
||||
|
||||
PR driver/17537
|
||||
* g++spec.c (lang_specific_driver): Unrecognized libraries, other
|
||||
than -lc and -lm, may require linking against libstc++.
|
||||
|
||||
2004-09-27 Mark Mitchell <mark@codesourcery.com>
|
||||
|
||||
PR c++/17585
|
||||
* cp-tree.h (shared_member_p): Declare.
|
||||
* search.c (shared_member_p): Give it external linkage.
|
||||
* semantics.c (finish_qualified_id_expr): Use it.
|
||||
(finish_id_expression): Likewise.
|
||||
|
||||
2004-09-22 Giovanni Bajo <giovannibajo@gcc.gnu.org>
|
||||
|
||||
PR c++/14179
|
||||
* parser.c (cp_parser_initializer): Speed up parsing of simple
|
||||
literals as initializers.
|
||||
|
||||
2004-09-21 Giovanni Bajo <giovannibajo@gcc.gnu.org>
|
||||
|
||||
PR c++/14179
|
||||
* decl.c (reshape_init): Extract array handling into...
|
||||
(reshape_init_array): New function. Use integers instead of trees
|
||||
for indices. Handle out-of-range designated initializers.
|
||||
|
||||
2004-09-16 Mark Mitchell <mark@codesourcery.com>
|
||||
|
||||
PR c++/17501
|
||||
* parser.c (cp_parser_nested_name_specifier): Do not resolve
|
||||
typename types if the user explicitly said "typename".
|
||||
|
||||
2004-09-13 Mark Mitchell <mark@codesourcery.com>
|
||||
|
||||
PR c++/16162
|
||||
* parser.c (cp_parser_id_expression): Correct value for
|
||||
is_declarator.
|
||||
(cp_parser_nested_name_specifier_opt): Look through typenames as
|
||||
necessary.
|
||||
(cp_parser_template_name): Honor check_dependency_p.
|
||||
|
||||
2004-09-13 Mark Mitchell <mark@codesourcery.com>
|
||||
|
||||
PR c++/17327
|
||||
* pt.c (unify): Add ENUMERAL_TYPE case. Replace sorry with
|
||||
gcc_unreacable.
|
||||
|
||||
2004-09-06 Release Manager
|
||||
|
||||
* GCC 3.4.2 released.
|
||||
|
||||
2004-08-25 Roger Sayle <roger@eyesopen.com>
|
||||
|
||||
PR middle-end/16693
|
||||
PR tree-optimization/16372
|
||||
* decl.c (finish_enum): Make the precision of the enumerated type
|
||||
the same width as the underlying integer type.
|
||||
|
||||
2004-08-24 Jason Merrill <jason@redhat.com>
|
||||
|
||||
PR c++/16851
|
||||
* tree.c (stabilize_init): See through a COMPOUND_EXPR.
|
||||
|
||||
PR c++/15461
|
||||
* semantics.c (nullify_returns_r): Replace a DECL_STMT
|
||||
for the NRV with an INIT_EXPR.
|
||||
|
||||
2004-08-24 Nathan Sidwell <nathan@codesourcery.com>
|
||||
|
||||
PR c++/16889
|
||||
* (is_subobject_of_p): Resurrect & optimize.
|
||||
(lookup_field_r): Use it.
|
||||
|
||||
2004-08-24 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
|
||||
|
||||
PR c++/16706
|
||||
* search.c (friend_accessible_p): Increment processing_template_decl
|
||||
when deal with TEMPLATE_DECL of SCOPE.
|
||||
|
||||
2004-08-23 Janis Johnson <janis187@us.ibm.com>
|
||||
|
||||
Backports from mainline:
|
||||
|
||||
2004-02-27 Ziemowit Laski <zlaski@apple.com>
|
||||
2004-03-24 Ziemowit Laski <zlaski@apple.com>
|
||||
|
||||
* Make-lang.in (cp/mangle.o): Depend on $(TARGET_H).
|
||||
* mangle.c (write_type): Add call to 'mangle_fundamental_type'
|
||||
target hook.
|
||||
* tree.c (pod_type_p): Treat VECTOR_TYPEs as PODs.
|
||||
|
||||
2004-08-19 Mark Mitchell <mark@codesourcery.com>
|
||||
|
||||
PR c++/15890
|
||||
* pt.c (push_template_decl_real): Disallow template allocation
|
||||
functions with fewer than two parameters.
|
||||
|
||||
2004-08-18 Mark Mitchell <mark@codesourcery.com>
|
||||
|
||||
PR c++/17068
|
||||
* pt.c (dependent_template_p): Treat IDENTIFIER_NODEs as
|
||||
dependent.
|
||||
|
||||
2004-08-17 Mark Mitchell <mark@codesourcery.com>
|
||||
|
||||
PR c++/16246
|
||||
* pt.c (unify): Make sure that non-type arguments have the same
|
||||
type as the corresponding parameter.
|
||||
|
||||
2004-08-12 Mark Mitchell <mark@codesourcery.com>
|
||||
|
||||
PR c++/16273
|
||||
* class.c (count_depth_data): New type.
|
||||
(dfs_depth_post): New function.
|
||||
(dfs_depth_q): Likewise.
|
||||
(find_final_overrider_data_s): Change type of vpath.
|
||||
Add vpath_list.
|
||||
(dfs_find_final_overrider_1): New function.
|
||||
(dfs_find_final_overrider): Use it.
|
||||
(dfs_find_final_overrider_q): Adjust use of vpath.
|
||||
(dfs_find_final_overrider_post): Likewise.
|
||||
(find_final_overrider): Use dfs_depth. Allocate and deallocate
|
||||
vpath_list.
|
||||
|
||||
2004-08-12 Jan Beulich <jbeulich@novell.com>
|
||||
|
||||
* parser.c (cp_parser_asm_definition): Properly consume scope operator
|
||||
tokens preceding the clobbers. Don't check for scope operator
|
||||
following inputs. Simplify inputs handling to match that now used for
|
||||
clobbers.
|
||||
|
||||
2004-08-11 Mark Mitchell <mark@codesourcery.com>
|
||||
|
||||
PR c++/16698
|
||||
* except.c (build_throw): Allocate cleanup_type and the function
|
||||
for __cxa_throw separately.
|
||||
|
||||
2004-08-11 Mark Mitchell <mark@codesourcery.com>
|
||||
|
||||
PR c++/16717
|
||||
* semantics.c (expand_body): Do not update static_ctors and
|
||||
static_dtors here.
|
||||
(expand_or_defer_fn): Do it here, instead.
|
||||
|
||||
PR c++/16853
|
||||
* call.c (standard_conversion): Do not accept conversions between
|
||||
pointers to members if the class types are unrelated.
|
||||
|
||||
PR c++/16870
|
||||
* pt.c (tsubst): Just return the unknown_type_node.
|
||||
|
||||
PR c++/16964
|
||||
* parser.c (cp_parser_class_specifier): Robustify.
|
||||
|
||||
PR c++/16904
|
||||
* pt.c (tsubst_copy_and_build): Complain about invalid
|
||||
qualification.
|
||||
|
||||
PR c++/16929
|
||||
* pt.c (tsubst_default_argument): Clear out current_class_ptr and
|
||||
current_class_ref while tsubsting.
|
||||
|
||||
2004-08-01 Mark Mitchell <mark@codesourcery.com>
|
||||
|
||||
PR c++/16224
|
||||
* name-lookup.c (decl_namespace): Remove.
|
||||
(current_decl_namespace): Use decl_namespace_context instead of
|
||||
decl_namespace.
|
||||
(push_decl_namespace): Likewise.
|
||||
(arg_assoc_class): Likewise.
|
||||
(arg_assoc_type): Likewise.
|
||||
* pt.c (check_specialization_namespace): New function.
|
||||
(maybe_process_partial_specialization): Use it.
|
||||
(register_specialization): Likewise.
|
||||
|
||||
2004-08-01 Mark Mitchell <mark@codesourcery.com>
|
||||
|
||||
PR c++/16489
|
||||
* cp-tree.h (DECL_INTEGRAL_CONSTANT_VAR_P): New macro.
|
||||
* call.c (null_ptr_cst_p): Handle variables with constant
|
||||
initializers.
|
||||
* pt.c (convert_nontype_argument): Use
|
||||
DECL_INTEGRAL_CONSTANT_VAR_P.
|
||||
* semantics.c (finish_id_expression): Likewise.
|
||||
|
||||
PR c++/16529
|
||||
* decl.c (duplicate_decls): Reject duplicate namespace
|
||||
declarations.
|
||||
|
||||
PR c++/16810
|
||||
* typeck.c (build_ptrmemfunc): Loosen assertion.
|
||||
|
||||
2004-07-28 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
|
||||
|
||||
PR c++/13092
|
||||
* init.c (build_offset_ref): Build SCOPE_REF with non-null
|
||||
TREE_TYPE for non-dependent names.
|
||||
* typeck.c (build_x_unary_op): Handle non-dependent SCOPE_REF.
|
||||
* pt.c (type_dependent_expression_p): Handle SCOPE_REF with
|
||||
unknown_type_node as its TREE_TYPE.
|
||||
* cxx-pretty_print.c (pp_cxx_unqualified_id): Handle BASELINK.
|
||||
* error.c (dump_decl) <SCOPE_REF case>: Use pp_expression.
|
||||
(dump_expr) <SCOPE_REF case>: Likewise.
|
||||
|
||||
2004-07-21 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
|
||||
|
||||
PR c++/16175
|
||||
|
@ -258,7 +258,8 @@ cp/semantics.o: cp/semantics.c $(CXX_TREE_H) $(TM_H) cp/lex.h except.h toplev.h
|
||||
cp/dump.o: cp/dump.c $(CXX_TREE_H) $(TM_H) tree-dump.h
|
||||
cp/optimize.o: cp/optimize.c $(CXX_TREE_H) $(TM_H) rtl.h integrate.h insn-config.h \
|
||||
input.h $(PARAMS_H) debug.h tree-inline.h
|
||||
cp/mangle.o: cp/mangle.c $(CXX_TREE_H) $(TM_H) toplev.h real.h gt-cp-mangle.h $(TM_P_H)
|
||||
cp/mangle.o: cp/mangle.c $(CXX_TREE_H) $(TM_H) toplev.h real.h gt-cp-mangle.h \
|
||||
$(TARGET_H) $(TM_P_H)
|
||||
|
||||
cp/parser.o: cp/parser.c $(CXX_TREE_H) $(TM_H) diagnostic.h gt-cp-parser.h output.h
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
/* Functions related to invoking methods and overloaded functions.
|
||||
Copyright (C) 1987, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
|
||||
1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
|
||||
1999, 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
|
||||
Contributed by Michael Tiemann (tiemann@cygnus.com) and
|
||||
modified by Brendan Kehoe (brendan@cygnus.com).
|
||||
|
||||
@ -86,7 +86,7 @@ static struct z_candidate *add_conv_candidate
|
||||
static struct z_candidate *add_function_candidate
|
||||
(struct z_candidate **, tree, tree, tree, tree, tree, int);
|
||||
static tree implicit_conversion (tree, tree, tree, int);
|
||||
static tree standard_conversion (tree, tree, tree);
|
||||
static tree standard_conversion (tree, tree, tree, int);
|
||||
static tree reference_binding (tree, tree, tree, int);
|
||||
static tree build_conv (enum tree_code, tree, tree);
|
||||
static bool is_subseq (tree, tree);
|
||||
@ -373,6 +373,9 @@ struct z_candidate GTY(()) {
|
||||
#define USER_CONV_CAND(NODE) WRAPPER_ZC (TREE_OPERAND (NODE, 1))
|
||||
#define USER_CONV_FN(NODE) (USER_CONV_CAND (NODE)->fn)
|
||||
|
||||
/* Returns true iff T is a null pointer constant in the sense of
|
||||
[conv.ptr]. */
|
||||
|
||||
bool
|
||||
null_ptr_cst_p (tree t)
|
||||
{
|
||||
@ -380,6 +383,8 @@ null_ptr_cst_p (tree t)
|
||||
|
||||
A null pointer constant is an integral constant expression
|
||||
(_expr.const_) rvalue of integer type that evaluates to zero. */
|
||||
if (DECL_INTEGRAL_CONSTANT_VAR_P (t))
|
||||
t = decl_constant_value (t);
|
||||
if (t == null_node
|
||||
|| (CP_INTEGRAL_TYPE_P (TREE_TYPE (t)) && integer_zerop (t)))
|
||||
return true;
|
||||
@ -449,7 +454,7 @@ strip_top_quals (tree t)
|
||||
also pass the expression EXPR to convert from. */
|
||||
|
||||
static tree
|
||||
standard_conversion (tree to, tree from, tree expr)
|
||||
standard_conversion (tree to, tree from, tree expr, int flags)
|
||||
{
|
||||
enum tree_code fcode, tcode;
|
||||
tree conv;
|
||||
@ -500,7 +505,7 @@ standard_conversion (tree to, tree from, tree expr)
|
||||
the standard conversion sequence to perform componentwise
|
||||
conversion. */
|
||||
tree part_conv = standard_conversion
|
||||
(TREE_TYPE (to), TREE_TYPE (from), NULL_TREE);
|
||||
(TREE_TYPE (to), TREE_TYPE (from), NULL_TREE, flags);
|
||||
|
||||
if (part_conv)
|
||||
{
|
||||
@ -573,6 +578,8 @@ standard_conversion (tree to, tree from, tree expr)
|
||||
TYPE_PTRMEM_POINTED_TO_TYPE (from));
|
||||
conv = build_conv (PMEM_CONV, from, conv);
|
||||
}
|
||||
else if (!same_type_p (fbase, tbase))
|
||||
return NULL;
|
||||
}
|
||||
else if (IS_AGGR_TYPE (TREE_TYPE (from))
|
||||
&& IS_AGGR_TYPE (TREE_TYPE (to))
|
||||
@ -685,7 +692,8 @@ standard_conversion (tree to, tree from, tree expr)
|
||||
&& ((*targetm.vector_opaque_p) (from)
|
||||
|| (*targetm.vector_opaque_p) (to)))
|
||||
return build_conv (STD_CONV, to, conv);
|
||||
else if (IS_AGGR_TYPE (to) && IS_AGGR_TYPE (from)
|
||||
else if (!(flags & LOOKUP_CONSTRUCTOR_CALLABLE)
|
||||
&& IS_AGGR_TYPE (to) && IS_AGGR_TYPE (from)
|
||||
&& is_properly_derived_from (from, to))
|
||||
{
|
||||
if (TREE_CODE (conv) == RVALUE_CONV)
|
||||
@ -1098,7 +1106,7 @@ implicit_conversion (tree to, tree from, tree expr, int flags)
|
||||
if (TREE_CODE (to) == REFERENCE_TYPE)
|
||||
conv = reference_binding (to, from, expr, flags);
|
||||
else
|
||||
conv = standard_conversion (to, from, expr);
|
||||
conv = standard_conversion (to, from, expr, flags);
|
||||
|
||||
if (conv)
|
||||
return conv;
|
||||
@ -2195,10 +2203,18 @@ any_strictly_viable (struct z_candidate *cands)
|
||||
return false;
|
||||
}
|
||||
|
||||
/* OBJ is being used in an expression like "OBJ.f (...)". In other
|
||||
words, it is about to become the "this" pointer for a member
|
||||
function call. Take the address of the object. */
|
||||
|
||||
static tree
|
||||
build_this (tree obj)
|
||||
{
|
||||
/* Fix this to work on non-lvalues. */
|
||||
/* In a template, we are only concerned about the type of the
|
||||
expression, so we can take a shortcut. */
|
||||
if (processing_template_decl)
|
||||
return build_address (obj);
|
||||
|
||||
return build_unary_op (ADDR_EXPR, obj, 0);
|
||||
}
|
||||
|
||||
@ -3270,7 +3286,8 @@ build_conditional_expr (tree arg1, tree arg2, tree arg3)
|
||||
}
|
||||
|
||||
valid_operands:
|
||||
result = fold (build (COND_EXPR, result_type, arg1, arg2, arg3));
|
||||
result = fold_if_not_in_template (build (COND_EXPR, result_type,
|
||||
arg1, arg2, arg3));
|
||||
/* We can't use result_type below, as fold might have returned a
|
||||
throw_expr. */
|
||||
|
||||
@ -3554,20 +3571,6 @@ build_new_op (enum tree_code code, int flags, tree arg1, tree arg2, tree arg3,
|
||||
if (overloaded_p)
|
||||
*overloaded_p = true;
|
||||
|
||||
if (warn_synth
|
||||
&& fnname == ansi_assopname (NOP_EXPR)
|
||||
&& DECL_ARTIFICIAL (cand->fn)
|
||||
&& candidates->next
|
||||
&& ! candidates->next->next)
|
||||
{
|
||||
warning ("using synthesized `%#D' for copy assignment",
|
||||
cand->fn);
|
||||
cp_warning_at (" where cfront would use `%#D'",
|
||||
cand == candidates
|
||||
? candidates->next->fn
|
||||
: candidates->fn);
|
||||
}
|
||||
|
||||
return build_over_call (cand, LOOKUP_NORMAL);
|
||||
}
|
||||
|
||||
@ -3871,6 +3874,7 @@ check_constructor_callable (tree type, tree expr)
|
||||
build_tree_list (NULL_TREE, expr),
|
||||
TYPE_BINFO (type),
|
||||
LOOKUP_NORMAL | LOOKUP_ONLYCONVERTING
|
||||
| LOOKUP_NO_CONVERSION
|
||||
| LOOKUP_CONSTRUCTOR_CALLABLE);
|
||||
}
|
||||
|
||||
@ -6181,6 +6185,8 @@ initialize_reference (tree type, tree expr, tree decl, tree *cleanup)
|
||||
/*fn=*/NULL_TREE, /*argnum=*/0,
|
||||
/*inner=*/-1,
|
||||
/*issue_conversion_warnings=*/true);
|
||||
if (error_operand_p (expr))
|
||||
return error_mark_node;
|
||||
if (!real_lvalue_p (expr))
|
||||
{
|
||||
tree init;
|
||||
|
@ -1,6 +1,7 @@
|
||||
/* Functions related to building classes and their related objects.
|
||||
Copyright (C) 1987, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
|
||||
1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
|
||||
1999, 2000, 2001, 2002, 2003, 2004, 2005
|
||||
Free Software Foundation, Inc.
|
||||
Contributed by Michael Tiemann (tiemann@cygnus.com)
|
||||
|
||||
This file is part of GCC.
|
||||
@ -1847,6 +1848,36 @@ base_derived_from (tree derived, tree base)
|
||||
return false;
|
||||
}
|
||||
|
||||
typedef struct count_depth_data {
|
||||
/* The depth of the current subobject, with "1" as the depth of the
|
||||
most derived object in the hierarchy. */
|
||||
size_t depth;
|
||||
/* The maximum depth found so far. */
|
||||
size_t max_depth;
|
||||
} count_depth_data;
|
||||
|
||||
/* Called from find_final_overrider via dfs_walk. */
|
||||
|
||||
static tree
|
||||
dfs_depth_post (tree binfo ATTRIBUTE_UNUSED, void *data)
|
||||
{
|
||||
count_depth_data *cd = (count_depth_data *) data;
|
||||
if (cd->depth > cd->max_depth)
|
||||
cd->max_depth = cd->depth;
|
||||
cd->depth--;
|
||||
return NULL_TREE;
|
||||
}
|
||||
|
||||
/* Called from find_final_overrider via dfs_walk. */
|
||||
|
||||
static tree
|
||||
dfs_depth_q (tree derived, int i, void *data)
|
||||
{
|
||||
count_depth_data *cd = (count_depth_data *) data;
|
||||
cd->depth++;
|
||||
return BINFO_BASETYPE (derived, i);
|
||||
}
|
||||
|
||||
typedef struct find_final_overrider_data_s {
|
||||
/* The function for which we are trying to find a final overrider. */
|
||||
tree fn;
|
||||
@ -1856,10 +1887,64 @@ typedef struct find_final_overrider_data_s {
|
||||
tree most_derived_type;
|
||||
/* The candidate overriders. */
|
||||
tree candidates;
|
||||
/* Binfos which inherited virtually on the current path. */
|
||||
tree vpath;
|
||||
/* Each entry in this array is the next-most-derived class for a
|
||||
virtual base class along the current path. */
|
||||
tree *vpath_list;
|
||||
/* A pointer one past the top of the VPATH_LIST. */
|
||||
tree *vpath;
|
||||
} find_final_overrider_data;
|
||||
|
||||
/* Add the overrider along the current path to FFOD->CANDIDATES.
|
||||
Returns true if an overrider was found; false otherwise. */
|
||||
|
||||
static bool
|
||||
dfs_find_final_overrider_1 (tree binfo,
|
||||
tree *vpath,
|
||||
find_final_overrider_data *ffod)
|
||||
{
|
||||
tree method;
|
||||
|
||||
/* If BINFO is not the most derived type, try a more derived class.
|
||||
A definition there will overrider a definition here. */
|
||||
if (!same_type_p (BINFO_TYPE (binfo), ffod->most_derived_type))
|
||||
{
|
||||
tree derived;
|
||||
|
||||
if (TREE_VIA_VIRTUAL (binfo))
|
||||
derived = *--vpath;
|
||||
else
|
||||
derived = BINFO_INHERITANCE_CHAIN (binfo);
|
||||
if (dfs_find_final_overrider_1 (derived, vpath, ffod))
|
||||
return true;
|
||||
}
|
||||
|
||||
method = look_for_overrides_here (BINFO_TYPE (binfo), ffod->fn);
|
||||
if (method)
|
||||
{
|
||||
tree *candidate = &ffod->candidates;
|
||||
|
||||
/* Remove any candidates overridden by this new function. */
|
||||
while (*candidate)
|
||||
{
|
||||
/* If *CANDIDATE overrides METHOD, then METHOD
|
||||
cannot override anything else on the list. */
|
||||
if (base_derived_from (TREE_VALUE (*candidate), binfo))
|
||||
return true;
|
||||
/* If METHOD overrides *CANDIDATE, remove *CANDIDATE. */
|
||||
if (base_derived_from (binfo, TREE_VALUE (*candidate)))
|
||||
*candidate = TREE_CHAIN (*candidate);
|
||||
else
|
||||
candidate = &TREE_CHAIN (*candidate);
|
||||
}
|
||||
|
||||
/* Add the new function. */
|
||||
ffod->candidates = tree_cons (method, binfo, ffod->candidates);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Called from find_final_overrider via dfs_walk. */
|
||||
|
||||
static tree
|
||||
@ -1868,57 +1953,7 @@ dfs_find_final_overrider (tree binfo, void* data)
|
||||
find_final_overrider_data *ffod = (find_final_overrider_data *) data;
|
||||
|
||||
if (binfo == ffod->declaring_base)
|
||||
{
|
||||
/* We've found a path to the declaring base. Walk the path from
|
||||
derived to base, looking for an overrider for FN. */
|
||||
tree path, probe, vpath;
|
||||
|
||||
/* Build the path, using the inheritance chain and record of
|
||||
virtual inheritance. */
|
||||
for (path = NULL_TREE, probe = binfo, vpath = ffod->vpath;;)
|
||||
{
|
||||
path = tree_cons (NULL_TREE, probe, path);
|
||||
if (same_type_p (BINFO_TYPE (probe), ffod->most_derived_type))
|
||||
break;
|
||||
if (TREE_VIA_VIRTUAL (probe))
|
||||
{
|
||||
probe = TREE_VALUE (vpath);
|
||||
vpath = TREE_CHAIN (vpath);
|
||||
}
|
||||
else
|
||||
probe = BINFO_INHERITANCE_CHAIN (probe);
|
||||
}
|
||||
/* Now walk path, looking for overrides. */
|
||||
for (; path; path = TREE_CHAIN (path))
|
||||
{
|
||||
tree method = look_for_overrides_here
|
||||
(BINFO_TYPE (TREE_VALUE (path)), ffod->fn);
|
||||
|
||||
if (method)
|
||||
{
|
||||
tree *candidate = &ffod->candidates;
|
||||
path = TREE_VALUE (path);
|
||||
|
||||
/* Remove any candidates overridden by this new function. */
|
||||
while (*candidate)
|
||||
{
|
||||
/* If *CANDIDATE overrides METHOD, then METHOD
|
||||
cannot override anything else on the list. */
|
||||
if (base_derived_from (TREE_VALUE (*candidate), path))
|
||||
return NULL_TREE;
|
||||
/* If METHOD overrides *CANDIDATE, remove *CANDIDATE. */
|
||||
if (base_derived_from (path, TREE_VALUE (*candidate)))
|
||||
*candidate = TREE_CHAIN (*candidate);
|
||||
else
|
||||
candidate = &TREE_CHAIN (*candidate);
|
||||
}
|
||||
|
||||
/* Add the new function. */
|
||||
ffod->candidates = tree_cons (method, path, ffod->candidates);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
dfs_find_final_overrider_1 (binfo, ffod->vpath, ffod);
|
||||
|
||||
return NULL_TREE;
|
||||
}
|
||||
@ -1930,7 +1965,7 @@ dfs_find_final_overrider_q (tree derived, int ix, void *data)
|
||||
find_final_overrider_data *ffod = (find_final_overrider_data *) data;
|
||||
|
||||
if (TREE_VIA_VIRTUAL (binfo))
|
||||
ffod->vpath = tree_cons (NULL_TREE, derived, ffod->vpath);
|
||||
*ffod->vpath++ = derived;
|
||||
|
||||
return binfo;
|
||||
}
|
||||
@ -1940,8 +1975,8 @@ dfs_find_final_overrider_post (tree binfo, void *data)
|
||||
{
|
||||
find_final_overrider_data *ffod = (find_final_overrider_data *) data;
|
||||
|
||||
if (TREE_VIA_VIRTUAL (binfo) && TREE_CHAIN (ffod->vpath))
|
||||
ffod->vpath = TREE_CHAIN (ffod->vpath);
|
||||
if (TREE_VIA_VIRTUAL (binfo))
|
||||
ffod->vpath--;
|
||||
|
||||
return NULL_TREE;
|
||||
}
|
||||
@ -1955,6 +1990,7 @@ static tree
|
||||
find_final_overrider (tree derived, tree binfo, tree fn)
|
||||
{
|
||||
find_final_overrider_data ffod;
|
||||
count_depth_data cd;
|
||||
|
||||
/* Getting this right is a little tricky. This is valid:
|
||||
|
||||
@ -1976,12 +2012,18 @@ find_final_overrider (tree derived, tree binfo, tree fn)
|
||||
different overriders along any two, then there is a problem. */
|
||||
if (DECL_THUNK_P (fn))
|
||||
fn = THUNK_TARGET (fn);
|
||||
|
||||
|
||||
/* Determine the depth of the hierarchy. */
|
||||
cd.depth = 0;
|
||||
cd.max_depth = 0;
|
||||
dfs_walk (derived, dfs_depth_post, dfs_depth_q, &cd);
|
||||
|
||||
ffod.fn = fn;
|
||||
ffod.declaring_base = binfo;
|
||||
ffod.most_derived_type = BINFO_TYPE (derived);
|
||||
ffod.candidates = NULL_TREE;
|
||||
ffod.vpath = NULL_TREE;
|
||||
ffod.vpath_list = (tree *) xcalloc (cd.max_depth, sizeof (tree));
|
||||
ffod.vpath = ffod.vpath_list;
|
||||
|
||||
dfs_walk_real (derived,
|
||||
dfs_find_final_overrider,
|
||||
@ -1989,6 +2031,8 @@ find_final_overrider (tree derived, tree binfo, tree fn)
|
||||
dfs_find_final_overrider_q,
|
||||
&ffod);
|
||||
|
||||
free (ffod.vpath_list);
|
||||
|
||||
/* If there was no winner, issue an error message. */
|
||||
if (!ffod.candidates || TREE_CHAIN (ffod.candidates))
|
||||
{
|
||||
@ -2072,6 +2116,9 @@ update_vtable_entry_for_fn (tree t, tree binfo, tree fn, tree* virtuals,
|
||||
also be converting to the return type of FN, we have to
|
||||
combine the two conversions here. */
|
||||
tree fixed_offset, virtual_offset;
|
||||
|
||||
over_return = TREE_TYPE (over_return);
|
||||
base_return = TREE_TYPE (base_return);
|
||||
|
||||
if (DECL_THUNK_P (fn))
|
||||
{
|
||||
@ -2089,32 +2136,51 @@ update_vtable_entry_for_fn (tree t, tree binfo, tree fn, tree* virtuals,
|
||||
virtual_offset =
|
||||
TREE_VALUE (purpose_member
|
||||
(BINFO_TYPE (virtual_offset),
|
||||
CLASSTYPE_VBASECLASSES (TREE_TYPE (over_return))));
|
||||
else if (!same_type_p (TREE_TYPE (over_return),
|
||||
TREE_TYPE (base_return)))
|
||||
CLASSTYPE_VBASECLASSES (over_return)));
|
||||
else if (!same_type_ignoring_top_level_qualifiers_p
|
||||
(over_return, base_return))
|
||||
{
|
||||
/* There was no existing virtual thunk (which takes
|
||||
precedence). */
|
||||
tree thunk_binfo;
|
||||
base_kind kind;
|
||||
|
||||
thunk_binfo = lookup_base (TREE_TYPE (over_return),
|
||||
TREE_TYPE (base_return),
|
||||
ba_check | ba_quiet, &kind);
|
||||
/* There was no existing virtual thunk (which takes
|
||||
precedence). So find the binfo of the base function's
|
||||
return type within the overriding function's return type.
|
||||
We cannot call lookup base here, because we're inside a
|
||||
dfs_walk, and will therefore clobber the BINFO_MARKED
|
||||
flags. Fortunately we know the covariancy is valid (it
|
||||
has already been checked), so we can just iterate along
|
||||
the binfos, which have been chained in inheritance graph
|
||||
order. Of course it is lame that we have to repeat the
|
||||
search here anyway -- we should really be caching pieces
|
||||
of the vtable and avoiding this repeated work. */
|
||||
tree thunk_binfo, base_binfo;
|
||||
|
||||
if (thunk_binfo && (kind == bk_via_virtual
|
||||
|| !BINFO_OFFSET_ZEROP (thunk_binfo)))
|
||||
/* Find the base binfo within the overriding function's
|
||||
return type. We will always find a thunk_binfo, except
|
||||
when the covariancy is invalid (which we will have
|
||||
already diagnosed). */
|
||||
for (base_binfo = TYPE_BINFO (base_return),
|
||||
thunk_binfo = TYPE_BINFO (over_return);
|
||||
thunk_binfo;
|
||||
thunk_binfo = TREE_CHAIN (thunk_binfo))
|
||||
if (same_type_p (BINFO_TYPE (thunk_binfo),
|
||||
BINFO_TYPE (base_binfo)))
|
||||
break;
|
||||
|
||||
/* See if virtual inheritance is involved. */
|
||||
for (virtual_offset = thunk_binfo;
|
||||
virtual_offset;
|
||||
virtual_offset = BINFO_INHERITANCE_CHAIN (virtual_offset))
|
||||
if (TREE_VIA_VIRTUAL (virtual_offset))
|
||||
break;
|
||||
|
||||
if (virtual_offset
|
||||
|| (thunk_binfo && !BINFO_OFFSET_ZEROP (thunk_binfo)))
|
||||
{
|
||||
tree offset = convert (ssizetype, BINFO_OFFSET (thunk_binfo));
|
||||
|
||||
if (kind == bk_via_virtual)
|
||||
if (virtual_offset)
|
||||
{
|
||||
/* We convert via virtual base. Find the virtual
|
||||
base and adjust the fixed offset to be from there. */
|
||||
while (!TREE_VIA_VIRTUAL (thunk_binfo))
|
||||
thunk_binfo = BINFO_INHERITANCE_CHAIN (thunk_binfo);
|
||||
|
||||
virtual_offset = thunk_binfo;
|
||||
/* We convert via virtual base. Adjust the fixed
|
||||
offset to be from there. */
|
||||
offset = size_diffop
|
||||
(offset, convert
|
||||
(ssizetype, BINFO_OFFSET (virtual_offset)));
|
||||
@ -5174,6 +5240,7 @@ finish_struct (tree t, tree attributes)
|
||||
{
|
||||
finish_struct_methods (t);
|
||||
TYPE_SIZE (t) = bitsize_zero_node;
|
||||
TYPE_SIZE_UNIT (t) = size_zero_node;
|
||||
}
|
||||
else
|
||||
finish_struct_1 (t);
|
||||
|
@ -1,6 +1,6 @@
|
||||
/* Definitions for C++ parsing and type checking.
|
||||
Copyright (C) 1987, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
|
||||
2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
|
||||
2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
|
||||
Contributed by Michael Tiemann (tiemann@cygnus.com)
|
||||
|
||||
This file is part of GCC.
|
||||
@ -1899,6 +1899,23 @@ struct lang_decl GTY(())
|
||||
#define DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P(NODE) \
|
||||
(TREE_LANG_FLAG_2 (VAR_DECL_CHECK (NODE)))
|
||||
|
||||
/* Nonzero for a VAR_DECL that can be used in an integral constant
|
||||
expression.
|
||||
|
||||
[expr.const]
|
||||
|
||||
An integral constant-expression can only involve ... const
|
||||
variables of static or enumeration types initialized with
|
||||
constant expressions ...
|
||||
|
||||
The standard does not require that the expression be non-volatile.
|
||||
G++ implements the proposed correction in DR 457. */
|
||||
#define DECL_INTEGRAL_CONSTANT_VAR_P(NODE) \
|
||||
(TREE_CODE (NODE) == VAR_DECL \
|
||||
&& CP_TYPE_CONST_NON_VOLATILE_P (TREE_TYPE (NODE)) \
|
||||
&& INTEGRAL_OR_ENUMERATION_TYPE_P (TREE_TYPE (NODE)) \
|
||||
&& DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (NODE))
|
||||
|
||||
/* Nonzero if the DECL was initialized in the class definition itself,
|
||||
rather than outside the class. This is used for both static member
|
||||
VAR_DECLS, and FUNTION_DECLS that are defined in the class. */
|
||||
@ -2900,7 +2917,8 @@ struct lang_decl GTY(())
|
||||
#define THUNK_ALIAS(DECL) \
|
||||
(DECL_LANG_SPECIFIC (FUNCTION_DECL_CHECK (DECL))->decl_flags.u.thunk_alias)
|
||||
|
||||
/* For thunk NODE, this is the FUNCTION_DECL thunked to. */
|
||||
/* For thunk NODE, this is the FUNCTION_DECL thunked to. It is
|
||||
possible for the target to be a thunk too. */
|
||||
#define THUNK_TARGET(NODE) \
|
||||
(DECL_LANG_SPECIFIC (NODE)->u.f.befriending_classes)
|
||||
|
||||
@ -3711,6 +3729,7 @@ extern tree cp_fname_init (const char *, tree *);
|
||||
extern tree check_elaborated_type_specifier (enum tag_types, tree, bool);
|
||||
extern tree cxx_builtin_type_decls (void);
|
||||
extern void warn_extern_redeclared_static (tree, tree);
|
||||
extern tree check_var_type (tree, tree);
|
||||
|
||||
extern bool have_extern_spec;
|
||||
|
||||
@ -3903,7 +3922,6 @@ extern int is_specialization_of (tree, tree);
|
||||
extern bool is_specialization_of_friend (tree, tree);
|
||||
extern int comp_template_args (tree, tree);
|
||||
extern void maybe_process_partial_specialization (tree);
|
||||
extern void maybe_check_template_type (tree);
|
||||
extern tree most_specialized_instantiation (tree);
|
||||
extern void print_candidates (tree);
|
||||
extern int instantiate_pending_templates (void);
|
||||
@ -3997,6 +4015,7 @@ extern tree adjust_result_of_qualified_name_lookup
|
||||
(tree, tree, tree);
|
||||
extern tree copied_binfo (tree, tree);
|
||||
extern tree original_binfo (tree, tree);
|
||||
extern int shared_member_p (tree);
|
||||
|
||||
/* in semantics.c */
|
||||
extern void push_deferring_access_checks (deferring_kind);
|
||||
@ -4176,6 +4195,7 @@ extern int cp_cannot_inline_tree_fn (tree*);
|
||||
extern tree cp_add_pending_fn_decls (void*,tree);
|
||||
extern int cp_is_overload_p (tree);
|
||||
extern int cp_auto_var_in_fn_p (tree,tree);
|
||||
extern tree fold_if_not_in_template (tree);
|
||||
extern tree cp_copy_res_decl_for_inlining (tree, tree, tree, void*,
|
||||
int*, tree);
|
||||
|
||||
|
@ -793,6 +793,11 @@ convert_to_void (tree expr, const char *implicit)
|
||||
return expr;
|
||||
if (invalid_nonstatic_memfn_p (expr))
|
||||
return error_mark_node;
|
||||
if (TREE_CODE (expr) == PSEUDO_DTOR_EXPR)
|
||||
{
|
||||
error ("pseudo-destructor is not called");
|
||||
return error_mark_node;
|
||||
}
|
||||
if (VOID_TYPE_P (TREE_TYPE (expr)))
|
||||
return expr;
|
||||
switch (TREE_CODE (expr))
|
||||
|
@ -177,6 +177,10 @@ pp_cxx_unqualified_id (cxx_pretty_printer *pp, tree t)
|
||||
pp_cxx_template_id (pp, t);
|
||||
break;
|
||||
|
||||
case BASELINK:
|
||||
pp_cxx_unqualified_id (pp, BASELINK_FUNCTIONS (t));
|
||||
break;
|
||||
|
||||
case RECORD_TYPE:
|
||||
case UNION_TYPE:
|
||||
case ENUMERAL_TYPE:
|
||||
|
@ -1203,9 +1203,15 @@ build_anon_union_vars (tree object)
|
||||
void
|
||||
finish_anon_union (tree anon_union_decl)
|
||||
{
|
||||
tree type = TREE_TYPE (anon_union_decl);
|
||||
tree type;
|
||||
tree main_decl;
|
||||
bool public_p = TREE_PUBLIC (anon_union_decl);
|
||||
bool public_p;
|
||||
|
||||
if (anon_union_decl == error_mark_node)
|
||||
return;
|
||||
|
||||
type = TREE_TYPE (anon_union_decl);
|
||||
public_p = TREE_PUBLIC (anon_union_decl);
|
||||
|
||||
/* The VAR_DECL's context is the same as the TYPE's context. */
|
||||
DECL_CONTEXT (anon_union_decl) = DECL_CONTEXT (TYPE_NAME (type));
|
||||
|
@ -815,9 +815,7 @@ dump_decl (tree t, int flags)
|
||||
break;
|
||||
|
||||
case SCOPE_REF:
|
||||
dump_decl (TREE_OPERAND (t, 0), flags & ~TFF_DECL_SPECIFIERS);
|
||||
pp_colon_colon (cxx_pp);
|
||||
dump_decl (TREE_OPERAND (t, 1), flags);
|
||||
pp_expression (cxx_pp, t);
|
||||
break;
|
||||
|
||||
case ARRAY_REF:
|
||||
@ -1489,6 +1487,7 @@ dump_expr (tree t, int flags)
|
||||
case CEIL_DIV_EXPR:
|
||||
case FLOOR_DIV_EXPR:
|
||||
case ROUND_DIV_EXPR:
|
||||
case RDIV_EXPR:
|
||||
dump_binary_op ("/", t, flags);
|
||||
break;
|
||||
|
||||
@ -1736,9 +1735,7 @@ dump_expr (tree t, int flags)
|
||||
break;
|
||||
|
||||
case SCOPE_REF:
|
||||
dump_type (TREE_OPERAND (t, 0), flags);
|
||||
pp_colon_colon (cxx_pp);
|
||||
dump_expr (TREE_OPERAND (t, 1), flags | TFF_EXPR_IN_PARENS);
|
||||
pp_expression (cxx_pp, t);
|
||||
break;
|
||||
|
||||
case CAST_EXPR:
|
||||
@ -2409,6 +2406,9 @@ cp_error_at (const char *msgid, ...)
|
||||
va_end (ap);
|
||||
|
||||
va_start (ap, msgid);
|
||||
diagnostic_set_info (&diagnostic, msgid, &ap,
|
||||
input_location, DK_ERROR);
|
||||
cp_diagnostic_starter (global_dc, &diagnostic);
|
||||
diagnostic_set_info (&diagnostic, msgid, &ap,
|
||||
location_of (here), DK_ERROR);
|
||||
report_diagnostic (&diagnostic);
|
||||
|
@ -167,6 +167,9 @@ lang_specific_driver (int *in_argc, const char *const **in_argv,
|
||||
}
|
||||
saw_speclang = 1;
|
||||
}
|
||||
/* Unrecognized libraries (e.g. -lfoo) may require libstdc++. */
|
||||
else if (strncmp (argv[i], "-l", 2) == 0)
|
||||
library = (library == 0) ? 1 : library;
|
||||
else if (((argv[i][2] == '\0'
|
||||
&& strchr ("bBVDUoeTuIYmLiA", argv[i][1]) != NULL)
|
||||
|| strcmp (argv[i], "-Xlinker") == 0
|
||||
|
@ -217,7 +217,6 @@ build_zero_init (tree type, tree nelts, bool static_storage_p)
|
||||
}
|
||||
else if (TREE_CODE (type) == ARRAY_TYPE)
|
||||
{
|
||||
tree index;
|
||||
tree max_index;
|
||||
tree inits;
|
||||
|
||||
@ -231,14 +230,16 @@ build_zero_init (tree type, tree nelts, bool static_storage_p)
|
||||
/* A zero-sized array, which is accepted as an extension, will
|
||||
have an upper bound of -1. */
|
||||
if (!tree_int_cst_equal (max_index, integer_minus_one_node))
|
||||
for (index = size_zero_node;
|
||||
!tree_int_cst_lt (max_index, index);
|
||||
index = size_binop (PLUS_EXPR, index, size_one_node))
|
||||
inits = tree_cons (index,
|
||||
build_zero_init (TREE_TYPE (type),
|
||||
/*nelts=*/NULL_TREE,
|
||||
static_storage_p),
|
||||
inits);
|
||||
{
|
||||
tree elt_init = build_zero_init (TREE_TYPE (type),
|
||||
/*nelts=*/NULL_TREE,
|
||||
static_storage_p);
|
||||
tree range = build (RANGE_EXPR,
|
||||
sizetype, size_zero_node, max_index);
|
||||
|
||||
inits = tree_cons (range, elt_init, inits);
|
||||
}
|
||||
|
||||
CONSTRUCTOR_ELTS (init) = nreverse (inits);
|
||||
}
|
||||
else if (TREE_CODE (type) == REFERENCE_TYPE)
|
||||
@ -1378,7 +1379,7 @@ build_offset_ref (tree type, tree name, bool address_p)
|
||||
if (TREE_CODE (name) == TEMPLATE_DECL)
|
||||
return name;
|
||||
|
||||
if (processing_template_decl || uses_template_parms (type))
|
||||
if (dependent_type_p (type) || type_dependent_expression_p (name))
|
||||
return build_min_nt (SCOPE_REF, type, name);
|
||||
|
||||
if (TREE_CODE (name) == TEMPLATE_ID_EXPR)
|
||||
@ -1442,6 +1443,7 @@ build_offset_ref (tree type, tree name, bool address_p)
|
||||
return error_mark_node;
|
||||
}
|
||||
|
||||
/* Set up BASEBINFO for member lookup. */
|
||||
decl = maybe_dummy_object (type, &basebinfo);
|
||||
|
||||
if (BASELINK_P (name) || DECL_P (name))
|
||||
@ -1621,21 +1623,23 @@ decl_constant_value (tree decl)
|
||||
TREE_OPERAND (decl, 0), d1, d2);
|
||||
}
|
||||
|
||||
if (DECL_P (decl)
|
||||
&& (/* Enumeration constants are constant. */
|
||||
TREE_CODE (decl) == CONST_DECL
|
||||
/* And so are variables with a 'const' type -- unless they
|
||||
are also 'volatile'. */
|
||||
|| CP_TYPE_CONST_NON_VOLATILE_P (TREE_TYPE (decl)))
|
||||
&& DECL_INITIAL (decl)
|
||||
&& DECL_INITIAL (decl) != error_mark_node
|
||||
/* This is invalid if initial value is not constant.
|
||||
If it has either a function call, a memory reference,
|
||||
or a variable, then re-evaluating it could give different results. */
|
||||
&& TREE_CONSTANT (DECL_INITIAL (decl))
|
||||
/* Check for cases where this is sub-optimal, even though valid. */
|
||||
&& TREE_CODE (DECL_INITIAL (decl)) != CONSTRUCTOR)
|
||||
return DECL_INITIAL (decl);
|
||||
while (DECL_P (decl)
|
||||
&& (/* Enumeration constants are constant. */
|
||||
TREE_CODE (decl) == CONST_DECL
|
||||
/* And so are variables with a 'const' type -- unless they
|
||||
are also 'volatile'. */
|
||||
|| CP_TYPE_CONST_NON_VOLATILE_P (TREE_TYPE (decl)))
|
||||
&& DECL_INITIAL (decl)
|
||||
&& DECL_INITIAL (decl) != error_mark_node
|
||||
/* This is invalid if initial value is not constant. If it
|
||||
has either a function call, a memory reference, or a
|
||||
variable, then re-evaluating it could give different
|
||||
results. */
|
||||
&& TREE_CONSTANT (DECL_INITIAL (decl))
|
||||
/* Check for cases where this is sub-optimal, even though
|
||||
valid. */
|
||||
&& TREE_CODE (DECL_INITIAL (decl)) != CONSTRUCTOR)
|
||||
decl = DECL_INITIAL (decl);
|
||||
return decl;
|
||||
}
|
||||
|
||||
@ -2540,6 +2544,9 @@ build_vec_init (tree base, tree maxindex, tree init, int from_array)
|
||||
tree atype = TREE_TYPE (base);
|
||||
/* The type of an element in the array. */
|
||||
tree type = TREE_TYPE (atype);
|
||||
/* The element type reached after removing all outer array
|
||||
types. */
|
||||
tree inner_elt_type;
|
||||
/* The type of a pointer to an element in the array. */
|
||||
tree ptype;
|
||||
tree stmt_expr;
|
||||
@ -2556,15 +2563,17 @@ build_vec_init (tree base, tree maxindex, tree init, int from_array)
|
||||
if (maxindex == NULL_TREE || maxindex == error_mark_node)
|
||||
return error_mark_node;
|
||||
|
||||
inner_elt_type = strip_array_types (atype);
|
||||
if (init
|
||||
&& (from_array == 2
|
||||
? (!CLASS_TYPE_P (type) || !TYPE_HAS_COMPLEX_ASSIGN_REF (type))
|
||||
? (!CLASS_TYPE_P (inner_elt_type)
|
||||
|| !TYPE_HAS_COMPLEX_ASSIGN_REF (inner_elt_type))
|
||||
: !TYPE_NEEDS_CONSTRUCTING (type))
|
||||
&& ((TREE_CODE (init) == CONSTRUCTOR
|
||||
/* Don't do this if the CONSTRUCTOR might contain something
|
||||
that might throw and require us to clean up. */
|
||||
&& (CONSTRUCTOR_ELTS (init) == NULL_TREE
|
||||
|| ! TYPE_HAS_NONTRIVIAL_DESTRUCTOR (target_type (type))))
|
||||
|| ! TYPE_HAS_NONTRIVIAL_DESTRUCTOR (inner_elt_type)))
|
||||
|| from_array))
|
||||
{
|
||||
/* Do non-default initialization of POD arrays resulting from
|
||||
|
@ -59,6 +59,7 @@
|
||||
#include "toplev.h"
|
||||
#include "varray.h"
|
||||
#include "flags.h"
|
||||
#include "target.h"
|
||||
|
||||
/* Debugging support. */
|
||||
|
||||
@ -1497,12 +1498,24 @@ write_type (tree type)
|
||||
case BOOLEAN_TYPE:
|
||||
case INTEGER_TYPE: /* Includes wchar_t. */
|
||||
case REAL_TYPE:
|
||||
{
|
||||
/* Handle any target-specific fundamental types. */
|
||||
const char *target_mangling
|
||||
= targetm.mangle_fundamental_type (type);
|
||||
|
||||
if (target_mangling)
|
||||
{
|
||||
write_string (target_mangling);
|
||||
return;
|
||||
}
|
||||
|
||||
/* If this is a typedef, TYPE may not be one of
|
||||
the standard builtin type nodes, but an alias of one. Use
|
||||
TYPE_MAIN_VARIANT to get to the underlying builtin type. */
|
||||
write_builtin_type (TYPE_MAIN_VARIANT (type));
|
||||
++is_builtin_type;
|
||||
break;
|
||||
}
|
||||
|
||||
case COMPLEX_TYPE:
|
||||
write_char ('C');
|
||||
|
@ -357,6 +357,10 @@ use_thunk (tree thunk_fndecl, bool emit_p)
|
||||
There's no need to process this thunk again. */
|
||||
return;
|
||||
|
||||
if (DECL_THUNK_P (function))
|
||||
/* The target is itself a thunk, process it now. */
|
||||
use_thunk (function, emit_p);
|
||||
|
||||
/* Thunks are always addressable; they only appear in vtables. */
|
||||
TREE_ADDRESSABLE (thunk_fndecl) = 1;
|
||||
|
||||
@ -583,14 +587,14 @@ do_build_copy_constructor (tree fndecl)
|
||||
|
||||
for (; fields; fields = TREE_CHAIN (fields))
|
||||
{
|
||||
tree init;
|
||||
tree init = parm;
|
||||
tree field = fields;
|
||||
tree expr_type;
|
||||
|
||||
if (TREE_CODE (field) != FIELD_DECL)
|
||||
continue;
|
||||
|
||||
init = parm;
|
||||
expr_type = TREE_TYPE (field);
|
||||
if (DECL_NAME (field))
|
||||
{
|
||||
if (VFIELD_NAME_P (DECL_NAME (field)))
|
||||
@ -600,9 +604,7 @@ do_build_copy_constructor (tree fndecl)
|
||||
if (IDENTIFIER_CLASS_VALUE (DECL_NAME (field)) != field)
|
||||
continue;
|
||||
}
|
||||
else if ((t = TREE_TYPE (field)) != NULL_TREE
|
||||
&& ANON_AGGR_TYPE_P (t)
|
||||
&& TYPE_FIELDS (t) != NULL_TREE)
|
||||
else if (ANON_AGGR_TYPE_P (expr_type) && TYPE_FIELDS (expr_type))
|
||||
/* Just use the field; anonymous types can't have
|
||||
nontrivial copy ctors or assignment ops. */;
|
||||
else
|
||||
@ -613,14 +615,19 @@ do_build_copy_constructor (tree fndecl)
|
||||
the field is "T", then the type will usually be "const
|
||||
T". (There are no cv-qualified variants of reference
|
||||
types.) */
|
||||
expr_type = TREE_TYPE (field);
|
||||
if (TREE_CODE (expr_type) != REFERENCE_TYPE)
|
||||
expr_type = cp_build_qualified_type (expr_type, cvquals);
|
||||
{
|
||||
int quals = cvquals;
|
||||
|
||||
if (DECL_MUTABLE_P (field))
|
||||
quals &= ~TYPE_QUAL_CONST;
|
||||
expr_type = cp_build_qualified_type (expr_type, quals);
|
||||
}
|
||||
|
||||
init = build (COMPONENT_REF, expr_type, init, field);
|
||||
init = build_tree_list (NULL_TREE, init);
|
||||
|
||||
member_init_list
|
||||
= tree_cons (field, init, member_init_list);
|
||||
member_init_list = tree_cons (field, init, member_init_list);
|
||||
}
|
||||
finish_mem_initializers (member_init_list);
|
||||
}
|
||||
@ -675,26 +682,27 @@ do_build_assign_ref (tree fndecl)
|
||||
fields;
|
||||
fields = TREE_CHAIN (fields))
|
||||
{
|
||||
tree comp, init, t;
|
||||
tree comp = current_class_ref;
|
||||
tree init = parm;
|
||||
tree field = fields;
|
||||
tree expr_type;
|
||||
int quals;
|
||||
|
||||
if (TREE_CODE (field) != FIELD_DECL || DECL_ARTIFICIAL (field))
|
||||
continue;
|
||||
|
||||
if (CP_TYPE_CONST_P (TREE_TYPE (field)))
|
||||
expr_type = TREE_TYPE (field);
|
||||
if (CP_TYPE_CONST_P (expr_type))
|
||||
{
|
||||
error ("non-static const member `%#D', can't use default assignment operator", field);
|
||||
continue;
|
||||
}
|
||||
else if (TREE_CODE (TREE_TYPE (field)) == REFERENCE_TYPE)
|
||||
else if (TREE_CODE (expr_type) == REFERENCE_TYPE)
|
||||
{
|
||||
error ("non-static reference member `%#D', can't use default assignment operator", field);
|
||||
continue;
|
||||
}
|
||||
|
||||
comp = current_class_ref;
|
||||
init = parm;
|
||||
|
||||
if (DECL_NAME (field))
|
||||
{
|
||||
if (VFIELD_NAME_P (DECL_NAME (field)))
|
||||
@ -704,24 +712,27 @@ do_build_assign_ref (tree fndecl)
|
||||
if (IDENTIFIER_CLASS_VALUE (DECL_NAME (field)) != field)
|
||||
continue;
|
||||
}
|
||||
else if ((t = TREE_TYPE (field)) != NULL_TREE
|
||||
&& ANON_AGGR_TYPE_P (t)
|
||||
&& TYPE_FIELDS (t) != NULL_TREE)
|
||||
else if (ANON_AGGR_TYPE_P (expr_type) && TYPE_FIELDS (expr_type))
|
||||
/* Just use the field; anonymous types can't have
|
||||
nontrivial copy ctors or assignment ops. */;
|
||||
else
|
||||
continue;
|
||||
|
||||
comp = build (COMPONENT_REF, TREE_TYPE (field), comp, field);
|
||||
init = build (COMPONENT_REF,
|
||||
cp_build_qualified_type (TREE_TYPE (field), cvquals),
|
||||
init, field);
|
||||
|
||||
/* Compute the type of init->field */
|
||||
quals = cvquals;
|
||||
if (DECL_MUTABLE_P (field))
|
||||
quals &= ~TYPE_QUAL_CONST;
|
||||
expr_type = cp_build_qualified_type (expr_type, quals);
|
||||
|
||||
init = build (COMPONENT_REF, expr_type, init, field);
|
||||
|
||||
if (DECL_NAME (field))
|
||||
finish_expr_stmt (build_modify_expr (comp, NOP_EXPR, init));
|
||||
init = build_modify_expr (comp, NOP_EXPR, init);
|
||||
else
|
||||
finish_expr_stmt (build (MODIFY_EXPR, TREE_TYPE (comp), comp,
|
||||
init));
|
||||
init = build (MODIFY_EXPR, TREE_TYPE (comp), comp, init);
|
||||
finish_expr_stmt (init);
|
||||
}
|
||||
}
|
||||
finish_return_stmt (current_class_ref);
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* Definitions for C++ name lookup routines.
|
||||
Copyright (C) 2003, 2004 Free Software Foundation, Inc.
|
||||
Copyright (C) 2003, 2004, 2005 Free Software Foundation, Inc.
|
||||
Contributed by Gabriel Dos Reis <gdr@integrable-solutions.net>
|
||||
|
||||
This file is part of GCC.
|
||||
@ -2018,7 +2018,8 @@ push_overloaded_decl (tree decl, int flags)
|
||||
if (TREE_CODE (tmp) == OVERLOAD && OVL_USED (tmp)
|
||||
&& !(flags & PUSH_USING)
|
||||
&& compparms (TYPE_ARG_TYPES (TREE_TYPE (fn)),
|
||||
TYPE_ARG_TYPES (TREE_TYPE (decl))))
|
||||
TYPE_ARG_TYPES (TREE_TYPE (decl)))
|
||||
&& ! decls_match (fn, decl))
|
||||
error ("`%#D' conflicts with previous using declaration `%#D'",
|
||||
decl, fn);
|
||||
|
||||
@ -2804,6 +2805,7 @@ push_class_level_binding (tree name, tree x)
|
||||
|| TREE_CODE (x) == CONST_DECL
|
||||
|| (TREE_CODE (x) == TYPE_DECL
|
||||
&& !DECL_SELF_REFERENCE_P (x))
|
||||
|| DECL_CLASS_TEMPLATE_P (x)
|
||||
/* A data member of an anonymous union. */
|
||||
|| (TREE_CODE (x) == FIELD_DECL
|
||||
&& DECL_CONTEXT (x) != current_class_type))
|
||||
@ -2968,27 +2970,6 @@ set_namespace_binding (tree name, tree scope, tree val)
|
||||
timevar_pop (TV_NAME_LOOKUP);
|
||||
}
|
||||
|
||||
/* Compute the namespace where a declaration is defined. */
|
||||
|
||||
static tree
|
||||
decl_namespace (tree decl)
|
||||
{
|
||||
timevar_push (TV_NAME_LOOKUP);
|
||||
if (TYPE_P (decl))
|
||||
decl = TYPE_STUB_DECL (decl);
|
||||
while (DECL_CONTEXT (decl))
|
||||
{
|
||||
decl = DECL_CONTEXT (decl);
|
||||
if (TREE_CODE (decl) == NAMESPACE_DECL)
|
||||
POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, decl);
|
||||
if (TYPE_P (decl))
|
||||
decl = TYPE_STUB_DECL (decl);
|
||||
my_friendly_assert (DECL_P (decl), 390);
|
||||
}
|
||||
|
||||
POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, global_namespace);
|
||||
}
|
||||
|
||||
/* Set the context of a declaration to scope. Complain if we are not
|
||||
outside scope. */
|
||||
|
||||
@ -3057,9 +3038,9 @@ current_decl_namespace (void)
|
||||
return TREE_PURPOSE (decl_namespace_list);
|
||||
|
||||
if (current_class_type)
|
||||
result = decl_namespace (TYPE_STUB_DECL (current_class_type));
|
||||
result = decl_namespace_context (current_class_type);
|
||||
else if (current_function_decl)
|
||||
result = decl_namespace (current_function_decl);
|
||||
result = decl_namespace_context (current_function_decl);
|
||||
else
|
||||
result = current_namespace;
|
||||
return result;
|
||||
@ -3187,7 +3168,7 @@ void
|
||||
push_decl_namespace (tree decl)
|
||||
{
|
||||
if (TREE_CODE (decl) != NAMESPACE_DECL)
|
||||
decl = decl_namespace (decl);
|
||||
decl = decl_namespace_context (decl);
|
||||
decl_namespace_list = tree_cons (ORIGINAL_NAMESPACE (decl),
|
||||
NULL_TREE, decl_namespace_list);
|
||||
}
|
||||
@ -3231,6 +3212,9 @@ do_namespace_alias (tree alias, tree namespace)
|
||||
alias = build_lang_decl (NAMESPACE_DECL, alias, void_type_node);
|
||||
DECL_NAMESPACE_ALIAS (alias) = namespace;
|
||||
DECL_EXTERNAL (alias) = 1;
|
||||
DECL_CONTEXT (alias) = current_scope ();
|
||||
if (!DECL_CONTEXT (alias))
|
||||
DECL_CONTEXT (alias) = FROB_CONTEXT (current_namespace);
|
||||
pushdecl (alias);
|
||||
}
|
||||
|
||||
@ -3405,7 +3389,7 @@ parse_using_directive (tree namespace, tree attribs)
|
||||
{
|
||||
if (!toplevel_bindings_p ())
|
||||
error ("strong using only meaningful at namespace scope");
|
||||
else
|
||||
else if (namespace != error_mark_node)
|
||||
DECL_NAMESPACE_ASSOCIATIONS (namespace)
|
||||
= tree_cons (current_namespace, 0,
|
||||
DECL_NAMESPACE_ASSOCIATIONS (namespace));
|
||||
@ -4275,7 +4259,7 @@ arg_assoc_class (struct arg_lookup *k, tree type)
|
||||
return false;
|
||||
k->classes = tree_cons (type, NULL_TREE, k->classes);
|
||||
|
||||
context = decl_namespace (TYPE_MAIN_DECL (type));
|
||||
context = decl_namespace_context (type);
|
||||
if (arg_assoc_namespace (k, context))
|
||||
return true;
|
||||
|
||||
@ -4357,7 +4341,7 @@ arg_assoc_type (struct arg_lookup *k, tree type)
|
||||
return arg_assoc_type (k, TREE_TYPE (type));
|
||||
case UNION_TYPE:
|
||||
case ENUMERAL_TYPE:
|
||||
return arg_assoc_namespace (k, decl_namespace (TYPE_MAIN_DECL (type)));
|
||||
return arg_assoc_namespace (k, decl_namespace_context (type));
|
||||
case METHOD_TYPE:
|
||||
/* The basetype is referenced in the first arg type, so just
|
||||
fall through. */
|
||||
@ -4559,12 +4543,9 @@ maybe_process_template_type_declaration (tree type, int globalize,
|
||||
;
|
||||
else
|
||||
{
|
||||
maybe_check_template_type (type);
|
||||
|
||||
my_friendly_assert (IS_AGGR_TYPE (type)
|
||||
|| TREE_CODE (type) == ENUMERAL_TYPE, 0);
|
||||
|
||||
|
||||
if (processing_template_decl)
|
||||
{
|
||||
/* This may change after the call to
|
||||
|
@ -1,5 +1,6 @@
|
||||
/* C++ Parser.
|
||||
Copyright (C) 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
|
||||
Copyright (C) 2000, 2001, 2002, 2003, 2004,
|
||||
2005 Free Software Foundation, Inc.
|
||||
Written by Mark Mitchell <mark@codesourcery.com>.
|
||||
|
||||
This file is part of GCC.
|
||||
@ -1483,9 +1484,9 @@ static void cp_parser_linkage_specification
|
||||
static tree cp_parser_init_declarator
|
||||
(cp_parser *, tree, tree, bool, bool, int, bool *);
|
||||
static tree cp_parser_declarator
|
||||
(cp_parser *, cp_parser_declarator_kind, int *, bool *);
|
||||
(cp_parser *, cp_parser_declarator_kind, int *, bool *, bool);
|
||||
static tree cp_parser_direct_declarator
|
||||
(cp_parser *, cp_parser_declarator_kind, int *);
|
||||
(cp_parser *, cp_parser_declarator_kind, int *, bool);
|
||||
static enum tree_code cp_parser_ptr_operator
|
||||
(cp_parser *, tree *, tree *);
|
||||
static tree cp_parser_cv_qualifier_seq_opt
|
||||
@ -2701,7 +2702,7 @@ cp_parser_id_expression (cp_parser *parser,
|
||||
/*typename_keyword_p=*/false,
|
||||
check_dependency_p,
|
||||
/*type_p=*/false,
|
||||
/*is_declarator=*/false)
|
||||
declarator_p)
|
||||
!= NULL_TREE);
|
||||
/* If there is a nested-name-specifier, then we are looking at
|
||||
the first qualified-id production. */
|
||||
@ -2850,6 +2851,7 @@ cp_parser_unqualified_id (cp_parser* parser,
|
||||
tree qualifying_scope;
|
||||
tree object_scope;
|
||||
tree scope;
|
||||
bool done;
|
||||
|
||||
/* Consume the `~' token. */
|
||||
cp_lexer_consume_token (parser->lexer);
|
||||
@ -2906,6 +2908,8 @@ cp_parser_unqualified_id (cp_parser* parser,
|
||||
|
||||
/* If there was an explicit qualification (S::~T), first look
|
||||
in the scope given by the qualification (i.e., S). */
|
||||
done = false;
|
||||
type_decl = NULL_TREE;
|
||||
if (scope)
|
||||
{
|
||||
cp_parser_parse_tentatively (parser);
|
||||
@ -2917,10 +2921,10 @@ cp_parser_unqualified_id (cp_parser* parser,
|
||||
/*class_head_p=*/false,
|
||||
declarator_p);
|
||||
if (cp_parser_parse_definitely (parser))
|
||||
return build_nt (BIT_NOT_EXPR, TREE_TYPE (type_decl));
|
||||
done = true;
|
||||
}
|
||||
/* In "N::S::~S", look in "N" as well. */
|
||||
if (scope && qualifying_scope)
|
||||
if (!done && scope && qualifying_scope)
|
||||
{
|
||||
cp_parser_parse_tentatively (parser);
|
||||
parser->scope = qualifying_scope;
|
||||
@ -2935,10 +2939,10 @@ cp_parser_unqualified_id (cp_parser* parser,
|
||||
/*class_head_p=*/false,
|
||||
declarator_p);
|
||||
if (cp_parser_parse_definitely (parser))
|
||||
return build_nt (BIT_NOT_EXPR, TREE_TYPE (type_decl));
|
||||
done = true;
|
||||
}
|
||||
/* In "p->S::~T", look in the scope given by "*p" as well. */
|
||||
else if (object_scope)
|
||||
else if (!done && object_scope)
|
||||
{
|
||||
cp_parser_parse_tentatively (parser);
|
||||
parser->scope = object_scope;
|
||||
@ -2953,20 +2957,23 @@ cp_parser_unqualified_id (cp_parser* parser,
|
||||
/*class_head_p=*/false,
|
||||
declarator_p);
|
||||
if (cp_parser_parse_definitely (parser))
|
||||
return build_nt (BIT_NOT_EXPR, TREE_TYPE (type_decl));
|
||||
done = true;
|
||||
}
|
||||
/* Look in the surrounding context. */
|
||||
parser->scope = NULL_TREE;
|
||||
parser->object_scope = NULL_TREE;
|
||||
parser->qualifying_scope = NULL_TREE;
|
||||
type_decl
|
||||
= cp_parser_class_name (parser,
|
||||
/*typename_keyword_p=*/false,
|
||||
/*template_keyword_p=*/false,
|
||||
/*type_p=*/false,
|
||||
/*check_dependency=*/false,
|
||||
/*class_head_p=*/false,
|
||||
declarator_p);
|
||||
if (!done)
|
||||
{
|
||||
parser->scope = NULL_TREE;
|
||||
parser->object_scope = NULL_TREE;
|
||||
parser->qualifying_scope = NULL_TREE;
|
||||
type_decl
|
||||
= cp_parser_class_name (parser,
|
||||
/*typename_keyword_p=*/false,
|
||||
/*template_keyword_p=*/false,
|
||||
/*type_p=*/false,
|
||||
/*check_dependency=*/false,
|
||||
/*class_head_p=*/false,
|
||||
declarator_p);
|
||||
}
|
||||
/* If an error occurred, assume that the name of the
|
||||
destructor is the same as the name of the qualifying
|
||||
class. That allows us to keep parsing after running
|
||||
@ -3141,6 +3148,16 @@ cp_parser_nested_name_specifier_opt (cp_parser *parser,
|
||||
might destroy it. */
|
||||
old_scope = parser->scope;
|
||||
saved_qualifying_scope = parser->qualifying_scope;
|
||||
/* In a declarator-id like "X<T>::I::Y<T>" we must be able to
|
||||
look up names in "X<T>::I" in order to determine that "Y" is
|
||||
a template. So, if we have a typename at this point, we make
|
||||
an effort to look through it. */
|
||||
if (is_declaration
|
||||
&& !typename_keyword_p
|
||||
&& parser->scope
|
||||
&& TREE_CODE (parser->scope) == TYPENAME_TYPE)
|
||||
parser->scope = resolve_typename_type (parser->scope,
|
||||
/*only_current_p=*/false);
|
||||
/* Parse the qualifying entity. */
|
||||
new_scope
|
||||
= cp_parser_class_or_namespace_name (parser,
|
||||
@ -3534,18 +3551,22 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p)
|
||||
bool template_p = false;
|
||||
tree id;
|
||||
tree type;
|
||||
tree scope;
|
||||
|
||||
/* Consume the `typename' token. */
|
||||
cp_lexer_consume_token (parser->lexer);
|
||||
/* Look for the optional `::' operator. */
|
||||
cp_parser_global_scope_opt (parser,
|
||||
/*current_scope_valid_p=*/false);
|
||||
/* Look for the nested-name-specifier. */
|
||||
cp_parser_nested_name_specifier (parser,
|
||||
/*typename_keyword_p=*/true,
|
||||
/*check_dependency_p=*/true,
|
||||
/*type_p=*/true,
|
||||
/*is_declaration=*/true);
|
||||
/* Look for the nested-name-specifier. In case of error here,
|
||||
consume the trailing id to avoid subsequent error messages
|
||||
for usual cases. */
|
||||
scope = cp_parser_nested_name_specifier (parser,
|
||||
/*typename_keyword_p=*/true,
|
||||
/*check_dependency_p=*/true,
|
||||
/*type_p=*/true,
|
||||
/*is_declaration=*/true);
|
||||
|
||||
/* Look for the optional `template' keyword. */
|
||||
template_p = cp_parser_optional_template_keyword (parser);
|
||||
/* We don't know whether we're looking at a template-id or an
|
||||
@ -3558,9 +3579,13 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p)
|
||||
/* If that didn't work, try an identifier. */
|
||||
if (!cp_parser_parse_definitely (parser))
|
||||
id = cp_parser_identifier (parser);
|
||||
|
||||
/* Don't process id if nested name specifier is invalid. */
|
||||
if (scope == error_mark_node)
|
||||
return error_mark_node;
|
||||
/* If we look up a template-id in a non-dependent qualifying
|
||||
scope, there's no need to create a dependent type. */
|
||||
if (TREE_CODE (id) == TYPE_DECL
|
||||
else if (TREE_CODE (id) == TYPE_DECL
|
||||
&& !dependent_type_p (parser->scope))
|
||||
type = TREE_TYPE (id);
|
||||
/* Create a TYPENAME_TYPE to represent the type to which the
|
||||
@ -3741,20 +3766,36 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p)
|
||||
koenig_p = false;
|
||||
if (idk == CP_ID_KIND_UNQUALIFIED)
|
||||
{
|
||||
if (TREE_CODE (postfix_expression) == IDENTIFIER_NODE)
|
||||
{
|
||||
if (args)
|
||||
{
|
||||
koenig_p = true;
|
||||
postfix_expression
|
||||
= perform_koenig_lookup (postfix_expression, args);
|
||||
}
|
||||
else
|
||||
postfix_expression
|
||||
= unqualified_fn_lookup_error (postfix_expression);
|
||||
}
|
||||
/* We do not perform argument-dependent lookup if
|
||||
normal lookup finds a non-function, in accordance
|
||||
with the expected resolution of DR 218. */
|
||||
if (args
|
||||
&& (is_overloaded_fn (postfix_expression)
|
||||
|| TREE_CODE (postfix_expression) == IDENTIFIER_NODE))
|
||||
else if (args && is_overloaded_fn (postfix_expression))
|
||||
{
|
||||
koenig_p = true;
|
||||
postfix_expression
|
||||
= perform_koenig_lookup (postfix_expression, args);
|
||||
tree fn = get_first_fn (postfix_expression);
|
||||
if (TREE_CODE (fn) == TEMPLATE_ID_EXPR)
|
||||
fn = OVL_CURRENT (TREE_OPERAND (fn, 0));
|
||||
/* Only do argument dependent lookup if regular
|
||||
lookup does not find a set of member functions.
|
||||
[basic.lookup.koenig]/2a */
|
||||
if (!DECL_FUNCTION_MEMBER_P (fn))
|
||||
{
|
||||
koenig_p = true;
|
||||
postfix_expression
|
||||
= perform_koenig_lookup (postfix_expression, args);
|
||||
}
|
||||
}
|
||||
else if (TREE_CODE (postfix_expression) == IDENTIFIER_NODE)
|
||||
postfix_expression
|
||||
= unqualified_fn_lookup_error (postfix_expression);
|
||||
}
|
||||
|
||||
if (TREE_CODE (postfix_expression) == COMPONENT_REF)
|
||||
@ -3820,6 +3861,7 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p)
|
||||
tree name;
|
||||
bool dependent_p;
|
||||
bool template_p;
|
||||
bool pseudo_destructor_p;
|
||||
tree scope = NULL_TREE;
|
||||
enum cpp_ttype token_type = token->type;
|
||||
|
||||
@ -3870,11 +3912,34 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p)
|
||||
|
||||
/* Consume the `.' or `->' operator. */
|
||||
cp_lexer_consume_token (parser->lexer);
|
||||
/* If the SCOPE is not a scalar type, we are looking at an
|
||||
ordinary class member access expression, rather than a
|
||||
pseudo-destructor-name. */
|
||||
if (!scope || !SCALAR_TYPE_P (scope))
|
||||
|
||||
/* Assume this expression is not a pseudo-destructor access. */
|
||||
pseudo_destructor_p = false;
|
||||
|
||||
/* If the SCOPE is a scalar type, then, if this is a valid program,
|
||||
we must be looking at a pseudo-destructor-name. */
|
||||
if (scope && SCALAR_TYPE_P (scope))
|
||||
{
|
||||
tree s = NULL_TREE;
|
||||
tree type;
|
||||
|
||||
cp_parser_parse_tentatively (parser);
|
||||
/* Parse the pseudo-destructor-name. */
|
||||
cp_parser_pseudo_destructor_name (parser, &s, &type);
|
||||
if (cp_parser_parse_definitely (parser))
|
||||
{
|
||||
pseudo_destructor_p = true;
|
||||
postfix_expression
|
||||
= finish_pseudo_destructor_expr (postfix_expression,
|
||||
s, TREE_TYPE (type));
|
||||
}
|
||||
}
|
||||
|
||||
if (!pseudo_destructor_p)
|
||||
{
|
||||
/* If the SCOPE is not a scalar type, we are looking
|
||||
at an ordinary class member access expression,
|
||||
rather than a pseudo-destructor-name. */
|
||||
template_p = cp_parser_optional_template_keyword (parser);
|
||||
/* Parse the id-expression. */
|
||||
name = cp_parser_id_expression (parser,
|
||||
@ -3914,19 +3979,6 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p)
|
||||
postfix_expression
|
||||
= finish_class_member_access_expr (postfix_expression, name);
|
||||
}
|
||||
/* Otherwise, try the pseudo-destructor-name production. */
|
||||
else
|
||||
{
|
||||
tree s = NULL_TREE;
|
||||
tree type;
|
||||
|
||||
/* Parse the pseudo-destructor-name. */
|
||||
cp_parser_pseudo_destructor_name (parser, &s, &type);
|
||||
/* Form the call. */
|
||||
postfix_expression
|
||||
= finish_pseudo_destructor_expr (postfix_expression,
|
||||
s, TREE_TYPE (type));
|
||||
}
|
||||
|
||||
/* We no longer need to look up names in the scope of the
|
||||
object on the left-hand side of the `.' or `->'
|
||||
@ -5811,7 +5863,8 @@ cp_parser_condition (cp_parser* parser)
|
||||
/* Parse the declarator. */
|
||||
declarator = cp_parser_declarator (parser, CP_PARSER_DECLARATOR_NAMED,
|
||||
/*ctor_dtor_or_conv_p=*/NULL,
|
||||
/*parenthesized_p=*/NULL);
|
||||
/*parenthesized_p=*/NULL,
|
||||
/*member_p=*/false);
|
||||
/* Parse the attributes. */
|
||||
attributes = cp_parser_attributes_opt (parser);
|
||||
/* Parse the asm-specification. */
|
||||
@ -7992,6 +8045,13 @@ cp_parser_template_id (cp_parser *parser,
|
||||
token->keyword = RID_MAX;
|
||||
/* Purge all subsequent tokens. */
|
||||
cp_lexer_purge_tokens_after (parser->lexer, token);
|
||||
|
||||
/* ??? Can we actually assume that, if template_id ==
|
||||
error_mark_node, we will have issued a diagnostic to the
|
||||
user, as opposed to simply marking the tentative parse as
|
||||
failed? */
|
||||
if (cp_parser_error_occurred (parser) && template_id != error_mark_node)
|
||||
error ("parse error in template argument list");
|
||||
}
|
||||
|
||||
pop_deferring_access_checks ();
|
||||
@ -8095,6 +8155,7 @@ cp_parser_template_name (cp_parser* parser,
|
||||
if (is_declaration
|
||||
&& !template_keyword_p
|
||||
&& parser->scope && TYPE_P (parser->scope)
|
||||
&& check_dependency_p
|
||||
&& dependent_type_p (parser->scope)
|
||||
/* Do not do this for dtors (or ctors), since they never
|
||||
need the template keyword before their name. */
|
||||
@ -8170,6 +8231,8 @@ cp_parser_template_name (cp_parser* parser,
|
||||
;
|
||||
else
|
||||
{
|
||||
tree fn = NULL_TREE;
|
||||
|
||||
/* The standard does not explicitly indicate whether a name that
|
||||
names a set of overloaded declarations, some of which are
|
||||
templates, is a template-name. However, such a name should
|
||||
@ -8177,14 +8240,11 @@ cp_parser_template_name (cp_parser* parser,
|
||||
template-id for the overloaded templates. */
|
||||
fns = BASELINK_P (decl) ? BASELINK_FUNCTIONS (decl) : decl;
|
||||
if (TREE_CODE (fns) == OVERLOAD)
|
||||
{
|
||||
tree fn;
|
||||
|
||||
for (fn = fns; fn; fn = OVL_NEXT (fn))
|
||||
if (TREE_CODE (OVL_CURRENT (fn)) == TEMPLATE_DECL)
|
||||
break;
|
||||
}
|
||||
else
|
||||
for (fn = fns; fn; fn = OVL_NEXT (fn))
|
||||
if (TREE_CODE (OVL_CURRENT (fn)) == TEMPLATE_DECL)
|
||||
break;
|
||||
|
||||
if (!fn)
|
||||
{
|
||||
/* Otherwise, the name does not name a template. */
|
||||
cp_parser_error (parser, "expected template-name");
|
||||
@ -8548,7 +8608,8 @@ cp_parser_explicit_instantiation (cp_parser* parser)
|
||||
declarator
|
||||
= cp_parser_declarator (parser, CP_PARSER_DECLARATOR_NAMED,
|
||||
/*ctor_dtor_or_conv_p=*/NULL,
|
||||
/*parenthesized_p=*/NULL);
|
||||
/*parenthesized_p=*/NULL,
|
||||
/*member_p=*/false);
|
||||
cp_parser_check_for_definition_in_return_type (declarator,
|
||||
declares_class_or_enum);
|
||||
if (declarator != error_mark_node)
|
||||
@ -8684,21 +8745,40 @@ cp_parser_type_specifier (cp_parser* parser,
|
||||
keyword = token->keyword;
|
||||
switch (keyword)
|
||||
{
|
||||
case RID_ENUM:
|
||||
/* 'enum' [identifier] '{' introduces an enum-specifier;
|
||||
'enum' <anything else> introduces an elaborated-type-specifier. */
|
||||
if (cp_lexer_peek_nth_token (parser->lexer, 2)->type == CPP_OPEN_BRACE
|
||||
|| (cp_lexer_peek_nth_token (parser->lexer, 2)->type == CPP_NAME
|
||||
&& cp_lexer_peek_nth_token (parser->lexer, 3)->type
|
||||
== CPP_OPEN_BRACE))
|
||||
{
|
||||
if (parser->num_template_parameter_lists)
|
||||
{
|
||||
error ("template declaration of `enum'");
|
||||
cp_parser_skip_to_end_of_block_or_statement (parser);
|
||||
type_spec = error_mark_node;
|
||||
}
|
||||
else
|
||||
type_spec = cp_parser_enum_specifier (parser);
|
||||
|
||||
if (declares_class_or_enum)
|
||||
*declares_class_or_enum = 2;
|
||||
return type_spec;
|
||||
}
|
||||
else
|
||||
goto elaborated_type_specifier;
|
||||
|
||||
/* Any of these indicate either a class-specifier, or an
|
||||
elaborated-type-specifier. */
|
||||
case RID_CLASS:
|
||||
case RID_STRUCT:
|
||||
case RID_UNION:
|
||||
case RID_ENUM:
|
||||
/* Parse tentatively so that we can back up if we don't find a
|
||||
class-specifier or enum-specifier. */
|
||||
cp_parser_parse_tentatively (parser);
|
||||
/* Look for the class-specifier or enum-specifier. */
|
||||
if (keyword == RID_ENUM)
|
||||
type_spec = cp_parser_enum_specifier (parser);
|
||||
else
|
||||
type_spec = cp_parser_class_specifier (parser);
|
||||
|
||||
/* Look for the class-specifier. */
|
||||
type_spec = cp_parser_class_specifier (parser);
|
||||
/* If that worked, we're done. */
|
||||
if (cp_parser_parse_definitely (parser))
|
||||
{
|
||||
@ -8710,6 +8790,7 @@ cp_parser_type_specifier (cp_parser* parser,
|
||||
/* Fall through. */
|
||||
|
||||
case RID_TYPENAME:
|
||||
elaborated_type_specifier:
|
||||
/* Look for an elaborated-type-specifier. */
|
||||
type_spec = cp_parser_elaborated_type_specifier (parser,
|
||||
is_friend,
|
||||
@ -9765,25 +9846,18 @@ cp_parser_asm_definition (cp_parser* parser)
|
||||
/* If the next token is `::', there are no outputs, and the
|
||||
next token is the beginning of the inputs. */
|
||||
else if (cp_lexer_next_token_is (parser->lexer, CPP_SCOPE))
|
||||
{
|
||||
/* Consume the `::' token. */
|
||||
cp_lexer_consume_token (parser->lexer);
|
||||
/* The inputs are coming next. */
|
||||
inputs_p = true;
|
||||
}
|
||||
/* The inputs are coming next. */
|
||||
inputs_p = true;
|
||||
|
||||
/* Look for inputs. */
|
||||
if (inputs_p
|
||||
|| cp_lexer_next_token_is (parser->lexer, CPP_COLON))
|
||||
{
|
||||
if (!inputs_p)
|
||||
/* Consume the `:'. */
|
||||
cp_lexer_consume_token (parser->lexer);
|
||||
/* Consume the `:' or `::'. */
|
||||
cp_lexer_consume_token (parser->lexer);
|
||||
/* Parse the output-operands. */
|
||||
if (cp_lexer_next_token_is_not (parser->lexer,
|
||||
CPP_COLON)
|
||||
&& cp_lexer_next_token_is_not (parser->lexer,
|
||||
CPP_SCOPE)
|
||||
&& cp_lexer_next_token_is_not (parser->lexer,
|
||||
CPP_CLOSE_PAREN))
|
||||
inputs = cp_parser_asm_operand_list (parser);
|
||||
@ -9796,9 +9870,8 @@ cp_parser_asm_definition (cp_parser* parser)
|
||||
if (clobbers_p
|
||||
|| cp_lexer_next_token_is (parser->lexer, CPP_COLON))
|
||||
{
|
||||
if (!clobbers_p)
|
||||
/* Consume the `:'. */
|
||||
cp_lexer_consume_token (parser->lexer);
|
||||
/* Consume the `:' or `::'. */
|
||||
cp_lexer_consume_token (parser->lexer);
|
||||
/* Parse the clobbers. */
|
||||
if (cp_lexer_next_token_is_not (parser->lexer,
|
||||
CPP_CLOSE_PAREN))
|
||||
@ -9899,7 +9972,8 @@ cp_parser_init_declarator (cp_parser* parser,
|
||||
declarator
|
||||
= cp_parser_declarator (parser, CP_PARSER_DECLARATOR_NAMED,
|
||||
&ctor_dtor_or_conv_p,
|
||||
/*parenthesized_p=*/NULL);
|
||||
/*parenthesized_p=*/NULL,
|
||||
/*member_p=*/false);
|
||||
/* Gather up the deferred checks. */
|
||||
stop_deferring_access_checks ();
|
||||
|
||||
@ -10182,13 +10256,16 @@ cp_parser_init_declarator (cp_parser* parser,
|
||||
expression, not a declaration.)
|
||||
|
||||
If PARENTHESIZED_P is non-NULL, *PARENTHESIZED_P is set to true iff
|
||||
the declarator is a direct-declarator of the form "(...)". */
|
||||
the declarator is a direct-declarator of the form "(...)".
|
||||
|
||||
MEMBER_P is true iff this declarator is a member-declarator. */
|
||||
|
||||
static tree
|
||||
cp_parser_declarator (cp_parser* parser,
|
||||
cp_parser_declarator_kind dcl_kind,
|
||||
int* ctor_dtor_or_conv_p,
|
||||
bool* parenthesized_p)
|
||||
bool* parenthesized_p,
|
||||
bool member_p)
|
||||
{
|
||||
cp_token *token;
|
||||
tree declarator;
|
||||
@ -10229,7 +10306,8 @@ cp_parser_declarator (cp_parser* parser,
|
||||
/* Parse the dependent declarator. */
|
||||
declarator = cp_parser_declarator (parser, dcl_kind,
|
||||
/*ctor_dtor_or_conv_p=*/NULL,
|
||||
/*parenthesized_p=*/NULL);
|
||||
/*parenthesized_p=*/NULL,
|
||||
/*member_p=*/false);
|
||||
|
||||
/* If we are parsing an abstract-declarator, we must handle the
|
||||
case where the dependent declarator is absent. */
|
||||
@ -10255,7 +10333,8 @@ cp_parser_declarator (cp_parser* parser,
|
||||
*parenthesized_p = cp_lexer_next_token_is (parser->lexer,
|
||||
CPP_OPEN_PAREN);
|
||||
declarator = cp_parser_direct_declarator (parser, dcl_kind,
|
||||
ctor_dtor_or_conv_p);
|
||||
ctor_dtor_or_conv_p,
|
||||
member_p);
|
||||
}
|
||||
|
||||
if (attributes && declarator != error_mark_node)
|
||||
@ -10303,7 +10382,8 @@ cp_parser_declarator (cp_parser* parser,
|
||||
static tree
|
||||
cp_parser_direct_declarator (cp_parser* parser,
|
||||
cp_parser_declarator_kind dcl_kind,
|
||||
int* ctor_dtor_or_conv_p)
|
||||
int* ctor_dtor_or_conv_p,
|
||||
bool member_p)
|
||||
{
|
||||
cp_token *token;
|
||||
tree declarator = NULL_TREE;
|
||||
@ -10362,7 +10442,14 @@ cp_parser_direct_declarator (cp_parser* parser,
|
||||
tree params;
|
||||
unsigned saved_num_template_parameter_lists;
|
||||
|
||||
cp_parser_parse_tentatively (parser);
|
||||
/* In a member-declarator, the only valid interpretation
|
||||
of a parenthesis is the start of a
|
||||
parameter-declaration-clause. (It is invalid to
|
||||
initialize a static data member with a parenthesized
|
||||
initializer; only the "=" form of initialization is
|
||||
permitted.) */
|
||||
if (!member_p)
|
||||
cp_parser_parse_tentatively (parser);
|
||||
|
||||
/* Consume the `('. */
|
||||
cp_lexer_consume_token (parser->lexer);
|
||||
@ -10388,7 +10475,7 @@ cp_parser_direct_declarator (cp_parser* parser,
|
||||
|
||||
/* If all went well, parse the cv-qualifier-seq and the
|
||||
exception-specification. */
|
||||
if (cp_parser_parse_definitely (parser))
|
||||
if (member_p || cp_parser_parse_definitely (parser))
|
||||
{
|
||||
tree cv_qualifiers;
|
||||
tree exception_specification;
|
||||
@ -10436,7 +10523,8 @@ cp_parser_direct_declarator (cp_parser* parser,
|
||||
parser->in_type_id_in_expr_p = true;
|
||||
declarator
|
||||
= cp_parser_declarator (parser, dcl_kind, ctor_dtor_or_conv_p,
|
||||
/*parenthesized_p=*/NULL);
|
||||
/*parenthesized_p=*/NULL,
|
||||
member_p);
|
||||
parser->in_type_id_in_expr_p = saved_in_type_id_in_expr_p;
|
||||
first = false;
|
||||
/* Expect a `)'. */
|
||||
@ -10854,7 +10942,8 @@ cp_parser_type_id (cp_parser* parser)
|
||||
/* Look for the declarator. */
|
||||
abstract_declarator
|
||||
= cp_parser_declarator (parser, CP_PARSER_DECLARATOR_ABSTRACT, NULL,
|
||||
/*parenthesized_p=*/NULL);
|
||||
/*parenthesized_p=*/NULL,
|
||||
/*member_p=*/false);
|
||||
/* Check to see if there really was a declarator. */
|
||||
if (!cp_parser_parse_definitely (parser))
|
||||
abstract_declarator = NULL_TREE;
|
||||
@ -11212,7 +11301,8 @@ cp_parser_parameter_declaration (cp_parser *parser,
|
||||
declarator = cp_parser_declarator (parser,
|
||||
CP_PARSER_DECLARATOR_EITHER,
|
||||
/*ctor_dtor_or_conv_p=*/NULL,
|
||||
parenthesized_p);
|
||||
parenthesized_p,
|
||||
/*member_p=*/false);
|
||||
parser->default_arg_ok_p = saved_default_arg_ok_p;
|
||||
/* After the declarator, allow more attributes. */
|
||||
attributes = chainon (attributes, cp_parser_attributes_opt (parser));
|
||||
@ -11471,18 +11561,52 @@ cp_parser_initializer (cp_parser* parser, bool* is_parenthesized_init,
|
||||
static tree
|
||||
cp_parser_initializer_clause (cp_parser* parser, bool* non_constant_p)
|
||||
{
|
||||
tree initializer;
|
||||
tree initializer = NULL_TREE;
|
||||
|
||||
/* Assume the expression is constant. */
|
||||
*non_constant_p = false;
|
||||
|
||||
/* If it is not a `{', then we are looking at an
|
||||
assignment-expression. */
|
||||
if (cp_lexer_next_token_is_not (parser->lexer, CPP_OPEN_BRACE))
|
||||
{
|
||||
initializer
|
||||
= cp_parser_constant_expression (parser,
|
||||
/*allow_non_constant_p=*/true,
|
||||
non_constant_p);
|
||||
if (!*non_constant_p)
|
||||
initializer = fold_non_dependent_expr (initializer);
|
||||
/* Speed up common initializers (simply a literal). */
|
||||
cp_token* token = cp_lexer_peek_token (parser->lexer);
|
||||
cp_token* token2 = cp_lexer_peek_nth_token (parser->lexer, 2);
|
||||
|
||||
if (token2->type == CPP_COMMA)
|
||||
switch (token->type)
|
||||
{
|
||||
case CPP_CHAR:
|
||||
case CPP_WCHAR:
|
||||
case CPP_NUMBER:
|
||||
token = cp_lexer_consume_token (parser->lexer);
|
||||
initializer = token->value;
|
||||
break;
|
||||
|
||||
case CPP_STRING:
|
||||
case CPP_WSTRING:
|
||||
token = cp_lexer_consume_token (parser->lexer);
|
||||
if (TREE_CHAIN (token->value))
|
||||
initializer = TREE_CHAIN (token->value);
|
||||
else
|
||||
initializer = token->value;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
/* Otherwise, fall back to the generic assignment expression. */
|
||||
if (!initializer)
|
||||
{
|
||||
initializer
|
||||
= cp_parser_constant_expression (parser,
|
||||
/*allow_non_constant_p=*/true,
|
||||
non_constant_p);
|
||||
if (!*non_constant_p)
|
||||
initializer = fold_non_dependent_expr (initializer);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -11742,6 +11866,7 @@ cp_parser_class_specifier (cp_parser* parser)
|
||||
bool nested_name_specifier_p;
|
||||
unsigned saved_num_template_parameter_lists;
|
||||
bool pop_p = false;
|
||||
tree scope = NULL_TREE;
|
||||
|
||||
push_deferring_access_checks (dk_no_deferred);
|
||||
|
||||
@ -11777,7 +11902,10 @@ cp_parser_class_specifier (cp_parser* parser)
|
||||
|
||||
/* Start the class. */
|
||||
if (nested_name_specifier_p)
|
||||
pop_p = push_scope (CP_DECL_CONTEXT (TYPE_MAIN_DECL (type)));
|
||||
{
|
||||
scope = CP_DECL_CONTEXT (TYPE_MAIN_DECL (type));
|
||||
pop_p = push_scope (scope);
|
||||
}
|
||||
type = begin_class_definition (type);
|
||||
if (type == error_mark_node)
|
||||
/* If the type is erroneous, skip the entire body of the class. */
|
||||
@ -11800,7 +11928,7 @@ cp_parser_class_specifier (cp_parser* parser)
|
||||
if (type != error_mark_node)
|
||||
type = finish_struct (type, attributes);
|
||||
if (pop_p)
|
||||
pop_scope (CP_DECL_CONTEXT (TYPE_MAIN_DECL (type)));
|
||||
pop_scope (scope);
|
||||
/* If this class is not itself within the scope of another class,
|
||||
then we need to parse the bodies of all of the queued function
|
||||
definitions. Note that the queued functions defined in a class
|
||||
@ -12071,6 +12199,15 @@ cp_parser_class_head (cp_parser* parser,
|
||||
else if (nested_name_specifier)
|
||||
{
|
||||
tree scope;
|
||||
|
||||
/* Reject typedef-names in class heads. */
|
||||
if (!DECL_IMPLICIT_TYPEDEF_P (type))
|
||||
{
|
||||
error ("invalid class name in declaration of `%D'", type);
|
||||
type = NULL_TREE;
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* Figure out in what scope the declaration is being placed. */
|
||||
scope = current_scope ();
|
||||
if (!scope)
|
||||
@ -12528,7 +12665,8 @@ cp_parser_member_declaration (cp_parser* parser)
|
||||
declarator
|
||||
= cp_parser_declarator (parser, CP_PARSER_DECLARATOR_NAMED,
|
||||
&ctor_dtor_or_conv_p,
|
||||
/*parenthesized_p=*/NULL);
|
||||
/*parenthesized_p=*/NULL,
|
||||
/*member_p=*/true);
|
||||
|
||||
/* If something went wrong parsing the declarator, make sure
|
||||
that we at least consume some tokens. */
|
||||
@ -13144,7 +13282,8 @@ cp_parser_exception_declaration (cp_parser* parser)
|
||||
else
|
||||
declarator = cp_parser_declarator (parser, CP_PARSER_DECLARATOR_EITHER,
|
||||
/*ctor_dtor_or_conv_p=*/NULL,
|
||||
/*parenthesized_p=*/NULL);
|
||||
/*parenthesized_p=*/NULL,
|
||||
/*member_p=*/false);
|
||||
|
||||
/* Restore the saved message. */
|
||||
parser->type_definition_forbidden_message = saved_message;
|
||||
@ -13409,36 +13548,39 @@ cp_parser_attribute_list (cp_parser* parser)
|
||||
/* Look for the identifier. We also allow keywords here; for
|
||||
example `__attribute__ ((const))' is legal. */
|
||||
token = cp_lexer_peek_token (parser->lexer);
|
||||
if (token->type != CPP_NAME
|
||||
&& token->type != CPP_KEYWORD)
|
||||
return error_mark_node;
|
||||
/* Consume the token. */
|
||||
token = cp_lexer_consume_token (parser->lexer);
|
||||
|
||||
/* Save away the identifier that indicates which attribute this is. */
|
||||
identifier = token->value;
|
||||
attribute = build_tree_list (identifier, NULL_TREE);
|
||||
|
||||
/* Peek at the next token. */
|
||||
token = cp_lexer_peek_token (parser->lexer);
|
||||
/* If it's an `(', then parse the attribute arguments. */
|
||||
if (token->type == CPP_OPEN_PAREN)
|
||||
if (token->type == CPP_NAME
|
||||
|| token->type == CPP_KEYWORD)
|
||||
{
|
||||
tree arguments;
|
||||
/* Consume the token. */
|
||||
token = cp_lexer_consume_token (parser->lexer);
|
||||
|
||||
arguments = (cp_parser_parenthesized_expression_list
|
||||
(parser, true, /*non_constant_p=*/NULL));
|
||||
/* Save the identifier and arguments away. */
|
||||
TREE_VALUE (attribute) = arguments;
|
||||
/* Save away the identifier that indicates which attribute
|
||||
this is. */
|
||||
identifier = token->value;
|
||||
attribute = build_tree_list (identifier, NULL_TREE);
|
||||
|
||||
/* Peek at the next token. */
|
||||
token = cp_lexer_peek_token (parser->lexer);
|
||||
/* If it's an `(', then parse the attribute arguments. */
|
||||
if (token->type == CPP_OPEN_PAREN)
|
||||
{
|
||||
tree arguments;
|
||||
|
||||
arguments = (cp_parser_parenthesized_expression_list
|
||||
(parser, true, /*non_constant_p=*/NULL));
|
||||
/* Save the identifier and arguments away. */
|
||||
TREE_VALUE (attribute) = arguments;
|
||||
}
|
||||
|
||||
/* Add this attribute to the list. */
|
||||
TREE_CHAIN (attribute) = attribute_list;
|
||||
attribute_list = attribute;
|
||||
|
||||
/* Now, look for more attributes. */
|
||||
token = cp_lexer_peek_token (parser->lexer);
|
||||
}
|
||||
|
||||
/* Add this attribute to the list. */
|
||||
TREE_CHAIN (attribute) = attribute_list;
|
||||
attribute_list = attribute;
|
||||
|
||||
/* Now, look for more attributes. */
|
||||
token = cp_lexer_peek_token (parser->lexer);
|
||||
/* If the next token isn't a `,', we're done. */
|
||||
/* Now, look for more attributes. If the next token isn't a
|
||||
`,', we're done. */
|
||||
if (token->type != CPP_COMMA)
|
||||
break;
|
||||
|
||||
@ -14728,10 +14870,12 @@ cp_parser_late_parsing_default_args (cp_parser *parser, tree fn)
|
||||
saved_local_variables_forbidden_p = parser->local_variables_forbidden_p;
|
||||
parser->local_variables_forbidden_p = true;
|
||||
/* Parse the assignment-expression. */
|
||||
if (DECL_CLASS_SCOPE_P (fn))
|
||||
if (DECL_FRIEND_CONTEXT (fn))
|
||||
push_nested_class (DECL_FRIEND_CONTEXT (fn));
|
||||
else if (DECL_CLASS_SCOPE_P (fn))
|
||||
push_nested_class (DECL_CONTEXT (fn));
|
||||
TREE_PURPOSE (parameters) = cp_parser_assignment_expression (parser);
|
||||
if (DECL_CLASS_SCOPE_P (fn))
|
||||
if (DECL_FRIEND_CONTEXT (fn) || DECL_CLASS_SCOPE_P (fn))
|
||||
pop_nested_class ();
|
||||
|
||||
/* If the token stream has not been completely used up, then
|
||||
@ -14998,9 +15142,7 @@ cp_parser_next_token_starts_class_definition_p (cp_parser *parser)
|
||||
}
|
||||
|
||||
/* Returns TRUE iff the next token is the "," or ">" ending a
|
||||
template-argument. ">>" is also accepted (after the full
|
||||
argument was parsed) because it's probably a typo for "> >",
|
||||
and there is a specific diagnostic for this. */
|
||||
template-argument. */
|
||||
|
||||
static bool
|
||||
cp_parser_next_token_ends_template_argument_p (cp_parser *parser)
|
||||
@ -15008,8 +15150,7 @@ cp_parser_next_token_ends_template_argument_p (cp_parser *parser)
|
||||
cp_token *token;
|
||||
|
||||
token = cp_lexer_peek_token (parser->lexer);
|
||||
return (token->type == CPP_COMMA || token->type == CPP_GREATER
|
||||
|| token->type == CPP_RSHIFT);
|
||||
return (token->type == CPP_COMMA || token->type == CPP_GREATER);
|
||||
}
|
||||
|
||||
/* Returns TRUE iff the n-th token is a ">", or the n-th is a "[" and the
|
||||
|
@ -1,6 +1,6 @@
|
||||
/* Handle parameterized types (templates) for GNU C++.
|
||||
Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
|
||||
2001, 2002, 2003, 2004 Free Software Foundation, Inc.
|
||||
2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
|
||||
Written by Ken Raeburn (raeburn@cygnus.com) while at Watchmaker Computing.
|
||||
Rewritten by Jason Merrill (jason@cygnus.com).
|
||||
|
||||
@ -180,7 +180,9 @@ push_access_scope (tree t)
|
||||
|| TREE_CODE (t) == VAR_DECL,
|
||||
0);
|
||||
|
||||
if (DECL_CLASS_SCOPE_P (t))
|
||||
if (DECL_FRIEND_CONTEXT (t))
|
||||
push_nested_class (DECL_FRIEND_CONTEXT (t));
|
||||
else if (DECL_CLASS_SCOPE_P (t))
|
||||
push_nested_class (DECL_CONTEXT (t));
|
||||
else
|
||||
push_to_top_level ();
|
||||
@ -205,7 +207,7 @@ pop_access_scope (tree t)
|
||||
saved_access_scope = TREE_CHAIN (saved_access_scope);
|
||||
}
|
||||
|
||||
if (DECL_CLASS_SCOPE_P (t))
|
||||
if (DECL_FRIEND_CONTEXT (t) || DECL_CLASS_SCOPE_P (t))
|
||||
pop_nested_class ();
|
||||
else
|
||||
pop_from_top_level ();
|
||||
@ -706,6 +708,36 @@ end_explicit_instantiation (void)
|
||||
processing_explicit_instantiation = false;
|
||||
}
|
||||
|
||||
/* A explicit specialization or partial specialization TMPL is being
|
||||
declared. Check that the namespace in which the specialization is
|
||||
occurring is permissible. Returns false iff it is invalid to
|
||||
specialize TMPL in the current namespace. */
|
||||
|
||||
static bool
|
||||
check_specialization_namespace (tree tmpl)
|
||||
{
|
||||
tree tpl_ns = decl_namespace_context (tmpl);
|
||||
|
||||
/* [tmpl.expl.spec]
|
||||
|
||||
An explicit specialization shall be declared in the namespace of
|
||||
which the template is a member, or, for member templates, in the
|
||||
namespace of which the enclosing class or enclosing class
|
||||
template is a member. An explicit specialization of a member
|
||||
function, member class or static data member of a class template
|
||||
shall be declared in the namespace of which the class template is
|
||||
a member. */
|
||||
if (is_associated_namespace (current_namespace, tpl_ns))
|
||||
/* Same or super-using namespace. */
|
||||
return true;
|
||||
else
|
||||
{
|
||||
pedwarn ("specialization of `%D' in different namespace", tmpl);
|
||||
cp_pedwarn_at (" from definition of `%#D'", tmpl);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/* The TYPE is being declared. If it is a template type, that means it
|
||||
is a partial specialization. Do appropriate error-checking. */
|
||||
|
||||
@ -731,15 +763,7 @@ maybe_process_partial_specialization (tree type)
|
||||
if (CLASSTYPE_IMPLICIT_INSTANTIATION (type)
|
||||
&& !COMPLETE_TYPE_P (type))
|
||||
{
|
||||
tree tpl_ns = decl_namespace_context (CLASSTYPE_TI_TEMPLATE (type));
|
||||
if (is_associated_namespace (current_namespace, tpl_ns))
|
||||
/* Same or super-using namespace. */;
|
||||
else
|
||||
{
|
||||
pedwarn ("specializing `%#T' in different namespace", type);
|
||||
cp_pedwarn_at (" from definition of `%#D'",
|
||||
CLASSTYPE_TI_TEMPLATE (type));
|
||||
}
|
||||
check_specialization_namespace (CLASSTYPE_TI_TEMPLATE (type));
|
||||
SET_CLASSTYPE_TEMPLATE_SPECIALIZATION (type);
|
||||
if (processing_template_decl)
|
||||
push_template_decl (TYPE_MAIN_DECL (type));
|
||||
@ -1114,6 +1138,12 @@ register_specialization (tree spec, tree tmpl, tree args)
|
||||
}
|
||||
}
|
||||
|
||||
/* A specialization must be declared in the same namespace as the
|
||||
template it is specializing. */
|
||||
if (DECL_TEMPLATE_SPECIALIZATION (spec)
|
||||
&& !check_specialization_namespace (tmpl))
|
||||
DECL_CONTEXT (spec) = decl_namespace_context (tmpl);
|
||||
|
||||
DECL_TEMPLATE_SPECIALIZATIONS (tmpl)
|
||||
= tree_cons (args, spec, DECL_TEMPLATE_SPECIALIZATIONS (tmpl));
|
||||
|
||||
@ -1927,6 +1957,10 @@ check_explicit_specialization (tree declarator,
|
||||
DECL_SOURCE_LOCATION (tmpl) = DECL_SOURCE_LOCATION (decl);
|
||||
DECL_SOURCE_LOCATION (DECL_TEMPLATE_RESULT (tmpl))
|
||||
= DECL_SOURCE_LOCATION (decl);
|
||||
/* We want to use the argument list specified in the
|
||||
definition, not in the original declaration. */
|
||||
DECL_ARGUMENTS (DECL_TEMPLATE_RESULT (tmpl))
|
||||
= DECL_ARGUMENTS (decl);
|
||||
}
|
||||
return tmpl;
|
||||
}
|
||||
@ -1963,49 +1997,6 @@ check_explicit_specialization (tree declarator,
|
||||
return decl;
|
||||
}
|
||||
|
||||
/* TYPE is being declared. Verify that the use of template headers
|
||||
and such is reasonable. Issue error messages if not. */
|
||||
|
||||
void
|
||||
maybe_check_template_type (tree type)
|
||||
{
|
||||
if (template_header_count)
|
||||
{
|
||||
/* We are in the scope of some `template <...>' header. */
|
||||
|
||||
int context_depth
|
||||
= template_class_depth_real (TYPE_CONTEXT (type),
|
||||
/*count_specializations=*/1);
|
||||
|
||||
if (template_header_count <= context_depth)
|
||||
/* This is OK; the template headers are for the context. We
|
||||
are actually too lenient here; like
|
||||
check_explicit_specialization we should consider the number
|
||||
of template types included in the actual declaration. For
|
||||
example,
|
||||
|
||||
template <class T> struct S {
|
||||
template <class U> template <class V>
|
||||
struct I {};
|
||||
};
|
||||
|
||||
is invalid, but:
|
||||
|
||||
template <class T> struct S {
|
||||
template <class U> struct I;
|
||||
};
|
||||
|
||||
template <class T> template <class U.
|
||||
struct S<T>::I {};
|
||||
|
||||
is not. */
|
||||
;
|
||||
else if (template_header_count > context_depth + 1)
|
||||
/* There are two many template parameter lists. */
|
||||
error ("too many template parameter lists in declaration of `%T'", type);
|
||||
}
|
||||
}
|
||||
|
||||
/* Returns 1 iff PARMS1 and PARMS2 are identical sets of template
|
||||
parameters. These are represented in the same format used for
|
||||
DECL_TEMPLATE_PARMS. */
|
||||
@ -2815,19 +2806,35 @@ push_template_decl_real (tree decl, int is_friend)
|
||||
else if (TREE_CODE (decl) == TYPE_DECL
|
||||
&& ANON_AGGRNAME_P (DECL_NAME (decl)))
|
||||
error ("template class without a name");
|
||||
else if (TREE_CODE (decl) == FUNCTION_DECL
|
||||
&& DECL_DESTRUCTOR_P (decl))
|
||||
else if (TREE_CODE (decl) == FUNCTION_DECL)
|
||||
{
|
||||
/* [temp.mem]
|
||||
|
||||
A destructor shall not be a member template. */
|
||||
error ("destructor `%D' declared as member template", decl);
|
||||
return error_mark_node;
|
||||
if (DECL_DESTRUCTOR_P (decl))
|
||||
{
|
||||
/* [temp.mem]
|
||||
|
||||
A destructor shall not be a member template. */
|
||||
error ("destructor `%D' declared as member template", decl);
|
||||
return error_mark_node;
|
||||
}
|
||||
if (NEW_DELETE_OPNAME_P (DECL_NAME (decl))
|
||||
&& (!TYPE_ARG_TYPES (TREE_TYPE (decl))
|
||||
|| TYPE_ARG_TYPES (TREE_TYPE (decl)) == void_list_node
|
||||
|| !TREE_CHAIN (TYPE_ARG_TYPES (TREE_TYPE (decl)))
|
||||
|| (TREE_CHAIN (TYPE_ARG_TYPES ((TREE_TYPE (decl))))
|
||||
== void_list_node)))
|
||||
{
|
||||
/* [basic.stc.dynamic.allocation]
|
||||
|
||||
An allocation function can be a function
|
||||
template. ... Template allocation functions shall
|
||||
have two or more parameters. */
|
||||
error ("invalid template declaration of `%D'", decl);
|
||||
return decl;
|
||||
}
|
||||
}
|
||||
else if ((DECL_IMPLICIT_TYPEDEF_P (decl)
|
||||
&& CLASS_TYPE_P (TREE_TYPE (decl)))
|
||||
|| (TREE_CODE (decl) == VAR_DECL && ctx && CLASS_TYPE_P (ctx))
|
||||
|| TREE_CODE (decl) == FUNCTION_DECL)
|
||||
|| (TREE_CODE (decl) == VAR_DECL && ctx && CLASS_TYPE_P (ctx)))
|
||||
/* OK */;
|
||||
else
|
||||
{
|
||||
@ -3199,9 +3206,7 @@ convert_nontype_argument (tree type, tree expr)
|
||||
will not return the initializer. Handle that special case
|
||||
here. */
|
||||
if (expr == const_expr
|
||||
&& TREE_CODE (expr) == VAR_DECL
|
||||
&& DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (expr)
|
||||
&& CP_TYPE_CONST_NON_VOLATILE_P (TREE_TYPE (expr))
|
||||
&& DECL_INTEGRAL_CONSTANT_VAR_P (expr)
|
||||
/* DECL_INITIAL can be NULL if we are processing a
|
||||
variable initialized to an expression involving itself.
|
||||
We know it is initialized to a constant -- but not what
|
||||
@ -5470,14 +5475,28 @@ instantiate_class_template (tree type)
|
||||
tree tag = t;
|
||||
tree name = TYPE_IDENTIFIER (tag);
|
||||
tree newtag;
|
||||
bool class_template_p;
|
||||
|
||||
class_template_p = (TREE_CODE (tag) != ENUMERAL_TYPE
|
||||
&& TYPE_LANG_SPECIFIC (tag)
|
||||
&& CLASSTYPE_IS_TEMPLATE (tag));
|
||||
/* If the member is a class template, then -- even after
|
||||
substituition -- there may be dependent types in the
|
||||
template argument list for the class. We increment
|
||||
PROCESSING_TEMPLATE_DECL so that dependent_type_p, as
|
||||
that function will assume that no types are dependent
|
||||
when outside of a template. */
|
||||
if (class_template_p)
|
||||
++processing_template_decl;
|
||||
newtag = tsubst (tag, args, tf_error, NULL_TREE);
|
||||
if (class_template_p)
|
||||
--processing_template_decl;
|
||||
if (newtag == error_mark_node)
|
||||
continue;
|
||||
|
||||
if (TREE_CODE (newtag) != ENUMERAL_TYPE)
|
||||
{
|
||||
if (TYPE_LANG_SPECIFIC (tag) && CLASSTYPE_IS_TEMPLATE (tag))
|
||||
if (class_template_p)
|
||||
/* Unfortunately, lookup_template_class sets
|
||||
CLASSTYPE_IMPLICIT_INSTANTIATION for a partial
|
||||
instantiation (i.e., for the type of a member
|
||||
@ -5872,6 +5891,9 @@ tsubst_aggr_type (tree t,
|
||||
tree
|
||||
tsubst_default_argument (tree fn, tree type, tree arg)
|
||||
{
|
||||
tree saved_class_ptr = NULL_TREE;
|
||||
tree saved_class_ref = NULL_TREE;
|
||||
|
||||
/* This default argument came from a template. Instantiate the
|
||||
default argument here, not in tsubst. In the case of
|
||||
something like:
|
||||
@ -5889,12 +5911,27 @@ tsubst_default_argument (tree fn, tree type, tree arg)
|
||||
within the scope of FN. Since push_access_scope sets
|
||||
current_function_decl, we must explicitly clear it here. */
|
||||
current_function_decl = NULL_TREE;
|
||||
/* The "this" pointer is not valid in a default argument. */
|
||||
if (cfun)
|
||||
{
|
||||
saved_class_ptr = current_class_ptr;
|
||||
cp_function_chain->x_current_class_ptr = NULL_TREE;
|
||||
saved_class_ref = current_class_ref;
|
||||
cp_function_chain->x_current_class_ref = NULL_TREE;
|
||||
}
|
||||
|
||||
push_deferring_access_checks(dk_no_deferred);
|
||||
arg = tsubst_expr (arg, DECL_TI_ARGS (fn),
|
||||
tf_error | tf_warning, NULL_TREE);
|
||||
pop_deferring_access_checks();
|
||||
|
||||
/* Restore the "this" pointer. */
|
||||
if (cfun)
|
||||
{
|
||||
cp_function_chain->x_current_class_ptr = saved_class_ptr;
|
||||
cp_function_chain->x_current_class_ref = saved_class_ref;
|
||||
}
|
||||
|
||||
pop_access_scope (fn);
|
||||
|
||||
/* Make sure the default argument is reasonable. */
|
||||
@ -6384,6 +6421,7 @@ tsubst_decl (tree t, tree args, tree type, tsubst_flags_t complain)
|
||||
type = complete_type (type);
|
||||
DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (r)
|
||||
= DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (t);
|
||||
type = check_var_type (DECL_NAME (r), type);
|
||||
}
|
||||
else if (DECL_SELF_REFERENCE_P (t))
|
||||
SET_DECL_SELF_REFERENCE_P (r);
|
||||
@ -6424,9 +6462,6 @@ tsubst_decl (tree t, tree args, tree type, tsubst_flags_t complain)
|
||||
register_local_specialization (r, t);
|
||||
|
||||
TREE_CHAIN (r) = NULL_TREE;
|
||||
if (TREE_CODE (r) == VAR_DECL && VOID_TYPE_P (type))
|
||||
cp_error_at ("instantiation of `%D' as type `%T'", r, type);
|
||||
/* Compute the size, alignment, etc. of R. */
|
||||
layout_decl (r, 0);
|
||||
}
|
||||
break;
|
||||
@ -6618,6 +6653,7 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl)
|
||||
|| t == integer_type_node
|
||||
|| t == void_type_node
|
||||
|| t == char_type_node
|
||||
|| t == unknown_type_node
|
||||
|| TREE_CODE (t) == NAMESPACE_DECL)
|
||||
return t;
|
||||
|
||||
@ -7446,7 +7482,16 @@ tsubst_copy (tree t, tree args, tsubst_flags_t complain, tree in_decl)
|
||||
ctx = tsubst_aggr_type (DECL_CONTEXT (t), args, complain, in_decl,
|
||||
/*entering_scope=*/1);
|
||||
if (ctx != DECL_CONTEXT (t))
|
||||
return lookup_field (ctx, DECL_NAME (t), 0, false);
|
||||
{
|
||||
tree r = lookup_field (ctx, DECL_NAME (t), 0, false);
|
||||
if (!r)
|
||||
{
|
||||
if (complain & tf_error)
|
||||
error ("using invalid field `%D'", t);
|
||||
return error_mark_node;
|
||||
}
|
||||
return r;
|
||||
}
|
||||
}
|
||||
return t;
|
||||
|
||||
@ -8381,7 +8426,11 @@ tsubst_copy_and_build (tree t,
|
||||
lookup finds a non-function, in accordance with the
|
||||
expected resolution of DR 218. */
|
||||
if (koenig_p
|
||||
&& (is_overloaded_fn (function)
|
||||
&& ((is_overloaded_fn (function)
|
||||
/* If lookup found a member function, the Koenig lookup is
|
||||
not appropriate, even if an unqualified-name was used
|
||||
to denote the function. */
|
||||
&& !DECL_FUNCTION_MEMBER_P (get_first_fn (function)))
|
||||
|| TREE_CODE (function) == IDENTIFIER_NODE))
|
||||
function = perform_koenig_lookup (function, call_args);
|
||||
|
||||
@ -8471,7 +8520,9 @@ tsubst_copy_and_build (tree t,
|
||||
else
|
||||
member = tsubst_copy (member, args, complain, in_decl);
|
||||
|
||||
if (!CLASS_TYPE_P (TREE_TYPE (object)))
|
||||
if (member == error_mark_node)
|
||||
return error_mark_node;
|
||||
else if (!CLASS_TYPE_P (TREE_TYPE (object)))
|
||||
{
|
||||
if (TREE_CODE (member) == BIT_NOT_EXPR)
|
||||
return finish_pseudo_destructor_expr (object,
|
||||
@ -8497,15 +8548,35 @@ tsubst_copy_and_build (tree t,
|
||||
/*is_type_p=*/false,
|
||||
/*complain=*/false);
|
||||
if (BASELINK_P (member))
|
||||
BASELINK_FUNCTIONS (member)
|
||||
= build_nt (TEMPLATE_ID_EXPR, BASELINK_FUNCTIONS (member),
|
||||
args);
|
||||
{
|
||||
BASELINK_FUNCTIONS (member)
|
||||
= build_nt (TEMPLATE_ID_EXPR, BASELINK_FUNCTIONS (member),
|
||||
args);
|
||||
member = (adjust_result_of_qualified_name_lookup
|
||||
(member, BINFO_TYPE (BASELINK_BINFO (member)),
|
||||
TREE_TYPE (object)));
|
||||
}
|
||||
else
|
||||
{
|
||||
qualified_name_lookup_error (TREE_TYPE (object), tmpl);
|
||||
return error_mark_node;
|
||||
}
|
||||
}
|
||||
else if (TREE_CODE (member) == SCOPE_REF
|
||||
&& !CLASS_TYPE_P (TREE_OPERAND (member, 0))
|
||||
&& TREE_CODE (TREE_OPERAND (member, 0)) != NAMESPACE_DECL)
|
||||
{
|
||||
if (complain & tf_error)
|
||||
{
|
||||
if (TYPE_P (TREE_OPERAND (member, 0)))
|
||||
error ("`%T' is not a class or namespace",
|
||||
TREE_OPERAND (member, 0));
|
||||
else
|
||||
error ("`%D' is not a class or namespace",
|
||||
TREE_OPERAND (member, 0));
|
||||
}
|
||||
return error_mark_node;
|
||||
}
|
||||
else if (TREE_CODE (member) == FIELD_DECL)
|
||||
return finish_non_static_data_member (member, object, NULL_TREE);
|
||||
|
||||
@ -8574,6 +8645,14 @@ tsubst_copy_and_build (tree t,
|
||||
tsubst_copy (TREE_TYPE (t), args, complain,
|
||||
in_decl));
|
||||
|
||||
case CONST_DECL:
|
||||
t = tsubst_copy (t, args, complain, in_decl);
|
||||
/* As in finish_id_expression, we resolve enumeration constants
|
||||
to their underlying values. */
|
||||
if (TREE_CODE (t) == CONST_DECL)
|
||||
return DECL_INITIAL (t);
|
||||
return t;
|
||||
|
||||
default:
|
||||
return tsubst_copy (t, args, complain, in_decl);
|
||||
}
|
||||
@ -8813,6 +8892,9 @@ fn_type_unification (tree fn,
|
||||
tree converted_args;
|
||||
bool incomplete;
|
||||
|
||||
if (explicit_targs == error_mark_node)
|
||||
return 1;
|
||||
|
||||
converted_args
|
||||
= (coerce_template_parms (DECL_INNERMOST_TEMPLATE_PARMS (fn),
|
||||
explicit_targs, NULL_TREE, tf_none,
|
||||
@ -9833,7 +9915,10 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict)
|
||||
else if ((strict & UNIFY_ALLOW_INTEGER)
|
||||
&& (TREE_CODE (tparm) == INTEGER_TYPE
|
||||
|| TREE_CODE (tparm) == BOOLEAN_TYPE))
|
||||
/* OK */;
|
||||
/* Convert the ARG to the type of PARM; the deduced non-type
|
||||
template argument must exactly match the types of the
|
||||
corresponding parameter. */
|
||||
arg = fold (build_nop (TREE_TYPE (parm), arg));
|
||||
else if (uses_template_parms (tparm))
|
||||
/* We haven't deduced the type of this parameter yet. Try again
|
||||
later. */
|
||||
@ -9913,6 +9998,7 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict)
|
||||
case VECTOR_TYPE:
|
||||
case INTEGER_TYPE:
|
||||
case BOOLEAN_TYPE:
|
||||
case ENUMERAL_TYPE:
|
||||
case VOID_TYPE:
|
||||
if (TREE_CODE (arg) != TREE_CODE (parm))
|
||||
return 1;
|
||||
@ -10108,10 +10194,8 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict)
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
sorry ("use of `%s' in template type unification",
|
||||
tree_code_name [(int) TREE_CODE (parm)]);
|
||||
|
||||
sorry ("use of `%s' in template type unification",
|
||||
tree_code_name [(int) TREE_CODE (parm)]);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
@ -11927,6 +12011,9 @@ type_dependent_expression_p (tree expression)
|
||||
if (TREE_CODE (expression) == IDENTIFIER_NODE)
|
||||
return false;
|
||||
}
|
||||
/* SCOPE_REF with non-null TREE_TYPE is always non-dependent. */
|
||||
if (TREE_CODE (expression) == SCOPE_REF)
|
||||
return false;
|
||||
|
||||
if (TREE_CODE (expression) == BASELINK)
|
||||
expression = BASELINK_FUNCTIONS (expression);
|
||||
@ -12031,8 +12118,9 @@ dependent_template_p (tree tmpl)
|
||||
if (DECL_TEMPLATE_TEMPLATE_PARM_P (tmpl)
|
||||
|| TREE_CODE (tmpl) == TEMPLATE_TEMPLATE_PARM)
|
||||
return true;
|
||||
/* So are qualified names that have not been looked up. */
|
||||
if (TREE_CODE (tmpl) == SCOPE_REF)
|
||||
/* So arenames that have not been looked up. */
|
||||
if (TREE_CODE (tmpl) == SCOPE_REF
|
||||
|| TREE_CODE (tmpl) == IDENTIFIER_NODE)
|
||||
return true;
|
||||
/* So are member templates of dependent classes. */
|
||||
if (TYPE_P (CP_DECL_CONTEXT (tmpl)))
|
||||
@ -12148,7 +12236,8 @@ build_non_dependent_expr (tree expr)
|
||||
if (TREE_CODE (inner_expr) == OVERLOAD
|
||||
|| TREE_CODE (inner_expr) == FUNCTION_DECL
|
||||
|| TREE_CODE (inner_expr) == TEMPLATE_DECL
|
||||
|| TREE_CODE (inner_expr) == TEMPLATE_ID_EXPR)
|
||||
|| TREE_CODE (inner_expr) == TEMPLATE_ID_EXPR
|
||||
|| TREE_CODE (inner_expr) == OFFSET_REF)
|
||||
return expr;
|
||||
/* Preserve string constants; conversions from string constants to
|
||||
"char *" are allowed, even though normally a "const char *"
|
||||
|
@ -78,6 +78,7 @@ struct vbase_info
|
||||
tree inits;
|
||||
};
|
||||
|
||||
static int is_subobject_of_p (tree, tree);
|
||||
static tree dfs_check_overlap (tree, void *);
|
||||
static tree dfs_no_overlap_yet (tree, int, void *);
|
||||
static base_kind lookup_base_r (tree, tree, base_access, bool, tree *);
|
||||
@ -97,7 +98,6 @@ static struct search_level *pop_search_level (struct stack_level *);
|
||||
static tree bfs_walk (tree, tree (*) (tree, void *),
|
||||
tree (*) (tree, int, void *), void *);
|
||||
static tree lookup_field_queue_p (tree, int, void *);
|
||||
static int shared_member_p (tree);
|
||||
static tree lookup_field_r (tree, void *);
|
||||
static tree dfs_accessible_queue_p (tree, int, void *);
|
||||
static tree dfs_accessible_p (tree, void *);
|
||||
@ -891,10 +891,26 @@ friend_accessible_p (tree scope, tree decl, tree binfo)
|
||||
|
||||
/* Or an instantiation of something which is a friend. */
|
||||
if (DECL_TEMPLATE_INFO (scope))
|
||||
return friend_accessible_p (DECL_TI_TEMPLATE (scope), decl, binfo);
|
||||
{
|
||||
int ret;
|
||||
/* Increment processing_template_decl to make sure that
|
||||
dependent_type_p works correctly. */
|
||||
++processing_template_decl;
|
||||
ret = friend_accessible_p (DECL_TI_TEMPLATE (scope), decl, binfo);
|
||||
--processing_template_decl;
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
else if (CLASSTYPE_TEMPLATE_INFO (scope))
|
||||
return friend_accessible_p (CLASSTYPE_TI_TEMPLATE (scope), decl, binfo);
|
||||
{
|
||||
int ret;
|
||||
/* Increment processing_template_decl to make sure that
|
||||
dependent_type_p works correctly. */
|
||||
++processing_template_decl;
|
||||
ret = friend_accessible_p (CLASSTYPE_TI_TEMPLATE (scope), decl, binfo);
|
||||
--processing_template_decl;
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -1058,7 +1074,6 @@ template_self_reference_p (tree type, tree decl)
|
||||
&& DECL_NAME (decl) == constructor_name (type));
|
||||
}
|
||||
|
||||
|
||||
/* Nonzero for a class member means that it is shared between all objects
|
||||
of that class.
|
||||
|
||||
@ -1069,7 +1084,7 @@ template_self_reference_p (tree type, tree decl)
|
||||
|
||||
This function checks that T contains no nonstatic members. */
|
||||
|
||||
static int
|
||||
int
|
||||
shared_member_p (tree t)
|
||||
{
|
||||
if (TREE_CODE (t) == VAR_DECL || TREE_CODE (t) == TYPE_DECL \
|
||||
@ -1088,6 +1103,27 @@ shared_member_p (tree t)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Routine to see if the sub-object denoted by the binfo PARENT can be
|
||||
found as a base class and sub-object of the object denoted by
|
||||
BINFO. */
|
||||
|
||||
static int
|
||||
is_subobject_of_p (tree parent, tree binfo)
|
||||
{
|
||||
tree probe;
|
||||
|
||||
for (probe = parent; probe; probe = BINFO_INHERITANCE_CHAIN (probe))
|
||||
{
|
||||
if (probe == binfo)
|
||||
return 1;
|
||||
if (TREE_VIA_VIRTUAL (probe))
|
||||
return (purpose_member (BINFO_TYPE (probe),
|
||||
CLASSTYPE_VBASECLASSES (BINFO_TYPE (binfo)))
|
||||
!= NULL_TREE);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* DATA is really a struct lookup_field_info. Look for a field with
|
||||
the name indicated there in BINFO. If this function returns a
|
||||
non-NULL value it is the result of the lookup. Called from
|
||||
@ -1155,12 +1191,14 @@ lookup_field_r (tree binfo, void *data)
|
||||
|
||||
/* If the lookup already found a match, and the new value doesn't
|
||||
hide the old one, we might have an ambiguity. */
|
||||
if (lfi->rval_binfo && !original_binfo (lfi->rval_binfo, binfo))
|
||||
if (lfi->rval_binfo
|
||||
&& !is_subobject_of_p (lfi->rval_binfo, binfo))
|
||||
|
||||
{
|
||||
if (nval == lfi->rval && shared_member_p (nval))
|
||||
/* The two things are really the same. */
|
||||
;
|
||||
else if (original_binfo (binfo, lfi->rval_binfo))
|
||||
else if (is_subobject_of_p (binfo, lfi->rval_binfo))
|
||||
/* The previous value hides the new one. */
|
||||
;
|
||||
else
|
||||
|
@ -4,7 +4,7 @@
|
||||
and during the instantiation of template functions.
|
||||
|
||||
Copyright (C) 1998, 1999, 2000, 2001, 2002,
|
||||
2003, 2004 Free Software Foundation, Inc.
|
||||
2003, 2004, 2005 Free Software Foundation, Inc.
|
||||
Written by Mark Mitchell (mmitchell@usa.net) based on code found
|
||||
formerly in parse.y and pt.c.
|
||||
|
||||
@ -1388,19 +1388,16 @@ finish_qualified_id_expr (tree qualifying_class, tree expr, bool done,
|
||||
qualifying_class);
|
||||
else if (BASELINK_P (expr) && !processing_template_decl)
|
||||
{
|
||||
tree fn;
|
||||
tree fns;
|
||||
|
||||
/* See if any of the functions are non-static members. */
|
||||
fns = BASELINK_FUNCTIONS (expr);
|
||||
if (TREE_CODE (fns) == TEMPLATE_ID_EXPR)
|
||||
fns = TREE_OPERAND (fns, 0);
|
||||
for (fn = fns; fn; fn = OVL_NEXT (fn))
|
||||
if (DECL_NONSTATIC_MEMBER_FUNCTION_P (fn))
|
||||
break;
|
||||
/* If so, the expression may be relative to the current
|
||||
class. */
|
||||
if (fn && current_class_type
|
||||
if (!shared_member_p (fns)
|
||||
&& current_class_type
|
||||
&& DERIVED_FROM_P (qualifying_class, current_class_type))
|
||||
expr = (build_class_member_access_expr
|
||||
(maybe_dummy_object (qualifying_class, NULL),
|
||||
@ -1446,6 +1443,9 @@ finish_stmt_expr_expr (tree expr)
|
||||
tree result = NULL_TREE;
|
||||
tree type = void_type_node;
|
||||
|
||||
if (error_operand_p (expr))
|
||||
return error_mark_node;
|
||||
|
||||
if (expr)
|
||||
{
|
||||
type = TREE_TYPE (expr);
|
||||
@ -2561,31 +2561,35 @@ finish_id_expression (tree id_expression,
|
||||
if (TREE_CODE (decl) == VAR_DECL
|
||||
|| TREE_CODE (decl) == PARM_DECL)
|
||||
return decl;
|
||||
/* The same is true for FIELD_DECL, but we also need to
|
||||
make sure that the syntax is correct. */
|
||||
else if (TREE_CODE (decl) == FIELD_DECL)
|
||||
{
|
||||
/* Since SCOPE is NULL here, this is an unqualified name.
|
||||
Access checking has been performed during name lookup
|
||||
already. Turn off checking to avoid duplicate errors. */
|
||||
push_deferring_access_checks (dk_no_check);
|
||||
decl = finish_non_static_data_member
|
||||
(decl, current_class_ref,
|
||||
/*qualifying_scope=*/NULL_TREE);
|
||||
pop_deferring_access_checks ();
|
||||
return decl;
|
||||
}
|
||||
return id_expression;
|
||||
}
|
||||
|
||||
/* Only certain kinds of names are allowed in constant
|
||||
expression. Enumerators and template parameters
|
||||
have already been handled above. */
|
||||
if (integral_constant_expression_p)
|
||||
if (integral_constant_expression_p
|
||||
&& !DECL_INTEGRAL_CONSTANT_VAR_P (decl))
|
||||
{
|
||||
/* Const variables or static data members of integral or
|
||||
enumeration types initialized with constant expressions
|
||||
are OK. */
|
||||
if (TREE_CODE (decl) == VAR_DECL
|
||||
&& CP_TYPE_CONST_P (TREE_TYPE (decl))
|
||||
&& INTEGRAL_OR_ENUMERATION_TYPE_P (TREE_TYPE (decl))
|
||||
&& DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (decl))
|
||||
;
|
||||
else
|
||||
if (!allow_non_integral_constant_expression_p)
|
||||
{
|
||||
if (!allow_non_integral_constant_expression_p)
|
||||
{
|
||||
error ("`%D' cannot appear in a constant-expression", decl);
|
||||
return error_mark_node;
|
||||
}
|
||||
*non_integral_constant_expression_p = true;
|
||||
error ("`%D' cannot appear in a constant-expression", decl);
|
||||
return error_mark_node;
|
||||
}
|
||||
*non_integral_constant_expression_p = true;
|
||||
}
|
||||
|
||||
if (TREE_CODE (decl) == NAMESPACE_DECL)
|
||||
@ -2630,8 +2634,15 @@ finish_id_expression (tree id_expression,
|
||||
decl = build (SCOPE_REF, TREE_TYPE (decl), scope, decl);
|
||||
}
|
||||
else if (TREE_CODE (decl) == FIELD_DECL)
|
||||
decl = finish_non_static_data_member (decl, current_class_ref,
|
||||
/*qualifying_scope=*/NULL_TREE);
|
||||
{
|
||||
/* Since SCOPE is NULL here, this is an unqualified name.
|
||||
Access checking has been performed during name lookup
|
||||
already. Turn off checking to avoid duplicate errors. */
|
||||
push_deferring_access_checks (dk_no_check);
|
||||
decl = finish_non_static_data_member (decl, current_class_ref,
|
||||
/*qualifying_scope=*/NULL_TREE);
|
||||
pop_deferring_access_checks ();
|
||||
}
|
||||
else if (is_overloaded_fn (decl))
|
||||
{
|
||||
tree first_fn = OVL_CURRENT (decl);
|
||||
@ -2643,7 +2654,8 @@ finish_id_expression (tree id_expression,
|
||||
mark_used (first_fn);
|
||||
|
||||
if (TREE_CODE (first_fn) == FUNCTION_DECL
|
||||
&& DECL_FUNCTION_MEMBER_P (first_fn))
|
||||
&& DECL_FUNCTION_MEMBER_P (first_fn)
|
||||
&& !shared_member_p (decl))
|
||||
{
|
||||
/* A set of member functions. */
|
||||
decl = maybe_dummy_object (DECL_CONTEXT (first_fn), 0);
|
||||
@ -2935,18 +2947,6 @@ expand_body (tree fn)
|
||||
|
||||
extract_interface_info ();
|
||||
|
||||
/* If this function is marked with the constructor attribute, add it
|
||||
to the list of functions to be called along with constructors
|
||||
from static duration objects. */
|
||||
if (DECL_STATIC_CONSTRUCTOR (fn))
|
||||
static_ctors = tree_cons (NULL_TREE, fn, static_ctors);
|
||||
|
||||
/* If this function is marked with the destructor attribute, add it
|
||||
to the list of functions to be called along with destructors from
|
||||
static duration objects. */
|
||||
if (DECL_STATIC_DESTRUCTOR (fn))
|
||||
static_dtors = tree_cons (NULL_TREE, fn, static_dtors);
|
||||
|
||||
if (DECL_CLONED_FUNCTION_P (fn))
|
||||
{
|
||||
/* If this is a clone, go through the other clones now and mark
|
||||
@ -3009,6 +3009,18 @@ expand_or_defer_fn (tree fn)
|
||||
if (DECL_DECLARED_INLINE_P (fn))
|
||||
import_export_decl (fn);
|
||||
|
||||
/* If this function is marked with the constructor attribute, add it
|
||||
to the list of functions to be called along with constructors
|
||||
from static duration objects. */
|
||||
if (DECL_STATIC_CONSTRUCTOR (fn))
|
||||
static_ctors = tree_cons (NULL_TREE, fn, static_ctors);
|
||||
|
||||
/* If this function is marked with the destructor attribute, add it
|
||||
to the list of functions to be called along with destructors from
|
||||
static duration objects. */
|
||||
if (DECL_STATIC_DESTRUCTOR (fn))
|
||||
static_dtors = tree_cons (NULL_TREE, fn, static_dtors);
|
||||
|
||||
function_depth++;
|
||||
|
||||
/* Expand or defer, at the whim of the compilation unit manager. */
|
||||
@ -3035,6 +3047,27 @@ nullify_returns_r (tree* tp, int* walk_subtrees, void* data)
|
||||
else if (TREE_CODE (*tp) == CLEANUP_STMT
|
||||
&& CLEANUP_DECL (*tp) == nrv)
|
||||
CLEANUP_EH_ONLY (*tp) = 1;
|
||||
/* Replace the DECL_STMT for the NRV with an initialization of the
|
||||
RESULT_DECL, if needed. */
|
||||
else if (TREE_CODE (*tp) == DECL_STMT
|
||||
&& DECL_STMT_DECL (*tp) == nrv)
|
||||
{
|
||||
tree init;
|
||||
if (DECL_INITIAL (nrv)
|
||||
&& DECL_INITIAL (nrv) != error_mark_node)
|
||||
{
|
||||
init = build (INIT_EXPR, void_type_node,
|
||||
DECL_RESULT (current_function_decl),
|
||||
DECL_INITIAL (nrv));
|
||||
DECL_INITIAL (nrv) = error_mark_node;
|
||||
}
|
||||
else
|
||||
init = NULL_TREE;
|
||||
init = build_stmt (EXPR_STMT, init);
|
||||
TREE_CHAIN (init) = TREE_CHAIN (*tp);
|
||||
STMT_LINENO (init) = STMT_LINENO (*tp);
|
||||
*tp = init;
|
||||
}
|
||||
|
||||
/* Keep iterating. */
|
||||
return NULL_TREE;
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user