* cp-tree.h (TYPE_LINKAGE_IDENTIFIER): New macro.
authorjason <jason@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 12 Apr 2001 14:15:48 +0000 (14:15 +0000)
committerjason <jason@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 12 Apr 2001 14:15:48 +0000 (14:15 +0000)
        (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.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@41303 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/cp/ChangeLog
gcc/cp/cp-tree.h
gcc/cp/decl.c
gcc/cp/lex.c
gcc/cp/pt.c
gcc/cp/semantics.c
gcc/cp/tree.c
gcc/testsuite/g++.old-deja/g++.other/anon9.C [new file with mode: 0644]

index 634c8cf..c26c7f5 100644 (file)
@@ -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.
index 77a12f6..5a8a3ba 100644 (file)
@@ -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)
index ff8a819..0e97ad1 100644 (file)
@@ -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);
index ef9314c..5120f20 100644 (file)
@@ -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
index 24bdff4..ac88bec 100644 (file)
@@ -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
index 9295564..a6e13ec 100644 (file)
@@ -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.  */
index 5f67840..09aa0cd 100644 (file)
@@ -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 (file)
index 0000000..45c326b
--- /dev/null
@@ -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