pt.c revision 18334
118334Speter/* Handle parameterized types (templates) for GNU C++.
218334Speter   Copyright (C) 1992, 1993, 1994, 1995 Free Software Foundation, Inc.
318334Speter   Written by Ken Raeburn (raeburn@cygnus.com) while at Watchmaker Computing.
418334Speter
518334SpeterThis file is part of GNU CC.
618334Speter
718334SpeterGNU CC is free software; you can redistribute it and/or modify
818334Speterit under the terms of the GNU General Public License as published by
918334Speterthe Free Software Foundation; either version 2, or (at your option)
1018334Speterany later version.
1118334Speter
1218334SpeterGNU CC is distributed in the hope that it will be useful,
1318334Speterbut WITHOUT ANY WARRANTY; without even the implied warranty of
1418334SpeterMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1518334SpeterGNU General Public License for more details.
1618334Speter
1718334SpeterYou should have received a copy of the GNU General Public License
1818334Speteralong with GNU CC; see the file COPYING.  If not, write to
1918334Speterthe Free Software Foundation, 59 Temple Place - Suite 330,
2018334SpeterBoston, MA 02111-1307, USA.  */
2118334Speter
2218334Speter/* Known bugs or deficiencies include:
2318334Speter   * templates for class static data don't work (methods only)
2418334Speter   * duplicated method templates can crash the compiler
2518334Speter   * interface/impl data is taken from file defining the template
2618334Speter   * all methods must be provided in header files; can't use a source
2718334Speter     file that contains only the method templates and "just win"
2818334Speter   * method templates must be seen before the expansion of the
2918334Speter     class template is done
3018334Speter */
3118334Speter
3218334Speter#include "config.h"
3318334Speter#include <stdio.h>
3418334Speter#include "obstack.h"
3518334Speter
3618334Speter#include "tree.h"
3718334Speter#include "flags.h"
3818334Speter#include "cp-tree.h"
3918334Speter#include "decl.h"
4018334Speter#include "parse.h"
4118334Speter#include "lex.h"
4218334Speter#include "output.h"
4318334Speter#include "defaults.h"
4418334Speter
4518334Speterextern struct obstack permanent_obstack;
4618334Speter
4718334Speterextern int lineno;
4818334Speterextern char *input_filename;
4918334Speterstruct pending_inline *pending_template_expansions;
5018334Speter
5118334Speterint processing_template_decl;
5218334Speterint processing_template_defn;
5318334Speter
5418334Speter/* This is a kludge to handle instantiation of template methods that are
5518334Speter   used before their definition.  It should not be necessary after the
5618334Speter   template rewrite.  */
5718334Speterstatic tree template_classes;
5818334Speter
5918334Speter#define obstack_chunk_alloc xmalloc
6018334Speter#define obstack_chunk_free free
6118334Speter
6218334Speterstatic int unify ();
6318334Speterstatic void add_pending_template ();
6418334Speter
6518334Spetervoid overload_template_name (), pop_template_decls ();
6618334Speter
6718334Speter/* We've got a template header coming up; set obstacks up to save the
6818334Speter   nodes created permanently.  (There might be cases with nested templates
6918334Speter   where we don't have to do this, but they aren't implemented, and it
7018334Speter   probably wouldn't be worth the effort.)  */
7118334Spetervoid
7218334Speterbegin_template_parm_list ()
7318334Speter{
7418334Speter  pushlevel (0);
7518334Speter  push_obstacks (&permanent_obstack, &permanent_obstack);
7618334Speter  pushlevel (0);
7718334Speter}
7818334Speter
7918334Speter/* Process information from new template parameter NEXT and append it to the
8018334Speter   LIST being built.  The rules for use of a template parameter type name
8118334Speter   by later parameters are not well-defined for us just yet.  However, the
8218334Speter   only way to avoid having to parse expressions of unknown complexity (and
8318334Speter   with tokens of unknown types) is to disallow it completely.	So for now,
8418334Speter   that is what is assumed.  */
8518334Spetertree
8618334Speterprocess_template_parm (list, next)
8718334Speter     tree list, next;
8818334Speter{
8918334Speter  tree parm;
9018334Speter  tree decl = 0;
9118334Speter  tree defval;
9218334Speter  int is_type;
9318334Speter  parm = next;
9418334Speter  my_friendly_assert (TREE_CODE (parm) == TREE_LIST, 259);
9518334Speter  defval = TREE_PURPOSE (parm);
9618334Speter  parm = TREE_VALUE (parm);
9718334Speter  is_type = TREE_PURPOSE (parm) == class_type_node;
9818334Speter  if (!is_type)
9918334Speter    {
10018334Speter      tree tinfo = 0;
10118334Speter      my_friendly_assert (TREE_CODE (TREE_PURPOSE (parm)) == TREE_LIST, 260);
10218334Speter      /* is a const-param */
10318334Speter      parm = grokdeclarator (TREE_VALUE (parm), TREE_PURPOSE (parm),
10418334Speter			     PARM, 0, NULL_TREE, NULL_TREE);
10518334Speter      /* A template parameter is not modifiable.  */
10618334Speter      TREE_READONLY (parm) = 1;
10718334Speter      if (IS_AGGR_TYPE (TREE_TYPE (parm)))
10818334Speter	{
10918334Speter	  sorry ("aggregate template parameter types");
11018334Speter	  TREE_TYPE (parm) = void_type_node;
11118334Speter	}
11218334Speter      tinfo = make_node (TEMPLATE_CONST_PARM);
11318334Speter      my_friendly_assert (TREE_PERMANENT (tinfo), 260.5);
11418334Speter      if (TREE_PERMANENT (parm) == 0)
11518334Speter        {
11618334Speter	  parm = copy_node (parm);
11718334Speter	  TREE_PERMANENT (parm) = 1;
11818334Speter        }
11918334Speter      TREE_TYPE (tinfo) = TREE_TYPE (parm);
12018334Speter      decl = build_decl (CONST_DECL, DECL_NAME (parm), TREE_TYPE (parm));
12118334Speter      DECL_INITIAL (decl) = tinfo;
12218334Speter      DECL_INITIAL (parm) = tinfo;
12318334Speter    }
12418334Speter  else
12518334Speter    {
12618334Speter      tree t = make_node (TEMPLATE_TYPE_PARM);
12718334Speter      decl = build_decl (TYPE_DECL, TREE_VALUE (parm), t);
12818334Speter      TYPE_MAIN_DECL (t) = decl;
12918334Speter      parm = decl;
13018334Speter      if (defval)
13118334Speter	{
13218334Speter	  if (IDENTIFIER_HAS_TYPE_VALUE (defval))
13318334Speter	    defval = IDENTIFIER_TYPE_VALUE (defval);
13418334Speter	  else
13518334Speter	    defval = TREE_TYPE (IDENTIFIER_GLOBAL_VALUE (defval));
13618334Speter	}
13718334Speter    }
13818334Speter  SET_DECL_ARTIFICIAL (decl);
13918334Speter  pushdecl (decl);
14018334Speter  parm = build_tree_list (defval, parm);
14118334Speter  return chainon (list, parm);
14218334Speter}
14318334Speter
14418334Speter/* The end of a template parameter list has been reached.  Process the
14518334Speter   tree list into a parameter vector, converting each parameter into a more
14618334Speter   useful form.	 Type parameters are saved as IDENTIFIER_NODEs, and others
14718334Speter   as PARM_DECLs.  */
14818334Speter
14918334Spetertree
15018334Speterend_template_parm_list (parms)
15118334Speter     tree parms;
15218334Speter{
15318334Speter  int nparms = 0;
15418334Speter  int saw_default = 0;
15518334Speter  tree saved_parmlist;
15618334Speter  tree parm;
15718334Speter  for (parm = parms; parm; parm = TREE_CHAIN (parm))
15818334Speter    nparms++;
15918334Speter  saved_parmlist = make_tree_vec (nparms);
16018334Speter
16118334Speter  for (parm = parms, nparms = 0; parm; parm = TREE_CHAIN (parm), nparms++)
16218334Speter    {
16318334Speter      tree p = TREE_VALUE (parm);
16418334Speter      if (TREE_PURPOSE (parm))
16518334Speter	saw_default = 1;
16618334Speter      else if (saw_default)
16718334Speter	{
16818334Speter	  error ("if a default argument is given for one template parameter");
16918334Speter	  error ("default arguments must be given for all subsequent");
17018334Speter	  error ("parameters as well");
17118334Speter	}
17218334Speter
17318334Speter      if (TREE_CODE (p) == TYPE_DECL)
17418334Speter	{
17518334Speter	  tree t = TREE_TYPE (p);
17618334Speter	  TEMPLATE_TYPE_SET_INFO (t, saved_parmlist, nparms);
17718334Speter	}
17818334Speter      else
17918334Speter	{
18018334Speter	  tree tinfo = DECL_INITIAL (p);
18118334Speter	  DECL_INITIAL (p) = NULL_TREE;
18218334Speter	  TEMPLATE_CONST_SET_INFO (tinfo, saved_parmlist, nparms);
18318334Speter	}
18418334Speter      TREE_VEC_ELT (saved_parmlist, nparms) = parm;
18518334Speter    }
18618334Speter  set_current_level_tags_transparency (1);
18718334Speter  processing_template_decl++;
18818334Speter  return saved_parmlist;
18918334Speter}
19018334Speter
19118334Speter/* end_template_decl is called after a template declaration is seen.
19218334Speter   D1 is template header; D2 is class_head_sans_basetype or a
19318334Speter   TEMPLATE_DECL with its DECL_RESULT field set.  */
19418334Spetervoid
19518334Speterend_template_decl (d1, d2, is_class, defn)
19618334Speter     tree d1, d2, is_class;
19718334Speter     int defn;
19818334Speter{
19918334Speter  tree decl;
20018334Speter  struct template_info *tmpl;
20118334Speter
20218334Speter  tmpl = (struct template_info *) obstack_alloc (&permanent_obstack,
20318334Speter					    sizeof (struct template_info));
20418334Speter  tmpl->text = 0;
20518334Speter  tmpl->length = 0;
20618334Speter  tmpl->aggr = is_class;
20718334Speter
20818334Speter  /* cloned from reinit_parse_for_template */
20918334Speter  tmpl->filename = input_filename;
21018334Speter  tmpl->lineno = lineno;
21118334Speter  tmpl->parm_vec = d1;          /* [eichin:19911015.2306EST] */
21218334Speter
21318334Speter  if (d2 == NULL_TREE || d2 == error_mark_node)
21418334Speter    {
21518334Speter      decl = 0;
21618334Speter      goto lose;
21718334Speter    }
21818334Speter
21918334Speter  if (is_class)
22018334Speter    {
22118334Speter      decl = build_lang_decl (TEMPLATE_DECL, d2, NULL_TREE);
22218334Speter      GNU_xref_decl (current_function_decl, decl);
22318334Speter    }
22418334Speter  else
22518334Speter    {
22618334Speter      if (TREE_CODE (d2) == TEMPLATE_DECL)
22718334Speter	decl = d2;
22818334Speter      else
22918334Speter	{
23018334Speter	  /* Class destructor templates and operator templates are
23118334Speter	     slipping past as non-template nodes.  Process them here, since
23218334Speter	     I haven't figured out where to catch them earlier.  I could
23318334Speter	     go do that, but it's a choice between getting that done and
23418334Speter	     staying only N months behind schedule.  Sorry....  */
23518334Speter	  enum tree_code code;
23618334Speter	  my_friendly_assert (TREE_CODE (d2) == CALL_EXPR, 263);
23718334Speter	  code = TREE_CODE (TREE_OPERAND (d2, 0));
23818334Speter	  my_friendly_assert (code == BIT_NOT_EXPR
23918334Speter		  || code == OP_IDENTIFIER
24018334Speter		  || code == SCOPE_REF, 264);
24118334Speter	  d2 = grokdeclarator (d2, NULL_TREE, MEMFUNCDEF, 0, NULL_TREE, NULL_TREE);
24218334Speter	  decl = build_lang_decl (TEMPLATE_DECL, DECL_NAME (d2),
24318334Speter				  TREE_TYPE (d2));
24418334Speter	  DECL_TEMPLATE_RESULT (decl) = d2;
24518334Speter	  DECL_CONTEXT (decl) = DECL_CONTEXT (d2);
24618334Speter	  DECL_CLASS_CONTEXT (decl) = DECL_CLASS_CONTEXT (d2);
24718334Speter	  DECL_NAME (decl) = DECL_NAME (d2);
24818334Speter	  TREE_TYPE (decl) = TREE_TYPE (d2);
24918334Speter	  if (interface_unknown && flag_external_templates
25018334Speter	      && ! flag_alt_external_templates
25118334Speter	      && ! DECL_IN_SYSTEM_HEADER (decl))
25218334Speter	    warn_if_unknown_interface (decl);
25318334Speter	  TREE_PUBLIC (decl) = TREE_PUBLIC (d2) = flag_external_templates && !interface_unknown;
25418334Speter	  DECL_EXTERNAL (decl) = (DECL_EXTERNAL (d2)
25518334Speter				  && !(DECL_CLASS_CONTEXT (d2)
25618334Speter				       && !DECL_THIS_EXTERN (d2)));
25718334Speter	}
25818334Speter
25918334Speter      /* All routines creating TEMPLATE_DECL nodes should now be using
26018334Speter	 build_lang_decl, which will have set this up already.	*/
26118334Speter      my_friendly_assert (DECL_LANG_SPECIFIC (decl) != 0, 265);
26218334Speter
26318334Speter      /* @@ Somewhere, permanent allocation isn't being used.  */
26418334Speter      if (! DECL_TEMPLATE_IS_CLASS (decl)
26518334Speter	  && TREE_CODE (DECL_TEMPLATE_RESULT (decl)) == FUNCTION_DECL)
26618334Speter	{
26718334Speter	  tree result = DECL_TEMPLATE_RESULT (decl);
26818334Speter	  /* Will do nothing if allocation was already permanent.  */
26918334Speter	  DECL_ARGUMENTS (result) = copy_to_permanent (DECL_ARGUMENTS (result));
27018334Speter	}
27118334Speter
27218334Speter      /* If this is for a method, there's an extra binding level here.	*/
27318334Speter      if (DECL_CONTEXT (DECL_TEMPLATE_RESULT (decl)) != NULL_TREE)
27418334Speter	{
27518334Speter	  /* @@ Find out where this should be getting set!  */
27618334Speter	  tree r = DECL_TEMPLATE_RESULT (decl);
27718334Speter	  if (DECL_LANG_SPECIFIC (r) && DECL_CLASS_CONTEXT (r) == NULL_TREE)
27818334Speter	    DECL_CLASS_CONTEXT (r) = DECL_CONTEXT (r);
27918334Speter	}
28018334Speter    }
28118334Speter  DECL_TEMPLATE_INFO (decl) = tmpl;
28218334Speter  DECL_TEMPLATE_PARMS (decl) = d1;
28318334Speter
28418334Speter  /* So that duplicate_decls can do the right thing.  */
28518334Speter  if (defn)
28618334Speter    DECL_INITIAL (decl) = error_mark_node;
28718334Speter
28818334Speter  /* If context of decl is non-null (i.e., method template), add it
28918334Speter     to the appropriate class template, and pop the binding levels.  */
29018334Speter  if (! is_class && DECL_CONTEXT (DECL_TEMPLATE_RESULT (decl)) != NULL_TREE)
29118334Speter    {
29218334Speter      tree ctx = DECL_CONTEXT (DECL_TEMPLATE_RESULT (decl));
29318334Speter      tree tmpl, t;
29418334Speter      my_friendly_assert (TREE_CODE (ctx) == UNINSTANTIATED_P_TYPE, 266);
29518334Speter      tmpl = UPT_TEMPLATE (ctx);
29618334Speter      for (t = DECL_TEMPLATE_MEMBERS (tmpl); t; t = TREE_CHAIN (t))
29718334Speter	if (TREE_PURPOSE (t) == DECL_NAME (decl)
29818334Speter	    && duplicate_decls (decl, TREE_VALUE (t)))
29918334Speter	  goto already_there;
30018334Speter      DECL_TEMPLATE_MEMBERS (tmpl) =
30118334Speter	perm_tree_cons (DECL_NAME (decl), decl, DECL_TEMPLATE_MEMBERS (tmpl));
30218334Speter    already_there:
30318334Speter      poplevel (0, 0, 0);
30418334Speter      poplevel (0, 0, 0);
30518334Speter    }
30618334Speter  /* Otherwise, go back to top level first, and push the template decl
30718334Speter     again there.  */
30818334Speter  else
30918334Speter    {
31018334Speter      poplevel (0, 0, 0);
31118334Speter      poplevel (0, 0, 0);
31218334Speter      pushdecl (decl);
31318334Speter    }
31418334Speter lose:
31518334Speter#if 0 /* It happens sometimes, with syntactic or semantic errors.
31618334Speter
31718334Speter	 One specific case:
31818334Speter	 template <class A, int X, int Y> class Foo { ... };
31918334Speter	 template <class A, int X, int y> Foo<X,Y>::method (Foo& x) { ... }
32018334Speter	 Note the missing "A" in the class containing "method".  */
32118334Speter  my_friendly_assert (global_bindings_p (), 267);
32218334Speter#else
32318334Speter  while (! global_bindings_p ())
32418334Speter    poplevel (0, 0, 0);
32518334Speter#endif
32618334Speter  pop_obstacks ();
32718334Speter  processing_template_decl--;
32818334Speter  (void) get_pending_sizes ();
32918334Speter}
33018334Speter
33118334Spetertree tsubst		PROTO ((tree, tree*, int, tree));
33218334Speter
33318334Speter/* Convert all template arguments to their appropriate types, and return
33418334Speter   a vector containing the resulting values.  If any error occurs, return
33518334Speter   error_mark_node.  */
33618334Speterstatic tree
33718334Spetercoerce_template_parms (parms, arglist, in_decl)
33818334Speter     tree parms, arglist;
33918334Speter     tree in_decl;
34018334Speter{
34118334Speter  int nparms, nargs, i, lost = 0;
34218334Speter  tree vec;
34318334Speter
34418334Speter  if (arglist == NULL_TREE)
34518334Speter    nargs = 0;
34618334Speter  else if (TREE_CODE (arglist) == TREE_VEC)
34718334Speter    nargs = TREE_VEC_LENGTH (arglist);
34818334Speter  else
34918334Speter    nargs = list_length (arglist);
35018334Speter
35118334Speter  nparms = TREE_VEC_LENGTH (parms);
35218334Speter
35318334Speter  if (nargs > nparms
35418334Speter      || (nargs < nparms
35518334Speter	  && TREE_PURPOSE (TREE_VEC_ELT (parms, nargs)) == NULL_TREE))
35618334Speter    {
35718334Speter      error ("incorrect number of parameters (%d, should be %d)",
35818334Speter	     nargs, nparms);
35918334Speter      if (in_decl)
36018334Speter	cp_error_at ("in template expansion for decl `%D'", in_decl);
36118334Speter      return error_mark_node;
36218334Speter    }
36318334Speter
36418334Speter  if (arglist && TREE_CODE (arglist) == TREE_VEC)
36518334Speter    vec = copy_node (arglist);
36618334Speter  else
36718334Speter    {
36818334Speter      vec = make_tree_vec (nparms);
36918334Speter      for (i = 0; i < nparms; i++)
37018334Speter	{
37118334Speter	  tree arg;
37218334Speter
37318334Speter	  if (arglist)
37418334Speter	    {
37518334Speter	      arg = arglist;
37618334Speter	      arglist = TREE_CHAIN (arglist);
37718334Speter
37818334Speter	      if (arg == error_mark_node)
37918334Speter		lost++;
38018334Speter	      else
38118334Speter		arg = TREE_VALUE (arg);
38218334Speter	    }
38318334Speter	  else
38418334Speter	    arg = TREE_PURPOSE (TREE_VEC_ELT (parms, i));
38518334Speter
38618334Speter	  TREE_VEC_ELT (vec, i) = arg;
38718334Speter	}
38818334Speter    }
38918334Speter  for (i = 0; i < nparms; i++)
39018334Speter    {
39118334Speter      tree arg = TREE_VEC_ELT (vec, i);
39218334Speter      tree parm = TREE_VALUE (TREE_VEC_ELT (parms, i));
39318334Speter      tree val = 0;
39418334Speter      int is_type, requires_type;
39518334Speter
39618334Speter      is_type = TREE_CODE_CLASS (TREE_CODE (arg)) == 't';
39718334Speter      requires_type = TREE_CODE (parm) == TYPE_DECL;
39818334Speter      if (is_type != requires_type)
39918334Speter	{
40018334Speter	  if (in_decl)
40118334Speter	    cp_error ("type/value mismatch in template parameter list for `%D'",
40218334Speter		      in_decl);
40318334Speter	  lost++;
40418334Speter	  TREE_VEC_ELT (vec, i) = error_mark_node;
40518334Speter	  continue;
40618334Speter	}
40718334Speter      if (is_type)
40818334Speter	val = groktypename (arg);
40918334Speter      else
41018334Speter	{
41118334Speter	  tree t = tsubst (TREE_TYPE (parm), &TREE_VEC_ELT (vec, 0),
41218334Speter			   TREE_VEC_LENGTH (vec), in_decl);
41318334Speter	  val = digest_init (t, arg, (tree *) 0);
41418334Speter
41518334Speter	  if (val == error_mark_node)
41618334Speter	    ;
41718334Speter
41818334Speter	  /* 14.2: Other template-arguments must be constant-expressions,
41918334Speter	     addresses of objects or functions with external linkage, or of
42018334Speter	     static class members.  */
42118334Speter	  else if (!TREE_CONSTANT (val))
42218334Speter	    {
42318334Speter	      cp_error ("non-const `%E' cannot be used as template argument",
42418334Speter			arg);
42518334Speter	      val = error_mark_node;
42618334Speter	    }
42718334Speter	  else if (POINTER_TYPE_P (TREE_TYPE (val))
42818334Speter		   && ! integer_zerop (val)
42918334Speter		   && TREE_CODE (TREE_TYPE (TREE_TYPE (val))) != OFFSET_TYPE
43018334Speter		   && TREE_CODE (TREE_TYPE (TREE_TYPE (val))) != METHOD_TYPE)
43118334Speter	    {
43218334Speter	      t = val;
43318334Speter	      STRIP_NOPS (t);
43418334Speter	      if (TREE_CODE (t) == ADDR_EXPR)
43518334Speter		{
43618334Speter		  tree a = TREE_OPERAND (t, 0);
43718334Speter		  STRIP_NOPS (a);
43818334Speter		  if (TREE_CODE (a) == STRING_CST)
43918334Speter		    {
44018334Speter		      cp_error ("string literal %E is not a valid template argument", a);
44118334Speter		      error ("because it is the address of an object with static linkage");
44218334Speter		      val = error_mark_node;
44318334Speter		    }
44418334Speter		  else if (TREE_CODE (a) != VAR_DECL
44518334Speter			   && TREE_CODE (a) != FUNCTION_DECL)
44618334Speter		    goto bad;
44718334Speter		  else if (! DECL_PUBLIC (a))
44818334Speter		    {
44918334Speter		      cp_error ("address of non-extern `%E' cannot be used as template argument", a);
45018334Speter		      val = error_mark_node;
45118334Speter		    }
45218334Speter		}
45318334Speter	      else
45418334Speter		{
45518334Speter		bad:
45618334Speter		  cp_error ("`%E' is not a valid template argument", t);
45718334Speter		  error ("it must be %s%s with external linkage",
45818334Speter			 TREE_CODE (TREE_TYPE (val)) == POINTER_TYPE
45918334Speter			 ? "a pointer to " : "",
46018334Speter			 TREE_CODE (TREE_TYPE (TREE_TYPE (val))) == FUNCTION_TYPE
46118334Speter			 ? "a function" : "an object");
46218334Speter		  val = error_mark_node;
46318334Speter		}
46418334Speter	    }
46518334Speter	}
46618334Speter
46718334Speter      if (val == error_mark_node)
46818334Speter	lost++;
46918334Speter
47018334Speter      TREE_VEC_ELT (vec, i) = val;
47118334Speter    }
47218334Speter  if (lost)
47318334Speter    return error_mark_node;
47418334Speter  return vec;
47518334Speter}
47618334Speter
47718334Speter/* Given class template name and parameter list, produce a user-friendly name
47818334Speter   for the instantiation.  */
47918334Speterstatic char *
48018334Spetermangle_class_name_for_template (name, parms, arglist)
48118334Speter     char *name;
48218334Speter     tree parms, arglist;
48318334Speter{
48418334Speter  static struct obstack scratch_obstack;
48518334Speter  static char *scratch_firstobj;
48618334Speter  int i, nparms;
48718334Speter
48818334Speter  if (!scratch_firstobj)
48918334Speter    {
49018334Speter      gcc_obstack_init (&scratch_obstack);
49118334Speter      scratch_firstobj = obstack_alloc (&scratch_obstack, 1);
49218334Speter    }
49318334Speter  else
49418334Speter    obstack_free (&scratch_obstack, scratch_firstobj);
49518334Speter
49618334Speter#if 0
49718334Speter#define buflen	sizeof(buf)
49818334Speter#define check	if (bufp >= buf+buflen-1) goto too_long
49918334Speter#define ccat(c) *bufp++=(c); check
50018334Speter#define advance	bufp+=strlen(bufp); check
50118334Speter#define cat(s)	strncpy(bufp, s, buf+buflen-bufp-1); advance
50218334Speter#else
50318334Speter#define check
50418334Speter#define ccat(c)	obstack_1grow (&scratch_obstack, (c));
50518334Speter#define advance
50618334Speter#define cat(s)	obstack_grow (&scratch_obstack, (s), strlen (s))
50718334Speter#endif
50818334Speter
50918334Speter  cat (name);
51018334Speter  ccat ('<');
51118334Speter  nparms = TREE_VEC_LENGTH (parms);
51218334Speter  my_friendly_assert (nparms == TREE_VEC_LENGTH (arglist), 268);
51318334Speter  for (i = 0; i < nparms; i++)
51418334Speter    {
51518334Speter      tree parm = TREE_VALUE (TREE_VEC_ELT (parms, i));
51618334Speter      tree arg = TREE_VEC_ELT (arglist, i);
51718334Speter
51818334Speter      if (i)
51918334Speter	ccat (',');
52018334Speter
52118334Speter      if (TREE_CODE (parm) == TYPE_DECL)
52218334Speter	{
52318334Speter	  cat (type_as_string (arg, 0));
52418334Speter	  continue;
52518334Speter	}
52618334Speter      else
52718334Speter	my_friendly_assert (TREE_CODE (parm) == PARM_DECL, 269);
52818334Speter
52918334Speter      if (TREE_CODE (arg) == TREE_LIST)
53018334Speter	{
53118334Speter	  /* New list cell was built because old chain link was in
53218334Speter	     use.  */
53318334Speter	  my_friendly_assert (TREE_PURPOSE (arg) == NULL_TREE, 270);
53418334Speter	  arg = TREE_VALUE (arg);
53518334Speter	}
53618334Speter      /* No need to check arglist against parmlist here; we did that
53718334Speter	 in coerce_template_parms, called from lookup_template_class.  */
53818334Speter      cat (expr_as_string (arg, 0));
53918334Speter    }
54018334Speter  {
54118334Speter    char *bufp = obstack_next_free (&scratch_obstack);
54218334Speter    int offset = 0;
54318334Speter    while (bufp[offset - 1] == ' ')
54418334Speter      offset--;
54518334Speter    obstack_blank_fast (&scratch_obstack, offset);
54618334Speter
54718334Speter    /* B<C<char> >, not B<C<char>> */
54818334Speter    if (bufp[offset - 1] == '>')
54918334Speter      ccat (' ');
55018334Speter  }
55118334Speter  ccat ('>');
55218334Speter  ccat ('\0');
55318334Speter  return (char *) obstack_base (&scratch_obstack);
55418334Speter
55518334Speter#if 0
55618334Speter too_long:
55718334Speter#endif
55818334Speter  fatal ("out of (preallocated) string space creating template instantiation name");
55918334Speter  /* NOTREACHED */
56018334Speter  return NULL;
56118334Speter}
56218334Speter
56318334Speter/* Given an IDENTIFIER_NODE (type TEMPLATE_DECL) and a chain of
56418334Speter   parameters, find the desired type.
56518334Speter
56618334Speter   D1 is the PTYPENAME terminal, and ARGLIST is the list of arguments.
56718334Speter   Since ARGLIST is build on the decl_obstack, we must copy it here
56818334Speter   to keep it from being reclaimed when the decl storage is reclaimed.
56918334Speter
57018334Speter   IN_DECL, if non-NULL, is the template declaration we are trying to
57118334Speter   instantiate.  */
57218334Spetertree
57318334Speterlookup_template_class (d1, arglist, in_decl)
57418334Speter     tree d1, arglist;
57518334Speter     tree in_decl;
57618334Speter{
57718334Speter  tree template, parmlist;
57818334Speter  char *mangled_name;
57918334Speter  tree id;
58018334Speter
58118334Speter  my_friendly_assert (TREE_CODE (d1) == IDENTIFIER_NODE, 272);
58218334Speter  template = IDENTIFIER_GLOBAL_VALUE (d1); /* XXX */
58318334Speter  if (! template)
58418334Speter    template = IDENTIFIER_CLASS_VALUE (d1);
58518334Speter  /* With something like `template <class T> class X class X { ... };'
58618334Speter     we could end up with D1 having nothing but an IDENTIFIER_LOCAL_VALUE.
58718334Speter     We don't want to do that, but we have to deal with the situation, so
58818334Speter     let's give them some syntax errors to chew on instead of a crash.  */
58918334Speter  if (! template)
59018334Speter    return error_mark_node;
59118334Speter  if (TREE_CODE (template) != TEMPLATE_DECL)
59218334Speter    {
59318334Speter      cp_error ("non-template type `%T' used as a template", d1);
59418334Speter      if (in_decl)
59518334Speter	cp_error_at ("for template declaration `%D'", in_decl);
59618334Speter      return error_mark_node;
59718334Speter    }
59818334Speter  parmlist = DECL_TEMPLATE_PARMS (template);
59918334Speter
60018334Speter  arglist = coerce_template_parms (parmlist, arglist, template);
60118334Speter  if (arglist == error_mark_node)
60218334Speter    return error_mark_node;
60318334Speter  if (uses_template_parms (arglist))
60418334Speter    {
60518334Speter      tree t = make_lang_type (UNINSTANTIATED_P_TYPE);
60618334Speter      tree d;
60718334Speter      id = make_anon_name ();
60818334Speter      d = build_decl (TYPE_DECL, id, t);
60918334Speter      TYPE_NAME (t) = d;
61018334Speter      TYPE_VALUES (t) = build_tree_list (template, arglist);
61118334Speter      pushdecl_top_level (d);
61218334Speter    }
61318334Speter  else
61418334Speter    {
61518334Speter      mangled_name = mangle_class_name_for_template (IDENTIFIER_POINTER (d1),
61618334Speter						     parmlist, arglist);
61718334Speter      id = get_identifier (mangled_name);
61818334Speter    }
61918334Speter  if (!IDENTIFIER_TEMPLATE (id))
62018334Speter    {
62118334Speter      arglist = copy_to_permanent (arglist);
62218334Speter      IDENTIFIER_TEMPLATE (id) = perm_tree_cons (template, arglist, NULL_TREE);
62318334Speter    }
62418334Speter  return id;
62518334Speter}
62618334Speter
62718334Spetervoid
62818334Speterpush_template_decls (parmlist, arglist, class_level)
62918334Speter     tree parmlist, arglist;
63018334Speter     int class_level;
63118334Speter{
63218334Speter  int i, nparms;
63318334Speter
63418334Speter  /* Don't want to push values into global context.  */
63518334Speter  if (!class_level)
63618334Speter    {
63718334Speter      pushlevel (1);
63818334Speter      declare_pseudo_global_level ();
63918334Speter    }
64018334Speter
64118334Speter  nparms = TREE_VEC_LENGTH (parmlist);
64218334Speter
64318334Speter  for (i = 0; i < nparms; i++)
64418334Speter    {
64518334Speter      int requires_type, is_type;
64618334Speter      tree parm = TREE_VALUE (TREE_VEC_ELT (parmlist, i));
64718334Speter      tree arg = TREE_VEC_ELT (arglist, i);
64818334Speter      tree decl = 0;
64918334Speter
65018334Speter      requires_type = TREE_CODE (parm) == TYPE_DECL;
65118334Speter      is_type = TREE_CODE_CLASS (TREE_CODE (arg)) == 't';
65218334Speter      if (is_type)
65318334Speter	{
65418334Speter	  /* add typename to namespace */
65518334Speter	  if (!requires_type)
65618334Speter	    {
65718334Speter	      error ("template use error: type provided where value needed");
65818334Speter	      continue;
65918334Speter	    }
66018334Speter	  decl = arg;
66118334Speter	  my_friendly_assert (TREE_CODE_CLASS (TREE_CODE (decl)) == 't', 273);
66218334Speter	  decl = build_decl (TYPE_DECL, DECL_NAME (parm), decl);
66318334Speter	}
66418334Speter      else
66518334Speter	{
66618334Speter	  /* add const decl to namespace */
66718334Speter	  tree val;
66818334Speter	  tree parmtype;
66918334Speter	  if (requires_type)
67018334Speter	    {
67118334Speter	      error ("template use error: value provided where type needed");
67218334Speter	      continue;
67318334Speter	    }
67418334Speter	  parmtype = tsubst (TREE_TYPE (parm), &TREE_VEC_ELT (arglist, 0),
67518334Speter			     TREE_VEC_LENGTH (arglist), NULL_TREE);
67618334Speter	  val = digest_init (parmtype, arg, (tree *) 0);
67718334Speter	  if (val != error_mark_node)
67818334Speter	    {
67918334Speter	      decl = build_decl (CONST_DECL, DECL_NAME (parm),
68018334Speter				 parmtype);
68118334Speter	      DECL_INITIAL (decl) = val;
68218334Speter	      TREE_READONLY (decl) = 1;
68318334Speter	    }
68418334Speter	}
68518334Speter      if (decl != 0)
68618334Speter	{
68718334Speter	  SET_DECL_ARTIFICIAL (decl);
68818334Speter	  layout_decl (decl, 0);
68918334Speter	  if (class_level)
69018334Speter	    pushdecl_class_level (decl);
69118334Speter	  else
69218334Speter	    pushdecl (decl);
69318334Speter	}
69418334Speter    }
69518334Speter}
69618334Speter
69718334Spetervoid
69818334Speterpop_template_decls (parmlist, arglist, class_level)
69918334Speter     tree parmlist, arglist;
70018334Speter     int class_level;
70118334Speter{
70218334Speter  if (!class_level)
70318334Speter    poplevel (0, 0, 0);
70418334Speter}
70518334Speter
70618334Speter/* Should be defined in parse.h.  */
70718334Speterextern int yychar;
70818334Speter
70918334Speterint
71018334Speteruses_template_parms (t)
71118334Speter     tree t;
71218334Speter{
71318334Speter  if (!t)
71418334Speter    return 0;
71518334Speter  switch (TREE_CODE (t))
71618334Speter    {
71718334Speter    case INDIRECT_REF:
71818334Speter    case COMPONENT_REF:
71918334Speter      /* We assume that the object must be instantiated in order to build
72018334Speter	 the COMPONENT_REF, so we test only whether the type of the
72118334Speter	 COMPONENT_REF uses template parms.  */
72218334Speter      return uses_template_parms (TREE_TYPE (t));
72318334Speter
72418334Speter    case IDENTIFIER_NODE:
72518334Speter      if (!IDENTIFIER_TEMPLATE (t))
72618334Speter	return 0;
72718334Speter      return uses_template_parms (TREE_VALUE (IDENTIFIER_TEMPLATE (t)));
72818334Speter
72918334Speter      /* aggregates of tree nodes */
73018334Speter    case TREE_VEC:
73118334Speter      {
73218334Speter	int i = TREE_VEC_LENGTH (t);
73318334Speter	while (i--)
73418334Speter	  if (uses_template_parms (TREE_VEC_ELT (t, i)))
73518334Speter	    return 1;
73618334Speter	return 0;
73718334Speter      }
73818334Speter    case TREE_LIST:
73918334Speter      if (uses_template_parms (TREE_PURPOSE (t))
74018334Speter	  || uses_template_parms (TREE_VALUE (t)))
74118334Speter	return 1;
74218334Speter      return uses_template_parms (TREE_CHAIN (t));
74318334Speter
74418334Speter      /* constructed type nodes */
74518334Speter    case POINTER_TYPE:
74618334Speter    case REFERENCE_TYPE:
74718334Speter      return uses_template_parms (TREE_TYPE (t));
74818334Speter    case RECORD_TYPE:
74918334Speter      if (TYPE_PTRMEMFUNC_FLAG (t))
75018334Speter	return uses_template_parms (TYPE_PTRMEMFUNC_FN_TYPE (t));
75118334Speter    case UNION_TYPE:
75218334Speter      if (!TYPE_NAME (t))
75318334Speter	return 0;
75418334Speter      if (!TYPE_IDENTIFIER (t))
75518334Speter	return 0;
75618334Speter      return uses_template_parms (TYPE_IDENTIFIER (t));
75718334Speter    case FUNCTION_TYPE:
75818334Speter      if (uses_template_parms (TYPE_ARG_TYPES (t)))
75918334Speter	return 1;
76018334Speter      return uses_template_parms (TREE_TYPE (t));
76118334Speter    case ARRAY_TYPE:
76218334Speter      if (uses_template_parms (TYPE_DOMAIN (t)))
76318334Speter	return 1;
76418334Speter      return uses_template_parms (TREE_TYPE (t));
76518334Speter    case OFFSET_TYPE:
76618334Speter      if (uses_template_parms (TYPE_OFFSET_BASETYPE (t)))
76718334Speter	return 1;
76818334Speter      return uses_template_parms (TREE_TYPE (t));
76918334Speter    case METHOD_TYPE:
77018334Speter      if (uses_template_parms (TYPE_METHOD_BASETYPE (t)))
77118334Speter	return 1;
77218334Speter      if (uses_template_parms (TYPE_ARG_TYPES (t)))
77318334Speter	return 1;
77418334Speter      return uses_template_parms (TREE_TYPE (t));
77518334Speter
77618334Speter      /* decl nodes */
77718334Speter    case TYPE_DECL:
77818334Speter      return uses_template_parms (DECL_NAME (t));
77918334Speter    case FUNCTION_DECL:
78018334Speter      if (uses_template_parms (TREE_TYPE (t)))
78118334Speter	return 1;
78218334Speter      /* fall through */
78318334Speter    case VAR_DECL:
78418334Speter    case PARM_DECL:
78518334Speter      /* ??? What about FIELD_DECLs?  */
78618334Speter      /* The type of a decl can't use template parms if the name of the
78718334Speter	 variable doesn't, because it's impossible to resolve them.  So
78818334Speter	 ignore the type field for now.	 */
78918334Speter      if (DECL_CONTEXT (t) && uses_template_parms (DECL_CONTEXT (t)))
79018334Speter	return 1;
79118334Speter      if (uses_template_parms (TREE_TYPE (t)))
79218334Speter	{
79318334Speter	  error ("template parms used where they can't be resolved");
79418334Speter	}
79518334Speter      return 0;
79618334Speter
79718334Speter    case CALL_EXPR:
79818334Speter      return uses_template_parms (TREE_TYPE (t));
79918334Speter    case ADDR_EXPR:
80018334Speter      return uses_template_parms (TREE_OPERAND (t, 0));
80118334Speter
80218334Speter      /* template parm nodes */
80318334Speter    case TEMPLATE_TYPE_PARM:
80418334Speter    case TEMPLATE_CONST_PARM:
80518334Speter      return 1;
80618334Speter
80718334Speter      /* simple type nodes */
80818334Speter    case INTEGER_TYPE:
80918334Speter      if (uses_template_parms (TYPE_MIN_VALUE (t)))
81018334Speter	return 1;
81118334Speter      return uses_template_parms (TYPE_MAX_VALUE (t));
81218334Speter
81318334Speter    case REAL_TYPE:
81418334Speter    case VOID_TYPE:
81518334Speter    case ENUMERAL_TYPE:
81618334Speter    case BOOLEAN_TYPE:
81718334Speter      return 0;
81818334Speter
81918334Speter      /* constants */
82018334Speter    case INTEGER_CST:
82118334Speter    case REAL_CST:
82218334Speter    case STRING_CST:
82318334Speter      return 0;
82418334Speter
82518334Speter    case ERROR_MARK:
82618334Speter      /* Non-error_mark_node ERROR_MARKs are bad things.  */
82718334Speter      my_friendly_assert (t == error_mark_node, 274);
82818334Speter      /* NOTREACHED */
82918334Speter      return 0;
83018334Speter
83118334Speter    case UNINSTANTIATED_P_TYPE:
83218334Speter      return 1;
83318334Speter
83418334Speter    case CONSTRUCTOR:
83518334Speter      if (TREE_TYPE (t) && TYPE_PTRMEMFUNC_P (TREE_TYPE (t)))
83618334Speter	return uses_template_parms (TYPE_PTRMEMFUNC_FN_TYPE (TREE_TYPE (t)));
83718334Speter      /* else fall through */
83818334Speter
83918334Speter    default:
84018334Speter      switch (TREE_CODE_CLASS (TREE_CODE (t)))
84118334Speter	{
84218334Speter	case '1':
84318334Speter	case '2':
84418334Speter	case '3':
84518334Speter	case '<':
84618334Speter	  {
84718334Speter	    int i;
84818334Speter	    for (i = tree_code_length[(int) TREE_CODE (t)]; --i >= 0;)
84918334Speter	      if (uses_template_parms (TREE_OPERAND (t, i)))
85018334Speter		return 1;
85118334Speter	    return 0;
85218334Speter	  }
85318334Speter	default:
85418334Speter	  break;
85518334Speter	}
85618334Speter      sorry ("testing %s for template parms",
85718334Speter	     tree_code_name [(int) TREE_CODE (t)]);
85818334Speter      my_friendly_abort (82);
85918334Speter      /* NOTREACHED */
86018334Speter      return 0;
86118334Speter    }
86218334Speter}
86318334Speter
86418334Spetervoid
86518334Speterinstantiate_member_templates (classname)
86618334Speter     tree classname;
86718334Speter{
86818334Speter  tree t;
86918334Speter  tree id = classname;
87018334Speter  tree members = DECL_TEMPLATE_MEMBERS (TREE_PURPOSE (IDENTIFIER_TEMPLATE (id)));
87118334Speter
87218334Speter  for (t = members; t; t = TREE_CHAIN (t))
87318334Speter    {
87418334Speter      tree parmvec, type, classparms, tdecl, t2;
87518334Speter      int nparms, xxx = 0, i;
87618334Speter
87718334Speter      my_friendly_assert (TREE_VALUE (t) != NULL_TREE, 275);
87818334Speter      my_friendly_assert (TREE_CODE (TREE_VALUE (t)) == TEMPLATE_DECL, 276);
87918334Speter      /* @@ Should verify that class parm list is a list of
88018334Speter	 distinct template parameters, and covers all the template
88118334Speter	 parameters.  */
88218334Speter      tdecl = TREE_VALUE (t);
88318334Speter      type = DECL_CONTEXT (DECL_TEMPLATE_RESULT (tdecl));
88418334Speter      classparms = UPT_PARMS (type);
88518334Speter      nparms = TREE_VEC_LENGTH (classparms);
88618334Speter      parmvec = make_tree_vec (nparms);
88718334Speter      for (i = 0; i < nparms; i++)
88818334Speter	TREE_VEC_ELT (parmvec, i) = NULL_TREE;
88918334Speter      switch (unify (DECL_TEMPLATE_PARMS (tdecl),
89018334Speter		     &TREE_VEC_ELT (parmvec, 0), nparms,
89118334Speter		     type, IDENTIFIER_TYPE_VALUE (classname),
89218334Speter		     &xxx))
89318334Speter	{
89418334Speter	case 0:
89518334Speter	  /* Success -- well, no inconsistency, at least.  */
89618334Speter	  for (i = 0; i < nparms; i++)
89718334Speter	    if (TREE_VEC_ELT (parmvec, i) == NULL_TREE)
89818334Speter	      goto failure;
89918334Speter	  t2 = instantiate_template (tdecl,
90018334Speter				     &TREE_VEC_ELT (parmvec, 0));
90118334Speter	  type = IDENTIFIER_TYPE_VALUE (id);
90218334Speter	  my_friendly_assert (type != 0, 277);
90318334Speter	  break;
90418334Speter	case 1:
90518334Speter	  /* Failure.  */
90618334Speter	failure:
90718334Speter	  cp_error_at ("type unification error instantiating `%D'", tdecl);
90818334Speter	  cp_error ("while instantiating members of `%T'", classname);
90918334Speter
91018334Speter	  continue /* loop of members */;
91118334Speter	default:
91218334Speter	  /* Eek, a bug.  */
91318334Speter	  my_friendly_abort (83);
91418334Speter	}
91518334Speter    }
91618334Speter}
91718334Speter
91818334Speterstatic struct tinst_level *current_tinst_level = 0;
91918334Speterstatic struct tinst_level *free_tinst_level = 0;
92018334Speterstatic int tinst_depth = 0;
92118334Speterint max_tinst_depth = 17;
92218334Speter
92318334Speterint
92418334Speterpush_tinst_level (name)
92518334Speter     tree name;
92618334Speter{
92718334Speter  struct tinst_level *new;
92818334Speter  tree global = IDENTIFIER_GLOBAL_VALUE (name);
92918334Speter
93018334Speter  if (tinst_depth >= max_tinst_depth)
93118334Speter    {
93218334Speter      error ("template instantiation depth exceeds maximum of %d",
93318334Speter	     max_tinst_depth);
93418334Speter      cp_error ("  instantiating `%D'", name);
93518334Speter      return 0;
93618334Speter    }
93718334Speter
93818334Speter  if (free_tinst_level)
93918334Speter    {
94018334Speter      new = free_tinst_level;
94118334Speter      free_tinst_level = new->next;
94218334Speter    }
94318334Speter  else
94418334Speter    new = (struct tinst_level *) xmalloc (sizeof (struct tinst_level));
94518334Speter
94618334Speter  new->classname = name;
94718334Speter  if (global)
94818334Speter    {
94918334Speter      new->line = DECL_SOURCE_LINE (global);
95018334Speter      new->file = DECL_SOURCE_FILE (global);
95118334Speter    }
95218334Speter  else
95318334Speter    {
95418334Speter      new->line = lineno;
95518334Speter      new->file = input_filename;
95618334Speter    }
95718334Speter  new->next = current_tinst_level;
95818334Speter  current_tinst_level = new;
95918334Speter  ++tinst_depth;
96018334Speter  return 1;
96118334Speter}
96218334Speter
96318334Spetervoid
96418334Speterpop_tinst_level ()
96518334Speter{
96618334Speter  struct tinst_level *old = current_tinst_level;
96718334Speter
96818334Speter  current_tinst_level = old->next;
96918334Speter  old->next = free_tinst_level;
97018334Speter  free_tinst_level = old;
97118334Speter  --tinst_depth;
97218334Speter}
97318334Speter
97418334Speterstruct tinst_level *
97518334Spetertinst_for_decl ()
97618334Speter{
97718334Speter  struct tinst_level *p = current_tinst_level;
97818334Speter
97918334Speter  if (p)
98018334Speter    for (; p->next ; p = p->next )
98118334Speter      ;
98218334Speter  return p;
98318334Speter}
98418334Speter
98518334Spetertree
98618334Speterinstantiate_class_template (classname, setup_parse)
98718334Speter     tree classname;
98818334Speter     int setup_parse;
98918334Speter{
99018334Speter  struct template_info *template_info;
99118334Speter  tree template, t1;
99218334Speter
99318334Speter  if (classname == error_mark_node)
99418334Speter    return error_mark_node;
99518334Speter
99618334Speter  my_friendly_assert (TREE_CODE (classname) == IDENTIFIER_NODE, 278);
99718334Speter  template = IDENTIFIER_TEMPLATE (classname);
99818334Speter
99918334Speter  if (IDENTIFIER_HAS_TYPE_VALUE (classname))
100018334Speter    {
100118334Speter      tree type = IDENTIFIER_TYPE_VALUE (classname);
100218334Speter      if (TREE_CODE (type) == UNINSTANTIATED_P_TYPE)
100318334Speter	return type;
100418334Speter      if (TYPE_BEING_DEFINED (type)
100518334Speter	  || TYPE_SIZE (type)
100618334Speter	  || CLASSTYPE_USE_TEMPLATE (type) != 0)
100718334Speter	return type;
100818334Speter    }
100918334Speter
101018334Speter  /* If IDENTIFIER_LOCAL_VALUE is already set on this template classname
101118334Speter     (it's something like `foo<int>'), that means we're already working on
101218334Speter     the instantiation for it.  Normally, a classname comes in with nothing
101318334Speter     but its IDENTIFIER_TEMPLATE slot set.  If we were to try to instantiate
101418334Speter     this again, we'd get a redeclaration error.  Since we're already working
101518334Speter     on it, we'll pass back this classname's TYPE_DECL (it's the value of
101618334Speter     the classname's IDENTIFIER_LOCAL_VALUE).  Only do this if we're setting
101718334Speter     things up for the parser, though---if we're just trying to instantiate
101818334Speter     it (e.g., via tsubst) we can trip up cuz it may not have an
101918334Speter     IDENTIFIER_TYPE_VALUE when it will need one.  */
102018334Speter  if (setup_parse && IDENTIFIER_LOCAL_VALUE (classname))
102118334Speter    return IDENTIFIER_LOCAL_VALUE (classname);
102218334Speter
102318334Speter  if (uses_template_parms (classname))
102418334Speter    {
102518334Speter      if (!TREE_TYPE (classname))
102618334Speter	{
102718334Speter	  tree t = make_lang_type (RECORD_TYPE);
102818334Speter	  tree d = build_decl (TYPE_DECL, classname, t);
102918334Speter	  DECL_NAME (d) = classname;
103018334Speter	  TYPE_NAME (t) = d;
103118334Speter	  pushdecl (d);
103218334Speter	}
103318334Speter      return NULL_TREE;
103418334Speter    }
103518334Speter
103618334Speter  t1 = TREE_PURPOSE (template);
103718334Speter  my_friendly_assert (TREE_CODE (t1) == TEMPLATE_DECL, 279);
103818334Speter
103918334Speter  /* If a template is declared but not defined, accept it; don't crash.
104018334Speter     Later uses requiring the definition will be flagged as errors by
104118334Speter     other code.  Thanks to niklas@appli.se for this bug fix.  */
104218334Speter  if (DECL_TEMPLATE_INFO (t1)->text == 0)
104318334Speter    setup_parse = 0;
104418334Speter
104518334Speter  push_to_top_level ();
104618334Speter  template_info = DECL_TEMPLATE_INFO (t1);
104718334Speter  if (setup_parse && push_tinst_level (classname))
104818334Speter    {
104918334Speter      push_template_decls (DECL_TEMPLATE_PARMS (TREE_PURPOSE (template)),
105018334Speter			   TREE_VALUE (template), 0);
105118334Speter      set_current_level_tags_transparency (1);
105218334Speter      feed_input (template_info->text, template_info->length, (struct obstack *)0);
105318334Speter      lineno = template_info->lineno;
105418334Speter      input_filename = template_info->filename;
105518334Speter      /* Get interface/implementation back in sync.  */
105618334Speter      extract_interface_info ();
105718334Speter      overload_template_name (classname, 0);
105818334Speter      /* Kludge so that we don't get screwed by our own base classes.  */
105918334Speter      TYPE_BEING_DEFINED (TREE_TYPE (classname)) = 1;
106018334Speter      yychar = PRE_PARSED_CLASS_DECL;
106118334Speter      yylval.ttype = classname;
106218334Speter      processing_template_defn++;
106318334Speter      if (!flag_external_templates)
106418334Speter	interface_unknown++;
106518334Speter      template_classes
106618334Speter	= perm_tree_cons (classname, NULL_TREE, template_classes);
106718334Speter    }
106818334Speter  else
106918334Speter    {
107018334Speter      tree t, decl, id, tmpl;
107118334Speter
107218334Speter      id = classname;
107318334Speter      tmpl = TREE_PURPOSE (IDENTIFIER_TEMPLATE (id));
107418334Speter      t = xref_tag (DECL_TEMPLATE_INFO (tmpl)->aggr, id, NULL_TREE, 0);
107518334Speter      my_friendly_assert (TREE_CODE (t) == RECORD_TYPE
107618334Speter			  || TREE_CODE (t) == UNION_TYPE, 280);
107718334Speter
107818334Speter      /* Now, put a copy of the decl in global scope, to avoid
107918334Speter       * recursive expansion.  */
108018334Speter      decl = IDENTIFIER_LOCAL_VALUE (id);
108118334Speter      if (!decl)
108218334Speter	decl = IDENTIFIER_CLASS_VALUE (id);
108318334Speter      if (decl)
108418334Speter	{
108518334Speter	  my_friendly_assert (TREE_CODE (decl) == TYPE_DECL, 281);
108618334Speter	  /* We'd better make sure we're on the permanent obstack or else
108718334Speter	   * we'll get a "friendly" abort 124 in pushdecl.  Perhaps a
108818334Speter	   * copy_to_permanent would be sufficient here, but then a
108918334Speter	   * sharing problem might occur.  I don't know -- niklas@appli.se */
109018334Speter	  push_obstacks (&permanent_obstack, &permanent_obstack);
109118334Speter	  pushdecl_top_level (copy_node (decl));
109218334Speter	  pop_obstacks ();
109318334Speter	}
109418334Speter      pop_from_top_level ();
109518334Speter    }
109618334Speter
109718334Speter  return NULL_TREE;
109818334Speter}
109918334Speter
110018334Speterstatic int
110118334Speterlist_eq (t1, t2)
110218334Speter     tree t1, t2;
110318334Speter{
110418334Speter  if (t1 == NULL_TREE)
110518334Speter    return t2 == NULL_TREE;
110618334Speter  if (t2 == NULL_TREE)
110718334Speter    return 0;
110818334Speter  /* Don't care if one declares its arg const and the other doesn't -- the
110918334Speter     main variant of the arg type is all that matters.  */
111018334Speter  if (TYPE_MAIN_VARIANT (TREE_VALUE (t1))
111118334Speter      != TYPE_MAIN_VARIANT (TREE_VALUE (t2)))
111218334Speter    return 0;
111318334Speter  return list_eq (TREE_CHAIN (t1), TREE_CHAIN (t2));
111418334Speter}
111518334Speter
111618334Speterstatic tree
111718334Speterlookup_nested_type_by_name (ctype, name)
111818334Speter        tree ctype, name;
111918334Speter{
112018334Speter  tree t;
112118334Speter
112218334Speter  for (t = CLASSTYPE_TAGS (ctype); t; t = TREE_CHAIN (t))
112318334Speter    {
112418334Speter      if (name == TREE_PURPOSE (t))
112518334Speter	return TREE_VALUE (t);
112618334Speter    }
112718334Speter  return NULL_TREE;
112818334Speter}
112918334Speter
113018334Speterstatic tree
113118334Spetersearch_nested_type_in_tmpl (tmpl, type)
113218334Speter        tree tmpl, type;
113318334Speter{
113418334Speter  tree t;
113518334Speter
113618334Speter  if (tmpl == NULL || TYPE_CONTEXT(type) == NULL)
113718334Speter    return tmpl;
113818334Speter  t = search_nested_type_in_tmpl (tmpl, TYPE_CONTEXT(type));
113918334Speter  if (t == NULL) return t;
114018334Speter  t = lookup_nested_type_by_name(t, DECL_NAME(TYPE_NAME(type)));
114118334Speter  return t;
114218334Speter}
114318334Speter
114418334Spetertree
114518334Spetertsubst (t, args, nargs, in_decl)
114618334Speter     tree t, *args;
114718334Speter     int nargs;
114818334Speter     tree in_decl;
114918334Speter{
115018334Speter  tree type;
115118334Speter
115218334Speter  if (t == NULL_TREE || t == error_mark_node)
115318334Speter    return t;
115418334Speter
115518334Speter  type = TREE_TYPE (t);
115618334Speter  if (type
115718334Speter      /* Minor optimization.
115818334Speter	 ?? Are these really the most frequent cases?  Is the savings
115918334Speter	 significant?  */
116018334Speter      && type != integer_type_node
116118334Speter      && type != void_type_node
116218334Speter      && type != char_type_node)
116318334Speter    type = tsubst (type, args, nargs, in_decl);
116418334Speter
116518334Speter  switch (TREE_CODE (t))
116618334Speter    {
116718334Speter    case RECORD_TYPE:
116818334Speter      if (TYPE_PTRMEMFUNC_P (t))
116918334Speter	return build_ptrmemfunc_type
117018334Speter	  (tsubst (TYPE_PTRMEMFUNC_FN_TYPE (t), args, nargs, in_decl));
117118334Speter
117218334Speter      /* else fall through */
117318334Speter
117418334Speter    case ERROR_MARK:
117518334Speter    case IDENTIFIER_NODE:
117618334Speter    case OP_IDENTIFIER:
117718334Speter    case VOID_TYPE:
117818334Speter    case REAL_TYPE:
117918334Speter    case ENUMERAL_TYPE:
118018334Speter    case BOOLEAN_TYPE:
118118334Speter    case INTEGER_CST:
118218334Speter    case REAL_CST:
118318334Speter    case STRING_CST:
118418334Speter    case UNION_TYPE:
118518334Speter      return t;
118618334Speter
118718334Speter    case INTEGER_TYPE:
118818334Speter      if (t == integer_type_node)
118918334Speter	return t;
119018334Speter
119118334Speter      if (TREE_CODE (TYPE_MIN_VALUE (t)) == INTEGER_CST
119218334Speter	  && TREE_CODE (TYPE_MAX_VALUE (t)) == INTEGER_CST)
119318334Speter	return t;
119418334Speter      return build_index_2_type
119518334Speter	(tsubst (TYPE_MIN_VALUE (t), args, nargs, in_decl),
119618334Speter	 tsubst (TYPE_MAX_VALUE (t), args, nargs, in_decl));
119718334Speter
119818334Speter    case TEMPLATE_TYPE_PARM:
119918334Speter      {
120018334Speter	tree arg = args[TEMPLATE_TYPE_IDX (t)];
120118334Speter	return cp_build_type_variant
120218334Speter	  (arg, TYPE_READONLY (arg) || TYPE_READONLY (t),
120318334Speter	   TYPE_VOLATILE (arg) || TYPE_VOLATILE (t));
120418334Speter      }
120518334Speter
120618334Speter    case TEMPLATE_CONST_PARM:
120718334Speter      return args[TEMPLATE_CONST_IDX (t)];
120818334Speter
120918334Speter    case FUNCTION_DECL:
121018334Speter      {
121118334Speter	tree r;
121218334Speter	tree fnargs, result;
121318334Speter
121418334Speter	if (type == TREE_TYPE (t)
121518334Speter	    && (DECL_CONTEXT (t) == NULL_TREE
121618334Speter		|| TREE_CODE_CLASS (TREE_CODE (DECL_CONTEXT (t))) != 't'))
121718334Speter	  return t;
121818334Speter	fnargs = tsubst (DECL_ARGUMENTS (t), args, nargs, t);
121918334Speter	result = tsubst (DECL_RESULT (t), args, nargs, t);
122018334Speter	if (DECL_CONTEXT (t) != NULL_TREE
122118334Speter	    && TREE_CODE_CLASS (TREE_CODE (DECL_CONTEXT (t))) == 't')
122218334Speter	  {
122318334Speter	    /* Look it up in that class, and return the decl node there,
122418334Speter	       instead of creating a new one.  */
122518334Speter	    tree ctx, methods, name, method;
122618334Speter	    int n_methods;
122718334Speter	    int i, found = 0;
122818334Speter
122918334Speter	    name = DECL_NAME (t);
123018334Speter	    ctx = tsubst (DECL_CONTEXT (t), args, nargs, t);
123118334Speter	    methods = CLASSTYPE_METHOD_VEC (ctx);
123218334Speter	    if (methods == NULL_TREE)
123318334Speter	      /* No methods at all -- no way this one can match.  */
123418334Speter	      goto no_match;
123518334Speter	    n_methods = TREE_VEC_LENGTH (methods);
123618334Speter
123718334Speter	    r = NULL_TREE;
123818334Speter
123918334Speter	    if (!strncmp (OPERATOR_TYPENAME_FORMAT,
124018334Speter			  IDENTIFIER_POINTER (name),
124118334Speter			  sizeof (OPERATOR_TYPENAME_FORMAT) - 1))
124218334Speter	      {
124318334Speter		/* Type-conversion operator.  Reconstruct the name, in
124418334Speter		   case it's the name of one of the template's parameters.  */
124518334Speter		name = build_typename_overload (TREE_TYPE (type));
124618334Speter	      }
124718334Speter
124818334Speter	    if (DECL_CONTEXT (t) != NULL_TREE
124918334Speter		&& TREE_CODE_CLASS (TREE_CODE (DECL_CONTEXT (t))) == 't'
125018334Speter		&& constructor_name (DECL_CONTEXT (t)) == DECL_NAME (t))
125118334Speter	      name = constructor_name (ctx);
125218334Speter
125318334Speter	    if (DECL_CONSTRUCTOR_P (t) && TYPE_USES_VIRTUAL_BASECLASSES (ctx))
125418334Speter	      {
125518334Speter		/* Since we didn't know that this class had virtual bases until after
125618334Speter		   we instantiated it, we have to recreate the arguments to this
125718334Speter		   constructor, as otherwise it would miss the __in_chrg parameter.  */
125818334Speter		tree newtype, parm;
125918334Speter		tree parms = TREE_CHAIN (TYPE_ARG_TYPES (type));
126018334Speter		parms = hash_tree_chain (integer_type_node, parms);
126118334Speter		newtype = build_cplus_method_type (ctx,
126218334Speter						   TREE_TYPE (type),
126318334Speter						   parms);
126418334Speter		newtype = build_type_variant (newtype,
126518334Speter					      TYPE_READONLY (type),
126618334Speter					      TYPE_VOLATILE (type));
126718334Speter		type = newtype;
126818334Speter
126918334Speter		fnargs = copy_node (DECL_ARGUMENTS (t));
127018334Speter		TREE_CHAIN (fnargs) = TREE_CHAIN (DECL_ARGUMENTS (t));
127118334Speter
127218334Speter		/* In this case we need "in-charge" flag saying whether
127318334Speter		   this constructor is responsible for initialization
127418334Speter		   of virtual baseclasses or not.  */
127518334Speter		parm = build_decl (PARM_DECL, in_charge_identifier, integer_type_node);
127618334Speter		/* Mark the artificial `__in_chrg' parameter as "artificial".  */
127718334Speter		SET_DECL_ARTIFICIAL (parm);
127818334Speter		DECL_ARG_TYPE (parm) = integer_type_node;
127918334Speter		DECL_REGISTER (parm) = 1;
128018334Speter		TREE_CHAIN (parm) = TREE_CHAIN (fnargs);
128118334Speter		TREE_CHAIN (fnargs) = parm;
128218334Speter
128318334Speter		fnargs = tsubst (fnargs, args, nargs, t);
128418334Speter	      }
128518334Speter#if 0
128618334Speter	    fprintf (stderr, "\nfor function %s in class %s:\n",
128718334Speter		     IDENTIFIER_POINTER (name),
128818334Speter		     IDENTIFIER_POINTER (TYPE_IDENTIFIER (ctx)));
128918334Speter#endif
129018334Speter	    for (i = 0; i < n_methods; i++)
129118334Speter	      {
129218334Speter		int pass;
129318334Speter
129418334Speter		method = TREE_VEC_ELT (methods, i);
129518334Speter		if (method == NULL_TREE || DECL_NAME (method) != name)
129618334Speter		  continue;
129718334Speter
129818334Speter		pass = 0;
129918334Speter	      maybe_error:
130018334Speter		for (; method; method = DECL_CHAIN (method))
130118334Speter		  {
130218334Speter		    my_friendly_assert (TREE_CODE (method) == FUNCTION_DECL,
130318334Speter					282);
130418334Speter		    if (! comptypes (type, TREE_TYPE (method), 1))
130518334Speter		      {
130618334Speter			tree mtype = TREE_TYPE (method);
130718334Speter			tree t1, t2;
130818334Speter
130918334Speter			/* Keep looking for a method that matches
131018334Speter			   perfectly.  This takes care of the problem
131118334Speter			   where destructors (which have implicit int args)
131218334Speter			   look like constructors which have an int arg.  */
131318334Speter			if (pass == 0)
131418334Speter			  continue;
131518334Speter
131618334Speter			t1 = TYPE_ARG_TYPES (mtype);
131718334Speter			t2 = TYPE_ARG_TYPES (type);
131818334Speter			if (TREE_CODE (mtype) == FUNCTION_TYPE)
131918334Speter			  t2 = TREE_CHAIN (t2);
132018334Speter
132118334Speter			if (list_eq (t1, t2))
132218334Speter			  {
132318334Speter			    if (TREE_CODE (mtype) == FUNCTION_TYPE)
132418334Speter			      {
132518334Speter				tree newtype;
132618334Speter				newtype = build_function_type (TREE_TYPE (type),
132718334Speter							       TYPE_ARG_TYPES (type));
132818334Speter				newtype = build_type_variant (newtype,
132918334Speter							      TYPE_READONLY (type),
133018334Speter							      TYPE_VOLATILE (type));
133118334Speter				type = newtype;
133218334Speter				if (TREE_TYPE (type) != TREE_TYPE (mtype))
133318334Speter				  goto maybe_bad_return_type;
133418334Speter			      }
133518334Speter			    else if (TYPE_METHOD_BASETYPE (mtype)
133618334Speter				     == TYPE_METHOD_BASETYPE (type))
133718334Speter			      {
133818334Speter				/* Types didn't match, but arg types and
133918334Speter				   `this' do match, so the return type is
134018334Speter				   all that should be messing it up.  */
134118334Speter			      maybe_bad_return_type:
134218334Speter				if (TREE_TYPE (type) != TREE_TYPE (mtype))
134318334Speter				  error ("inconsistent return types for method `%s' in class `%s'",
134418334Speter					 IDENTIFIER_POINTER (name),
134518334Speter					 IDENTIFIER_POINTER (TYPE_IDENTIFIER (ctx)));
134618334Speter			      }
134718334Speter			    r = method;
134818334Speter			    break;
134918334Speter			  }
135018334Speter			found = 1;
135118334Speter			continue;
135218334Speter		      }
135318334Speter#if 0
135418334Speter		    fprintf (stderr, "\tfound %s\n\n",
135518334Speter			     IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (method)));
135618334Speter#endif
135718334Speter		    if (DECL_ARTIFICIAL (method))
135818334Speter		      {
135918334Speter			cp_error ("template for method `%D' which has default implementation in class `%T'", name, ctx);
136018334Speter			if (in_decl)
136118334Speter			  cp_error_at ("in attempt to instantiate `%D' declared at this point in file", in_decl);
136218334Speter			return error_mark_node;
136318334Speter		      }
136418334Speter
136518334Speter		    if (DECL_ARGUMENTS (method)
136618334Speter			&& ! TREE_PERMANENT (DECL_ARGUMENTS (method)))
136718334Speter		      /* @@ Is this early enough?  Might we want to do
136818334Speter			 this instead while processing the expansion?	 */
136918334Speter		      DECL_ARGUMENTS (method)
137018334Speter			= tsubst (DECL_ARGUMENTS (t), args, nargs, t);
137118334Speter		    r = method;
137218334Speter		    break;
137318334Speter		  }
137418334Speter		if (r == NULL_TREE && pass == 0)
137518334Speter		  {
137618334Speter		    pass = 1;
137718334Speter		    method = TREE_VEC_ELT (methods, i);
137818334Speter		    goto maybe_error;
137918334Speter		  }
138018334Speter	      }
138118334Speter	    if (r == NULL_TREE)
138218334Speter	      {
138318334Speter	      no_match:
138418334Speter		cp_error
138518334Speter		  (found
138618334Speter		   ? "template for method `%D' doesn't match any in class `%T'"
138718334Speter		   : "method `%D' not found in class `%T'", name, ctx);
138818334Speter		if (in_decl)
138918334Speter		  cp_error_at ("in attempt to instantiate `%D' declared at this point in file", in_decl);
139018334Speter		return error_mark_node;
139118334Speter	      }
139218334Speter	  }
139318334Speter	else
139418334Speter	  {
139518334Speter	    r = DECL_NAME (t);
139618334Speter	    {
139718334Speter	      tree decls;
139818334Speter	      int got_it = 0;
139918334Speter
140018334Speter	      decls = lookup_name_nonclass (r);
140118334Speter	      if (decls == NULL_TREE)
140218334Speter		/* no match */;
140318334Speter	      else if (TREE_CODE (decls) == TREE_LIST)
140418334Speter		for (decls = TREE_VALUE (decls); decls ;
140518334Speter		     decls = DECL_CHAIN (decls))
140618334Speter		  {
140718334Speter		    if (TREE_CODE (decls) == FUNCTION_DECL
140818334Speter			&& TREE_TYPE (decls) == type)
140918334Speter		      {
141018334Speter			got_it = 1;
141118334Speter			r = decls;
141218334Speter			break;
141318334Speter		      }
141418334Speter		  }
141518334Speter	      else
141618334Speter		{
141718334Speter		  tree val = decls;
141818334Speter		  decls = NULL_TREE;
141918334Speter		  if (TREE_CODE (val) == FUNCTION_DECL
142018334Speter		      && TREE_TYPE (val) == type)
142118334Speter		    {
142218334Speter		      got_it = 1;
142318334Speter		      r = val;
142418334Speter		    }
142518334Speter		}
142618334Speter
142718334Speter	      if (!got_it)
142818334Speter		{
142918334Speter		  tree a = build_decl_overload (r, TYPE_VALUES (type),
143018334Speter						DECL_CONTEXT (t) != NULL_TREE);
143118334Speter		  r = build_lang_decl (FUNCTION_DECL, r, type);
143218334Speter		  DECL_ASSEMBLER_NAME (r) = a;
143318334Speter		}
143418334Speter	      else if (TREE_STATIC (r))
143518334Speter		{
143618334Speter		  /* This overrides the template version, use it. */
143718334Speter		  return r;
143818334Speter		}
143918334Speter	    }
144018334Speter	  }
144118334Speter	TREE_PUBLIC (r) = 1;
144218334Speter	DECL_EXTERNAL (r) = 1;
144318334Speter	TREE_STATIC (r) = 0;
144418334Speter	DECL_INTERFACE_KNOWN (r) = 0;
144518334Speter	DECL_INLINE (r) = DECL_INLINE (t);
144618334Speter	DECL_THIS_INLINE (r) = DECL_THIS_INLINE (t);
144718334Speter	TREE_READONLY (r) = TREE_READONLY (t);
144818334Speter	TREE_THIS_VOLATILE (r) = TREE_THIS_VOLATILE (t);
144918334Speter	{
145018334Speter#if 0				/* Maybe later.  -jason  */
145118334Speter	  struct tinst_level *til = tinst_for_decl();
145218334Speter
145318334Speter	  /* should always be true under new approach */
145418334Speter	  if (til)
145518334Speter	    {
145618334Speter	      DECL_SOURCE_FILE (r) = til->file;
145718334Speter	      DECL_SOURCE_LINE (r) = til->line;
145818334Speter	    }
145918334Speter	  else
146018334Speter#endif
146118334Speter	    {
146218334Speter	      DECL_SOURCE_FILE (r) = DECL_SOURCE_FILE (t);
146318334Speter	      DECL_SOURCE_LINE (r) = DECL_SOURCE_LINE (t);
146418334Speter	    }
146518334Speter	}
146618334Speter	DECL_CLASS_CONTEXT (r) = tsubst (DECL_CLASS_CONTEXT (t), args, nargs, t);
146718334Speter	make_decl_rtl (r, NULL_PTR, 1);
146818334Speter	DECL_ARGUMENTS (r) = fnargs;
146918334Speter	DECL_RESULT (r) = result;
147018334Speter#if 0
147118334Speter	if (DECL_CONTEXT (t) == NULL_TREE
147218334Speter	    || TREE_CODE_CLASS (TREE_CODE (DECL_CONTEXT (t))) != 't')
147318334Speter	  push_overloaded_decl_top_level (r, 0);
147418334Speter#endif
147518334Speter	return r;
147618334Speter      }
147718334Speter
147818334Speter    case PARM_DECL:
147918334Speter      {
148018334Speter	tree r;
148118334Speter	r = build_decl (PARM_DECL, DECL_NAME (t), type);
148218334Speter	DECL_INITIAL (r) = TREE_TYPE (r);
148318334Speter	DECL_ARTIFICIAL (r) = DECL_ARTIFICIAL (t);
148418334Speter#ifdef PROMOTE_PROTOTYPES
148518334Speter	if ((TREE_CODE (type) == INTEGER_TYPE
148618334Speter	     || TREE_CODE (type) == ENUMERAL_TYPE)
148718334Speter	    && TYPE_PRECISION (type) < TYPE_PRECISION (integer_type_node))
148818334Speter	  DECL_ARG_TYPE (r) = integer_type_node;
148918334Speter#endif
149018334Speter	if (TREE_CHAIN (t))
149118334Speter	  TREE_CHAIN (r) = tsubst (TREE_CHAIN (t), args, nargs, TREE_CHAIN (t));
149218334Speter	return r;
149318334Speter      }
149418334Speter
149518334Speter    case TREE_LIST:
149618334Speter      {
149718334Speter	tree purpose, value, chain, result;
149818334Speter	int via_public, via_virtual, via_protected;
149918334Speter
150018334Speter	if (t == void_list_node)
150118334Speter	  return t;
150218334Speter
150318334Speter	via_public = TREE_VIA_PUBLIC (t);
150418334Speter	via_protected = TREE_VIA_PROTECTED (t);
150518334Speter	via_virtual = TREE_VIA_VIRTUAL (t);
150618334Speter
150718334Speter	purpose = TREE_PURPOSE (t);
150818334Speter	if (purpose)
150918334Speter	  purpose = tsubst (purpose, args, nargs, in_decl);
151018334Speter	value = TREE_VALUE (t);
151118334Speter	if (value)
151218334Speter	  value = tsubst (value, args, nargs, in_decl);
151318334Speter	chain = TREE_CHAIN (t);
151418334Speter	if (chain && chain != void_type_node)
151518334Speter	  chain = tsubst (chain, args, nargs, in_decl);
151618334Speter	if (purpose == TREE_PURPOSE (t)
151718334Speter	    && value == TREE_VALUE (t)
151818334Speter	    && chain == TREE_CHAIN (t))
151918334Speter	  return t;
152018334Speter	result = hash_tree_cons (via_public, via_virtual, via_protected,
152118334Speter				 purpose, value, chain);
152218334Speter	TREE_PARMLIST (result) = TREE_PARMLIST (t);
152318334Speter	return result;
152418334Speter      }
152518334Speter    case TREE_VEC:
152618334Speter      {
152718334Speter	int len = TREE_VEC_LENGTH (t), need_new = 0, i;
152818334Speter	tree *elts = (tree *) alloca (len * sizeof (tree));
152918334Speter	bzero ((char *) elts, len * sizeof (tree));
153018334Speter
153118334Speter	for (i = 0; i < len; i++)
153218334Speter	  {
153318334Speter	    elts[i] = tsubst (TREE_VEC_ELT (t, i), args, nargs, in_decl);
153418334Speter	    if (elts[i] != TREE_VEC_ELT (t, i))
153518334Speter	      need_new = 1;
153618334Speter	  }
153718334Speter
153818334Speter	if (!need_new)
153918334Speter	  return t;
154018334Speter
154118334Speter	t = make_tree_vec (len);
154218334Speter	for (i = 0; i < len; i++)
154318334Speter	  TREE_VEC_ELT (t, i) = elts[i];
154418334Speter	return t;
154518334Speter      }
154618334Speter    case POINTER_TYPE:
154718334Speter    case REFERENCE_TYPE:
154818334Speter      {
154918334Speter	tree r;
155018334Speter	enum tree_code code;
155118334Speter	if (type == TREE_TYPE (t))
155218334Speter	  return t;
155318334Speter
155418334Speter	code = TREE_CODE (t);
155518334Speter	if (code == POINTER_TYPE)
155618334Speter	  r = build_pointer_type (type);
155718334Speter	else
155818334Speter	  r = build_reference_type (type);
155918334Speter	r = cp_build_type_variant (r, TYPE_READONLY (t), TYPE_VOLATILE (t));
156018334Speter	/* Will this ever be needed for TYPE_..._TO values?  */
156118334Speter	layout_type (r);
156218334Speter	return r;
156318334Speter      }
156418334Speter    case OFFSET_TYPE:
156518334Speter      return build_offset_type
156618334Speter	(tsubst (TYPE_OFFSET_BASETYPE (t), args, nargs, in_decl), type);
156718334Speter    case FUNCTION_TYPE:
156818334Speter    case METHOD_TYPE:
156918334Speter      {
157018334Speter	tree values = TYPE_ARG_TYPES (t);
157118334Speter	tree context = TYPE_CONTEXT (t);
157218334Speter	tree new_value;
157318334Speter
157418334Speter	/* Don't bother recursing if we know it won't change anything.	*/
157518334Speter	if (values != void_list_node)
157618334Speter	  values = tsubst (values, args, nargs, in_decl);
157718334Speter	if (context)
157818334Speter	  context = tsubst (context, args, nargs, in_decl);
157918334Speter	/* Could also optimize cases where return value and
158018334Speter	   values have common elements (e.g., T min(const &T, const T&).  */
158118334Speter
158218334Speter	/* If the above parameters haven't changed, just return the type.  */
158318334Speter	if (type == TREE_TYPE (t)
158418334Speter	    && values == TYPE_VALUES (t)
158518334Speter	    && context == TYPE_CONTEXT (t))
158618334Speter	  return t;
158718334Speter
158818334Speter	/* Construct a new type node and return it.  */
158918334Speter	if (TREE_CODE (t) == FUNCTION_TYPE
159018334Speter	    && context == NULL_TREE)
159118334Speter	  {
159218334Speter	    new_value = build_function_type (type, values);
159318334Speter	  }
159418334Speter	else if (context == NULL_TREE)
159518334Speter	  {
159618334Speter	    tree base = tsubst (TREE_TYPE (TREE_VALUE (TYPE_ARG_TYPES (t))),
159718334Speter				args, nargs, in_decl);
159818334Speter	    new_value = build_cplus_method_type (base, type,
159918334Speter						 TREE_CHAIN (values));
160018334Speter	  }
160118334Speter	else
160218334Speter	  {
160318334Speter	    new_value = make_node (TREE_CODE (t));
160418334Speter	    TREE_TYPE (new_value) = type;
160518334Speter	    TYPE_CONTEXT (new_value) = context;
160618334Speter	    TYPE_VALUES (new_value) = values;
160718334Speter	    TYPE_SIZE (new_value) = TYPE_SIZE (t);
160818334Speter	    TYPE_ALIGN (new_value) = TYPE_ALIGN (t);
160918334Speter	    TYPE_MODE (new_value) = TYPE_MODE (t);
161018334Speter	    if (TYPE_METHOD_BASETYPE (t))
161118334Speter	      TYPE_METHOD_BASETYPE (new_value) = tsubst (TYPE_METHOD_BASETYPE (t),
161218334Speter							 args, nargs, in_decl);
161318334Speter	    /* Need to generate hash value.  */
161418334Speter	    my_friendly_abort (84);
161518334Speter	  }
161618334Speter	new_value = build_type_variant (new_value,
161718334Speter					TYPE_READONLY (t),
161818334Speter					TYPE_VOLATILE (t));
161918334Speter	return new_value;
162018334Speter      }
162118334Speter    case ARRAY_TYPE:
162218334Speter      {
162318334Speter	tree domain = tsubst (TYPE_DOMAIN (t), args, nargs, in_decl);
162418334Speter	tree r;
162518334Speter	if (type == TREE_TYPE (t) && domain == TYPE_DOMAIN (t))
162618334Speter	  return t;
162718334Speter	r = build_cplus_array_type (type, domain);
162818334Speter	return r;
162918334Speter      }
163018334Speter
163118334Speter    case UNINSTANTIATED_P_TYPE:
163218334Speter      {
163318334Speter	int nparms = TREE_VEC_LENGTH (DECL_TEMPLATE_PARMS (UPT_TEMPLATE (t)));
163418334Speter	tree argvec = make_tree_vec (nparms);
163518334Speter	tree parmvec = UPT_PARMS (t);
163618334Speter	int i;
163718334Speter	tree id, rt;
163818334Speter	for (i = 0; i < nparms; i++)
163918334Speter	  TREE_VEC_ELT (argvec, i) = tsubst (TREE_VEC_ELT (parmvec, i),
164018334Speter					     args, nargs, in_decl);
164118334Speter	id = lookup_template_class (DECL_NAME (UPT_TEMPLATE (t)), argvec, NULL_TREE);
164218334Speter	if (! IDENTIFIER_HAS_TYPE_VALUE (id)) {
164318334Speter	  instantiate_class_template(id, 0);
164418334Speter	  /* set up pending_classes */
164518334Speter	  add_pending_template (id);
164618334Speter
164718334Speter	  TYPE_MAIN_VARIANT (IDENTIFIER_TYPE_VALUE (id)) =
164818334Speter	    IDENTIFIER_TYPE_VALUE (id);
164918334Speter	}
165018334Speter        rt = IDENTIFIER_TYPE_VALUE (id);
165118334Speter
165218334Speter	/* kung: this part handles nested type in template definition */
165318334Speter
165418334Speter	if ( !ANON_AGGRNAME_P (DECL_NAME(TYPE_NAME(t))))
165518334Speter          {
165618334Speter	    rt = search_nested_type_in_tmpl (rt, t);
165718334Speter          }
165818334Speter
165918334Speter	return build_type_variant (rt, TYPE_READONLY (t), TYPE_VOLATILE (t));
166018334Speter      }
166118334Speter
166218334Speter    case MINUS_EXPR:
166318334Speter    case PLUS_EXPR:
166418334Speter      return fold (build (TREE_CODE (t), TREE_TYPE (t),
166518334Speter			  tsubst (TREE_OPERAND (t, 0), args, nargs, in_decl),
166618334Speter			  tsubst (TREE_OPERAND (t, 1), args, nargs, in_decl)));
166718334Speter
166818334Speter    case NEGATE_EXPR:
166918334Speter    case NOP_EXPR:
167018334Speter      return fold (build1 (TREE_CODE (t), TREE_TYPE (t),
167118334Speter			   tsubst (TREE_OPERAND (t, 0), args, nargs, in_decl)));
167218334Speter
167318334Speter    default:
167418334Speter      sorry ("use of `%s' in function template",
167518334Speter	     tree_code_name [(int) TREE_CODE (t)]);
167618334Speter      return error_mark_node;
167718334Speter    }
167818334Speter}
167918334Speter
168018334Spetertree
168118334Speterinstantiate_template (tmpl, targ_ptr)
168218334Speter     tree tmpl, *targ_ptr;
168318334Speter{
168418334Speter  tree targs, fndecl;
168518334Speter  int i, len;
168618334Speter  struct pending_inline *p;
168718334Speter  struct template_info *t;
168818334Speter  struct obstack *old_fmp_obstack;
168918334Speter  extern struct obstack *function_maybepermanent_obstack;
169018334Speter
169118334Speter  push_obstacks (&permanent_obstack, &permanent_obstack);
169218334Speter  old_fmp_obstack = function_maybepermanent_obstack;
169318334Speter  function_maybepermanent_obstack = &permanent_obstack;
169418334Speter
169518334Speter  my_friendly_assert (TREE_CODE (tmpl) == TEMPLATE_DECL, 283);
169618334Speter  len = TREE_VEC_LENGTH (DECL_TEMPLATE_PARMS (tmpl));
169718334Speter
169818334Speter  i = len;
169918334Speter  while (i--)
170018334Speter    targ_ptr[i] = copy_to_permanent (targ_ptr[i]);
170118334Speter
170218334Speter  for (fndecl = DECL_TEMPLATE_INSTANTIATIONS (tmpl);
170318334Speter       fndecl; fndecl = TREE_CHAIN (fndecl))
170418334Speter    {
170518334Speter      tree *t1 = &TREE_VEC_ELT (TREE_PURPOSE (fndecl), 0);
170618334Speter      for (i = len - 1; i >= 0; i--)
170718334Speter	if (simple_cst_equal (t1[i], targ_ptr[i]) <= 0)
170818334Speter	  goto no_match;
170918334Speter
171018334Speter      /* Here, we have a match.  */
171118334Speter      fndecl = TREE_VALUE (fndecl);
171218334Speter      goto exit;
171318334Speter
171418334Speter    no_match:
171518334Speter      ;
171618334Speter    }
171718334Speter
171818334Speter  targs = make_tree_vec (len);
171918334Speter  i = len;
172018334Speter  while (i--)
172118334Speter    TREE_VEC_ELT (targs, i) = targ_ptr[i];
172218334Speter
172318334Speter  /* substitute template parameters */
172418334Speter  fndecl = tsubst (DECL_RESULT (tmpl), targ_ptr,
172518334Speter		   TREE_VEC_LENGTH (targs), tmpl);
172618334Speter
172718334Speter  if (fndecl == error_mark_node)
172818334Speter    goto exit;
172918334Speter
173018334Speter  assemble_external (fndecl);
173118334Speter
173218334Speter  /* If it's a static member fn in the template, we need to change it
173318334Speter     into a FUNCTION_TYPE and chop off its this pointer.  */
173418334Speter  if (TREE_CODE (TREE_TYPE (DECL_RESULT (tmpl))) == METHOD_TYPE
173518334Speter      && DECL_STATIC_FUNCTION_P (fndecl))
173618334Speter    {
173718334Speter      revert_static_member_fn (&DECL_RESULT (tmpl), NULL, NULL);
173818334Speter      /* Chop off the this pointer that grokclassfn so kindly added
173918334Speter	 for us (it didn't know yet if the fn was static or not).  */
174018334Speter      DECL_ARGUMENTS (fndecl) = TREE_CHAIN (DECL_ARGUMENTS (fndecl));
174118334Speter    }
174218334Speter
174318334Speter  t = DECL_TEMPLATE_INFO (tmpl);
174418334Speter
174518334Speter  /* If we have a preexisting version of this function, don't expand
174618334Speter     the template version, use the other instead.  */
174718334Speter  if (TREE_STATIC (fndecl) || DECL_TEMPLATE_SPECIALIZATION (fndecl))
174818334Speter    {
174918334Speter      SET_DECL_TEMPLATE_SPECIALIZATION (fndecl);
175018334Speter      p = (struct pending_inline *)0;
175118334Speter    }
175218334Speter  else if (t->text)
175318334Speter    {
175418334Speter      SET_DECL_IMPLICIT_INSTANTIATION (fndecl);
175518334Speter      repo_template_used (fndecl);
175618334Speter      p = (struct pending_inline *) permalloc (sizeof (struct pending_inline));
175718334Speter      p->parm_vec = t->parm_vec;
175818334Speter      p->bindings = targs;
175918334Speter      p->can_free = 0;
176018334Speter      p->deja_vu = 0;
176118334Speter      p->buf = t->text;
176218334Speter      p->len = t->length;
176318334Speter      p->fndecl = fndecl;
176418334Speter      {
176518334Speter	int l = lineno;
176618334Speter	char * f = input_filename;
176718334Speter
176818334Speter	lineno = p->lineno = t->lineno;
176918334Speter	input_filename = p->filename = t->filename;
177018334Speter
177118334Speter	extract_interface_info ();
177218334Speter
177318334Speter	if (interface_unknown && flag_external_templates)
177418334Speter	  {
177518334Speter	    if (DECL_CLASS_CONTEXT (fndecl)
177618334Speter		&& CLASSTYPE_INTERFACE_KNOWN (DECL_CLASS_CONTEXT (fndecl)))
177718334Speter	      {
177818334Speter		interface_unknown = 0;
177918334Speter		interface_only
178018334Speter		  = CLASSTYPE_INTERFACE_ONLY (DECL_CLASS_CONTEXT (fndecl));
178118334Speter	      }
178218334Speter	    else if (! DECL_IN_SYSTEM_HEADER (tmpl))
178318334Speter	      warn_if_unknown_interface (tmpl);
178418334Speter	  }
178518334Speter
178618334Speter	if (interface_unknown || ! flag_external_templates)
178718334Speter	  p->interface = 1;		/* unknown */
178818334Speter	else
178918334Speter	  p->interface = interface_only ? 0 : 2;
179018334Speter
179118334Speter	lineno = l;
179218334Speter	input_filename = f;
179318334Speter
179418334Speter	extract_interface_info ();
179518334Speter      }
179618334Speter    }
179718334Speter  else
179818334Speter    p = (struct pending_inline *)0;
179918334Speter
180018334Speter  DECL_TEMPLATE_INSTANTIATIONS (tmpl) =
180118334Speter    tree_cons (targs, fndecl, DECL_TEMPLATE_INSTANTIATIONS (tmpl));
180218334Speter
180318334Speter  if (p == (struct pending_inline *)0)
180418334Speter    {
180518334Speter      /* do nothing */
180618334Speter    }
180718334Speter  else if (DECL_INLINE (fndecl))
180818334Speter    {
180918334Speter      DECL_PENDING_INLINE_INFO (fndecl) = p;
181018334Speter      p->next = pending_inlines;
181118334Speter      pending_inlines = p;
181218334Speter    }
181318334Speter  else
181418334Speter    {
181518334Speter      p->next = pending_template_expansions;
181618334Speter      pending_template_expansions = p;
181718334Speter    }
181818334Speter exit:
181918334Speter  function_maybepermanent_obstack = old_fmp_obstack;
182018334Speter  pop_obstacks ();
182118334Speter
182218334Speter  return fndecl;
182318334Speter}
182418334Speter
182518334Speter/* classlevel should now never be true.  jason 4/12/94 */
182618334Spetervoid
182718334Speterundo_template_name_overload (id, classlevel)
182818334Speter     tree id;
182918334Speter     int classlevel;
183018334Speter{
183118334Speter  tree template;
183218334Speter
183318334Speter  template = IDENTIFIER_TEMPLATE (id);
183418334Speter  if (!template)
183518334Speter    return;
183618334Speter
183718334Speter#if 0 /* not yet, should get fixed properly later */
183818334Speter  poplevel (0, 0, 0);
183918334Speter#endif
184018334Speter#if 1 /* XXX */
184118334Speter  /* This was a botch... See `overload_template_name' just below.  */
184218334Speter  if (!classlevel)
184318334Speter    poplevel (0, 0, 0);
184418334Speter#endif
184518334Speter}
184618334Speter
184718334Speter/* classlevel should now never be true.  jason 4/12/94 */
184818334Spetervoid
184918334Speteroverload_template_name (id, classlevel)
185018334Speter     tree id;
185118334Speter     int classlevel;
185218334Speter{
185318334Speter  tree template, t, decl;
185418334Speter  struct template_info *tinfo;
185518334Speter
185618334Speter  my_friendly_assert (TREE_CODE (id) == IDENTIFIER_NODE, 284);
185718334Speter  template = IDENTIFIER_TEMPLATE (id);
185818334Speter  if (!template)
185918334Speter    return;
186018334Speter
186118334Speter  template = TREE_PURPOSE (template);
186218334Speter  tinfo = DECL_TEMPLATE_INFO (template);
186318334Speter  template = DECL_NAME (template);
186418334Speter  my_friendly_assert (template != NULL_TREE, 285);
186518334Speter
186618334Speter#if 1 /* XXX */
186718334Speter  /* This was a botch... names of templates do not get their own private
186818334Speter     scopes.  Rather, they should go into the binding level already created
186918334Speter     by push_template_decls.  Except that there isn't one of those for
187018334Speter     specializations.  */
187118334Speter  if (!classlevel)
187218334Speter    {
187318334Speter      pushlevel (1);
187418334Speter      declare_pseudo_global_level ();
187518334Speter    }
187618334Speter#endif
187718334Speter
187818334Speter  t = xref_tag (tinfo->aggr, id, NULL_TREE, 1);
187918334Speter  my_friendly_assert (TREE_CODE (t) == RECORD_TYPE
188018334Speter		      || TREE_CODE (t) == UNION_TYPE
188118334Speter		      || TREE_CODE (t) == UNINSTANTIATED_P_TYPE, 286);
188218334Speter
188318334Speter  decl = build_decl (TYPE_DECL, template, t);
188418334Speter  SET_DECL_ARTIFICIAL (decl);
188518334Speter
188618334Speter#if 0 /* fix this later */
188718334Speter  /* We don't want to call here if the work has already been done.  */
188818334Speter  t = (classlevel
188918334Speter       ? IDENTIFIER_CLASS_VALUE (template)
189018334Speter       : IDENTIFIER_LOCAL_VALUE (template));
189118334Speter  if (t
189218334Speter      && TREE_CODE (t) == TYPE_DECL
189318334Speter      && TREE_TYPE (t) == t)
189418334Speter    my_friendly_abort (85);
189518334Speter#endif
189618334Speter
189718334Speter  if (classlevel)
189818334Speter    pushdecl_class_level (decl);
189918334Speter  else
190018334Speter    pushdecl (decl);
190118334Speter
190218334Speter#if 0 /* This seems bogus to me; if it isn't, explain why.  (jason) */
190318334Speter  /* Fake this for now, just to make dwarfout.c happy.  It will have to
190418334Speter     be done in a proper way later on.  */
190518334Speter  DECL_CONTEXT (decl) = t;
190618334Speter#endif
190718334Speter}
190818334Speter
190918334Speterextern struct pending_input *to_be_restored;
191018334Speter
191118334Speter/* NAME is the IDENTIFIER value of a PRE_PARSED_CLASS_DECL. */
191218334Spetervoid
191318334Speterend_template_instantiation (name)
191418334Speter     tree name;
191518334Speter{
191618334Speter  tree t, decl;
191718334Speter
191818334Speter  processing_template_defn--;
191918334Speter  if (!flag_external_templates)
192018334Speter    interface_unknown--;
192118334Speter
192218334Speter  /* Restore the old parser input state.  */
192318334Speter  if (yychar == YYEMPTY)
192418334Speter    yychar = yylex ();
192518334Speter  if (yychar != END_OF_SAVED_INPUT)
192618334Speter    error ("parse error at end of class template");
192718334Speter  else
192818334Speter    {
192918334Speter      restore_pending_input (to_be_restored);
193018334Speter      to_be_restored = 0;
193118334Speter    }
193218334Speter
193318334Speter  /* Our declarations didn't get stored in the global slot, since
193418334Speter     there was a (supposedly tags-transparent) scope in between.  */
193518334Speter  t = IDENTIFIER_TYPE_VALUE (name);
193618334Speter  my_friendly_assert (t != NULL_TREE
193718334Speter		      && TREE_CODE_CLASS (TREE_CODE (t)) == 't',
193818334Speter		      287);
193918334Speter  SET_CLASSTYPE_IMPLICIT_INSTANTIATION (t);
194018334Speter  /* Make methods of template classes static, unless
194118334Speter     -fexternal-templates is given.  */
194218334Speter  if (!flag_external_templates)
194318334Speter    SET_CLASSTYPE_INTERFACE_UNKNOWN (t);
194418334Speter  decl = IDENTIFIER_GLOBAL_VALUE (name);
194518334Speter  my_friendly_assert (TREE_CODE (decl) == TYPE_DECL, 288);
194618334Speter
194718334Speter  undo_template_name_overload (name, 0);
194818334Speter  t = IDENTIFIER_TEMPLATE (name);
194918334Speter  pop_template_decls (DECL_TEMPLATE_PARMS (TREE_PURPOSE (t)), TREE_VALUE (t),
195018334Speter		      0);
195118334Speter  /* This will fix up the type-value field.  */
195218334Speter  pushdecl (decl);
195318334Speter  pop_from_top_level ();
195418334Speter
195518334Speter#ifdef DWARF_DEBUGGING_INFO
195618334Speter  if (write_symbols == DWARF_DEBUG && TREE_CODE (decl) == TYPE_DECL)
195718334Speter    {
195818334Speter      /* We just completed the definition of a new file-scope type,
195918334Speter	 so we can go ahead and output debug-info for it now.  */
196018334Speter      TYPE_STUB_DECL (TREE_TYPE (decl)) = decl;
196118334Speter      rest_of_type_compilation (TREE_TYPE (decl), 1);
196218334Speter    }
196318334Speter#endif /* DWARF_DEBUGGING_INFO */
196418334Speter
196518334Speter  /* Restore interface/implementation settings.	 */
196618334Speter  extract_interface_info ();
196718334Speter}
196818334Speter
196918334Speter/* Store away the text of an template.  */
197018334Speter
197118334Spetervoid
197218334Speterreinit_parse_for_template (yychar, d1, d2)
197318334Speter     int yychar;
197418334Speter     tree d1, d2;
197518334Speter{
197618334Speter  struct template_info *template_info;
197718334Speter  extern struct obstack inline_text_obstack; /* see comment in lex.c */
197818334Speter
197918334Speter  if (d2 == NULL_TREE || d2 == error_mark_node)
198018334Speter    {
198118334Speter    lose:
198218334Speter      /* @@ Should use temp obstack, and discard results.  */
198318334Speter      reinit_parse_for_block (yychar, &inline_text_obstack, 1);
198418334Speter      return;
198518334Speter    }
198618334Speter
198718334Speter  if (TREE_CODE (d2) == IDENTIFIER_NODE)
198818334Speter    d2 = IDENTIFIER_GLOBAL_VALUE (d2);
198918334Speter  if (!d2)
199018334Speter    goto lose;
199118334Speter  template_info = DECL_TEMPLATE_INFO (d2);
199218334Speter  if (!template_info)
199318334Speter    {
199418334Speter      template_info = (struct template_info *) permalloc (sizeof (struct template_info));
199518334Speter      bzero ((char *) template_info, sizeof (struct template_info));
199618334Speter      DECL_TEMPLATE_INFO (d2) = template_info;
199718334Speter    }
199818334Speter  template_info->filename = input_filename;
199918334Speter  template_info->lineno = lineno;
200018334Speter  reinit_parse_for_block (yychar, &inline_text_obstack, 1);
200118334Speter  template_info->text = obstack_base (&inline_text_obstack);
200218334Speter  template_info->length = obstack_object_size (&inline_text_obstack);
200318334Speter  obstack_finish (&inline_text_obstack);
200418334Speter  template_info->parm_vec = d1;
200518334Speter}
200618334Speter
200718334Speter/* Type unification.
200818334Speter
200918334Speter   We have a function template signature with one or more references to
201018334Speter   template parameters, and a parameter list we wish to fit to this
201118334Speter   template.  If possible, produce a list of parameters for the template
201218334Speter   which will cause it to fit the supplied parameter list.
201318334Speter
201418334Speter   Return zero for success, 2 for an incomplete match that doesn't resolve
201518334Speter   all the types, and 1 for complete failure.  An error message will be
201618334Speter   printed only for an incomplete match.
201718334Speter
201818334Speter   TPARMS[NTPARMS] is an array of template parameter types;
201918334Speter   TARGS[NTPARMS] is the array of template parameter values.  PARMS is
202018334Speter   the function template's signature (using TEMPLATE_PARM_IDX nodes),
202118334Speter   and ARGS is the argument list we're trying to match against it.
202218334Speter
202318334Speter   If SUBR is 1, we're being called recursively (to unify the arguments of
202418334Speter   a function or method parameter of a function template), so don't zero
202518334Speter   out targs and don't fail on an incomplete match. */
202618334Speter
202718334Speterint
202818334Spetertype_unification (tparms, targs, parms, args, nsubsts, subr)
202918334Speter     tree tparms, *targs, parms, args;
203018334Speter     int *nsubsts, subr;
203118334Speter{
203218334Speter  tree parm, arg;
203318334Speter  int i;
203418334Speter  int ntparms = TREE_VEC_LENGTH (tparms);
203518334Speter
203618334Speter  my_friendly_assert (TREE_CODE (tparms) == TREE_VEC, 289);
203718334Speter  my_friendly_assert (TREE_CODE (parms) == TREE_LIST, 290);
203818334Speter  /* ARGS could be NULL (via a call from parse.y to
203918334Speter     build_x_function_call).  */
204018334Speter  if (args)
204118334Speter    my_friendly_assert (TREE_CODE (args) == TREE_LIST, 291);
204218334Speter  my_friendly_assert (ntparms > 0, 292);
204318334Speter
204418334Speter  if (!subr)
204518334Speter    bzero ((char *) targs, sizeof (tree) * ntparms);
204618334Speter
204718334Speter  while (parms
204818334Speter	 && parms != void_list_node
204918334Speter	 && args
205018334Speter	 && args != void_list_node)
205118334Speter    {
205218334Speter      parm = TREE_VALUE (parms);
205318334Speter      parms = TREE_CHAIN (parms);
205418334Speter      arg = TREE_VALUE (args);
205518334Speter      args = TREE_CHAIN (args);
205618334Speter
205718334Speter      if (arg == error_mark_node)
205818334Speter	return 1;
205918334Speter      if (arg == unknown_type_node)
206018334Speter	return 1;
206118334Speter
206218334Speter      if (! uses_template_parms (parm)
206318334Speter	  && TREE_CODE_CLASS (TREE_CODE (arg)) != 't')
206418334Speter	{
206518334Speter	  if (can_convert_arg (parm, TREE_TYPE (arg), arg))
206618334Speter	    continue;
206718334Speter	  return 1;
206818334Speter	}
206918334Speter
207018334Speter#if 0
207118334Speter      if (TREE_CODE (arg) == VAR_DECL)
207218334Speter	arg = TREE_TYPE (arg);
207318334Speter      else if (TREE_CODE_CLASS (TREE_CODE (arg)) == 'e')
207418334Speter	arg = TREE_TYPE (arg);
207518334Speter#else
207618334Speter      if (TREE_CODE_CLASS (TREE_CODE (arg)) != 't')
207718334Speter	{
207818334Speter	  my_friendly_assert (TREE_TYPE (arg) != NULL_TREE, 293);
207918334Speter	  if (TREE_CODE (arg) == TREE_LIST
208018334Speter	      && TREE_TYPE (arg) == unknown_type_node
208118334Speter	      && TREE_CODE (TREE_VALUE (arg)) == TEMPLATE_DECL)
208218334Speter	    {
208318334Speter	      int nsubsts, ntparms;
208418334Speter	      tree *targs;
208518334Speter
208618334Speter	      /* Have to back unify here */
208718334Speter	      arg = TREE_VALUE (arg);
208818334Speter	      nsubsts = 0;
208918334Speter	      ntparms = TREE_VEC_LENGTH (DECL_TEMPLATE_PARMS (arg));
209018334Speter	      targs = (tree *) alloca (sizeof (tree) * ntparms);
209118334Speter	      parm = tree_cons (NULL_TREE, parm, NULL_TREE);
209218334Speter	      return type_unification (DECL_TEMPLATE_PARMS (arg), targs,
209318334Speter				       TYPE_ARG_TYPES (TREE_TYPE (arg)),
209418334Speter				       parm, &nsubsts, 0);
209518334Speter	    }
209618334Speter	  arg = TREE_TYPE (arg);
209718334Speter	}
209818334Speter#endif
209918334Speter      if (TREE_CODE (arg) == REFERENCE_TYPE)
210018334Speter	arg = TREE_TYPE (arg);
210118334Speter
210218334Speter      if (TREE_CODE (parm) != REFERENCE_TYPE)
210318334Speter	{
210418334Speter	  if (TREE_CODE (arg) == FUNCTION_TYPE
210518334Speter	      || TREE_CODE (arg) == METHOD_TYPE)
210618334Speter	    arg = build_pointer_type (arg);
210718334Speter	  else if (TREE_CODE (arg) == ARRAY_TYPE)
210818334Speter	    arg = build_pointer_type (TREE_TYPE (arg));
210918334Speter	  else
211018334Speter	    arg = TYPE_MAIN_VARIANT (arg);
211118334Speter	}
211218334Speter
211318334Speter      switch (unify (tparms, targs, ntparms, parm, arg, nsubsts))
211418334Speter	{
211518334Speter	case 0:
211618334Speter	  break;
211718334Speter	case 1:
211818334Speter	  return 1;
211918334Speter	}
212018334Speter    }
212118334Speter  /* Fail if we've reached the end of the parm list, and more args
212218334Speter     are present, and the parm list isn't variadic.  */
212318334Speter  if (args && args != void_list_node && parms == void_list_node)
212418334Speter    return 1;
212518334Speter  /* Fail if parms are left and they don't have default values.	 */
212618334Speter  if (parms
212718334Speter      && parms != void_list_node
212818334Speter      && TREE_PURPOSE (parms) == NULL_TREE)
212918334Speter    return 1;
213018334Speter  if (!subr)
213118334Speter    for (i = 0; i < ntparms; i++)
213218334Speter      if (!targs[i])
213318334Speter	{
213418334Speter	  error ("incomplete type unification");
213518334Speter	  return 2;
213618334Speter	}
213718334Speter  return 0;
213818334Speter}
213918334Speter
214018334Speter/* Tail recursion is your friend.  */
214118334Speterstatic int
214218334Speterunify (tparms, targs, ntparms, parm, arg, nsubsts)
214318334Speter     tree tparms, *targs, parm, arg;
214418334Speter     int *nsubsts, ntparms;
214518334Speter{
214618334Speter  int idx;
214718334Speter
214818334Speter  /* I don't think this will do the right thing with respect to types.
214918334Speter     But the only case I've seen it in so far has been array bounds, where
215018334Speter     signedness is the only information lost, and I think that will be
215118334Speter     okay.  */
215218334Speter  while (TREE_CODE (parm) == NOP_EXPR)
215318334Speter    parm = TREE_OPERAND (parm, 0);
215418334Speter
215518334Speter  if (arg == error_mark_node)
215618334Speter    return 1;
215718334Speter  if (arg == unknown_type_node)
215818334Speter    return 1;
215918334Speter  if (arg == parm)
216018334Speter    return 0;
216118334Speter
216218334Speter  switch (TREE_CODE (parm))
216318334Speter    {
216418334Speter    case TEMPLATE_TYPE_PARM:
216518334Speter      (*nsubsts)++;
216618334Speter      if (TEMPLATE_TYPE_TPARMLIST (parm) != tparms)
216718334Speter	{
216818334Speter	  error ("mixed template headers?!");
216918334Speter	  my_friendly_abort (86);
217018334Speter	  return 1;
217118334Speter	}
217218334Speter      idx = TEMPLATE_TYPE_IDX (parm);
217318334Speter#if 0
217418334Speter      /* Template type parameters cannot contain cv-quals; i.e.
217518334Speter         template <class T> void f (T& a, T& b) will not generate
217618334Speter	 void f (const int& a, const int& b).  */
217718334Speter      if (TYPE_READONLY (arg) > TYPE_READONLY (parm)
217818334Speter	  || TYPE_VOLATILE (arg) > TYPE_VOLATILE (parm))
217918334Speter	return 1;
218018334Speter      arg = TYPE_MAIN_VARIANT (arg);
218118334Speter#else
218218334Speter      {
218318334Speter	int constp = TYPE_READONLY (arg) > TYPE_READONLY (parm);
218418334Speter	int volatilep = TYPE_VOLATILE (arg) > TYPE_VOLATILE (parm);
218518334Speter	arg = cp_build_type_variant (arg, constp, volatilep);
218618334Speter      }
218718334Speter#endif
218818334Speter      /* Simple cases: Value already set, does match or doesn't.  */
218918334Speter      if (targs[idx] == arg)
219018334Speter	return 0;
219118334Speter      else if (targs[idx])
219218334Speter	return 1;
219318334Speter      /* Check for mixed types and values.  */
219418334Speter      if (TREE_CODE (TREE_VALUE (TREE_VEC_ELT (tparms, idx))) != TYPE_DECL)
219518334Speter	return 1;
219618334Speter      targs[idx] = arg;
219718334Speter      return 0;
219818334Speter    case TEMPLATE_CONST_PARM:
219918334Speter      (*nsubsts)++;
220018334Speter      idx = TEMPLATE_CONST_IDX (parm);
220118334Speter      if (targs[idx] == arg)
220218334Speter	return 0;
220318334Speter      else if (targs[idx])
220418334Speter	{
220518334Speter	  tree t = targs[idx];
220618334Speter	  if (TREE_CODE (t) == TREE_CODE (arg))
220718334Speter	    switch (TREE_CODE (arg))
220818334Speter	      {
220918334Speter	      case INTEGER_CST:
221018334Speter		if (tree_int_cst_equal (t, arg))
221118334Speter		  return 0;
221218334Speter		break;
221318334Speter	      case REAL_CST:
221418334Speter		if (REAL_VALUES_EQUAL (TREE_REAL_CST (t), TREE_REAL_CST (arg)))
221518334Speter		  return 0;
221618334Speter		break;
221718334Speter	      /* STRING_CST values are not valid template const parms.  */
221818334Speter	      default:
221918334Speter		;
222018334Speter	      }
222118334Speter	  my_friendly_abort (87);
222218334Speter	  return 1;
222318334Speter	}
222418334Speter/*	else if (typeof arg != tparms[idx])
222518334Speter	return 1;*/
222618334Speter
222718334Speter      targs[idx] = copy_to_permanent (arg);
222818334Speter      return 0;
222918334Speter
223018334Speter    case POINTER_TYPE:
223118334Speter      if (TREE_CODE (arg) != POINTER_TYPE)
223218334Speter	return 1;
223318334Speter      return unify (tparms, targs, ntparms, TREE_TYPE (parm), TREE_TYPE (arg),
223418334Speter		    nsubsts);
223518334Speter
223618334Speter    case REFERENCE_TYPE:
223718334Speter      if (TREE_CODE (arg) == REFERENCE_TYPE)
223818334Speter	arg = TREE_TYPE (arg);
223918334Speter      return unify (tparms, targs, ntparms, TREE_TYPE (parm), arg, nsubsts);
224018334Speter
224118334Speter    case ARRAY_TYPE:
224218334Speter      if (TREE_CODE (arg) != ARRAY_TYPE)
224318334Speter	return 1;
224418334Speter      if (unify (tparms, targs, ntparms, TYPE_DOMAIN (parm), TYPE_DOMAIN (arg),
224518334Speter		 nsubsts) != 0)
224618334Speter	return 1;
224718334Speter      return unify (tparms, targs, ntparms, TREE_TYPE (parm), TREE_TYPE (arg),
224818334Speter		    nsubsts);
224918334Speter
225018334Speter    case REAL_TYPE:
225118334Speter    case INTEGER_TYPE:
225218334Speter      if (TREE_CODE (arg) != TREE_CODE (parm))
225318334Speter	return 1;
225418334Speter
225518334Speter      if (TREE_CODE (parm) == INTEGER_TYPE)
225618334Speter	{
225718334Speter	  if (TYPE_MIN_VALUE (parm) && TYPE_MIN_VALUE (arg)
225818334Speter	      && unify (tparms, targs, ntparms,
225918334Speter			TYPE_MIN_VALUE (parm), TYPE_MIN_VALUE (arg), nsubsts))
226018334Speter	    return 1;
226118334Speter	  if (TYPE_MAX_VALUE (parm) && TYPE_MAX_VALUE (arg)
226218334Speter	      && unify (tparms, targs, ntparms,
226318334Speter			TYPE_MAX_VALUE (parm), TYPE_MAX_VALUE (arg), nsubsts))
226418334Speter	    return 1;
226518334Speter	}
226618334Speter      /* As far as unification is concerned, this wins.	 Later checks
226718334Speter	 will invalidate it if necessary.  */
226818334Speter      return 0;
226918334Speter
227018334Speter      /* Types INTEGER_CST and MINUS_EXPR can come from array bounds.  */
227118334Speter    case INTEGER_CST:
227218334Speter      if (TREE_CODE (arg) != INTEGER_CST)
227318334Speter	return 1;
227418334Speter      return !tree_int_cst_equal (parm, arg);
227518334Speter
227618334Speter    case MINUS_EXPR:
227718334Speter      {
227818334Speter	tree t1, t2;
227918334Speter	t1 = TREE_OPERAND (parm, 0);
228018334Speter	t2 = TREE_OPERAND (parm, 1);
228118334Speter	return unify (tparms, targs, ntparms, t1,
228218334Speter		      fold (build (PLUS_EXPR, integer_type_node, arg, t2)),
228318334Speter		      nsubsts);
228418334Speter      }
228518334Speter
228618334Speter    case TREE_VEC:
228718334Speter      {
228818334Speter	int i;
228918334Speter	if (TREE_CODE (arg) != TREE_VEC)
229018334Speter	  return 1;
229118334Speter	if (TREE_VEC_LENGTH (parm) != TREE_VEC_LENGTH (arg))
229218334Speter	  return 1;
229318334Speter	for (i = TREE_VEC_LENGTH (parm) - 1; i >= 0; i--)
229418334Speter	  if (unify (tparms, targs, ntparms,
229518334Speter		     TREE_VEC_ELT (parm, i), TREE_VEC_ELT (arg, i),
229618334Speter		     nsubsts))
229718334Speter	    return 1;
229818334Speter	return 0;
229918334Speter      }
230018334Speter
230118334Speter    case UNINSTANTIATED_P_TYPE:
230218334Speter      {
230318334Speter	tree a;
230418334Speter	/* Unification of something that is not a class fails.  */
230518334Speter	if (! IS_AGGR_TYPE (arg))
230618334Speter	  return 1;
230718334Speter	a = IDENTIFIER_TEMPLATE (TYPE_IDENTIFIER (arg));
230818334Speter	if (a && UPT_TEMPLATE (parm) == TREE_PURPOSE (a))
230918334Speter	  return unify (tparms, targs, ntparms, UPT_PARMS (parm),
231018334Speter			TREE_VALUE (a), nsubsts);
231118334Speter	/* FIXME: Should check base conversions here.  */
231218334Speter	return 1;
231318334Speter      }
231418334Speter
231518334Speter    case RECORD_TYPE:
231618334Speter      if (TYPE_PTRMEMFUNC_FLAG (parm))
231718334Speter	return unify (tparms, targs, ntparms, TYPE_PTRMEMFUNC_FN_TYPE (parm),
231818334Speter		      arg, nsubsts);
231918334Speter
232018334Speter      /* Allow trivial conversions.  */
232118334Speter      if (TYPE_MAIN_VARIANT (parm) != TYPE_MAIN_VARIANT (arg)
232218334Speter	  || TYPE_READONLY (parm) < TYPE_READONLY (arg)
232318334Speter	  || TYPE_VOLATILE (parm) < TYPE_VOLATILE (arg))
232418334Speter	return 1;
232518334Speter      return 0;
232618334Speter
232718334Speter    case METHOD_TYPE:
232818334Speter      if (TREE_CODE (arg) != METHOD_TYPE)
232918334Speter	return 1;
233018334Speter      goto check_args;
233118334Speter
233218334Speter    case FUNCTION_TYPE:
233318334Speter      if (TREE_CODE (arg) != FUNCTION_TYPE)
233418334Speter	return 1;
233518334Speter     check_args:
233618334Speter      if (unify (tparms, targs, ntparms, TREE_TYPE (parm),
233718334Speter		 TREE_TYPE (arg), nsubsts))
233818334Speter	return 1;
233918334Speter      return type_unification (tparms, targs, TYPE_ARG_TYPES (parm),
234018334Speter			       TYPE_ARG_TYPES (arg), nsubsts, 1);
234118334Speter
234218334Speter    case OFFSET_TYPE:
234318334Speter      if (TREE_CODE (arg) != OFFSET_TYPE)
234418334Speter	return 1;
234518334Speter      if (unify (tparms, targs, ntparms, TYPE_OFFSET_BASETYPE (parm),
234618334Speter		 TYPE_OFFSET_BASETYPE (arg), nsubsts))
234718334Speter	return 1;
234818334Speter      return unify (tparms, targs, ntparms, TREE_TYPE (parm),
234918334Speter		    TREE_TYPE (arg), nsubsts);
235018334Speter
235118334Speter    default:
235218334Speter      sorry ("use of `%s' in template type unification",
235318334Speter	     tree_code_name [(int) TREE_CODE (parm)]);
235418334Speter      return 1;
235518334Speter    }
235618334Speter}
235718334Speter
235818334Speter
235918334Speter#undef DEBUG
236018334Speter
236118334Speterint
236218334Speterdo_pending_expansions ()
236318334Speter{
236418334Speter  struct pending_inline *i, *new_list = 0;
236518334Speter
236618334Speter  {
236718334Speter    tree t;
236818334Speter    for (t = template_classes; t; t = TREE_CHAIN (t))
236918334Speter      instantiate_member_templates (TREE_PURPOSE (t));
237018334Speter  }
237118334Speter
237218334Speter  if (!pending_template_expansions)
237318334Speter    return 0;
237418334Speter
237518334Speter#ifdef DEBUG
237618334Speter  fprintf (stderr, "\n\n\t\t IN DO_PENDING_EXPANSIONS\n\n");
237718334Speter#endif
237818334Speter
237918334Speter  i = pending_template_expansions;
238018334Speter  while (i)
238118334Speter    {
238218334Speter      tree context;
238318334Speter
238418334Speter      struct pending_inline *next = i->next;
238518334Speter      tree t = i->fndecl;
238618334Speter
238718334Speter      int decision = 0;
238818334Speter#define DECIDE(N) do {decision=(N); goto decided;} while(0)
238918334Speter
239018334Speter      my_friendly_assert (TREE_CODE (t) == FUNCTION_DECL
239118334Speter			  || TREE_CODE (t) == VAR_DECL, 294);
239218334Speter      if (TREE_ASM_WRITTEN (t))
239318334Speter	DECIDE (0);
239418334Speter
239518334Speter      if (DECL_EXPLICIT_INSTANTIATION (t))
239618334Speter	DECIDE (DECL_NOT_REALLY_EXTERN (t));
239718334Speter      else if (! flag_implicit_templates)
239818334Speter	DECIDE (0);
239918334Speter
240018334Speter      if (i->interface == 1)
240118334Speter	/* OK, it was an implicit instantiation.  */
240218334Speter	{
240318334Speter	  if (SUPPORTS_WEAK)
240418334Speter	    DECL_WEAK (t) = 1;
240518334Speter	  else
240618334Speter	    TREE_PUBLIC (t) = 0;
240718334Speter	}
240818334Speter
240918334Speter      /* If it's a method, let the class type decide it.
241018334Speter	 @@ What if the method template is in a separate file?
241118334Speter	 Maybe both file contexts should be taken into account?
241218334Speter	 Maybe only do this if i->interface == 1 (unknown)?  */
241318334Speter      context = DECL_CONTEXT (t);
241418334Speter      if (context != NULL_TREE
241518334Speter	  && TREE_CODE_CLASS (TREE_CODE (context)) == 't')
241618334Speter	{
241718334Speter	  /* I'm interested in the context of this version of the function,
241818334Speter	     not the original virtual declaration.  */
241918334Speter	  context = DECL_CLASS_CONTEXT (t);
242018334Speter
242118334Speter	  /* If `unknown', we might want a static copy.
242218334Speter	     If `implementation', we want a global one.
242318334Speter	     If `interface', ext ref.  */
242418334Speter	  if (CLASSTYPE_INTERFACE_KNOWN (context))
242518334Speter	    DECIDE (!CLASSTYPE_INTERFACE_ONLY (context));
242618334Speter#if 1 /* This doesn't get us stuff needed only by the file initializer.  */
242718334Speter	  DECIDE (TREE_USED (t));
242818334Speter#else /* This compiles too much stuff, but that's probably better in
242918334Speter	 most cases than never compiling the stuff we need.  */
243018334Speter	  DECIDE (1);
243118334Speter#endif
243218334Speter	}
243318334Speter
243418334Speter      if (i->interface == 1)
243518334Speter	DECIDE (TREE_USED (t));
243618334Speter      else
243718334Speter	DECIDE (i->interface);
243818334Speter
243918334Speter    decided:
244018334Speter#ifdef DEBUG
244118334Speter      print_node_brief (stderr, decision ? "yes: " : "no: ", t, 0);
244218334Speter      fprintf (stderr, "\t%s\n",
244318334Speter	       (DECL_ASSEMBLER_NAME (t)
244418334Speter		? IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (t))
244518334Speter		: ""));
244618334Speter#endif
244718334Speter      if (decision)
244818334Speter	{
244918334Speter	  i->next = pending_inlines;
245018334Speter	  pending_inlines = i;
245118334Speter	}
245218334Speter      else
245318334Speter	{
245418334Speter	  i->next = new_list;
245518334Speter	  new_list = i;
245618334Speter	}
245718334Speter      i = next;
245818334Speter    }
245918334Speter  pending_template_expansions = new_list;
246018334Speter  if (!pending_inlines)
246118334Speter    return 0;
246218334Speter  do_pending_inlines ();
246318334Speter  return 1;
246418334Speter}
246518334Speter
246618334Speter
246718334Speterstruct pending_template {
246818334Speter  struct pending_template *next;
246918334Speter  tree id;
247018334Speter};
247118334Speter
247218334Speterstatic struct pending_template* pending_templates;
247318334Speter
247418334Spetervoid
247518334Speterdo_pending_templates ()
247618334Speter{
247718334Speter  struct pending_template* t;
247818334Speter
247918334Speter  for ( t = pending_templates; t; t = t->next)
248018334Speter    {
248118334Speter      instantiate_class_template (t->id, 1);
248218334Speter    }
248318334Speter
248418334Speter  for ( t = pending_templates; t; t = pending_templates)
248518334Speter    {
248618334Speter      pending_templates = t->next;
248718334Speter      free(t);
248818334Speter    }
248918334Speter}
249018334Speter
249118334Speterstatic void
249218334Speteradd_pending_template (pt)
249318334Speter     tree pt;
249418334Speter{
249518334Speter  struct pending_template *p;
249618334Speter
249718334Speter  p = (struct pending_template *) malloc (sizeof (struct pending_template));
249818334Speter  p->next = pending_templates;
249918334Speter  pending_templates = p;
250018334Speter  p->id = pt;
250118334Speter}
250218334Speter
250318334Spetervoid
250418334Spetermark_function_instantiated (result, extern_p)
250518334Speter     tree result;
250618334Speter     int extern_p;
250718334Speter{
250818334Speter  if (DECL_TEMPLATE_INSTANTIATION (result))
250918334Speter    SET_DECL_EXPLICIT_INSTANTIATION (result);
251018334Speter  TREE_PUBLIC (result) = 1;
251118334Speter
251218334Speter  if (! extern_p)
251318334Speter    {
251418334Speter      DECL_INTERFACE_KNOWN (result) = 1;
251518334Speter      DECL_NOT_REALLY_EXTERN (result) = 1;
251618334Speter    }
251718334Speter}
251818334Speter
251918334Speter/* called from the parser.  */
252018334Spetervoid
252118334Speterdo_function_instantiation (declspecs, declarator, storage)
252218334Speter     tree declspecs, declarator, storage;
252318334Speter{
252418334Speter  tree decl = grokdeclarator (declarator, declspecs, NORMAL, 0,
252518334Speter			      NULL_TREE, NULL_TREE);
252618334Speter  tree name;
252718334Speter  tree fn;
252818334Speter  tree result = NULL_TREE;
252918334Speter  int extern_p = 0;
253018334Speter
253118334Speter  /* If we've already seen this template instance, use it.  */
253218334Speter  if (name = DECL_ASSEMBLER_NAME (decl),
253318334Speter      fn = IDENTIFIER_GLOBAL_VALUE (name),
253418334Speter      fn && DECL_TEMPLATE_INSTANTIATION (fn))
253518334Speter    result = fn;
253618334Speter  else if (name = DECL_NAME (decl), fn = IDENTIFIER_GLOBAL_VALUE (name), fn)
253718334Speter    {
253818334Speter      for (fn = get_first_fn (fn); fn; fn = DECL_CHAIN (fn))
253918334Speter	if (decls_match (fn, decl)
254018334Speter	    && DECL_DEFER_OUTPUT (fn))
254118334Speter	  {
254218334Speter	    result = fn;
254318334Speter	    break;
254418334Speter	  }
254518334Speter	else if (TREE_CODE (fn) == TEMPLATE_DECL)
254618334Speter	  {
254718334Speter	    int ntparms = TREE_VEC_LENGTH (DECL_TEMPLATE_PARMS (fn));
254818334Speter	    tree *targs = (tree *) malloc (sizeof (tree) * ntparms);
254918334Speter	    int i, dummy = 0;
255018334Speter	    i = type_unification (DECL_TEMPLATE_PARMS (fn), targs,
255118334Speter				  TYPE_ARG_TYPES (TREE_TYPE (fn)),
255218334Speter				  TYPE_ARG_TYPES (TREE_TYPE (decl)),
255318334Speter				  &dummy, 0);
255418334Speter	    if (i == 0)
255518334Speter	      {
255618334Speter		if (result)
255718334Speter		  cp_error ("ambiguous template instantiation for `%D' requested", decl);
255818334Speter		else
255918334Speter		  result = instantiate_template (fn, targs);
256018334Speter	      }
256118334Speter	    free (targs);
256218334Speter	  }
256318334Speter    }
256418334Speter  if (! result)
256518334Speter    {
256618334Speter      cp_error ("no matching template for `%D' found", decl);
256718334Speter      return;
256818334Speter    }
256918334Speter
257018334Speter  if (flag_external_templates)
257118334Speter    return;
257218334Speter
257318334Speter  if (storage == NULL_TREE)
257418334Speter    ;
257518334Speter  else if (storage == ridpointers[(int) RID_EXTERN])
257618334Speter    extern_p = 1;
257718334Speter  else
257818334Speter    cp_error ("storage class `%D' applied to template instantiation",
257918334Speter	      storage);
258018334Speter  mark_function_instantiated (result, extern_p);
258118334Speter  repo_template_instantiated (result, extern_p);
258218334Speter}
258318334Speter
258418334Spetervoid
258518334Spetermark_class_instantiated (t, extern_p)
258618334Speter     tree t;
258718334Speter     int extern_p;
258818334Speter{
258918334Speter  SET_CLASSTYPE_EXPLICIT_INSTANTIATION (t);
259018334Speter  SET_CLASSTYPE_INTERFACE_KNOWN (t);
259118334Speter  CLASSTYPE_INTERFACE_ONLY (t) = extern_p;
259218334Speter  CLASSTYPE_VTABLE_NEEDS_WRITING (t) = ! extern_p;
259318334Speter  TYPE_DECL_SUPPRESS_DEBUG (TYPE_NAME (t)) = extern_p;
259418334Speter  if (! extern_p)
259518334Speter    {
259618334Speter      CLASSTYPE_DEBUG_REQUESTED (t) = 1;
259718334Speter      rest_of_type_compilation (t, 1);
259818334Speter    }
259918334Speter}
260018334Speter
260118334Spetervoid
260218334Speterdo_type_instantiation (name, storage)
260318334Speter     tree name, storage;
260418334Speter{
260518334Speter  tree t = TREE_TYPE (name);
260618334Speter  int extern_p = 0;
260718334Speter  int nomem_p = 0;
260818334Speter
260918334Speter  /* With -fexternal-templates, explicit instantiations are treated the same
261018334Speter     as implicit ones.  */
261118334Speter  if (flag_external_templates)
261218334Speter    return;
261318334Speter
261418334Speter  if (TYPE_SIZE (t) == NULL_TREE)
261518334Speter    {
261618334Speter      cp_error ("explicit instantiation of `%#T' before definition of template",
261718334Speter		t);
261818334Speter      return;
261918334Speter    }
262018334Speter
262118334Speter  if (storage == NULL_TREE)
262218334Speter    /* OK */;
262318334Speter  else if (storage == ridpointers[(int) RID_INLINE])
262418334Speter    nomem_p = 1;
262518334Speter  else if (storage == ridpointers[(int) RID_EXTERN])
262618334Speter    extern_p = 1;
262718334Speter  else
262818334Speter    {
262918334Speter      cp_error ("storage class `%D' applied to template instantiation",
263018334Speter		storage);
263118334Speter      extern_p = 0;
263218334Speter    }
263318334Speter
263418334Speter  /* We've already instantiated this.  */
263518334Speter  if (CLASSTYPE_EXPLICIT_INSTANTIATION (t) && ! CLASSTYPE_INTERFACE_ONLY (t)
263618334Speter      && extern_p)
263718334Speter    return;
263818334Speter
263918334Speter  if (! CLASSTYPE_TEMPLATE_SPECIALIZATION (t))
264018334Speter    {
264118334Speter      mark_class_instantiated (t, extern_p);
264218334Speter      repo_template_instantiated (t, extern_p);
264318334Speter    }
264418334Speter
264518334Speter  if (nomem_p)
264618334Speter    return;
264718334Speter
264818334Speter  {
264918334Speter    tree tmp;
265018334Speter    /* Classes nested in template classes currently don't have an
265118334Speter       IDENTIFIER_TEMPLATE--their out-of-line members are handled
265218334Speter       by the enclosing template class.  Note that there are name
265318334Speter       conflict bugs with this approach. */
265418334Speter    tmp = TYPE_IDENTIFIER (t);
265518334Speter    if (IDENTIFIER_TEMPLATE (tmp))
265618334Speter      instantiate_member_templates (tmp);
265718334Speter
265818334Speter    /* this should really be done by instantiate_member_templates */
265918334Speter    tmp = TREE_VEC_ELT (CLASSTYPE_METHOD_VEC (t), 0);
266018334Speter    for (; tmp; tmp = TREE_CHAIN (tmp))
266118334Speter      if (DECL_TEMPLATE_INSTANTIATION (tmp))
266218334Speter	{
266318334Speter	  mark_function_instantiated (tmp, extern_p);
266418334Speter	  repo_template_instantiated (tmp, extern_p);
266518334Speter	}
266618334Speter
266718334Speter#if 0
266818334Speter    for (tmp = TYPE_FIELDS (t); tmp; tmp = TREE_CHAIN (tmp))
266918334Speter      {
267018334Speter	if (TREE_CODE (tmp) == VAR_DECL)
267118334Speter	  /* eventually do something */;
267218334Speter      }
267318334Speter#endif
267418334Speter
267518334Speter    for (tmp = CLASSTYPE_TAGS (t); tmp; tmp = TREE_CHAIN (tmp))
267618334Speter      if (IS_AGGR_TYPE (TREE_VALUE (tmp)))
267718334Speter	do_type_instantiation (TYPE_MAIN_DECL (TREE_VALUE (tmp)), storage);
267818334Speter  }
267918334Speter}
268018334Speter
268118334Spetertree
268218334Spetercreate_nested_upt (scope, name)
268318334Speter     tree scope, name;
268418334Speter{
268518334Speter  tree t = make_lang_type (UNINSTANTIATED_P_TYPE);
268618334Speter  tree d = build_decl (TYPE_DECL, name, t);
268718334Speter
268818334Speter  TYPE_NAME (t) = d;
268918334Speter  TYPE_VALUES (t) = TYPE_VALUES (scope);
269018334Speter  TYPE_CONTEXT (t) = scope;
269118334Speter
269218334Speter  pushdecl (d);
269318334Speter  return d;
269418334Speter}
2695