Subversion Repositories tendra.SVN

Rev

Rev 2 | 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
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 "err_ops.h"
65
#include "exp_ops.h"
66
#include "graph_ops.h"
67
#include "hashid_ops.h"
68
#include "id_ops.h"
69
#include "member_ops.h"
70
#include "off_ops.h"
71
#include "nspace_ops.h"
72
#include "str_ops.h"
73
#include "tok_ops.h"
74
#include "type_ops.h"
75
#include "error.h"
76
#include "catalog.h"
77
#include "access.h"
78
#include "basetype.h"
79
#include "char.h"
80
#include "check.h"
81
#include "chktype.h"
82
#include "class.h"
83
#include "compile.h"
84
#include "constant.h"
85
#include "copy.h"
86
#include "declare.h"
87
#include "derive.h"
88
#include "dump.h"
89
#include "file.h"
90
#include "function.h"
91
#include "identifier.h"
92
#include "instance.h"
93
#include "literal.h"
94
#include "namespace.h"
95
#include "option.h"
96
#include "overload.h"
97
#include "predict.h"
98
#include "redeclare.h"
99
#include "syntax.h"
100
#include "template.h"
101
#include "tokdef.h"
102
#include "token.h"
103
#include "ustring.h"
104
 
105
 
106
/*
107
    CURRENT LINKAGE SPECIFIER
108
 
109
    The current linkage specifier is handled by means of this global
110
    variable.  The default, of no linkage being given, is interpreted
111
    according to the source language.
112
*/
113
 
7 7u83 114
DECL_SPEC crt_linkage = dspec_none;
115
DECL_SPEC new_linkage = dspec_none;
2 7u83 116
 
117
 
118
/*
119
    FIND A LINKAGE SPECIFIER
120
 
121
    This routine translates the string literal expression e into a linkage
122
    specifier.  The only recognised strings are "C" and "C++".
123
*/
124
 
7 7u83 125
DECL_SPEC
126
find_linkage(EXP e)
2 7u83 127
{
7 7u83 128
	STRING s = DEREF_str(exp_string_lit_str(e));
129
	unsigned kind = DEREF_unsigned(str_simple_kind(s));
2 7u83 130
 
7 7u83 131
	/* Can only occur in namespace scope */
132
	if (in_function_defn || in_class_defn) {
133
		report(crt_loc, ERR_dcl_link_scope());
134
	}
2 7u83 135
 
7 7u83 136
	/* Check the linkage string */
137
	if (kind == STRING_NONE) {
138
		char *t = strlit(DEREF_string(str_simple_text(s)));
139
		unsigned long len = DEREF_ulong(str_simple_len(s));
140
		if (len == 1 && streq(t, "C")) {
141
			return (dspec_c);
142
		}
143
		if (len == 3 && streq(t, "C++")) {
144
			return (dspec_cpp);
145
		}
2 7u83 146
	}
147
 
7 7u83 148
	/* Report unknown strings */
149
	report(crt_loc, ERR_dcl_link_unknown(s));
150
	return (crt_linkage);
2 7u83 151
}
152
 
153
 
154
/*
155
    FIND A LINKAGE STRING
156
 
157
    This routine returns the string corresponding to the linkage specifiers
158
    given by ds and cv.
159
*/
160
 
7 7u83 161
string
162
linkage_string(DECL_SPEC ds, CV_SPEC cv)
2 7u83 163
{
7 7u83 164
	CONST char *str;
165
	if ((ds & dspec_c) || (cv & cv_c)) {
166
		str = "C";
167
	} else {
168
		str = "C++";
169
	}
170
	return (ustrlit(str));
2 7u83 171
}
172
 
173
 
174
/*
175
    ADJUST DECLARATION SPECIFIER FOR LANGUAGE
176
 
177
    This routine adds the current language specifier to the declaration
178
    specifier ds.  mem is true for a member declaration (which always
179
    has C++ linkage).  ds may contain a language specifier from a
180
    previous declaration, otherwise it is deduced from crt_linkage.
181
*/
182
 
7 7u83 183
DECL_SPEC
184
adjust_linkage(DECL_SPEC ds, int mem)
2 7u83 185
{
7 7u83 186
	DECL_SPEC rs = (ds & ~dspec_language);
187
	if (mem) {
188
		/* Members have C++ linkage */
189
		rs |= dspec_cpp;
190
	} else if (rs & dspec_linkage) {
191
		/* Only applies to objects with linkage */
192
		DECL_SPEC ln = (ds | crt_linkage);
193
		if (ln & dspec_c) {
194
			rs |= dspec_c;
195
		} else {
196
			rs |= dspec_cpp;
197
		}
2 7u83 198
	}
7 7u83 199
	return (rs);
2 7u83 200
}
201
 
202
 
203
/*
204
    CHECK C LINKAGE DECLARATIONS
205
 
206
    This routine checks the identifier id declared with C linkage.  Objects
207
    with C linkage in different namespaces are actually the same.
208
*/
209
 
7 7u83 210
void
211
c_linkage(IDENTIFIER id, int def)
2 7u83 212
{
7 7u83 213
    TYPE t = NULL_type;
214
    unsigned tag = TAG_id(id);
215
    if (tag == id_function_tag) {
2 7u83 216
	/* Template functions can't have C linkage */
7 7u83 217
	t = DEREF_type(id_function_type(id));
218
	if (IS_type_templ(t)) {
219
	    report(decl_loc, ERR_temp_decl_linkage());
2 7u83 220
	}
7 7u83 221
    } else if (tag == id_variable_tag) {
222
	t = DEREF_type(id_variable_type(id));
2 7u83 223
    }
7 7u83 224
    if (!IS_NULL_type(t)) {
225
	NAMESPACE ns = c_namespace;
226
	if (!IS_NULL_nspace(ns)) {
227
	    HASHID nm = DEREF_hashid(id_name(id));
228
	    MEMBER mem = search_member(ns, nm, 1);
229
	    IDENTIFIER pid = DEREF_id(member_id(mem));
230
	    if (!IS_NULL_id(pid) && !EQ_id(id, pid)) {
231
		NAMESPACE cns = DEREF_nspace(id_parent(id));
232
		NAMESPACE pns = DEREF_nspace(id_parent(pid));
233
		if (!EQ_nspace(cns, pns)) {
234
		    DECL_SPEC cl = crt_linkage;
235
		    QUALIFIER cq = crt_id_qualifier;
236
		    DECL_SPEC ds = DEREF_dspec(id_storage(id));
237
		    crt_linkage = (ds & dspec_language);
238
		    crt_id_qualifier = qual_none;
239
		    pid = redecl_id(ds, t, pid, 3, -1);
240
		    if (!IS_NULL_id(pid)) {
2 7u83 241
			/* Set up alias */
7 7u83 242
			if (IS_id_function(pid)) {
243
			    TYPE s = DEREF_type(id_function_type(pid));
244
			    s = redecl_func_type(pid, s, t, def, 0);
245
			    COPY_type(id_function_type(pid), s);
2 7u83 246
			}
7 7u83 247
			ds |= dspec_alias;
248
			COPY_dspec(id_storage(id), ds);
249
			pid = DEREF_id(id_alias(pid));
250
			COPY_id(id_alias(id), pid);
251
			if (do_dump) {
252
				dump_alias(id, pid, &decl_loc);
253
			}
254
			id = pid;
2 7u83 255
		    }
7 7u83 256
		    crt_id_qualifier = cq;
257
		    crt_linkage = cl;
2 7u83 258
		}
259
	    }
7 7u83 260
	    COPY_id(member_id(mem), id);
2 7u83 261
	}
262
    }
7 7u83 263
    return;
2 7u83 264
}
265
 
266
 
267
/*
268
    FIND A PREVIOUS DECLARATION
269
 
270
    If a declaration in block scope is declared extern then it has external
271
    linkage unless the declaration matches a visible declaration of namespace
272
    scope.  This routine finds such a declaration for the identifier id
273
    of type t.
274
*/
275
 
7 7u83 276
IDENTIFIER
277
find_previous(TYPE t, IDENTIFIER id)
2 7u83 278
{
7 7u83 279
	if (crt_id_qualifier == qual_none) {
280
		NAMESPACE ns = nonblock_namespace;
281
		HASHID nm = DEREF_hashid(id_name(id));
282
		IDENTIFIER pid = find_extern_id(nm, ns, 0);
283
		if (!IS_NULL_id(pid)) {
284
			TYPE s;
285
			DECL_SPEC st;
286
			switch (TAG_id(pid)) {
287
			case id_variable_tag:
288
				/* Variables may be redeclared */
289
				s = DEREF_type(id_variable_type(pid));
290
				break;
291
			case id_function_tag: {
292
				/* Functions may be redeclared */
2 7u83 293
#if LANGUAGE_CPP
7 7u83 294
				int eq = 0;
295
				LIST(IDENTIFIER) pids = NULL_list(IDENTIFIER);
296
				pid = resolve_func(pid, t, 0, 0, pids, &eq);
297
				if (IS_NULL_id(pid)) {
298
					return (NULL_id);
299
				}
300
				if (!IS_id_function(pid)) {
301
					return (NULL_id);
302
				}
2 7u83 303
#endif
7 7u83 304
				s = DEREF_type(id_function_type(pid));
305
				break;
306
			}
307
			default:
308
				/* Nothing else can be redeclared */
309
				return (NULL_id);
310
			}
311
			st = DEREF_dspec(id_storage(pid));
312
			if (st & dspec_linkage) {
313
				/* Previous declaration must have linkage */
314
				s = type_composite(s, t, 0, 0, KILL_err, 0);
315
				if (!IS_NULL_type(s)) {
316
					return (pid);
317
				}
318
			}
2 7u83 319
		}
320
	}
7 7u83 321
	return (NULL_id);
2 7u83 322
}
323
 
