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 – /branches/tendra5/src/producers/common/construct/token.c – Rev 5 and 6

Subversion Repositories tendra.SVN

Rev

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

Rev 5 Rev 6
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
32
    		 Crown Copyright (c) 1997
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 85... Line 115...
85
 
115
 
86
    This routine returns the keyword associated with a type token of
116
    This routine returns the keyword associated with a type token of
87
    kind bt.
117
    kind bt.
88
*/
118
*/
89
 
119
 
90
int type_token_key
120
int
91
    PROTO_N ( ( bt ) )
-
 
92
    PROTO_T ( BASE_TYPE bt )
121
type_token_key(BASE_TYPE bt)
93
{
122
{
94
    int key = lex_type_Hcap ;
123
	int key = lex_type_Hcap;
95
    if ( bt & btype_float ) {
124
	if (bt & btype_float) {
96
	if ( bt & btype_star ) {
125
		if (bt & btype_star) {
97
	    key = lex_scalar_Hcap ;
126
			key = lex_scalar_Hcap;
98
	} else if ( bt & btype_int ) {
127
		} else if (bt & btype_int) {
99
	    key = lex_arith_Hcap ;
128
			key = lex_arith_Hcap;
100
	} else {
129
		} else {
101
	    key = lex_float_Hcap ;
130
			key = lex_float_Hcap;
102
	}
131
		}
103
    } else if ( bt & btype_int ) {
132
	} else if (bt & btype_int) {
104
	if ( bt & btype_signed ) {
133
		if (bt & btype_signed) {
105
	    key = lex_signed ;
134
			key = lex_signed;
106
	} else if ( bt & btype_unsigned ) {
135
		} else if (bt & btype_unsigned) {
107
	    key = lex_unsigned ;
136
			key = lex_unsigned;
108
	} else {
137
		} else {
109
	    key = lex_variety_Hcap ;
138
			key = lex_variety_Hcap;
-
 
139
		}
-
 
140
	} else if (bt == btype_class) {
-
 
141
		key = lex_class_Hcap;
-
 
142
	} else if (bt == btype_struct) {
-
 
143
		key = lex_struct_Hcap;
-
 
144
	} else if (bt == btype_union) {
-
 
145
		key = lex_union_Hcap;
110
	}
146
	}
111
    } else if ( bt == btype_class ) {
-
 
112
	key = lex_class_Hcap ;
-
 
113
    } else if ( bt == btype_struct ) {
-
 
114
	key = lex_struct_Hcap ;
-
 
115
    } else if ( bt == btype_union ) {
-
 
116
	key = lex_union_Hcap ;
-
 
117
    }
-
 
118
    return ( key ) ;
147
	return (key);
119
}
148
}
120
 
149
 
121
 
150
 
122
/*
151
/*
123
    CREATE A TYPE TOKEN
152
    CREATE A TYPE TOKEN
124
 
153
 
125
    This routine creates a type token of kind bt.
154
    This routine creates a type token of kind bt.
126
*/
155
*/
127
 
156
 
-
 
157
TOKEN
-
 
158
make_type_token(BASE_TYPE bt)
-
 
159
{
128
TOKEN make_type_token
160
	TOKEN tok;
-
 
161
	MAKE_tok_type(bt, NULL_type, tok);
-
 
162
	return (tok);
-
 
163
}
-
 
164
 
-
 
165
 
-
 
166
/*
129
    PROTO_N ( ( bt ) )
167
    CREATE AN EXPRESSION TOKEN
-
 
168
 
-
 
169
    This routine creates an expression token of type t.
-
 
170
*/
-
 
171
 
-
 
172
TOKEN
130
    PROTO_T ( BASE_TYPE bt )
173
make_exp_token(TYPE t, int lv, int c)
131
{
174
{
132
    TOKEN tok ;
175
	TOKEN tok;
133
    MAKE_tok_type ( bt, NULL_type, tok ) ;
-
 
134
    return ( tok ) ;
-
 
135
}
-
 
136
 
-
 
137
 
-
 
138
/*
-
 
139
    CREATE AN EXPRESSION TOKEN
-
 
140
 
-
 
141
    This routine creates an expression token of type t.
-
 
142
*/
-
 
143
 
-
 
144
TOKEN make_exp_token
-
 
145
    PROTO_N ( ( t, lv, c ) )
-
 
146
    PROTO_T ( TYPE t X int lv X int c )
-
 
147
{
-
 
148
    TOKEN tok ;
-
 
149
    if ( lv ) {
176
	if (lv) {
150
	t = lvalue_type ( t ) ;
177
		t = lvalue_type(t);
151
    } else {
178
	} else {
152
	t = rvalue_type ( t ) ;
179
		t = rvalue_type(t);
153
    }
180
	}
154
    object_type ( t, id_token_tag ) ;
181
	object_type(t, id_token_tag);
155
    MAKE_tok_exp ( t, c, NULL_exp, tok ) ;
182
	MAKE_tok_exp(t, c, NULL_exp, tok);
156
    return ( tok ) ;
183
	return (tok);
157
}
184
}
158
 
185
 
159
 
186
 
160
/*
187
/*
161
    CREATE A FUNCTION TOKEN
188
    CREATE A FUNCTION TOKEN
162
 
189
 
163
    This routine creates a function token of type t.
190
    This routine creates a function token of type t.
164
*/
191
*/
165
 
192
 
166
TOKEN make_func_token
193
TOKEN
167
    PROTO_N ( ( t ) )
-
 
168
    PROTO_T ( TYPE t )
194
make_func_token(TYPE t)
169
{
195
{
170
    int ell ;
196
	int ell;
171
    TOKEN tok ;
197
	TOKEN tok;
172
    if ( !IS_type_func ( t ) ) {
198
	if (!IS_type_func(t)) {
173
	report ( preproc_loc, ERR_token_func ( t ) ) ;
199
		report(preproc_loc, ERR_token_func(t));
174
	tok = make_exp_token ( t, 0, 0 ) ;
200
		tok = make_exp_token(t, 0, 0);
175
	return ( tok ) ;
201
		return (tok);
176
    }
202
	}
177
    ell = DEREF_int ( type_func_ellipsis ( t ) ) ;
203
	ell = DEREF_int(type_func_ellipsis(t));
178
    if ( ell & FUNC_NO_PARAMS ) {
204
	if (ell & FUNC_NO_PARAMS) {
179
	/* Map 't ()' to 't ( void )' */
205
		/* Map 't ()' to 't ( void )' */
180
	COPY_int ( type_func_ellipsis ( t ), FUNC_NONE ) ;
206
		COPY_int(type_func_ellipsis(t), FUNC_NONE);
181
    }
207
	}
182
    MAKE_tok_func ( t, tok ) ;
208
	MAKE_tok_func(t, tok);
183
    return ( tok ) ;
209
	return (tok);
184
}
210
}
185
 
211
 
186
 
212
 
187
/*
213
/*
188
    CREATE A MEMBER SELECTOR TOKEN
214
    CREATE A MEMBER SELECTOR TOKEN
189
 
215
 
190
    This routine creates a member selector token for a member of s of
216
    This routine creates a member selector token for a member of s of
191
    type t.  acc gives the member access.
217
    type t.  acc gives the member access.
192
*/
218
*/
193
 
219
 
194
TOKEN make_member_token
220
TOKEN
195
    PROTO_N ( ( t, s, acc ) )
-
 
196
    PROTO_T ( TYPE t X TYPE s X DECL_SPEC acc )
221
make_member_token(TYPE t, TYPE s, DECL_SPEC acc)
197
{
222
{
198
    TOKEN tok ;
223
	TOKEN tok;
199
    if ( !IS_type_compound ( s ) ) {
224
	if (!IS_type_compound(s)) {
200
	report ( preproc_loc, ERR_token_mem ( s ) ) ;
225
		report(preproc_loc, ERR_token_mem(s));
201
	tok = make_exp_token ( t, 0, 0 ) ;
226
		tok = make_exp_token(t, 0, 0);
202
	return ( tok ) ;
227
		return (tok);
203
    }
228
	}
204
#if LANGUAGE_CPP
229
#if LANGUAGE_CPP
205
    crt_access = acc ;
230
	crt_access = acc;
206
#else
231
#else
207
    UNUSED ( acc ) ;
232
	UNUSED(acc);
208
#endif
233
#endif
209
    MAKE_tok_member ( s, t, NULL_off, tok ) ;
234
	MAKE_tok_member(s, t, NULL_off, tok);
210
    return ( tok ) ;
235
	return (tok);
211
}
236
}
212
 
237
 
213
 
238
 
214
/*
239
/*
215
    CHECK A TOKEN PARAMETER OR RESULT SORT
240
    CHECK A TOKEN PARAMETER OR RESULT SORT
216
 
241
 
217
    Procedure tokens which take or return other procedure tokens are not
242
    Procedure tokens which take or return other procedure tokens are not
218
    allowed.  This routine checks the parameter token sort tok.
243
    allowed.  This routine checks the parameter token sort tok.
219
*/
244
*/
220
 
-
 
221
static TOKEN check_param_sort
-
 
222
    PROTO_N ( ( tok ) )
-
 
223
    PROTO_T ( TOKEN tok )
-
 
224
{
-
 
225
    if ( !IS_NULL_tok ( tok ) ) {
-
 
226
	if ( IS_tok_func ( tok ) ) {
-
 
227
	    tok = func_proc_token ( tok ) ;
-
 
228
	}
-
 
229
	if ( IS_tok_proc ( tok ) ) {
-
 
230
	    report ( preproc_loc, ERR_token_proc_high () ) ;
-
 
231
	    tok = DEREF_tok ( tok_proc_res ( tok ) ) ;
-
 
232
	}
-
 
233
    }
-
 
234
    return ( tok ) ;
-
 
235
}
-
 
236
 
-
 
237
 
-
 
238
/*
-
 
239
    BEGIN THE DEFINITION OF A PROCEDURE TOKEN
-
 
240
 
245
 
241
    This routine begins the construction of a procedure token.
-
 
242
*/
-
 
243
 
-
 
244
TOKEN begin_proc_token
246
static TOKEN
245
    PROTO_Z ()
247
check_param_sort(TOKEN tok)
246
{
248
{
247
    TOKEN tok ;
249
	if (!IS_NULL_tok(tok)) {
-
 
250
		if (IS_tok_func(tok)) {
248
    begin_param ( NULL_id ) ;
251
			tok = func_proc_token(tok);
-
 
252
		}
-
 
253
		if (IS_tok_proc(tok)) {
249
    MAKE_tok_proc ( NULL_tok, crt_namespace, lex_identifier, tok ) ;
254
			report(preproc_loc, ERR_token_proc_high());
-
 
255
			tok = DEREF_tok(tok_proc_res(tok));
-
 
256
		}
-
 
257
	}
250
    return ( tok ) ;
258
	return (tok);
251
}
259
}
252
 
260
 
253
 
261
 
254
/*
262
/*
-
 
263
    BEGIN THE DEFINITION OF A PROCEDURE TOKEN
-
 
264
 
-
 
265
    This routine begins the construction of a procedure token.
-
 
266
*/
-
 
267
 
-
 
268
TOKEN
-
 
269
begin_proc_token(void)
-
 
270
{
-
 
271
	TOKEN tok;
-
 
272
	begin_param(NULL_id);
-
 
273
	MAKE_tok_proc(NULL_tok, crt_namespace, lex_identifier, tok);
-
 
274
	return (tok);
-
 
275
}
-
 
276
 
-
 
277
 
-
 
278
/*
255
    SET THE PARAMETER NUMBERS FOR A PROCEDURE TOKEN
279
    SET THE PARAMETER NUMBERS FOR A PROCEDURE TOKEN
256
 
280
 
257
    This routine sets the token numbers for the list of procedure token
281
    This routine sets the token numbers for the list of procedure token
258
    parameters p.
282
    parameters p.
259
*/
283
*/
260
 
284
 
261
void set_proc_token
285
void
262
    PROTO_N ( ( p ) )
-
 
263
    PROTO_T ( LIST ( IDENTIFIER ) p )
286
set_proc_token(LIST(IDENTIFIER) p)
264
{
287
{
265
    ulong n = 0 ;
288
	ulong n = 0;
266
    while ( !IS_NULL_list ( p ) ) {
289
	while (!IS_NULL_list(p)) {
267
	IDENTIFIER pid = DEREF_id ( HEAD_list ( p ) ) ;
290
		IDENTIFIER pid = DEREF_id(HEAD_list(p));
268
	if ( !IS_NULL_id ( pid ) ) {
291
		if (!IS_NULL_id(pid)) {
269
	    COPY_ulong ( id_no ( pid ), n ) ;
292
			COPY_ulong(id_no(pid), n);
-
 
293
		}
-
 
294
		n++;
-
 
295
		p = TAIL_list(p);
270
	}
296
	}
271
	n++ ;
-
 
272
	p = TAIL_list ( p ) ;
-
 
273
    }
-
 
274
    return ;
297
	return;
275
}
298
}
276
 
299
 
277
 
300
 
278
/*
301
/*
279
    CONTINUE THE DEFINITION OF A PROCEDURE TOKEN
302
    CONTINUE THE DEFINITION OF A PROCEDURE TOKEN
280
 
303
 
281
    This routine continues the definition of the procedure token prev
304
    This routine continues the definition of the procedure token prev
282
    by adding the lists of bound and program parameters, p and q.
305
    by adding the lists of bound and program parameters, p and q.
283
*/
306
*/
284
 
307
 
285
TOKEN cont_proc_token
308
TOKEN
286
    PROTO_N ( ( prev, p, q ) )
-
 
287
    PROTO_T ( TOKEN prev X LIST ( IDENTIFIER ) p X LIST ( IDENTIFIER ) q )
309
cont_proc_token(TOKEN prev, LIST(IDENTIFIER) p, LIST(IDENTIFIER) q)
288
{
310
{
289
    if ( !IS_NULL_tok ( prev ) ) {
311
	if (!IS_NULL_tok(prev)) {
290
	unsigned n ;
312
		unsigned n;
291
	if ( !EQ_list ( p, q ) ) {
313
		if (!EQ_list(p, q)) {
292
	    int eq = 1 ;
314
			int eq = 1;
293
	    LIST ( IDENTIFIER ) ps = p ;
315
			LIST(IDENTIFIER) ps = p;
294
	    LIST ( IDENTIFIER ) qs = q ;
316
			LIST(IDENTIFIER) qs = q;
295
	    while ( !IS_NULL_list ( ps ) && !IS_NULL_list ( qs ) ) {
317
			while (!IS_NULL_list(ps) && !IS_NULL_list(qs)) {
296
		IDENTIFIER ip = DEREF_id ( HEAD_list ( ps ) ) ;
318
				IDENTIFIER ip = DEREF_id(HEAD_list(ps));
297
		IDENTIFIER iq = DEREF_id ( HEAD_list ( qs ) ) ;
319
				IDENTIFIER iq = DEREF_id(HEAD_list(qs));
298
		if ( !EQ_id ( ip, iq ) ) {
320
				if (!EQ_id(ip, iq)) {
299
		    eq = 0 ;
321
					eq = 0;
300
		    break ;
322
					break;
301
		}
323
				}
302
		ps = TAIL_list ( ps ) ;
324
				ps = TAIL_list(ps);
303
		qs = TAIL_list ( qs ) ;
325
				qs = TAIL_list(qs);
304
	    }
326
			}
305
	    if ( eq && EQ_list ( ps, qs ) ) {
327
			if (eq && EQ_list(ps, qs)) {
306
		/* Parameter lists match */
328
				/* Parameter lists match */
307
		DESTROY_list ( q, SIZE_id ) ;
329
				DESTROY_list(q, SIZE_id);
308
		q = p ;
330
				q = p;
309
	    } else {
331
			} else {
310
		set_proc_token ( q ) ;
332
				set_proc_token(q);
311
	    }
333
			}
312
	}
334
		}
313
	set_proc_token ( p ) ;
335
		set_proc_token(p);
314
	COPY_list ( tok_proc_bids ( prev ), p ) ;
336
		COPY_list(tok_proc_bids(prev), p);
315
	COPY_list ( tok_proc_pids ( prev ), q ) ;
337
		COPY_list(tok_proc_pids(prev), q);
316
	n = LENGTH_list ( q ) ;
338
		n = LENGTH_list(q);
317
	IGNORE check_value ( OPT_VAL_macro_pars, ( ulong ) n ) ;
339
		IGNORE check_value(OPT_VAL_macro_pars,(ulong)n);
318
    }
340
	}
319
    return ( prev ) ;
341
	return (prev);
320
}
342
}
321
 
343
 
322
 
344
 
323
/*
345
/*
324
    COMPLETE THE DEFINITION OF A PROCEDURE TOKEN
346
    COMPLETE THE DEFINITION OF A PROCEDURE TOKEN
325
 
347
 
326
    This routine completes the definition of the procedure token prev by
348
    This routine completes the definition of the procedure token prev by
327
    filling in the token result sort res.
349
    filling in the token result sort res.
328
*/
350
*/
329
 
351
 
330
TOKEN end_proc_token
352
TOKEN
331
    PROTO_N ( ( prev, res ) )
-
 
332
    PROTO_T ( TOKEN prev X TOKEN res )
353
end_proc_token(TOKEN prev, TOKEN res)
333
{
354
{
334
    res = check_param_sort ( res ) ;
355
	res = check_param_sort(res);
335
    if ( !IS_NULL_tok ( prev ) ) {
356
	if (!IS_NULL_tok(prev)) {
336
	COPY_tok ( tok_proc_res ( prev ), res ) ;
357
		COPY_tok(tok_proc_res(prev), res);
337
    }
358
	}
338
    end_param () ;
359
	end_param();
339
    return ( prev ) ;
360
	return (prev);
340
}
361
}
341
 
362
 
342
 
363
 
343
/*
364
/*
344
    CREATE A TOKEN PARAMETER
365
    CREATE A TOKEN PARAMETER
345
 
366
 
346
    This routine declares a token bound parameter of sort tok with name
367
    This routine declares a token bound parameter of sort tok with name
347
    id, which belongs to the tag namespace if tag is true.
368
    id, which belongs to the tag namespace if tag is true.
348
*/
369
*/
349
 
370
 
350
IDENTIFIER make_tok_param
371
IDENTIFIER
351
    PROTO_N ( ( tok, tag, id ) )
-
 
352
    PROTO_T ( TOKEN tok X int tag X IDENTIFIER id )
372
make_tok_param(TOKEN tok, int tag, IDENTIFIER id)
353
{
373
{
354
    if ( IS_NULL_id ( id ) ) {
374
	if (IS_NULL_id(id)) {
355
	HASHID nm = lookup_anon () ;
375
		HASHID nm = lookup_anon();
356
	id = DEREF_id ( hashid_id ( nm ) ) ;
376
		id = DEREF_id(hashid_id(nm));
357
    }
377
	}
358
    tok = check_param_sort ( tok ) ;
378
	tok = check_param_sort(tok);
359
    id = make_token_decl ( tok, tag, id, NULL_id ) ;
379
	id = make_token_decl(tok, tag, id, NULL_id);
-
 
380
	if (do_dump) {
360
    if ( do_dump ) dump_token_param ( id ) ;
381
		dump_token_param(id);
-
 
382
	}
361
    return ( id ) ;
383
	return (id);
362
}
384
}
363
 
385
 
364
 
386
 
365
/*
387
/*
366
    FIND A TOKEN MEMBER
388
    FIND A TOKEN MEMBER
367
 
389
 
368
    This routine looks up a member id of the class type t.  If the member
390
    This routine looks up a member id of the class type t.  If the member
369
    is not found or t is not a class type then an error message is printed
391
    is not found or t is not a class type then an error message is printed
370
    and the null identifier is returned.
392
    and the null identifier is returned.
371
*/
393
*/
372
 
394
 
373
IDENTIFIER tok_member
395
IDENTIFIER
374
    PROTO_N ( ( id, t, force ) )
-
 
375
    PROTO_T ( IDENTIFIER id X TYPE t X int force )
396
tok_member(IDENTIFIER id, TYPE t, int force)
376
{
397
{
377
    if ( IS_type_compound ( t ) ) {
398
	if (IS_type_compound(t)) {
378
	HASHID nm = DEREF_hashid ( id_name ( id ) ) ;
399
		HASHID nm = DEREF_hashid(id_name(id));
379
	CLASS_TYPE ct = DEREF_ctype ( type_compound_defn ( t ) ) ;
400
		CLASS_TYPE ct = DEREF_ctype(type_compound_defn(t));
380
	NAMESPACE ns = DEREF_nspace ( ctype_member ( ct ) ) ;
401
		NAMESPACE ns = DEREF_nspace(ctype_member(ct));
381
	IDENTIFIER fid = search_id ( ns, nm, 0, 0 ) ;
402
		IDENTIFIER fid = search_id(ns, nm, 0, 0);
382
	if ( IS_NULL_id ( fid ) ) {
403
		if (IS_NULL_id(fid)) {
383
	    /* Member not declared */
404
			/* Member not declared */
384
	    if ( force ) {
405
			if (force) {
385
		/* Report error */
406
				/* Report error */
-
 
407
				report(preproc_loc,
386
		report ( preproc_loc, ERR_lookup_qual_bad ( id, ns ) ) ;
408
				       ERR_lookup_qual_bad(id, ns));
387
	    } else {
409
			} else {
388
		/* Create token member */
410
				/* Create token member */
389
		TOKEN tok ;
411
				TOKEN tok;
390
		HASHID fnm = lookup_anon () ;
412
				HASHID fnm = lookup_anon();
391
		fid = DEREF_id ( hashid_id ( fnm ) ) ;
413
				fid = DEREF_id(hashid_id(fnm));
392
		MAKE_tok_member ( t, type_error, NULL_off, tok ) ;
414
				MAKE_tok_member(t, type_error, NULL_off, tok);
393
		fid = make_token_decl ( tok, 0, id, fid ) ;
415
				fid = make_token_decl(tok, 0, id, fid);
394
		fid = DEREF_id ( id_token_alt ( fid ) ) ;
416
				fid = DEREF_id(id_token_alt(fid));
395
	    }
417
			}
396
	}
418
		}
397
	return ( fid ) ;
419
		return (fid);
398
    }
420
	}
399
    report ( preproc_loc, ERR_token_mem ( t ) ) ;
421
	report(preproc_loc, ERR_token_mem(t));
400
    return ( NULL_id ) ;
422
	return (NULL_id);
401
}
423
}
402
 
424
 
403
 
425
 
404
/*
426
/*
405
    CREATE A TOKEN PROGRAM PARAMETER
427
    CREATE A TOKEN PROGRAM PARAMETER
406
 
428
 
407
    This routine declares a token program parameter named id.  tt gives
429
    This routine declares a token program parameter named id.  tt gives
408
    the associated token sort, while t gives the structure type if this
430
    the associated token sort, while t gives the structure type if this
409
    denotes a member token or the parameter type if this denotes a type
431
    denotes a member token or the parameter type if this denotes a type
410
    token.
432
    token.
411
*/
433
*/
412
 
434
 
413
IDENTIFIER prog_tok_param
435
IDENTIFIER
414
    PROTO_N ( ( id, t, tt, p ) )
-
 
415
    PROTO_T ( IDENTIFIER id X TYPE t X unsigned tt X LIST ( IDENTIFIER ) p )
436
prog_tok_param(IDENTIFIER id, TYPE t, unsigned tt, LIST(IDENTIFIER) p)
416
{
437
{
417
    /* Look up member identifier */
438
	/* Look up member identifier */
418
    IDENTIFIER tid = id ;
439
	IDENTIFIER tid = id;
419
    if ( tt == tok_member_tag ) {
440
	if (tt == tok_member_tag) {
420
	tid = tok_member ( tid, t, 1 ) ;
441
		tid = tok_member(tid, t, 1);
-
 
442
		if (IS_NULL_id(tid)) {
-
 
443
			return (NULL_id);
-
 
444
		}
-
 
445
	}
-
 
446
 
-
 
447
	/* Check through tokens */
-
 
448
	while (!IS_NULL_list(p)) {
-
 
449
		IDENTIFIER pid = DEREF_id(HEAD_list(p));
421
	if ( IS_NULL_id ( tid ) ) return ( NULL_id ) ;
450
		if (!IS_NULL_id(pid) && IS_id_token(pid)) {
-
 
451
			IDENTIFIER qid = DEREF_id(id_token_alt(pid));
-
 
452
			if (EQ_id(qid, tid)) {
-
 
453
				/* Matching token found */
-
 
454
				TOKEN tok = DEREF_tok(id_token_sort(pid));
-
 
455
				unsigned pt = TAG_tok(tok);
-
 
456
				switch (pt) {
-
 
457
				case tok_nat_tag:
-
 
458
				case tok_snat_tag:
-
 
459
					pt = tok_exp_tag;
-
 
460
					break;
-
 
461
				case tok_templ_tag:
-
 
462
				case tok_func_tag:
-
 
463
					pt = tok_proc_tag;
-
 
464
					break;
-
 
465
				}
-
 
466
				if (pt != tt) {
-
 
467
					/* Wrong sort given for token
-
 
468
					 * parameter */
-
 
469
					report(preproc_loc,
-
 
470
					       ERR_token_arg_sort(pid));
422
    }
471
				}
-
 
472
				return (pid);
-
 
473
			}
-
 
474
		}
-
 
475
		p = TAIL_list(p);
-
 
476
	}
423
 
477
 
424
    /* Check through tokens */
478
	/* Allow for complex type parameters */
425
    while ( !IS_NULL_list ( p ) ) {
-
 
426
	IDENTIFIER pid = DEREF_id ( HEAD_list ( p ) ) ;
-
 
427
	if ( !IS_NULL_id ( pid ) && IS_id_token ( pid ) ) {
-
 
428
	    IDENTIFIER qid = DEREF_id ( id_token_alt ( pid ) ) ;
-
 
429
	    if ( EQ_id ( qid, tid ) ) {
479
	if (tt == tok_type_tag) {
430
		/* Matching token found */
480
		HASHID nm = lookup_anon();
431
		TOKEN tok = DEREF_tok ( id_token_sort ( pid ) ) ;
481
		int tq = crt_templ_qualifier;
432
		unsigned pt = TAG_tok ( tok ) ;
482
		QUALIFIER cq = crt_id_qualifier;
433
		switch ( pt ) {
-
 
434
		    case tok_nat_tag :
483
		crt_id_qualifier = qual_none;
435
		    case tok_snat_tag : {
484
		crt_templ_qualifier = 0;
436
			pt = tok_exp_tag ;
485
		tid = DEREF_id(hashid_id(nm));
437
			break ;
-
 
438
		    }
-
 
439
		    case tok_templ_tag :
486
		tid = make_object_decl(dspec_typedef, t, tid, 0);
440
		    case tok_func_tag : {
487
		crt_templ_qualifier = tq;
441
			pt = tok_proc_tag ;
488
		crt_id_qualifier = cq;
442
			break ;
-
 
443
		    }
-
 
444
		}
-
 
445
		if ( pt != tt ) {
-
 
446
		    /* Wrong sort given for token parameter */
-
 
447
		    report ( preproc_loc, ERR_token_arg_sort ( pid ) ) ;
-
 
448
		}
-
 
449
		return ( pid ) ;
489
		return (tid);
450
	    }
-
 
451
	}
490
	}
452
	p = TAIL_list ( p ) ;
-
 
453
    }
-
 
454
 
-
 
455
    /* Allow for complex type parameters */
-
 
456
    if ( tt == tok_type_tag ) {
-
 
457
	HASHID nm = lookup_anon () ;
-
 
458
	int tq = crt_templ_qualifier ;
-
 
459
	QUALIFIER cq = crt_id_qualifier ;
-
 
460
	crt_id_qualifier = qual_none ;
-
 
461
	crt_templ_qualifier = 0 ;
-
 
462
	tid = DEREF_id ( hashid_id ( nm ) ) ;
-
 
463
	tid = make_object_decl ( dspec_typedef, t, tid, 0 ) ;
-
 
464
	crt_templ_qualifier = tq ;
-
 
465
	crt_id_qualifier = cq ;
-
 
466
	return ( tid ) ;
-
 
467
    }
-
 
468
    report ( preproc_loc, ERR_token_arg_bad ( tid ) ) ;
491
	report(preproc_loc, ERR_token_arg_bad(tid));
469
    return ( NULL_id ) ;
492
	return (NULL_id);
470
}
493
}
471
 
