Subversion Repositories tendra.SVN

Rev

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

Rev 2 Rev 7
Line -... Line 1...
-
 
1
/*
-
 
2
 * Copyright (c) 2002-2006 The TenDRA Project <http://www.tendra.org/>.
-
 
3
 * All rights reserved.
-
 
4
 *
-
 
5
 * Redistribution and use in source and binary forms, with or without
-
 
6
 * modification, are permitted provided that the following conditions are met:
-
 
7
 *
-
 
8
 * 1. Redistributions of source code must retain the above copyright notice,
-
 
9
 *    this list of conditions and the following disclaimer.
-
 
10
 * 2. Redistributions in binary form must reproduce the above copyright notice,
-
 
11
 *    this list of conditions and the following disclaimer in the documentation
-
 
12
 *    and/or other materials provided with the distribution.
-
 
13
 * 3. Neither the name of The TenDRA Project nor the names of its contributors
-
 
14
 *    may be used to endorse or promote products derived from this software
-
 
15
 *    without specific, prior written permission.
-
 
16
 *
-
 
17
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS
-
 
18
 * IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
-
 
19
 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
-
 
20
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR
-
 
21
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
-
 
22
 * EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
-
 
23
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
-
 
24
 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-
 
25
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
-
 
26
 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
-
 
27
 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
 
28
 *
-
 
29
 * $Id$
-
 
30
 */
1
/*
31
/*
2
    		 Crown Copyright (c) 1997
32
    		 Crown Copyright (c) 1997
3
    
33
 
4
    This TenDRA(r) Computer Program is subject to Copyright
34
    This TenDRA(r) Computer Program is subject to Copyright
5
    owned by the United Kingdom Secretary of State for Defence
35
    owned by the United Kingdom Secretary of State for Defence
6
    acting through the Defence Evaluation and Research Agency
36
    acting through the Defence Evaluation and Research Agency
7
    (DERA).  It is made available to Recipients with a
37
    (DERA).  It is made available to Recipients with a
8
    royalty-free licence for its use, reproduction, transfer
38
    royalty-free licence for its use, reproduction, transfer
9
    to other parties and amendment for any purpose not excluding
39
    to other parties and amendment for any purpose not excluding
10
    product development provided that any such use et cetera
40
    product development provided that any such use et cetera
11
    shall be deemed to be acceptance of the following conditions:-
41
    shall be deemed to be acceptance of the following conditions:-
12
    
42
 
13
        (1) Its Recipients shall ensure that this Notice is
43
        (1) Its Recipients shall ensure that this Notice is
14
        reproduced upon any copies or amended versions of it;
44
        reproduced upon any copies or amended versions of it;
15
    
45
 
16
        (2) Any amended version of it shall be clearly marked to
46
        (2) Any amended version of it shall be clearly marked to
17
        show both the nature of and the organisation responsible
47
        show both the nature of and the organisation responsible
18
        for the relevant amendment or amendments;
48
        for the relevant amendment or amendments;
19
    
49
 
20
        (3) Its onward transfer from a recipient to another
50
        (3) Its onward transfer from a recipient to another
21
        party shall be deemed to be that party's acceptance of
51
        party shall be deemed to be that party's acceptance of
22
        these conditions;
52
        these conditions;
23
    
53
 
24
        (4) DERA gives no warranty or assurance as to its
54
        (4) DERA gives no warranty or assurance as to its
25
        quality or suitability for any purpose and DERA accepts
55
        quality or suitability for any purpose and DERA accepts
26
        no liability whatsoever in relation to any use to which
56
        no liability whatsoever in relation to any use to which
27
        it may be put.
57
        it may be put.
28
*/
58
*/
Line 52... Line 82...
52
 
82
 
53
    The labels in a function occupy a distinct namespace.  This is given by
83
    The labels in a function occupy a distinct namespace.  This is given by
54
    the following variable.
84
    the following variable.
55
*/
85
*/
56
 
86
 
57
NAMESPACE label_namespace = NULL_nspace ;
87
NAMESPACE label_namespace = NULL_nspace;
58
 
88
 
59
 
89
 
60
/*
90
/*
61
    LABEL USAGE VALUES
91
    LABEL USAGE VALUES
62
 
92
 
Line 79... Line 109...
79
    CREATE A LABEL
109
    CREATE A LABEL
80
 
110
 
81
    This routine creates a label named nm with usage information info.
111
    This routine creates a label named nm with usage information info.
82
*/
112
*/
83
 
113
 
84
static IDENTIFIER make_label
114
static IDENTIFIER
85
    PROTO_N ( ( nm, info, op ) )
-
 
86
    PROTO_T ( HASHID nm X DECL_SPEC info X int op )
115
make_label(HASHID nm, DECL_SPEC info, int op)
87
{
116
{
88
    IDENTIFIER lab ;
117
	IDENTIFIER lab;
89
    NAMESPACE ns = label_namespace ;
118
	NAMESPACE ns = label_namespace;
90
    MAKE_id_label ( nm, info, ns, crt_loc, op, lab ) ;
119
	MAKE_id_label(nm, info, ns, crt_loc, op, lab);
91
    return ( lab ) ;
120
	return (lab);
92
}
121
}
93
 
122
 
94
 
123
 
95
/*
124
/*
96
    BEGIN A LABELLED STATEMENT
125
    BEGIN A LABELLED STATEMENT
Line 123... Line 152...
123
				....
152
				....
124
			    }
153
			    }
125
			}
154
			}
126
 
155
 
127
    except that the introduced block does not establish a scope.
156
    except that the introduced block does not establish a scope.
128
*/
157
*/
129
 
158
 
130
EXP begin_label_stmt
159
EXP
131
    PROTO_N ( ( lab, op ) )
-
 
132
    PROTO_T ( IDENTIFIER lab X int op )
160
begin_label_stmt(IDENTIFIER lab, int op)
133
{
161
{
134
    EXP e ;
162
	EXP e;
135
    EXP seq ;
163
	EXP seq;
136
    HASHID nm ;
164
	HASHID nm;
137
    MEMBER mem ;
165
	MEMBER mem;
138
    DECL_SPEC def_info = ( dspec_defn | dspec_scope ) ;
166
	DECL_SPEC def_info = (dspec_defn | dspec_scope);
139
 
167
 
140
    /* Make up label name if necessary */
168
	/* Make up label name if necessary */
141
    if ( IS_NULL_id ( lab ) ) {
169
	if (IS_NULL_id(lab)) {
142
	nm = lookup_anon () ;
170
		nm = lookup_anon();
143
	def_info |= dspec_anon ;
171
		def_info |= dspec_anon;
144
	if ( op == lex_case || op == lex_default ) {
172
		if (op == lex_case || op == lex_default) {
145
	    /* Mark case and default labels */
173
			/* Mark case and default labels */
146
	    def_info |= ( dspec_used | dspec_goto ) ;
174
			def_info |= (dspec_used | dspec_goto);
147
	}
175
		}
148
    } else {
176
	} else {
149
	nm = DEREF_hashid ( id_name ( lab ) ) ;
177
		nm = DEREF_hashid(id_name(lab));
150
    }
178
	}
151
 
179
 
152
    /* Check for fall through */
180
	/* Check for fall through */
-
 
181
	if (!unreached_code) {
153
    if ( !unreached_code ) def_info |= dspec_fall_thru ;
182
		def_info |= dspec_fall_thru;
-
 
183
	}
154
 
184
 
155
    /* Check if label has already been defined */
185
	/* Check if label has already been defined */
156
    mem = search_member ( label_namespace, nm, 1 ) ;
186
	mem = search_member(label_namespace, nm, 1);
157
    lab = DEREF_id ( member_id ( mem ) ) ;
187
	lab = DEREF_id(member_id(mem));
158
    if ( !IS_NULL_id ( lab ) ) {
188
	if (!IS_NULL_id(lab)) {
159
	DECL_SPEC info = DEREF_dspec ( id_storage ( lab ) ) ;
189
		DECL_SPEC info = DEREF_dspec(id_storage(lab));
160
	if ( info & dspec_defn ) {
190
		if (info & dspec_defn) {
161
	    /* Already defined */
191
			/* Already defined */
162
	    IDENTIFIER fn = crt_func_id ;
192
			IDENTIFIER fn = crt_func_id;
163
	    PTR ( LOCATION ) loc = id_loc ( lab ) ;
193
			PTR(LOCATION) loc = id_loc(lab);
164
	    report ( crt_loc, ERR_stmt_label_redef ( lab, fn, loc ) ) ;
194
			report(crt_loc, ERR_stmt_label_redef(lab, fn, loc));
165
	    return ( NULL_exp ) ;
195
			return (NULL_exp);
166
	}
196
		}
167
	/* Already used */
197
		/* Already used */
168
	info |= def_info ;
198
		info |= def_info;
169
	COPY_dspec ( id_storage ( lab ), info ) ;
199
		COPY_dspec(id_storage(lab), info);
170
	COPY_loc ( id_loc ( lab ), crt_loc ) ;
200
		COPY_loc(id_loc(lab), crt_loc);
171
    } else {
201
	} else {
172
	/* Not used or defined previously */
202
		/* Not used or defined previously */
173
	lab = make_label ( nm, def_info, op ) ;
203
		lab = make_label(nm, def_info, op);
174
	COPY_id ( member_id ( mem ), lab ) ;
204
		COPY_id(member_id(mem), lab);
175
    }
205
	}
176
    if ( do_local && !IS_hashid_anon ( nm ) ) {
206
	if (do_local && !IS_hashid_anon(nm)) {
177
	dump_declare ( lab, &crt_loc, 1 ) ;
207
		dump_declare(lab, &crt_loc, 1);
178
    }
208
	}
179
 
209
 
180
    /* Create a labelled statement */
210
	/* Create a labelled statement */
181
    seq = begin_compound_stmt ( 0 ) ;
211
	seq = begin_compound_stmt(0);
182
    MAKE_exp_label_stmt ( type_void, lab, seq, e ) ;
212
	MAKE_exp_label_stmt(type_void, lab, seq, e);
183
    COPY_exp ( exp_sequence_parent ( seq ), e ) ;
213
	COPY_exp(exp_sequence_parent(seq), e);
184
    COPY_exp ( id_label_stmt ( lab ), e ) ;
214
	COPY_exp(id_label_stmt(lab), e);
185
    unreached_code = 0 ;
215
	unreached_code = 0;
186
    unreached_last = 0 ;
216
	unreached_last = 0;
187
    return ( e ) ;
217
	return (e);
188
}
218
}
189
 
219
 
190
 
220
 
