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

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

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

Subversion Repositories tendra.SVN

Rev

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

Rev 2 Rev 7
Line -... Line 1...
-
 
1
/*
-
 
2
 * Copyright (c) 2002-2006 The TenDRA Project <http://www.tendra.org/>.
-
 
3
 * All rights reserved.
-
 
4
 *
-
 
5
 * Redistribution and use in source and binary forms, with or without
-
 
6
 * modification, are permitted provided that the following conditions are met:
-
 
7
 *
-
 
8
 * 1. Redistributions of source code must retain the above copyright notice,
-
 
9
 *    this list of conditions and the following disclaimer.
-
 
10
 * 2. Redistributions in binary form must reproduce the above copyright notice,
-
 
11
 *    this list of conditions and the following disclaimer in the documentation
-
 
12
 *    and/or other materials provided with the distribution.
-
 
13
 * 3. Neither the name of The TenDRA Project nor the names of its contributors
-
 
14
 *    may be used to endorse or promote products derived from this software
-
 
15
 *    without specific, prior written permission.
-
 
16
 *
-
 
17
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS
-
 
18
 * IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
-
 
19
 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
-
 
20
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR
-
 
21
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
-
 
22
 * EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
-
 
23
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
-
 
24
 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-
 
25
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
-
 
26
 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
-
 
27
 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
 
28
 *
-
 
29
 * $Id$
-
 
30
 */
1
/*
31
/*
2
    		 Crown Copyright (c) 1997, 1998
32
    		 Crown Copyright (c) 1997, 1998
3
    
33
 
4
    This TenDRA(r) Computer Program is subject to Copyright
34
    This TenDRA(r) Computer Program is subject to Copyright
5
    owned by the United Kingdom Secretary of State for Defence
35
    owned by the United Kingdom Secretary of State for Defence
6
    acting through the Defence Evaluation and Research Agency
36
    acting through the Defence Evaluation and Research Agency
7
    (DERA).  It is made available to Recipients with a
37
    (DERA).  It is made available to Recipients with a
8
    royalty-free licence for its use, reproduction, transfer
38
    royalty-free licence for its use, reproduction, transfer
9
    to other parties and amendment for any purpose not excluding
39
    to other parties and amendment for any purpose not excluding
10
    product development provided that any such use et cetera
40
    product development provided that any such use et cetera
11
    shall be deemed to be acceptance of the following conditions:-
41
    shall be deemed to be acceptance of the following conditions:-
12
    
42
 
13
        (1) Its Recipients shall ensure that this Notice is
43
        (1) Its Recipients shall ensure that this Notice is
14
        reproduced upon any copies or amended versions of it;
44
        reproduced upon any copies or amended versions of it;
15
    
45
 
16
        (2) Any amended version of it shall be clearly marked to
46
        (2) Any amended version of it shall be clearly marked to
17
        show both the nature of and the organisation responsible
47
        show both the nature of and the organisation responsible
18
        for the relevant amendment or amendments;
48
        for the relevant amendment or amendments;
19
    
49
 
20
        (3) Its onward transfer from a recipient to another
50
        (3) Its onward transfer from a recipient to another
21
        party shall be deemed to be that party's acceptance of
51
        party shall be deemed to be that party's acceptance of
22
        these conditions;
52
        these conditions;
23
    
53
 
24
        (4) DERA gives no warranty or assurance as to its
54
        (4) DERA gives no warranty or assurance as to its
25
        quality or suitability for any purpose and DERA accepts
55
        quality or suitability for any purpose and DERA accepts
26
        no liability whatsoever in relation to any use to which
56
        no liability whatsoever in relation to any use to which
27
        it may be put.
57
        it may be put.
28
*/
58
*/
Line 91... Line 121...
91
    that statement.  The flag unreached_fall is set to false immediately
121
    that statement.  The flag unreached_fall is set to false immediately
92
    following a 'case' or 'default' label, but set to true after a non-
122
    following a 'case' or 'default' label, but set to true after a non-
93
    trivial statement (this is included in the grammar).
123
    trivial statement (this is included in the grammar).
94
*/
124
*/
95
 
125
 
96
int unreached_code = 0 ;
126
int unreached_code = 0;
97
int unreached_last = 0 ;
127
int unreached_last = 0;
98
int unreached_prev = 0 ;
128
int unreached_prev = 0;
99
int unreached_fall = 0 ;
129
int unreached_fall = 0;
100
int suppress_fall = 0 ;
130
int suppress_fall = 0;
101
 
131
 
102
 
132
 
103
/*
133
/*
104
    DOES AN EXPRESSION NOT RETURN?
134
    DOES AN EXPRESSION NOT RETURN?
105
 
135
 
106
    This routine tests whether the expression e has type bottom, i.e. does
136
    This routine tests whether the expression e has type bottom, i.e. does
107
    not return a value.
137
    not return a value.
108
*/
138
*/
109
 
139
 
110
static int is_bottom
140
static int
111
    PROTO_N ( ( e ) )
-
 
112
    PROTO_T ( EXP e )
141
is_bottom(EXP e)
113
{
142
{
114
    TYPE t ;
143
	TYPE t;
115
    if ( IS_NULL_exp ( e ) ) return ( 0 ) ;
144
	if (IS_NULL_exp(e)) {
-
 
145
		return (0);
-
 
146
	}
116
    t = DEREF_type ( exp_type ( e ) ) ;
147
	t = DEREF_type(exp_type(e));
117
    return ( IS_type_bottom ( t ) ) ;
148
	return (IS_type_bottom(t));
118
}
149
}
119
 
150
 
120
 
151
 
121
/*
152
/*
122
    FIND THE PARENT OF A STATEMENT
153
    FIND THE PARENT OF A STATEMENT
123
 
154
 
124
    This routine returns a pointer to the parent of the statement e.  It
155
    This routine returns a pointer to the parent of the statement e.  It
125
    returns the null pointer if e is a simple expression.
156
    returns the null pointer if e is a simple expression.
126
*/
157
*/
127
 
158
 
128
static PTR ( EXP ) parent_stmt
159
static PTR(EXP)
129
    PROTO_N ( ( e ) )
-
 
130
    PROTO_T ( EXP e )
160
parent_stmt(EXP e)
131
{
161
{
132
    PTR ( EXP ) ptr = NULL_ptr ( EXP ) ;
162
	PTR(EXP) ptr = NULL_ptr(EXP);
133
    if ( !IS_NULL_exp ( e ) ) {
163
	if (!IS_NULL_exp(e)) {
134
	switch ( TAG_exp ( e ) ) {
164
		switch (TAG_exp(e)) {
135
	    case exp_reach_tag : {
165
		case exp_reach_tag:
136
		ptr = exp_reach_parent ( e ) ;
166
			ptr = exp_reach_parent(e);
137
		break ;
167
			break;
138
	    }
-
 
139
	    case exp_unreach_tag : {
168
		case exp_unreach_tag:
140
		ptr = exp_unreach_parent ( e ) ;
169
			ptr = exp_unreach_parent(e);
141
		break ;
170
			break;
142
	    }
-
 
143
	    case exp_sequence_tag : {
171
		case exp_sequence_tag:
144
		ptr = exp_sequence_parent ( e ) ;
172
			ptr = exp_sequence_parent(e);
145
		break ;
173
			break;
146
	    }
-
 
147
	    case exp_solve_stmt_tag : {
174
		case exp_solve_stmt_tag:
148
		ptr = exp_solve_stmt_parent ( e ) ;
175
			ptr = exp_solve_stmt_parent(e);
149
		break ;
176
			break;
150
	    }
-
 
151
	    case exp_decl_stmt_tag : {
177
		case exp_decl_stmt_tag:
152
		ptr = exp_decl_stmt_parent ( e ) ;
178
			ptr = exp_decl_stmt_parent(e);
153
		break ;
179
			break;
154
	    }
-
 
155
	    case exp_if_stmt_tag : {
180
		case exp_if_stmt_tag:
156
		ptr = exp_if_stmt_parent ( e ) ;
181
			ptr = exp_if_stmt_parent(e);
157
		break ;
182
			break;
158
	    }
-
 
159
	    case exp_while_stmt_tag : {
183
		case exp_while_stmt_tag:
160
		ptr = exp_while_stmt_parent ( e ) ;
184
			ptr = exp_while_stmt_parent(e);
161
		break ;
185
			break;
162
	    }
-
 
163
	    case exp_do_stmt_tag : {
186
		case exp_do_stmt_tag:
164
		ptr = exp_do_stmt_parent ( e ) ;
187
			ptr = exp_do_stmt_parent(e);
165
		break ;
188
			break;
166
	    }
-
 
167
	    case exp_switch_stmt_tag : {
189
		case exp_switch_stmt_tag:
168
		ptr = exp_switch_stmt_parent ( e ) ;
190
			ptr = exp_switch_stmt_parent(e);
169
		break ;
191
			break;
170
	    }
-
 
171
	    case exp_hash_if_tag : {
192
		case exp_hash_if_tag:
172
		ptr = exp_hash_if_parent ( e ) ;
193
			ptr = exp_hash_if_parent(e);
173
		break ;
194
			break;
174
	    }
-
 
175
	    case exp_return_stmt_tag : {
195
		case exp_return_stmt_tag:
176
		ptr = exp_return_stmt_parent ( e ) ;
196
			ptr = exp_return_stmt_parent(e);
177
		break ;
197
			break;
178
	    }
-
 
179
	    case exp_goto_stmt_tag : {
198
		case exp_goto_stmt_tag:
180
		ptr = exp_goto_stmt_parent ( e ) ;
199
			ptr = exp_goto_stmt_parent(e);
181
		break ;
200
			break;
182
	    }
-
 
183
	    case exp_label_stmt_tag : {
201
		case exp_label_stmt_tag:
184
		ptr = exp_label_stmt_parent ( e ) ;
202
			ptr = exp_label_stmt_parent(e);
185
		break ;
203
			break;
186
	    }
-
 
187
	    case exp_try_block_tag : {
204
		case exp_try_block_tag:
188
		ptr = exp_try_block_parent ( e ) ;
205
			ptr = exp_try_block_parent(e);
189
		break ;
206
			break;
190
	    }
-
 
191
	    case exp_handler_tag : {
207
		case exp_handler_tag:
192
		ptr = exp_handler_parent ( e ) ;
208
			ptr = exp_handler_parent(e);
193
		break ;
209
			break;
194
	    }
-
 
195
	    case exp_token_tag : {
210
		case exp_token_tag:
196
		ptr = exp_token_parent ( e ) ;
211
			ptr = exp_token_parent(e);
197
		break ;
212
			break;
198
	    }
-
 
199
	    case exp_location_tag : {
213
		case exp_location_tag: {
200
		EXP a = DEREF_exp ( exp_location_arg ( e ) ) ;
214
			EXP a = DEREF_exp(exp_location_arg(e));
201
		ptr = parent_stmt ( a ) ;
215
			ptr = parent_stmt(a);
202
		break ;
216
			break;
203
	    }
217
		}
204
	    case exp_paren_tag : {
218
		case exp_paren_tag: {
205
		EXP a = DEREF_exp ( exp_paren_arg ( e ) ) ;
219
			EXP a = DEREF_exp(exp_paren_arg(e));
206
		ptr = parent_stmt ( a ) ;
220
			ptr = parent_stmt(a);
207
		break ;
221
			break;
-
 
222
		}
208
	    }
223
		}
209
	}
224
	}
210
    }
-
 
211
    return ( ptr ) ;
225
	return (ptr);
212
}
226
}
213
 
227
 
214
 
228
 
215
/*
229
/*
216
    GET THE PARENT OF A STATEMENT
230
    GET THE PARENT OF A STATEMENT
217
 
231
 
218
    This routine returns the parent statement of e.
232
    This routine returns the parent statement of e.
219
*/
233
*/
220
 
234
 
221
EXP get_parent_stmt
235
EXP
222
    PROTO_N ( ( e ) )
-
 
223
    PROTO_T ( EXP e )
236
get_parent_stmt(EXP e)
224
{
237
{
225
    EXP p = NULL_exp ;
238
	EXP p = NULL_exp;
226
    if ( !IS_NULL_exp ( e ) ) {
239
	if (!IS_NULL_exp(e)) {
227
	PTR ( EXP ) ptr = parent_stmt ( e ) ;
240
		PTR(EXP)ptr = parent_stmt(e);
228
	if ( !IS_NULL_ptr ( ptr ) ) p = DEREF_exp ( ptr ) ;
241
		if (!IS_NULL_ptr(ptr)) {
-
 
242
			p = DEREF_exp(ptr);
229
    }
243
		}
-
 
244
	}
230
    return ( p ) ;
245
	return (p);
231
}
246
}
232
 
247
 
233
 
248
 
234
/*
249
/*
235
    SET THE PARENT OF A STATEMENT
250
    SET THE PARENT OF A STATEMENT
236
 
251
 
237
    This routine sets the parent of the statement e to be p.
252
    This routine sets the parent of the statement e to be p.
238
*/
253
*/
239
 
254
 
240
void set_parent_stmt
255
void
241
    PROTO_N ( ( e, p ) )
-
 
242
    PROTO_T ( EXP e X EXP p )
256
set_parent_stmt(EXP e, EXP p)
243
{
257
{
244
    if ( !IS_NULL_exp ( e ) ) {
258
	if (!IS_NULL_exp(e)) {
245
	PTR ( EXP ) ptr = parent_stmt ( e ) ;
259
		PTR(EXP)ptr = parent_stmt(e);
246
	if ( !IS_NULL_ptr ( ptr ) ) COPY_exp ( ptr, p ) ;
260
		if (!IS_NULL_ptr(ptr)) {
-
 
261
			COPY_exp(ptr, p);
247
    }
262
		}
-
 
263
	}
248
    return ;
264
	return;
249
}
265
}
250
 
266
 
251
 
267
 
252
/*
268
/*
253
    STATEMENT LOCATION FLAG
269
    STATEMENT LOCATION FLAG
254
 
270
 
255
    The flag record_location may be set to true to force extra expressions
271
    The flag record_location may be set to true to force extra expressions
256
    giving the location of each statement to be inserted into the output.
272
    giving the location of each statement to be inserted into the output.
257
    The variable stmt_loc records the last such location.
273
    The variable stmt_loc records the last such location.
258
*/
274
*/
259
 
275
 
260
int record_location = 0 ;
276
int record_location = 0;
261
LOCATION stmt_loc = NULL_loc ;
277
LOCATION stmt_loc = NULL_loc;
262
static int adjusted_line = 0 ;
278
static int adjusted_line = 0;
263
 
279
 
264
 
280
 
265
/*
281
/*
266
    ADJUST COLUMN NUMBER
282
    ADJUST COLUMN NUMBER
267
 
283
 
268
    This routine sets stmt_loc to point to the start of the preprocessing
284
    This routine sets stmt_loc to point to the start of the preprocessing
269
    token p.
285
    token p.
270
*/
286
*/
271
 
287
 
272
static void adjust_column
288
static void
273
    PROTO_N ( ( p ) )
-
 
274
    PROTO_T ( PPTOKEN *p )
289
adjust_column(PPTOKEN *p)
275
{
-
 
276
    if ( p ) {
-
 
277
	int t = p->tok ;
-
 
278
	if ( t >= FIRST_SYMBOL && t <= LAST_SYMBOL ) {
-
 
279
	    /* Adjust to start of symbol */
-
 
280
	    ulong len = ( ulong ) ustrlen ( token_name ( t ) ) ;
-
 
281
	    stmt_loc = crt_loc ;
-
 
282
	    stmt_loc.column -= ( len - 1 ) ;
-
 
283
	    return ;
-
 
284
	}
-
 
285
	if ( t >= FIRST_KEYWORD && t <= LAST_KEYWORD ) {
-
 
286
	    /* Map keywords to underlying identifier */
-
 
287
	    t = lex_identifier ;
-
 
288
	}
-
 
289
	if ( t == lex_identifier ) {
-
 
290
	    IDENTIFIER id = p->pp_data.id.use ;
-
 
291
	    id = underlying_id ( id ) ;
-
 
292
	    DEREF_loc ( id_loc ( id ), stmt_loc ) ;
-
 
293
	    return ;
-
 
294
	}
-
 
295
    }
-
 
296
    stmt_loc = crt_loc ;
-
 
297
    return ;
-
 
298
}
-
 
299
 
-
 
300
 
-
 
301
/*
-
 
302
    ADJUST LINE NUMBER
-
 
303
 
-
 
304
    This routine is called whenever the location of a statement is
-
 
305
    recorded.  It is intended to ensure that the current location points
-
 
306
    to the start of the next statement rather than the end of the current
-
 
307
    statement.
-
 
308
*/
-
 
309
 
-
 
310
static void adjust_line
-
 
311
    PROTO_N ( ( next ) )
-
 
312
    PROTO_T ( int next )
-
 
313
{
290
{
314
    if ( !adjusted_line ) {
-
 
315
	adjusted_line = 1 ;
-
 
316
	if ( next ) {
291
	if (p) {
317
	    switch ( crt_lex_token ) {
-
 
318
		case lex_open_Hbrace_H1 :
-
 
319
		case lex_colon :
292
		int t = p->tok;
320
		case lex_semicolon :
-
 
321
		case lex_close_Hround :
-
 
322
		case lex_else :
-
 
323
		case lex_exhaustive : {
-
 
324
		    /* Scan to next token */
-
 
325
		    PPTOKEN *p = crt_token->next ;
293
		if (t >= FIRST_SYMBOL && t <= LAST_SYMBOL) {
326
		    if ( p ) {
-
 
327
			/* Set location from next token */
294
			/* Adjust to start of symbol */
328
			p = read_loc_tokens ( p ) ;
295
			ulong len = (ulong)ustrlen(token_name(t));
329
			if ( crt_state_depth == 0 ) {
296
			stmt_loc = crt_loc;
330
			    adjust_column ( p ) ;
297
			stmt_loc.column -= (len - 1);
331
			    return ;
298
			return;
332
			}
299
		}
333
		    } else {
-
 
334
			if ( crt_state_depth == 0 ) {
300
		if (t >= FIRST_KEYWORD && t <= LAST_KEYWORD) {
335
			    /* Skip white space from input file */
301
			/* Map keywords to underlying identifier */
336
			    unsigned long sp = skip_white ( 1 ) ;
-
 
337
			    update_column () ;
-
 
338
			    stmt_loc = crt_loc ;
-
 
339
			    stmt_loc.column++ ;
-
 
340
			    if ( sp ) patch_white ( sp ) ;
-
 
341
			    return ;
302
			t = lex_identifier;
342
			}
-
 
343
		    }
-
 
344
		    break ;
-
 
345
		}
303
		}
346
		default : {
304
		if (t == lex_identifier) {
347
		    /* Use current token */
305
			IDENTIFIER id = p->pp_data.id.use;
348
		    if ( crt_state_depth == 0 ) {
306
			id = underlying_id(id);
349
			adjust_column ( crt_token ) ;
307
			DEREF_loc(id_loc(id), stmt_loc);
350
			return ;
308
			return;
351
		    }
-
 
352
		    break ;
-
 
353
		}
309
		}
354
	    }
-
 
355
	}
310
	}
356
	stmt_loc = crt_loc ;
311
	stmt_loc = crt_loc;
-
 
312
	return;
-
 
313
}
-
 
314
 
-
 
315
 
-
 
316
/*
-
 
317
    ADJUST LINE NUMBER
-
 
318
 
-
 
319
    This routine is called whenever the location of a statement is
-
 
320
    recorded.  It is intended to ensure that the current location points
-
 
321
    to the start of the next statement rather than the end of the current
-
 
322
    statement.
-
 
323
*/
-
 
324
 
-
 
325
static void
-
 
326
adjust_line(int next)
-
 
327
{
-
 
328
	if (!adjusted_line) {
-
 
329
		adjusted_line = 1;
-
 
330
		if (next) {
-
 
331
			switch (crt_lex_token) {
-
 
332
			case lex_open_Hbrace_H1:
-
 
333
			case lex_colon:
-
 
334
			case lex_semicolon:
-
 
335
			case lex_close_Hround:
-
 
336
			case lex_else:
-
 
337
			case lex_exhaustive: {
-
 
338
				/* Scan to next token */
-
 
339
				PPTOKEN *p = crt_token->next;
-
 
340
				if (p) {
-
 
341
					/* Set location from next token */
-
 
342
					p = read_loc_tokens(p);
-
 
343
					if (crt_state_depth == 0) {
-
 
344
						adjust_column(p);
-
 
345
						return;
-
 
346
					}
-
 
347
				} else {
-
 
348
					if (crt_state_depth == 0) {
-
 
349
						/* Skip white space from input
-
 
350
						 * file */
-
 
351
						unsigned long sp =
-
 
352
						    skip_white(1);
-
 
353
						update_column();
-
 
354
						stmt_loc = crt_loc;
-
 
355
						stmt_loc.column++;
-
 
356
						if (sp) {
-
 
357
							patch_white(sp);
-
 
358
						}
-
 
359
						return;
-
 
360
					}
-
 
361
				}
-
 
362
				break;
-
 
363
			}
-
 
364
			default:
-
 
365
				/* Use current token */
-
 
366
				if (crt_state_depth == 0) {
-
 
367
					adjust_column(crt_token);
-
 
368
					return;
357
    }
369
				}
-
 
370
				break;
-
 
371
			}
-
 
372
		}
-
 
373
		stmt_loc = crt_loc;
-
 
374
	}
358
    return ;
375
	return;
359
}
376
}
360
 
377
 
361
 
378
 
362
/*
379
/*
363
    BLOCK NAMESPACE
380
    BLOCK NAMESPACE
364
 
381
 
365
    This variable can be set to make begin_compound_stmt use an existing
382
    This variable can be set to make begin_compound_stmt use an existing
366
    namespace rather than creating a new one.
383
    namespace rather than creating a new one.
367
*/
384
*/
368
 
385
 
369
NAMESPACE block_namespace = NULL_nspace ;
386
NAMESPACE block_namespace = NULL_nspace;
370
 
387
 
371
 
388
 
372
/*
389
/*
373
    BEGIN A COMPOUND STATEMENT
390
    BEGIN A COMPOUND STATEMENT
374
 
391
 
Line 384... Line 401...
384
    statement is used within the construction to point to the innermost
401
    statement is used within the construction to point to the innermost
385
    block of this kind.  It is only set to its correct value at the end
402
    block of this kind.  It is only set to its correct value at the end
386
    of the compound statement.
403
    of the compound statement.
387
*/
404
*/
388
 
405
 
389
EXP begin_compound_stmt
406
EXP
390
    PROTO_N ( ( scope ) )
-
 
391
    PROTO_T ( int scope )
407
begin_compound_stmt(int scope)
392
{
408
{
393
    TYPE t ;
409
	TYPE t;
394
    NAMESPACE ns ;
410
	NAMESPACE ns;
395
    EXP e = NULL_exp ;
411
	EXP e = NULL_exp;
396
    LIST ( EXP ) stmts ;
412
	LIST(EXP) stmts;
397
    NAMESPACE cns = NULL_nspace ;
413
	NAMESPACE cns = NULL_nspace;
398
 
414
 
399
    /* Create block namespace */
415
	/* Create block namespace */
400
    if ( scope > 0 ) {
416
	if (scope > 0) {
401
	ns = block_namespace ;
417
		ns = block_namespace;
402
	if ( IS_NULL_nspace ( ns ) ) {
418
		if (IS_NULL_nspace(ns)) {
403
	    /* Create new namespace */
419
			/* Create new namespace */
404
	    unsigned tag = nspace_block_tag ;
420
			unsigned tag = nspace_block_tag;
-
 
421
			if (scope == 2) {
405
	    if ( scope == 2 ) tag = nspace_dummy_tag ;
422
				tag = nspace_dummy_tag;
-
 
423
			}
406
	    cns = crt_namespace ;
424
			cns = crt_namespace;
407
	    ns = make_namespace ( crt_func_id, tag, 0 ) ;
425
			ns = make_namespace(crt_func_id, tag, 0);
408
	    push_namespace ( ns ) ;
426
			push_namespace(ns);
-
 
427
		} else {
-
 
428
			/* Use existing namespace */
-
 
429
			MEMBER mem = DEREF_member(nspace_last(ns));
-
 
430
			COPY_member(nspace_prev(ns), mem);
-
 
431
			cns = ns;
-
 
432
			block_namespace = NULL_nspace;
-
 
433
		}
-
 
434
		IGNORE incr_value(OPT_VAL_statement_depth);
409
	} else {
435
	} else {
410
	    /* Use existing namespace */
-
 
411
	    MEMBER mem = DEREF_member ( nspace_last ( ns ) ) ;
-
 
412
	    COPY_member ( nspace_prev ( ns ), mem ) ;
-
 
413
	    cns = ns ;
-
 
414
	    block_namespace = NULL_nspace ;
436
		ns = NULL_nspace;
415
	}
437
	}
416
	IGNORE incr_value ( OPT_VAL_statement_depth ) ;
-
 
417
    } else {
-
 
418
	ns = NULL_nspace ;
-
 
419
    }
-
 
420
 
438
 
421
    /* Create compound statement */
439
	/* Create compound statement */
422
    t = ( unreached_code ? type_bottom : type_void ) ;
440
	t = (unreached_code ? type_bottom : type_void);
423
    if ( record_location && scope >= 0 ) {
441
	if (record_location && scope >= 0) {
424
	/* Record start of block */
442
		/* Record start of block */
425
	adjust_line ( scope ) ;
443
		adjust_line(scope);
426
	adjusted_line = 0 ;
444
		adjusted_line = 0;
427
	MAKE_exp_location ( t, stmt_loc, e, e ) ;
445
		MAKE_exp_location(t, stmt_loc, e, e);
-
 
446
		if (do_scope) {
428
	if ( do_scope ) dump_begin_scope ( NULL_id, ns, cns, &crt_loc ) ;
447
			dump_begin_scope(NULL_id, ns, cns, &crt_loc);
429
    }
448
		}
-
 
449
	}
430
    CONS_exp ( e, NULL_list ( EXP ), stmts ) ;
450
	CONS_exp(e, NULL_list(EXP), stmts);
431
    MAKE_exp_sequence ( t, stmts, stmts, ns, 0, e ) ;
451
	MAKE_exp_sequence(t, stmts, stmts, ns, 0, e);
432
    COPY_exp ( exp_sequence_parent ( e ), e ) ;
452
	COPY_exp(exp_sequence_parent(e), e);
433
    return ( e ) ;
453
	return (e);
434
}
454
}
435
 
455
 
436
 
456
 
437
/*
457
/*
438
    MARK THE START OF A COMPOUND STATEMENT
458
    MARK THE START OF A COMPOUND STATEMENT
439
 
459
 
440
    On occasions a compound statement may be created before the open brace
460
    On occasions a compound statement may be created before the open brace
441
    which marks its start.  In this case this routine is called when the
461
    which marks its start.  In this case this routine is called when the
442
    open brace is encountered to record the actual position of the start
462
    open brace is encountered to record the actual position of the start
443
    of the block.
463
    of the block.
444
*/
464
*/
445
 
465
 
446
void mark_compound_stmt
466
void
447
    PROTO_N ( ( prev ) )
-
 
448
    PROTO_T ( EXP prev )
467
mark_compound_stmt(EXP prev)
449
{
468
{
450
    if ( record_location ) {
469
	if (record_location) {
451
	LIST ( EXP ) stmts = DEREF_list ( exp_sequence_first ( prev ) ) ;
470
		LIST(EXP) stmts = DEREF_list(exp_sequence_first(prev));
452
	EXP stmt = DEREF_exp ( HEAD_list ( stmts ) ) ;
471
		EXP stmt = DEREF_exp(HEAD_list(stmts));
453
	if ( !IS_NULL_exp ( stmt ) && IS_exp_location ( stmt ) ) {
472
		if (!IS_NULL_exp(stmt) && IS_exp_location(stmt)) {
454
	    adjust_line ( 1 ) ;
473
			adjust_line(1);
455
	    adjusted_line = 0 ;
474
			adjusted_line = 0;
456
	    COPY_loc ( exp_location_end ( stmt ), stmt_loc ) ;
475
			COPY_loc(exp_location_end(stmt), stmt_loc);
-
 
476
		}
457
	}
477
	}
458
    }
-
 
459
    return ;
478
	return;
460
}
479
}
461
 
