1
0
mirror of https://github.com/cc65/cc65.git synced 2024-06-17 16:29:32 +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:
cuz 2002-06-12 12:12:04 +00:00
parent fc3d55d196
commit a96da498f5
9 changed files with 103 additions and 72 deletions

View File

@ -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
* 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);
AsmErrorSkip ();
return;

View File

@ -417,7 +417,7 @@ static void ParseTypeSpec (DeclSpec* D, int Default)
optionalint ();
D->Type[0] = T_LONG;
D->Type[1] = T_END;
break;
break;
case TOK_INT:
NextToken ();
@ -454,13 +454,13 @@ static void ParseTypeSpec (DeclSpec* D, int Default)
D->Type[1] = T_END;
break;
case TOK_INT:
case TOK_INT:
NextToken ();
/* FALL THROUGH */
default:
D->Type[0] = T_UINT;
D->Type[1] = T_END;
D->Type[1] = T_END;
break;
}
break;
@ -497,7 +497,7 @@ static void ParseTypeSpec (DeclSpec* D, int Default)
if (SymIsLocal (Entry) && (Entry->Flags & SC_ENUM) == 0) {
Error ("Symbol `%s' is already different kind", Entry->Name);
}
} else {
} else {
/* Insert entry into table ### */
}
/* Skip the identifier */
@ -626,7 +626,7 @@ static void ParseOldStyleParamList (FuncDesc* F)
}
if (CurTok.Tok == TOK_COMMA) {
NextToken ();
NextToken ();
} else {
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. */
{
unsigned Offs;
@ -749,6 +749,14 @@ static FuncDesc* ParseFuncDecl (void)
if (Sym == 0 || !IsTypeDef (Sym)) {
/* Old style (K&R) function. Assume variable param list. */
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. */
{
if (CurTok.Tok == TOK_STAR) {
type T = T_PTR;
type T = T_PTR;
NextToken ();
/* Allow optional const or volatile qualifiers */
T |= OptionalQualifiers (T_QUAL_NONE);
Decl (D, Mode);
/* Allow optional const or volatile qualifiers */
T |= OptionalQualifiers (T_QUAL_NONE);
Decl (Spec, D, Mode);
*D->T++ = T;
return;
} else if (CurTok.Tok == TOK_LPAREN) {
NextToken ();
Decl (D, Mode);
Decl (Spec, D, Mode);
ConsumeRParen ();
} else if (CurTok.Tok == TOK_FASTCALL) {
/* Remember the current type pointer */
@ -805,7 +813,7 @@ static void Decl (Declaration* D, unsigned Mode)
/* Skip the fastcall token */
NextToken ();
/* Parse the function */
Decl (D, Mode);
Decl (Spec, D, Mode);
/* Set the fastcall flag */
if (!IsTypeFunc (T) && !IsTypeFuncPtr (T)) {
Error ("__fastcall__ modifier applied to non function");
@ -821,11 +829,11 @@ static void Decl (Declaration* D, unsigned Mode)
* - Mode == DM_NEED_IDENT means:
* we *must* have a type and a variable identifer.
* - 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).
* - Mode == DM_ACCEPT_IDENT means:
* we *may* have an identifier. If there is an identifier,
* it is read, but it is no error, if there is none.
* we *may* have an identifier. If there is an identifier,
* it is read, but it is no error, if there is none.
*/
if (Mode == DM_NO_IDENT) {
D->Ident[0] = '\0';
@ -847,7 +855,7 @@ static void Decl (Declaration* D, unsigned Mode)
FuncDesc* F;
NextToken ();
/* Parse the function declaration */
F = ParseFuncDecl ();
F = ParseFuncDecl (Spec);
*D->T++ = T_FUNC;
EncodePtr (D->T, F);
D->T += DECODE_SIZE;
@ -907,18 +915,18 @@ void ParseDecl (const DeclSpec* Spec, Declaration* D, unsigned Mode)
InitDeclaration (D);
/* Get additional declarators and the identifier */
Decl (D, Mode);
Decl (Spec, D, Mode);
/* Add the base type. */
TypeCpy (D->T, Spec->Type);
/* Check the size of the generated type */
if (!IsTypeFunc (D->Type) && !IsTypeVoid (D->Type) && SizeOf (D->Type) >= 0x10000) {
if (D->Ident[0] != '\0') {
Error ("Size of `%s' is invalid", D->Ident);
} else {
Error ("Invalid size");
}
if (D->Ident[0] != '\0') {
Error ("Size of `%s' is invalid", D->Ident);
} else {
Error ("Invalid size");
}
}
}

View File

@ -913,9 +913,9 @@ static int primary (ExprDesc* lval)
* function, we have to add some address calculations, and the
* 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 */
g_leavariadic (Sym->V.Offs - GetParamSize (CurrentFunc));
g_leavariadic (Sym->V.Offs - F_GetParamSize (CurrentFunc));
lval->Flags = E_MEXPR;
lval->ConstVal = 0;
} else {

View File

@ -51,7 +51,8 @@
#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 */
#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 */
#define FD_IGNORE (FD_IMPLICIT | FD_UNNAMED_PARAMS)

View File

@ -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 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 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 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 */
{
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 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 (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 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 */
{
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
* 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
* nothing if there is no reserved local space.
*/
{
if (F->Reserved > 0) {
/* Create space on the stack */
g_space (F->Reserved);
/* Create space on the stack */
g_space (F->Reserved);
/* Correct the stack pointer */
oursp -= F->Reserved;
/* Correct the stack pointer */
oursp -= F->Reserved;
/* Nothing more reserved */
F->Reserved = 0;
/* Nothing more reserved */
F->Reserved = 0;
}
}
@ -276,7 +292,7 @@ void NewFunc (SymEntry* Func)
}
/* Generate function entry code if needed */
g_enter (TypeOf (Func->Type), GetParamSize (CurrentFunc));
g_enter (TypeOf (Func->Type), F_GetParamSize (CurrentFunc));
/* Setup the stack */
oursp = 0;
@ -305,16 +321,16 @@ void NewFunc (SymEntry* Func)
/* If the function has a return type but no return statement, flag
* a warning
*/
IsVoidFunc = HasVoidReturn (CurrentFunc);
IsVoidFunc = F_HasVoidReturn (CurrentFunc);
#if 0
/* Does not work reliably */
if (!IsVoidFunc && !HadReturn) {
if (!F_IsVoidFunc && !HadReturn) {
Warning ("Function `%s' should return a value", Func->Name);
}
#endif
/* Output the function exit code label */
g_defcodelabel (GetRetLab (CurrentFunc));
g_defcodelabel (F_GetRetLab (CurrentFunc));
/* Restore the register variables */
RestoreRegVars (!IsVoidFunc);

View File

@ -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 */
unsigned GetParamCount (const Function* F);
unsigned F_GetParamCount (const Function* F);
/* 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 */
type* GetReturnType (Function* F);
type* F_GetReturnType (Function* F);
/* 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 */
int IsVariadic (const Function* F);
int F_IsVariadic (const Function* F);
/* 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 */
int GetTopLevelSP (const Function* F);
int F_GetTopLevelSP (const Function* F);
/* 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
* offset.
*/
void AllocLocalSpace (Function* F);
void F_AllocLocalSpace (Function* F);
/* Allocate any local space previously reserved. The function will do
* nothing if there is no reserved local space.
*/

View File

@ -184,7 +184,7 @@ static void ParseOneDecl (const DeclSpec* Spec)
ExprDesc lval;
/* Allocate previously reserved local space */
AllocLocalSpace (CurrentFunc);
F_AllocLocalSpace (CurrentFunc);
/* Skip the '=' */
NextToken ();
@ -215,7 +215,7 @@ static void ParseOneDecl (const DeclSpec* Spec)
/* Non-initialized local variable. Just keep track of
* the space needed.
*/
SymData = ReserveLocalSpace (CurrentFunc, Size);
SymData = F_ReserveLocalSpace (CurrentFunc, Size);
}
} else {
@ -377,7 +377,7 @@ void DeclareLocals (void)
}
/* 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
* the stack checking routine if stack checks are enabled.
@ -404,7 +404,7 @@ void RestoreRegVars (int HaveResult)
}
/* Save the accumulator if needed */
if (!HasVoidReturn (CurrentFunc) && HaveResult) {
if (!F_HasVoidReturn (CurrentFunc) && HaveResult) {
g_save (CF_CHAR | CF_FORCECHAR);
}
@ -449,7 +449,7 @@ void RestoreRegVars (int HaveResult)
}
/* Restore the accumulator if needed */
if (!HasVoidReturn (CurrentFunc) && HaveResult) {
if (!F_HasVoidReturn (CurrentFunc) && HaveResult) {
g_restore (CF_CHAR | CF_FORCECHAR);
}
}

View File

@ -547,7 +547,7 @@ void NextToken (void)
} else if (strcmp (token, "__func__") == 0) {
/* __func__ is only defined in functions */
if (CurrentFunc) {
NextTok.IVal = AddLiteral (GetFuncName (CurrentFunc));
NextTok.IVal = AddLiteral (F_GetFuncName (CurrentFunc));
NextTok.Tok = TOK_SCONST;
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.
* This routine is used for error recovery.
*/
{
{
while (CurTok.Tok != TOK_CEOF) {
/* Check if the current token is in the token list */

View File

@ -242,7 +242,7 @@ static void ReturnStatement (void)
NextToken ();
if (CurTok.Tok != TOK_SEMI) {
if (HasVoidReturn (CurrentFunc)) {
if (F_HasVoidReturn (CurrentFunc)) {
Error ("Returning a value in function with return type void");
}
@ -250,18 +250,18 @@ static void ReturnStatement (void)
expression (&lval);
/* Convert the return value to the type of the function result */
if (!HasVoidReturn (CurrentFunc)) {
assignadjust (GetReturnType (CurrentFunc), &lval);
if (!F_HasVoidReturn (CurrentFunc)) {
assignadjust (F_GetReturnType (CurrentFunc), &lval);
}
} else if (!HasVoidReturn (CurrentFunc)) {
Error ("Function `%s' must return a value", GetFuncName (CurrentFunc));
} else if (!F_HasVoidReturn (CurrentFunc) && !F_HasOldStyleIntRet (CurrentFunc)) {
Error ("Function `%s' must return a value", F_GetFuncName (CurrentFunc));
}
/* 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 */
g_jump (GetRetLab (CurrentFunc));
g_jump (F_GetRetLab (CurrentFunc));
}