OSDN Git Service

PR c++/27951
[pf3gnuchains/gcc-fork.git] / gcc / cp / decl2.c
index 10296a7..49e320c 100644 (file)
@@ -82,6 +82,7 @@ static tree prune_vars_needing_no_initialization (tree *);
 static void write_out_vars (tree);
 static void import_export_class (tree);
 static tree get_guard_bits (tree);
+static void determine_visibility_from_class (tree, tree);
 
 /* A list of static class variables.  This is needed, because a
    static class variable can be declared inside the class without
@@ -102,33 +103,31 @@ tree static_ctors;
 tree static_dtors;
 
 \f
-/* Incorporate `const' and `volatile' qualifiers for member functions.
-   FUNCTION is a TYPE_DECL or a FUNCTION_DECL.
-   QUALS is a list of qualifiers.  Returns any explicit
-   top-level qualifiers of the method's this pointer, anything other than
-   TYPE_UNQUALIFIED will be an extension.  */
-
-int
-grok_method_quals (tree ctype, tree function, cp_cv_quals quals)
+
+/* Return a member function type (a METHOD_TYPE), given FNTYPE (a
+   FUNCTION_TYPE), CTYPE (class type), and QUALS (the cv-qualifiers
+   that apply to the function).  */
+
+tree
+build_memfn_type (tree fntype, tree ctype, cp_cv_quals quals)
 {
-  tree fntype = TREE_TYPE (function);
-  tree raises = TYPE_RAISES_EXCEPTIONS (fntype);
-  int type_quals = TYPE_UNQUALIFIED;
-  int this_quals = TYPE_UNQUALIFIED;
+  tree raises;
+  int type_quals;
 
-  type_quals = quals & ~TYPE_QUAL_RESTRICT;
-  this_quals = quals & TYPE_QUAL_RESTRICT;
+  if (fntype == error_mark_node || ctype == error_mark_node)
+    return error_mark_node;
 
+  type_quals = quals & ~TYPE_QUAL_RESTRICT;
   ctype = cp_build_qualified_type (ctype, type_quals);
   fntype = build_method_type_directly (ctype, TREE_TYPE (fntype),
                                       (TREE_CODE (fntype) == METHOD_TYPE
                                        ? TREE_CHAIN (TYPE_ARG_TYPES (fntype))
                                        : TYPE_ARG_TYPES (fntype)));
+  raises = TYPE_RAISES_EXCEPTIONS (fntype);
   if (raises)
     fntype = build_exception_variant (fntype, raises);
 
-  TREE_TYPE (function) = fntype;
-  return this_quals;
+  return fntype;
 }
 
 /* Build a PARM_DECL with NAME and TYPE, and set DECL_ARG_TYPE
@@ -148,7 +147,7 @@ cp_build_parm_decl (tree name, tree type)
 /* Returns a PARM_DECL for a parameter of the indicated TYPE, with the
    indicated NAME.  */
 
