From f43b4468c62bb9e7462971f2c3dd411d825895c6 Mon Sep 17 00:00:00 2001 From: David Anderson Date: Fri, 10 Nov 2006 00:16:12 +0000 Subject: [PATCH] added the ability to pre-declare a struct, like extern --HG-- extra : convert_revision : svn%3A39bc706e-5318-0410-9160-8a85361fbb7c/trunk%40174 --- sourcepawn/compiler/sc.h | 1 + sourcepawn/compiler/sc1.c | 41 +++++++++++++++++++++++++++++++++------ 2 files changed, 36 insertions(+), 6 deletions(-) diff --git a/sourcepawn/compiler/sc.h b/sourcepawn/compiler/sc.h index 7a1ebd80..7f78fd4a 100644 --- a/sourcepawn/compiler/sc.h +++ b/sourcepawn/compiler/sc.h @@ -214,6 +214,7 @@ typedef struct s_symbol { #define uENUMFIELD 0x040 #define uMISSING 0x080 #define uFORWARD 0x100 +#define uSTRUCT 0x200 /* :TODO: make this an ident */ /* 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. diff --git a/sourcepawn/compiler/sc1.c b/sourcepawn/compiler/sc1.c index 84fcd25c..7d621142 100644 --- a/sourcepawn/compiler/sc1.c +++ b/sourcepawn/compiler/sc1.c @@ -1700,7 +1700,7 @@ static void declstructvar(char *firstname,int fpublic, pstruct_t *pstruct) int cur_litidx = 0; cell *values, *found; int usage; - symbol *mysym; + symbol *mysym,*sym; strcpy(name, firstname); @@ -1709,23 +1709,53 @@ static void declstructvar(char *firstname,int fpublic, pstruct_t *pstruct) memset(found, 0, sizeof(cell) * pstruct->argcount); + //:TODO: Make this work with stock /** * Lastly, very lastly, we will insert a copy of this variable. * This is soley to expose the pubvar. */ - usage = uDEFINE|uREAD|uCONST; + usage = uREAD|uCONST|uSTRUCT; if (fpublic) { usage |= uPUBLIC; } - mysym=addsym(name, 0, iVARIABLE, sGLOBAL, pc_addtag(pstruct->name), usage); + mysym = NULL; + for (sym=glbtab.next; sym!=NULL; sym=sym->next) + { + if (strcmp(name, sym->name) == 0) + { + if ((sym->usage & uSTRUCT) && sym->vclass == sGLOBAL) + { + if (sym->usage & uDEFINE) + { + error(21, name); + } else { + if (sym->usage & uPUBLIC && !fpublic) + { + error(42); + } + } + } else { + error(21, name); + } + mysym = sym; + break; + } + } + if (!mysym) + { + mysym=addsym(name, 0, iVARIABLE, sGLOBAL, pc_addtag(pstruct->name), usage); + } - /* Maybe error with "public struct requires initialization?" */ - if (!needtoken('=')) + if (!matchtoken('=')) { matchtoken(';'); + /* Mark it as undefined instead */ + mysym->usage = uSTOCK|uSTRUCT; return; + } else { + mysym->usage = usage; } needtoken('{'); do @@ -1792,7 +1822,6 @@ static void declstructvar(char *firstname,int fpublic, pstruct_t *pstruct) found[arg->index] = 1; } } else if (tok == tSYMBOL) { - symbol *sym = NULL; for (sym=glbtab.next; sym!=NULL; sym=sym->next) { if (sym->vclass != sGLOBAL)