]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
re PR c++/9447 (using Base<T>::member does not work)
authorNathan Sidwell <nathan@codesourcery.com>
Sat, 2 Aug 2003 18:52:16 +0000 (18:52 +0000)
committerNathan Sidwell <nathan@gcc.gnu.org>
Sat, 2 Aug 2003 18:52:16 +0000 (18:52 +0000)
cp:
PR c++/9447
* cp-tree.def (USING_DECL): Document its type.
* class.c (pushclass): If we're entering a template, push any
dependent using decls it has.
* decl2.c (do_class_using_decl): Refactor. Type is NULL iff it is
a dependent scope.
* pt.c (tsubst_decl) <USING_DECL case>: Set type.
(tsubst): Remove USING_DECL checks.
(type_dependent_expression_p): Remove USING_DECL case.
* semantics.c (finish_member_declaration): A USING_DECL's type
indicates whether it is dependent.
testsuite:
PR c++/9447
* g++.dg/template/using7.C: New test.

From-SVN: r70107

gcc/cp/ChangeLog
gcc/cp/class.c
gcc/cp/cp-tree.def
gcc/cp/decl.c
gcc/cp/decl2.c
gcc/cp/pt.c
gcc/cp/semantics.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/template/using7.C [new file with mode: 0644]

index 4a5f939491720aba4e9f3e2a664f75221892e784..de0923a96cf14b4bcfb8095932b7837a3f9877a8 100644 (file)
@@ -1,3 +1,17 @@
+2003-08-02  Nathan Sidwell  <nathan@codesourcery.com>
+
+       PR c++/9447
+       * cp-tree.def (USING_DECL): Document its type.
+       * class.c (pushclass): If we're entering a template, push any
+       dependent using decls it has.
+       * decl2.c (do_class_using_decl): Refactor. Type is NULL iff it is
+       a dependent scope.
+       * pt.c (tsubst_decl) <USING_DECL case>: Set type.
+       (tsubst): Remove USING_DECL checks.
+       (type_dependent_expression_p): Remove USING_DECL case.
+       * semantics.c (finish_member_declaration): A USING_DECL's type
+       indicates whether it is dependent.
+
 2003-08-02  Nathan Sidwell  <nathan@codesourcery.com>
 
        * cp-tree.h (pushclass): Remove unneeded parameter.
index a85b11274c8dddfc504dd4c192859741bd3068cf..bf1672127bfd9f22ff713825487cb844f07bbf53 100644 (file)
@@ -5457,7 +5457,21 @@ pushclass (tree type)
   pushlevel_class ();
 
   if (type != previous_class_type || current_class_depth > 1)
-    push_class_decls (type);
+    {
+      push_class_decls (type);
+      if (CLASSTYPE_IS_TEMPLATE (type))
+       {
+         /* If we are entering the scope of a template (not a
+            specialization), we need to push all the using decls with
+            dependent scope too.  */
+         tree fields;
+
+         for (fields = TYPE_FIELDS (type);
+              fields; fields = TREE_CHAIN (fields))
+           if (TREE_CODE (fields) == USING_DECL && !TREE_TYPE (fields))
+             pushdecl_class_level (fields);
+       }
+    }
   else
     {
       tree item;
index 5e853fea085799271e490b3a02f2a0f35d4e9bb3..f020a23d6a2f65e68c57d3f1fbf69dd4be943b0c 100644 (file)
@@ -195,7 +195,9 @@ DEFTREECODE (UNBOUND_CLASS_TEMPLATE, "unbound_class_template", 't', 0)
 DEFTREECODE (TYPEOF_TYPE, "typeof_type", 't', 0)
 
 /* A using declaration.  DECL_INITIAL contains the specified scope.  
-   This is not an alias, but is later expanded into multiple aliases.  */
+   This is not an alias, but is later expanded into multiple aliases.
+   The decl will have a NULL_TYPE iff the scope is a dependent scope,
+   otherwise it will have a void type. */
 DEFTREECODE (USING_DECL, "using_decl", 'd', 0)
 
 /* A using directive. The operand is USING_STMT_NAMESPACE. */     
index 593dcede6e6ba4d89cad3444dfd10844d4124bb4..ab6913cc0c81ae584645612d49b7a6e7d70417bc 100644 (file)
@@ -11632,7 +11632,8 @@ grokdeclarator (tree declarator,
                            inlinep, friendp, raises != NULL_TREE);
          }
       }
