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 "id_ops.h"
65
#include "off_ops.h"
66
#include "type_ops.h"
67
#include "error.h"
68
#include "catalog.h"
69
#include "assign.h"
70
#include "basetype.h"
71
#include "cast.h"
72
#include "construct.h"
73
#include "convert.h"
74
#include "chktype.h"
75
#include "expression.h"
76
#include "identifier.h"
77
#include "initialise.h"
78
#include "literal.h"
79
#include "member.h"
80
#include "operator.h"
81
#include "predict.h"
82
#include "syntax.h"
83
#include "ustring.h"
84
 
85
 
86
/*
87
    CONVERT BY ASSIGNMENT
88
 
89
    This routine converts the expression a to the type t, as if by
90
    assignment.  The cases where t is a class type or a reference are
91
    handled elsewhere.
92
*/
93
 
6 7u83 94
EXP
95
convert_assign(TYPE t, EXP a, ERROR *err)
2 7u83 96
{
6 7u83 97
	EXP e = cast_exp(t, a, err, CAST_IMPLICIT);
98
	return (e);
2 7u83 99
}
100
 
101
 
102
/*
103
    CONVERT TO A CLASS TYPE BY ASSIGNMENT
104
 
105
    This routine converts the expression a to the class t, as if by
106
    assignment.  The constructors of t are ignored, only base class
107
    conversions and conversion operators being considered.
108
*/
109
 
6 7u83 110
EXP
111
convert_class(TYPE t, EXP a, ERROR *err)
2 7u83 112
{
6 7u83 113
	EXP e;
114
	TYPE s = DEREF_type(exp_type(a));
115
	if (IS_type_compound(s)) {
116
		e = cast_class_class(t, a, err, CAST_IMPLICIT, 0);
117
		if (!IS_NULL_exp(e)) {
118
			return (e);
119
		}
120
	}
121
	e = convert_conv(t, a, err, CAST_IMPLICIT);
122
	return (e);
2 7u83 123
}
124
 
125
 
126
/*
127
    CONSTRUCT A POSTFIX EXPRESSION
128
 
129
    This routine constructs the expressions 'a++' and 'a--'.  Note that
130
    in this and other assignment expressions, a cannot have array type,
131
    so that no bounds checks are appropriate.  The result is an rvalue.
132
*/
133
 
