1 /*****************************************************************************/
5 /* Type string handling for the cc65 C compiler */
9 /* (C) 1998-2008 Ullrich von Bassewitz */
10 /* Roemerstrasse 52 */
11 /* D-70794 Filderstadt */
12 /* EMail: uz@cc65.org */
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. */
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: */
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 */
32 /*****************************************************************************/
52 /*****************************************************************************/
54 /*****************************************************************************/
59 /* Basic data 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,
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,
91 T_SIGN_NONE = 0x000000,
92 T_SIGN_UNSIGNED = 0x000080,
93 T_SIGN_SIGNED = 0x000100,
94 T_MASK_SIGN = 0x000180,
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,
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,
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,
142 /* Type code entry */
143 typedef unsigned long TypeCode;
146 typedef struct Type Type;
148 TypeCode C; /* Code for this entry */
150 void* P; /* Arbitrary attribute pointer */
151 long L; /* Numeric attribute value */
152 unsigned long U; /* Dito, unsigned */
153 } A; /* Type attribute if necessary */
156 /* A macro that expands to a full initializer for struct Type */
157 #define TYPE(T) { (T), { 0 } }
159 /* Maximum length of a type string */
160 #define MAXTYPELEN 30
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 */
166 /* Sizes. Floating point sizes come from fp.h */
167 #define SIZEOF_CHAR 1
168 #define SIZEOF_SHORT 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())
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[];
188 /* Forward for the SymEntry struct */
193 /*****************************************************************************/
195 /*****************************************************************************/
199 unsigned TypeLen (const Type* T);
200 /* Return the length of the type string */
202 Type* TypeCpy (Type* Dest, const Type* Src);
203 /* Copy a type string */
205 Type* TypeDup (const Type* T);
206 /* Create a copy of the given type on the heap */
208 Type* TypeAlloc (unsigned Len);
209 /* Allocate memory for a type string of length Len. Len *must* include the
213 void TypeFree (Type* T);
214 /* Free a type string */
216 int SignExtendChar (int C);
217 /* Do correct sign extension of a character */
219 TypeCode GetDefaultChar (void);
220 /* Return the default char type (signed/unsigned) depending on the settings */
222 Type* GetCharArrayType (unsigned Len);
223 /* Return the type for a char array of the given length */
225 Type* GetImplicitFuncType (void);
226 /* Return a type string for an inplicitly declared function */
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.
233 void PrintType (FILE* F, const Type* T);
234 /* Output translation of type array. */
236 void PrintRawType (FILE* F, const Type* T);
237 /* Print a type string in raw format (for debugging) */
239 void PrintFuncSig (FILE* F, const char* Name, Type* T);
240 /* Print a function signature. */
242 int TypeHasAttr (const Type* T);
243 /* Return true if the given type has attribute data */
245 #if defined(HAVE_INLINE)
246 INLINE void CopyTypeAttr (const Type* Src, Type* Dest)
247 /* Copy attribute data from Src to Dest */
252 # define CopyTypeAttr(Src, Dest) ((Dest)->A = (Src)->A)
255 #if defined(HAVE_INLINE)
256 INLINE TypeCode UnqualifiedType (TypeCode T)
257 /* Return the unqalified type code */
259 return (T & ~T_MASK_QUAL);
262 # define UnqualifiedType(T) ((T) & ~T_MASK_QUAL)
265 unsigned SizeOf (const Type* T);
266 /* Compute size of object represented by type array. */
268 unsigned PSizeOf (const Type* T);
269 /* Compute size of pointer object. */
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).
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).
282 unsigned TypeOf (const Type* T);
283 /* Get the code generator base type of the object */
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.
290 Type* ArrayToPtr (const Type* T);
291 /* Convert an array to a pointer to it's first element */
293 #if defined(HAVE_INLINE)
294 INLINE TypeCode GetType (const Type* T)
295 /* Get the raw type */
297 return (T->C & T_MASK_TYPE);
300 # define GetType(T) ((T)->C & T_MASK_TYPE)
303 #if defined(HAVE_INLINE)
304 INLINE int IsTypeChar (const Type* T)
305 /* Return true if this is a character type */
307 return (GetType (T) == T_TYPE_CHAR);
310 # define IsTypeChar(T) (GetType (T) == T_TYPE_CHAR)
313 #if defined(HAVE_INLINE)
314 INLINE int IsTypeInt (const Type* T)
315 /* Return true if this is an int type (signed or unsigned) */
317 return (GetType (T) == T_TYPE_INT);
320 # define IsTypeInt(T) (GetType (T) == T_TYPE_INT)
323 #if defined(HAVE_INLINE)
324 INLINE int IsTypeLong (const Type* T)
325 /* Return true if this is a long type (signed or unsigned) */
327 return (GetType (T) == T_TYPE_LONG);
330 # define IsTypeLong(T) (GetType (T) == T_TYPE_LONG)
333 #if defined(HAVE_INLINE)
334 INLINE int IsTypeFloat (const Type* T)
335 /* Return true if this is a float type */
337 return (GetType (T) == T_TYPE_FLOAT);
340 # define IsTypeFloat(T) (GetType (T) == T_TYPE_FLOAT)
343 #if defined(HAVE_INLINE)
344 INLINE int IsTypeDouble (const Type* T)
345 /* Return true if this is a double type */
347 return (GetType (T) == T_TYPE_DOUBLE);
350 # define IsTypeDouble(T) (GetType (T) == T_TYPE_DOUBLE)
353 #if defined(HAVE_INLINE)
354 INLINE int IsTypePtr (const Type* T)
355 /* Return true if this is a pointer type */
357 return (GetType (T) == T_TYPE_PTR);
360 # define IsTypePtr(T) (GetType (T) == T_TYPE_PTR)
363 #if defined(HAVE_INLINE)
364 INLINE int IsTypeStruct (const Type* T)
365 /* Return true if this is a struct type */
367 return (GetType (T) == T_TYPE_STRUCT);
370 # define IsTypeStruct(T) (GetType (T) == T_TYPE_STRUCT)
373 #if defined(HAVE_INLINE)
374 INLINE int IsTypeUnion (const Type* T)
375 /* Return true if this is a union type */
377 return (GetType (T) == T_TYPE_UNION);
380 # define IsTypeUnion(T) (GetType (T) == T_TYPE_UNION)
383 #if defined(HAVE_INLINE)
384 INLINE int IsTypeArray (const Type* T)
385 /* Return true if this is an array type */
387 return (GetType (T) == T_TYPE_ARRAY);
390 # define IsTypeArray(T) (GetType (T) == T_TYPE_ARRAY)
393 #if defined(HAVE_INLINE)
394 INLINE int IsTypeVoid (const Type* T)
395 /* Return true if this is a void type */
397 return (GetType (T) == T_TYPE_VOID);
400 # define IsTypeVoid(T) (GetType (T) == T_TYPE_VOID)
403 #if defined(HAVE_INLINE)
404 INLINE int IsTypeFunc (const Type* T)
405 /* Return true if this is a function class */
407 return (GetType (T) == T_TYPE_FUNC);
410 # define IsTypeFunc(T) (GetType (T) == T_TYPE_FUNC)
413 #if defined(HAVE_INLINE)
414 INLINE int IsTypeFuncPtr (const Type* T)
415 /* Return true if this is a function pointer */
417 return (IsTypePtr (T) && IsTypeFunc (T+1));
420 # define IsTypeFuncPtr(T) (IsTypePtr (T) && IsTypeFunc (T+1))
423 #if defined(HAVE_INLINE)
424 INLINE TypeCode GetClass (const Type* T)
425 /* Get the class of a type string */
427 return (T->C & T_MASK_CLASS);
430 # define GetClass(T) ((T)->C & T_MASK_CLASS)
433 #if defined(HAVE_INLINE)
434 INLINE int IsClassInt (const Type* T)
435 /* Return true if this is an integer type */
437 return (GetClass (T) == T_CLASS_INT);
440 # define IsClassInt(T) (GetClass (T) == T_CLASS_INT)
443 #if defined(HAVE_INLINE)
444 INLINE int IsClassFloat (const Type* T)
445 /* Return true if this is a float type */
447 return (GetClass (T) == T_CLASS_FLOAT);
450 # define IsClassFloat(T) (GetClass (T) == T_CLASS_FLOAT)
453 #if defined(HAVE_INLINE)
454 INLINE int IsClassPtr (const Type* T)
455 /* Return true if this is a pointer type */
457 return (GetClass (T) == T_CLASS_PTR);
460 # define IsClassPtr(T) (GetClass (T) == T_CLASS_PTR)
463 #if defined(HAVE_INLINE)
464 INLINE int IsClassStruct (const Type* T)
465 /* Return true if this is a struct type */
467 return (GetClass (T) == T_CLASS_STRUCT);
470 # define IsClassStruct(T) (GetClass (T) == T_CLASS_STRUCT)
473 #if defined(HAVE_INLINE)
474 INLINE int IsClassFunc (const Type* T)
475 /* Return true if this is a function type */
477 return (GetClass (T) == T_CLASS_FUNC);
480 # define IsClassFunc(T) (GetClass (T) == T_CLASS_FUNC)
483 #if defined(HAVE_INLINE)
484 INLINE TypeCode GetSignedness (const Type* T)
485 /* Get the sign of a type */
487 return (T->C & T_MASK_SIGN);
490 # define GetSignedness(T) ((T)->C & T_MASK_SIGN)
493 #if defined(HAVE_INLINE)
494 INLINE int IsSignUnsigned (const Type* T)
495 /* Return true if this is an unsigned type */
497 return (GetSignedness (T) == T_SIGN_UNSIGNED);
500 # define IsSignUnsigned(T) (GetSignedness (T) == T_SIGN_UNSIGNED)
503 #if defined(HAVE_INLINE)
504 INLINE int IsSignSigned (const Type* T)
505 /* Return true if this is a signed type */
507 return (GetSignedness (T) == T_SIGN_SIGNED);
510 # define IsSignSigned(T) (GetSignedness (T) == T_SIGN_SIGNED)
513 #if defined(HAVE_INLINE)
514 INLINE TypeCode GetQualifier (const Type* T)
515 /* Get the qualifier from the given type string */
517 return (T->C & T_MASK_QUAL);
520 # define GetQualifier(T) ((T)->C & T_MASK_QUAL)
523 #if defined(HAVE_INLINE)
524 INLINE int IsQualConst (const Type* T)
525 /* Return true if the given type has a const memory image */
527 return (T->C & T_QUAL_CONST) != 0;
530 # define IsQualConst(T) ((T->C & T_QUAL_CONST) != 0)
533 #if defined(HAVE_INLINE)
534 INLINE int IsQualVolatile (const Type* T)
535 /* Return true if the given type has a volatile type qualifier */
537 return (T->C & T_QUAL_VOLATILE) != 0;
540 # define IsQualVolatile(T) (T->C & T_QUAL_VOLATILE) != 0)
543 #if defined(HAVE_INLINE)
544 INLINE int IsQualRestrict (const Type* T)
545 /* Return true if the given type has a restrict qualifier */
547 return (T->C & T_QUAL_RESTRICT) != 0;
550 # define IsQualRestrict(T) (T->C & T_QUAL_RESTRICT) != 0)
553 #if defined(HAVE_INLINE)
554 INLINE int IsQualNear (const Type* T)
555 /* Return true if the given type has a near qualifier */
557 return (T->C & T_QUAL_NEAR) != 0;
560 # define IsQualNear(T) (T->C & T_QUAL_NEAR) != 0)
563 #if defined(HAVE_INLINE)
564 INLINE int IsQualFar (const Type* T)
565 /* Return true if the given type has a far qualifier */
567 return (T->C & T_QUAL_FAR) != 0;
570 # define IsQualFar(T) (T->C & T_QUAL_FAR) != 0)
573 #if defined(HAVE_INLINE)
574 INLINE int IsQualFastcall (const Type* T)
575 /* Return true if the given type has a fastcall qualifier */
577 return (T->C & T_QUAL_FASTCALL) != 0;
580 # define IsQualFastcall(T) (T->C & T_QUAL_FASTCALL) != 0)
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
588 #if defined(HAVE_INLINE)
589 INLINE TypeCode GetSizeModifier (const Type* T)
590 /* Get the size modifier of a type */
592 return (T->C & T_MASK_SIZE);
595 # define GetSizeModifier(T) ((T)->C & T_MASK_SIZE)
598 FuncDesc* GetFuncDesc (const Type* T) attribute ((const));
599 /* Get the FuncDesc pointer from a function or pointer-to-function type */
601 void SetFuncDesc (Type* T, FuncDesc* F);
602 /* Set the FuncDesc pointer in a function or pointer-to-function type */
604 Type* GetFuncReturn (Type* T) attribute ((const));
605 /* Return a pointer to the return type of a function or pointer-to-function type */
607 long GetElementCount (const Type* T);
608 /* Get the element count of the array specified in T (which must be of
612 void SetElementCount (Type* T, long Count);
613 /* Set the element count of the array specified in T (which must be of
617 Type* GetElementType (Type* T);
618 /* Return the element type of the given array type. */
620 struct SymEntry* GetSymEntry (const Type* T) attribute ((const));
621 /* Return a SymEntry pointer from a type */
623 void SetSymEntry (Type* T, struct SymEntry* S);
624 /* Set the SymEntry pointer for a type */
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.
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
637 TypeCode CodeAddrSizeQualifier (void);
638 /* Return T_QUAL_NEAR or T_QUAL_FAR depending on the code address size */
640 TypeCode DataAddrSizeQualifier (void);
641 /* Return T_QUAL_NEAR or T_QUAL_FAR depending on the data address size */
645 /* End of datatype.h */