Annotation of gcc/cp-pt.c, revision 1.1.1.6

1.1       root        1: /* Handle parameterized types (templates) for GNU C++.
1.1.1.5   root        2:    Copyright (C) 1992, 1993 Free Software Foundation, Inc.
                      3:    Written by Ken Raeburn ([email protected]) while at Watchmaker Computing.
1.1       root        4: 
                      5: This file is part of GNU CC.
                      6: 
                      7: GNU CC is free software; you can redistribute it and/or modify
                      8: it under the terms of the GNU General Public License as published by
                      9: the Free Software Foundation; either version 2, or (at your option)
                     10: any later version.
                     11: 
                     12: GNU CC is distributed in the hope that it will be useful,
                     13: but WITHOUT ANY WARRANTY; without even the implied warranty of
                     14: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
                     15: GNU General Public License for more details.
                     16: 
                     17: You should have received a copy of the GNU General Public License
                     18: along with GNU CC; see the file COPYING.  If not, write to
                     19: the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
                     20: 
                     21: /* Known bugs or deficiencies include:
                     22:    * templates for class static data don't work (methods only)
                     23:    * duplicated method templates can crash the compiler
                     24:    * interface/impl data is taken from file defining the template
                     25:    * all methods must be provided in header files; can't use a source
                     26:      file that contains only the method templates and "just win"
                     27:    * method templates must be seen before the expansion of the
                     28:      class template is done
                     29:  */
                     30: 
                     31: #include "config.h"
                     32: #include <stdio.h>
                     33: #include "obstack.h"
                     34: 
                     35: #include "tree.h"
1.1.1.6 ! root       36: #include "flags.h"
1.1       root       37: #include "cp-tree.h"
                     38: #include "cp-decl.h"
                     39: #include "cp-parse.h"
                     40: 
                     41: extern struct obstack permanent_obstack;
                     42: extern tree grokdeclarator ();
                     43: 
                     44: extern int lineno;
                     45: extern char *input_filename;
                     46: struct pending_inline *pending_template_expansions;
                     47: 
                     48: int processing_template_decl;
                     49: int processing_template_defn;
                     50: 
                     51: #define obstack_chunk_alloc xmalloc
                     52: #define obstack_chunk_free free
                     53: 
                     54: static int unify ();
1.1.1.4   root       55: static void add_pending_template ();
1.1       root       56: 
                     57: void overload_template_name (), pop_template_decls ();
                     58: 
                     59: /* We've got a template header coming up; set obstacks up to save the
                     60:    nodes created permanently.  (There might be cases with nested templates
                     61:    where we don't have to do this, but they aren't implemented, and it
                     62:    probably wouldn't be worth the effort.)  */
                     63: void
                     64: begin_template_parm_list ()
                     65: {
                     66:   pushlevel (0);
                     67:   push_obstacks (&permanent_obstack, &permanent_obstack);
1.1.1.6 ! root       68:   pushlevel (0);
1.1       root       69: }
                     70: 
                     71: /* Process information from new template parameter NEXT and append it to the
                     72:    LIST being built.  The rules for use of a template parameter type name
                     73:    by later parameters are not well-defined for us just yet.  However, the
                     74:    only way to avoid having to parse expressions of unknown complexity (and
                     75:    with tokens of unknown types) is to disallow it completely. So for now,
                     76:    that is what is assumed.  */
                     77: tree
                     78: process_template_parm (list, next)
                     79:      tree list, next;
                     80: {
                     81:   tree parm;
1.1.1.6 ! root       82:   tree decl = 0;
1.1       root       83:   int is_type;
                     84:   parm = next;
1.1.1.4   root       85:   my_friendly_assert (TREE_CODE (parm) == TREE_LIST, 259);
1.1       root       86:   is_type = TREE_CODE (TREE_PURPOSE (parm)) == IDENTIFIER_NODE;
                     87:   if (!is_type)
                     88:     {
1.1.1.6 ! root       89:       tree tinfo = 0;
        !            90:       int  idx = 0;
1.1       root       91:       parm = TREE_PURPOSE (parm);
1.1.1.4   root       92:       my_friendly_assert (TREE_CODE (parm) == TREE_LIST, 260);
1.1       root       93:       parm = TREE_VALUE (parm);
                     94:       /* is a const-param */
                     95:       parm = grokdeclarator (TREE_VALUE (next), TREE_PURPOSE (next),
1.1.1.6 ! root       96:                             PARM, 0, NULL_TREE);
1.1       root       97:       /* A template parameter is not modifiable.  */
                     98:       TREE_READONLY (parm) = 1;
                     99:       if (TREE_CODE (TREE_TYPE (parm)) == RECORD_TYPE
                    100:          || TREE_CODE (TREE_TYPE (parm)) == UNION_TYPE)
                    101:        {
                    102:          sorry ("aggregate template parameter types");
                    103:          TREE_TYPE (parm) = void_type_node;
                    104:        }
1.1.1.6 ! root      105:       tinfo = make_node (TEMPLATE_CONST_PARM);
        !           106:       my_friendly_assert (TREE_PERMANENT (tinfo), 260.5);
        !           107:       if (TREE_PERMANENT (parm) == 0)
        !           108:         {
        !           109:          parm = copy_node (parm);
        !           110:          TREE_PERMANENT (parm) = 1;
        !           111:         }
        !           112:       TREE_TYPE (tinfo) = TREE_TYPE (parm);
        !           113:       decl = build_decl (CONST_DECL, DECL_NAME (parm), TREE_TYPE (parm));
        !           114:       DECL_INITIAL (decl) = tinfo;
        !           115:       DECL_INITIAL (parm) = tinfo;
        !           116:     }
        !           117:   else
        !           118:     {
        !           119:       tree t = make_node (TEMPLATE_TYPE_PARM);
        !           120:       decl = build_lang_decl (TYPE_DECL, TREE_PURPOSE (parm), t);
        !           121:       TYPE_NAME (t) = decl;
        !           122:       TREE_VALUE (parm) = t;
1.1       root      123:     }
1.1.1.6 ! root      124:   pushdecl (decl);
1.1       root      125:   return chainon (list, parm);
                    126: }
                    127: 
                    128: /* The end of a template parameter list has been reached.  Process the
                    129:    tree list into a parameter vector, converting each parameter into a more
                    130:    useful form.         Type parameters are saved as IDENTIFIER_NODEs, and others
                    131:    as PARM_DECLs.  */
                    132: 
                    133: tree
                    134: end_template_parm_list (parms)
                    135:      tree parms;
                    136: {
                    137:   int nparms = 0;
                    138:   tree saved_parmlist;
                    139:   tree parm;
                    140:   for (parm = parms; parm; parm = TREE_CHAIN (parm))
                    141:     nparms++;
                    142:   saved_parmlist = make_tree_vec (nparms);
                    143: 
                    144:   for (parm = parms, nparms = 0; parm; parm = TREE_CHAIN (parm), nparms++)
                    145:     {
1.1.1.6 ! root      146:       tree p = parm;
1.1       root      147:       if (TREE_CODE (p) == TREE_LIST)
                    148:        {
1.1.1.6 ! root      149:          tree t = TREE_VALUE (p);
        !           150:          TREE_VALUE (p) = NULL_TREE;
1.1       root      151:          p = TREE_PURPOSE (p);
1.1.1.4   root      152:          my_friendly_assert (TREE_CODE (p) == IDENTIFIER_NODE, 261);
1.1       root      153:          TEMPLATE_TYPE_SET_INFO (t, saved_parmlist, nparms);
                    154:        }
                    155:       else
                    156:        {
1.1.1.6 ! root      157:          tree tinfo = DECL_INITIAL (p);
        !           158:          DECL_INITIAL (p) = NULL_TREE;
1.1       root      159:          TEMPLATE_CONST_SET_INFO (tinfo, saved_parmlist, nparms);
                    160:        }
                    161:       TREE_VEC_ELT (saved_parmlist, nparms) = p;
                    162:     }
                    163:   set_current_level_tags_transparency (1);
                    164:   processing_template_decl++;
                    165:   return saved_parmlist;
                    166: }
                    167: 
                    168: /* end_template_decl is called after a template declaration is seen.
                    169:    D1 is template header; D2 is class_head_sans_basetype or a
                    170:    TEMPLATE_DECL with its DECL_RESULT field set.  */
                    171: void
                    172: end_template_decl (d1, d2, is_class)
                    173:      tree d1, d2, is_class;
                    174: {
                    175:   tree decl;
                    176:   struct template_info *tmpl;
                    177: 
                    178:   tmpl = (struct template_info *) obstack_alloc (&permanent_obstack,
                    179:                                            sizeof (struct template_info));
                    180:   tmpl->text = 0;
                    181:   tmpl->length = 0;
                    182:   tmpl->aggr = is_class;
                    183: 
                    184:   /* cloned from reinit_parse_for_template */
                    185:   tmpl->filename = input_filename;
                    186:   tmpl->lineno = lineno;
                    187:   tmpl->parm_vec = d1;          /* [eichin:19911015.2306EST] */
                    188: 
                    189:   if (d2 == NULL_TREE || d2 == error_mark_node)
                    190:     {
                    191:       decl = 0;
                    192:       goto lose;
                    193:     }
                    194: 
                    195:   if (is_class)
                    196:     {
                    197:       decl = build_lang_decl (TEMPLATE_DECL, d2, NULL_TREE);
                    198:     }
                    199:   else
                    200:     {
                    201:       if (TREE_CODE (d2) == TEMPLATE_DECL)
                    202:        decl = d2;
                    203:       else
                    204:        {
                    205:          /* Class destructor templates and operator templates are
                    206:             slipping past as non-template nodes.  Process them here, since
                    207:             I haven't figured out where to catch them earlier.  I could
                    208:             go do that, but it's a choice between getting that done and
                    209:             staying only N months behind schedule.  Sorry....  */
                    210:          enum tree_code code;
1.1.1.4   root      211:          my_friendly_assert (TREE_CODE (d2) == CALL_EXPR, 263);
1.1       root      212:          code = TREE_CODE (TREE_OPERAND (d2, 0));
1.1.1.4   root      213:          my_friendly_assert (code == BIT_NOT_EXPR
1.1       root      214:                  || code == OP_IDENTIFIER
1.1.1.4   root      215:                  || code == SCOPE_REF, 264);
1.1       root      216:          d2 = grokdeclarator (d2, NULL_TREE, MEMFUNCDEF, 0, NULL_TREE);
                    217:          decl = build_lang_decl (TEMPLATE_DECL, DECL_NAME (d2),
                    218:                                  TREE_TYPE (d2));
                    219:          DECL_TEMPLATE_RESULT (decl) = d2;
                    220:          DECL_CONTEXT (decl) = DECL_CONTEXT (d2);
                    221:          DECL_CLASS_CONTEXT (decl) = DECL_CLASS_CONTEXT (d2);
                    222:          DECL_NAME (decl) = DECL_NAME (d2);
                    223:          TREE_TYPE (decl) = TREE_TYPE (d2);
1.1.1.6 ! root      224:          if (interface_unknown && flag_external_templates)
        !           225:            warn_if_unknown_interface ();
        !           226:          TREE_PUBLIC (decl) = TREE_PUBLIC (d2) = flag_external_templates && !interface_unknown;
1.1.1.4   root      227:          DECL_EXTERNAL (decl) = (DECL_EXTERNAL (d2)
1.1       root      228:                                  && !(DECL_CLASS_CONTEXT (d2)
1.1.1.4   root      229:                                       && !DECL_THIS_EXTERN (d2)));
1.1       root      230:        }
                    231: 
                    232:       /* All routines creating TEMPLATE_DECL nodes should now be using
                    233:         build_lang_decl, which will have set this up already.  */
1.1.1.4   root      234:       my_friendly_assert (DECL_LANG_SPECIFIC (decl) != 0, 265);
1.1       root      235: 
                    236:       /* @@ Somewhere, permanent allocation isn't being used.  */
                    237:       if (! DECL_TEMPLATE_IS_CLASS (decl)
                    238:          && TREE_CODE (DECL_TEMPLATE_RESULT (decl)) == FUNCTION_DECL)
                    239:        {
                    240:          tree result = DECL_TEMPLATE_RESULT (decl);
                    241:          /* Will do nothing if allocation was already permanent.  */
                    242:          DECL_ARGUMENTS (result) = copy_to_permanent (DECL_ARGUMENTS (result));
                    243:        }
                    244: 
                    245:       /* If this is for a method, there's an extra binding level here. */
                    246:       if (! DECL_TEMPLATE_IS_CLASS (decl)
                    247:          && DECL_CONTEXT (DECL_TEMPLATE_RESULT (decl)) != NULL_TREE)
                    248:        {
                    249:          /* @@ Find out where this should be getting set!  */
                    250:          tree r = DECL_TEMPLATE_RESULT (decl);
                    251:          if (DECL_CLASS_CONTEXT (r) == NULL_TREE)
                    252:            DECL_CLASS_CONTEXT (r) = DECL_CONTEXT (r);
                    253:        }
                    254:     }
                    255:   DECL_TEMPLATE_INFO (decl) = tmpl;
                    256:   DECL_TEMPLATE_PARMS (decl) = d1;
                    257: lose:
                    258:   if (decl)
                    259:     {
                    260:       /* If context of decl is non-null (i.e., method template), add it
                    261:         to the appropriate class template, and pop the binding levels.  */
                    262:       if (! DECL_TEMPLATE_IS_CLASS (decl)
                    263:          && DECL_CONTEXT (DECL_TEMPLATE_RESULT (decl)) != NULL_TREE)
                    264:        {
                    265:          tree ctx = DECL_CONTEXT (DECL_TEMPLATE_RESULT (decl));
                    266:          tree tmpl;
1.1.1.4   root      267:          my_friendly_assert (TREE_CODE (ctx) == UNINSTANTIATED_P_TYPE, 266);
1.1       root      268:          tmpl = UPT_TEMPLATE (ctx);
                    269:          DECL_TEMPLATE_MEMBERS (tmpl) =
                    270:            perm_tree_cons (DECL_NAME (decl), decl,
                    271:                            DECL_TEMPLATE_MEMBERS (tmpl));
                    272:          poplevel (0, 0, 0);
                    273:          poplevel (0, 0, 0);
                    274:        }
                    275:       /* Otherwise, go back to top level first, and push the template decl
                    276:         again there.  */
                    277:       else
                    278:        {
                    279:          poplevel (0, 0, 0);
                    280:          poplevel (0, 0, 0);
                    281:          if (TREE_TYPE (decl)
                    282:              && IDENTIFIER_GLOBAL_VALUE (DECL_NAME (decl)) != NULL_TREE)
                    283:            push_overloaded_decl (decl, 0);
                    284:          else
                    285:            pushdecl (decl);
                    286:        }
                    287:     }
                    288: #if 0 /* It happens sometimes, with syntactic or semantic errors.
                    289: 
                    290:         One specific case:
                    291:         template <class A, int X, int Y> class Foo { ... };
                    292:         template <class A, int X, int y> Foo<X,Y>::method (Foo& x) { ... }
                    293:         Note the missing "A" in the class containing "method".  */
1.1.1.4   root      294:   my_friendly_assert (global_bindings_p (), 267);
1.1       root      295: #else
                    296:   while (! global_bindings_p ())
                    297:     poplevel (0, 0, 0);
                    298: #endif
                    299:   pop_obstacks ();
                    300:   processing_template_decl--;
                    301:   (void) get_pending_sizes ();
                    302: }
                    303: 