324
 
325
/*
326
    UNIFY AN EXTERNAL IDENTIFIER
327
 
328
    This routine checks the identifier id, which is a variable declared
329
    extern in a block, against conflicts with the namespace ns into
330
    which it is injected.  p gives all the other extern block identifiers
331
    declared before id.  The routine returns any previous identifier.
332
*/
333
 
7 7u83 334
IDENTIFIER
335
unify_extern(IDENTIFIER id, TYPE t, NAMESPACE ns, LIST(IDENTIFIER) p)
2 7u83 336
{
7 7u83 337
	IDENTIFIER pid = NULL_id;
338
	HASHID nm = DEREF_hashid(id_name(id));
339
	LIST(IDENTIFIER) pids = NULL_list(IDENTIFIER);
340
	while (!IS_NULL_list(p)) {
341
		/* Check other block externs */
342
		IDENTIFIER bid = DEREF_id(HEAD_list(p));
343
		HASHID bnm = DEREF_hashid(id_name(bid));
344
		if (EQ_hashid(bnm, nm)) {
345
			bid = DEREF_id(id_alias(bid));
346
			CONS_id(bid, pids, pids);
347
		}
348
		p = TAIL_list(p);
2 7u83 349
	}
7 7u83 350
	if (!IS_NULL_nspace(ns)) {
351
		/* Check actual namespace */
352
		MEMBER mem = search_member(ns, nm, 0);
353
		if (!IS_NULL_member(mem)) {
354
			IDENTIFIER bid = DEREF_id(member_id(mem));
355
			if (!IS_NULL_id(bid)) {
356
				bid = DEREF_id(id_alias(bid));
357
				CONS_id(bid, pids, pids);
358
			}
359
		}
2 7u83 360
	}
7 7u83 361
	if (!IS_NULL_list(pids)) {
362
		/* Match found */
363
		if (IS_NULL_type(t)) {
364
			if (IS_NULL_list(TAIL_list(pids))) {
365
				pid = DEREF_id(HEAD_list(pids));
366
				DESTROY_list(pids, SIZE_id);
367
			} else {
368
				DECL_SPEC ds;
369
				pids = REVERSE_list(pids);
370
				ds = find_ambig_dspec(pids);
371
				MAKE_id_ambig(nm, ds, ns, crt_loc, pids, 1,
372
					      pid);
373
			}
2 7u83 374
		} else {
7 7u83 375
			LIST(IDENTIFIER) qids;
376
			DECL_SPEC cl = crt_linkage;
377
			QUALIFIER cq = crt_id_qualifier;
378
			DECL_SPEC ds = DEREF_dspec(id_storage(id));
379
			crt_linkage = (ds & dspec_language);
380
			crt_id_qualifier = qual_none;
381
			DEREF_loc(id_loc(id), decl_loc);
382
			pids = REVERSE_list(pids);
383
			qids = pids;
384
			while (!IS_NULL_list(qids)) {
385
				IDENTIFIER qid = DEREF_id(HEAD_list(qids));
386
				qid = DEREF_id(id_alias(qid));
387
				if (IS_type_func(t)) {
388
					/* Check function redeclaration */
389
					IDENTIFIER over = NULL_id;
390
					unsigned tag = TAG_id(id);
391
					qid = redecl_func(ds, t, qid, tag,
392
							  &over, -1);
393
				} else {
394
					/* Check variable redeclaration */
395
					qid = redecl_id(ds, t, qid, 0, -1);
396
				}
397
				if (!IS_NULL_id(qid)) {
398
					pid = qid;
399
				}
400
				qids = TAIL_list(qids);
401
			}
402
			DESTROY_list(pids, SIZE_id);
403
			crt_id_qualifier = cq;
404
			crt_linkage = cl;
2 7u83 405
		}
406
	}
7 7u83 407
	return (pid);
2 7u83 408
}
409
 
410
 
411
/*
412
    UNIFY A BLOCK DECLARATION WITH A PREVIOUS DECLARATION
413
 
414
    This routine is used to unify the external block declaration id of
415
    type t with its previous declaration pid (as returned by find_previous).
416
    def is true is id is a function definition.  The routine returns id.
417
    If there is no previous declaration then one is created and added to
418
    the extra identifier list of the enclosing non-block namespace.
419
*/
420
 
7 7u83 421
IDENTIFIER
422
unify_previous(IDENTIFIER id, TYPE t, IDENTIFIER pid, int def)
2 7u83 423
{
7 7u83 424
	/* Unify external linkage */
425
	if (IS_NULL_id(pid)) {
426
		LIST(IDENTIFIER) p;
427
		NAMESPACE ns = nonblock_namespace;
428
		p = DEREF_list(nspace_named_etc_extra(ns));
429
		pid = unify_extern(id, t, ns, p);
430
		if (IS_NULL_id(pid)) {
431
			if (!is_templ_depend(t)) {
432
				/* Declare new external object */
433
				DECL_SPEC ds;
434
				pid = copy_id(id, 0);
435
				ds = DEREF_dspec(id_storage(pid));
436
				if (!(ds & dspec_linkage)) {
437
					ds |= dspec_extern;
438
				}
439
				ds &= ~dspec_alias;
440
				COPY_dspec(id_storage(pid), ds);
441
				COPY_nspace(id_parent(pid), ns);
442
				COPY_id(id_alias(pid), pid);
443
				CONS_id(pid, p, p);
444
				COPY_list(nspace_named_etc_extra(ns), p);
445
			}
2 7u83 446
 
7 7u83 447
			/* Check object type */
448
			if (!is_global_type(t)) {
449
				report(crt_loc, ERR_basic_link_none(t, id));
450
			}
451
		}
2 7u83 452
	}
453
 
7 7u83 454
	/* Alias id to be pid */
455
	if (!IS_NULL_id(pid)) {
456
		if (IS_id_function_etc(pid)) {
457
			TYPE s = DEREF_type(id_function_etc_type(pid));
458
			s = redecl_func_type(pid, s, t, def, 0);
459
			COPY_type(id_function_etc_type(pid), s);
460
		}
461
		pid = DEREF_id(id_alias(pid));
462
		COPY_id(id_alias(id), pid);
2 7u83 463
	}
7 7u83 464
	return (id);
2 7u83 465
}
466
 
467
 
468
/*
469
    UNIFY A DECLARATION WITH A PREVIOUS BLOCK DECLARATION
470
 
471
    This routine is used to unify the external declaration id of type
472
    t with any previous external block declaration of the same object.
473
    def is true if id is a function definition.  The routine returns id.
474
*/
475
 
7 7u83 476
IDENTIFIER
477
unify_subsequent(IDENTIFIER id, TYPE t, int def)
2 7u83 478
{
7 7u83 479
	NAMESPACE ns = DEREF_nspace(id_parent(id));
480
	if (IS_nspace_named_etc(ns)) {
481
		LIST(IDENTIFIER) p;
482
		p = DEREF_list(nspace_named_etc_extra(ns));
483
		if (!IS_NULL_list(p)) {
484
			IDENTIFIER pid = unify_extern(id, t, NULL_nspace, p);
485
			if (!IS_NULL_id(pid)) {
486
				/* Alias id to be pid */
487
				if (IS_id_function_etc(pid)) {
488
					TYPE s = DEREF_type(id_function_etc_type(pid));
489
					s = redecl_func_type(pid, s, t, def, 0);
490
					COPY_type(id_function_etc_type(pid), s);
491
				}
492
				pid = DEREF_id(id_alias(pid));
493
				COPY_id(id_alias(id), pid);
494
			}
2 7u83 495
		}
496
	}
7 7u83 497
	return (id);
2 7u83 498
}
499
 
500
 
501
/*
502
    CHECK FOR CLASS-LIKE TYPEDEF NAMES
503
 
504
    This routine checks whether the typedef name id behaves like a class
505
    or an object with respect to name hiding.  It is not entirely clear
506
    whether it is just original class and enumeration names or all class
507
    and enumeration names (including those introduced using typedef)
508
    which behave in this way.
509
*/
510
 
7 7u83 511
int
512
is_tagged_type(IDENTIFIER id)
2 7u83 513
{
7 7u83 514
	switch (TAG_id(id)) {
515
	case id_class_name_tag:
516
	case id_enum_name_tag:
517
		/* Original class and enumeration names */
518
		return (1);
519
	case id_class_alias_tag:
520
	case id_enum_alias_tag:
521
	case id_type_alias_tag:
522
		/* Type aliases */
523
		return (0);
2 7u83 524
	}
7 7u83 525
	return (0);
2 7u83 526
}
527
 
528
 
529
/*
530
    REPORT AN OVERLOADIN ERROR
531
 
532
    This routine reports the overloading error err for the function id
533
    which cannot be overloaded for the reason corresponding to reason.
534
    It returns the severity of the error.
535
*/
536
 
