Subversion Repositories tendra.SVN

Rev

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

Rev Author Line No. Line
2 7u83 1
/*
7 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
7 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:-
7 7u83 42
 
2 7u83 43
        (1) Its Recipients shall ensure that this Notice is
44
        reproduced upon any copies or amended versions of it;
7 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;
7 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;
7 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 "hashid_ops.h"
65
#include "id_ops.h"
66
#include "loc_ext.h"
67
#include "member_ops.h"
68
#include "nspace_ops.h"
69
#include "off_ops.h"
70
#include "type_ops.h"
71
#include "error.h"
72
#include "catalog.h"
73
#include "option.h"
74
#include "access.h"
75
#include "allocate.h"
76
#include "basetype.h"
77
#include "capsule.h"
78
#include "chktype.h"
79
#include "class.h"
80
#include "compile.h"
81
#include "construct.h"
82
#include "declare.h"
83
#include "derive.h"
84
#include "dump.h"
85
#include "exception.h"
86
#include "file.h"
87
#include "function.h"
88
#include "hash.h"
89
#include "identifier.h"
90
#include "initialise.h"
91
#include "instance.h"
92
#include "inttype.h"
93
#include "namespace.h"
94
#include "operator.h"
95
#include "overload.h"
96
#include "predict.h"
97
#include "preproc.h"
98
#include "redeclare.h"
99
#include "syntax.h"
100
#include "template.h"
101
#include "tokdef.h"
102
#include "token.h"
103
#include "virtual.h"
104
 
105
 
106
/*
107
    DECLARATION LOCATION
108
 
109
    This variable is used to record the location of the current declaration.
110
    This is primarily so that the location of a declaration can be set to
111
    the location of the declarator rather than the end of the corresponding
112
    initialiser.
113
*/
114
 
7 7u83 115
LOCATION decl_loc = NULL_loc;
116
int is_redeclared = 0;
2 7u83 117
 
118
 
119
/*
120
    DEFAULT LINKAGE FOR INLINE FUNCTIONS AND CONST OBJECTS
121
 
122
    These variables give the default linkages for inline functions and
123
    const objects and the default cv-qualifiers for external objects.
124
*/
125
 
7 7u83 126
DECL_SPEC inline_linkage = dspec_static;
127
DECL_SPEC const_linkage = dspec_static;
128
CV_SPEC cv_extern = cv_none;
2 7u83 129
 
130
 
131
/*
132
    DUMMY EMPTY DECLARATION SPECIFIER
133
 
134
    The value dspec_empty is used during the processing of declarations
135
    to mark any declaration specifier which does not contain an explicit
136
    specifier.  The value dspec_nonempty gives those declaration
137
    specifiers which constitute an explicit specifier.
138
*/
139
 
140
#define dspec_empty		dspec_pure
141
#define dspec_nonempty		dspec_keyword
142
 
143
 
144
/*
145
    COMPLETE A DECLARATION SPECIFIER
146
 
147
    This routine completes the declaration specifier given by the
148
    specifiers ds, the type t and the cv-qualifier cv.  If these are
149
    all empty then the result is marked using dspec_empty.  The special
150
    case 'extern "LANG" typedef' is checked.
151
*/
152
 
7 7u83 153
DECL_SPEC
154
complete_dspec(DECL_SPEC ds, BASE_TYPE bt, TYPE t, CV_SPEC cv)
2 7u83 155
{
7 7u83 156
	DECL_SPEC key = (ds & dspec_nonempty);
157
	if (key || bt || !IS_NULL_type(t) || cv) {
158
		/* Have a declaration specifier */
159
		if (ds & dspec_c) {
160
			/* Have a linkage specification */
161
			if (ds & dspec_typedef) {
162
				ds &= ~dspec_extern;
163
			}
164
			ds &= ~dspec_c;
165
		}
166
	} else {
167
		ds |= dspec_empty;
2 7u83 168
	}
7 7u83 169
	return (ds);
2 7u83 170
}
171
 
172
 
173
/*
174
    CHECK INFERRED OBJECT TYPES
175
 
176
    This routine checks the declaration specifiers ds and the type *p for
177
    inferred types and empty specifier lists.  It is used in object,
178
    parameter and class member declarations.
179
*/
180
 
7 7u83 181
static DECL_SPEC
182
check_inferred_type(DECL_SPEC ds, TYPE *p, int mem)
2 7u83 183
{
7 7u83 184
	int infer;
185
	TYPE t = *p;
186
	int empty = 0;
187
	ERROR err = NULL_err;
2 7u83 188
 
7 7u83 189
	/* Report if there are no declaration specifiers */
190
	if (ds & dspec_empty) {
191
		if (mem) {
192
			err = ERR_class_mem_ds_empty();
193
		} else {
194
			err = ERR_dcl_dcl_ds_empty();
195
		}
196
		ds &= ~dspec_empty;
197
		empty = 1;
2 7u83 198
	}
199
 
7 7u83 200
	/* Check on inferred types */
201
	infer = is_type_inferred(t);
202
	if (infer != INFERRED_NOT) {
203
		ERROR err2;
204
		t = clean_inferred_type(t);
205
		if (empty) {
206
			err2 = ERR_dcl_type_infer(t);
207
		} else {
208
			err2 = report_inferred_type(t, infer);
209
		}
210
		err = concat_error(err, err2);
211
		*p = t;
2 7u83 212
	}
7 7u83 213
	if (!IS_NULL_err(err)) {
214
		report(crt_loc, err);
215
	}
216
	return (ds);
2 7u83 217
}
218
 
219
 
220
/*
221
    CHECK INFERRED FUNCTION TYPES
222
 
223
    This routine checks the declaration specifiers ds and the function
224
    type t for inferred types and empty specifier lists.  It is used in
225
    function declarations and definitions (as indicated by def).
226
*/
227
 
7 7u83 228
static DECL_SPEC
229
check_func_type(DECL_SPEC ds, TYPE t, int def, int chk, int mem)
2 7u83 230
{
7 7u83 231
	int empty = 0;
232
	ERROR err = NULL_err;
2 7u83 233
 
7 7u83 234
	/* Report if there are no declaration specifiers */
235
	if (ds & dspec_empty) {
236
		if (mem) {
237
			err = ERR_class_mem_ds_empty();
238
		} else if (def) {
239
			err = ERR_dcl_dcl_ds_func();
240
		} else {
241
			err = ERR_dcl_dcl_ds_empty();
242
		}
243
		ds &= ~dspec_empty;
244
		empty = 1;
2 7u83 245
	}
246
 
7 7u83 247
	/* Check for template types */
248
	while (IS_type_templ(t)) {
249
		ds |= dspec_template;
250
		t = DEREF_type(type_templ_defn(t));
251
	}
2 7u83 252
 
7 7u83 253
	/* Check the return type */
254
	if (chk) {
255
		TYPE r = DEREF_type(type_func_ret(t));
256
		int infer = is_type_inferred(r);
257
		if (infer != INFERRED_NOT) {
258
			ERROR err2;
259
			r = clean_inferred_type(r);
260
			if (empty) {
261
				err2 = ERR_dcl_type_infer(r);
262
			} else {
263
				err2 = report_inferred_type(r, infer);
264
			}
265
			err = concat_error(err, err2);
266
			COPY_type(type_func_ret(t), r);
267
		}
2 7u83 268
	}
7 7u83 269
	if (!IS_NULL_err(err)) {
270
		report(crt_loc, err);
271
	}
272
	return (ds);
2 7u83 273
}
274
 
275
 
276
/*
277
    SHIFT A STORAGE CLASS
278
 
279
    This macro is used to shift a storage class specifier into a more
280
    sensible range.
281
*/
282
 
7 7u83 283
#define DSPEC_STORAGE(A)	((A) >> 6)
2 7u83 284
 
285
 
286
/*
287
    CHECK STORAGE CLASS SPECIFIERS
288
 
289
    This routine extracts the storage class specifiers from the declaration
290
    specifiers ds in the context given by loc.  It returns a valid storage
291
    class specifier.
292
*/
293
 
7 7u83 294
static DECL_SPEC
295
check_storage(DECL_SPEC ds, int loc, IDENTIFIER id)
2 7u83 296
{
7 7u83 297
	DECL_SPEC st = (ds & dspec_storage);
2 7u83 298
 
7 7u83 299
	/* Check on storage class */
300
switch_label:
301
	switch (DSPEC_STORAGE(st)) {
302
	case DSPEC_STORAGE(dspec_none): {
2 7u83 303
		/* No storage class given */
7 7u83 304
		break;
305
	}
306
	case DSPEC_STORAGE(dspec_auto):
307
	case DSPEC_STORAGE(dspec_register): {
2 7u83 308
		/* Deal with auto and register */
7 7u83 309
		switch (loc) {
310
		case CONTEXT_OBJECT: {
2 7u83 311
			/* Objects declared in a block are alright */
7 7u83 312
			if (!in_function_defn) {
313
				goto bad_auto_lab;
314
			}
315
			break;
316
		}
317
		case CONTEXT_FUNCTION: {
2 7u83 318
			/* Functions can't be auto */
7 7u83 319
			if (!in_function_defn) {
320
				goto bad_auto_lab;
321
			}
322
			report(crt_loc, ERR_dcl_stc_auto_func(st));
323
			st = dspec_none;
324
			break;
325
		}
326
		case CONTEXT_PARAMETER:
327
		case CONTEXT_WEAK_PARAM: {
2 7u83 328
			/* Function parameters are alright */
7 7u83 329
			if (st == dspec_auto) {
330
				/* Can't have auto parameters in C */
331
				report(crt_loc, ERR_dcl_stc_auto_par());
2 7u83 332
			}
7 7u83 333
			break;
334
		}
335
		case CONTEXT_TEMPL_PARAM: {
2 7u83 336
			/* Template parameters can't have storage class */
7 7u83 337
			report(crt_loc, ERR_temp_param_dcl_stc(st));
338
			st = dspec_none;
339
			break;
340
		}
341
		default:
342
bad_auto_lab:
2 7u83 343
			/* Anything outside a block can't be auto */
7 7u83 344
			report(crt_loc, ERR_dcl_stc_auto_bad(st));
345
			st = dspec_none;
346
			break;
2 7u83 347
		}
7 7u83 348
		break;
349
	}
350
	case DSPEC_STORAGE(dspec_static): {
2 7u83 351
		/* Deal with static */
7 7u83 352
		switch (loc) {
353
		case CONTEXT_PARAMETER:
354
		case CONTEXT_WEAK_PARAM: {
2 7u83 355
			/* Function parameters can't be static */
7 7u83 356
			report(crt_loc, ERR_dcl_stc_param(st));
357
			st = dspec_none;
358
			break;
359
		}
360
		case CONTEXT_TEMPL_PARAM: {
2 7u83 361
			/* Template parameters can't have storage class */
7 7u83 362
			report(crt_loc, ERR_temp_param_dcl_stc(st));
363
			st = dspec_none;
364
			break;
2 7u83 365
		}
7 7u83 366
		}
367
		break;
368
	}
369
	case DSPEC_STORAGE(dspec_extern): {
2 7u83 370
		/* Deal with extern */
7 7u83 371
		switch (loc) {
372
		case CONTEXT_OBJECT:
373
		case CONTEXT_FUNCTION: {
2 7u83 374
			/* Objects and functions can be extern */
7 7u83 375
			if (!IS_NULL_id(id)) {
376
				switch (TAG_id(id)) {
377
				case id_member_tag:
378
				case id_mem_func_tag:
379
				case id_stat_member_tag:
380
				case id_stat_mem_func_tag: {
381
					/* But not class members */
382
					ERROR err = ERR_dcl_stc_ext_mem();
383
					report(crt_loc, err);
384
					break;
2 7u83 385
				}
7 7u83 386
				}
2 7u83 387
			}
7 7u83 388
			break;
389
		}
390
		case CONTEXT_PARAMETER:
391
		case CONTEXT_WEAK_PARAM: {
2 7u83 392
			/* Function parameters can't be extern */
7 7u83 393
			report(crt_loc, ERR_dcl_stc_param(st));
394
			st = dspec_none;
395
			break;
396
		}
397
		case CONTEXT_TEMPL_PARAM: {
2 7u83 398
			/* Template parameters can't have storage class */
7 7u83 399
			report(crt_loc, ERR_temp_param_dcl_stc(st));
400
			st = dspec_none;
401
			break;
402
		}
403
		default:
2 7u83 404
			/* Class members can't be extern */
7 7u83 405
			report(crt_loc, ERR_dcl_stc_ext_mem());
406
			st = dspec_none;
407
			break;
2 7u83 408
		}
7 7u83 409
		break;
410
	}
411
	case DSPEC_STORAGE(dspec_mutable): {
2 7u83 412
		/* Deal with mutable */
7 7u83 413
		if (loc != CONTEXT_MEMBER) {
414
			/* Only data members can be mutable */
415
			report(crt_loc, ERR_dcl_stc_mut_bad());
416
			st = dspec_none;
2 7u83 417
		}
7 7u83 418
		break;
419
	}
420
	default: {
2 7u83 421
		/* More than one storage class - select one */
7 7u83 422
		DECL_SPEC nst = dspec_static;
423
		while (!(st & nst)) {
424
			ASSERT(nst != dspec_none);
425
			nst <<= 1;
2 7u83 426
		}
7 7u83 427
		report(crt_loc, ERR_dcl_stc_dup(st, nst));
428
		st = nst;
429
		goto switch_label;
2 7u83 430
	}
7 7u83 431
	}
432
	return (st);
2 7u83 433
}
434
 
435
 
436
/*
437
    CHECK STORAGE CLASS SPECIFIERS
438
 
439
    This routine extracts the function specifiers (plus friend specifiers)
440
    from the declaration specifiers ds in the context given by loc (as
441
    above).  It returns a valid combination of function and friend
442
    specifiers.
443
*/
444
 
