]> git.sur5r.net Git - cc65/commitdiff
Rewrote parsing of locals.
authorcuz <cuz@b7a2c559-68d2-44c3-8de9-860c34a00d81>
Thu, 22 Jun 2000 11:28:39 +0000 (11:28 +0000)
committercuz <cuz@b7a2c559-68d2-44c3-8de9-860c34a00d81>
Thu, 22 Jun 2000 11:28:39 +0000 (11:28 +0000)
Removed non working code for register variables.

git-svn-id: svn://svn.cc65.org/cc65/trunk@96 b7a2c559-68d2-44c3-8de9-860c34a00d81

src/cc65/function.c
src/cc65/function.h
src/cc65/locals.c
src/cc65/symtab.c

index effb97aab2bdaf4587ad2ad0732156340524393e..7f26312d94ef6200f9a63a22acfcbf6f34a7fb71 100644 (file)
@@ -61,9 +61,8 @@ struct Function {
     type*              ReturnType;     /* Function return type */
     struct FuncDesc*   Desc;           /* Function descriptor */
     CodeMark           EntryCode;      /* Backpatch addr for entry code */
-    int                        LocalMax;       /* Total space for locals */
-    int                        LocalSize;      /* Current space for locals */
-    unsigned           RetLab;         /* Return code label */
+    int                        Reserved;       /* Reserved local space */
+    unsigned           RetLab;         /* Return code label */
 };
 
 /* Pointer to current function */
@@ -88,8 +87,7 @@ static Function* NewFunction (struct SymEntry* Sym)
     F->ReturnType = Sym->Type + 1 + DECODE_SIZE;
     F->Desc      = DecodePtr (Sym->Type + 1);
     F->EntryCode  = 0;
-    F->LocalMax          = 0;
-    F->LocalSize  = 0;
+    F->Reserved          = 0;
     F->RetLab    = GetLabel ();
 
     /* Return the new structure */
@@ -154,39 +152,42 @@ unsigned GetRetLab (const Function* F)
 
 
 
-int AllocLocalSpace (Function* F, unsigned Size)
-/* Allocate space for the function locals, return stack offset */
+int ReserveLocalSpace (Function* F, unsigned Size)
+/* Reserve (but don't allocate) the given local space and return the stack
+ * offset.
+ */
 {
-    /* Add the size */
-    F->LocalSize += Size;
-    if (F->LocalSize > F->LocalMax) {
-       F->LocalMax = F->LocalSize;
-    }
-
-    /* Return the offset, it is below the initial stack pointer */
-    return -F->LocalSize;;
+    F->Reserved += Size;
+    return oursp - F->Reserved;
 }
 
 
 
-void FreeLocalSpace (Function* F, unsigned Size)
-/* Free space allocated for function locals */
+void AllocLocalSpace (Function* F)
+/* Allocate any local space previously reserved. The function will do
+ * nothing if there is no reserved local space.
+ */
 {
-    F->LocalSize -= Size;
-}
+    if (F->Reserved > 0) {
 
+       /* Switch to the code segment */
+       g_usecode ();
 
+       /* Create space on the stack */
+       g_space (F->Reserved);
 
-unsigned GetLocalSpace (const Function* F)
-/* Get the local variable space needed for the function */
-{
-    return F->LocalMax;
+       /* Correct the stack pointer */
+       oursp -= F->Reserved;
+
+       /* Nothing more reserved */
+       F->Reserved = 0;
+    }
 }
 
 
 
 /*****************************************************************************/
-/*                                          code                                    */
+/*                                          code                                    */
 /*****************************************************************************/
 
 
index a07683637489ea5fef8f5b3300098960e35c9529..a2b11f1b7ad1f53de3f66b3c5776f2c82297902a 100644 (file)
@@ -49,19 +49,20 @@ void RememberEntry (Function* F);
 unsigned GetRetLab (const Function* F);
 /* Return the return jump label */
 
-int AllocLocalSpace (Function* F, unsigned Size);
-/* Allocate space for the function locals, return stack offset  */
+int ReserveLocalSpace (Function* F, unsigned Size);
+/* Reserve (but don't allocate) the given local space and return the stack
+ * offset.
+ */
 