480
 
462
 
481
 
463
/*
482
/*
464
    EXTEND A COMPOUND STATEMENT
483
    EXTEND A COMPOUND STATEMENT
465
 
484
 
466
    This routine adds the statement stmt to the end of the compound
485
    This routine adds the statement stmt to the end of the compound
467
    statement prev.  Note that this routine also decides where the
486
    statement prev.  Note that this routine also decides where the
468
    statement after this one is to go on the basis of the rules above.
487
    statement after this one is to go on the basis of the rules above.
469
*/
488
*/
470
 
489
 
471
static EXP extend_compound_stmt
490
static EXP
472
    PROTO_N ( ( prev, stmt, loc ) )
-
 
473
    PROTO_T ( EXP prev X EXP stmt X int loc )
491
extend_compound_stmt(EXP prev, EXP stmt, int loc)
474
{
492
{
475
    EXP body ;
493
	EXP body;
476
    EXP parent ;
494
	EXP parent;
477
    LIST ( EXP ) elem ;
495
	LIST(EXP) elem;
478
    LIST ( EXP ) elem0 ;
496
	LIST(EXP) elem0;
479
    LIST ( EXP ) stmts ;
497
	LIST(EXP) stmts;
480
 
498
 
481
    /* Allow for null statements */
499
	/* Allow for null statements */
482
    if ( IS_NULL_exp ( stmt ) ) return ( prev ) ;
500
	if (IS_NULL_exp(stmt)) {
-
 
501
		return (prev);
-
 
502
	}
483
 
503
 
484
    /* Add statement to list */
504
	/* Add statement to list */
485
    stmts = DEREF_list ( exp_sequence_last ( prev ) ) ;
505
	stmts = DEREF_list(exp_sequence_last(prev));
486
    CONS_exp ( stmt, NULL_list ( EXP ), elem ) ;
506
	CONS_exp(stmt, NULL_list(EXP), elem);
487
    COPY_list ( PTR_TAIL_list ( stmts ), elem ) ;
507
	COPY_list(PTR_TAIL_list(stmts), elem);
488
    elem0 = elem ;
508
	elem0 = elem;
489
 
509
 
490
    /* Set the parent of stmt */
510
	/* Set the parent of stmt */
491
    parent = DEREF_exp ( exp_sequence_parent ( prev ) ) ;
511
	parent = DEREF_exp(exp_sequence_parent(prev));
492
    set_parent_stmt ( stmt, parent ) ;
512
	set_parent_stmt(stmt, parent);
493
 
513
 
494
    /* Find location of next statement */
514
	/* Find location of next statement */
495
    switch ( TAG_exp ( stmt ) ) {
515
	switch (TAG_exp(stmt)) {
496
	case exp_decl_stmt_tag : {
516
	case exp_decl_stmt_tag: {
497
	    /* Transfer to the body of a declaration */
517
		/* Transfer to the body of a declaration */
498
	    unsigned tag ;
518
		unsigned tag;
499
	    body = stmt ;
519
		body = stmt;
500
	    do {
520
		do {
501
		body = DEREF_exp ( exp_decl_stmt_body ( body ) ) ;
521
			body = DEREF_exp(exp_decl_stmt_body(body));
502
		tag = TAG_exp ( body ) ;
522
			tag = TAG_exp(body);
503
	    } while ( tag == exp_decl_stmt_tag ) ;
523
		} while (tag == exp_decl_stmt_tag);
504
	    if ( tag == exp_sequence_tag ) {
524
		if (tag == exp_sequence_tag) {
505
		elem = DEREF_list ( exp_sequence_last ( body ) ) ;
525
			elem = DEREF_list(exp_sequence_last(body));
506
		COPY_exp ( exp_sequence_parent ( prev ), body ) ;
526
			COPY_exp(exp_sequence_parent(prev), body);
507
	    }
527
		}
508
	    loc = 0 ;
528
		loc = 0;
509
	    break ;
529
		break;
510
	}
530
	}
511
	case exp_label_stmt_tag : {
531
	case exp_label_stmt_tag:
512
	    /* Transfer to the body of a labelled statement */
532
		/* Transfer to the body of a labelled statement */
513
	    body = DEREF_exp ( exp_label_stmt_body ( stmt ) ) ;
533
		body = DEREF_exp(exp_label_stmt_body(stmt));
514
	    if ( IS_exp_sequence ( body ) ) {
534
		if (IS_exp_sequence(body)) {
515
		elem = DEREF_list ( exp_sequence_last ( body ) ) ;
535
			elem = DEREF_list(exp_sequence_last(body));
516
		COPY_exp ( exp_sequence_parent ( prev ), body ) ;
536
			COPY_exp(exp_sequence_parent(prev), body);
517
	    }
537
		}
518
	    loc = 0 ;
538
		loc = 0;
519
	    break ;
539
		break;
520
	}
-
 
521
	case exp_location_tag :
540
	case exp_location_tag:
522
	case exp_thrown_tag : {
541
	case exp_thrown_tag:
523
	    /* Don't record location in these cases */
542
		/* Don't record location in these cases */
524
	    loc = 0 ;
543
		loc = 0;
525
	    break ;
544
		break;
526
	}
545
	}
527
    }
-
 
528
    COPY_list ( exp_sequence_last ( prev ), elem ) ;
546
	COPY_list(exp_sequence_last(prev), elem);
529
 
547
 
530
    /* Record statement location */
548
	/* Record statement location */
531
    if ( record_location ) {
549
	if (record_location) {
532
	adjust_line ( 1 ) ;
550
		adjust_line(1);
533
	if ( loc ) {
551
		if (loc) {
534
	    TYPE t = DEREF_type ( exp_type ( stmt ) ) ;
552
			TYPE t = DEREF_type(exp_type(stmt));
535
	    MAKE_exp_location ( t, stmt_loc, stmt, stmt ) ;
553
			MAKE_exp_location(t, stmt_loc, stmt, stmt);
536
	    COPY_exp ( HEAD_list ( elem0 ), stmt ) ;
554
			COPY_exp(HEAD_list(elem0), stmt);
537
	}
555
		}
538
    }
556
	}
539
 
557
 
540
    /* Unreached code analysis */
558
	/* Unreached code analysis */
541
    if ( is_bottom ( stmt ) ) {
559
	if (is_bottom(stmt)) {
542
	COPY_type ( exp_type ( prev ), type_bottom ) ;
560
		COPY_type(exp_type(prev), type_bottom);
543
    }
561
	}
544
    return ( prev ) ;
562
	return (prev);
545
}
563
}
546
 
564
 
547
 
565
 
548
/*
566
/*
549
    ADD A STATEMENT TO A COMPOUND STATEMENT
567
    ADD A STATEMENT TO A COMPOUND STATEMENT
Line 556... Line 574...
556
    statement has been introduced.  The treatment of labelled statements
574
    statement has been introduced.  The treatment of labelled statements
557
    is tricky - the declarations need to be inserted between the label
575
    is tricky - the declarations need to be inserted between the label
558
    and its body.
576
    and its body.
559
*/
577
*/
560
 
578
 
561
EXP add_compound_stmt
579
EXP
562
    PROTO_N ( ( prev, stmt ) )
-
 
563
    PROTO_T ( EXP prev X EXP stmt )
580
add_compound_stmt(EXP prev, EXP stmt)
564
{
581
{
565
    EXP parent = NULL_exp ;
582
    EXP parent = NULL_exp;
566
    LIST ( EXP ) last = NULL_list ( EXP ) ;
583
    LIST(EXP) last = NULL_list(EXP);
567
    NAMESPACE ns = DEREF_nspace ( exp_sequence_decl ( prev ) ) ;
584
    NAMESPACE ns = DEREF_nspace(exp_sequence_decl(prev));
568
    if ( !IS_NULL_nspace ( ns ) ) {
585
    if (!IS_NULL_nspace(ns)) {
569
	MEMBER p = DEREF_member ( nspace_last ( ns ) ) ;
586
	MEMBER p = DEREF_member(nspace_last(ns));
570
	MEMBER q = DEREF_member ( nspace_prev ( ns ) ) ;
587
	MEMBER q = DEREF_member(nspace_prev(ns));
571
	if ( !EQ_member ( p, q ) ) {
588
	if (!EQ_member(p, q)) {
572
	    /* Create declaration statement */
589
	    /* Create declaration statement */
573
	    int vars = 0 ;
590
	    int vars = 0;
574
	    EXP decl = make_decl_stmt ( p, q, &vars ) ;
591
	    EXP decl = make_decl_stmt(p, q, &vars);
575
	    if ( !IS_NULL_exp ( stmt ) && IS_exp_label_stmt ( stmt ) ) {
592
	    if (!IS_NULL_exp(stmt) && IS_exp_label_stmt(stmt)) {
576
		/* Labels come before declarations */
593
		/* Labels come before declarations */
577
		EXP body = DEREF_exp ( exp_label_stmt_body ( stmt ) ) ;
594
		EXP body = DEREF_exp(exp_label_stmt_body(stmt));
578
		if ( IS_exp_sequence ( body ) ) {
595
		if (IS_exp_sequence(body)) {
579
		    last = DEREF_list ( exp_sequence_last ( body ) ) ;
596
		    last = DEREF_list(exp_sequence_last(body));
580
		    body = DEREF_exp ( HEAD_list ( last ) ) ;
597
		    body = DEREF_exp(HEAD_list(last));
581
		    if ( !IS_NULL_exp ( body ) ) {
598
		    if (!IS_NULL_exp(body)) {
582
			EXP b = body ;
599
			EXP b = body;
583
			if ( IS_exp_location ( b ) ) {
600
			if (IS_exp_location(b)) {
584
			    b = DEREF_exp ( exp_location_arg ( b ) ) ;
601
			    b = DEREF_exp(exp_location_arg(b));
585
			}
602
			}
586
			if ( !IS_NULL_exp ( b ) ) {
603
			if (!IS_NULL_exp(b)) {
587
			    COPY_exp ( HEAD_list ( last ), NULL_exp ) ;
604
			    COPY_exp(HEAD_list(last), NULL_exp);
588
			}
605
			}
589
		    }
606
		    }
590
		    last = NULL_list ( EXP ) ;
607
		    last = NULL_list(EXP);
591
		    prev = extend_compound_stmt ( prev, stmt, 1 ) ;
608
		    prev = extend_compound_stmt(prev, stmt, 1);
592
		    stmt = body ;
609
		    stmt = body;
593
		}
610
		}
594
	    }
611
	    }
595
	    if ( !vars ) {
612
	    if (!vars) {
596
		last = DEREF_list ( exp_sequence_last ( prev ) ) ;
613
		last = DEREF_list(exp_sequence_last(prev));
597
		parent = DEREF_exp ( exp_sequence_parent ( prev ) ) ;
614
		parent = DEREF_exp(exp_sequence_parent(prev));
598
	    }
615
	    }
599
	    prev = extend_compound_stmt ( prev, decl, 0 ) ;
616
	    prev = extend_compound_stmt(prev, decl, 0);
600
	    COPY_member ( nspace_prev ( ns ), p ) ;
617
	    COPY_member(nspace_prev(ns), p);
601
	}
618
	}
602
    }
619
    }
603
    if ( !IS_NULL_exp ( stmt ) ) {
620
    if (!IS_NULL_exp(stmt)) {
604
	/* Add the new statement */
621
	/* Add the new statement */
605
	prev = extend_compound_stmt ( prev, stmt, 1 ) ;
622
	prev = extend_compound_stmt(prev, stmt, 1);
606
    }
623
    }
607
    if ( !IS_NULL_list ( last ) ) {
624
    if (!IS_NULL_list(last)) {
608
	/* Restrict scope of temporaries to stmt */
625
	/* Restrict scope of temporaries to stmt */
609
	last = END_list ( last ) ;
626
	last = END_list(last);
610
	COPY_list ( exp_sequence_last ( prev ), last ) ;
627
	COPY_list(exp_sequence_last(prev), last);
611
	COPY_exp ( exp_sequence_parent ( prev ), parent ) ;
628
	COPY_exp(exp_sequence_parent(prev), parent);
612
    }
629
    }
613
    adjusted_line = 0 ;
630
    adjusted_line = 0;
614
    return ( prev ) ;
631
    return (prev);
615
}
632
}
616
 
633
 
617
 
634
 
618
/*
635
/*
619
    END A COMPOUND STATEMENT
636
    END A COMPOUND STATEMENT
620
 
637
 
621
    This routine ends the compound statement prev.
638
    This routine ends the compound statement prev.
622
*/
639
*/
-
 
640
 
-
 
641
EXP
-
 
642
end_compound_stmt(EXP prev)
-
 
643
{
-
 
644
	/* Take local declarations out of scope */
-
 
645
	int blk = DEREF_int(exp_sequence_block(prev));
-
 
646
	NAMESPACE ns = DEREF_nspace(exp_sequence_decl(prev));
-
 
647
	if (!IS_NULL_nspace(ns)) {
-
 
648
		if (check_namespace(ns, prev, ANON_NONE, 1)) {
-
 
649
			if (blk == 0) {
-
 
650
				COPY_int(exp_sequence_block(prev), 1);
-
 
651
			}
-
 
652
		}
-
 
653
		if (do_scope) {
-
 
654
			dump_end_scope(NULL_id, ns, &stmt_loc);
-
 
655
		}
-
 
656
		decr_value(OPT_VAL_statement_depth);
-
 
657
		IGNORE pop_namespace();
-
 
658
	}
-
 
659
	COPY_exp(exp_sequence_parent(prev), NULL_exp);
-
 
660
	return (prev);
-
 
661
}
-
 
662
 
-
 
663
 
-
 
664
/*
-
 
665
    CONSTRUCT A TEMPORARY DECLARATION STATEMENT
623
 
666
 
-
 
667
    This routine binds any temporary variable declarations given by the
624
EXP end_compound_stmt
668
    namespace members p to q to the expression e.  This is part of the
625
    PROTO_N ( ( prev ) )
669
    action of make_decl_stmt.
-
 
670
*/
-
 
671
 
-
 
672
EXP
626
    PROTO_T ( EXP prev )
673
make_temp_decl(MEMBER p, MEMBER q, EXP e)
627
{
674
{
-
 
675
	MEMBER r = p;
-
 
676
	while (!EQ_member(r, q)) {
628
    /* Take local declarations out of scope */
677
		IDENTIFIER id = DEREF_id(member_id(r));
629
    int blk = DEREF_int ( exp_sequence_block ( prev ) ) ;
678
		if (!IS_NULL_id(id) && IS_id_variable(id)) {
-
 
679
			/* Construct declaration statement */
630
    NAMESPACE ns = DEREF_nspace ( exp_sequence_decl ( prev ) ) ;
680
			DECL_SPEC ds = DEREF_dspec(id_storage(id));
-
 
681
			if (ds & dspec_temp) {
-
 
682
				/* Temporary variables */
631
    if ( !IS_NULL_nspace ( ns ) ) {
683
				if (!(ds & dspec_ignore)) {
-
 
684
					EXP d;
-
 
685
					TYPE t =
632
	if ( check_namespace ( ns, prev, ANON_NONE, 1 ) ) {
686
					    DEREF_type(id_variable_type(id));
-
 
687
					EXP term =
-
 
688
					    DEREF_exp(id_variable_term(id));
633
	    if ( blk == 0 ) {
689
					if (!IS_NULL_exp(term)) {
-
 
690
						have_destructor = 1;
-
 
691
					}
634
		COPY_int ( exp_sequence_block ( prev ), 1 ) ;
692
					MAKE_exp_decl_stmt(t, id, e, d);
-
 
693
					set_parent_stmt(e, d);
-
 
694
					e = d;
635
	    }
695
				}
-
 
696
			}
-
 
697
		}
-
 
698
		r = DEREF_member(member_next(r));
636
	}
699
	}
637
	if ( do_scope ) dump_end_scope ( NULL_id, ns, &stmt_loc ) ;
-
 
638
	decr_value ( OPT_VAL_statement_depth ) ;
-
 
639
	IGNORE pop_namespace () ;
-
 
640
    }
-
 
641
    COPY_exp ( exp_sequence_parent ( prev ), NULL_exp ) ;
-
 
642
    return ( prev ) ;
700
	return (e);
643
}
701
}
644
 
702
 
645
 
703
 
646
/*
-
 
647
    CONSTRUCT A TEMPORARY DECLARATION STATEMENT
-
 
648
 
-
 
649
    This routine binds any temporary variable declarations given by the
-
 
650
    namespace members p to q to the expression e.  This is part of the
-
 
651
    action of make_decl_stmt.
-
 
652
*/
-
 
653
 
-
 
654
EXP make_temp_decl
-
 
655
    PROTO_N ( ( p, q, e ) )
-
 
656
    PROTO_T ( MEMBER p X MEMBER q X EXP e )
-
 
657
{
-
 
658
    MEMBER r = p ;
-
 
659
    while ( !EQ_member ( r, q ) ) {
-
 
660
	IDENTIFIER id = DEREF_id ( member_id ( r ) ) ;
-
 
661
	if ( !IS_NULL_id ( id ) && IS_id_variable ( id ) ) {
-
 
662
	    /* Construct declaration statement */
-
 
663
	    DECL_SPEC ds = DEREF_dspec ( id_storage ( id ) ) ;
-
 
664
	    if ( ds & dspec_temp ) {
-
 
665
		/* Temporary variables */
-
 
666
		if ( !( ds & dspec_ignore ) ) {
-
 
667
		    EXP d ;
-
 
668
		    TYPE t = DEREF_type ( id_variable_type ( id ) ) ;
-
 
669
		    EXP term = DEREF_exp ( id_variable_term ( id ) ) ;
-
 
670
		    if ( !IS_NULL_exp ( term ) ) have_destructor = 1 ;
-
 
671
		    MAKE_exp_decl_stmt ( t, id, e, d ) ;
-
 
672
		    set_parent_stmt ( e, d ) ;
-
 
673
		    e = d ;
-
 
674
		}
-
 
675
	    }
-
 
676
	}
-
 
677
	r = DEREF_member ( member_next ( r ) ) ;
-
 
678
    }
-
 
679
    return ( e ) ;
-
 
680
}
-
 
681
 
-
 
682
 
-
 
683
/*
704
/*
684
    CONSTRUCT A DECLARATION STATEMENT
705
    CONSTRUCT A DECLARATION STATEMENT
685
 
706
 
686
    This routine constructs a series of nested declaration statements
707
    This routine constructs a series of nested declaration statements
687
    corresponding to the given list of namespace members.  p gives the
708
    corresponding to the given list of namespace members.  p gives the
688
    last member of the current block namespace defined, while q gives
709
    last member of the current block namespace defined, while q gives
Line 695... Line 716...
695
			    ....
716
			    ....
696
			    decl1 ;
717
			    decl1 ;
697
			    decl2 ;
718
			    decl2 ;
698
			    ....
719
			    ....
699
			    body1 ;
720
			    body1 ;
700
			    ....
721
			    ....
701
			}
722
			}
702
 
723
 
703
    is transformed into:
724
    is transformed into:
704
 
725
 
705
			{
726
			{
706
			    stmt1 ;
727
			    stmt1 ;
707
			    ....
728
			    ....
708
			    decl1 ; {
729
			    decl1 ; {
Line 716... Line 737...
716
			}
737
			}
717
 
738
 
718
    except that the introduced blocks do not establish scopes.  Any
739
    except that the introduced blocks do not establish scopes.  Any
719
    temporary variables introduced are declared before the normal
740
    temporary variables introduced are declared before the normal
720
    variables regardless of their actual order of declaration.
741
    variables regardless of their actual order of declaration.
721
*/
742
*/
722
 
743
 
723
EXP make_decl_stmt
744
EXP
724
    PROTO_N ( ( p, q, vars ) )
-
 
725
    PROTO_T ( MEMBER p X MEMBER q X int *vars )
745
make_decl_stmt(MEMBER p, MEMBER q, int *vars)
726
{
746
{
727
    MEMBER r = p ;
747
    MEMBER r = p;
728
    unsigned temps = 0 ;
748
    unsigned temps = 0;
729
    IDENTIFIER init = NULL_id ;
749
    IDENTIFIER init = NULL_id;
730
    LIST ( IDENTIFIER ) destr = NULL_list ( IDENTIFIER ) ;
750
    LIST(IDENTIFIER) destr = NULL_list(IDENTIFIER);
731
    EXP e = begin_compound_stmt ( -1 ) ;
751
    EXP e = begin_compound_stmt(-1);
732
 
752
 
733
    /* Scan through members */
753
    /* Scan through members */
734
    while ( !EQ_member ( r, q ) ) {
754
    while (!EQ_member(r, q)) {
735
	IDENTIFIER id = DEREF_id ( member_id ( r ) ) ;
755
	IDENTIFIER id = DEREF_id(member_id(r));
736
	if ( !IS_NULL_id ( id ) && IS_id_variable ( id ) ) {
756
	if (!IS_NULL_id(id) && IS_id_variable(id)) {
737
	    /* Construct declaration statement */
757
	    /* Construct declaration statement */
738
	    DECL_SPEC ds = DEREF_dspec ( id_storage ( id ) ) ;
758
	    DECL_SPEC ds = DEREF_dspec(id_storage(id));
739
	    if ( ds & dspec_temp ) {
759
	    if (ds & dspec_temp) {
740
		/* Temporary variables */
760
		/* Temporary variables */
741
		if ( !( ds & dspec_ignore ) ) {
761
		if (!(ds & dspec_ignore)) {
742
		    if ( ds & dspec_register ) {
762
		    if (ds & dspec_register) {
743
			EXP term = DEREF_exp ( id_variable_term ( id ) ) ;
763
			EXP term = DEREF_exp(id_variable_term(id));
744
			if ( !IS_NULL_exp ( term ) ) {
764
			if (!IS_NULL_exp(term)) {
745
			    CONS_id ( id, destr, destr ) ;
765
			    CONS_id(id, destr, destr);
746
			}
766
			}
747
		    }
767
		    }
748
		    temps++ ;
768
		    temps++;
749
		}
769
		}
750
	    } else if ( ds & dspec_linkage ) {
770
	    } else if (ds & dspec_linkage) {
751
		/* External variables */
771
		/* External variables */
752
		/* EMPTY */
772
		/* EMPTY */
753
	    } else if ( ( ds & dspec_reserve ) && !is_anon_member ( id ) ) {
773
	    } else if ((ds & dspec_reserve) && !is_anon_member(id)) {
754
		/* Injected variables */
774
		/* Injected variables */
755
		/* EMPTY */
775
		/* EMPTY */
756
	    } else {
776
	    } else {
757
		EXP d ;
777
		EXP d;
758
		TYPE t = DEREF_type ( id_variable_type ( id ) ) ;
778
		TYPE t = DEREF_type(id_variable_type(id));
759
		EXP def = DEREF_exp ( id_variable_init ( id ) ) ;
779
		EXP def = DEREF_exp(id_variable_init(id));
760
		EXP term = DEREF_exp ( id_variable_term ( id ) ) ;
780
		EXP term = DEREF_exp(id_variable_term(id));
761
		if ( !IS_NULL_exp ( term ) ) have_destructor = 1 ;
781
		if (!IS_NULL_exp(term)) {
-
 
782
			have_destructor = 1;
-
 
783
		}
762
		if ( !IS_NULL_exp ( def ) && !IS_exp_null ( def ) ) {
784
		if (!IS_NULL_exp(def) && !IS_exp_null(def)) {
763
		    /* Identifier is initialised */
785
		    /* Identifier is initialised */
764
		    init = id ;
786
		    init = id;
765
		}
787
		}
766
		MAKE_exp_decl_stmt ( t, id, e, d ) ;
788
		MAKE_exp_decl_stmt(t, id, e, d);
767
		set_parent_stmt ( e, d ) ;
789
		set_parent_stmt(e, d);
768
		*vars = 1 ;
790
		*vars = 1;
769
		e = d ;
791
		e = d;
770
	    }
792
	    }
771
	}
793
	}
772
	r = DEREF_member ( member_next ( r ) ) ;
794
	r = DEREF_member(member_next(r));
773
    }
795
    }
774
 
796
 
775
    /* Scan through again for temporary variables */
797
    /* Scan through again for temporary variables */
776
    if ( temps ) {
798
    if (temps) {
777
	e = make_temp_decl ( p, q, e ) ;
799
	e = make_temp_decl(p, q, e);
778
	if ( !IS_NULL_list ( destr ) ) {
800
	if (!IS_NULL_list(destr)) {
779
	    /* NOT YET IMPLEMENTED */
801
	    /* NOT YET IMPLEMENTED */
780
	    DESTROY_list ( destr, SIZE_id ) ;
802
	    DESTROY_list(destr, SIZE_id);
781
	}
803
	}
782
    }
804
    }
783
 
805
 
784
    /* Only report unreached declarations if they are initialised */
806
    /* Only report unreached declarations if they are initialised */
785
    if ( !IS_NULL_id ( init ) && unreached_code ) {
807
    if (!IS_NULL_id(init) && unreached_code) {
786
	if ( !unreached_last ) {
808
	if (!unreached_last) {
787
	    LOCATION loc ;
809
	    LOCATION loc;
788
	    DEREF_loc ( id_loc ( init ), loc ) ;
810
	    DEREF_loc(id_loc(init), loc);
789
	    report ( loc, ERR_stmt_stmt_unreach () ) ;
811
	    report(loc, ERR_stmt_stmt_unreach());
790
	    unreached_last = 1 ;
812
	    unreached_last = 1;
791
	}
813
	}
792
    }
814
    }
793
    return ( e ) ;
815
    return (e);
794
}
816
}
795
 
817
 
796
 
818
 
797
/*
819
/*
798
    BIND TEMPORARY VARIABLES TO AN EXPRESSION
820
    BIND TEMPORARY VARIABLES TO AN EXPRESSION
799
 
821
 
800
    This routine binds any temporary variables declared in e to the
822
    This routine binds any temporary variables declared in e to the
801
    expression.  Reference conversions are also applied, but any
823
    expression.  Reference conversions are also applied, but any
802
    parentheses are preserved for the benefit of the assignment in
824
    parentheses are preserved for the benefit of the assignment in
803
    boolean check.
825
    boolean check.
804
*/
826
*/
805
 
827
 
806
EXP bind_temporary
828
EXP
807
    PROTO_N ( ( e ) )
-
 
808
    PROTO_T ( EXP e )
829
bind_temporary(EXP e)
809
{
830
{
810
    if ( !IS_NULL_exp ( e ) ) {
831
	if (!IS_NULL_exp(e)) {
811
	NAMESPACE ns = crt_namespace ;
832
		NAMESPACE ns = crt_namespace;
812
	unsigned tag = TAG_exp ( e ) ;
833
		unsigned tag = TAG_exp(e);
813
	e = convert_reference ( e, REF_NORMAL ) ;
834
		e = convert_reference(e, REF_NORMAL);
814
	if ( !IS_NULL_nspace ( ns ) && IS_nspace_block_etc ( ns ) ) {
835
		if (!IS_NULL_nspace(ns) && IS_nspace_block_etc(ns)) {
815
	    MEMBER p = DEREF_member ( nspace_last ( ns ) ) ;
836
			MEMBER p = DEREF_member(nspace_last(ns));
816
	    MEMBER q = DEREF_member ( nspace_prev ( ns ) ) ;
837
			MEMBER q = DEREF_member(nspace_prev(ns));
817
	    if ( !EQ_member ( p, q ) ) {
838
			if (!EQ_member(p, q)) {
818
		e = make_temp_decl ( p, q, e ) ;
839
				e = make_temp_decl(p, q, e);
819
		COPY_member ( nspace_prev ( ns ), p ) ;
840
				COPY_member(nspace_prev(ns), p);
820
	    }
841
			}
821
	}
842
		}
822
	if ( tag == exp_paren_tag && option ( OPT_bool_assign ) ) {
843
		if (tag == exp_paren_tag && option(OPT_bool_assign)) {
823
	    e = make_paren_exp ( e ) ;
844
			e = make_paren_exp(e);
-
 
845
		}
824
	}
846
	}
825
    }
-
 
826
    return ( e ) ;
847
	return (e);
827
}
848
}
828
 