494
 
472
 
495
 
473
/*
496
/*
474
    FIND AN UNDERLYING PROCEDURE TOKEN
497
    FIND AN UNDERLYING PROCEDURE TOKEN
475
 
498
 
476
    This routine returns the procedure token underlying the function
499
    This routine returns the procedure token underlying the function
477
    token tok, creating this if necessary.
500
    token tok, creating this if necessary.
478
*/
501
*/
479
 
502
 
480
TOKEN func_proc_token
503
TOKEN
481
    PROTO_N ( ( tok ) )
-
 
482
    PROTO_T ( TOKEN tok )
504
func_proc_token(TOKEN tok)
483
{
505
{
484
    TOKEN res ;
506
	TOKEN res;
485
    if ( !IS_tok_func ( tok ) ) return ( tok ) ;
507
	if (!IS_tok_func(tok)) {
-
 
508
		return (tok);
-
 
509
	}
486
    res = DEREF_tok ( tok_func_proc ( tok ) ) ;
510
	res = DEREF_tok(tok_func_proc(tok));
487
    if ( IS_NULL_tok ( res ) ) {
511
	if (IS_NULL_tok(res)) {
488
	TYPE t = DEREF_type ( tok_func_type ( tok ) ) ;
512
		TYPE t = DEREF_type(tok_func_type(tok));
489
	int ell = DEREF_int ( type_func_ellipsis ( t ) ) ;
513
		int ell = DEREF_int(type_func_ellipsis(t));
490
	if ( ell & FUNC_ELLIPSIS ) {
514
		if (ell & FUNC_ELLIPSIS) {
491
	    res = tok ;
515
			res = tok;
492
	} else {
516
		} else {
493
	    TOKEN rtok ;
517
			TOKEN rtok;
494
	    IDENTIFIER pid ;
518
			IDENTIFIER pid;
495
	    EXP e = NULL_exp ;
519
			EXP e = NULL_exp;
496
	    LIST ( IDENTIFIER ) qids ;
520
			LIST(IDENTIFIER) qids;
497
	    IDENTIFIER fn = DEREF_id ( tok_func_defn ( tok ) ) ;
521
			IDENTIFIER fn = DEREF_id(tok_func_defn(tok));
498
	    TYPE r = DEREF_type ( type_func_ret ( t ) ) ;
522
			TYPE r = DEREF_type(type_func_ret(t));
499
	    LIST ( TYPE ) p = DEREF_list ( type_func_mtypes ( t ) ) ;
523
			LIST(TYPE) p = DEREF_list(type_func_mtypes(t));
500
	    LIST ( IDENTIFIER ) pids = NULL_list ( IDENTIFIER ) ;
524
			LIST(IDENTIFIER) pids = NULL_list(IDENTIFIER);
501
	    res = begin_proc_token () ;
525
			res = begin_proc_token();
502
	    while ( !IS_NULL_list ( p ) ) {
526
			while (!IS_NULL_list(p)) {
503
		/* Normal function parameters */
527
				/* Normal function parameters */
504
		TYPE s = DEREF_type ( HEAD_list ( p ) ) ;
528
				TYPE s = DEREF_type(HEAD_list(p));
505
		if ( pass_complex_type ( s ) ) {
529
				if (pass_complex_type(s)) {
506
		    MAKE_type_ptr ( cv_none, s, s ) ;
530
					MAKE_type_ptr(cv_none, s, s);
-
 
531
				}
-
 
532
				MAKE_tok_exp(s, 0, NULL_exp, rtok);
-
 
533
				pid = make_tok_param(rtok, 0, NULL_id);
-
 
534
				CONS_id(pid, pids, pids);
-
 
535
				p = TAIL_list(p);
-
 
536
			}
-
 
537
			/* Extra constructor parameters ... */
-
 
538
			pids = REVERSE_list(pids);
-
 
539
			qids = pids;
-
 
540
			if (pass_complex_type(r)) {
-
 
541
				/* Complex function return */
-
 
542
				TYPE s;
-
 
543
				MAKE_type_ptr(cv_none, r, s);
-
 
544
				MAKE_tok_exp(s, 0, NULL_exp, rtok);
-
 
545
				pid = make_tok_param(rtok, 0, NULL_id);
-
 
546
				CONS_id(pid, pids, pids);
-
 
547
				r = type_void;
-
 
548
			}
-
 
549
			res = cont_proc_token(res, pids, qids);
-
 
550
			if (!IS_NULL_id(fn)) {
-
 
551
				/* Token already defined */
-
 
552
				MAKE_exp_value(t, e);
-
 
553
			}
-
 
554
			MAKE_tok_exp(r, 0, e, rtok);
-
 
555
			res = end_proc_token(res, rtok);
507
		}
556
		}
508
		MAKE_tok_exp ( s, 0, NULL_exp, rtok ) ;
-
 
509
		pid = make_tok_param ( rtok, 0, NULL_id ) ;
-
 
510
		CONS_id ( pid, pids, pids ) ;
-
 
511
		p = TAIL_list ( p ) ;
-
 
512
	    }
-
 
513
	    /* Extra constructor parameters ... */
-
 
514
	    pids = REVERSE_list ( pids ) ;
-
 
515
	    qids = pids ;
-
 
516
	    if ( pass_complex_type ( r ) ) {
-
 
517
		/* Complex function return */
-
 
518
		TYPE s ;
-
 
519
		MAKE_type_ptr ( cv_none, r, s ) ;
557
		COPY_tok(tok_func_proc(tok), res);
520
		MAKE_tok_exp ( s, 0, NULL_exp, rtok ) ;
-
 
521
		pid = make_tok_param ( rtok, 0, NULL_id ) ;
-
 
522
		CONS_id ( pid, pids, pids ) ;
-
 
523
		r = type_void ;
-
 
524
	    }
-
 
525
	    res = cont_proc_token ( res, pids, qids ) ;
-
 
526
	    if ( !IS_NULL_id ( fn ) ) {
-
 
527
		/* Token already defined */
-
 
528
		MAKE_exp_value ( t, e ) ;
-
 
529
	    }
-
 
530
	    MAKE_tok_exp ( r, 0, e, rtok ) ;
-
 
531
	    res = end_proc_token ( res, rtok ) ;
-
 
532
	}
558
	}
533
	COPY_tok ( tok_func_proc ( tok ), res ) ;
-
 
534
    }
-
 
535
    return ( res ) ;
559
	return (res);
536
}
560
}
537
 
561
 
538
 
562
 
539
/*
563
/*
540
    EXPAND A TOKEN VALUE
564
    EXPAND A TOKEN VALUE
541
 
565
 
542
    This routine expands the token value tok. If force is true then a copy
566
    This routine expands the token value tok. If force is true then a copy
543
    is always made.
567
    is always made.
544
*/
568
*/
545
 
569
 
546
TOKEN expand_sort
570
TOKEN
547
    PROTO_N ( ( tok, rec, force ) )
-
 
548
    PROTO_T ( TOKEN tok X int rec X int force )
571
expand_sort(TOKEN tok, int rec, int force)
549
{
572
{
550
    if ( !IS_NULL_tok ( tok ) ) {
573
	if (!IS_NULL_tok(tok)) {
551
	unsigned tag = TAG_tok ( tok ) ;
574
		unsigned tag = TAG_tok(tok);
552
	switch ( tag ) {
575
		switch (tag) {
553
	    case tok_exp_tag : {
576
		case tok_exp_tag: {
554
		/* Expression tokens */
577
			/* Expression tokens */
555
		EXP a1 = DEREF_exp ( tok_exp_value ( tok ) ) ;
578
			EXP a1 = DEREF_exp(tok_exp_value(tok));
556
		EXP a2 = expand_exp ( a1, rec, 0 ) ;
579
			EXP a2 = expand_exp(a1, rec, 0);
557
		if ( force || !eq_exp_exact ( a1, a2 ) ) {
580
			if (force || !eq_exp_exact(a1, a2)) {
558
		    int c = DEREF_int ( tok_exp_constant ( tok ) ) ;
581
				int c = DEREF_int(tok_exp_constant(tok));
559
		    TYPE t = DEREF_type ( tok_exp_type ( tok ) ) ;
582
				TYPE t = DEREF_type(tok_exp_type(tok));
560
		    t = expand_type ( t, rec ) ;
583
				t = expand_type(t, rec);
561
		    MAKE_tok_exp ( t, c, a2, tok ) ;
584
				MAKE_tok_exp(t, c, a2, tok);
562
		}
585
			}
563
		break ;
586
			break;
564
	    }
587
		}
565
	    case tok_nat_tag :
588
		case tok_nat_tag:
566
	    case tok_snat_tag : {
589
		case tok_snat_tag: {
567
		/* Integral constant tokens */
590
			/* Integral constant tokens */
568
		ERROR err = NULL_err ;
591
			ERROR err = NULL_err;
569
		NAT n1 = DEREF_nat ( tok_nat_etc_value ( tok ) ) ;
592
			NAT n1 = DEREF_nat(tok_nat_etc_value(tok));
570
		NAT n2 = expand_nat ( n1, rec, 0, &err ) ;
593
			NAT n2 = expand_nat(n1, rec, 0, &err);
571
		if ( !IS_NULL_err ( err ) ) report ( crt_loc, err ) ;
594
			if (!IS_NULL_err(err)) {
-
 
595
				report(crt_loc, err);
-
 
596
			}
572
		if ( force || !EQ_nat ( n1, n2 ) ) {
597
			if (force || !EQ_nat(n1, n2)) {
573
		    MAKE_tok_nat_etc ( tag, n2, tok ) ;
598
				MAKE_tok_nat_etc(tag, n2, tok);
574
		}
599
			}
575
		break ;
600
			break;
576
	    }
601
		}
577
	    case tok_stmt_tag : {
602
		case tok_stmt_tag: {
578
		/* Statement tokens */
603
			/* Statement tokens */
579
		EXP a1 = DEREF_exp ( tok_stmt_value ( tok ) ) ;
604
			EXP a1 = DEREF_exp(tok_stmt_value(tok));
580
		EXP a2 = expand_exp ( a1, rec, 1 ) ;
605
			EXP a2 = expand_exp(a1, rec, 1);
581
		if ( force || !eq_exp_exact ( a1, a2 ) ) {
606
			if (force || !eq_exp_exact(a1, a2)) {
582
		    EXP b = get_parent_stmt ( a1 ) ;
607
				EXP b = get_parent_stmt(a1);
583
		    set_parent_stmt ( a2, b ) ;
608
				set_parent_stmt(a2, b);
584
		    MAKE_tok_stmt ( a2, tok ) ;
609
				MAKE_tok_stmt(a2, tok);
585
		}
610
			}
586
		break ;
611
			break;
587
	    }
612
		}
588
	    case tok_member_tag : {
613
		case tok_member_tag: {
589
		/* Member tokens */
614
			/* Member tokens */
590
		OFFSET a1 = DEREF_off ( tok_member_value ( tok ) ) ;
615
			OFFSET a1 = DEREF_off(tok_member_value(tok));
591
		OFFSET a2 = expand_offset ( a1, rec ) ;
616
			OFFSET a2 = expand_offset(a1, rec);
592
		if ( force || !EQ_off ( a1, a2 ) ) {
617
			if (force || !EQ_off(a1, a2)) {
593
		    TYPE s = DEREF_type ( tok_member_of ( tok ) ) ;
618
				TYPE s = DEREF_type(tok_member_of(tok));
594
		    TYPE t = DEREF_type ( tok_member_type ( tok ) ) ;
619
				TYPE t = DEREF_type(tok_member_type(tok));
595
		    s = expand_type ( s, rec ) ;
620
				s = expand_type(s, rec);
596
		    t = expand_type ( t, rec ) ;
621
				t = expand_type(t, rec);
597
		    MAKE_tok_member ( s, t, a2, tok ) ;
622
				MAKE_tok_member(s, t, a2, tok);
598
		}
623
			}
599
		break ;
624
			break;
600
	    }
625
		}
601
	    case tok_type_tag : {
626
		case tok_type_tag: {
602
		/* Type tokens */
627
			/* Type tokens */
603
		TYPE t1 = DEREF_type ( tok_type_value ( tok ) ) ;
628
			TYPE t1 = DEREF_type(tok_type_value(tok));
604
		TYPE t2 = expand_type ( t1, rec ) ;
629
			TYPE t2 = expand_type(t1, rec);
605
		if ( force || !EQ_type ( t1, t2 ) ) {
630
			if (force || !EQ_type(t1, t2)) {
606
		    BASE_TYPE bs = DEREF_btype ( tok_type_kind ( tok ) ) ;
631
				BASE_TYPE bs = DEREF_btype(tok_type_kind(tok));
607
		    MAKE_tok_type ( bs, t2, tok ) ;
632
				MAKE_tok_type(bs, t2, tok);
608
		}
633
			}
609
		break ;
634
			break;
610
	    }
635
		}
611
	    case tok_class_tag : {
636
		case tok_class_tag: {
612
		/* Template class tokens */
637
			/* Template class tokens */
613
		IDENTIFIER cid = DEREF_id ( tok_class_value ( tok ) ) ;
638
			IDENTIFIER cid = DEREF_id(tok_class_value(tok));
614
		/* NOT YET IMPLEMENTED */
639
			/* NOT YET IMPLEMENTED */
615
		if ( force ) {
640
			if (force) {
616
		    TYPE s = DEREF_type ( tok_class_type ( tok ) ) ;
641
				TYPE s = DEREF_type(tok_class_type(tok));
617
		    TYPE t = DEREF_type ( tok_class_alt ( tok ) ) ;
642
				TYPE t = DEREF_type(tok_class_alt(tok));
618
		    MAKE_tok_class ( s, cid, tok ) ;
643
				MAKE_tok_class(s, cid, tok);
619
		    COPY_type ( tok_class_alt ( tok ), t ) ;
644
				COPY_type(tok_class_alt(tok), t);
-
 
645
			}
-
 
646
			break;
-
 
647
		}
-
 
648
		case tok_templ_tag: {
-
 
649
			/* Template tokens */
-
 
650
			if (force) {
-
 
651
				int d;
-
 
652
				LIST(IDENTIFIER) pids;
-
 
653
				LIST(IDENTIFIER) rids;
-
 
654
				LIST(IDENTIFIER) qids = NULL_list(IDENTIFIER);
-
 
655
				DECL_SPEC ds =
-
 
656
				    DEREF_dspec(tok_templ_usage(tok));
-
 
657
				NAMESPACE ns =
-
 
658
				    DEREF_nspace(tok_templ_pars(tok));
-
 
659
				pids = DEREF_list(tok_templ_pids(tok));
-
 
660
				rids = pids;
-
 
661
				d = save_token_args(rids, NULL_list(TOKEN));
-
 
662
				while (!IS_NULL_list(pids)) {
-
 
663
					/* Copy template parameters */
-
 
664
					TOKEN arg;
-
 
665
					IDENTIFIER qid2;
-
 
666
					IDENTIFIER pid =
-
 
667
					    DEREF_id(HEAD_list(pids));
-
 
668
					IDENTIFIER pid2 =
-
 
669
					    DEREF_id(id_token_alt(pid));
-
 
670
					IDENTIFIER qid = copy_id(pid, 2);
-
 
671
					DECL_SPEC qds =
-
 
672
					    DEREF_dspec(id_storage(qid));
-
 
673
					qds |= dspec_pure;
-
 
674
					COPY_dspec(id_storage(qid), qds);
-
 
675
					arg = apply_token(qid,
-
 
676
							  NULL_list(TOKEN));
-
 
677
					assign_token(pid, arg);
-
 
678
					qid2 = copy_id(pid2, 2);
-
 
679
					COPY_id(id_token_alt(qid), qid2);
-
 
680
					CONS_id(qid, qids, qids);
-
 
681
					pids = TAIL_list(pids);
-
 
682
				}
-
 
683
				restore_token_args(rids, d);
-
 
684
				MAKE_tok_templ(ds, ns, tok);
-
 
685
				qids = REVERSE_list(qids);
-
 
686
				COPY_list(tok_templ_pids(tok), qids);
-
 
687
				set_proc_token(qids);
-
 
688
			}
-
 
689
			break;
620
		}
690
		}
621
		break ;
-
 
622
	    }
-
 
623
	    case tok_templ_tag : {
-
 
624
		/* Template tokens */
-
 
625
		if ( force ) {
-
 
626
		    int d ;
-
 
627
		    LIST ( IDENTIFIER ) pids ;
-
 
628
		    LIST ( IDENTIFIER ) rids ;
-
 
629
		    LIST ( IDENTIFIER ) qids = NULL_list ( IDENTIFIER ) ;
-
 
630
		    DECL_SPEC ds = DEREF_dspec ( tok_templ_usage ( tok ) ) ;
-
 
631
		    NAMESPACE ns = DEREF_nspace ( tok_templ_pars ( tok ) ) ;
-
 
632
		    pids = DEREF_list ( tok_templ_pids ( tok ) ) ;
-
 
633
		    rids = pids ;
-
 
634
		    d = save_token_args ( rids, NULL_list ( TOKEN ) ) ;
-
 
635
		    while ( !IS_NULL_list ( pids ) ) {
-
 
636
			/* Copy template parameters */
-
 
637
			TOKEN arg ;
-
 
638
			IDENTIFIER qid2 ;
-
 
639
			IDENTIFIER pid = DEREF_id ( HEAD_list ( pids ) ) ;
-
 
640
			IDENTIFIER pid2 = DEREF_id ( id_token_alt ( pid ) ) ;
-
 
641
			IDENTIFIER qid = copy_id ( pid, 2 ) ;
-
 
642
			DECL_SPEC qds = DEREF_dspec ( id_storage ( qid ) ) ;
-
 
643
			qds |= dspec_pure ;
-
 
644
			COPY_dspec ( id_storage ( qid ), qds ) ;
-
 
645
			arg = apply_token ( qid, NULL_list ( TOKEN ) ) ;
-
 
646
			assign_token ( pid, arg ) ;
-
 
647
			qid2 = copy_id ( pid2, 2 ) ;
-
 
648
			COPY_id ( id_token_alt ( qid ), qid2 ) ;
-
 
649
			CONS_id ( qid, qids, qids ) ;
-
 
650
			pids = TAIL_list ( pids ) ;
-
 
651
		    }
-
 
652
		    restore_token_args ( rids, d ) ;
-
 
653
		    MAKE_tok_templ ( ds, ns, tok ) ;
-
 
654
		    qids = REVERSE_list ( qids ) ;
-
 
655
		    COPY_list ( tok_templ_pids ( tok ), qids ) ;
-
 
656
		    set_proc_token ( qids ) ;
-
 
657
		}
691
		}
658
		break ;
-
 
659
	    }
-
 
660
	}
692
	}
661
    }
-
 
662
    return ( tok ) ;
693
	return (tok);
663
}
694
}
664
 
695
 
665
 
696
 
666
/*
697
/*
667
    EXPAND A LIST OF TOKEN ARGUMENTS
698
    EXPAND A LIST OF TOKEN ARGUMENTS
668
 
699
 
669
    This routine expands the list of token arguments p passing the parameter
700
    This routine expands the list of token arguments p passing the parameter
670
    rec to the individual expansion routines.  The null list is returned to
701
    rec to the individual expansion routines.  The null list is returned to
671
    indicate that the expansion has no effect.
702
    indicate that the expansion has no effect.
672
*/
703
*/
673
 
704
 
674
LIST ( TOKEN ) expand_args
705
LIST(TOKEN)
675
    PROTO_N ( ( p, rec, force ) )
-
 
676
    PROTO_T ( LIST ( TOKEN ) p X int rec X int force )
706
expand_args(LIST(TOKEN) p, int rec, int force)
677
{
707
{
678
    int changed = 0 ;
708
	int changed = 0;
679
    LIST ( TOKEN ) q = NULL_list ( TOKEN ) ;
709
	LIST(TOKEN) q = NULL_list(TOKEN);
680
    while ( !IS_NULL_list ( p ) ) {
710
	while (!IS_NULL_list(p)) {
681
	TOKEN a = DEREF_tok ( HEAD_list ( p ) ) ;
711
		TOKEN a = DEREF_tok(HEAD_list(p));
682
	TOKEN b = expand_sort ( a, rec, force ) ;
712
		TOKEN b = expand_sort(a, rec, force);
683
	if ( !EQ_tok ( a, b ) ) changed = 1 ;
713
		if (!EQ_tok(a, b)) {
-
 
714
			changed = 1;
-
 
715
		}
684
	CONS_tok ( b, q, q ) ;
716
		CONS_tok(b, q, q);
685
	p = TAIL_list ( p ) ;
717
		p = TAIL_list(p);
686
    }
718
	}
687
    if ( !changed ) {
719
	if (!changed) {
688
	/* No effect */
720
		/* No effect */
689
	DESTROY_list ( q, SIZE_tok ) ;
721
		DESTROY_list(q, SIZE_tok);
690
	return ( NULL_list ( TOKEN ) ) ;
722
		return (NULL_list(TOKEN));
691
    }
723
	}
692
    q = REVERSE_list ( q ) ;
724
	q = REVERSE_list(q);
693
    return ( q ) ;
725
	return (q);
694
}
726
}
695
 
727
 
696
 
728
 
697
/*
729
/*
698
    EXPAND A TEMPLATE SORT
730
    EXPAND A TEMPLATE SORT
699
 
731
 
700
    This routine copies the given template sort producing a new sort
732
    This routine copies the given template sort producing a new sort
701
    comprising only those parameters which are unbound.  If all the
733
    comprising only those parameters which are unbound.  If all the
702
    parameters are bound then the null sort is returned.
734
    parameters are bound then the null sort is returned.
703
*/
735
*/
704
 
736
 
705
TOKEN expand_templ_sort
737
TOKEN
706
    PROTO_N ( ( sort, rec ) )
-
 
707
    PROTO_T ( TOKEN sort X int rec )
738
expand_templ_sort(TOKEN sort, int rec)
708
{
739
{
709
    NAMESPACE ns ;
740
	NAMESPACE ns;
710
    int changed = 0 ;
741
	int changed = 0;
711
    int all_unbound = 1 ;
742
	int all_unbound = 1;
712
    LIST ( TOKEN ) dargs = NULL_list ( TOKEN ) ;
743
	LIST(TOKEN) dargs = NULL_list(TOKEN);
713
    DECL_SPEC ex = DEREF_dspec ( tok_templ_usage ( sort ) ) ;
744
	DECL_SPEC ex = DEREF_dspec(tok_templ_usage(sort));
714
    LIST ( IDENTIFIER ) p = DEREF_list ( tok_templ_pids ( sort ) ) ;
745
	LIST(IDENTIFIER) p = DEREF_list(tok_templ_pids(sort));
715
    LIST ( IDENTIFIER ) q = NULL_list ( IDENTIFIER ) ;
746
	LIST(IDENTIFIER) q = NULL_list(IDENTIFIER);
716
    LIST ( IDENTIFIER ) p0 = p ;
747
	LIST(IDENTIFIER) p0 = p;
717
    while ( !IS_NULL_list ( p ) ) {
748
	while (!IS_NULL_list(p)) {
718
	IDENTIFIER pid = DEREF_id ( HEAD_list ( p ) ) ;
749
		IDENTIFIER pid = DEREF_id(HEAD_list(p));
719
	if ( !IS_NULL_id ( pid ) && IS_id_token ( pid ) ) {
750
		if (!IS_NULL_id(pid) && IS_id_token(pid)) {
720
	    TOKEN tok = DEREF_tok ( id_token_sort ( pid ) ) ;
751
			TOKEN tok = DEREF_tok(id_token_sort(pid));
721
	    if ( is_bound_tok ( tok, 0 ) ) {
752
			if (is_bound_tok(tok, 0)) {
722
		/* Have bound parameter */
753
				/* Have bound parameter */
723
		all_unbound = 0 ;
754
				all_unbound = 0;
724
		changed = 1 ;
755
				changed = 1;
725
	    } else {
756
			} else {
726
		/* Add unbound parameter to list */
757
				/* Add unbound parameter to list */
727
		/* NOT YET IMPLEMENTED */
758
				/* NOT YET IMPLEMENTED */
728
		CONS_id ( pid, q, q ) ;
759
				CONS_id(pid, q, q);
729
	    }
760
			}
-
 
761
		}
-
 
762
		p = TAIL_list(p);
730
	}
763
	}
731
	p = TAIL_list ( p ) ;
-
 
732
    }
-
 
733
    if ( IS_NULL_list ( q ) ) {
764
	if (IS_NULL_list(q)) {
734
	/* All parameters are bound */
765
		/* All parameters are bound */
735
	return ( NULL_tok ) ;
766
		return (NULL_tok);
736
    }
767
	}
737
    if ( changed ) {
768
	if (changed) {
738
	/* Get unbound parameters into order */
769
		/* Get unbound parameters into order */
739
	q = REVERSE_list ( q ) ;
770
		q = REVERSE_list(q);
740
    } else {
771
	} else {
741
	/* Use existing list */
772
		/* Use existing list */
742
	DESTROY_list ( q, SIZE_id ) ;
773
		DESTROY_list(q, SIZE_id);
743
	q = p0 ;
774
		q = p0;
744
    }
775
	}
745
    if ( all_unbound ) {
776
	if (all_unbound) {
746
	/* Preserve instances and default arguments */
777
		/* Preserve instances and default arguments */
747
	LIST ( TOKEN ) d ;
778
		LIST(TOKEN) d;
748
	dargs = DEREF_list ( tok_templ_dargs ( sort ) ) ;
779
		dargs = DEREF_list(tok_templ_dargs(sort));
749
	d = expand_args ( dargs, rec, 0 ) ;
780
		d = expand_args(dargs, rec, 0);
750
	if ( !IS_NULL_list ( d ) ) dargs = d ;
781
		if (!IS_NULL_list(d)) {
-
 
782
			dargs = d;
751
    }
783
		}
-
 
784
	}
752
    ns = DEREF_nspace ( tok_templ_pars ( sort ) ) ;
785
	ns = DEREF_nspace(tok_templ_pars(sort));
753
    MAKE_tok_templ ( ex, ns, sort ) ;
786
	MAKE_tok_templ(ex, ns, sort);
754
    COPY_list ( tok_templ_pids ( sort ), q ) ;
787
	COPY_list(tok_templ_pids(sort), q);
755
    COPY_list ( tok_templ_dargs ( sort ), dargs ) ;
788
	COPY_list(tok_templ_dargs(sort), dargs);
756
    return ( sort ) ;
789
	return (sort);
757
}
790
}
758
 
