diff options
author | Ondřej Surý <ondrej@sury.org> | 2011-09-13 13:11:55 +0200 |
---|---|---|
committer | Ondřej Surý <ondrej@sury.org> | 2011-09-13 13:11:55 +0200 |
commit | 80f18fc933cf3f3e829c5455a1023d69f7b86e52 (patch) | |
tree | 4b825dc642cb6eb9a060e54bf8d69288fbee4904 /src/cmd/cc/dpchk.c | |
parent | 28592ee1ea1f5cdffcf85472f9de0285d928cf12 (diff) | |
download | golang-80f18fc933cf3f3e829c5455a1023d69f7b86e52.tar.gz |
Imported Upstream version 60
Diffstat (limited to 'src/cmd/cc/dpchk.c')
-rw-r--r-- | src/cmd/cc/dpchk.c | 724 |
1 files changed, 0 insertions, 724 deletions
diff --git a/src/cmd/cc/dpchk.c b/src/cmd/cc/dpchk.c deleted file mode 100644 index 42c245b56..000000000 --- a/src/cmd/cc/dpchk.c +++ /dev/null @@ -1,724 +0,0 @@ -// Inferno utils/cc/dpchk.c -// http://code.google.com/p/inferno-os/source/browse/utils/cc/dpchk.c -// -// Copyright © 1994-1999 Lucent Technologies Inc. All rights reserved. -// Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net) -// Portions Copyright © 1997-1999 Vita Nuova Limited -// Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com) -// Portions Copyright © 2004,2006 Bruce Ellis -// Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net) -// Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others -// Portions Copyright © 2009 The Go Authors. All rights reserved. -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. - -#include <u.h> -#include <ctype.h> -#include "cc.h" -#include "y.tab.h" - -enum -{ - Fnone = 0, - Fl, - Fvl, - Fignor, - Fstar, - Fadj, - - Fverb = 10, -}; - -typedef struct Tprot Tprot; -struct Tprot -{ - Type* type; - Bits flag; - Tprot* link; -}; - -typedef struct Tname Tname; -struct Tname -{ - char* name; - int param; - int count; - Tname* link; - Tprot* prot; -}; - -static Type* indchar; -static uchar flagbits[512]; -static char* lastfmt; -static int lastadj; -static int lastverb; -static int nstar; -static Tprot* tprot; -static Tname* tname; - -void -argflag(int c, int v) -{ - - switch(v) { - case Fignor: - case Fstar: - case Fl: - case Fvl: - flagbits[c] = v; - break; - case Fverb: - flagbits[c] = lastverb; -/*print("flag-v %c %d\n", c, lastadj);*/ - lastverb++; - break; - case Fadj: - flagbits[c] = lastadj; -/*print("flag-l %c %d\n", c, lastadj);*/ - lastadj++; - break; - } -} - -Bits -getflag(char *s) -{ - Bits flag; - int f; - Fmt fmt; - Rune c; - - flag = zbits; - nstar = 0; - fmtstrinit(&fmt); - for(;;) { - s += chartorune(&c, s); - if(c == 0 || c >= nelem(flagbits)) - break; - fmtrune(&fmt, c); - f = flagbits[c]; - switch(f) { - case Fnone: - argflag(c, Fverb); - f = flagbits[c]; - break; - case Fstar: - nstar++; - case Fignor: - continue; - case Fl: - if(bset(flag, Fl)) - flag = bor(flag, blsh(Fvl)); - } - flag = bor(flag, blsh(f)); - if(f >= Fverb) - break; - } - free(lastfmt); - lastfmt = fmtstrflush(&fmt); - return flag; -} - -static void -newprot(Sym *m, Type *t, char *s, Tprot **prot) -{ - Bits flag; - Tprot *l; - - if(t == T) { - warn(Z, "%s: newprot: type not defined", m->name); - return; - } - flag = getflag(s); - for(l=*prot; l; l=l->link) - if(beq(flag, l->flag) && sametype(t, l->type)) - return; - l = alloc(sizeof(*l)); - l->type = t; - l->flag = flag; - l->link = *prot; - *prot = l; -} - -static Tname* -newname(char *s, int p, int count) -{ - Tname *l; - - for(l=tname; l; l=l->link) - if(strcmp(l->name, s) == 0) { - if(p >= 0 && l->param != p) - yyerror("vargck %s already defined\n", s); - return l; - } - if(p < 0) - return nil; - - l = alloc(sizeof(*l)); - l->name = s; - l->param = p; - l->link = tname; - l->count = count; - tname = l; - return l; -} - -void -arginit(void) -{ - int i; - -/* debug['F'] = 1;*/ -/* debug['w'] = 1;*/ - - lastadj = Fadj; - lastverb = Fverb; - indchar = typ(TIND, types[TCHAR]); - - memset(flagbits, Fnone, sizeof(flagbits)); - - for(i='0'; i<='9'; i++) - argflag(i, Fignor); - argflag('.', Fignor); - argflag('#', Fignor); - argflag('u', Fignor); - argflag('h', Fignor); - argflag('+', Fignor); - argflag('-', Fignor); - - argflag('*', Fstar); - argflag('l', Fl); - - argflag('o', Fverb); - flagbits['x'] = flagbits['o']; - flagbits['X'] = flagbits['o']; -} - -static char* -getquoted(void) -{ - int c; - Rune r; - Fmt fmt; - - c = getnsc(); - if(c != '"') - return nil; - fmtstrinit(&fmt); - for(;;) { - r = getr(); - if(r == '\n') { - free(fmtstrflush(&fmt)); - return nil; - } - if(r == '"') - break; - fmtrune(&fmt, r); - } - free(lastfmt); - lastfmt = fmtstrflush(&fmt); - return strdup(lastfmt); -} - -void -pragvararg(void) -{ - Sym *s; - int n, c; - char *t; - Type *ty; - Tname *l; - - if(!debug['F']) - goto out; - s = getsym(); - if(s && strcmp(s->name, "argpos") == 0) - goto ckpos; - if(s && strcmp(s->name, "type") == 0) - goto cktype; - if(s && strcmp(s->name, "flag") == 0) - goto ckflag; - if(s && strcmp(s->name, "countpos") == 0) - goto ckcount; - yyerror("syntax in #pragma varargck"); - goto out; - -ckpos: -/*#pragma varargck argpos warn 2*/ - s = getsym(); - if(s == S) - goto bad; - n = getnsn(); - if(n < 0) - goto bad; - newname(s->name, n, 0); - goto out; - -ckcount: -/*#pragma varargck countpos name 2*/ - s = getsym(); - if(s == S) - goto bad; - n = getnsn(); - if(n < 0) - goto bad; - newname(s->name, 0, n); - goto out; - -ckflag: -/*#pragma varargck flag 'c'*/ - c = getnsc(); - if(c != '\'') - goto bad; - c = getr(); - if(c == '\\') - c = getr(); - else if(c == '\'') - goto bad; - if(c == '\n') - goto bad; - if(getc() != '\'') - goto bad; - argflag(c, Fignor); - goto out; - -cktype: - c = getnsc(); - unget(c); - if(c != '"') { -/*#pragma varargck type name int*/ - s = getsym(); - if(s == S) - goto bad; - l = newname(s->name, -1, -1); - s = getsym(); - if(s == S) - goto bad; - ty = s->type; - while((c = getnsc()) == '*') - ty = typ(TIND, ty); - unget(c); - newprot(s, ty, "a", &l->prot); - goto out; - } - -/*#pragma varargck type O int*/ - t = getquoted(); - if(t == nil) - goto bad; - s = getsym(); - if(s == S) - goto bad; - ty = s->type; - while((c = getnsc()) == '*') - ty = typ(TIND, ty); - unget(c); - newprot(s, ty, t, &tprot); - goto out; - -bad: - yyerror("syntax in #pragma varargck"); - -out: - while(getnsc() != '\n') - ; -} - -Node* -nextarg(Node *n, Node **a) -{ - if(n == Z) { - *a = Z; - return Z; - } - if(n->op == OLIST) { - *a = n->left; - return n->right; - } - *a = n; - return Z; -} - -void -checkargs(Node *nn, char *s, int pos) -{ - Node *a, *n; - Bits flag; - Tprot *l; - - if(!debug['F']) - return; - n = nn; - for(;;) { - s = strchr(s, '%'); - if(s == 0) { - nextarg(n, &a); - if(a != Z) - warn(nn, "more arguments than format %T", - a->type); - return; - } - s++; - flag = getflag(s); - while(nstar > 0) { - n = nextarg(n, &a); - pos++; - nstar--; - if(a == Z) { - warn(nn, "more format than arguments %s", - lastfmt); - return; - } - if(a->type == T) - continue; - if(!sametype(types[TINT], a->type) && - !sametype(types[TUINT], a->type)) - warn(nn, "format mismatch '*' in %s %T, arg %d", - lastfmt, a->type, pos); - } - for(l=tprot; l; l=l->link) - if(sametype(types[TVOID], l->type)) { - if(beq(flag, l->flag)) { - s++; - goto loop; - } - } - - n = nextarg(n, &a); - pos++; - if(a == Z) { - warn(nn, "more format than arguments %s", - lastfmt); - return; - } - if(a->type == 0) - continue; - for(l=tprot; l; l=l->link) - if(sametype(a->type, l->type)) { -/*print("checking %T/%ux %T/%ux\n", a->type, flag.b[0], l->type, l->flag.b[0]);*/ - if(beq(flag, l->flag)) - goto loop; - } - warn(nn, "format mismatch %s %T, arg %d", lastfmt, a->type, pos); - loop:; - } -} - -void -dpcheck(Node *n) -{ - char *s; - Node *a, *b; - Tname *l; - Tprot *tl; - int i, j; - - if(n == Z) - return; - b = n->left; - if(b == Z || b->op != ONAME) - return; - s = b->sym->name; - for(l=tname; l; l=l->link) - if(strcmp(s, l->name) == 0) - break; - if(l == 0) - return; - - if(l->count > 0) { - // fetch count, then check remaining length - i = l->count; - a = nil; - b = n->right; - while(i > 0) { - b = nextarg(b, &a); - i--; - } - if(a == Z) { - diag(n, "can't find count arg"); - return; - } - if(a->op != OCONST || !typechl[a->type->etype]) { - diag(n, "count is invalid constant"); - return; - } - j = a->vconst; - i = 0; - while(b != Z) { - b = nextarg(b, &a); - i++; - } - if(i != j) - diag(n, "found %d argument%s after count %d", i, i == 1 ? "" : "s", j); - } - - if(l->prot != nil) { - // check that all arguments after param or count - // are listed in type list. - i = l->count; - if(i == 0) - i = l->param; - if(i == 0) - return; - a = nil; - b = n->right; - while(i > 0) { - b = nextarg(b, &a); - i--; - } - if(a == Z) { - diag(n, "can't find count/param arg"); - return; - } - while(b != Z) { - b = nextarg(b, &a); - for(tl=l->prot; tl; tl=tl->link) - if(sametype(a->type, tl->type)) - break; - if(tl == nil) - diag(a, "invalid type %T in call to %s", a->type, s); - } - } - - if(l->param <= 0) - return; - i = l->param; - a = nil; - b = n->right; - while(i > 0) { - b = nextarg(b, &a); - i--; - } - if(a == Z) { - diag(n, "can't find format arg"); - return; - } - if(!sametype(indchar, a->type)) { - diag(n, "format arg type %T", a->type); - return; - } - if(a->op != OADDR || a->left->op != ONAME || a->left->sym != symstring) { -/* warn(n, "format arg not constant string");*/ - return; - } - s = a->left->cstring; - checkargs(b, s, l->param); -} - -void -pragpack(void) -{ - Sym *s; - - packflg = 0; - s = getsym(); - if(s) { - packflg = atoi(s->name+1); - if(strcmp(s->name, "on") == 0 || - strcmp(s->name, "yes") == 0) - packflg = 1; - } - while(getnsc() != '\n') - ; - if(debug['f']) - if(packflg) - print("%4d: pack %d\n", lineno, packflg); - else - print("%4d: pack off\n", lineno); -} - -void -pragfpround(void) -{ - Sym *s; - - fproundflg = 0; - s = getsym(); - if(s) { - fproundflg = atoi(s->name+1); - if(strcmp(s->name, "on") == 0 || - strcmp(s->name, "yes") == 0) - fproundflg = 1; - } - while(getnsc() != '\n') - ; - if(debug['f']) - if(fproundflg) - print("%4d: fproundflg %d\n", lineno, fproundflg); - else - print("%4d: fproundflg off\n", lineno); -} - -void -pragtextflag(void) -{ - Sym *s; - - textflag = 0; - s = getsym(); - textflag = 7; - if(s) - textflag = atoi(s->name+1); - while(getnsc() != '\n') - ; - if(debug['f']) - print("%4d: textflag %d\n", lineno, textflag); -} - -void -pragincomplete(void) -{ - Sym *s; - Type *t; - int istag, w, et; - - istag = 0; - s = getsym(); - if(s == nil) - goto out; - et = 0; - w = s->lexical; - if(w == LSTRUCT) - et = TSTRUCT; - else if(w == LUNION) - et = TUNION; - if(et != 0){ - s = getsym(); - if(s == nil){ - yyerror("missing struct/union tag in pragma incomplete"); - goto out; - } - if(s->lexical != LNAME && s->lexical != LTYPE){ - yyerror("invalid struct/union tag: %s", s->name); - goto out; - } - dotag(s, et, 0); - istag = 1; - }else if(strcmp(s->name, "_off_") == 0){ - debug['T'] = 0; - goto out; - }else if(strcmp(s->name, "_on_") == 0){ - debug['T'] = 1; - goto out; - } - t = s->type; - if(istag) - t = s->suetag; - if(t == T) - yyerror("unknown type %s in pragma incomplete", s->name); - else if(!typesu[t->etype]) - yyerror("not struct/union type in pragma incomplete: %s", s->name); - else - t->garb |= GINCOMPLETE; -out: - while(getnsc() != '\n') - ; - if(debug['f']) - print("%s incomplete\n", s->name); -} - -Sym* -getimpsym(void) -{ - int c; - char *cp; - - c = getnsc(); - if(isspace(c) || c == '"') { - unget(c); - return S; - } - for(cp = symb;;) { - if(cp <= symb+NSYMB-4) - *cp++ = c; - c = getc(); - if(c > 0 && !isspace(c) && c != '"') - continue; - unget(c); - break; - } - *cp = 0; - if(cp > symb+NSYMB-4) - yyerror("symbol too large: %s", symb); - return lookup(); -} - -void -pragdynimport(void) -{ - Sym *local, *remote; - char *path; - Dynimp *f; - - local = getimpsym(); - if(local == nil) - goto err; - - remote = getimpsym(); - if(remote == nil) - goto err; - - path = getquoted(); - if(path == nil) - goto err; - - if(ndynimp%32 == 0) - dynimp = realloc(dynimp, (ndynimp+32)*sizeof dynimp[0]); - f = &dynimp[ndynimp++]; - f->local = local->name; - f->remote = remote->name; - f->path = path; - goto out; - -err: - yyerror("usage: #pragma dynimport local remote \"path\""); - -out: - while(getnsc() != '\n') - ; -} - -void -pragdynexport(void) -{ - Sym *local, *remote; - Dynexp *f; - - local = getsym(); - if(local == nil) - goto err; - - remote = getsym(); - if(remote == nil) - goto err; - - if(ndynexp%32 == 0) - dynexp = realloc(dynexp, (ndynexp+32)*sizeof dynexp[0]); - f = &dynexp[ndynexp++]; - f->local = local->name; - f->remote = remote->name; - goto out; - -err: - yyerror("usage: #pragma dynexport local remote"); - -out: - while(getnsc() != '\n') - ; -} |