7 7u83 445
static DECL_SPEC
446
check_func_spec(DECL_SPEC ds, int loc)
2 7u83 447
{
7 7u83 448
	DECL_SPEC fn = dspec_none;
2 7u83 449
 
7 7u83 450
	/* Only functions can be inline */
451
	if (ds & dspec_inline) {
452
		if (loc == CONTEXT_FUNCTION || loc == CONTEXT_FUNC_MEMBER) {
453
			fn |= dspec_inline;
454
		} else {
455
			report(crt_loc, ERR_dcl_fct_spec_inline_bad());
456
		}
2 7u83 457
	}
458
 
7 7u83 459
	/* Only function members can be virtual */
460
	if (ds & dspec_virtual) {
461
		if (loc == CONTEXT_FUNC_MEMBER) {
462
			fn |= dspec_virtual;
463
		} else {
464
			report(crt_loc, ERR_dcl_fct_spec_virtual());
465
		}
2 7u83 466
	}
467
 
7 7u83 468
	/* Only function members can be explicit */
469
	if (ds & dspec_explicit) {
470
		if (loc == CONTEXT_FUNC_MEMBER) {
471
			fn |= dspec_explicit;
472
		} else {
473
			report(crt_loc, ERR_dcl_fct_spec_explicit());
474
		}
2 7u83 475
	}
476
 
7 7u83 477
	/* Only functions declared in a class can be friends */
478
	if (ds & dspec_friend) {
479
		if (loc == CONTEXT_FUNCTION && in_class_defn) {
480
			/* Don't add to specifier list */
481
			/* EMPTY */
482
		} else if (in_class_defn) {
483
			report(crt_loc, ERR_class_friend_decl());
484
		} else {
485
			report(crt_loc, ERR_dcl_friend_class());
486
		}
2 7u83 487
	}
488
 
7 7u83 489
	/* Allow for function discarding */
490
	if (loc == CONTEXT_FUNCTION || loc == CONTEXT_FUNC_MEMBER) {
491
		fn |= dspec_ignore;
492
	}
493
	return (fn);
2 7u83 494
}
495
 
496
 
497
/*
498
    CONSTRUCT A TYPE DECLARATION
499
 
500
    This routine constructs the declaration of a type with declaration
501
    specifiers ds (which will include typedef), type t and name id in the
502
    namespace ns.  mem gives the member of ns corresponding to id or the
503
    null member for class member redeclarations.
504
*/
505
 
7 7u83 506
static IDENTIFIER
507
make_type_decl(NAMESPACE ns, DECL_SPEC ds, TYPE t, MEMBER mem, IDENTIFIER id)
2 7u83 508
{
7 7u83 509
	int reported = 0;
510
	IDENTIFIER old_id;
511
	unsigned tag = TAG_type(t);
512
	QUALIFIER cq = crt_id_qualifier;
513
	HASHID nm = DEREF_hashid(id_name(id));
2 7u83 514
 
7 7u83 515
	/* Can't have other declaration specifiers with typedef */
516
	DECL_SPEC st = (ds & dspec_keyword);
517
	if (st != dspec_typedef) {
518
		st &= ~dspec_typedef;
519
		report(crt_loc, ERR_dcl_typedef_dspec(st));
520
	}
2 7u83 521
 
7 7u83 522
	/* Check for function cv-qualifiers and exception specifiers */
523
	object_type(t, id_type_alias_tag);
2 7u83 524
 
7 7u83 525
	/* Check for previous declaration */
526
	if (IS_NULL_member(mem)) {
527
		mem = search_member(ns, nm, 1);
528
		old_id = DEREF_id(member_id(mem));
529
		old_id = redecl_inherit(old_id, cq, in_class_defn, 2);
530
		if (IS_NULL_id(old_id)) {
531
			report(crt_loc, ERR_lookup_qual_undef(nm, ns));
532
		}
533
	} else {
534
		old_id = DEREF_id(member_id(mem));
535
		old_id = redecl_inherit(old_id, cq, in_class_defn, 2);
2 7u83 536
	}
537
 
7 7u83 538
	/* Allow for type redeclarations */
2 7u83 539
#if LANGUAGE_CPP
7 7u83 540
	id = type_member(mem, 3);
541
	id = redecl_inherit(id, cq, in_class_defn, 2);
2 7u83 542
#else
7 7u83 543
	id = old_id;
2 7u83 544
#endif
7 7u83 545
	if (!IS_NULL_id(id) && IS_id_class_name_etc(id)) {
546
		/* Already declared as a type name */
547
		TYPE s;
548
		ERROR err = NULL_err;
549
		PTR(LOCATION)loc = id_loc(id);
550
		unsigned long tokdefs = no_token_defns;
2 7u83 551
 
7 7u83 552
		/* Check for reserved identifiers */
553
		DECL_SPEC ods = DEREF_dspec(id_storage(id));
554
		if ((ds | ods) & dspec_reserve) {
555
			report(crt_loc, ERR_basic_odr_decl(id, loc));
556
			return (id);
557
		}
2 7u83 558
 
7 7u83 559
		/* Check type compatibility */
560
		s = DEREF_type(id_class_name_etc_defn(id));
561
		s = check_compatible(s, t, 0, &err, 1);
562
		/* QUERY: or is type equality required? */
2 7u83 563
 
7 7u83 564
		/* Compatible redefinition */
565
		if (IS_NULL_err(err)) {
566
			NAMESPACE cns = crt_namespace;
567
			if (cq != qual_none) {
568
				/* Check qualified definitions */
569
				check_decl_nspace(id, ns, 1, cns);
570
			}
571
			if (in_class_defn && EQ_nspace(ns, cns)) {
572
				if (!is_tagged_type(id)) {
573
					/* Still not allowed in a class
574
					 * definition */
575
					report(crt_loc,
576
					       ERR_class_mem_redecl(id, loc));
577
				}
578
			} else if (tokdefs == no_token_defns &&
579
				   !in_pragma_dir) {
580
				/* Can't redeclare types in C */
581
				report(crt_loc, ERR_basic_odr_typedef(id, loc));
582
			}
583
			if (tag == type_func_tag) {
584
				/* Check function types */
585
				s = redecl_func_type(id, s, t, 0, 1);
586
			}
587
			COPY_type(id_class_name_etc_defn(id), s);
588
			adjust_access(id, crt_access, 0);
589
			return (id);
2 7u83 590
		}
7 7u83 591
 
592
		/* Incompatible redefinition */
593
		err = concat_error(err, ERR_basic_link_typedef(id, loc));
594
		report(crt_loc, err);
595
		reported = 1;
2 7u83 596
	}
597
 
7 7u83 598
	/* Declare the type */
599
	id = make_typedef(ns, nm, t, dspec_none);
600
	if (is_tagged_type(id)) {
601
		/* Class-like typedef-names */
602
		set_type_member(mem, id);
603
	} else {
604
		/* Object-like typedef-names */
605
		if (!IS_NULL_id(old_id) && !reported) {
606
			/* Already declared as an object */
607
			PTR(LOCATION)loc = id_loc(old_id);
608
			report(crt_loc, ERR_basic_odr_diff(old_id, loc));
609
		}
610
		set_member(mem, id);
2 7u83 611
	}
7 7u83 612
	if (tag == type_func_tag) {
613
		/* Check function type */
614
		decl_func_type(id, t, 0);
615
	} else if (tag == type_templ_tag) {
616
		IGNORE check_templ_params(t, id);
617
		report(crt_loc, ERR_temp_decl_bad());
618
	}
619
	return (id);
2 7u83 620
}
621
 
622
 
623
/*
624
    CREATE A SPECIAL TYPE DEFINITION
625
 
626
    This routine creates a typedef of the identifier id to the special
627
    type t.
628
*/
629
 
7 7u83 630
void
631
typedef_special(IDENTIFIER id, TYPE t)
2 7u83 632
{
7 7u83 633
	int pushed = 0;
634
	NAMESPACE ns = nonblock_namespace;
635
	if (!EQ_nspace(ns, crt_namespace)) {
636
		push_namespace(ns);
637
		pushed = 1;
638
	}
639
	decl_loc = preproc_loc;
640
	if (in_class_defn) {
641
		id = make_member_decl(dspec_typedef, t, id, 0);
642
	} else {
643
		id = make_object_decl(dspec_typedef, t, id, 0);
644
	}
645
	if (do_dump) {
646
		dump_declare(id, &decl_loc, 1);
647
	}
648
	if (pushed) {
649
		IGNORE pop_namespace();
650
	}
651
	return;
2 7u83 652
}
653
 
654
 
655
/*
656
    FIND THE LINKAGE OF AN IDENTIFIER
657
 
658
    This routine finds the linkage of the identifier id (including the
659
    language specifier), returning the default value st if id does not
660
    represent an object or function.
661
*/
662
 
7 7u83 663
static DECL_SPEC
664
find_storage(IDENTIFIER id, DECL_SPEC st, TYPE t)
2 7u83 665
{
7 7u83 666
	if (!IS_NULL_id(id)) {
667
		switch (TAG_id(id)) {
668
		case id_variable_tag:
669
		case id_parameter_tag:
670
		case id_stat_member_tag:
671
		case id_weak_param_tag: {
672
			/* Objects */
673
			DECL_SPEC ds = DEREF_dspec(id_storage(id));
674
			st = (ds & (dspec_storage | dspec_language));
675
			break;
676
		}
677
		case id_function_tag:
678
		case id_mem_func_tag:
679
		case id_stat_mem_func_tag: {
680
			/* Functions */
681
			DECL_SPEC ds;
2 7u83 682
#if LANGUAGE_CPP
7 7u83 683
			LIST(IDENTIFIER)pids = NULL_list(IDENTIFIER);
684
			if (!IS_NULL_type(t)) {
685
				int eq = 0;
686
				id = resolve_func(id, t, 0, 0, pids, &eq);
687
				if (IS_NULL_id(id) ||
688
				    !IS_id_function_etc(id)) {
689
					return (st);
690
				}
691
			}
2 7u83 692
#else
7 7u83 693
			UNUSED(t);
2 7u83 694
#endif
7 7u83 695
			ds = DEREF_dspec(id_storage(id));
696
			st = (ds & (dspec_storage | dspec_language));
697
			break;
698
		}
699
		}
2 7u83 700
	}
7 7u83 701
	return (st);
2 7u83 702
}
703
 
704
 
705
/*
706
    CHECK THE LOCATION OF A DECLARATION
707
 
708
    This routine checks whether the namespace cns is a suitable location
709
    for redeclaring the object id, which is a member of the namespace ns.
710
    def is true for a definition.
711
*/
712
 
7 7u83 713
void
714
check_decl_nspace(IDENTIFIER id, NAMESPACE ns, int def, NAMESPACE cns)
2 7u83 715
{
7 7u83 716
	int func = 0;
717
	int local_def = really_in_function_defn;
718
	switch (TAG_id(id)) {
719
	case id_class_name_tag:
720
	case id_enum_name_tag:
721
	case id_class_alias_tag:
722
	case id_enum_alias_tag:
723
	case id_type_alias_tag: {
724
		/* Can define local types */
725
		local_def = 0;
726
		break;
2 7u83 727
	}
7 7u83 728
	case id_mem_func_tag:
729
	case id_stat_mem_func_tag: {
730
		/* Member function */
731
		DECL_SPEC ds = DEREF_dspec(id_storage(id));
732
		if (ds & dspec_implicit) {
733
			/* Ignore implicit constructors etc */
734
			return;
735
		}
736
		if (!def && !is_templ_nspace(ns)) {
737
			/* Can't even redeclare in this case */
738
			report(crt_loc, ERR_class_mfct_redecl(id));
739
			return;
740
		}
741
		func = 1;
742
		break;
2 7u83 743
	}
7 7u83 744
	case id_undef_tag: {
745
		/* Report undeclared members */
746
		HASHID nm = DEREF_hashid(id_name(id));
747
		report(crt_loc, ERR_lookup_qual_undef(nm, ns));
748
		return;
2 7u83 749
	}
7 7u83 750
	}
2 7u83 751
 
7 7u83 752
	if (def) {
753
		/* Check for enclosing namespace scope */
754
		if (local_def || !is_subnspace(cns, ns)) {
755
			/* Report badly placed definition */
756
			ERROR err;
757
			if (IS_nspace_ctype(ns)) {
758
				if (func) {
759
					/* Member functions */
760
					err = ERR_class_mfct_scope(id);
761
				} else {
762
					/* Other class members */
763
					err = ERR_class_static_data_scope(id);
764
				}
765
			} else {
766
				/* Namespace members */
767
				err = ERR_dcl_nspace_memdef_scope(id);
768
			}
769
			report(crt_loc, err);
2 7u83 770
		}
771
	}
7 7u83 772
	return;
2 7u83 773
}
774
 
775
 
776
/*
777
    CHECK AN OBJECT TYPE
778
 
779
    This routine checks the type t for the object id with declaration
780
    specifiers ds.
781
*/
782
 
7 7u83 783
void
784
check_obj_decl(DECL_SPEC ds, TYPE t, IDENTIFIER id, int tentative)
2 7u83 785
{
7 7u83 786
	unsigned tag = TAG_type(t);
787
	if (tag == type_top_tag || tag == type_bottom_tag) {
788
		/* Always report void declarations */
789
		report(crt_loc, ERR_basic_fund_void_decl(id, t));
790
	} else if (tag == type_templ_tag) {
791
		/* Shouldn't have template type */
792
		report(crt_loc, ERR_temp_decl_bad());
793
	} else if (ds & dspec_defn) {
794
		/* Only check otherwise if this is a definition */
795
		if (tag == type_array_tag) {
796
			/* Arrays may be completed by the initialiser */
797
			/* EMPTY */
798
		} else if (tag == type_ref_tag) {
799
			/* References don't need checking */
800
			/* EMPTY */
801
		} else {
802
			ERROR err;
803
			if (!tentative) {
804
				err = check_complete(t);
805
				if (!IS_NULL_err(err)) {
806
					/* Other definitions should have
807
					 * complete type */
808
					ERROR err2 =
809
					    ERR_basic_types_def_incompl(id);
810
					err = concat_error(err, err2);
811
					report(crt_loc, err);
812
				}
813
			}
814
			err = check_abstract(t);
815
			if (!IS_NULL_err(err)) {
816
				/* Objects can't have abstract type */
817
				ERROR err2 = ERR_class_abstract_decl(id);
818
				err = concat_error(err, err2);
819
				report(crt_loc, err);
820
			}
2 7u83 821
		}
822
	}
7 7u83 823
	return;
2 7u83 824
}
825
 
826
 
827
/*
828
    DECLARE AN OBJECT
829
 
830
    This routine constructs the declaration of an object with declaration
831
    specifiers ds, type t and name id.
832
*/
833
 