791
 
759
 
792
 
760
/*
793
/*
761
    RESTORE A TEMPLATE SORT
794
    RESTORE A TEMPLATE SORT
762
 
795
 
763
    This routine is called at the end of the expansion of a template
796
    This routine is called at the end of the expansion of a template
764
    type to restore the sort produced by expand_templ_sort.
797
    type to restore the sort produced by expand_templ_sort.
765
*/
798
*/
766
 
799
 
767
void reset_templ_sort
800
void
768
    PROTO_N ( ( sort ) )
-
 
769
    PROTO_T ( TOKEN sort )
801
reset_templ_sort(TOKEN sort)
770
{
802
{
771
    UNUSED ( sort ) ;
803
	UNUSED(sort);
772
    return ;
804
	return;
773
}
805
}
774
 
806
 
775
 
807
 
776
/*
808
/*
777
    EXPAND AN EXPRESSION TOKEN
809
    EXPAND AN EXPRESSION TOKEN
778
 
810
 
779
    This routine expands any token definitions in the expression e.
811
    This routine expands any token definitions in the expression e.
780
    rec gives the level of expansion, 0 for just the top level, 1 for a
812
    rec gives the level of expansion, 0 for just the top level, 1 for a
781
    complete recursive expansion, and 2 for a recursive expansion of
813
    complete recursive expansion, and 2 for a recursive expansion of
782
    token parameters only.  Negative values just return e.
814
    token parameters only.  Negative values just return e.
783
*/
-
 
784
 
-
 
785
EXP expand_exp
-
 
786
    PROTO_N ( ( e, rec, stmt ) )
-
 
787
    PROTO_T ( EXP e X int rec X int stmt )
-
 
788
{
-
 
789
    unsigned etag ;
-
 
790
    if ( rec < 0 ) return ( e ) ;
-
 
791
    if ( IS_NULL_exp ( e ) ) return ( NULL_exp ) ;
-
 
792
    etag = TAG_exp ( e ) ;
-
 
793
    if ( etag == exp_token_tag ) {
-
 
794
	/* Tokenised values */
-
 
795
	TOKEN tok ;
-
 
796
	DECL_SPEC ds ;
-
 
797
	unsigned tag ;
-
 
798
	IDENTIFIER id = DEREF_id ( exp_token_tok ( e ) ) ;
-
 
799
	IDENTIFIER aid = DEREF_id ( id_alias ( id ) ) ;
-
 
800
	LIST ( TOKEN ) p = DEREF_list ( exp_token_args ( e ) ) ;
-
 
801
	if ( !EQ_id ( id, aid ) ) {
-
 
802
	    /* Replace token by its alias */
-
 
803
	    e = apply_exp_token ( aid, p, 1 ) ;
-
 
804
	    id = aid ;
-
 
805
	}
-
 
806
	ds = DEREF_dspec ( id_storage ( id ) ) ;
-
 
807
	tok = DEREF_tok ( id_token_sort ( id ) ) ;
-
 
808
	tag = TAG_tok ( tok ) ;
-
 
809
	if ( tag == tok_proc_tag ) {
-
 
810
	    tok = DEREF_tok ( tok_proc_res ( tok ) ) ;
-
 
811
	    tag = TAG_tok ( tok ) ;
-
 
812
	}
-
 
813
	if ( rec ) {
-
 
814
	    /* Expand token arguments */
-
 
815
	    p = expand_args ( p, rec, 1 ) ;
-
 
816
	    e = apply_exp_token ( id, p, rec ) ;
-
 
817
	}
-
 
818
	/* if ( rec == 2 && !( ds & dspec_auto ) ) break ; */
-
 
819
	if ( ds & dspec_temp ) {
-
 
820
	    /* Check for recursive token expansions */
-
 
821
	    report ( crt_loc, ERR_token_recursive ( id ) ) ;
-
 
822
	    return ( make_error_exp ( 0 ) ) ;
-
 
823
	}
-
 
824
	COPY_dspec ( id_storage ( id ), ( ds | dspec_temp ) ) ;
-
 
825
	if ( tag == tok_exp_tag ) {
-
 
826
	    EXP a = DEREF_exp ( tok_exp_value ( tok ) ) ;
-
 
827
	    if ( !IS_NULL_exp ( a ) ) {
-
 
828
		/* Expand token definition */
-
 
829
		e = expand_exp ( a, rec, 0 ) ;
-
 
830
		if ( ds & dspec_auto ) {
-
 
831
		    COPY_exp ( tok_exp_value ( tok ), e ) ;
-
 
832
		}
-
 
833
	    }
-
 
834
	} else if ( tag == tok_stmt_tag ) {
-
 
835
	    EXP a = DEREF_exp ( tok_stmt_value ( tok ) ) ;
-
 
836
	    if ( !IS_NULL_exp ( a ) ) {
-
 
837
		/* Expand token definition */
-
 
838
		EXP b = get_parent_stmt ( a ) ;
-
 
839
		e = expand_exp ( a, rec, 1 ) ;
-
 
840
		set_parent_stmt ( e, b ) ;
-
 
841
		if ( ds & dspec_auto ) {
-
 
842
		    COPY_exp ( tok_stmt_value ( tok ), e ) ;
-
 
843
		}
-
 
844
	    }
-
 
845
	}
-
 
846
	COPY_dspec ( id_storage ( id ), ds ) ;
-
 
847
 
-
 
848
    } else if ( etag == exp_int_lit_tag ) {
-
 
849
	/* Integer constants */
-
 
850
	ERROR err = NULL_err ;
-
 
851
	NAT n1 = DEREF_nat ( exp_int_lit_nat ( e ) ) ;
-
 
852
	NAT n2 = expand_nat ( n1, rec, 0, &err ) ;
-
 
853
	if ( rec || !EQ_nat ( n1, n2 ) ) {
-
 
854
	    TYPE t = DEREF_type ( exp_type ( e ) ) ;
-
 
855
	    unsigned tag = DEREF_unsigned ( exp_int_lit_etag ( e ) ) ;
-
 
856
	    MAKE_exp_int_lit ( t, n2, tag, e ) ;
-
 
857
	    if ( !IS_NULL_err ( err ) ) report ( crt_loc, err ) ;
-
 
858
	}
-
 
859
 
-
 
860
    } else {
-
 
861
	/* Other cases */
-
 
862
	if ( rec && !stmt ) e = copy_exp ( e, NULL_type, NULL_type ) ;
-
 
863
    }
-
 
864
    return ( e ) ;
-
 
865
}
-
 
866
 
-
 
867
 
-
 
868
/*
-
 
869
    EXPAND AN INTEGER CONSTANT TOKEN
-
 
870
 
-
 
871
    This routine expands any token definitions in the integer constant
-
 
872
    expression n.  rec is as above, ch is as in eval_exp.
-
 
873
*/
815
*/
874
 
816
 
875
NAT expand_nat
817
EXP
876
    PROTO_N ( ( n, rec, ch, err ) )
818
expand_exp(EXP e, int rec, int stmt)
877
    PROTO_T ( NAT n X int rec X int ch X ERROR *err )
-
 
878
{
819
{
-
 
820
	unsigned etag;
879
    if ( rec < 0 ) return ( n ) ;
821
	if (rec < 0) {
-
 
822
		return (e);
-
 
823
	}
880
    if ( IS_NULL_nat ( n ) ) return ( NULL_nat ) ;
824
	if (IS_NULL_exp(e)) {
-
 
825
		return (NULL_exp);
-
 
826
	}
881
    switch ( TAG_nat ( n ) ) {
827
	etag = TAG_exp(e);
882
	case nat_calc_tag : {
828
	if (etag == exp_token_tag) {
883
	    /* Calculated values */
829
		/* Tokenised values */
884
	    EXP e2 ;
830
		TOKEN tok;
-
 
831
		DECL_SPEC ds;
-
 
832
		unsigned tag;
-
 
833
		IDENTIFIER id = DEREF_id(exp_token_tok(e));
-
 
834
		IDENTIFIER aid = DEREF_id(id_alias(id));
885
	    EXP e1 = DEREF_exp ( nat_calc_value ( n ) ) ;
835
		LIST(TOKEN) p = DEREF_list(exp_token_args(e));
-
 
836
		if (!EQ_id(id, aid)) {
-
 
837
			/* Replace token by its alias */
-
 
838
			e = apply_exp_token(aid, p, 1);
-
 
839
			id = aid;
-
 
840
		}
-
 
841
		ds = DEREF_dspec(id_storage(id));
-
 
842
		tok = DEREF_tok(id_token_sort(id));
-
 
843
		tag = TAG_tok(tok);
-
 
844
		if (tag == tok_proc_tag) {
886
	    ulong tok = DEREF_ulong ( nat_calc_tok ( n ) ) ;
845
			tok = DEREF_tok(tok_proc_res(tok));
-
 
846
			tag = TAG_tok(tok);
-
 
847
		}
887
	    if ( rec ) {
848
		if (rec) {
-
 
849
			/* Expand token arguments */
888
		e2 = eval_exp ( e1, ch ) ;
850
			p = expand_args(p, rec, 1);
-
 
851
			e = apply_exp_token(id, p, rec);
-
 
852
		}
-
 
853
		/* if ( rec == 2 && !( ds & dspec_auto ) ) break ; */
889
	    } else {
854
		if (ds & dspec_temp) {
-
 
855
			/* Check for recursive token expansions */
-
 
856
			report(crt_loc, ERR_token_recursive(id));
-
 
857
			return (make_error_exp(0));
-
 
858
		}
-
 
859
		COPY_dspec(id_storage(id), (ds | dspec_temp));
-
 
860
		if (tag == tok_exp_tag) {
-
 
861
			EXP a = DEREF_exp(tok_exp_value(tok));
-
 
862
			if (!IS_NULL_exp(a)) {
-
 
863
				/* Expand token definition */
890
		e2 = expand_exp ( e1, 0, 0 ) ;
864
				e = expand_exp(a, rec, 0);
-
 
865
				if (ds & dspec_auto) {
-
 
866
					COPY_exp(tok_exp_value(tok), e);
891
	    }
867
				}
-
 
868
			}
-
 
869
		} else if (tag == tok_stmt_tag) {
-
 
870
			EXP a = DEREF_exp(tok_stmt_value(tok));
-
 
871
			if (!IS_NULL_exp(a)) {
-
 
872
				/* Expand token definition */
-
 
873
				EXP b = get_parent_stmt(a);
-
 
874
				e = expand_exp(a, rec, 1);
-
 
875
				set_parent_stmt(e, b);
-
 
876
				if (ds & dspec_auto) {
-
 
877
					COPY_exp(tok_stmt_value(tok), e);
-
 
878
				}
-
 
879
			}
-
 
880
		}
-
 
881
		COPY_dspec(id_storage(id), ds);
-
 
882
 
-
 
883
	} else if (etag == exp_int_lit_tag) {
-
 
884
		/* Integer constants */
-
 
885
		ERROR err = NULL_err;
-
 
886
		NAT n1 = DEREF_nat(exp_int_lit_nat(e));
892
	    e2 = convert_reference ( e2, REF_NORMAL ) ;
887
		NAT n2 = expand_nat(n1, rec, 0, &err);
893
	    e2 = convert_lvalue ( e2 ) ;
888
		if (rec || !EQ_nat(n1, n2)) {
-
 
889
			TYPE t = DEREF_type(exp_type(e));
894
	    if ( !EQ_exp ( e1, e2 ) && !eq_exp_exact ( e1, e2 ) ) {
890
			unsigned tag = DEREF_unsigned(exp_int_lit_etag(e));
895
		n = make_nat_exp ( e2, err ) ;
891
			MAKE_exp_int_lit(t, n2, tag, e);
896
		if ( IS_nat_calc ( n ) ) {
892
			if (!IS_NULL_err(err)) {
-
 
893
				report(crt_loc, err);
-
 
894
			}
-
 
895
		}
-
 
896
	} else {
-
 
897
		/* Other cases */
-
 
898
		if (rec && !stmt) {
897
		    COPY_ulong ( nat_calc_tok ( n ), tok ) ;
899
			e = copy_exp(e, NULL_type, NULL_type);
898
		}
900
		}
899
	    }
-
 
900
	    break ;
-
 
901
	}
901
	}
-
 
902
	return (e);
-
 
903
}
-
 
904
 
-
 
905
 
-
 
906
/*
-
 
907
    EXPAND AN INTEGER CONSTANT TOKEN
-
 
908
 
-
 
909
    This routine expands any token definitions in the integer constant
-
 
910
    expression n.  rec is as above, ch is as in eval_exp.
-
 
911
*/
-
 
912
 
-
 
913
NAT
-
 
914
expand_nat(NAT n, int rec, int ch, ERROR *err)
-
 
915
{
-
 
916
	if (rec < 0) {
-
 
917
		return (n);
-
 
918
	}
-
 
919
	if (IS_NULL_nat(n)) {
-
 
920
		return (NULL_nat);
-
 
921
	}
-
 
922
	switch (TAG_nat(n)) {
-
 
923
	case nat_calc_tag: {
-
 
924
		/* Calculated values */
-
 
925
		EXP e2;
-
 
926
		EXP e1 = DEREF_exp(nat_calc_value(n));
-
 
927
		ulong tok = DEREF_ulong(nat_calc_tok(n));
-
 
928
		if (rec) {
-
 
929
			e2 = eval_exp(e1, ch);
-
 
930
		} else {
-
 
931
			e2 = expand_exp(e1, 0, 0);
-
 
932
		}
-
 
933
		e2 = convert_reference(e2, REF_NORMAL);
-
 
934
		e2 = convert_lvalue(e2);
-
 
935
		if (!EQ_exp(e1, e2) && !eq_exp_exact(e1, e2)) {
-
 
936
			n = make_nat_exp(e2, err);
-
 
937
			if (IS_nat_calc(n)) {
-
 
938
				COPY_ulong(nat_calc_tok(n), tok);
-
 
939
			}
-
 
940
		}
-
 
941
		break;
-
 
942
	}
902
	case nat_token_tag : {
943
	case nat_token_tag: {
903
	    /* Tokenised values */
944
		/* Tokenised values */
904
	    TOKEN tok ;
945
		TOKEN tok;
905
	    DECL_SPEC ds ;
946
		DECL_SPEC ds;
906
	    unsigned tag ;
947
		unsigned tag;
907
	    IDENTIFIER id = DEREF_id ( nat_token_tok ( n ) ) ;
948
		IDENTIFIER id = DEREF_id(nat_token_tok(n));
908
	    IDENTIFIER aid = DEREF_id ( id_alias ( id ) ) ;
949
		IDENTIFIER aid = DEREF_id(id_alias(id));
909
	    LIST ( TOKEN ) p = DEREF_list ( nat_token_args ( n ) ) ;
950
		LIST(TOKEN)p = DEREF_list(nat_token_args(n));
910
	    if ( !EQ_id ( id, aid ) ) {
951
		if (!EQ_id(id, aid)) {
911
		/* Replace token by its alias */
952
			/* Replace token by its alias */
912
		n = apply_nat_token ( aid, p ) ;
953
			n = apply_nat_token(aid, p);
913
		id = aid ;
954
			id = aid;
914
	    }
955
		}
915
	    ds = DEREF_dspec ( id_storage ( id ) ) ;
956
		ds = DEREF_dspec(id_storage(id));
916
	    tok = DEREF_tok ( id_token_sort ( id ) ) ;
957
		tok = DEREF_tok(id_token_sort(id));
917
	    tag = TAG_tok ( tok ) ;
958
		tag = TAG_tok(tok);
918
	    if ( tag == tok_proc_tag ) {
959
		if (tag == tok_proc_tag) {
919
		if ( rec ) {
960
			if (rec) {
920
		    /* Expand token arguments */
961
				/* Expand token arguments */
921
		    p = expand_args ( p, rec, 0 ) ;
962
				p = expand_args(p, rec, 0);
922
		    if ( !IS_NULL_list ( p ) ) {
963
				if (!IS_NULL_list(p)) {
923
			n = apply_nat_token ( id, p ) ;
964
					n = apply_nat_token(id, p);
924
		    }
965
				}
925
		}
966
			}
926
		tok = DEREF_tok ( tok_proc_res ( tok ) ) ;
967
			tok = DEREF_tok(tok_proc_res(tok));
927
		tag = TAG_tok ( tok ) ;
968
			tag = TAG_tok(tok);
928
	    }
969
		}
929
	    /* if ( rec == 2 && !( ds & dspec_auto ) ) break ; */
970
		/* if ( rec == 2 && !( ds & dspec_auto ) ) break ; */
930
	    if ( ds & dspec_temp ) {
971
		if (ds & dspec_temp) {
931
		/* Check for recursive token expansions */
972
			/* Check for recursive token expansions */
932
		report ( crt_loc, ERR_token_recursive ( id ) ) ;
973
			report(crt_loc, ERR_token_recursive(id));
933
		return ( small_nat [1] ) ;
974
			return (small_nat[1]);
934
	    }
975
		}
935
	    COPY_dspec ( id_storage ( id ), ( ds | dspec_temp ) ) ;
976
		COPY_dspec(id_storage(id), (ds | dspec_temp));
936
	    if ( tag == tok_nat_tag || tag == tok_snat_tag ) {
977
		if (tag == tok_nat_tag || tag == tok_snat_tag) {
937
		NAT m = DEREF_nat ( tok_nat_etc_value ( tok ) ) ;
978
			NAT m = DEREF_nat(tok_nat_etc_value(tok));
938
		if ( !IS_NULL_nat ( m ) ) {
979
			if (!IS_NULL_nat(m)) {
939
		    /* Expand token definition */
980
				/* Expand token definition */
940
		    n = expand_nat ( m, rec, ch, err ) ;
981
				n = expand_nat(m, rec, ch, err);
941
		    if ( ds & dspec_auto ) {
982
				if (ds & dspec_auto) {
942
			COPY_nat ( tok_nat_etc_value ( tok ), n ) ;
983
					COPY_nat(tok_nat_etc_value(tok), n);
943
		    }
984
				}
944
		}
985
			}
945
	    }
986
		}
946
	    COPY_dspec ( id_storage ( id ), ds ) ;
987
		COPY_dspec(id_storage(id), ds);
947
	    break ;
988
		break;
948
	}
989
	}
949
    }
990
	}
950
    return ( n ) ;
991
	return (n);
951
}
992
}
952
 
993
 
953
 
994
 
954
/*
995
/*
955
    EXPAND A MEMBER TOKEN
996
    EXPAND A MEMBER TOKEN
956
 
997
 
957
    This routine expands any token definitions in the offset off.  rec
998
    This routine expands any token definitions in the offset off.  rec
958
    is as above.
999
    is as above.
959
*/
1000
*/
960
 
1001
 
961
OFFSET expand_offset
1002
OFFSET
962
    PROTO_N ( ( off, rec ) )
-
 
963
    PROTO_T ( OFFSET off X int rec )
1003
expand_offset(OFFSET off, int rec)
964
{
1004
{
-
 
1005
	if (rec > 0) {
965
    if ( rec > 0 ) off = copy_offset ( off, lex_plus ) ;
1006
		off = copy_offset(off, lex_plus);
-
 
1007
	}
966
    return ( off ) ;
1008
	return (off);
967
}
1009
}
968
 
1010
 
969
 
1011
 
970
/*
1012
/*
971
    EXPAND A TEMPLATE TYPE
1013
    EXPAND A TEMPLATE TYPE
972
 
1014
 
973
    This routine is a special case of expand_type which deals with
1015
    This routine is a special case of expand_type which deals with
974
    template types.
1016
    template types.
975
*/
1017
*/
976
 
1018
 
977
static TYPE expand_templ_type
1019
static TYPE
978
    PROTO_N ( ( t, rec ) )
-
 
979
    PROTO_T ( TYPE t X int rec )
1020
expand_templ_type(TYPE t, int rec)
980
{
1021
{
981
    CV_SPEC cv = DEREF_cv ( type_qual ( t ) ) ;
1022
	CV_SPEC cv = DEREF_cv(type_qual(t));
982
    TYPE s = DEREF_type ( type_templ_defn ( t ) ) ;
1023
	TYPE s = DEREF_type(type_templ_defn(t));
983
    TOKEN sort = DEREF_tok ( type_templ_sort ( t ) ) ;
1024
	TOKEN sort = DEREF_tok(type_templ_sort(t));
984
    sort = expand_templ_sort ( sort, rec ) ;
1025
	sort = expand_templ_sort(sort, rec);
985
    if ( IS_type_compound ( s ) ) {
1026
	if (IS_type_compound(s)) {
986
	/* Template classes */
1027
		/* Template classes */
987
	s = copy_class ( s, dspec_instance ) ;
1028
		s = copy_class(s, dspec_instance);
988
    } else {
1029
	} else {
989
	/* Other template types */
1030
		/* Other template types */
990
	s = expand_type ( s, rec ) ;
1031
		s = expand_type(s, rec);
991
    }
1032
	}
992
    if ( IS_NULL_tok ( sort ) ) {
1033
	if (IS_NULL_tok(sort)) {
993
	/* No unbound parameters */
1034
		/* No unbound parameters */
994
	t = qualify_type ( s, cv, 0 ) ;
1035
		t = qualify_type(s, cv, 0);
995
    } else {
1036
	} else {
996
	/* Unbound parameters - result is a specialisation */
1037
		/* Unbound parameters - result is a specialisation */
997
	MAKE_type_templ ( cv, sort, s, 1, t ) ;
1038
		MAKE_type_templ(cv, sort, s, 1, t);
998
    }
1039
	}
999
    reset_templ_sort ( sort ) ;
1040
	reset_templ_sort(sort);
1000
    return ( t ) ;
1041
	return (t);
1001
}
1042
}
1002
 
1043
 
1003
 
1044
 
1004
/*
1045
/*
1005
    EXPAND A LIST OF EXCEPTION TYPES
1046
    EXPAND A LIST OF EXCEPTION TYPES
1006
 
1047
 
1007
    This routine expands the list of exception types p, setting changed to
1048
    This routine expands the list of exception types p, setting changed to
1008
    true if any changes.
1049
    true if any changes.
1009
*/
1050
*/
1010
 
1051
 
1011
LIST ( TYPE ) expand_exceptions
1052
LIST(TYPE)
1012
    PROTO_N ( ( p, rec, changed ) )
-
 
1013
    PROTO_T ( LIST ( TYPE ) p X int rec X int *changed )
1053
expand_exceptions(LIST(TYPE) p, int rec, int *changed)
1014
{
1054
{
1015
    LIST ( TYPE ) q = NULL_list ( TYPE ) ;
1055
	LIST(TYPE) q = NULL_list(TYPE);
1016
    if ( EQ_list ( p, univ_type_set ) ) {
1056
	if (EQ_list(p, univ_type_set)) {
1017
	q = p ;
1057
		q = p;
1018
    } else if ( EQ_list ( p, empty_type_set ) ) {
1058
	} else if (EQ_list(p, empty_type_set)) {
1019
	q = p ;
1059
		q = p;
1020
    } else {
1060
	} else {
1021
	while ( !IS_NULL_list ( p ) ) {
1061
		while (!IS_NULL_list(p)) {
1022
	    TYPE s1 = DEREF_type ( HEAD_list ( p ) ) ;
1062
			TYPE s1 = DEREF_type(HEAD_list(p));
1023
	    TYPE s2 = expand_type ( s1, rec ) ;
1063
			TYPE s2 = expand_type(s1, rec);
1024
	    if ( !EQ_type ( s1, s2 ) ) {
1064
			if (!EQ_type(s1, s2)) {
1025
		s2 = check_except_type ( s2, 0 ) ;
1065
				s2 = check_except_type(s2, 0);
1026
		*changed = 1 ;
1066
				*changed = 1;
1027
	    }
1067
			}
1028
	    CONS_type ( s2, q, q ) ;
1068
			CONS_type(s2, q, q);
1029
	    p = TAIL_list ( p ) ;
1069
			p = TAIL_list(p);
1030
	}
1070
		}
1031
	q = REVERSE_list ( q ) ;
1071
		q = REVERSE_list(q);
1032
    }
1072
	}
1033
    return ( q ) ;
1073
	return (q);
1034
}
1074
}
1035
 
1075
 
1036
 
1076
 
1037
/*
1077
/*
1038
    EXPAND A FUNCTION TYPE
1078
    EXPAND A FUNCTION TYPE
1039
 
1079
 
1040
    This routine is a special case of expand_type which deals with
1080
    This routine is a special case of expand_type which deals with
1041
    function types.  rec will not be zero.
1081
    function types.  rec will not be zero.
1042
*/
1082
*/
1043
 
1083
 
1044
static TYPE expand_func_type
1084
static TYPE
1045
    PROTO_N ( ( t, rec ) )
-
 
1046
    PROTO_T ( TYPE t X int rec )
