1
0
mirror of https://github.com/cc65/cc65.git synced 2024-06-26 05:29:30 +00:00

Merge pull request #381 from pfusik/static-forward-decl

"static" forward declarations
This commit is contained in:
Oliver Schmidt 2017-03-12 18:26:14 +01:00 committed by GitHub
commit a780df1fe1
7 changed files with 146 additions and 26 deletions

View File

@ -157,7 +157,7 @@ static void Parse (void)
CurTok.Tok == TOK_ASSIGN))) {
/* We will allocate storage */
Decl.StorageClass |= SC_STORAGE | SC_DEF;
Decl.StorageClass |= SC_STORAGE;
}
/* If this is a function declarator that is not followed by a comma
@ -190,6 +190,13 @@ static void Parse (void)
/* Allow initialization */
if (CurTok.Tok == TOK_ASSIGN) {
/* This is a definition */
if (SymIsDef (Entry)) {
Error ("Global variable `%s' has already been defined",
Entry->Name);
}
Entry->Flags |= SC_DEF;
/* We cannot initialize types of unknown size, or
** void types in ISO modes.
*/
@ -237,18 +244,14 @@ static void Parse (void)
Entry->Flags &= ~(SC_STORAGE | SC_DEF);
}
/* Allocate storage if it is still needed */
if (Entry->Flags & SC_STORAGE) {
/* Switch to the BSS segment */
g_usebss ();
/* Define a label */
g_defgloblabel (Entry->Name);
/* Allocate space for uninitialized variable */
g_res (Size);
}
/* A global (including static) uninitialized variable
** is only a tentative definition. For example, this is valid:
** int i;
** int i;
** static int j;
** static int j = 42;
** Code for these will be generated in FinishCompile.
*/
}
}
@ -303,7 +306,7 @@ void Compile (const char* FileName)
struct tm* TM;
/* Since strftime is locale dependent, we need the abbreviated month names
** in english.
** in English.
*/
static const char MonthNames[12][4] = {
"Jan", "Feb", "Mar", "Apr", "May", "Jun",
@ -400,20 +403,26 @@ void Compile (const char* FileName)
void FinishCompile (void)
/* Emit literals, externals, debug info, do cleanup and optimizations */
{
SymTable* SymTab;
SymEntry* Func;
SymEntry* Entry;
/* Walk over all functions, doing cleanup, optimizations ... */
SymTab = GetGlobalSymTab ();
Func = SymTab->SymHead;
while (Func) {
if (SymIsOutputFunc (Func)) {
/* Walk over all global symbols:
** - for functions do cleanup, optimizations ...
** - generate code for uninitialized global variables
*/
for (Entry = GetGlobalSymTab ()->SymHead; Entry; Entry = Entry->NextSym) {
if (SymIsOutputFunc (Entry)) {
/* Function which is defined and referenced or extern */
MoveLiteralPool (Func->V.F.LitPool);
CS_MergeLabels (Func->V.F.Seg->Code);
RunOpt (Func->V.F.Seg->Code);
MoveLiteralPool (Entry->V.F.LitPool);
CS_MergeLabels (Entry->V.F.Seg->Code);
RunOpt (Entry->V.F.Seg->Code);
} else if ((Entry->Flags & (SC_STORAGE | SC_DEF | SC_STATIC)) == (SC_STORAGE | SC_STATIC)) {
/* Tentative definition of uninitialized global variable */
g_usebss ();
g_defgloblabel (Entry->Name);
g_res (SizeOf (Entry->Type));
/* Mark as defined, so that it will be exported not imported */
Entry->Flags |= SC_DEF;
}
Func = Func->NextSym;
}
/* Output the literal pool */

View File

@ -821,7 +821,7 @@ SymEntry* AddGlobalSym (const char* Name, const Type* T, unsigned Flags)
}
/* An extern declaration must not change the current linkage. */
if (IsFunc || (Flags & (SC_EXTERN | SC_DEF)) == SC_EXTERN) {
if (IsFunc || (Flags & (SC_EXTERN | SC_STORAGE)) == SC_EXTERN) {
Flags &= ~SC_EXTERN;
}

View File

@ -0,0 +1,18 @@
/*
!!DESCRIPTION!! global duplicated with static variable
!!ORIGIN!! cc65 regression tests
!!LICENCE!! Public Domain
!!AUTHOR!! Piotr Fusik
*/
/*
see: https://github.com/cc65/cc65/issues/191
*/
int n = 0;
static int n = 0; /* should give an error */
int main(void)
{
return n;
}

View File

@ -0,0 +1,20 @@
/*
!!DESCRIPTION!! duplicate globals
!!ORIGIN!! cc65 regression tests
!!LICENCE!! Public Domain
!!AUTHOR!! Piotr Fusik
*/
/*
see: https://github.com/cc65/cc65/issues/191
*/
#pragma warn(error, on)
int n = 0;
int n = 0; /* should give an error */
int main(void)
{
return n;
}

View File

@ -0,0 +1,18 @@
/*
!!DESCRIPTION!! static duplicated with global variable
!!ORIGIN!! cc65 regression tests
!!LICENCE!! Public Domain
!!AUTHOR!! Piotr Fusik
*/
/*
see: https://github.com/cc65/cc65/issues/191
*/
static int n = 0;
int n = 0; /* should give an error */
int main(void)
{
return n;
}

View File

@ -0,0 +1,20 @@
/*
!!DESCRIPTION!! duplicate static variables
!!ORIGIN!! cc65 regression tests
!!LICENCE!! Public Domain
!!AUTHOR!! Piotr Fusik
*/
/*
see: https://github.com/cc65/cc65/issues/191
*/
#pragma warn(error, on)
static int n = 0;
static int n = 0; /* should give an error */
int main(void)
{
return n;
}

View File

@ -0,0 +1,35 @@
/*
!!DESCRIPTION!! static forward declarations
!!ORIGIN!! cc65 regression tests
!!LICENCE!! Public Domain
!!AUTHOR!! Bob Andrews
*/
/*
see: https://github.com/cc65/cc65/issues/204
*/
#pragma warn(error, on)
typedef struct _DIRMENU
{
const char *name;
struct _DIRMENU *dest;
} DIRMENU;
static DIRMENU rmenu;
static DIRMENU lmenu = {
"left",
&rmenu
};
static DIRMENU rmenu = {
"right",
&lmenu
};
int main(void)
{
return lmenu.dest == &rmenu && rmenu.dest == &lmenu ? 0 : 1;
}