Subversion Repositories tendra.SVN

Rev

Rev 5 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 7u83 1
/*
6 7u83 2
 * Copyright (c) 2002-2006 The TenDRA Project <http://www.tendra.org/>.
3
 * All rights reserved.
4
 *
5
 * Redistribution and use in source and binary forms, with or without
6
 * modification, are permitted provided that the following conditions are met:
7
 *
8
 * 1. Redistributions of source code must retain the above copyright notice,
9
 *    this list of conditions and the following disclaimer.
10
 * 2. Redistributions in binary form must reproduce the above copyright notice,
11
 *    this list of conditions and the following disclaimer in the documentation
12
 *    and/or other materials provided with the distribution.
13
 * 3. Neither the name of The TenDRA Project nor the names of its contributors
14
 *    may be used to endorse or promote products derived from this software
15
 *    without specific, prior written permission.
16
 *
17
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS
18
 * IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
19
 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
20
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR
21
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
22
 * EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
23
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
24
 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
25
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
26
 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
27
 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28
 *
29
 * $Id$
30
 */
31
/*
2 7u83 32
    		 Crown Copyright (c) 1997
6 7u83 33
 
2 7u83 34
    This TenDRA(r) Computer Program is subject to Copyright
35
    owned by the United Kingdom Secretary of State for Defence
36
    acting through the Defence Evaluation and Research Agency
37
    (DERA).  It is made available to Recipients with a
38
    royalty-free licence for its use, reproduction, transfer
39
    to other parties and amendment for any purpose not excluding
40
    product development provided that any such use et cetera
41
    shall be deemed to be acceptance of the following conditions:-
6 7u83 42
 
2 7u83 43
        (1) Its Recipients shall ensure that this Notice is
44
        reproduced upon any copies or amended versions of it;
6 7u83 45
 
2 7u83 46
        (2) Any amended version of it shall be clearly marked to
47
        show both the nature of and the organisation responsible
48
        for the relevant amendment or amendments;
6 7u83 49
 
2 7u83 50
        (3) Its onward transfer from a recipient to another
51
        party shall be deemed to be that party's acceptance of
52
        these conditions;
6 7u83 53
 
2 7u83 54
        (4) DERA gives no warranty or assurance as to its
55
        quality or suitability for any purpose and DERA accepts
56
        no liability whatsoever in relation to any use to which
57
        it may be put.
58
*/
59
 
60
 
61
#include "config.h"
62
#include "c_types.h"
63
#include "exp_ops.h"
64
#include "graph_ops.h"
65
#include "hashid_ops.h"
66
#include "id_ops.h"
67
#include "nat_ops.h"
68
#include "nspace_ops.h"
69
#include "off_ops.h"
70
#include "tok_ops.h"
71
#include "type_ops.h"
72
#include "error.h"
73
#include "catalog.h"
74
#include "option.h"
75
#include "basetype.h"
76
#include "check.h"
77
#include "chktype.h"
78
#include "constant.h"
79
#include "convert.h"
80
#include "derive.h"
81
#include "function.h"
82
#include "hash.h"
83
#include "literal.h"
84
#include "merge.h"
85
#include "namespace.h"
86
#include "syntax.h"
87
#include "tokdef.h"
88
 
89
 
90
/*
91
    ARE TWO OFFSETS EQUAL?
92
 
93
    This routine checks whether the offsets a and b are equal.  The co
94
    argument is passed through to eq_exp.
95
*/
96
 
6 7u83 97
int
98
eq_offset(OFFSET a, OFFSET b, int co)
2 7u83 99
{
6 7u83 100
	unsigned taga, tagb;
2 7u83 101
 
6 7u83 102
	/* Check for obvious equality */
103
	if (EQ_off(a, b)) {
104
		return (1);
105
	}
106
	if (IS_NULL_off(a)) {
107
		return (0);
108
	}
109
	if (IS_NULL_off(b)) {
110
		return (0);
111
	}
2 7u83 112
 
6 7u83 113
	/* Check tags */
114
	taga = TAG_off(a);
115
	tagb = TAG_off(b);
116
	if (taga != tagb) {
117
		return (0);
118
	}
2 7u83 119
 
6 7u83 120
	/* Check individual cases */
121
	ASSERT(ORDER_off == 13);
122
	switch (TAG_off(a)) {
123
	case off_zero_tag: {
124
		/* Zero offsets */
125
		TYPE ta = DEREF_type(off_zero_type(a));
126
		TYPE tb = DEREF_type(off_zero_type(b));
127
		return (eq_type_offset(ta, tb));
2 7u83 128
	}
6 7u83 129
	case off_type_tag: {
130
		/* Type offsets */
131
		TYPE ta = DEREF_type(off_type_type(a));
132
		TYPE tb = DEREF_type(off_type_type(b));
133
		return (eq_type_offset(ta, tb));
2 7u83 134
	}
6 7u83 135
	case off_extra_tag: {
136
		/* Extra allocator offsets */
137
		TYPE ta = DEREF_type(off_extra_type(a));
138
		TYPE tb = DEREF_type(off_extra_type(b));
139
		int na = DEREF_int(off_extra_scale(a));
140
		int nb = DEREF_int(off_extra_scale(b));
141
		return (na == nb && eq_type_offset(ta, tb));
2 7u83 142
	}
6 7u83 143
	case off_array_tag: {
144
		/* Array offsets */
145
		TYPE ta = DEREF_type(off_array_type(a));
146
		TYPE tb = DEREF_type(off_array_type(b));
147
		unsigned na = DEREF_unsigned(off_array_arg(a));
148
		unsigned nb = DEREF_unsigned(off_array_arg(b));
149
		return (na == nb && eq_type_offset(ta, tb));
2 7u83 150
	}
6 7u83 151
	case off_base_tag: {
152
		/* Base class offsets */
153
		GRAPH ga = DEREF_graph(off_base_graph(a));
154
		GRAPH gb = DEREF_graph(off_base_graph(b));
155
		return (eq_graph(ga, gb));
2 7u83 156
	}
6 7u83 157
	case off_deriv_tag: {
158
		/* Derived class offsets */
159
		GRAPH ga = DEREF_graph(off_deriv_graph(a));
160
		GRAPH gb = DEREF_graph(off_deriv_graph(b));
161
		return (eq_graph(ga, gb));
2 7u83 162
	}
6 7u83 163
	case off_member_tag: {
164
		/* Member offsets */
165
		IDENTIFIER ia = DEREF_id(off_member_id(a));
166
		IDENTIFIER ib = DEREF_id(off_member_id(b));
167
		return (EQ_id(ia, ib));
2 7u83 168
	}
6 7u83 169
	case off_ptr_mem_tag: {
170
		/* Pointer member offsets */
171
		EXP xa = DEREF_exp(off_ptr_mem_arg(a));
172
		EXP xb = DEREF_exp(off_ptr_mem_arg(b));
173
		return (eq_exp(xa, xb, co));
2 7u83 174
	}
6 7u83 175
	case off_negate_tag: {
176
		/* Offset negation */
177
		OFFSET sa = DEREF_off(off_negate_arg(a));
178
		OFFSET sb = DEREF_off(off_negate_arg(b));
179
		return (eq_offset(sa, sb, co));
2 7u83 180
	}
6 7u83 181
	case off_plus_tag: {
182
		/* Offset addition */
183
		OFFSET sa = DEREF_off(off_plus_arg1(a));
184
		OFFSET sb = DEREF_off(off_plus_arg1(b));
185
		OFFSET ta = DEREF_off(off_plus_arg2(a));
186
		OFFSET tb = DEREF_off(off_plus_arg2(b));
187
		if (eq_offset(sa, sb, co) && eq_offset(ta, tb, co)) {
188
			return (1);
189
		}
190
		if (co && eq_offset(sa, tb, 1) && eq_offset(ta, sb, 1)) {
191
			return (1);
192
		}
193
		return (0);
2 7u83 194
	}
6 7u83 195
	case off_mult_tag: {
196
		/* Offset multiplication */
197
		OFFSET sa = DEREF_off(off_mult_arg1(a));
198
		OFFSET sb = DEREF_off(off_mult_arg1(b));
199
		EXP za = DEREF_exp(off_mult_arg2(a));
200
		EXP zb = DEREF_exp(off_mult_arg2(b));
201
		return (eq_offset(sa, sb, co) && eq_exp(za, zb, co));
2 7u83 202
	}
6 7u83 203
	case off_ptr_diff_tag: {
204
		/* Pointer difference */
205
		EXP xa = DEREF_exp(off_ptr_diff_ptr1(a));
206
		EXP xb = DEREF_exp(off_ptr_diff_ptr1(b));
207
		EXP za = DEREF_exp(off_ptr_diff_ptr2(a));
208
		EXP zb = DEREF_exp(off_ptr_diff_ptr2(b));
209
		return (eq_exp(xa, xb, co) && eq_exp(za, zb, co));
2 7u83 210
	}
6 7u83 211
	case off_token_tag: {
212
		/* Token application */
213
		IDENTIFIER ia = DEREF_id(off_token_tok(a));
214
		IDENTIFIER ib = DEREF_id(off_token_tok(b));
215
		LIST(TOKEN)pa = DEREF_list(off_token_args(a));
216
		LIST(TOKEN)pb = DEREF_list(off_token_args(b));
217
		return (eq_token_args(ia, ib, pa, pb));
2 7u83 218
	}
6 7u83 219
	}
220
	return (0);
2 7u83 221
}
222
 
223
 
224
/*
225
    ARE TWO LISTS OF EXPRESSIONS EQUAL?
226
 
227
    This routine checks whether the expression lists p and q are equal,
228
    in the sense that each of their components is equal.  The co argument
229
    is passed through to eq_exp.
230
*/
231
 
6 7u83 232
static int
233
eq_exp_list(LIST(EXP)p, LIST(EXP)q, int co)
2 7u83 234
{
6 7u83 235
	unsigned np = LENGTH_list(p);
236
	unsigned nq = LENGTH_list(q);
237
	if (np != nq) {
238
		return (0);
239
	}
240
	while (!IS_NULL_list(p)) {
241
		EXP a = DEREF_exp(HEAD_list(p));
242
		EXP b = DEREF_exp(HEAD_list(q));
243
		if (!eq_exp(a, b, co)) {
244
			return (0);
245
		}
246
		p = TAIL_list(p);
247
		q = TAIL_list(q);
248
	}
249
	return (1);
2 7u83 250
}
251
 
252
 
