Warning: Undefined variable $n in /usr/local/www/websvn.planix.org/include/diff_util.php on line 243

Warning: Undefined variable $n in /usr/local/www/websvn.planix.org/include/diff_util.php on line 247

Warning: Undefined variable $m in /usr/local/www/websvn.planix.org/include/diff_util.php on line 251
WebSVN – tendra.SVN – Diff – /trunk/src/producers/common/construct/template.c – Rev 2 and 7

Subversion Repositories tendra.SVN

Rev

Rev 2 | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

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