Commit 7c872f8a authored by Poul-Henning Kamp's avatar Poul-Henning Kamp

Rework the x-ref code in VCC to use the One and Only symbol table, rather

than have three different ones.



git-svn-id: http://www.varnish-cache.org/svn/trunk/varnish-cache@5386 d4fa192b-c00b-0410-8231-f00ffab90ce4
parent f508d29a
...@@ -74,6 +74,7 @@ ...@@ -74,6 +74,7 @@
-efile(451, "http_headers.h") // No include guard -efile(451, "http_headers.h") // No include guard
-efile(451, "acct_fields.h") // No include guard -efile(451, "acct_fields.h") // No include guard
-efile(451, "vcc_types.h") // No include guard -efile(451, "vcc_types.h") // No include guard
-efile(451, "symbol_kind.h") // No include guard
-efile(451, "config.h") // No include guard -efile(451, "config.h") // No include guard
////////////// //////////////
// -e458 // unprotected access // -e458 // unprotected access
......
/*-
* Copyright (c) 2010 Linpro AS
* All rights reserved.
*
* Author: Poul-Henning Kamp <phk@phk.freebsd.dk>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $Id: vcc_types.h 5163 2010-08-31 10:59:07Z phk $
*/
/*lint -save -e525 -e539 */
VCC_SYMB(NONE, none, "undefined")
VCC_SYMB(VAR, var, "variable")
VCC_SYMB(FUNC, func, "function") /* VMOD function */
VCC_SYMB(PROC, proc, "procedure") /* VMOD procedure */
VCC_SYMB(VMOD, vmod, "vmod")
VCC_SYMB(ACL, acl, "acl")
VCC_SYMB(SUB, sub, "sub") /* VCL subroutine */
VCC_SYMB(BACKEND, backend, "backend")
VCC_SYMB(PROBE, probe, "probe")
/*lint -restore */
...@@ -477,7 +477,7 @@ vcc_Acl(struct vcc *tl) ...@@ -477,7 +477,7 @@ vcc_Acl(struct vcc *tl)
an = tl->t; an = tl->t;
vcc_NextToken(tl); vcc_NextToken(tl);
vcc_AddDef(tl, an, R_ACL); vcc_AddDef(tl, an, SYM_ACL);
bprintf(acln, "%.*s", PF(an)); bprintf(acln, "%.*s", PF(an));
SkipToken(tl, '{'); SkipToken(tl, '{');
......
...@@ -53,7 +53,7 @@ parse_call(struct vcc *tl) ...@@ -53,7 +53,7 @@ parse_call(struct vcc *tl)
vcc_NextToken(tl); vcc_NextToken(tl);
ExpectErr(tl, ID); ExpectErr(tl, ID);
vcc_AddCall(tl, tl->t); vcc_AddCall(tl, tl->t);
vcc_AddRef(tl, tl->t, R_SUB); vcc_AddRef(tl, tl->t, SYM_SUB);
Fb(tl, 1, "if (VGC_function_%.*s(sp))\n", PF(tl->t)); Fb(tl, 1, "if (VGC_function_%.*s(sp))\n", PF(tl->t));
Fb(tl, 1, "\treturn (1);\n"); Fb(tl, 1, "\treturn (1);\n");
vcc_NextToken(tl); vcc_NextToken(tl);
...@@ -447,7 +447,7 @@ vcc_ParseAction(struct vcc *tl) ...@@ -447,7 +447,7 @@ vcc_ParseAction(struct vcc *tl)
return (1); return (1);
} }
} }
sym = VCC_FindSymbol(tl, tl->t); sym = VCC_FindSymbol(tl, tl->t, SYM_NONE);
if (sym != NULL && sym->kind == SYM_PROC) { if (sym != NULL && sym->kind == SYM_PROC) {
vcc_Expr_Call(tl, sym); vcc_Expr_Call(tl, sym);
return (1); return (1);
......
...@@ -422,7 +422,7 @@ vcc_ParseProbe(struct vcc *tl) ...@@ -422,7 +422,7 @@ vcc_ParseProbe(struct vcc *tl)
ERRCHK(tl); ERRCHK(tl);
t_probe = tl->t; t_probe = tl->t;
vcc_NextToken(tl); vcc_NextToken(tl);
vcc_AddDef(tl, t_probe, R_PROBE); vcc_AddDef(tl, t_probe, SYM_PROBE);
Fh(tl, 0, "\n#define vgc_probe_%.*s\tvgc_probe__%d\n", Fh(tl, 0, "\n#define vgc_probe_%.*s\tvgc_probe__%d\n",
PF(t_probe), tl->nprobe); PF(t_probe), tl->nprobe);
...@@ -554,7 +554,7 @@ vcc_ParseHostDef(struct vcc *tl, int serial, const char *vgcname) ...@@ -554,7 +554,7 @@ vcc_ParseHostDef(struct vcc *tl, int serial, const char *vgcname)
ERRCHK(tl); ERRCHK(tl);
} else if (vcc_IdIs(t_field, "probe") && tl->t->tok == ID) { } else if (vcc_IdIs(t_field, "probe") && tl->t->tok == ID) {
Fb(tl, 0, "\t.probe = &vgc_probe_%.*s,\n", PF(tl->t)); Fb(tl, 0, "\t.probe = &vgc_probe_%.*s,\n", PF(tl->t));
vcc_AddRef(tl, tl->t, R_PROBE); vcc_AddRef(tl, tl->t, SYM_PROBE);
vcc_NextToken(tl); vcc_NextToken(tl);
SkipToken(tl, ';'); SkipToken(tl, ';');
} else if (vcc_IdIs(t_field, "probe")) { } else if (vcc_IdIs(t_field, "probe")) {
...@@ -646,7 +646,7 @@ vcc_ParseBackendHost(struct vcc *tl, int serial, char **nm) ...@@ -646,7 +646,7 @@ vcc_ParseBackendHost(struct vcc *tl, int serial, char **nm)
vcc_ErrWhere(tl, tl->t); vcc_ErrWhere(tl, tl->t);
return; return;
} }
vcc_AddRef(tl, h->name, R_BACKEND); vcc_AddRef(tl, h->name, SYM_BACKEND);
vcc_NextToken(tl); vcc_NextToken(tl);
SkipToken(tl, ';'); SkipToken(tl, ';');
*nm = h->vgcname; *nm = h->vgcname;
...@@ -687,7 +687,7 @@ vcc_ParseSimpleDirector(struct vcc *tl) ...@@ -687,7 +687,7 @@ vcc_ParseSimpleDirector(struct vcc *tl)
h = TlAlloc(tl, sizeof *h); h = TlAlloc(tl, sizeof *h);
h->name = tl->t_dir; h->name = tl->t_dir;
vcc_AddDef(tl, tl->t_dir, R_BACKEND); vcc_AddDef(tl, tl->t_dir, SYM_BACKEND);
sprintf(vgcname, "_%.*s", PF(h->name)); sprintf(vgcname, "_%.*s", PF(h->name));
h->vgcname = TlAlloc(tl, strlen(vgcname) + 1); h->vgcname = TlAlloc(tl, strlen(vgcname) + 1);
strcpy(h->vgcname, vgcname); strcpy(h->vgcname, vgcname);
...@@ -735,7 +735,7 @@ vcc_ParseDirector(struct vcc *tl) ...@@ -735,7 +735,7 @@ vcc_ParseDirector(struct vcc *tl)
tl->t_policy = t_first; tl->t_policy = t_first;
vcc_ParseSimpleDirector(tl); vcc_ParseSimpleDirector(tl);
} else { } else {
vcc_AddDef(tl, tl->t_dir, R_BACKEND); vcc_AddDef(tl, tl->t_dir, SYM_BACKEND);
ExpectErr(tl, ID); /* ID: policy */ ExpectErr(tl, ID); /* ID: policy */
tl->t_policy = tl->t; tl->t_policy = tl->t;
vcc_NextToken(tl); vcc_NextToken(tl);
......
...@@ -477,8 +477,6 @@ vcc_NewVcc(const struct vcc *tl0) ...@@ -477,8 +477,6 @@ vcc_NewVcc(const struct vcc *tl0)
VTAILQ_INIT(&tl->hosts); VTAILQ_INIT(&tl->hosts);
VTAILQ_INIT(&tl->membits); VTAILQ_INIT(&tl->membits);
VTAILQ_INIT(&tl->tokens); VTAILQ_INIT(&tl->tokens);
VTAILQ_INIT(&tl->refs);
VTAILQ_INIT(&tl->procs);
VTAILQ_INIT(&tl->sources); VTAILQ_INIT(&tl->sources);
tl->nsources = 0; tl->nsources = 0;
...@@ -564,7 +562,7 @@ vcc_CompileSource(const struct vcc *tl0, struct vsb *sb, struct source *sp) ...@@ -564,7 +562,7 @@ vcc_CompileSource(const struct vcc *tl0, struct vsb *sb, struct source *sp)
tl->sb = sb; tl->sb = sb;
for (v = tl->vars; v->name != NULL; v++) { for (v = tl->vars; v->name != NULL; v++) {
sym = VCC_AddSymbol(tl, v->name, SYM_VAR); sym = VCC_AddSymbolStr(tl, v->name, SYM_VAR);
sym->var = v; sym->var = v;
sym->fmt = v->fmt; sym->fmt = v->fmt;
sym->r_methods = v->r_methods; sym->r_methods = v->r_methods;
...@@ -623,7 +621,7 @@ vcc_CompileSource(const struct vcc *tl0, struct vsb *sb, struct source *sp) ...@@ -623,7 +621,7 @@ vcc_CompileSource(const struct vcc *tl0, struct vsb *sb, struct source *sp)
/* Configure the default director */ /* Configure the default director */
Fi(tl, 0, "\tVCL_conf.director[0] = VCL_conf.director[%d];\n", Fi(tl, 0, "\tVCL_conf.director[0] = VCL_conf.director[%d];\n",
tl->defaultdir); tl->defaultdir);
vcc_AddRef(tl, tl->t_defaultdir, R_BACKEND); vcc_AddRef(tl, tl->t_defaultdir, SYM_BACKEND);
/* Check for orphans */ /* Check for orphans */
if (vcc_CheckReferences(tl)) if (vcc_CheckReferences(tl))
......
...@@ -37,6 +37,7 @@ ...@@ -37,6 +37,7 @@
#define INDENT 2 #define INDENT 2
struct acl_e; struct acl_e;
struct proc;
enum var_type { enum var_type {
#define VCC_TYPE(foo) foo, #define VCC_TYPE(foo) foo,
...@@ -69,11 +70,9 @@ struct token { ...@@ -69,11 +70,9 @@ struct token {
}; };
enum symkind { enum symkind {
SYM_NONE, #define VCC_SYMB(uu, ll, dd) SYM_##uu,
SYM_VAR, #include "symbol_kind.h"
SYM_FUNC, #undef VCC_SYMB
SYM_PROC,
SYM_VMOD
}; };
struct symbol { struct symbol {
...@@ -84,11 +83,14 @@ struct symbol { ...@@ -84,11 +83,14 @@ struct symbol {
char *name; char *name;
unsigned nlen; unsigned nlen;
unsigned wildcard; unsigned wildcard;
enum symkind kind; enum symkind kind;
unsigned nref, ndef;
const struct token *def_b, *def_e;
enum var_type fmt; enum var_type fmt;
struct token *def_b, *def_e; struct proc *proc;
const char *cfunc; const char *cfunc;
const char *args; const char *args;
...@@ -132,11 +134,9 @@ struct vcc { ...@@ -132,11 +134,9 @@ struct vcc {
* NULL otherwise * NULL otherwise
*/ */
struct vsb *fm[VCL_MET_MAX]; /* Method bodies */ struct vsb *fm[VCL_MET_MAX]; /* Method bodies */
VTAILQ_HEAD(, ref) refs;
struct vsb *sb; struct vsb *sb;
int err; int err;
int ndirector; int ndirector;
VTAILQ_HEAD(, proc) procs;
struct proc *curproc; struct proc *curproc;
struct proc *mprocs[VCL_MET_MAX]; struct proc *mprocs[VCL_MET_MAX];
...@@ -154,21 +154,6 @@ struct vcc { ...@@ -154,21 +154,6 @@ struct vcc {
unsigned nvmodpriv; unsigned nvmodpriv;
}; };
enum ref_type {
R_SUB,
R_ACL,
R_BACKEND,
R_PROBE
};
struct ref {
enum ref_type type;
struct token *name;
unsigned defcnt;
unsigned refcnt;
VTAILQ_ENTRY(ref) list;
};
struct var { struct var {
const char *name; const char *name;
enum var_type fmt; enum var_type fmt;
...@@ -260,9 +245,14 @@ int vcc_StringVal(struct vcc *tl); ...@@ -260,9 +245,14 @@ int vcc_StringVal(struct vcc *tl);
void vcc_ExpectedStringval(struct vcc *tl); void vcc_ExpectedStringval(struct vcc *tl);
/* vcc_symbol */ /* vcc_symbol */
struct symbol *VCC_AddSymbol(struct vcc *tl, const char *name, enum symkind); struct symbol *VCC_AddSymbolStr(struct vcc *tl, const char *name, enum symkind);
const struct symbol *VCC_FindSymbol(const struct vcc *tl, struct symbol *VCC_GetSymbolTok(struct vcc *tl, const struct token *tok,
const struct token *t); enum symkind);
struct symbol *VCC_FindSymbol(const struct vcc *tl,
const struct token *t, enum symkind kind);
const char * VCC_SymKind(struct vcc *tl, const struct symbol *s);
typedef void symwalk_f(struct vcc *tl, const struct symbol *s);
void VCC_WalkSymbols(struct vcc *tl, symwalk_f *func, enum symkind kind);
/* vcc_token.c */ /* vcc_token.c */
void vcc_Coord(const struct vcc *tl, struct vsb *vsb, void vcc_Coord(const struct vcc *tl, struct vsb *vsb,
...@@ -292,8 +282,8 @@ void vcc_VarVal(struct vcc *tl, const struct var *vp, ...@@ -292,8 +282,8 @@ void vcc_VarVal(struct vcc *tl, const struct var *vp,
void vcc_ParseImport(struct vcc *tl); void vcc_ParseImport(struct vcc *tl);
/* vcc_xref.c */ /* vcc_xref.c */
void vcc_AddDef(struct vcc *tl, struct token *t, enum ref_type type); void vcc_AddDef(struct vcc *tl, const struct token *t, enum symkind type);
void vcc_AddRef(struct vcc *tl, struct token *t, enum ref_type type); void vcc_AddRef(struct vcc *tl, const struct token *t, enum symkind type);
int vcc_CheckReferences(struct vcc *tl); int vcc_CheckReferences(struct vcc *tl);
void vcc_AddCall(struct vcc *tl, struct token *t); void vcc_AddCall(struct vcc *tl, struct token *t);
......
...@@ -540,13 +540,13 @@ vcc_expr4(struct vcc *tl, struct expr **e, enum var_type fmt) ...@@ -540,13 +540,13 @@ vcc_expr4(struct vcc *tl, struct expr **e, enum var_type fmt)
} }
if (fmt == BACKEND) { if (fmt == BACKEND) {
vcc_ExpectCid(tl); vcc_ExpectCid(tl);
vcc_AddRef(tl, tl->t, R_BACKEND); vcc_AddRef(tl, tl->t, SYM_BACKEND);
vsb_printf(e1->vsb, "VGCDIR(_%.*s)", PF(tl->t)); vsb_printf(e1->vsb, "VGCDIR(_%.*s)", PF(tl->t));
e1->fmt = BACKEND; e1->fmt = BACKEND;
vcc_NextToken(tl); vcc_NextToken(tl);
break; break;
} }
sym = VCC_FindSymbol(tl, tl->t); sym = VCC_FindSymbol(tl, tl->t, SYM_NONE);
if (sym == NULL) { if (sym == NULL) {
vsb_printf(tl->sb, "Symbol not found: "); vsb_printf(tl->sb, "Symbol not found: ");
vcc_ErrToken(tl, tl->t); vcc_ErrToken(tl, tl->t);
...@@ -687,9 +687,10 @@ vcc_expr_add(struct vcc *tl, struct expr **e, enum var_type fmt) ...@@ -687,9 +687,10 @@ vcc_expr_add(struct vcc *tl, struct expr **e, enum var_type fmt)
while (tl->t->tok == '+') { while (tl->t->tok == '+') {
vcc_NextToken(tl); vcc_NextToken(tl);
vcc_expr_mul(tl, &e2, STRING); vcc_expr_mul(tl, &e2, STRING);
ERRCHK(tl);
if (e2->fmt != STRING && e2->fmt != STRING_LIST) if (e2->fmt != STRING && e2->fmt != STRING_LIST)
vcc_expr_tostring(&e2, f2); vcc_expr_tostring(&e2, f2);
ERRCHK(tl); ERRCHK(tl);
assert(e2->fmt == STRING || e2->fmt == STRING_LIST); assert(e2->fmt == STRING || e2->fmt == STRING_LIST);
if ((*e)->constant && e2->constant) { if ((*e)->constant && e2->constant) {
assert((*e)->fmt == STRING); assert((*e)->fmt == STRING);
...@@ -833,7 +834,7 @@ vcc_expr_cmp(struct vcc *tl, struct expr **e, enum var_type fmt) ...@@ -833,7 +834,7 @@ vcc_expr_cmp(struct vcc *tl, struct expr **e, enum var_type fmt)
not = tl->t->tok == '~' ? "" : "!"; not = tl->t->tok == '~' ? "" : "!";
vcc_NextToken(tl); vcc_NextToken(tl);
ExpectErr(tl, ID); ExpectErr(tl, ID);
vcc_AddRef(tl, tl->t, R_ACL); vcc_AddRef(tl, tl->t, SYM_ACL);
bprintf(buf, "%smatch_acl_named_%.*s(sp, \v1)", not, PF(tl->t)); bprintf(buf, "%smatch_acl_named_%.*s(sp, \v1)", not, PF(tl->t));
vcc_NextToken(tl); vcc_NextToken(tl);
*e = vcc_expr_edit(BOOL, buf, *e, NULL); *e = vcc_expr_edit(BOOL, buf, *e, NULL);
...@@ -848,7 +849,7 @@ vcc_expr_cmp(struct vcc *tl, struct expr **e, enum var_type fmt) ...@@ -848,7 +849,7 @@ vcc_expr_cmp(struct vcc *tl, struct expr **e, enum var_type fmt)
(tl->t->tok == T_EQ || tl->t->tok == T_NEQ)) { (tl->t->tok == T_EQ || tl->t->tok == T_NEQ)) {
vcc_NextToken(tl); vcc_NextToken(tl);
ExpectErr(tl, ID); ExpectErr(tl, ID);
vcc_AddRef(tl, tl->t, R_BACKEND); vcc_AddRef(tl, tl->t, SYM_BACKEND);
bprintf(buf, "(\v1 %.*s VGCDIR(_%.*s))", PF(tk), PF(tl->t)); bprintf(buf, "(\v1 %.*s VGCDIR(_%.*s))", PF(tk), PF(tl->t));
vcc_NextToken(tl); vcc_NextToken(tl);
*e = vcc_expr_edit(BOOL, buf, *e, NULL); *e = vcc_expr_edit(BOOL, buf, *e, NULL);
...@@ -867,6 +868,8 @@ vcc_expr_cmp(struct vcc *tl, struct expr **e, enum var_type fmt) ...@@ -867,6 +868,8 @@ vcc_expr_cmp(struct vcc *tl, struct expr **e, enum var_type fmt)
PF(tl->t), vcc_Type((*e)->fmt)); PF(tl->t), vcc_Type((*e)->fmt));
vcc_ErrWhere(tl, tl->t); vcc_ErrWhere(tl, tl->t);
return; return;
default:
break;
} }
if (fmt == BOOL && (*e)->fmt == STRING) { if (fmt == BOOL && (*e)->fmt == STRING) {
*e = vcc_expr_edit(BOOL, "(\v1 != 0)", *e, NULL); *e = vcc_expr_edit(BOOL, "(\v1 != 0)", *e, NULL);
......
...@@ -207,9 +207,9 @@ vcc_Function(struct vcc *tl) ...@@ -207,9 +207,9 @@ vcc_Function(struct vcc *tl)
assert(m < VCL_MET_MAX); assert(m < VCL_MET_MAX);
tl->fb = tl->fm[m]; tl->fb = tl->fm[m];
if (tl->mprocs[m] == NULL) { if (tl->mprocs[m] == NULL) {
vcc_AddDef(tl, tl->t, SYM_SUB);
vcc_AddRef(tl, tl->t, SYM_SUB);
tl->mprocs[m] = vcc_AddProc(tl, tl->t); tl->mprocs[m] = vcc_AddProc(tl, tl->t);
vcc_AddDef(tl, tl->t, R_SUB);
vcc_AddRef(tl, tl->t, R_SUB);
} }
tl->curproc = tl->mprocs[m]; tl->curproc = tl->mprocs[m];
Fb(tl, 1, " /* ... from "); Fb(tl, 1, " /* ... from ");
...@@ -217,8 +217,8 @@ vcc_Function(struct vcc *tl) ...@@ -217,8 +217,8 @@ vcc_Function(struct vcc *tl)
Fb(tl, 0, " */\n"); Fb(tl, 0, " */\n");
} else { } else {
tl->fb = tl->fc; tl->fb = tl->fc;
vcc_AddDef(tl, tl->t, SYM_SUB);
tl->curproc = vcc_AddProc(tl, tl->t); tl->curproc = vcc_AddProc(tl, tl->t);
vcc_AddDef(tl, tl->t, R_SUB);
Fh(tl, 0, "static int VGC_function_%.*s (struct sess *sp);\n", Fh(tl, 0, "static int VGC_function_%.*s (struct sess *sp);\n",
PF(tl->t)); PF(tl->t));
Fc(tl, 1, "\nstatic int\n"); Fc(tl, 1, "\nstatic int\n");
......
...@@ -43,35 +43,80 @@ SVNID("$Id$") ...@@ -43,35 +43,80 @@ SVNID("$Id$")
/*--------------------------------------------------------------------*/ /*--------------------------------------------------------------------*/
const char *
VCC_SymKind(struct vcc *tl, const struct symbol *s)
{
switch(s->kind) {
#define VCC_SYMB(uu, ll, dd) case SYM_##uu: return(dd);
#include "symbol_kind.h"
#undef VCC_SYMB
default:
ErrInternal(tl);
vsb_printf(tl->sb, "Symbol Kind 0x%x\n", s->kind);
return("INTERNALERROR");
}
}
struct symbol *
VCC_AddSymbol(struct vcc *tl, const char *name, enum symkind kind) static struct symbol *
vcc_AddSymbol(struct vcc *tl, const char *nb, int l, enum symkind kind)
{ {
struct symbol *sym; struct symbol *sym;
VTAILQ_FOREACH(sym, &tl->symbols, list) { VTAILQ_FOREACH(sym, &tl->symbols, list) {
if (strcmp(name, sym->name)) if (sym->nlen != l)
continue;
if (memcmp(nb, sym->name, l))
continue; continue;
printf("%s <> %s\n", name, sym->name); if (kind != sym->kind)
WRONG("name collision"); continue;
vsb_printf(tl->sb, "Name Collision: <%.*s> <%s>\n",
l, nb, VCC_SymKind(tl, sym));
ErrInternal(tl);
return (NULL);
} }
ALLOC_OBJ(sym, SYMBOL_MAGIC); ALLOC_OBJ(sym, SYMBOL_MAGIC);
AN(sym); AN(sym);
REPLACE(sym->name, name); sym->name = malloc(l + 1);
AN(name); AN(sym->name);
sym->nlen = strlen(name); memcpy(sym->name, nb, l);
sym->name[l] = '\0';
sym->nlen = l;
VTAILQ_INSERT_TAIL(&tl->symbols, sym, list); VTAILQ_INSERT_TAIL(&tl->symbols, sym, list);
sym->kind = kind; sym->kind = kind;
return (sym); return (sym);
} }
const struct symbol * struct symbol *
VCC_FindSymbol(const struct vcc *tl, const struct token *t) VCC_AddSymbolStr(struct vcc *tl, const char *name, enum symkind kind)
{
return (vcc_AddSymbol(tl, name, strlen(name), kind));
}
struct symbol *
VCC_GetSymbolTok(struct vcc *tl, const struct token *tok, enum symkind kind)
{
struct symbol *sym;
sym = VCC_FindSymbol(tl, tok, kind);
if (sym == NULL) {
sym = vcc_AddSymbol(tl, tok->b, tok->e - tok->b, kind);
AN(sym);
sym->def_b = tok;
}
return (sym);
}
struct symbol *
VCC_FindSymbol(const struct vcc *tl, const struct token *t, enum symkind kind)
{ {
struct symbol *sym; struct symbol *sym;
assert(t->tok == ID); assert(t->tok == ID);
VTAILQ_FOREACH(sym, &tl->symbols, list) { VTAILQ_FOREACH(sym, &tl->symbols, list) {
if (kind != SYM_NONE && kind != sym->kind)
continue;
if (!sym->wildcard) { if (!sym->wildcard) {
if (vcc_IdIs(t, sym->name)) if (vcc_IdIs(t, sym->name))
return (sym); return (sym);
...@@ -84,3 +129,15 @@ VCC_FindSymbol(const struct vcc *tl, const struct token *t) ...@@ -84,3 +129,15 @@ VCC_FindSymbol(const struct vcc *tl, const struct token *t)
} }
return (NULL); return (NULL);
} }
void
VCC_WalkSymbols(struct vcc *tl, symwalk_f *func, enum symkind kind)
{
struct symbol *sym;
VTAILQ_FOREACH(sym, &tl->symbols, list) {
if (kind == SYM_NONE || kind == sym->kind)
func(tl, sym);
ERRCHK(tl);
}
}
...@@ -94,7 +94,7 @@ vcc_FindVar(struct vcc *tl, const struct token *t, int wr_access, ...@@ -94,7 +94,7 @@ vcc_FindVar(struct vcc *tl, const struct token *t, int wr_access,
const struct symbol *sym; const struct symbol *sym;
AN(tl->vars); AN(tl->vars);
sym = VCC_FindSymbol(tl, t); sym = VCC_FindSymbol(tl, t, SYM_NONE);
if (sym != NULL) { if (sym != NULL) {
v = sym->var; v = sym->var;
AN(v); AN(v);
......
...@@ -63,7 +63,7 @@ vcc_ParseImport(struct vcc *tl) ...@@ -63,7 +63,7 @@ vcc_ParseImport(struct vcc *tl)
vcc_NextToken(tl); vcc_NextToken(tl);
osym = VCC_FindSymbol(tl, mod); osym = VCC_FindSymbol(tl, mod, SYM_NONE);
if (osym != NULL && osym->kind != SYM_VMOD) { if (osym != NULL && osym->kind != SYM_VMOD) {
vsb_printf(tl->sb, "Module %.*s conflics with other symbol.\n", vsb_printf(tl->sb, "Module %.*s conflics with other symbol.\n",
PF(mod)); PF(mod));
...@@ -80,7 +80,9 @@ vcc_ParseImport(struct vcc *tl) ...@@ -80,7 +80,9 @@ vcc_ParseImport(struct vcc *tl)
} }
bprintf(fn, "%.*s", PF(mod)); bprintf(fn, "%.*s", PF(mod));
sym = VCC_AddSymbol(tl, fn, SYM_VMOD); sym = VCC_AddSymbolStr(tl, fn, SYM_VMOD);
ERRCHK(tl);
AN(sym);
sym->def_b = t1; sym->def_b = t1;
sym->def_e = tl->t; sym->def_e = tl->t;
...@@ -150,7 +152,9 @@ vcc_ParseImport(struct vcc *tl) ...@@ -150,7 +152,9 @@ vcc_ParseImport(struct vcc *tl)
p += strlen(p) + 1; p += strlen(p) + 1;
Fi(tl, 0, "\t%s(&vmod_priv_%.*s, &VCL_conf);\n", p, PF(mod)); Fi(tl, 0, "\t%s(&vmod_priv_%.*s, &VCL_conf);\n", p, PF(mod));
} else { } else {
sym = VCC_AddSymbol(tl, p, SYM_FUNC); sym = VCC_AddSymbolStr(tl, p, SYM_FUNC);
ERRCHK(tl);
AN(sym);
p += strlen(p) + 1; p += strlen(p) + 1;
sym->cfunc = p; sym->cfunc = p;
p += strlen(p) + 1; p += strlen(p) + 1;
......
...@@ -66,7 +66,6 @@ struct procuse { ...@@ -66,7 +66,6 @@ struct procuse {
}; };
struct proc { struct proc {
VTAILQ_ENTRY(proc) list;
VTAILQ_HEAD(,proccall) calls; VTAILQ_HEAD(,proccall) calls;
VTAILQ_HEAD(,procuse) uses; VTAILQ_HEAD(,procuse) uses;
struct token *name; struct token *name;
...@@ -77,106 +76,53 @@ struct proc { ...@@ -77,106 +76,53 @@ struct proc {
struct token *return_tok[VCL_RET_MAX]; struct token *return_tok[VCL_RET_MAX];
}; };
/*--------------------------------------------------------------------*/
static const char *
vcc_typename(struct vcc *tl, const struct ref *r)
{
switch (r->type) {
case R_SUB: return ("subroutine");
case R_ACL: return ("acl");
case R_BACKEND: return ("backend");
case R_PROBE: return ("probe");
default:
ErrInternal(tl);
vsb_printf(tl->sb, "Ref ");
vcc_ErrToken(tl, r->name);
vsb_printf(tl->sb, " has unknown type %d\n",
r->type);
return "?";
}
}
/*-------------------------------------------------------------------- /*--------------------------------------------------------------------
* Keep track of definitions and references * Keep track of definitions and references
*/ */
static struct ref * void
vcc_findref(struct vcc *tl, struct token *t, enum ref_type type) vcc_AddRef(struct vcc *tl, const struct token *t, enum symkind kind)
{ {
struct ref *r; struct symbol *sym;
VTAILQ_FOREACH(r, &tl->refs, list) { sym = VCC_GetSymbolTok(tl, t, kind);
if (r->type != type) AN(sym);
continue; sym->nref++;
if (vcc_Teq(r->name, t))
return (r);
}
r = TlAlloc(tl, sizeof *r);
assert(r != NULL);
r->name = t;
r->type = type;
VTAILQ_INSERT_TAIL(&tl->refs, r, list);
return (r);
} }
void void
vcc_AddRef(struct vcc *tl, struct token *t, enum ref_type type) vcc_AddDef(struct vcc *tl, const struct token *t, enum symkind kind)
{ {
struct symbol *sym;
vcc_findref(tl, t, type)->refcnt++; sym = VCC_GetSymbolTok(tl, t, kind);
AN(sym);
sym->ndef++;
} }
void /*--------------------------------------------------------------------*/
vcc_AddDef(struct vcc *tl, struct token *t, enum ref_type type)
static void
vcc_checkref(struct vcc *tl, const struct symbol *sym)
{ {
struct ref *r;
const char *tp; if (sym->ndef == 0 && sym->nref != 0) {
vsb_printf(tl->sb, "Undefined %s %.*s, first reference:\n",
r = vcc_findref(tl, t, type); VCC_SymKind(tl, sym), PF(sym->def_b));
if (r->defcnt > 0) { vcc_ErrWhere(tl, sym->def_b);
tp = vcc_typename(tl, r); } else if (sym->ndef != 0 && sym->nref == 0) {
vsb_printf(tl->sb, "Multiple definitions of %s \"%.*s\"\n", vsb_printf(tl->sb, "Unused %s %.*s, defined:\n",
tp, PF(t)); VCC_SymKind(tl, sym), PF(sym->def_b));
vcc_ErrWhere(tl, r->name); vcc_ErrWhere(tl, sym->def_b);
vsb_printf(tl->sb, "...and\n");
vcc_ErrWhere(tl, t);
} }
r->defcnt++;
r->name = t;
} }
/*--------------------------------------------------------------------*/
int int
vcc_CheckReferences(struct vcc *tl) vcc_CheckReferences(struct vcc *tl)
{ {
struct ref *r;
const char *type;
int nerr = 0;
const char *sep = "";
VTAILQ_FOREACH(r, &tl->refs, list) {
if (r->defcnt != 0 && r->refcnt != 0)
continue;
nerr++;
type = vcc_typename(tl, r);
if (r->defcnt == 0) {
vsb_printf(tl->sb,
"%sUndefined %s %.*s, first reference:\n",
sep, type, PF(r->name));
vcc_ErrWhere(tl, r->name);
continue;
}
vsb_printf(tl->sb, "%sUnused %s %.*s, defined:\n", VCC_WalkSymbols(tl, vcc_checkref, SYM_NONE);
sep, type, PF(r->name)); return (tl->err);
vcc_ErrWhere(tl, r->name);
sep = "\n";
}
return (nerr);
} }
/*-------------------------------------------------------------------- /*--------------------------------------------------------------------
...@@ -186,17 +132,21 @@ vcc_CheckReferences(struct vcc *tl) ...@@ -186,17 +132,21 @@ vcc_CheckReferences(struct vcc *tl)
static struct proc * static struct proc *
vcc_findproc(struct vcc *tl, struct token *t) vcc_findproc(struct vcc *tl, struct token *t)
{ {
struct symbol *sym;
struct proc *p; struct proc *p;
VTAILQ_FOREACH(p, &tl->procs, list)
if (vcc_Teq(p->name, t)) sym = VCC_GetSymbolTok(tl, t, SYM_SUB);
return (p); AN(sym);
if (sym->proc != NULL)
return (sym->proc);
p = TlAlloc(tl, sizeof *p); p = TlAlloc(tl, sizeof *p);
assert(p != NULL); assert(p != NULL);
VTAILQ_INIT(&p->calls); VTAILQ_INIT(&p->calls);
VTAILQ_INIT(&p->uses); VTAILQ_INIT(&p->uses);
VTAILQ_INSERT_TAIL(&tl->procs, p, list);
p->name = t; p->name = t;
sym->proc = p;
return (p); return (p);
} }
...@@ -298,42 +248,64 @@ vcc_CheckActionRecurse(struct vcc *tl, struct proc *p, unsigned bitmap) ...@@ -298,42 +248,64 @@ vcc_CheckActionRecurse(struct vcc *tl, struct proc *p, unsigned bitmap)
return (0); return (0);
} }
int /*--------------------------------------------------------------------*/
vcc_CheckAction(struct vcc *tl)
static void
vcc_checkaction1(struct vcc *tl, const struct symbol *sym)
{ {
struct proc *p; struct proc *p;
struct method *m; struct method *m;
int i; int i;
VTAILQ_FOREACH(p, &tl->procs, list) { p = sym->proc;
i = IsMethod(p->name); AN(p);
if (i < 0) i = IsMethod(p->name);
continue; if (i < 0)
m = method_tab + i; return;
if (vcc_CheckActionRecurse(tl, p, m->ret_bitmap)) { m = method_tab + i;
vsb_printf(tl->sb, if (vcc_CheckActionRecurse(tl, p, m->ret_bitmap)) {
"\n...which is the \"%s\" method\n", m->name); vsb_printf(tl->sb,
vsb_printf(tl->sb, "Legal returns are:"); "\n...which is the \"%s\" method\n", m->name);
vsb_printf(tl->sb, "Legal returns are:");
#define VCL_RET_MAC(l, U, B) \ #define VCL_RET_MAC(l, U, B) \
if (m->ret_bitmap & ((1 << VCL_RET_##U))) \ if (m->ret_bitmap & ((1 << VCL_RET_##U))) \
vsb_printf(tl->sb, " \"%s\"", #l); vsb_printf(tl->sb, " \"%s\"", #l);
#include "vcl_returns.h" #include "vcl_returns.h"
#undef VCL_RET_MAC #undef VCL_RET_MAC
vsb_printf(tl->sb, "\n"); vsb_printf(tl->sb, "\n");
return (1); tl->err = 1;
}
} }
VTAILQ_FOREACH(p, &tl->procs, list) {
if (p->called)
continue;
vsb_printf(tl->sb, "Function unused\n");
vcc_ErrWhere(tl, p->name);
return (1);
}
return (0);
} }
static void
vcc_checkaction2(struct vcc *tl, const struct symbol *sym)
{
struct proc *p;
p = sym->proc;
AN(p);
if (p->called)
return;
vsb_printf(tl->sb, "Function unused\n");
vcc_ErrWhere(tl, p->name);
}
int
vcc_CheckAction(struct vcc *tl)
{
VCC_WalkSymbols(tl, vcc_checkaction1, SYM_SUB);
if (tl->err)
return (tl->err);
VCC_WalkSymbols(tl, vcc_checkaction2, SYM_SUB);
return (tl->err);
}
/*--------------------------------------------------------------------*/
static struct procuse * static struct procuse *
vcc_FindIllegalUse(const struct proc *p, const struct method *m) vcc_FindIllegalUse(const struct proc *p, const struct method *m)
{ {
...@@ -374,34 +346,41 @@ vcc_CheckUseRecurse(struct vcc *tl, const struct proc *p, ...@@ -374,34 +346,41 @@ vcc_CheckUseRecurse(struct vcc *tl, const struct proc *p,
return (0); return (0);
} }
int static void
vcc_CheckUses(struct vcc *tl) vcc_checkuses(struct vcc *tl, const struct symbol *sym)
{ {
struct proc *p; struct proc *p;
struct method *m; struct method *m;
struct procuse *pu; struct procuse *pu;
int i; int i;
VTAILQ_FOREACH(p, &tl->procs, list) { p = sym->proc;
i = IsMethod(p->name); AN(p);
if (i < 0)
continue; i = IsMethod(p->name);
m = method_tab + i; if (i < 0)
pu = vcc_FindIllegalUse(p, m); return;
if (pu != NULL) { m = method_tab + i;
vsb_printf(tl->sb, pu = vcc_FindIllegalUse(p, m);
"'%.*s': %s in method '%.*s'.", if (pu != NULL) {
PF(pu->t), pu->use, PF(p->name)); vsb_printf(tl->sb,
vsb_cat(tl->sb, "\nAt: "); "'%.*s': %s in method '%.*s'.",
vcc_ErrWhere(tl, pu->t); PF(pu->t), pu->use, PF(p->name));
return (1); vsb_cat(tl->sb, "\nAt: ");
} vcc_ErrWhere(tl, pu->t);
if (vcc_CheckUseRecurse(tl, p, m)) { return;
vsb_printf(tl->sb, }
"\n...which is the \"%s\" method\n", m->name); if (vcc_CheckUseRecurse(tl, p, m)) {
return (1); vsb_printf(tl->sb,
} "\n...which is the \"%s\" method\n", m->name);
return;
} }
return (0);
} }
int
vcc_CheckUses(struct vcc *tl)
{
VCC_WalkSymbols(tl, vcc_checkuses, SYM_SUB);
return (tl->err);
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment