OSDN Git Service

84th Cygnus<->FSF merge
authormrs <mrs@138bc75d-0d04-0410-961f-82ee72b054a4>
Sat, 2 Mar 1996 01:49:15 +0000 (01:49 +0000)
committermrs <mrs@138bc75d-0d04-0410-961f-82ee72b054a4>
Sat, 2 Mar 1996 01:49:15 +0000 (01:49 +0000)
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@11399 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/cp/ChangeLog
gcc/cp/class.c
gcc/cp/cp-tree.def
gcc/cp/decl.c
gcc/cp/error.c
gcc/cp/method.c
gcc/cp/parse.y
gcc/cp/pt.c
gcc/cp/tree.c

index 49b3e9a..471bd9b 100644 (file)
@@ -1,5 +1,80 @@
+Fri Mar  1 13:09:33 1996  Jason Merrill  <jason@yorick.cygnus.com>
+
+       * pt.c (instantiate_class_template): If we don't have a pattern
+       yet, that's OK.
+       (coerce_template_parms): If we see a local class, bail.
+
+       * decl.c (grok_reference_init): Make sure there's a type before
+       checking its code.
+
+       * pt.c (do_function_instantiation): Avoid crashing on invalid decls.
+       (push_template_decl): Ditto.
+
+       * parse.y (named_class_head): Set
+       CLASSTYPE_TEMPLATE_SPECIALIZATION here if we have basetypes.
+
+       * decl.c (xref_tag): Diagnose redeclaration of template
+       type-parameter name.
+
+       * error.c (dump_type): Handle anonymous template type parms.
+
+       * pt.c (instantiate_template): Use TYPE_MAIN_DECL instead of
+       TYPE_STUB_DECL.
+       (coerce_template_parms): Ditto.
+
+Thu Feb 29 16:26:01 1996  Mike Stump  <mrs@cygnus.com>
+
+       * class.c (instantiate_type, case {ARRAY,INDIRECT}_REF,
+       case ADDR_EXPR): Don't modify rhs if a subinstantiation fails.
+
+Thu Feb 29 08:20:25 1996  Jason Merrill  <jason@yorick.cygnus.com>
+
+       * pt.c (instantiate_template): Take the MAIN_VARIANT of the type
+       before trying to get its STUB_DECL.
+       (coerce_template_parms): Ditto.
+
+       * parse.y (template_type_parm): If they didn't use 'class',
+       pretend they did after giving an error.
+
+       * pt.c (coerce_template_parms): Diagnose use of local class.
+
+       * decl.c (grok_reference_init): Use instantiate_type.
+
+       * error.c (dump_expr): Handle TEMPLATE_DECLs.
+
+       * parse.y (named_class_head): Diagnose mismatching types and tags.
+
+       * decl.c (pushdecl): Type decls and class templates clash with
+       artificial type decls, not hide them.
+
+       * decl.c (redeclaration_error_message): Diagnose redefinition of
+       templates properly.
+       (duplicate_decls): Diagnose disallowed overloads for template
+       functions, too.
+
+       * decl.c (start_decl): Call complete_type before checking for a
+       destructor.
+
+       * pt.c (tsubst): Use tsubst_expr on the elts of a VEC.
+
+       * decl.c (xref_tag): A TEMPLATE_TYPE_PARM is a match.
+
 Wed Feb 28 09:28:44 1996  Jason Merrill  <jason@yorick.cygnus.com>
 
+       * decl.c (grok_op_properties): Don't check for operator++(int) in
+       a template.
+
+       * tree.c (perm_manip): Return a copy of variable and function
+       decls with external linkage.
+
+       * tree.def: Change some of the min tree codes to type "1".
+       * pt.c (uses_template_parms): Handle 'e's, return 1 for LOOKUP_EXPRs.
+       * method.c (build_overload_int): Emit something arbitrary for
+       anything but an INTEGER_CST if we're in a template.
+
+       * decl.c (cp_finish_decl): Call complete_type before deciding
+       whether or not to lay out the decl.
+
        * lex.c (do_identifier): Check for DECL_INITIAL before using it.
 
 Tue Feb 27 16:35:32 1996  Jason Merrill  <jason@yorick.cygnus.com>
index 4bceaa1..e5ce5ba 100644 (file)
@@ -4842,9 +4842,12 @@ root_lang_context_p ()
 \f
 /* Type instantiation routines.  */
 
