diff options
-rw-r--r-- | gcc/cp/ChangeLog | 12 | ||||
-rw-r--r-- | gcc/cp/cp-tree.h | 11 | ||||
-rw-r--r-- | gcc/cp/decl.c | 37 | ||||
-rw-r--r-- | gcc/cp/lex.c | 2 | ||||
-rw-r--r-- | gcc/cp/pt.c | 2 | ||||
-rw-r--r-- | gcc/cp/semantics.c | 16 | ||||
-rw-r--r-- | gcc/cp/tree.c | 2 | ||||
-rw-r--r-- | gcc/testsuite/g++.old-deja/g++.other/anon9.C | 5 |
8 files changed, 53 insertions, 34 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 634c8cf..c26c7f5 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,15 @@ +2001-04-11 Jason Merrill <jason_merrill@redhat.com> + + * cp-tree.h (TYPE_LINKAGE_IDENTIFIER): New macro. + (TYPE_ANONYMOUS_P): New macro. + (TAGGED_TYPE_P): New macro. + * decl.c (check_tag_decl): Use TYPE_ANONYMOUS_P. + (grokfndecl, grokvardecl, grokdeclarator): Likewise. + * tree.c (no_linkage_helper): Likewise. + * semantics.c (begin_class_definition): Likewise. + * pt.c (convert_template_argument): Likewise. + * lex.c (check_for_missing_semicolon): Likewise. + 2001-04-12 Nathan Sidwell <nathan@codesourcery.com> * class.c (dfs_unshared_virtual_bases): New function. diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 77a12f6..5a8a3ba 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -1163,12 +1163,18 @@ enum languages { lang_c, lang_cplusplus, lang_java }; /* Macros to make error reporting functions' lives easier. */ #define TYPE_IDENTIFIER(NODE) (DECL_NAME (TYPE_NAME (NODE))) +#define TYPE_LINKAGE_IDENTIFIER(NODE) \ + (TYPE_IDENTIFIER (TYPE_MAIN_VARIANT (NODE))) #define TYPE_NAME_STRING(NODE) (IDENTIFIER_POINTER (TYPE_IDENTIFIER (NODE))) #define TYPE_NAME_LENGTH(NODE) (IDENTIFIER_LENGTH (TYPE_IDENTIFIER (NODE))) #define TYPE_ASSEMBLER_NAME_STRING(NODE) (IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (TYPE_NAME (NODE)))) #define TYPE_ASSEMBLER_NAME_LENGTH(NODE) (IDENTIFIER_LENGTH (DECL_ASSEMBLER_NAME (TYPE_NAME (NODE)))) +/* Nonzero if NODE has no name for linkage purposes. */ +#define TYPE_ANONYMOUS_P(NODE) \ + (TAGGED_TYPE_P (NODE) && ANON_AGGRNAME_P (TYPE_LINKAGE_IDENTIFIER (NODE))) + /* The _DECL for this _TYPE. */ #define TYPE_MAIN_DECL(NODE) (TYPE_STUB_DECL (TYPE_MAIN_VARIANT (NODE))) @@ -1198,8 +1204,9 @@ enum languages { lang_c, lang_cplusplus, lang_java }; #define IS_AGGR_TYPE_2(TYPE1,TYPE2) \ (TREE_CODE (TYPE1) == TREE_CODE (TYPE2) \ && IS_AGGR_TYPE (TYPE1) && IS_AGGR_TYPE (TYPE2)) -#define IS_OVERLOAD_TYPE(t) \ - (IS_AGGR_TYPE (t) || TREE_CODE (t) == ENUMERAL_TYPE) +#define TAGGED_TYPE_P(t) \ + (CLASS_TYPE_P (t) || TREE_CODE (t) == ENUMERAL_TYPE) +#define IS_OVERLOAD_TYPE(T) TAGGED_TYPE_P (T) /* In a *_TYPE, nonzero means a built-in type. */ #define TYPE_BUILT_IN(NODE) TYPE_LANG_FLAG_6(NODE) diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index ff8a819..0e97ad1 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -2873,6 +2873,7 @@ pushtag (name, type, globalize) else d = pushdecl_with_scope (d, b); + /* FIXME what if it gets a name from typedef? */ if (ANON_AGGRNAME_P (name)) DECL_IGNORED_P (d) = 1; @@ -6972,12 +6973,9 @@ check_tag_decl (declspecs) if (t == NULL_TREE && ! saw_friend) pedwarn ("declaration does not declare anything"); - /* Check for an anonymous union. We're careful - accessing TYPE_IDENTIFIER because some built-in types, like - pointer-to-member types, do not have TYPE_NAME. */ + /* Check for an anonymous union. */ else if (t && IS_AGGR_TYPE_CODE (TREE_CODE (t)) - && TYPE_NAME (t) - && ANON_AGGRNAME_P (TYPE_IDENTIFIER (t))) + && TYPE_ANONYMOUS_P (t)) { /* 7/3 In a simple-declaration, the optional init-declarator-list can be omitted only when declaring a class (clause 9) or @@ -8733,17 +8731,11 @@ grokfndecl (ctype, type, declarator, orig_declarator, virtualp, flags, quals, int check, friendp, publicp, inlinep, funcdef_flag, template_count; tree in_namespace; { - tree cname, decl; + tree decl; int staticp = ctype && TREE_CODE (type) == FUNCTION_TYPE; int has_default_arg = 0; tree t; - if (ctype) - cname = TREE_CODE (TYPE_NAME (ctype)) == TYPE_DECL - ? TYPE_IDENTIFIER (ctype) : TYPE_NAME (ctype); - else - cname = NULL_TREE; - if (raises) { type = build_exception_variant (type, raises); @@ -8799,7 +8791,8 @@ grokfndecl (ctype, type, declarator, orig_declarator, virtualp, flags, quals, /* Members of anonymous types and local classes have no linkage; make them internal. */ - if (ctype && (ANON_AGGRNAME_P (TYPE_IDENTIFIER (ctype)) + /* FIXME what if it gets a name from typedef? */ + if (ctype && (TYPE_ANONYMOUS_P (ctype) || decl_function_context (TYPE_MAIN_DECL (ctype)))) publicp = 0; @@ -8813,13 +8806,19 @@ grokfndecl (ctype, type, declarator, orig_declarator, virtualp, flags, quals, t = no_linkage_check (TREE_TYPE (decl)); if (t) { - if (ANON_AGGRNAME_P (TYPE_IDENTIFIER (t))) + if (TYPE_ANONYMOUS_P (t)) { if (DECL_EXTERN_C_P (decl)) /* Allow this; it's pretty common in C. */; else - cp_pedwarn ("non-local function `%#D' uses anonymous type", - decl); + { + cp_pedwarn ("non-local function `%#D' uses anonymous type", + decl); + if (DECL_ORIGINAL_TYPE (TYPE_NAME (t))) + cp_pedwarn_at ("\ +`%#D' does not refer to the unqualified type, so it is not used for linkage", + TYPE_NAME (t)); + } } else cp_pedwarn ("non-local function `%#D' uses local type `%T'", @@ -8931,7 +8930,7 @@ grokfndecl (ctype, type, declarator, orig_declarator, virtualp, flags, quals, if (check < 0) return decl; - if (flags == NO_SPECIAL && ctype && constructor_name (cname) == declarator) + if (flags == NO_SPECIAL && ctype && constructor_name (ctype) == declarator) DECL_CONSTRUCTOR_P (decl) = 1; /* Function gets the ugly name, field gets the nice one. This call @@ -9095,7 +9094,7 @@ grokvardecl (type, declarator, specbits_in, initialized, constp, in_namespace) tree t = no_linkage_check (TREE_TYPE (decl)); if (t) { - if (ANON_AGGRNAME_P (TYPE_IDENTIFIER (t))) + if (TYPE_ANONYMOUS_P (t)) /* Ignore for now; `enum { foo } e' is pretty common. */; else cp_pedwarn ("non-local variable `%#D' uses local type `%T'", @@ -11037,7 +11036,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist) && declarator && TYPE_NAME (type) && TREE_CODE (TYPE_NAME (type)) == TYPE_DECL - && ANON_AGGRNAME_P (TYPE_IDENTIFIER (type)) + && TYPE_ANONYMOUS_P (type) && CP_TYPE_QUALS (type) == TYPE_UNQUALIFIED) { tree oldname = TYPE_NAME (type); diff --git a/gcc/cp/lex.c b/gcc/cp/lex.c index ef9314c..5120f20 100644 --- a/gcc/cp/lex.c +++ b/gcc/cp/lex.c @@ -1011,7 +1011,7 @@ check_for_missing_semicolon (type) && yychar != SELFNAME) || yychar == 0 /* EOF */) { - if (ANON_AGGRNAME_P (TYPE_IDENTIFIER (type))) + if (TYPE_ANONYMOUS_P (type)) error ("semicolon missing after %s declaration", TREE_CODE (type) == ENUMERAL_TYPE ? "enum" : "struct"); else diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 24bdff4..ac88bec 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -3389,7 +3389,7 @@ convert_template_argument (parm, arg, args, complain, i, in_decl) tree t = no_linkage_check (val); if (t) { - if (ANON_AGGRNAME_P (TYPE_IDENTIFIER (t))) + if (TYPE_ANONYMOUS_P (t)) cp_pedwarn ("template-argument `%T' uses anonymous type", val); else diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c index 9295564..a6e13ec 100644 --- a/gcc/cp/semantics.c +++ b/gcc/cp/semantics.c @@ -1860,16 +1860,12 @@ begin_class_definition (t) /* Reset the interface data, at the earliest possible moment, as it might have been set via a class foo; before. */ - { - tree name = TYPE_IDENTIFIER (t); - - if (! ANON_AGGRNAME_P (name)) - { - CLASSTYPE_INTERFACE_ONLY (t) = interface_only; - SET_CLASSTYPE_INTERFACE_UNKNOWN_X - (t, interface_unknown); - } - } + if (! TYPE_ANONYMOUS_P (t)) + { + CLASSTYPE_INTERFACE_ONLY (t) = interface_only; + SET_CLASSTYPE_INTERFACE_UNKNOWN_X + (t, interface_unknown); + } reset_specialization(); /* Make a declaration for this class in its own scope. */ diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c index 5f67840..09aa0cd 100644 --- a/gcc/cp/tree.c +++ b/gcc/cp/tree.c @@ -1502,7 +1502,7 @@ no_linkage_helper (tp, walk_subtrees, data) if (TYPE_P (t) && (CLASS_TYPE_P (t) || TREE_CODE (t) == ENUMERAL_TYPE) && (decl_function_context (TYPE_MAIN_DECL (t)) - || ANON_AGGRNAME_P (TYPE_IDENTIFIER (t)))) + || TYPE_ANONYMOUS_P (t))) return t; return NULL_TREE; } diff --git a/gcc/testsuite/g++.old-deja/g++.other/anon9.C b/gcc/testsuite/g++.old-deja/g++.other/anon9.C new file mode 100644 index 0000000..45c326b --- /dev/null +++ b/gcc/testsuite/g++.old-deja/g++.other/anon9.C @@ -0,0 +1,5 @@ +// Test that we properly diagnose an attempt to use an anonymous class +// in declaring an external function. + +typedef const struct { int i; } T; // ERROR - referenced below +void f (T* t); // ERROR - uses unnamed type |