Alternative fix for Issue #1167.
This commit is contained in:
@@ -392,7 +392,7 @@ fncls_t GetFuncInfo (const char* Name, unsigned short* Use, unsigned short* Chg)
|
|||||||
|
|
||||||
/* Did we find it in the top-level table? */
|
/* Did we find it in the top-level table? */
|
||||||
if (E && IsTypeFunc (E->Type)) {
|
if (E && IsTypeFunc (E->Type)) {
|
||||||
FuncDesc* D = GetFuncCompositeDesc (E);
|
FuncDesc* D = GetFuncDesc (E->Type);
|
||||||
|
|
||||||
/* A variadic function will use the Y register (the parameter list
|
/* A variadic function will use the Y register (the parameter list
|
||||||
** size is passed there). A fastcall function will use the A or A/X
|
** size is passed there). A fastcall function will use the A or A/X
|
||||||
|
|||||||
@@ -77,6 +77,7 @@ static void Parse (void)
|
|||||||
{
|
{
|
||||||
int comma;
|
int comma;
|
||||||
SymEntry* Entry;
|
SymEntry* Entry;
|
||||||
|
FuncDesc* FuncDef = 0;
|
||||||
|
|
||||||
/* Go... */
|
/* Go... */
|
||||||
NextToken ();
|
NextToken ();
|
||||||
@@ -187,9 +188,9 @@ static void Parse (void)
|
|||||||
/* Convert an empty parameter list into one accepting no
|
/* Convert an empty parameter list into one accepting no
|
||||||
** parameters (same as void) as required by the standard.
|
** parameters (same as void) as required by the standard.
|
||||||
*/
|
*/
|
||||||
FuncDesc* D = GetFuncDesc (Decl.Type);
|
FuncDef = GetFuncDesc (Decl.Type);
|
||||||
if (D->Flags & FD_EMPTY) {
|
if (FuncDef->Flags & FD_EMPTY) {
|
||||||
D->Flags = (D->Flags & ~FD_EMPTY) | FD_VOID_PARAM;
|
FuncDef->Flags = (FuncDef->Flags & ~FD_EMPTY) | FD_VOID_PARAM;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
/* Just a declaration */
|
/* Just a declaration */
|
||||||
@@ -315,7 +316,7 @@ SkipOneDecl:
|
|||||||
NextToken ();
|
NextToken ();
|
||||||
} else {
|
} else {
|
||||||
/* Parse the function body */
|
/* Parse the function body */
|
||||||
NewFunc (Entry);
|
NewFunc (Entry, FuncDef);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1140,28 +1140,6 @@ Type* GetFuncReturn (Type* T)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
Type* GetFuncCompositeType (SymEntry* Func)
|
|
||||||
/* Get the composite function type */
|
|
||||||
{
|
|
||||||
/* Be sure it's a function type */
|
|
||||||
CHECK (IsClassFunc (Func->Type));
|
|
||||||
|
|
||||||
return Func->V.F.Composite->Type;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
FuncDesc* GetFuncCompositeDesc (SymEntry* Func)
|
|
||||||
/* Get the composite function type descriptor */
|
|
||||||
{
|
|
||||||
/* Be sure it's a function type */
|
|
||||||
CHECK (IsClassFunc (Func->Type));
|
|
||||||
|
|
||||||
return GetFuncDesc (Func->V.F.Composite->Type);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
long GetElementCount (const Type* T)
|
long GetElementCount (const Type* T)
|
||||||
/* Get the element count of the array specified in T (which must be of
|
/* Get the element count of the array specified in T (which must be of
|
||||||
** array type).
|
** array type).
|
||||||
|
|||||||
@@ -816,12 +816,6 @@ void SetFuncDesc (Type* T, FuncDesc* F);
|
|||||||
Type* GetFuncReturn (Type* T) attribute ((const));
|
Type* GetFuncReturn (Type* T) attribute ((const));
|
||||||
/* Return a pointer to the return type of a function or pointer-to-function type */
|
/* Return a pointer to the return type of a function or pointer-to-function type */
|
||||||
|
|
||||||
Type* GetFuncCompositeType (struct SymEntry* Func);
|
|
||||||
/* Get the composite function type */
|
|
||||||
|
|
||||||
FuncDesc* GetFuncCompositeDesc (struct SymEntry* Func);
|
|
||||||
/* Get the composite function type descriptor */
|
|
||||||
|
|
||||||
long GetElementCount (const Type* T);
|
long GetElementCount (const Type* T);
|
||||||
/* Get the element count of the array specified in T (which must be of
|
/* Get the element count of the array specified in T (which must be of
|
||||||
** array type).
|
** array type).
|
||||||
|
|||||||
@@ -72,7 +72,7 @@ Function* CurrentFunc = 0;
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
static Function* NewFunction (struct SymEntry* Sym)
|
static Function* NewFunction (struct SymEntry* Sym, FuncDesc* D)
|
||||||
/* Create a new function activation structure and return it */
|
/* Create a new function activation structure and return it */
|
||||||
{
|
{
|
||||||
/* Allocate a new structure */
|
/* Allocate a new structure */
|
||||||
@@ -81,7 +81,7 @@ static Function* NewFunction (struct SymEntry* Sym)
|
|||||||
/* Initialize the fields */
|
/* Initialize the fields */
|
||||||
F->FuncEntry = Sym;
|
F->FuncEntry = Sym;
|
||||||
F->ReturnType = GetFuncReturn (Sym->Type);
|
F->ReturnType = GetFuncReturn (Sym->Type);
|
||||||
F->Desc = GetFuncDesc (Sym->Type);
|
F->Desc = D;
|
||||||
F->Reserved = 0;
|
F->Reserved = 0;
|
||||||
F->RetLab = GetLocalLabel ();
|
F->RetLab = GetLocalLabel ();
|
||||||
F->TopLevelSP = 0;
|
F->TopLevelSP = 0;
|
||||||
@@ -295,7 +295,7 @@ static void F_RestoreRegVars (Function* F)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Get the first symbol from the function symbol table */
|
/* Get the first symbol from the function symbol table */
|
||||||
Sym = GetFuncDesc (F->FuncEntry->Type)->SymTab->SymHead;
|
Sym = F->Desc->SymTab->SymHead;
|
||||||
|
|
||||||
/* Walk through all symbols checking for register variables */
|
/* Walk through all symbols checking for register variables */
|
||||||
while (Sym) {
|
while (Sym) {
|
||||||
@@ -375,18 +375,15 @@ static void F_EmitDebugInfo (void)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
void NewFunc (SymEntry* Func)
|
void NewFunc (SymEntry* Func, FuncDesc* D)
|
||||||
/* Parse argument declarations and function body. */
|
/* Parse argument declarations and function body. */
|
||||||
{
|
{
|
||||||
int C99MainFunc = 0;/* Flag for C99 main function returning int */
|
int C99MainFunc = 0;/* Flag for C99 main function returning int */
|
||||||
SymEntry* Param;
|
SymEntry* Param;
|
||||||
const Type* RType; /* Real type used for struct parameters */
|
const Type* RType; /* Real type used for struct parameters */
|
||||||
|
|
||||||
/* Get the function descriptor from the function entry */
|
|
||||||
FuncDesc* D = GetFuncDesc (Func->Type);
|
|
||||||
|
|
||||||
/* Allocate the function activation record for the function */
|
/* Allocate the function activation record for the function */
|
||||||
CurrentFunc = NewFunction (Func);
|
CurrentFunc = NewFunction (Func, D);
|
||||||
|
|
||||||
/* Reenter the lexical level */
|
/* Reenter the lexical level */
|
||||||
ReenterFunctionLevel (D);
|
ReenterFunctionLevel (D);
|
||||||
|
|||||||
@@ -67,6 +67,9 @@ struct Function {
|
|||||||
/* Structure that holds all data needed for function activation */
|
/* Structure that holds all data needed for function activation */
|
||||||
typedef struct Function Function;
|
typedef struct Function Function;
|
||||||
|
|
||||||
|
/* Forward declaration */
|
||||||
|
struct FuncDesc;
|
||||||
|
|
||||||
/* Function activation data for current function (or NULL) */
|
/* Function activation data for current function (or NULL) */
|
||||||
extern Function* CurrentFunc;
|
extern Function* CurrentFunc;
|
||||||
|
|
||||||
@@ -138,7 +141,7 @@ int F_AllocRegVar (Function* F, const Type* Type);
|
|||||||
** bank (zero page storage). If there is no register space left, return -1.
|
** bank (zero page storage). If there is no register space left, return -1.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void NewFunc (struct SymEntry* Func);
|
void NewFunc (struct SymEntry* Func, struct FuncDesc* D);
|
||||||
/* Parse argument declarations and function body. */
|
/* Parse argument declarations and function body. */
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -527,7 +527,7 @@ static void WrappedCallPragma (StrBuf* B)
|
|||||||
|
|
||||||
PushWrappedCall(Entry, (unsigned char) Val);
|
PushWrappedCall(Entry, (unsigned char) Val);
|
||||||
Entry->Flags |= SC_REF;
|
Entry->Flags |= SC_REF;
|
||||||
GetFuncCompositeDesc (Entry)->Flags |= FD_CALL_WRAPPER;
|
GetFuncDesc (Entry->Type)->Flags |= FD_CALL_WRAPPER;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
|
|||||||
@@ -191,7 +191,6 @@ struct SymEntry {
|
|||||||
|
|
||||||
/* Data for functions */
|
/* Data for functions */
|
||||||
struct {
|
struct {
|
||||||
SymEntry* Composite;/* Entry to hold composite function type */
|
|
||||||
struct Segments* Seg; /* Segments for this function */
|
struct Segments* Seg; /* Segments for this function */
|
||||||
struct LiteralPool* LitPool; /* Literal pool for this function */
|
struct LiteralPool* LitPool; /* Literal pool for this function */
|
||||||
} F;
|
} F;
|
||||||
|
|||||||
@@ -590,14 +590,14 @@ static int HandleSymRedefinition (SymEntry* Entry, const Type* T, unsigned Flags
|
|||||||
Entry = 0;
|
Entry = 0;
|
||||||
} else {
|
} else {
|
||||||
/* New type must be compatible with the composite prototype */
|
/* New type must be compatible with the composite prototype */
|
||||||
if (TypeCmp (GetFuncCompositeType (Entry), T) < TC_EQUAL) {
|
if (TypeCmp (Entry->Type, T) < TC_EQUAL) {
|
||||||
Error ("Conflicting function types for '%s'", Entry->Name);
|
Error ("Conflicting function types for '%s'", Entry->Name);
|
||||||
Entry = 0;
|
Entry = 0;
|
||||||
} else {
|
} else {
|
||||||
/* Refine the existing composite prototype with this new
|
/* Refine the existing composite prototype with this new
|
||||||
** one.
|
** one.
|
||||||
*/
|
*/
|
||||||
RefineFuncDesc (GetFuncCompositeType (Entry), T);
|
RefineFuncDesc (Entry->Type, T);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1165,14 +1165,6 @@ SymEntry* AddGlobalSym (const char* Name, const Type* T, unsigned Flags)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (Entry) {
|
if (Entry) {
|
||||||
/* Update existing function type if this is a definition */
|
|
||||||
if (IsTypeFunc (Entry->Type) &&
|
|
||||||
!SymIsDef (Entry) &&
|
|
||||||
(Flags & SC_DEF) == SC_DEF) {
|
|
||||||
TypeFree (Entry->Type);
|
|
||||||
Entry->Type = TypeDup (T);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Add the new flags */
|
/* Add the new flags */
|
||||||
Entry->Flags |= Flags;
|
Entry->Flags |= Flags;
|
||||||
}
|
}
|
||||||
@@ -1192,17 +1184,8 @@ SymEntry* AddGlobalSym (const char* Name, const Type* T, unsigned Flags)
|
|||||||
/* Set the symbol attributes */
|
/* Set the symbol attributes */
|
||||||
Entry->Type = TypeDup (T);
|
Entry->Type = TypeDup (T);
|
||||||
|
|
||||||
/* If this is a function, set the function composite typeand clear
|
/* If this is a function, clear additional fields */
|
||||||
** additional fields.
|
|
||||||
*/
|
|
||||||
if (IsTypeFunc (T)) {
|
if (IsTypeFunc (T)) {
|
||||||
/* GitHub #1167 - Make a composite prototype */
|
|
||||||
ident Ident;
|
|
||||||
AnonName (Ident, "prototype");
|
|
||||||
Entry->V.F.Composite = NewSymEntry (Ident, SC_EXTERN | SC_DECL | SC_ALIAS | SC_FUNC);
|
|
||||||
Entry->V.F.Composite->Type = TypeDup (T);
|
|
||||||
AddSymEntry (SymTab0, Entry->V.F.Composite);
|
|
||||||
|
|
||||||
Entry->V.F.Seg = 0;
|
Entry->V.F.Seg = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user