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
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 "object.h"
33
#include "hash.h"
34
#include "type.h"
35
#include "utility.h"
36
 
37
 
38
/*
39
    FUNDAMENTAL TYPES
40
 
41
    These types represent the fundamental C types.
42
*/
43
 
44
#define BUILTIN( TYPE, NAME, VERS, ID )	type *TYPE
45
#include "builtin.h"
46
 
47
 
48
/*
49
    INITIALISE THE FUNDAMENTAL TYPES
50
 
51
    This routine initialises the fundamental C types.
52
*/
53
 
54
void init_types
55
    PROTO_Z ()
56
{
57
#define BUILTIN( TYPE, NAME, VERS, ID )\
58
    TYPE = make_type ( NAME, VERS, ID )
59
#include "builtin.h"
60
    return ;
61
}
62
 
63
 
64
/*
65
    FIND THE NAMESPACE FOR A TYPE IDENTIFIER
66
 
67
    This routine returns the hash table for types with identifier id.  In
68
    most cases this is types, but it can be tags.  If flds is true the
69
    corresponding field hash table is returned.
70
*/
71
 
72
static hash_table *find_namespace
73
    PROTO_N ( ( id, fld ) )
74
    PROTO_T ( int id X int fld )
75
{
76
    switch ( id ) {
77
	case TYPE_STRUCT_TAG :
78
	case TYPE_UNION_TAG :
79
	case TYPE_ENUM_TAG : {
80
	    return ( fld ? tag_fields : tags ) ;
81
	}
82
    }
83
    return ( fld ? type_fields : types ) ;
84
}
85
 
86
 
87
/*
88
    ALLOCATE A NEW TYPE
89
 
90
    This routine allocates space for a new type.
91
*/
92
 
93
static type *new_type
94
    PROTO_Z ()
95
{
96
    type *t ;
97
    alloc_variable ( t, type, 1000 ) ;
98
    t->state = 0 ;
99
    return ( t ) ;
100
}
101
 
102
 
103
/*
104
    FIND A BASIC TYPE
105
 
106
    This routine maps the combination of basic type specifiers n to a
107
    type.
108
*/
109
 
110
type *basic_type
111
    PROTO_N ( ( n ) )
112
    PROTO_T ( unsigned n )
