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>
* decl.c: Lose warn_about_return_type.
......
......@@ -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
......
......@@ -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));
......
......@@ -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;
}
......
......@@ -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);
......
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