diff options
author | Ziemowit Laski <zlaski@apple.com> | 2005-07-27 02:11:42 +0000 |
---|---|---|
committer | Ziemowit Laski <zlaski@apple.com> | 2005-07-27 02:11:42 +0000 |
commit | 1d8533a4f6f2a587d2a6deae8dc783f0a22dce7f (patch) | |
tree | 23437196f9106f136bf76bd674aaa34b7be3c113 /gcc/cp/decl.c | |
parent | 2a04bbde99a3cdab02ded5766f48fb72c096dc5a (diff) |
[gcc/cp/ChangeLog.apple-ppc]
2005-07-26 Ziemowit Laski <zlaski@apple.com>
Radar 4168392
* decl.c (check_tag_decl): In '-fms-extensions' mode,
turn anonymous fields of aggregate (struct or union) type
into anonymous aggregates. For structs, issue a warning
if in '-pedantic' mode.
[gcc/testsuite/ChangeLog.apple-ppc]
2005-07-26 Ziemowit Laski <zlaski@apple.com>
Radar 4168392
* g++.dg/ext/anon-struct3.C: Anonymous aggregate fields
may use typedefs.
* g++.dg/ext/apple-r4168392.C: New.
* gcc.dg/apple-r4168392.c: New.
git-svn-id: https://gcc.gnu.org/svn/gcc/branches/apple-local-200502-branch@102413 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/cp/decl.c')
-rw-r--r-- | gcc/cp/decl.c | 60 |
1 files changed, 58 insertions, 2 deletions
diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index f928ece442c..bfd937951a1 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -3498,7 +3498,52 @@ check_tag_decl (cp_decl_specifier_seq *declspecs) else if (declspecs->type == error_mark_node) error_p = true; if (declared_type == NULL_TREE && ! saw_friend && !error_p) - pedwarn ("declaration does not declare anything"); + /* APPLE LOCAL begin 4168392 */ + { + /* If '-fms-extensions' is on and the compiler encounters an anonymous + field declaration like + + T; + + where T denotes a struct, class or union type, we transform it to + an anonymous struct/union like + + struct/union { + <fields from T> + }; + + that the rest of C++ already knows how to handle. */ + if (flag_ms_extensions && current_class_type && DECL_P (declspecs->type) + && IS_AGGR_TYPE_CODE (TREE_CODE (TREE_TYPE (declspecs->type)))) + { + tree fields, field; + + declared_type + = make_aggr_type (TREE_CODE (TREE_TYPE (declspecs->type))); + SET_IS_AGGR_TYPE (declared_type, 1); + TYPE_CONTEXT (declared_type) = current_class_type; + xref_basetypes (declared_type, NULL_TREE); + fields + = nreverse (copy_list (TYPE_FIELDS (TREE_TYPE (declspecs->type)))); + + for (field = fields; field; field = TREE_CHAIN (field)) + { + if (TREE_CODE (field) == TYPE_DECL) + fields = TREE_CHAIN (field); + else + DECL_CONTEXT (field) = NULL_TREE; + } + + finish_builtin_struct (declared_type, + IDENTIFIER_POINTER (make_anon_name ()), + fields, TREE_TYPE (declspecs->type)); + + goto finish_anon_aggr; + } + + pedwarn ("declaration does not declare anything"); + } + /* APPLE LOCAL end 4168392 */ /* Check for an anonymous union. */ else if (declared_type && IS_AGGR_TYPE_CODE (TREE_CODE (declared_type)) && TYPE_ANONYMOUS_P (declared_type)) @@ -3524,12 +3569,23 @@ check_tag_decl (cp_decl_specifier_seq *declspecs) error ("missing type-name in typedef-declaration"); return NULL_TREE; } + /* APPLE LOCAL begin 4168392 */ + + finish_anon_aggr: + /* APPLE LOCAL end 4168392 */ /* Anonymous unions are objects, so they can have specifiers. */; SET_ANON_AGGR_TYPE_P (declared_type); if (TREE_CODE (declared_type) != UNION_TYPE && pedantic && !in_system_header) - pedwarn ("ISO C++ prohibits anonymous structs"); + /* APPLE LOCAL begin 4168392 */ + { + if (flag_ms_extensions) + warning ("ISO C++ prohibits anonymous structs"); + else + pedwarn ("ISO C++ prohibits anonymous structs"); + } + /* APPLE LOCAL end 4168392 */ } else |