7 7u83 834
IDENTIFIER
835
make_object_decl(DECL_SPEC ds, TYPE t, IDENTIFIER id, int def)
2 7u83 836
{
7 7u83 837
	ERROR err;
838
	MEMBER mem;
839
	NAMESPACE ns;
840
	int redef = 0;
841
	int simple_id = 1;
842
	int tentative = 0;
843
	IDENTIFIER old_id;
844
	IDENTIFIER alt_id;
845
	DECL_SPEC st, df, rs;
846
	IDENTIFIER prev_id = NULL_id;
847
	unsigned tag = TAG_type(t);
848
	unsigned itag = id_variable_tag;
849
	HASHID nm = DEREF_hashid(id_name(id));
2 7u83 850
 
7 7u83 851
	/* Check for template specialisations */
852
	bound_specialise = 0;
853
	if (is_templ_decl(id, NULL_type) || is_templ_spec(t)) {
854
		t = bind_specialise(&id, t, ds, 0, 1, def);
855
		if (IS_NULL_id(id)) {
856
			/* Invalid specialisation */
857
			crt_id_qualifier = qual_none;
858
			crt_templ_qualifier = 0;
859
			id = DEREF_id(hashid_id(nm));
860
			while (IS_type_templ(t)) {
861
				t = DEREF_type(type_templ_defn(t));
862
			}
863
			id = make_object_decl(ds, t, id, def);
864
			return (id);
865
		}
866
		ns = DEREF_nspace(id_parent(id));
867
		check_decl_nspace(id, ns, 0, crt_namespace);
868
		old_id = id;
869
		mem = NULL_member;
870
		simple_id = 0;
871
	} else {
872
		/* Check on identifier name */
873
		QUALIFIER cq = crt_id_qualifier;
874
		err = check_id_name(id, CONTEXT_OBJECT);
875
		if (!IS_NULL_err(err)) {
876
			report(crt_loc, err);
877
		}
2 7u83 878
 
7 7u83 879
		/* Check for qualified identifiers */
880
		if (cq == qual_none) {
881
			/* Declaration of simple identifier */
882
			ns = crt_namespace;
883
			mem = search_member(ns, nm, 1);
884
			old_id = DEREF_id(member_id(mem));
885
			alt_id = DEREF_id(member_alt(mem));
886
			if (!IS_NULL_id(old_id)) {
887
				if (in_function_defn && (ds & dspec_extern)) {
888
					/* Redeclaration of block external */
889
					prev_id = find_previous(t, id);
890
					if (EQ_id(prev_id, old_id)) {
891
						old_id = NULL_id;
892
					}
893
				} else {
894
					old_id = redecl_inherit(old_id, cq, 0,
895
								2);
896
				}
897
				redef = 1;
898
			} else if (!IS_NULL_id(alt_id)) {
899
				redef = 1;
900
			}
2 7u83 901
		} else {
7 7u83 902
			/* Redeclaration of class or namespace member */
903
			ns = DEREF_nspace(id_parent(id));
904
			check_decl_nspace(id, ns, 0, crt_namespace);
905
			if (IS_id_undef(id)) {
906
				if (IS_nspace_ctype(ns)) {
907
					itag = id_stat_member_tag;
908
				}
909
				mem = search_member(ns, nm, 1);
910
				old_id = NULL_id;
911
			} else {
912
				mem = NULL_member;
913
				old_id = redecl_inherit(id, cq, 0, 2);
914
				t = bind_specialise(&old_id, t, ds, 0, 0, def);
915
				if (!IS_NULL_id(old_id)) {
916
					id = old_id;
917
					itag = TAG_id(id);
918
					ns = DEREF_nspace(id_parent(id));
919
				}
920
			}
921
			simple_id = 0;
2 7u83 922
		}
923
	}
924
 
7 7u83 925
	/* Deal with inferred types */
926
	ds = check_inferred_type(ds, &t, 0);
2 7u83 927
 
7 7u83 928
	/* Check on storage class specifiers */
929
	st = check_storage(ds, CONTEXT_OBJECT, old_id);
2 7u83 930
 
7 7u83 931
	/* Deal with type definitions */
932
	if (ds & dspec_typedef) {
933
		id = make_type_decl(ns, ds, t, mem, id);
934
		return (id);
935
	}
2 7u83 936
 
7 7u83 937
	/* Check on function specifiers */
938
	IGNORE check_func_spec(ds, CONTEXT_OBJECT);
2 7u83 939
 
7 7u83 940
	/* Find the object linkage and whether it is a definition */
941
	if (st == dspec_extern) {
942
		/* Explicit extern indicates a declaration (probably) */
943
		df = dspec_none;
944
		if (in_function_defn && simple_id) {
945
			if (IS_NULL_id(prev_id)) {
946
				prev_id = find_previous(t, id);
947
			}
948
			st = find_storage(prev_id, st, NULL_type);
949
		} else {
950
			prev_id = old_id;
951
			st = find_storage(old_id, st, t);
952
		}
2 7u83 953
	} else {
7 7u83 954
		if (tag == type_templ_tag && bound_specialise) {
955
			/* A template specialisation is a declaration
956
			 * (probably) */
957
			df = dspec_none;
958
		} else {
959
			/* Everything else is a definition */
960
			df = dspec_defn;
2 7u83 961
		}
7 7u83 962
		if (in_function_defn) {
963
			/* Objects declared in a block have no linkage */
964
			if (IS_NULL_member(mem)) {
965
				/* Use old linkage if explicitly qualified */
966
				st = find_storage(old_id, dspec_none, t);
967
			} else if (st == dspec_static) {
968
				st = dspec_none;
969
			} else if (st == dspec_register) {
970
				st = (dspec_auto | dspec_register);
971
				used_register = 1;
972
			} else {
973
				st = dspec_auto;
974
			}
975
		} else if (st == dspec_static) {
976
			/* Check static declarations */
977
			if (!def) {
978
				tentative = LANGUAGE_C;
979
			}
980
		} else if (st == dspec_none) {
981
			/* Objects declared const have internal linkage */
982
			CV_SPEC qual = find_cv_qual(t);
983
			if (qual & cv_const) {
984
				st = const_linkage;
985
				if (st & dspec_static) {
986
					st = find_storage(old_id, st, t);
987
				}
988
			} else {
989
				st = dspec_extern;
990
			}
991
			/* find_storage is not applied for objects */
992
			if (!def) {
993
				tentative = LANGUAGE_C;
994
			}
995
		}
2 7u83 996
	}
997
 
7 7u83 998
	/* Create the declaration */
999
	t = lvalue_type(t);
1000
	rs = (ds & dspec_other);
1001
	ds = (st | df | rs);
1002
	if (!IS_NULL_id(old_id)) {
1003
		/* Check redeclarations */
1004
		old_id = redecl_id(ds, t, old_id, 0, 0);
1005
		if (IS_NULL_id(old_id) && IS_NULL_member(mem)) {
1006
			/* Bad redeclaration of class or namespace member */
1007
			nm = lookup_anon();
1008
			mem = search_member(ns, nm, 1);
1009
			itag = id_stat_member_tag;
1010
		}
2 7u83 1011
	}
7 7u83 1012
	object_type(t, itag);
1013
	if (IS_NULL_id(old_id)) {
1014
		/* Construct the declaration */
1015
		ds = adjust_linkage(ds, 0);
1016
		MAKE_id_variable_etc(itag, nm, ds, ns, decl_loc, t, id);
1017
		if (in_function_defn) {
1018
			if (ds & dspec_linkage) {
1019
				/* Block function declarations */
1020
				id = unify_previous(id, t, prev_id, 0);
1021
			} else if (redef && (ds & dspec_auto)) {
1022
				/* Redeclarations of local variables */
1023
				mem = update_member(ns, mem);
1024
			}
1025
		} else {
1026
			id = unify_subsequent(id, t, 0);
1027
		}
1028
		set_member(mem, id);
1029
		if (itag == id_variable_tag && option(OPT_decl_hide)) {
1030
			check_hiding(id);
1031
		}
1032
		is_redeclared = 0;
2 7u83 1033
	} else {
7 7u83 1034
		/* Redeclare an existing object */
1035
		id = old_id;
1036
		if (IS_id_member(id)) {
1037
			t = DEREF_type(id_member_type(id));
1038
		} else {
1039
			t = DEREF_type(id_variable_etc_type(id));
1040
		}
1041
		ds = DEREF_dspec(id_storage(id));
1042
		is_redeclared = 1;
2 7u83 1043
	}
7 7u83 1044
#if LANGUAGE_CPP
1045
	if (ds & dspec_c) {
1046
		c_linkage(id, 0);
2 7u83 1047
	}
1048
#endif
7 7u83 1049
	check_obj_decl(ds, t, id, tentative);
1050
	return (id);
2 7u83 1051
}
1052
 
1053
 
1054
/*
1055
    DECLARE A FUNCTION
1056
 
1057
    This routine constructs a function declaration for a function with
1058
    declaration specifiers ds, type t and name id.  The argument def is
1059
    true to distinguish function definitions from function declarations.
1060
*/
1061
 