253
/*
254
    CHECK EXPRESSION EQUALITY
255
 
256
    This is an auxiliary routine for eq_exp which checks whether the
257
    expressions a and b, which have the same tag value, are equal.
258
*/
259
 
6 7u83 260
static int
261
eq_exp_aux(EXP a, EXP b, int co)
2 7u83 262
{
6 7u83 263
	/* Check expressions */
264
	ASSERT(ORDER_exp == 88);
265
	switch (TAG_exp(a)) {
266
	case exp_identifier_tag:
267
	case exp_member_tag:
268
	case exp_ambiguous_tag:
269
	case exp_undeclared_tag: {
270
		/* Identifier expressions */
271
		IDENTIFIER ia = DEREF_id(exp_identifier_etc_id(a));
272
		IDENTIFIER ib = DEREF_id(exp_identifier_etc_id(b));
273
		return (EQ_id(ia, ib));
2 7u83 274
	}
6 7u83 275
	case exp_int_lit_tag: {
276
		/* Integer literal expressions */
277
		TYPE ta = DEREF_type(exp_type(a));
278
		TYPE tb = DEREF_type(exp_type(b));
279
		NAT na = DEREF_nat(exp_int_lit_nat(a));
280
		NAT nb = DEREF_nat(exp_int_lit_nat(b));
281
		if (!eq_type(ta, tb)) {
282
			return (0);
283
		}
284
		if (EQ_nat(na, nb) || eq_nat(na, nb)) {
285
			return (1);
286
		}
287
		return (0);
2 7u83 288
	}
6 7u83 289
	case exp_float_lit_tag: {
290
		/* Floating literal expressions */
291
		TYPE ta = DEREF_type(exp_type(a));
292
		TYPE tb = DEREF_type(exp_type(b));
293
		FLOAT fa = DEREF_flt(exp_float_lit_flt(a));
294
		FLOAT fb = DEREF_flt(exp_float_lit_flt(b));
295
		if (!eq_type(ta, tb)) {
296
			return (0);
297
		}
298
		if (EQ_flt(fa, fb)) {
299
			return (1);
300
		}
301
		return (eq_float_lit(fa, fb));
2 7u83 302
	}
6 7u83 303
	case exp_char_lit_tag: {
304
		/* Character literal expressions */
305
		TYPE ta = DEREF_type(exp_type(a));
306
		TYPE tb = DEREF_type(exp_type(b));
307
		STRING ca = DEREF_str(exp_char_lit_str(a));
308
		STRING cb = DEREF_str(exp_char_lit_str(b));
309
		if (!eq_type(ta, tb)) {
310
			return (0);
311
		}
312
		if (EQ_str(ca, cb)) {
313
			return (1);
314
		}
315
		return (eq_string_lit(ca, cb));
2 7u83 316
	}
6 7u83 317
	case exp_string_lit_tag: {
318
		/* String literal expressions */
319
		TYPE ta = DEREF_type(exp_type(a));
320
		TYPE tb = DEREF_type(exp_type(b));
321
		STRING ca = DEREF_str(exp_string_lit_str(a));
322
		STRING cb = DEREF_str(exp_string_lit_str(b));
323
		if (!eq_type(ta, tb)) {
324
			return (0);
325
		}
326
		if (EQ_str(ca, cb)) {
327
			return (1);
328
		}
329
		return (eq_string_lit(ca, cb));
2 7u83 330
	}
6 7u83 331
	case exp_null_tag:
332
	case exp_zero_tag:
333
	case exp_value_tag: {
334
		/* Null expressions */
335
		TYPE ta = DEREF_type(exp_type(a));
336
		TYPE tb = DEREF_type(exp_type(b));
337
		if (eq_type(ta, tb) == 1) {
338
			return (1);
339
		}
340
		return (0);
2 7u83 341
	}
6 7u83 342
	case exp_paren_tag:
343
	case exp_copy_tag: {
344
		/* Parenthesised expressions */
345
		EXP sa = DEREF_exp(exp_paren_etc_arg(a));
346
		EXP sb = DEREF_exp(exp_paren_etc_arg(b));
347
		return (eq_exp(sa, sb, co));
2 7u83 348
	}
6 7u83 349
	case exp_assign_tag: {
350
		/* Assignment expressions */
351
		EXP ra = DEREF_exp(exp_assign_ref(a));
352
		EXP rb = DEREF_exp(exp_assign_ref(b));
353
		EXP sa = DEREF_exp(exp_assign_arg(a));
354
		EXP sb = DEREF_exp(exp_assign_arg(b));
355
		return (eq_exp(ra, rb, co) && eq_exp(sa, sb, co));
2 7u83 356
	}
6 7u83 357
	case exp_init_tag: {
358
		/* Initialisation expressions */
359
		IDENTIFIER ia = DEREF_id(exp_init_id(a));
360
		IDENTIFIER ib = DEREF_id(exp_init_id(b));
361
		EXP sa = DEREF_exp(exp_init_arg(a));
362
		EXP sb = DEREF_exp(exp_init_arg(b));
363
		return (EQ_id(ia, ib) && eq_exp(sa, sb, co));
2 7u83 364
	}
6 7u83 365
	case exp_preinc_tag: {
366
		/* Pre-increment expressions */
367
		EXP sa = DEREF_exp(exp_preinc_op(a));
368
		EXP sb = DEREF_exp(exp_preinc_op(b));
369
		return (eq_exp(sa, sb, co));
2 7u83 370
	}
6 7u83 371
	case exp_postinc_tag: {
372
		/* Post-increment expressions */
373
		EXP sa = DEREF_exp(exp_postinc_op(a));
374
		EXP sb = DEREF_exp(exp_postinc_op(b));
375
		return (eq_exp(sa, sb, co));
2 7u83 376
	}
6 7u83 377
	case exp_indir_tag: {
378
		/* Indirection expressions */
379
		EXP sa = DEREF_exp(exp_indir_ptr(a));
380
		EXP sb = DEREF_exp(exp_indir_ptr(b));
381
		return (eq_exp(sa, sb, co));
2 7u83 382
	}
6 7u83 383
	case exp_contents_tag: {
384
		/* Contents expressions */
385
		EXP sa = DEREF_exp(exp_contents_ptr(a));
386
		EXP sb = DEREF_exp(exp_contents_ptr(b));
387
		return (eq_exp(sa, sb, co));
2 7u83 388
	}
6 7u83 389
	case exp_address_tag: {
390
		/* Address expressions */
391
		EXP sa = DEREF_exp(exp_address_arg(a));
392
		EXP sb = DEREF_exp(exp_address_arg(b));
393
		return (eq_exp(sa, sb, co));
2 7u83 394
	}
6 7u83 395
	case exp_address_mem_tag: {
396
		/* Address expressions */
397
		EXP sa = DEREF_exp(exp_address_mem_arg(a));
398
		EXP sb = DEREF_exp(exp_address_mem_arg(b));
399
		return (eq_exp(sa, sb, co));
2 7u83 400
	}
6 7u83 401
	case exp_func_tag: {
402
		/* Function expressions */
403
		EXP sa = DEREF_exp(exp_func_fn(a));
404
		EXP sb = DEREF_exp(exp_func_fn(b));
405
		LIST(EXP)pa = DEREF_list(exp_func_args(a));
406
		LIST(EXP)pb = DEREF_list(exp_func_args(b));
407
		return (eq_exp(sa, sb, co) && eq_exp_list(pa, pb, co));
2 7u83 408
	}
6 7u83 409
	case exp_func_id_tag: {
410
		/* Function expressions */
411
		IDENTIFIER ia = DEREF_id(exp_func_id_id(a));
412
		IDENTIFIER ib = DEREF_id(exp_func_id_id(b));
413
		LIST(EXP)pa = DEREF_list(exp_func_id_args(a));
414
		LIST(EXP)pb = DEREF_list(exp_func_id_args(b));
415
		return (EQ_id(ia, ib) && eq_exp_list(pa, pb, co));
2 7u83 416
	}
6 7u83 417
	case exp_call_tag: {
418
		/* Member function call expressions */
419
		EXP ra = DEREF_exp(exp_call_ptr(a));
420
		EXP rb = DEREF_exp(exp_call_ptr(b));
421
		EXP sa = DEREF_exp(exp_call_arg(a));
422
		EXP sb = DEREF_exp(exp_call_arg(b));
423
		return (eq_exp(ra, rb, co) && eq_exp(sa, sb, co));
2 7u83 424
	}
6 7u83 425
	case exp_negate_tag:
426
	case exp_compl_tag:
427
	case exp_not_tag:
428
	case exp_abs_tag: {
429
		/* Unary expressions */
430
		EXP sa = DEREF_exp(exp_negate_etc_arg(a));
431
		EXP sb = DEREF_exp(exp_negate_etc_arg(b));
432
		return (eq_exp(sa, sb, co));
2 7u83 433
	}
6 7u83 434
	case exp_plus_tag:
435
	case exp_mult_tag:
436
	case exp_and_tag:
437
	case exp_or_tag:
438
	case exp_xor_tag:
439
	case exp_log_and_tag:
440
	case exp_log_or_tag:
441
	case exp_max_tag:
442
	case exp_min_tag: {
443
		/* Commutative binary expressions */
444
		EXP ra = DEREF_exp(exp_plus_etc_arg1(a));
445
		EXP rb = DEREF_exp(exp_plus_etc_arg1(b));
446
		EXP sa = DEREF_exp(exp_plus_etc_arg2(a));
447
		EXP sb = DEREF_exp(exp_plus_etc_arg2(b));
448
		if (eq_exp(ra, rb, co) && eq_exp(sa, sb, co)) {
449
			return (1);
450
		}
451
		if (co && eq_exp(ra, sb, 1) && eq_exp(sa, rb, 1)) {
452
			return (1);
453
		}
454
		return (0);
2 7u83 455
	}
6 7u83 456
	case exp_minus_tag:
457
	case exp_div_tag:
458
	case exp_rem_tag:
459
	case exp_lshift_tag:
460
	case exp_rshift_tag: {
461
		/* Non-commutative binary expressions */
462
		EXP ra = DEREF_exp(exp_plus_etc_arg1(a));
463
		EXP rb = DEREF_exp(exp_plus_etc_arg1(b));
464
		EXP sa = DEREF_exp(exp_plus_etc_arg2(a));
465
		EXP sb = DEREF_exp(exp_plus_etc_arg2(b));
466
		return (eq_exp(ra, rb, co) && eq_exp(sa, sb, co));
2 7u83 467
	}
6 7u83 468
	case exp_test_tag: {
469
		/* Test expressions */
470
		NTEST ca = DEREF_ntest(exp_test_tst(a));
471
		NTEST cb = DEREF_ntest(exp_test_tst(b));
472
		EXP sa = DEREF_exp(exp_test_arg(a));
473
		EXP sb = DEREF_exp(exp_test_arg(b));
474
		if (ca != cb) {
475
			return (0);
476
		}
477
		return (eq_exp(sa, sb, co));
2 7u83 478
	}
6 7u83 479
	case exp_compare_tag: {
480
		/* Comparison expressions */
481
		NTEST ca = DEREF_ntest(exp_compare_tst(a));
482
		NTEST cb = DEREF_ntest(exp_compare_tst(b));
483
		EXP ra = DEREF_exp(exp_compare_arg1(a));
484
		EXP rb = DEREF_exp(exp_compare_arg1(b));
485
		EXP sa = DEREF_exp(exp_compare_arg2(a));
486
		EXP sb = DEREF_exp(exp_compare_arg2(b));
487
		if (ca != cb) {
488
			return (0);
2 7u83 489
		}
6 7u83 490
		if (eq_exp(ra, rb, co) && eq_exp(sa, sb, co)) {
491
			return (1);
492
		}
493
		if (co && (ca == ntest_eq || ca == ntest_not_eq)) {
494
			/* Commutative comparisons */
495
			if (eq_exp(ra, sb, 1) && eq_exp(sa, rb, 1)) {
496
				return (1);
497
			}
498
		}
499
		return (0);
2 7u83 500
	}
6 7u83 501
	case exp_cast_tag: {
502
		/* Cast expressions */
503
		EXP sa = DEREF_exp(exp_cast_arg(a));
504
		EXP sb = DEREF_exp(exp_cast_arg(b));
505
		unsigned va = DEREF_unsigned(exp_cast_conv(a));
506
		unsigned vb = DEREF_unsigned(exp_cast_conv(b));
507
		return (va == vb && eq_exp(sa, sb, co));
2 7u83 508
	}
6 7u83 509
	case exp_base_cast_tag: {
510
		/* Base cast expressions */
511
		EXP ra = DEREF_exp(exp_base_cast_arg(a));
512
		EXP rb = DEREF_exp(exp_base_cast_arg(b));
513
		OFFSET za = DEREF_off(exp_base_cast_off(a));
514
		OFFSET zb = DEREF_off(exp_base_cast_off(b));
515
		unsigned va = DEREF_unsigned(exp_base_cast_conv(a));
516
		unsigned vb = DEREF_unsigned(exp_base_cast_conv(b));
517
		if (va != vb) {
518
			return (0);
519
		}
520
		return (eq_exp(ra, rb, co) && eq_offset(za, zb, co));
2 7u83 521
	}
6 7u83 522
	case exp_dyn_cast_tag: {
523
		/* Dynamic cast expressions */
524
		EXP sa = DEREF_exp(exp_dyn_cast_arg(a));
525
		EXP sb = DEREF_exp(exp_dyn_cast_arg(b));
526
		EXP ra = DEREF_exp(exp_dyn_cast_except(a));
527
		EXP rb = DEREF_exp(exp_dyn_cast_except(b));
528
		return (eq_exp(sa, sb, co) && eq_exp(ra, rb, co));
2 7u83 529
	}
6 7u83 530
	case exp_add_ptr_tag: {
531
		/* Pointer addition expressions */
532
		EXP ra = DEREF_exp(exp_add_ptr_ptr(a));
533
		EXP rb = DEREF_exp(exp_add_ptr_ptr(b));
534
		OFFSET za = DEREF_off(exp_add_ptr_off(a));
535
		OFFSET zb = DEREF_off(exp_add_ptr_off(b));
536
		return (eq_exp(ra, rb, co) && eq_offset(za, zb, co));
2 7u83 537
	}
6 7u83 538
	case exp_offset_size_tag: {
539
		/* Offset size expressions */
540
		OFFSET xa = DEREF_off(exp_offset_size_off(a));
541
		OFFSET xb = DEREF_off(exp_offset_size_off(b));
542
		TYPE sa = DEREF_type(exp_offset_size_step(a));
543
		TYPE sb = DEREF_type(exp_offset_size_step(b));
544
		return (eq_offset(xa, xb, co) && eq_type_offset(sa, sb));
2 7u83 545
	}
6 7u83 546
	case exp_constr_tag: {
547
		/* Constructors */
548
		EXP sa = DEREF_exp(exp_constr_call(a));
549
		EXP sb = DEREF_exp(exp_constr_call(b));
550
		return (eq_exp(sa, sb, co));
2 7u83 551
	}
6 7u83 552
	case exp_destr_tag: {
553
		/* Destructors */
554
		EXP sa = DEREF_exp(exp_destr_call(a));
555
		EXP sb = DEREF_exp(exp_destr_call(b));
556
		return (eq_exp(sa, sb, co));
2 7u83 557
	}
6 7u83 558
	case exp_alloc_tag: {
559
		/* Allocators */
560
		EXP sa = DEREF_exp(exp_alloc_call(a));
561
		EXP sb = DEREF_exp(exp_alloc_call(b));
562
		EXP ra = DEREF_exp(exp_alloc_init(a));
563
		EXP rb = DEREF_exp(exp_alloc_init(b));
564
		return (eq_exp(sa, sb, co) && eq_exp(ra, rb, co));
2 7u83 565
	}
6 7u83 566
	case exp_dealloc_tag: {
567
		/* Deallocators */
568
		EXP sa = DEREF_exp(exp_dealloc_call(a));
569
		EXP sb = DEREF_exp(exp_dealloc_call(b));
570
		EXP ra = DEREF_exp(exp_dealloc_term(a));
571
		EXP rb = DEREF_exp(exp_dealloc_term(b));
572
		return (eq_exp(sa, sb, co) && eq_exp(ra, rb, co));
2 7u83 573
	}
6 7u83 574
	case exp_rtti_tag: {
575
		/* Run-time type information */
576
		EXP sa = DEREF_exp(exp_rtti_arg(a));
577
		EXP sb = DEREF_exp(exp_rtti_arg(b));
578
		EXP ra = DEREF_exp(exp_rtti_except(a));
579
		EXP rb = DEREF_exp(exp_rtti_except(b));
580
		int ia = DEREF_int(exp_rtti_op(a));
581
		int ib = DEREF_int(exp_rtti_op(b));
582
		if (ia != ib) {
583
			return (0);
584
		}
585
		return (eq_exp(sa, sb, co) && eq_exp(ra, rb, co));
2 7u83 586
	}
6 7u83 587
	case exp_rtti_type_tag: {
588
		/* Run-time type information */
589
		TYPE sa = DEREF_type(exp_rtti_type_arg(a));
590
		TYPE sb = DEREF_type(exp_rtti_type_arg(b));
591
		int ia = DEREF_int(exp_rtti_type_op(a));
592
		int ib = DEREF_int(exp_rtti_type_op(b));
593
		if (ia != ib) {
594
			return (0);
595
		}
596
		if (eq_type(sa, sb) == 1) {
597
			return (1);
598
		}
599
		return (0);
2 7u83 600
	}
6 7u83 601
	case exp_rtti_no_tag: {
602
		/* Link-time type information */
603
		TYPE sa = DEREF_type(exp_rtti_no_arg(a));
604
		TYPE sb = DEREF_type(exp_rtti_no_arg(b));
605
		if (eq_type(sa, sb) == 1) {
606
			return (1);
607
		}
608
		return (0);
2 7u83 609
	}
6 7u83 610
	case exp_dynamic_tag: {
611
		/* Dynamic initialisers */
612
		EXP sa = DEREF_exp(exp_dynamic_arg(a));
613
		EXP sb = DEREF_exp(exp_dynamic_arg(b));
614
		return (eq_exp(sa, sb, co));
2 7u83 615
	}
6 7u83 616
	case exp_aggregate_tag: {
617
		/* Aggregate initialisers */
618
		LIST(EXP)pa = DEREF_list(exp_aggregate_args(a));
619
		LIST(EXP)pb = DEREF_list(exp_aggregate_args(b));
620
		return (eq_exp_list(pa, pb, co));
2 7u83 621
	}
6 7u83 622
	case exp_initialiser_tag: {
623
		/* Function style initialisers */
624
		LIST(EXP)pa = DEREF_list(exp_initialiser_args(a));
625
		LIST(EXP)pb = DEREF_list(exp_initialiser_args(b));
626
		return (eq_exp_list(pa, pb, co));
2 7u83 627
	}
6 7u83 628
	case exp_nof_tag: {
629
		/* Array initialisers */
630
		EXP ra = DEREF_exp(exp_nof_start(a));
631
		EXP rb = DEREF_exp(exp_nof_start(b));
632
		EXP sa = DEREF_exp(exp_nof_pad(a));
633
		EXP sb = DEREF_exp(exp_nof_pad(b));
634
		NAT na = DEREF_nat(exp_nof_size(a));
635
		NAT nb = DEREF_nat(exp_nof_size(b));
636
		EXP ua = DEREF_exp(exp_nof_end(a));
637
		EXP ub = DEREF_exp(exp_nof_end(b));
638
		if (!EQ_nat(na, nb)) {
639
			if (!eq_nat(na, nb)) {
640
				return (0);
641
			}
642
		}
643
		if (!eq_exp(sa, sb, co)) {
644
			return (0);
645
		}
646
		return (eq_exp(ra, rb, co) && eq_exp(ua, ub, co));
2 7u83 647
	}
6 7u83 648
	case exp_comma_tag: {
649
		/* Comma expressions */
650
		LIST(EXP)pa = DEREF_list(exp_comma_args(a));
651
		LIST(EXP)pb = DEREF_list(exp_comma_args(b));
652
		return (eq_exp_list(pa, pb, co));
2 7u83 653
	}
6 7u83 654
	case exp_set_tag:
655
	case exp_unused_tag: {
656
		/* Flow analysis expressions */
657
		EXP sa = DEREF_exp(exp_set_etc_arg(a));
658
		EXP sb = DEREF_exp(exp_set_etc_arg(b));
659
		return (eq_exp(sa, sb, co));
2 7u83 660
	}
6 7u83 661
	case exp_if_stmt_tag: {
662
		/* Conditional expressions */
663
		EXP ca = DEREF_exp(exp_if_stmt_cond(a));
664
		EXP cb = DEREF_exp(exp_if_stmt_cond(b));
665
		EXP ra = DEREF_exp(exp_if_stmt_true_code(a));
666
		EXP rb = DEREF_exp(exp_if_stmt_true_code(b));
667
		EXP sa = DEREF_exp(exp_if_stmt_false_code(a));
668
		EXP sb = DEREF_exp(exp_if_stmt_false_code(b));
669
		if (!eq_exp(ca, cb, co)) {
670
			return (0);
671
		}
672
		return (eq_exp(ra, rb, co) && eq_exp(sa, sb, co));
2 7u83 673
	}
6 7u83 674
	case exp_exception_tag: {
675
		/* Throw expressions */
676
		EXP sa = DEREF_exp(exp_exception_arg(a));
677
		EXP sb = DEREF_exp(exp_exception_arg(b));
678
		return (eq_exp(sa, sb, co));
2 7u83 679
	}
6 7u83 680
	case exp_thrown_tag: {
681
		/* Thrown expressions */
682
		TYPE ta = DEREF_type(exp_type(a));
683
		TYPE tb = DEREF_type(exp_type(b));
684
		if (eq_type(ta, tb) == 1) {
685
			return (1);
686
		}
687
		return (0);
2 7u83 688
	}
6 7u83 689
	case exp_op_tag: {
690
		/* Undetermined expressions */
691
		int ca = DEREF_int(exp_op_lex(a));
692
		int cb = DEREF_int(exp_op_lex(b));
693
		EXP ra = DEREF_exp(exp_op_arg1(a));
694
		EXP rb = DEREF_exp(exp_op_arg1(b));
695
		EXP sa = DEREF_exp(exp_op_arg2(a));
696
		EXP sb = DEREF_exp(exp_op_arg2(b));
697
		if (ca != cb) {
698
			return (0);
699
		}
700
		return (eq_exp(ra, rb, co) && eq_exp(sa, sb, co));
2 7u83 701
	}
6 7u83 702
	case exp_opn_tag: {
703
		/* Undetermined expressions */
704
		int ca = DEREF_int(exp_opn_lex(a));
705
		int cb = DEREF_int(exp_opn_lex(b));
706
		LIST(EXP)pa = DEREF_list(exp_opn_args(a));
707
		LIST(EXP)pb = DEREF_list(exp_opn_args(b));
708
		if (ca != cb) {
709
			return (0);
710
		}
711
		return (eq_exp_list(pa, pb, co));
2 7u83 712
	}
6 7u83 713
	case exp_assembler_tag: {
714
		/* Assembler expressions */
715
		STRING ca = DEREF_str(exp_assembler_op(a));
716
		STRING cb = DEREF_str(exp_assembler_op(b));
717
		if (EQ_str(ca, cb) || eq_string_lit(ca, cb)) {
718
			LIST(EXP)pa = DEREF_list(exp_assembler_args(a));
719
			LIST(EXP)pb = DEREF_list(exp_assembler_args(b));
720
			return (eq_exp_list(pa, pb, co));
721
		}
722
		break;
2 7u83 723
	}
6 7u83 724
	case exp_location_tag: {
725
		/* Location expressions */
726
		EXP sa = DEREF_exp(exp_location_arg(a));
727
		EXP sb = DEREF_exp(exp_location_arg(b));
728
		return (eq_exp(sa, sb, co));
2 7u83 729
	}
6 7u83 730
	case exp_token_tag: {
731
		/* Token application */
732
		IDENTIFIER ia = DEREF_id(exp_token_tok(a));
733
		IDENTIFIER ib = DEREF_id(exp_token_tok(b));
734
		LIST(TOKEN)pa = DEREF_list(exp_token_args(a));
735
		LIST(TOKEN)pb = DEREF_list(exp_token_args(b));
736
		return (eq_token_args(ia, ib, pa, pb));
2 7u83 737
	}
6 7u83 738
	case exp_dummy_tag: {
739
		/* Dummy expressions */
740
		EXP sa = DEREF_exp(exp_dummy_value(a));
741
		EXP sb = DEREF_exp(exp_dummy_value(b));
742
		return (eq_exp(sa, sb, co));
2 7u83 743
	}
6 7u83 744
	case exp_reach_tag:
745
	case exp_unreach_tag:
746
	case exp_sequence_tag:
747
	case exp_solve_stmt_tag:
748
	case exp_decl_stmt_tag:
749
	case exp_while_stmt_tag:
750
	case exp_do_stmt_tag:
751
	case exp_switch_stmt_tag:
752
	case exp_hash_if_tag:
753
	case exp_return_stmt_tag:
754
	case exp_goto_stmt_tag:
755
	case exp_label_stmt_tag:
756
	case exp_try_block_tag:
757
	case exp_handler_tag:
758
	case exp_uncompiled_tag:
759
	case exp_fail_tag: {
760
		/* Statements are never equal */
761
		return (0);
2 7u83 762
	}
6 7u83 763
	}
764
	return (0);
2 7u83 765
}
766
 
