diff --git a/doc/cc65.sgml b/doc/cc65.sgml
index 37e3e493d..efe48b61b 100644
--- a/doc/cc65.sgml
+++ b/doc/cc65.sgml
@@ -1613,13 +1613,13 @@ parameter with the function will be used
to determine the number from the bank attribute defined in the linker config,
see . Note that
@@ -1629,6 +1629,11 @@ parameter with the WrappedCall = WrappedCall;
- F->WrappedCallData = WrappedCallData;
- }
-
/* Return the function descriptor */
return F;
}
@@ -2099,7 +2088,6 @@ static void DirectDecl (DeclSpec* Spec, Declarator* D, declmode_t Mode)
/* Function declarator */
FuncDesc* F;
- SymEntry* PrevEntry;
/* Parse the function declarator */
F = ParseFuncDecl ();
@@ -2110,16 +2098,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;
diff --git a/src/cc65/expr.c b/src/cc65/expr.c
index 963ea8bd6..af39a79f9 100644
--- a/src/cc65/expr.c
+++ b/src/cc65/expr.c
@@ -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;
diff --git a/src/cc65/funcdesc.c b/src/cc65/funcdesc.c
index 2291b35ee..de881167d 100644
--- a/src/cc65/funcdesc.c
+++ b/src/cc65/funcdesc.c
@@ -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;
diff --git a/src/cc65/funcdesc.h b/src/cc65/funcdesc.h
index e065c7602..8d21d3080 100644
--- a/src/cc65/funcdesc.h
+++ b/src/cc65/funcdesc.h
@@ -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 */
};
diff --git a/src/cc65/symentry.h b/src/cc65/symentry.h
index 715c036d6..639221625 100644
--- a/src/cc65/symentry.h
+++ b/src/cc65/symentry.h
@@ -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 */
diff --git a/src/cc65/symtab.c b/src/cc65/symtab.c
index 1b5c1e0b5..3018c910d 100644
--- a/src/cc65/symtab.c
+++ b/src/cc65/symtab.c
@@ -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 */
diff --git a/test/val/trampoline.c b/test/val/trampoline.c
index 8f1e1547c..d3e73b47d 100644
--- a/test/val/trampoline.c
+++ b/test/val/trampoline.c
@@ -22,23 +22,23 @@ void func3() {
}
-#pragma wrapped-call(push, trampoline_inc, 0)
-
void func2() {
func3();
}
+#pragma wrapped-call(push, trampoline_inc, 0)
+
+void func2(void);
+
#pragma wrapped-call(push, trampoline_set, 4)
-void func1(void);
-
-#pragma wrapped-call(pop)
-#pragma wrapped-call(pop)
-
void func1(void) {
func2();
}
+#pragma wrapped-call(pop)
+#pragma wrapped-call(pop)
+
int main(void)
{
flag = 0;