class.c (finish_vtbls): Copy BINFO_VIRTUALs before using it to intialize a vtable.
authorMark Mitchell <mark@codesourcery.com>
Tue, 25 May 1999 15:31:38 +0000 (15:31 +0000)
committerMark Mitchell <mmitchel@gcc.gnu.org>
Tue, 25 May 1999 15:31:38 +0000 (15:31 +0000)
* class.c (finish_vtbls): Copy BINFO_VIRTUALs before using it to
intialize a vtable.
* cp-tree.h (NAMESPACE_LEVEL): Reformat.
(lang_decl_flags): Document MEMFUNC_POINTER_TO.  Save four bytes
by combining TEMPLATE_INFO and LEVEL into a single union.
(DECL_TEMPLATE_INFO): Reformat.
(DECL_SAVED_TREE): Document.
(DECL_TEMPLATE_INJECT): Remove.
* class.c (finish_struct): Remove code to deal with
DECL_TEMPLATE_INJECT.
* decl.c (maybe_process_template_type_declaration): Handle all new
types in templates uniformly.
* method.c (bulid_overload_identifier): Use CP_DECL_CONTEXT, not
DECL_CONTEXT.
* pt.c (lookup_template_class): Inject template instantiations of
forward-declarations.
(instantiate_class_template): Remove code processing
DECL_TEMPLATE_INJECT.
* pt.c (lookup_template_class): Tweak lookup to find member
templates.
* pt.c (tsubst_expr, case ASM_STMT): Don't tsubst into
ASM_CV_QUAL.
* semantics.c (finish_asm_stmt): Make strings permanent if they're
used in a template.

From-SVN: r27144

12 files changed:
gcc/cp/ChangeLog
gcc/cp/class.c
gcc/cp/cp-tree.h
gcc/cp/decl.c
gcc/cp/method.c
gcc/cp/pt.c
gcc/cp/semantics.c
gcc/testsuite/g++.old-deja/g++.pt/asm1.C [new file with mode: 0644]
gcc/testsuite/g++.old-deja/g++.pt/asm2.C [new file with mode: 0644]
gcc/testsuite/g++.old-deja/g++.pt/inject1.C [new file with mode: 0644]
gcc/testsuite/g++.old-deja/g++.pt/inject2.C [new file with mode: 0644]
gcc/testsuite/g++.old-deja/g++.pt/memclass21.C [new file with mode: 0644]

index 36cb365fee5a39c0a9b155fc689ed936bbfab4e7..32de5b16c0488a5998bfbcd65efd8361dbe97a32 100644 (file)
@@ -1,3 +1,34 @@
+1999-05-25  Mark Mitchell  <mark@codesourcery.com>
+
+       * class.c (finish_vtbls): Copy BINFO_VIRTUALs before using it to
+       intialize a vtable.
+
+       * cp-tree.h (NAMESPACE_LEVEL): Reformat.
+       (lang_decl_flags): Document MEMFUNC_POINTER_TO.  Save four bytes
+       by combining TEMPLATE_INFO and LEVEL into a single union.
+       (DECL_TEMPLATE_INFO): Reformat.
+       (DECL_SAVED_TREE): Document.
+       (DECL_TEMPLATE_INJECT): Remove.
+       * class.c (finish_struct): Remove code to deal with
+       DECL_TEMPLATE_INJECT. 
+
+       * decl.c (maybe_process_template_type_declaration): Handle all new
+       types in templates uniformly.
+       * method.c (bulid_overload_identifier): Use CP_DECL_CONTEXT, not
+       DECL_CONTEXT.
+       * pt.c (lookup_template_class): Inject template instantiations of
+       forward-declarations.
+       (instantiate_class_template): Remove code processing
+       DECL_TEMPLATE_INJECT.
+       
+       * pt.c (lookup_template_class): Tweak lookup to find member
+       templates.
+
+       * pt.c (tsubst_expr, case ASM_STMT): Don't tsubst into
+       ASM_CV_QUAL.
+       * semantics.c (finish_asm_stmt): Make strings permanent if they're
+       used in a template.
+       
 1999-05-25  Jason Merrill  <jason@yorick.cygnus.com>
 
        * typeck.c (casts_away_constness, casts_away_constness_r): Strip both