-    else if (TREE_CODE (type) == FUNCTION_TYPE || TREE_CODE (type) == METHOD_TYPE)
+    else if (TREE_CODE (type) == FUNCTION_TYPE
+            || TREE_CODE (type) == METHOD_TYPE)
       {
        tree original_name;
        int publicp = 0;
index 6f0686069e13d5db7a18cf127ab47d1fea3c1bcd..8ec34b2e03e5292f3e1e1b89fc9eb1ce8b5520f7 100644 (file)
@@ -4045,8 +4045,8 @@ do_local_using_decl (tree decl)
 tree
 do_class_using_decl (tree decl)
 {
-  tree name, value;
-
+  tree name, value, scope, type;
+  
   if (TREE_CODE (decl) != SCOPE_REF
       || !TREE_OPERAND (decl, 0)
       || !TYPE_P (TREE_OPERAND (decl, 0)))
@@ -4054,50 +4054,44 @@ do_class_using_decl (tree decl)
       error ("using-declaration for non-member at class scope");
       return NULL_TREE;
     }
+  scope = TREE_OPERAND (decl, 0);
   name = TREE_OPERAND (decl, 1);
   if (TREE_CODE (name) == BIT_NOT_EXPR)
     {
-      error ("using-declaration for destructor");
+      error ("using-declaration cannot name destructor");
       return NULL_TREE;
     }
   else if (TREE_CODE (name) == TEMPLATE_ID_EXPR)
     {
-      name = TREE_OPERAND (name, 0);
-      error ("a using-declaration cannot specify a template-id.  Try  `using %T::%D'", TREE_OPERAND (decl, 0), name);
+    template_id_error:;
+      
+      error ("a using-declaration cannot specify a template-id");
       return NULL_TREE;
     }
   if (TREE_CODE (name) == TYPE_DECL)
     {
-      tree type = TREE_TYPE (name);
       if (CLASSTYPE_USE_TEMPLATE (TREE_TYPE (name)))
-       {
-         name = DECL_NAME (CLASSTYPE_TI_TEMPLATE (type));
-         error ("a using-declaration cannot specify a template-id.");
-         return NULL_TREE;
-       }
+       goto template_id_error;
       name = DECL_NAME (name);
     }
   else if (TREE_CODE (name) == TEMPLATE_DECL)
      name = DECL_NAME (name);
   else if (BASELINK_P (name))
     {
-      tree fns;
-
-      fns = BASELINK_FUNCTIONS (name);
+      tree fns = BASELINK_FUNCTIONS (name);
+      
       if (TREE_CODE (fns) == TEMPLATE_ID_EXPR)
-       {
-         fns = TREE_OPERAND (fns, 0);
-         error ("a using-declaration cannot specify a template-id.  Try  `using %T::%D'", 
-                BASELINK_ACCESS_BINFO (name),
-                DECL_NAME (get_first_fn (fns)));
-       }
+       goto template_id_error;
       name = DECL_NAME (get_first_fn (fns));
     }
 
   my_friendly_assert (TREE_CODE (name) == IDENTIFIER_NODE, 980716);
 
-  value = build_lang_decl (USING_DECL, name, NULL_TREE);
-  DECL_INITIAL (value) = TREE_OPERAND (decl, 0);
+  /* Dependent using decls have a NULL type, non-dependent ones have a
+     void type.  */
+  type = dependent_type_p (scope) ? NULL_TREE : void_type_node;
+  value = build_lang_decl (USING_DECL, name, type);
+  DECL_INITIAL (value) = scope;
   return value;
 }
 
