aboutsummaryrefslogtreecommitdiff
path: root/gcc/c
diff options
context:
space:
mode:
authorMarek Polacek <polacek@redhat.com>2015-09-15 17:19:11 +0000
committerMarek Polacek <mpolacek@gcc.gnu.org>2015-09-15 17:19:11 +0000
commit0e36f5c7c103e2d897fcbc9728fa98768b386f9a (patch)
treeea4ad4601177b57e46c4c68bebdfb4668db9e541 /gcc/c
parentc33c18cdc6b29a312464cb16996530b47a333c98 (diff)
downloadgcc-0e36f5c7c103e2d897fcbc9728fa98768b386f9a.zip
gcc-0e36f5c7c103e2d897fcbc9728fa98768b386f9a.tar.gz
gcc-0e36f5c7c103e2d897fcbc9728fa98768b386f9a.tar.bz2
re PR c/67580 (Improve error message on missing "struct" tag)
PR c/67580 * c-decl.c (tag_exists_p): New function. * c-parser.c (c_parser_declaration_or_fndef): Give a hint when struct/union/enum keywords are missing. * c-tree.h (tag_exists_p): Declare. * gcc.dg/pr67580.c: New test. From-SVN: r227803
Diffstat (limited to 'gcc/c')
-rw-r--r--gcc/c/ChangeLog8
-rw-r--r--gcc/c/c-decl.c12
-rw-r--r--gcc/c/c-parser.c12
-rw-r--r--gcc/c/c-tree.h1
4 files changed, 31 insertions, 2 deletions
diff --git a/gcc/c/ChangeLog b/gcc/c/ChangeLog
index 37124b3..27659e2 100644
--- a/gcc/c/ChangeLog
+++ b/gcc/c/ChangeLog
@@ -1,5 +1,13 @@
2015-09-15 Marek Polacek <polacek@redhat.com>
+ PR c/67580
+ * c-decl.c (tag_exists_p): New function.
+ * c-parser.c (c_parser_declaration_or_fndef): Give a hint when
+ struct/union/enum keywords are missing.
+ * c-tree.h (tag_exists_p): Declare.
+
+2015-09-15 Marek Polacek <polacek@redhat.com>
+
* c-decl.c (lookup_label): Return NULL_TREE instead of 0.
(lookup_tag): Change the type of THISLEVEL_ONLY to bool.
Return NULL_TREE instead of 0.
diff --git a/gcc/c/c-decl.c b/gcc/c/c-decl.c
index 989ff99..a110226 100644
--- a/gcc/c/c-decl.c
+++ b/gcc/c/c-decl.c
@@ -3856,6 +3856,18 @@ lookup_tag (enum tree_code code, tree name, bool thislevel_only,
return b->decl;
}
+/* Return true if a definition exists for NAME with code CODE. */
+
+bool
+tag_exists_p (enum tree_code code, tree name)
+{
+ struct c_binding *b = I_TAG_BINDING (name);
+
+ if (b == NULL || b->decl == NULL_TREE)
+ return false;
+ return TREE_CODE (b->decl) == code;
+}
+
/* Print an error message now
for a recent invalid struct, union or enum cross reference.
We don't print them immediately because they are not invalid
diff --git a/gcc/c/c-parser.c b/gcc/c/c-parser.c
index 4d9cbe0..d5de102 100644
--- a/gcc/c/c-parser.c
+++ b/gcc/c/c-parser.c
@@ -1539,8 +1539,16 @@ c_parser_declaration_or_fndef (c_parser *parser, bool fndef_ok,
|| c_parser_peek_2nd_token (parser)->type == CPP_MULT)
&& (!nested || !lookup_name (c_parser_peek_token (parser)->value)))
{
- error_at (here, "unknown type name %qE",
- c_parser_peek_token (parser)->value);
+ tree name = c_parser_peek_token (parser)->value;
+ error_at (here, "unknown type name %qE", name);
+ /* Give a hint to the user. This is not C++ with its implicit
+ typedef. */
+ if (tag_exists_p (RECORD_TYPE, name))
+ inform (here, "use %<struct%> keyword to refer to the type");
+ else if (tag_exists_p (UNION_TYPE, name))
+ inform (here, "use %<union%> keyword to refer to the type");
+ else if (tag_exists_p (ENUMERAL_TYPE, name))
+ inform (here, "use %<enum%> keyword to refer to the type");
/* Parse declspecs normally to get a correct pointer type, but avoid
a further "fails to be a type name" error. Refuse nested functions
diff --git a/gcc/c/c-tree.h b/gcc/c/c-tree.h
index a3979dd..667529a 100644
--- a/gcc/c/c-tree.h
+++ b/gcc/c/c-tree.h
@@ -701,6 +701,7 @@ extern tree c_omp_reduction_lookup (tree, tree);
extern tree c_check_omp_declare_reduction_r (tree *, int *, void *);
extern void c_pushtag (location_t, tree, tree);
extern void c_bind (location_t, tree, bool);
+extern bool tag_exists_p (enum tree_code, tree);
/* In c-errors.c */
extern void pedwarn_c90 (location_t, int opt, const char *, ...)