849
 
829
 
850
 
830
/*
851
/*
831
    DISCARD AN EXPRESSION
852
    DISCARD AN EXPRESSION
832
 
853
 
833
    This routine discards the expression e.  If e is an lvalue then the
854
    This routine discards the expression e.  If e is an lvalue then the
834
    lvalue conversions are checked but not performed.
855
    lvalue conversions are checked but not performed.
835
*/
856
*/
836
 
857
 
837
EXP make_discard_exp
858
EXP
838
    PROTO_N ( ( e ) )
-
 
839
    PROTO_T ( EXP e )
859
make_discard_exp(EXP e)
840
{
860
{
841
    if ( !IS_NULL_exp ( e ) ) {
861
	if (!IS_NULL_exp(e)) {
842
	unsigned tag = TAG_exp ( e ) ;
862
		unsigned tag = TAG_exp(e);
843
	TYPE t = DEREF_type ( exp_type ( e ) ) ;
863
		TYPE t = DEREF_type(exp_type(e));
844
	switch ( TAG_type ( t ) ) {
864
		switch (TAG_type(t)) {
845
	    case type_top_tag :
865
		case type_top_tag:
846
	    case type_bottom_tag : {
866
		case type_bottom_tag:
847
		/* Void types */
867
			/* Void types */
848
		break ;
868
			break;
849
	    }
-
 
850
	    case type_bitfield_tag : {
869
		case type_bitfield_tag:
851
		/* Remove bitfield components */
870
			/* Remove bitfield components */
852
		if ( tag == exp_contents_tag ) {
871
			if (tag == exp_contents_tag) {
853
		    e = DEREF_exp ( exp_contents_ptr ( e ) ) ;
872
				e = DEREF_exp(exp_contents_ptr(e));
854
		    tag = TAG_exp ( e ) ;
873
				tag = TAG_exp(e);
855
		}
874
			}
856
		if ( tag == exp_indir_tag ) {
875
			if (tag == exp_indir_tag) {
857
		    e = DEREF_exp ( exp_indir_ptr ( e ) ) ;
876
				e = DEREF_exp(exp_indir_ptr(e));
858
		    tag = TAG_exp ( e ) ;
877
				tag = TAG_exp(e);
859
		    if ( tag == exp_add_ptr_tag ) {
878
				if (tag == exp_add_ptr_tag) {
860
			e = DEREF_exp ( exp_add_ptr_ptr ( e ) ) ;
879
					e = DEREF_exp(exp_add_ptr_ptr(e));
861
			tag = TAG_exp ( e ) ;
880
					tag = TAG_exp(e);
862
			if ( tag == exp_address_tag ) {
881
					if (tag == exp_address_tag) {
863
			    e = DEREF_exp ( exp_address_arg ( e ) ) ;
882
						e = DEREF_exp(exp_address_arg(e));
864
			    tag = TAG_exp ( e ) ;
883
						tag = TAG_exp(e);
-
 
884
					}
-
 
885
				}
865
			}
886
			}
866
		    }
-
 
867
		}
-
 
868
		break ;
887
			break;
869
	    }
-
 
870
	    case type_array_tag :
888
		case type_array_tag:
871
	    case type_func_tag :
889
		case type_func_tag:
872
	    case type_templ_tag : {
890
		case type_templ_tag:
873
		/* Check for overloaded functions */
891
			/* Check for overloaded functions */
874
		e = convert_lvalue ( e ) ;
892
			e = convert_lvalue(e);
875
		tag = TAG_exp ( e ) ;
893
			tag = TAG_exp(e);
876
		break ;
894
			break;
877
	    }
-
 
878
	    case type_token_tag : {
895
		case type_token_tag:
879
		if ( is_templ_type ( t ) ) {
896
			if (is_templ_type(t)) {
880
		    /* Mark template parameters */
897
				/* Mark template parameters */
881
		    MAKE_exp_op ( t, lex_void, e, NULL_exp, e ) ;
898
				MAKE_exp_op(t, lex_void, e, NULL_exp, e);
882
		    tag = exp_op_tag ;
899
				tag = exp_op_tag;
-
 
900
				break;
-
 
901
			}
-
 
902
			goto default_lab;
-
 
903
		default:
-
 
904
default_lab: {
-
 
905
		     /* Check lvalue conversions */
-
 
906
		     ERROR err;
-
 
907
		     CV_SPEC qual = DEREF_cv(type_qual(t));
-
 
908
		     if (!(qual & cv_lvalue)) {
-
 
909
			     break;
-
 
910
		     }
-
 
911
		     if (qual == (cv_lvalue | cv_const)) {
-
 
912
			     if (tag == exp_identifier_tag) {
-
 
913
				     e = convert_const(e);
-
 
914
				     tag = TAG_exp(e);
-
 
915
				     break;
-
 
916
			     }
-
 
917
		     }
-
 
918
		     err = check_incomplete(t);
-
 
919
		     if (!IS_NULL_err(err)) {
-
 
920
			     err = concat_error(err, ERR_stmt_expr_incompl());
-
 
921
			     report(crt_loc, err);
-
 
922
		     }
883
		    break ;
923
		     break;
-
 
924
	     }
884
		}
925
		}
885
		goto default_lab ;
926
		switch (tag) {
886
	    }
-
 
887
	    default :
927
		case exp_postinc_tag:
888
	    default_lab : {
928
			/* Discard postincrement expressions */
889
		/* Check lvalue conversions */
929
			COPY_exp(exp_postinc_value(e), NULL_exp);
890
		ERROR err ;
930
			break;
-
 
931
		case exp_address_tag:
891
		CV_SPEC qual = DEREF_cv ( type_qual ( t ) ) ;
932
		case exp_address_mem_tag:
892
		if ( !( qual & cv_lvalue ) ) break ;
933
			/* Check for overloaded functions */
893
		if ( qual == ( cv_lvalue | cv_const ) ) {
934
			e = convert_lvalue(e);
-
 
935
			break;
894
		    if ( tag == exp_identifier_tag ) {
936
		case exp_constr_tag:
895
			e = convert_const ( e ) ;
937
			/* Introduce temporary for constructor */
896
			tag = TAG_exp ( e ) ;
938
			e = convert_none(e);
897
			break ;
939
			break;
898
		    }
-
 
899
		}
940
		}
900
		err = check_incomplete ( t ) ;
-
 
901
		if ( !IS_NULL_err ( err ) ) {
-
 
902
		    err = concat_error ( err, ERR_stmt_expr_incompl () ) ;
-
 
903
		    report ( crt_loc, err ) ;
-
 
904
		}
-
 
905
		break ;
-
 
906
	    }
-
 
907
	}
-
 
908
	switch ( tag ) {
-
 
909
	    case exp_postinc_tag : {
-
 
910
		/* Discard postincrement expressions */
-
 
911
		COPY_exp ( exp_postinc_value ( e ), NULL_exp ) ;
-
 
912
		break ;
-
 
913
	    }
-
 
914
	    case exp_address_tag :
-
 
915
	    case exp_address_mem_tag : {
-
 
916
		/* Check for overloaded functions */
-
 
917
		e = convert_lvalue ( e ) ;
-
 
918
		break ;
-
 
919
	    }
-
 
920
	    case exp_constr_tag : {
-
 
921
		/* Introduce temporary for constructor */
-
 
922
		e = convert_none ( e ) ;
-
 
923
		break ;
-
 
924
	    }
-
 
925
	}
941
	}
926
    }
-
 
927
    return ( e ) ;
942
	return (e);
928
}
943
}
929
 
944
 
930
 
945
 
931
/*
946
/*
932
    CHECK A DISCARDED EXPRESSION
947
    CHECK A DISCARDED EXPRESSION
933
 
948
 
934
    This routine checks whether discarding the expression e should be
949
    This routine checks whether discarding the expression e should be
935
    warned about.
950
    warned about.
936
*/
951
*/
937
 
952
 
938
static int check_discard_exp
953
static int
939
    PROTO_N ( ( e ) )
-
 
940
    PROTO_T ( EXP e )
954
check_discard_exp(EXP e)
941
{
955
{
942
    if ( !IS_NULL_exp ( e ) ) {
956
	if (!IS_NULL_exp(e)) {
943
	switch ( TAG_exp ( e ) ) {
957
		switch (TAG_exp(e)) {
944
	    case exp_indir_tag : {
958
		case exp_indir_tag: {
945
		/* Ignore indirection expressions */
959
			/* Ignore indirection expressions */
946
		EXP a = DEREF_exp ( exp_indir_ptr ( e ) ) ;
960
			EXP a = DEREF_exp(exp_indir_ptr(e));
947
		return ( check_discard_exp ( a ) ) ;
961
			return (check_discard_exp(a));
948
	    }
962
		}
949
	    case exp_contents_tag : {
963
		case exp_contents_tag: {
950
		/* Ignore contents expressions */
964
			/* Ignore contents expressions */
951
		EXP a = DEREF_exp ( exp_contents_ptr ( e ) ) ;
965
			EXP a = DEREF_exp(exp_contents_ptr(e));
952
		return ( check_discard_exp ( a ) ) ;
966
			return (check_discard_exp(a));
953
	    }
967
		}
954
	    case exp_comma_tag : {
968
		case exp_comma_tag: {
955
		/* Examine final component of comma expression */
969
			/* Examine final component of comma expression */
956
		LIST ( EXP ) p = DEREF_list ( exp_comma_args ( e ) ) ;
970
			LIST(EXP) p = DEREF_list(exp_comma_args(e));
957
		EXP a = DEREF_exp ( HEAD_list ( END_list ( p ) ) ) ;
971
			EXP a = DEREF_exp(HEAD_list(END_list(p)));
958
		return ( check_discard_exp ( a ) ) ;
972
			return (check_discard_exp(a));
959
	    }
973
		}
960
	    case exp_postinc_tag : {
974
		case exp_postinc_tag:
961
		/* Discard postincrement expressions */
975
			/* Discard postincrement expressions */
962
		COPY_exp ( exp_postinc_value ( e ), NULL_exp ) ;
976
			COPY_exp(exp_postinc_value(e), NULL_exp);
963
		goto assign_lab ;
977
			goto assign_lab;
964
	    }
-
 
965
	    case exp_assign_tag :
978
		case exp_assign_tag:
966
	    case exp_init_tag :
979
		case exp_init_tag:
967
	    case exp_preinc_tag :
980
		case exp_preinc_tag:
968
	    case exp_decl_stmt_tag :
981
		case exp_decl_stmt_tag:
969
	    assign_lab : {
982
assign_lab:
970
		/* Assignments and declarations are allowed */
983
			/* Assignments and declarations are allowed */
971
		if ( !IS_NULL_id ( made_temporary ) ) {
984
			if (!IS_NULL_id(made_temporary)) {
972
		    report ( crt_loc, ERR_stmt_expr_discard_val () ) ;
985
				report(crt_loc, ERR_stmt_expr_discard_val());
-
 
986
			}
-
 
987
			break;
-
 
988
		case exp_func_tag:
-
 
989
			/* Discarded function return */
-
 
990
			report(crt_loc, ERR_stmt_expr_discard_func());
-
 
991
			break;
-
 
992
		case exp_func_id_tag: {
-
 
993
			/* Discarded function return */
-
 
994
			DECL_SPEC ds;
-
 
995
			IDENTIFIER id = DEREF_id(exp_func_id_id(e));
-
 
996
			if (IS_id_token(id)) {
-
 
997
				id = DEREF_id(id_token_alt(id));
-
 
998
			}
-
 
999
			ds = DEREF_dspec(id_storage(id));
-
 
1000
			if (!(ds & dspec_ignore)) {
-
 
1001
				ERROR err = ERR_expr_call_func(id);
-
 
1002
				ERROR err2 = ERR_stmt_expr_discard_func();
-
 
1003
				err = concat_error(err, err2);
-
 
1004
				report(crt_loc, err);
-
 
1005
			}
-
 
1006
			break;
973
		}
1007
		}
974
		break ;
1008
		default:
975
	    }
-
 
976
	    case exp_func_tag : {
-
 
977
		/* Discarded function return */
1009
			/* Discarded value */
978
		report ( crt_loc, ERR_stmt_expr_discard_func () ) ;
1010
			report(crt_loc, ERR_stmt_expr_discard_val());
979
		break ;
1011
			return (1);
980
	    }
-
 
981
	    case exp_func_id_tag : {
-
 
982
		/* Discarded function return */
-
 
983
		DECL_SPEC ds ;
-
 
984
		IDENTIFIER id = DEREF_id ( exp_func_id_id ( e ) ) ;
-
 
985
		if ( IS_id_token ( id ) ) {
-
 
986
		    id = DEREF_id ( id_token_alt ( id ) ) ;
-
 
987
		}
1012
		}
988
		ds = DEREF_dspec ( id_storage ( id ) ) ;
-
 
989
		if ( !( ds & dspec_ignore ) ) {
-
 
990
		    ERROR err = ERR_expr_call_func ( id ) ;
-
 
991
		    ERROR err2 = ERR_stmt_expr_discard_func () ;
-
 
992
		    err = concat_error ( err, err2 ) ;
-
 
993
		    report ( crt_loc, err ) ;
-
 
994
		}
-
 
995
		break ;
-
 
996
	    }
-
 
997
	    default : {
-
 
998
		/* Discarded value */
-
 
999
		report ( crt_loc, ERR_stmt_expr_discard_val () ) ;
-
 
1000
		return ( 1 ) ;
-
 
1001
	    }
-
 
1002
	}
1013
	}
1003
    }
-
 
1004
    return ( 0 ) ;
1014
	return (0);
1005
}
1015
}
1006
 
1016
 
1007
 
1017
 
1008
/*
1018
/*
1009
    CONSTRUCT AN EXPRESSION STATEMENT
1019
    CONSTRUCT AN EXPRESSION STATEMENT
1010
 
1020
 
1011
    This routine constructs an expression statement from the expression e.
1021
    This routine constructs an expression statement from the expression e.
1012
    This is basically an identity operation, however various reachability
1022
    This is basically an identity operation, however various reachability
1013
    and discarded value checks (which need to take account of certain
1023
    and discarded value checks (which need to take account of certain
1014
    special forms) are applied.
1024
    special forms) are applied.
1015
*/
1025
*/
1016
 
1026
 
1017
EXP make_exp_stmt
1027
EXP
1018
    PROTO_N ( ( e ) )
-
 
1019
    PROTO_T ( EXP e )
1028
make_exp_stmt(EXP e)
1020
{
1029
{
1021
    TYPE t ;
1030
	TYPE t;
1022
 
1031
 
1023
    /* Perform operand conversion */
1032
	/* Perform operand conversion */
1024
    if ( IS_NULL_exp ( e ) ) return ( e ) ;
1033
	if (IS_NULL_exp(e)) {
-
 
1034
		return (e);
-
 
1035
	}
1025
    e = convert_reference ( e, REF_NORMAL ) ;
1036
	e = convert_reference(e, REF_NORMAL);
1026
    made_temporary = NULL_id ;
1037
	made_temporary = NULL_id;
1027
    e = make_discard_exp ( e ) ;
1038
	e = make_discard_exp(e);
1028
 
1039
 
1029
    /* Check the type of e */
1040
	/* Check the type of e */
1030
    t = DEREF_type ( exp_type ( e ) ) ;
1041
	t = DEREF_type(exp_type(e));
1031
    switch ( TAG_type ( t ) ) {
1042
	switch (TAG_type(t)) {
1032
	case type_bottom_tag : {
1043
	case type_bottom_tag:
1033
	    /* Unreached code */
1044
		/* Unreached code */
1034
	    unreached_code = 1 ;
1045
		unreached_code = 1;
1035
	    return ( e ) ;
1046
		return (e);
1036
	}
-
 
1037
	case type_top_tag :
1047
	case type_top_tag:
1038
	case type_error_tag : {
1048
	case type_error_tag:
1039
	    /* No effect */
1049
		/* No effect */
1040
	    return ( e ) ;
1050
		return (e);
1041
	}
-
 
1042
	case type_token_tag : {
1051
	case type_token_tag:
1043
	    /* Check for template types */
1052
		/* Check for template types */
1044
	    if ( is_templ_type ( t ) ) {
1053
		if (is_templ_type(t)) {
1045
		MAKE_exp_op ( t, lex_discard, e, NULL_exp, e ) ;
1054
			MAKE_exp_op(t, lex_discard, e, NULL_exp, e);
1046
		return ( e ) ;
1055
			return (e);
1047
	    }
1056
		}
1048
	    break ;
1057
		break;
1049
	}
1058
	}
1050
    }
-
 
1051
 
1059
 
1052
    /* Check discarded value */
1060
	/* Check discarded value */
1053
    if ( check_discard_exp ( e ) ) {
1061
	if (check_discard_exp(e)) {
1054
	MAKE_exp_cast ( type_void, CONV_ELLIPSIS, e, e ) ;
1062
		MAKE_exp_cast(type_void, CONV_ELLIPSIS, e, e);
1055
    }
1063
	}
1056
    return ( e ) ;
1064
	return (e);
1057
}
1065
}
1058
 
1066
 
1059
 
1067
 
1060
/*
1068
/*
1061
    CURRENT CONDITION
1069
    CURRENT CONDITION
Line 1064... Line 1072...
1064
    in the current conditional or iteration statement.  There are four
1072
    in the current conditional or iteration statement.  There are four
1065
    possible values corresponding to true, false and interminate constant
1073
    possible values corresponding to true, false and interminate constant
1066
    conditions, plus non-constant conditions.
1074
    conditions, plus non-constant conditions.
1067
*/
1075
*/
1068
 
1076
 
1069
unsigned crt_condition = BOOL_INVALID ;
1077
unsigned crt_condition = BOOL_INVALID;
1070
 
1078
 
1071
 
1079
 
1072
/*
1080
/*
1073
    CHECK A CONDITION
1081
    CHECK A CONDITION
1074
 
1082
 
Line 1076... Line 1084...
1076
    including setting the value of crt_condition.  Note that the condition
1084
    including setting the value of crt_condition.  Note that the condition
1077
    can be a condition declaration or the null expression (indicating an
1085
    can be a condition declaration or the null expression (indicating an
1078
    absent condition in a for-statement).  In the former case the
1086
    absent condition in a for-statement).  In the former case the
1079
    declaration is returned via pd.  op denotes the context for the
1087
    declaration is returned via pd.  op denotes the context for the
1080
    condition (an if-statement etc.).
1088
    condition (an if-statement etc.).
1081
*/
1089
*/
1082
 
1090
 
1083
EXP check_cond
1091
EXP
1084
    PROTO_N ( ( cond, pd, op ) )
-
 
1085
    PROTO_T ( EXP cond X EXP *pd X int op )
1092
check_cond(EXP cond, EXP *pd, int op)
1086
{
1093
{
1087
    EXP c ;
1094
	EXP c;
1088
    TYPE tc ;
1095
	TYPE tc;
1089
    unsigned ca ;
1096
	unsigned ca;
1090
    unsigned cc ;
1097
	unsigned cc;
1091
    unsigned tag ;
1098
	unsigned tag;
1092
    EXP a = NULL_exp ;
1099
	EXP a = NULL_exp;
1093
    ERROR err = NULL_err ;
1100
	ERROR err = NULL_err;
1094
 
1101
 
1095
    /* Check for null expressions */
1102
	/* Check for null expressions */
1096
    if ( IS_NULL_exp ( cond ) ) {
1103
	if (IS_NULL_exp(cond)) {
1097
	c = make_bool_exp ( BOOL_TRUE, exp_int_lit_tag ) ;
1104
		c = make_bool_exp(BOOL_TRUE, exp_int_lit_tag);
1098
	crt_condition = BOOL_TRUE ;
1105
		crt_condition = BOOL_TRUE;
1099
	if ( record_location && op != lex_cond_Hop ) {
1106
		if (record_location && op != lex_cond_Hop) {
1100
	    /* Mark position of condition */
1107
			/* Mark position of condition */
1101
	    TYPE t = DEREF_type ( exp_type ( c ) ) ;
1108
			TYPE t = DEREF_type(exp_type(c));
1102
	    MAKE_exp_location ( t, crt_loc, c, c ) ;
1109
			MAKE_exp_location(t, crt_loc, c, c);
1103
	}
1110
		}
1104
	return ( c ) ;
1111
		return (c);
1105
    }
1112
	}
1106
 
1113
 
1107
    /* Check for condition declarations */
1114
	/* Check for condition declarations */
1108
    tag = TAG_exp ( cond ) ;
1115
	tag = TAG_exp(cond);
1109
    if ( tag == exp_paren_tag ) {
1116
	if (tag == exp_paren_tag) {
1110
	TYPE t ;
1117
		TYPE t;
1111
	DESTROY_exp_paren ( destroy, t, cond, cond ) ;
1118
		DESTROY_exp_paren(destroy, t, cond, cond);
1112
	UNUSED ( t ) ;
1119
		UNUSED(t);
1113
    }
1120
	}
1114
    if ( IS_exp_decl_stmt ( cond ) ) {
1121
	if (IS_exp_decl_stmt(cond)) {
1115
	DECL_SPEC ds ;
1122
		DECL_SPEC ds;
1116
	IDENTIFIER id ;
1123
		IDENTIFIER id;
1117
	*pd = cond ;
1124
		*pd = cond;
1118
	do {
1125
		do {
1119
	    /* Step over temporary variables */
1126
			/* Step over temporary variables */
1120
	    id = DEREF_id ( exp_decl_stmt_id ( cond ) ) ;
1127
			id = DEREF_id(exp_decl_stmt_id(cond));
1121
	    cond = DEREF_exp ( exp_decl_stmt_body ( cond ) ) ;
1128
			cond = DEREF_exp(exp_decl_stmt_body(cond));
1122
	} while ( IS_exp_decl_stmt ( cond ) ) ;
1129
		} while (IS_exp_decl_stmt(cond));
1123
	ds = DEREF_dspec ( id_storage ( id ) ) ;
1130
		ds = DEREF_dspec(id_storage(id));
1124
	if ( IS_id_variable ( id ) && !( ds & dspec_temp ) ) {
1131
		if (IS_id_variable(id) && !(ds & dspec_temp)) {
1125
	    /* This doesn't count as a use of id */
1132
			/* This doesn't count as a use of id */
1126
	    EXP b = DEREF_exp ( id_variable_init ( id ) ) ;
1133
			EXP b = DEREF_exp(id_variable_init(id));
1127
	    TYPE t = DEREF_type ( id_variable_type ( id ) ) ;
1134
			TYPE t = DEREF_type(id_variable_type(id));
1128
	    if ( !IS_NULL_exp ( b ) ) {
1135
			if (!IS_NULL_exp(b)) {
1129
		if ( !IS_type_compound ( t ) ) {
1136
				if (!IS_type_compound(t)) {
1130
		    /* Condition value is used in constant checks */
1137
					/* Condition value is used in constant
-
 
1138
					 * checks */
1131
		    a = convert_boolean ( b, exp_paren_tag, KILL_err ) ;
1139
					a = convert_boolean(b, exp_paren_tag,
-
 
1140
							    KILL_err);
1132
		}
1141
				}
1133
		if ( op == lex_while || op == lex_for ) {
1142
				if (op == lex_while || op == lex_for) {
1134
		    /* Move initialisation into loop condition */
1143
					/* Move initialisation into loop
-
 
1144
					 * condition */
1135
		    MAKE_exp_init ( t, id, b, cond ) ;
1145
					MAKE_exp_init(t, id, b, cond);
1136
		    COPY_exp ( id_variable_init ( id ), NULL_exp ) ;
1146
					COPY_exp(id_variable_init(id),
-
 
1147
						 NULL_exp);
1137
		    ds |= dspec_explicit ;
1148
					ds |= dspec_explicit;
1138
		    COPY_dspec ( id_storage ( id ), ds ) ;
1149
					COPY_dspec(id_storage(id), ds);
1139
		} else {
1150
				} else {
1140
		    MAKE_exp_identifier ( t, id, qual_none, cond ) ;
1151
					MAKE_exp_identifier(t, id, qual_none,
-
 
1152
							    cond);
1141
		}
1153
				}
1142
	    } else {
1154
			} else {
1143
		MAKE_exp_identifier ( t, id, qual_none, cond ) ;
1155
				MAKE_exp_identifier(t, id, qual_none, cond);
1144
	    }
1156
			}
1145
	}
1157
		}
1146
    }
1158
	}
1147
 
1159
 
1148
    /* Convert the condition to a boolean */
1160
	/* Convert the condition to a boolean */
1149
    c = convert_reference ( cond, REF_NORMAL ) ;
1161
	c = convert_reference(cond, REF_NORMAL);
1150
    tc = DEREF_type ( exp_type ( c ) ) ;
1162
	tc = DEREF_type(exp_type(c));
1151
    ca = type_category ( &tc ) ;
1163
	ca = type_category(&tc);
1152
    if ( IS_TYPE_CLASS ( ca ) ) {
1164
	if (IS_TYPE_CLASS(ca)) {
1153
	/* Allow for conversion functions */
1165
		/* Allow for conversion functions */
1154
	c = convert_conv ( type_bool, c, &err, CAST_IMPLICIT ) ;
1166
		c = convert_conv(type_bool, c, &err, CAST_IMPLICIT);
1155
    } else if ( IS_TYPE_TEMPL ( ca ) ) {
1167
	} else if (IS_TYPE_TEMPL(ca)) {
1156
	/* Allow for template parameters */
1168
		/* Allow for template parameters */
1157
	MAKE_exp_op ( type_bool, op, c, NULL_exp, c ) ;
1169
		MAKE_exp_op(type_bool, op, c, NULL_exp, c);
1158
    } else {
-
 
1159
	/* Simple conversions */
-
 
1160
	c = convert_lvalue ( c ) ;
-
 
1161
	c = convert_boolean ( c, tag, &err ) ;
-
 
1162
    }
-
 
1163
    if ( !IS_NULL_err ( err ) ) {
-
 
1164
	ERROR err2 ;
-
 
1165
	switch ( op ) {
-
 
1166
	    case lex_if : err2 = ERR_stmt_if_cond () ; break ;
-
 
1167
	    case lex_do : err2 = ERR_stmt_do_cond () ; break ;
-
 
1168
	    case lex_for : err2 = ERR_stmt_for_cond () ; break ;
-
 
1169
	    case lex_while : err2 = ERR_stmt_while_cond () ; break ;
-
 
1170
	    case lex_cond_Hop : err2 = ERR_expr_cond_bool () ; break ;
-
 
1171
	    default : err2 = NULL_err ; break ;
-
 
1172
	}
-
 
1173
	err = concat_error ( err, err2 ) ;
-
 
1174
	report ( crt_loc, err ) ;
-
 
1175
    }
-
 
1176
 
-
 
1177
    /* Check for constant conditions */
-
 
1178
    if ( IS_NULL_exp ( a ) ) a = c ;
-
 
1179
    cc = eval_const_cond ( a ) ;
-
 
1180
    if ( cc != BOOL_INVALID ) {
-
 
1181
	if ( op == lex_if ) {
-
 
1182
	    /* Report determinate constants in if statements */
-
 
1183
	    if ( cc != BOOL_UNKNOWN ) {
-
 
1184
		report ( crt_loc, ERR_stmt_if_const () ) ;
-
 
1185
	    }
-
 
1186
	} else if ( op == lex_cond_Hop ) {
-
 
1187
	    /* Similarly for conditional expressions */
-
 
1188
	    if ( cc != BOOL_UNKNOWN ) {
-
 
1189
		report ( crt_loc, ERR_expr_cond_const () ) ;
-
 
1190
	    }
-
 
1191
	} else {
1170
	} else {
-
 
1171
		/* Simple conversions */
-
 
1172
		c = convert_lvalue(c);
-
 
1173
		c = convert_boolean(c, tag, &err);
-
 
1174
	}
-
 
1175
	if (!IS_NULL_err(err)) {
-
 
1176
		ERROR err2;
-
 
1177
		switch (op) {
-
 
1178
		case lex_if:
-
 
1179
			err2 = ERR_stmt_if_cond();
-
 
1180
			break;
-
 
1181
		case lex_do:
-
 
1182
			err2 = ERR_stmt_do_cond();
-
 
1183
			break;
-
 
1184
		case lex_for:
-
 
1185
			err2 = ERR_stmt_for_cond();
-
 
1186
			break;
-
 
1187
		case lex_while:
-
 
1188
			err2 = ERR_stmt_while_cond();
-
 
1189
			break;
-
 
1190
		case lex_cond_Hop:
-
 
1191
			err2 = ERR_expr_cond_bool();
-
 
1192
			break;
-
 
1193
		default:
-
 
1194
			err2 = NULL_err;
-
 
1195
			break;
-
 
1196
		}
-
 
1197
		err = concat_error(err, err2);
-
 
1198
		report(crt_loc, err);
-
 
1199
	}
-
 
1200
 
-
 
1201
	/* Check for constant conditions */
-
 
1202
	if (IS_NULL_exp(a)) {
-
 
1203
		a = c;
-
 
1204
	}
-
 
1205
	cc = eval_const_cond(a);
-
 
1206
	if (cc != BOOL_INVALID) {
-
 
1207
		if (op == lex_if) {
-
 
1208
			/* Report determinate constants in if statements */
-
 
1209
			if (cc != BOOL_UNKNOWN) {
-
 
1210
				report(crt_loc, ERR_stmt_if_const());
-
 
1211
			}
-
 
1212
		} else if (op == lex_cond_Hop) {
-
 
1213
			/* Similarly for conditional expressions */
-
 
1214
			if (cc != BOOL_UNKNOWN) {
-
 
1215
				report(crt_loc, ERR_expr_cond_const());
-
 
1216
			}
-
 
1217
		} else {
1192
	    /* Report non-literal constants in iteration statements */
1218
			/* Report non-literal constants in iteration
-
 
1219
			 * statements */
1193
	    if ( !is_literal ( a ) ) {
1220
			if (!is_literal(a)) {
1194
		ERROR err2 ;
1221
				ERROR err2;
1195
		switch ( op ) {
1222
				switch (op) {
-
 
1223
				case lex_do:
1196
		    case lex_do : err2 = ERR_stmt_do_const () ; break ;
1224
					err2 = ERR_stmt_do_const();
-
 
1225
					break;
-
 
1226
				case lex_for:
1197
		    case lex_for : err2 = ERR_stmt_for_const () ; break ;
1227
					err2 = ERR_stmt_for_const();
-
 
1228
					break;
-
 
1229
				case lex_while:
1198
		    case lex_while : err2 = ERR_stmt_while_const () ; break ;
1230
					err2 = ERR_stmt_while_const();
-
 
1231
					break;
-
 
1232
				default:
1199
		    default : err2 = NULL_err ; break ;
1233
					err2 = NULL_err;
-
 
1234
					break;
-
 
1235
				}
-
 
1236
				report(crt_loc, err2);
-
 
1237
			}
1200
		}
1238
		}
1201
		report ( crt_loc, err2 ) ;
-
 
1202
	    }
-
 
1203
	}
1239
	}
1204
    }
-
 
1205
    crt_condition = cc ;
1240
	crt_condition = cc;
1206
    if ( record_location && op != lex_cond_Hop ) {
1241
	if (record_location && op != lex_cond_Hop) {
1207
	/* Mark position of condition */
1242
		/* Mark position of condition */
1208
	TYPE t = DEREF_type ( exp_type ( c ) ) ;
1243
		TYPE t = DEREF_type(exp_type(c));
1209
	MAKE_exp_location ( t, crt_loc, c, c ) ;
1244
		MAKE_exp_location(t, crt_loc, c, c);
1210
    }
1245
	}
1211
    return ( c ) ;
1246
	return (c);
1212
}
1247
}
1213
 
