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
/*
2
    		 Crown Copyright (c) 1997, 1998
3
 
4
    This TenDRA(r) Computer Program is subject to Copyright
5
    owned by the United Kingdom Secretary of State for Defence
6
    acting through the Defence Evaluation and Research Agency
7
    (DERA).  It is made available to Recipients with a
8
    royalty-free licence for its use, reproduction, transfer
9
    to other parties and amendment for any purpose not excluding
10
    product development provided that any such use et cetera
11
    shall be deemed to be acceptance of the following conditions:-
12
 
13
        (1) Its Recipients shall ensure that this Notice is
14
        reproduced upon any copies or amended versions of it;
15
 
16
        (2) Any amended version of it shall be clearly marked to
17
        show both the nature of and the organisation responsible
18
        for the relevant amendment or amendments;
19
 
20
        (3) Its onward transfer from a recipient to another
21
        party shall be deemed to be that party's acceptance of
22
        these conditions;
23
 
24
        (4) DERA gives no warranty or assurance as to its
25
        quality or suitability for any purpose and DERA accepts
26
        no liability whatsoever in relation to any use to which
27
        it may be put.
28
*/
29
 
30
 
31
#include "config.h"
32
#include "c_types.h"
33
#include "etype_ops.h"
34
#include "exp_ops.h"
35
#include "hashid_ops.h"
36
#include "id_ops.h"
37
#include "loc_ext.h"
38
#include "member_ops.h"
39
#include "nspace_ops.h"
40
#include "str_ops.h"
41
#include "type_ops.h"
42
#include "error.h"
43
#include "catalog.h"
44
#include "option.h"
45
#include "assign.h"
46
#include "basetype.h"
47
#include "cast.h"
48
#include "check.h"
49
#include "chktype.h"
50
#include "class.h"
51
#include "constant.h"
52
#include "construct.h"
53
#include "convert.h"
54
#include "declare.h"
55
#include "destroy.h"
56
#include "dump.h"
57
#include "exception.h"
58
#include "expression.h"
59
#include "file.h"
60
#include "function.h"
61
#include "hash.h"
62
#include "identifier.h"
63
#include "initialise.h"
64
#include "label.h"
65
#include "lex.h"
66
#include "literal.h"
67
#include "member.h"
68
#include "namespace.h"
69
#include "overload.h"
70
#include "parse.h"
71
#include "predict.h"
72
#include "quality.h"
73
#include "redeclare.h"
74
#include "statement.h"
75
#include "symbols.h"
76
#include "syntax.h"
77
#include "template.h"
78
#include "ustring.h"
79
#include "variable.h"
80
 
81
 
82
/*
83
    UNREACHED CODE ANALYSIS
84
 
85
    The detection of unreachable code is primarily by means of the simple
86
    flag, which is true for unreported statements.  The flag unreached_last
87
    is set to equal unreached_code whenever a reachability check is applied.
88
    This is to ensure that only the first statement in an unreached block
89
    is reported.  At the end of a conditional, or other complex statement,
90
    unreached_prev is set to the value of unreached_code at the start of
91
    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-
93
    trivial statement (this is included in the grammar).
94
*/
95
 
96
int unreached_code = 0 ;
97
int unreached_last = 0 ;
98
int unreached_prev = 0 ;
99
int unreached_fall = 0 ;
100
int suppress_fall = 0 ;
101
 
102
 
103
/*
104
    DOES AN EXPRESSION NOT RETURN?
105
 
106
    This routine tests whether the expression e has type bottom, i.e. does
107
    not return a value.
108
*/
109
 
110
static int is_bottom
111
    PROTO_N ( ( e ) )
112
    PROTO_T ( EXP e )
113
{
114
    TYPE t ;
115
    if ( IS_NULL_exp ( e ) ) return ( 0 ) ;
116
    t = DEREF_type ( exp_type ( e ) ) ;
117
    return ( IS_type_bottom ( t ) ) ;
118
}
119
 
120
 
121
/*
122
    FIND THE PARENT OF A STATEMENT
123
 
124
    This routine returns a pointer to the parent of the statement e.  It
125
    returns the null pointer if e is a simple expression.
126
*/
127
 
128
static PTR ( EXP ) parent_stmt
129
    PROTO_N ( ( e ) )
130
    PROTO_T ( EXP e )
131
{
132
    PTR ( EXP ) ptr = NULL_ptr ( EXP ) ;
133
    if ( !IS_NULL_exp ( e ) ) {
134
	switch ( TAG_exp ( e ) ) {
135
	    case exp_reach_tag : {
136
		ptr = exp_reach_parent ( e ) ;
137
		break ;
138
	    }
139
	    case exp_unreach_tag : {
140
		ptr = exp_unreach_parent ( e ) ;
141
		break ;
142
	    }
143
	    case exp_sequence_tag : {
144
		ptr = exp_sequence_parent ( e ) ;
145
		break ;
146
	    }
147
	    case exp_solve_stmt_tag : {
148
		ptr = exp_solve_stmt_parent ( e ) ;
149
		break ;
150
	    }
151
	    case exp_decl_stmt_tag : {
152
		ptr = exp_decl_stmt_parent ( e ) ;
153
		break ;
154
	    }
155
	    case exp_if_stmt_tag : {
156
		ptr = exp_if_stmt_parent ( e ) ;
157
		break ;
158
	    }
159
	    case exp_while_stmt_tag : {
160
		ptr = exp_while_stmt_parent ( e ) ;
161
		break ;
162
	    }
163
	    case exp_do_stmt_tag : {
164
		ptr = exp_do_stmt_parent ( e ) ;
165
		break ;
166
	    }
167
	    case exp_switch_stmt_tag : {
168
		ptr = exp_switch_stmt_parent ( e ) ;
169
		break ;
170
	    }
171
	    case exp_hash_if_tag : {
172
		ptr = exp_hash_if_parent ( e ) ;
173
		break ;
174
	    }
175
	    case exp_return_stmt_tag : {
176
		ptr = exp_return_stmt_parent ( e ) ;
177
		break ;
178
	    }
179
	    case exp_goto_stmt_tag : {
180
		ptr = exp_goto_stmt_parent ( e ) ;
181
		break ;
182
	    }
183
	    case exp_label_stmt_tag : {
184
		ptr = exp_label_stmt_parent ( e ) ;
185
		break ;
186
	    }
187
	    case exp_try_block_tag : {
188
		ptr = exp_try_block_parent ( e ) ;
189
		break ;
190
	    }
191
	    case exp_handler_tag : {
192
		ptr = exp_handler_parent ( e ) ;
193
		break ;
194
	    }
195
	    case exp_token_tag : {
196
		ptr = exp_token_parent ( e ) ;
197
		break ;
198
	    }
199
	    case exp_location_tag : {
200
		EXP a = DEREF_exp ( exp_location_arg ( e ) ) ;
201
		ptr = parent_stmt ( a ) ;
202
		break ;
203
	    }
204
	    case exp_paren_tag : {
205
		EXP a = DEREF_exp ( exp_paren_arg ( e ) ) ;
206
		ptr = parent_stmt ( a ) ;
207
		break ;
208
	    }
209
	}
210
    }
211
    return ( ptr ) ;
212
}
213
 
214
 
215
/*
216
    GET THE PARENT OF A STATEMENT
217
 
218
    This routine returns the parent statement of e.
219
*/
220
 
221
EXP get_parent_stmt
222
    PROTO_N ( ( e ) )
223
    PROTO_T ( EXP e )
224
{
225
    EXP p = NULL_exp ;
226
    if ( !IS_NULL_exp ( e ) ) {
227
	PTR ( EXP ) ptr = parent_stmt ( e ) ;
228
	if ( !IS_NULL_ptr ( ptr ) ) p = DEREF_exp ( ptr ) ;
229
    }
230
    return ( p ) ;
231
}
232
 
233
 
234
/*
235
    SET THE PARENT OF A STATEMENT
236
 
237
    This routine sets the parent of the statement e to be p.
238
*/
239
 
240
void set_parent_stmt
241
    PROTO_N ( ( e, p ) )
242
    PROTO_T ( EXP e X EXP p )
243
{
244
    if ( !IS_NULL_exp ( e ) ) {
245
	PTR ( EXP ) ptr = parent_stmt ( e ) ;
246
	if ( !IS_NULL_ptr ( ptr ) ) COPY_exp ( ptr, p ) ;
247
    }
248
    return ;
249
}
250
 
251
 
252
/*
253
    STATEMENT LOCATION FLAG
254
 
255
    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.
257
    The variable stmt_loc records the last such location.
258
*/
259
 
260
int record_location = 0 ;
261
LOCATION stmt_loc = NULL_loc ;
262
static int adjusted_line = 0 ;
263
 
264
 
265
/*
266
    ADJUST COLUMN NUMBER
267
 
268
    This routine sets stmt_loc to point to the start of the preprocessing
269
    token p.
270
*/
271
 
272
static void adjust_column
273
    PROTO_N ( ( p ) )
274
    PROTO_T ( 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
{
314
    if ( !adjusted_line ) {
315
	adjusted_line = 1 ;
316
	if ( next ) {
317
	    switch ( crt_lex_token ) {
318
		case lex_open_Hbrace_H1 :
319
		case lex_colon :
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 ;
326
		    if ( p ) {
327
			/* Set location from next token */
328
			p = read_loc_tokens ( p ) ;
329
			if ( crt_state_depth == 0 ) {
330
			    adjust_column ( p ) ;
331
			    return ;
332
			}
333
		    } else {
334
			if ( crt_state_depth == 0 ) {
335
			    /* Skip white space from input file */
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 ;
342
			}
343
		    }
344
		    break ;
345
		}
346
		default : {
347
		    /* Use current token */
348
		    if ( crt_state_depth == 0 ) {
349
			adjust_column ( crt_token ) ;
350
			return ;
351
		    }
352
		    break ;
353
		}
354
	    }
355
	}
356
	stmt_loc = crt_loc ;
357
    }
358
    return ;
359
}
360
 
361
 
362
/*
363
    BLOCK NAMESPACE
364
 
365
    This variable can be set to make begin_compound_stmt use an existing
366
    namespace rather than creating a new one.
367
*/
368
 
369
NAMESPACE block_namespace = NULL_nspace ;
370
 
371
 
372
/*
373
    BEGIN A COMPOUND STATEMENT
374
 
375
    These routine begins the construction of a compound statement.  If
376
    scope is true then this compound statement also establishes a scope.
377
    A compound statement consists of a list of statements (the first of
378
    which is always a dummy null expression) plus a pointer indicating
379
    where the next statement to be added to the compound statement is to
380
    go.  For simple statement lists this is the last element of the list,
381
    but if labels or declarations are introduced then any statements added
382
    subsequently will go at the end of the dummy block introduced by
383
    begin_label_stmt or make_decl_stmt.  The parent field of the main
384
    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
386
    of the compound statement.
387
*/
388
 
389
EXP begin_compound_stmt
390
    PROTO_N ( ( scope ) )
391
    PROTO_T ( int scope )
392
{
393
    TYPE t ;
394
    NAMESPACE ns ;
395
    EXP e = NULL_exp ;
396
    LIST ( EXP ) stmts ;
397
    NAMESPACE cns = NULL_nspace ;
398
 
399
    /* Create block namespace */
400
    if ( scope > 0 ) {
401
	ns = block_namespace ;
402
	if ( IS_NULL_nspace ( ns ) ) {
403
	    /* Create new namespace */
404
	    unsigned tag = nspace_block_tag ;
405
	    if ( scope == 2 ) tag = nspace_dummy_tag ;
406
	    cns = crt_namespace ;
407
	    ns = make_namespace ( crt_func_id, tag, 0 ) ;
408
	    push_namespace ( ns ) ;
409
	} 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 ;
415
	}
416
	IGNORE incr_value ( OPT_VAL_statement_depth ) ;
417
    } else {
418
	ns = NULL_nspace ;
419
    }
420
 
