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:
Vincent Herbet 2016-02-23 19:41:43 +01:00
commit f2272ab4cb
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 */ 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.

View File

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

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