if (!CLASSTYPE_INTERFACE_ONLY (t) && !extern_p) cp_error ("duplicate explicit instantiation of `%#T'", t);
if (!CLASSTYPE_INTERFACE_ONLY (t) && !extern_p && !flag_use_repository) cp_pedwarn ("duplicate explicit instantiation of `%#T'", t);
do_type_instantiation (t, storage)     tree t, storage;{  int extern_p = 0;  int nomem_p = 0;  int static_p = 0;  if (TREE_CODE (t) == TYPE_DECL)    t = TREE_TYPE (t);  if (! CLASS_TYPE_P (t) || ! CLASSTYPE_TEMPLATE_INFO (t))    {      cp_error ("explicit instantiation of non-template type `%T'", t);      return;    }  complete_type (t);  /* With -fexternal-templates, explicit instantiations are treated the same     as implicit ones.  */  if (flag_external_templates)    return;  if (TYPE_SIZE (t) == NULL_TREE)    {      cp_error ("explicit instantiation of `%#T' before definition of template",		t);      return;    }  if (storage != NULL_TREE)    {      if (pedantic)	cp_pedwarn("ANSI C++ forbids the use of `%s' on explicit instantiations", 		   IDENTIFIER_POINTER (storage));      if (storage == ridpointers[(int) RID_INLINE])	nomem_p = 1;      else if (storage == ridpointers[(int) RID_EXTERN])	extern_p = 1;      else if (storage == ridpointers[(int) RID_STATIC])	static_p = 1;      else	{	  cp_error ("storage class `%D' applied to template instantiation",		    storage);	  extern_p = 0;	}    }  if (CLASSTYPE_TEMPLATE_SPECIALIZATION (t))    {      /* [temp.spec]	 No program shall both explicitly instantiate and explicitly	 specialize a template.  */      cp_error ("explicit instantiation of `%#T' after", t);      cp_error_at ("explicit specialization here", t);      return;    }  else if (CLASSTYPE_EXPLICIT_INSTANTIATION (t))    {      /* [temp.spec]	 No program shall explicitly instantiate any template more	 than once.           If CLASSTYPE_INTERFACE_ONLY, then the first explicit	 instantiation was `extern', and if EXTERN_P then the second	 is.  Both cases are OK.  */      if (!CLASSTYPE_INTERFACE_ONLY (t) && !extern_p)	cp_error ("duplicate explicit instantiation of `%#T'", t);            /* If we've already instantiated the template, just return now.  */      if (!CLASSTYPE_INTERFACE_ONLY (t))	return;    }  mark_class_instantiated (t, extern_p);  repo_template_instantiated (t, extern_p);  if (nomem_p)    return;  {    tree tmp;    /* In contrast to implicit instantiation, where only the       declarations, and not the definitions, of members are       instantiated, we have here:         [temp.explicit]	 The explicit instantiation of a class template specialization	 implies the instantiation of all of its members not	 previously explicitly specialized in the translation unit	 containing the explicit instantiation.         Of course, we can't instantiate member template classes, since       we don't have any arguments for them.  Note that the standard       is unclear on whether the instatiation of the members are       *explicit* instantiations or not.  We choose to be generous,       and not set DECL_EXPLICIT_INSTANTIATION.  Therefore, we allow       the explicit instantiation of a class where some of the members       have no definition in the current translation unit.  */    if (! static_p)      for (tmp = TYPE_METHODS (t); tmp; tmp = TREE_CHAIN (tmp))	if (TREE_CODE (tmp) == FUNCTION_DECL	    && DECL_TEMPLATE_INSTANTIATION (tmp))	  {	    mark_decl_instantiated (tmp, extern_p);	    repo_template_instantiated (tmp, extern_p);	    if (! extern_p)	      instantiate_decl (tmp);	  }    for (tmp = TYPE_FIELDS (t); tmp; tmp = TREE_CHAIN (tmp))      if (TREE_CODE (tmp) == VAR_DECL && DECL_TEMPLATE_INSTANTIATION (tmp))	{	  mark_decl_instantiated (tmp, extern_p);	  repo_template_instantiated (tmp, extern_p);	  if (! extern_p)	    instantiate_decl (tmp);	}    for (tmp = CLASSTYPE_TAGS (t); tmp; tmp = TREE_CHAIN (tmp))      if (IS_AGGR_TYPE (TREE_VALUE (tmp))	  && !uses_template_parms (CLASSTYPE_TI_ARGS (TREE_VALUE (tmp))))	do_type_instantiation (TYPE_MAIN_DECL (TREE_VALUE (tmp)), storage);  }}