Subversion Repositories tendra.SVN

Rev

Rev 2 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 7u83 1
/*
7 7u83 2
 * Copyright (c) 2002-2006 The TenDRA Project <http://www.tendra.org/>.
3
 * All rights reserved.
4
 *
5
 * Redistribution and use in source and binary forms, with or without
6
 * modification, are permitted provided that the following conditions are met:
7
 *
8
 * 1. Redistributions of source code must retain the above copyright notice,
9
 *    this list of conditions and the following disclaimer.
10
 * 2. Redistributions in binary form must reproduce the above copyright notice,
11
 *    this list of conditions and the following disclaimer in the documentation
12
 *    and/or other materials provided with the distribution.
13
 * 3. Neither the name of The TenDRA Project nor the names of its contributors
14
 *    may be used to endorse or promote products derived from this software
15
 *    without specific, prior written permission.
16
 *
17
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS
18
 * IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
19
 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
20
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR
21
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
22
 * EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
23
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
24
 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
25
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
26
 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
27
 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28
 *
29
 * $Id$
30
 */
31
/*
2 7u83 32
    		 Crown Copyright (c) 1997, 1998
7 7u83 33
 
2 7u83 34
    This TenDRA(r) Computer Program is subject to Copyright
35
    owned by the United Kingdom Secretary of State for Defence
36
    acting through the Defence Evaluation and Research Agency
37
    (DERA).  It is made available to Recipients with a
38
    royalty-free licence for its use, reproduction, transfer
39
    to other parties and amendment for any purpose not excluding
40
    product development provided that any such use et cetera
41
    shall be deemed to be acceptance of the following conditions:-
7 7u83 42
 
2 7u83 43
        (1) Its Recipients shall ensure that this Notice is
44
        reproduced upon any copies or amended versions of it;
7 7u83 45
 
2 7u83 46
        (2) Any amended version of it shall be clearly marked to
47
        show both the nature of and the organisation responsible
48
        for the relevant amendment or amendments;
7 7u83 49
 
2 7u83 50
        (3) Its onward transfer from a recipient to another
51
        party shall be deemed to be that party's acceptance of
52
        these conditions;
7 7u83 53
 
2 7u83 54
        (4) DERA gives no warranty or assurance as to its
55
        quality or suitability for any purpose and DERA accepts
56
        no liability whatsoever in relation to any use to which
57
        it may be put.
58
*/
59
 
60
 
61
#include "config.h"
62
#include "c_types.h"
63
#include "ctype_ops.h"
64
#include "etype_ops.h"
65
#include "exp_ops.h"
66
#include "hashid_ops.h"
67
#include "id_ops.h"
68
#include "inst_ops.h"
69
#include "itype_ops.h"
70
#include "member_ops.h"
71
#include "nat_ops.h"
72
#include "nspace_ops.h"
73
#include "off_ops.h"
74
#include "tok_ops.h"
75
#include "type_ops.h"
76
#include "error.h"
77
#include "catalog.h"
78
#include "option.h"
79
#include "basetype.h"
80
#include "check.h"
81
#include "chktype.h"
82
#include "class.h"
83
#include "compile.h"
84
#include "convert.h"
85
#include "copy.h"
86
#include "declare.h"
87
#include "derive.h"
88
#include "dump.h"
89
#include "expression.h"
90
#include "hash.h"
91
#include "identifier.h"
92
#include "initialise.h"
93
#include "instance.h"
94
#include "macro.h"
95
#include "namespace.h"
96
#include "option.h"
97
#include "overload.h"
98
#include "parse.h"
99
#include "predict.h"
100
#include "statement.h"
101
#include "syntax.h"
102
#include "template.h"
103
#include "tokdef.h"
104
#include "token.h"
105
#include "ustring.h"
106
 
107
 
108
/*
109
    TEMPLATE ARGUMENT HACK FLAG
110
 
111
    This flag can be set to true to indicate that the template argument
112
    hack, namely mapping '>>' to '> >' at the end of a set of template
113
    arguments, should be applied.
114
*/
115
 
7 7u83 116
static int apply_rshift_hack = 0;
2 7u83 117
 
118
 
119
/*
120
    SKIP TEMPLATE ARGUMENTS OR PARAMETERS
121
 
122
    This routine skips a set of template arguments or parameters.  It
123
    returns the sequence of preprocessing tokens enclosed between the
124
    initial '<' and the matching closing '>'.
125
*/
126
 
7 7u83 127
static PPTOKEN *
128
skip_template(IDENTIFIER id)
2 7u83 129
{
7 7u83 130
	PPTOKEN *q;
131
	LOCATION loc;
132
	int templ = 0;
133
	int angles = 1;
134
	int brackets = 0;
135
	int t = crt_lex_token;
136
	PPTOKEN *p = crt_token;
137
	loc = crt_loc;
138
	do {
139
		switch (t) {
140
		case lex_less:
141
			/* Open angle brackets */
142
			if (!brackets && templ) {
143
				angles++;
144
			}
145
			templ = 0;
146
			break;
147
		case lex_greater:
148
			/* Close angle brackets */
149
			if (!brackets) {
150
				angles--;
151
			}
152
			templ = 0;
153
			break;
154
		case lex_rshift:
155
			/* Map '>>' to '> >' */
156
			if (!brackets && apply_rshift_hack) {
157
				PPTOKEN *r = new_pptok();
158
				r->tok = lex_greater;
159
				r->next = crt_token->next;
160
				crt_token->tok = lex_greater;
161
				crt_token->next = r;
162
				angles--;
163
				report(crt_loc, ERR_temp_names_hack());
164
			}
165
			templ = 0;
166
			break;
167
		case lex_open_Hround:
168
		case lex_open_Hbrace_H1:
169
		case lex_open_Hbrace_H2:
170
		case lex_open_Hsquare_H1:
171
		case lex_open_Hsquare_H2:
172
			/* Open brackets */
173
			brackets++;
174
			templ = 0;
175
			break;
176
		case lex_close_Hround:
177
		case lex_close_Hbrace_H1:
178
		case lex_close_Hbrace_H2:
179
		case lex_close_Hsquare_H1:
180
		case lex_close_Hsquare_H2:
181
			/* Close brackets */
182
			if (brackets) {
183
				brackets--;
184
			}
185
			templ = 0;
186
			break;
187
		case lex_identifier:
188
		case lex_template:
189
		case lex_const_Hcast:
190
		case lex_static_Hcast:
191
		case lex_dynamic_Hcast:
192
		case lex_reinterpret_Hcast:
193
			/* These may be followed by '<' */
194
			/* NOT YET IMPLEMENTED - but are they? */
195
			templ = 1;
196
			break;
197
		case lex_eof:
198
			/* End of file */
199
			if (IS_NULL_id(id)) {
200
				report(loc, ERR_temp_param_eof());
201
			} else {
202
				report(loc, ERR_temp_names_eof(id));
203
			}
204
			angles = 0;
205
			break;
206
		default:
207
			/* Other tokens */
208
			templ = 0;
209
			break;
2 7u83 210
		}
7 7u83 211
		q = crt_token;
212
		t = expand_preproc(EXPAND_AHEAD);
213
	} while (angles);
214
	q->tok = lex_close_Htemplate;
215
	snip_tokens(p, q);
216
	return (p);
2 7u83 217
}
218
 
219
 
220
/*
221
    SKIP A SET OF TEMPLATE ARGUMENTS
222
 
223
    This routine skips a set of arguments for the template id.  It is
224
    entered with the current token equal to the template name preceeding
225
    the initial '<' if started is false, and equal to the initial '<'
226
    otherwise.  After skipping the current token is either still the
227
    template name or the token following the template arguments, depending
228
    on the value of started.
229
*/
230
 
7 7u83 231
PPTOKEN *
232
skip_template_args(IDENTIFIER id, int started)
2 7u83 233
{
7 7u83 234
	PPTOKEN *q;
235
	PPTOKEN *p = crt_token;
236
	int t = crt_lex_token;
237
	if (started) {
238
		/* Patch in dummy preprocessing token */
239
		q = patch_tokens(1);
240
		q->tok = t;
241
		t = lex_ignore_token;
242
		p->tok = t;
243
	}
244
	IGNORE expand_preproc(EXPAND_AHEAD);
245
	crt_lex_token = lex_open_Htemplate;
246
	crt_token->tok = lex_open_Htemplate;
247
	q = skip_template(id);
248
	crt_lex_token = t;
249
	crt_token = p;
250
	if (started) {
251
		/* Advance to following token */
252
		ADVANCE_LEXER;
253
	}
254
	return (q);
2 7u83 255
}
256
 
257
 
258
/*
259
    PARSE A SET OF TEMPLATE ARGUMENTS
260
 
261
    This routine parses the template arguments p.  Note that unlike token
262
    arguments the template argument sorts are deduced by look-ahead rather
263
    than from the template sort.
264
*/
265
 
7 7u83 266
static LIST(TOKEN)
267
parse_template_args(PPTOKEN *p)
2 7u83 268
{
7 7u83 269
	int t;
270
	PARSE_STATE st;
271
	LIST(TOKEN) args = NULL_list(TOKEN);
272
	if (p == NULL) {
273
		return (args);
274
	}
2 7u83 275
 
7 7u83 276
	/* Initialise parser */
277
	save_state(&st, 1);
278
	init_parser(p);
279
	ADVANCE_LEXER;
280
	t = crt_lex_token;
281
	if (t == lex_open_Htemplate) {
282
		/* Step over open bracket */
283
		ADVANCE_LEXER;
284
		t = crt_lex_token;
285
	}
2 7u83 286
 
7 7u83 287
	/* Scan through arguments */
288
	if (t != lex_close_Htemplate) {
289
		for (;;) {
290
			TOKEN arg;
291
			if (predict_typeid(2)) {
292
				TYPE r = NULL_type;
293
				have_type_specifier = 0;
294
				if (predict_typename()) {
295
					/* Template argument */
296
					IDENTIFIER rid = NULL_id;
297
					parse_id(&rid);
298
					MAKE_tok_class(r, rid, arg);
299
				} else {
300
					/* Type argument */
301
					parse_type(&r);
302
					MAKE_tok_type(btype_lang, r, arg);
303
				}
304
			} else {
305
				/* Expression argument */
306
				EXP e = NULL_exp;
307
				TYPE r = NULL_type;
308
				parse_exp(&e);
309
				if (!IS_NULL_exp(e)) {
310
					r = DEREF_type(exp_type(e));
311
				}
312
				MAKE_tok_exp(r, 1, e, arg);
313
			}
314
			if (have_syntax_error) {
315
				break;
316
			}
317
			CONS_tok(arg, args, args);
318
			t = crt_lex_token;
319
			if (t == lex_close_Htemplate) {
320
				break;
321
			} else if (t == lex_comma) {
322
				ADVANCE_LEXER;
323
			} else {
324
				t = lex_close_Htemplate;
325
				report(crt_loc, ERR_lex_expect(t));
326
				break;
327
			}
2 7u83 328
		}
329
	}
330
 
7 7u83 331
	/* Restore state */
332
	restore_state(&st);
333
	p = restore_parser();
334
	free_tok_list(p);
2 7u83 335
 
7 7u83 336
	/* Return result */
337
	args = REVERSE_list(args);
338
	return (args);
2 7u83 339
}
340
 
341
 
342
/*
343
    CHECK A TEMPLATE PARAMETER TYPE
344
 
345
    This routine checks the type t of the template parameter id.
346
*/
347
 
7 7u83 348
static void
349
templ_param_type(IDENTIFIER id, TYPE t)
2 7u83 350
{
7 7u83 351
	switch (TAG_type(t)) {
352
	case type_floating_tag:
353
	case type_top_tag:
354
	case type_bottom_tag:
355
		/* Illegal parameter types */
356
		report(crt_loc, ERR_temp_param_type(id, t));
357
		break;
2 7u83 358
	}
7 7u83 359
	return;
2 7u83 360
}
361
 
362
 
363
/*
364
    DEFINE A TEMPLATE PARAMETER
365
 
366
    This routine defines the template parameter id to be arg.
367
*/
368
 
7 7u83 369
static int
370
define_templ_param(IDENTIFIER id, TOKEN arg, IDENTIFIER tid, int def)
2 7u83 371
{
7 7u83 372
    int ok = 1;
373
    TOKEN sort = DEREF_tok(id_token_sort(id));
374
    unsigned tag = TAG_tok(sort);
375
    if (tag == tok_type_tag) {
2 7u83 376
	/* Type parameter */
7 7u83 377
	TYPE t;
378
	if (IS_tok_type(arg)) {
379
	    t = DEREF_type(tok_type_value(arg));
380
	    if (def) {
381
		    t = expand_type(t, 2);
382
	    }
383
	    if (!is_global_type(t)) {
2 7u83 384
		/* Type must have external linkage */
7 7u83 385
		ERROR err = ERR_temp_arg_local(t);
386
		err = concat_error(ERR_temp_arg_init(id, tid), err);
387
		report(crt_loc, err);
2 7u83 388
	    }
7 7u83 389
	    COPY_type(tok_type_value(arg), t);
2 7u83 390
	} else {
391
	    /* Non-type argument supplied */
7 7u83 392
	    t = type_error;
393
	    report(crt_loc, ERR_temp_arg_type(id, tid));
394
	    ok = 0;
2 7u83 395
	}
7 7u83 396
	COPY_type(tok_type_value(sort), t);
2 7u83 397
 
7 7u83 398
    } else if (tag == tok_exp_tag) {
2 7u83 399
	/* Expression parameter */
7 7u83 400
	EXP e;
401
	if (IS_tok_exp(arg)) {
402
	    int over = 0;
403
	    ERROR err = NULL_err;
404
	    TYPE s1 = DEREF_type(tok_exp_type(sort));
405
	    TYPE s2 = expand_type(s1, 2);
406
	    if (!EQ_type(s1, s2)) {
407
		    templ_param_type(id, s2);
408
	    }
409
	    e = DEREF_exp(tok_exp_value(arg));
410
	    if (def) {
2 7u83 411
		/* Perform conversion if necessary */
7 7u83 412
		unsigned etag = TAG_exp(e);
413
		e = convert_reference(e, REF_ASSIGN);
414
		e = expand_exp(e, 2, 0);
415
		if (IS_exp_address_mem(e)) {
2 7u83 416
		    /* Check for overloaded pointer to members */
7 7u83 417
		    EXP a = DEREF_exp(exp_address_mem_arg(e));
418
		    if (IS_exp_member(a)) {
419
			IDENTIFIER mid = DEREF_id(exp_member_id(a));
420
			if (IS_id_function_etc(mid)) {
421
			    mid = DEREF_id(id_function_etc_over(mid));
422
			    if (!IS_NULL_id(mid)) {
423
				    over = 1;
424
			    }
2 7u83 425
			}
426
		    }
427
		}
7 7u83 428
		if (IS_type_array(s2)) {
429
		    if (etag == exp_paren_tag) {
430
			    e = make_paren_exp(e);
431
		    }
432
		    e = init_array(s2, cv_none, e, 1, &err);
2 7u83 433
		} else {
7 7u83 434
		    e = init_assign(s2, cv_none, e, &err);
2 7u83 435
		}
7 7u83 436
		if (!IS_NULL_err(err)) {
437
			err = init_error(err, 0);
438
		}
2 7u83 439
	    }
7 7u83 440
	    if (is_const_exp(e, 1)) {
441
		switch (TAG_type(s2)) {
442
		    case type_integer_tag:
443
		    case type_floating_tag:
444
		    case type_top_tag:
445
		    case type_bottom_tag:
446
		    case type_enumerate_tag:
447
		    case type_token_tag:
448
		    case type_error_tag:
2 7u83 449
			/* Constants of these types are alright */
7 7u83 450
			break;
451
		    default: {
2 7u83 452
			/* Check linkage in other cases */
7 7u83 453
			EXP pa = NULL_exp;
454
			DECL_SPEC ln = find_exp_linkage(e, &pa, 0);
455
			if (ln & dspec_extern) {
2 7u83 456
			    /* External linkage */
457
			    /* EMPTY */
7 7u83 458
			} else if (ln & dspec_static) {
2 7u83 459
			    /* Internal linkage */
7 7u83 460
			    ERROR err2 = ERR_temp_arg_internal();
461
			    err = concat_error(err, err2);
2 7u83 462
			} else {
463
			    /* No linkage */
7 7u83 464
			    ERROR err2 = ERR_temp_arg_bad();
465
			    err = concat_error(err, err2);
2 7u83 466
			}
7 7u83 467
			if (over) {
2 7u83 468
			    /* Overloaded pointer to member */
7 7u83 469
			    ERROR err2 = ERR_temp_arg_over();
470
			    err = concat_error(err, err2);
2 7u83 471
			}
7 7u83 472
			break;
2 7u83 473
		    }
474
		}
475
	    } else {
7 7u83 476
		err = concat_error(err, ERR_temp_arg_const());
2 7u83 477
	    }
7 7u83 478
	    if (!IS_NULL_err(err)) {
479
		err = concat_error(ERR_temp_arg_init(id, tid), err);
480
		report(crt_loc, err);
2 7u83 481
	    }
7 7u83 482
	    COPY_type(tok_exp_type(arg), s2);
483
	    COPY_exp(tok_exp_value(arg), e);
2 7u83 484
	} else {
485
	    /* Non-expression argument supplied */
7 7u83 486
	    e = make_error_exp(0);
487
	    report(crt_loc, ERR_temp_arg_exp(id, tid));
488
	    ok = 0;
2 7u83 489
	}
7 7u83 490
	COPY_exp(tok_exp_value(sort), e);
2 7u83 491
 
492
    } else {
493
	/* Template class parameter */
7 7u83 494
	IDENTIFIER sid;
495
	if (IS_tok_class(arg)) {
496
	    sid = DEREF_id(tok_class_value(arg));
497
	    if (!IS_NULL_id(sid) && IS_id_class_name_etc(sid)) {
498
		TYPE s = DEREF_type(id_class_name_etc_defn(sid));
499
		if (!is_global_type(s)) {
2 7u83 500
		    /* Type must have external linkage */
7 7u83 501
		    ERROR err = ERR_temp_arg_local(s);
502
		    err = concat_error(ERR_temp_arg_init(id, tid), err);
503
		    report(crt_loc, err);
2 7u83 504
		}
505
	    }
7 7u83 506
	    init_template_param(id, sid);
2 7u83 507
	} else {
508
	    /* Non-template argument supplied */
7 7u83 509
	    HASHID nm = KEYWORD(lex_zzzz);
510
	    sid = DEREF_id(hashid_id(nm));
511
	    report(crt_loc, ERR_temp_arg_templ(id, tid));
512
	    ok = 0;
2 7u83 513
	}
7 7u83 514
	COPY_id(tok_class_value(sort), sid);
2 7u83 515
 
516
    }
7 7u83 517
    return (ok);
2 7u83 518
}
519
 
