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:
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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 */
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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 */
|
||||
|
||||
Reference in New Issue
Block a user