]> git.sur5r.net Git - cc65/blob - src/cc65/datatype.c
ac86cfa4963b564838862a40287c8c611c799705
[cc65] / src / cc65 / datatype.c
1 /*****************************************************************************/
2 /*                                                                           */
3 /*                                datatype.c                                 */
4 /*                                                                           */
5 /*               Type string handling for the cc65 C compiler                */
6 /*                                                                           */
7 /*                                                                           */
8 /*                                                                           */
9 /* (C) 1998-2000 Ullrich von Bassewitz                                       */
10 /*               Wacholderweg 14                                             */
11 /*               D-70597 Stuttgart                                           */
12 /* EMail:        uz@musoftware.de                                            */
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 #include <string.h>
37
38 /* common */
39 #include "check.h"
40 #include "xmalloc.h"
41
42 /* cc65 */
43 #include "codegen.h"
44 #include "datatype.h"
45 #include "error.h"
46 #include "funcdesc.h"
47 #include "global.h"
48 #include "util.h"
49 #include "symtab.h"
50
51
52
53 /*****************************************************************************/
54 /*                                   Data                                    */
55 /*****************************************************************************/
56
57
58
59 /* Predefined type strings */
60 type type_uchar []      = { T_UCHAR,    T_END };
61 type type_int []        = { T_INT,      T_END };
62 type type_uint []       = { T_UINT,     T_END };
63 type type_long []       = { T_LONG,     T_END };
64 type type_ulong []      = { T_ULONG,    T_END };
65 type type_void []       = { T_VOID,     T_END };
66
67
68
69 /*****************************************************************************/
70 /*                                   Code                                    */
71 /*****************************************************************************/
72
73
74
75 unsigned TypeLen (const type* T)
76 /* Return the length of the type string */
77 {
78     const type* Start = T;
79     while (*T != T_END) {
80         ++T;
81     }
82     return T - Start;
83 }
84
85
86
87 type* TypeCpy (type* Dest, const type* Src)
88 /* Copy a type string */
89 {
90     type T;
91     type* Orig = Dest;
92     do {
93         T = *Src++;
94         *Dest++ = T;
95     } while (T);
96     return Orig;
97 }
98
99
100
101 type* TypeCat (type* Dest, const type* Src)
102 /* Append Src */
103 {
104     TypeCpy (Dest + TypeLen (Dest), Src);
105     return Dest;
106 }
107
108
109
110 type* TypeDup (const type* T)
111 /* Create a copy of the given type on the heap */
112 {
113     unsigned Len = (TypeLen (T) + 1) * sizeof (type);
114     return memcpy (xmalloc (Len), T, Len);
115 }
116
117
118
119 type* TypeAlloc (unsigned Len)
120 /* Allocate memory for a type string of length Len. Len *must* include the
121  * trailing T_END.
122  */
123 {
124     return xmalloc (Len * sizeof (type));
125 }
126
127
128
129 void TypeFree (type* T)
130 /* Free a type string */
131 {
132     xfree (T);
133 }
134
135
136
137 type GetDefaultChar (void)
138 /* Return the default char type (signed/unsigned) depending on the settings */
139 {
140     return SignedChars? T_SCHAR : T_UCHAR;
141 }
142
143
144
145 type* GetCharArrayType (unsigned Len)
146 /* Return the type for a char array of the given length */
147 {
148     /* Allocate memory for the type string */
149     type* T = TypeAlloc (1 + DECODE_SIZE + 2);
150
151     /* Fill the type string */
152     T [0]             = T_ARRAY;
153     T [DECODE_SIZE+1] = GetDefaultChar();
154     T [DECODE_SIZE+2] = T_END;
155
156     /* Encode the length in the type string */
157     Encode (T+1, Len);
158
159     /* Return the new type */
160     return T;
161 }
162
163
164
165 type* GetImplicitFuncType (void)
166 /* Return a type string for an inplicitly declared function */
167 {
168     /* Get a new function descriptor */
169     FuncDesc* F = NewFuncDesc ();
170
171     /* Allocate memory for the type string */
172     type* T = TypeAlloc (1 + DECODE_SIZE + 2);
173
174     /* Prepare the function descriptor */
175     F->Flags  = FD_IMPLICIT | FD_EMPTY | FD_ELLIPSIS;
176     F->SymTab = &EmptySymTab;
177     F->TagTab = &EmptySymTab;
178
179     /* Fill the type string */
180     T [0]             = T_FUNC;
181     T [DECODE_SIZE+1] = T_INT;
182     T [DECODE_SIZE+2] = T_END;
183
184     /* Encode the function descriptor into the type string */
185     EncodePtr (T+1, F);
186
187     /* Return the new type */
188     return T;
189 }
190
191
192
193 static type PrintTypeComp (FILE* F, type T, type Mask, const char* Name)
194 /* Check for a specific component of the type. If it is there, print the
195  * name and remove it. Return the type with the component removed.
196  */
197 {
198     if ((T & Mask) == Mask) {
199         fprintf (F, "%s ", Name);
200         T &= ~Mask;
201     }
202     return T;
203 }
204
205
206
207 void PrintType (FILE* F, const type* Type)
208 /* Output translation of type array. */
209 {
210     type T;
211
212
213     /* Walk over the complete string */
214     while ((T = *Type++) != T_END) {
215
216         /* Print any qualifiers */
217         T = PrintTypeComp (F, T, T_QUAL_CONST, "const");
218         T = PrintTypeComp (F, T, T_QUAL_VOLATILE, "volatile");
219
220         /* Signedness */
221         T = PrintTypeComp (F, T, T_SIGN_SIGNED, "signed");
222         T = PrintTypeComp (F, T, T_SIGN_UNSIGNED, "unsigned");
223
224         /* Now check the real type */
225         switch (T & T_MASK_TYPE) {
226             case T_TYPE_CHAR:
227                 fprintf (F, "char\n");
228                 break;
229             case T_TYPE_SHORT:
230                 fprintf (F, "short\n");
231                 break;
232             case T_TYPE_INT:
233                 fprintf (F, "int\n");
234                 break;
235             case T_TYPE_LONG:
236                 fprintf (F, "long\n");
237                 break;
238             case T_TYPE_LONGLONG:
239                 fprintf (F, "long long\n");
240                 break;
241             case T_TYPE_FLOAT:
242                 fprintf (F, "float\n");
243                 break;
244             case T_TYPE_DOUBLE:
245                 fprintf (F, "double\n");
246                 break;
247             case T_TYPE_VOID:
248                 fprintf (F, "void\n");
249                 break;
250             case T_TYPE_STRUCT:
251                 fprintf (F, "struct %s\n", ((SymEntry*) DecodePtr (Type))->Name);
252                 Type += DECODE_SIZE;
253                 break;
254             case T_TYPE_UNION:
255                 fprintf (F, "union %s\n", ((SymEntry*) DecodePtr (Type))->Name);
256                 Type += DECODE_SIZE;
257                 break;
258             case T_TYPE_ARRAY:
259                 fprintf (F, "array[%lu] of ", Decode (Type));
260                 Type += DECODE_SIZE;
261                 break;
262             case T_TYPE_PTR:
263                 fprintf (F, "pointer to ");
264                 break;
265             case T_TYPE_FUNC:
266                 fprintf (F, "function returning ");
267                 Type += DECODE_SIZE;
268                 break;
269             default:
270                 fprintf (F, "unknown type: %04X\n", T);
271         }
272
273     }
274 }
275
276
277
278 void PrintRawType (FILE* F, const type* Type)
279 /* Print a type string in raw format (for debugging) */
280 {
281     while (*Type != T_END) {
282         fprintf (F, "%04X ", *Type++);
283     }
284     fprintf (F, "\n");
285 }
286
287
288
289 void Encode (type* Type, unsigned long Val)
290 /* Encode p[0] and p[1] so that neither p[0] nore p[1] is zero */
291 {
292     int I;
293     for (I = 0; I < DECODE_SIZE; ++I) {
294         *Type++ = ((type) Val) | 0x8000;
295         Val >>= 15;
296     }
297 }
298
299
300
301 void EncodePtr (type* Type, void* P)
302 /* Encode a pointer into a type array */
303 {
304     Encode (Type, (unsigned long) P);
305 }
306
307
308
309 unsigned long Decode (const type* Type)
310 /* Decode */
311 {
312     int I;
313     unsigned long Val = 0;
314     for (I = DECODE_SIZE-1; I >= 0; I--) {
315         Val <<= 15;
316         Val |= (Type[I] & 0x7FFF);
317     }
318     return Val;
319 }
320
321
322
323 void* DecodePtr (const type* Type)
324 /* Decode a pointer from a type array */
325 {
326     return (void*) Decode (Type);
327 }
328
329
330
331 int HasEncode (const type* Type)
332 /* Return true if the given type has encoded data */
333 {
334     return IsClassStruct (Type) || IsTypeArray (Type) || IsTypeFunc (Type);
335 }
336
337
338
339 void CopyEncode (const type* Source, type* Target)
340 /* Copy encoded data from Source to Target */
341 {
342     memcpy (Target, Source, DECODE_SIZE * sizeof (type));
343 }
344
345
346
347 type UnqualifiedType (type T)
348 /* Return the unqalified type */
349 {
350     return (T & ~T_MASK_QUAL);
351 }
352
353
354
355 unsigned SizeOf (const type* T)
356 /* Compute size of object represented by type array. */
357 {
358     SymEntry* Entry;
359
360     switch (UnqualifiedType (T[0])) {
361
362         case T_VOID:
363             Error (ERR_ILLEGAL_SIZE);
364             return 0;
365
366         case T_SCHAR:
367         case T_UCHAR:
368             return 1;
369
370         case T_SHORT:
371         case T_USHORT:
372         case T_INT:
373         case T_UINT:
374         case T_PTR:
375             return 2;
376
377         case T_LONG:
378         case T_ULONG:
379             return 4;
380
381         case T_LONGLONG:
382         case T_ULONGLONG:
383             return 8;
384
385         case T_ENUM:
386             return 2;
387
388         case T_FLOAT:
389         case T_DOUBLE:
390             return 4;
391
392         case T_STRUCT:
393         case T_UNION:
394             Entry = DecodePtr (T+1);
395             return Entry->V.S.Size;
396
397         case T_ARRAY:
398             return (Decode (T+ 1) * SizeOf (T + DECODE_SIZE + 1));
399
400         default:
401             Internal ("Unknown type in SizeOf: %04X", *T);
402             return 0;
403
404     }
405 }
406
407
408
409 unsigned PSizeOf (const type* T)
410 /* Compute size of pointer object. */
411 {
412     /* We are expecting a pointer expression */
413     CHECK ((*T & T_CLASS_PTR) != 0);
414
415     /* Skip the pointer or array token itself */
416     if (IsTypeArray (T)) {
417         return SizeOf (T + DECODE_SIZE + 1);
418     } else {
419         return SizeOf (T + 1);
420     }
421 }
422
423
424
425 unsigned TypeOf (const type* T)
426 /* Get the code generator base type of the object */
427 {
428     FuncDesc* F;
429
430     switch (UnqualifiedType (T[0])) {
431
432         case T_SCHAR:
433             return CF_CHAR;
434
435         case T_UCHAR:
436             return CF_CHAR | CF_UNSIGNED;
437
438         case T_SHORT:
439         case T_INT:
440         case T_ENUM:
441             return CF_INT;
442
443         case T_USHORT:
444         case T_UINT:
445         case T_PTR:
446         case T_ARRAY:
447             return CF_INT | CF_UNSIGNED;
448
449         case T_LONG:
450             return CF_LONG;
451
452         case T_ULONG:
453             return CF_LONG | CF_UNSIGNED;
454
455         case T_FUNC:
456             F = DecodePtr (T+1);
457             return (F->Flags & FD_ELLIPSIS)? 0 : CF_FIXARGC;
458
459         case T_STRUCT:
460         case T_UNION:
461             /* Address of ... */
462             return CF_INT | CF_UNSIGNED;
463
464         default:
465             Error (ERR_ILLEGAL_TYPE);
466             return CF_INT;
467     }
468 }
469
470
471
472 type* Indirect (type* T)
473 /* Do one indirection for the given type, that is, return the type where the
474  * given type points to.
475  */
476 {
477     /* We are expecting a pointer expression */
478     CHECK ((*T & T_MASK_CLASS) == T_CLASS_PTR);
479
480     /* Skip the pointer or array token itself */
481     if (IsTypeArray (T)) {
482         return T + DECODE_SIZE + 1;
483     } else {
484         return T + 1;
485     }
486 }
487
488
489
490 int IsTypeChar (const type* T)
491 /* Return true if this is a character type */
492 {
493     return (T[0] & T_MASK_TYPE) == T_TYPE_CHAR;
494 }
495
496
497
498 int IsTypeInt (const type* T)
499 /* Return true if this is an int type (signed or unsigned) */
500 {
501     return (T[0] & T_MASK_TYPE) == T_TYPE_INT;
502 }
503
504
505
506 int IsTypeLong (const type* T)
507 /* Return true if this is a long type (signed or unsigned) */
508 {
509     return (T[0] & T_MASK_TYPE) == T_TYPE_LONG;
510 }
511
512
513
514 int IsTypePtr (const type* T)
515 /* Return true if this is a pointer type */
516 {
517     return ((T[0] & T_MASK_TYPE) == T_TYPE_PTR);
518 }
519
520
521
522 int IsTypeArray (const type* T)
523 /* Return true if this is an array type */
524 {
525     return ((T[0] & T_MASK_TYPE) == T_TYPE_ARRAY);
526 }
527
528
529
530 int IsTypeVoid (const type* T)
531 /* Return true if this is a void type */
532 {
533     return (T[0] & T_MASK_TYPE) == T_TYPE_VOID;
534 }
535
536
537
538 int IsTypeFunc (const type* T)
539 /* Return true if this is a function class */
540 {
541     return ((T[0] & T_MASK_TYPE) == T_TYPE_FUNC);
542 }
543
544
545
546 int IsClassInt (const type* T)
547 /* Return true if this is an integer type */
548 {
549     return (T[0] & T_MASK_CLASS) == T_CLASS_INT;
550 }
551
552
553
554 int IsClassPtr (const type* T)
555 /* Return true if this is a pointer type */
556 {
557     return (T[0] & T_MASK_CLASS) == T_CLASS_PTR;
558 }
559
560
561
562 int IsClassStruct (const type* T)
563 /* Return true if this is a struct type */
564 {
565     return (T[0] & T_MASK_CLASS) == T_CLASS_STRUCT;
566 }
567
568
569
570 int IsSignUnsigned (const type* T)
571 /* Return true if this is an unsigned type */
572 {
573     return (T[0] & T_MASK_SIGN) == T_SIGN_UNSIGNED;
574 }
575
576
577
578 int IsQualConst (const type* T)
579 /* Return true if the given type has a const memory image */
580 {
581     return (GetQualifier (T) & T_QUAL_CONST) != 0;
582 }
583
584
585
586 int IsQualVolatile (const type* T)
587 /* Return true if the given type has a volatile type qualifier */
588 {
589     return (GetQualifier (T) & T_QUAL_VOLATILE) != 0;
590 }
591
592
593
594 int IsFastCallFunc (const type* T)
595 /* Return true if this is a function type with __fastcall__ calling conventions */
596 {
597     FuncDesc* F;
598     CHECK (IsTypeFunc (T));
599     F = DecodePtr (T+1);
600     return (F->Flags & FD_FASTCALL) != 0;
601 }
602
603
604
605 int IsTypeFuncPtr (const type* T)
606 /* Return true if this is a function pointer */
607 {
608     return ((T[0] & T_MASK_TYPE) == T_TYPE_PTR && (T[1] & T_MASK_TYPE) == T_TYPE_FUNC);
609 }
610
611
612
613 type GetType (const type* T)
614 /* Get the raw type */
615 {
616     PRECONDITION (T[0] != T_END);
617     return (T[0] & T_MASK_TYPE);
618 }
619
620
621
622 type GetClass (const type* T)
623 /* Get the class of a type string */
624 {
625     PRECONDITION (T[0] != T_END);
626     return (T[0] & T_MASK_CLASS);
627 }
628
629
630
631 type GetSignedness (const type* T)
632 /* Get the sign of a type */
633 {
634     PRECONDITION (T[0] != T_END);
635     return (T[0] & T_MASK_SIGN);
636 }
637
638
639
640 type GetSizeModifier (const type* T)
641 /* Get the size modifier of a type */
642 {
643     PRECONDITION (T[0] != T_END);
644     return (T[0] & T_MASK_SIZE);
645 }
646
647
648
649 type GetQualifier (const type* T)
650 /* Get the qualifier from the given type string */
651 {
652     /* If this is an array, look at the element type, otherwise look at the
653      * type itself.
654      */
655     if (IsTypeArray (T)) {
656         T += DECODE_SIZE + 1;
657     }
658     return (T[0] & T_QUAL_CONST);
659 }
660
661
662
663 struct FuncDesc* GetFuncDesc (const type* T)
664 /* Get the FuncDesc pointer from a function or pointer-to-function type */
665 {
666     if (T[0] == T_PTR) {
667         /* Pointer to function */
668         ++T;
669     }
670
671     /* Be sure it's a function type */
672     CHECK (T[0] == T_FUNC);
673
674     /* Decode the function descriptor and return it */
675     return DecodePtr (T+1);
676 }
677
678
679
680