Subversion Repositories tendra.SVN

Rev

Rev 5 | Go to most recent revision | 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, 1998
6 7u83 33
 
2 7u83 34
    This TenDRA(r) Computer Program is subject to Copyright
35
    owned by the United Kingdom Secretary of State for Defence
36
    acting through the Defence Evaluation and Research Agency
37
    (DERA).  It is made available to Recipients with a
38
    royalty-free licence for its use, reproduction, transfer
39
    to other parties and amendment for any purpose not excluding
40
    product development provided that any such use et cetera
41
    shall be deemed to be acceptance of the following conditions:-
6 7u83 42
 
2 7u83 43
        (1) Its Recipients shall ensure that this Notice is
44
        reproduced upon any copies or amended versions of it;
6 7u83 45
 
2 7u83 46
        (2) Any amended version of it shall be clearly marked to
47
        show both the nature of and the organisation responsible
48
        for the relevant amendment or amendments;
6 7u83 49
 
2 7u83 50
        (3) Its onward transfer from a recipient to another
51
        party shall be deemed to be that party's acceptance of
52
        these conditions;
6 7u83 53
 
2 7u83 54
        (4) DERA gives no warranty or assurance as to its
55
        quality or suitability for any purpose and DERA accepts
56
        no liability whatsoever in relation to any use to which
57
        it may be put.
58
*/
59
 
60
 
61
#include "config.h"
62
#include "c_types.h"
63
#include "ctype_ops.h"
64
#include "etype_ops.h"
65
#include "exp_ops.h"
66
#include "ftype_ops.h"
67
#include "graph_ops.h"
68
#include "hashid_ops.h"
69
#include "id_ops.h"
70
#include "member_ops.h"
71
#include "nat_ops.h"
72
#include "nspace_ops.h"
73
#include "str_ops.h"
74
#include "type_ops.h"
75
#include "error.h"
76
#include "catalog.h"
77
#include "option.h"
78
#include "tdf.h"
79
#include "access.h"
80
#include "assign.h"
81
#include "basetype.h"
82
#include "buffer.h"
83
#include "cast.h"
84
#include "check.h"
85
#include "chktype.h"
86
#include "class.h"
87
#include "compile.h"
88
#include "constant.h"
89
#include "construct.h"
90
#include "convert.h"
91
#include "declare.h"
92
#include "derive.h"
93
#include "destroy.h"
94
#include "dump.h"
95
#include "exception.h"
96
#include "expression.h"
97
#include "file.h"
98
#include "function.h"
99
#include "hash.h"
100
#include "identifier.h"
101
#include "initialise.h"
102
#include "instance.h"
103
#include "inttype.h"
104
#include "literal.h"
105
#include "namespace.h"
106
#include "overload.h"
107
#include "parse.h"
108
#include "predict.h"
109
#include "print.h"
110
#include "statement.h"
111
#include "syntax.h"
112
#include "template.h"
113
#include "tok.h"
114
#include "tokdef.h"
115
#include "token.h"
116
#include "ustring.h"
117
 
118
 
119
/*
120
    INLINE MEMBER DEFINITIONS
121
 
122
    A static member can be defined inline in its class.  This is only a
123
    provisional definition for use in constant expressions etc.  The real
124
    definition (which cannot contain an initialiser) must be provided
125
    elsewhere.  This value is used to indicate such members.
126
*/
127
 
128
#define dspec_stat_inline	dspec_explicit
6 7u83 129
#define dspec_ignore_mem	(dspec_alias | dspec_inherit | dspec_token)
2 7u83 130
 
131
 
132
/*
133
    MEMBER NUMBER
134
 
135
    This variable is used to keep track of the number of data members
136
    within next_data_member.  Anonymous unions, rather than their members,
137
    are counted.
138
*/
139
 
6 7u83 140
unsigned long member_no = 0;
2 7u83 141
 
142
 
143
/*
144
    FIND NEXT DATA MEMBER
145
 
146
    This routine returns the first non-static, non-function member of a
147
    class following mem.  Anonymous unions are included if bit 1 of bf
148
    is false, but their members if it is true.  Anonymous bitfields are
149
    included if bit 0 of bf is true.  The null member is returned if there
150
    are no further members.
151
*/
152
 
6 7u83 153
MEMBER
154
next_data_member(MEMBER mem, int bf)
2 7u83 155
{
6 7u83 156
	while (!IS_NULL_member(mem)) {
157
		IDENTIFIER id = DEREF_id(member_id(mem));
158
		if (!IS_NULL_id(id) && IS_id_member(id)) {
159
			DECL_SPEC ds = DEREF_dspec(id_storage(id));
160
			if (!(ds & dspec_ignore_mem)) {
161
				int ok = 1;
162
				HASHID nm = DEREF_hashid(id_name(id));
163
				if (ds & dspec_reserve) {
164
					/* Anonymous union members */
165
					if (!(bf & 2)) {
166
						ok = 0;
167
					}
168
				} else {
169
					member_no++;
170
				}
171
				if (IS_hashid_anon(nm)) {
172
					TYPE t = DEREF_type(id_member_type(id));
173
					unsigned tag = TAG_type(t);
174
					if (tag == type_bitfield_tag) {
175
						/* Anonymous bitfield */
176
						if (!(bf & 1)) {
177
							ok = 0;
178
						}
179
					} else if (tag == type_compound_tag) {
180
						/* Anonymous union */
181
						if (bf & 2) {
182
							ok = 0;
183
						}
184
					}
185
				}
186
				if (ok) {
187
					return (mem);
188
				}
189
			}
2 7u83 190
		}
6 7u83 191
		mem = DEREF_member(member_next(mem));
2 7u83 192
	}
6 7u83 193
	return (NULL_member);
2 7u83 194
}
195
 
196
 
197
/*
198
    CONSTRUCT A DYNAMIC INITIALISER
199
 
200
    This routine checks whether the expression e is a non-constant
201
    initialiser for id (or a component of id if off is not null).  If so
202
    it is embedded in a dynamic initialiser expression and an error is
203
    reported.
204
*/
205
 
6 7u83 206
EXP
207
dynamic_init(IDENTIFIER id, string off, EXP e)
2 7u83 208
{
6 7u83 209
	int fs = 0;
210
	int c = -1;
211
	if (!IS_NULL_id(id)) {
212
		switch (TAG_id(id)) {
213
		case id_variable_tag: {
214
			DECL_SPEC ds = DEREF_dspec(id_storage(id));
215
			if (ds & dspec_auto) {
216
				if (off == NULL) {
217
					return (e);
218
				}
219
			} else {
220
				if (!(ds & dspec_linkage)) {
221
					fs = 1;
222
				}
223
			}
224
			break;
2 7u83 225
		}
6 7u83 226
		case id_stat_member_tag:
227
			/* Check static members */
228
			break;
229
		default:
230
			/* Ignore other identifiers */
231
			return (e);
232
		}
2 7u83 233
	}
6 7u83 234
	if (option(OPT_init_dynamic)) {
235
		/* Dynamic initialisation not allowed */
236
		c = 1;
2 7u83 237
	}
6 7u83 238
	if (!is_const_exp(e, c)) {
239
		/* Non-constant initialiser */
240
		TYPE t = DEREF_type(exp_type(e));
241
		if (!is_templ_type(t)) {
242
			ERROR err;
243
			if (off) {
244
				err = ERR_dcl_init_aggr_dynamic();
245
			} else {
246
				err = ERR_dcl_init_dynamic();
247
			}
248
			if (!IS_NULL_err(err)) {
249
				ERROR err2 = ERR_dcl_init_decl(id, off);
250
				err = concat_error(err2, err);
251
				report(crt_loc, err);
252
			}
253
			if (fs) {
254
				/* Check function statics */
255
				e = check_return_exp(e, lex_static);
256
			}
257
			MAKE_exp_dynamic(t, e, e);
258
		}
259
	}
260
	return (e);
2 7u83 261
}
262
 
263
 
264
/*
265
    CHECK A VARIABLE INITIALISER
266
 
267
    This routine is called to check the initialiser for a variable or static
268
    data member.  Its primary purpose is to mark those temporaries which
269
    are bound to variables.
270
*/
271
 
6 7u83 272
EXP
273
check_init(EXP e)
2 7u83 274
{
6 7u83 275
	if (!IS_NULL_exp(e)) {
276
		switch (TAG_exp(e)) {
277
		case exp_identifier_tag: {
278
			IDENTIFIER id = DEREF_id(exp_identifier_id(e));
279
			DECL_SPEC ds = DEREF_dspec(id_storage(id));
280
			if (ds & dspec_temp) {
281
				ds &= ~dspec_register;
282
				COPY_dspec(id_storage(id), ds);
283
			}
284
			break;
2 7u83 285
		}
6 7u83 286
		case exp_init_tag: {
287
			IDENTIFIER id = DEREF_id(exp_init_id(e));
288
			DECL_SPEC ds = DEREF_dspec(id_storage(id));
289
			if (ds & dspec_temp) {
290
				ds &= ~dspec_register;
291
				COPY_dspec(id_storage(id), ds);
292
			}
293
			break;
2 7u83 294
		}
6 7u83 295
		case exp_indir_tag: {
296
			EXP a = DEREF_exp(exp_indir_ptr(e));
297
			a = check_init(a);
298
			COPY_exp(exp_indir_ptr(e), a);
299
			break;
2 7u83 300
		}
6 7u83 301
		case exp_address_tag: {
302
			EXP a = DEREF_exp(exp_address_arg(e));
303
			a = check_init(a);
304
			COPY_exp(exp_address_arg(e), a);
305
			break;
306
		}
307
		case exp_base_cast_tag: {
308
			EXP a = DEREF_exp(exp_base_cast_arg(e));
309
			a = check_init(a);
310
			COPY_exp(exp_base_cast_arg(e), a);
311
			break;
312
		}
313
		case exp_add_ptr_tag: {
314
			EXP a = DEREF_exp(exp_add_ptr_ptr(e));
315
			a = check_init(a);
316
			COPY_exp(exp_add_ptr_ptr(e), a);
317
			break;
318
		}
319
		case exp_dynamic_tag: {
320
			EXP a = DEREF_exp(exp_dynamic_arg(e));
321
			a = check_init(a);
322
			COPY_exp(exp_dynamic_arg(e), a);
323
			break;
324
		}
325
		case exp_aggregate_tag: {
326
			LIST(EXP) p = DEREF_list(exp_aggregate_args(e));
327
			while (!IS_NULL_list(p)) {
328
				EXP a = DEREF_exp(HEAD_list(p));
329
				a = check_init(a);
330
				COPY_exp(HEAD_list(p), a);
331
				p = TAIL_list(p);
332
			}
333
			break;
334
		}
335
		case exp_nof_tag: {
336
			EXP a = DEREF_exp(exp_nof_start(e));
337
			EXP b = DEREF_exp(exp_nof_pad(e));
338
			EXP c = DEREF_exp(exp_nof_end(e));
339
			a = check_init(a);
340
			b = check_init(b);
341
			c = check_init(c);
342
			COPY_exp(exp_nof_start(e), a);
343
			COPY_exp(exp_nof_pad(e), b);
344
			COPY_exp(exp_nof_end(e), c);
345
			break;
346
		}
347
		}
2 7u83 348
	}
6 7u83 349
	return (e);
2 7u83 350
}
351
 
352
 
353
/*
354
    TEMPORARY VARIABLE FLAG
355
 
356
    The variable made_temporary is set to the temporary variable whenever
357
    a temporary variable is created.  temp_storage is used to determine
358
    the storage class for a local variable.
359
*/
360
 
6 7u83 361
IDENTIFIER made_temporary = NULL_id;
362
int keep_temporary = 0;
363
static DECL_SPEC temp_storage = dspec_auto;
2 7u83 364
 
365
 
366
/*
367
    DECLARE A TEMPORARY VARIABLE
368
 
369
    This routine declares a temporary variable of type t, initial value
370
    e, and destructor d (the implicit destructor will be created if this
371
    is the null expression).  It returns an expression giving the value of
372
    this temporary.  Note the use of an assignment expression to ensure
373
    that the temporary gets initialised in the right place.
374
*/
375
 