191
/*
221
/*
192
    COMPLETE A LABELLED STATEMENT
222
    COMPLETE A LABELLED STATEMENT
193
 
223
 
194
    This routine completes the construction of the labelled statement prev
224
    This routine completes the construction of the labelled statement prev
195
    using the statement body.  It is also used to handle case and default
225
    using the statement body.  It is also used to handle case and default
196
    statements.  If prev is the null expression, indicating any illegal
226
    statements.  If prev is the null expression, indicating any illegal
197
    label of some kind, then body is returned.  Otherwise body is added
227
    label of some kind, then body is returned.  Otherwise body is added
198
    to the compound statement which is labelled.
228
    to the compound statement which is labelled.
199
*/
229
*/
200
 
230
 
201
EXP end_label_stmt
231
EXP
202
    PROTO_N ( ( prev, body ) )
-
 
203
    PROTO_T ( EXP prev X EXP body )
232
end_label_stmt(EXP prev, EXP body)
204
{
233
{
205
    EXP seq ;
234
	EXP seq;
206
    IDENTIFIER lab ;
235
	IDENTIFIER lab;
207
    DECL_SPEC info ;
236
	DECL_SPEC info;
208
    if ( IS_NULL_exp ( prev ) ) return ( body ) ;
237
	if (IS_NULL_exp(prev)) {
-
 
238
		return (body);
-
 
239
	}
209
 
240
 
210
    /* Mark end of label scope */
241
	/* Mark end of label scope */
211
    lab = DEREF_id ( exp_label_stmt_label ( prev ) ) ;
242
	lab = DEREF_id(exp_label_stmt_label(prev));
212
    info = DEREF_dspec ( id_storage ( lab ) ) ;
243
	info = DEREF_dspec(id_storage(lab));
213
    info &= ~dspec_scope ;
244
	info &= ~dspec_scope;
214
    COPY_dspec ( id_storage ( lab ), info ) ;
245
	COPY_dspec(id_storage(lab), info);
215
 
246
 
216
    /* Check for consecutive labels */
247
	/* Check for consecutive labels */
217
    if ( !IS_NULL_exp ( body ) && IS_exp_label_stmt ( body ) ) {
248
	if (!IS_NULL_exp(body) && IS_exp_label_stmt(body)) {
218
	/* Two consecutive labels */
249
		/* Two consecutive labels */
219
	IDENTIFIER blab = DEREF_id ( exp_label_stmt_label ( body ) ) ;
250
		IDENTIFIER blab = DEREF_id(exp_label_stmt_label(body));
220
	blab = DEREF_id ( id_alias ( blab ) ) ;
251
		blab = DEREF_id(id_alias(blab));
221
	COPY_id ( id_alias ( lab ), blab ) ;
252
		COPY_id(id_alias(lab), blab);
222
    }
253
	}
223
 
254
 
224
    /* Assign to label body */
255
	/* Assign to label body */
225
    seq = DEREF_exp ( exp_label_stmt_body ( prev ) ) ;
256
	seq = DEREF_exp(exp_label_stmt_body(prev));
226
    seq = add_compound_stmt ( seq, body ) ;
257
	seq = add_compound_stmt(seq, body);
227
    COPY_exp ( exp_label_stmt_body ( prev ), seq ) ;
258
	COPY_exp(exp_label_stmt_body(prev), seq);
228
    return ( prev ) ;
259
	return (prev);
229
}
260
}
230
 
261
 
231
 
262
 
232
/*
263
/*
233
    CONSTRUCT A JUMP TO A LABEL
264
    CONSTRUCT A JUMP TO A LABEL
234
 
265
 
235
    This routine constructs a jump to the label lab (including break and
266
    This routine constructs a jump to the label lab (including break and
236
    continue statements).  join gives the smallest statement containing
267
    continue statements).  join gives the smallest statement containing
237
    both the label and the jump.  This can only be filled in later for
268
    both the label and the jump.  This can only be filled in later for
238
    named labels.
269
    named labels.
239
*/
270
*/
240
 
271
 
241
EXP make_jump_stmt
272
EXP
242
    PROTO_N ( ( lab, join ) )
-
 
243
    PROTO_T ( IDENTIFIER lab X EXP join )
273
make_jump_stmt(IDENTIFIER lab, EXP join)
244
{
274
{
245
    DECL_SPEC info ;
275
	DECL_SPEC info;
246
    EXP e = DEREF_exp ( id_label_gotos ( lab ) ) ;
276
	EXP e = DEREF_exp(id_label_gotos(lab));
247
 
277
 
248
    /* Mark the label as used */
278
	/* Mark the label as used */
249
    info = DEREF_dspec ( id_storage ( lab ) ) ;
279
	info = DEREF_dspec(id_storage(lab));
250
    info |= ( dspec_used | dspec_goto ) ;
280
	info |= (dspec_used | dspec_goto);
-
 
281
	if (!unreached_code) {
251
    if ( !unreached_code ) info |= dspec_reached ;
282
		info |= dspec_reached;
-
 
283
	}
252
    COPY_dspec ( id_storage ( lab ), info ) ;
284
	COPY_dspec(id_storage(lab), info);
253
 
285
 
254
    /* Construct the jump statement */
286
	/* Construct the jump statement */
255
    if ( IS_NULL_exp ( join ) && ( info & dspec_scope ) ) {
287
	if (IS_NULL_exp(join) && (info & dspec_scope)) {
256
	join = DEREF_exp ( id_label_stmt ( lab ) ) ;
288
		join = DEREF_exp(id_label_stmt(lab));
257
    }
289
	}
258
    MAKE_exp_goto_stmt ( type_bottom, lab, join, e, e ) ;
290
	MAKE_exp_goto_stmt(type_bottom, lab, join, e, e);
259
    COPY_exp ( id_label_gotos ( lab ), e ) ;
291
	COPY_exp(id_label_gotos(lab), e);
260
    unreached_code = 1 ;
292
	unreached_code = 1;
261
    unreached_last = 0 ;
293
	unreached_last = 0;
262
    return ( e ) ;
294
	return (e);
263
}
295
}
264
 
296
 
265
 
297
 
266
/*
298
/*
267
    CONSTRUCT A GOTO STATEMENT
299
    CONSTRUCT A GOTO STATEMENT
Line 269... Line 301...
269
    This routine constructs a goto statement where the destination label
301
    This routine constructs a goto statement where the destination label
270
    is given by lab.  Note that it is possible to use a label before it
302
    is given by lab.  Note that it is possible to use a label before it
271
    is defined.
303
    is defined.
272
*/
304
*/
273
 
305
 
274
EXP make_goto_stmt
306
EXP
275
    PROTO_N ( ( lab ) )
-
 
276
    PROTO_T ( IDENTIFIER lab )
307
make_goto_stmt(IDENTIFIER lab)
277
{
308
{
278
    /* Look up existing label */
309
	/* Look up existing label */
279
    EXP e ;
310
	EXP e;
280
    HASHID nm ;
311
	HASHID nm;
281
    MEMBER mem ;
312
	MEMBER mem;
282
    if ( IS_NULL_id ( lab ) ) {
313
	if (IS_NULL_id(lab)) {
283
	nm = lookup_anon () ;
314
		nm = lookup_anon();
284
    } else {
315
	} else {
285
	nm = DEREF_hashid ( id_name ( lab ) ) ;
316
		nm = DEREF_hashid(id_name(lab));
286
    }
317
	}
287
    mem = search_member ( label_namespace, nm, 1 ) ;
318
	mem = search_member(label_namespace, nm, 1);
288
    lab = DEREF_id ( member_id ( mem ) ) ;
319
	lab = DEREF_id(member_id(mem));
289
    if ( IS_NULL_id ( lab ) ) {
320
	if (IS_NULL_id(lab)) {
290
	/* Create new label */
321
		/* Create new label */
291
	DECL_SPEC info = ( dspec_used | dspec_goto ) ;
322
		DECL_SPEC info = (dspec_used | dspec_goto);
292
	lab = make_label ( nm, info, lex_identifier ) ;
323
		lab = make_label(nm, info, lex_identifier);
293
	COPY_id ( member_id ( mem ), lab ) ;
324
		COPY_id(member_id(mem), lab);
294
    } else {
325
	} else {
295
	DECL_SPEC info = DEREF_dspec ( id_storage ( lab ) ) ;
326
		DECL_SPEC info = DEREF_dspec(id_storage(lab));
296
	if ( info & dspec_defn ) {
327
		if (info & dspec_defn) {
297
	    /* Backward jump */
328
			/* Backward jump */
298
	    info |= dspec_reserve ;
329
			info |= dspec_reserve;
299
	    COPY_dspec ( id_storage ( lab ), info ) ;
330
			COPY_dspec(id_storage(lab), info);
-
 
331
		}
-
 
332
	}
-
 
333
	if (do_local && do_usage && !IS_hashid_anon(nm)) {
-
 
334
		dump_use(lab, &crt_loc, 1);
300
	}
335
	}
301
    }
-
 
302
    if ( do_local && do_usage && !IS_hashid_anon ( nm ) ) {
-
 
303
	dump_use ( lab, &crt_loc, 1 ) ;
-
 
304
    }
-
 
305
    e = make_jump_stmt ( lab, NULL_exp ) ;
336
	e = make_jump_stmt(lab, NULL_exp);
306
    return ( e ) ;
337
	return (e);
307
}
338
}
308
 
339
 
309
 
340
 
310
/*
341
/*
311
    POSTLUDE LABEL NAME
342
    POSTLUDE LABEL NAME
312
 
343
 
313
    This value gives the name associated with all postlude labels.  It is
344
    This value gives the name associated with all postlude labels.  It is
314
    assigned when the first postlude label is created.
345
    assigned when the first postlude label is created.
315
*/
346
*/
316
 
347
 
317
static HASHID postlude_name = NULL_hashid ;
348
static HASHID postlude_name = NULL_hashid;
318
 
349
 
319
 
350
 
320
/*
351
/*
321
    CREATE A POSTLUDE LABEL
352
    CREATE A POSTLUDE LABEL
322
 
353
 
Line 325... Line 356...
325
    At present this is only used in functions which do not return a value.
356
    At present this is only used in functions which do not return a value.
326
    A return statement within such a function is mapped onto a jump to
357
    A return statement within such a function is mapped onto a jump to
327
    the postlude label.
358
    the postlude label.
328
*/
359
*/
329
 
360
 
330
IDENTIFIER postlude_label
361
IDENTIFIER
331
    PROTO_Z ()
362
postlude_label(void)
332
{
363
{
333
    IDENTIFIER lab ;
364
	IDENTIFIER lab;
334
    HASHID nm = postlude_name ;
365
	HASHID nm = postlude_name;
335
    if ( IS_NULL_hashid ( nm ) ) {
366
	if (IS_NULL_hashid(nm)) {
336
	/* Assign postlude label name */
367
		/* Assign postlude label name */
337
	nm = lookup_anon () ;
368
		nm = lookup_anon();
338
	postlude_name = nm ;
369
		postlude_name = nm;
339
    }
370
	}
340
    lab = DEREF_id ( hashid_id ( nm ) ) ;
371
	lab = DEREF_id(hashid_id(nm));
341
    return ( lab ) ;
372
	return (lab);
342
}
373
}
343
 