7 7u83 537
static int
538
overload_error(IDENTIFIER id, ERROR err, int reason)
2 7u83 539
{
7 7u83 540
	int sev = ERROR_NONE;
541
	switch (reason) {
542
	case 1:
543
		/* Two functions with C linkage */
544
		err = concat_error(err, ERR_dcl_link_over());
545
		break;
546
	case 2:
547
		/* Two functions with indistinguishable parameters */
548
		err = concat_error(err, ERR_over_load_pars());
549
		break;
550
	case 3: {
551
		/* Two objects with C linkage */
552
		PTR(LOCATION)loc = id_loc(id);
553
		HASHID nm = DEREF_hashid(id_name(id));
554
		err = concat_error(err, ERR_dcl_link_redecl(nm, loc));
555
		break;
2 7u83 556
	}
557
	}
7 7u83 558
 
559
	if (!IS_NULL_err(err)) {
560
		sev = DEREF_int(err_severity(err));
561
		report(decl_loc, err);
2 7u83 562
	}
7 7u83 563
	return (sev);
2 7u83 564
}
565
 
566
 
567
/*
568
    REDECLARE AN OBJECT IDENTIFIER
569
 
570
    This routine checks the redeclaration of the identifier id as an object
571
    with declaration specifiers ds and type t.  It returns id for a valid
572
    redeclaration and the null identifier otherwise, reporting any errors
573
    if necessary.  Note that it is possible to reserve an identifier using
574
    the reserve declaration specifier.  At present this is only done for
575
    the fields of an anonymous union and enumerators.  Also a class or
576
    enumeration name can be hidden by an object in the same scope.  A
577
    redeclared identifier will be marked as defined according to whether
578
    the redeclaration is a definition.  Whether the initial declaration
579
    was a definition may be determined from the initialiser expression.
580
*/
581
 
7 7u83 582
IDENTIFIER
583
redecl_id(DECL_SPEC ds, TYPE t, IDENTIFIER id, int reason, int def)
2 7u83 584
{
7 7u83 585
	TYPE s;
586
	DECL_SPEC ln;
587
	PTR(TYPE) pt;
588
	int changed = 0;
589
	int is_member = 0;
590
	int is_function = 0;
591
	ERROR err = NULL_err;
592
	DECL_SPEC ds_old, ln_old;
2 7u83 593
 
7 7u83 594
	/* Check previous definition */
595
	switch (TAG_id(id)) {
596
	case id_variable_tag:
597
		/* Variables may be redeclared */
598
		pt = id_variable_type(id);
599
		break;
600
	case id_function_tag:
601
		/* Functions may be redeclared */
602
		is_function = 1;
603
		pt = id_function_type(id);
604
		break;
605
	case id_class_name_tag:
606
	case id_enum_name_tag:
607
	case id_class_alias_tag:
608
	case id_enum_alias_tag:
609
	case id_type_alias_tag: {
610
		/* Unqualified class and enumeration names can be hidden */
611
		PTR(LOCATION)loc;
612
		if (!is_tagged_type(id)) {
613
			loc = id_loc(id);
614
			report(decl_loc, ERR_basic_odr_diff(id, loc));
615
			return (NULL_id);
616
		}
617
		if (crt_id_qualifier == qual_none) {
618
			/* Check for templates */
619
			ds_old = DEREF_dspec(id_storage(id));
620
			if (!(ds_old & dspec_template)) {
621
				return (NULL_id);
622
			}
623
		}
624
		loc = id_loc(id);
625
		report(decl_loc, ERR_basic_odr_diff(id, loc));
626
		return (NULL_id);
2 7u83 627
	}
7 7u83 628
	case id_stat_member_tag:
629
		/* Members may be defined outside their class */
630
		is_member = 1;
631
		if (crt_id_qualifier == qual_none) {
632
			goto error_lab;
633
		}
634
		pt = id_stat_member_type(id);
635
		break;
636
	case id_mem_func_tag:
637
	case id_stat_mem_func_tag:
638
		/* Members may be defined outside their class */
639
		is_member = 1;
640
		is_function = 1;
641
		if (crt_id_qualifier == qual_none) {
642
			goto error_lab;
643
		}
644
		pt = id_function_etc_type(id);
645
		break;
646
	case id_member_tag:
647
		/* Non-static members cannot be redeclared */
648
		is_member = 1;
649
		if (crt_id_qualifier == qual_none) {
650
			goto error_lab;
651
		}
652
		report(decl_loc, ERR_class_mem_def(id));
653
		return (NULL_id);
654
	case id_token_tag:
655
		/* Allow for token definitions */
656
		return (NULL_id);
657
	case id_undef_tag:
658
	case id_ambig_tag:
659
		/* Allow for error propagation */
660
		return (NULL_id);
661
	default:
662
error_lab:
663
		/* No other identifiers can be redeclared */
664
		if (is_member) {
665
			/* Member redeclaration */
666
			err = ERR_class_mem_redecl(id, id_loc(id));
667
		} else {
668
			/* Object redeclaration */
669
			err = ERR_basic_odr_decl(id, id_loc(id));
670
		}
671
		IGNORE overload_error(id, err, reason);
672
		return (NULL_id);
2 7u83 673
	}
7 7u83 674
 
675
	/* Check declaration specifiers */
676
	ds_old = DEREF_dspec(id_storage(id));
677
	if ((ds | ds_old) & dspec_reserve) {
678
		/* Reserved names can't be redeclared */
679
		reason = 0;
680
		goto error_lab;
2 7u83 681
	}
7 7u83 682
 
683
	/* Check for objects with no linkage */
684
	ln = (ds & dspec_linkage);
685
	ln_old = (ds_old & dspec_linkage);
686
	if (ln == dspec_none || ln_old == dspec_none) {
687
		/* Can't redeclare objects with no linkage */
688
		if (!is_function) {
689
			reason = 0;
690
			goto error_lab;
691
		}
2 7u83 692
	}
7 7u83 693
 
694
	/* Check previous type */
695
	s = DEREF_type(pt);
696
	s = check_compatible(s, t, 0, &err, 1);
697
	if (!IS_NULL_err(err)) {
698
		/* Incompatible declaration */
699
		PTR(LOCATION) loc = id_loc(id);
700
		err = concat_error(err, ERR_basic_link_decl_type(id, loc));
701
		if ((ds | ds_old) & dspec_token) {
702
			/* Allow for interface declarations */
703
			err = set_severity(err, OPT_interf_incompat, -1);
704
		}
705
		if (overload_error(id, err, reason) == ERROR_SERIOUS) {
706
			return (NULL_id);
707
		}
2 7u83 708
	}
7 7u83 709
	if (is_function) {
710
		/* Sanity check for error types */
711
		if (type_tag(s) != type_func_tag) {
712
			return (NULL_id);
713
		}
714
	} else {
715
		if (type_tag(s) == type_func_tag) {
716
			return (NULL_id);
717
		}
2 7u83 718
	}
7 7u83 719
	if (def >= 0) {
720
		COPY_type(pt, s);
2 7u83 721
	}
7 7u83 722
 
723
	/* Check for redeclaration of aliases */
724
	if ((ds | ds_old) & dspec_alias) {
725
		PTR(LOCATION) loc = id_loc(id);
726
		report(decl_loc, ERR_dcl_nspace_udecl_redecl(id, loc));
2 7u83 727
	}
728
 
7 7u83 729
	/* Check for inconsistent linkage */
730
	if (ln != ln_old) {
731
		ERROR err1;
732
		DECL_SPEC ln_new;
733
		PTR(LOCATION) loc = id_loc(id);
734
		if (ln_old == dspec_static) {
735
			err1 = ERR_dcl_stc_internal(id, loc);
736
		} else {
737
			err1 = ERR_dcl_stc_external(id, loc);
738
			if (is_member) {
739
				/* Members have external linkage */
740
				ERROR err2 = ERR_basic_link_mem_extern(id);
741
				err1 = concat_error(err2, err1);
742
			}
743
		}
744
		if (reason == 3) {
745
			/* Identification of objects with C linkage */
746
			HASHID nm = DEREF_hashid(id_name(id));
747
			ERROR err2 = ERR_dcl_link_redecl(nm, loc);
748
			err1 = concat_error(err1, err2);
749
		}
750
		if (def == -1 && option(OPT_link_internal) == OPTION_OFF) {
751
			ln_new = dspec_extern;
752
		} else {
753
			ln_new = dspec_static;
754
		}
755
		ds_old = (ln_new | (ds_old & ~dspec_linkage));
756
		report(decl_loc, err1);
757
		changed = 1;
2 7u83 758
	}
759
 
7 7u83 760
	/* Check language specifier */
761
	ln = crt_linkage;
762
	if (ln != dspec_none) {
763
		/* Check against the current language */
764
		ln_old = (ds_old & dspec_language);
765
		if ((ds_old & dspec_extern) && ln != ln_old) {
766
			/* Report inconsistent linkage */
767
			if (!is_member) {
768
				/* Should this only apply to functions? */
769
				PTR(LOCATION) loc = id_loc(id);
770
				string lang = linkage_string(ln_old, cv_none);
771
				report(decl_loc,
772
				       ERR_dcl_link_lang(id, lang, loc));
773
				ds_old = adjust_linkage(ds_old, is_member);
774
				changed = 1;
775
			}
776
		}
2 7u83 777
	}
778
 
7 7u83 779
	/* Check for inline specifier */
780
	if (ds & dspec_inline) {
781
		ds_old |= dspec_inline;
782
		changed = 1;
2 7u83 783
	}
784
 
7 7u83 785
	/* Mark whether this declaration is a definition */
786
	if (def >= 0) {
787
		if (ds & dspec_defn) {
788
			ds_old |= dspec_defn;
789
		} else {
790
			ds_old &= ~dspec_defn;
791
		}
2 7u83 792
	}
793
 
7 7u83 794
	/* Compatible redeclaration */
795
	COPY_dspec(id_storage(id), ds_old);
796
	if (changed) {
797
		update_tag(id, 0);
2 7u83 798
	}
7 7u83 799
	return (id);
2 7u83 800
}
801
 