1248
 
1214
 
1249
 
1215
/*
1250
/*
1216
    CHECK A CONDITIONAL BODY
1251
    CHECK A CONDITIONAL BODY
1217
 
1252
 
1218
    This routine is called following a conditional or loop statement
1253
    This routine is called following a conditional or loop statement
1219
    (given by op) to check for suspicious empty bodies which may be
1254
    (given by op) to check for suspicious empty bodies which may be
1220
    due to a misplaced semicolon.
1255
    due to a misplaced semicolon.
1221
*/
1256
*/
1222
 
1257
 
1223
void check_empty_stmt
1258
void
1224
    PROTO_N ( ( op ) )
-
 
1225
    PROTO_T ( int op )
1259
check_empty_stmt(int op)
1226
{
1260
{
1227
    if ( !suppress_quality ) {
1261
	if (!suppress_quality) {
1228
	int t = crt_lex_token ;
1262
		int t = crt_lex_token;
1229
	if ( t == lex_semicolon ) {
1263
		if (t == lex_semicolon) {
1230
	    PPTOKEN *p = crt_token ;
1264
			PPTOKEN *p = crt_token;
1231
	    NAMESPACE ns = crt_lookup ;
1265
			NAMESPACE ns = crt_lookup;
1232
	    t = next_token () ;
1266
			t = next_token();
1233
	    if ( t == lex_open_Hbrace_H1 ) {
1267
			if (t == lex_open_Hbrace_H1) {
1234
		/* Have 'op ; {', probably mean 'op {' */
1268
				/* Have 'op ; {', probably mean 'op {' */
1235
		report ( crt_loc, ERR_stmt_stmt_empty ( op ) ) ;
1269
				report(crt_loc, ERR_stmt_stmt_empty(op));
1236
	    }
1270
			}
1237
	    crt_lookup = ns ;
1271
			crt_lookup = ns;
1238
	    crt_token = p ;
1272
			crt_token = p;
-
 
1273
		}
1239
	}
1274
	}
1240
    }
-
 
1241
    return ;
1275
	return;
1242
}
1276
}
1243
 
1277
 
1244
 
1278
 
1245
/*
1279
/*
1246
    CREATE A CONDITION DECLARATION
1280
    CREATE A CONDITION DECLARATION
1247
 
1281
 
1248
    This routine combines the condition declaration d with its associated
1282
    This routine combines the condition declaration d with its associated
1249
    condition e.  If tmp is true a temporary variable is introduced for
1283
    condition e.  If tmp is true a temporary variable is introduced for
1250
    the value of e.
1284
    the value of e.
1251
*/
1285
*/
1252
 
1286
 
1253
static EXP make_cond_decl
1287
static EXP
1254
    PROTO_N ( ( d, e, tmp ) )
-
 
1255
    PROTO_T ( EXP d X EXP e X int tmp )
1288
make_cond_decl(EXP d, EXP e, int tmp)
1256
{
1289
{
1257
    EXP b ;
1290
	EXP b;
1258
    EXP c = d ;
1291
	EXP c = d;
1259
    if ( tmp ) {
1292
	if (tmp) {
1260
	/* Introduce temporary variable */
1293
		/* Introduce temporary variable */
1261
	ERROR err = NULL_err ;
1294
		ERROR err = NULL_err;
1262
	TYPE t = DEREF_type ( exp_type ( e ) ) ;
1295
		TYPE t = DEREF_type(exp_type(e));
1263
	e = make_temporary ( t, e, NULL_exp, 0, &err ) ;
1296
		e = make_temporary(t, e, NULL_exp, 0, &err);
1264
	if ( !IS_NULL_err ( err ) ) report ( crt_loc, err ) ;
1297
		if (!IS_NULL_err(err)) {
-
 
1298
			report(crt_loc, err);
1265
    }
1299
		}
-
 
1300
	}
1266
    for ( ; ; ) {
1301
	for (;;) {
1267
	b = DEREF_exp ( exp_decl_stmt_body ( c ) ) ;
1302
		b = DEREF_exp(exp_decl_stmt_body(c));
1268
	if ( !IS_exp_decl_stmt ( b ) ) break ;
1303
		if (!IS_exp_decl_stmt(b)) {
-
 
1304
			break;
-
 
1305
		}
1269
	c = b ;
1306
		c = b;
1270
    }
1307
	}
1271
    if ( IS_exp_sequence ( b ) ) free_exp ( b, 0 ) ;
1308
	if (IS_exp_sequence(b)) {
-
 
1309
		free_exp(b, 0);
-
 
1310
	}
1272
    COPY_exp ( exp_decl_stmt_body ( c ), e ) ;
1311
	COPY_exp(exp_decl_stmt_body(c), e);
1273
    set_parent_stmt ( e, c ) ;
1312
	set_parent_stmt(e, c);
1274
    if ( tmp ) {
1313
	if (tmp) {
1275
	/* Result is contents of temporary variable */
1314
		/* Result is contents of temporary variable */
1276
	e = make_id_exp ( made_temporary ) ;
1315
		e = make_id_exp(made_temporary);
1277
	e = convert_reference ( e, REF_NORMAL ) ;
1316
		e = convert_reference(e, REF_NORMAL);
1278
	e = convert_lvalue ( e ) ;
1317
		e = convert_lvalue(e);
1279
	d = join_exp ( d, e ) ;
1318
		d = join_exp(d, e);
1280
    }
1319
	}
1281
    return ( d ) ;
1320
	return (d);
1282
}
1321
}
1283
 
1322
 
1284
 
1323
 
1285
/*
1324
/*
1286
    FIND A CONDITIONAL STATEMENT
1325
    FIND A CONDITIONAL STATEMENT
1287
 
1326
 
1288
    This routine finds the conditional statement associated with e.
1327
    This routine finds the conditional statement associated with e.
1289
    e may contain an enclosing condition declaration.
1328
    e may contain an enclosing condition declaration.
1290
*/
1329
*/
1291
 
1330
 
1292
static EXP find_cond_stmt
1331
static EXP
1293
    PROTO_N ( ( e ) )
-
 
1294
    PROTO_T ( EXP e )
1332
find_cond_stmt(EXP e)
1295
{
1333
{
1296
    unsigned tag = TAG_exp ( e ) ;
1334
	unsigned tag = TAG_exp(e);
1297
    while ( tag == exp_decl_stmt_tag ) {
1335
	while (tag == exp_decl_stmt_tag) {
1298
	e = DEREF_exp ( exp_decl_stmt_body ( e ) ) ;
1336
		e = DEREF_exp(exp_decl_stmt_body(e));
1299
	tag = TAG_exp ( e ) ;
1337
		tag = TAG_exp(e);
1300
    }
1338
	}
1301
    while ( tag == exp_sequence_tag ) {
1339
	while (tag == exp_sequence_tag) {
1302
	LIST ( EXP ) p = DEREF_list ( exp_sequence_first ( e ) ) ;
1340
		LIST(EXP)p = DEREF_list(exp_sequence_first(e));
1303
	p = TAIL_list ( p ) ;
1341
		p = TAIL_list(p);
1304
	e = DEREF_exp ( HEAD_list ( p ) ) ;
1342
		e = DEREF_exp(HEAD_list(p));
1305
	tag = TAG_exp ( e ) ;
1343
		tag = TAG_exp(e);
1306
	if ( tag == exp_location_tag ) {
1344
		if (tag == exp_location_tag) {
1307
	    e = DEREF_exp ( exp_location_arg ( e ) ) ;
1345
			e = DEREF_exp(exp_location_arg(e));
1308
	    tag = TAG_exp ( e ) ;
1346
			tag = TAG_exp(e);
-
 
1347
		}
1309
	}
1348
	}
1310
    }
-
 
1311
    return ( e ) ;
1349
	return (e);
1312
}
1350
}
1313
 
1351
 
1314
 
1352
 
1315
/*
1353
/*
1316
    BEGIN AN IF STATEMENT
1354
    BEGIN AN IF STATEMENT
Line 1318... Line 1356...
1318
    This routine begins the construction of an if statement with condition
1356
    This routine begins the construction of an if statement with condition
1319
    cond.  In this and all routines involving a condition, a constant true
1357
    cond.  In this and all routines involving a condition, a constant true
1320
    condition is replaced by the null expression.
1358
    condition is replaced by the null expression.
1321
*/
1359
*/
1322
 
1360
 
1323
EXP begin_if_stmt
1361
EXP
1324
    PROTO_N ( ( cond ) )
-
 
1325
    PROTO_T ( EXP cond )
1362
begin_if_stmt(EXP cond)
1326
{
1363
{
1327
    EXP e ;
1364
	EXP e;
1328
    EXP d = NULL_exp ;
1365
	EXP d = NULL_exp;
1329
    EXP b = begin_label_stmt ( NULL_id, lex_if ) ;
1366
	EXP b = begin_label_stmt(NULL_id, lex_if);
1330
    IDENTIFIER lab = DEREF_id ( exp_label_stmt_label ( b ) ) ;
1367
	IDENTIFIER lab = DEREF_id(exp_label_stmt_label(b));
1331
 
1368
 
1332
    /* Check the condition */
1369
	/* Check the condition */
1333
    cond = check_cond ( cond, &d, lex_if ) ;
1370
	cond = check_cond(cond, &d, lex_if);
1334
    if ( crt_condition == BOOL_FALSE ) unreached_code = 1 ;
1371
	if (crt_condition == BOOL_FALSE) {
-
 
1372
		unreached_code = 1;
-
 
1373
	}
1335
 
1374
 
1336
    /* Construct the result */
1375
	/* Construct the result */
1337
    MAKE_exp_if_stmt ( type_void, cond, NULL_exp, NULL_exp, lab, e ) ;
1376
	MAKE_exp_if_stmt(type_void, cond, NULL_exp, NULL_exp, lab, e);
1338
    check_empty_stmt ( lex_if ) ;
1377
	check_empty_stmt(lex_if);
1339
    set_parent_stmt ( b, e ) ;
1378
	set_parent_stmt(b, e);
-
 
1379
	if (!IS_NULL_exp(d)) {
1340
    if ( !IS_NULL_exp ( d ) ) e = make_cond_decl ( d, e, 0 ) ;
1380
		e = make_cond_decl(d, e, 0);
-
 
1381
	}
1341
    return ( e ) ;
1382
	return (e);
1342
}
1383
}
1343
 
1384
 
1344
 
1385
 
1345
/*
1386
/*
1346
    CONTINUE AN IF STATEMENT
1387
    CONTINUE AN IF STATEMENT
1347
 
1388
 
1348
    This routine continues the construction of an if statement by adding
1389
    This routine continues the construction of an if statement by adding
1349
    the statement, right, which is evaluated if the condition is true.
1390
    the statement, right, which is evaluated if the condition is true.
1350
    This is called just before any else clause is processed.
1391
    This is called just before any else clause is processed.
1351
*/
1392
*/
1352
 
1393
 
1353
EXP cont_if_stmt
1394
EXP
1354
    PROTO_N ( ( prev, right ) )
-
 
1355
    PROTO_T ( EXP prev X EXP right )
1395
cont_if_stmt(EXP prev, EXP right)
1356
{
1396
{
1357
    /* Do unreached code analysis */
1397
	/* Do unreached code analysis */
1358
    EXP e ;
1398
	EXP e;
1359
    if ( crt_condition == BOOL_TRUE ) {
1399
	if (crt_condition == BOOL_TRUE) {
1360
	unreached_code = 1 ;
1400
		unreached_code = 1;
1361
    } else {
1401
	} else {
1362
	unreached_code = unreached_prev ;
1402
		unreached_code = unreached_prev;
1363
    }
1403
	}
1364
 
1404
 
1365
    /* Copy the right code into the conditional */
1405
	/* Copy the right code into the conditional */
1366
    e = find_cond_stmt ( prev ) ;
1406
	e = find_cond_stmt(prev);
1367
    COPY_exp ( exp_if_stmt_true_code ( e ), right ) ;
1407
	COPY_exp(exp_if_stmt_true_code(e), right);
1368
    set_parent_stmt ( right, e ) ;
1408
	set_parent_stmt(right, e);
1369
    return ( prev ) ;
1409
	return (prev);
1370
}
1410
}
1371
 
1411
 
1372
 
1412
 
1373
/*
1413
/*
1374
    COMPLETE AN IF STATEMENT
1414
    COMPLETE AN IF STATEMENT
1375
 
1415
 
1376
    This routine completes the construction of an if statement by adding
1416
    This routine completes the construction of an if statement by adding
1377
    the statement, wrong, which is evaluated if the condition is false.
1417
    the statement, wrong, which is evaluated if the condition is false.
1378
*/
1418
*/
1379
 
1419
 
1380
EXP end_if_stmt
1420
EXP
1381
    PROTO_N ( ( prev, wrong ) )
-
 
1382
    PROTO_T ( EXP prev X EXP wrong )
1421
end_if_stmt(EXP prev, EXP wrong)
1383
{
1422
{
1384
    /* Do unreached code analysis */
1423
	/* Do unreached code analysis */
1385
    EXP e = find_cond_stmt ( prev ) ;
1424
	EXP e = find_cond_stmt(prev);
1386
    EXP right = DEREF_exp ( exp_if_stmt_true_code ( e ) ) ;
1425
	EXP right = DEREF_exp(exp_if_stmt_true_code(e));
1387
    if ( is_bottom ( wrong ) ) {
1426
	if (is_bottom(wrong)) {
1388
	if ( is_bottom ( right ) ) {
1427
		if (is_bottom(right)) {
1389
	    /* Don't reach the end of either branch */
1428
			/* Don't reach the end of either branch */
1390
	    COPY_type ( exp_type ( prev ), type_bottom ) ;
1429
			COPY_type(exp_type(prev), type_bottom);
1391
	    COPY_type ( exp_type ( e ), type_bottom ) ;
1430
			COPY_type(exp_type(e), type_bottom);
1392
	    unreached_code = 1 ;
1431
			unreached_code = 1;
1393
	} else if ( crt_condition == BOOL_FALSE ) {
1432
		} else if (crt_condition == BOOL_FALSE) {
-
 
1433
			/* Don't reach the end of the taken branch */
-
 
1434
			COPY_type(exp_type(e), type_bottom);
-
 
1435
			unreached_code = 1;
-
 
1436
		} else {
-
 
1437
			/* Reach the end of one branch */
-
 
1438
			unreached_code = unreached_prev;
-
 
1439
		}
-
 
1440
	} else if (is_bottom(right)) {
-
 
1441
		if (crt_condition == BOOL_TRUE) {
1394
	    /* Don't reach the end of the taken branch */
1442
			/* Don't reach the end of the taken branch */
-
 
1443
			COPY_type(exp_type(prev), type_bottom);
1395
	    COPY_type ( exp_type ( e ), type_bottom ) ;
1444
			COPY_type(exp_type(e), type_bottom);
1396
	    unreached_code = 1 ;
1445
			unreached_code = 1;
-
 
1446
		} else {
-
 
1447
			/* Reach the end of one branch */
-
 
1448
			unreached_code = unreached_prev;
-
 
1449
		}
1397
	} else {
1450
	} else {
1398
	    /* Reach the end of one branch */
1451
		/* Reach the end of both branches */
1399
	    unreached_code = unreached_prev ;
1452
		unreached_code = unreached_prev;
1400
	}
1453
	}
1401
    } else if ( is_bottom ( right ) ) {
-
 
1402
	if ( crt_condition == BOOL_TRUE ) {
-
 
1403
	    /* Don't reach the end of the taken branch */
-
 
1404
	    COPY_type ( exp_type ( prev ), type_bottom ) ;
-
 
1405
	    COPY_type ( exp_type ( e ), type_bottom ) ;
-
 
1406
	    unreached_code = 1 ;
-
 
1407
	} else {
-
 
1408
	    /* Reach the end of one branch */
-
 
1409
	    unreached_code = unreached_prev ;
-
 
1410
	}
-
 
1411
    } else {
-
 
1412
	/* Reach the end of both branches */
-
 
1413
	unreached_code = unreached_prev ;
-
 
1414
    }
-
 
1415
 
1454
 
1416
    /* Copy the wrong code into the conditional */
1455
	/* Copy the wrong code into the conditional */
1417
    COPY_exp ( exp_if_stmt_false_code ( e ), wrong ) ;
1456
	COPY_exp(exp_if_stmt_false_code(e), wrong);
1418
    set_parent_stmt ( wrong, e ) ;
1457
	set_parent_stmt(wrong, e);
1419
    return ( prev ) ;
1458
	return (prev);
1420
}
1459
}
1421
 
1460
 
1422
 
1461
 
1423
/*
1462
/*
1424
    STACK OF CURRENTLY ACTIVE ITERATION AND SWITCH STATEMENTS
1463
    STACK OF CURRENTLY ACTIVE ITERATION AND SWITCH STATEMENTS
Line 1426... Line 1465...
1426
    This stack is used to record a nested list of iteration and switch
1465
    This stack is used to record a nested list of iteration and switch
1427
    statements in order to determine which statement a break, continue,
1466
    statements in order to determine which statement a break, continue,
1428
    case or default refers to.
1467
    case or default refers to.
1429
*/
1468
*/
1430
 
1469
 
1431
STACK ( EXP ) crt_loop_stack = NULL_stack ( EXP ) ;
1470
STACK(EXP) crt_loop_stack = NULL_stack(EXP);
1432
 
1471
 
1433
 
1472
 
1434
/*
1473
/*
1435
    BEGIN A DO STATEMENT
1474
    BEGIN A DO STATEMENT
1436
 
1475
 
1437
    This routine begins the construction of a do statement.
1476
    This routine begins the construction of a do statement.
1438
*/
1477
*/
1439
 
1478
 
1440
EXP begin_do_stmt
1479
EXP
1441
    PROTO_Z ()
1480
begin_do_stmt(void)
1442
{
1481
{
1443
    EXP e ;
1482
	EXP e;
1444
 
1483
 
1445
    /* Construct the break and continue destinations */
1484
	/* Construct the break and continue destinations */
1446
    EXP bk = begin_label_stmt ( NULL_id, lex_break ) ;
1485
	EXP bk = begin_label_stmt(NULL_id, lex_break);
1447
    EXP cn = begin_label_stmt ( NULL_id, lex_continue ) ;
1486
	EXP cn = begin_label_stmt(NULL_id, lex_continue);
1448
    EXP lp = begin_label_stmt ( NULL_id, lex_do ) ;
1487
	EXP lp = begin_label_stmt(NULL_id, lex_do);
1449
    IDENTIFIER bk_lab = DEREF_id ( exp_label_stmt_label ( bk ) ) ;
1488
	IDENTIFIER bk_lab = DEREF_id(exp_label_stmt_label(bk));
1450
    IDENTIFIER cn_lab = DEREF_id ( exp_label_stmt_label ( cn ) ) ;
1489
	IDENTIFIER cn_lab = DEREF_id(exp_label_stmt_label(cn));
1451
    IDENTIFIER lp_lab = DEREF_id ( exp_label_stmt_label ( lp ) ) ;
1490
	IDENTIFIER lp_lab = DEREF_id(exp_label_stmt_label(lp));
1452
 
1491
 
1453
    /* Construct the do statement */
1492
	/* Construct the do statement */
1454
    MAKE_exp_do_stmt ( type_void, NULL_exp, bk_lab, cn_lab, lp_lab, e ) ;
1493
	MAKE_exp_do_stmt(type_void, NULL_exp, bk_lab, cn_lab, lp_lab, e);
1455
    set_parent_stmt ( bk, e ) ;
1494
	set_parent_stmt(bk, e);
1456
    set_parent_stmt ( cn, e ) ;
1495
	set_parent_stmt(cn, e);
1457
    set_parent_stmt ( lp, e ) ;
1496
	set_parent_stmt(lp, e);
1458
 
1497
 
1459
    /* Add statement to loop stack */
1498
	/* Add statement to loop stack */
1460
    PUSH_exp ( e, crt_loop_stack ) ;
1499
	PUSH_exp(e, crt_loop_stack);
1461
    return ( e ) ;
1500
	return (e);
1462
}
1501
}
1463
 
1502
 
1464
 
1503
 
1465
/*
1504
/*
1466
    COMPLETE A DO STATEMENT
1505
    COMPLETE A DO STATEMENT
1467
 
1506
 
1468
    This routine completes the construction of the do statement prev
1507
    This routine completes the construction of the do statement prev
1469
    using the statement body and the condition cond.
1508
    using the statement body and the condition cond.
1470
*/
1509
*/
1471
 
1510
 
1472
EXP end_do_stmt
1511
EXP
1473
    PROTO_N ( ( prev, body, cond ) )
-
 
1474
    PROTO_T ( EXP prev X EXP body X EXP cond )
1512
end_do_stmt(EXP prev, EXP body, EXP cond)
1475
{
1513
{
1476
    int uc ;
1514
	int uc;
1477
    IDENTIFIER bk ;
1515
	IDENTIFIER bk;
1478
    EXP d = NULL_exp ;
1516
	EXP d = NULL_exp;
1479
 
1517
 
1480
    /* Remove statement from loop stack */
1518
	/* Remove statement from loop stack */
1481
    EXP e ;
1519
	EXP e;
1482
    POP_exp ( e, crt_loop_stack ) ;
1520
	POP_exp(e, crt_loop_stack);
1483
    UNUSED ( e ) ;
1521
	UNUSED(e);
1484
 
1522
 
1485
    /* Convert the condition to a boolean */
1523
	/* Convert the condition to a boolean */
1486
    cond = check_cond ( cond, &d, lex_do ) ;
1524
	cond = check_cond(cond, &d, lex_do);
-
 
1525
	if (!IS_NULL_exp(d)) {
1487
    if ( !IS_NULL_exp ( d ) ) cond = make_cond_decl ( d, cond, 1 ) ;
1526
		cond = make_cond_decl(d, cond, 1);
-
 
1527
	}
1488
 
1528
 
1489
    /* Find whether the condition is reached */
1529
	/* Find whether the condition is reached */
1490
    uc = unreached_code ;
1530
	uc = unreached_code;
1491
    if ( uc ) {
1531
	if (uc) {
1492
	IDENTIFIER cn = DEREF_id ( exp_do_stmt_cont_lab ( prev ) ) ;
1532
		IDENTIFIER cn = DEREF_id(exp_do_stmt_cont_lab(prev));
1493
	if ( used_label ( cn ) == 1 ) {
1533
		if (used_label(cn) == 1) {
1494
	    /* Reached using a continue */
1534
			/* Reached using a continue */
1495
	    uc = unreached_prev ;
1535
			uc = unreached_prev;
1496
	} else {
1536
		} else {
1497
	    /* Report unreached code */
1537
			/* Report unreached code */
1498
	    if ( !unreached_last ) {
1538
			if (!unreached_last) {
1499
		report ( crt_loc, ERR_stmt_stmt_unreach () ) ;
1539
				report(crt_loc, ERR_stmt_stmt_unreach());
1500
		unreached_last = 1 ;
1540
				unreached_last = 1;
1501
	    }
1541
			}
1502
	}
1542
		}
1503
    }
1543
	}
1504
 
1544
 
1505
    /* Find whether the following statement is reached */
1545
	/* Find whether the following statement is reached */
1506
    bk = DEREF_id ( exp_do_stmt_break_lab ( prev ) ) ;
1546
	bk = DEREF_id(exp_do_stmt_break_lab(prev));
1507
    COPY_loc ( id_loc ( bk ), crt_loc ) ;
1547
	COPY_loc(id_loc(bk), crt_loc);
1508
    if ( crt_condition == BOOL_TRUE ) uc = 1 ;
1548
	if (crt_condition == BOOL_TRUE) {
-
 
1549
		uc = 1;
-
 
1550
	}
1509
    if ( uc ) {
1551
	if (uc) {
1510
	if ( used_label ( bk ) == 1 ) {
1552
		if (used_label(bk) == 1) {
1511
	    /* Can reach next statement using break */
1553
			/* Can reach next statement using break */
1512
	    uc = unreached_prev ;
1554
			uc = unreached_prev;
1513
	} else {
1555
		} else {
1514
	    COPY_type ( exp_type ( prev ), type_bottom ) ;
1556
			COPY_type(exp_type(prev), type_bottom);
1515
	}
1557
		}
1516
    }
1558
	}
1517
    unreached_code = uc ;
1559
	unreached_code = uc;
1518
 
1560
 
1519
    /* Fill in the gaps in the do statement */
1561
	/* Fill in the gaps in the do statement */
1520
    COPY_exp ( exp_do_stmt_cond ( prev ), cond ) ;
1562
	COPY_exp(exp_do_stmt_cond(prev), cond);
1521
    COPY_exp ( exp_do_stmt_body ( prev ), body ) ;
1563
	COPY_exp(exp_do_stmt_body(prev), body);
1522
    set_parent_stmt ( body, prev ) ;
1564
	set_parent_stmt(body, prev);
1523
    return ( prev ) ;
1565
	return (prev);
1524
}
1566
}
1525
 