1085
expand_func_type(TYPE t, int rec)
1047
{
1086
{
1048
    int mf = 0 ;
1087
	int mf = 0;
1049
    int expanded = 0 ;
1088
	int expanded = 0;
1050
    TYPE r1 = DEREF_type ( type_func_ret ( t ) ) ;
1089
	TYPE r1 = DEREF_type(type_func_ret(t));
1051
    TYPE r2 ;
1090
	TYPE r2;
1052
    LIST ( TYPE ) p1 = DEREF_list ( type_func_ptypes ( t ) ) ;
1091
	LIST(TYPE) p1 = DEREF_list(type_func_ptypes(t));
1053
    LIST ( TYPE ) p2 ;
1092
	LIST(TYPE) p2;
1054
    LIST ( TYPE ) m1 = DEREF_list ( type_func_mtypes ( t ) ) ;
1093
	LIST(TYPE) m1 = DEREF_list(type_func_mtypes(t));
1055
    LIST ( TYPE ) m2 = NULL_list ( TYPE ) ;
1094
	LIST(TYPE) m2 = NULL_list(TYPE);
1056
    LIST ( TYPE ) e1 = DEREF_list ( type_func_except ( t ) ) ;
1095
	LIST(TYPE) e1 = DEREF_list(type_func_except(t));
1057
    LIST ( TYPE ) e2 ;
1096
	LIST(TYPE) e2;
1058
    if ( !EQ_list ( p1, m1 ) ) {
1097
	if (!EQ_list(p1, m1)) {
1059
	if ( !IS_NULL_list ( m1 ) && EQ_list ( p1, TAIL_list ( m1 ) ) ) {
1098
		if (!IS_NULL_list(m1) && EQ_list(p1, TAIL_list(m1))) {
1060
	    /* Normal member function type */
1099
			/* Normal member function type */
1061
	    mf = 1 ;
1100
			mf = 1;
1062
	} else {
1101
		} else {
1063
	    /* Swapped member function type */
1102
			/* Swapped member function type */
1064
	    mf = -1 ;
1103
			mf = -1;
1065
	    m1 = p1 ;
1104
			m1 = p1;
1066
	}
1105
		}
1067
    }
1106
	}
1068
 
1107
 
1069
    /* Copy return type */
1108
	/* Copy return type */
1070
    r2 = expand_type ( r1, rec ) ;
1109
	r2 = expand_type(r1, rec);
1071
    if ( !EQ_type ( r1, r2 ) ) expanded = 1 ;
1110
	if (!EQ_type(r1, r2)) {
-
 
1111
		expanded = 1;
-
 
1112
	}
1072
 
1113
 
1073
    /* Copy parameter types */
1114
	/* Copy parameter types */
1074
    while ( !IS_NULL_list ( m1 ) ) {
1115
	while (!IS_NULL_list(m1)) {
1075
	TYPE s1 = DEREF_type ( HEAD_list ( m1 ) ) ;
1116
		TYPE s1 = DEREF_type(HEAD_list(m1));
1076
	TYPE s2 = expand_type ( s1, rec ) ;
1117
		TYPE s2 = expand_type(s1, rec);
1077
	if ( !EQ_type ( s1, s2 ) ) expanded = 1 ;
1118
		if (!EQ_type(s1, s2)) {
-
 
1119
			expanded = 1;
-
 
1120
		}
1078
	CONS_type ( s2, m2, m2 ) ;
1121
		CONS_type(s2, m2, m2);
1079
	m1 = TAIL_list ( m1 ) ;
1122
		m1 = TAIL_list(m1);
1080
    }
1123
	}
1081
    m2 = REVERSE_list ( m2 ) ;
1124
	m2 = REVERSE_list(m2);
1082
 
1125
 
1083
    /* Copy exception types */
1126
	/* Copy exception types */
1084
    e2 = expand_exceptions ( e1, rec, &expanded ) ;
1127
	e2 = expand_exceptions(e1, rec, &expanded);
1085
 
1128
 
1086
    /* Check for default arguments */
1129
	/* Check for default arguments */
1087
    if ( !expanded ) {
1130
	if (!expanded) {
1088
	LIST ( IDENTIFIER ) pids = DEREF_list ( type_func_pids ( t ) ) ;
1131
		LIST(IDENTIFIER) pids = DEREF_list(type_func_pids(t));
1089
	while ( !IS_NULL_list ( pids ) ) {
1132
		while (!IS_NULL_list(pids)) {
1090
	    IDENTIFIER id = DEREF_id ( HEAD_list ( pids ) ) ;
1133
			IDENTIFIER id = DEREF_id(HEAD_list(pids));
1091
	    EXP e = DEREF_exp ( id_parameter_init ( id ) ) ;
1134
			EXP e = DEREF_exp(id_parameter_init(id));
1092
	    if ( !IS_NULL_exp ( e ) ) {
1135
			if (!IS_NULL_exp(e)) {
1093
		if ( depends_on_exp ( e, any_token_param, 0 ) ) {
1136
				if (depends_on_exp(e, any_token_param, 0)) {
1094
		    /* Needs expansion */
1137
					/* Needs expansion */
1095
		    expanded = 1 ;
1138
					expanded = 1;
1096
		    break ;
1139
					break;
-
 
1140
				}
-
 
1141
			}
-
 
1142
			pids = TAIL_list(pids);
-
 
1143
		}
-
 
1144
	}
-
 
1145
 
-
 
1146
	/* Expand remaining items */
-
 
1147
	if (expanded) {
-
 
1148
		CV_SPEC cv = DEREF_cv(type_qual(t));
-
 
1149
		CV_SPEC mq = DEREF_cv(type_func_mqual(t));
-
 
1150
		int ell = DEREF_int(type_func_ellipsis(t));
-
 
1151
		NAMESPACE pars = DEREF_nspace(type_func_pars(t));
-
 
1152
		LIST(IDENTIFIER) pids = DEREF_list(type_func_pids(t));
-
 
1153
		LIST(IDENTIFIER) qids = NULL_list(IDENTIFIER);
-
 
1154
 
-
 
1155
		/* Copy parameters */
-
 
1156
		while (!IS_NULL_list(pids)) {
-
 
1157
			TYPE s;
-
 
1158
			IDENTIFIER id = DEREF_id(HEAD_list(pids));
-
 
1159
			IDENTIFIER lid = chase_alias(id);
-
 
1160
			EXP e = DEREF_exp(id_parameter_init(id));
-
 
1161
			id = copy_id(id, 2);
-
 
1162
			COPY_id(id_alias(id), lid);
-
 
1163
			s = DEREF_type(id_parameter_type(id));
-
 
1164
			check_par_decl(s, id, CONTEXT_WEAK_PARAM);
-
 
1165
			if (!IS_NULL_exp(e)) {
-
 
1166
				/* Copy default argument */
-
 
1167
				EXP d;
-
 
1168
				e = expand_exp(e, rec, 0);
-
 
1169
				e = init_general(s, e, id, 0);
-
 
1170
				d = destroy_general(s, id);
-
 
1171
				COPY_exp(id_parameter_term(id), d);
-
 
1172
				COPY_exp(id_parameter_init(id), e);
-
 
1173
			}
-
 
1174
			CONS_id(id, qids, qids);
-
 
1175
			pids = TAIL_list(pids);
-
 
1176
		}
-
 
1177
		qids = REVERSE_list(qids);
-
 
1178
 
-
 
1179
		/* Form function type */
-
 
1180
		if (mf == 0) {
-
 
1181
			p2 = m2;
-
 
1182
		} else if (mf == 1) {
-
 
1183
			p2 = TAIL_list(m2);
-
 
1184
		} else {
-
 
1185
			p2 = m2;
-
 
1186
			m2 = TAIL_list(p2);
-
 
1187
		}
-
 
1188
		MAKE_type_func(cv, NULL_type, p2, ell, mq, m2, pars, qids, e2,
-
 
1189
			       t);
-
 
1190
		t = inject_pre_type(t, r2, 0);
-
 
1191
	} else {
-
 
1192
		/* Free unused type lists */
-
 
1193
		if (!EQ_list(m2, m1)) {
-
 
1194
			DESTROY_list(m2, SIZE_type);
-
 
1195
		}
-
 
1196
		if (!EQ_list(e2, e1)) {
-
 
1197
			DESTROY_list(e2, SIZE_type);
1097
		}
1198
		}
1098
	    }
-
 
1099
	    pids = TAIL_list ( pids ) ;
-
 
1100
	}
-
 
1101
    }
-
 
1102
 
-
 
1103
    /* Expand remaining items */
-
 
1104
    if ( expanded ) {
-
 
1105
	CV_SPEC cv = DEREF_cv ( type_qual ( t ) ) ;
-
 
1106
	CV_SPEC mq = DEREF_cv ( type_func_mqual ( t ) ) ;
-
 
1107
	int ell = DEREF_int ( type_func_ellipsis ( t ) ) ;
-
 
1108
	NAMESPACE pars = DEREF_nspace ( type_func_pars ( t ) ) ;
-
 
1109
	LIST ( IDENTIFIER ) pids = DEREF_list ( type_func_pids ( t ) ) ;
-
 
1110
	LIST ( IDENTIFIER ) qids = NULL_list ( IDENTIFIER ) ;
-
 
1111
 
-
 
1112
	/* Copy parameters */
-
 
1113
	while ( !IS_NULL_list ( pids ) ) {
-
 
1114
	    TYPE s ;
-
 
1115
	    IDENTIFIER id = DEREF_id ( HEAD_list ( pids ) ) ;
-
 
1116
	    IDENTIFIER lid = chase_alias ( id ) ;
-
 
1117
	    EXP e = DEREF_exp ( id_parameter_init ( id ) ) ;
-
 
1118
	    id = copy_id ( id, 2 ) ;
-
 
1119
	    COPY_id ( id_alias ( id ), lid ) ;
-
 
1120
	    s = DEREF_type ( id_parameter_type ( id ) ) ;
-
 
1121
	    check_par_decl ( s, id, CONTEXT_WEAK_PARAM ) ;
-
 
1122
	    if ( !IS_NULL_exp ( e ) ) {
-
 
1123
		/* Copy default argument */
-
 
1124
		EXP d ;
-
 
1125
		e = expand_exp ( e, rec, 0 ) ;
-
 
1126
		e = init_general ( s, e, id, 0 ) ;
-
 
1127
		d = destroy_general ( s, id ) ;
-
 
1128
		COPY_exp ( id_parameter_term ( id ), d ) ;
-
 
1129
		COPY_exp ( id_parameter_init ( id ), e ) ;
-
 
1130
	    }
-
 
1131
	    CONS_id ( id, qids, qids ) ;
-
 
1132
	    pids = TAIL_list ( pids ) ;
-
 
1133
	}
-
 
1134
	qids = REVERSE_list ( qids ) ;
-
 
1135
 
-
 
1136
	/* Form function type */
-
 
1137
	if ( mf == 0 ) {
-
 
1138
	    p2 = m2 ;
-
 
1139
	} else if ( mf == 1 ) {
-
 
1140
	    p2 = TAIL_list ( m2 ) ;
-
 
1141
	} else {
-
 
1142
	    p2 = m2 ;
-
 
1143
	    m2 = TAIL_list ( p2 ) ;
-
 
1144
	}
1199
	}
1145
	MAKE_type_func ( cv, NULL_type, p2, ell, mq, m2, pars, qids, e2, t ) ;
-
 
1146
	t = inject_pre_type ( t, r2, 0 ) ;
-
 
1147
    } else {
-
 
1148
	/* Free unused type lists */
-
 
1149
	if ( !EQ_list ( m2, m1 ) ) DESTROY_list ( m2, SIZE_type ) ;
-
 
1150
	if ( !EQ_list ( e2, e1 ) ) DESTROY_list ( e2, SIZE_type ) ;
-
 
1151
    }
-
 
1152
    return ( t ) ;
1200
	return (t);
1153
}
1201
}
1154
 
1202
 
1155
 
1203
 
1156
/*
1204
/*
1157
    RESCAN A CLASS NAME
1205
    RESCAN A CLASS NAME
1158
 
1206
 
1159
    This routine expands the class type ct by rescanning its name in the
1207
    This routine expands the class type ct by rescanning its name in the
1160
    current context.  It returns the null type if the result is not a
1208
    current context.  It returns the null type if the result is not a
1161
    type name.
1209
    type name.
1162
*/
1210
*/
1163
 
1211
 
1164
static TYPE rescan_class
1212
static TYPE
1165
    PROTO_N ( ( ct ) )
-
 
1166
    PROTO_T ( CLASS_TYPE ct )
1213
rescan_class(CLASS_TYPE ct)
1167
{
1214
{
1168
    IDENTIFIER cid = DEREF_id ( ctype_name ( ct ) ) ;
1215
	IDENTIFIER cid = DEREF_id(ctype_name(ct));
1169
    TYPE t = find_typename ( cid, NULL_list ( TOKEN ), btype_none, 1 ) ;
1216
	TYPE t = find_typename(cid, NULL_list(TOKEN), btype_none, 1);
1170
    return ( t ) ;
1217
	return (t);
1171
}
1218
}
1172
 
1219
 
1173
 
1220
 
1174
/*
1221
/*
1175
    RESCAN AN ENUMERATION NAME
1222
    RESCAN AN ENUMERATION NAME
1176
 
1223
 
1177
    This routine expands the enumeration type et by rescanning its name
1224
    This routine expands the enumeration type et by rescanning its name
1178
    in the current context.  It returns the null type if the result is
1225
    in the current context.  It returns the null type if the result is
1179
    not a type name.
1226
    not a type name.
1180
*/
1227
*/
1181
 
1228
 
1182
static TYPE rescan_enum
1229
static TYPE
1183
    PROTO_N ( ( et ) )
-
 
1184
    PROTO_T ( ENUM_TYPE et )
1230
rescan_enum(ENUM_TYPE et)
1185
{
1231
{
1186
    IDENTIFIER eid = DEREF_id ( etype_name ( et ) ) ;
1232
	IDENTIFIER eid = DEREF_id(etype_name(et));
1187
    TYPE t = find_typename ( eid, NULL_list ( TOKEN ), btype_none, 1 ) ;
1233
	TYPE t = find_typename(eid, NULL_list(TOKEN), btype_none, 1);
1188
    return ( t ) ;
1234
	return (t);
1189
}
1235
}
1190
 
1236
 
1191
 
1237
 
1192
/*
1238
/*
1193
    EXPAND A CLASS TYPE
1239
    EXPAND A CLASS TYPE
1194
 
1240
 
1195
    This routine expands any token definitions in the class type ct.
1241
    This routine expands any token definitions in the class type ct.
1196
    rec is as above.  The null class is returned if the result is not
1242
    rec is as above.  The null class is returned if the result is not
1197
    a class type with the actual type being assigned to pt.
1243
    a class type with the actual type being assigned to pt.
1198
*/
1244
*/
1199
 
1245
 
1200
CLASS_TYPE expand_ctype
1246
CLASS_TYPE
1201
    PROTO_N ( ( ct, rec, pt ) )
-
 
1202
    PROTO_T ( CLASS_TYPE ct X int rec X TYPE *pt )
1247
expand_ctype(CLASS_TYPE ct, int rec, TYPE *pt)
1203
{
1248
{
1204
    if ( rec >= 0 ) {
1249
	if (rec >= 0) {
1205
	TYPE s = NULL_type ;
1250
		TYPE s = NULL_type;
1206
	TYPE t = DEREF_type ( ctype_form ( ct ) ) ;
1251
		TYPE t = DEREF_type(ctype_form(ct));
1207
	if ( !IS_NULL_type ( t ) ) {
1252
		if (!IS_NULL_type(t)) {
1208
	    if ( IS_type_token ( t ) ) {
1253
			if (IS_type_token(t)) {
1209
		IDENTIFIER id = DEREF_id ( type_token_tok ( t ) ) ;
1254
				IDENTIFIER id = DEREF_id(type_token_tok(t));
1210
		LIST ( TOKEN ) p = DEREF_list ( type_token_args ( t ) ) ;
1255
				LIST(TOKEN) p = DEREF_list(type_token_args(t));
1211
		if ( IS_id_token ( id ) ) {
1256
				if (IS_id_token(id)) {
1212
		    /* Tokenised classes */
1257
					/* Tokenised classes */
1213
		    s = expand_type ( t, rec ) ;
1258
					s = expand_type(t, rec);
1214
		} else if ( rec ) {
1259
				} else if (rec) {
1215
		    /* Template classes */
1260
					/* Template classes */
1216
		    p = expand_args ( p, rec, 0 ) ;
1261
					p = expand_args(p, rec, 0);
1217
		    if ( !IS_NULL_list ( p ) ) {
1262
					if (!IS_NULL_list(p)) {
1218
			/* Template class instance */
1263
						/* Template class instance */
1219
			id = instance_type ( id, p, 0, 1 ) ;
1264
						id = instance_type(id, p, 0, 1);
1220
			s = DEREF_type ( id_class_name_defn ( id ) ) ;
1265
						s = DEREF_type(id_class_name_defn(id));
1221
			while ( IS_type_templ ( s ) ) {
1266
						while (IS_type_templ(s)) {
1222
			    s = DEREF_type ( type_templ_defn ( s ) ) ;
1267
							s = DEREF_type(type_templ_defn(s));
1223
			}
1268
						}
1224
		    }
1269
					}
1225
		}
1270
				}
1226
		if ( EQ_type ( s, t ) ) {
1271
				if (EQ_type(s, t)) {
1227
		    /* No expansion possible */
1272
					/* No expansion possible */
1228
		    return ( ct ) ;
1273
					return (ct);
1229
		}
1274
				}
1230
	    } else if ( IS_type_instance ( t ) ) {
1275
			} else if (IS_type_instance(t)) {
1231
		s = rescan_class ( ct ) ;
1276
				s = rescan_class(ct);
1232
		if ( EQ_type ( s, t ) ) {
1277
				if (EQ_type(s, t)) {
1233
		    /* No expansion possible */
1278
					/* No expansion possible */
1234
		    return ( ct ) ;
1279
					return (ct);
1235
		}
1280
				}
1236
	    } else {
1281
			} else {
1237
		/* Recursive template classes */
1282
				/* Recursive template classes */
1238
		s = expand_type ( t, rec ) ;
1283
				s = expand_type(t, rec);
1239
	    }
1284
			}
1240
	} else {
1285
		} else {
1241
	    CLASS_INFO ci = DEREF_cinfo ( ctype_info ( ct ) ) ;
1286
			CLASS_INFO ci = DEREF_cinfo(ctype_info(ct));
1242
	    if ( ci & cinfo_rescan ) s = rescan_class ( ct ) ;
1287
			if (ci & cinfo_rescan)s = rescan_class(ct);
1243
	}
1288
		}
1244
	if ( !IS_NULL_type ( s ) ) {
1289
		if (!IS_NULL_type(s)) {
1245
	    if ( IS_type_compound ( s ) ) {
1290
			if (IS_type_compound(s)) {
1246
		ct = DEREF_ctype ( type_compound_defn ( s ) ) ;
1291
				ct = DEREF_ctype(type_compound_defn(s));
1247
	    } else {
1292
			} else {
1248
		*pt = s ;
1293
				*pt = s;
1249
		if ( is_templ_type ( s ) ) {
1294
				if (is_templ_type(s)) {
-
 
1295
					IDENTIFIER id =
1250
		    IDENTIFIER id = DEREF_id ( type_token_tok ( s ) ) ;
1296
					    DEREF_id(type_token_tok(s));
1251
		    ct = find_class ( id ) ;
1297
					ct = find_class(id);
1252
		} else {
1298
				} else {
1253
		    ct = NULL_ctype ;
1299
					ct = NULL_ctype;
1254
		}
1300
				}
1255
	    }
1301
			}
1256
	}
1302
		}
1257
    }
1303
	}
1258
    return ( ct ) ;
1304
	return (ct);
1259
}
1305
}
1260
 
1306
 
1261
 
1307
 
1262
/*
1308
/*
1263
    BITFIELD EXPANSION FLAG
1309
    BITFIELD EXPANSION FLAG
Line 1265... Line 1311...
1265
    This flag may be set to true to allow for zero sized bitfields in
1311
    This flag may be set to true to allow for zero sized bitfields in
1266
    expand_type.  The only way this can occur is in the expansion
1312
    expand_type.  The only way this can occur is in the expansion
1267
    of an anonymous member type.
1313
    of an anonymous member type.
1268
*/
1314
*/
1269
 
1315
 
1270
int expand_anon_bitfield = 0 ;
1316
int expand_anon_bitfield = 0;
1271
 
1317
 
1272
 
1318
 
1273
/*
1319
/*
1274
    EXPAND A TYPE TOKEN
1320
    EXPAND A TYPE TOKEN
1275
 
1321
 
1276
    This routine expands any token definitions in the type t.  rec is
1322
    This routine expands any token definitions in the type t.  rec is
1277
    as above.
1323
    as above.
1278
*/
1324
*/
1279
 
1325
 
1280
TYPE expand_type
1326
TYPE
1281
    PROTO_N ( ( t, rec ) )
-
 
1282
    PROTO_T ( TYPE t X int rec )
