Changed the low level type representation from a strung of unsigned short
elements to a string of structs, each representing one type element. This should fix problems on unusual architectures, since it is no longer necessary to embedd pointers and other data converted to numbers in the string of unsigned shorts. Increased the TypeCode length to unsigned long to make room for more type bits. Inline more functions in datatype.h. git-svn-id: svn://svn.cc65.org/cc65/trunk@3709 b7a2c559-68d2-44c3-8de9-860c34a00d81
This commit is contained in:
parent
1375c85405
commit
de3a20a898
26 changed files with 636 additions and 633 deletions
|
@ -6,7 +6,7 @@
|
||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* (C) 2002-2004 Ullrich von Bassewitz */
|
/* (C) 2002-2006 Ullrich von Bassewitz */
|
||||||
/* Römerstrasse 52 */
|
/* Römerstrasse 52 */
|
||||||
/* D-70794 Filderstadt */
|
/* D-70794 Filderstadt */
|
||||||
/* EMail: uz@cc65.org */
|
/* EMail: uz@cc65.org */
|
||||||
|
@ -57,7 +57,7 @@ void Assignment (ExprDesc* Expr)
|
||||||
/* Parse an assignment */
|
/* Parse an assignment */
|
||||||
{
|
{
|
||||||
ExprDesc Expr2;
|
ExprDesc Expr2;
|
||||||
type* ltype = Expr->Type;
|
Type* ltype = Expr->Type;
|
||||||
|
|
||||||
|
|
||||||
/* We must have an lvalue for an assignment */
|
/* We must have an lvalue for an assignment */
|
||||||
|
@ -87,7 +87,7 @@ void Assignment (ExprDesc* Expr)
|
||||||
* the former case, push the address only if really needed.
|
* the former case, push the address only if really needed.
|
||||||
*/
|
*/
|
||||||
int UseReg = 1;
|
int UseReg = 1;
|
||||||
type* stype;
|
Type* stype;
|
||||||
switch (Size) {
|
switch (Size) {
|
||||||
case SIZEOF_CHAR: stype = type_uchar; break;
|
case SIZEOF_CHAR: stype = type_uchar; break;
|
||||||
case SIZEOF_INT: stype = type_uint; break;
|
case SIZEOF_INT: stype = type_uint; break;
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* (C) 2001-2005, Ullrich von Bassewitz */
|
/* (C) 2001-2006, Ullrich von Bassewitz */
|
||||||
/* Römerstrasse 52 */
|
/* Römerstrasse 52 */
|
||||||
/* D-70794 Filderstadt */
|
/* D-70794 Filderstadt */
|
||||||
/* EMail: uz@cc65.org */
|
/* EMail: uz@cc65.org */
|
||||||
|
@ -449,7 +449,7 @@ CodeSeg* NewCodeSeg (const char* SegName, SymEntry* Func)
|
||||||
/* Create a new code segment, initialize and return it */
|
/* Create a new code segment, initialize and return it */
|
||||||
{
|
{
|
||||||
unsigned I;
|
unsigned I;
|
||||||
const type* RetType;
|
const Type* RetType;
|
||||||
|
|
||||||
/* Allocate memory */
|
/* Allocate memory */
|
||||||
CodeSeg* S = xmalloc (sizeof (CodeSeg));
|
CodeSeg* S = xmalloc (sizeof (CodeSeg));
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* (C) 1998-2004 Ullrich von Bassewitz */
|
/* (C) 1998-2006 Ullrich von Bassewitz */
|
||||||
/* Römerstraße 52 */
|
/* Römerstraße 52 */
|
||||||
/* D-70794 Filderstadt */
|
/* D-70794 Filderstadt */
|
||||||
/* EMail: uz@cc65.org */
|
/* EMail: uz@cc65.org */
|
||||||
|
@ -56,16 +56,16 @@
|
||||||
|
|
||||||
|
|
||||||
/* Predefined type strings */
|
/* Predefined type strings */
|
||||||
type type_schar[] = { T_SCHAR, T_END };
|
Type type_schar[] = { TYPE(T_SCHAR), TYPE(T_END) };
|
||||||
type type_uchar[] = { T_UCHAR, T_END };
|
Type type_uchar[] = { TYPE(T_UCHAR), TYPE(T_END) };
|
||||||
type type_int[] = { T_INT, T_END };
|
Type type_int[] = { TYPE(T_INT), TYPE(T_END) };
|
||||||
type type_uint[] = { T_UINT, T_END };
|
Type type_uint[] = { TYPE(T_UINT), TYPE(T_END) };
|
||||||
type type_long[] = { T_LONG, T_END };
|
Type type_long[] = { TYPE(T_LONG), TYPE(T_END) };
|
||||||
type type_ulong[] = { T_ULONG, T_END };
|
Type type_ulong[] = { TYPE(T_ULONG), TYPE(T_END) };
|
||||||
type type_void[] = { T_VOID, T_END };
|
Type type_void[] = { TYPE(T_VOID), TYPE(T_END) };
|
||||||
type type_size_t[] = { T_SIZE_T, T_END };
|
Type type_size_t[] = { TYPE(T_SIZE_T), TYPE(T_END) };
|
||||||
type type_float[] = { T_FLOAT, T_END };
|
Type type_float[] = { TYPE(T_FLOAT), TYPE(T_END) };
|
||||||
type type_double[] = { T_DOUBLE, T_END };
|
Type type_double[] = { TYPE(T_DOUBLE), TYPE(T_END) };
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -75,11 +75,11 @@ type type_double[] = { T_DOUBLE, T_END };
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
unsigned TypeLen (const type* T)
|
unsigned TypeLen (const Type* T)
|
||||||
/* Return the length of the type string */
|
/* Return the length of the type string */
|
||||||
{
|
{
|
||||||
const type* Start = T;
|
const Type* Start = T;
|
||||||
while (*T != T_END) {
|
while (T->C != T_END) {
|
||||||
++T;
|
++T;
|
||||||
}
|
}
|
||||||
return T - Start;
|
return T - Start;
|
||||||
|
@ -87,49 +87,43 @@ unsigned TypeLen (const type* T)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
type* TypeCpy (type* Dest, const type* Src)
|
Type* TypeCpy (Type* Dest, const Type* Src)
|
||||||
/* Copy a type string */
|
/* Copy a type string */
|
||||||
{
|
{
|
||||||
type T;
|
Type* Orig = Dest;
|
||||||
type* Orig = Dest;
|
while (1) {
|
||||||
do {
|
*Dest = *Src;
|
||||||
T = *Src++;
|
if (Src->C == T_END) {
|
||||||
*Dest++ = T;
|
break;
|
||||||
} while (T);
|
}
|
||||||
|
Src++;
|
||||||
|
Dest++;
|
||||||
|
}
|
||||||
return Orig;
|
return Orig;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
type* TypeCat (type* Dest, const type* Src)
|
Type* TypeDup (const Type* T)
|
||||||
/* Append Src */
|
|
||||||
{
|
|
||||||
TypeCpy (Dest + TypeLen (Dest), Src);
|
|
||||||
return Dest;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
type* TypeDup (const type* T)
|
|
||||||
/* Create a copy of the given type on the heap */
|
/* Create a copy of the given type on the heap */
|
||||||
{
|
{
|
||||||
unsigned Len = (TypeLen (T) + 1) * sizeof (type);
|
unsigned Len = (TypeLen (T) + 1) * sizeof (Type);
|
||||||
return (type*) memcpy (xmalloc (Len), T, Len);
|
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
|
/* Allocate memory for a type string of length Len. Len *must* include the
|
||||||
* trailing T_END.
|
* 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 */
|
/* Free a type string */
|
||||||
{
|
{
|
||||||
xfree (T);
|
xfree (T);
|
||||||
|
@ -149,7 +143,7 @@ int SignExtendChar (int C)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
type GetDefaultChar (void)
|
TypeCode GetDefaultChar (void)
|
||||||
/* Return the default char type (signed/unsigned) depending on the settings */
|
/* Return the default char type (signed/unsigned) depending on the settings */
|
||||||
{
|
{
|
||||||
return IS_Get (&SignedChars)? T_SCHAR : T_UCHAR;
|
return IS_Get (&SignedChars)? T_SCHAR : T_UCHAR;
|
||||||
|
@ -157,19 +151,17 @@ type GetDefaultChar (void)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
type* GetCharArrayType (unsigned Len)
|
Type* GetCharArrayType (unsigned Len)
|
||||||
/* Return the type for a char array of the given length */
|
/* Return the type for a char array of the given length */
|
||||||
{
|
{
|
||||||
/* Allocate memory for the type string */
|
/* Allocate memory for the type string */
|
||||||
type* T = TypeAlloc (1 + DECODE_SIZE + 2);
|
Type* T = TypeAlloc (3); /* array/char/terminator */
|
||||||
|
|
||||||
/* Fill the type string */
|
/* Fill the type string */
|
||||||
T [0] = T_ARRAY;
|
T[0].C = T_ARRAY;
|
||||||
T [DECODE_SIZE+1] = GetDefaultChar();
|
T[0].A.L = Len; /* Array length is in the L attribute */
|
||||||
T [DECODE_SIZE+2] = T_END;
|
T[1].C = GetDefaultChar ();
|
||||||
|
T[2].C = T_END;
|
||||||
/* Encode the length in the type string */
|
|
||||||
Encode (T+1, Len);
|
|
||||||
|
|
||||||
/* Return the new type */
|
/* Return the new type */
|
||||||
return T;
|
return T;
|
||||||
|
@ -177,14 +169,14 @@ type* GetCharArrayType (unsigned Len)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
type* GetImplicitFuncType (void)
|
Type* GetImplicitFuncType (void)
|
||||||
/* Return a type string for an inplicitly declared function */
|
/* Return a type string for an inplicitly declared function */
|
||||||
{
|
{
|
||||||
/* Get a new function descriptor */
|
/* Get a new function descriptor */
|
||||||
FuncDesc* F = NewFuncDesc ();
|
FuncDesc* F = NewFuncDesc ();
|
||||||
|
|
||||||
/* Allocate memory for the type string */
|
/* 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 */
|
/* Prepare the function descriptor */
|
||||||
F->Flags = FD_IMPLICIT | FD_EMPTY | FD_VARIADIC;
|
F->Flags = FD_IMPLICIT | FD_EMPTY | FD_VARIADIC;
|
||||||
|
@ -192,12 +184,10 @@ type* GetImplicitFuncType (void)
|
||||||
F->TagTab = &EmptySymTab;
|
F->TagTab = &EmptySymTab;
|
||||||
|
|
||||||
/* Fill the type string */
|
/* Fill the type string */
|
||||||
T [0] = T_FUNC;
|
T[0].C = T_FUNC;
|
||||||
T [DECODE_SIZE+1] = T_INT;
|
T[0].A.P = F;
|
||||||
T [DECODE_SIZE+2] = T_END;
|
T[1].C = T_INT;
|
||||||
|
T[2].C = T_END;
|
||||||
/* Encode the function descriptor into the type string */
|
|
||||||
EncodePtr (T+1, F);
|
|
||||||
|
|
||||||
/* Return the new type */
|
/* Return the new type */
|
||||||
return T;
|
return T;
|
||||||
|
@ -205,7 +195,7 @@ type* GetImplicitFuncType (void)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
type* PointerTo (const type* T)
|
Type* PointerTo (const Type* T)
|
||||||
/* Return a type string that is "pointer to T". The type string is allocated
|
/* Return a type string that is "pointer to T". The type string is allocated
|
||||||
* on the heap and may be freed after use.
|
* on the heap and may be freed after use.
|
||||||
*/
|
*/
|
||||||
|
@ -214,11 +204,11 @@ type* PointerTo (const type* T)
|
||||||
unsigned Size = TypeLen (T) + 1;
|
unsigned Size = TypeLen (T) + 1;
|
||||||
|
|
||||||
/* Allocate the new type string */
|
/* Allocate the new type string */
|
||||||
type* P = TypeAlloc (Size + 1);
|
Type* P = TypeAlloc (Size + 1);
|
||||||
|
|
||||||
/* Create the return type... */
|
/* Create the return type... */
|
||||||
P[0] = T_PTR;
|
P[0].C = T_PTR;
|
||||||
memcpy (P+1, T, Size * sizeof (type));
|
memcpy (P+1, T, Size * sizeof (Type));
|
||||||
|
|
||||||
/* ...and return it */
|
/* ...and return it */
|
||||||
return P;
|
return P;
|
||||||
|
@ -226,41 +216,42 @@ type* PointerTo (const type* T)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
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
|
/* 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.
|
* name and remove it. Return the type with the component removed.
|
||||||
*/
|
*/
|
||||||
{
|
{
|
||||||
if ((T & Mask) == Mask) {
|
if ((C & Mask) == Mask) {
|
||||||
fprintf (F, "%s ", Name);
|
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. */
|
/* Output translation of type array. */
|
||||||
{
|
{
|
||||||
type T;
|
/* Walk over the type string */
|
||||||
long Size;
|
while (T->C != T_END) {
|
||||||
|
|
||||||
/* Walk over the complete string */
|
/* Get the type code */
|
||||||
while ((T = *Type++) != T_END) {
|
TypeCode C = T->C;
|
||||||
|
|
||||||
/* Print any qualifiers */
|
/* Print any qualifiers */
|
||||||
T = PrintTypeComp (F, T, T_QUAL_CONST, "const");
|
C = PrintTypeComp (F, C, T_QUAL_CONST, "const");
|
||||||
T = PrintTypeComp (F, T, T_QUAL_VOLATILE, "volatile");
|
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 */
|
/* Signedness. Omit the signedness specifier for long and int */
|
||||||
if ((T & T_MASK_TYPE) != T_TYPE_INT && (T & T_MASK_TYPE) != T_TYPE_LONG) {
|
if ((C & T_MASK_TYPE) != T_TYPE_INT && (C & T_MASK_TYPE) != T_TYPE_LONG) {
|
||||||
T = PrintTypeComp (F, T, T_SIGN_SIGNED, "signed");
|
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 */
|
/* Now check the real type */
|
||||||
switch (T & T_MASK_TYPE) {
|
switch (C & T_MASK_TYPE) {
|
||||||
case T_TYPE_CHAR:
|
case T_TYPE_CHAR:
|
||||||
fprintf (F, "char");
|
fprintf (F, "char");
|
||||||
break;
|
break;
|
||||||
|
@ -286,49 +277,47 @@ void PrintType (FILE* F, const type* Type)
|
||||||
fprintf (F, "void");
|
fprintf (F, "void");
|
||||||
break;
|
break;
|
||||||
case T_TYPE_STRUCT:
|
case T_TYPE_STRUCT:
|
||||||
fprintf (F, "struct %s", ((SymEntry*) DecodePtr (Type))->Name);
|
fprintf (F, "struct %s", ((SymEntry*) T->A.P)->Name);
|
||||||
Type += DECODE_SIZE;
|
|
||||||
break;
|
break;
|
||||||
case T_TYPE_UNION:
|
case T_TYPE_UNION:
|
||||||
fprintf (F, "union %s", ((SymEntry*) DecodePtr (Type))->Name);
|
fprintf (F, "union %s", ((SymEntry*) T->A.P)->Name);
|
||||||
Type += DECODE_SIZE;
|
|
||||||
break;
|
break;
|
||||||
case T_TYPE_ARRAY:
|
case T_TYPE_ARRAY:
|
||||||
/* Recursive call */
|
/* Recursive call */
|
||||||
PrintType (F, Type + DECODE_SIZE);
|
PrintType (F, T + 1);
|
||||||
Size = Decode (Type);
|
if (T->A.L == UNSPECIFIED) {
|
||||||
if (Size == UNSPECIFIED) {
|
|
||||||
fprintf (F, "[]");
|
fprintf (F, "[]");
|
||||||
} else {
|
} else {
|
||||||
fprintf (F, "[%lu]", Size);
|
fprintf (F, "[%ld]", T->A.L);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
case T_TYPE_PTR:
|
case T_TYPE_PTR:
|
||||||
/* Recursive call */
|
/* Recursive call */
|
||||||
PrintType (F, Type);
|
PrintType (F, T + 1);
|
||||||
fprintf (F, "*");
|
fprintf (F, "*");
|
||||||
return;
|
return;
|
||||||
case T_TYPE_FUNC:
|
case T_TYPE_FUNC:
|
||||||
fprintf (F, "function returning ");
|
fprintf (F, "function returning ");
|
||||||
Type += DECODE_SIZE;
|
|
||||||
break;
|
break;
|
||||||
default:
|
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. */
|
/* Print a function signature. */
|
||||||
{
|
{
|
||||||
/* Get the function descriptor */
|
/* Get the function descriptor */
|
||||||
const FuncDesc* D = GetFuncDesc (Type);
|
const FuncDesc* D = GetFuncDesc (T);
|
||||||
|
|
||||||
/* Print a comment with the function signature */
|
/* Print a comment with the function signature */
|
||||||
PrintType (F, GetFuncReturn (Type));
|
PrintType (F, GetFuncReturn (T));
|
||||||
if (D->Flags & FD_NEAR) {
|
if (D->Flags & FD_NEAR) {
|
||||||
fprintf (F, " __near__");
|
fprintf (F, " __near__");
|
||||||
}
|
}
|
||||||
|
@ -364,82 +353,30 @@ void PrintFuncSig (FILE* F, const char* Name, type* Type)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void PrintRawType (FILE* F, const type* Type)
|
void PrintRawType (FILE* F, const Type* T)
|
||||||
/* Print a type string in raw format (for debugging) */
|
/* Print a type string in raw format (for debugging) */
|
||||||
{
|
{
|
||||||
while (*Type != T_END) {
|
while (T->C != T_END) {
|
||||||
fprintf (F, "%04X ", *Type++);
|
fprintf (F, "%04lX ", T->C);
|
||||||
|
++T;
|
||||||
}
|
}
|
||||||
fprintf (F, "\n");
|
fprintf (F, "\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void Encode (type* Type, unsigned long Val)
|
int TypeHasAttr (const Type* T)
|
||||||
/* Encode Val into the given type string */
|
/* Return true if the given type has attribute data */
|
||||||
{
|
{
|
||||||
int I;
|
return IsClassStruct (T) || IsTypeArray (T) || IsClassFunc (T);
|
||||||
for (I = 0; I < DECODE_SIZE; ++I) {
|
|
||||||
*Type++ = ((type) Val) | 0x8000;
|
|
||||||
Val >>= 15;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void EncodePtr (type* Type, void* P)
|
unsigned SizeOf (const Type* T)
|
||||||
/* 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 */
|
|
||||||
{
|
|
||||||
memcpy (Target, Source, DECODE_SIZE * sizeof (type));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
unsigned SizeOf (const type* T)
|
|
||||||
/* Compute size of object represented by type array. */
|
/* Compute size of object represented by type array. */
|
||||||
{
|
{
|
||||||
SymEntry* Entry;
|
switch (UnqualifiedType (T->C)) {
|
||||||
long ElementCount;
|
|
||||||
|
|
||||||
switch (UnqualifiedType (T[0])) {
|
|
||||||
|
|
||||||
case T_VOID:
|
case T_VOID:
|
||||||
return 0; /* Assume voids have size zero */
|
return 0; /* Assume voids have size zero */
|
||||||
|
@ -479,20 +416,18 @@ unsigned SizeOf (const type* T)
|
||||||
|
|
||||||
case T_STRUCT:
|
case T_STRUCT:
|
||||||
case T_UNION:
|
case T_UNION:
|
||||||
Entry = DecodePtr (T+1);
|
return ((SymEntry*) T->A.P)->V.S.Size;
|
||||||
return Entry->V.S.Size;
|
|
||||||
|
|
||||||
case T_ARRAY:
|
case T_ARRAY:
|
||||||
ElementCount = GetElementCount (T);
|
if (T->A.L == UNSPECIFIED) {
|
||||||
if (ElementCount == UNSPECIFIED) {
|
|
||||||
/* Array with unspecified size */
|
/* Array with unspecified size */
|
||||||
return 0;
|
return 0;
|
||||||
} else {
|
} else {
|
||||||
return ElementCount * SizeOf (T + DECODE_SIZE + 1);
|
return T->A.L * SizeOf (T + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
Internal ("Unknown type in SizeOf: %04X", *T);
|
Internal ("Unknown type in SizeOf: %04lX", T->C);
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -500,23 +435,19 @@ unsigned SizeOf (const type* T)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
unsigned PSizeOf (const type* T)
|
unsigned PSizeOf (const Type* T)
|
||||||
/* Compute size of pointer object. */
|
/* Compute size of pointer object. */
|
||||||
{
|
{
|
||||||
/* We are expecting a pointer expression */
|
/* 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 */
|
/* Skip the pointer or array token itself */
|
||||||
if (IsTypeArray (T)) {
|
return SizeOf (T + 1);
|
||||||
return SizeOf (T + DECODE_SIZE + 1);
|
|
||||||
} else {
|
|
||||||
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 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
|
* return some valid size instead (so the rest of the compiler doesn't have
|
||||||
* to work with invalid sizes).
|
* to work with invalid sizes).
|
||||||
|
@ -532,7 +463,7 @@ unsigned CheckedSizeOf (const type* T)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
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
|
/* 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
|
* 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).
|
* rest of the compiler doesn't have to work with invalid sizes).
|
||||||
|
@ -548,12 +479,10 @@ unsigned CheckedPSizeOf (const type* T)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
unsigned TypeOf (const type* T)
|
unsigned TypeOf (const Type* T)
|
||||||
/* Get the code generator base type of the object */
|
/* Get the code generator base type of the object */
|
||||||
{
|
{
|
||||||
FuncDesc* F;
|
switch (UnqualifiedType (T->C)) {
|
||||||
|
|
||||||
switch (UnqualifiedType (T[0])) {
|
|
||||||
|
|
||||||
case T_SCHAR:
|
case T_SCHAR:
|
||||||
return CF_CHAR;
|
return CF_CHAR;
|
||||||
|
@ -584,8 +513,7 @@ unsigned TypeOf (const type* T)
|
||||||
return CF_FLOAT;
|
return CF_FLOAT;
|
||||||
|
|
||||||
case T_FUNC:
|
case T_FUNC:
|
||||||
F = DecodePtr (T+1);
|
return (((FuncDesc*) T->A.P)->Flags & FD_VARIADIC)? 0 : CF_FIXARGC;
|
||||||
return (F->Flags & FD_VARIADIC)? 0 : CF_FIXARGC;
|
|
||||||
|
|
||||||
case T_STRUCT:
|
case T_STRUCT:
|
||||||
case T_UNION:
|
case T_UNION:
|
||||||
|
@ -593,100 +521,54 @@ unsigned TypeOf (const type* T)
|
||||||
return CF_INT | CF_UNSIGNED;
|
return CF_INT | CF_UNSIGNED;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
Error ("Illegal type");
|
Error ("Illegal type %04lX", T->C);
|
||||||
return CF_INT;
|
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
|
/* Do one indirection for the given type, that is, return the type where the
|
||||||
* given type points to.
|
* given type points to.
|
||||||
*/
|
*/
|
||||||
{
|
{
|
||||||
/* We are expecting a pointer expression */
|
/* 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 */
|
/* Skip the pointer or array token itself */
|
||||||
if (IsTypeArray (T)) {
|
return T + 1;
|
||||||
return T + DECODE_SIZE + 1;
|
|
||||||
} else {
|
|
||||||
return T + 1;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
type* ArrayToPtr (const type* T)
|
Type* ArrayToPtr (const Type* T)
|
||||||
/* Convert an array to a pointer to it's first element */
|
/* Convert an array to a pointer to it's first element */
|
||||||
{
|
{
|
||||||
/* Function must only be called for an array */
|
/* 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 pointer to first element */
|
||||||
return PointerTo (T + DECODE_SIZE + 1);
|
return PointerTo (T + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int IsClassInt (const type* T)
|
TypeCode GetQualifier (const Type* T)
|
||||||
/* Return true if this is an integer type */
|
/* Get the qualifier from the given type string */
|
||||||
{
|
{
|
||||||
return (T[0] & T_MASK_CLASS) == T_CLASS_INT;
|
/* 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 IsClassFloat (const type* T)
|
int IsFastCallFunc (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;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
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 */
|
|
||||||
{
|
|
||||||
return (GetQualifier (T) & T_QUAL_VOLATILE) != 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int IsFastCallFunc (const type* T)
|
|
||||||
/* Return true if this is a function type or pointer to function with
|
/* Return true if this is a function type or pointer to function with
|
||||||
* __fastcall__ calling conventions
|
* __fastcall__ calling conventions
|
||||||
*/
|
*/
|
||||||
|
@ -697,7 +579,7 @@ int IsFastCallFunc (const type* T)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int IsVariadicFunc (const type* T)
|
int IsVariadicFunc (const Type* T)
|
||||||
/* Return true if this is a function type or pointer to function type with
|
/* Return true if this is a function type or pointer to function type with
|
||||||
* variable parameter list
|
* variable parameter list
|
||||||
*/
|
*/
|
||||||
|
@ -708,76 +590,113 @@ int IsVariadicFunc (const type* T)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
type GetQualifier (const type* T)
|
FuncDesc* GetFuncDesc (const Type* T)
|
||||||
/* Get the qualifier from the given type string */
|
|
||||||
{
|
|
||||||
/* If this is an array, look at the element type, otherwise look at the
|
|
||||||
* type itself.
|
|
||||||
*/
|
|
||||||
if (IsTypeArray (T)) {
|
|
||||||
T += DECODE_SIZE + 1;
|
|
||||||
}
|
|
||||||
return (T[0] & T_MASK_QUAL);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
FuncDesc* GetFuncDesc (const type* T)
|
|
||||||
/* Get the FuncDesc pointer from a function or pointer-to-function type */
|
/* Get the FuncDesc pointer from a function or pointer-to-function type */
|
||||||
{
|
{
|
||||||
if (UnqualifiedType (T[0]) == T_PTR) {
|
if (UnqualifiedType (T->C) == T_PTR) {
|
||||||
/* Pointer to function */
|
/* Pointer to function */
|
||||||
++T;
|
++T;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Be sure it's a function type */
|
/* Be sure it's a function type */
|
||||||
CHECK (T[0] == T_FUNC);
|
CHECK (IsClassFunc (T));
|
||||||
|
|
||||||
/* Decode the function descriptor and return it */
|
/* Get the function descriptor from the type attributes */
|
||||||
return DecodePtr (T+1);
|
return T->A.P;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
type* GetFuncReturn (type* T)
|
void SetFuncDesc (Type* T, FuncDesc* F)
|
||||||
|
/* Set the FuncDesc pointer in a function or pointer-to-function type */
|
||||||
|
{
|
||||||
|
if (UnqualifiedType (T->C) == T_PTR) {
|
||||||
|
/* Pointer to function */
|
||||||
|
++T;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Be sure it's a function type */
|
||||||
|
CHECK (IsClassFunc (T));
|
||||||
|
|
||||||
|
/* Set the function descriptor */
|
||||||
|
T->A.P = F;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Type* GetFuncReturn (Type* T)
|
||||||
/* Return a pointer to the return type of a function or pointer-to-function type */
|
/* Return a pointer to the return type of a function or pointer-to-function type */
|
||||||
{
|
{
|
||||||
if (UnqualifiedType (T[0]) == T_PTR) {
|
if (UnqualifiedType (T->C) == T_PTR) {
|
||||||
/* Pointer to function */
|
/* Pointer to function */
|
||||||
++T;
|
++T;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Be sure it's a function type */
|
/* Be sure it's a function type */
|
||||||
CHECK (T[0] == T_FUNC);
|
CHECK (IsClassFunc (T));
|
||||||
|
|
||||||
/* Return a pointer to the return type */
|
/* 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
|
/* Get the element count of the array specified in T (which must be of
|
||||||
* array type).
|
* array type).
|
||||||
*/
|
*/
|
||||||
{
|
{
|
||||||
CHECK (IsTypeArray (T));
|
CHECK (IsTypeArray (T));
|
||||||
return Decode (T+1);
|
return T->A.L;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
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).
|
||||||
|
*/
|
||||||
|
{
|
||||||
|
CHECK (IsTypeArray (T));
|
||||||
|
T->A.L = Count;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Type* GetElementType (Type* T)
|
||||||
/* Return the element type of the given array type. */
|
/* Return the element type of the given array type. */
|
||||||
{
|
{
|
||||||
CHECK (IsTypeArray (T));
|
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
|
/* 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.
|
* string may be T if there is no need to change it.
|
||||||
*/
|
*/
|
||||||
|
@ -797,11 +716,11 @@ type* IntPromotion (type* T)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
type* PtrConversion (type* T)
|
Type* PtrConversion (Type* T)
|
||||||
/* If the type is a function, convert it to pointer to function. If the
|
/* 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
|
* expression is an array, convert it to pointer to first element. Otherwise
|
||||||
* return T.
|
* return T.
|
||||||
*/
|
*/
|
||||||
{
|
{
|
||||||
if (IsTypeFunc (T)) {
|
if (IsTypeFunc (T)) {
|
||||||
return PointerTo (T);
|
return PointerTo (T);
|
||||||
|
@ -814,3 +733,4 @@ type* PtrConversion (type* T)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* (C) 1998-2004 Ullrich von Bassewitz */
|
/* (C) 1998-2006 Ullrich von Bassewitz */
|
||||||
/* Römerstrasse 52 */
|
/* Römerstrasse 52 */
|
||||||
/* D-70794 Filderstadt */
|
/* D-70794 Filderstadt */
|
||||||
/* EMail: uz@cc65.org */
|
/* EMail: uz@cc65.org */
|
||||||
|
@ -135,15 +135,26 @@ enum {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* Type code entry */
|
||||||
|
typedef unsigned long TypeCode;
|
||||||
|
|
||||||
/* Type entry */
|
/* 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 */
|
/* Maximum length of a type string */
|
||||||
#define MAXTYPELEN 30
|
#define MAXTYPELEN 30
|
||||||
|
|
||||||
/* Type elements needed for Encode/Decode */
|
|
||||||
#define DECODE_SIZE 5
|
|
||||||
|
|
||||||
/* Special encodings for element counts of an array */
|
/* Special encodings for element counts of an array */
|
||||||
#define UNSPECIFIED -1L /* Element count was not specified */
|
#define UNSPECIFIED -1L /* Element count was not specified */
|
||||||
#define FLEXIBLE 0L /* Flexible array struct member */
|
#define FLEXIBLE 0L /* Flexible array struct member */
|
||||||
|
@ -159,16 +170,19 @@ typedef unsigned short type;
|
||||||
#define SIZEOF_PTR 2
|
#define SIZEOF_PTR 2
|
||||||
|
|
||||||
/* Predefined type strings */
|
/* Predefined type strings */
|
||||||
extern type type_schar[];
|
extern Type type_schar[];
|
||||||
extern type type_uchar[];
|
extern Type type_uchar[];
|
||||||
extern type type_int[];
|
extern Type type_int[];
|
||||||
extern type type_uint[];
|
extern Type type_uint[];
|
||||||
extern type type_long[];
|
extern Type type_long[];
|
||||||
extern type type_ulong[];
|
extern Type type_ulong[];
|
||||||
extern type type_void[];
|
extern Type type_void[];
|
||||||
extern type type_size_t[];
|
extern Type type_size_t[];
|
||||||
extern type type_float[];
|
extern Type type_float[];
|
||||||
extern type type_double[];
|
extern Type type_double[];
|
||||||
|
|
||||||
|
/* Forward for the SymEntry struct */
|
||||||
|
struct SymEntry;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -178,73 +192,65 @@ extern type type_double[];
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
unsigned TypeLen (const type* Type);
|
unsigned TypeLen (const Type* T);
|
||||||
/* Return the length of the type string */
|
/* 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 */
|
/* Copy a type string */
|
||||||
|
|
||||||
type* TypeCat (type* Dest, const type* Src);
|
Type* TypeDup (const Type* T);
|
||||||
/* Append Src */
|
|
||||||
|
|
||||||
type* TypeDup (const type* Type);
|
|
||||||
/* Create a copy of the given type on the heap */
|
/* 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
|
/* Allocate memory for a type string of length Len. Len *must* include the
|
||||||
* trailing T_END.
|
* trailing T_END.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void TypeFree (type* Type);
|
void TypeFree (Type* T);
|
||||||
/* Free a type string */
|
/* Free a type string */
|
||||||
|
|
||||||
int SignExtendChar (int C);
|
int SignExtendChar (int C);
|
||||||
/* Do correct sign extension of a character */
|
/* Do correct sign extension of a character */
|
||||||
|
|
||||||
type GetDefaultChar (void);
|
TypeCode GetDefaultChar (void);
|
||||||
/* Return the default char type (signed/unsigned) depending on the settings */
|
/* 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 */
|
/* 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 */
|
/* 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
|
/* Return a type string that is "pointer to T". The type string is allocated
|
||||||
* on the heap and may be freed after use.
|
* 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. */
|
/* 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) */
|
/* 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. */
|
/* Print a function signature. */
|
||||||
|
|
||||||
void Encode (type* Type, unsigned long Val);
|
int TypeHasAttr (const Type* T);
|
||||||
/* Encode Val into the given type string */
|
/* Return true if the given type has attribute data */
|
||||||
|
|
||||||
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 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)
|
#if defined(HAVE_INLINE)
|
||||||
INLINE type UnqualifiedType (type T)
|
INLINE void CopyTypeAttr (const Type* Src, Type* Dest)
|
||||||
/* Return the unqalified type */
|
/* 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 TypeCode UnqualifiedType (TypeCode T)
|
||||||
|
/* Return the unqalified type code */
|
||||||
{
|
{
|
||||||
return (T & ~T_MASK_QUAL);
|
return (T & ~T_MASK_QUAL);
|
||||||
}
|
}
|
||||||
|
@ -252,249 +258,322 @@ INLINE type UnqualifiedType (type T)
|
||||||
# define UnqualifiedType(T) ((T) & ~T_MASK_QUAL)
|
# define UnqualifiedType(T) ((T) & ~T_MASK_QUAL)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
unsigned SizeOf (const type* Type);
|
unsigned SizeOf (const Type* T);
|
||||||
/* Compute size of object represented by type array. */
|
/* Compute size of object represented by type array. */
|
||||||
|
|
||||||
unsigned PSizeOf (const type* Type);
|
unsigned PSizeOf (const Type* T);
|
||||||
/* Compute size of pointer object. */
|
/* 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 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
|
* return some valid size instead (so the rest of the compiler doesn't have
|
||||||
* to work with invalid sizes).
|
* 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
|
/* 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
|
* 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).
|
* 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 */
|
/* 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
|
/* Do one indirection for the given type, that is, return the type where the
|
||||||
* given type points to.
|
* 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 */
|
/* Convert an array to a pointer to it's first element */
|
||||||
|
|
||||||
#if defined(HAVE_INLINE)
|
#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 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
|
#else
|
||||||
# define IsTypeChar(T) (((T)[0] & T_MASK_TYPE) == T_TYPE_CHAR)
|
# define IsTypeChar(T) (((T)->C & T_MASK_TYPE) == T_TYPE_CHAR)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(HAVE_INLINE)
|
#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 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
|
#else
|
||||||
# define IsTypeInt(T) (((T)[0] & T_MASK_TYPE) == T_TYPE_INT)
|
# define IsTypeInt(T) (((T)->C & T_MASK_TYPE) == T_TYPE_INT)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(HAVE_INLINE)
|
#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 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
|
#else
|
||||||
# define IsTypeLong(T) (((T)[0] & T_MASK_TYPE) == T_TYPE_LONG)
|
# define IsTypeLong(T) (((T)->C & T_MASK_TYPE) == T_TYPE_LONG)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(HAVE_INLINE)
|
#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 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
|
#else
|
||||||
# define IsTypeFloat(T) (((T)[0] & T_MASK_TYPE) == T_TYPE_FLOAT)
|
# define IsTypeFloat(T) (((T)->C & T_MASK_TYPE) == T_TYPE_FLOAT)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(HAVE_INLINE)
|
#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 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
|
#else
|
||||||
# define IsTypeDouble(T) (((T)[0] & T_MASK_TYPE) == T_TYPE_DOUBLE)
|
# define IsTypeDouble(T) (((T)->C & T_MASK_TYPE) == T_TYPE_DOUBLE)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(HAVE_INLINE)
|
#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 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
|
#else
|
||||||
# define IsTypePtr(T) (((T)[0] & T_MASK_TYPE) == T_TYPE_PTR)
|
# define IsTypePtr(T) (((T)->C & T_MASK_TYPE) == T_TYPE_PTR)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(HAVE_INLINE)
|
#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 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
|
#else
|
||||||
# define IsTypeStruct(T) (((T)[0] & T_MASK_TYPE) == T_TYPE_STRUCT)
|
# define IsTypeStruct(T) (((T)->C & T_MASK_TYPE) == T_TYPE_STRUCT)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(HAVE_INLINE)
|
#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 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
|
#else
|
||||||
# define IsTypeUnion(T) (((T)[0] & T_MASK_TYPE) == T_TYPE_UNION)
|
# define IsTypeUnion(T) (((T)->C & T_MASK_TYPE) == T_TYPE_UNION)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(HAVE_INLINE)
|
#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 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
|
#else
|
||||||
# define IsTypeArray(T) (((T)[0] & T_MASK_TYPE) == T_TYPE_ARRAY)
|
# define IsTypeArray(T) (((T)->C & T_MASK_TYPE) == T_TYPE_ARRAY)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(HAVE_INLINE)
|
#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 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
|
#else
|
||||||
# define IsTypeVoid(T) (((T)[0] & T_MASK_TYPE) == T_TYPE_VOID)
|
# define IsTypeVoid(T) (((T)->C & T_MASK_TYPE) == T_TYPE_VOID)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(HAVE_INLINE)
|
#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 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
|
#else
|
||||||
# define IsTypeFunc(T) (((T)[0] & T_MASK_TYPE) == T_TYPE_FUNC)
|
# define IsTypeFunc(T) (((T)->C & T_MASK_TYPE) == T_TYPE_FUNC)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(HAVE_INLINE)
|
#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 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
|
#else
|
||||||
# define IsTypeFuncPtr(T) \
|
# 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
|
#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 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 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 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 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 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 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 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
|
/* Return true if this is a function type or pointer to function with
|
||||||
* __fastcall__ calling conventions
|
* __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
|
/* Return true if this is a function type or pointer to function type with
|
||||||
* variable parameter list
|
* variable parameter list
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#if defined(HAVE_INLINE)
|
#if defined(HAVE_INLINE)
|
||||||
INLINE type GetType (const type* T)
|
INLINE TypeCode GetType (const Type* T)
|
||||||
/* Get the raw type */
|
/* Get the raw type */
|
||||||
{
|
{
|
||||||
return (T[0] & T_MASK_TYPE);
|
return (T->C & T_MASK_TYPE);
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
# define GetType(T) ((T)[0] & T_MASK_TYPE)
|
# define GetType(T) ((T)->C & T_MASK_TYPE)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(HAVE_INLINE)
|
#if defined(HAVE_INLINE)
|
||||||
INLINE type GetClass (const type* T)
|
INLINE TypeCode GetClass (const Type* T)
|
||||||
/* Get the class of a type string */
|
/* Get the class of a type string */
|
||||||
{
|
{
|
||||||
return (T[0] & T_MASK_CLASS);
|
return (T->C & T_MASK_CLASS);
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
# define GetClass(T) ((T)[0] & T_MASK_CLASS)
|
# define GetClass(T) ((T)->C & T_MASK_CLASS)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(HAVE_INLINE)
|
#if defined(HAVE_INLINE)
|
||||||
INLINE type GetSignedness (const type* T)
|
INLINE TypeCode GetSignedness (const Type* T)
|
||||||
/* Get the sign of a type */
|
/* Get the sign of a type */
|
||||||
{
|
{
|
||||||
return (T[0] & T_MASK_SIGN);
|
return (T->C & T_MASK_SIGN);
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
# define GetSignedness(T) ((T)[0] & T_MASK_SIGN)
|
# define GetSignedness(T) ((T)->C & T_MASK_SIGN)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(HAVE_INLINE)
|
#if defined(HAVE_INLINE)
|
||||||
INLINE type GetSizeModifier (const type* T)
|
INLINE TypeCode GetSizeModifier (const Type* T)
|
||||||
/* Get the size modifier of a type */
|
/* Get the size modifier of a type */
|
||||||
{
|
{
|
||||||
return (T[0] & T_MASK_SIZE);
|
return (T->C & T_MASK_SIZE);
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
# define GetSizeModifier(T) ((T)[0] & T_MASK_SIZE)
|
# define GetSizeModifier(T) ((T)->C & T_MASK_SIZE)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
type GetQualifier (const type* T) attribute ((const));
|
FuncDesc* GetFuncDesc (const Type* T) attribute ((const));
|
||||||
/* Get the qualifier from the given type string */
|
|
||||||
|
|
||||||
FuncDesc* GetFuncDesc (const type* T) attribute ((const));
|
|
||||||
/* Get the FuncDesc pointer from a function or pointer-to-function type */
|
/* 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 */
|
/* 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
|
/* Get the element count of the array specified in T (which must be of
|
||||||
* array type).
|
* 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. */
|
/* 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
|
/* 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.
|
* 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
|
/* 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
|
* expression is an array, convert it to pointer to first element. Otherwise
|
||||||
* return T.
|
* return T.
|
||||||
|
|
|
@ -68,10 +68,10 @@
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static void ParseTypeSpec (DeclSpec* D, int Default, type Qualifiers);
|
static void ParseTypeSpec (DeclSpec* D, long Default, TypeCode Qualifiers);
|
||||||
/* Parse a type specificier */
|
/* 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. */
|
/* Parse initialization of variables. Return the number of data bytes. */
|
||||||
|
|
||||||
|
|
||||||
|
@ -82,7 +82,7 @@ static unsigned ParseInitInternal (type* T, int AllowFlexibleMembers);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static type OptionalQualifiers (type Q)
|
static TypeCode OptionalQualifiers (TypeCode Q)
|
||||||
/* Read type qualifiers if we have any */
|
/* Read type qualifiers if we have any */
|
||||||
{
|
{
|
||||||
while (TokIsTypeQual (&CurTok)) {
|
while (TokIsTypeQual (&CurTok)) {
|
||||||
|
@ -151,7 +151,7 @@ static void InitDeclSpec (DeclSpec* D)
|
||||||
/* Initialize the DeclSpec struct for use */
|
/* Initialize the DeclSpec struct for use */
|
||||||
{
|
{
|
||||||
D->StorageClass = 0;
|
D->StorageClass = 0;
|
||||||
D->Type[0] = T_END;
|
D->Type[0].C = T_END;
|
||||||
D->Flags = 0;
|
D->Flags = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -160,9 +160,9 @@ static void InitDeclSpec (DeclSpec* D)
|
||||||
static void InitDeclaration (Declaration* D)
|
static void InitDeclaration (Declaration* D)
|
||||||
/* Initialize the Declaration struct for use */
|
/* Initialize the Declaration struct for use */
|
||||||
{
|
{
|
||||||
D->Ident[0] = '\0';
|
D->Ident[0] = '\0';
|
||||||
D->Type[0] = T_END;
|
D->Type[0].C = T_END;
|
||||||
D->Index = 0;
|
D->Index = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -181,22 +181,33 @@ static void NeedTypeSpace (Declaration* D, unsigned Count)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static void AddTypeToDeclaration (Declaration* D, type T)
|
static void AddTypeToDeclaration (Declaration* D, TypeCode T)
|
||||||
/* Add a type specifier to the type of a declaration */
|
/* Add a type specifier to the type of a declaration */
|
||||||
{
|
{
|
||||||
NeedTypeSpace (D, 1);
|
NeedTypeSpace (D, 1);
|
||||||
D->Type[D->Index++] = T;
|
D->Type[D->Index++].C = T;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static void AddEncodeToDeclaration (Declaration* D, type T, unsigned long Val)
|
static void AddFuncTypeToDeclaration (Declaration* D, FuncDesc* F)
|
||||||
/* Add a type plus encoding to the type of a declaration */
|
/* Add a function type plus function descriptor to the type of a declaration */
|
||||||
{
|
{
|
||||||
NeedTypeSpace (D, DECODE_SIZE+1);
|
NeedTypeSpace (D, 1);
|
||||||
D->Type[D->Index++] = T;
|
D->Type[D->Index].C = T_FUNC;
|
||||||
Encode (D->Type + D->Index, Val);
|
SetFuncDesc (D->Type + D->Index, F);
|
||||||
D->Index += DECODE_SIZE;
|
++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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -294,7 +305,7 @@ static void ParseEnumDecl (void)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static SymEntry* ParseStructDecl (const char* Name, type StructType)
|
static SymEntry* ParseStructDecl (const char* Name, TypeCode StructType)
|
||||||
/* Parse a struct/union declaration. */
|
/* Parse a struct/union declaration. */
|
||||||
{
|
{
|
||||||
|
|
||||||
|
@ -372,7 +383,7 @@ static SymEntry* ParseStructDecl (const char* Name, type StructType)
|
||||||
}
|
}
|
||||||
FlexibleMember = 1;
|
FlexibleMember = 1;
|
||||||
/* Assume zero for size calculations */
|
/* Assume zero for size calculations */
|
||||||
Encode (Decl.Type + 1, FLEXIBLE);
|
SetElementCount (Decl.Type, FLEXIBLE);
|
||||||
} else {
|
} else {
|
||||||
StructSize += CheckedSizeOf (Decl.Type);
|
StructSize += CheckedSizeOf (Decl.Type);
|
||||||
}
|
}
|
||||||
|
@ -410,12 +421,12 @@ static SymEntry* ParseStructDecl (const char* Name, type StructType)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static void ParseTypeSpec (DeclSpec* D, int Default, type Qualifiers)
|
static void ParseTypeSpec (DeclSpec* D, long Default, TypeCode Qualifiers)
|
||||||
/* Parse a type specificier */
|
/* Parse a type specificier */
|
||||||
{
|
{
|
||||||
ident Ident;
|
ident Ident;
|
||||||
SymEntry* Entry;
|
SymEntry* Entry;
|
||||||
type StructType;
|
TypeCode StructType;
|
||||||
|
|
||||||
/* Assume we have an explicit type */
|
/* Assume we have an explicit type */
|
||||||
D->Flags &= ~DS_DEF_TYPE;
|
D->Flags &= ~DS_DEF_TYPE;
|
||||||
|
@ -428,14 +439,14 @@ static void ParseTypeSpec (DeclSpec* D, int Default, type Qualifiers)
|
||||||
|
|
||||||
case TOK_VOID:
|
case TOK_VOID:
|
||||||
NextToken ();
|
NextToken ();
|
||||||
D->Type[0] = T_VOID;
|
D->Type[0].C = T_VOID;
|
||||||
D->Type[1] = T_END;
|
D->Type[1].C = T_END;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case TOK_CHAR:
|
case TOK_CHAR:
|
||||||
NextToken ();
|
NextToken ();
|
||||||
D->Type[0] = GetDefaultChar();
|
D->Type[0].C = GetDefaultChar();
|
||||||
D->Type[1] = T_END;
|
D->Type[1].C = T_END;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case TOK_LONG:
|
case TOK_LONG:
|
||||||
|
@ -443,13 +454,13 @@ static void ParseTypeSpec (DeclSpec* D, int Default, type Qualifiers)
|
||||||
if (CurTok.Tok == TOK_UNSIGNED) {
|
if (CurTok.Tok == TOK_UNSIGNED) {
|
||||||
NextToken ();
|
NextToken ();
|
||||||
optionalint ();
|
optionalint ();
|
||||||
D->Type[0] = T_ULONG;
|
D->Type[0].C = T_ULONG;
|
||||||
D->Type[1] = T_END;
|
D->Type[1].C = T_END;
|
||||||
} else {
|
} else {
|
||||||
optionalsigned ();
|
optionalsigned ();
|
||||||
optionalint ();
|
optionalint ();
|
||||||
D->Type[0] = T_LONG;
|
D->Type[0].C = T_LONG;
|
||||||
D->Type[1] = T_END;
|
D->Type[1].C = T_END;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -458,20 +469,20 @@ static void ParseTypeSpec (DeclSpec* D, int Default, type Qualifiers)
|
||||||
if (CurTok.Tok == TOK_UNSIGNED) {
|
if (CurTok.Tok == TOK_UNSIGNED) {
|
||||||
NextToken ();
|
NextToken ();
|
||||||
optionalint ();
|
optionalint ();
|
||||||
D->Type[0] = T_USHORT;
|
D->Type[0].C = T_USHORT;
|
||||||
D->Type[1] = T_END;
|
D->Type[1].C = T_END;
|
||||||
} else {
|
} else {
|
||||||
optionalsigned ();
|
optionalsigned ();
|
||||||
optionalint ();
|
optionalint ();
|
||||||
D->Type[0] = T_SHORT;
|
D->Type[0].C = T_SHORT;
|
||||||
D->Type[1] = T_END;
|
D->Type[1].C = T_END;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case TOK_INT:
|
case TOK_INT:
|
||||||
NextToken ();
|
NextToken ();
|
||||||
D->Type[0] = T_INT;
|
D->Type[0].C = T_INT;
|
||||||
D->Type[1] = T_END;
|
D->Type[1].C = T_END;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case TOK_SIGNED:
|
case TOK_SIGNED:
|
||||||
|
@ -480,22 +491,22 @@ static void ParseTypeSpec (DeclSpec* D, int Default, type Qualifiers)
|
||||||
|
|
||||||
case TOK_CHAR:
|
case TOK_CHAR:
|
||||||
NextToken ();
|
NextToken ();
|
||||||
D->Type[0] = T_SCHAR;
|
D->Type[0].C = T_SCHAR;
|
||||||
D->Type[1] = T_END;
|
D->Type[1].C = T_END;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case TOK_SHORT:
|
case TOK_SHORT:
|
||||||
NextToken ();
|
NextToken ();
|
||||||
optionalint ();
|
optionalint ();
|
||||||
D->Type[0] = T_SHORT;
|
D->Type[0].C = T_SHORT;
|
||||||
D->Type[1] = T_END;
|
D->Type[1].C = T_END;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case TOK_LONG:
|
case TOK_LONG:
|
||||||
NextToken ();
|
NextToken ();
|
||||||
optionalint ();
|
optionalint ();
|
||||||
D->Type[0] = T_LONG;
|
D->Type[0].C = T_LONG;
|
||||||
D->Type[1] = T_END;
|
D->Type[1].C = T_END;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case TOK_INT:
|
case TOK_INT:
|
||||||
|
@ -503,8 +514,8 @@ static void ParseTypeSpec (DeclSpec* D, int Default, type Qualifiers)
|
||||||
/* FALL THROUGH */
|
/* FALL THROUGH */
|
||||||
|
|
||||||
default:
|
default:
|
||||||
D->Type[0] = T_INT;
|
D->Type[0].C = T_INT;
|
||||||
D->Type[1] = T_END;
|
D->Type[1].C = T_END;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -515,22 +526,22 @@ static void ParseTypeSpec (DeclSpec* D, int Default, type Qualifiers)
|
||||||
|
|
||||||
case TOK_CHAR:
|
case TOK_CHAR:
|
||||||
NextToken ();
|
NextToken ();
|
||||||
D->Type[0] = T_UCHAR;
|
D->Type[0].C = T_UCHAR;
|
||||||
D->Type[1] = T_END;
|
D->Type[1].C = T_END;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case TOK_SHORT:
|
case TOK_SHORT:
|
||||||
NextToken ();
|
NextToken ();
|
||||||
optionalint ();
|
optionalint ();
|
||||||
D->Type[0] = T_USHORT;
|
D->Type[0].C = T_USHORT;
|
||||||
D->Type[1] = T_END;
|
D->Type[1].C = T_END;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case TOK_LONG:
|
case TOK_LONG:
|
||||||
NextToken ();
|
NextToken ();
|
||||||
optionalint ();
|
optionalint ();
|
||||||
D->Type[0] = T_ULONG;
|
D->Type[0].C = T_ULONG;
|
||||||
D->Type[1] = T_END;
|
D->Type[1].C = T_END;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case TOK_INT:
|
case TOK_INT:
|
||||||
|
@ -538,22 +549,22 @@ static void ParseTypeSpec (DeclSpec* D, int Default, type Qualifiers)
|
||||||
/* FALL THROUGH */
|
/* FALL THROUGH */
|
||||||
|
|
||||||
default:
|
default:
|
||||||
D->Type[0] = T_UINT;
|
D->Type[0].C = T_UINT;
|
||||||
D->Type[1] = T_END;
|
D->Type[1].C = T_END;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case TOK_FLOAT:
|
case TOK_FLOAT:
|
||||||
NextToken ();
|
NextToken ();
|
||||||
D->Type[0] = T_FLOAT;
|
D->Type[0].C = T_FLOAT;
|
||||||
D->Type[1] = T_END;
|
D->Type[1].C = T_END;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case TOK_DOUBLE:
|
case TOK_DOUBLE:
|
||||||
NextToken ();
|
NextToken ();
|
||||||
D->Type[0] = T_DOUBLE;
|
D->Type[0].C = T_DOUBLE;
|
||||||
D->Type[1] = T_END;
|
D->Type[1].C = T_END;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case TOK_STRUCT:
|
case TOK_STRUCT:
|
||||||
|
@ -572,9 +583,9 @@ static void ParseTypeSpec (DeclSpec* D, int Default, type Qualifiers)
|
||||||
/* Declare the struct in the current scope */
|
/* Declare the struct in the current scope */
|
||||||
Entry = ParseStructDecl (Ident, StructType);
|
Entry = ParseStructDecl (Ident, StructType);
|
||||||
/* Encode the struct entry into the type */
|
/* Encode the struct entry into the type */
|
||||||
D->Type[0] = StructType;
|
D->Type[0].C = StructType;
|
||||||
EncodePtr (D->Type+1, Entry);
|
SetSymEntry (D->Type, Entry);
|
||||||
D->Type[DECODE_SIZE+1] = T_END;
|
D->Type[1].C = T_END;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case TOK_ENUM:
|
case TOK_ENUM:
|
||||||
|
@ -601,8 +612,8 @@ static void ParseTypeSpec (DeclSpec* D, int Default, type Qualifiers)
|
||||||
D->Flags |= DS_EXTRA_TYPE;
|
D->Flags |= DS_EXTRA_TYPE;
|
||||||
/* Parse the enum decl */
|
/* Parse the enum decl */
|
||||||
ParseEnumDecl ();
|
ParseEnumDecl ();
|
||||||
D->Type[0] = T_INT;
|
D->Type[0].C = T_INT;
|
||||||
D->Type[1] = T_END;
|
D->Type[1].C = T_END;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case TOK_IDENT:
|
case TOK_IDENT:
|
||||||
|
@ -618,30 +629,29 @@ static void ParseTypeSpec (DeclSpec* D, int Default, type Qualifiers)
|
||||||
default:
|
default:
|
||||||
if (Default < 0) {
|
if (Default < 0) {
|
||||||
Error ("Type expected");
|
Error ("Type expected");
|
||||||
D->Type[0] = T_INT;
|
D->Type[0].C = T_INT;
|
||||||
D->Type[1] = T_END;
|
D->Type[1].C = T_END;
|
||||||
} else {
|
} else {
|
||||||
D->Flags |= DS_DEF_TYPE;
|
D->Flags |= DS_DEF_TYPE;
|
||||||
D->Type[0] = (type) Default;
|
D->Type[0].C = (TypeCode) Default;
|
||||||
D->Type[1] = T_END;
|
D->Type[1].C = T_END;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* There may also be qualifiers *after* the initial type */
|
/* 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
|
/* If T is an array, convert it to a pointer else do nothing. Return the
|
||||||
* resulting type.
|
* resulting type.
|
||||||
*/
|
*/
|
||||||
{
|
{
|
||||||
if (IsTypeArray (T)) {
|
if (IsTypeArray (T)) {
|
||||||
T += DECODE_SIZE;
|
T->C = T_PTR;
|
||||||
T[0] = T_PTR;
|
|
||||||
}
|
}
|
||||||
return T;
|
return T;
|
||||||
}
|
}
|
||||||
|
@ -847,8 +857,8 @@ static FuncDesc* ParseFuncDecl (const DeclSpec* Spec)
|
||||||
|
|
||||||
/* Check for an implicit int return in the function */
|
/* Check for an implicit int return in the function */
|
||||||
if ((Spec->Flags & DS_DEF_TYPE) != 0 &&
|
if ((Spec->Flags & DS_DEF_TYPE) != 0 &&
|
||||||
Spec->Type[0] == T_INT &&
|
Spec->Type[0].C == T_INT &&
|
||||||
Spec->Type[1] == T_END) {
|
Spec->Type[1].C == T_END) {
|
||||||
/* Function has an implicit int return. Output a warning if we don't
|
/* Function has an implicit int return. Output a warning if we don't
|
||||||
* have the C89 standard enabled explicitly.
|
* have the C89 standard enabled explicitly.
|
||||||
*/
|
*/
|
||||||
|
@ -945,7 +955,7 @@ static unsigned FunctionModifierFlags (void)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static void ApplyFunctionModifiers (type* T, unsigned Flags)
|
static void ApplyFunctionModifiers (Type* T, unsigned Flags)
|
||||||
/* Apply a set of function modifier flags to a function */
|
/* Apply a set of function modifier flags to a function */
|
||||||
{
|
{
|
||||||
/* Get the function descriptor */
|
/* Get the function descriptor */
|
||||||
|
@ -973,19 +983,19 @@ static void Decl (const DeclSpec* Spec, Declaration* D, unsigned Mode)
|
||||||
/* Pointer to something */
|
/* Pointer to something */
|
||||||
if (CurTok.Tok == TOK_STAR) {
|
if (CurTok.Tok == TOK_STAR) {
|
||||||
|
|
||||||
type T;
|
TypeCode C;
|
||||||
|
|
||||||
/* Skip the star */
|
/* Skip the star */
|
||||||
NextToken ();
|
NextToken ();
|
||||||
|
|
||||||
/* Allow optional const or volatile qualifiers */
|
/* 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 */
|
/* Parse the type, the pointer points to */
|
||||||
Decl (Spec, D, Mode);
|
Decl (Spec, D, Mode);
|
||||||
|
|
||||||
/* Add the type */
|
/* Add the type */
|
||||||
AddTypeToDeclaration (D, T);
|
AddTypeToDeclaration (D, C);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -993,7 +1003,7 @@ static void Decl (const DeclSpec* Spec, Declaration* D, unsigned Mode)
|
||||||
if (CurTok.Tok == TOK_FASTCALL || CurTok.Tok == TOK_NEAR || CurTok.Tok == TOK_FAR) {
|
if (CurTok.Tok == TOK_FASTCALL || CurTok.Tok == TOK_NEAR || CurTok.Tok == TOK_FAR) {
|
||||||
|
|
||||||
/* Remember the current type pointer */
|
/* Remember the current type pointer */
|
||||||
type* T = D->Type + D->Index;
|
Type* T = D->Type + D->Index;
|
||||||
|
|
||||||
/* Read the flags */
|
/* Read the flags */
|
||||||
unsigned Flags = FunctionModifierFlags ();
|
unsigned Flags = FunctionModifierFlags ();
|
||||||
|
@ -1051,7 +1061,7 @@ static void Decl (const DeclSpec* Spec, Declaration* D, unsigned Mode)
|
||||||
F = ParseFuncDecl (Spec);
|
F = ParseFuncDecl (Spec);
|
||||||
|
|
||||||
/* Add the function type. Be sure to bounds check the type buffer */
|
/* Add the function type. Be sure to bounds check the type buffer */
|
||||||
AddEncodeToDeclaration (D, T_FUNC, (unsigned long) F);
|
AddFuncTypeToDeclaration (D, F);
|
||||||
} else {
|
} else {
|
||||||
/* Array declaration */
|
/* Array declaration */
|
||||||
long Size = UNSPECIFIED;
|
long Size = UNSPECIFIED;
|
||||||
|
@ -1072,8 +1082,8 @@ static void Decl (const DeclSpec* Spec, Declaration* D, unsigned Mode)
|
||||||
}
|
}
|
||||||
ConsumeRBrack ();
|
ConsumeRBrack ();
|
||||||
|
|
||||||
/* Add the type */
|
/* Add the array type with the size */
|
||||||
AddEncodeToDeclaration (D, T_ARRAY, Size);
|
AddArrayToDeclaration (D, Size);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1086,7 +1096,7 @@ static void Decl (const DeclSpec* Spec, Declaration* D, unsigned Mode)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
type* ParseType (type* Type)
|
Type* ParseType (Type* T)
|
||||||
/* Parse a complete type specification */
|
/* Parse a complete type specification */
|
||||||
{
|
{
|
||||||
DeclSpec Spec;
|
DeclSpec Spec;
|
||||||
|
@ -1100,10 +1110,10 @@ type* ParseType (type* Type)
|
||||||
ParseDecl (&Spec, &Decl, DM_NO_IDENT);
|
ParseDecl (&Spec, &Decl, DM_NO_IDENT);
|
||||||
|
|
||||||
/* Copy the type to the target buffer */
|
/* Copy the type to the target buffer */
|
||||||
TypeCpy (Type, Decl.Type);
|
TypeCpy (T, Decl.Type);
|
||||||
|
|
||||||
/* Return a pointer to the target buffer */
|
/* Return a pointer to the target buffer */
|
||||||
return Type;
|
return T;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1139,7 +1149,7 @@ void ParseDecl (const DeclSpec* Spec, Declaration* D, unsigned Mode)
|
||||||
void ParseDeclSpec (DeclSpec* D, unsigned DefStorage, int DefType)
|
void ParseDeclSpec (DeclSpec* D, unsigned DefStorage, int DefType)
|
||||||
/* Parse a declaration specification */
|
/* Parse a declaration specification */
|
||||||
{
|
{
|
||||||
type Qualifiers;
|
TypeCode Qualifiers;
|
||||||
|
|
||||||
/* Initialize the DeclSpec struct */
|
/* Initialize the DeclSpec struct */
|
||||||
InitDeclSpec (D);
|
InitDeclSpec (D);
|
||||||
|
@ -1271,7 +1281,7 @@ static void DefineData (ExprDesc* Expr)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static unsigned ParseScalarInit (type* T)
|
static unsigned ParseScalarInit (Type* T)
|
||||||
/* Parse initializaton for scalar data types. Return the number of data bytes. */
|
/* Parse initializaton for scalar data types. Return the number of data bytes. */
|
||||||
{
|
{
|
||||||
ExprDesc ED;
|
ExprDesc ED;
|
||||||
|
@ -1302,7 +1312,7 @@ static unsigned ParseScalarInit (type* T)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static unsigned ParsePointerInit (type* T)
|
static unsigned ParsePointerInit (Type* T)
|
||||||
/* Parse initializaton for pointer data types. Return the number of data bytes. */
|
/* Parse initializaton for pointer data types. Return the number of data bytes. */
|
||||||
{
|
{
|
||||||
/* Optional opening brace */
|
/* Optional opening brace */
|
||||||
|
@ -1325,13 +1335,13 @@ static unsigned ParsePointerInit (type* T)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static unsigned ParseArrayInit (type* T, int AllowFlexibleMembers)
|
static unsigned ParseArrayInit (Type* T, int AllowFlexibleMembers)
|
||||||
/* Parse initializaton for arrays. Return the number of data bytes. */
|
/* Parse initializaton for arrays. Return the number of data bytes. */
|
||||||
{
|
{
|
||||||
int Count;
|
int Count;
|
||||||
|
|
||||||
/* Get the array data */
|
/* Get the array data */
|
||||||
type* ElementType = GetElementType (T);
|
Type* ElementType = GetElementType (T);
|
||||||
unsigned ElementSize = CheckedSizeOf (ElementType);
|
unsigned ElementSize = CheckedSizeOf (ElementType);
|
||||||
long ElementCount = GetElementCount (T);
|
long ElementCount = GetElementCount (T);
|
||||||
|
|
||||||
|
@ -1406,10 +1416,9 @@ static unsigned ParseArrayInit (type* T, int AllowFlexibleMembers)
|
||||||
ConsumeRCurly ();
|
ConsumeRCurly ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (ElementCount == UNSPECIFIED) {
|
if (ElementCount == UNSPECIFIED) {
|
||||||
/* Number of elements determined by initializer */
|
/* Number of elements determined by initializer */
|
||||||
Encode (T + 1, Count);
|
SetElementCount (T, Count);
|
||||||
ElementCount = Count;
|
ElementCount = Count;
|
||||||
} else if (ElementCount == FLEXIBLE && AllowFlexibleMembers) {
|
} else if (ElementCount == FLEXIBLE && AllowFlexibleMembers) {
|
||||||
/* In non ANSI mode, allow initialization of flexible array
|
/* In non ANSI mode, allow initialization of flexible array
|
||||||
|
@ -1426,7 +1435,7 @@ static unsigned ParseArrayInit (type* T, int AllowFlexibleMembers)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
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. */
|
/* Parse initialization of a struct or union. Return the number of data bytes. */
|
||||||
{
|
{
|
||||||
SymEntry* Entry;
|
SymEntry* Entry;
|
||||||
|
@ -1439,7 +1448,7 @@ static unsigned ParseStructInit (type* Type, int AllowFlexibleMembers)
|
||||||
ConsumeLCurly ();
|
ConsumeLCurly ();
|
||||||
|
|
||||||
/* Get a pointer to the struct entry from the type */
|
/* 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 */
|
/* Get the size of the struct from the symbol table entry */
|
||||||
StructSize = Entry->V.S.Size;
|
StructSize = Entry->V.S.Size;
|
||||||
|
@ -1511,7 +1520,7 @@ static unsigned ParseVoidInit (void)
|
||||||
Size = 0;
|
Size = 0;
|
||||||
do {
|
do {
|
||||||
ConstExpr (hie1, &Expr);
|
ConstExpr (hie1, &Expr);
|
||||||
switch (UnqualifiedType (Expr.Type[0])) {
|
switch (UnqualifiedType (Expr.Type[0].C)) {
|
||||||
|
|
||||||
case T_SCHAR:
|
case T_SCHAR:
|
||||||
case T_UCHAR:
|
case T_UCHAR:
|
||||||
|
@ -1569,10 +1578,10 @@ static unsigned ParseVoidInit (void)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static unsigned ParseInitInternal (type* T, int AllowFlexibleMembers)
|
static unsigned ParseInitInternal (Type* T, int AllowFlexibleMembers)
|
||||||
/* Parse initialization of variables. Return the number of data bytes. */
|
/* Parse initialization of variables. Return the number of data bytes. */
|
||||||
{
|
{
|
||||||
switch (UnqualifiedType (*T)) {
|
switch (UnqualifiedType (T->C)) {
|
||||||
|
|
||||||
case T_SCHAR:
|
case T_SCHAR:
|
||||||
case T_UCHAR:
|
case T_UCHAR:
|
||||||
|
@ -1610,7 +1619,7 @@ static unsigned ParseInitInternal (type* T, int AllowFlexibleMembers)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
unsigned ParseInit (type* T)
|
unsigned ParseInit (Type* T)
|
||||||
/* Parse initialization of variables. Return the number of data bytes. */
|
/* Parse initialization of variables. Return the number of data bytes. */
|
||||||
{
|
{
|
||||||
/* Parse the initialization. Flexible array members can only be initialized
|
/* Parse the initialization. Flexible array members can only be initialized
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* (C) 1998-2003 Ullrich von Bassewitz */
|
/* (C) 1998-2006 Ullrich von Bassewitz */
|
||||||
/* Römerstrasse 52 */
|
/* Römerstrasse 52 */
|
||||||
/* D-70794 Filderstadt */
|
/* D-70794 Filderstadt */
|
||||||
/* EMail: uz@cc65.org */
|
/* EMail: uz@cc65.org */
|
||||||
|
@ -59,7 +59,7 @@
|
||||||
typedef struct DeclSpec DeclSpec;
|
typedef struct DeclSpec DeclSpec;
|
||||||
struct DeclSpec {
|
struct DeclSpec {
|
||||||
unsigned StorageClass; /* One of the SC_xxx flags */
|
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 */
|
unsigned Flags; /* Bitmapped flags */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -67,7 +67,7 @@ struct DeclSpec {
|
||||||
typedef struct Declaration Declaration;
|
typedef struct Declaration Declaration;
|
||||||
struct Declaration {
|
struct Declaration {
|
||||||
ident Ident; /* The identifier if any, else empty */
|
ident Ident; /* The identifier if any, else empty */
|
||||||
type Type [MAXTYPELEN]; /* The type */
|
Type Type[MAXTYPELEN]; /* The type */
|
||||||
|
|
||||||
/* Working variables */
|
/* Working variables */
|
||||||
unsigned Index; /* Used to build Type */
|
unsigned Index; /* Used to build Type */
|
||||||
|
@ -86,7 +86,7 @@ struct Declaration {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
type* ParseType (type* Type);
|
Type* ParseType (Type* Type);
|
||||||
/* Parse a complete type specification */
|
/* Parse a complete type specification */
|
||||||
|
|
||||||
void ParseDecl (const DeclSpec* Spec, Declaration* D, unsigned Mode);
|
void ParseDecl (const DeclSpec* Spec, Declaration* D, unsigned Mode);
|
||||||
|
@ -101,7 +101,7 @@ void CheckEmptyDecl (const DeclSpec* D);
|
||||||
* warning if not.
|
* warning if not.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
unsigned ParseInit (type* T);
|
unsigned ParseInit (Type* T);
|
||||||
/* Parse initialization of variables. Return the number of initialized data
|
/* Parse initialization of variables. Return the number of initialized data
|
||||||
* bytes.
|
* bytes.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -115,7 +115,7 @@ void ExprWithCheck (void (*Func) (ExprDesc*), ExprDesc *Expr)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
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 */
|
/* In an expression with two ints, return the type of the result */
|
||||||
{
|
{
|
||||||
/* Rules for integer types:
|
/* Rules for integer types:
|
||||||
|
@ -154,8 +154,8 @@ static unsigned typeadjust (ExprDesc* lhs, ExprDesc* rhs, int NoPush)
|
||||||
unsigned flags;
|
unsigned flags;
|
||||||
|
|
||||||
/* Get the type strings */
|
/* Get the type strings */
|
||||||
type* lhst = lhs->Type;
|
Type* lhst = lhs->Type;
|
||||||
type* rhst = rhs->Type;
|
Type* rhst = rhs->Type;
|
||||||
|
|
||||||
/* Generate type adjustment code if needed */
|
/* Generate type adjustment code if needed */
|
||||||
ltype = TypeOf (lhst);
|
ltype = TypeOf (lhst);
|
||||||
|
@ -805,8 +805,8 @@ static void ArrayRef (ExprDesc* Expr)
|
||||||
ExprDesc SubScript;
|
ExprDesc SubScript;
|
||||||
CodeMark Mark1;
|
CodeMark Mark1;
|
||||||
CodeMark Mark2;
|
CodeMark Mark2;
|
||||||
type* ElementType;
|
Type* ElementType;
|
||||||
type* tptr1;
|
Type* tptr1;
|
||||||
|
|
||||||
|
|
||||||
/* Skip the bracket */
|
/* Skip the bracket */
|
||||||
|
@ -1183,7 +1183,7 @@ static void hie11 (ExprDesc *Expr)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
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
|
/* 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 given, use this type when storing instead of Expr->Type. If StoreType
|
||||||
* is NULL, use Expr->Type instead.
|
* is NULL, use Expr->Type instead.
|
||||||
|
@ -1216,7 +1216,7 @@ void Store (ExprDesc* Expr, const type* StoreType)
|
||||||
case E_LOC_LITERAL:
|
case E_LOC_LITERAL:
|
||||||
/* Static variable or literal in the literal pool */
|
/* Static variable or literal in the literal pool */
|
||||||
g_putstatic (Flags | CF_STATIC, Expr->Name, Expr->IVal);
|
g_putstatic (Flags | CF_STATIC, Expr->Name, Expr->IVal);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case E_LOC_REGISTER:
|
case E_LOC_REGISTER:
|
||||||
/* Register variable */
|
/* Register variable */
|
||||||
|
@ -1560,9 +1560,9 @@ void hie10 (ExprDesc* Expr)
|
||||||
case TOK_SIZEOF:
|
case TOK_SIZEOF:
|
||||||
NextToken ();
|
NextToken ();
|
||||||
if (TypeSpecAhead ()) {
|
if (TypeSpecAhead ()) {
|
||||||
type Type[MAXTYPELEN];
|
Type T[MAXTYPELEN];
|
||||||
NextToken ();
|
NextToken ();
|
||||||
Size = CheckedSizeOf (ParseType (Type));
|
Size = CheckedSizeOf (ParseType (T));
|
||||||
ConsumeRParen ();
|
ConsumeRParen ();
|
||||||
} else {
|
} else {
|
||||||
/* Remember the output queue pointer */
|
/* Remember the output queue pointer */
|
||||||
|
@ -1757,9 +1757,9 @@ static void hie_compare (const GenDesc* Ops, /* List of generators */
|
||||||
/* Both pointers are allowed in comparison if they point to
|
/* Both pointers are allowed in comparison if they point to
|
||||||
* the same type, or if one of them is a void pointer.
|
* the same type, or if one of them is a void pointer.
|
||||||
*/
|
*/
|
||||||
type* left = Indirect (Expr->Type);
|
Type* left = Indirect (Expr->Type);
|
||||||
type* right = Indirect (Expr2.Type);
|
Type* right = Indirect (Expr2.Type);
|
||||||
if (TypeCmp (left, right) < TC_EQUAL && *left != T_VOID && *right != T_VOID) {
|
if (TypeCmp (left, right) < TC_EQUAL && left->C != T_VOID && right->C != T_VOID) {
|
||||||
/* Incomatible pointers */
|
/* Incomatible pointers */
|
||||||
Error ("Incompatible types");
|
Error ("Incompatible types");
|
||||||
}
|
}
|
||||||
|
@ -1853,8 +1853,8 @@ static void parseadd (ExprDesc* Expr)
|
||||||
ExprDesc Expr2;
|
ExprDesc Expr2;
|
||||||
unsigned flags; /* Operation flags */
|
unsigned flags; /* Operation flags */
|
||||||
CodeMark Mark; /* Remember code position */
|
CodeMark Mark; /* Remember code position */
|
||||||
type* lhst; /* Type of left hand side */
|
Type* lhst; /* Type of left hand side */
|
||||||
type* rhst; /* Type of right hand side */
|
Type* rhst; /* Type of right hand side */
|
||||||
|
|
||||||
|
|
||||||
/* Skip the PLUS token */
|
/* Skip the PLUS token */
|
||||||
|
@ -2077,8 +2077,8 @@ static void parsesub (ExprDesc* Expr)
|
||||||
{
|
{
|
||||||
ExprDesc Expr2;
|
ExprDesc Expr2;
|
||||||
unsigned flags; /* Operation flags */
|
unsigned flags; /* Operation flags */
|
||||||
type* lhst; /* Type of left hand side */
|
Type* lhst; /* Type of left hand side */
|
||||||
type* rhst; /* Type of right hand side */
|
Type* rhst; /* Type of right hand side */
|
||||||
CodeMark Mark1; /* Save position of output queue */
|
CodeMark Mark1; /* Save position of output queue */
|
||||||
CodeMark Mark2; /* Another position in the queue */
|
CodeMark Mark2; /* Another position in the queue */
|
||||||
int rscale; /* Scale factor for the result */
|
int rscale; /* Scale factor for the result */
|
||||||
|
@ -2505,7 +2505,7 @@ static void hieQuest (ExprDesc* Expr)
|
||||||
ExprDesc Expr3; /* Expression 3 */
|
ExprDesc Expr3; /* Expression 3 */
|
||||||
int Expr2IsNULL; /* Expression 2 is a NULL pointer */
|
int Expr2IsNULL; /* Expression 2 is a NULL pointer */
|
||||||
int Expr3IsNULL; /* Expression 3 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 */
|
/* Call the lower level eval routine */
|
||||||
|
|
|
@ -33,7 +33,7 @@ void PushAddr (const ExprDesc* Expr);
|
||||||
* must be saved if it's not constant, before evaluating the rhs.
|
* 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
|
/* 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 given, use this type when storing instead of lval->Type. If StoreType
|
||||||
* is NULL, use lval->Type instead.
|
* is NULL, use lval->Type instead.
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* (C) 2002-2004 Ullrich von Bassewitz */
|
/* (C) 2002-2006 Ullrich von Bassewitz */
|
||||||
/* Römerstraße 52 */
|
/* Römerstraße 52 */
|
||||||
/* D-70794 Filderstadt */
|
/* D-70794 Filderstadt */
|
||||||
/* EMail: uz@cc65.org */
|
/* EMail: uz@cc65.org */
|
||||||
|
@ -133,7 +133,7 @@ int ED_GetStackOffs (const ExprDesc* Expr, int 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. */
|
/* Make Expr an absolute const with the given value and type. */
|
||||||
{
|
{
|
||||||
Expr->Sym = 0;
|
Expr->Sym = 0;
|
||||||
|
@ -325,10 +325,10 @@ void PrintExprDesc (FILE* F, ExprDesc* E)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
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 */
|
/* 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);
|
Expr->Type = TypeDup (NewType);
|
||||||
return OldType;
|
return OldType;
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* (C) 2002-2004 Ullrich von Bassewitz */
|
/* (C) 2002-2006 Ullrich von Bassewitz */
|
||||||
/* Römerstraße 52 */
|
/* Römerstraße 52 */
|
||||||
/* D-70794 Filderstadt */
|
/* D-70794 Filderstadt */
|
||||||
/* EMail: uz@cc65.org */
|
/* EMail: uz@cc65.org */
|
||||||
|
@ -85,7 +85,7 @@ enum {
|
||||||
typedef struct ExprDesc ExprDesc;
|
typedef struct ExprDesc ExprDesc;
|
||||||
struct ExprDesc {
|
struct ExprDesc {
|
||||||
struct SymEntry* Sym; /* Symbol table entry if known */
|
struct SymEntry* Sym; /* Symbol table entry if known */
|
||||||
type* Type; /* Type array of expression */
|
Type* Type; /* Type array of expression */
|
||||||
unsigned Flags;
|
unsigned Flags;
|
||||||
unsigned long Name; /* Name or label number */
|
unsigned long Name; /* Name or label number */
|
||||||
long IVal; /* Integer value if expression constant */
|
long IVal; /* Integer value if expression constant */
|
||||||
|
@ -285,7 +285,7 @@ int ED_GetStackOffs (const ExprDesc* Expr, int Offs);
|
||||||
* an additional offset in Offs.
|
* 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. */
|
/* Make Expr an absolute const with the given value and type. */
|
||||||
|
|
||||||
ExprDesc* ED_MakeConstAbsInt (ExprDesc* Expr, long Value);
|
ExprDesc* ED_MakeConstAbsInt (ExprDesc* Expr, long Value);
|
||||||
|
@ -334,7 +334,7 @@ int ED_IsBool (const ExprDesc* Expr);
|
||||||
void PrintExprDesc (FILE* F, ExprDesc* Expr);
|
void PrintExprDesc (FILE* F, ExprDesc* Expr);
|
||||||
/* Print an ExprDesc */
|
/* 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 */
|
/* Replace the type of Expr by a copy of Newtype and return the old type string */
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* (C) 2000-2004 Ullrich von Bassewitz */
|
/* (C) 2000-2006 Ullrich von Bassewitz */
|
||||||
/* Römerstrasse 52 */
|
/* Römerstrasse 52 */
|
||||||
/* D-70794 Filderstadt */
|
/* D-70794 Filderstadt */
|
||||||
/* EMail: uz@cc65.org */
|
/* EMail: uz@cc65.org */
|
||||||
|
@ -65,7 +65,7 @@
|
||||||
/* Structure that holds all data needed for function activation */
|
/* Structure that holds all data needed for function activation */
|
||||||
struct Function {
|
struct Function {
|
||||||
struct SymEntry* FuncEntry; /* Symbol table entry */
|
struct SymEntry* FuncEntry; /* Symbol table entry */
|
||||||
type* ReturnType; /* Function return type */
|
Type* ReturnType; /* Function return type */
|
||||||
struct FuncDesc* Desc; /* Function descriptor */
|
struct FuncDesc* Desc; /* Function descriptor */
|
||||||
int Reserved; /* Reserved local space */
|
int Reserved; /* Reserved local space */
|
||||||
unsigned RetLab; /* Return code label */
|
unsigned RetLab; /* Return code label */
|
||||||
|
@ -93,7 +93,7 @@ static Function* NewFunction (struct SymEntry* Sym)
|
||||||
/* Initialize the fields */
|
/* Initialize the fields */
|
||||||
F->FuncEntry = Sym;
|
F->FuncEntry = Sym;
|
||||||
F->ReturnType = GetFuncReturn (Sym->Type);
|
F->ReturnType = GetFuncReturn (Sym->Type);
|
||||||
F->Desc = (FuncDesc*) DecodePtr (Sym->Type + 1);
|
F->Desc = GetFuncDesc (Sym->Type);
|
||||||
F->Reserved = 0;
|
F->Reserved = 0;
|
||||||
F->RetLab = GetLocalLabel ();
|
F->RetLab = GetLocalLabel ();
|
||||||
F->TopLevelSP = 0;
|
F->TopLevelSP = 0;
|
||||||
|
@ -137,7 +137,7 @@ unsigned F_GetParamSize (const Function* F)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
type* F_GetReturnType (Function* F)
|
Type* F_GetReturnType (Function* F)
|
||||||
/* Get the return type for the function */
|
/* Get the return type for the function */
|
||||||
{
|
{
|
||||||
return F->ReturnType;
|
return F->ReturnType;
|
||||||
|
@ -224,7 +224,7 @@ void F_AllocLocalSpace (Function* F)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
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
|
/* Allocate a register variable for the given variable type. If the allocation
|
||||||
* was successful, return the offset of the register variable in the register
|
* 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.
|
* bank (zero page storage). If there is no register space left, return -1.
|
||||||
|
@ -354,7 +354,7 @@ void NewFunc (SymEntry* Func)
|
||||||
AddConstSym ("__fixargs__", type_uint, SC_DEF | SC_CONST, D->ParamSize);
|
AddConstSym ("__fixargs__", type_uint, SC_DEF | SC_CONST, D->ParamSize);
|
||||||
if (D->Flags & FD_VARIADIC) {
|
if (D->Flags & FD_VARIADIC) {
|
||||||
/* Variadic function. The variable must be const. */
|
/* 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);
|
AddLocalSym ("__argsize__", T, SC_DEF | SC_REF | SC_AUTO, 0);
|
||||||
} else {
|
} else {
|
||||||
/* Non variadic */
|
/* Non variadic */
|
||||||
|
@ -374,10 +374,10 @@ void NewFunc (SymEntry* Func)
|
||||||
Error ("`main' cannot be declared as __fastcall__");
|
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.
|
* 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");
|
Error ("`main' must always return an int");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -6,9 +6,9 @@
|
||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* (C) 1998-2001 Ullrich von Bassewitz */
|
/* (C) 1998-2006 Ullrich von Bassewitz */
|
||||||
/* Wacholderweg 14 */
|
/* Römerstrasse 52 */
|
||||||
/* D-70597 Stuttgart */
|
/* D-70794 Filderstadt */
|
||||||
/* EMail: uz@cc65.org */
|
/* EMail: uz@cc65.org */
|
||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
|
@ -67,7 +67,7 @@ unsigned F_GetParamCount (const Function* F);
|
||||||
unsigned F_GetParamSize (const Function* F);
|
unsigned F_GetParamSize (const Function* F);
|
||||||
/* Return the parameter size for the current function */
|
/* 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 */
|
/* Get the return type for the function */
|
||||||
|
|
||||||
int F_HasVoidReturn (const Function* F);
|
int F_HasVoidReturn (const Function* F);
|
||||||
|
@ -98,7 +98,7 @@ void F_AllocLocalSpace (Function* F);
|
||||||
* nothing if there is no reserved local space.
|
* 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
|
/* Allocate a register variable for the given variable type. If the allocation
|
||||||
* was successful, return the offset of the register variable in the register
|
* 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.
|
* bank (zero page storage). If there is no register space left, return -1.
|
||||||
|
|
|
@ -193,7 +193,7 @@ struct Token {
|
||||||
double FVal; /* The float attribute */
|
double FVal; /* The float attribute */
|
||||||
ident Ident; /* Identifier if IDENT */
|
ident Ident; /* Identifier if IDENT */
|
||||||
LineInfo* LI; /* Source line where the token comes from */
|
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 */
|
extern Token CurTok; /* The current token */
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* (C) 2004 Ullrich von Bassewitz */
|
/* (C) 2004-2006 Ullrich von Bassewitz */
|
||||||
/* Römerstraße 52 */
|
/* Römerstraße 52 */
|
||||||
/* D-70794 Filderstadt */
|
/* D-70794 Filderstadt */
|
||||||
/* EMail: uz@cc65.org */
|
/* EMail: uz@cc65.org */
|
||||||
|
@ -65,8 +65,8 @@ void ShiftExpr (struct ExprDesc* Expr)
|
||||||
CodeMark Mark1;
|
CodeMark Mark1;
|
||||||
CodeMark Mark2;
|
CodeMark Mark2;
|
||||||
token_t Tok; /* The operator token */
|
token_t Tok; /* The operator token */
|
||||||
type* EffType; /* Effective lhs type */
|
Type* EffType; /* Effective lhs type */
|
||||||
type* ResultType; /* Type of the result */
|
Type* ResultType; /* Type of the result */
|
||||||
unsigned ExprBits; /* Bits of the lhs operand */
|
unsigned ExprBits; /* Bits of the lhs operand */
|
||||||
unsigned GenFlags; /* Generator flags */
|
unsigned GenFlags; /* Generator flags */
|
||||||
unsigned ltype;
|
unsigned ltype;
|
||||||
|
@ -185,7 +185,7 @@ void ShiftExpr (struct ExprDesc* Expr)
|
||||||
(ED_IsLocConst (Expr) || ED_IsLocStack (Expr)) &&
|
(ED_IsLocConst (Expr) || ED_IsLocStack (Expr)) &&
|
||||||
Expr2.IVal >= 8) {
|
Expr2.IVal >= 8) {
|
||||||
|
|
||||||
type* OldType;
|
Type* OldType;
|
||||||
|
|
||||||
/* Increase the address by one and decrease the shift count */
|
/* Increase the address by one and decrease the shift count */
|
||||||
++Expr->IVal;
|
++Expr->IVal;
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* (C) 2004 Ullrich von Bassewitz */
|
/* (C) 2004-2006 Ullrich von Bassewitz */
|
||||||
/* Römerstraße 52 */
|
/* Römerstraße 52 */
|
||||||
/* D-70794 Filderstadt */
|
/* D-70794 Filderstadt */
|
||||||
/* EMail: uz@cc65.org */
|
/* EMail: uz@cc65.org */
|
||||||
|
@ -55,7 +55,7 @@ int StackPtr = 0;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
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 */
|
/* Adjust the stackpointer for a push of an argument of the given type */
|
||||||
{
|
{
|
||||||
StackPtr -= SizeOf (T);
|
StackPtr -= SizeOf (T);
|
||||||
|
@ -63,12 +63,12 @@ void SP_Push (const type* 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 */
|
/* Adjust the stackpointer for a pop of an argument of the given type */
|
||||||
{
|
{
|
||||||
StackPtr += SizeOf (T);
|
StackPtr += SizeOf (T);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* (C) 2004 Ullrich von Bassewitz */
|
/* (C) 2004-2006 Ullrich von Bassewitz */
|
||||||
/* Römerstraße 52 */
|
/* Römerstraße 52 */
|
||||||
/* D-70794 Filderstadt */
|
/* D-70794 Filderstadt */
|
||||||
/* EMail: uz@cc65.org */
|
/* EMail: uz@cc65.org */
|
||||||
|
@ -37,7 +37,7 @@
|
||||||
#define STACKPTR_H
|
#define STACKPTR_H
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* cc65 */
|
/* cc65 */
|
||||||
#include "datatype.h"
|
#include "datatype.h"
|
||||||
|
|
||||||
|
@ -60,10 +60,10 @@ extern int StackPtr;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
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 */
|
/* 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 */
|
/* Adjust the stackpointer for a pop of an argument of the given type */
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* (C) 1998-2004 Ullrich von Bassewitz */
|
/* (C) 1998-2006 Ullrich von Bassewitz */
|
||||||
/* Römerstrasse 52 */
|
/* Römerstrasse 52 */
|
||||||
/* D-70794 Filderstadt */
|
/* D-70794 Filderstadt */
|
||||||
/* EMail: uz@cc65.org */
|
/* EMail: uz@cc65.org */
|
||||||
|
@ -93,9 +93,9 @@ static struct StdFuncDesc {
|
||||||
|
|
||||||
typedef struct ArgDesc ArgDesc;
|
typedef struct ArgDesc ArgDesc;
|
||||||
struct ArgDesc {
|
struct ArgDesc {
|
||||||
const type* ArgType; /* Required argument type */
|
const Type* ArgType; /* Required argument type */
|
||||||
ExprDesc Expr; /* Argument expression */
|
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 Start; /* Start of the code for calculation */
|
||||||
CodeMark Push; /* Start of argument push code */
|
CodeMark Push; /* Start of argument push code */
|
||||||
CodeMark End; /* End of the code for calculation+push */
|
CodeMark End; /* End of the code for calculation+push */
|
||||||
|
@ -139,7 +139,7 @@ static long ArrayElementCount (const ArgDesc* Arg)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
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
|
/* Parse one argument but do not push it onto the stack. Make all fields in
|
||||||
* Arg valid.
|
* Arg valid.
|
||||||
*/
|
*/
|
||||||
|
@ -192,10 +192,10 @@ static void ParseArg (ArgDesc* Arg, type* Type)
|
||||||
static void StdFunc_memcpy (FuncDesc* F attribute ((unused)), ExprDesc* Expr)
|
static void StdFunc_memcpy (FuncDesc* F attribute ((unused)), ExprDesc* Expr)
|
||||||
/* Handle the memcpy function */
|
/* Handle the memcpy function */
|
||||||
{
|
{
|
||||||
/* Argument types */
|
/* Argument types: (void*, const void*, size_t) */
|
||||||
static type Arg1Type[] = { T_PTR, T_VOID, T_END }; /* void* */
|
static Type Arg1Type[] = { TYPE(T_PTR), TYPE(T_VOID), TYPE(T_END) };
|
||||||
static type Arg2Type[] = { T_PTR, T_VOID|T_QUAL_CONST, T_END }; /* const void* */
|
static Type Arg2Type[] = { TYPE(T_PTR), TYPE(T_VOID|T_QUAL_CONST), TYPE(T_END) };
|
||||||
static type Arg3Type[] = { T_SIZE_T, T_END }; /* size_t */
|
static Type Arg3Type[] = { TYPE(T_SIZE_T), TYPE(T_END) };
|
||||||
|
|
||||||
CodeMark Start;
|
CodeMark Start;
|
||||||
ArgDesc Arg1, Arg2, Arg3;
|
ArgDesc Arg1, Arg2, Arg3;
|
||||||
|
@ -486,10 +486,10 @@ ExitPoint:
|
||||||
static void StdFunc_memset (FuncDesc* F attribute ((unused)), ExprDesc* Expr)
|
static void StdFunc_memset (FuncDesc* F attribute ((unused)), ExprDesc* Expr)
|
||||||
/* Handle the memset function */
|
/* Handle the memset function */
|
||||||
{
|
{
|
||||||
/* Argument types */
|
/* Argument types: (void*, int, size_t) */
|
||||||
static type Arg1Type[] = { T_PTR, T_VOID, T_END }; /* void* */
|
static Type Arg1Type[] = { TYPE(T_PTR), TYPE(T_VOID), TYPE(T_END) };
|
||||||
static type Arg2Type[] = { T_INT, T_END }; /* int */
|
static Type Arg2Type[] = { TYPE(T_INT), TYPE(T_END) };
|
||||||
static type Arg3Type[] = { T_SIZE_T, T_END }; /* size_t */
|
static Type Arg3Type[] = { TYPE(T_SIZE_T), TYPE(T_END) };
|
||||||
|
|
||||||
CodeMark Start;
|
CodeMark Start;
|
||||||
ArgDesc Arg1, Arg2, Arg3;
|
ArgDesc Arg1, Arg2, Arg3;
|
||||||
|
@ -702,9 +702,9 @@ ExitPoint:
|
||||||
static void StdFunc_strcpy (FuncDesc* F attribute ((unused)), ExprDesc* Expr)
|
static void StdFunc_strcpy (FuncDesc* F attribute ((unused)), ExprDesc* Expr)
|
||||||
/* Handle the strcpy function */
|
/* Handle the strcpy function */
|
||||||
{
|
{
|
||||||
/* Argument types */
|
/* Argument types: (char*, const char*) */
|
||||||
static type Arg1Type[] = { T_PTR, T_CHAR, T_END }; /* char* */
|
static Type Arg1Type[] = { TYPE(T_PTR), TYPE(T_CHAR), TYPE(T_END) };
|
||||||
static type Arg2Type[] = { T_PTR, T_CHAR|T_QUAL_CONST, T_END }; /* const char* */
|
static Type Arg2Type[] = { TYPE(T_PTR), TYPE(T_CHAR|T_QUAL_CONST), TYPE(T_END) };
|
||||||
|
|
||||||
CodeMark Start;
|
CodeMark Start;
|
||||||
ArgDesc Arg1, Arg2;
|
ArgDesc Arg1, Arg2;
|
||||||
|
@ -713,8 +713,8 @@ static void StdFunc_strcpy (FuncDesc* F attribute ((unused)), ExprDesc* Expr)
|
||||||
unsigned L1;
|
unsigned L1;
|
||||||
|
|
||||||
/* Setup the argument type string */
|
/* Setup the argument type string */
|
||||||
Arg1Type[1] = GetDefaultChar ();
|
Arg1Type[1].C = GetDefaultChar ();
|
||||||
Arg2Type[1] = GetDefaultChar () | T_QUAL_CONST;
|
Arg2Type[1].C = GetDefaultChar () | T_QUAL_CONST;
|
||||||
|
|
||||||
/* Remember where we are now */
|
/* Remember where we are now */
|
||||||
GetCodePos (&Start);
|
GetCodePos (&Start);
|
||||||
|
@ -893,7 +893,7 @@ static void StdFunc_strcpy (FuncDesc* F attribute ((unused)), ExprDesc* Expr)
|
||||||
static void StdFunc_strlen (FuncDesc* F attribute ((unused)), ExprDesc* Expr)
|
static void StdFunc_strlen (FuncDesc* F attribute ((unused)), ExprDesc* Expr)
|
||||||
/* Handle the strlen function */
|
/* 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;
|
ExprDesc Arg;
|
||||||
int IsArray;
|
int IsArray;
|
||||||
int IsPtr;
|
int IsPtr;
|
||||||
|
@ -904,7 +904,7 @@ static void StdFunc_strlen (FuncDesc* F attribute ((unused)), ExprDesc* Expr)
|
||||||
|
|
||||||
|
|
||||||
/* Setup the argument type string */
|
/* Setup the argument type string */
|
||||||
ArgType[1] = GetDefaultChar () | T_QUAL_CONST;
|
ArgType[1].C = GetDefaultChar () | T_QUAL_CONST;
|
||||||
|
|
||||||
/* Evaluate the parameter */
|
/* Evaluate the parameter */
|
||||||
hie1 (&Arg);
|
hie1 (&Arg);
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* (C) 1998-2004 Ullrich von Bassewitz */
|
/* (C) 1998-2006 Ullrich von Bassewitz */
|
||||||
/* Römerstraße 52 */
|
/* Römerstraße 52 */
|
||||||
/* D-70794 Filderstadt */
|
/* D-70794 Filderstadt */
|
||||||
/* EMail: uz@cc65.org */
|
/* EMail: uz@cc65.org */
|
||||||
|
@ -67,7 +67,7 @@ void SwitchStatement (void)
|
||||||
Collection* Nodes; /* CaseNode tree */
|
Collection* Nodes; /* CaseNode tree */
|
||||||
ExprDesc SwitchExpr; /* Switch statement expression */
|
ExprDesc SwitchExpr; /* Switch statement expression */
|
||||||
ExprDesc CaseExpr; /* Case label 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 CaseCodeStart; /* Start of code marker */
|
||||||
CodeMark SwitchCodeStart; /* Start of switch code */
|
CodeMark SwitchCodeStart; /* Start of switch code */
|
||||||
CodeMark SwitchCodeEnd; /* End of switch code */
|
CodeMark SwitchCodeEnd; /* End of switch code */
|
||||||
|
@ -116,7 +116,7 @@ void SwitchStatement (void)
|
||||||
ConsumeLCurly ();
|
ConsumeLCurly ();
|
||||||
|
|
||||||
/* Get the unqualified type of the switch expression */
|
/* 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 */
|
/* Get the number of bytes the selector type has */
|
||||||
Depth = SizeOf (SwitchExpr.Type);
|
Depth = SizeOf (SwitchExpr.Type);
|
||||||
|
@ -184,7 +184,7 @@ void SwitchStatement (void)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
Internal ("Invalid type: %04X", SwitchExprType);
|
Internal ("Invalid type: %06lX", SwitchExprType);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Insert the case selector into the selector table */
|
/* Insert the case selector into the selector table */
|
||||||
|
|
|
@ -6,9 +6,9 @@
|
||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* (C) 2000-2002 Ullrich von Bassewitz */
|
/* (C) 2000-2006 Ullrich von Bassewitz */
|
||||||
/* Wacholderweg 14 */
|
/* Römerstrasse 52 */
|
||||||
/* D-70597 Stuttgart */
|
/* D-70794 Filderstadt */
|
||||||
/* EMail: uz@cc65.org */
|
/* EMail: uz@cc65.org */
|
||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
|
@ -161,11 +161,11 @@ void CvtRegVarToAuto (SymEntry* Sym)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void ChangeSymType (SymEntry* Entry, type* Type)
|
void ChangeSymType (SymEntry* Entry, Type* T)
|
||||||
/* Change the type of the given symbol */
|
/* Change the type of the given symbol */
|
||||||
{
|
{
|
||||||
TypeFree (Entry->Type);
|
TypeFree (Entry->Type);
|
||||||
Entry->Type = TypeDup (Type);
|
Entry->Type = TypeDup (T);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -6,9 +6,9 @@
|
||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* (C) 2000-2002 Ullrich von Bassewitz */
|
/* (C) 2000-2006 Ullrich von Bassewitz */
|
||||||
/* Wacholderweg 14 */
|
/* Römerstrasse 52 */
|
||||||
/* D-70597 Stuttgart */
|
/* D-70794 Filderstadt */
|
||||||
/* EMail: uz@cc65.org */
|
/* EMail: uz@cc65.org */
|
||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
|
@ -100,7 +100,7 @@ struct SymEntry {
|
||||||
SymEntry* Link; /* General purpose single linked list */
|
SymEntry* Link; /* General purpose single linked list */
|
||||||
struct SymTable* Owner; /* Symbol table the symbol is in */
|
struct SymTable* Owner; /* Symbol table the symbol is in */
|
||||||
unsigned Flags; /* Symbol flags */
|
unsigned Flags; /* Symbol flags */
|
||||||
type* Type; /* Symbol type */
|
Type* Type; /* Symbol type */
|
||||||
char* AsmName; /* Assembler name if any */
|
char* AsmName; /* Assembler name if any */
|
||||||
|
|
||||||
/* Data that differs for the different symbol types */
|
/* Data that differs for the different symbol types */
|
||||||
|
@ -210,7 +210,7 @@ INLINE const char* SymGetAsmName (const SymEntry* Sym)
|
||||||
void CvtRegVarToAuto (SymEntry* Sym);
|
void CvtRegVarToAuto (SymEntry* Sym);
|
||||||
/* Convert a register variable to an auto variable */
|
/* 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 */
|
/* Change the type of the given symbol */
|
||||||
|
|
||||||
void ChangeAsmName (SymEntry* Entry, const char* NewAsmName);
|
void ChangeAsmName (SymEntry* Entry, const char* NewAsmName);
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* (C) 2000-2004 Ullrich von Bassewitz */
|
/* (C) 2000-2006 Ullrich von Bassewitz */
|
||||||
/* Römerstrasse 52 */
|
/* Römerstrasse 52 */
|
||||||
/* D-70794 Filderstadt */
|
/* D-70794 Filderstadt */
|
||||||
/* EMail: uz@cc65.org */
|
/* EMail: uz@cc65.org */
|
||||||
|
@ -472,23 +472,23 @@ SymEntry* FindTagSym (const char* Name)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
SymEntry* FindStructField (const type* Type, const char* Name)
|
SymEntry* FindStructField (const Type* T, const char* Name)
|
||||||
/* Find a struct field in the fields list */
|
/* Find a struct field in the fields list */
|
||||||
{
|
{
|
||||||
SymEntry* Field = 0;
|
SymEntry* Field = 0;
|
||||||
|
|
||||||
/* The given type may actually be a pointer to struct */
|
/* The given type may actually be a pointer to struct */
|
||||||
if (Type[0] == T_PTR) {
|
if (T->C == T_PTR) {
|
||||||
++Type;
|
++T;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Non-structs do not have any struct fields... */
|
/* Non-structs do not have any struct fields... */
|
||||||
if (IsClassStruct (Type)) {
|
if (IsClassStruct (T)) {
|
||||||
|
|
||||||
const SymTable* Tab;
|
const SymTable* Tab;
|
||||||
|
|
||||||
/* Get a pointer to the struct/union type */
|
/* Get a pointer to the struct/union type */
|
||||||
const SymEntry* Struct = (const SymEntry*) Decode (Type+1);
|
const SymEntry* Struct = GetSymEntry (T);
|
||||||
CHECK (Struct != 0);
|
CHECK (Struct != 0);
|
||||||
|
|
||||||
/* Get the field symbol table from the struct entry.
|
/* Get the field symbol table from the struct entry.
|
||||||
|
@ -582,7 +582,7 @@ SymEntry* AddStructSym (const char* Name, unsigned Size, SymTable* Tab)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
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 */
|
/* Add an constant symbol to the symbol table and return it */
|
||||||
{
|
{
|
||||||
/* Enums must be inserted in the global symbol table */
|
/* Enums must be inserted in the global symbol table */
|
||||||
|
@ -603,7 +603,7 @@ SymEntry* AddConstSym (const char* Name, const type* Type, unsigned Flags, long
|
||||||
Entry = NewSymEntry (Name, Flags);
|
Entry = NewSymEntry (Name, Flags);
|
||||||
|
|
||||||
/* Enum values are ints */
|
/* Enum values are ints */
|
||||||
Entry->Type = TypeDup (Type);
|
Entry->Type = TypeDup (T);
|
||||||
|
|
||||||
/* Set the enum data */
|
/* Set the enum data */
|
||||||
Entry->V.ConstVal = Val;
|
Entry->V.ConstVal = Val;
|
||||||
|
@ -652,7 +652,7 @@ SymEntry* AddLabelSym (const char* Name, unsigned Flags)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
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 */
|
/* Add a local symbol and return the symbol entry */
|
||||||
{
|
{
|
||||||
/* Do we have an entry with this name already? */
|
/* Do we have an entry with this name already? */
|
||||||
|
@ -668,12 +668,12 @@ SymEntry* AddLocalSym (const char* Name, const type* Type, unsigned Flags, int O
|
||||||
Entry = NewSymEntry (Name, Flags);
|
Entry = NewSymEntry (Name, Flags);
|
||||||
|
|
||||||
/* Set the symbol attributes */
|
/* Set the symbol attributes */
|
||||||
Entry->Type = TypeDup (Type);
|
Entry->Type = TypeDup (T);
|
||||||
if ((Flags & SC_AUTO) == SC_AUTO) {
|
if ((Flags & SC_AUTO) == SC_AUTO) {
|
||||||
Entry->V.Offs = Offs;
|
Entry->V.Offs = Offs;
|
||||||
} else if ((Flags & SC_REGISTER) == SC_REGISTER) {
|
} else if ((Flags & SC_REGISTER) == SC_REGISTER) {
|
||||||
Entry->V.R.RegOffs = Offs;
|
Entry->V.R.RegOffs = Offs;
|
||||||
Entry->V.R.SaveOffs = StackPtr;
|
Entry->V.R.SaveOffs = StackPtr;
|
||||||
} else if ((Flags & SC_STATIC) == SC_STATIC) {
|
} else if ((Flags & SC_STATIC) == SC_STATIC) {
|
||||||
/* Generate the assembler name from the label number */
|
/* Generate the assembler name from the label number */
|
||||||
Entry->V.Label = Offs;
|
Entry->V.Label = Offs;
|
||||||
|
@ -695,11 +695,11 @@ SymEntry* AddLocalSym (const char* Name, const type* Type, unsigned Flags, int O
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
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 */
|
/* 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 */
|
/* 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 */
|
/* Functions must be inserted in the global symbol table */
|
||||||
SymTable* Tab = IsFunc? SymTab0 : SymTab;
|
SymTable* Tab = IsFunc? SymTab0 : SymTab;
|
||||||
|
@ -708,7 +708,7 @@ SymEntry* AddGlobalSym (const char* Name, const type* Type, unsigned Flags)
|
||||||
SymEntry* Entry = FindSymInTable (Tab, Name, HashStr (Name));
|
SymEntry* Entry = FindSymInTable (Tab, Name, HashStr (Name));
|
||||||
if (Entry) {
|
if (Entry) {
|
||||||
|
|
||||||
type* EType;
|
Type* EType;
|
||||||
|
|
||||||
/* We have a symbol with this name already */
|
/* We have a symbol with this name already */
|
||||||
if (Entry->Flags & SC_TYPE) {
|
if (Entry->Flags & SC_TYPE) {
|
||||||
|
@ -723,28 +723,28 @@ SymEntry* AddGlobalSym (const char* Name, const type* Type, unsigned Flags)
|
||||||
* incomplete declaration. Accept this, and if the exsting entry is
|
* incomplete declaration. Accept this, and if the exsting entry is
|
||||||
* incomplete, complete it.
|
* incomplete, complete it.
|
||||||
*/
|
*/
|
||||||
if (IsTypeArray (Type) && IsTypeArray (EType)) {
|
if (IsTypeArray (T) && IsTypeArray (EType)) {
|
||||||
|
|
||||||
/* Get the array sizes */
|
/* Get the array sizes */
|
||||||
long Size = GetElementCount (Type);
|
long Size = GetElementCount (T);
|
||||||
long ESize = GetElementCount (EType);
|
long ESize = GetElementCount (EType);
|
||||||
|
|
||||||
if ((Size != UNSPECIFIED && ESize != UNSPECIFIED && Size != ESize) ||
|
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 */
|
/* Types not identical: Conflicting types */
|
||||||
Error ("Conflicting types for `%s'", Name);
|
Error ("Conflicting types for `%s'", Name);
|
||||||
return Entry;
|
return Entry;
|
||||||
} else {
|
} else {
|
||||||
/* Check if we have a size in the existing definition */
|
/* Check if we have a size in the existing definition */
|
||||||
if (ESize == UNSPECIFIED) {
|
if (ESize == UNSPECIFIED) {
|
||||||
/* Existing, size not given, use size from new def */
|
/* Existing, size not given, use size from new def */
|
||||||
Encode (EType + 1, Size);
|
SetElementCount (EType, Size);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
/* New type must be identical */
|
/* New type must be identical */
|
||||||
if (TypeCmp (EType, Type) < TC_EQUAL) {
|
if (TypeCmp (EType, T) < TC_EQUAL) {
|
||||||
Error ("Conflicting types for `%s'", Name);
|
Error ("Conflicting types for `%s'", Name);
|
||||||
return Entry;
|
return Entry;
|
||||||
}
|
}
|
||||||
|
@ -755,10 +755,10 @@ SymEntry* AddGlobalSym (const char* Name, const type* Type, unsigned Flags)
|
||||||
*/
|
*/
|
||||||
if (IsFunc) {
|
if (IsFunc) {
|
||||||
/* Get the function descriptor from the new type */
|
/* Get the function descriptor from the new type */
|
||||||
FuncDesc* F = GetFuncDesc (Type);
|
FuncDesc* F = GetFuncDesc (T);
|
||||||
/* Use this new function descriptor */
|
/* Use this new function descriptor */
|
||||||
Entry->V.F.Func = F;
|
Entry->V.F.Func = F;
|
||||||
EncodePtr (EType+1, F);
|
SetFuncDesc (EType, F);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -773,7 +773,7 @@ SymEntry* AddGlobalSym (const char* Name, const type* Type, unsigned Flags)
|
||||||
Entry = NewSymEntry (Name, Flags);
|
Entry = NewSymEntry (Name, Flags);
|
||||||
|
|
||||||
/* Set the symbol attributes */
|
/* Set the symbol attributes */
|
||||||
Entry->Type = TypeDup (Type);
|
Entry->Type = TypeDup (T);
|
||||||
|
|
||||||
/* If this is a function, set the function descriptor and clear
|
/* If this is a function, set the function descriptor and clear
|
||||||
* additional fields.
|
* additional fields.
|
||||||
|
|
|
@ -133,7 +133,7 @@ SymEntry* FindLocalSym (const char* Name);
|
||||||
SymEntry* FindTagSym (const char* Name);
|
SymEntry* FindTagSym (const char* Name);
|
||||||
/* Find the symbol with the given name in the tag table */
|
/* 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 */
|
/* Find a struct field in the fields list */
|
||||||
|
|
||||||
|
|
||||||
|
@ -147,16 +147,16 @@ SymEntry* FindStructField (const type* TypeArray, const char* Name);
|
||||||
SymEntry* AddStructSym (const char* Name, unsigned Size, SymTable* Tab);
|
SymEntry* AddStructSym (const char* Name, unsigned Size, SymTable* Tab);
|
||||||
/* Add a struct/union entry and return it */
|
/* 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 */
|
/* Add an constant symbol to the symbol table and return it */
|
||||||
|
|
||||||
SymEntry* AddLabelSym (const char* Name, unsigned Flags);
|
SymEntry* AddLabelSym (const char* Name, unsigned Flags);
|
||||||
/* Add a goto label to the symbol table */
|
/* 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 */
|
/* 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 */
|
/* Add an external or global symbol to the symbol table and return the entry */
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -125,7 +125,7 @@ static int EqualSymTables (SymTable* Tab1, SymTable* Tab2)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
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. */
|
/* Recursively compare two types. */
|
||||||
{
|
{
|
||||||
unsigned Indirections;
|
unsigned Indirections;
|
||||||
|
@ -144,15 +144,15 @@ static void DoCompare (const type* lhs, const type* rhs, typecmp_t* Result)
|
||||||
ElementCount = 0;
|
ElementCount = 0;
|
||||||
|
|
||||||
/* Compare two types. Determine, where they differ */
|
/* Compare two types. Determine, where they differ */
|
||||||
while (*lhs != T_END) {
|
while (lhs->C != T_END) {
|
||||||
|
|
||||||
type LeftType, RightType;
|
TypeCode LeftType, RightType;
|
||||||
type LeftSign, RightSign;
|
TypeCode LeftSign, RightSign;
|
||||||
type LeftQual, RightQual;
|
TypeCode LeftQual, RightQual;
|
||||||
long LeftCount, RightCount;
|
long LeftCount, RightCount;
|
||||||
|
|
||||||
/* Check if the end of the type string is reached */
|
/* Check if the end of the type string is reached */
|
||||||
if (*rhs == T_END) {
|
if (rhs->C == T_END) {
|
||||||
/* End of comparison reached */
|
/* End of comparison reached */
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -170,7 +170,6 @@ static void DoCompare (const type* lhs, const type* rhs, typecmp_t* Result)
|
||||||
*/
|
*/
|
||||||
if (LeftType == T_TYPE_PTR && RightType == T_TYPE_ARRAY) {
|
if (LeftType == T_TYPE_PTR && RightType == T_TYPE_ARRAY) {
|
||||||
RightType = T_TYPE_PTR;
|
RightType = T_TYPE_PTR;
|
||||||
rhs += DECODE_SIZE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If the raw types are not identical, the types are incompatible */
|
/* If the raw types are not identical, the types are incompatible */
|
||||||
|
@ -231,8 +230,8 @@ static void DoCompare (const type* lhs, const type* rhs, typecmp_t* Result)
|
||||||
|
|
||||||
case T_TYPE_FUNC:
|
case T_TYPE_FUNC:
|
||||||
/* Compare the function descriptors */
|
/* Compare the function descriptors */
|
||||||
F1 = DecodePtr (lhs+1);
|
F1 = GetFuncDesc (lhs);
|
||||||
F2 = DecodePtr (rhs+1);
|
F2 = GetFuncDesc (rhs);
|
||||||
|
|
||||||
/* If one of the functions is implicitly declared, both
|
/* If one of the functions is implicitly declared, both
|
||||||
* functions are considered equal. If one of the functions is
|
* functions are considered equal. If one of the functions is
|
||||||
|
@ -267,9 +266,7 @@ static void DoCompare (const type* lhs, const type* rhs, typecmp_t* Result)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Skip the FuncDesc pointers to compare the return type */
|
/* Keep on and compare the return type */
|
||||||
lhs += DECODE_SIZE;
|
|
||||||
rhs += DECODE_SIZE;
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case T_TYPE_ARRAY:
|
case T_TYPE_ARRAY:
|
||||||
|
@ -283,8 +280,6 @@ static void DoCompare (const type* lhs, const type* rhs, typecmp_t* Result)
|
||||||
SetResult (Result, TC_INCOMPATIBLE);
|
SetResult (Result, TC_INCOMPATIBLE);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
lhs += DECODE_SIZE;
|
|
||||||
rhs += DECODE_SIZE;
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case T_TYPE_STRUCT:
|
case T_TYPE_STRUCT:
|
||||||
|
@ -293,8 +288,8 @@ static void DoCompare (const type* lhs, const type* rhs, typecmp_t* Result)
|
||||||
* pointer to the struct definition from the type, and compare
|
* pointer to the struct definition from the type, and compare
|
||||||
* the fields.
|
* the fields.
|
||||||
*/
|
*/
|
||||||
Sym1 = DecodePtr (lhs+1);
|
Sym1 = GetSymEntry (lhs);
|
||||||
Sym2 = DecodePtr (rhs+1);
|
Sym2 = GetSymEntry (rhs);
|
||||||
|
|
||||||
/* If one symbol has a name, the names must be identical */
|
/* If one symbol has a name, the names must be identical */
|
||||||
if (!HasAnonName (Sym1) || !HasAnonName (Sym2)) {
|
if (!HasAnonName (Sym1) || !HasAnonName (Sym2)) {
|
||||||
|
@ -324,8 +319,6 @@ static void DoCompare (const type* lhs, const type* rhs, typecmp_t* Result)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Structs are equal */
|
/* Structs are equal */
|
||||||
lhs += DECODE_SIZE;
|
|
||||||
rhs += DECODE_SIZE;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -336,7 +329,7 @@ static void DoCompare (const type* lhs, const type* rhs, typecmp_t* Result)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check if end of rhs reached */
|
/* Check if end of rhs reached */
|
||||||
if (*rhs == T_END) {
|
if (rhs->C == T_END) {
|
||||||
SetResult (Result, TC_EQUAL);
|
SetResult (Result, TC_EQUAL);
|
||||||
} else {
|
} else {
|
||||||
SetResult (Result, TC_INCOMPATIBLE);
|
SetResult (Result, TC_INCOMPATIBLE);
|
||||||
|
@ -345,7 +338,7 @@ static void DoCompare (const type* lhs, const type* rhs, typecmp_t* Result)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
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 */
|
/* Compare two types and return the result */
|
||||||
{
|
{
|
||||||
/* Assume the types are identical */
|
/* Assume the types are identical */
|
||||||
|
@ -367,3 +360,4 @@ typecmp_t TypeCmp (const type* lhs, const type* rhs)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -67,7 +67,7 @@ typedef enum {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
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 */
|
/* Compare two types and return the result */
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* (C) 2002-2004 Ullrich von Bassewitz */
|
/* (C) 2002-2006 Ullrich von Bassewitz */
|
||||||
/* Römerstrasse 52 */
|
/* Römerstrasse 52 */
|
||||||
/* D-70794 Filderstadt */
|
/* D-70794 Filderstadt */
|
||||||
/* EMail: uz@cc65.org */
|
/* EMail: uz@cc65.org */
|
||||||
|
@ -55,10 +55,10 @@
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
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. */
|
/* Emit code to convert the given expression to a new type. */
|
||||||
{
|
{
|
||||||
type* OldType;
|
Type* OldType;
|
||||||
unsigned OldSize;
|
unsigned OldSize;
|
||||||
unsigned NewSize;
|
unsigned NewSize;
|
||||||
|
|
||||||
|
@ -162,7 +162,7 @@ ExitPoint:
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
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
|
/* Do an automatic conversion of the given expression to the new type. Output
|
||||||
* warnings or errors where this automatic conversion is suspicious or
|
* warnings or errors where this automatic conversion is suspicious or
|
||||||
* impossible.
|
* impossible.
|
||||||
|
@ -264,7 +264,7 @@ void TypeCast (ExprDesc* Expr)
|
||||||
* expression is an lvalue and false if not.
|
* expression is an lvalue and false if not.
|
||||||
*/
|
*/
|
||||||
{
|
{
|
||||||
type NewType[MAXTYPELEN];
|
Type NewType[MAXTYPELEN];
|
||||||
|
|
||||||
/* Skip the left paren */
|
/* Skip the left paren */
|
||||||
NextToken ();
|
NextToken ();
|
||||||
|
@ -288,3 +288,4 @@ void TypeCast (ExprDesc* Expr)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* (C) 2002-2004 Ullrich von Bassewitz */
|
/* (C) 2002-2006 Ullrich von Bassewitz */
|
||||||
/* Römerstrasse 52 */
|
/* Römerstrasse 52 */
|
||||||
/* D-70794 Filderstadt */
|
/* D-70794 Filderstadt */
|
||||||
/* EMail: uz@cc65.org */
|
/* EMail: uz@cc65.org */
|
||||||
|
@ -49,7 +49,7 @@
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
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
|
/* Do an automatic conversion of the given expression to the new type. Output
|
||||||
* warnings or errors where this automatic conversion is suspicious or
|
* warnings or errors where this automatic conversion is suspicious or
|
||||||
* impossible.
|
* impossible.
|
||||||
|
|
Loading…
Add table
Reference in a new issue