421
    /* Create compound statement */
422
    t = ( unreached_code ? type_bottom : type_void ) ;
423
    if ( record_location && scope >= 0 ) {
424
	/* Record start of block */
425
	adjust_line ( scope ) ;
426
	adjusted_line = 0 ;
427
	MAKE_exp_location ( t, stmt_loc, e, e ) ;
428
	if ( do_scope ) dump_begin_scope ( NULL_id, ns, cns, &crt_loc ) ;
429
    }
430
    CONS_exp ( e, NULL_list ( EXP ), stmts ) ;
431
    MAKE_exp_sequence ( t, stmts, stmts, ns, 0, e ) ;
432
    COPY_exp ( exp_sequence_parent ( e ), e ) ;
433
    return ( e ) ;
434
}
435
 
436
 
437
/*
438
    MARK THE START OF A COMPOUND STATEMENT
439
 
440
    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
442
    open brace is encountered to record the actual position of the start
443
    of the block.
444
*/
445
 
446
void mark_compound_stmt
447
    PROTO_N ( ( prev ) )
448
    PROTO_T ( EXP prev )
449
{
450
    if ( record_location ) {
451
	LIST ( EXP ) stmts = DEREF_list ( exp_sequence_first ( prev ) ) ;
452
	EXP stmt = DEREF_exp ( HEAD_list ( stmts ) ) ;
453
	if ( !IS_NULL_exp ( stmt ) && IS_exp_location ( stmt ) ) {
454
	    adjust_line ( 1 ) ;
455
	    adjusted_line = 0 ;
456
	    COPY_loc ( exp_location_end ( stmt ), stmt_loc ) ;
457
	}
458
    }
459
    return ;
460
}
461
 
462
 
463
/*
464
    EXTEND A COMPOUND STATEMENT
465
 
466
    This routine adds the statement stmt to the end of the compound
467
    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.
469
*/
470
 
471
static EXP extend_compound_stmt
472
    PROTO_N ( ( prev, stmt, loc ) )
473
    PROTO_T ( EXP prev X EXP stmt X int loc )
474
{
475
    EXP body ;
476
    EXP parent ;
477
    LIST ( EXP ) elem ;
478
    LIST ( EXP ) elem0 ;
479
    LIST ( EXP ) stmts ;
480
 
481
    /* Allow for null statements */
482
    if ( IS_NULL_exp ( stmt ) ) return ( prev ) ;
483
 
484
    /* Add statement to list */
485
    stmts = DEREF_list ( exp_sequence_last ( prev ) ) ;
486
    CONS_exp ( stmt, NULL_list ( EXP ), elem ) ;
487
    COPY_list ( PTR_TAIL_list ( stmts ), elem ) ;
488
    elem0 = elem ;
489
 
490
    /* Set the parent of stmt */
491
    parent = DEREF_exp ( exp_sequence_parent ( prev ) ) ;
492
    set_parent_stmt ( stmt, parent ) ;
493
 
494
    /* Find location of next statement */
495
    switch ( TAG_exp ( stmt ) ) {
496
	case exp_decl_stmt_tag : {
497
	    /* Transfer to the body of a declaration */
498
	    unsigned tag ;
499
	    body = stmt ;
500
	    do {
501
		body = DEREF_exp ( exp_decl_stmt_body ( body ) ) ;
502
		tag = TAG_exp ( body ) ;
503
	    } while ( tag == exp_decl_stmt_tag ) ;
504
	    if ( tag == exp_sequence_tag ) {
505
		elem = DEREF_list ( exp_sequence_last ( body ) ) ;
506
		COPY_exp ( exp_sequence_parent ( prev ), body ) ;
507
	    }
508
	    loc = 0 ;
509
	    break ;
510
	}
511
	case exp_label_stmt_tag : {
512
	    /* Transfer to the body of a labelled statement */
513
	    body = DEREF_exp ( exp_label_stmt_body ( stmt ) ) ;
514
	    if ( IS_exp_sequence ( body ) ) {
515
		elem = DEREF_list ( exp_sequence_last ( body ) ) ;
516
		COPY_exp ( exp_sequence_parent ( prev ), body ) ;
517
	    }
518
	    loc = 0 ;
519
	    break ;
520
	}
521
	case exp_location_tag :
522
	case exp_thrown_tag : {
523
	    /* Don't record location in these cases */
524
	    loc = 0 ;
525
	    break ;
526
	}
527
    }
528
    COPY_list ( exp_sequence_last ( prev ), elem ) ;
529
 
530
    /* Record statement location */
531
    if ( record_location ) {
532
	adjust_line ( 1 ) ;
533
	if ( loc ) {
534
	    TYPE t = DEREF_type ( exp_type ( stmt ) ) ;
535
	    MAKE_exp_location ( t, stmt_loc, stmt, stmt ) ;
536
	    COPY_exp ( HEAD_list ( elem0 ), stmt ) ;
537
	}
538
    }
539
 
540
    /* Unreached code analysis */
541
    if ( is_bottom ( stmt ) ) {
542
	COPY_type ( exp_type ( prev ), type_bottom ) ;
543
    }
544
    return ( prev ) ;
545
}
546
 
547
 
548
/*
549
    ADD A STATEMENT TO A COMPOUND STATEMENT
550
 
551
    This routine adds the statement stmt to the compound statement prev,
552
    returning the resulting compound statement.  It differs from the
553
    previous routine in taking any declarations in stmt into account.
554
    This is done using the last field of the current namespace which keeps
555
    track of the last variable in the block for which a declaration
556
    statement has been introduced.  The treatment of labelled statements
557
    is tricky - the declarations need to be inserted between the label
558
    and its body.
559
*/
560
 
561
EXP add_compound_stmt
562
    PROTO_N ( ( prev, stmt ) )
563
    PROTO_T ( EXP prev X EXP stmt )
564
{
565
    EXP parent = NULL_exp ;
566
    LIST ( EXP ) last = NULL_list ( EXP ) ;
567
    NAMESPACE ns = DEREF_nspace ( exp_sequence_decl ( prev ) ) ;
568
    if ( !IS_NULL_nspace ( ns ) ) {
569
	MEMBER p = DEREF_member ( nspace_last ( ns ) ) ;
570
	MEMBER q = DEREF_member ( nspace_prev ( ns ) ) ;
571
	if ( !EQ_member ( p, q ) ) {
572
	    /* Create declaration statement */
573
	    int vars = 0 ;
574
	    EXP decl = make_decl_stmt ( p, q, &vars ) ;
575
	    if ( !IS_NULL_exp ( stmt ) && IS_exp_label_stmt ( stmt ) ) {
576
		/* Labels come before declarations */
577
		EXP body = DEREF_exp ( exp_label_stmt_body ( stmt ) ) ;
578
		if ( IS_exp_sequence ( body ) ) {
579
		    last = DEREF_list ( exp_sequence_last ( body ) ) ;
580
		    body = DEREF_exp ( HEAD_list ( last ) ) ;
581
		    if ( !IS_NULL_exp ( body ) ) {
582
			EXP b = body ;
583
			if ( IS_exp_location ( b ) ) {
584
			    b = DEREF_exp ( exp_location_arg ( b ) ) ;
585
			}
586
			if ( !IS_NULL_exp ( b ) ) {
587
			    COPY_exp ( HEAD_list ( last ), NULL_exp ) ;
588
			}
589
		    }
590
		    last = NULL_list ( EXP ) ;
591
		    prev = extend_compound_stmt ( prev, stmt, 1 ) ;
592
		    stmt = body ;
593
		}
594
	    }
595
	    if ( !vars ) {
596
		last = DEREF_list ( exp_sequence_last ( prev ) ) ;
597
		parent = DEREF_exp ( exp_sequence_parent ( prev ) ) ;
598
	    }
599
	    prev = extend_compound_stmt ( prev, decl, 0 ) ;
600
	    COPY_member ( nspace_prev ( ns ), p ) ;
601
	}
602
    }
603
    if ( !IS_NULL_exp ( stmt ) ) {
604
	/* Add the new statement */
605
	prev = extend_compound_stmt ( prev, stmt, 1 ) ;
606
    }
607
    if ( !IS_NULL_list ( last ) ) {
608
	/* Restrict scope of temporaries to stmt */
609
	last = END_list ( last ) ;
610
	COPY_list ( exp_sequence_last ( prev ), last ) ;
611
	COPY_exp ( exp_sequence_parent ( prev ), parent ) ;
612
    }
613
    adjusted_line = 0 ;
614
    return ( prev ) ;
615
}
616
 
617
 
618
/*
619
    END A COMPOUND STATEMENT
620
 
621
    This routine ends the compound statement prev.
622
*/
623
 
624
EXP end_compound_stmt
625
    PROTO_N ( ( prev ) )
626
    PROTO_T ( EXP prev )
627
{
628
    /* Take local declarations out of scope */
629
    int blk = DEREF_int ( exp_sequence_block ( prev ) ) ;
630
    NAMESPACE ns = DEREF_nspace ( exp_sequence_decl ( prev ) ) ;
631
    if ( !IS_NULL_nspace ( ns ) ) {
632
	if ( check_namespace ( ns, prev, ANON_NONE, 1 ) ) {
633
	    if ( blk == 0 ) {
634
		COPY_int ( exp_sequence_block ( prev ), 1 ) ;
635
	    }
636
	}
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 ) ;
643
}
644
 
645
 
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
/*
684
    CONSTRUCT A DECLARATION STATEMENT
685
 
686
    This routine constructs a series of nested declaration statements
687
    corresponding to the given list of namespace members.  p gives the
688
    last member of the current block namespace defined, while q gives
689
    the last member defined before this declaration.  The body of a
690
    declaration statement consists of the rest of the statements in the
691
    enclosing block.  That is:
692
 
693
			{
694
			    stmt1 ;
695
			    ....
696
			    decl1 ;
697
			    decl2 ;
698
			    ....
699
			    body1 ;
700
			    ....
701
			}
702
 
703
    is transformed into:
704
 
705
			{
706
			    stmt1 ;
707
			    ....
708
			    decl1 ; {
709
				decl2 ; {
710
				    .... {
711
					body1 ;
712
					....
713
				    }
714
				}
715
			    }
716
			}
717
 
718
    except that the introduced blocks do not establish scopes.  Any
719
    temporary variables introduced are declared before the normal
720
    variables regardless of their actual order of declaration.
721
*/
722
 
723
EXP make_decl_stmt
724
    PROTO_N ( ( p, q, vars ) )
725
    PROTO_T ( MEMBER p X MEMBER q X int *vars )
