OSDN Git Service

* cp-tree.def (LOOKUP_EXPR): Document. Remove second argument.
authormmitchel <mmitchel@138bc75d-0d04-0410-961f-82ee72b054a4>
Sun, 2 Aug 1998 21:37:23 +0000 (21:37 +0000)
committermmitchel <mmitchel@138bc75d-0d04-0410-961f-82ee72b054a4>
Sun, 2 Aug 1998 21:37:23 +0000 (21:37 +0000)
* cp-tree.h (DECL_TI_TEMPLATE): Improve documentation.
* lex.c (do_identifier): Don't use a second argument, or a type,
when building LOOKUP_EXPRs.
(do_identifier): Likewise.
(do_scoped_id): Likewise.
* method.c (hack_identifier): Improve error message.
* pt.c (lookup_template_function): Don't needlessly call
copy_to_permanent or build_min.
(tsubst_copy): Remove #if 0'd code.  Tsubst into LOOKUP_EXPRs if
necessary.
(do_decl_instantiation): Improve error message.
* tree.c (mapcar, case LOOKUP_EXPR): Don't be sorry; make a copy.
(build_min): Copy the type to the permanent obstack, too.

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

gcc/cp/ChangeLog
gcc/cp/cp-tree.def
gcc/cp/cp-tree.h
gcc/cp/lex.c
gcc/cp/method.c
gcc/cp/pt.c
gcc/cp/tree.c
gcc/testsuite/g++.old-deja/g++.pt/conv2.C [new file with mode: 0644]
gcc/testsuite/g++.old-deja/g++.pt/spec19.C [new file with mode: 0644]

index 4b80666..b7f83bc 100644 (file)
@@ -1,3 +1,20 @@
+1998-08-02  Mark Mitchell  <mark@markmitchell.com>
+
+       * cp-tree.def (LOOKUP_EXPR): Document.  Remove second argument.
+       * cp-tree.h (DECL_TI_TEMPLATE): Improve documentation.
+       * lex.c (do_identifier): Don't use a second argument, or a type,
+       when building LOOKUP_EXPRs.
+       (do_identifier): Likewise.
+       (do_scoped_id): Likewise.
+       * method.c (hack_identifier): Improve error message.
+       * pt.c (lookup_template_function): Don't needlessly call
+       copy_to_permanent or build_min.
+       (tsubst_copy): Remove #if 0'd code.  Tsubst into LOOKUP_EXPRs if
+       necessary.
+       (do_decl_instantiation): Improve error message.
+       * tree.c (mapcar, case LOOKUP_EXPR): Don't be sorry; make a copy.
+       (build_min): Copy the type to the permanent obstack, too.
+       
 1998-08-01  Jason Merrill  <jason@yorick.cygnus.com>
 
        * init.c (init_init_processing): Remove BI* handling.
index dbbdb66..b610737 100644 (file)
@@ -182,9 +182,14 @@ DEFTREECODE (WRAPPER, "wrapper", 'x', 1)
 /* A node to remember a source position.  */
 DEFTREECODE (SRCLOC, "srcloc", 'x', 2)
 
+/* Used to represent deferred name lookup for dependent names while
+   parsing a template declaration.  The first argument is an
+   IDENTIFIER_NODE for the name in question.  The TREE_TYPE is
+   unused.  */
+DEFTREECODE (LOOKUP_EXPR, "lookup_expr", 'e', 1)
+
 /* A whole bunch of tree codes for the initial, superficial parsing of
    templates.  */
-DEFTREECODE (LOOKUP_EXPR, "lookup_expr", 'e', 2)
 DEFTREECODE (MODOP_EXPR, "modop_expr", 'e', 3)
 DEFTREECODE (CAST_EXPR, "cast_expr", '1', 1)
 DEFTREECODE (REINTERPRET_CAST_EXPR, "reinterpret_cast_expr", '1', 1)
index 4e1d1bd..72a1655 100644 (file)
@@ -1265,8 +1265,8 @@ struct lang_decl
 
    As a special case, for a member friend template of a template
    class, this value will not be a TEMPLATE_DECL, but rather a