1567
 
1526
 
1568
 
1527
/*
1569
/*
1528
    BEGIN A FOR STATEMENT
1570
    BEGIN A FOR STATEMENT
1529
 
1571
 
1530
    The construction of a for statement is in four stages, given by the
1572
    The construction of a for statement is in four stages, given by the
1531
    following four routines.  A statement of the form:
1573
    following four routines.  A statement of the form:
1532
 
1574
 
Line 1547... Line 1589...
1547
    do not form a scope - or rather they don't until after the init).
1589
    do not form a scope - or rather they don't until after the init).
1548
    This routine, begin_for_stmt, creates the initial compound statement.
1590
    This routine, begin_for_stmt, creates the initial compound statement.
1549
    The next, init_for_stmt, adds init to this compound.  The third,
1591
    The next, init_for_stmt, adds init to this compound.  The third,
1550
    cond_for_stmt, creates the while loop from cond and body.  Finally
1592
    cond_for_stmt, creates the while loop from cond and body.  Finally
1551
    end_for_stmt fills in the body and completes the construction.
1593
    end_for_stmt fills in the body and completes the construction.
1552
*/
1594
*/
1553
 
1595
 
-
 
1596
EXP
1554
EXP begin_for_stmt
1597
begin_for_stmt(void)
1555
    PROTO_Z ()
-
 
1556
{
1598
{
1557
    EXP e ;
1599
	EXP e;
1558
    int scope = 0 ;
1600
	int scope = 0;
1559
    if ( option ( OPT_for_scope ) == OPTION_ON ) scope = 1 ;
1601
	if (option(OPT_for_scope) == OPTION_ON) {
-
 
1602
		scope = 1;
-
 
1603
	}
1560
    e = begin_compound_stmt ( scope ) ;
1604
	e = begin_compound_stmt(scope);
1561
    return ( e ) ;
1605
	return (e);
1562
}
1606
}
1563
 
1607
 
1564
 
1608
 
1565
/*
1609
/*
1566
    ADD AN INITIAL STATEMENT TO A FOR STATEMENT
1610
    ADD AN INITIAL STATEMENT TO A FOR STATEMENT
1567
 
1611
 
1568
    This routine adds the initial statement pointed to by init to the for
1612
    This routine adds the initial statement pointed to by init to the for
1569
    statement prev (see above).  If the initial statement is a declaration
1613
    statement prev (see above).  If the initial statement is a declaration
1570
    then the declaration statement is only created during this routine
1614
    then the declaration statement is only created during this routine
1571
    (init is the null expression).  In this case init is set to point to
1615
    (init is the null expression).  In this case init is set to point to
1572
    the declaration statement created.
1616
    the declaration statement created.
1573
*/
1617
*/
1574
 
1618
 
1575
EXP init_for_stmt
1619
EXP
1576
    PROTO_N ( ( prev, init ) )
-
 
1577
    PROTO_T ( EXP prev X EXP *init )
1620
init_for_stmt(EXP prev, EXP *init)
1578
{
1621
{
1579
    EXP stmt = *init ;
1622
	EXP stmt = *init;
1580
    NAMESPACE ns = DEREF_nspace ( exp_sequence_decl ( prev ) ) ;
1623
	NAMESPACE ns = DEREF_nspace(exp_sequence_decl(prev));
1581
    if ( !IS_NULL_nspace ( ns ) ) {
1624
	if (!IS_NULL_nspace(ns)) {
1582
	/* Add any declarations to the block */
1625
		/* Add any declarations to the block */
1583
	MEMBER p = DEREF_member ( nspace_last ( ns ) ) ;
1626
		MEMBER p = DEREF_member(nspace_last(ns));
1584
	MEMBER q = DEREF_member ( nspace_prev ( ns ) ) ;
1627
		MEMBER q = DEREF_member(nspace_prev(ns));
1585
	if ( !EQ_member ( p, q ) ) {
1628
		if (!EQ_member(p, q)) {
1586
	    /* Create declaration statement */
1629
			/* Create declaration statement */
1587
	    int vars = 0 ;
1630
			int vars = 0;
1588
	    EXP decl = make_decl_stmt ( p, q, &vars ) ;
1631
			EXP decl = make_decl_stmt(p, q, &vars);
1589
	    prev = extend_compound_stmt ( prev, decl, 0 ) ;
1632
			prev = extend_compound_stmt(prev, decl, 0);
1590
	    COPY_member ( nspace_prev ( ns ), p ) ;
1633
			COPY_member(nspace_prev(ns), p);
1591
	    *init = decl ;
1634
			*init = decl;
-
 
1635
		}
-
 
1636
	} else {
-
 
1637
		/* Defer declarations to enclosing block */
-
 
1638
		NAMESPACE cns = crt_namespace;
-
 
1639
		ns = make_namespace(crt_func_id, nspace_block_tag, 0);
-
 
1640
		push_namespace(ns);
-
 
1641
		if (do_scope) {
-
 
1642
			dump_begin_scope(NULL_id, ns, cns, &crt_loc);
-
 
1643
		}
-
 
1644
		COPY_nspace(exp_sequence_decl(prev), ns);
-
 
1645
		IGNORE incr_value(OPT_VAL_statement_depth);
-
 
1646
	}
-
 
1647
	if (!IS_NULL_exp(stmt)) {
-
 
1648
		/* Add the new statement */
-
 
1649
		prev = extend_compound_stmt(prev, stmt, 1);
1592
	}
1650
	}
1593
    } else {
-
 
1594
	/* Defer declarations to enclosing block */
-
 
1595
	NAMESPACE cns = crt_namespace ;
-
 
1596
	ns = make_namespace ( crt_func_id, nspace_block_tag, 0 ) ;
-
 
1597
	push_namespace ( ns ) ;
-
 
1598
	if ( do_scope ) dump_begin_scope ( NULL_id, ns, cns, &crt_loc ) ;
-
 
1599
	COPY_nspace ( exp_sequence_decl ( prev ), ns ) ;
-
 
1600
	IGNORE incr_value ( OPT_VAL_statement_depth ) ;
-
 
1601
    }
-
 
1602
    if ( !IS_NULL_exp ( stmt ) ) {
-
 
1603
	/* Add the new statement */
-
 
1604
	prev = extend_compound_stmt ( prev, stmt, 1 ) ;
-
 
1605
    }
-
 
1606
    adjusted_line = 0 ;
1651
	adjusted_line = 0;
1607
    return ( prev ) ;
1652
	return (prev);
1608
}
1653
}
1609
 
1654
 
1610
 
1655
 
1611
/*
1656
/*
1612
    ADD A CONDITION TO A FOR STATEMENT
1657
    ADD A CONDITION TO A FOR STATEMENT
1613
 
1658
 
1614
    This routine adds the condition and step statements, cond and step, to
1659
    This routine adds the condition and step statements, cond and step, to
1615
    the for statement prev (see above).  Note that cond is wrapped in a
1660
    the for statement prev (see above).  Note that cond is wrapped in a
1616
    location expression.
1661
    location expression.
1617
*/
1662
*/
1618
 
1663
 
1619
EXP cond_for_stmt
1664
EXP
1620
    PROTO_N ( ( prev, cond, step ) )
-
 
1621
    PROTO_T ( EXP prev X EXP cond X EXP step )
1665
cond_for_stmt(EXP prev, EXP cond, EXP step)
1622
{
1666
{
1623
    EXP e ;
1667
	EXP e;
1624
    TYPE t ;
1668
	TYPE t;
1625
    LOCATION loc ;
1669
	LOCATION loc;
1626
    EXP d = NULL_exp ;
1670
	EXP d = NULL_exp;
1627
 
1671
 
1628
    /* Construct the break and continue destinations */
1672
	/* Construct the break and continue destinations */
1629
    EXP bk = begin_label_stmt ( NULL_id, lex_break ) ;
1673
	EXP bk = begin_label_stmt(NULL_id, lex_break);
1630
    EXP cn = begin_label_stmt ( NULL_id, lex_continue ) ;
1674
	EXP cn = begin_label_stmt(NULL_id, lex_continue);
1631
    EXP lp = begin_label_stmt ( NULL_id, lex_for ) ;
1675
	EXP lp = begin_label_stmt(NULL_id, lex_for);
1632
    IDENTIFIER bk_lab = DEREF_id ( exp_label_stmt_label ( bk ) ) ;
1676
	IDENTIFIER bk_lab = DEREF_id(exp_label_stmt_label(bk));
1633
    IDENTIFIER cn_lab = DEREF_id ( exp_label_stmt_label ( cn ) ) ;
1677
	IDENTIFIER cn_lab = DEREF_id(exp_label_stmt_label(cn));
1634
    IDENTIFIER lp_lab = DEREF_id ( exp_label_stmt_label ( lp ) ) ;
1678
	IDENTIFIER lp_lab = DEREF_id(exp_label_stmt_label(lp));
1635
 
1679
 
1636
    /* Convert condition to a boolean */
1680
	/* Convert condition to a boolean */
1637
    bad_crt_loc++ ;
1681
	bad_crt_loc++;
1638
    loc = crt_loc ;
1682
	loc = crt_loc;
1639
    DESTROY_exp_location ( destroy, t, crt_loc, cond, cond ) ;
1683
	DESTROY_exp_location(destroy, t, crt_loc, cond, cond);
1640
    cond = check_cond ( cond, &d, lex_for ) ;
1684
	cond = check_cond(cond, &d, lex_for);
1641
    if ( crt_condition == BOOL_FALSE ) unreached_code = 1 ;
1685
	if (crt_condition == BOOL_FALSE) {
-
 
1686
		unreached_code = 1;
-
 
1687
	}
1642
    crt_loc = loc ;
1688
	crt_loc = loc;
1643
    bad_crt_loc-- ;
1689
	bad_crt_loc--;
1644
    UNUSED ( t ) ;
1690
	UNUSED(t);
1645
 
1691
 
1646
    /* Deal with the step statement */
1692
	/* Deal with the step statement */
1647
    if ( !IS_NULL_exp ( step ) ) {
1693
	if (!IS_NULL_exp(step)) {
1648
	if ( record_location ) {
1694
		if (record_location) {
1649
	    t = DEREF_type ( exp_type ( step ) ) ;
1695
			t = DEREF_type(exp_type(step));
1650
	    MAKE_exp_location ( t, stmt_loc, step, step ) ;
1696
			MAKE_exp_location(t, stmt_loc, step, step);
1651
	}
1697
		}
1652
	IGNORE end_label_stmt ( cn, step ) ;
1698
		IGNORE end_label_stmt(cn, step);
1653
    }
1699
	}
1654
 
1700
 
1655
    /* Construct the while statement */
1701
	/* Construct the while statement */
1656
    MAKE_exp_while_stmt ( type_void, cond, bk_lab, cn_lab, lp_lab, e ) ;
1702
	MAKE_exp_while_stmt(type_void, cond, bk_lab, cn_lab, lp_lab, e);
1657
    set_parent_stmt ( bk, e ) ;
1703
	set_parent_stmt(bk, e);
1658
    set_parent_stmt ( cn, e ) ;
1704
	set_parent_stmt(cn, e);
1659
    set_parent_stmt ( lp, e ) ;
1705
	set_parent_stmt(lp, e);
1660
    check_empty_stmt ( lex_for ) ;
1706
	check_empty_stmt(lex_for);
1661
 
1707
 
1662
    /* Add statement to loop stack */
1708
	/* Add statement to loop stack */
1663
    PUSH_exp ( e, crt_loop_stack ) ;
1709
	PUSH_exp(e, crt_loop_stack);
1664
 
1710
 
1665
    /* Add to for statement */
1711
	/* Add to for statement */
1666
    if ( !IS_NULL_exp ( d ) ) {
1712
	if (!IS_NULL_exp(d)) {
1667
	EXP c = d ;
1713
		EXP c = d;
1668
	LIST ( IDENTIFIER ) cids = NULL_list ( IDENTIFIER ) ;
1714
		LIST(IDENTIFIER) cids = NULL_list(IDENTIFIER);
1669
	while ( !IS_NULL_exp ( c ) && IS_exp_decl_stmt ( c ) ) {
1715
		while (!IS_NULL_exp(c) && IS_exp_decl_stmt(c)) {
1670
	    IDENTIFIER cid = DEREF_id ( exp_decl_stmt_id ( c ) ) ;
1716
			IDENTIFIER cid = DEREF_id(exp_decl_stmt_id(c));
1671
	    CONS_id ( cid, cids, cids ) ;
1717
			CONS_id(cid, cids, cids);
1672
	    c = DEREF_exp ( exp_decl_stmt_body ( c ) ) ;
1718
			c = DEREF_exp(exp_decl_stmt_body(c));
1673
	}
1719
		}
1674
	COPY_list ( exp_while_stmt_cond_id ( e ), cids ) ;
1720
		COPY_list(exp_while_stmt_cond_id(e), cids);
1675
	d = make_cond_decl ( d, e, 0 ) ;
1721
		d = make_cond_decl(d, e, 0);
1676
	e = d ;
1722
		e = d;
1677
    }
1723
	}
1678
    e = add_compound_stmt ( prev, e ) ;
1724
	e = add_compound_stmt(prev, e);
1679
    return ( e ) ;
1725
	return (e);
1680
}
1726
}
1681
 
1727
 
1682
 
1728
 
1683
/*
1729
/*
1684
    END A FOR STATEMENT
1730
    END A FOR STATEMENT
1685
 
1731
 
1686
    This routine completes the construction of the for statement prev by
1732
    This routine completes the construction of the for statement prev by
1687
    adding the body statement, body (see above).
1733
    adding the body statement, body (see above).
1688
*/
1734
*/
1689
 
1735
 
-
 
1736
EXP
-
 
1737
end_for_stmt(EXP prev, EXP body)
-
 
1738
{
-
 
1739
	TYPE t;
-
 
1740
	LIST(EXP) stmts = DEREF_list(exp_sequence_last(prev));
-
 
1741
	EXP stmt = DEREF_exp(HEAD_list(stmts));
1690
EXP end_for_stmt
1742
	if (IS_exp_location(stmt)) {
-
 
1743
		EXP e = DEREF_exp(exp_location_arg(stmt));
1691
    PROTO_N ( ( prev, body ) )
1744
		e = end_while_stmt(e, body);
-
 
1745
		t = DEREF_type(exp_type(e));
-
 
1746
		COPY_exp(exp_location_arg(stmt), e);
-
 
1747
	} else {
1692
    PROTO_T ( EXP prev X EXP body )
1748
		EXP e = end_while_stmt(stmt, body);
-
 
1749
		t = DEREF_type(exp_type(e));
-
 
1750
		COPY_exp(HEAD_list(stmts), e);
-
 
1751
	}
-
 
1752
	prev = end_compound_stmt(prev);
-
 
1753
	COPY_type(exp_type(prev), t);
-
 
1754
 
-
 
1755
	/* Mark for-init variables as private */
-
 
1756
	if (option(OPT_for_scope) == OPTION_WARN) {
-
 
1757
		NAMESPACE ns = crt_namespace;
-
 
1758
		MEMBER p = DEREF_member(nspace_last(ns));
-
 
1759
		MEMBER q = DEREF_member(nspace_prev(ns));
-
 
1760
		while (!EQ_member(p, q)) {
-
 
1761
			IDENTIFIER id = DEREF_id(member_id(p));
-
 
1762
			if (!IS_NULL_id(id) && IS_id_variable(id)) {
-
 
1763
				DECL_SPEC ds = DEREF_dspec(id_storage(id));
-
 
1764
				if (ds & dspec_auto) {
-
 
1765
					ds |= dspec_private;
-
 
1766
					COPY_dspec(id_storage(id), ds);
-
 
1767
				}
-
 
1768
			}
-
 
1769
			p = DEREF_member(member_next(p));
-
 
1770
		}
-
 
1771
	}
-
 
1772
	return (prev);
-
 
1773
}
-
 
1774
 
-
 
1775
 
-
 
1776
/*
-
 
1777
    BEGIN A WHILE STATEMENT
-
 
1778
 
-
 
1779
    This routine begins the construction of a while statement with
-
 
1780
    condition cond.
-
 
1781
*/
-
 
1782
 
-
 
1783
EXP
-
 
1784
begin_while_stmt(EXP cond)
1693
{
1785
{
1694
    TYPE t ;
1786
	EXP e;
1695
    LIST ( EXP ) stmts = DEREF_list ( exp_sequence_last ( prev ) ) ;
-
 
1696
    EXP stmt = DEREF_exp ( HEAD_list ( stmts ) ) ;
-
 
1697
    if ( IS_exp_location ( stmt ) ) {
-
 
1698
	EXP e = DEREF_exp ( exp_location_arg ( stmt ) ) ;
-
 
1699
	e = end_while_stmt ( e, body ) ;
-
 
1700
	t = DEREF_type ( exp_type ( e ) ) ;
-
 
1701
	COPY_exp ( exp_location_arg ( stmt ), e ) ;
-
 
1702
    } else {
1787
	EXP d = NULL_exp;
1703
	EXP e = end_while_stmt ( stmt, body ) ;
-
 
1704
	t = DEREF_type ( exp_type ( e ) ) ;
-
 
1705
	COPY_exp ( HEAD_list ( stmts ), e ) ;
-
 
1706
    }
-
 
1707
    prev = end_compound_stmt ( prev ) ;
-
 
1708
    COPY_type ( exp_type ( prev ), t ) ;
-
 
1709
 
1788
 
1710
    /* Mark for-init variables as private */
1789
	/* Construct the break and continue destinations */
1711
    if ( option ( OPT_for_scope ) == OPTION_WARN ) {
1790
	EXP bk = begin_label_stmt(NULL_id, lex_break);
1712
	NAMESPACE ns = crt_namespace ;
1791
	EXP cn = begin_label_stmt(NULL_id, lex_continue);
1713
	MEMBER p = DEREF_member ( nspace_last ( ns ) ) ;
1792
	EXP lp = begin_label_stmt(NULL_id, lex_while);
1714
	MEMBER q = DEREF_member ( nspace_prev ( ns ) ) ;
1793
	IDENTIFIER bk_lab = DEREF_id(exp_label_stmt_label(bk));
1715
	while ( !EQ_member ( p, q ) ) {
1794
	IDENTIFIER cn_lab = DEREF_id(exp_label_stmt_label(cn));
1716
	    IDENTIFIER id = DEREF_id ( member_id ( p ) ) ;
1795
	IDENTIFIER lp_lab = DEREF_id(exp_label_stmt_label(lp));
-
 
1796
 
-
 
1797
	/* Convert the condition to a boolean */
-
 
1798
	cond = check_cond(cond, &d, lex_while);
-
 
1799
	if (crt_condition == BOOL_FALSE) {
-
 
1800
		unreached_code = 1;
-
 
1801
	}
-
 
1802
 
-
 
1803
	/* Construct the while statement */
1717
	    if ( !IS_NULL_id ( id ) && IS_id_variable ( id ) ) {
1804
	MAKE_exp_while_stmt(type_void, cond, bk_lab, cn_lab, lp_lab, e);
-
 
1805
	set_parent_stmt(bk, e);
-
 
1806
	set_parent_stmt(cn, e);
-
 
1807
	set_parent_stmt(lp, e);
-
 
1808
	check_empty_stmt(lex_while);
-
 
1809
 
-
 
1810
	/* Add statement to loop stack */
-
 
1811
	PUSH_exp(e, crt_loop_stack);
-
 
1812
 
1718
		DECL_SPEC ds = DEREF_dspec ( id_storage ( id ) ) ;
1813
	/* Allow for condition declarations */
1719
		if ( ds & dspec_auto ) {
1814
	if (!IS_NULL_exp(d)) {
-
 
1815
		EXP c = d;
-
 
1816
		LIST(IDENTIFIER) cids = NULL_list(IDENTIFIER);
-
 
1817
		while (!IS_NULL_exp(c) && IS_exp_decl_stmt(c)) {
-
 
1818
			IDENTIFIER cid = DEREF_id(exp_decl_stmt_id(c));
1720
		    ds |= dspec_private ;
1819
			CONS_id(cid, cids, cids);
1721
		    COPY_dspec ( id_storage ( id ), ds ) ;
1820
			c = DEREF_exp(exp_decl_stmt_body(c));
1722
		}
1821
		}
-
 
1822
		COPY_list(exp_while_stmt_cond_id(e), cids);
-
 
1823
		d = make_cond_decl(d, e, 0);
1723
	    }
1824
		e = d;
1724
	    p = DEREF_member ( member_next ( p ) ) ;
-
 
1725
	}
1825
	}
1726
    }
-
 
1727
    return ( prev ) ;
1826
	return (e);
1728
}
1827
}
1729
 
-
 
1730
 
-
 
1731
/*
-
 
1732
    BEGIN A WHILE STATEMENT
-
 
1733
 
-
 
1734
    This routine begins the construction of a while statement with
-
 
1735
    condition cond.
-
 
1736
*/
-
 
1737
 
-
 
1738
EXP begin_while_stmt
-
 
1739
    PROTO_N ( ( cond ) )
-
 
1740
    PROTO_T ( EXP cond )
-
 
1741
{
-
 
1742
    EXP e ;
-
 
1743
    EXP d = NULL_exp ;
-
 
1744
 
-
 
1745
    /* Construct the break and continue destinations */
-
 
1746
    EXP bk = begin_label_stmt ( NULL_id, lex_break ) ;
-
 
1747
    EXP cn = begin_label_stmt ( NULL_id, lex_continue ) ;
-
 
1748
    EXP lp = begin_label_stmt ( NULL_id, lex_while ) ;
-
 
1749
    IDENTIFIER bk_lab = DEREF_id ( exp_label_stmt_label ( bk ) ) ;
-
 
1750
    IDENTIFIER cn_lab = DEREF_id ( exp_label_stmt_label ( cn ) ) ;
-
 
1751
    IDENTIFIER lp_lab = DEREF_id ( exp_label_stmt_label ( lp ) ) ;
-
 
1752
 
-
 
1753
    /* Convert the condition to a boolean */
-
 
1754
    cond = check_cond ( cond, &d, lex_while ) ;
-
 
1755
    if ( crt_condition == BOOL_FALSE ) unreached_code = 1 ;
-
 
1756
 
-
 
1757
    /* Construct the while statement */
-
 
1758
    MAKE_exp_while_stmt ( type_void, cond, bk_lab, cn_lab, lp_lab, e ) ;
-
 
1759
    set_parent_stmt ( bk, e ) ;
-
 
1760
    set_parent_stmt ( cn, e ) ;
-
 
1761
    set_parent_stmt ( lp, e ) ;
-
 
1762
    check_empty_stmt ( lex_while ) ;
-
 
1763
 
-
 
1764
    /* Add statement to loop stack */
-
 
1765
    PUSH_exp ( e, crt_loop_stack ) ;
-
 
1766
 
-
 
1767
    /* Allow for condition declarations */
-
 
1768
    if ( !IS_NULL_exp ( d ) ) {
-
 
1769
	EXP c = d ;
-
 
1770
	LIST ( IDENTIFIER ) cids = NULL_list ( IDENTIFIER ) ;
-
 
1771
	while ( !IS_NULL_exp ( c ) && IS_exp_decl_stmt ( c ) ) {
-
 
1772
	    IDENTIFIER cid = DEREF_id ( exp_decl_stmt_id ( c ) ) ;
-
 
1773
	    CONS_id ( cid, cids, cids ) ;
-
 
1774
	    c = DEREF_exp ( exp_decl_stmt_body ( c ) ) ;
-
 
1775
	}
-
 
1776
	COPY_list ( exp_while_stmt_cond_id ( e ), cids ) ;
-
 
1777
	d = make_cond_decl ( d, e, 0 ) ;
-
 
1778
	e = d ;
-
 
1779
    }
-
 
1780
    return ( e ) ;
-
 
1781
}
-
 
1782
 
1828
 
1783
 
1829
 
1784
/*
1830
/*
1785
    COMPLETE A WHILE STATEMENT
1831
    COMPLETE A WHILE STATEMENT
1786
 
1832
 
1787
    This routine completes the construction of the while statement prev
1833
    This routine completes the construction of the while statement prev
1788
    using the statement body.
1834
    using the statement body.
1789
*/
1835
*/
1790
 
1836
 
1791
EXP end_while_stmt
1837
EXP
1792
    PROTO_N ( ( prev, body ) )
-
 
1793
    PROTO_T ( EXP prev X EXP body )