520
 
521
/*
522
    DEFAULT TEMPLATE ARGUMENTS FLAG
523
 
524
    This flag may be set to false to suppress template default arguments.
525
*/
526
 
7 7u83 527
int allow_templ_dargs = 1;
2 7u83 528
 
529
 
530
/*
531
    CHECK A SET OF TEMPLATE ARGUMENTS
532
 
533
    This routine checks the set of template arguments args for the template
534
    tid of sort tok.  Note that if tid is a function then there may be
535
    less arguments than parameters, in this case in_template_decl is set
536
    to indicate that certain template parameters remain unbound.
537
*/
538
 
7 7u83 539
static LIST(TOKEN)
540
check_templ_args(TOKEN tok, LIST(TOKEN) args, IDENTIFIER tid)
2 7u83 541
{
7 7u83 542
	int s;
543
	int reported = 0;
544
	LIST(TOKEN) a = args;
545
	LIST(TOKEN) b = NULL_list(TOKEN);
546
	LIST(TOKEN) d = DEREF_list(tok_templ_dargs(tok));
547
	LIST(IDENTIFIER) pids = DEREF_list(tok_templ_pids(tok));
548
	LIST(IDENTIFIER) qids = pids;
549
	if (in_template_decl && depends_on_args(args, pids, 0, 1)) {
550
		/* Be extra careful in this case */
551
		tok = expand_sort(tok, 1, 1);
552
		args = check_templ_args(tok, args, tid);
553
		return (args);
2 7u83 554
	}
7 7u83 555
	s = save_token_args(qids, NULL_list(TOKEN));
556
	if (!allow_templ_dargs)d = NULL_list(TOKEN);
557
	while (!IS_NULL_list(pids)) {
558
		TOKEN arg = NULL_tok;
559
		IDENTIFIER pid = DEREF_id(HEAD_list(pids));
560
		if (!IS_NULL_list(a)) {
561
			/* Use argument from list */
562
			arg = DEREF_tok(HEAD_list(a));
563
		} else if (!IS_NULL_list(d)) {
564
			/* Use default argument */
565
			arg = DEREF_tok(HEAD_list(d));
566
			if (!IS_NULL_tok(arg)) {
567
				/* Add copy to list of arguments */
568
				arg = expand_sort(arg, -1, 1);
569
				CONS_tok(arg, b, b);
570
			}
2 7u83 571
		}
7 7u83 572
		if (IS_NULL_tok(arg)) {
573
			/* Not enough arguments */
574
			if (!reported) {
575
				if (IS_id_function_etc(tid)) {
576
					/* Allow for argument deduction */
577
					a = NULL_list(TOKEN);
578
					in_template_decl++;
579
					break;
580
				}
581
				report(crt_loc, ERR_temp_arg_less(tid));
582
				reported = 1;
583
			}
584
			arg = DEREF_tok(id_token_sort(pid));
585
			IGNORE is_bound_tok(arg, 1);
586
			arg = expand_sort(arg, 2, 1);
587
			CONS_tok(arg, b, b);
588
		}
589
		IGNORE define_templ_param(pid, arg, tid, 1);
590
		if (!IS_NULL_list(d)) {
591
			d = TAIL_list(d);
592
		}
593
		if (!IS_NULL_list(a)) {
594
			a = TAIL_list(a);
595
		}
596
		pids = TAIL_list(pids);
2 7u83 597
	}
7 7u83 598
	if (!IS_NULL_list(a)) {
599
		/* Too many arguments */
600
		report(crt_loc, ERR_temp_arg_more(tid));
601
	}
602
	if (!IS_NULL_list(b)) {
603
		/* Add default arguments to list */
604
		b = REVERSE_list(b);
605
		args = APPEND_list(args, b);
606
	}
607
	restore_token_args(qids, s);
608
	return (args);
2 7u83 609
}
610
 
611
 
612
/*
613
    CHECK A SET OF DEDUCED TEMPLATE ARGUMENTS
614
 
615
    This routine checks the deduced template arguments args for the
616
    template tid with parameters pids.
617
*/
618
 
7 7u83 619
void
620
check_deduced_args(IDENTIFIER tid, LIST(IDENTIFIER) pids, LIST(TOKEN) args)
2 7u83 621
{
7 7u83 622
	while (!IS_NULL_list(pids) && !IS_NULL_list(args)) {
623
		IDENTIFIER pid = DEREF_id(HEAD_list(pids));
624
		TOKEN arg = DEREF_tok(HEAD_list(args));
625
		IGNORE define_templ_param(pid, arg, tid, 0);
626
		args = TAIL_list(args);
627
		pids = TAIL_list(pids);
628
	}
629
	return;
2 7u83 630
}
631
 
632
 
633
/*
634
    DOES A SET OF TEMPLATE ARGUMENTS MATCH A SORT?
635
 
636
    This routine checks whether the template arguments args form a match
637
    for an initial segment of the template sort tok.
638
*/
639
 
7 7u83 640
static int
641
match_template_args(TOKEN tok, LIST(TOKEN) args)
2 7u83 642
{
7 7u83 643
	LIST(IDENTIFIER) pids = DEREF_list(tok_templ_pids(tok));
644
	while (!IS_NULL_list(pids) && !IS_NULL_list(args)) {
645
		IDENTIFIER pid = DEREF_id(HEAD_list(pids));
646
		TOKEN sort = DEREF_tok(id_token_sort(pid));
647
		TOKEN arg = DEREF_tok(HEAD_list(args));
648
		if (TAG_tok(arg)!= TAG_tok(sort)) {
649
			/* Argument sorts do not match */
650
			return (0);
651
		}
652
		args = TAIL_list(args);
653
		pids = TAIL_list(pids);
2 7u83 654
	}
7 7u83 655
	if (!IS_NULL_list(args)) {
656
		/* Too many arguments */
657
		return (0);
658
	}
659
	return (1);
2 7u83 660
}
661
 
662
 
663
/*
664
    APPLY A FUNCTION TEMPLATE
665
 
666
    This routine applies the function template id to the arguments args.
667
    Because id may comprise several overloaded template functions it is
668
    necessary to check each to determine whether the template parameter
669
    sorts match the argument sorts.  If more than one match is found the
670
    result is an overloaded function.
671
*/
672
 
7 7u83 673
static IDENTIFIER
674
apply_func_templ(IDENTIFIER id, LIST(TOKEN) args, int def)
2 7u83 675
{
7 7u83 676
	int force = 0;
677
	IDENTIFIER tid = NULL_id;
678
	do {
679
		/* Build up result */
680
		IDENTIFIER fid = id;
681
		while (!IS_NULL_id(fid)) {
682
			TYPE t = DEREF_type(id_function_etc_type(fid));
683
			if (IS_type_templ(t)) {
684
				TOKEN sort = DEREF_tok(type_templ_sort(t));
685
				if (force || match_template_args(sort, args)) {
686
					/* Argument sorts match */
687
					IDENTIFIER sid = tid;
688
					int td = in_template_decl;
689
					args =
690
					    check_templ_args(sort, args, fid);
691
					tid = instance_func(fid, args, 0, def);
692
					COPY_id(id_function_etc_over(tid), sid);
693
					in_template_decl = td;
694
				}
695
			}
696
			fid = DEREF_id(id_function_etc_over(fid));
2 7u83 697
		}
7 7u83 698
		if (force) {
699
			/* Should have bound arguments by now */
700
			if (IS_NULL_id(tid)) {
701
				tid = id;
702
			}
703
		} else {
704
			/* Try again allowing for mismatches */
705
			force = 1;
706
		}
707
	} while (IS_NULL_id(tid));
708
	return (tid);
2 7u83 709
}
710
 
711
 
712
/*
713
    APPLY A TYPEDEF TEMPLATE
714
 
715
    This routine applies the typedef template id to the arguments args.
716
*/
717
 
7 7u83 718
static TYPE
719
apply_typedef_templ(IDENTIFIER id, LIST(TOKEN) args)
2 7u83 720
{
7 7u83 721
	TYPE t = DEREF_type(id_class_name_etc_defn(id));
722
	if (IS_type_templ(t)) {
723
		int td = in_template_decl;
724
		TOKEN sort = DEREF_tok(type_templ_sort(t));
725
		LIST(IDENTIFIER) pids = DEREF_list(tok_templ_pids(sort));
726
		args = check_templ_args(sort, args, id);
727
		t = DEREF_type(type_templ_defn(t));
728
		if (is_templ_type(t)) {
729
			/* Template template parameter */
730
			IDENTIFIER tid = DEREF_id(type_token_tok(t));
731
			MAKE_type_token(cv_none, tid, args, t);
732
		} else {
733
			/* Expand type definition */
734
			int d = save_token_args(pids, args);
735
			TYPE s = expand_type(t, 1);
736
			if (EQ_type(s, t)) {
737
				s = copy_typedef(id, t, cv_none);
738
			}
739
			restore_token_args(pids, d);
740
			t = s;
741
		}
742
		in_template_decl = td;
2 7u83 743
	} else {
7 7u83 744
		report(crt_loc, ERR_temp_names_not(id));
745
		t = copy_typedef(id, t, cv_none);
2 7u83 746
	}
7 7u83 747
	return (t);
2 7u83 748
}
749
 
750
 
751
/*
752
    APPLY A CLASS TEMPLATE
753
 
754
    This routine applies the class template id to the arguments args.
755
*/
756
 
7 7u83 757
static IDENTIFIER
758
apply_type_templ(IDENTIFIER id, LIST(TOKEN) args, int def)
2 7u83 759
{
7 7u83 760
	if (IS_id_class_name(id)) {
761
		/* Class template */
762
		TYPE t;
763
		DECL_SPEC ds = DEREF_dspec(id_storage(id));
764
		if (ds & dspec_implicit) {
765
			/* Allow for nested calls */
766
			IDENTIFIER tid = find_template(id, 0);
767
			if (!IS_NULL_id(tid)) {
768
				id = tid;
769
			}
770
		}
771
		t = DEREF_type(id_class_name_etc_defn(id));
772
		if (IS_type_templ(t)) {
773
			int td = in_template_decl;
774
			TOKEN sort = DEREF_tok(type_templ_sort(t));
775
			args = check_templ_args(sort, args, id);
776
			id = instance_type(id, args, 0, def);
777
			in_template_decl = td;
778
		} else {
779
			report(crt_loc, ERR_temp_names_not(id));
780
		}
2 7u83 781
	} else {
7 7u83 782
		/* Type alias template */
783
		TYPE t = apply_typedef_templ(id, args);
784
		if (IS_type_compound(t)) {
785
			CLASS_TYPE ct = DEREF_ctype(type_compound_defn(t));
786
			complete_class(ct, def);
787
			id = DEREF_id(ctype_name(ct));
788
		} else {
789
			HASHID nm = DEREF_hashid(id_name(id));
790
			NAMESPACE ns = DEREF_nspace(id_parent(id));
791
			decl_loc = crt_loc;
792
			id = make_typedef(ns, nm, t, dspec_none);
793
		}
2 7u83 794
	}
7 7u83 795
	return (id);
2 7u83 796
}
797
 
798
 
799
/*
800
    APPLY A TEMPLATE TO A SET OF ARGUMENTS
801
 
802
    This routine applies the template id to the arguments args.
803
*/
804
 
7 7u83 805
IDENTIFIER
806
apply_template(IDENTIFIER id, LIST(TOKEN) args, int def, int force)
2 7u83 807
{
7 7u83 808
	DECL_SPEC ds = DEREF_dspec(id_storage(id));
809
	if (ds & dspec_template) {
810
		if (IS_id_function_etc(id)) {
811
			id = apply_func_templ(id, args, def);
812
		} else {
813
			id = apply_type_templ(id, args, def);
814
		}
2 7u83 815
	} else {
7 7u83 816
		TYPE form;
817
		MAKE_type_token(cv_none, id, args, form);
818
		if (force || is_templ_depend(form)) {
819
			/* Dummy template identifier */
820
			HASHID nm = DEREF_hashid(id_name(id));
821
			NAMESPACE ns = DEREF_nspace(id_parent(id));
822
			MAKE_id_undef(nm, dspec_none, ns, crt_loc, id);
823
			COPY_type(id_undef_form(id), form);
824
		} else {
825
			report(crt_loc, ERR_temp_names_not(id));
826
		}
2 7u83 827
	}
7 7u83 828
	return (id);
2 7u83 829
}
830
 
831
 
832
/*
833
    PARSE A SET OF NON-TYPE TEMPLATE ARGUMENTS
834
 
835
    This routine parses the template arguments p for the non-class template
836
    id.  This includes both template functions and dummy template identifiers
837
    such as in 'ptr->template id < ... >'.
838
*/
839
 
7 7u83 840
IDENTIFIER
841
parse_id_template(IDENTIFIER id, PPTOKEN *p, int def)
2 7u83 842
{
7 7u83 843
	LIST(TOKEN) args = parse_template_args(p);
844
	id = apply_template(id, args, def, 1);
845
	return (id);
2 7u83 846
}
847
 
848
 
849
/*
850
    PARSE A SET OF TYPE TEMPLATE ARGUMENTS
851
 
852
    This routine parses the template arguments p for the class template
853
    id.  def is passed to instance_type.
854
*/
855
 
7 7u83 856
IDENTIFIER
857
parse_type_template(IDENTIFIER id, PPTOKEN *p, int def)
2 7u83 858
{
7 7u83 859
	LIST(TOKEN) args = parse_template_args(p);
860
	id = apply_type_templ(id, args, def);
861
	return (id);
2 7u83 862
}
863
 
864
 
865
/*
866
    PARSE A SET OF TYPEDEF TEMPLATE ARGUMENTS
867
 
868
    This routine parses the template arguments p for the typedef
869
    template id.
870
*/
871
 
7 7u83 872
TYPE
873
parse_typedef_templ(IDENTIFIER id, PPTOKEN *p)
2 7u83 874
{
7 7u83 875
	LIST(TOKEN) args = parse_template_args(p);
876
	TYPE t = apply_typedef_templ(id, args);
877
	return (t);
2 7u83 878
}
879
 
880
 
881
/*
882
    DEDUCE A TEMPLATE TYPE
883
 
884
    This routine deduces the arguments for the template type id called
885
    without arguments.  Within a template class definition the template
886
    name gives the the template applied to the current arguments.
887
    Otherwise template declarations and definitions (for which used is
888
    false) are allowed but other instances are not.
889
*/
890
 
7 7u83 891
TYPE
892
deduce_type_template(IDENTIFIER id, int used)
2 7u83 893
{
7 7u83 894
	TYPE t = DEREF_type(id_class_name_etc_defn(id));
895
	if (used) {
896
		TYPE s = t;
897
		while (IS_type_templ(s)) {
898
			s = DEREF_type(type_templ_defn(s));
899
		}
900
		if (IS_type_compound(s)) {
901
			CLASS_TYPE cs = DEREF_ctype(type_compound_defn(s));
902
			if (defining_class(cs)) {
903
				/* In class definition */
904
				return (s);
905
			}
906
		}
907
		report(crt_loc, ERR_temp_local_not(t));
2 7u83 908
	}
7 7u83 909
	return (t);
2 7u83 910
}
911
 