6 7u83 376
EXP
377
make_temporary(TYPE t, EXP e, EXP d, int ref, ERROR *err)
2 7u83 378
{
6 7u83 379
	LOCATION loc;
380
	DECL_SPEC ds;
381
	EXP c = NULL_exp;
382
	HASHID nm = lookup_anon();
383
	NAMESPACE ns = crt_namespace;
384
	QUALIFIER cq = crt_id_qualifier;
385
	int tq = crt_templ_qualifier;
386
	int fn = in_function_defn;
387
	IDENTIFIER id = DEREF_id(hashid_id(nm));
388
	loc = decl_loc;
389
	decl_loc = crt_loc;
390
	crt_id_qualifier = qual_none;
391
	crt_templ_qualifier = 0;
2 7u83 392
 
6 7u83 393
	/* Declare the temporary object */
394
	if (IS_type_ref(t)) {
395
		t = DEREF_type(type_ref_sub(t));
396
	}
397
	if (in_default_arg) {
398
		/* NOT YET IMPLEMENTED */
399
		crt_namespace = global_namespace;
400
		in_function_defn = 0;
401
	}
402
	t = qualify_type(t, cv_none, 0);
403
	if (IS_type_compound(t)) {
404
		add_error(err, ERR_dcl_init_ref_tmp(t));
405
	}
406
	id = make_object_decl(dspec_temp, t, id, 0);
407
	ds = DEREF_dspec(id_storage(id));
408
	if (temp_storage != dspec_auto) {
409
		/* Set storage class */
410
		ds &= ~dspec_storage;
411
		ds |= temp_storage;
412
	}
413
	if (ds & dspec_auto) {
414
		ds |= dspec_register;
415
	}
416
	COPY_dspec(id_storage(id), ds);
417
	made_temporary = id;
2 7u83 418
 
6 7u83 419
	/* Check initialiser */
420
	if (!is_const_exp(e, -1)) {
421
		if (ds & dspec_auto) {
422
			c = e;
423
			e = NULL_exp;
424
		} else if (ref) {
425
			TYPE s = DEREF_type(exp_type(e));
426
			MAKE_exp_dynamic(s, e, e);
427
			add_error(err, ERR_dcl_init_dynamic());
428
		} else {
429
			TYPE s = DEREF_type(exp_type(e));
430
			c = e;
431
			e = make_null_exp(s);
432
		}
433
	}
434
	if (IS_NULL_exp(d)) {
435
		/* Create destructor */
436
		int du = do_usage;
437
		do_usage = 0;
438
		d = init_default(t, &d, DEFAULT_DESTR, EXTRA_DESTR, err);
439
		do_usage = du;
440
	}
441
	COPY_exp(id_variable_init(id), e);
442
	COPY_exp(id_variable_term(id), d);
443
	define_id(id);
444
 
445
	/* Construct the result expression */
446
	if (!IS_NULL_exp(c)) {
447
		/* Assign initial value */
448
		t = DEREF_type(id_variable_type(id));
449
		MAKE_exp_init(t, id, c, e);
450
		ds = DEREF_dspec(id_storage(id));
451
		ds |= dspec_explicit;
452
		COPY_dspec(id_storage(id), ds);
2 7u83 453
	} else {
6 7u83 454
		e = make_id_exp(id);
2 7u83 455
	}
456
 
6 7u83 457
	/* Define variable */
458
	if (!(ds & dspec_auto)) {
459
		if (!really_in_function_defn && !in_template_decl) {
460
			/* Compile variable definition */
461
			compile_variable(id, 0);
462
		}
2 7u83 463
	}
6 7u83 464
	if (do_dump) {
465
		dump_implicit = 1;
466
		dump_declare(id, &decl_loc, 1);
467
	}
468
	crt_templ_qualifier = tq;
469
	crt_id_qualifier = cq;
470
	in_function_defn = fn;
471
	crt_namespace = ns;
472
	decl_loc = loc;
473
	return (e);
2 7u83 474
}
475
 
476
 
477
/*
478
    IS A VARIABLE ALIASED IN AN EXPRESSION
479
 
480
    This routine checks whether the variable expression d is aliased in
481
    the expression e.
482
*/
483
 
6 7u83 484
static int
485
involves_alias(EXP e, EXP d)
2 7u83 486
{
6 7u83 487
	if (!IS_NULL_exp(d)) {
488
		/* NOT YET IMPLEMENTED */
489
		UNUSED(e);
490
		return (1);
491
	}
492
	return (0);
2 7u83 493
}
494
 
495
 
496
/*
497
    ELIMINATE A TEMPORARY VARIABLE
498
 
499
    This routine is called to eliminate any temporary variables from the
500
    value e which is to be assigned to a variable given by d.  d is the
501
    null expression in a variable initialisation, otherwise care needs
502
    to be taken if d is aliased in e.  Note that creating a temporary and
503
    then removing it ensures that the accesses for the copy constructor
504
    and destructor are checked correctly.
505
*/
506
 
6 7u83 507
EXP
508
remove_temporary(EXP e, EXP d)
2 7u83 509
{
6 7u83 510
	if (!IS_NULL_exp(e)) {
511
		EXP a = NULL_exp;
512
		unsigned tag = TAG_exp(e);
513
		if (tag == exp_constr_tag) {
514
			LIST(EXP)p;
515
			int info = DEREF_int(exp_constr_info(e));
516
			if (info != DEFAULT_COPY) {
517
				return (e);
518
			}
519
			a = DEREF_exp(exp_constr_call(e));
520
			p = DEREF_list(exp_func_id_args(a));
521
			if (IS_NULL_list(p)) {
522
				return (e);
523
			}
524
			p = TAIL_list(p);
525
			if (IS_NULL_list(p)) {
526
				return (e);
527
			}
528
			a = DEREF_exp(HEAD_list(p));
529
			if (!IS_exp_address(a)) {
530
				return (e);
531
			}
532
			a = DEREF_exp(exp_address_arg(a));
533
		} else if (tag == exp_contents_tag) {
534
			a = DEREF_exp(exp_contents_ptr(e));
2 7u83 535
		}
6 7u83 536
		if (!IS_NULL_exp(a) && IS_exp_init(a)) {
537
			/* Check for temporary variable */
538
			IDENTIFIER id = DEREF_id(exp_init_id(a));
539
			if (IS_id_variable(id)) {
540
				DECL_SPEC ds = DEREF_dspec(id_storage(id));
541
				if ((ds & dspec_temp) && !keep_temporary) {
542
					/* Eliminate temporary variable */
543
					EXP b = DEREF_exp(exp_init_arg(a));
544
					if (IS_NULL_exp(b)) {
545
						b = DEREF_exp(id_variable_init(id));
546
					}
547
					if (!involves_alias(b, d)) {
548
						ds |= dspec_ignore;
549
						COPY_dspec(id_storage(id), ds);
550
						return (b);
551
					}
552
				}
553
			}
554
		}
2 7u83 555
	}
6 7u83 556
	return (e);
2 7u83 557
}
558
 
559
 
560
/*
561
    FORCE A REFERENCE INITIALISATION
562
 
563
    This flag forces a reference to be initialised by a less cv-qualified
564
    version of the same type.  Values of greater than 1 can arise in
565
    copy constructors.
566
*/
567
 
6 7u83 568
int init_ref_force = 1;
2 7u83 569
 
570
 
571
/*
572
    INITIALISE A REFERENCE WITH AN LVALUE
573
 
574
    This routine checks whether e is a suitable lvalue initialiser for a
575
    reference to type t.  If so a suitably converted version of e is
576
    returned.  The null expression is returned otherwise.
577
*/
578
 
6 7u83 579
EXP
580
init_ref_lvalue(TYPE t, EXP e, ERROR *err)
2 7u83 581
{
6 7u83 582
	EXP a = NULL_exp;
583
	if (!IS_NULL_exp(e)) {
584
		TYPE s = DEREF_type(exp_type(e));
585
		CV_SPEC qual = DEREF_cv(type_qual(s));
586
		if (qual & cv_lvalue) {
587
			/* Check whether t is reference compatible with s */
588
			unsigned nt = TAG_type(t);
589
			unsigned ns = TAG_type(s);
590
			CV_SPEC cv = cv_compare(t, s);
591
			if (nt == ns) {
592
				if (nt == type_compound_tag) {
593
					/* Check for base class conversions */
594
					if (cv == cv_none || init_ref_force) {
595
						a = cast_class_class(t, e, err, CAST_IMPLICIT, 1);
596
					}
597
				} else if (nt == type_func_tag) {
598
					/* Allow for overloading */
599
					LIST(IDENTIFIER) pids =
600
					    NULL_list(IDENTIFIER);
601
					e = resolve_cast(t, e, err, 1, 0, pids);
602
					if (!IS_exp_member(e)) {
603
						s = DEREF_type(exp_type(e));
604
						if (eq_type_unqual(t, s)) {
605
							if (eq_except(t, s) != 2) {
606
								add_error(err, ERR_except_spec_init());
607
							}
608
							a = e;
609
						}
610
					}
611
				} else {
612
					/* Otherwise check for equal types */
613
					if (eq_type_unqual(t, s)) {
614
						a = e;
615
						if (cv != cv_none) {
616
							add_error(err, ERR_dcl_init_ref_qual(cv));
617
						}
618
					}
619
				}
2 7u83 620
			}
621
		}
6 7u83 622
		if (is_templ_type(s)) {
623
			/* Allow for template parameters */
624
			a = cast_templ_type(t, e, CAST_IMPLICIT);
625
		}
2 7u83 626
	}
6 7u83 627
	return (a);
2 7u83 628
}
629
 
630
 
631
/*
632
    INITIALISE A REFERENCE WITH AN RVALUE
633
 
634
    This routine checks whether e is a suitable rvalue initialiser for a
635
    reference to type t.  It is firstly checked that t is a const reference
636
    and not a reference to function.  If t is reference compatible with the
637
    type of s then a temporary is created to hold the value of e and the
638
    contents of this temporary are returned.  Otherwise the null expression
639
    is returned.
640
*/
641
 
6 7u83 642
static EXP
643
init_ref_rvalue(TYPE t, EXP e, ERROR *err)
2 7u83 644
{
6 7u83 645
	/* Check for reference to functions */
646
	CV_SPEC qual;
647
	unsigned nt = TAG_type(t);
648
	if (nt == type_func_tag) {
649
		add_error(err, ERR_dcl_init_ref_func());
650
		e = make_null_exp(t);
651
		return (e);
652
	}
2 7u83 653
 
6 7u83 654
	/* Check for const references */
655
	qual = find_cv_qual(t);
656
	qual &= cv_qual;
657
	if (qual != cv_const) {
658
		int ok = 0;
659
		if (!IS_NULL_exp(e)) {
660
			TYPE s = DEREF_type(exp_type(e));
661
			if (IS_type_error(s)) {
662
				ok = 1;
663
			}
664
		}
665
		if (!ok) {
666
			add_error(err, ERR_dcl_init_ref_const());
667
		}
2 7u83 668
	}
669
 
6 7u83 670
	/* Check the initialiser */
671
	if (!IS_NULL_exp(e)) {
672
		/* Check whether t is reference compatible with s */
673
		int force = init_ref_force;
674
		TYPE s = DEREF_type(exp_type(e));
675
		unsigned ns = TAG_type(s);
676
		CV_SPEC cv = cv_compare(t, s);
677
		if (nt == ns && (cv == cv_none || force)) {
678
			TYPE r = t;
679
			if (nt == type_compound_tag) {
680
				/* t must be a base class of s */
681
				CLASS_TYPE ct =
682
				    DEREF_ctype(type_compound_defn(t));
683
				CLASS_TYPE cs =
684
				    DEREF_ctype(type_compound_defn(s));
685
				GRAPH gr = find_base_class(cs, ct, 1);
686
				if (IS_NULL_graph(gr)) {
687
					return (NULL_exp);
688
				}
689
				r = qualify_type(s, qual, 0);
690
				/* NOT YET IMPLEMENTED: copy e */
691
			} else {
692
				/* Otherwise check for equal types */
693
				if (!eq_type_unqual(t, s)) {
694
					return (NULL_exp);
695
				}
696
			}
697
			if (cv != cv_none) {
698
				/* Binding from more qualified type */
699
				add_error(err, ERR_dcl_init_ref_qual(cv));
700
			}
701
			e = make_temporary(r, e, NULL_exp, 1, err);
702
			if (nt == type_compound_tag) {
703
				/* Bind temporary to reference */
704
				e = cast_class_class(t, e, err, CAST_IMPLICIT, 1);
705
			}
706
			return (e);
707
		}
2 7u83 708
	}
6 7u83 709
	return (NULL_exp);
2 7u83 710
}
711
 
712
 