-   LOOKUP_EXPR indicating the name of the template and any explicit
-   template arguments provided.  For example, in:
+   LOOKUP_EXPR or IDENTIFIER_NODE indicating the name of the template
+   and any explicit template arguments provided.  For example, in:
 
      template <class T> struct S { friend void f<int>(int, double); }
 
index d127ddc..a9166d1 100644 (file)
@@ -2891,7 +2891,7 @@ do_identifier (token, parsing, args)
        }
 
       if (current_template_parms)
-       return build_min_nt (LOOKUP_EXPR, token, NULL_TREE);
+       return build_min_nt (LOOKUP_EXPR, token);
       else if (IDENTIFIER_OPNAME_P (token))
        {
          if (token != ansi_opname[ERROR_MARK])
@@ -2988,21 +2988,12 @@ do_identifier (token, parsing, args)
   else
     id = hack_identifier (id, token);
 
-  if (current_template_parms)
-    {
-      if (is_overloaded_fn (id))
-       {
-         tree t = build_min (LOOKUP_EXPR, unknown_type_node,
-                             token, get_first_fn (id));
-         if (id != IDENTIFIER_NAMESPACE_VALUE (token))
-           TREE_OPERAND (t, 1) = error_mark_node;
-         id = t;
-       }
-      else if (! TREE_PERMANENT (id) || TREE_CODE (id) == PARM_DECL
-              || TREE_CODE (id) == USING_DECL)
-       id = build_min (LOOKUP_EXPR, TREE_TYPE (id), token, error_mark_node);
-      /* else just use the decl */
-    }
+  if (current_template_parms
+      && (is_overloaded_fn (id) 
+         || !TREE_PERMANENT (id)
+         || TREE_CODE (id) == PARM_DECL
+         || TREE_CODE (id) == USING_DECL))
+    id = build_min_nt (LOOKUP_EXPR, token);
       
   return id;
 }
@@ -3031,7 +3022,7 @@ do_scoped_id (token, parsing)
     {
       if (processing_template_decl)
        {
-         id = build_min_nt (LOOKUP_EXPR, token, NULL_TREE);
+         id = build_min_nt (LOOKUP_EXPR, token);
          LOOKUP_EXPR_GLOBAL (id) = 1;
          return id;
        }
@@ -3068,9 +3059,9 @@ do_scoped_id (token, parsing)
     {
       if (is_overloaded_fn (id))
        {
-         id = build_min (LOOKUP_EXPR, unknown_type_node,
-                         token, get_first_fn (id));
+         id = build_min_nt (LOOKUP_EXPR, token);
          LOOKUP_EXPR_GLOBAL (id) = 1;
+         return id;
        }
       /* else just use the decl */
     }
index a4c1982..18e638c 100644 (file)
@@ -1845,8 +1845,16 @@ hack_identifier (value, name)
     {
       if (current_class_ptr == NULL_TREE)
        {
-         error ("request for member `%s' in static member function",
-                IDENTIFIER_POINTER (DECL_NAME (value)));
+         if (current_function_decl 
+             && DECL_STATIC_FUNCTION_P (current_function_decl))
+           cp_error ("invalid use of member `%D' in static member function",
+                     value);
+         else
+           /* We can get here when processing a bad default
+              argument, like:
+                struct S { int a; void f(int i = a); }  */
+           cp_error ("invalid use of member `%D'", value);
+
          return error_mark_node;
        }
       TREE_USED (current_class_ptr) = 1;
index 9e13916..3906eb3 100644 (file)
@@ -2999,14 +2999,14 @@ lookup_template_function (fns, arglist)
       return error_mark_node;
     }
 
-  if (arglist != NULL_TREE && !TREE_PERMANENT (arglist))
-    copy_to_permanent (arglist);
-
   type = TREE_TYPE (fns);
   if (TREE_CODE (fns) == OVERLOAD || !type)
     type = unknown_type_node;
 
-  return build_min (TEMPLATE_ID_EXPR, type, fns, arglist);  
+  if (processing_template_decl)
+    return build_min (TEMPLATE_ID_EXPR, type, fns, arglist);  
+  else
+    return build (TEMPLATE_ID_EXPR, type, fns, arglist);
 }
 
 /* Within the scope of a template class S<T>, the name S gets bound
@@ -5469,11 +5469,25 @@ tsubst_copy (t, args, in_decl)
       else
        return t;
 
-#if 0
-    case IDENTIFIER_NODE:
-      return do_identifier (t, 0);
-#endif
-      
+    case LOOKUP_EXPR:
+      {
+       /* We must tsbust into a LOOKUP_EXPR in case the names to
+          which it refers is a conversion operator; in that case the
+          name will change.  We avoid making unnecessary copies,
+          however.  */
+       
+       tree id = tsubst_copy (TREE_OPERAND (t, 0), args, in_decl);
+
+       if (id != TREE_OPERAND (t, 0))
+         {
+           tree r = build_nt (LOOKUP_EXPR, id);
+           LOOKUP_EXPR_GLOBAL (r) = LOOKUP_EXPR_GLOBAL (t);
+           t = r;
+         }
+
+       return t;
+      }
+
     case CAST_EXPR:
     case REINTERPRET_CAST_EXPR:
     case CONST_CAST_EXPR:
