]> git.sur5r.net Git - cc65/blobdiff - src/cc65/function.c
Fixed a bug
[cc65] / src / cc65 / function.c
index 39f9b5bb6e146ded863aa888eb88fec9d3c3c796..66777b189e624246bda42449db6ecb241992d70a 100644 (file)
@@ -47,6 +47,7 @@
 #include "litpool.h"
 #include "locals.h"
 #include "scanner.h"
+#include "segments.h"
 #include "stmt.h"
 #include "symtab.h"
 #include "function.h"
@@ -108,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;
@@ -116,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;
@@ -124,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;
@@ -132,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;
@@ -140,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);
@@ -148,7 +149,7 @@ 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;
@@ -156,7 +157,23 @@ int IsVariadic (const Function* F)
 
 
 
-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;
@@ -164,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;
@@ -172,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.
  */
@@ -183,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;
     }
 }
 
@@ -214,7 +231,7 @@ void NewFunc (SymEntry* Func)
 {
     int HadReturn;
     int IsVoidFunc;
-    unsigned Flags;
+    SymEntry* LastParam;
 
     /* Get the function descriptor from the function entry */
     FuncDesc* D = Func->V.F.Func;
@@ -225,17 +242,20 @@ void NewFunc (SymEntry* Func)
     /* Reenter the lexical level */
     ReenterFunctionLevel (D);
 
+    /* Before adding more symbols, remember the last parameter for later */
+    LastParam = D->SymTab->SymTail;
+
     /* Declare two special functions symbols: __fixargs__ and __argsize__.
      * The latter is different depending on the type of the function (variadic
      * or not).
      */
     AddConstSym ("__fixargs__", type_uint, SC_DEF | SC_CONST, D->ParamSize);
     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);
+       /* 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);
     } else {
-       /* Non variadic */
+       /* Non variadic */
                AddConstSym ("__argsize__", type_uchar, SC_DEF | SC_CONST, D->ParamSize);
     }
 
@@ -246,22 +266,18 @@ void NewFunc (SymEntry* Func)
     InitRegVars ();
 
     /* Allocate code and data segments for this function */
-    g_pushseg (&Func->V.F.CS, &Func->V.F.DS, Func->Name);
+    Func->V.F.Seg = PushSegments (Func);
 
     /* If this is a fastcall function, push the last parameter onto the stack */
     if (IsFastCallFunc (Func->Type) && D->ParamCount > 0) {
 
-       SymEntry* LastParam;
-       unsigned Flags;
-
-       /* Fastcall functions may never have an ellipsis or the compiler is buggy */
-       CHECK ((D->Flags & FD_VARIADIC) == 0);
+       unsigned Flags;
 
-       /* Get a pointer to the last parameter entry */
-       LastParam = D->SymTab->SymTail;
+       /* Fastcall functions may never have an ellipsis or the compiler is buggy */
+       CHECK ((D->Flags & FD_VARIADIC) == 0);
 
-       /* Generate the push */
-       if (IsTypeFunc (LastParam->Type)) {
+       /* Generate the push */
+       if (IsTypeFunc (LastParam->Type)) {
            /* Pointer to function */
            Flags = CF_PTR;
        } else {
@@ -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;
@@ -294,9 +310,9 @@ void NewFunc (SymEntry* Func)
 
     /* Now process statements in this block */
     HadReturn = 0;
-    while (curtok != TOK_RCURLY) {
-       if (curtok != TOK_CEOF) {
-           HadReturn = Statement ();
+    while (CurTok.Tok != TOK_RCURLY) {
+       if (CurTok.Tok != TOK_CEOF) {
+           HadReturn = Statement (0);
        } else {
            break;
        }
@@ -305,23 +321,22 @@ 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);
 
     /* Generate the exit code */
-    Flags = IsVoidFunc? CF_NONE : CF_REG;
-    g_leave (Flags, 0);
+    g_leave ();
 
     /* Eat the closing brace */
     ConsumeRCurly ();
@@ -336,7 +351,7 @@ void NewFunc (SymEntry* Func)
     LeaveFunctionLevel ();
 
     /* Switch back to the old segments */
-    g_popseg ();
+    PopSegments ();
 
     /* Reset the current function pointer */
     FreeFunction (CurrentFunc);