912
 
913
/*
914
    CURRENT TEMPLATE NAMESPACE
915
 
916
    This variable is used within a template declaration to hold the
917
    namespace in which the template parameters are declared.
918
*/
919
 
7 7u83 920
NAMESPACE templ_namespace = NULL_nspace;
2 7u83 921
 
922
 
923
/*
924
    LIST OF ALL TEMPLATE PARAMETERS
925
 
926
    These lists are dummy values representing the lists of all template
927
    parameters and all template or token parameters.
928
*/
929
 
7 7u83 930
LIST(IDENTIFIER) any_templ_param = NULL_list(IDENTIFIER);
931
LIST(IDENTIFIER) any_token_param = NULL_list(IDENTIFIER);
2 7u83 932
 
933
 
934
/*
935
    PARSE A SET OF TEMPLATE PARAMETERS
936
 
937
    This routine parses a set of template parameters.  It is entered after
938
    the initial 'template' has been read.  ex is true if this was preceded
939
    by 'export'.
940
*/
941
 
7 7u83 942
TOKEN
943
template_params(int ex)
2 7u83 944
{
7 7u83 945
	int t;
946
	TOKEN tok;
947
	PPTOKEN *p;
948
	NAMESPACE ns;
949
	LOCATION loc;
950
	PARSE_STATE s;
951
	int have_darg = 0;
952
	unsigned long npars = 0;
953
	DECL_SPEC use = dspec_none;
954
	LIST(TOKEN) dargs = NULL_list(TOKEN);
955
	LIST(IDENTIFIER) pids = NULL_list(IDENTIFIER);
2 7u83 956
 
7 7u83 957
	/* Can't have template declarations inside blocks */
958
	if (in_function_defn) {
959
		report(crt_loc, ERR_temp_decl_scope());
960
	} else if (in_class_defn && really_in_function_defn) {
961
		report(crt_loc, ERR_temp_mem_local());
962
	}
2 7u83 963
 
7 7u83 964
	/* Mark exported templates */
965
	if (ex || option(OPT_templ_export))use |= dspec_extern;
2 7u83 966
 
7 7u83 967
	/* Check for initial '<' */
968
	if (crt_lex_token != lex_less) {
969
		/* Explicit instantiation */
970
		MAKE_tok_templ(use, NULL_nspace, tok);
971
		return (tok);
972
	}
2 7u83 973
 
7 7u83 974
	/* Start template parameter namespace */
975
	ns = make_namespace(NULL_id, nspace_templ_tag, 0);
976
	push_namespace(ns);
977
	in_template_decl++;
978
	record_location++;
2 7u83 979
 
7 7u83 980
	/* Prepare to parse template parameters */
981
	ADVANCE_LEXER;
982
	loc = crt_loc;
983
	p = skip_template(NULL_id);
984
	save_state(&s, 1);
985
	crt_loc = loc;
986
	init_parser(p);
987
	ADVANCE_LEXER;
988
	t = crt_lex_token;
2 7u83 989
 
7 7u83 990
	/* Parse template parameters */
991
	if (t != lex_close_Htemplate) {
992
		for (;;) {
993
			/* Declare parameter */
994
			IDENTIFIER pid = NULL_id;
995
			decl_loc = crt_loc;
996
			if (predict_template()) {
997
				/* Type parameter */
998
				parse_type_param(&pid);
2 7u83 999
			} else {
7 7u83 1000
				/* Expression parameter */
1001
				if (crt_lex_token == lex_typename) {
1002
					/* Replace 'typename' by 'class' */
1003
					crt_lex_token = lex_class;
1004
				}
1005
				parse_param(NULL_type, CONTEXT_TEMPL_PARAM,
1006
					    &pid);
2 7u83 1007
			}
1008
 
7 7u83 1009
			/* Add parameter to list */
1010
			if (!IS_NULL_id(pid)) {
1011
				DECL_SPEC ds = DEREF_dspec(id_storage(pid));
1012
				ds |= dspec_template;
1013
				COPY_dspec(id_storage(pid), ds);
1014
				if (do_dump) {
1015
					dump_token_param(pid);
1016
				}
1017
				tok = DEREF_tok(id_token_sort(pid));
1018
				switch (TAG_tok(tok)) {
1019
				case tok_exp_tag: {
1020
					/* Expression parameter */
1021
					int c;
1022
					EXP e;
1023
					TYPE r;
1024
					DECONS_tok_exp(r, c, e, tok);
1025
					templ_param_type(pid, r);
1026
					if (IS_NULL_exp(e)) {
1027
						if (have_darg) {
1028
							have_darg = 2;
1029
						}
1030
						tok = NULL_tok;
1031
					} else {
1032
						COPY_exp(tok_exp_value(tok),
1033
							 NULL_exp);
1034
						MAKE_tok_exp(r, c, e, tok);
1035
						have_darg = 1;
1036
					}
1037
					break;
1038
				}
1039
				case tok_type_tag: {
1040
					/* Type parameter */
1041
					TYPE r = DEREF_type(tok_type_value(tok));
1042
					if (IS_NULL_type(r)) {
1043
						if (have_darg) {
1044
							have_darg = 2;
1045
						}
1046
						tok = NULL_tok;
1047
					} else {
1048
						COPY_type(tok_type_value(tok),
1049
							  NULL_type);
1050
						MAKE_tok_type(btype_lang, r,
1051
							      tok);
1052
						have_darg = 1;
1053
					}
1054
					break;
1055
				}
1056
				case tok_class_tag: {
1057
					/* Template class parameter */
1058
					TYPE r =
1059
					    DEREF_type(tok_class_type(tok));
1060
					IDENTIFIER cid =
1061
					    DEREF_id(tok_class_value(tok));
1062
					if (IS_NULL_id(cid)) {
1063
						if (have_darg) {
1064
							have_darg = 2;
1065
						}
1066
						tok = NULL_tok;
1067
					} else {
1068
						COPY_id(tok_class_value(tok),
1069
							NULL_id);
1070
						MAKE_tok_class(r, cid, tok);
1071
						have_darg = 1;
1072
					}
1073
					break;
1074
				}
1075
				default:
1076
					/* Shouldn't occur */
1077
					tok = NULL_tok;
1078
					break;
1079
				}
1080
				if (have_darg == 2) {
1081
					/* Missing default argument */
1082
					report(crt_loc,
1083
					       ERR_temp_param_default(pid));
1084
				}
1085
				CONS_tok(tok, dargs, dargs);
1086
				CONS_id(pid, pids, pids);
1087
				npars++;
2 7u83 1088
			}
1089
 
7 7u83 1090
			/* Check for next parameter */
1091
			t = crt_lex_token;
1092
			if (t == lex_close_Htemplate) {
1093
				/* End of parameter list */
1094
				break;
1095
			} else if (t == lex_comma) {
1096
				/* Move on to next parameter */
1097
				ADVANCE_LEXER;
2 7u83 1098
			} else {
7 7u83 1099
				/* Syntax error */
1100
				if (!have_syntax_error) {
1101
					ERROR err = ERR_lex_parse(crt_token);
1102
					report(crt_loc, err);
1103
				}
1104
				break;
2 7u83 1105
			}
1106
		}
1107
	}
1108
 
7 7u83 1109
	/* Restore parser */
1110
	restore_state(&s);
1111
	p = restore_parser();
1112
	free_tok_list(p);
2 7u83 1113
 
7 7u83 1114
	/* Construct the result */
1115
	MAKE_tok_templ(use, crt_namespace, tok);
1116
	if (IS_NULL_list(pids)) {
1117
		/* Explicit specialisation */
1118
		IGNORE pop_namespace();
1119
		in_template_decl--;
1120
		record_location--;
1121
	} else {
1122
		IGNORE check_value(OPT_VAL_template_pars, npars);
1123
		pids = REVERSE_list(pids);
1124
		dargs = REVERSE_list(dargs);
1125
		COPY_list(tok_templ_pids(tok), pids);
1126
		COPY_list(tok_templ_dargs(tok), dargs);
1127
		set_proc_token(pids);
1128
		templ_namespace = ns;
1129
	}
1130
	return (tok);
2 7u83 1131
}
1132
 
1133
 
1134
/*
1135
    CREATE A TEMPLATE TYPE QUALIFIER
1136
 
1137
    This routine creates a template type qualifier from the template
1138
    parameters tok and the type t.  It also terminates the template
1139
    parameter namespace while leaving its names in scope.
1140
*/
1141
 
7 7u83 1142
TYPE
1143
make_template_type(TOKEN tok, TYPE t)
2 7u83 1144
{
7 7u83 1145
	TYPE s;
1146
	LIST(IDENTIFIER) pids = DEREF_list(tok_templ_pids(tok));
1147
	if (!IS_NULL_list(pids)) {
1148
		/* Remove template parameters */
1149
		IGNORE restore_namespace();
1150
	}
1151
	MAKE_type_templ(cv_none, tok, NULL_type, 0, s);
1152
	if (!IS_NULL_type(t)) {
1153
		unsigned tag = TAG_type(t);
1154
		NAMESPACE ns = DEREF_nspace(tok_templ_pars(tok));
1155
		if (IS_NULL_nspace(ns)) {
1156
			/* Can't have 'template template < ... >' */
1157
			report(crt_loc, ERR_temp_explicit_templ());
1158
			s = NULL_type;
1159
		} else {
1160
			if (tag == type_templ_tag) {
1161
				tok = DEREF_tok(type_templ_sort(t));
1162
				ns = DEREF_nspace(tok_templ_pars(tok));
1163
				if (IS_NULL_nspace(ns)) {
1164
					/* Can't have 'template < ... >
1165
					 * template' */
1166
					report(crt_loc,
1167
					       ERR_temp_explicit_templ());
1168
					t = DEREF_type(type_templ_defn(t));
1169
					tag = TAG_type(t);
1170
				}
1171
			}
2 7u83 1172
		}
7 7u83 1173
		if (tag == type_func_tag) {
1174
			/* Ignore linkage specifiers */
1175
			CV_SPEC cv = DEREF_cv(type_func_mqual(t));
1176
			cv &= ~cv_language;
1177
			cv |= cv_cpp;
1178
			COPY_cv(type_func_mqual(t), cv);
1179
		}
1180
		s = inject_pre_type(t, s, 0);
2 7u83 1181
	}
7 7u83 1182
	return (s);
2 7u83 1183
}
1184
 
1185
 
1186
/*
1187
    END A TEMPLATE DECLARATION
1188
 
1189
    This routine ends a template declaration.  It removes the names from
1190
    the template parameter namespace from scope.
1191
*/
1192
 
7 7u83 1193
void
1194
end_template(TOKEN tok)
2 7u83 1195
{
7 7u83 1196
	LIST(IDENTIFIER) pids = DEREF_list(tok_templ_pids(tok));
1197
	if (!IS_NULL_list(pids)) {
1198
		remove_namespace();
1199
		templ_namespace = NULL_nspace;
1200
		in_template_decl--;
1201
		record_location--;
1202
		if (in_template_decl) {
1203
			/* Find enclosing template namespace */
1204
			LIST(NAMESPACE) lns = LIST_stack(namespace_stack);
1205
			while (!IS_NULL_list(lns)) {
1206
				NAMESPACE ns = DEREF_nspace(HEAD_list(lns));
1207
				if (IS_nspace_templ(ns)) {
1208
					templ_namespace = ns;
1209
					break;
1210
				}
1211
				lns = TAIL_list(lns);
1212
			}
2 7u83 1213
		}
1214
	}
7 7u83 1215
	if (!in_template_decl) {
1216
		clear_templates(1);
1217
	}
1218
	return;
2 7u83 1219
}
1220
 
1221
 
1222
/*
1223
    CHECK A TEMPLATE DECLARATOR
1224
 
1225
    This routine is called whenever the template type t is used to qualify
1226
    a class definition or a function declarator.
1227
*/
1228
 
7 7u83 1229
void
1230
template_decl(TYPE t)
2 7u83 1231
{
7 7u83 1232
	while (!IS_NULL_type(t) && IS_type_templ(t)) {
1233
		TOKEN sort = DEREF_tok(type_templ_sort(t));
1234
		DECL_SPEC ds = DEREF_dspec(tok_templ_usage(sort));
1235
		if (ds & dspec_used) {
1236
			/* Already used */
1237
			report(crt_loc, ERR_temp_decl_one());
1238
		}
1239
		ds |= dspec_used;
1240
		COPY_dspec(tok_templ_usage(sort), ds);
1241
		t = DEREF_type(type_templ_defn(t));
2 7u83 1242
	}
7 7u83 1243
	return;
2 7u83 1244
}
1245
 
1246
 
1247
/*
1248
    EXPORT A SET OF TEMPLATE INSTANCES
1249
 
1250
    This routine exports the instances associated with the template type t.
1251
    It returns the non-template component of t.
1252
*/
1253
 
7 7u83 1254
static TYPE
1255
export_instances(TYPE t, int def)
2 7u83 1256
{
7 7u83 1257
	while (IS_type_templ(t)) {
1258
		TOKEN sort = DEREF_tok(type_templ_sort(t));
1259
		INSTANCE apps = DEREF_inst(tok_templ_apps(sort));
1260
		while (!IS_NULL_inst(apps)) {
1261
			DECL_SPEC acc = DEREF_dspec(inst_templ_access(apps));
1262
			if (!(acc & (dspec_alias | dspec_main))) {
1263
				IDENTIFIER id = DEREF_id(inst_templ_id(apps));
1264
				export_template(id, def);
1265
			}
1266
			acc |= dspec_typedef;
1267
			COPY_dspec(inst_templ_access(apps), acc);
1268
			apps = DEREF_inst(inst_next(apps));
1269
		}
1270
		t = DEREF_type(type_templ_defn(t));
2 7u83 1271
	}
7 7u83 1272
	return (t);
2 7u83 1273
}
1274
 
1275
 
1276
/*
1277
    EXPORT A TEMPLATE IDENTIFIER
1278
 
1279
    This routine marks the template identifier id as having been exported.
1280
    def is 2 for the first explicit declaration of a template, 1 for a
1281
    redeclaration and 0 otherwise.
1282
*/
1283
 
7 7u83 1284
void export_template(IDENTIFIER id, int def)
2 7u83 1285
{
7 7u83 1286
	DECL_SPEC ds = DEREF_dspec(id_storage(id));
1287
	if (ds & (dspec_inherit | dspec_implicit)) {
1288
		return;
1289
	}
1290
	if (ds & (dspec_inline | dspec_static)) {
1291
		return;
1292
	}
1293
	if (def == 0 && (ds & dspec_typedef)) {
1294
		/* Already exported */
1295
		return;
1296
	}
1297
	ds |= dspec_typedef;
1298
	COPY_dspec(id_storage(id), ds);
1299
	if (def == 2 && !has_linkage(id)) {
1300
		/* Can't export anonymous identifiers */
1301
		report(crt_loc, ERR_temp_decl_export(id));
1302
	}
1303
	switch (TAG_id(id)) {
1304
	case id_class_name_tag:
1305
	case id_class_alias_tag: {
1306
		/* Template classes */
1307
		TYPE t = DEREF_type(id_class_name_etc_defn(id));
1308
		t = export_instances(t, def);
1309
		if (IS_type_compound(t)) {
1310
			CLASS_TYPE ct = DEREF_ctype(type_compound_defn(t));
1311
			IDENTIFIER cid = DEREF_id(ctype_name(ct));
1312
			if (EQ_id(id, cid)) {
1313
				NAMESPACE ns = DEREF_nspace(ctype_member(ct));
1314
				MEMBER mem =
1315
				    DEREF_member(nspace_ctype_first(ns));
1316
				while (!IS_NULL_member(mem)) {
1317
					/* Scan through class members */
1318
					IDENTIFIER pid =
1319
					    DEREF_id(member_id(mem));
1320
					IDENTIFIER qid =
1321
					    DEREF_id(member_alt(mem));
1322
					if (!IS_NULL_id(pid)) {
1323
						export_template(pid, def);
1324
					}
1325
					if (!IS_NULL_id(qid) &&
1326
					    !EQ_id(qid, pid)) {
1327
						export_template(qid, def);
1328
					}
1329
					mem = DEREF_member(member_next(mem));
1330
				}
2 7u83 1331
			}
1332
		}
7 7u83 1333
		break;
2 7u83 1334
	}
7 7u83 1335
	case id_function_tag:
1336
	case id_mem_func_tag:
1337
	case id_stat_mem_func_tag: {
1338
		/* Template functions */
1339
		TYPE t = DEREF_type(id_function_etc_type(id));
1340
		IGNORE export_instances(t, def);
1341
		update_tag(id, 0);
1342
		break;
2 7u83 1343
	}
7 7u83 1344
	case id_stat_member_tag:
1345
		/* Static data members */
1346
		update_tag(id, 0);
1347
		break;
2 7u83 1348
	}
7 7u83 1349
	return;
2 7u83 1350
}
1351
 