1327
expand_type(TYPE t, int rec)
1283
{
1328
{
1284
    CV_SPEC cv ;
1329
	CV_SPEC cv;
1285
    int prom = 0 ;
1330
	int prom = 0;
1286
    IDENTIFIER id ;
1331
	IDENTIFIER id;
1287
    LIST ( TOKEN ) p ;
1332
	LIST(TOKEN) p;
1288
    if ( rec < 0 ) return ( t ) ;
-
 
1289
    if ( IS_NULL_type ( t ) ) return ( NULL_type ) ;
-
 
1290
    cv = DEREF_cv ( type_qual ( t ) ) ;
-
 
1291
    ASSERT ( ORDER_type == 18 ) ;
-
 
1292
    switch ( TAG_type ( t ) ) {
-
 
1293
 
-
 
1294
	case type_integer_tag : {
-
 
1295
	    /* Integral types */
-
 
1296
	    INT_TYPE it = DEREF_itype ( type_integer_rep ( t ) ) ;
-
 
1297
	    unsigned tag = TAG_itype ( it ) ;
-
 
1298
	    if ( tag == itype_arith_tag ) {
-
 
1299
		/* Expand arithmetic types */
-
 
1300
		INT_TYPE ir = DEREF_itype ( itype_arith_arg1 ( it ) ) ;
-
 
1301
		INT_TYPE is = DEREF_itype ( itype_arith_arg2 ( it ) ) ;
-
 
1302
		TYPE r1 = DEREF_type ( itype_prom ( ir ) ) ;
-
 
1303
		TYPE r2 = expand_type ( r1, rec ) ;
-
 
1304
		TYPE s1 = DEREF_type ( itype_prom ( is ) ) ;
-
 
1305
		TYPE s2 = expand_type ( s1, rec ) ;
-
 
1306
		if ( !EQ_type ( r1, r2 ) || !EQ_type ( s1, s2 ) ) {
-
 
1307
		    t = arith_type ( r2, s2, NULL_exp, NULL_exp ) ;
-
 
1308
		    if ( cv ) t = qualify_type ( t, cv, 0 ) ;
-
 
1309
		}
-
 
1310
	    } else {
-
 
1311
		/* Expand other integral types */
-
 
1312
		if ( tag == itype_promote_tag ) {
-
 
1313
		    it = DEREF_itype ( itype_promote_arg ( it ) ) ;
-
 
1314
		    tag = TAG_itype ( it ) ;
-
 
1315
		    prom = 1 ;
-
 
1316
		}
-
 
1317
		if ( tag == itype_token_tag ) {
-
 
1318
		    id = DEREF_id ( itype_token_tok ( it ) ) ;
-
 
1319
		    p = DEREF_list ( itype_token_args ( it ) ) ;
-
 
1320
		    goto expand_label ;
-
 
1321
		}
-
 
1322
		if ( tag == itype_basic_tag ) {
-
 
1323
		    /* Allow for special tokens */
-
 
1324
		    BUILTIN_TYPE n = DEREF_ntype ( itype_basic_no ( it ) ) ;
-
 
1325
		    id = get_special ( base_token [n].tok, 0 ) ;
-
 
1326
		    if ( !IS_NULL_id ( id ) ) {
-
 
1327
			p = NULL_list ( TOKEN ) ;
-
 
1328
			goto expand_label ;
-
 
1329
		    }
-
 
1330
		}
-
 
1331
	    }
-
 
1332
	    break ;
-
 
1333
	}
-
 
1334
 
-
 
1335
	case type_floating_tag : {
-
 
1336
	    /* Floating point types */
-
 
1337
	    FLOAT_TYPE ft = DEREF_ftype ( type_floating_rep ( t ) ) ;
-
 
1338
	    unsigned tag = TAG_ftype ( ft ) ;
-
 
1339
	    if ( tag == ftype_arith_tag ) {
-
 
1340
		/* Expand arithmetic types */
-
 
1341
		FLOAT_TYPE fr = DEREF_ftype ( ftype_arith_arg1 ( ft ) ) ;
-
 
1342
		FLOAT_TYPE fs = DEREF_ftype ( ftype_arith_arg2 ( ft ) ) ;
-
 
1343
		TYPE r1 = make_ftype ( fr, NULL_ftype ) ;
-
 
1344
		TYPE r2 = expand_type ( r1, rec ) ;
-
 
1345
		TYPE s1 = make_ftype ( fs, NULL_ftype ) ;
-
 
1346
		TYPE s2 = expand_type ( s1, rec ) ;
-
 
1347
		if ( !EQ_type ( r1, r2 ) || !EQ_type ( s1, s2 ) ) {
-
 
1348
		    t = arith_type ( r2, s2, NULL_exp, NULL_exp ) ;
-
 
1349
		    if ( cv ) t = qualify_type ( t, cv, 0 ) ;
-
 
1350
		}
-
 
1351
	    } else {
-
 
1352
		/* Expand other floating point types */
-
 
1353
		if ( tag == ftype_arg_promote_tag ) {
-
 
1354
		    ft = DEREF_ftype ( ftype_arg_promote_arg ( ft ) ) ;
-
 
1355
		    tag = TAG_ftype ( ft ) ;
-
 
1356
		    prom = 2 ;
-
 
1357
		}
-
 
1358
		if ( tag == ftype_token_tag ) {
-
 
1359
		    id = DEREF_id ( ftype_token_tok ( ft ) ) ;
-
 
1360
		    p = DEREF_list ( ftype_token_args ( ft ) ) ;
-
 
1361
		    goto expand_label ;
-
 
1362
		}
-
 
1363
	    }
-
 
1364
	    break ;
-
 
1365
	}
-
 
1366
 
-
 
1367
	case type_ptr_tag : {
-
 
1368
	    /* Pointer types */
-
 
1369
	    if ( rec ) {
-
 
1370
		TYPE s1 = DEREF_type ( type_ptr_sub ( t ) ) ;
-
 
1371
		TYPE s2 = expand_type ( s1, rec ) ;
-
 
1372
		if ( !EQ_type ( s1, s2 ) ) {
-
 
1373
		    if ( TAG_type ( s1 ) == TAG_type ( s2 ) ) {
-
 
1374
			/* Don't check in this case */
-
 
1375
			MAKE_type_ptr ( cv, s2, t ) ;
-
 
1376
		    } else {
-
 
1377
			MAKE_type_ptr ( cv, NULL_type, t ) ;
-
 
1378
			t = inject_pre_type ( t, s2, 0 ) ;
-
 
1379
		    }
-
 
1380
		}
-
 
1381
	    }
-
 
1382
	    break ;
-
 
1383
	}
-
 
1384
 
-
 
1385
	case type_ref_tag : {
-
 
1386
	    /* Reference types */
-
 
1387
	    if ( rec ) {
1333
	if (rec < 0) {
1388
		TYPE s1 = DEREF_type ( type_ref_sub ( t ) ) ;
-
 
1389
		TYPE s2 = expand_type ( s1, rec ) ;
-
 
1390
		if ( !EQ_type ( s1, s2 ) ) {
-
 
1391
		    MAKE_type_ref ( cv, NULL_type, t ) ;
-
 
1392
		    t = inject_pre_type ( t, s2, 0 ) ;
-
 
1393
		}
-
 
1394
	    }
-
 
1395
	    break ;
1334
		return (t);
1396
	}
-
 
1397
 
-
 
1398
	case type_ptr_mem_tag : {
-
 
1399
	    /* Pointer to member types */
-
 
1400
	    if ( rec ) {
-
 
1401
		TYPE r2 = NULL_type ;
-
 
1402
		CLASS_TYPE c1 = DEREF_ctype ( type_ptr_mem_of ( t ) ) ;
-
 
1403
		CLASS_TYPE c2 = expand_ctype ( c1, rec, &r2 ) ;
-
 
1404
		TYPE s1 = DEREF_type ( type_ptr_mem_sub ( t ) ) ;
-
 
1405
		TYPE s2 = expand_type ( s1, rec ) ;
-
 
1406
		if ( !EQ_ctype ( c1, c2 ) ) {
-
 
1407
		    if ( IS_NULL_ctype ( c2 ) ) {
-
 
1408
			/* Illegal class type expansion */
-
 
1409
			report ( crt_loc, ERR_dcl_mptr_class ( r2 ) ) ;
-
 
1410
			MAKE_type_ptr ( cv, NULL_type, t ) ;
-
 
1411
		    } else {
-
 
1412
			MAKE_type_ptr_mem ( cv, c2, NULL_type, t ) ;
-
 
1413
		    }
-
 
1414
		    t = inject_pre_type ( t, s2, 0 ) ;
-
 
1415
		} else if ( !EQ_type ( s1, s2 ) ) {
-
 
1416
		    MAKE_type_ptr_mem ( cv, c1, NULL_type, t ) ;
-
 
1417
		    t = inject_pre_type ( t, s2, 0 ) ;
-
 
1418
		}
-
 
1419
	    }
-
 
1420
	    break ;
-
 
1421
	}
-
 
1422
 
-
 
1423
	case type_func_tag : {
-
 
1424
	    /* Function types */
-
 
1425
	    if ( rec ) t = expand_func_type ( t, rec ) ;
-
 
1426
	    break ;
-
 
1427
	}
1335
	}
1428
 
-
 
1429
	case type_array_tag : {
-
 
1430
	    /* Array types */
-
 
1431
	    if ( rec ) {
-
 
1432
		ERROR err = NULL_err ;
-
 
1433
		TYPE s1 = DEREF_type ( type_array_sub ( t ) ) ;
-
 
1434
		TYPE s2 = expand_type ( s1, rec ) ;
-
 
1435
		NAT n1 = DEREF_nat ( type_array_size ( t ) ) ;
-
 
1436
		NAT n2 = expand_nat ( n1, rec, 0, &err ) ;
-
 
1437
		if ( !EQ_nat ( n1, n2 ) ) {
-
 
1438
		    if ( !IS_NULL_err ( err ) ) {
1336
	if (IS_NULL_type(t)) {
1439
			ERROR err2 = ERR_dcl_array_dim_const () ;
-
 
1440
			err = concat_error ( err, err2 ) ;
-
 
1441
			report ( crt_loc, err ) ;
1337
		return (NULL_type);
1442
		    }
-
 
1443
		    n2 = check_array_dim ( n2 ) ;
-
 
1444
		    MAKE_type_array ( cv, NULL_type, n2, t ) ;
-
 
1445
		    t = inject_pre_type ( t, s2, 0 ) ;
-
 
1446
		} else if ( !EQ_type ( s1, s2 ) ) {
-
 
1447
		    MAKE_type_array ( cv, NULL_type, n2, t ) ;
-
 
1448
		    t = inject_pre_type ( t, s2, 0 ) ;
-
 
1449
		}
-
 
1450
	    }
-
 
1451
	    break ;
-
 
1452
	}
1338
	}
1453
 
-
 
-
 
1339
	cv = DEREF_cv(type_qual(t));
-
 
1340
	ASSERT(ORDER_type == 18);
-
 
1341
	switch (TAG_type(t)) {
1454
	case type_bitfield_tag : {
1342
	case type_integer_tag: {
1455
	    /* Bitfield types */
1343
		/* Integral types */
-
 
1344
		INT_TYPE it = DEREF_itype(type_integer_rep(t));
-
 
1345
		unsigned tag = TAG_itype(it);
1456
	    if ( rec ) {
1346
		if (tag == itype_arith_tag) {
1457
		ERROR err = NULL_err ;
1347
			/* Expand arithmetic types */
1458
		INT_TYPE it = DEREF_itype ( type_bitfield_defn ( t ) ) ;
1348
			INT_TYPE ir = DEREF_itype(itype_arith_arg1(it));
1459
		TYPE s1 = DEREF_type ( itype_bitfield_sub ( it ) ) ;
1349
			INT_TYPE is = DEREF_itype(itype_arith_arg2(it));
1460
		NAT n1 = DEREF_nat ( itype_bitfield_size ( it ) ) ;
1350
			TYPE r1 = DEREF_type(itype_prom(ir));
1461
		TYPE s2 = expand_type ( s1, rec ) ;
1351
			TYPE r2 = expand_type(r1, rec);
-
 
1352
			TYPE s1 = DEREF_type(itype_prom(is));
1462
		NAT n2 = expand_nat ( n1, rec, 0, &err ) ;
1353
			TYPE s2 = expand_type(s1, rec);
1463
		if ( !EQ_type ( s1, s2 ) || !EQ_nat ( n1, n2 ) ) {
1354
			if (!EQ_type(r1, r2) || !EQ_type(s1, s2)) {
-
 
1355
				t = arith_type(r2, s2, NULL_exp, NULL_exp);
-
 
1356
				if (cv) {
1464
		    BASE_TYPE rep ;
1357
					t = qualify_type(t, cv, 0);
-
 
1358
				}
-
 
1359
			}
-
 
1360
		} else {
-
 
1361
			/* Expand other integral types */
1465
		    int anon = expand_anon_bitfield ;
1362
			if (tag == itype_promote_tag) {
1466
		    rep = DEREF_btype ( itype_bitfield_rep ( it ) ) ;
1363
				it = DEREF_itype(itype_promote_arg(it));
-
 
1364
				tag = TAG_itype(it);
-
 
1365
				prom = 1;
-
 
1366
			}
1467
		    if ( !IS_NULL_err ( err ) ) {
1367
			if (tag == itype_token_tag) {
1468
			ERROR err2 = ERR_class_bit_dim_const () ;
1368
				id = DEREF_id(itype_token_tok(it));
1469
			err = concat_error ( err, err2 ) ;
1369
				p = DEREF_list(itype_token_args(it));
1470
			report ( crt_loc, err ) ;
1370
				goto expand_label;
1471
		    }
1371
			}
-
 
1372
			if (tag == itype_basic_tag) {
-
 
1373
				/* Allow for special tokens */
-
 
1374
				BUILTIN_TYPE n =
1472
		    rep = get_bitfield_rep ( s2, rep ) ;
1375
				    DEREF_ntype(itype_basic_no(it));
1473
		    t = check_bitfield_type ( cv, s2, rep, n2, anon ) ;
1376
				id = get_special(base_token[n].tok, 0);
-
 
1377
				if (!IS_NULL_id(id)) {
-
 
1378
					p = NULL_list(TOKEN);
-
 
1379
					goto expand_label;
-
 
1380
				}
-
 
1381
			}
1474
		}
1382
		}
1475
	    }
-
 
1476
	    break ;
1383
		break;
1477
	}
1384
	}
1478
 
-
 
1479
	case type_compound_tag : {
1385
	case type_floating_tag: {
1480
	    /* Class types */
1386
		/* Floating point types */
1481
	    CLASS_TYPE ct = DEREF_ctype ( type_compound_defn ( t ) ) ;
1387
		FLOAT_TYPE ft = DEREF_ftype(type_floating_rep(t));
1482
	    TYPE s = DEREF_type ( ctype_form ( ct ) ) ;
-
 
1483
	    if ( !IS_NULL_type ( s ) ) {
1388
		unsigned tag = TAG_ftype(ft);
1484
		if ( IS_type_token ( s ) ) {
1389
		if (tag == ftype_arith_tag) {
1485
		    /* Tokenised and template classes */
1390
			/* Expand arithmetic types */
1486
		    id = DEREF_id ( type_token_tok ( s ) ) ;
1391
			FLOAT_TYPE fr = DEREF_ftype(ftype_arith_arg1(ft));
1487
		    p = DEREF_list ( type_token_args ( s ) ) ;
1392
			FLOAT_TYPE fs = DEREF_ftype(ftype_arith_arg2(ft));
1488
		    if ( IS_id_token ( id ) ) goto expand_label ;
1393
			TYPE r1 = make_ftype(fr, NULL_ftype);
1489
		    if ( rec ) {
-
 
1490
			p = expand_args ( p, rec, 0 ) ;
1394
			TYPE r2 = expand_type(r1, rec);
1491
			if ( !IS_NULL_list ( p ) ) {
-
 
1492
			    /* Template class instance */
1395
			TYPE s1 = make_ftype(fs, NULL_ftype);
1493
			    id = instance_type ( id, p, 0, 1 ) ;
1396
			TYPE s2 = expand_type(s1, rec);
1494
			    t = DEREF_type ( id_class_name_defn ( id ) ) ;
1397
			if (!EQ_type(r1, r2) || !EQ_type(s1, s2)) {
1495
			    while ( IS_type_templ ( t ) ) {
-
 
1496
				t = DEREF_type ( type_templ_defn ( t ) ) ;
1398
				t = arith_type(r2, s2, NULL_exp, NULL_exp);
1497
			    }
1399
				if (cv) {
1498
			    if ( cv ) t = qualify_type ( t, cv, 0 ) ;
1400
					t = qualify_type(t, cv, 0);
1499
			}
1401
				}
1500
		    }
-
 
1501
		} else if ( IS_type_instance ( s ) ) {
-
 
1502
		    s = rescan_class ( ct ) ;
-
 
1503
		    if ( !IS_NULL_type ( s ) ) {
-
 
1504
			t = s ;
-
 
1505
			if ( cv ) t = qualify_type ( t, cv, 0 ) ;
-
 
1506
		    }
1402
			}
1507
		} else {
1403
		} else {
1508
		    /* Recursive template classes */
1404
			/* Expand other floating point types */
1509
		    t = expand_type ( s, rec ) ;
1405
			if (tag == ftype_arg_promote_tag) {
1510
		    if ( cv ) t = qualify_type ( t, cv, 0 ) ;
-
 
1511
		}
-
 
1512
	    } else {
-
 
1513
		CLASS_INFO ci = DEREF_cinfo ( ctype_info ( ct ) ) ;
1406
				ft = DEREF_ftype(ftype_arg_promote_arg(ft));
1514
		if ( ci & cinfo_rescan ) {
-
 
1515
		    /* Force rescan */
-
 
1516
		    s = rescan_class ( ct ) ;
1407
				tag = TAG_ftype(ft);
1517
		    if ( !IS_NULL_type ( s ) ) {
-
 
1518
			t = s ;
1408
				prom = 2;
1519
			if ( cv ) t = qualify_type ( t, cv, 0 ) ;
-
 
1520
		    }
-
 
1521
		}
1409
			}
1522
	    }
-
 
1523
	    break ;
-
 
1524
	}
-
 
1525
 
-
 
1526
	case type_enumerate_tag : {
1410
			if (tag == ftype_token_tag) {
1527
	    /* Enumeration types */
-
 
1528
	    ENUM_TYPE et = DEREF_etype ( type_enumerate_defn ( t ) ) ;
1411
				id = DEREF_id(ftype_token_tok(ft));
1529
	    CLASS_INFO ei = DEREF_cinfo ( etype_info ( et ) ) ;
1412
				p = DEREF_list(ftype_token_args(ft));
1530
	    if ( ei & cinfo_rescan ) {
-
 
1531
		/* Force rescan */
1413
				goto expand_label;
1532
		TYPE s = rescan_enum ( et ) ;
-
 
1533
		if ( !IS_NULL_type ( s ) ) {
-
 
1534
		    t = s ;
-
 
1535
		    if ( cv ) t = qualify_type ( t, cv, 0 ) ;
-
 
1536
		}
1414
			}
1537
	    }
1415
		}
1538
	    break ;
1416
		break;
1539
	}
1417
	}
1540
 
-
 
1541
	case type_token_tag : {
1418
	case type_ptr_tag:
1542
	    /* Tokenised types */
1419
		/* Pointer types */
1543
	    id = DEREF_id ( type_token_tok ( t ) ) ;
-
 
1544
	    p = DEREF_list ( type_token_args ( t ) ) ;
-
 
1545
	    expand_label : {
-
 
1546
		TOKEN tok ;
1420
		if (rec) {
1547
		unsigned tag ;
-
 
1548
		DECL_SPEC ds ;
-
 
1549
		IDENTIFIER aid ;
-
 
1550
		int changed = 0 ;
-
 
1551
		if ( !IS_id_token ( id ) ) break ;
1421
			TYPE s1 = DEREF_type(type_ptr_sub(t));
1552
		aid = DEREF_id ( id_alias ( id ) ) ;
1422
			TYPE s2 = expand_type(s1, rec);
1553
		if ( !EQ_id ( id, aid ) ) {
1423
			if (!EQ_type(s1, s2)) {
1554
		    /* Replace token by its alias */
-
 
1555
		    t = apply_type_token ( aid, p, NULL_id ) ;
-
 
1556
		    changed = 1 ;
-
 
1557
		    id = aid ;
-
 
1558
		}
-
 
1559
		ds = DEREF_dspec ( id_storage ( id ) ) ;
1424
				if (TAG_type(s1) == TAG_type(s2)) {
1560
		tok = DEREF_tok ( id_token_sort ( id ) ) ;
-
 
1561
		tag = TAG_tok ( tok ) ;
1425
					/* Don't check in this case */
1562
		if ( tag == tok_proc_tag ) {
1426
					MAKE_type_ptr(cv, s2, t);
1563
		    if ( rec ) {
1427
				} else {
1564
			/* Expand token arguments */
-
 
1565
			p = expand_args ( p, rec, 0 ) ;
1428
					MAKE_type_ptr(cv, NULL_type, t);
1566
			if ( !IS_NULL_list ( p ) ) {
-
 
1567
			    t = apply_type_token ( id, p, NULL_id ) ;
1429
					t = inject_pre_type(t, s2, 0);
1568
			    changed = 1 ;
1430
				}
1569
			}
1431
			}
1570
		    }
-
 
1571
		    tok = DEREF_tok ( tok_proc_res ( tok ) ) ;
-
 
1572
		    tag = TAG_tok ( tok ) ;
-
 
1573
		}
-
 
1574
		/* if ( rec == 2 && !( ds & dspec_auto ) ) break ; */
-
 
1575
		if ( ds & dspec_temp ) {
-
 
1576
		    /* Check for recursive token expansions */
-
 
1577
		    report ( crt_loc, ERR_token_recursive ( id ) ) ;
-
 
1578
		    return ( type_error ) ;
-
 
1579
		}
1432
		}
1580
		COPY_dspec ( id_storage ( id ), ( ds | dspec_temp ) ) ;
1433
		break;
1581
		if ( tag == tok_type_tag ) {
1434
	case type_ref_tag:
1582
		    /* Tokenised type */
1435
		/* Reference types */
-
 
1436
		if (rec) {
1583
		    TYPE s = DEREF_type ( tok_type_value ( tok ) ) ;
1437
			TYPE s1 = DEREF_type(type_ref_sub(t));
1584
		    if ( !IS_NULL_type ( s ) ) {
1438
			TYPE s2 = expand_type(s1, rec);
1585
			/* Expand token definition */
-
 
1586
			t = expand_type ( s, rec ) ;
1439
			if (!EQ_type(s1, s2)) {
1587
			if ( ds & dspec_auto ) {
1440
				MAKE_type_ref(cv, NULL_type, t);
1588
			    COPY_type ( tok_type_value ( tok ), t ) ;
1441
				t = inject_pre_type(t, s2, 0);
1589
			}
1442
			}
1590
			changed = 1 ;
-
 
1591
		    } else {
-
 
1592
			BASE_TYPE bt ;
-
 
1593
			bt = DEREF_btype ( tok_type_kind ( tok ) ) ;
-
 
1594
			if ( bt & btype_typename ) {
-
 
1595
			    /* Allow for typename */
-
 
1596
			    s = find_typename ( id, p, bt, 0 ) ;
-
 
1597
			    if ( !IS_NULL_type ( s ) ) {
-
 
1598
				t = expand_type ( s, rec ) ;
-
 
1599
				changed = 1 ;
-
 
1600
			    }
-
 
1601
			}
-
 
1602
		    }
-
 
1603
		} else if ( tag == tok_class_tag ) {
-
 
1604
		    /* Template template parameter */
-
 
1605
		    aid = DEREF_id ( tok_class_value ( tok ) ) ;
-
 
1606
		    if ( !IS_NULL_id ( aid ) && rec ) {
-
 
1607
			p = expand_args ( p, rec, 1 ) ;
-
 
1608
			aid = apply_template ( aid, p, 0, 0 ) ;
-
 
1609
			if ( IS_id_class_name_etc ( aid ) ) {
-
 
1610
			    t = DEREF_type ( id_class_name_etc_defn ( aid ) ) ;
-
 
1611
			    changed = 1 ;
-
 
1612
			}
-
 
1613
		    }
-
 
1614
		}
1443
		}
-
 
1444
		break;
-
 
1445
	case type_ptr_mem_tag: {
-
 
1446
		/* Pointer to member types */
1615
		if ( changed ) {
1447
		if (rec) {
-
 
1448
			TYPE r2 = NULL_type;
-
 
1449
			CLASS_TYPE c1 = DEREF_ctype(type_ptr_mem_of(t));
-
 
1450
			CLASS_TYPE c2 = expand_ctype(c1, rec, &r2);
-
 
1451
			TYPE s1 = DEREF_type(type_ptr_mem_sub(t));
1616
		    /* Qualify modified type */
1452
			TYPE s2 = expand_type(s1, rec);
1617
		    if ( prom == 1 ) {
1453
			if (!EQ_ctype(c1, c2)) {
-
 
1454
				if (IS_NULL_ctype(c2)) {
-
 
1455
					/* Illegal class type expansion */
-
 
1456
					report(crt_loc, ERR_dcl_mptr_class(r2));
-
 
1457
					MAKE_type_ptr(cv, NULL_type, t);
-
 
1458
				} else {
-
 
1459
					MAKE_type_ptr_mem(cv, c2, NULL_type, t);
-
 
1460
				}
1618
			t = promote_type ( t ) ;
1461
				t = inject_pre_type(t, s2, 0);
1619
		    } else if ( prom == 2 ) {
1462
			} else if (!EQ_type(s1, s2)) {
-
 
1463
				MAKE_type_ptr_mem(cv, c1, NULL_type, t);
1620
			t = arg_promote_type ( t, KILL_err ) ;
1464
				t = inject_pre_type(t, s2, 0);
1621
		    }
1465
			}
-
 
1466
		}
-
 
1467
		break;
-
 
1468
	}
-
 
1469
	case type_func_tag:
-
 
1470
		/* Function types */
-
 
1471
		if (rec) {
-
 
1472
			t = expand_func_type(t, rec);
-
 
1473
		}
-
 
1474
		break;
-
 
1475
	case type_array_tag:
-
 
1476
		/* Array types */
1622
		    if ( cv ) {
1477
		if (rec) {
-
 
1478
			ERROR err = NULL_err;
1623
			CV_SPEC qual = DEREF_cv ( type_qual ( t ) ) ;
1479
			TYPE s1 = DEREF_type(type_array_sub(t));
-
 
1480
			TYPE s2 = expand_type(s1, rec);
-
 
1481
			NAT n1 = DEREF_nat(type_array_size(t));
-
 
1482
			NAT n2 = expand_nat(n1, rec, 0, &err);
-
 
1483
			if (!EQ_nat(n1, n2)) {
-
 
1484
				if (!IS_NULL_err(err)) {
-
 
1485
					ERROR err2 = ERR_dcl_array_dim_const();
-
 
1486
					err = concat_error(err, err2);
-
 
1487
					report(crt_loc, err);
-
 
1488
				}
-
 
1489
				n2 = check_array_dim(n2);
-
 
1490
				MAKE_type_array(cv, NULL_type, n2, t);
-
 
1491
				t = inject_pre_type(t, s2, 0);
-
 
1492
			} else if (!EQ_type(s1, s2)) {
-
 
1493
				MAKE_type_array(cv, NULL_type, n2, t);
1624
			t = qualify_type ( t, ( qual | cv ), 0 ) ;
1494
				t = inject_pre_type(t, s2, 0);
1625
		    }
1495
			}
1626
		}
1496
		}
-
 
1497
		break;
-
 
1498
	case type_bitfield_tag:
-
 
1499
		/* Bitfield types */
-
 
1500
		if (rec) {
-
 
1501
			ERROR err = NULL_err;
-
 
1502
			INT_TYPE it = DEREF_itype(type_bitfield_defn(t));
-
 
1503
			TYPE s1 = DEREF_type(itype_bitfield_sub(it));
-
 
1504
			NAT n1 = DEREF_nat(itype_bitfield_size(it));
1627
		COPY_dspec ( id_storage ( id ), ds ) ;
1505
			TYPE s2 = expand_type(s1, rec);
-
 
1506
			NAT n2 = expand_nat(n1, rec, 0, &err);
-
 
1507
			if (!EQ_type(s1, s2) || !EQ_nat(n1, n2)) {
-
 
1508
				BASE_TYPE rep;
-
 
1509
				int anon = expand_anon_bitfield;
-
 
1510
				rep = DEREF_btype(itype_bitfield_rep(it));
-
 
1511
				if (!IS_NULL_err(err)) {
-
 
1512
					ERROR err2 = ERR_class_bit_dim_const();
-
 
1513
					err = concat_error(err, err2);
-
 
1514
					report(crt_loc, err);
1628
	    }
1515
				}
-
 
1516
				rep = get_bitfield_rep(s2, rep);
-
 
1517
				t = check_bitfield_type(cv, s2, rep, n2, anon);
-
 
1518
			}
-
 
1519
		}
1629
	    break ;
1520
		break;
-
 
1521
	case type_compound_tag: {
-
 
1522
		/* Class types */
-
 
1523
		CLASS_TYPE ct = DEREF_ctype(type_compound_defn(t));
-
 
1524
		TYPE s = DEREF_type(ctype_form(ct));
-
 
1525
		if (!IS_NULL_type(s)) {
-
 
1526
			if (IS_type_token(s)) {
-
 
1527
				/* Tokenised and template classes */
-
 
1528
				id = DEREF_id(type_token_tok(s));
-
 
1529
				p = DEREF_list(type_token_args(s));
-
 
1530
				if (IS_id_token(id)) {
-
 
1531
					goto expand_label;
-
 
1532
				}
-
 
1533
				if (rec) {
-
 
1534
					p = expand_args(p, rec, 0);
-
 
1535
					if (!IS_NULL_list(p)) {
-
 
1536
						/* Template class instance */
-
 
1537
						id = instance_type(id, p, 0, 1);
-
 
1538
						t = DEREF_type(id_class_name_defn(id));
-
 
1539
						while (IS_type_templ(t)) {
-
 
1540
							t = DEREF_type(type_templ_defn(t));
-
 
1541
						}
-
 
1542
						if (cv) {
-
 
1543
							t = qualify_type(t, cv, 0);
-
 
1544
						}
-
 
1545
					}
-
 
1546
				}
-
 
1547
			} else if (IS_type_instance(s)) {
-
 
1548
				s = rescan_class(ct);
-
 
1549
				if (!IS_NULL_type(s)) {
-
 
1550
					t = s;
-
 
1551
					if (cv) {
-
 
1552
						t = qualify_type(t, cv, 0);
-
 
1553
					}
-
 
1554
				}
-
 
1555
			} else {
-
 
1556
				/* Recursive template classes */
-
 
1557
				t = expand_type(s, rec);
-
 
1558
				if (cv) {
-
 
1559
					t = qualify_type(t, cv, 0);
-
 
1560
				}
-
 
1561
			}
-
 
1562
		} else {
-
 
1563
			CLASS_INFO ci = DEREF_cinfo(ctype_info(ct));
-
 
1564
			if (ci & cinfo_rescan) {
-
 
1565
				/* Force rescan */
-
 
1566
				s = rescan_class(ct);
-
 
1567
				if (!IS_NULL_type(s)) {
-
 
1568
					t = s;
-
 
1569
					if (cv) {
-
 
1570
						t = qualify_type(t, cv, 0);
-
 
1571
					}
-
 
1572
				}
-
 
1573
			}
1630
	}
1574
		}
-
 
1575
		break;
1631
 
1576
	}
1632
	case type_templ_tag : {
1577
	case type_enumerate_tag: {
1633
	    /* Template types */
1578
		/* Enumeration types */
-
 
1579
		ENUM_TYPE et = DEREF_etype(type_enumerate_defn(t));
-
 
1580
		CLASS_INFO ei = DEREF_cinfo(etype_info(et));
-
 
1581
		if (ei & cinfo_rescan) {
-
 
1582
			/* Force rescan */
-
 
1583
			TYPE s = rescan_enum(et);
-
 
1584
			if (!IS_NULL_type(s)) {
-
 
1585
				t = s;
-
 
1586
				if (cv) {
1634
	    t = expand_templ_type ( t, rec ) ;
1587
					t = qualify_type(t, cv, 0);
-
 
1588
				}
-
 
1589
			}
-
 
1590
		}
1635
	    break ;
1591
		break;
1636
	}
1592
	}
-
 
1593
	case type_token_tag:
-
 
1594
		/* Tokenised types */
-
 
1595
		id = DEREF_id(type_token_tok(t));
-
 
1596
		p = DEREF_list(type_token_args(t));
-
 
1597
expand_label: {
-
 
1598
		      TOKEN tok;
-
 
1599
		      unsigned tag;
-
 
1600
		      DECL_SPEC ds;
-
 
1601
		      IDENTIFIER aid;
-
 
1602
		      int changed = 0;
-
 
1603
		      if (!IS_id_token(id)) {
-
 
1604
			      break;
-
 
1605
		      }
-
 
1606
		      aid = DEREF_id(id_alias(id));
-
 
1607
		      if (!EQ_id(id, aid)) {
-
 
1608
			      /* Replace token by its alias */
-
 
1609
			      t = apply_type_token(aid, p, NULL_id);
-
 
1610
			      changed = 1;
-
 
1611
			      id = aid;
-
 
1612
		      }
-
 
1613
		      ds = DEREF_dspec(id_storage(id));
-
 
1614
		      tok = DEREF_tok(id_token_sort(id));
-
 
1615
		      tag = TAG_tok(tok);
-
 
1616
		      if (tag == tok_proc_tag) {
-
 
1617
			      if (rec) {
-
 
1618
				      /* Expand token arguments */
-
 
1619
				      p = expand_args(p, rec, 0);
-
 
1620
				      if (!IS_NULL_list(p)) {
-
 
1621
					      t = apply_type_token(id, p,
-
 
1622
								   NULL_id);
-
 
1623
					      changed = 1;
-
 
1624
				      }
-
 
1625
			      }
-
 
1626
			      tok = DEREF_tok(tok_proc_res(tok));
-
 
1627
			      tag = TAG_tok(tok);
-
 
1628
		      }
-
 
1629
		      /* if ( rec == 2 && !( ds & dspec_auto ) ) break ; */
-
 
1630
		      if (ds & dspec_temp) {
-
 
1631
			      /* Check for recursive token expansions */
-
 
1632
			      report(crt_loc, ERR_token_recursive(id));
-
 
1633
			      return (type_error);
-
 
1634
		      }
-
 
1635
		      COPY_dspec(id_storage(id), (ds | dspec_temp));
-
 
1636
		      if (tag == tok_type_tag) {
-
 
1637
			      /* Tokenised type */
-
 
1638
			      TYPE s = DEREF_type(tok_type_value(tok));
-
 
1639
			      if (!IS_NULL_type(s)) {
-
 
1640
				      /* Expand token definition */
-
 
1641
				      t = expand_type(s, rec);
-
 
1642
				      if (ds & dspec_auto) {
-
 
1643
					      COPY_type(tok_type_value(tok), t);
-
 
1644
				      }
-
 
1645
				      changed = 1;
-
 
1646
			      } else {
-
 
1647
				      BASE_TYPE bt;
-
 
1648
				      bt = DEREF_btype(tok_type_kind(tok));
-
 
1649
				      if (bt & btype_typename) {
-
 
1650
					      /* Allow for typename */
-
 
1651
					      s = find_typename(id, p, bt, 0);
-
 
1652
					      if (!IS_NULL_type(s)) {
-
 
1653
						      t = expand_type(s, rec);
-
 
1654
						      changed = 1;
-
 
1655
					      }
-
 
1656
				      }
-
 
1657
			      }
-
 
1658
		      } else if (tag == tok_class_tag) {
-
 
1659
			      /* Template template parameter */
-
 
1660
			      aid = DEREF_id(tok_class_value(tok));
-
 
1661
			      if (!IS_NULL_id(aid) && rec) {
-
 
1662
				      p = expand_args(p, rec, 1);
-
 
1663
				      aid = apply_template(aid, p, 0, 0);
-
 
1664
				      if (IS_id_class_name_etc(aid)) {
-
 
1665
					      t = DEREF_type(id_class_name_etc_defn(aid));
-
 
1666
					      changed = 1;
-
 
1667
				      }
-
 
1668
			      }
-
 
1669
		      }
-
 
1670
		      if (changed) {
-
 
1671
			      /* Qualify modified type */
-
 
1672
			      if (prom == 1) {
-
 
1673
				      t = promote_type(t);
-
 
1674
			      } else if (prom == 2) {
-
 
1675
				      t = arg_promote_type(t, KILL_err);
-
 
1676
			      }
-
 
1677
			      if (cv) {
-
 
1678
				      CV_SPEC qual = DEREF_cv(type_qual(t));
-
 
1679
				      t = qualify_type(t,(qual | cv), 0);
-
 
1680
			      }
-
 
1681
		      }
-
 
1682
		      COPY_dspec(id_storage(id), ds);
1637
    }
1683
	      }
-
 
1684
	      break;
-
 
1685
	case type_templ_tag:
-
 
1686
		/* Template types */
-
 
1687
		t = expand_templ_type(t, rec);
-
 
1688
		break;
-
 
1689
	}
1638
    return ( t ) ;
1690
	return (t);
1639
}
1691
}
1640
 