374
 
344
 
375
 
345
/*
376
/*
346
    FIND A POSTLUDE LABEL
377
    FIND A POSTLUDE LABEL
347
 
378
 
348
    This routine returns the postlude label associated with the current
379
    This routine returns the postlude label associated with the current
349
    function or the null identifier if the function has no postlude.
380
    function or the null identifier if the function has no postlude.
350
*/
381
*/
351
 
382
 
352
IDENTIFIER find_postlude_label
383
IDENTIFIER
353
    PROTO_Z ()
384
find_postlude_label(void)
354
{
385
{
355
    HASHID nm = postlude_name ;
386
	HASHID nm = postlude_name;
356
    if ( !IS_NULL_hashid ( nm ) ) {
387
	if (!IS_NULL_hashid(nm)) {
357
	MEMBER mem = search_member ( label_namespace, nm, 0 ) ;
388
		MEMBER mem = search_member(label_namespace, nm, 0);
358
	if ( !IS_NULL_member ( mem ) ) {
389
		if (!IS_NULL_member(mem)) {
359
	    IDENTIFIER lab = DEREF_id ( member_id ( mem ) ) ;
390
			IDENTIFIER lab = DEREF_id(member_id(mem));
360
	    return ( lab ) ;
391
			return (lab);
361
	}
392
		}
362
    }
393
	}
363
    return ( NULL_id ) ;
394
	return (NULL_id);
364
}
395
}
365
 
396
 
366
 
397
 
367
/*
398
/*
368
    HAS A LABELLED STATEMENT BEEN REACHED?
399
    HAS A LABELLED STATEMENT BEEN REACHED?
369
 
400
 
370
    This routine checks whether the label label has been reached using
401
    This routine checks whether the label label has been reached using
371
    an explicit goto, break or continue statement in a reached portion of
402
    an explicit goto, break or continue statement in a reached portion of
372
    the program (when it returns 1) or by fall through from the previous
403
    the program (when it returns 1) or by fall through from the previous
373
    statement (when it returns 2).
404
    statement (when it returns 2).
374
*/
405
*/
375
 
406
 
376
int used_label
407
int
377
    PROTO_N ( ( lab ) )
-
 
378
    PROTO_T ( IDENTIFIER lab )
408
used_label(IDENTIFIER lab)
379
{
409
{
380
    DECL_SPEC info = DEREF_dspec ( id_storage ( lab ) ) ;
410
	DECL_SPEC info = DEREF_dspec(id_storage(lab));
381
    if ( info & dspec_reached ) return ( 1 ) ;
411
	if (info & dspec_reached) {
-
 
412
		return (1);
-
 
413
	}
382
    if ( info & dspec_fall_thru ) return ( 2 ) ;
414
	if (info & dspec_fall_thru) {
-
 
415
		return (2);
-
 
416
	}
383
    return ( 0 ) ;
417
	return (0);
384
}
418
}
385
 
419
 
386
 
420
 
387
/*
421
/*
388
    CHECK ALL LABELS IN A FUNCTION
422
    CHECK ALL LABELS IN A FUNCTION
389
 
423
 
390
    This routine scans through all the labels defined in the current
424
    This routine scans through all the labels defined in the current
391
    function searching for any which have been used but not defined.
425
    function searching for any which have been used but not defined.
392
    It returns the number of named labels defined.
426
    It returns the number of named labels defined.
393
*/
427
*/
394
 
428
 
395
unsigned check_labels
429
unsigned
396
    PROTO_Z ()
430
check_labels(void)
397
{
431
{
398
    /* Scan through all labels */
432
    /* Scan through all labels */
399
    unsigned no_labs = 0 ;
433
    unsigned no_labs = 0;
400
    NAMESPACE ns = label_namespace ;
434
    NAMESPACE ns = label_namespace;
401
    MEMBER mem = DEREF_member ( nspace_last ( ns ) ) ;
435
    MEMBER mem = DEREF_member(nspace_last(ns));
402
    while ( !IS_NULL_member ( mem ) ) {
436
    while (!IS_NULL_member(mem)) {
403
	LOCATION loc ;
437
	LOCATION loc;
404
	IDENTIFIER lab = DEREF_id ( member_id ( mem ) ) ;
438
	IDENTIFIER lab = DEREF_id(member_id(mem));
405
	if ( !IS_NULL_id ( lab ) ) {
439
	if (!IS_NULL_id(lab)) {
406
	    /* Check label information */
440
	    /* Check label information */
407
	    DECL_SPEC info = DEREF_dspec ( id_storage ( lab ) ) ;
441
	    DECL_SPEC info = DEREF_dspec(id_storage(lab));
408
	    IDENTIFIER flab = DEREF_id ( id_alias ( lab ) ) ;
442
	    IDENTIFIER flab = DEREF_id(id_alias(lab));
409
	    if ( !EQ_id ( lab, flab ) ) {
443
	    if (!EQ_id(lab, flab)) {
410
		/* Deal with label aliases */
444
		/* Deal with label aliases */
411
		DECL_SPEC finfo = DEREF_dspec ( id_storage ( flab ) ) ;
445
		DECL_SPEC finfo = DEREF_dspec(id_storage(flab));
412
		finfo |= ( info & dspec_used ) ;
446
		finfo |= (info & dspec_used);
413
		COPY_dspec ( id_storage ( flab ), finfo ) ;
447
		COPY_dspec(id_storage(flab), finfo);
414
	    }
448
	    }
415
	    if ( info & dspec_anon ) {
449
	    if (info & dspec_anon) {
416
		/* Unnamed labels are ignored */
450
		/* Unnamed labels are ignored */
417
		/* EMPTY */
451
		/* EMPTY */
418
	    } else if ( info & dspec_defn ) {
452
	    } else if (info & dspec_defn) {
419
		/* Defined labels */
453
		/* Defined labels */
420
		HASHID nm = DEREF_hashid ( id_name ( lab ) ) ;
454
		HASHID nm = DEREF_hashid(id_name(lab));
421
		if ( !IS_hashid_anon ( nm ) ) {
455
		if (!IS_hashid_anon(nm)) {
422
		    if ( info & dspec_goto ) {
456
		    if (info & dspec_goto) {
423
			/* Label used and defined */
457
			/* Label used and defined */
424
			/* EMPTY */
458
			/* EMPTY */
425
		    } else {
459
		    } else {
426
			/* Label defined but not used */
460
			/* Label defined but not used */
427
			IDENTIFIER fn = crt_func_id ;
461
			IDENTIFIER fn = crt_func_id;
428
			DEREF_loc ( id_loc ( lab ), loc ) ;
462
			DEREF_loc(id_loc(lab), loc);
429
			report ( loc, ERR_stmt_label_unused ( lab, fn ) ) ;
463
			report(loc, ERR_stmt_label_unused(lab, fn));
430
		    }
464
		    }
431
		    if ( info & ( dspec_reached | dspec_fall_thru ) ) {
465
		    if (info & (dspec_reached | dspec_fall_thru)) {
432
			/* Label reached */
466
			/* Label reached */
433
			/* EMPTY */
467
			/* EMPTY */
434
		    } else {
468
		    } else {
435
			/* Label unreached */
469
			/* Label unreached */
436
			DEREF_loc ( id_loc ( lab ), loc ) ;
470
			DEREF_loc(id_loc(lab), loc);
437
			report ( loc, ERR_stmt_stmt_unreach () ) ;
471
			report(loc, ERR_stmt_stmt_unreach());
438
		    }
472
		    }
439
		}
473
		}
440
		no_labs++ ;
474
		no_labs++;
441
	    } else {
475
	    } else {
442
		/* Undefined labels */
476
		/* Undefined labels */
443
		HASHID nm = DEREF_hashid ( id_name ( lab ) ) ;
477
		HASHID nm = DEREF_hashid(id_name(lab));
444
		if ( !IS_hashid_anon ( nm ) ) {
478
		if (!IS_hashid_anon(nm)) {
445
		    IDENTIFIER fn = crt_func_id ;
479
		    IDENTIFIER fn = crt_func_id;
446
		    DEREF_loc ( id_loc ( lab ), loc ) ;
480
		    DEREF_loc(id_loc(lab), loc);
447
		    report ( loc, ERR_stmt_goto_undef ( lab, fn ) ) ;
481
		    report(loc, ERR_stmt_goto_undef(lab, fn));
448
		}
482
		}
449
	    }
483
	    }
450
	}
484
	}
451
 
485
 
452
	/* Check next label */
486
	/* Check next label */
453
	mem = DEREF_member ( member_next ( mem ) ) ;
487
	mem = DEREF_member(member_next(mem));
454
    }
488
    }
455
    return ( no_labs ) ;
489
    return (no_labs);
456
}
490
}
457
 
491
 
458
 
492
 
459
/*
493
/*
460
    FIND THE VALUE OF A CASE LABEL
494
    FIND THE VALUE OF A CASE LABEL
461
 
495
 
462
    This routine determines the value associated with the case label lab.
496
    This routine determines the value associated with the case label lab.
463
*/
497
*/
464
 
498
 
465
NAT find_case_nat
499
NAT
466
    PROTO_N ( ( lab ) )
-
 
467
    PROTO_T ( IDENTIFIER lab )
500
find_case_nat(IDENTIFIER lab)
468
{
501
{
469
    EXP e = DEREF_exp ( id_label_gotos ( lab ) ) ;
502
	EXP e = DEREF_exp(id_label_gotos(lab));
470
    if ( !IS_NULL_exp ( e ) && IS_exp_switch_stmt ( e ) ) {
503
	if (!IS_NULL_exp(e) && IS_exp_switch_stmt(e)) {
471
	LIST ( NAT ) p ;
504
		LIST(NAT) p;
472
	LIST ( IDENTIFIER ) q ;
505
		LIST(IDENTIFIER) q;
473
	p = DEREF_list ( exp_switch_stmt_cases ( e ) ) ;
506
		p = DEREF_list(exp_switch_stmt_cases(e));
474
	q = DEREF_list ( exp_switch_stmt_case_labs ( e ) ) ;
507
		q = DEREF_list(exp_switch_stmt_case_labs(e));
475
	while ( !IS_NULL_list ( q ) ) {
508
		while (!IS_NULL_list(q)) {
476
	    IDENTIFIER id = DEREF_id ( HEAD_list ( q ) ) ;
509
			IDENTIFIER id = DEREF_id(HEAD_list(q));
477
	    if ( EQ_id ( id, lab ) ) {
510
			if (EQ_id(id, lab)) {
478
		NAT n = DEREF_nat ( HEAD_list ( p ) ) ;
511
				NAT n = DEREF_nat(HEAD_list(p));
479
		return ( n ) ;
512
				return (n);
480
	    }
513
			}
481
	    p = TAIL_list ( p ) ;
514
			p = TAIL_list(p);
482
	    q = TAIL_list ( q ) ;
515
			q = TAIL_list(q);
-
 
516
		}
483
	}
517
	}
484
    }
-
 
485
    return ( NULL_nat ) ;
518
	return (NULL_nat);
486
}
519
}
487
 