6 7u83 134
EXP
135
make_postfix_exp(int op, EXP a)
2 7u83 136
{
6 7u83 137
	EXP e;
138
	TYPE ta;
139
	ERROR err;
140
	unsigned ca;
2 7u83 141
 
6 7u83 142
	/* An assignment is a side effect */
143
	no_side_effects++;
2 7u83 144
 
6 7u83 145
	/* Allow for reference conversions */
146
	a = convert_reference(a, REF_NORMAL);
147
	ta = DEREF_type(exp_type(a));
148
	ca = type_category(&ta);
2 7u83 149
 
6 7u83 150
	/* Check for overloading */
2 7u83 151
#if LANGUAGE_CPP
6 7u83 152
	if (IS_TYPE_OVERLOAD(ca)) {
153
		if (overload_depth == 0) {
154
			/* Overloads as 'operator op ( a, 0 )' */
155
			EXP b = make_null_exp(type_sint);
156
			e = binary_overload(op, a, b);
157
			return (e);
158
		}
159
		if (IS_TYPE_CLASS(ca)) {
160
			goto error_lab;
161
		}
2 7u83 162
	}
163
#else
6 7u83 164
	if (IS_TYPE_CLASS(ca)) {
165
		goto error_lab;
166
	}
2 7u83 167
#endif
168
 
6 7u83 169
	/* Operand should be a modifiable lvalue */
170
	err = check_modifiable(ta, a);
171
	if (!IS_NULL_err(err)) {
172
		err = concat_error(err, ERR_expr_post_incr_mod(op));
173
		report(crt_loc, err);
174
		err = NULL_err;
175
	}
2 7u83 176
 
6 7u83 177
	/* Operand can be arithmetic ... */
178
	if (IS_TYPE_ARITH(ca)) {
179
		EXP b;
180
		TYPE t;
181
		TYPE tb;
182
		OFFSET off = NULL_off;
2 7u83 183
 
6 7u83 184
		/* Allow for bitfields */
185
		if (IS_TYPE_BITF(ca)) {
186
			off = decons_bitf_exp(&a);
187
		}
2 7u83 188
 
6 7u83 189
		/* Form the result */
190
		MAKE_exp_dummy(ta, a, LINK_NONE, off, 0, a);
191
		b = convert_lvalue(a);
192
		tb = DEREF_type(exp_type(b));
193
		t = promote_type(tb);
194
		if (IS_NULL_off(off)) {
195
			MAKE_exp_dummy(tb, b, LINK_NONE, NULL_off, 0, b);
196
			e = convert_promote(t, b);
197
		} else {
198
			b = convert_promote(t, b);
199
			MAKE_exp_dummy(t, b, LINK_NONE, NULL_off, 0, b);
200
			e = b;
201
			tb = t;
202
		}
203
		if (check_int_type(ta, btype_bool)) {
204
			/* Booleans are weird */
205
			unsigned v = BOOL_TRUE;
206
			if (op == lex_plus_Hplus) {
207
				report(crt_loc,
208
				       ERR_expr_post_incr_bool_inc(op, ta));
209
			} else {
210
				report(crt_loc,
211
				       ERR_expr_post_incr_bool_dec(op, ta));
212
				v = BOOL_FALSE;
213
			}
214
			e = make_bool_exp(v, exp_int_lit_tag);
215
		} else {
216
			/* Other types are simple */
217
			EXP c = make_unit_exp(t);
218
			if (op == lex_plus_Hplus) {
219
				MAKE_exp_plus(t, e, c, e);
220
			} else {
221
				MAKE_exp_minus(t, e, c, e);
222
			}
223
			e = convert_assign(ta, e, &err);
224
			if (!IS_NULL_err(err)) {
225
				err = concat_warning(err, ERR_expr_ass_conv());
226
				report(crt_loc, err);
227
			}
228
		}
229
		MAKE_exp_postinc(tb, a, b, e, e);
230
		return (e);
2 7u83 231
	}
232
 
6 7u83 233
	/* ... or pointer ... */
234
	if (IS_TYPE_PTR(ca)) {
235
		/* Pointer must be to complete object type */
236
		EXP b;
237
		OFFSET off;
238
		TYPE t = check_pointer(ta, &err);
239
		if (!IS_NULL_err(err)) {
240
			err = concat_error(err, ERR_expr_post_incr_incompl(op));
241
			report(crt_loc, err);
242
		}
243
		if (IS_type_top_etc(t)) {
244
			t = type_char;
245
		}
2 7u83 246
 
6 7u83 247
		/* Create the identities */
248
		MAKE_exp_dummy(ta, a, LINK_NONE, NULL_off, 0, a);
249
		b = convert_lvalue(a);
250
		ta = DEREF_type(exp_type(b));
251
		MAKE_exp_dummy(ta, b, LINK_NONE, NULL_off, 0, b);
2 7u83 252
 
6 7u83 253
		/* Form the result */
254
		MAKE_off_type(t, off);
255
		if (op == lex_minus_Hminus) {
256
			MAKE_off_negate(off, off);
257
		}
258
		e = make_add_ptr(ta, b, off);
259
		MAKE_exp_postinc(ta, a, b, e, e);
260
		return (e);
261
	}
2 7u83 262
 
6 7u83 263
	/* ... and nothing else */
264
error_lab:
265
	if (!IS_TYPE_ERROR(ca)) {
266
		report(crt_loc, ERR_expr_post_incr_op(op, ta));
2 7u83 267
	}
6 7u83 268
	e = make_error_exp(0);
269
	return (e);
2 7u83 270
}
271
 
272
 
