diff options
-rw-r--r-- | gcc/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/c-common.c | 80 | ||||
-rw-r--r-- | gcc/c-common.h | 8 | ||||
-rw-r--r-- | gcc/c-tree.h | 9 | ||||
-rw-r--r-- | gcc/c-typeck.c | 75 | ||||
-rw-r--r-- | gcc/cp/ChangeLog | 13 | ||||
-rw-r--r-- | gcc/cp/cp-tree.h | 10 | ||||
-rw-r--r-- | gcc/cp/decl2.c | 41 | ||||
-rw-r--r-- | gcc/cp/parse.y | 8 | ||||
-rw-r--r-- | gcc/cp/semantics.c | 28 | ||||
-rw-r--r-- | gcc/cp/tree.c | 7 | ||||
-rw-r--r-- | gcc/cp/typeck.c | 29 |
12 files changed, 147 insertions, 167 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index f58f86e..f033914 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -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> * config/ia64/ia64.c (rws_update): If !pred, set write_count diff --git a/gcc/c-common.c b/gcc/c-common.c index 8fe6e53..84a9262 100644 --- a/gcc/c-common.c +++ b/gcc/c-common.c @@ -2851,7 +2851,87 @@ lang_get_alias_set (t) 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 frontends. */ diff --git a/gcc/c-common.h b/gcc/c-common.h index 2b24560..e93f212 100644 --- a/gcc/c-common.h +++ b/gcc/c-common.h @@ -410,6 +410,11 @@ extern int warn_sequence_point; 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; @@ -522,6 +527,9 @@ extern void set_Wformat PARAMS ((int)); 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)); diff --git a/gcc/c-tree.h b/gcc/c-tree.h index c517545..df3b7fe 100644 --- a/gcc/c-tree.h +++ b/gcc/c-tree.h @@ -218,11 +218,7 @@ extern void c_expand_decl_stmt PARAMS ((tree)); /* 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)); @@ -287,11 +283,6 @@ extern int flag_no_asm; 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; diff --git a/gcc/c-typeck.c b/gcc/c-typeck.c index 9bd0802..ec89e26 100644 --- a/gcc/c-typeck.c +++ b/gcc/c-typeck.c @@ -783,82 +783,7 @@ c_size_in_bytes (type) 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)); -} -/* 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 diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 3038bc2..4a4f80d 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -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> * pt.c (tsubst_expr): Hand off to the TREE_CHAIN of a statement. diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 24027cf..947c932 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -943,11 +943,6 @@ extern int warn_ctor_dtor_privacy; 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. */ @@ -3729,7 +3724,6 @@ extern void grok_x_components PARAMS ((tree)); 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)); @@ -4125,6 +4119,8 @@ extern tree finish_base_specifier 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)); @@ -4243,9 +4239,7 @@ extern int compparms PARAMS ((tree, 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)); diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c index 7be3368..cb84d26 100644 --- a/gcc/cp/decl2.c +++ b/gcc/cp/decl2.c @@ -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 along the way. */ @@ -3858,8 +3822,9 @@ build_expr_from_tree (t) { 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: diff --git a/gcc/cp/parse.y b/gcc/cp/parse.y index 2765375..3b89022 100644 --- a/gcc/cp/parse.y +++ b/gcc/cp/parse.y @@ -1226,14 +1226,14 @@ unary_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 diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c index c295bde..fbfd756 100644 --- a/gcc/cp/semantics.c +++ b/gcc/cp/semantics.c @@ -2165,6 +2165,9 @@ check_multiple_declarators () 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; @@ -2185,6 +2188,31 @@ finish_typeof (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. */ diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c index 40a2d55..f5c6510 100644 --- a/gcc/cp/tree.c +++ b/gcc/cp/tree.c @@ -487,7 +487,8 @@ build_cplus_array_type (elt_type, index_type) 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); @@ -557,9 +558,7 @@ cp_build_qualified_type_real (type, type_quals, complain) 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) diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c index d68e57e..8a84565 100644 --- a/gcc/cp/typeck.c +++ b/gcc/cp/typeck.c @@ -1670,35 +1670,6 @@ c_sizeof_nowarn (type) 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)); -} /* Perform the array-to-pointer and function-to-pointer conversions for EXP. |