113
{
114
    type *t ;
115
    switch ( n ) {
116
	case BTYPE_CHAR : {
117
	    t = type_char ;
118
	    break ;
119
	}
120
	case ( BTYPE_SIGNED | BTYPE_CHAR ) : {
121
	    t = type_schar ;
122
	    break ;
123
	}
124
	case ( BTYPE_UNSIGNED | BTYPE_CHAR ) : {
125
	    t = type_uchar ;
126
	    break ;
127
	}
128
	case BTYPE_SHORT :
129
	case ( BTYPE_SHORT | BTYPE_INT ) : {
130
	    t = type_short ;
131
	    break ;
132
	}
133
	case ( BTYPE_SIGNED | BTYPE_SHORT ) :
134
	case ( BTYPE_SIGNED | BTYPE_SHORT | BTYPE_INT ) : {
135
	    t = type_sshort ;
136
	    break ;
137
	}
138
	case ( BTYPE_UNSIGNED | BTYPE_SHORT ) :
139
	case ( BTYPE_UNSIGNED | BTYPE_SHORT | BTYPE_INT ) : {
140
	    t = type_ushort ;
141
	    break ;
142
	}
143
	case BTYPE_INT : {
144
	    t = type_int ;
145
	    break ;
146
	}
147
	case BTYPE_SIGNED :
148
	case ( BTYPE_SIGNED | BTYPE_INT ) : {
149
	    t = type_sint ;
150
	    break ;
151
	}
152
	case BTYPE_UNSIGNED :
153
	case ( BTYPE_UNSIGNED | BTYPE_INT ) : {
154
	    t = type_uint ;
155
	    break ;
156
	}
157
	case BTYPE_LONG :
158
	case ( BTYPE_LONG | BTYPE_INT ) : {
159
	    t = type_long ;
160
	    break ;
161
	}
162
	case ( BTYPE_SIGNED | BTYPE_LONG ) :
163
	case ( BTYPE_SIGNED | BTYPE_LONG | BTYPE_INT ) : {
164
	    t = type_slong ;
165
	    break ;
166
	}
167
	case ( BTYPE_UNSIGNED | BTYPE_LONG ) :
168
	case ( BTYPE_UNSIGNED | BTYPE_LONG | BTYPE_INT ) : {
169
	    t = type_ulong ;
170
	    break ;
171
	}
172
	case ( BTYPE_LONG | BTYPE_LLONG ) :
173
	case ( BTYPE_LONG | BTYPE_LLONG | BTYPE_INT ) : {
174
	    t = type_llong ;
175
	    break ;
176
	}
177
	case ( BTYPE_SIGNED | BTYPE_LONG | BTYPE_LLONG ) :
178
	case ( BTYPE_SIGNED | BTYPE_LONG | BTYPE_LLONG | BTYPE_INT ) : {
179
	    t = type_sllong ;
180
	    break ;
181
	}
182
	case ( BTYPE_UNSIGNED | BTYPE_LONG | BTYPE_LLONG ) :
183
	case ( BTYPE_UNSIGNED | BTYPE_LONG | BTYPE_LLONG | BTYPE_INT ) : {
184
	    t = type_ullong ;
185
	    break ;
186
	}
187
	default : {
188
	    if ( n == BTYPE_FLOAT ) {
189
		t = type_float ;
190
	    } else if ( n == BTYPE_DOUBLE ) {
191
		t = type_double ;
192
	    } else if ( n == ( BTYPE_LONG | BTYPE_DOUBLE ) ) {
193
		t = type_ldouble ;
194
	    } else if ( n == BTYPE_VOID ) {
195
		t = type_void ;
196
	    } else {
197
		error ( ERR_SERIOUS, "Invalid type specifier" ) ;
198
		t = type_int ;
199
	    }
200
	    break ;
201
	}
202
    }
203
    return ( t ) ;
204
}
205
 
206
 
207
/*
208
    FIND A SPECIAL TYPE NAME
209
 
210
    This routine returns the special type described by the string s.
211
*/
212
 
213
type *special_type
214
    PROTO_N ( ( s ) )
215
    PROTO_T ( char *s )
216
{
217
    if ( streq ( s, "bottom" ) ) return ( type_bottom ) ;
218
    if ( streq ( s, "printf" ) ) return ( type_printf ) ;
219
    if ( streq ( s, "scanf" ) ) return ( type_scanf ) ;
220
    error ( ERR_SERIOUS, "Unknown special type '%s'", s ) ;
221
    return ( type_int ) ;
222
}
223
 
224
 
225
/*
226
    MAKE A NEW TYPE
227
 
228
    This routine creates a type called nm (version vers) with identifier id.
229
*/
230
 
231
type *make_type
232
    PROTO_N ( ( nm, vers, id ) )
233
    PROTO_T ( char *nm X int vers X int id )
234
{
235
    type *t = new_type () ;
236
    object *p = make_object ( nm, OBJ_TYPE ) ;
237
    p->u.u_type = t ;
238
    t->id = id ;
239
    t->u.obj = p ;
240
    t->v.obj2 = null ;
241
    p = add_hash ( find_namespace ( id, 0 ), p, vers ) ;
242
    return ( p->u.u_type ) ;
243
}
244
 
245
 
246
/*
247
    FIND A TYPE
248
 
249
    This routine looks up a type called nm (version vers) with identifier
250
    id.  If it does not exist then it creates one, also printing an error
251
    if force is true.
252
*/
253
 
254
type *find_type
255
    PROTO_N ( ( nm, vers, id, force ) )
256
    PROTO_T ( char *nm X int vers X int id X int force )