1692
 
1641
 
1693
 
1642
/*
1694
/*
1643
    APPLY AN EXPRESSION TOKEN
1695
    APPLY AN EXPRESSION TOKEN
1644
 
1696
 
1645
    This routine applies the expression, statement or integer constant
1697
    This routine applies the expression, statement or integer constant
1646
    token id to the arguments args.  If rec is true then the result
1698
    token id to the arguments args.  If rec is true then the result
1647
    type is expanded.
1699
    type is expanded.
1648
*/
1700
*/
1649
 
1701
 
1650
EXP apply_exp_token
1702
EXP
1651
    PROTO_N ( ( id, args, rec ) )
-
 
1652
    PROTO_T ( IDENTIFIER id X LIST ( TOKEN ) args X int rec )
1703
apply_exp_token(IDENTIFIER id, LIST(TOKEN) args, int rec)
1653
{
1704
{
1654
    EXP e ;
1705
	EXP e;
1655
    int is_proc = 0 ;
1706
	int is_proc = 0;
1656
    TOKEN tok = DEREF_tok ( id_token_sort ( id ) ) ;
1707
	TOKEN tok = DEREF_tok(id_token_sort(id));
1657
    unsigned tag = TAG_tok ( tok ) ;
1708
	unsigned tag = TAG_tok(tok);
1658
    if ( tag == tok_func_tag ) {
1709
	if (tag == tok_func_tag) {
1659
	tok = func_proc_token ( tok ) ;
1710
		tok = func_proc_token(tok);
1660
	tag = TAG_tok ( tok ) ;
1711
		tag = TAG_tok(tok);
1661
    }
1712
	}
1662
    if ( tag == tok_proc_tag ) {
1713
	if (tag == tok_proc_tag) {
1663
	is_proc = 1 ;
1714
		is_proc = 1;
1664
	tok = DEREF_tok ( tok_proc_res ( tok ) ) ;
1715
		tok = DEREF_tok(tok_proc_res(tok));
1665
	tag = TAG_tok ( tok ) ;
1716
		tag = TAG_tok(tok);
1666
    }
1717
	}
1667
    switch ( tag ) {
1718
	switch (tag) {
1668
	case tok_exp_tag : {
1719
	case tok_exp_tag: {
1669
	    /* Expression tokens */
1720
		/* Expression tokens */
1670
	    int pt = in_proc_token ;
1721
		int pt = in_proc_token;
1671
	    TYPE t = DEREF_type ( tok_exp_type ( tok ) ) ;
1722
		TYPE t = DEREF_type(tok_exp_type(tok));
1672
	    int c = DEREF_int ( tok_exp_constant ( tok ) ) ;
1723
		int c = DEREF_int(tok_exp_constant(tok));
1673
	    if ( rec > 0 ) {
1724
		if (rec > 0) {
1674
		t = expand_type ( t, rec ) ;
1725
			t = expand_type(t, rec);
1675
	    } else if ( pt ) {
1726
		} else if (pt) {
1676
		in_proc_token = 0 ;
1727
			in_proc_token = 0;
1677
		t = expand_type ( t, 2 ) ;
1728
			t = expand_type(t, 2);
1678
		in_proc_token = pt ;
1729
			in_proc_token = pt;
1679
	    }
1730
		}
1680
	    t = convert_qual_type ( t ) ;
1731
		t = convert_qual_type(t);
1681
	    MAKE_exp_token ( t, id, args, e ) ;
1732
		MAKE_exp_token(t, id, args, e);
1682
	    if ( c ) {
1733
		if (c) {
1683
		/* Check for integer constant tokens */
1734
			/* Check for integer constant tokens */
1684
		unsigned tt = TAG_type ( t ) ;
1735
			unsigned tt = TAG_type(t);
-
 
1736
			if (tt == type_integer_tag ||
1685
		if ( tt == type_integer_tag || tt == type_enumerate_tag ) {
1737
			    tt == type_enumerate_tag) {
1686
		    NAT n ;
1738
				NAT n;
1687
		    MAKE_nat_calc ( e, n ) ;
1739
				MAKE_nat_calc(e, n);
1688
		    MAKE_exp_int_lit ( t, n, exp_token_tag, e ) ;
1740
				MAKE_exp_int_lit(t, n, exp_token_tag, e);
1689
		}
1741
			}
1690
	    } else {
1742
		} else {
1691
		/* Allow for exceptions */
1743
			/* Allow for exceptions */
1692
		if ( is_proc ) {
1744
			if (is_proc) {
1693
		    IGNORE check_throw ( NULL_type, 0 ) ;
1745
				IGNORE check_throw(NULL_type, 0);
1694
		}
1746
			}
1695
	    }
1747
		}
1696
	    break ;
1748
		break;
1697
	}
1749
	}
1698
	case tok_stmt_tag : {
1750
	case tok_stmt_tag:
1699
	    /* Statement tokens */
1751
		/* Statement tokens */
1700
	    MAKE_exp_token ( type_void, id, args, e ) ;
1752
		MAKE_exp_token(type_void, id, args, e);
1701
	    while ( !IS_NULL_list ( args ) ) {
1753
		while (!IS_NULL_list(args)) {
1702
		TOKEN arg = DEREF_tok ( HEAD_list ( args ) ) ;
1754
			TOKEN arg = DEREF_tok(HEAD_list(args));
1703
		if ( IS_tok_stmt ( arg ) ) {
1755
			if (IS_tok_stmt(arg)) {
1704
		    /* Set parent statement for arguments */
1756
				/* Set parent statement for arguments */
1705
		    EXP a = DEREF_exp ( tok_stmt_value ( arg ) ) ;
1757
				EXP a = DEREF_exp(tok_stmt_value(arg));
1706
		    set_parent_stmt ( a, e ) ;
1758
				set_parent_stmt(a, e);
1707
		}
1759
			}
1708
		args = TAIL_list ( args ) ;
1760
			args = TAIL_list(args);
1709
	    }
1761
		}
1710
	    IGNORE check_throw ( NULL_type, 0 ) ;
1762
		IGNORE check_throw(NULL_type, 0);
1711
	    break ;
1763
		break;
1712
	}
-
 
1713
	case tok_nat_tag :
1764
	case tok_nat_tag:
1714
	case tok_snat_tag : {
1765
	case tok_snat_tag: {
1715
	    /* Integer constant tokens */
1766
		/* Integer constant tokens */
1716
	    NAT n ;
1767
		NAT n;
1717
	    MAKE_nat_token ( id, args, n ) ;
1768
		MAKE_nat_token(id, args, n);
1718
	    MAKE_exp_int_lit ( type_sint, n, exp_token_tag, e ) ;
1769
		MAKE_exp_int_lit(type_sint, n, exp_token_tag, e);
1719
	    break ;
1770
		break;
1720
	}
1771
	}
1721
	default : {
1772
	default:
1722
	    /* Other tokens */
1773
		/* Other tokens */
1723
	    e = NULL_exp ;
1774
		e = NULL_exp;
1724
	    break ;
1775
		break;
1725
	}
1776
	}
1726
    }
-
 
1727
    return ( e ) ;
1777
	return (e);
1728
}
1778
}
1729
 
1779
 
1730
 
1780
 
1731
/*
1781
/*
1732
    APPLY AN INTEGER CONSTANT TOKEN
1782
    APPLY AN INTEGER CONSTANT TOKEN
1733
 
1783
 
1734
    This routine applies the integer constant token id to the arguments args.
1784
    This routine applies the integer constant token id to the arguments args.
1735
*/
1785
*/
1736
 
1786
 
1737
NAT apply_nat_token
1787
NAT
1738
    PROTO_N ( ( id, args ) )
-
 
1739
    PROTO_T ( IDENTIFIER id X LIST ( TOKEN ) args )
1788
apply_nat_token(IDENTIFIER id, LIST(TOKEN) args)
1740
{
1789
{
1741
    NAT n ;
1790
	NAT n;
1742
    TOKEN tok = DEREF_tok ( id_token_sort ( id ) ) ;
1791
	TOKEN tok = DEREF_tok(id_token_sort(id));
1743
    unsigned tag = TAG_tok ( tok ) ;
1792
	unsigned tag = TAG_tok(tok);
1744
    if ( tag == tok_proc_tag ) {
1793
	if (tag == tok_proc_tag) {
1745
	tok = DEREF_tok ( tok_proc_res ( tok ) ) ;
1794
		tok = DEREF_tok(tok_proc_res(tok));
1746
	tag = TAG_tok ( tok ) ;
1795
		tag = TAG_tok(tok);
1747
    }
1796
	}
1748
    if ( tag == tok_nat_tag || tag == tok_snat_tag ) {
1797
	if (tag == tok_nat_tag || tag == tok_snat_tag) {
1749
	MAKE_nat_token ( id, args, n ) ;
1798
		MAKE_nat_token(id, args, n);
1750
    } else {
1799
	} else {
1751
	n = NULL_nat ;
1800
		n = NULL_nat;
1752
    }
1801
	}
1753
    return ( n ) ;
1802
	return (n);
1754
}
1803
}
1755
 
1804
 
1756
 
1805
 
1757
/*
1806
/*
1758
    APPLY A BUILT-IN TYPE TOKEN
1807
    APPLY A BUILT-IN TYPE TOKEN
1759
 
1808
 
1760
    Certain language extensions are implemented as built-in tokens (see
1809
    Certain language extensions are implemented as built-in tokens (see
1761
    define_keyword).  This routine applies such a token, given by the
1810
    define_keyword).  This routine applies such a token, given by the
1762
    keyword lex, to the arguments args.
1811
    keyword lex, to the arguments args.
1763
*/
1812
*/
1764
 
1813
 
1765
static TYPE key_type_token
1814
static TYPE
1766
    PROTO_N ( ( lex, args ) )
-
 
1767
    PROTO_T ( int lex X LIST ( TOKEN ) args )
1815
key_type_token(int lex, LIST(TOKEN) args)
1768
{
1816
{
1769
    TYPE t = NULL_type ;
1817
	TYPE t = NULL_type;
1770
    switch ( lex ) {
1818
	switch (lex) {
1771
	case lex_representation : {
1819
	case lex_representation: {
1772
	    TOKEN arg = DEREF_tok ( HEAD_list ( args ) ) ;
1820
		TOKEN arg = DEREF_tok(HEAD_list(args));
1773
	    t = DEREF_type ( tok_type_value ( arg ) ) ;
1821
		t = DEREF_type(tok_type_value(arg));
1774
	    if ( !IS_NULL_type ( t ) && IS_type_integer ( t ) ) {
1822
		if (!IS_NULL_type(t) && IS_type_integer(t)) {
1775
		TYPE s ;
1823
			TYPE s;
1776
		args = TAIL_list ( args ) ;
1824
			args = TAIL_list(args);
1777
		arg = DEREF_tok ( HEAD_list ( args ) ) ;
1825
			arg = DEREF_tok(HEAD_list(args));
1778
		s = DEREF_type ( tok_type_value ( arg ) ) ;
1826
			s = DEREF_type(tok_type_value(arg));
1779
		if ( !IS_NULL_type ( s ) && IS_type_integer ( s ) ) {
1827
			if (!IS_NULL_type(s) && IS_type_integer(s)) {
1780
		    INT_TYPE it = DEREF_itype ( type_integer_rep ( t ) ) ;
1828
				INT_TYPE it = DEREF_itype(type_integer_rep(t));
1781
		    INT_TYPE is = DEREF_itype ( type_integer_rep ( s ) ) ;
1829
				INT_TYPE is = DEREF_itype(type_integer_rep(s));
1782
		    t = make_itype ( it, is ) ;
1830
				t = make_itype(it, is);
1783
		}
1831
			}
1784
	    }
1832
		}
1785
	    break ;
1833
		break;
1786
	}
1834
	}
1787
	case lex_typeof : {
1835
	case lex_typeof: {
1788
	    TOKEN arg = DEREF_tok ( HEAD_list ( args ) ) ;
1836
		TOKEN arg = DEREF_tok(HEAD_list(args));
1789
	    EXP e = DEREF_exp ( tok_exp_value ( arg ) ) ;
1837
		EXP e = DEREF_exp(tok_exp_value(arg));
1790
	    if ( !IS_NULL_exp ( e ) ) {
1838
		if (!IS_NULL_exp(e)) {
1791
		t = DEREF_type ( exp_type ( e ) ) ;
1839
			t = DEREF_type(exp_type(e));
1792
		if ( IS_type_bitfield ( t ) ) {
1840
			if (IS_type_bitfield(t)) {
1793
		    t = promote_type ( t ) ;
1841
				t = promote_type(t);
1794
		}
1842
			}
1795
	    }
1843
		}
1796
	    break ;
1844
		break;
-
 
1845
	}
1797
	}
1846
	}
1798
    }
-
 
1799
    return ( t ) ;
1847
	return (t);
1800
}
1848
}
1801
 
1849
 
1802
 
1850
 
1803
/*
1851
/*
1804
    APPLY A TYPE TOKEN
1852
    APPLY A TYPE TOKEN
1805
 
1853
 
1806
    This routine applies the type token id to the arguments args.  tid
1854
    This routine applies the type token id to the arguments args.  tid
1807
    gives the name, if any, to be given to any class created.
1855
    gives the name, if any, to be given to any class created.
1808
*/
1856
*/
1809
 
1857
 
1810
TYPE apply_type_token
1858
TYPE
1811
    PROTO_N ( ( id, args, tid ) )
-
 
1812
    PROTO_T ( IDENTIFIER id X LIST ( TOKEN ) args X IDENTIFIER tid )
1859
apply_type_token(IDENTIFIER id, LIST(TOKEN) args, IDENTIFIER tid)
1813
{
1860
{
1814
    TYPE t ;
1861
	TYPE t;
1815
    int pt = in_proc_token ;
1862
	int pt = in_proc_token;
1816
    TOKEN tok = DEREF_tok ( id_token_sort ( id ) ) ;
1863
	TOKEN tok = DEREF_tok(id_token_sort(id));
1817
    unsigned tag = TAG_tok ( tok ) ;
1864
	unsigned tag = TAG_tok(tok);
1818
    if ( tag == tok_proc_tag ) {
1865
	if (tag == tok_proc_tag) {
1819
	int lex = DEREF_int ( tok_proc_key ( tok ) ) ;
1866
		int lex = DEREF_int(tok_proc_key(tok));
1820
	if ( lex != lex_identifier ) {
1867
		if (lex != lex_identifier) {
1821
	    t = key_type_token ( lex, args ) ;
1868
			t = key_type_token(lex, args);
1822
	    if ( !IS_NULL_type ( t ) ) return ( t ) ;
1869
			if (!IS_NULL_type(t)) {
-
 
1870
				return (t);
-
 
1871
			}
1823
	}
1872
		}
1824
	tok = DEREF_tok ( tok_proc_res ( tok ) ) ;
1873
		tok = DEREF_tok(tok_proc_res(tok));
1825
	tag = TAG_tok ( tok ) ;
1874
		tag = TAG_tok(tok);
1826
    }
1875
	}
1827
    if ( tag == tok_type_tag ) {
1876
	if (tag == tok_type_tag) {
1828
	BASE_TYPE bt = DEREF_btype ( tok_type_kind ( tok ) ) ;
1877
		BASE_TYPE bt = DEREF_btype(tok_type_kind(tok));
1829
	if ( bt & btype_scalar ) {
1878
		if (bt & btype_scalar) {
1830
	    /* Scalar types */
1879
			/* Scalar types */
1831
	    t = apply_itype_token ( id, args ) ;
1880
			t = apply_itype_token(id, args);
1832
 
1881
 
1833
	} else if ( bt & btype_named ) {
1882
		} else if (bt & btype_named) {
1834
	    /* Structure and union types */
1883
			/* Structure and union types */
1835
	    TYPE s ;
1884
			TYPE s;
1836
	    CLASS_TYPE ct ;
1885
			CLASS_TYPE ct;
1837
	    CLASS_INFO ci ;
1886
			CLASS_INFO ci;
1838
	    int tq = crt_templ_qualifier ;
1887
			int tq = crt_templ_qualifier;
1839
	    QUALIFIER cq = crt_id_qualifier ;
1888
			QUALIFIER cq = crt_id_qualifier;
1840
	    int td = have_type_declaration ;
1889
			int td = have_type_declaration;
1841
	    if ( IS_NULL_id ( tid ) ) {
1890
			if (IS_NULL_id(tid)) {
1842
		/* Make up class name if necessary */
1891
				/* Make up class name if necessary */
1843
		HASHID tnm = lookup_anon () ;
1892
				HASHID tnm = lookup_anon();
1844
		tid = DEREF_id ( hashid_id ( tnm ) ) ;
1893
				tid = DEREF_id(hashid_id(tnm));
1845
	    }
1894
			}
1846
 
1895
 
1847
	    /* Define the class */
1896
			/* Define the class */
1848
	    crt_id_qualifier = qual_none ;
1897
			crt_id_qualifier = qual_none;
1849
	    crt_templ_qualifier = 0 ;
1898
			crt_templ_qualifier = 0;
1850
	    tid = begin_class_defn ( tid, bt, cinfo_token, NULL_type ) ;
1899
			tid = begin_class_defn(tid, bt, cinfo_token, NULL_type);
1851
	    if ( IS_NULL_list ( args ) ) {
1900
			if (IS_NULL_list(args)) {
1852
		COPY_id ( id_token_alt ( id ), tid ) ;
1901
				COPY_id(id_token_alt(id), tid);
1853
	    }
1902
			}
1854
	    t = DEREF_type ( id_class_name_etc_defn ( tid ) ) ;
1903
			t = DEREF_type(id_class_name_etc_defn(tid));
1855
	    while ( IS_type_templ ( t ) ) {
1904
			while (IS_type_templ(t)) {
1856
		t = DEREF_type ( type_templ_defn ( t ) ) ;
1905
				t = DEREF_type(type_templ_defn(t));
1857
	    }
1906
			}
1858
	    ct = DEREF_ctype ( type_compound_defn ( t ) ) ;
1907
			ct = DEREF_ctype(type_compound_defn(t));
1859
	    ci = DEREF_cinfo ( ctype_info ( ct ) ) ;
1908
			ci = DEREF_cinfo(ctype_info(ct));
1860
	    ci &= ~cinfo_empty ;
1909
			ci &= ~cinfo_empty;
1861
	    COPY_cinfo ( ctype_info ( ct ), ci ) ;
1910
			COPY_cinfo(ctype_info(ct), ci);
1862
	    MAKE_type_token ( cv_none, id, args, s ) ;
1911
			MAKE_type_token(cv_none, id, args, s);
1863
	    COPY_type ( ctype_form ( ct ), s ) ;
1912
			COPY_type(ctype_form(ct), s);
1864
	    in_class_defn++ ;
1913
			in_class_defn++;
1865
	    really_in_class_defn++ ;
1914
			really_in_class_defn++;
1866
	    IGNORE end_class_defn ( tid ) ;
1915
			IGNORE end_class_defn(tid);
1867
	    really_in_class_defn-- ;
1916
			really_in_class_defn--;
1868
	    in_class_defn-- ;
1917
			in_class_defn--;
1869
	    have_type_declaration = td ;
1918
			have_type_declaration = td;
1870
	    crt_templ_qualifier = tq ;
1919
			crt_templ_qualifier = tq;
1871
	    crt_id_qualifier = cq ;
1920
			crt_id_qualifier = cq;
1872
 
1921
 
-
 
1922
		} else {
-
 
1923
			/* Generic types */
-
 
1924
			MAKE_type_token(cv_none, id, args, t);
-
 
1925
		}
1873
	} else {
1926
	} else {
-
 
1927
		/* Shouldn't occur */
-
 
1928
		t = type_error;
-
 
1929
	}
-
 
1930
	if (pt) {
-
 
1931
		/* Expand token arguments */
-
 
1932
		in_proc_token = 0;
1874
	    /* Generic types */
1933
		t = expand_type(t, 2);
-
 
1934
		in_proc_token = pt;
-
 
1935
	}
-
 
1936
	return (t);
-
 
1937
}
-
 
1938
 
-
 
1939
 
-
 
1940
/*
-
 
1941
    APPLY A MEMBER TOKEN
-
 
1942
 
-
 
1943
    This routine applies the member token id to the arguments args.
-
 
1944
*/
-
 
1945
 
-
 
1946
OFFSET
-
 
1947
apply_mem_token(IDENTIFIER id, LIST(TOKEN) args)
-
 
1948
{
-
 
1949
	OFFSET off;
1875
	    MAKE_type_token ( cv_none, id, args, t ) ;
1950
	MAKE_off_token(id, args, off);
-
 
1951
	return (off);
-
 
1952
}
-
 
1953
 
-
 
1954
 
-
 
1955
/*
-
 
1956
    APPLY A TOKEN
-
 
1957
 
-
 
1958
    This routine applies the token id to the arguments args.
-
 
1959
*/
-
 
1960
 
-
 
1961
TOKEN
-
 
1962
apply_token(IDENTIFIER id, LIST(TOKEN) args)
-
 
1963
{
-
 
1964
	TOKEN tok = NULL_tok;
-
 
1965
	TOKEN sort = DEREF_tok(id_token_sort(id));
-
 
1966
	unsigned tag = TAG_tok(sort);
-
 
1967
	if (tag == tok_proc_tag) {
-
 
1968
		sort = DEREF_tok(tok_proc_res(sort));
-
 
1969
		tag = TAG_tok(sort);
-
 
1970
	}
-
 
1971
	switch (tag) {
-
 
1972
	case tok_exp_tag: {
-
 
1973
		EXP e = apply_exp_token(id, args, 0);
-
 
1974
		TYPE t = DEREF_type(exp_type(e));
-
 
1975
		int c = DEREF_int(tok_exp_constant(sort));
-
 
1976
		MAKE_tok_exp(t, c, e, tok);
-
 
1977
		break;
-
 
1978
	}
-
 
1979
	case tok_nat_tag:
-
 
1980
	case tok_snat_tag: {
-
 
1981
		NAT n = apply_nat_token(id, args);
-
 
1982
		MAKE_tok_nat_etc(tag, n, tok);
-
 
1983
		break;
-
 
1984
	}
-
 
1985
	case tok_stmt_tag: {
-
 
1986
		EXP e = apply_exp_token(id, args, 0);
-
 
1987
		MAKE_tok_stmt(e, tok);
-
 
1988
		break;
-
 
1989
	}
-
 
1990
	case tok_type_tag: {
-
 
1991
		TYPE t;
-
 
1992
		BASE_TYPE bt = DEREF_btype(tok_type_kind(sort));
-
 
1993
		t = apply_type_token(id, args, NULL_id);
-
 
1994
		MAKE_tok_type(bt, t, tok);
-
 
1995
		break;
-
 
1996
	}
-
 
1997
	case tok_member_tag: {
-
 
1998
		TYPE s = DEREF_type(tok_member_of(sort));
-
 
1999
		TYPE t = DEREF_type(tok_member_type(sort));
-
 
2000
		OFFSET off = apply_mem_token(id, args);
-
 
2001
		MAKE_tok_member(s, t, off, tok);
-
 
2002
		break;
-
 
2003
	}
-
 
2004
	case tok_class_tag: {
-
 
2005
		TYPE t = DEREF_type(tok_class_type(sort));
-
 
2006
		MAKE_tok_class(t, id, tok);
-
 
2007
		break;
-
 
2008
	}
1876
	}
2009
	}
1877
    } else {
-
 
1878
	/* Shouldn't occur */
-
 
1879
	t = type_error ;
-
 
1880
    }
-
 
1881
    if ( pt ) {
-
 
1882
	/* Expand token arguments */
-
 
1883
	in_proc_token = 0 ;
-
 
1884
	t = expand_type ( t, 2 ) ;
-
 
1885
	in_proc_token = pt ;
-
 
1886
    }
-
 
1887
    return ( t ) ;
2010
	return (tok);
1888
}
2011
}
1889
 
2012
 
1890
 
2013
 
1891
/*
2014
/*
1892
    APPLY A MEMBER TOKEN
2015
    COMPARE TWO TOKENS
1893
 
-
 
1894
    This routine applies the member token id to the arguments args.
-
 
1895
*/
-
 
1896
 
2016
 
1897
OFFSET apply_mem_token
2017
    This routine compares the token sorts a and b.
-
 
2018
*/
-
 
2019
 
1898
    PROTO_N ( ( id, args ) )
2020
static int
1899
    PROTO_T ( IDENTIFIER id X LIST ( TOKEN ) args )