767
 
768
/*
769
    UNIFY TWO EXPRESSIONS
770
 
771
    This routine unifies the expressions a and b by defining tokens as
772
    necessary.  It returns true if a value is assigned to a token.  Note
773
    that it is necessary to consider integer constant tokens as well as
774
    expression tokens.
775
*/
776
 
6 7u83 777
static int
778
unify_exp(EXP a, EXP b)
2 7u83 779
{
6 7u83 780
	IDENTIFIER id;
781
	LIST(TOKEN)args;
782
	switch (TAG_exp(a)) {
783
	case exp_token_tag: {
784
		id = DEREF_id(exp_token_tok(a));
785
		args = DEREF_list(exp_token_args(a));
786
		break;
2 7u83 787
	}
6 7u83 788
	case exp_int_lit_tag: {
789
		NAT n = DEREF_nat(exp_int_lit_nat(a));
790
		if (!IS_nat_token(n)) {
791
			return (0);
792
		}
793
		id = DEREF_id(nat_token_tok(n));
794
		args = DEREF_list(nat_token_args(n));
795
		break;
2 7u83 796
	}
6 7u83 797
	default:
798
		return (0);
2 7u83 799
	}
6 7u83 800
	if (IS_NULL_list(args) && defining_token(id)) {
801
		return (define_exp_token(id, b, 1));
802
	}
803
	return (0);
2 7u83 804
}
805
 
