Subversion Repositories tendra.SVN

Rev

Rev 2 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 7u83 1
/*
2
    		 Crown Copyright (c) 1997, 1998
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 "graph_ops.h"
35
#include "hashid_ops.h"
36
#include "id_ops.h"
37
#include "member_ops.h"
38
#include "nspace_ops.h"
39
#include "type_ops.h"
40
#include "error.h"
41
#include "catalog.h"
42
#include "option.h"
43
#include "access.h"
44
#include "class.h"
45
#include "declare.h"
46
#include "derive.h"
47
#include "dump.h"
48
#include "hash.h"
49
#include "identifier.h"
50
#include "instance.h"
51
#include "label.h"
52
#include "namespace.h"
53
#include "parse.h"
54
#include "predict.h"
55
#include "print.h"
56
#include "redeclare.h"
57
#include "syntax.h"
58
#include "tokdef.h"
59
#include "ustring.h"
60
#include "variable.h"
61
 
62
 
63
/*
64
    CURRENT NAMESPACE LISTS
65
 
66
    These variables give the current namespace (the one which is currently
67
    being defined) and the stack of all enclosing namespaces.  Another stack
68
    of namespaces, which will be a superset of the first, gives the list
69
    of locations to be searched during name look-up.
70
*/
71
 
72
NAMESPACE crt_namespace = NULL_nspace ;
73
NAMESPACE last_namespace = NULL_nspace ;
74
NAMESPACE qual_namespace = NULL_nspace ;
75
STACK ( NAMESPACE ) namespace_stack = NULL_stack ( NAMESPACE ) ;
76
STACK ( NAMESPACE ) crt_nspace_stack = NULL_stack ( NAMESPACE ) ;
77
STACK ( NAMESPACE ) local_nspace_stack = NULL_stack ( NAMESPACE ) ;
78
 
79
 
80
/*
81
    STANDARD NAMESPACES
82
 
83
    These variables give the various standard namespaces, including the
84
    global namespace and the external token namespace.  In addition a
85
    dynamic record of the smallest named namespace enclosing the current
86
    namespace and the smallest named or block namespace (or, if the
87
    proto_scope option is true, function prototype namespace) enclosing
88
    the current namespace are maintained in nonblock_namespace and
89
    nonclass_namespace respectively.
90
*/
91
 
92
NAMESPACE global_namespace = NULL_nspace ;
93
NAMESPACE token_namespace = NULL_nspace ;
94
NAMESPACE c_namespace = NULL_nspace ;
95
NAMESPACE nonblock_namespace = NULL_nspace ;
96
NAMESPACE nonclass_namespace = NULL_nspace ;
97
static NAMESPACE scope_namespace = NULL_nspace ;
98
 
99
 
100
/*
101
    STANDARD NAMESPACE IDENTIFIERS
102
 
103
    The identifier local_namespace_id is used as the name for all unnamed
104
    namespaces defined within the current translation unit.
105
*/
106
 
107
static IDENTIFIER local_namespace_id = NULL_id ;
108
 
109
 
110
/*
111
    NAME LOOK-UP CACHE FLAG
112
 
113
    This flag is set to indicate that name look-up should be cached
114
    whenever possible.  It is switched off temporarily in field selectors
115
    as an optimisation.
116
*/
117
 
118
int cache_lookup = 1 ;
119
int old_cache_lookup = 1 ;
120
 
121
 
122
/*
123
    CREATE A STANDARD NAMESPACE
124
 
125
    This routine creates a global namespace of size sz with a dummy name
126
    given by s.
127
*/
128
 
129
NAMESPACE make_global_nspace
130
    PROTO_N ( ( s, sz ) )
131
    PROTO_T ( CONST char *s X int sz )
132
{
133
    IDENTIFIER id ;
134
    string u = ustrlit ( s ) ;
135
    NAMESPACE ns = NULL_nspace ;
136
    DECL_SPEC ds = ( dspec_defn | dspec_extern ) ;
137
    HASHID nm = lookup_name ( u, hash ( u ), 1, lex_identifier ) ;
138
    MAKE_id_nspace_name ( nm, ds, NULL_nspace, crt_loc, ns, id ) ;
139
    ns = make_namespace ( id, nspace_global_tag, sz ) ;
140
    COPY_nspace ( id_nspace_name_defn ( id ), ns ) ;
141
    return ( ns ) ;
142
}
143
 
144
 
145
/*
146
    INITIALISE STANDARD NAMESPACES
147
 
148
    This routine initialises the standard namespaces above.
149
*/
150
 
151
void init_namespace
152
    PROTO_Z ()
153
{
154
    string s = ustrlit ( "<local>" ) ;
155
    HASHID nm = lookup_name ( s, hash ( s ), 1, lex_identifier ) ;
156
    local_namespace_id = DEREF_id ( hashid_id ( nm ) ) ;
157
    global_namespace = make_global_nspace ( "<global>", 50 ) ;
158
#if LANGUAGE_CPP
159
    c_namespace = make_global_nspace ( "<c>", 50 ) ;
160
#endif
161
    token_namespace = make_global_nspace ( "<token>", 50 ) ;
162
    scope_namespace = make_global_nspace ( "<scope>", 50 ) ;
163
    last_namespace = global_namespace ;
164
    old_cache_lookup = cache_lookup ;
165
    return ;
166
}
167
 
168
 
169
/*
170
    DOES ONE NAMESPACE CONTAIN ANOTHER?
171
 
172
    This routine checks whether the namespace ns contains the definition
173
    of the namespace pns.
174
*/
175
 
176
int is_subnspace
177
    PROTO_N ( ( ns, pns ) )
178
    PROTO_T ( NAMESPACE ns X NAMESPACE pns )
179
{
180
    if ( EQ_nspace ( ns, pns ) ) return ( 1 ) ;
181
    while ( !IS_NULL_nspace ( pns ) ) {
182
	pns = DEREF_nspace ( nspace_parent ( pns ) ) ;
183
	if ( EQ_nspace ( ns, pns ) ) return ( 1 ) ;
184
    }
185
    return ( 0 ) ;
186
}
187
 
188
 
189
/*
190
    FIND THE JOIN OF TWO NAMESPACES
191
 
192
    This routine finds the join of the namespaces ns and nt, that is to
193
    say the smallest namespace which contains both ns and nt.  A using
194
    directive for nt in ns causes the members of nt to be treated as
195
    members of the join namespace for the purposes of unqualified name
196
    look-up.
197
*/
198
 
199
static NAMESPACE join_namespace
200
    PROTO_N ( ( ns, nt ) )
201
    PROTO_T ( NAMESPACE ns X NAMESPACE nt )
202
{
203
    while ( !EQ_nspace ( ns, nt ) ) {
204
	if ( IS_NULL_nspace ( ns ) ) return ( NULL_nspace ) ;
205
	if ( IS_NULL_nspace ( nt ) ) return ( NULL_nspace ) ;
206
	if ( is_subnspace ( ns, nt ) ) return ( ns ) ;
207
	if ( is_subnspace ( nt, ns ) ) return ( nt ) ;
208
	ns = DEREF_nspace ( nspace_parent ( ns ) ) ;
209
	nt = DEREF_nspace ( nspace_parent ( nt ) ) ;
210
    }
211
    return ( ns ) ;
212
}
213
 
214
 
215
/*
216
    UNCACHE A NAMESPACE
217
 
218
    This routine clears the cached name look-ups for all the names
219
    accessible from the namespace ns.
220
*/
221
 
222
void uncache_namespace
223
    PROTO_N ( ( ns, add ) )
224
    PROTO_T ( NAMESPACE ns X int add )
225
{
226
    if ( !IS_NULL_nspace ( ns ) && cache_lookup ) {
227
	MEMBER mem ;
228
	LIST ( NAMESPACE ) uns ;
229
 
230
	/* Clear cache fields for all members */
231
	if ( IS_nspace_named_etc ( ns ) ) {
232
	    mem = DEREF_member ( nspace_named_etc_first ( ns ) ) ;
233
	} else {
234
	    mem = DEREF_member ( nspace_last ( ns ) ) ;
235
	}
236
	while ( !IS_NULL_member ( mem ) ) {
237
	    IDENTIFIER id = DEREF_id ( member_id ( mem ) ) ;
238
	    if ( !IS_NULL_id ( id ) ) {
239
		HASHID nm = DEREF_hashid ( id_name ( id ) ) ;
240
		if ( !add ) id = NULL_id ;
241
		COPY_id ( hashid_cache ( nm ), id ) ;
242
	    }
243
	    mem = DEREF_member ( member_next ( mem ) ) ;
244
	}
245
 
246
	/* Recursively clear all used namespaces */
247
	uns = DEREF_list ( nspace_use ( ns ) ) ;
248
	if ( !IS_NULL_list ( uns ) ) {
249
	    LIST ( NAMESPACE ) lns = uns ;
250
	    COPY_list ( nspace_use ( ns ), NULL_list ( NAMESPACE ) ) ;
251
	    while ( !IS_NULL_list ( lns ) ) {
252
		NAMESPACE pns = DEREF_nspace ( HEAD_list ( lns ) ) ;
253
		uncache_namespace ( pns, 0 ) ;
254
		lns = TAIL_list ( lns ) ;
255
	    }
256
	    COPY_list ( nspace_use ( ns ), uns ) ;
257
	}
258
    }
259
    return ;
260
}
261
 
262
 
263
/*
264
    ADD A NAMESPACE TO THE LOOK-UP LIST
265
 
266
    This routine adds the namespace ns to the look-up namespace list.  Note
267
    that this is automatically called by push_namespace.
268
*/
269
 
270
void add_namespace
271
    PROTO_N ( ( ns ) )
272
    PROTO_T ( NAMESPACE ns )
273
{
274
    PUSH_nspace ( ns, namespace_stack ) ;
275
    uncache_namespace ( ns, 1 ) ;
276
    return ;
277
}
278
 
279
 
280
/*
281
    REMOVE A NAMESPACE FROM THE LOOK-UP LIST
282
 
283
    This routine removes the top namespace from the look-up namespace list.
284
    Note that this is automatically called by pop_namespace.
285
*/
286
 