802
 
803
/*
804
    REDECLARE A FUNCTION IDENTIFIER
805
 
806
    This routine is similar to redecl_id except that it allows for function
807
    overloading.  As before it returns id if this is a redeclaration of an
808
    existing function, and the null identifier otherwise.  However in the
809
    latter case any functions overloaded by the declaration are returned
810
    via over.
811
*/
812
 
7 7u83 813
IDENTIFIER
814
redecl_func(DECL_SPEC ds, TYPE t, IDENTIFIER id, unsigned tag,
815
	    IDENTIFIER *over, int def)
2 7u83 816
{
7 7u83 817
	int reason = 0;
818
	IDENTIFIER fid = id;
2 7u83 819
#if LANGUAGE_CPP
7 7u83 820
	if (IS_id_function_etc(fid)) {
821
		DECL_SPEC ds_old;
822
		*over = fid;
2 7u83 823
 
7 7u83 824
		/* Scan through overloaded functions for a match */
825
		while (!IS_NULL_id(fid)) {
826
			int m;
827
			TYPE s;
828
			int mq = 1;
829
			if ((ds & dspec_extern) && crt_linkage == dspec_c) {
830
				/* Two functions with C linkage are the same */
831
				ds_old = DEREF_dspec(id_storage(fid));
832
				if ((ds_old & dspec_c) && IS_id_function(fid)) {
833
					reason = 1;
834
					break;
835
				}
836
			}
837
 
838
			/* Two functions with the same parameters are the
839
			 * same */
840
			s = DEREF_type(id_function_etc_type(fid));
841
			if (tag == id_stat_mem_func_tag) {
842
				mq = 0;
843
			}
844
			if (IS_id_stat_mem_func(fid)) {
845
				mq = 0;
846
			}
847
			m = eq_func_type(t, s, mq, 0);
848
			if (m) {
849
				/* Function types basically match */
850
				if (m == 1) {
851
					/* Return types don't match */
852
					reason = 2;
853
				}
854
				break;
855
			}
856
			fid = DEREF_id(id_function_etc_over(fid));
2 7u83 857
		}
858
 
7 7u83 859
		if (IS_NULL_id(fid)) {
860
			/* No match found */
861
			IDENTIFIER tid = find_template(id, 0);
862
			if (!IS_NULL_id(tid)) {
863
				/* Must have match with template
864
				 * specialisation */
865
				report(decl_loc, ERR_temp_spec_type(t, id));
866
				return (NULL_id);
867
			}
868
			if (crt_id_qualifier != qual_none) {
869
				/* Must have match with qualified identifier */
870
				if (def == -2 && tag == id_function_tag) {
871
					/* Allow for name injection */
872
					/* EMPTY */
873
				} else {
874
					report(decl_loc,
875
					       ERR_basic_link_unmatch(t, id));
876
				}
877
				return (NULL_id);
878
			}
879
			if (reason == 0) {
880
				return (NULL_id);
881
			}
882
			fid = id;
2 7u83 883
		}
884
 
7 7u83 885
		/* Match found */
886
		ds_old = DEREF_dspec(id_storage(fid));
887
		if ((ds_old & dspec_implicit) && !(ds & dspec_implicit)) {
888
			if (IS_id_mem_func(fid)) {
889
				/* Matches implicitly declared member
890
				 * function */
891
				report(decl_loc, ERR_class_special_decl(fid));
892
				return (NULL_id);
893
			}
2 7u83 894
		}
7 7u83 895
		if (ds_old & dspec_inherit) {
896
			/* Inherited functions (including aliases) are hidden */
897
			return (NULL_id);
898
		}
899
		/* *over = NULL_id ; */
2 7u83 900
	}
901
#else
7 7u83 902
	/* Don't check overloading in C */
903
	*over = NULL_id;
904
	UNUSED(tag);
2 7u83 905
#endif
906
 
7 7u83 907
	/* Redeclare id */
908
	fid = redecl_id(ds, t, fid, reason, def);
909
	if (!IS_NULL_id(fid)) {
910
		TYPE form = DEREF_type(id_function_etc_form(id));
911
		if (def >= 0) {
912
			/* Allow for default arguments etc. */
913
			TYPE s = DEREF_type(id_function_etc_type(fid));
914
			s = redecl_func_type(fid, s, t, def, 1);
915
			COPY_type(id_function_etc_type(fid), s);
2 7u83 916
		}
7 7u83 917
		if (!IS_NULL_type(form) && IS_type_token(form)) {
918
			IDENTIFIER ext = DEREF_id(type_token_tok(form));
919
			if (!IS_NULL_id(ext) && IS_id_token(ext)) {
920
				/* Check for tokenised functions */
921
				ds = DEREF_dspec(id_storage(ext));
922
				ds |= dspec_explicit;
923
				COPY_dspec(id_storage(ext), ds);
924
				if (def) {
925
					/* Check for token definitions */
926
					IGNORE define_func_token(ext, fid);
927
					if (ds & dspec_pure) {
928
						report(decl_loc,
929
						       ERR_token_def_not(ext));
930
					}
931
				}
932
			}
933
		}
2 7u83 934
	}
7 7u83 935
	return (fid);
2 7u83 936
}
937
 
938
 
939
/*
940
    REDECLARE AN INHERITED OR ALIASED MEMBER
941
 
942
    This routine is used to allow for declarations of class members to
943
    override any inherited value of the member.  id gives the inherited
944
    value, mem is true for a member declaration, fn is true for a function
945
    declaration or a declaration which can't coexist with a function
946
    declaration.  The null identifier is returned to indicate that id is
947
    to be overridden.
948
*/
949
 
7 7u83 950
IDENTIFIER
951
redecl_inherit(IDENTIFIER id, QUALIFIER qual, int mem, int fn)
2 7u83 952
{
7 7u83 953
	if (!IS_NULL_id(id)) {
954
		DECL_SPEC ds = DEREF_dspec(id_storage(id));
955
		if (ds & dspec_alias) {
956
			if (fn && IS_id_function_etc(id)) {
957
				/* Everything is a function */
958
				return (id);
959
			}
960
			if (mem && IS_id_class_name(id)) {
961
				/* Allow for injected type names */
962
				if (ds & dspec_implicit) {
963
					return (id);
964
				}
965
			}
966
			if (qual == qual_none) {
967
				/* New declaration */
968
				PTR(LOCATION) loc = id_loc(id);
969
				report(decl_loc,
970
				       ERR_dcl_nspace_udecl_multi(id, loc));
971
				return (NULL_id);
972
			}
973
		}
974
		if (ds & dspec_inherit) {
975
			NAMESPACE ns;
976
			if (mem) {
977
				return (NULL_id);
978
			}
979
			ns = DEREF_nspace(id_parent(id));
980
			id = DEREF_id(id_alias(id));
981
			report(decl_loc, ERR_lookup_qual_decl(id, ns));
982
		}
2 7u83 983
	}
7 7u83 984
	return (id);
2 7u83 985
}
986
 
987
 
988
/*
989
    COPY AN IDENTIFIER
990
 
991
    This routine creates a copy of the identifier id.  If type is 1
992
    then any type components in id are copied using copy_typedef, if it
993
    is 2 they are further expanded using expand_type.
994
*/
995
 