806
 
807
/*
808
    ARE TWO EXPRESSIONS EQUAL?
809
 
810
    This routine checks whether the expressions a and b are equal.  If
811
    co is true then commutivity and other such relations are taken
812
    into account.
813
*/
814
 
6 7u83 815
int
816
eq_exp(EXP a, EXP b, int co)
2 7u83 817
{
6 7u83 818
	/* Check for obvious equality */
819
	unsigned ta, tb;
820
	if (EQ_exp(a, b)) {
821
		return (1);
822
	}
823
	if (IS_NULL_exp(a)) {
824
		return (0);
825
	}
826
	if (IS_NULL_exp(b)) {
827
		return (0);
828
	}
2 7u83 829
 
6 7u83 830
	/* Allow for parentheses */
831
	ta = TAG_exp(a);
832
	while (ta == exp_paren_tag || ta == exp_copy_tag) {
833
		a = DEREF_exp(exp_paren_etc_arg(a));
834
		ta = TAG_exp(a);
835
	}
836
	tb = TAG_exp(b);
837
	while (tb == exp_paren_tag || tb == exp_copy_tag) {
838
		b = DEREF_exp(exp_paren_etc_arg(b));
839
		tb = TAG_exp(b);
840
	}
2 7u83 841
 
6 7u83 842
	/* Check equality of expressions */
843
	if (ta == tb && eq_exp_aux(a, b, co)) {
844
		return (1);
2 7u83 845
	}
6 7u83 846
	if (force_tokdef || force_template || expand_tokdef) {
847
		TYPE sa = DEREF_type(exp_type(a));
848
		TYPE sb = DEREF_type(exp_type(b));
849
		if (eq_type(sa, sb) == 1) {
850
			if (unify_exp(a, b)) {
851
				return (1);
852
			}
853
			if (unify_exp(b, a)) {
854
				return (1);
855
			}
856
		}
857
	}
858
	return (0);
2 7u83 859
}
860
 
861
 
862
/*
863
    ARE TWO EXPRESSIONS PRECISELY EQUAL?
864
 
865
    This routine is similar to eq_exp, but it disallows token and template
866
    unification and does not allow for commutivity relations.
867
*/
868
 
6 7u83 869
int
870
eq_exp_exact(EXP a, EXP b)
2 7u83 871
{
6 7u83 872
	int eq;
873
	int tok = force_tokdef;
874
	int templ = force_template;
875
	force_tokdef = 0;
876
	force_template = 0;
877
	eq = eq_exp(a, b, 0);
878
	force_template = templ;
879
	force_tokdef = tok;
880
	return (eq);
2 7u83 881
}
882
 
883
 
884
/*
885
    ARE TWO TOKENS EQUAL?
886
 
887
    This routine checks whether the tokens a and b are equal.
888
*/
889
 
6 7u83 890
int
891
eq_token(TOKEN a, TOKEN b)
2 7u83 892
{
6 7u83 893
	unsigned na, nb;
894
	if (EQ_tok(a, b)) {
895
		return (1);
2 7u83 896
	}
6 7u83 897
	if (IS_NULL_tok(a)) {
898
		return (0);
2 7u83 899
	}
6 7u83 900
	if (IS_NULL_tok(b)) {
901
		return (0);
2 7u83 902
	}
6 7u83 903
	na = TAG_tok(a);
904
	nb = TAG_tok(b);
905
	if (na != nb) {
906
		return (0);
2 7u83 907
	}
6 7u83 908
	switch (na) {
909
	case tok_exp_tag: {
910
		EXP va = DEREF_exp(tok_exp_value(a));
911
		EXP vb = DEREF_exp(tok_exp_value(b));
912
		return (eq_exp(va, vb, 0));
2 7u83 913
	}
6 7u83 914
	case tok_stmt_tag: {
915
		EXP va = DEREF_exp(tok_stmt_value(a));
916
		EXP vb = DEREF_exp(tok_stmt_value(b));
917
		return (eq_exp(va, vb, 0));
2 7u83 918
	}
6 7u83 919
	case tok_nat_tag:
920
	case tok_snat_tag: {
921
		NAT va = DEREF_nat(tok_nat_etc_value(a));
922
		NAT vb = DEREF_nat(tok_nat_etc_value(b));
923
		if (compare_nat(va, vb) == 0) {
924
			return (1);
925
		}
926
		break;
927
	}
928
	case tok_type_tag: {
929
		TYPE va = DEREF_type(tok_type_value(a));
930
		TYPE vb = DEREF_type(tok_type_value(b));
931
		if (eq_type(va, vb) == 1) {
932
			return (1);
933
		}
934
		return (0);
935
	}
936
	case tok_member_tag: {
937
		OFFSET va = DEREF_off(tok_member_value(a));
938
		OFFSET vb = DEREF_off(tok_member_value(b));
939
		return (eq_offset(va, vb, 0));
940
	}
941
	case tok_class_tag: {
942
		IDENTIFIER ia = DEREF_id(tok_class_value(a));
943
		IDENTIFIER ib = DEREF_id(tok_class_value(b));
944
		return (EQ_id(ia, ib));
945
	}
946
	}
947
	return (0);
2 7u83 948
}
949
 
