Skip to content

Commit

Permalink
Merge pull request cc65#2344 from acqn/Cleanup
Browse files Browse the repository at this point in the history
[cc65] Cleanup for symbol types and flags
  • Loading branch information
mrdudz authored Jan 12, 2024
2 parents 0f7d2dd + 38dac90 commit 8c329df
Show file tree
Hide file tree
Showing 12 changed files with 368 additions and 259 deletions.
25 changes: 13 additions & 12 deletions src/cc65/asmstmt.c
Original file line number Diff line number Diff line change
Expand Up @@ -80,9 +80,9 @@ static void AsmErrorSkip (void)



static SymEntry* AsmGetSym (unsigned Arg, unsigned Type)
/* Find the symbol with the name currently in NextTok. The symbol must be of
** the given type. On errors, NULL is returned.
static SymEntry* AsmGetSym (unsigned Arg, int OnStack)
/* Find the symbol with the name currently in NextTok. The symbol must be on
** the stack if OnStack is true. On errors, NULL is returned.
*/
{
SymEntry* Sym;
Expand Down Expand Up @@ -110,8 +110,8 @@ static SymEntry* AsmGetSym (unsigned Arg, unsigned Type)
/* We found the symbol - skip the name token */
NextToken ();

/* Check if we have a global symbol */
if ((Sym->Flags & Type) != Type) {
/* Check if the symbol is on the stack */
if ((Sym->Flags & SC_STORAGEMASK) != SC_AUTO ? OnStack : !OnStack) {
Error ("Type of argument %u differs from format specifier", Arg);
AsmErrorSkip ();
return 0;
Expand Down Expand Up @@ -218,23 +218,24 @@ static void ParseGVarArg (StrBuf* T, unsigned Arg)
*/
{
/* Parse the symbol name parameter and check the type */
SymEntry* Sym = AsmGetSym (Arg, SC_STATIC);
SymEntry* Sym = AsmGetSym (Arg, 0);
if (Sym == 0) {
/* Some sort of error */
return;
}

/* Check for external linkage */
if (Sym->Flags & (SC_EXTERN | SC_STORAGE | SC_FUNC)) {
/* External linkage or a function */
/* Get the correct asm name */
if ((Sym->Flags & SC_TYPEMASK) == SC_FUNC || SymIsGlobal (Sym)) {
/* External or internal linkage or a function */
SB_AppendChar (T, '_');
SB_AppendStr (T, Sym->Name);
} else if (Sym->Flags & SC_REGISTER) {
} else if ((Sym->Flags & SC_STORAGEMASK) == SC_REGISTER) {
/* Register variable */
char Buf[32];
xsprintf (Buf, sizeof (Buf), "regbank+%d", Sym->V.R.RegOffs);
SB_AppendStr (T, Buf);
} else {
/* Static variable */
/* Local static variable */
SB_AppendStr (T, LocalDataLabelName (Sym->V.L.Label));
}
}
Expand All @@ -248,7 +249,7 @@ static void ParseLVarArg (StrBuf* T, unsigned Arg)
char Buf [16];

/* Parse the symbol name parameter and check the type */
SymEntry* Sym = AsmGetSym (Arg, SC_AUTO);
SymEntry* Sym = AsmGetSym (Arg, 1);
if (Sym == 0) {
/* Some sort of error */
return;
Expand Down
57 changes: 30 additions & 27 deletions src/cc65/compile.c
Original file line number Diff line number Diff line change
Expand Up @@ -121,15 +121,13 @@ static void Parse (void)
}

/* Read the declaration specifier */
ParseDeclSpec (&Spec, TS_DEFAULT_TYPE_INT, SC_EXTERN | SC_STATIC);
ParseDeclSpec (&Spec, TS_DEFAULT_TYPE_INT, SC_NONE);

/* Don't accept illegal storage classes */
if ((Spec.StorageClass & SC_TYPEMASK) == 0) {
if ((Spec.StorageClass & SC_AUTO) != 0 ||
(Spec.StorageClass & SC_REGISTER) != 0) {
Error ("Illegal storage class");
Spec.StorageClass = SC_EXTERN | SC_STATIC;
}
if ((Spec.StorageClass & SC_STORAGEMASK) == SC_AUTO ||
(Spec.StorageClass & SC_STORAGEMASK) == SC_REGISTER) {
Error ("Illegal storage class");
Spec.StorageClass &= ~SC_STORAGEMASK;
}

/* Check if this is only a type declaration */
Expand Down Expand Up @@ -172,26 +170,26 @@ static void Parse (void)
** - if the storage class is explicitly specified as static,
** - or if there is an initialization.
**
** This means that "extern int i;" will not get storage allocated.
** This means that "extern int i;" will not get storage allocated
** in this translation unit.
*/
if ((Decl.StorageClass & SC_FUNC) != SC_FUNC &&
if ((Decl.StorageClass & SC_TYPEMASK) != SC_FUNC &&
(Decl.StorageClass & SC_TYPEMASK) != SC_TYPEDEF) {
if ((Spec.Flags & DS_DEF_STORAGE) != 0 ||
(Decl.StorageClass & (SC_EXTERN|SC_STATIC)) == SC_STATIC ||
((Decl.StorageClass & SC_EXTERN) != 0 &&
/* The variable is visible in the file scope */
if ((Decl.StorageClass & SC_STORAGEMASK) == SC_NONE ||
(Decl.StorageClass & SC_STORAGEMASK) == SC_STATIC ||
((Decl.StorageClass & SC_STORAGEMASK) == SC_EXTERN &&
CurTok.Tok == TOK_ASSIGN)) {
/* We will allocate storage */
Decl.StorageClass |= SC_STORAGE;
} else {
/* It's a declaration */
Decl.StorageClass |= SC_DECL;
/* We will allocate storage in this translation unit */
Decl.StorageClass |= SC_TU_STORAGE;
}
}

/* If this is a function declarator that is not followed by a comma
** or semicolon, it must be followed by a function body.
*/
if ((Decl.StorageClass & SC_FUNC) != 0) {
if ((Decl.StorageClass & SC_TYPEMASK) == SC_FUNC) {
/* The function is now visible in the file scope */
if (CurTok.Tok == TOK_LCURLY) {
/* A definition */
Decl.StorageClass |= SC_DEF;
Expand All @@ -205,8 +203,6 @@ static void Parse (void)
}
} else {
/* Just a declaration */
Decl.StorageClass |= SC_DECL;

FuncDef = GetFuncDesc (Decl.Type);
if ((FuncDef->Flags & (FD_EMPTY | FD_OLDSTYLE)) == FD_OLDSTYLE) {
/* A parameter list without types is only allowed in a
Expand All @@ -224,7 +220,7 @@ static void Parse (void)
SymUseAttr (Sym, &Decl);

/* Reserve storage for the variable if we need to */
if (Decl.StorageClass & SC_STORAGE) {
if (Decl.StorageClass & SC_TU_STORAGE) {

/* Get the size of the variable */
unsigned Size = SizeOf (Decl.Type);
Expand Down Expand Up @@ -327,9 +323,13 @@ static void Parse (void)
}

/* Make the symbol zeropage according to the segment address size */
if ((Sym->Flags & SC_STATIC) != 0) {
if (GetSegAddrSize (GetSegName (CS->CurDSeg)) == ADDR_SIZE_ZP) {
Sym->Flags |= SC_ZEROPAGE;
if ((Sym->Flags & SC_TYPEMASK) == SC_NONE) {
if (SymIsGlobal (Sym) ||
(Sym->Flags & SC_STORAGEMASK) == SC_STATIC ||
(Sym->Flags & SC_STORAGEMASK) == SC_REGISTER) {
if (GetSegAddrSize (GetSegName (CS->CurDSeg)) == ADDR_SIZE_ZP) {
Sym->Flags |= SC_ZEROPAGE;
}
}
}

Expand Down Expand Up @@ -517,7 +517,10 @@ void Compile (const char* FileName)
** global variables.
*/
for (Entry = GetGlobalSymTab ()->SymHead; Entry; Entry = Entry->NextSym) {
if ((Entry->Flags & (SC_STORAGE | SC_DEF | SC_STATIC)) == (SC_STORAGE | SC_STATIC)) {
/* Is it a global (with or without static) tentative declaration of
** an uninitialized variable?
*/
if ((Entry->Flags & (SC_TU_STORAGE | SC_DEF)) == SC_TU_STORAGE) {
/* Assembly definition of uninitialized global variable */
SymEntry* TagSym = GetESUTagSym (Entry->Type);
unsigned Size = SizeOf (Entry->Type);
Expand Down Expand Up @@ -552,9 +555,9 @@ void Compile (const char* FileName)
Entry->Name,
GetFullTypeName (Entry->Type));
}
} else if (!SymIsDef (Entry) && (Entry->Flags & SC_FUNC) == SC_FUNC) {
} else if (!SymIsDef (Entry) && (Entry->Flags & SC_TYPEMASK) == SC_FUNC) {
/* Check for undefined functions */
if ((Entry->Flags & (SC_EXTERN | SC_STATIC)) == SC_STATIC && SymIsRef (Entry)) {
if ((Entry->Flags & SC_STORAGEMASK) == SC_STATIC && SymIsRef (Entry)) {
Warning ("Static function '%s' used but never defined",
Entry->Name);
}
Expand Down
38 changes: 20 additions & 18 deletions src/cc65/declare.c
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ static unsigned ParseOneStorageClass (void)
switch (CurTok.Tok) {

case TOK_EXTERN:
StorageClass = SC_EXTERN | SC_STATIC;
StorageClass = SC_EXTERN;
NextToken ();
break;

Expand All @@ -101,7 +101,7 @@ static unsigned ParseOneStorageClass (void)
break;

case TOK_REGISTER:
StorageClass = SC_REGISTER | SC_STATIC;
StorageClass = SC_REGISTER;
NextToken ();
break;

Expand Down Expand Up @@ -136,9 +136,9 @@ static int ParseStorageClass (DeclSpec* Spec)
}

while (StorageClass != 0) {
if (Spec->StorageClass == 0) {
Spec->StorageClass = StorageClass;
} else if (Spec->StorageClass == StorageClass) {
if ((Spec->StorageClass & SC_STORAGEMASK) == 0) {
Spec->StorageClass |= StorageClass;
} else if ((Spec->StorageClass & SC_STORAGEMASK) == StorageClass) {
Warning ("Duplicate storage class specifier");
} else {
Error ("Conflicting storage class specifier");
Expand Down Expand Up @@ -618,12 +618,12 @@ static SymEntry* ForwardESU (const char* Name, unsigned Flags, unsigned* DSFlags
*/
SymEntry* TagEntry = FindTagSym (Name);
if (TagEntry == 0) {
if ((Flags & SC_ESUTYPEMASK) != SC_ENUM) {
if ((Flags & SC_TYPEMASK) != SC_ENUM) {
TagEntry = AddStructSym (Name, Flags, 0, 0, DSFlags);
} else {
TagEntry = AddEnumSym (Name, Flags, 0, 0, DSFlags);
}
} else if ((TagEntry->Flags & SC_TYPEMASK) != (Flags & SC_ESUTYPEMASK)) {
} else if ((TagEntry->Flags & SC_TYPEMASK) != (Flags & SC_TYPEMASK)) {
/* Already defined, but not the same type class */
Error ("Symbol '%s' is already different kind", Name);
}
Expand Down Expand Up @@ -798,7 +798,7 @@ static SymEntry* ParseEnumSpec (const char* Name, unsigned* DSFlags)
}

/* Add an entry of the enumerator to the symbol table */
AddConstSym (Ident, NewType, SC_ENUMERATOR | SC_CONST, EnumVal);
AddConstSym (Ident, NewType, SC_DEF | SC_ENUMERATOR, EnumVal);

/* Use this type for following members */
MemberType = NewType;
Expand Down Expand Up @@ -1825,8 +1825,8 @@ static void ParseOldStyleParamDeclList (FuncDesc* F attribute ((unused)))
/* We accept only auto and register as storage class specifiers, but
** we ignore all this, since we use auto anyway.
*/
if ((Spec.StorageClass & SC_AUTO) == 0 &&
(Spec.StorageClass & SC_REGISTER) == 0) {
if ((Spec.StorageClass & SC_STORAGEMASK) != SC_AUTO &&
(Spec.StorageClass & SC_STORAGEMASK) != SC_REGISTER) {
Error ("Illegal storage class");
}

Expand Down Expand Up @@ -1942,12 +1942,12 @@ static void ParseAnsiParamList (FuncDesc* F)
ParseDeclSpec (&Spec, TS_DEFAULT_TYPE_NONE, SC_AUTO);

/* We accept only auto and register as storage class specifiers */
if ((Spec.StorageClass & SC_AUTO) == SC_AUTO) {
Spec.StorageClass = SC_AUTO | SC_PARAM | SC_DEF;
} else if ((Spec.StorageClass & SC_REGISTER) == SC_REGISTER) {
Spec.StorageClass = SC_REGISTER | SC_STATIC | SC_PARAM | SC_DEF;
if ((Spec.StorageClass & SC_STORAGEMASK) == SC_REGISTER) {
Spec.StorageClass = SC_REGISTER | SC_PARAM | SC_DEF;
} else {
Error ("Illegal storage class");
if ((Spec.StorageClass & SC_STORAGEMASK) != SC_AUTO) {
Error ("Illegal storage class");
}
Spec.StorageClass = SC_AUTO | SC_PARAM | SC_DEF;
}

Expand Down Expand Up @@ -2355,7 +2355,9 @@ int ParseDecl (DeclSpec* Spec, Declarator* D, declmode_t Mode)
D->StorageClass = Spec->StorageClass;

/* If we have a function, add a special symbol type */
if (IsTypeFunc (D->Type)) {
if (Mode != DM_ACCEPT_PARAM_IDENT &&
IsTypeFunc (D->Type) &&
(D->StorageClass & SC_TYPEMASK) == SC_NONE) {
D->StorageClass |= SC_FUNC;
}

Expand Down Expand Up @@ -2479,9 +2481,9 @@ void ParseDeclSpec (DeclSpec* Spec, typespec_t TSFlags, unsigned DefStorage)
ParseTypeSpec (Spec, TSFlags | TS_STORAGE_CLASS_SPEC | TS_FUNCTION_SPEC);

/* If no explicit storage class is given, use the default */
if (Spec->StorageClass == 0) {
if ((Spec->StorageClass & SC_STORAGEMASK) == 0) {
Spec->Flags |= DS_DEF_STORAGE;
Spec->StorageClass = DefStorage;
Spec->StorageClass |= DefStorage;
}
}

Expand Down
31 changes: 15 additions & 16 deletions src/cc65/expr.c
Original file line number Diff line number Diff line change
Expand Up @@ -1223,8 +1223,8 @@ static void Primary (ExprDesc* E)
NextToken ();

/* Check for illegal symbol types */
CHECK ((Sym->Flags & SC_LABEL) != SC_LABEL);
if (Sym->Flags & SC_ESUTYPEMASK) {
CHECK ((Sym->Flags & SC_TYPEMASK) != SC_LABEL);
if ((Sym->Flags & SC_TYPEMASK) == SC_TYPEDEF) {
/* Cannot use type symbols */
Error ("Variable identifier expected");
/* Assume an int type to make E valid */
Expand All @@ -1244,7 +1244,7 @@ static void Primary (ExprDesc* E)
/* Enum or some other numeric constant */
E->Flags = E_LOC_NONE | E_RTYPE_RVAL;
E->IVal = Sym->V.ConstVal;
} else if ((Sym->Flags & SC_AUTO) == SC_AUTO) {
} else if ((Sym->Flags & SC_STORAGEMASK) == SC_AUTO) {
/* Local variable. If this is a parameter for a variadic
** function, we have to add some address calculations, and the
** address is not const.
Expand All @@ -1258,26 +1258,25 @@ static void Primary (ExprDesc* E)
E->Flags = E_LOC_STACK | E_RTYPE_LVAL;
E->IVal = Sym->V.Offs;
}
} else if ((Sym->Flags & SC_FUNC) == SC_FUNC) {
} else if ((Sym->Flags & SC_TYPEMASK) == SC_FUNC) {
/* Function */
E->Flags = E_LOC_GLOBAL | E_RTYPE_LVAL;
E->Name = (uintptr_t) Sym->Name;
} else if ((Sym->Flags & SC_REGISTER) == SC_REGISTER) {
} else if ((Sym->Flags & SC_STORAGEMASK) == SC_REGISTER) {
/* Register variable, zero page based */
E->Flags = E_LOC_REGISTER | E_RTYPE_LVAL;
E->Name = Sym->V.R.RegOffs;
} else if ((Sym->Flags & SC_STATIC) == SC_STATIC) {
/* Static variable */
if (Sym->Flags & (SC_EXTERN | SC_STORAGE | SC_DECL)) {
E->Flags = E_LOC_GLOBAL | E_RTYPE_LVAL;
E->Name = (uintptr_t) Sym->Name;
} else {
E->Flags = E_LOC_STATIC | E_RTYPE_LVAL;
E->Name = Sym->V.L.Label;
}
} else {
} else if (SymIsGlobal (Sym)) {
/* Global variable */
E->Flags = E_LOC_GLOBAL | E_RTYPE_LVAL;
E->Name = (uintptr_t) Sym->Name;
} else if ((Sym->Flags & SC_STORAGEMASK) == SC_STATIC) {
/* Local static variable */
E->Flags = E_LOC_STATIC | E_RTYPE_LVAL;
E->Name = Sym->V.L.Label;
} else {
/* Other */
E->Flags = E_LOC_STATIC | E_RTYPE_LVAL;
E->Name = Sym->V.Offs;
}

Expand Down Expand Up @@ -1311,7 +1310,7 @@ static void Primary (ExprDesc* E)
} else {
Warning ("Call to undeclared function '%s'", Ident);
}
Sym = AddGlobalSym (Ident, GetImplicitFuncType(), SC_EXTERN | SC_REF | SC_FUNC);
Sym = AddGlobalSym (Ident, GetImplicitFuncType(), SC_REF | SC_FUNC);
E->Type = Sym->Type;
E->Flags = E_LOC_GLOBAL | E_RTYPE_RVAL;
E->Name = (uintptr_t) Sym->Name;
Expand Down
2 changes: 1 addition & 1 deletion src/cc65/exprdesc.h
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ enum {
E_LOC_NONE = 0x0000, /* Pure rvalue with no storage */
E_LOC_ABS = 0x0001, /* Absolute numeric addressed variable */
E_LOC_GLOBAL = 0x0002, /* Global variable */
E_LOC_STATIC = 0x0004, /* Static variable */
E_LOC_STATIC = 0x0004, /* Local static variable */
E_LOC_REGISTER = 0x0008, /* Register variable */
E_LOC_STACK = 0x0010, /* Value on the stack */
E_LOC_PRIMARY = 0x0020, /* Temporary in primary register */
Expand Down
2 changes: 1 addition & 1 deletion src/cc65/goto.c
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ void GotoStatement (void)

/* Find array size */
if (!IsTypeArray (arr->Type) || SizeOf (arr->Type) == 0 ||
!(arr->Flags & SC_STATIC) ||
(arr->Flags & SC_STORAGEMASK) != SC_STATIC ||
SizeOf (GetElementType(arr->Type)) != 2) {
Error ("Expected a static array");
} else if (GetElementCount (arr->Type) > 127) {
Expand Down
Loading

0 comments on commit 8c329df

Please sign in to comment.