1352
 
1353
/*
1354
    HAS A TEMPLATE BEEN EXPORTED?
1355
 
1356
    This routine checks whether the template instance id has been exported.
1357
*/
1358
 
7 7u83 1359
int
1360
is_exported(IDENTIFIER id)
2 7u83 1361
{
7 7u83 1362
	TYPE form;
1363
	int def = 0;
1364
	DECL_SPEC ds = DEREF_dspec(id_storage(id));
1365
	if (ds & dspec_typedef) {
1366
		return (1);
2 7u83 1367
	}
7 7u83 1368
	form = find_form(id, &def);
1369
	if (!IS_NULL_type(form) && IS_type_instance(form)) {
1370
		IDENTIFIER tid = DEREF_id(type_instance_id(form));
1371
		ds = DEREF_dspec(id_storage(tid));
1372
		if (ds & dspec_typedef) {
1373
			export_template(id, 0);
1374
			return (1);
1375
		}
1376
	}
1377
	return (0);
2 7u83 1378
}
1379
 
1380
 
1381
/*
1382
    CREATE A SET OF PRIMARY TEMPLATE ARGUMENTS
1383
 
1384
    This routine creates a list of primary template arguments corresponding
1385
    to the template parameters pids.
1386
*/
1387
 
7 7u83 1388
LIST(TOKEN)
1389
make_primary_args(LIST(IDENTIFIER) pids)
2 7u83 1390
{
7 7u83 1391
	LIST(TOKEN) args = NULL_list(TOKEN);
1392
	while (!IS_NULL_list(pids)) {
1393
		IDENTIFIER pid = DEREF_id(HEAD_list(pids));
1394
		TOKEN arg = apply_token(pid, NULL_list(TOKEN));
1395
		CONS_tok(arg, args, args);
1396
		pids = TAIL_list(pids);
1397
	}
1398
	return (REVERSE_list(args));
2 7u83 1399
}
1400
 
1401
 
1402
/*
1403
    CHECK A SET OF PRIMARY TEMPLATE PARAMETERS
1404
 
1405
    This routine checks the template parameters given by the type t for
1406
    the declaration of the primary template class or function id.  It
1407
    returns the non-template component of t.
1408
*/
1409
 
7 7u83 1410
TYPE
1411
check_templ_params(TYPE t, IDENTIFIER id)
2 7u83 1412
{
7 7u83 1413
	int depth = 0;
1414
	unsigned tag = TAG_type(t);
1415
	while (tag == type_templ_tag) {
1416
		TOKEN sort = DEREF_tok(type_templ_sort(t));
1417
		NAMESPACE ns = DEREF_nspace(tok_templ_pars(sort));
1418
		DECL_SPEC use = DEREF_dspec(tok_templ_usage(sort));
1419
		LIST(IDENTIFIER) pids = DEREF_list(tok_templ_pids(sort));
1420
		TYPE s = DEREF_type(type_templ_defn(t));
1421
		tag = TAG_type(s);
1422
		if (IS_NULL_list(pids)) {
1423
			/* No template parameters */
1424
			if (IS_NULL_nspace(ns)) {
1425
				/* Explicit instantiation */
1426
				report(decl_loc, ERR_temp_explicit_bad(id));
1427
			} else {
1428
				/* Specialisation */
1429
				report(decl_loc, ERR_temp_param_none(id));
1430
				COPY_id(nspace_name(ns), id);
1431
			}
1432
		} else {
1433
			/* Create primary specialisation */
1434
			TYPE form;
1435
			TYPE prim;
1436
			INSTANCE apps;
1437
			DECL_SPEC ds = (dspec_template | dspec_extern |
1438
					dspec_main);
1439
			LIST(TOKEN) args = make_primary_args(pids);
1440
			MAKE_type_token(cv_none, id, args, form);
1441
			MAKE_type_templ(cv_none, sort, form, 1, prim);
1442
			apps = DEREF_inst(tok_templ_apps(sort));
1443
			MAKE_inst_templ(prim, apps, id, ds, all_instances,
1444
					apps);
1445
			COPY_inst(type_token_app(form), apps);
1446
			COPY_inst(tok_templ_apps(sort), apps);
1447
			all_instances = apps;
1448
			if (tag == type_compound_tag) {
1449
				CLASS_TYPE cs =
1450
				    DEREF_ctype(type_compound_defn(s));
1451
				COPY_type(ctype_form(cs), form);
1452
			} else if (tag == type_func_tag) {
1453
				/* Can't have default arguments with function */
1454
				if (check_templ_dargs(t)) {
1455
					report(decl_loc, ERR_temp_param_func());
1456
				}
1457
			}
1458
			COPY_id(nspace_name(ns), id);
2 7u83 1459
		}
7 7u83 1460
		if (use & dspec_extern) {
1461
			export_template(id, 2);
1462
		}
1463
		depth++;
1464
		t = s;
2 7u83 1465
	}
7 7u83 1466
	if (depth > 1) {
1467
		/* More than one level of templates */
1468
		report(decl_loc, ERR_temp_decl_bad());
1469
	}
1470
	return (t);
2 7u83 1471
}
1472
 
1473
 
1474
/*
1475
    CHECK FOR TEMPLATE DEFAULT ARGUMENTS
1476
 
1477
    This routine returns true if the template type t has default arguments.
1478
*/
1479
 
7 7u83 1480
int
1481
check_templ_dargs(TYPE t)
2 7u83 1482
{
7 7u83 1483
	if (IS_type_templ(t)) {
1484
		TOKEN sort = DEREF_tok(type_templ_sort(t));
1485
		LIST(TOKEN) dargs = DEREF_list(tok_templ_dargs(sort));
1486
		while (!IS_NULL_list(dargs)) {
1487
			TOKEN darg = DEREF_tok(HEAD_list(dargs));
1488
			if (!IS_NULL_tok(darg)) {
1489
				return (1);
1490
			}
1491
			dargs = TAIL_list(dargs);
1492
		}
2 7u83 1493
	}
7 7u83 1494
	return (0);
2 7u83 1495
}
1496
 
1497
 
1498
/*
1499
    FIND AN UNDERLYING TEMPLATE
1500
 
1501
    This routine checks whether the identifier id results from the
1502
    application of a template.  If so it returns the underlying template.
1503
*/
1504
 
7 7u83 1505
IDENTIFIER
1506
find_template(IDENTIFIER id, int force)
2 7u83 1507
{
7 7u83 1508
	if (!IS_NULL_id(id)) {
1509
		switch (TAG_id(id)) {
1510
		case id_class_name_tag: {
1511
			/* Template classes */
1512
			CLASS_TYPE ct;
1513
			int templ = 0;
1514
			TYPE t = DEREF_type(id_class_name_defn(id));
1515
			while (IS_type_templ(t)) {
1516
				t = DEREF_type(type_templ_defn(t));
1517
				templ = 1;
1518
			}
1519
			ct = DEREF_ctype(type_compound_defn(t));
1520
			t = DEREF_type(ctype_form(ct));
1521
			if (!IS_NULL_type(t) && IS_type_token(t)) {
1522
				IDENTIFIER tid = DEREF_id(type_token_tok(t));
1523
				if (!IS_id_token(tid)) {
1524
					return (tid);
1525
				}
1526
			}
1527
			if (templ && force) {
1528
				/* Primary template class */
1529
				return (id);
1530
			}
1531
			break;
2 7u83 1532
		}
7 7u83 1533
		case id_function_tag:
1534
		case id_mem_func_tag:
1535
		case id_stat_mem_func_tag: {
1536
			/* Template functions */
1537
			TYPE t = DEREF_type(id_function_etc_form(id));
1538
			if (!IS_NULL_type(t) && IS_type_token(t)) {
1539
				IDENTIFIER tid = DEREF_id(type_token_tok(t));
1540
				if (!IS_id_token(tid)) {
1541
					return (tid);
1542
				}
1543
			}
1544
			if (force) {
1545
				t = DEREF_type(id_function_etc_type(id));
1546
				if (IS_type_templ(t)) {
1547
					/* Primary template function */
1548
					return (id);
1549
				}
1550
			}
1551
			break;
2 7u83 1552
		}
7 7u83 1553
		case id_ambig_tag: {
1554
			/* Ambiguous identifiers */
1555
			LIST(IDENTIFIER) pids;
1556
			pids = DEREF_list(id_ambig_ids(id));
1557
			if (!IS_NULL_list(pids)) {
1558
				IDENTIFIER pid = DEREF_id(HEAD_list(pids));
1559
				IDENTIFIER tid = find_template(pid, force);
1560
				if (!IS_NULL_id(tid)) {
1561
					pids = TAIL_list(pids);
1562
					while (!IS_NULL_list(pids)) {
1563
						IDENTIFIER sid;
1564
						pid = DEREF_id(HEAD_list(pids));
1565
						sid = find_template(pid, force);
1566
						if (!EQ_id(sid, tid)) {
1567
							return (NULL_id);
1568
						}
1569
						pids = TAIL_list(pids);
1570
					}
1571
					return (tid);
1572
				}
1573
			}
1574
			break;
2 7u83 1575
		}
1576
		}
1577
	}
7 7u83 1578
	return (NULL_id);
2 7u83 1579
}
1580
 
1581
 
1582
/*
1583
    REDECLARE A TEMPLATE PARAMETER
1584
 
1585
    This routine checks the template parameter id for redeclarations.
1586
*/
1587
 
7 7u83 1588
static IDENTIFIER
1589
redecl_templ_param(IDENTIFIER id)
2 7u83 1590
{
7 7u83 1591
	HASHID nm = DEREF_hashid(id_name(id));
1592
	MEMBER mem = search_member(crt_namespace, nm, 1);
1593
	IDENTIFIER pid = DEREF_id(member_id(mem));
1594
	if (!IS_NULL_id(pid)) {
1595
		/* Parameter already defined */
1596
		report(crt_loc, ERR_temp_param_dup(nm));
1597
		nm = lookup_anon();
1598
		id = DEREF_id(hashid_id(nm));
1599
	}
1600
	return (id);
2 7u83 1601
}
1602
 
1603
 
1604
/*
1605
    DECLARE A TEMPLATE TYPE PARAMETER
1606
 
1607
    This routine declares a template type parameter named id.
1608
*/
1609
 
7 7u83 1610
IDENTIFIER
1611
make_type_param(IDENTIFIER id)
2 7u83 1612
{
7 7u83 1613
	TOKEN tok;
1614
	MAKE_tok_type(btype_template, NULL_type, tok);
1615
	id = redecl_templ_param(id);
1616
	id = make_token_decl(tok, 0, id, NULL_id);
1617
	return (id);
2 7u83 1618
}
1619
 
1620
 
1621
/*
1622
    SET A DEFAULT TEMPLATE TYPE ARGUMENT
1623
 
1624
    This routine sets the default value for the template type parameter id
1625
    to be t.
1626
*/
1627
 
7 7u83 1628
void
1629
init_type_param(IDENTIFIER id, TYPE t)
2 7u83 1630
{
7 7u83 1631
	DECL_SPEC ds = DEREF_dspec(id_storage(id));
1632
	COPY_dspec(id_storage(id), (ds & ~dspec_pure));
1633
	IGNORE define_type_token(id, t, 0);
1634
	COPY_dspec(id_storage(id), ds);
1635
	return;
2 7u83 1636
}
1637
 
1638
 
1639
/*
1640
    DECLARE A TEMPLATE EXPRESSION PARAMETER
1641
 
1642
    This routine declares a template expression parameter named id of
1643
    type t.
1644
*/
1645
 
7 7u83 1646
IDENTIFIER
1647
make_exp_param(TYPE t, IDENTIFIER id)
2 7u83 1648
{
7 7u83 1649
	TOKEN tok;
1650
	t = rvalue_type(t);
1651
	MAKE_tok_exp(t, 1, NULL_exp, tok);
1652
	id = make_token_decl(tok, 0, id, NULL_id);
1653
	return (id);
2 7u83 1654
}
1655
 
1656
 
1657
/*
1658
    SET A DEFAULT TEMPLATE EXPRESSION ARGUMENT
1659
 
1660
    This routine sets the default value for the template expression
1661
    parameter id to be e.
1662
*/
1663
 
7 7u83 1664
void
1665
init_exp_param(IDENTIFIER id, EXP e)
2 7u83 1666
{
7 7u83 1667
	DECL_SPEC ds = DEREF_dspec(id_storage(id));
1668
	COPY_dspec(id_storage(id), (ds & ~dspec_pure));
1669
	IGNORE define_exp_token(id, e, 1);
1670
	COPY_dspec(id_storage(id), ds);
1671
	return;
2 7u83 1672
}
1673
 
1674
 
1675
/*
1676
    DECLARE A TEMPLATE TEMPLATE PARAMETER
1677
 
1678
    This routine declares a template template parameter named id of type t.
1679
*/
1680
 
7 7u83 1681
IDENTIFIER
1682
make_template_param(TYPE t, IDENTIFIER id)
2 7u83 1683
{
7 7u83 1684
	TOKEN tok;
1685
	MAKE_tok_class(t, NULL_id, tok);
1686
	id = redecl_templ_param(id);
1687
	id = make_token_decl(tok, 0, id, NULL_id);
1688
	return (id);
2 7u83 1689
}
1690
 
1691
 
1692
/*
1693
    SET A TEMPLATE TEMPLATE ARGUMENT
1694
 
1695
    This routine sets the value for the template template parameter id to
1696
    be tid.  This is used both to set a default argument value and to
1697
    define a template template parameter.
1698
*/
1699
 
7 7u83 1700
void
1701
init_template_param(IDENTIFIER id, IDENTIFIER tid)
2 7u83 1702
{
7 7u83 1703
	if (!IS_NULL_id(tid)) {
1704
		if (IS_id_class_name_etc(tid)) {
1705
			DECL_SPEC ds = DEREF_dspec(id_storage(id));
1706
			COPY_dspec(id_storage(id), (ds & ~dspec_pure));
1707
			IGNORE define_templ_token(id, tid);
1708
			COPY_dspec(id_storage(id), ds);
1709
		} else {
1710
			report(crt_loc, ERR_temp_arg_templ_not(id, tid));
1711
		}
2 7u83 1712
	}
7 7u83 1713
	return;
2 7u83 1714
}
1715
 
1716
 
1717
/*
1718
    LIST OF DUMMY TYPE PARAMETERS
1719
 
1720
    This list is used to store all the dummy type parameters created by
1721
    make_dummy_type to avoid duplicates.
1722
*/
1723
 
7 7u83 1724
static LIST(IDENTIFIER) dummy_types = NULL_list(IDENTIFIER);
2 7u83 1725
 
1726
 
1727
/*
1728
    CREATE A DUMMY TYPE PARAMETER
1729
 
1730
    This routine creates a dummy type parameter named id in the namespace
1731
    ns.  bt gives the token type kind.
1732
*/
1733
 
7 7u83 1734
static TYPE
1735
make_dummy_type(NAMESPACE ns, IDENTIFIER id, BASE_TYPE bt, LIST(TOKEN) args)
2 7u83 1736
{
7 7u83 1737
	TYPE t;
1738
	HASHID nm = DEREF_hashid(id_name(id));
1739
	LIST(IDENTIFIER) p = dummy_types;
1740
	while (!IS_NULL_list(p)) {
1741
		IDENTIFIER pid = DEREF_id(HEAD_list(p));
1742
		HASHID pnm = DEREF_hashid(id_name(pid));
1743
		NAMESPACE pns = DEREF_nspace(id_parent(pid));
1744
		if (EQ_hashid(nm, pnm) && EQ_nspace(ns, pns)) {
1745
			TOKEN tok = DEREF_tok(id_token_sort(pid));
1746
			BASE_TYPE pt = DEREF_btype(tok_type_kind(tok));
1747
			if (bt == pt) {
1748
				id = pid;
1749
				break;
1750
			}
1751
		}
1752
		p = TAIL_list(p);
2 7u83 1753
	}
7 7u83 1754
	if (IS_NULL_list(p)) {
1755
		/* Create new parameter */
1756
		TOKEN tok;
1757
		DECL_SPEC ds = (dspec_template | dspec_token | dspec_auto |
1758
				dspec_pure | dspec_implicit);
1759
		MAKE_tok_type(bt, NULL_type, tok);
1760
		MAKE_id_token(nm, ds, ns, crt_loc, tok, NULL_id, id);
1761
		COPY_id(id_token_alt(id), id);
1762
		CONS_id(id, dummy_types, dummy_types);
1763
	}
1764
	MAKE_type_token(cv_none, id, args, t);
1765
	return (t);
2 7u83 1766
}
1767
 
1768
 
1769
/*
1770
    DOES A TYPE REPRESENT A TEMPLATE SPECIALISATION?
1771
 
1772
    This routine checks whether the type t represents an explicit template
1773
    specialisation or instantiation.
1774
*/
1775
 
