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 "etype_ops.h"
35
#include "ftype_ops.h"
36
#include "hashid_ops.h"
37
#include "id_ops.h"
38
#include "itype_ops.h"
39
#include "member_ops.h"
40
#include "type_ops.h"
41
#include "error.h"
42
#include "option.h"
43
#include "basetype.h"
44
#include "char.h"
45
#include "chktype.h"
46
#include "hash.h"
47
#include "lex.h"
48
#include "namespace.h"
49
#include "symbols.h"
50
#include "syntax.h"
51
#include "token.h"
52
#include "ustring.h"
53
#include "xalloc.h"
54
 
55
 
56
/*
57
    HASH TABLES
58
 
59
    The hash tables consist of an array of hash identifiers, one for each
60
    hash value.  All the hash table entries with the same hash value are
61
    chained into a list using their next field.  There are two hash tables,
62
    one for strings and one for types.
63
*/
64
 
65
HASHID *hash_table ;
66
static HASHID *hash_type_table ;
67
 
68
 
69
/*
70
    IDENTIFIER NAME HASHING FUNCTION
71
 
72
    This routine calculates the hash value associated with the identifier
73
    name s.  The main parser routine, read_token, calculates the hash values
74
    of the identifiers it reads on the fly and stores them in token_hash.
75
    Therefore any changes to this routine should also be reflected in
76
    read_token.
77
*/
78
 
79
unsigned long hash
80
    PROTO_N ( ( s ) )
81
    PROTO_T ( string s )
82
{
83
    character c ;
84
    unsigned long h = 0 ;
85
    while ( c = *( s++ ), c != 0 ) {
86
	h = HASH_POWER * h + ( unsigned long ) c ;
87
    }
88
    return ( h % HASH_SIZE ) ;
89
}
90
 
91
 
92
/*
93
    TYPE NAME HASHING FUNCTION
94
 
95
    This routine calculates the hash value associated with the type t.
96
    This is used in the look-up for the conversion function identifier
97
    'operator t'.
98
*/
99
 
100
static unsigned long hash_type
101
    PROTO_N ( ( t ) )
102
    PROTO_T ( TYPE t )