726
{
727
    MEMBER r = p ;
728
    unsigned temps = 0 ;
729
    IDENTIFIER init = NULL_id ;
730
    LIST ( IDENTIFIER ) destr = NULL_list ( IDENTIFIER ) ;
731
    EXP e = begin_compound_stmt ( -1 ) ;
732
 
733
    /* Scan through members */
734
    while ( !EQ_member ( r, q ) ) {
735
	IDENTIFIER id = DEREF_id ( member_id ( r ) ) ;
736
	if ( !IS_NULL_id ( id ) && IS_id_variable ( id ) ) {
737
	    /* Construct declaration statement */
738
	    DECL_SPEC ds = DEREF_dspec ( id_storage ( id ) ) ;
739
	    if ( ds & dspec_temp ) {
740
		/* Temporary variables */
741
		if ( !( ds & dspec_ignore ) ) {
742
		    if ( ds & dspec_register ) {
743
			EXP term = DEREF_exp ( id_variable_term ( id ) ) ;
744
			if ( !IS_NULL_exp ( term ) ) {
745
			    CONS_id ( id, destr, destr ) ;
746
			}
747
		    }
748
		    temps++ ;
749
		}
750
	    } else if ( ds & dspec_linkage ) {
751
		/* External variables */
752
		/* EMPTY */
753
	    } else if ( ( ds & dspec_reserve ) && !is_anon_member ( id ) ) {
754
		/* Injected variables */
755
		/* EMPTY */
756
	    } else {
757
		EXP d ;
758
		TYPE t = DEREF_type ( id_variable_type ( id ) ) ;
759
		EXP def = DEREF_exp ( id_variable_init ( id ) ) ;
760
		EXP term = DEREF_exp ( id_variable_term ( id ) ) ;
761
		if ( !IS_NULL_exp ( term ) ) have_destructor = 1 ;
762
		if ( !IS_NULL_exp ( def ) && !IS_exp_null ( def ) ) {
763
		    /* Identifier is initialised */
764
		    init = id ;
765
		}
766
		MAKE_exp_decl_stmt ( t, id, e, d ) ;
767
		set_parent_stmt ( e, d ) ;
768
		*vars = 1 ;
769
		e = d ;
770
	    }
771
	}
772
	r = DEREF_member ( member_next ( r ) ) ;
773
    }
774
 
775
    /* Scan through again for temporary variables */
776
    if ( temps ) {
777
	e = make_temp_decl ( p, q, e ) ;
778
	if ( !IS_NULL_list ( destr ) ) {
779
	    /* NOT YET IMPLEMENTED */
780
	    DESTROY_list ( destr, SIZE_id ) ;
781
	}
782
    }
783
 
784
    /* Only report unreached declarations if they are initialised */
785
    if ( !IS_NULL_id ( init ) && unreached_code ) {
786
	if ( !unreached_last ) {
787
	    LOCATION loc ;
788
	    DEREF_loc ( id_loc ( init ), loc ) ;
789
	    report ( loc, ERR_stmt_stmt_unreach () ) ;
790
	    unreached_last = 1 ;
791
	}
792
    }
793
    return ( e ) ;
794
}
795
 
796
 
797
/*
798
    BIND TEMPORARY VARIABLES TO AN EXPRESSION
799
 
800
    This routine binds any temporary variables declared in e to the
801
    expression.  Reference conversions are also applied, but any
802
    parentheses are preserved for the benefit of the assignment in
803
    boolean check.
804
*/
805
 
806
EXP bind_temporary
807
    PROTO_N ( ( e ) )
808
    PROTO_T ( EXP e )
809
{
810
    if ( !IS_NULL_exp ( e ) ) {
811
	NAMESPACE ns = crt_namespace ;
812
	unsigned tag = TAG_exp ( e ) ;
813
	e = convert_reference ( e, REF_NORMAL ) ;
814
	if ( !IS_NULL_nspace ( ns ) && IS_nspace_block_etc ( ns ) ) {
815
	    MEMBER p = DEREF_member ( nspace_last ( ns ) ) ;
816
	    MEMBER q = DEREF_member ( nspace_prev ( ns ) ) ;
817
	    if ( !EQ_member ( p, q ) ) {
818
		e = make_temp_decl ( p, q, e ) ;
819
		COPY_member ( nspace_prev ( ns ), p ) ;
820
	    }
821
	}
822
	if ( tag == exp_paren_tag && option ( OPT_bool_assign ) ) {
823
	    e = make_paren_exp ( e ) ;
824
	}
825
    }
826
    return ( e ) ;
827
}
828
 
829
 
830
/*
831
    DISCARD AN EXPRESSION
832
 
833
    This routine discards the expression e.  If e is an lvalue then the
834
    lvalue conversions are checked but not performed.
835
*/
836
 
837
EXP make_discard_exp
838
    PROTO_N ( ( e ) )
839
    PROTO_T ( EXP e )
