From a96da498f559cc9e794d26924ce0fb7c81c459a0 Mon Sep 17 00:00:00 2001 From: cuz Date: Wed, 12 Jun 2002 12:12:04 +0000 Subject: [PATCH] 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 --- src/cc65/asmstmt.c | 2 +- src/cc65/declare.c | 54 +++++++++++++++++++++++------------------ src/cc65/expr.c | 4 ++-- src/cc65/funcdesc.h | 3 ++- src/cc65/function.c | 58 +++++++++++++++++++++++++++++---------------- src/cc65/function.h | 26 ++++++++++++-------- src/cc65/locals.c | 10 ++++---- src/cc65/scanner.c | 4 ++-- src/cc65/stmt.c | 14 +++++------ 9 files changed, 103 insertions(+), 72 deletions(-) diff --git a/src/cc65/asmstmt.c b/src/cc65/asmstmt.c index 1910d945b..25ab944fc 100644 --- a/src/cc65/asmstmt.c +++ b/src/cc65/asmstmt.c @@ -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; diff --git a/src/cc65/declare.c b/src/cc65/declare.c index c05322f2f..9989cd4ce 100644 --- a/src/cc65/declare.c +++ b/src/cc65/declare.c @@ -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"); + } } } diff --git a/src/cc65/expr.c b/src/cc65/expr.c index 2bf506bbf..c5e308163 100644 --- a/src/cc65/expr.c +++ b/src/cc65/expr.c @@ -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 { diff --git a/src/cc65/funcdesc.h b/src/cc65/funcdesc.h index d2c2ed57e..afdda89d9 100644 --- a/src/cc65/funcdesc.h +++ b/src/cc65/funcdesc.h @@ -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) diff --git a/src/cc65/function.c b/src/cc65/function.c index 1959f94d7..b0269576a 100644 --- a/src/cc65/function.c +++ b/src/cc65/function.c @@ -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); diff --git a/src/cc65/function.h b/src/cc65/function.h index 04c855e6e..56e532179 100644 --- a/src/cc65/function.h +++ b/src/cc65/function.h @@ -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. */ diff --git a/src/cc65/locals.c b/src/cc65/locals.c index 591cbb73a..46cd83960 100644 --- a/src/cc65/locals.c +++ b/src/cc65/locals.c @@ -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); } } diff --git a/src/cc65/scanner.c b/src/cc65/scanner.c index 3584a56a1..0ad5580a2 100644 --- a/src/cc65/scanner.c +++ b/src/cc65/scanner.c @@ -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 */ diff --git a/src/cc65/stmt.c b/src/cc65/stmt.c index 55478e84f..3ab5fd1d6 100644 --- a/src/cc65/stmt.c +++ b/src/cc65/stmt.c @@ -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)); } -- 2.39.2