7 7u83 1062
IDENTIFIER
1063
make_func_decl(DECL_SPEC ds, TYPE t, IDENTIFIER id, int def)
2 7u83 1064
{
7 7u83 1065
	ERROR err;
1066
	MEMBER mem;
1067
	int ok = 1;
1068
	int chk = 1;
1069
	unsigned it;
1070
	int simple_id = 1;
1071
	int main_func = 0;
1072
	IDENTIFIER old_id;
1073
	NAMESPACE ns, ens;
1074
	DECL_SPEC st, df, fn, rs;
1075
	IDENTIFIER over_id = NULL_id;
1076
	IDENTIFIER prev_id = NULL_id;
1077
	unsigned itag = id_function_tag;
1078
	HASHID nm = DEREF_hashid(id_name(id));
2 7u83 1079
#if LANGUAGE_CPP
7 7u83 1080
	int allocator = 0;
2 7u83 1081
#endif
1082
 
7 7u83 1083
	/* Check for template specialisations */
1084
	if (is_templ_decl(id, t) || is_templ_spec(t)) {
1085
		t = bind_specialise(&id, t, ds, 0, 1, def);
1086
		if (IS_NULL_id(id)) {
1087
			/* Invalid specialisation */
1088
			crt_id_qualifier = qual_none;
1089
			crt_templ_qualifier = 0;
1090
			id = DEREF_id(hashid_id(nm));
1091
			while (IS_type_templ(t)) {
1092
				t = DEREF_type(type_templ_defn(t));
1093
			}
1094
			id = make_func_decl(ds, t, id, def);
1095
			return (id);
1096
		}
1097
		ns = DEREF_nspace(id_parent(id));
1098
		check_decl_nspace(id, ns, def, crt_namespace);
1099
		ens = ns;
1100
		mem = NULL_member;
1101
		old_id = id;
1102
		simple_id = 0;
2 7u83 1103
	} else {
7 7u83 1104
		/* Check on identifier name */
1105
		QUALIFIER cq = crt_id_qualifier;
1106
		err = check_id_name(id, CONTEXT_FUNCTION);
1107
		if (!IS_NULL_err(err)) {
1108
			report(crt_loc, err);
1109
			ok = 0;
2 7u83 1110
		}
7 7u83 1111
		/* Check for qualified identifiers */
1112
		if (cq == qual_none) {
1113
			/* Declaration of simple identifier */
1114
			ns = crt_namespace;
1115
			ens = nonblock_namespace;
1116
			mem = search_member(ns, nm, 1);
1117
			old_id = DEREF_id(member_id(mem));
1118
			if (!IS_NULL_id(old_id)) {
1119
				old_id = redecl_inherit(old_id, cq, 0, 1);
1120
			}
1121
			if (def && in_function_defn) {
1122
				/* Check for nested function definitions */
1123
				report(crt_loc, ERR_dcl_fct_def_scope());
1124
			}
1125
		} else {
1126
			/* Redeclaration of class or namespace member */
1127
			ns = DEREF_nspace(id_parent(id));
1128
			check_decl_nspace(id, ns, def, crt_namespace);
1129
			ens = ns;
1130
			if (IS_id_undef(id)) {
1131
				if (IS_nspace_ctype(ns)) {
1132
					itag = id_mem_func_tag;
1133
				}
1134
				mem = search_member(ns, nm, 1);
1135
				old_id = NULL_id;
1136
			} else {
1137
				mem = NULL_member;
1138
				old_id = redecl_inherit(id, cq, 0, 1);
1139
				t = bind_specialise(&old_id, t, ds, 0, 0, def);
1140
				if (!IS_NULL_id(old_id)) {
1141
					id = old_id;
1142
					itag = TAG_id(id);
1143
					ns = DEREF_nspace(id_parent(id));
1144
					ens = ns;
1145
				}
1146
			}
1147
			simple_id = 0;
1148
		}
2 7u83 1149
	}
1150
 
7 7u83 1151
	/* Allow for special functions */
1152
	if (EQ_KEYWORD(nm, lex_main) && IS_nspace_global(ens)) {
1153
		if (ds & dspec_typedef) {
1154
			/* Ignore type definition */
1155
			/* EMPTY */
1156
		} else {
1157
			t = check_main(t, nm);
1158
			main_func = 1;
1159
		}
2 7u83 1160
	}
7 7u83 1161
	it = TAG_hashid(nm);
2 7u83 1162
#if LANGUAGE_CPP
7 7u83 1163
	switch (it) {
1164
	case hashid_constr_tag: {
1165
		t = check_constr(t, id, ns);
1166
		ds &= ~dspec_empty;
1167
		ds |= dspec_main;
1168
		break;
2 7u83 1169
	}
7 7u83 1170
	case hashid_destr_tag: {
1171
		t = check_destr(t, id, ns);
1172
		ds &= ~dspec_empty;
1173
		ds |= dspec_main;
1174
		break;
2 7u83 1175
	}
7 7u83 1176
	case hashid_op_tag: {
1177
		int cl = IS_nspace_ctype(ns);
1178
		t = check_operator(t, id, cl, &allocator);
1179
		if (!allocator) {
1180
			ds |= dspec_ignore;
1181
		}
1182
		break;
2 7u83 1183
	}
7 7u83 1184
	case hashid_conv_tag: {
1185
		t = check_conv(t, id);
1186
		ds &= ~dspec_empty;
1187
		chk = 0;
1188
		break;
2 7u83 1189
	}
7 7u83 1190
	}
2 7u83 1191
#endif
1192
 
7 7u83 1193
	/* Deal with inferred types */
1194
	ds = check_func_type(ds, t, def, chk, 0);
1195
	if (main_func) {
1196
		ds |= dspec_main;
1197
	}
2 7u83 1198
 
7 7u83 1199
	/* Handle function definitions */
1200
	df = (def ? dspec_defn : dspec_none);
2 7u83 1201
 
7 7u83 1202
	/* Check on storage class specifiers */
1203
	st = check_storage(ds, CONTEXT_FUNCTION, old_id);
1204
	if (st == dspec_static) {
1205
		/* Check on static functions */
1206
		if (main_func) {
1207
			report(crt_loc, ERR_basic_start_main_link(nm, st));
1208
			st = dspec_extern;
1209
		} else {
1210
			/* Check static declarations */
1211
			/* EMPTY */
1212
		}
1213
	} else if (ds & dspec_inline) {
1214
		/* Check on inline functions */
1215
		if (main_func) {
1216
			fn = dspec_inline;
1217
			report(crt_loc, ERR_basic_start_main_link(nm, fn));
1218
			ds &= ~dspec_inline;
1219
		} else {
1220
			if (st == dspec_extern &&
1221
			    inline_linkage == dspec_static) {
1222
				/* Inline functions can't be extern */
1223
				report(crt_loc, ERR_dcl_stc_ext_inline());
1224
			}
1225
			if (in_function_defn) {
1226
				/* Can't declare inline functions in a block */
1227
				report(crt_loc, ERR_dcl_fct_spec_block());
1228
				st = dspec_none;
1229
			}
1230
		}
2 7u83 1231
	}
1232
 
7 7u83 1233
	/* Deal with type definitions */
1234
	if (ds & dspec_typedef) {
1235
		/* Can only apply typedef to declarations, not definitions */
1236
		if (!def) {
1237
			if (ok) {
1238
				/* Recheck identifier name */
1239
				err = check_id_name(id, CONTEXT_OBJECT);
1240
				if (!IS_NULL_err(err)) {
1241
					report(crt_loc, err);
1242
				}
1243
			}
1244
			id = make_type_decl(ns, ds, t, mem, id);
1245
			return (id);
1246
		}
1247
		report(crt_loc, ERR_dcl_typedef_func());
2 7u83 1248
	}
1249
 
7 7u83 1250
	/* Check on function specifiers */
1251
	fn = check_func_spec(ds, CONTEXT_FUNCTION);
2 7u83 1252
 
7 7u83 1253
	/* Find the function linkage */
1254
	if (st == dspec_extern) {
1255
		if (in_function_defn && simple_id) {
1256
			prev_id = find_previous(t, id);
1257
			st = find_storage(prev_id, st, NULL_type);
1258
		} else {
1259
			prev_id = old_id;
1260
			st = find_storage(old_id, st, t);
1261
		}
1262
	} else if (st == dspec_static) {
1263
		if (in_function_defn) {
1264
			/* Can't declare static functions in a block */
1265
			report(crt_loc, ERR_dcl_stc_stat_block());
1266
			if (simple_id) {
1267
				prev_id = find_previous(t, id);
1268
			} else {
1269
				prev_id = old_id;
1270
			}
1271
		}
1272
	} else if (st == dspec_none) {
1273
		/* Inline functions have internal linkage */
1274
		if (fn & dspec_inline) {
1275
			st = inline_linkage;
1276
		} else {
1277
			st = dspec_extern;
1278
		}
1279
		if (in_function_defn) {
1280
			prev_id = find_previous(t, id);
1281
			st = find_storage(prev_id, st, NULL_type);
1282
		} else {
1283
			prev_id = old_id;
1284
			st = find_storage(old_id, st, t);
1285
		}
2 7u83 1286
	}
7 7u83 1287
 
1288
	/* Create the declaration */
1289
	t = lvalue_type(t);
1290
	rs = (ds & dspec_other);
1291
	ds = (st | df | fn | rs);
1292
	if (!IS_NULL_id(old_id)) {
1293
		/* Check redeclarations */
1294
		old_id = redecl_func(ds, t, old_id, itag, &over_id, def);
1295
		if (IS_NULL_id(old_id) && IS_NULL_member(mem)) {
1296
			/* Bad redeclaration of class or namespace member */
1297
			nm = lookup_anon();
1298
			mem = search_member(ns, nm, 1);
1299
			if (IS_nspace_ctype(ns)) {
1300
				itag = id_mem_func_tag;
1301
			}
1302
			over_id = NULL_id;
1303
		}
2 7u83 1304
	}
7 7u83 1305
	object_type(t, itag);
1306
	if (IS_NULL_id(old_id)) {
1307
		/* Declare the function */
1308
		ds = adjust_linkage(ds, 0);
1309
		MAKE_id_function_etc(itag, nm, ds, ns, decl_loc, t, over_id,
1310
				     id);
1311
		if (in_function_defn) {
1312
			id = unify_previous(id, t, prev_id, def);
1313
		} else {
1314
			id = unify_subsequent(id, t, def);
1315
		}
1316
		set_member(mem, id);
1317
		decl_func_type(id, t, def);
2 7u83 1318
 
7 7u83 1319
		/* Check for conversion functions */
1320
		if (it == hashid_conv_tag && itag != id_mem_func_tag) {
1321
			report(crt_loc, ERR_class_conv_fct_mem());
1322
		}
1323
		if (itag == id_function_tag && option(OPT_decl_hide)) {
1324
			check_hiding(id);
1325
		}
1326
		is_redeclared = 0;
2 7u83 1327
	} else {
7 7u83 1328
		/* Redeclare the function */
1329
		id = old_id;
1330
		is_redeclared = 1;
2 7u83 1331
	}
7 7u83 1332
	ds = DEREF_dspec(id_storage(id));
1333
#if LANGUAGE_CPP
1334
	if (ds & dspec_c) {
1335
		c_linkage(id, def);
2 7u83 1336
	}
1337
#endif
1338
 
7 7u83 1339
	/* Allow for discarded functions */
1340
	if (!(rs & dspec_ignore) && option(OPT_discard_func)) {
1341
		ds &= ~dspec_ignore;
1342
		COPY_dspec(id_storage(id), ds);
1343
	}
2 7u83 1344
#if LANGUAGE_CPP
7 7u83 1345
	if (allocator) {
1346
		recheck_allocator(id, allocator);
1347
	}
2 7u83 1348
#endif
7 7u83 1349
	if (main_func) {
1350
		recheck_main(id);
1351
	}
1352
	return (id);
2 7u83 1353
}
1354
 
1355
 
1356
/*
1357
    CHECK A PARAMETER DECLARATION
1358
 
1359
    This routine checks the type of the parameter id declared with type t.
1360
*/
1361
 
7 7u83 1362
void
1363
check_par_decl(TYPE t, IDENTIFIER id, int loc)
2 7u83 1364
{
7 7u83 1365
	unsigned tag = TAG_type(t);
1366
	if (tag == type_compound_tag) {
1367
		/* Parameters can't have abstract type */
1368
		ERROR err = check_abstract(t);
1369
		if (!IS_NULL_err(err)) {
1370
			err = concat_error(err, ERR_class_abstract_par());
1371
			report(crt_loc, err);
1372
		}
1373
	} else if (tag == type_templ_tag) {
1374
		/* Shouldn't have template type */
1375
		report(crt_loc, ERR_temp_decl_bad());
2 7u83 1376
	}
7 7u83 1377
	if (loc == CONTEXT_WEAK_PARAM) {
1378
		/* Check for 'void' and other types */
1379
		ERROR err = check_param_type(id, t);
1380
		if (!IS_NULL_err(err)) {
1381
			report(crt_loc, err);
1382
		}
1383
	}
1384
	return;
2 7u83 1385
}
1386
 
1387
 
1388
/*
1389
    DECLARE A FUNCTION PARAMETER
1390
 
1391
    This routine constructs the declaration of a function parameter or
1392
    non-type template parameter (as indicated by loc) with declaration
1393
    specifiers ds, type t and name id.  Note that t is not checked - this
1394
    is only a declaration, and t may still legitimately be void, however
1395
    function and array parameters are adjusted to pointer parameters at
1396
    this stage.
1397
*/
1398
 
7 7u83 1399
IDENTIFIER
1400
make_param_decl(DECL_SPEC ds, TYPE t, IDENTIFIER id, int loc)
2 7u83 1401
{
7 7u83 1402
	ERROR err;
1403
	DECL_SPEC st, rs;
1404
	NAMESPACE ns = crt_namespace;
1405
	HASHID nm = DEREF_hashid(id_name(id));
1406
	MEMBER mem = search_member(ns, nm, 1);
1407
	IDENTIFIER old_id = DEREF_id(member_id(mem));
2 7u83 1408
 
7 7u83 1409
	/* Check on identifier name */
1410
	err = check_id_name(id, loc);
1411
	if (!IS_NULL_err(err)) {
1412
		report(decl_loc, err);
1413
	}
2 7u83 1414
 
7 7u83 1415
	/* Deal with inferred types */
1416
	ds = check_inferred_type(ds, &t, 0);
1417
	func_type_defn(1);
2 7u83 1418
 
7 7u83 1419
	/* Check on storage class specifiers */
1420
	st = check_storage(ds, loc, old_id);
1421
	if (st == dspec_register) {
1422
		st = (dspec_auto | dspec_register);
1423
		used_register = 1;
1424
	} else {
1425
		st = dspec_auto;
1426
	}
2 7u83 1427
 
7 7u83 1428
	/* Deal with type definitions */
1429
	if (ds & dspec_typedef) {
1430
		/* Can't have typedef in function parameters */
1431
		report(decl_loc, ERR_dcl_typedef_par());
1432
	}
2 7u83 1433
 
7 7u83 1434
	/* Check on function specifiers */
1435
	IGNORE check_func_spec(ds, loc);
2 7u83 1436
 
7 7u83 1437
	/* Create the parameter declaration */
1438
	t = make_param_type(t, loc);
1439
	rs = (ds & dspec_other);
1440
	ds = (st | rs | dspec_defn);
1441
	if (!IS_NULL_id(old_id)) {
1442
		/* Check for redeclarations */
1443
		if (loc == CONTEXT_TEMPL_PARAM) {
1444
			report(decl_loc, ERR_temp_param_dup(nm));
1445
			nm = lookup_anon();
1446
			mem = search_member(ns, nm, 1);
1447
			id = DEREF_id(hashid_id(nm));
1448
		} else {
1449
			if (loc == CONTEXT_WEAK_PARAM) {
1450
				if (IS_id_weak_param(old_id)) {
1451
					/* Check for order of declaration */
1452
					MEMBER mem1 =
1453
					    DEREF_member(nspace_last(ns));
1454
					while (!EQ_member(mem1, mem)) {
1455
						IDENTIFIER mid =
1456
						    DEREF_id(member_id(mem1));
1457
						if (!IS_NULL_id(mid) &&
1458
						    IS_id_parameter(mid)) {
1459
							report(decl_loc, ERR_dcl_fct_par_order());
1460
							break;
1461
						}
1462
						mem1 = DEREF_member(member_next(mem1));
1463
					}
1464
					old_id = NULL_id;
1465
				} else if (!IS_id_parameter(old_id)) {
1466
					report(decl_loc, ERR_dcl_fct_par_undecl(nm));
1467
				}
2 7u83 1468
			}
7 7u83 1469
			if (!IS_NULL_id(old_id)) {
1470
				if (IS_id_parameter(old_id)) {
1471
					/* Make up new name for parameter */
1472
					nm = lookup_anon();
1473
					mem = search_member(ns, nm, 1);
1474
				}
1475
				IGNORE redecl_id(ds, t, old_id, 0, 0);
1476
			}
2 7u83 1477
		}
7 7u83 1478
	} else {
1479
		if (loc == CONTEXT_WEAK_PARAM) {
1480
			report(decl_loc, ERR_dcl_fct_par_undecl(nm));
2 7u83 1481
		}
1482
	}
7 7u83 1483
	ds = adjust_linkage(ds, 0);
1484
	if (loc == CONTEXT_TEMPL_PARAM) {
1485
		IDENTIFIER pid;
1486
		object_type(t, id_token_tag);
1487
		id = make_exp_param(t, id);
1488
		pid = DEREF_id(id_token_alt(id));
1489
		set_member(mem, pid);
1490
	} else {
1491
		t = lvalue_type(t);
1492
		object_type(t, id_parameter_tag);
1493
		MAKE_id_parameter(nm, ds, ns, decl_loc, t, id);
1494
		set_member(mem, id);
2 7u83 1495
	}
7 7u83 1496
	check_par_decl(t, id, loc);
1497
	is_redeclared = 0;
1498
	return (id);
2 7u83 1499
}
1500
 
1501
 
1502
/*
1503
    DECLARE A NON-PROTOTYPE FUNCTION PARAMETER
1504
 
1505
    This routine is used to declare a non-prototype function parameter.
1506
*/
1507
 
7 7u83 1508
IDENTIFIER
1509
weak_param_decl(IDENTIFIER id)
2 7u83 1510
{
7 7u83 1511
	NAMESPACE ns = crt_namespace;
1512
	HASHID nm = DEREF_hashid(id_name(id));
1513
	MEMBER mem = search_member(ns, nm, 1);
1514
	IDENTIFIER old_id = DEREF_id(member_id(mem));
1515
	if (!IS_NULL_id(old_id)) {
1516
		nm = lookup_anon();
1517
		mem = search_member(ns, nm, 1);
1518
		IGNORE redecl_id(dspec_none, NULL_type, old_id, 0, 0);
1519
	}
1520
	MAKE_id_weak_param(nm, dspec_none, ns, decl_loc, id);
1521
	set_member(mem, id);
1522
	is_redeclared = 0;
1523
	return (id);
2 7u83 1524
}
1525
 
1526
 
1527
/*
1528
    CHECK A MEMBER DECLARATION
1529
 
1530
    This routine checks the declaration of the class member id with type
1531
    t and declaration specifiers ds.
1532
*/
1533
 
