c-common.c (c_alignof, [...]): Move here...

* c-common.c (c_alignof, c_alignof_expr): Move here...
        * c-typeck.c: ...from here.
        * c-tree.h, c-common.h: Adjust.

        * tree.c (cp_build_qualified_type_real): Use get_qualified_type.
        (build_cplus_array_type): Use cp_build_qualified_type, not
        TYPE_MAIN_VARIANT, to get an unqualified version.

        * decl2.c (grok_alignof): Lose.
        (build_expr_from_tree): Use expr_sizeof and c_alignof_expr.
        * typeck.c (c_alignof): Lose.
        * semantics.c (finish_sizeof, finish_alignof): New.
        * parse.y: Use them.
        * cp-tree.h: Declare them.

From-SVN: r45145
This commit is contained in:
Jason Merrill 2001-08-24 08:07:46 -04:00 committed by Jason Merrill
parent 2dc8352c90
commit 0213a35528
12 changed files with 147 additions and 167 deletions

View File

@ -1,3 +1,9 @@
2001-08-23 Jason Merrill <jason_merrill@redhat.com>
* c-common.c (c_alignof, c_alignof_expr): Move here...
* c-typeck.c: ...from here.
* c-tree.h, c-common.h: Adjust.
2001-08-23 Bernd Schmidt <bernds@redhat.com> 2001-08-23 Bernd Schmidt <bernds@redhat.com>
* config/ia64/ia64.c (rws_update): If !pred, set write_count * config/ia64/ia64.c (rws_update): If !pred, set write_count

View File

@ -2851,7 +2851,87 @@ lang_get_alias_set (t)
return -1; return -1;
} }
/* Implement the __alignof keyword: Return the minimum required
alignment of TYPE, measured in bytes. */
tree
c_alignof (type)
tree type;
{
enum tree_code code = TREE_CODE (type);
tree t;
/* In C++, sizeof applies to the referent. Handle alignof the same way. */
if (code == REFERENCE_TYPE)
{
type = TREE_TYPE (type);
code = TREE_CODE (type);
}
if (code == FUNCTION_TYPE)
t = size_int (FUNCTION_BOUNDARY / BITS_PER_UNIT);
else if (code == VOID_TYPE || code == ERROR_MARK)
t = size_one_node;
else if (!COMPLETE_TYPE_P (type))
{
error ("__alignof__ applied to an incomplete type");
t = size_zero_node;
}
else
t = size_int (TYPE_ALIGN (type) / BITS_PER_UNIT);
return fold (build1 (NOP_EXPR, c_size_type_node, t));
}
/* Implement the __alignof keyword: Return the minimum required
alignment of EXPR, measured in bytes. For VAR_DECL's and
FIELD_DECL's return DECL_ALIGN (which can be set from an
"aligned" __attribute__ specification). */
tree
c_alignof_expr (expr)
tree expr;
{
tree t;
if (TREE_CODE (expr) == VAR_DECL)
t = size_int (DECL_ALIGN (expr) / BITS_PER_UNIT);
else if (TREE_CODE (expr) == COMPONENT_REF
&& DECL_C_BIT_FIELD (TREE_OPERAND (expr, 1)))
{
error ("`__alignof' applied to a bit-field");
t = size_one_node;
}
else if (TREE_CODE (expr) == COMPONENT_REF
&& TREE_CODE (TREE_OPERAND (expr, 1)) == FIELD_DECL)
t = size_int (DECL_ALIGN (TREE_OPERAND (expr, 1)) / BITS_PER_UNIT);
else if (TREE_CODE (expr) == INDIRECT_REF)
{
tree t = TREE_OPERAND (expr, 0);
tree best = t;
int bestalign = TYPE_ALIGN (TREE_TYPE (TREE_TYPE (t)));
while (TREE_CODE (t) == NOP_EXPR
&& TREE_CODE (TREE_TYPE (TREE_OPERAND (t, 0))) == POINTER_TYPE)
{
int thisalign;
t = TREE_OPERAND (t, 0);
thisalign = TYPE_ALIGN (TREE_TYPE (TREE_TYPE (t)));
if (thisalign > bestalign)
best = t, bestalign = thisalign;
}
return c_alignof (TREE_TYPE (TREE_TYPE (best)));
}
else
return c_alignof (TREE_TYPE (expr));
return fold (build1 (NOP_EXPR, c_size_type_node, t));
}
/* Build tree nodes and builtin functions common to both C and C++ language /* Build tree nodes and builtin functions common to both C and C++ language
frontends. */ frontends. */

