Merge pull request #351 from Arkshine/fix/native-array-compilation
Fix issue where native functions returning an array would not compile
This commit is contained in:
commit
f2272ab4cb
|
@ -127,7 +127,7 @@ typedef struct s_symbol {
|
||||||
cell codeaddr; /* address (in the code segment) where the symbol declaration starts */
|
cell codeaddr; /* address (in the code segment) where the symbol declaration starts */
|
||||||
char vclass; /* sLOCAL if "addr" refers to a local symbol */
|
char vclass; /* sLOCAL if "addr" refers to a local symbol */
|
||||||
char ident; /* see below for possible values */
|
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 */
|
char flags; /* see below for possible values */
|
||||||
int compound; /* compound level (braces nesting level) */
|
int compound; /* compound level (braces nesting level) */
|
||||||
int tag; /* tagname id */
|
int tag; /* tagname id */
|
||||||
|
@ -217,6 +217,7 @@ typedef struct s_symbol {
|
||||||
#define uSTOCK 0x40
|
#define uSTOCK 0x40
|
||||||
#define uENUMFIELD 0x40
|
#define uENUMFIELD 0x40
|
||||||
#define uMISSING 0x80
|
#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
|
/* 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
|
* used during parsing a function, to detect a mix of "return;" and
|
||||||
* "return value;" in a few special cases.
|
* "return value;" in a few special cases.
|
||||||
|
|
|
@ -3244,7 +3244,7 @@ static void funcstub(int native)
|
||||||
/* attach the array to the function symbol */
|
/* attach the array to the function symbol */
|
||||||
if (numdim>0) {
|
if (numdim>0) {
|
||||||
assert(sym!=NULL);
|
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;
|
sub->parent=sym;
|
||||||
} /* if */
|
} /* if */
|
||||||
|
|
||||||
|
|
|
@ -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)
|
SC_FUNC void delete_symbols(symbol *root,int level,int delete_labels,int delete_functions)
|
||||||
{
|
{
|
||||||
symbol *origRoot=root;
|
symbol *base;
|
||||||
symbol *sym,*parent_sym;
|
symbol *sym,*parent_sym,*child_sym;
|
||||||
constvalue *stateptr;
|
constvalue *stateptr;
|
||||||
int mustdelete=0;
|
int mustdelete=0;
|
||||||
|
|
||||||
/* erase only the symbols with a deeper nesting level than the
|
/* erase only the symbols with a deeper nesting level than the
|
||||||
* specified nesting level */
|
* specified nesting level */
|
||||||
while (root->next!=NULL) {
|
base=root;
|
||||||
sym=root->next;
|
while (base->next!=NULL) {
|
||||||
|
sym=base->next;
|
||||||
if (get_actual_compound(sym)<level)
|
if (get_actual_compound(sym)<level)
|
||||||
break;
|
break;
|
||||||
|
if ((sym->usage & uVISITED) != 0) {
|
||||||
|
base=sym; /* skip the symbol */
|
||||||
|
continue;
|
||||||
|
}
|
||||||
switch (sym->ident) {
|
switch (sym->ident) {
|
||||||
case iLABEL:
|
case iLABEL:
|
||||||
mustdelete=delete_labels;
|
mustdelete=delete_labels;
|
||||||
|
@ -2653,10 +2658,22 @@ SC_FUNC void delete_symbols(symbol *root,int level,int delete_labels,int delete_
|
||||||
break;
|
break;
|
||||||
} /* switch */
|
} /* switch */
|
||||||
if (mustdelete) {
|
if (mustdelete) {
|
||||||
if (origRoot == &glbtab)
|
/* 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);
|
RemoveFromHashTable(sp_Globals, sym);
|
||||||
root->next=sym->next;
|
base->next=sym->next;
|
||||||
free_symbol(sym);
|
free_symbol(sym);
|
||||||
|
} else {
|
||||||
|
/* chain has changed */
|
||||||
|
delete_symbol(root,sym);
|
||||||
|
base=root; /* restart */
|
||||||
|
} /* if */
|
||||||
} else {
|
} else {
|
||||||
/* if the function was prototyped, but not implemented in this source,
|
/* if the function was prototyped, but not implemented in this source,
|
||||||
* mark it as such, so that its use can be flagged
|
* 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))
|
if (sym->ident==iFUNCTN && !alpha(*sym->name))
|
||||||
sym->usage &= ~uPROTOTYPED;
|
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 */
|
||||||
} /* 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)
|
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
|
/* global variables may only be defined once
|
||||||
* One complication is that functions returning arrays declare an array
|
* One complication is that functions returning arrays declare an array
|
||||||
* with the same name as the function, so the assertion must allow for
|
* 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
|
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) {
|
if (ident==iARRAY || ident==iREFARRAY) {
|
||||||
symbol *parent=NULL,*top;
|
symbol *parent=NULL,*top;
|
||||||
|
|
Loading…
Reference in New Issue
Block a user