decl2.c (finish_file): Don't call import_export_decl for functions that are not defined.
authorMark Mitchell <mark@codesourcery.com>
Sat, 26 Apr 2003 01:27:09 +0000 (01:27 +0000)
committerMark Mitchell <mmitchel@gcc.gnu.org>
Sat, 26 Apr 2003 01:27:09 +0000 (01:27 +0000)
* decl2.c (finish_file): Don't call import_export_decl for
functions that are not defined.
(handle_class_head): Robustify.
* pt.c (instantiate_decl): Do not call cp_finish_decl for
variables that are not defined.

* g++.old-deja/g++.pt/instantiate12.C: Explicit instantiate
initialized static data members.

From-SVN: r66095

gcc/cp/ChangeLog
gcc/cp/decl2.c
gcc/cp/pt.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.old-deja/g++.pt/instantiate12.C

index f246bee225f8fba45d1f68293bc6f2dee64a19bc..e4b5602f61c68d7a787e39a7303d64637ba36764 100644 (file)
@@ -1,3 +1,11 @@
+2003-04-25  Mark Mitchell  <mark@codesourcery.com>
+
+       * decl2.c (finish_file): Don't call import_export_decl for
+       functions that are not defined.
+       (handle_class_head): Robustify.
+       * pt.c (instantiate_decl): Do not call cp_finish_decl for
+       variables that are not defined.
+
 2003-04-24  Sylvain Pion  <Sylvain.Pion@mpi-sb.mpg.de>
 
         * call.c (print_z_candidates): Fix off by one error.
index 3f9c66fd4d4abaa8bd0531f669e5efdfd5037aef..a52bdaa65fafa03c4b0886219a3cb3ac26bbb9b7 100644 (file)
@@ -2730,9 +2730,7 @@ finish_file ()
       for (i = 0; i < deferred_fns_used; ++i)
        {
          tree decl = VARRAY_TREE (deferred_fns, i);
-         
-         import_export_decl (decl);
-         
+
          /* Does it need synthesizing?  */
          if (DECL_ARTIFICIAL (decl) && ! DECL_INITIAL (decl)
              && TREE_USED (decl)
@@ -2749,6 +2747,15 @@ finish_file ()
              reconsider = true;
            }
 
+         /* If the function has no body, avoid calling
+            import_export_decl.  On a system without weak symbols,
+            calling import_export_decl will make an inline template
+            instantiation "static", which will result in errors about
+            the use of undefined functions if there is no body for
+            the function.  */
+         if (!DECL_SAVED_TREE (decl))
+           continue;
+
          /* We lie to the back-end, pretending that some functions
             are not defined when they really are.  This keeps these
             functions from being put out unnecessarily.  But, we must
@@ -4668,7 +4675,10 @@ handle_class_head (enum tag_types tag_kind, tree scope, tree id,
   
   if (!decl)
     {
-      decl = TYPE_MAIN_DECL (xref_tag (tag_kind, id, attributes, false));
+      decl = xref_tag (tag_kind, id, attributes, false);
+      if (decl == error_mark_node)
+       return error_mark_node;
+      decl = TYPE_MAIN_DECL (decl);
       xrefd_p = true;
     }
 
index 74f497e1cf699a443b201bbe15a6594719a5bfe8..9faf0353e0f47df3e509d8b3f2983c03c7999fee 100644 (file)
@@ -10927,11 +10927,6 @@ instantiate_decl (d, defer_ok)
   if (need_push)
     push_to_top_level ();
 
-  /* We're now committed to instantiating this template.  Mark it as
-     instantiated so that recursive calls to instantiate_decl do not
-     try to instantiate it again.  */
-  DECL_TEMPLATE_INSTANTIATED (d) = 1;
-
   /* Regenerate the declaration in case the template has been modified
      by a subsequent redeclaration.  */
   regenerate_decl_from_template (d, td);
@@ -10950,10 +10945,36 @@ instantiate_decl (d, defer_ok)
       DECL_IN_AGGR_P (d) = 0;
       import_export_decl (d);
       DECL_EXTERNAL (d) = ! DECL_NOT_REALLY_EXTERN (d);
-      cp_finish_decl (d, 
-                     (!DECL_INITIALIZED_IN_CLASS_P (d) 
-                      ? DECL_INITIAL (d) : NULL_TREE),
-                     NULL_TREE, 0);
+
+      if (DECL_EXTERNAL (d))
+       {
+         /* The fact that this code is executing indicates that:
+            
+            (1) D is a template static data member, for which a
+                definition is available.
+
+            (2) An implicit or explicit instantiation has occured.
+
+            (3) We are not going to emit a definition of the static
+                data member at this time.
+
+            This situation is peculiar, but it occurs on platforms
+            without weak symbols when performing an implicit
+            instantiation.  There, we cannot implicitly instantiate a
+            defined static data member in more than one translation
+            unit, so import_export_decl marks the declaration as
+            external; we must rely on explicit instantiation.  */
+       }
+      else
+       {
+         /* Mark D as instantiated so that recursive calls to
+            instantiate_decl do not try to instantiate it again.  */
+         DECL_TEMPLATE_INSTANTIATED (d) = 1;
+         cp_finish_decl (d, 
+                         (!DECL_INITIALIZED_IN_CLASS_P (d) 
+                          ? DECL_INITIAL (d) : NULL_TREE),
+                         NULL_TREE, 0);
+       }
     }
   else if (TREE_CODE (d) == FUNCTION_DECL)
     {
@@ -10962,6 +10983,10 @@ instantiate_decl (d, defer_ok)
       tree tmpl_parm;
       tree spec_parm;
 
+      /* Mark D as instantiated so that recursive calls to
+        instantiate_decl do not try to instantiate it again.  */
+      DECL_TEMPLATE_INSTANTIATED (d) = 1;
+
       /* Save away the current list, in case we are instantiating one
         template from within the body of another.  */
       saved_local_specializations = local_specializations;
index bfc4ff2cbd804c4836397feb0ef74adec763d963..2590adf336a4bbc703ee24982cf4cf538bcf421e 100644 (file)
@@ -1,3 +1,8 @@
+2003-04-25  Mark Mitchell  <mark@codesourcery.com>
+
+       * g++.old-deja/g++.pt/instantiate12.C: Explicit instantiate
+       initialized static data members.
+
 2003-04-25  H.J. Lu <hjl@gnu.org>
 
        * gcc.dg/ia64-sync-4.c: New test.
index e1cc8534c8d3cc60e64f1bbc177acde755683359..ce1efe0c7314a067d9e8ebfbfb72099e6cd867ce 100644 (file)
@@ -48,3 +48,13 @@ int main ()
     return 9;
   return 0;
 }
+
+// On platforms that do not have weak symbols, these static data
+// members must be explicitly instantiated.  The iflag and jflag data
+// members should not have to be explicitly instantiated because their
+// const-ness should allow the compiler to elide references to the
+// actual variables.
+template const bool X<int>::cflag;
+template const bool X<int>::flag;
+template const bool X<float>::cflag;
+template const bool X<float>::flag;