713
/*
714
    CREATE A REFERENCE INITIALISER
715
 
716
    This routine creates a reference initialiser of type t out of the
717
    expression e.
718
*/
719
 
6 7u83 720
EXP
721
make_ref_init(TYPE t, EXP e)
2 7u83 722
{
6 7u83 723
	if (!IS_NULL_exp(e)) {
724
		if (IS_exp_op(e)) {
725
			/* Allow for template parameters */
726
			COPY_type(exp_type(e), t);
727
		} else {
728
			TYPE s = t;
729
			unsigned tag = TAG_type(s);
730
			if (tag == type_ref_tag) {
731
				s = DEREF_type(type_ref_sub(s));
732
				tag = TAG_type(s);
733
			}
734
			if (tag == type_token_tag && is_templ_type(s)) {
735
				/* Check again later */
736
				/* EMPTY */
737
			} else {
738
				MAKE_exp_address(t, e, e);
739
			}
740
		}
2 7u83 741
	}
6 7u83 742
	return (e);
2 7u83 743
}
744
 
745
 
746
/*
747
    CREATE A NULL EXPRESSION
748
 
749
    This routine creates a null expression (i.e. all zeros) for the type t.
750
    This is the default value for a non-explicitly initialised variable with
751
    internal or external linkage.
752
*/
753
 
6 7u83 754
EXP
755
make_null_exp(TYPE t)
2 7u83 756
{
6 7u83 757
	EXP e;
758
	switch (TAG_type(t)) {
759
	case type_integer_tag:
760
	case type_enumerate_tag: {
761
		NAT n = small_nat[0];
762
		MAKE_exp_int_lit(t, n, exp_int_lit_tag, e);
763
		break;
2 7u83 764
	}
6 7u83 765
	case type_floating_tag: {
766
		FLOAT f = get_float(t, 0);
767
		MAKE_exp_float_lit(t, f, e);
768
		break;
2 7u83 769
	}
6 7u83 770
	case type_bitfield_tag: {
771
		TYPE s = find_bitfield_type(t);
772
		e = make_null_exp(s);
773
		MAKE_exp_cast(t, (CONV_BITFIELD | CONV_REVERSE), e, e);
774
		break;
2 7u83 775
	}
6 7u83 776
	default:
777
		MAKE_exp_null(t, e);
778
		break;
2 7u83 779
	}
6 7u83 780
	return (e);
2 7u83 781
}
782
 
783
 
784
/*
785
    CREATE A UNIT EXPRESSION
786
 
787
    This routine creates a unit expression (i.e. one) for the type t.
788
*/
789
 
6 7u83 790
EXP
791
make_unit_exp(TYPE t)
2 7u83 792
{
6 7u83 793
	EXP e;
794
	switch (TAG_type(t)) {
795
	case type_integer_tag:
796
	case type_enumerate_tag: {
797
		NAT n = small_nat[1];
798
		MAKE_exp_int_lit(t, n, exp_int_lit_tag, e);
799
		break;
2 7u83 800
	}
6 7u83 801
	case type_floating_tag: {
802
		FLOAT f = get_float(t, 1);
803
		MAKE_exp_float_lit(t, f, e);
804
		break;
2 7u83 805
	}
6 7u83 806
	case type_bitfield_tag: {
807
		TYPE s = find_bitfield_type(t);
808
		e = make_unit_exp(s);
809
		MAKE_exp_cast(t,(CONV_BITFIELD | CONV_REVERSE), e, e);
810
		break;
2 7u83 811
	}
6 7u83 812
	default:
813
		FAIL(Invalid unit type);
814
		MAKE_exp_null(t, e);
815
		break;
2 7u83 816
	}
6 7u83 817
	return (e);
2 7u83 818
}
819
 
820
 
821
/*
822
    IS AN EXPRESSION NULL?
823
 
824
    This routine checks whether the expression e is a null expression.
825
*/
826
 
6 7u83 827
int
828
is_null_exp(EXP e)
2 7u83 829
{
6 7u83 830
	if (IS_NULL_exp(e)) {
831
		return (1);
2 7u83 832
	}
6 7u83 833
	switch (TAG_exp(e)) {
834
	case exp_int_lit_tag: {
835
		NAT n = DEREF_nat(exp_int_lit_nat(e));
836
		return (is_zero_nat(n));
2 7u83 837
	}
6 7u83 838
	case exp_float_lit_tag: {
839
		FLOAT f = DEREF_flt(exp_float_lit_flt(e));
840
		return (is_zero_float(f));
2 7u83 841
	}
6 7u83 842
	case exp_null_tag:
843
	case exp_zero_tag:
844
		return (1);
845
	case exp_aggregate_tag: {
846
		LIST(EXP)p = DEREF_list(exp_aggregate_args(e));
847
		while (!IS_NULL_list(p)) {
848
			EXP a = DEREF_exp(HEAD_list(p));
849
			if (!is_null_exp(a)) {
850
				return (0);
851
			}
852
			p = TAIL_list(p);
853
		}
854
		return (1);
2 7u83 855
	}
6 7u83 856
	case exp_nof_tag: {
857
		EXP a = DEREF_exp(exp_nof_start(e));
858
		EXP b = DEREF_exp(exp_nof_pad(e));
859
		EXP c = DEREF_exp(exp_nof_end(e));
860
		if (!is_null_exp(a)) {
861
			return (0);
862
		}
863
		if (!is_null_exp(b)) {
864
			return (0);
865
		}
866
		return (is_null_exp(c));
2 7u83 867
	}
6 7u83 868
	}
869
	return (0);
2 7u83 870
}
871
 
872
 
873
/*
874
    CREATE AN EMPTY INITIALISER
875
 
876
    This routine creates an empty initialiser for the type t.  Basically
877
    this is the same as make_null_exp except that it also checks for
878
    uninitialised references and const objects.  Also if force is false
879
    then a value is only created if absolutely necessary.
880
*/
881
 
6 7u83 882
EXP
883
init_empty(TYPE t, CV_SPEC cv, int force, ERROR *err)
2 7u83 884
{
6 7u83 885
	EXP e = NULL_exp;
886
	switch (TAG_type(t)) {
887
	case type_array_tag: {
888
		NAT n = DEREF_nat(type_array_size(t));
889
		TYPE s = DEREF_type(type_array_sub(t));
890
		e = init_empty(s, cv, force, err);
891
		if (!IS_NULL_exp(e)) {
892
			MAKE_exp_nof(t, NULL_exp, n, e, NULL_exp, e);
893
		}
894
		break;
2 7u83 895
	}
6 7u83 896
	case type_ref_tag: {
897
		/* References must be initialised */
898
		TYPE s = DEREF_type(type_ref_sub(t));
899
		add_error(err, ERR_dcl_init_ref_none());
900
		if (IS_type_func(s)) {
901
			e = make_null_exp(s);
902
		} else {
903
			e = init_empty(s, cv_none, 1, err);
904
			e = make_temporary(s, e, NULL_exp, 1, err);
905
			e = make_ref_init(t, e);
2 7u83 906
		}
6 7u83 907
		break;
2 7u83 908
	}
6 7u83 909
	case type_compound_tag:
910
		/* Call default constructor for classes */
911
		e = init_default(t, &e, DEFAULT_CONSTR, EXTRA_CONSTR, err);
912
		if (IS_NULL_exp(e)) {
913
			goto default_lab;
2 7u83 914
		}
6 7u83 915
		break;
916
	case type_enumerate_tag:
917
		if (force) {
918
			/* Check for zero enumerator */
919
			ENUM_TYPE et = DEREF_etype(type_enumerate_defn(t));
920
			CLASS_INFO ei = DEREF_cinfo(etype_info(et));
921
			if (!(ei & cinfo_usr_constr)) {
922
				add_error(err, ERR_dcl_enum_zero(t));
923
			}
924
		}
925
		goto default_lab;
926
	case type_token_tag:
927
		if (is_templ_type(t)) {
928
			/* Allow for template parameters */
929
			if (force) {
930
				MAKE_exp_op(t, lex_cast, NULL_exp, NULL_exp, e);
931
			}
932
			break;
933
		}
934
		goto default_lab;
2 7u83 935
	default :
6 7u83 936
default_lab: {
937
		     CV_SPEC qual = find_cv_qual(t);
938
		     qual |= cv;
939
		     if (qual & cv_const) {
940
			     /* Const objects must be initialised */
941
			     add_error(err, ERR_dcl_init_const());
942
		     }
943
		     if (force) {
944
			     e = make_null_exp(t);
945
		     }
946
		     break;
947
	     }
2 7u83 948
	}
6 7u83 949
	return (e);
2 7u83 950
}
951
 
952
 
953
/*
954
    LAST ARRAY INITIALISER SIZE
955
 
956
    This variable is used to hold the number of elements in the last array
957
    initialiser processed.  It is subsequently used to calculate the bound
958
    for an unbounded, but initialised, array type.
959
*/
960
 
6 7u83 961
static NAT last_array_size = NULL_nat;
2 7u83 962
 
963
 
964
/*
965
    IS A TYPE A CHARACTER ARRAY?
966
 
967
    This routine checks whether the type t is an array of 'char', 'signed
968
    char', 'unsigned char' 'wchar_t', and so may be initialised by a single
969
    literal.  It returns 1 for character arrays, 2 for wide character
970
    arrays, and 3 for types compatible with wide character arrays.
971
*/
972
 
6 7u83 973
static int
974
is_char_array(TYPE t)
2 7u83 975
{
6 7u83 976
	if (IS_type_array(t)) {
977
		TYPE s = DEREF_type(type_array_sub(t));
978
		if (check_int_type(s, btype_char)) {
979
			return (1);
980
		}
981
		if (check_int_type(s, btype_wchar_t)) {
982
			return (2);
983
		}
984
		if (!basetype_info[ntype_wchar_t].key) {
985
			s = type_composite(s, type_wchar_t, 1, 0, KILL_err, 0);
986
			if (!IS_NULL_type(s)) {
987
				return (3);
988
			}
989
		}
2 7u83 990
	}
6 7u83 991
	return (0);
2 7u83 992
 
993
}
994
 
995
 
996
/*
997
    PAD AN ARRAY INITIALISER
998
 
999
    This routine pads the array initialiser e, which contains m elements,
1000
    with zeros until it matches the type t.  n gives the bound size of t.
1001
*/
1002
 
6 7u83 1003
static EXP
1004
pad_array(EXP e, NAT m, TYPE t, NAT n, int pad, ERROR *err)
2 7u83 1005
{
6 7u83 1006
	EXP a;
1007
	int eq;
1008
	unsigned long c;
1009
	ERROR err2 = NULL_err;
1010
	TYPE s = DEREF_type(type_array_sub(t));
2 7u83 1011
 
6 7u83 1012
	/* Check for equality */
1013
	eq = compare_nat(n, m);
1014
	if (eq == 0) {
1015
		return (e);
1016
	} else if (eq == 1) {
1017
		if (!pad) {
1018
			return (NULL_exp);
1019
		}
1020
	} else if (eq == -1) {
1021
		/* Too many initialisers */
1022
		if (!pad) {
1023
			return (NULL_exp);
1024
		}
1025
		add_error(err, ERR_dcl_init_aggr_excess(t));
1026
		return (e);
1027
	} else {
1028
		/* Allow for token definitions */
1029
		force_tokdef++;
1030
		eq = eq_nat(n, m);
1031
		force_tokdef--;
1032
		if (eq) {
1033
			return (e);
1034
		}
1035
		if (!pad) {
1036
			return (NULL_exp);
1037
		}
1038
	}
2 7u83 1039
 
6 7u83 1040
	/* Find number of uninitialised elements */
1041
	c = get_nat_value(m);
1042
	if (c != 0) {
1043
		EXP en = calc_nat_value(n, type_size_t);
1044
		EXP em = calc_nat_value(m, type_size_t);
1045
		en = make_minus_exp(en, em);
1046
		if (IS_exp_int_lit(en)) {
1047
			n = DEREF_nat(exp_int_lit_nat(en));
1048
			if (pad && c > 1 && is_calc_nat(n)) {
1049
				/* Warn about potentially dubious
1050
				 * initialisers */
1051
				err2 = ERR_dcl_init_aggr_array_ti(m, t);
1052
			}
1053
			c = get_nat_value(n);
1054
			if (c == 0) {
1055
				return (e);
1056
			}
1057
		}
2 7u83 1058
	}
1059
 
6 7u83 1060
	/* Form initialiser */
1061
	if (IS_NULL_err(err2)) {
1062
		err2 = ERR_dcl_init_aggr_pad(n, t);
2 7u83 1063
	}
6 7u83 1064
	if (!IS_NULL_err(err2)) {
1065
		add_error(err, err2);
1066
	}
1067
	a = init_empty(s, cv_none, 1, err);
1068
	if (!IS_NULL_exp(e) && IS_exp_aggregate(e)) {
1069
		if (c <= ARRAY_PADDING) {
1070
			/* Explicitly pad small arrays */
1071
			LIST(EXP)p = DEREF_list(exp_aggregate_args(e));
1072
			LIST(EXP)q = NULL_list(EXP);
1073
			while (c) {
1074
				CONS_exp(a, q, q);
1075
				c--;
1076
			}
1077
			p = APPEND_list(p, q);
1078
			COPY_list(exp_aggregate_args(e), p);
1079
			COPY_type(exp_type(e), t);
1080
			return (e);
1081
		}
1082
	}
1083
	MAKE_exp_nof(t, e, n, a, NULL_exp, e);
1084
	return (e);
2 7u83 1085
}
1086
 