1.1.1.6 ! root      304: /* If TYPE is a template parm type, then return its actual type found
        !           305:    in TVEC. Otherwise, return TYPE.  */
        !           306: static tree
        !           307: grok_template_type (tvec, type)
        !           308:      tree tvec, type;
        !           309: {
        !           310:   if (TREE_CODE (type) == TEMPLATE_TYPE_PARM)
        !           311:     return TREE_VEC_ELT (tvec, TEMPLATE_TYPE_IDX (type));
        !           312:   else
        !           313:     return type;
        !           314: }
1.1       root      315: 
                    316: /* Convert all template arguments to their appropriate types, and return
                    317:    a vector containing the resulting values.  If any error occurs, return
                    318:    error_mark_node.  */
                    319: static tree
1.1.1.5   root      320: coerce_template_parms (parms, arglist, in_decl)
1.1       root      321:      tree parms, arglist;
1.1.1.5   root      322:      tree in_decl;
1.1       root      323: {
                    324:   int nparms, i, lost = 0;
                    325:   tree vec;
                    326: 
                    327:   if (TREE_CODE (arglist) == TREE_VEC)
                    328:     nparms = TREE_VEC_LENGTH (arglist);
                    329:   else
                    330:     nparms = list_length (arglist);
                    331:   if (nparms != TREE_VEC_LENGTH (parms))
                    332:     {
1.1.1.5   root      333:       error ("incorrect number of parameters (%d, should be %d)",
1.1       root      334:             nparms, TREE_VEC_LENGTH (parms));
1.1.1.5   root      335:       if (in_decl)
1.1.1.6 ! root      336:        cp_error_at ("in template expansion for decl `%D'", in_decl);
1.1       root      337:       return error_mark_node;
                    338:     }
                    339: 
                    340:   if (TREE_CODE (arglist) == TREE_VEC)
                    341:     vec = copy_node (arglist);
                    342:   else
                    343:     {
                    344:       vec = make_tree_vec (nparms);
                    345:       for (i = 0; i < nparms; i++)
                    346:        {
                    347:          tree arg = arglist;
                    348:          arglist = TREE_CHAIN (arglist);
                    349:          if (arg == error_mark_node)
                    350:            lost++;
                    351:          else
                    352:            arg = TREE_VALUE (arg);
                    353:          TREE_VEC_ELT (vec, i) = arg;
                    354:        }
                    355:     }
                    356:   for (i = 0; i < nparms; i++)
                    357:     {
                    358:       tree arg = TREE_VEC_ELT (vec, i);
                    359:       tree parm = TREE_VEC_ELT (parms, i);
1.1.1.6 ! root      360:       tree val = 0;
1.1       root      361:       int is_type, requires_type;
                    362: 
                    363:       is_type = TREE_CODE_CLASS (TREE_CODE (arg)) == 't';
                    364:       requires_type = TREE_CODE (parm) == IDENTIFIER_NODE;
                    365:       if (is_type != requires_type)
                    366:        {
1.1.1.5   root      367:          if (in_decl)
1.1.1.6 ! root      368:            cp_error_at ("type/value mismatch in template parameter list for `%D'", in_decl);
1.1       root      369:          lost++;
                    370:          TREE_VEC_ELT (vec, i) = error_mark_node;
                    371:          continue;
                    372:        }
                    373:       if (is_type)
1.1.1.5   root      374:        val = groktypename (arg);
1.1.1.6 ! root      375:       else if (TREE_CODE (arg) == STRING_CST)
        !           376:        {
        !           377:          cp_error ("string literal %E is not a valid template argument", arg);
        !           378:          error ("because it is the address of an object with static linkage");
        !           379:          val = error_mark_node;
        !           380:        }
1.1       root      381:       else
1.1.1.6 ! root      382:        {
        !           383:          TREE_TYPE (parm) = grok_template_type (vec, TREE_TYPE (parm));
        !           384:          val = digest_init (TREE_TYPE (parm), arg, (tree *) 0);
        !           385:          
        !           386:          if (val == error_mark_node)
        !           387:            ;
        !           388: 
        !           389:          /* 14.2: Other template-arguments must be constant-expressions,
        !           390:             addresses of objects or functions with external linkage, or of
        !           391:             static class members.  */
        !           392:          else if (!TREE_CONSTANT (val))
        !           393:            {
        !           394:              cp_error ("non-const `%E' cannot be used as template argument",
        !           395:                        arg);
        !           396:              val = error_mark_node;
        !           397:            }
        !           398:          else if (TREE_CODE (val) == ADDR_EXPR)
        !           399:            {
        !           400:              tree a = TREE_OPERAND (val, 0);
        !           401:              if ((TREE_CODE (a) == VAR_DECL
        !           402:                   || TREE_CODE (a) == FUNCTION_DECL)
        !           403:                  && !TREE_PUBLIC (a))
        !           404:                {
        !           405:                  cp_error ("address of non-extern `%E' cannot be used as template argument", a);
        !           406:                  val = error_mark_node;
        !           407:                }
        !           408:            }
        !           409:        }
1.1.1.5   root      410: 
1.1       root      411:       if (val == error_mark_node)
                    412:        lost++;
1.1.1.5   root      413: 
1.1       root      414:       TREE_VEC_ELT (vec, i) = val;
                    415:     }
                    416:   if (lost)
                    417:     return error_mark_node;
                    418:   return vec;
                    419: }
                    420: 
                    421: /* Given class template name and parameter list, produce a user-friendly name
1.1.1.6 ! root      422:    for the instantiation.  */
1.1       root      423: static char *
                    424: mangle_class_name_for_template (name, parms, arglist)
                    425:      char *name;
                    426:      tree parms, arglist;
                    427: {
                    428:   static struct obstack scratch_obstack;
                    429:   static char *scratch_firstobj;
                    430:   int i, nparms;
                    431:   char ibuf[100];
                    432: 
                    433:   if (!scratch_firstobj)
                    434:     {
                    435:       gcc_obstack_init (&scratch_obstack);
                    436:       scratch_firstobj = obstack_alloc (&scratch_obstack, 1);
                    437:     }
                    438:   else
                    439:     obstack_free (&scratch_obstack, scratch_firstobj);
                    440: 
                    441: #if 0
                    442: #define buflen sizeof(buf)
                    443: #define check  if (bufp >= buf+buflen-1) goto too_long
                    444: #define ccat(c) *bufp++=(c); check
                    445: #define advance        bufp+=strlen(bufp); check
                    446: #define cat(s) strncpy(bufp, s, buf+buflen-bufp-1); advance
                    447: #else
                    448: #define check
                    449: #define ccat(c)        obstack_1grow (&scratch_obstack, (c));
                    450: #define advance
                    451: #define cat(s) obstack_grow (&scratch_obstack, (s), strlen (s))
                    452: #endif
                    453: #define icat(n)        sprintf(ibuf,"%d",(n)); cat(ibuf)
                    454: #define xcat(n)        sprintf(ibuf,"%ux",n); cat(ibuf)
                    455: 
                    456:   cat (name);
                    457:   ccat ('<');
                    458:   nparms = TREE_VEC_LENGTH (parms);
1.1.1.4   root      459:   my_friendly_assert (nparms == TREE_VEC_LENGTH (arglist), 268);
1.1       root      460:   for (i = 0; i < nparms; i++)
                    461:     {
                    462:       tree parm = TREE_VEC_ELT (parms, i), arg = TREE_VEC_ELT (arglist, i);
                    463: 
                    464:       if (i)
                    465:        ccat (',');
                    466: 
                    467:       if (TREE_CODE (parm) == IDENTIFIER_NODE)
                    468:        {
1.1.1.6 ! root      469:          cat (type_as_string (arg, 0));
1.1       root      470:          continue;
                    471:        }
                    472:       else
1.1.1.4   root      473:        my_friendly_assert (TREE_CODE (parm) == PARM_DECL, 269);
1.1       root      474: 
                    475:       if (TREE_CODE (arg) == TREE_LIST)
                    476:        {
                    477:          /* New list cell was built because old chain link was in
                    478:             use.  */
1.1.1.4   root      479:          my_friendly_assert (TREE_PURPOSE (arg) == NULL_TREE, 270);
1.1       root      480:          arg = TREE_VALUE (arg);
                    481:        }
1.1.1.6 ! root      482:       /* No need to check arglist against parmlist here; we did that
        !           483:         in coerce_template_parms, called from lookup_template_class.  */
        !           484:       cat (expr_as_string (arg, 0));
1.1       root      485:     }
                    486:   {
                    487:     char *bufp = obstack_next_free (&scratch_obstack);
                    488:     int offset = 0;
                    489:     while (bufp[offset - 1] == ' ')
                    490:       offset--;
                    491:     obstack_blank_fast (&scratch_obstack, offset);
1.1.1.6 ! root      492: 
        !           493:     /* B<C<char> >, not B<C<char>> */
        !           494:     if (bufp[offset - 1] == '>')
        !           495:       ccat (' ');
1.1       root      496:   }
                    497:   ccat ('>');
                    498:   ccat ('\0');
                    499:   return (char *) obstack_base (&scratch_obstack);
                    500: 
                    501:  too_long:
                    502:   fatal ("out of (preallocated) string space creating template instantiation name");
                    503:   /* NOTREACHED */
                    504:   return NULL;
                    505: }
                    506: 
                    507: /* Given an IDENTIFIER_NODE (type TEMPLATE_DECL) and a chain of
                    508:    parameters, find the desired type.
                    509: 
                    510:    D1 is the PTYPENAME terminal, and ARGLIST is the list of arguments.
                    511:    Since ARGLIST is build on the decl_obstack, we must copy it here
1.1.1.5   root      512:    to keep it from being reclaimed when the decl storage is reclaimed.
                    513: 
                    514:    IN_DECL, if non-NULL, is the template declaration we are trying to
                    515:    instantiate.  */
