diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 5d70567db7c..29bd60037f5 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,26 @@ +2005-05-27 Roger Sayle + Giovanni Bajo + + * cp-tree.def (UNARY_PLUS_EXPR): New C++ unary tree code. + * parser.c (cp_parser_unary_expression): Use UNARY_PLUS_EXPR instead + of CONVERT_EXPR. + (cp_parser_unary_expression): Likewise. + * typeck.c (build_unary_op): Likewise. + * call.c (add_builtin_candidate, build_new_op): Likewise. + * error.c (dump_expr): Likewise. + * pt.c (tsubst_copy, tsubst_copy_and_build): Likewise. + * decl.c (ambi_op_p, grok_op_properties): Likewise. + * dump.c (dump_op): Likewise. + * lex.c (init_operators): Likewise. + * operators.def ("+"): Likewise. + * cp-gimplify.c (cp_gimplify_expr): Handle UNARY_PLUS_EXPR like a + conversion, if the result and argument types differ. + * tree.c (fold_if_not_in_template): Fold UNARY_PLUS_EXPR much + like a NOP_EXPR when !processing_template_decl. + + * cxx-pretty-print.c (pp_cxx_cast_expression): Prototype. + (pp_cxx_unary_expression): Handle new UNARY_PLUS_EXPR tree code. + 2005-05-27 Nathan Sidwell PR c++/21455 diff --git a/gcc/cp/call.c b/gcc/cp/call.c index e9fdc6fa6c4..01d4046e0bf 100644 --- a/gcc/cp/call.c +++ b/gcc/cp/call.c @@ -1652,7 +1652,7 @@ add_builtin_candidate (struct z_candidate **candidates, enum tree_code code, T operator+(T); T operator-(T); */ - case CONVERT_EXPR: /* unary + */ + case UNARY_PLUS_EXPR: /* unary + */ if (TREE_CODE (type1) == POINTER_TYPE) break; case NEGATE_EXPR: @@ -3848,7 +3848,7 @@ build_new_op (enum tree_code code, int flags, tree arg1, tree arg2, tree arg3, case TRUTH_ORIF_EXPR: return cp_build_binary_op (code, arg1, arg2); - case CONVERT_EXPR: + case UNARY_PLUS_EXPR: case NEGATE_EXPR: case BIT_NOT_EXPR: case TRUTH_NOT_EXPR: diff --git a/gcc/cp/cp-gimplify.c b/gcc/cp/cp-gimplify.c index fc8c1af2d21..4ad30b98008 100644 --- a/gcc/cp/cp-gimplify.c +++ b/gcc/cp/cp-gimplify.c @@ -557,6 +557,16 @@ cp_gimplify_expr (tree *expr_p, tree *pre_p, tree *post_p) ret = GS_OK; break; + case UNARY_PLUS_EXPR: + { + tree arg = TREE_OPERAND (*expr_p, 0); + tree type = TREE_TYPE (*expr_p); + *expr_p = (TREE_TYPE (arg) != type) ? fold_convert (type, arg) + : arg; + ret = GS_OK; + } + break; + default: ret = c_gimplify_expr (expr_p, pre_p, post_p); break; diff --git a/gcc/cp/cp-tree.def b/gcc/cp/cp-tree.def index 705517a2e4a..c42dbfbf7c0 100644 --- a/gcc/cp/cp-tree.def +++ b/gcc/cp/cp-tree.def @@ -340,6 +340,10 @@ DEFTREECODE (ALIGNOF_EXPR, "alignof_expr", tcc_unary, 1) STMT_EXPR_STMT is the statement given by the expression. */ DEFTREECODE (STMT_EXPR, "stmt_expr", tcc_expression, 1) +/* Unary plus. Operand 0 is the expression to which the unary plus + is applied. */ +DEFTREECODE (UNARY_PLUS_EXPR, "unary_plus_expr", tcc_unary, 1) + /* Local variables: mode:c diff --git a/gcc/cp/cxx-pretty-print.c b/gcc/cp/cxx-pretty-print.c index 0ad1e9a4025..afa969f9f71 100644 --- a/gcc/cp/cxx-pretty-print.c +++ b/gcc/cp/cxx-pretty-print.c @@ -43,6 +43,7 @@ static void pp_cxx_parameter_declaration_clause (cxx_pretty_printer *, tree); static void pp_cxx_abstract_declarator (cxx_pretty_printer *, tree); static void pp_cxx_statement (cxx_pretty_printer *, tree); static void pp_cxx_template_parameter (cxx_pretty_printer *, tree); +static void pp_cxx_cast_expression (cxx_pretty_printer *, tree); static inline void @@ -640,6 +641,11 @@ pp_cxx_unary_expression (cxx_pretty_printer *pp, tree t) pp_unary_expression (pp, TREE_OPERAND (t, 0)); break; + case UNARY_PLUS_EXPR: + pp_plus (pp); + pp_cxx_cast_expression (pp, TREE_OPERAND (t, 0)); + break; + default: pp_c_unary_expression (pp_c_base (pp), t); break; diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index d3544172bc4..7f919d5c99b 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -8586,7 +8586,7 @@ ambi_op_p (enum tree_code code) { return (code == INDIRECT_REF || code == ADDR_EXPR - || code == CONVERT_EXPR + || code == UNARY_PLUS_EXPR || code == NEGATE_EXPR || code == PREINCREMENT_EXPR || code == PREDECREMENT_EXPR); @@ -8806,7 +8806,7 @@ grok_op_properties (tree decl, int friendp, bool complain) operator_code = BIT_AND_EXPR; break; - case CONVERT_EXPR: + case UNARY_PLUS_EXPR: operator_code = PLUS_EXPR; break; diff --git a/gcc/cp/dump.c b/gcc/cp/dump.c index 6b93045e02f..daf55952c53 100644 --- a/gcc/cp/dump.c +++ b/gcc/cp/dump.c @@ -65,7 +65,7 @@ dump_op (dump_info_p di, tree t) case VEC_DELETE_EXPR: dump_string (di, "vecdelete"); break; - case CONVERT_EXPR: + case UNARY_PLUS_EXPR: dump_string (di, "pos"); break; case NEGATE_EXPR: diff --git a/gcc/cp/error.c b/gcc/cp/error.c index 1748fe0aa69..8eab2292696 100644 --- a/gcc/cp/error.c +++ b/gcc/cp/error.c @@ -1511,7 +1511,7 @@ dump_expr (tree t, int flags) pp_cxx_right_bracket (cxx_pp); break; - case CONVERT_EXPR: + case UNARY_PLUS_EXPR: if (TREE_TYPE (t) && VOID_TYPE_P (TREE_TYPE (t))) { pp_cxx_left_paren (cxx_pp); diff --git a/gcc/cp/lex.c b/gcc/cp/lex.c index 21fe2a13581..7e891860306 100644 --- a/gcc/cp/lex.c +++ b/gcc/cp/lex.c @@ -145,7 +145,7 @@ init_operators (void) operator_name_info [(int) TRUTH_AND_EXPR].name = "strict &&"; operator_name_info [(int) TRUTH_OR_EXPR].name = "strict ||"; operator_name_info [(int) RANGE_EXPR].name = "..."; - operator_name_info [(int) CONVERT_EXPR].name = "+"; + operator_name_info [(int) UNARY_PLUS_EXPR].name = "+"; assignment_operator_name_info [(int) EXACT_DIV_EXPR].name = "(exact /=)"; diff --git a/gcc/cp/operators.def b/gcc/cp/operators.def index 16e603d31bf..19c1b6f9c70 100644 --- a/gcc/cp/operators.def +++ b/gcc/cp/operators.def @@ -84,7 +84,7 @@ DEF_SIMPLE_OPERATOR ("delete", DELETE_EXPR, "dl", -1) DEF_SIMPLE_OPERATOR ("delete []", VEC_DELETE_EXPR, "da", -1) /* Unary operators. */ -DEF_SIMPLE_OPERATOR ("+", CONVERT_EXPR, "ps", 1) +DEF_SIMPLE_OPERATOR ("+", UNARY_PLUS_EXPR, "ps", 1) DEF_SIMPLE_OPERATOR ("-", NEGATE_EXPR, "ng", 1) DEF_SIMPLE_OPERATOR ("&", ADDR_EXPR, "ad", 1) DEF_SIMPLE_OPERATOR ("*", INDIRECT_REF, "de", 1) diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index 7f39c91a95a..27c1751cb02 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -4873,7 +4873,7 @@ cp_parser_unary_expression (cp_parser *parser, bool address_p, bool cast_p) non_constant_p = (unary_operator == PREINCREMENT_EXPR ? "`++'" : "`--'"); /* Fall through. */ - case CONVERT_EXPR: + case UNARY_PLUS_EXPR: case NEGATE_EXPR: case TRUTH_NOT_EXPR: expression = finish_unary_op_expr (unary_operator, cast_expression); @@ -4909,7 +4909,7 @@ cp_parser_unary_operator (cp_token* token) return ADDR_EXPR; case CPP_PLUS: - return CONVERT_EXPR; + return UNARY_PLUS_EXPR; case CPP_MINUS: return NEGATE_EXPR; diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index dd18567d641..8a0a430add2 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -7784,7 +7784,7 @@ tsubst_copy (tree t, tree args, tsubst_flags_t complain, tree in_decl) case TRUTH_NOT_EXPR: case BIT_NOT_EXPR: case ADDR_EXPR: - case CONVERT_EXPR: /* Unary + */ + case UNARY_PLUS_EXPR: /* Unary + */ case SIZEOF_EXPR: case ALIGNOF_EXPR: case ARROW_EXPR: @@ -8465,7 +8465,7 @@ tsubst_copy_and_build (tree t, case BIT_NOT_EXPR: case ABS_EXPR: case TRUTH_NOT_EXPR: - case CONVERT_EXPR: /* Unary + */ + case UNARY_PLUS_EXPR: /* Unary + */ case REALPART_EXPR: case IMAGPART_EXPR: return build_x_unary_op (TREE_CODE (t), RECUR (TREE_OPERAND (t, 0))); diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c index 64a5aa5bd25..8ef383c30ee 100644 --- a/gcc/cp/tree.c +++ b/gcc/cp/tree.c @@ -2268,7 +2268,14 @@ fold_if_not_in_template (tree expr) "fold". We will call fold later when actually instantiating the template. Integral constant expressions in templates will be evaluated via fold_non_dependent_expr, as necessary. */ - return (processing_template_decl ? expr : fold (expr)); + if (processing_template_decl) + return expr; + + /* Fold C++ front-end specific tree codes. */ + if (TREE_CODE (expr) == UNARY_PLUS_EXPR) + return fold_convert (TREE_TYPE (expr), TREE_OPERAND (expr, 0)); + + return fold (expr); } diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c index 92bbc1e071c..464b8efd3fa 100644 --- a/gcc/cp/typeck.c +++ b/gcc/cp/typeck.c @@ -3692,13 +3692,12 @@ build_unary_op (enum tree_code code, tree xarg, int noconvert) switch (code) { - /* CONVERT_EXPR stands for unary plus in this context. */ - case CONVERT_EXPR: + case UNARY_PLUS_EXPR: case NEGATE_EXPR: { int flags = WANT_ARITH | WANT_ENUM; /* Unary plus (but not unary minus) is allowed on pointers. */ - if (code == CONVERT_EXPR) + if (code == UNARY_PLUS_EXPR) flags |= WANT_POINTER; arg = build_expr_type_conversion (flags, arg, true); if (!arg)