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