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