103
{
104
    unsigned long h = 0 ;
105
    while ( !IS_NULL_type ( t ) ) {
106
	unsigned long sub = 0 ;
107
	unsigned long tag = ( unsigned long ) TAG_type ( t ) ;
108
	CV_SPEC qual = DEREF_cv ( type_qual ( t ) ) ;
109
	switch ( tag ) {
110
	    case type_integer_tag : {
111
		INT_TYPE it = DEREF_itype ( type_integer_rep ( t ) ) ;
112
		if ( IS_itype_basic ( it ) ) {
113
		    BUILTIN_TYPE no = DEREF_ntype ( itype_basic_no ( it ) ) ;
114
		    sub = ( unsigned long ) no ;
115
		}
116
		t = NULL_type ;
117
		break ;
118
	    }
119
	    case type_floating_tag : {
120
		FLOAT_TYPE ft = DEREF_ftype ( type_floating_rep ( t ) ) ;
121
		if ( IS_ftype_basic ( ft ) ) {
122
		    BUILTIN_TYPE no = DEREF_ntype ( ftype_basic_no ( ft ) ) ;
123
		    sub = ( unsigned long ) no ;
124
		}
125
		t = NULL_type ;
126
		break ;
127
	    }
128
	    case type_ptr_tag :
129
	    case type_ref_tag : {
130
		t = DEREF_type ( type_ptr_etc_sub ( t ) ) ;
131
		break ;
132
	    }
133
	    case type_ptr_mem_tag : {
134
		CLASS_TYPE ct = DEREF_ctype ( type_ptr_mem_of ( t ) ) ;
135
		IDENTIFIER cid = DEREF_id ( ctype_name ( ct ) ) ;
136
		HASHID cnm = DEREF_hashid ( id_name ( cid ) ) ;
137
		sub = DEREF_ulong ( hashid_hash ( cnm ) ) ;
138
		t = DEREF_type ( type_ptr_mem_sub ( t ) ) ;
139
		break ;
140
	    }
141
	    case type_func_tag : {
142
		LIST ( TYPE ) p = DEREF_list ( type_func_ptypes ( t ) ) ;
143
		sub = ( unsigned long ) LENGTH_list ( p ) ;
144
		t = DEREF_type ( type_func_ret ( t ) ) ;
145
		break ;
146
	    }
147
	    case type_array_tag : {
148
		t = DEREF_type ( type_array_sub ( t ) ) ;
149
		break ;
150
	    }
151
	    case type_bitfield_tag : {
152
		t = find_bitfield_type ( t ) ;
153
		break ;
154
	    }
155
	    case type_compound_tag : {
156
		CLASS_TYPE ct = DEREF_ctype ( type_compound_defn ( t ) ) ;
157
		IDENTIFIER cid = DEREF_id ( ctype_name ( ct ) ) ;
158
		HASHID cnm = DEREF_hashid ( id_name ( cid ) ) ;
159
		sub = DEREF_ulong ( hashid_hash ( cnm ) ) ;
160
		t = NULL_type ;
161
		break ;
162
	    }
163
	    case type_enumerate_tag : {
164
		ENUM_TYPE et = DEREF_etype ( type_enumerate_defn ( t ) ) ;
165
		IDENTIFIER eid = DEREF_id ( etype_name ( et ) ) ;
166
		HASHID enm = DEREF_hashid ( id_name ( eid ) ) ;
167
		sub = DEREF_ulong ( hashid_hash ( enm ) ) ;
168
		t = NULL_type ;
169
		break ;
170
	    }
171
	    default : {
172
		t = NULL_type ;
173
		break ;
174
	    }
175
	}
176
	h += ( 64 * sub + 4 * tag + ( unsigned long ) qual ) ;
177
    }
178
    return ( h % HASH_TYPE_SIZE ) ;
179
}
180
 
181
 
182
/*
183
    INITIALISE A HASH TABLE ENTRY
184
 
185
    This routine initialises the hash table entry nm by creating a dummy
186
    identifier with lexical token value tok for it to point to.
187
*/
188
 
189
static void init_hashid
190
    PROTO_N ( ( nm, tok ) )
191
    PROTO_T ( HASHID nm X int tok )
192
{
193
    IDENTIFIER id ;
194
    MAKE_id_dummy ( nm, dspec_none, NULL_nspace, crt_loc, id ) ;
195
    COPY_ulong ( id_no ( id ), ( unsigned long ) tok ) ;
196
    COPY_id ( hashid_id ( nm ), id ) ;
197
    COPY_id ( hashid_cache ( nm ), id ) ;
198
    return ;
199
}
200
 
201
 
202
/*
203
    LOOK UP AN IDENTIFIER NAME IN THE HASH TABLE
204
 
205
    This routine looks up the identifier name s in the hash table, creating
206
    it if it does not already exist.  h gives the value of hash ( s ) (which
207
    gets checked by an assertion).  The argument tok is set to lex_unknown to
208
    indicate that the identifier has just been read by read_token, otherwise
209
    it gives the underlying default lexical token.
210
*/
211
 
212
HASHID lookup_name
213
    PROTO_N ( ( s, h, ext, tok ) )
214
    PROTO_T ( string s X unsigned long h X int ext X int tok )