1.1       root      516: tree
1.1.1.5   root      517: lookup_template_class (d1, arglist, in_decl)
1.1       root      518:      tree d1, arglist;
1.1.1.5   root      519:      tree in_decl;
1.1       root      520: {
                    521:   tree template, parmlist;
                    522:   char *mangled_name;
                    523:   tree id;
                    524: 
1.1.1.4   root      525:   my_friendly_assert (TREE_CODE (d1) == IDENTIFIER_NODE, 272);
1.1       root      526:   template = IDENTIFIER_GLOBAL_VALUE (d1); /* XXX */
1.1.1.5   root      527:   if (! template)
                    528:     template = IDENTIFIER_CLASS_VALUE (d1);
                    529:   /* With something like `template <class T> class X class X { ... };'
                    530:      we could end up with D1 having nothing but an IDENTIFIER_LOCAL_VALUE.
                    531:      We don't want to do that, but we have to deal with the situation, so
                    532:      let's give them some syntax errors to chew on instead of a crash.  */
                    533:   if (! template)
                    534:     return error_mark_node;
1.1.1.4   root      535:   if (TREE_CODE (template) != TEMPLATE_DECL)
                    536:     {
1.1.1.6 ! root      537:       cp_error ("non-template type `%T' used as a template", d1);
1.1.1.5   root      538:       if (in_decl)
1.1.1.6 ! root      539:        cp_error_at ("for template declaration `%D'", in_decl);
1.1.1.4   root      540:       return error_mark_node;
                    541:     }
1.1       root      542:   parmlist = DECL_TEMPLATE_PARMS (template);
                    543: 
1.1.1.5   root      544:   arglist = coerce_template_parms (parmlist, arglist, in_decl);
1.1       root      545:   if (arglist == error_mark_node)
                    546:     return error_mark_node;
                    547:   if (uses_template_parms (arglist))
                    548:     {
                    549:       tree t = make_lang_type (UNINSTANTIATED_P_TYPE);
                    550:       tree d;
                    551:       id = make_anon_name ();
                    552:       d = build_lang_decl (TYPE_DECL, id, t);
                    553:       TYPE_NAME (t) = d;
                    554:       TYPE_VALUES (t) = build_tree_list (template, arglist);
                    555:       pushdecl_top_level (d);
                    556:     }
                    557:   else
                    558:     {
                    559:       mangled_name = mangle_class_name_for_template (IDENTIFIER_POINTER (d1),
                    560:                                                     parmlist, arglist);
                    561:       id = get_identifier (mangled_name);
                    562:     }
                    563:   if (!IDENTIFIER_TEMPLATE (id))
                    564:     {
                    565:       arglist = copy_to_permanent (arglist);
                    566:       IDENTIFIER_TEMPLATE (id) = perm_tree_cons (template, arglist, NULL_TREE);
                    567:     }
                    568:   return id;
                    569: }
                    570: 
                    571: void
                    572: push_template_decls (parmlist, arglist, class_level)
                    573:      tree parmlist, arglist;
                    574:      int class_level;
                    575: {
                    576:   int i, nparms;
                    577: 
                    578:   /* Don't want to push values into global context.  */
                    579:   if (!class_level)
                    580:     pushlevel (0);
                    581:   nparms = TREE_VEC_LENGTH (parmlist);
                    582: 
                    583:   for (i = 0; i < nparms; i++)
                    584:     {
                    585:       int requires_type, is_type;
                    586:       tree parm = TREE_VEC_ELT (parmlist, i);
                    587:       tree arg = TREE_VEC_ELT (arglist, i);
                    588:       tree decl = 0;
                    589: 
                    590:       requires_type = TREE_CODE (parm) == IDENTIFIER_NODE;
                    591:       is_type = TREE_CODE_CLASS (TREE_CODE (arg)) == 't';
                    592:       if (is_type)
                    593:        {
                    594:          /* add typename to namespace */
                    595:          if (!requires_type)
                    596:            {
                    597:              error ("template use error: type provided where value needed");
                    598:              continue;
                    599:            }
                    600:          decl = arg;
1.1.1.4   root      601:          my_friendly_assert (TREE_CODE_CLASS (TREE_CODE (decl)) == 't', 273);
1.1       root      602:          decl = build_lang_decl (TYPE_DECL, parm, decl);
                    603:        }
                    604:       else
                    605:        {
                    606:          /* add const decl to namespace */
                    607:          tree val;
                    608:          if (requires_type)
                    609:            {
                    610:              error ("template use error: value provided where type needed");
                    611:              continue;
                    612:            }
                    613:          val = digest_init (TREE_TYPE (parm), arg, (tree *) 0);
                    614:          if (val != error_mark_node)
                    615:            {
                    616:              decl = build_decl (VAR_DECL, DECL_NAME (parm), TREE_TYPE (parm));
                    617:              DECL_INITIAL (decl) = val;
                    618:              TREE_READONLY (decl) = 1;
                    619:            }
                    620:        }
                    621:       if (decl != 0)
                    622:        {
                    623:          layout_decl (decl, 0);
                    624:          if (class_level)
                    625:            pushdecl_class_level (decl);
                    626:          else
                    627:            pushdecl (decl);
                    628:        }
                    629:     }
                    630:   if (!class_level)
                    631:     set_current_level_tags_transparency (1);
                    632: }
                    633: 
                    634: void
                    635: pop_template_decls (parmlist, arglist, class_level)
                    636:      tree parmlist, arglist;
                    637:      int class_level;
                    638: {
                    639:   if (!class_level)
                    640:     poplevel (0, 0, 0);
                    641: }
                    642: 
                    643: /* Should be defined in cp-parse.h.  */
                    644: extern int yychar;
                    645: 
                    646: int
                    647: uses_template_parms (t)
                    648:      tree t;
                    649: {
                    650:   if (!t)
                    651:     return 0;
                    652:   switch (TREE_CODE (t))
                    653:     {
                    654:     case INDIRECT_REF:
                    655:     case COMPONENT_REF:
                    656:       /* We assume that the object must be instantiated in order to build
                    657:         the COMPONENT_REF, so we test only whether the type of the
                    658:         COMPONENT_REF uses template parms.  */
                    659:       return uses_template_parms (TREE_TYPE (t));
                    660: 
                    661:     case IDENTIFIER_NODE:
                    662:       if (!IDENTIFIER_TEMPLATE (t))
                    663:        return 0;
                    664:       return uses_template_parms (TREE_VALUE (IDENTIFIER_TEMPLATE (t)));
                    665: 
                    666:       /* aggregates of tree nodes */
                    667:     case TREE_VEC:
                    668:       {
                    669:        int i = TREE_VEC_LENGTH (t);
                    670:        while (i--)
                    671:          if (uses_template_parms (TREE_VEC_ELT (t, i)))
                    672:            return 1;
                    673:        return 0;
                    674:       }
                    675:     case TREE_LIST:
                    676:       if (uses_template_parms (TREE_PURPOSE (t))
                    677:          || uses_template_parms (TREE_VALUE (t)))
                    678:        return 1;
                    679:       return uses_template_parms (TREE_CHAIN (t));
                    680: 
                    681:       /* constructed type nodes */
                    682:     case POINTER_TYPE:
                    683:     case REFERENCE_TYPE:
                    684:       return uses_template_parms (TREE_TYPE (t));
                    685:     case RECORD_TYPE:
                    686:     case UNION_TYPE:
                    687:       if (!TYPE_NAME (t))
                    688:        return 0;
1.1.1.3   root      689:       if (!TYPE_IDENTIFIER (t))
1.1       root      690:        return 0;
1.1.1.3   root      691:       return uses_template_parms (TYPE_IDENTIFIER (t));
1.1       root      692:     case FUNCTION_TYPE:
                    693:       if (uses_template_parms (TYPE_ARG_TYPES (t)))
                    694:        return 1;
                    695:       return uses_template_parms (TREE_TYPE (t));
                    696:     case ARRAY_TYPE:
                    697:       if (uses_template_parms (TYPE_DOMAIN (t)))
                    698:        return 1;
                    699:       return uses_template_parms (TREE_TYPE (t));
                    700:     case OFFSET_TYPE:
                    701:       if (uses_template_parms (TYPE_OFFSET_BASETYPE (t)))
                    702:        return 1;
                    703:       return uses_template_parms (TREE_TYPE (t));
                    704:     case METHOD_TYPE:
                    705:       if (uses_template_parms (TYPE_OFFSET_BASETYPE (t)))
                    706:        return 1;
                    707:       if (uses_template_parms (TYPE_ARG_TYPES (t)))
                    708:        return 1;
                    709:       return uses_template_parms (TREE_TYPE (t));
                    710: 
                    711:       /* decl nodes */
                    712:     case TYPE_DECL:
                    713:       return uses_template_parms (DECL_NAME (t));
                    714:     case FUNCTION_DECL:
                    715:       if (uses_template_parms (TREE_TYPE (t)))
                    716:        return 1;
                    717:       /* fall through */
                    718:     case VAR_DECL:
                    719:     case PARM_DECL:
                    720:       /* ??? What about FIELD_DECLs?  */
                    721:       /* The type of a decl can't use template parms if the name of the
                    722:         variable doesn't, because it's impossible to resolve them.  So
                    723:         ignore the type field for now.  */
                    724:       if (DECL_CONTEXT (t) && uses_template_parms (DECL_CONTEXT (t)))
                    725:        return 1;
                    726:       if (uses_template_parms (TREE_TYPE (t)))
                    727:        {
                    728:          error ("template parms used where they can't be resolved");
                    729:        }
                    730:       return 0;
                    731: 
                    732:     case CALL_EXPR:
                    733:       return uses_template_parms (TREE_TYPE (t));
                    734:     case ADDR_EXPR:
                    735:       return uses_template_parms (TREE_OPERAND (t, 0));
                    736: 
                    737:       /* template parm nodes */
                    738:     case TEMPLATE_TYPE_PARM:
                    739:     case TEMPLATE_CONST_PARM:
                    740:       return 1;
                    741: 
                    742:       /* simple type nodes */
                    743:     case INTEGER_TYPE:
                    744:       if (uses_template_parms (TYPE_MIN_VALUE (t)))
                    745:        return 1;
                    746:       return uses_template_parms (TYPE_MAX_VALUE (t));
                    747: 
                    748:     case REAL_TYPE:
                    749:     case VOID_TYPE:
                    750:     case ENUMERAL_TYPE:
                    751:       return 0;
                    752: 
                    753:       /* constants */
                    754:     case INTEGER_CST:
                    755:     case REAL_CST:
                    756:     case STRING_CST:
                    757:       return 0;
                    758: 
                    759:     case ERROR_MARK:
                    760:       /* Non-error_mark_node ERROR_MARKs are bad things.  */
1.1.1.4   root      761:       my_friendly_assert (t == error_mark_node, 274);
1.1       root      762:       /* NOTREACHED */
                    763:       return 0;
                    764: 
                    765:     case UNINSTANTIATED_P_TYPE:
                    766:       return 1;
                    767: 
                    768:     default:
                    769:       switch (TREE_CODE_CLASS (TREE_CODE (t)))
                    770:        {
                    771:        case '1':
                    772:        case '2':
                    773:        case '3':
                    774:        case '<':
                    775:          {
                    776:            int i;
                    777:            for (i = tree_code_length[(int) TREE_CODE (t)]; --i >= 0;)
                    778:              if (uses_template_parms (TREE_OPERAND (t, i)))
                    779:                return 1;
                    780:            return 0;
                    781:          }
                    782:        default:
                    783:          break;
                    784:        }
                    785:       sorry ("testing %s for template parms",
                    786:             tree_code_name [(int) TREE_CODE (t)]);
1.1.1.3   root      787:       my_friendly_abort (82);
1.1       root      788:       /* NOTREACHED */
                    789:       return 0;
                    790:     }
                    791: }
                    792: 
                    793: void
                    794: instantiate_member_templates (arg)
                    795:      tree arg;
                    796: {
                    797:   tree t;
                    798:   tree classname = TREE_VALUE (arg);
                    799:   tree id = classname;
                    800:   tree members = DECL_TEMPLATE_MEMBERS (TREE_PURPOSE (IDENTIFIER_TEMPLATE (id)));
                    801: 
                    802:   for (t = members; t; t = TREE_CHAIN (t))
                    803:     {
                    804:       tree parmvec, type, classparms, tdecl, t2;
1.1.1.6 ! root      805:       int nparms, xxx = 0, i;
1.1       root      806: 
1.1.1.4   root      807:       my_friendly_assert (TREE_VALUE (t) != NULL_TREE, 275);
                    808:       my_friendly_assert (TREE_CODE (TREE_VALUE (t)) == TEMPLATE_DECL, 276);
1.1       root      809:       /* @@ Should verify that class parm list is a list of
                    810:         distinct template parameters, and covers all the template
                    811:         parameters.  */
                    812:       tdecl = TREE_VALUE (t);
                    813:       type = DECL_CONTEXT (DECL_TEMPLATE_RESULT (tdecl));
                    814:       classparms = UPT_PARMS (type);
                    815:       nparms = TREE_VEC_LENGTH (classparms);
                    816:       parmvec = make_tree_vec (nparms);
                    817:       for (i = 0; i < nparms; i++)
                    818:        TREE_VEC_ELT (parmvec, i) = NULL_TREE;
                    819:       switch (unify (DECL_TEMPLATE_PARMS (tdecl),
                    820:                     &TREE_VEC_ELT (parmvec, 0), nparms,
                    821:                     type, IDENTIFIER_TYPE_VALUE (classname),
                    822:                     &xxx))
                    823:        {
                    824:        case 0:
                    825:          /* Success -- well, no inconsistency, at least.  */
                    826:          for (i = 0; i < nparms; i++)
                    827:            if (TREE_VEC_ELT (parmvec, i) == NULL_TREE)
                    828:              goto failure;
                    829:          t2 = instantiate_template (tdecl,
                    830:                                     &TREE_VEC_ELT (parmvec, 0));
                    831:          type = IDENTIFIER_TYPE_VALUE (id);
1.1.1.4   root      832:          my_friendly_assert (type != 0, 277);
1.1       root      833:          if (CLASSTYPE_INTERFACE_UNKNOWN (type))
                    834:            {
1.1.1.4   root      835:              DECL_EXTERNAL (t2) = 0;
1.1       root      836:              TREE_PUBLIC (t2) = 0;
                    837:            }
                    838:          else
                    839:            {
1.1.1.4   root      840:              DECL_EXTERNAL (t2) = CLASSTYPE_INTERFACE_ONLY (type);
1.1.1.3   root      841:              TREE_PUBLIC (t2) = 1;
1.1       root      842:            }
                    843:          break;
                    844:        case 1:
                    845:          /* Failure.  */
                    846:        failure:
1.1.1.6 ! root      847:          cp_error ("type unification error instantiating %T::%D",
        !           848:                      classname, tdecl);
        !           849:          cp_error_at ("for template declaration `%D'", tdecl);
1.1.1.5   root      850: 
1.1       root      851:          continue /* loop of members */;
                    852:        default:
                    853:          /* Eek, a bug.  */
1.1.1.3   root      854:          my_friendly_abort (83);
1.1       root      855:        }
                    856:     }
                    857: }
                    858: 