7 7u83 1776
int
1777
is_templ_spec(TYPE t)
2 7u83 1778
{
7 7u83 1779
	while (!IS_NULL_type(t) && IS_type_templ(t)) {
1780
		LIST(IDENTIFIER) pids;
1781
		TOKEN sort = DEREF_tok(type_templ_sort(t));
1782
		pids = DEREF_list(tok_templ_pids(sort));
1783
		if (IS_NULL_list(pids)) {
1784
			return (1);
1785
		}
1786
		t = DEREF_type(type_templ_defn(t));
1787
	}
1788
	return (0);
2 7u83 1789
}
1790
 
1791
 
1792
/*
1793
    IS A TYPE A TEMPLATE PARAMETER?
1794
 
1795
    This routine checks whether the type t represents a template parameter
1796
    and a template declaration is currently being processed.
1797
*/
1798
 
7 7u83 1799
int
1800
is_templ_type(TYPE t)
2 7u83 1801
{
7 7u83 1802
	if (!IS_NULL_type(t) && IS_type_token(t)) {
1803
		IDENTIFIER id = DEREF_id(type_token_tok(t));
1804
		if (is_templ_param(id)) {
1805
			return (in_template_decl);
1806
		}
1807
	}
1808
	return (0);
2 7u83 1809
}
1810
 
1811
 
1812
/*
1813
    DOES A TYPE DEPEND ON A TEMPLATE TYPE PARAMETER?
1814
 
1815
    This routine checks whether the type t is dependent on any template
1816
    parameter.
1817
*/
1818
 
7 7u83 1819
int
1820
is_templ_depend(TYPE t)
2 7u83 1821
{
7 7u83 1822
	if (in_template_decl) {
1823
		/* Only need to check in a template declaration */
1824
		return (depends_on(t, any_templ_param));
1825
	}
1826
	return (0);
2 7u83 1827
}
1828
 
1829
 
1830
/*
1831
    IS AN IDENTIFIER A TEMPLATE TYPE PARAMETER?
1832
 
1833
    This routine checks whether the token identifier id represents a
1834
    template type parameter.
1835
*/
1836
 
7 7u83 1837
int
1838
is_templ_param(IDENTIFIER id)
2 7u83 1839
{
7 7u83 1840
	DECL_SPEC ds = DEREF_dspec(id_storage(id));
1841
	if ((ds & dspec_template) && (ds & dspec_auto)) {
1842
		return (1);
1843
	}
1844
	return (0);
2 7u83 1845
}
1846
 
1847
 
1848
/*
1849
    IS AN IDENTIFIER AN ALIAS FOR A TEMPLATE TYPE PARAMETER?
1850
 
1851
    This routine checks whether the identifier id is the internal name
1852
    for a template type parameter.
1853
*/
1854
 
7 7u83 1855
int
1856
is_templ_alias(IDENTIFIER id)
2 7u83 1857
{
7 7u83 1858
	unsigned tag = TAG_id(id);
1859
	if (tag == id_type_alias_tag) {
1860
		TYPE t = DEREF_type(id_type_alias_defn(id));
1861
		if (IS_type_token(t)) {
1862
			id = DEREF_id(type_token_tok(t));
1863
			tag = TAG_id(id);
1864
		}
1865
	} else if (tag == id_token_tag) {
1866
		id = DEREF_id(id_token_alt(id));
1867
		tag = TAG_id(id);
2 7u83 1868
	}
7 7u83 1869
	if (tag == id_token_tag && is_templ_param(id)) {
1870
		DECL_SPEC ds = DEREF_dspec(id_storage(id));
1871
		if (!(ds & dspec_implicit)) {
1872
			return (1);
1873
		}
1874
	}
1875
	return (0);
2 7u83 1876
}
1877
 
1878
 
1879
/*
1880
    IS AN IDENTIFIER A TEMPLATE DECLARATOR?
1881
 
1882
    This routine checks whether the declarator id represents a template
1883
    instance.  If id is a function declaration then t gives the function
1884
    type.
1885
*/
1886
 
7 7u83 1887
int
1888
is_templ_decl(IDENTIFIER id, TYPE t)
2 7u83 1889
{
7 7u83 1890
	if (crt_templ_qualifier) {
1891
		/* Declaration is a template-id */
1892
		IDENTIFIER tid = find_template(id, 0);
1893
		if (!IS_NULL_id(tid)) {
1894
			return (1);
1895
		}
2 7u83 1896
	}
7 7u83 1897
	if (!IS_NULL_type(t) && crt_id_qualifier != qual_none) {
1898
		/* Function declarator is a qualified-id */
1899
		int eq = 0;
1900
		LIST(IDENTIFIER) pids = NULL_list(IDENTIFIER);
1901
		IDENTIFIER pid = resolve_func(id, t, 1, 1, pids, &eq);
1902
		if (!IS_NULL_id(pid)) {
1903
			IDENTIFIER tid = find_template(pid, 0);
1904
			if (!IS_NULL_id(tid)) {
1905
				return (1);
1906
			}
1907
		}
1908
	}
1909
	return (0);
2 7u83 1910
}
1911
 
1912
 
1913
/*
1914
    IS A NAMESPACE A TEMPLATE CLASS?
1915
 
1916
    This routine checks whether the namespace ns represents a template
1917
    class or a nested class of a template class or a block of a template
1918
    function.
1919
*/
1920
 
7 7u83 1921
int
1922
is_templ_nspace(NAMESPACE ns)
2 7u83 1923
{
7 7u83 1924
	while (!IS_NULL_nspace(ns)) {
1925
		IDENTIFIER tid;
1926
		IDENTIFIER id = DEREF_id(nspace_name(ns));
1927
		if (IS_NULL_id(id)) {
1928
			break;
1929
		}
1930
		tid = find_template(id, 1);
1931
		if (!IS_NULL_id(tid)) {
1932
			return (1);
1933
		}
1934
		ns = DEREF_nspace(id_parent(id));
1935
	}
1936
	return (0);
2 7u83 1937
}
1938
 
1939
 
1940
/*
1941
    CHECK A TYPENAME
1942
 
1943
    This routine checks whether 'typename ns::id' can be used to declare
1944
    a type.  If so this type is returned, otherwise the null type is
1945
    returned.  Any following template arguments are dealt with in this
1946
    routine.
1947
*/
1948
 
7 7u83 1949
TYPE
1950
check_typename(NAMESPACE ns, IDENTIFIER id, BASE_TYPE key)
2 7u83 1951
{
7 7u83 1952
	TYPE s = NULL_type;
1953
	if (in_template_decl) {
1954
		if (!IS_NULL_nspace(ns) && IS_nspace_ctype(ns)) {
1955
			IDENTIFIER tid = DEREF_id(nspace_name(ns));
1956
			TYPE t = DEREF_type(id_class_name_etc_defn(tid));
1957
			while (IS_type_templ(t)) {
1958
				/* Step over any template qualifiers */
1959
				t = DEREF_type(type_templ_defn(t));
1960
			}
1961
			if (is_templ_depend(t)) {
1962
				/* Qualifier depends on a template parameter */
1963
				int templ = 0;
1964
				LIST(TOKEN) args = NULL_list(TOKEN);
1965
				if (crt_lex_token == lex_less) {
1966
					/* Step over template arguments */
1967
					PPTOKEN *p =
1968
					    skip_template_args(NULL_id, 1);
1969
					args = parse_template_args(p);
1970
					templ = 1;
1971
				}
1972
				if (IS_id_class_name_etc(id)) {
1973
					if (templ) {
1974
						/* Apply template arguments */
1975
						id = apply_template(id, args,
1976
								    0, 0);
1977
					}
1978
					s = DEREF_type(id_class_name_etc_defn(id));
1979
					if (IS_type_templ(s)) {
1980
						s = deduce_type_template(id, 1);
1981
					}
1982
					s = copy_typedef(id, s, cv_none);
1983
					COPY_id(type_name(s), id);
1984
					use_id(id, 0);
1985
				} else {
1986
					BASE_TYPE bt = (btype_template |
1987
							btype_typename);
1988
					if (templ) {
1989
						bt |= btype_args;
1990
					}
1991
					s = make_dummy_type(ns, id, bt, args);
1992
					if (key != btype_none) {
1993
						/* Result should be a class */
1994
						id = DEREF_id(type_token_tok(s));
1995
						args = NULL_list(TOKEN);
1996
						s = make_dummy_class(id, args,
1997
								     key);
1998
					}
1999
				}
2000
			}
2 7u83 2001
		}
2002
	}
7 7u83 2003
	return (s);
2 7u83 2004
}
2005
 
2006
 
2007
/*
2008
    DECLARE A TYPENAME
2009
 
2010
    This routine handles a type declared using typename.  ns gives the
2011
    name qualifiers used in the declaration and id gives the actual member
2012
    name.  Any following template arguments are dealt with in this
2013
    routine.
2014
*/
2015
 
7 7u83 2016
TYPE
2017
make_typename(NAMESPACE ns, IDENTIFIER id)
2 7u83 2018
{
7 7u83 2019
	TYPE s = check_typename(ns, id, btype_none);
2020
	if (IS_NULL_type(s)) {
2021
		int templ = 0;
2022
		LIST(TOKEN) args = NULL_list(TOKEN);
2023
		report(crt_loc, ERR_temp_res_qual());
2024
		if (crt_lex_token == lex_less) {
2025
			/* Step over template arguments */
2026
			PPTOKEN *p = skip_template_args(NULL_id, 1);
2027
			args = parse_template_args(p);
2028
			templ = 1;
2029
		}
2030
		if (IS_id_class_name_etc(id)) {
2031
			/* Name denotes a type - return that */
2032
			if (templ) {
2033
				/* Apply template arguments */
2034
				id = apply_template(id, args, 0, 0);
2035
			}
2036
			s = DEREF_type(id_class_name_etc_defn(id));
2037
			if (IS_type_templ(s)) {
2038
				s = deduce_type_template(id, 1);
2039
			}
2040
			s = copy_typedef(id, s, cv_none);
2041
			COPY_id(type_name(s), id);
2042
			use_id(id, 0);
2043
		} else {
2044
			/* Return the error type */
2045
			s = type_error;
2046
		}
2 7u83 2047
	}
7 7u83 2048
	return (s);
2 7u83 2049
}
2050
 
2051
 
2052
/*
2053
    LIST OF BAD TYPENAMES
2054
 
2055
    Without some action, an illegal typename can be reported many times.
2056
    A list of all bad typename look-ups is maintained so that the error is
2057
    only reported once.
2058
*/
2059
 
7 7u83 2060
static LIST(IDENTIFIER) non_typenames = NULL_list(IDENTIFIER);
2 7u83 2061
 
2062
 
2063
/*
2064
    FIND THE TYPE GIVEN BY A TYPENAME
2065
 
2066
    This routine expands the type name id.  If no expansion is possible
2067
    then the null type is returned.  type indicates whether the look-up
2068
    should be for a type name or an object name (the latter is used when
2069
    searching for a type previously declared using typename).
2070
*/
2071
 
7 7u83 2072
TYPE
2073
find_typename(IDENTIFIER id, LIST(TOKEN) args, BASE_TYPE bt, int type)
2 7u83 2074
{
7 7u83 2075
	TYPE t = NULL_type;
2076
	NAMESPACE ns = DEREF_nspace(id_parent(id));
2077
	NAMESPACE cns = rescan_nspace(ns);
2078
	if (!EQ_nspace(cns, ns)) {
2079
		/* Rescan type name */
2080
		LIST(IDENTIFIER) p;
2081
		HASHID nm = DEREF_hashid(id_name(id));
2082
		IDENTIFIER tid = search_field(cns, nm, 0, type);
2083
		if (!IS_NULL_id(tid) && IS_id_class_name_etc(tid)) {
2084
			/* Type name */
2085
			if (bt & btype_args) {
2086
				/* Apply template arguments */
2087
				tid = apply_template(tid, args, 0, 0);
2088
			}
2089
			t = DEREF_type(id_class_name_etc_defn(tid));
2090
			if (IS_type_templ(t)) {
2091
				t = deduce_type_template(tid, 1);
2092
			}
2093
			t = copy_typedef(tid, t, cv_none);
2094
			COPY_id(type_name(t), tid);
2095
			use_id(tid, 0);
2096
			return (t);
2097
		}
2 7u83 2098
 
7 7u83 2099
		/* Check for template parameters */
2100
		if (in_template_decl) {
2101
			if (!IS_NULL_nspace(cns) && IS_nspace_ctype(cns)) {
2102
				tid = DEREF_id(nspace_name(cns));
2103
				t = DEREF_type(id_class_name_etc_defn(tid));
2104
				while (IS_type_templ(t)) {
2105
					t = DEREF_type(type_templ_defn(t));
2106
				}
2107
				if (is_templ_depend(t)) {
2108
					t = make_dummy_type(cns, id, bt, args);
2109
					return (t);
2110
				}
2111
			}
2 7u83 2112
		}
7 7u83 2113
 
2114
		/* Report error */
2115
		p = non_typenames;
2116
		t = type_error;
2117
		while (!IS_NULL_list(p)) {
2118
			IDENTIFIER pid = DEREF_id(HEAD_list(p));
2119
			HASHID pnm = DEREF_hashid(id_name(pid));
2120
			NAMESPACE pns = DEREF_nspace(id_parent(pid));
2121
			if (EQ_hashid(pnm, nm) && EQ_nspace(pns, cns)) {
2122
				/* Already reported */
2123
				break;
2124
			}
2 7u83 2125
		}
7 7u83 2126
		if (IS_NULL_list(p)) {
2127
			/* Report undefined type */
2128
			MAKE_id_type_alias(nm, dspec_none, cns, crt_loc, t,
2129
					   tid);
2130
			CONS_id(tid, non_typenames, non_typenames);
2131
			report(crt_loc, ERR_temp_res_type(cns, nm));
2132
		}
2 7u83 2133
	}
7 7u83 2134
	return (t);
2 7u83 2135
}
2136
 
2137
 
2138
/*
2139
    IDENTIFY TWO LISTS OF TEMPLATE PARAMETERS
2140
 
2141
    This routine identifies the list of template parameters ps with those
2142
    in pt, returning true if this is possible.
2143
*/
2144
 
7 7u83 2145
int
2146
eq_templ_params(LIST(IDENTIFIER) ps, LIST(IDENTIFIER) pt)
2 7u83 2147
{
7 7u83 2148
	int ok = 1;
2149
	while (!IS_NULL_list(ps) && !IS_NULL_list(pt)) {
2150
		IDENTIFIER is = DEREF_id(HEAD_list(ps));
2151
		IDENTIFIER it = DEREF_id(HEAD_list(pt));
2152
		if (!EQ_id(is, it)) {
2153
			TOKEN ns, nt;
2154
			unsigned vs, vt;
2155
			if (IS_NULL_id(is)) {
2156
				return (0);
2157
			}
2158
			if (IS_NULL_id(it)) {
2159
				return (0);
2160
			}
2161
			ns = DEREF_tok(id_token_sort(is));
2162
			nt = DEREF_tok(id_token_sort(it));
2163
			vs = TAG_tok(ns);
2164
			vt = TAG_tok(nt);
2165
			if (vs != vt) {
2166
				/* Parameter sorts should be equal */
2167
				ok = 0;
2168
				break;
2169
			}
2170
			if (vs == tok_exp_tag) {
2171
				/* Check expression parameter types */
2172
				TYPE rs = DEREF_type(tok_exp_type(ns));
2173
				TYPE rt = DEREF_type(tok_exp_type(nt));
2174
				rs = expand_type(rs, 2);
2175
				if (eq_type(rs, rt)!= 1) {
2176
					ok = 0;
2177
					break;
2178
				}
2179
			}
2180
			if (vs == tok_class_tag) {
2181
				/* Check template class parameter types */
2182
				TYPE rs = DEREF_type(tok_class_type(ns));
2183
				TYPE rt = DEREF_type(tok_class_type(nt));
2184
				rs = expand_type(rs, 2);
2185
				if (eq_template(rs, rt, 0, 1, 0) != 3) {
2186
					ok = 0;
2187
					break;
2188
				}
2189
			}
2190
			it = DEREF_id(id_alias(it));
2191
			COPY_id(id_alias(is), it);
2 7u83 2192
		}
7 7u83 2193
		pt = TAIL_list(pt);
2194
		ps = TAIL_list(ps);
2 7u83 2195
	}
7 7u83 2196
	if (!EQ_list(ps, pt)) {
2197
		ok = 0;
2198
	}
2199
	return (ok);
2 7u83 2200
}
2201
 
2202
 
2203
/*
2204
    RESTORE A LIST OF TEMPLATE PARAMETERS
2205
 
2206
    This routine clears the aliases set up by eq_templ_param from the
2207
    list of template parameters ps.
2208
*/
2209
 
7 7u83 2210
void
2211
restore_templ_params(LIST(IDENTIFIER)ps)
2 7u83 2212
{
7 7u83 2213
	while (!IS_NULL_list(ps)) {
2214
		IDENTIFIER is = DEREF_id(HEAD_list(ps));
2215
		COPY_id(id_alias(is), is);
2216
		ps = TAIL_list(ps);
2217
	}
2218
	return;
2 7u83 2219
}
2220
 
