Merge pull request #2297 from acqn/WrappedCall

[cc65] Fixed wrapped call when the function was defined before its later declaration gets wrapped with the pragma
This commit is contained in:
Bob Andrews
2023-12-12 17:11:47 +01:00
committed by GitHub
8 changed files with 34 additions and 50 deletions

View File

@@ -61,7 +61,6 @@
#include "standard.h"
#include "staticassert.h"
#include "symtab.h"
#include "wrappedcall.h"
#include "typeconv.h"
@@ -1965,9 +1964,6 @@ static void ParseAnsiParamList (FuncDesc* F)
static FuncDesc* ParseFuncDecl (void)
/* Parse the argument list of a function with the enclosing parentheses */
{
SymEntry* WrappedCall;
unsigned int WrappedCallData;
/* Create a new function descriptor */
FuncDesc* F = NewFuncDesc ();
@@ -2023,13 +2019,6 @@ static FuncDesc* ParseFuncDecl (void)
/* Leave the lexical level remembering the symbol tables */
RememberFunctionLevel (F);
/* Did we have a WrappedCall for this function? */
GetWrappedCall((void **) &WrappedCall, &WrappedCallData);
if (WrappedCall) {
F->WrappedCall = WrappedCall;
F->WrappedCallData = WrappedCallData;
}
/* Return the function descriptor */
return F;
}
@@ -2102,7 +2091,6 @@ static void DirectDecl (DeclSpec* Spec, Declarator* D, declmode_t Mode)
/* Function declarator */
FuncDesc* F;
SymEntry* PrevEntry;
/* Parse the function declarator */
F = ParseFuncDecl ();
@@ -2113,16 +2101,6 @@ static void DirectDecl (DeclSpec* Spec, Declarator* D, declmode_t Mode)
Qualifiers &= ~T_QUAL_FASTCALL;
}
/* Was there a previous entry? If so, copy WrappedCall info from it */
PrevEntry = FindGlobalSym (D->Ident);
if (PrevEntry && PrevEntry->Flags & SC_FUNC) {
FuncDesc* D = GetFuncDesc (PrevEntry->Type);
if (D->WrappedCall && !F->WrappedCall) {
F->WrappedCall = D->WrappedCall;
F->WrappedCallData = D->WrappedCallData;
}
}
/* Add the function type. Be sure to bounds check the type buffer */
NeedTypeSpace (D, 1);
D->Type[D->Index].C = T_FUNC | Qualifiers;

View File

@@ -1057,11 +1057,6 @@ static void FunctionCall (ExprDesc* Expr)
/* Special handling for function pointers */
if (IsFuncPtr) {
if (Func->WrappedCall) {
Warning ("Calling a wrapped function via a pointer, wrapped-call will not be used");
}
/* If the function is not a fastcall function, load the pointer to
** the function into the primary.
*/
@@ -1110,18 +1105,18 @@ static void FunctionCall (ExprDesc* Expr)
} else {
/* Normal function */
if (Func->WrappedCall) {
if (Expr->Sym && Expr->Sym->V.F.WrappedCall) {
char tmp[64];
StrBuf S = AUTO_STRBUF_INITIALIZER;
if (Func->WrappedCallData == WRAPPED_CALL_USE_BANK) {
if (Expr->Sym->V.F.WrappedCallData == WRAPPED_CALL_USE_BANK) {
/* Store the bank attribute in tmp4 */
SB_AppendStr (&S, "ldy #<.bank(_");
SB_AppendStr (&S, (const char*) Expr->Name);
SB_AppendChar (&S, ')');
} else {
/* Store the WrappedCall data in tmp4 */
sprintf(tmp, "ldy #%u", Func->WrappedCallData);
sprintf(tmp, "ldy #%u", Expr->Sym->V.F.WrappedCallData);
SB_AppendStr (&S, tmp);
}
g_asmcode (&S);
@@ -1154,7 +1149,7 @@ static void FunctionCall (ExprDesc* Expr)
SB_Done (&S);
g_call (CG_CallFlags (Expr->Type), Func->WrappedCall->Name, ArgSize);
g_call (CG_CallFlags (Expr->Type), Expr->Sym->V.F.WrappedCall->Name, ArgSize);
} else {
g_call (CG_CallFlags (Expr->Type), (const char*) Expr->Name, ArgSize);
}
@@ -1328,6 +1323,7 @@ static void Primary (ExprDesc* E)
E->Type = type_int;
}
E->Sym = Sym;
}
break;

View File

@@ -61,8 +61,6 @@ FuncDesc* NewFuncDesc (void)
F->ParamSize = 0;
F->LastParam = 0;
F->FuncDef = 0;
F->WrappedCall = 0;
F->WrappedCallData = 0;
/* Return the new struct */
return F;

View File

@@ -70,8 +70,6 @@ struct FuncDesc {
unsigned ParamSize; /* Size of the parameters */
struct SymEntry* LastParam; /* Pointer to last parameter */
struct FuncDesc* FuncDef; /* Descriptor used in definition */
struct SymEntry* WrappedCall; /* Pointer to the WrappedCall */
unsigned int WrappedCallData; /* The WrappedCall's user data */
};

View File

@@ -159,6 +159,8 @@ struct SymEntry {
struct {
struct SegContext* Seg; /* SegContext for this function */
struct LiteralPool* LitPool; /* Literal pool for this function */
struct SymEntry* WrappedCall; /* Pointer to the WrappedCall */
unsigned int WrappedCallData; /* The WrappedCall's user data */
} F;
/* Label name for static symbols */

View File

@@ -61,6 +61,7 @@
#include "symentry.h"
#include "typecmp.h"
#include "typeconv.h"
#include "wrappedcall.h"
#include "symtab.h"
@@ -1407,24 +1408,30 @@ SymEntry* AddGlobalSym (const char* Name, const Type* T, unsigned Flags)
}
if (Entry == 0) {
/* Create a new entry */
Entry = NewSymEntry (Name, Flags);
/* Set the symbol attributes */
Entry->Type = TypeDup (T);
/* If this is a function, clear additional fields */
if (IsTypeFunc (T)) {
Entry->V.F.Seg = 0;
}
/* Add the assembler name of the symbol */
SymSetAsmName (Entry);
/* Add the entry to the symbol table */
AddSymEntry (Tab, Entry);
}
/* If this is a function, do we wrap calls to it? */
if (IsTypeFunc (Entry->Type)) {
SymEntry* WrappedCall;
unsigned int WrappedCallData;
/* Always use the latest wrapper data for it */
GetWrappedCall ((void**)&WrappedCall, &WrappedCallData);
if (WrappedCall) {
Entry->V.F.WrappedCall = WrappedCall;
Entry->V.F.WrappedCallData = WrappedCallData;
}
}
/* Add an alias of the global symbol to the local symbol table */