mirror of
https://github.com/cc65/cc65.git
synced 2024-12-30 20:29:25 +00:00
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
This commit is contained in:
parent
980c17daef
commit
b4326d1930
@ -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)
|
static void CS_MoveLabelsToEntry (CodeSeg* S, CodeEntry* E)
|
||||||
/* Move all labels from the label pool to the given entry and remove them
|
/* Move all labels from the label pool to the given entry and remove them
|
||||||
* from the pool.
|
* from the pool.
|
||||||
@ -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)
|
void CS_Output (const CodeSeg* S, FILE* F)
|
||||||
/* Output the code segment data to a file */
|
/* Output the code segment data to a file */
|
||||||
{
|
{
|
||||||
@ -1089,11 +1145,6 @@ void CS_Output (const CodeSeg* S, FILE* F)
|
|||||||
/* Output the segment directive */
|
/* Output the segment directive */
|
||||||
fprintf (F, ".segment\t\"%s\"\n\n", S->SegName);
|
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 */
|
/* Output all entries, prepended by the line information if it has changed */
|
||||||
LI = 0;
|
LI = 0;
|
||||||
for (I = 0; I < Count; ++I) {
|
for (I = 0; I < Count; ++I) {
|
||||||
@ -1126,11 +1177,6 @@ void CS_Output (const CodeSeg* S, FILE* F)
|
|||||||
if (DebugInfo) {
|
if (DebugInfo) {
|
||||||
fprintf (F, "\t.dbg\tline\n");
|
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");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -216,6 +216,18 @@ void CS_MoveLabelRef (CodeSeg* S, struct CodeEntry* E, CodeLabel* L);
|
|||||||
void CS_DelCodeAfter (CodeSeg* S, unsigned Last);
|
void CS_DelCodeAfter (CodeSeg* S, unsigned Last);
|
||||||
/* Delete all entries including the given one */
|
/* 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);
|
void CS_Output (const CodeSeg* S, FILE* F);
|
||||||
/* Output the code segment data to a file */
|
/* Output the code segment data to a file */
|
||||||
|
|
||||||
|
@ -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)
|
void OutputSegments (const Segments* S, FILE* F)
|
||||||
/* Output the given segments to the file */
|
/* Output the given segments to the file */
|
||||||
{
|
{
|
||||||
/* If the code segment is associated with a function, print a function header */
|
/* Output the function prologue if the segments came from a function */
|
||||||
if (S->Code->Func) {
|
CS_OutputPrologue (S->Code, F);
|
||||||
PrintFunctionHeader (S->Code->Func, F);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Output the text segment */
|
/* Output the text segment */
|
||||||
TS_Output (S->Text, F);
|
TS_Output (S->Text, F);
|
||||||
@ -277,6 +260,9 @@ void OutputSegments (const Segments* S, FILE* F)
|
|||||||
|
|
||||||
/* Output the code segment */
|
/* Output the code segment */
|
||||||
CS_Output (S->Code, F);
|
CS_Output (S->Code, F);
|
||||||
|
|
||||||
|
/* Output the code segment epiloque */
|
||||||
|
CS_OutputEpilogue (S->Code, F);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user