-/* This function will instantiate the type of the expression given
-   in RHS to match the type of LHSTYPE.  If LHSTYPE is NULL_TREE,
-   or other errors exist, the TREE_TYPE of RHS will be ERROR_MARK_NODE.
+/* This function will instantiate the type of the expression given in
+   RHS to match the type of LHSTYPE.  If errors exist, then return
+   error_mark_node.  If only complain is COMPLAIN is set.  If we are
+   not complaining, never modify rhs, as overload resolution wants to
+   try many possible instantiations, in hopes that at least one will
+   work.
 
    This function is used in build_modify_expr, convert_arguments,
    build_c_cast, and compute_conversion_costs.  */
@@ -4880,14 +4883,18 @@ instantiate_type (lhstype, rhs, complain)
 
     case INDIRECT_REF:
     case ARRAY_REF:
-      TREE_TYPE (rhs) = lhstype;
-      lhstype = build_pointer_type (lhstype);
-      TREE_OPERAND (rhs, 0)
-       = instantiate_type (lhstype, TREE_OPERAND (rhs, 0), complain);
-      if (TREE_OPERAND (rhs, 0) == error_mark_node)
-       return error_mark_node;
+      {
+       tree new_rhs;
 
-      return rhs;
+       new_rhs = instantiate_type (build_pointer_type (lhstype),
+                                   TREE_OPERAND (rhs, 0), complain);
+       if (new_rhs == error_mark_node)
+         return error_mark_node;
+
+       TREE_TYPE (rhs) = lhstype;
+       TREE_OPERAND (rhs, 0) = new_rhs;
+       return rhs;
+      }
 
     case NOP_EXPR:
       rhs = copy_node (TREE_OPERAND (rhs, 0));
@@ -5262,13 +5269,12 @@ instantiate_type (lhstype, rhs, complain)
            error ("type for resolving address of overloaded function must be pointer type");
          return error_mark_node;
        }
-      TREE_TYPE (rhs) = lhstype;
-      lhstype = TREE_TYPE (lhstype);
       {
-       tree fn = instantiate_type (lhstype, TREE_OPERAND (rhs, 0), complain);
+       tree fn = instantiate_type (TREE_TYPE (lhstype), TREE_OPERAND (rhs, 0), complain);
        if (fn == error_mark_node)
          return error_mark_node;
        mark_addressable (fn);
+       TREE_TYPE (rhs) = lhstype;
        TREE_OPERAND (rhs, 0) = fn;
        TREE_CONSTANT (rhs) = staticp (fn);
       }
index 51edcb0..d965783 100644 (file)
@@ -116,9 +116,9 @@ DEFTREECODE (USING_DECL, "using_decl", "d", 0)
 
 DEFTREECODE (LOOKUP_EXPR, "lookup_expr", "e", 2)
 DEFTREECODE (MODOP_EXPR, "modop_expr", "e", 3)
-DEFTREECODE (CAST_EXPR, "cast_expr", "e", 1)
-DEFTREECODE (REINTERPRET_CAST_EXPR, "reinterpret_cast_expr", "e", 1)
-DEFTREECODE (SIZEOF_EXPR, "sizeof_expr", "e", 1)
+DEFTREECODE (CAST_EXPR, "cast_expr", "1", 1)
+DEFTREECODE (REINTERPRET_CAST_EXPR, "reinterpret_cast_expr", "1", 1)
+DEFTREECODE (SIZEOF_EXPR, "sizeof_expr", "1", 1)
 DEFTREECODE (ARROW_EXPR, "arrow_expr", "e", 1)
 DEFTREECODE (DOTSTAR_EXPR, "dotstar_expr", "e", 2)
 
index 2dd92e5..8d1d8cd 100644 (file)
@@ -2501,6 +2501,14 @@ duplicate_decls (newdecl, olddecl)
              cp_error_at ("conflicts with previous declaration `%#D'",
                           olddecl);
            }
