diff options
author | David Malcolm <dmalcolm@redhat.com> | 2016-06-07 15:04:22 +0000 |
---|---|---|
committer | David Malcolm <dmalcolm@gcc.gnu.org> | 2016-06-07 15:04:22 +0000 |
commit | 6ffd47b70a4553b621a124ce2632cb2d39a8008f (patch) | |
tree | 71a730994243919c88c4e269b3d48b4000eb9529 /gcc/c | |
parent | 0f471dc3e81fee3d346c4887ce63688dc2735fdd (diff) | |
download | gcc-6ffd47b70a4553b621a124ce2632cb2d39a8008f.zip gcc-6ffd47b70a4553b621a124ce2632cb2d39a8008f.tar.gz gcc-6ffd47b70a4553b621a124ce2632cb2d39a8008f.tar.bz2 |
C: add fixit hint to misspelled field names
gcc/c/ChangeLog:
* c-parser.c (c_parser_postfix_expression): In __builtin_offsetof
and structure element reference, capture the location of the
element name token and pass it to build_component_ref.
(c_parser_postfix_expression_after_primary): Likewise for
structure element dereference.
(c_parser_omp_variable_list): Likewise for
OMP_CLAUSE_{_CACHE, MAP, FROM, TO},
* c-tree.h (build_component_ref): Add location_t param.
* c-typeck.c (build_component_ref): Add location_t param
COMPONENT_LOC. Use it, if available, when issuing hints about
mispelled member names to provide a fixit replacement hint.
gcc/objc/ChangeLog:
* objc-act.c (objc_build_component_ref): Update call
to build_component_ref for added param, passing UNKNOWN_LOCATION.
gcc/testsuite/ChangeLog:
* gcc.dg/spellcheck-fields-2.c: New test case.
From-SVN: r237176
Diffstat (limited to 'gcc/c')
-rw-r--r-- | gcc/c/ChangeLog | 14 | ||||
-rw-r--r-- | gcc/c/c-parser.c | 34 | ||||
-rw-r--r-- | gcc/c/c-tree.h | 2 | ||||
-rw-r--r-- | gcc/c/c-typeck.c | 26 |
4 files changed, 61 insertions, 15 deletions
diff --git a/gcc/c/ChangeLog b/gcc/c/ChangeLog index 3b7feaa..de23e36 100644 --- a/gcc/c/ChangeLog +++ b/gcc/c/ChangeLog @@ -1,3 +1,17 @@ +2016-06-07 David Malcolm <dmalcolm@redhat.com> + + * c-parser.c (c_parser_postfix_expression): In __builtin_offsetof + and structure element reference, capture the location of the + element name token and pass it to build_component_ref. + (c_parser_postfix_expression_after_primary): Likewise for + structure element dereference. + (c_parser_omp_variable_list): Likewise for + OMP_CLAUSE_{_CACHE, MAP, FROM, TO}, + * c-tree.h (build_component_ref): Add location_t param. + * c-typeck.c (build_component_ref): Add location_t param + COMPONENT_LOC. Use it, if available, when issuing hints about + mispelled member names to provide a fixit replacement hint. + 2016-06-06 Marek Polacek <polacek@redhat.com> PR c/71362 diff --git a/gcc/c/c-parser.c b/gcc/c/c-parser.c index 799a473..2fef1ac 100644 --- a/gcc/c/c-parser.c +++ b/gcc/c/c-parser.c @@ -7708,8 +7708,9 @@ c_parser_postfix_expression (c_parser *parser) accept sub structure and sub array references. */ if (c_parser_next_token_is (parser, CPP_NAME)) { + c_token *comp_tok = c_parser_peek_token (parser); offsetof_ref = build_component_ref - (loc, offsetof_ref, c_parser_peek_token (parser)->value); + (loc, offsetof_ref, comp_tok->value, comp_tok->location); c_parser_consume_token (parser); while (c_parser_next_token_is (parser, CPP_DOT) || c_parser_next_token_is (parser, @@ -7735,9 +7736,10 @@ c_parser_postfix_expression (c_parser *parser) c_parser_error (parser, "expected identifier"); break; } + c_token *comp_tok = c_parser_peek_token (parser); offsetof_ref = build_component_ref - (loc, offsetof_ref, - c_parser_peek_token (parser)->value); + (loc, offsetof_ref, comp_tok->value, + comp_tok->location); c_parser_consume_token (parser); } else @@ -8214,7 +8216,7 @@ c_parser_postfix_expression_after_primary (c_parser *parser, { struct c_expr orig_expr; tree ident, idx; - location_t sizeof_arg_loc[3]; + location_t sizeof_arg_loc[3], comp_loc; tree sizeof_arg[3]; unsigned int literal_zero_mask; unsigned int i; @@ -8328,7 +8330,11 @@ c_parser_postfix_expression_after_primary (c_parser *parser, c_parser_consume_token (parser); expr = default_function_array_conversion (expr_loc, expr); if (c_parser_next_token_is (parser, CPP_NAME)) - ident = c_parser_peek_token (parser)->value; + { + c_token *comp_tok = c_parser_peek_token (parser); + ident = comp_tok->value; + comp_loc = comp_tok->location; + } else { c_parser_error (parser, "expected identifier"); @@ -8340,7 +8346,8 @@ c_parser_postfix_expression_after_primary (c_parser *parser, start = expr.get_start (); finish = c_parser_peek_token (parser)->get_finish (); c_parser_consume_token (parser); - expr.value = build_component_ref (op_loc, expr.value, ident); + expr.value = build_component_ref (op_loc, expr.value, ident, + comp_loc); set_c_expr_source_range (&expr, start, finish); expr.original_code = ERROR_MARK; if (TREE_CODE (expr.value) != COMPONENT_REF) @@ -8360,7 +8367,11 @@ c_parser_postfix_expression_after_primary (c_parser *parser, c_parser_consume_token (parser); expr = convert_lvalue_to_rvalue (expr_loc, expr, true, false); if (c_parser_next_token_is (parser, CPP_NAME)) - ident = c_parser_peek_token (parser)->value; + { + c_token *comp_tok = c_parser_peek_token (parser); + ident = comp_tok->value; + comp_loc = comp_tok->location; + } else { c_parser_error (parser, "expected identifier"); @@ -8376,7 +8387,7 @@ c_parser_postfix_expression_after_primary (c_parser *parser, build_indirect_ref (op_loc, expr.value, RO_ARROW), - ident); + ident, comp_loc); set_c_expr_source_range (&expr, start, finish); expr.original_code = ERROR_MARK; if (TREE_CODE (expr.value) != COMPONENT_REF) @@ -10622,9 +10633,12 @@ c_parser_omp_variable_list (c_parser *parser, t = error_mark_node; break; } - tree ident = c_parser_peek_token (parser)->value; + + c_token *comp_tok = c_parser_peek_token (parser); + tree ident = comp_tok->value; + location_t comp_loc = comp_tok->location; c_parser_consume_token (parser); - t = build_component_ref (op_loc, t, ident); + t = build_component_ref (op_loc, t, ident, comp_loc); } /* FALLTHROUGH */ case OMP_CLAUSE_DEPEND: diff --git a/gcc/c/c-tree.h b/gcc/c/c-tree.h index 444e9a4..b4374e3 100644 --- a/gcc/c/c-tree.h +++ b/gcc/c/c-tree.h @@ -614,7 +614,7 @@ extern struct c_expr convert_lvalue_to_rvalue (location_t, struct c_expr, bool, bool); extern void mark_exp_read (tree); extern tree composite_type (tree, tree); -extern tree build_component_ref (location_t, tree, tree); +extern tree build_component_ref (location_t, tree, tree, location_t); extern tree build_array_ref (location_t, tree, tree); extern tree build_external_ref (location_t, tree, int, tree *); extern void pop_maybe_used (bool); diff --git a/gcc/c/c-typeck.c b/gcc/c/c-typeck.c index cee566f..cd8e9e5 100644 --- a/gcc/c/c-typeck.c +++ b/gcc/c/c-typeck.c @@ -2329,10 +2329,12 @@ should_suggest_deref_p (tree datum_type) /* Make an expression to refer to the COMPONENT field of structure or union value DATUM. COMPONENT is an IDENTIFIER_NODE. LOC is the - location of the COMPONENT_REF. */ + location of the COMPONENT_REF. COMPONENT_LOC is the location + of COMPONENT. */ tree -build_component_ref (location_t loc, tree datum, tree component) +build_component_ref (location_t loc, tree datum, tree component, + location_t component_loc) { tree type = TREE_TYPE (datum); enum tree_code code = TREE_CODE (type); @@ -2364,8 +2366,24 @@ build_component_ref (location_t loc, tree datum, tree component) { tree guessed_id = lookup_field_fuzzy (type, component); if (guessed_id) - error_at (loc, "%qT has no member named %qE; did you mean %qE?", - type, component, guessed_id); + { + /* Attempt to provide a fixit replacement hint, if + we have a valid range for the component. */ + location_t reported_loc + = (component_loc != UNKNOWN_LOCATION) ? component_loc : loc; + rich_location rich_loc (line_table, reported_loc); + if (component_loc != UNKNOWN_LOCATION) + { + source_range component_range = + get_range_from_loc (line_table, component_loc); + rich_loc.add_fixit_replace (component_range, + IDENTIFIER_POINTER (guessed_id)); + } + error_at_rich_loc + (&rich_loc, + "%qT has no member named %qE; did you mean %qE?", + type, component, guessed_id); + } else error_at (loc, "%qT has no member named %qE", type, component); return error_mark_node; |