1087
 
1088
/*
1089
    CHECK AN ASSIGNMENT STYLE ARRAY INITIALISER
1090
 
1091
    This routine checks the assignment style initialiser 't id = e ;' where
1092
    t is an array type.  If arr is true then e is allowed to be another
1093
    array expression of compatible type.  The routine returns the
1094
    initialising expression for id.
1095
*/
1096
 
6 7u83 1097
EXP
1098
init_array(TYPE t, CV_SPEC cv, EXP e, int arr, ERROR *err)
2 7u83 1099
{
6 7u83 1100
	TYPE r = DEREF_type(exp_type(e));
1101
	NAT n = DEREF_nat(type_array_size(t));
1102
	TYPE s = DEREF_type(type_array_sub(t));
1103
	if (IS_type_array(r)) {
1104
		unsigned tag = TAG_exp(e);
1105
		NAT m = DEREF_nat(type_array_size(r));
1106
		TYPE u = DEREF_type(type_array_sub(r));
1107
		if (IS_NULL_nat(n)) {
1108
			n = m;
1109
		}
1110
		last_array_size = m;
2 7u83 1111
 
6 7u83 1112
		/* Check for templates */
1113
		if (in_template_decl) {
1114
			if (is_templ_type(s) || is_templ_type(u)) {
1115
				e = cast_templ_type(t, e, CAST_IMPLICIT);
1116
				return (e);
1117
			}
1118
		}
2 7u83 1119
 
6 7u83 1120
		/* Initialisation by string literal */
1121
		if (tag == exp_string_lit_tag) {
1122
			unsigned long na, ma;
1123
			int ca = is_char_array(t);
1124
			STRING str = DEREF_str(exp_string_lit_str(e));
1125
			unsigned kind = DEREF_unsigned(str_simple_kind(str));
1126
			if (kind & STRING_WIDE) {
1127
				/* Wide string literals */
1128
				if (ca == 2) {
1129
					u = s;
1130
				} else if (ca == 3) {
1131
					if (IS_type_enumerate(s)) {
1132
						/* It could happen ... */
1133
						EXP a;
1134
						ENUM_TYPE es;
1135
						MAKE_exp_value(u, a);
1136
						a = cast_int_int(s, a, err, CAST_IMPLICIT, -1);
1137
						es = DEREF_etype(type_enumerate_defn(s));
1138
						s = DEREF_type(etype_rep(es));
1139
						free_exp(a, 1);
1140
					}
1141
				} else {
1142
					add_error(err,
1143
						  ERR_dcl_init_string_wchar());
1144
				}
1145
			} else {
1146
				/* Normal string literals */
1147
				if (ca == 1) {
1148
					u = s;
1149
				} else {
1150
					add_error(err,
1151
						  ERR_dcl_init_string_char());
1152
				}
1153
			}
1154
			if (!EQ_type(u, s)) {
1155
				/* Deal with invalid cases */
1156
				if (IS_type_integer(s)) {
1157
					/* Cast string to appropriate type */
1158
					MAKE_type_array(cv_none, s, m, r);
1159
					MAKE_exp_string_lit(r, str, e);
1160
				} else {
1161
					/* Don't take any initialisers from the string */
1162
					e = NULL_exp;
1163
				}
1164
			}
1165
 
1166
			/* Check array bound */
1167
			na = get_nat_value(n);
1168
			ma = get_nat_value(m);
1169
			if (na != EXTENDED_MAX) {
1170
				/* Known array bounds */
1171
				if (ma > na) {
1172
					/* Too many initialisers - trim string */
1173
					if (ma == na + 1) {
1174
						add_error(err, ERR_dcl_init_string_zero(t));
1175
					} else {
1176
						add_error(err, ERR_dcl_init_string_excess(t));
1177
					}
1178
					MAKE_exp_string_lit(t, str, e);
1179
				} else if (ma < na) {
1180
					/* Not enough initialisers */
1181
					NAT d = make_nat_value(na - ma);
1182
					add_error(err,
1183
						  ERR_dcl_init_aggr_pad(d, t));
1184
					MAKE_exp_string_lit(t, str, e);
1185
				}
1186
			} else {
1187
				/* Unknown array bounds */
1188
				e = pad_array(e, m, t, n, 1, err);
1189
			}
1190
			return (e);
2 7u83 1191
		}
6 7u83 1192
 
1193
		/* Check array initialisers */
1194
		if (tag == exp_token_tag) {
1195
			/* Allow rvalue array tokens */
1196
			CV_SPEC qual = DEREF_cv(type_qual(r));
1197
			if (!(qual & cv_lvalue)) {
1198
				arr = 2;
1199
			}
2 7u83 1200
		}
6 7u83 1201
		e = convert_reference(e, REF_ASSIGN);
1202
		if (arr == 0) {
1203
			/* Invalid array initialiser */
1204
			report(crt_loc, ERR_dcl_init_aggr_array_bad());
1205
			if (tag == exp_paren_tag) {
1206
				/* Parenthesised initialiser */
1207
				e = init_array(t, cv, e, arr, err);
1208
				return (e);
1209
			}
1210
			arr = 1;
2 7u83 1211
		}
6 7u83 1212
		if (eq_type_unqual(s, u)) {
1213
			if (arr != 2) {
1214
				EXP d;
1215
				d = init_default(r, &e, DEFAULT_COPY,
1216
						 EXTRA_CONSTR, err);
1217
				if (IS_NULL_exp(d)) {
1218
					MAKE_exp_contents(r, e, e);
1219
				} else {
1220
					MAKE_exp_preinc(r, e, d, lex_array, e);
1221
				}
1222
			}
1223
			e = pad_array(e, m, t, n, arr - 1, err);
1224
			if (!IS_NULL_exp(e)) {
1225
				return (e);
1226
			}
2 7u83 1227
		}
6 7u83 1228
		add_error(err, ERR_basic_link_incompat(t, r));
1229
	} else {
1230
		/* Other array initialisations are not allowed */
1231
		report(crt_loc, ERR_dcl_init_aggr_array_bad());
1232
		last_array_size = NULL_nat;
2 7u83 1233
	}
6 7u83 1234
	e = init_empty(t, cv, 1, err);
1235
	return (e);
2 7u83 1236
}
1237
 
1238
 
1239
/*
1240
    REPORT AN INITIALISATION ERROR
1241
 
1242
    In C there is no distinction between conversion by initialisation and
1243
    conversion by assignment.  This routine adds a suitable error message
1244
    to err which says that the conversion cannot be done by initialisation.
1245
*/
1246
 
6 7u83 1247
ERROR
1248
init_error(ERROR err, int init)
2 7u83 1249
{
6 7u83 1250
	ERROR ferr;
2 7u83 1251
#if LANGUAGE_CPP
6 7u83 1252
	ferr = ERR_dcl_init_conv();
1253
	UNUSED(init);
2 7u83 1254
#else
6 7u83 1255
	ferr = ERR_expr_ass_conv();
1256
	if (init) {
1257
		ferr = concat_error(ferr, ERR_dcl_init_assign());
1258
	}
2 7u83 1259
#endif
6 7u83 1260
	err = concat_warning(err, ferr);
1261
	return (err);
2 7u83 1262
}
1263
 
1264
 
1265
/*
1266
    CHECK AN ASSIGNMENT STYLE INITIALISER
1267
 
1268
    This routine checks the assignment style initialiser 'cv t id = e ;'.
1269
    It returns a suitably converted version of e.
1270
*/
1271
 
6 7u83 1272
EXP
1273
init_assign(TYPE t, CV_SPEC cv, EXP e, ERROR *err)
2 7u83 1274
{
6 7u83 1275
    switch (TAG_type(t)) {
1276
	case type_array_tag: {
2 7u83 1277
	    /* Array initialisers */
6 7u83 1278
	    e = init_array(t, cv, e, 0, err);
1279
	    break;
2 7u83 1280
	}
6 7u83 1281
	case type_ref_tag: {
2 7u83 1282
	    /* Reference initialisers */
6 7u83 1283
	    EXP a;
1284
	    TYPE s = DEREF_type(type_ref_sub(t));
1285
	    TYPE r = DEREF_type(exp_type(e));
1286
	    if (IS_type_compound(r)) {
1287
		if (IS_type_compound(s)) {
2 7u83 1288
		    /* Check base class conversions first */
6 7u83 1289
		    a = init_ref_lvalue(s, e, err);
1290
		    if (!IS_NULL_exp(a)) {
1291
			e = make_ref_init(t, a);
1292
			break;
2 7u83 1293
		    }
1294
		}
6 7u83 1295
		a = convert_conv_aux(t, e, err, CAST_IMPLICIT);
1296
		if (!IS_NULL_exp(a)) {
1297
		    e = a;
1298
		    r = DEREF_type(exp_type(e));
1299
		    if (eq_type(r, t)) {
1300
			    break;
1301
		    }
1302
		    e = convert_reference(e, REF_ASSIGN);
2 7u83 1303
		}
1304
	    }
6 7u83 1305
	    a = init_ref_lvalue(s, e, err);
1306
	    if (IS_NULL_exp(a)) {
1307
		a = init_ref_rvalue(s, e, err);
1308
		if (IS_NULL_exp(a)) {
1309
		    e = init_assign(s, cv_none, e, err);
1310
		    if (!IS_exp_null(e)) {
1311
			e = make_temporary(s, e, NULL_exp, 1, err);
2 7u83 1312
		    }
1313
		} else {
6 7u83 1314
		    e = a;
2 7u83 1315
		}
1316
	    } else {
6 7u83 1317
		e = a;
2 7u83 1318
	    }
6 7u83 1319
	    e = make_ref_init(t, e);
1320
	    break;
2 7u83 1321
	}
6 7u83 1322
	case type_compound_tag: {
2 7u83 1323
	    /* Class initialisers */
6 7u83 1324
	    TYPE s = DEREF_type(exp_type(e));
1325
	    if (IS_type_compound(s)) {
2 7u83 1326
		/* Check for base class initialisers */
6 7u83 1327
		CLASS_TYPE cs = DEREF_ctype(type_compound_defn(s));
1328
		CLASS_TYPE ct = DEREF_ctype(type_compound_defn(t));
1329
		GRAPH gr = find_base_class(cs, ct, 1);
1330
		if (!IS_NULL_graph(gr)) {
1331
		    e = init_direct(t, e, err);
1332
		    break;
2 7u83 1333
		}
1334
	    }
6 7u83 1335
	    e = convert_conv(t, e, err, CAST_IMPLICIT);
1336
	    if (!IS_exp_null(e)) {
1337
		e = make_temporary(t, e, NULL_exp, 0, err);
1338
		e = init_direct(t, e, err);
1339
		e = remove_temporary(e, NULL_exp);
2 7u83 1340
	    }
6 7u83 1341
	    break;
2 7u83 1342
	}
6 7u83 1343
	default:
1344
		/* Do conversion by initialisation */
1345
		e = convert_assign(t, e, err);
1346
		break;
2 7u83 1347
    }
6 7u83 1348
    return (e);
2 7u83 1349
}
1350
 
1351
 
1352
/*
1353
    CHECK A CONSTRUCTOR STYLE INITIALISER
1354
 
1355
    This routine checks the constructor style initialiser 't id ( args ) ;'.
1356
    It returns an expression representing the result of converting args to
1357
    type t.
1358
*/
1359
 
