1
0
mirror of https://github.com/cc65/cc65.git synced 2024-12-24 11:31:31 +00:00

Inline parameter frame building

git-svn-id: svn://svn.cc65.org/cc65/trunk@661 b7a2c559-68d2-44c3-8de9-860c34a00d81
This commit is contained in:
cuz 2001-03-24 13:00:16 +00:00
parent 59bcc726b6
commit c18453ebcb
8 changed files with 279 additions and 158 deletions

View File

@ -652,63 +652,63 @@ void g_getimmed (unsigned flags, unsigned long val, unsigned offs)
{
if ((flags & CF_CONST) != 0) {
/* Numeric constant */
switch (flags & CF_TYPE) {
/* Numeric constant */
switch (flags & CF_TYPE) {
case CF_CHAR:
if ((flags & CF_FORCECHAR) != 0) {
ldaconst (val);
break;
}
/* FALL THROUGH */
case CF_INT:
ldxconst ((val >> 8) & 0xFF);
ldaconst (val & 0xFF);
break;
case CF_CHAR:
if ((flags & CF_FORCECHAR) != 0) {
ldaconst (val);
break;
}
/* FALL THROUGH */
case CF_INT:
ldxconst ((val >> 8) & 0xFF);
ldaconst (val & 0xFF);
break;
case CF_LONG:
if (val < 0x100) {
AddCodeLine ("\tldx\t#$00");
AddCodeLine ("\tstx\tsreg+1");
AddCodeLine ("\tstx\tsreg");
AddCodeLine ("\tlda\t#$%02X", (unsigned char) val);
} else if ((val & 0xFFFF00FF) == 0) {
AddCodeLine ("\tlda\t#$00");
AddCodeLine ("\tsta\tsreg+1");
AddCodeLine ("\tsta\tsreg");
AddCodeLine ("\tldx\t#$%02X", (unsigned char) (val >> 8));
} else if ((val & 0xFFFF0000) == 0 && FavourSize == 0) {
AddCodeLine ("\tlda\t#$00");
AddCodeLine ("\tsta\tsreg+1");
AddCodeLine ("\tsta\tsreg");
AddCodeLine ("\tlda\t#$%02X", (unsigned char) val);
AddCodeLine ("\tldx\t#$%02X", (unsigned char) (val >> 8));
} else if ((val & 0xFFFFFF00) == 0xFFFFFF00) {
AddCodeLine ("\tldx\t#$FF");
AddCodeLine ("\tstx\tsreg+1");
AddCodeLine ("\tstx\tsreg");
if ((val & 0xFF) == 0xFF) {
AddCodeLine ("\ttxa");
} else {
AddCodeLine ("\tlda\t#$%02X", (unsigned char) val);
}
} else if ((val & 0xFFFF00FF) == 0xFFFF00FF) {
AddCodeLine ("\tlda\t#$FF");
AddCodeLine ("\tsta\tsreg+1");
AddCodeLine ("\tsta\tsreg");
AddCodeLine ("\tldx\t#$%02X", (unsigned char) (val >> 8));
} else {
/* Call a subroutine that will load following value */
AddCodeLine ("\tjsr\tldeax");
AddCodeLine ("\t.dword\t$%08lX", val & 0xFFFFFFFF);
}
break;
case CF_LONG:
if (val < 0x100) {
AddCodeLine ("\tldx\t#$00");
AddCodeLine ("\tstx\tsreg+1");
AddCodeLine ("\tstx\tsreg");
AddCodeLine ("\tlda\t#$%02X", (unsigned char) val);
} else if ((val & 0xFFFF00FF) == 0) {
AddCodeLine ("\tlda\t#$00");
AddCodeLine ("\tsta\tsreg+1");
AddCodeLine ("\tsta\tsreg");
AddCodeLine ("\tldx\t#$%02X", (unsigned char) (val >> 8));
} else if ((val & 0xFFFF0000) == 0 && FavourSize == 0) {
AddCodeLine ("\tlda\t#$00");
AddCodeLine ("\tsta\tsreg+1");
AddCodeLine ("\tsta\tsreg");
AddCodeLine ("\tlda\t#$%02X", (unsigned char) val);
AddCodeLine ("\tldx\t#$%02X", (unsigned char) (val >> 8));
} else if ((val & 0xFFFFFF00) == 0xFFFFFF00) {
AddCodeLine ("\tldx\t#$FF");
AddCodeLine ("\tstx\tsreg+1");
AddCodeLine ("\tstx\tsreg");
if ((val & 0xFF) == 0xFF) {
AddCodeLine ("\ttxa");
} else {
AddCodeLine ("\tlda\t#$%02X", (unsigned char) val);
}
} else if ((val & 0xFFFF00FF) == 0xFFFF00FF) {
AddCodeLine ("\tlda\t#$FF");
AddCodeLine ("\tsta\tsreg+1");
AddCodeLine ("\tsta\tsreg");
AddCodeLine ("\tldx\t#$%02X", (unsigned char) (val >> 8));
} else {
/* Call a subroutine that will load following value */
AddCodeLine ("\tjsr\tldeax");
AddCodeLine ("\t.dword\t$%08lX", val & 0xFFFFFFFF);
}
break;
default:
typeerror (flags);
break;
default:
typeerror (flags);
break;
}
}
} else {
@ -1084,34 +1084,79 @@ void g_putstatic (unsigned flags, unsigned long label, unsigned offs)
void g_putlocal (unsigned flags, int offs)
void g_putlocal (unsigned Flags, int Offs, long Val)
/* Put data into local object. */
{
offs -= oursp;
CheckLocalOffs (offs);
switch (flags & CF_TYPE) {
Offs -= oursp;
CheckLocalOffs (Offs);
switch (Flags & CF_TYPE) {
case CF_CHAR:
if (CPU == CPU_65C02 && offs == 0) {
AddCodeLine ("\tsta\t(sp)");
} else {
ldyconst (offs);
AddCodeLine ("\tsta\t(sp),y");
if (Flags & CF_CONST) {
AddCodeLine ("\tlda\t#$%02X", (unsigned char) Val);
}
break;
case CF_INT:
if (offs) {
ldyconst (offs);
AddCodeLine ("\tjsr\tstaxysp");
if (CPU == CPU_65C02 && Offs == 0) {
AddCodeLine ("\tsta\t(sp)");
} else {
AddCodeLine ("\tjsr\tstax0sp");
ldyconst (Offs);
AddCodeLine ("\tsta\t(sp),y");
}
break;
case CF_INT:
if (Flags & CF_CONST) {
ldyconst (Offs+1);
AddCodeLine ("\tlda\t#$%02X", (unsigned char) (Val >> 8));
AddCodeLine ("\tsta\t(sp),y");
if ((Flags & CF_NOKEEP) == 0) {
/* Place high byte into X */
AddCodeLine ("\ttax");
}
if (CPU == CPU_65C02 && Offs == 0) {
AddCodeLine ("\tlda\t#$%02X", (unsigned char) Val);
AddCodeLine ("\tsta\t(sp)");
} else {
if ((Val & 0xFF) == Offs+1) {
/* The value we need is already in Y */
AddCodeLine ("\ttya");
AddCodeLine ("\tdey");
} else {
AddCodeLine ("\tdey");
AddCodeLine ("\tlda\t#$%02X", (unsigned char) Val);
}
AddCodeLine ("\tsta\t(sp),y");
}
} else {
if ((Flags & CF_NOKEEP) == 0 || FavourSize) {
if (Offs) {
ldyconst (Offs);
AddCodeLine ("\tjsr\tstaxysp");
} else {
AddCodeLine ("\tjsr\tstax0sp");
}
} else {
if (CPU == CPU_65C02 && Offs == 0) {
AddCodeLine ("\tsta\t(sp)");
ldyconst (1);
AddCodeLine ("\ttxa");
AddCodeLine ("\tsta\t(sp),y");
} else {
ldyconst (Offs);
AddCodeLine ("\tsta\t(sp),y");
AddCodeLine ("\tiny");
AddCodeLine ("\ttxa");
AddCodeLine ("\tsta\t(sp),y");
}
}
}
break;
case CF_LONG:
if (offs) {
ldyconst (offs);
if (Flags & CF_CONST) {
g_getimmed (Flags, Val, 0);
}
if (Offs) {
ldyconst (Offs);
AddCodeLine ("\tjsr\tsteaxysp");
} else {
AddCodeLine ("\tjsr\tsteax0sp");
@ -1119,7 +1164,7 @@ void g_putlocal (unsigned flags, int offs)
break;
default:
typeerror (flags);
typeerror (Flags);
}
}
@ -2461,44 +2506,44 @@ void g_swap (unsigned flags)
void g_call (unsigned flags, char* lbl, unsigned argsize)
void g_call (unsigned Flags, const char* Label, unsigned ArgSize)
/* Call the specified subroutine name */
{
if ((flags & CF_FIXARGC) == 0) {
/* Pass arg count */
ldyconst (argsize);
if ((Flags & CF_FIXARGC) == 0) {
/* Pass the argument count */
ldyconst (ArgSize);
}
AddCodeLine ("\tjsr\t_%s", lbl);
oursp += argsize; /* callee pops args */
AddCodeLine ("\tjsr\t_%s", Label);
oursp += ArgSize; /* callee pops args */
}
void g_callind (unsigned flags, unsigned argsize)
void g_callind (unsigned Flags, unsigned ArgSize)
/* Call subroutine with address in AX */
{
if ((flags & CF_FIXARGC) == 0) {
if ((Flags & CF_FIXARGC) == 0) {
/* Pass arg count */
ldyconst (argsize);
ldyconst (ArgSize);
}
AddCodeLine ("\tjsr\tcallax"); /* do the call */
oursp += argsize; /* callee pops args */
oursp += ArgSize; /* callee pops args */
}
void g_jump (unsigned label)
void g_jump (unsigned Label)
/* Jump to specified internal label number */
{
AddCodeLine ("\tjmp\tL%04X", label);
AddCodeLine ("\tjmp\tL%04X", Label);
}
void g_switch (unsigned flags)
/* Output switch statement preample */
void g_switch (unsigned Flags)
/* Output switch statement preamble */
{
switch (flags & CF_TYPE) {
switch (Flags & CF_TYPE) {
case CF_CHAR:
case CF_INT:
@ -2510,7 +2555,7 @@ void g_switch (unsigned flags)
break;
default:
typeerror (flags);
typeerror (Flags);
}
}

View File

@ -50,12 +50,14 @@
*/
#define CF_NONE 0x0000 /* No special flags */
#define CF_TYPE 0x000F /* Mask for operand type */
#define CF_TYPE 0x0007 /* Mask for operand type */
#define CF_CHAR 0x0003 /* Operation on characters */
#define CF_INT 0x0001 /* Operation on ints */
#define CF_PTR CF_INT /* Alias for readability */
#define CF_LONG 0x0000 /* Operation on longs */
#define CF_NOKEEP 0x0008 /* Value may get destroyed when storing */
#define CF_UNSIGNED 0x0010 /* Value is unsigned */
#define CF_CONST 0x0020 /* Constant value available */
#define CF_CONSTADDR 0x0040 /* Constant address value available */
@ -273,7 +275,7 @@ void g_leavariadic (int Offs);
void g_putstatic (unsigned flags, unsigned long label, unsigned offs);
/* Store the primary register into the specified static memory cell */
void g_putlocal (unsigned flags, int offs);
void g_putlocal (unsigned Flags, int Offs, long Val);
/* Put data into local object. */
void g_putind (unsigned flags, unsigned offs);
@ -370,10 +372,18 @@ void g_cmp (unsigned flags, unsigned long val);
void g_test (unsigned flags);
void g_push (unsigned flags, unsigned long val);
void g_swap (unsigned flags);
void g_call (unsigned flags, char *lbl, unsigned argsize);
void g_callind (unsigned flags, unsigned argsize);
void g_jump (unsigned label);
void g_switch (unsigned flags);
void g_call (unsigned Flags, const char* Label, unsigned ArgSize);
/* Call the specified subroutine name */
void g_callind (unsigned Flags, unsigned ArgSize);
/* Call subroutine with address in AX */
void g_jump (unsigned Label);
/* Jump to specified internal label number */
void g_switch (unsigned Flags);
/* Output switch statement preamble */
void g_case (unsigned flags, unsigned label, unsigned long val);
/* Create table code for one case selector */

View File

@ -173,7 +173,7 @@ type* GetImplicitFuncType (void)
type* T = TypeAlloc (1 + DECODE_SIZE + 2);
/* Prepare the function descriptor */
F->Flags = FD_IMPLICIT | FD_EMPTY | FD_ELLIPSIS;
F->Flags = FD_IMPLICIT | FD_EMPTY | FD_VARIADIC;
F->SymTab = &EmptySymTab;
F->TagTab = &EmptySymTab;
@ -476,7 +476,7 @@ unsigned TypeOf (const type* T)
case T_FUNC:
F = (FuncDesc*) DecodePtr (T+1);
return (F->Flags & FD_ELLIPSIS)? 0 : CF_FIXARGC;
return (F->Flags & FD_VARIADIC)? 0 : CF_FIXARGC;
case T_STRUCT:
case T_UNION:
@ -654,7 +654,7 @@ int IsVariadicFunc (const type* T)
FuncDesc* F;
CHECK (IsTypeFunc (T));
F = (FuncDesc*) DecodePtr (T+1);
return (F->Flags & FD_ELLIPSIS) != 0;
return (F->Flags & FD_VARIADIC) != 0;
}

View File

@ -626,7 +626,7 @@ static void ParseAnsiParamList (FuncDesc* F)
/* Allow an ellipsis as last parameter */
if (curtok == TOK_ELLIPSIS) {
NextToken ();
F->Flags |= FD_ELLIPSIS;
F->Flags |= FD_VARIADIC;
break;
}
@ -708,14 +708,14 @@ static FuncDesc* ParseFuncDecl (void)
/* Check for several special parameter lists */
if (curtok == TOK_RPAREN) {
/* Parameter list is empty */
F->Flags |= (FD_EMPTY | FD_ELLIPSIS);
F->Flags |= (FD_EMPTY | FD_VARIADIC);
} else if (curtok == TOK_VOID && nxttok == TOK_RPAREN) {
/* Parameter list declared as void */
NextToken ();
F->Flags |= FD_VOID_PARAM;
} else if (curtok == TOK_IDENT && (nxttok == TOK_COMMA || nxttok == TOK_RPAREN)) {
/* Old style (K&R) function. Assume variable param list. */
F->Flags |= (FD_OLDSTYLE | FD_ELLIPSIS);
F->Flags |= (FD_OLDSTYLE | FD_VARIADIC);
}
/* Parse params */
@ -730,7 +730,7 @@ static FuncDesc* ParseFuncDecl (void)
/* Assign offsets. If the function has a variable parameter list,
* there's one additional byte (the arg size).
*/
Offs = (F->Flags & FD_ELLIPSIS)? 1 : 0;
Offs = (F->Flags & FD_VARIADIC)? 1 : 0;
Sym = GetSymTab()->SymTail;
while (Sym) {
unsigned Size = SizeOf (Sym->Type);

View File

@ -510,54 +510,70 @@ void exprhs (unsigned flags, int k, struct expent *lval)
}
static void callfunction (struct expent* lval)
/* Perform a function call. Called from hie11, this routine will
* either call the named function, or if the supplied ptr is zero,
* will call the contents of P.
static unsigned FunctionParamList (FuncDesc* Func)
/* Parse a function parameter list and pass the parameters to the called
* function. Depending on several criteria this may be done by just pushing
* each parameter separately, or creating the parameter frame once and then
* storing into this frame.
* The function returns the size of the parameters pushed.
*/
{
struct expent lval2;
FuncDesc* Func; /* Function descriptor */
int Ellipsis; /* True if we have an open param list */
SymEntry* Param; /* Current formal parameter */
unsigned ParamCount; /* Actual parameter count */
unsigned ParamSize; /* Number of parameter bytes */
unsigned Flags;
unsigned CFlags;
CodeMark Mark;
struct expent lval;
/* Initialize variables */
SymEntry* Param = 0; /* Keep gcc silent */
unsigned ParamSize = 0; /* Size of parameters pushed */
unsigned ParamCount = 0; /* Number of parameters pushed */
unsigned FrameSize = 0; /* Size of parameter frame */
unsigned FrameParams = 0; /* Number of params in frame */
int FrameOffs = 0; /* Offset into parameter frame */
int Ellipsis = 0; /* Function is variadic */
/* Get a pointer to the function descriptor from the type string */
Func = GetFuncDesc (lval->e_tptr);
/* Initialize vars to keep gcc silent */
Param = 0;
Mark = 0;
/* Check if this is a function pointer. If so, save it. If not, check for
* special known library functions that may be inlined.
/* As an optimization, we may allocate the complete parameter frame at
* once instead of pushing each parameter as it comes. We may do that,
* if...
*
* - optimizations that increase code size are enabled (allocating the
* stack frame at once gives usually larger code).
* - we have more than one parameter to push (don't count the last param
* for __fastcall__ functions).
*/
if (lval->e_flags & E_MEXPR) {
/* Function pointer is in primary register, save it */
Mark = GetCodePos ();
g_save (CF_PTR);
} else if (InlineStdFuncs && IsStdFunc ((const char*) lval->e_name)) {
/* Inline this function */
HandleStdFunc (lval);
return;
if (Optimize && !FavourSize) {
/* Calculate the number and size of the parameters */
FrameParams = Func->ParamCount;
FrameSize = Func->ParamSize;
if (FrameParams > 0 && (Func->Flags & FD_FASTCALL) != 0) {
/* Last parameter is not pushed */
const SymEntry* LastParam = Func->SymTab->SymTail;
FrameSize -= SizeOf (LastParam->Type);
--FrameParams;
}
/* Do we have more than one parameter in the frame? */
if (FrameParams > 1) {
/* Okeydokey, setup the frame */
FrameOffs = oursp;
g_space (FrameSize);
oursp -= FrameSize;
} else {
/* Don't use a preallocated frame */
FrameSize = 0;
}
}
/* Parse the actual parameter list */
ParamSize = 0;
ParamCount = 0;
Ellipsis = 0;
while (curtok != TOK_RPAREN) {
unsigned CFlags;
unsigned Flags;
/* Add a hint for the optimizer */
AddCodeHint ("param:start");
/* Count arguments */
++ParamCount;
/* Count arguments */
++ParamCount;
/* Fetch the pointer to the next argument, check for too many args */
if (ParamCount <= Func->ParamCount) {
@ -579,7 +595,7 @@ static void callfunction (struct expent* lval)
}
} else if (!Ellipsis) {
/* Too many arguments. Do we have an open param list? */
if ((Func->Flags & FD_ELLIPSIS) == 0) {
if ((Func->Flags & FD_VARIADIC) == 0) {
/* End of param list reached, no ellipsis */
Error ("Too many arguments in function call");
}
@ -596,8 +612,8 @@ static void callfunction (struct expent* lval)
if (!Ellipsis && SizeOf (Param->Type) == 1) {
CFlags = CF_FORCECHAR;
}
Flags = 0;
if (evalexpr (CFlags, hie1, &lval2) == 0) {
Flags = CF_NONE;
if (evalexpr (CFlags, hie1, &lval) == 0) {
/* A constant value */
Flags |= CF_CONST;
}
@ -607,14 +623,14 @@ static void callfunction (struct expent* lval)
*/
if (!Ellipsis) {
/* Promote the argument if needed */
assignadjust (Param->Type, &lval2);
assignadjust (Param->Type, &lval);
/* If we have a prototype, chars may be pushed as chars */
Flags |= CF_FORCECHAR;
}
/* Use the type of the argument for the push */
Flags |= TypeOf (lval2.e_tptr);
Flags |= TypeOf (lval.e_tptr);
/* If this is a fastcall function, don't push the last argument */
if (ParamCount == Func->ParamCount && (Func->Flags & FD_FASTCALL) != 0) {
@ -623,12 +639,24 @@ static void callfunction (struct expent* lval)
* the primary.
*/
if (Flags & CF_CONST) {
exprhs (CF_FORCECHAR, 0, &lval2);
exprhs (CF_FORCECHAR, 0, &lval);
}
} else {
/* Push the argument, count the argument size */
g_push (Flags, lval2.e_const);
ParamSize += sizeofarg (Flags);
unsigned ArgSize = sizeofarg (Flags);
if (FrameSize > 0) {
/* We have the space already allocated, store in the frame */
CHECK (FrameSize >= ArgSize);
FrameSize -= ArgSize;
FrameOffs -= ArgSize;
/* Store */
g_putlocal (Flags | CF_NOKEEP, FrameOffs, lval.e_const);
} else {
/* Push the argument */
g_push (Flags, lval.e_const);
}
/* Calculate total parameter size */
ParamSize += ArgSize;
}
/* Add an optimizer hint */
@ -641,14 +669,52 @@ static void callfunction (struct expent* lval)
NextToken ();
}
/* We need the closing bracket here */
ConsumeRParen ();
/* Check if we had enough parameters */
if (ParamCount < Func->ParamCount) {
Error ("Too few arguments in function call");
}
/* Return the size of all parameters pushed onto the stack */
return ParamSize;
}
static void CallFunction (struct expent* lval)
/* Perform a function call. Called from hie11, this routine will
* either call the named function, or the function pointer in a/x.
*/
{
FuncDesc* Func; /* Function descriptor */
unsigned ParamSize; /* Number of parameter bytes */
CodeMark Mark;
/* Get a pointer to the function descriptor from the type string */
Func = GetFuncDesc (lval->e_tptr);
/* Initialize vars to keep gcc silent */
Mark = 0;
/* Check if this is a function pointer. If so, save it. If not, check for
* special known library functions that may be inlined.
*/
if (lval->e_flags & E_MEXPR) {
/* Function pointer is in primary register, save it */
Mark = GetCodePos ();
g_save (CF_PTR);
} else if (InlineStdFuncs && IsStdFunc ((const char*) lval->e_name)) {
/* Inline this function */
HandleStdFunc (lval);
return;
}
/* Parse the parameter list */
ParamSize = FunctionParamList (Func);
/* We need the closing bracket here */
ConsumeRParen ();
/* */
if (lval->e_flags & E_MEXPR) {
/* Function called via pointer: Restore it and call function */
@ -660,7 +726,7 @@ static void callfunction (struct expent* lval)
}
g_callind (TypeOf (lval->e_tptr), ParamSize);
} else {
g_call (TypeOf (lval->e_tptr), (char*) lval->e_name, ParamSize);
g_call (TypeOf (lval->e_tptr), (const char*) lval->e_name, ParamSize);
}
}
@ -1205,7 +1271,7 @@ static int hie11 (struct expent *lval)
++lval->e_tptr; /* Skip T_PTR */
lval->e_flags |= E_MEXPR;
}
callfunction (lval);
CallFunction (lval);
lval->e_flags = E_MEXPR;
lval->e_tptr += DECODE_SIZE + 1; /* Set to result */
} else {
@ -1255,7 +1321,7 @@ static void store (struct expent* lval)
g_putstatic (flags, lval->e_name, lval->e_const);
} else if (f & E_MLOCAL) {
g_putlocal (flags, lval->e_const);
g_putlocal (flags, lval->e_const, 0);
} else if (f == E_MEOFFS) {
g_putind (flags, lval->e_const);
} else if (f != E_MREG) {

View File

@ -48,7 +48,7 @@
#define FD_IMPLICIT 0x0001U /* Implicitly declared function */
#define FD_EMPTY 0x0002U /* Function with empty param list */
#define FD_VOID_PARAM 0x0004U /* Function with a void param list */
#define FD_ELLIPSIS 0x0008U /* Function with variable param list */
#define FD_VARIADIC 0x0008U /* Function with variable param list */
#define FD_FASTCALL 0x0010U /* __fastcall__ function */
#define FD_OLDSTYLE 0x0020U /* Old style (K&R) function */
#define FD_UNNAMED_PARAMS 0x0040U /* Function has unnamed params */

View File

@ -151,7 +151,7 @@ int HasVoidReturn (const Function* F)
int IsVariadic (const Function* F)
/* Return true if this is a variadic function */
{
return (F->Desc->Flags & FD_ELLIPSIS) != 0;
return (F->Desc->Flags & FD_VARIADIC) != 0;
}
@ -232,7 +232,7 @@ void NewFunc (SymEntry* Func)
* or not).
*/
AddConstSym ("__fixargs__", type_uint, SC_DEF | SC_CONST, D->ParamSize);
if (D->Flags & FD_ELLIPSIS) {
if (D->Flags & FD_VARIADIC) {
/* Variadic function. The variable must be const. */
static const type T [] = { T_UCHAR | T_QUAL_CONST, T_END };
AddLocalSym ("__argsize__", T, SC_DEF | SC_REF | SC_AUTO, 0);
@ -263,7 +263,7 @@ void NewFunc (SymEntry* Func)
unsigned Flags;
/* Fastcall functions may never have an ellipsis or the compiler is buggy */
CHECK ((D->Flags & FD_ELLIPSIS) == 0);
CHECK ((D->Flags & FD_VARIADIC) == 0);
/* Get a pointer to the last parameter entry */
LastParam = D->SymTab->SymTail;

View File

@ -589,7 +589,7 @@ static ExprNode* DoFunctionCall (ExprNode* Left)
}
} else if (!Ellipsis) {
/* Too many arguments. Do we have an open param list? */
if ((Func->Flags & FD_ELLIPSIS) == 0) {
if ((Func->Flags & FD_VARIADIC) == 0) {
/* End of param list reached, no ellipsis */
Error ("Too many function arguments");
}