1.1.1.6 ! root      859: struct tinst_level *current_tinst_level = 0;
        !           860: struct tinst_level *free_tinst_level = 0;
        !           861: 
        !           862: void
        !           863: push_tinst_level (name)
        !           864:      tree name;
        !           865: {
        !           866:   struct tinst_level *new;
        !           867:   tree global = IDENTIFIER_GLOBAL_VALUE (name);
        !           868: 
        !           869:   if (free_tinst_level)
        !           870:     {
        !           871:       new = free_tinst_level;
        !           872:       free_tinst_level = new->next;
        !           873:     }
        !           874:   else
        !           875:     new = (struct tinst_level *) xmalloc (sizeof (struct tinst_level));
        !           876: 
        !           877:   new->classname = name;
        !           878:   if (global)
        !           879:     {
        !           880:       new->line = DECL_SOURCE_LINE (global);
        !           881:       new->file = DECL_SOURCE_FILE (global);
        !           882:     }
        !           883:   else
        !           884:     {
        !           885:       new->line = lineno;
        !           886:       new->file = input_filename;
        !           887:     }
        !           888:   new->next = current_tinst_level;
        !           889:   current_tinst_level = new;
        !           890: }
        !           891: 
        !           892: void
        !           893: pop_tinst_level ()
        !           894: {
        !           895:   struct tinst_level *old = current_tinst_level;
        !           896: 
        !           897:   current_tinst_level = old->next;
        !           898:   old->next = free_tinst_level;
        !           899:   free_tinst_level = old;
        !           900: }
        !           901: 
        !           902: struct tinst_level *
        !           903: tinst_for_decl ()
        !           904: {
        !           905:   struct tinst_level *p = current_tinst_level;
        !           906: 
        !           907:   if (p)
        !           908:     for (; p->next ; p = p->next )
        !           909:       ;
        !           910:   return p;
        !           911: }
        !           912: 
1.1       root      913: tree
                    914: instantiate_class_template (classname, setup_parse)
                    915:      tree classname;
                    916:      int setup_parse;
                    917: {
                    918:   struct template_info *template_info;
                    919:   tree template, t1;
                    920: 
                    921:   if (classname == error_mark_node)
                    922:     return error_mark_node;
                    923: 
1.1.1.4   root      924:   my_friendly_assert (TREE_CODE (classname) == IDENTIFIER_NODE, 278);
1.1       root      925:   template = IDENTIFIER_TEMPLATE (classname);
                    926: 
                    927:   if (IDENTIFIER_HAS_TYPE_VALUE (classname))
                    928:     {
                    929:       tree type = IDENTIFIER_TYPE_VALUE (classname);
                    930:       if (TREE_CODE (type) == UNINSTANTIATED_P_TYPE)
                    931:        return type;
                    932:       if (TYPE_BEING_DEFINED (type)
                    933:          || TYPE_SIZE (type)
                    934:          || CLASSTYPE_USE_TEMPLATE (type) != 0)
                    935:        return type;
                    936:     }
1.1.1.6 ! root      937: 
        !           938:   /* If IDENTIFIER_LOCAL_VALUE is already set on this template classname
        !           939:      (it's something like `foo<int>'), that means we're already working on
        !           940:      the instantiation for it.  Normally, a classname comes in with nothing
        !           941:      but its IDENTIFIER_TEMPLATE slot set.  If we were to try to instantiate
        !           942:      this again, we'd get a redeclaration error.  Since we're already working
        !           943:      on it, we'll pass back this classname's TYPE_DECL (it's the value of
        !           944:      the classname's IDENTIFIER_LOCAL_VALUE).  Only do this if we're setting
        !           945:      things up for the parser, though---if we're just trying to instantiate
        !           946:      it (e.g., via tsubst) we can trip up cuz it may not have an
        !           947:      IDENTIFIER_TYPE_VALUE when it will need one.  */
        !           948:   if (setup_parse && IDENTIFIER_LOCAL_VALUE (classname))
        !           949:     return IDENTIFIER_LOCAL_VALUE (classname);
        !           950: 
1.1       root      951:   if (uses_template_parms (classname))
                    952:     {
                    953:       if (!TREE_TYPE (classname))
                    954:        {
                    955:          tree t = make_lang_type (RECORD_TYPE);
                    956:          tree d = build_lang_decl (TYPE_DECL, classname, t);
                    957:          DECL_NAME (d) = classname;
                    958:          TYPE_NAME (t) = d;
                    959:          pushdecl (d);
                    960:        }
                    961:       return NULL_TREE;
                    962:     }
                    963: 
                    964:   t1 = TREE_PURPOSE (template);
1.1.1.4   root      965:   my_friendly_assert (TREE_CODE (t1) == TEMPLATE_DECL, 279);
1.1       root      966: 
1.1.1.2   root      967:   /* If a template is declared but not defined, accept it; don't crash.
                    968:      Later uses requiring the definition will be flagged as errors by
                    969:      other code.  Thanks to [email protected] for this bug fix.  */
1.1       root      970:   if (DECL_TEMPLATE_INFO (t1)->text == 0)
1.1.1.2   root      971:     setup_parse = 0;
1.1       root      972: 
1.1.1.2   root      973:   push_to_top_level ();
                    974:   template_info = DECL_TEMPLATE_INFO (t1);
1.1       root      975:   if (setup_parse)
                    976:     {
1.1.1.6 ! root      977:       push_tinst_level (classname);
        !           978:       push_template_decls (DECL_TEMPLATE_PARMS (TREE_PURPOSE (template)),
        !           979:                           TREE_VALUE (template), 0);
        !           980:       set_current_level_tags_transparency (1);
1.1       root      981:       feed_input (template_info->text, template_info->length, (struct obstack *)0);
                    982:       lineno = template_info->lineno;
                    983:       input_filename = template_info->filename;
                    984:       /* Get interface/implementation back in sync.  */
                    985:       extract_interface_info ();
                    986:       overload_template_name (classname, 0);
                    987:       yychar = PRE_PARSED_CLASS_DECL;
                    988:       yylval.ttype = build_tree_list (class_type_node, classname);
                    989:       processing_template_defn++;
1.1.1.6 ! root      990:       if (!flag_external_templates)
        !           991:        interface_unknown++;
1.1       root      992:     }
                    993:   else
                    994:     {
                    995:       tree t, decl, id, tmpl;
                    996: 
                    997:       id = classname;
                    998:       tmpl = TREE_PURPOSE (IDENTIFIER_TEMPLATE (id));
                    999:       t = xref_tag (DECL_TEMPLATE_INFO (tmpl)->aggr, id, NULL_TREE);
1.1.1.6 ! root     1000:       my_friendly_assert (TREE_CODE (t) == RECORD_TYPE
        !          1001:                          || TREE_CODE (t) == UNION_TYPE, 280);
1.1       root     1002: 
                   1003:       /* Now, put a copy of the decl in global scope, to avoid
                   1004:        * recursive expansion.  */
                   1005:       decl = IDENTIFIER_LOCAL_VALUE (id);
                   1006:       if (!decl)
                   1007:        decl = IDENTIFIER_CLASS_VALUE (id);
                   1008:       if (decl)
                   1009:        {
1.1.1.4   root     1010:          my_friendly_assert (TREE_CODE (decl) == TYPE_DECL, 281);
                   1011:          /* We'd better make sure we're on the permanent obstack or else
                   1012:           * we'll get a "friendly" abort 124 in pushdecl.  Perhaps a
                   1013:           * copy_to_permanent would be sufficient here, but then a
                   1014:           * sharing problem might occur.  I don't know -- [email protected] */
                   1015:          push_obstacks (&permanent_obstack, &permanent_obstack);
1.1       root     1016:          pushdecl_top_level (copy_node (decl));
1.1.1.4   root     1017:          pop_obstacks ();
1.1       root     1018:        }
                   1019:       pop_from_top_level ();
                   1020:     }
                   1021: 
                   1022:   return NULL_TREE;
                   1023: }
                   1024: 
1.1.1.4   root     1025: static int
                   1026: list_eq (t1, t2)
                   1027:      tree t1, t2;
                   1028: {
                   1029:   if (t1 == NULL_TREE)
                   1030:     return t2 == NULL_TREE;
                   1031:   if (t2 == NULL_TREE)
                   1032:     return 0;
                   1033:   /* Don't care if one declares its arg const and the other doesn't -- the
                   1034:      main variant of the arg type is all that matters.  */
                   1035:   if (TYPE_MAIN_VARIANT (TREE_VALUE (t1))
                   1036:       != TYPE_MAIN_VARIANT (TREE_VALUE (t2)))
                   1037:     return 0;
                   1038:   return list_eq (TREE_CHAIN (t1), TREE_CHAIN (t2));
                   1039: }
                   1040: 
1.1       root     1041: static tree
1.1.1.5   root     1042: tsubst (t, args, nargs, in_decl)
1.1       root     1043:      tree t, *args;
1.1.1.5   root     1044:      int nargs;
                   1045:      tree in_decl;