2221
 
2222
/*
2223
    CHECK FOR TEMPLATE TYPE EQUALITY
2224
 
2225
    This routine checks whether the template types s and t are equal
2226
    under a simple renaming of template parameters.  If def is false
2227
    only the template parameters (and not the underlying type) are checked.
2228
    mq and rf are as in eq_func_type, as is the return value.
2229
*/
2230
 
7 7u83 2231
int
2232
eq_template(TYPE s, TYPE t, int def, int mq, int rf)
2 7u83 2233
{
7 7u83 2234
	TOKEN as = DEREF_tok(type_templ_sort(s));
2235
	TOKEN at = DEREF_tok(type_templ_sort(t));
2236
	LIST(IDENTIFIER) ps = DEREF_list(tok_templ_pids(as));
2237
	LIST(IDENTIFIER) pt = DEREF_list(tok_templ_pids(at));
2238
	int eq = eq_templ_params(ps, pt);
2239
	if (eq && def) {
2240
		/* Check for equality of definitions */
2241
		int ft = force_template;
2242
		TYPE ds = DEREF_type(type_templ_defn(s));
2243
		TYPE dt = DEREF_type(type_templ_defn(t));
2244
		force_template = 0;
2245
		eq = eq_func_type(ds, dt, mq, rf);
2246
		force_template = ft;
2247
	}
2248
	restore_templ_params(ps);
2249
	return (eq);
2 7u83 2250
}
2251
 
2252
 
2253
/*
2254
    RENAME TEMPLATE PARAMETERS IN A TYPE
2255
 
2256
    This routine renames the parameters in the given template sort,
2257
    returning the template type formed by applying this renaming to t.
2258
*/
2259
 
7 7u83 2260
static TYPE
2261
rename_templ_params(TOKEN sort, TYPE t, int rec)
2 7u83 2262
{
7 7u83 2263
	if (rec) {
2264
		int d;
2265
		LIST(TOKEN) args;
2266
		LIST(IDENTIFIER) pids;
2267
		LIST(IDENTIFIER) qids;
2268
		pids = DEREF_list(tok_templ_pids(sort));
2269
		sort = expand_sort(sort, 1, 1);
2270
		qids = DEREF_list(tok_templ_pids(sort));
2271
		args = make_primary_args(qids);
2272
		d = save_token_args(pids, args);
2273
		t = expand_type(t, 1);
2274
		restore_token_args(pids, d);
2275
	}
2276
	MAKE_type_templ(cv_none, sort, t, 1, t);
2277
	return (t);
2 7u83 2278
}
2279
 
2280
 
2281
/*
2282
    CHECK FOR TEMPLATE TYPE SPECIALISATION
2283
 
2284
    This routine checks whether the type t is a specialisation of the
2285
    template type s.  Type qualifiers are ignored if qu is false.
2286
*/
2287
 
7 7u83 2288
int
2289
deduce_template(TYPE s, TYPE t, int qu)
2 7u83 2290
{
7 7u83 2291
	int eq;
2292
	TYPE r = DEREF_type(type_templ_defn(s));
2293
	TOKEN sort = DEREF_tok(type_templ_sort(s));
2294
	LIST(IDENTIFIER) pids = DEREF_list(tok_templ_pids(sort));
2295
	if (in_template_decl && depends_on(t, pids)) {
2296
		/* Rename parameters if necessary */
2297
		CV_SPEC cv = DEREF_cv(type_qual(s));
2298
		s = rename_templ_params(sort, r, 1);
2299
		COPY_cv(type_qual(s), cv);
2300
		eq = deduce_template(s, t, qu);
2301
	} else {
2302
		/* Perform argument deduction */
2303
		int d;
2304
		force_template++;
2305
		d = save_token_args(pids, NULL_list(TOKEN));
2306
		eq = eq_type_qual(r, t, qu);
2307
		if (eq == 3) {
2308
			eq = 0;
2309
		}
2310
		restore_token_args(pids, d);
2311
		force_template--;
2312
	}
2313
	return (eq);
2 7u83 2314
}
2315
 
2316
 
2317
/*
2318
    REDECLARE A TEMPLATE TYPE
2319
 
2320
    This routine checks the redeclaration of the template id of type ps to
2321
    have type pt.  The primary purpose of this is to check for default
2322
    arguments in the redeclaration.  The non-template components are
2323
    returned via ps and pt.
2324
*/
2325
 
7 7u83 2326
void
2327
redecl_template(TYPE *ps, TYPE *pt, IDENTIFIER id)
2 7u83 2328
{
7 7u83 2329
	TYPE s = *ps;
2330
	TYPE t = *pt;
2331
	while (IS_type_templ(s)) {
2332
		s = DEREF_type(type_templ_defn(s));
2 7u83 2333
	}
7 7u83 2334
	while (IS_type_templ(t)) {
2335
		TOKEN sort = DEREF_tok(type_templ_sort(t));
2336
		DECL_SPEC use = DEREF_dspec(tok_templ_usage(sort));
2337
		if (use & dspec_extern) {
2338
			export_template(id, 1);
2339
		}
2340
		if (check_templ_dargs(t)) {
2341
			/* Can't have default arguments in redeclaration */
2342
			report(decl_loc, ERR_temp_param_redecl());
2343
		}
2344
		t = DEREF_type(type_templ_defn(t));
2345
	}
2346
	*pt = t;
2347
	*ps = s;
2348
	return;
2 7u83 2349
}
2350
 
2351
 
2352
/*
2353
    RESET THE PRIMARY FORM OF A TEMPLATE
2354
 
2355
    This routine changes the primary representation of a template from
2356
    s to t.  This is done when, for example, the latter is a definition
2357
    while the former is only a declaration.
2358
*/
2359
 
7 7u83 2360
void
2361
reset_primary_templ(TYPE s, TYPE t)
2 7u83 2362
{
7 7u83 2363
	unsigned ns = TAG_type(s);
2364
	unsigned nt = TAG_type(t);
2365
	while (ns == type_templ_tag && nt == type_templ_tag) {
2366
		TOKEN as = DEREF_tok(type_templ_sort(s));
2367
		TOKEN at = DEREF_tok(type_templ_sort(t));
2368
		LIST(IDENTIFIER) ps = DEREF_list(tok_templ_pids(as));
2369
		LIST(IDENTIFIER) pt = DEREF_list(tok_templ_pids(at));
2370
		INSTANCE apps = DEREF_inst(tok_templ_apps(as));
2371
		INSTANCE app = apps;
2372
		LIST(TOKEN) dargs = DEREF_list(tok_templ_dargs(as));
2373
		while (!IS_NULL_inst(app)) {
2374
			DECL_SPEC ds = DEREF_dspec(inst_templ_access(app));
2375
			if (ds & dspec_main) {
2376
				/* Replace primary template instance */
2377
				TYPE form = DEREF_type(inst_form(app));
2378
				LIST(TOKEN) args = make_primary_args(pt);
2379
				COPY_tok(type_templ_sort(form), at);
2380
				form = DEREF_type(type_templ_defn(form));
2381
				COPY_list(type_token_args(form), args);
2382
			}
2383
			app = DEREF_inst(inst_next(app));
2384
		}
2385
		if (check_templ_dargs(s)) {
2386
			/* Expand default arguments */
2387
			LIST(TOKEN) args = make_primary_args(pt);
2388
			int d = save_token_args(ps, args);
2389
			dargs = expand_args(dargs, 1, 1);
2390
			restore_token_args(ps, d);
2391
		}
2392
		COPY_list(tok_templ_dargs(at), dargs);
2393
		COPY_inst(tok_templ_apps(at), apps);
2394
		s = DEREF_type(type_templ_defn(s));
2395
		t = DEREF_type(type_templ_defn(t));
2396
		ns = TAG_type(s);
2397
		nt = TAG_type(t);
2 7u83 2398
	}
7 7u83 2399
	return;
2 7u83 2400
}
2401
 
2402
 
2403
/*
2404
    IS AN IDENTIFIER A TEMPLATE PARAMETER?
2405
 
2406
    This routine checks whether the token identifier id is one of the
2407
    template or token parameters given by pids.
2408
*/
2409
 
7 7u83 2410
int
2411
depends_on_param(IDENTIFIER id, LIST(IDENTIFIER) pids)
2 7u83 2412
{
7 7u83 2413
	if (IS_id_token(id)) {
2414
		DECL_SPEC ds = DEREF_dspec(id_storage(id));
2415
		if (!(ds & dspec_ignore)) {
2416
			if (EQ_list(pids, any_templ_param)) {
2417
				/* Short-cut for list of all template
2418
				 * parameters */
2419
				if ((ds & dspec_template) &&
2420
				    (ds & dspec_auto)) {
2421
					return (1);
2422
				}
2423
				return (0);
2424
			}
2425
			if (EQ_list(pids, any_token_param)) {
2426
				/* Short-cut for list of all token parameters */
2427
				if (ds & dspec_auto) {
2428
					return (1);
2429
				}
2430
				return (0);
2431
			}
2432
			while (!IS_NULL_list(pids)) {
2433
				IDENTIFIER pid = DEREF_id(HEAD_list(pids));
2434
				if (EQ_id(pid, id)) {
2435
					return (1);
2436
				}
2437
				pids = TAIL_list(pids);
2438
			}
2 7u83 2439
		}
2440
	}
7 7u83 2441
	return (0);
2 7u83 2442
}
2443
 
2444
 
2445
/*
2446
    DOES AN IDENTIFIER DEPEND ON A TEMPLATE PARAMETER?
2447
 
2448
    This routine checks whether the identifier id is one of the template
2449
    parameters pids or is a template function with an argument depending
2450
    on pids.  If use is true then any other identifiers found are marked
2451
    as used.
2452
*/
2453
 
7 7u83 2454
static int
2455
depends_on_id(IDENTIFIER id, LIST(IDENTIFIER) pids, int use)
2 7u83 2456
{
7 7u83 2457
	if (!IS_NULL_id(id)) {
2458
		NAMESPACE ns;
2459
		switch (TAG_id(id)) {
2460
		case id_class_name_tag: {
2461
			/* Check for template classes */
2462
			TYPE form;
2463
			CLASS_TYPE ct;
2464
			TYPE t = DEREF_type(id_class_name_defn(id));
2465
			while (IS_type_templ(t)) {
2466
				t = DEREF_type(type_templ_defn(t));
2467
			}
2468
			ct = DEREF_ctype(type_compound_defn(t));
2469
			form = DEREF_type(ctype_form(ct));
2470
			if (!IS_NULL_type(form)) {
2471
				if (depends_on(form, pids)) {
2472
					return (1);
2473
				}
2474
			}
2475
			break;
2 7u83 2476
		}
7 7u83 2477
		case id_function_tag:
2478
		case id_mem_func_tag:
2479
		case id_stat_mem_func_tag: {
2480
			/* Check for template functions */
2481
			TYPE form = DEREF_type(id_function_etc_form(id));
2482
			if (!IS_NULL_type(form)) {
2483
				/* Check function form */
2484
				if (depends_on(form, pids)) {
2485
					return (1);
2486
				}
2487
			}
2488
			if (use) {
2489
				reuse_id(id, 0);
2490
			}
2491
			break;
2 7u83 2492
		}
7 7u83 2493
		case id_token_tag: {
2494
			/* Check for template parameters */
2495
			if (depends_on_param(id, pids)) {
2496
				return (1);
2497
			}
2498
			break;
2 7u83 2499
		}
7 7u83 2500
		case id_ambig_tag: {
2501
			/* Check ambiguous identifiers */
2502
			LIST(IDENTIFIER) qids;
2503
			qids = DEREF_list(id_ambig_ids(id));
2504
			while (!IS_NULL_list(qids)) {
2505
				IDENTIFIER qid = DEREF_id(HEAD_list(qids));
2506
				if (depends_on_id(qid, pids, use)) {
2507
					return (1);
2508
				}
2509
				qids = TAIL_list(qids);
2510
			}
2511
			break;
2 7u83 2512
		}
7 7u83 2513
		case id_stat_member_tag: {
2514
			/* Mark static data members */
2515
			if (use) {
2516
				reuse_id(id, 0);
2517
			}
2518
			break;
2519
		}
2520
		}
2521
		ns = DEREF_nspace(id_parent(id));
2522
		if (!IS_NULL_nspace(ns)) {
2523
			/* Check enclosing namespace */
2524
			IDENTIFIER cid = DEREF_id(nspace_name(ns));
2525
			return (depends_on_id(cid, pids, 0));
2526
		}
2 7u83 2527
	}
7 7u83 2528
	return (0);
2 7u83 2529
}
2530
 
2531
 
2532
/*
2533
    DOES A LIST OF TOKEN ARGUMENTS DEPEND ON A TEMPLATE PARAMETER?
2534
 
2535
    This routine checks whether the list of token arguments args depends
2536
    on one of the template parameters pids.  If next is true then the
2537
    algorithm is modified to check whether any token argument depends
2538
    on a later template parameter (e.g. does the first element of args
2539
    depend on the second, third, etc. element of pids).
2540
*/
2541
 
7 7u83 2542
int
2543
depends_on_args(LIST(TOKEN) args, LIST(IDENTIFIER) pids, int use, int next)
2 7u83 2544
{
7 7u83 2545
	while (!IS_NULL_list(args)) {
2546
		TOKEN tok = DEREF_tok(HEAD_list(args));
2547
		if (next) {
2548
			/* Move on to next parameter */
2549
			if (IS_NULL_list(pids)) {
2550
				break;
2551
			}
2552
			pids = TAIL_list(pids);
2 7u83 2553
		}
7 7u83 2554
		if (!IS_NULL_tok(tok)) {
2555
			switch (TAG_tok(tok)) {
2556
			case tok_exp_tag: {
2557
				EXP e = DEREF_exp(tok_exp_value(tok));
2558
				if (depends_on_exp(e, pids, use)) {
2559
					return (1);
2560
				}
2561
				break;
2562
			}
2563
			case tok_stmt_tag: {
2564
				EXP e = DEREF_exp(tok_stmt_value(tok));
2565
				if (depends_on_exp(e, pids, use)) {
2566
					return (1);
2567
				}
2568
				break;
2569
			}
2570
			case tok_nat_tag:
2571
			case tok_snat_tag: {
2572
				NAT n = DEREF_nat(tok_nat_etc_value(tok));
2573
				if (depends_on_nat(n, pids, use)) {
2574
					return (1);
2575
				}
2576
				break;
2577
			}
2578
			case tok_type_tag: {
2579
				TYPE t = DEREF_type(tok_type_value(tok));
2580
				if (depends_on(t, pids)) {
2581
					return (1);
2582
				}
2583
				break;
2584
			}
2585
			case tok_member_tag: {
2586
				OFFSET off = DEREF_off(tok_member_value(tok));
2587
				if (depends_on_off(off, pids, use)) {
2588
					return (1);
2589
				}
2590
				break;
2591
			}
2592
			case tok_class_tag:
2593
				/* NOT YET IMPLEMENTED */
2594
				break;
2595
			}
2 7u83 2596
		}
7 7u83 2597
		args = TAIL_list(args);
2 7u83 2598
	}
7 7u83 2599
	return (0);
2 7u83 2600
}
2601
 
2602
 
2603
/*
2604
    DOES AN INTEGRAL CONSTANT DEPEND ON A TEMPLATE PARAMETER?
2605
 
2606
    This routine checks whether the integral constant n depends on one
2607
    of the template parameters pids.
2608
*/
2609
 
7 7u83 2610
int
2611
depends_on_nat(NAT n, LIST(IDENTIFIER) pids, int use)
2 7u83 2612
{
7 7u83 2613
	if (!IS_NULL_nat(n)) {
2614
		switch (TAG_nat(n)) {
2615
		case nat_calc_tag: {
2616
			EXP e = DEREF_exp(nat_calc_value(n));
2617
			return (depends_on_exp(e, pids, use));
2618
		}
2619
		case nat_token_tag: {
2620
			IDENTIFIER tid = DEREF_id(nat_token_tok(n));
2621
			LIST(TOKEN) args = DEREF_list(nat_token_args(n));
2622
			if (depends_on_param(tid, pids)) {
2623
				return (2);
2624
			}
2625
			if (depends_on_args(args, pids, use, 0)) {
2626
				return (1);
2627
			}
2628
			break;
2629
		}
2630
		}
2 7u83 2631
	}
7 7u83 2632
	return (0);
2 7u83 2633
}
2634
 
2635
 
2636
/*
2637
    DOES A LIST OF EXPRESSIONS DEPEND ON A TEMPLATE PARAMETER?
2638
 
2639
    This routine checks whether the list of expressions p depends on one
2640
    of the template parameters pids.
2641
*/
2642
 