2021
eq_tok(TOKEN a, TOKEN b)
1900
{
2022
{
-
 
2023
	/* Check for obvious equality */
1901
    OFFSET off ;
2024
	unsigned na, nb;
1902
    MAKE_off_token ( id, args, off ) ;
2025
	if (EQ_tok(a, b)) {
-
 
2026
		return (1);
-
 
2027
	}
-
 
2028
	if (IS_NULL_tok(a)) {
-
 
2029
		return (0);
-
 
2030
	}
-
 
2031
	if (IS_NULL_tok(b)) {
1903
    return ( off ) ;
2032
		return (0);
1904
}
2033
	}
1905
 
2034
 
-
 
2035
	/* Compare tags */
-
 
2036
	na = TAG_tok(a);
-
 
2037
	nb = TAG_tok(b);
-
 
2038
	if (na != nb) {
-
 
2039
		return (0);
-
 
2040
	}
1906
 
2041
 
-
 
2042
	/* Compare token components */
-
 
2043
	ASSERT(ORDER_tok == 10);
-
 
2044
	switch (na) {
-
 
2045
	case tok_exp_tag: {
-
 
2046
		/* Expression tokens */
-
 
2047
		TYPE ta = DEREF_type(tok_exp_type(a));
-
 
2048
		TYPE tb = DEREF_type(tok_exp_type(b));
-
 
2049
		CV_SPEC qa = DEREF_cv(type_qual(ta));
-
 
2050
		CV_SPEC qb = DEREF_cv(type_qual(tb));
-
 
2051
		int ca = DEREF_int(tok_exp_constant(a));
-
 
2052
		int cb = DEREF_int(tok_exp_constant(b));
-
 
2053
		return (ca == cb && qa == qb && eq_type(ta, tb));
1907
/*
2054
	}
-
 
2055
	case tok_nat_tag:
1908
    APPLY A TOKEN
2056
	case tok_snat_tag:
-
 
2057
	case tok_stmt_tag:
-
 
2058
		/* Trivial cases */
-
 
2059
		break;
-
 
2060
	case tok_func_tag: {
-
 
2061
		/* Function tokens */
-
 
2062
		TYPE ta = DEREF_type(tok_func_type(a));
-
 
2063
		TYPE tb = DEREF_type(tok_func_type(b));
-
 
2064
		return (eq_type(ta, tb));
-
 
2065
	}
-
 
2066
	case tok_member_tag: {
-
 
2067
		/* Member tokens */
-
 
2068
		TYPE sa = DEREF_type(tok_member_of(a));
-
 
2069
		TYPE sb = DEREF_type(tok_member_of(b));
-
 
2070
		TYPE ta = DEREF_type(tok_member_type(a));
-
 
2071
		TYPE tb = DEREF_type(tok_member_type(b));
-
 
2072
		return (eq_type(sa, sb) && eq_type(ta, tb));
-
 
2073
	}
-
 
2074
	case tok_proc_tag: {
-
 
2075
		/* Procedure tokens */
-
 
2076
		LIST(IDENTIFIER) pa, pb;
-
 
2077
		TOKEN ra = DEREF_tok(tok_proc_res(a));
-
 
2078
		TOKEN rb = DEREF_tok(tok_proc_res(b));
-
 
2079
		if (!eq_tok(ra, rb)) {
-
 
2080
			return (0);
-
 
2081
		}
1909
 
2082
 
2081
	}
2157
	}
2082
 
-
 
2083
	case tok_templ_tag : {
-
 
2084
	    /* Templates */
-
 
2085
	    /* NOT YET IMPLEMENTED */
-
 
2086
	    return ( 0 ) ;
-
 
2087
	}
-
 
2088
    }
-
 
2089
    return ( 1 ) ;
2158
	return (1);
2090
}
2159
}
2091
 
2160
 
2092
 
2161
 
2093
/*
2162
/*
2094
    DECLARE A TOKEN IDENTIFIER
2163
    DECLARE A TOKEN IDENTIFIER
2095
 
2164
 
2096
    This routine declares a token identifier id with sort tok and external
2165
    This routine declares a token identifier id with sort tok and external
2097
    name ext in the namespace ns.
2166
    name ext in the namespace ns.
2098
*/
2167
*/
2099
 
2168
 
2100
static IDENTIFIER declare_token
2169
static IDENTIFIER
2101
    PROTO_N ( ( id, tok, ns, ext ) )
-
 
2102
    PROTO_T ( IDENTIFIER id X TOKEN tok X NAMESPACE ns X IDENTIFIER ext )
2170
declare_token(IDENTIFIER id, TOKEN tok, NAMESPACE ns, IDENTIFIER ext)
2103
{
2171
{
2104
    HASHID nm = DEREF_hashid ( id_name ( id ) ) ;
2172
	HASHID nm = DEREF_hashid(id_name(id));
2105
    MEMBER mem = search_member ( ns, nm, 1 ) ;
2173
	MEMBER mem = search_member(ns, nm, 1);
-
 
2174
 
-
 
2175
	/* Check identifier name */
-
 
2176
	ERROR err = check_id_name(id, CONTEXT_OBJECT);
-
 
2177
	if (!IS_NULL_err(err))report(crt_loc, err);
2106
 
2178
 
2107
    /* Check identifier name */
-
 
2108
    ERROR err = check_id_name ( id, CONTEXT_OBJECT ) ;
-
 
2109
    if ( !IS_NULL_err ( err ) ) report ( crt_loc, err ) ;
-
 
2110
 
-
 
2111
    /* Check for previous definition */
2179
	/* Check for previous definition */
2112
    id = DEREF_id ( member_id ( mem ) ) ;
2180
	id = DEREF_id(member_id(mem));
2113
    if ( !IS_NULL_id ( id ) ) {
2181
	if (!IS_NULL_id(id)) {
2114
	id = redecl_inherit ( id, qual_none, 0, 0 ) ;
2182
		id = redecl_inherit(id, qual_none, 0, 0);
2115
	if ( !IS_NULL_id ( id ) ) {
2183
		if (!IS_NULL_id(id)) {
2116
	    if ( IS_id_token ( id ) ) {
2184
			if (IS_id_token(id)) {
2117
		/* Allow for redeclarations */
2185
				/* Allow for redeclarations */
2118
		IDENTIFIER tid = DEREF_id ( id_token_alt ( id ) ) ;
2186
				IDENTIFIER tid = DEREF_id(id_token_alt(id));
2119
		if ( EQ_id ( tid, ext ) ) return ( id ) ;
2187
				if (EQ_id(tid, ext)) {
-
 
2188
					return (id);
2120
	    }
2189
				}
-
 
2190
			}
2121
	    if ( IS_id_function ( id ) && IS_tok_proc ( tok ) ) {
2191
			if (IS_id_function(id) && IS_tok_proc(tok)) {
2122
		IDENTIFIER pid = id ;
2192
				IDENTIFIER pid = id;
2123
		while ( !IS_NULL_id ( pid ) ) {
2193
				while (!IS_NULL_id(pid)) {
-
 
2194
					TYPE t =
2124
		    TYPE t = DEREF_type ( id_function_type ( pid ) ) ;
2195
					    DEREF_type(id_function_type(pid));
2125
		    if ( IS_type_func ( t ) ) {
2196
					if (IS_type_func(t)) {
2126
			TOKEN ptok ;
2197
						TOKEN ptok;
2127
			MAKE_tok_func ( t, ptok ) ;
2198
						MAKE_tok_func(t, ptok);
2128
			ptok = func_proc_token ( ptok ) ;
2199
						ptok = func_proc_token(ptok);
2129
			if ( eq_tok ( ptok, tok ) ) {
2200
						if (eq_tok(ptok, tok)) {
-
 
2201
							/* Procedure token
2130
			    /* Procedure token matches function */
2202
							 * matches function */
2131
			    return ( pid ) ;
2203
							return (pid);
-
 
2204
						}
-
 
2205
					}
-
 
2206
					pid = DEREF_id(id_function_over(pid));
-
 
2207
				}
2132
			}
2208
			}
2133
		    }
-
 
2134
		    pid = DEREF_id ( id_function_over ( pid ) ) ;
-
 
2135
		}
2209
		}
2136
	    }
-
 
2137
	}
2210
	}
2138
    }
-
 
2139
 
2211
 
2140
    /* Declare the token */
2212
	/* Declare the token */
2141
    MAKE_id_token ( nm, dspec_token, ns, preproc_loc, tok, ext, id ) ;
2213
	MAKE_id_token(nm, dspec_token, ns, preproc_loc, tok, ext, id);
2142
    set_member ( mem, id ) ;
2214
	set_member(mem, id);
2143
    return ( id ) ;
2215
	return (id);
2144
}
2216
}
2145
 
2217
 
2146
 
2218
 
2147
/*
2219
/*
2148
    DECLARE AN EXTERNAL TOKEN
2220
    DECLARE AN EXTERNAL TOKEN
2149
 
2221
 
2150
    This routine declares a token of sort tok with internal name id,
2222
    This routine declares a token of sort tok with internal name id,
2151
    which belongs to the tag namespace if tag is true, and external name
2223
    which belongs to the tag namespace if tag is true, and external name
2152
    ext.  It returns the external token identifier.
2224
    ext.  It returns the external token identifier.
2153
*/
2225
*/
2154
 
2226
 
2155
IDENTIFIER make_token_decl
2227
IDENTIFIER
2156
    PROTO_N ( ( tok, tag, id, ext ) )
-
 
2157
    PROTO_T ( TOKEN tok X int tag X IDENTIFIER id X IDENTIFIER ext )
2228
make_token_decl(TOKEN tok, int tag, IDENTIFIER id, IDENTIFIER ext)
2158
{
2229
{
2159
    int tq ;
2230
	int tq;
2160
    HASHID nm ;
2231
	HASHID nm;
2161
    MEMBER mem ;
2232
	MEMBER mem;
2162
    unsigned tt ;
2233
	unsigned tt;
2163
    QUALIFIER cq ;
2234
	QUALIFIER cq;
2164
    NAMESPACE ns ;
2235
	NAMESPACE ns;
2165
    NAMESPACE gns ;
2236
	NAMESPACE gns;
2166
    int macro = 0 ;
2237
	int macro = 0;
2167
    int pushed = 0 ;
2238
	int pushed = 0;
2168
    int done_dump = 0 ;
2239
	int done_dump = 0;
2169
    IDENTIFIER tid = NULL_id ;
2240
	IDENTIFIER tid = NULL_id;
2170
    DECL_SPEC ds = dspec_token ;
2241
	DECL_SPEC ds = dspec_token;
2171
    DECL_SPEC mark = dspec_token ;
2242
	DECL_SPEC mark = dspec_token;
2172
 
2243
 
2173
    /* Ignore illegal tokens */
2244
	/* Ignore illegal tokens */
2174
    if ( IS_NULL_tok ( tok ) ) return ( NULL_id ) ;
2245
	if (IS_NULL_tok(tok)) {
-
 
2246
		return (NULL_id);
-
 
2247
	}
2175
 
2248
 
2176
    /* Find token name */
2249
	/* Find token name */
2177
    if ( !IS_NULL_id ( ext ) ) {
2250
	if (!IS_NULL_id(ext)) {
2178
	/* Externally named token */
2251
		/* Externally named token */
2179
	ns = token_namespace ;
2252
		ns = token_namespace;
2180
	/* gns = global_namespace ; */
2253
		/* gns = global_namespace ; */
2181
	gns = nonblock_namespace ;
2254
		gns = nonblock_namespace;
2182
	nm = DEREF_hashid ( id_name ( ext ) ) ;
2255
		nm = DEREF_hashid(id_name(ext));
2183
	mem = search_member ( ns, nm, 1 ) ;
2256
		mem = search_member(ns, nm, 1);
2184
	ext = DEREF_id ( member_id ( mem ) ) ;
2257
		ext = DEREF_id(member_id(mem));
2185
	if ( !IS_NULL_id ( ext ) ) {
2258
		if (!IS_NULL_id(ext)) {
2186
	    TOKEN tok2 = DEREF_tok ( id_token_sort ( ext ) ) ;
2259
			TOKEN tok2 = DEREF_tok(id_token_sort(ext));
2187
	    force_tokdef++ ;
2260
			force_tokdef++;
2188
	    if ( !eq_tok ( tok, tok2 ) ) {
2261
			if (!eq_tok(tok, tok2)) {
2189
		ERROR err = ERR_token_redecl ( ext, id_loc ( ext ) ) ;
2262
				ERROR err = ERR_token_redecl(ext, id_loc(ext));
2190
		report ( preproc_loc, err ) ;
2263
				report(preproc_loc, err);
2191
		ext = NULL_id ;
2264
				ext = NULL_id;
2192
	    }
2265
			}
2193
	    force_tokdef-- ;
2266
			force_tokdef--;
2194
	}
2267
		}
2195
	if ( IS_hashid_anon ( nm ) ) {
2268
		if (IS_hashid_anon(nm)) {
2196
	    ds |= dspec_static ;
2269
			ds |= dspec_static;
2197
	} else {
2270
		} else {
2198
	    ds |= dspec_extern ;
2271
			ds |= dspec_extern;
2199
	}
2272
		}
2200
    } else {
2273
	} else {
2201
	/* Token parameter */
2274
		/* Token parameter */
2202
	ns = crt_namespace ;
2275
		ns = crt_namespace;
2203
	gns = ns ;
2276
		gns = ns;
2204
	nm = DEREF_hashid ( id_name ( id ) ) ;
2277
		nm = DEREF_hashid(id_name(id));
2205
	mem = NULL_member ;
2278
		mem = NULL_member;
2206
	ds |= ( dspec_auto | dspec_pure ) ;
2279
		ds |= (dspec_auto | dspec_pure);
2207
    }
2280
	}
2208
 
2281
 
2209
    /* Create the token */
2282
	/* Create the token */
2210
    if ( IS_NULL_id ( ext ) ) {
2283
	if (IS_NULL_id(ext)) {
2211
	IDENTIFIER uid = underlying_id ( id ) ;
2284
		IDENTIFIER uid = underlying_id(id);
2212
	MAKE_id_token ( nm, ds, ns, preproc_loc, tok, uid, ext ) ;
2285
		MAKE_id_token(nm, ds, ns, preproc_loc, tok, uid, ext);
2213
	if ( !IS_NULL_member ( mem ) ) {
2286
		if (!IS_NULL_member(mem)) {
2214
	    COPY_id ( member_id ( mem ), ext ) ;
2287
			COPY_id(member_id(mem), ext);
2215
	}
2288
		}
2216
    }
2289
	}
2217
 
2290
 
2218
    /* Declare the corresponding identifier */
2291
	/* Declare the corresponding identifier */
2219
    cq = crt_id_qualifier ;
2292
	cq = crt_id_qualifier;
2220
    tq = crt_templ_qualifier ;
2293
	tq = crt_templ_qualifier;
2221
    crt_id_qualifier = qual_none ;
2294
	crt_id_qualifier = qual_none;
2222
    crt_templ_qualifier = 0 ;
2295
	crt_templ_qualifier = 0;
2223
    if ( !EQ_nspace ( gns, crt_namespace ) ) {
2296
	if (!EQ_nspace(gns, crt_namespace)) {
2224
	push_namespace ( gns ) ;
2297
		push_namespace(gns);
2225
	pushed = 1 ;
2298
		pushed = 1;
2226
    }
2299
	}
2227
    tt = TAG_tok ( tok ) ;
2300
	tt = TAG_tok(tok);
2228
    if ( tt == tok_type_tag ) {
2301
	if (tt == tok_type_tag) {
2229
	BASE_TYPE bt = DEREF_btype ( tok_type_kind ( tok ) ) ;
2302
		BASE_TYPE bt = DEREF_btype(tok_type_kind(tok));
2230
	if ( bt & btype_named ) {
2303
		if (bt & btype_named) {
2231
	    /* Allow structure and union tags */
2304
			/* Allow structure and union tags */
-
 
2305
			if (tag) {
2232
	    if ( tag ) tid = id ;
2306
				tid = id;
-
 
2307
			}
-
 
2308
		} else {
-
 
2309
			tag = 0;
-
 
2310
		}
2233
	} else {
2311
	} else {
-
 
2312
		/* Other tags are not allowed */
2234
	    tag = 0 ;
2313
		tag = 0;
-
 
2314
	}
-
 
2315
	switch (tt) {
-
 
2316
	case tok_type_tag: {
-
 
2317
		/* Simple type tokens */
-
 
2318
		TYPE t = apply_type_token(ext, NULL_list(TOKEN), tid);
-
 
2319
		if (tag) {
-
 
2320
			CLASS_TYPE ct = DEREF_ctype(type_compound_defn(t));
-
 
2321
			id = DEREF_id(ctype_name(ct));
-
 
2322
			done_dump = 1;
-
 
2323
		} else {
-
 
2324
			id = make_object_decl(dspec_typedef, t, id, 0);
-
 
2325
			if (!(ds & dspec_auto)) {
-
 
2326
				macro = 2;
-
 
2327
			}
-
 
2328
		}
-
 
2329
		break;
2235
	}
2330
	}
2236
    } else {
-
 
2237
	/* Other tags are not allowed */
-
 
2238
	tag = 0 ;
-
 
2239
    }
-
 
2240
    switch ( tt ) {
-
 
2241
 
-
 
2242
	case tok_type_tag : {
-
 
2243
	    /* Simple type tokens */
-
 
2244
	    TYPE t = apply_type_token ( ext, NULL_list ( TOKEN ), tid ) ;
-
 
2245
	    if ( tag ) {
-
 
2246
		CLASS_TYPE ct = DEREF_ctype ( type_compound_defn ( t ) ) ;
-
 
2247
		id = DEREF_id ( ctype_name ( ct ) ) ;
-
 
2248
		done_dump = 1 ;
-
 
2249
	    } else {
-
 
2250
		id = make_object_decl ( dspec_typedef, t, id, 0 ) ;
-
 
2251
		if ( !( ds & dspec_auto ) ) macro = 2 ;
-
 
2252
	    }
-
 
2253
	    break ;
-
 
2254
	}
-
 
2255
 
-
 
2256
	case tok_func_tag : {
2331
	case tok_func_tag: {
2257
	    /* Function tokens (C linkage by default) */
2332
		/* Function tokens (C linkage by default) */
2258
	    TYPE t = DEREF_type ( tok_func_type ( tok ) ) ;
2333
		TYPE t = DEREF_type(tok_func_type(tok));
2259
	    int ell = DEREF_int ( type_func_ellipsis ( t ) ) ;
2334
		int ell = DEREF_int(type_func_ellipsis(t));
2260
	    DECL_SPEC ln = crt_linkage ;
2335
		DECL_SPEC ln = crt_linkage;
2261
	    if ( ln == dspec_none ) crt_linkage = dspec_c ;
-
 
2262
	    id = make_func_decl ( dspec_extern, t, id, 0 ) ;
-
 
2263
	    IGNORE init_object ( id, NULL_exp ) ;
-
 
2264
	    if ( IS_id_function_etc ( id ) && ell == FUNC_NONE ) {
-
 
2265
		TYPE form ;
-
 
2266
		MAKE_type_token ( cv_none, ext, NULL_list ( TOKEN ), form ) ;
-
 
2267
		COPY_type ( id_function_etc_form ( id ), form ) ;
-
 
2268
		if ( !( ds & dspec_auto ) ) macro = 1 ;
-
 
2269
		if ( is_redeclared ) {
2336
		if (ln == dspec_none) {
2270
		    /* Mark functions which have already been declared */
-
 
2271
		    ds |= dspec_explicit ;
2337
			crt_linkage = dspec_c;
2272
		    COPY_dspec ( id_storage ( ext ), ds ) ;
-
 
2273
		}
2338
		}
2274
	    } else {
-
 
2275
		/* Ellipsis functions are not really tokenised */
2339
		id = make_func_decl(dspec_extern, t, id, 0);
2276
		mark = dspec_none ;
2340
		IGNORE init_object(id, NULL_exp);
2277
	    }
-
 
2278
	    crt_linkage = ln ;
2341
		if (IS_id_function_etc(id) && ell == FUNC_NONE) {
2279
	    break ;
2342
			TYPE form;
2280
	}
-
 
2281
 
-
 
2282
	case tok_member_tag : {
-
 
2283
	    /* Member tokens */
-
 
2284
	    int pt = in_proc_token ;
-
 
2285
	    CLASS_TYPE cs = crt_class ;
-
 
2286
	    TYPE t = DEREF_type ( tok_member_of ( tok ) ) ;
-
 
2287
	    CLASS_TYPE ct = DEREF_ctype ( type_compound_defn ( t ) ) ;
2343
			MAKE_type_token(cv_none, ext, NULL_list(TOKEN), form);
2288
	    NAMESPACE cns = DEREF_nspace ( ctype_member ( ct ) ) ;
-
 
2289
	    crt_class = ct ;
-
 
2290
	    in_class_defn++ ;
-
 
2291
	    really_in_class_defn++ ;
-
 
2292
	    push_namespace ( cns ) ;
-
 
2293
	    t = DEREF_type ( tok_member_type ( tok ) ) ;
2344
			COPY_type(id_function_etc_form(id), form);
2294
	    if ( pt ) {
-
 
2295
		in_proc_token = 0 ;
-
 
2296
		t = expand_type ( t, 2 ) ;
2345
			if (!(ds & dspec_auto)) {
2297
		in_proc_token = pt ;
2346
				macro = 1;
2298
	    }
2347
			}
2299
	    id = make_member_decl ( dspec_token, t, id, 0 ) ;
-
 
2300
	    if ( IS_id_member ( id ) ) {
2348
			if (is_redeclared) {
2301
		OFFSET off = DEREF_off ( id_member_off ( id ) ) ;
2349
				/* Mark functions which have already been
2302
		if ( !IS_NULL_off ( off ) ) {
-
 
2303
		    t = DEREF_type ( id_member_type ( id ) ) ;
-
 
2304
		    IGNORE define_mem_token ( ext, off, t, 1 ) ;
-
 
2305
		    if ( !IS_NULL_member ( mem ) ) {
-
 
2306
			if ( IS_off_member ( off ) ) {
-
 
2307
			    /* Record old member name */
2350
				 * declared */
2308
			    IDENTIFIER pid ;
2351
				ds |= dspec_explicit;
2309
			    pid = DEREF_id ( off_member_id ( off ) ) ;
-
 
2310
			    COPY_id ( member_alt ( mem ), pid ) ;
2352
				COPY_dspec(id_storage(ext), ds);
2311
			}
2353
			}
2312
		    }
2354
		} else {
-
 
2355
			/* Ellipsis functions are not really tokenised */
-
 
2356
			mark = dspec_none;
2313
		}
2357
		}
-
 
2358
		crt_linkage = ln;
-
 
2359
		break;
-
 
2360
	}
-
 
2361
	case tok_member_tag: {
-
 
2362
		/* Member tokens */
-
 
2363
		int pt = in_proc_token;
-
 
2364
		CLASS_TYPE cs = crt_class;
2314
		off = apply_mem_token ( ext, NULL_list ( TOKEN ) ) ;
2365
		TYPE t = DEREF_type(tok_member_of(tok));
2315
		COPY_off ( id_member_off ( id ), off ) ;
2366
		CLASS_TYPE ct = DEREF_ctype(type_compound_defn(t));
2316
		if ( !( ds & dspec_auto ) ) macro = 2 ;
2367
		NAMESPACE cns = DEREF_nspace(ctype_member(ct));
2317
	    }
2368
		crt_class = ct;
2318
	    IGNORE pop_namespace () ;
2369
		in_class_defn++;
2319
	    really_in_class_defn-- ;
2370
		really_in_class_defn++;
2320
	    in_class_defn-- ;
2371
		push_namespace(cns);
-
 
2372
		t = DEREF_type(tok_member_type(tok));
-
 
2373
		if (pt) {
2321
	    crt_class = cs ;
2374
			in_proc_token = 0;
-
 
2375
			t = expand_type(t, 2);
2322
	    break ;
2376
			in_proc_token = pt;
2323
	}
2377
		}
2324
 
-
 
-
 
2378
		id = make_member_decl(dspec_token, t, id, 0);
2325
	case tok_class_tag : {
2379
		if (IS_id_member(id)) {
2326
	    /* Template template parameters */
2380
			OFFSET off = DEREF_off(id_member_off(id));
2327
	    TYPE t ;
2381
			if (!IS_NULL_off(off)) {
2328
	    TYPE q = DEREF_type ( tok_class_type ( tok ) ) ;
2382
				t = DEREF_type(id_member_type(id));
2329
	    MAKE_type_token ( cv_none, ext, NULL_list ( TOKEN ), t ) ;
2383
				IGNORE define_mem_token(ext, off, t, 1);
2330
	    id = make_object_decl ( dspec_typedef, t, id, 0 ) ;
2384
				if (!IS_NULL_member(mem)) {
2331
	    t = inject_pre_type ( q, t, 0 ) ;
2385
					if (IS_off_member(off)) {
2332
	    COPY_type ( id_class_name_etc_defn ( id ), t ) ;
2386
						/* Record old member name */
-
 
2387
						IDENTIFIER pid;
2333
	    COPY_type ( tok_class_type ( tok ), t ) ;
2388
						pid = DEREF_id(off_member_id(off));
2334
	    mark |= dspec_template ;
2389
						COPY_id(member_alt(mem), pid);
2335
	    break ;
2390
					}
2336
	}
2391
				}
2337
 
2392
			}
2338
	default : {
-
 
2339
	    /* Other tokens */
-
 
2340
	    decl_loc = preproc_loc ;
2393
			off = apply_mem_token(ext, NULL_list(TOKEN));
2341
	    id = declare_token ( id, tok, gns, ext ) ;
2394
			COPY_off(id_member_off(id), off);
2342
	    if ( IS_id_function ( id ) ) {
2395
			if (!(ds & dspec_auto)) {
2343
		TYPE form ;
2396
				macro = 2;
-
 
2397
			}
-
 
2398
		}
2344
		MAKE_type_token ( cv_none, ext, NULL_list ( TOKEN ), form ) ;
2399
		IGNORE pop_namespace();
2345
		COPY_type ( id_function_form ( id ), form ) ;
2400
		really_in_class_defn--;
2346
	    }
2401
		in_class_defn--;
2347
	    if ( !( ds & dspec_auto ) ) macro = 1 ;
2402
		crt_class = cs;
2348
	    break ;
2403
		break;
2349
	}
2404
	}
2350
    }
-
 
2351
    if ( mark ) {
2405
	case tok_class_tag: {
2352
	/* Mark object as a token */
2406
		/* Template template parameters */
2353
	ds = DEREF_dspec ( id_storage ( id ) ) ;
-
 
2354
	ds |= mark ;
2407
		TYPE t;
2355
	COPY_dspec ( id_storage ( id ), ds ) ;
2408
		TYPE q = DEREF_type(tok_class_type(tok));
2356
    }
-
 
2357
    COPY_id ( id_token_alt ( ext ), id ) ;
2409
		MAKE_type_token(cv_none, ext, NULL_list(TOKEN), t);
2358
    if ( !IS_NULL_member ( mem ) ) {
2410
		id = make_object_decl(dspec_typedef, t, id, 0);
2359
	IDENTIFIER pid = DEREF_id ( member_alt ( mem ) ) ;
2411
		t = inject_pre_type(q, t, 0);
2360
	if ( IS_NULL_id ( pid ) ) COPY_id ( member_alt ( mem ), id ) ;
2412
		COPY_type(id_class_name_etc_defn(id), t);
2361
	if ( do_dump ) {
-
 
2362
	    if ( !done_dump ) dump_declare ( id, &preproc_loc, 0 ) ;
2413
		COPY_type(tok_class_type(tok), t);
2363
	    dump_token ( id, ext ) ;
2414
		mark |= dspec_template;
-
 
2415
		break;
2364
	}
2416
	}
-
 
2417
	default:
-
 
2418
		/* Other tokens */
-
 
2419
		decl_loc = preproc_loc;
-
 
2420
		id = declare_token(id, tok, gns, ext);
-
 
2421
		if (IS_id_function(id)) {
-
 
2422
			TYPE form;
-
 
2423
			MAKE_type_token(cv_none, ext, NULL_list(TOKEN), form);
-
 
2424
			COPY_type(id_function_form(id), form);
-
 
2425
		}
-
 
2426
		if (!(ds & dspec_auto)) {
-
 
2427
			macro = 1;
-
 
2428
		}
-
 
2429
		break;
-
 
2430
	}
-
 
2431
	if (mark) {
-
 
2432
		/* Mark object as a token */
-
 
2433
		ds = DEREF_dspec(id_storage(id));
-
 
2434
		ds |= mark;
-
 
2435
		COPY_dspec(id_storage(id), ds);
-
 
2436
	}
-
 
2437
	COPY_id(id_token_alt(ext), id);
-
 
2438
	if (!IS_NULL_member(mem)) {
-
 
2439
		IDENTIFIER pid = DEREF_id(member_alt(mem));
-
 
2440
		if (IS_NULL_id(pid)) {
-
 
2441
			COPY_id(member_alt(mem), id);
-
 
2442
		}
-
 
2443
		if (do_dump) {
-
 
2444
			if (!done_dump) {
-
 
2445
				dump_declare(id, &preproc_loc, 0);
2365
    }
2446
			}
-
 
2447
			dump_token(id, ext);
-
 
2448
		}