273
/*
274
    CREATE A PRE-INCREMENT EXPRESSION
275
 
276
    This routine creates a pre-increment or assignment expression for
277
    the expression a of type t given by the operation b.  If a is a
278
    bitfield then off gives the bitfield offset.  The result is an
279
    lvalue in C++, but an rvalue in C.  There is a slight problem in the
280
    latter case when t is a bitfield: the value is not b, but
281
    convert_bitfield ( b ).  This conversion is left implicit, and is
282
    only made explicit in the TDF output routines.
283
*/
284
 
6 7u83 285
static EXP
286
make_preinc_exp(TYPE t, EXP a, EXP b, OFFSET off, int op)
2 7u83 287
{
6 7u83 288
	EXP e;
2 7u83 289
#if LANGUAGE_C
6 7u83 290
	t = rvalue_type(t);
2 7u83 291
#endif
6 7u83 292
	if (IS_NULL_off(off)) {
293
		/* Simple case */
294
		if (op == lex_assign) {
295
			MAKE_exp_assign(t, a, b, e);
296
		} else {
297
			MAKE_exp_preinc(t, a, b, op, e);
298
		}
2 7u83 299
	} else {
6 7u83 300
		/* Bitfield case */
2 7u83 301
#if LANGUAGE_C
6 7u83 302
		MAKE_exp_preinc(t, a, b, op, e);
303
		t = promote_type(t);
2 7u83 304
#else
6 7u83 305
		TYPE p;
306
		TYPE s = find_bitfield_type(t);
307
		MAKE_type_ptr(cv_none, s, p);
308
		s = lvalue_type(s);
309
		MAKE_exp_preinc(s, a, b, op, e);
310
		MAKE_exp_address(p, e, e);
311
		MAKE_exp_add_ptr(p, e, off, 0, e);
312
		MAKE_exp_indir(t, e, e);
2 7u83 313
#endif
6 7u83 314
	}
2 7u83 315
#if LANGUAGE_C
6 7u83 316
	MAKE_exp_contents(t, e, e);
2 7u83 317
#endif
6 7u83 318
	return (e);
2 7u83 319
}
320
 
321
 
322
/*
323
    CONSTRUCT A PREFIX EXPRESSION
324
 
325
    This routine constructs the expressions '++a' and '--a'.  The result is
326
    an lvalue in C++ but an rvalue in C.
327
*/
328
 
