Fix issue where native functions returning an array would not compile

This commit is contained in:
Arkshine 2016-02-08 10:55:02 +01:00
parent 664c25bdac
commit 2c73268668
3 changed files with 40 additions and 13 deletions

View File

@ -127,7 +127,7 @@ typedef struct s_symbol {
cell codeaddr; /* address (in the code segment) where the symbol declaration starts */
char vclass; /* sLOCAL if "addr" refers to a local symbol */
char ident; /* see below for possible values */
char usage; /* see below for possible values */
short usage; /* see below for possible values */
char flags; /* see below for possible values */
int compound; /* compound level (braces nesting level) */
int tag; /* tagname id */
@ -217,6 +217,7 @@ typedef struct s_symbol {
#define uSTOCK 0x40
#define uENUMFIELD 0x40
#define uMISSING 0x80
#define uVISITED 0x100 /* temporary flag, to mark fields as "visited" in recursive loops */
/* uRETNONE is not stored in the "usage" field of a symbol. It is
* used during parsing a function, to detect a mix of "return;" and
* "return value;" in a few special cases.

View File

@ -3244,7 +3244,7 @@ static void funcstub(int native)
/* attach the array to the function symbol */
if (numdim>0) {
assert(sym!=NULL);
sub=addvariable(symbolname,0,iARRAY,sGLOBAL,tag,dim,numdim,idxtag);
sub=addvariable(symbolname,0,iREFARRAY,sGLOBAL,tag,dim,numdim,idxtag);
sub->parent=sym;
} /* if */

View File

@ -2599,17 +2599,22 @@ SC_FUNC int get_actual_compound(symbol *sym)
SC_FUNC void delete_symbols(symbol *root,int level,int delete_labels,int delete_functions)
{
symbol *origRoot=root;
symbol *sym,*parent_sym;
symbol *base;
symbol *sym,*parent_sym,*child_sym;
constvalue *stateptr;
int mustdelete=0;
/* erase only the symbols with a deeper nesting level than the
* specified nesting level */
while (root->next!=NULL) {
sym=root->next;
base=root;
while (base->next!=NULL) {
sym=base->next;
if (get_actual_compound(sym)<level)
break;
if ((sym->usage & uVISITED) != 0) {
base=sym; /* skip the symbol */
continue;
}
switch (sym->ident) {
case iLABEL:
mustdelete=delete_labels;
@ -2653,10 +2658,22 @@ SC_FUNC void delete_symbols(symbol *root,int level,int delete_labels,int delete_
break;
} /* switch */
if (mustdelete) {
if (origRoot == &glbtab)
RemoveFromHashTable(sp_Globals, sym);
root->next=sym->next;
free_symbol(sym);
/* first delete children, if any */
int count=0;
while ((child_sym=finddepend(sym))!=NULL) {
delete_symbol(root,child_sym);
count++;
} /* while */
if (count==0) {
if (root == &glbtab)
RemoveFromHashTable(sp_Globals, sym);
base->next=sym->next;
free_symbol(sym);
} else {
/* chain has changed */
delete_symbol(root,sym);
base=root; /* restart */
} /* if */
} else {
/* if the function was prototyped, but not implemented in this source,
* mark it as such, so that its use can be flagged
@ -2674,9 +2691,16 @@ SC_FUNC void delete_symbols(symbol *root,int level,int delete_labels,int delete_
*/
if (sym->ident==iFUNCTN && !alpha(*sym->name))
sym->usage &= ~uPROTOTYPED;
root=sym; /* skip the symbol */
/* mark the symbol as "visited", so we won't process it twice */
sym->usage |= uVISITED;
base=sym; /* skip the symbol */
} /* if */
} /* if */
/* go through the symbols again to erase any "visited" marks */
for (sym = root->next; sym != NULL; sym = sym->next)
sym->usage &= ~uVISITED;
}
static symbol *find_symbol(const symbol *root,const char *name,int fnumber,int includechildren)
@ -2869,10 +2893,12 @@ SC_FUNC symbol *addvariable(const char *name,cell addr,int ident,int vclass,int
/* global variables may only be defined once
* One complication is that functions returning arrays declare an array
* with the same name as the function, so the assertion must allow for
* this special case.
* this special case. Another complication is that variables may be
* "redeclared" if they are local to an automaton (and findglb() will find
* the symbol without states if no symbol with states exists).
*/
assert(vclass!=sGLOBAL || (sym=findglb(name))==NULL || (sym->usage & uDEFINE)==0
|| (sym->ident==iFUNCTN && sym==curfunc));
|| (sym->ident==iFUNCTN && (sym==curfunc || (sym->usage & uNATIVE) != 0)));
if (ident==iARRAY || ident==iREFARRAY) {
symbol *parent=NULL,*top;