1.1       root     1046: {
                   1047:   tree type;
1.1.1.5   root     1048: 
1.1.1.4   root     1049:   if (t == NULL_TREE || t == error_mark_node)
1.1       root     1050:     return t;
1.1.1.5   root     1051: 
1.1       root     1052:   type = TREE_TYPE (t);
                   1053:   if (type
1.1.1.4   root     1054:       /* Minor optimization.
                   1055:         ?? Are these really the most frequent cases?  Is the savings
                   1056:         significant?  */
1.1       root     1057:       && type != integer_type_node
                   1058:       && type != void_type_node
                   1059:       && type != char_type_node)
1.1.1.5   root     1060:     type = build_type_variant (tsubst (type, args, nargs, in_decl),
1.1       root     1061:                               TYPE_READONLY (type),
                   1062:                               TYPE_VOLATILE (type));
                   1063:   switch (TREE_CODE (t))
                   1064:     {
                   1065:     case ERROR_MARK:
                   1066:     case IDENTIFIER_NODE:
                   1067:     case OP_IDENTIFIER:
                   1068:     case VOID_TYPE:
                   1069:     case REAL_TYPE:
                   1070:     case ENUMERAL_TYPE:
                   1071:     case INTEGER_CST:
                   1072:     case REAL_CST:
                   1073:     case STRING_CST:
                   1074:     case RECORD_TYPE:
                   1075:     case UNION_TYPE:
                   1076:       return t;
                   1077: 
                   1078:     case INTEGER_TYPE:
                   1079:       if (t == integer_type_node)
                   1080:        return t;
                   1081: 
                   1082:       if (TREE_CODE (TYPE_MIN_VALUE (t)) == INTEGER_CST
                   1083:          && TREE_CODE (TYPE_MAX_VALUE (t)) == INTEGER_CST)
                   1084:        return t;
1.1.1.6 ! root     1085:       return build_index_2_type
        !          1086:        (tsubst (TYPE_MIN_VALUE (t), args, nargs, in_decl),
        !          1087:         tsubst (TYPE_MAX_VALUE (t), args, nargs, in_decl));
1.1       root     1088: 
                   1089:     case TEMPLATE_TYPE_PARM:
                   1090:       return build_type_variant (args[TEMPLATE_TYPE_IDX (t)],
                   1091:                                 TYPE_READONLY (t),
                   1092:                                 TYPE_VOLATILE (t));
                   1093: 
                   1094:     case TEMPLATE_CONST_PARM:
                   1095:       return args[TEMPLATE_CONST_IDX (t)];
                   1096: 
                   1097:     case FUNCTION_DECL:
                   1098:       {
                   1099:        tree r;
                   1100:        tree fnargs, result;
                   1101:        
                   1102:        if (type == TREE_TYPE (t)
1.1.1.4   root     1103:            && (DECL_CONTEXT (t) == NULL_TREE
                   1104:                || TREE_CODE_CLASS (TREE_CODE (DECL_CONTEXT (t))) != 't'))
1.1       root     1105:          return t;
1.1.1.5   root     1106:        fnargs = tsubst (DECL_ARGUMENTS (t), args, nargs, t);
                   1107:        result = tsubst (DECL_RESULT (t), args, nargs, t);
1.1.1.4   root     1108:        if (DECL_CONTEXT (t) != NULL_TREE
                   1109:            && TREE_CODE_CLASS (TREE_CODE (DECL_CONTEXT (t))) == 't')
1.1       root     1110:          {
                   1111:            /* Look it up in that class, and return the decl node there,
                   1112:               instead of creating a new one.  */
1.1.1.4   root     1113:            tree ctx, methods, name, method;
                   1114:            int n_methods;
1.1       root     1115:            int i, found = 0;
                   1116: 
1.1.1.4   root     1117:            name = DECL_NAME (t);
1.1.1.5   root     1118:            ctx = tsubst (DECL_CONTEXT (t), args, nargs, t);
1.1.1.4   root     1119:            methods = CLASSTYPE_METHOD_VEC (ctx);
                   1120:            if (methods == NULL_TREE)
                   1121:              /* No methods at all -- no way this one can match.  */
                   1122:              goto no_match;
                   1123:            n_methods = TREE_VEC_LENGTH (methods);
                   1124: 
1.1       root     1125:            r = NULL_TREE;
                   1126: 
1.1.1.4   root     1127:            if (!strncmp (OPERATOR_TYPENAME_FORMAT,
                   1128:                          IDENTIFIER_POINTER (name),
                   1129:                          sizeof (OPERATOR_TYPENAME_FORMAT) - 1))
                   1130:              {
                   1131:                /* Type-conversion operator.  Reconstruct the name, in
                   1132:                   case it's the name of one of the template's parameters.  */
                   1133:                name = build_typename_overload (TREE_TYPE (type));
                   1134:              }
                   1135: 
                   1136:            if (DECL_CONTEXT (t) != NULL_TREE
                   1137:                && TREE_CODE_CLASS (TREE_CODE (DECL_CONTEXT (t))) == 't'
1.1       root     1138:                && constructor_name (DECL_CONTEXT (t)) == DECL_NAME (t))
                   1139:              name = constructor_name (ctx);
                   1140: #if 0
                   1141:            fprintf (stderr, "\nfor function %s in class %s:\n",
                   1142:                     IDENTIFIER_POINTER (name),
1.1.1.3   root     1143:                     IDENTIFIER_POINTER (TYPE_IDENTIFIER (ctx)));
1.1       root     1144: #endif
                   1145:            for (i = 0; i < n_methods; i++)
                   1146:              {
1.1.1.5   root     1147:                int pass;
                   1148: 
1.1       root     1149:                method = TREE_VEC_ELT (methods, i);
                   1150:                if (method == NULL_TREE || DECL_NAME (method) != name)
                   1151:                  continue;
1.1.1.5   root     1152: 
                   1153:                pass = 0;
                   1154:              maybe_error:
1.1       root     1155:                for (; method; method = TREE_CHAIN (method))
                   1156:                  {
1.1.1.4   root     1157:                    my_friendly_assert (TREE_CODE (method) == FUNCTION_DECL,
                   1158:                                        282);
1.1       root     1159:                    if (TREE_TYPE (method) != type)
                   1160:                      {
1.1.1.4   root     1161:                        tree mtype = TREE_TYPE (method);
                   1162:                        tree t1, t2;
                   1163: 
1.1.1.5   root     1164:                        /* Keep looking for a method that matches
                   1165:                           perfectly.  This takes care of the problem
                   1166:                           where destructors (which have implicit int args)
                   1167:                           look like constructors which have an int arg.  */
                   1168:                        if (pass == 0)
                   1169:                          continue;
                   1170: 
1.1.1.4   root     1171:                        t1 = TYPE_ARG_TYPES (mtype);
                   1172:                        t2 = TYPE_ARG_TYPES (type);
                   1173:                        if (TREE_CODE (mtype) == FUNCTION_TYPE)
                   1174:                          t2 = TREE_CHAIN (t2);
                   1175: 
                   1176:                        if (list_eq (t1, t2))
                   1177:                          {
                   1178:                            if (TREE_CODE (mtype) == FUNCTION_TYPE)
                   1179:                              {
                   1180:                                tree newtype;
                   1181:                                newtype = build_function_type (TREE_TYPE (type),
                   1182:                                                               TYPE_ARG_TYPES (type));
                   1183:                                newtype = build_type_variant (newtype,
                   1184:                                                              TYPE_READONLY (type),
                   1185:                                                              TYPE_VOLATILE (type));
                   1186:                                type = newtype;
                   1187:                                if (TREE_TYPE (type) != TREE_TYPE (mtype))
                   1188:                                  goto maybe_bad_return_type;
                   1189:                              }
                   1190:                            else if (TYPE_METHOD_BASETYPE (mtype)
                   1191:                                     == TYPE_METHOD_BASETYPE (type))
                   1192:                              {
                   1193:                                /* Types didn't match, but arg types and
                   1194:                                   `this' do match, so the return type is
                   1195:                                   all that should be messing it up.  */
                   1196:                              maybe_bad_return_type:
                   1197:                                if (TREE_TYPE (type) != TREE_TYPE (mtype))
                   1198:                                  error ("inconsistent return types for method `%s' in class `%s'",
                   1199:                                         IDENTIFIER_POINTER (name),
                   1200:                                         IDENTIFIER_POINTER (TYPE_IDENTIFIER (ctx)));
                   1201:                              }
                   1202:                            r = method;
                   1203:                            break;
                   1204:                          }
1.1       root     1205:                        found = 1;
                   1206:                        continue;
                   1207:                      }
                   1208: #if 0
                   1209:                    fprintf (stderr, "\tfound %s\n\n",
                   1210:                             IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (method)));
                   1211: #endif
1.1.1.6 ! root     1212: 
1.1.1.5   root     1213:                    if (DECL_ARGUMENTS (method)
                   1214:                        && ! TREE_PERMANENT (DECL_ARGUMENTS (method)))
1.1       root     1215:                      /* @@ Is this early enough?  Might we want to do
                   1216:                         this instead while processing the expansion?    */
                   1217:                      DECL_ARGUMENTS (method)
1.1.1.5   root     1218:                        = tsubst (DECL_ARGUMENTS (t), args, nargs, t);
1.1       root     1219:                    r = method;
                   1220:                    break;
                   1221:                  }
1.1.1.5   root     1222:                if (r == NULL_TREE && pass == 0)
                   1223:                  {
                   1224:                    pass = 1;
                   1225:                    method = TREE_VEC_ELT (methods, i);
                   1226:                    goto maybe_error;
                   1227:                  }
1.1       root     1228:              }
                   1229:            if (r == NULL_TREE)
                   1230:              {
1.1.1.4   root     1231:              no_match:
1.1.1.6 ! root     1232:                cp_error
        !          1233:                  (found
        !          1234:                   ? "template for method `%D' doesn't match any in class `%T'"
        !          1235:                   : "method `%D' not found in class `%T'", name, ctx);
1.1.1.5   root     1236:                if (in_decl)
1.1.1.6 ! root     1237:                  cp_error_at ("in attempt to instantiate `%D' declared at this point in file", in_decl);
1.1       root     1238:                return error_mark_node;
                   1239:              }
                   1240:          }
                   1241:        else
                   1242:          {
                   1243:            r = DECL_NAME (t);
1.1.1.4   root     1244:            {
                   1245:              tree decls, val;
                   1246:              int got_it = 0;
                   1247: 
                   1248:              decls = IDENTIFIER_GLOBAL_VALUE (r);
                   1249:              if (decls == NULL_TREE)
                   1250:                /* no match */;
                   1251:              else if (TREE_CODE (decls) == TREE_LIST)
                   1252:                while (decls)
                   1253:                  {
                   1254:                    val = TREE_VALUE (decls);
                   1255:                    decls = TREE_CHAIN (decls);
                   1256:                  try_one:
                   1257:                    if (TREE_CODE (val) == FUNCTION_DECL
                   1258:                        && TREE_TYPE (val) == type)
                   1259:                      {
                   1260:                        got_it = 1;
                   1261:                        r = val;
                   1262:                        break;
                   1263:                      }
                   1264:                  }
                   1265:              else
                   1266:                {
                   1267:                  val = decls;
                   1268:                  decls = NULL_TREE;
                   1269:                  goto try_one;
                   1270:                }
1.1.1.5   root     1271: 
1.1.1.4   root     1272:              if (!got_it)
1.1.1.5   root     1273:                {
                   1274:                  r = build_decl_overload (r, TYPE_VALUES (type),
                   1275:                                           DECL_CONTEXT (t) != NULL_TREE);
                   1276:                  r = build_lang_decl (FUNCTION_DECL, r, type);
                   1277:                }
1.1.1.4   root     1278:            }
1.1       root     1279:          }
                   1280:        TREE_PUBLIC (r) = TREE_PUBLIC (t);
1.1.1.4   root     1281:        DECL_EXTERNAL (r) = DECL_EXTERNAL (t);
1.1       root     1282:        TREE_STATIC (r) = TREE_STATIC (t);
1.1.1.4   root     1283:        DECL_INLINE (r) = DECL_INLINE (t);
1.1.1.6 ! root     1284:        {
        !          1285: #if 0                          /* Maybe later.  -jason  */
        !          1286:          struct tinst_level *til = tinst_for_decl();
        !          1287: 
        !          1288:          /* should always be true under new approach */
        !          1289:          if (til)
        !          1290:            {
        !          1291:              DECL_SOURCE_FILE (r) = til->file;
        !          1292:              DECL_SOURCE_LINE (r) = til->line;
        !          1293:            }
        !          1294:          else
        !          1295: #endif
        !          1296:            {
        !          1297:              DECL_SOURCE_FILE (r) = DECL_SOURCE_FILE (t);
        !          1298:              DECL_SOURCE_LINE (r) = DECL_SOURCE_LINE (t);
        !          1299:            }
        !          1300:        }
1.1.1.5   root     1301:        DECL_CLASS_CONTEXT (r) = tsubst (DECL_CLASS_CONTEXT (t), args, nargs, t);
                   1302:        make_decl_rtl (r, NULL_PTR, 1);
1.1       root     1303:        DECL_ARGUMENTS (r) = fnargs;
                   1304:        DECL_RESULT (r) = result;
1.1.1.4   root     1305:        if (DECL_CONTEXT (t) == NULL_TREE
                   1306:            || TREE_CODE_CLASS (TREE_CODE (DECL_CONTEXT (t))) != 't')
1.1       root     1307:          push_overloaded_decl_top_level (r, 0);
                   1308:        return r;
                   1309:       }
                   1310: 
                   1311:     case PARM_DECL:
                   1312:       {
                   1313:        tree r;
                   1314:        r = build_decl (PARM_DECL, DECL_NAME (t), type);
                   1315:        DECL_INITIAL (r) = TREE_TYPE (r);
                   1316:        if (TREE_CHAIN (t))
1.1.1.5   root     1317:          TREE_CHAIN (r) = tsubst (TREE_CHAIN (t), args, nargs, TREE_CHAIN (t));
1.1       root     1318:        return r;
                   1319:       }
                   1320: 
                   1321:     case TREE_LIST:
                   1322:       {
                   1323:        tree purpose, value, chain, result;
1.1.1.4   root     1324:        int via_public, via_virtual, via_protected;
1.1       root     1325: 
                   1326:        if (t == void_list_node)
                   1327:          return t;
                   1328: 
                   1329:        via_public = TREE_VIA_PUBLIC (t);
1.1.1.4   root     1330:        via_protected = TREE_VIA_PROTECTED (t);
1.1       root     1331:        via_virtual = TREE_VIA_VIRTUAL (t);
                   1332: 
                   1333:        purpose = TREE_PURPOSE (t);
                   1334:        if (purpose)
1.1.1.5   root     1335:          purpose = tsubst (purpose, args, nargs, in_decl);
1.1       root     1336:        value = TREE_VALUE (t);
                   1337:        if (value)
1.1.1.5   root     1338:          value = tsubst (value, args, nargs, in_decl);
1.1       root     1339:        chain = TREE_CHAIN (t);
1.1.1.5   root     1340:        if (chain && chain != void_type_node)
                   1341:          chain = tsubst (chain, args, nargs, in_decl);
1.1       root     1342:        if (purpose == TREE_PURPOSE (t)
                   1343:            && value == TREE_VALUE (t)
                   1344:            && chain == TREE_CHAIN (t))
                   1345:          return t;
1.1.1.4   root     1346:        result = hash_tree_cons (via_public, via_virtual, via_protected,
1.1       root     1347:                                 purpose, value, chain);
                   1348:        TREE_PARMLIST (result) = TREE_PARMLIST (t);
                   1349:        return result;
                   1350:       }
                   1351:     case TREE_VEC:
                   1352:       {
                   1353:        int len = TREE_VEC_LENGTH (t), need_new = 0, i;
                   1354:        tree *elts = (tree *) alloca (len * sizeof (tree));
                   1355:        bzero (elts, len * sizeof (tree));
                   1356: 
                   1357:        for (i = 0; i < len; i++)
                   1358:          {
1.1.1.5   root     1359:            elts[i] = tsubst (TREE_VEC_ELT (t, i), args, nargs, in_decl);
1.1       root     1360:            if (elts[i] != TREE_VEC_ELT (t, i))
                   1361:              need_new = 1;
                   1362:          }
                   1363: 
                   1364:        if (!need_new)
                   1365:          return t;
                   1366: 
                   1367:        t = make_tree_vec (len);
                   1368:        for (i = 0; i < len; i++)
                   1369:          TREE_VEC_ELT (t, i) = elts[i];
                   1370:        return t;
                   1371:       }
                   1372:     case POINTER_TYPE:
                   1373:     case REFERENCE_TYPE:
                   1374:       {
                   1375:        tree r;
                   1376:        enum tree_code code;
                   1377:        if (type == TREE_TYPE (t))
                   1378:          return t;
                   1379: 
                   1380:        code = TREE_CODE (t);
                   1381:        if (code == POINTER_TYPE)
                   1382:          r = build_pointer_type (type);
                   1383:        else
                   1384:          r = build_reference_type (type);
                   1385:        r = build_type_variant (r, TYPE_READONLY (t), TYPE_VOLATILE (t));
                   1386:        /* Will this ever be needed for TYPE_..._TO values?  */
                   1387:        layout_type (r);
                   1388:        return r;
                   1389:       }
                   1390:     case FUNCTION_TYPE:
                   1391:     case METHOD_TYPE:
                   1392:       {
                   1393:        tree values = TYPE_VALUES (t); /* same as TYPE_ARG_TYPES */
                   1394:        tree context = TYPE_CONTEXT (t);
                   1395:        tree new_value;
                   1396: 
                   1397:        /* Don't bother recursing if we know it won't change anything.  */
                   1398:        if (! (values == void_type_node
                   1399:               || values == integer_type_node))
1.1.1.5   root     1400:          values = tsubst (values, args, nargs, in_decl);
1.1       root     1401:        if (context)
1.1.1.5   root     1402:          context = tsubst (context, args, nargs, in_decl);
1.1       root     1403:        /* Could also optimize cases where return value and
                   1404:           values have common elements (e.g., T min(const &T, const T&).  */
                   1405: 
                   1406:        /* If the above parameters haven't changed, just return the type.  */
                   1407:        if (type == TREE_TYPE (t)
                   1408:            && values == TYPE_VALUES (t)
                   1409:            && context == TYPE_CONTEXT (t))
                   1410:          return t;
                   1411: 
                   1412:        /* Construct a new type node and return it.  */
                   1413:        if (TREE_CODE (t) == FUNCTION_TYPE
                   1414:            && context == NULL_TREE)
                   1415:          {
                   1416:            new_value = build_function_type (type, values);
                   1417:          }
                   1418:        else if (context == NULL_TREE)
                   1419:          {
1.1.1.4   root     1420:            tree base = tsubst (TREE_TYPE (TREE_VALUE (TYPE_ARG_TYPES (t))),
1.1.1.5   root     1421:                                args, nargs, in_decl);
1.1       root     1422:            new_value = build_cplus_method_type (base, type,
                   1423:                                                 TREE_CHAIN (values));
                   1424:          }
                   1425:        else
                   1426:          {
                   1427:            new_value = make_node (TREE_CODE (t));
                   1428:            TREE_TYPE (new_value) = type;
                   1429:            TYPE_CONTEXT (new_value) = context;
                   1430:            TYPE_VALUES (new_value) = values;
                   1431:            TYPE_SIZE (new_value) = TYPE_SIZE (t);
                   1432:            TYPE_ALIGN (new_value) = TYPE_ALIGN (t);
                   1433:            TYPE_MODE (new_value) = TYPE_MODE (t);
                   1434:            if (TYPE_METHOD_BASETYPE (t))
                   1435:              TYPE_METHOD_BASETYPE (new_value) = tsubst (TYPE_METHOD_BASETYPE (t),
1.1.1.5   root     1436:                                                         args, nargs, in_decl);
1.1       root     1437:            /* Need to generate hash value.  */
1.1.1.3   root     1438:            my_friendly_abort (84);
1.1       root     1439:          }
                   1440:        new_value = build_type_variant (new_value,
1.1.1.4   root     1441:                                        TYPE_READONLY (t),
                   1442:                                        TYPE_VOLATILE (t));
1.1       root     1443:        return new_value;
                   1444:       }
                   1445:     case ARRAY_TYPE:
                   1446:       {
1.1.1.5   root     1447:        tree domain = tsubst (TYPE_DOMAIN (t), args, nargs, in_decl);
1.1       root     1448:        tree r;
                   1449:        if (type == TREE_TYPE (t) && domain == TYPE_DOMAIN (t))
                   1450:          return t;
                   1451:        r = build_cplus_array_type (type, domain);
                   1452:        return r;
                   1453:       }
                   1454: 
                   1455:     case UNINSTANTIATED_P_TYPE:
                   1456:       {
                   1457:        int nparms = TREE_VEC_LENGTH (DECL_TEMPLATE_PARMS (UPT_TEMPLATE (t)));
                   1458:        tree argvec = make_tree_vec (nparms);
                   1459:        tree parmvec = UPT_PARMS (t);
                   1460:        int i;
                   1461:        tree id;
                   1462:        for (i = 0; i < nparms; i++)
                   1463:          TREE_VEC_ELT (argvec, i) = tsubst (TREE_VEC_ELT (parmvec, i),
1.1.1.5   root     1464:                                             args, nargs, in_decl);
                   1465:        id = lookup_template_class (DECL_NAME (UPT_TEMPLATE (t)), argvec, NULL_TREE);
1.1       root     1466:        if (! IDENTIFIER_HAS_TYPE_VALUE (id)) {
                   1467:          instantiate_class_template(id, 0);
                   1468:          /* set up pending_classes */
                   1469:          add_pending_template (id);
                   1470: 
                   1471:          TYPE_MAIN_VARIANT (IDENTIFIER_TYPE_VALUE (id)) =
                   1472:            IDENTIFIER_TYPE_VALUE (id);
                   1473:        }
1.1.1.4   root     1474:        return build_type_variant (IDENTIFIER_TYPE_VALUE (id),
                   1475:                                   TYPE_READONLY (t),
                   1476:                                   TYPE_VOLATILE (t));
1.1       root     1477:       }
                   1478: 
                   1479:     case MINUS_EXPR:
                   1480:     case PLUS_EXPR:
                   1481:       return fold (build (TREE_CODE (t), TREE_TYPE (t),
1.1.1.5   root     1482:                          tsubst (TREE_OPERAND (t, 0), args, nargs, in_decl),
                   1483:                          tsubst (TREE_OPERAND (t, 1), args, nargs, in_decl)));
1.1       root     1484: 
                   1485:     case NEGATE_EXPR:
                   1486:     case NOP_EXPR:
                   1487:       return fold (build1 (TREE_CODE (t), TREE_TYPE (t),
1.1.1.5   root     1488:                           tsubst (TREE_OPERAND (t, 0), args, nargs, in_decl)));
1.1       root     1489: 
                   1490:     default:
                   1491:       sorry ("use of `%s' in function template",
                   1492:             tree_code_name [(int) TREE_CODE (t)]);
                   1493:       return error_mark_node;
                   1494:     }
                   1495: }
                   1496: 
                   1497: tree
                   1498: instantiate_template (tmpl, targ_ptr)
                   1499:      tree tmpl, *targ_ptr;
                   1500: {
                   1501:   tree targs, fndecl;
                   1502:   int i, len;
                   1503:   struct pending_inline *p;
                   1504:   struct template_info *t;
                   1505:   struct obstack *old_fmp_obstack;
                   1506:   extern struct obstack *function_maybepermanent_obstack;
                   1507: 
                   1508:   push_obstacks (&permanent_obstack, &permanent_obstack);
                   1509:   old_fmp_obstack = function_maybepermanent_obstack;
                   1510:   function_maybepermanent_obstack = &permanent_obstack;
                   1511: 
1.1.1.4   root     1512:   my_friendly_assert (TREE_CODE (tmpl) == TEMPLATE_DECL, 283);
1.1       root     1513:   len = TREE_VEC_LENGTH (DECL_TEMPLATE_PARMS (tmpl));
                   1514: 
                   1515:   for (fndecl = DECL_TEMPLATE_INSTANTIATIONS (tmpl);
                   1516:        fndecl; fndecl = TREE_CHAIN (fndecl))
                   1517:     {
                   1518:       tree *t1 = &TREE_VEC_ELT (TREE_PURPOSE (fndecl), 0);
                   1519:       for (i = len - 1; i >= 0; i--)
                   1520:        if (t1[i] != targ_ptr[i])
                   1521:          goto no_match;
                   1522: 
                   1523:       /* Here, we have a match.  */
                   1524:       fndecl = TREE_VALUE (fndecl);
                   1525:       function_maybepermanent_obstack = old_fmp_obstack;
                   1526:       pop_obstacks ();
                   1527:       return fndecl;
                   1528: 
                   1529:     no_match:
                   1530:       ;
                   1531:     }
                   1532: 
                   1533:   targs = make_tree_vec (len);
                   1534:   i = len;
                   1535:   while (i--)
                   1536:     TREE_VEC_ELT (targs, i) = targ_ptr[i];
                   1537: 
                   1538:   /* substitute template parameters */
                   1539:   fndecl = tsubst (DECL_RESULT (tmpl), targ_ptr,
1.1.1.5   root     1540:                   TREE_VEC_LENGTH (targs), tmpl);
                   1541: 
                   1542:   /* If it's a static member fn in the template, we need to change it
                   1543:      into a FUNCTION_TYPE and chop off its this pointer.  */
                   1544:   if (TREE_CODE (TREE_TYPE (DECL_RESULT (tmpl))) == METHOD_TYPE
                   1545:       && fndecl != error_mark_node
                   1546:       && DECL_STATIC_FUNCTION_P (fndecl))
                   1547:     {
                   1548:       tree olddecl = DECL_RESULT (tmpl);
                   1549:       revert_static_member_fn (&TREE_TYPE (olddecl), &DECL_RESULT (tmpl),
                   1550:                               &TYPE_ARG_TYPES (TREE_TYPE (olddecl)));
                   1551:       /* Chop off the this pointer that grokclassfn so kindly added
                   1552:         for us (it didn't know yet if the fn was static or not).  */
                   1553:       DECL_ARGUMENTS (olddecl) = TREE_CHAIN (DECL_ARGUMENTS (olddecl));
                   1554:       DECL_ARGUMENTS (fndecl) = TREE_CHAIN (DECL_ARGUMENTS (fndecl));
                   1555:     }
                   1556:      
1.1       root     1557:   t = DECL_TEMPLATE_INFO (tmpl);
1.1.1.2   root     1558:   if (t->text)
                   1559:     {
                   1560:       p = (struct pending_inline *) permalloc (sizeof (struct pending_inline));
                   1561:       p->parm_vec = t->parm_vec;
                   1562:       p->bindings = targs;
                   1563:       p->can_free = 0;
                   1564:       p->deja_vu = 0;
                   1565:       p->buf = t->text;
                   1566:       p->len = t->length;
                   1567:       p->fndecl = fndecl;
1.1.1.6 ! root     1568:       {
        !          1569:        int l = lineno;
        !          1570:        char * f = input_filename;
        !          1571: 
        !          1572:        lineno = p->lineno = t->lineno;
        !          1573:        input_filename = p->filename = t->filename;
        !          1574: 
        !          1575:        extract_interface_info ();
        !          1576:        
        !          1577:        if (interface_unknown && flag_external_templates)
        !          1578:          warn_if_unknown_interface ();
        !          1579:        if (interface_unknown || !flag_external_templates)
        !          1580:          p->interface = 1;             /* unknown */
        !          1581:        else
        !          1582:          p->interface = interface_only ? 0 : 2;
        !          1583: 
        !          1584:        lineno = l;
        !          1585:        input_filename = f;
        !          1586: 
        !          1587:        extract_interface_info ();
        !          1588:       }
1.1.1.2   root     1589:     }
                   1590:   else
1.1.1.5   root     1591:     p = (struct pending_inline *)0;
1.1       root     1592: 
                   1593:   DECL_TEMPLATE_INSTANTIATIONS (tmpl) =
                   1594:     tree_cons (targs, fndecl, DECL_TEMPLATE_INSTANTIATIONS (tmpl));
                   1595: 
                   1596:   function_maybepermanent_obstack = old_fmp_obstack;
                   1597:   pop_obstacks ();
                   1598: 
1.1.1.5   root     1599:   if (fndecl == error_mark_node || p == (struct pending_inline *)0)
1.1       root     1600:     {
                   1601:       /* do nothing */
                   1602:     }
1.1.1.4   root     1603:   else if (DECL_INLINE (fndecl))
1.1       root     1604:     {
                   1605:       DECL_PENDING_INLINE_INFO (fndecl) = p;
                   1606:       p->next = pending_inlines;
                   1607:       pending_inlines = p;
                   1608:     }
                   1609:   else
                   1610:     {
                   1611:       p->next = pending_template_expansions;
                   1612:       pending_template_expansions = p;
                   1613:     }
                   1614:   return fndecl;
                   1615: }
                   1616: 
                   1617: void
                   1618: undo_template_name_overload (id, classlevel)
                   1619:      tree id;
                   1620:      int classlevel;
                   1621: {
                   1622:   tree template;
                   1623: 
                   1624:   template = IDENTIFIER_TEMPLATE (id);
                   1625:   if (!template)
                   1626:     return;
                   1627: 
1.1.1.2   root     1628: #if 0 /* not yet, should get fixed properly later */
                   1629:   poplevel (0, 0, 0);
                   1630: #endif
1.1.1.6 ! root     1631: #if 1 /* XXX */
        !          1632:   /* This was a botch... See `overload_template_name' just below.  */
1.1       root     1633:   if (!classlevel)
                   1634:     poplevel (0, 0, 0);
                   1635: #endif
                   1636: }
                   1637: 
                   1638: void
                   1639: overload_template_name (id, classlevel)
                   1640:      tree id;
                   1641:      int classlevel;
                   1642: {
                   1643:   tree template, t, decl;
                   1644:   struct template_info *tinfo;
                   1645: 
1.1.1.4   root     1646:   my_friendly_assert (TREE_CODE (id) == IDENTIFIER_NODE, 284);
1.1       root     1647:   template = IDENTIFIER_TEMPLATE (id);
                   1648:   if (!template)
                   1649:     return;
                   1650: 
                   1651:   template = TREE_PURPOSE (template);
                   1652:   tinfo = DECL_TEMPLATE_INFO (template);
                   1653:   template = DECL_NAME (template);
1.1.1.4   root     1654:   my_friendly_assert (template != NULL_TREE, 285);
1.1       root     1655: 
1.1.1.6 ! root     1656: #if 1 /* XXX */
        !          1657:   /* This was a botch... names of templates do not get their own private
        !          1658:      scopes.  Rather, the names of generated template instances should
        !          1659:      just get pushed into whatever scope we happen to be in at the moment.
        !          1660:      This will typically (but not always) be the global scope.  (Maybe
        !          1661:      what we really want to do here is a `push_to_toplevel' and then stay
        !          1662:      there while we are generating the instance; popping back out to the
        !          1663:      current scope when we are done generating the instance.)  */
1.1       root     1664:   if (!classlevel)
1.1.1.4   root     1665:     {
                   1666:       pushlevel (1);
                   1667:       declare_pseudo_global_level ();
                   1668:     }
1.1.1.6 ! root     1669: #endif
1.1       root     1670: 
                   1671:   t = xref_tag (tinfo->aggr, id, NULL_TREE);
1.1.1.4   root     1672:   my_friendly_assert (TREE_CODE (t) == RECORD_TYPE
1.1.1.6 ! root     1673:                      || TREE_CODE (t) == UNION_TYPE
        !          1674:                      || TREE_CODE (t) == UNINSTANTIATED_P_TYPE, 286);
1.1       root     1675: 
                   1676:   decl = build_decl (TYPE_DECL, template, t);
                   1677: 
                   1678: #if 0 /* fix this later */
                   1679:   /* We don't want to call here if the work has already been done.  */
                   1680:   t = (classlevel
                   1681:        ? IDENTIFIER_CLASS_VALUE (template)
                   1682:        : IDENTIFIER_LOCAL_VALUE (template));
                   1683:   if (t
                   1684:       && TREE_CODE (t) == TYPE_DECL
                   1685:       && TREE_TYPE (t) == t)
1.1.1.3   root     1686:     my_friendly_abort (85);
1.1       root     1687: #endif
                   1688: 
                   1689:   if (classlevel)
                   1690:     pushdecl_class_level (decl);
                   1691:   else
1.1.1.2   root     1692: #if 0 /* not yet, should get fixed properly later */
                   1693:     pushdecl (decl);
                   1694:   pushlevel (1);
                   1695: #else
1.1       root     1696:     {
                   1697:       pushdecl (decl);
                   1698:       /* @@ Is this necessary now?  */
                   1699:       IDENTIFIER_LOCAL_VALUE (template) = decl;
                   1700:     }
1.1.1.2   root     1701: #endif
1.1       root     1702: 
1.1.1.6 ! root     1703:   /* Fake this for now, just to make dwarfout.c happy.  It will have to
        !          1704:      be done in a proper way later on.  */
        !          1705:   DECL_CONTEXT (decl) = t;
1.1       root     1706: }
                   1707: 
                   1708: /* T1 is PRE_PARSED_CLASS_DECL; T3 is result of XREF_TAG lookup.  */
                   1709: void
                   1710: end_template_instantiation (t1, t3)
                   1711:      tree t1, t3;
                   1712: {
                   1713:   extern struct pending_input *to_be_restored;
                   1714:   tree t, decl;
                   1715: 
                   1716:   processing_template_defn--;
1.1.1.6 ! root     1717:   if (!flag_external_templates)
        !          1718:     interface_unknown--;
1.1       root     1719: 
                   1720:   /* Restore the old parser input state.  */
1.1.1.4   root     1721:   if (yychar == YYEMPTY)
1.1       root     1722:     yychar = yylex ();
                   1723:   if (yychar != END_OF_SAVED_INPUT)
                   1724:     error ("parse error at end of class template");
                   1725:   else
                   1726:     {
                   1727:       restore_pending_input (to_be_restored);
                   1728:       to_be_restored = 0;
                   1729:     }
                   1730: 
                   1731:   /* Our declarations didn't get stored in the global slot, since
                   1732:      there was a (supposedly tags-transparent) scope in between.  */
                   1733:   t = IDENTIFIER_TYPE_VALUE (TREE_VALUE (t1));
1.1.1.4   root     1734:   my_friendly_assert (t != NULL_TREE
                   1735:                      && TREE_CODE_CLASS (TREE_CODE (t)) == 't',
                   1736:                      287);
1.1       root     1737:   CLASSTYPE_USE_TEMPLATE (t) = 2;
1.1.1.6 ! root     1738:   /* Make methods of template classes static, unless
        !          1739:      -fexternal-templates is given.  */
        !          1740:   if (!flag_external_templates)
        !          1741:     SET_CLASSTYPE_INTERFACE_UNKNOWN (t);
1.1       root     1742:   decl = IDENTIFIER_GLOBAL_VALUE (TREE_VALUE (t1));
1.1.1.4   root     1743:   my_friendly_assert (TREE_CODE (decl) == TYPE_DECL, 288);
1.1       root     1744: 
                   1745:   undo_template_name_overload (TREE_VALUE (t1), 0);
                   1746:   t = IDENTIFIER_TEMPLATE (TREE_VALUE (t1));
                   1747:   pop_template_decls (DECL_TEMPLATE_PARMS (TREE_PURPOSE (t)), TREE_VALUE (t),
                   1748:                      0);
                   1749:   pop_from_top_level ();
                   1750: 
                   1751:   /* This will fix up the type-value field.  */
                   1752:   pushdecl_top_level (decl);
1.1.1.6 ! root     1753: #ifdef DWARF_DEBUGGING_INFO
        !          1754:   if (write_symbols == DWARF_DEBUG && TREE_CODE (decl) == TYPE_DECL)
        !          1755:     {
        !          1756:       /* We just completed the definition of a new file-scope type,
        !          1757:         so we can go ahead and output debug-info for it now.  */
        !          1758:       TYPE_STUB_DECL (TREE_TYPE (decl)) = decl;
        !          1759:       rest_of_type_compilation (TREE_TYPE (decl), 1);
        !          1760:     }
        !          1761: #endif /* DWARF_DEBUGGING_INFO */
1.1       root     1762: 
                   1763:   /* Restore interface/implementation settings.         */
                   1764:   extract_interface_info ();
                   1765: }
                   1766: 
                   1767: /* Store away the text of an inline template function. No rtl is
                   1768:    generated for this function until it is actually needed.  */
                   1769: 
                   1770: void
                   1771: reinit_parse_for_template (yychar, d1, d2)
                   1772:      int yychar;
                   1773:      tree d1, d2;
                   1774: {
                   1775:   struct template_info *template_info;
1.1.1.6 ! root     1776:   extern struct obstack inline_text_obstack; /* see comment in cp-lex.c */
1.1       root     1777: 
                   1778:   if (d2 == NULL_TREE || d2 == error_mark_node)
                   1779:     {
                   1780:     lose:
                   1781:       /* @@ Should use temp obstack, and discard results.  */
1.1.1.6 ! root     1782:       reinit_parse_for_block (yychar, &inline_text_obstack, 1);
1.1       root     1783:       return;
                   1784:     }
                   1785: 
                   1786:   if (TREE_CODE (d2) == IDENTIFIER_NODE)
                   1787:     d2 = IDENTIFIER_GLOBAL_VALUE (d2);
                   1788:   if (!d2)
                   1789:     goto lose;
                   1790:   template_info = DECL_TEMPLATE_INFO (d2);
                   1791:   if (!template_info)
                   1792:     {
                   1793:       template_info = (struct template_info *) permalloc (sizeof (struct template_info));
                   1794:       bzero (template_info, sizeof (struct template_info));
                   1795:       DECL_TEMPLATE_INFO (d2) = template_info;
                   1796:     }
                   1797:   template_info->filename = input_filename;
                   1798:   template_info->lineno = lineno;
1.1.1.6 ! root     1799:   reinit_parse_for_block (yychar, &inline_text_obstack, 1);
        !          1800:   template_info->text = obstack_base (&inline_text_obstack);
        !          1801:   template_info->length = obstack_object_size (&inline_text_obstack);
        !          1802:   obstack_finish (&inline_text_obstack);
1.1       root     1803:   template_info->parm_vec = d1;
                   1804: }
                   1805: 
                   1806: /* Type unification.
                   1807: 
                   1808:    We have a function template signature with one or more references to
                   1809:    template parameters, and a parameter list we wish to fit to this
                   1810:    template.  If possible, produce a list of parameters for the template
                   1811:    which will cause it to fit the supplied parameter list.
                   1812: 
                   1813:    Return zero for success, 2 for an incomplete match that doesn't resolve
                   1814:    all the types, and 1 for complete failure.  An error message will be
                   1815:    printed only for an incomplete match.
                   1816: 
                   1817:    TPARMS[NTPARMS] is an array of template parameter types;
                   1818:    TARGS[NTPARMS] is the array of template parameter values.  PARMS is
                   1819:    the function template's signature (using TEMPLATE_PARM_IDX nodes),
                   1820:    and ARGS is the argument list we're trying to match against it.  */
                   1821: 
                   1822: int
                   1823: type_unification (tparms, targs, parms, args, nsubsts)
                   1824:      tree tparms, *targs, parms, args;
                   1825:      int *nsubsts;
                   1826: {
                   1827:   tree parm, arg;
                   1828:   int i;
                   1829:   int ntparms = TREE_VEC_LENGTH (tparms);
                   1830: 
1.1.1.4   root     1831:   my_friendly_assert (TREE_CODE (tparms) == TREE_VEC, 289);
                   1832:   my_friendly_assert (TREE_CODE (parms) == TREE_LIST, 290);
1.1.1.5   root     1833:   /* ARGS could be NULL (via a call from cp-parse.y to
                   1834:      build_x_function_call).  */
                   1835:   if (args)
                   1836:     my_friendly_assert (TREE_CODE (args) == TREE_LIST, 291);
1.1.1.4   root     1837:   my_friendly_assert (ntparms > 0, 292);
1.1       root     1838: 
                   1839:   bzero (targs, sizeof (tree) * ntparms);
                   1840: 
                   1841:   while (parms
                   1842:         && parms != void_list_node
                   1843:         && args)
                   1844:     {
                   1845:       parm = TREE_VALUE (parms);
                   1846:       parms = TREE_CHAIN (parms);
                   1847:       arg = TREE_VALUE (args);
                   1848:       args = TREE_CHAIN (args);
                   1849: 
                   1850:       if (arg == error_mark_node)
                   1851:        return 1;
1.1.1.4   root     1852:       if (arg == unknown_type_node)
                   1853:        return 1;
1.1       root     1854: #if 0
                   1855:       if (TREE_CODE (arg) == VAR_DECL)
                   1856:        arg = TREE_TYPE (arg);
                   1857:       else if (TREE_CODE_CLASS (TREE_CODE (arg)) == 'e')
                   1858:        arg = TREE_TYPE (arg);
                   1859: #else
1.1.1.4   root     1860:       my_friendly_assert (TREE_TYPE (arg) != NULL_TREE, 293);
1.1       root     1861:       arg = TREE_TYPE (arg);
                   1862: #endif
                   1863: 
                   1864:       switch (unify (tparms, targs, ntparms, parm, arg, nsubsts))
                   1865:        {
                   1866:        case 0:
                   1867:          break;
                   1868:        case 1:
                   1869:          return 1;
                   1870:        }
                   1871:     }
                   1872:   /* Fail if we've reached the end of the parm list, and more args
                   1873:      are present, and the parm list isn't variadic.  */
                   1874:   if (args && parms == void_list_node)
                   1875:     return 1;
                   1876:   /* Fail if parms are left and they don't have default values.         */
                   1877:   if (parms
                   1878:       && parms != void_list_node
                   1879:       && TREE_PURPOSE (parms) == NULL_TREE)
                   1880:     return 1;
                   1881:   for (i = 0; i < ntparms; i++)
                   1882:     if (!targs[i])
                   1883:       {
                   1884:        error ("incomplete type unification");
                   1885:        return 2;
                   1886:       }
                   1887:   return 0;
                   1888: }
                   1889: 
                   1890: /* Tail recursion is your friend.  */
                   1891: static int
                   1892: unify (tparms, targs, ntparms, parm, arg, nsubsts)
                   1893:      tree tparms, *targs, parm, arg;
