* 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
+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>
* config/ia64/ia64.c (rws_update): If !pred, set write_count
return -1;
}
+\f
+/* 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));
+}
+\f
/* Build tree nodes and builtin functions common to both C and C++ language
frontends. */
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. */
extern int flag_traditional;
extern void decl_handle_format_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 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.
NOP_EXPR is used as a special case (see truthvalue_conversion). */
extern void binary_op_error PARAMS ((enum tree_code));
/* in c-typeck.c */
extern tree require_complete_type PARAMS ((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_alignof PARAMS ((tree));
-extern tree c_alignof_expr PARAMS ((tree));
extern tree build_component_ref PARAMS ((tree, tree));
extern tree build_indirect_ref PARAMS ((tree, const char *));
extern tree build_array_ref PARAMS ((tree, tree));
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. */
extern int warn_strict_prototypes;
size_int (TYPE_PRECISION (char_type_node)
/ 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));
-}
\f
-/* 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). */
tree
+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>
* pt.c (tsubst_expr): Hand off to the TREE_CHAIN of a statement.
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
variable or function. */
extern void maybe_retrofit_in_chrg PARAMS ((tree));
extern void maybe_make_one_only PARAMS ((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 delete_sanity PARAMS ((tree, tree, int, int));
extern tree check_classfn PARAMS ((tree, tree));
extern void finish_member_declaration PARAMS ((tree));
extern void check_multiple_declarators PARAMS ((void));
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_named_return_value PARAMS ((tree, tree));
extern void expand_body PARAMS ((tree));
extern int comp_cv_qualification PARAMS ((tree, tree));
extern int comp_cv_qual_signature PARAMS ((tree, tree));
extern tree expr_sizeof PARAMS ((tree));
-extern tree c_sizeof PARAMS ((tree));
extern tree c_sizeof_nowarn PARAMS ((tree));
-extern tree c_alignof PARAMS ((tree));
extern tree inline_conversion PARAMS ((tree));
extern tree decay_conversion PARAMS ((tree));
extern tree build_object_ref PARAMS ((tree, tree, tree));
}
}
-/* 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
along the way. */
{
tree r = build_expr_from_tree (TREE_OPERAND (t, 0));
if (!TYPE_P (r))
- r = TREE_TYPE (r);
- return TREE_CODE (t) == SIZEOF_EXPR ? c_sizeof (r) : c_alignof (r);
+ return TREE_CODE (t) == SIZEOF_EXPR ? expr_sizeof (r) : c_alignof_expr (r);
+ else
+ return TREE_CODE (t) == SIZEOF_EXPR ? c_sizeof (r) : c_alignof (r);
}
case MODOP_EXPR:
| ANDAND identifier
{ $$ = finish_label_address_expr ($2); }
| SIZEOF unary_expr %prec UNARY
- { $$ = expr_sizeof ($2); }
+ { $$ = finish_sizeof ($2); }
| SIZEOF '(' type_id ')' %prec HYPERUNARY
- { $$ = c_sizeof (groktypename ($3.t));
+ { $$ = finish_sizeof (groktypename ($3.t));
check_for_new_type ("sizeof", $3); }
| ALIGNOF unary_expr %prec UNARY
- { $$ = grok_alignof ($2); }
+ { $$ = finish_alignof ($2); }
| ALIGNOF '(' type_id ')' %prec HYPERUNARY
- { $$ = c_alignof (groktypename ($3.t));
+ { $$ = finish_alignof (groktypename ($3.t));
check_for_new_type ("alignof", $3); }
/* The %prec EMPTY's here are required by the = init initializer
cp_error ("multiple declarators in template declaration");
}
+/* Implement the __typeof keyword: Return the type of EXPR, suitable for
+ use as a type-specifier. */
+
tree
finish_typeof (expr)
tree 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
other statements at its nesting level. */
tree t;
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);
return error_mark_node;
/* See if we already have an identically qualified type. */
- for (t = TYPE_MAIN_VARIANT (type); t; t = TYPE_NEXT_VARIANT (t))
- if (CP_TYPE_QUALS (t) == type_quals)
- break;
+ t = get_qualified_type (type, type_quals);
/* If we didn't already have it, create it now. */
if (!t)
20001021);
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));
-}
\f
/* Perform the array-to-pointer and function-to-pointer conversions
for EXP.