-void FreeLocalSpace (Function* F, unsigned Size);
-/* Free space allocated for function locals */
+void AllocLocalSpace (Function* F);
+/* Allocate any local space previously reserved. The function will do
+ * nothing if there is no reserved local space.
+ */
 
 void NewFunc (struct SymEntry* Func);
 /* Parse argument declarations and function body. */
 
-unsigned GetLocalSpace (const Function* F);
-/* Get the local variable space needed for the function */
 
-                                
 
 /* End of function.h */
 #endif
index ca8715836702412733a13acb9e6d0708686e42a4..1649edcbedf98c50d3bae78f9a3d0b35e39d74e7 100644 (file)
@@ -39,6 +39,7 @@
 #include "asmlabel.h"
 #include "codegen.h"
 #include "declare.h"
+#include "error.h"
 #include "expr.h"
 #include "function.h"
 #include "global.h"
@@ -129,276 +130,236 @@ static int AllocRegVar (const SymEntry* Sym, const type* tarray)
 
 
 
-void DeclareLocals (void)
-/* Declare local variables and types. */
+static void ParseOneDecl (const DeclSpec* Spec)
+/* Parse one variable declaration */
 {
-    int offs = oursp;                  /* Current stack offset for variable */
-    int AutoSpace = 0;                 /* Unallocated space on the stack */
-    int Size;                  /* Size of an auto variable */
-    int Reg;                   /* Register variable offset */
-    unsigned flags = 0;                /* Code generator flags */
-    int SymbolSC;                      /* Storage class for symbol */
-    int ldata = 0;                     /* Local symbol data temp storage */
-
-    /* Loop until we don't find any more variables */
-    while (1) {
-
-       /* Check variable declarations. We need to distinguish between a
-        * default int type and the end of variable declarations. So we
-        * will do the following: If there is no explicit storage class
-        * specifier *and* no explicit type given, it is assume that we
-                * have reached the end of declarations.
-        */
-       DeclSpec Spec;
-       ParseDeclSpec (&Spec, SC_AUTO, T_INT);
-               if ((Spec.Flags & DS_DEF_STORAGE) != 0 && (Spec.Flags & DS_DEF_TYPE) != 0) {
-           break;
-       }
-
-       /* Accept type only declarations */
-       if (curtok == TOK_SEMI) {
-           /* Type declaration only */
-           CheckEmptyDecl (&Spec);
-           NextToken ();
-           continue;
+    int        Size;           /* Size of an auto variable */
+    int        SC;             /* Storage class for symbol */
+    int                SymData = 0;    /* Symbol data (offset, label name, ...) */
+    unsigned   flags = 0;      /* Code generator flags */
+    Declaration Decl;          /* Declaration data structure */
+
+    /* Remember the storage class for the new symbol */
+    SC = Spec->StorageClass;
+
+    /* Read the declaration */
+    ParseDecl (Spec, &Decl, DM_NEED_IDENT);
+
+    /* Set the correct storage class for functions */
+    if (IsFunc (Decl.Type)) {
+       /* Function prototypes are always external */
+       if ((SC & SC_EXTERN) == 0) {
+                   Warning (WARN_FUNC_MUST_BE_EXTERN);
        }
+               SC |= SC_FUNC | SC_EXTERN;
 
-       /* Parse a comma separated variable list */
-       while (1) {
-
-           Declaration Decl;
-
-           /* Remember the storage class for the new symbol */
-           SymbolSC = Spec.StorageClass;
-
-           /* Read the declaration */
-           ParseDecl (&Spec, &Decl, DM_NEED_IDENT);
-
-           /* If we don't have a name, this was flagged as an error earlier.
-            * To avoid problems later, use an anonymous name here.
-            */
-                   if (Decl.Ident[0] == '\0') {
-               AnonName (Decl.Ident, "param");
-           }
-
-                   if (!IsFunc (Decl.Type) && (SymbolSC & SC_TYPEDEF) != SC_TYPEDEF) {
-
-               /* Get the size of the variable */
-               Size = SizeOf (Decl.Type);
-
-#if 0
-               /* Check the storage class */
-               if ((SymbolSC & SC_REGISTER) && (Reg = AllocRegVar (psym, tarray)) >= 0) {
-
-                   /* We will store the current value of the register onto the
-                    * stack, thus making functions with register variables
-                    * reentrant. If we have pending auto variables, emit them
-                    * now.
-                    */
-                   g_usecode ();
-                   g_space (AutoSpace);
-                   oursp -= AutoSpace;
-                   AutoSpace = 0;
-
-                   /* Remember the register bank offset */
-                   ldata = Reg;
-
-                   /* Save the current register value onto the stack */
-                   g_save_regvars (Reg, Size);
+    }
 
-                   /* Allow variable initialization */
-                   if (curtok == TOK_ASSIGN) {
+    /* If we don't have a name, this was flagged as an error earlier.
+     * To avoid problems later, use an anonymous name here.
+     */
+    if (Decl.Ident[0] == '\0') {
+       AnonName (Decl.Ident, "param");
+    }
 
-                       struct expent lval;
+    /* Handle anything that needs storage (no functions, no typdefs) */
+    if ((SC & SC_FUNC) != SC_FUNC && (SC & SC_TYPEDEF) != SC_TYPEDEF) {
 
-                       /* Skip the '=' */
-                       NextToken ();
+       /* Get the size of the variable */
+       Size = SizeOf (Decl.Type);
 
-                       /* Get the expression into the primary */
-                       expression1 (&lval);
+               if (SC & (SC_AUTO | SC_REGISTER)) {
 
-                       /* Make type adjustments if needed */
-                       assignadjust (tarray, &lval);
+           /* Auto variable */
+           if (StaticLocals == 0) {
 
-                       /* Setup the type flags for the assignment */
-                       flags = TypeOf (tarray) | CF_REGVAR;
-                       if (Size == 1) {
-                           flags |= CF_FORCECHAR;
-                       }
+               /* Change SC in case it was register */
+               SC = (SC & ~SC_REGISTER) | SC_AUTO;
+               if (curtok == TOK_ASSIGN) {
 
-                               /* Store the value into the register */
-                               g_putstatic (flags, Reg, 0);
+                   struct expent lval;
 
-                       /* Mark the variable as referenced */
-                       SymbolSC |= SC_REF;
+                   /* Allocate previously reserved local space */
+                   AllocLocalSpace (CurrentFunc);
 
-                   }
+                   /* Skip the '=' */
+                   NextToken ();
 
-                   /* Account for the stack space needed and remember the
-                    * stack offset of the save area.
-                    */
-                   offs -= Size;
-                   psym->h_lattr = offs;
+                   /* Setup the type flags for the assignment */
+                   flags = Size == 1? CF_FORCECHAR : CF_NONE;
 
-               } else if (SymbolSC & (SC_AUTO | SC_REGISTER)) {
-#endif
-               if (SymbolSC & (SC_AUTO | SC_REGISTER)) {
+                   /* Get the expression into the primary */
+                   if (evalexpr (flags, hie1, &lval) == 0) {
+                       /* Constant expression. Adjust the types */
+                       assignadjust (Decl.Type, &lval);
+                       flags |= CF_CONST;
+                   } else {
+                       /* Expression is not constant and in the primary */
+                       assignadjust (Decl.Type, &lval);
+                   }
 
-                   /* Auto variable */
-                   if (StaticLocals == 0) {
+                   /* Push the value */
+                   g_push (flags | TypeOf (Decl.Type), lval.e_const);
 
-                       /* Change SC in case it was register */
-                               SymbolSC = (SymbolSC & ~SC_REGISTER) | SC_AUTO;
-                       if (curtok == TOK_ASSIGN) {
+                   /* Mark the variable as referenced */
+                   SC |= SC_REF;
 
-                           struct expent lval;
+                   /* Variable is located at the current SP */
+                   SymData = oursp;
 
-                           /* Switch to the code segment, allocate space for
-                            * uninitialized variables.
-                            */
-                           g_usecode ();
-                           g_space (AutoSpace);
-                           oursp -= AutoSpace;
-                           AutoSpace = 0;
+               } else {
+                   /* Non-initialized local variable. Just keep track of
+                    * the space needed.
+                    */
+                   SymData = ReserveLocalSpace (CurrentFunc, Size);
+               }
 
-                           /* Skip the '=' */
-                           NextToken ();
+           } else {
 
-                           /* Setup the type flags for the assignment */
-                           flags = Size == 1? CF_FORCECHAR : CF_NONE;
+               /* Static local variables. */
+               SC = (SC & ~(SC_REGISTER | SC_AUTO)) | SC_STATIC;
 
-                           /* Get the expression into the primary */
-                           if (evalexpr (flags, hie1, &lval) == 0) {
-                               /* Constant expression. Adjust the types */
-                               assignadjust (Decl.Type, &lval);
-                               flags |= CF_CONST;
-                           } else {
-                               /* Expression is not constant and in the primary */
-                               assignadjust (Decl.Type, &lval);
-                           }
+               /* Put them into the BSS */
+               g_usebss ();
 
-                           /* Push the value */
-                           g_push (flags | TypeOf (Decl.Type), lval.e_const);
+               /* Define the variable label */
+               SymData = GetLabel ();
+               g_defloclabel (SymData);
 
-                           /* Mark the variable as referenced */
-                           SymbolSC |= SC_REF;
+               /* Reserve space for the data */
+               g_res (Size);
 
-                       } else {
-                           /* Non-initialized local variable. Just keep track of
-                            * the space needed.
-                            */
-                           AutoSpace += Size;
-                       }
+               /* Allow assignments */
+               if (curtok == TOK_ASSIGN) {
 
-                       /* Allocate space on the stack, assign the offset */
-                       offs -= Size;
-                       ldata = offs;
+                   struct expent lval;
 
-                   } else {
+                   /* Switch to the code segment. */
+                   g_usecode ();
 
-                       /* Static local variables. */
-                               SymbolSC = (SymbolSC & ~(SC_REGISTER | SC_AUTO)) | SC_STATIC;
+                   /* Skip the '=' */
+                   NextToken ();
 
-                       /* Put them into the BSS */
-                       g_usebss ();
+                   /* Get the expression into the primary */
+                   expression1 (&lval);
 
-                       /* Define the variable label */
-                       g_defloclabel (ldata = GetLabel ());
+                   /* Make type adjustments if needed */
+                   assignadjust (Decl.Type, &lval);
 
-                       /* Reserve space for the data */
-                       g_res (Size);
+                   /* Setup the type flags for the assignment */
+                   flags = TypeOf (Decl.Type);
+                   if (Size == 1) {
+                       flags |= CF_FORCECHAR;
+                   }
 
-                       /* Allow assignments */
-                       if (curtok == TOK_ASSIGN) {
+                   /* Store the value into the variable */
+                   g_putstatic (flags, SymData, 0);
 
-                           struct expent lval;
+                   /* Mark the variable as referenced */
+                   SC |= SC_REF;
+               }
+           }
 
-                           /* Switch to the code segment. */
-                           g_usecode ();
+       } else if ((SC & SC_STATIC) == SC_STATIC) {
 
-                           /* Skip the '=' */
-                           NextToken ();
+           /* Static data */
+           if (curtok == TOK_ASSIGN) {
 
-                           /* Get the expression into the primary */
-                           expression1 (&lval);
+               /* Initialization ahead, switch to data segment */
+               g_usedata ();
 
-                           /* Make type adjustments if needed */
-                           assignadjust (Decl.Type, &lval);
+               /* Define the variable label */
+               SymData = GetLabel ();
+               g_defloclabel (SymData);
 
-                           /* Setup the type flags for the assignment */
-                           flags = TypeOf (Decl.Type);
-                           if (Size == 1) {
-                               flags |= CF_FORCECHAR;
-                           }
+               /* Skip the '=' */
+               NextToken ();
 
-                           /* Store the value into the variable */
-                           g_putstatic (flags, ldata, 0);
+               /* Allow initialization of static vars */
+               ParseInit (Decl.Type);
 
-                           /* Mark the variable as referenced */
-                           SymbolSC |= SC_REF;
-                       }
-                   }
+               /* Mark the variable as referenced */
+               SC |= SC_REF;
 
-               } else if ((SymbolSC & SC_STATIC) == SC_STATIC) {
+           } else {
 
-                   /* Static data */
-                   if (curtok == TOK_ASSIGN) {
+               /* Uninitialized data, use BSS segment */
+               g_usebss ();
 
-                       /* Initialization ahead, switch to data segment */
-                       g_usedata ();
+               /* Define the variable label */
+               SymData = GetLabel ();
+               g_defloclabel (SymData);
 
-                       /* Define the variable label */
-                       g_defloclabel (ldata = GetLabel ());
+               /* Reserve space for the data */
+               g_res (Size);
 
-                       /* Skip the '=' */
-                       NextToken ();
+           }
+       }
 
-                       /* Allow initialization of static vars */
-                       ParseInit (Decl.Type);
+    }
 
-                       /* Mark the variable as referenced */
-                       SymbolSC |= SC_REF;
+    /* If the symbol is not marked as external, it will be defined */
+    if ((SC & SC_EXTERN) == 0) {
+       SC |= SC_DEF;
+    }
 
-                   } else {
+    /* Add the symbol to the symbol table */
+    AddLocalSym (Decl.Ident, Decl.Type, SC, SymData);
+}
 
-                       /* Uninitialized data, use BSS segment */
-                       g_usebss ();
 
-                       /* Define the variable label */
-                       g_defloclabel (ldata = GetLabel ());
 
-                       /* Reserve space for the data */
-                       g_res (Size);
+void DeclareLocals (void)
+/* Declare local variables and types. */
+{
+    /* Loop until we don't find any more variables */
+    while (1) {
 
-                   }
-               }
+       /* Check variable declarations. We need to distinguish between a
+        * default int type and the end of variable declarations. So we
+        * will do the following: If there is no explicit storage class
+        * specifier *and* no explicit type given, it is assume that we
+                * have reached the end of declarations.
+        */
+       DeclSpec Spec;
+       ParseDeclSpec (&Spec, SC_AUTO, T_INT);
+               if ((Spec.Flags & DS_DEF_STORAGE) != 0 && (Spec.Flags & DS_DEF_TYPE) != 0) {
+           break;
+       }
 
-           }
+       /* Accept type only declarations */
+       if (curtok == TOK_SEMI) {
+           /* Type declaration only */
+           CheckEmptyDecl (&Spec);
+           NextToken ();
+           continue;
+       }
 
-           /* If the symbol is not marked as external, it will be defined */
-           if ((SymbolSC & SC_EXTERN) == 0) {
-               SymbolSC |= SC_DEF;
-           }
+       /* Parse a comma separated variable list */
+       while (1) {
 
-           /* Add the symbol to the symbol table */
-           AddLocalSym (Decl.Ident, Decl.Type, SymbolSC, ldata);
+           /* Parse one declaration */
+           ParseOneDecl (&Spec);
 
-           if (curtok != TOK_COMMA) {
+           /* Check if there is more */
+           if (curtok == TOK_COMMA) {
+               /* More to come */
+               NextToken ();
+           } else {
+               /* Done */
                break;
            }
-           NextToken ();
                }
-       if (curtok == TOK_SEMI) {
-           NextToken ();
-       }
+
+       /* A semicolon must follow */
+       ConsumeSemi ();
     }
 
+    /* Be sure to allocate any reserved space for locals */
+    AllocLocalSpace (CurrentFunc);
+
     /* In case we switched away from code segment, switch back now */
     g_usecode ();
-
-    /* Create space for locals */
-    g_space (AutoSpace);
-    oursp -= AutoSpace;
 }
 
 
index 28288df6c09635e3065f6855d51bd87f54f11cc6..86cbf41e5555ecc34afc2464dfaebe83a8223711 100644 (file)
@@ -631,18 +631,8 @@ SymEntry* AddLabelSym (const char* Name, unsigned Flags)
 SymEntry* AddLocalSym (const char* Name, type* Type, unsigned Flags, int Offs)
 /* Add a local symbol and return the symbol entry */
 {
-    SymEntry* Entry;
-
-    /* Functions declared inside of functions do always have external linkage */
-    if (Type != 0 && IsFunc (Type)) {
-               if ((Flags & (SC_DEFAULT | SC_EXTERN)) == 0) {
-                   Warning (WARN_FUNC_MUST_BE_EXTERN);
-               }
-               Flags = SC_EXTERN;
-    }
-
     /* Do we have an entry with this name already? */
-    Entry = FindSymInTable (SymTab, Name, HashStr (Name));
+    SymEntry* Entry = FindSymInTable (SymTab, Name, HashStr (Name));
     if (Entry) {
 
        /* We have a symbol with this name already */