diff options
author | jsm28 <jsm28@138bc75d-0d04-0410-961f-82ee72b054a4> | 2004-10-14 00:34:01 +0000 |
---|---|---|
committer | jsm28 <jsm28@138bc75d-0d04-0410-961f-82ee72b054a4> | 2004-10-14 00:34:01 +0000 |
commit | 19702c1d34daddd799073407407ff47a44d0084c (patch) | |
tree | d480ea1c4408842eab54602e3d430ca39cc2a0b7 /gcc/c-decl.c | |
parent | a86d7a65a99e943f5cd93f16e1d8b8b9c31ff1b1 (diff) | |
download | gcc-19702c1d34daddd799073407407ff47a44d0084c.tar.gz |
* c-tree.h (enum c_typespec_kind, struct c_typespec,
parser_xref_tag): New.
(struct c_declspecs): Add tag_defined_p. Adjust definition of
typedef_p.
(declspecs_add_type): Adjust prototypes.
* c-parse.in (%union): Add tstype.
(typespec_nonattr, typespec_attr, typespec_reserved_nonattr,
typespec_reserved_attr, typespec_nonreserved_nonattr,
structsp_attr, structsp_nonattr): Change to tstype. Update
actions.
* c-decl.c (build_null_declspecs): Initialize tag_defined_p.
(declspecs_add_type): Update to take struct c_typespec argument.
Set tag_defined_p and typedef_p as appropriate.
(xref_tag): Rename to parser_xref_tag and replace by wrapper.
Update to return struct c_typespec.
(shadow_tag_warned): Don't let empty declarations with qualifiers
or storage class specifiers redeclare a tag if a previous
declaration is visible.
testsuite:
* gcc.dg/c99-tag-3.c, gcc.dg/declspec-14.c: New tests.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@89021 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/c-decl.c')
-rw-r--r-- | gcc/c-decl.c | 64 |
1 files changed, 55 insertions, 9 deletions
diff --git a/gcc/c-decl.c b/gcc/c-decl.c index b548f850dd3..30a154cd996 100644 --- a/gcc/c-decl.c +++ b/gcc/c-decl.c @@ -2696,8 +2696,6 @@ shadow_tag_warned (const struct c_declspecs *declspecs, int warned) { bool found_tag = false; - pending_invalid_xref = 0; - if (declspecs->type && !declspecs->default_int_p && !declspecs->typedef_p) { tree value = declspecs->type; @@ -2721,8 +2719,29 @@ shadow_tag_warned (const struct c_declspecs *declspecs, int warned) warned = 1; } } + else if (!declspecs->tag_defined_p + && declspecs->storage_class != csc_none) + { + if (warned != 1) + pedwarn ("empty declaration with storage class specifier " + "does not redeclare tag"); + warned = 1; + pending_xref_error (); + } + else if (!declspecs->tag_defined_p + && (declspecs->const_p + || declspecs->volatile_p + || declspecs->restrict_p)) + { + if (warned != 1) + pedwarn ("empty declaration with type qualifier " + "does not redeclare tag"); + warned = 1; + pending_xref_error (); + } else { + pending_invalid_xref = 0; t = lookup_tag (code, name, 1); if (t == 0) @@ -2747,6 +2766,8 @@ shadow_tag_warned (const struct c_declspecs *declspecs, int warned) warned = 1; } + pending_invalid_xref = 0; + if (declspecs->inline_p) { error ("%<inline%> in empty declaration"); @@ -4877,11 +4898,13 @@ get_parm_info (bool ellipsis) } /* Get the struct, enum or union (CODE says which) with tag NAME. - Define the tag as a forward-reference if it is not defined. */ + Define the tag as a forward-reference if it is not defined. + Return a c_typespec structure for the type specifier. */ -tree -xref_tag (enum tree_code code, tree name) +struct c_typespec +parser_xref_tag (enum tree_code code, tree name) { + struct c_typespec ret; /* If a cross reference is requested, look up the type already defined for this tag and return it. */ @@ -4897,8 +4920,12 @@ xref_tag (enum tree_code code, tree name) this would not work properly if we return the reference found. (For example, with "struct foo" in an outer scope, "union foo;" must shadow that tag with a new one of union type.) */ + ret.kind = (ref ? ctsk_tagref : ctsk_tagfirstref); if (ref && TREE_CODE (ref) == code) - return ref; + { + ret.spec = ref; + return ret; + } /* If no such tag is yet defined, create a forward-reference node and record it as the "definition". @@ -4921,7 +4948,18 @@ xref_tag (enum tree_code code, tree name) pushtag (name, ref); - return ref; + ret.spec = ref; + return ret; +} + +/* Get the struct, enum or union (CODE says which) with tag NAME. + Define the tag as a forward-reference if it is not defined. + Return a tree for the type. */ + +tree +xref_tag (enum tree_code code, tree name) +{ + return parser_xref_tag (code, name).spec; } /* Make sure that the tag NAME is defined *in the current scope* @@ -6643,6 +6681,7 @@ build_null_declspecs (void) ret->storage_class = csc_none; ret->non_sc_seen_p = false; ret->typedef_p = false; + ret->tag_defined_p = false; ret->explicit_signed_p = false; ret->deprecated_p = false; ret->default_int_p = false; @@ -6698,8 +6737,9 @@ declspecs_add_qual (struct c_declspecs *specs, tree qual) returning SPECS. */ struct c_declspecs * -declspecs_add_type (struct c_declspecs *specs, tree type) +declspecs_add_type (struct c_declspecs *specs, struct c_typespec spec) { + tree type = spec.spec; specs->non_sc_seen_p = true; if (TREE_DEPRECATED (type)) specs->deprecated_p = true; @@ -6975,7 +7015,13 @@ declspecs_add_type (struct c_declspecs *specs, tree type) specs->type = TREE_TYPE (t); } else if (TREE_CODE (type) != ERROR_MARK) - specs->type = type; + { + if (spec.kind == ctsk_tagdef || spec.kind == ctsk_tagfirstref) + specs->tag_defined_p = true; + if (spec.kind == ctsk_typeof) + specs->typedef_p = true; + specs->type = type; + } return specs; } |