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