1838
end_while_stmt(EXP prev, EXP body)
1794
{
1839
{
1795
    /* Remove statement from loop stack */
1840
	/* Remove statement from loop stack */
1796
    EXP e ;
1841
	EXP e;
1797
    IDENTIFIER bk ;
1842
	IDENTIFIER bk;
1798
    POP_exp ( e, crt_loop_stack ) ;
1843
	POP_exp(e, crt_loop_stack);
1799
    UNUSED ( e ) ;
1844
	UNUSED(e);
-
 
1845
 
-
 
1846
	/* Find whether the end of the body is reached */
-
 
1847
	e = find_cond_stmt(prev);
-
 
1848
	if (unreached_code) {
-
 
1849
		IDENTIFIER cn = DEREF_id(exp_while_stmt_cont_lab(e));
-
 
1850
		if (used_label(cn) == 1) {
-
 
1851
			/* Reached using a continue */
-
 
1852
			unreached_code = unreached_prev;
-
 
1853
		} else {
-
 
1854
			/* Check for unreached continuation statement */
-
 
1855
			LIST(EXP) step;
-
 
1856
			EXP cont = DEREF_exp(id_label_stmt(cn));
-
 
1857
			cont = DEREF_exp(exp_label_stmt_body(cont));
-
 
1858
			step = DEREF_list(exp_sequence_first(cont));
-
 
1859
			step = TAIL_list(step);
-
 
1860
			if (!IS_NULL_list(step)) {
-
 
1861
				LOCATION loc;
-
 
1862
				DEREF_loc(id_loc(cn), loc);
-
 
1863
				report(loc, ERR_stmt_stmt_unreach());
-
 
1864
			}
-
 
1865
		}
-
 
1866
	}
1800
 
1867
 
1801
    /* Find whether the end of the body is reached */
1868
	/* Find whether the following statement is reached */
1802
    e = find_cond_stmt ( prev ) ;
-
 
1803
    if ( unreached_code ) {
-
 
1804
	IDENTIFIER cn = DEREF_id ( exp_while_stmt_cont_lab ( e ) ) ;
1869
	bk = DEREF_id(exp_while_stmt_break_lab(e));
1805
	if ( used_label ( cn ) == 1 ) {
1870
	COPY_loc(id_loc(bk), crt_loc);
1806
	    /* Reached using a continue */
-
 
1807
	    unreached_code = unreached_prev ;
1871
	unreached_code = unreached_prev;
1808
	} else {
-
 
1809
	    /* Check for unreached continuation statement */
1872
	if (crt_condition == BOOL_TRUE) {
1810
	    LIST ( EXP ) step ;
1873
		if (used_label(bk) != 1) {
1811
	    EXP cont = DEREF_exp ( id_label_stmt ( cn ) ) ;
1874
			/* Infinite loop and no breaks */
1812
	    cont = DEREF_exp ( exp_label_stmt_body ( cont ) ) ;
1875
			COPY_type(exp_type(prev), type_bottom);
1813
	    step = DEREF_list ( exp_sequence_first ( cont ) ) ;
1876
			COPY_type(exp_type(e), type_bottom);
1814
	    step = TAIL_list ( step ) ;
-
 
1815
	    if ( !IS_NULL_list ( step ) ) {
-
 
1816
		LOCATION loc ;
1877
			unreached_code = 1;
1817
		DEREF_loc ( id_loc ( cn ), loc ) ;
-
 
1818
		report ( loc, ERR_stmt_stmt_unreach () ) ;
-
 
1819
	    }
1878
		}
1820
	}
1879
	}
1821
    }
-
 
1822
 
-
 
1823
    /* Find whether the following statement is reached */
-
 
1824
    bk = DEREF_id ( exp_while_stmt_break_lab ( e ) ) ;
-
 
1825
    COPY_loc ( id_loc ( bk ), crt_loc ) ;
-
 
1826
    unreached_code = unreached_prev ;
-
 
1827
    if ( crt_condition == BOOL_TRUE ) {
-
 
1828
	if ( used_label ( bk ) != 1 ) {
-
 
1829
	    /* Infinite loop and no breaks */
-
 
1830
	    COPY_type ( exp_type ( prev ), type_bottom ) ;
-
 
1831
	    COPY_type ( exp_type ( e ), type_bottom ) ;
-
 
1832
	    unreached_code = 1 ;
-
 
1833
	}
-
 
1834
    }
-
 
1835
 
1880
 
1836
    /* Copy the body into the result */
1881
	/* Copy the body into the result */
1837
    COPY_exp ( exp_while_stmt_body ( e ), body ) ;
1882
	COPY_exp(exp_while_stmt_body(e), body);
1838
    set_parent_stmt ( body, e ) ;
1883
	set_parent_stmt(body, e);
1839
    return ( prev ) ;
1884
	return (prev);
1840
}
1885
}
1841
 
1886
 
1842
 
1887
 
1843
/*
1888
/*
1844
    CONSTRUCT A BREAK STATEMENT
1889
    CONSTRUCT A BREAK STATEMENT
Line 1846... Line 1891...
1846
    This routine constructs a break statement.  Note that this must appear
1891
    This routine constructs a break statement.  Note that this must appear
1847
    inside an iteration or a switch statement.  It is implemented as a jump
1892
    inside an iteration or a switch statement.  It is implemented as a jump
1848
    to the break label.
1893
    to the break label.
1849
*/
1894
*/
1850
 
1895
 
-
 
1896
EXP
1851
EXP make_break_stmt
1897
make_break_stmt(void)
1852
    PROTO_Z ()
-
 
1853
{
1898
{
1854
    LIST ( EXP ) st = LIST_stack ( crt_loop_stack ) ;
1899
	LIST(EXP) st = LIST_stack(crt_loop_stack);
1855
    if ( !IS_NULL_list ( st ) ) {
1900
	if (!IS_NULL_list(st)) {
1856
	IDENTIFIER lab ;
1901
		IDENTIFIER lab;
1857
	EXP stmt = DEREF_exp ( HEAD_list ( st ) ) ;
1902
		EXP stmt = DEREF_exp(HEAD_list(st));
1858
	unsigned tag = TAG_exp ( stmt ) ;
1903
		unsigned tag = TAG_exp(stmt);
1859
	if ( tag == exp_while_stmt_tag ) {
1904
		if (tag == exp_while_stmt_tag) {
1860
	    lab = DEREF_id ( exp_while_stmt_break_lab ( stmt ) ) ;
1905
			lab = DEREF_id(exp_while_stmt_break_lab(stmt));
1861
	} else if ( tag == exp_do_stmt_tag ) {
1906
		} else if (tag == exp_do_stmt_tag) {
1862
	    lab = DEREF_id ( exp_do_stmt_break_lab ( stmt ) ) ;
1907
			lab = DEREF_id(exp_do_stmt_break_lab(stmt));
1863
	} else {
1908
		} else {
1864
	    lab = DEREF_id ( exp_switch_stmt_break_lab ( stmt ) ) ;
1909
			lab = DEREF_id(exp_switch_stmt_break_lab(stmt));
-
 
1910
		}
-
 
1911
		return (make_jump_stmt(lab, stmt));
1865
	}
1912
	}
1866
	return ( make_jump_stmt ( lab, stmt ) ) ;
-
 
1867
    }
-
 
1868
    report ( crt_loc, ERR_stmt_break_bad () ) ;
1913
	report(crt_loc, ERR_stmt_break_bad());
1869
    return ( NULL_exp ) ;
1914
	return (NULL_exp);
1870
}
1915
}
1871
 
1916
 
1872
 
1917
 
1873
/*
1918
/*
1874
    CONSTRUCT A CONTINUE STATEMENT
1919
    CONSTRUCT A CONTINUE STATEMENT
1875
 
1920
 
1876
    This routine constructs a continue statement.  Note that this must
1921
    This routine constructs a continue statement.  Note that this must
1877
    appear inside an iteration statement.  It is implemented as a jump to
1922
    appear inside an iteration statement.  It is implemented as a jump to
1878
    the continue label.
1923
    the continue label.
1879
*/
1924
*/
1880
 
1925
 
-
 
1926
EXP
1881
EXP make_continue_stmt
1927
make_continue_stmt(void)
1882
    PROTO_Z ()
-
 
1883
{
1928
{
1884
    LIST ( EXP ) st = LIST_stack ( crt_loop_stack ) ;
1929
	LIST(EXP) st = LIST_stack(crt_loop_stack);
1885
    while ( !IS_NULL_list ( st ) ) {
1930
	while (!IS_NULL_list(st)) {
1886
	EXP stmt = DEREF_exp ( HEAD_list ( st ) ) ;
1931
		EXP stmt = DEREF_exp(HEAD_list(st));
1887
	unsigned tag = TAG_exp ( stmt ) ;
1932
		unsigned tag = TAG_exp(stmt);
1888
	if ( tag == exp_switch_stmt_tag ) {
1933
		if (tag == exp_switch_stmt_tag) {
1889
	    /* Switch statements don't count for continues */
1934
			/* Switch statements don't count for continues */
1890
	    /* EMPTY */
1935
			/* EMPTY */
1891
	} else {
1936
		} else {
1892
	    /* Find continue destination label */
1937
			/* Find continue destination label */
1893
	    IDENTIFIER lab ;
1938
			IDENTIFIER lab;
1894
	    if ( tag == exp_while_stmt_tag ) {
1939
			if (tag == exp_while_stmt_tag) {
1895
		lab = DEREF_id ( exp_while_stmt_cont_lab ( stmt ) ) ;
1940
				lab = DEREF_id(exp_while_stmt_cont_lab(stmt));
1896
	    } else {
1941
			} else {
1897
		lab = DEREF_id ( exp_do_stmt_cont_lab ( stmt ) ) ;
1942
				lab = DEREF_id(exp_do_stmt_cont_lab(stmt));
1898
	    }
1943
			}
1899
	    return ( make_jump_stmt ( lab, stmt ) ) ;
1944
			return (make_jump_stmt(lab, stmt));
-
 
1945
		}
-
 
1946
		st = TAIL_list(st);
1900
	}
1947
	}
1901
	st = TAIL_list ( st ) ;
-
 
1902
    }
-
 
1903
    report ( crt_loc, ERR_stmt_cont_bad () ) ;
1948
	report(crt_loc, ERR_stmt_cont_bad());
1904
    return ( NULL_exp ) ;
1949
	return (NULL_exp);
1905
}
1950
}
1906
 
1951
 
1907
 
1952
 
1908
/*
1953
/*
1909
    CHECK A RETURN EXPRESSION
1954
    CHECK A RETURN EXPRESSION
Line 1911... Line 1956...
1911
    This routine checks the return expression a.  In particular returning
1956
    This routine checks the return expression a.  In particular returning
1912
    a reference to a local variable is detected.  It is also used to check
1957
    a reference to a local variable is detected.  It is also used to check
1913
    a throw expression (as indicated by op).
1958
    a throw expression (as indicated by op).
1914
*/
1959
*/
1915
 
1960
 
1916
EXP check_return_exp
1961
EXP
1917
    PROTO_N ( ( a, op ) )
-
 
1918
    PROTO_T ( EXP a X int op )
1962
check_return_exp(EXP a, int op)
1919
{
1963
{
1920
    if ( option ( OPT_ptr_operator ) ) {
1964
    if (option(OPT_ptr_operator)) {
1921
	EXP b = NULL_exp ;
1965
	EXP b = NULL_exp;
1922
	DECL_SPEC ds = find_exp_linkage ( a, &b, 1 ) ;
1966
	DECL_SPEC ds = find_exp_linkage(a, &b, 1);
1923
	if ( ds & dspec_auto ) {
1967
	if (ds & dspec_auto) {
1924
	    if ( IS_exp_identifier ( b ) ) {
1968
	    if (IS_exp_identifier(b)) {
1925
		IDENTIFIER id = DEREF_id ( exp_identifier_id ( b ) ) ;
1969
		IDENTIFIER id = DEREF_id(exp_identifier_id(b));
1926
		if ( IS_id_variable ( id ) ) {
1970
		if (IS_id_variable(id)) {
1927
		    TYPE t = DEREF_type ( id_variable_type ( id ) ) ;
1971
		    TYPE t = DEREF_type(id_variable_type(id));
1928
		    if ( !IS_type_ref ( t ) ) {
1972
		    if (!IS_type_ref(t)) {
1929
			report ( crt_loc, ERR_stmt_return_auto ( id, op ) ) ;
1973
			report(crt_loc, ERR_stmt_return_auto(id, op));
1930
		    }
1974
		    }
1931
		}
1975
		}
1932
	    }
1976
	    }
1933
	}
1977
	}
1934
    }
1978
    }
1935
    return ( a ) ;
1979
    return (a);
1936
}
1980
}
1937
 
1981
 
1938
 
1982
 
1939
/*
1983
/*
1940
    CONSTRUCT A RETURN EXPRESSION
1984
    CONSTRUCT A RETURN EXPRESSION
Line 1942... Line 1986...
1942
    This routine constructs the value for the statement 'return a'.  a can
1986
    This routine constructs the value for the statement 'return a'.  a can
1943
    be the null expression to indicate a plain 'return'.  op is lex_return
1987
    be the null expression to indicate a plain 'return'.  op is lex_return
1944
    to indicate explicit returns rather than the implicit return at the
1988
    to indicate explicit returns rather than the implicit return at the
1945
    end of the function.  If the return is via a jump then the label is
1989
    end of the function.  If the return is via a jump then the label is
1946
    assigned to lab.
1990
    assigned to lab.
1947
*/
1991
*/
1948
 
1992
 
1949
EXP find_return_exp
1993
EXP
1950
    PROTO_N ( ( a, lab, op ) )
-
 
1951
    PROTO_T ( EXP a X IDENTIFIER *lab X int op )
1994
find_return_exp(EXP a, IDENTIFIER *lab, int op)
1952
{
1995
{
1953
    TYPE r = crt_func_return ;
1996
	TYPE r = crt_func_return;
1954
    if ( !IS_NULL_exp ( a ) ) {
1997
	if (!IS_NULL_exp(a)) {
1955
	/* Apply reference conversion */
1998
		/* Apply reference conversion */
1956
	a = convert_reference ( a, REF_NORMAL ) ;
1999
		a = convert_reference(a, REF_NORMAL);
1957
    }
-
 
1958
    if ( IS_NULL_type ( r ) ) {
-
 
1959
	/* Not in a function definition */
-
 
1960
	IDENTIFIER id = crt_func_id ;
-
 
1961
	report ( crt_loc, ERR_token_stmt_ret ( id ) ) ;
-
 
1962
	if ( IS_NULL_exp ( a ) ) {
-
 
1963
	    r = type_void ;
-
 
1964
	} else {
-
 
1965
	    a = convert_lvalue ( a ) ;
-
 
1966
	    r = DEREF_type ( exp_type ( a ) ) ;
-
 
1967
	}
-
 
1968
    }
-
 
1969
    switch ( TAG_type ( r ) ) {
-
 
1970
 
-
 
1971
	case type_top_tag : {
-
 
1972
	    /* Function returns no value */
-
 
1973
	    if ( !IS_NULL_exp ( a ) ) {
-
 
1974
		IDENTIFIER id = crt_func_id ;
-
 
1975
		HASHID nm = DEREF_hashid ( id_name ( id ) ) ;
-
 
1976
		unsigned tag = TAG_hashid ( nm ) ;
-
 
1977
		if ( tag == hashid_constr_tag ) {
-
 
1978
		    report ( crt_loc, ERR_class_ctor_result ( id ) ) ;
-
 
1979
		} else if ( tag == hashid_destr_tag ) {
-
 
1980
		    report ( crt_loc, ERR_class_dtor_result ( id ) ) ;
-
 
1981
		    *lab = find_postlude_label () ;
-
 
1982
		} else {
-
 
1983
		    report ( crt_loc, ERR_stmt_return_none ( id, r ) ) ;
-
 
1984
		}
-
 
1985
	    }
-
 
1986
	    if ( in_func_handler == 2 ) {
-
 
1987
		/* In function-try-block handler */
-
 
1988
		IDENTIFIER id = crt_func_id ;
-
 
1989
		report ( crt_loc, ERR_except_handle_return ( id ) ) ;
-
 
1990
	    }
-
 
1991
	    break ;
-
 
1992
	}
-
 
1993
 
-
 
1994
	case type_bottom_tag : {
-
 
1995
	    /* Function should not return */
-
 
1996
	    IDENTIFIER id = crt_func_id ;
-
 
1997
	    if ( IS_NULL_exp ( a ) ) {
-
 
1998
		report ( crt_loc, ERR_stmt_return_bottom ( id, r ) ) ;
-
 
1999
	    } else {
-
 
2000
		report ( crt_loc, ERR_stmt_return_none ( id, r ) ) ;
-
 
2001
	    }
-
 
2002
	    break ;
-
 
2003
	}
-
 
2004
 
-
 
2005
	case type_token_tag : {
-
 
2006
	    /* Check for template types */
-
 
2007
	    if ( is_templ_type ( r ) ) {
-
 
2008
		MAKE_exp_op ( r, op, a, NULL_exp, a ) ;
-
 
2009
		break ;
-
 
2010
	    }
-
 
2011
	    goto default_lab ;
-
 
2012
	}
2000
	}
2013
 
-
 
2014
	default :
-
 
2015
	default_lab : {
2001
	if (IS_NULL_type(r)) {
2016
	    /* Function returns a value */
2002
		/* Not in a function definition */
2017
	    if ( IS_NULL_exp ( a ) ) {
-
 
2018
		IDENTIFIER id = crt_func_id ;
2003
		IDENTIFIER id = crt_func_id;
2019
		if ( op == lex_return ) {
2004
		report(crt_loc, ERR_token_stmt_ret(id));
2020
		    /* Explicit return statement */
2005
		if (IS_NULL_exp(a)) {
2021
		    report ( crt_loc, ERR_stmt_return_void ( id, r ) ) ;
-
 
2022
		    MAKE_exp_value ( r, a ) ;
2006
			r = type_void;
2023
		} else {
2007
		} else {
-
 
2008
			a = convert_lvalue(a);
-
 
2009
			r = DEREF_type(exp_type(a));
-
 
2010
		}
-
 
2011
	}
-
 
2012
	switch (TAG_type(r)) {
-
 
2013
	case type_top_tag:
2024
		    /* Implicit fall out of function */
2014
		/* Function returns no value */
-
 
2015
		if (!IS_NULL_exp(a)) {
-
 
2016
			IDENTIFIER id = crt_func_id;
2025
		    HASHID nm = DEREF_hashid ( id_name ( id ) ) ;
2017
			HASHID nm = DEREF_hashid(id_name(id));
2026
		    DECL_SPEC ds = DEREF_dspec ( id_storage ( id ) ) ;
2018
			unsigned tag = TAG_hashid(nm);
2027
		    if ( ( ds & dspec_main ) && IS_hashid_name ( nm ) ) {
2019
			if (tag == hashid_constr_tag) {
2028
			/* Implicit 'return 0' in main */
2020
				report(crt_loc, ERR_class_ctor_result(id));
2029
			ERROR err = ERR_basic_start_main_fall ( id, r ) ;
2021
			} else if (tag == hashid_destr_tag) {
2030
			report ( crt_loc, err ) ;
2022
				report(crt_loc, ERR_class_dtor_result(id));
2031
			MAKE_exp_null ( r, a ) ;
2023
				*lab = find_postlude_label();
2032
		    } else {
2024
			} else {
2033
			report ( crt_loc, ERR_stmt_return_fall ( id, r ) ) ;
2025
				report(crt_loc, ERR_stmt_return_none(id, r));
2034
			MAKE_exp_value ( r, a ) ;
-
 
2035
		    }
2026
			}
2036
		}
2027
		}
2037
	    } else {
-
 
2038
		/* Convert to result type by initialisation */
-
 
2039
		ERROR err = NULL_err ;
-
 
2040
		a = init_assign ( r, cv_none, a, &err ) ;
-
 
2041
		if ( !IS_NULL_err ( err ) ) {
2028
		if (in_func_handler == 2) {
2042
		    /* Bad return type */
2029
			/* In function-try-block handler */
2043
		    err = init_error ( err, 0 ) ;
2030
			IDENTIFIER id = crt_func_id;
2044
		    err = concat_error ( err, ERR_stmt_return_conv () ) ;
-
 
2045
		    report ( crt_loc, err ) ;
2031
			report(crt_loc, ERR_except_handle_return(id));
2046
		}
2032
		}
-
 
2033
		break;
-
 
2034
	case type_bottom_tag: {
-
 
2035
		/* Function should not return */
-
 
2036
		IDENTIFIER id = crt_func_id;
2047
		if ( crt_func_complex ) {
2037
		if (IS_NULL_exp(a)) {
2048
		    a = remove_temporary ( a, NULL_exp ) ;
2038
			report(crt_loc, ERR_stmt_return_bottom(id, r));
-
 
2039
		} else {
-
 
2040
			report(crt_loc, ERR_stmt_return_none(id, r));
2049
		}
2041
		}
2050
		a = check_return_exp ( a, lex_return ) ;
-
 
2051
	    }
2042
		break;
2052
	}
2043
	}
-
 
2044
	case type_token_tag:
-
 
2045
		/* Check for template types */
-
 
2046
		if (is_templ_type(r)) {
-
 
2047
			MAKE_exp_op(r, op, a, NULL_exp, a);
-
 
2048
			break;
-
 
2049
		}
-
 
2050
		goto default_lab;
-
 
2051
	default:
-
 
2052
default_lab:
-
 
2053
		/* Function returns a value */
-
 
2054
		if (IS_NULL_exp(a)) {
-
 
2055
			IDENTIFIER id = crt_func_id;
-
 
2056
			if (op == lex_return) {
-
 
2057
				/* Explicit return statement */
-
 
2058
				report(crt_loc, ERR_stmt_return_void(id, r));
-
 
2059
				MAKE_exp_value(r, a);
-
 
2060
			} else {
-
 
2061
				/* Implicit fall out of function */
-
 
2062
				HASHID nm = DEREF_hashid(id_name(id));
-
 
2063
				DECL_SPEC ds = DEREF_dspec(id_storage(id));
-
 
2064
				if ((ds & dspec_main) && IS_hashid_name(nm)) {
-
 
2065
					/* Implicit 'return 0' in main */
-
 
2066
					ERROR err =
-
 
2067
					    ERR_basic_start_main_fall(id, r);
-
 
2068
					report(crt_loc, err);
-
 
2069
					MAKE_exp_null(r, a);
-
 
2070
				} else {
-
 
2071
					report(crt_loc,
-
 
2072
					       ERR_stmt_return_fall(id, r));
-
 
2073
					MAKE_exp_value(r, a);
2053
    }
2074
				}
-
 
2075
			}
-
 
2076
		} else {
-
 
2077
			/* Convert to result type by initialisation */
-
 
2078
			ERROR err = NULL_err;
-
 
2079
			a = init_assign(r, cv_none, a, &err);
-
 
2080
			if (!IS_NULL_err(err)) {
-
 
2081
				/* Bad return type */
-
 
2082
				err = init_error(err, 0);
-
 
2083
				err = concat_error(err, ERR_stmt_return_conv());
-
 
2084
				report(crt_loc, err);
-
 
2085
			}
-
 
2086
			if (crt_func_complex) {
-
 
2087
				a = remove_temporary(a, NULL_exp);
-
 
2088
			}
-
 
2089
			a = check_return_exp(a, lex_return);
-
 
2090
		}
-
 
2091
	}
2054
    return ( a ) ;
2092
	return (a);
2055
}
2093
}
2056
 
2094
 
2057
 
2095
 
2058
/*
2096
/*
2059
    CONSTRUCT A RETURN STATEMENT
2097
    CONSTRUCT A RETURN STATEMENT
2060
 
2098
 
2061
    This routine constructs the return statement 'return a'.  op is as in
2099
    This routine constructs the return statement 'return a'.  op is as in
2062
    find_return_exp.
2100
    find_return_exp.
2063
*/
2101
*/
2064
 
2102
 
2065
EXP make_return_stmt
2103
EXP
2066
    PROTO_N ( ( a, op ) )
-
 
2067
    PROTO_T ( EXP a X int op )
2104
make_return_stmt(EXP a, int op)
2068
{
2105
{
2069
    IDENTIFIER lab = NULL_id ;
2106
	IDENTIFIER lab = NULL_id;
2070
    EXP e = find_return_exp ( a, &lab, op ) ;
2107
	EXP e = find_return_exp(a, &lab, op);
2071
    if ( IS_NULL_id ( lab ) ) {
2108
	if (IS_NULL_id(lab)) {
2072
	/* Construct return statement */
2109
		/* Construct return statement */
2073
	MAKE_exp_return_stmt ( type_bottom, e, e ) ;
2110
		MAKE_exp_return_stmt(type_bottom, e, e);
2074
    } else {
2111
	} else {
2075
	/* Jump to postlude label */
2112
		/* Jump to postlude label */
2076
	e = make_jump_stmt ( lab, NULL_exp ) ;
2113
		e = make_jump_stmt(lab, NULL_exp);
2077
    }
2114
	}
2078
    unreached_code = 1 ;
2115
	unreached_code = 1;
2079
    unreached_last = 0 ;
2116
	unreached_last = 0;
2080
    return ( e ) ;
2117
	return (e);
2081
}
2118
}
2082
 
2119
 
2083
 
2120
 
2084
/*
2121
/*
2085
    FALL OUT OF A FUNCTION DEFINITION
2122
    FALL OUT OF A FUNCTION DEFINITION
2086
 
2123
 
2087
    This routine is called at the end of a function definition to check
2124
    This routine is called at the end of a function definition to check
2088
    the implicit 'return' statement caused by falling out of the function.
2125
    the implicit 'return' statement caused by falling out of the function.
2089
*/
2126
*/
2090
 
2127
 
-
 
2128
EXP
2091
EXP fall_return_stmt
2129
fall_return_stmt(void)
2092
    PROTO_Z ()
-
 
2093
{
2130
{
2094
    EXP e = NULL_exp ;
2131
	EXP e = NULL_exp;
2095
    if ( !unreached_code ) {
2132
	if (!unreached_code) {
2096
	TYPE ret = crt_func_return ;
2133
		TYPE ret = crt_func_return;
2097
	if ( !IS_NULL_type ( ret ) && !IS_type_top ( ret ) ) {
2134
		if (!IS_NULL_type(ret) && !IS_type_top(ret)) {
2098
	    e = make_return_stmt ( NULL_exp, lex_fall ) ;
2135
			e = make_return_stmt(NULL_exp, lex_fall);
-
 
2136
		}
-
 
2137
	}
-
 
2138
	return (e);
-
 
2139
}
-
 
2140
 
-
 
2141
 
-
 
2142
/*
-
 
2143
    CHECK A SWITCH CONTROL EXPRESSION
-
 
2144
 
-
 
2145
    This routine checks the switch control expression cont.  pd is as in
-
 
2146
    check_cond and pb is used to return an enumeration or boolean control
-
 
2147
    expression.
-
 
2148
*/
-
 
2149
 
-
 
2150
EXP
-
 
2151
check_control(EXP cont, EXP *pd, EXP *pb)
-
 
2152
{
-
 
2153
	TYPE t;
-
 
2154
	int ok = 1;
-
 
2155
	unsigned c;
-
 
2156
	EXP a = NULL_exp;
-
 
2157
 
-
 
2158
	/* Check for condition declarations */
-
 
2159
	if (IS_exp_decl_stmt(cont)) {
-
 
2160
		IDENTIFIER id = DEREF_id(exp_decl_stmt_id(cont));
-
 
2161
		if (IS_id_variable(id)) {
-
 
2162
			*pd = cont;
-
 
2163
			t = DEREF_type(id_variable_type(id));
-
 
2164
			a = DEREF_exp(id_variable_init(id));
-
 
2165
			/* This doesn't count as a use of id */
-
 
2166
			MAKE_exp_identifier(t, id, qual_none, cont);
-
 
2167
		}
-
 
2168
	}
-
 
2169
 
-
 
2170
	/* Apply reference conversions to control */
-
 
2171
	cont = convert_reference(cont, REF_NORMAL);
-
 
2172
	t = DEREF_type(exp_type(cont));
-
 
2173
	c = type_category(&t);
-
 
2174
	if (IS_TYPE_INT(c)) {
-
 
2175
		/* Integral types are allowed */
-
 
2176
		/* EMPTY */
-
 
2177
	} else if (IS_TYPE_TEMPL(c)) {
-
 
2178
		/* Allow for template parameters */
-
 
2179
		MAKE_exp_op(t, lex_switch, cont, NULL_exp, cont);
-
 
2180
		ok = 0;
-
 
2181
	} else {
-
 
2182
		/* Allow for overloading */
-
 
2183
		ok = 0;
-
 
2184
		if (IS_TYPE_CLASS(c)) {
-
 
2185
			ERROR err = NULL_err;
-
 
2186
			a = convert_gen(CTYPE_INT, cont, &err);
-
 
2187
			if (!IS_NULL_exp(a)) {
-
 
2188
				if (!IS_NULL_err(err)) {
-
 
2189
					err = concat_error(err, ERR_stmt_switch_conv());
-
 
2190
					report(crt_loc, err);
-
 
2191
				}
-
 
2192
				cont = a;
-
 
2193
				t = DEREF_type(exp_type(cont));
-
 
2194
				c = type_category(&t);
-
 
2195
				ok = 1;
-
 
2196
			}
-
 
2197
		}
-
 
2198
		if (!ok && !IS_TYPE_ERROR(c)) {
-
 
2199
			report(crt_loc, ERR_stmt_switch_control(t));
-
 
2200
		}
-
 
2201
	}
-
 
2202
 
-
 
2203
	/* Promote control construct */
-
 
2204
	if (ok) {
-
 
2205
		if (IS_TYPE_ADDRESS(c)) {
-
 
2206
			cont = convert_lvalue(cont);
-
 
2207
			t = DEREF_type(exp_type(cont));
-
 
2208
		}
-
 
2209
		if (IS_NULL_exp(a)) {
-
 
2210
			a = cont;
-
 
2211
		}
-
 
2212
		if (is_const_exp(a, -1)) {
-
 
2213
			/* Report constant control expressions */
-
 
2214
			report(crt_loc, ERR_stmt_switch_const());
-
 
2215
		}
-
 
2216
		if (IS_type_enumerate(t) || check_int_type(t, btype_bool)) {
-
 
2217
			/* Store enumeration control expression */
-
 
2218
			*pb = cont;
-
 
2219
		}
-
 
2220
		t = promote_type(t);
-
 
2221
		cont = convert_promote(t, cont);
-
 
2222
		if (record_location) {
-
 
2223
			/* Mark position of control expression */
-
 
2224
			MAKE_exp_location(t, crt_loc, cont, cont);
-
 
2225
		}
2099
	}
2226
	}
2100
    }
-
 
2101
    return ( e ) ;
2227
	return (cont);
2102
}
2228
}
2103
 
