This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.
Index Nav: | [Date Index] [Subject Index] [Author Index] [Thread Index] | |
---|---|---|
Message Nav: | [Date Prev] [Date Next] | [Thread Prev] [Thread Next] |
Other format: | [Raw text] |
This is a relatively large patch which tackles the difficult issue of generating more sloc information in front-ends (in particular C and C++ front-ends), so that "static analyzers" based on GCC can get more useful and detailed information. This happens to be related/similar to the need mentioned in PR43486, hence the mention of this PR in the subject line. In my work, as I mentioned a few times in the past, this patch is the first foundation for another patch, which will provide source navigation capabilities in IDEs/editors, by generating source cross reference information based on the C and C++ front-ends (introducing a new switch -fdump-xref). Ideally I'd like to submit both patches. Since this issue is more general, I have split my changes and introduced a new tentative switch called -fextra-slocs, which is the subject of this email. In order to provide more sloc info attached to nodes (and in particular VAR_DECLs), there are basically two possibilities: - the one mentioned in comment 4 of PR43486: << Jason Merrill 2010-03-23 01:51:34 UTC I suppose we could wrap rvalue uses in NOP_EXPR and lvalue uses in VIEW_CONVERT_EXPR. >> I investigated this option, and unfortunately this does not work because of folding occurring all over the place in the C and C++ front-ends, removing these extra EXPRs very early. So I opted for the second approach: - Keep another data structure which will associate extra slocs with some node expressions. The idea is that since you can't associate slocs with VAR_DECLs in an expr, instead we store extra slocs in the containing expression node. For instance, all binary expressions (add ADD, MINUS, ...) will contain two extra slocs: one for the left hand side, and one for the right hand side of the expression. One extra sloc for unary operators, etc... I've used a hash table which associates an array of location_t to some expr nodes, which could then be used by static analysis passes (as done by my patch to implement a -fdump-xref switch). I have attached the various patches, split in directories: - difs.common contains the common parts, introducing the -fextra-slocs switch and the generic data structure/API to store/retrieve extra slocs (in tree.[hc]) - difs.c contains the C front-end specific parts and add lots of source location information, add some extra loc parameters to various parser functions, and store these extra slocs when -fextra-slocs is enabled - difs.cp does the same thing for the C++ front-end and includes testsuite updates which are triggered by this patch, showing some of the immediate benefits/side effects of generating more accurate "primary" slocs in some cases (the case of Class::Method () references, where we now want to reference the sloc pointing to Method rather than Class) OK on principle? Or is the whole approach not suitable/doomed? If OK on principle, I'd appreciate a C, C++ front-end maintainers, and a general maintainer (for the common/general part) to review my patches in more details, and hopefully give their review/OK. Here is the ChangeLog (which will be split into the various directories of course), patches are in attachment. 2012-09-18 Arnaud Charlet <charlet@adacore.com> * tree.h, tree.c (stabilize_reference): Copy source locations. (sloc_struct, extra_slocs): New. (node_hash, node_eq): Implement extra_slocs hash table. (expr_locations, set_expr_locations, set_expr_location2, duplicate_expr_locations, expr_location_n): New functions. (EXPR_LOCATIONS, SET_EXPR_LOCATION2, SET_EXPR_LOCATIONS): New macros. * common.opt: New switch -fextra-slocs. c/ * c-parser.c (c_parser_expr_list): New parameter locs, num_locs. Set extra locations. (c_parser_attributes): Adjust calls to c_parser_expr_list. (c_parser_statement_after_labels): Adjust calls to c_finish_return with extra expr location. (c_parser_expr_no_commas, c_parser_conditional_expression, c_parser_binary_expression, c_parser_cast_expression, c_parser_unary_expression, c_parser_postfix_expression_after_primary, c_parser_expr_list): Set extra locations. (c_parser_postfix_expression): Remove extra semicolon. (c_parser_objc_keywordexpr): Adjust call to c_parser_expr_list. * c-typeck.c (c_finish_return): New parameter loc_expr. * c-tree.h (c_finish_return): Add location_t parameter. * c-decl.c (finish_function): Update call to c_finish_return. (build_function_declarator): Set ret->id_loc. c-family/ * c-common.c (c_fully_fold_internal): Copy extra locations on new node. objc/ * objc-act.c (objc_synthesize_getter): Update call to c_finish_return. cp/ * parser.c (cp_parser_unary_expression, cp_parser_binary_expression, cp_parser_question_colon_clause, cp_parser_assignment_expression, cp_parser_enumerator_definition): Set extra locations. (cp_parser_parenthesized_expression_list): Ditto. New parameters locs, num_locs. (cp_parser_parse_and_diagnose_invalid_typ): Adjust call to cp_parser_id_location. (cp_parser_userdef_char_literal, cp_parser_userdef_numeric_literal, cp_parser_userdef_string_literal, cp_parser_perform_range_for_lookup, cp_parser_range_for_member_function): Adjust calls to finish_call_expr. (cp_parser_primary_expression, cp_parser_postfix_dot_deref_expression, cp_parser_decltype, cp_parser_type_parameter, cp_parser_template_argument, cp_parser_omp_var_list_no_open): Adjust calls to cp_parser_id_expression. (cp_parser_id_expression, cp_parser_declarator_id): New parameter location_t *. Set location to proper sloc for class::method declarations. (cp_parser_postfix_expression): Set extra locations. Update calls to cp_parser_parenthesized_expression_list, build_new_method_call and finish_call_expr. (cp_parser_postfix_open_square_expression): Add extra locations for array refs (e.g. a[i]). (cp_parser_direct_declarator): Adjust call to cp_parser_declarator_id and adjust sloc of declarator. (cp_parser_new_placement, cp_parser_new_initializer, cp_parser_mem_initializer, cp_parser_initializer, cp_parser_attribute_list, cp_parser_functional_cast): Adjust call to cp_parser_parenthesized_expression_list. * typeck.c (build_c_cast): Ensure extra sloc information is preserved over this function. * call.c (build_over_call): New parameter loc. (build_new_function_call, build_operator_new_call, build_op_call_1, build_new_op_1, convert_like_real): Update call to build_over_call. (build_new_method_call, build_new_method_call_1, finish_call_expr): New parameter loc. (build_special_member_call): Update call to build_new_method_call. (perform_implicit_conversion_flags): Ensure line number information is preserved over this function. * method.c (locate_fn_flags): Update call to build_new_method_call. * class.c (build_self_reference): Update decl location of internal type. * cp-tree.h (build_new_method_call, finish_call_expr): New parameter loc. * pt.c (tsubst_copy_and_build): Update call to build_new_method_call and finish_call_expr. * init.c (build_new_1, build_dtor_call): Ditto. * semantics.c (finish_omp_barrier, finish_omp_flush, finish_omp_taskyield, finish_omp_taskwait): Ditto. (finish_call_expr): Ditto. New parameter loc. (finish_id_expression): Add sloc on decl. testsuite/ * g++.dg/warn/pr26785.C, g++.old-deja/g++.brendan/crash16.C: Update column numbers. * g++.dg/tc1/dr52.C: Update baseline.
Attachment:
difs.common
Description: Text document
Index: c-family/c-common.c =================================================================== --- c-family/c-common.c (revision 190939) +++ c-family/c-common.c (working copy) @@ -1440,7 +1440,10 @@ c_fully_fold_internal (tree expr, bool i TREE_NO_WARNING (ret) = 1; } if (ret != expr) - protected_set_expr_location (ret, loc); + { + protected_set_expr_location (ret, loc); + duplicate_expr_locations (ret, expr); + } return ret; } Index: c/c-parser.c =================================================================== --- c/c-parser.c (revision 190939) +++ c/c-parser.c (working copy) @@ -1186,7 +1186,8 @@ static struct c_expr c_parser_expression static struct c_expr c_parser_expression_conv (c_parser *); static VEC(tree,gc) *c_parser_expr_list (c_parser *, bool, bool, VEC(tree,gc) **, - struct c_tree_loc_pair *); + struct c_tree_loc_pair *, location_t *, + int *); static void c_parser_omp_construct (c_parser *); static void c_parser_omp_threadprivate (c_parser *); static void c_parser_omp_barrier (c_parser *); @@ -3586,7 +3587,7 @@ c_parser_attributes (c_parser *parser) tree tree_list; c_parser_consume_token (parser); expr_list = c_parser_expr_list (parser, false, true, - NULL, NULL); + NULL, NULL, NULL, NULL); tree_list = build_tree_list_vec (expr_list); attr_args = tree_cons (NULL_TREE, arg1, tree_list); release_tree_vector (expr_list); @@ -3599,7 +3600,7 @@ c_parser_attributes (c_parser *parser) else { expr_list = c_parser_expr_list (parser, false, true, - NULL, NULL); + NULL, NULL, NULL, NULL); attr_args = build_tree_list_vec (expr_list); release_tree_vector (expr_list); } @@ -4509,19 +4510,28 @@ c_parser_statement_after_labels (c_parse stmt = c_finish_bc_stmt (loc, &c_break_label, true); goto expect_semicolon; case RID_RETURN: - c_parser_consume_token (parser); - if (c_parser_next_token_is (parser, CPP_SEMICOLON)) - { - stmt = c_finish_return (loc, NULL_TREE, NULL_TREE); - c_parser_consume_token (parser); - } - else - { - struct c_expr expr = c_parser_expression_conv (parser); - mark_exp_read (expr.value); - stmt = c_finish_return (loc, expr.value, expr.original_type); - goto expect_semicolon; - } + { + location_t ret_loc; + c_parser_consume_token (parser); + ret_loc = c_parser_peek_token (parser)->location; + + if (c_parser_next_token_is (parser, CPP_SEMICOLON)) + { + stmt = c_finish_return (loc, + ret_loc, + NULL_TREE, NULL_TREE); + c_parser_consume_token (parser); + } + else + { + struct c_expr expr = c_parser_expression_conv (parser); + mark_exp_read (expr.value); + stmt = c_finish_return (loc, + ret_loc, + expr.value, expr.original_type); + goto expect_semicolon; + } + } break; case RID_ASM: stmt = c_parser_asm_statement (parser); @@ -5357,8 +5367,9 @@ c_parser_expr_no_commas (c_parser *parse { struct c_expr lhs, rhs, ret; enum tree_code code; - location_t op_location, exp_location; + location_t op_location, exp_location, locs[2]; gcc_assert (!after || c_dialect_objc ()); + locs[0] = c_parser_peek_token (parser)->location; lhs = c_parser_conditional_expression (parser, after); op_location = c_parser_peek_token (parser)->location; switch (c_parser_peek_token (parser)->type) @@ -5406,6 +5417,8 @@ c_parser_expr_no_commas (c_parser *parse ret.value = build_modify_expr (op_location, lhs.value, lhs.original_type, code, exp_location, rhs.value, rhs.original_type); + locs[1] = exp_location; + SET_EXPR_LOCATIONS (ret.value, locs, 2); if (code == NOP_EXPR) ret.original_code = MODIFY_EXPR; else @@ -5435,10 +5448,11 @@ static struct c_expr c_parser_conditional_expression (c_parser *parser, struct c_expr *after) { struct c_expr cond, exp1, exp2, ret; - location_t cond_loc, colon_loc, middle_loc; + location_t cond_loc, colon_loc, middle_loc, locs[3]; gcc_assert (!after || c_dialect_objc ()); + locs[0] = c_parser_peek_token (parser)->location; cond = c_parser_binary_expression (parser, after, PREC_NONE); if (c_parser_next_token_is_not (parser, CPP_QUERY)) @@ -5446,6 +5460,7 @@ c_parser_conditional_expression (c_parse cond_loc = c_parser_peek_token (parser)->location; cond = default_function_array_read_conversion (cond_loc, cond); c_parser_consume_token (parser); + locs[1] = c_parser_peek_token (parser)->location; if (c_parser_next_token_is (parser, CPP_COLON)) { tree eptype = NULL_TREE; @@ -5466,12 +5481,14 @@ c_parser_conditional_expression (c_parse exp1.original_type = NULL; cond.value = c_objc_common_truthvalue_conversion (cond_loc, exp1.value); c_inhibit_evaluation_warnings += cond.value == truthvalue_true_node; + locs[1] = UNKNOWN_LOCATION; } else { cond.value = c_objc_common_truthvalue_conversion (cond_loc, default_conversion (cond.value)); + SET_EXPR_LOCATION2 (cond.value, locs[0]); c_inhibit_evaluation_warnings += cond.value == truthvalue_false_node; exp1 = c_parser_expression_conv (parser); mark_exp_read (exp1.value); @@ -5491,6 +5508,7 @@ c_parser_conditional_expression (c_parse } { location_t exp2_loc = c_parser_peek_token (parser)->location; + locs[2] = exp2_loc; exp2 = c_parser_conditional_expression (parser, NULL); exp2 = default_function_array_read_conversion (exp2_loc, exp2); } @@ -5506,6 +5524,7 @@ c_parser_conditional_expression (c_parse { tree t1, t2; + SET_EXPR_LOCATIONS (ret.value, locs, 3); /* If both sides are enum type, the default conversion will have made the type of the result be an integer type. We want to remember the enum types we started with. */ @@ -5610,9 +5629,10 @@ c_parser_binary_expression (c_parser *pa /* The operation on its left. */ enum tree_code op; /* The source location of this operation. */ - location_t loc; + location_t loc, loc2; } stack[NUM_PRECS]; int sp; + location_t *locs; /* Location of the binary operator. */ location_t binary_loc = UNKNOWN_LOCATION; /* Quiet warning. */ #define POP \ @@ -5641,12 +5661,27 @@ c_parser_binary_expression (c_parser *pa stack[sp - 1].expr, \ stack[sp].expr); \ sp--; \ + if (EXPR_P (stack[sp].expr.value)) \ + { \ + location_t locs[2]; \ + if (stack[sp].expr.original_code == TREE_CODE (stack[sp].expr.value)) \ + locs[0] = stack[sp].loc2, locs[1] = stack[sp + 1].loc2; \ + else \ + locs[1] = stack[sp].loc2, locs[0] = stack[sp + 1].loc2; \ + SET_EXPR_LOCATIONS (stack[sp].expr.value, locs, 2); \ + } \ } while (0) gcc_assert (!after || c_dialect_objc ()); - stack[0].loc = c_parser_peek_token (parser)->location; + stack[0].loc2 = stack[0].loc = c_parser_peek_token (parser)->location; stack[0].expr = c_parser_cast_expression (parser, after); stack[0].prec = prec; sp = 0; + if (EXPR_P (stack[sp].expr.value)) + { + locs = EXPR_LOCATIONS (stack[sp].expr.value); + if (locs) stack [sp].loc2 = *locs; + } + while (true) { enum c_parser_prec oprec; @@ -5765,10 +5800,16 @@ c_parser_binary_expression (c_parser *pa } sp++; stack[sp].loc = binary_loc; + stack[sp].loc2 = c_parser_peek_token (parser)->location; stack[sp].expr = c_parser_cast_expression (parser, NULL); stack[sp].prec = oprec; stack[sp].op = ocode; stack[sp].loc = binary_loc; + if (EXPR_P (stack[sp].expr.value)) + { + locs = EXPR_LOCATIONS (stack[sp].expr.value); + if (locs) stack [sp].loc2 = *locs; + } } out: while (sp > 0) @@ -5826,11 +5867,12 @@ c_parser_cast_expression (c_parser *pars location_t expr_loc = c_parser_peek_token (parser)->location; expr = c_parser_cast_expression (parser, NULL); expr = default_function_array_read_conversion (expr_loc, expr); + ret.value = c_cast_expr (cast_loc, type_name, expr.value); + SET_EXPR_LOCATION2 (ret.value, expr_loc); + ret.original_code = ERROR_MARK; + ret.original_type = NULL; + return ret; } - ret.value = c_cast_expr (cast_loc, type_name, expr.value); - ret.original_code = ERROR_MARK; - ret.original_type = NULL; - return ret; } else return c_parser_unary_expression (parser); @@ -5886,24 +5928,32 @@ c_parser_unary_expression (c_parser *par exp_loc = c_parser_peek_token (parser)->location; op = c_parser_cast_expression (parser, NULL); op = default_function_array_read_conversion (exp_loc, op); - return parser_build_unary_op (op_loc, PREINCREMENT_EXPR, op); + ret = parser_build_unary_op (op_loc, PREINCREMENT_EXPR, op); + SET_EXPR_LOCATION2 (ret.value, exp_loc); + return ret; case CPP_MINUS_MINUS: c_parser_consume_token (parser); exp_loc = c_parser_peek_token (parser)->location; op = c_parser_cast_expression (parser, NULL); op = default_function_array_read_conversion (exp_loc, op); - return parser_build_unary_op (op_loc, PREDECREMENT_EXPR, op); + ret = parser_build_unary_op (op_loc, PREDECREMENT_EXPR, op); + SET_EXPR_LOCATION2 (ret.value, exp_loc); + return ret; case CPP_AND: c_parser_consume_token (parser); + exp_loc = c_parser_peek_token (parser)->location; op = c_parser_cast_expression (parser, NULL); mark_exp_read (op.value); - return parser_build_unary_op (op_loc, ADDR_EXPR, op); + ret = parser_build_unary_op (op_loc, ADDR_EXPR, op); + SET_EXPR_LOCATION2 (ret.value, exp_loc); + return ret; case CPP_MULT: c_parser_consume_token (parser); exp_loc = c_parser_peek_token (parser)->location; op = c_parser_cast_expression (parser, NULL); op = default_function_array_read_conversion (exp_loc, op); ret.value = build_indirect_ref (op_loc, op.value, RO_UNARY_STAR); + SET_EXPR_LOCATION2 (ret.value, exp_loc); return ret; case CPP_PLUS: if (!c_dialect_objc () && !in_system_header) @@ -5914,25 +5964,32 @@ c_parser_unary_expression (c_parser *par exp_loc = c_parser_peek_token (parser)->location; op = c_parser_cast_expression (parser, NULL); op = default_function_array_read_conversion (exp_loc, op); - return parser_build_unary_op (op_loc, CONVERT_EXPR, op); + ret = parser_build_unary_op (op_loc, CONVERT_EXPR, op); + SET_EXPR_LOCATION2 (ret.value, exp_loc); + return ret; case CPP_MINUS: c_parser_consume_token (parser); exp_loc = c_parser_peek_token (parser)->location; op = c_parser_cast_expression (parser, NULL); op = default_function_array_read_conversion (exp_loc, op); - return parser_build_unary_op (op_loc, NEGATE_EXPR, op); + ret = parser_build_unary_op (op_loc, NEGATE_EXPR, op); + SET_EXPR_LOCATION2 (ret.value, exp_loc); + return ret; case CPP_COMPL: c_parser_consume_token (parser); exp_loc = c_parser_peek_token (parser)->location; op = c_parser_cast_expression (parser, NULL); op = default_function_array_read_conversion (exp_loc, op); - return parser_build_unary_op (op_loc, BIT_NOT_EXPR, op); + ret = parser_build_unary_op (op_loc, BIT_NOT_EXPR, op); + return ret; case CPP_NOT: c_parser_consume_token (parser); exp_loc = c_parser_peek_token (parser)->location; op = c_parser_cast_expression (parser, NULL); op = default_function_array_read_conversion (exp_loc, op); - return parser_build_unary_op (op_loc, TRUTH_NOT_EXPR, op); + ret = parser_build_unary_op (op_loc, TRUTH_NOT_EXPR, op); + SET_EXPR_LOCATION2 (ret.value, exp_loc); + return ret; case CPP_AND_AND: /* Refer to the address of a label as a pointer. */ c_parser_consume_token (parser); @@ -6232,7 +6289,7 @@ c_parser_postfix_expression (c_parser *p { struct c_expr expr, e1; struct c_type_name *t1, *t2; - location_t loc = c_parser_peek_token (parser)->location;; + location_t loc = c_parser_peek_token (parser)->location; expr.original_code = ERROR_MARK; expr.original_type = NULL; switch (c_parser_peek_token (parser)->type) @@ -6875,9 +6932,14 @@ c_parser_postfix_expression_after_primar { struct c_expr orig_expr; tree ident, idx; + location_t locs [64]; + location_t op2_loc; + int length = 63; struct c_tree_loc_pair sizeof_arg; VEC(tree,gc) *exprlist; VEC(tree,gc) *origtypes; + + locs [0] = expr_loc; while (true) { location_t op_loc = c_parser_peek_token (parser)->location; @@ -6886,10 +6948,20 @@ c_parser_postfix_expression_after_primar case CPP_OPEN_SQUARE: /* Array reference. */ c_parser_consume_token (parser); + locs [1] = c_parser_peek_token (parser)->location; idx = c_parser_expression (parser).value; c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE, "expected %<]%>"); expr.value = build_array_ref (op_loc, expr.value, idx); + if (CAN_HAVE_LOCATION_P (expr.value)) + { + if (TREE_CODE (expr.value) == ARRAY_REF) + SET_EXPR_LOCATIONS (expr.value, locs, 2); + else if (TREE_CODE (expr.value) == INDIRECT_REF + && TREE_CODE (TREE_OPERAND (expr.value, 0)) + == POINTER_PLUS_EXPR) + SET_EXPR_LOCATIONS (TREE_OPERAND (expr.value, 0), locs, 2); + } expr.original_code = ERROR_MARK; expr.original_type = NULL; break; @@ -6898,10 +6970,13 @@ c_parser_postfix_expression_after_primar c_parser_consume_token (parser); sizeof_arg.expr = NULL_TREE; if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN)) - exprlist = NULL; + { + exprlist = NULL; + length = 0; + } else exprlist = c_parser_expr_list (parser, true, false, &origtypes, - &sizeof_arg); + &sizeof_arg, locs + 1, &length); c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, "expected %<)%>"); orig_expr = expr; @@ -6916,6 +6991,9 @@ c_parser_postfix_expression_after_primar "(" after the FUNCNAME, which is what we have now. */ expr.value = build_function_call_vec (op_loc, expr.value, exprlist, origtypes); + if (CAN_HAVE_LOCATION_P (expr.value)) + SET_EXPR_LOCATIONS (expr.value, locs, length + 1); + expr.original_code = ERROR_MARK; if (TREE_CODE (expr.value) == INTEGER_CST && TREE_CODE (orig_expr.value) == FUNCTION_DECL @@ -6943,9 +7021,15 @@ c_parser_postfix_expression_after_primar expr.original_type = NULL; return expr; } + op2_loc = c_parser_peek_token (parser)->location; c_parser_consume_token (parser); expr.value = build_component_ref (op_loc, expr.value, ident); expr.original_code = ERROR_MARK; + if (CAN_HAVE_LOCATION_P (expr.value)) + { + locs[1] = op2_loc; + SET_EXPR_LOCATIONS (expr.value, locs, 2); + } if (TREE_CODE (expr.value) != COMPONENT_REF) expr.original_type = NULL; else @@ -6972,13 +7056,17 @@ c_parser_postfix_expression_after_primar expr.original_type = NULL; return expr; } + op2_loc = c_parser_peek_token (parser)->location; c_parser_consume_token (parser); - expr.value = build_component_ref (op_loc, - build_indirect_ref (op_loc, - expr.value, - RO_ARROW), - ident); + expr.value = build_indirect_ref (op_loc, expr.value, RO_ARROW), + SET_EXPR_LOCATION2 (expr.value, locs[0]); + expr.value = build_component_ref (op_loc, expr.value, ident); expr.original_code = ERROR_MARK; + if (CAN_HAVE_LOCATION_P (expr.value)) + { + locs[1] = op2_loc; + SET_EXPR_LOCATIONS (expr.value, locs, 2); + } if (TREE_CODE (expr.value) != COMPONENT_REF) expr.original_type = NULL; else @@ -6997,6 +7085,7 @@ c_parser_postfix_expression_after_primar expr = default_function_array_read_conversion (expr_loc, expr); expr.value = build_unary_op (op_loc, POSTINCREMENT_EXPR, expr.value, 0); + SET_EXPR_LOCATION2 (expr.value, expr_loc); expr.original_code = ERROR_MARK; expr.original_type = NULL; break; @@ -7006,6 +7095,7 @@ c_parser_postfix_expression_after_primar expr = default_function_array_read_conversion (expr_loc, expr); expr.value = build_unary_op (op_loc, POSTDECREMENT_EXPR, expr.value, 0); + SET_EXPR_LOCATION2 (expr.value, expr_loc); expr.original_code = ERROR_MARK; expr.original_type = NULL; break; @@ -7073,11 +7163,13 @@ c_parser_expression_conv (c_parser *pars static VEC(tree,gc) * c_parser_expr_list (c_parser *parser, bool convert_p, bool fold_p, VEC(tree,gc) **p_orig_types, - struct c_tree_loc_pair *sizeof_arg) + struct c_tree_loc_pair *sizeof_arg, + location_t *locs, int *num_locs) { VEC(tree,gc) *ret; VEC(tree,gc) *orig_types; struct c_expr expr; + int i = 0; location_t loc = c_parser_peek_token (parser)->location; location_t sizeof_arg_loc = UNKNOWN_LOCATION; @@ -7095,6 +7187,9 @@ c_parser_expr_list (c_parser *parser, bo expr = default_function_array_read_conversion (loc, expr); if (fold_p) expr.value = c_fully_fold (expr.value, false, NULL); + if (locs && i < *num_locs) + locs [i++] = loc; + VEC_quick_push (tree, ret, expr.value); if (orig_types != NULL) VEC_quick_push (tree, orig_types, expr.original_type); @@ -7115,6 +7210,8 @@ c_parser_expr_list (c_parser *parser, bo VEC_safe_push (tree, gc, ret, expr.value); if (orig_types != NULL) VEC_safe_push (tree, gc, orig_types, expr.original_type); + if (locs && i < *num_locs) + locs [i++] = loc; } if (sizeof_arg != NULL) { @@ -7132,6 +7229,8 @@ c_parser_expr_list (c_parser *parser, bo } if (orig_types != NULL) *p_orig_types = orig_types; + if (locs) + *num_locs = i; return ret; } @@ -8209,7 +8308,7 @@ c_parser_objc_keywordexpr (c_parser *par { tree ret; VEC(tree,gc) *expr_list = c_parser_expr_list (parser, true, true, - NULL, NULL); + NULL, NULL, NULL, NULL); if (VEC_length (tree, expr_list) == 1) { /* Just return the expression, remove a level of Index: c/c-typeck.c =================================================================== --- c/c-typeck.c (revision 190939) +++ c/c-typeck.c (working copy) @@ -8627,11 +8627,13 @@ c_finish_goto_ptr (location_t loc, tree /* Generate a C `return' statement. RETVAL is the expression for what to return, or a null pointer for `return;' with no value. LOC is - the location of the return statement. If ORIGTYPE is not NULL_TREE, it + the location of the return statement. LOC_EXPR is the location of the + return expression, if any. If ORIGTYPE is not NULL_TREE, it is the original type of RETVAL. */ tree -c_finish_return (location_t loc, tree retval, tree origtype) +c_finish_return (location_t loc, location_t loc_expr, tree retval, + tree origtype) { tree valtype = TREE_TYPE (TREE_TYPE (current_function_decl)), ret_stmt; bool no_warning = false; @@ -8747,6 +8749,12 @@ c_finish_return (location_t loc, tree re retval = build2 (MODIFY_EXPR, TREE_TYPE (res), res, t); SET_EXPR_LOCATION (retval, loc); + { + location_t locs[2]; + locs[0] = loc; + locs[1] = loc_expr; + SET_EXPR_LOCATIONS (retval, locs, 2); + } if (warn_sequence_point) verify_sequence_points (retval); Index: c/c-tree.h =================================================================== --- c/c-tree.h (revision 190939) +++ c/c-tree.h (working copy) @@ -635,7 +635,7 @@ extern tree c_begin_stmt_expr (void); extern tree c_finish_stmt_expr (location_t, tree); extern tree c_process_expr_stmt (location_t, tree); extern tree c_finish_expr_stmt (location_t, tree); -extern tree c_finish_return (location_t, tree, tree); +extern tree c_finish_return (location_t, location_t, tree, tree); extern tree c_finish_bc_stmt (location_t, tree *, bool); extern tree c_finish_goto_label (location_t, tree); extern tree c_finish_goto_ptr (location_t, tree); Index: c/c-decl.c =================================================================== --- c/c-decl.c (revision 190939) +++ c/c-decl.c (working copy) @@ -8365,7 +8365,8 @@ finish_function (void) annotate_one_with_locus. A cleaner solution might be to ensure ! should_carry_locus_p (stmt), but that needs a flag. */ - c_finish_return (BUILTINS_LOCATION, integer_zero_node, NULL_TREE); + c_finish_return (BUILTINS_LOCATION, BUILTINS_LOCATION, + integer_zero_node, NULL_TREE); } /* Tie off the statement tree for this function. */ @@ -8738,6 +8739,7 @@ build_function_declarator (struct c_arg_ ret->kind = cdk_function; ret->declarator = target; ret->u.arg_info = args; + ret->id_loc = target->id_loc; return ret; } Index: objc/objc-act.c =================================================================== --- objc/objc-act.c (revision 190939) +++ objc/objc-act.c (working copy) @@ -7314,7 +7314,7 @@ objc_synthesize_getter (tree klass, tree #ifdef OBJCPLUS finish_return_stmt (ret_val); #else - c_finish_return (location, ret_val, NULL_TREE); + c_finish_return (location, location, ret_val, NULL_TREE); #endif add_stmt (c_end_compound_stmt (location, body, true));
Attachment:
difs.cp
Description: Text document
Index Nav: | [Date Index] [Subject Index] [Author Index] [Thread Index] | |
---|---|---|
Message Nav: | [Date Prev] [Date Next] | [Thread Prev] [Thread Next] |