287
void remove_namespace
288
    PROTO_Z ()
289
{
290
    NAMESPACE ns ;
291
    POP_nspace ( ns, namespace_stack ) ;
292
    uncache_namespace ( ns, 0 ) ;
293
    return ;
294
}
295
 
296
 
297
/*
298
    PUSH A NAMESPACE
299
 
300
    This routine pushes the namespace ns onto the namespace stack.
301
*/
302
 
303
void store_namespace
304
    PROTO_N ( ( ns ) )
305
    PROTO_T ( NAMESPACE ns )
306
{
307
    NAMESPACE cns = crt_namespace ;
308
    switch ( TAG_nspace ( ns ) ) {
309
	case nspace_named_tag :
310
	case nspace_unnamed_tag :
311
	case nspace_global_tag : {
312
	    /* Record named namespaces */
313
	    nonblock_namespace = ns ;
314
	    nonclass_namespace = ns ;
315
	    break ;
316
	}
317
	case nspace_param_tag : {
318
	    /* Deal with function prototype scopes */
319
	    if ( option ( OPT_proto_scope ) ) {
320
		nonclass_namespace = ns ;
321
	    }
322
	    break ;
323
	}
324
	case nspace_block_tag : {
325
	    /* A block is a non-class namespace */
326
	    nonclass_namespace = ns ;
327
	    break ;
328
	}
329
    }
330
    COPY_nspace ( nspace_parent ( ns ), cns ) ;
331
    PUSH_nspace ( cns, crt_nspace_stack ) ;
332
    crt_namespace = ns ;
333
    return ;
334
}
335
 
336
 
337
/*
338
    POP A NAMESPACE
339
 
340
    This routine removes a namespace from the namespace stack.
341
*/
342
 
343
NAMESPACE restore_namespace
344
    PROTO_Z ()
345
{
346
    NAMESPACE ns = crt_namespace ;
347
    int fb = EQ_nspace ( ns, nonblock_namespace ) ;
348
    int fc = EQ_nspace ( ns, nonclass_namespace ) ;
349
    int fa = ( fb || fc ) ;
350
    if ( fa ) {
351
	/* Check for enclosing namespaces */
352
	LIST ( NAMESPACE ) lns = LIST_stack ( crt_nspace_stack ) ;
353
	while ( fa && !IS_NULL_list ( lns ) ) {
354
	    NAMESPACE pns = DEREF_nspace ( HEAD_list ( lns ) ) ;
355
	    switch ( TAG_nspace ( pns ) ) {
356
		case nspace_named_tag :
357
		case nspace_unnamed_tag :
358
		case nspace_global_tag : {
359
		    if ( fb ) {
360
			/* Non-block namespace found */
361
			nonblock_namespace = pns ;
362
			fa = fc ;
363
			fb = 0 ;
364
		    }
365
		    goto nonclass_namespace_lab ;
366
		}
367
		case nspace_param_tag : {
368
		    /* Deal with function prototype scopes */
369
		    if ( !option ( OPT_proto_scope ) ) break ;
370
		    goto nonclass_namespace_lab ;
371
		}
372
		case nspace_block_tag :
373
		nonclass_namespace_lab : {
374
		    if ( fc ) {
375
			/* Non-class namespace found */
376
			nonclass_namespace = pns ;
377
			fa = fb ;
378
			fc = 0 ;
379
		    }
380
		    break ;
381
		}
382
	    }
383
	    lns = TAIL_list ( lns ) ;
384
	}
385
    }
386
    POP_nspace ( crt_namespace, crt_nspace_stack ) ;
387
    return ( ns ) ;
388
}
389
 
390
 
391
/*
392
    SET CURRENT NAMESPACE
393
 
394
    This routine makes the namespace ns into the current namespace, pushing
395
    the previous namespace onto the stack.
396
*/
397
 
398
void push_namespace
399
    PROTO_N ( ( ns ) )
400
    PROTO_T ( NAMESPACE ns )
401
{
402
    store_namespace ( ns ) ;
403
    add_namespace ( ns ) ;
404
    return ;
405
}
406
 
407
 
408
/*
409
    RESTORE PREVIOUS NAMESPACE
410
 
411
    This routine restores the current namespace to its previous value by
412
    popping it from the stack.  It returns the removed namespace.
413
*/
414
 
415
NAMESPACE pop_namespace
416
    PROTO_Z ()
417
{
418
    NAMESPACE ns = restore_namespace () ;
419
    remove_namespace () ;
420
    return ( ns ) ;
421
}
422
 
423
 
424
/*
425
    RECALCULATE NAMESPACES
426
 
427
    This routine forces the recalculation of nonblock_namespace and
428
    nonclass_namespace by pushing and immediately popping the global
429
    namespace.
430
*/
431
 
432
void update_namespace
433
    PROTO_Z ()
434
{
435
    NAMESPACE ns = global_namespace ;
436
    if ( !IS_NULL_nspace ( ns ) ) {
437
	store_namespace ( ns ) ;
438
	IGNORE restore_namespace () ;
439
    }
440
    return ;
441
}
442
 
443
 
444
/*
445
    CREATE A NAMESPACE
446
 
447
    This routine creates a namespace named id of type tag.  If tag is
448
    indicates a small namespace then sz will be zero.  Otherwise sz gives
449
    the size of hash table to be created.
450
*/
451
 
452
NAMESPACE make_namespace
453
    PROTO_N ( ( id, tag, sz ) )
454
    PROTO_T ( IDENTIFIER id X unsigned tag X int sz )
455
{
456
    NAMESPACE ns ;
457
    NAMESPACE pns ;
458
    if ( !IS_NULL_id ( id ) ) {
459
	pns = DEREF_nspace ( id_parent ( id ) ) ;
460
    } else {
461
	pns = crt_namespace ;
462
    }
463
    if ( sz == 0 ) {
464
	/* Small namespace */
465
	MAKE_nspace_block_etc ( tag, id, pns, ns ) ;
466
    } else {
467
	/* Large namespace */
468
	PTR ( MEMBER ) ptr ;
469
	SIZE ( MEMBER ) psz ;
470
	unsigned long i, n = ( unsigned long ) sz ;
471
 
472
	/* Allocate namespace hash table */
473
	psz = SCALE ( SIZE_member, n ) ;
474
	ptr = MAKE_ptr ( psz ) ;
475
	MAKE_nspace_named_etc ( tag, id, pns, n, ptr, ns ) ;
476
 
477
	/* Initialise hash table entries */
478
	for ( i = 0 ; i < n ; i++ ) {
479
	    COPY_member ( ptr, NULL_member ) ;
480
	    ptr = STEP_ptr ( ptr, SIZE_member ) ;
481
	}
482
    }
483
    return ( ns ) ;
484
}
485
 
486
 
487
/*
488
    USE A NAMESPACE
489
 
490
    This routine creates a using directive for the namespace ns in
491
    the namespace cns.  nt gives the join of cns and ns.  The routine
492
    returns zero to indicate that ns has already been used from cns.
493
*/
494
 
495
int use_namespace
496
    PROTO_N ( ( ns, cns, nt ) )
497
    PROTO_T ( NAMESPACE ns X NAMESPACE cns X NAMESPACE nt )
498
{
499
    if ( !EQ_nspace ( cns, ns ) ) {
500
	LIST ( NAMESPACE ) p = DEREF_list ( nspace_use ( cns ) ) ;
501
	LIST ( NAMESPACE ) r = DEREF_list ( nspace_join ( cns ) ) ;
502
	LIST ( NAMESPACE ) q = p ;
503
	while ( !IS_NULL_list ( q ) ) {
504
	    NAMESPACE qns = DEREF_nspace ( HEAD_list ( q ) ) ;
505
	    if ( EQ_nspace ( qns, ns ) ) return ( 0 ) ;
506
	    q = TAIL_list ( q ) ;
507
	}
508
	CONS_nspace ( nt, r, r ) ;
509
	COPY_list ( nspace_join ( cns ), r ) ;
510
	CONS_nspace ( ns, p, p ) ;
511
	COPY_list ( nspace_use ( cns ), p ) ;
512
	return ( 1 ) ;
513
    }
514
    return ( 0 ) ;
515
}
516
 
517
 
518
/*
519
    LIST OF JOIN NAMESPACES
520
 
521
    During unqualified name look-up any using-directives are treated as
522
    injecting the names from the used namespace into the join on the
523
    used and the using namespaces.  This is implemented by injecting a
524
    dummy using-directive into the join namespace.  This list is used
525
    to keep track of all the join namespaces which have using-directives
526
    injected in this way.
527
*/
528
 
529
static LIST ( NAMESPACE ) join_nspaces = NULL_list ( NAMESPACE ) ;
530
 
531
 
532
/*
533
    CLEAR LIST OF JOIN NAMESPACES
534
 
535
    This routine removes any dummy using-directives from the list of join
536
    namespaces above.
537
*/
538
 
539
static void clear_join_nspaces
540
    PROTO_Z ()
541
{
542
    LIST ( NAMESPACE ) lns = join_nspaces ;
543
    while ( !IS_NULL_list ( lns ) ) {
544
	NAMESPACE ns ;
545
	NAMESPACE dns ;
546
	LIST ( NAMESPACE ) p ;
547
	DESTROY_CONS_nspace ( destroy, ns, lns, lns ) ;
548
	p = DEREF_list ( nspace_use ( ns ) ) ;
549
	if ( !IS_NULL_list ( p ) ) {
550
	    DESTROY_CONS_nspace ( destroy, dns, p, p ) ;
551
	    UNUSED ( dns ) ;
552
	    COPY_list ( nspace_use ( ns ), p ) ;
553
	}
554
	p = DEREF_list ( nspace_join ( ns ) ) ;
555
	if ( !IS_NULL_list ( p ) ) {
556
	    DESTROY_CONS_nspace ( destroy, dns, p, p ) ;
557
	    UNUSED ( dns ) ;
558
	    COPY_list ( nspace_join ( ns ), p ) ;
559
	}
560
    }
561
    join_nspaces = NULL_list ( NAMESPACE ) ;
562
    return ;
563
}
564
 
