+2003-09-04 Nathan Sidwell <nathan@codesourcery.com>
+
+ * cp-tree.h (finish_sizeof, finish_alignof): Remove.
+ (expr_sizeof): Replace with ...
+ (cxx_sizeof_or_alignof_expr): ... here.
+ (cxx_sizeof_or_alignof_type): Make complain parameter a bool.
+ * parser.c (cp_parser_unary_expression): Commonize alignof and
+ sizeof handling.
+ * pt.c (tsubst_copy_and_build): Adjust alignof and sizeof
+ substitution.
+ * semantics.c (finish_sizeof, finish_alignof): Remove.
+ * typeck.c (cxx_sizeof_or_alignof_type): Complain parameter
+ becomes bool. Set TREE_READONLY.
+ (expr_sizeof): Replace with ...
+ (cxx_sizeof_or_alignof_expr): ... here. Clear TREE_SIDE_EFFECTS.
+
2003-09-04 Mark Mitchell <mark@codesourcery.com>
Remove cast-as-lvalue extension.
bool, bool, bool *,
const char **);
extern tree finish_typeof (tree);
-extern tree finish_sizeof (tree);
-extern tree finish_alignof (tree);
extern void finish_decl_cleanup (tree, tree);
extern void finish_eh_cleanup (tree);
extern void expand_body (tree);
extern bool compparms (tree, tree);
extern int comp_cv_qualification (tree, tree);
extern int comp_cv_qual_signature (tree, tree);
-extern tree expr_sizeof (tree);
-extern tree cxx_sizeof_or_alignof_type (tree, enum tree_code, int);
+extern tree cxx_sizeof_or_alignof_expr (tree, enum tree_code);
+extern tree cxx_sizeof_or_alignof_type (tree, enum tree_code, bool);
#define cxx_sizeof_nowarn(T) cxx_sizeof_or_alignof_type (T, SIZEOF_EXPR, false)
extern tree inline_conversion (tree);
extern tree decay_conversion (tree);
switch (keyword)
{
case RID_ALIGNOF:
- {
- /* Consume the `alignof' token. */
- cp_lexer_consume_token (parser->lexer);
- /* Parse the operand. */
- return finish_alignof (cp_parser_sizeof_operand
- (parser, keyword));
- }
-
case RID_SIZEOF:
{
tree operand;
+ enum tree_code op;
- /* Consume the `sizeof' token. */
+ op = keyword == RID_ALIGNOF ? ALIGNOF_EXPR : SIZEOF_EXPR;
+ /* Consume the token. */
cp_lexer_consume_token (parser->lexer);
/* Parse the operand. */
operand = cp_parser_sizeof_operand (parser, keyword);
- /* If the type of the operand cannot be determined build a
- SIZEOF_EXPR. */
- if (TYPE_P (operand)
- ? dependent_type_p (operand)
- : type_dependent_expression_p (operand))
- return build_min (SIZEOF_EXPR, size_type_node, operand);
- /* Otherwise, compute the constant value. */
+ if (TYPE_P (operand))
+ return cxx_sizeof_or_alignof_type (operand, op, true);
else
- return finish_sizeof (operand);
+ return cxx_sizeof_or_alignof_expr (operand, op);
}
case RID_NEW:
op1 = RECUR (op1);
--skip_evaluation;
}
- if (TREE_CODE (t) == SIZEOF_EXPR)
- return finish_sizeof (op1);
+ if (TYPE_P (op1))
+ return cxx_sizeof_or_alignof_type (op1, TREE_CODE (t), true);
else
- return finish_alignof (op1);
+ return cxx_sizeof_or_alignof_expr (op1, TREE_CODE (t));
case MODOP_EXPR:
return build_x_modify_expr
return type;
}
-/* Compute the value of the `sizeof' operator. */
-
-tree
-finish_sizeof (tree t)
-{
- return TYPE_P (t) ? cxx_sizeof (t) : expr_sizeof (t);
-}
-
-/* Implement the __alignof keyword: Return the minimum required
- alignment of T, measured in bytes. */
-
-tree
-finish_alignof (tree t)
-{
- if (processing_template_decl)
- return build_min (ALIGNOF_EXPR, size_type_node, t);
-
- return TYPE_P (t) ? cxx_alignof (t) : c_alignof_expr (t);
-}
-
/* Generate RTL for the statement T, and its substatements, and any
other statements at its nesting level. */
}
\f
+/* Process a sizeof or alignof expression where the operand is a
+ type. */
+
tree
-cxx_sizeof_or_alignof_type (tree type, enum tree_code op, int complain)
+cxx_sizeof_or_alignof_type (tree type, enum tree_code op, bool complain)
{
enum tree_code type_code;
tree value;
const char *op_name;
my_friendly_assert (op == SIZEOF_EXPR || op == ALIGNOF_EXPR, 20020720);
+ if (type == error_mark_node)
+ return error_mark_node;
+
if (processing_template_decl)
- return build_min (op, size_type_node, type);
+ {
+ value = build_min (op, size_type_node, type);
+ TREE_READONLY (value) = 1;
+ return value;
+ }
op_name = operator_name_info[(int) op].name;
return value;
}
+/* Process a sizeof or alignof expression where the operand is an
+ expression. */
+
tree
-expr_sizeof (tree e)
+cxx_sizeof_or_alignof_expr (tree e, enum tree_code op)
{
+ const char *op_name = operator_name_info[(int) op].name;
+
+ if (e == error_mark_node)
+ return error_mark_node;
+
if (processing_template_decl)
- return build_min (SIZEOF_EXPR, size_type_node, e);
-
+ {
+ e = build_min (op, size_type_node, e);
+ TREE_SIDE_EFFECTS (e) = 0;
+ TREE_READONLY (e) = 1;
+
+ return e;
+ }
+
if (TREE_CODE (e) == COMPONENT_REF
&& DECL_C_BIT_FIELD (TREE_OPERAND (e, 1)))
- error ("sizeof applied to a bit-field");
- if (is_overloaded_fn (e))
{
- pedwarn ("ISO C++ forbids applying `sizeof' to an expression of function type");
- return c_sizeof (char_type_node);
+ error ("invalid application of `%s' to a bit-field", op_name);
+ e = char_type_node;
+ }
+ else if (is_overloaded_fn (e))
+ {
+ pedwarn ("ISO C++ forbids applying `%s' to an expression of function type", op_name);
+ e = char_type_node;
}
else if (type_unknown_p (e))
{
cxx_incomplete_type_error (e, TREE_TYPE (e));
- return c_sizeof (char_type_node);
+ e = char_type_node;
}
-
- if (e == error_mark_node)
- return e;
-
- return cxx_sizeof (TREE_TYPE (e));
+ else
+ e = TREE_TYPE (e);
+
+ return cxx_sizeof_or_alignof_type (e, op, true);
}
\f