index e3d5bb9549002262f020f09a9bcc0aa5b0019155..c6d6bcc84e8d827df48c41d48eb0a9f3c25e53eb 100644 (file)
@@ -2170,9 +2170,14 @@ finish_vtbls (binfo, do_self, t)
          decl = BINFO_VTABLE (binfo);
          context = DECL_CONTEXT (decl);
          DECL_CONTEXT (decl) = 0;
-         if (DECL_INITIAL (decl) != BINFO_VIRTUALS (binfo))
-           DECL_INITIAL (decl) = build_nt (CONSTRUCTOR, NULL_TREE,
-                                           BINFO_VIRTUALS (binfo));
+
+         /* We make a copy here in case we need to replace pure
+            virtual functions with __pure_virtual.  We don't want to
+            mess up BINFO_VIRTUALS when we do this.  */
+         DECL_INITIAL (decl) = copy_list (BINFO_VIRTUALS (binfo));
+         DECL_INITIAL (decl) = build_nt (CONSTRUCTOR, NULL_TREE,
+                                         DECL_INITIAL (decl));
+
          cp_finish_decl (decl, DECL_INITIAL (decl), NULL_TREE, 0, 0);
          DECL_CONTEXT (decl) = context;
        }
@@ -4197,24 +4202,6 @@ finish_struct (t, attributes, warn_anon)
 
   if (processing_template_decl)
     {
-      tree d = getdecls ();
-      for (; d; d = TREE_CHAIN (d))
-       {
-         /* If this is the decl for the class or one of the template
-             parms, we've seen all the injected decls.  */
-         if ((TREE_CODE (d) == TYPE_DECL
-              && (TREE_TYPE (d) == t
-                  || TREE_CODE (TREE_TYPE (d)) == TEMPLATE_TYPE_PARM
-                  || TREE_CODE (TREE_TYPE (d)) == TEMPLATE_TEMPLATE_PARM))
-             || TREE_CODE (d) == CONST_DECL)
-           break;
-         /* Don't inject cache decls.  */
-         else if (IDENTIFIER_TEMPLATE (DECL_NAME (d)))
-           continue;
-         DECL_TEMPLATE_INJECT (CLASSTYPE_TI_TEMPLATE (t))
-           = tree_cons (NULL_TREE, d,
-                        DECL_TEMPLATE_INJECT (CLASSTYPE_TI_TEMPLATE (t)));
-       }
       finish_struct_methods (t);
       TYPE_SIZE (t) = integer_zero_node;
     }      
index a482824c15ed1638c403091917d90a6d91b22655..4971b7999d4bde0635a865534f8005cc389525e0 100644 (file)
@@ -1136,7 +1136,8 @@ struct lang_type
    && TREE_VALUE (TYPE_RAISES_EXCEPTIONS (NODE)) == NULL_TREE)
 
 /* The binding level associated with the namespace.  */
-#define NAMESPACE_LEVEL(NODE) (DECL_LANG_SPECIFIC(NODE)->decl_flags.level)
+#define NAMESPACE_LEVEL(NODE) \
+  (DECL_LANG_SPECIFIC(NODE)->decl_flags.u.level)
 \f
 
 /* If a DECL has DECL_LANG_SPECIFIC, it is either a lang_decl_flags or
@@ -1180,9 +1181,19 @@ struct lang_decl_flags
 
   tree access;
   tree context;
+
+  /* In a template FUNCTION_DECL, this is DECL_SAVED_TREE.
+     In a non-template FUNCTION_DECL, this is DECL_MEMFUNC_POINTER_TO.
+     In a FIELD_DECL, this is DECL_MEMFUNC_POINTING_TO.  */
   tree memfunc_pointer_to;
-  tree template_info;
-  struct binding_level *level;
+
+  union {
+    /* In a FUNCTION_DECL, this is DECL_TEMPLATE_INFO.  */
+    tree template_info;
+
+    /* In a NAMESPACE_DECL, this is NAMESPACE_LEVEL.  */
+    struct binding_level *level;
+  } u;
 };
 
 struct lang_decl
