From dcdaf8fd49c997f1c1715703937b18170cd0293e Mon Sep 17 00:00:00 2001 From: cuz Date: Thu, 10 Oct 2002 20:24:16 +0000 Subject: [PATCH] Restructured DeclareLocals() git-svn-id: svn://svn.cc65.org/cc65/trunk@1457 b7a2c559-68d2-44c3-8de9-860c34a00d81 --- src/cc65/locals.c | 294 ++++++++++++++++++++++++++-------------------- 1 file changed, 164 insertions(+), 130 deletions(-) diff --git a/src/cc65/locals.c b/src/cc65/locals.c index 46cd83960..4e50ea959 100644 --- a/src/cc65/locals.c +++ b/src/cc65/locals.c @@ -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) { -- 2.39.5