X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=src%2Fcc65%2Fdatatype.c;h=282385ed7e211c34173ff7dae4609f006ea80aa3;hb=92dfde6c4e748946c5e13323bb48bf2abd72c2b3;hp=e50f56ffbd32837f30d33732a9938fa4137d4620;hpb=c18453ebcb1ecd80cdde83fb08c61534cac47e48;p=cc65 diff --git a/src/cc65/datatype.c b/src/cc65/datatype.c index e50f56ffb..282385ed7 100644 --- a/src/cc65/datatype.c +++ b/src/cc65/datatype.c @@ -6,9 +6,9 @@ /* */ /* */ /* */ -/* (C) 1998-2000 Ullrich von Bassewitz */ -/* Wacholderweg 14 */ -/* D-70597 Stuttgart */ +/* (C) 1998-2003 Ullrich von Bassewitz */ +/* Römerstrasse 52 */ +/* D-70794 Filderstadt */ /* EMail: uz@musoftware.de */ /* */ /* */ @@ -135,6 +135,18 @@ void TypeFree (type* T) +int SignExtendChar (int C) +/* Do correct sign extension of a character */ +{ + if (SignedChars && (C & 0x80) != 0) { + return C | ~0xFF; + } else { + return C & 0xFF; + } +} + + + type GetDefaultChar (void) /* Return the default char type (signed/unsigned) depending on the settings */ { @@ -230,7 +242,7 @@ void PrintType (FILE* F, const type* Type) /* Output translation of type array. */ { type T; - + unsigned long Size; /* Walk over the complete string */ while ((T = *Type++) != T_END) { @@ -239,57 +251,67 @@ void PrintType (FILE* F, const type* Type) T = PrintTypeComp (F, T, T_QUAL_CONST, "const"); T = PrintTypeComp (F, T, T_QUAL_VOLATILE, "volatile"); - /* Signedness */ - T = PrintTypeComp (F, T, T_SIGN_SIGNED, "signed"); + /* Signedness. Omit the signedness specifier for long and int */ + if ((T & T_MASK_TYPE) != T_TYPE_INT && (T & T_MASK_TYPE) != T_TYPE_LONG) { + T = PrintTypeComp (F, T, T_SIGN_SIGNED, "signed"); + } T = PrintTypeComp (F, T, T_SIGN_UNSIGNED, "unsigned"); /* Now check the real type */ switch (T & T_MASK_TYPE) { case T_TYPE_CHAR: - fprintf (F, "char\n"); + fprintf (F, "char"); break; case T_TYPE_SHORT: - fprintf (F, "short\n"); + fprintf (F, "short"); break; case T_TYPE_INT: - fprintf (F, "int\n"); + fprintf (F, "int"); break; case T_TYPE_LONG: - fprintf (F, "long\n"); + fprintf (F, "long"); break; case T_TYPE_LONGLONG: - fprintf (F, "long long\n"); + fprintf (F, "long long"); break; case T_TYPE_FLOAT: - fprintf (F, "float\n"); + fprintf (F, "float"); break; case T_TYPE_DOUBLE: - fprintf (F, "double\n"); + fprintf (F, "double"); break; case T_TYPE_VOID: - fprintf (F, "void\n"); + fprintf (F, "void"); break; case T_TYPE_STRUCT: - fprintf (F, "struct %s\n", ((SymEntry*) DecodePtr (Type))->Name); + fprintf (F, "struct %s", ((SymEntry*) DecodePtr (Type))->Name); Type += DECODE_SIZE; break; case T_TYPE_UNION: - fprintf (F, "union %s\n", ((SymEntry*) DecodePtr (Type))->Name); + fprintf (F, "union %s", ((SymEntry*) DecodePtr (Type))->Name); Type += DECODE_SIZE; break; case T_TYPE_ARRAY: - fprintf (F, "array[%lu] of ", Decode (Type)); - Type += DECODE_SIZE; - break; + /* Recursive call */ + PrintType (F, Type + DECODE_SIZE); + Size = Decode (Type); + if (Size == 0) { + fprintf (F, "[]"); + } else { + fprintf (F, "[%lu]", Size); + } + return; case T_TYPE_PTR: - fprintf (F, "pointer to "); - break; + /* Recursive call */ + PrintType (F, Type); + fprintf (F, "*"); + return; case T_TYPE_FUNC: fprintf (F, "function returning "); Type += DECODE_SIZE; break; default: - fprintf (F, "unknown type: %04X\n", T); + fprintf (F, "unknown type: %04X", T); } } @@ -297,6 +319,43 @@ void PrintType (FILE* F, const type* Type) +void PrintFuncSig (FILE* F, const char* Name, type* Type) +/* Print a function signature. */ +{ + /* Get the function descriptor */ + const FuncDesc* D = GetFuncDesc (Type); + + /* Print a comment with the function signature */ + PrintType (F, GetFuncReturn (Type)); + if (D->Flags & FD_FASTCALL) { + fprintf (F, " __fastcall__"); + } + fprintf (F, " %s (", Name); + + /* Parameters */ + if (D->Flags & FD_VOID_PARAM) { + fprintf (F, "void"); + } else { + unsigned I; + SymEntry* E = D->SymTab->SymHead; + for (I = 0; I < D->ParamCount; ++I) { + if (I > 0) { + fprintf (F, ", "); + } + if (SymIsRegVar (E)) { + fprintf (F, "register "); + } + PrintType (F, E->Type); + E = E->NextSym; + } + } + + /* End of parameter list */ + fprintf (F, ")"); +} + + + void PrintRawType (FILE* F, const type* Type) /* Print a type string in raw format (for debugging) */ { @@ -309,7 +368,7 @@ void PrintRawType (FILE* F, const type* Type) void Encode (type* Type, unsigned long Val) -/* Encode p[0] and p[1] so that neither p[0] nore p[1] is zero */ +/* Encode Val into the given type string */ { int I; for (I = 0; I < DECODE_SIZE; ++I) { @@ -366,58 +425,63 @@ void CopyEncode (const type* Source, type* Target) -type UnqualifiedType (type T) -/* Return the unqalified type */ -{ - return (T & ~T_MASK_QUAL); -} - - - unsigned SizeOf (const type* T) /* Compute size of object represented by type array. */ { SymEntry* Entry; + long ElementCount; switch (UnqualifiedType (T[0])) { case T_VOID: - Error ("Variable has unknown size"); - return 1; /* Return something that makes sense */ + return 0; /* Assume voids have size zero */ case T_SCHAR: case T_UCHAR: - return 1; + return SIZEOF_CHAR; case T_SHORT: case T_USHORT: + return SIZEOF_SHORT; + case T_INT: case T_UINT: + return SIZEOF_INT; + case T_PTR: - return 2; + case T_FUNC: /* Maybe pointer to function */ + return SIZEOF_PTR; case T_LONG: case T_ULONG: - return 4; + return SIZEOF_LONG; case T_LONGLONG: case T_ULONGLONG: - return 8; + return SIZEOF_LONGLONG; case T_ENUM: - return 2; + return SIZEOF_INT; case T_FLOAT: + return SIZEOF_FLOAT; + case T_DOUBLE: - return 4; + return SIZEOF_DOUBLE; case T_STRUCT: case T_UNION: - Entry = (SymEntry*) DecodePtr (T+1); + Entry = DecodePtr (T+1); return Entry->V.S.Size; case T_ARRAY: - return (Decode (T+ 1) * SizeOf (T + DECODE_SIZE + 1)); + ElementCount = GetElementCount (T); + if (ElementCount < 0) { + /* Array with unspecified size */ + return 0; + } else { + return ElementCount * SizeOf (T + DECODE_SIZE + 1); + } default: Internal ("Unknown type in SizeOf: %04X", *T); @@ -432,7 +496,7 @@ unsigned PSizeOf (const type* T) /* Compute size of pointer object. */ { /* We are expecting a pointer expression */ - CHECK ((*T & T_CLASS_PTR) != 0); + CHECK ((T[0] & T_MASK_CLASS) == T_CLASS_PTR); /* Skip the pointer or array token itself */ if (IsTypeArray (T)) { @@ -444,6 +508,38 @@ unsigned PSizeOf (const type* T) +unsigned CheckedSizeOf (const type* T) +/* Return the size of a data type. If the size is zero, emit an error and + * return some valid size instead (so the rest of the compiler doesn't have + * to work with invalid sizes). + */ +{ + unsigned Size = SizeOf (T); + if (Size == 0) { + Error ("Size of data type is unknown"); + Size = SIZEOF_CHAR; /* Don't return zero */ + } + return Size; +} + + + +unsigned CheckedPSizeOf (const type* T) +/* Return the size of a data type that is pointed to by a pointer. If the + * size is zero, emit an error and return some valid size instead (so the + * rest of the compiler doesn't have to work with invalid sizes). + */ +{ + unsigned Size = PSizeOf (T); + if (Size == 0) { + Error ("Size of data type is unknown"); + Size = SIZEOF_CHAR; /* Don't return zero */ + } + return Size; +} + + + unsigned TypeOf (const type* T) /* Get the code generator base type of the object */ { @@ -475,7 +571,7 @@ unsigned TypeOf (const type* T) return CF_LONG | CF_UNSIGNED; case T_FUNC: - F = (FuncDesc*) DecodePtr (T+1); + F = DecodePtr (T+1); return (F->Flags & FD_VARIADIC)? 0 : CF_FIXARGC; case T_STRUCT: @@ -497,7 +593,7 @@ type* Indirect (type* T) */ { /* We are expecting a pointer expression */ - CHECK ((*T & T_MASK_CLASS) == T_CLASS_PTR); + CHECK ((T[0] & T_MASK_CLASS) == T_CLASS_PTR); /* Skip the pointer or array token itself */ if (IsTypeArray (T)) { @@ -509,74 +605,14 @@ type* Indirect (type* T) -int IsTypeChar (const type* T) -/* Return true if this is a character type */ -{ - return (T[0] & T_MASK_TYPE) == T_TYPE_CHAR; -} - - - -int IsTypeInt (const type* T) -/* Return true if this is an int type (signed or unsigned) */ -{ - return (T[0] & T_MASK_TYPE) == T_TYPE_INT; -} - - - -int IsTypeLong (const type* T) -/* Return true if this is a long type (signed or unsigned) */ -{ - return (T[0] & T_MASK_TYPE) == T_TYPE_LONG; -} - - - -int IsTypeFloat (const type* T) -/* Return true if this is a float type */ -{ - return (T[0] & T_MASK_TYPE) == T_TYPE_FLOAT; -} - - - -int IsTypeDouble (const type* T) -/* Return true if this is a double type */ -{ - return (T[0] & T_MASK_TYPE) == T_TYPE_DOUBLE; -} - - - -int IsTypePtr (const type* T) -/* Return true if this is a pointer type */ -{ - return ((T[0] & T_MASK_TYPE) == T_TYPE_PTR); -} - - - -int IsTypeArray (const type* T) -/* Return true if this is an array type */ -{ - return ((T[0] & T_MASK_TYPE) == T_TYPE_ARRAY); -} - - - -int IsTypeVoid (const type* T) -/* Return true if this is a void type */ +type* ArrayToPtr (const type* T) +/* Convert an array to a pointer to it's first element */ { - return (T[0] & T_MASK_TYPE) == T_TYPE_VOID; -} + /* Function must only be called for an array */ + CHECK ((T[0] & T_MASK_TYPE) == T_TYPE_ARRAY); - - -int IsTypeFunc (const type* T) -/* Return true if this is a function class */ -{ - return ((T[0] & T_MASK_TYPE) == T_TYPE_FUNC); + /* Return pointer to first element */ + return PointerTo (T + DECODE_SIZE + 1); } @@ -638,71 +674,27 @@ int IsQualVolatile (const type* T) int IsFastCallFunc (const type* T) -/* Return true if this is a function type with __fastcall__ calling conventions */ +/* Return true if this is a function type or pointer to function with + * __fastcall__ calling conventions + */ { - FuncDesc* F; - CHECK (IsTypeFunc (T)); - F = (FuncDesc*) DecodePtr (T+1); + FuncDesc* F = GetFuncDesc (T); return (F->Flags & FD_FASTCALL) != 0; } int IsVariadicFunc (const type* T) -/* Return true if this is a function type with variable parameter list */ +/* Return true if this is a function type or pointer to function type with + * variable parameter list + */ { - FuncDesc* F; - CHECK (IsTypeFunc (T)); - F = (FuncDesc*) DecodePtr (T+1); + FuncDesc* F = GetFuncDesc (T); return (F->Flags & FD_VARIADIC) != 0; } -int IsTypeFuncPtr (const type* T) -/* Return true if this is a function pointer */ -{ - return ((T[0] & T_MASK_TYPE) == T_TYPE_PTR && (T[1] & T_MASK_TYPE) == T_TYPE_FUNC); -} - - - -type GetType (const type* T) -/* Get the raw type */ -{ - PRECONDITION (T[0] != T_END); - return (T[0] & T_MASK_TYPE); -} - - - -type GetClass (const type* T) -/* Get the class of a type string */ -{ - PRECONDITION (T[0] != T_END); - return (T[0] & T_MASK_CLASS); -} - - - -type GetSignedness (const type* T) -/* Get the sign of a type */ -{ - PRECONDITION (T[0] != T_END); - return (T[0] & T_MASK_SIGN); -} - - - -type GetSizeModifier (const type* T) -/* Get the size modifier of a type */ -{ - PRECONDITION (T[0] != T_END); - return (T[0] & T_MASK_SIZE); -} - - - type GetQualifier (const type* T) /* Get the qualifier from the given type string */ { @@ -720,7 +712,7 @@ type GetQualifier (const type* T) FuncDesc* GetFuncDesc (const type* T) /* Get the FuncDesc pointer from a function or pointer-to-function type */ { - if (T[0] == T_PTR) { + if (UnqualifiedType (T[0]) == T_PTR) { /* Pointer to function */ ++T; } @@ -729,9 +721,46 @@ FuncDesc* GetFuncDesc (const type* T) CHECK (T[0] == T_FUNC); /* Decode the function descriptor and return it */ - return (FuncDesc*) DecodePtr (T+1); + return DecodePtr (T+1); +} + + + +type* GetFuncReturn (type* T) +/* Return a pointer to the return type of a function or pointer-to-function type */ +{ + if (UnqualifiedType (T[0]) == T_PTR) { + /* Pointer to function */ + ++T; + } + + /* Be sure it's a function type */ + CHECK (T[0] == T_FUNC); + + /* Return a pointer to the return type */ + return T + 1 + DECODE_SIZE; + } +long GetElementCount (const type* T) +/* Get the element count of the array specified in T (which must be of + * array type). + */ +{ + CHECK (IsTypeArray (T)); + return (unsigned) Decode (T+1); +} + + + +type* GetElementType (type* T) +/* Return the element type of the given array type. */ +{ + CHECK (IsTypeArray (T)); + return T + DECODE_SIZE + 1; +} + +