840
{
841
    if ( !IS_NULL_exp ( e ) ) {
842
	unsigned tag = TAG_exp ( e ) ;
843
	TYPE t = DEREF_type ( exp_type ( e ) ) ;
844
	switch ( TAG_type ( t ) ) {
845
	    case type_top_tag :
846
	    case type_bottom_tag : {
847
		/* Void types */
848
		break ;
849
	    }
850
	    case type_bitfield_tag : {
851
		/* Remove bitfield components */
852
		if ( tag == exp_contents_tag ) {
853
		    e = DEREF_exp ( exp_contents_ptr ( e ) ) ;
854
		    tag = TAG_exp ( e ) ;
855
		}
856
		if ( tag == exp_indir_tag ) {
857
		    e = DEREF_exp ( exp_indir_ptr ( e ) ) ;
858
		    tag = TAG_exp ( e ) ;
859
		    if ( tag == exp_add_ptr_tag ) {
860
			e = DEREF_exp ( exp_add_ptr_ptr ( e ) ) ;
861
			tag = TAG_exp ( e ) ;
862
			if ( tag == exp_address_tag ) {
863
			    e = DEREF_exp ( exp_address_arg ( e ) ) ;
864
			    tag = TAG_exp ( e ) ;
865
			}
866
		    }
867
		}
868
		break ;
869
	    }
870
	    case type_array_tag :
871
	    case type_func_tag :
872
	    case type_templ_tag : {
873
		/* Check for overloaded functions */
874
		e = convert_lvalue ( e ) ;
875
		tag = TAG_exp ( e ) ;
876
		break ;
877
	    }
878
	    case type_token_tag : {
879
		if ( is_templ_type ( t ) ) {
880
		    /* Mark template parameters */
881
		    MAKE_exp_op ( t, lex_void, e, NULL_exp, e ) ;
882
		    tag = exp_op_tag ;
883
		    break ;
884
		}
885
		goto default_lab ;
886
	    }
887
	    default :
888
	    default_lab : {
889
		/* Check lvalue conversions */
890
		ERROR err ;
891
		CV_SPEC qual = DEREF_cv ( type_qual ( t ) ) ;
892
		if ( !( qual & cv_lvalue ) ) break ;
893
		if ( qual == ( cv_lvalue | cv_const ) ) {
894
		    if ( tag == exp_identifier_tag ) {
895
			e = convert_const ( e ) ;
896
			tag = TAG_exp ( e ) ;
897
			break ;
898
		    }
899
		}
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
	}
926
    }
927
    return ( e ) ;
928
}
929
 
930
 
931
/*
932
    CHECK A DISCARDED EXPRESSION
933
 
934
    This routine checks whether discarding the expression e should be
935
    warned about.
936
*/
937
 
938
static int check_discard_exp
939
    PROTO_N ( ( e ) )
940
    PROTO_T ( EXP e )
941
{
942
    if ( !IS_NULL_exp ( e ) ) {
943
	switch ( TAG_exp ( e ) ) {
944
	    case exp_indir_tag : {
945
		/* Ignore indirection expressions */
946
		EXP a = DEREF_exp ( exp_indir_ptr ( e ) ) ;
947
		return ( check_discard_exp ( a ) ) ;
948
	    }
949
	    case exp_contents_tag : {
950
		/* Ignore contents expressions */
951
		EXP a = DEREF_exp ( exp_contents_ptr ( e ) ) ;
952
		return ( check_discard_exp ( a ) ) ;
953
	    }
954
	    case exp_comma_tag : {
955
		/* Examine final component of comma expression */
956
		LIST ( EXP ) p = DEREF_list ( exp_comma_args ( e ) ) ;
957
		EXP a = DEREF_exp ( HEAD_list ( END_list ( p ) ) ) ;
958
		return ( check_discard_exp ( a ) ) ;
959
	    }
960
	    case exp_postinc_tag : {
961
		/* Discard postincrement expressions */
962
		COPY_exp ( exp_postinc_value ( e ), NULL_exp ) ;
963
		goto assign_lab ;
964
	    }
965
	    case exp_assign_tag :
966
	    case exp_init_tag :
967
	    case exp_preinc_tag :
968
	    case exp_decl_stmt_tag :
969
	    assign_lab : {
970
		/* Assignments and declarations are allowed */
971
		if ( !IS_NULL_id ( made_temporary ) ) {
972
		    report ( crt_loc, ERR_stmt_expr_discard_val () ) ;
973
		}
974
		break ;
975
	    }
976
	    case exp_func_tag : {
977
		/* Discarded function return */
978
		report ( crt_loc, ERR_stmt_expr_discard_func () ) ;
979
		break ;
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
		}
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
	}
1003
    }
1004
    return ( 0 ) ;
1005
}
1006
 
1007
 
1008
/*
1009
    CONSTRUCT AN EXPRESSION STATEMENT
1010
 
1011
    This routine constructs an expression statement from the expression e.
1012
    This is basically an identity operation, however various reachability
1013
    and discarded value checks (which need to take account of certain
1014
    special forms) are applied.
1015
*/
1016
 
1017
EXP make_exp_stmt
1018
    PROTO_N ( ( e ) )
1019
    PROTO_T ( EXP e )
1020
{
1021
    TYPE t ;
1022
 
1023
    /* Perform operand conversion */
1024
    if ( IS_NULL_exp ( e ) ) return ( e ) ;
1025
    e = convert_reference ( e, REF_NORMAL ) ;
1026
    made_temporary = NULL_id ;
1027
    e = make_discard_exp ( e ) ;
1028
 
1029
    /* Check the type of e */
1030
    t = DEREF_type ( exp_type ( e ) ) ;
1031
    switch ( TAG_type ( t ) ) {
1032
	case type_bottom_tag : {
1033
	    /* Unreached code */
1034
	    unreached_code = 1 ;
1035
	    return ( e ) ;
1036
	}
1037
	case type_top_tag :
1038
	case type_error_tag : {
1039
	    /* No effect */
1040
	    return ( e ) ;
1041
	}
1042
	case type_token_tag : {
1043
	    /* Check for template types */
1044
	    if ( is_templ_type ( t ) ) {
1045
		MAKE_exp_op ( t, lex_discard, e, NULL_exp, e ) ;
1046
		return ( e ) ;
1047
	    }
1048
	    break ;
1049
	}
1050
    }
1051
 
1052
    /* Check discarded value */
1053
    if ( check_discard_exp ( e ) ) {
1054
	MAKE_exp_cast ( type_void, CONV_ELLIPSIS, e, e ) ;
1055
    }
1056
    return ( e ) ;
1057
}
1058
 
1059
 
1060
/*
1061
    CURRENT CONDITION
1062
 
1063
    This value is used to hold an indicating of the value of the condition
1064
    in the current conditional or iteration statement.  There are four
1065
    possible values corresponding to true, false and interminate constant
1066
    conditions, plus non-constant conditions.
1067
*/
1068
 
1069
unsigned crt_condition = BOOL_INVALID ;
1070
 
1071
 
1072
/*
1073
    CHECK A CONDITION
1074
 
1075
    This routine converts the condition expression cond to a boolean,
1076
    including setting the value of crt_condition.  Note that the condition
1077
    can be a condition declaration or the null expression (indicating an
1078
    absent condition in a for-statement).  In the former case the
1079
    declaration is returned via pd.  op denotes the context for the
1080
    condition (an if-statement etc.).
1081
*/
1082
 
1083
EXP check_cond
1084
    PROTO_N ( ( cond, pd, op ) )
1085
    PROTO_T ( EXP cond X EXP *pd X int op )
1086
{
1087
    EXP c ;
1088
    TYPE tc ;
1089
    unsigned ca ;
1090
    unsigned cc ;
1091
    unsigned tag ;
1092
    EXP a = NULL_exp ;
1093
    ERROR err = NULL_err ;
1094
 
1095
    /* Check for null expressions */
1096
    if ( IS_NULL_exp ( cond ) ) {
1097
	c = make_bool_exp ( BOOL_TRUE, exp_int_lit_tag ) ;
1098
	crt_condition = BOOL_TRUE ;
1099
	if ( record_location && op != lex_cond_Hop ) {
1100
	    /* Mark position of condition */
1101
	    TYPE t = DEREF_type ( exp_type ( c ) ) ;
1102
	    MAKE_exp_location ( t, crt_loc, c, c ) ;
1103
	}
1104
	return ( c ) ;
1105
    }
1106
 
1107
    /* Check for condition declarations */
1108
    tag = TAG_exp ( cond ) ;
1109
    if ( tag == exp_paren_tag ) {
1110
	TYPE t ;
1111
	DESTROY_exp_paren ( destroy, t, cond, cond ) ;
1112
	UNUSED ( t ) ;
1113
    }
1114
    if ( IS_exp_decl_stmt ( cond ) ) {
1115
	DECL_SPEC ds ;
1116
	IDENTIFIER id ;
1117
	*pd = cond ;
1118
	do {
1119
	    /* Step over temporary variables */
1120
	    id = DEREF_id ( exp_decl_stmt_id ( cond ) ) ;
1121
	    cond = DEREF_exp ( exp_decl_stmt_body ( cond ) ) ;
1122
	} while ( IS_exp_decl_stmt ( cond ) ) ;
1123
	ds = DEREF_dspec ( id_storage ( id ) ) ;
1124
	if ( IS_id_variable ( id ) && !( ds & dspec_temp ) ) {
1125
	    /* This doesn't count as a use of id */
1126
	    EXP b = DEREF_exp ( id_variable_init ( id ) ) ;
1127
	    TYPE t = DEREF_type ( id_variable_type ( id ) ) ;
1128
	    if ( !IS_NULL_exp ( b ) ) {
1129
		if ( !IS_type_compound ( t ) ) {
1130
		    /* Condition value is used in constant checks */
1131
		    a = convert_boolean ( b, exp_paren_tag, KILL_err ) ;
1132
		}
1133
		if ( op == lex_while || op == lex_for ) {
1134
		    /* Move initialisation into loop condition */
1135
		    MAKE_exp_init ( t, id, b, cond ) ;
1136
		    COPY_exp ( id_variable_init ( id ), NULL_exp ) ;
1137
		    ds |= dspec_explicit ;
1138
		    COPY_dspec ( id_storage ( id ), ds ) ;
1139
		} else {
1140
		    MAKE_exp_identifier ( t, id, qual_none, cond ) ;
1141
		}
1142
	    } else {
1143
		MAKE_exp_identifier ( t, id, qual_none, cond ) ;
1144
	    }
1145
	}
1146
    }
1147
 
1148
    /* Convert the condition to a boolean */
1149
    c = convert_reference ( cond, REF_NORMAL ) ;
1150
    tc = DEREF_type ( exp_type ( c ) ) ;
1151
    ca = type_category ( &tc ) ;
1152
    if ( IS_TYPE_CLASS ( ca ) ) {
1153
	/* Allow for conversion functions */
1154
	c = convert_conv ( type_bool, c, &err, CAST_IMPLICIT ) ;
1155
    } else if ( IS_TYPE_TEMPL ( ca ) ) {
1156
	/* Allow for template parameters */
1157
	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 {
1192
	    /* Report non-literal constants in iteration statements */
1193
	    if ( !is_literal ( a ) ) {
1194
		ERROR err2 ;
1195
		switch ( op ) {
1196
		    case lex_do : err2 = ERR_stmt_do_const () ; break ;
1197
		    case lex_for : err2 = ERR_stmt_for_const () ; break ;
1198
		    case lex_while : err2 = ERR_stmt_while_const () ; break ;
1199
		    default : err2 = NULL_err ; break ;
1200
		}
1201
		report ( crt_loc, err2 ) ;
1202
	    }
1203
	}
1204
    }
1205
    crt_condition = cc ;
1206
    if ( record_location && op != lex_cond_Hop ) {
1207
	/* Mark position of condition */
1208
	TYPE t = DEREF_type ( exp_type ( c ) ) ;
1209
	MAKE_exp_location ( t, crt_loc, c, c ) ;
1210
    }
1211
    return ( c ) ;
1212
}
1213
 
1214
 
1215
/*
1216
    CHECK A CONDITIONAL BODY
1217
 
1218
    This routine is called following a conditional or loop statement
1219
    (given by op) to check for suspicious empty bodies which may be
1220
    due to a misplaced semicolon.
1221
*/
1222
 
1223
void check_empty_stmt
1224
    PROTO_N ( ( op ) )
1225
    PROTO_T ( int op )
1226
{
1227
    if ( !suppress_quality ) {
1228
	int t = crt_lex_token ;
1229
	if ( t == lex_semicolon ) {
1230
	    PPTOKEN *p = crt_token ;
1231
	    NAMESPACE ns = crt_lookup ;
1232
	    t = next_token () ;
1233
	    if ( t == lex_open_Hbrace_H1 ) {
1234
		/* Have 'op ; {', probably mean 'op {' */
1235
		report ( crt_loc, ERR_stmt_stmt_empty ( op ) ) ;
1236
	    }
1237
	    crt_lookup = ns ;
1238
	    crt_token = p ;
1239
	}
1240
    }
1241
    return ;
1242
}
1243
 
1244
 
1245
/*
1246
    CREATE A CONDITION DECLARATION
1247
 
1248
    This routine combines the condition declaration d with its associated
1249
    condition e.  If tmp is true a temporary variable is introduced for
1250
    the value of e.
1251
*/
1252
 
1253
static EXP make_cond_decl
1254
    PROTO_N ( ( d, e, tmp ) )
1255
    PROTO_T ( EXP d X EXP e X int tmp )
1256
{
1257
    EXP b ;
1258
    EXP c = d ;
1259
    if ( tmp ) {
1260
	/* Introduce temporary variable */
1261
	ERROR err = NULL_err ;
1262
	TYPE t = DEREF_type ( exp_type ( e ) ) ;
1263
	e = make_temporary ( t, e, NULL_exp, 0, &err ) ;
1264
	if ( !IS_NULL_err ( err ) ) report ( crt_loc, err ) ;
1265
    }
1266
    for ( ; ; ) {
1267
	b = DEREF_exp ( exp_decl_stmt_body ( c ) ) ;
1268
	if ( !IS_exp_decl_stmt ( b ) ) break ;
1269
	c = b ;
1270
    }
1271
    if ( IS_exp_sequence ( b ) ) free_exp ( b, 0 ) ;
1272
    COPY_exp ( exp_decl_stmt_body ( c ), e ) ;
1273
    set_parent_stmt ( e, c ) ;
1274
    if ( tmp ) {
1275
	/* Result is contents of temporary variable */
1276
	e = make_id_exp ( made_temporary ) ;
1277
	e = convert_reference ( e, REF_NORMAL ) ;
1278
	e = convert_lvalue ( e ) ;
1279
	d = join_exp ( d, e ) ;
1280
    }
1281
    return ( d ) ;
1282
}
1283
 
1284
 
1285
/*
1286
    FIND A CONDITIONAL STATEMENT
1287
 
1288
    This routine finds the conditional statement associated with e.
1289
    e may contain an enclosing condition declaration.
1290
*/
1291
 
1292
static EXP find_cond_stmt
1293
    PROTO_N ( ( e ) )
1294
    PROTO_T ( EXP e )
1295
{
1296
    unsigned tag = TAG_exp ( e ) ;
1297
    while ( tag == exp_decl_stmt_tag ) {
1298
	e = DEREF_exp ( exp_decl_stmt_body ( e ) ) ;
1299
	tag = TAG_exp ( e ) ;
1300
    }
1301
    while ( tag == exp_sequence_tag ) {
1302
	LIST ( EXP ) p = DEREF_list ( exp_sequence_first ( e ) ) ;
1303
	p = TAIL_list ( p ) ;
1304
	e = DEREF_exp ( HEAD_list ( p ) ) ;
1305
	tag = TAG_exp ( e ) ;
1306
	if ( tag == exp_location_tag ) {
1307
	    e = DEREF_exp ( exp_location_arg ( e ) ) ;
1308
	    tag = TAG_exp ( e ) ;
1309
	}
1310
    }
1311
    return ( e ) ;
1312
}
1313
 
1314
 
1315
/*
1316
    BEGIN AN IF STATEMENT
1317
 
1318
    This routine begins the construction of an if statement with condition
1319
    cond.  In this and all routines involving a condition, a constant true
1320
    condition is replaced by the null expression.
1321
*/
1322
 
1323
EXP begin_if_stmt
1324
    PROTO_N ( ( cond ) )
1325
    PROTO_T ( EXP cond )
1326
{
1327
    EXP e ;
1328
    EXP d = NULL_exp ;
1329
    EXP b = begin_label_stmt ( NULL_id, lex_if ) ;
1330
    IDENTIFIER lab = DEREF_id ( exp_label_stmt_label ( b ) ) ;
1331
 
1332
    /* Check the condition */
1333
    cond = check_cond ( cond, &d, lex_if ) ;
1334
    if ( crt_condition == BOOL_FALSE ) unreached_code = 1 ;
1335
 
1336
    /* Construct the result */
1337
    MAKE_exp_if_stmt ( type_void, cond, NULL_exp, NULL_exp, lab, e ) ;
1338
    check_empty_stmt ( lex_if ) ;
1339
    set_parent_stmt ( b, e ) ;
1340
    if ( !IS_NULL_exp ( d ) ) e = make_cond_decl ( d, e, 0 ) ;
1341
    return ( e ) ;
1342
}
1343
 
1344
 
1345
/*
1346
    CONTINUE AN IF STATEMENT
1347
 
1348
    This routine continues the construction of an if statement by adding
1349
    the statement, right, which is evaluated if the condition is true.
1350
    This is called just before any else clause is processed.
1351
*/
1352
 
1353
EXP cont_if_stmt
1354
    PROTO_N ( ( prev, right ) )
1355
    PROTO_T ( EXP prev X EXP right )
1356
{
1357
    /* Do unreached code analysis */
1358
    EXP e ;
1359
    if ( crt_condition == BOOL_TRUE ) {
1360
	unreached_code = 1 ;
1361
    } else {
1362
	unreached_code = unreached_prev ;
1363
    }
1364
 
1365
    /* Copy the right code into the conditional */
1366
    e = find_cond_stmt ( prev ) ;
1367
    COPY_exp ( exp_if_stmt_true_code ( e ), right ) ;
1368
    set_parent_stmt ( right, e ) ;
1369
    return ( prev ) ;
1370
}
1371
 
1372
 
1373
/*
1374
    COMPLETE AN IF STATEMENT
1375
 
1376
    This routine completes the construction of an if statement by adding
1377
    the statement, wrong, which is evaluated if the condition is false.
1378
*/
1379
 
1380
EXP end_if_stmt
1381
    PROTO_N ( ( prev, wrong ) )
1382
    PROTO_T ( EXP prev X EXP wrong )
1383
{
1384
    /* Do unreached code analysis */
1385
    EXP e = find_cond_stmt ( prev ) ;
1386
    EXP right = DEREF_exp ( exp_if_stmt_true_code ( e ) ) ;
1387
    if ( is_bottom ( wrong ) ) {
1388
	if ( is_bottom ( right ) ) {
1389
	    /* Don't reach the end of either branch */
1390
	    COPY_type ( exp_type ( prev ), type_bottom ) ;
1391
	    COPY_type ( exp_type ( e ), type_bottom ) ;
1392
	    unreached_code = 1 ;
1393
	} else if ( crt_condition == BOOL_FALSE ) {
1394
	    /* Don't reach the end of the taken branch */
1395
	    COPY_type ( exp_type ( e ), type_bottom ) ;
1396
	    unreached_code = 1 ;
1397
	} else {
1398
	    /* Reach the end of one branch */
1399
	    unreached_code = unreached_prev ;
1400
	}
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
 
1416
    /* Copy the wrong code into the conditional */
1417
    COPY_exp ( exp_if_stmt_false_code ( e ), wrong ) ;
1418
    set_parent_stmt ( wrong, e ) ;
1419
    return ( prev ) ;
1420
}
1421
 
1422
 
1423
/*
1424
    STACK OF CURRENTLY ACTIVE ITERATION AND SWITCH STATEMENTS
1425
 
1426
    This stack is used to record a nested list of iteration and switch
1427
    statements in order to determine which statement a break, continue,
1428
    case or default refers to.
1429
*/
1430
 
1431
STACK ( EXP ) crt_loop_stack = NULL_stack ( EXP ) ;
1432
 
1433
 
1434
/*
1435
    BEGIN A DO STATEMENT
1436
 
1437
    This routine begins the construction of a do statement.
1438
*/
1439
 
1440
EXP begin_do_stmt
1441
    PROTO_Z ()
1442
{
1443
    EXP e ;
1444
 
1445
    /* Construct the break and continue destinations */
1446
    EXP bk = begin_label_stmt ( NULL_id, lex_break ) ;
1447
    EXP cn = begin_label_stmt ( NULL_id, lex_continue ) ;
1448
    EXP lp = begin_label_stmt ( NULL_id, lex_do ) ;
1449
    IDENTIFIER bk_lab = DEREF_id ( exp_label_stmt_label ( bk ) ) ;
1450
    IDENTIFIER cn_lab = DEREF_id ( exp_label_stmt_label ( cn ) ) ;
1451
    IDENTIFIER lp_lab = DEREF_id ( exp_label_stmt_label ( lp ) ) ;
1452
 
1453
    /* Construct the do statement */
1454
    MAKE_exp_do_stmt ( type_void, NULL_exp, bk_lab, cn_lab, lp_lab, e ) ;
1455
    set_parent_stmt ( bk, e ) ;
1456
    set_parent_stmt ( cn, e ) ;
1457
    set_parent_stmt ( lp, e ) ;
1458
 
1459
    /* Add statement to loop stack */
1460
    PUSH_exp ( e, crt_loop_stack ) ;
1461
    return ( e ) ;
1462
}
1463
 
1464
 
1465
/*
1466
    COMPLETE A DO STATEMENT
1467
 
1468
    This routine completes the construction of the do statement prev
1469
    using the statement body and the condition cond.
1470
*/
1471
 
1472
EXP end_do_stmt
1473
    PROTO_N ( ( prev, body, cond ) )
1474
    PROTO_T ( EXP prev X EXP body X EXP cond )
1475
{
1476
    int uc ;
1477
    IDENTIFIER bk ;
1478
    EXP d = NULL_exp ;
1479
 
1480
    /* Remove statement from loop stack */
1481
    EXP e ;
1482
    POP_exp ( e, crt_loop_stack ) ;
1483
    UNUSED ( e ) ;
1484
 
1485
    /* Convert the condition to a boolean */
1486
    cond = check_cond ( cond, &d, lex_do ) ;
1487
    if ( !IS_NULL_exp ( d ) ) cond = make_cond_decl ( d, cond, 1 ) ;
1488
 
1489
    /* Find whether the condition is reached */
1490
    uc = unreached_code ;
1491
    if ( uc ) {
1492
	IDENTIFIER cn = DEREF_id ( exp_do_stmt_cont_lab ( prev ) ) ;
1493
	if ( used_label ( cn ) == 1 ) {
1494
	    /* Reached using a continue */
1495
	    uc = unreached_prev ;
1496
	} else {
1497
	    /* Report unreached code */
1498
	    if ( !unreached_last ) {
1499
		report ( crt_loc, ERR_stmt_stmt_unreach () ) ;
1500
		unreached_last = 1 ;
1501
	    }
1502
	}
1503
    }
1504
 
1505
    /* Find whether the following statement is reached */
1506
    bk = DEREF_id ( exp_do_stmt_break_lab ( prev ) ) ;
1507
    COPY_loc ( id_loc ( bk ), crt_loc ) ;
1508
    if ( crt_condition == BOOL_TRUE ) uc = 1 ;
1509
    if ( uc ) {
1510
	if ( used_label ( bk ) == 1 ) {
1511
	    /* Can reach next statement using break */
1512
	    uc = unreached_prev ;
1513
	} else {
1514
	    COPY_type ( exp_type ( prev ), type_bottom ) ;
1515
	}
1516
    }
1517
    unreached_code = uc ;
1518
 
1519
    /* Fill in the gaps in the do statement */
1520
    COPY_exp ( exp_do_stmt_cond ( prev ), cond ) ;
1521
    COPY_exp ( exp_do_stmt_body ( prev ), body ) ;
1522
    set_parent_stmt ( body, prev ) ;
1523
    return ( prev ) ;
1524
}
1525
 
1526
 
1527
/*
1528
    BEGIN A FOR STATEMENT
1529
 
1530
    The construction of a for statement is in four stages, given by the
1531
    following four routines.  A statement of the form:
1532
 
1533
		    for ( init ; cond ; step ) body ;
1534
 
1535
    is translated to:
1536
 
1537
		    {
1538
			init ;
1539
			while ( cond ) {
1540
			    body ;
1541
			    cn : step ;
1542
			}
1543
		    }
1544
 
1545
    where an absent cond is replaced by 'true', except that 'continue' is
1546
    mapped to 'goto cn' (for the pre-ISO scoping rules the outer braces
1547
    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.
1549
    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
1551
    end_for_stmt fills in the body and completes the construction.
1552
*/
1553
 
1554
EXP begin_for_stmt
1555
    PROTO_Z ()
1556
{
1557
    EXP e ;
1558
    int scope = 0 ;
1559
    if ( option ( OPT_for_scope ) == OPTION_ON ) scope = 1 ;
1560
    e = begin_compound_stmt ( scope ) ;
1561
    return ( e ) ;
1562
}
1563
 
1564
 
1565
/*
1566
    ADD AN INITIAL STATEMENT TO A FOR STATEMENT
1567
 
1568
    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
1570
    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
1572
    the declaration statement created.
1573
*/
1574
 
1575
EXP init_for_stmt
1576
    PROTO_N ( ( prev, init ) )
1577
    PROTO_T ( EXP prev X EXP *init )
1578
{
1579
    EXP stmt = *init ;
1580
    NAMESPACE ns = DEREF_nspace ( exp_sequence_decl ( prev ) ) ;
1581
    if ( !IS_NULL_nspace ( ns ) ) {
1582
	/* Add any declarations to the block */
1583
	MEMBER p = DEREF_member ( nspace_last ( ns ) ) ;
1584
	MEMBER q = DEREF_member ( nspace_prev ( ns ) ) ;
1585
	if ( !EQ_member ( p, q ) ) {
1586
	    /* Create declaration statement */
1587
	    int vars = 0 ;
1588
	    EXP decl = make_decl_stmt ( p, q, &vars ) ;
1589
	    prev = extend_compound_stmt ( prev, decl, 0 ) ;
1590
	    COPY_member ( nspace_prev ( ns ), p ) ;
1591
	    *init = decl ;
1592
	}
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 ;
1607
    return ( prev ) ;
1608
}
1609
 
1610
 
1611
/*
1612
    ADD A CONDITION TO A FOR STATEMENT
1613
 
1614
    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
1616
    location expression.
1617
*/
1618
 
1619
EXP cond_for_stmt
1620
    PROTO_N ( ( prev, cond, step ) )
1621
    PROTO_T ( EXP prev X EXP cond X EXP step )
1622
{
1623
    EXP e ;
1624
    TYPE t ;
1625
    LOCATION loc ;
1626
    EXP d = NULL_exp ;
1627
 
1628
    /* Construct the break and continue destinations */
1629
    EXP bk = begin_label_stmt ( NULL_id, lex_break ) ;
1630
    EXP cn = begin_label_stmt ( NULL_id, lex_continue ) ;
1631
    EXP lp = begin_label_stmt ( NULL_id, lex_for ) ;
1632
    IDENTIFIER bk_lab = DEREF_id ( exp_label_stmt_label ( bk ) ) ;
1633
    IDENTIFIER cn_lab = DEREF_id ( exp_label_stmt_label ( cn ) ) ;
1634
    IDENTIFIER lp_lab = DEREF_id ( exp_label_stmt_label ( lp ) ) ;
1635
 
1636
    /* Convert condition to a boolean */
1637
    bad_crt_loc++ ;
1638
    loc = crt_loc ;
1639
    DESTROY_exp_location ( destroy, t, crt_loc, cond, cond ) ;
1640
    cond = check_cond ( cond, &d, lex_for ) ;
1641
    if ( crt_condition == BOOL_FALSE ) unreached_code = 1 ;
1642
    crt_loc = loc ;
1643
    bad_crt_loc-- ;
1644
    UNUSED ( t ) ;
1645
 
1646
    /* Deal with the step statement */
1647
    if ( !IS_NULL_exp ( step ) ) {
1648
	if ( record_location ) {
1649
	    t = DEREF_type ( exp_type ( step ) ) ;
1650
	    MAKE_exp_location ( t, stmt_loc, step, step ) ;
1651
	}
1652
	IGNORE end_label_stmt ( cn, step ) ;
1653
    }
1654
 
1655
    /* Construct the while statement */
1656
    MAKE_exp_while_stmt ( type_void, cond, bk_lab, cn_lab, lp_lab, e ) ;
1657
    set_parent_stmt ( bk, e ) ;
1658
    set_parent_stmt ( cn, e ) ;
1659
    set_parent_stmt ( lp, e ) ;
1660
    check_empty_stmt ( lex_for ) ;
1661
 
1662
    /* Add statement to loop stack */
1663
    PUSH_exp ( e, crt_loop_stack ) ;
1664
 
1665
    /* Add to for statement */
1666
    if ( !IS_NULL_exp ( d ) ) {
1667
	EXP c = d ;
1668
	LIST ( IDENTIFIER ) cids = NULL_list ( IDENTIFIER ) ;
1669
	while ( !IS_NULL_exp ( c ) && IS_exp_decl_stmt ( c ) ) {
1670
	    IDENTIFIER cid = DEREF_id ( exp_decl_stmt_id ( c ) ) ;
1671
	    CONS_id ( cid, cids, cids ) ;
1672
	    c = DEREF_exp ( exp_decl_stmt_body ( c ) ) ;
1673
	}
1674
	COPY_list ( exp_while_stmt_cond_id ( e ), cids ) ;
1675
	d = make_cond_decl ( d, e, 0 ) ;
1676
	e = d ;
1677
    }
1678
    e = add_compound_stmt ( prev, e ) ;
1679
    return ( e ) ;
1680
}
1681
 
1682
 
1683
/*
1684
    END A FOR STATEMENT
1685
 
1686
    This routine completes the construction of the for statement prev by
1687
    adding the body statement, body (see above).
1688
*/
1689
 
1690
EXP end_for_stmt
1691
    PROTO_N ( ( prev, body ) )
1692
    PROTO_T ( EXP prev X EXP body )
1693
{
1694
    TYPE t ;
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 {
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
 
1710
    /* Mark for-init variables as private */
1711
    if ( option ( OPT_for_scope ) == OPTION_WARN ) {
1712
	NAMESPACE ns = crt_namespace ;
1713
	MEMBER p = DEREF_member ( nspace_last ( ns ) ) ;
1714
	MEMBER q = DEREF_member ( nspace_prev ( ns ) ) ;
1715
	while ( !EQ_member ( p, q ) ) {
1716
	    IDENTIFIER id = DEREF_id ( member_id ( p ) ) ;
1717
	    if ( !IS_NULL_id ( id ) && IS_id_variable ( id ) ) {
1718
		DECL_SPEC ds = DEREF_dspec ( id_storage ( id ) ) ;
1719
		if ( ds & dspec_auto ) {
1720
		    ds |= dspec_private ;
1721
		    COPY_dspec ( id_storage ( id ), ds ) ;
1722
		}
1723
	    }
1724
	    p = DEREF_member ( member_next ( p ) ) ;
1725
	}
1726
    }
1727
    return ( prev ) ;
1728
}
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
 
1783
 
1784
/*
1785
    COMPLETE A WHILE STATEMENT
1786
 
1787
    This routine completes the construction of the while statement prev
1788
    using the statement body.
1789
*/
1790
 
1791
EXP end_while_stmt
1792
    PROTO_N ( ( prev, body ) )
1793
    PROTO_T ( EXP prev X EXP body )
1794
{
1795
    /* Remove statement from loop stack */
1796
    EXP e ;
1797
    IDENTIFIER bk ;
1798
    POP_exp ( e, crt_loop_stack ) ;
1799
    UNUSED ( e ) ;
1800
 
1801
    /* Find whether the end of the body is reached */
1802
    e = find_cond_stmt ( prev ) ;
1803
    if ( unreached_code ) {
1804
	IDENTIFIER cn = DEREF_id ( exp_while_stmt_cont_lab ( e ) ) ;
1805
	if ( used_label ( cn ) == 1 ) {
1806
	    /* Reached using a continue */
1807
	    unreached_code = unreached_prev ;
1808
	} else {
1809
	    /* Check for unreached continuation statement */
1810
	    LIST ( EXP ) step ;
1811
	    EXP cont = DEREF_exp ( id_label_stmt ( cn ) ) ;
1812
	    cont = DEREF_exp ( exp_label_stmt_body ( cont ) ) ;
1813
	    step = DEREF_list ( exp_sequence_first ( cont ) ) ;
1814
	    step = TAIL_list ( step ) ;
1815
	    if ( !IS_NULL_list ( step ) ) {
1816
		LOCATION loc ;
1817
		DEREF_loc ( id_loc ( cn ), loc ) ;
1818
		report ( loc, ERR_stmt_stmt_unreach () ) ;
1819
	    }
1820
	}
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
 
1836
    /* Copy the body into the result */
1837
    COPY_exp ( exp_while_stmt_body ( e ), body ) ;
1838
    set_parent_stmt ( body, e ) ;
1839
    return ( prev ) ;
1840
}
1841
 
1842
 
1843
/*
1844
    CONSTRUCT A BREAK STATEMENT
1845
 
1846
    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
1848
    to the break label.
1849
*/
1850
 
1851
EXP make_break_stmt
1852
    PROTO_Z ()
1853
{
1854
    LIST ( EXP ) st = LIST_stack ( crt_loop_stack ) ;
1855
    if ( !IS_NULL_list ( st ) ) {
1856
	IDENTIFIER lab ;
1857
	EXP stmt = DEREF_exp ( HEAD_list ( st ) ) ;
1858
	unsigned tag = TAG_exp ( stmt ) ;
1859
	if ( tag == exp_while_stmt_tag ) {
1860
	    lab = DEREF_id ( exp_while_stmt_break_lab ( stmt ) ) ;
1861
	} else if ( tag == exp_do_stmt_tag ) {
1862
	    lab = DEREF_id ( exp_do_stmt_break_lab ( stmt ) ) ;
1863
	} else {
1864
	    lab = DEREF_id ( exp_switch_stmt_break_lab ( stmt ) ) ;
1865
	}
1866
	return ( make_jump_stmt ( lab, stmt ) ) ;
1867
    }
1868
    report ( crt_loc, ERR_stmt_break_bad () ) ;
1869
    return ( NULL_exp ) ;
1870
}
1871
 
1872
 
1873
/*
1874
    CONSTRUCT A CONTINUE STATEMENT
1875
 
1876
    This routine constructs a continue statement.  Note that this must
1877
    appear inside an iteration statement.  It is implemented as a jump to
1878
    the continue label.
1879
*/
1880
 
1881
EXP make_continue_stmt
1882
    PROTO_Z ()
1883
{
1884
    LIST ( EXP ) st = LIST_stack ( crt_loop_stack ) ;
1885
    while ( !IS_NULL_list ( st ) ) {
1886
	EXP stmt = DEREF_exp ( HEAD_list ( st ) ) ;
1887
	unsigned tag = TAG_exp ( stmt ) ;
1888
	if ( tag == exp_switch_stmt_tag ) {
1889
	    /* Switch statements don't count for continues */
1890
	    /* EMPTY */
1891
	} else {
1892
	    /* Find continue destination label */
1893
	    IDENTIFIER lab ;
1894
	    if ( tag == exp_while_stmt_tag ) {
1895
		lab = DEREF_id ( exp_while_stmt_cont_lab ( stmt ) ) ;
1896
	    } else {
1897
		lab = DEREF_id ( exp_do_stmt_cont_lab ( stmt ) ) ;
1898
	    }
1899
	    return ( make_jump_stmt ( lab, stmt ) ) ;
1900
	}
1901
	st = TAIL_list ( st ) ;
1902
    }
1903
    report ( crt_loc, ERR_stmt_cont_bad () ) ;
1904
    return ( NULL_exp ) ;
1905
}
1906
 
1907
 
1908
/*
1909
    CHECK A RETURN EXPRESSION
1910
 
1911
    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
1913
    a throw expression (as indicated by op).
1914
*/
1915
 
1916
EXP check_return_exp
1917
    PROTO_N ( ( a, op ) )
1918
    PROTO_T ( EXP a X int op )
1919
{
1920
    if ( option ( OPT_ptr_operator ) ) {
1921
	EXP b = NULL_exp ;
1922
	DECL_SPEC ds = find_exp_linkage ( a, &b, 1 ) ;
1923
	if ( ds & dspec_auto ) {
1924
	    if ( IS_exp_identifier ( b ) ) {
1925
		IDENTIFIER id = DEREF_id ( exp_identifier_id ( b ) ) ;
1926
		if ( IS_id_variable ( id ) ) {
1927
		    TYPE t = DEREF_type ( id_variable_type ( id ) ) ;
1928
		    if ( !IS_type_ref ( t ) ) {
1929
			report ( crt_loc, ERR_stmt_return_auto ( id, op ) ) ;
1930
		    }
1931
		}
1932
	    }
1933
	}
1934
    }
1935
    return ( a ) ;
1936
}
1937
 
1938
 
1939
/*
1940
    CONSTRUCT A RETURN EXPRESSION
1941
 
1942
    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
1944
    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
1946
    assigned to lab.
1947
*/
1948
 
1949
EXP find_return_exp
1950
    PROTO_N ( ( a, lab, op ) )
1951
    PROTO_T ( EXP a X IDENTIFIER *lab X int op )
1952
{
1953
    TYPE r = crt_func_return ;
1954
    if ( !IS_NULL_exp ( a ) ) {
1955
	/* Apply reference conversion */
1956
	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
	}
2013
 
2014
	default :
2015
	default_lab : {
2016
	    /* Function returns a value */
2017
	    if ( IS_NULL_exp ( a ) ) {
2018
		IDENTIFIER id = crt_func_id ;
2019
		if ( op == lex_return ) {
2020
		    /* Explicit return statement */
2021
		    report ( crt_loc, ERR_stmt_return_void ( id, r ) ) ;
2022
		    MAKE_exp_value ( r, a ) ;
2023
		} else {
2024
		    /* Implicit fall out of function */
2025
		    HASHID nm = DEREF_hashid ( id_name ( id ) ) ;
2026
		    DECL_SPEC ds = DEREF_dspec ( id_storage ( id ) ) ;
2027
		    if ( ( ds & dspec_main ) && IS_hashid_name ( nm ) ) {
2028
			/* Implicit 'return 0' in main */
2029
			ERROR err = ERR_basic_start_main_fall ( id, r ) ;
2030
			report ( crt_loc, err ) ;
2031
			MAKE_exp_null ( r, a ) ;
2032
		    } else {
2033
			report ( crt_loc, ERR_stmt_return_fall ( id, r ) ) ;
2034
			MAKE_exp_value ( r, a ) ;
2035
		    }
2036
		}
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 ) ) {
2042
		    /* Bad return type */
2043
		    err = init_error ( err, 0 ) ;
2044
		    err = concat_error ( err, ERR_stmt_return_conv () ) ;
2045
		    report ( crt_loc, err ) ;
2046
		}
2047
		if ( crt_func_complex ) {
2048
		    a = remove_temporary ( a, NULL_exp ) ;
2049
		}
2050
		a = check_return_exp ( a, lex_return ) ;
2051
	    }
2052
	}
2053
    }
2054
    return ( a ) ;
2055
}
2056
 
2057
 
2058
/*
2059
    CONSTRUCT A RETURN STATEMENT
2060
 
2061
    This routine constructs the return statement 'return a'.  op is as in
2062
    find_return_exp.
2063
*/
2064
 
2065
EXP make_return_stmt
2066
    PROTO_N ( ( a, op ) )
2067
    PROTO_T ( EXP a X int op )
2068
{
2069
    IDENTIFIER lab = NULL_id ;
2070
    EXP e = find_return_exp ( a, &lab, op ) ;
2071
    if ( IS_NULL_id ( lab ) ) {
2072
	/* Construct return statement */
2073
	MAKE_exp_return_stmt ( type_bottom, e, e ) ;
2074
    } else {
2075
	/* Jump to postlude label */
2076
	e = make_jump_stmt ( lab, NULL_exp ) ;
2077
    }
2078
    unreached_code = 1 ;
2079
    unreached_last = 0 ;
2080
    return ( e ) ;
2081
}
2082
 
2083
 
2084
/*
2085
    FALL OUT OF A FUNCTION DEFINITION
2086
 
2087
    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.
2089
*/
2090
 
2091
EXP fall_return_stmt
2092
    PROTO_Z ()
2093
{
2094
    EXP e = NULL_exp ;
2095
    if ( !unreached_code ) {
2096
	TYPE ret = crt_func_return ;
2097
	if ( !IS_NULL_type ( ret ) && !IS_type_top ( ret ) ) {
2098
	    e = make_return_stmt ( NULL_exp, lex_fall ) ;
2099
	}
2100
    }
2101
    return ( e ) ;
2102
}
2103
 
2104
 
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
/*
2194
    BEGIN A SWITCH STATEMENT
2195
 
2196
    This routine begins the construction of a switch statement with
2197
    controlling expression cont.  During construction an enumeration or
2198
    boolean control expression is held in the body field.
2199
*/
2200
 
2201
EXP begin_switch_stmt
2202
    PROTO_N ( ( cont ) )
2203
    PROTO_T ( EXP cont )
2204
{
2205
    EXP e ;
2206
    EXP d = NULL_exp ;
2207
    EXP body = NULL_exp ;
2208
    EXP bk = begin_label_stmt ( NULL_id, lex_break ) ;
2209
    IDENTIFIER bk_lab = DEREF_id ( exp_label_stmt_label ( bk ) ) ;
2210
    cont = check_control ( cont, &d, &body ) ;
2211
    MAKE_exp_switch_stmt ( type_void, cont, body, 0, bk_lab, e ) ;
2212
    check_empty_stmt ( lex_switch ) ;
2213
 
2214
    /* Add statement to loop stack */
2215
    PUSH_exp ( e, crt_loop_stack ) ;
2216
 
2217
    /* Allow for condition declarations */
2218
    if ( !IS_NULL_exp ( d ) ) e = make_cond_decl ( d, e, 0 ) ;
2219
 
2220
    /* The following statement is never reached */
2221
    unreached_code = 1 ;
2222
    unreached_last = 0 ;
2223
    unreached_fall = 1 ;
2224
    return ( e ) ;
2225
}
2226
 
2227
 
2228
/*
2229
    DOES A VALUE APPEAR IN A CASE LIST?
2230
 
2231
    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
2233
    statement drawn from the list of labels q.
2234
*/
2235
 
2236
IDENTIFIER find_case
2237
    PROTO_N ( ( p, q, n ) )
2238
    PROTO_T ( LIST ( NAT ) p X LIST ( IDENTIFIER ) q X NAT n )
2239
{
2240
    while ( !IS_NULL_list ( p ) ) {
2241
	NAT m = DEREF_nat ( HEAD_list ( p ) ) ;
2242
	if ( EQ_nat ( n, m ) || eq_nat ( n, m ) ) {
2243
	    IDENTIFIER lab = DEREF_id ( HEAD_list ( q ) ) ;
2244
	    return ( lab ) ;
2245
	}
2246
	q = TAIL_list ( q ) ;
2247
	p = TAIL_list ( p ) ;
2248
    }
2249
    return ( NULL_id ) ;
2250
}
2251
 
2252
 
2253
/*
2254
    COMPLETE A SWITCH STATEMENT
2255
 
2256
    This routine completes the construction of the switch statement prev
2257
    using the statement body.  exhaust is true if the switch statement
2258
    is declared to be exhaustive.
2259
*/
2260
 
2261
EXP end_switch_stmt
2262
    PROTO_N ( ( prev, body, exhaust ) )
2263
    PROTO_T ( EXP prev X EXP body X int exhaust )
2264
{
2265
    EXP bk ;
2266
    EXP cont ;
2267
    EXP stmt ;
2268
    unsigned ncases ;
2269
    IDENTIFIER bk_lab ;
2270
    LIST ( NAT ) cases ;
2271
    IDENTIFIER default_lab ;
2272
    LIST ( IDENTIFIER ) case_labs ;
2273
 
2274
    /* Remove statement from loop stack */
2275
    EXP e ;
2276
    POP_exp ( e, crt_loop_stack ) ;
2277
    UNUSED ( e ) ;
2278
 
2279
    /* Copy the body into the result */
2280
    stmt = find_cond_stmt ( prev ) ;
2281
    cont = DEREF_exp ( exp_switch_stmt_body ( stmt ) ) ;
2282
    bk_lab = DEREF_id ( exp_switch_stmt_break_lab ( stmt ) ) ;
2283
    bk = DEREF_exp ( id_label_stmt ( bk_lab ) ) ;
2284
    if ( !unreached_code ) {
2285
	/* Add break statement to end if necessary */
2286
	if ( !IS_NULL_exp ( body ) && IS_exp_sequence ( body ) ) {
2287
	    EXP b = make_jump_stmt ( bk_lab, stmt ) ;
2288
	    body = add_compound_stmt ( body, b ) ;
2289
	}
2290
    }
2291
    MAKE_exp_solve_stmt ( type_void, body, e ) ;
2292
    CONS_exp ( e, all_solve_stmts, all_solve_stmts ) ;
2293
    COPY_exp ( exp_solve_stmt_parent ( e ), stmt ) ;
2294
    COPY_exp ( exp_switch_stmt_body ( stmt ), e ) ;
2295
    set_parent_stmt ( body, e ) ;
2296
    set_parent_stmt ( bk, e ) ;
2297
 
2298
    /* Check lists of cases */
2299
    cases = DEREF_list ( exp_switch_stmt_cases ( stmt ) ) ;
2300
    cases = REVERSE_list ( cases ) ;
2301
    ncases = LENGTH_list ( cases ) ;
2302
    if ( ncases == 0 ) {
2303
	ERROR err ;
2304
	if ( exhaust ) {
2305
	    err = ERR_stmt_switch_exhaust_none () ;
2306
	} else {
2307
	    err = ERR_stmt_switch_case_none () ;
2308
	}
2309
	report ( crt_loc, err ) ;
2310
    }
2311
    IGNORE check_value ( OPT_VAL_switch_cases, ( ulong ) ncases ) ;
2312
    COPY_list ( exp_switch_stmt_cases ( stmt ), cases ) ;
2313
    case_labs = DEREF_list ( exp_switch_stmt_case_labs ( stmt ) ) ;
2314
    case_labs = REVERSE_list ( case_labs ) ;
2315
    COPY_list ( exp_switch_stmt_case_labs ( stmt ), case_labs ) ;
2316
 
2317
    /* Check default label */
2318
    default_lab = DEREF_id ( exp_switch_stmt_default_lab ( stmt ) ) ;
2319
    if ( IS_NULL_id ( default_lab ) ) {
2320
	report ( crt_loc, ERR_stmt_switch_no_default () ) ;
2321
    } else {
2322
	exhaust = 1 ;
2323
    }
2324
 
2325
    /* Check switch jumps */
2326
    stmt = solve_switch ( stmt ) ;
2327
 
2328
    /* Check switches on enumerations and booleans */
2329
    if ( !IS_NULL_exp ( cont ) && !exhaust ) {
2330
	TYPE t = DEREF_type ( exp_type ( cont ) ) ;
2331
	if ( IS_type_enumerate ( t ) ) {
2332
	    ENUM_TYPE et = DEREF_etype ( type_enumerate_defn ( t ) ) ;
2333
	    LIST ( IDENTIFIER ) evals = DEREF_list ( etype_values ( et ) ) ;
2334
	    exhaust = 1 ;
2335
	    while ( !IS_NULL_list ( evals ) ) {
2336
		IDENTIFIER eid = DEREF_id ( HEAD_list ( evals ) ) ;
2337
		EXP en = DEREF_exp ( id_enumerator_value ( eid ) ) ;
2338
		NAT n = DEREF_nat ( exp_int_lit_nat ( en ) ) ;
2339
		IDENTIFIER lid = find_case ( cases, case_labs, n ) ;
2340
		if ( IS_NULL_id ( lid ) ) {
2341
		    report ( crt_loc, ERR_stmt_switch_case_enum ( eid ) ) ;
2342
		    exhaust = 0 ;
2343
		}
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
	}
2370
    }
2371
    COPY_int ( exp_switch_stmt_exhaust ( stmt ), exhaust ) ;
2372
    return ( prev ) ;
2373
}
2374
 
2375
 
2376
/*
2377
    BEGIN A CASE STATEMENT
2378
 
2379
    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
2381
    that a case statement must appear inside a switch statement.
2382
*/
2383
 
2384
EXP begin_case_stmt
2385
    PROTO_N ( ( val, jump ) )
2386
    PROTO_T ( EXP val X int jump )
2387
{
2388
    /* Search for enclosing switch statement */
2389
    LIST ( EXP ) st = LIST_stack ( crt_loop_stack ) ;
2390
    while ( !IS_NULL_list ( st ) ) {
2391
	EXP stmt = DEREF_exp ( HEAD_list ( st ) ) ;
2392
 
2393
	if ( IS_exp_switch_stmt ( stmt ) ) {
2394
	    /* Switch statement found */
2395
	    NAT n ;
2396
	    EXP e ;
2397
	    IDENTIFIER lab ;
2398
	    IDENTIFIER old_lab ;
2399
	    LIST ( NAT ) cases ;
2400
	    ERROR err = NULL_err ;
2401
	    int uc = unreached_code ;
2402
	    LIST ( IDENTIFIER ) lbls ;
2403
	    unsigned etag = null_tag ;
2404
	    unsigned tag = TAG_exp ( val ) ;
2405
	    TYPE ta = DEREF_type ( exp_type ( val ) ) ;
2406
	    EXP cont = DEREF_exp ( exp_switch_stmt_control ( stmt ) ) ;
2407
	    TYPE tc = DEREF_type ( exp_type ( cont ) ) ;
2408
 
2409
	    /* Cast val to control type */
2410
	    while ( tag == exp_paren_tag ) {
2411
		val = DEREF_exp ( exp_paren_arg ( val ) ) ;
2412
		tag = TAG_exp ( val ) ;
2413
	    }
2414
	    if ( tag == exp_int_lit_tag ) {
2415
		TYPE tb = ta ;
2416
		if ( IS_type_enumerate ( ta ) ) tb = promote_type ( ta ) ;
2417
		etag = DEREF_unsigned ( exp_int_lit_etag ( val ) ) ;
2418
		if ( !eq_type ( tb, tc ) ) {
2419
		    val = make_cast_nat ( tc, val, &err, CAST_IMPLICIT ) ;
2420
		}
2421
	    }
2422
 
2423
	    /* Check that val is a constant */
2424
	    n = make_nat_exp ( val, &err ) ;
2425
	    if ( !IS_NULL_err ( err ) ) {
2426
		err = concat_error ( err, ERR_stmt_switch_case_const () ) ;
2427
		report ( crt_loc, err ) ;
2428
	    }
2429
 
2430
	    /* Check whether this value has been used previously */
2431
	    lbls = DEREF_list ( exp_switch_stmt_case_labs ( stmt ) ) ;
2432
	    cases = DEREF_list ( exp_switch_stmt_cases ( stmt ) ) ;
2433
	    old_lab = find_case ( cases, lbls, n ) ;
2434
	    if ( !IS_NULL_id ( old_lab ) && !jump ) {
2435
		DECL_SPEC info = DEREF_dspec ( id_storage ( old_lab ) ) ;
2436
		if ( ( info & dspec_defn ) && !is_error_nat ( n ) ) {
2437
		    /* Duplicate case */
2438
		    PTR ( LOCATION ) loc = id_loc ( old_lab ) ;
2439
		    report ( crt_loc, ERR_stmt_switch_case_dup ( n, loc ) ) ;
2440
		    old_lab = NULL_id ;
2441
		}
2442
	    }
2443
 
2444
	    /* Construct the case statement */
2445
	    if ( jump ) {
2446
		e = make_goto_stmt ( old_lab ) ;
2447
		lab = DEREF_id ( exp_goto_stmt_label ( e ) ) ;
2448
		COPY_int ( id_label_op ( lab ), lex_case ) ;
2449
	    } else {
2450
		e = begin_label_stmt ( old_lab, lex_case ) ;
2451
		lab = DEREF_id ( exp_label_stmt_label ( e ) ) ;
2452
	    }
2453
	    COPY_exp ( id_label_gotos ( lab ), stmt ) ;
2454
	    if ( IS_NULL_id ( old_lab ) ) {
2455
		CONS_id ( lab, lbls, lbls ) ;
2456
		CONS_nat ( n, cases, cases ) ;
2457
		COPY_list ( exp_switch_stmt_case_labs ( stmt ), lbls ) ;
2458
		COPY_list ( exp_switch_stmt_cases ( stmt ), cases ) ;
2459
	    }
2460
	    if ( jump ) return ( e ) ;
2461
 
2462
	    /* Check enumeration switches */
2463
	    cont = DEREF_exp ( exp_switch_stmt_body ( stmt ) ) ;
2464
	    if ( !IS_NULL_exp ( cont ) ) {
2465
		int ok = 0 ;
2466
		TYPE t = DEREF_type ( exp_type ( cont ) ) ;
2467
		if ( IS_type_enumerate ( t ) ) {
2468
		    /* Enumeration switch */
2469
		    if ( etag == exp_identifier_tag && eq_type ( t, ta ) ) {
2470
			ok = 1 ;
2471
		    } else {
2472
			ENUM_TYPE et ;
2473
			IDENTIFIER eid ;
2474
			et = DEREF_etype ( type_enumerate_defn ( t ) ) ;
2475
			eid = find_enumerator ( et, n ) ;
2476
			if ( !IS_NULL_id ( eid ) ) ok = 1 ;
2477
		    }
2478
		} else {
2479
		    /* Boolean switch */
2480
		    unsigned long v = get_nat_value ( n ) ;
2481
		    if ( v == 0 || v == 1 ) ok = 1 ;
2482
		}
2483
		if ( !ok && !is_error_nat ( n ) ) {
2484
		    err = ERR_stmt_switch_case_extra ( n, t ) ;
2485
		    report ( crt_loc, err ) ;
2486
		}
2487
	    }
2488
 
2489
	    /* Check for falling into a case */
2490
	    if ( !uc && unreached_fall && !suppress_fall ) {
2491
		report ( crt_loc, ERR_stmt_label_fall ( lex_case ) ) ;
2492
	    }
2493
	    suppress_fall = 0 ;
2494
	    return ( e ) ;
2495
	}
2496
 
2497
	/* Iteration statements are ignored for cases */
2498
	st = TAIL_list ( st ) ;
2499
    }
2500
    report ( crt_loc, ERR_stmt_label_case () ) ;
2501
    return ( NULL_exp ) ;
2502
}
2503
 
2504
 
2505
/*
2506
    COMPLETE A CASE STATEMENT
2507
 
2508
    This routine completes the construction of the case statement prev
2509
    using the statement body.  This is just a call to end_label_stmt.
2510
*/
2511
 
2512
EXP end_case_stmt
2513
    PROTO_N ( ( prev, body ) )
2514
    PROTO_T ( EXP prev X EXP body )
2515
{
2516
    return ( end_label_stmt ( prev, body ) ) ;
2517
}
2518
 
2519
 
2520
/*
2521
    BEGIN A DEFAULT STATEMENT
2522
 
2523
    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
2525
    must appear inside a switch statement.
2526
*/
2527
 
2528
EXP begin_default_stmt
2529
    PROTO_N ( ( jump ) )
2530
    PROTO_T ( int jump )
2531
{
2532
    /* Search for enclosing switch statement */
2533
    LIST ( EXP ) st = LIST_stack ( crt_loop_stack ) ;
2534
    while ( !IS_NULL_list ( st ) ) {
2535
	EXP stmt = DEREF_exp ( HEAD_list ( st ) ) ;
2536
 
2537
	if ( IS_exp_switch_stmt ( stmt ) ) {
2538
	    /* Switch statement found */
2539
	    EXP e ;
2540
	    IDENTIFIER lab ;
2541
	    int uc = unreached_code ;
2542
 
2543
	    /* Check for previous default statements */
2544
	    lab = DEREF_id ( exp_switch_stmt_default_lab ( stmt ) ) ;
2545
	    if ( !IS_NULL_id ( lab ) && !jump ) {
2546
		DECL_SPEC info = DEREF_dspec ( id_storage ( lab ) ) ;
2547
		if ( info & dspec_defn ) {
2548
		    /* Duplicate default statement */
2549
		    PTR ( LOCATION ) loc = id_loc ( lab ) ;
2550
		    report ( crt_loc, ERR_stmt_switch_default_dup ( loc ) ) ;
2551
		    lab = NULL_id ;
2552
		}
2553
	    }
2554
 
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 */
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 ;
2578
	    }
2579
	    return ( e ) ;
2580
	}
2581
 
2582
	/* Iteration statements are ignored for defaults */
2583
	st = TAIL_list ( st ) ;
2584
    }
2585
    report ( crt_loc, ERR_stmt_label_default () ) ;
2586
    return ( NULL_exp ) ;
2587
}
2588
 
2589
 
2590
/*
2591
    COMPLETE A DEFAULT STATEMENT
2592
 
2593
    This routine completes the construction of the default statement prev
2594
    using the statement body.  This is just a call to end_label_stmt.
2595
*/
2596
 
2597
EXP end_default_stmt
2598
    PROTO_N ( ( prev, body ) )
2599
    PROTO_T ( EXP prev X EXP body )
2600
{
2601
    return ( end_label_stmt ( prev, body ) ) ;
2602
}
2603
 
2604
 
2605
/*
2606
    CURRENT #IF CONDITION
2607
 
2608
    This variable is used to keep track of the cummulative target dependent
2609
    condition at any point in the compilation.  It takes the form
2610
    'c1 && c2 && ... && cn' where c1, c2, ..., cn are the target dependent
2611
    conditions currently in scope.  The case n = 0 gives the null expression.
2612
*/
2613
 
2614
EXP crt_hash_cond = NULL_exp ;
2615
 
2616
 
2617
/*
2618
    ADD A CONDITION TO A LIST OF CONDITIONS
2619
 
2620
    This routine adds the condition a to the list of conditions b by
2621
    forming 'b && a'.
2622
*/
2623
 
2624
EXP make_if_cond
2625
    PROTO_N ( ( a, b ) )
2626
    PROTO_T ( EXP a X EXP b )
2627
{
2628
    if ( !IS_NULL_exp ( b ) ) {
2629
	MAKE_exp_log_and ( type_bool, b, a, a ) ;
2630
    }
2631
    return ( a ) ;
2632
}
2633
 
2634
 
2635
/*
2636
    NEGATE THE LAST CONDITION IN A LIST
2637
 
2638
    This routine negates the last condition in the list of conditions a,
2639
    that is, it maps 'a1 && a2 && ... && an' to 'a1 && a2 && ... && !an'.
2640
*/
2641
 
2642
EXP make_else_cond
2643
    PROTO_N ( ( a ) )
2644
    PROTO_T ( EXP a )
2645
{
2646
    if ( !IS_NULL_exp ( a ) ) {
2647
	if ( IS_exp_log_and ( a ) ) {
2648
	    EXP b = DEREF_exp ( exp_log_and_arg1 ( a ) ) ;
2649
	    EXP c = DEREF_exp ( exp_log_and_arg2 ( a ) ) ;
2650
	    MAKE_exp_not ( type_bool, c, c ) ;
2651
	    MAKE_exp_log_and ( type_bool, b, c, a ) ;
2652
	} else {
2653
	    MAKE_exp_not ( type_bool, a, a ) ;
2654
	}
2655
    }
2656
    return ( a ) ;
2657
}
2658
 
2659
 
2660
/*
2661
    BEGIN A #IF STATEMENT
2662
 
2663
    This routine begins the construction of a #if statement.  cond gives
2664
    the condition, which is already a boolean value.  The case where cond
2665
    is a target independent constant have already been handled by the
2666
    preprocessor.  right gives the code which is evaluated if this condition
2667
    is true.
2668
*/
2669
 
2670
EXP begin_hash_if_stmt
2671
    PROTO_N ( ( cond, right ) )
2672
    PROTO_T ( EXP cond X EXP right )
2673
{
2674
    /* Construct the result */
2675
    EXP e ;
2676
    MAKE_exp_hash_if ( type_void, cond, right, NULL_exp, e ) ;
2677
    COPY_exp ( exp_hash_if_last ( e ), e ) ;
2678
    set_parent_stmt ( right, e ) ;
2679
 
2680
    /* Unreached code analysis */
2681
    if ( is_bottom ( right ) ) {
2682
	COPY_type ( exp_type ( e ), type_bottom ) ;
2683
    }
2684
    /* Next branch is reached */
2685
    unreached_code = unreached_prev ;
2686
    return ( e ) ;
2687
}
2688
 
2689
 
2690
/*
2691
    CONTINUE A #IF STATEMENT
2692
 
2693
    This routine continues the construction of a #if statement, prev, by
2694
    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
2696
    independent constant have already been handled by the preprocessor.
2697
    right gives the code which is evaluated if this condition, and none of
2698
    the previous conditions in prev, is true.
2699
*/
2700
 
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
 
2714
    /* Unreached code analysis */
2715
    if ( !is_bottom ( right ) ) {
2716
	/* Reaching the end of a condition */
2717
	COPY_type ( exp_type ( prev ), type_void ) ;
2718
    }
2719
    /* Next branch is reached */
2720
    unreached_code = unreached_prev ;
2721
    return ( prev ) ;
2722
}
2723
 
2724
 
2725
/*
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
2761
 
2762
    This routine creates a flow control statement indicating that the
2763
    statement body is either reached or unreached, depending on the
2764
    value of reach.
2765
*/
2766
 
2767
EXP make_reach_stmt
2768
    PROTO_N ( ( body, reach ) )
2769
    PROTO_T ( EXP body X int reach )
2770
{
2771
    EXP e ;
2772
    TYPE t ;
2773
    if ( IS_NULL_exp ( body ) ) {
2774
	t = type_void ;
2775
    } else {
2776
	unsigned tag = TAG_exp ( body ) ;
2777
	if ( tag == exp_decl_stmt_tag || tag == exp_label_stmt_tag ) {
2778
	    /* Don't bother in these cases */
2779
	    return ( body ) ;
2780
	}
2781
	t = DEREF_type ( exp_type ( body ) ) ;
2782
    }
2783
    if ( reach ) {
2784
	MAKE_exp_reach ( t, body, e ) ;
2785
    } else {
2786
	MAKE_exp_unreach ( t, body, e ) ;
2787
    }
2788
    set_parent_stmt ( body, e ) ;
2789
    return ( e ) ;
2790
}
2791
 
2792
 
2793
/*
2794
    CHECK A CONDITION DECLARATION TYPE
2795
 
2796
    This routine checks the type t of a condition declaration.
2797
*/
2798
 
2799
TYPE make_cond_type
2800
    PROTO_N ( ( t ) )
2801
    PROTO_T ( TYPE t )
2802
{
2803
    int td = have_type_declaration ;
2804
    if ( td != TYPE_DECL_NONE ) {
2805
	/* Check for type declarations */
2806
	if ( td == TYPE_DECL_ELABORATE && found_elaborate_type ) {
2807
	    /* This is allowed */
2808
	    /* EMPTY */
2809
	} else {
2810
	    report ( crt_loc, ERR_stmt_select_typedef () ) ;
2811
	}
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
	}
2821
	case type_array_tag : {
2822
	    report ( crt_loc, ERR_stmt_select_type ( t ) ) ;
2823
	    t = DEREF_type ( type_array_sub ( t ) ) ;
2824
	    MAKE_type_ptr ( cv_none, t, t ) ;
2825
	    break ;
2826
	}
2827
    }
2828
    return ( t ) ;
2829
}
2830
 
