re PR c++/15096 (parse error with templates and pointer to const member)
authorMark Mitchell <mark@codesourcery.com>
Mon, 14 Jun 2004 15:58:54 +0000 (15:58 +0000)
committerMark Mitchell <mmitchel@gcc.gnu.org>
Mon, 14 Jun 2004 15:58:54 +0000 (15:58 +0000)
PR c++/15096
* decl.c (grokdeclarator): Ignore pointer-to-members when
computing template depth.

PR c++/14930
* name-lookup.c (pushtag): Do not try to put class declarations in
explicit specialization scopes.

PR c++/15096
* g++.dg/template/ptrmem10.C: New test.

PR c++/14930
* g++.dg/template/friend30.C: New test.

From-SVN: r83112

gcc/cp/ChangeLog
gcc/cp/decl.c
gcc/cp/name-lookup.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/template/friend30.C [new file with mode: 0644]
gcc/testsuite/g++.dg/template/ptrmem10.C [new file with mode: 0644]

index cb18209818f3157ca8fb8b9f9dee61c09df09445..d99aef0a8fdfb7a88220a87e3e8a058516ef4aa7 100644 (file)
@@ -1,3 +1,13 @@
+2004-06-14  Mark Mitchell  <mark@codesourcery.com>
+
+       PR c++/15096
+       * decl.c (grokdeclarator): Ignore pointer-to-members when
+       computing template depth.
+
+       PR c++/14930
+       * name-lookup.c (pushtag): Do not try to put class declarations in
+       explicit specialization scopes.
+
 2004-06-11  Andrew Pinski  <pinskia@physics.uc.edu>
 
        * decl.c (grokdeclarator): Do not depend on C99's _Bool's behavior.
index 950bac10b7330b2b00ed2ac1f2aa01589125ebe8..417171e760cbc36549927e6cd09e83e82b051b84 100644 (file)
@@ -7599,27 +7599,28 @@ grokdeclarator (tree declarator,
            ctype = TREE_OPERAND (declarator, 0);
 
            t = ctype;
-           while (t != NULL_TREE && CLASS_TYPE_P (t))
-             {
-               /* You're supposed to have one `template <...>'
-                  for every template class, but you don't need one
-                  for a full specialization.  For example:
-
+           if (TREE_CODE (TREE_OPERAND (declarator, 1)) != INDIRECT_REF)
+             while (t != NULL_TREE && CLASS_TYPE_P (t))
+               {
+                 /* You're supposed to have one `template <...>'
+                    for every template class, but you don't need one
+                    for a full specialization.  For example:
+                    
                     template <class T> struct S{};
                     template <> struct S<int> { void f(); };
                     void S<int>::f () {}
-
-                  is correct; there shouldn't be a `template <>' for
-                  the definition of `S<int>::f'.  */
-               if (CLASSTYPE_TEMPLATE_INFO (t)
-                   && (CLASSTYPE_TEMPLATE_INSTANTIATION (t)
-                       || uses_template_parms (CLASSTYPE_TI_ARGS (t)))
-                   && PRIMARY_TEMPLATE_P (CLASSTYPE_TI_TEMPLATE (t)))
-                 template_count += 1;
-
-               t = TYPE_MAIN_DECL (t);
-               t = DECL_CONTEXT (t);
-             }
+                    
+                    is correct; there shouldn't be a `template <>' for
+                    the definition of `S<int>::f'.  */
+                 if (CLASSTYPE_TEMPLATE_INFO (t)
+                     && (CLASSTYPE_TEMPLATE_INSTANTIATION (t)
+                         || uses_template_parms (CLASSTYPE_TI_ARGS (t)))
+                     && PRIMARY_TEMPLATE_P (CLASSTYPE_TI_TEMPLATE (t)))
+                   template_count += 1;
+                 
+                 t = TYPE_MAIN_DECL (t);
+                 t = DECL_CONTEXT (t);
+               }
 
            if (sname == NULL_TREE)
              goto done_scoping;
index d470251d3170eb621d82c2d0cc67f12181a5fbbf..3e42f3b5dce4c041feaf28b694212795074fa1ab 100644 (file)
@@ -4635,7 +4635,16 @@ pushtag (tree name, tree type, int globalize)
 
   timevar_push (TV_NAME_LOOKUP);
   b = current_binding_level;
-  while (b->kind == sk_cleanup
+  while (/* Cleanup scopes are not scopes from the point of view of
+           the language.  */
+        b->kind == sk_cleanup
+        /* Neither are the scopes used to hold template parameters
+           for an explicit specialization.  For an ordinary template
+           declaration, these scopes are not scopes from the point of
+           view of the language -- but we need a place to stash
+           things that will go in the containing namespace when the
+           template is instantiated.  */
+        || (b->kind == sk_template_parms && b->explicit_spec_p)
         || (b->kind == sk_class
             && (globalize
                 /* We may be defining a new type in the initializer
index 02da20e350993d9a15eaf51f99278c11e0ba9aba..0bff3abb8defd6dc9366b8baf29c95bcd1cff836 100644 (file)
@@ -1,3 +1,11 @@
+2004-06-14  Mark Mitchell  <mark@codesourcery.com>
+
+       PR c++/15096
+       * g++.dg/template/ptrmem10.C: New test.
+
+       PR c++/14930
+       * g++.dg/template/friend30.C: New test.
+
 2004-06-14  Tobias Schlueter  <tobias.schlueter@physik.uni-muenchen.de>
 
        PR fortran/14928
diff --git a/gcc/testsuite/g++.dg/template/friend30.C b/gcc/testsuite/g++.dg/template/friend30.C
new file mode 100644 (file)
index 0000000..055fc8d
--- /dev/null
@@ -0,0 +1,15 @@
+// PR c++/14930
+
+template<typename T> class Point;
+
+template<> class Point<double> {
+  friend class Plane;
+  double v;
+};
+
+struct Plane {
+  double get(const Point<double>& p);
+};
+
+double Plane::get(const Point<double> &p) { return p.v; }
+
diff --git a/gcc/testsuite/g++.dg/template/ptrmem10.C b/gcc/testsuite/g++.dg/template/ptrmem10.C
new file mode 100644 (file)
index 0000000..b76d5e8
--- /dev/null
@@ -0,0 +1,21 @@
+// PR c++/15096
+
+template <typename T_>
+class C1
+{
+public:
+    C1 ();
+    ~C1 ();
+    const int C1<T_>::* getPtr () const;
+
+private:
+    int x;
+    T_ y;
+};
+
+
+template <typename T_>
+const int C1<T_>::* C1<T_>::getPtr () const
+{ return &C1<T_>::x; }
+
+