@@ -7236,6 +7250,16 @@ do_decl_instantiation (declspecs, declarator, storage)
       cp_error ("explicit instantiation of `%#D'", decl);
       return;
     }
+  else if (DECL_TEMPLATE_SPECIALIZATION (decl))
+    /* [temp.spec]
+
+       No program shall both explicit instantiation and explicit
+       specialize a template.  */
+    {
+      cp_error ("explicit instantiation of `%#D' after", decl);
+      cp_error_at ("explicit specialization here", decl);
+      return;
+    }
   else if (DECL_TEMPLATE_INSTANTIATION (decl))
     result = decl;
 
index dce01cb..8b782bb 100644 (file)
@@ -1784,6 +1784,11 @@ mapcar (t, func)
       TREE_OPERAND (t, 2) = mapcar (TREE_OPERAND (t, 2), func);
       return t;
 
+    case LOOKUP_EXPR:
+      t = copy_node (t);
+      TREE_OPERAND (t, 0) = mapcar (TREE_OPERAND (t, 0), func);
+      return t;
+
     case RECORD_TYPE:
       if (TYPE_PTRMEMFUNC_P (t))
        return build_ptrmemfunc_type
@@ -2022,7 +2027,7 @@ build_min VPROTO((enum tree_code code, tree tt, ...))
 
   t = make_node (code);
   length = tree_code_length[(int) code];
-  TREE_TYPE (t) = tt;
+  TREE_TYPE (t) = copy_to_permanent (tt);
   TREE_COMPLEXITY (t) = lineno;
 
   for (i = 0; i < length; i++)
diff --git a/gcc/testsuite/g++.old-deja/g++.pt/conv2.C b/gcc/testsuite/g++.old-deja/g++.pt/conv2.C
new file mode 100644 (file)
index 0000000..f3e0b35
--- /dev/null
@@ -0,0 +1,15 @@
+// Build don't link:
+
+template<class T>
+class A {
+public:
+  operator const T*() const;
+  const T* cast() const;
+};
+
+template<class T>
+const T* A<T>::cast() const {
+  return operator const T*();
+}
+
+template class A<char>;
diff --git a/gcc/testsuite/g++.old-deja/g++.pt/spec19.C b/gcc/testsuite/g++.old-deja/g++.pt/spec19.C
new file mode 100644 (file)
index 0000000..f9b6011
--- /dev/null
@@ -0,0 +1,5 @@
+// Build don't link:
+
+template<class T> T f(T o) { return o; }
+template<> int f(int o)    { return o; } // ERROR - after specialization
+template int f(int);  // ERROR - explicit instantiation