2831
 
2832
/*
2833
    BEGIN A CONDITION DECLARATION
2834
 
2835
    Condition declarations are declared in their own local scope and
2836
    brought into the outermost scope of the the statements they control
2837
    using inject_cond.  This routine begins the construction of such a
2838
    local scope.
2839
*/
2840
 
2841
void begin_cond
2842
    PROTO_Z ()
2843
{
2844
    NAMESPACE ns = make_namespace ( crt_func_id, nspace_dummy_tag, 0 ) ;
2845
    push_namespace ( ns ) ;
2846
    return ;
2847
}
2848
 
2849
 
2850
/*
2851
    END A CONDITION DECLARATION
2852
 
2853
    This routine ends the local scope for a condition declaration, returning
2854
    a corresponding declaration statement.
2855
*/
2856
 
2857
EXP end_cond
2858
    PROTO_Z ()
2859
{
2860
    int vars = 0 ;
2861
    NAMESPACE ns = pop_namespace () ;
2862
    MEMBER p = DEREF_member ( nspace_last ( ns ) ) ;
2863
    EXP cond = make_decl_stmt ( p, NULL_member, &vars ) ;
2864
    return ( cond ) ;
2865
}
2866
 
2867
 
2868
/*
2869
    INJECT A CONDITION DECLARATION INTO THE CURRENT SCOPE
2870
 
2871
    This routine injects the condition declaration cond into the current
2872
    scope, prev, returning the result.  It is also used to deal with
2873
    declarations in for-init statements.
2874
*/
2875
 