7 7u83 2643
static int
2644
depends_on_exp_list(LIST(EXP) p, LIST(IDENTIFIER) pids, int use)
2 7u83 2645
{
7 7u83 2646
	while (!IS_NULL_list(p)) {
2647
		EXP a = DEREF_exp(HEAD_list(p));
2648
		if (depends_on_exp(a, pids, use)) {
2649
			return (1);
2650
		}
2651
		p = TAIL_list(p);
2652
	}
2653
	return (0);
2 7u83 2654
}
2655
 
2656
 
2657
/*
2658
    DOES AN EXPRESSION DEPEND ON A TEMPLATE PARAMETER?
2659
 
2660
    This routine checks whether the expression e depends on one of the
2661
    template parameters pids.  If e is actually a template parameter
2662
    then 2 is returned.
2663
*/
2664
 
7 7u83 2665
int
2666
depends_on_exp(EXP e, LIST(IDENTIFIER) pids, int use)
2 7u83 2667
{
7 7u83 2668
	if (!IS_NULL_exp(e)) {
2669
		unsigned tag = TAG_exp(e);
2670
		TYPE t = DEREF_type(exp_type(e));
2671
		if (tag == exp_token_tag) {
2672
			/* Check for template parameters */
2673
			IDENTIFIER tid = DEREF_id(exp_token_tok(e));
2674
			LIST(TOKEN) args = DEREF_list(exp_token_args(e));
2675
			if (depends_on_param(tid, pids)) {
2676
				return (2);
2677
			}
2678
			if (depends_on_args(args, pids, use, 0)) {
2679
				return (1);
2680
			}
2681
		}
2682
		if (depends_on(t, pids)) {
2683
			return (1);
2684
		}
2685
		ASSERT(ORDER_exp == 88);
2686
		switch (tag) {
2687
		case exp_identifier_tag:
2688
		case exp_member_tag:
2689
		case exp_ambiguous_tag:
2690
		case exp_undeclared_tag: {
2691
			IDENTIFIER id = DEREF_id(exp_identifier_etc_id(e));
2692
			if (depends_on_id(id, pids, use)) {
2693
				return (1);
2694
			}
2695
			break;
2696
		}
2697
		case exp_int_lit_tag: {
2698
			NAT n = DEREF_nat(exp_int_lit_nat(e));
2699
			return (depends_on_nat(n, pids, use));
2700
		}
2701
		case exp_paren_tag:
2702
		case exp_copy_tag: {
2703
			EXP a = DEREF_exp(exp_paren_etc_arg(e));
2704
			return (depends_on_exp(a, pids, use));
2705
		}
2706
		case exp_assign_tag: {
2707
			EXP a = DEREF_exp(exp_assign_ref(e));
2708
			EXP b = DEREF_exp(exp_assign_arg(e));
2709
			if (depends_on_exp(a, pids, use)) {
2710
				return (1);
2711
			}
2712
			if (depends_on_exp(b, pids, use)) {
2713
				return (1);
2714
			}
2715
			break;
2716
		}
2717
		case exp_init_tag: {
2718
			IDENTIFIER id = DEREF_id(exp_init_id(e));
2719
			EXP a = DEREF_exp(exp_init_arg(e));
2720
			if (depends_on_id(id, pids, use)) {
2721
				return (1);
2722
			}
2723
			if (depends_on_exp(a, pids, use)) {
2724
				return (1);
2725
			}
2726
			break;
2727
		}
2728
		case exp_preinc_tag: {
2729
			EXP a = DEREF_exp(exp_preinc_op(e));
2730
			if (depends_on_exp(a, pids, use)) {
2731
				return (1);
2732
			}
2733
			break;
2734
		}
2735
		case exp_postinc_tag: {
2736
			EXP a = DEREF_exp(exp_postinc_op(e));
2737
			if (depends_on_exp(a, pids, use)) {
2738
				return (1);
2739
			}
2740
			break;
2741
		}
2742
		case exp_indir_tag: {
2743
			EXP a = DEREF_exp(exp_indir_ptr(e));
2744
			if (depends_on_exp(a, pids, use)) {
2745
				return (1);
2746
			}
2747
			break;
2748
		}
2749
		case exp_contents_tag: {
2750
			EXP a = DEREF_exp(exp_contents_ptr(e));
2751
			if (depends_on_exp(a, pids, use)) {
2752
				return (1);
2753
			}
2754
			break;
2755
		}
2756
		case exp_address_tag: {
2757
			EXP a = DEREF_exp(exp_address_arg(e));
2758
			if (depends_on_exp(a, pids, use)) {
2759
				return (1);
2760
			}
2761
			break;
2762
		}
2763
		case exp_address_mem_tag: {
2764
			EXP a = DEREF_exp(exp_address_mem_arg(e));
2765
			if (depends_on_exp(a, pids, use)) {
2766
				return (1);
2767
			}
2768
			break;
2769
		}
2770
		case exp_func_tag: {
2771
			EXP a = DEREF_exp(exp_func_fn(e));
2772
			LIST(EXP) p = DEREF_list(exp_func_args(e));
2773
			if (depends_on_exp(a, pids, use)) {
2774
				return (1);
2775
			}
2776
			if (depends_on_exp_list(p, pids, use)) {
2777
				return (1);
2778
			}
2779
			break;
2780
		}
2781
		case exp_func_id_tag: {
2782
			IDENTIFIER id = DEREF_id(exp_func_id_id(e));
2783
			LIST(EXP) p = DEREF_list(exp_func_id_args(e));
2784
			if (depends_on_id(id, pids, use)) {
2785
				return (1);
2786
			}
2787
			if (depends_on_exp_list(p, pids, use)) {
2788
				return (1);
2789
			}
2790
			break;
2791
		}
2792
		case exp_call_tag: {
2793
			EXP a = DEREF_exp(exp_call_ptr(e));
2794
			EXP b = DEREF_exp(exp_call_arg(e));
2795
			if (depends_on_exp(a, pids, use)) {
2796
				return (1);
2797
			}
2798
			if (depends_on_exp(b, pids, use)) {
2799
				return (1);
2800
			}
2801
			break;
2802
		}
2803
		case exp_negate_tag:
2804
		case exp_compl_tag:
2805
		case exp_not_tag:
2806
		case exp_abs_tag: {
2807
			EXP a = DEREF_exp(exp_negate_etc_arg(e));
2808
			if (depends_on_exp(a, pids, use)) {
2809
				return (1);
2810
			}
2811
			break;
2812
		}
2813
		case exp_plus_tag:
2814
		case exp_minus_tag:
2815
		case exp_mult_tag:
2816
		case exp_div_tag:
2817
		case exp_rem_tag:
2818
		case exp_and_tag:
2819
		case exp_or_tag:
2820
		case exp_xor_tag:
2821
		case exp_log_and_tag:
2822
		case exp_log_or_tag:
2823
		case exp_lshift_tag:
2824
		case exp_rshift_tag:
2825
		case exp_max_tag:
2826
		case exp_min_tag: {
2827
			EXP a = DEREF_exp(exp_plus_etc_arg1(e));
2828
			EXP b = DEREF_exp(exp_plus_etc_arg2(e));
2829
			if (depends_on_exp(a, pids, use)) {
2830
				return (1);
2831
			}
2832
			if (depends_on_exp(b, pids, use)) {
2833
				return (1);
2834
			}
2835
			break;
2836
		}
2837
		case exp_test_tag: {
2838
			EXP a = DEREF_exp(exp_test_arg(e));
2839
			if (depends_on_exp(a, pids, use)) {
2840
				return (1);
2841
			}
2842
			break;
2843
		}
2844
		case exp_compare_tag: {
2845
			EXP a = DEREF_exp(exp_compare_arg1(e));
2846
			EXP b = DEREF_exp(exp_compare_arg2(e));
2847
			if (depends_on_exp(a, pids, use)) {
2848
				return (1);
2849
			}
2850
			if (depends_on_exp(b, pids, use)) {
2851
				return (1);
2852
			}
2853
			break;
2854
		}
2855
		case exp_cast_tag: {
2856
			EXP a = DEREF_exp(exp_cast_arg(e));
2857
			if (depends_on_exp(a, pids, use)) {
2858
				return (1);
2859
			}
2860
			break;
2861
		}
2862
		case exp_base_cast_tag: {
2863
			EXP a = DEREF_exp(exp_base_cast_arg(e));
2864
			if (depends_on_exp(a, pids, use)) {
2865
				return (1);
2866
			}
2867
			break;
2868
		}
2869
		case exp_dyn_cast_tag: {
2870
			EXP a = DEREF_exp(exp_dyn_cast_arg(e));
2871
			if (depends_on_exp(a, pids, use)) {
2872
				return (1);
2873
			}
2874
			break;
2875
		}
2876
		case exp_add_ptr_tag: {
2877
			EXP a = DEREF_exp(exp_add_ptr_ptr(e));
2878
			OFFSET off = DEREF_off(exp_add_ptr_off(e));
2879
			if (depends_on_exp(a, pids, use)) {
2880
				return (1);
2881
			}
2882
			if (depends_on_off(off, pids, use)) {
2883
				return (1);
2884
			}
2885
			break;
2886
		}
2887
		case exp_offset_size_tag: {
2888
			OFFSET off = DEREF_off(exp_offset_size_off(e));
2889
			TYPE s = DEREF_type(exp_offset_size_step(e));
2890
			if (depends_on_off(off, pids, use)) {
2891
				return (1);
2892
			}
2893
			if (depends_on(s, pids)) {
2894
				return (1);
2895
			}
2896
			break;
2897
		}
2898
		case exp_constr_tag: {
2899
			EXP a = DEREF_exp(exp_constr_call(e));
2900
			if (depends_on_exp(a, pids, use)) {
2901
				return (1);
2902
			}
2903
			break;
2904
		}
2905
		case exp_destr_tag: {
2906
			EXP a = DEREF_exp(exp_destr_call(e));
2907
			if (depends_on_exp(a, pids, use)) {
2908
				return (1);
2909
			}
2910
			break;
2911
		}
2912
		case exp_alloc_tag: {
2913
			EXP a = DEREF_exp(exp_alloc_call(e));
2914
			EXP b = DEREF_exp(exp_alloc_init(e));
2915
			if (depends_on_exp(a, pids, use)) {
2916
				return (1);
2917
			}
2918
			if (depends_on_exp(b, pids, use)) {
2919
				return (1);
2920
			}
2921
			break;
2922
		}
2923
		case exp_dealloc_tag: {
2924
			EXP a = DEREF_exp(exp_dealloc_term(e));
2925
			EXP b = DEREF_exp(exp_dealloc_call(e));
2926
			if (depends_on_exp(a, pids, use)) {
2927
				return (1);
2928
			}
2929
			if (depends_on_exp(b, pids, use)) {
2930
				return (1);
2931
			}
2932
			break;
2933
		}
2934
		case exp_rtti_tag: {
2935
			EXP a = DEREF_exp(exp_rtti_arg(e));
2936
			if (depends_on_exp(a, pids, use)) {
2937
				return (1);
2938
			}
2939
			break;
2940
		}
2941
		case exp_rtti_type_tag: {
2942
			TYPE s = DEREF_type(exp_rtti_type_arg(e));
2943
			if (depends_on(s, pids)) {
2944
				return (1);
2945
			}
2946
			break;
2947
		}
2948
		case exp_rtti_no_tag: {
2949
			TYPE s = DEREF_type(exp_rtti_no_arg(e));
2950
			if (depends_on(s, pids)) {
2951
				return (1);
2952
			}
2953
			break;
2954
		}
2955
		case exp_dynamic_tag: {
2956
			EXP a = DEREF_exp(exp_dynamic_arg(e));
2957
			if (depends_on_exp(a, pids, use)) {
2958
				return (1);
2959
			}
2960
			break;
2961
		}
2962
		case exp_aggregate_tag: {
2963
			LIST(EXP)p = DEREF_list(exp_aggregate_args(e));
2964
			if (depends_on_exp_list(p, pids, use)) {
2965
				return (1);
2966
			}
2967
			break;
2968
		}
2969
		case exp_initialiser_tag: {
2970
			LIST(EXP)p = DEREF_list(exp_initialiser_args(e));
2971
			if (depends_on_exp_list(p, pids, use)) {
2972
				return (1);
2973
			}
2974
			break;
2975
		}
2976
		case exp_nof_tag: {
2977
			EXP a = DEREF_exp(exp_nof_start(e));
2978
			EXP b = DEREF_exp(exp_nof_pad(e));
2979
			EXP c = DEREF_exp(exp_nof_end(e));
2980
			if (depends_on_exp(a, pids, use)) {
2981
				return (1);
2982
			}
2983
			if (depends_on_exp(b, pids, use)) {
2984
				return (1);
2985
			}
2986
			if (depends_on_exp(c, pids, use)) {
2987
				return (1);
2988
			}
2989
			break;
2990
		}
2991
		case exp_comma_tag: {
2992
			LIST(EXP) p = DEREF_list(exp_comma_args(e));
2993
			if (depends_on_exp_list(p, pids, use)) {
2994
				return (1);
2995
			}
2996
			break;
2997
		}
2998
		case exp_set_tag: {
2999
			EXP a = DEREF_exp(exp_set_arg(e));
3000
			if (depends_on_exp(a, pids, use)) {
3001
				return (1);
3002
			}
3003
			break;
3004
		}
3005
		case exp_unused_tag: {
3006
			EXP a = DEREF_exp(exp_unused_arg(e));
3007
			if (depends_on_exp(a, pids, use)) {
3008
				return (1);
3009
			}
3010
			break;
3011
		}
3012
		case exp_sequence_tag: {
3013
			LIST(EXP)p = DEREF_list(exp_sequence_first(e));
3014
			if (depends_on_exp_list(p, pids, use)) {
3015
				return (1);
3016
			}
3017
			break;
3018
		}
3019
		case exp_if_stmt_tag: {
3020
			EXP c = DEREF_exp(exp_if_stmt_cond(e));
3021
			EXP a = DEREF_exp(exp_if_stmt_true_code(e));
3022
			EXP b = DEREF_exp(exp_if_stmt_false_code(e));
3023
			if (depends_on_exp(c, pids, use)) {
3024
				return (1);
3025
			}
3026
			if (depends_on_exp(a, pids, use)) {
3027
				return (1);
3028
			}
3029
			if (depends_on_exp(b, pids, use)) {
3030
				return (1);
3031
			}
3032
			break;
3033
		}
3034
		case exp_try_block_tag: {
3035
			EXP a = DEREF_exp(exp_try_block_body(e));
3036
			if (depends_on_exp(a, pids, use)) {
3037
				return (1);
3038
			}
3039
			break;
3040
		}
3041
		case exp_exception_tag: {
3042
			EXP a = DEREF_exp(exp_exception_arg(e));
3043
			if (depends_on_exp(a, pids, use)) {
3044
				return (1);
3045
			}
3046
			break;
3047
		}
3048
		case exp_op_tag: {
3049
			EXP a = DEREF_exp(exp_op_arg1(e));
3050
			EXP b = DEREF_exp(exp_op_arg2(e));
3051
			if (depends_on_exp(a, pids, use)) {
3052
				return (1);
3053
			}
3054
			if (depends_on_exp(b, pids, use)) {
3055
				return (1);
3056
			}
3057
			break;
3058
		}
3059
		case exp_opn_tag: {
3060
			LIST(EXP) p = DEREF_list(exp_opn_args(e));
3061
			if (depends_on_exp_list(p, pids, use)) {
3062
				return (1);
3063
			}
3064
			break;
3065
		}
3066
		case exp_location_tag: {
3067
			EXP a = DEREF_exp(exp_location_arg(e));
3068
			if (depends_on_exp(a, pids, use)) {
3069
				return (1);
3070
			}
3071
			break;
3072
		}
3073
		case exp_dummy_tag: {
3074
			EXP a = DEREF_exp(exp_dummy_value(e));
3075
			if (depends_on_exp(a, pids, use)) {
3076
				return (1);
3077
			}
3078
			break;
3079
		}
3080
		}
2 7u83 3081
	}
7 7u83 3082
	return (0);
2 7u83 3083
}
3084
 
3085
 
3086
/*
3087
    DOES AN OFFSET DEPEND ON A TEMPLATE PARAMETER?
3088
 
3089
    This routine checks whether the offset off depends on one of the
3090
    template parameters pids.
3091
*/
3092
 