6 7u83 329
EXP
330
make_prefix_exp(int op, EXP a)
2 7u83 331
{
6 7u83 332
	EXP e;
333
	TYPE ta;
334
	ERROR err;
335
	unsigned ca;
2 7u83 336
 
6 7u83 337
	/* An assignment is a side effect */
338
	no_side_effects++;
2 7u83 339
 
6 7u83 340
	/* Allow for reference conversions */
341
	a = convert_reference(a, REF_NORMAL);
342
	ta = DEREF_type(exp_type(a));
343
	ca = type_category(&ta);
2 7u83 344
 
6 7u83 345
	/* Check for overloading */
2 7u83 346
#if LANGUAGE_CPP
6 7u83 347
	if (IS_TYPE_OVERLOAD(ca)) {
348
		if (overload_depth == 0) {
349
			/* Overloads as 'operator op ( a )' */
350
			e = unary_overload(op, a);
351
			return (e);
352
		}
353
		if (IS_TYPE_CLASS(ca)) {
354
			goto error_lab;
355
		}
2 7u83 356
	}
357
#else
6 7u83 358
	if (IS_TYPE_CLASS(ca)) {
359
		goto error_lab;
360
	}
2 7u83 361
#endif
362
 
6 7u83 363
	/* Operand should be a modifiable lvalue */
364
	err = check_modifiable(ta, a);
365
	if (!IS_NULL_err(err)) {
366
		err = concat_error(err, ERR_expr_pre_incr_mod(op));
367
		report(crt_loc, err);
368
		err = NULL_err;
369
	}
2 7u83 370
 
6 7u83 371
	/* Operand can be arithmetic ... */
372
	if (IS_TYPE_ARITH(ca)) {
373
		EXP c;
374
		TYPE t;
375
		OFFSET off = NULL_off;
2 7u83 376
 
6 7u83 377
		/* Booleans are weird */
378
		if (check_int_type(ta, btype_bool)) {
379
			unsigned v = BOOL_TRUE;
380
			if (op == lex_plus_Hplus) {
381
				report(crt_loc,
382
				       ERR_expr_pre_incr_bool_inc(op, ta));
383
			} else {
384
				report(crt_loc,
385
				       ERR_expr_pre_incr_bool_dec(op, ta));
386
				v = BOOL_FALSE;
387
			}
388
			c = make_bool_exp(v, exp_int_lit_tag);
389
			e = make_preinc_exp(ta, a, c, NULL_off, lex_assign);
390
			return (e);
391
		}
2 7u83 392
 
6 7u83 393
		/* Allow for bitfields */
394
		if (IS_TYPE_BITF(ca)) {
395
			off = decons_bitf_exp(&a);
396
		}
2 7u83 397
 
6 7u83 398
		/* Form the result */
399
		MAKE_exp_dummy(ta, a, LINK_NONE, off, 0, a);
400
		e = convert_lvalue(a);
401
		t = DEREF_type(exp_type(e));
402
		t = promote_type(t);
403
		e = convert_promote(t, e);
404
		c = make_unit_exp(t);
405
		if (op == lex_plus_Hplus) {
406
			MAKE_exp_plus(t, e, c, e);
407
		} else {
408
			MAKE_exp_minus(t, e, c, e);
409
		}
410
		e = convert_assign(ta, e, &err);
411
		if (!IS_NULL_err(err)) {
412
			err = concat_warning(err, ERR_expr_ass_conv());
413
			report(crt_loc, err);
414
		}
415
		e = make_preinc_exp(ta, a, e, off, op);
416
		return (e);
2 7u83 417
	}
418
 
6 7u83 419
	/* ... or pointer ... */
420
	if (IS_TYPE_PTR(ca)) {
421
		/* Pointer must be to complete object type */
422
		OFFSET off;
423
		TYPE t = check_pointer(ta, &err);
424
		if (!IS_NULL_err(err)) {
425
			err = concat_error(err, ERR_expr_pre_incr_incompl(op));
426
			report(crt_loc, err);
427
		}
428
		if (IS_type_top_etc(t)) {
429
			t = type_char;
430
		}
431
 
432
		/* Form the result */
433
		MAKE_exp_dummy(ta, a, LINK_NONE, NULL_off, 0, a);
434
		e = convert_lvalue(a);
435
		if (!IS_type_ptr(ta)) {
436
			ta = DEREF_type(exp_type(e));
437
		}
438
		MAKE_off_type(t, off);
439
		if (op == lex_minus_Hminus) {
440
			MAKE_off_negate(off, off);
441
		}
442
		e = make_add_ptr(ta, e, off);
443
		e = make_preinc_exp(ta, a, e, NULL_off, op);
444
		return (e);
2 7u83 445
	}
446
 
6 7u83 447
	/* ... and nothing else */
448
error_lab:
449
	if (!IS_TYPE_ERROR(ca)) {
450
		report(crt_loc, ERR_expr_pre_incr_op(op, ta));
2 7u83 451
	}
6 7u83 452
	e = make_error_exp(LANGUAGE_CPP);
453
	return (e);
2 7u83 454
}
455
 
456
 
457
/*
458
    CONSTRUCT AN ASSIGNMENT EXPRESSION
459
 
460
    This routine constructs the expression 'a = b'.  If c is true then
461
    assignment of classes is done directly rather than via an assignment
462
    operator.  The result is an lvalue in C++ but an rvalue in C.
463
*/
464
 