950
 
951
/*
952
    ARE TWO TOKEN APPLICATIONS EQUAL?
953
 
954
    This routine checks whether the token applications ia ( pa ) and
955
    ib ( pb ) are equal.
956
*/
957
 
6 7u83 958
int
959
eq_token_args(IDENTIFIER ia, IDENTIFIER ib, LIST(TOKEN)pa, LIST(TOKEN)pb)
2 7u83 960
{
6 7u83 961
	if (!EQ_id(ia, ib)) {
962
		/* Check that tokens are the same */
963
		ia = DEREF_id(id_alias(ia));
964
		ib = DEREF_id(id_alias(ib));
965
		if (!EQ_id(ia, ib)) {
966
			if (!force_merge || !merge_type(ia, ib)) {
967
				return (0);
968
			}
969
		}
2 7u83 970
	}
6 7u83 971
	if (EQ_list(pa, pb)) {
972
		return (1);
973
	}
974
	if (LENGTH_list(pa)!= LENGTH_list(pb)) {
975
		return (0);
976
	}
977
	while (!IS_NULL_list(pa)) {
978
		TOKEN a, b;
979
		if (EQ_list(pa, pb)) {
980
			return (1);
981
		}
982
		a = DEREF_tok(HEAD_list(pa));
983
		b = DEREF_tok(HEAD_list(pb));
984
		if (!eq_token(a, b)) {
985
			return (0);
986
		}
987
		pb = TAIL_list(pb);
988
		pa = TAIL_list(pa);
989
	}
990
	return (1);
2 7u83 991
}
992
 
993
 
994
/*
995
    IS A TOKEN APPLICATION A CONSTANT?
996
 
997
    This routine checks whether the token id applied to the arguments args
998
    is a constant.
999
*/
1000
 
6 7u83 1001
static int
1002
is_const_token(IDENTIFIER id, LIST(TOKEN)args, int c)
2 7u83 1003
{
6 7u83 1004
	TOKEN tok = DEREF_tok(id_token_sort(id));
1005
	if (IS_tok_proc(tok)) {
1006
		/* Allow for procedure tokens */
1007
		tok = DEREF_tok(tok_proc_res(tok));
2 7u83 1008
	}
6 7u83 1009
	switch (TAG_tok(tok)) {
1010
	case tok_exp_tag: {
1011
		/* Check for constant expression tokens */
1012
		int cn = DEREF_int(tok_exp_constant(tok));
1013
		if (cn) {
1014
			/* Constant token */
1015
			return (1);
1016
		}
1017
		if (c >= 0) {
1018
			/* Constant expression expected */
1019
			report(crt_loc, ERR_token_const(id));
1020
		}
1021
		if (option(OPT_token_const) == OPTION_DISALLOW) {
1022
			/* Non-constant tokens not allowed */
1023
			return (0);
1024
		}
1025
		break;
2 7u83 1026
	}
6 7u83 1027
	case tok_nat_tag: {
1028
		/* Integer constants */
1029
		return (1);
2 7u83 1030
	}
6 7u83 1031
	case tok_stmt_tag: {
1032
		/* Statements are not constant */
1033
		return (0);
1034
	}
1035
	}
2 7u83 1036
 
6 7u83 1037
	/* Check all token arguments */
1038
	while (!IS_NULL_list(args)) {
1039
		TOKEN a = DEREF_tok(HEAD_list(args));
1040
		if (!IS_NULL_tok(a)) {
1041
			switch (TAG_tok(a)) {
1042
			case tok_exp_tag: {
1043
				EXP e = DEREF_exp(tok_exp_value(a));
1044
				if (!is_const_exp(e, c)) {
1045
					return (0);
1046
				}
1047
				break;
1048
			}
1049
			case tok_stmt_tag: {
1050
				EXP e = DEREF_exp(tok_stmt_value(a));
1051
				if (!is_const_exp(e, c)) {
1052
					return (0);
1053
				}
1054
				break;
1055
			}
1056
			case tok_member_tag: {
1057
				OFFSET off = DEREF_off(tok_member_value(a));
1058
				if (!is_const_offset(off, c, 1)) {
1059
					return (0);
1060
				}
1061
				break;
1062
			}
1063
			}
2 7u83 1064
		}
6 7u83 1065
		args = TAIL_list(args);
2 7u83 1066
	}
6 7u83 1067
	return (1);
2 7u83 1068
}
1069
 
1070
 
1071
/*
1072
    IS AN OFFSET A CONSTANT?
1073
 
1074
    This routine checks whether the offset off is a constant offset.  virt
1075
    is true if virtual base classes are to be taken into account.
1076
*/
1077
 
6 7u83 1078
int
1079
is_const_offset(OFFSET off, int c, int virt)
2 7u83 1080
{
6 7u83 1081
	ASSERT(ORDER_off == 13);
1082
	switch (TAG_off(off)) {
1083
	case off_zero_tag:
1084
	case off_type_tag:
1085
	case off_extra_tag:
1086
	case off_array_tag:
1087
	case off_member_tag: {
1088
		/* Constant offsets */
1089
		return (1);
2 7u83 1090
	}
6 7u83 1091
	case off_base_tag: {
1092
		/* Base class offsets */
1093
		if (virt) {
1094
			GRAPH gr = DEREF_graph(off_base_graph(off));
1095
			DECL_SPEC acc = DEREF_dspec(graph_access(gr));
1096
			if (!(acc & dspec_mutable)) {
1097
				return (1);
1098
			}
1099
		} else {
1100
			return (1);
1101
		}
1102
		break;
2 7u83 1103
	}
6 7u83 1104
	case off_deriv_tag: {
1105
		/* Derived class offsets */
1106
		if (virt) {
1107
			GRAPH gr = DEREF_graph(off_deriv_graph(off));
1108
			DECL_SPEC acc = DEREF_dspec(graph_access(gr));
1109
			if (!(acc & dspec_mutable)) {
1110
				return (1);
1111
			}
1112
		} else {
1113
			return (1);
1114
		}
1115
		break;
2 7u83 1116
	}
6 7u83 1117
	case off_ptr_mem_tag: {
1118
		/* Pointer member offsets */
1119
		EXP a = DEREF_exp(off_ptr_mem_arg(off));
1120
		return (is_const_exp(a, c));
2 7u83 1121
	}
6 7u83 1122
	case off_negate_tag: {
1123
		/* Offset negation */
1124
		OFFSET off1 = DEREF_off(off_negate_arg(off));
1125
		return (is_const_offset(off1, c, 1));
2 7u83 1126
	}
6 7u83 1127
	case off_plus_tag: {
1128
		/* Offset addition */
1129
		OFFSET off1 = DEREF_off(off_plus_arg1(off));
1130
		OFFSET off2 = DEREF_off(off_plus_arg2(off));
1131
		if (!is_const_offset(off1, c, 1)) {
1132
			return (0);
1133
		}
1134
		return (is_const_offset(off2, c, 1));
2 7u83 1135
	}
6 7u83 1136
	case off_mult_tag: {
1137
		/* Offset multiplication */
1138
		OFFSET off1 = DEREF_off(off_mult_arg1(off));
1139
		EXP a = DEREF_exp(off_mult_arg2(off));
1140
		if (!is_const_offset(off1, c, 1)) {
1141
			return (0);
1142
		}
1143
		return (is_const_exp(a, c));
2 7u83 1144
	}
6 7u83 1145
	case off_ptr_diff_tag: {
1146
		/* Pointer difference */
1147
		EXP a = DEREF_exp(off_ptr_diff_ptr1(off));
1148
		EXP b = DEREF_exp(off_ptr_diff_ptr2(off));
1149
		if (is_const_exp(a, c) && is_const_exp(b, c)) {
1150
			/* Only allow pointers from same array */
1151
			EXP pa = NULL_exp;
1152
			EXP pb = NULL_exp;
1153
			IGNORE find_exp_linkage(a, &pa, 1);
1154
			IGNORE find_exp_linkage(b, &pb, 1);
1155
			if (!IS_NULL_exp(pa) && !IS_exp_string_lit(pa)) {
1156
				return (eq_exp(pa, pb, 0));
1157
			}
2 7u83 1158
		}
6 7u83 1159
		break;
2 7u83 1160
	}
6 7u83 1161
	case off_token_tag: {
1162
		/* All member tokens are constant */
1163
		IDENTIFIER id = DEREF_id(off_token_tok(off));
1164
		LIST(TOKEN)args = DEREF_list(off_token_args(off));
1165
		return (is_const_token(id, args, c));
2 7u83 1166
	}
6 7u83 1167
	}
1168
	return (0);
2 7u83 1169
}
1170
 
1171
 
1172
/*
1173
    IS AN EXPRESSION AN ADDRESS CONSTANT?
1174
 
1175
    This routine checks whether the address of e is a constant expression.
1176
    c will be nonzero.
1177
*/
1178
 
