1 /*****************************************************************************/
5 /* Type string handling for the cc65 C compiler */
9 /* (C) 1998-2015, 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 /*****************************************************************************/
53 /*****************************************************************************/
55 /*****************************************************************************/
60 /* Basic data types */
65 T_TYPE_NONE = 0x000000,
66 T_TYPE_CHAR = 0x000001,
67 T_TYPE_SHORT = 0x000002,
68 T_TYPE_INT = 0x000003,
69 T_TYPE_LONG = 0x000004,
70 T_TYPE_LONGLONG = 0x000005,
71 T_TYPE_ENUM = 0x000006,
72 T_TYPE_FLOAT = 0x000007,
73 T_TYPE_DOUBLE = 0x000008,
74 T_TYPE_VOID = 0x000009,
75 T_TYPE_STRUCT = 0x00000A,
76 T_TYPE_UNION = 0x00000B,
77 T_TYPE_ARRAY = 0x00000C,
78 T_TYPE_PTR = 0x00000D,
79 T_TYPE_FUNC = 0x00000E,
80 T_MASK_TYPE = 0x00000F,
83 T_CLASS_NONE = 0x000000,
84 T_CLASS_INT = 0x000010,
85 T_CLASS_FLOAT = 0x000020,
86 T_CLASS_PTR = 0x000030,
87 T_CLASS_STRUCT = 0x000040,
88 T_CLASS_FUNC = 0x000050,
89 T_MASK_CLASS = 0x000070,
92 T_SIGN_NONE = 0x000000,
93 T_SIGN_UNSIGNED = 0x000080,
94 T_SIGN_SIGNED = 0x000100,
95 T_MASK_SIGN = 0x000180,
97 /* Type size modifiers */
98 T_SIZE_NONE = 0x000000,
99 T_SIZE_SHORT = 0x000200,
100 T_SIZE_LONG = 0x000400,
101 T_SIZE_LONGLONG = 0x000600,
102 T_MASK_SIZE = 0x000600,
104 /* Type qualifiers */
105 T_QUAL_NONE = 0x000000,
106 T_QUAL_CONST = 0x000800,
107 T_QUAL_VOLATILE = 0x001000,
108 T_QUAL_RESTRICT = 0x002000,
109 T_QUAL_NEAR = 0x004000,
110 T_QUAL_FAR = 0x008000,
111 T_QUAL_ADDRSIZE = T_QUAL_NEAR | T_QUAL_FAR,
112 T_QUAL_FASTCALL = 0x010000,
113 T_QUAL_CDECL = 0x020000,
114 T_QUAL_CCONV = T_QUAL_FASTCALL | T_QUAL_CDECL,
115 T_MASK_QUAL = 0x03F800,
118 T_CHAR = T_TYPE_CHAR | T_CLASS_INT | T_SIGN_UNSIGNED | T_SIZE_NONE,
119 T_SCHAR = T_TYPE_CHAR | T_CLASS_INT | T_SIGN_SIGNED | T_SIZE_NONE,
120 T_UCHAR = T_TYPE_CHAR | T_CLASS_INT | T_SIGN_UNSIGNED | T_SIZE_NONE,
121 T_SHORT = T_TYPE_SHORT | T_CLASS_INT | T_SIGN_SIGNED | T_SIZE_SHORT,
122 T_USHORT = T_TYPE_SHORT | T_CLASS_INT | T_SIGN_UNSIGNED | T_SIZE_SHORT,
123 T_INT = T_TYPE_INT | T_CLASS_INT | T_SIGN_SIGNED | T_SIZE_NONE,
124 T_UINT = T_TYPE_INT | T_CLASS_INT | T_SIGN_UNSIGNED | T_SIZE_NONE,
125 T_LONG = T_TYPE_LONG | T_CLASS_INT | T_SIGN_SIGNED | T_SIZE_LONG,
126 T_ULONG = T_TYPE_LONG | T_CLASS_INT | T_SIGN_UNSIGNED | T_SIZE_LONG,
127 T_LONGLONG = T_TYPE_LONGLONG | T_CLASS_INT | T_SIGN_SIGNED | T_SIZE_LONGLONG,
128 T_ULONGLONG = T_TYPE_LONGLONG | T_CLASS_INT | T_SIGN_UNSIGNED | T_SIZE_LONGLONG,
129 T_ENUM = T_TYPE_ENUM | T_CLASS_INT | T_SIGN_SIGNED | T_SIZE_NONE,
130 T_FLOAT = T_TYPE_FLOAT | T_CLASS_FLOAT | T_SIGN_NONE | T_SIZE_NONE,
131 T_DOUBLE = T_TYPE_DOUBLE | T_CLASS_FLOAT | T_SIGN_NONE | T_SIZE_NONE,
132 T_VOID = T_TYPE_VOID | T_CLASS_NONE | T_SIGN_NONE | T_SIZE_NONE,
133 T_STRUCT = T_TYPE_STRUCT | T_CLASS_STRUCT | T_SIGN_NONE | T_SIZE_NONE,
134 T_UNION = T_TYPE_UNION | T_CLASS_STRUCT | T_SIGN_NONE | T_SIZE_NONE,
135 T_ARRAY = T_TYPE_ARRAY | T_CLASS_PTR | T_SIGN_NONE | T_SIZE_NONE,
136 T_PTR = T_TYPE_PTR | T_CLASS_PTR | T_SIGN_NONE | T_SIZE_NONE,
137 T_FUNC = T_TYPE_FUNC | T_CLASS_FUNC | T_SIGN_NONE | T_SIZE_NONE,
145 /* Type code entry */
146 typedef unsigned long TypeCode;
149 typedef struct Type Type;
151 TypeCode C; /* Code for this entry */
153 void* P; /* Arbitrary attribute pointer */
154 long L; /* Numeric attribute value */
155 unsigned long U; /* Dito, unsigned */
156 } A; /* Type attribute if necessary */
159 /* A macro that expands to a full initializer for struct Type */
160 #define TYPE(T) { (T), { 0 } }
162 /* Maximum length of a type string */
163 #define MAXTYPELEN 30
165 /* Special encodings for element counts of an array */
166 #define UNSPECIFIED -1L /* Element count was not specified */
167 #define FLEXIBLE 0L /* Flexible array struct member */
169 /* Sizes. Floating point sizes come from fp.h */
170 #define SIZEOF_CHAR 1U
171 #define SIZEOF_SHORT 2U
172 #define SIZEOF_INT 2U
173 #define SIZEOF_LONG 4U
174 #define SIZEOF_LONGLONG 8U
175 #define SIZEOF_FLOAT (FP_F_Size())
176 #define SIZEOF_DOUBLE (FP_D_Size())
177 #define SIZEOF_PTR SIZEOF_INT
180 #define CHAR_BITS (8 * SIZEOF_CHAR)
181 #define SHORT_BITS (8 * SIZEOF_SHORT)
182 #define INT_BITS (8 * SIZEOF_INT)
183 #define LONG_BITS (8 * SIZEOF_LONG)
184 #define LONGLONG_BITS (8 * SIZEOF_LONGLONG)
185 #define FLOAT_BITS (8 * SIZEOF_FLOAT)
186 #define DOUBLE_BITS (8 * SIZEOF_DOUBLE)
187 #define PTR_BITS (8 * SIZEOF_PTR)
189 /* Predefined type strings */
190 extern Type type_schar[];
191 extern Type type_uchar[];
192 extern Type type_int[];
193 extern Type type_uint[];
194 extern Type type_long[];
195 extern Type type_ulong[];
196 extern Type type_void[];
197 extern Type type_size_t[];
198 extern Type type_float[];
199 extern Type type_double[];
201 /* Forward for the SymEntry struct */
206 /*****************************************************************************/
208 /*****************************************************************************/
212 unsigned TypeLen (const Type* T);
213 /* Return the length of the type string */
215 Type* TypeCopy (Type* Dest, const Type* Src);
216 /* Copy a type string */
218 Type* TypeDup (const Type* T);
219 /* Create a copy of the given type on the heap */
221 Type* TypeAlloc (unsigned Len);
222 /* Allocate memory for a type string of length Len. Len *must* include the
226 void TypeFree (Type* T);
227 /* Free a type string */
229 int SignExtendChar (int C);
230 /* Do correct sign extension of a character */
232 TypeCode GetDefaultChar (void);
233 /* Return the default char type (signed/unsigned) depending on the settings */
235 Type* GetCharArrayType (unsigned Len);
236 /* Return the type for a char array of the given length */
238 Type* GetImplicitFuncType (void);
239 /* Return a type string for an inplicitly declared function */
241 Type* PointerTo (const Type* T);
242 /* Return a type string that is "pointer to T". The type string is allocated
243 ** on the heap and may be freed after use.
246 void PrintType (FILE* F, const Type* T);
247 /* Output translation of type array. */
249 void PrintRawType (FILE* F, const Type* T);
250 /* Print a type string in raw format (for debugging) */
252 void PrintFuncSig (FILE* F, const char* Name, Type* T);
253 /* Print a function signature. */
255 int TypeHasAttr (const Type* T);
256 /* Return true if the given type has attribute data */
258 #if defined(HAVE_INLINE)
259 INLINE void CopyTypeAttr (const Type* Src, Type* Dest)
260 /* Copy attribute data from Src to Dest */
265 # define CopyTypeAttr(Src, Dest) ((Dest)->A = (Src)->A)
268 #if defined(HAVE_INLINE)
269 INLINE TypeCode UnqualifiedType (TypeCode T)
270 /* Return the unqalified type code */
272 return (T & ~T_MASK_QUAL);
275 # define UnqualifiedType(T) ((T) & ~T_MASK_QUAL)
278 unsigned SizeOf (const Type* T);
279 /* Compute size of object represented by type array. */
281 unsigned PSizeOf (const Type* T);
282 /* Compute size of pointer object. */
284 unsigned CheckedSizeOf (const Type* T);
285 /* Return the size of a data type. If the size is zero, emit an error and
286 ** return some valid size instead (so the rest of the compiler doesn't have
287 ** to work with invalid sizes).
289 unsigned CheckedPSizeOf (const Type* T);
290 /* Return the size of a data type that is pointed to by a pointer. If the
291 ** size is zero, emit an error and return some valid size instead (so the
292 ** rest of the compiler doesn't have to work with invalid sizes).
295 unsigned TypeOf (const Type* T);
296 /* Get the code generator base type of the object */
298 Type* Indirect (Type* T);
299 /* Do one indirection for the given type, that is, return the type where the
300 ** given type points to.
303 Type* ArrayToPtr (Type* T);
304 /* Convert an array to a pointer to it's first element */
306 #if defined(HAVE_INLINE)
307 INLINE TypeCode GetType (const Type* T)
308 /* Get the raw type */
310 return (T->C & T_MASK_TYPE);
313 # define GetType(T) ((T)->C & T_MASK_TYPE)
316 #if defined(HAVE_INLINE)
317 INLINE int IsTypeChar (const Type* T)
318 /* Return true if this is a character type */
320 return (GetType (T) == T_TYPE_CHAR);
323 # define IsTypeChar(T) (GetType (T) == T_TYPE_CHAR)
326 #if defined(HAVE_INLINE)
327 INLINE int IsTypeInt (const Type* T)
328 /* Return true if this is an int type (signed or unsigned) */
330 return (GetType (T) == T_TYPE_INT);
333 # define IsTypeInt(T) (GetType (T) == T_TYPE_INT)
336 #if defined(HAVE_INLINE)
337 INLINE int IsTypeLong (const Type* T)
338 /* Return true if this is a long type (signed or unsigned) */
340 return (GetType (T) == T_TYPE_LONG);
343 # define IsTypeLong(T) (GetType (T) == T_TYPE_LONG)
346 #if defined(HAVE_INLINE)
347 INLINE int IsTypeFloat (const Type* T)
348 /* Return true if this is a float type */
350 return (GetType (T) == T_TYPE_FLOAT);
353 # define IsTypeFloat(T) (GetType (T) == T_TYPE_FLOAT)
356 #if defined(HAVE_INLINE)
357 INLINE int IsTypeDouble (const Type* T)
358 /* Return true if this is a double type */
360 return (GetType (T) == T_TYPE_DOUBLE);
363 # define IsTypeDouble(T) (GetType (T) == T_TYPE_DOUBLE)
366 #if defined(HAVE_INLINE)
367 INLINE int IsTypePtr (const Type* T)
368 /* Return true if this is a pointer type */
370 return (GetType (T) == T_TYPE_PTR);
373 # define IsTypePtr(T) (GetType (T) == T_TYPE_PTR)
376 #if defined(HAVE_INLINE)
377 INLINE int IsTypeStruct (const Type* T)
378 /* Return true if this is a struct type */
380 return (GetType (T) == T_TYPE_STRUCT);
383 # define IsTypeStruct(T) (GetType (T) == T_TYPE_STRUCT)
386 #if defined(HAVE_INLINE)
387 INLINE int IsTypeUnion (const Type* T)
388 /* Return true if this is a union type */
390 return (GetType (T) == T_TYPE_UNION);
393 # define IsTypeUnion(T) (GetType (T) == T_TYPE_UNION)
396 #if defined(HAVE_INLINE)
397 INLINE int IsTypeArray (const Type* T)
398 /* Return true if this is an array type */
400 return (GetType (T) == T_TYPE_ARRAY);
403 # define IsTypeArray(T) (GetType (T) == T_TYPE_ARRAY)
406 #if defined(HAVE_INLINE)
407 INLINE int IsTypeVoid (const Type* T)
408 /* Return true if this is a void type */
410 return (GetType (T) == T_TYPE_VOID);
413 # define IsTypeVoid(T) (GetType (T) == T_TYPE_VOID)
416 #if defined(HAVE_INLINE)
417 INLINE int IsTypeFunc (const Type* T)
418 /* Return true if this is a function class */
420 return (GetType (T) == T_TYPE_FUNC);
423 # define IsTypeFunc(T) (GetType (T) == T_TYPE_FUNC)
426 #if defined(HAVE_INLINE)
427 INLINE int IsTypeFuncPtr (const Type* T)
428 /* Return true if this is a function pointer */
430 return (IsTypePtr (T) && IsTypeFunc (T+1));
433 # define IsTypeFuncPtr(T) (IsTypePtr (T) && IsTypeFunc (T+1))
436 #if defined(HAVE_INLINE)
437 INLINE TypeCode GetClass (const Type* T)
438 /* Get the class of a type string */
440 return (T->C & T_MASK_CLASS);
443 # define GetClass(T) ((T)->C & T_MASK_CLASS)
446 #if defined(HAVE_INLINE)
447 INLINE int IsClassInt (const Type* T)
448 /* Return true if this is an integer type */
450 return (GetClass (T) == T_CLASS_INT);
453 # define IsClassInt(T) (GetClass (T) == T_CLASS_INT)
456 #if defined(HAVE_INLINE)
457 INLINE int IsClassFloat (const Type* T)
458 /* Return true if this is a float type */
460 return (GetClass (T) == T_CLASS_FLOAT);
463 # define IsClassFloat(T) (GetClass (T) == T_CLASS_FLOAT)
466 #if defined(HAVE_INLINE)
467 INLINE int IsClassPtr (const Type* T)
468 /* Return true if this is a pointer type */
470 return (GetClass (T) == T_CLASS_PTR);
473 # define IsClassPtr(T) (GetClass (T) == T_CLASS_PTR)
476 #if defined(HAVE_INLINE)
477 INLINE int IsClassStruct (const Type* T)
478 /* Return true if this is a struct type */
480 return (GetClass (T) == T_CLASS_STRUCT);
483 # define IsClassStruct(T) (GetClass (T) == T_CLASS_STRUCT)
486 #if defined(HAVE_INLINE)
487 INLINE int IsClassFunc (const Type* T)
488 /* Return true if this is a function type */
490 return (GetClass (T) == T_CLASS_FUNC);
493 # define IsClassFunc(T) (GetClass (T) == T_CLASS_FUNC)
496 #if defined(HAVE_INLINE)
497 INLINE TypeCode GetSignedness (const Type* T)
498 /* Get the sign of a type */
500 return (T->C & T_MASK_SIGN);
503 # define GetSignedness(T) ((T)->C & T_MASK_SIGN)
506 #if defined(HAVE_INLINE)
507 INLINE int IsSignUnsigned (const Type* T)
508 /* Return true if this is an unsigned type */
510 return (GetSignedness (T) == T_SIGN_UNSIGNED);
513 # define IsSignUnsigned(T) (GetSignedness (T) == T_SIGN_UNSIGNED)
516 #if defined(HAVE_INLINE)
517 INLINE int IsSignSigned (const Type* T)
518 /* Return true if this is a signed type */
520 return (GetSignedness (T) == T_SIGN_SIGNED);
523 # define IsSignSigned(T) (GetSignedness (T) == T_SIGN_SIGNED)
526 #if defined(HAVE_INLINE)
527 INLINE TypeCode GetQualifier (const Type* T)
528 /* Get the qualifier from the given type string */
530 return (T->C & T_MASK_QUAL);
533 # define GetQualifier(T) ((T)->C & T_MASK_QUAL)
536 #if defined(HAVE_INLINE)
537 INLINE int IsQualConst (const Type* T)
538 /* Return true if the given type has a const memory image */
540 return (T->C & T_QUAL_CONST) != 0;
543 # define IsQualConst(T) (((T)->C & T_QUAL_CONST) != 0)
546 #if defined(HAVE_INLINE)
547 INLINE int IsQualVolatile (const Type* T)
548 /* Return true if the given type has a volatile type qualifier */
550 return (T->C & T_QUAL_VOLATILE) != 0;
553 # define IsQualVolatile(T) (((T)->C & T_QUAL_VOLATILE) != 0)
556 #if defined(HAVE_INLINE)
557 INLINE int IsQualRestrict (const Type* T)
558 /* Return true if the given type has a restrict qualifier */
560 return (T->C & T_QUAL_RESTRICT) != 0;
563 # define IsQualRestrict(T) (((T)->C & T_QUAL_RESTRICT) != 0)
566 #if defined(HAVE_INLINE)
567 INLINE int IsQualNear (const Type* T)
568 /* Return true if the given type has a near qualifier */
570 return (T->C & T_QUAL_NEAR) != 0;
573 # define IsQualNear(T) (((T)->C & T_QUAL_NEAR) != 0)
576 #if defined(HAVE_INLINE)
577 INLINE int IsQualFar (const Type* T)
578 /* Return true if the given type has a far qualifier */
580 return (T->C & T_QUAL_FAR) != 0;
583 # define IsQualFar(T) (((T)->C & T_QUAL_FAR) != 0)
586 #if defined(HAVE_INLINE)
587 INLINE int IsQualFastcall (const Type* T)
588 /* Return true if the given type has a fastcall qualifier */
590 return (T->C & T_QUAL_FASTCALL) != 0;
593 # define IsQualFastcall(T) (((T)->C & T_QUAL_FASTCALL) != 0)
596 #if defined(HAVE_INLINE)
597 INLINE int IsQualCDecl (const Type* T)
598 /* Return true if the given type has a cdecl qualifier */
600 return (T->C & T_QUAL_CDECL) != 0;
603 # define IsQualCDecl(T) (((T)->C & T_QUAL_CDECL) != 0)
606 #if defined(HAVE_INLINE)
607 INLINE int IsQualCConv (const Type* T)
608 /* Return true if the given type has a calling convention qualifier */
610 return (T->C & T_QUAL_CCONV) != 0;
613 # define IsQualCConv(T) (((T)->C & T_QUAL_CCONV) != 0)
616 int IsVariadicFunc (const Type* T) attribute ((const));
617 /* Return true if this is a function type or pointer to function type with
618 ** variable parameter list
621 #if defined(HAVE_INLINE)
622 INLINE TypeCode GetSizeModifier (const Type* T)
623 /* Get the size modifier of a type */
625 return (T->C & T_MASK_SIZE);
628 # define GetSizeModifier(T) ((T)->C & T_MASK_SIZE)
631 FuncDesc* GetFuncDesc (const Type* T) attribute ((const));
632 /* Get the FuncDesc pointer from a function or pointer-to-function type */
634 void SetFuncDesc (Type* T, FuncDesc* F);
635 /* Set the FuncDesc pointer in a function or pointer-to-function type */
637 Type* GetFuncReturn (Type* T) attribute ((const));
638 /* Return a pointer to the return type of a function or pointer-to-function type */
640 long GetElementCount (const Type* T);
641 /* Get the element count of the array specified in T (which must be of
645 void SetElementCount (Type* T, long Count);
646 /* Set the element count of the array specified in T (which must be of
650 Type* GetElementType (Type* T);
651 /* Return the element type of the given array type. */
653 Type* GetBaseElementType (Type* T);
654 /* Return the base element type of a given type. If T is not an array, this
655 ** will return. Otherwise it will return the base element type, which means
656 ** the element type that is not an array.
659 struct SymEntry* GetSymEntry (const Type* T) attribute ((const));
660 /* Return a SymEntry pointer from a type */
662 void SetSymEntry (Type* T, struct SymEntry* S);
663 /* Set the SymEntry pointer for a type */
665 Type* IntPromotion (Type* T);
666 /* Apply the integer promotions to T and return the result. The returned type
667 ** string may be T if there is no need to change it.
670 Type* PtrConversion (Type* T);
671 /* If the type is a function, convert it to pointer to function. If the
672 ** expression is an array, convert it to pointer to first element. Otherwise
676 TypeCode AddrSizeQualifier (unsigned AddrSize);
677 /* Return T_QUAL_NEAR or T_QUAL_FAR depending on the address size */
679 #if defined(HAVE_INLINE)
680 INLINE TypeCode CodeAddrSizeQualifier (void)
681 /* Return T_QUAL_NEAR or T_QUAL_FAR depending on the code address size */
683 return AddrSizeQualifier (CodeAddrSize);
686 # define CodeAddrSizeQualifier() (AddrSizeQualifier (CodeAddrSize))
689 #if defined(HAVE_INLINE)
690 INLINE TypeCode DataAddrSizeQualifier (void)
691 /* Return T_QUAL_NEAR or T_QUAL_FAR depending on the data address size */
693 return AddrSizeQualifier (DataAddrSize);
696 # define DataAddrSizeQualifier() (AddrSizeQualifier (DataAddrSize))
701 /* End of datatype.h */