View File

@ -410,6 +410,11 @@ extern int warn_sequence_point;
extern int warn_missing_format_attribute; extern int warn_missing_format_attribute;
/* Nonzero means warn about sizeof (function) or addition/subtraction
of function pointers. */
extern int warn_pointer_arith;
/* Nonzero means do some things the same way PCC does. */ /* Nonzero means do some things the same way PCC does. */
extern int flag_traditional; extern int flag_traditional;
@ -522,6 +527,9 @@ extern void set_Wformat PARAMS ((int));
extern void decl_handle_format_attribute PARAMS ((tree, tree)); extern void decl_handle_format_attribute PARAMS ((tree, tree));
extern void decl_handle_format_arg_attribute PARAMS ((tree, tree)); extern void decl_handle_format_arg_attribute PARAMS ((tree, tree));
extern void c_apply_type_quals_to_decl PARAMS ((int, tree)); extern void c_apply_type_quals_to_decl PARAMS ((int, tree));
extern tree c_sizeof PARAMS ((tree));
extern tree c_alignof PARAMS ((tree));
extern tree c_alignof_expr PARAMS ((tree));
/* Print an error message for invalid operands to arith operation CODE. /* Print an error message for invalid operands to arith operation CODE.
NOP_EXPR is used as a special case (see truthvalue_conversion). */ NOP_EXPR is used as a special case (see truthvalue_conversion). */
extern void binary_op_error PARAMS ((enum tree_code)); extern void binary_op_error PARAMS ((enum tree_code));

View File

@ -218,11 +218,7 @@ extern void c_expand_decl_stmt PARAMS ((tree));
/* in c-typeck.c */ /* in c-typeck.c */
extern tree require_complete_type PARAMS ((tree)); extern tree require_complete_type PARAMS ((tree));
extern int comptypes PARAMS ((tree, tree)); extern int comptypes PARAMS ((tree, tree));
extern tree c_sizeof PARAMS ((tree));
extern tree c_sizeof_nowarn PARAMS ((tree));
extern tree c_size_in_bytes PARAMS ((tree)); extern tree c_size_in_bytes PARAMS ((tree));
extern tree c_alignof PARAMS ((tree));
extern tree c_alignof_expr PARAMS ((tree));
extern tree build_component_ref PARAMS ((tree, tree)); extern tree build_component_ref PARAMS ((tree, tree));
extern tree build_indirect_ref PARAMS ((tree, const char *)); extern tree build_indirect_ref PARAMS ((tree, const char *));
extern tree build_array_ref PARAMS ((tree, tree)); extern tree build_array_ref PARAMS ((tree, tree));
@ -287,11 +283,6 @@ extern int flag_no_asm;
extern int warn_implicit; extern int warn_implicit;
/* Nonzero means warn about sizeof (function) or addition/subtraction
of function pointers. */
extern int warn_pointer_arith;
/* Nonzero means warn for all old-style non-prototype function decls. */ /* Nonzero means warn for all old-style non-prototype function decls. */
extern int warn_strict_prototypes; extern int warn_strict_prototypes;

View File