2229
 
2104
 
2230
 
2105
/*
-
 
2106
    CHECK A SWITCH CONTROL EXPRESSION
-
 
2107
 
-
 
2108
    This routine checks the switch control expression cont.  pd is as in
-
 
2109
    check_cond and pb is used to return an enumeration or boolean control
-
 
2110
    expression.
-
 
2111
*/
-
 
2112
 
-
 
2113
EXP check_control
-
 
2114
    PROTO_N ( ( cont, pd, pb ) )
-
 
2115
    PROTO_T ( EXP cont X EXP *pd X EXP *pb )
-
 
2116
{
-
 
2117
    TYPE t ;
-
 
2118
    int ok = 1 ;
-
 
2119
    unsigned c ;
-
 
2120
    EXP a = NULL_exp ;
-
 
2121
 
-
 
2122
    /* Check for condition declarations */
-
 
2123
    if ( IS_exp_decl_stmt ( cont ) ) {
-
 
2124
	IDENTIFIER id = DEREF_id ( exp_decl_stmt_id ( cont ) ) ;
-
 
2125
	if ( IS_id_variable ( id ) ) {
-
 
2126
	    *pd = cont ;
-
 
2127
	    t = DEREF_type ( id_variable_type ( id ) ) ;
-
 
2128
	    a = DEREF_exp ( id_variable_init ( id ) ) ;
-
 
2129
	    /* This doesn't count as a use of id */
-
 
2130
	    MAKE_exp_identifier ( t, id, qual_none, cont ) ;
-
 
2131
	}
-
 
2132
    }
-
 
2133
 
-
 
2134
    /* Apply reference conversions to control */
-
 
2135
    cont = convert_reference ( cont, REF_NORMAL ) ;
-
 
2136
    t = DEREF_type ( exp_type ( cont ) ) ;
-
 
2137
    c = type_category ( &t ) ;
-
 
2138
    if ( IS_TYPE_INT ( c ) ) {
-
 
2139
	/* Integral types are allowed */
-
 
2140
	/* EMPTY */
-
 
2141
    } else if ( IS_TYPE_TEMPL ( c ) ) {
-
 
2142
	/* Allow for template parameters */
-
 
2143
	MAKE_exp_op ( t, lex_switch, cont, NULL_exp, cont ) ;
-
 
2144
	ok = 0 ;
-
 
2145
    } else {
-
 
2146
	/* Allow for overloading */
-
 
2147
	ok = 0 ;
-
 
2148
	if ( IS_TYPE_CLASS ( c ) ) {
-
 
2149
	    ERROR err = NULL_err ;
-
 
2150
	    a = convert_gen ( CTYPE_INT, cont, &err ) ;
-
 
2151
	    if ( !IS_NULL_exp ( a ) ) {
-
 
2152
		if ( !IS_NULL_err ( err ) ) {
-
 
2153
		    err = concat_error ( err, ERR_stmt_switch_conv () ) ;
-
 
2154
		    report ( crt_loc, err ) ;
-
 
2155
		}
-
 
2156
		cont = a ;
-
 
2157
		t = DEREF_type ( exp_type ( cont ) ) ;
-
 
2158
		c = type_category ( &t ) ;
-
 
2159
		ok = 1 ;
-
 
2160
	    }
-
 
2161
	}
-
 
2162
	if ( !ok && !IS_TYPE_ERROR ( c ) ) {
-
 
2163
	    report ( crt_loc, ERR_stmt_switch_control ( t ) ) ;
-
 
2164
	}
-
 
2165
    }
-
 
2166
 
-
 
2167
    /* Promote control construct */
-
 
2168
    if ( ok ) {
-
 
2169
	if ( IS_TYPE_ADDRESS ( c ) ) {
-
 
2170
	    cont = convert_lvalue ( cont ) ;
-
 
2171
	    t = DEREF_type ( exp_type ( cont ) ) ;
-
 
2172
	}
-
 
2173
	if ( IS_NULL_exp ( a ) ) a = cont ;
-
 
2174
	if ( is_const_exp ( a, -1 ) ) {
-
 
2175
	    /* Report constant control expressions */
-
 
2176
	    report ( crt_loc, ERR_stmt_switch_const () ) ;
-
 
2177
	}
-
 
2178
	if ( IS_type_enumerate ( t ) || check_int_type ( t, btype_bool ) ) {
-
 
2179
	    /* Store enumeration control expression */
-
 
2180
	    *pb = cont ;
-
 
2181
	}
-
 
2182
	t = promote_type ( t ) ;
-
 
2183
	cont = convert_promote ( t, cont ) ;
-
 
2184
	if ( record_location ) {
-
 
2185
	    /* Mark position of control expression */
-
 
2186
	    MAKE_exp_location ( t, crt_loc, cont, cont ) ;
-
 
2187
	}
-
 
2188
    }
-
 
2189
    return ( cont ) ;
-
 
2190
}
-
 
2191
 
-
 
2192
 
-
 
2193
/*
2231
/*
2194
    BEGIN A SWITCH STATEMENT
2232
    BEGIN A SWITCH STATEMENT
2195
 
2233
 
2196
    This routine begins the construction of a switch statement with
2234
    This routine begins the construction of a switch statement with
2197
    controlling expression cont.  During construction an enumeration or
2235
    controlling expression cont.  During construction an enumeration or
2198
    boolean control expression is held in the body field.
2236
    boolean control expression is held in the body field.
2199
*/
2237
*/
2200
 
2238
 
2201
EXP begin_switch_stmt
2239
EXP
2202
    PROTO_N ( ( cont ) )
-
 
2203
    PROTO_T ( EXP cont )
2240
begin_switch_stmt(EXP cont)
2204
{
2241
{
2205
    EXP e ;
2242
	EXP e;
2206
    EXP d = NULL_exp ;
2243
	EXP d = NULL_exp;
2207
    EXP body = NULL_exp ;
2244
	EXP body = NULL_exp;
2208
    EXP bk = begin_label_stmt ( NULL_id, lex_break ) ;
2245
	EXP bk = begin_label_stmt(NULL_id, lex_break);
2209
    IDENTIFIER bk_lab = DEREF_id ( exp_label_stmt_label ( bk ) ) ;
2246
	IDENTIFIER bk_lab = DEREF_id(exp_label_stmt_label(bk));
2210
    cont = check_control ( cont, &d, &body ) ;
2247
	cont = check_control(cont, &d, &body);
2211
    MAKE_exp_switch_stmt ( type_void, cont, body, 0, bk_lab, e ) ;
2248
	MAKE_exp_switch_stmt(type_void, cont, body, 0, bk_lab, e);
2212
    check_empty_stmt ( lex_switch ) ;
2249
	check_empty_stmt(lex_switch);
-
 
2250
 
-
 
2251
	/* Add statement to loop stack */
-
 
2252
	PUSH_exp(e, crt_loop_stack);
2213
 
2253
 
2214
    /* Add statement to loop stack */
2254
	/* Allow for condition declarations */
-
 
2255
	if (!IS_NULL_exp(d)) {
2215
    PUSH_exp ( e, crt_loop_stack ) ;
2256
		e = make_cond_decl(d, e, 0);
2216
 
2257
	}
2217
    /* Allow for condition declarations */
-
 
2218
    if ( !IS_NULL_exp ( d ) ) e = make_cond_decl ( d, e, 0 ) ;
-
 
2219
 
2258
 
2220
    /* The following statement is never reached */
2259
	/* The following statement is never reached */
2221
    unreached_code = 1 ;
2260
	unreached_code = 1;
2222
    unreached_last = 0 ;
2261
	unreached_last = 0;
2223
    unreached_fall = 1 ;
2262
	unreached_fall = 1;
2224
    return ( e ) ;
2263
	return (e);
2225
}
2264
}
2226
 
2265
 
2227
 
2266
 
2228
/*
2267
/*
2229
    DOES A VALUE APPEAR IN A CASE LIST?
2268
    DOES A VALUE APPEAR IN A CASE LIST?
Line 2231... Line 2270...
2231
    This routine checks whether the integer constant n appears in the list
2270
    This routine checks whether the integer constant n appears in the list
2232
    of cases p.  If so it returns the label corresponding to the case
2271
    of cases p.  If so it returns the label corresponding to the case
2233
    statement drawn from the list of labels q.
2272
    statement drawn from the list of labels q.
2234
*/
2273
*/
2235
 
2274
 
2236
IDENTIFIER find_case
2275
IDENTIFIER
2237
    PROTO_N ( ( p, q, n ) )
-
 
2238
    PROTO_T ( LIST ( NAT ) p X LIST ( IDENTIFIER ) q X NAT n )
2276
find_case(LIST(NAT) p, LIST(IDENTIFIER) q, NAT n)
2239
{
2277
{
2240
    while ( !IS_NULL_list ( p ) ) {
2278
	while (!IS_NULL_list(p)) {
2241
	NAT m = DEREF_nat ( HEAD_list ( p ) ) ;
2279
		NAT m = DEREF_nat(HEAD_list(p));
2242
	if ( EQ_nat ( n, m ) || eq_nat ( n, m ) ) {
2280
		if (EQ_nat(n, m) || eq_nat(n, m)) {
2243
	    IDENTIFIER lab = DEREF_id ( HEAD_list ( q ) ) ;
2281
			IDENTIFIER lab = DEREF_id(HEAD_list(q));
2244
	    return ( lab ) ;
2282
			return (lab);
-
 
2283
		}
-
 
2284
		q = TAIL_list(q);
-
 
2285
		p = TAIL_list(p);
2245
	}
2286
	}
2246
	q = TAIL_list ( q ) ;
-
 
2247
	p = TAIL_list ( p ) ;
-
 
2248
    }
-
 
2249
    return ( NULL_id ) ;
2287
	return (NULL_id);
2250
}
2288
}
2251
 
2289
 
2252
 
2290
 
2253
/*
2291
/*
2254
    COMPLETE A SWITCH STATEMENT
2292
    COMPLETE A SWITCH STATEMENT
2255
 
2293
 
2256
    This routine completes the construction of the switch statement prev
2294
    This routine completes the construction of the switch statement prev
2257
    using the statement body.  exhaust is true if the switch statement
2295
    using the statement body.  exhaust is true if the switch statement
2258
    is declared to be exhaustive.
2296
    is declared to be exhaustive.
2259
*/
2297
*/
2260
 
2298
 
2261
EXP end_switch_stmt
2299
EXP
2262
    PROTO_N ( ( prev, body, exhaust ) )
-
 
2263
    PROTO_T ( EXP prev X EXP body X int exhaust )
2300
end_switch_stmt(EXP prev, EXP body, int exhaust)
2264
{
2301
{
2265
    EXP bk ;
2302
	EXP bk;
2266
    EXP cont ;
2303
	EXP cont;
2267
    EXP stmt ;
2304
	EXP stmt;
2268
    unsigned ncases ;
2305
	unsigned ncases;
2269
    IDENTIFIER bk_lab ;
2306
	IDENTIFIER bk_lab;
2270
    LIST ( NAT ) cases ;
2307
	LIST(NAT) cases;
2271
    IDENTIFIER default_lab ;
2308
	IDENTIFIER default_lab;
2272
    LIST ( IDENTIFIER ) case_labs ;
2309
	LIST(IDENTIFIER) case_labs;
2273
 
2310
 
2274
    /* Remove statement from loop stack */
2311
	/* Remove statement from loop stack */
2275
    EXP e ;
2312
	EXP e;
2276
    POP_exp ( e, crt_loop_stack ) ;
2313
	POP_exp(e, crt_loop_stack);
2277
    UNUSED ( e ) ;
2314
	UNUSED(e);
2278
 
2315
 
2279
    /* Copy the body into the result */
2316
	/* Copy the body into the result */
2280
    stmt = find_cond_stmt ( prev ) ;
2317
	stmt = find_cond_stmt(prev);
2281
    cont = DEREF_exp ( exp_switch_stmt_body ( stmt ) ) ;
2318
	cont = DEREF_exp(exp_switch_stmt_body(stmt));
2282
    bk_lab = DEREF_id ( exp_switch_stmt_break_lab ( stmt ) ) ;
2319
	bk_lab = DEREF_id(exp_switch_stmt_break_lab(stmt));
2283
    bk = DEREF_exp ( id_label_stmt ( bk_lab ) ) ;
2320
	bk = DEREF_exp(id_label_stmt(bk_lab));
2284
    if ( !unreached_code ) {
2321
	if (!unreached_code) {
2285
	/* Add break statement to end if necessary */
2322
		/* Add break statement to end if necessary */
2286
	if ( !IS_NULL_exp ( body ) && IS_exp_sequence ( body ) ) {
2323
		if (!IS_NULL_exp(body) && IS_exp_sequence(body)) {
2287
	    EXP b = make_jump_stmt ( bk_lab, stmt ) ;
2324
			EXP b = make_jump_stmt(bk_lab, stmt);
2288
	    body = add_compound_stmt ( body, b ) ;
2325
			body = add_compound_stmt(body, b);
2289
	}
2326
		}
2290
    }
2327
	}
2291
    MAKE_exp_solve_stmt ( type_void, body, e ) ;
2328
	MAKE_exp_solve_stmt(type_void, body, e);
2292
    CONS_exp ( e, all_solve_stmts, all_solve_stmts ) ;
2329
	CONS_exp(e, all_solve_stmts, all_solve_stmts);
2293
    COPY_exp ( exp_solve_stmt_parent ( e ), stmt ) ;
2330
	COPY_exp(exp_solve_stmt_parent(e), stmt);
2294
    COPY_exp ( exp_switch_stmt_body ( stmt ), e ) ;
2331
	COPY_exp(exp_switch_stmt_body(stmt), e);
2295
    set_parent_stmt ( body, e ) ;
2332
	set_parent_stmt(body, e);
2296
    set_parent_stmt ( bk, e ) ;
2333
	set_parent_stmt(bk, e);
2297
 
2334
 
2298
    /* Check lists of cases */
2335
	/* Check lists of cases */
2299
    cases = DEREF_list ( exp_switch_stmt_cases ( stmt ) ) ;
2336
	cases = DEREF_list(exp_switch_stmt_cases(stmt));
2300
    cases = REVERSE_list ( cases ) ;
2337
	cases = REVERSE_list(cases);
2301
    ncases = LENGTH_list ( cases ) ;
2338
	ncases = LENGTH_list(cases);
2302
    if ( ncases == 0 ) {
2339
	if (ncases == 0) {
2303
	ERROR err ;
2340
		ERROR err;
2304
	if ( exhaust ) {
2341
		if (exhaust) {
2305
	    err = ERR_stmt_switch_exhaust_none () ;
2342
			err = ERR_stmt_switch_exhaust_none();
2306
	} else {
2343
		} else {
2307
	    err = ERR_stmt_switch_case_none () ;
2344
			err = ERR_stmt_switch_case_none();
2308
	}
2345
		}
2309
	report ( crt_loc, err ) ;
2346
		report(crt_loc, err);
2310
    }
2347
	}
2311
    IGNORE check_value ( OPT_VAL_switch_cases, ( ulong ) ncases ) ;
2348
	IGNORE check_value(OPT_VAL_switch_cases,(ulong)ncases);
2312
    COPY_list ( exp_switch_stmt_cases ( stmt ), cases ) ;
2349
	COPY_list(exp_switch_stmt_cases(stmt), cases);
2313
    case_labs = DEREF_list ( exp_switch_stmt_case_labs ( stmt ) ) ;
2350
	case_labs = DEREF_list(exp_switch_stmt_case_labs(stmt));
2314
    case_labs = REVERSE_list ( case_labs ) ;
2351
	case_labs = REVERSE_list(case_labs);
2315
    COPY_list ( exp_switch_stmt_case_labs ( stmt ), case_labs ) ;
2352
	COPY_list(exp_switch_stmt_case_labs(stmt), case_labs);
2316
 
2353
 
2317
    /* Check default label */
2354
	/* Check default label */
2318
    default_lab = DEREF_id ( exp_switch_stmt_default_lab ( stmt ) ) ;
2355
	default_lab = DEREF_id(exp_switch_stmt_default_lab(stmt));
2319
    if ( IS_NULL_id ( default_lab ) ) {
2356
	if (IS_NULL_id(default_lab)) {
2320
	report ( crt_loc, ERR_stmt_switch_no_default () ) ;
2357
		report(crt_loc, ERR_stmt_switch_no_default());
2321
    } else {
2358
	} else {
2322
	exhaust = 1 ;
2359
		exhaust = 1;
2323
    }
2360
	}
2324
 
2361
 
2325
    /* Check switch jumps */
2362
	/* Check switch jumps */
2326
    stmt = solve_switch ( stmt ) ;
2363
	stmt = solve_switch (stmt);
2327
 
2364
 
2328
    /* Check switches on enumerations and booleans */
2365
	/* Check switches on enumerations and booleans */
2329
    if ( !IS_NULL_exp ( cont ) && !exhaust ) {
2366
	if (!IS_NULL_exp(cont) && !exhaust) {
2330
	TYPE t = DEREF_type ( exp_type ( cont ) ) ;
2367
		TYPE t = DEREF_type(exp_type(cont));
2331
	if ( IS_type_enumerate ( t ) ) {
2368
		if (IS_type_enumerate(t)) {
2332
	    ENUM_TYPE et = DEREF_etype ( type_enumerate_defn ( t ) ) ;
2369
			ENUM_TYPE et = DEREF_etype(type_enumerate_defn(t));
2333
	    LIST ( IDENTIFIER ) evals = DEREF_list ( etype_values ( et ) ) ;
2370
			LIST(IDENTIFIER) evals = DEREF_list(etype_values(et));
2334
	    exhaust = 1 ;
2371
			exhaust = 1;
2335
	    while ( !IS_NULL_list ( evals ) ) {
2372
			while (!IS_NULL_list(evals)) {
2336
		IDENTIFIER eid = DEREF_id ( HEAD_list ( evals ) ) ;
2373
				IDENTIFIER eid = DEREF_id(HEAD_list(evals));
2337
		EXP en = DEREF_exp ( id_enumerator_value ( eid ) ) ;
2374
				EXP en = DEREF_exp(id_enumerator_value(eid));
2338
		NAT n = DEREF_nat ( exp_int_lit_nat ( en ) ) ;
2375
				NAT n = DEREF_nat(exp_int_lit_nat(en));
2339
		IDENTIFIER lid = find_case ( cases, case_labs, n ) ;
2376
				IDENTIFIER lid = find_case(cases, case_labs, n);
2340
		if ( IS_NULL_id ( lid ) ) {
2377
				if (IS_NULL_id(lid)) {
-
 
2378
					report(crt_loc,
2341
		    report ( crt_loc, ERR_stmt_switch_case_enum ( eid ) ) ;
2379
					       ERR_stmt_switch_case_enum(eid));
2342
		    exhaust = 0 ;
2380
					exhaust = 0;
-
 
2381
				}
-
 
2382
				evals = TAIL_list(evals);
-
 
2383
			}
-
 
2384
		} else {
-
 
2385
			NAT n = small_nat[BOOL_FALSE];
-
 
2386
			IDENTIFIER lid = find_case(cases, case_labs, n);
-
 
2387
			if (!IS_NULL_id(lid)) {
-
 
2388
				n = small_nat[BOOL_TRUE];
-
 
2389
				lid = find_case(cases, case_labs, n);
-
 
2390
				if (!IS_NULL_id(lid)) {
-
 
2391
					exhaust = 1;
-
 
2392
				}
-
 
2393
			}
-
 
2394
		}
-
 
2395
	}
-
 
2396
 
-
 
2397
	/* Unreached code analysis */
-
 
2398
	if (unreached_code) {
-
 
2399
		if (used_label(bk_lab) == 1) {
-
 
2400
			/* Can reach the end using break */
-
 
2401
			unreached_code = unreached_prev;
-
 
2402
		} else if (exhaust) {
-
 
2403
			/* All cases covered by switch */
-
 
2404
			COPY_type(exp_type(stmt), type_bottom);
-
 
2405
			COPY_type(exp_type(prev), type_bottom);
-
 
2406
		} else {
-
 
2407
			/* Not all cases covered by switch */
-
 
2408
			unreached_code = unreached_prev;
2343
		}
2409
		}
2344
		evals = TAIL_list ( evals ) ;
-
 
2345
	    }
-
 
2346
	} else {
-
 
2347
	    NAT n = small_nat [ BOOL_FALSE ] ;
-
 
2348
	    IDENTIFIER lid = find_case ( cases, case_labs, n ) ;
-
 
2349
	    if ( !IS_NULL_id ( lid ) ) {
-
 
2350
		n = small_nat [ BOOL_TRUE ] ;
-
 
2351
		lid = find_case ( cases, case_labs, n ) ;
-
 
2352
		if ( !IS_NULL_id ( lid ) ) exhaust = 1 ;
-
 
2353
	    }
-
 
2354
	}
-
 
2355
    }
-
 
2356
 
-
 
2357
    /* Unreached code analysis */
-
 
2358
    if ( unreached_code ) {
-
 
2359
	if ( used_label ( bk_lab ) == 1 ) {
-
 
2360
	    /* Can reach the end using break */
-
 
2361
	    unreached_code = unreached_prev ;
-
 
2362
	} else if ( exhaust ) {
-
 
2363
	    /* All cases covered by switch */
-
 
2364
	    COPY_type ( exp_type ( stmt ), type_bottom ) ;
-
 
2365
	    COPY_type ( exp_type ( prev ), type_bottom ) ;
-
 
2366
	} else {
-
 
2367
	    /* Not all cases covered by switch */
-
 
2368
	    unreached_code = unreached_prev ;
-
 
2369
	}
2410
	}
2370
    }
-
 
2371
    COPY_int ( exp_switch_stmt_exhaust ( stmt ), exhaust ) ;
2411
	COPY_int(exp_switch_stmt_exhaust(stmt), exhaust);
2372
    return ( prev ) ;
2412
	return (prev);
2373
}
2413
}
2374
 
2414
 
2375
 
2415
 
2376
/*
2416
/*
2377
    BEGIN A CASE STATEMENT
2417
    BEGIN A CASE STATEMENT
2378
 
2418
 
2379
    This routine begins the construction of a case statement (or a jump
2419
    This routine begins the construction of a case statement (or a jump
2380
    to a case statement if jump is true) with labelling value val.  Note
2420
    to a case statement if jump is true) with labelling value val.  Note
2381
    that a case statement must appear inside a switch statement.
2421
    that a case statement must appear inside a switch statement.
2503
 
2553
 
2504
 
2554
 
2505
/*
2555
/*
2506
    COMPLETE A CASE STATEMENT
2556
    COMPLETE A CASE STATEMENT
2507
 
2557
 
2508
    This routine completes the construction of the case statement prev
2558
    This routine completes the construction of the case statement prev
2509
    using the statement body.  This is just a call to end_label_stmt.
2559
    using the statement body.  This is just a call to end_label_stmt.
2510
*/
2560
*/
2511
 
2561
 
2512
EXP end_case_stmt
2562
EXP
2513
    PROTO_N ( ( prev, body ) )
-
 
2514
    PROTO_T ( EXP prev X EXP body )
2563
end_case_stmt(EXP prev, EXP body)
2515
{
2564
{
2516
    return ( end_label_stmt ( prev, body ) ) ;
2565
	return (end_label_stmt(prev, body));
2517
}
2566
}
2518
 
2567
 
2519
 
2568
 
2520
/*
2569
/*
2521
    BEGIN A DEFAULT STATEMENT
2570
    BEGIN A DEFAULT STATEMENT
Line 2523... Line 2572...
2523
    This routine begins the construction of a default statement (or a jump
2572
    This routine begins the construction of a default statement (or a jump
2524
    to a default statement if jump is true).  Note that a default statement
2573
    to a default statement if jump is true).  Note that a default statement
2525
    must appear inside a switch statement.
2574
    must appear inside a switch statement.
2526
*/
2575
*/
2527
 
2576
 
2528
EXP begin_default_stmt
2577
EXP
2529
    PROTO_N ( ( jump ) )
-
 
2530
    PROTO_T ( int jump )
