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 */
66 T_TYPE_SHORT = 0x0002,
69 T_TYPE_LONGLONG = 0x0005,
71 T_TYPE_FLOAT = 0x0007,
72 T_TYPE_DOUBLE = 0x0008,
74 T_TYPE_STRUCT = 0x000A,
75 T_TYPE_UNION = 0x000B,
76 T_TYPE_ARRAY = 0x000C,
82 T_CLASS_NONE = 0x0000,
84 T_CLASS_FLOAT = 0x0040,
86 T_CLASS_STRUCT = 0x0080,
87 T_CLASS_FUNC = 0x00A0,
88 T_MASK_CLASS = 0x00E0,
92 T_SIGN_UNSIGNED = 0x0100,
93 T_SIGN_SIGNED = 0x0200,
96 /* Type size modifiers */
98 T_SIZE_SHORT = 0x0400,
100 T_SIZE_LONGLONG = 0x0C00,
101 T_MASK_SIZE = 0x0C00,
103 /* Type qualifiers */
104 T_QUAL_NONE = 0x0000,
105 T_QUAL_CONST = 0x1000,
106 T_QUAL_VOLATILE = 0x2000,
107 T_QUAL_RESTRICT = 0x4000,
108 T_MASK_QUAL = 0x7000,
111 T_CHAR = T_TYPE_CHAR | T_CLASS_INT | T_SIGN_UNSIGNED | T_SIZE_NONE,
112 T_SCHAR = T_TYPE_CHAR | T_CLASS_INT | T_SIGN_SIGNED | T_SIZE_NONE,
113 T_UCHAR = T_TYPE_CHAR | T_CLASS_INT | T_SIGN_UNSIGNED | T_SIZE_NONE,
114 T_SHORT = T_TYPE_SHORT | T_CLASS_INT | T_SIGN_SIGNED | T_SIZE_SHORT,
115 T_USHORT = T_TYPE_SHORT | T_CLASS_INT | T_SIGN_UNSIGNED | T_SIZE_SHORT,
116 T_INT = T_TYPE_INT | T_CLASS_INT | T_SIGN_SIGNED | T_SIZE_NONE,
117 T_UINT = T_TYPE_INT | T_CLASS_INT | T_SIGN_UNSIGNED | T_SIZE_NONE,
118 T_LONG = T_TYPE_LONG | T_CLASS_INT | T_SIGN_SIGNED | T_SIZE_LONG,
119 T_ULONG = T_TYPE_LONG | T_CLASS_INT | T_SIGN_UNSIGNED | T_SIZE_LONG,
120 T_LONGLONG = T_TYPE_LONGLONG | T_CLASS_INT | T_SIGN_SIGNED | T_SIZE_LONGLONG,
121 T_ULONGLONG = T_TYPE_LONGLONG | T_CLASS_INT | T_SIGN_UNSIGNED | T_SIZE_LONGLONG,
122 T_ENUM = T_TYPE_ENUM | T_CLASS_INT | T_SIGN_SIGNED | T_SIZE_NONE,
123 T_FLOAT = T_TYPE_FLOAT | T_CLASS_FLOAT | T_SIGN_NONE | T_SIZE_NONE,
124 T_DOUBLE = T_TYPE_DOUBLE | T_CLASS_FLOAT | T_SIGN_NONE | T_SIZE_NONE,
125 T_VOID = T_TYPE_VOID | T_CLASS_NONE | T_SIGN_NONE | T_SIZE_NONE,
126 T_STRUCT = T_TYPE_STRUCT | T_CLASS_STRUCT | T_SIGN_NONE | T_SIZE_NONE,
127 T_UNION = T_TYPE_UNION | T_CLASS_STRUCT | T_SIGN_NONE | T_SIZE_NONE,
128 T_ARRAY = T_TYPE_ARRAY | T_CLASS_PTR | T_SIGN_NONE | T_SIZE_NONE,
129 T_PTR = T_TYPE_PTR | T_CLASS_PTR | T_SIGN_NONE | T_SIZE_NONE,
130 T_FUNC = T_TYPE_FUNC | T_CLASS_FUNC | T_SIGN_NONE | T_SIZE_NONE,
138 /* Type code entry */
139 typedef unsigned long TypeCode;
142 typedef struct Type Type;
144 TypeCode C; /* Code for this entry */
146 void* P; /* Arbitrary attribute pointer */
147 long L; /* Numeric attribute value */
148 unsigned long U; /* Dito, unsigned */
149 } A; /* Type attribute if necessary */
152 /* A macro that expands to a full initializer for struct Type */
153 #define TYPE(T) { (T), { 0 } }
155 /* Maximum length of a type string */
156 #define MAXTYPELEN 30
158 /* Special encodings for element counts of an array */
159 #define UNSPECIFIED -1L /* Element count was not specified */
160 #define FLEXIBLE 0L /* Flexible array struct member */
162 /* Sizes. Floating point sizes come from fp.h */
163 #define SIZEOF_CHAR 1
164 #define SIZEOF_SHORT 2
166 #define SIZEOF_LONG 4
167 #define SIZEOF_LONGLONG 8
168 #define SIZEOF_FLOAT (FP_F_Size())
169 #define SIZEOF_DOUBLE (FP_D_Size())
172 /* Predefined type strings */
173 extern Type type_schar[];
174 extern Type type_uchar[];
175 extern Type type_int[];
176 extern Type type_uint[];
177 extern Type type_long[];
178 extern Type type_ulong[];
179 extern Type type_void[];
180 extern Type type_size_t[];
181 extern Type type_float[];
182 extern Type type_double[];
184 /* Forward for the SymEntry struct */
189 /*****************************************************************************/
191 /*****************************************************************************/
195 unsigned TypeLen (const Type* T);
196 /* Return the length of the type string */
198 Type* TypeCpy (Type* Dest, const Type* Src);
199 /* Copy a type string */
201 Type* TypeDup (const Type* T);
202 /* Create a copy of the given type on the heap */
204 Type* TypeAlloc (unsigned Len);
205 /* Allocate memory for a type string of length Len. Len *must* include the
209 void TypeFree (Type* T);
210 /* Free a type string */
212 int SignExtendChar (int C);
213 /* Do correct sign extension of a character */
215 TypeCode GetDefaultChar (void);
216 /* Return the default char type (signed/unsigned) depending on the settings */
218 Type* GetCharArrayType (unsigned Len);
219 /* Return the type for a char array of the given length */
221 Type* GetImplicitFuncType (void);
222 /* Return a type string for an inplicitly declared function */
224 Type* PointerTo (const Type* T);
225 /* Return a type string that is "pointer to T". The type string is allocated
226 * on the heap and may be freed after use.
229 void PrintType (FILE* F, const Type* T);
230 /* Output translation of type array. */
232 void PrintRawType (FILE* F, const Type* T);
233 /* Print a type string in raw format (for debugging) */
235 void PrintFuncSig (FILE* F, const char* Name, Type* T);
236 /* Print a function signature. */
238 int TypeHasAttr (const Type* T);
239 /* Return true if the given type has attribute data */
241 #if defined(HAVE_INLINE)
242 INLINE void CopyTypeAttr (const Type* Src, Type* Dest)
243 /* Copy attribute data from Src to Dest */
248 # define CopyTypeAttr(Src, Dest) ((Dest)->A = (Src)->A)
251 #if defined(HAVE_INLINE)
252 INLINE TypeCode UnqualifiedType (TypeCode T)
253 /* Return the unqalified type code */
255 return (T & ~T_MASK_QUAL);
258 # define UnqualifiedType(T) ((T) & ~T_MASK_QUAL)
261 unsigned SizeOf (const Type* T);
262 /* Compute size of object represented by type array. */
264 unsigned PSizeOf (const Type* T);
265 /* Compute size of pointer object. */
267 unsigned CheckedSizeOf (const Type* T);
268 /* Return the size of a data type. If the size is zero, emit an error and
269 * return some valid size instead (so the rest of the compiler doesn't have
270 * to work with invalid sizes).
272 unsigned CheckedPSizeOf (const Type* T);
273 /* Return the size of a data type that is pointed to by a pointer. If the
274 * size is zero, emit an error and return some valid size instead (so the
275 * rest of the compiler doesn't have to work with invalid sizes).
278 unsigned TypeOf (const Type* T);
279 /* Get the code generator base type of the object */
281 Type* Indirect (Type* T);
282 /* Do one indirection for the given type, that is, return the type where the
283 * given type points to.
286 Type* ArrayToPtr (const Type* T);
287 /* Convert an array to a pointer to it's first element */
289 #if defined(HAVE_INLINE)
290 INLINE TypeCode GetType (const Type* T)
291 /* Get the raw type */
293 return (T->C & T_MASK_TYPE);
296 # define GetType(T) ((T)->C & T_MASK_TYPE)
299 #if defined(HAVE_INLINE)
300 INLINE int IsTypeChar (const Type* T)
301 /* Return true if this is a character type */
303 return (GetType (T) == T_TYPE_CHAR);
306 # define IsTypeChar(T) (GetType (T) == T_TYPE_CHAR)
309 #if defined(HAVE_INLINE)
310 INLINE int IsTypeInt (const Type* T)
311 /* Return true if this is an int type (signed or unsigned) */
313 return (GetType (T) == T_TYPE_INT);
316 # define IsTypeInt(T) (GetType (T) == T_TYPE_INT)
319 #if defined(HAVE_INLINE)
320 INLINE int IsTypeLong (const Type* T)
321 /* Return true if this is a long type (signed or unsigned) */
323 return (GetType (T) == T_TYPE_LONG);
326 # define IsTypeLong(T) (GetType (T) == T_TYPE_LONG)
329 #if defined(HAVE_INLINE)
330 INLINE int IsTypeFloat (const Type* T)
331 /* Return true if this is a float type */
333 return (GetType (T) == T_TYPE_FLOAT);
336 # define IsTypeFloat(T) (GetType (T) == T_TYPE_FLOAT)
339 #if defined(HAVE_INLINE)
340 INLINE int IsTypeDouble (const Type* T)
341 /* Return true if this is a double type */
343 return (GetType (T) == T_TYPE_DOUBLE);
346 # define IsTypeDouble(T) (GetType (T) == T_TYPE_DOUBLE)
349 #if defined(HAVE_INLINE)
350 INLINE int IsTypePtr (const Type* T)
351 /* Return true if this is a pointer type */
353 return (GetType (T) == T_TYPE_PTR);
356 # define IsTypePtr(T) (GetType (T) == T_TYPE_PTR)
359 #if defined(HAVE_INLINE)
360 INLINE int IsTypeStruct (const Type* T)
361 /* Return true if this is a struct type */
363 return (GetType (T) == T_TYPE_STRUCT);
366 # define IsTypeStruct(T) (GetType (T) == T_TYPE_STRUCT)
369 #if defined(HAVE_INLINE)
370 INLINE int IsTypeUnion (const Type* T)
371 /* Return true if this is a union type */
373 return (GetType (T) == T_TYPE_UNION);
376 # define IsTypeUnion(T) (GetType (T) == T_TYPE_UNION)
379 #if defined(HAVE_INLINE)
380 INLINE int IsTypeArray (const Type* T)
381 /* Return true if this is an array type */
383 return (GetType (T) == T_TYPE_ARRAY);
386 # define IsTypeArray(T) (GetType (T) == T_TYPE_ARRAY)
389 #if defined(HAVE_INLINE)
390 INLINE int IsTypeVoid (const Type* T)
391 /* Return true if this is a void type */
393 return (GetType (T) == T_TYPE_VOID);
396 # define IsTypeVoid(T) (GetType (T) == T_TYPE_VOID)
399 #if defined(HAVE_INLINE)
400 INLINE int IsTypeFunc (const Type* T)
401 /* Return true if this is a function class */
403 return (GetType (T) == T_TYPE_FUNC);
406 # define IsTypeFunc(T) (GetType (T) == T_TYPE_FUNC)
409 #if defined(HAVE_INLINE)
410 INLINE int IsTypeFuncPtr (const Type* T)
411 /* Return true if this is a function pointer */
413 return (IsTypePtr (T) && IsTypeFunc (T+1));
416 # define IsTypeFuncPtr(T) (IsTypePtr (T) && IsTypeFunc (T+1))
419 #if defined(HAVE_INLINE)
420 INLINE TypeCode GetClass (const Type* T)
421 /* Get the class of a type string */
423 return (T->C & T_MASK_CLASS);
426 # define GetClass(T) ((T)->C & T_MASK_CLASS)
429 #if defined(HAVE_INLINE)
430 INLINE int IsClassInt (const Type* T)
431 /* Return true if this is an integer type */
433 return (GetClass (T) == T_CLASS_INT);
436 # define IsClassInt(T) (GetClass (T) == T_CLASS_INT)
439 #if defined(HAVE_INLINE)
440 INLINE int IsClassFloat (const Type* T)
441 /* Return true if this is a float type */
443 return (GetClass (T) == T_CLASS_FLOAT);
446 # define IsClassFloat(T) (GetClass (T) == T_CLASS_FLOAT)
449 #if defined(HAVE_INLINE)
450 INLINE int IsClassPtr (const Type* T)
451 /* Return true if this is a pointer type */
453 return (GetClass (T) == T_CLASS_PTR);
456 # define IsClassPtr(T) (GetClass (T) == T_CLASS_PTR)
459 #if defined(HAVE_INLINE)
460 INLINE int IsClassStruct (const Type* T)
461 /* Return true if this is a struct type */
463 return (GetClass (T) == T_CLASS_STRUCT);
466 # define IsClassStruct(T) (GetClass (T) == T_CLASS_STRUCT)
469 #if defined(HAVE_INLINE)
470 INLINE int IsClassFunc (const Type* T)
471 /* Return true if this is a function type */
473 return (GetClass (T) == T_CLASS_FUNC);
476 # define IsClassFunc(T) (GetClass (T) == T_CLASS_FUNC)
479 #if defined(HAVE_INLINE)
480 INLINE TypeCode GetSignedness (const Type* T)
481 /* Get the sign of a type */
483 return (T->C & T_MASK_SIGN);
486 # define GetSignedness(T) ((T)->C & T_MASK_SIGN)
489 #if defined(HAVE_INLINE)
490 INLINE int IsSignUnsigned (const Type* T)
491 /* Return true if this is an unsigned type */
493 return (GetSignedness (T) == T_SIGN_UNSIGNED);
496 # define IsSignUnsigned(T) (GetSignedness (T) == T_SIGN_UNSIGNED)
499 #if defined(HAVE_INLINE)
500 INLINE int IsSignSigned (const Type* T)
501 /* Return true if this is a signed type */
503 return (GetSignedness (T) == T_SIGN_SIGNED);
506 # define IsSignSigned(T) (GetSignedness (T) == T_SIGN_SIGNED)
509 TypeCode GetQualifier (const Type* T) attribute ((const));
510 /* Get the qualifier from the given type string */
512 #if defined(HAVE_INLINE)
513 INLINE int IsQualConst (const Type* T)
514 /* Return true if the given type has a const memory image */
516 return (GetQualifier (T) & T_QUAL_CONST) != 0;
519 # define IsQualConst(T) ((GetQualifier (T) & T_QUAL_CONST) != 0)
522 #if defined(HAVE_INLINE)
523 INLINE int IsQualVolatile (const Type* T)
524 /* Return true if the given type has a volatile type qualifier */
526 return (GetQualifier (T) & T_QUAL_VOLATILE) != 0;
529 # define IsQualVolatile(T) ((GetQualifier (T) & T_QUAL_VOLATILE) != 0)
532 #if defined(HAVE_INLINE)
533 INLINE int IsQualRestrict (const Type* T)
534 /* Return true if the given type has a restrict qualifier */
536 return (GetQualifier (T) & T_QUAL_RESTRICT) != 0;
539 # define IsQualRestrict(T) ((GetQualifier (T) & T_QUAL_RESTRICT) != 0)
542 int IsFastCallFunc (const Type* T) attribute ((const));
543 /* Return true if this is a function type or pointer to function with
544 * __fastcall__ calling conventions
547 int IsVariadicFunc (const Type* T) attribute ((const));
548 /* Return true if this is a function type or pointer to function type with
549 * variable parameter list
552 #if defined(HAVE_INLINE)
553 INLINE TypeCode GetSizeModifier (const Type* T)
554 /* Get the size modifier of a type */
556 return (T->C & T_MASK_SIZE);
559 # define GetSizeModifier(T) ((T)->C & T_MASK_SIZE)
562 FuncDesc* GetFuncDesc (const Type* T) attribute ((const));
563 /* Get the FuncDesc pointer from a function or pointer-to-function type */
565 void SetFuncDesc (Type* T, FuncDesc* F);
566 /* Set the FuncDesc pointer in a function or pointer-to-function type */
568 Type* GetFuncReturn (Type* T) attribute ((const));
569 /* Return a pointer to the return type of a function or pointer-to-function type */
571 long GetElementCount (const Type* T);
572 /* Get the element count of the array specified in T (which must be of
576 void SetElementCount (Type* T, long Count);
577 /* Set the element count of the array specified in T (which must be of
581 Type* GetElementType (Type* T);
582 /* Return the element type of the given array type. */
584 struct SymEntry* GetSymEntry (const Type* T) attribute ((const));
585 /* Return a SymEntry pointer from a type */
587 void SetSymEntry (Type* T, struct SymEntry* S);
588 /* Set the SymEntry pointer for a type */
590 Type* IntPromotion (Type* T);
591 /* Apply the integer promotions to T and return the result. The returned type
592 * string may be T if there is no need to change it.
595 Type* PtrConversion (Type* T);
596 /* If the type is a function, convert it to pointer to function. If the
597 * expression is an array, convert it to pointer to first element. Otherwise
603 /* End of datatype.h */