2876
EXP inject_cond
2877
    PROTO_N ( ( prev, cond ) )
2878
    PROTO_T ( EXP prev X EXP cond )
2879
{
2880
    if ( !IS_NULL_exp ( cond ) ) {
2881
	NAMESPACE ns = crt_namespace ;
2882
	while ( IS_exp_decl_stmt ( cond ) ) {
2883
	    IDENTIFIER id = DEREF_id ( exp_decl_stmt_id ( cond ) ) ;
2884
	    IGNORE redeclare_id ( ns, id ) ;
2885
	    cond = DEREF_exp ( exp_decl_stmt_body ( cond ) ) ;
2886
	}
2887
    }
2888
    return ( prev ) ;
2889
}
2890
 
2891
 
2892
/*
2893
    CONSTRUCT AN ASM STATEMENT
2894
 
2895
    This routine constructs an asm statement from the string literal
2896
    expression e.  Note that the semantics of asm are totally implementation
2897
    dependent, so anything goes.
2898
*/
2899
 
2900
EXP make_asm
2901
    PROTO_N ( ( e, args ) )
2902
    PROTO_T ( EXP e X LIST ( EXP ) args )
2903
{
2904
    STRING s = DEREF_str ( exp_string_lit_str ( e ) ) ;
2905
    if ( !IS_NULL_list ( args ) ) {
2906
	report ( crt_loc, ERR_dcl_asm_args () ) ;
2907
	args = convert_args ( args ) ;
2908
    }
2909
    MAKE_exp_assembler ( type_void, s, args, e ) ;
2910
    report ( crt_loc, ERR_dcl_asm_ti () ) ;
2911
    return ( e ) ;
2912
}