2578
begin_default_stmt(int jump)
2531
{
2579
{
2532
    /* Search for enclosing switch statement */
2580
	/* Search for enclosing switch statement */
2533
    LIST ( EXP ) st = LIST_stack ( crt_loop_stack ) ;
2581
	LIST(EXP) st = LIST_stack(crt_loop_stack);
2534
    while ( !IS_NULL_list ( st ) ) {
2582
	while (!IS_NULL_list(st)) {
2535
	EXP stmt = DEREF_exp ( HEAD_list ( st ) ) ;
2583
		EXP stmt = DEREF_exp(HEAD_list(st));
2536
 
2584
 
2537
	if ( IS_exp_switch_stmt ( stmt ) ) {
2585
		if (IS_exp_switch_stmt(stmt)) {
2538
	    /* Switch statement found */
2586
			/* Switch statement found */
2539
	    EXP e ;
2587
			EXP e;
2540
	    IDENTIFIER lab ;
2588
			IDENTIFIER lab;
2541
	    int uc = unreached_code ;
2589
			int uc = unreached_code;
2542
 
2590
 
2543
	    /* Check for previous default statements */
2591
			/* Check for previous default statements */
2544
	    lab = DEREF_id ( exp_switch_stmt_default_lab ( stmt ) ) ;
2592
			lab = DEREF_id(exp_switch_stmt_default_lab(stmt));
2545
	    if ( !IS_NULL_id ( lab ) && !jump ) {
2593
			if (!IS_NULL_id(lab) && !jump) {
2546
		DECL_SPEC info = DEREF_dspec ( id_storage ( lab ) ) ;
2594
				DECL_SPEC info = DEREF_dspec(id_storage(lab));
2547
		if ( info & dspec_defn ) {
2595
				if (info & dspec_defn) {
2548
		    /* Duplicate default statement */
2596
					/* Duplicate default statement */
2549
		    PTR ( LOCATION ) loc = id_loc ( lab ) ;
2597
					PTR(LOCATION) loc = id_loc(lab);
2550
		    report ( crt_loc, ERR_stmt_switch_default_dup ( loc ) ) ;
2598
					report(crt_loc, ERR_stmt_switch_default_dup(loc));
2551
		    lab = NULL_id ;
2599
					lab = NULL_id;
-
 
2600
				}
-
 
2601
			}
-
 
2602
 
-
 
2603
			/* Construct the default statement */
-
 
2604
			if (jump) {
-
 
2605
				e = make_goto_stmt(lab);
-
 
2606
				lab = DEREF_id(exp_goto_stmt_label(e));
-
 
2607
				COPY_int(id_label_op(lab), lex_default);
-
 
2608
			} else {
-
 
2609
				int exhaust;
-
 
2610
				exhaust =
-
 
2611
				    DEREF_int(exp_switch_stmt_exhaust(stmt));
-
 
2612
				if (exhaust) {
-
 
2613
					report(crt_loc, ERR_stmt_switch_exhaust_default());
-
 
2614
				}
-
 
2615
				e = begin_label_stmt(lab, lex_default);
-
 
2616
				lab = DEREF_id(exp_label_stmt_label(e));
-
 
2617
			}
-
 
2618
			COPY_exp(id_label_gotos(lab), stmt);
-
 
2619
			COPY_id(exp_switch_stmt_default_lab(stmt), lab);
-
 
2620
 
-
 
2621
			/* Check for falling into default */
-
 
2622
			if (!jump) {
-
 
2623
				if (!uc && unreached_fall && !suppress_fall) {
-
 
2624
					report(crt_loc, ERR_stmt_label_fall(lex_default));
-
 
2625
				}
-
 
2626
				suppress_fall = 0;
-
 
2627
			}
-
 
2628
			return (e);
2552
		}
2629
		}
2553
	    }
-
 
2554
 
2630
 
2555
	    /* Construct the default statement */
-
 
2556
	    if ( jump ) {
-
 
2557
		e = make_goto_stmt ( lab ) ;
-
 
2558
		lab = DEREF_id ( exp_goto_stmt_label ( e ) ) ;
-
 
2559
		COPY_int ( id_label_op ( lab ), lex_default ) ;
-
 
2560
	    } else {
-
 
2561
		int exhaust ;
-
 
2562
		exhaust = DEREF_int ( exp_switch_stmt_exhaust ( stmt ) ) ;
-
 
2563
		if ( exhaust ) {
-
 
2564
		    report ( crt_loc, ERR_stmt_switch_exhaust_default () ) ;
-
 
2565
		}
-
 
2566
		e = begin_label_stmt ( lab, lex_default ) ;
-
 
2567
		lab = DEREF_id ( exp_label_stmt_label ( e ) ) ;
-
 
2568
	    }
-
 
2569
	    COPY_exp ( id_label_gotos ( lab ), stmt ) ;
-
 
2570
	    COPY_id ( exp_switch_stmt_default_lab ( stmt ), lab ) ;
-
 
2571
 
-
 
2572
	    /* Check for falling into default */
2631
		/* Iteration statements are ignored for defaults */
2573
	    if ( !jump ) {
-
 
2574
		if ( !uc && unreached_fall && !suppress_fall ) {
-
 
2575
		    report ( crt_loc, ERR_stmt_label_fall ( lex_default ) ) ;
-
 
2576
		}
-
 
2577
		suppress_fall = 0 ;
2632
		st = TAIL_list(st);
2578
	    }
-
 
2579
	    return ( e ) ;
-
 
2580
	}
2633
	}
2581
 
-
 
2582
	/* Iteration statements are ignored for defaults */
-
 
2583
	st = TAIL_list ( st ) ;
-
 
2584
    }
-
 
2585
    report ( crt_loc, ERR_stmt_label_default () ) ;
2634
	report(crt_loc, ERR_stmt_label_default());
2586
    return ( NULL_exp ) ;
2635
	return (NULL_exp);
2587
}
2636
}
2588
 
2637
 
2589
 
2638
 
2590
/*
2639
/*
2591
    COMPLETE A DEFAULT STATEMENT
2640
    COMPLETE A DEFAULT STATEMENT
2592
 
2641
 
2593
    This routine completes the construction of the default statement prev
2642
    This routine completes the construction of the default statement prev
2594
    using the statement body.  This is just a call to end_label_stmt.
2643
    using the statement body.  This is just a call to end_label_stmt.
2595
*/
2644
*/
2596
 
2645
 
2597
EXP end_default_stmt
2646
EXP
2598
    PROTO_N ( ( prev, body ) )
-
 
2599
    PROTO_T ( EXP prev X EXP body )
2647
end_default_stmt(EXP prev, EXP body)
2600
{
2648
{
2601
    return ( end_label_stmt ( prev, body ) ) ;
2649
	return (end_label_stmt(prev, body));
2602
}
2650
}
2603
 
2651
 
2604
 
2652
 
2605
/*
2653
/*
2606
    CURRENT #IF CONDITION
2654
    CURRENT #IF CONDITION
2607
 
2655
 
2608
    This variable is used to keep track of the cummulative target dependent
2656
    This variable is used to keep track of the cummulative target dependent
2609
    condition at any point in the compilation.  It takes the form
2657
    condition at any point in the compilation.  It takes the form
2610
    'c1 && c2 && ... && cn' where c1, c2, ..., cn are the target dependent
2658
    'c1 && c2 && ... && cn' where c1, c2, ..., cn are the target dependent
2611
    conditions currently in scope.  The case n = 0 gives the null expression.
2659
    conditions currently in scope.  The case n = 0 gives the null expression.
2612
*/
2660
*/
2613
 
2661
 
2614
EXP crt_hash_cond = NULL_exp ;
2662
EXP crt_hash_cond = NULL_exp;
2615
 
2663
 
2616
 
2664
 
2617
/*
2665
/*
2618
    ADD A CONDITION TO A LIST OF CONDITIONS
2666
    ADD A CONDITION TO A LIST OF CONDITIONS
2619
 
2667
 
2620
    This routine adds the condition a to the list of conditions b by
2668
    This routine adds the condition a to the list of conditions b by
2621
    forming 'b && a'.
2669
    forming 'b && a'.
2622
*/
2670
*/
2623
 
2671
 
2624
EXP make_if_cond
2672
EXP
2625
    PROTO_N ( ( a, b ) )
-
 
2626
    PROTO_T ( EXP a X EXP b )
2673
make_if_cond(EXP a, EXP b)
2627
{
2674
{
2628
    if ( !IS_NULL_exp ( b ) ) {
2675
	if (!IS_NULL_exp(b)) {
2629
	MAKE_exp_log_and ( type_bool, b, a, a ) ;
2676
		MAKE_exp_log_and(type_bool, b, a, a);
2630
    }
2677
	}
2631
    return ( a ) ;
2678
	return (a);
2632
}
2679
}
2633
 
2680
 
2634
 
2681
 
2635
/*
2682
/*
2636
    NEGATE THE LAST CONDITION IN A LIST
2683
    NEGATE THE LAST CONDITION IN A LIST
2637
 
2684
 
2638
    This routine negates the last condition in the list of conditions a,
2685
    This routine negates the last condition in the list of conditions a,
2639
    that is, it maps 'a1 && a2 && ... && an' to 'a1 && a2 && ... && !an'.
2686
    that is, it maps 'a1 && a2 && ... && an' to 'a1 && a2 && ... && !an'.
2640
*/
2687
*/
2641
 
2688
 
2642
EXP make_else_cond
2689
EXP
2643
    PROTO_N ( ( a ) )
-
 
2644
    PROTO_T ( EXP a )
2690
make_else_cond(EXP a)
2645
{
2691
{
2646
    if ( !IS_NULL_exp ( a ) ) {
2692
	if (!IS_NULL_exp(a)) {
2647
	if ( IS_exp_log_and ( a ) ) {
2693
		if (IS_exp_log_and(a)) {
2648
	    EXP b = DEREF_exp ( exp_log_and_arg1 ( a ) ) ;
2694
			EXP b = DEREF_exp(exp_log_and_arg1(a));
2649
	    EXP c = DEREF_exp ( exp_log_and_arg2 ( a ) ) ;
2695
			EXP c = DEREF_exp(exp_log_and_arg2(a));
2650
	    MAKE_exp_not ( type_bool, c, c ) ;
2696
			MAKE_exp_not(type_bool, c, c);
2651
	    MAKE_exp_log_and ( type_bool, b, c, a ) ;
2697
			MAKE_exp_log_and(type_bool, b, c, a);
2652
	} else {
2698
		} else {
2653
	    MAKE_exp_not ( type_bool, a, a ) ;
2699
			MAKE_exp_not(type_bool, a, a);
-
 
2700
		}
2654
	}
2701
	}
2655
    }
-
 
2656
    return ( a ) ;
2702
	return (a);
2657
}
2703
}
2658
 
2704
 
2659
 
2705
 
2660
/*
2706
/*
2661
    BEGIN A #IF STATEMENT
2707
    BEGIN A #IF STATEMENT
2662
 
2708
 
2663
    This routine begins the construction of a #if statement.  cond gives
2709
    This routine begins the construction of a #if statement.  cond gives
2664
    the condition, which is already a boolean value.  The case where cond
2710
    the condition, which is already a boolean value.  The case where cond
2665
    is a target independent constant have already been handled by the
2711
    is a target independent constant have already been handled by the
2666
    preprocessor.  right gives the code which is evaluated if this condition
2712
    preprocessor.  right gives the code which is evaluated if this condition
2667
    is true.
2713
    is true.
2668
*/
2714
*/
2669
 
2715
 
2670
EXP begin_hash_if_stmt
2716
EXP
2671
    PROTO_N ( ( cond, right ) )
-
 
2672
    PROTO_T ( EXP cond X EXP right )
2717
begin_hash_if_stmt(EXP cond, EXP right)
2673
{
2718
{
2674
    /* Construct the result */
2719
	/* Construct the result */
2675
    EXP e ;
2720
	EXP e;
2676
    MAKE_exp_hash_if ( type_void, cond, right, NULL_exp, e ) ;
2721
	MAKE_exp_hash_if (type_void, cond, right, NULL_exp, e);
2677
    COPY_exp ( exp_hash_if_last ( e ), e ) ;
2722
	COPY_exp(exp_hash_if_last(e), e);
2678
    set_parent_stmt ( right, e ) ;
2723
	set_parent_stmt(right, e);
2679
 
2724
 
2680
    /* Unreached code analysis */
2725
	/* Unreached code analysis */
2681
    if ( is_bottom ( right ) ) {
2726
	if (is_bottom(right)) {
2682
	COPY_type ( exp_type ( e ), type_bottom ) ;
2727
		COPY_type(exp_type(e), type_bottom);
2683
    }
2728
	}
2684
    /* Next branch is reached */
2729
	/* Next branch is reached */
2685
    unreached_code = unreached_prev ;
2730
	unreached_code = unreached_prev;
2686
    return ( e ) ;
2731
	return (e);
2687
}
2732
}
2688
 
2733
 
2689
 
2734
 
2690
/*
2735
/*
2691
    CONTINUE A #IF STATEMENT
2736
    CONTINUE A #IF STATEMENT
2692
 
2737
 
2693
    This routine continues the construction of a #if statement, prev, by
2738
    This routine continues the construction of a #if statement, prev, by
2694
    adding a #elif statement to the condition.  cond gives the condition,
2739
    adding a #elif statement to the condition.  cond gives the condition,
2695
    which is already a boolean value.  The case where cond is a target
2740
    which is already a boolean value.  The case where cond is a target
2696
    independent constant have already been handled by the preprocessor.
2741
    independent constant have already been handled by the preprocessor.
2697
    right gives the code which is evaluated if this condition, and none of
2742
    right gives the code which is evaluated if this condition, and none of
2698
    the previous conditions in prev, is true.
2743
    the previous conditions in prev, is true.
2699
*/
2744
*/
-
 
2745
 
-
 
2746
EXP
-
 
2747
cont_hash_if_stmt(EXP prev, EXP cond, EXP right)
-
 
2748
{
-
 
2749
	/* Map '#elif' to '#else #if' */
-
 
2750
	EXP e;
-
 
2751
	EXP last = DEREF_exp(exp_hash_if_last(prev));
-
 
2752
	MAKE_exp_hash_if (type_void, cond, right, NULL_exp, e);
-
 
2753
	COPY_exp(exp_hash_if_parent(e), last);
-
 
2754
	COPY_exp(exp_hash_if_false_code(last), e);
-
 
2755
	COPY_exp(exp_hash_if_last(prev), e);
-
 
2756
	set_parent_stmt(right, e);
-
 
2757
 
-
 
2758
	/* Unreached code analysis */
-
 
2759
	if (!is_bottom(right)) {
-
 
2760
		/* Reaching the end of a condition */
-
 
2761
		COPY_type(exp_type(prev), type_void);
-
 
2762
	}
-
 
2763
	/* Next branch is reached */
-
 
2764
	unreached_code = unreached_prev;
-
 
2765
	return (prev);
-
 
2766
}
2700
 
2767
 
2701
EXP cont_hash_if_stmt
-
 
2702
    PROTO_N ( ( prev, cond, right ) )
-
 
2703
    PROTO_T ( EXP prev X EXP cond X EXP right )
-
 
2704
{
-
 
2705
    /* Map '#elif' to '#else #if' */
-
 
2706
    EXP e ;
-
 
2707
    EXP last = DEREF_exp ( exp_hash_if_last ( prev ) ) ;
-
 
2708
    MAKE_exp_hash_if ( type_void, cond, right, NULL_exp, e ) ;
-
 
2709
    COPY_exp ( exp_hash_if_parent ( e ), last ) ;
-
 
2710
    COPY_exp ( exp_hash_if_false_code ( last ), e ) ;
-
 
2711
    COPY_exp ( exp_hash_if_last ( prev ), e ) ;
-
 
2712
    set_parent_stmt ( right, e ) ;
-
 
2713
 
2768
 
-
 
2769
/*
-
 
2770
    COMPLETE A #IF STATEMENT
-
 
2771
 
-
 
2772
    This routine completes the construction of a #if statement, prev.
-
 
2773
    wrong gives the code which is evaluated if none of the conditions in
-
 
2774
    prev is true.
-
 
2775
*/
-
 
2776
 
-
 
2777
EXP
-
 
2778
end_hash_if_stmt(EXP prev, EXP wrong)
-
 
2779
{
-
 
2780
	/* Copy wrong expression into result */
-
 
2781
	EXP last = DEREF_exp(exp_hash_if_last(prev));
-
 
2782
	COPY_exp(exp_hash_if_false_code(last), wrong);
-
 
2783
	set_parent_stmt(wrong, last);
-
 
2784
 
2714
    /* Unreached code analysis */
2785
	/* Unreached code analysis */
2715
    if ( !is_bottom ( right ) ) {
2786
	if (is_bottom(wrong)) {
2716
	/* Reaching the end of a condition */
2787
		/* Reachability is determined by the previous branches */
-
 
2788
		if (is_bottom(prev)) {
-
 
2789
			unreached_code = 1;
-
 
2790
		} else {
2717
	COPY_type ( exp_type ( prev ), type_void ) ;
2791
			unreached_code = unreached_prev;
2718
    }
2792
		}
-
 
2793
	} else {
2719
    /* Next branch is reached */
2794
		/* End of statement is reached */
-
 
2795
		COPY_type(exp_type(prev), type_void);
2720
    unreached_code = unreached_prev ;
2796
		unreached_code = unreached_prev;
-
 
2797
	}
2721
    return ( prev ) ;
2798
	return (prev);
2722
}
2799
}
2723
 
2800
 
2724
 
2801
 
2725
/*
2802
/*
2726
    COMPLETE A #IF STATEMENT
-
 
2727
 
-
 
2728
    This routine completes the construction of a #if statement, prev.
-
 
2729
    wrong gives the code which is evaluated if none of the conditions in
-
 
2730
    prev is true.
-
 
2731
*/
-
 
2732
 
-
 
2733
EXP end_hash_if_stmt
-
 
2734
    PROTO_N ( ( prev, wrong ) )
-
 
2735
    PROTO_T ( EXP prev X EXP wrong )
-
 
2736
{
-
 
2737
    /* Copy wrong expression into result */
-
 
2738
    EXP last = DEREF_exp ( exp_hash_if_last ( prev ) ) ;
-
 
2739
    COPY_exp ( exp_hash_if_false_code ( last ), wrong ) ;
-
 
2740
    set_parent_stmt ( wrong, last ) ;
-
 
2741
 
-
 
2742
    /* Unreached code analysis */
-
 
2743
    if ( is_bottom ( wrong ) ) {
-
 
2744
	/* Reachability is determined by the previous branches */
-
 
2745
	if ( is_bottom ( prev ) ) {
-
 
2746
	    unreached_code = 1 ;
-
 
2747
	} else {
-
 
2748
	    unreached_code = unreached_prev ;
-
 
2749
	}
-
 
2750
    } else {
-
 
2751
	/* End of statement is reached */
-
 
2752
	COPY_type ( exp_type ( prev ), type_void ) ;
-
 
2753
	unreached_code = unreached_prev ;
-
 
2754
    }
-
 
2755
    return ( prev ) ;
-
 
2756
}
-
 
2757
 
-
 
2758
 
-
 
2759
/*
-
 
2760
    CREATE A FLOW CONTROL STATEMENT
2803
    CREATE A FLOW CONTROL STATEMENT
2761
 
2804
 
2762
    This routine creates a flow control statement indicating that the
2805
    This routine creates a flow control statement indicating that the
2763
    statement body is either reached or unreached, depending on the
2806
    statement body is either reached or unreached, depending on the
2764
    value of reach.
2807
    value of reach.
2765
*/
2808
*/
2766
 
2809
 
2767
EXP make_reach_stmt
2810
EXP
2768
    PROTO_N ( ( body, reach ) )
-
 
2769
    PROTO_T ( EXP body X int reach )
2811
make_reach_stmt(EXP body, int reach)
2770
{
2812
{
2771
    EXP e ;
2813
	EXP e;
2772
    TYPE t ;
2814
	TYPE t;
2773
    if ( IS_NULL_exp ( body ) ) {
2815
	if (IS_NULL_exp(body)) {
2774
	t = type_void ;
2816
		t = type_void;
2775
    } else {
2817
	} else {
2776
	unsigned tag = TAG_exp ( body ) ;
2818
		unsigned tag = TAG_exp(body);
2777
	if ( tag == exp_decl_stmt_tag || tag == exp_label_stmt_tag ) {
2819
		if (tag == exp_decl_stmt_tag || tag == exp_label_stmt_tag) {
2778
	    /* Don't bother in these cases */
2820
			/* Don't bother in these cases */
2779
	    return ( body ) ;
2821
			return (body);
-
 
2822
		}
-
 
2823
		t = DEREF_type(exp_type(body));
2780
	}
2824
	}
2781
	t = DEREF_type ( exp_type ( body ) ) ;
-
 
2782
    }
-
 
2783
    if ( reach ) {
2825
	if (reach) {
2784
	MAKE_exp_reach ( t, body, e ) ;
2826
		MAKE_exp_reach(t, body, e);
2785
    } else {
2827
	} else {
2786
	MAKE_exp_unreach ( t, body, e ) ;
2828
		MAKE_exp_unreach(t, body, e);
2787
    }
2829
	}
2788
    set_parent_stmt ( body, e ) ;
2830
	set_parent_stmt(body, e);
2789
    return ( e ) ;
2831
	return (e);
2790
}
2832
}
2791
 
2833
 
2792
 
2834
 
2793
/*
2835
/*
2794
    CHECK A CONDITION DECLARATION TYPE
2836
    CHECK A CONDITION DECLARATION TYPE
2795
 
2837
 
2796
    This routine checks the type t of a condition declaration.
2838
    This routine checks the type t of a condition declaration.
2797
*/
2839
*/
2798
 
2840
 
2799
TYPE make_cond_type
2841
TYPE
2800
    PROTO_N ( ( t ) )
-
 
2801
    PROTO_T ( TYPE t )
2842
make_cond_type(TYPE t)
2802
{
2843
{
2803
    int td = have_type_declaration ;
2844
	int td = have_type_declaration;
2804
    if ( td != TYPE_DECL_NONE ) {
2845
	if (td != TYPE_DECL_NONE) {
2805
	/* Check for type declarations */
2846
		/* Check for type declarations */
2806
	if ( td == TYPE_DECL_ELABORATE && found_elaborate_type ) {
2847
		if (td == TYPE_DECL_ELABORATE && found_elaborate_type) {
2807
	    /* This is allowed */
2848
			/* This is allowed */
2808
	    /* EMPTY */
2849
			/* EMPTY */
2809
	} else {
2850
		} else {
2810
	    report ( crt_loc, ERR_stmt_select_typedef () ) ;
2851
			report(crt_loc, ERR_stmt_select_typedef());
2811
	}
2852
		}
2812
    }
-
 
2813
    switch ( TAG_type ( t ) ) {
-
 
2814
	case type_func_tag : {
-
 
2815
	    member_func_type ( NULL_ctype, id_variable_tag, t ) ;
-
 
2816
	    check_weak_func ( t, 0 ) ;
-
 
2817
	    report ( crt_loc, ERR_stmt_select_type ( t ) ) ;
-
 
2818
	    MAKE_type_ptr ( cv_none, t, t ) ;
-
 
2819
	    break ;
-
 
2820
	}
2853
	}
-
 
2854
	switch (TAG_type(t)) {
-
 
2855
	case type_func_tag:
-
 
2856
		member_func_type(NULL_ctype, id_variable_tag, t);
-
 
2857
		check_weak_func(t, 0);
-
 
2858
		report(crt_loc, ERR_stmt_select_type(t));
-
 
2859
		MAKE_type_ptr(cv_none, t, t);
-
 
2860
		break;
2821
	case type_array_tag : {
2861
	case type_array_tag:
2822
	    report ( crt_loc, ERR_stmt_select_type ( t ) ) ;
2862
		report(crt_loc, ERR_stmt_select_type(t));
2823
	    t = DEREF_type ( type_array_sub ( t ) ) ;
2863
		t = DEREF_type(type_array_sub(t));
2824
	    MAKE_type_ptr ( cv_none, t, t ) ;
2864
		MAKE_type_ptr(cv_none, t, t);
2825
	    break ;
2865
		break;
2826
	}
2866
	}
2827
    }
-
 
2828
    return ( t ) ;
2867
	return (t);
2829
}
2868
}
2830
 
2869
 
2831
 
2870
 
2832
/*
2871
/*
2833
    BEGIN A CONDITION DECLARATION
2872
    BEGIN A CONDITION DECLARATION
2834
 
2873
 
2835
    Condition declarations are declared in their own local scope and
2874
    Condition declarations are declared in their own local scope and
2836
    brought into the outermost scope of the the statements they control
2875
    brought into the outermost scope of the the statements they control
2837
    using inject_cond.  This routine begins the construction of such a
2876
    using inject_cond.  This routine begins the construction of such a
2838
    local scope.
2877
    local scope.
2839
*/
2878
*/
2840
 
2879
 
2841
void begin_cond
2880
void
2842
    PROTO_Z ()
2881
begin_cond(void)
2843
{
2882
{
2844
    NAMESPACE ns = make_namespace ( crt_func_id, nspace_dummy_tag, 0 ) ;
2883
	NAMESPACE ns = make_namespace(crt_func_id, nspace_dummy_tag, 0);
2845
    push_namespace ( ns ) ;
2884
	push_namespace(ns);
2846
    return ;
2885
	return;
2847
}
2886
}
2848
 
2887
 
2849
 
2888
 
2850
/*
2889
/*
2851
    END A CONDITION DECLARATION
2890
    END A CONDITION DECLARATION
2852
 
2891
 
2853
    This routine ends the local scope for a condition declaration, returning
2892
    This routine ends the local scope for a condition declaration, returning
2854
    a corresponding declaration statement.
2893
    a corresponding declaration statement.
2855
*/
2894
*/
2856
 
2895
 
2857
EXP end_cond
2896
EXP
2858
    PROTO_Z ()
2897
end_cond(void)
2859
{
2898
{
2860
    int vars = 0 ;
2899
	int vars = 0;
2861
    NAMESPACE ns = pop_namespace () ;
2900
	NAMESPACE ns = pop_namespace();
2862
    MEMBER p = DEREF_member ( nspace_last ( ns ) ) ;
2901
	MEMBER p = DEREF_member(nspace_last(ns));
2863
    EXP cond = make_decl_stmt ( p, NULL_member, &vars ) ;
2902
	EXP cond = make_decl_stmt(p, NULL_member, &vars);
2864
    return ( cond ) ;
2903
	return (cond);
2865
}
2904
}
2866
 
2905
 
2867
 
2906
 
2868
/*
2907
/*
2869
    INJECT A CONDITION DECLARATION INTO THE CURRENT SCOPE
2908
    INJECT A CONDITION DECLARATION INTO THE CURRENT SCOPE
Line 2871... Line 2910...
2871
    This routine injects the condition declaration cond into the current
2910
    This routine injects the condition declaration cond into the current
2872
    scope, prev, returning the result.  It is also used to deal with
2911
    scope, prev, returning the result.  It is also used to deal with
2873
    declarations in for-init statements.
2912
    declarations in for-init statements.
2874
*/
2913
*/
2875
 
2914
 
2876
EXP inject_cond
2915
EXP
2877
    PROTO_N ( ( prev, cond ) )
-
 
2878
    PROTO_T ( EXP prev X EXP cond )
2916
inject_cond(EXP prev, EXP cond)
2879
{
2917
{
2880
    if ( !IS_NULL_exp ( cond ) ) {
2918
	if (!IS_NULL_exp(cond)) {
2881
	NAMESPACE ns = crt_namespace ;
2919
		NAMESPACE ns = crt_namespace;
2882
	while ( IS_exp_decl_stmt ( cond ) ) {
2920
		while (IS_exp_decl_stmt(cond)) {
2883
	    IDENTIFIER id = DEREF_id ( exp_decl_stmt_id ( cond ) ) ;
2921
			IDENTIFIER id = DEREF_id(exp_decl_stmt_id(cond));
2884
	    IGNORE redeclare_id ( ns, id ) ;
2922
			IGNORE redeclare_id(ns, id);
2885
	    cond = DEREF_exp ( exp_decl_stmt_body ( cond ) ) ;
2923
			cond = DEREF_exp(exp_decl_stmt_body(cond));
2886
	}
2924
		}
2887
    }
2925
	}
2888
    return ( prev ) ;
2926
	return (prev);
2889
}
2927
}
2890
 
2928
 
2891
 
2929
 
2892
/*
2930
/*
2893
    CONSTRUCT AN ASM STATEMENT
2931
    CONSTRUCT AN ASM STATEMENT
2894
 
2932
 
2895
    This routine constructs an asm statement from the string literal
2933
    This routine constructs an asm statement from the string literal
2896
    expression e.  Note that the semantics of asm are totally implementation
2934
    expression e.  Note that the semantics of asm are totally implementation
2897
    dependent, so anything goes.
2935
    dependent, so anything goes.
2898
*/
2936
*/
2899
 
2937
 
2900
EXP make_asm
2938
EXP
2901
    PROTO_N ( ( e, args ) )
-
 
2902
    PROTO_T ( EXP e X LIST ( EXP ) args )
2939
make_asm(EXP e, LIST(EXP) args)
2903
{
2940
{
2904
    STRING s = DEREF_str ( exp_string_lit_str ( e ) ) ;
2941
	STRING s = DEREF_str(exp_string_lit_str(e));
2905
    if ( !IS_NULL_list ( args ) ) {
2942
	if (!IS_NULL_list(args)) {
2906
	report ( crt_loc, ERR_dcl_asm_args () ) ;
2943
		report(crt_loc, ERR_dcl_asm_args());
2907
	args = convert_args ( args ) ;
2944
		args = convert_args(args);
2908
    }
2945
	}
2909
    MAKE_exp_assembler ( type_void, s, args, e ) ;
2946
	MAKE_exp_assembler(type_void, s, args, e);
2910
    report ( crt_loc, ERR_dcl_asm_ti () ) ;
2947
	report(crt_loc, ERR_dcl_asm_ti());
2911
    return ( e ) ;
2948
	return (e);
2912
}
2949
}