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 @@
-efile(451, "http_headers.h") // No include guard
-efile(451, "acct_fields.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
//////////////
// -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)
an = tl->t;
vcc_NextToken(tl);
vcc_AddDef(tl, an, R_ACL);
vcc_AddDef(tl, an, SYM_ACL);
bprintf(acln, "%.*s", PF(an));
SkipToken(tl, '{');
......
......@@ -53,7 +53,7 @@ parse_call(struct vcc *tl)
vcc_NextToken(tl);
ExpectErr(tl, ID);
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, "\treturn (1);\n");
vcc_NextToken(tl);
......@@ -447,7 +447,7 @@ vcc_ParseAction(struct vcc *tl)
return (1);
}
}
sym = VCC_FindSymbol(tl, tl->t);
sym = VCC_FindSymbol(tl, tl->t, SYM_NONE);
if (sym != NULL && sym->kind == SYM_PROC) {
vcc_Expr_Call(tl, sym);
return (1);
......
......@@ -422,7 +422,7 @@ vcc_ParseProbe(struct vcc *tl)
ERRCHK(tl);
t_probe = tl->t;
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",
PF(t_probe), tl->nprobe);
......@@ -554,7 +554,7 @@ vcc_ParseHostDef(struct vcc *tl, int serial, const char *vgcname)
ERRCHK(tl);
} else if (vcc_IdIs(t_field, "probe") && tl->t->tok == ID) {
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);
SkipToken(tl, ';');
} else if (vcc_IdIs(t_field, "probe")) {
......@@ -646,7 +646,7 @@ vcc_ParseBackendHost(struct vcc *tl, int serial, char **nm)
vcc_ErrWhere(tl, tl->t);
return;
}
vcc_AddRef(tl, h->name, R_BACKEND);
vcc_AddRef(tl, h->name, SYM_BACKEND);
vcc_NextToken(tl);
SkipToken(tl, ';');
*nm = h->vgcname;
......@@ -687,7 +687,7 @@ vcc_ParseSimpleDirector(struct vcc *tl)
h = TlAlloc(tl, sizeof *h);
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));
h->vgcname = TlAlloc(tl, strlen(vgcname) + 1);
strcpy(h->vgcname, vgcname);
......@@ -735,7 +735,7 @@ vcc_ParseDirector(struct vcc *tl)
tl->t_policy = t_first;
vcc_ParseSimpleDirector(tl);
} else {
vcc_AddDef(tl, tl->t_dir, R_BACKEND);
vcc_AddDef(tl, tl->t_dir, SYM_BACKEND);
ExpectErr(tl, ID); /* ID: policy */
tl->t_policy = tl->t;
vcc_NextToken(tl);
......
......@@ -477,8 +477,6 @@ vcc_NewVcc(const struct vcc *tl0)
VTAILQ_INIT(&tl->hosts);
VTAILQ_INIT(&tl->membits);
VTAILQ_INIT(&tl->tokens);
VTAILQ_INIT(&tl->refs);
VTAILQ_INIT(&tl->procs);
VTAILQ_INIT(&tl->sources);
tl->nsources = 0;
......@@ -564,7 +562,7 @@ vcc_CompileSource(const struct vcc *tl0, struct vsb *sb, struct source *sp)
tl->sb = sb;
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->fmt = v->fmt;
sym->r_methods = v->r_methods;
......@@ -623,7 +621,7 @@ vcc_CompileSource(const struct vcc *tl0, struct vsb *sb, struct source *sp)
/* Configure the default director */
Fi(tl, 0, "\tVCL_conf.director[0] = VCL_conf.director[%d];\n",
tl->defaultdir);
vcc_AddRef(tl, tl->t_defaultdir, R_BACKEND);
vcc_AddRef(tl, tl->t_defaultdir, SYM_BACKEND);
/* Check for orphans */
if (vcc_CheckReferences(tl))
......
......@@ -37,6 +37,7 @@
#define INDENT 2
struct acl_e;
struct proc;
enum var_type {
#define VCC_TYPE(foo) foo,
......@@ -69,11 +70,9 @@ struct token {
};
enum symkind {
SYM_NONE,
SYM_VAR,
SYM_FUNC,
SYM_PROC,
SYM_VMOD
#define VCC_SYMB(uu, ll, dd) SYM_##uu,
#include "symbol_kind.h"
#undef VCC_SYMB
};
struct symbol {
......@@ -84,11 +83,14 @@ struct symbol {
char *name;
unsigned nlen;
unsigned wildcard;
enum symkind kind;
unsigned nref, ndef;
const struct token *def_b, *def_e;
enum var_type fmt;
struct token *def_b, *def_e;
struct proc *proc;
const char *cfunc;
const char *args;
......@@ -132,11 +134,9 @@ struct vcc {
* NULL otherwise
*/
struct vsb *fm[VCL_MET_MAX]; /* Method bodies */
VTAILQ_HEAD(, ref) refs;
struct vsb *sb;
int err;
int ndirector;
VTAILQ_HEAD(, proc) procs;
struct proc *curproc;
struct proc *mprocs[VCL_MET_MAX];
......@@ -154,21 +154,6 @@ struct vcc {
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 {
const char *name;
enum var_type fmt;
......@@ -260,9 +245,14 @@ int vcc_StringVal(struct vcc *tl);
void vcc_ExpectedStringval(struct vcc *tl);
/* vcc_symbol */
struct symbol *VCC_AddSymbol(struct vcc *tl, const char *name, enum symkind);
const struct symbol *VCC_FindSymbol(const struct vcc *tl,
const struct token *t);
struct symbol *VCC_AddSymbolStr(struct vcc *tl, const char *name, enum symkind);
struct symbol *VCC_GetSymbolTok(struct vcc *tl, const struct token *tok,
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 */
void vcc_Coord(const struct vcc *tl, struct vsb *vsb,
......@@ -292,8 +282,8 @@ void vcc_VarVal(struct vcc *tl, const struct var *vp,
void vcc_ParseImport(struct vcc *tl);
/* vcc_xref.c */
void vcc_AddDef(struct vcc *tl, struct token *t, enum ref_type type);
void vcc_AddRef(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, const struct token *t, enum symkind type);
int vcc_CheckReferences(struct vcc *tl);
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)
}
if (fmt == BACKEND) {
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));
e1->fmt = BACKEND;
vcc_NextToken(tl);
break;
}
sym = VCC_FindSymbol(tl, tl->t);
sym = VCC_FindSymbol(tl, tl->t, SYM_NONE);
if (sym == NULL) {
vsb_printf(tl->sb, "Symbol not found: ");
vcc_ErrToken(tl, tl->t);
......@@ -687,9 +687,10 @@ vcc_expr_add(struct vcc *tl, struct expr **e, enum var_type fmt)
while (tl->t->tok == '+') {
vcc_NextToken(tl);
vcc_expr_mul(tl, &e2, STRING);
ERRCHK(tl);
if (e2->fmt != STRING && e2->fmt != STRING_LIST)
vcc_expr_tostring(&e2, f2);
ERRCHK(tl);
ERRCHK(tl);
assert(e2->fmt == STRING || e2->fmt == STRING_LIST);
if ((*e)->constant && e2->constant) {
assert((*e)->fmt == STRING);
......@@ -833,7 +834,7 @@ vcc_expr_cmp(struct vcc *tl, struct expr **e, enum var_type fmt)
not = tl->t->tok == '~' ? "" : "!";
vcc_NextToken(tl);
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));
vcc_NextToken(tl);
*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)
(tl->t->tok == T_EQ || tl->t->tok == T_NEQ)) {
vcc_NextToken(tl);
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));
vcc_NextToken(tl);
*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)
PF(tl->t), vcc_Type((*e)->fmt));
vcc_ErrWhere(tl, tl->t);
return;
default:
break;
}
if (fmt == BOOL && (*e)->fmt == STRING) {
*e = vcc_expr_edit(BOOL, "(\v1 != 0)", *e, NULL);
......
......@@ -207,9 +207,9 @@ vcc_Function(struct vcc *tl)
assert(m < VCL_MET_MAX);
tl->fb = tl->fm[m];
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);
vcc_AddDef(tl, tl->t, R_SUB);
vcc_AddRef(tl, tl->t, R_SUB);
}
tl->curproc = tl->mprocs[m];
Fb(tl, 1, " /* ... from ");
......@@ -217,8 +217,8 @@ vcc_Function(struct vcc *tl)
Fb(tl, 0, " */\n");
} else {
tl->fb = tl->fc;
vcc_AddDef(tl, tl->t, SYM_SUB);
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",
PF(tl->t));
Fc(tl, 1, "\nstatic int\n");
......
......@@ -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;
VTAILQ_FOREACH(sym, &tl->symbols, list) {
if (strcmp(name, sym->name))
if (sym->nlen != l)
continue;
if (memcmp(nb, sym->name, l))
continue;
printf("%s <> %s\n", name, sym->name);
WRONG("name collision");
if (kind != sym->kind)
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);
AN(sym);
REPLACE(sym->name, name);
AN(name);
sym->nlen = strlen(name);
sym->name = malloc(l + 1);
AN(sym->name);
memcpy(sym->name, nb, l);
sym->name[l] = '\0';
sym->nlen = l;
VTAILQ_INSERT_TAIL(&tl->symbols, sym, list);
sym->kind = kind;
return (sym);
}
const struct symbol *
VCC_FindSymbol(const struct vcc *tl, const struct token *t)
struct symbol *
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;
assert(t->tok == ID);
VTAILQ_FOREACH(sym, &tl->symbols, list) {
if (kind != SYM_NONE && kind != sym->kind)
continue;
if (!sym->wildcard) {
if (vcc_IdIs(t, sym->name))
return (sym);
......@@ -84,3 +129,15 @@ VCC_FindSymbol(const struct vcc *tl, const struct token *t)
}
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,
const struct symbol *sym;
AN(tl->vars);
sym = VCC_FindSymbol(tl, t);
sym = VCC_FindSymbol(tl, t, SYM_NONE);
if (sym != NULL) {
v = sym->var;
AN(v);
......
......@@ -63,7 +63,7 @@ vcc_ParseImport(struct vcc *tl)
vcc_NextToken(tl);
osym = VCC_FindSymbol(tl, mod);
osym = VCC_FindSymbol(tl, mod, SYM_NONE);
if (osym != NULL && osym->kind != SYM_VMOD) {
vsb_printf(tl->sb, "Module %.*s conflics with other symbol.\n",
PF(mod));
......@@ -80,7 +80,9 @@ vcc_ParseImport(struct vcc *tl)
}
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_e = tl->t;
......@@ -150,7 +152,9 @@ vcc_ParseImport(struct vcc *tl)
p += strlen(p) + 1;
Fi(tl, 0, "\t%s(&vmod_priv_%.*s, &VCL_conf);\n", p, PF(mod));
} else {
sym = VCC_AddSymbol(tl, p, SYM_FUNC);
sym = VCC_AddSymbolStr(tl, p, SYM_FUNC);
ERRCHK(tl);
AN(sym);
p += strlen(p) + 1;
sym->cfunc = p;
p += strlen(p) + 1;
......
......@@ -66,7 +66,6 @@ struct procuse {
};
struct proc {
VTAILQ_ENTRY(proc) list;
VTAILQ_HEAD(,proccall) calls;
VTAILQ_HEAD(,procuse) uses;
struct token *name;
......@@ -77,106 +76,53 @@ struct proc {
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
*/
static struct ref *
vcc_findref(struct vcc *tl, struct token *t, enum ref_type type)
void
vcc_AddRef(struct vcc *tl, const struct token *t, enum symkind kind)
{
struct ref *r;
struct symbol *sym;
VTAILQ_FOREACH(r, &tl->refs, list) {
if (r->type != type)
continue;
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);
sym = VCC_GetSymbolTok(tl, t, kind);
AN(sym);
sym->nref++;
}
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;
r = vcc_findref(tl, t, type);
if (r->defcnt > 0) {
tp = vcc_typename(tl, r);
vsb_printf(tl->sb, "Multiple definitions of %s \"%.*s\"\n",
tp, PF(t));
vcc_ErrWhere(tl, r->name);
vsb_printf(tl->sb, "...and\n");
vcc_ErrWhere(tl, t);
if (sym->ndef == 0 && sym->nref != 0) {
vsb_printf(tl->sb, "Undefined %s %.*s, first reference:\n",
VCC_SymKind(tl, sym), PF(sym->def_b));
vcc_ErrWhere(tl, sym->def_b);
} else if (sym->ndef != 0 && sym->nref == 0) {
vsb_printf(tl->sb, "Unused %s %.*s, defined:\n",
VCC_SymKind(tl, sym), PF(sym->def_b));
vcc_ErrWhere(tl, sym->def_b);
}
r->defcnt++;
r->name = t;
}
/*--------------------------------------------------------------------*/
int
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",
sep, type, PF(r->name));
vcc_ErrWhere(tl, r->name);
sep = "\n";
}
return (nerr);
VCC_WalkSymbols(tl, vcc_checkref, SYM_NONE);
return (tl->err);
}
/*--------------------------------------------------------------------
......@@ -186,17 +132,21 @@ vcc_CheckReferences(struct vcc *tl)
static struct proc *
vcc_findproc(struct vcc *tl, struct token *t)
{
struct symbol *sym;
struct proc *p;
VTAILQ_FOREACH(p, &tl->procs, list)
if (vcc_Teq(p->name, t))
return (p);
sym = VCC_GetSymbolTok(tl, t, SYM_SUB);
AN(sym);
if (sym->proc != NULL)
return (sym->proc);
p = TlAlloc(tl, sizeof *p);
assert(p != NULL);
VTAILQ_INIT(&p->calls);
VTAILQ_INIT(&p->uses);
VTAILQ_INSERT_TAIL(&tl->procs, p, list);
p->name = t;
sym->proc = p;
return (p);
}
......@@ -298,42 +248,64 @@ vcc_CheckActionRecurse(struct vcc *tl, struct proc *p, unsigned bitmap)
return (0);
}
int
vcc_CheckAction(struct vcc *tl)
/*--------------------------------------------------------------------*/
static void
vcc_checkaction1(struct vcc *tl, const struct symbol *sym)
{
struct proc *p;
struct method *m;
int i;
VTAILQ_FOREACH(p, &tl->procs, list) {
i = IsMethod(p->name);
if (i < 0)
continue;
m = method_tab + i;
if (vcc_CheckActionRecurse(tl, p, m->ret_bitmap)) {
vsb_printf(tl->sb,
"\n...which is the \"%s\" method\n", m->name);
vsb_printf(tl->sb, "Legal returns are:");
p = sym->proc;
AN(p);
i = IsMethod(p->name);
if (i < 0)
return;
m = method_tab + i;
if (vcc_CheckActionRecurse(tl, p, m->ret_bitmap)) {
vsb_printf(tl->sb,
"\n...which is the \"%s\" method\n", m->name);
vsb_printf(tl->sb, "Legal returns are:");
#define VCL_RET_MAC(l, U, B) \
if (m->ret_bitmap & ((1 << VCL_RET_##U))) \
vsb_printf(tl->sb, " \"%s\"", #l);
if (m->ret_bitmap & ((1 << VCL_RET_##U))) \
vsb_printf(tl->sb, " \"%s\"", #l);
#include "vcl_returns.h"
#undef VCL_RET_MAC
vsb_printf(tl->sb, "\n");
return (1);
}
vsb_printf(tl->sb, "\n");
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 *
vcc_FindIllegalUse(const struct proc *p, const struct method *m)
{
......@@ -374,34 +346,41 @@ vcc_CheckUseRecurse(struct vcc *tl, const struct proc *p,
return (0);
}
int
vcc_CheckUses(struct vcc *tl)
static void
vcc_checkuses(struct vcc *tl, const struct symbol *sym)
{
struct proc *p;
struct method *m;
struct procuse *pu;
int i;
VTAILQ_FOREACH(p, &tl->procs, list) {
i = IsMethod(p->name);
if (i < 0)
continue;
m = method_tab + i;
pu = vcc_FindIllegalUse(p, m);
if (pu != NULL) {
vsb_printf(tl->sb,
"'%.*s': %s in method '%.*s'.",
PF(pu->t), pu->use, PF(p->name));
vsb_cat(tl->sb, "\nAt: ");
vcc_ErrWhere(tl, pu->t);
return (1);
}
if (vcc_CheckUseRecurse(tl, p, m)) {
vsb_printf(tl->sb,
"\n...which is the \"%s\" method\n", m->name);
return (1);
}
p = sym->proc;
AN(p);
i = IsMethod(p->name);
if (i < 0)
return;
m = method_tab + i;
pu = vcc_FindIllegalUse(p, m);
if (pu != NULL) {
vsb_printf(tl->sb,
"'%.*s': %s in method '%.*s'.",
PF(pu->t), pu->use, PF(p->name));
vsb_cat(tl->sb, "\nAt: ");
vcc_ErrWhere(tl, pu->t);
return;
}
if (vcc_CheckUseRecurse(tl, p, m)) {
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