7 7u83 996
IDENTIFIER
997
copy_id(IDENTIFIER id, int type)
2 7u83 998
{
7 7u83 999
	TYPE t;
1000
	ulong no;
1001
	ulong dno;
1002
	HASHID nm;
1003
	unsigned tag;
1004
	LOCATION loc;
1005
	NAMESPACE ns;
1006
	DECL_SPEC ds;
1007
	IDENTIFIER lid;
1008
	IDENTIFIER cid = id;
2 7u83 1009
 
7 7u83 1010
	/* Examine various cases */
1011
	if (IS_NULL_id(cid)) {
1012
		return (NULL_id);
1013
	}
1014
	tag = TAG_id(cid);
1015
	switch (tag) {
1016
	case id_class_name_tag:
1017
	case id_class_alias_tag:
1018
	case id_enum_name_tag:
1019
	case id_enum_alias_tag:
1020
	case id_type_alias_tag: {
1021
		/* Types */
1022
		BASE_TYPE bt;
1023
		DECONS_id_class_name_etc(nm, ds, ns, loc, lid, no, dno, t, bt,
1024
					 cid);
1025
		if (type) {
1026
			t = copy_typedef(cid, t, cv_none);
1027
			if (type == 2) {
1028
				t = expand_type(t, 1);
1029
				if (tag == id_class_name_tag) {
1030
					/* Name already copied by copy_class */
1031
					CLASS_TYPE ct;
1032
					while (IS_type_templ(t)) {
1033
						t = DEREF_type(type_templ_defn(t));
1034
					}
1035
					ct = DEREF_ctype(type_compound_defn(t));
1036
					cid = DEREF_id(ctype_name(ct));
1037
					if (!EQ_id(cid, id)) {
1038
						COPY_hashid(id_name(cid), nm);
1039
						COPY_dspec(id_storage(cid), ds);
1040
						COPY_nspace(id_parent(cid), ns);
1041
						COPY_loc(id_loc(cid), loc);
1042
						break;
1043
					}
1044
				}
1045
				if (tag != id_enum_name_tag) {
1046
					/* Find type alias tag */
1047
					unsigned ta = type_tag(t);
1048
					if (ta == type_compound_tag) {
1049
						tag = id_class_alias_tag;
1050
					} else if (ta == type_enumerate_tag) {
1051
						tag = id_enum_alias_tag;
1052
					} else {
1053
						tag = id_type_alias_tag;
1054
					}
1055
				}
2 7u83 1056
			}
7 7u83 1057
		}
1058
		MAKE_id_class_name_etc(tag, nm, ds, ns, loc, t, cid);
1059
		COPY_btype(id_class_name_etc_rep(cid), bt);
1060
		break;
1061
	}
1062
	case id_variable_tag:
1063
	case id_parameter_tag:
1064
	case id_stat_member_tag: {
1065
		/* Objects */
1066
		EXP a, b;
1067
		DECONS_id_variable_etc(nm, ds, ns, loc, lid, no, dno, t,
1068
				       a, b, cid);
1069
		if (type) {
1070
			t = copy_typedef(cid, t, cv_none);
1071
			if (type == 2) {
1072
				t = expand_type(t, 1);
2 7u83 1073
			}
7 7u83 1074
		}
1075
		MAKE_id_variable_etc(tag, nm, ds, ns, loc, t, cid);
1076
		COPY_exp(id_variable_etc_init(cid), a);
1077
		COPY_exp(id_variable_etc_term(cid), b);
1078
		break;
1079
	}
1080
	case id_function_tag:
1081
	case id_mem_func_tag:
1082
	case id_stat_mem_func_tag: {
1083
		/* Functions */
1084
		EXP a;
1085
		TYPE form;
1086
		IDENTIFIER over;
1087
		LIST(CLASS_TYPE)fr;
1088
		DECONS_id_function_etc(nm, ds, ns, loc, lid, no, dno, t,
1089
				       over, form, fr, a, cid);
1090
		if (type) {
1091
			t = copy_typedef(cid, t, cv_none);
1092
			if (type == 2) {
1093
				t = expand_type(t, 1);
2 7u83 1094
			}
1095
		}
7 7u83 1096
		MAKE_id_function_etc(tag, nm, ds, ns, loc, t, over, cid);
1097
		COPY_type(id_function_etc_form(cid), form);
1098
		COPY_exp(id_function_etc_defn(cid), a);
1099
		if (type == 2) {
1100
			/* Copy friend classes */
1101
			while (!IS_NULL_list(fr)) {
1102
				TYPE r = NULL_type;
1103
				CLASS_TYPE cr = DEREF_ctype(HEAD_list(fr));
1104
				cr = expand_ctype(cr, 2, &r);
1105
				friend_function(cr, cid, 0);
1106
				fr = TAIL_list(fr);
1107
			}
1108
		} else {
1109
			COPY_list(id_function_etc_chums(cid), fr);
1110
		}
1111
		break;
2 7u83 1112
	}
7 7u83 1113
	case id_member_tag: {
1114
		/* Members */
1115
		GRAPH gr;
1116
		OFFSET off;
1117
		DECONS_id_member(nm, ds, ns, loc, lid, no, dno, t, off, gr,
1118
				 cid);
1119
		if (type) {
1120
			t = copy_typedef(cid, t, cv_none);
1121
			if (type == 2) {
1122
				if (IS_hashid_anon(nm)) {
1123
					/* Allow for anonymous bitfields */
1124
					expand_anon_bitfield = 1;
1125
				}
1126
				t = expand_type(t, 1);
1127
				expand_anon_bitfield = 0;
1128
			}
1129
		}
1130
		MAKE_id_member(nm, ds, ns, loc, t, cid);
1131
		COPY_graph(id_member_base(cid), gr);
1132
		COPY_off(id_member_off(cid), off);
1133
		break;
2 7u83 1134
	}
7 7u83 1135
	case id_enumerator_tag: {
1136
		/* Enumerators */
1137
		EXP a;
1138
		ERROR err = NULL_err;
1139
		DECONS_id_enumerator(nm, ds, ns, loc, lid, no, dno, t, a, cid);
1140
		if (type == 2) {
1141
			/* Copy enumerator value */
1142
			TYPE s = expand_type(t, 1);
1143
			a = copy_exp(a, t, s);
1144
			IGNORE make_nat_exp(a, &err);
1145
			t = s;
2 7u83 1146
		}
7 7u83 1147
		MAKE_id_enumerator(nm, ds, ns, loc, t, a, cid);
1148
		if (!IS_NULL_err(err)) {
1149
			err = concat_error(err, ERR_dcl_enum_const(cid));
1150
			report(crt_loc, err);
1151
		}
1152
		break;
2 7u83 1153
	}
7 7u83 1154
	case id_token_tag: {
1155
		/* Tokens */
1156
		TOKEN sort;
1157
		IDENTIFIER alt;
1158
		DECONS_id_token(nm, ds, ns, loc, lid, no, dno, sort, alt, cid);
1159
		if (type == 2) {
1160
			/* Expand token sort */
1161
			sort = expand_sort(sort, 1, 1);
2 7u83 1162
		}
7 7u83 1163
		MAKE_id_token(nm, ds, ns, loc, sort, alt, cid);
1164
		break;
2 7u83 1165
	}
7 7u83 1166
	default:
1167
		/* Don't copy other identifiers */
1168
		return (cid);
2 7u83 1169
	}
1170
 
7 7u83 1171
	if (type != 2) {
1172
		COPY_id(id_alias(cid), lid);
1173
		COPY_ulong(id_no(cid), no);
1174
		COPY_ulong(id_dump(cid), dno);
2 7u83 1175
	}
7 7u83 1176
	return (cid);
2 7u83 1177
}
1178
 
1179
 
1180
/*
1181
    CREATE AN IDENTIFIER ALIAS
1182
 
1183
    This routine creates an alias for the identifier id in the namespace
1184
    ns.  fn gives a list of function which the alias will overload if
1185
    it is a function.
1186
*/
1187
 
7 7u83 1188
IDENTIFIER
1189
alias_id(IDENTIFIER id, NAMESPACE ns, IDENTIFIER fn, int rec)
2 7u83 1190
{
7 7u83 1191
	IDENTIFIER cid = copy_id(id, 1);
1192
	if (!EQ_id(cid, id)) {
1193
		DECL_SPEC ds = DEREF_dspec(id_storage(cid));
1194
		DECL_SPEC acc = (ds & dspec_access);
1195
		if (acc) {
1196
			IDENTIFIER sid = DEREF_id(nspace_name(ns));
1197
			immediate_access(sid, cid);
2 7u83 1198
		}
7 7u83 1199
		ds = ((ds & ~dspec_access) | dspec_alias | crt_access);
1200
		COPY_dspec(id_storage(cid), ds);
1201
		COPY_nspace(id_parent(cid), ns);
1202
		if (do_dump) {
1203
			dump_alias(cid, id, &crt_loc);
1204
		}
1205
		if (IS_id_function_etc(cid)) {
1206
			/* Deal with overloaded functions */
1207
			IDENTIFIER over;
1208
			if (rec) {
1209
				over = DEREF_id(id_function_etc_over(cid));
1210
				if (IS_NULL_id(over)) {
1211
					over = fn;
1212
				} else {
1213
					over = alias_id(over, ns, fn, rec);
1214
				}
1215
			} else {
1216
				over = fn;
1217
			}
1218
			COPY_id(id_function_etc_over(cid), over);
1219
		}
2 7u83 1220
	}
7 7u83 1221
	return (cid);
2 7u83 1222
}
1223
 
1224
 
1225
/*
1226
    DUMMY DECLARATION SPECIFIER
1227
 
1228
    This value is used as a dummy declaration specifier in the adjusting
1229
    of overloaded functions.
1230
*/
1231
 
7 7u83 1232
#define dspec_mark	((DECL_SPEC)0x7fffffff)
2 7u83 1233
 
1234
 
1235
/*
1236
    REMOVE HIDDEN FUNCTIONS
1237
 
1238
    This routine adjusts the set of overloaded functions id by removing
1239
    any with storage field equal to dspec_mark.
1240
*/
1241
 
