mirror of
https://github.com/cc65/cc65.git
synced 2024-11-16 18:08:04 +00:00
Fixed an error when parsing local variables: Variables must be inserted into
the symbol table *before* the optional initializer is parsed, because they might be referenced in the intializer. git-svn-id: svn://svn.cc65.org/cc65/trunk@5648 b7a2c559-68d2-44c3-8de9-860c34a00d81
This commit is contained in:
parent
b0c4678ad2
commit
faf58a8220
@ -6,7 +6,7 @@
|
|||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* (C) 2000-2011, Ullrich von Bassewitz */
|
/* (C) 2000-2012, Ullrich von Bassewitz */
|
||||||
/* Roemerstrasse 52 */
|
/* Roemerstrasse 52 */
|
||||||
/* D-70794 Filderstadt */
|
/* D-70794 Filderstadt */
|
||||||
/* EMail: uz@cc65.org */
|
/* EMail: uz@cc65.org */
|
||||||
@ -237,6 +237,16 @@ int F_ReserveLocalSpace (Function* F, unsigned Size)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
int F_GetStackPtr (const Function* F)
|
||||||
|
/* Return the current stack pointer including reserved (but not allocated)
|
||||||
|
* space on the stack.
|
||||||
|
*/
|
||||||
|
{
|
||||||
|
return StackPtr - F->Reserved;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void F_AllocLocalSpace (Function* F)
|
void F_AllocLocalSpace (Function* F)
|
||||||
/* Allocate any local space previously reserved. The function will do
|
/* Allocate any local space previously reserved. The function will do
|
||||||
* nothing if there is no reserved local space.
|
* nothing if there is no reserved local space.
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* (C) 1998-2009, Ullrich von Bassewitz */
|
/* (C) 1998-2012, Ullrich von Bassewitz */
|
||||||
/* Roemerstrasse 52 */
|
/* Roemerstrasse 52 */
|
||||||
/* D-70794 Filderstadt */
|
/* D-70794 Filderstadt */
|
||||||
/* EMail: uz@cc65.org */
|
/* EMail: uz@cc65.org */
|
||||||
@ -102,6 +102,11 @@ int F_ReserveLocalSpace (Function* F, unsigned Size);
|
|||||||
* offset.
|
* offset.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
int F_GetStackPtr (const Function* F);
|
||||||
|
/* Return the current stack pointer including reserved (but not allocated)
|
||||||
|
* space on the stack.
|
||||||
|
*/
|
||||||
|
|
||||||
void F_AllocLocalSpace (Function* F);
|
void F_AllocLocalSpace (Function* F);
|
||||||
/* Allocate any local space previously reserved. The function will do
|
/* Allocate any local space previously reserved. The function will do
|
||||||
* nothing if there is no reserved local space.
|
* nothing if there is no reserved local space.
|
||||||
|
@ -79,29 +79,27 @@ static unsigned AllocLabel (void (*UseSeg) ())
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
static unsigned AllocStorage (void (*UseSeg) (), unsigned Size)
|
static void AllocStorage (unsigned Label, void (*UseSeg) (), unsigned Size)
|
||||||
/* Reserve Size bytes of BSS storage prefixed by a local label. Return the
|
/* Reserve Size bytes of BSS storage prefixed by a local label. */
|
||||||
* label.
|
|
||||||
*/
|
|
||||||
{
|
{
|
||||||
/* Switch to the segment and define the label */
|
/* Switch to the segment */
|
||||||
unsigned Label = AllocLabel (UseSeg);
|
UseSeg ();
|
||||||
|
|
||||||
|
/* Define the variable label */
|
||||||
|
g_defdatalabel (Label);
|
||||||
|
|
||||||
/* Reserve space for the data */
|
/* Reserve space for the data */
|
||||||
g_res (Size);
|
g_res (Size);
|
||||||
|
|
||||||
/* Return the label */
|
|
||||||
return Label;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static unsigned ParseRegisterDecl (Declaration* Decl, unsigned* SC, int Reg)
|
static void ParseRegisterDecl (Declaration* Decl, int Reg)
|
||||||
/* Parse the declaration of a register variable. The function returns the
|
/* Parse the declaration of a register variable. Reg is the offset of the
|
||||||
* symbol data, which is the offset of the variable in the register bank.
|
* variable in the register bank.
|
||||||
*/
|
*/
|
||||||
{
|
{
|
||||||
unsigned InitLabel;
|
SymEntry* Sym;
|
||||||
|
|
||||||
/* Determine if this is a compound variable */
|
/* Determine if this is a compound variable */
|
||||||
int IsCompound = IsClassStruct (Decl->Type) || IsTypeArray (Decl->Type);
|
int IsCompound = IsClassStruct (Decl->Type) || IsTypeArray (Decl->Type);
|
||||||
@ -113,6 +111,12 @@ static unsigned ParseRegisterDecl (Declaration* Decl, unsigned* SC, int Reg)
|
|||||||
F_AllocLocalSpace (CurrentFunc);
|
F_AllocLocalSpace (CurrentFunc);
|
||||||
g_save_regvars (Reg, Size);
|
g_save_regvars (Reg, Size);
|
||||||
|
|
||||||
|
/* Add the symbol to the symbol table. We do that now, because for register
|
||||||
|
* variables the current stack pointer is implicitly used as location for
|
||||||
|
* the save area.
|
||||||
|
*/
|
||||||
|
Sym = AddLocalSym (Decl->Ident, Decl->Type, Decl->StorageClass, Reg);
|
||||||
|
|
||||||
/* Check for an optional initialization */
|
/* Check for an optional initialization */
|
||||||
if (CurTok.Tok == TOK_ASSIGN) {
|
if (CurTok.Tok == TOK_ASSIGN) {
|
||||||
|
|
||||||
@ -127,7 +131,7 @@ static unsigned ParseRegisterDecl (Declaration* Decl, unsigned* SC, int Reg)
|
|||||||
/* Switch to read only data and define a label for the
|
/* Switch to read only data and define a label for the
|
||||||
* initialization data.
|
* initialization data.
|
||||||
*/
|
*/
|
||||||
InitLabel = AllocLabel (g_userodata);
|
unsigned InitLabel = AllocLabel (g_userodata);
|
||||||
|
|
||||||
/* Parse the initialization generating a memory image of the
|
/* Parse the initialization generating a memory image of the
|
||||||
* data in the RODATA segment. The function does return the size
|
* data in the RODATA segment. The function does return the size
|
||||||
@ -137,7 +141,7 @@ static unsigned ParseRegisterDecl (Declaration* Decl, unsigned* SC, int Reg)
|
|||||||
* know the size of the data in advance for register variables,
|
* know the size of the data in advance for register variables,
|
||||||
* we cannot allow that here.
|
* we cannot allow that here.
|
||||||
*/
|
*/
|
||||||
if (ParseInit (Decl->Type) != Size) {
|
if (ParseInit (Sym->Type) != Size) {
|
||||||
Error ("Cannot initialize flexible array members of storage class `register'");
|
Error ("Cannot initialize flexible array members of storage class `register'");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -150,39 +154,33 @@ static unsigned ParseRegisterDecl (Declaration* Decl, unsigned* SC, int Reg)
|
|||||||
hie1 (&Expr);
|
hie1 (&Expr);
|
||||||
|
|
||||||
/* Convert it to the target type */
|
/* Convert it to the target type */
|
||||||
TypeConversion (&Expr, Decl->Type);
|
TypeConversion (&Expr, Sym->Type);
|
||||||
|
|
||||||
/* Load the value into the primary */
|
/* Load the value into the primary */
|
||||||
LoadExpr (CF_NONE, &Expr);
|
LoadExpr (CF_NONE, &Expr);
|
||||||
|
|
||||||
/* Store the value into the variable */
|
/* Store the value into the variable */
|
||||||
g_putstatic (CF_REGVAR | TypeOf (Decl->Type), Reg, 0);
|
g_putstatic (CF_REGVAR | TypeOf (Sym->Type), Reg, 0);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Mark the variable as referenced */
|
/* Mark the variable as referenced */
|
||||||
*SC |= SC_REF;
|
Sym->Flags |= SC_REF;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Cannot allocate a variable of zero size */
|
/* Cannot allocate a variable of zero size */
|
||||||
if (Size == 0) {
|
if (Size == 0) {
|
||||||
Error ("Variable `%s' has unknown size", Decl->Ident);
|
Error ("Variable `%s' has unknown size", Decl->Ident);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Return the symbol data */
|
|
||||||
return Reg;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static unsigned ParseAutoDecl (Declaration* Decl, unsigned* SC)
|
static void ParseAutoDecl (Declaration* Decl)
|
||||||
/* Parse the declaration of an auto variable. The function returns the symbol
|
/* Parse the declaration of an auto variable. */
|
||||||
* data, which is the offset for variables on the stack, and the label for
|
|
||||||
* static variables.
|
|
||||||
*/
|
|
||||||
{
|
{
|
||||||
unsigned Flags;
|
unsigned Flags;
|
||||||
unsigned SymData;
|
SymEntry* Sym;
|
||||||
|
|
||||||
/* Determine if this is a compound variable */
|
/* Determine if this is a compound variable */
|
||||||
int IsCompound = IsClassStruct (Decl->Type) || IsTypeArray (Decl->Type);
|
int IsCompound = IsClassStruct (Decl->Type) || IsTypeArray (Decl->Type);
|
||||||
@ -193,6 +191,13 @@ static unsigned ParseAutoDecl (Declaration* Decl, unsigned* SC)
|
|||||||
/* Check if this is a variable on the stack or in static memory */
|
/* Check if this is a variable on the stack or in static memory */
|
||||||
if (IS_Get (&StaticLocals) == 0) {
|
if (IS_Get (&StaticLocals) == 0) {
|
||||||
|
|
||||||
|
/* Add the symbol to the symbol table. The stack offset we use here
|
||||||
|
* may get corrected later.
|
||||||
|
*/
|
||||||
|
Sym = AddLocalSym (Decl->Ident, Decl->Type,
|
||||||
|
Decl->StorageClass,
|
||||||
|
F_GetStackPtr (CurrentFunc) - (int) Size);
|
||||||
|
|
||||||
/* Check for an optional initialization */
|
/* Check for an optional initialization */
|
||||||
if (CurTok.Tok == TOK_ASSIGN) {
|
if (CurTok.Tok == TOK_ASSIGN) {
|
||||||
|
|
||||||
@ -216,10 +221,12 @@ static unsigned ParseAutoDecl (Declaration* Decl, unsigned* SC)
|
|||||||
* that contains a flexible array member and we're not in
|
* that contains a flexible array member and we're not in
|
||||||
* ANSI mode.
|
* ANSI mode.
|
||||||
*/
|
*/
|
||||||
Size = ParseInit (Decl->Type);
|
Size = ParseInit (Sym->Type);
|
||||||
|
|
||||||
/* Now reserve space for the variable on the stack */
|
/* Now reserve space for the variable on the stack and correct
|
||||||
SymData = F_ReserveLocalSpace (CurrentFunc, Size);
|
* the offset in the symbol table entry.
|
||||||
|
*/
|
||||||
|
Sym->V.Offs = F_ReserveLocalSpace (CurrentFunc, Size);
|
||||||
|
|
||||||
/* Next, allocate the space on the stack. This means that the
|
/* Next, allocate the space on the stack. This means that the
|
||||||
* variable is now located at offset 0 from the current sp.
|
* variable is now located at offset 0 from the current sp.
|
||||||
@ -243,7 +250,7 @@ static unsigned ParseAutoDecl (Declaration* Decl, unsigned* SC)
|
|||||||
hie1 (&Expr);
|
hie1 (&Expr);
|
||||||
|
|
||||||
/* Convert it to the target type */
|
/* Convert it to the target type */
|
||||||
TypeConversion (&Expr, Decl->Type);
|
TypeConversion (&Expr, Sym->Type);
|
||||||
|
|
||||||
/* If the value is not const, load it into the primary.
|
/* If the value is not const, load it into the primary.
|
||||||
* Otherwise pass the information to the code generator.
|
* Otherwise pass the information to the code generator.
|
||||||
@ -256,27 +263,33 @@ static unsigned ParseAutoDecl (Declaration* Decl, unsigned* SC)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Push the value */
|
/* Push the value */
|
||||||
g_push (Flags | TypeOf (Decl->Type), Expr.IVal);
|
g_push (Flags | TypeOf (Sym->Type), Expr.IVal);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Mark the variable as referenced */
|
/* Mark the variable as referenced */
|
||||||
*SC |= SC_REF;
|
Sym->Flags |= SC_REF;
|
||||||
|
|
||||||
/* Variable is located at the current SP */
|
|
||||||
SymData = StackPtr;
|
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
/* Non-initialized local variable. Just keep track of
|
/* Non-initialized local variable. Just keep track of
|
||||||
* the space needed.
|
* the space needed.
|
||||||
*/
|
*/
|
||||||
SymData = F_ReserveLocalSpace (CurrentFunc, Size);
|
F_ReserveLocalSpace (CurrentFunc, Size);
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
|
unsigned DataLabel;
|
||||||
|
|
||||||
|
|
||||||
/* Static local variables. */
|
/* Static local variables. */
|
||||||
*SC = (*SC & ~SC_AUTO) | SC_STATIC;
|
Decl->StorageClass = (Decl->StorageClass & ~SC_AUTO) | SC_STATIC;
|
||||||
|
|
||||||
|
/* Generate a label, but don't define it */
|
||||||
|
DataLabel = GetLocalLabel ();
|
||||||
|
|
||||||
|
/* Add the symbol to the symbol table. */
|
||||||
|
Sym = AddLocalSym (Decl->Ident, Decl->Type, Decl->StorageClass, DataLabel);
|
||||||
|
|
||||||
/* Allow assignments */
|
/* Allow assignments */
|
||||||
if (CurTok.Tok == TOK_ASSIGN) {
|
if (CurTok.Tok == TOK_ASSIGN) {
|
||||||
@ -296,39 +309,39 @@ static unsigned ParseAutoDecl (Declaration* Decl, unsigned* SC)
|
|||||||
/* Parse the initialization generating a memory image of the
|
/* Parse the initialization generating a memory image of the
|
||||||
* data in the RODATA segment.
|
* data in the RODATA segment.
|
||||||
*/
|
*/
|
||||||
Size = ParseInit (Decl->Type);
|
Size = ParseInit (Sym->Type);
|
||||||
|
|
||||||
/* Allocate a label and space for the variable */
|
/* Allocate space for the variable */
|
||||||
SymData = AllocStorage (g_usebss, Size);
|
AllocStorage (DataLabel, g_usebss, Size);
|
||||||
|
|
||||||
/* Generate code to copy this data into the variable space */
|
/* Generate code to copy this data into the variable space */
|
||||||
g_initstatic (InitLabel, SymData, Size);
|
g_initstatic (InitLabel, DataLabel, Size);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
/* Allocate a label and space for the variable */
|
/* Allocate space for the variable */
|
||||||
SymData = AllocStorage (g_usebss, Size);
|
AllocStorage (DataLabel, g_usebss, Size);
|
||||||
|
|
||||||
/* Parse the expression */
|
/* Parse the expression */
|
||||||
hie1 (&Expr);
|
hie1 (&Expr);
|
||||||
|
|
||||||
/* Convert it to the target type */
|
/* Convert it to the target type */
|
||||||
TypeConversion (&Expr, Decl->Type);
|
TypeConversion (&Expr, Sym->Type);
|
||||||
|
|
||||||
/* Load the value into the primary */
|
/* Load the value into the primary */
|
||||||
LoadExpr (CF_NONE, &Expr);
|
LoadExpr (CF_NONE, &Expr);
|
||||||
|
|
||||||
/* Store the value into the variable */
|
/* Store the value into the variable */
|
||||||
g_putstatic (TypeOf (Decl->Type), SymData, 0);
|
g_putstatic (TypeOf (Sym->Type), DataLabel, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Mark the variable as referenced */
|
/* Mark the variable as referenced */
|
||||||
*SC |= SC_REF;
|
Sym->Flags |= SC_REF;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
/* No assignment - allocate a label and space for the variable */
|
/* No assignment - allocate a label and space for the variable */
|
||||||
SymData = AllocStorage (g_usebss, Size);
|
AllocStorage (DataLabel, g_usebss, Size);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -337,50 +350,50 @@ static unsigned ParseAutoDecl (Declaration* Decl, unsigned* SC)
|
|||||||
if (Size == 0) {
|
if (Size == 0) {
|
||||||
Error ("Variable `%s' has unknown size", Decl->Ident);
|
Error ("Variable `%s' has unknown size", Decl->Ident);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Return the symbol data */
|
|
||||||
return SymData;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static unsigned ParseStaticDecl (Declaration* Decl, unsigned* SC)
|
static void ParseStaticDecl (Declaration* Decl)
|
||||||
/* Parse the declaration of a static variable. The function returns the symbol
|
/* Parse the declaration of a static variable. */
|
||||||
* data, which is the asm label of the variable.
|
|
||||||
*/
|
|
||||||
{
|
{
|
||||||
unsigned SymData;
|
|
||||||
unsigned Size;
|
unsigned Size;
|
||||||
|
|
||||||
|
/* Generate a label, but don't define it */
|
||||||
|
unsigned DataLabel = GetLocalLabel ();
|
||||||
|
|
||||||
|
/* Add the symbol to the symbol table. */
|
||||||
|
SymEntry* Sym = AddLocalSym (Decl->Ident, Decl->Type,
|
||||||
|
Decl->StorageClass,
|
||||||
|
DataLabel);
|
||||||
|
|
||||||
/* Static data */
|
/* Static data */
|
||||||
if (CurTok.Tok == TOK_ASSIGN) {
|
if (CurTok.Tok == TOK_ASSIGN) {
|
||||||
|
|
||||||
/* Initialization ahead, switch to data segment and define a label.
|
/* Initialization ahead, switch to data segment and define the label.
|
||||||
* For arrays, we need to check the elements of the array for
|
* For arrays, we need to check the elements of the array for
|
||||||
* constness, not the array itself.
|
* constness, not the array itself.
|
||||||
*/
|
*/
|
||||||
if (IsQualConst (GetBaseElementType (Decl->Type))) {
|
if (IsQualConst (GetBaseElementType (Sym->Type))) {
|
||||||
SymData = AllocLabel (g_userodata);
|
g_userodata ();
|
||||||
} else {
|
} else {
|
||||||
SymData = AllocLabel (g_usedata);
|
g_usedata ();
|
||||||
}
|
}
|
||||||
|
g_defdatalabel (DataLabel);
|
||||||
|
|
||||||
/* Skip the '=' */
|
/* Skip the '=' */
|
||||||
NextToken ();
|
NextToken ();
|
||||||
|
|
||||||
/* Allow initialization of static vars */
|
/* Allow initialization of static vars */
|
||||||
Size = ParseInit (Decl->Type);
|
Size = ParseInit (Sym->Type);
|
||||||
|
|
||||||
/* Mark the variable as referenced */
|
/* Mark the variable as referenced */
|
||||||
*SC |= SC_REF;
|
Sym->Flags |= SC_REF;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
/* Get the size of the variable */
|
|
||||||
Size = SizeOf (Decl->Type);
|
|
||||||
|
|
||||||
/* Allocate a label and space for the variable in the BSS segment */
|
/* Allocate a label and space for the variable in the BSS segment */
|
||||||
SymData = AllocStorage (g_usebss, Size);
|
AllocStorage (DataLabel, g_usebss, SizeOf (Sym->Type));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -388,9 +401,6 @@ static unsigned ParseStaticDecl (Declaration* Decl, unsigned* SC)
|
|||||||
if (Size == 0) {
|
if (Size == 0) {
|
||||||
Error ("Variable `%s' has unknown size", Decl->Ident);
|
Error ("Variable `%s' has unknown size", Decl->Ident);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Return the symbol data */
|
|
||||||
return SymData;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -398,7 +408,6 @@ static unsigned ParseStaticDecl (Declaration* Decl, unsigned* SC)
|
|||||||
static void ParseOneDecl (const DeclSpec* Spec)
|
static void ParseOneDecl (const DeclSpec* Spec)
|
||||||
/* Parse one variable declaration */
|
/* Parse one variable declaration */
|
||||||
{
|
{
|
||||||
unsigned SymData = 0; /* Symbol data (offset, label name, ...) */
|
|
||||||
Declaration Decl; /* Declaration data structure */
|
Declaration Decl; /* Declaration data structure */
|
||||||
|
|
||||||
|
|
||||||
@ -421,6 +430,11 @@ static void ParseOneDecl (const DeclSpec* Spec)
|
|||||||
AnonName (Decl.Ident, "param");
|
AnonName (Decl.Ident, "param");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* If the symbol is not marked as external, it will be defined now */
|
||||||
|
if ((Decl.StorageClass & SC_EXTERN) == 0) {
|
||||||
|
Decl.StorageClass |= SC_DEF;
|
||||||
|
}
|
||||||
|
|
||||||
/* Handle anything that needs storage (no functions, no typdefs) */
|
/* Handle anything that needs storage (no functions, no typdefs) */
|
||||||
if ((Decl.StorageClass & SC_FUNC) != SC_FUNC &&
|
if ((Decl.StorageClass & SC_FUNC) != SC_FUNC &&
|
||||||
(Decl.StorageClass & SC_TYPEDEF) != SC_TYPEDEF) {
|
(Decl.StorageClass & SC_TYPEDEF) != SC_TYPEDEF) {
|
||||||
@ -438,31 +452,30 @@ static void ParseOneDecl (const DeclSpec* Spec)
|
|||||||
/* Check the variable type */
|
/* Check the variable type */
|
||||||
if ((Decl.StorageClass & SC_REGISTER) == SC_REGISTER) {
|
if ((Decl.StorageClass & SC_REGISTER) == SC_REGISTER) {
|
||||||
/* Register variable */
|
/* Register variable */
|
||||||
SymData = ParseRegisterDecl (&Decl, &Decl.StorageClass, Reg);
|
ParseRegisterDecl (&Decl, Reg);
|
||||||
} else if ((Decl.StorageClass & SC_AUTO) == SC_AUTO) {
|
} else if ((Decl.StorageClass & SC_AUTO) == SC_AUTO) {
|
||||||
/* Auto variable */
|
/* Auto variable */
|
||||||
SymData = ParseAutoDecl (&Decl, &Decl.StorageClass);
|
ParseAutoDecl (&Decl);
|
||||||
} else if ((Decl.StorageClass & SC_EXTERN) == SC_EXTERN) {
|
} else if ((Decl.StorageClass & SC_EXTERN) == SC_EXTERN) {
|
||||||
/* External identifier - may not get initialized */
|
/* External identifier - may not get initialized */
|
||||||
if (CurTok.Tok == TOK_ASSIGN) {
|
if (CurTok.Tok == TOK_ASSIGN) {
|
||||||
Error ("Cannot initialize externals");
|
Error ("Cannot initialize externals");
|
||||||
}
|
}
|
||||||
SymData = 0;
|
/* Add the external symbol to the symbol table */
|
||||||
|
AddLocalSym (Decl.Ident, Decl.Type, Decl.StorageClass, 0);
|
||||||
} else if ((Decl.StorageClass & SC_STATIC) == SC_STATIC) {
|
} else if ((Decl.StorageClass & SC_STATIC) == SC_STATIC) {
|
||||||
/* Static variable */
|
/* Static variable */
|
||||||
SymData = ParseStaticDecl (&Decl, &Decl.StorageClass);
|
ParseStaticDecl (&Decl);
|
||||||
} else {
|
} else {
|
||||||
Internal ("Invalid storage class in ParseOneDecl: %04X", Decl.StorageClass);
|
Internal ("Invalid storage class in ParseOneDecl: %04X", Decl.StorageClass);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/* If the symbol is not marked as external, it will be defined now */
|
} else {
|
||||||
if ((Decl.StorageClass & SC_EXTERN) == 0) {
|
|
||||||
Decl.StorageClass |= SC_DEF;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Add the symbol to the symbol table */
|
/* Add the symbol to the symbol table */
|
||||||
AddLocalSym (Decl.Ident, Decl.Type, Decl.StorageClass, SymData);
|
AddLocalSym (Decl.Ident, Decl.Type, Decl.StorageClass, 0);
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -19,7 +19,7 @@ CC65_INC = \"/usr/lib/cc65/include/\"
|
|||||||
|
|
||||||
#
|
#
|
||||||
CC = gcc
|
CC = gcc
|
||||||
CFLAGS = -O2 -g -Wall -W -std=c89
|
CFLAGS = -g -Wall -W -std=c89
|
||||||
override CFLAGS += -I$(COMMON)
|
override CFLAGS += -I$(COMMON)
|
||||||
override CFLAGS += -DCC65_INC=$(CC65_INC)
|
override CFLAGS += -DCC65_INC=$(CC65_INC)
|
||||||
EBIND = emxbind
|
EBIND = emxbind
|
||||||
|
Loading…
Reference in New Issue
Block a user