]> git.sur5r.net Git - cc65/commitdiff
Restructured DeclareLocals()
authorcuz <cuz@b7a2c559-68d2-44c3-8de9-860c34a00d81>
Thu, 10 Oct 2002 20:24:16 +0000 (20:24 +0000)
committercuz <cuz@b7a2c559-68d2-44c3-8de9-860c34a00d81>
Thu, 10 Oct 2002 20:24:16 +0000 (20:24 +0000)
git-svn-id: svn://svn.cc65.org/cc65/trunk@1457 b7a2c559-68d2-44c3-8de9-860c34a00d81

src/cc65/locals.c

index 46cd83960b6e783e06e5df1f7ba327d9493106b2..4e50ea959f3c00f63321960bdc35d02bb0239508 100644 (file)
@@ -133,181 +133,215 @@ static int AllocRegVar (const SymEntry* Sym, const type* tarray)
 
 
 
-static void ParseOneDecl (const DeclSpec* Spec)
-/* Parse one variable declaration */
+static unsigned ParseAutoDecl (Declaration* Decl, unsigned Size, unsigned* SC)
+/* Parse the declaration of an auto variable. The function returns the symbol
+ * data, which is the offset for variables on the stack, and the label for
+ * static variables.
+ */
 {
-    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 */
+    unsigned Flags;
+    unsigned SymData;
 
-    /* Remember the storage class for the new symbol */
-    SC = Spec->StorageClass;
+    /* Check if this is a variable on the stack or in static memory */
+    if (StaticLocals == 0) {
 
-    /* Read the declaration */
-    ParseDecl (Spec, &Decl, DM_NEED_IDENT);
+        /* Change SC in case it was register */
+        *SC = (*SC & ~SC_REGISTER) | SC_AUTO;
+        if (CurTok.Tok == TOK_ASSIGN) {
 
-    /* Set the correct storage class for functions */
-    if (IsTypeFunc (Decl.Type)) {
-       /* Function prototypes are always external */
-       if ((SC & SC_EXTERN) == 0) {
-                   Warning ("Function must be extern");
-       }
-               SC |= SC_FUNC | SC_EXTERN;
+            ExprDesc lval;
 
-    }
+            /* Allocate previously reserved local space */
+            F_AllocLocalSpace (CurrentFunc);
 
-    /* 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");
-    }
+            /* Skip the '=' */
+            NextToken ();
 
-    /* Handle anything that needs storage (no functions, no typdefs) */
-    if ((SC & SC_FUNC) != SC_FUNC && (SC & SC_TYPEDEF) != SC_TYPEDEF) {
+            /* Setup the type flags for the assignment */
+            Flags = (Size == 1)? CF_FORCECHAR : CF_NONE;
 
-       /* Get the size of the variable */
-       Size = SizeOf (Decl.Type);
+            /* 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);
+            }
 
-        /* */
-               if (SC & (SC_AUTO | SC_REGISTER)) {
+            /* Push the value */
+            g_push (Flags | TypeOf (Decl->Type), lval.ConstVal);
 
-           /* Auto variable */
-           if (StaticLocals == 0) {
+            /* Mark the variable as referenced */
+            *SC |= SC_REF;
 
-               /* Change SC in case it was register */
-               SC = (SC & ~SC_REGISTER) | SC_AUTO;
-               if (CurTok.Tok == TOK_ASSIGN) {
+            /* Variable is located at the current SP */
+            SymData = oursp;
 
-                   ExprDesc lval;
+        } else {
+            /* Non-initialized local variable. Just keep track of
+             * the space needed.
+             */
+            SymData = F_ReserveLocalSpace (CurrentFunc, Size);
+        }
 
-                   /* Allocate previously reserved local space */
-                   F_AllocLocalSpace (CurrentFunc);
+    } else {
 
-                   /* Skip the '=' */
-                   NextToken ();
+        /* Static local variables. */
+        *SC = (*SC & ~(SC_REGISTER | SC_AUTO)) | SC_STATIC;
 
-                   /* Setup the type flags for the assignment */
-                   flags = Size == 1? CF_FORCECHAR : CF_NONE;
+        /* Put them into the BSS */
+        g_usebss ();
 
-                   /* 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);
-                   }
+        /* Define the variable label */
+        SymData = GetLocalLabel ();
+        g_defdatalabel (SymData);
 
-                   /* Push the value */
-                   g_push (flags | TypeOf (Decl.Type), lval.ConstVal);
+        /* Reserve space for the data */
+        g_res (Size);
 
-                   /* Mark the variable as referenced */
-                   SC |= SC_REF;
+        /* Allow assignments */
+        if (CurTok.Tok == TOK_ASSIGN) {
 
-                   /* Variable is located at the current SP */
-                   SymData = oursp;
+            ExprDesc lval;
 
-               } else {
-                   /* Non-initialized local variable. Just keep track of
-                    * the space needed.
-                    */
-                   SymData = F_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;
+                /* Load it into the primary */
+                exprhs (Flags, 0, &lval);
+            } else {
+                /* Expression is not constant and in the primary */
+                assignadjust (Decl->Type, &lval);
+            }
 
-               /* Put them into the BSS */
-               g_usebss ();
+            /* Store the value into the variable */
+            g_putstatic (Flags | TypeOf (Decl->Type), SymData, 0);
 
-               /* Define the variable label */
-               SymData = GetLocalLabel ();
-               g_defdatalabel (SymData);
+            /* Mark the variable as referenced */
+            *SC |= SC_REF;
+        }
+    }
 
-               /* Reserve space for the data */
-               g_res (Size);
+    /* Return the symbol data */
+    return SymData;
+}
 
-               /* Allow assignments */
-               if (CurTok.Tok == TOK_ASSIGN) {
 
-                   ExprDesc lval;
 
-                   /* Skip the '=' */
-                   NextToken ();
+static unsigned ParseStaticDecl (Declaration* Decl, unsigned Size, unsigned* SC)
+/* Parse the declaration of a static variable. The function returns the symbol
+ * data, which is the asm label of the variable.
+ */
+{
+    unsigned SymData;
 
-                   /* Setup the type flags for the assignment */
-                   flags = Size == 1? CF_FORCECHAR : CF_NONE;
+    /* Static data */
+    if (CurTok.Tok == TOK_ASSIGN) {
 
-                   /* Get the expression into the primary */
-                   if (evalexpr (flags, hie1, &lval) == 0) {
-                       /* Constant expression. Adjust the types */
-                       assignadjust (Decl.Type, &lval);
-                       flags |= CF_CONST;
-                       /* Load it into the primary */
-                       exprhs (flags, 0, &lval);
-                   } else {
-                       /* Expression is not constant and in the primary */
-                       assignadjust (Decl.Type, &lval);
-                   }
+        /* Initialization ahead, switch to data segment */
+        if (IsQualConst (Decl->Type)) {
+            g_userodata ();
+        } else {
+            g_usedata ();
+        }
 
-                   /* Store the value into the variable */
-                   g_putstatic (flags | TypeOf (Decl.Type), SymData, 0);
+        /* Define the variable label */
+        SymData = GetLocalLabel ();
+        g_defdatalabel (SymData);
 
-                   /* Mark the variable as referenced */
-                   SC |= SC_REF;
-               }
-           }
+        /* Skip the '=' */
+        NextToken ();
 
-       } else if ((SC & SC_STATIC) == SC_STATIC) {
+        /* Allow initialization of static vars */
+        ParseInit (Decl->Type);
 
-           /* Static data */
-           if (CurTok.Tok == TOK_ASSIGN) {
+        /* If the previous size has been unknown, it must be known now */
+        if (Size == 0) {
+            Size = SizeOf (Decl->Type);
+        }
 
-               /* Initialization ahead, switch to data segment */
-               if (IsQualConst (Decl.Type)) {
-                   g_userodata ();
-               } else {
-                   g_usedata ();
-               }
+        /* Mark the variable as referenced */
+        *SC |= SC_REF;
 
-               /* Define the variable label */
-               SymData = GetLocalLabel ();
-               g_defdatalabel (SymData);
+    } else {
 
-               /* Skip the '=' */
-               NextToken ();
+        /* Uninitialized data, use BSS segment */
+        g_usebss ();
 
-               /* Allow initialization of static vars */
-               ParseInit (Decl.Type);
+        /* Define the variable label */
+        SymData = GetLocalLabel ();
+        g_defdatalabel (SymData);
 
-               /* If the previous size has been unknown, it must be known now */
-               if (Size == 0) {
-                           Size = SizeOf (Decl.Type);
-               }
+        /* Reserve space for the data */
+        g_res (Size);
 
-               /* Mark the variable as referenced */
-               SC |= SC_REF;
+    }
 
-           } else {
+    /* Return the symbol data */
+    return SymData;
+}
 
-               /* Uninitialized data, use BSS segment */
-               g_usebss ();
 
-               /* Define the variable label */
-               SymData = GetLocalLabel ();
-               g_defdatalabel (SymData);
 
-               /* Reserve space for the data */
-               g_res (Size);
+static void ParseOneDecl (const DeclSpec* Spec)
+/* Parse one variable declaration */
+{
+    unsigned    SC;            /* Storage class for symbol */
+    unsigned    Size;           /* Size of the data object */
+    unsigned    SymData = 0;    /* Symbol data (offset, label name, ...) */
+    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 (IsTypeFunc (Decl.Type)) {
+       /* Function prototypes are always external */
+       if ((SC & SC_EXTERN) == 0) {
+                   Warning ("Function must be extern");
+       }
+               SC |= SC_FUNC | SC_EXTERN;
+
+    }
+
+    /* 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");
+    }
+
+    /* Handle anything that needs storage (no functions, no typdefs) */
+    if ((SC & SC_FUNC) != SC_FUNC && (SC & SC_TYPEDEF) != SC_TYPEDEF) {
+
+        /* Get the size of the variable */
+        Size = SizeOf (Decl.Type);
+
+        /* */
+               if (SC & (SC_AUTO | SC_REGISTER)) {
+
+            /* Auto variable */
+            SymData = ParseAutoDecl (&Decl, Size, &SC);
+
+       } else if ((SC & SC_STATIC) == SC_STATIC) {
+
+            /* Static variable */
+            SymData = ParseStaticDecl (&Decl, Size, &SC);
+
+               }
 
        /* Cannot allocate a variable of zero size */
        if (Size == 0) {