+         else if (TREE_CODE (DECL_TEMPLATE_RESULT (olddecl)) == FUNCTION_DECL
+                  && TREE_CODE (DECL_TEMPLATE_RESULT (newdecl)) == FUNCTION_DECL
+                  && compparms (TYPE_ARG_TYPES (TREE_TYPE (DECL_TEMPLATE_RESULT (olddecl))),
+                                TYPE_ARG_TYPES (TREE_TYPE (DECL_TEMPLATE_RESULT (newdecl))), 3))
+           {
+             cp_error ("new declaration `%#D'", newdecl);
+             cp_error_at ("ambiguates old declaration `%#D'", olddecl);
+           }
          return 0;
        }
       if (TREE_CODE (newdecl) == FUNCTION_DECL)
@@ -3044,8 +3052,15 @@ pushdecl (x)
            }
          else if (TREE_CODE (t) != TREE_CODE (x))
            {
-             if ((TREE_CODE (t) == TYPE_DECL && DECL_ARTIFICIAL (t))
-                 || (TREE_CODE (x) == TYPE_DECL && DECL_ARTIFICIAL (x)))
+             if ((TREE_CODE (t) == TYPE_DECL && DECL_ARTIFICIAL (t)
+                  && TREE_CODE (x) != TYPE_DECL
+                  && ! (TREE_CODE (x) == TEMPLATE_DECL
+                        && TREE_CODE (DECL_TEMPLATE_RESULT (x)) == TYPE_DECL))
+                 || (TREE_CODE (x) == TYPE_DECL && DECL_ARTIFICIAL (x)
+                     && TREE_CODE (t) != TYPE_DECL
+                     && ! (TREE_CODE (t) == TEMPLATE_DECL
+                           && (TREE_CODE (DECL_TEMPLATE_RESULT (t))
+                               == TYPE_DECL))))
                {
                  /* We do nothing special here, because C++ does such nasty
                     things with TYPE_DECLs.  Instead, just let the TYPE_DECL
@@ -3714,7 +3729,12 @@ redeclaration_error_message (newdecl, olddecl)
     }
   else if (TREE_CODE (newdecl) == TEMPLATE_DECL)
     {
-      if (DECL_INITIAL (olddecl) && DECL_INITIAL (newdecl))
+      if ((TREE_CODE (DECL_TEMPLATE_RESULT (newdecl)) == FUNCTION_DECL
+          && DECL_INITIAL (DECL_TEMPLATE_RESULT (newdecl))
+          && DECL_INITIAL (DECL_TEMPLATE_RESULT (olddecl)))
+         || (TREE_CODE (DECL_TEMPLATE_RESULT (newdecl)) == TYPE_DECL
+             && TYPE_SIZE (TREE_TYPE (newdecl))
+             && TYPE_SIZE (TREE_TYPE (olddecl))))
        return "redefinition of `%#D'";
       return 0;
     }
@@ -5737,7 +5757,7 @@ start_decl (declarator, declspecs, initialized, raises)
 
   /* Don't lose if destructors must be executed at file-level.  */
   if (! current_template_parms && TREE_STATIC (decl)
-      && TYPE_NEEDS_DESTRUCTOR (type)
+      && TYPE_NEEDS_DESTRUCTOR (complete_type (type))
       && !TREE_PERMANENT (decl))
     {
       push_obstacks (&permanent_obstack, &permanent_obstack);
@@ -6029,6 +6049,10 @@ grok_reference_init (decl, type, init, cleanupp)
       return;
     }
 
+  if (TREE_TYPE (init) && TREE_CODE (TREE_TYPE (init)) == UNKNOWN_TYPE)
+    /* decay_conversion is probably wrong for references to functions.  */
+    init = decay_conversion (instantiate_type (TREE_TYPE (type), init, 1));
+
   if (TREE_CODE (init) == TREE_LIST)
     init = build_compound_expr (init);
 
@@ -6417,7 +6441,7 @@ cp_finish_decl (decl, init, asmspec_tree, need_pop, flags)
   if (TREE_CODE (decl) == VAR_DECL)
     {
       if (DECL_SIZE (decl) == NULL_TREE
-         && TYPE_SIZE (TREE_TYPE (decl)) != NULL_TREE)
+         && TYPE_SIZE (complete_type (TREE_TYPE (decl))) != NULL_TREE)
        layout_decl (decl, 0);
 
       if (TREE_STATIC (decl) && DECL_SIZE (decl) == NULL_TREE)
@@ -10152,6 +10176,7 @@ grok_op_properties (decl, virtualp, friendp)
            {
              if ((name == ansi_opname[(int) POSTINCREMENT_EXPR]
                   || name == ansi_opname[(int) POSTDECREMENT_EXPR])
+                 && ! current_template_parms
                  && TREE_VALUE (TREE_CHAIN (argtypes)) != integer_type_node)
                {
                  if (methodp)
@@ -10259,11 +10284,16 @@ xref_tag (code_type_node, name, binfo, globalize)
     }
   else
     t = IDENTIFIER_TYPE_VALUE (name);
-  if (t && TREE_CODE (t) != code)
+  if (t && TREE_CODE (t) != code && TREE_CODE (t) != TEMPLATE_TYPE_PARM)
     t = NULL_TREE;
 
   if (! globalize)
     {
+      if (pedantic && t && TREE_CODE (t) == TEMPLATE_TYPE_PARM)
+       {
+         cp_pedwarn ("redeclaration of template type-parameter `%T'", name);
+         cp_pedwarn_at ("  previously declared here", t);
+       }
       /* If we know we are defining this tag, only look it up in this scope
        * and don't try to find it as a type. */
       if (t && TYPE_CONTEXT(t) && TREE_MANGLED (name))
index 3c1d9a2..99f72fb 100644 (file)
@@ -209,7 +209,10 @@ dump_type (t, v)
       break;
 
     case TEMPLATE_TYPE_PARM:
-      OB_PUTID (TYPE_IDENTIFIER (t));
+      if (TYPE_IDENTIFIER (t))
+       OB_PUTID (TYPE_IDENTIFIER (t));
+      else
+       OB_PUTS ("{anonymous template type parm}");
       break;
 
       /* This is not always necessary for pointers and such, but doing this
@@ -941,6 +944,7 @@ dump_expr (t, nop)
     case FIELD_DECL:
     case CONST_DECL:
     case FUNCTION_DECL:
+    case TEMPLATE_DECL:
       dump_decl (t, -1);
       break;
 
index 5156121..6b45ff4 100644 (file)
@@ -364,7 +364,8 @@ build_overload_int (value)
        OB_PUTC ('_');
       return;
     }
-  else if (uses_template_parms (value))
+  else if (current_template_parms
+          && TREE_CODE (value) != INTEGER_CST)
     /* We don't ever want this output, but it's inconvenient not to
        be able to build the string.  This should cause assembler
        errors we'll notice.  */
index be782b7..c53bef3 100644 (file)
@@ -427,7 +427,10 @@ template_type_parm:
                  if (TREE_PURPOSE ($$) == signature_type_node)
                    sorry ("signature as template type parameter");
                  else if (TREE_PURPOSE ($$) != class_type_node)
-                   pedwarn ("template type parameters must use the keyword `class'");
+                   {
+                     pedwarn ("template type parameters must use the keyword `class'");
+                     TREE_PURPOSE ($$) = class_type_node;
+                   }
                }
        | aggr identifier
                { $$ = build_tree_list ($1, $2); goto ttpa; }
@@ -2129,8 +2132,24 @@ named_class_head:
        | named_complex_class_head_sans_basetype maybe_base_class_list
                { 
                  $$ = TREE_TYPE ($1);
+                 if (TREE_INT_CST_LOW (current_aggr) == union_type 
+                     && TREE_CODE ($$) != UNION_TYPE)
+                   cp_pedwarn ("`union' tag used in declaring `%#T'", $$);
+                 else if (TREE_CODE ($$) == UNION_TYPE
+                          && TREE_INT_CST_LOW (current_aggr) != union_type)
+                   cp_pedwarn ("non-`union' tag used in declaring `%#T'", $$);
                  if ($2)
-                   xref_basetypes (current_aggr, $1, $$, $2); 
+                   {
+                     if (IS_AGGR_TYPE ($$) && CLASSTYPE_USE_TEMPLATE ($$))
+                       {
+                         if (CLASSTYPE_IMPLICIT_INSTANTIATION ($$)
+                             && TYPE_SIZE ($$) == NULL_TREE)
+                           SET_CLASSTYPE_TEMPLATE_SPECIALIZATION ($$);
+                         else if (CLASSTYPE_TEMPLATE_INSTANTIATION ($$))
+                           cp_error ("specialization after instantiation of `%T'", $$);
+                       }
+                     xref_basetypes (current_aggr, $1, $$, $2); 
+                   }
                }
        ;
 
index 5a30c9a..02e2822 100644 (file)
@@ -253,6 +253,8 @@ push_template_decl (decl)
       CLASSTYPE_TEMPLATE_INFO (TREE_TYPE (tmpl)) = info;
       DECL_NAME (decl) = classtype_mangled_name (TREE_TYPE (decl));
     }
+  else if (! DECL_LANG_SPECIFIC (decl))
+    cp_error ("template declaration of `%#D'", decl);
   else
     DECL_TEMPLATE_INFO (decl) = info;
 }
@@ -352,12 +354,24 @@ coerce_template_parms (parms, arglist, in_decl)
          continue;
        }
       if (is_type)