520
 
488
 
521
 
489
/*
522
/*
490
    LISTS OF ALL SOLVE STATEMENTS AND TRY BLOCKS
523
    LISTS OF ALL SOLVE STATEMENTS AND TRY BLOCKS
491
 
524
 
492
    The list all_solve_stmts keeps track of all the solve statements in
525
    The list all_solve_stmts keeps track of all the solve statements in
493
    the current function.  Similarly all_try_blocks keeps track of all the
526
    the current function.  Similarly all_try_blocks keeps track of all the
494
    try blocks.
527
    try blocks.
495
*/
528
*/
496
 
529
 
497
LIST ( EXP ) all_solve_stmts = NULL_list ( EXP ) ;
530
LIST(EXP) all_solve_stmts = NULL_list(EXP);
498
LIST ( EXP ) all_try_blocks = NULL_list ( EXP ) ;
531
LIST(EXP) all_try_blocks = NULL_list(EXP);
499
 
532
 
500
 
533
 
501
/*
534
/*
502
    CHECK JUMPED OVER STATEMENTS
535
    CHECK JUMPED OVER STATEMENTS
503
 
536
 
504
    This routine checks whether a jump over the statement e to the label
537
    This routine checks whether a jump over the statement e to the label
505
    lab causes the initialisation of a variable to be bypassed or control
538
    lab causes the initialisation of a variable to be bypassed or control
Line 508... Line 541...
508
    reported.  It is 2 for a jump into the statement, 1 for a jump from
541
    reported.  It is 2 for a jump into the statement, 1 for a jump from
509
    one branch of a statement to another (for example, a handler to the
542
    one branch of a statement to another (for example, a handler to the
510
    body of a try block), and 0 otherwise.  The routine adds any variable
543
    body of a try block), and 0 otherwise.  The routine adds any variable
511
    or label which is jumped over, whether initialised or not, to the
544
    or label which is jumped over, whether initialised or not, to the
512
    list ids.
545
    list ids.
513
*/
546
*/
514
 
-
 
515
static LIST ( IDENTIFIER ) jump_over_stmt
-
 
516
    PROTO_N ( ( ids, e, lab, force ) )
-
 
517
    PROTO_T ( LIST ( IDENTIFIER ) ids X EXP e X IDENTIFIER lab X int force )
-
 
518
{
-
 
519
    switch ( TAG_exp ( e ) ) {
-
 
520
 
-
 
521
	case exp_decl_stmt_tag : {
-
 
522
	    /* Jump into declaration body */
-
 
523
	    IDENTIFIER id = DEREF_id ( exp_decl_stmt_id ( e ) ) ;
-
 
524
	    DECL_SPEC ds = DEREF_dspec ( id_storage ( id ) ) ;
-
 
525
	    if ( ds & dspec_auto ) {
-
 
526
		if ( force == 2 ) {
-
 
527
		    int init = 1 ;
-
 
528
		    EXP d = DEREF_exp ( id_variable_init ( id ) ) ;
-
 
529
		    if ( IS_NULL_exp ( d ) || IS_exp_null ( d ) ) {
-
 
530
			if ( ds & dspec_reserve ) {
-
 
531
			    /* Initialised in conditional */
-
 
532
			    /* EMPTY */
-
 
533
			} else {
-
 
534
			    /* No initialiser */
-
 
535
			    init = 0 ;
-
 
536
			}
-
 
537
		    }
-
 
538
		    if ( init ) {
-
 
539
			/* Jump over initialiser */
-
 
540
			ERROR err ;
-
 
541
			LOCATION loc ;
-
 
542
			int op = DEREF_int ( id_label_op ( lab ) ) ;
-
 
543
			if ( op == lex_identifier ) {
-
 
544
			    err = ERR_stmt_dcl_bypass_lab ( lab, id ) ;
-
 
545
			} else if ( op == lex_case ) {
-
 
546
			    NAT n = find_case_nat ( lab ) ;
-
 
547
			    err = ERR_stmt_dcl_bypass_case ( n, id ) ;
-
 
548
			} else {
-
 
549
			    err = ERR_stmt_dcl_bypass_default ( id ) ;
-
 
550
			}
-
 
551
			DEREF_loc ( id_loc ( id ), loc ) ;
-
 
552
			report ( loc, err ) ;
-
 
553
		    }
-
 
554
		}
-
 
555
		CONS_id ( id, ids, ids ) ;
-
 
556
	    }
-
 
557
	    break ;
-
 
558
	}
-
 
559
 
-
 
560
	case exp_if_stmt_tag : {
-
 
561
	    /* Jump into if statement */
-
 
562
	    IDENTIFIER lb = DEREF_id ( exp_if_stmt_label ( e ) ) ;
-
 
563
	    if ( !IS_NULL_id ( lb ) ) CONS_id ( lb, ids, ids ) ;
-
 
564
	    break ;
-
 
565
	}
-
 
566
 
-
 
567
	case exp_while_stmt_tag : {
-
 
568
	    /* Jump into while loop */
-
 
569
	    IDENTIFIER bk = DEREF_id ( exp_while_stmt_break_lab ( e ) ) ;
-
 
570
	    IDENTIFIER cn = DEREF_id ( exp_while_stmt_cont_lab ( e ) ) ;
-
 
571
	    IDENTIFIER lp = DEREF_id ( exp_while_stmt_loop_lab ( e ) ) ;
-
 
572
	    CONS_id ( bk, ids, ids ) ;
-
 
573
	    CONS_id ( cn, ids, ids ) ;
-
 
574
	    CONS_id ( lp, ids, ids ) ;
-
 
575
	    break ;
-
 
576
	}
-
 
577
 
-
 
578
	case exp_do_stmt_tag : {
-
 
579
	    /* Jump into do loop */
-
 
580
	    IDENTIFIER bk = DEREF_id ( exp_do_stmt_break_lab ( e ) ) ;
-
 
581
	    IDENTIFIER cn = DEREF_id ( exp_do_stmt_cont_lab ( e ) ) ;
-
 
582
	    IDENTIFIER lp = DEREF_id ( exp_do_stmt_loop_lab ( e ) ) ;
-
 
583
	    CONS_id ( bk, ids, ids ) ;
-
 
584
	    CONS_id ( cn, ids, ids ) ;
-
 
585
	    CONS_id ( lp, ids, ids ) ;
-
 
586
	    break ;
-
 
587
	}
-
 
588
 
-
 
589
	case exp_switch_stmt_tag : {
-
 
590
	    /* Jump into switch statement */
-
 
591
	    IDENTIFIER bk = DEREF_id ( exp_switch_stmt_break_lab ( e ) ) ;
-
 
592
	    CONS_id ( bk, ids, ids ) ;
-
 
593
	    break ;
-
 
594
	}
-
 
595
 
-
 
596
	case exp_solve_stmt_tag : {
-
 
597
	    /* Jump into solve statement */
-
 
598
	    LIST ( IDENTIFIER ) lbs ;
-
 
599
	    LIST ( IDENTIFIER ) vars ;
-
 
600
	    lbs = DEREF_list ( exp_solve_stmt_labels ( e ) ) ;
-
 
601
	    while ( !IS_NULL_list ( lbs ) ) {
-
 
602
		IDENTIFIER lb = DEREF_id ( HEAD_list ( lbs ) ) ;
-
 
603
		CONS_id ( lb, ids, ids ) ;
-
 
604
		lbs = TAIL_list ( lbs ) ;
-
 
605
	    }
-
 
606
	    vars = DEREF_list ( exp_solve_stmt_vars ( e ) ) ;
-
 
607
	    while ( !IS_NULL_list ( vars ) ) {
-
 
608
		IDENTIFIER var = DEREF_id ( HEAD_list ( vars ) ) ;
-
 
609
		CONS_id ( var, ids, ids ) ;
-
 
610
		vars = TAIL_list ( vars ) ;
-
 
611
	    }
-
 
612
	    break ;
-
 
613
	}
-
 
614
 
547
 
-
 
548
static LIST(IDENTIFIER)
-
 
549
jump_over_stmt(LIST(IDENTIFIER) ids, EXP e, IDENTIFIER lab, int force)
-
 
550
{
-
 
551
	switch (TAG_exp(e)) {
-
 
552
	case exp_decl_stmt_tag: {
-
 
553
		/* Jump into declaration body */
-
 
554
		IDENTIFIER id = DEREF_id(exp_decl_stmt_id(e));
-
 
555
		DECL_SPEC ds = DEREF_dspec(id_storage(id));
-
 
556
		if (ds & dspec_auto) {
-
 
557
			if (force == 2) {
-
 
558
				int init = 1;
-
 
559
				EXP d = DEREF_exp(id_variable_init(id));
-
 
560
				if (IS_NULL_exp(d) || IS_exp_null(d)) {
-
 
561
					if (ds & dspec_reserve) {
-
 
562
						/* Initialised in conditional */
-
 
563
						/* EMPTY */
-
 
564
					} else {
-
 
565
						/* No initialiser */
-
 
566
						init = 0;
-
 
567
					}
-
 
568
				}
-
 
569
				if (init) {
-
 
570
					/* Jump over initialiser */
-
 
571
					ERROR err;
-
 
572
					LOCATION loc;
-
 
573
					int op = DEREF_int(id_label_op(lab));
-
 
574
					if (op == lex_identifier) {
-
 
575
						err = ERR_stmt_dcl_bypass_lab(lab, id);
-
 
576
					} else if (op == lex_case) {
-
 
577
						NAT n = find_case_nat(lab);
-
 
578
						err = ERR_stmt_dcl_bypass_case(n, id);
-
 
579
					} else {
-
 
580
						err = ERR_stmt_dcl_bypass_default(id);
-
 
581
					}
-
 
582
					DEREF_loc(id_loc(id), loc);
-
 
583
					report(loc, err);
-
 
584
				}
-
 
585
			}
-
 
586
			CONS_id(id, ids, ids);
-
 
587
		}
-
 
588
		break;
-
 
589
	}
-
 
590
	case exp_if_stmt_tag: {
-
 
591
		/* Jump into if statement */
-
 
592
		IDENTIFIER lb = DEREF_id(exp_if_stmt_label(e));
-
 
593
		if (!IS_NULL_id(lb)) {
-
 
594
			CONS_id(lb, ids, ids);
-
 
595
		}
-
 
596
		break;
-
 
597
	}
-
 
598
	case exp_while_stmt_tag: {
-
 
599
		/* Jump into while loop */
-
 
600
		IDENTIFIER bk = DEREF_id(exp_while_stmt_break_lab(e));
-
 
601
		IDENTIFIER cn = DEREF_id(exp_while_stmt_cont_lab(e));
-
 
602
		IDENTIFIER lp = DEREF_id(exp_while_stmt_loop_lab(e));
-
 
603
		CONS_id(bk, ids, ids);
-
 
604
		CONS_id(cn, ids, ids);
-
 
605
		CONS_id(lp, ids, ids);
-
 
606
		break;
-
 
607
	}
-
 
608
	case exp_do_stmt_tag: {
-
 
609
		/* Jump into do loop */
-
 
610
		IDENTIFIER bk = DEREF_id(exp_do_stmt_break_lab(e));
-
 
611
		IDENTIFIER cn = DEREF_id(exp_do_stmt_cont_lab(e));
-
 
612
		IDENTIFIER lp = DEREF_id(exp_do_stmt_loop_lab(e));
-
 
613
		CONS_id(bk, ids, ids);
-
 
614
		CONS_id(cn, ids, ids);
-
 
615
		CONS_id(lp, ids, ids);
-
 
616
		break;
-
 
617
	}
-
 
618
	case exp_switch_stmt_tag: {
-
 
619
		/* Jump into switch statement */
-
 
620
		IDENTIFIER bk = DEREF_id(exp_switch_stmt_break_lab(e));
-
 
621
		CONS_id(bk, ids, ids);
-
 
622
		break;
-
 
623
	}
-
 
624
	case exp_solve_stmt_tag: {
-
 
625
		/* Jump into solve statement */
-
 
626
		LIST(IDENTIFIER) lbs;
-
 
627
		LIST(IDENTIFIER) vars;
-
 
628
		lbs = DEREF_list(exp_solve_stmt_labels(e));
-
 
629
		while (!IS_NULL_list(lbs)) {
-
 
630
			IDENTIFIER lb = DEREF_id(HEAD_list(lbs));
-
 
631
			CONS_id(lb, ids, ids);
-
 
632
			lbs = TAIL_list(lbs);
-
 
633
		}
-
 
634
		vars = DEREF_list(exp_solve_stmt_vars(e));
-
 
635
		while (!IS_NULL_list(vars)) {
-
 
636
			IDENTIFIER var = DEREF_id(HEAD_list(vars));
-
 
637
			CONS_id(var, ids, ids);
-
 
638
			vars = TAIL_list(vars);
-
 
639
		}
-
 
640
		break;
-
 
641
	}
615
	case exp_label_stmt_tag : {
642
	case exp_label_stmt_tag: {
616
	    /* Jump into labelled block */
643
		/* Jump into labelled block */
617
	    IDENTIFIER lb = DEREF_id ( exp_label_stmt_label ( e ) ) ;
644
		IDENTIFIER lb = DEREF_id(exp_label_stmt_label(e));
618
	    CONS_id ( lb, ids, ids ) ;
645
		CONS_id(lb, ids, ids);
619
	    break ;
646
		break;
620
	}
647
	}
621
 
-
 
622
	case exp_try_block_tag : {
648
	case exp_try_block_tag:
623
	    /* Jump into try block */
649
		/* Jump into try block */
624
	    if ( force != 0 ) {
650
		if (force != 0) {
625
		LOCATION loc ;
651
			LOCATION loc;
626
		DEREF_loc ( id_loc ( lab ), loc ) ;
652
			DEREF_loc(id_loc(lab), loc);
627
		report ( loc, ERR_except_jump_into () ) ;
653
			report(loc, ERR_except_jump_into());
-
 
654
		}
-
 
655
		break;
-
 
656
	case exp_hash_if_tag:
-
 
657
		/* Jump into target dependent '#if' */
-
 
658
		if (force != 0) {
-
 
659
			LOCATION loc;
-
 
660
			DEREF_loc(id_loc(lab), loc);
-
 
661
			report(loc, ERR_cpp_cond_if_jump_into());
-
 
662
		}
-
 
663
		break;
-
 
664
	case exp_token_tag:
-
 
665
		/* Jump into statement token */
-
 
666
		if (force != 0) {
-
 
667
			LOCATION loc;
-
 
668
			DEREF_loc(id_loc(lab), loc);
-
 
669
			report(loc, ERR_token_stmt_jump());
628
	    }
670
		}
629
	    break ;
671
		break;
630
	}
672
	}
631
 
-
 
632
	case exp_hash_if_tag : {
-
 
633
	    /* Jump into target dependent '#if' */
-
 
634
	    if ( force != 0 ) {
-
 
635
		LOCATION loc ;
-
 
636
		DEREF_loc ( id_loc ( lab ), loc ) ;
-
 
637
		report ( loc, ERR_cpp_cond_if_jump_into () ) ;
-
 
638
	    }
-
 
639
	    break ;
-
 
640
	}
-
 
641
 
-
 
642
	case exp_token_tag : {
-
 
643
	    /* Jump into statement token */
-
 
644
	    if ( force != 0 ) {
-
 
645
		LOCATION loc ;
-
 
646
		DEREF_loc ( id_loc ( lab ), loc ) ;
-
 
647
		report ( loc, ERR_token_stmt_jump () ) ;
-
 
648
	    }
-
 
649
	    break ;
-
 
650
	}
-
 
651
    }
-
 
652
    return ( ids ) ;
673
	return (ids);
653
}
674
}
654
 