-static tree
+tree
 build_artificial_parm (tree name, tree type)
 {
   tree parm = cp_build_parm_decl (name, type);
@@ -256,11 +255,9 @@ maybe_retrofit_in_chrg (tree fn)
    QUALS are the qualifiers for the this pointer.  */
 
 void
-grokclassfn (tree ctype, tree function, enum overload_flags flags,
-            cp_cv_quals quals)
+grokclassfn (tree ctype, tree function, enum overload_flags flags)
 {
   tree fn_name = DECL_NAME (function);
-  cp_cv_quals this_quals = TYPE_UNQUALIFIED;
 
   /* Even within an `extern "C"' block, members get C++ linkage.  See
      [dcl.link] for details.  */
@@ -273,28 +270,6 @@ grokclassfn (tree ctype, tree function, enum overload_flags flags,
       DECL_NAME (function) = fn_name;
     }
 
-  if (quals)
-    this_quals = grok_method_quals (ctype, function, quals);
-
-  if (TREE_CODE (TREE_TYPE (function)) == METHOD_TYPE)
-    {
-      /* Must add the class instance variable up front.  */
-      /* Right now we just make this a pointer.  But later
-        we may wish to make it special.  */
-      tree type = TREE_VALUE (TYPE_ARG_TYPES (TREE_TYPE (function)));
-      tree qual_type;
-      tree parm;
-
-      /* The `this' parameter is implicitly `const'; it cannot be
-        assigned to.  */
-      this_quals |= TYPE_QUAL_CONST;
-      qual_type = cp_build_qualified_type (type, this_quals);
-      parm = build_artificial_parm (this_identifier, qual_type);
-      cp_apply_type_quals_to_decl (this_quals, parm);
-      TREE_CHAIN (parm) = DECL_ARGUMENTS (function);
-      DECL_ARGUMENTS (function) = parm;
-    }
-
   DECL_CONTEXT (function) = ctype;
 
   if (flags == DTOR_FLAG)
@@ -477,16 +452,9 @@ check_member_template (tree tmpl)
        error ("invalid declaration of member template %q#D in local class",
               decl);
 
-      if (TREE_CODE (decl) == FUNCTION_DECL && DECL_VIRTUAL_P (decl))
-       {
-         /* 14.5.2.3 [temp.mem]
-
-            A member function template shall not be virtual.  */
-         error
-           ("invalid use of %<virtual%> in template declaration of %q#D",
-            decl);
-         DECL_VIRTUAL_P (decl) = 0;
-       }
+      /* The parser rejects any use of virtual in a function template.  */
+      gcc_assert (!(TREE_CODE (decl) == FUNCTION_DECL
+                   && DECL_VIRTUAL_P (decl)));
 
       /* The debug-information generating code doesn't know what to do
         with member templates.  */
@@ -737,12 +705,12 @@ note_vague_linkage_var (tree var)
 }
 
 /* We have just processed the DECL, which is a static data member.
-   Its initializer, if present, is INIT.  The ASMSPEC_TREE, if
-   present, is the assembly-language name for the data member.
-   FLAGS is as for cp_finish_decl.  */
+   The other parameters are as for cp_finish_decl.  */
 
 void
-finish_static_data_member_decl (tree decl, tree init, tree asmspec_tree,
+finish_static_data_member_decl (tree decl,
+                               tree init, bool init_const_expr_p,
+                               tree asmspec_tree,
                                int flags)
 {
   gcc_assert (TREE_PUBLIC (decl));
@@ -752,9 +720,6 @@ finish_static_data_member_decl (tree decl, tree init, tree asmspec_tree,
   /* We cannot call pushdecl here, because that would fill in the
      TREE_CHAIN of our decl.  Instead, we modify cp_finish_decl to do
      the right thing, namely, to put this decl out straight away.  */
-  /* current_class_type can be NULL_TREE in case of error.  */
-  if (!asmspec_tree && current_class_type)
-    DECL_INITIAL (decl) = error_mark_node;
 
   if (! processing_template_decl)
     note_vague_linkage_var (decl);
@@ -783,31 +748,18 @@ finish_static_data_member_decl (tree decl, tree init, tree asmspec_tree,
   DECL_INITIAL (decl) = init;
   DECL_IN_AGGR_P (decl) = 1;
 
-  cp_finish_decl (decl, init, asmspec_tree, flags);
+  cp_finish_decl (decl, init, init_const_expr_p, asmspec_tree, flags);
 }
 
-/* Process the specs, declarator (NULL if omitted) and width (NULL if omitted)
-   of a structure component, returning a _DECL node.
-   QUALS is a list of type qualifiers for this decl (such as for declaring
-   const member functions).
-
-   This is done during the parsing of the struct declaration.
-   The _DECL nodes are chained together and the lot of them
-   are ultimately passed to `build_struct' to make the RECORD_TYPE node.
-
-   If class A defines that certain functions in class B are friends, then
-   the way I have set things up, it is B who is interested in permission
-   granted by A.  However, it is in A's context that these declarations
-   are parsed.  By returning a void_type_node, class A does not attempt
-   to incorporate the declarations of the friends within its structure.
-
-   DO NOT MAKE ANY CHANGES TO THIS CODE WITHOUT MAKING CORRESPONDING
-   CHANGES TO CODE IN `start_method'.  */
+/* DECLARATOR and DECLSPECS correspond to a class member.  The other
+   parameters are as for cp_finish_decl.  Return the DECL for the
+   class member declared.  */
 
 tree
 grokfield (const cp_declarator *declarator,
           cp_decl_specifier_seq *declspecs,
-          tree init, tree asmspec_tree,
+          tree init, bool init_const_expr_p,
+          tree asmspec_tree,
           tree attrlist)
 {
   tree value;
@@ -946,8 +898,8 @@ grokfield (const cp_declarator *declarator,
   switch (TREE_CODE (value))
     {
     case VAR_DECL:
-      finish_static_data_member_decl (value, init, asmspec_tree,
-                                     flags);
+      finish_static_data_member_decl (value, init, init_const_expr_p,
+                                     asmspec_tree, flags);
       return value;
 
     case FIELD_DECL:
@@ -955,7 +907,8 @@ grokfield (const cp_declarator *declarator,
        error ("%<asm%> specifiers are not permitted on non-static data members");
       if (DECL_INITIAL (value) == error_mark_node)
        init = error_mark_node;
-      cp_finish_decl (value, init, NULL_TREE, flags);
+      cp_finish_decl (value, init, /*init_const_expr_p=*/false,
+                     NULL_TREE, flags);
       DECL_INITIAL (value) = init;
       DECL_IN_AGGR_P (value) = 1;
       return value;
@@ -963,10 +916,11 @@ grokfield (const cp_declarator *declarator,
     case  FUNCTION_DECL:
       if (asmspec)
        set_user_assembler_name (value, asmspec);
-      if (!DECL_FRIEND_P (value))
-       grok_special_member_properties (value);
 
-      cp_finish_decl (value, init, asmspec_tree, flags);
+      cp_finish_decl (value,
+                     /*init=*/NULL_TREE,
+                     /*init_const_expr_p=*/false,
+                     asmspec_tree, flags);
 
       /* Pass friends back this way.  */
       if (DECL_FRIEND_P (value))
@@ -1025,7 +979,7 @@ grokbitfield (const cp_declarator *declarator,
       error ("static member %qD cannot be a bit-field", value);
       return NULL_TREE;
     }
-  cp_finish_decl (value, NULL_TREE, NULL_TREE, 0);
+  finish_decl (value, NULL_TREE, NULL_TREE);
 
   if (width != error_mark_node)
     {
@@ -1155,6 +1109,8 @@ finish_anon_union (tree anon_union_decl)
     }
 
   main_decl = build_anon_union_vars (type, anon_union_decl);
+  if (main_decl == error_mark_node)
+    return;
   if (main_decl == NULL_TREE)
     {
       warning (0, "anonymous union with no members");
@@ -1577,13 +1533,27 @@ maybe_emit_vtables (tree ctype)
 }
 
 /* Like c_determine_visibility, but with additional C++-specific
-   behavior.  */
+   behavior.
+
+   Function-scope entities can rely on the function's visibility because
+   it is set in start_preparsed_function.
+
+   Class-scope entities cannot rely on the class's visibility until the end
+   of the enclosing class definition.
+
+   Note that because namespaces have multiple independent definitions,
+   namespace visibility is handled elsewhere using the #pragma visibility
+   machinery rather than by decorating the namespace declaration.  */
 
 void
 determine_visibility (tree decl)
 {
   tree class_type;
 
+  /* Only relevant for names with external linkage.  */
+  if (!TREE_PUBLIC (decl))
+    return;
+
   /* Cloned constructors and destructors get the same visibility as
      the underlying function.  That should be set up in
      maybe_clone_body.  */
@@ -1607,6 +1577,14 @@ determine_visibility (tree decl)
         so they are automatically handled above.  */
       gcc_assert (TREE_CODE (decl) != VAR_DECL
                  || !DECL_VTABLE_OR_VTT_P (decl));
+
+      if (DECL_FUNCTION_SCOPE_P (decl))
+       {
+         tree fn = DECL_CONTEXT (decl);
+         DECL_VISIBILITY (decl) = DECL_VISIBILITY (fn);
+         DECL_VISIBILITY_SPECIFIED (decl) = DECL_VISIBILITY_SPECIFIED (fn);
+       }
+
       /* Entities not associated with any class just get the
         visibility specified by their attributes.  */
       return;
@@ -1616,33 +1594,62 @@ determine_visibility (tree decl)
      the visibility of their containing class.  */
   if (class_type)
     {
-      if (TARGET_DLLIMPORT_DECL_ATTRIBUTES
-         && lookup_attribute ("dllexport", TYPE_ATTRIBUTES (class_type)))
-       {
-         DECL_VISIBILITY (decl) = VISIBILITY_DEFAULT;
-         DECL_VISIBILITY_SPECIFIED (decl) = 1;
-       }
-      else if (TREE_CODE (decl) == FUNCTION_DECL
-              && DECL_DECLARED_INLINE_P (decl)
-              && visibility_options.inlines_hidden)
-       {
-         /* Don't change it if it has been set explicitly by user.  */
-         if (!DECL_VISIBILITY_SPECIFIED (decl))
-           {
-             DECL_VISIBILITY (decl) = VISIBILITY_HIDDEN;
-             DECL_VISIBILITY_SPECIFIED (decl) = 1;
-           }
-       }
-      else if (CLASSTYPE_VISIBILITY_SPECIFIED (class_type))
+      determine_visibility_from_class (decl, class_type);
+
+      /* Give the target a chance to override the visibility associated
+        with DECL.  */
+      if (TREE_CODE (decl) == VAR_DECL
+         && (DECL_TINFO_P (decl)
+             || (DECL_VTABLE_OR_VTT_P (decl)
+                 /* Construction virtual tables are not exported because
+                    they cannot be referred to from other object files;
+                    their name is not standardized by the ABI.  */
+                 && !DECL_CONSTRUCTION_VTABLE_P (decl)))
+         && TREE_PUBLIC (decl)
+         && !DECL_REALLY_EXTERN (decl)
+         && DECL_VISIBILITY_SPECIFIED (decl)
+         && (!class_type || !CLASSTYPE_VISIBILITY_SPECIFIED (class_type)))
+       targetm.cxx.determine_class_data_visibility (decl);
+    }
+}
+
+static void
+determine_visibility_from_class (tree decl, tree class_type)
+{
+  if (TARGET_DLLIMPORT_DECL_ATTRIBUTES
+      && lookup_attribute ("dllexport", TYPE_ATTRIBUTES (class_type)))
+    {
+      DECL_VISIBILITY (decl) = VISIBILITY_DEFAULT;
+      DECL_VISIBILITY_SPECIFIED (decl) = 1;
+    }
+  else if (TREE_CODE (decl) == FUNCTION_DECL
+          && DECL_DECLARED_INLINE_P (decl)
+          && visibility_options.inlines_hidden)
+    {
+      /* Don't change it if it has been set explicitly by user.  */
+      if (!DECL_VISIBILITY_SPECIFIED (decl))
        {
-         DECL_VISIBILITY (decl) = CLASSTYPE_VISIBILITY (class_type);
+         DECL_VISIBILITY (decl) = VISIBILITY_HIDDEN;
          DECL_VISIBILITY_SPECIFIED (decl) = 1;
        }
-      else if (!DECL_VISIBILITY_SPECIFIED (decl))
-       {
-         DECL_VISIBILITY (decl) = CLASSTYPE_VISIBILITY (class_type);
-         DECL_VISIBILITY_SPECIFIED (decl) = 0;
-       }
+    }
+  else if (CLASSTYPE_VISIBILITY_SPECIFIED (class_type))
+    {
+      DECL_VISIBILITY (decl) = CLASSTYPE_VISIBILITY (class_type);
+      DECL_VISIBILITY_SPECIFIED (decl) = 1;
+    }
+  else if (TYPE_CLASS_SCOPE_P (class_type))
+    determine_visibility_from_class (decl, TYPE_CONTEXT (class_type));
+  else if (TYPE_FUNCTION_SCOPE_P (class_type))
+    {
+      tree fn = TYPE_CONTEXT (class_type);
+      DECL_VISIBILITY (decl) = DECL_VISIBILITY (fn);
+      DECL_VISIBILITY_SPECIFIED (decl) = DECL_VISIBILITY_SPECIFIED (fn);
+    }
+  else if (!DECL_VISIBILITY_SPECIFIED (decl))
+    {
+      DECL_VISIBILITY (decl) = CLASSTYPE_VISIBILITY (class_type);
+      DECL_VISIBILITY_SPECIFIED (decl) = 0;
     }
 }
 
@@ -1795,9 +1802,13 @@ import_export_decl (tree decl)
              /* The generic C++ ABI says that class data is always
                 COMDAT, even if there is a key function.  Some
                 variants (e.g., the ARM EABI) says that class data
-                only has COMDAT linkage if the class data might
-                be emitted in more than one translation unit.  */
+                only has COMDAT linkage if the class data might be
+                emitted in more than one translation unit.  When the
+                key method can be inline and is inline, we still have
+                to arrange for comdat even though
+                class_data_always_comdat is false.  */
              if (!CLASSTYPE_KEY_METHOD (class_type)
+                 || DECL_DECLARED_INLINE_P (CLASSTYPE_KEY_METHOD (class_type))
                  || targetm.cxx.class_data_always_comdat ())
                {
                  /* The ABI requires COMDAT linkage.  Normally, we
@@ -1836,7 +1847,9 @@ import_export_decl (tree decl)
              if (CLASSTYPE_INTERFACE_KNOWN (type)
                  && !CLASSTYPE_INTERFACE_ONLY (type))
                {
-                 comdat_p = targetm.cxx.class_data_always_comdat ();
+                 comdat_p = (targetm.cxx.class_data_always_comdat ()
+                             || (CLASSTYPE_KEY_METHOD (type)
+                                 && DECL_DECLARED_INLINE_P (CLASSTYPE_KEY_METHOD (type))));
                  mark_needed (decl);
                  if (!flag_weak)
                    {
@@ -1910,21 +1923,6 @@ import_export_decl (tree decl)
       comdat_linkage (decl);
     }
 
-  /* Give the target a chance to override the visibility associated
-     with DECL.  */
-  if (TREE_CODE (decl) == VAR_DECL
-      && (DECL_TINFO_P (decl)
-         || (DECL_VTABLE_OR_VTT_P (decl)
-             /* Construction virtual tables are not exported because
-                they cannot be referred to from other object files;
-                their name is not standardized by the ABI.  */
-             && !DECL_CONSTRUCTION_VTABLE_P (decl)))
-      && TREE_PUBLIC (decl)
-      && !DECL_REALLY_EXTERN (decl)
-      && DECL_VISIBILITY_SPECIFIED (decl)
-      && (!class_type || !CLASSTYPE_VISIBILITY_SPECIFIED (class_type)))
-    targetm.cxx.determine_class_data_visibility (decl);
-
   DECL_INTERFACE_KNOWN (decl) = 1;
 }
 
@@ -2110,7 +2108,7 @@ start_objects (int method_type, int initp)
 
   /* We cannot allow these functions to be elided, even if they do not
      have external linkage.  And, there's no point in deferring
-     compilation of thes functions; they're all going to have to be
+     compilation of these functions; they're all going to have to be
      out anyhow.  */
   DECL_INLINE (current_function_decl) = 0;
   DECL_UNINLINABLE (current_function_decl) = 1;
@@ -2424,12 +2422,12 @@ one_static_initialization_or_destruction (tree decl, tree init, bool initp)
   if (initp)
     {
       if (init)
-        finish_expr_stmt (init);
+       finish_expr_stmt (init);
 
       /* If we're using __cxa_atexit, register a function that calls the
-         destructor for the object.  */
+        destructor for the object.  */
       if (flag_use_cxa_atexit)
-        finish_expr_stmt (register_dtor_fn (decl));
+       finish_expr_stmt (register_dtor_fn (decl));
     }
   else
     finish_expr_stmt (build_cleanup (decl));
@@ -2502,7 +2500,7 @@ do_static_initialization_or_destruction (tree vars, bool initp)
         node = TREE_CHAIN (node))
       /* Do one initialization or destruction.  */
       one_static_initialization_or_destruction (TREE_VALUE (node),
-                                               TREE_PURPOSE (node), initp);
+                                               TREE_PURPOSE (node), initp);
 
     /* Finish up the priority if-stmt body.  */
     finish_then_clause (priority_if_stmt);
@@ -2683,7 +2681,7 @@ generate_ctor_or_dtor_function (bool constructor_p, int priority,
 static int
 generate_ctor_and_dtor_functions_for_priority (splay_tree_node n, void * data)
 {
-  location_t *locus = data;
+  location_t *locus = (location_t *) data;
   int priority = (int) n->key;
   priority_info pi = (priority_info) n->value;
 
@@ -2998,7 +2996,7 @@ cp_finish_file (void)
             DECL_EXTERNAL appropriately, so there's no need to check
             again, and we do not want to clear DECL_EXTERNAL if a
             previous call to import_export_decl set it.
-            
+
             This is done in a separate for cycle, because if some
             deferred function is contained in another deferred
             function later in deferred_fns varray,
@@ -3091,7 +3089,7 @@ cp_finish_file (void)
   else
     {
       /* If we have a ctor or this is obj-c++ and we need a static init,
-         call generate_ctor_or_dtor_function.  */
+        call generate_ctor_or_dtor_function.  */
       if (static_ctors || (c_dialect_objc () && objc_static_init_needed_p ()))
        generate_ctor_or_dtor_function (/*constructor_p=*/true,
                                        DEFAULT_INIT_PRIORITY, &locus);
@@ -3120,7 +3118,7 @@ cp_finish_file (void)
   if (VEC_length (tree, pending_statics) != 0)
     {
       check_global_declarations (VEC_address (tree, pending_statics),
-                                VEC_length (tree, pending_statics));
+                                VEC_length (tree, pending_statics));
       emit_debug_global_declarations (VEC_address (tree, pending_statics),
                                      VEC_length (tree, pending_statics));
     }
@@ -3228,12 +3226,12 @@ check_default_args (tree x)
       else if (saw_def)
        {
          error ("default argument missing for parameter %P of %q+#D", i, x);
-         break;
+         TREE_PURPOSE (arg) = error_mark_node;
        }
     }
 }
 
-/* Mark DECL (eithet a _DECL or a BASELINK) as "used" in the program.
+/* Mark DECL (either a _DECL or a BASELINK) as "used" in the program.
    If DECL is a specialization or implicitly declared class member,
    generate the actual definition.  */
 
@@ -3255,7 +3253,7 @@ mark_used (tree decl)
     }
 
   TREE_USED (decl) = 1;
-  /* If we don't need a value, then we don't need to synthesize DECL.  */ 
+  /* If we don't need a value, then we don't need to synthesize DECL.  */
   if (skip_evaluation)
     return;
   /* Normally, we can wait until instantiation-time to synthesize
@@ -3279,9 +3277,9 @@ mark_used (tree decl)
       saved_processing_template_decl = processing_template_decl;
       processing_template_decl = 0;
     }
-  
+
   if (processing_template_decl)
-    return;  
+    return;
 
   if (TREE_CODE (decl) == FUNCTION_DECL && DECL_DECLARED_INLINE_P (decl)
       && !TREE_ASM_WRITTEN (decl))
@@ -3316,30 +3314,29 @@ mark_used (tree decl)
     {
       synthesize_method (decl);
       /* If we've already synthesized the method we don't need to
-        instantiate it, so we can return right away.  */
-      return;
-    }
-
-  /* If this is a function or variable that is an instance of some
-     template, we now know that we will need to actually do the
-     instantiation. We check that DECL is not an explicit
-     instantiation because that is not checked in instantiate_decl.  */
-  if ((DECL_NON_THUNK_FUNCTION_P (decl) || TREE_CODE (decl) == VAR_DECL)
-      && DECL_LANG_SPECIFIC (decl) && DECL_TEMPLATE_INFO (decl)
-      && (!DECL_EXPLICIT_INSTANTIATION (decl)
-         || (TREE_CODE (decl) == FUNCTION_DECL
-             && DECL_INLINE (DECL_TEMPLATE_RESULT
-                             (template_for_substitution (decl))))
-         /* We need to instantiate static data members so that there
-            initializers are available in integral constant
-            expressions.  */
-         || (TREE_CODE (decl) == VAR_DECL
-             && DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (decl))))
-    /* We put off instantiating functions in order to improve compile
+        do the instantiation test below.  */
+    }
+  else if ((DECL_NON_THUNK_FUNCTION_P (decl) || TREE_CODE (decl) == VAR_DECL)
+          && DECL_LANG_SPECIFIC (decl) && DECL_TEMPLATE_INFO (decl)
+          && (!DECL_EXPLICIT_INSTANTIATION (decl)
+              || (TREE_CODE (decl) == FUNCTION_DECL
+                  && DECL_INLINE (DECL_TEMPLATE_RESULT
+                                  (template_for_substitution (decl))))
+              /* We need to instantiate static data members so that there
+                 initializers are available in integral constant
+                 expressions.  */
+              || (TREE_CODE (decl) == VAR_DECL
+                  && DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (decl))))
+    /* If this is a function or variable that is an instance of some
+       template, we now know that we will need to actually do the
+       instantiation. We check that DECL is not an explicit
+       instantiation because that is not checked in instantiate_decl.
+
+       We put off instantiating functions in order to improve compile
        times.  Maintaining a stack of active functions is expensive,
        and the inliner knows to instantiate any functions it might
-       need.  */
-    instantiate_decl (decl, /*defer_ok=*/true, 
+       need.  Therefore, we always try to defer instantiation.  */
+    instantiate_decl (decl, /*defer_ok=*/true,
                      /*expl_inst_class_mem_p=*/false);
 
   processing_template_decl = saved_processing_template_decl;