7 7u83 1242
static IDENTIFIER
1243
remove_functions(IDENTIFIER id)
2 7u83 1244
{
7 7u83 1245
	if (!IS_NULL_id(id)) {
1246
		DECL_SPEC ds = DEREF_dspec(id_storage(id));
1247
		IDENTIFIER over = DEREF_id(id_function_etc_over(id));
1248
		over = remove_functions(over);
1249
		if (ds == dspec_mark) {
1250
			id = over;
1251
		} else {
1252
			COPY_id(id_function_etc_over(id), over);
1253
		}
2 7u83 1254
	}
7 7u83 1255
	return (id);
2 7u83 1256
}
1257
 
1258
 
1259
/*
1260
    COMPARE HIDING FUNCTIONS
1261
 
1262
    This routine compares two functions id and over, one declared in the
1263
    normal fashion and the other by a using-declaration.  It returns
1264
    true if the former overrides the latter.
1265
*/
1266
 
7 7u83 1267
static int
1268
compare_functions(IDENTIFIER id, IDENTIFIER over, int mem)
2 7u83 1269
{
7 7u83 1270
	TYPE t = DEREF_type(id_function_etc_type(id));
1271
	TYPE s = DEREF_type(id_function_etc_type(over));
1272
	int eq = eq_func_type(t, s, 1, 0);
1273
	if (eq) {
1274
		/* Equal parameter types */
1275
		if (mem) {
1276
			return (1);
1277
		}
1278
	}
1279
	if (eq >= 2) {
1280
		/* Equal types */
1281
		PTR(LOCATION)loc = id_loc(over);
1282
		report(crt_loc, ERR_dcl_nspace_udecl_multi(over, loc));
1283
		return (1);
1284
	}
1285
	return (0);
2 7u83 1286
}
1287
 
1288
 
1289
/*
1290
    MARK HIDDEN FUNCTIONS
1291
 
1292
    This routine marks any functions which hide, or are hidden by, id in
1293
    its set of overloaded functions.  mem is true for member functions.
1294
    Any hidden function is marked by setting its storage field to the
1295
    value dspec_mark.
1296
*/
1297
 
7 7u83 1298
static int
1299
mark_functions(IDENTIFIER id, int mem)
2 7u83 1300
{
7 7u83 1301
    int ret = 0;
1302
    DECL_SPEC ds = DEREF_dspec(id_storage(id));
1303
    if (ds != dspec_mark) {
1304
	IDENTIFIER over = DEREF_id(id_function_etc_over(id));
1305
	while (!IS_NULL_id(over)) {
1306
	    DECL_SPEC pds = DEREF_dspec(id_storage(over));
1307
	    if (pds != dspec_mark) {
1308
		if (ds & dspec_alias) {
1309
		    if (pds & dspec_alias) {
2 7u83 1310
			/* Both are using declarations */
7 7u83 1311
			IDENTIFIER a = DEREF_id(id_alias(id));
1312
			IDENTIFIER b = DEREF_id(id_alias(over));
1313
			if (EQ_id(a, b)) {
2 7u83 1314
			    /* Duplicate declarations */
7 7u83 1315
			    if (mem) {
1316
				ERROR err;
1317
				PTR(LOCATION) loc = id_loc(over);
1318
				err = ERR_class_mem_redecl(over, loc);
1319
				report(crt_loc, err);
2 7u83 1320
			    }
7 7u83 1321
			    COPY_dspec(id_storage(over), dspec_mark);
1322
			    ret++;
2 7u83 1323
			}
1324
		    } else {
1325
			/* The first is a using declaration */
7 7u83 1326
			if (compare_functions(id, over, mem)) {
1327
			    COPY_dspec(id_storage(id), dspec_mark);
1328
			    ret++;
2 7u83 1329
			}
1330
		    }
7 7u83 1331
		} else if (pds & dspec_alias) {
2 7u83 1332
		    /* The second is a using declaration */
7 7u83 1333
		    if (compare_functions(id, over, mem)) {
1334
			COPY_dspec(id_storage(over), dspec_mark);
1335
			ret++;
1336
			break;
2 7u83 1337
		    }
1338
		}
1339
	    }
7 7u83 1340
	    over = DEREF_id(id_function_etc_over(over));
2 7u83 1341
	}
1342
    }
7 7u83 1343
    return (ret);
2 7u83 1344
}
1345
 
1346
 
1347
/*
1348
    HANDLE HIDDEN FUNCTIONS WITH USING DECLARATIONS
1349
 
1350
    The interaction of using declarations with the hiding and overriding
1351
    of member functions is somewhat complex.  It is implemented by this
1352
    routine which adjusts the declarations of the overloaded functions id
1353
    up to the existing declarations over.  mem is true for member functions.
1354
*/
1355
 
7 7u83 1356
IDENTIFIER
1357
hide_functions(IDENTIFIER id, IDENTIFIER over, int mem)
2 7u83 1358
{
7 7u83 1359
	if (!IS_NULL_id(over)) {
1360
		int marked = 0;
1361
		IDENTIFIER pid = id;
1362
		while (!EQ_id(pid, over)) {
1363
			marked += mark_functions(pid, mem);
1364
			pid = DEREF_id(id_function_etc_over(pid));
1365
		}
1366
		if (marked) {
1367
			id = remove_functions(id);
1368
		}
1369
		pid = id;
1370
		while (!IS_NULL_id(pid)) {
1371
			/* Mark template functions */
1372
			DECL_SPEC ds = DEREF_dspec(id_storage(pid));
1373
			if (ds & dspec_template) {
1374
				templ_func_decl(id);
1375
				break;
1376
			}
1377
			pid = DEREF_id(id_function_etc_over(pid));
1378
		}
2 7u83 1379
	}
7 7u83 1380
	return (id);
2 7u83 1381
}
1382
 
1383
 
1384
/*
1385
    CHECK THE VISIBILITY OF AN IDENTIFIER
1386
 
1387
    A member name in a using declaration should be visible from a direct
1388
    base class.  This routine checks whether the member id meets this
1389
    criterion by comparing it with its look-up in the direct base
1390
    classes, pid.
1391
*/
1392
 
7 7u83 1393
static int
1394
using_visible(IDENTIFIER id, IDENTIFIER pid)
2 7u83 1395
{
7 7u83 1396
	while (!IS_NULL_id(pid)) {
1397
		IDENTIFIER qid = DEREF_id(id_alias(pid));
1398
		if (EQ_id(qid, id)) {
1399
			return (1);
2 7u83 1400
		}
7 7u83 1401
		switch (TAG_id(pid)) {
1402
		case id_function_tag:
1403
		case id_mem_func_tag:
1404
		case id_stat_mem_func_tag:
1405
			/* Check overloaded functions */
1406
			pid = DEREF_id(id_function_etc_over(pid));
1407
			break;
1408
		case id_ambig_tag: {
1409
			/* Check ambiguous identifiers */
1410
			LIST(IDENTIFIER)pids;
1411
			pids = DEREF_list(id_ambig_ids(pid));
1412
			while (!IS_NULL_list(pids)) {
1413
				pid = DEREF_id(HEAD_list(pids));
1414
				if (using_visible(id, pid)) {
1415
					return (1);
1416
				}
1417
				pids = TAIL_list(pids);
1418
			}
1419
			return (0);
1420
		}
1421
		default:
1422
			/* Other identifiers */
1423
			return (0);
1424
		}
2 7u83 1425
	}
7 7u83 1426
	return (0);
2 7u83 1427
}
1428
 
1429
 
1430
/*
1431
    PROCESS A CLASS USING DECLARATION
1432
 
1433
    This routine processes a using-declaration of the identifier id in
1434
    the case when this declaration is a member-declaration.
1435
*/
1436
 