675
 
655
 
676
 
656
/*
677
/*
657
    ADD AN IDENTIFIER TO A LIST
678
    ADD AN IDENTIFIER TO A LIST
658
 
679
 
659
    This routine adds the identifier id to the start of the list p if it
680
    This routine adds the identifier id to the start of the list p if it
660
    is not already a member.
681
    is not already a member.
661
*/
682
*/
662
 
683
 
663
static LIST ( IDENTIFIER ) add_id
684
static LIST(IDENTIFIER)
664
    PROTO_N ( ( id, p ) )
-
 
665
    PROTO_T ( IDENTIFIER id X LIST ( IDENTIFIER ) p )
685
add_id(IDENTIFIER id, LIST(IDENTIFIER) p)
666
{
686
{
667
    LIST ( IDENTIFIER ) q = p ;
687
	LIST(IDENTIFIER) q = p;
668
    while ( !IS_NULL_list ( q ) ) {
688
	while (!IS_NULL_list(q)) {
669
	IDENTIFIER qid = DEREF_id ( HEAD_list ( q ) ) ;
689
		IDENTIFIER qid = DEREF_id(HEAD_list(q));
670
	if ( EQ_id ( id, qid ) ) return ( p ) ;
690
		if (EQ_id(id, qid)) {
-
 
691
			return (p);
-
 
692
		}
671
	q = TAIL_list ( q ) ;
693
		q = TAIL_list(q);
672
    }
694
	}
673
    CONS_id ( id, p, p ) ;
695
	CONS_id(id, p, p);
674
    return ( p ) ;
696
	return (p);
675
}
697
}
676
 
698
 
677
 
699
 
678
/*
700
/*
679
    EXTEND A SOLVE STATEMENT
701
    EXTEND A SOLVE STATEMENT
680
 
702
 
681
    This routine extends the solve statement a by adding the label lab
703
    This routine extends the solve statement a by adding the label lab
682
    and the variables ids.
704
    and the variables ids.
683
*/
705
*/
684
 
706
 
685
static void extend_solve_stmt
707
static void
686
    PROTO_N ( ( a, lab, ids ) )
-
 
687
    PROTO_T ( EXP a X IDENTIFIER lab X LIST ( IDENTIFIER ) ids )
708
extend_solve_stmt(EXP a, IDENTIFIER lab, LIST(IDENTIFIER) ids)
688
{
709
{
689
    LIST ( IDENTIFIER ) vars = DEREF_list ( exp_solve_stmt_vars ( a ) ) ;
710
	LIST(IDENTIFIER) vars = DEREF_list(exp_solve_stmt_vars(a));
690
    LIST ( IDENTIFIER ) labels = DEREF_list ( exp_solve_stmt_labels ( a ) ) ;
711
	LIST(IDENTIFIER) labels = DEREF_list(exp_solve_stmt_labels(a));
691
    labels = add_id ( lab, labels ) ;
712
	labels = add_id(lab, labels);
692
    while ( !IS_NULL_list ( ids ) ) {
713
	while (!IS_NULL_list(ids)) {
693
	IDENTIFIER id = DEREF_id ( HEAD_list ( ids ) ) ;
714
		IDENTIFIER id = DEREF_id(HEAD_list(ids));
694
	if ( IS_id_label ( id ) ) {
715
		if (IS_id_label(id)) {
695
	    labels = add_id ( id, labels ) ;
716
			labels = add_id(id, labels);
696
	} else {
717
		} else {
697
	    vars = add_id ( id, vars ) ;
718
			vars = add_id(id, vars);
-
 
719
		}
-
 
720
		ids = TAIL_list(ids);
698
	}
721
	}
699
	ids = TAIL_list ( ids ) ;
-
 
700
    }
-
 
701
    COPY_list ( exp_solve_stmt_labels ( a ), labels ) ;
722
	COPY_list(exp_solve_stmt_labels(a), labels);
702
    COPY_list ( exp_solve_stmt_vars ( a ), vars ) ;
723
	COPY_list(exp_solve_stmt_vars(a), vars);
703
    return ;
724
	return;
704
}
725
}
705
 
726
 
706
 
727
 
707
/*
728
/*
708
    CHECK FOR UNSTRUCTURED JUMPS
729
    CHECK FOR UNSTRUCTURED JUMPS
Line 720... Line 741...
720
    Jumps which bypass the initialisation of a variable or transfer
741
    Jumps which bypass the initialisation of a variable or transfer
721
    control into an exception handler can also be detected during this
742
    control into an exception handler can also be detected during this
722
    process.
743
    process.
723
*/
744
*/
724
 
745
 
725
EXP solve_labels
746
EXP
726
    PROTO_N ( ( e ) )
-
 
727
    PROTO_T ( EXP e )