@@ -1392,7 +1403,8 @@ struct lang_decl
 #define DECL_MEMFUNC_POINTING_TO(NODE) (DECL_LANG_SPECIFIC(NODE)->decl_flags.memfunc_pointer_to)
 
 /* For a VAR_DECL or FUNCTION_DECL: template-specific information.  */
-#define DECL_TEMPLATE_INFO(NODE) (DECL_LANG_SPECIFIC(NODE)->decl_flags.template_info)
+#define DECL_TEMPLATE_INFO(NODE) \
+  (DECL_LANG_SPECIFIC(NODE)->decl_flags.u.template_info)
 
 /* Template information for a RECORD_TYPE or UNION_TYPE.  */
 #define CLASSTYPE_TEMPLATE_INFO(NODE) (TYPE_LANG_SPECIFIC(NODE)->template_info)
@@ -1475,7 +1487,10 @@ struct lang_decl
    the class definition is complete.  */
 #define TEMPLATE_PARMS_FOR_INLINE(NODE) TREE_LANG_FLAG_1 (NODE)
 
+/* In a template FUNCTION_DECL, the tree structure that will be
+   substituted into to obtain instantiations.  */
 #define DECL_SAVED_TREE(NODE)          DECL_MEMFUNC_POINTER_TO (NODE)
+
 #define COMPOUND_STMT_NO_SCOPE(NODE)   TREE_LANG_FLAG_0 (NODE)
 #define NEW_EXPR_USE_GLOBAL(NODE)      TREE_LANG_FLAG_0 (NODE)
 #define DELETE_EXPR_USE_GLOBAL(NODE)   TREE_LANG_FLAG_0 (NODE)
@@ -1898,7 +1913,6 @@ extern int flag_new_for_scope;
 
    This list is not used for static variable templates.  */
 #define DECL_TEMPLATE_SPECIALIZATIONS(NODE)     DECL_SIZE(NODE)
-#define DECL_TEMPLATE_INJECT(NODE)     DECL_INITIAL(NODE)
 
 /* Nonzero for a DECL which is actually a template parameter.  */
 #define DECL_TEMPLATE_PARM_P(NODE) \
index cd9955536b947c18583555b86aa716b57bc27d77..d990a82f715c09c860f734d172fb216630f64032 100644 (file)
@@ -2783,25 +2783,7 @@ maybe_process_template_type_declaration (type, globalize, b)
                          || TREE_CODE (type) == ENUMERAL_TYPE, 0);
                          
                          
