From 680a8e02833a21137603768f141ffdca73faa20c Mon Sep 17 00:00:00 2001 From: David Anderson Date: Sat, 5 Jul 2014 00:44:46 -0700 Subject: [PATCH] Fix tests. --- sourcepawn/compiler/sc.h | 1 + sourcepawn/compiler/sc1.c | 32 ++++++++++++++++++++++++++++---- 2 files changed, 29 insertions(+), 4 deletions(-) diff --git a/sourcepawn/compiler/sc.h b/sourcepawn/compiler/sc.h index 9f660d7c..e81b5e9f 100644 --- a/sourcepawn/compiler/sc.h +++ b/sourcepawn/compiler/sc.h @@ -264,6 +264,7 @@ typedef struct svalue_s { #define DECLFLAG_ENUMROOT 0x08 // Multi-dimensional arrays should have an enumroot. #define DECLFLAG_MAYBE_FUNCTION 0x10 // Might be a named function. #define DECLFLAG_DYNAMIC_ARRAYS 0x20 // Dynamic arrays are allowed. +#define DECLFLAG_OLD 0x40 // Known old-style declaration. #define DECLMASK_NAMED_DECL (DECLFLAG_ARGUMENT | DECLFLAG_VARIABLE | DECLFLAG_MAYBE_FUNCTION) typedef struct { diff --git a/sourcepawn/compiler/sc1.c b/sourcepawn/compiler/sc1.c index 52fbeb8e..c7cf1ca7 100644 --- a/sourcepawn/compiler/sc1.c +++ b/sourcepawn/compiler/sc1.c @@ -1478,8 +1478,12 @@ static void dodecl(const token_t *tok) int fpublic = (tok->id == tPUBLIC); int fstock = (tok->id == tSTOCK); int fstatic = (tok->id == tSTATIC); + + int flags = DECLFLAG_MAYBE_FUNCTION | DECLFLAG_VARIABLE | DECLFLAG_ENUMROOT; + if (tok->id == tNEW) + flags |= DECLFLAG_OLD; - parse_decl(&decl, DECLFLAG_MAYBE_FUNCTION|DECLFLAG_VARIABLE|DECLFLAG_ENUMROOT); + parse_decl(&decl, flags); if (!decl.opertok && (tok->id == tNEW || decl.has_postdims || !lexpeek('('))) { if (tok->id == tNEW && decl.is_new) @@ -2119,7 +2123,9 @@ static void declloc(int tokid) int fstatic = (tokid == tSTATIC); declinfo_t decl; - const int declflags = DECLFLAG_VARIABLE | DECLFLAG_ENUMROOT | DECLFLAG_DYNAMIC_ARRAYS; + int declflags = DECLFLAG_VARIABLE | DECLFLAG_ENUMROOT | DECLFLAG_DYNAMIC_ARRAYS; + if (tokid == tNEW || tokid == tDECL) + declflags |= DECLFLAG_OLD; parse_decl(&decl, declflags); @@ -3286,6 +3292,19 @@ static int parse_old_decl(declinfo_t *decl, int flags) if (decl->opertok == 0) strcpy(decl->name, ""); } else { + if (!lexpeek(tSYMBOL)) { + switch (lextok(&tok)) { + case tOBJECT: + case tCHAR: + case tVOID: + case tINT: + error(143); + break; + default: + lexpush(); + break; + } + } if (expecttoken(tSYMBOL, &tok)) strcpy(decl->name, tok.str); else @@ -3400,6 +3419,11 @@ int parse_decl(declinfo_t *decl, int flags) if (matchtoken(tCONST)) decl->type.usage |= uCONST; + // Sometimes we know ahead of time whether the declaration will be old, for + // example, if preceded by tNEW or tDECL. + if (flags & DECLFLAG_OLD) + return parse_old_decl(decl, flags); + // If parsing an argument, there are two simple checks for whether this is a // new or old-style declaration. if ((flags & DECLFLAG_ARGUMENT) && (lexpeek('&') || lexpeek('{'))) @@ -6480,7 +6504,7 @@ static void statement(int *lastindent,int allow_decl) lexpush(); autozero = TRUE; lastst = tNEW; - declloc(tNEW); + declloc(tok); return; } } @@ -6939,7 +6963,7 @@ static int dofor(void) */ nestlevel++; autozero=1; - declloc(tFOR); /* declare local variable */ + declloc(tok.id); /* declare local variable */ break; default: lexpush();