mirror of
https://github.com/cc65/cc65.git
synced 2025-01-10 03:30:05 +00:00
Renamed the functions working with "struct Function".
Fixed a problem with K&R functions: In a function with no return type specified, the compiler did not allow a simple "return" statement. However, there was no "void" type at that time, so it was not possible to specify something else. The solution is to allow omission of a return value in a K&R function with an implicit int type. Other types or an explicit int is still checked. git-svn-id: svn://svn.cc65.org/cc65/trunk@1302 b7a2c559-68d2-44c3-8de9-860c34a00d81
This commit is contained in:
parent
fc3d55d196
commit
a96da498f5
@ -254,7 +254,7 @@ static void ParseLVarArg (StrBuf* T, unsigned Arg)
|
|||||||
* don't have a fixed stack offset, so check it and bail out with an error
|
* don't have a fixed stack offset, so check it and bail out with an error
|
||||||
* if this is the case.
|
* if this is the case.
|
||||||
*/
|
*/
|
||||||
if ((Sym->Flags & SC_PARAM) == SC_PARAM && IsVariadic (CurrentFunc)) {
|
if ((Sym->Flags & SC_PARAM) == SC_PARAM && F_IsVariadic (CurrentFunc)) {
|
||||||
Error ("Argument %u has no fixed stack offset", Arg);
|
Error ("Argument %u has no fixed stack offset", Arg);
|
||||||
AsmErrorSkip ();
|
AsmErrorSkip ();
|
||||||
return;
|
return;
|
||||||
|
@ -417,7 +417,7 @@ static void ParseTypeSpec (DeclSpec* D, int Default)
|
|||||||
optionalint ();
|
optionalint ();
|
||||||
D->Type[0] = T_LONG;
|
D->Type[0] = T_LONG;
|
||||||
D->Type[1] = T_END;
|
D->Type[1] = T_END;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case TOK_INT:
|
case TOK_INT:
|
||||||
NextToken ();
|
NextToken ();
|
||||||
@ -454,13 +454,13 @@ static void ParseTypeSpec (DeclSpec* D, int Default)
|
|||||||
D->Type[1] = T_END;
|
D->Type[1] = T_END;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case TOK_INT:
|
case TOK_INT:
|
||||||
NextToken ();
|
NextToken ();
|
||||||
/* FALL THROUGH */
|
/* FALL THROUGH */
|
||||||
|
|
||||||
default:
|
default:
|
||||||
D->Type[0] = T_UINT;
|
D->Type[0] = T_UINT;
|
||||||
D->Type[1] = T_END;
|
D->Type[1] = T_END;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -497,7 +497,7 @@ static void ParseTypeSpec (DeclSpec* D, int Default)
|
|||||||
if (SymIsLocal (Entry) && (Entry->Flags & SC_ENUM) == 0) {
|
if (SymIsLocal (Entry) && (Entry->Flags & SC_ENUM) == 0) {
|
||||||
Error ("Symbol `%s' is already different kind", Entry->Name);
|
Error ("Symbol `%s' is already different kind", Entry->Name);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
/* Insert entry into table ### */
|
/* Insert entry into table ### */
|
||||||
}
|
}
|
||||||
/* Skip the identifier */
|
/* Skip the identifier */
|
||||||
@ -626,7 +626,7 @@ static void ParseOldStyleParamList (FuncDesc* F)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (CurTok.Tok == TOK_COMMA) {
|
if (CurTok.Tok == TOK_COMMA) {
|
||||||
NextToken ();
|
NextToken ();
|
||||||
} else {
|
} else {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -720,7 +720,7 @@ static void ParseAnsiParamList (FuncDesc* F)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
static FuncDesc* ParseFuncDecl (void)
|
static FuncDesc* ParseFuncDecl (const DeclSpec* Spec)
|
||||||
/* Parse the argument list of a function. */
|
/* Parse the argument list of a function. */
|
||||||
{
|
{
|
||||||
unsigned Offs;
|
unsigned Offs;
|
||||||
@ -749,6 +749,14 @@ static FuncDesc* ParseFuncDecl (void)
|
|||||||
if (Sym == 0 || !IsTypeDef (Sym)) {
|
if (Sym == 0 || !IsTypeDef (Sym)) {
|
||||||
/* Old style (K&R) function. Assume variable param list. */
|
/* Old style (K&R) function. Assume variable param list. */
|
||||||
F->Flags |= (FD_OLDSTYLE | FD_VARIADIC);
|
F->Flags |= (FD_OLDSTYLE | FD_VARIADIC);
|
||||||
|
|
||||||
|
/* Check for an implicit int return in the K&R function */
|
||||||
|
if ((Spec->Flags & DS_DEF_TYPE) != 0 &&
|
||||||
|
Spec->Type[0] == T_INT &&
|
||||||
|
Spec->Type[1] == T_END) {
|
||||||
|
/* Function has an implicit int return */
|
||||||
|
F->Flags |= FD_OLDSTYLE_INTRET;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -783,21 +791,21 @@ static FuncDesc* ParseFuncDecl (void)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
static void Decl (Declaration* D, unsigned Mode)
|
static void Decl (const DeclSpec* Spec, Declaration* D, unsigned Mode)
|
||||||
/* Recursively process declarators. Build a type array in reverse order. */
|
/* Recursively process declarators. Build a type array in reverse order. */
|
||||||
{
|
{
|
||||||
|
|
||||||
if (CurTok.Tok == TOK_STAR) {
|
if (CurTok.Tok == TOK_STAR) {
|
||||||
type T = T_PTR;
|
type T = T_PTR;
|
||||||
NextToken ();
|
NextToken ();
|
||||||
/* Allow optional const or volatile qualifiers */
|
/* Allow optional const or volatile qualifiers */
|
||||||
T |= OptionalQualifiers (T_QUAL_NONE);
|
T |= OptionalQualifiers (T_QUAL_NONE);
|
||||||
Decl (D, Mode);
|
Decl (Spec, D, Mode);
|
||||||
*D->T++ = T;
|
*D->T++ = T;
|
||||||
return;
|
return;
|
||||||
} else if (CurTok.Tok == TOK_LPAREN) {
|
} else if (CurTok.Tok == TOK_LPAREN) {
|
||||||
NextToken ();
|
NextToken ();
|
||||||
Decl (D, Mode);
|
Decl (Spec, D, Mode);
|
||||||
ConsumeRParen ();
|
ConsumeRParen ();
|
||||||
} else if (CurTok.Tok == TOK_FASTCALL) {
|
} else if (CurTok.Tok == TOK_FASTCALL) {
|
||||||
/* Remember the current type pointer */
|
/* Remember the current type pointer */
|
||||||
@ -805,7 +813,7 @@ static void Decl (Declaration* D, unsigned Mode)
|
|||||||
/* Skip the fastcall token */
|
/* Skip the fastcall token */
|
||||||
NextToken ();
|
NextToken ();
|
||||||
/* Parse the function */
|
/* Parse the function */
|
||||||
Decl (D, Mode);
|
Decl (Spec, D, Mode);
|
||||||
/* Set the fastcall flag */
|
/* Set the fastcall flag */
|
||||||
if (!IsTypeFunc (T) && !IsTypeFuncPtr (T)) {
|
if (!IsTypeFunc (T) && !IsTypeFuncPtr (T)) {
|
||||||
Error ("__fastcall__ modifier applied to non function");
|
Error ("__fastcall__ modifier applied to non function");
|
||||||
@ -821,11 +829,11 @@ static void Decl (Declaration* D, unsigned Mode)
|
|||||||
* - Mode == DM_NEED_IDENT means:
|
* - Mode == DM_NEED_IDENT means:
|
||||||
* we *must* have a type and a variable identifer.
|
* we *must* have a type and a variable identifer.
|
||||||
* - Mode == DM_NO_IDENT means:
|
* - Mode == DM_NO_IDENT means:
|
||||||
* we must have a type but no variable identifer
|
* we must have a type but no variable identifer
|
||||||
* (if there is one, it's not read).
|
* (if there is one, it's not read).
|
||||||
* - Mode == DM_ACCEPT_IDENT means:
|
* - Mode == DM_ACCEPT_IDENT means:
|
||||||
* we *may* have an identifier. If there is an identifier,
|
* we *may* have an identifier. If there is an identifier,
|
||||||
* it is read, but it is no error, if there is none.
|
* it is read, but it is no error, if there is none.
|
||||||
*/
|
*/
|
||||||
if (Mode == DM_NO_IDENT) {
|
if (Mode == DM_NO_IDENT) {
|
||||||
D->Ident[0] = '\0';
|
D->Ident[0] = '\0';
|
||||||
@ -847,7 +855,7 @@ static void Decl (Declaration* D, unsigned Mode)
|
|||||||
FuncDesc* F;
|
FuncDesc* F;
|
||||||
NextToken ();
|
NextToken ();
|
||||||
/* Parse the function declaration */
|
/* Parse the function declaration */
|
||||||
F = ParseFuncDecl ();
|
F = ParseFuncDecl (Spec);
|
||||||
*D->T++ = T_FUNC;
|
*D->T++ = T_FUNC;
|
||||||
EncodePtr (D->T, F);
|
EncodePtr (D->T, F);
|
||||||
D->T += DECODE_SIZE;
|
D->T += DECODE_SIZE;
|
||||||
@ -907,18 +915,18 @@ void ParseDecl (const DeclSpec* Spec, Declaration* D, unsigned Mode)
|
|||||||
InitDeclaration (D);
|
InitDeclaration (D);
|
||||||
|
|
||||||
/* Get additional declarators and the identifier */
|
/* Get additional declarators and the identifier */
|
||||||
Decl (D, Mode);
|
Decl (Spec, D, Mode);
|
||||||
|
|
||||||
/* Add the base type. */
|
/* Add the base type. */
|
||||||
TypeCpy (D->T, Spec->Type);
|
TypeCpy (D->T, Spec->Type);
|
||||||
|
|
||||||
/* Check the size of the generated type */
|
/* Check the size of the generated type */
|
||||||
if (!IsTypeFunc (D->Type) && !IsTypeVoid (D->Type) && SizeOf (D->Type) >= 0x10000) {
|
if (!IsTypeFunc (D->Type) && !IsTypeVoid (D->Type) && SizeOf (D->Type) >= 0x10000) {
|
||||||
if (D->Ident[0] != '\0') {
|
if (D->Ident[0] != '\0') {
|
||||||
Error ("Size of `%s' is invalid", D->Ident);
|
Error ("Size of `%s' is invalid", D->Ident);
|
||||||
} else {
|
} else {
|
||||||
Error ("Invalid size");
|
Error ("Invalid size");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -913,9 +913,9 @@ static int primary (ExprDesc* lval)
|
|||||||
* function, we have to add some address calculations, and the
|
* function, we have to add some address calculations, and the
|
||||||
* address is not const.
|
* address is not const.
|
||||||
*/
|
*/
|
||||||
if ((Sym->Flags & SC_PARAM) == SC_PARAM && IsVariadic (CurrentFunc)) {
|
if ((Sym->Flags & SC_PARAM) == SC_PARAM && F_IsVariadic (CurrentFunc)) {
|
||||||
/* Variadic parameter */
|
/* Variadic parameter */
|
||||||
g_leavariadic (Sym->V.Offs - GetParamSize (CurrentFunc));
|
g_leavariadic (Sym->V.Offs - F_GetParamSize (CurrentFunc));
|
||||||
lval->Flags = E_MEXPR;
|
lval->Flags = E_MEXPR;
|
||||||
lval->ConstVal = 0;
|
lval->ConstVal = 0;
|
||||||
} else {
|
} else {
|
||||||
|
@ -51,7 +51,8 @@
|
|||||||
#define FD_VARIADIC 0x0008U /* Function with variable param list */
|
#define FD_VARIADIC 0x0008U /* Function with variable param list */
|
||||||
#define FD_FASTCALL 0x0010U /* __fastcall__ function */
|
#define FD_FASTCALL 0x0010U /* __fastcall__ function */
|
||||||
#define FD_OLDSTYLE 0x0020U /* Old style (K&R) function */
|
#define FD_OLDSTYLE 0x0020U /* Old style (K&R) function */
|
||||||
#define FD_UNNAMED_PARAMS 0x0040U /* Function has unnamed params */
|
#define FD_OLDSTYLE_INTRET 0x0040U /* K&R func has implicit int return */
|
||||||
|
#define FD_UNNAMED_PARAMS 0x0080U /* Function has unnamed params */
|
||||||
|
|
||||||
/* Bits that must be ignored when comparing funcs */
|
/* Bits that must be ignored when comparing funcs */
|
||||||
#define FD_IGNORE (FD_IMPLICIT | FD_UNNAMED_PARAMS)
|
#define FD_IGNORE (FD_IMPLICIT | FD_UNNAMED_PARAMS)
|
||||||
|
@ -109,7 +109,7 @@ static void FreeFunction (Function* F)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
const char* GetFuncName (const Function* F)
|
const char* F_GetFuncName (const Function* F)
|
||||||
/* Return the name of the current function */
|
/* Return the name of the current function */
|
||||||
{
|
{
|
||||||
return F->FuncEntry->Name;
|
return F->FuncEntry->Name;
|
||||||
@ -117,7 +117,7 @@ const char* GetFuncName (const Function* F)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
unsigned GetParamCount (const Function* F)
|
unsigned F_GetParamCount (const Function* F)
|
||||||
/* Return the parameter count for the current function */
|
/* Return the parameter count for the current function */
|
||||||
{
|
{
|
||||||
return F->Desc->ParamCount;
|
return F->Desc->ParamCount;
|
||||||
@ -125,7 +125,7 @@ unsigned GetParamCount (const Function* F)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
unsigned 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 */
|
||||||
{
|
{
|
||||||
return F->Desc->ParamSize;
|
return F->Desc->ParamSize;
|
||||||
@ -133,7 +133,7 @@ unsigned GetParamSize (const Function* F)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
type* 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;
|
||||||
@ -141,7 +141,7 @@ type* GetReturnType (Function* F)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
int HasVoidReturn (const Function* F)
|
int F_HasVoidReturn (const Function* F)
|
||||||
/* Return true if the function does not have a return value */
|
/* Return true if the function does not have a return value */
|
||||||
{
|
{
|
||||||
return IsTypeVoid (F->ReturnType);
|
return IsTypeVoid (F->ReturnType);
|
||||||
@ -149,15 +149,31 @@ int HasVoidReturn (const Function* F)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
int IsVariadic (const Function* F)
|
int F_IsVariadic (const Function* F)
|
||||||
/* Return true if this is a variadic function */
|
/* Return true if this is a variadic function */
|
||||||
{
|
{
|
||||||
return (F->Desc->Flags & FD_VARIADIC) != 0;
|
return (F->Desc->Flags & FD_OLDSTYLE) != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
unsigned GetRetLab (const Function* F)
|
int F_IsOldStyle (const Function* F)
|
||||||
|
/* Return true if this is an old style (K&R) function */
|
||||||
|
{
|
||||||
|
return (F->Desc->Flags & FD_OLDSTYLE) != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
int F_HasOldStyleIntRet (const Function* F)
|
||||||
|
/* Return true if this is an old style (K&R) function with an implicit int return */
|
||||||
|
{
|
||||||
|
return (F->Desc->Flags & FD_OLDSTYLE_INTRET) != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
unsigned F_GetRetLab (const Function* F)
|
||||||
/* Return the return jump label */
|
/* Return the return jump label */
|
||||||
{
|
{
|
||||||
return F->RetLab;
|
return F->RetLab;
|
||||||
@ -165,7 +181,7 @@ unsigned GetRetLab (const Function* F)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
int GetTopLevelSP (const Function* F)
|
int F_GetTopLevelSP (const Function* F)
|
||||||
/* Get the value of the stack pointer on function top level */
|
/* Get the value of the stack pointer on function top level */
|
||||||
{
|
{
|
||||||
return F->TopLevelSP;
|
return F->TopLevelSP;
|
||||||
@ -173,7 +189,7 @@ int GetTopLevelSP (const Function* F)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
int ReserveLocalSpace (Function* F, unsigned Size)
|
int F_ReserveLocalSpace (Function* F, unsigned Size)
|
||||||
/* Reserve (but don't allocate) the given local space and return the stack
|
/* Reserve (but don't allocate) the given local space and return the stack
|
||||||
* offset.
|
* offset.
|
||||||
*/
|
*/
|
||||||
@ -184,21 +200,21 @@ int ReserveLocalSpace (Function* F, unsigned Size)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
void AllocLocalSpace (Function* F)
|
void F_AllocLocalSpace (Function* F)
|
||||||
/* Allocate any local space previously reserved. The function will do
|
/* Allocate any local space previously reserved. The function will do
|
||||||
* nothing if there is no reserved local space.
|
* nothing if there is no reserved local space.
|
||||||
*/
|
*/
|
||||||
{
|
{
|
||||||
if (F->Reserved > 0) {
|
if (F->Reserved > 0) {
|
||||||
|
|
||||||
/* Create space on the stack */
|
/* Create space on the stack */
|
||||||
g_space (F->Reserved);
|
g_space (F->Reserved);
|
||||||
|
|
||||||
/* Correct the stack pointer */
|
/* Correct the stack pointer */
|
||||||
oursp -= F->Reserved;
|
oursp -= F->Reserved;
|
||||||
|
|
||||||
/* Nothing more reserved */
|
/* Nothing more reserved */
|
||||||
F->Reserved = 0;
|
F->Reserved = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -276,7 +292,7 @@ void NewFunc (SymEntry* Func)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Generate function entry code if needed */
|
/* Generate function entry code if needed */
|
||||||
g_enter (TypeOf (Func->Type), GetParamSize (CurrentFunc));
|
g_enter (TypeOf (Func->Type), F_GetParamSize (CurrentFunc));
|
||||||
|
|
||||||
/* Setup the stack */
|
/* Setup the stack */
|
||||||
oursp = 0;
|
oursp = 0;
|
||||||
@ -305,16 +321,16 @@ void NewFunc (SymEntry* Func)
|
|||||||
/* If the function has a return type but no return statement, flag
|
/* If the function has a return type but no return statement, flag
|
||||||
* a warning
|
* a warning
|
||||||
*/
|
*/
|
||||||
IsVoidFunc = HasVoidReturn (CurrentFunc);
|
IsVoidFunc = F_HasVoidReturn (CurrentFunc);
|
||||||
#if 0
|
#if 0
|
||||||
/* Does not work reliably */
|
/* Does not work reliably */
|
||||||
if (!IsVoidFunc && !HadReturn) {
|
if (!F_IsVoidFunc && !HadReturn) {
|
||||||
Warning ("Function `%s' should return a value", Func->Name);
|
Warning ("Function `%s' should return a value", Func->Name);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Output the function exit code label */
|
/* Output the function exit code label */
|
||||||
g_defcodelabel (GetRetLab (CurrentFunc));
|
g_defcodelabel (F_GetRetLab (CurrentFunc));
|
||||||
|
|
||||||
/* Restore the register variables */
|
/* Restore the register variables */
|
||||||
RestoreRegVars (!IsVoidFunc);
|
RestoreRegVars (!IsVoidFunc);
|
||||||
|
@ -58,36 +58,42 @@ extern Function* CurrentFunc;
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
const char* GetFuncName (const Function* F);
|
const char* F_GetFuncName (const Function* F);
|
||||||
/* Return the name of the current function */
|
/* Return the name of the current function */
|
||||||
|
|
||||||
unsigned GetParamCount (const Function* F);
|
unsigned F_GetParamCount (const Function* F);
|
||||||
/* Return the parameter count for the current function */
|
/* Return the parameter count for the current function */
|
||||||
|
|
||||||
unsigned 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* GetReturnType (Function* F);
|
type* F_GetReturnType (Function* F);
|
||||||
/* Get the return type for the function */
|
/* Get the return type for the function */
|
||||||
|
|
||||||
int HasVoidReturn (const Function* F);
|
int F_HasVoidReturn (const Function* F);
|
||||||
/* Return true if the function does not have a return value */
|
/* Return true if the function does not have a return value */
|
||||||
|
|
||||||
int IsVariadic (const Function* F);
|
int F_IsVariadic (const Function* F);
|
||||||
/* Return true if this is a variadic function */
|
/* Return true if this is a variadic function */
|
||||||
|
|
||||||
unsigned GetRetLab (const Function* F);
|
int F_IsOldStyle (const Function* F);
|
||||||
|
/* Return true if this is an old style (K&R) function */
|
||||||
|
|
||||||
|
int F_HasOldStyleIntRet (const Function* F);
|
||||||
|
/* Return true if this is an old style (K&R) function with an implicit int return */
|
||||||
|
|
||||||
|
unsigned F_GetRetLab (const Function* F);
|
||||||
/* Return the return jump label */
|
/* Return the return jump label */
|
||||||
|
|
||||||
int GetTopLevelSP (const Function* F);
|
int F_GetTopLevelSP (const Function* F);
|
||||||
/* Get the value of the stack pointer on function top level */
|
/* Get the value of the stack pointer on function top level */
|
||||||
|
|
||||||
int ReserveLocalSpace (Function* F, unsigned Size);
|
int F_ReserveLocalSpace (Function* F, unsigned Size);
|
||||||
/* Reserve (but don't allocate) the given local space and return the stack
|
/* Reserve (but don't allocate) the given local space and return the stack
|
||||||
* offset.
|
* offset.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void AllocLocalSpace (Function* F);
|
void F_AllocLocalSpace (Function* F);
|
||||||
/* Allocate any local space previously reserved. The function will do
|
/* Allocate any local space previously reserved. The function will do
|
||||||
* nothing if there is no reserved local space.
|
* nothing if there is no reserved local space.
|
||||||
*/
|
*/
|
||||||
|
@ -184,7 +184,7 @@ static void ParseOneDecl (const DeclSpec* Spec)
|
|||||||
ExprDesc lval;
|
ExprDesc lval;
|
||||||
|
|
||||||
/* Allocate previously reserved local space */
|
/* Allocate previously reserved local space */
|
||||||
AllocLocalSpace (CurrentFunc);
|
F_AllocLocalSpace (CurrentFunc);
|
||||||
|
|
||||||
/* Skip the '=' */
|
/* Skip the '=' */
|
||||||
NextToken ();
|
NextToken ();
|
||||||
@ -215,7 +215,7 @@ static void ParseOneDecl (const DeclSpec* Spec)
|
|||||||
/* Non-initialized local variable. Just keep track of
|
/* Non-initialized local variable. Just keep track of
|
||||||
* the space needed.
|
* the space needed.
|
||||||
*/
|
*/
|
||||||
SymData = ReserveLocalSpace (CurrentFunc, Size);
|
SymData = F_ReserveLocalSpace (CurrentFunc, Size);
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
@ -377,7 +377,7 @@ void DeclareLocals (void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Be sure to allocate any reserved space for locals */
|
/* Be sure to allocate any reserved space for locals */
|
||||||
AllocLocalSpace (CurrentFunc);
|
F_AllocLocalSpace (CurrentFunc);
|
||||||
|
|
||||||
/* In case we've allocated local variables in this block, emit a call to
|
/* In case we've allocated local variables in this block, emit a call to
|
||||||
* the stack checking routine if stack checks are enabled.
|
* the stack checking routine if stack checks are enabled.
|
||||||
@ -404,7 +404,7 @@ void RestoreRegVars (int HaveResult)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Save the accumulator if needed */
|
/* Save the accumulator if needed */
|
||||||
if (!HasVoidReturn (CurrentFunc) && HaveResult) {
|
if (!F_HasVoidReturn (CurrentFunc) && HaveResult) {
|
||||||
g_save (CF_CHAR | CF_FORCECHAR);
|
g_save (CF_CHAR | CF_FORCECHAR);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -449,7 +449,7 @@ void RestoreRegVars (int HaveResult)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Restore the accumulator if needed */
|
/* Restore the accumulator if needed */
|
||||||
if (!HasVoidReturn (CurrentFunc) && HaveResult) {
|
if (!F_HasVoidReturn (CurrentFunc) && HaveResult) {
|
||||||
g_restore (CF_CHAR | CF_FORCECHAR);
|
g_restore (CF_CHAR | CF_FORCECHAR);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -547,7 +547,7 @@ void NextToken (void)
|
|||||||
} else if (strcmp (token, "__func__") == 0) {
|
} else if (strcmp (token, "__func__") == 0) {
|
||||||
/* __func__ is only defined in functions */
|
/* __func__ is only defined in functions */
|
||||||
if (CurrentFunc) {
|
if (CurrentFunc) {
|
||||||
NextTok.IVal = AddLiteral (GetFuncName (CurrentFunc));
|
NextTok.IVal = AddLiteral (F_GetFuncName (CurrentFunc));
|
||||||
NextTok.Tok = TOK_SCONST;
|
NextTok.Tok = TOK_SCONST;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -805,7 +805,7 @@ void SkipTokens (const token_t* TokenList, unsigned TokenCount)
|
|||||||
/* Skip tokens until we reach TOK_CEOF or a token in the given token list.
|
/* Skip tokens until we reach TOK_CEOF or a token in the given token list.
|
||||||
* This routine is used for error recovery.
|
* This routine is used for error recovery.
|
||||||
*/
|
*/
|
||||||
{
|
{
|
||||||
while (CurTok.Tok != TOK_CEOF) {
|
while (CurTok.Tok != TOK_CEOF) {
|
||||||
|
|
||||||
/* Check if the current token is in the token list */
|
/* Check if the current token is in the token list */
|
||||||
|
@ -242,7 +242,7 @@ static void ReturnStatement (void)
|
|||||||
|
|
||||||
NextToken ();
|
NextToken ();
|
||||||
if (CurTok.Tok != TOK_SEMI) {
|
if (CurTok.Tok != TOK_SEMI) {
|
||||||
if (HasVoidReturn (CurrentFunc)) {
|
if (F_HasVoidReturn (CurrentFunc)) {
|
||||||
Error ("Returning a value in function with return type void");
|
Error ("Returning a value in function with return type void");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -250,18 +250,18 @@ static void ReturnStatement (void)
|
|||||||
expression (&lval);
|
expression (&lval);
|
||||||
|
|
||||||
/* Convert the return value to the type of the function result */
|
/* Convert the return value to the type of the function result */
|
||||||
if (!HasVoidReturn (CurrentFunc)) {
|
if (!F_HasVoidReturn (CurrentFunc)) {
|
||||||
assignadjust (GetReturnType (CurrentFunc), &lval);
|
assignadjust (F_GetReturnType (CurrentFunc), &lval);
|
||||||
}
|
}
|
||||||
} else if (!HasVoidReturn (CurrentFunc)) {
|
} else if (!F_HasVoidReturn (CurrentFunc) && !F_HasOldStyleIntRet (CurrentFunc)) {
|
||||||
Error ("Function `%s' must return a value", GetFuncName (CurrentFunc));
|
Error ("Function `%s' must return a value", F_GetFuncName (CurrentFunc));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Cleanup the stack in case we're inside a block with locals */
|
/* Cleanup the stack in case we're inside a block with locals */
|
||||||
g_space (oursp - GetTopLevelSP (CurrentFunc));
|
g_space (oursp - F_GetTopLevelSP (CurrentFunc));
|
||||||
|
|
||||||
/* Output a jump to the function exit code */
|
/* Output a jump to the function exit code */
|
||||||
g_jump (GetRetLab (CurrentFunc));
|
g_jump (F_GetRetLab (CurrentFunc));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user