7 7u83 1534
void
1535
check_mem_decl(DECL_SPEC ds, TYPE t, IDENTIFIER id)
2 7u83 1536
{
7 7u83 1537
	unsigned tag = TAG_type(t);
1538
	if (ds & dspec_mutable) {
1539
		/* Can't apply mutable to a const member */
1540
		CV_SPEC qual = find_cv_qual(t);
1541
		if (qual & cv_const) {
1542
			report(crt_loc, ERR_dcl_stc_mut_const(id));
1543
			if (IS_id_member(id)) {
1544
				qual &= ~cv_const;
1545
				t = qualify_type(t, qual, 0);
1546
				COPY_type(id_member_type(id), t);
1547
			}
1548
		}
2 7u83 1549
	}
7 7u83 1550
	if (tag == type_top_tag || tag == type_bottom_tag) {
1551
		/* Always report void members */
1552
		report(crt_loc, ERR_basic_fund_void_mem(id, t));
1553
	} else if (tag == type_templ_tag) {
1554
		/* Shouldn't have template type */
1555
		report(crt_loc, ERR_temp_decl_bad());
1556
	} else if (ds & dspec_defn) {
1557
		/* Only check otherwise for defined (non-static) members */
1558
		if (tag == type_ref_tag) {
1559
			/* References don't need checking */
1560
			/* EMPTY */
1561
		} else {
1562
			/* Other members should have complete type */
1563
			ERROR err = check_complete(t);
1564
			if (!IS_NULL_err(err)) {
1565
				ERROR err2 = ERR_class_mem_incompl_mem(id);
1566
				err = concat_error(err, err2);
1567
				report(crt_loc, err);
1568
			} else {
1569
				/* Members can't have abstract type */
1570
				err = check_abstract(t);
1571
				if (!IS_NULL_err(err)) {
1572
					ERROR err2 = ERR_class_abstract_mem(id);
1573
					err = concat_error(err, err2);
1574
					report(crt_loc, err);
1575
				}
1576
			}
2 7u83 1577
		}
1578
	}
7 7u83 1579
	return;
2 7u83 1580
}
1581
 
1582
 
1583
/*
1584
    DECLARE A CLASS MEMBER
1585
 
1586
    This routine constructs the declaration of a class member with
1587
    declaration specifiers ds, type t and name id.  Note that the access
1588
    declarations (i.e. just a qualified-id and a semicolon) can only be
1589
    spotted at this stage.  The argument sm is true if this is the first
1590
    declarator in a list and the next token is a semicolon.
1591
*/
1592
 
7 7u83 1593
IDENTIFIER
1594
make_member_decl(DECL_SPEC ds, TYPE t, IDENTIFIER id, int sm)
2 7u83 1595
{
7 7u83 1596
	ERROR err;
1597
	HASHID nm;
1598
	MEMBER mem;
1599
	int redef = 0;
1600
	int tokenised = 0;
1601
	IDENTIFIER old_id;
1602
	IDENTIFIER alt_id;
1603
	DECL_SPEC st, df, rs;
1604
	OFFSET off = NULL_off;
1605
	CLASS_TYPE ct = crt_class;
1606
	IDENTIFIER tok_id = NULL_id;
1607
	NAMESPACE ns = crt_namespace;
1608
	unsigned tag = TAG_type(t);
1609
	QUALIFIER cq = crt_id_qualifier;
1610
	CLASS_INFO ci = DEREF_cinfo(ctype_info(ct));
2 7u83 1611
 
7 7u83 1612
	/* Check for template specialisations */
1613
	if (is_templ_decl(id, NULL_type)) {
1614
		IGNORE bind_specialise(&id, t, dspec_extern, 0, 1, 0);
1615
		if (!IS_NULL_id(id)) {
1616
			report(crt_loc, ERR_temp_spec_member(id));
1617
		}
1618
		return (id);
2 7u83 1619
	}
1620
 
7 7u83 1621
	/* Find previous declaration */
1622
	nm = DEREF_hashid(id_name(id));
1623
	if (IS_hashid_constr(nm) && cq == qual_none) {
1624
		DECL_SPEC sds = (dspec_static | dspec_typedef | dspec_reserve);
1625
		if (!(ds & sds)) {
1626
			/* Can use class name for non-static member */
1627
			report(crt_loc, ERR_class_mem_ctor_data(id));
1628
			id = DEREF_id(hashid_constr_tid(nm));
1629
			nm = DEREF_hashid(id_name(id));
1630
		}
2 7u83 1631
	}
7 7u83 1632
	mem = search_member(ns, nm, 1);
1633
	old_id = DEREF_id(member_id(mem));
1634
	alt_id = DEREF_id(member_alt(mem));
1635
	if (!IS_NULL_id(old_id)) {
1636
		old_id = redecl_inherit(old_id, cq, 1, 2);
1637
	}
2 7u83 1638
 
7 7u83 1639
	/* Check on member qualifications */
1640
	if (cq != qual_none) {
1641
		if ((ds & dspec_empty) && sm) {
1642
			/* Spot access declarations */
1643
			id = access_decl(id);
1644
			return (id);
1645
		}
1646
		ns = DEREF_nspace(id_parent(id));
1647
		if (EQ_nspace(ns, crt_namespace)) {
1648
			/* Qualifier indicates the current class */
1649
			report(crt_loc, ERR_dcl_meaning_mem(cq, id));
1650
			crt_id_qualifier = qual_none;
1651
		} else {
1652
			/* Qualifier indicates some other namespace */
1653
			id = make_object_decl(ds, t, id, 0);
1654
			return (id);
1655
		}
2 7u83 1656
	}
7 7u83 1657
 
1658
	/* Check on identifier name */
1659
	err = check_id_name(id, CONTEXT_MEMBER);
1660
	if (!IS_NULL_err(err)) {
1661
		report(crt_loc, err);
2 7u83 1662
	}
1663
 
7 7u83 1664
	/* Deal with inferred types */
1665
	ds = check_inferred_type(ds, &t, 1);
2 7u83 1666
 
7 7u83 1667
	/* Check on storage class specifiers */
1668
	st = check_storage(ds, CONTEXT_MEMBER, old_id);
1669
	if (st == dspec_static) {
1670
		if (tag == type_bitfield_tag) {
1671
			/* Bitfield members can't be static */
1672
			report(crt_loc, ERR_class_bit_static());
1673
			st = dspec_none;
1674
			df = dspec_defn;
1675
		} else {
1676
			if (ci & cinfo_union) {
1677
				/* Unions can't have static data members */
1678
				report(crt_loc, ERR_class_union_static(ct));
1679
				st = dspec_none;
1680
				df = dspec_defn;
1681
			} else {
1682
				/* Static members are only declared */
1683
				df = dspec_none;
1684
			}
1685
		}
2 7u83 1686
	} else {
7 7u83 1687
		/* Other members are defined */
1688
		df = dspec_defn;
2 7u83 1689
	}
1690
 
7 7u83 1691
	/* Deal with type definitions */
1692
	if (ds & dspec_typedef) {
1693
		LIST(IDENTIFIER)ft = DEREF_list(ctype_nest(ct));
1694
		if (tag == type_bitfield_tag) {
1695
			report(crt_loc, ERR_class_bit_typedef());
1696
			t = find_bitfield_type(t);
1697
		}
1698
		id = make_type_decl(ns, ds, t, mem, id);
1699
		CONS_id(id, ft, ft);
1700
		COPY_list(ctype_nest(ct), ft);
1701
		return (id);
2 7u83 1702
	}
1703
 
7 7u83 1704
	/* Check on function specifiers */
1705
	IGNORE check_func_spec(ds, CONTEXT_MEMBER);
2 7u83 1706
 
7 7u83 1707
	/* Record class properties */
1708
	rs = (ds & dspec_other);
1709
	if (rs & dspec_token) {
1710
		tokenised = 1;
1711
	}
1712
	if (st == dspec_static) {
1713
		ds = (df | rs | crt_access);
1714
	} else {
1715
		ds = (st | df | rs | crt_access);
1716
	}
2 7u83 1717
 
7 7u83 1718
	/* Check for redeclarations */
1719
	t = lvalue_type(t);
1720
	if (!IS_NULL_id(old_id)) {
1721
		if (st != dspec_static && IS_id_member(old_id)) {
1722
			/* Allow for token definitions */
1723
			if (tokenised) {
1724
				/* Token with previous definition */
1725
				off = DEREF_off(id_member_off(old_id));
1726
				t = DEREF_type(id_member_type(old_id));
1727
				tokenised = 3;
1728
			} else {
1729
				tok_id = find_token(old_id);
1730
				if (IS_id_token(tok_id)) {
1731
					/* Member was previously tokenised */
1732
					DECL_SPEC tds =
1733
					    DEREF_dspec(id_storage(tok_id));
1734
					if (!(tds & (dspec_pure |
1735
						     dspec_auto))) {
1736
						/* Token can't be defined */
1737
						tokenised = 2;
1738
					}
1739
				}
1740
			}
2 7u83 1741
		}
7 7u83 1742
		if (tokenised == 0) {
1743
			/* Redeclare if neither is a token */
1744
			old_id = redecl_id(ds, t, old_id, 0, 0);
1745
			if (IS_NULL_id(old_id)) {
1746
				redef = 1;
1747
			}
1748
		}
1749
	} else if (!IS_NULL_id(alt_id)) {
1750
		redef = 1;
2 7u83 1751
	}
7 7u83 1752
 
1753
	/* Create the declaration */
1754
	ds = adjust_linkage(ds, 1);
1755
	if (!really_in_function_defn) {
1756
		ds |= dspec_extern;
2 7u83 1757
	}
7 7u83 1758
	if (st == dspec_static) {
1759
		object_type(t, id_stat_member_tag);
1760
		MAKE_id_stat_member(nm, ds, ns, decl_loc, t, id);
1761
	} else {
1762
		object_type(t, id_member_tag);
1763
		MAKE_id_member(nm, ds, ns, decl_loc, t, id);
1764
		if (tokenised == 0 || tokenised == 2) {
1765
			/* Construct member offset if not tokenised */
1766
			MAKE_off_member(id, off);
1767
		}
1768
		COPY_off(id_member_off(id), off);
1769
		if (redef) {
1770
			mem = update_member(ns, mem);
1771
		}
1772
	}
2 7u83 1773
 
7 7u83 1774
	/* Set the namespace member */
1775
	if (tokenised >= 2) {
1776
		/* Create dummy member */
1777
		MEMBER mem_old = DEREF_member(nspace_last(ns));
1778
		if (tokenised == 2) {
1779
			/* Define existing token */
1780
			IGNORE define_mem_token(tok_id, off, t, 1);
1781
		} else {
1782
			/* Token is defined later ... */
1783
			/* EMPTY */
1784
		}
1785
		MAKE_member_large(NULL_member, NULL_member, mem);
1786
		COPY_id(member_id(mem), id);
1787
		COPY_member(nspace_last(ns), mem);
1788
		COPY_member(member_next(mem_old), mem);
2 7u83 1789
	}
7 7u83 1790
	set_member(mem, id);
1791
	check_mem_decl(ds, t, id);
1792
	is_redeclared = 0;
2 7u83 1793
 
7 7u83 1794
	/* Adjust class information */
1795
	if (st == dspec_static) {
1796
		if (really_in_function_defn) {
1797
			/* Can't have static members in local classes */
1798
			report(crt_loc, ERR_class_local_static(id));
1799
		}
1800
		ci |= cinfo_static;
2 7u83 1801
	} else {
7 7u83 1802
		/* Check member types */
1803
		if (crt_access != dspec_public) {
1804
			ci |= cinfo_private;
1805
		}
1806
		ci = check_member_type(ct, ci, t, 0);
1807
		ci &= ~cinfo_empty;
2 7u83 1808
	}
7 7u83 1809
	COPY_cinfo(ctype_info(ct), ci);
1810
	return (id);
2 7u83 1811
}
1812
 
1813
 
1814
/*
1815
    MAINTAIN SPECIAL MEMBER FUNCTIONS FOR A CLASS
1816
 
1817
    This routine updates the special member function information for
1818
    the class ct using the function id.  tag gives the identifier name tag.
1819
*/
1820
 
7 7u83 1821
void
1822
special_func_mem(CLASS_TYPE ct, IDENTIFIER id, unsigned tag, IDENTIFIER prev)
2 7u83 1823
{
7 7u83 1824
	switch (tag) {
1825
	case hashid_constr_tag: {
1826
		/* Set constructor */
1827
		COPY_id(ctype_constr(ct), id);
1828
		break;
2 7u83 1829
	}
7 7u83 1830
	case hashid_destr_tag: {
1831
		/* Set destructor */
1832
		COPY_id(ctype_destr(ct), id);
1833
		break;
2 7u83 1834
	}
7 7u83 1835
	case hashid_conv_tag: {
1836
		/* Maintain list of conversion functions */
1837
		HASHID nm = DEREF_hashid(id_name(id));
1838
		LIST(IDENTIFIER)conv = DEREF_list(ctype_conv(ct));
1839
		LIST(IDENTIFIER)p = conv;
1840
		while (!IS_NULL_list(p)) {
1841
			IDENTIFIER pid = DEREF_id(HEAD_list(p));
1842
			HASHID pnm = DEREF_hashid(id_name(pid));
1843
			if (EQ_hashid(nm, pnm)) {
1844
				/* Already member of list */
1845
				IDENTIFIER over;
1846
				over = DEREF_id(id_function_etc_over(id));
1847
				if (!EQ_id(pid, over) && !EQ_id(pid, prev)) {
1848
					/* Template function has produced
1849
					 * duplicate */
1850
					PTR(LOCATION)ploc = id_loc(pid);
1851
					report(crt_loc,
1852
					       ERR_class_mem_redecl(id, ploc));
1853
				}
1854
				COPY_id(HEAD_list(p), id);
1855
				return;
1856
			}
1857
			p = TAIL_list(p);
2 7u83 1858
		}
7 7u83 1859
		CONS_id(id, conv, conv);
1860
		COPY_list(ctype_conv(ct), conv);
1861
		break;
2 7u83 1862
	}
7 7u83 1863
	}
1864
	return;
2 7u83 1865
}
1866
 
1867
 
1868
/*
1869
    DECLARE A CLASS FUNCTION MEMBER
1870
 
1871
    This routine constructs a function declaration for a class member
1872
    function with declaration specifiers ds, type t and name id.  The
1873
    argument def is true to distinguish function definitions from function
1874
    declarations.
1875
*/
1876
 
1877
#if LANGUAGE_CPP
1878
 