-      if (/* If !GLOBALIZE then we are looking at a definition.
-            It may not be a primary template.  (For example, in:
-                 
-              template <class T>
-              struct S1 { class S2 {}; }
-                 
-            we have to push_template_decl for S2.)  */
-         (processing_template_decl && !globalize)
-         /* If we are declaring a friend template class, we will
-            have GLOBALIZE set, since something like:
-
-              template <class T>
-              struct S1 {
-                template <class U>
-                friend class S2; 
-              };
-
-            declares S2 to be at global scope.  */
-         || PROCESSING_REAL_TEMPLATE_DECL_P ())
+      if (processing_template_decl)
        {
          /* This may change after the call to
             push_template_decl_real, but we want the original value.  */
index 48701696bbd4bd27e6e253e6506b20c0c3084d38..873ccd411d28d653695f2895cbc12cfa92384400 100644 (file)
@@ -999,8 +999,8 @@ build_overload_identifier (name)
       && CLASS_TYPE_P (TREE_TYPE (name))
       && CLASSTYPE_TEMPLATE_INFO (TREE_TYPE (name))
       && (PRIMARY_TEMPLATE_P (CLASSTYPE_TI_TEMPLATE (TREE_TYPE (name)))
-         || (TREE_CODE (DECL_CONTEXT (CLASSTYPE_TI_TEMPLATE 
-                                      (TREE_TYPE (name))))
+         || (TREE_CODE (CP_DECL_CONTEXT (CLASSTYPE_TI_TEMPLATE 
+                                         (TREE_TYPE (name))))
              == FUNCTION_DECL)))
     {
       /* NAME is the TYPE_DECL for a template specialization.  */
index 702c48fab12369ac737859116cd4d8dcc1dea72d..2592ab4459854f57a48a8286811db811c86ddfa0 100644 (file)
@@ -3613,12 +3613,8 @@ lookup_template_class (d1, arglist, in_decl, context, entering_scope)
        {
          if (context)
            push_decl_namespace (context);
-         if (current_class_type != NULL_TREE)
-           template =
-             maybe_get_template_decl_from_type_decl
-             (IDENTIFIER_CLASS_VALUE (d1));
-         if (template == NULL_TREE)
-           template = lookup_name_nonclass (d1);
+         template = lookup_name (d1, /*prefer_type=*/0);
+         template = maybe_get_template_decl_from_type_decl (template);
          if (context)
            pop_decl_namespace ();
        }
@@ -3834,24 +3830,35 @@ lookup_template_class (d1, arglist, in_decl, context, entering_scope)
          if (found)
            found = TREE_VALUE (found);
        }
-      
+
       if (found)
        {
          pop_momentary ();
          return found;
        }
 
-      /* Since we didn't find the type, we'll have to create it.
-        Since we'll be saving this type on the
-        DECL_TEMPLATE_INSTANTIATIONS list, it must be permanent.  */
-      push_obstacks (&permanent_obstack, &permanent_obstack);
-      
       /* This type is a "partial instantiation" if any of the template
         arguments still inolve template parameters.  Note that we set
         IS_PARTIAL_INSTANTIATION for partial specializations as
         well.  */
       is_partial_instantiation = uses_template_parms (arglist);
 
+      if (!is_partial_instantiation 
+         && !PRIMARY_TEMPLATE_P (template)
+         && TREE_CODE (CP_DECL_CONTEXT (template)) == NAMESPACE_DECL)
+       {
+         pop_momentary ();
+         found = xref_tag_from_type (TREE_TYPE (template),
+                                     DECL_NAME (template),
+                                     /*globalize=*/1);
+         return found;
+       }
+                                   
+      /* Since we didn't find the type, we'll have to create it.
+        Since we'll be saving this type on the
+        DECL_TEMPLATE_INSTANTIATIONS list, it must be permanent.  */
+      push_obstacks (&permanent_obstack, &permanent_obstack);
+      
       /* Create the type.  */
       if (TREE_CODE (template_type) == ENUMERAL_TYPE)
        {
@@ -5111,23 +5118,6 @@ instantiate_class_template (type)
        --processing_template_decl;
     }
 
-  /* This does injection for friend functions. */
-  if (!processing_template_decl)
-    {
-      t = tsubst (DECL_TEMPLATE_INJECT (template), args,
-                 /*complain=*/1, NULL_TREE);
-
-      for (; t; t = TREE_CHAIN (t))
-       {
-         tree d = TREE_VALUE (t);
-
-         if (TREE_CODE (d) == TYPE_DECL)
-           /* Already injected.  */;
-         else
-           pushdecl (d);
-       }
-    } 
-
   for (t = TYPE_FIELDS (type); t; t = TREE_CHAIN (t))
     if (TREE_CODE (t) == FIELD_DECL)
       {
@@ -7200,7 +7190,7 @@ tsubst_expr (t, args, complain, in_decl)
 
     case ASM_STMT:
       lineno = TREE_COMPLEXITY (t);
-      finish_asm_stmt (tsubst_expr (ASM_CV_QUAL (t), args, complain, in_decl),
+      finish_asm_stmt (ASM_CV_QUAL (t),
                       tsubst_expr (ASM_STRING (t), args, complain, in_decl),
                       tsubst_expr (ASM_OUTPUTS (t), args, complain, in_decl),
                       tsubst_expr (ASM_INPUTS (t), args, complain, in_decl), 
index 847a982e260434bd51422ce60b205573167d3ee0..5be0ae1832678f87643d8edeba55cc88d243c104 100644 (file)
@@ -718,7 +718,7 @@ finish_compound_stmt (has_no_scope, compound_stmt)
 
 void
 finish_asm_stmt (cv_qualifier, string, output_operands,
-                     input_operands, clobbers)
+                input_operands, clobbers)
      tree cv_qualifier;
      tree string;
      tree output_operands;
@@ -726,7 +726,20 @@ finish_asm_stmt (cv_qualifier, string, output_operands,
      tree clobbers;
 {
   if (TREE_CHAIN (string))
-    string = combine_strings (string);
+    {
+      if (processing_template_decl)
+       {
+         /* We need to build the combined string on the permanent
+            obstack so that we can use it during instantiations.  */
+         push_obstacks_nochange ();
+         end_temporary_allocation ();
+       }
+
+      string = combine_strings (string);
+
+      if (processing_template_decl)
+       pop_obstacks ();
+    }
 
   if (processing_template_decl)
     {
diff --git a/gcc/testsuite/g++.old-deja/g++.pt/asm1.C b/gcc/testsuite/g++.old-deja/g++.pt/asm1.C
new file mode 100644 (file)
index 0000000..d093002
--- /dev/null
@@ -0,0 +1,16 @@
+// Build don't link:
+// Origin: "Weidmann, Nicholas" <nicholas.weidmann@swx.ch>
+// Skip if not target: i?86-*-linux*
+
+template<int i> int foo(int v)
+{
+       __asm__ __volatile__("addl %1, %0" : "=a" (v) : "b" (i));
+
+       return v;
+}
+
+int bar(int i)
+{
+       return foo<123>(i);
+}
+
diff --git a/gcc/testsuite/g++.old-deja/g++.pt/asm2.C b/gcc/testsuite/g++.old-deja/g++.pt/asm2.C
new file mode 100644 (file)
index 0000000..4f6bd0a
--- /dev/null
@@ -0,0 +1,23 @@
+// Build don't link:
+// Origin: "Weidmann, Nicholas" <nicholas.weidmann@swx.ch>
+// Skip if not target: i?86-*-linux*
+
+typedef void (function_ptr)(int);
+
+void foo(int)
+{
+}
+
+template<function_ptr ptr> void doit(int i)
+{
+       __asm__("pushl %0\n\t"
+                 "call *%1\n\t"
+                 "popl %0"
+                 :
+                 : "a" (i), "b" (ptr));
+}
+
+void bar()
+{
+       doit<foo>(123);
+}
diff --git a/gcc/testsuite/g++.old-deja/g++.pt/inject1.C b/gcc/testsuite/g++.old-deja/g++.pt/inject1.C
new file mode 100644 (file)
index 0000000..8d35120
--- /dev/null
@@ -0,0 +1,11 @@
+// Build don't link:
+// Origin: Mark Mitchell <mark@codesourcery.com>
+
+template <int I>
+struct S {
+  struct T* x;
+};
+
+template struct S<2>;
+
+T* t;
diff --git a/gcc/testsuite/g++.old-deja/g++.pt/inject2.C b/gcc/testsuite/g++.old-deja/g++.pt/inject2.C
new file mode 100644 (file)
index 0000000..e94ac1c
--- /dev/null
@@ -0,0 +1,15 @@
+// Build don't link:
+// Origin: Mark Mitchell <mark@codesourcery.com>
+// Special g++ Options: -Wno-non-template-friend
+
+template<int I>
+class C {
+    friend void f(struct X *);
+};
+
+template class C<0>;
+
+class D {
+    friend void f(struct X*);
+};
+
diff --git a/gcc/testsuite/g++.old-deja/g++.pt/memclass21.C b/gcc/testsuite/g++.old-deja/g++.pt/memclass21.C
new file mode 100644 (file)
index 0000000..a3217e6
--- /dev/null
@@ -0,0 +1,11 @@
+// Build don't link:
+// Origin: <Corey Kosak> kosak@cs.cmu.edu
+
+struct moo {
+  template<bool x> struct cow {};
+
+  template<bool x>
+  struct moo2 {
+    void func(cow<x> &c) { }
+  };
+};