Alternative fix for Issue #1167.

This commit is contained in:
acqn
2020-08-15 09:10:17 +08:00
committed by Oliver Schmidt
parent 0afa1a9a95
commit f206833a20
9 changed files with 19 additions and 64 deletions

View File

@@ -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

View File

@@ -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);
} }
} }

View File

@@ -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).

View File

@@ -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).

View File

@@ -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);

View File

@@ -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. */

View File

@@ -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 {

View File

@@ -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;

View File

@@ -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;
} }