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