@ -783,82 +783,7 @@ c_size_in_bytes (type)
size_int (TYPE_PRECISION (char_type_node) size_int (TYPE_PRECISION (char_type_node)
/ BITS_PER_UNIT)); / BITS_PER_UNIT));
} }
/* Implement the __alignof keyword: Return the minimum required
alignment of TYPE, measured in bytes. */
tree
c_alignof (type)
tree type;
{
enum tree_code code = TREE_CODE (type);
tree t;
if (code == FUNCTION_TYPE)
t = size_int (FUNCTION_BOUNDARY / BITS_PER_UNIT);
else if (code == VOID_TYPE || code == ERROR_MARK)
t = size_one_node;
else if (code == ERROR_MARK)
t = size_one_node;
else if (!COMPLETE_TYPE_P (type))
{
error ("__alignof__ applied to an incomplete type");
t = size_zero_node;
}
else
t = size_int (TYPE_ALIGN (type) / BITS_PER_UNIT);
return fold (build1 (NOP_EXPR, c_size_type_node, t));
}
/* Implement the __alignof keyword: Return the minimum required
alignment of EXPR, measured in bytes. For VAR_DECL's and
FIELD_DECL's return DECL_ALIGN (which can be set from an
"aligned" __attribute__ specification). */
tree
c_alignof_expr (expr)
tree expr;
{
tree t;
if (TREE_CODE (expr) == VAR_DECL)
t = size_int (DECL_ALIGN (expr) / BITS_PER_UNIT);
else if (TREE_CODE (expr) == COMPONENT_REF
&& DECL_C_BIT_FIELD (TREE_OPERAND (expr, 1)))
{
error ("`__alignof' applied to a bit-field");
t = size_one_node;
}
else if (TREE_CODE (expr) == COMPONENT_REF
&& TREE_CODE (TREE_OPERAND (expr, 1)) == FIELD_DECL)
t = size_int (DECL_ALIGN (TREE_OPERAND (expr, 1)) / BITS_PER_UNIT);
else if (TREE_CODE (expr) == INDIRECT_REF)
{
tree t = TREE_OPERAND (expr, 0);
tree best = t;
int bestalign = TYPE_ALIGN (TREE_TYPE (TREE_TYPE (t)));
while (TREE_CODE (t) == NOP_EXPR
&& TREE_CODE (TREE_TYPE (TREE_OPERAND (t, 0))) == POINTER_TYPE)
{
int thisalign;
t = TREE_OPERAND (t, 0);
thisalign = TYPE_ALIGN (TREE_TYPE (TREE_TYPE (t)));
if (thisalign > bestalign)
best = t, bestalign = thisalign;
}
return c_alignof (TREE_TYPE (TREE_TYPE (best)));
}
else
return c_alignof (TREE_TYPE (expr));
return fold (build1 (NOP_EXPR, c_size_type_node, t));
}
/* Return either DECL or its known constant value (if it has one). */ /* Return either DECL or its known constant value (if it has one). */
tree tree

View File

@ -1,3 +1,16 @@
2001-08-23 Jason Merrill <jason_merrill@redhat.com>
* tree.c (cp_build_qualified_type_real): Use get_qualified_type.
(build_cplus_array_type): Use cp_build_qualified_type, not
TYPE_MAIN_VARIANT, to get an unqualified version.
* decl2.c (grok_alignof): Lose.
(build_expr_from_tree): Use expr_sizeof and c_alignof_expr.
* typeck.c (c_alignof): Lose.
* semantics.c (finish_sizeof, finish_alignof): New.
* parse.y: Use them.
* cp-tree.h: Declare them.
2001-08-22 Jason Merrill <jason_merrill@redhat.com> 2001-08-22 Jason Merrill <jason_merrill@redhat.com>
* pt.c (tsubst_expr): Hand off to the TREE_CHAIN of a statement. * pt.c (tsubst_expr): Hand off to the TREE_CHAIN of a statement.

View File

@ -943,11 +943,6 @@ extern int warn_ctor_dtor_privacy;
extern int warn_write_strings; extern int warn_write_strings;
/* Nonzero means warn about sizeof(function) or addition/subtraction
of function pointers. */
extern int warn_pointer_arith;
/* Nonzero means warn about multiple (redundant) decls for the same single /* Nonzero means warn about multiple (redundant) decls for the same single
variable or function. */ variable or function. */
@ -3729,7 +3724,6 @@ extern void grok_x_components PARAMS ((tree));
extern void maybe_retrofit_in_chrg PARAMS ((tree)); extern void maybe_retrofit_in_chrg PARAMS ((tree));
extern void maybe_make_one_only PARAMS ((tree)); extern void maybe_make_one_only PARAMS ((tree));
extern void grokclassfn PARAMS ((tree, tree, enum overload_flags, tree)); extern void grokclassfn PARAMS ((tree, tree, enum overload_flags, tree));
extern tree grok_alignof PARAMS ((tree));
extern tree grok_array_decl PARAMS ((tree, tree)); extern tree grok_array_decl PARAMS ((tree, tree));
extern tree delete_sanity PARAMS ((tree, tree, int, int)); extern tree delete_sanity PARAMS ((tree, tree, int, int));
extern tree check_classfn PARAMS ((tree, tree)); extern tree check_classfn PARAMS ((tree, tree));
@ -4125,6 +4119,8 @@ extern tree finish_base_specifier PARAMS ((tree, tree));
extern void finish_member_declaration PARAMS ((tree)); extern void finish_member_declaration PARAMS ((tree));
extern void check_multiple_declarators PARAMS ((void)); extern void check_multiple_declarators PARAMS ((void));
extern tree finish_typeof PARAMS ((tree)); extern tree finish_typeof PARAMS ((tree));
extern tree finish_sizeof PARAMS ((tree));
extern tree finish_alignof PARAMS ((tree));
extern void finish_decl_cleanup PARAMS ((tree, tree)); extern void finish_decl_cleanup PARAMS ((tree, tree));
extern void finish_named_return_value PARAMS ((tree, tree)); extern void finish_named_return_value PARAMS ((tree, tree));
extern void expand_body PARAMS ((tree)); extern void expand_body PARAMS ((tree));
@ -4243,9 +4239,7 @@ extern int compparms PARAMS ((tree, tree));
extern int comp_cv_qualification PARAMS ((tree, tree)); extern int comp_cv_qualification PARAMS ((tree, tree));
extern int comp_cv_qual_signature PARAMS ((tree, tree)); extern int comp_cv_qual_signature PARAMS ((tree, tree));
extern tree expr_sizeof PARAMS ((tree)); extern tree expr_sizeof PARAMS ((tree));
extern tree c_sizeof PARAMS ((tree));
extern tree c_sizeof_nowarn PARAMS ((tree)); extern tree c_sizeof_nowarn PARAMS ((tree));
extern tree c_alignof PARAMS ((tree));
extern tree inline_conversion PARAMS ((tree)); extern tree inline_conversion PARAMS ((tree));
extern tree decay_conversion PARAMS ((tree)); extern tree decay_conversion PARAMS ((tree));
extern tree build_object_ref PARAMS ((tree, tree, tree)); extern tree build_object_ref PARAMS ((tree, tree, tree));