6 7u83 1360
EXP
1361
init_constr(TYPE t, LIST(EXP)args, ERROR *err)
2 7u83 1362
{
6 7u83 1363
	EXP e;
1364
	unsigned tag = TAG_type(t);
1365
	switch (tag) {
1366
	case type_ref_tag: {
1367
		/* Reference initialisers */
1368
		EXP a;
1369
		TYPE s = DEREF_type(type_ref_sub(t));
1370
		if (LENGTH_list(args) == 1) {
1371
			a = DEREF_exp(HEAD_list(args));
1372
			a = init_ref_lvalue(s, a, err);
2 7u83 1373
		} else {
6 7u83 1374
			a = NULL_exp;
2 7u83 1375
		}
6 7u83 1376
		if (IS_NULL_exp(a)) {
1377
			a = init_ref_rvalue(s, a, err);
1378
			if (IS_NULL_exp(a)) {
1379
				e = init_constr(s, args, err);
1380
				if (!IS_exp_null(e)) {
1381
					e = make_temporary(s, e, NULL_exp, 1,
1382
							   err);
1383
				}
1384
			} else {
1385
				e = a;
1386
			}
1387
		} else {
1388
			e = a;
1389
		}
1390
		e = make_ref_init(t, e);
1391
		break;
2 7u83 1392
	}
6 7u83 1393
	case type_compound_tag: {
1394
		/* Class constructor initialisers */
1395
		e = convert_constr(t, args, err, CAST_STATIC);
1396
		e = remove_temporary(e, NULL_exp);
1397
		break;
2 7u83 1398
	}
6 7u83 1399
	case type_token_tag: {
1400
		/* Check for template parameters */
1401
		if (is_templ_type(t)) {
1402
			LIST(OFFSET) offs = NULL_list(OFFSET);
1403
			MAKE_exp_initialiser(t, args, offs, 0, 0, 0, e);
1404
			e = cast_templ_type(t, e, CAST_IMPLICIT);
1405
			break;
1406
		}
1407
		goto default_lab;
2 7u83 1408
	}
6 7u83 1409
	default:
1410
default_lab: {
1411
		/* Should have at most one argument otherwise */
1412
		unsigned nargs = LENGTH_list(args);
1413
		if (nargs == 0) {
1414
			e = init_empty(t, cv_none, 1, err);
2 7u83 1415
		} else {
6 7u83 1416
			EXP a = DEREF_exp(HEAD_list(args));
1417
			DESTROY_list(args, SIZE_exp);
1418
			if (nargs > 1) {
1419
				/* Can't have more than one initialiser */
1420
				add_error(err, ERR_dcl_init_ctor(t));
1421
			}
1422
			if (tag == type_array_tag) {
1423
				e = init_array(t, cv_none, a, 0, err);
1424
			} else {
1425
				TYPE s = DEREF_type(exp_type(a));
1426
				if (IS_type_compound(s)) {
1427
					e = convert_conv(t, a, err,
1428
							 CAST_STATIC);
1429
				} else {
1430
					e = convert_assign(t, a, err);
1431
				}
1432
			}
2 7u83 1433
		}
6 7u83 1434
		break;
1435
	     }
1436
	return (e);
2 7u83 1437
	}
1438
}
1439
 
1440
 
1441
/*
1442
    CHECK A DIRECT INITIALISER
1443
 
1444
    This routine checks the direct initialiser 't id ( a ) ;'.  It is
1445
    a special case of init_constr in which there is only one initialiser.
1446
*/
1447
 
6 7u83 1448
EXP
1449
init_direct(TYPE t, EXP a, ERROR *err)
2 7u83 1450
{
6 7u83 1451
	LIST(EXP) args;
1452
	CONS_exp(a, NULL_list(EXP), args);
1453
	a = init_constr(t, args, err);
1454
	return (a);
2 7u83 1455
}
1456
 
1457
 
1458
/*
1459
    FIELD NAME BUFFER
1460
 
1461
    This buffer is used to build up field names for use in error reporting.
1462
*/
1463
 
6 7u83 1464
BUFFER field_buff = NULL_buff;
2 7u83 1465
 
1466
 
1467
/*
1468
    SET LOCATION FROM AN AGGREGATE INITIALISER
1469
 
1470
    Because aggregate initialisers may be spread over several lines each
1471
    component is embedded in a location expression.  This routine gets
1472
    the first element of the aggregate list p, setting the current location
1473
    as appropriate.  It returns the tag of e (ignoring parentheses) via
1474
    ptag.
1475
*/
1476
 
6 7u83 1477
static EXP
1478
get_aggr_elem(LIST(EXP) p, unsigned *ptag)
2 7u83 1479
{
6 7u83 1480
	EXP a = DEREF_exp(HEAD_list(p));
1481
	if (!IS_NULL_exp(a)) {
1482
		if (IS_exp_location(a)) {
1483
			TYPE t;
1484
			DESTROY_exp_location(destroy, t, crt_loc, a, a);
1485
			UNUSED(t);
1486
			COPY_exp(HEAD_list(p), a);
1487
		}
1488
		if (!IS_NULL_exp(a)) {
1489
			EXP b = a;
1490
			unsigned tag = TAG_exp(b);
1491
			while (tag == exp_paren_tag) {
1492
				b = DEREF_exp(exp_paren_arg(b));
1493
				tag = TAG_exp(b);
1494
			}
1495
			*ptag = tag;
1496
		}
2 7u83 1497
	}
6 7u83 1498
	return (a);
2 7u83 1499
}
1500
 
1501
 
1502
/*
1503
    CHECK AN AGGREGATE INITIALISER
1504
 
1505
    This routine checks the aggregate initialiser expression list pointed
1506
    to by r against the type t.  The argument start is 1 to indicate the
1507
    presence of a open brace immediately preceding r and 2 to indicate
1508
    the top-level aggregate.  The result is a structured aggregate
1509
    initialiser expression for compound types t or a suitably converted
1510
    initialiser expression.
1511
*/
1512
 
6 7u83 1513
static EXP
1514
init_aggr_aux(TYPE t, CV_SPEC cv, LIST(EXP) *r, int start, IDENTIFIER id,
1515
	      ERROR *err)