257
{
258
    type *t ;
259
    object *p ;
260
    hash_table *h = find_namespace ( id, 0 ) ;
261
    p = search_hash ( h, nm, vers ) ;
262
    if ( p == null ) {
263
	if ( force == 0 ) return ( null ) ;
264
	error ( ERR_SERIOUS, "%s '%s' not defined", h->name, nm ) ;
265
	return ( make_type ( nm, vers, id ) ) ;
266
    }
267
    t = p->u.u_type ;
268
    if ( id != TYPE_GENERIC && id != t->id ) {
269
	char *err = "%s '%s' used inconsistently (see %s, line %d)" ;
270
	error ( ERR_SERIOUS, err, h->name, nm, p->filename, p->line_no ) ;
271
    }
272
    return ( t ) ;
273
}
274
 
275
 
276
/*
277
    CREATE A NEW COMPOUND TYPE
278
 
279
    This routine creates a compound type with identifier id and subtype t.
280
*/
281
 
282
type *make_subtype
283
    PROTO_N ( ( t, id ) )
284
    PROTO_T ( type *t X int id )
285
{
286
    type *s = new_type () ;
287
    s->id = id ;
288
    s->u.subtype = t ;
289
    s->v.obj2 = null ;
290
    return ( s ) ;
291
}
292
 
293
 
294
/*
295
    FORM A QUALIFIED TYPE
296
 
297
    This type forms a type from the incomplete type qualifier s and
298
    the type t.
299
*/
300
 
301
type *inject_type
302
    PROTO_N ( ( s, t ) )
303
    PROTO_T ( type *s X type *t )
304
{
305
    type *p = s ;
306
    if ( p == null ) return ( t ) ;
307
    if ( t ) {
308
	while ( p->u.subtype ) p = p->u.subtype ;
309
	p->u.subtype = t ;
310
    }
311
    return ( s ) ;
312
}
313
 
314
 
315
/*
316
    CONSTRUCT A FIELD
317
 
318
    This routine creates a field called nm (version vers) which is a field
319
    of the structure of union s of type t.
320
*/
321
 
322
field *make_field
323
    PROTO_N ( ( nm, vers, s, t ) )
324
    PROTO_T ( char *nm X int vers X type *s X type *t )
325
{
326
    char *n ;
327
    field *r ;
328
    object *p = make_object ( nm, OBJ_FIELD ) ;
329
    alloc_variable ( r, field, 1000 ) ;
330
    r->obj = p ;
331
    r->stype = s ;
332
    r->ftype = t ;
333
    n = strchr ( nm, '.' ) ;
334
    r->fname = ( n ? n + 1 : nm ) ;
335
    p->u.u_field = r ;
336
    p = add_hash ( find_namespace ( s->id, 1 ), p, vers ) ;
337
    return ( p->u.u_field ) ;
338
}
339
 
340
 
341
/*
342
    EXPAND A TYPE
343
 
344
    This routine expands the type t by replacing any typedefs by their
345
    definitions.
346
*/
347
 
348
type *expand_type
349
    PROTO_N ( ( t ) )
350
    PROTO_T ( type *t )
351
{
352
    while ( t && t->id == TYPE_DEFINED ) {
353
	t = t->v.next ;
354
    }
355
    return ( t ) ;
356
}
357
 
358
 
359
/*
360
    AUXILIARY TYPE CHECKING ROUTINE
361
 
362
    This routine applies various checks to the type t.
363
*/
364
 
365
static type *check_type_aux
366
    PROTO_N ( ( t, obj, c, ret ) )
367
    PROTO_T ( type *t X int obj X int c X int ret )
