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