Warning: Attempt to read property "date" on null in /usr/local/www/websvn.planix.org/blame.php on line 247

Warning: Attempt to read property "msg" on null in /usr/local/www/websvn.planix.org/blame.php on line 247

Warning: Attempt to read property "date" on null in /usr/local/www/websvn.planix.org/blame.php on line 247

Warning: Attempt to read property "msg" on null in /usr/local/www/websvn.planix.org/blame.php on line 247
WebSVN – tendra.SVN – Blame – /branches/tendra5-amd64/src/producers/common/construct/statement.c – Rev 6

Subversion Repositories tendra.SVN

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

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