1
0
mirror of https://github.com/cc65/cc65.git synced 2024-08-28 18:29:20 +00:00

Merge pull request #454 from greg-king5/dup-segment

Stop cc65 from putting redundant .segment directives into its output file.
This commit is contained in:
Oliver Schmidt 2017-06-17 11:25:10 +02:00 committed by GitHub
commit 8fcb5139da
2 changed files with 31 additions and 14 deletions

View File

@ -243,19 +243,20 @@ static void Parse (void)
} }
Entry->Flags &= ~(SC_STORAGE | SC_DEF); Entry->Flags &= ~(SC_STORAGE | SC_DEF);
} else { } else {
/* A global (including static) uninitialized variable /* A global (including static) uninitialized variable is
** is only a tentative definition. For example, this is valid: ** only a tentative definition. For example, this is valid:
** int i; ** int i;
** int i; ** int i;
** static int j; ** static int j;
** static int j = 42; ** static int j = 42;
** Code for these will be generated in FinishCompile. ** Code for them will be generated by FinishCompile().
** For now, just save the BSS segment name ** For now, just save the BSS segment name
** (can be set with #pragma bss-name) ** (can be set by #pragma bss-name).
*/ */
const char* bssName = GetSegName (SEG_BSS); const char* bssName = GetSegName (SEG_BSS);
if (Entry->V.BssName && strcmp (Entry->V.BssName, bssName) != 0) { if (Entry->V.BssName && strcmp (Entry->V.BssName, bssName) != 0) {
Error ("Global variable `%s' has already been defined in `%s' segment", Error ("Global variable `%s' already was defined in the `%s' segment.",
Entry->Name, Entry->V.BssName); Entry->Name, Entry->V.BssName);
} }
Entry->V.BssName = xstrdup (bssName); Entry->V.BssName = xstrdup (bssName);
@ -419,7 +420,7 @@ void FinishCompile (void)
SymEntry* Entry; SymEntry* Entry;
/* Walk over all global symbols: /* Walk over all global symbols:
** - for functions do cleanup, optimizations ... ** - for functions, do clean-up and optimizations
** - generate code for uninitialized global variables ** - generate code for uninitialized global variables
*/ */
for (Entry = GetGlobalSymTab ()->SymHead; Entry; Entry = Entry->NextSym) { for (Entry = GetGlobalSymTab ()->SymHead; Entry; Entry = Entry->NextSym) {
@ -429,13 +430,17 @@ void FinishCompile (void)
CS_MergeLabels (Entry->V.F.Seg->Code); CS_MergeLabels (Entry->V.F.Seg->Code);
RunOpt (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)) { } else if ((Entry->Flags & (SC_STORAGE | SC_DEF | SC_STATIC)) == (SC_STORAGE | SC_STATIC)) {
/* Tentative definition of uninitialized global variable */ /* Assembly definition of uninitialized global variable */
/* Set the segment name only when it changes */
if (strcmp (GetSegName (SEG_BSS), Entry->V.BssName) != 0) {
SetSegName (SEG_BSS, Entry->V.BssName);
g_segname (SEG_BSS);
}
g_usebss (); g_usebss ();
SetSegName (SEG_BSS, Entry->V.BssName);
g_segname (SEG_BSS); /* TODO: skip if same as before */
g_defgloblabel (Entry->Name); g_defgloblabel (Entry->Name);
g_res (SizeOf (Entry->Type)); g_res (SizeOf (Entry->Type));
/* Mark as defined, so that it will be exported not imported */ /* Mark as defined; so that it will be exported, not imported */
Entry->Flags |= SC_DEF; Entry->Flags |= SC_DEF;
} }
} }

View File

@ -386,11 +386,11 @@ static void StringPragma (StrBuf* B, void (*Func) (const char*))
static void SegNamePragma (StrBuf* B, segment_t Seg) static void SegNamePragma (StrBuf* B, segment_t Seg)
/* Handle a pragma that expects a segment name parameter */ /* Handle a pragma that expects a segment name parameter */
{ {
StrBuf S = AUTO_STRBUF_INITIALIZER;
const char* Name; const char* Name;
StrBuf S = AUTO_STRBUF_INITIALIZER;
int Push = 0;
/* Check for the "push" or "pop" keywords */ /* Check for the "push" or "pop" keywords */
int Push = 0;
switch (ParsePushPop (B)) { switch (ParsePushPop (B)) {
case PP_NONE: case PP_NONE:
@ -403,7 +403,13 @@ static void SegNamePragma (StrBuf* B, segment_t Seg)
case PP_POP: case PP_POP:
/* Pop the old value and output it */ /* Pop the old value and output it */
PopSegName (Seg); PopSegName (Seg);
g_segname (Seg);
/* BSS variables are output at the end of the compilation. Don't
** bother to change their segment, now.
*/
if (Seg != SEG_BSS) {
g_segname (Seg);
}
/* Done */ /* Done */
goto ExitPoint; goto ExitPoint;
@ -434,7 +440,13 @@ static void SegNamePragma (StrBuf* B, segment_t Seg)
} else { } else {
SetSegName (Seg, Name); SetSegName (Seg, Name);
} }
g_segname (Seg);
/* BSS variables are output at the end of the compilation. Don't
** bother to change their segment, now.
*/
if (Seg != SEG_BSS) {
g_segname (Seg);
}
} else { } else {