mirror of
https://github.com/cc65/cc65.git
synced 2024-12-23 04:30:10 +00:00
Rewrote parsing of locals.
Removed non working code for register variables. git-svn-id: svn://svn.cc65.org/cc65/trunk@96 b7a2c559-68d2-44c3-8de9-860c34a00d81
This commit is contained in:
parent
ea43c68b9b
commit
9e83b00152
@ -61,9 +61,8 @@ struct Function {
|
|||||||
type* ReturnType; /* Function return type */
|
type* ReturnType; /* Function return type */
|
||||||
struct FuncDesc* Desc; /* Function descriptor */
|
struct FuncDesc* Desc; /* Function descriptor */
|
||||||
CodeMark EntryCode; /* Backpatch addr for entry code */
|
CodeMark EntryCode; /* Backpatch addr for entry code */
|
||||||
int LocalMax; /* Total space for locals */
|
int Reserved; /* Reserved local space */
|
||||||
int LocalSize; /* Current space for locals */
|
unsigned RetLab; /* Return code label */
|
||||||
unsigned RetLab; /* Return code label */
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Pointer to current function */
|
/* Pointer to current function */
|
||||||
@ -88,8 +87,7 @@ static Function* NewFunction (struct SymEntry* Sym)
|
|||||||
F->ReturnType = Sym->Type + 1 + DECODE_SIZE;
|
F->ReturnType = Sym->Type + 1 + DECODE_SIZE;
|
||||||
F->Desc = DecodePtr (Sym->Type + 1);
|
F->Desc = DecodePtr (Sym->Type + 1);
|
||||||
F->EntryCode = 0;
|
F->EntryCode = 0;
|
||||||
F->LocalMax = 0;
|
F->Reserved = 0;
|
||||||
F->LocalSize = 0;
|
|
||||||
F->RetLab = GetLabel ();
|
F->RetLab = GetLabel ();
|
||||||
|
|
||||||
/* Return the new structure */
|
/* Return the new structure */
|
||||||
@ -154,39 +152,42 @@ unsigned GetRetLab (const Function* F)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
int AllocLocalSpace (Function* F, unsigned Size)
|
int ReserveLocalSpace (Function* F, unsigned Size)
|
||||||
/* Allocate space for the function locals, return stack offset */
|
/* Reserve (but don't allocate) the given local space and return the stack
|
||||||
|
* offset.
|
||||||
|
*/
|
||||||
{
|
{
|
||||||
/* Add the size */
|
F->Reserved += Size;
|
||||||
F->LocalSize += Size;
|
return oursp - F->Reserved;
|
||||||
if (F->LocalSize > F->LocalMax) {
|
}
|
||||||
F->LocalMax = F->LocalSize;
|
|
||||||
|
|
||||||
|
|
||||||
|
void 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) {
|
||||||
|
|
||||||
|
/* Switch to the code segment */
|
||||||
|
g_usecode ();
|
||||||
|
|
||||||
|
/* Create space on the stack */
|
||||||
|
g_space (F->Reserved);
|
||||||
|
|
||||||
|
/* Correct the stack pointer */
|
||||||
|
oursp -= F->Reserved;
|
||||||
|
|
||||||
|
/* Nothing more reserved */
|
||||||
|
F->Reserved = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Return the offset, it is below the initial stack pointer */
|
|
||||||
return -F->LocalSize;;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void FreeLocalSpace (Function* F, unsigned Size)
|
|
||||||
/* Free space allocated for function locals */
|
|
||||||
{
|
|
||||||
F->LocalSize -= Size;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
unsigned GetLocalSpace (const Function* F)
|
|
||||||
/* Get the local variable space needed for the function */
|
|
||||||
{
|
|
||||||
return F->LocalMax;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
/* code */
|
/* code */
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
@ -49,19 +49,20 @@ void RememberEntry (Function* F);
|
|||||||
unsigned GetRetLab (const Function* F);
|
unsigned GetRetLab (const Function* F);
|
||||||
/* Return the return jump label */
|
/* Return the return jump label */
|
||||||
|
|
||||||
int AllocLocalSpace (Function* F, unsigned Size);
|
int ReserveLocalSpace (Function* F, unsigned Size);
|
||||||
/* Allocate space for the function locals, return stack offset */
|
/* Reserve (but don't allocate) the given local space and return the stack
|
||||||
|
* offset.
|
||||||
|
*/
|
||||||
|
|
||||||
void FreeLocalSpace (Function* F, unsigned Size);
|
void AllocLocalSpace (Function* F);
|
||||||
/* Free space allocated for function locals */
|
/* Allocate any local space previously reserved. The function will do
|
||||||
|
* nothing if there is no reserved local space.
|
||||||
|
*/
|
||||||
|
|
||||||
void NewFunc (struct SymEntry* Func);
|
void NewFunc (struct SymEntry* Func);
|
||||||
/* Parse argument declarations and function body. */
|
/* Parse argument declarations and function body. */
|
||||||
|
|
||||||
unsigned GetLocalSpace (const Function* F);
|
|
||||||
/* Get the local variable space needed for the function */
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* End of function.h */
|
/* End of function.h */
|
||||||
#endif
|
#endif
|
||||||
|
@ -39,6 +39,7 @@
|
|||||||
#include "asmlabel.h"
|
#include "asmlabel.h"
|
||||||
#include "codegen.h"
|
#include "codegen.h"
|
||||||
#include "declare.h"
|
#include "declare.h"
|
||||||
|
#include "error.h"
|
||||||
#include "expr.h"
|
#include "expr.h"
|
||||||
#include "function.h"
|
#include "function.h"
|
||||||
#include "global.h"
|
#include "global.h"
|
||||||
@ -129,17 +130,188 @@ static int AllocRegVar (const SymEntry* Sym, const type* tarray)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
static void ParseOneDecl (const DeclSpec* Spec)
|
||||||
|
/* Parse one variable declaration */
|
||||||
|
{
|
||||||
|
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;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 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 */
|
||||||
|
if (StaticLocals == 0) {
|
||||||
|
|
||||||
|
/* Change SC in case it was register */
|
||||||
|
SC = (SC & ~SC_REGISTER) | SC_AUTO;
|
||||||
|
if (curtok == TOK_ASSIGN) {
|
||||||
|
|
||||||
|
struct expent lval;
|
||||||
|
|
||||||
|
/* Allocate previously reserved local space */
|
||||||
|
AllocLocalSpace (CurrentFunc);
|
||||||
|
|
||||||
|
/* Skip the '=' */
|
||||||
|
NextToken ();
|
||||||
|
|
||||||
|
/* Setup the type flags for the assignment */
|
||||||
|
flags = Size == 1? CF_FORCECHAR : CF_NONE;
|
||||||
|
|
||||||
|
/* 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);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Push the value */
|
||||||
|
g_push (flags | TypeOf (Decl.Type), lval.e_const);
|
||||||
|
|
||||||
|
/* Mark the variable as referenced */
|
||||||
|
SC |= SC_REF;
|
||||||
|
|
||||||
|
/* Variable is located at the current SP */
|
||||||
|
SymData = oursp;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
/* Non-initialized local variable. Just keep track of
|
||||||
|
* the space needed.
|
||||||
|
*/
|
||||||
|
SymData = ReserveLocalSpace (CurrentFunc, Size);
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
/* Static local variables. */
|
||||||
|
SC = (SC & ~(SC_REGISTER | SC_AUTO)) | SC_STATIC;
|
||||||
|
|
||||||
|
/* Put them into the BSS */
|
||||||
|
g_usebss ();
|
||||||
|
|
||||||
|
/* Define the variable label */
|
||||||
|
SymData = GetLabel ();
|
||||||
|
g_defloclabel (SymData);
|
||||||
|
|
||||||
|
/* Reserve space for the data */
|
||||||
|
g_res (Size);
|
||||||
|
|
||||||
|
/* Allow assignments */
|
||||||
|
if (curtok == TOK_ASSIGN) {
|
||||||
|
|
||||||
|
struct expent lval;
|
||||||
|
|
||||||
|
/* Switch to the code segment. */
|
||||||
|
g_usecode ();
|
||||||
|
|
||||||
|
/* Skip the '=' */
|
||||||
|
NextToken ();
|
||||||
|
|
||||||
|
/* Get the expression into the primary */
|
||||||
|
expression1 (&lval);
|
||||||
|
|
||||||
|
/* Make type adjustments if needed */
|
||||||
|
assignadjust (Decl.Type, &lval);
|
||||||
|
|
||||||
|
/* Setup the type flags for the assignment */
|
||||||
|
flags = TypeOf (Decl.Type);
|
||||||
|
if (Size == 1) {
|
||||||
|
flags |= CF_FORCECHAR;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Store the value into the variable */
|
||||||
|
g_putstatic (flags, SymData, 0);
|
||||||
|
|
||||||
|
/* Mark the variable as referenced */
|
||||||
|
SC |= SC_REF;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} else if ((SC & SC_STATIC) == SC_STATIC) {
|
||||||
|
|
||||||
|
/* Static data */
|
||||||
|
if (curtok == TOK_ASSIGN) {
|
||||||
|
|
||||||
|
/* Initialization ahead, switch to data segment */
|
||||||
|
g_usedata ();
|
||||||
|
|
||||||
|
/* Define the variable label */
|
||||||
|
SymData = GetLabel ();
|
||||||
|
g_defloclabel (SymData);
|
||||||
|
|
||||||
|
/* Skip the '=' */
|
||||||
|
NextToken ();
|
||||||
|
|
||||||
|
/* Allow initialization of static vars */
|
||||||
|
ParseInit (Decl.Type);
|
||||||
|
|
||||||
|
/* Mark the variable as referenced */
|
||||||
|
SC |= SC_REF;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
/* Uninitialized data, use BSS segment */
|
||||||
|
g_usebss ();
|
||||||
|
|
||||||
|
/* Define the variable label */
|
||||||
|
SymData = GetLabel ();
|
||||||
|
g_defloclabel (SymData);
|
||||||
|
|
||||||
|
/* Reserve space for the data */
|
||||||
|
g_res (Size);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If the symbol is not marked as external, it will be defined */
|
||||||
|
if ((SC & SC_EXTERN) == 0) {
|
||||||
|
SC |= SC_DEF;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Add the symbol to the symbol table */
|
||||||
|
AddLocalSym (Decl.Ident, Decl.Type, SC, SymData);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void DeclareLocals (void)
|
void DeclareLocals (void)
|
||||||
/* Declare local variables and types. */
|
/* Declare local variables and types. */
|
||||||
{
|
{
|
||||||
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 */
|
/* Loop until we don't find any more variables */
|
||||||
while (1) {
|
while (1) {
|
||||||
|
|
||||||
@ -166,239 +338,28 @@ void DeclareLocals (void)
|
|||||||
/* Parse a comma separated variable list */
|
/* Parse a comma separated variable list */
|
||||||
while (1) {
|
while (1) {
|
||||||
|
|
||||||
Declaration Decl;
|
/* Parse one declaration */
|
||||||
|
ParseOneDecl (&Spec);
|
||||||
|
|
||||||
/* Remember the storage class for the new symbol */
|
/* Check if there is more */
|
||||||
SymbolSC = Spec.StorageClass;
|
if (curtok == TOK_COMMA) {
|
||||||
|
/* More to come */
|
||||||
/* Read the declaration */
|
NextToken ();
|
||||||
ParseDecl (&Spec, &Decl, DM_NEED_IDENT);
|
} else {
|
||||||
|
/* Done */
|
||||||
/* 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) {
|
|
||||||
|
|
||||||
struct expent lval;
|
|
||||||
|
|
||||||
/* Skip the '=' */
|
|
||||||
NextToken ();
|
|
||||||
|
|
||||||
/* Get the expression into the primary */
|
|
||||||
expression1 (&lval);
|
|
||||||
|
|
||||||
/* Make type adjustments if needed */
|
|
||||||
assignadjust (tarray, &lval);
|
|
||||||
|
|
||||||
/* Setup the type flags for the assignment */
|
|
||||||
flags = TypeOf (tarray) | CF_REGVAR;
|
|
||||||
if (Size == 1) {
|
|
||||||
flags |= CF_FORCECHAR;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Store the value into the register */
|
|
||||||
g_putstatic (flags, Reg, 0);
|
|
||||||
|
|
||||||
/* Mark the variable as referenced */
|
|
||||||
SymbolSC |= SC_REF;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Account for the stack space needed and remember the
|
|
||||||
* stack offset of the save area.
|
|
||||||
*/
|
|
||||||
offs -= Size;
|
|
||||||
psym->h_lattr = offs;
|
|
||||||
|
|
||||||
} else if (SymbolSC & (SC_AUTO | SC_REGISTER)) {
|
|
||||||
#endif
|
|
||||||
if (SymbolSC & (SC_AUTO | SC_REGISTER)) {
|
|
||||||
|
|
||||||
/* Auto variable */
|
|
||||||
if (StaticLocals == 0) {
|
|
||||||
|
|
||||||
/* Change SC in case it was register */
|
|
||||||
SymbolSC = (SymbolSC & ~SC_REGISTER) | SC_AUTO;
|
|
||||||
if (curtok == TOK_ASSIGN) {
|
|
||||||
|
|
||||||
struct expent lval;
|
|
||||||
|
|
||||||
/* Switch to the code segment, allocate space for
|
|
||||||
* uninitialized variables.
|
|
||||||
*/
|
|
||||||
g_usecode ();
|
|
||||||
g_space (AutoSpace);
|
|
||||||
oursp -= AutoSpace;
|
|
||||||
AutoSpace = 0;
|
|
||||||
|
|
||||||
/* Skip the '=' */
|
|
||||||
NextToken ();
|
|
||||||
|
|
||||||
/* Setup the type flags for the assignment */
|
|
||||||
flags = Size == 1? CF_FORCECHAR : CF_NONE;
|
|
||||||
|
|
||||||
/* 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);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Push the value */
|
|
||||||
g_push (flags | TypeOf (Decl.Type), lval.e_const);
|
|
||||||
|
|
||||||
/* Mark the variable as referenced */
|
|
||||||
SymbolSC |= SC_REF;
|
|
||||||
|
|
||||||
} else {
|
|
||||||
/* Non-initialized local variable. Just keep track of
|
|
||||||
* the space needed.
|
|
||||||
*/
|
|
||||||
AutoSpace += Size;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Allocate space on the stack, assign the offset */
|
|
||||||
offs -= Size;
|
|
||||||
ldata = offs;
|
|
||||||
|
|
||||||
} else {
|
|
||||||
|
|
||||||
/* Static local variables. */
|
|
||||||
SymbolSC = (SymbolSC & ~(SC_REGISTER | SC_AUTO)) | SC_STATIC;
|
|
||||||
|
|
||||||
/* Put them into the BSS */
|
|
||||||
g_usebss ();
|
|
||||||
|
|
||||||
/* Define the variable label */
|
|
||||||
g_defloclabel (ldata = GetLabel ());
|
|
||||||
|
|
||||||
/* Reserve space for the data */
|
|
||||||
g_res (Size);
|
|
||||||
|
|
||||||
/* Allow assignments */
|
|
||||||
if (curtok == TOK_ASSIGN) {
|
|
||||||
|
|
||||||
struct expent lval;
|
|
||||||
|
|
||||||
/* Switch to the code segment. */
|
|
||||||
g_usecode ();
|
|
||||||
|
|
||||||
/* Skip the '=' */
|
|
||||||
NextToken ();
|
|
||||||
|
|
||||||
/* Get the expression into the primary */
|
|
||||||
expression1 (&lval);
|
|
||||||
|
|
||||||
/* Make type adjustments if needed */
|
|
||||||
assignadjust (Decl.Type, &lval);
|
|
||||||
|
|
||||||
/* Setup the type flags for the assignment */
|
|
||||||
flags = TypeOf (Decl.Type);
|
|
||||||
if (Size == 1) {
|
|
||||||
flags |= CF_FORCECHAR;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Store the value into the variable */
|
|
||||||
g_putstatic (flags, ldata, 0);
|
|
||||||
|
|
||||||
/* Mark the variable as referenced */
|
|
||||||
SymbolSC |= SC_REF;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
} else if ((SymbolSC & SC_STATIC) == SC_STATIC) {
|
|
||||||
|
|
||||||
/* Static data */
|
|
||||||
if (curtok == TOK_ASSIGN) {
|
|
||||||
|
|
||||||
/* Initialization ahead, switch to data segment */
|
|
||||||
g_usedata ();
|
|
||||||
|
|
||||||
/* Define the variable label */
|
|
||||||
g_defloclabel (ldata = GetLabel ());
|
|
||||||
|
|
||||||
/* Skip the '=' */
|
|
||||||
NextToken ();
|
|
||||||
|
|
||||||
/* Allow initialization of static vars */
|
|
||||||
ParseInit (Decl.Type);
|
|
||||||
|
|
||||||
/* Mark the variable as referenced */
|
|
||||||
SymbolSC |= SC_REF;
|
|
||||||
|
|
||||||
} else {
|
|
||||||
|
|
||||||
/* Uninitialized data, use BSS segment */
|
|
||||||
g_usebss ();
|
|
||||||
|
|
||||||
/* Define the variable label */
|
|
||||||
g_defloclabel (ldata = GetLabel ());
|
|
||||||
|
|
||||||
/* Reserve space for the data */
|
|
||||||
g_res (Size);
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/* If the symbol is not marked as external, it will be defined */
|
|
||||||
if ((SymbolSC & SC_EXTERN) == 0) {
|
|
||||||
SymbolSC |= SC_DEF;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Add the symbol to the symbol table */
|
|
||||||
AddLocalSym (Decl.Ident, Decl.Type, SymbolSC, ldata);
|
|
||||||
|
|
||||||
if (curtok != TOK_COMMA) {
|
|
||||||
break;
|
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 */
|
/* In case we switched away from code segment, switch back now */
|
||||||
g_usecode ();
|
g_usecode ();
|
||||||
|
|
||||||
/* Create space for locals */
|
|
||||||
g_space (AutoSpace);
|
|
||||||
oursp -= AutoSpace;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -631,18 +631,8 @@ SymEntry* AddLabelSym (const char* Name, unsigned Flags)
|
|||||||
SymEntry* AddLocalSym (const char* Name, type* Type, unsigned Flags, int Offs)
|
SymEntry* AddLocalSym (const char* Name, type* Type, unsigned Flags, int Offs)
|
||||||
/* Add a local symbol and return the symbol entry */
|
/* 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? */
|
/* Do we have an entry with this name already? */
|
||||||
Entry = FindSymInTable (SymTab, Name, HashStr (Name));
|
SymEntry* Entry = FindSymInTable (SymTab, Name, HashStr (Name));
|
||||||
if (Entry) {
|
if (Entry) {
|
||||||
|
|
||||||
/* We have a symbol with this name already */
|
/* We have a symbol with this name already */
|
||||||
|
Loading…
Reference in New Issue
Block a user