747
solve_labels(EXP e)
728
{
748
{
729
    MEMBER mem = DEREF_member ( nspace_last ( label_namespace ) ) ;
749
    MEMBER mem = DEREF_member(nspace_last(label_namespace));
730
    while ( !IS_NULL_member ( mem ) ) {
750
    while (!IS_NULL_member(mem)) {
731
	IDENTIFIER lab = DEREF_id ( member_id ( mem ) ) ;
751
	IDENTIFIER lab = DEREF_id(member_id(mem));
732
	if ( !IS_NULL_id ( lab ) ) {
752
	if (!IS_NULL_id(lab)) {
733
	    DECL_SPEC info = DEREF_dspec ( id_storage ( lab ) ) ;
753
	    DECL_SPEC info = DEREF_dspec(id_storage(lab));
734
	    if ( info & dspec_anon ) {
754
	    if (info & dspec_anon) {
735
		/* Unnamed labels are ignored */
755
		/* Unnamed labels are ignored */
736
		/* EMPTY */
756
		/* EMPTY */
737
	    } else if ( info & dspec_defn ) {
757
	    } else if (info & dspec_defn) {
738
		/* Only check defined labels */
758
		/* Only check defined labels */
739
		int solve = 0 ;
759
		int solve = 0;
740
		EXP a = DEREF_exp ( id_label_stmt ( lab ) ) ;
760
		EXP a = DEREF_exp(id_label_stmt(lab));
741
		EXP p = DEREF_exp ( id_label_gotos ( lab ) ) ;
761
		EXP p = DEREF_exp(id_label_gotos(lab));
742
		LIST ( IDENTIFIER ) ids = NULL_list ( IDENTIFIER ) ;
762
		LIST(IDENTIFIER) ids = NULL_list(IDENTIFIER);
743
		for ( ; ; ) {
763
		for (;;) {
744
		    /* Scan for enclosing statement */
764
		    /* Scan for enclosing statement */
745
		    EXP q = p ;
765
		    EXP q = p;
746
		    int ok = 1 ;
766
		    int ok = 1;
747
		    while ( !IS_NULL_exp ( q ) && IS_exp_goto_stmt ( q ) ) {
767
		    while (!IS_NULL_exp(q) && IS_exp_goto_stmt(q)) {
748
			/* Check each goto statement */
768
			/* Check each goto statement */
749
			EXP b = q ;
769
			EXP b = q;
750
			PTR ( EXP ) pb = exp_goto_stmt_join ( b ) ;
770
			PTR(EXP) pb = exp_goto_stmt_join(b);
751
			if ( IS_NULL_exp ( DEREF_exp ( pb ) ) ) {
771
			if (IS_NULL_exp(DEREF_exp(pb))) {
752
			    /* Join statement not yet assigned */
772
			    /* Join statement not yet assigned */
753
			    for ( ; ; ) {
773
			    for (;;) {
754
				if ( EQ_exp ( a, b ) ) {
774
				if (EQ_exp(a, b)) {
755
				    /* b is a sub-statement of a */
775
				    /* b is a sub-statement of a */
756
				    COPY_exp ( pb, a ) ;
776
				    COPY_exp(pb, a);
757
				    break ;
777
				    break;
758
				}
778
				}
759
				b = get_parent_stmt ( b ) ;
779
				b = get_parent_stmt(b);
760
				if ( IS_NULL_exp ( b ) ) {
780
				if (IS_NULL_exp(b)) {
761
				    /* b is not a sub-statement of a */
781
				    /* b is not a sub-statement of a */
762
				    ok = 0 ;
782
				    ok = 0;
763
				    break ;
783
				    break;
764
				}
784
				}
765
			    }
785
			    }
766
			}
786
			}
767
			q = DEREF_exp ( exp_goto_stmt_next ( q ) ) ;
787
			q = DEREF_exp(exp_goto_stmt_next(q));
768
		    }
788
		    }
769
 
789
 
770
		    /* Check whether a encloses all the jumps to lab */
790
		    /* Check whether a encloses all the jumps to lab */
771
		    if ( ok ) {
791
		    if (ok) {
772
			int force = 1 ;
792
			int force = 1;
773
			while ( !IS_exp_solve_stmt ( a ) ) {
793
			while (!IS_exp_solve_stmt(a)) {
774
			    /* Scan to enclosing solve statement */
794
			    /* Scan to enclosing solve statement */
775
			    ids = jump_over_stmt ( ids, a, lab, force ) ;
795
			    ids = jump_over_stmt(ids, a, lab, force);
776
			    a = get_parent_stmt ( a ) ;
796
			    a = get_parent_stmt(a);
777
			    if ( IS_NULL_exp ( a ) ) break ;
797
			    if (IS_NULL_exp(a)) {
-
 
798
				    break;
-
 
799
			    }
778
			    force = 0 ;
800
			    force = 0;
779
			}
801
			}
780
			break ;
802
			break;
781
		    }
803
		    }
782
 
804
 
783
		    /* Some jump to lab is from outside a */
805
		    /* Some jump to lab is from outside a */
784
		    ids = jump_over_stmt ( ids, a, lab, 2 ) ;
806
		    ids = jump_over_stmt(ids, a, lab, 2);
785
		    solve = 1 ;
807
		    solve = 1;
786
 
808
 
787
		    /* Expand a to enclosing statement */
809
		    /* Expand a to enclosing statement */
788
		    a = get_parent_stmt ( a ) ;
810
		    a = get_parent_stmt(a);
789
		    if ( IS_NULL_exp ( a ) ) {
811
		    if (IS_NULL_exp(a)) {
790
			/* Can happen with statement tokens */
812
			/* Can happen with statement tokens */
791
			a = e ;
813
			a = e;
792
			break ;
814
			break;
793
		    }
815
		    }
794
		}
816
		}
795
 
817
 
796
		/* Deal with unstructured labels */
818
		/* Deal with unstructured labels */
797
		if ( solve ) {
819
		if (solve) {
798
		    info |= dspec_solve ;
820
		    info |= dspec_solve;
799
		    COPY_dspec ( id_storage ( lab ), info ) ;
821
		    COPY_dspec(id_storage(lab), info);
800
		    extend_solve_stmt ( a, lab, ids ) ;
822
		    extend_solve_stmt(a, lab, ids);
801
		}
823
		}
802
		DESTROY_list ( ids, SIZE_id ) ;
824
		DESTROY_list(ids, SIZE_id);
803
	    }
825
	    }
804
	}
826
	}
805
	mem = DEREF_member ( member_next ( mem ) ) ;
827
	mem = DEREF_member(member_next(mem));
806
    }
828
    }
807
    return ( e ) ;
829
    return (e);
808
}
830
}
809
 
831
 
810
 
832
 
811
/*
833
/*
812
    CHECK A JUMP TO A CASE OR DEFAULT STATEMENT
834
    CHECK A JUMP TO A CASE OR DEFAULT STATEMENT
813
 
835
 
814
    This routine checks whether the jump from the switch statement e to
836
    This routine checks whether the jump from the switch statement e to
815
    the case or default label lab bypasses the initialisation of a variable
837
    the case or default label lab bypasses the initialisation of a variable
Line 817... Line 839...
817
    checked is passed in as prev.  If e is a sub-statement of prev then
839
    checked is passed in as prev.  If e is a sub-statement of prev then
818
    there is no need to check further.  The routine returns the labelled
840
    there is no need to check further.  The routine returns the labelled
819
    statement corresponding to lab.
841
    statement corresponding to lab.
820
*/
842
*/
821
 
843
 
822
static EXP solve_case
844
static EXP
823
    PROTO_N ( ( e, lab, prev ) )
-
 
824
    PROTO_T ( EXP e X IDENTIFIER lab X EXP prev )
845
solve_case(EXP e, IDENTIFIER lab, EXP prev)
825
{
846
{
826
    DECL_SPEC info = DEREF_dspec ( id_storage ( lab ) ) ;
847
	DECL_SPEC info = DEREF_dspec(id_storage(lab));
827
    if ( info & dspec_defn ) {
848
	if (info & dspec_defn) {
828
	EXP b = DEREF_exp ( id_label_stmt ( lab ) ) ;
849
		EXP b = DEREF_exp(id_label_stmt(lab));
829
	EXP a = b ;
850
		EXP a = b;
830
	LIST ( IDENTIFIER ) ids = NULL_list ( IDENTIFIER ) ;
851
		LIST(IDENTIFIER) ids = NULL_list(IDENTIFIER);
831
	while ( !EQ_exp ( a, e ) && !EQ_exp ( a, prev ) ) {
852
		while (!EQ_exp(a, e) && !EQ_exp(a, prev)) {
832
	    ids = jump_over_stmt ( ids, a, lab, 2 ) ;
853
			ids = jump_over_stmt(ids, a, lab, 2);
833
	    a = get_parent_stmt ( a ) ;
854
			a = get_parent_stmt(a);
834
	    if ( IS_NULL_exp ( a ) ) break ;
855
			if (IS_NULL_exp(a)) {
-
 
856
				break;
-
 
857
			}
835
	}
858
		}
836
	if ( !IS_NULL_list ( ids ) ) {
859
		if (!IS_NULL_list(ids)) {
837
	    EXP s = DEREF_exp ( exp_switch_stmt_body ( e ) ) ;
860
			EXP s = DEREF_exp(exp_switch_stmt_body(e));
838
	    extend_solve_stmt ( s, lab, ids ) ;
861
			extend_solve_stmt(s, lab, ids);
839
	    DESTROY_list ( ids, SIZE_id ) ;
862
			DESTROY_list(ids, SIZE_id);
840
	}
863
		}
841
	prev = b ;
864
		prev = b;
842
    } else {
-
 
843
	/* Case not defined */
-
 
844
	EXP a, b ;
-
 
845
	LOCATION loc ;
-
 
846
	int uc = unreached_code ;
-
 
847
	IDENTIFIER flab = NULL_id ;
-
 
848
	int op = DEREF_int ( id_label_op ( lab ) ) ;
-
 
849
	DEREF_loc ( id_loc ( lab ), loc ) ;
-
 
850
	if ( op == lex_case ) {
-
 
851
	    NAT n = find_case_nat ( lab ) ;
-
 
852
	    report ( loc, ERR_stmt_switch_case_not ( n ) ) ;
-
 
853
	    flab = DEREF_id ( exp_switch_stmt_default_lab ( e ) ) ;
-
 
854
	} else {
865
	} else {
-
 
866
		/* Case not defined */
-
 
867
		EXP a, b;
-
 
868
		LOCATION loc;
-
 
869
		int uc = unreached_code;
-
 
870
		IDENTIFIER flab = NULL_id;
-
 
871
		int op = DEREF_int(id_label_op(lab));
-
 
872
		DEREF_loc(id_loc(lab), loc);
-
 
873
		if (op == lex_case) {
-
 
874
			NAT n = find_case_nat(lab);
-
 
875
			report(loc, ERR_stmt_switch_case_not(n));
-
 
876
			flab = DEREF_id(exp_switch_stmt_default_lab(e));
-
 
877
		} else {
855
	    report ( loc, ERR_stmt_switch_default_not () ) ;
878
			report(loc, ERR_stmt_switch_default_not());
-
 
879
		}
-
 
880
		if (IS_NULL_id(flab)) {
-
 
881
			flab = DEREF_id(exp_switch_stmt_break_lab(e));
-
 
882
		}
-
 
883
		a = begin_label_stmt(lab, op);
-
 
884
		b = make_jump_stmt(flab, e);
-
 
885
		IGNORE end_label_stmt(a, b);
-
 
886
		unreached_code = uc;
856
	}
887
	}
857
	if ( IS_NULL_id ( flab ) ) {
-
 
858
	    flab = DEREF_id ( exp_switch_stmt_break_lab ( e ) ) ;
-
 
859
	}
-
 
860
	a = begin_label_stmt ( lab, op ) ;
-
 
861
	b = make_jump_stmt ( flab, e ) ;
-
 
862
	IGNORE end_label_stmt ( a, b ) ;
-
 
863
	unreached_code = uc ;
-
 
864
    }
-
 
865
    return ( prev ) ;
888
	return (prev);
866
}
889
}
867
 