368
{
369
    if ( t == null ) return ( null ) ;
370
    switch ( t->id ) {
371
	case TYPE_VOID : {
372
	    if ( ( obj || c ) && !ret ) {
373
		error ( ERR_SERIOUS, "The type 'void' is incomplete" ) ;
374
	    }
375
	    break ;
376
	}
377
	case TYPE_ARRAY : {
378
	    if ( c && t->v.str [0] == 0 ) {
379
		error ( ERR_SERIOUS, "Incomplete array type" ) ;
380
	    }
381
	    if ( ret ) {
382
		error ( ERR_SERIOUS, "A function can't return an array" ) ;
383
	    }
384
	    t->u.subtype = check_type_aux ( t->u.subtype, 1, 1, 0 ) ;
385
	    break ;
386
	}
387
	case TYPE_BITFIELD : {
388
	    type *s = expand_type ( t->u.subtype ) ;
389
	    if ( s ) {
390
		switch ( s->id ) {
391
		    case TYPE_INT :
392
		    case TYPE_SIGNED :
393
		    case TYPE_UNSIGNED : {
394
			break ;
395
		    }
396
		    default : {
397
			error ( ERR_SERIOUS, "Non-integral bitfield type" ) ;
398
			break ;
399
		    }
400
		}
401
	    }
402
	    break ;
403
	}
404
	case TYPE_QUALIFIER : {
405
	    t->u.subtype = check_type_aux ( t->u.subtype, obj, c, ret ) ;
406
	    break ;
407
	}
408
	case TYPE_LIST : {
409
	    t->u.subtype = check_type_aux ( t->u.subtype, obj, c, ret ) ;
410
	    t->v.next = check_type_aux ( t->v.next, obj, c, ret ) ;
411
	    break ;
412
	}
413
	case TYPE_LVALUE : {
414
	    t->u.subtype = check_type_aux ( t->u.subtype, 1, 0, ret ) ;
415
	    break ;
416
	}
417
	case TYPE_RVALUE : {
418
	    t->u.subtype = check_type_aux ( t->u.subtype, 1, 1, ret ) ;
419
	    break ;
420
	}
421
	case TYPE_PROC : {
422
	    if ( obj ) error ( ERR_SERIOUS, "Object type expected" ) ;
423
	    t->u.subtype = check_type_aux ( t->u.subtype, 1, 1, 1 ) ;
424
	    if ( t->v.next && t->v.next->v.next == null ) {
425
		/* Check for '( void )' */
426
		type *s = t->v.next->u.subtype ;
427
		if ( s && s->id == TYPE_VOID ) break ;
428
	    }
429
	    t->v.next = check_type_aux ( t->v.next, 1, 0, 0 ) ;
430
	    break ;
431
	}
432
	case TYPE_PTR : {
433
	    t->u.subtype = check_type_aux ( t->u.subtype, 0, 0, 0 ) ;
434
	    break ;
435
	}
436
	case TYPE_DEFINED : {
437
	    t->v.next = check_type_aux ( t->v.next, obj, c, ret ) ;
438
	    break ;
439
	}
440
    }
441
    return ( t ) ;
442
}
443
 
444
 
445
/*
446
    CHECK A TYPE
447
 
448
    This routine checks that the type t is a valid type for an object of
449
    type id.  It returns an equivalent type.
450
*/
451
 
452
type *check_type
453
    PROTO_N ( ( t, id ) )
454
    PROTO_T ( type *t X int id )
455
{
456
    if ( t ) {
457
	switch ( id ) {
458
	    case OBJ_EXP :
459
	    case OBJ_EXTERN : {
460
		t = check_type_aux ( t, 1, 0, 0 ) ;
461
		break ;
462
	    }
463
	    case OBJ_CONST :
464
	    case OBJ_FIELD : {
465
		t = check_type_aux ( t, 1, 1, 0 ) ;
466
		break ;
467
	    }
468
	    case OBJ_FUNC : {
469
		if ( t->id != TYPE_PROC ) {
470
		    error ( ERR_SERIOUS, "Function type expected" ) ;
471
		}
472
		t = check_type_aux ( t, 0, 0, 0 ) ;
473
		break ;
474
	    }
475
	    case OBJ_TYPE :
476
	    case OBJ_MACRO :
477
	    case OBJ_STATEMENT : {
478
		t = check_type_aux ( t, 0, 0, 0 ) ;
479
		break ;
480
	    }
481
	}
482
    }
483
    return ( t ) ;
484
}