View File

@ -1018,42 +1018,6 @@ grokclassfn (ctype, function, flags, quals)
} }
} }
/* Work on the expr used by alignof (this is only called by the parser). */
tree
grok_alignof (expr)
tree expr;
{
tree best, t;
int bestalign;
if (processing_template_decl)
return build_min (ALIGNOF_EXPR, sizetype, expr);
if (TREE_CODE (expr) == COMPONENT_REF
&& DECL_C_BIT_FIELD (TREE_OPERAND (expr, 1)))
error ("`__alignof__' applied to a bit-field");
if (TREE_CODE (expr) == INDIRECT_REF)
{
best = t = TREE_OPERAND (expr, 0);
bestalign = TYPE_ALIGN (TREE_TYPE (TREE_TYPE (t)));
while (TREE_CODE (t) == NOP_EXPR
&& TREE_CODE (TREE_TYPE (TREE_OPERAND (t, 0))) == POINTER_TYPE)
{
int thisalign;
t = TREE_OPERAND (t, 0);
thisalign = TYPE_ALIGN (TREE_TYPE (TREE_TYPE (t)));
if (thisalign > bestalign)
best = t, bestalign = thisalign;
}
return c_alignof (TREE_TYPE (TREE_TYPE (best)));
}
else
return c_alignof (TREE_TYPE (expr));
}
/* Create an ARRAY_REF, checking for the user doing things backwards /* Create an ARRAY_REF, checking for the user doing things backwards
along the way. */ along the way. */
@ -3858,8 +3822,9 @@ build_expr_from_tree (t)
{ {
tree r = build_expr_from_tree (TREE_OPERAND (t, 0)); tree r = build_expr_from_tree (TREE_OPERAND (t, 0));
if (!TYPE_P (r)) if (!TYPE_P (r))
r = TREE_TYPE (r); return TREE_CODE (t) == SIZEOF_EXPR ? expr_sizeof (r) : c_alignof_expr (r);
return TREE_CODE (t) == SIZEOF_EXPR ? c_sizeof (r) : c_alignof (r); else
return TREE_CODE (t) == SIZEOF_EXPR ? c_sizeof (r) : c_alignof (r);
} }
case MODOP_EXPR: case MODOP_EXPR:

View File