890
 
868
 
891
 
869
/*
892
/*
870
    CHECK A SWITCH STATEMENT
893
    CHECK A SWITCH STATEMENT
871
 
894
 
872
    This routine scans through the switch statement e for jumps which
895
    This routine scans through the switch statement e for jumps which
873
    bypass the initialisation of a variable.
896
    bypass the initialisation of a variable.
874
*/
897
*/
875
 
898
 
876
EXP solve_switch
899
EXP
877
    PROTO_N ( ( e ) )
-
 
878
    PROTO_T ( EXP e )
900
solve_switch(EXP e)
879
{
901
{
880
    IDENTIFIER lab ;
902
	IDENTIFIER lab;
881
    EXP prev = NULL_exp ;
903
	EXP prev = NULL_exp;
882
    LIST ( IDENTIFIER ) cases ;
904
	LIST(IDENTIFIER) cases;
883
    cases = DEREF_list ( exp_switch_stmt_case_labs ( e ) ) ;
905
	cases = DEREF_list(exp_switch_stmt_case_labs(e));
884
    while ( !IS_NULL_list ( cases ) ) {
906
	while (!IS_NULL_list(cases)) {
885
	/* Check each case statement */
907
		/* Check each case statement */
886
	lab = DEREF_id ( HEAD_list ( cases ) ) ;
908
		lab = DEREF_id(HEAD_list(cases));
887
	prev = solve_case ( e, lab, prev ) ;
909
		prev = solve_case(e, lab, prev);
888
	cases = TAIL_list ( cases ) ;
910
		cases = TAIL_list(cases);
889
    }
911
	}
890
    lab = DEREF_id ( exp_switch_stmt_default_lab ( e ) ) ;
912
	lab = DEREF_id(exp_switch_stmt_default_lab(e));
891
    if ( !IS_NULL_id ( lab ) ) {
913
	if (!IS_NULL_id(lab)) {
892
	/* Check any default statement */
914
		/* Check any default statement */
893
	IGNORE solve_case ( e, lab, prev ) ;
915
		IGNORE solve_case(e, lab, prev);
894
    }
916
	}
895
    return ( e ) ;
917
	return (e);
896
}
918
}
897
 
919
 
898
 
920
 
899
/*
921
/*
900
    CONSTRUCT A LABEL FOR THE FOLLOWING STATEMENT
922
    CONSTRUCT A LABEL FOR THE FOLLOWING STATEMENT
901
 
923
 
902
    This routine turns the list of statements following the position p
924
    This routine turns the list of statements following the position p
903
    in the block statement e into a labelled statement, returning the
925
    in the block statement e into a labelled statement, returning the
904
    label created.  If p is the last statement in the block then the
926
    label created.  If p is the last statement in the block then the
905
    null identifier is returned.
927
    null identifier is returned.
906
*/
928
*/
907
 
929
 
908
static IDENTIFIER follow_label
930
static IDENTIFIER
909
    PROTO_N ( ( e, p ) )
-
 
910
    PROTO_T ( EXP e X LIST ( EXP ) p )
931
follow_label(EXP e, LIST(EXP) p)
911
{
932
{
912
    EXP a, b, c ;
933
	EXP a, b, c;
913
    DECL_SPEC ds ;
934
	DECL_SPEC ds;
914
    IDENTIFIER lab ;
935
	IDENTIFIER lab;
915
    LIST ( EXP ) r ;
936
	LIST(EXP) r;
916
    LIST ( EXP ) q = TAIL_list ( p ) ;
937
	LIST(EXP) q = TAIL_list(p);
917
    if ( IS_NULL_list ( q ) ) return ( NULL_id ) ;
938
	if (IS_NULL_list(q)) {
-
 
939
		return (NULL_id);
-
 
940
	}
918
 
941
 
919
    /* Examine following statement */
942
	/* Examine following statement */
920
    a = DEREF_exp ( HEAD_list ( q ) ) ;
943
	a = DEREF_exp(HEAD_list(q));
921
    if ( !IS_NULL_exp ( a ) ) {
944
	if (!IS_NULL_exp(a)) {
922
	unsigned tag = TAG_exp ( a ) ;
945
		unsigned tag = TAG_exp(a);
923
	if ( tag == exp_location_tag ) {
946
		if (tag == exp_location_tag) {
924
	    a = DEREF_exp ( exp_location_arg ( a ) ) ;
947
			a = DEREF_exp(exp_location_arg(a));
925
	    if ( !IS_NULL_exp ( a ) ) tag = TAG_exp ( a ) ;
948
			if (!IS_NULL_exp(a)) {
-
 
949
				tag = TAG_exp(a);
-
 
950
			}
926
	    if ( tag == exp_label_stmt_tag ) {
951
			if (tag == exp_label_stmt_tag) {
927
		/* Statement is already labelled */
952
				/* Statement is already labelled */
928
		lab = DEREF_id ( exp_label_stmt_label ( a ) ) ;
953
				lab = DEREF_id(exp_label_stmt_label(a));
929
		return ( lab ) ;
954
				return (lab);
930
	    }
955
			}
-
 
956
		}
-
 
957
	}
-
 
958
 
-
 
959
	/* Create new labelled statement */
-
 
960
	b = begin_label_stmt(NULL_id, lex_end);
-
 
961
	b = end_label_stmt(b, NULL_exp);
-
 
962
	set_parent_stmt(b, e);
-
 
963
	c = DEREF_exp(exp_label_stmt_body(b));
-
 
964
	r = DEREF_list(exp_sequence_first(c));
-
 
965
	IGNORE APPEND_list(r, q);
-
 
966
	while (!IS_NULL_list(q)) {
-
 
967
		a = DEREF_exp(HEAD_list(q));
-
 
968
		set_parent_stmt(a, b);
-
 
969
		q = TAIL_list(q);
931
	}
970
	}
932
    }
-
 
933
 
-
 
934
    /* Create new labelled statement */
-
 
935
    b = begin_label_stmt ( NULL_id, lex_end ) ;
-
 
936
    b = end_label_stmt ( b, NULL_exp ) ;
-
 
937
    set_parent_stmt ( b, e ) ;
-
 
938
    c = DEREF_exp ( exp_label_stmt_body ( b ) ) ;
-
 
939
    r = DEREF_list ( exp_sequence_first ( c ) ) ;
-
 
940
    IGNORE APPEND_list ( r, q ) ;
-
 
941
    while ( !IS_NULL_list ( q ) ) {
-
 
942
	a = DEREF_exp ( HEAD_list ( q ) ) ;
-
 
943
	set_parent_stmt ( a, b ) ;
-
 
944
	q = TAIL_list ( q ) ;
-
 
945
    }
-
 
946
    COPY_list ( PTR_TAIL_list ( p ), NULL_list ( EXP ) ) ;
971
	COPY_list(PTR_TAIL_list(p), NULL_list(EXP));
947
    CONS_exp ( b, NULL_list ( EXP ), q ) ;
972
	CONS_exp(b, NULL_list(EXP), q);
948
    IGNORE APPEND_list ( p, q ) ;
973
	IGNORE APPEND_list(p, q);
949
    lab = DEREF_id ( exp_label_stmt_label ( b ) ) ;
974
	lab = DEREF_id(exp_label_stmt_label(b));
950
    ds = DEREF_dspec ( id_storage ( lab ) ) ;
975
	ds = DEREF_dspec(id_storage(lab));
951
    ds |= ( dspec_goto | dspec_used ) ;
976
	ds |= (dspec_goto | dspec_used);
952
    COPY_dspec ( id_storage ( lab ), ds ) ;
977
	COPY_dspec(id_storage(lab), ds);
953
    return ( lab ) ;
978
	return (lab);
954
}
979
}
955
 
980
 
956
 
981
 
957
/*
982
/*
958
    FIND THE END OF A BRANCH OF A SOLVE STATEMENT
983
    FIND THE END OF A BRANCH OF A SOLVE STATEMENT
959
 
984
 
960
    This routine finds the end of the branch of the solve statement e
985
    This routine finds the end of the branch of the solve statement e
961
    given by the label lab.  This is a label which gives any immediately
986
    given by the label lab.  This is a label which gives any immediately
962
    following code.
987
    following code.
963
*/
988
*/
964
 
989
 
965
static IDENTIFIER end_solve_branch
990
static IDENTIFIER
966
    PROTO_N ( ( lab, e ) )
-
 
967
    PROTO_T ( IDENTIFIER lab X EXP e )