2 7u83 1516
{
6 7u83 1517
	EXP e;
1518
	LIST(EXP) p = *r;
1519
	ERROR cerr = NULL_err;
1520
	CLASS_INFO ci = cinfo_none;
1521
	unsigned tag = TAG_type(t);
1522
	switch (tag) {
1523
	case type_array_tag: {
1524
		/* Array types */
1525
		NAT nc;
1526
		LIST(EXP) a = NULL_list(EXP);
1527
		TYPE s = DEREF_type(type_array_sub(t));
1528
		int str = is_char_array(s);
1529
		BUFFER *bf = &field_buff;
1530
		unsigned boff = (unsigned)(bf->posn - bf->start);
2 7u83 1531
 
6 7u83 1532
		/* Find the array size */
1533
		NAT n = DEREF_nat(type_array_size(t));
1534
		unsigned long m = get_nat_value(n);
1535
		unsigned long c = 0;
2 7u83 1536
 
6 7u83 1537
		/* Report partially bracketed initialisers */
1538
		if (!start) {
1539
			add_error(err, ERR_dcl_init_aggr_partial());
1540
		}
2 7u83 1541
 
6 7u83 1542
		/* Check for string literals in braces */
1543
		if (start && !IS_NULL_list(p)) {
1544
			unsigned et = null_tag;
1545
			e = get_aggr_elem(p, &et);
1546
			if (et == exp_string_lit_tag && is_char_array(t)) {
1547
				e = init_array(t, cv, e, 0, err);
1548
				p = TAIL_list(p);
1549
				break;
1550
			}
2 7u83 1551
		}
1552
 
6 7u83 1553
		/* Loop through at most m initialisers */
1554
		while (!IS_NULL_list(p) && c != m) {
1555
			LIST(EXP) p0 = p;
1556
			ERROR serr = NULL_err;
1557
			unsigned et = null_tag;
2 7u83 1558
 
6 7u83 1559
			/* Build up the field name */
1560
			bfprintf(bf, " [%lu]", c);
2 7u83 1561
 
6 7u83 1562
			/* Check first element of aggregate */
1563
			e = get_aggr_elem(p, &et);
1564
			if (IS_NULL_exp(e)) {
1565
				/* Can occur in template initialisers */
1566
				e = init_empty(s, cv_none, 1, &serr);
1567
				COPY_exp(HEAD_list(p), e);
1568
			}
1569
			if (et == exp_string_lit_tag && str) {
1570
				/* Check for string literals */
1571
				e = init_array(s, cv, e, 0, &serr);
1572
				p = TAIL_list(p);
1573
			} else if (et == exp_aggregate_tag && start) {
1574
				/* Check for sub-aggregates */
1575
				LIST(EXP) q;
1576
				q = DEREF_list(exp_aggregate_args(e));
1577
				e = init_aggr_aux(s, cv, &q, 1, id, &serr);
1578
				p = TAIL_list(p);
1579
			} else {
1580
				/* Otherwise read constituents from p */
1581
				e = init_aggr_aux(s, cv, &p, 0, id, &serr);
1582
			}
2 7u83 1583
 
6 7u83 1584
			/* Report any errors for this member */
1585
			if (!IS_NULL_err(serr)) {
1586
				ERROR ferr = ERR_dcl_init_decl(id, bf->start);
1587
				serr = concat_error(ferr, serr);
1588
				report(crt_loc, serr);
1589
			}
2 7u83 1590
 
6 7u83 1591
			/* Check for dynamic initialisers */
1592
			e = dynamic_init(id, bf->start, e);
2 7u83 1593
 
6 7u83 1594
			/* Restore the field name */
1595
			bf->posn = bf->start + boff;
1596
			bf->posn[0] = 0;
2 7u83 1597
 
6 7u83 1598
			/* Check that some initialisers were used up */
1599
			if (EQ_list(p, p0)) {
1600
				break;
1601
			}
2 7u83 1602
 
6 7u83 1603
			/* Build up the result (in reverse order) */
1604
			CONS_exp(e, a, a);
1605
			c++;
1606
		}
2 7u83 1607
 
6 7u83 1608
		/* Construct the result */
1609
		a = REVERSE_list(a);
1610
		nc = make_nat_value(c);
1611
		MAKE_type_array(cv_none, s, nc, s);
1612
		MAKE_exp_aggregate(s, a, NULL_list(OFFSET), e);
2 7u83 1613
 
6 7u83 1614
		/* Check array size */
1615
		if (!IS_NULL_nat(n)) {
1616
			e = pad_array(e, nc, t, n, 1, err);
1617
		}
1618
		last_array_size = nc;
1619
		break;
2 7u83 1620
	}
6 7u83 1621
	case type_ref_tag: {
1622
		/* Reference types */
1623
		TYPE s = DEREF_type(type_ref_sub(t));
1624
		e = init_ref_rvalue(s, NULL_exp, err);
1625
		if (IS_NULL_exp(e)) {
1626
			e = init_aggr_aux(s, cv, r, start, id, err);
1627
			e = make_temporary(s, e, NULL_exp, 1, err);
1628
			e = make_ref_init(t, e);
1629
		}
1630
		return (e);
2 7u83 1631
	}
6 7u83 1632
	case type_compound_tag: {
1633
		/* Compound types */
1634
		MEMBER mem;
1635
		NAMESPACE ns;
1636
		unsigned long pads = 0;
1637
		LIST(EXP) a = NULL_list(EXP);
1638
		LIST(OFFSET)b = NULL_list(OFFSET);
1639
		CV_SPEC cv1 = (DEREF_cv(type_qual(t)) | cv);
1640
		CLASS_TYPE ct = DEREF_ctype(type_compound_defn(t));
1641
		GRAPH gr = DEREF_graph(ctype_base(ct));
1642
		LIST(GRAPH) br = DEREF_list(graph_tails(gr));
1643
		BUFFER *bf = &field_buff;
1644
		unsigned boff = (unsigned)(bf->posn - bf->start);
2 7u83 1645
 
6 7u83 1646
		/* Check for non-aggregate classes */
1647
		ci = DEREF_cinfo(ctype_info(ct));
1648
		if (!(ci & cinfo_defined)) {
1649
			/* Instantiate template types if necessary */
1650
			complete_class(ct, 1);
1651
			ci = DEREF_cinfo(ctype_info(ct));
2 7u83 1652
		}
6 7u83 1653
		if (!(ci & cinfo_complete)) {
1654
			/* Incomplete types can't be initialised */
1655
			goto incomplete_lab;
1656
		}
1657
		if (ci & cinfo_non_aggregate) {
1658
			/* Types with these properties can't be initialised */
1659
			cerr = class_info(ct, cinfo_non_aggregate, 1);
1660
			if (ci & cinfo_token) {
1661
				goto token_lab;
1662
			}
1663
			if (ci & cinfo_usr_constr) {
1664
				goto non_aggregate_lab;
1665
			}
1666
			add_error(err, cerr);
1667
			add_error(err, ERR_dcl_init_aggr_type(t));
1668
			cerr = NULL_err;
1669
		}
2 7u83 1670
 
6 7u83 1671
		/* Check for non-aggregate initialisations */
1672
		if (!IS_NULL_list(p)) {
1673
			unsigned rank;
1674
			CONVERSION conv;
1675
			unsigned et = null_tag;
1676
			e = get_aggr_elem(p, &et);
1677
			conv.from = DEREF_type(exp_type(e));
1678
			conv.to = t;
1679
			rank = std_convert_seq(&conv, e, 0, 0);
1680
			if (rank != CONV_NONE) {
1681
				goto non_aggregate_lab;
1682
			}
2 7u83 1683
		}
1684
 
6 7u83 1685
		/* Report partially bracketed initialisers */
1686
		if (!start) {
1687
			add_error(err, ERR_dcl_init_aggr_partial());
2 7u83 1688
		}
1689
 
6 7u83 1690
		/* Loop through base classes */
1691
		while (!IS_NULL_list(br)) {
1692
			ERROR serr = NULL_err;
1693
			GRAPH gs = DEREF_graph(HEAD_list(br));
1694
			OFFSET off = DEREF_off(graph_off(gs));
1695
			CLASS_TYPE cs = DEREF_ctype(graph_head(gs));
1696
			TYPE s = make_class_type(cs);
2 7u83 1697
 
6 7u83 1698
			/* Build up field name */
1699
			IDENTIFIER sid = DEREF_id(ctype_name(cs));
1700
			HASHID snm = DEREF_hashid(id_name(sid));
1701
			if (!IS_hashid_anon(snm)) {
1702
				bfputc(bf, '.');
1703
				IGNORE print_hashid(snm, 1, 0, bf, 0);
1704
			}
2 7u83 1705
 
6 7u83 1706
			/* Check next initialiser */
1707
			if (!IS_NULL_list(p)) {
1708
				unsigned et = null_tag;
1709
				e = get_aggr_elem(p, &et);
1710
				if (et == exp_aggregate_tag && start) {
1711
					/* Check for sub-aggregates */
1712
					LIST(EXP) q;
1713
					q = DEREF_list(exp_aggregate_args(e));
1714
					e = init_aggr_aux(s, cv1, &q, 1, id,
1715
							  &serr);
1716
					p = TAIL_list(p);
1717
				} else {
1718
					/* Otherwise read constituents from p */
1719
					e = init_aggr_aux(s, cv1, &p, 0, id,
1720
							  &serr);
1721
				}
1722
			} else {
1723
				e = init_empty(s, cv1, 1, &serr);
1724
				pads++;
1725
			}
2 7u83 1726
 
6 7u83 1727
			/* Report any errors for this field */
1728
			if (!IS_NULL_err(serr)) {
1729
				ERROR ferr = ERR_dcl_init_decl(id, bf->start);
1730
				serr = concat_error(ferr, serr);
1731
				report(crt_loc, serr);
1732
			}
2 7u83 1733
 
6 7u83 1734
			/* Check for dynamic initialisers */
1735
			e = dynamic_init(id, bf->start, e);
2 7u83 1736
 
6 7u83 1737
			/* Restore field name */
1738
			bf->posn = bf->start + boff;
1739
			bf->posn[0] = 0;
1740
 
1741
			/* Build up the result (in reverse order) */
1742
			CONS_exp(e, a, a);
1743
			CONS_off(off, b, b);
1744
			br = TAIL_list(br);
2 7u83 1745
		}
1746
 
6 7u83 1747
		/* Find list of class members */
1748
		ns = DEREF_nspace(ctype_member(ct));
1749
		mem = DEREF_member(nspace_ctype_first(ns));
1750
		mem = next_data_member(mem, 0);
2 7u83 1751
 
6 7u83 1752
		/* Loop through structure members */
1753
		while (!IS_NULL_member(mem)) {
1754
			ERROR serr = NULL_err;
1755
			CV_SPEC cv2 = cv1;
1756
			IDENTIFIER sid = DEREF_id(member_id(mem));
1757
			TYPE s = DEREF_type(id_member_type(sid));
1758
			DECL_SPEC ds = DEREF_dspec(id_storage(sid));
1759
			OFFSET off = DEREF_off(id_member_off(sid));
2 7u83 1760
 
6 7u83 1761
			/* Build up field name */
1762
			HASHID snm = DEREF_hashid(id_name(sid));
1763
			if (!IS_hashid_anon(snm)) {
1764
				bfputc(bf, '.');
1765
				IGNORE print_hashid(snm, 1, 0, bf, 0);
1766
			}
2 7u83 1767
 
6 7u83 1768
			/* Adjust cv-qualifiers */
1769
			if (ds & dspec_mutable)cv2 = cv_none;
2 7u83 1770
 
6 7u83 1771
			/* Check next initialiser */
1772
			if (!IS_NULL_list(p)) {
1773
				unsigned et = null_tag;
1774
				e = get_aggr_elem(p, &et);
1775
				if (et == exp_string_lit_tag &&
1776
				    is_char_array(s)) {
1777
					/* Check for string literals */
1778
					e = init_array(s, cv2, e, 0, &serr);
1779
					p = TAIL_list(p);
1780
				} else if (et == exp_aggregate_tag && start) {
1781
					/* Check for sub-aggregates */
1782
					LIST(EXP) q;
1783
					q = DEREF_list(exp_aggregate_args(e));
1784
					e = init_aggr_aux(s, cv2, &q, 1, id,
1785
							  &serr);
1786
					p = TAIL_list(p);
1787
				} else {
1788
					/* Otherwise read constituents from p */
1789
					e = init_aggr_aux(s, cv2, &p, 0, id,
1790
							  &serr);
1791
				}
1792
			} else {
1793
				/* Pad rest of structure */
1794
				e = init_empty(s, cv2, 1, &serr);
1795
				pads++;
1796
			}
2 7u83 1797
 
6 7u83 1798
			/* Report any errors for this field */
1799
			if (!IS_NULL_err(serr)) {
1800
				ERROR ferr = ERR_dcl_init_decl(id, bf->start);
1801
				serr = concat_error(ferr, serr);
1802
				report(crt_loc, serr);
1803
			}
2 7u83 1804
 
6 7u83 1805
			/* Check for dynamic initialisers */
1806
			e = dynamic_init(id, bf->start, e);
2 7u83 1807
 
6 7u83 1808
			/* Restore field name */
1809
			bf->posn = bf->start + boff;
1810
			bf->posn[0] = 0;
2 7u83 1811
 
6 7u83 1812
			/* Build up the result (in reverse order) */
1813
			CONS_exp(e, a, a);
1814
			CONS_off(off, b, b);
2 7u83 1815
 
6 7u83 1816
			/* Examine next member */
1817
			if (ci & cinfo_union) {
1818
				break;
1819
			}
1820
			mem = DEREF_member(member_next(mem));
1821
			mem = next_data_member(mem, 0);
2 7u83 1822
		}
1823
 
6 7u83 1824
		/* Report padded structures */
1825
		if (pads) {
1826
			NAT n = make_nat_value(pads);
1827
			add_error(err, ERR_dcl_init_aggr_pad(n, t));
1828
		}
2 7u83 1829
 
6 7u83 1830
		/* Construct the result */
1831
		a = REVERSE_list(a);
1832
		b = REVERSE_list(b);
1833
		MAKE_exp_aggregate(t, a, b, e);
1834
		break;
2 7u83 1835
	}
6 7u83 1836
	case type_integer_tag:
1837
	case type_floating_tag:
1838
	case type_enumerate_tag:
1839
	case type_ptr_tag:
1840
	case type_ptr_mem_tag: {
1841
		/* Scalar types */
1842
		if (IS_NULL_list(p)) {
1843
			/* Can't have empty initialiser */
1844
			add_error(err, ERR_dcl_init_aggr_no_scalar());
1845
			e = init_empty(t, cv, 1, err);
2 7u83 1846
		} else {
6 7u83 1847
			/* The first element must be a scalar */
1848
			unsigned et = null_tag;
1849
			e = get_aggr_elem(p, &et);
1850
			if (et == exp_aggregate_tag) {
1851
				LIST(EXP)q;
1852
				q = DEREF_list(exp_aggregate_args(e));
1853
				e = init_aggr_aux(t, cv, &q, 1, id, err);
1854
			} else {
1855
				ERROR ferr = NULL_err;
1856
				if (start == 1) {
1857
					/* Can only have aggregate at top
1858
					 * level */
1859
					ferr = ERR_dcl_init_aggr_nest();
1860
				}
1861
				e = convert_reference(e, REF_ASSIGN);
1862
				e = init_assign(t, cv, e, &ferr);
1863
				if (!IS_NULL_err(ferr)) {
1864
					ferr = init_error(ferr, 1);
1865
					add_error(err, ferr);
1866
				}
2 7u83 1867
			}
6 7u83 1868
			p = TAIL_list(p);
2 7u83 1869
		}
6 7u83 1870
		break;
2 7u83 1871
	}
6 7u83 1872
	case type_token_tag:
1873
token_lab: {
1874
		   /* Tokenised types */
1875
		   TYPE s = expand_type(t, 0);
1876
		   if (EQ_type(s, t)) {
1877
			   goto non_aggregate_lab;
1878
		   }
1879
		   e = init_aggr_aux(s, cv, r, start, id, err);
1880
		   return (e);
1881
	   }
1882
	case type_top_tag:
1883
	case type_bottom_tag:
1884
incomplete_lab:
1885
	   /* Incomplete types */
1886
	   add_error(err, ERR_basic_types_incompl(t));
1887
	   add_error(err, ERR_dcl_init_incompl());
1888
	   e = init_empty(t, cv, 1, err);
1889
	   break;
1890
	default:
1891
non_aggregate_lab:
1892
	   /* Other types */
1893
	   if (start) {
1894
		   /* Can't have aggregate initialisers */
1895
		   ERROR ferr = ERR_dcl_init_decl(id, NULL_string);
1896
		   ferr = concat_error(ferr, cerr);
1897
		   ferr = concat_error(ferr, ERR_dcl_init_aggr_type(t));
1898
		   report(crt_loc, ferr);
1899
		   if (ci & cinfo_usr_constr) {
1900
			   /* Map to constructor call */
1901
			   LIST(EXP) q = p;
1902
			   while (!IS_NULL_list(q)) {
1903
				   unsigned et = null_tag;
1904
				   IGNORE get_aggr_elem(q, &et);
1905
				   q = TAIL_list(q);
1906
			   }
1907
			   e = init_constr(t, p, err);
1908
			   return (e);
1909
		   }
1910
	   } else {
1911
		   if (!IS_NULL_err(cerr)) {
1912
			   destroy_error(cerr, 1);
1913
		   }
1914
	   }
1915
	   if (IS_NULL_list(p)) {
1916
		   /* Empty initialiser list */
1917
		   e = init_empty(t, cv, 1, err);
1918
	   } else {
1919
		   /* Get next initialiser from list */
1920
		   unsigned et = null_tag;
1921
		   e = get_aggr_elem(p, &et);
1922
		   if (et == exp_aggregate_tag) {
1923
			   LIST(EXP) q;
1924
			   q = DEREF_list(exp_aggregate_args(e));
1925
			   e = init_aggr_aux(t, cv, &q, 1, id, err);
1926
		   } else {
1927
			   e = convert_reference(e, REF_ASSIGN);
1928
			   if (tag == type_token_tag && is_zero_exp(e)) {
1929
				   /* Special concession to tokenised types */
1930
				   e = init_empty(t, cv, 1, err);
1931
			   } else {
1932
				   ERROR ferr = NULL_err;
1933
				   e = init_assign(t, cv, e, &ferr);
1934
				   if (!IS_NULL_err(ferr)) {
1935
					   ferr = init_error(ferr, 1);
1936
					   add_error(err, ferr);
1937
				   }
1938
			   }
1939
		   }
1940
		   p = TAIL_list(p);
1941
	   }
1942
	   break;
1943
	}
2 7u83 1944
 
6 7u83 1945
	/* Check for end of initialiser list */
1946
	if (start && !IS_NULL_list(p)) {
1947
		ERROR ferr = ERR_dcl_init_decl(id, NULL_string);
1948
		ferr = concat_error(ferr, ERR_dcl_init_aggr_excess(t));
1949
		report(crt_loc, ferr);
1950
		p = NULL_list(EXP);
1951
	}
1952
	*r = p;
1953
	return (e);
2 7u83 1954
}
1955
 
