diff options
author | Ondřej Surý <ondrej@sury.org> | 2011-09-13 13:13:40 +0200 |
---|---|---|
committer | Ondřej Surý <ondrej@sury.org> | 2011-09-13 13:13:40 +0200 |
commit | 5ff4c17907d5b19510a62e08fd8d3b11e62b431d (patch) | |
tree | c0650497e988f47be9c6f2324fa692a52dea82e1 /src/cmd/cc/acid.c | |
parent | 80f18fc933cf3f3e829c5455a1023d69f7b86e52 (diff) | |
download | golang-5ff4c17907d5b19510a62e08fd8d3b11e62b431d.tar.gz |
Imported Upstream version 60upstream/60
Diffstat (limited to 'src/cmd/cc/acid.c')
-rw-r--r-- | src/cmd/cc/acid.c | 344 |
1 files changed, 344 insertions, 0 deletions
diff --git a/src/cmd/cc/acid.c b/src/cmd/cc/acid.c new file mode 100644 index 000000000..23147e519 --- /dev/null +++ b/src/cmd/cc/acid.c @@ -0,0 +1,344 @@ +// Inferno utils/cc/acid.c +// http://code.google.com/p/inferno-os/source/browse/utils/cc/acid.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 "cc.h" + +static char *kwd[] = +{ + "$adt", "$aggr", "$append", "$complex", "$defn", + "$delete", "$do", "$else", "$eval", "$head", "$if", + "$local", "$loop", "$return", "$tail", "$then", + "$union", "$whatis", "$while", +}; + +char* +amap(char *s) +{ + int i, bot, top, new; + + bot = 0; + top = bot + nelem(kwd) - 1; + while(bot <= top){ + new = bot + (top - bot)/2; + i = strcmp(kwd[new]+1, s); + if(i == 0) + return kwd[new]; + + if(i < 0) + bot = new + 1; + else + top = new - 1; + } + return s; +} + +Sym* +acidsue(Type *t) +{ + int h; + Sym *s; + + if(t != T) + for(h=0; h<nelem(hash); h++) + for(s = hash[h]; s != S; s = s->link) + if(s->suetag && s->suetag->link == t) + return s; + return 0; +} + +Sym* +acidfun(Type *t) +{ + int h; + Sym *s; + + for(h=0; h<nelem(hash); h++) + for(s = hash[h]; s != S; s = s->link) + if(s->type == t) + return s; + return 0; +} + +char acidchar[NTYPE]; +Init acidcinit[] = +{ + TCHAR, 'C', 0, + TUCHAR, 'b', 0, + TSHORT, 'd', 0, + TUSHORT, 'u', 0, + TLONG, 'D', 0, + TULONG, 'U', 0, + TVLONG, 'V', 0, + TUVLONG, 'W', 0, + TFLOAT, 'f', 0, + TDOUBLE, 'F', 0, + TARRAY, 'a', 0, + TIND, 'X', 0, + -1, 0, 0, +}; + +static void +acidinit(void) +{ + Init *p; + + for(p=acidcinit; p->code >= 0; p++) + acidchar[p->code] = p->value; + + acidchar[TINT] = acidchar[TLONG]; + acidchar[TUINT] = acidchar[TULONG]; + if(types[TINT]->width != types[TLONG]->width) { + acidchar[TINT] = acidchar[TSHORT]; + acidchar[TUINT] = acidchar[TUSHORT]; + if(types[TINT]->width != types[TSHORT]->width) + warn(Z, "acidmember int not long or short"); + } + if(types[TIND]->width == types[TUVLONG]->width) + acidchar[TIND] = 'Y'; + +} + +void +acidmember(Type *t, int32 off, int flag) +{ + Sym *s, *s1; + Type *l; + static int acidcharinit = 0; + + if(acidcharinit == 0) { + acidinit(); + acidcharinit = 1; + } + s = t->sym; + switch(t->etype) { + default: + Bprint(&outbuf, " T%d\n", t->etype); + break; + + case TIND: + if(s == S) + break; + l = t->link; + if(flag) { + if(typesu[l->etype]) { + s1 = acidsue(l->link); + if(s1 != S) { + Bprint(&outbuf, " 'A' %s %d %s;\n", + amap(s1->name), + t->offset+off, amap(s->name)); + break; + } + } + } else { + l = t->link; + s1 = S; + if(typesu[l->etype]) + s1 = acidsue(l->link); + if(s1 != S) { + Bprint(&outbuf, + "\tprint(indent, \"%s\t(%s)\", addr.%s\\X, \"\\n\");\n", + amap(s->name), amap(s1->name), amap(s->name)); + } else { + Bprint(&outbuf, + "\tprint(indent, \"%s\t\", addr.%s\\X, \"\\n\");\n", + amap(s->name), amap(s->name)); + } + break; + } + + case TINT: + case TUINT: + case TCHAR: + case TUCHAR: + case TSHORT: + case TUSHORT: + case TLONG: + case TULONG: + case TVLONG: + case TUVLONG: + case TFLOAT: + case TDOUBLE: + case TARRAY: + if(s == S) + break; + if(flag) { + Bprint(&outbuf, " '%c' %d %s;\n", + acidchar[t->etype], t->offset+off, amap(s->name)); + } else { + Bprint(&outbuf, "\tprint(indent, \"%s\t\", addr.%s, \"\\n\");\n", + amap(s->name), amap(s->name)); + } + break; + + case TSTRUCT: + case TUNION: + s1 = acidsue(t->link); + if(s1 == S) + break; + if(flag) { + if(s == S) { + Bprint(&outbuf, " {\n"); + for(l = t->link; l != T; l = l->down) + acidmember(l, t->offset+off, flag); + Bprint(&outbuf, " };\n"); + } else { + Bprint(&outbuf, " %s %d %s;\n", + amap(s1->name), + t->offset+off, amap(s->name)); + } + } else { + if(s != S) { + Bprint(&outbuf, "\tprint(indent, \"%s %s {\\n\");\n", + amap(s1->name), amap(s->name)); + Bprint(&outbuf, "\tindent_%s(addr.%s, indent+\"\\t\");\n", + amap(s1->name), amap(s->name)); + Bprint(&outbuf, "\tprint(indent, \"}\\n\");\n"); + } else { + Bprint(&outbuf, "\tprint(indent, \"%s {\\n\");\n", + amap(s1->name)); + Bprint(&outbuf, "\tindent_%s(addr+%d, indent+\"\\t\");\n", + amap(s1->name), t->offset+off); + Bprint(&outbuf, "\tprint(indent, \"}\\n\");\n"); + } + } + break; + } +} + +void +acidtype(Type *t) +{ + Sym *s; + Type *l; + Io *i; + int n; + char *an; + + if(!debug['a']) + return; + if(debug['a'] > 1) { + n = 0; + for(i=iostack; i; i=i->link) + n++; + if(n > 1) + return; + } + s = acidsue(t->link); + if(s == S) + return; + switch(t->etype) { + default: + Bprint(&outbuf, "T%d\n", t->etype); + return; + + case TUNION: + case TSTRUCT: + if(debug['s']) + goto asmstr; + an = amap(s->name); + Bprint(&outbuf, "sizeof%s = %d;\n", an, t->width); + Bprint(&outbuf, "aggr %s\n{\n", an); + for(l = t->link; l != T; l = l->down) + acidmember(l, 0, 1); + Bprint(&outbuf, "};\n\n"); + + Bprint(&outbuf, "defn\n%s(addr) {\n\tindent_%s(addr, \"\\t\");\n}\n", an, an); + Bprint(&outbuf, "defn\nindent_%s(addr, indent) {\n\tcomplex %s addr;\n", an, an); + for(l = t->link; l != T; l = l->down) + acidmember(l, 0, 0); + Bprint(&outbuf, "};\n\n"); + break; + asmstr: + if(s == S) + break; + for(l = t->link; l != T; l = l->down) + if(l->sym != S) + Bprint(&outbuf, "#define\t%s.%s\t%d\n", + s->name, + l->sym->name, + l->offset); + break; + } +} + +void +acidvar(Sym *s) +{ + int n; + Io *i; + Type *t; + Sym *s1, *s2; + + if(!debug['a'] || debug['s']) + return; + if(debug['a'] > 1) { + n = 0; + for(i=iostack; i; i=i->link) + n++; + if(n > 1) + return; + } + t = s->type; + while(t && t->etype == TIND) + t = t->link; + if(t == T) + return; + if(t->etype == TENUM) { + Bprint(&outbuf, "%s = ", amap(s->name)); + if(!typefd[t->etype]) + Bprint(&outbuf, "%lld;\n", s->vconst); + else + Bprint(&outbuf, "%f\n;", s->fconst); + return; + } + if(!typesu[t->etype]) + return; + s1 = acidsue(t->link); + if(s1 == S) + return; + switch(s->class) { + case CAUTO: + case CPARAM: + s2 = acidfun(thisfn); + if(s2) + Bprint(&outbuf, "complex %s %s:%s;\n", + amap(s1->name), amap(s2->name), amap(s->name)); + break; + + case CSTATIC: + case CEXTERN: + case CGLOBL: + case CLOCAL: + Bprint(&outbuf, "complex %s %s;\n", + amap(s1->name), amap(s->name)); + break; + } +} |