565
 
566
/*
567
    BEGIN A NAMESPACE DEFINITION
568
 
569
    This routine begins the definition of a namespace named id (or an
570
    anonymous namespace if anon is true).  Note that there may be multiple
571
    definitions of a namespace, the effect of the later definitions being
572
    to add elements to the existing namespace.  Only original namespace
573
    names, and not namespace aliases, can be used in these namespace
574
    extensions.
575
*/
576
 
577
void begin_namespace
578
    PROTO_N ( ( id, anon ) )
579
    PROTO_T ( IDENTIFIER id X int anon )
580
{
581
    HASHID nm ;
582
    MEMBER mem ;
583
    IDENTIFIER old_id ;
584
    NAMESPACE ns = NULL_nspace ;
585
    NAMESPACE cns = crt_namespace ;
586
    unsigned tag = nspace_named_tag ;
587
 
588
    /* Find name for anonymous namespaces */
589
    if ( anon ) {
590
	id = local_namespace_id ;
591
	tag = nspace_unnamed_tag ;
592
    }
593
    nm = DEREF_hashid ( id_name ( id ) ) ;
594
 
595
    /* Can only occur in namespace scope */
596
    if ( in_function_defn || in_class_defn ) {
597
	report ( crt_loc, ERR_dcl_nspace_scope () ) ;
598
    }
599
 
600
    /* Look up namespace name */
601
    mem = search_member ( cns, nm, 1 ) ;
602
    old_id = DEREF_id ( member_id ( mem ) ) ;
603
    if ( !IS_NULL_id ( old_id ) ) {
604
	/* Check for redeclarations */
605
	old_id = redecl_inherit ( old_id, qual_none, in_class_defn, 2 ) ;
606
	switch ( TAG_id ( old_id ) ) {
607
	    case id_nspace_name_tag : {
608
		/* Previously defined namespace */
609
		ns = DEREF_nspace ( id_nspace_name_defn ( old_id ) ) ;
610
		break ;
611
	    }
612
	    case id_nspace_alias_tag : {
613
		/* Previously defined namespace alias */
614
		IDENTIFIER ns_id ;
615
		ns = DEREF_nspace ( id_nspace_alias_defn ( old_id ) ) ;
616
		ns_id = DEREF_id ( nspace_name ( ns ) ) ;
617
		if ( !IS_id_nspace_name ( ns_id ) ) {
618
		    /* Alias for class namespace */
619
		    ns = NULL_nspace ;
620
		    goto default_lab ;
621
		}
622
		report ( crt_loc, ERR_dcl_nspace_def_orig ( ns_id, old_id ) ) ;
623
		break ;
624
	    }
625
	    default :
626
	    default_lab : {
627
		/* Other previously defined identifier */
628
		PTR ( LOCATION ) loc = id_loc ( old_id ) ;
629
		report ( crt_loc, ERR_basic_odr_decl ( old_id, loc ) ) ;
630
		break ;
631
	    }
632
	}
633
    }
634
 
635
    /* Construct the namespace if necessary */
636
    if ( IS_NULL_nspace ( ns ) ) {
637
	DECL_SPEC ds = ( dspec_defn | dspec_extern ) ;
638
	MAKE_id_nspace_name ( nm, ds, cns, decl_loc, ns, id ) ;
639
	ns = make_namespace ( id, tag, 50 ) ;
640
	COPY_nspace ( id_nspace_name_defn ( id ), ns ) ;
641
	set_member ( mem, id ) ;
642
	if ( anon ) {
643
	    /* Anonymous namespaces are implicitly used */
644
	    IGNORE use_namespace ( ns, cns, cns ) ;
645
	    if ( do_dump ) dump_using ( ns, cns, &decl_loc ) ;
646
	}
647
    }
648
 
649
    /* Adjust the current namespace */
650
    if ( do_dump ) dump_declare ( id, &decl_loc, 1 ) ;
651
    push_namespace ( ns ) ;
652
    cns = DEREF_nspace ( id_parent ( id ) ) ;
653
    COPY_nspace ( nspace_parent ( ns ), cns ) ;
654
    return ;
655
}
656
 
657
 
658
/*
659
    END A NAMESPACE DEFINITION
660
 
661
    This routine ends the definition of the current namespace.
662
*/
663
 
664
void end_namespace
665
    PROTO_N ( ( anon ) )
666
    PROTO_T ( int anon )
667
{
668
    NAMESPACE ns ;
669
    clear_decl_blocks () ;
670
    ns = pop_namespace () ;
671
    if ( do_dump ) {
672
	IDENTIFIER id = DEREF_id ( nspace_name ( ns ) ) ;
673
	dump_undefine ( id, &crt_loc, 0 ) ;
674
    }
675
    UNUSED ( anon ) ;
676
    return ;
677
}
678
 
679
 
680
/*
681
    PROCESS A TARGET DEPENDENT DECLARATION SEQUENCE
682
 
683
    This routine is called in the processing of target dependent
684
    preprocessing directives within declaration sequences.  The directive
685
    involved is given by dir, while c gives the associated condition for
686
    '#if' and '#elif'.
687
*/
688
 
689
void target_decl
690
    PROTO_N ( ( dir, c ) )
691
    PROTO_T ( int dir X EXP c )
692
{
693
    if ( !IS_NULL_exp ( c ) ) {
694
	report ( crt_loc, ERR_cpp_cond_if_ti_decl ( dir ) ) ;
695
    }
696
    return ;
697
}
698
 
699
 
700
/*
701
    BEGIN A DECLARATION BLOCK
702
 
703
    A declaration block is a technique for partitioning the external
704
    declarations into subsets.  These subsets have no significance within
705
    the language, but are useful for indicating, for example, those
706
    identifiers which form part of a certain API.  This routine starts
707
    a declaration block named id.
708
*/
709
 
710
void begin_decl_block
711
    PROTO_N ( ( id ) )
712
    PROTO_T ( IDENTIFIER id )
713
{
714
    NAMESPACE cns = nonblock_namespace ;
715
    NAMESPACE sns = scope_namespace ;
716
    HASHID nm = DEREF_hashid ( id_name ( id ) ) ;
717
    MEMBER mem = search_member ( sns, nm, 1 ) ;
718
    id = DEREF_id ( member_id ( mem ) ) ;
719
    if ( IS_NULL_id ( id ) ) {
720
	/* Create dummy namespace identifier */
721
	NAMESPACE bns = NULL_nspace ;
722
	DECL_SPEC ds = ( dspec_defn | dspec_extern ) ;
723
	MAKE_id_nspace_name ( nm, ds, cns, crt_loc, bns, id ) ;
724
	bns = make_namespace ( id, nspace_block_tag, 0 ) ;
725
	COPY_nspace ( id_nspace_name_defn ( id ), bns ) ;
726
	COPY_id ( member_id ( mem ), id ) ;
727
    }
728
    if ( do_dump ) {
729
	/* Output scope to dump file */
730
	NAMESPACE bns = DEREF_nspace ( id_nspace_name_defn ( id ) ) ;
731
	dump_begin_scope ( id, bns, cns, &crt_loc ) ;
732
    }
733
    if ( !IS_NULL_nspace ( cns ) ) {
734
	/* Add to current namespace */
735
	STACK ( IDENTIFIER ) pids = DEREF_stack ( nspace_set ( cns ) ) ;
736
	PUSH_id ( id, pids ) ;
737
	COPY_stack ( nspace_set ( cns ), pids ) ;
738
    }
739
    return ;
740
}
741
 
742
 
743
/*
744
    END A DECLARATION BLOCK
745
 
746
    This routine ends a declaration block named id or the current
747
    declaration block if id is the null identifier.  If there is no
748
    current declaration block and force is true then an error is
749
    raised.  The routine returns true if a declaration block is ended.
750
*/
751
 
752
int end_decl_block
753
    PROTO_N ( ( id, force ) )
754
    PROTO_T ( IDENTIFIER id X int force )
755
{
756
    int res = 0 ;
757
    NAMESPACE cns = nonblock_namespace ;
758
    if ( !IS_NULL_nspace ( cns ) ) {
759
	/* Add to current namespace */
760
	STACK ( IDENTIFIER ) pids = DEREF_stack ( nspace_set ( cns ) ) ;
761
	if ( IS_NULL_stack ( pids ) ) {
762
	    if ( force ) {
763
		/* Stack shouldn't be empty */
764
		report ( crt_loc, ERR_pragma_dblock_end () ) ;
765
	    }
766
	} else {
767
	    IDENTIFIER pid ;
768
	    POP_id ( pid, pids ) ;
769
	    COPY_stack ( nspace_set ( cns ), pids ) ;
770
	    if ( !IS_NULL_id ( id ) ) {
771
		/* Check block name if given */
772
		HASHID nm = DEREF_hashid ( id_name ( id ) ) ;
773
		HASHID pnm = DEREF_hashid ( id_name ( pid ) ) ;
774
		if ( !EQ_hashid ( nm, pnm ) ) {
775
		    report ( crt_loc, ERR_pragma_dblock_name ( pnm ) ) ;
776
		}
777
	    }
778
	    if ( do_dump ) {
779
		/* Output scope to dump file */
780
		NAMESPACE bns = DEREF_nspace ( id_nspace_name_defn ( pid ) ) ;
781
		dump_end_scope ( pid, bns, &crt_loc ) ;
782
	    }
783
	    res = 1 ;
784
	}
785
    }
786
    return ( res ) ;
787
}
788
 
789
 
790
/*
791
    END ALL DECLARATION BLOCKS
792
 
793
    This routine ends all the declaration blocks associated with the
794
    current namespace.  This is called at the end of a namespace definition
795
    and at the end of the input file.
796
*/
797
 
798
void clear_decl_blocks
799
    PROTO_Z ()
800
{
801
    while ( end_decl_block ( NULL_id, 0 ) ) ;
802
    return ;
803
}
804
 
805
 
806
/*
807
    FIND A NAMESPACE
808
 
809
    This routine finds the namespace corresponding to the identifier id,
810
    returning the null namespace if id does not represent a class or a
811
    namespace.
812
*/
813
 