1956
 
1957
/*
1958
    CHECK AN AGGREGATE INITIALISER
1959
 
1960
    This is the top-level routine for analysing the aggregate initialiser
1961
    e for the object id of type t.  Any errors are added to err.
1962
*/
1963
 
6 7u83 1964
EXP
1965
init_aggregate(TYPE t, EXP e, IDENTIFIER id, ERROR *err)
2 7u83 1966
{
6 7u83 1967
	LOCATION loc;
1968
	LIST(EXP) args = DEREF_list(exp_aggregate_args(e));
1969
	if (IS_NULL_list(args)) {
1970
		/* Report empty aggregate initialisers */
1971
		add_error(err, ERR_dcl_init_aggr_empty());
1972
	}
1973
	bad_crt_loc++;
1974
	loc = crt_loc;
1975
	IGNORE clear_buffer(&field_buff, NIL(FILE));
1976
	e = init_aggr_aux(t, cv_none, &args, 2, id, err);
1977
	crt_loc = loc;
1978
	bad_crt_loc--;
1979
	return (e);
2 7u83 1980
}
1981
 
1982
 
1983
/*
1984
    CHECK ANY INITIALISER
1985
 
1986
    This routine calls init_assign, init_constr or init_aggregate depending
1987
    on the value of e.  If tentative is true then an absent initialiser
1988
    (i.e. when e is null) is treated as a tentative definition.
1989
*/
1990
 
6 7u83 1991
EXP
1992
init_general(TYPE t, EXP e, IDENTIFIER id, int tentative)
2 7u83 1993
{
6 7u83 1994
	/* Check the initialiser */
1995
	ERROR err = NULL_err;
1996
	if (IS_NULL_exp(e)) {
1997
		/* Empty initialisers */
1998
		DECL_SPEC ds = DEREF_dspec(id_storage(id));
1999
		if (ds & dspec_auto) {
2000
			e = init_empty(t, cv_none, 0, &err);
2001
		} else if (tentative) {
2002
			MAKE_exp_zero(t, e);
2 7u83 2003
		} else {
6 7u83 2004
			e = init_empty(t, cv_none, 1, &err);
2 7u83 2005
		}
6 7u83 2006
	} else {
2007
		switch (TAG_exp(e)) {
2008
		case exp_aggregate_tag: {
2009
			/* Aggregate initialisers */
2010
			if (is_templ_type(t)) {
2011
				e = cast_templ_type(t, e, CAST_IMPLICIT);
2012
			} else {
2013
				e = init_aggregate(t, e, id, &err);
2014
			}
2015
			break;
2 7u83 2016
		}
6 7u83 2017
		case exp_nof_tag: {
2018
			/* Padded aggregate initialisers */
2019
			e = DEREF_exp(exp_nof_start(e));
2020
			e = init_general(t, e, id, 0);
2021
			return (e);
2022
		}
2023
		case exp_initialiser_tag: {
2024
			/* Function style initialisers */
2025
			LIST(EXP)args;
2026
			args = DEREF_list(exp_initialiser_args(e));
2027
			args = convert_args(args);
2028
			e = init_constr(t, args, &err);
2029
			if (!IS_NULL_err(err)) {
2030
				err = init_error(err, 1);
2031
			}
2032
			break;
2033
		}
2034
		default: {
2035
			/* Simple initialisers */
2036
			unsigned etag = TAG_exp(e);
2037
			e = convert_reference(e, REF_ASSIGN);
2038
			if (etag == exp_paren_tag && IS_type_array(t)) {
2039
				e = make_paren_exp(e);
2040
			}
2041
			e = init_assign(t, cv_none, e, &err);
2042
			if (!IS_NULL_err(err)) {
2043
				err = init_error(err, 1);
2044
			}
2045
			break;
2046
		}
2047
		}
2 7u83 2048
	}
2049
 
6 7u83 2050
	/* Report any errors */
2051
	if (!IS_NULL_err(err)) {
2052
		ERROR ferr = ERR_dcl_init_decl(id, NULL_string);
2053
		err = concat_error(ferr, err);
2054
		report(crt_loc, err);
2055
	}
2 7u83 2056
 
6 7u83 2057
	/* Check for dynamic initialisers */
2058
	if (!IS_NULL_exp(e)) {
2059
		e = dynamic_init(id, NULL_string, e);
2060
	}
2061
	return (e);
2 7u83 2062
}
2063
 
2064
 
2065
/*
2066
    DESTROY AN OBJECT
2067
 
2068
    This routine creates a destructor for the object id of type t,
2069
    reporting any errors.
2070
*/
2071
 
6 7u83 2072
EXP
2073
destroy_general(TYPE t, IDENTIFIER id)
2 7u83 2074
{
6 7u83 2075
	EXP d = NULL_exp;
2076
	int du = do_usage;
2077
	ERROR err = NULL_err;
2078
	do_usage = 0;
2079
	d = init_default(t, &d, DEFAULT_DESTR, EXTRA_DESTR, &err);
2080
	if (!IS_NULL_err(err)) {
2081
		/* Report any destructor errors */
2082
		ERROR ferr = ERR_dcl_init_decl(id, NULL_string);
2083
		err = concat_error(ferr, err);
2084
		report(decl_loc, err);
2085
	}
2086
	do_usage = du;
2087
	return (d);
2 7u83 2088
}
2089
 
2090
 
2091
/*
2092
    INITIALISE AN OBJECT
2093
 
2094
    This routine initialises the object given by id to the value e.  Note
2095
    that e can be the null expression, indicating that no initialiser is
2096
    given.  The routine 1 if the object is defined, 2 if it is tentatively
2097
    defined, and 0 if it is just declared (see dump_declare).
2098
*/
2099
 
6 7u83 2100
int
2101
init_object(IDENTIFIER id, EXP e)
2 7u83 2102
{
6 7u83 2103
	EXP d;
2104
	TYPE t;
2105
	int def = 0;
2106
	unsigned tag;
2107
	DECL_SPEC ds;
2108
	unsigned itag;
2109
	int ignore = 0;
2 7u83 2110
 
6 7u83 2111
	/* Check for non-object declarations */
2112
	if (IS_NULL_id(id)) {
2113
		return (0);
2 7u83 2114
	}
6 7u83 2115
	itag = TAG_id(id);
2116
	switch (itag) {
2117
	case id_variable_tag:
2118
	case id_stat_member_tag:
2119
		/* Variables and static data members */
2120
		break;
2121
	case id_parameter_tag:
2122
		/* Function parameters */
2123
		if (!in_default_arg) {
2124
			if (!IS_NULL_exp(e)) {
2125
				report(crt_loc, ERR_dcl_fct_default_weak(id));
2126
			}
2127
			return (0);
2128
		}
2129
		break;
2130
	case id_function_tag:
2131
	case id_mem_func_tag:
2132
	case id_stat_mem_func_tag:
2133
		/* Check for function declarations */
2134
		if (!IS_NULL_exp(e)) {
2135
			/* Can't initialise functions */
2136
			report(crt_loc, ERR_dcl_init_func(id));
2137
		}
2 7u83 2138
 
6 7u83 2139
		/* Check previous definition */
2140
		d = DEREF_exp(id_function_etc_defn(id));
2141
		if (!IS_NULL_exp(d)) {
2142
			ds = DEREF_dspec(id_storage(id));
2143
			ds |= dspec_defn;
2144
			COPY_dspec(id_storage(id), ds);
2 7u83 2145
		}
6 7u83 2146
		return (0);
2147
	case id_member_tag:
2148
		/* Check for non-static members (shouldn't be reached) */
2149
		report(crt_loc, ERR_class_mem_init_mem(id));
2150
		return (0);
2151
	default:
2152
		/* The declaration could have been a typedef */
2153
		if (!IS_NULL_exp(e)) {
2154
			/* Can't initialise a typedef */
2155
			report(crt_loc, ERR_dcl_init_typedef(id));
2156
		}
2157
		return (1);
2 7u83 2158
	}
2159
 
6 7u83 2160
	/* Get declaration data */
2161
	t = DEREF_type(id_variable_etc_type(id));
2162
	tag = TAG_type(t);
2163
	ds = DEREF_dspec(id_storage(id));
2164
	temp_storage = (ds & dspec_storage);
2 7u83 2165
 
6 7u83 2166
	/* Check array initialisers */
2167
	if (tag == type_array_tag) {
2168
		int chk = 0;
2169
		if (!IS_NULL_exp(e)) {
2170
			/* Initialisation of array types */
2171
			NAT n = DEREF_nat(type_array_size(t));
2172
			if ((ds & dspec_auto) && itag == id_variable_tag) {
2173
				/* Local aggregate initialiser */
2174
				report(crt_loc, ERR_dcl_init_aggr_auto(id));
2175
			}
2176
			last_array_size = NULL_nat;
2177
			e = init_general(t, e, id, 0);
2178
			if (IS_NULL_nat(n)) {
2179
				/* Complete unbounded arrays */
2180
				n = last_array_size;
2181
				if (!IS_NULL_nat(n)) {
2182
					CV_SPEC qual = DEREF_cv(type_qual(t));
2183
					TYPE s = DEREF_type(type_array_sub(t));
2184
					n = check_array_dim(n);
2185
					MAKE_type_array(qual, s, n, t);
2186
					COPY_type(id_variable_etc_type(id), t);
2187
				}
2188
			}
2189
			ds |= dspec_defn;
2190
			chk = 1;
2191
		} else {
2192
			/* Allow for tentative definitions */
2193
			if (ds & dspec_defn) {
2194
				chk = LANGUAGE_CPP;
2195
			}
2196
		}
2 7u83 2197
 
6 7u83 2198
		/* Can only spot incomplete arrays at this stage */
2199
		if (chk) {
2200
			ERROR err = check_complete(t);
2201
			if (!IS_NULL_err(err)) {
2202
				ERROR err2 = ERR_basic_types_def_incompl(id);
2203
				err = concat_error(err, err2);
2204
				report(decl_loc, err);
2205
			}
2206
		}
2207
	} else {
2208
		/* Other initialisers */
2209
		if (!IS_NULL_exp(e)) {
2210
			if (tag == type_compound_tag) {
2211
				if ((ds & dspec_auto) &&
2212
				    itag == id_variable_tag) {
2213
					/* Local aggregate initialiser */
2214
					report(crt_loc,
2215
					       ERR_dcl_init_aggr_auto(id));
2216
				}
2217
			}
2218
			if (ds & dspec_defn) {
2219
				/* Type already check for completeness */
2220
				/* EMPTY */
2221
			} else if (tag == type_ref_tag) {
2222
				/* Reference types don't need checking */
2223
				/* EMPTY */
2224
			} else {
2225
				/* Type not yet checked for completeness */
2226
				ERROR err = check_complete(t);
2227
				if (!IS_NULL_err(err)) {
2228
					ERROR err2 =
2229
					    ERR_basic_types_def_incompl(id);
2230
					err = concat_error(err, err2);
2231
					report(decl_loc, err);
2232
				}
2233
				ds |= dspec_defn;
2234
			}
2 7u83 2235
 
6 7u83 2236
			/* Examine initialiser */
2237
			e = init_general(t, e, id, 0);
2238
		}
2 7u83 2239
	}
2240
 
6 7u83 2241
	/* Check on definition */
2242
	if (ds & dspec_stat_inline) {
2243
		/* Check for definitions of inline static members */
2244
		if (ds & dspec_defn) {
2245
			if (!IS_NULL_exp(e)) {
2246
				/* Can't give a value in the definition */
2247
				PTR(LOCATION) loc = id_loc(id);
2248
				report(decl_loc,
2249
				       ERR_class_static_data_def(id, loc));
2250
			} else {
2251
				/* Force definition to existing value */
2252
				e = DEREF_exp(id_variable_etc_init(id));
2253
			}
2254
			/* Mark as defined and no longer inline */
2255
			ds &= ~dspec_stat_inline;
2 7u83 2256
		}
2257
	} else {
6 7u83 2258
		/* Provide default definition if necessary */
2259
		if (ds & dspec_defn) {
2260
			def = 1;
2261
			if (IS_NULL_exp(e)) {
2262
				e = init_general(t, e, id, LANGUAGE_C);
2263
				if (!IS_NULL_exp(e) && IS_exp_zero(e)) {
2264
					def = 2;
2265
				}
2266
			}
2267
		}
2 7u83 2268
 
6 7u83 2269
		/* Check previous definition */
2270
		d = DEREF_exp(id_variable_etc_init(id));
2271
		if (!IS_NULL_exp(d)) {
2272
			if (!IS_NULL_exp(e)) {
2273
				/* Defined twice */
2274
				ERROR err;
2275
				PTR(LOCATION) loc = id_loc(id);
2276
				if (def == 2) {
2277
					/* This definition is tentative */
2278
					err = ERR_basic_odr_tentative(id, loc);
2279
					ignore = 1;
2280
				} else if (IS_exp_zero(d)) {
2281
					/* Previous definition was tentative */
2282
					err = ERR_basic_odr_tentative(id, loc);
2283
				} else {
2284
					/* Neither definition is tentative */
2285
					err = ERR_basic_odr_def(id, loc);
2286
				}
2287
				report(decl_loc, err);
2288
			}
2289
			ds |= dspec_defn;
2290
		}
2 7u83 2291
	}
2292
 
6 7u83 2293
	/* Update declaration data */
2294
	COPY_type(id_variable_etc_type(id), t);
2295
	COPY_dspec(id_storage(id), ds);
2296
	if (!IS_NULL_exp(e)) {
2297
		/* Define object */
2298
		if (!ignore) {
2299
			if ((ds & dspec_auto) && (ds & dspec_used)) {
2300
				/* Local variable initialised in terms of
2301
				 * itself */
2302
				TYPE s = DEREF_type(exp_type(e));
2303
				MAKE_exp_dynamic(s, e, e);
2304
			}
2305
			if (itag != id_parameter_tag) {
2306
				e = check_init(e);
2307
			}
2308
			COPY_exp(id_variable_etc_init(id), e);
2309
			COPY_loc(id_loc(id), decl_loc);
2310
			define_id(id);
2 7u83 2311
		}
6 7u83 2312
		if (ds & dspec_linkage) {
2313
			/* Check enclosing namespace */
2314
			NAMESPACE ns = DEREF_nspace(id_parent(id));
2315
			check_decl_nspace(id, ns, 1, crt_namespace);
2 7u83 2316
		}
6 7u83 2317
		if (def == 0) {
2318
			def = 1;
2319
		}
2 7u83 2320
	}
6 7u83 2321
	if (def) {
2322
		/* Create destructor */
2323
		EXP d1 = DEREF_exp(id_variable_etc_term(id));
2324
		d = destroy_general(t, id);
2325
		if (!IS_NULL_exp(d1) && IS_exp_paren(d1)) {
2326
			/* Preserve parenthesised type information */
2327
			TYPE t1 = DEREF_type(exp_type(d1));
2328
			MAKE_exp_paren(t1, d, d);
2329
		}
2330
		COPY_exp(id_variable_etc_term(id), d);
2 7u83 2331
	}
6 7u83 2332
	if (!IS_NULL_id(unify_id_pending)) {
2333
		/* Deal with any pending identifiers */
2334
		IGNORE unify_id(unify_id_pending, id, 1);
2 7u83 2335
	}
6 7u83 2336
	temp_storage = dspec_auto;
2337
	if (def && !(ds & dspec_auto)) {
2338
		if (!really_in_function_defn && !in_template_decl) {
2339
			/* Compile variable definition */
2340
			compile_variable(id, 0);
2 7u83 2341
		}
2342
	}
6 7u83 2343
	return (def);
2 7u83 2344
}
2345
 