6 7u83 1179
static int
1180
is_const_addr(EXP e, int c)
2 7u83 1181
{
6 7u83 1182
	if (IS_NULL_exp(e)) {
1183
		return (1);
2 7u83 1184
	}
6 7u83 1185
	switch (TAG_exp(e)) {
1186
	case exp_identifier_tag: {
1187
		/* Identifier expressions */
1188
		IDENTIFIER id = DEREF_id(exp_identifier_id(e));
1189
		DECL_SPEC ds = DEREF_dspec(id_storage(id));
1190
		if (!(ds & dspec_auto)) {
1191
			TYPE t = DEREF_type(exp_type(e));
1192
			if (!IS_type_ref(t)) {
1193
				return (1);
1194
			}
1195
		}
1196
		break;
2 7u83 1197
	}
6 7u83 1198
	case exp_indir_tag: {
1199
		/* Indirection expressions */
1200
		EXP a = DEREF_exp(exp_indir_ptr(e));
1201
		return (is_const_exp(a, c));
2 7u83 1202
	}
6 7u83 1203
	case exp_member_tag:
1204
	case exp_string_lit_tag:
1205
	case exp_rtti_type_tag: {
1206
		/* lvalue expressions */
1207
		return (1);
2 7u83 1208
	}
6 7u83 1209
	case exp_token_tag: {
1210
		/* Tokenised expressions */
1211
		return (is_const_exp(e, c));
1212
	}
1213
	case exp_comma_tag: {
1214
		/* Comma expressions (not allowed) */
1215
		if (c < 0) {
1216
			LIST(EXP)p = DEREF_list(exp_comma_args(e));
1217
			while (!IS_NULL_list(p)) {
1218
				EXP a = DEREF_exp(HEAD_list(p));
1219
				p = TAIL_list(p);
1220
				if (IS_NULL_list(p)) {
1221
					return (is_const_addr(a, c));
1222
				}
1223
				if (!is_const_exp(a, c)) {
1224
					break;
1225
				}
1226
			}
2 7u83 1227
		}
6 7u83 1228
		break;
2 7u83 1229
	}
6 7u83 1230
	case exp_if_stmt_tag: {
1231
		/* Conditional expressions */
1232
		EXP d = DEREF_exp(exp_if_stmt_cond(e));
1233
		EXP a = DEREF_exp(exp_if_stmt_true_code(e));
1234
		EXP b = DEREF_exp(exp_if_stmt_false_code(e));
1235
		if (!is_const_exp(d, c)) {
1236
			break;
1237
		}
1238
		if (!is_const_addr(a, c)) {
1239
			break;
1240
		}
1241
		return (is_const_addr(b, c));
2 7u83 1242
	}
6 7u83 1243
	}
1244
	return (0);
2 7u83 1245
}
1246
 
1247
 
1248
/*
1249
    IS AN EXPRESSION CONSTANT?
1250
 
1251
    This routine checks whether e is a constant expression.  Note that
1252
    most integer constant expressions are dealt with in a bottom-up
1253
    fashion by means of the constant evaluation routines.  Other
1254
    constants are dealt with in a top-down fashion by this routine.  If
1255
    c is 0 then only valid integer constant expressions are allowed; c
1256
    is -1 then only a check is intended.
1257
*/
1258
 
6 7u83 1259
int
1260
is_const_exp(EXP e, int c)
2 7u83 1261
{
6 7u83 1262
	TYPE t;
1263
	if (IS_NULL_exp(e)) {
1264
		return (1);
2 7u83 1265
	}
6 7u83 1266
	ASSERT(ORDER_exp == 88);
1267
	switch (TAG_exp(e)) {
1268
	case exp_int_lit_tag:
1269
	case exp_char_lit_tag: {
1270
		/* Integer literals */
1271
		return (1);
1272
	}
1273
	case exp_identifier_tag: {
1274
		/* Identifiers */
1275
		if (c) {
1276
			IDENTIFIER id = DEREF_id(exp_identifier_id(e));
1277
			DECL_SPEC ds = DEREF_dspec(id_storage(id));
1278
			if (!(ds & dspec_auto)) {
1279
				t = DEREF_type(exp_type(e));
1280
				if (!IS_type_ref(t)) {
1281
					return (1);
1282
				}
1283
			}
2 7u83 1284
		}
6 7u83 1285
		break;
2 7u83 1286
	}
6 7u83 1287
	case exp_string_lit_tag:
1288
	case exp_float_lit_tag:
1289
	case exp_null_tag:
1290
	case exp_zero_tag:
1291
	case exp_value_tag:
1292
	case exp_rtti_type_tag:
1293
	case exp_rtti_no_tag:
1294
	case exp_set_tag:
1295
	case exp_unused_tag: {
1296
		/* Floating literals, null pointers etc. */
1297
		if (c) {
1298
			return (1);
1299
		}
1300
		break;
2 7u83 1301
	}
6 7u83 1302
	case exp_paren_tag:
1303
	case exp_copy_tag: {
1304
		/* Parenthesised expressions */
1305
		EXP a = DEREF_exp(exp_paren_etc_arg(e));
1306
		return (is_const_exp(a, c));
2 7u83 1307
	}
6 7u83 1308
	case exp_indir_tag: {
1309
		/* Indirection expressions */
1310
		if (c) {
1311
			EXP a = DEREF_exp(exp_indir_ptr(e));
1312
			return (is_const_exp(a, c));
1313
		}
1314
		break;
2 7u83 1315
	}
6 7u83 1316
	case exp_address_tag: {
1317
		/* Address expressions */
1318
		if (c) {
1319
			EXP a = DEREF_exp(exp_address_arg(e));
1320
			return (is_const_addr(a, c));
1321
		}
1322
		break;
2 7u83 1323
	}
6 7u83 1324
	case exp_address_mem_tag: {
1325
		/* Address expressions */
1326
		if (c) {
1327
			EXP a = DEREF_exp(exp_address_mem_arg(e));
1328
			if (IS_exp_member(a)) {
1329
				return (1);
1330
			}
1331
		}
1332
		break;
2 7u83 1333
	}
6 7u83 1334
	case exp_negate_tag:
1335
	case exp_compl_tag:
1336
	case exp_not_tag:
1337
	case exp_abs_tag: {
1338
		/* Unary expressions */
1339
		EXP a = DEREF_exp(exp_negate_etc_arg(e));
1340
		return (is_const_exp(a, c));
2 7u83 1341
	}
6 7u83 1342
	case exp_plus_tag:
1343
	case exp_minus_tag:
1344
	case exp_mult_tag:
1345
	case exp_and_tag:
1346
	case exp_or_tag:
1347
	case exp_xor_tag:
1348
	case exp_log_and_tag:
1349
	case exp_log_or_tag:
1350
	case exp_lshift_tag:
1351
	case exp_rshift_tag:
1352
	case exp_max_tag:
1353
	case exp_min_tag: {
1354
		/* Binary expressions */
1355
		EXP a = DEREF_exp(exp_plus_etc_arg1(e));
1356
		EXP b = DEREF_exp(exp_plus_etc_arg2(e));
1357
		return (is_const_exp(a, c) && is_const_exp(b, c));
2 7u83 1358
	}
6 7u83 1359
	case exp_div_tag:
1360
	case exp_rem_tag: {
1361
		/* Division expressions */
1362
		EXP a = DEREF_exp(exp_plus_etc_arg1(e));
1363
		EXP b = DEREF_exp(exp_plus_etc_arg2(e));
1364
		if (c == 0 && is_zero_exp(b)) {
1365
			/* Division by zero doesn't count */
1366
			break;
1367
		}
1368
		return (is_const_exp(a, c) && is_const_exp(b, c));
2 7u83 1369
	}
6 7u83 1370
	case exp_test_tag: {
1371
		/* Test expressions */
1372
		EXP a = DEREF_exp(exp_test_arg(e));
1373
		return (is_const_exp(a, c));
2 7u83 1374
	}
6 7u83 1375
	case exp_compare_tag: {
1376
		/* Comparison expressions */
1377
		EXP a = DEREF_exp(exp_compare_arg1(e));
1378
		EXP b = DEREF_exp(exp_compare_arg2(e));
1379
		return (is_const_exp(a, c) && is_const_exp(b, c));
2 7u83 1380
	}
6 7u83 1381
	case exp_cast_tag: {
1382
		/* Cast expressions */
1383
		EXP a = DEREF_exp(exp_cast_arg(e));
1384
		if (!c) {
1385
			unsigned tc;
1386
			t = DEREF_type(exp_type(a));
1387
			tc = type_category(&t);
1388
			if (!IS_TYPE_INT(tc)) {
1389
				break;
1390
			}
1391
		}
1392
		return (is_const_exp(a, c));
2 7u83 1393
	}
6 7u83 1394
	case exp_base_cast_tag: {
1395
		/* Base cast expressions */
1396
		if (c) {
1397
			EXP a = DEREF_exp(exp_base_cast_arg(e));
1398
			OFFSET off = DEREF_off(exp_base_cast_off(e));
1399
			unsigned conv = DEREF_unsigned(exp_base_cast_conv(e));
1400
			if (conv & CONV_PTR_MEM_BASE) {
1401
				/* Pointer to member conversions */
1402
				if (conv & CONV_REVERSE) {
1403
					return (0);
1404
				}
1405
			} else {
1406
				/* Pointer conversions */
1407
				if (!is_zero_offset(off)) {
1408
					return (0);
1409
				}
1410
			}
1411
			return (is_const_exp(a, c));
2 7u83 1412
		}
6 7u83 1413
		break;
2 7u83 1414
	}
6 7u83 1415
	case exp_add_ptr_tag: {
1416
		/* Pointer addition */
1417
		if (c) {
1418
			t = DEREF_type(exp_type(e));
1419
			if (!IS_type_ref(t)) {
1420
				EXP a = DEREF_exp(exp_add_ptr_ptr(e));
1421
				OFFSET b = DEREF_off(exp_add_ptr_off(e));
1422
				int v = DEREF_int(exp_add_ptr_virt(e));
1423
				if (!is_const_exp(a, c)) {
1424
					return (0);
1425
				}
1426
				return (is_const_offset(b, c, v));
1427
			}
2 7u83 1428
		}
6 7u83 1429
		break;
2 7u83 1430
	}
6 7u83 1431
	case exp_offset_size_tag: {
1432
		/* Offset size */
1433
		OFFSET a = DEREF_off(exp_offset_size_off(e));
1434
		if (IS_off_type(a)) {
1435
			/* Allow for sizeof expressions */
1436
			TYPE s = DEREF_type(exp_offset_size_step(e));
1437
			if (EQ_type(s, type_char)) {
1438
				return (1);
1439
			}
1440
		}
1441
		if (c) {
1442
			return (is_const_offset(a, c, c));
1443
		}
1444
		break;
2 7u83 1445
	}
6 7u83 1446
	case exp_aggregate_tag: {
1447
		/* Aggregate initialisers */
1448
		if (c) {
1449
			LIST(EXP)p = DEREF_list(exp_aggregate_args(e));
1450
			while (!IS_NULL_list(p)) {
1451
				EXP a = DEREF_exp(HEAD_list(p));
1452
				if (!is_const_exp(a, c)) {
1453
					return (0);
1454
				}
1455
				p = TAIL_list(p);
1456
			}
1457
			return (1);
2 7u83 1458
		}
6 7u83 1459
		break;
2 7u83 1460
	}
6 7u83 1461
	case exp_nof_tag: {
1462
		/* Array initialisers */
1463
		if (c) {
1464
			EXP a = DEREF_exp(exp_nof_start(e));
1465
			EXP b = DEREF_exp(exp_nof_pad(e));
1466
			EXP d = DEREF_exp(exp_nof_end(e));
1467
			if (!is_const_exp(a, c)) {
1468
				return (0);
1469
			}
1470
			if (!is_const_exp(b, c)) {
1471
				return (0);
1472
			}
1473
			return (is_const_exp(d, c));
1474
		}
1475
		break;
2 7u83 1476
	}
6 7u83 1477
	case exp_comma_tag: {
1478
		/* Comma expressions (not allowed) */
1479
		if (c < 0) {
1480
			LIST(EXP)p = DEREF_list(exp_comma_args(e));
1481
			while (!IS_NULL_list(p)) {
1482
				EXP a = DEREF_exp(HEAD_list(p));
1483
				if (!is_const_exp(a, c)) {
1484
					return (0);
1485
				}
1486
				p = TAIL_list(p);
1487
			}
1488
			return (1);
2 7u83 1489
		}
6 7u83 1490
		break;
2 7u83 1491
	}
6 7u83 1492
	case exp_if_stmt_tag: {
1493
		/* Conditional expressions */
1494
		if (c) {
1495
			EXP d = DEREF_exp(exp_if_stmt_cond(e));
1496
			EXP a = DEREF_exp(exp_if_stmt_true_code(e));
1497
			EXP b = DEREF_exp(exp_if_stmt_false_code(e));
1498
			if (!is_const_exp(d, c)) {
1499
				break;
1500
			}
1501
			if (!is_const_exp(a, c)) {
1502
				break;
1503
			}
1504
			return (is_const_exp(b, c));
1505
		}
1506
		break;
2 7u83 1507
	}
6 7u83 1508
	case exp_op_tag: {
1509
		/* Undetermined expressions */
1510
		EXP a = DEREF_exp(exp_op_arg1(e));
1511
		EXP b = DEREF_exp(exp_op_arg2(e));
1512
		return (is_const_exp(a, c) && is_const_exp(b, c));
2 7u83 1513
	}
6 7u83 1514
	case exp_opn_tag: {
1515
		/* Undetermined nary expressions */
1516
		LIST(EXP)p = DEREF_list(exp_opn_args(e));
1517
		while (!IS_NULL_list(p)) {
1518
			EXP a = DEREF_exp(HEAD_list(p));
1519
			if (!is_const_exp(a, c)) {
1520
				return (0);
1521
			}
1522
			p = TAIL_list(p);
1523
		}
1524
		return (1);
2 7u83 1525
	}
6 7u83 1526
	case exp_token_tag: {
1527
		/* Tokenised expressions (C compatibility) */
1528
		IDENTIFIER id = DEREF_id(exp_token_tok(e));
1529
		LIST(TOKEN)args = DEREF_list(exp_token_args(e));
1530
		if (!c) {
1531
			unsigned tc;
1532
			t = DEREF_type(exp_type(e));
1533
			tc = type_category(&t);
1534
			if (!IS_TYPE_INT(tc)) {
1535
				break;
1536
			}
1537
		}
1538
		return (is_const_token(id, args, c));
2 7u83 1539
	}
6 7u83 1540
	case exp_location_tag: {
1541
		/* Location expressions */
1542
		EXP a = DEREF_exp(exp_location_arg(e));
1543
		return (is_const_exp(a, c));
2 7u83 1544
	}
6 7u83 1545
	case exp_dummy_tag: {
1546
		/* Dummy expressions */
1547
		EXP a = DEREF_exp(exp_dummy_value(e));
1548
		return (is_const_exp(a, c));
2 7u83 1549
	}
6 7u83 1550
	}
2 7u83 1551
 
6 7u83 1552
	/* Allow for errors */
1553
	t = DEREF_type(exp_type(e));
1554
	if (IS_type_error(t)) {
1555
		return (1);
1556
	}
1557
	return (0);
2 7u83 1558
}
1559
 