-
 
2449
	}
2366
    if ( pushed ) {
2450
	if (pushed) {
2367
	IGNORE pop_namespace () ;
2451
		IGNORE pop_namespace();
2368
    }
2452
	}
2369
    crt_templ_qualifier = tq ;
2453
	crt_templ_qualifier = tq;
2370
    crt_id_qualifier = cq ;
2454
	crt_id_qualifier = cq;
2371
 
2455
 
2372
    /* Check for previous macro definition */
2456
	/* Check for previous macro definition */
2373
    if ( macro ) {
2457
	if (macro) {
2374
	IDENTIFIER mid ;
2458
		IDENTIFIER mid;
2375
	nm = DEREF_hashid ( id_name ( id ) ) ;
2459
		nm = DEREF_hashid(id_name(id));
2376
	mid = DEREF_id ( hashid_id ( nm ) ) ;
2460
		mid = DEREF_id(hashid_id(nm));
2377
	switch ( TAG_id ( mid ) ) {
2461
		switch (TAG_id(mid)) {
2378
	    case id_obj_macro_tag :
2462
		case id_obj_macro_tag:
2379
	    case id_func_macro_tag : {
2463
		case id_func_macro_tag: {
2380
		LOCATION loc ;
2464
			LOCATION loc;
2381
		loc = preproc_loc ;
2465
			loc = preproc_loc;
2382
		DEREF_loc ( id_loc ( mid ), preproc_loc ) ;
2466
			DEREF_loc(id_loc(mid), preproc_loc);
2383
		ds = DEREF_dspec ( id_storage ( mid ) ) ;
2467
			ds = DEREF_dspec(id_storage(mid));
2384
		COPY_dspec ( id_storage ( mid ), ( ds | dspec_temp ) ) ;
2468
			COPY_dspec(id_storage(mid), (ds | dspec_temp));
2385
		if ( define_token_macro ( id, mid ) ) {
2469
			if (define_token_macro(id, mid)) {
2386
		    ds |= dspec_used ;
2470
				ds |= dspec_used;
2387
		    if ( do_macro && do_usage ) {
2471
				if (do_macro && do_usage) {
2388
			dump_use ( mid, &loc, 1 ) ;
2472
					dump_use(mid, &loc, 1);
2389
		    }
2473
				}
2390
		    COPY_loc ( id_loc ( ext ), preproc_loc ) ;
2474
				COPY_loc(id_loc(ext), preproc_loc);
2391
		    no_declarations++ ;
2475
				no_declarations++;
-
 
2476
			}
-
 
2477
			COPY_dspec(id_storage(mid), ds);
-
 
2478
			preproc_loc = loc;
-
 
2479
			break;
-
 
2480
		}
2392
		}
2481
		}
2393
		COPY_dspec ( id_storage ( mid ), ds ) ;
-
 
2394
		preproc_loc = loc ;
-
 
2395
		break ;
-
 
2396
	    }
-
 
2397
	}
2482
	}
2398
    }
-
 
2399
    return ( ext ) ;
2483
	return (ext);
2400
}
2484
}
2401
 
2485
 
2402
 
2486
 
2403
/*
2487
/*
2404
    FIND A TOKEN IDENTIFIER
2488
    FIND A TOKEN IDENTIFIER
2405
 
2489
 
2406
    This routine finds the token identifier associated with the identifier
2490
    This routine finds the token identifier associated with the identifier
2407
    id.
2491
    id.
2408
*/
2492
*/
2409
 
2493
 
2410
static IDENTIFIER find_token_aux
2494
static IDENTIFIER
2411
    PROTO_N ( ( id ) )
-
 
2412
    PROTO_T ( IDENTIFIER id )
2495
find_token_aux(IDENTIFIER id)
2413
{
2496
{
2414
    switch ( TAG_id ( id ) ) {
2497
	switch (TAG_id(id)) {
2415
	case id_class_name_tag :
2498
	case id_class_name_tag:
2416
	case id_class_alias_tag : {
2499
	case id_class_alias_tag: {
2417
	    /* Classes */
2500
		/* Classes */
2418
	    TYPE t = DEREF_type ( id_class_name_etc_defn ( id ) ) ;
2501
		TYPE t = DEREF_type(id_class_name_etc_defn(id));
2419
	    if ( IS_type_compound ( t ) ) {
2502
		if (IS_type_compound(t)) {
2420
		CLASS_TYPE ct = DEREF_ctype ( type_compound_defn ( t ) ) ;
2503
			CLASS_TYPE ct = DEREF_ctype(type_compound_defn(t));
2421
		t = DEREF_type ( ctype_form ( ct ) ) ;
2504
			t = DEREF_type(ctype_form(ct));
2422
		if ( !IS_NULL_type ( t ) && IS_type_token ( t ) ) {
2505
			if (!IS_NULL_type(t) && IS_type_token(t)) {
2423
		    id = DEREF_id ( type_token_tok ( t ) ) ;
2506
				id = DEREF_id(type_token_tok(t));
2424
		    return ( id ) ;
2507
				return (id);
-
 
2508
			}
-
 
2509
		}
-
 
2510
		break;
-
 
2511
	}
-
 
2512
	case id_type_alias_tag: {
-
 
2513
		/* Types */
-
 
2514
		TYPE t = DEREF_type(id_type_alias_defn(id));
-
 
2515
		if (IS_type_token(t)) {
-
 
2516
			id = DEREF_id(type_token_tok(t));
-
 
2517
			return (id);
-
 
2518
		}
-
 
2519
		break;
-
 
2520
	}
-
 
2521
	case id_function_tag:
-
 
2522
	case id_mem_func_tag:
-
 
2523
	case id_stat_mem_func_tag: {
-
 
2524
		/* Functions */
-
 
2525
		TYPE form = DEREF_type(id_function_etc_form(id));
-
 
2526
		if (!IS_NULL_type(form) && IS_type_token(form)) {
-
 
2527
			IDENTIFIER ext = DEREF_id(type_token_tok(form));
-
 
2528
			if (!IS_NULL_id(ext)) {
-
 
2529
				return (ext);
-
 
2530
			}
-
 
2531
		}
-
 
2532
		return (id);
-
 
2533
	}
-
 
2534
	case id_member_tag: {
-
 
2535
		/* Members */
-
 
2536
		OFFSET off = DEREF_off(id_member_off(id));
-
 
2537
		if (IS_off_token(off)) {
-
 
2538
			id = DEREF_id(off_token_tok(off));
-
 
2539
			return (id);
2425
		}
2540
		}
2426
	    }
-
 
2427
	    break ;
2541
		break;
2428
	}
2542
	}
2429
	case id_type_alias_tag : {
2543
	case id_token_tag: {
2430
	    /* Types */
2544
		/* Tokens */
2431
	    TYPE t = DEREF_type ( id_type_alias_defn ( id ) ) ;
2545
		IDENTIFIER alt = DEREF_id(id_token_alt(id));
2432
	    if ( IS_type_token ( t ) ) {
2546
		if (IS_id_token(alt)) {
2433
		id = DEREF_id ( type_token_tok ( t ) ) ;
-
 
2434
		return ( id ) ;
2547
			return (alt);
2435
	    }
-
 
2436
	    break ;
-
 
2437
	}
-
 
2438
	case id_function_tag :
-
 
2439
	case id_mem_func_tag :
-
 
2440
	case id_stat_mem_func_tag : {
-
 
2441
	    /* Functions */
-
 
2442
	    TYPE form = DEREF_type ( id_function_etc_form ( id ) ) ;
-
 
2443
	    if ( !IS_NULL_type ( form ) && IS_type_token ( form ) ) {
-
 
2444
		IDENTIFIER ext = DEREF_id ( type_token_tok ( form ) ) ;
-
 
2445
		if ( !IS_NULL_id ( ext ) ) return ( ext ) ;
-
 
2446
	    }
-
 
2447
	    return ( id ) ;
-
 
2448
	}
2548
		}
2449
	case id_member_tag : {
-
 
2450
	    /* Members */
-
 
2451
	    OFFSET off = DEREF_off ( id_member_off ( id ) ) ;
-
 
2452
	    if ( IS_off_token ( off ) ) {
-
 
2453
		id = DEREF_id ( off_token_tok ( off ) ) ;
-
 
2454
		return ( id ) ;
2549
		return (id);
2455
	    }
-
 
2456
	    break ;
-
 
2457
	}
2550
	}
2458
	case id_token_tag : {
-
 
2459
	    /* Tokens */
-
 
2460
	    IDENTIFIER alt = DEREF_id ( id_token_alt ( id ) ) ;
-
 
2461
	    if ( IS_id_token ( alt ) ) return ( alt ) ;
-
 
2462
	    return ( id ) ;
-
 
2463
	}
2551
	}
2464
    }
-
 
2465
    return ( id ) ;
2552
	return (id);
2466
}
2553
}
2467
 
2554
 
2468
 
2555
 
2469
/*
2556
/*
2470
    FIND AN EXTERNAL TOKEN IDENTIFIER
2557
    FIND AN EXTERNAL TOKEN IDENTIFIER
2471
 
2558
 
2472
    This routine finds the external token corresponding to the identifier id.
2559
    This routine finds the external token corresponding to the identifier id.
2473
    For functions this refers only to the function id itself and not to
2560
    For functions this refers only to the function id itself and not to
2474
    any overloading functions.
2561
    any overloading functions.
2475
*/
2562
*/
2476
 
2563
 
2477
IDENTIFIER find_token
2564
IDENTIFIER
2478
    PROTO_N ( ( id ) )
-
 
2479
    PROTO_T ( IDENTIFIER id )
2565
find_token(IDENTIFIER id)
2480
{
2566
{
2481
    MEMBER mem ;
2567
	MEMBER mem;
2482
    DECL_SPEC ds ;
2568
	DECL_SPEC ds;
2483
    IDENTIFIER tid ;
2569
	IDENTIFIER tid;
2484
    HASHID nm = DEREF_hashid ( id_name ( id ) ) ;
2570
	HASHID nm = DEREF_hashid(id_name(id));
2485
    if ( IS_id_keyword_etc ( id ) ) {
2571
	if (IS_id_keyword_etc(id)) {
2486
	/* Rescan keywords */
2572
		/* Rescan keywords */
2487
	id = find_id ( nm ) ;
2573
		id = find_id(nm);
2488
    }
2574
	}
2489
    ds = DEREF_dspec ( id_storage ( id ) ) ;
2575
	ds = DEREF_dspec(id_storage(id));
2490
    if ( ds & dspec_token ) {
2576
	if (ds & dspec_token) {
2491
	/* Deal with simple tokens */
2577
		/* Deal with simple tokens */
2492
	tid = find_token_aux ( id ) ;
2578
		tid = find_token_aux(id);
2493
	if ( IS_id_token ( tid ) ) {
2579
		if (IS_id_token(tid)) {
2494
	    ds = DEREF_dspec ( id_storage ( tid ) ) ;
2580
			ds = DEREF_dspec(id_storage(tid));
2495
	    if ( !( ds & dspec_auto ) ) return ( tid ) ;
2581
			if (!(ds & dspec_auto)) {
-
 
2582
				return (tid);
-
 
2583
			}
-
 
2584
		}
2496
	}
2585
	}
2497
    }
-
 
2498
 
2586
 
2499
    /* Complex cases - check through token namespace */
2587
	/* Complex cases - check through token namespace */
2500
    id = DEREF_id ( id_alias ( id ) ) ;
2588
	id = DEREF_id(id_alias(id));
2501
    mem = DEREF_member ( nspace_global_first ( token_namespace ) ) ;
2589
	mem = DEREF_member(nspace_global_first(token_namespace));
2502
    while ( !IS_NULL_member ( mem ) ) {
2590
	while (!IS_NULL_member(mem)) {
2503
	tid = DEREF_id ( member_alt ( mem ) ) ;
2591
		tid = DEREF_id(member_alt(mem));
2504
	if ( EQ_id ( tid, id ) ) {
2592
		if (EQ_id(tid, id)) {
2505
	    tid = DEREF_id ( member_id ( mem ) ) ;
2593
			tid = DEREF_id(member_id(mem));
2506
	    return ( tid ) ;
2594
			return (tid);
-
 
2595
		}
-
 
2596
		mem = DEREF_member(member_next(mem));
2507
	}
2597
	}
2508
	mem = DEREF_member ( member_next ( mem ) ) ;
-
 
2509
    }
-
 
2510
    return ( id ) ;
2598
	return (id);
2511
}
2599
}
2512
 
2600
 
2513
 
2601
 
2514
/*
2602
/*
2515
    FIND A TAG TOKEN IDENTIFIER
2603
    FIND A TAG TOKEN IDENTIFIER
2516
 
2604
 
2517
    This routine finds the token corresponding to the tag identifier id.
2605
    This routine finds the token corresponding to the tag identifier id.
2518
*/
2606
*/
2519
 
2607
 
2520
IDENTIFIER find_tag_token
2608
IDENTIFIER
-
 
2609
find_tag_token(IDENTIFIER id)
-
 
2610
{
-
 
2611
	id = find_elaborate_type(id, btype_any, NULL_type, dspec_used);
2521
    PROTO_N ( ( id ) )
2612
	return (id);
-
 
2613
}
-
 
2614
 
-
 
2615
 
-
 
2616
/*
2522
    PROTO_T ( IDENTIFIER id )
2617
    FIND A MEMBER TOKEN IDENTIFIER
-
 
2618
 
-
 
2619
    This routine finds the token corresponding to the member mid of cid.
-
 
2620
*/
-
 
2621
 
-
 
2622
IDENTIFIER
-
 
2623
find_mem_token(IDENTIFIER cid, IDENTIFIER mid)
2523
{
2624
{
-
 
2625
	if (IS_id_class_name_etc(cid)) {
2524
    id = find_elaborate_type ( id, btype_any, NULL_type, dspec_used ) ;
2626
		TYPE t = DEREF_type(id_class_name_etc_defn(cid));
-
 
2627
		IDENTIFIER fid = tok_member(mid, t, 1);
-
 
2628
		if (!IS_NULL_id(fid)) {
2525
    return ( id ) ;
2629
			return (fid);
-
 
2630
		}
-
 
2631
		return (mid);
-
 
2632
	}
-
 
2633
	report(preproc_loc, ERR_dcl_type_simple_undef(cid));
-
 
2634
	return (mid);
2526
}
2635
}
2527
 
2636
 
2528
 
2637
 
2529
/*
2638
/*
2530
    FIND A MEMBER TOKEN IDENTIFIER
2639
    FIND AN EXTERNAL TOKEN IDENTIFIER
2531
 
2640
 
2532
    This routine finds the token corresponding to the member mid of cid.
2641
    This routine finds the token with external name given by id.
2533
*/
2642
*/
2534
 
2643
 
2535
IDENTIFIER find_mem_token
2644
IDENTIFIER
2536
    PROTO_N ( ( cid, mid ) )
-
 
2537
    PROTO_T ( IDENTIFIER cid X IDENTIFIER mid )
2645
find_ext_token(IDENTIFIER id)
2538
{
2646
{
2539
    if ( IS_id_class_name_etc ( cid ) ) {
-
 
2540
	TYPE t = DEREF_type ( id_class_name_etc_defn ( cid ) ) ;
2647
	HASHID nm = DEREF_hashid(id_name(id));
2541
	IDENTIFIER fid = tok_member ( mid, t, 1 ) ;
2648
	id = search_id(token_namespace, nm, 0, 0);
2542
	if ( !IS_NULL_id ( fid ) ) return ( fid ) ;
2649
	if (IS_NULL_id(id)) {
2543
	return ( mid ) ;
2650
		id = DEREF_id(hashid_id(nm));
2544
    }
2651
	}
2545
    report ( preproc_loc, ERR_dcl_type_simple_undef ( cid ) ) ;
-
 
2546
    return ( mid ) ;
2652
	return (id);
2547
}
2653
}
2548
 
2654
 
2549
 
2655
 
2550
/*
2656
/*
2551
    FIND AN EXTERNAL TOKEN IDENTIFIER
-
 
2552
 
-
 
2553
    This routine finds the token with external name given by id.
-
 
2554
*/
-
 
2555
 
-
 
2556
IDENTIFIER find_ext_token
-
 
2557
    PROTO_N ( ( id ) )
-
 
2558
    PROTO_T ( IDENTIFIER id )
-
 
2559
{
-
 
2560
    HASHID nm = DEREF_hashid ( id_name ( id ) ) ;
-
 
2561
    id = search_id ( token_namespace, nm, 0, 0 ) ;
-
 
2562
    if ( IS_NULL_id ( id ) ) id = DEREF_id ( hashid_id ( nm ) ) ;
-
 
2563
    return ( id ) ;
-
 
2564
}
-
 
2565
 
-
 
2566
 
-
 
2567
/*
-
 
2568
    FIND A FUNCTION TOKEN IDENTIFIER
2657
    FIND A FUNCTION TOKEN IDENTIFIER
2569
 
2658
 
2570
    This routine is identical to find_token except that it does a primitive
2659
    This routine is identical to find_token except that it does a primitive
2571
    form of overload resolution on function tokens based on the number of
2660
    form of overload resolution on function tokens based on the number of
2572
    arguments n.  A value of UINT_MAX indicates that any number of
2661
    arguments n.  A value of UINT_MAX indicates that any number of
2573
    parameters is allowed.
2662
    parameters is allowed.
2574
*/
2663
*/
2575
 
2664
 
2576
IDENTIFIER find_func_token
2665
IDENTIFIER
2577
    PROTO_N ( ( id, n ) )
-
 
2578
    PROTO_T ( IDENTIFIER id X unsigned n )
2666
find_func_token(IDENTIFIER id, unsigned n)
2579
{
2667
{
2580
    if ( IS_id_function_etc ( id ) ) {
2668
    if (IS_id_function_etc(id)) {
2581
	int no = 0 ;
2669
	int no = 0;
2582
	IDENTIFIER tid = NULL_id ;
2670
	IDENTIFIER tid = NULL_id;
2583
	IDENTIFIER fid = id ;
2671
	IDENTIFIER fid = id;
2584
	while ( !IS_NULL_id ( fid ) ) {
2672
	while (!IS_NULL_id(fid)) {
2585
	    TYPE form = DEREF_type ( id_function_etc_form ( fid ) ) ;
2673
	    TYPE form = DEREF_type(id_function_etc_form(fid));
2586
	    if ( !IS_NULL_type ( form ) && IS_type_token ( form ) ) {
2674
	    if (!IS_NULL_type(form) && IS_type_token(form)) {
2587
		IDENTIFIER ext = DEREF_id ( type_token_tok ( form ) ) ;
2675
		IDENTIFIER ext = DEREF_id(type_token_tok(form));
2588
		if ( !IS_NULL_id ( ext ) && IS_id_token ( ext ) ) {
2676
		if (!IS_NULL_id(ext) && IS_id_token(ext)) {
2589
		    if ( n == ( unsigned ) UINT_MAX ) {
2677
		    if (n == (unsigned)UINT_MAX) {
2590
			tid = ext ;
2678
			tid = ext;
2591
			no++ ;
2679
			no++;
2592
		    } else {
2680
		    } else {
2593
			TYPE t ;
2681
			TYPE t;
2594
			int ell ;
2682
			int ell;
2595
			LIST ( TYPE ) p ;
2683
			LIST(TYPE)p;
2596
			t = DEREF_type ( id_function_etc_type ( fid ) ) ;
2684
			t = DEREF_type(id_function_etc_type(fid));
2597
			while ( IS_type_templ ( t ) ) {
2685
			while (IS_type_templ(t)) {
2598
			    t = DEREF_type ( type_templ_defn ( t ) ) ;
2686
			    t = DEREF_type(type_templ_defn(t));
2599
			}
2687
			}
2600
			p = DEREF_list ( type_func_ptypes ( t ) ) ;
2688
			p = DEREF_list(type_func_ptypes(t));
2601
			ell = DEREF_int ( type_func_ellipsis ( t ) ) ;
2689
			ell = DEREF_int(type_func_ellipsis(t));
2602
			if ( LENGTH_list ( p ) == n ) {
2690
			if (LENGTH_list(p) == n) {
2603
			    if ( !( ell & FUNC_ELLIPSIS ) ) {
2691
			    if (!(ell & FUNC_ELLIPSIS)) {
2604
				tid = ext ;
2692
				tid = ext;
2605
				no++ ;
2693
				no++;
2606
			    }
2694
			    }
2607
			}
2695
			}
2608
		    }
2696
		    }
2609
		}
2697
		}
2610
	    }
2698
	    }
2611
	    fid = DEREF_id ( id_function_etc_over ( fid ) ) ;
2699
	    fid = DEREF_id(id_function_etc_over(fid));
-
 
2700
	}
-
 
2701
	if (no > 1) {
-
 
2702
		report(preproc_loc, ERR_token_def_ambig(id));
2612
	}
2703
	}
2613
	if ( no > 1 ) report ( preproc_loc, ERR_token_def_ambig ( id ) ) ;
-
 
2614
	return ( tid ) ;
2704
	return (tid);
2615
    }
2705
    }
2616
    return ( find_token ( id ) ) ;
2706
    return (find_token(id));
2617
}
2707
}
2618
 
2708
 
2619
 
2709
 
2620
/*
2710
/*
2621
    CURRENT INTERFACE METHOD
2711
    CURRENT INTERFACE METHOD
2622
 
2712
 
2623
    This flag is used to record the current interface method.  It gives the
2713
    This flag is used to record the current interface method.  It gives the
2624
    mapping of any '#pragma interface' to one of '#pragma define', '#pragma
2714
    mapping of any '#pragma interface' to one of '#pragma define', '#pragma
2625
    no_def' or '#pragma ignore'.
2715
    no_def' or '#pragma ignore'.
2626
*/
2716
*/
2627
 
2717
 
2628
int crt_interface = lex_no_Hdef ;
2718
int crt_interface = lex_no_Hdef;
2629
 
2719
 
2630
 
2720
 
2631
/*
2721
/*
2632
    PERFORM A TOKEN INTERFACE OPERATION
2722
    PERFORM A TOKEN INTERFACE OPERATION
2633
 
2723
 
2634
    This routine performs the token interface operation indicated by i
2724
    This routine performs the token interface operation indicated by i
2635
    (which will be lex_define, lex_no_Hdef, lex_ignore) on the token tid.
2725
    (which will be lex_define, lex_no_Hdef, lex_ignore) on the token tid.
2636
*/
2726
*/
2637
 
2727
 
2638
static void mark_interface
2728
static void
2639
    PROTO_N ( ( tid, i ) )
-
 
2640
    PROTO_T ( IDENTIFIER tid X int i )
2729
mark_interface(IDENTIFIER tid, int i)
2641
{
2730
{
2642
    DECL_SPEC ds = DEREF_dspec ( id_storage ( tid ) ) ;
2731
	DECL_SPEC ds = DEREF_dspec(id_storage(tid));
2643
    if ( i == lex_define ) {
2732
	if (i == lex_define) {
2644
	/* Token must be defined */
2733
		/* Token must be defined */
2645
	ds |= dspec_static ;
2734
		ds |= dspec_static;
2646
	ds &= ~dspec_pure ;
2735
		ds &= ~dspec_pure;
2647
    } else if ( i == lex_no_Hdef ) {
2736
	} else if (i == lex_no_Hdef) {
2648
	/* Token must not be defined */
2737
		/* Token must not be defined */
2649
	ds |= dspec_pure ;
2738
		ds |= dspec_pure;
2650
	if ( ds & dspec_defn ) {
2739
		if (ds & dspec_defn) {
2651
	    /* Token already defined */
2740
			/* Token already defined */
2652
	    PTR ( LOCATION ) loc = id_loc ( tid ) ;
2741
			PTR(LOCATION)loc = id_loc(tid);
2653
	    report ( preproc_loc, ERR_token_no_def ( tid, loc ) ) ;
2742
			report(preproc_loc, ERR_token_no_def(tid, loc));
2654
	}
2743
		}
2655
    } else {
2744
	} else {
2656
	/* Ignore token definitions */
2745
		/* Ignore token definitions */
2657
	ds |= dspec_done ;
2746
		ds |= dspec_done;
2658
	ds &= ~dspec_pure ;
2747
		ds &= ~dspec_pure;
2659
    }
2748
	}
2660
    COPY_dspec ( id_storage ( tid ), ds ) ;
2749
	COPY_dspec(id_storage(tid), ds);
2661
    return ;
2750
	return;
2662
}
2751
}
2663
 
2752
 
2664
 
2753
 
2665
/*
2754
/*
2666
    PERFORM A TOKEN INTERFACE OPERATION
2755
    PERFORM A TOKEN INTERFACE OPERATION
2667
 
2756
 
2668
    This routine looks up the token id and performs the token operation
2757
    This routine looks up the token id and performs the token operation
2669
    i on it.  In addition to the values above i can be lex_undef indicating
2758
    i on it.  In addition to the values above i can be lex_undef indicating
2670
    that the token should be undefined.
2759
    that the token should be undefined.
2671
*/
2760
*/
2672
 
2761
 
2673
void token_interface
2762
void
2674
    PROTO_N ( ( id, i ) )
-
 
2675
    PROTO_T ( IDENTIFIER id X int i )
2763
token_interface(IDENTIFIER id, int i)
2676
{
2764
{
2677
    int ok = 0 ;
2765
	int ok = 0;
2678
    IDENTIFIER pid = id ;
2766
	IDENTIFIER pid = id;
2679
    while ( !IS_NULL_id ( pid ) ) {
2767
	while (!IS_NULL_id(pid)) {
2680
	IDENTIFIER tid = find_token ( pid ) ;
2768
		IDENTIFIER tid = find_token(pid);
2681
	if ( IS_id_token ( tid ) ) {
2769
		if (IS_id_token(tid)) {
2682
	    /* Token found */
2770
			/* Token found */
2683
	    if ( i == lex_undef ) {
2771
			if (i == lex_undef) {
-
 
2772
				if (do_dump) {
2684
		if ( do_dump ) dump_undefine ( pid, &preproc_loc, 1 ) ;
2773
					dump_undefine(pid, &preproc_loc, 1);
-
 
2774
				}
2685
		remove_id ( pid ) ;
2775
				remove_id(pid);
2686
	    } else {
2776
			} else {
2687
		mark_interface ( tid, i ) ;
2777
				mark_interface(tid, i);
2688
	    }
2778
			}
2689
	    ok = 1 ;
2779
			ok = 1;
-
 
2780
		}
-
 
2781
		if (!IS_id_function_etc(pid)) {
-
 
2782
			break;
-
 
2783
		}
-
 
2784
		pid = DEREF_id(id_function_etc_over(pid));
2690
	}
2785
	}
2691
	if ( !IS_id_function_etc ( pid ) ) break ;
-
 
2692
	pid = DEREF_id ( id_function_etc_over ( pid ) ) ;
-
 
2693
    }
-
 
2694
    if ( !ok ) {
2786
	if (!ok) {
2695
	/* Token not found */
2787
		/* Token not found */
2696
	report ( preproc_loc, ERR_token_undecl ( id ) ) ;
2788
		report(preproc_loc, ERR_token_undecl(id));
2697
    }
2789
	}
2698
    return ;
2790
	return;
2699
}
2791
}