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