814
NAMESPACE find_namespace
815
    PROTO_N ( ( id ) )
816
    PROTO_T ( IDENTIFIER id )
817
{
818
    NAMESPACE ns = NULL_nspace ;
819
    if ( !IS_NULL_id ( id ) ) {
820
	switch ( TAG_id ( id ) ) {
821
	    case id_nspace_name_tag :
822
	    case id_nspace_alias_tag : {
823
		/* Explicitly named namespaces */
824
		ns = DEREF_nspace ( id_nspace_name_etc_defn ( id ) ) ;
825
		break ;
826
	    }
827
	    case id_class_name_tag :
828
	    case id_class_alias_tag : {
829
		/* Class namespaces */
830
		TYPE t = DEREF_type ( id_class_name_etc_defn ( id ) ) ;
831
		if ( IS_type_compound ( t ) ) {
832
		    CLASS_TYPE ct = DEREF_ctype ( type_compound_defn ( t ) ) ;
833
		    complete_class ( ct, 1 ) ;
834
		    ns = DEREF_nspace ( ctype_member ( ct ) ) ;
835
		} else {
836
		    CLASS_TYPE ct = find_class ( id ) ;
837
		    if ( !IS_NULL_ctype ( ct ) ) {
838
			complete_class ( ct, 1 ) ;
839
			ns = DEREF_nspace ( ctype_member ( ct ) ) ;
840
		    }
841
		}
842
		break ;
843
	    }
844
	}
845
    }
846
    return ( ns ) ;
847
}
848
 
849
 
850
/*
851
    LOOK UP A NAMESPACE NAME
852
 
853
    This routine looks up the identifier id as a namespace name in a
854
    namespace alias or namespace directive.
855
*/
856
 
857
NAMESPACE find_nspace_id
858
    PROTO_N ( ( id ) )
859
    PROTO_T ( IDENTIFIER id )
860
{
861
    NAMESPACE ns ;
862
    if ( IS_id_nspace_name_etc ( id ) ) {
863
	ns = DEREF_nspace ( id_nspace_name_etc_defn ( id ) ) ;
864
    } else {
865
	if ( crt_templ_qualifier == 0 ) {
866
	    HASHID nm = DEREF_hashid ( id_name ( id ) ) ;
867
	    if ( crt_id_qualifier == qual_none ) {
868
		IDENTIFIER nid = find_type_id ( nm, 2 ) ;
869
		if ( !IS_NULL_id ( nid ) ) id = nid ;
870
	    } else {
871
		NAMESPACE pns = DEREF_nspace ( id_parent ( id ) ) ;
872
		IDENTIFIER nid = find_qual_id ( pns, nm, 0, 2 ) ;
873
		if ( !IS_NULL_id ( nid ) ) id = nid ;
874
	    }
875
	}
876
	ns = find_namespace ( id ) ;
877
	if ( IS_NULL_nspace ( ns ) ) {
878
	    /* Invalid namespace identifier */
879
	    report ( crt_loc, ERR_dcl_nspace_undef ( id ) ) ;
880
	    return ( NULL_nspace ) ;
881
	}
882
    }
883
    use_id ( id, 0 ) ;
884
    return ( ns ) ;
885
}
886
 
887
 
888
/*
889
    CONSTRUCT A NAMESPACE ALIAS
890
 
891
    This routine sets up id as an alias for the namespace ns.  A namespace
892
    alias may be consistently redefined any number of times.
893
*/
894
 
895
void alias_namespace
896
    PROTO_N ( ( id, ns ) )
897
    PROTO_T ( IDENTIFIER id X NAMESPACE ns )
898
{
899
    MEMBER mem ;
900
    IDENTIFIER old_id ;
901
    NAMESPACE cns = crt_namespace ;
902
    HASHID nm = DEREF_hashid ( id_name ( id ) ) ;
903
    DECL_SPEC ds = ( dspec_defn | dspec_extern ) ;
904
    if ( IS_NULL_nspace ( ns ) ) {
905
	/* Invalid namespace identifier */
906
	begin_namespace ( id, 0 ) ;
907
	end_namespace ( 0 ) ;
908
	return ;
909
    }
910
    if ( IS_nspace_ctype ( ns ) ) {
911
	/* Can't have a class namespace */
912
	report ( crt_loc, ERR_dcl_nspace_alias_class ( ns ) ) ;
913
    }
914
 
915
    /* Look up namespace alias name */
916
    mem = search_member ( cns, nm, 1 ) ;
917
    old_id = DEREF_id ( member_id ( mem ) ) ;
918
 
919
    /* Check for redeclarations */
920
    if ( !IS_NULL_id ( old_id ) ) {
921
	old_id = redecl_inherit ( old_id, qual_none, in_class_defn, 2 ) ;
922
	switch ( TAG_id ( old_id ) ) {
923
	    case id_nspace_name_tag : {
924
		/* Previously defined namespace name */
925
		ERROR err ;
926
		NAMESPACE old_ns ;
927
		PTR ( LOCATION ) loc = id_loc ( old_id ) ;
928
		old_ns = DEREF_nspace ( id_nspace_name_defn ( old_id ) ) ;
929
		report ( crt_loc, ERR_dcl_nspace_alias_bad ( old_id, loc ) ) ;
930
		if ( EQ_nspace ( ns, old_ns ) ) {
931
		    /* No further action if consistent */
932
		    return ;
933
		}
934
		/* Hide namespace name with namespace alias */
935
		err = ERR_dcl_nspace_alias_redef ( old_id, loc ) ;
936
		report ( crt_loc, err ) ;
937
		break ;
938
	    }
939
	    case id_nspace_alias_tag : {
940
		/* Previously defined namespace alias */
941
		NAMESPACE old_ns ;
942
		old_ns = DEREF_nspace ( id_nspace_alias_defn ( old_id ) ) ;
943
		if ( !EQ_nspace ( ns, old_ns ) ) {
944
		    /* Inconsistent alias redefinition */
945
		    ERROR err ;
946
		    PTR ( LOCATION ) loc = id_loc ( old_id ) ;
947
		    err = ERR_dcl_nspace_alias_redef ( old_id, loc ) ;
948
		    report ( crt_loc, err ) ;
949
		    COPY_nspace ( id_nspace_alias_defn ( old_id ), ns ) ;
950
		}
951
		return ;
952
	    }
953
	    default : {
954
		/* Other previously defined identifier */
955
		PTR ( LOCATION ) loc = id_loc ( old_id ) ;
956
		report ( crt_loc, ERR_basic_odr_decl ( old_id, loc ) ) ;
957
		break ;
958
	    }
959
	}
960
    }
961
 
962
    /* Set up the namespace alias */
963
    MAKE_id_nspace_alias ( nm, ds, cns, decl_loc, ns, id ) ;
964
    set_member ( mem, id ) ;
965
    return ;
966
}
967
 
968
 
969
/*
970
    PROCESS A USING NAMESPACE DIRECTIVE
971
 
972
    This routine processes a using namespace directive for the namespace ns.
973
*/
974
 
975
void using_namespace
976
    PROTO_N ( ( ns ) )
977
    PROTO_T ( NAMESPACE ns )
978
{
979
    if ( !IS_NULL_nspace ( ns ) ) {
980
	if ( IS_nspace_ctype ( ns ) ) {
981
	    /* Namespace designates a class */
982
	    report ( crt_loc, ERR_dcl_nspace_udir_class ( ns ) ) ;
983
	} else {
984
	    NAMESPACE cns = crt_namespace ;
985
	    NAMESPACE jns = join_namespace ( ns, cns ) ;
986
	    if ( IS_NULL_nspace ( jns ) ) jns = global_namespace ;
987
	    if ( !use_namespace ( ns, cns, jns ) ) {
988
		/* Namespace already used */
989
		report ( crt_loc, ERR_dcl_nspace_udir_dup ( ns ) ) ;
990
	    }
991
	    uncache_namespace ( ns, 0 ) ;
992
	    if ( do_dump ) dump_using ( ns, cns, &crt_loc ) ;
993
	}
994
    }
995
    return ;
996
}
997
 
998
 
999
/*
1000
    ADD A NESTED NAMESPACE
1001
 
1002
    This routine adds the namespace ns to the look-up stack.  If ns is
1003
    a nested namespace then the enclosing namespaces are also added.
1004
    It returns true if the stack is changed.
1005
*/
1006
 
1007
int add_nested_nspace
1008
    PROTO_N ( ( ns ) )
1009
    PROTO_T ( NAMESPACE ns )
1010
{
1011
    int res = 0 ;
1012
    if ( !IS_NULL_nspace ( ns ) && !EQ_nspace ( ns, crt_namespace ) ) {
1013
	switch ( TAG_nspace ( ns ) ) {
1014
	    case nspace_named_tag :
1015
	    case nspace_unnamed_tag :
1016
	    case nspace_ctype_tag : {
1017
		IDENTIFIER id = DEREF_id ( nspace_name ( ns ) ) ;
1018
		if ( !IS_NULL_id ( id ) ) {
1019
		    NAMESPACE pns = DEREF_nspace ( id_parent ( id ) ) ;
1020
		    IGNORE add_nested_nspace ( pns ) ;
1021
		}
1022
		add_namespace ( ns ) ;
1023
		res = 1 ;
1024
		break ;
1025
	    }
1026
	}
1027
    }
1028
    return ( res ) ;
1029
}
1030
 
1031
 
1032
/*
1033
    REMOVE A NESTED NAMESPACE
1034
 
1035
    This routine removes the namespace ns from the look-up stack.  If
1036
    ns is a namespace class then the enclosing namespaces are also
1037
    removed.  It returns true if the stack is changed.
1038
*/
1039
 
1040
int remove_nested_nspace
1041
    PROTO_N ( ( ns ) )
1042
    PROTO_T ( NAMESPACE ns )
