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] |