7 7u83 1437
static IDENTIFIER
1438
using_member(IDENTIFIER id, int type)
2 7u83 1439
{
7 7u83 1440
	MEMBER mem;
1441
	IDENTIFIER aid;
1442
	IDENTIFIER pid;
2 7u83 1443
 
7 7u83 1444
	/* Check the identifier */
1445
	NAMESPACE cns = crt_namespace;
1446
	HASHID nm = DEREF_hashid(id_name(id));
1447
	GRAPH gr = is_subfield(cns, id);
1448
	if (IS_NULL_graph(gr)) {
1449
		/* id is not a member of a base class */
1450
		CLASS_TYPE ct = crt_class;
1451
		report(crt_loc, ERR_dcl_nspace_udecl_base(id, ct));
1452
		return (NULL_id);
1453
	} else {
1454
		GRAPH gu = DEREF_graph(graph_up(gr));
1455
		GRAPH gt = DEREF_graph(graph_top(gr));
1456
		if (EQ_graph(gt, gr)) {
1457
			/* id is a member of the current class */
1458
			report(crt_loc, ERR_dcl_nspace_udecl_mem(id));
1459
			return (id);
2 7u83 1460
		}
7 7u83 1461
		if (!EQ_graph(gt, gu)) {
1462
			/* Not a member of a direct base class */
1463
			IDENTIFIER bid = search_base_field(cns, nm, type, 0);
1464
			aid = id;
1465
			while (!IS_NULL_id(aid)) {
1466
				IDENTIFIER qid = find_template(aid, 1);
1467
				if (IS_NULL_id(qid)) {
1468
					qid = aid;
1469
				}
1470
				qid = DEREF_id(id_alias(qid));
1471
				if (!using_visible(qid, bid)) {
1472
					CLASS_TYPE ct = crt_class;
1473
					report(crt_loc, ERR_dcl_nspace_udecl_vis(aid, ct));
1474
					break;
1475
				}
1476
				if (!IS_id_function_etc(aid)) {
1477
					break;
1478
				}
1479
				aid = DEREF_id(id_function_etc_over(aid));
1480
			}
1481
		}
2 7u83 1482
	}
1483
 
7 7u83 1484
	/* Check declarations */
1485
	mem = search_member(cns, nm, 1);
1486
	if (type) {
1487
		DECL_SPEC ds = DEREF_dspec(id_storage(id));
1488
		if (ds & dspec_template) {
1489
			pid = DEREF_id(member_id(mem));
1490
		} else {
1491
			pid = type_member(mem, 3);
1492
		}
2 7u83 1493
	} else {
7 7u83 1494
		pid = DEREF_id(member_id(mem));
1495
		if (!IS_NULL_id(pid) && is_tagged_type(pid)) {
1496
			/* Allow hiding of non-template classes */
1497
			DECL_SPEC ds = DEREF_dspec(id_storage(pid));
1498
			if (!(ds & dspec_template)) {
1499
				pid = NULL_id;
1500
			}
1501
		}
2 7u83 1502
	}
7 7u83 1503
	if (!IS_NULL_id(pid)) {
1504
		DECL_SPEC ds = DEREF_dspec(id_storage(pid));
1505
		if ((ds & dspec_inherit) && !(ds & dspec_alias)) {
1506
			/* Ignore inherited members */
1507
			pid = NULL_id;
1508
		} else {
1509
			IDENTIFIER rid = DEREF_id(id_alias(id));
1510
			IDENTIFIER qid = DEREF_id(id_alias(pid));
1511
			if (EQ_id(rid, qid)) {
1512
				/* Redeclaration of existing meaning */
1513
				if (!type) {
1514
					PTR(LOCATION)loc = id_loc(pid);
1515
					ERROR err =
1516
					    ERR_class_mem_redecl(pid, loc);
1517
					report(crt_loc, err);
1518
				}
1519
				adjust_access(pid, crt_access, 1);
1520
				return (pid);
1521
			}
1522
			if (IS_id_function_etc(id) && IS_id_function_etc(pid)) {
1523
				/* Both new and old meanings are functions */
1524
				/* EMPTY */
1525
			} else {
1526
				/* One meaning is not a function */
1527
				PTR(LOCATION) loc = id_loc(pid);
1528
				ERROR err =
1529
				    ERR_dcl_nspace_udecl_multi(pid, loc);
1530
				report(crt_loc, err);
1531
				return (NULL_id);
1532
			}
1533
		}
2 7u83 1534
	}
7 7u83 1535
 
1536
	/* Find inherited member */
1537
	id = search_subfield(cns, gr, id);
1538
	aid = alias_id(id, cns, pid, 1);
1539
	if (!IS_NULL_id(pid)) {
1540
		/* Deal with function hiding */
1541
		aid = hide_functions(aid, pid, 1);
1542
	}
1543
	adjust_access(id, crt_access, 1);
1544
	if (type) {
1545
		set_type_member(mem, aid);
2 7u83 1546
	} else {
7 7u83 1547
		set_member(mem, aid);
2 7u83 1548
	}
7 7u83 1549
	return (aid);
2 7u83 1550
}
1551
 
1552
 
1553
/*
1554
    PROCESS A NAMESPACE USING DECLARATION
1555
 
1556
    This routine processes a using-declaration of the identifier id in
1557
    the case when this declaration is not a member-declaration.
1558
*/
1559
 
7 7u83 1560
static IDENTIFIER
1561
using_name(IDENTIFIER id)
2 7u83 1562
{
7 7u83 1563
	int type;
1564
	HASHID nm;
1565
	MEMBER mem;
1566
	IDENTIFIER pid;
2 7u83 1567
 
7 7u83 1568
	/* Check the identifier */
1569
	NAMESPACE cns = crt_namespace;
1570
	NAMESPACE ns = DEREF_nspace(id_parent(id));
1571
	if (IS_nspace_ctype(ns)) {
1572
		/* id denotes a class member */
1573
		report(crt_loc, ERR_dcl_nspace_udecl_id(id));
1574
		switch (TAG_id(id)) {
1575
		case id_member_tag:
1576
		case id_stat_member_tag:
1577
		case id_mem_func_tag:
1578
		case id_stat_mem_func_tag:
1579
			/* Don't even try in these cases */
1580
			return (NULL_id);
1581
		}
2 7u83 1582
	}
1583
 
7 7u83 1584
	/* Check declarations */
1585
	nm = DEREF_hashid(id_name(id));
1586
	mem = search_member(cns, nm, 1);
1587
	type = is_tagged_type(id);
1588
	if (type) {
1589
		DECL_SPEC ds = DEREF_dspec(id_storage(id));
1590
		if (ds & dspec_template) {
1591
			pid = DEREF_id(member_id(mem));
1592
		} else {
1593
			pid = type_member(mem, 3);
1594
		}
2 7u83 1595
	} else {
7 7u83 1596
		pid = DEREF_id(member_id(mem));
1597
		if (!IS_id_nspace_name_etc(id)) {
1598
			if (!IS_NULL_id(pid) && is_tagged_type(pid)) {
1599
				/* Allow hiding of non-template classes */
1600
				DECL_SPEC ds = DEREF_dspec(id_storage(pid));
1601
				if (!(ds & dspec_template)) {
1602
					pid = NULL_id;
1603
				}
1604
			}
1605
		}
2 7u83 1606
	}
7 7u83 1607
	if (!IS_NULL_id(pid)) {
1608
		IDENTIFIER qid = DEREF_id(id_alias(pid));
1609
		if (EQ_id(id, qid)) {
1610
			/* Redeclaration of existing meaning */
1611
			if (EQ_id(id, pid)) {
1612
				report(crt_loc, ERR_dcl_nspace_udecl_mem(id));
1613
			}
1614
			return (pid);
1615
		}
1616
		if (IS_id_function_etc(id) && IS_id_function_etc(pid)) {
1617
			/* Both new and old meanings are functions */
1618
			/* EMPTY */
1619
		} else {
1620
			/* Invalid redeclaration */
1621
			PTR(LOCATION) loc = id_loc(pid);
1622
			ERROR err = ERR_dcl_nspace_udecl_multi(pid, loc);
1623
			report(crt_loc, err);
1624
			pid = NULL_id;
1625
		}
2 7u83 1626
	}
7 7u83 1627
 
1628
	/* Create the alias */
1629
	id = alias_id(id, cns, pid, 1);
1630
	if (!IS_NULL_id(pid)) {
1631
		/* Deal with function hiding */
1632
		id = hide_functions(id, pid, 0);
2 7u83 1633
	}
7 7u83 1634
	if (type) {
1635
		set_type_member(mem, id);
2 7u83 1636
	} else {
7 7u83 1637
		set_member(mem, id);
2 7u83 1638
	}
7 7u83 1639
	return (id);
2 7u83 1640
}
1641
 
1642
 
1643
/*
1644
    PROCESS A USING DECLARATION
1645
 
1646
    This routine processes a using-declaration of the identifier id.  Note
1647
    that this includes the access declarations used to modify access to
1648
    class members.
1649
*/
1650
 
7 7u83 1651
IDENTIFIER
1652
using_identifier(IDENTIFIER id)
2 7u83 1653
{
7 7u83 1654
	/* Identifier must be qualified */
1655
	MEMBER mem;
1656
	HASHID unm;
1657
	IDENTIFIER cid;
1658
	IDENTIFIER uid = id;
1659
	NAMESPACE uns = DEREF_nspace(id_parent(uid));
1660
	uid = constr_name(uns, uid);
1661
	unm = DEREF_hashid(id_name(uid));
1662
	if (crt_id_qualifier == qual_none) {
1663
		report(crt_loc, ERR_dcl_nspace_udecl_unqual());
1664
		return (uid);
1665
	}
2 7u83 1666
 
7 7u83 1667
	/* Report undefined and ambiguous identifiers */
1668
	switch (TAG_id(uid)) {
1669
	case id_ambig_tag: {
1670
		/* Introduce all the ambiguous meanings */
1671
		LIST(IDENTIFIER) pids = DEREF_list(id_ambig_ids(uid));
1672
		while (!IS_NULL_list(pids)) {
1673
			IDENTIFIER pid = DEREF_id(HEAD_list(pids));
1674
			IGNORE using_identifier(pid);
1675
			pids = TAIL_list(pids);
1676
		}
1677
		uid = find_qual_id(crt_namespace, unm, 0, 0);
1678
		return (uid);
2 7u83 1679
	}
7 7u83 1680
	case id_undef_tag:
1681
		/* Report undeclared identifiers */
1682
		report(crt_loc, ERR_lookup_qual_undef(unm, uns));
1683
		return (uid);
2 7u83 1684
	}
1685
 
7 7u83 1686
	/* Can have constructors or destructors */
1687
	switch (TAG_hashid(unm)) {
1688
	case hashid_constr_tag:
1689
	case hashid_destr_tag:
1690
		report(crt_loc, ERR_dcl_nspace_udecl_constr(uid));
1691
		return (uid);
2 7u83 1692
	}
1693
 
7 7u83 1694
	/* Check for hidden type names */
1695
	mem = search_member(uns, unm, 0);
1696
	cid = type_member(mem, 1);
1697
	if (EQ_id(cid, uid)) {
1698
		cid = NULL_id;
1699
	}
2 7u83 1700
 
7 7u83 1701
	/* Process the declaration */
1702
	if (in_class_defn) {
1703
		if (!IS_NULL_id(cid)) {
1704
			IGNORE using_member(cid, 1);
1705
		}
1706
		uid = using_member(uid, 0);
1707
	} else {
1708
		if (!IS_NULL_id(cid)) {
1709
			cid = DEREF_id(id_alias(cid));
1710
			IGNORE using_name(cid);
1711
		}
1712
		uid = DEREF_id(id_alias(uid));
1713
		uid = using_name(uid);
2 7u83 1714
	}
7 7u83 1715
	if (IS_NULL_id(uid)) {
1716
		uid = id;
1717
	} else {
1718
		/* Check for hiding */
1719
		if (option(OPT_decl_hide)) {
1720
			switch (TAG_id(id)) {
1721
			case id_variable_tag:
1722
			case id_function_tag:
1723
				check_hiding(uid);
1724
				break;
1725
			}
2 7u83 1726
		}
1727
	}
7 7u83 1728
	return (uid);
2 7u83 1729
}
1730
 