1043
{
1044
    int res = 0 ;
1045
    if ( !IS_NULL_nspace ( ns ) && !EQ_nspace ( ns, crt_namespace ) ) {
1046
	switch ( TAG_nspace ( ns ) ) {
1047
	    case nspace_named_tag :
1048
	    case nspace_unnamed_tag :
1049
	    case nspace_ctype_tag : {
1050
		IDENTIFIER id ;
1051
		remove_namespace () ;
1052
		id = DEREF_id ( nspace_name ( ns ) ) ;
1053
		if ( !IS_NULL_id ( id ) ) {
1054
		    NAMESPACE pns = DEREF_nspace ( id_parent ( id ) ) ;
1055
		    IGNORE remove_nested_nspace ( pns ) ;
1056
		}
1057
		res = 1 ;
1058
		break ;
1059
	    }
1060
	}
1061
    }
1062
    return ( res ) ;
1063
}
1064
 
1065
 
1066
/*
1067
    BEGIN THE LOOK-UP SCOPE FOR A DECLARATOR
1068
 
1069
    This routine is called immediately after the declarator id given with
1070
    identifier qualifiers idtype and qns to set the name look-up
1071
    appropriately.  Thus for example, in 'int C::a = b ;', b is looked up
1072
    in the scope of C.
1073
*/
1074
 
1075
void begin_declarator
1076
    PROTO_N ( ( id, idtype, qns, scan ) )
1077
    PROTO_T ( IDENTIFIER id X QUALIFIER idtype X NAMESPACE qns X int scan )
1078
{
1079
    NAMESPACE ns = NULL_nspace ;
1080
    if ( idtype != qual_none ) {
1081
	ns = DEREF_nspace ( id_parent ( id ) ) ;
1082
	if ( !IS_NULL_nspace ( ns ) && !IS_nspace_ctype ( ns ) ) {
1083
	    if ( !IS_NULL_nspace ( qns ) && !EQ_nspace ( qns, ns ) ) {
1084
		/* Should have an immediate member */
1085
		report ( crt_loc, ERR_lookup_qual_decl ( id, qns ) ) ;
1086
		ns = qns ;
1087
	    }
1088
	}
1089
	if ( add_nested_nspace ( ns ) && scan ) {
1090
	    /* Rescan identifier if stack has changed */
1091
	    RESCAN_LEXER ;
1092
	}
1093
    }
1094
    PUSH_nspace ( ns, local_nspace_stack ) ;
1095
    if ( crt_state_depth == 0 ) {
1096
	id = underlying_id ( id ) ;
1097
	DEREF_loc ( id_loc ( id ), decl_loc ) ;
1098
    } else {
1099
	decl_loc = crt_loc ;
1100
    }
1101
    return ;
1102
}
1103
 
1104
 
1105
/*
1106
    END THE LOOK-UP SCOPE FOR A DECLARATOR
1107
 
1108
    This routine is called at the end of the initialiser or definition
1109
    of the declarator id to reset the name look-up.
1110
*/
1111
 
1112
void end_declarator
1113
    PROTO_N ( ( id, scan ) )
1114
    PROTO_T ( IDENTIFIER id X int scan )
1115
{
1116
    NAMESPACE ns ;
1117
    POP_nspace ( ns, local_nspace_stack ) ;
1118
    if ( IS_NULL_nspace ( ns ) ) {
1119
	if ( !IS_NULL_id ( id ) ) {
1120
	    HASHID nm = DEREF_hashid ( id_name ( id ) ) ;
1121
	    IDENTIFIER cid = DEREF_id ( hashid_cache ( nm ) ) ;
1122
	    if ( !EQ_id ( id, cid ) ) {
1123
		/* Look-up may have changed */
1124
		COPY_id ( hashid_cache ( nm ), NULL_id ) ;
1125
		if ( scan ) {
1126
		    /* Rescan identifier if look-up has changed */
1127
		    RESCAN_LEXER ;
1128
		}
1129
	    }
1130
	}
1131
    } else {
1132
	if ( remove_nested_nspace ( ns ) && scan ) {
1133
	    /* Rescan identifier if stack has changed */
1134
	    RESCAN_LEXER ;
1135
	}
1136
    }
1137
    return ;
1138
}
1139
 
1140
 
1141
/*
1142
    SET A NAMESPACE MEMBER
1143
 
1144
    This routine sets the identifier id to be a namespace member as
1145
    indicated by mem.  It also sets the look-up cache to id if appropriate.
1146
*/
1147
 
1148
void set_member
1149
    PROTO_N ( ( mem, id ) )
1150
    PROTO_T ( MEMBER mem X IDENTIFIER id )
1151
{
1152
    if ( !IS_NULL_member ( mem ) ) {
1153
	HASHID nm ;
1154
	IDENTIFIER cid ;
1155
	LIST ( NAMESPACE ) lns ;
1156
 
1157
	/* Check any previous definition */
1158
	IDENTIFIER pid = DEREF_id ( member_id ( mem ) ) ;
1159
	if ( !IS_NULL_id ( pid ) ) {
1160
	    if ( IS_id_token ( pid ) ) {
1161
		IGNORE unify_id ( pid, id, 1 ) ;
1162
	    } else if ( IS_id_token ( id ) ) {
1163
		if ( unify_id ( id, pid, 0 ) ) return ;
1164
	    }
1165
	}
1166
 
1167
	/* Check look-up cache */
1168
	cid = NULL_id ;
1169
	nm = DEREF_hashid ( id_name ( id ) ) ;
1170
	lns = LIST_stack ( namespace_stack ) ;
1171
	if ( !IS_NULL_list ( lns ) ) {
1172
	    /* Check for current namespace */
1173
	    NAMESPACE ns = DEREF_nspace ( id_parent ( id ) ) ;
1174
	    NAMESPACE pns = DEREF_nspace ( HEAD_list ( lns ) ) ;
1175
	    if ( EQ_nspace ( ns, pns ) ) {
1176
		/* Check for unambiguous look-up */
1177
		lns = DEREF_list ( nspace_use ( ns ) ) ;
1178
		if ( IS_NULL_list ( lns ) ) cid = id ;
1179
	    }
1180
	}
1181
	COPY_id ( hashid_cache ( nm ), cid ) ;
1182
 
1183
	/* Set member identifier */
1184
	COPY_id ( member_id ( mem ), id ) ;
1185
    }
1186
    return ;
1187
}
1188
 
1189
 
1190
/*
1191
    SET A NAMESPACE TYPE MEMBER
1192
 
1193
    This routine sets the type identifier id to be a namespace member
1194
    as indicated by mem.  Note that in C this just sets the alt field
1195
    of mem, whereas in C++ it may also set the id field.
1196
*/
1197
 
1198
void set_type_member
1199
    PROTO_N ( ( mem, id ) )
1200
    PROTO_T ( MEMBER mem X IDENTIFIER id )
1201
{
1202
    if ( !IS_NULL_member ( mem ) ) {
1203
#if LANGUAGE_CPP
1204
	IDENTIFIER mid = DEREF_id ( member_id ( mem ) ) ;
1205
	if ( IS_NULL_id ( mid ) ) {
1206
	    /* No object of the same name */
1207
	    set_member ( mem, id ) ;
1208
	} else {
1209
	    /* Hidden by object of the same name */
1210
	    HASHID nm = DEREF_hashid ( id_name ( id ) ) ;
1211
	    DECL_SPEC ds = DEREF_dspec ( id_storage ( mid ) ) ;
1212
	    if ( ( ds & dspec_inherit ) && !( ds & dspec_alias ) ) {
1213
		ds = DEREF_dspec ( id_storage ( id ) ) ;
1214
		if ( !( ds & dspec_inherit ) ) {
1215
		    /* An uninherited type overrrides an inherited object */
1216
		    COPY_id ( member_id ( mem ), id ) ;
1217
		}
1218
	    }
1219
	    COPY_id ( hashid_cache ( nm ), NULL_id ) ;
1220
	}
1221
#endif
1222
	COPY_id ( member_alt ( mem ), id ) ;
1223
    }
1224
    return ;
1225
}
1226
 
1227
 
1228
/*
1229
    CLEAR A NAMESPACE MEMBER
1230
 
1231
    This routine clears all meanings of the member nm of the namespace ns.
1232
*/
1233
 
1234
void clear_member
1235
    PROTO_N ( ( ns, nm ) )
1236
    PROTO_T ( NAMESPACE ns X HASHID nm )
1237
{
1238
    MEMBER mem = search_member ( ns, nm, 0 ) ;
1239
    if ( !IS_NULL_member ( mem ) ) {
1240
	COPY_id ( member_id ( mem ), NULL_id ) ;
1241
	COPY_id ( member_alt ( mem ), NULL_id ) ;
1242
    }
1243
    COPY_id ( hashid_cache ( nm ), NULL_id ) ;
1244
    return ;
1245
}
1246
 
1247
 
1248
/*
1249
    FIND A MEMBER OF A NAMESPACE
1250
 
1251
    This routine searches the namespace ns for a member named nm.  This
1252
    is returned if found.  Otherwise if create is true then an empty
1253
    member is created and returned.  Otherwise the null member is returned.
1254
*/
1255
 
1256
MEMBER search_member
1257
    PROTO_N ( ( ns, nm, create ) )
1258
    PROTO_T ( NAMESPACE ns X HASHID nm X int create )
