mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-04-15 14:01:04 +08:00
c-typeck.c (build_offsetof): Remove.
* c-typeck.c (build_offsetof): Remove. * c-tree.h (build_offsetof): Remove. * c-common.c (fold_offsetof_1, fold_offsetof): New. * c-common.h (fold_offsetof): Declare. * c-parse.in (offsetof_base): New. (offsetof_member_designator): Use it. Build references, not just a tree list. (primary): Use fold_offsetof, not build_offsetof. From-SVN: r86651
This commit is contained in:
parent
525c6bf5a6
commit
ee8a6a3ee5
@ -1,3 +1,14 @@
|
||||
2004-08-26 Richard Henderson <rth@redhat.com>
|
||||
|
||||
* c-typeck.c (build_offsetof): Remove.
|
||||
* c-tree.h (build_offsetof): Remove.
|
||||
* c-common.c (fold_offsetof_1, fold_offsetof): New.
|
||||
* c-common.h (fold_offsetof): Declare.
|
||||
* c-parse.in (offsetof_base): New.
|
||||
(offsetof_member_designator): Use it. Build references, not just
|
||||
a tree list.
|
||||
(primary): Use fold_offsetof, not build_offsetof.
|
||||
|
||||
2004-08-26 Richard Henderson <rth@redhat.com>
|
||||
|
||||
* tree.c (staticp): Return the static object.
|
||||
|
@ -5436,4 +5436,69 @@ c_warn_unused_result (tree *top_p)
|
||||
}
|
||||
}
|
||||
|
||||
/* Build the result of __builtin_offsetof. EXPR is a nested sequence of
|
||||
component references, with an INDIRECT_REF at the bottom; much like
|
||||
the traditional rendering of offsetof as a macro. Returns the folded
|
||||
and properly cast result. */
|
||||
|
||||
static tree
|
||||
fold_offsetof_1 (tree expr)
|
||||
{
|
||||
enum tree_code code = PLUS_EXPR;
|
||||
tree base, off, t;
|
||||
|
||||
switch (TREE_CODE (expr))
|
||||
{
|
||||
case ERROR_MARK:
|
||||
return expr;
|
||||
|
||||
case INDIRECT_REF:
|
||||
return size_zero_node;
|
||||
|
||||
case COMPONENT_REF:
|
||||
base = fold_offsetof_1 (TREE_OPERAND (expr, 0));
|
||||
if (base == error_mark_node)
|
||||
return base;
|
||||
|
||||
t = TREE_OPERAND (expr, 1);
|
||||
if (DECL_C_BIT_FIELD (t))
|
||||
{
|
||||
error ("attempt to take address of bit-field structure "
|
||||
"member `%s'", IDENTIFIER_POINTER (DECL_NAME (t)));
|
||||
return error_mark_node;
|
||||
}
|
||||
off = size_binop (PLUS_EXPR, DECL_FIELD_OFFSET (t),
|
||||
size_int (tree_low_cst (DECL_FIELD_BIT_OFFSET (t), 1)
|
||||
/ BITS_PER_UNIT));
|
||||
break;
|
||||
|
||||
case ARRAY_REF:
|
||||
base = fold_offsetof_1 (TREE_OPERAND (expr, 0));
|
||||
if (base == error_mark_node)
|
||||
return base;
|
||||
|
||||
t = TREE_OPERAND (expr, 1);
|
||||
if (TREE_CODE (t) == INTEGER_CST && tree_int_cst_sgn (t) < 0)
|
||||
{
|
||||
code = MINUS_EXPR;
|
||||
t = fold (build1 (NEGATE_EXPR, TREE_TYPE (t), t));
|
||||
}
|
||||
t = convert (sizetype, t);
|
||||
off = size_binop (MULT_EXPR, TYPE_SIZE_UNIT (TREE_TYPE (expr)), t);
|
||||
break;
|
||||
|
||||
default:
|
||||
abort ();
|
||||
}
|
||||
|
||||
return size_binop (code, base, off);
|
||||
}
|
||||
|
||||
tree
|
||||
fold_offsetof (tree expr)
|
||||
{
|
||||
/* Convert back from the internal sizetype to size_t. */
|
||||
return convert (size_type_node, fold_offsetof_1 (expr));
|
||||
}
|
||||
|
||||
#include "gt-c-common.h"
|
||||
|
@ -870,6 +870,8 @@ extern void c_warn_unused_result (tree *);
|
||||
|
||||
extern void verify_sequence_points (tree);
|
||||
|
||||
extern tree fold_offsetof (tree);
|
||||
|
||||
/* In c-gimplify.c */
|
||||
extern void c_genericize (tree);
|
||||
extern int c_gimplify_expr (tree *, tree *, tree *);
|
||||
|
@ -275,6 +275,9 @@ static GTY(()) tree all_prefix_attributes;
|
||||
all_prefix_attributes. */
|
||||
static GTY(()) tree declspec_stack;
|
||||
|
||||
/* INDIRECT_REF with a TREE_TYPE of the type being queried for offsetof. */
|
||||
static tree offsetof_base;
|
||||
|
||||
/* PUSH_DECLSPEC_STACK is called from setspecs; POP_DECLSPEC_STACK
|
||||
should be called from the productions making use of setspecs. */
|
||||
#define PUSH_DECLSPEC_STACK \
|
||||
@ -681,8 +684,15 @@ primary:
|
||||
{ $$.value = build_va_arg ($3.value, groktypename ($5));
|
||||
$$.original_code = ERROR_MARK; }
|
||||
|
||||
| OFFSETOF '(' typename ',' offsetof_member_designator ')'
|
||||
{ $$.value = build_offsetof (groktypename ($3), $5);
|
||||
| OFFSETOF '(' typename ','
|
||||
{ tree type = groktypename ($3);
|
||||
if (type == error_mark_node)
|
||||
offsetof_base = error_mark_node;
|
||||
else
|
||||
offsetof_base = build1 (INDIRECT_REF, type, NULL);
|
||||
}
|
||||
offsetof_member_designator ')'
|
||||
{ $$.value = fold_offsetof ($6);
|
||||
$$.original_code = ERROR_MARK; }
|
||||
| OFFSETOF '(' error ')'
|
||||
{ $$.value = error_mark_node; $$.original_code = ERROR_MARK; }
|
||||
@ -753,17 +763,15 @@ primary:
|
||||
|
||||
/* This is the second argument to __builtin_offsetof. We must have one
|
||||
identifier, and beyond that we want to accept sub structure and sub
|
||||
array references. We return tree list where each element has
|
||||
PURPOSE set for component refs or VALUE set for array refs. We'll
|
||||
turn this into something real inside build_offsetof. */
|
||||
array references. */
|
||||
|
||||
offsetof_member_designator:
|
||||
identifier
|
||||
{ $$ = tree_cons ($1, NULL_TREE, NULL_TREE); }
|
||||
{ $$ = build_component_ref (offsetof_base, $1); }
|
||||
| offsetof_member_designator '.' identifier
|
||||
{ $$ = tree_cons ($3, NULL_TREE, $1); }
|
||||
{ $$ = build_component_ref ($1, $3); }
|
||||
| offsetof_member_designator '[' expr ']'
|
||||
{ $$ = tree_cons (NULL_TREE, $3.value, $1); }
|
||||
{ $$ = build_array_ref ($1, $3.value); }
|
||||
;
|
||||
|
||||
old_style_parm_decls:
|
||||
|
@ -277,7 +277,6 @@ extern tree c_finish_return (tree);
|
||||
extern tree c_finish_bc_stmt (tree *, bool);
|
||||
extern tree c_finish_goto_label (tree);
|
||||
extern tree c_finish_goto_ptr (tree);
|
||||
extern tree build_offsetof (tree, tree);
|
||||
|
||||
/* Set to 0 at beginning of a function definition, set to 1 if
|
||||
a return statement that specifies a return value is seen. */
|
||||
|
@ -7583,31 +7583,3 @@ build_binary_op (enum tree_code code, tree orig_op0, tree orig_op1,
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
/* Build the result of __builtin_offsetof. TYPE is the first argument to
|
||||
offsetof, i.e. a type. LIST is a tree_list that encodes component and
|
||||
array references; PURPOSE is set for the former and VALUE is set for
|
||||
the later. */
|
||||
|
||||
tree
|
||||
build_offsetof (tree type, tree list)
|
||||
{
|
||||
tree t;
|
||||
|
||||
/* Build "*(type *)0". */
|
||||
t = convert (build_pointer_type (type), null_pointer_node);
|
||||
t = build_indirect_ref (t, "");
|
||||
|
||||
/* Build COMPONENT and ARRAY_REF expressions as needed. */
|
||||
for (list = nreverse (list); list ; list = TREE_CHAIN (list))
|
||||
if (TREE_PURPOSE (list))
|
||||
t = build_component_ref (t, TREE_PURPOSE (list));
|
||||
else
|
||||
t = build_array_ref (t, TREE_VALUE (list));
|
||||
|
||||
/* Finalize the offsetof expression. For now all we need to do is take
|
||||
the address of the expression we created, and cast that to an integer
|
||||
type; this mirrors the traditional macro implementation of offsetof. */
|
||||
t = build_unary_op (ADDR_EXPR, t, 0);
|
||||
return convert (size_type_node, t);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user