6 7u83 465
EXP
466
make_assign_exp(EXP a, EXP b, int c)
2 7u83 467
{
6 7u83 468
	EXP e;
469
	ERROR err;
470
	TYPE ta, tb;
471
	unsigned ca, cb;
472
	int to_class = 0;
473
	int op = lex_assign;
474
	OFFSET off = NULL_off;
2 7u83 475
 
6 7u83 476
	/* An assignment is a side effect */
477
	no_side_effects++;
2 7u83 478
 
6 7u83 479
	/* Apply reference conversion on first operand */
480
	a = convert_reference(a, REF_NORMAL);
481
	ta = DEREF_type(exp_type(a));
482
	ca = type_category(&ta);
2 7u83 483
 
6 7u83 484
	/* Apply reference conversion on second operand */
485
	b = convert_reference(b, REF_ASSIGN);
486
	tb = DEREF_type(exp_type(b));
487
	cb = type_category(&tb);
2 7u83 488
 
6 7u83 489
	/* Check for template parameters */
2 7u83 490
#if LANGUAGE_CPP
6 7u83 491
	if (IS_TYPE_TEMPL(ca) || IS_TYPE_TEMPL(cb)) {
492
		if (overload_depth == 0) {
493
			e = binary_overload(op, a, b);
494
			return (e);
495
		}
2 7u83 496
	}
497
#endif
498
 
6 7u83 499
	/* Check for overloading (classes only) */
500
	if (IS_TYPE_CLASS(ca)) {
2 7u83 501
#if LANGUAGE_CPP
6 7u83 502
		if (c == 0) {
503
			if (overload_depth == 0) {
504
				e = binary_overload(op, a, b);
505
				return (e);
506
			}
507
			if (!IS_TYPE_ERROR(cb)) {
508
				/* Find reason for failure */
509
				err = check_incomplete(ta);
510
				if (IS_NULL_err(err) && IS_type_compound(ta)) {
511
					CLASS_TYPE ct;
512
					IDENTIFIER id;
513
					ct = DEREF_ctype(type_compound_defn(ta));
514
					id = find_operator(ct, op);
515
					if (!IS_NULL_id(id)) {
516
						err = ERR_over_match_viable_none(id);
517
					}
518
				}
519
				err = concat_error(err, ERR_expr_ass_op(op, ta, tb));
520
				report(crt_loc, err);
521
			}
522
			e = make_error_exp(LANGUAGE_CPP);
523
			return (e);
2 7u83 524
		}
525
#else
6 7u83 526
		UNUSED(c);
527
		UNUSED(cb);
2 7u83 528
#endif
6 7u83 529
		to_class = 1;
530
	}
2 7u83 531
 
6 7u83 532
	/* First operand should be a modifiable lvalue */
533
	err = check_modifiable(ta, a);
534
	if (!IS_NULL_err(err)) {
535
		err = concat_error(err, ERR_expr_ass_mod(op));
536
		report(crt_loc, err);
537
	}
2 7u83 538
 
6 7u83 539
	/* Do operand conversion */
540
	err = NULL_err;
541
	if (to_class) {
542
		b = convert_none(b);
543
		b = convert_class(ta, b, &err);
544
		b = remove_temporary(b, a);
545
	} else {
546
		b = convert_assign(ta, b, &err);
547
	}
548
	if (!IS_NULL_err(err)) {
549
		err = concat_warning(err, ERR_expr_ass_conv());
550
		report(crt_loc, err);
551
	}
2 7u83 552
 
6 7u83 553
	/* Construct the result */
554
	if (IS_type_bitfield(ta)) {
555
		off = decons_bitf_exp(&a);
556
		MAKE_exp_dummy(ta, a, LINK_NONE, off, 0, a);
557
	}
558
	e = make_preinc_exp(ta, a, b, off, op);
559
	return (e);
2 7u83 560
}
561
 
562
 
563
/*
564
    CONSTRUCT A BECOMES EXPRESSION
565
 
566
    This routine constructs the expression 'a op b' where op is one of the
567
    assignment operators, '*=', '/=' etc.  The result is an lvalue in
568
    C++, but an rvalue in C.
569
*/
570
 