@ -1226,14 +1226,14 @@ unary_expr:
| ANDAND identifier | ANDAND identifier
{ $$ = finish_label_address_expr ($2); } { $$ = finish_label_address_expr ($2); }
| SIZEOF unary_expr %prec UNARY | SIZEOF unary_expr %prec UNARY
{ $$ = expr_sizeof ($2); } { $$ = finish_sizeof ($2); }
| SIZEOF '(' type_id ')' %prec HYPERUNARY | SIZEOF '(' type_id ')' %prec HYPERUNARY
{ $$ = c_sizeof (groktypename ($3.t)); { $$ = finish_sizeof (groktypename ($3.t));
check_for_new_type ("sizeof", $3); } check_for_new_type ("sizeof", $3); }
| ALIGNOF unary_expr %prec UNARY | ALIGNOF unary_expr %prec UNARY
{ $$ = grok_alignof ($2); } { $$ = finish_alignof ($2); }
| ALIGNOF '(' type_id ')' %prec HYPERUNARY | ALIGNOF '(' type_id ')' %prec HYPERUNARY
{ $$ = c_alignof (groktypename ($3.t)); { $$ = finish_alignof (groktypename ($3.t));
check_for_new_type ("alignof", $3); } check_for_new_type ("alignof", $3); }
/* The %prec EMPTY's here are required by the = init initializer /* The %prec EMPTY's here are required by the = init initializer

View File

@ -2165,6 +2165,9 @@ check_multiple_declarators ()
cp_error ("multiple declarators in template declaration"); cp_error ("multiple declarators in template declaration");
} }
/* Implement the __typeof keyword: Return the type of EXPR, suitable for
use as a type-specifier. */
tree tree
finish_typeof (expr) finish_typeof (expr)
tree expr; tree expr;
@ -2185,6 +2188,31 @@ finish_typeof (expr)
return TREE_TYPE (expr); return TREE_TYPE (expr);
} }
/* Compute the value of the `sizeof' operator. */
tree
finish_sizeof (t)
tree t;
{
if (processing_template_decl)
return build_min (SIZEOF_EXPR, sizetype, t);
return TYPE_P (t) ? c_sizeof (t) : expr_sizeof (t);
}
/* Implement the __alignof keyword: Return the minimum required
alignment of T, measured in bytes. */
tree
finish_alignof (t)
tree t;
{
if (processing_template_decl)
return build_min (ALIGNOF_EXPR, sizetype, t);
return TYPE_P (t) ? c_alignof (t) : c_alignof_expr (t);
}
/* Generate RTL for the statement T, and its substatements, and any /* Generate RTL for the statement T, and its substatements, and any
other statements at its nesting level. */ other statements at its nesting level. */

View File

@ -487,7 +487,8 @@ build_cplus_array_type (elt_type, index_type)
tree t; tree t;
int type_quals = CP_TYPE_QUALS (elt_type); int type_quals = CP_TYPE_QUALS (elt_type);
elt_type = TYPE_MAIN_VARIANT (elt_type); if (type_quals != TYPE_UNQUALIFIED)
elt_type = cp_build_qualified_type (elt_type, TYPE_UNQUALIFIED);
t = build_cplus_array_type_1 (elt_type, index_type); t = build_cplus_array_type_1 (elt_type, index_type);
@ -557,9 +558,7 @@ cp_build_qualified_type_real (type, type_quals, complain)
return error_mark_node; return error_mark_node;
/* See if we already have an identically qualified type. */ /* See if we already have an identically qualified type. */
for (t = TYPE_MAIN_VARIANT (type); t; t = TYPE_NEXT_VARIANT (t)) t = get_qualified_type (type, type_quals);
if (CP_TYPE_QUALS (t) == type_quals)
break;
/* If we didn't already have it, create it now. */ /* If we didn't already have it, create it now. */
if (!t) if (!t)

View File

@ -1670,35 +1670,6 @@ c_sizeof_nowarn (type)
20001021); 20001021);
return size; return size;
} }
/* Implement the __alignof keyword: Return the minimum required
alignment of TYPE, measured in bytes. */
tree
c_alignof (type)
tree type;
{
enum tree_code code = TREE_CODE (type);
tree t;
if (processing_template_decl)
return build_min (ALIGNOF_EXPR, sizetype, type);
if (code == FUNCTION_TYPE || code == METHOD_TYPE)
t = size_int (FUNCTION_BOUNDARY / BITS_PER_UNIT);
else if (code == VOID_TYPE || code == ERROR_MARK)
t = size_one_node;
else
{
/* Similar to sizeof, __alignof applies to the referant. */
if (code == REFERENCE_TYPE)
type = TREE_TYPE (type);
t = size_int (TYPE_ALIGN (type) / BITS_PER_UNIT);
}
return fold (build1 (NOP_EXPR, c_size_type_node, t));
}
/* Perform the array-to-pointer and function-to-pointer conversions /* Perform the array-to-pointer and function-to-pointer conversions
for EXP. for EXP.