home *** CD-ROM | disk | FTP | other *** search
/ Fresh Fish 7 / FreshFishVol7.bin / bbs / gnu / gcc-2.3.3-src.lha / GNU / src / amiga / gcc-2.3.3 / cp-pt.c < prev    next >
C/C++ Source or Header  |  1994-02-06  |  57KB  |  2,058 lines

  1. /* Handle parameterized types (templates) for GNU C++.
  2.    Written by Ken Raeburn of Watchmaker Computing.
  3.    Copyright (C) 1992 Free Software Foundation, Inc.
  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"
  36. #include "cp-tree.h"
  37. #include "cp-decl.h"
  38. #include "cp-parse.h"
  39.  
  40. extern struct obstack permanent_obstack;
  41. extern tree grokdeclarator ();
  42.  
  43. extern int lineno;
  44. extern char *input_filename;
  45. struct pending_inline *pending_template_expansions;
  46.  
  47. int processing_template_decl;
  48. int processing_template_defn;
  49.  
  50. #define obstack_chunk_alloc xmalloc
  51. #define obstack_chunk_free free
  52.  
  53. static int unify ();
  54. static void add_pending_template ();
  55.  
  56. void overload_template_name (), pop_template_decls ();
  57.  
  58. /* We've got a template header coming up; set obstacks up to save the
  59.    nodes created permanently.  (There might be cases with nested templates
  60.    where we don't have to do this, but they aren't implemented, and it
  61.    probably wouldn't be worth the effort.)  */
  62. void
  63. begin_template_parm_list ()
  64. {
  65.   pushlevel (0);
  66.   push_obstacks (&permanent_obstack, &permanent_obstack);
  67. }
  68.  
  69. /* Process information from new template parameter NEXT and append it to the
  70.    LIST being built.  The rules for use of a template parameter type name
  71.    by later parameters are not well-defined for us just yet.  However, the
  72.    only way to avoid having to parse expressions of unknown complexity (and
  73.    with tokens of unknown types) is to disallow it completely.    So for now,
  74.    that is what is assumed.  */
  75. tree
  76. process_template_parm (list, next)
  77.      tree list, next;
  78. {
  79.   tree parm;
  80.   int is_type;
  81.   parm = next;
  82.   my_friendly_assert (TREE_CODE (parm) == TREE_LIST, 259);
  83.   is_type = TREE_CODE (TREE_PURPOSE (parm)) == IDENTIFIER_NODE;
  84.   if (!is_type)
  85.     {
  86.       parm = TREE_PURPOSE (parm);
  87.       my_friendly_assert (TREE_CODE (parm) == TREE_LIST, 260);
  88.       parm = TREE_VALUE (parm);
  89.       /* is a const-param */
  90.       parm = grokdeclarator (TREE_VALUE (next), TREE_PURPOSE (next),
  91.                  NORMAL, 0, NULL_TREE);
  92.       /* A template parameter is not modifiable.  */
  93.       TREE_READONLY (parm) = 1;
  94.       if (TREE_CODE (TREE_TYPE (parm)) == RECORD_TYPE
  95.       || TREE_CODE (TREE_TYPE (parm)) == UNION_TYPE)
  96.     {
  97.       sorry ("aggregate template parameter types");
  98.       TREE_TYPE (parm) = void_type_node;
  99.     }
  100.     }
  101.   return chainon (list, parm);
  102. }
  103.  
  104. /* The end of a template parameter list has been reached.  Process the
  105.    tree list into a parameter vector, converting each parameter into a more
  106.    useful form.     Type parameters are saved as IDENTIFIER_NODEs, and others
  107.    as PARM_DECLs.  */
  108.  
  109. tree
  110. end_template_parm_list (parms)
  111.      tree parms;
  112. {
  113.   int nparms = 0;
  114.   tree saved_parmlist;
  115.   tree parm;
  116.   for (parm = parms; parm; parm = TREE_CHAIN (parm))
  117.     nparms++;
  118.   saved_parmlist = make_tree_vec (nparms);
  119.  
  120.   pushlevel (0);
  121.  
  122.   for (parm = parms, nparms = 0; parm; parm = TREE_CHAIN (parm), nparms++)
  123.     {
  124.       tree p = parm, decl;
  125.       if (TREE_CODE (p) == TREE_LIST)
  126.     {
  127.       tree t;
  128.       p = TREE_PURPOSE (p);
  129.       my_friendly_assert (TREE_CODE (p) == IDENTIFIER_NODE, 261);
  130.       t = make_node (TEMPLATE_TYPE_PARM);
  131.       TEMPLATE_TYPE_SET_INFO (t, saved_parmlist, nparms);
  132.       decl = build_lang_decl (TYPE_DECL, p, t);
  133.       TYPE_NAME (t) = decl;
  134.     }
  135.       else
  136.     {
  137.       tree tinfo = make_node (TEMPLATE_CONST_PARM);
  138.       my_friendly_assert (TREE_PERMANENT (tinfo), 262);
  139.       if (!TREE_PERMANENT (p))
  140.         {
  141.           tree old_p = p;
  142.           TREE_PERMANENT (old_p) = 1;
  143.           p = copy_node (p);
  144.           TREE_PERMANENT (old_p) = 0;
  145.         }
  146.       TEMPLATE_CONST_SET_INFO (tinfo, saved_parmlist, nparms);
  147.       TREE_TYPE (tinfo) = TREE_TYPE (p);
  148.       decl = build_decl (CONST_DECL, DECL_NAME (p), TREE_TYPE (p));
  149.       DECL_INITIAL (decl) = tinfo;
  150.     }
  151.       TREE_VEC_ELT (saved_parmlist, nparms) = p;
  152.       pushdecl (decl);
  153.     }
  154.   set_current_level_tags_transparency (1);
  155.   processing_template_decl++;
  156.   return saved_parmlist;
  157. }
  158.  
  159. /* end_template_decl is called after a template declaration is seen.
  160.    D1 is template header; D2 is class_head_sans_basetype or a
  161.    TEMPLATE_DECL with its DECL_RESULT field set.  */
  162. void
  163. end_template_decl (d1, d2, is_class)
  164.      tree d1, d2, is_class;
  165. {
  166.   tree decl;
  167.   struct template_info *tmpl;
  168.  
  169.   tmpl = (struct template_info *) obstack_alloc (&permanent_obstack,
  170.                         sizeof (struct template_info));
  171.   tmpl->text = 0;
  172.   tmpl->length = 0;
  173.   tmpl->aggr = is_class;
  174.  
  175.   /* cloned from reinit_parse_for_template */
  176.   tmpl->filename = input_filename;
  177.   tmpl->lineno = lineno;
  178.   tmpl->parm_vec = d1;          /* [eichin:19911015.2306EST] */
  179.  
  180. #ifdef DEBUG_CP_BINDING_LEVELS
  181.   indent_to (stderr, debug_bindings_indentation);
  182.   fprintf (stderr, "end_template_decl");
  183.   debug_bindings_indentation += 4;
  184. #endif
  185.  
  186.   if (d2 == NULL_TREE || d2 == error_mark_node)
  187.     {
  188.       decl = 0;
  189.       goto lose;
  190.     }
  191.  
  192.   if (is_class)
  193.     {
  194.       decl = build_lang_decl (TEMPLATE_DECL, d2, NULL_TREE);
  195.     }
  196.   else
  197.     {
  198.       if (TREE_CODE (d2) == TEMPLATE_DECL)
  199.     decl = d2;
  200.       else
  201.     {
  202.       /* Class destructor templates and operator templates are
  203.          slipping past as non-template nodes.  Process them here, since
  204.          I haven't figured out where to catch them earlier.  I could
  205.          go do that, but it's a choice between getting that done and
  206.          staying only N months behind schedule.  Sorry....  */
  207.       enum tree_code code;
  208.       my_friendly_assert (TREE_CODE (d2) == CALL_EXPR, 263);
  209.       code = TREE_CODE (TREE_OPERAND (d2, 0));
  210.       my_friendly_assert (code == BIT_NOT_EXPR
  211.           || code == OP_IDENTIFIER
  212.           || code == SCOPE_REF, 264);
  213.       d2 = grokdeclarator (d2, NULL_TREE, MEMFUNCDEF, 0, NULL_TREE);
  214.       decl = build_lang_decl (TEMPLATE_DECL, DECL_NAME (d2),
  215.                   TREE_TYPE (d2));
  216.       DECL_TEMPLATE_RESULT (decl) = d2;
  217.       DECL_CONTEXT (decl) = DECL_CONTEXT (d2);
  218.       DECL_CLASS_CONTEXT (decl) = DECL_CLASS_CONTEXT (d2);
  219.       DECL_NAME (decl) = DECL_NAME (d2);
  220.       TREE_TYPE (decl) = TREE_TYPE (d2);
  221.       TREE_PUBLIC (decl) = TREE_PUBLIC (d2) = 0;
  222.       DECL_EXTERNAL (decl) = (DECL_EXTERNAL (d2)
  223.                   && !(DECL_CLASS_CONTEXT (d2)
  224.                        && !DECL_THIS_EXTERN (d2)));
  225.     }
  226.  
  227.       /* All routines creating TEMPLATE_DECL nodes should now be using
  228.      build_lang_decl, which will have set this up already.    */
  229.       my_friendly_assert (DECL_LANG_SPECIFIC (decl) != 0, 265);
  230.  
  231.       /* @@ Somewhere, permanent allocation isn't being used.  */
  232.       if (! DECL_TEMPLATE_IS_CLASS (decl)
  233.       && TREE_CODE (DECL_TEMPLATE_RESULT (decl)) == FUNCTION_DECL)
  234.     {
  235.       tree result = DECL_TEMPLATE_RESULT (decl);
  236.       /* Will do nothing if allocation was already permanent.  */
  237.       DECL_ARGUMENTS (result) = copy_to_permanent (DECL_ARGUMENTS (result));
  238.     }
  239.  
  240.       /* If this is for a method, there's an extra binding level here.    */
  241.       if (! DECL_TEMPLATE_IS_CLASS (decl)
  242.       && DECL_CONTEXT (DECL_TEMPLATE_RESULT (decl)) != NULL_TREE)
  243.     {
  244.       /* @@ Find out where this should be getting set!  */
  245.       tree r = DECL_TEMPLATE_RESULT (decl);
  246.       if (DECL_CLASS_CONTEXT (r) == NULL_TREE)
  247.         DECL_CLASS_CONTEXT (r) = DECL_CONTEXT (r);
  248.     }
  249.     }
  250.   DECL_TEMPLATE_INFO (decl) = tmpl;
  251.   DECL_TEMPLATE_PARMS (decl) = d1;
  252.