1560
 
1561
/*
1562
    DOES AN EXPRESSION CONTAIN AN OVERFLOW?
1563
 
1564
    Certain evaluations on integer constant expressions are only valid
1565
    if it can be shown that the operands cannot raise an exception.
1566
    For example, 'a - a' can only safely be replaced by zero if the
1567
    evaluation of a does not overflow.  This routine returns true if
1568
    the evaluation of the expression a may raise an overflow exception
1569
    or contains some other side effect.
1570
*/
1571
 
6 7u83 1572
int
1573
overflow_exp(EXP a)
2 7u83 1574
{
6 7u83 1575
	if (IS_NULL_exp(a)) {
1576
		return (0);
1577
	}
1578
	switch (TAG_exp(a)) {
1579
	case exp_int_lit_tag: {
1580
		/* Check integer constant expressions */
1581
		NAT n = DEREF_nat(exp_int_lit_nat(a));
1582
		unsigned etag = DEREF_unsigned(exp_int_lit_etag(a));
1583
		switch (etag) {
1584
		case exp_char_lit_tag:
1585
		case exp_offset_size_tag: {
1586
			/* These never overflow */
1587
			return (0);
2 7u83 1588
		}
6 7u83 1589
		}
1590
		return (is_calc_nat(n));
2 7u83 1591
	}
6 7u83 1592
	case exp_identifier_tag:
1593
	case exp_member_tag:
1594
	case exp_char_lit_tag:
1595
	case exp_value_tag:
1596
	case exp_null_tag:
1597
	case exp_zero_tag: {
1598
		return (0);
2 7u83 1599
	}
6 7u83 1600
	case exp_string_lit_tag: {
1601
		/* String literals deliberately excluded */
1602
		return (1);
2 7u83 1603
	}
6 7u83 1604
	case exp_paren_tag:
1605
	case exp_copy_tag: {
1606
		EXP b = DEREF_exp(exp_paren_etc_arg(a));
1607
		return (overflow_exp(b));
2 7u83 1608
	}
6 7u83 1609
	case exp_address_tag: {
1610
		EXP b = DEREF_exp(exp_address_arg(a));
1611
		return (overflow_exp(b));
2 7u83 1612
	}
6 7u83 1613
	case exp_address_mem_tag: {
1614
		EXP b = DEREF_exp(exp_address_mem_arg(a));
1615
		return (overflow_exp(b));
2 7u83 1616
	}
6 7u83 1617
	case exp_cast_tag: {
1618
		/* Cast expressions */
1619
		unsigned c = DEREF_unsigned(exp_cast_conv(a));
1620
		if (c == CONV_ELLIPSIS) {
1621
			EXP b = DEREF_exp(exp_cast_arg(a));
1622
			return (overflow_exp(b));
1623
		}
1624
		break;
2 7u83 1625
	}
6 7u83 1626
	case exp_comma_tag: {
1627
		LIST(EXP)p = DEREF_list(exp_comma_args(a));
1628
		while (!IS_NULL_list(p)) {
1629
			EXP b = DEREF_exp(HEAD_list(p));
1630
			if (overflow_exp(b)) {
1631
				return (1);
1632
			}
1633
			p = TAIL_list(p);
1634
		}
1635
		return (0);
2 7u83 1636
	}
6 7u83 1637
	case exp_aggregate_tag: {
1638
		LIST(EXP)p = DEREF_list(exp_aggregate_args(a));
1639
		while (!IS_NULL_list(p)) {
1640
			EXP b = DEREF_exp(HEAD_list(p));
1641
			if (overflow_exp(b)) {
1642
				return (1);
1643
			}
1644
			p = TAIL_list(p);
1645
		}
1646
		return (0);
2 7u83 1647
	}
6 7u83 1648
	case exp_nof_tag: {
1649
		EXP b = DEREF_exp(exp_nof_start(a));
1650
		EXP c = DEREF_exp(exp_nof_pad(a));
1651
		EXP d = DEREF_exp(exp_nof_end(a));
1652
		NAT n = DEREF_nat(exp_nof_size(a));
1653
		if (overflow_exp(b)) {
1654
			return (1);
1655
		}
1656
		if (overflow_exp(c)) {
1657
			return (1);
1658
		}
1659
		if (overflow_exp(d)) {
1660
			return (1);
1661
		}
1662
		return (is_calc_nat(n));
2 7u83 1663
	}
6 7u83 1664
	}
1665
	return (1);
2 7u83 1666
}
1667
 
1668
 
1669
/*
1670
    FIND THE LINKAGE OF AN EXPRESSION
1671
 
1672
    This routine checks the linkage of the expression a.  If vol is true
1673
    then the result is or-ed with dspec_implicit if a is derived from
1674
    an implicitly volatile external identifier and or-ed with dspec_pure
1675
    if a is derived from an implicitly const string literal.  The
1676
    component of a which determines the linkage is returned via pa.
1677
*/
1678
 