1259
{
1260
    MEMBER mem ;
1261
 
1262
    if ( IS_NULL_nspace ( ns ) ) {
1263
	/* Null namespace */
1264
	if ( create ) {
1265
	    MAKE_member_small ( NULL_member, mem ) ;
1266
	} else {
1267
	    mem = NULL_member ;
1268
	}
1269
 
1270
    } else if ( IS_nspace_block_etc ( ns ) ) {
1271
	/* Small namespaces */
1272
	MEMBER last = DEREF_member ( nspace_last ( ns ) ) ;
1273
 
1274
	/* Search through members */
1275
	mem = last ;
1276
	while ( !IS_NULL_member ( mem ) ) {
1277
	    IDENTIFIER mid = DEREF_id ( member_id ( mem ) ) ;
1278
	    if ( !IS_NULL_id ( mid ) ) {
1279
		HASHID mnm = DEREF_hashid ( id_name ( mid ) ) ;
1280
		if ( EQ_hashid ( nm, mnm ) ) return ( mem ) ;
1281
	    }
1282
#if LANGUAGE_C
1283
	    /* ... continues */ else {
1284
		/* Need to also check tag namespace in C */
1285
		mid = DEREF_id ( member_alt ( mem ) ) ;
1286
		if ( !IS_NULL_id ( mid ) ) {
1287
		    HASHID mnm = DEREF_hashid ( id_name ( mid ) ) ;
1288
		    if ( EQ_hashid ( nm, mnm ) ) return ( mem ) ;
1289
		}
1290
	    }
1291
#endif
1292
	    mem = DEREF_member ( member_next ( mem ) ) ;
1293
	}
1294
 
1295
	/* Create new member if necessary */
1296
	if ( create ) {
1297
	    MAKE_member_small ( last, mem ) ;
1298
	    COPY_member ( nspace_last ( ns ), mem ) ;
1299
	}
1300
 
1301
    } else {
1302
	/* Large namespaces */
1303
	PTR ( MEMBER ) ptr = DEREF_ptr ( nspace_named_etc_table ( ns ) ) ;
1304
	unsigned long sz = DEREF_ulong ( nspace_named_etc_size ( ns ) ) ;
1305
	unsigned long h = DEREF_ulong ( hashid_hash ( nm ) ) ;
1306
	SIZE ( MEMBER ) psz = SCALE ( SIZE_member, ( h % sz ) ) ;
1307
 
1308
	/* Search through members */
1309
	ptr = STEP_ptr ( ptr, psz ) ;
1310
	mem = DEREF_member ( ptr ) ;
1311
	while ( !IS_NULL_member ( mem ) ) {
1312
	    IDENTIFIER mid = DEREF_id ( member_id ( mem ) ) ;
1313
	    if ( !IS_NULL_id ( mid ) ) {
1314
		HASHID mnm = DEREF_hashid ( id_name ( mid ) ) ;
1315
		if ( EQ_hashid ( nm, mnm ) ) return ( mem ) ;
1316
	    }
1317
#if LANGUAGE_C
1318
	    /* ... continues */ else {
1319
		/* Need to also check tag namespace in C */
1320
		mid = DEREF_id ( member_alt ( mem ) ) ;
1321
		if ( !IS_NULL_id ( mid ) ) {
1322
		    HASHID mnm = DEREF_hashid ( id_name ( mid ) ) ;
1323
		    if ( EQ_hashid ( nm, mnm ) ) return ( mem ) ;
1324
		}
1325
	    }
1326
#endif
1327
	    mem = DEREF_member ( member_large_tnext ( mem ) ) ;
1328
	}
1329
 
1330
	/* Create new member if necessary */
1331
	if ( create ) {
1332
	    MEMBER last ;
1333
	    mem = DEREF_member ( ptr ) ;
1334
	    MAKE_member_large ( NULL_member, mem, mem ) ;
1335
	    COPY_member ( ptr, mem ) ;
1336
	    last = DEREF_member ( nspace_last ( ns ) ) ;
1337
	    if ( IS_NULL_member ( last ) ) {
1338
		COPY_member ( nspace_named_etc_first ( ns ), mem ) ;
1339
	    } else {
1340
		COPY_member ( member_next ( last ), mem ) ;
1341
	    }
1342
	    COPY_member ( nspace_last ( ns ), mem ) ;
1343
	}
1344
    }
1345
    return ( mem ) ;
1346
}
1347
 
1348
 
1349
/*
1350
    UPDATE A NAMESPACE MEMBER
1351
 
1352
    This routine copies the member mem of the namespace ns to the end of
1353
    the list of all members.  In block namespaces this is to force the
1354
    member to be re-examined in make_decl_stmt.  In class namespaces this
1355
    is to preserve the order of the data members.
1356
*/
1357
 
1358
MEMBER update_member
1359
    PROTO_N ( ( ns, mem ) )
1360
    PROTO_T ( NAMESPACE ns X MEMBER mem )
1361
{
1362
    IDENTIFIER id = DEREF_id ( member_id ( mem ) ) ;
1363
    IDENTIFIER alt = DEREF_id ( member_alt ( mem ) ) ;
1364
    COPY_id ( member_id ( mem ), NULL_id ) ;
1365
    COPY_id ( member_alt ( mem ), NULL_id ) ;
1366
    if ( IS_member_small ( mem ) ) {
1367
	/* Create new small member */
1368
	MEMBER last = DEREF_member ( nspace_last ( ns ) ) ;
1369
	MAKE_member_small ( last, mem ) ;
1370
	COPY_member ( nspace_last ( ns ), mem ) ;
1371
    } else {
1372
	/* Create new large member */
1373
	if ( !IS_NULL_id ( id ) ) {
1374
	    HASHID nm = DEREF_hashid ( id_name ( id ) ) ;
1375
	    mem = search_member ( ns, nm, 1 ) ;
1376
	} else if ( !IS_NULL_id ( alt ) ) {
1377
	    HASHID nm = DEREF_hashid ( id_name ( alt ) ) ;
1378
	    mem = search_member ( ns, nm, 1 ) ;
1379
	}
1380
    }
1381
    COPY_id ( member_id ( mem ), id ) ;
1382
    COPY_id ( member_alt ( mem ), alt ) ;
1383
    return ( mem ) ;
1384
}
1385
 
1386
 
1387
/*
1388
    FIND A TYPE IDENTIFIER
1389
 
1390
    This routine checks whether the identifier id is a type name (if bit 0
1391
    of type is true) or a namespace name (if bit 1 of type is true).  In
1392
    C only struct, union and enum tags are allowed.
1393
*/
1394
 
1395
static IDENTIFIER select_type_id
1396
    PROTO_N ( ( id, type ) )
1397
    PROTO_T ( IDENTIFIER id X int type )
1398
{
1399
    if ( !IS_NULL_id ( id ) ) {
1400
	switch ( TAG_id ( id ) ) {
1401
	    case id_class_name_tag :
1402
	    case id_enum_name_tag : {
1403
		if ( type & 1 ) return ( id ) ;
1404
		break ;
1405
	    }
1406
#if LANGUAGE_CPP
1407
	    case id_class_alias_tag :
1408
	    case id_enum_alias_tag :
1409
	    case id_type_alias_tag : {
1410
		if ( type & 1 ) return ( id ) ;
1411
		break ;
1412
	    }
1413
	    case id_nspace_name_tag :
1414
	    case id_nspace_alias_tag : {
1415
		if ( type & 2 ) return ( id ) ;
1416
		break ;
1417
	    }
1418
#endif
1419
	}
1420
    }
1421
    return ( NULL_id ) ;
1422
}
1423
 
1424
 
1425
/*
1426
    FIND A TYPE MEMBER
1427
 
1428
    This routine returns the type or namespace name associated with the
1429
    member mem, or the null identifier if this does not exist.  The
1430
    type argument is as above.  In C++ it is necessary to check both
1431
    the id and the alt fields of mem, whereas in C only the alt field
1432
    needs to be examined.
1433
*/
1434
 
1435
IDENTIFIER type_member
1436
    PROTO_N ( ( mem, type ) )
1437
    PROTO_T ( MEMBER mem X int type )
1438
{
1439
    IDENTIFIER id = NULL_id ;
1440
    if ( !IS_NULL_member ( mem ) ) {
1441
#if LANGUAGE_CPP
1442
	id = DEREF_id ( member_id ( mem ) ) ;
1443
	id = select_type_id ( id, type ) ;
1444
	if ( IS_NULL_id ( id ) ) {
1445
	    id = DEREF_id ( member_alt ( mem ) ) ;
1446
	    id = select_type_id ( id, type ) ;
1447
	}
1448
#else
1449
	id = DEREF_id ( member_alt ( mem ) ) ;
1450
	id = select_type_id ( id, type ) ;
1451
#endif
1452
    }
1453
    return ( id ) ;
1454
}
1455
 
1456
 
1457
/*
1458
    IS AN IDENTIFIER IN A LIST?
1459
 
1460
    This routine checks whether the identifier id is in the list of
1461
    ambiguous meanings given by pid and pids.  Functions are excluded
1462
    because of the complications introduced by using-declarations and
1463
    overloading.  Overload resolution will eliminate duplicate entries
1464
    in this case.
1465
*/
1466
 
1467
static int already_found_id
1468
    PROTO_N ( ( id, pid, pids ) )
1469
    PROTO_T ( IDENTIFIER id X IDENTIFIER pid X LIST ( IDENTIFIER ) pids )
1470
{
1471
    if ( IS_id_function_etc ( id ) ) {
1472
	/* Exclude functions */
1473
	return ( 0 ) ;
1474
    }
1475
    if ( !IS_NULL_id ( pid ) ) {
1476
	if ( IS_id_ambig ( pid ) ) {
1477
	    /* Check ambiguous identifiers */
1478
	    LIST ( IDENTIFIER ) qids = DEREF_list ( id_ambig_ids ( pid ) ) ;
1479
	    if ( already_found_id ( id, NULL_id, qids ) ) return ( 1 ) ;
1480
	} else {
1481
	    /* Check simple identifiers */
1482
	    if ( !IS_id_function_etc ( pid ) ) {
1483
		id = DEREF_id ( id_alias ( id ) ) ;
1484
		pid = DEREF_id ( id_alias ( pid ) ) ;
1485
		if ( EQ_id ( id, pid ) ) return ( 1 ) ;
1486
	    }
1487
	}
1488
    }
1489
    if ( !IS_NULL_list ( pids ) ) {
1490
	/* Check identifier lists */
1491
	IDENTIFIER qid = DEREF_id ( HEAD_list ( pids ) ) ;
1492
	pids = TAIL_list ( pids ) ;
1493
	return ( already_found_id ( id, qid, pids ) ) ;
1494
    }
1495
    return ( 0 ) ;
1496
}
1497
 
1498
 
1499
/*
1500
    LOOK UP AN IDENTIFIER IN A NAMESPACE
1501
 
1502
    This routine looks up the identifier nm in the namespace ns.
1503
*/
1504
 
1505
IDENTIFIER search_id
1506
    PROTO_N ( ( ns, nm, create, type ) )
1507
    PROTO_T ( NAMESPACE ns X HASHID nm X int create X int type )
