mirror of
https://github.com/cc65/cc65.git
synced 2024-12-28 06:30:16 +00:00
Merge pull request #1783 from acqn/MiscFixes
[cc65] Misc fixes and improvements
This commit is contained in:
commit
82b268ee50
@ -49,21 +49,6 @@
|
||||
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Data */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
|
||||
/* Map a generator function and its attributes to a token */
|
||||
typedef struct GenDesc {
|
||||
token_t Tok; /* Token to map to */
|
||||
unsigned Flags; /* Flags for generator function */
|
||||
void (*Func) (unsigned, unsigned long); /* Generator func */
|
||||
} GenDesc;
|
||||
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Code */
|
||||
/*****************************************************************************/
|
||||
|
@ -218,14 +218,16 @@ static void Parse (void)
|
||||
** void types in ISO modes.
|
||||
*/
|
||||
if (Size == 0) {
|
||||
if (!IsTypeVoid (Decl.Type)) {
|
||||
if (!IsEmptiableObjectType (Decl.Type)) {
|
||||
if (!IsTypeArray (Decl.Type)) {
|
||||
/* Size is unknown and not an array */
|
||||
Error ("Variable '%s' has unknown size", Decl.Ident);
|
||||
Error ("Cannot initialize variable '%s' of unknown size", Decl.Ident);
|
||||
}
|
||||
} else if (IS_Get (&Standard) != STD_CC65) {
|
||||
/* We cannot declare variables of type void */
|
||||
Error ("Illegal type for variable '%s'", Decl.Ident);
|
||||
Error ("Illegal type '%s' for variable '%s'",
|
||||
GetFullTypeName (Decl.Type),
|
||||
Decl.Ident);
|
||||
}
|
||||
}
|
||||
|
||||
@ -253,7 +255,7 @@ static void Parse (void)
|
||||
/* We cannot declare variables of type void */
|
||||
Error ("Illegal type for variable '%s'", Decl.Ident);
|
||||
Entry->Flags &= ~(SC_STORAGE | SC_DEF);
|
||||
} else if (Size == 0 && SymIsDef (Entry)) {
|
||||
} else if (Size == 0 && SymIsDef (Entry) && !IsEmptiableObjectType (Decl.Type)) {
|
||||
/* Size is unknown. Is it an array? */
|
||||
if (!IsTypeArray (Decl.Type)) {
|
||||
Error ("Variable '%s' has unknown size", Decl.Ident);
|
||||
|
@ -805,7 +805,11 @@ unsigned CheckedSizeOf (const Type* T)
|
||||
{
|
||||
unsigned Size = SizeOf (T);
|
||||
if (Size == 0) {
|
||||
Error ("Size of type '%s' is unknown", GetFullTypeName (T));
|
||||
if (HasUnknownSize (T + 1)) {
|
||||
Error ("Size of type '%s' is unknown", GetFullTypeName (T));
|
||||
} else {
|
||||
Error ("Size of type '%s' is 0", GetFullTypeName (T));
|
||||
}
|
||||
Size = SIZEOF_CHAR; /* Don't return zero */
|
||||
}
|
||||
return Size;
|
||||
@ -821,7 +825,11 @@ unsigned CheckedPSizeOf (const Type* T)
|
||||
{
|
||||
unsigned Size = PSizeOf (T);
|
||||
if (Size == 0) {
|
||||
Error ("Size of type '%s' is unknown", GetFullTypeName (T + 1));
|
||||
if (HasUnknownSize (T + 1)) {
|
||||
Error ("Pointer to type '%s' of unknown size", GetFullTypeName (T + 1));
|
||||
} else {
|
||||
Error ("Pointer to type '%s' of 0 size", GetFullTypeName (T + 1));
|
||||
}
|
||||
Size = SIZEOF_CHAR; /* Don't return zero */
|
||||
}
|
||||
return Size;
|
||||
@ -999,6 +1007,25 @@ const Type* PtrConversion (const Type* T)
|
||||
|
||||
|
||||
|
||||
const Type* StdConversion (const Type* T)
|
||||
/* If the type is a function, convert it to pointer to function. If the
|
||||
** expression is an array, convert it to pointer to first element. If the
|
||||
** type is an integer, do integeral promotion. Otherwise return T.
|
||||
*/
|
||||
{
|
||||
if (IsTypeFunc (T)) {
|
||||
return AddressOf (T);
|
||||
} else if (IsTypeArray (T)) {
|
||||
return AddressOf (GetElementType (T));
|
||||
} else if (IsClassInt (T)) {
|
||||
return IntPromotion (T);
|
||||
} else {
|
||||
return T;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
const Type* IntPromotion (const Type* T)
|
||||
/* Apply the integer promotions to T and return the result. The returned type
|
||||
** string may be T if there is no need to change it.
|
||||
|
@ -368,6 +368,12 @@ const Type* PtrConversion (const Type* T);
|
||||
** return T.
|
||||
*/
|
||||
|
||||
const Type* StdConversion (const Type* T);
|
||||
/* If the type is a function, convert it to pointer to function. If the
|
||||
** expression is an array, convert it to pointer to first element. If the
|
||||
** type is an integer, do integeral promotion. Otherwise return T.
|
||||
*/
|
||||
|
||||
const Type* IntPromotion (const Type* T);
|
||||
/* Apply the integer promotions to T and return the result. The returned type
|
||||
** string may be T if there is no need to change it.
|
||||
|
@ -48,13 +48,6 @@
|
||||
|
||||
|
||||
|
||||
/* Map a generator function and its attributes to a token */
|
||||
typedef struct GenDesc {
|
||||
token_t Tok; /* Token to map to */
|
||||
unsigned Flags; /* Flags for generator function */
|
||||
void (*Func) (unsigned, unsigned long); /* Generator func */
|
||||
} GenDesc;
|
||||
|
||||
/* Descriptors for the operations */
|
||||
static GenDesc GenPASGN = { TOK_PLUS_ASSIGN, GEN_NOPUSH, g_add };
|
||||
static GenDesc GenSASGN = { TOK_MINUS_ASSIGN, GEN_NOPUSH, g_sub };
|
||||
@ -243,7 +236,7 @@ static const GenDesc* FindGen (token_t Tok, const GenDesc* Table)
|
||||
/* Find a token in a generator table */
|
||||
{
|
||||
while (Table->Tok != TOK_INVALID) {
|
||||
if (Table->Tok == Tok) {
|
||||
if ((token_t)Table->Tok == Tok) {
|
||||
return Table;
|
||||
}
|
||||
++Table;
|
||||
@ -772,9 +765,10 @@ static unsigned FunctionArgList (FuncDesc* Func, int IsFastcall, ExprDesc* ED)
|
||||
} else {
|
||||
|
||||
/* No prototype available. Convert array to "pointer to first
|
||||
** element", and function to "pointer to function".
|
||||
** element", function to "pointer to function" and do integral
|
||||
** promotion if necessary.
|
||||
*/
|
||||
Expr.Type = PtrConversion (Expr.Type);
|
||||
TypeConversion (&Expr, StdConversion (Expr.Type));
|
||||
|
||||
}
|
||||
|
||||
@ -1133,7 +1127,7 @@ static void Primary (ExprDesc* E)
|
||||
/* output its label */
|
||||
E->Flags = E_RTYPE_RVAL | E_LOC_CODE | E_ADDRESS_OF;
|
||||
E->Name = Entry->V.L.Label;
|
||||
E->Type = NewPointerTo (type_void);
|
||||
E->Type = type_void_p;
|
||||
NextToken ();
|
||||
} else {
|
||||
Error ("Computed gotos are a C extension, not supported with this --standard");
|
||||
@ -1952,7 +1946,7 @@ void hie10 (ExprDesc* Expr)
|
||||
/* The & operator yields an rvalue address */
|
||||
ED_AddrExpr (Expr);
|
||||
}
|
||||
Expr->Type = NewPointerTo (Expr->Type);
|
||||
Expr->Type = AddressOf (Expr->Type);
|
||||
break;
|
||||
|
||||
case TOK_SIZEOF:
|
||||
@ -2271,9 +2265,9 @@ static void hie_compare (const GenDesc* Ops, /* List of generators */
|
||||
Tok = CurTok.Tok;
|
||||
NextToken ();
|
||||
|
||||
/* If lhs is a function, convert it to pointer to function */
|
||||
/* If lhs is a function, convert it to the address of the function */
|
||||
if (IsTypeFunc (Expr->Type)) {
|
||||
Expr->Type = NewPointerTo (Expr->Type);
|
||||
Expr->Type = AddressOf (Expr->Type);
|
||||
}
|
||||
|
||||
/* Get the lhs on stack */
|
||||
@ -2293,9 +2287,9 @@ static void hie_compare (const GenDesc* Ops, /* List of generators */
|
||||
/* Get the right hand side */
|
||||
MarkedExprWithCheck (hienext, &Expr2);
|
||||
|
||||
/* If rhs is a function, convert it to pointer to function */
|
||||
/* If rhs is a function, convert it to the address of the function */
|
||||
if (IsTypeFunc (Expr2.Type)) {
|
||||
Expr2.Type = NewPointerTo (Expr2.Type);
|
||||
Expr2.Type = AddressOf (Expr2.Type);
|
||||
}
|
||||
|
||||
/* Check for a numeric constant expression */
|
||||
@ -3069,7 +3063,7 @@ static void parseadd (ExprDesc* Expr, int DoArrayRef)
|
||||
Error ("Invalid operands for binary operator '+'");
|
||||
} else {
|
||||
/* Array and function types must be converted to pointer types */
|
||||
Expr->Type = PtrConversion (Expr->Type);
|
||||
Expr->Type = StdConversion (Expr->Type);
|
||||
}
|
||||
}
|
||||
|
||||
@ -3348,7 +3342,7 @@ static void parsesub (ExprDesc* Expr)
|
||||
}
|
||||
|
||||
/* Result type is either a pointer or an integer */
|
||||
Expr->Type = PtrConversion (Expr->Type);
|
||||
Expr->Type = StdConversion (Expr->Type);
|
||||
|
||||
/* Condition code not set */
|
||||
ED_MarkAsUntested (Expr);
|
||||
|
@ -26,13 +26,20 @@
|
||||
#define SQP_KEEP_NONE 0x00
|
||||
#define SQP_KEEP_TEST 0x01U
|
||||
#define SQP_KEEP_EAX 0x02U
|
||||
#define SQP_KEEP_EXPR 0x03U /* SQP_KEEP_TEST | SQP_KEEP_EAX */
|
||||
#define SQP_KEEP_EXPR 0x03U /* SQP_KEEP_TEST | SQP_KEEP_EAX */
|
||||
|
||||
/* Generator attributes */
|
||||
#define GEN_NOPUSH 0x01 /* Don't push lhs */
|
||||
#define GEN_COMM 0x02 /* Operator is commutative */
|
||||
#define GEN_NOFUNC 0x04 /* Not allowed for function pointers */
|
||||
|
||||
/* Map a generator function and its attributes to a token */
|
||||
typedef struct GenDesc {
|
||||
long Tok; /* Token to map to */
|
||||
unsigned Flags; /* Flags for generator function */
|
||||
void (*Func) (unsigned, unsigned long); /* Generator func */
|
||||
} GenDesc;
|
||||
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
|
@ -93,8 +93,7 @@ int ED_IsLocPrimaryOrExpr (const ExprDesc* Expr)
|
||||
int ED_IsIndExpr (const ExprDesc* Expr)
|
||||
/* Check if the expression is a reference to its value */
|
||||
{
|
||||
return (Expr->Flags & E_ADDRESS_OF) == 0 &&
|
||||
!ED_IsLocNone (Expr) && !ED_IsLocPrimary (Expr);
|
||||
return (Expr->Flags & E_ADDRESS_OF) == 0 && !ED_IsLocNone (Expr);
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -282,7 +281,7 @@ ExprDesc* ED_AddrExpr (ExprDesc* Expr)
|
||||
|
||||
case E_LOC_EXPR:
|
||||
Expr->Flags &= ~(E_MASK_LOC | E_MASK_RTYPE);
|
||||
Expr->Flags |= E_LOC_PRIMARY | E_RTYPE_RVAL;
|
||||
Expr->Flags |= E_ADDRESS_OF | E_LOC_PRIMARY | E_RTYPE_RVAL;
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -493,8 +493,7 @@ INLINE int ED_IsAddrExpr (const ExprDesc* Expr)
|
||||
INLINE int ED_IsIndExpr (const ExprDesc* Expr)
|
||||
/* Check if the expression is a reference to its value */
|
||||
{
|
||||
return (Expr->Flags & E_ADDRESS_OF) == 0 &&
|
||||
!ED_IsLocNone (Expr) && !ED_IsLocPrimary (Expr);
|
||||
return (Expr->Flags & E_ADDRESS_OF) == 0 && !ED_IsLocNone (Expr);
|
||||
}
|
||||
#else
|
||||
int ED_IsIndExpr (const ExprDesc* Expr);
|
||||
|
@ -92,6 +92,7 @@ static void LoadAddress (unsigned Flags, ExprDesc* Expr)
|
||||
g_leasp (Expr->IVal);
|
||||
break;
|
||||
|
||||
case E_LOC_PRIMARY:
|
||||
case E_LOC_EXPR:
|
||||
if (Expr->IVal != 0) {
|
||||
/* We have an expression in the primary plus a constant
|
||||
|
@ -174,8 +174,8 @@ static void ParseRegisterDecl (Declaration* Decl, int Reg)
|
||||
Sym->Flags |= SC_REF;
|
||||
}
|
||||
|
||||
/* Cannot allocate a variable of zero size */
|
||||
if (Size == 0) {
|
||||
/* Cannot allocate a variable of unknown size */
|
||||
if (HasUnknownSize (Sym->Type)) {
|
||||
if (IsTypeArray (Decl->Type)) {
|
||||
Error ("Array '%s' has unknown size", Decl->Ident);
|
||||
} else {
|
||||
@ -370,8 +370,8 @@ static void ParseAutoDecl (Declaration* Decl)
|
||||
}
|
||||
}
|
||||
|
||||
/* Cannot allocate a variable of zero size */
|
||||
if (Size == 0) {
|
||||
/* Cannot allocate an incomplete variable */
|
||||
if (HasUnknownSize (Sym->Type)) {
|
||||
if (IsTypeArray (Decl->Type)) {
|
||||
Error ("Array '%s' has unknown size", Decl->Ident);
|
||||
} else {
|
||||
@ -428,8 +428,8 @@ static void ParseStaticDecl (Declaration* Decl)
|
||||
|
||||
}
|
||||
|
||||
/* Cannot allocate a variable of zero size */
|
||||
if (Size == 0) {
|
||||
/* Cannot allocate an incomplete variable */
|
||||
if (HasUnknownSize (Sym->Type)) {
|
||||
if (IsTypeArray (Decl->Type)) {
|
||||
Error ("Array '%s' has unknown size", Decl->Ident);
|
||||
} else {
|
||||
|
@ -206,7 +206,7 @@ void SwitchStatement (void)
|
||||
|
||||
|
||||
void CaseLabel (void)
|
||||
/* Handle a case sabel */
|
||||
/* Handle a case label */
|
||||
{
|
||||
ExprDesc CaseExpr; /* Case label expression */
|
||||
long Val; /* Case label value */
|
||||
|
@ -143,10 +143,10 @@ static void DoConversion (ExprDesc* Expr, const Type* NewType)
|
||||
|
||||
/* Do the integer constant <-> absolute address conversion if necessary */
|
||||
if (IsClassPtr (NewType)) {
|
||||
Expr->Flags &= ~E_LOC_NONE;
|
||||
Expr->Flags &= ~E_MASK_LOC;
|
||||
Expr->Flags |= E_LOC_ABS | E_ADDRESS_OF;
|
||||
} else if (IsClassInt (NewType)) {
|
||||
Expr->Flags &= ~(E_LOC_ABS | E_ADDRESS_OF);
|
||||
Expr->Flags &= ~(E_MASK_LOC | E_ADDRESS_OF);
|
||||
Expr->Flags |= E_LOC_NONE;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user