]> git.sur5r.net Git - cc65/blob - src/cc65/datatype.h
Moved the fascall and near/far flags from the function desriptor into the
[cc65] / src / cc65 / datatype.h
1 /*****************************************************************************/
2 /*                                                                           */
3 /*                                datatype.h                                 */
4 /*                                                                           */
5 /*               Type string handling for the cc65 C compiler                */
6 /*                                                                           */
7 /*                                                                           */
8 /*                                                                           */
9 /* (C) 1998-2008 Ullrich von Bassewitz                                       */
10 /*               Roemerstrasse 52                                            */
11 /*               D-70794 Filderstadt                                         */
12 /* EMail:        uz@cc65.org                                                 */
13 /*                                                                           */
14 /*                                                                           */
15 /* This software is provided 'as-is', without any expressed or implied       */
16 /* warranty.  In no event will the authors be held liable for any damages    */
17 /* arising from the use of this software.                                    */
18 /*                                                                           */
19 /* Permission is granted to anyone to use this software for any purpose,     */
20 /* including commercial applications, and to alter it and redistribute it    */
21 /* freely, subject to the following restrictions:                            */
22 /*                                                                           */
23 /* 1. The origin of this software must not be misrepresented; you must not   */
24 /*    claim that you wrote the original software. If you use this software   */
25 /*    in a product, an acknowledgment in the product documentation would be  */
26 /*    appreciated but is not required.                                       */
27 /* 2. Altered source versions must be plainly marked as such, and must not   */
28 /*    be misrepresented as being the original software.                      */
29 /* 3. This notice may not be removed or altered from any source              */
30 /*    distribution.                                                          */
31 /*                                                                           */
32 /*****************************************************************************/
33
34
35
36 #ifndef DATATYPE_H
37 #define DATATYPE_H
38
39
40
41 #include <stdio.h>
42
43 /* common */
44 #include "attrib.h"
45 #include "inline.h"
46
47 /* cc65 */
48 #include "funcdesc.h"
49
50
51
52 /*****************************************************************************/
53 /*                                   Data                                    */
54 /*****************************************************************************/
55
56
57
58
59 /* Basic data types */
60 enum {
61     T_END           = 0x000000,
62
63     /* Basic types */
64     T_TYPE_NONE     = 0x000000,
65     T_TYPE_CHAR     = 0x000001,
66     T_TYPE_SHORT    = 0x000002,
67     T_TYPE_INT      = 0x000003,
68     T_TYPE_LONG     = 0x000004,
69     T_TYPE_LONGLONG = 0x000005,
70     T_TYPE_ENUM     = 0x000006,
71     T_TYPE_FLOAT    = 0x000007,
72     T_TYPE_DOUBLE   = 0x000008,
73     T_TYPE_VOID     = 0x000009,
74     T_TYPE_STRUCT   = 0x00000A,
75     T_TYPE_UNION    = 0x00000B,
76     T_TYPE_ARRAY    = 0x00000C,
77     T_TYPE_PTR      = 0x00000D,
78     T_TYPE_FUNC     = 0x00000E,
79     T_MASK_TYPE     = 0x00000F,
80
81     /* Type classes */
82     T_CLASS_NONE    = 0x000000,
83     T_CLASS_INT     = 0x000010,
84     T_CLASS_FLOAT   = 0x000020,
85     T_CLASS_PTR     = 0x000030,
86     T_CLASS_STRUCT  = 0x000040,
87     T_CLASS_FUNC    = 0x000050,
88     T_MASK_CLASS    = 0x000070,
89
90     /* Type signedness */
91     T_SIGN_NONE     = 0x000000,
92     T_SIGN_UNSIGNED = 0x000080,
93     T_SIGN_SIGNED   = 0x000100,
94     T_MASK_SIGN     = 0x000180,
95
96     /* Type size modifiers */
97     T_SIZE_NONE     = 0x000000,
98     T_SIZE_SHORT    = 0x000200,
99     T_SIZE_LONG     = 0x000400,
100     T_SIZE_LONGLONG = 0x000600,
101     T_MASK_SIZE     = 0x000600,
102
103     /* Type qualifiers */
104     T_QUAL_NONE     = 0x000000,
105     T_QUAL_CONST    = 0x000800,
106     T_QUAL_VOLATILE = 0x001000,
107     T_QUAL_RESTRICT = 0x002000,
108     T_QUAL_NEAR     = 0x004000,
109     T_QUAL_FAR      = 0x008000,
110     T_QUAL_ADDRSIZE = T_QUAL_NEAR | T_QUAL_FAR,
111     T_QUAL_FASTCALL = 0x010000,
112     T_MASK_QUAL     = 0x01F800,
113
114     /* Types */
115     T_CHAR      = T_TYPE_CHAR     | T_CLASS_INT    | T_SIGN_UNSIGNED | T_SIZE_NONE,
116     T_SCHAR     = T_TYPE_CHAR     | T_CLASS_INT    | T_SIGN_SIGNED   | T_SIZE_NONE,
117     T_UCHAR     = T_TYPE_CHAR     | T_CLASS_INT    | T_SIGN_UNSIGNED | T_SIZE_NONE,
118     T_SHORT     = T_TYPE_SHORT    | T_CLASS_INT    | T_SIGN_SIGNED   | T_SIZE_SHORT,
119     T_USHORT    = T_TYPE_SHORT    | T_CLASS_INT    | T_SIGN_UNSIGNED | T_SIZE_SHORT,
120     T_INT       = T_TYPE_INT      | T_CLASS_INT    | T_SIGN_SIGNED   | T_SIZE_NONE,
121     T_UINT      = T_TYPE_INT      | T_CLASS_INT    | T_SIGN_UNSIGNED | T_SIZE_NONE,
122     T_LONG      = T_TYPE_LONG     | T_CLASS_INT    | T_SIGN_SIGNED   | T_SIZE_LONG,
123     T_ULONG     = T_TYPE_LONG     | T_CLASS_INT    | T_SIGN_UNSIGNED | T_SIZE_LONG,
124     T_LONGLONG  = T_TYPE_LONGLONG | T_CLASS_INT    | T_SIGN_SIGNED   | T_SIZE_LONGLONG,
125     T_ULONGLONG = T_TYPE_LONGLONG | T_CLASS_INT    | T_SIGN_UNSIGNED | T_SIZE_LONGLONG,
126     T_ENUM      = T_TYPE_ENUM     | T_CLASS_INT    | T_SIGN_SIGNED   | T_SIZE_NONE,
127     T_FLOAT     = T_TYPE_FLOAT    | T_CLASS_FLOAT  | T_SIGN_NONE     | T_SIZE_NONE,
128     T_DOUBLE    = T_TYPE_DOUBLE   | T_CLASS_FLOAT  | T_SIGN_NONE     | T_SIZE_NONE,
129     T_VOID      = T_TYPE_VOID     | T_CLASS_NONE   | T_SIGN_NONE     | T_SIZE_NONE,
130     T_STRUCT    = T_TYPE_STRUCT   | T_CLASS_STRUCT | T_SIGN_NONE     | T_SIZE_NONE,
131     T_UNION     = T_TYPE_UNION    | T_CLASS_STRUCT | T_SIGN_NONE     | T_SIZE_NONE,
132     T_ARRAY     = T_TYPE_ARRAY    | T_CLASS_PTR    | T_SIGN_NONE     | T_SIZE_NONE,
133     T_PTR       = T_TYPE_PTR      | T_CLASS_PTR    | T_SIGN_NONE     | T_SIZE_NONE,
134     T_FUNC      = T_TYPE_FUNC     | T_CLASS_FUNC   | T_SIGN_NONE     | T_SIZE_NONE,
135
136     /* Aliases */
137     T_SIZE_T    = T_UINT,
138 };
139
140
141
142 /* Type code entry */
143 typedef unsigned long TypeCode;
144
145 /* Type entry */
146 typedef struct Type Type;
147 struct Type {
148     TypeCode            C;      /* Code for this entry */
149     union {
150         void*           P;      /* Arbitrary attribute pointer */
151         long            L;      /* Numeric attribute value */
152         unsigned long   U;      /* Dito, unsigned */
153     } A;                        /* Type attribute if necessary */
154 };
155
156 /* A macro that expands to a full initializer for struct Type */
157 #define TYPE(T)         { (T), { 0 } }
158
159 /* Maximum length of a type string */
160 #define MAXTYPELEN      30
161
162 /* Special encodings for element counts of an array */
163 #define UNSPECIFIED     -1L     /* Element count was not specified */
164 #define FLEXIBLE        0L      /* Flexible array struct member */
165
166 /* Sizes. Floating point sizes come from fp.h */
167 #define SIZEOF_CHAR     1
168 #define SIZEOF_SHORT    2
169 #define SIZEOF_INT      2
170 #define SIZEOF_LONG     4
171 #define SIZEOF_LONGLONG 8
172 #define SIZEOF_FLOAT    (FP_F_Size())
173 #define SIZEOF_DOUBLE   (FP_D_Size())
174 #define SIZEOF_PTR      2
175
176 /* Predefined type strings */
177 extern Type type_schar[];
178 extern Type type_uchar[];
179 extern Type type_int[];
180 extern Type type_uint[];
181 extern Type type_long[];
182 extern Type type_ulong[];
183 extern Type type_void[];
184 extern Type type_size_t[];
185 extern Type type_float[];
186 extern Type type_double[];
187
188 /* Forward for the SymEntry struct */
189 struct SymEntry;
190
191
192
193 /*****************************************************************************/
194 /*                                   Code                                    */
195 /*****************************************************************************/
196
197
198
199 unsigned TypeLen (const Type* T);
200 /* Return the length of the type string */
201
202 Type* TypeCpy (Type* Dest, const Type* Src);
203 /* Copy a type string */
204
205 Type* TypeDup (const Type* T);
206 /* Create a copy of the given type on the heap */
207
208 Type* TypeAlloc (unsigned Len);
209 /* Allocate memory for a type string of length Len. Len *must* include the
210  * trailing T_END.
211  */
212
213 void TypeFree (Type* T);
214 /* Free a type string */
215
216 int SignExtendChar (int C);
217 /* Do correct sign extension of a character */
218
219 TypeCode GetDefaultChar (void);
220 /* Return the default char type (signed/unsigned) depending on the settings */
221
222 Type* GetCharArrayType (unsigned Len);
223 /* Return the type for a char array of the given length */
224
225 Type* GetImplicitFuncType (void);
226 /* Return a type string for an inplicitly declared function */
227
228 Type* PointerTo (const Type* T);
229 /* Return a type string that is "pointer to T". The type string is allocated
230  * on the heap and may be freed after use.
231  */
232
233 void PrintType (FILE* F, const Type* T);
234 /* Output translation of type array. */
235
236 void PrintRawType (FILE* F, const Type* T);
237 /* Print a type string in raw format (for debugging) */
238
239 void PrintFuncSig (FILE* F, const char* Name, Type* T);
240 /* Print a function signature. */
241
242 int TypeHasAttr (const Type* T);
243 /* Return true if the given type has attribute data */
244
245 #if defined(HAVE_INLINE)
246 INLINE void CopyTypeAttr (const Type* Src, Type* Dest)
247 /* Copy attribute data from Src to Dest */
248 {
249     Dest->A = Src->A;
250 }
251 #else
252 #  define CopyTypeAttr(Src, Dest)       ((Dest)->A = (Src)->A)
253 #endif
254
255 #if defined(HAVE_INLINE)
256 INLINE TypeCode UnqualifiedType (TypeCode T)
257 /* Return the unqalified type code */
258 {
259     return (T & ~T_MASK_QUAL);
260 }
261 #else
262 #  define UnqualifiedType(T)    ((T) & ~T_MASK_QUAL)
263 #endif
264
265 unsigned SizeOf (const Type* T);
266 /* Compute size of object represented by type array. */
267
268 unsigned PSizeOf (const Type* T);
269 /* Compute size of pointer object. */
270
271 unsigned CheckedSizeOf (const Type* T);
272 /* Return the size of a data type. If the size is zero, emit an error and
273  * return some valid size instead (so the rest of the compiler doesn't have
274  * to work with invalid sizes).
275  */
276 unsigned CheckedPSizeOf (const Type* T);
277 /* Return the size of a data type that is pointed to by a pointer. If the
278  * size is zero, emit an error and return some valid size instead (so the
279  * rest of the compiler doesn't have to work with invalid sizes).
280  */
281
282 unsigned TypeOf (const Type* T);
283 /* Get the code generator base type of the object */
284
285 Type* Indirect (Type* T);
286 /* Do one indirection for the given type, that is, return the type where the
287  * given type points to.
288  */
289
290 Type* ArrayToPtr (const Type* T);
291 /* Convert an array to a pointer to it's first element */
292
293 #if defined(HAVE_INLINE)
294 INLINE TypeCode GetType (const Type* T)
295 /* Get the raw type */
296 {
297     return (T->C & T_MASK_TYPE);
298 }
299 #else
300 #  define GetType(T)    ((T)->C & T_MASK_TYPE)
301 #endif
302
303 #if defined(HAVE_INLINE)
304 INLINE int IsTypeChar (const Type* T)
305 /* Return true if this is a character type */
306 {
307     return (GetType (T) == T_TYPE_CHAR);
308 }
309 #else
310 #  define IsTypeChar(T)         (GetType (T) == T_TYPE_CHAR)
311 #endif
312
313 #if defined(HAVE_INLINE)
314 INLINE int IsTypeInt (const Type* T)
315 /* Return true if this is an int type (signed or unsigned) */
316 {
317     return (GetType (T) == T_TYPE_INT);
318 }
319 #else
320 #  define IsTypeInt(T)          (GetType (T) == T_TYPE_INT)
321 #endif
322
323 #if defined(HAVE_INLINE)
324 INLINE int IsTypeLong (const Type* T)
325 /* Return true if this is a long type (signed or unsigned) */
326 {
327     return (GetType (T) == T_TYPE_LONG);
328 }
329 #else
330 #  define IsTypeLong(T)         (GetType (T) == T_TYPE_LONG)
331 #endif
332
333 #if defined(HAVE_INLINE)
334 INLINE int IsTypeFloat (const Type* T)
335 /* Return true if this is a float type */
336 {
337     return (GetType (T) == T_TYPE_FLOAT);
338 }
339 #else
340 #  define IsTypeFloat(T)        (GetType (T) == T_TYPE_FLOAT)
341 #endif
342
343 #if defined(HAVE_INLINE)
344 INLINE int IsTypeDouble (const Type* T)
345 /* Return true if this is a double type */
346 {
347     return (GetType (T) == T_TYPE_DOUBLE);
348 }
349 #else
350 #  define IsTypeDouble(T)       (GetType (T) == T_TYPE_DOUBLE)
351 #endif
352
353 #if defined(HAVE_INLINE)
354 INLINE int IsTypePtr (const Type* T)
355 /* Return true if this is a pointer type */
356 {
357     return (GetType (T) == T_TYPE_PTR);
358 }
359 #else
360 #  define IsTypePtr(T)          (GetType (T) == T_TYPE_PTR)
361 #endif
362
363 #if defined(HAVE_INLINE)
364 INLINE int IsTypeStruct (const Type* T)
365 /* Return true if this is a struct type */
366 {
367     return (GetType (T) == T_TYPE_STRUCT);
368 }
369 #else
370 #  define IsTypeStruct(T)       (GetType (T) == T_TYPE_STRUCT)
371 #endif
372
373 #if defined(HAVE_INLINE)
374 INLINE int IsTypeUnion (const Type* T)
375 /* Return true if this is a union type */
376 {
377     return (GetType (T) == T_TYPE_UNION);
378 }
379 #else
380 #  define IsTypeUnion(T)       (GetType (T) == T_TYPE_UNION)
381 #endif
382
383 #if defined(HAVE_INLINE)
384 INLINE int IsTypeArray (const Type* T)
385 /* Return true if this is an array type */
386 {
387     return (GetType (T) == T_TYPE_ARRAY);
388 }
389 #else
390 #  define IsTypeArray(T)        (GetType (T) == T_TYPE_ARRAY)
391 #endif
392
393 #if defined(HAVE_INLINE)
394 INLINE int IsTypeVoid (const Type* T)
395 /* Return true if this is a void type */
396 {
397     return (GetType (T) == T_TYPE_VOID);
398 }
399 #else
400 #  define IsTypeVoid(T)         (GetType (T) == T_TYPE_VOID)
401 #endif
402
403 #if defined(HAVE_INLINE)
404 INLINE int IsTypeFunc (const Type* T)
405 /* Return true if this is a function class */
406 {
407     return (GetType (T) == T_TYPE_FUNC);
408 }
409 #else
410 #  define IsTypeFunc(T)         (GetType (T) == T_TYPE_FUNC)
411 #endif
412
413 #if defined(HAVE_INLINE)
414 INLINE int IsTypeFuncPtr (const Type* T)
415 /* Return true if this is a function pointer */
416 {
417     return (IsTypePtr (T) && IsTypeFunc (T+1));
418 }
419 #else
420 #  define IsTypeFuncPtr(T)      (IsTypePtr (T) && IsTypeFunc (T+1))
421 #endif
422
423 #if defined(HAVE_INLINE)
424 INLINE TypeCode GetClass (const Type* T)
425 /* Get the class of a type string */
426 {
427     return (T->C & T_MASK_CLASS);
428 }
429 #else
430 #  define GetClass(T)    ((T)->C & T_MASK_CLASS)
431 #endif
432
433 #if defined(HAVE_INLINE)
434 INLINE int IsClassInt (const Type* T)
435 /* Return true if this is an integer type */
436 {
437     return (GetClass (T) == T_CLASS_INT);
438 }
439 #else
440 #  define IsClassInt(T)         (GetClass (T) == T_CLASS_INT)
441 #endif
442
443 #if defined(HAVE_INLINE)
444 INLINE int IsClassFloat (const Type* T)
445 /* Return true if this is a float type */
446 {
447     return (GetClass (T) == T_CLASS_FLOAT);
448 }
449 #else
450 #  define IsClassFloat(T)       (GetClass (T) == T_CLASS_FLOAT)
451 #endif
452
453 #if defined(HAVE_INLINE)
454 INLINE int IsClassPtr (const Type* T)
455 /* Return true if this is a pointer type */
456 {
457     return (GetClass (T) == T_CLASS_PTR);
458 }
459 #else
460 #  define IsClassPtr(T)         (GetClass (T) == T_CLASS_PTR)
461 #endif
462
463 #if defined(HAVE_INLINE)
464 INLINE int IsClassStruct (const Type* T)
465 /* Return true if this is a struct type */
466 {
467     return (GetClass (T) == T_CLASS_STRUCT);
468 }
469 #else
470 #  define IsClassStruct(T)      (GetClass (T) == T_CLASS_STRUCT)
471 #endif
472
473 #if defined(HAVE_INLINE)
474 INLINE int IsClassFunc (const Type* T)
475 /* Return true if this is a function type */
476 {
477     return (GetClass (T) == T_CLASS_FUNC);
478 }
479 #else
480 #  define IsClassFunc(T)        (GetClass (T) == T_CLASS_FUNC)
481 #endif
482
483 #if defined(HAVE_INLINE)
484 INLINE TypeCode GetSignedness (const Type* T)
485 /* Get the sign of a type */
486 {
487     return (T->C & T_MASK_SIGN);
488 }
489 #else
490 #  define GetSignedness(T)      ((T)->C & T_MASK_SIGN)
491 #endif
492
493 #if defined(HAVE_INLINE)
494 INLINE int IsSignUnsigned (const Type* T)
495 /* Return true if this is an unsigned type */
496 {
497     return (GetSignedness (T) == T_SIGN_UNSIGNED);
498 }
499 #else
500 #  define IsSignUnsigned(T)     (GetSignedness (T) == T_SIGN_UNSIGNED)
501 #endif
502
503 #if defined(HAVE_INLINE)
504 INLINE int IsSignSigned (const Type* T)
505 /* Return true if this is a signed type */
506 {
507     return (GetSignedness (T) == T_SIGN_SIGNED);
508 }
509 #else
510 #  define IsSignSigned(T)       (GetSignedness (T) == T_SIGN_SIGNED)
511 #endif
512
513 #if defined(HAVE_INLINE)
514 INLINE TypeCode GetQualifier (const Type* T)
515 /* Get the qualifier from the given type string */
516 {
517     return (T->C & T_MASK_QUAL);
518 }
519 #else
520 #  define GetQualifier(T)      ((T)->C & T_MASK_QUAL)
521 #endif
522
523 #if defined(HAVE_INLINE)
524 INLINE int IsQualConst (const Type* T)
525 /* Return true if the given type has a const memory image */
526 {
527     return (T->C & T_QUAL_CONST) != 0;
528 }
529 #else
530 #  define IsQualConst(T)        ((T->C & T_QUAL_CONST) != 0)
531 #endif
532
533 #if defined(HAVE_INLINE)
534 INLINE int IsQualVolatile (const Type* T)
535 /* Return true if the given type has a volatile type qualifier */
536 {
537     return (T->C & T_QUAL_VOLATILE) != 0;
538 }
539 #else
540 #  define IsQualVolatile(T)     (T->C & T_QUAL_VOLATILE) != 0)
541 #endif
542
543 #if defined(HAVE_INLINE)
544 INLINE int IsQualRestrict (const Type* T)
545 /* Return true if the given type has a restrict qualifier */
546 {
547     return (T->C & T_QUAL_RESTRICT) != 0;
548 }
549 #else
550 #  define IsQualRestrict(T)     (T->C & T_QUAL_RESTRICT) != 0)
551 #endif
552
553 #if defined(HAVE_INLINE)
554 INLINE int IsQualNear (const Type* T)
555 /* Return true if the given type has a near qualifier */
556 {
557     return (T->C & T_QUAL_NEAR) != 0;
558 }
559 #else
560 #  define IsQualNear(T)         (T->C & T_QUAL_NEAR) != 0)
561 #endif
562
563 #if defined(HAVE_INLINE)
564 INLINE int IsQualFar (const Type* T)
565 /* Return true if the given type has a far qualifier */
566 {
567     return (T->C & T_QUAL_FAR) != 0;
568 }
569 #else
570 #  define IsQualFar(T)          (T->C & T_QUAL_FAR) != 0)
571 #endif
572
573 #if defined(HAVE_INLINE)
574 INLINE int IsQualFastcall (const Type* T)
575 /* Return true if the given type has a fastcall qualifier */
576 {
577     return (T->C & T_QUAL_FASTCALL) != 0;
578 }
579 #else
580 #  define IsQualFastcall(T)     (T->C & T_QUAL_FASTCALL) != 0)
581 #endif
582
583 int IsVariadicFunc (const Type* T) attribute ((const));
584 /* Return true if this is a function type or pointer to function type with
585  * variable parameter list
586  */
587
588 #if defined(HAVE_INLINE)
589 INLINE TypeCode GetSizeModifier (const Type* T)
590 /* Get the size modifier of a type */
591 {
592     return (T->C & T_MASK_SIZE);
593 }
594 #else
595 #  define GetSizeModifier(T)      ((T)->C & T_MASK_SIZE)
596 #endif
597
598 FuncDesc* GetFuncDesc (const Type* T) attribute ((const));
599 /* Get the FuncDesc pointer from a function or pointer-to-function type */
600
601 void SetFuncDesc (Type* T, FuncDesc* F);
602 /* Set the FuncDesc pointer in a function or pointer-to-function type */
603
604 Type* GetFuncReturn (Type* T) attribute ((const));
605 /* Return a pointer to the return type of a function or pointer-to-function type */
606
607 long GetElementCount (const Type* T);
608 /* Get the element count of the array specified in T (which must be of
609  * array type).
610  */
611
612 void SetElementCount (Type* T, long Count);
613 /* Set the element count of the array specified in T (which must be of
614  * array type).
615  */
616
617 Type* GetElementType (Type* T);
618 /* Return the element type of the given array type. */
619
620 struct SymEntry* GetSymEntry (const Type* T) attribute ((const));
621 /* Return a SymEntry pointer from a type */
622
623 void SetSymEntry (Type* T, struct SymEntry* S);
624 /* Set the SymEntry pointer for a type */
625
626 Type* IntPromotion (Type* T);
627 /* Apply the integer promotions to T and return the result. The returned type
628  * string may be T if there is no need to change it.
629  */
630
631 Type* PtrConversion (Type* T);
632 /* If the type is a function, convert it to pointer to function. If the
633  * expression is an array, convert it to pointer to first element. Otherwise
634  * return T.
635  */
636
637 TypeCode CodeAddrSizeQualifier (void);
638 /* Return T_QUAL_NEAR or T_QUAL_FAR depending on the code address size */
639
640 TypeCode DataAddrSizeQualifier (void);
641 /* Return T_QUAL_NEAR or T_QUAL_FAR depending on the data address size */
642
643
644
645 /* End of datatype.h */
646
647 #endif
648
649
650