-       val = groktypename (arg);
+       {
+         val = groktypename (arg);
+         if (! current_template_parms)
+           {
+             tree t = target_type (val);
+             if (IS_AGGR_TYPE (t)
+                 && decl_function_context (TYPE_MAIN_DECL (t)))
+               {
+                 cp_error ("type `%T' composed from a local class is not a valid template-argument", val);
+                 return error_mark_node;
+               }
+           }
+       }
       else
        {
          tree t = tsubst (TREE_TYPE (parm), &TREE_VEC_ELT (vec, 0),
                           TREE_VEC_LENGTH (vec), in_decl);
-         if (current_template_parms && uses_template_parms (arg))
+         if (current_template_parms)
            val = arg;
          else
            val = digest_init (t, arg, (tree *) 0);
@@ -844,6 +858,7 @@ uses_template_parms (t)
       /* NOTREACHED */
       return 0;
 
+    case LOOKUP_EXPR:
     case TYPENAME_TYPE:
       return 1;
 
@@ -857,7 +872,7 @@ uses_template_parms (t)
        {
        case '1':
        case '2':
-       case '3':
+       case 'e':
        case '<':
          {
            int i;
@@ -980,11 +995,7 @@ instantiate_class_template (type)
   pattern = TREE_TYPE (template);
 
   if (TYPE_SIZE (pattern) == NULL_TREE)
-    {
-      cp_error_at ("no definition available for `%#D'", template);
-      cp_error ("  trying to instantiate `%#T'", type);
-      return error_mark_node;
-    }
+    return type;
 
   TYPE_BEING_DEFINED (type) = 1;
 
@@ -1608,7 +1619,7 @@ tsubst (t, args, nargs, in_decl)
 
        for (i = 0; i < len; i++)
          {
-           elts[i] = tsubst_copy (TREE_VEC_ELT (t, i), args, nargs, in_decl);
+           elts[i] = tsubst_expr (TREE_VEC_ELT (t, i), args, nargs, in_decl);
            if (elts[i] != TREE_VEC_ELT (t, i))
              need_new = 1;
          }
@@ -2287,7 +2298,7 @@ instantiate_template (tmpl, targ_ptr)
       if (TREE_CODE_CLASS (TREE_CODE (t)) == 't')
        {
          tree nt = target_type (t);
-         if (IS_AGGR_TYPE (nt) && decl_function_context (TYPE_STUB_DECL (nt)))
+         if (IS_AGGR_TYPE (nt) && decl_function_context (TYPE_MAIN_DECL (nt)))
            {
              cp_error ("type `%T' composed from a local class is not a valid template-argument", t);
              cp_error ("  trying to instantiate `%D'", tmpl);
@@ -2696,6 +2707,12 @@ do_function_instantiation (declspecs, declarator, storage)
   tree result = NULL_TREE;
   int extern_p = 0;
 
+  if (! DECL_LANG_SPECIFIC (decl))
+    {
+      cp_error ("explicit instantiation of non-template `%#D'", decl);
+      return;
+    }
+
   /* If we've already seen this template instance, use it.  */
   if (name = DECL_ASSEMBLER_NAME (decl),
       fn = IDENTIFIER_GLOBAL_VALUE (name),
index e5eb647..8fbd59b 100644 (file)
@@ -1625,6 +1625,10 @@ perm_manip (t)
 {
   if (TREE_PERMANENT (t))
     return t;
+  /* Support `void f () { extern int i; A<&i> a; }' */
+  if ((TREE_CODE (t) == VAR_DECL || TREE_CODE (t) == FUNCTION_DECL)
+      && TREE_PUBLIC (t))
+    return copy_node (t);
   return NULL_TREE;
 }