7 7u83 1879
IDENTIFIER
1880
make_func_mem_decl(DECL_SPEC ds, TYPE t, IDENTIFIER id, int def)
2 7u83 1881
{
7 7u83 1882
	ERROR err;
1883
	MEMBER mem;
1884
	int ok = 1;
1885
	int chk = 1;
1886
	unsigned it;
1887
	unsigned itag;
1888
	int allocator = 0;
1889
	IDENTIFIER old_id;
1890
	LIST(VIRTUAL)vt;
1891
	DECL_SPEC st, df, fn, rs;
1892
	IDENTIFIER over_id = NULL_id;
1893
	IDENTIFIER hide_id = NULL_id;
1894
	NAMESPACE ns = crt_namespace;
1895
	QUALIFIER cq = crt_id_qualifier;
1896
	HASHID nm = DEREF_hashid(id_name(id));
1897
	CLASS_TYPE ct = crt_class;
1898
	CLASS_INFO ci = DEREF_cinfo(ctype_info(ct));
2 7u83 1899
 
7 7u83 1900
	/* Check for template specialisations */
1901
	if (is_templ_decl(id, t) || is_templ_spec(t)) {
1902
		st = (dspec_extern | (ds & dspec_inline));
1903
		IGNORE bind_specialise(&id, t, st, 0, 1, def);
1904
		if (!IS_NULL_id(id)) {
1905
			report(crt_loc, ERR_temp_spec_member(id));
1906
		}
1907
		return (id);
2 7u83 1908
	}
1909
 
7 7u83 1910
	/* Find previous declaration */
1911
	mem = search_member(ns, nm, 1);
1912
	old_id = DEREF_id(member_id(mem));
1913
	if (!IS_NULL_id(old_id)) {
1914
		old_id = redecl_inherit(old_id, cq, 1, 1);
1915
	}
2 7u83 1916
 
7 7u83 1917
	/* Check on member qualifications */
1918
	if (cq != qual_none) {
1919
		ns = DEREF_nspace(id_parent(id));
1920
		if (EQ_nspace(ns, crt_namespace)) {
1921
			/* Qualifier indicates the current class */
1922
			report(crt_loc, ERR_dcl_meaning_mem(cq, id));
1923
			crt_id_qualifier = qual_none;
1924
		} else {
1925
			/* Qualifier indicates some other namespace */
1926
			id = make_func_decl(ds, t, id, def);
1927
			return (id);
1928
		}
2 7u83 1929
	}
1930
 
7 7u83 1931
	/* Check on identifier name */
1932
	err = check_id_name(id, CONTEXT_FUNC_MEMBER);
1933
	if (!IS_NULL_err(err)) {
1934
		report(crt_loc, err);
1935
		ok = 0;
1936
	}
2 7u83 1937
 
7 7u83 1938
	/* Allow for special functions */
1939
	it = TAG_hashid(nm);
1940
	switch (it) {
1941
	case hashid_constr_tag: {
1942
		t = check_constr(t, id, ns);
1943
		ds &= ~dspec_empty;
1944
		ds |= dspec_main;
1945
		break;
2 7u83 1946
	}
7 7u83 1947
	case hashid_destr_tag: {
1948
		t = check_destr(t, id, ns);
1949
		ds &= ~dspec_empty;
1950
		ds |= dspec_main;
1951
		break;
2 7u83 1952
	}
7 7u83 1953
	case hashid_op_tag: {
1954
		t = check_operator(t, id, 1, &allocator);
1955
		if (!allocator) {
1956
			ds |= dspec_ignore;
1957
		}
1958
		break;
2 7u83 1959
	}
7 7u83 1960
	case hashid_conv_tag: {
1961
		t = check_conv(t, id);
1962
		ds &= ~dspec_empty;
1963
		chk = 0;
1964
		break;
2 7u83 1965
	}
7 7u83 1966
	}
2 7u83 1967
 
7 7u83 1968
	/* Deal with inferred types */
1969
	ds = check_func_type(ds, t, def, chk, 1);
2 7u83 1970
 
7 7u83 1971
	/* Handle function definitions */
1972
	if (def) {
1973
		/* Functions defined in a class are inline */
1974
		df = dspec_defn;
1975
		ds |= dspec_inline;
1976
	} else {
1977
		df = dspec_none;
1978
	}
2 7u83 1979
 
7 7u83 1980
	/* Check on storage class specifiers */
1981
	st = check_storage(ds, CONTEXT_FUNC_MEMBER, old_id);
2 7u83 1982
 
7 7u83 1983
	/* Deal with type definitions */
1984
	if (ds & dspec_typedef) {
1985
		/* Can only apply typedef to declarations, not definitions */
1986
		if (!def) {
1987
			if (ok) {
1988
				/* Recheck identifier name */
1989
				err = check_id_name(id, CONTEXT_MEMBER);
1990
				if (!IS_NULL_err(err)) {
1991
					report(crt_loc, err);
1992
				}
1993
			}
1994
			id = make_type_decl(ns, ds, t, mem, id);
1995
			return (id);
1996
		}
1997
		report(crt_loc, ERR_dcl_typedef_func());
2 7u83 1998
	}
1999
 
7 7u83 2000
	/* Check special functions */
2001
	if (allocator) {
2002
		/* Allocator functions are implicitly static */
2003
		if (st != dspec_static) {
2004
			st = dspec_static;
2005
			allocator |= 0x4;
2006
		}
2007
	} else if (st == dspec_static) {
2008
		switch (it) {
2009
		case hashid_constr_tag: {
2010
			/* Constructors can't be static */
2011
			report(crt_loc, ERR_class_ctor_static());
2012
			st = dspec_none;
2013
			break;
2014
		}
2015
		case hashid_destr_tag: {
2016
			/* Destructors can't be static */
2017
			report(crt_loc, ERR_class_dtor_static());
2018
			st = dspec_none;
2019
			break;
2020
		}
2021
		case hashid_op_tag: {
2022
			/* Overloaded operators can't be static */
2023
			report(crt_loc, ERR_over_oper_static());
2024
			st = dspec_none;
2025
			break;
2026
		}
2027
		case hashid_conv_tag: {
2028
			/* Conversion functions can't be static */
2029
			report(crt_loc, ERR_class_conv_fct_mem());
2030
			st = dspec_none;
2031
			break;
2032
		}
2033
		}
2 7u83 2034
	}
2035
 
7 7u83 2036
	/* Check on function specifiers */
2037
	fn = check_func_spec(ds, CONTEXT_FUNC_MEMBER);
2038
	vt = overrides_virtual(ct, nm, t, &hide_id);
2039
	if (!IS_NULL_list(vt)) {
2040
		/* Check for overriding of virtual functions */
2041
		if (!(fn & dspec_virtual)) {
2042
			if (!(ds & dspec_implicit)) {
2043
				err = ERR_class_virtual_override(nm);
2044
				if (!IS_NULL_err(err))report(crt_loc, err);
2045
			}
2046
			fn |= dspec_virtual;
2047
		}
2048
	} else if (!IS_NULL_id(hide_id)) {
2049
		err = ERR_class_virtual_hide(nm, hide_id);
2050
		if (!IS_NULL_err(err)) {
2051
			report(crt_loc, err);
2052
		}
2 7u83 2053
	}
7 7u83 2054
	if (fn & dspec_virtual) {
2055
		if (st == dspec_static) {
2056
			/* Static members can't be virtual */
2057
			err = ERR_class_static_mfct_virt();
2058
			if (allocator & 0x4) {
2059
				/* Allocator functions are implicitly static */
2060
				err = concat_error(ERR_class_free_static(nm),
2061
						   err);
2062
			}
2063
			report(crt_loc, err);
2064
			fn &= ~dspec_virtual;
2065
		} else if (it == hashid_constr_tag) {
2066
			/* Constructors can't be virtual */
2067
			report(crt_loc, ERR_class_ctor_virtual());
2068
			fn &= ~dspec_virtual;
2069
		} else {
2070
			if (ci & cinfo_union) {
2071
				/* Unions can't have virtual functions */
2072
				report(crt_loc, ERR_class_union_virtual(ct));
2073
				fn &= ~dspec_virtual;
2074
			} else if (ds & dspec_template) {
2075
				/* Can't have a virtual template function */
2076
				report(crt_loc, ERR_temp_mem_virtual());
2077
				fn &= ~dspec_virtual;
2078
			} else {
2079
				/* The current class is polymorphic */
2080
				ci |= cinfo_polymorphic;
2081
				ci &= ~cinfo_empty;
2082
			}
2083
		}
2 7u83 2084
	}
7 7u83 2085
	if (fn & dspec_explicit) {
2086
		/* Only constructors can be explicit */
2087
		if (it == hashid_constr_tag) {
2088
			have_constr_expl = 1;
2089
		} else {
2090
			if (it == hashid_conv_tag) {
2091
				report(crt_loc, ERR_dcl_fct_spec_expl_conv());
2092
				have_conv_expl = 1;
2093
			} else {
2094
				report(crt_loc, ERR_dcl_fct_spec_expl_constr());
2095
				fn &= ~dspec_explicit;
2096
			}
2097
		}
2098
	}
2099
	if (ds & dspec_template) {
2100
		/* Check for template function members */
2101
		if (it == hashid_destr_tag) {
2102
			report(crt_loc, ERR_temp_mem_destr());
2103
		}
2104
	}
2105
 
2106
	/* Record class properties */
2107
	rs = (ds & dspec_other);
2108
	if (st == dspec_static) {
2109
		itag = id_stat_mem_func_tag;
2110
		ds = (df | fn | rs | crt_access);
2 7u83 2111
	} else {
7 7u83 2112
		itag = id_mem_func_tag;
2113
		ds = (st | df | fn | rs | crt_access);
2 7u83 2114
	}
7 7u83 2115
	if (!(ds & dspec_implicit)) {
2116
		ci |= cinfo_function;
2 7u83 2117
	}
7 7u83 2118
	COPY_cinfo(ctype_info(ct), ci);
2 7u83 2119
 
7 7u83 2120
	/* Create the function declaration */
2121
	t = lvalue_type(t);
2122
	if (!IS_NULL_id(old_id)) {
2123
		/* Check for redeclarations */
2124
		IGNORE redecl_func(ds, t, old_id, itag, &over_id, def);
2125
	}
2126
	object_type(t, itag);
2127
	ds = adjust_linkage(ds, 1);
2128
	if (!really_in_function_defn) {
2129
		ds |= dspec_extern;
2130
	}
2131
	MAKE_id_function_etc(itag, nm, ds, ns, decl_loc, t, over_id, id);
2132
	if (!IS_NULL_id(over_id)) {
2133
		id = hide_functions(id, over_id, 1);
2134
	}
2135
	set_member(mem, id);
2136
	decl_func_type(id, t, def);
2137
	is_redeclared = 0;
2138
	ds = DEREF_dspec(id_storage(id));
2 7u83 2139
 
7 7u83 2140
	/* Maintain lists of functions */
2141
	special_func_mem(ct, id, it, old_id);
2142
	if (def) {
2143
		LIST(IDENTIFIER) ft = DEREF_list(ctype_nest(ct));
2144
		CONS_id(id, ft, ft);
2145
		COPY_list(ctype_nest(ct), ft);
2146
	}
2147
	if (ds & dspec_virtual) {
2148
		add_virtual(ct, id, vt);
2149
	}
2150
	if (allocator) {
2151
		allocator &= 0x3;
2152
		recheck_allocator(id, allocator);
2153
	}
2 7u83 2154
 
7 7u83 2155
	/* Allow for discarded functions */
2156
	if (!(rs & dspec_ignore) && option(OPT_discard_func)) {
2157
		ds &= ~dspec_ignore;
2158
		COPY_dspec(id_storage(id), ds);
2159
	}
2160
	return (id);
2 7u83 2161
}
2162
 
2163
#endif
2164
 
2165
 
2166
/*
2167
    DECLARE A FRIEND FUNCTION
2168
 
2169
    This routine is used to handle the declaration of a friend function
2170
    within a class.  The parameters are identical to those in the previous
2171
    routine.
2172
*/
2173
 
2174
#if LANGUAGE_CPP
2175
 