1508
{
1509
    IDENTIFIER id ;
1510
    MEMBER mem = search_member ( ns, nm, create ) ;
1511
    if ( !IS_NULL_member ( mem ) ) {
1512
	if ( type ) {
1513
	    id = type_member ( mem, type ) ;
1514
	} else {
1515
	    id = DEREF_id ( member_id ( mem ) ) ;
1516
	}
1517
    } else {
1518
	id = NULL_id ;
1519
    }
1520
    return ( id ) ;
1521
}
1522
 
1523
 
1524
/*
1525
    SEARCH A NAMESPACE FOR AN IDENTIFIER
1526
 
1527
    This routine searches the namespace ns and used namespaces for an
1528
    identifier named nm, which is returned if found.  Otherwise if create
1529
    is true then a dummy identifier is created and returned.  Otherwise
1530
    the null identifier is returned.  qual is true for qualified look-ups.
1531
    If type is nonzero then only type and namespace names are considered.
1532
    rns gives the original value of ns for use when recursively searching
1533
    used namespaces.
1534
*/
1535
 
1536
static IDENTIFIER search_nspace
1537
    PROTO_N ( ( ns, nm, rns, qual, create, type ) )
1538
    PROTO_T ( NAMESPACE ns X HASHID nm X NAMESPACE rns X int qual X
1539
	      int create X int type )
1540
{
1541
    IDENTIFIER id ;
1542
    LIST ( NAMESPACE ) uns ;
1543
 
1544
    /* Allow for class namespaces */
1545
    if ( IS_nspace_ctype ( ns ) ) {
1546
	id = search_field ( ns, nm, create, type ) ;
1547
	return ( id ) ;
1548
    }
1549
 
1550
    /* Search main namespace */
1551
    id = search_id ( ns, nm, create, type ) ;
1552
    if ( !IS_NULL_id ( id ) && qual ) {
1553
	/* Return found identifier */
1554
	return ( id ) ;
1555
    }
1556
 
1557
    /* Search used namespaces */
1558
    uns = DEREF_list ( nspace_use ( ns ) ) ;
1559
    if ( !IS_NULL_list ( uns ) ) {
1560
	LIST ( NAMESPACE ) vns = DEREF_list ( nspace_join ( ns ) ) ;
1561
	LIST ( NAMESPACE ) uns_orig = uns ;
1562
	LIST ( NAMESPACE ) vns_orig = vns ;
1563
	LIST ( IDENTIFIER ) ambig = NULL_list ( IDENTIFIER ) ;
1564
	COPY_list ( nspace_use ( ns ), NULL_list ( NAMESPACE ) ) ;
1565
	COPY_list ( nspace_join ( ns ), NULL_list ( NAMESPACE ) ) ;
1566
	while ( !IS_NULL_list ( uns ) ) {
1567
	    NAMESPACE pns = DEREF_nspace ( HEAD_list ( uns ) ) ;
1568
	    NAMESPACE jns = DEREF_nspace ( HEAD_list ( vns ) ) ;
1569
	    if ( qual || is_subnspace ( rns, jns ) ) {
1570
		/* Look-up identifier in used namespace */
1571
		IDENTIFIER pid ;
1572
		pid = search_nspace ( pns, nm, rns, qual, 0, type ) ;
1573
		if ( !IS_NULL_id ( pid ) ) {
1574
		    /* Add found identifier to list */
1575
		    if ( IS_NULL_id ( id ) ) {
1576
			id = pid ;
1577
		    } else if ( !already_found_id ( pid, id, ambig ) ) {
1578
			CONS_id ( pid, ambig, ambig ) ;
1579
		    }
1580
		}
1581
	    } else {
1582
		/* Postpone look-up until join namespace */
1583
		if ( use_namespace ( pns, jns, jns ) ) {
1584
		    CONS_nspace ( jns, join_nspaces, join_nspaces ) ;
1585
		}
1586
	    }
1587
	    vns = TAIL_list ( vns ) ;
1588
	    uns = TAIL_list ( uns ) ;
1589
	}
1590
	if ( !IS_NULL_list ( ambig ) ) {
1591
	    /* Ambiguous resolution */
1592
	    DECL_SPEC ds ;
1593
	    CONS_id ( id, ambig, ambig ) ;
1594
	    ds = find_ambig_dspec ( ambig ) ;
1595
	    MAKE_id_ambig ( nm, ds, rns, crt_loc, ambig, 1, id ) ;
1596
	}
1597
	COPY_list ( nspace_use ( ns ), uns_orig ) ;
1598
	COPY_list ( nspace_join ( ns ), vns_orig ) ;
1599
    }
1600
 
1601
    /* Create dummy identifier if necessary */
1602
    if ( IS_NULL_id ( id ) && create ) {
1603
	MAKE_id_undef ( nm, dspec_none, ns, crt_loc, id ) ;
1604
    }
1605
    return ( id ) ;
1606
}
1607
 
1608
 
1609
/*
1610
    EXTERNAL NAME LOOK-UP
1611
 
1612
    This routine searches all the namespaces in the current namespace stack
1613
    which are contained within pns for the identifier pns.  If type is
1614
    nonzero then only type and namespace names are considered.
1615
*/
1616
 
1617
IDENTIFIER find_extern_id
1618
    PROTO_N ( ( nm, pns, type ) )
1619
    PROTO_T ( HASHID nm X NAMESPACE pns X int type )
1620
{
1621
    IDENTIFIER id = NULL_id ;
1622
    LIST ( NAMESPACE ) lns = LIST_stack ( namespace_stack ) ;
1623
    while ( !IS_NULL_list ( lns ) ) {
1624
	NAMESPACE ns = DEREF_nspace ( HEAD_list ( lns ) ) ;
1625
	if ( !IS_NULL_nspace ( ns ) ) {
1626
	    id = search_nspace ( ns, nm, ns, 0, 0, type ) ;
1627
	    if ( !IS_NULL_id ( id ) ) break ;
1628
	    if ( EQ_nspace ( ns, pns ) ) break ;
1629
	}
1630
	lns = TAIL_list ( lns ) ;
1631
    }
1632
    if ( !IS_NULL_list ( join_nspaces ) ) clear_join_nspaces () ;
1633
    return ( id ) ;
1634
}
1635
 
1636
 
1637
/*
1638
    UNQUALIFIED NAME LOOK-UP
1639
 
1640
    This routine (aka who the feck is fred?) looks up the name nm in the
1641
    current scope, returning the corresponding identifier.  Note that
1642
    there is always a meaning for nm even if it is the underlying dummy
1643
    identifier.
1644
*/
1645
 
1646
IDENTIFIER find_id
1647
    PROTO_N ( ( nm ) )
1648
    PROTO_T ( HASHID nm )
1649
{
1650
    IDENTIFIER id ;
1651
    if ( cache_lookup ) {
1652
	id = DEREF_id ( hashid_cache ( nm ) ) ;
1653
	if ( IS_NULL_id ( id ) ) {
1654
	    id = find_extern_id ( nm, NULL_nspace, 0 ) ;
1655
	    if ( IS_NULL_id ( id ) ) {
1656
		/* Use underlying meaning if not found */
1657
		id = DEREF_id ( hashid_id ( nm ) ) ;
1658
	    }
1659
	    COPY_id ( hashid_cache ( nm ), id ) ;
1660
	}
1661
    } else {
1662
	id = find_extern_id ( nm, NULL_nspace, 0 ) ;
1663
	if ( IS_NULL_id ( id ) ) {
1664
	    /* Use underlying meaning if not found */
1665
	    id = DEREF_id ( hashid_id ( nm ) ) ;
1666
	}
1667
    }
1668
    return ( id ) ;
1669
}
1670
 
1671
 
1672
/*
1673
    QUALIFIED NAME LOOK-UP
1674
 
1675
    This routine (aka who the feck is fred::bloggs?) looks up the name nm
1676
    in the namespace ns.  Only type names are considered when type is
1677
    nonzero.  When ns is the null namespace this reduces to an unqualified
1678
    name look-up.
1679
*/
1680
 
1681
IDENTIFIER find_qual_id
1682
    PROTO_N ( ( ns, nm, create, type ) )
1683
    PROTO_T ( NAMESPACE ns X HASHID nm X int create X int type )
1684
{
1685
    IDENTIFIER id ;
1686
    if ( IS_NULL_nspace ( ns ) ) {
1687
	/* Unqualified name look-up */
1688
	if ( type == 0 ) {
1689
	    id = find_id ( nm ) ;
1690
	} else {
1691
	    id = find_type_id ( nm, type ) ;
1692
	}
1693
    } else {
1694
	/* Qualified name look-up */
1695
	id = search_nspace ( ns, nm, ns, 1, create, type ) ;
1696
    }
1697
    return ( id ) ;
1698
}
1699
 
1700
 
1701
/*
1702
    SIMPLE TYPE NAME LOOK-UP
1703
 
1704
    This routine looks up the name nm as a type in the current scope,
1705
    returning the corresponding identifier.  If there is no type named
1706
    nm then the null identifier is returned.
1707
*/
1708
 
1709
IDENTIFIER find_type_id
1710
    PROTO_N ( ( nm, type ) )
1711
    PROTO_T ( HASHID nm X int type )
1712
{
1713
    IDENTIFIER id ;
1714
    if ( cache_lookup ) {
1715
	/* Check whether cached value is a type */
1716
	id = DEREF_id ( hashid_cache ( nm ) ) ;
1717
	id = select_type_id ( id, type ) ;
1718
	if ( !IS_NULL_id ( id ) ) return ( id ) ;
1719
    }
1720
    id = find_extern_id ( nm, NULL_nspace, type ) ;
1721
    return ( id ) ;
1722
}
1723
 
1724
 
1725
/*
1726
    OPERATOR FUNCTION NAME LOOK-UP
1727
 
1728
    This routine is identical to find_id except that it ignores all class
1729
    namespaces.  This is used when looking up operator functions in C++
1730
    and is the default look-up rule in C.
1731
*/
1732
 
1733
IDENTIFIER find_op_id
1734
    PROTO_N ( ( nm ) )
1735
    PROTO_T ( HASHID nm )