2346
 
2347
/*
2348
    INITIALISE A FUNCTION PARAMETER
2349
 
2350
    This routine initialises the function parameter id with the expression
2351
    e (i.e. sets up a default argument value).  Note that the class
2352
    definition case, where e is initially just skipped over, is dealt
2353
    with here.
2354
*/
2355
 
6 7u83 2356
void
2357
init_param(IDENTIFIER id, EXP e)
2 7u83 2358
{
6 7u83 2359
	if (!IS_NULL_exp(e)) {
2360
		if (!IS_NULL_id(id)) {
2361
			if (IS_id_token(id)) {
2362
				/* Template parameter */
2363
				init_exp_param(id, e);
2364
			} else {
2365
				/* Function parameter */
2366
				if (IS_exp_uncompiled(e)) {
2367
					if (in_class_defn) {
2368
						LIST(IDENTIFIER) ft;
2369
						CLASS_TYPE ct = crt_class;
2370
						ft = DEREF_list(ctype_nest(ct));
2371
						CONS_id(id, ft, ft);
2372
						COPY_list(ctype_nest(ct), ft);
2373
					}
2374
					COPY_exp(id_parameter_init(id), e);
2375
				} else {
2376
					in_default_arg++;
2377
					IGNORE init_object(id, e);
2378
					in_default_arg--;
2379
				}
2380
			}
2 7u83 2381
		}
2382
	}
6 7u83 2383
	return;
2 7u83 2384
}
2385
 
2386
 
2387
/*
2388
    INITIALISE A CLASS MEMBER
2389
 
2390
    This routine initialises the class member id with the expression e
2391
    (which since it is a constant-expression has already undergone the
2392
    appropriate operand conversions).  Note that the pure specifier is
2393
    indistinguishible syntactically from a member initialiser, and so is
2394
    only spotted at this stage.  See above for inline definitions of static
2395
    data members.  The routine returns 1 for a definition and 0 for a
2396
    declaration (see dump_declare).
2397
*/
2398
 
6 7u83 2399
int
2400
init_member(IDENTIFIER id, EXP e)
2 7u83 2401
{
6 7u83 2402
	int def;
2403
	unsigned tag;
2 7u83 2404
 
6 7u83 2405
	/* Check for definitions */
2406
	if (IS_NULL_id(id)) {
2407
		return (0);
2 7u83 2408
	}
6 7u83 2409
	tag = TAG_id(id);
2410
	if (have_access_decl) {
2411
		def = 2;
2412
		have_access_decl = 0;
2413
	} else {
2414
		switch (tag) {
2415
		case id_stat_member_tag:
2416
		case id_mem_func_tag:
2417
		case id_stat_mem_func_tag:
2418
			def = 0;
2419
			break;
2420
		default:
2421
			def = 1;
2422
			break;
2423
		}
2424
	}
2 7u83 2425
 
6 7u83 2426
	/* Check for function declarations */
2427
	if (IS_NULL_exp(e)) {
2428
		if (tag == id_mem_func_tag || tag == id_stat_mem_func_tag) {
2429
			if (really_in_function_defn) {
2430
				NAMESPACE ns = DEREF_nspace(id_parent(id));
2431
				if (EQ_nspace(ns, crt_namespace)) {
2432
					DECL_SPEC ds, mds;
2433
					ds = DEREF_dspec(id_storage(id));
2434
					mds = (dspec_inherit | dspec_implicit |
2435
					       dspec_defn);
2436
					if (!(ds & mds)) {
2437
						/* Local functions should be
2438
						 * defined */
2439
						report(decl_loc, ERR_class_local_func(id));
2440
					}
2441
				}
2442
			}
2 7u83 2443
		}
6 7u83 2444
		return (def);
2 7u83 2445
	}
2446
 
6 7u83 2447
	/* Check the various types of member */
2448
	switch (tag) {
2449
	case id_stat_member_tag: {
2450
		/* Static data members may be initialised */
2451
		DECL_SPEC ds;
2452
		TYPE t = DEREF_type(id_stat_member_type(id));
2453
		CV_SPEC cv = find_cv_qual(t);
2454
		switch (TAG_type(t)) {
2455
		case type_integer_tag:
2456
		case type_enumerate_tag: {
2457
			ERROR err = NULL_err;
2458
			IGNORE make_nat_exp(e, &err);
2459
			if (!IS_NULL_err(err)) {
2460
				/* Initialiser should be a constant
2461
				 * expression */
2462
				ERROR err2 = ERR_class_mem_init_const();
2463
				err = concat_error(err, err2);
2464
				report(crt_loc, err);
2465
			}
2466
			break;
2 7u83 2467
		}
6 7u83 2468
		case type_token_tag: {
2469
			if (!is_templ_type(t)) {
2470
				goto default_lab;
2471
			}
2472
			break;
2 7u83 2473
		}
6 7u83 2474
		default:
2475
default_lab:
2476
			/* Only integral types allowed */
2477
			report(crt_loc, ERR_class_static_data_init(id, t));
2478
			break;
2 7u83 2479
		}
6 7u83 2480
		if (cv != (cv_const | cv_lvalue)) {
2481
			/* Only const types allowed */
2482
			report(crt_loc, ERR_class_static_data_const(id, t));
2483
		}
2484
		e = init_general(t, e, id, 0);
2485
		e = dynamic_init(id, NULL_string, e);
2486
		e = check_init(e);
2487
		COPY_exp(id_stat_member_init(id), e);
2 7u83 2488
 
6 7u83 2489
		/* Mark inline member definition */
2490
		ds = DEREF_dspec(id_storage(id));
2491
		ds |= dspec_stat_inline;
2492
		COPY_dspec(id_storage(id), ds);
2493
		break;
2 7u83 2494
	}
6 7u83 2495
	case id_mem_func_tag:
2496
	case id_stat_mem_func_tag: {
2497
		/* Check for pure specifiers */
2498
		if (is_zero_exp(e)) {
2499
			DECL_SPEC ds = DEREF_dspec(id_storage(id));
2500
			if (ds & dspec_virtual) {
2501
				CLASS_TYPE ct = crt_class;
2502
				CLASS_INFO ci = DEREF_cinfo(ctype_info(ct));
2 7u83 2503
 
6 7u83 2504
				/* Pure specifier should be precisely '0' */
2505
				int tok = last_lex_token;
2506
				if (tok != lex_integer_Hexp ||
2507
				    is_literal(e)!= 2) {
2508
					report(crt_loc,
2509
					       ERR_class_abstract_zero());
2510
				}
2 7u83 2511
 
6 7u83 2512
				/* Mark class as abstract */
2513
				ci |= cinfo_abstract;
2514
				COPY_cinfo(ctype_info(ct), ci);
2 7u83 2515
 
6 7u83 2516
				/* Mark function as pure */
2517
				ds |= dspec_pure;
2518
				COPY_dspec(id_storage(id), ds);
2519
			} else {
2520
				/* Only virtual functions can be pure */
2521
				report(crt_loc, ERR_class_abstract_virt());
2522
			}
2 7u83 2523
		} else {
6 7u83 2524
			/* Can't initialise functions otherwise */
2525
			report(crt_loc, ERR_dcl_init_func(id));
2 7u83 2526
		}
6 7u83 2527
		break;
2 7u83 2528
	}
6 7u83 2529
	case id_member_tag: {
2530
		/* Can't initialise non-static members */
2531
		report(crt_loc, ERR_class_mem_init_mem(id));
2532
		break;
2 7u83 2533
	}
6 7u83 2534
	default:
2535
		/* Can't initialise a typedef */
2536
		report(crt_loc, ERR_dcl_init_typedef(id));
2537
		break;
2 7u83 2538
	}
6 7u83 2539
	return (def);
2 7u83 2540
}
2541
 
2542
 
2543
/*
2544
    ALLOW A TOKEN AS AN INITIALISER
2545
 
2546
    This routine enables the token id as an initialiser.
2547
*/
2548
 
6 7u83 2549
void
2550
allow_initialiser(IDENTIFIER id)
2 7u83 2551
{
6 7u83 2552
	id = find_token(id);
2553
	if (IS_id_token(id)) {
2554
		/* NOT YET IMPLEMENTED */
2555
		/* EMPTY */
2556
	} else {
2557
		report(crt_loc, ERR_token_undecl(id));
2558
	}
2559
	return;
2 7u83 2560
}
2561
 
2562
 
2563
/*
2564
    INITIALISE THE FIELD BUFFER
2565
 
2566
    This routine initialises the field buffer.
2567
*/
2568
 
6 7u83 2569
void
2570
init_initialise(void)
2 7u83 2571
{
6 7u83 2572
	field_buff.posn = extend_buffer(&field_buff, field_buff.posn);
2573
	return;
2 7u83 2574
}