215
{
216
    unsigned tag ;
217
    unsigned long len ;
218
    HASHID prev = NULL_hashid ;
219
    HASHID nm = hash_table [h] ;
220
    ASSERT ( h == hash ( s ) ) ;
221
 
222
    /* Search through existing entries */
223
    while ( !IS_NULL_hashid ( nm ) ) {
224
	string t = DEREF_string ( hashid_name_etc_text ( nm ) ) ;
225
	int c = ustrcmp ( t, s ) ;
226
	if ( c == 0 ) {
227
	    /* Name matches */
228
	    return ( nm ) ;
229
	}
230
	if ( c > 0 ) break ;
231
	prev = nm ;
232
	nm = DEREF_hashid ( hashid_next ( nm ) ) ;
233
    }
234
 
235
    /* Create new hash table entry */
236
    len = ( unsigned long ) ustrlen ( s ) ;
237
    if ( tok == lex_unknown ) {
238
	s = xustrncpy ( s, ( gen_size ) len ) ;
239
	tok = lex_identifier ;
240
    }
241
    tag = hashid_name_tag ;
242
    if ( ext ) {
243
	/* Check for extended identifiers */
244
	string t = s ;
245
	while ( t = ustrchr ( t, char_backslash ), t != NULL ) {
246
	    t++ ;
247
	    if ( *t == char_u ) {
248
		/* '\uxxxx' counts as one character */
249
		len -= 5 ;
250
	    } else {
251
		/* '\Uxxxxxxxx' counts as one character */
252
		len -= 9 ;
253
	    }
254
	}
255
	tag = hashid_ename_tag ;
256
    }
257
    MAKE_hashid_name_etc ( tag, nm, h, s, nm ) ;
258
    if ( IS_NULL_hashid ( prev ) ) {
259
	hash_table [h] = nm ;
260
    } else {
261
	COPY_hashid ( hashid_next ( prev ), nm ) ;
262
    }
263
    init_hashid ( nm, tok ) ;
264
    if ( len >= max_id_length ) {
265
	/* Check name length */
266
	IGNORE check_value ( OPT_VAL_name_limit, len, nm ) ;
267
    }
268
    return ( nm ) ;
269
}
270
 
271
 
272
/*
273
    CREATE A SPECIAL FUNCTION NAME
274
 
275
    This routine creates a constructor, destructor or conversion function
276
    name (as indicated by tag) for the non-class type t named id.
277
*/
278
 
279
static HASHID lookup_special
280
    PROTO_N ( ( t, id, tag ) )
281
    PROTO_T ( TYPE t X IDENTIFIER id X unsigned tag )
282
{
283
    unsigned long h = hash_type ( t ) ;
284
    HASHID prev = hash_type_table [h] ;
285
    HASHID nm = prev ;
286
 
287
    /* Search through existing entries */
288
    while ( !IS_NULL_hashid ( nm ) ) {
289
	if ( TAG_hashid ( nm ) == tag ) {
290
	    TYPE s = DEREF_type ( hashid_constr_etc_type ( nm ) ) ;
291
	    if ( eq_type ( s, t ) ) {
292
		COPY_id ( hashid_constr_etc_tid ( nm ), id ) ;
293
		return ( nm ) ;
294
	    }
295
	}
296
	nm = DEREF_hashid ( hashid_next ( nm ) ) ;
297
    }
298
 
299
    /* Create new hash table entry */
300
    ASSERT ( h < HASH_SIZE ) ;
301
    MAKE_hashid_constr_etc ( tag, prev, h, t, id, nm ) ;
302
    init_hashid ( nm, lex_identifier ) ;
303
    hash_type_table [h] = nm ;
304
    return ( nm ) ;
305
}
306
 
307
 
308
/*
309
    CREATE THE CONSTRUCTOR FOR A TYPE
310
 
311
    This routine creates the hash table entry for the constructor of type t
312
    and name id.
313
*/
314
 
315
HASHID lookup_constr
316
    PROTO_N ( ( t, id ) )
317
    PROTO_T ( TYPE t X IDENTIFIER id )
318
{
319
    HASHID nm ;
320
    if ( IS_type_compound ( t ) ) {
321
	CLASS_TYPE ct = DEREF_ctype ( type_compound_defn ( t ) ) ;
322
	IDENTIFIER cid = DEREF_id ( ctype_constr ( ct ) ) ;
323
	if ( IS_NULL_id ( cid ) ) {
324
	    /* Create class contructor */
325
	    NAMESPACE ns = DEREF_nspace ( ctype_member ( ct ) ) ;
326
	    MAKE_hashid_constr ( NULL_hashid, 0, t, id, nm ) ;
327
	    init_hashid ( nm, lex_identifier ) ;
328
	    cid = DEREF_id ( hashid_id ( nm ) ) ;
329
	    COPY_nspace ( id_parent ( cid ), ns ) ;
330
	    COPY_id ( ctype_constr ( ct ), cid ) ;
331
	    IGNORE search_member ( ns, nm, 1 ) ;
332
	} else {
333
	    nm = DEREF_hashid ( id_name ( cid ) ) ;
334
	}
335
    } else {
336
	nm = lookup_special ( t, id, hashid_constr_tag ) ;
337
    }
338
    return ( nm ) ;
339
}
340
 
341
 
342
/*
343
    CREATE THE DESTRUCTOR FOR A TYPE
344
 
345
    This routine creates the hash table entry for the destructor of type t
346
    and name id.
347
*/
348
 
349
HASHID lookup_destr
350
    PROTO_N ( ( t, id ) )
351
    PROTO_T ( TYPE t X IDENTIFIER id )
352
{
353
    HASHID nm ;
354
    if ( IS_type_compound ( t ) ) {
355
	CLASS_TYPE ct = DEREF_ctype ( type_compound_defn ( t ) ) ;
356
	IDENTIFIER cid = DEREF_id ( ctype_destr ( ct ) ) ;
357
	if ( IS_NULL_id ( cid ) ) {
358
	    /* Create class destructor */
359
	    NAMESPACE ns = DEREF_nspace ( ctype_member ( ct ) ) ;
360
	    MAKE_hashid_destr ( NULL_hashid, 1, t, id, nm ) ;
361
	    init_hashid ( nm, lex_identifier ) ;
362
	    cid = DEREF_id ( hashid_id ( nm ) ) ;
363
	    COPY_nspace ( id_parent ( cid ), ns ) ;
364
	    COPY_id ( ctype_destr ( ct ), cid ) ;
365
	    IGNORE search_member ( ns, nm, 1 ) ;
366
	} else {
367
	    nm = DEREF_hashid ( id_name ( cid ) ) ;
368
	}
369
    } else {
370
	nm = lookup_special ( t, id, hashid_destr_tag ) ;
371
    }
372
    return ( nm ) ;
373
}
374
 
375
 
376
/*
377
    LOOK UP A CONVERSION FUNCTION NAME
378
 
379
    This routine returns the hash table entry for the conversion function
380
    corresponding to the type t.
381
*/
382
 
383
HASHID lookup_conv
384
    PROTO_N ( ( t ) )
385
    PROTO_T ( TYPE t )
386
{
387
    HASHID nm = lookup_special ( t, NULL_id, hashid_conv_tag ) ;
388
    return ( nm ) ;
389
}
390
 
391
 
392
/*
393
    OVERLOADED OPERATOR LOOK-UP TABLE
394
 
395
    This table gives the hash table entries for the overloaded operator
396
    function names, 'operator +' etc.  It gives a straight look-up depending
397
    on the lexical token number of the operator.  All ISO keyword and
398
    digraphs are represented in their primary form.
399
*/
400
 
401
HASHID *hash_ops_table ;
402
 
403
 
404
/*
405
    CREATE AN OPERATOR HASH TABLE ENTRY
406
 
407
    This routine creates a hash table entry for 'operator op' when op has
408
    lexical token number t.
409
*/
410
 
411
static HASHID make_op
412
    PROTO_N ( ( t ) )
413
    PROTO_T ( int t )
414
{
415
    HASHID nm ;
416
    unsigned long h = ( unsigned long ) t ;
417
    MAKE_hashid_op ( NULL_hashid, ( h % HASH_SIZE ), t, nm ) ;
418
    init_hashid ( nm, lex_identifier ) ;
419
    return ( nm ) ;
420
}
421
 
422
 
423
/*
424
    LOOK UP AN ANONYMOUS IDENTIFIER
425
 
426
    This routine creates a hash table entry for an anonymous identifier.
427
    Note that each anonymous identifier gives a distinct hash table entry.
428
*/
429
 
430
HASHID lookup_anon
431
    PROTO_Z ()
432
{
433
    HASHID nm ;
434
    static unsigned long anon_no = 0 ;
435
    unsigned long a = anon_no++ ;
436
    MAKE_hashid_anon ( NULL_hashid, ( a % HASH_SIZE ), a, nm ) ;
437
    init_hashid ( nm, lex_identifier ) ;
438
    return ( nm ) ;
439
}
440
 
441
 
442
/*
443
    EXPAND AN IDENTIFIER NAME
444
 
445
    This routine expands the identifier name nm.  For example, if t is
446
    a tokenised type defined to be int, then 'operator t' expands to
447
    'operator int'.  ct gives the expansion type for constructors and
448
    destructors.
449
*/
450
 
451
HASHID expand_name
452
    PROTO_N ( ( nm, ct ) )
453
    PROTO_T ( HASHID nm X CLASS_TYPE ct )
454
{
455
    switch ( TAG_hashid ( nm ) ) {
456
	case hashid_constr_tag : {
457
	    /* Constructor names */
458
	    if ( !IS_NULL_ctype ( ct ) ) {
459
		IDENTIFIER id = DEREF_id ( ctype_constr ( ct ) ) ;
460
		nm = DEREF_hashid ( id_name ( id ) ) ;
461
	    } else {
462
		TYPE t = DEREF_type ( hashid_constr_type ( nm ) ) ;
463
		TYPE s = expand_type ( t, 1 ) ;
464
		if ( !EQ_type ( t, s ) ) {
465
		    nm = lookup_constr ( s, NULL_id ) ;
466
		}
467
	    }
468
	    break ;
469
	}
470
	case hashid_destr_tag : {
471
	    /* Destructor names */
472
	    if ( !IS_NULL_ctype ( ct ) ) {
473
		IDENTIFIER id = DEREF_id ( ctype_destr ( ct ) ) ;
474
		nm = DEREF_hashid ( id_name ( id ) ) ;
475
	    } else {
476
		TYPE t = DEREF_type ( hashid_destr_type ( nm ) ) ;
477
		TYPE s = expand_type ( t, 1 ) ;
478
		if ( !EQ_type ( t, s ) ) {
479
		    nm = lookup_destr ( s, NULL_id ) ;
480
		}
481
	    }
482
	    break ;
483
	}
484
	case hashid_conv_tag : {
485
	    /* Conversion function names */
486
	    TYPE t = DEREF_type ( hashid_conv_type ( nm ) ) ;
487
	    TYPE s = expand_type ( t, 1 ) ;
488
	    if ( !EQ_type ( t, s ) ) {
489
		nm = lookup_conv ( s ) ;
490
	    }
491
	    break ;
492
	}
493
    }
494
    return ( nm ) ;
495
}
496
 
497
 
498
/*
499
    FIND NEXT VERSION OF AN EXPANDED IDENTIFIER NAME
500
 
501
    There is a complication in the expansion of conversion function names
502
    in that when types are identified more than one name may refer to the
503
    same type.  This routine finds the next such possible name returning
504
    the null identifier name to indicate that there are no more.
505
*/
506
 
507
HASHID next_expand_name
508
    PROTO_N ( ( nm ) )
509
    PROTO_T ( HASHID nm )
510
{
511
    if ( IS_hashid_conv ( nm ) ) {
512
	int started = 0 ;
513
	TYPE t = DEREF_type ( hashid_conv_type ( nm ) ) ;
514
	unsigned long h = hash_type ( t ) ;
515
	HASHID pnm = hash_type_table [h] ;
516
	while ( !IS_NULL_hashid ( pnm ) ) {
517
	    if ( EQ_hashid ( pnm, nm ) ) {
518
		started = 1 ;
519
	    } else if ( started && IS_hashid_conv ( pnm ) ) {
520
		TYPE s = DEREF_type ( hashid_conv_type ( pnm ) ) ;
521
		if ( eq_type ( s, t ) ) return ( pnm ) ;
522
	    }
523
	    pnm = DEREF_hashid ( hashid_next ( pnm ) ) ;
524
	}
525
    }
526
    return ( NULL_hashid ) ;
527
}
528
 
529
 
530
/*
531
    FIND A HASH IDENTIFIER NUMBER
532
 
533
    This routine finds the lexical token number associated with the hash
534
    identifier nm.  For a keyword, whether active or not, this is the
535
    associated value from syntax.h, otherwise it is lex_identifier.
536
*/
537
 
538
int find_hashid
539
    PROTO_N ( ( nm ) )
540
    PROTO_T ( HASHID nm )
541
{
542
    unsigned long lex ;
543
    IDENTIFIER id = DEREF_id ( hashid_id ( nm ) ) ;
544
    while ( !IS_id_dummy ( id ) ) {
545
	/* Scan to last hidden value */
546
	id = DEREF_id ( id_alias ( id ) ) ;
547
    }
548
    lex = DEREF_ulong ( id_no ( id ) ) ;
549
    return ( ( int ) lex ) ;
550
}
551
 
552
 
553
/*
554
    FIND AN UNDERLYING IDENTIFIER
555
 
556
    This routine finds the dummy identifier underlying id.
557
*/
558
 
559
IDENTIFIER underlying_id
560
    PROTO_N ( ( id ) )
561
    PROTO_T ( IDENTIFIER id )
562
{
563
    HASHID nm = DEREF_hashid ( id_name ( id ) ) ;
564
    id = DEREF_id ( hashid_id ( nm ) ) ;
565
    while ( !IS_id_dummy ( id ) ) {
566
	/* Scan to last hidden value */
567
	id = DEREF_id ( id_alias ( id ) ) ;
568
    }
569
    return ( id ) ;
570
}
571
 
572
 
573
/*
574
    SET THE LOCATION OF A COMPLEX IDENTIFIER
575
 
576
    The precise location of the last use of a hash identifier is stored
577
    in the loc field of its associated dummy identifier.  For simple
578
    identifiers this is set in read_token, however for more complex
579
    cases this routine sets the location of id to be the location of pid.
580
*/
581
 
582
void set_hashid_loc
583
    PROTO_N ( ( id, pid ) )
584
    PROTO_T ( IDENTIFIER id X IDENTIFIER pid )
585
{
586
    if ( !IS_NULL_id ( pid ) ) {
587
	LOCATION loc ;
588
	if ( !IS_id_dummy ( id ) ) id = underlying_id ( id ) ;
589
	if ( !IS_id_dummy ( pid ) ) pid = underlying_id ( pid ) ;
590
	DEREF_loc ( id_loc ( pid ), loc ) ;
591
	COPY_loc ( id_loc ( id ), loc ) ;
592
    }
593
    return ;
594
}
595
 
596
 
597
/*
598
    MODIFY AN IDENTIFIER NAME
599
 
600
    This routine modifies the name of the identifier id by adding a prime
601
    to it.  This is intended primarily for debugging purposes.
602
*/
603
 
604
void prime_name
605
    PROTO_N ( ( id ) )
606
    PROTO_T ( IDENTIFIER id )
607
{
608
    if ( !IS_NULL_id ( id ) ) {
609
	HASHID nm = DEREF_hashid ( id_name ( id ) ) ;
610
	if ( IS_hashid_name ( nm ) ) {
611
	    string s = DEREF_string ( hashid_name_text ( nm ) ) ;
612
	    s = xustrcat ( s, ustrlit ( "'" ) ) ;
613
	    nm = lookup_name ( s, hash ( s ), 0, lex_identifier ) ;
614
	}
615
	COPY_hashid ( id_name ( id ), nm ) ;
616
    }
617
    return ;
618
}
619
 
620
 
621
/*
622
    KEYWORD HASH TABLE ENTRIES
623
 
624
    The table hash_keyword gives the hash table entries for the keywords.
625
    These are numbered from LAST_KEYWORD to FIRST_KEYWORD.  The array
626
    should be accessed through the macro KEYWORD defined in hash.h, which
627
    includes the appropriate offset.
628
*/
629
 
630
HASHID hash_keyword [ LAST_KEYWORD - FIRST_KEYWORD + 1 ] ;
631
IDENTIFIER underlying_op = NULL_id ;
632
 
633
 
634
/*
635
    INITIALISE THE HASH TABLE
636
 
637
    This routine allocates space for the hash table and sets all its entries
638
    to NULL.  It also sets up the operator look-up table.
639
*/
640
 
641
void init_hash
642
    PROTO_Z ()
643
{
644
    int n ;
645
    unsigned long i ;
646
 
647
    /* Set up identifier hash table */
648
    hash_table = xmalloc_nof ( HASHID, HASH_SIZE ) ;
649
    for ( i = 0 ; i < HASH_SIZE ; i++ ) {
650
	hash_table [i] = NULL_hashid ;
651
    }
652
 
653
    /* Set up type hash table */
654
    hash_type_table = xmalloc_nof ( HASHID, HASH_TYPE_SIZE ) ;
655
    for ( i = 0 ; i < HASH_TYPE_SIZE ; i++ ) {
656
	hash_type_table [i] = NULL_hashid ;
657
    }
658
 
659
    /* Set up operator look-up table */
660
    hash_ops_table = xmalloc_nof ( HASHID, LAST_TOKEN + 1 ) ;
661
    for ( n = 0 ; n <= LAST_TOKEN ; n++ ) {
662
	hash_ops_table [n] = NULL_hashid ;
663
    }
664
 
665
    /* Allocate hash table entries for all symbols */
666
    for ( n = FIRST_C_SYMBOL ; n <= LAST_C_SYMBOL ; n++ ) {
667
	hash_ops_table [n] = make_op ( n ) ;
668
    }
669
    for ( n = FIRST_CPP_SYMBOL ; n <= LAST_CPP_SYMBOL ; n++ ) {
670
	hash_ops_table [n] = make_op ( n ) ;
671
    }
672
    for ( n = FIRST_EXTRA_SYMBOL ; n <= LAST_EXTRA_SYMBOL ; n++ ) {
673
	hash_ops_table [n] = make_op ( n ) ;
674
    }
675
    hash_ops_table [ lex_array_Hop ] = make_op ( lex_array_Hop ) ;
676
    hash_ops_table [ lex_cond_Hop ] = make_op ( lex_cond_Hop ) ;
677
    hash_ops_table [ lex_delete ] = make_op ( lex_delete ) ;
678
    hash_ops_table [ lex_delete_Harray ] = make_op ( lex_delete_Harray ) ;
679
    hash_ops_table [ lex_func_Hop ] = make_op ( lex_func_Hop ) ;
680
    hash_ops_table [ lex_new ] = make_op ( lex_new ) ;
681
    hash_ops_table [ lex_new_Harray ] = make_op ( lex_new_Harray ) ;
682
    hash_ops_table [ lex_alignof ] = make_op ( lex_alignof ) ;
683
    hash_ops_table [ lex_sizeof ] = make_op ( lex_sizeof ) ;
684
    hash_ops_table [ lex_typeid ] = make_op ( lex_typeid ) ;
685
    hash_ops_table [ lex_vtable ] = make_op ( lex_vtable ) ;
686
 
687
    /* Map secondary representations to primary representations */
688
    for ( n = FIRST_DIGRAPH ; n <= LAST_DIGRAPH ; n++ ) {
689
	int m = primary_form ( n ) ;
690
	hash_ops_table [n] = hash_ops_table [m] ;
691
    }
692
    for ( n = FIRST_ISO_KEYWORD ; n <= LAST_ISO_KEYWORD ; n++ ) {
693
	int m = primary_form ( n ) ;
694
	hash_ops_table [n] = hash_ops_table [m] ;
695
    }
696
 
697
    /* This is necessary for the definition of KEYWORD */
698
    ASSERT ( FIRST_KEYWORD == lex_auto ) ;
699
    return ;
700
}