6 7u83 1679
DECL_SPEC
1680
find_exp_linkage(EXP e, EXP *pa, int vol)
2 7u83 1681
{
6 7u83 1682
	if (!IS_NULL_exp(e)) {
1683
		ASSERT(ORDER_exp == 88);
1684
		switch (TAG_exp(e)) {
1685
		case exp_identifier_tag:
1686
		case exp_member_tag: {
1687
			/* Identifier expressions */
1688
			IDENTIFIER id = DEREF_id(exp_identifier_etc_id(e));
1689
			DECL_SPEC ds = DEREF_dspec(id_storage(id));
1690
			ds &= (dspec_storage | dspec_temp);
1691
			if (vol && IS_id_variable_etc(id)) {
1692
				TYPE t = DEREF_type(id_variable_etc_type(id));
1693
				CV_SPEC cv = find_cv_qual(t);
1694
				if (!(cv & cv_volatile)) {
1695
					ds |= dspec_implicit;
1696
				}
1697
			}
1698
			*pa = e;
1699
			return (ds);
2 7u83 1700
		}
6 7u83 1701
		case exp_string_lit_tag: {
1702
			/* String literals have internal linkage */
1703
			*pa = e;
1704
			return (dspec_static | dspec_pure);
2 7u83 1705
		}
6 7u83 1706
		case exp_paren_tag:
1707
		case exp_copy_tag: {
1708
			/* Parenthesised expressions */
1709
			EXP a = DEREF_exp(exp_paren_etc_arg(e));
1710
			return (find_exp_linkage(a, pa, vol));
2 7u83 1711
		}
6 7u83 1712
		case exp_indir_tag: {
1713
			/* Indirection expressions */
1714
			EXP a = DEREF_exp(exp_indir_ptr(e));
1715
			return (find_exp_linkage(a, pa, vol));
1716
		}
1717
		case exp_address_tag: {
1718
			/* Address expressions */
1719
			EXP a = DEREF_exp(exp_address_arg(e));
1720
			return (find_exp_linkage(a, pa, vol));
1721
		}
1722
		case exp_address_mem_tag: {
1723
			/* Address expressions */
1724
			EXP a = DEREF_exp(exp_address_mem_arg(e));
1725
			if (IS_exp_member(a)) {
1726
				return (find_exp_linkage(a, pa, vol));
1727
			}
1728
			break;
1729
		}
1730
		case exp_cast_tag: {
1731
			/* Cast expressions */
1732
			EXP a = DEREF_exp(exp_cast_arg(e));
1733
			DECL_SPEC ds = find_exp_linkage(a, pa, vol);
1734
			ds &= ~(dspec_implicit | dspec_pure);
1735
			return (ds);
1736
		}
1737
		case exp_add_ptr_tag: {
1738
			/* Pointer offset expressions */
1739
			EXP a = DEREF_exp(exp_add_ptr_ptr(e));
1740
			DECL_SPEC ds = find_exp_linkage(a, pa, vol);
1741
			OFFSET off = DEREF_off(exp_add_ptr_off(e));
1742
			if (vol) {
1743
				/* Check for volatile members */
1744
				while (IS_off_plus(off)) {
1745
					off = DEREF_off(off_plus_arg2(off));
1746
				}
1747
				if (IS_off_member(off)) {
1748
					TYPE t;
1749
					CV_SPEC cv;
1750
					IDENTIFIER id;
1751
					id = DEREF_id(off_member_id(off));
1752
					t = DEREF_type(id_member_type(id));
1753
					cv = find_cv_qual(t);
1754
					if (cv & cv_volatile)ds &= ~dspec_implicit;
1755
				}
1756
			} else {
1757
				/* Only base class conversions allowed */
1758
				if (!IS_off_base(off) && !IS_off_deriv(off)) {
1759
					ds = dspec_none;
1760
				}
1761
			}
1762
			return (ds);
1763
		}
1764
		case exp_base_cast_tag: {
1765
			/* Base cast expressions */
1766
			EXP a = DEREF_exp(exp_base_cast_arg(e));
1767
			return (find_exp_linkage(a, pa, vol));
1768
		}
1769
		case exp_location_tag: {
1770
			/* Location expressions */
1771
			EXP a = DEREF_exp(exp_location_arg(e));
1772
			return (find_exp_linkage(a, pa, vol));
1773
		}
1774
		case exp_int_lit_tag:
1775
		case exp_char_lit_tag:
1776
		case exp_null_tag:
1777
		case exp_zero_tag:
1778
		case exp_value_tag:
1779
		case exp_token_tag: {
1780
			/* These count as external linkage */
1781
			*pa = e;
1782
			return (dspec_extern);
1783
		}
1784
		}
2 7u83 1785
	}
6 7u83 1786
	return (dspec_none);
2 7u83 1787
}
1788
 
1789
 
1790
/*
1791
    IS AN OFFSET ZERO?
1792
 
1793
    This routine checks whether the offset off is zero.  The only
1794
    non-trivial case is for base class offsets where the single
1795
    inheritance (zero offset) cases are marked using dspec_ignore.
1796
*/
1797
 
6 7u83 1798
int
1799
is_zero_offset(OFFSET off)
2 7u83 1800
{
6 7u83 1801
	if (IS_NULL_off(off)) {
1802
		return (1);
2 7u83 1803
	}
6 7u83 1804
	ASSERT(ORDER_off == 13);
1805
	switch (TAG_off(off)) {
1806
	case off_zero_tag: {
1807
		/* Zero offsets */
1808
		return (1);
2 7u83 1809
	}
6 7u83 1810
	case off_array_tag: {
1811
		/* Array offsets */
1812
		unsigned n = DEREF_unsigned(off_array_arg(off));
1813
		if (n == 0) {
1814
			return (1);
1815
		}
1816
		break;
2 7u83 1817
	}
6 7u83 1818
	case off_base_tag: {
1819
		/* Base class offsets */
1820
		GRAPH gr = DEREF_graph(off_base_graph(off));
1821
		DECL_SPEC acc = DEREF_dspec(graph_access(gr));
1822
		if (acc & dspec_ignore) {
1823
			return (1);
1824
		}
1825
		break;
2 7u83 1826
	}
6 7u83 1827
	case off_deriv_tag: {
1828
		/* Derived class offsets */
1829
		GRAPH gr = DEREF_graph(off_deriv_graph(off));
1830
		DECL_SPEC acc = DEREF_dspec(graph_access(gr));
1831
		if (acc & dspec_ignore) {
1832
			return (1);
1833
		}
1834
		break;
2 7u83 1835
	}
6 7u83 1836
	case off_negate_tag: {
1837
		/* Offset negations */
1838
		OFFSET a = DEREF_off(off_negate_arg(off));
1839
		return (is_zero_offset(a));
2 7u83 1840
	}
6 7u83 1841
	case off_plus_tag: {
1842
		/* Offset additions */
1843
		OFFSET a = DEREF_off(off_plus_arg1(off));
1844
		OFFSET b = DEREF_off(off_plus_arg2(off));
1845
		return (is_zero_offset(a) && is_zero_offset(b));
2 7u83 1846
	}
6 7u83 1847
	case off_mult_tag: {
1848
		/* Offset multiplications */
1849
		OFFSET a = DEREF_off(off_mult_arg1(off));
1850
		return (is_zero_offset(a));
1851
	}
1852
	}
1853
	return (0);
2 7u83 1854
}
1855
 
1856
 
1857
/*
1858
    IS THE TYPE OF AN OFFSET STATICALLY DETERMINED?
1859
 
1860
    This routine checks whether the type of a pointer plus the offset off
1861
    can be statically determined.  It returns 2 if the type is known
1862
    independent of the value of the pointer, 1 if it is known if the
1863
    type of the pointer is known, and 0 otherwise.
1864
*/
1865
 
6 7u83 1866
static int
1867
know_offset(OFFSET off)
2 7u83 1868
{
6 7u83 1869
	if (!IS_NULL_off(off)) {
1870
		switch (TAG_off(off)) {
1871
		case off_base_tag:
1872
		case off_deriv_tag:
1873
		case off_ptr_mem_tag: {
1874
			/* Base class offsets */
1875
			return (0);
1876
		}
1877
		case off_member_tag: {
1878
			/* Member offsets */
1879
			return (2);
1880
		}
1881
		case off_plus_tag: {
1882
			/* Check for derived member offsets */
1883
			off = DEREF_off(off_plus_arg2(off));
1884
			if (IS_off_member(off)) {
1885
				return (2);
1886
			}
1887
			break;
1888
		}
1889
		}
2 7u83 1890
	}
6 7u83 1891
	return (1);
2 7u83 1892
}
1893
 
1894
 
1895
/*
1896
    IS THE TYPE OF AN EXPRESSION STATICALLY DETERMINED?
1897
 
1898
    This routine checks whether the expression of class type or pointer to
1899
    class type, e, is derived from an object so that its type can be
1900
    statically determined.  It is used to check whether the virtual call
1901
    mechanism and virtual base class conversions can be bypassed for e.
1902
    A value of 2 is returned for non-obvious known types.
1903
*/
1904
 
6 7u83 1905
int
1906
know_type(EXP e)
2 7u83 1907
{
6 7u83 1908
	if (!IS_NULL_exp(e)) {
1909
		unsigned tag = TAG_exp(e);
1910
		switch (tag) {
1911
		case exp_address_tag: {
1912
			EXP a = DEREF_exp(exp_address_arg(e));
1913
			tag = TAG_exp(a);
1914
			if (tag == exp_identifier_tag) {
1915
				return (1);
1916
			}
1917
			if (tag == exp_indir_tag) {
1918
				EXP b = DEREF_exp(exp_indir_ptr(a));
1919
				return (know_type(b));
1920
			}
1921
			if (tag == exp_dummy_tag) {
1922
				EXP b = DEREF_exp(exp_dummy_value(a));
1923
				if (IS_NULL_exp(b)) {
1924
					int v = DEREF_int(exp_dummy_virt(a));
1925
					if (!v) {
1926
						return (1);
1927
					}
1928
				}
1929
			}
1930
			break;
2 7u83 1931
		}
6 7u83 1932
		case exp_indir_tag: {
1933
			EXP a = DEREF_exp(exp_indir_ptr(e));
1934
			return (know_type(a));
2 7u83 1935
		}
6 7u83 1936
		case exp_add_ptr_tag: {
1937
			OFFSET off = DEREF_off(exp_add_ptr_off(e));
1938
			int k = know_offset(off);
1939
			if (k == 2) {
1940
				return (1);
1941
			}
1942
			if (k == 1) {
1943
				EXP a = DEREF_exp(exp_add_ptr_ptr(e));
1944
				return (know_type(a));
1945
			}
1946
			break;
2 7u83 1947
		}
6 7u83 1948
		case exp_contents_tag: {
1949
			e = DEREF_exp(exp_contents_ptr(e));
1950
			if (IS_exp_identifier(e)) {
1951
				goto identifier_lab;
1952
			}
1953
			break;
2 7u83 1954
		}
6 7u83 1955
		case exp_identifier_tag:
1956
identifier_lab: {
1957
			 IDENTIFIER id = DEREF_id(exp_identifier_id(e));
1958
			 HASHID nm = DEREF_hashid(id_name(id));
1959
			 if (EQ_KEYWORD(nm, lex_this_Hname)) {
1960
				 /* A 'this' expression */
1961
				 NAMESPACE ns = DEREF_nspace(id_parent(id));
1962
				 id = DEREF_id(nspace_name(ns));
1963
				 nm = DEREF_hashid(id_name(id));
1964
				 if (IS_hashid_constr(nm)) {
1965
					 /* Function is a constructor */
1966
					 return (2);
1967
				 }
1968
				 if (IS_hashid_destr(nm)) {
1969
					 /* Function is a destructor */
1970
					 return (2);
1971
				 }
1972
			 }
1973
			 break;
1974
		 }
2 7u83 1975
		}
1976
	}
6 7u83 1977
	return (0);
2 7u83 1978
}