7 7u83 2176
IDENTIFIER
2177
make_friend_decl(DECL_SPEC ds, TYPE t, IDENTIFIER id, int def, int chum)
2 7u83 2178
{
7 7u83 2179
	ERROR err;
2180
	MEMBER mem;
2181
	int chk = 1;
2182
	unsigned it;
2183
	int allocator = 0;
2184
	int main_func = 0;
2185
	IDENTIFIER old_id;
2186
	NAMESPACE ns, ens;
2187
	DECL_SPEC st, df, fn, rs;
2188
	IDENTIFIER over_id = NULL_id;
2189
	unsigned itag = id_function_tag;
2190
	QUALIFIER cq = crt_id_qualifier;
2191
	int td = crt_templ_qualifier;
2192
	HASHID nm = DEREF_hashid(id_name(id));
2 7u83 2193
 
7 7u83 2194
	/* Check for template specialisations */
2195
	if (in_template_decl && cq == qual_none && td == 0 && chum) {
2196
		TYPE s = injected_type(t, 1);
2197
		if (!EQ_type(s, t)) {
2198
			/* Friend declaration is implicitly a template */
2199
			int eq = 0;
2200
			IDENTIFIER tid = make_friend_decl(ds, s, id, 0, 0);
2201
			if (do_dump) {
2202
				dump_declare(tid, &decl_loc, 0);
2203
			}
2204
			id = deduce_func(tid, t, &eq);
2205
			if (IS_NULL_id(id)) {
2206
				return (tid);
2207
			}
2208
			crt_templ_qualifier = 1;
2209
		}
2 7u83 2210
	}
7 7u83 2211
	if (is_templ_decl(id, t) || is_templ_spec(t)) {
2212
		t = bind_specialise(&id, t, ds, 0, 1, def);
2213
		if (IS_NULL_id(id)) {
2214
			/* Invalid specialisation */
2215
			crt_id_qualifier = qual_none;
2216
			crt_templ_qualifier = 0;
2217
			id = DEREF_id(hashid_id(nm));
2218
			while (IS_type_templ(t)) {
2219
				t = DEREF_type(type_templ_defn(t));
2220
			}
2221
			id = make_friend_decl(ds, t, id, def, chum);
2222
			return (id);
2223
		}
2224
		ns = DEREF_nspace(id_parent(id));
2225
		ens = ns;
2226
		mem = NULL_member;
2227
		old_id = id;
2228
		if (def) {
2229
			/* Check enclosing namespace scope */
2230
			check_decl_nspace(id, ns, def, nonclass_namespace);
2231
		}
2232
	} else {
2233
		/* Deal with typedef immediately */
2234
		if ((ds & dspec_typedef) && !def) {
2235
			id = make_func_mem_decl(ds, t, id, def);
2236
			return (id);
2237
		}
2 7u83 2238
 
7 7u83 2239
		/* Check on identifier name */
2240
		err = check_id_name(id, CONTEXT_FUNCTION);
2241
		if (!IS_NULL_err(err)) {
2242
			report(crt_loc, err);
2243
		}
2 7u83 2244
 
7 7u83 2245
		/* Check on member qualification */
2246
		if (cq == qual_none) {
2247
			/* Declaration of simple identifier */
2248
			ns = nonclass_namespace;
2249
			ens = nonblock_namespace;
2250
			mem = search_member(ns, nm, 1);
2251
			old_id = DEREF_id(member_id(mem));
2252
			if (!IS_NULL_id(old_id)) {
2253
				old_id = redecl_inherit(old_id, cq, 0, 1);
2254
			}
2255
			if (in_template_decl &&
2256
			    is_templ_nspace(crt_namespace)) {
2257
				/* Friend of template class */
2258
				NAMESPACE tns = templ_namespace;
2259
				mem = search_member(tns, nm, 1);
2260
			}
2261
		} else {
2262
			/* Redeclaration of class or namespace member */
2263
			ns = DEREF_nspace(id_parent(id));
2264
			ens = ns;
2265
			/* QUERY: Any other restrictions? */
2266
			if (IS_id_undef(id)) {
2267
				report(crt_loc, ERR_lookup_qual_undef(nm, ns));
2268
				if (IS_nspace_ctype(ns)) {
2269
					itag = id_mem_func_tag;
2270
				}
2271
				mem = search_member(ns, nm, 1);
2272
				old_id = NULL_id;
2273
			} else {
2274
				mem = NULL_member;
2275
				old_id = redecl_inherit(id, cq, 0, 1);
2276
				t = bind_specialise(&old_id, t, ds, 0, 0, def);
2277
				if (!IS_NULL_id(old_id)) {
2278
					id = old_id;
2279
					itag = TAG_id(id);
2280
					ns = DEREF_nspace(id_parent(id));
2281
					ens = ns;
2282
					if (def) {
2283
						/* Check enclosing namespace
2284
						 * scope */
2285
						check_decl_nspace(id, ns, def, nonclass_namespace);
2286
					}
2287
				}
2288
			}
2 7u83 2289
		}
2290
	}
2291
 
7 7u83 2292
	/* Can't define function in local class */
2293
	if (def && really_in_function_defn) {
2294
		report(crt_loc, ERR_class_friend_local());
2295
	}
2 7u83 2296
 
7 7u83 2297
	/* Allow for special functions */
2298
	if (EQ_KEYWORD(nm, lex_main) && IS_nspace_global(ens)) {
2299
		/* Declare main as a friend - it could happen */
2300
		t = check_main(t, nm);
2301
		main_func = 1;
2 7u83 2302
	}
7 7u83 2303
	it = TAG_hashid(nm);
2304
	switch (it) {
2305
	case hashid_constr_tag: {
2306
		t = check_constr(t, id, ns);
2307
		ds |= dspec_main;
2308
		break;
2 7u83 2309
	}
7 7u83 2310
	case hashid_destr_tag: {
2311
		t = check_destr(t, id, ns);
2312
		ds |= dspec_main;
2313
		break;
2 7u83 2314
	}
7 7u83 2315
	case hashid_op_tag: {
2316
		int cl = IS_nspace_ctype(ns);
2317
		t = check_operator(t, id, cl, &allocator);
2318
		if (!allocator) {
2319
			ds |= dspec_ignore;
2320
		}
2321
		break;
2 7u83 2322
	}
7 7u83 2323
	case hashid_conv_tag: {
2324
		t = check_conv(t, id);
2325
		chk = 0;
2326
		break;
2327
	}
2328
	}
2 7u83 2329
 
7 7u83 2330
	/* Deal with inferred types */
2331
	ds = check_func_type(ds, t, def, chk, 1);
2332
	if (main_func) {
2333
		ds |= dspec_main;
2334
	}
2 7u83 2335
 
7 7u83 2336
	/* Check on storage class specifiers */
2337
	st = check_storage(ds, CONTEXT_FUNCTION, old_id);
2338
	if (st != dspec_none) {
2339
		/* Can't have storage class with friend */
2340
		report(crt_loc, ERR_class_friend_storage(st));
2341
	}
2342
	if (def) {
2343
		/* Functions defined in a class are inline */
2344
		df = dspec_defn;
2345
		ds |= dspec_inline;
2346
		st = find_storage(old_id, inline_linkage, t);
2347
	} else if (ds & dspec_inline) {
2348
		df = dspec_none;
2349
		st = find_storage(old_id, inline_linkage, t);
2350
	} else {
2351
		df = dspec_none;
2352
		st = find_storage(old_id, dspec_extern, t);
2353
	}
2354
	if ((ds & dspec_inline) && main_func) {
2355
		report(crt_loc, ERR_basic_start_main_link(nm, dspec_inline));
2356
		ds &= ~dspec_inline;
2357
		st = dspec_extern;
2358
	}
2 7u83 2359
 
7 7u83 2360
	/* Check on function specifiers */
2361
	fn = check_func_spec(ds, CONTEXT_FUNCTION);
2 7u83 2362
 
7 7u83 2363
	/* Create the declaration */
2364
	t = lvalue_type(t);
2365
	rs = (ds & dspec_other);
2366
	ds = (st | df | fn | rs);
2367
	if (!IS_NULL_id(old_id)) {
2368
		/* Check redeclarations */
2369
		old_id = redecl_func(ds, t, old_id, itag, &over_id, def);
2370
		if (IS_NULL_id(old_id) && IS_NULL_member(mem)) {
2371
			/* Bad redeclaration of class or namespace member */
2372
			nm = lookup_anon();
2373
			mem = search_member(ns, nm, 1);
2374
			if (IS_nspace_ctype(ns)) {
2375
				itag = id_mem_func_tag;
2376
			}
2377
			over_id = NULL_id;
2378
		}
2 7u83 2379
	}
7 7u83 2380
	object_type(t, itag);
2381
	if (IS_NULL_id(old_id)) {
2382
		/* Declare the function */
2383
		ds = adjust_linkage(ds, 0);
2384
		MAKE_id_function_etc(itag, nm, ds, ns, decl_loc, t, over_id,
2385
				     id);
2386
		id = unify_subsequent(id, t, def);
2387
		set_member(mem, id);
2388
		decl_func_type(id, t, def);
2389
		report(decl_loc, ERR_class_friend_pre(id));
2 7u83 2390
 
7 7u83 2391
		/* Check for conversion functions */
2392
		if (it == hashid_conv_tag && itag != id_mem_func_tag) {
2393
			report(crt_loc, ERR_class_conv_fct_mem());
2394
		}
2395
		if (itag == id_function_tag && option(OPT_decl_hide)) {
2396
			check_hiding(id);
2397
		}
2398
		is_redeclared = 0;
2399
	} else {
2400
		/* Redeclare the function */
2401
		id = old_id;
2402
		is_redeclared = 1;
2 7u83 2403
	}
7 7u83 2404
	ds = DEREF_dspec(id_storage(id));
2405
#if LANGUAGE_CPP
2406
	if (ds & dspec_c) {
2407
		c_linkage(id, def);
2 7u83 2408
	}
2409
#endif
2410
 
7 7u83 2411
	/* Maintain list of inline functions */
2412
	if (def) {
2413
		CLASS_TYPE ct = crt_class;
2414
		LIST(IDENTIFIER)ft = DEREF_list(ctype_nest(ct));
2415
		CONS_id(id, ft, ft);
2416
		COPY_list(ctype_nest(ct), ft);
2417
	}
2 7u83 2418
 
7 7u83 2419
	/* Allow for discarded functions */
2420
	if (!(rs & dspec_ignore) && option(OPT_discard_func)) {
2421
		ds &= ~dspec_ignore;
2422
		COPY_dspec(id_storage(id), ds);
2423
	}
2 7u83 2424
 
7 7u83 2425
	/* Make the function a friend */
2426
	if (chum) {
2427
		friend_function(crt_class, id, 1);
2428
	}
2429
	if (main_func) {
2430
		recheck_main(id);
2431
	}
2432
	if (allocator) {
2433
		recheck_allocator(id, allocator);
2434
	}
2435
	return (id);
2 7u83 2436
}
2437
 
2438
#endif
2439
 
2440
 
2441
/*
2442
    CHECK ON AN ANONYMOUS UNION
2443
 
2444
    An anonymous union cannot have private or protected members or member
2445
    functions (in addition, no union can have static data members).  This
2446
    information is readily accessible from the class information field.
2447
    The routine class_info is not used in this case because it includes
2448
    the name of ct in its errors, which is not particularly useful when
2449
    ct is anonymous.
2450
*/
2451
 
2452
#if LANGUAGE_CPP
2453
 
7 7u83 2454
static void
2455
check_anon_union(CLASS_TYPE ct)
2 7u83 2456
{
7 7u83 2457
	CLASS_INFO ci = DEREF_cinfo(ctype_info(ct));
2458
	if (ci & cinfo_private) {
2459
		report(crt_loc, ERR_class_union_anon_private());
2460
	}
2461
	if (ci & cinfo_function) {
2462
		report(crt_loc, ERR_class_union_anon_func());
2463
	}
2464
	return;
2 7u83 2465
}
2466
 
2467
#endif
2468
 
2469
 
2470
/*
2471
    CHECK AN EMPTY OBJECT DECLARATION
2472
 
2473
    This routine handles a declaration with no declarators, comprising the
2474
    declaration specifiers ds, the template type qualifiers q and the type
2475
    specifiers t (which may be an elaborate pre-type).  Whether this is
2476
    legal depends on the value of the flag have_type_specifier described
2477
    in predict.c, which indicates whether t contained a type declaration
2478
    or definition.  Note that anonymous unions come under this heading
2479
    (I hate anonymous unions).
2480
*/
2481
 
7 7u83 2482
static IDENTIFIER
2483
empty_object_decl(DECL_SPEC ds, TYPE q, TYPE t)
2 7u83 2484
{
7 7u83 2485
	CV_SPEC qual;
2486
	DECL_SPEC st;
2487
	IDENTIFIER tid;
2488
	BASE_TYPE key = btype_class;
2489
	int td = have_type_declaration;
2 7u83 2490
 
7 7u83 2491
	/* Check for type declarations */
2492
	if (IS_type_pre(t)) {
2493
		QUALIFIER it;
2494
		DESTROY_type_pre(destroy, qual, tid, key, it, t);
2495
		if (it == qual_none) {
2496
			/* Unqualified identifier */
2497
			DECL_SPEC mode = (dspec_defn | dspec_auto);
2498
			td = TYPE_DECL_ELABORATE;
2499
			tid = find_elaborate_type(tid, key, q, mode);
2500
		} else {
2501
			/* Qualified identifier */
2502
			DECL_SPEC mode = (dspec_defn | dspec_alias);
2503
			td = TYPE_DECL_OVER_ELAB;
2504
			if (!IS_NULL_type(q)) {
2505
				td = TYPE_DECL_ELABORATE;
2506
			}
2507
			tid = find_elaborate_type(tid, key, q, mode);
2508
		}
2509
#if LANGUAGE_CPP
2510
		t = DEREF_type(id_class_name_etc_defn(tid));
2511
		t = qualify_type(t, qual, 0);
2512
#endif
2 7u83 2513
	} else {
7 7u83 2514
		tid = DEREF_id(type_name(t));
2515
		qual = DEREF_cv(type_qual(t));
2 7u83 2516
	}
7 7u83 2517
	qual &= cv_qual;
2 7u83 2518
 
2519
#if LANGUAGE_CPP
7 7u83 2520
	/* Check for anonymous unions */
2521
	if (td == TYPE_DECL_ANON && !(ds & dspec_typedef)) {
2522
		TYPE s = t;
2523
		while (IS_type_templ(s)) {
2524
			s = DEREF_type(type_templ_defn(s));
2 7u83 2525
		}
7 7u83 2526
		if (IS_type_compound(s)) {
2527
			CLASS_TYPE ct = DEREF_ctype(type_compound_defn(s));
2528
			CLASS_INFO ci = DEREF_cinfo(ctype_info(ct));
2529
			if (ci & cinfo_union) {
2530
				/* Anonymous union found */
2531
				int def;
2532
				HASHID nm;
2533
				IDENTIFIER id;
2534
				check_anon_union(ct);
2 7u83 2535
 
7 7u83 2536
				/* Create the union object */
2537
				nm = lookup_anon();
2538
				id = DEREF_id(hashid_id(nm));
2539
				crt_id_qualifier = qual_none;
2540
				crt_templ_qualifier = 0;
2541
				id = make_object_decl(ds, t, id, 0);
2542
				ds = DEREF_dspec(id_storage(id));
2543
				if (ds & dspec_extern) {
2544
					/* Anonymous unions can't have external
2545
					 * linkage */
2546
					report(crt_loc,
2547
					       ERR_class_union_anon_static());
2548
				}
2549
				def = init_object(id, NULL_exp);
2550
				if (do_dump) {
2551
					dump_declare(id, &crt_loc, def);
2552
				}
2553
				if (output_diag && !in_function_defn) {
2554
					compile_variable(id, 1);
2555
				}
2556
 
2557
				/* Bring fields into scope */
2558
				if (!redecl_anon_union(ct, ds, id)) {
2559
					report(crt_loc, ERR_dcl_dcl_empty());
2560
				}
2561
				return (id);
2562
			}
2 7u83 2563
		}
2564
	}
2565
#endif
2566
 
7 7u83 2567
	/* Check declaration specifiers */
2568
	if (ds != dspec_none) {
2569
		st = check_storage(ds, CONTEXT_OBJECT, NULL_id);
2570
		if (st != dspec_none) {
2571
			/* Can't have a storage class specifier */
2572
			report(crt_loc, ERR_dcl_stc_bad(st));
2573
		}
2574
		if (ds & dspec_typedef) {
2575
			report(crt_loc, ERR_dcl_typedef_dcl());
2576
		}
2577
		IGNORE check_func_spec(ds, CONTEXT_OBJECT);
2 7u83 2578
	}
7 7u83 2579
 
2580
	/* Check type qualifiers */
2581
	if (qual != cv_none && td != TYPE_DECL_NONE) {
2582
		report(crt_loc, ERR_dcl_type_cv_unused(qual));
2 7u83 2583
	}
2584
 
7 7u83 2585
	/* Check for type definitions */
2586
	switch (td) {
2587
	case TYPE_DECL_NONE: {
2588
		report(crt_loc, ERR_dcl_dcl_empty());
2589
		tid = NULL_id;
2590
		break;
2 7u83 2591
	}
7 7u83 2592
	case TYPE_DECL_ANON: {
2593
		report(crt_loc, ERR_dcl_dcl_anon());
2594
		break;
2 7u83 2595
	}
7 7u83 2596
	case TYPE_DECL_OVER_ELAB: {
2597
		report(crt_loc, ERR_dcl_type_elab_qual(key));
2598
		break;
2 7u83 2599
	}
7 7u83 2600
	}
2601
	return (tid);
2 7u83 2602
}
2603
 