7 7u83 3093
int
3094
depends_on_off(OFFSET off, LIST(IDENTIFIER) pids, int use)
2 7u83 3095
{
7 7u83 3096
	if (!IS_NULL_off(off)) {
3097
		ASSERT(ORDER_off == 13);
3098
		switch (TAG_off(off)) {
3099
		case off_zero_tag: {
3100
			TYPE t = DEREF_type(off_zero_type(off));
3101
			if (depends_on(t, pids)) {
3102
				return (1);
3103
			}
3104
			break;
3105
		}
3106
		case off_type_tag: {
3107
			TYPE t = DEREF_type(off_type_type(off));
3108
			if (depends_on(t, pids)) {
3109
				return (1);
3110
			}
3111
			break;
3112
		}
3113
		case off_array_tag: {
3114
			TYPE t = DEREF_type(off_array_type(off));
3115
			if (depends_on(t, pids)) {
3116
				return (1);
3117
			}
3118
			break;
3119
		}
3120
		case off_extra_tag: {
3121
			TYPE t = DEREF_type(off_extra_type(off));
3122
			if (depends_on(t, pids)) {
3123
				return (1);
3124
			}
3125
			break;
3126
		}
2 7u83 3127
#if 0
7 7u83 3128
		case off_base_tag: {
3129
			GRAPH graph = DEREF_graph(off_base_graph(off));
3130
			break;
3131
		}
3132
		case off_deriv_tag: {
3133
			GRAPH graph = DEREF_graph(off_deriv_graph(off));
3134
			OFFSET direct = DEREF_off(off_deriv_direct(off));
3135
			OFFSET indirect = DEREF_off(off_deriv_indirect(off));
3136
			break;
3137
		}
3138
		case off_member_tag: {
3139
			IDENTIFIER id = DEREF_id(off_member_id(off));
3140
			break;
3141
		}
2 7u83 3142
#endif
7 7u83 3143
		case off_ptr_mem_tag: {
3144
			EXP a = DEREF_exp(off_ptr_mem_arg(off));
3145
			if (depends_on_exp(a, pids, use)) {
3146
				return (1);
3147
			}
3148
			break;
3149
		}
3150
		case off_negate_tag: {
3151
			OFFSET a = DEREF_off(off_negate_arg(off));
3152
			if (depends_on_off(a, pids, use)) {
3153
				return (1);
3154
			}
3155
			break;
3156
		}
3157
		case off_plus_tag: {
3158
			OFFSET a = DEREF_off(off_plus_arg1(off));
3159
			OFFSET b = DEREF_off(off_plus_arg2(off));
3160
			if (depends_on_off(a, pids, use)) {
3161
				return (1);
3162
			}
3163
			if (depends_on_off(b, pids, use)) {
3164
				return (1);
3165
			}
3166
			break;
3167
		}
3168
		case off_mult_tag: {
3169
			OFFSET a = DEREF_off(off_mult_arg1(off));
3170
			EXP b = DEREF_exp(off_mult_arg2(off));
3171
			if (depends_on_off(a, pids, use)) {
3172
				return (1);
3173
			}
3174
			if (depends_on_exp(b, pids, use)) {
3175
				return (1);
3176
			}
3177
			break;
3178
		}
3179
		case off_ptr_diff_tag: {
3180
			EXP a = DEREF_exp(off_ptr_diff_ptr1(off));
3181
			EXP b = DEREF_exp(off_ptr_diff_ptr2(off));
3182
			if (depends_on_exp(a, pids, use)) {
3183
				return (1);
3184
			}
3185
			if (depends_on_exp(b, pids, use)) {
3186
				return (1);
3187
			}
3188
			break;
3189
		}
3190
		case off_token_tag: {
3191
			IDENTIFIER tid = DEREF_id(off_token_tok(off));
3192
			LIST(TOKEN) args = DEREF_list(off_token_args(off));
3193
			if (depends_on_param(tid, pids)) {
3194
				return (2);
3195
			}
3196
			if (depends_on_args(args, pids, use, 0)) {
3197
				return (1);
3198
			}
3199
			break;
3200
		}
3201
		}
2 7u83 3202
	}
7 7u83 3203
	return (0);
2 7u83 3204
}
3205
 
3206
 
3207
/*
3208
    DOES A TYPE DEPEND ON A TEMPLATE PARAMETER?
3209
 
3210
    This routine checks whether the type t depends on one of the template
3211
    parameters pids.
3212
*/
3213
 
7 7u83 3214
int
3215
depends_on(TYPE t, LIST(IDENTIFIER) pids)
2 7u83 3216
{
7 7u83 3217
	if (!IS_NULL_type(t)) {
3218
		ASSERT(ORDER_type == 18);
3219
		switch (TAG_type(t)) {
3220
		case type_ptr_tag:
3221
		case type_ref_tag: {
3222
			TYPE s = DEREF_type(type_ptr_etc_sub(t));
3223
			return (depends_on(s, pids));
2 7u83 3224
		}
7 7u83 3225
		case type_ptr_mem_tag: {
3226
			TYPE s = DEREF_type(type_ptr_mem_sub(t));
3227
			CLASS_TYPE cr = DEREF_ctype(type_ptr_mem_of(t));
3228
			TYPE r = DEREF_type(ctype_form(cr));
3229
			if (depends_on(s, pids)) {
3230
				return (1);
2 7u83 3231
			}
7 7u83 3232
			return (depends_on(r, pids));
2 7u83 3233
		}
7 7u83 3234
		case type_func_tag: {
3235
			TYPE r = DEREF_type(type_func_ret(t));
3236
			LIST(TYPE) p = DEREF_list(type_func_mtypes(t));
3237
			if (depends_on(r, pids)) {
3238
				return (1);
3239
			}
3240
			while (!IS_NULL_list(p)) {
3241
				TYPE s = DEREF_type(HEAD_list(p));
3242
				if (depends_on(s, pids)) {
3243
					return (1);
3244
				}
3245
				p = TAIL_list(p);
3246
			}
3247
			break;
2 7u83 3248
		}
7 7u83 3249
		case type_array_tag: {
3250
			TYPE s = DEREF_type(type_array_sub(t));
3251
			NAT n = DEREF_nat(type_array_size(t));
3252
			if (depends_on(s, pids)) {
3253
				return (1);
3254
			}
3255
			return (depends_on_nat(n, pids, 0));
2 7u83 3256
		}
7 7u83 3257
		case type_bitfield_tag: {
3258
			INT_TYPE it = DEREF_itype(type_bitfield_defn(t));
3259
			TYPE s = DEREF_type(itype_bitfield_sub(it));
3260
			NAT n = DEREF_nat(itype_bitfield_size(it));
3261
			if (depends_on(s, pids)) {
3262
				return (1);
3263
			}
3264
			return (depends_on_nat(n, pids, 0));
3265
		}
3266
		case type_compound_tag: {
3267
			CLASS_TYPE cs = DEREF_ctype(type_compound_defn(t));
3268
			IDENTIFIER cid = DEREF_id(ctype_name(cs));
3269
			return (depends_on_id(cid, pids, 0));
3270
		}
3271
		case type_enumerate_tag: {
3272
			ENUM_TYPE et = DEREF_etype(type_enumerate_defn(t));
3273
			IDENTIFIER eid = DEREF_id(etype_name(et));
3274
			return (depends_on_id(eid, pids, 0));
3275
		}
3276
		case type_token_tag: {
3277
			IDENTIFIER tid = DEREF_id(type_token_tok(t));
3278
			LIST(TOKEN) args = DEREF_list(type_token_args(t));
3279
			if (depends_on_param(tid, pids)) {
3280
				return (1);
3281
			}
3282
			if (depends_on_args(args, pids, 0, 0)) {
3283
				return (1);
3284
			}
3285
			if (IS_id_token(tid)) {
3286
				TOKEN sort = DEREF_tok(id_token_sort(tid));
3287
				if (IS_tok_type(sort)) {
3288
					BASE_TYPE bt;
3289
					bt = DEREF_btype(tok_type_kind(sort));
3290
					if (bt & btype_typename) {
3291
						/* Allow for typename */
3292
						return (depends_on_id(tid, pids,
3293
								      0));
3294
					}
3295
				}
3296
			}
3297
			break;
3298
		}
3299
		case type_templ_tag: {
3300
			int dep;
3301
			LIST(IDENTIFIER) qids;
3302
			TYPE s = DEREF_type(type_templ_defn(t));
3303
			TOKEN sort = DEREF_tok(type_templ_sort(t));
3304
			qids = DEREF_list(tok_templ_pids(sort));
3305
			while (!IS_NULL_list(qids)) {
3306
				/* Suppress template parameters */
3307
				IDENTIFIER qid = DEREF_id(HEAD_list(qids));
3308
				DECL_SPEC ds = DEREF_dspec(id_storage(qid));
3309
				ds |= dspec_ignore;
3310
				COPY_dspec(id_storage(qid), ds);
3311
				qids = TAIL_list(qids);
3312
			}
3313
			dep = depends_on(s, pids);
3314
			qids = DEREF_list(tok_templ_pids(sort));
3315
			while (!IS_NULL_list(qids)) {
3316
				/* Restore template parameters */
3317
				IDENTIFIER qid = DEREF_id(HEAD_list(qids));
3318
				DECL_SPEC ds = DEREF_dspec(id_storage(qid));
3319
				ds &= ~dspec_ignore;
3320
				COPY_dspec(id_storage(qid), ds);
3321
				qids = TAIL_list(qids);
3322
			}
3323
			return (dep);
3324
		}
3325
		}
2 7u83 3326
	}
7 7u83 3327
	return (0);
2 7u83 3328
}
3329
 
3330
 
3331
/*
3332
    DOES A FUNCTION CALL DEPEND ON A TEMPLATE PARAMETER?
3333
 
3334
    This routine checks whether the function call 'id ( args )' depends
3335
    on a template parameter.
3336
*/
3337
 
7 7u83 3338
int
3339
dependent_call(IDENTIFIER id, LIST(EXP) args)
2 7u83 3340
{
7 7u83 3341
	if (in_template_decl) {
3342
		/* Only check in a template declaration */
3343
		LIST(IDENTIFIER) pids = any_templ_param;
3344
		if (depends_on_id(id, pids, 0)) {
3345
			return (1);
3346
		}
3347
		if (IS_id_function_etc(id)) {
3348
			while (!IS_NULL_id(id)) {
3349
				TYPE t = DEREF_type(id_function_etc_type(id));
3350
				if (depends_on(t, pids)) {
3351
					return (1);
3352
				}
3353
				id = DEREF_id(id_function_etc_over(id));
3354
			}
3355
		}
3356
		while (!IS_NULL_list(args)) {
3357
			EXP a = DEREF_exp(HEAD_list(args));
3358
			if (!IS_NULL_exp(a)) {
3359
				/* Check argument type */
3360
				TYPE t = DEREF_type(exp_type(a));
3361
				if (depends_on(t, pids)) {
3362
					return (1);
3363
				}
3364
			}
3365
			args = TAIL_list(args);
3366
		}
2 7u83 3367
	}
7 7u83 3368
	return (0);
2 7u83 3369
}
3370
 
3371
 
3372
/*
3373
    DOES A FUNCTION CAST DEPEND ON A TEMPLATE PARAMETER?
3374
 
3375
    This routine checks whether the resolution of the overloaded function
3376
    id to the type t depends on a template parameter.
3377
*/
3378
 
7 7u83 3379
int
3380
dependent_cast(IDENTIFIER id, TYPE t)
2 7u83 3381
{
7 7u83 3382
	if (in_template_decl) {
3383
		/* Only check in a template declaration */
3384
		LIST(IDENTIFIER) pids = any_templ_param;
3385
		if (depends_on_id(id, pids, 0)) {
3386
			return (1);
3387
		}
3388
		if (depends_on(t, pids)) {
3389
			return (1);
3390
		}
3391
	}
3392
	return (0);
2 7u83 3393
}
3394
 
3395
 
3396
/*
3397
    DOES A CONVERSION DEPEND ON A TEMPLATE PARAMETER?
3398
 
3399
    This routine checks whether the conversion 't ( args )' depends
3400
    on a template parameter.
3401
*/
3402
 
7 7u83 3403
int
3404
dependent_conv(TYPE t, LIST(EXP) args)
2 7u83 3405
{
7 7u83 3406
	if (in_template_decl) {
3407
		/* Only check in a template declaration */
3408
		LIST(IDENTIFIER) pids = any_templ_param;
3409
		if (depends_on(t, pids)) {
3410
			return (1);
3411
		}
3412
		while (!IS_NULL_list(args)) {
3413
			EXP a = DEREF_exp(HEAD_list(args));
3414
			if (!IS_NULL_exp(a)) {
3415
				/* Check argument type */
3416
				TYPE s = DEREF_type(exp_type(a));
3417
				if (depends_on(s, pids)) {
3418
					return (1);
3419
				}
3420
			}
3421
			args = TAIL_list(args);
3422
		}
2 7u83 3423
	}
7 7u83 3424
	return (0);
2 7u83 3425
}
3426
 
3427
 
3428
/*
3429
    DOES AN IDENTIFIER DEPEND ON A TEMPLATE PARAMETER?
3430
 
3431
    This routine checks whether the identifier id depends on a template
3432
    parameter.
3433
*/
3434
 
7 7u83 3435
int
3436
dependent_id(IDENTIFIER id)
2 7u83 3437
{
7 7u83 3438
	if (in_template_decl) {
3439
		/* Only check in a template declaration */
3440
		LIST(IDENTIFIER) pids = any_templ_param;
3441
		if (depends_on_id(id, pids, 0)) {
3442
			return (1);
3443
		}
3444
	}
3445
	return (0);
2 7u83 3446
}
3447
 
3448
 
3449
/*
3450
    MARK THE IDENTIFIERS IN AN EXPRESSION AS USED
3451
 
3452
    This routine marks all the identifiers in the expression e as having
3453
    been used.  This routine is combined with the depends_on functions
3454
    only because they happen to give a convenient tree-walking skeleton.
3455
*/
3456
 
7 7u83 3457
void
3458
mark_used(EXP e)
2 7u83 3459
{
7 7u83 3460
	if (!suppress_usage) {
3461
		IGNORE depends_on_exp(e, NULL_list(IDENTIFIER), 1);
3462
	}
3463
	return;
2 7u83 3464
}
3465
 
3466
 
3467
/*
3468
    FIND AN INJECTED TYPE
3469
 
3470
    This routine modifies the type t which is injected from a template
3471
    into an enclosing scope (for example, a friend of a template class)
3472
    by qualifying it by copies of any unbound template qualifiers.
3473
*/
3474
 
7 7u83 3475
TYPE
3476
injected_type(TYPE t, int rec)
2 7u83 3477
{
7 7u83 3478
	IDENTIFIER pid = NULL_id;
3479
	LIST(NAMESPACE)lns = LIST_stack(namespace_stack);
3480
	while (!IS_NULL_list(lns)) {
3481
		NAMESPACE ns = DEREF_nspace(HEAD_list(lns));
3482
		IDENTIFIER id = DEREF_id(nspace_name(ns));
3483
		if (!IS_NULL_id(id)) {
3484
			if (!EQ_id(id, pid)) {
3485
				TYPE s = NULL_type;
3486
				switch (TAG_id(id)) {
3487
				case id_class_name_tag:
3488
				case id_class_alias_tag:
3489
					s = DEREF_type(id_class_name_etc_defn(id));
3490
					break;
3491
				case id_function_tag:
3492
				case id_mem_func_tag:
3493
				case id_stat_mem_func_tag:
3494
					s = DEREF_type(id_function_etc_type(id));
3495
					break;
3496
				}
3497
 
3498
				if (!IS_NULL_type(s) && IS_type_templ(s)) {
3499
					LIST(IDENTIFIER)pids;
3500
					TOKEN sort =
3501
					    DEREF_tok(type_templ_sort(s));
3502
					pids = DEREF_list(tok_templ_pids(sort));
3503
					if (depends_on(t, pids)) {
3504
						t = rename_templ_params(sort, t,
3505
									rec);
3506
					}
3507
				}
3508
				pid = id;
3509
			}
2 7u83 3510
		}
7 7u83 3511
		lns = TAIL_list(lns);
2 7u83 3512
	}
7 7u83 3513
	return (t);
2 7u83 3514
}
3515
 
3516
 
3517
/*
3518
    DUMMY TEMPLATE PARAMETER TYPE
3519
 
3520
    This variable gives a dummy template parameter type which allows the
3521
    propagation of types dependent in some non-obvious fashion on some
3522
    template parameter.
3523
*/
3524
 
7 7u83 3525
TYPE type_templ_param;
2 7u83 3526
 
3527
 
3528
/*
3529
    INITIALISE TEMPLATE ROUTINES
3530
 
3531
    This routine initialises the template routines.  In particular it
3532
    initialises the dummy template parameter type.
3533
*/
3534
 
7 7u83 3535
void
3536
init_templates(void)
2 7u83 3537
{
7 7u83 3538
	string s = ustrlit("<type>");
3539
	unsigned long h = hash(s);
3540
	HASHID nm = lookup_name(s, h, 0, lex_identifier);
3541
	IDENTIFIER id = DEREF_id(hashid_id(nm));
3542
	LIST(TOKEN) args = NULL_list(TOKEN);
3543
	TYPE t = make_dummy_type(crt_namespace, id, btype_template, args);
3544
	type_templ_param = t;
3545
	CONS_id(NULL_id, NULL_list(IDENTIFIER), any_templ_param);
3546
	CONS_id(NULL_id, NULL_list(IDENTIFIER), any_token_param);
3547
	return;
2 7u83 3548
}