FreeBSD/contrib/gcc/cp/decl.c
/* Resolve `CONTEXT::template NAME'.  Returns a TEMPLATE_DECL if the name
   can be resolved or an UNBOUND_CLASS_TEMPLATE, unless an error occurs,
   in which case error_mark_node is returned.

   If PARM_LIST is non-NULL, also make sure that the template parameter
   list of TEMPLATE_DECL matches.

   If COMPLAIN zero, don't complain about any errors that occur.  */
Resolve `CONTEXT::template NAME'.  Returns a TEMPLATE_DECL if the name
can be resolved or an UNBOUND_CLASS_TEMPLATE, unless an error occurs,
in which case error_mark_node is returned.

If PARM_LIST is non-NULL, also make sure that the template parameter
list of TEMPLATE_DECL matches.

If COMPLAIN zero, don't complain about any errors that occur.
Resolve ` CONTEXT :: template NAME ' . Returns a TEMPLATE_DECL if the name can be resolved or an UNBOUND_CLASS_TEMPLATE unless an error occurs in which case error_mark_node is returned . If PARM_LIST is non - NULL also make sure that the template parameter list of TEMPLATE_DECL matches . If COMPLAIN zero don ' t complain about any errors that occur .
tree
make_unbound_class_template (tree context, tree name, tree parm_list,
			     tsubst_flags_t complain)
{
  tree t;
  tree d;
  if (TYPE_P (name))
    name = TYPE_IDENTIFIER (name);
  else if (DECL_P (name))
    name = DECL_NAME (name);
  gcc_assert (TREE_CODE (name) == IDENTIFIER_NODE);
  if (!dependent_type_p (context)
      || currently_open_class (context))
    {
      tree tmpl = NULL_TREE;
      if (IS_AGGR_TYPE (context))
	tmpl = lookup_field (context, name, 0, false);
      if (!tmpl || !DECL_CLASS_TEMPLATE_P (tmpl))
	{
	  if (complain & tf_error)
	    error ("no class template named %q#T in %q#T", name, context);
	  return error_mark_node;
	}
      if (parm_list
	  && !comp_template_parms (DECL_TEMPLATE_PARMS (tmpl), parm_list))
	{
	  if (complain & tf_error)
	    {
	      error ("template parameters do not match template");
	      error ("%q+D declared here", tmpl);
	    }
	  return error_mark_node;
	}
      if (complain & tf_error)
	perform_or_defer_access_check (TYPE_BINFO (context), tmpl, tmpl);
      return tmpl;
    }
  t = make_aggr_type (UNBOUND_CLASS_TEMPLATE);
  TYPE_CONTEXT (t) = FROB_CONTEXT (context);
  TREE_TYPE (t) = NULL_TREE;
  d = build_decl (TEMPLATE_DECL, name, t);
  TYPE_NAME (TREE_TYPE (d)) = d;
  TYPE_STUB_DECL (TREE_TYPE (d)) = d;
  DECL_CONTEXT (d) = FROB_CONTEXT (context);
  DECL_ARTIFICIAL (d) = 1;
  DECL_TEMPLATE_PARMS (d) = parm_list;
  return t;
}
tree make_unbound_class_template ( tree context , tree name , tree parm_list , tsubst_flags_t complain ) { tree t ; tree d ; if ( TYPE_P ( name ) ) name = TYPE_IDENTIFIER ( name ) ; else if ( DECL_P ( name ) ) name = DECL_NAME ( name ) ; gcc_assert ( TREE_CODE ( name ) == IDENTIFIER_NODE ) ; if ( ! dependent_type_p ( context ) || currently_open_class ( context ) ) { tree tmpl = NULL_TREE ; if ( IS_AGGR_TYPE ( context ) ) tmpl = lookup_field ( context , name , 0 , false ) ; if ( ! tmpl || ! DECL_CLASS_TEMPLATE_P ( tmpl ) ) { if ( complain & tf_error ) error ( " " , name , context ) ; return error_mark_node ; } if ( parm_list && ! comp_template_parms ( DECL_TEMPLATE_PARMS ( tmpl ) , parm_list ) ) { if ( complain & tf_error ) { error ( " " ) ; error ( " " , tmpl ) ; } return error_mark_node ; } if ( complain & tf_error ) perform_or_defer_access_check ( TYPE_BINFO ( context ) , tmpl , tmpl ) ; return tmpl ; } t = make_aggr_type ( UNBOUND_CLASS_TEMPLATE ) ; TYPE_CONTEXT ( t ) = FROB_CONTEXT ( context ) ; TREE_TYPE ( t ) = NULL_TREE ; d = build_decl ( TEMPLATE_DECL , name , t ) ; TYPE_NAME ( TREE_TYPE ( d ) ) = d ; TYPE_STUB_DECL ( TREE_TYPE ( d ) ) = d ; DECL_CONTEXT ( d ) = FROB_CONTEXT ( context ) ; DECL_ARTIFICIAL ( d ) = 1 ; DECL_TEMPLATE_PARMS ( d ) = parm_list ; return t ; }
Resolve `CONTEXT::template NAME'.
Resolve ` CONTEXT :: template NAME ' .
/* Build the UNBOUND_CLASS_TEMPLATE.  */ /* Build the corresponding TEMPLATE_DECL.  */