1.1.1.6 ! root     1894:      int *nsubsts, ntparms;
1.1       root     1895: {
                   1896:   int idx;
                   1897: 
                   1898:   /* I don't think this will do the right thing with respect to types.
                   1899:      But the only case I've seen it in so far has been array bounds, where
                   1900:      signedness is the only information lost, and I think that will be
                   1901:      okay.  */
                   1902:   while (TREE_CODE (parm) == NOP_EXPR)
                   1903:     parm = TREE_OPERAND (parm, 0);
                   1904: 
                   1905:   if (arg == error_mark_node)
                   1906:     return 1;
1.1.1.4   root     1907:   if (arg == unknown_type_node)
                   1908:     return 1;
1.1       root     1909:   if (arg == parm)
                   1910:     return 0;
                   1911: 
1.1.1.6 ! root     1912:   if (TREE_CODE (arg) == REFERENCE_TYPE)
        !          1913:     arg = TREE_TYPE (arg);
        !          1914: 
1.1       root     1915:   switch (TREE_CODE (parm))
                   1916:     {
                   1917:     case TEMPLATE_TYPE_PARM:
                   1918:       (*nsubsts)++;
                   1919:       if (TEMPLATE_TYPE_TPARMLIST (parm) != tparms)
                   1920:        {
                   1921:          error ("mixed template headers?!");
1.1.1.3   root     1922:          my_friendly_abort (86);
1.1       root     1923:          return 1;
                   1924:        }
                   1925:       idx = TEMPLATE_TYPE_IDX (parm);
                   1926:       /* Simple cases: Value already set, does match or doesn't.  */
                   1927:       if (targs[idx] == arg)
                   1928:        return 0;
                   1929:       else if (targs[idx])
                   1930:        return 1;
                   1931:       /* Check for mixed types and values.  */
                   1932:       if (TREE_CODE (TREE_VEC_ELT (tparms, idx)) != IDENTIFIER_NODE)
                   1933:        return 1;
                   1934:       targs[idx] = arg;
                   1935:       return 0;
                   1936:     case TEMPLATE_CONST_PARM:
                   1937:       (*nsubsts)++;
                   1938:       idx = TEMPLATE_CONST_IDX (parm);
                   1939:       if (targs[idx] == arg)
                   1940:        return 0;
                   1941:       else if (targs[idx])
                   1942:        {
1.1.1.3   root     1943:          my_friendly_abort (87);
1.1       root     1944:          return 1;
                   1945:        }
                   1946: /*     else if (typeof arg != tparms[idx])
                   1947:        return 1;*/
                   1948: 
                   1949:       targs[idx] = copy_to_permanent (arg);
                   1950:       return 0;
                   1951: 
                   1952:     case POINTER_TYPE:
                   1953:       if (TREE_CODE (arg) != POINTER_TYPE)
                   1954:        return 1;
                   1955:       return unify (tparms, targs, ntparms, TREE_TYPE (parm), TREE_TYPE (arg),
                   1956:                    nsubsts);
                   1957: 
                   1958:     case REFERENCE_TYPE:
                   1959:       return unify (tparms, targs, ntparms, TREE_TYPE (parm), arg, nsubsts);
                   1960: 
                   1961:     case ARRAY_TYPE:
                   1962:       if (TREE_CODE (arg) != ARRAY_TYPE)
                   1963:        return 1;
                   1964:       if (unify (tparms, targs, ntparms, TYPE_DOMAIN (parm), TYPE_DOMAIN (arg),
                   1965:                 nsubsts) != 0)
                   1966:        return 1;
                   1967:       return unify (tparms, targs, ntparms, TREE_TYPE (parm), TREE_TYPE (arg),
                   1968:                    nsubsts);
                   1969: 
                   1970:     case REAL_TYPE:
                   1971:     case INTEGER_TYPE:
                   1972:       if (TREE_CODE (parm) == INTEGER_TYPE && TREE_CODE (arg) == INTEGER_TYPE)
                   1973:        {
                   1974:          if (TYPE_MIN_VALUE (parm) && TYPE_MIN_VALUE (arg)
                   1975:              && unify (tparms, targs, ntparms,
                   1976:                        TYPE_MIN_VALUE (parm), TYPE_MIN_VALUE (arg), nsubsts))
                   1977:            return 1;
                   1978:          if (TYPE_MAX_VALUE (parm) && TYPE_MAX_VALUE (arg)
                   1979:              && unify (tparms, targs, ntparms,
                   1980:                        TYPE_MAX_VALUE (parm), TYPE_MAX_VALUE (arg), nsubsts))
                   1981:            return 1;
                   1982:        }
                   1983:       /* As far as unification is concerned, this wins.         Later checks
                   1984:         will invalidate it if necessary.  */
                   1985:       return 0;
                   1986: 
                   1987:       /* Types INTEGER_CST and MINUS_EXPR can come from array bounds.  */
                   1988:     case INTEGER_CST:
                   1989:       if (TREE_CODE (arg) != INTEGER_CST)
                   1990:        return 1;
                   1991:       return !tree_int_cst_equal (parm, arg);
                   1992: 
                   1993:     case MINUS_EXPR:
                   1994:       {
                   1995:        tree t1, t2;
                   1996:        t1 = TREE_OPERAND (parm, 0);
                   1997:        t2 = TREE_OPERAND (parm, 1);
                   1998:        if (TREE_CODE (t1) != TEMPLATE_CONST_PARM)
                   1999:          return 1;
                   2000:        return unify (tparms, targs, ntparms, t1,
                   2001:                      fold (build (PLUS_EXPR, integer_type_node, arg, t2)),
                   2002:                      nsubsts);
                   2003:       }
                   2004: 
                   2005:     case TREE_VEC:
                   2006:       {
                   2007:        int i;
                   2008:        if (TREE_CODE (arg) != TREE_VEC)
                   2009:          return 1;
                   2010:        if (TREE_VEC_LENGTH (parm) != TREE_VEC_LENGTH (arg))
                   2011:          return 1;
                   2012:        for (i = TREE_VEC_LENGTH (parm) - 1; i >= 0; i--)
                   2013:          if (unify (tparms, targs, ntparms,
                   2014:                     TREE_VEC_ELT (parm, i), TREE_VEC_ELT (arg, i),
                   2015:                     nsubsts))
                   2016:            return 1;
                   2017:        return 0;
                   2018:       }
                   2019: 
                   2020:     case UNINSTANTIATED_P_TYPE:
                   2021:       {
1.1.1.4   root     2022:        tree a;
                   2023:        /* Unification of something that is not a template fails. (mrs) */
                   2024:        if (TYPE_NAME (arg) == 0)
                   2025:          return 1;
                   2026:        a = IDENTIFIER_TEMPLATE (TYPE_IDENTIFIER (arg));
                   2027:        /* Unification of something that is not a template fails. (mrs) */
                   2028:        if (a == 0)
                   2029:          return 1;
1.1       root     2030:        if (UPT_TEMPLATE (parm) != TREE_PURPOSE (a))
                   2031:          /* different templates */
                   2032:          return 1;
                   2033:        return unify (tparms, targs, ntparms, UPT_PARMS (parm), TREE_VALUE (a),
                   2034:                      nsubsts);
                   2035:       }
                   2036: 
1.1.1.4   root     2037:     case RECORD_TYPE:
                   2038:       /* Unification of something that is not a template fails. (mrs) */
                   2039:       return 1;
                   2040: 
1.1       root     2041:     default:
                   2042:       sorry ("use of `%s' in template type unification",
                   2043:             tree_code_name [(int) TREE_CODE (parm)]);
                   2044:       return 1;
                   2045:     }
                   2046: }
                   2047: 
                   2048: 
                   2049: #undef DEBUG
                   2050: 
                   2051: int
                   2052: do_pending_expansions ()
                   2053: {
                   2054:   struct pending_inline *i, *new_list = 0;
                   2055: 
                   2056:   if (!pending_template_expansions)
                   2057:     return 0;
                   2058: 
                   2059: #ifdef DEBUG
                   2060:   fprintf (stderr, "\n\n\t\t IN DO_PENDING_EXPANSIONS\n\n");
                   2061: #endif
                   2062: 
                   2063:   i = pending_template_expansions;
                   2064:   while (i)
                   2065:     {
                   2066:       tree context;
                   2067: 
                   2068:       struct pending_inline *next = i->next;
                   2069:       tree t = i->fndecl;
                   2070: 
                   2071:       int decision = 0;
                   2072: #define DECIDE(N) if(1){decision=(N); goto decided;}else
                   2073: 
1.1.1.4   root     2074:       my_friendly_assert (TREE_CODE (t) == FUNCTION_DECL
                   2075:                          || TREE_CODE (t) == VAR_DECL, 294);
1.1       root     2076:       if (TREE_ASM_WRITTEN (t))
                   2077:        DECIDE (0);
                   2078:       /* If it's a method, let the class type decide it.
                   2079:         @@ What if the method template is in a separate file?
                   2080:         Maybe both file contexts should be taken into account?  */
                   2081:       context = DECL_CONTEXT (t);
1.1.1.4   root     2082:       if (context != NULL_TREE
                   2083:          && TREE_CODE_CLASS (TREE_CODE (context)) == 't')
1.1       root     2084:        {
                   2085:          /* If `unknown', we might want a static copy.
                   2086:             If `implementation', we want a global one.
                   2087:             If `interface', ext ref.  */
1.1.1.6 ! root     2088:          if (CLASSTYPE_INTERFACE_KNOWN (context))
1.1       root     2089:            DECIDE (!CLASSTYPE_INTERFACE_ONLY (context));
                   2090: #if 0 /* This doesn't get us stuff needed only by the file initializer.  */
                   2091:          DECIDE (TREE_USED (t));
                   2092: #else /* This compiles too much stuff, but that's probably better in
                   2093:         most cases than never compiling the stuff we need.  */
                   2094:          DECIDE (1);
                   2095: #endif
                   2096:        }
                   2097:       /* else maybe call extract_interface_info? */
                   2098:       if (TREE_USED (t)) /* is this right? */
                   2099:        DECIDE (1);
                   2100: 
                   2101:     decided:
                   2102: #ifdef DEBUG
                   2103:       print_node_brief (stderr, decision ? "yes: " : "no: ", t, 0);
                   2104:       fprintf (stderr, "\t%s\n",
                   2105:               (DECL_ASSEMBLER_NAME (t)
                   2106:                ? IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (t))
                   2107:                : ""));
                   2108: #endif
                   2109:       if (decision == 1)
                   2110:        {
                   2111:          i->next = pending_inlines;
                   2112:          pending_inlines = i;
                   2113:        }
                   2114:       else
                   2115:        {
                   2116:          i->next = new_list;
                   2117:          new_list = i;
                   2118:        }
                   2119:       i = next;
                   2120:     }
                   2121:   pending_template_expansions = new_list;
                   2122:   if (!pending_inlines)
                   2123:     return 0;
                   2124:   do_pending_inlines ();
                   2125:   return 1;
                   2126: }
                   2127: 
1.1.1.4   root     2128: 
1.1       root     2129: struct pending_template {
                   2130:   struct pending_template *next;
                   2131:   tree id;
                   2132: };
                   2133: 
1.1.1.4   root     2134: static struct pending_template* pending_templates;
1.1       root     2135: 
                   2136: void
                   2137: do_pending_templates ()
                   2138: {
                   2139:   struct pending_template* t;
                   2140:   
                   2141:   for ( t = pending_templates; t; t = t->next)
                   2142:     {
                   2143:       instantiate_class_template (t->id, 1);
                   2144:     }
                   2145: 
                   2146:   for ( t = pending_templates; t; t = pending_templates)
                   2147:     {
                   2148:       pending_templates = t->next;
                   2149:       free(t);
                   2150:     }
                   2151: }
                   2152: 
1.1.1.4   root     2153: static void
1.1       root     2154: add_pending_template (pt)
                   2155:      tree pt;
                   2156: {
                   2157:   struct pending_template *p;
                   2158:   
                   2159:   p = (struct pending_template *) malloc (sizeof (struct pending_template));
                   2160:   p->next = pending_templates;
                   2161:   pending_templates = p;
                   2162:   p->id = pt;
                   2163: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.