diff options
author | Jason Merrill <jason@yorick.cygnus.com> | 1998-11-23 01:14:55 +0000 |
---|---|---|
committer | Jason Merrill <jason@gcc.gnu.org> | 1998-11-22 20:14:55 -0500 |
commit | 72a931432542edeb7e222774af95942663e66ff2 (patch) | |
tree | 088be5fe665d74f30c3058b147464cb4006c1d4e /gcc | |
parent | 64b7869acb648286176938c866ad9cbd0d966893 (diff) | |
download | gcc-72a931432542edeb7e222774af95942663e66ff2.zip gcc-72a931432542edeb7e222774af95942663e66ff2.tar.gz gcc-72a931432542edeb7e222774af95942663e66ff2.tar.bz2 |
class.c (finish_struct_1): Set things up for 0-width bitfields like we do for others.
* class.c (finish_struct_1): Set things up for 0-width bitfields
like we do for others.
* decl.c (check_tag_decl): New fn.
(shadow_tag): Split out from here.
* decl2.c (grok_x_components): Call it.
From-SVN: r23762
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/cp/ChangeLog | 9 | ||||
-rw-r--r-- | gcc/cp/class.c | 25 | ||||
-rw-r--r-- | gcc/cp/cp-tree.h | 1 | ||||
-rw-r--r-- | gcc/cp/decl.c | 118 | ||||
-rw-r--r-- | gcc/cp/decl2.c | 13 |
5 files changed, 97 insertions, 69 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index bc99a43..9616c2c 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,12 @@ +1998-11-23 Jason Merrill <jason@yorick.cygnus.com> + + * class.c (finish_struct_1): Set things up for 0-width bitfields + like we do for others. + + * decl.c (check_tag_decl): New fn. + (shadow_tag): Split out from here. + * decl2.c (grok_x_components): Call it. + 1998-11-22 Jason Merrill <jason@yorick.cygnus.com> * decl.c: Lose warn_about_return_type. diff --git a/gcc/cp/class.c b/gcc/cp/class.c index 9ade201..17f728f 100644 --- a/gcc/cp/class.c +++ b/gcc/cp/class.c @@ -3669,23 +3669,24 @@ finish_struct_1 (t, warn_anon) x, TREE_TYPE (x)); } - if (DECL_INITIAL (x) == NULL_TREE) - ; - else if (width == 0) + if (DECL_INITIAL (x)) { + DECL_INITIAL (x) = NULL_TREE; + DECL_FIELD_SIZE (x) = width; + DECL_BIT_FIELD (x) = 1; + + if (width == 0) + { #ifdef EMPTY_FIELD_BOUNDARY - DECL_ALIGN (x) = MAX (DECL_ALIGN (x), EMPTY_FIELD_BOUNDARY); + DECL_ALIGN (x) = MAX (DECL_ALIGN (x), + EMPTY_FIELD_BOUNDARY); #endif #ifdef PCC_BITFIELD_TYPE_MATTERS - DECL_ALIGN (x) = MAX (DECL_ALIGN (x), - TYPE_ALIGN (TREE_TYPE (x))); + if (PCC_BITFIELD_TYPE_MATTERS) + DECL_ALIGN (x) = MAX (DECL_ALIGN (x), + TYPE_ALIGN (TREE_TYPE (x))); #endif - } - else - { - DECL_INITIAL (x) = NULL_TREE; - DECL_FIELD_SIZE (x) = width; - DECL_BIT_FIELD (x) = 1; + } } } else diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 340d992..4f2fccb 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -2706,6 +2706,7 @@ extern int init_type_desc PROTO((void)); extern tree define_function PROTO((char *, tree, enum built_in_function, void (*) (tree), char *)); +extern tree check_tag_decl PROTO((tree)); extern void shadow_tag PROTO((tree)); extern tree groktypename PROTO((tree)); extern tree start_decl PROTO((tree, tree, int, tree, tree)); diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index 9611b0d..cacdf05 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -6452,41 +6452,33 @@ fixup_anonymous_union (t) error ("an anonymous union cannot have function members"); } -/* Called when a declaration is seen that contains no names to declare. - If its type is a reference to a structure, union or enum inherited - from a containing scope, shadow that tag name for the current scope - with a forward reference. - If its type defines a new named structure or union - or defines an enum, it is valid but we need not do anything here. - Otherwise, it is an error. +/* Make sure that a declaration with no declarator is well-formed, i.e. + just defines a tagged type or anonymous union. - C++: may have to grok the declspecs to learn about static, - complain for anonymous unions. */ + Returns the type defined, if any. */ -void -shadow_tag (declspecs) +tree +check_tag_decl (declspecs) tree declspecs; { - int found_tag = 0; + int found_type = 0; tree ob_modifier = NULL_TREE; register tree link; - register enum tree_code code, ok_code = ERROR_MARK; register tree t = NULL_TREE; for (link = declspecs; link; link = TREE_CHAIN (link)) { register tree value = TREE_VALUE (link); - code = TREE_CODE (value); - if (IS_AGGR_TYPE_CODE (code) || code == ENUMERAL_TYPE) + if (TYPE_P (value)) { - my_friendly_assert (TYPE_MAIN_DECL (value) != NULL_TREE, 261); - - maybe_process_partial_specialization (value); + ++found_type; - t = value; - ok_code = code; - found_tag++; + if (IS_AGGR_TYPE (value) || TREE_CODE (value) == ENUMERAL_TYPE) + { + my_friendly_assert (TYPE_MAIN_DECL (value) != NULL_TREE, 261); + t = value; + } } else if (value == ridpointers[(int) RID_STATIC] || value == ridpointers[(int) RID_EXTERN] @@ -6494,31 +6486,22 @@ shadow_tag (declspecs) || value == ridpointers[(int) RID_REGISTER] || value == ridpointers[(int) RID_INLINE] || value == ridpointers[(int) RID_VIRTUAL] + || (value == ridpointers[(int) RID_FRIEND] + && (current_class_type == NULL_TREE + || current_scope () != current_class_type)) + || value == ridpointers[(int) RID_CONST] + || value == ridpointers[(int) RID_VOLATILE] || value == ridpointers[(int) RID_EXPLICIT]) ob_modifier = value; } - /* This is where the variables in an anonymous union are - declared. An anonymous union declaration looks like: - union { ... } ; - because there is no declarator after the union, the parser - sends that declaration here. */ - if (ok_code == UNION_TYPE - && t != NULL_TREE - && ((TREE_CODE (TYPE_NAME (t)) == IDENTIFIER_NODE - && ANON_AGGRNAME_P (TYPE_NAME (t))) - || (TREE_CODE (TYPE_NAME (t)) == TYPE_DECL - && ANON_AGGRNAME_P (TYPE_IDENTIFIER (t))))) - { - fixup_anonymous_union (t); - - if (TYPE_FIELDS (t)) - { - tree decl = grokdeclarator (NULL_TREE, declspecs, NORMAL, 0, - NULL_TREE); - finish_anon_union (decl); - } - } + if (found_type > 1) + error ("multiple types in one declaration"); + + if (t == NULL_TREE) + pedwarn ("declaration does not declare anything"); + else if (ANON_UNION_TYPE_P (t)) + return t; else { /* Anonymous unions are objects, that's why we only check for @@ -6529,6 +6512,8 @@ shadow_tag (declspecs) if (ob_modifier == ridpointers[(int) RID_INLINE] || ob_modifier == ridpointers[(int) RID_VIRTUAL]) cp_error ("`%D' can only be specified for functions", ob_modifier); + else if (ob_modifier == ridpointers[(int) RID_FRIEND]) + cp_error ("`%D' can only be specified inside a class", ob_modifier); else if (ob_modifier == ridpointers[(int) RID_EXPLICIT]) cp_error ("`%D' can only be specified for constructors", ob_modifier); @@ -6536,11 +6521,46 @@ shadow_tag (declspecs) cp_error ("`%D' can only be specified for objects and functions", ob_modifier); } + } - if (found_tag == 0) - cp_error ("abstract declarator used as declaration"); - else if (found_tag > 1) - pedwarn ("multiple types in one declaration"); + return t; +} + +/* Called when a declaration is seen that contains no names to declare. + If its type is a reference to a structure, union or enum inherited + from a containing scope, shadow that tag name for the current scope + with a forward reference. + If its type defines a new named structure or union + or defines an enum, it is valid but we need not do anything here. + Otherwise, it is an error. + + C++: may have to grok the declspecs to learn about static, + complain for anonymous unions. */ + +void +shadow_tag (declspecs) + tree declspecs; +{ + tree t = check_tag_decl (declspecs); + + if (t) + maybe_process_partial_specialization (t); + + /* This is where the variables in an anonymous union are + declared. An anonymous union declaration looks like: + union { ... } ; + because there is no declarator after the union, the parser + sends that declaration here. */ + if (t && ANON_UNION_TYPE_P (t)) + { + fixup_anonymous_union (t); + + if (TYPE_FIELDS (t)) + { + tree decl = grokdeclarator (NULL_TREE, declspecs, NORMAL, 0, + NULL_TREE); + finish_anon_union (decl); + } } } @@ -10761,9 +10781,9 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist) type)) /* If we just return the declaration, crashes will sometimes occur. We therefore return - void_type_node, as if this was a friend - declaration, to cause callers to completely - ignore this declaration. */ + void_type_node, as if this was a friend + declaration, to cause callers to completely + ignore this declaration. */ return void_type_node; } diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c index 79025a5..bd09eba 100644 --- a/gcc/cp/decl2.c +++ b/gcc/cp/decl2.c @@ -858,17 +858,14 @@ grok_x_components (specs) struct pending_inline **p; tree t; - t = groktypename (build_decl_list (strip_attrs (specs), NULL_TREE)); - - if (t == NULL_TREE) - { - cp_error ("invalid member declaration"); - return; - } + specs = strip_attrs (specs); + + check_tag_decl (specs); + t = groktypename (build_decl_list (specs, NULL_TREE)); /* The only case where we need to do anything additional here is an anonymous union field, e.g.: `struct S { union { int i; }; };'. */ - if (!ANON_UNION_TYPE_P (t)) + if (t == NULL_TREE || !ANON_UNION_TYPE_P (t)) return; fixup_anonymous_union (t); |