PR c++/23699
authormmitchel <mmitchel@138bc75d-0d04-0410-961f-82ee72b054a4>
Sat, 3 Sep 2005 18:27:39 +0000 (18:27 +0000)
committermmitchel <mmitchel@138bc75d-0d04-0410-961f-82ee72b054a4>
Sat, 3 Sep 2005 18:27:39 +0000 (18:27 +0000)
* decl2.c (mark_used): Always instantiate static data members
initialized by constant expressions.
* pt.c (instantiate_decl): Instantiate the initializers for static
data members initialized by constant expressions.

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

gcc/cp/pt.c

index 773d865..b159077 100644 (file)
@@ -11371,6 +11371,7 @@ instantiate_decl (tree d, int defer_ok,
   bool pattern_defined;
   int need_push;
   location_t saved_loc = input_location;
+  bool external_p;
 
   /* This function should only be used to instantiate templates for
      functions and static member variables.  */
@@ -11488,17 +11489,32 @@ instantiate_decl (tree d, int defer_ok,
       pop_access_scope (d);
     }
 
-  /* Do not instantiate templates that we know will be defined
-     elsewhere.  */
-  if (DECL_INTERFACE_KNOWN (d)
-      && DECL_REALLY_EXTERN (d)
-      && ! (TREE_CODE (d) == FUNCTION_DECL
-           && DECL_INLINE (d)))
+  /* Check to see whether we know that this template will be
+     instantiated in some other file, as with "extern template"
+     extension.  */
+  external_p = (DECL_INTERFACE_KNOWN (d) && DECL_REALLY_EXTERN (d));
+  /* In general, we do not instantiate such templates...  */
+  if (external_p
+      /* ... but we instantiate inline functions so that we can inline
+        them and ... */
+      && ! (TREE_CODE (d) == FUNCTION_DECL && DECL_INLINE (d))
+      /* ... we instantiate static data members whose values are
+        needed in integral constant expressions.  */
+      && ! (TREE_CODE (d) == VAR_DECL 
+           && DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (d)))
     goto out;
   /* Defer all other templates, unless we have been explicitly
-     forbidden from doing so.  We restore the source position here
-     because it's used by add_pending_template.  */
-  else if (! pattern_defined || defer_ok)
+     forbidden from doing so.  */
+  if (/* If there is no definition, we cannot instantiate the
+        template.  */
+      ! pattern_defined 
+      /* If it's OK to postpone instantiation, do so.  */
+      || defer_ok
+      /* If this is a static data member that will be defined
+        elsewhere, we don't want to instantiate the entire data
+        member, but we do want to instantiate the initializer so that
+        we can substitute that elsewhere.  */
+      || (external_p && TREE_CODE (d) == VAR_DECL))
     {
       /* The definition of the static data member is now required so
         we must substitute the initializer.  */
@@ -11514,6 +11530,8 @@ instantiate_decl (tree d, int defer_ok,
          pop_nested_class ();
        }
 
+      /* We restore the source position here because it's used by
+        add_pending_template.  */
       input_location = saved_loc;
 
       if (at_eof && !pattern_defined
@@ -11528,7 +11546,10 @@ instantiate_decl (tree d, int defer_ok,
        pedwarn
          ("explicit instantiation of %qD but no definition available", d);
 
-      add_pending_template (d);
+      /* ??? Historically, we have instantiated inline functions, even
+        when marked as "extern template".  */
+      if (!(external_p && TREE_CODE (d) == VAR_DECL))
+       add_pending_template (d);
       goto out;
     }
   /* Tell the repository that D is available in this translation unit