1736
{
1737
    IDENTIFIER id ;
1738
    LIST ( NAMESPACE ) lns ;
1739
    int cache = cache_lookup ;
1740
    if ( cache ) {
1741
	/* Check cached look-up */
1742
	id = DEREF_id ( hashid_cache ( nm ) ) ;
1743
	if ( !IS_NULL_id ( id ) ) {
1744
	    NAMESPACE ns = DEREF_nspace ( id_parent ( id ) ) ;
1745
	    if ( IS_NULL_nspace ( ns ) || !IS_nspace_ctype ( ns ) ) {
1746
		return ( id ) ;
1747
	    }
1748
	    cache = 0 ;
1749
	}
1750
    }
1751
 
1752
    /* Scan through namespace stack */
1753
    lns = LIST_stack ( namespace_stack ) ;
1754
    while ( !IS_NULL_list ( lns ) ) {
1755
	NAMESPACE ns = DEREF_nspace ( HEAD_list ( lns ) ) ;
1756
	if ( !IS_NULL_nspace ( ns ) && !IS_nspace_ctype ( ns ) ) {
1757
	    id = search_nspace ( ns, nm, ns, 0, 0, 0 ) ;
1758
	    if ( !IS_NULL_id ( id ) ) {
1759
		if ( !IS_NULL_list ( join_nspaces ) ) clear_join_nspaces () ;
1760
		if ( cache ) COPY_id ( hashid_cache ( nm ), id ) ;
1761
		return ( id ) ;
1762
	    }
1763
	} else {
1764
	    cache = 0 ;
1765
	}
1766
	lns = TAIL_list ( lns ) ;
1767
    }
1768
    if ( !IS_NULL_list ( join_nspaces ) ) clear_join_nspaces () ;
1769
    id = DEREF_id ( hashid_id ( nm ) ) ;
1770
    if ( cache ) COPY_id ( hashid_cache ( nm ), id ) ;
1771
    return ( id ) ;
1772
}
1773
 
1774
 
1775
/*
1776
    FINAL NAME LOOK-UP CHECK
1777
 
1778
    This routine gives a final check in the name look-up.  In most cases
1779
    id will already be a valid identifier for the namespace ns - the couple
1780
    of exceptions - undeclared members and non-simple identifier names
1781
    are handled by this routine.
1782
*/
1783
 
1784
IDENTIFIER check_id
1785
    PROTO_N ( ( ns, id, templ ) )
1786
    PROTO_T ( NAMESPACE ns X IDENTIFIER id X int templ )
1787
{
1788
    if ( !IS_NULL_id ( id ) ) {
1789
	unsigned tag = TAG_id ( id ) ;
1790
	if ( tag == id_dummy_tag ) {
1791
	    /* Re-scan dummy identifiers */
1792
	    HASHID nm = DEREF_hashid ( id_name ( id ) ) ;
1793
	    id = find_qual_id ( ns, nm, 1, 0 ) ;
1794
	    tag = TAG_id ( id ) ;
1795
	}
1796
	if ( tag == id_token_tag && crt_id_qualifier != qual_none ) {
1797
	    /* Can't qualify token names */
1798
	    report ( crt_loc, ERR_token_qual ( id ) ) ;
1799
	}
1800
	UNUSED ( templ ) ;
1801
    }
1802
    return ( id ) ;
1803
}
1804
 
1805
 
1806
/*
1807
    REMOVE AN ELEMENT OF A SET OF OVERLOADED FUNCTIONS
1808
 
1809
    This routine removes the function id from the set of overloaded
1810
    functions fid.
1811
*/
1812
 
1813
static IDENTIFIER remove_func
1814
    PROTO_N ( ( fid, id ) )
1815
    PROTO_T ( IDENTIFIER fid X IDENTIFIER id )
1816
{
1817
    if ( !IS_NULL_id ( fid ) ) {
1818
	IDENTIFIER pid = DEREF_id ( id_function_etc_over ( fid ) ) ;
1819
	if ( EQ_id ( fid, id ) ) {
1820
	    fid = pid ;
1821
	    COPY_id ( id_function_etc_over ( id ), NULL_id ) ;
1822
	} else {
1823
	    pid = remove_func ( pid, id ) ;
1824
	    COPY_id ( id_function_etc_over ( fid ), pid ) ;
1825
	}
1826
    }
1827
    return ( fid ) ;
1828
}
1829
 
1830
 
1831
/*
1832
    REMOVE AN IDENTIFIER FROM A NAMESPACE
1833
 
1834
    This routine removes the identifier id its parent namespace.
1835
*/
1836
 
1837
void remove_id
1838
    PROTO_N ( ( id ) )
1839
    PROTO_T ( IDENTIFIER id )
1840
{
1841
    HASHID nm = DEREF_hashid ( id_name ( id ) ) ;
1842
    NAMESPACE ns = DEREF_nspace ( id_parent ( id ) ) ;
1843
    MEMBER mem = search_member ( ns, nm, 0 ) ;
1844
    if ( !IS_NULL_member ( mem ) ) {
1845
	IDENTIFIER mid = DEREF_id ( member_id ( mem ) ) ;
1846
	IDENTIFIER tid = DEREF_id ( member_alt ( mem ) ) ;
1847
	if ( IS_id_function_etc ( id ) ) {
1848
	    mid = remove_func ( mid, id ) ;
1849
	} else {
1850
	    if ( EQ_id ( id, mid ) ) mid = NULL_id ;
1851
	    if ( EQ_id ( id, tid ) ) tid = NULL_id ;
1852
	}
1853
	if ( IS_NULL_id ( mid ) ) mid = tid ;
1854
	COPY_id ( member_id ( mem ), mid ) ;
1855
	COPY_id ( member_alt ( mem ), tid ) ;
1856
	COPY_id ( hashid_cache ( nm ), NULL_id ) ;
1857
	IGNORE check_identifier ( id, ns, NULL_exp, ANON_NONE, 1 ) ;
1858
    }
1859
    return ;
1860
}
1861
 
1862
 
1863
/*
1864
    DOES AN IDENTIFIER HAVE AN EXTERNAL LINKAGE NAME?
1865
 
1866
    This routine checks whether the identifier id has an external linkage
1867
    name.  It cannot be a member of a block, an unnamed class or an
1868
    anonymous namespace.
1869
*/
1870
 
1871
int has_linkage
1872
    PROTO_N ( ( id ) )
1873
    PROTO_T ( IDENTIFIER id )
1874
{
1875
    while ( !IS_NULL_id ( id ) ) {
1876
	HASHID nm = DEREF_hashid ( id_name ( id ) ) ;
1877
	NAMESPACE ns = DEREF_nspace ( id_parent ( id ) ) ;
1878
	DECL_SPEC ds = DEREF_dspec ( id_storage ( id ) ) ;
1879
	if ( IS_hashid_anon ( nm ) ) return ( 0 ) ;
1880
	if ( !( ds & dspec_extern ) ) return ( 0 ) ;
1881
	if ( ( ds & dspec_c ) && !anon_c_linkage ) return ( 1 ) ;
1882
	if ( IS_NULL_nspace ( ns ) ) return ( 0 ) ;
1883
	switch ( TAG_nspace ( ns ) ) {
1884
	    case nspace_named_tag : break ;
1885
	    case nspace_ctype_tag : break ;
1886
	    case nspace_global_tag : return ( 1 ) ;
1887
	    default : return ( 0 ) ;
1888
	}
1889
	id = DEREF_id ( nspace_name ( ns ) ) ;
1890
    }
1891
    return ( 0 ) ;
1892
}
1893
 
1894
 
1895
/*
1896
    CHECK HIDING OF LOCAL VARIABLES
1897
 
1898
    This routine is used to report on variables, parameters and functions
1899
    hidden by id.  Note that only the first instance is reported, and that
1900
    the hiding of one declaration by a subsequent incompatible redeclaration
1901
    is excluded.
1902
*/
1903
 
1904
void check_hiding
1905
    PROTO_N ( ( id ) )
1906
    PROTO_T ( IDENTIFIER id )
1907
{
1908
    if ( crt_id_qualifier == qual_none ) {
1909
	/* Check through all look-up namespaces */
1910
	HASHID nm = DEREF_hashid ( id_name ( id ) ) ;
1911
	LIST ( NAMESPACE ) lns = LIST_stack ( namespace_stack ) ;
1912
	while ( !IS_NULL_list ( lns ) ) {
1913
	    NAMESPACE ns = DEREF_nspace ( HEAD_list ( lns ) ) ;
1914
	    if ( !IS_NULL_nspace ( ns ) ) {
1915
		IDENTIFIER mid = search_nspace ( ns, nm, ns, 0, 0, 0 ) ;
1916
		if ( !IS_NULL_id ( mid ) && !EQ_id ( mid, id ) ) {
1917
		    ERROR err = NULL_err ;
1918
		    switch ( TAG_id ( mid ) ) {
1919
			case id_variable_tag :
1920
			case id_parameter_tag :
1921
			case id_function_tag : {
1922
			    /* Report hiding of these objects */
1923
			    PTR ( LOCATION ) mloc = id_loc ( mid ) ;
1924
			    err = ERR_basic_scope_hide ( nm, mloc ) ;
1925
			    break ;
1926
			}
1927
			case id_stat_member_tag :
1928
			case id_mem_func_tag :
1929
			case id_stat_mem_func_tag :
1930
			case id_member_tag : {
1931
			    /* Report hiding of members */
1932
			    err = ERR_basic_scope_hide_mem ( nm, mid ) ;
1933
			    break ;
1934
			}
1935
		    }
1936
		    if ( !IS_NULL_err ( err ) ) {
1937
			/* Print error */
1938
			LOCATION loc ;
1939
			DEREF_loc ( id_loc ( id ), loc ) ;
1940
			report ( crt_loc, err ) ;
1941
		    }
1942
		    break ;
1943
		}
1944
	    }
1945
	    lns = TAIL_list ( lns ) ;
1946
	}
1947
	if ( !IS_NULL_list ( join_nspaces ) ) clear_join_nspaces () ;
1948
    }
1949
    return ;
1950
}