/* */
/* */
/* */
-/* (C) 2002-2004 Ullrich von Bassewitz */
+/* (C) 2002-2006 Ullrich von Bassewitz */
/* Römerstrasse 52 */
/* D-70794 Filderstadt */
/* EMail: uz@cc65.org */
/* Parse an assignment */
{
ExprDesc Expr2;
- type* ltype = Expr->Type;
+ Type* ltype = Expr->Type;
/* We must have an lvalue for an assignment */
* the former case, push the address only if really needed.
*/
int UseReg = 1;
- type* stype;
+ Type* stype;
switch (Size) {
case SIZEOF_CHAR: stype = type_uchar; break;
case SIZEOF_INT: stype = type_uint; break;
/* */
/* */
/* */
-/* (C) 2001-2005, Ullrich von Bassewitz */
+/* (C) 2001-2006, Ullrich von Bassewitz */
/* Römerstrasse 52 */
/* D-70794 Filderstadt */
/* EMail: uz@cc65.org */
/* Create a new code segment, initialize and return it */
{
unsigned I;
- const type* RetType;
+ const Type* RetType;
/* Allocate memory */
CodeSeg* S = xmalloc (sizeof (CodeSeg));
/* */
/* */
/* */
-/* (C) 1998-2004 Ullrich von Bassewitz */
+/* (C) 1998-2006 Ullrich von Bassewitz */
/* Römerstraße 52 */
/* D-70794 Filderstadt */
/* EMail: uz@cc65.org */
/* Predefined type strings */
-type type_schar[] = { T_SCHAR, T_END };
-type type_uchar[] = { T_UCHAR, T_END };
-type type_int[] = { T_INT, T_END };
-type type_uint[] = { T_UINT, T_END };
-type type_long[] = { T_LONG, T_END };
-type type_ulong[] = { T_ULONG, T_END };
-type type_void[] = { T_VOID, T_END };
-type type_size_t[] = { T_SIZE_T, T_END };
-type type_float[] = { T_FLOAT, T_END };
-type type_double[] = { T_DOUBLE, T_END };
+Type type_schar[] = { TYPE(T_SCHAR), TYPE(T_END) };
+Type type_uchar[] = { TYPE(T_UCHAR), TYPE(T_END) };
+Type type_int[] = { TYPE(T_INT), TYPE(T_END) };
+Type type_uint[] = { TYPE(T_UINT), TYPE(T_END) };
+Type type_long[] = { TYPE(T_LONG), TYPE(T_END) };
+Type type_ulong[] = { TYPE(T_ULONG), TYPE(T_END) };
+Type type_void[] = { TYPE(T_VOID), TYPE(T_END) };
+Type type_size_t[] = { TYPE(T_SIZE_T), TYPE(T_END) };
+Type type_float[] = { TYPE(T_FLOAT), TYPE(T_END) };
+Type type_double[] = { TYPE(T_DOUBLE), TYPE(T_END) };
-unsigned TypeLen (const type* T)
+unsigned TypeLen (const Type* T)
/* Return the length of the type string */
{
- const type* Start = T;
- while (*T != T_END) {
+ const Type* Start = T;
+ while (T->C != T_END) {
++T;
}
return T - Start;
-type* TypeCpy (type* Dest, const type* Src)
+Type* TypeCpy (Type* Dest, const Type* Src)
/* Copy a type string */
{
- type T;
- type* Orig = Dest;
- do {
- T = *Src++;
- *Dest++ = T;
- } while (T);
+ Type* Orig = Dest;
+ while (1) {
+ *Dest = *Src;
+ if (Src->C == T_END) {
+ break;
+ }
+ Src++;
+ Dest++;
+ }
return Orig;
}
-type* TypeCat (type* Dest, const type* Src)
-/* Append Src */
-{
- TypeCpy (Dest + TypeLen (Dest), Src);
- return Dest;
-}
-
-
-
-type* TypeDup (const type* T)
+Type* TypeDup (const Type* T)
/* Create a copy of the given type on the heap */
{
- unsigned Len = (TypeLen (T) + 1) * sizeof (type);
- return (type*) memcpy (xmalloc (Len), T, Len);
+ unsigned Len = (TypeLen (T) + 1) * sizeof (Type);
+ return memcpy (xmalloc (Len), T, Len);
}
-type* TypeAlloc (unsigned Len)
+Type* TypeAlloc (unsigned Len)
/* Allocate memory for a type string of length Len. Len *must* include the
* trailing T_END.
*/
{
- return (type*) xmalloc (Len * sizeof (type));
+ return xmalloc (Len * sizeof (Type));
}
-void TypeFree (type* T)
+void TypeFree (Type* T)
/* Free a type string */
{
xfree (T);
-type GetDefaultChar (void)
+TypeCode GetDefaultChar (void)
/* Return the default char type (signed/unsigned) depending on the settings */
{
return IS_Get (&SignedChars)? T_SCHAR : T_UCHAR;
-type* GetCharArrayType (unsigned Len)
+Type* GetCharArrayType (unsigned Len)
/* Return the type for a char array of the given length */
{
/* Allocate memory for the type string */
- type* T = TypeAlloc (1 + DECODE_SIZE + 2);
+ Type* T = TypeAlloc (3); /* array/char/terminator */
/* Fill the type string */
- T [0] = T_ARRAY;
- T [DECODE_SIZE+1] = GetDefaultChar();
- T [DECODE_SIZE+2] = T_END;
-
- /* Encode the length in the type string */
- Encode (T+1, Len);
+ T[0].C = T_ARRAY;
+ T[0].A.L = Len; /* Array length is in the L attribute */
+ T[1].C = GetDefaultChar ();
+ T[2].C = T_END;
/* Return the new type */
return T;
-type* GetImplicitFuncType (void)
+Type* GetImplicitFuncType (void)
/* Return a type string for an inplicitly declared function */
{
/* Get a new function descriptor */
FuncDesc* F = NewFuncDesc ();
/* Allocate memory for the type string */
- type* T = TypeAlloc (1 + DECODE_SIZE + 2);
+ Type* T = TypeAlloc (3); /* func/returns int/terminator */
/* Prepare the function descriptor */
F->Flags = FD_IMPLICIT | FD_EMPTY | FD_VARIADIC;
F->TagTab = &EmptySymTab;
/* Fill the type string */
- T [0] = T_FUNC;
- T [DECODE_SIZE+1] = T_INT;
- T [DECODE_SIZE+2] = T_END;
-
- /* Encode the function descriptor into the type string */
- EncodePtr (T+1, F);
+ T[0].C = T_FUNC;
+ T[0].A.P = F;
+ T[1].C = T_INT;
+ T[2].C = T_END;
/* Return the new type */
return T;
-type* PointerTo (const type* T)
+Type* PointerTo (const Type* T)
/* Return a type string that is "pointer to T". The type string is allocated
* on the heap and may be freed after use.
*/
unsigned Size = TypeLen (T) + 1;
/* Allocate the new type string */
- type* P = TypeAlloc (Size + 1);
+ Type* P = TypeAlloc (Size + 1);
/* Create the return type... */
- P[0] = T_PTR;
- memcpy (P+1, T, Size * sizeof (type));
+ P[0].C = T_PTR;
+ memcpy (P+1, T, Size * sizeof (Type));
/* ...and return it */
return P;
-static type PrintTypeComp (FILE* F, type T, type Mask, const char* Name)
+static TypeCode PrintTypeComp (FILE* F, TypeCode C, TypeCode Mask, const char* Name)
/* Check for a specific component of the type. If it is there, print the
* name and remove it. Return the type with the component removed.
*/
{
- if ((T & Mask) == Mask) {
+ if ((C & Mask) == Mask) {
fprintf (F, "%s ", Name);
- T &= ~Mask;
+ C &= ~Mask;
}
- return T;
+ return C;
}
-void PrintType (FILE* F, const type* Type)
+void PrintType (FILE* F, const Type* T)
/* Output translation of type array. */
{
- type T;
- long Size;
+ /* Walk over the type string */
+ while (T->C != T_END) {
- /* Walk over the complete string */
- while ((T = *Type++) != T_END) {
+ /* Get the type code */
+ TypeCode C = T->C;
/* Print any qualifiers */
- T = PrintTypeComp (F, T, T_QUAL_CONST, "const");
- T = PrintTypeComp (F, T, T_QUAL_VOLATILE, "volatile");
+ C = PrintTypeComp (F, C, T_QUAL_CONST, "const");
+ C = PrintTypeComp (F, C, T_QUAL_VOLATILE, "volatile");
+ C = PrintTypeComp (F, C, T_QUAL_RESTRICT, "restrict");
/* 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");
+ if ((C & T_MASK_TYPE) != T_TYPE_INT && (C & T_MASK_TYPE) != T_TYPE_LONG) {
+ C = PrintTypeComp (F, C, T_SIGN_SIGNED, "signed");
}
- T = PrintTypeComp (F, T, T_SIGN_UNSIGNED, "unsigned");
+ C = PrintTypeComp (F, C, T_SIGN_UNSIGNED, "unsigned");
/* Now check the real type */
- switch (T & T_MASK_TYPE) {
+ switch (C & T_MASK_TYPE) {
case T_TYPE_CHAR:
fprintf (F, "char");
break;
fprintf (F, "void");
break;
case T_TYPE_STRUCT:
- fprintf (F, "struct %s", ((SymEntry*) DecodePtr (Type))->Name);
- Type += DECODE_SIZE;
+ fprintf (F, "struct %s", ((SymEntry*) T->A.P)->Name);
break;
case T_TYPE_UNION:
- fprintf (F, "union %s", ((SymEntry*) DecodePtr (Type))->Name);
- Type += DECODE_SIZE;
+ fprintf (F, "union %s", ((SymEntry*) T->A.P)->Name);
break;
case T_TYPE_ARRAY:
/* Recursive call */
- PrintType (F, Type + DECODE_SIZE);
- Size = Decode (Type);
- if (Size == UNSPECIFIED) {
+ PrintType (F, T + 1);
+ if (T->A.L == UNSPECIFIED) {
fprintf (F, "[]");
} else {
- fprintf (F, "[%lu]", Size);
+ fprintf (F, "[%ld]", T->A.L);
}
return;
case T_TYPE_PTR:
/* Recursive call */
- PrintType (F, Type);
+ PrintType (F, T + 1);
fprintf (F, "*");
return;
case T_TYPE_FUNC:
fprintf (F, "function returning ");
- Type += DECODE_SIZE;
break;
default:
- fprintf (F, "unknown type: %04X", T);
+ fprintf (F, "unknown type: %04lX", T->C);
}
+ /* Next element */
+ ++T;
}
}
-void PrintFuncSig (FILE* F, const char* Name, type* Type)
+void PrintFuncSig (FILE* F, const char* Name, Type* T)
/* Print a function signature. */
{
/* Get the function descriptor */
- const FuncDesc* D = GetFuncDesc (Type);
+ const FuncDesc* D = GetFuncDesc (T);
/* Print a comment with the function signature */
- PrintType (F, GetFuncReturn (Type));
+ PrintType (F, GetFuncReturn (T));
if (D->Flags & FD_NEAR) {
fprintf (F, " __near__");
}
-void PrintRawType (FILE* F, const type* Type)
+void PrintRawType (FILE* F, const Type* T)
/* Print a type string in raw format (for debugging) */
{
- while (*Type != T_END) {
- fprintf (F, "%04X ", *Type++);
+ while (T->C != T_END) {
+ fprintf (F, "%04lX ", T->C);
+ ++T;
}
fprintf (F, "\n");
}
-void Encode (type* Type, unsigned long Val)
-/* Encode Val into the given type string */
-{
- int I;
- for (I = 0; I < DECODE_SIZE; ++I) {
- *Type++ = ((type) Val) | 0x8000;
- Val >>= 15;
- }
-}
-
-
-
-void EncodePtr (type* Type, void* P)
-/* Encode a pointer into a type array */
-{
- Encode (Type, (unsigned long) P);
-}
-
-
-
-unsigned long Decode (const type* Type)
-/* Decode */
-{
- int I;
- unsigned long Val = 0;
- for (I = DECODE_SIZE-1; I >= 0; I--) {
- Val <<= 15;
- Val |= (Type[I] & 0x7FFF);
- }
- return Val;
-}
-
-
-
-void* DecodePtr (const type* Type)
-/* Decode a pointer from a type array */
-{
- return (void*) Decode (Type);
-}
-
-
-
-int HasEncode (const type* Type)
-/* Return true if the given type has encoded data */
-{
- return IsClassStruct (Type) || IsTypeArray (Type) || IsTypeFunc (Type);
-}
-
-
-
-void CopyEncode (const type* Source, type* Target)
-/* Copy encoded data from Source to Target */
+int TypeHasAttr (const Type* T)
+/* Return true if the given type has attribute data */
{
- memcpy (Target, Source, DECODE_SIZE * sizeof (type));
+ return IsClassStruct (T) || IsTypeArray (T) || IsClassFunc (T);
}
-unsigned SizeOf (const type* T)
+unsigned SizeOf (const Type* T)
/* Compute size of object represented by type array. */
{
- SymEntry* Entry;
- long ElementCount;
-
- switch (UnqualifiedType (T[0])) {
+ switch (UnqualifiedType (T->C)) {
case T_VOID:
return 0; /* Assume voids have size zero */
case T_STRUCT:
case T_UNION:
- Entry = DecodePtr (T+1);
- return Entry->V.S.Size;
+ return ((SymEntry*) T->A.P)->V.S.Size;
case T_ARRAY:
- ElementCount = GetElementCount (T);
- if (ElementCount == UNSPECIFIED) {
+ if (T->A.L == UNSPECIFIED) {
/* Array with unspecified size */
return 0;
} else {
- return ElementCount * SizeOf (T + DECODE_SIZE + 1);
+ return T->A.L * SizeOf (T + 1);
}
default:
- Internal ("Unknown type in SizeOf: %04X", *T);
+ Internal ("Unknown type in SizeOf: %04lX", T->C);
return 0;
}
-unsigned PSizeOf (const type* T)
+unsigned PSizeOf (const Type* T)
/* Compute size of pointer object. */
{
/* We are expecting a pointer expression */
- CHECK ((T[0] & T_MASK_CLASS) == T_CLASS_PTR);
+ CHECK (IsClassPtr (T));
/* Skip the pointer or array token itself */
- if (IsTypeArray (T)) {
- return SizeOf (T + DECODE_SIZE + 1);
- } else {
- return SizeOf (T + 1);
- }
+ return SizeOf (T + 1);
}
-unsigned CheckedSizeOf (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 CheckedPSizeOf (const type* T)
+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 TypeOf (const type* T)
+unsigned TypeOf (const Type* T)
/* Get the code generator base type of the object */
{
- FuncDesc* F;
-
- switch (UnqualifiedType (T[0])) {
+ switch (UnqualifiedType (T->C)) {
case T_SCHAR:
return CF_CHAR;
return CF_FLOAT;
case T_FUNC:
- F = DecodePtr (T+1);
- return (F->Flags & FD_VARIADIC)? 0 : CF_FIXARGC;
+ return (((FuncDesc*) T->A.P)->Flags & FD_VARIADIC)? 0 : CF_FIXARGC;
case T_STRUCT:
case T_UNION:
return CF_INT | CF_UNSIGNED;
default:
- Error ("Illegal type");
+ Error ("Illegal type %04lX", T->C);
return CF_INT;
}
}
-type* Indirect (type* T)
+Type* Indirect (Type* T)
/* Do one indirection for the given type, that is, return the type where the
* given type points to.
*/
{
/* We are expecting a pointer expression */
- CHECK ((T[0] & T_MASK_CLASS) == T_CLASS_PTR);
+ CHECK (IsClassPtr (T));
/* Skip the pointer or array token itself */
- if (IsTypeArray (T)) {
- return T + DECODE_SIZE + 1;
- } else {
- return T + 1;
- }
+ return T + 1;
}
-type* ArrayToPtr (const type* T)
+Type* ArrayToPtr (const Type* T)
/* Convert an array to a pointer to it's first element */
{
/* Function must only be called for an array */
- CHECK ((T[0] & T_MASK_TYPE) == T_TYPE_ARRAY);
+ CHECK (IsTypeArray (T));
/* Return pointer to first element */
- return PointerTo (T + DECODE_SIZE + 1);
-}
-
-
-
-int IsClassInt (const type* T)
-/* Return true if this is an integer type */
-{
- return (T[0] & T_MASK_CLASS) == T_CLASS_INT;
-}
-
-
-
-int IsClassFloat (const type* T)
-/* Return true if this is a float type */
-{
- return (T[0] & T_MASK_CLASS) == T_CLASS_FLOAT;
-}
-
-
-
-int IsClassPtr (const type* T)
-/* Return true if this is a pointer type */
-{
- return (T[0] & T_MASK_CLASS) == T_CLASS_PTR;
-}
-
-
-
-int IsClassStruct (const type* T)
-/* Return true if this is a struct type */
-{
- return (T[0] & T_MASK_CLASS) == T_CLASS_STRUCT;
+ return PointerTo (T + 1);
}
-int IsSignUnsigned (const type* T)
-/* Return true if this is an unsigned type */
-{
- return (T[0] & T_MASK_SIGN) == T_SIGN_UNSIGNED;
-}
-
-
-
-int IsQualConst (const type* T)
-/* Return true if the given type has a const memory image */
-{
- return (GetQualifier (T) & T_QUAL_CONST) != 0;
-}
-
-
-
-int IsQualVolatile (const type* T)
-/* Return true if the given type has a volatile type qualifier */
+TypeCode GetQualifier (const Type* T)
+/* Get the qualifier from the given type string */
{
- return (GetQualifier (T) & T_QUAL_VOLATILE) != 0;
+ /* If this is an array, look at the element type, otherwise look at the
+ * type itself.
+ */
+ if (IsTypeArray (T)) {
+ ++T;
+ }
+ return (T->C & T_MASK_QUAL);
}
-int IsFastCallFunc (const type* T)
+int IsFastCallFunc (const Type* T)
/* Return true if this is a function type or pointer to function with
* __fastcall__ calling conventions
*/
-int IsVariadicFunc (const type* T)
+int IsVariadicFunc (const Type* T)
/* Return true if this is a function type or pointer to function type with
* variable parameter list
*/
-type GetQualifier (const type* T)
-/* Get the qualifier from the given type string */
+FuncDesc* GetFuncDesc (const Type* T)
+/* Get the FuncDesc pointer from a function or pointer-to-function type */
{
- /* If this is an array, look at the element type, otherwise look at the
- * type itself.
- */
- if (IsTypeArray (T)) {
- T += DECODE_SIZE + 1;
+ if (UnqualifiedType (T->C) == T_PTR) {
+ /* Pointer to function */
+ ++T;
}
- return (T[0] & T_MASK_QUAL);
+
+ /* Be sure it's a function type */
+ CHECK (IsClassFunc (T));
+
+ /* Get the function descriptor from the type attributes */
+ return T->A.P;
}
-FuncDesc* GetFuncDesc (const type* T)
-/* Get the FuncDesc pointer from a function or pointer-to-function type */
+void SetFuncDesc (Type* T, FuncDesc* F)
+/* Set the FuncDesc pointer in a function or pointer-to-function type */
{
- if (UnqualifiedType (T[0]) == T_PTR) {
- /* Pointer to function */
- ++T;
+ if (UnqualifiedType (T->C) == T_PTR) {
+ /* Pointer to function */
+ ++T;
}
/* Be sure it's a function type */
- CHECK (T[0] == T_FUNC);
+ CHECK (IsClassFunc (T));
- /* Decode the function descriptor and return it */
- return DecodePtr (T+1);
+ /* Set the function descriptor */
+ T->A.P = F;
}
-type* GetFuncReturn (type* T)
+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;
+ if (UnqualifiedType (T->C) == T_PTR) {
+ /* Pointer to function */
+ ++T;
}
/* Be sure it's a function type */
- CHECK (T[0] == T_FUNC);
+ CHECK (IsClassFunc (T));
/* Return a pointer to the return type */
- return T + 1 + DECODE_SIZE;
-
+ return T + 1;
}
-long GetElementCount (const type* T)
+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 Decode (T+1);
+ return T->A.L;
+}
+
+
+
+void SetElementCount (Type* T, long Count)
+/* Set the element count of the array specified in T (which must be of
+ * array type).
+ */
+{
+ CHECK (IsTypeArray (T));
+ T->A.L = Count;
}
-type* GetElementType (type* T)
+Type* GetElementType (Type* T)
/* Return the element type of the given array type. */
{
CHECK (IsTypeArray (T));
- return T + DECODE_SIZE + 1;
+ return T + 1;
}
-type* IntPromotion (type* T)
+SymEntry* GetSymEntry (const Type* T)
+/* Return a SymEntry pointer from a type */
+{
+ /* Only structs or unions have a SymEntry attribute */
+ CHECK (IsClassStruct (T));
+
+ /* Return the attribute */
+ return T->A.P;
+}
+
+
+
+void SetSymEntry (Type* T, SymEntry* S)
+/* Set the SymEntry pointer for a type */
+{
+ /* Only structs or unions have a SymEntry attribute */
+ CHECK (IsClassStruct (T));
+
+ /* Set the attribute */
+ T->A.P = S;
+}
+
+
+
+Type* IntPromotion (Type* T)
/* Apply the integer promotions to T and return the result. The returned type
* string may be T if there is no need to change it.
*/
-type* PtrConversion (type* T)
+Type* PtrConversion (Type* T)
/* If the type is a function, convert it to pointer to function. If the
* expression is an array, convert it to pointer to first element. Otherwise
* return T.
- */
+ */
{
if (IsTypeFunc (T)) {
return PointerTo (T);
+
/* */
/* */
/* */
-/* (C) 1998-2004 Ullrich von Bassewitz */
+/* (C) 1998-2006 Ullrich von Bassewitz */
/* Römerstrasse 52 */
/* D-70794 Filderstadt */
/* EMail: uz@cc65.org */
+/* Type code entry */
+typedef unsigned long TypeCode;
+
/* Type entry */
-typedef unsigned short type;
+typedef struct Type Type;
+struct Type {
+ TypeCode C; /* Code for this entry */
+ union {
+ void* P; /* Arbitrary attribute pointer */
+ long L; /* Numeric attribute value */
+ unsigned long U; /* Dito, unsigned */
+ } A; /* Type attribute if necessary */
+};
+
+/* A macro that expands to a full initializer for struct Type */
+#define TYPE(T) { (T), { 0 } }
/* Maximum length of a type string */
#define MAXTYPELEN 30
-/* Type elements needed for Encode/Decode */
-#define DECODE_SIZE 5
-
/* Special encodings for element counts of an array */
#define UNSPECIFIED -1L /* Element count was not specified */
#define FLEXIBLE 0L /* Flexible array struct member */
#define SIZEOF_PTR 2
/* Predefined type strings */
-extern type type_schar[];
-extern type type_uchar[];
-extern type type_int[];
-extern type type_uint[];
-extern type type_long[];
-extern type type_ulong[];
-extern type type_void[];
-extern type type_size_t[];
-extern type type_float[];
-extern type type_double[];
+extern Type type_schar[];
+extern Type type_uchar[];
+extern Type type_int[];
+extern Type type_uint[];
+extern Type type_long[];
+extern Type type_ulong[];
+extern Type type_void[];
+extern Type type_size_t[];
+extern Type type_float[];
+extern Type type_double[];
+
+/* Forward for the SymEntry struct */
+struct SymEntry;
-unsigned TypeLen (const type* Type);
+unsigned TypeLen (const Type* T);
/* Return the length of the type string */
-type* TypeCpy (type* Dest, const type* Src);
+Type* TypeCpy (Type* Dest, const Type* Src);
/* Copy a type string */
-type* TypeCat (type* Dest, const type* Src);
-/* Append Src */
-
-type* TypeDup (const type* Type);
+Type* TypeDup (const Type* T);
/* Create a copy of the given type on the heap */
-type* TypeAlloc (unsigned Len);
+Type* TypeAlloc (unsigned Len);
/* Allocate memory for a type string of length Len. Len *must* include the
* trailing T_END.
*/
-void TypeFree (type* Type);
+void TypeFree (Type* T);
/* Free a type string */
int SignExtendChar (int C);
/* Do correct sign extension of a character */
-type GetDefaultChar (void);
+TypeCode GetDefaultChar (void);
/* Return the default char type (signed/unsigned) depending on the settings */
-type* GetCharArrayType (unsigned Len);
+Type* GetCharArrayType (unsigned Len);
/* Return the type for a char array of the given length */
-type* GetImplicitFuncType (void);
+Type* GetImplicitFuncType (void);
/* Return a type string for an inplicitly declared function */
-type* PointerTo (const type* T);
+Type* PointerTo (const Type* T);
/* Return a type string that is "pointer to T". The type string is allocated
* on the heap and may be freed after use.
*/
-void PrintType (FILE* F, const type* Type);
+void PrintType (FILE* F, const Type* T);
/* Output translation of type array. */
-void PrintRawType (FILE* F, const type* Type);
+void PrintRawType (FILE* F, const Type* T);
/* Print a type string in raw format (for debugging) */
-void PrintFuncSig (FILE* F, const char* Name, type* Type);
+void PrintFuncSig (FILE* F, const char* Name, Type* T);
/* Print a function signature. */
-void Encode (type* Type, unsigned long Val);
-/* Encode Val into the given type string */
-
-void EncodePtr (type* Type, void* P);
-/* Encode a pointer into a type array */
-
-unsigned long Decode (const type* Type);
-/* Decode an unsigned long from a type array */
-
-void* DecodePtr (const type* Type);
-/* Decode a pointer from a type array */
+int TypeHasAttr (const Type* T);
+/* Return true if the given type has attribute data */
-int HasEncode (const type* Type);
-/* Return true if the given type has encoded data */
-
-void CopyEncode (const type* Source, type* Target);
-/* Copy encoded data from Source to Target */
+#if defined(HAVE_INLINE)
+INLINE void CopyTypeAttr (const Type* Src, Type* Dest)
+/* Copy attribute data from Src to Dest */
+{
+ Dest->A = Src->A;
+}
+#else
+# define CopyTypeAttr(Src, Dest) ((Dest)->A = (Src)->A)
+#endif
#if defined(HAVE_INLINE)
-INLINE type UnqualifiedType (type T)
-/* Return the unqalified type */
+INLINE TypeCode UnqualifiedType (TypeCode T)
+/* Return the unqalified type code */
{
return (T & ~T_MASK_QUAL);
}
# define UnqualifiedType(T) ((T) & ~T_MASK_QUAL)
#endif
-unsigned SizeOf (const type* Type);
+unsigned SizeOf (const Type* T);
/* Compute size of object represented by type array. */
-unsigned PSizeOf (const type* Type);
+unsigned PSizeOf (const Type* T);
/* Compute size of pointer object. */
-unsigned CheckedSizeOf (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 CheckedPSizeOf (const type* T);
+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 TypeOf (const type* Type);
+unsigned TypeOf (const Type* T);
/* Get the code generator base type of the object */
-type* Indirect (type* Type);
+Type* Indirect (Type* T);
/* Do one indirection for the given type, that is, return the type where the
* given type points to.
*/
-type* ArrayToPtr (const type* Type);
+Type* ArrayToPtr (const Type* T);
/* Convert an array to a pointer to it's first element */
#if defined(HAVE_INLINE)
-INLINE int IsTypeChar (const type* T)
+INLINE int IsTypeChar (const Type* T)
/* Return true if this is a character type */
{
- return (T[0] & T_MASK_TYPE) == T_TYPE_CHAR;
+ return (T->C & T_MASK_TYPE) == T_TYPE_CHAR;
}
#else
-# define IsTypeChar(T) (((T)[0] & T_MASK_TYPE) == T_TYPE_CHAR)
+# define IsTypeChar(T) (((T)->C & T_MASK_TYPE) == T_TYPE_CHAR)
#endif
#if defined(HAVE_INLINE)
-INLINE int IsTypeInt (const type* T)
+INLINE 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;
+ return (T->C & T_MASK_TYPE) == T_TYPE_INT;
}
#else
-# define IsTypeInt(T) (((T)[0] & T_MASK_TYPE) == T_TYPE_INT)
+# define IsTypeInt(T) (((T)->C & T_MASK_TYPE) == T_TYPE_INT)
#endif
#if defined(HAVE_INLINE)
-INLINE int IsTypeLong (const type* T)
+INLINE 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;
+ return (T->C & T_MASK_TYPE) == T_TYPE_LONG;
}
#else
-# define IsTypeLong(T) (((T)[0] & T_MASK_TYPE) == T_TYPE_LONG)
+# define IsTypeLong(T) (((T)->C & T_MASK_TYPE) == T_TYPE_LONG)
#endif
#if defined(HAVE_INLINE)
-INLINE int IsTypeFloat (const type* T)
+INLINE int IsTypeFloat (const Type* T)
/* Return true if this is a float type */
{
- return (T[0] & T_MASK_TYPE) == T_TYPE_FLOAT;
+ return (T->C & T_MASK_TYPE) == T_TYPE_FLOAT;
}
#else
-# define IsTypeFloat(T) (((T)[0] & T_MASK_TYPE) == T_TYPE_FLOAT)
+# define IsTypeFloat(T) (((T)->C & T_MASK_TYPE) == T_TYPE_FLOAT)
#endif
#if defined(HAVE_INLINE)
-INLINE int IsTypeDouble (const type* T)
+INLINE int IsTypeDouble (const Type* T)
/* Return true if this is a double type */
{
- return (T[0] & T_MASK_TYPE) == T_TYPE_DOUBLE;
+ return (T->C & T_MASK_TYPE) == T_TYPE_DOUBLE;
}
#else
-# define IsTypeDouble(T) (((T)[0] & T_MASK_TYPE) == T_TYPE_DOUBLE)
+# define IsTypeDouble(T) (((T)->C & T_MASK_TYPE) == T_TYPE_DOUBLE)
#endif
#if defined(HAVE_INLINE)
-INLINE int IsTypePtr (const type* T)
+INLINE int IsTypePtr (const Type* T)
/* Return true if this is a pointer type */
{
- return ((T[0] & T_MASK_TYPE) == T_TYPE_PTR);
+ return ((T->C & T_MASK_TYPE) == T_TYPE_PTR);
}
#else
-# define IsTypePtr(T) (((T)[0] & T_MASK_TYPE) == T_TYPE_PTR)
+# define IsTypePtr(T) (((T)->C & T_MASK_TYPE) == T_TYPE_PTR)
#endif
#if defined(HAVE_INLINE)
-INLINE int IsTypeStruct (const type* T)
+INLINE int IsTypeStruct (const Type* T)
/* Return true if this is a struct type */
{
- return ((T[0] & T_MASK_TYPE) == T_TYPE_STRUCT);
+ return ((T->C & T_MASK_TYPE) == T_TYPE_STRUCT);
}
#else
-# define IsTypeStruct(T) (((T)[0] & T_MASK_TYPE) == T_TYPE_STRUCT)
+# define IsTypeStruct(T) (((T)->C & T_MASK_TYPE) == T_TYPE_STRUCT)
#endif
#if defined(HAVE_INLINE)
-INLINE int IsTypeUnion (const type* T)
+INLINE int IsTypeUnion (const Type* T)
/* Return true if this is a union type */
{
- return ((T[0] & T_MASK_TYPE) == T_TYPE_UNION);
+ return ((T->C & T_MASK_TYPE) == T_TYPE_UNION);
}
#else
-# define IsTypeUnion(T) (((T)[0] & T_MASK_TYPE) == T_TYPE_UNION)
+# define IsTypeUnion(T) (((T)->C & T_MASK_TYPE) == T_TYPE_UNION)
#endif
#if defined(HAVE_INLINE)
-INLINE int IsTypeArray (const type* T)
+INLINE int IsTypeArray (const Type* T)
/* Return true if this is an array type */
{
- return ((T[0] & T_MASK_TYPE) == T_TYPE_ARRAY);
+ return ((T->C & T_MASK_TYPE) == T_TYPE_ARRAY);
}
#else
-# define IsTypeArray(T) (((T)[0] & T_MASK_TYPE) == T_TYPE_ARRAY)
+# define IsTypeArray(T) (((T)->C & T_MASK_TYPE) == T_TYPE_ARRAY)
#endif
#if defined(HAVE_INLINE)
-INLINE int IsTypeVoid (const type* T)
+INLINE int IsTypeVoid (const Type* T)
/* Return true if this is a void type */
{
- return (T[0] & T_MASK_TYPE) == T_TYPE_VOID;
+ return (T->C & T_MASK_TYPE) == T_TYPE_VOID;
}
#else
-# define IsTypeVoid(T) (((T)[0] & T_MASK_TYPE) == T_TYPE_VOID)
+# define IsTypeVoid(T) (((T)->C & T_MASK_TYPE) == T_TYPE_VOID)
#endif
#if defined(HAVE_INLINE)
-INLINE int IsTypeFunc (const type* T)
+INLINE int IsTypeFunc (const Type* T)
/* Return true if this is a function class */
{
- return ((T[0] & T_MASK_TYPE) == T_TYPE_FUNC);
+ return ((T->C & T_MASK_TYPE) == T_TYPE_FUNC);
}
#else
-# define IsTypeFunc(T) (((T)[0] & T_MASK_TYPE) == T_TYPE_FUNC)
+# define IsTypeFunc(T) (((T)->C & T_MASK_TYPE) == T_TYPE_FUNC)
#endif
#if defined(HAVE_INLINE)
-INLINE int IsTypeFuncPtr (const type* T)
+INLINE 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);
+ return ((T[0].C & T_MASK_TYPE) == T_TYPE_PTR && (T[1].C & T_MASK_TYPE) == T_TYPE_FUNC);
}
#else
# define IsTypeFuncPtr(T) \
- ((((T)[0] & T_MASK_TYPE) == T_TYPE_PTR) && (((T)[1] & T_MASK_TYPE) == T_TYPE_FUNC))
+ ((((T)[0].C & T_MASK_TYPE) == T_TYPE_PTR) && (((T)[1].C & T_MASK_TYPE) == T_TYPE_FUNC))
#endif
-int IsClassInt (const type* Type) attribute ((const));
+#if defined(HAVE_INLINE)
+INLINE int IsClassInt (const Type* T)
/* Return true if this is an integer type */
+{
+ return (T->C & T_MASK_CLASS) == T_CLASS_INT;
+}
+#else
+# define IsClassInt(T) (((T)->C & T_MASK_CLASS) == T_CLASS_INT)
+#endif
-int IsClassFloat (const type* Type) attribute ((const));
+#if defined(HAVE_INLINE)
+INLINE int IsClassFloat (const Type* T)
/* Return true if this is a float type */
+{
+ return (T->C & T_MASK_CLASS) == T_CLASS_FLOAT;
+}
+#else
+# define IsClassFloat(T) (((T)->C & T_MASK_CLASS) == T_CLASS_FLOAT)
+#endif
-int IsClassPtr (const type* Type) attribute ((const));
+#if defined(HAVE_INLINE)
+INLINE int IsClassPtr (const Type* T)
/* Return true if this is a pointer type */
+{
+ return (T->C & T_MASK_CLASS) == T_CLASS_PTR;
+}
+#else
+# define IsClassPtr(T) (((T)->C & T_MASK_CLASS) == T_CLASS_PTR)
+#endif
-int IsClassStruct (const type* Type) attribute ((const));
+#if defined(HAVE_INLINE)
+INLINE int IsClassStruct (const Type* T)
/* Return true if this is a struct type */
+{
+ return (T->C & T_MASK_CLASS) == T_CLASS_STRUCT;
+}
+#else
+# define IsClassStruct(T) (((T)->C & T_MASK_CLASS) == T_CLASS_STRUCT)
+#endif
-int IsSignUnsigned (const type* Type) attribute ((const));
+#if defined(HAVE_INLINE)
+INLINE int IsClassFunc (const Type* T)
+/* Return true if this is a function type */
+{
+ return (T->C & T_MASK_CLASS) == T_CLASS_FUNC;
+}
+#else
+# define IsClassFunc(T) (((T)->C & T_MASK_CLASS) == T_CLASS_FUNC)
+#endif
+
+#if defined(HAVE_INLINE)
+INLINE int IsSignUnsigned (const Type* T)
/* Return true if this is an unsigned type */
+{
+ return (T->C & T_MASK_SIGN) == T_SIGN_UNSIGNED;
+}
+#else
+# define IsSignUnsigned(T) (((T)->C & T_MASK_SIGN) == T_SIGN_UNSIGNED)
+#endif
-int IsQualConst (const type* T) attribute ((const));
+TypeCode GetQualifier (const Type* T) attribute ((const));
+/* Get the qualifier from the given type string */
+
+#if defined(HAVE_INLINE)
+INLINE int IsQualConst (const Type* T)
/* Return true if the given type has a const memory image */
+{
+ return (GetQualifier (T) & T_QUAL_CONST) != 0;
+}
+#else
+# define IsQualConst(T) (((T)->C & T_QUAL_CONST) != 0)
+#endif
-int IsQualVolatile (const type* T) attribute ((const));
+#if defined(HAVE_INLINE)
+INLINE int IsQualVolatile (const Type* T)
/* Return true if the given type has a volatile type qualifier */
+{
+ return (GetQualifier (T) & T_QUAL_VOLATILE) != 0;
+}
+#else
+# define IsQualVolatile(T) (((T)->C & T_QUAL_VOLATILE) != 0)
+#endif
-int IsFastCallFunc (const type* T) attribute ((const));
+int IsFastCallFunc (const Type* T) attribute ((const));
/* Return true if this is a function type or pointer to function with
* __fastcall__ calling conventions
*/
-int IsVariadicFunc (const type* T) attribute ((const));
+int IsVariadicFunc (const Type* T) attribute ((const));
/* Return true if this is a function type or pointer to function type with
* variable parameter list
*/
#if defined(HAVE_INLINE)
-INLINE type GetType (const type* T)
+INLINE TypeCode GetType (const Type* T)
/* Get the raw type */
{
- return (T[0] & T_MASK_TYPE);
+ return (T->C & T_MASK_TYPE);
}
#else
-# define GetType(T) ((T)[0] & T_MASK_TYPE)
+# define GetType(T) ((T)->C & T_MASK_TYPE)
#endif
#if defined(HAVE_INLINE)
-INLINE type GetClass (const type* T)
+INLINE TypeCode GetClass (const Type* T)
/* Get the class of a type string */
{
- return (T[0] & T_MASK_CLASS);
+ return (T->C & T_MASK_CLASS);
}
#else
-# define GetClass(T) ((T)[0] & T_MASK_CLASS)
+# define GetClass(T) ((T)->C & T_MASK_CLASS)
#endif
#if defined(HAVE_INLINE)
-INLINE type GetSignedness (const type* T)
+INLINE TypeCode GetSignedness (const Type* T)
/* Get the sign of a type */
{
- return (T[0] & T_MASK_SIGN);
+ return (T->C & T_MASK_SIGN);
}
#else
-# define GetSignedness(T) ((T)[0] & T_MASK_SIGN)
+# define GetSignedness(T) ((T)->C & T_MASK_SIGN)
#endif
#if defined(HAVE_INLINE)
-INLINE type GetSizeModifier (const type* T)
+INLINE TypeCode GetSizeModifier (const Type* T)
/* Get the size modifier of a type */
{
- return (T[0] & T_MASK_SIZE);
+ return (T->C & T_MASK_SIZE);
}
#else
-# define GetSizeModifier(T) ((T)[0] & T_MASK_SIZE)
+# define GetSizeModifier(T) ((T)->C & T_MASK_SIZE)
#endif
-type GetQualifier (const type* T) attribute ((const));
-/* Get the qualifier from the given type string */
-
-FuncDesc* GetFuncDesc (const type* T) attribute ((const));
+FuncDesc* GetFuncDesc (const Type* T) attribute ((const));
/* Get the FuncDesc pointer from a function or pointer-to-function type */
-type* GetFuncReturn (type* T) attribute ((const));
+void SetFuncDesc (Type* T, FuncDesc* F);
+/* Set the FuncDesc pointer in a function or pointer-to-function type */
+
+Type* GetFuncReturn (Type* T) attribute ((const));
/* Return a pointer to the return type of a function or pointer-to-function type */
-long GetElementCount (const type* T);
+long GetElementCount (const Type* T);
/* Get the element count of the array specified in T (which must be of
* array type).
*/
-type* GetElementType (type* T);
+void SetElementCount (Type* T, long Count);
+/* Set the element count of the array specified in T (which must be of
+ * array type).
+ */
+
+Type* GetElementType (Type* T);
/* Return the element type of the given array type. */
-type* IntPromotion (type* T);
+struct SymEntry* GetSymEntry (const Type* T) attribute ((const));
+/* Return a SymEntry pointer from a type */
+
+void SetSymEntry (Type* T, struct SymEntry* S);
+/* Set the SymEntry pointer for a type */
+
+Type* IntPromotion (Type* T);
/* Apply the integer promotions to T and return the result. The returned type
* string may be T if there is no need to change it.
*/
-type* PtrConversion (type* T);
+Type* PtrConversion (Type* T);
/* If the type is a function, convert it to pointer to function. If the
* expression is an array, convert it to pointer to first element. Otherwise
* return T.
-static void ParseTypeSpec (DeclSpec* D, int Default, type Qualifiers);
+static void ParseTypeSpec (DeclSpec* D, long Default, TypeCode Qualifiers);
/* Parse a type specificier */
-static unsigned ParseInitInternal (type* T, int AllowFlexibleMembers);
+static unsigned ParseInitInternal (Type* T, int AllowFlexibleMembers);
/* Parse initialization of variables. Return the number of data bytes. */
-static type OptionalQualifiers (type Q)
+static TypeCode OptionalQualifiers (TypeCode Q)
/* Read type qualifiers if we have any */
{
while (TokIsTypeQual (&CurTok)) {
/* Initialize the DeclSpec struct for use */
{
D->StorageClass = 0;
- D->Type[0] = T_END;
+ D->Type[0].C = T_END;
D->Flags = 0;
}
static void InitDeclaration (Declaration* D)
/* Initialize the Declaration struct for use */
{
- D->Ident[0] = '\0';
- D->Type[0] = T_END;
- D->Index = 0;
+ D->Ident[0] = '\0';
+ D->Type[0].C = T_END;
+ D->Index = 0;
}
-static void AddTypeToDeclaration (Declaration* D, type T)
+static void AddTypeToDeclaration (Declaration* D, TypeCode T)
/* Add a type specifier to the type of a declaration */
{
NeedTypeSpace (D, 1);
- D->Type[D->Index++] = T;
+ D->Type[D->Index++].C = T;
}
-static void AddEncodeToDeclaration (Declaration* D, type T, unsigned long Val)
-/* Add a type plus encoding to the type of a declaration */
+static void AddFuncTypeToDeclaration (Declaration* D, FuncDesc* F)
+/* Add a function type plus function descriptor to the type of a declaration */
{
- NeedTypeSpace (D, DECODE_SIZE+1);
- D->Type[D->Index++] = T;
- Encode (D->Type + D->Index, Val);
- D->Index += DECODE_SIZE;
+ NeedTypeSpace (D, 1);
+ D->Type[D->Index].C = T_FUNC;
+ SetFuncDesc (D->Type + D->Index, F);
+ ++D->Index;
+}
+
+
+
+static void AddArrayToDeclaration (Declaration* D, long Size)
+/* Add an array type plus size to the type of a declaration */
+{
+ NeedTypeSpace (D, 1);
+ D->Type[D->Index].C = T_ARRAY;
+ D->Type[D->Index].A.L = Size;
+ ++D->Index;
}
-static SymEntry* ParseStructDecl (const char* Name, type StructType)
+static SymEntry* ParseStructDecl (const char* Name, TypeCode StructType)
/* Parse a struct/union declaration. */
{
}
FlexibleMember = 1;
/* Assume zero for size calculations */
- Encode (Decl.Type + 1, FLEXIBLE);
+ SetElementCount (Decl.Type, FLEXIBLE);
} else {
StructSize += CheckedSizeOf (Decl.Type);
}
-static void ParseTypeSpec (DeclSpec* D, int Default, type Qualifiers)
+static void ParseTypeSpec (DeclSpec* D, long Default, TypeCode Qualifiers)
/* Parse a type specificier */
{
ident Ident;
SymEntry* Entry;
- type StructType;
+ TypeCode StructType;
/* Assume we have an explicit type */
D->Flags &= ~DS_DEF_TYPE;
case TOK_VOID:
NextToken ();
- D->Type[0] = T_VOID;
- D->Type[1] = T_END;
+ D->Type[0].C = T_VOID;
+ D->Type[1].C = T_END;
break;
case TOK_CHAR:
NextToken ();
- D->Type[0] = GetDefaultChar();
- D->Type[1] = T_END;
+ D->Type[0].C = GetDefaultChar();
+ D->Type[1].C = T_END;
break;
case TOK_LONG:
if (CurTok.Tok == TOK_UNSIGNED) {
NextToken ();
optionalint ();
- D->Type[0] = T_ULONG;
- D->Type[1] = T_END;
+ D->Type[0].C = T_ULONG;
+ D->Type[1].C = T_END;
} else {
optionalsigned ();
optionalint ();
- D->Type[0] = T_LONG;
- D->Type[1] = T_END;
+ D->Type[0].C = T_LONG;
+ D->Type[1].C = T_END;
}
break;
if (CurTok.Tok == TOK_UNSIGNED) {
NextToken ();
optionalint ();
- D->Type[0] = T_USHORT;
- D->Type[1] = T_END;
+ D->Type[0].C = T_USHORT;
+ D->Type[1].C = T_END;
} else {
optionalsigned ();
optionalint ();
- D->Type[0] = T_SHORT;
- D->Type[1] = T_END;
+ D->Type[0].C = T_SHORT;
+ D->Type[1].C = T_END;
}
break;
case TOK_INT:
NextToken ();
- D->Type[0] = T_INT;
- D->Type[1] = T_END;
+ D->Type[0].C = T_INT;
+ D->Type[1].C = T_END;
break;
case TOK_SIGNED:
case TOK_CHAR:
NextToken ();
- D->Type[0] = T_SCHAR;
- D->Type[1] = T_END;
+ D->Type[0].C = T_SCHAR;
+ D->Type[1].C = T_END;
break;
case TOK_SHORT:
NextToken ();
optionalint ();
- D->Type[0] = T_SHORT;
- D->Type[1] = T_END;
+ D->Type[0].C = T_SHORT;
+ D->Type[1].C = T_END;
break;
case TOK_LONG:
NextToken ();
optionalint ();
- D->Type[0] = T_LONG;
- D->Type[1] = T_END;
+ D->Type[0].C = T_LONG;
+ D->Type[1].C = T_END;
break;
case TOK_INT:
/* FALL THROUGH */
default:
- D->Type[0] = T_INT;
- D->Type[1] = T_END;
+ D->Type[0].C = T_INT;
+ D->Type[1].C = T_END;
break;
}
break;
case TOK_CHAR:
NextToken ();
- D->Type[0] = T_UCHAR;
- D->Type[1] = T_END;
+ D->Type[0].C = T_UCHAR;
+ D->Type[1].C = T_END;
break;
case TOK_SHORT:
NextToken ();
optionalint ();
- D->Type[0] = T_USHORT;
- D->Type[1] = T_END;
+ D->Type[0].C = T_USHORT;
+ D->Type[1].C = T_END;
break;
case TOK_LONG:
NextToken ();
optionalint ();
- D->Type[0] = T_ULONG;
- D->Type[1] = T_END;
+ D->Type[0].C = T_ULONG;
+ D->Type[1].C = T_END;
break;
case TOK_INT:
/* FALL THROUGH */
default:
- D->Type[0] = T_UINT;
- D->Type[1] = T_END;
+ D->Type[0].C = T_UINT;
+ D->Type[1].C = T_END;
break;
}
break;
case TOK_FLOAT:
NextToken ();
- D->Type[0] = T_FLOAT;
- D->Type[1] = T_END;
+ D->Type[0].C = T_FLOAT;
+ D->Type[1].C = T_END;
break;
case TOK_DOUBLE:
NextToken ();
- D->Type[0] = T_DOUBLE;
- D->Type[1] = T_END;
+ D->Type[0].C = T_DOUBLE;
+ D->Type[1].C = T_END;
break;
case TOK_STRUCT:
/* Declare the struct in the current scope */
Entry = ParseStructDecl (Ident, StructType);
/* Encode the struct entry into the type */
- D->Type[0] = StructType;
- EncodePtr (D->Type+1, Entry);
- D->Type[DECODE_SIZE+1] = T_END;
+ D->Type[0].C = StructType;
+ SetSymEntry (D->Type, Entry);
+ D->Type[1].C = T_END;
break;
case TOK_ENUM:
D->Flags |= DS_EXTRA_TYPE;
/* Parse the enum decl */
ParseEnumDecl ();
- D->Type[0] = T_INT;
- D->Type[1] = T_END;
+ D->Type[0].C = T_INT;
+ D->Type[1].C = T_END;
break;
case TOK_IDENT:
default:
if (Default < 0) {
Error ("Type expected");
- D->Type[0] = T_INT;
- D->Type[1] = T_END;
+ D->Type[0].C = T_INT;
+ D->Type[1].C = T_END;
} else {
- D->Flags |= DS_DEF_TYPE;
- D->Type[0] = (type) Default;
- D->Type[1] = T_END;
+ D->Flags |= DS_DEF_TYPE;
+ D->Type[0].C = (TypeCode) Default;
+ D->Type[1].C = T_END;
}
break;
}
/* There may also be qualifiers *after* the initial type */
- D->Type[0] |= OptionalQualifiers (Qualifiers);
+ D->Type[0].C |= OptionalQualifiers (Qualifiers);
}
-static type* ParamTypeCvt (type* T)
+static Type* ParamTypeCvt (Type* T)
/* If T is an array, convert it to a pointer else do nothing. Return the
* resulting type.
*/
{
if (IsTypeArray (T)) {
- T += DECODE_SIZE;
- T[0] = T_PTR;
+ T->C = T_PTR;
}
return T;
}
/* Check for an implicit int return in the function */
if ((Spec->Flags & DS_DEF_TYPE) != 0 &&
- Spec->Type[0] == T_INT &&
- Spec->Type[1] == T_END) {
+ Spec->Type[0].C == T_INT &&
+ Spec->Type[1].C == T_END) {
/* Function has an implicit int return. Output a warning if we don't
* have the C89 standard enabled explicitly.
*/
-static void ApplyFunctionModifiers (type* T, unsigned Flags)
+static void ApplyFunctionModifiers (Type* T, unsigned Flags)
/* Apply a set of function modifier flags to a function */
{
/* Get the function descriptor */
/* Pointer to something */
if (CurTok.Tok == TOK_STAR) {
- type T;
+ TypeCode C;
/* Skip the star */
NextToken ();
/* Allow optional const or volatile qualifiers */
- T = T_PTR | OptionalQualifiers (T_QUAL_NONE);
+ C = T_PTR | OptionalQualifiers (T_QUAL_NONE);
/* Parse the type, the pointer points to */
Decl (Spec, D, Mode);
/* Add the type */
- AddTypeToDeclaration (D, T);
+ AddTypeToDeclaration (D, C);
return;
}
if (CurTok.Tok == TOK_FASTCALL || CurTok.Tok == TOK_NEAR || CurTok.Tok == TOK_FAR) {
/* Remember the current type pointer */
- type* T = D->Type + D->Index;
+ Type* T = D->Type + D->Index;
/* Read the flags */
unsigned Flags = FunctionModifierFlags ();
F = ParseFuncDecl (Spec);
/* Add the function type. Be sure to bounds check the type buffer */
- AddEncodeToDeclaration (D, T_FUNC, (unsigned long) F);
+ AddFuncTypeToDeclaration (D, F);
} else {
/* Array declaration */
long Size = UNSPECIFIED;
}
ConsumeRBrack ();
- /* Add the type */
- AddEncodeToDeclaration (D, T_ARRAY, Size);
+ /* Add the array type with the size */
+ AddArrayToDeclaration (D, Size);
}
}
}
-type* ParseType (type* Type)
+Type* ParseType (Type* T)
/* Parse a complete type specification */
{
DeclSpec Spec;
ParseDecl (&Spec, &Decl, DM_NO_IDENT);
/* Copy the type to the target buffer */
- TypeCpy (Type, Decl.Type);
+ TypeCpy (T, Decl.Type);
/* Return a pointer to the target buffer */
- return Type;
+ return T;
}
void ParseDeclSpec (DeclSpec* D, unsigned DefStorage, int DefType)
/* Parse a declaration specification */
{
- type Qualifiers;
+ TypeCode Qualifiers;
/* Initialize the DeclSpec struct */
InitDeclSpec (D);
-static unsigned ParseScalarInit (type* T)
+static unsigned ParseScalarInit (Type* T)
/* Parse initializaton for scalar data types. Return the number of data bytes. */
{
ExprDesc ED;
-static unsigned ParsePointerInit (type* T)
+static unsigned ParsePointerInit (Type* T)
/* Parse initializaton for pointer data types. Return the number of data bytes. */
{
/* Optional opening brace */
-static unsigned ParseArrayInit (type* T, int AllowFlexibleMembers)
+static unsigned ParseArrayInit (Type* T, int AllowFlexibleMembers)
/* Parse initializaton for arrays. Return the number of data bytes. */
{
int Count;
/* Get the array data */
- type* ElementType = GetElementType (T);
+ Type* ElementType = GetElementType (T);
unsigned ElementSize = CheckedSizeOf (ElementType);
long ElementCount = GetElementCount (T);
ConsumeRCurly ();
}
-
if (ElementCount == UNSPECIFIED) {
/* Number of elements determined by initializer */
- Encode (T + 1, Count);
+ SetElementCount (T, Count);
ElementCount = Count;
} else if (ElementCount == FLEXIBLE && AllowFlexibleMembers) {
/* In non ANSI mode, allow initialization of flexible array
-static unsigned ParseStructInit (type* Type, int AllowFlexibleMembers)
+static unsigned ParseStructInit (Type* T, int AllowFlexibleMembers)
/* Parse initialization of a struct or union. Return the number of data bytes. */
{
SymEntry* Entry;
ConsumeLCurly ();
/* Get a pointer to the struct entry from the type */
- Entry = DecodePtr (Type + 1);
+ Entry = GetSymEntry (T);
/* Get the size of the struct from the symbol table entry */
StructSize = Entry->V.S.Size;
Size = 0;
do {
ConstExpr (hie1, &Expr);
- switch (UnqualifiedType (Expr.Type[0])) {
+ switch (UnqualifiedType (Expr.Type[0].C)) {
case T_SCHAR:
case T_UCHAR:
-static unsigned ParseInitInternal (type* T, int AllowFlexibleMembers)
+static unsigned ParseInitInternal (Type* T, int AllowFlexibleMembers)
/* Parse initialization of variables. Return the number of data bytes. */
{
- switch (UnqualifiedType (*T)) {
+ switch (UnqualifiedType (T->C)) {
case T_SCHAR:
case T_UCHAR:
-unsigned ParseInit (type* T)
+unsigned ParseInit (Type* T)
/* Parse initialization of variables. Return the number of data bytes. */
{
/* Parse the initialization. Flexible array members can only be initialized
/* */
/* */
/* */
-/* (C) 1998-2003 Ullrich von Bassewitz */
+/* (C) 1998-2006 Ullrich von Bassewitz */
/* Römerstrasse 52 */
/* D-70794 Filderstadt */
/* EMail: uz@cc65.org */
typedef struct DeclSpec DeclSpec;
struct DeclSpec {
unsigned StorageClass; /* One of the SC_xxx flags */
- type Type [MAXTYPELEN]; /* Type of the declaration spec */
+ Type Type[MAXTYPELEN]; /* Type of the declaration spec */
unsigned Flags; /* Bitmapped flags */
};
typedef struct Declaration Declaration;
struct Declaration {
ident Ident; /* The identifier if any, else empty */
- type Type [MAXTYPELEN]; /* The type */
+ Type Type[MAXTYPELEN]; /* The type */
/* Working variables */
unsigned Index; /* Used to build Type */
-type* ParseType (type* Type);
+Type* ParseType (Type* Type);
/* Parse a complete type specification */
void ParseDecl (const DeclSpec* Spec, Declaration* D, unsigned Mode);
* warning if not.
*/
-unsigned ParseInit (type* T);
+unsigned ParseInit (Type* T);
/* Parse initialization of variables. Return the number of initialized data
* bytes.
*/
-static type* promoteint (type* lhst, type* rhst)
+static Type* promoteint (Type* lhst, Type* rhst)
/* In an expression with two ints, return the type of the result */
{
/* Rules for integer types:
unsigned flags;
/* Get the type strings */
- type* lhst = lhs->Type;
- type* rhst = rhs->Type;
+ Type* lhst = lhs->Type;
+ Type* rhst = rhs->Type;
/* Generate type adjustment code if needed */
ltype = TypeOf (lhst);
ExprDesc SubScript;
CodeMark Mark1;
CodeMark Mark2;
- type* ElementType;
- type* tptr1;
+ Type* ElementType;
+ Type* tptr1;
/* Skip the bracket */
-void Store (ExprDesc* Expr, const type* StoreType)
+void Store (ExprDesc* Expr, const Type* StoreType)
/* Store the primary register into the location denoted by Expr. If StoreType
* is given, use this type when storing instead of Expr->Type. If StoreType
* is NULL, use Expr->Type instead.
case E_LOC_LITERAL:
/* Static variable or literal in the literal pool */
g_putstatic (Flags | CF_STATIC, Expr->Name, Expr->IVal);
- break;
+ break;
case E_LOC_REGISTER:
/* Register variable */
case TOK_SIZEOF:
NextToken ();
if (TypeSpecAhead ()) {
- type Type[MAXTYPELEN];
+ Type T[MAXTYPELEN];
NextToken ();
- Size = CheckedSizeOf (ParseType (Type));
+ Size = CheckedSizeOf (ParseType (T));
ConsumeRParen ();
} else {
/* Remember the output queue pointer */
/* Both pointers are allowed in comparison if they point to
* the same type, or if one of them is a void pointer.
*/
- type* left = Indirect (Expr->Type);
- type* right = Indirect (Expr2.Type);
- if (TypeCmp (left, right) < TC_EQUAL && *left != T_VOID && *right != T_VOID) {
+ Type* left = Indirect (Expr->Type);
+ Type* right = Indirect (Expr2.Type);
+ if (TypeCmp (left, right) < TC_EQUAL && left->C != T_VOID && right->C != T_VOID) {
/* Incomatible pointers */
Error ("Incompatible types");
}
ExprDesc Expr2;
unsigned flags; /* Operation flags */
CodeMark Mark; /* Remember code position */
- type* lhst; /* Type of left hand side */
- type* rhst; /* Type of right hand side */
+ Type* lhst; /* Type of left hand side */
+ Type* rhst; /* Type of right hand side */
/* Skip the PLUS token */
{
ExprDesc Expr2;
unsigned flags; /* Operation flags */
- type* lhst; /* Type of left hand side */
- type* rhst; /* Type of right hand side */
+ Type* lhst; /* Type of left hand side */
+ Type* rhst; /* Type of right hand side */
CodeMark Mark1; /* Save position of output queue */
CodeMark Mark2; /* Another position in the queue */
int rscale; /* Scale factor for the result */
ExprDesc Expr3; /* Expression 3 */
int Expr2IsNULL; /* Expression 2 is a NULL pointer */
int Expr3IsNULL; /* Expression 3 is a NULL pointer */
- type* ResultType; /* Type of result */
+ Type* ResultType; /* Type of result */
/* Call the lower level eval routine */
* must be saved if it's not constant, before evaluating the rhs.
*/
-void Store (ExprDesc* Expr, const type* StoreType);
+void Store (ExprDesc* Expr, const Type* StoreType);
/* Store the primary register into the location denoted by lval. If StoreType
* is given, use this type when storing instead of lval->Type. If StoreType
* is NULL, use lval->Type instead.
/* */
/* */
/* */
-/* (C) 2002-2004 Ullrich von Bassewitz */
+/* (C) 2002-2006 Ullrich von Bassewitz */
/* Römerstraße 52 */
/* D-70794 Filderstadt */
/* EMail: uz@cc65.org */
-ExprDesc* ED_MakeConstAbs (ExprDesc* Expr, long Value, type* Type)
+ExprDesc* ED_MakeConstAbs (ExprDesc* Expr, long Value, Type* Type)
/* Make Expr an absolute const with the given value and type. */
{
Expr->Sym = 0;
-type* ReplaceType (ExprDesc* Expr, const type* NewType)
+Type* ReplaceType (ExprDesc* Expr, const Type* NewType)
/* Replace the type of Expr by a copy of Newtype and return the old type string */
{
- type* OldType = Expr->Type;
+ Type* OldType = Expr->Type;
Expr->Type = TypeDup (NewType);
return OldType;
}
/* */
/* */
/* */
-/* (C) 2002-2004 Ullrich von Bassewitz */
+/* (C) 2002-2006 Ullrich von Bassewitz */
/* Römerstraße 52 */
/* D-70794 Filderstadt */
/* EMail: uz@cc65.org */
typedef struct ExprDesc ExprDesc;
struct ExprDesc {
struct SymEntry* Sym; /* Symbol table entry if known */
- type* Type; /* Type array of expression */
+ Type* Type; /* Type array of expression */
unsigned Flags;
unsigned long Name; /* Name or label number */
long IVal; /* Integer value if expression constant */
* an additional offset in Offs.
*/
-ExprDesc* ED_MakeConstAbs (ExprDesc* Expr, long Value, type* Type);
+ExprDesc* ED_MakeConstAbs (ExprDesc* Expr, long Value, Type* Type);
/* Make Expr an absolute const with the given value and type. */
ExprDesc* ED_MakeConstAbsInt (ExprDesc* Expr, long Value);
void PrintExprDesc (FILE* F, ExprDesc* Expr);
/* Print an ExprDesc */
-type* ReplaceType (ExprDesc* Expr, const type* NewType);
+Type* ReplaceType (ExprDesc* Expr, const Type* NewType);
/* Replace the type of Expr by a copy of Newtype and return the old type string */
/* */
/* */
/* */
-/* (C) 2000-2004 Ullrich von Bassewitz */
+/* (C) 2000-2006 Ullrich von Bassewitz */
/* Römerstrasse 52 */
/* D-70794 Filderstadt */
/* EMail: uz@cc65.org */
/* Structure that holds all data needed for function activation */
struct Function {
struct SymEntry* FuncEntry; /* Symbol table entry */
- type* ReturnType; /* Function return type */
+ Type* ReturnType; /* Function return type */
struct FuncDesc* Desc; /* Function descriptor */
int Reserved; /* Reserved local space */
unsigned RetLab; /* Return code label */
/* Initialize the fields */
F->FuncEntry = Sym;
F->ReturnType = GetFuncReturn (Sym->Type);
- F->Desc = (FuncDesc*) DecodePtr (Sym->Type + 1);
+ F->Desc = GetFuncDesc (Sym->Type);
F->Reserved = 0;
F->RetLab = GetLocalLabel ();
F->TopLevelSP = 0;
-type* F_GetReturnType (Function* F)
+Type* F_GetReturnType (Function* F)
/* Get the return type for the function */
{
return F->ReturnType;
-int F_AllocRegVar (Function* F, const type* Type)
+int F_AllocRegVar (Function* F, const Type* Type)
/* Allocate a register variable for the given variable type. If the allocation
* was successful, return the offset of the register variable in the register
* bank (zero page storage). If there is no register space left, return -1.
AddConstSym ("__fixargs__", type_uint, SC_DEF | SC_CONST, D->ParamSize);
if (D->Flags & FD_VARIADIC) {
/* Variadic function. The variable must be const. */
- static const type T [] = { T_UCHAR | T_QUAL_CONST, T_END };
+ static const Type T[] = { TYPE(T_UCHAR | T_QUAL_CONST), TYPE(T_END) };
AddLocalSym ("__argsize__", T, SC_DEF | SC_REF | SC_AUTO, 0);
} else {
/* Non variadic */
Error ("`main' cannot be declared as __fastcall__");
}
- /* If cc65 extensions aren't enabled, don't allow a main function that
+ /* If cc65 extensions aren't enabled, don't allow a main function that
* doesn't return an int.
*/
- if (IS_Get (&Standard) != STD_CC65 && CurrentFunc->ReturnType[0] != T_INT) {
+ if (IS_Get (&Standard) != STD_CC65 && CurrentFunc->ReturnType[0].C != T_INT) {
Error ("`main' must always return an int");
}
/* */
/* */
/* */
-/* (C) 1998-2001 Ullrich von Bassewitz */
-/* Wacholderweg 14 */
-/* D-70597 Stuttgart */
+/* (C) 1998-2006 Ullrich von Bassewitz */
+/* Römerstrasse 52 */
+/* D-70794 Filderstadt */
/* EMail: uz@cc65.org */
/* */
/* */
unsigned F_GetParamSize (const Function* F);
/* Return the parameter size for the current function */
-type* F_GetReturnType (Function* F);
+Type* F_GetReturnType (Function* F);
/* Get the return type for the function */
int F_HasVoidReturn (const Function* F);
* nothing if there is no reserved local space.
*/
-int F_AllocRegVar (Function* F, const type* Type);
+int F_AllocRegVar (Function* F, const Type* Type);
/* Allocate a register variable for the given variable type. If the allocation
* was successful, return the offset of the register variable in the register
* bank (zero page storage). If there is no register space left, return -1.
double FVal; /* The float attribute */
ident Ident; /* Identifier if IDENT */
LineInfo* LI; /* Source line where the token comes from */
- type* Type; /* Type if integer or float constant */
+ Type* Type; /* Type if integer or float constant */
};
extern Token CurTok; /* The current token */
/* */
/* */
/* */
-/* (C) 2004 Ullrich von Bassewitz */
+/* (C) 2004-2006 Ullrich von Bassewitz */
/* Römerstraße 52 */
/* D-70794 Filderstadt */
/* EMail: uz@cc65.org */
CodeMark Mark1;
CodeMark Mark2;
token_t Tok; /* The operator token */
- type* EffType; /* Effective lhs type */
- type* ResultType; /* Type of the result */
+ Type* EffType; /* Effective lhs type */
+ Type* ResultType; /* Type of the result */
unsigned ExprBits; /* Bits of the lhs operand */
unsigned GenFlags; /* Generator flags */
unsigned ltype;
(ED_IsLocConst (Expr) || ED_IsLocStack (Expr)) &&
Expr2.IVal >= 8) {
- type* OldType;
+ Type* OldType;
/* Increase the address by one and decrease the shift count */
++Expr->IVal;
/* */
/* */
/* */
-/* (C) 2004 Ullrich von Bassewitz */
+/* (C) 2004-2006 Ullrich von Bassewitz */
/* Römerstraße 52 */
/* D-70794 Filderstadt */
/* EMail: uz@cc65.org */
-void SP_Push (const type* T)
+void SP_Push (const Type* T)
/* Adjust the stackpointer for a push of an argument of the given type */
{
StackPtr -= SizeOf (T);
-void SP_Pop (const type* T)
+void SP_Pop (const Type* T)
/* Adjust the stackpointer for a pop of an argument of the given type */
-{
+{
StackPtr += SizeOf (T);
}
-
+
/* */
/* */
/* */
-/* (C) 2004 Ullrich von Bassewitz */
+/* (C) 2004-2006 Ullrich von Bassewitz */
/* Römerstraße 52 */
/* D-70794 Filderstadt */
/* EMail: uz@cc65.org */
#define STACKPTR_H
-
+
/* cc65 */
#include "datatype.h"
-void SP_Push (const type* T);
+void SP_Push (const Type* T);
/* Adjust the stackpointer for a push of an argument of the given type */
-void SP_Pop (const type* T);
+void SP_Pop (const Type* T);
/* Adjust the stackpointer for a pop of an argument of the given type */
/* */
/* */
/* */
-/* (C) 1998-2004 Ullrich von Bassewitz */
+/* (C) 1998-2006 Ullrich von Bassewitz */
/* Römerstrasse 52 */
/* D-70794 Filderstadt */
/* EMail: uz@cc65.org */
typedef struct ArgDesc ArgDesc;
struct ArgDesc {
- const type* ArgType; /* Required argument type */
+ const Type* ArgType; /* Required argument type */
ExprDesc Expr; /* Argument expression */
- const type* Type; /* The original type before conversion */
+ const Type* Type; /* The original type before conversion */
CodeMark Start; /* Start of the code for calculation */
CodeMark Push; /* Start of argument push code */
CodeMark End; /* End of the code for calculation+push */
-static void ParseArg (ArgDesc* Arg, type* Type)
+static void ParseArg (ArgDesc* Arg, Type* Type)
/* Parse one argument but do not push it onto the stack. Make all fields in
* Arg valid.
*/
static void StdFunc_memcpy (FuncDesc* F attribute ((unused)), ExprDesc* Expr)
/* Handle the memcpy function */
{
- /* Argument types */
- static type Arg1Type[] = { T_PTR, T_VOID, T_END }; /* void* */
- static type Arg2Type[] = { T_PTR, T_VOID|T_QUAL_CONST, T_END }; /* const void* */
- static type Arg3Type[] = { T_SIZE_T, T_END }; /* size_t */
+ /* Argument types: (void*, const void*, size_t) */
+ static Type Arg1Type[] = { TYPE(T_PTR), TYPE(T_VOID), TYPE(T_END) };
+ static Type Arg2Type[] = { TYPE(T_PTR), TYPE(T_VOID|T_QUAL_CONST), TYPE(T_END) };
+ static Type Arg3Type[] = { TYPE(T_SIZE_T), TYPE(T_END) };
CodeMark Start;
ArgDesc Arg1, Arg2, Arg3;
static void StdFunc_memset (FuncDesc* F attribute ((unused)), ExprDesc* Expr)
/* Handle the memset function */
{
- /* Argument types */
- static type Arg1Type[] = { T_PTR, T_VOID, T_END }; /* void* */
- static type Arg2Type[] = { T_INT, T_END }; /* int */
- static type Arg3Type[] = { T_SIZE_T, T_END }; /* size_t */
+ /* Argument types: (void*, int, size_t) */
+ static Type Arg1Type[] = { TYPE(T_PTR), TYPE(T_VOID), TYPE(T_END) };
+ static Type Arg2Type[] = { TYPE(T_INT), TYPE(T_END) };
+ static Type Arg3Type[] = { TYPE(T_SIZE_T), TYPE(T_END) };
CodeMark Start;
ArgDesc Arg1, Arg2, Arg3;
static void StdFunc_strcpy (FuncDesc* F attribute ((unused)), ExprDesc* Expr)
/* Handle the strcpy function */
{
- /* Argument types */
- static type Arg1Type[] = { T_PTR, T_CHAR, T_END }; /* char* */
- static type Arg2Type[] = { T_PTR, T_CHAR|T_QUAL_CONST, T_END }; /* const char* */
+ /* Argument types: (char*, const char*) */
+ static Type Arg1Type[] = { TYPE(T_PTR), TYPE(T_CHAR), TYPE(T_END) };
+ static Type Arg2Type[] = { TYPE(T_PTR), TYPE(T_CHAR|T_QUAL_CONST), TYPE(T_END) };
CodeMark Start;
ArgDesc Arg1, Arg2;
unsigned L1;
/* Setup the argument type string */
- Arg1Type[1] = GetDefaultChar ();
- Arg2Type[1] = GetDefaultChar () | T_QUAL_CONST;
+ Arg1Type[1].C = GetDefaultChar ();
+ Arg2Type[1].C = GetDefaultChar () | T_QUAL_CONST;
/* Remember where we are now */
GetCodePos (&Start);
static void StdFunc_strlen (FuncDesc* F attribute ((unused)), ExprDesc* Expr)
/* Handle the strlen function */
{
- static type ArgType[] = { T_PTR, T_SCHAR, T_END };
+ static Type ArgType[] = { TYPE(T_PTR), TYPE(T_CHAR|T_QUAL_CONST), TYPE(T_END) };
ExprDesc Arg;
int IsArray;
int IsPtr;
/* Setup the argument type string */
- ArgType[1] = GetDefaultChar () | T_QUAL_CONST;
+ ArgType[1].C = GetDefaultChar () | T_QUAL_CONST;
/* Evaluate the parameter */
hie1 (&Arg);
/* */
/* */
/* */
-/* (C) 1998-2004 Ullrich von Bassewitz */
+/* (C) 1998-2006 Ullrich von Bassewitz */
/* Römerstraße 52 */
/* D-70794 Filderstadt */
/* EMail: uz@cc65.org */
Collection* Nodes; /* CaseNode tree */
ExprDesc SwitchExpr; /* Switch statement expression */
ExprDesc CaseExpr; /* Case label expression */
- type SwitchExprType; /* Basic switch expression type */
+ TypeCode SwitchExprType; /* Basic switch expression type */
CodeMark CaseCodeStart; /* Start of code marker */
CodeMark SwitchCodeStart; /* Start of switch code */
CodeMark SwitchCodeEnd; /* End of switch code */
ConsumeLCurly ();
/* Get the unqualified type of the switch expression */
- SwitchExprType = UnqualifiedType (SwitchExpr.Type[0]);
+ SwitchExprType = UnqualifiedType (SwitchExpr.Type[0].C);
/* Get the number of bytes the selector type has */
Depth = SizeOf (SwitchExpr.Type);
break;
default:
- Internal ("Invalid type: %04X", SwitchExprType);
+ Internal ("Invalid type: %06lX", SwitchExprType);
}
/* Insert the case selector into the selector table */
/* */
/* */
/* */
-/* (C) 2000-2002 Ullrich von Bassewitz */
-/* Wacholderweg 14 */
-/* D-70597 Stuttgart */
+/* (C) 2000-2006 Ullrich von Bassewitz */
+/* Römerstrasse 52 */
+/* D-70794 Filderstadt */
/* EMail: uz@cc65.org */
/* */
/* */
-void ChangeSymType (SymEntry* Entry, type* Type)
+void ChangeSymType (SymEntry* Entry, Type* T)
/* Change the type of the given symbol */
{
TypeFree (Entry->Type);
- Entry->Type = TypeDup (Type);
+ Entry->Type = TypeDup (T);
}
/* */
/* */
/* */
-/* (C) 2000-2002 Ullrich von Bassewitz */
-/* Wacholderweg 14 */
-/* D-70597 Stuttgart */
+/* (C) 2000-2006 Ullrich von Bassewitz */
+/* Römerstrasse 52 */
+/* D-70794 Filderstadt */
/* EMail: uz@cc65.org */
/* */
/* */
SymEntry* Link; /* General purpose single linked list */
struct SymTable* Owner; /* Symbol table the symbol is in */
unsigned Flags; /* Symbol flags */
- type* Type; /* Symbol type */
+ Type* Type; /* Symbol type */
char* AsmName; /* Assembler name if any */
/* Data that differs for the different symbol types */
void CvtRegVarToAuto (SymEntry* Sym);
/* Convert a register variable to an auto variable */
-void ChangeSymType (SymEntry* Entry, type* Type);
+void ChangeSymType (SymEntry* Entry, Type* T);
/* Change the type of the given symbol */
void ChangeAsmName (SymEntry* Entry, const char* NewAsmName);
/* */
/* */
/* */
-/* (C) 2000-2004 Ullrich von Bassewitz */
+/* (C) 2000-2006 Ullrich von Bassewitz */
/* Römerstrasse 52 */
/* D-70794 Filderstadt */
/* EMail: uz@cc65.org */
-SymEntry* FindStructField (const type* Type, const char* Name)
+SymEntry* FindStructField (const Type* T, const char* Name)
/* Find a struct field in the fields list */
{
SymEntry* Field = 0;
/* The given type may actually be a pointer to struct */
- if (Type[0] == T_PTR) {
- ++Type;
+ if (T->C == T_PTR) {
+ ++T;
}
/* Non-structs do not have any struct fields... */
- if (IsClassStruct (Type)) {
+ if (IsClassStruct (T)) {
const SymTable* Tab;
/* Get a pointer to the struct/union type */
- const SymEntry* Struct = (const SymEntry*) Decode (Type+1);
+ const SymEntry* Struct = GetSymEntry (T);
CHECK (Struct != 0);
/* Get the field symbol table from the struct entry.
-SymEntry* AddConstSym (const char* Name, const type* Type, unsigned Flags, long Val)
+SymEntry* AddConstSym (const char* Name, const Type* T, unsigned Flags, long Val)
/* Add an constant symbol to the symbol table and return it */
{
/* Enums must be inserted in the global symbol table */
Entry = NewSymEntry (Name, Flags);
/* Enum values are ints */
- Entry->Type = TypeDup (Type);
+ Entry->Type = TypeDup (T);
/* Set the enum data */
Entry->V.ConstVal = Val;
-SymEntry* AddLocalSym (const char* Name, const type* Type, unsigned Flags, int Offs)
+SymEntry* AddLocalSym (const char* Name, const Type* T, unsigned Flags, int Offs)
/* Add a local symbol and return the symbol entry */
{
/* Do we have an entry with this name already? */
Entry = NewSymEntry (Name, Flags);
/* Set the symbol attributes */
- Entry->Type = TypeDup (Type);
+ Entry->Type = TypeDup (T);
if ((Flags & SC_AUTO) == SC_AUTO) {
Entry->V.Offs = Offs;
} else if ((Flags & SC_REGISTER) == SC_REGISTER) {
Entry->V.R.RegOffs = Offs;
- Entry->V.R.SaveOffs = StackPtr;
+ Entry->V.R.SaveOffs = StackPtr;
} else if ((Flags & SC_STATIC) == SC_STATIC) {
/* Generate the assembler name from the label number */
Entry->V.Label = Offs;
-SymEntry* AddGlobalSym (const char* Name, const type* Type, unsigned Flags)
+SymEntry* AddGlobalSym (const char* Name, const Type* T, unsigned Flags)
/* Add an external or global symbol to the symbol table and return the entry */
{
/* There is some special handling for functions, so check if it is one */
- int IsFunc = IsTypeFunc (Type);
+ int IsFunc = IsTypeFunc (T);
/* Functions must be inserted in the global symbol table */
SymTable* Tab = IsFunc? SymTab0 : SymTab;
SymEntry* Entry = FindSymInTable (Tab, Name, HashStr (Name));
if (Entry) {
- type* EType;
+ Type* EType;
/* We have a symbol with this name already */
if (Entry->Flags & SC_TYPE) {
* incomplete declaration. Accept this, and if the exsting entry is
* incomplete, complete it.
*/
- if (IsTypeArray (Type) && IsTypeArray (EType)) {
+ if (IsTypeArray (T) && IsTypeArray (EType)) {
/* Get the array sizes */
- long Size = GetElementCount (Type);
+ long Size = GetElementCount (T);
long ESize = GetElementCount (EType);
if ((Size != UNSPECIFIED && ESize != UNSPECIFIED && Size != ESize) ||
- TypeCmp (Type+DECODE_SIZE+1, EType+DECODE_SIZE+1) < TC_EQUAL) {
+ TypeCmp (T + 1, EType + 1) < TC_EQUAL) {
/* Types not identical: Conflicting types */
Error ("Conflicting types for `%s'", Name);
- return Entry;
+ return Entry;
} else {
/* Check if we have a size in the existing definition */
if (ESize == UNSPECIFIED) {
/* Existing, size not given, use size from new def */
- Encode (EType + 1, Size);
+ SetElementCount (EType, Size);
}
}
} else {
/* New type must be identical */
- if (TypeCmp (EType, Type) < TC_EQUAL) {
+ if (TypeCmp (EType, T) < TC_EQUAL) {
Error ("Conflicting types for `%s'", Name);
return Entry;
}
*/
if (IsFunc) {
/* Get the function descriptor from the new type */
- FuncDesc* F = GetFuncDesc (Type);
+ FuncDesc* F = GetFuncDesc (T);
/* Use this new function descriptor */
Entry->V.F.Func = F;
- EncodePtr (EType+1, F);
+ SetFuncDesc (EType, F);
}
}
Entry = NewSymEntry (Name, Flags);
/* Set the symbol attributes */
- Entry->Type = TypeDup (Type);
+ Entry->Type = TypeDup (T);
/* If this is a function, set the function descriptor and clear
* additional fields.
SymEntry* FindTagSym (const char* Name);
/* Find the symbol with the given name in the tag table */
-SymEntry* FindStructField (const type* TypeArray, const char* Name);
+SymEntry* FindStructField (const Type* TypeArray, const char* Name);
/* Find a struct field in the fields list */
SymEntry* AddStructSym (const char* Name, unsigned Size, SymTable* Tab);
/* Add a struct/union entry and return it */
-SymEntry* AddConstSym (const char* Name, const type* Type, unsigned Flags, long Val);
+SymEntry* AddConstSym (const char* Name, const Type* T, unsigned Flags, long Val);
/* Add an constant symbol to the symbol table and return it */
SymEntry* AddLabelSym (const char* Name, unsigned Flags);
/* Add a goto label to the symbol table */
-SymEntry* AddLocalSym (const char* Name, const type* Type, unsigned Flags, int Offs);
+SymEntry* AddLocalSym (const char* Name, const Type* T, unsigned Flags, int Offs);
/* Add a local symbol and return the symbol entry */
-SymEntry* AddGlobalSym (const char* Name, const type* Type, unsigned Flags);
+SymEntry* AddGlobalSym (const char* Name, const Type* T, unsigned Flags);
/* Add an external or global symbol to the symbol table and return the entry */
-static void DoCompare (const type* lhs, const type* rhs, typecmp_t* Result)
+static void DoCompare (const Type* lhs, const Type* rhs, typecmp_t* Result)
/* Recursively compare two types. */
{
unsigned Indirections;
ElementCount = 0;
/* Compare two types. Determine, where they differ */
- while (*lhs != T_END) {
+ while (lhs->C != T_END) {
- type LeftType, RightType;
- type LeftSign, RightSign;
- type LeftQual, RightQual;
+ TypeCode LeftType, RightType;
+ TypeCode LeftSign, RightSign;
+ TypeCode LeftQual, RightQual;
long LeftCount, RightCount;
/* Check if the end of the type string is reached */
- if (*rhs == T_END) {
+ if (rhs->C == T_END) {
/* End of comparison reached */
return;
}
*/
if (LeftType == T_TYPE_PTR && RightType == T_TYPE_ARRAY) {
RightType = T_TYPE_PTR;
- rhs += DECODE_SIZE;
}
/* If the raw types are not identical, the types are incompatible */
case T_TYPE_FUNC:
/* Compare the function descriptors */
- F1 = DecodePtr (lhs+1);
- F2 = DecodePtr (rhs+1);
+ F1 = GetFuncDesc (lhs);
+ F2 = GetFuncDesc (rhs);
/* If one of the functions is implicitly declared, both
* functions are considered equal. If one of the functions is
}
}
- /* Skip the FuncDesc pointers to compare the return type */
- lhs += DECODE_SIZE;
- rhs += DECODE_SIZE;
+ /* Keep on and compare the return type */
break;
case T_TYPE_ARRAY:
SetResult (Result, TC_INCOMPATIBLE);
return;
}
- lhs += DECODE_SIZE;
- rhs += DECODE_SIZE;
break;
case T_TYPE_STRUCT:
* pointer to the struct definition from the type, and compare
* the fields.
*/
- Sym1 = DecodePtr (lhs+1);
- Sym2 = DecodePtr (rhs+1);
+ Sym1 = GetSymEntry (lhs);
+ Sym2 = GetSymEntry (rhs);
/* If one symbol has a name, the names must be identical */
if (!HasAnonName (Sym1) || !HasAnonName (Sym2)) {
}
/* Structs are equal */
- lhs += DECODE_SIZE;
- rhs += DECODE_SIZE;
break;
}
}
/* Check if end of rhs reached */
- if (*rhs == T_END) {
+ if (rhs->C == T_END) {
SetResult (Result, TC_EQUAL);
} else {
SetResult (Result, TC_INCOMPATIBLE);
-typecmp_t TypeCmp (const type* lhs, const type* rhs)
+typecmp_t TypeCmp (const Type* lhs, const Type* rhs)
/* Compare two types and return the result */
{
/* Assume the types are identical */
+
-typecmp_t TypeCmp (const type* lhs, const type* rhs);
+typecmp_t TypeCmp (const Type* lhs, const Type* rhs);
/* Compare two types and return the result */
/* */
/* */
/* */
-/* (C) 2002-2004 Ullrich von Bassewitz */
+/* (C) 2002-2006 Ullrich von Bassewitz */
/* Römerstrasse 52 */
/* D-70794 Filderstadt */
/* EMail: uz@cc65.org */
-static void DoConversion (ExprDesc* Expr, const type* NewType)
+static void DoConversion (ExprDesc* Expr, const Type* NewType)
/* Emit code to convert the given expression to a new type. */
{
- type* OldType;
+ Type* OldType;
unsigned OldSize;
unsigned NewSize;
-void TypeConversion (ExprDesc* Expr, type* NewType)
+void TypeConversion (ExprDesc* Expr, Type* NewType)
/* Do an automatic conversion of the given expression to the new type. Output
* warnings or errors where this automatic conversion is suspicious or
* impossible.
* expression is an lvalue and false if not.
*/
{
- type NewType[MAXTYPELEN];
+ Type NewType[MAXTYPELEN];
/* Skip the left paren */
NextToken ();
+
/* */
/* */
/* */
-/* (C) 2002-2004 Ullrich von Bassewitz */
+/* (C) 2002-2006 Ullrich von Bassewitz */
/* Römerstrasse 52 */
/* D-70794 Filderstadt */
/* EMail: uz@cc65.org */
-void TypeConversion (ExprDesc* Expr, type* NewType);
+void TypeConversion (ExprDesc* Expr, Type* NewType);
/* Do an automatic conversion of the given expression to the new type. Output
* warnings or errors where this automatic conversion is suspicious or
* impossible.