6 7u83 571
EXP
572
make_become_exp(int op, EXP a, EXP b)
2 7u83 573
{
6 7u83 574
	EXP e;
575
	EXP d;
576
	TYPE td;
577
	ERROR err;
578
	TYPE ta, tb;
579
	unsigned tag;
580
	unsigned ca, cb;
581
	OFFSET off = NULL_off;
2 7u83 582
 
6 7u83 583
	/* An assignment is a side effect */
584
	no_side_effects++;
2 7u83 585
 
6 7u83 586
	/* Apply reference conversion on first operand */
587
	a = convert_reference(a, REF_NORMAL);
588
	ta = DEREF_type(exp_type(a));
589
	ca = type_category(&ta);
2 7u83 590
 
6 7u83 591
	/* Apply reference conversion on second operand */
592
	b = convert_reference(b, REF_NORMAL);
593
	tb = DEREF_type(exp_type(b));
594
	cb = type_category(&tb);
2 7u83 595
 
6 7u83 596
	/* Allow for overloading */
2 7u83 597
#if LANGUAGE_CPP
6 7u83 598
	if (IS_TYPE_OVERLOAD(ca) || IS_TYPE_OVERLOAD(cb)) {
599
		if (overload_depth == 0) {
600
			e = binary_overload(op, a, b);
601
			return (e);
602
		}
603
		if (IS_TYPE_CLASS(ca)) {
604
			goto error_lab;
605
		}
2 7u83 606
	}
607
#else
6 7u83 608
	if (IS_TYPE_CLASS(ca)) {
609
		goto error_lab;
610
	}
2 7u83 611
#endif
612
 
6 7u83 613
	/* First operand should be a modifiable lvalue */
614
	err = check_modifiable(ta, a);
615
	if (!IS_NULL_err(err)) {
616
		err = concat_error(err, ERR_expr_ass_mod(op));
617
		report(crt_loc, err);
618
		err = NULL_err;
619
	}
2 7u83 620
 
6 7u83 621
	/* Allow for bitfields */
622
	if (IS_TYPE_BITF(ca)) {
623
		off = decons_bitf_exp(&a);
624
	}
2 7u83 625
 
6 7u83 626
	/* Introduce identity for assignment variable */
627
	td = ta;
628
	MAKE_exp_dummy(td, a, LINK_NONE, off, 0, d);
629
	a = convert_lvalue(d);
630
	ta = DEREF_type(exp_type(a));
631
	ca = type_category(&ta);
2 7u83 632
 
6 7u83 633
	/* Do lvalue conversions */
634
	if (IS_TYPE_ADDRESS(cb)) {
635
		b = convert_lvalue(b);
636
		tb = DEREF_type(exp_type(b));
637
		cb = type_category(&tb);
638
	}
2 7u83 639
 
6 7u83 640
	/* Weed out booleans immediately */
641
	if (IS_TYPE_INT(ca) && check_int_type(ta, btype_bool)) {
642
		report(crt_loc, ERR_expr_ass_op(op, ta, tb));
643
		e = make_error_exp(LANGUAGE_CPP);
644
		return (e);
645
	}
2 7u83 646
 
6 7u83 647
	/* Find the operation type */
648
	switch (op) {
649
	case lex_and_Heq_H1:
650
		tag = exp_and_tag;
651
		goto integral_lab;
652
	case lex_div_Heq:
653
		tag = exp_div_tag;
654
		goto arithmetic_lab;
655
	case lex_lshift_Heq:
656
		tag = exp_lshift_tag;
657
		goto shift_lab;
658
	case lex_minus_Heq:
659
		tag = exp_minus_tag;
660
		goto pointer_lab;
661
	case lex_or_Heq_H1:
662
		tag = exp_or_tag;
663
		goto integral_lab;
664
	case lex_plus_Heq:
665
		tag = exp_plus_tag;
666
		goto pointer_lab;
667
	case lex_rem_Heq:
668
		tag = exp_rem_tag;
669
		goto integral_lab;
670
	case lex_rshift_Heq:
671
		tag = exp_rshift_tag;
672
		goto shift_lab;
673
	case lex_star_Heq:
674
		tag = exp_mult_tag;
675
		goto arithmetic_lab;
676
	case lex_xor_Heq_H1:
677
		tag = exp_xor_tag;
678
		goto integral_lab;
679
	default:
680
		goto error_lab;
681
	}
2 7u83 682
 
6 7u83 683
integral_lab:
2 7u83 684
	/* Integral operations */
6 7u83 685
	if (IS_TYPE_INT(ca) && IS_TYPE_INT(cb)) {
686
		TYPE t = arith_type(ta, tb, a, b);
687
		a = convert_arith(t, a, op, 1);
688
		b = convert_arith(t, b, op, 2);
689
		if (op == lex_rem_Heq) {
690
			IGNORE check_div_exp(op, a, b);
691
		}
692
		MAKE_exp_plus_etc(tag, t, a, b, e);
693
		e = convert_assign(td, e, &err);
694
		if (!IS_NULL_err(err)) {
695
			err = concat_warning(err, ERR_expr_ass_conv());
696
			report(crt_loc, err);
697
		}
698
		e = make_preinc_exp(td, d, e, off, op);
699
		return (e);
2 7u83 700
	}
6 7u83 701
	goto error_lab;
2 7u83 702
 
6 7u83 703
arithmetic_lab:
2 7u83 704
	/* Arithmetic operations */
6 7u83 705
	if (IS_TYPE_ARITH(ca) && IS_TYPE_ARITH(cb)) {
706
		TYPE t = arith_type(ta, tb, a, b);
707
		a = convert_arith(t, a, op, 1);
708
		b = convert_arith(t, b, op, 2);
709
		if (op == lex_div_Heq) {
710
			IGNORE check_div_exp(op, a, b);
711
		}
712
		MAKE_exp_plus_etc(tag, t, a, b, e);
713
		e = convert_assign(td, e, &err);
714
		if (!IS_NULL_err(err)) {
715
			err = concat_warning(err, ERR_expr_ass_conv());
716
			report(crt_loc, err);
717
		}
718
		e = make_preinc_exp(td, d, e, off, op);
719
		return (e);
2 7u83 720
	}
6 7u83 721
	goto error_lab;
2 7u83 722
 
6 7u83 723
shift_lab:
2 7u83 724
	/* Shift operations */
6 7u83 725
	if (IS_TYPE_INT(ca) && IS_TYPE_INT(cb)) {
726
		TYPE pta = promote_type(ta);
727
		TYPE ptb = promote_type(tb);
728
		a = convert_promote(pta, a);
729
		b = convert_promote(ptb, b);
730
		IGNORE check_shift_exp(op, pta, a, b);
731
		MAKE_exp_plus_etc(tag, pta, a, b, e);
732
		e = convert_assign(td, e, &err);
733
		if (!IS_NULL_err(err)) {
734
			err = concat_warning(err, ERR_expr_ass_conv());
735
			report(crt_loc, err);
736
		}
737
		e = make_preinc_exp(td, d, e, off, op);
738
		return (e);
2 7u83 739
	}
6 7u83 740
	goto error_lab;
2 7u83 741
 
6 7u83 742
pointer_lab:
2 7u83 743
	/* Pointer or arithmetic operations */
6 7u83 744
	if (IS_TYPE_PTR(ca) && IS_TYPE_INT(cb)) {
745
		OFFSET off1;
746
		int neg = 0;
747
		TYPE t = check_pointer(ta, &err);
748
		if (!IS_NULL_err(err)) {
749
			err = concat_error(err, ERR_expr_ass_incompl(op));
750
			report(crt_loc, err);
751
		}
752
		if (op == lex_minus_Heq) {
753
			neg = 1;
754
		}
755
		off1 = make_off_mult(t, b, neg);
756
		e = make_add_ptr(ta, a, off1);
757
		e = make_preinc_exp(td, d, e, NULL_off, op);
758
		return (e);
2 7u83 759
	}
6 7u83 760
	goto arithmetic_lab;
2 7u83 761
 
6 7u83 762
error_lab:
2 7u83 763
	/* Bad operations */
6 7u83 764
	if (!IS_TYPE_ERROR(ca) && !IS_TYPE_ERROR(cb)) {
765
		report(crt_loc, ERR_expr_ass_op(op, ta, tb));
2 7u83 766
	}
6 7u83 767
	e = make_error_exp(LANGUAGE_CPP);
768
	return (e);
2 7u83 769
}