From b4326d1930068c6361d2edee4de0f38200147c03 Mon Sep 17 00:00:00 2001 From: cuz Date: Wed, 2 Oct 2002 13:00:04 +0000 Subject: [PATCH] Place all declarations that are local to a function into the local function scope. Apart from some other advantages, this works around a bug where having an external identifier in global scope and using an "extern" declaration for exactly the same identifier in a function did not work, because the assembler refused to export and import one and the same identifier. Since the import now imports into local scope, both identifiers are distinct for the assembler and the (valid) C code works. git-svn-id: svn://svn.cc65.org/cc65/trunk@1424 b7a2c559-68d2-44c3-8de9-860c34a00d81 --- src/cc65/codeseg.c | 70 +++++++++++++++++++++++++++++++++++++-------- src/cc65/codeseg.h | 12 ++++++++ src/cc65/segments.c | 24 ++++------------ 3 files changed, 75 insertions(+), 31 deletions(-) diff --git a/src/cc65/codeseg.c b/src/cc65/codeseg.c index 99497da07..d52b36fcd 100644 --- a/src/cc65/codeseg.c +++ b/src/cc65/codeseg.c @@ -62,6 +62,27 @@ +static void CS_PrintFunctionHeader (const CodeSeg* S, FILE* F) +/* Print a comment with the function signature to the given file */ +{ + /* Get the associated function */ + const SymEntry* Func = S->Func; + + /* If this is a global code segment, do nothing */ + if (Func) { + fprintf (F, + "; ---------------------------------------------------------------\n" + "; "); + PrintFuncSig (F, Func->Name, Func->Type); + fprintf (F, + "\n" + "; ---------------------------------------------------------------\n" + "\n"); + } +} + + + static void CS_MoveLabelsToEntry (CodeSeg* S, CodeEntry* E) /* Move all labels from the label pool to the given entry and remove them * from the pool. @@ -748,7 +769,7 @@ int CS_RangeHasLabel (CodeSeg* S, unsigned Start, unsigned Count) return 1; } } - + /* No label in the complete range */ return 0; } @@ -859,7 +880,7 @@ void CS_MergeLabels (CodeSeg* S) CodeEntry* E = CL_GetRef (X, J); /* And remove the reference */ E->JumpTo = 0; - } + } /* Print some debugging output */ if (Debug) { @@ -1072,6 +1093,41 @@ void CS_DelCodeAfter (CodeSeg* S, unsigned Last) +void CS_OutputPrologue (const CodeSeg* S, FILE* F) +/* If the given code segment is a code segment for a function, output the + * assembler prologue into the file. That is: Output a comment header, switch + * to the correct segment and enter the local function scope. If the code + * segment is global, do nothing. + */ +{ + /* Get the function associated with the code segment */ + SymEntry* Func = S->Func; + + /* If the code segment is associated with a function, print a function + * header and enter a local scope. Be sure to switch to the correct + * segment before outputing the function label. + */ + if (Func) { + CS_PrintFunctionHeader (S, F); + fprintf (F, ".segment\t\"%s\"\n\n.proc\t_%s\n\n", S->SegName, Func->Name); + } + +} + + + +void CS_OutputEpilogue (const CodeSeg* S, FILE* F) +/* If the given code segment is a code segment for a function, output the + * assembler epilogue into the file. That is: Close the local function scope. + */ +{ + if (S->Func) { + fprintf (F, "\n.endproc\n\n"); + } +} + + + void CS_Output (const CodeSeg* S, FILE* F) /* Output the code segment data to a file */ { @@ -1089,11 +1145,6 @@ void CS_Output (const CodeSeg* S, FILE* F) /* Output the segment directive */ fprintf (F, ".segment\t\"%s\"\n\n", S->SegName); - /* If this is a segment for a function, enter a function */ - if (S->Func) { - fprintf (F, ".proc\t_%s\n\n", S->Func->Name); - } - /* Output all entries, prepended by the line information if it has changed */ LI = 0; for (I = 0; I < Count; ++I) { @@ -1126,11 +1177,6 @@ void CS_Output (const CodeSeg* S, FILE* F) if (DebugInfo) { fprintf (F, "\t.dbg\tline\n"); } - - /* If this is a segment for a function, leave the function */ - if (S->Func) { - fprintf (F, "\n.endproc\n\n"); - } } diff --git a/src/cc65/codeseg.h b/src/cc65/codeseg.h index fc61ab25e..67de3efba 100644 --- a/src/cc65/codeseg.h +++ b/src/cc65/codeseg.h @@ -216,6 +216,18 @@ void CS_MoveLabelRef (CodeSeg* S, struct CodeEntry* E, CodeLabel* L); void CS_DelCodeAfter (CodeSeg* S, unsigned Last); /* Delete all entries including the given one */ +void CS_OutputPrologue (const CodeSeg* S, FILE* F); +/* If the given code segment is a code segment for a function, output the + * assembler prologue into the file. That is: Output a comment header, switch + * to the correct segment and enter the local function scope. If the code + * segment is global, do nothing. + */ + +void CS_OutputEpilogue (const CodeSeg* S, FILE* F); +/* If the given code segment is a code segment for a function, output the + * assembler epilogue into the file. That is: Close the local function scope. + */ + void CS_Output (const CodeSeg* S, FILE* F); /* Output the code segment data to a file */ diff --git a/src/cc65/segments.c b/src/cc65/segments.c index b4f5ee88b..77b787ca8 100644 --- a/src/cc65/segments.c +++ b/src/cc65/segments.c @@ -244,28 +244,11 @@ void AddDataLine (const char* Format, ...) -static void PrintFunctionHeader (const SymEntry* Entry, FILE* F) -{ - /* Print a comment with the function signature */ - fprintf (F, - "; ---------------------------------------------------------------\n" - "; "); - PrintFuncSig (F, Entry->Name, Entry->Type); - fprintf (F, - "\n" - "; ---------------------------------------------------------------\n" - "\n"); -} - - - void OutputSegments (const Segments* S, FILE* F) /* Output the given segments to the file */ { - /* If the code segment is associated with a function, print a function header */ - if (S->Code->Func) { - PrintFunctionHeader (S->Code->Func, F); - } + /* Output the function prologue if the segments came from a function */ + CS_OutputPrologue (S->Code, F); /* Output the text segment */ TS_Output (S->Text, F); @@ -277,6 +260,9 @@ void OutputSegments (const Segments* S, FILE* F) /* Output the code segment */ CS_Output (S->Code, F); + + /* Output the code segment epiloque */ + CS_OutputEpilogue (S->Code, F); }