991
end_solve_branch(IDENTIFIER lab, EXP e)
968
{
992
{
969
    EXP a ;
993
    EXP a;
970
    IDENTIFIER nlab ;
994
    IDENTIFIER nlab;
971
    int op = DEREF_int ( id_label_op ( lab ) ) ;
995
    int op = DEREF_int(id_label_op(lab));
972
    switch ( op ) {
996
    switch (op) {
973
	case lex_continue :
997
	case lex_continue:
974
	case lex_while :
998
	case lex_while:
975
	case lex_for :
999
	case lex_for:
976
	case lex_do : {
1000
	case lex_do:
977
	    /* Don't bother in these cases */
1001
	    /* Don't bother in these cases */
978
	    return ( NULL_id ) ;
1002
	    return (NULL_id);
979
	}
-
 
980
    }
1003
    }
981
    a = DEREF_exp ( id_label_stmt ( lab ) ) ;
1004
    a = DEREF_exp(id_label_stmt(lab));
982
    if ( IS_NULL_exp ( a ) ) {
1005
    if (IS_NULL_exp(a)) {
983
	/* Ignore undefined labels */
1006
	/* Ignore undefined labels */
984
	return ( NULL_id ) ;
1007
	return (NULL_id);
985
    }
1008
    }
986
    nlab = DEREF_id ( exp_label_stmt_next ( a ) ) ;
1009
    nlab = DEREF_id(exp_label_stmt_next(a));
987
    if ( IS_NULL_id ( nlab ) ) {
1010
    if (IS_NULL_id(nlab)) {
988
	/* Scan up to enclosing block */
1011
	/* Scan up to enclosing block */
989
	EXP b = a ;
1012
	EXP b = a;
990
	EXP c = DEREF_exp ( exp_label_stmt_parent ( b ) ) ;
1013
	EXP c = DEREF_exp(exp_label_stmt_parent(b));
991
	while ( !EQ_exp ( c, e ) && !IS_NULL_exp ( c ) ) {
1014
	while (!EQ_exp(c, e) && !IS_NULL_exp(c)) {
992
	    int again ;
1015
	    int again;
993
	    EXP d = c ;
1016
	    EXP d = c;
994
	    do {
1017
	    do {
995
		again = 0 ;
1018
		again = 0;
996
		switch ( TAG_exp ( d ) ) {
1019
		switch (TAG_exp(d)) {
997
		    case exp_sequence_tag : {
1020
		    case exp_sequence_tag: {
998
			/* Found enclosing block */
1021
			/* Found enclosing block */
999
			LIST ( EXP ) q ;
1022
			LIST(EXP) q;
1000
			q = DEREF_list ( exp_sequence_first ( d ) ) ;
1023
			q = DEREF_list(exp_sequence_first(d));
1001
			q = TAIL_list ( q ) ;
1024
			q = TAIL_list(q);
1002
			while ( !IS_NULL_list ( q ) ) {
1025
			while (!IS_NULL_list(q)) {
1003
			    EXP f = DEREF_exp ( HEAD_list ( q ) ) ;
1026
			    EXP f = DEREF_exp(HEAD_list(q));
1004
			    if ( !IS_NULL_exp ( f ) ) {
1027
			    if (!IS_NULL_exp(f)) {
1005
				if ( IS_exp_location ( f ) ) {
1028
				if (IS_exp_location(f)) {
1006
				    /* Allow for location statements */
1029
				    /* Allow for location statements */
1007
				    f = DEREF_exp ( exp_location_arg ( f ) ) ;
1030
				    f = DEREF_exp(exp_location_arg(f));
1008
				}
1031
				}
1009
				if ( EQ_exp ( f, b ) ) {
1032
				if (EQ_exp(f, b)) {
1010
				    /* Found labelled statement in block */
1033
				    /* Found labelled statement in block */
1011
				    nlab = follow_label ( d, q ) ;
1034
				    nlab = follow_label(d, q);
1012
				    break ;
1035
				    break;
1013
				}
1036
				}
1014
			    }
1037
			    }
1015
			    q = TAIL_list ( q ) ;
1038
			    q = TAIL_list(q);
1016
			}
1039
			}
1017
			break ;
1040
			break;
1018
		    }
1041
		    }
1019
		    case exp_while_stmt_tag : {
1042
		    case exp_while_stmt_tag: {
1020
			/* Found enclosing while statement */
1043
			/* Found enclosing while statement */
1021
			IDENTIFIER blab ;
1044
			IDENTIFIER blab;
1022
			blab = DEREF_id ( exp_while_stmt_break_lab ( d ) ) ;
1045
			blab = DEREF_id(exp_while_stmt_break_lab(d));
1023
			if ( !EQ_id ( blab, lab ) ) {
1046
			if (!EQ_id(blab, lab)) {
1024
			    nlab = DEREF_id ( exp_while_stmt_cont_lab ( d ) ) ;
1047
			    nlab = DEREF_id(exp_while_stmt_cont_lab(d));
1025
			}
1048
			}
1026
			break ;
1049
			break;
1027
		    }
1050
		    }
1028
		    case exp_do_stmt_tag : {
1051
		    case exp_do_stmt_tag: {
1029
			/* Found enclosing do statement */
1052
			/* Found enclosing do statement */
1030
			IDENTIFIER blab ;
1053
			IDENTIFIER blab;
1031
			blab = DEREF_id ( exp_do_stmt_break_lab ( d ) ) ;
1054
			blab = DEREF_id(exp_do_stmt_break_lab(d));
1032
			if ( !EQ_id ( blab, lab ) ) {
1055
			if (!EQ_id(blab, lab)) {
1033
			    nlab = DEREF_id ( exp_do_stmt_cont_lab ( d ) ) ;
1056
			    nlab = DEREF_id(exp_do_stmt_cont_lab(d));
1034
			}
1057
			}
1035
			break ;
1058
			break;
1036
		    }
1059
		    }
1037
		    case exp_switch_stmt_tag : {
1060
		    case exp_switch_stmt_tag:
1038
			/* Found enclosing switch statement */
1061
			/* Found enclosing switch statement */
1039
			nlab = DEREF_id ( exp_switch_stmt_break_lab ( d ) ) ;
1062
			nlab = DEREF_id(exp_switch_stmt_break_lab(d));
1040
			if ( EQ_id ( nlab, lab ) ) nlab = NULL_id ;
1063
			if (EQ_id(nlab, lab))nlab = NULL_id;
1041
			break ;
1064
			break;
1042
		    }
-
 
1043
		    case exp_decl_stmt_tag : {
1065
		    case exp_decl_stmt_tag:
1044
			/* Found enclosing declaration */
1066
			/* Found enclosing declaration */
1045
			d = DEREF_exp ( exp_decl_stmt_body ( d ) ) ;
1067
			d = DEREF_exp(exp_decl_stmt_body(d));
1046
			if ( !EQ_exp ( d, b ) ) again = 1 ;
1068
			if (!EQ_exp(d, b))again = 1;
1047
			break ;
1069
			break;
1048
		    }
-
 
1049
		    case exp_label_stmt_tag : {
1070
		    case exp_label_stmt_tag:
1050
			/* Found enclosing label statement */
1071
			/* Found enclosing label statement */
1051
			d = DEREF_exp ( exp_label_stmt_body ( d ) ) ;
1072
			d = DEREF_exp(exp_label_stmt_body(d));
1052
			if ( !EQ_exp ( d, b ) ) again = 1 ;
1073
			if (!EQ_exp(d, b))again = 1;
1053
			break ;
1074
			break;
1054
		    }
-
 
1055
		}
1075
		}
1056
	    } while ( again ) ;
1076
	    } while (again);
1057
	    if ( !IS_NULL_id ( nlab ) ) {
1077
	    if (!IS_NULL_id(nlab)) {
1058
		/* Label for next statement found */
1078
		/* Label for next statement found */
1059
		nlab = DEREF_id ( id_alias ( nlab ) ) ;
1079
		nlab = DEREF_id(id_alias(nlab));
1060
		if ( op == lex_break ) {
1080
		if (op == lex_break) {
1061
		    /* Alias break labels */
1081
		    /* Alias break labels */
1062
		    COPY_id ( id_alias ( lab ), nlab ) ;
1082
		    COPY_id(id_alias(lab), nlab);
1063
		}
1083
		}
1064
		break ;
1084
		break;
1065
	    }
1085
	    }
1066
	    b = c ;
1086
	    b = c;
1067
	    c = get_parent_stmt ( b ) ;
1087
	    c = get_parent_stmt(b);
1068
	}
1088
	}
1069
    }
1089
    }
1070
    COPY_id ( exp_label_stmt_next ( a ), nlab ) ;
1090
    COPY_id(exp_label_stmt_next(a), nlab);
1071
    return ( nlab ) ;
1091
    return (nlab);
1072
}
1092
}
1073
 
1093
 
1074
 
1094
 
1075
/*
1095
/*
1076
    END ALL SOLVE STATEMENTS
1096
    END ALL SOLVE STATEMENTS
1077
 
1097
 
1078
    This routine calls end_solve_branch for all the branches of all the
1098
    This routine calls end_solve_branch for all the branches of all the
1079
    solve statements in the current function.
1099
    solve statements in the current function.
1080
*/
1100
*/
1081
 
1101
 
1082
void end_solve_stmts
1102
void
1083
    PROTO_Z ()
1103
end_solve_stmts(void)
1084
{
1104
{
1085
    LIST ( EXP ) p = all_solve_stmts ;
1105
    LIST(EXP) p = all_solve_stmts;
1086
    if ( !IS_NULL_list ( p ) ) {
1106
    if (!IS_NULL_list(p)) {
1087
	while ( !IS_NULL_list ( p ) ) {
1107
	while (!IS_NULL_list(p)) {
1088
	    int changed ;
1108
	    int changed;
1089
	    LIST ( IDENTIFIER ) q0 ;
1109
	    LIST(IDENTIFIER) q0;
1090
	    EXP e = DEREF_exp ( HEAD_list ( p ) ) ;
1110
	    EXP e = DEREF_exp(HEAD_list(p));
1091
	    q0 = DEREF_list ( exp_solve_stmt_labels ( e ) ) ;
1111
	    q0 = DEREF_list(exp_solve_stmt_labels(e));
1092
	    do {
1112
	    do {
1093
		LIST ( IDENTIFIER ) q = q0 ;
1113
		LIST(IDENTIFIER) q = q0;
1094
		changed = 0 ;
1114
		changed = 0;
1095
		while ( !IS_NULL_list ( q ) ) {
1115
		while (!IS_NULL_list(q)) {
1096
		    IDENTIFIER lab = DEREF_id ( HEAD_list ( q ) ) ;
1116
		    IDENTIFIER lab = DEREF_id(HEAD_list(q));
1097
		    IDENTIFIER nlab = end_solve_branch ( lab, e ) ;
1117
		    IDENTIFIER nlab = end_solve_branch(lab, e);
1098
		    if ( !IS_NULL_id ( nlab ) ) {
1118
		    if (!IS_NULL_id(nlab)) {
1099
			/* Add new label to list */
1119
			/* Add new label to list */
1100
			LIST ( IDENTIFIER ) q1 = add_id ( nlab, q0 ) ;
1120
			LIST(IDENTIFIER) q1 = add_id(nlab, q0);
1101
			if ( !EQ_list ( q1, q0 ) ) {
1121
			if (!EQ_list(q1, q0)) {
1102
			    q0 = q1 ;
1122
			    q0 = q1;
1103
			    changed = 1 ;
1123
			    changed = 1;
1104
			}
1124
			}
1105
		    }
1125
		    }
1106
		    q = TAIL_list ( q ) ;
1126
		    q = TAIL_list(q);
1107
		}
1127
		}
1108
	    } while ( changed ) ;
1128
	    } while (changed);
1109
	    COPY_list ( exp_solve_stmt_labels ( e ), q0 ) ;
1129
	    COPY_list(exp_solve_stmt_labels(e), q0);
1110
	    p = TAIL_list ( p ) ;
1130
	    p = TAIL_list(p);
1111
	}
1131
	}
1112
	DESTROY_list ( all_solve_stmts, SIZE_exp ) ;
1132
	DESTROY_list(all_solve_stmts, SIZE_exp);
1113
	all_solve_stmts = NULL_list ( EXP ) ;
1133
	all_solve_stmts = NULL_list(EXP);
1114
    }
1134
    }
1115
    return ;
1135
    return;
1116
}
1136
}