index 35c13670c7c20dff5722b95a0cae157bdd8f7b0f..185a203c20024cd29d067cb10d2ec8103e972b04 100644 (file)
@@ -6093,6 +6093,8 @@ tsubst_decl (tree t, tree args, tree type, tsubst_flags_t complain)
     case USING_DECL:
       {
        r = copy_node (t);
+       /* It is not a dependent using decl any more.  */
+       TREE_TYPE (r) = void_type_node;
        DECL_INITIAL (r)
          = tsubst_copy (DECL_INITIAL (t), args, complain, in_decl);
        TREE_CHAIN (r) = NULL_TREE;
@@ -6403,15 +6405,13 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl)
   else
     type = TREE_TYPE (t);
 
-  my_friendly_assert (type != unknown_type_node
-                     || TREE_CODE (t) == USING_DECL, 20030716);
+  my_friendly_assert (type != unknown_type_node, 20030716);
 
   if (type && TREE_CODE (t) != FUNCTION_DECL
       && TREE_CODE (t) != TYPENAME_TYPE
       && TREE_CODE (t) != TEMPLATE_DECL
       && TREE_CODE (t) != IDENTIFIER_NODE
       && TREE_CODE (t) != FUNCTION_TYPE
-      && TREE_CODE (t) != USING_DECL
       && TREE_CODE (t) != METHOD_TYPE)
     type = tsubst (type, args, complain, in_decl);
   if (type == error_mark_node)
@@ -11623,8 +11623,6 @@ type_dependent_expression_p (tree expression)
 
   if (TREE_TYPE (expression) == unknown_type_node)
     {
-      if (TREE_CODE (expression) == USING_DECL)
-       return true;
       if (TREE_CODE (expression) == ADDR_EXPR)
        return type_dependent_expression_p (TREE_OPERAND (expression, 0));
       if (TREE_CODE (expression) == BASELINK)
index 11f5ff045d3bd478ee0f2db23bdab8f853fa5317..0931e891e048bc13fcc8eba3b2af053fcfa5233d 100644 (file)
@@ -2099,8 +2099,7 @@ finish_member_declaration (tree decl)
                                          /*friend_p=*/0);
     }
   /* Enter the DECL into the scope of the class.  */
-  else if ((TREE_CODE (decl) == USING_DECL && !processing_template_decl
-           && !dependent_type_p (DECL_INITIAL (decl)))
+  else if ((TREE_CODE (decl) == USING_DECL && TREE_TYPE (decl))
           || pushdecl_class_level (decl))
     {
       /* All TYPE_DECLs go at the end of TYPE_FIELDS.  Ordinary fields
index 9b982ee16b291c66f58b228d5dcc9662d5e506e5..93da3595af9078562e95f49a2d74cb1f712a6702 100644 (file)
@@ -1,3 +1,8 @@
+2003-08-02  Nathan Sidwell  <nathan@codesourcery.com>
+
+       PR c++/9447
+       * g++.dg/template/using7.C: New test.
+
 2003-08-02  Neil Booth  <neil@daikokuya.co.uk>
 
        * import1.c, import2.c: New tests.
diff --git a/gcc/testsuite/g++.dg/template/using7.C b/gcc/testsuite/g++.dg/template/using7.C
new file mode 100644 (file)
index 0000000..390dfba
--- /dev/null
@@ -0,0 +1,21 @@
+// { dg-do compile }
+
+// Copyright (C) 2003 Free Software Foundation, Inc.
+// Contributed by Nathan Sidwell 1 Aug 2003 <nathan@codesourcery.com>
+
+// PR 9447. Using decls in reopened template classes.
+
+template <typename> struct A { int i; };
+
+template <typename T> struct B : public A<T>
+{
+    using A<T>::i;
+    int foo() const;
+};
+
+struct C {};
+
+template <typename T> int B<T>::foo() const
+{
+  return i;
+}