Commit 72a93143 by Jason Merrill Committed by Jason Merrill

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
parent 64b7869a
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> 1998-11-22 Jason Merrill <jason@yorick.cygnus.com>
* decl.c: Lose warn_about_return_type. * decl.c: Lose warn_about_return_type.
......
...@@ -3669,23 +3669,24 @@ finish_struct_1 (t, warn_anon) ...@@ -3669,23 +3669,24 @@ finish_struct_1 (t, warn_anon)
x, TREE_TYPE (x)); x, TREE_TYPE (x));
} }
if (DECL_INITIAL (x) == NULL_TREE) if (DECL_INITIAL (x))
;
else if (width == 0)
{ {
DECL_INITIAL (x) = NULL_TREE;
DECL_FIELD_SIZE (x) = width;
DECL_BIT_FIELD (x) = 1;
if (width == 0)
{
#ifdef EMPTY_FIELD_BOUNDARY #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 #endif
#ifdef PCC_BITFIELD_TYPE_MATTERS #ifdef PCC_BITFIELD_TYPE_MATTERS
DECL_ALIGN (x) = MAX (DECL_ALIGN (x), if (PCC_BITFIELD_TYPE_MATTERS)
TYPE_ALIGN (TREE_TYPE (x))); DECL_ALIGN (x) = MAX (DECL_ALIGN (x),
TYPE_ALIGN (TREE_TYPE (x)));
#endif #endif
} }
else
{
DECL_INITIAL (x) = NULL_TREE;
DECL_FIELD_SIZE (x) = width;
DECL_BIT_FIELD (x) = 1;
} }
} }
else else
......
...@@ -2706,6 +2706,7 @@ extern int init_type_desc PROTO((void)); ...@@ -2706,6 +2706,7 @@ extern int init_type_desc PROTO((void));
extern tree define_function extern tree define_function
PROTO((char *, tree, enum built_in_function, PROTO((char *, tree, enum built_in_function,
void (*) (tree), char *)); void (*) (tree), char *));
extern tree check_tag_decl PROTO((tree));
extern void shadow_tag PROTO((tree)); extern void shadow_tag PROTO((tree));
extern tree groktypename PROTO((tree)); extern tree groktypename PROTO((tree));
extern tree start_decl PROTO((tree, tree, int, tree, tree)); extern tree start_decl PROTO((tree, tree, int, tree, tree));
......
...@@ -6452,41 +6452,33 @@ fixup_anonymous_union (t) ...@@ -6452,41 +6452,33 @@ fixup_anonymous_union (t)
error ("an anonymous union cannot have function members"); error ("an anonymous union cannot have function members");
} }
/* Called when a declaration is seen that contains no names to declare. /* Make sure that a declaration with no declarator is well-formed, i.e.
If its type is a reference to a structure, union or enum inherited just defines a tagged type or anonymous union.
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, Returns the type defined, if any. */
complain for anonymous unions. */
void tree
shadow_tag (declspecs) check_tag_decl (declspecs)
tree declspecs; tree declspecs;
{ {
int found_tag = 0; int found_type = 0;
tree ob_modifier = NULL_TREE; tree ob_modifier = NULL_TREE;
register tree link; register tree link;
register enum tree_code code, ok_code = ERROR_MARK;
register tree t = NULL_TREE; register tree t = NULL_TREE;
for (link = declspecs; link; link = TREE_CHAIN (link)) for (link = declspecs; link; link = TREE_CHAIN (link))
{ {
register tree value = TREE_VALUE (link); register tree value = TREE_VALUE (link);
code = TREE_CODE (value); if (TYPE_P (value))
if (IS_AGGR_TYPE_CODE (code) || code == ENUMERAL_TYPE)
{ {
my_friendly_assert (TYPE_MAIN_DECL (value) != NULL_TREE, 261); ++found_type;
maybe_process_partial_specialization (value);
t = value; if (IS_AGGR_TYPE (value) || TREE_CODE (value) == ENUMERAL_TYPE)
ok_code = code; {
found_tag++; my_friendly_assert (TYPE_MAIN_DECL (value) != NULL_TREE, 261);
t = value;
}
} }
else if (value == ridpointers[(int) RID_STATIC] else if (value == ridpointers[(int) RID_STATIC]
|| value == ridpointers[(int) RID_EXTERN] || value == ridpointers[(int) RID_EXTERN]
...@@ -6494,31 +6486,22 @@ shadow_tag (declspecs) ...@@ -6494,31 +6486,22 @@ shadow_tag (declspecs)
|| value == ridpointers[(int) RID_REGISTER] || value == ridpointers[(int) RID_REGISTER]
|| value == ridpointers[(int) RID_INLINE] || value == ridpointers[(int) RID_INLINE]
|| value == ridpointers[(int) RID_VIRTUAL] || 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]) || value == ridpointers[(int) RID_EXPLICIT])
ob_modifier = value; ob_modifier = value;
} }
/* This is where the variables in an anonymous union are if (found_type > 1)
declared. An anonymous union declaration looks like: error ("multiple types in one declaration");
union { ... } ;
because there is no declarator after the union, the parser if (t == NULL_TREE)
sends that declaration here. */ pedwarn ("declaration does not declare anything");
if (ok_code == UNION_TYPE else if (ANON_UNION_TYPE_P (t))
&& t != NULL_TREE return t;
&& ((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);
}
}
else else
{ {
/* Anonymous unions are objects, that's why we only check for /* Anonymous unions are objects, that's why we only check for
...@@ -6529,6 +6512,8 @@ shadow_tag (declspecs) ...@@ -6529,6 +6512,8 @@ shadow_tag (declspecs)
if (ob_modifier == ridpointers[(int) RID_INLINE] if (ob_modifier == ridpointers[(int) RID_INLINE]
|| ob_modifier == ridpointers[(int) RID_VIRTUAL]) || ob_modifier == ridpointers[(int) RID_VIRTUAL])
cp_error ("`%D' can only be specified for functions", ob_modifier); 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]) else if (ob_modifier == ridpointers[(int) RID_EXPLICIT])
cp_error ("`%D' can only be specified for constructors", cp_error ("`%D' can only be specified for constructors",
ob_modifier); ob_modifier);
...@@ -6536,11 +6521,46 @@ shadow_tag (declspecs) ...@@ -6536,11 +6521,46 @@ shadow_tag (declspecs)
cp_error ("`%D' can only be specified for objects and functions", cp_error ("`%D' can only be specified for objects and functions",
ob_modifier); ob_modifier);
} }
}
if (found_tag == 0) return t;
cp_error ("abstract declarator used as declaration"); }
else if (found_tag > 1)
pedwarn ("multiple types in one declaration"); /* 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) ...@@ -10761,9 +10781,9 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
type)) type))
/* If we just return the declaration, crashes /* If we just return the declaration, crashes
will sometimes occur. We therefore return will sometimes occur. We therefore return
void_type_node, as if this was a friend void_type_node, as if this was a friend
declaration, to cause callers to completely declaration, to cause callers to completely
ignore this declaration. */ ignore this declaration. */
return void_type_node; return void_type_node;
} }
......
...@@ -858,17 +858,14 @@ grok_x_components (specs) ...@@ -858,17 +858,14 @@ grok_x_components (specs)
struct pending_inline **p; struct pending_inline **p;
tree t; tree t;
t = groktypename (build_decl_list (strip_attrs (specs), NULL_TREE)); specs = strip_attrs (specs);
if (t == NULL_TREE) check_tag_decl (specs);
{ t = groktypename (build_decl_list (specs, NULL_TREE));
cp_error ("invalid member declaration");
return;
}
/* The only case where we need to do anything additional here is an /* The only case where we need to do anything additional here is an
anonymous union field, e.g.: `struct S { union { int i; }; };'. */ 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; return;
fixup_anonymous_union (t); fixup_anonymous_union (t);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment