Subversion Repositories tendra.SVN

Rev

Rev 2 | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

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