2604
 
2605
/*
2606
    CHECK AN EMPTY MEMBER DECLARATION
2607
 
2608
    This routine handles a class member declaration with no declarators,
2609
    comprising the declaration specifiers ds, the template type qualifiers
2610
    q and the type specifiers t.  This is similar to empty_object_decl,
2611
    except that provision needs to be made for friend declarations of the
2612
    form 'friend class C'.
2613
*/
2614
 
7 7u83 2615
static IDENTIFIER
2616
empty_member_decl(DECL_SPEC ds, TYPE q, TYPE t)
2 7u83 2617
{
7 7u83 2618
	CV_SPEC qual;
2619
	IDENTIFIER tid;
2620
	BASE_TYPE key = btype_class;
2621
	int td = have_type_declaration;
2 7u83 2622
 
7 7u83 2623
	/* Check for type declarations */
2624
	if (IS_type_pre(t)) {
2625
		QUALIFIER it;
2626
		DESTROY_type_pre(destroy, qual, tid, key, it, t);
2627
		if (it == qual_none) {
2628
			/* Unqualified identifier */
2629
			DECL_SPEC mode = dspec_defn;
2630
			if (option(OPT_class_scope)) {
2631
				mode |= dspec_auto;
2632
			}
2633
			if (ds & dspec_friend) {
2634
				mode = (dspec_defn | dspec_used | dspec_friend);
2635
				if (in_template_decl &&
2636
				    is_templ_nspace(crt_namespace)) {
2637
					/* Friend of template class */
2638
					mode |= dspec_template;
2639
				}
2640
				mode |= dspec_register;
2641
			}
2642
			tid = find_elaborate_type(tid, key, q, mode);
2643
			if (mode & dspec_template) {
2644
				NAMESPACE ns = DEREF_nspace(id_parent(tid));
2645
				if (EQ_nspace(ns, templ_namespace)) {
2646
					ns = nonclass_namespace;
2647
					COPY_nspace(id_parent(tid), ns);
2648
				}
2649
			}
2650
			td = TYPE_DECL_ELABORATE;
2651
		} else {
2652
			/* Qualified identifier */
2653
			DECL_SPEC mode = (dspec_defn | dspec_alias);
2654
			if (ds & dspec_friend) {
2655
				mode |= dspec_friend;
2656
			}
2657
			tid = find_elaborate_type(tid, key, q, mode);
2658
			td = TYPE_DECL_OVER_ELAB;
2 7u83 2659
		}
7 7u83 2660
		t = DEREF_type(id_class_name_etc_defn(tid));
2661
		t = qualify_type(t, qual, 0);
2 7u83 2662
	} else {
7 7u83 2663
		tid = DEREF_id(type_name(t));
2664
		qual = DEREF_cv(type_qual(t));
2 7u83 2665
	}
7 7u83 2666
	qual &= cv_qual;
2 7u83 2667
 
2668
#if LANGUAGE_CPP
7 7u83 2669
	/* Check for anonymous unions */
2670
	if (td == TYPE_DECL_ANON && !(ds & dspec_typedef)) {
2671
		TYPE s = t;
2672
		while (IS_type_templ(s)) {
2673
			s = DEREF_type(type_templ_defn(s));
2 7u83 2674
		}
7 7u83 2675
		if (IS_type_compound(s)) {
2676
			CLASS_TYPE ct = DEREF_ctype(type_compound_defn(s));
2677
			CLASS_INFO ci = DEREF_cinfo(ctype_info(ct));
2678
			if (ci & cinfo_union) {
2679
				/* Anonymous union found */
2680
				int def;
2681
				HASHID nm;
2682
				IDENTIFIER id;
2683
				check_anon_union(ct);
2 7u83 2684
 
7 7u83 2685
				/* Create union member */
2686
				nm = lookup_anon();
2687
				id = DEREF_id(hashid_id(nm));
2688
				crt_id_qualifier = qual_none;
2689
				crt_templ_qualifier = 0;
2690
				if (ds & dspec_static) {
2691
					/* Can't be a static data member */
2692
					report(crt_loc,
2693
					       ERR_class_union_anon_mem());
2694
					ds &= ~dspec_static;
2695
				}
2696
				id = make_member_decl(ds, t, id, 0);
2697
				def = init_member(id, NULL_exp);
2698
				if (do_dump) {
2699
					dump_declare(id, &crt_loc, def);
2700
				}
2701
 
2702
				/* Bring fields into scope */
2703
				if (!redecl_anon_union(ct, dspec_none, id)) {
2704
					report(crt_loc, ERR_class_mem_empty());
2705
				}
2706
				return (id);
2707
			}
2 7u83 2708
		}
2709
	}
2710
#endif
2711
 
7 7u83 2712
	/* Check declaration specifiers */
2713
	if (ds != dspec_none) {
2714
		CLASS_TYPE cs = crt_class;
2715
		CLASS_TYPE ct = NULL_ctype;
2716
		DECL_SPEC st = check_storage(ds, CONTEXT_MEMBER, NULL_id);
2717
		if (st != dspec_none) {
2718
			/* Can't have a storage class specifier */
2719
			report(crt_loc, ERR_dcl_stc_bad(st));
2 7u83 2720
		}
7 7u83 2721
		if (ds & dspec_typedef) {
2722
			report(crt_loc, ERR_dcl_typedef_dcl());
2723
		}
2724
		if (ds & dspec_friend) {
2725
			/* Allow for friend declarations */
2726
			while (IS_type_templ(t)) {
2727
				t = DEREF_type(type_templ_defn(t));
2728
			}
2729
			if (IS_type_compound(t)) {
2730
				ct = DEREF_ctype(type_compound_defn(t));
2731
			} else if (is_templ_type(t)) {
2732
				IDENTIFIER cid = DEREF_id(type_token_tok(t));
2733
				ct = find_class(cid);
2734
			}
2735
			if (!IS_NULL_ctype(ct)) {
2736
				switch (td) {
2737
				case TYPE_DECL_ELABORATE:
2738
				case TYPE_DECL_OVER_ELAB:
2739
					/* Have 'friend class A ;' */
2740
					break;
2741
				case TYPE_DECL_NORMAL:
2742
					/* Have 'friend class A { ... } ;' */
2743
					report(crt_loc, ERR_class_friend_def());
2744
					break;
2745
				case TYPE_DECL_ANON:
2746
					/* Have 'friend class { ... } ;' */
2747
					report(crt_loc, ERR_class_mem_anon());
2748
					report(crt_loc, ERR_class_friend_def());
2749
					break;
2750
				default:
2751
					/* Have 'friend A ;' */
2752
					report(crt_loc,
2753
					       ERR_class_friend_elab());
2754
					break;
2755
				}
2756
				ds &= ~dspec_friend;
2757
			}
2758
		}
2759
		IGNORE check_func_spec(ds, CONTEXT_MEMBER);
2760
		if (!IS_NULL_ctype(ct)) {
2761
			/* Declare a class as a friend */
2762
			tid = DEREF_id(ctype_name(ct));
2763
			if (qual != cv_none) {
2764
				report(crt_loc, ERR_dcl_type_cv_unused(qual));
2765
			}
2766
			friend_class(cs, tid, 1);
2767
			return (tid);
2768
		}
2 7u83 2769
	}
7 7u83 2770
 
2771
	/* Check type qualifiers */
2772
	if (qual != cv_none && td != TYPE_DECL_NONE) {
2773
		report(crt_loc, ERR_dcl_type_cv_unused(qual));
2 7u83 2774
	}
2775
 
7 7u83 2776
	/* Check for type definitions */
2777
	switch (td) {
2778
	case TYPE_DECL_NONE: {
2779
		report(crt_loc, ERR_class_mem_empty());
2780
		tid = NULL_id;
2781
		break;
2 7u83 2782
	}
7 7u83 2783
	case TYPE_DECL_ANON: {
2784
		report(crt_loc, ERR_class_mem_anon());
2785
		break;
2 7u83 2786
	}
7 7u83 2787
	case TYPE_DECL_OVER_ELAB: {
2788
		report(crt_loc, ERR_dcl_type_elab_qual(key));
2789
		break;
2 7u83 2790
	}
7 7u83 2791
	}
2792
	return (tid);
2 7u83 2793
}
2794
 
2795
 
2796
/*
2797
    CHECK AN EMPTY DECLARATION
2798
 
2799
    This routine checks the empty declaration declared with the declaration
2800
    specifiers ds, the template type qualifiers q, the pre-type bt and t
2801
    and the cv-qualifiers cv (not all of which will be empty).  The tok
2802
    parameter is used to pass in the number of the last lexical token read,
2803
    this is used for a backwards compatibility hack involving types such
2804
    as wchar_t which used to be defined by typedefs, but are now keywords.
2805
    mem is true for member declarations.
2806
*/
2807
 
7 7u83 2808
IDENTIFIER
2809
empty_decl(DECL_SPEC ds, TYPE q, BASE_TYPE bt, TYPE t, CV_SPEC cv, int tok,
2810
	   int mem)
2 7u83 2811
{
7 7u83 2812
	/* Check for empty declarations */
2813
	IDENTIFIER id;
2814
	int have_specifier = 1;
2815
	decl_loc = crt_loc;
2816
	if (ds == dspec_none && bt == btype_none && cv == cv_none) {
2817
		if (IS_NULL_type(q)) {
2818
			if (IS_NULL_type(t)) {
2819
				/* Only semicolon in declaration */
2820
				if (mem) {
2821
					if (tok != lex_func_Hop) {
2822
						/* Allowed after function
2823
						 * definition */
2824
						report(crt_loc, ERR_class_mem_semicolon());
2825
					}
2826
				} else {
2827
					report(crt_loc,
2828
					       ERR_dcl_dcl_semicolon());
2829
				}
2830
				return (NULL_id);
2831
			}
2832
			if (have_type_declaration == TYPE_DECL_NONE) {
2833
				/* No type specifier in declaration */
2834
				have_specifier = 0;
2835
			}
2 7u83 2836
		}
2837
	}
2838
 
7 7u83 2839
	/* Check for definitions of built-in types */
2840
	if ((ds & dspec_typedef) && !mem) {
2841
		BASE_TYPE bs = key_type(tok);
2842
		if (bs) {
2843
			/* Type is now a keyword */
2844
			HASHID nm = KEYWORD(tok);
2845
			id = DEREF_id(hashid_id(nm));
2846
			bt &= ~bs;
2847
			t = complete_pre_type(bt, t, cv, 0);
2848
			report(crt_loc, ERR_lex_key_word(tok));
2849
			crt_id_qualifier = qual_none;
2850
			crt_templ_qualifier = 0;
2851
			id = make_object_decl(ds, t, id, 0);
2852
			return (id);
2853
		}
2 7u83 2854
	}
2855
 
7 7u83 2856
	/* Check for type access declarations */
2857
	if (!have_specifier && mem) {
2858
		if (!IS_NULL_type(t) && IS_type_pre(t)) {
2859
			BASE_TYPE key = DEREF_btype(type_pre_rep(t));
2860
			if (key == btype_alias) {
2861
				IDENTIFIER tid = DEREF_id(type_name(t));
2862
				QUALIFIER qual = DEREF_qual(type_pre_nqual(t));
2863
				if (qual && !IS_NULL_id(tid)) {
2864
					id = access_decl(tid);
2865
					return (id);
2866
				}
2867
			}
2 7u83 2868
		}
2869
	}
2870
 
7 7u83 2871
	/* Perform the declaration */
2872
	t = empty_complete_pre_type(bt, t, cv, 0);
2873
	if (mem) {
2874
		report(crt_loc, ERR_class_mem_declarator());
2875
		id = empty_member_decl(ds, q, t);
2876
	} else {
2877
		id = empty_object_decl(ds, q, t);
2878
	}
2879
	if (in_weak_param) {
2880
		/* Shouldn't happen in parameter declaration lists */
2881
		report(crt_loc, ERR_dcl_fct_par_none());
2882
	}
2883
	return (id);
2 7u83 2884
}
2885
 
2886
 
2887
/*
2888
    UPDATE EXTERNAL DECLARATION INFORMATION
2889
 
2890
    This routine is called after each external declaration.  d gives
2891
    the number of objects declared and e gives the associated expression
2892
    for an asm definition.  Note that this is the point of instantiation
2893
    for any pending templates.
2894
*/
2895
 
7 7u83 2896
void
2897
external_declaration(EXP e, int d)
2 7u83 2898
{
7 7u83 2899
	if (crt_file_type == 0) {
2900
		no_declarations += (unsigned long)d;
2 7u83 2901
	}
7 7u83 2902
	if (!IS_NULL_exp(e)) {
2903
		/* Compile any asm definitions */
2904
		compile_asm(e);
2 7u83 2905
	}
7 7u83 2906
	if (!in_preproc_dir) {
2907
		if (crt_access_list.pending) {
2908
			/* Clear any outstanding access checks */
2909
			IGNORE report_access(NULL_id);
2910
		}
2911
		if (!IS_NULL_list(pending_templates)) {
2912
			/* Instantiate any pending templates */
2913
			clear_templates(0);
2914
		}
2915
	}
2916
	return;
2 7u83 2917
}