1731
 
1732
/*
1733
    PROCESS A USING TYPENAME DECLARATION
1734
 
1735
    This routine processes a using-declaration involving the type t
1736
    declared using typename.
1737
*/
1738
 
7 7u83 1739
void
1740
using_typename(TYPE t)
2 7u83 1741
{
7 7u83 1742
	UNUSED(t);
1743
	return;
2 7u83 1744
}
1745
 
1746
 
1747
/*
1748
    REDECLARE AN IDENTIFIER
1749
 
1750
    This routine redeclares the identifier id in the namespace ns.
1751
*/
1752
 
7 7u83 1753
IDENTIFIER
1754
redeclare_id(NAMESPACE ns, IDENTIFIER id)
2 7u83 1755
{
7 7u83 1756
	IDENTIFIER old_id;
1757
	int cl = is_tagged_type(id);
1758
	HASHID nm = DEREF_hashid(id_name(id));
1759
	MEMBER mem = search_member(ns, nm, 1);
1760
	DECL_SPEC ds = DEREF_dspec(id_storage(id));
1761
	if (cl) {
1762
		old_id = type_member(mem, 3);
1763
	} else {
1764
		old_id = DEREF_id(member_id(mem));
1765
	}
1766
	if (!IS_NULL_id(old_id)) {
1767
		PTR(LOCATION) loc = id_loc(old_id);
1768
		report(crt_loc, ERR_basic_odr_decl(old_id, loc));
1769
	}
1770
	if (cl) {
1771
		set_type_member(mem, id);
1772
	} else {
1773
		set_member(mem, id);
1774
	}
1775
	ds |= dspec_reserve;
1776
	COPY_dspec(id_storage(id), ds);
1777
	COPY_nspace(id_parent(id), ns);
1778
	return (id);
2 7u83 1779
}
1780
 
1781
 
1782
/*
1783
    CHECK ANONYMOUS UNION MEMBER
1784
 
1785
    This routine checks whether the identifier id is member of an
1786
    anonymous union.
1787
*/
1788
 
7 7u83 1789
int
1790
is_anon_member(IDENTIFIER id)
2 7u83 1791
{
7 7u83 1792
	DECL_SPEC ds = DEREF_dspec(id_storage(id));
1793
	if (ds & dspec_reserve) {
1794
		IDENTIFIER pid = DEREF_id(id_alias(id));
1795
		if (!EQ_id(pid, id)) {
1796
			TYPE s = DEREF_type(id_variable_etc_type(pid));
1797
			if (IS_type_compound(s)) {
1798
				TYPE t = DEREF_type(id_variable_etc_type(id));
1799
				if (!eq_type(s, t)) {
1800
					return (1);
1801
				}
1802
			}
1803
		}
2 7u83 1804
	}
7 7u83 1805
	return (0);
2 7u83 1806
}
1807
 
1808
 
1809
/*
1810
    REDECLARE A MEMBER OF AN ANONYMOUS UNION
1811
 
1812
    This routine redeclares the member id of an anonymous union.  The
1813
    remaining arguments are as in redecl_anon_union.
1814
*/
1815
 
7 7u83 1816
static IDENTIFIER
1817
redecl_anon_member(IDENTIFIER id, CLASS_TYPE ct, DECL_SPEC ds, IDENTIFIER obj)
2 7u83 1818
{
7 7u83 1819
	IDENTIFIER pid = NULL_id;
1820
	HASHID nm = DEREF_hashid(id_name(id));
1821
	if (!IS_hashid_anon(nm)) {
1822
		switch (TAG_id(id)) {
1823
		case id_member_tag: {
1824
			/* Redeclare a type member */
1825
			TYPE t = DEREF_type(id_member_type(id));
1826
			DEREF_loc(id_loc(id), crt_loc);
1827
			if (IS_id_member(obj)) {
1828
				NAMESPACE cns = crt_namespace;
1829
				OFFSET off1 = DEREF_off(id_member_off(id));
1830
				OFFSET off2 = DEREF_off(id_member_off(obj));
1831
				id = find_id(nm);
1832
				id = constr_name(cns, id);
1833
				id = make_member_decl(ds, t, id, 0);
1834
				MAKE_off_plus(off2, off1, off1);
1835
				COPY_off(id_member_off(id), off1);
1836
			} else {
1837
				id = make_object_decl(ds, t, id, 0);
1838
				obj = DEREF_id(id_alias(obj));
1839
				COPY_id(id_alias(id), obj);
1840
			}
1841
			pid = id;
1842
			break;
2 7u83 1843
		}
7 7u83 1844
		case id_class_name_tag: {
1845
			/* Redeclare a class name */
1846
			int templ = 0;
1847
			CLASS_TYPE cs;
1848
			TYPE t = DEREF_type(id_class_name_defn(id));
1849
			while (IS_type_templ(t)) {
1850
				templ = 1;
1851
				t = DEREF_type(type_templ_defn(t));
1852
			}
1853
			cs = DEREF_ctype(type_compound_defn(t));
1854
			if (!eq_ctype(ct, cs)) {
1855
				NAMESPACE cns = crt_namespace;
1856
				if (templ) {
1857
					/* Shouldn't be a template class */
1858
					LOCATION loc;
1859
					DEREF_loc(id_loc(id), loc);
1860
					report(loc, ERR_temp_decl_bad());
1861
				}
1862
				pid = redeclare_id(cns, id);
1863
			}
1864
			break;
2 7u83 1865
		}
7 7u83 1866
		case id_enum_name_tag:
1867
		case id_class_alias_tag:
1868
		case id_enum_alias_tag:
1869
		case id_type_alias_tag:
1870
		case id_enumerator_tag: {
1871
			/* Redeclare other identifiers */
1872
			NAMESPACE cns = crt_namespace;
1873
			pid = redeclare_id(cns, id);
1874
			break;
2 7u83 1875
		}
7 7u83 1876
		}
2 7u83 1877
	}
7 7u83 1878
	return (pid);
2 7u83 1879
}
1880
 
1881
 
1882
/*
1883
    REDECLARE AN ANONYMOUS UNION
1884
 
1885
    This routine redeclares all the members of the anonymous union obj of
1886
    type ct in the current namespace using the declaration specifiers ds.
1887
    The routine returns false if there are no members to redeclare.  The
1888
    redeclared members are added to the extra field of the namespace given
1889
    by ct.
1890
*/
1891
 
7 7u83 1892
int
1893
redecl_anon_union(CLASS_TYPE ct, DECL_SPEC ds, IDENTIFIER obj)
2 7u83 1894
{
7 7u83 1895
	int ok = 0;
1896
	MEMBER mem;
1897
	NAMESPACE ns;
1898
	LOCATION old_loc;
1899
	bad_crt_loc++;
1900
	old_loc = crt_loc;
1901
	ds |= dspec_reserve;
1902
	crt_id_qualifier = qual_none;
1903
	crt_templ_qualifier = 0;
1904
	ns = DEREF_nspace(ctype_member(ct));
1905
	mem = DEREF_member(nspace_ctype_first(ns));
1906
	while (!IS_NULL_member(mem)) {
1907
		IDENTIFIER id = DEREF_id(member_id(mem));
1908
		IDENTIFIER aid = DEREF_id(member_alt(mem));
1909
		if (!IS_NULL_id(aid) && !EQ_id(aid, id)) {
1910
			aid = redecl_anon_member(aid, ct, ds, obj);
1911
			if (!IS_NULL_id(aid)) {
1912
				ok = 1;
1913
			}
1914
		}
1915
		if (!IS_NULL_id(id)) {
1916
			id = redecl_anon_member(id, ct, ds, obj);
1917
			if (!IS_NULL_id(id)) {
1918
				ok = 1;
1919
			}
1920
		}
1921
		mem = DEREF_member(member_next(mem));
2 7u83 1922
	}
7 7u83 1923
	crt_loc = old_loc;
1924
	bad_crt_loc--;
1925
	return (ok);
2 7u83 1926
}