The initial version of the patch kit added location wrapper nodes around constants and uses-of-declarations, along with some other places in the parser (typeid, alignof, sizeof, offsetof).
This version takes a much more minimal approach: it only adds location wrapper nodes around the arguments at callsites, thus not adding wrapper nodes around uses of constants and decls in other locations. It keeps them for the other places in the parser (typeid, alignof, sizeof, offsetof). In addition, for now, each site that adds wrapper nodes is guarded with !processing_template_decl, suppressing the creation of wrapper nodes when processing template declarations. This is to simplify the patch kit so that we don't have to support wrapper nodes during template expansion. gcc/cp/ChangeLog: * parser.c (cp_parser_postfix_expression): Call maybe_add_location_wrapper on the result for RID_TYPEID. Pass true for new "wrap_locations_p" param of cp_parser_parenthesized_expression_list. (cp_parser_parenthesized_expression_list): Add "wrap_locations_p" param, defaulting to false. Convert "expr" to a cp_expr, and call maybe_add_location_wrapper on it when wrap_locations_p is true, except when processing template decls. (cp_parser_unary_expression): Call maybe_add_location_wrapper on the result for RID_ALIGNOF and RID_SIZEOF. (cp_parser_builtin_offsetof): Likewise. FIXME: don't do alignof etc when processing template decls --- gcc/cp/parser.c | 29 +++++++++++++++++++++++------ 1 file changed, 23 insertions(+), 6 deletions(-) diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index 77b9637..54029ef 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -2054,7 +2054,8 @@ static tree cp_parser_postfix_open_square_expression static tree cp_parser_postfix_dot_deref_expression (cp_parser *, enum cpp_ttype, cp_expr, bool, cp_id_kind *, location_t); static vec<tree, va_gc> *cp_parser_parenthesized_expression_list - (cp_parser *, int, bool, bool, bool *, location_t * = NULL); + (cp_parser *, int, bool, bool, bool *, location_t * = NULL, + bool = false); /* Values for the second parameter of cp_parser_parenthesized_expression_list. */ enum { non_attr = 0, normal_attr = 1, id_attr = 2 }; static void cp_parser_pseudo_destructor_name @@ -6776,6 +6777,8 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p, bool cast_p, location_t typeid_loc = make_location (start_loc, start_loc, close_paren->location); postfix_expression.set_location (typeid_loc); + if (!processing_template_decl) + postfix_expression.maybe_add_location_wrapper (); } } break; @@ -7096,7 +7099,8 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p, bool cast_p, (parser, non_attr, /*cast_p=*/false, /*allow_expansion_p=*/true, /*non_constant_p=*/NULL, - /*close_paren_loc=*/&close_paren_loc)); + /*close_paren_loc=*/&close_paren_loc, + /*wrap_locations_p=*/true)); if (is_builtin_constant_p) { parser->integral_constant_expression_p @@ -7736,6 +7740,10 @@ cp_parser_postfix_dot_deref_expression (cp_parser *parser, ALLOW_EXPANSION_P is true if this expression allows expansion of an argument pack. + WRAP_LOCATIONS_P is true if expressions within this list for which + CAN_HAVE_LOCATION_P is false should be wrapped with nodes expressing + their source locations. + Returns a vector of trees. Each element is a representation of an assignment-expression. NULL is returned if the ( and or ) are missing. An empty, but allocated, vector is returned on no @@ -7755,7 +7763,8 @@ cp_parser_parenthesized_expression_list (cp_parser* parser, bool cast_p, bool allow_expansion_p, bool *non_constant_p, - location_t *close_paren_loc) + location_t *close_paren_loc, + bool wrap_locations_p) { vec<tree, va_gc> *expression_list; bool fold_expr_p = is_attribute_list != non_attr; @@ -7778,12 +7787,12 @@ cp_parser_parenthesized_expression_list (cp_parser* parser, = parser->greater_than_is_operator_p; parser->greater_than_is_operator_p = true; + cp_expr expr (NULL_TREE); + /* Consume expressions until there are no more. */ if (cp_lexer_next_token_is_not (parser->lexer, CPP_CLOSE_PAREN)) while (true) { - tree expr; - /* At the beginning of attribute lists, check to see if the next token is an identifier. */ if (is_attribute_list == id_attr @@ -7837,11 +7846,15 @@ cp_parser_parenthesized_expression_list (cp_parser* parser, expr = make_pack_expansion (expr); } + if (wrap_locations_p) + if (!processing_template_decl) + expr.maybe_add_location_wrapper (); + /* Add it to the list. We add error_mark_node expressions to the list, so that we can still tell if the correct form for a parenthesized expression-list is found. That gives better errors. */ - vec_safe_push (expression_list, expr); + vec_safe_push (expression_list, expr.get_value ()); if (expr == error_mark_node) goto skip_comma; @@ -8107,6 +8120,8 @@ cp_parser_unary_expression (cp_parser *parser, cp_id_kind * pidk, cp_expr ret_expr (ret); ret_expr.set_location (compound_loc); + if (!processing_template_decl) + ret_expr = ret_expr.maybe_add_location_wrapper (); return ret_expr; } @@ -9933,6 +9948,8 @@ cp_parser_builtin_offsetof (cp_parser *parser) parser->integral_constant_expression_p = save_ice_p; parser->non_integral_constant_expression_p = save_non_ice_p; + if (!processing_template_decl) + expr = expr.maybe_add_location_wrapper (); return expr; } -- 1.8.5.3