aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJason Merrill <jason@yorick.cygnus.com>1998-11-23 01:14:55 +0000
committerJason Merrill <jason@gcc.gnu.org>1998-11-22 20:14:55 -0500
commit72a931432542edeb7e222774af95942663e66ff2 (patch)
tree088be5fe665d74f30c3058b147464cb4006c1d4e /gcc
parent64b7869acb648286176938c866ad9cbd0d966893 (diff)
downloadgcc-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/ChangeLog9
-rw-r--r--gcc/cp/class.c25
-rw-r--r--gcc/cp/cp-tree.h1
-rw-r--r--gcc/cp/decl.c118
-rw-r--r--gcc/cp/decl2.c13
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);