Subversion Repositories tendra.SVN

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

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