Add unstaged changes.
This commit is contained in:
parent
6f3b08bbae
commit
beb557aa56
@ -1,3 +1,4 @@
|
||||
// vim: set sts=2 ts=8 sw=2 tw=99 et:
|
||||
/* Pawn compiler
|
||||
*
|
||||
* Drafted after the Small-C compiler Version 2.01, originally created
|
||||
@ -272,6 +273,7 @@ typedef struct {
|
||||
int numdim;
|
||||
int dim[sDIMEN_MAX];
|
||||
int idxtag[sDIMEN_MAX];
|
||||
cell array_size;
|
||||
constvalue *enumroot;
|
||||
|
||||
// Type information.
|
||||
|
@ -121,8 +121,7 @@ static void attachstatelist(symbol *sym, int state_id);
|
||||
static symbol *funcstub(int fnative, const funcstub_setup_t *setup);
|
||||
static int newfunc(const funcstub_setup_t *setup,int fpublic,int fstatic,int stock,symbol **symp);
|
||||
static int declargs(symbol *sym, int chkshadow, const int *thistag);
|
||||
static void doarg(char *name,int ident,int offset,int tags[],int numtags,
|
||||
int fpublic,int fconst,int chkshadow,arginfo *arg);
|
||||
static void doarg(declinfo_t *decl, int offset, int fpublic, int chkshadow, arginfo *arg);
|
||||
static void make_report(symbol *root,FILE *log,char *sourcefile);
|
||||
static void reduce_referrers(symbol *root);
|
||||
static long max_stacksize(symbol *root,int *recursion);
|
||||
@ -3271,14 +3270,16 @@ static int parse_new_typeexpr(typeinfo_t *type, const token_t *first, int flags)
|
||||
else
|
||||
lextok(&tok);
|
||||
|
||||
type->ident = iVARIABLE;
|
||||
|
||||
if (tok.id == tCONST) {
|
||||
if (type->usage & uCONST)
|
||||
error(138);
|
||||
type->usage |= uCONST;
|
||||
lextok(&tok);
|
||||
}
|
||||
|
||||
if (tok.id == '[') {
|
||||
// Note: we could have already filled in the prefix array bits below, so we
|
||||
// check that ident != iARRAY before looking for an open bracket.
|
||||
if (type->ident != iARRAY && tok.id == '[') {
|
||||
// Not yet supported for return vals. This is allowed with old decls, but
|
||||
// it's a huge hack. For now we forbid it in new code until it works right.
|
||||
if (flags & TYPEFLAG_RETURN)
|
||||
@ -3291,7 +3292,7 @@ static int parse_new_typeexpr(typeinfo_t *type, const token_t *first, int flags)
|
||||
}
|
||||
type->dim[type->numdim++] = 0;
|
||||
if (!needtoken(']'))
|
||||
return FALSE;
|
||||
goto err_out;
|
||||
lextok(&tok);
|
||||
}
|
||||
type->ident = iARRAY;
|
||||
@ -3330,14 +3331,14 @@ static int parse_new_typeexpr(typeinfo_t *type, const token_t *first, int flags)
|
||||
break;
|
||||
default:
|
||||
error(122);
|
||||
return FALSE;
|
||||
goto err_out;
|
||||
}
|
||||
|
||||
if (flags & TYPEFLAG_ARGUMENT) {
|
||||
if (matchtoken('&')) {
|
||||
if (type->ident == iARRAY) {
|
||||
error(137);
|
||||
return FALSE;
|
||||
goto err_out;
|
||||
}
|
||||
type->ident = iREFERENCE;
|
||||
}
|
||||
@ -3346,6 +3347,11 @@ static int parse_new_typeexpr(typeinfo_t *type, const token_t *first, int flags)
|
||||
type->tags[0] = type->tag;
|
||||
type->numtags = 1;
|
||||
return TRUE;
|
||||
|
||||
err_out:
|
||||
type->tags[0] = type->tag;
|
||||
type->numtags = 1;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void parse_old_array_dims(declinfo_t *decl, int flags)
|
||||
@ -3370,11 +3376,11 @@ static void parse_old_array_dims(declinfo_t *decl, int flags)
|
||||
return;
|
||||
}
|
||||
|
||||
size = needsub(&type->idxtag[type->numdim], enumrootp);
|
||||
if (size > INT_MAX)
|
||||
type->array_size = needsub(&type->idxtag[type->numdim], enumrootp);
|
||||
if (type->array_size > INT_MAX)
|
||||
error(165);
|
||||
|
||||
type->dim[type->numdim++] = (int)size;
|
||||
type->dim[type->numdim++] = type->array_size;
|
||||
} while (matchtoken('['));
|
||||
|
||||
type->ident = iARRAY;
|
||||
@ -3385,10 +3391,11 @@ static int parse_old_decl(declinfo_t *decl, int flags)
|
||||
token_t tok;
|
||||
typeinfo_t *type = &decl->type;
|
||||
|
||||
type->ident = iVARIABLE;
|
||||
|
||||
if (matchtoken(tCONST))
|
||||
if (matchtoken(tCONST)) {
|
||||
if (type->usage & uCONST)
|
||||
error(138);
|
||||
type->usage |= uCONST;
|
||||
}
|
||||
|
||||
if (flags & TYPEFLAG_ARGUMENT) {
|
||||
if (matchtoken('&'))
|
||||
@ -3413,9 +3420,22 @@ static int parse_old_decl(declinfo_t *decl, int flags)
|
||||
}
|
||||
needtoken(':');
|
||||
}
|
||||
} else {
|
||||
}
|
||||
|
||||
if (type->numtags == 0) {
|
||||
if (matchtoken2(tLABEL, &tok))
|
||||
type->tags[type->numtags++] = pc_addtag(tok.str);
|
||||
else
|
||||
type->tags[type->numtags++] = 0;
|
||||
}
|
||||
|
||||
// All finished with tag stuff.
|
||||
type->tag = type->tags[0];
|
||||
|
||||
// Look for varargs and end early.
|
||||
if (matchtoken(tELLIPS)) {
|
||||
type->ident = iVARARGS;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
if (flags & TYPEMASK_NAMED_DECL) {
|
||||
@ -3430,15 +3450,14 @@ static int parse_old_decl(declinfo_t *decl, int flags)
|
||||
parse_old_array_dims(decl, flags);
|
||||
}
|
||||
|
||||
type->tag = type->tags[0];
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static int parse_new_decl(declinfo_t *decl, int flags)
|
||||
static int parse_new_decl(declinfo_t *decl, const token_t *first, int flags)
|
||||
{
|
||||
token_t tok;
|
||||
|
||||
if (!parse_new_typeexpr(&decl->type, NULL, flags))
|
||||
if (!parse_new_typeexpr(&decl->type, first, flags))
|
||||
return FALSE;
|
||||
if (!expecttoken(tSYMBOL, &tok))
|
||||
return FALSE;
|
||||
@ -3465,9 +3484,16 @@ static int parse_new_decl(declinfo_t *decl, int flags)
|
||||
int parse_decl(declinfo_t *decl, int flags)
|
||||
{
|
||||
token_t tok;
|
||||
token_ident_t ident;
|
||||
|
||||
memset(decl, 0, sizeof(*decl));
|
||||
|
||||
decl->type.ident = iVARIABLE;
|
||||
|
||||
// Must attempt to match const first, since it's a common prefix.
|
||||
if (matchtoken(tCONST))
|
||||
decl->type.usage |= uCONST;
|
||||
|
||||
// If parsing an argument, there are two simple checks for whether this is a
|
||||
// new or old-style declaration.
|
||||
if ((flags & TYPEFLAG_ARGUMENT) && (lexpeek('&') || lexpeek('{')))
|
||||
@ -3478,22 +3504,51 @@ int parse_decl(declinfo_t *decl, int flags)
|
||||
return parse_old_decl(decl, flags);
|
||||
|
||||
// Otherwise, we have to eat a symbol to tell.
|
||||
if (lextok(&tok) == tSYMBOL) {
|
||||
if (lexpeek('[') || lexpeek(tSYMBOL)) {
|
||||
if (matchsymbol(&ident)) {
|
||||
if (lexpeek(tSYMBOL)) {
|
||||
// A new-style declaration only allows array dims or a symbol name, so
|
||||
// this is a new-style declaration. Make sure to push back the first
|
||||
// symbol.
|
||||
lexpush();
|
||||
return parse_new_decl(decl, flags);
|
||||
return parse_new_decl(decl, &ident.tok, flags);
|
||||
}
|
||||
|
||||
// Push the symbol back, we've got an old-style decl.
|
||||
if ((flags & TYPEMASK_NAMED_DECL) && matchtoken('[')) {
|
||||
// If we're not allowing postdims here, then it must be a newdecl.
|
||||
if (flags & TYPEFLAG_NO_POSTDIMS) {
|
||||
// Give the '[' and symbol back, since we're going to parse from the start.
|
||||
lexpush();
|
||||
lexpush();
|
||||
return parse_new_decl(decl, NULL, flags);
|
||||
}
|
||||
|
||||
// Oh no - we have to parse array dims before we can tell what kind of
|
||||
// declarator this is. It could be either:
|
||||
// "x[] y" (new-style), or
|
||||
// "y[]," (old-style)
|
||||
parse_old_array_dims(decl, flags);
|
||||
|
||||
if (matchtoken(tSYMBOL) || matchtoken('&')) {
|
||||
// This must be a newdecl, "x[] y" or "x[] &y", the latter of which
|
||||
// is illegal, but we flow it through the right path anyway.
|
||||
lexpush();
|
||||
return parse_new_decl(decl, &ident.tok, flags);
|
||||
}
|
||||
|
||||
// The most basic - "x[]" and that's it. Well, we know it has no tag and
|
||||
// we know its name. We might as well just complete the entire decl.
|
||||
strcpy(decl->name, ident.name);
|
||||
decl->type.tags[decl->type.numtags++] = 0;
|
||||
decl->type.tag = decl->type.tags[0];
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
// Give the symbol back to the lexer. This is an old decl.
|
||||
lexpush();
|
||||
return parse_old_decl(decl, flags);
|
||||
}
|
||||
|
||||
// All else has failed. Probably got a type keyword. New-style.
|
||||
return parse_new_decl(decl, flags);
|
||||
return parse_new_decl(decl, NULL, flags);
|
||||
}
|
||||
|
||||
void define_constructor(methodmap_t *map, methodmap_method_t *method)
|
||||
@ -5318,11 +5373,11 @@ static int argcompare(arginfo *a1,arginfo *a2)
|
||||
static int declargs(symbol *sym, int chkshadow, const int *thistag)
|
||||
{
|
||||
char *ptr;
|
||||
int argcnt,oldargcnt,tok,tags[MAXTAGS],numtags;
|
||||
int argcnt,oldargcnt,tok;
|
||||
cell val;
|
||||
arginfo arg, *arglist;
|
||||
char name[sNAMEMAX+1];
|
||||
int ident,fpublic,fconst;
|
||||
int ident,fpublic;
|
||||
int idx;
|
||||
|
||||
/* if the function is already defined earlier, get the number of arguments
|
||||
@ -5333,9 +5388,6 @@ static int declargs(symbol *sym, int chkshadow, const int *thistag)
|
||||
while (sym->dim.arglist[oldargcnt].ident!=0)
|
||||
oldargcnt++;
|
||||
argcnt=0; /* zero aruments up to now */
|
||||
ident=iVARIABLE;
|
||||
numtags=0;
|
||||
fconst=FALSE;
|
||||
fpublic = (sym->usage & (uPUBLIC|uSTOCK))!=0;
|
||||
|
||||
if (thistag && *thistag != -1) {
|
||||
@ -5370,52 +5422,43 @@ static int declargs(symbol *sym, int chkshadow, const int *thistag)
|
||||
/* the '(' parantheses has already been parsed */
|
||||
if (!matchtoken(')')){
|
||||
do { /* there are arguments; process them */
|
||||
/* any legal name increases argument count (and stack offset) */
|
||||
tok=lex(&val,&ptr);
|
||||
switch (tok) {
|
||||
case 0:
|
||||
/* nothing */
|
||||
break;
|
||||
case '&':
|
||||
if (ident!=iVARIABLE || numtags>0)
|
||||
error(1,"-identifier-","&");
|
||||
ident=iREFERENCE;
|
||||
break;
|
||||
case tCONST:
|
||||
if (ident!=iVARIABLE || numtags>0)
|
||||
error(1,"-identifier-","const");
|
||||
fconst=TRUE;
|
||||
break;
|
||||
case tLABEL:
|
||||
if (numtags>0)
|
||||
error(1,"-identifier-","-tagname-");
|
||||
tags[0]=pc_addtag(ptr);
|
||||
numtags=1;
|
||||
break;
|
||||
case '{':
|
||||
if (numtags>0)
|
||||
error(1,"-identifier-","-tagname-");
|
||||
numtags=0;
|
||||
while (numtags<MAXTAGS) {
|
||||
if (!matchtoken('_') && !needtoken(tSYMBOL))
|
||||
break;
|
||||
tokeninfo(&val,&ptr);
|
||||
tags[numtags++]=pc_addtag(ptr);
|
||||
if (matchtoken('}'))
|
||||
break;
|
||||
needtoken(',');
|
||||
} /* for */
|
||||
needtoken(':');
|
||||
tok=tLABEL; /* for outer loop: flag that we have seen a tagname */
|
||||
break;
|
||||
case tSYMBOL:
|
||||
if (argcnt>=sMAXARGS)
|
||||
error(45); /* too many function arguments */
|
||||
strcpy(name,ptr); /* save symbol name */
|
||||
if (name[0]==PUBLIC_CHAR)
|
||||
error(56,name); /* function arguments cannot be public */
|
||||
if (numtags==0)
|
||||
tags[numtags++]=0; /* default tag */
|
||||
declinfo_t decl;
|
||||
parse_decl(&decl, TYPEFLAG_ARGUMENT|TYPEFLAG_ENUMROOT);
|
||||
assert(decl.type.numtags > 0);
|
||||
|
||||
if (decl.type.ident == iVARARGS) {
|
||||
assert(decl.type.numtags > 0);
|
||||
if ((sym->usage & uPROTOTYPED)==0) {
|
||||
/* redimension the argument list, add the entry iVARARGS */
|
||||
sym->dim.arglist=(arginfo*)realloc(sym->dim.arglist,(argcnt+2)*sizeof(arginfo));
|
||||
if (sym->dim.arglist==0)
|
||||
error(163); /* insufficient memory */
|
||||
memset(&sym->dim.arglist[argcnt+1],0,sizeof(arginfo)); /* keep the list terminated */
|
||||
sym->dim.arglist[argcnt].ident=iVARARGS;
|
||||
sym->dim.arglist[argcnt].hasdefault=FALSE;
|
||||
sym->dim.arglist[argcnt].defvalue.val=0;
|
||||
sym->dim.arglist[argcnt].defvalue_tag=0;
|
||||
sym->dim.arglist[argcnt].numtags=decl.type.numtags;
|
||||
sym->dim.arglist[argcnt].tags=(int*)malloc(decl.type.numtags*sizeof decl.type.tags[0]);
|
||||
if (sym->dim.arglist[argcnt].tags==NULL)
|
||||
error(163); /* insufficient memory */
|
||||
memcpy(sym->dim.arglist[argcnt].tags,decl.type.tags,decl.type.numtags*sizeof decl.type.tags[0]);
|
||||
} else {
|
||||
if (argcnt>oldargcnt || sym->dim.arglist[argcnt].ident!=iVARARGS)
|
||||
error(25); /* function definition does not match prototype */
|
||||
} /* if */
|
||||
argcnt++;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (argcnt>=sMAXARGS)
|
||||
error(45);
|
||||
if (decl.name[0] == PUBLIC_CHAR)
|
||||
error(56,name); /* function arguments cannot be public */
|
||||
|
||||
if (1) {
|
||||
if (decl.type.ident == iARRAY)
|
||||
decl.type.ident = iREFARRAY;
|
||||
/* Stack layout:
|
||||
* base + 0*sizeof(cell) == previous "base"
|
||||
* base + 1*sizeof(cell) == function return address
|
||||
@ -5423,10 +5466,11 @@ static int declargs(symbol *sym, int chkshadow, const int *thistag)
|
||||
* base + 3*sizeof(cell) == first argument of the function
|
||||
* So the offset of each argument is "(argcnt+3) * sizeof(cell)".
|
||||
*/
|
||||
doarg(name,ident,(argcnt+3)*sizeof(cell),tags,numtags,fpublic,fconst,chkshadow,&arg);
|
||||
/* :TODO: fix this so stocks that are func pointers can't have default arguments? */
|
||||
doarg(&decl,(argcnt+3)*sizeof(cell),fpublic,chkshadow,&arg);
|
||||
|
||||
if ((sym->usage & uPUBLIC) && arg.hasdefault)
|
||||
error(59,name); /* arguments of a public function may not have a default value */
|
||||
|
||||
if ((sym->usage & uPROTOTYPED)==0) {
|
||||
/* redimension the argument list, add the entry */
|
||||
sym->dim.arglist=(arginfo*)realloc(sym->dim.arglist,(argcnt+2)*sizeof(arginfo));
|
||||
@ -5447,41 +5491,8 @@ static int declargs(symbol *sym, int chkshadow, const int *thistag)
|
||||
free(arg.tags);
|
||||
} /* if */
|
||||
argcnt++;
|
||||
ident=iVARIABLE;
|
||||
numtags=0;
|
||||
fconst=FALSE;
|
||||
break;
|
||||
case tELLIPS:
|
||||
if (ident!=iVARIABLE)
|
||||
error(10); /* illegal function or declaration */
|
||||
if (numtags==0)
|
||||
tags[numtags++]=0; /* default tag */
|
||||
if ((sym->usage & uPROTOTYPED)==0) {
|
||||
/* redimension the argument list, add the entry iVARARGS */
|
||||
sym->dim.arglist=(arginfo*)realloc(sym->dim.arglist,(argcnt+2)*sizeof(arginfo));
|
||||
if (sym->dim.arglist==0)
|
||||
error(163); /* insufficient memory */
|
||||
memset(&sym->dim.arglist[argcnt+1],0,sizeof(arginfo)); /* keep the list terminated */
|
||||
sym->dim.arglist[argcnt].ident=iVARARGS;
|
||||
sym->dim.arglist[argcnt].hasdefault=FALSE;
|
||||
sym->dim.arglist[argcnt].defvalue.val=0;
|
||||
sym->dim.arglist[argcnt].defvalue_tag=0;
|
||||
sym->dim.arglist[argcnt].numtags=numtags;
|
||||
sym->dim.arglist[argcnt].tags=(int*)malloc(numtags*sizeof tags[0]);
|
||||
if (sym->dim.arglist[argcnt].tags==NULL)
|
||||
error(163); /* insufficient memory */
|
||||
memcpy(sym->dim.arglist[argcnt].tags,tags,numtags*sizeof tags[0]);
|
||||
} else {
|
||||
if (argcnt>oldargcnt || sym->dim.arglist[argcnt].ident!=iVARARGS)
|
||||
error(25); /* function definition does not match prototype */
|
||||
} /* if */
|
||||
argcnt++;
|
||||
break;
|
||||
default:
|
||||
error(10); /* illegal function or declaration */
|
||||
} /* switch */
|
||||
} while (tok=='&' || tok==tLABEL || tok==tCONST
|
||||
|| (tok!=tELLIPS && matchtoken(','))); /* more? */
|
||||
}
|
||||
} while (matchtoken(','));
|
||||
/* if the next token is not ",", it should be ")" */
|
||||
needtoken(')');
|
||||
} /* if */
|
||||
@ -5540,50 +5551,29 @@ static int declargs(symbol *sym, int chkshadow, const int *thistag)
|
||||
* "fpublic" indicates whether the function for this argument list is public.
|
||||
* The arguments themselves are never public.
|
||||
*/
|
||||
static void doarg(char *name,int ident,int offset,int tags[],int numtags,
|
||||
int fpublic,int fconst,int chkshadow,arginfo *arg)
|
||||
static void doarg(declinfo_t *decl, int offset, int fpublic, int chkshadow, arginfo *arg)
|
||||
{
|
||||
symbol *argsym;
|
||||
constvalue *enumroot;
|
||||
cell size;
|
||||
int slength=0;
|
||||
typeinfo_t *type = &decl->type;
|
||||
|
||||
strcpy(arg->name,name);
|
||||
strcpy(arg->name, decl->name);
|
||||
arg->hasdefault=FALSE; /* preset (most common case) */
|
||||
arg->defvalue.val=0; /* clear */
|
||||
arg->defvalue_tag=0;
|
||||
arg->numdim=0;
|
||||
if (matchtoken('[')) {
|
||||
if (ident==iREFERENCE)
|
||||
error(67,name); /* illegal declaration ("&name[]" is unsupported) */
|
||||
do {
|
||||
if (arg->numdim == sDIMEN_MAX) {
|
||||
error(53); /* exceeding maximum number of dimensions */
|
||||
return;
|
||||
} /* if */
|
||||
size=needsub(&arg->idxtag[arg->numdim],&enumroot);/* may be zero here, it is a pointer anyway */
|
||||
#if INT_MAX < LONG_MAX
|
||||
if (size > INT_MAX)
|
||||
error(165); /* overflow, exceeding capacity */
|
||||
#endif
|
||||
arg->dim[arg->numdim]=(int)size;
|
||||
arg->numdim+=1;
|
||||
} while (matchtoken('['));
|
||||
ident=iREFARRAY; /* "reference to array" (is a pointer) */
|
||||
#if 0 /* For SM, multiple tags including string don't make sense,
|
||||
so just check the first tag. Done manually so the string
|
||||
tag isn't matched with the any tag. */
|
||||
if (checktag(tags, numtags, pc_tag_string)) {
|
||||
#endif
|
||||
assert(tags!=0);
|
||||
assert(numtags>0);
|
||||
if (tags[0] == pc_tag_string) {
|
||||
if (type->ident == iREFARRAY) {
|
||||
arg->numdim = type->numdim;
|
||||
memcpy(arg->dim, type->dim, sizeof(int) * type->numdim);
|
||||
memcpy(arg->idxtag, type->idxtag, sizeof(int) * type->numdim);
|
||||
assert(type->numtags > 0);
|
||||
if (type->tags[0] == pc_tag_string) {
|
||||
slength = arg->dim[arg->numdim - 1];
|
||||
arg->dim[arg->numdim - 1] = (size + sizeof(cell) - 1) / sizeof(cell);
|
||||
arg->dim[arg->numdim - 1] = (type->array_size + sizeof(cell) - 1) / sizeof(cell);
|
||||
}
|
||||
if (matchtoken('=')) {
|
||||
assert(litidx==0); /* at the start of a function, this is reset */
|
||||
assert(numtags>0);
|
||||
/* Check if there is a symbol */
|
||||
if (matchtoken(tSYMBOL)) {
|
||||
symbol *sym;
|
||||
@ -5603,8 +5593,8 @@ static void doarg(char *name,int ident,int offset,int tags[],int numtags,
|
||||
}
|
||||
}
|
||||
} else {
|
||||
initials2(ident,tags[0],&size,arg->dim,arg->numdim,enumroot, 1, 0);
|
||||
assert(size>=litidx);
|
||||
initials2(type->ident, type->tags[0], &type->array_size, arg->dim, arg->numdim, type->enumroot, 1, 0);
|
||||
assert(type->array_size >= litidx);
|
||||
/* allocate memory to hold the initial values */
|
||||
arg->defvalue.array.data=(cell *)malloc(litidx*sizeof(cell));
|
||||
if (arg->defvalue.array.data!=NULL) {
|
||||
@ -5626,7 +5616,7 @@ static void doarg(char *name,int ident,int offset,int tags[],int numtags,
|
||||
} else {
|
||||
if (matchtoken('=')) {
|
||||
unsigned char size_tag_token;
|
||||
assert(ident==iVARIABLE || ident==iREFERENCE);
|
||||
assert(type->ident==iVARIABLE || type->ident==iREFERENCE);
|
||||
arg->hasdefault=TRUE; /* argument has a default value */
|
||||
size_tag_token=(unsigned char)(matchtoken(tSIZEOF) ? uSIZEOF : 0);
|
||||
if (size_tag_token==0)
|
||||
@ -5635,8 +5625,8 @@ static void doarg(char *name,int ident,int offset,int tags[],int numtags,
|
||||
size_tag_token=(unsigned char)(matchtoken(tCELLSOF) ? uCOUNTOF : 0);
|
||||
if (size_tag_token!=0) {
|
||||
int paranthese;
|
||||
if (ident==iREFERENCE)
|
||||
error(66,name); /* argument may not be a reference */
|
||||
if (type->ident==iREFERENCE)
|
||||
error(66, decl->name); /* argument may not be a reference */
|
||||
paranthese=0;
|
||||
while (matchtoken('('))
|
||||
paranthese++;
|
||||
@ -5654,41 +5644,41 @@ static void doarg(char *name,int ident,int offset,int tags[],int numtags,
|
||||
needtoken(']');
|
||||
} /* while */
|
||||
} /* if */
|
||||
if (ident==iVARIABLE) /* make sure we set this only if not a reference */
|
||||
if (type->ident==iVARIABLE) /* make sure we set this only if not a reference */
|
||||
arg->hasdefault |= size_tag_token; /* uSIZEOF or uTAGOF */
|
||||
} /* if */
|
||||
while (paranthese--)
|
||||
needtoken(')');
|
||||
} else {
|
||||
constexpr(&arg->defvalue.val,&arg->defvalue_tag,NULL);
|
||||
assert(numtags>0);
|
||||
matchtag(tags[0],arg->defvalue_tag,TRUE);
|
||||
assert(type->numtags > 0);
|
||||
matchtag(type->tags[0], arg->defvalue_tag, TRUE);
|
||||
} /* if */
|
||||
} /* if */
|
||||
} /* if */
|
||||
arg->ident=(char)ident;
|
||||
arg->usage=(char)(fconst ? uCONST : 0);
|
||||
arg->numtags=numtags;
|
||||
arg->tags=(int*)malloc(numtags*sizeof tags[0]);
|
||||
arg->ident=(char)type->ident;
|
||||
arg->usage=type->usage;
|
||||
arg->numtags=type->numtags;
|
||||
arg->tags=(int*)malloc(type->numtags * sizeof(type->tags[0]));
|
||||
if (arg->tags==NULL)
|
||||
error(163); /* insufficient memory */
|
||||
memcpy(arg->tags,tags,numtags*sizeof tags[0]);
|
||||
argsym=findloc(name);
|
||||
memcpy(arg->tags, type->tags, type->numtags * sizeof(type->tags[0]));
|
||||
argsym=findloc(decl->name);
|
||||
if (argsym!=NULL) {
|
||||
error(21,name); /* symbol already defined */
|
||||
error(21, decl->name); /* symbol already defined */
|
||||
} else {
|
||||
if (chkshadow && (argsym=findglb(name,sSTATEVAR))!=NULL && argsym->ident!=iFUNCTN)
|
||||
error(219,name); /* variable shadows another symbol */
|
||||
if (chkshadow && (argsym=findglb(decl->name,sSTATEVAR))!=NULL && argsym->ident!=iFUNCTN)
|
||||
error(219, decl->name); /* variable shadows another symbol */
|
||||
/* add details of type and address */
|
||||
assert(numtags>0);
|
||||
argsym=addvariable2(name,offset,ident,sLOCAL,tags[0],
|
||||
assert(type->numtags > 0);
|
||||
argsym=addvariable2(decl->name,offset,type->ident,sLOCAL,type->tags[0],
|
||||
arg->dim,arg->numdim,arg->idxtag,slength);
|
||||
argsym->compound=0;
|
||||
if (ident==iREFERENCE)
|
||||
if (type->ident==iREFERENCE)
|
||||
argsym->usage|=uREAD; /* because references are passed back */
|
||||
if (fpublic)
|
||||
argsym->usage|=uREAD; /* arguments of public functions are always "used" */
|
||||
if (fconst)
|
||||
if (type->usage & uCONST)
|
||||
argsym->usage|=uCONST;
|
||||
} /* if */
|
||||
}
|
||||
|
@ -75,6 +75,10 @@ static short lastfile;
|
||||
char *msg,*pre;
|
||||
va_list argptr;
|
||||
|
||||
if (number == 47) {
|
||||
printf("EGG\n");
|
||||
}
|
||||
|
||||
// sErrLine is used to temporarily change the line number of reported errors.
|
||||
// Pawn has an upstream bug where this is not reset on early-return, which
|
||||
// can lead to broken line numbers in error messages.
|
||||
|
Loading…
Reference in New Issue
Block a user