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 | |
parent | 28592ee1ea1f5cdffcf85472f9de0285d928cf12 (diff) | |
download | golang-80f18fc933cf3f3e829c5455a1023d69f7b86e52.tar.gz |
Imported Upstream version 60
Diffstat (limited to 'src/cmd/cc')
-rw-r--r-- | src/cmd/cc/Makefile | 36 | ||||
-rw-r--r-- | src/cmd/cc/acid.c | 344 | ||||
-rw-r--r-- | src/cmd/cc/bits.c | 120 | ||||
-rw-r--r-- | src/cmd/cc/cc.h | 831 | ||||
-rw-r--r-- | src/cmd/cc/cc.y | 1215 | ||||
-rw-r--r-- | src/cmd/cc/com.c | 1385 | ||||
-rw-r--r-- | src/cmd/cc/com64.c | 644 | ||||
-rw-r--r-- | src/cmd/cc/dcl.c | 1669 | ||||
-rw-r--r-- | src/cmd/cc/doc.go | 11 | ||||
-rw-r--r-- | src/cmd/cc/dpchk.c | 724 | ||||
-rw-r--r-- | src/cmd/cc/funct.c | 431 | ||||
-rw-r--r-- | src/cmd/cc/godefs.c | 388 | ||||
-rw-r--r-- | src/cmd/cc/lex.c | 1562 | ||||
-rw-r--r-- | src/cmd/cc/lexbody | 769 | ||||
-rw-r--r-- | src/cmd/cc/mac.c | 35 | ||||
-rw-r--r-- | src/cmd/cc/macbody | 852 | ||||
-rw-r--r-- | src/cmd/cc/omachcap.c | 40 | ||||
-rw-r--r-- | src/cmd/cc/pgen.c | 594 | ||||
-rw-r--r-- | src/cmd/cc/pswt.c | 168 | ||||
-rw-r--r-- | src/cmd/cc/scon.c | 637 | ||||
-rw-r--r-- | src/cmd/cc/sub.c | 2056 |
21 files changed, 0 insertions, 14511 deletions
diff --git a/src/cmd/cc/Makefile b/src/cmd/cc/Makefile deleted file mode 100644 index 8327d9516..000000000 --- a/src/cmd/cc/Makefile +++ /dev/null @@ -1,36 +0,0 @@ -# Copyright 2009 The Go Authors. All rights reserved. -# Use of this source code is governed by a BSD-style -# license that can be found in the LICENSE file. - -include ../../Make.inc -O:=$(HOST_O) - -LIB=cc.a - -HFILES=\ - cc.h\ - y.tab.h\ - -YFILES=\ - cc.y\ - -OFILES=\ - y.tab.$O\ - lex.$O\ - mac.$O\ - dcl.$O\ - acid.$O\ - godefs.$O\ - bits.$O\ - com.$O\ - scon.$O\ - funct.$O\ - sub.$O\ - com64.$O\ - dpchk.$O\ - omachcap.$O\ - -NOINSTALL=1 -include ../../Make.clib - -install: $(LIB) diff --git a/src/cmd/cc/acid.c b/src/cmd/cc/acid.c deleted file mode 100644 index 23147e519..000000000 --- a/src/cmd/cc/acid.c +++ /dev/null @@ -1,344 +0,0 @@ -// 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; - } -} diff --git a/src/cmd/cc/bits.c b/src/cmd/cc/bits.c deleted file mode 100644 index 4496d65e7..000000000 --- a/src/cmd/cc/bits.c +++ /dev/null @@ -1,120 +0,0 @@ -// Inferno utils/cc/bits.c -// http://code.google.com/p/inferno-os/source/browse/utils/cc/bits.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" - -Bits -bor(Bits a, Bits b) -{ - Bits c; - int i; - - for(i=0; i<BITS; i++) - c.b[i] = a.b[i] | b.b[i]; - return c; -} - -Bits -band(Bits a, Bits b) -{ - Bits c; - int i; - - for(i=0; i<BITS; i++) - c.b[i] = a.b[i] & b.b[i]; - return c; -} - -/* -Bits -bnot(Bits a) -{ - Bits c; - int i; - - for(i=0; i<BITS; i++) - c.b[i] = ~a.b[i]; - return c; -} -*/ - -int -bany(Bits *a) -{ - int i; - - for(i=0; i<BITS; i++) - if(a->b[i]) - return 1; - return 0; -} - -int -beq(Bits a, Bits b) -{ - int i; - - for(i=0; i<BITS; i++) - if(a.b[i] != b.b[i]) - return 0; - return 1; -} - -int -bnum(Bits a) -{ - int i; - int32 b; - - for(i=0; i<BITS; i++) - if(b = a.b[i]) - return 32*i + bitno(b); - diag(Z, "bad in bnum"); - return 0; -} - -Bits -blsh(uint n) -{ - Bits c; - - c = zbits; - c.b[n/32] = 1L << (n%32); - return c; -} - -int -bset(Bits a, uint n) -{ - if(a.b[n/32] & (1L << (n%32))) - return 1; - return 0; -} diff --git a/src/cmd/cc/cc.h b/src/cmd/cc/cc.h deleted file mode 100644 index a38e658ce..000000000 --- a/src/cmd/cc/cc.h +++ /dev/null @@ -1,831 +0,0 @@ -// Inferno utils/cc/cc.h -// http://code.google.com/p/inferno-os/source/browse/utils/cc/cc.h -// -// 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 <libc.h> -#include <bio.h> - -#pragma lib "../cc/cc.a$O" - -#ifndef EXTERN -#define EXTERN extern -#endif - -#undef getc -#undef ungetc -#undef BUFSIZ - -#define getc ccgetc -#define ungetc ccungetc - -typedef struct Node Node; -typedef struct Sym Sym; -typedef struct Type Type; -typedef struct Funct Funct; -typedef struct Decl Decl; -typedef struct Io Io; -typedef struct Hist Hist; -typedef struct Term Term; -typedef struct Init Init; -typedef struct Bits Bits; -typedef struct Dynimp Dynimp; -typedef struct Dynexp Dynexp; - -#define BUFSIZ 8192 -#define NSYMB 500 -#define NHASH 1024 -#define STRINGSZ 200 -#define HISTSZ 20 -#define YYMAXDEPTH 500 -#define NTERM 10 -#define MAXALIGN 7 - -#define SIGN(n) ((uvlong)1<<(n-1)) -#define MASK(n) (SIGN(n)|(SIGN(n)-1)) - -#define BITS 5 -#define NVAR (BITS*sizeof(uint32)*8) -struct Bits -{ - uint32 b[BITS]; -}; - -struct Node -{ - Node* left; - Node* right; - void* label; - int32 pc; - int reg; - int32 xoffset; - double fconst; /* fp constant */ - vlong vconst; /* non fp const */ - char* cstring; /* character string */ - ushort* rstring; /* rune string */ - - Sym* sym; - Type* type; - int32 lineno; - uchar op; - uchar oldop; - uchar xcast; - uchar class; - uchar etype; - uchar complex; - uchar addable; - uchar scale; - uchar garb; -}; -#define Z ((Node*)0) - -struct Sym -{ - Sym* link; - Type* type; - Type* suetag; - Type* tenum; - char* macro; - int32 varlineno; - int32 offset; - vlong vconst; - double fconst; - Node* label; - ushort lexical; - char *name; - ushort block; - ushort sueblock; - uchar class; - uchar sym; - uchar aused; - uchar sig; -}; -#define S ((Sym*)0) - -enum{ - SIGNONE = 0, - SIGDONE = 1, - SIGINTERN = 2, - - SIGNINTERN = 1729*325*1729, -}; - -struct Decl -{ - Decl* link; - Sym* sym; - Type* type; - int32 varlineno; - int32 offset; - short val; - ushort block; - uchar class; - uchar aused; -}; -#define D ((Decl*)0) - -struct Type -{ - Sym* sym; - Sym* tag; - Funct* funct; - Type* link; - Type* down; - int32 width; - int32 offset; - int32 lineno; - uchar shift; - uchar nbits; - uchar etype; - uchar garb; - uchar align; -}; - -#define T ((Type*)0) -#define NODECL ((void(*)(int, Type*, Sym*))0) - -struct Init /* general purpose initialization */ -{ - int code; - uint32 value; - char* s; -}; - -EXTERN struct -{ - char* p; - int c; -} fi; - -struct Io -{ - Io* link; - char* p; - char b[BUFSIZ]; - short c; - short f; -}; -#define I ((Io*)0) - -struct Hist -{ - Hist* link; - char* name; - int32 line; - int32 offset; -}; -#define H ((Hist*)0) -EXTERN Hist* hist; - -struct Term -{ - vlong mult; - Node *node; -}; - -enum -{ - Axxx, - Ael1, - Ael2, - Asu2, - Aarg0, - Aarg1, - Aarg2, - Aaut3, - NALIGN, -}; - -enum -{ - DMARK, - DAUTO, - DSUE, - DLABEL, -}; -enum -{ - OXXX, - OADD, - OADDR, - OAND, - OANDAND, - OARRAY, - OAS, - OASI, - OASADD, - OASAND, - OASASHL, - OASASHR, - OASDIV, - OASHL, - OASHR, - OASLDIV, - OASLMOD, - OASLMUL, - OASLSHR, - OASMOD, - OASMUL, - OASOR, - OASSUB, - OASXOR, - OBIT, - OBREAK, - OCASE, - OCAST, - OCOMMA, - OCOND, - OCONST, - OCONTINUE, - ODIV, - ODOT, - ODOTDOT, - ODWHILE, - OENUM, - OEQ, - OEXREG, - OFOR, - OFUNC, - OGE, - OGOTO, - OGT, - OHI, - OHS, - OIF, - OIND, - OINDREG, - OINIT, - OLABEL, - OLDIV, - OLE, - OLIST, - OLMOD, - OLMUL, - OLO, - OLS, - OLSHR, - OLT, - OMOD, - OMUL, - ONAME, - ONE, - ONOT, - OOR, - OOROR, - OPOSTDEC, - OPOSTINC, - OPREDEC, - OPREINC, - OPROTO, - OREGISTER, - ORETURN, - OSET, - OSIGN, - OSIZE, - OSTRING, - OLSTRING, - OSTRUCT, - OSUB, - OSWITCH, - OUNION, - OUSED, - OWHILE, - OXOR, - ONEG, - OCOM, - OPOS, - OELEM, - - OTST, /* used in some compilers */ - OINDEX, - OFAS, - OREGPAIR, - - OEND -}; -enum -{ - TXXX, - TCHAR, - TUCHAR, - TSHORT, - TUSHORT, - TINT, - TUINT, - TLONG, - TULONG, - TVLONG, - TUVLONG, - TFLOAT, - TDOUBLE, - TIND, - TFUNC, - TARRAY, - TVOID, - TSTRUCT, - TUNION, - TENUM, - NTYPE, - - TAUTO = NTYPE, - TEXTERN, - TSTATIC, - TTYPEDEF, - TTYPESTR, - TREGISTER, - TCONSTNT, - TVOLATILE, - TUNSIGNED, - TSIGNED, - TDOT, - TFILE, - TOLD, - NALLTYPES, -}; -enum -{ - CXXX, - CAUTO, - CEXTERN, - CGLOBL, - CSTATIC, - CLOCAL, - CTYPEDEF, - CTYPESTR, - CPARAM, - CSELEM, - CLABEL, - CEXREG, - NCTYPES, -}; -enum -{ - GXXX = 0, - GCONSTNT = 1<<0, - GVOLATILE = 1<<1, - NGTYPES = 1<<2, - - GINCOMPLETE = 1<<2, -}; -enum -{ - BCHAR = 1L<<TCHAR, - BUCHAR = 1L<<TUCHAR, - BSHORT = 1L<<TSHORT, - BUSHORT = 1L<<TUSHORT, - BINT = 1L<<TINT, - BUINT = 1L<<TUINT, - BLONG = 1L<<TLONG, - BULONG = 1L<<TULONG, - BVLONG = 1L<<TVLONG, - BUVLONG = 1L<<TUVLONG, - BFLOAT = 1L<<TFLOAT, - BDOUBLE = 1L<<TDOUBLE, - BIND = 1L<<TIND, - BFUNC = 1L<<TFUNC, - BARRAY = 1L<<TARRAY, - BVOID = 1L<<TVOID, - BSTRUCT = 1L<<TSTRUCT, - BUNION = 1L<<TUNION, - BENUM = 1L<<TENUM, - BFILE = 1L<<TFILE, - BDOT = 1L<<TDOT, - BCONSTNT = 1L<<TCONSTNT, - BVOLATILE = 1L<<TVOLATILE, - BUNSIGNED = 1L<<TUNSIGNED, - BSIGNED = 1L<<TSIGNED, - BAUTO = 1L<<TAUTO, - BEXTERN = 1L<<TEXTERN, - BSTATIC = 1L<<TSTATIC, - BTYPEDEF = 1L<<TTYPEDEF, - BTYPESTR = 1L<<TTYPESTR, - BREGISTER = 1L<<TREGISTER, - - BINTEGER = BCHAR|BUCHAR|BSHORT|BUSHORT|BINT|BUINT| - BLONG|BULONG|BVLONG|BUVLONG, - BNUMBER = BINTEGER|BFLOAT|BDOUBLE, - -/* these can be overloaded with complex types */ - - BCLASS = BAUTO|BEXTERN|BSTATIC|BTYPEDEF|BTYPESTR|BREGISTER, - BGARB = BCONSTNT|BVOLATILE, -}; - -struct Funct -{ - Sym* sym[OEND]; - Sym* castto[NTYPE]; - Sym* castfr[NTYPE]; -}; - -struct Dynimp -{ - char* local; - char* remote; - char* path; -}; - -EXTERN Dynimp *dynimp; -EXTERN int ndynimp; - -struct Dynexp -{ - char* local; - char* remote; -}; - -EXTERN Dynexp *dynexp; -EXTERN int ndynexp; - -EXTERN struct -{ - Type* tenum; /* type of entire enum */ - Type* cenum; /* type of current enum run */ - vlong lastenum; /* value of current enum */ - double floatenum; /* value of current enum */ -} en; - -EXTERN int autobn; -EXTERN int32 autoffset; -EXTERN int blockno; -EXTERN Decl* dclstack; -EXTERN char debug[256]; -EXTERN Hist* ehist; -EXTERN int32 firstbit; -EXTERN Sym* firstarg; -EXTERN Type* firstargtype; -EXTERN Decl* firstdcl; -EXTERN int fperror; -EXTERN Sym* hash[NHASH]; -EXTERN char* hunk; -EXTERN char** include; -EXTERN Io* iofree; -EXTERN Io* ionext; -EXTERN Io* iostack; -EXTERN int32 lastbit; -EXTERN char lastclass; -EXTERN Type* lastdcl; -EXTERN int32 lastfield; -EXTERN Type* lasttype; -EXTERN int32 lineno; -EXTERN int32 nearln; -EXTERN int nerrors; -EXTERN int newflag; -EXTERN int32 nhunk; -EXTERN int ninclude; -EXTERN Node* nodproto; -EXTERN Node* nodcast; -EXTERN int32 nsymb; -EXTERN Biobuf outbuf; -EXTERN Biobuf diagbuf; -EXTERN char* outfile; -EXTERN char* pathname; -EXTERN int peekc; -EXTERN int32 stkoff; -EXTERN Type* strf; -EXTERN Type* strl; -EXTERN char* symb; -EXTERN Sym* symstring; -EXTERN int taggen; -EXTERN Type* tfield; -EXTERN Type* tufield; -EXTERN int thechar; -EXTERN char* thestring; -EXTERN Type* thisfn; -EXTERN int32 thunk; -EXTERN Type* types[NTYPE]; -EXTERN Type* fntypes[NTYPE]; -EXTERN Node* initlist; -EXTERN Term term[NTERM]; -EXTERN int nterm; -EXTERN int packflg; -EXTERN int fproundflg; -EXTERN int textflag; -EXTERN int ncontin; -EXTERN int canreach; -EXTERN int warnreach; -EXTERN Bits zbits; - -extern char *onames[], *tnames[], *gnames[]; -extern char *cnames[], *qnames[], *bnames[]; -extern uchar tab[NTYPE][NTYPE]; -extern uchar comrel[], invrel[], logrel[]; -extern int32 ncast[], tadd[], tand[]; -extern int32 targ[], tasadd[], tasign[], tcast[]; -extern int32 tdot[], tfunct[], tindir[], tmul[]; -extern int32 tnot[], trel[], tsub[]; - -extern uchar typeaf[]; -extern uchar typefd[]; -extern uchar typei[]; -extern uchar typesu[]; -extern uchar typesuv[]; -extern uchar typeu[]; -extern uchar typev[]; -extern uchar typec[]; -extern uchar typeh[]; -extern uchar typeil[]; -extern uchar typeilp[]; -extern uchar typechl[]; -extern uchar typechlv[]; -extern uchar typechlvp[]; -extern uchar typechlp[]; -extern uchar typechlpfd[]; - -EXTERN uchar* typeword; -EXTERN uchar* typecmplx; - -extern uint32 thash1; -extern uint32 thash2; -extern uint32 thash3; -extern uint32 thash[]; - -/* - * compat.c/unix.c/windows.c - */ -int systemtype(int); -int pathchar(void); - -/* - * parser - */ -int yyparse(void); -int mpatov(char*, vlong*); - -/* - * lex.c - */ -void* allocn(void*, int32, int32); -void* alloc(int32); -void ensuresymb(int32); -void cinit(void); -int compile(char*, char**, int); -void errorexit(void); -int filbuf(void); -int getc(void); -int32 getr(void); -int getnsc(void); -Sym* lookup(void); -void main(int, char*[]); -void newfile(char*, int); -void newio(void); -void pushio(void); -int32 escchar(int32, int, int); -Sym* slookup(char*); -void syminit(Sym*); -void unget(int); -int32 yylex(void); -int Lconv(Fmt*); -int Tconv(Fmt*); -int FNconv(Fmt*); -int Oconv(Fmt*); -int Qconv(Fmt*); -int VBconv(Fmt*); -void setinclude(char*); - -/* - * mac.c - */ -void dodefine(char*); -void domacro(void); -Sym* getsym(void); -int32 getnsn(void); -void linehist(char*, int); -void macdef(void); -void macprag(void); -void macend(void); -void macexpand(Sym*, char*); -void macif(int); -void macinc(void); -void maclin(void); -void macund(void); - -/* - * dcl.c - */ -Node* doinit(Sym*, Type*, int32, Node*); -Type* tcopy(Type*); -Node* init1(Sym*, Type*, int32, int); -Node* newlist(Node*, Node*); -void adecl(int, Type*, Sym*); -int anyproto(Node*); -void argmark(Node*, int); -void dbgdecl(Sym*); -Node* dcllabel(Sym*, int); -Node* dodecl(void(*)(int, Type*, Sym*), int, Type*, Node*); -Sym* mkstatic(Sym*); -void doenum(Sym*, Node*); -void snap(Type*); -Type* dotag(Sym*, int, int); -void edecl(int, Type*, Sym*); -Type* fnproto(Node*); -Type* fnproto1(Node*); -void markdcl(void); -Type* paramconv(Type*, int); -void pdecl(int, Type*, Sym*); -Decl* push(void); -Decl* push1(Sym*); -Node* revertdcl(void); -int32 xround(int32, int); -int rsametype(Type*, Type*, int, int); -int sametype(Type*, Type*); -uint32 sign(Sym*); -uint32 signature(Type*); -void sualign(Type*); -void tmerge(Type*, Sym*); -void walkparam(Node*, int); -void xdecl(int, Type*, Sym*); -Node* contig(Sym*, Node*, int32); - -/* - * com.c - */ -void ccom(Node*); -void complex(Node*); -int tcom(Node*); -int tcoma(Node*, Node*, Type*, int); -int tcomd(Node*); -int tcomo(Node*, int); -int tcomx(Node*); -int tlvalue(Node*); -void constas(Node*, Type*, Type*); - -/* - * con.c - */ -void acom(Node*); -void acom1(vlong, Node*); -void acom2(Node*, Type*); -int acomcmp1(const void*, const void*); -int acomcmp2(const void*, const void*); -int addo(Node*); -void evconst(Node*); - -/* - * funct.c - */ -int isfunct(Node*); -void dclfunct(Type*, Sym*); - -/* - * sub.c - */ -void arith(Node*, int); -int deadheads(Node*); -Type* dotsearch(Sym*, Type*, Node*, int32*); -int32 dotoffset(Type*, Type*, Node*); -void gethunk(void); -Node* invert(Node*); -int bitno(int32); -void makedot(Node*, Type*, int32); -int mixedasop(Type*, Type*); -Node* new(int, Node*, Node*); -Node* new1(int, Node*, Node*); -int nilcast(Type*, Type*); -int nocast(Type*, Type*); -void prtree(Node*, char*); -void prtree1(Node*, int, int); -void relcon(Node*, Node*); -int relindex(int); -int simpleg(int32); -Type* garbt(Type*, int32); -int simplec(int32); -Type* simplet(int32); -int stcompat(Node*, Type*, Type*, int32[]); -int tcompat(Node*, Type*, Type*, int32[]); -void tinit(void); -Type* typ(int, Type*); -Type* copytyp(Type*); -void typeext(Type*, Node*); -void typeext1(Type*, Node*); -int side(Node*); -int vconst(Node*); -int xlog2(uvlong); -int vlog(Node*); -int topbit(uint32); -void simplifyshift(Node*); -int32 typebitor(int32, int32); -void diag(Node*, char*, ...); -void warn(Node*, char*, ...); -void yyerror(char*, ...); -void fatal(Node*, char*, ...); - -/* - * acid.c - */ -void acidtype(Type*); -void acidvar(Sym*); - -/* - * godefs.c - */ -int Uconv(Fmt*); -void godeftype(Type*); -void godefvar(Sym*); - -/* - * bits.c - */ -Bits bor(Bits, Bits); -Bits band(Bits, Bits); -Bits bnot(Bits); -int bany(Bits*); -int bnum(Bits); -Bits blsh(uint); -int beq(Bits, Bits); -int bset(Bits, uint); - -/* - * dpchk.c - */ -void dpcheck(Node*); -void arginit(void); -void pragvararg(void); -void pragpack(void); -void pragfpround(void); -void pragtextflag(void); -void pragincomplete(void); -void pragdynimport(void); -void pragdynexport(void); - -/* - * calls to machine depend part - */ -void codgen(Node*, Node*); -void gclean(void); -void gextern(Sym*, Node*, int32, int32); -void ginit(void); -int32 outstring(char*, int32); -int32 outlstring(ushort*, int32); -void sextern(Sym*, Node*, int32, int32); -void xcom(Node*); -int32 exreg(Type*); -int32 align(int32, Type*, int, int32*); -int32 maxround(int32, int32); - -extern schar ewidth[]; - -/* - * com64 - */ -int com64(Node*); -void com64init(void); -void bool64(Node*); -double convvtof(vlong); -vlong convftov(double); -double convftox(double, int); -vlong convvtox(vlong, int); - -/* - * machcap - */ -int machcap(Node*); - -#pragma varargck argpos warn 2 -#pragma varargck argpos diag 2 -#pragma varargck argpos yyerror 1 - -#pragma varargck type "F" Node* -#pragma varargck type "L" int32 -#pragma varargck type "Q" int32 -#pragma varargck type "O" int -#pragma varargck type "O" uint -#pragma varargck type "T" Type* -#pragma varargck type "U" char* -#pragma varargck type "|" int - -enum -{ - Plan9 = 1<<0, - Unix = 1<<1, - Windows = 1<<2, -}; -int pathchar(void); -int systemtype(int); -void* alloc(int32 n); -void* allocn(void*, int32, int32); diff --git a/src/cmd/cc/cc.y b/src/cmd/cc/cc.y deleted file mode 100644 index 515a80372..000000000 --- a/src/cmd/cc/cc.y +++ /dev/null @@ -1,1215 +0,0 @@ -// Inferno utils/cc/cc.y -// http://code.google.com/p/inferno-os/source/browse/utils/cc/cc.y -// -// 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 <stdio.h> /* if we don't, bison will, and cc.h re-#defines getc */ -#include "cc.h" -%} -%union { - Node* node; - Sym* sym; - Type* type; - struct - { - Type* t; - uchar c; - } tycl; - struct - { - Type* t1; - Type* t2; - Type* t3; - uchar c; - } tyty; - struct - { - char* s; - int32 l; - } sval; - int32 lval; - double dval; - vlong vval; -} -%type <sym> ltag -%type <lval> gctname gcname cname gname tname -%type <lval> gctnlist gcnlist zgnlist -%type <type> tlist sbody complex -%type <tycl> types -%type <node> zarglist arglist zcexpr -%type <node> name block stmnt cexpr expr xuexpr pexpr -%type <node> zelist elist adecl slist uexpr string lstring -%type <node> xdecor xdecor2 labels label ulstmnt -%type <node> adlist edecor tag qual qlist -%type <node> abdecor abdecor1 abdecor2 abdecor3 -%type <node> zexpr lexpr init ilist forexpr - -%left ';' -%left ',' -%right '=' LPE LME LMLE LDVE LMDE LRSHE LLSHE LANDE LXORE LORE -%right '?' ':' -%left LOROR -%left LANDAND -%left '|' -%left '^' -%left '&' -%left LEQ LNE -%left '<' '>' LLE LGE -%left LLSH LRSH -%left '+' '-' -%left '*' '/' '%' -%right LMM LPP LMG '.' '[' '(' - -%token <sym> LNAME LTYPE -%token <dval> LFCONST LDCONST -%token <vval> LCONST LLCONST LUCONST LULCONST LVLCONST LUVLCONST -%token <sval> LSTRING LLSTRING -%token LAUTO LBREAK LCASE LCHAR LCONTINUE LDEFAULT LDO -%token LDOUBLE LELSE LEXTERN LFLOAT LFOR LGOTO -%token LIF LINT LLONG LREGISTER LRETURN LSHORT LSIZEOF LUSED -%token LSTATIC LSTRUCT LSWITCH LTYPEDEF LTYPESTR LUNION LUNSIGNED -%token LWHILE LVOID LENUM LSIGNED LCONSTNT LVOLATILE LSET LSIGNOF -%token LRESTRICT LINLINE -%% -prog: -| prog xdecl - -/* - * external declarator - */ -xdecl: - zctlist ';' - { - dodecl(xdecl, lastclass, lasttype, Z); - } -| zctlist xdlist ';' -| zctlist xdecor - { - lastdcl = T; - firstarg = S; - dodecl(xdecl, lastclass, lasttype, $2); - if(lastdcl == T || lastdcl->etype != TFUNC) { - diag($2, "not a function"); - lastdcl = types[TFUNC]; - } - thisfn = lastdcl; - markdcl(); - firstdcl = dclstack; - argmark($2, 0); - } - pdecl - { - argmark($2, 1); - } - block - { - Node *n; - - n = revertdcl(); - if(n) - $6 = new(OLIST, n, $6); - if(!debug['a'] && !debug['Z']) - codgen($6, $2); - } - -xdlist: - xdecor - { - dodecl(xdecl, lastclass, lasttype, $1); - } -| xdecor - { - $1 = dodecl(xdecl, lastclass, lasttype, $1); - } - '=' init - { - doinit($1->sym, $1->type, 0L, $4); - } -| xdlist ',' xdlist - -xdecor: - xdecor2 -| '*' zgnlist xdecor - { - $$ = new(OIND, $3, Z); - $$->garb = simpleg($2); - } - -xdecor2: - tag -| '(' xdecor ')' - { - $$ = $2; - } -| xdecor2 '(' zarglist ')' - { - $$ = new(OFUNC, $1, $3); - } -| xdecor2 '[' zexpr ']' - { - $$ = new(OARRAY, $1, $3); - } - -/* - * automatic declarator - */ -adecl: - ctlist ';' - { - $$ = dodecl(adecl, lastclass, lasttype, Z); - } -| ctlist adlist ';' - { - $$ = $2; - } - -adlist: - xdecor - { - dodecl(adecl, lastclass, lasttype, $1); - $$ = Z; - } -| xdecor - { - $1 = dodecl(adecl, lastclass, lasttype, $1); - } - '=' init - { - int32 w; - - w = $1->sym->type->width; - $$ = doinit($1->sym, $1->type, 0L, $4); - $$ = contig($1->sym, $$, w); - } -| adlist ',' adlist - { - $$ = $1; - if($3 != Z) { - $$ = $3; - if($1 != Z) - $$ = new(OLIST, $1, $3); - } - } - -/* - * parameter declarator - */ -pdecl: -| pdecl ctlist pdlist ';' - -pdlist: - xdecor - { - dodecl(pdecl, lastclass, lasttype, $1); - } -| pdlist ',' pdlist - -/* - * structure element declarator - */ -edecl: - tlist - { - lasttype = $1; - } - zedlist ';' -| edecl tlist - { - lasttype = $2; - } - zedlist ';' - -zedlist: /* extension */ - { - lastfield = 0; - edecl(CXXX, lasttype, S); - } -| edlist - -edlist: - edecor - { - dodecl(edecl, CXXX, lasttype, $1); - } -| edlist ',' edlist - -edecor: - xdecor - { - lastbit = 0; - firstbit = 1; - } -| tag ':' lexpr - { - $$ = new(OBIT, $1, $3); - } -| ':' lexpr - { - $$ = new(OBIT, Z, $2); - } - -/* - * abstract declarator - */ -abdecor: - { - $$ = (Z); - } -| abdecor1 - -abdecor1: - '*' zgnlist - { - $$ = new(OIND, (Z), Z); - $$->garb = simpleg($2); - } -| '*' zgnlist abdecor1 - { - $$ = new(OIND, $3, Z); - $$->garb = simpleg($2); - } -| abdecor2 - -abdecor2: - abdecor3 -| abdecor2 '(' zarglist ')' - { - $$ = new(OFUNC, $1, $3); - } -| abdecor2 '[' zexpr ']' - { - $$ = new(OARRAY, $1, $3); - } - -abdecor3: - '(' ')' - { - $$ = new(OFUNC, (Z), Z); - } -| '[' zexpr ']' - { - $$ = new(OARRAY, (Z), $2); - } -| '(' abdecor1 ')' - { - $$ = $2; - } - -init: - expr -| '{' ilist '}' - { - $$ = new(OINIT, invert($2), Z); - } - -qual: - '[' lexpr ']' - { - $$ = new(OARRAY, $2, Z); - } -| '.' ltag - { - $$ = new(OELEM, Z, Z); - $$->sym = $2; - } -| qual '=' - -qlist: - init ',' -| qlist init ',' - { - $$ = new(OLIST, $1, $2); - } -| qual -| qlist qual - { - $$ = new(OLIST, $1, $2); - } - -ilist: - qlist -| init -| qlist init - { - $$ = new(OLIST, $1, $2); - } - -zarglist: - { - $$ = Z; - } -| arglist - { - $$ = invert($1); - } - - -arglist: - name -| tlist abdecor - { - $$ = new(OPROTO, $2, Z); - $$->type = $1; - } -| tlist xdecor - { - $$ = new(OPROTO, $2, Z); - $$->type = $1; - } -| '.' '.' '.' - { - $$ = new(ODOTDOT, Z, Z); - } -| arglist ',' arglist - { - $$ = new(OLIST, $1, $3); - } - -block: - '{' slist '}' - { - $$ = invert($2); - // if($2 != Z) - // $$ = new(OLIST, $2, $$); - if($$ == Z) - $$ = new(OLIST, Z, Z); - } - -slist: - { - $$ = Z; - } -| slist adecl - { - $$ = new(OLIST, $1, $2); - } -| slist stmnt - { - $$ = new(OLIST, $1, $2); - } - -labels: - label -| labels label - { - $$ = new(OLIST, $1, $2); - } - -label: - LCASE expr ':' - { - $$ = new(OCASE, $2, Z); - } -| LDEFAULT ':' - { - $$ = new(OCASE, Z, Z); - } -| LNAME ':' - { - $$ = new(OLABEL, dcllabel($1, 1), Z); - } - -stmnt: - error ';' - { - $$ = Z; - } -| ulstmnt -| labels ulstmnt - { - $$ = new(OLIST, $1, $2); - } - -forexpr: - zcexpr -| ctlist adlist - { - $$ = $2; - } - -ulstmnt: - zcexpr ';' -| { - markdcl(); - } - block - { - $$ = revertdcl(); - if($$) - $$ = new(OLIST, $$, $2); - else - $$ = $2; - } -| LIF '(' cexpr ')' stmnt - { - $$ = new(OIF, $3, new(OLIST, $5, Z)); - if($5 == Z) - warn($3, "empty if body"); - } -| LIF '(' cexpr ')' stmnt LELSE stmnt - { - $$ = new(OIF, $3, new(OLIST, $5, $7)); - if($5 == Z) - warn($3, "empty if body"); - if($7 == Z) - warn($3, "empty else body"); - } -| { markdcl(); } LFOR '(' forexpr ';' zcexpr ';' zcexpr ')' stmnt - { - $$ = revertdcl(); - if($$){ - if($4) - $4 = new(OLIST, $$, $4); - else - $4 = $$; - } - $$ = new(OFOR, new(OLIST, $6, new(OLIST, $4, $8)), $10); - } -| LWHILE '(' cexpr ')' stmnt - { - $$ = new(OWHILE, $3, $5); - } -| LDO stmnt LWHILE '(' cexpr ')' ';' - { - $$ = new(ODWHILE, $5, $2); - } -| LRETURN zcexpr ';' - { - $$ = new(ORETURN, $2, Z); - $$->type = thisfn->link; - } -| LSWITCH '(' cexpr ')' stmnt - { - $$ = new(OCONST, Z, Z); - $$->vconst = 0; - $$->type = types[TINT]; - $3 = new(OSUB, $$, $3); - - $$ = new(OCONST, Z, Z); - $$->vconst = 0; - $$->type = types[TINT]; - $3 = new(OSUB, $$, $3); - - $$ = new(OSWITCH, $3, $5); - } -| LBREAK ';' - { - $$ = new(OBREAK, Z, Z); - } -| LCONTINUE ';' - { - $$ = new(OCONTINUE, Z, Z); - } -| LGOTO ltag ';' - { - $$ = new(OGOTO, dcllabel($2, 0), Z); - } -| LUSED '(' zelist ')' ';' - { - $$ = new(OUSED, $3, Z); - } -| LSET '(' zelist ')' ';' - { - $$ = new(OSET, $3, Z); - } - -zcexpr: - { - $$ = Z; - } -| cexpr - -zexpr: - { - $$ = Z; - } -| lexpr - -lexpr: - expr - { - $$ = new(OCAST, $1, Z); - $$->type = types[TLONG]; - } - -cexpr: - expr -| cexpr ',' cexpr - { - $$ = new(OCOMMA, $1, $3); - } - -expr: - xuexpr -| expr '*' expr - { - $$ = new(OMUL, $1, $3); - } -| expr '/' expr - { - $$ = new(ODIV, $1, $3); - } -| expr '%' expr - { - $$ = new(OMOD, $1, $3); - } -| expr '+' expr - { - $$ = new(OADD, $1, $3); - } -| expr '-' expr - { - $$ = new(OSUB, $1, $3); - } -| expr LRSH expr - { - $$ = new(OASHR, $1, $3); - } -| expr LLSH expr - { - $$ = new(OASHL, $1, $3); - } -| expr '<' expr - { - $$ = new(OLT, $1, $3); - } -| expr '>' expr - { - $$ = new(OGT, $1, $3); - } -| expr LLE expr - { - $$ = new(OLE, $1, $3); - } -| expr LGE expr - { - $$ = new(OGE, $1, $3); - } -| expr LEQ expr - { - $$ = new(OEQ, $1, $3); - } -| expr LNE expr - { - $$ = new(ONE, $1, $3); - } -| expr '&' expr - { - $$ = new(OAND, $1, $3); - } -| expr '^' expr - { - $$ = new(OXOR, $1, $3); - } -| expr '|' expr - { - $$ = new(OOR, $1, $3); - } -| expr LANDAND expr - { - $$ = new(OANDAND, $1, $3); - } -| expr LOROR expr - { - $$ = new(OOROR, $1, $3); - } -| expr '?' cexpr ':' expr - { - $$ = new(OCOND, $1, new(OLIST, $3, $5)); - } -| expr '=' expr - { - $$ = new(OAS, $1, $3); - } -| expr LPE expr - { - $$ = new(OASADD, $1, $3); - } -| expr LME expr - { - $$ = new(OASSUB, $1, $3); - } -| expr LMLE expr - { - $$ = new(OASMUL, $1, $3); - } -| expr LDVE expr - { - $$ = new(OASDIV, $1, $3); - } -| expr LMDE expr - { - $$ = new(OASMOD, $1, $3); - } -| expr LLSHE expr - { - $$ = new(OASASHL, $1, $3); - } -| expr LRSHE expr - { - $$ = new(OASASHR, $1, $3); - } -| expr LANDE expr - { - $$ = new(OASAND, $1, $3); - } -| expr LXORE expr - { - $$ = new(OASXOR, $1, $3); - } -| expr LORE expr - { - $$ = new(OASOR, $1, $3); - } - -xuexpr: - uexpr -| '(' tlist abdecor ')' xuexpr - { - $$ = new(OCAST, $5, Z); - dodecl(NODECL, CXXX, $2, $3); - $$->type = lastdcl; - $$->xcast = 1; - } -| '(' tlist abdecor ')' '{' ilist '}' /* extension */ - { - $$ = new(OSTRUCT, $6, Z); - dodecl(NODECL, CXXX, $2, $3); - $$->type = lastdcl; - } - -uexpr: - pexpr -| '*' xuexpr - { - $$ = new(OIND, $2, Z); - } -| '&' xuexpr - { - $$ = new(OADDR, $2, Z); - } -| '+' xuexpr - { - $$ = new(OPOS, $2, Z); - } -| '-' xuexpr - { - $$ = new(ONEG, $2, Z); - } -| '!' xuexpr - { - $$ = new(ONOT, $2, Z); - } -| '~' xuexpr - { - $$ = new(OCOM, $2, Z); - } -| LPP xuexpr - { - $$ = new(OPREINC, $2, Z); - } -| LMM xuexpr - { - $$ = new(OPREDEC, $2, Z); - } -| LSIZEOF uexpr - { - $$ = new(OSIZE, $2, Z); - } -| LSIGNOF uexpr - { - $$ = new(OSIGN, $2, Z); - } - -pexpr: - '(' cexpr ')' - { - $$ = $2; - } -| LSIZEOF '(' tlist abdecor ')' - { - $$ = new(OSIZE, Z, Z); - dodecl(NODECL, CXXX, $3, $4); - $$->type = lastdcl; - } -| LSIGNOF '(' tlist abdecor ')' - { - $$ = new(OSIGN, Z, Z); - dodecl(NODECL, CXXX, $3, $4); - $$->type = lastdcl; - } -| pexpr '(' zelist ')' - { - $$ = new(OFUNC, $1, Z); - if($1->op == ONAME) - if($1->type == T) - dodecl(xdecl, CXXX, types[TINT], $$); - $$->right = invert($3); - } -| pexpr '[' cexpr ']' - { - $$ = new(OIND, new(OADD, $1, $3), Z); - } -| pexpr LMG ltag - { - $$ = new(ODOT, new(OIND, $1, Z), Z); - $$->sym = $3; - } -| pexpr '.' ltag - { - $$ = new(ODOT, $1, Z); - $$->sym = $3; - } -| pexpr LPP - { - $$ = new(OPOSTINC, $1, Z); - } -| pexpr LMM - { - $$ = new(OPOSTDEC, $1, Z); - } -| name -| LCONST - { - $$ = new(OCONST, Z, Z); - $$->type = types[TINT]; - $$->vconst = $1; - $$->cstring = strdup(symb); - } -| LLCONST - { - $$ = new(OCONST, Z, Z); - $$->type = types[TLONG]; - $$->vconst = $1; - $$->cstring = strdup(symb); - } -| LUCONST - { - $$ = new(OCONST, Z, Z); - $$->type = types[TUINT]; - $$->vconst = $1; - $$->cstring = strdup(symb); - } -| LULCONST - { - $$ = new(OCONST, Z, Z); - $$->type = types[TULONG]; - $$->vconst = $1; - $$->cstring = strdup(symb); - } -| LDCONST - { - $$ = new(OCONST, Z, Z); - $$->type = types[TDOUBLE]; - $$->fconst = $1; - $$->cstring = strdup(symb); - } -| LFCONST - { - $$ = new(OCONST, Z, Z); - $$->type = types[TFLOAT]; - $$->fconst = $1; - $$->cstring = strdup(symb); - } -| LVLCONST - { - $$ = new(OCONST, Z, Z); - $$->type = types[TVLONG]; - $$->vconst = $1; - $$->cstring = strdup(symb); - } -| LUVLCONST - { - $$ = new(OCONST, Z, Z); - $$->type = types[TUVLONG]; - $$->vconst = $1; - $$->cstring = strdup(symb); - } -| string -| lstring - -string: - LSTRING - { - $$ = new(OSTRING, Z, Z); - $$->type = typ(TARRAY, types[TCHAR]); - $$->type->width = $1.l + 1; - $$->cstring = $1.s; - $$->sym = symstring; - $$->etype = TARRAY; - $$->class = CSTATIC; - } -| string LSTRING - { - char *s; - int n; - - n = $1->type->width - 1; - s = alloc(n+$2.l+MAXALIGN); - - memcpy(s, $1->cstring, n); - memcpy(s+n, $2.s, $2.l); - s[n+$2.l] = 0; - - $$ = $1; - $$->type->width += $2.l; - $$->cstring = s; - } - -lstring: - LLSTRING - { - $$ = new(OLSTRING, Z, Z); - $$->type = typ(TARRAY, types[TUSHORT]); - $$->type->width = $1.l + sizeof(ushort); - $$->rstring = (ushort*)$1.s; - $$->sym = symstring; - $$->etype = TARRAY; - $$->class = CSTATIC; - } -| lstring LLSTRING - { - char *s; - int n; - - n = $1->type->width - sizeof(ushort); - s = alloc(n+$2.l+MAXALIGN); - - memcpy(s, $1->rstring, n); - memcpy(s+n, $2.s, $2.l); - *(ushort*)(s+n+$2.l) = 0; - - $$ = $1; - $$->type->width += $2.l; - $$->rstring = (ushort*)s; - } - -zelist: - { - $$ = Z; - } -| elist - -elist: - expr -| elist ',' elist - { - $$ = new(OLIST, $1, $3); - } - -sbody: - '{' - { - $<tyty>$.t1 = strf; - $<tyty>$.t2 = strl; - $<tyty>$.t3 = lasttype; - $<tyty>$.c = lastclass; - strf = T; - strl = T; - lastbit = 0; - firstbit = 1; - lastclass = CXXX; - lasttype = T; - } - edecl '}' - { - $$ = strf; - strf = $<tyty>2.t1; - strl = $<tyty>2.t2; - lasttype = $<tyty>2.t3; - lastclass = $<tyty>2.c; - } - -zctlist: - { - lastclass = CXXX; - lasttype = types[TINT]; - } -| ctlist - -types: - complex - { - $$.t = $1; - $$.c = CXXX; - } -| tname - { - $$.t = simplet($1); - $$.c = CXXX; - } -| gcnlist - { - $$.t = simplet($1); - $$.c = simplec($1); - $$.t = garbt($$.t, $1); - } -| complex gctnlist - { - $$.t = $1; - $$.c = simplec($2); - $$.t = garbt($$.t, $2); - if($2 & ~BCLASS & ~BGARB) - diag(Z, "duplicate types given: %T and %Q", $1, $2); - } -| tname gctnlist - { - $$.t = simplet(typebitor($1, $2)); - $$.c = simplec($2); - $$.t = garbt($$.t, $2); - } -| gcnlist complex zgnlist - { - $$.t = $2; - $$.c = simplec($1); - $$.t = garbt($$.t, $1|$3); - } -| gcnlist tname - { - $$.t = simplet($2); - $$.c = simplec($1); - $$.t = garbt($$.t, $1); - } -| gcnlist tname gctnlist - { - $$.t = simplet(typebitor($2, $3)); - $$.c = simplec($1|$3); - $$.t = garbt($$.t, $1|$3); - } - -tlist: - types - { - $$ = $1.t; - if($1.c != CXXX) - diag(Z, "illegal combination of class 4: %s", cnames[$1.c]); - } - -ctlist: - types - { - lasttype = $1.t; - lastclass = $1.c; - } - -complex: - LSTRUCT ltag - { - dotag($2, TSTRUCT, 0); - $$ = $2->suetag; - } -| LSTRUCT ltag - { - dotag($2, TSTRUCT, autobn); - } - sbody - { - $$ = $2->suetag; - if($$->link != T) - diag(Z, "redeclare tag: %s", $2->name); - $$->link = $4; - sualign($$); - } -| LSTRUCT sbody - { - taggen++; - sprint(symb, "_%d_", taggen); - $$ = dotag(lookup(), TSTRUCT, autobn); - $$->link = $2; - sualign($$); - } -| LUNION ltag - { - dotag($2, TUNION, 0); - $$ = $2->suetag; - } -| LUNION ltag - { - dotag($2, TUNION, autobn); - } - sbody - { - $$ = $2->suetag; - if($$->link != T) - diag(Z, "redeclare tag: %s", $2->name); - $$->link = $4; - sualign($$); - } -| LUNION sbody - { - taggen++; - sprint(symb, "_%d_", taggen); - $$ = dotag(lookup(), TUNION, autobn); - $$->link = $2; - sualign($$); - } -| LENUM ltag - { - dotag($2, TENUM, 0); - $$ = $2->suetag; - if($$->link == T) - $$->link = types[TINT]; - $$ = $$->link; - } -| LENUM ltag - { - dotag($2, TENUM, autobn); - } - '{' - { - en.tenum = T; - en.cenum = T; - } - enum '}' - { - $$ = $2->suetag; - if($$->link != T) - diag(Z, "redeclare tag: %s", $2->name); - if(en.tenum == T) { - diag(Z, "enum type ambiguous: %s", $2->name); - en.tenum = types[TINT]; - } - $$->link = en.tenum; - $$ = en.tenum; - } -| LENUM '{' - { - en.tenum = T; - en.cenum = T; - } - enum '}' - { - $$ = en.tenum; - } -| LTYPE - { - $$ = tcopy($1->type); - } - -gctnlist: - gctname -| gctnlist gctname - { - $$ = typebitor($1, $2); - } - -zgnlist: - { - $$ = 0; - } -| zgnlist gname - { - $$ = typebitor($1, $2); - } - -gctname: - tname -| gname -| cname - -gcnlist: - gcname -| gcnlist gcname - { - $$ = typebitor($1, $2); - } - -gcname: - gname -| cname - -enum: - LNAME - { - doenum($1, Z); - } -| LNAME '=' expr - { - doenum($1, $3); - } -| enum ',' -| enum ',' enum - -tname: /* type words */ - LCHAR { $$ = BCHAR; } -| LSHORT { $$ = BSHORT; } -| LINT { $$ = BINT; } -| LLONG { $$ = BLONG; } -| LSIGNED { $$ = BSIGNED; } -| LUNSIGNED { $$ = BUNSIGNED; } -| LFLOAT { $$ = BFLOAT; } -| LDOUBLE { $$ = BDOUBLE; } -| LVOID { $$ = BVOID; } - -cname: /* class words */ - LAUTO { $$ = BAUTO; } -| LSTATIC { $$ = BSTATIC; } -| LEXTERN { $$ = BEXTERN; } -| LTYPEDEF { $$ = BTYPEDEF; } -| LTYPESTR { $$ = BTYPESTR; } -| LREGISTER { $$ = BREGISTER; } -| LINLINE { $$ = 0; } - -gname: /* garbage words */ - LCONSTNT { $$ = BCONSTNT; } -| LVOLATILE { $$ = BVOLATILE; } -| LRESTRICT { $$ = 0; } - -name: - LNAME - { - $$ = new(ONAME, Z, Z); - if($1->class == CLOCAL) - $1 = mkstatic($1); - $$->sym = $1; - $$->type = $1->type; - $$->etype = TVOID; - if($$->type != T) - $$->etype = $$->type->etype; - $$->xoffset = $1->offset; - $$->class = $1->class; - $1->aused = 1; - } -tag: - ltag - { - $$ = new(ONAME, Z, Z); - $$->sym = $1; - $$->type = $1->type; - $$->etype = TVOID; - if($$->type != T) - $$->etype = $$->type->etype; - $$->xoffset = $1->offset; - $$->class = $1->class; - } -ltag: - LNAME -| LTYPE -%% diff --git a/src/cmd/cc/com.c b/src/cmd/cc/com.c deleted file mode 100644 index 6e470ee64..000000000 --- a/src/cmd/cc/com.c +++ /dev/null @@ -1,1385 +0,0 @@ -// Inferno utils/cc/com.c -// http://code.google.com/p/inferno-os/source/browse/utils/cc/com.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" - -int compar(Node*, int); - -void -complex(Node *n) -{ - - if(n == Z) - return; - - nearln = n->lineno; - if(debug['t']) - if(n->op != OCONST) - prtree(n, "pre complex"); - if(tcom(n)) - return; - if(debug['t']) - if(n->op != OCONST) - prtree(n, "t complex"); - ccom(n); - if(debug['t']) - if(n->op != OCONST) - prtree(n, "c complex"); - acom(n); - if(debug['t']) - if(n->op != OCONST) - prtree(n, "a complex"); - xcom(n); - if(debug['t']) - if(n->op != OCONST) - prtree(n, "x complex"); -} - -/* - * evaluate types - * evaluate lvalues (addable == 1) - */ -enum -{ - ADDROF = 1<<0, - CASTOF = 1<<1, - ADDROP = 1<<2, -}; - -int -tcom(Node *n) -{ - - return tcomo(n, ADDROF); -} - -int -tcomo(Node *n, int f) -{ - Node *l, *r; - Type *t; - int o; - - if(n == Z) { - diag(Z, "Z in tcom"); - errorexit(); - } - n->addable = 0; - l = n->left; - r = n->right; - - switch(n->op) { - default: - diag(n, "unknown op in type complex: %O", n->op); - goto bad; - - case ODOTDOT: - /* - * tcom has already been called on this subtree - */ - *n = *n->left; - if(n->type == T) - goto bad; - break; - - case OCAST: - if(n->type == T) - break; - if(n->type->width == types[TLONG]->width) { - if(tcomo(l, ADDROF|CASTOF)) - goto bad; - } else - if(tcom(l)) - goto bad; - if(isfunct(n)) - break; - if(tcompat(n, l->type, n->type, tcast)) - goto bad; - break; - - case ORETURN: - if(l == Z) { - if(n->type->etype != TVOID) - diag(n, "null return of a typed function"); - break; - } - if(tcom(l)) - goto bad; - typeext(n->type, l); - if(tcompat(n, n->type, l->type, tasign)) - break; - constas(n, n->type, l->type); - if(!sametype(n->type, l->type)) { - l = new1(OCAST, l, Z); - l->type = n->type; - n->left = l; - } - break; - - case OASI: /* same as as, but no test for const */ - n->op = OAS; - o = tcom(l); - if(o | tcom(r)) - goto bad; - - typeext(l->type, r); - if(tlvalue(l) || tcompat(n, l->type, r->type, tasign)) - goto bad; - if(!sametype(l->type, r->type)) { - r = new1(OCAST, r, Z); - r->type = l->type; - n->right = r; - } - n->type = l->type; - break; - - case OAS: - o = tcom(l); - if(o | tcom(r)) - goto bad; - if(tlvalue(l)) - goto bad; - if(isfunct(n)) - break; - typeext(l->type, r); - if(tcompat(n, l->type, r->type, tasign)) - goto bad; - constas(n, l->type, r->type); - if(!sametype(l->type, r->type)) { - r = new1(OCAST, r, Z); - r->type = l->type; - n->right = r; - } - n->type = l->type; - break; - - case OASADD: - case OASSUB: - o = tcom(l); - if(o | tcom(r)) - goto bad; - if(tlvalue(l)) - goto bad; - if(isfunct(n)) - break; - typeext1(l->type, r); - if(tcompat(n, l->type, r->type, tasadd)) - goto bad; - constas(n, l->type, r->type); - t = l->type; - arith(n, 0); - while(n->left->op == OCAST) - n->left = n->left->left; - if(!sametype(t, n->type) && !mixedasop(t, n->type)) { - r = new1(OCAST, n->right, Z); - r->type = t; - n->right = r; - n->type = t; - } - break; - - case OASMUL: - case OASLMUL: - case OASDIV: - case OASLDIV: - o = tcom(l); - if(o | tcom(r)) - goto bad; - if(tlvalue(l)) - goto bad; - if(isfunct(n)) - break; - typeext1(l->type, r); - if(tcompat(n, l->type, r->type, tmul)) - goto bad; - constas(n, l->type, r->type); - t = l->type; - arith(n, 0); - while(n->left->op == OCAST) - n->left = n->left->left; - if(!sametype(t, n->type) && !mixedasop(t, n->type)) { - r = new1(OCAST, n->right, Z); - r->type = t; - n->right = r; - n->type = t; - } - if(typeu[n->type->etype]) { - if(n->op == OASDIV) - n->op = OASLDIV; - if(n->op == OASMUL) - n->op = OASLMUL; - } - break; - - case OASLSHR: - case OASASHR: - case OASASHL: - o = tcom(l); - if(o | tcom(r)) - goto bad; - if(tlvalue(l)) - goto bad; - if(isfunct(n)) - break; - if(tcompat(n, l->type, r->type, tand)) - goto bad; - n->type = l->type; - if(typeu[n->type->etype]) { - if(n->op == OASASHR) - n->op = OASLSHR; - } - break; - - case OASMOD: - case OASLMOD: - case OASOR: - case OASAND: - case OASXOR: - o = tcom(l); - if(o | tcom(r)) - goto bad; - if(tlvalue(l)) - goto bad; - if(isfunct(n)) - break; - if(tcompat(n, l->type, r->type, tand)) - goto bad; - t = l->type; - arith(n, 0); - while(n->left->op == OCAST) - n->left = n->left->left; - if(!sametype(t, n->type) && !mixedasop(t, n->type)) { - r = new1(OCAST, n->right, Z); - r->type = t; - n->right = r; - n->type = t; - } - if(typeu[n->type->etype]) { - if(n->op == OASMOD) - n->op = OASLMOD; - } - break; - - case OPREINC: - case OPREDEC: - case OPOSTINC: - case OPOSTDEC: - if(tcom(l)) - goto bad; - if(tlvalue(l)) - goto bad; - if(isfunct(n)) - break; - if(tcompat(n, l->type, types[TINT], tadd)) - goto bad; - n->type = l->type; - if(n->type->etype == TIND) - if(n->type->link->width < 1) - diag(n, "inc/dec of a void pointer"); - break; - - case OEQ: - case ONE: - o = tcom(l); - if(o | tcom(r)) - goto bad; - if(isfunct(n)) - break; - typeext(l->type, r); - typeext(r->type, l); - if(tcompat(n, l->type, r->type, trel)) - goto bad; - arith(n, 0); - n->type = types[TINT]; - break; - - case OLT: - case OGE: - case OGT: - case OLE: - o = tcom(l); - if(o | tcom(r)) - goto bad; - if(isfunct(n)) - break; - typeext1(l->type, r); - typeext1(r->type, l); - if(tcompat(n, l->type, r->type, trel)) - goto bad; - arith(n, 0); - if(typeu[n->type->etype]) - n->op = logrel[relindex(n->op)]; - n->type = types[TINT]; - break; - - case OCOND: - o = tcom(l); - o |= tcom(r->left); - if(o | tcom(r->right)) - goto bad; - if(r->right->type->etype == TIND && vconst(r->left) == 0) { - r->left->type = r->right->type; - r->left->vconst = 0; - } - if(r->left->type->etype == TIND && vconst(r->right) == 0) { - r->right->type = r->left->type; - r->right->vconst = 0; - } - if(sametype(r->right->type, r->left->type)) { - r->type = r->right->type; - n->type = r->type; - break; - } - if(tcompat(r, r->left->type, r->right->type, trel)) - goto bad; - arith(r, 0); - n->type = r->type; - break; - - case OADD: - o = tcom(l); - if(o | tcom(r)) - goto bad; - if(isfunct(n)) - break; - if(tcompat(n, l->type, r->type, tadd)) - goto bad; - arith(n, 1); - break; - - case OSUB: - o = tcom(l); - if(o | tcom(r)) - goto bad; - if(isfunct(n)) - break; - if(tcompat(n, l->type, r->type, tsub)) - goto bad; - arith(n, 1); - break; - - case OMUL: - case OLMUL: - case ODIV: - case OLDIV: - o = tcom(l); - if(o | tcom(r)) - goto bad; - if(isfunct(n)) - break; - if(tcompat(n, l->type, r->type, tmul)) - goto bad; - arith(n, 1); - if(typeu[n->type->etype]) { - if(n->op == ODIV) - n->op = OLDIV; - if(n->op == OMUL) - n->op = OLMUL; - } - break; - - case OLSHR: - case OASHL: - case OASHR: - o = tcom(l); - if(o | tcom(r)) - goto bad; - if(isfunct(n)) - break; - if(tcompat(n, l->type, r->type, tand)) - goto bad; - n->right = Z; - arith(n, 1); - n->right = new1(OCAST, r, Z); - n->right->type = types[TINT]; - if(typeu[n->type->etype]) - if(n->op == OASHR) - n->op = OLSHR; - break; - - case OAND: - case OOR: - case OXOR: - o = tcom(l); - if(o | tcom(r)) - goto bad; - if(isfunct(n)) - break; - if(tcompat(n, l->type, r->type, tand)) - goto bad; - arith(n, 1); - break; - - case OMOD: - case OLMOD: - o = tcom(l); - if(o | tcom(r)) - goto bad; - if(isfunct(n)) - break; - if(tcompat(n, l->type, r->type, tand)) - goto bad; - arith(n, 1); - if(typeu[n->type->etype]) - n->op = OLMOD; - break; - - case OPOS: - if(tcom(l)) - goto bad; - if(isfunct(n)) - break; - - r = l; - l = new(OCONST, Z, Z); - l->vconst = 0; - l->type = types[TINT]; - n->op = OADD; - n->right = r; - n->left = l; - - if(tcom(l)) - goto bad; - if(tcompat(n, l->type, r->type, tsub)) - goto bad; - arith(n, 1); - break; - - case ONEG: - if(tcom(l)) - goto bad; - if(isfunct(n)) - break; - - if(!machcap(n)) { - r = l; - l = new(OCONST, Z, Z); - l->vconst = 0; - l->type = types[TINT]; - n->op = OSUB; - n->right = r; - n->left = l; - - if(tcom(l)) - goto bad; - if(tcompat(n, l->type, r->type, tsub)) - goto bad; - } - arith(n, 1); - break; - - case OCOM: - if(tcom(l)) - goto bad; - if(isfunct(n)) - break; - - if(!machcap(n)) { - r = l; - l = new(OCONST, Z, Z); - l->vconst = -1; - l->type = types[TINT]; - n->op = OXOR; - n->right = r; - n->left = l; - - if(tcom(l)) - goto bad; - if(tcompat(n, l->type, r->type, tand)) - goto bad; - } - arith(n, 1); - break; - - case ONOT: - if(tcom(l)) - goto bad; - if(isfunct(n)) - break; - if(tcompat(n, T, l->type, tnot)) - goto bad; - n->type = types[TINT]; - break; - - case OANDAND: - case OOROR: - o = tcom(l); - if(o | tcom(r)) - goto bad; - if(tcompat(n, T, l->type, tnot) | - tcompat(n, T, r->type, tnot)) - goto bad; - n->type = types[TINT]; - break; - - case OCOMMA: - o = tcom(l); - if(o | tcom(r)) - goto bad; - n->type = r->type; - break; - - - case OSIGN: /* extension signof(type) returns a hash */ - if(l != Z) { - if(l->op != OSTRING && l->op != OLSTRING) - if(tcomo(l, 0)) - goto bad; - if(l->op == OBIT) { - diag(n, "signof bitfield"); - goto bad; - } - n->type = l->type; - } - if(n->type == T) - goto bad; - if(n->type->width < 0) { - diag(n, "signof undefined type"); - goto bad; - } - n->op = OCONST; - n->left = Z; - n->right = Z; - n->vconst = convvtox(signature(n->type), TULONG); - n->type = types[TULONG]; - break; - - case OSIZE: - if(l != Z) { - if(l->op != OSTRING && l->op != OLSTRING) - if(tcomo(l, 0)) - goto bad; - if(l->op == OBIT) { - diag(n, "sizeof bitfield"); - goto bad; - } - n->type = l->type; - } - if(n->type == T) - goto bad; - if(n->type->width <= 0) { - diag(n, "sizeof undefined type"); - goto bad; - } - if(n->type->etype == TFUNC) { - diag(n, "sizeof function"); - goto bad; - } - n->op = OCONST; - n->left = Z; - n->right = Z; - n->vconst = convvtox(n->type->width, TINT); - n->type = types[TINT]; - break; - - case OFUNC: - o = tcomo(l, 0); - if(o) - goto bad; - if(l->type->etype == TIND && l->type->link->etype == TFUNC) { - l = new1(OIND, l, Z); - l->type = l->left->type->link; - n->left = l; - } - if(tcompat(n, T, l->type, tfunct)) - goto bad; - if(o | tcoma(l, r, l->type->down, 1)) - goto bad; - n->type = l->type->link; - if(!debug['B']) - if(l->type->down == T || l->type->down->etype == TOLD) { - nerrors--; - diag(n, "function args not checked: %F", l); - } - dpcheck(n); - break; - - case ONAME: - if(n->type == T) { - diag(n, "name not declared: %F", n); - goto bad; - } - if(n->type->etype == TENUM) { - n->op = OCONST; - n->type = n->sym->tenum; - if(!typefd[n->type->etype]) - n->vconst = n->sym->vconst; - else - n->fconst = n->sym->fconst; - break; - } - n->addable = 1; - if(n->class == CEXREG) { - n->op = OREGISTER; - // on 386 or amd64, "extern register" generates - // memory references relative to the - // gs or fs segment. - if(thechar == '8' || thechar == '6') // [sic] - n->op = OEXREG; - n->reg = n->sym->offset; - n->xoffset = 0; - break; - } - break; - - case OLSTRING: - if(n->type->link != types[TUSHORT]) { - o = outstring(0, 0); - while(o & 3) { - ushort a[1]; - a[0] = 0; - outlstring(a, sizeof(ushort)); - o = outlstring(0, 0); - } - } - n->op = ONAME; - n->xoffset = outlstring(n->rstring, n->type->width); - n->addable = 1; - break; - - case OSTRING: - if(n->type->link != types[TCHAR]) { - o = outstring(0, 0); - while(o & 3) { - outstring("", 1); - o = outstring(0, 0); - } - } - n->op = ONAME; - n->xoffset = outstring(n->cstring, n->type->width); - n->addable = 1; - break; - - case OCONST: - break; - - case ODOT: - if(tcom(l)) - goto bad; - if(tcompat(n, T, l->type, tdot)) - goto bad; - if(tcomd(n)) - goto bad; - break; - - case OADDR: - if(tcomo(l, ADDROP)) - goto bad; - if(tlvalue(l)) - goto bad; - if(l->type->nbits) { - diag(n, "address of a bit field"); - goto bad; - } - if(l->op == OREGISTER) { - diag(n, "address of a register"); - goto bad; - } - n->type = typ(TIND, l->type); - n->type->width = types[TIND]->width; - break; - - case OIND: - if(tcom(l)) - goto bad; - if(tcompat(n, T, l->type, tindir)) - goto bad; - n->type = l->type->link; - n->addable = 1; - break; - - case OSTRUCT: - if(tcomx(n)) - goto bad; - break; - } - t = n->type; - if(t == T) - goto bad; - if(t->width < 0) { - snap(t); - if(t->width < 0) { - if(typesu[t->etype] && t->tag) - diag(n, "structure not fully declared %s", t->tag->name); - else - diag(n, "structure not fully declared"); - goto bad; - } - } - if(typeaf[t->etype]) { - if(f & ADDROF) - goto addaddr; - if(f & ADDROP) - warn(n, "address of array/func ignored"); - } - return 0; - -addaddr: - if(tlvalue(n)) - goto bad; - l = new1(OXXX, Z, Z); - *l = *n; - n->op = OADDR; - if(l->type->etype == TARRAY) - l->type = l->type->link; - n->left = l; - n->right = Z; - n->addable = 0; - n->type = typ(TIND, l->type); - n->type->width = types[TIND]->width; - return 0; - -bad: - n->type = T; - return 1; -} - -int -tcoma(Node *l, Node *n, Type *t, int f) -{ - Node *n1; - int o; - - if(t != T) - if(t->etype == TOLD || t->etype == TDOT) /* .../old in prototype */ - t = T; - if(n == Z) { - if(t != T && !sametype(t, types[TVOID])) { - diag(n, "not enough function arguments: %F", l); - return 1; - } - return 0; - } - if(n->op == OLIST) { - o = tcoma(l, n->left, t, 0); - if(t != T) { - t = t->down; - if(t == T) - t = types[TVOID]; - } - return o | tcoma(l, n->right, t, 1); - } - if(f && t != T) - tcoma(l, Z, t->down, 0); - if(tcom(n) || tcompat(n, T, n->type, targ)) - return 1; - if(sametype(t, types[TVOID])) { - diag(n, "too many function arguments: %F", l); - return 1; - } - if(t != T) { - typeext(t, n); - if(stcompat(nodproto, t, n->type, tasign)) { - diag(l, "argument prototype mismatch \"%T\" for \"%T\": %F", - n->type, t, l); - return 1; - } -// switch(t->etype) { -// case TCHAR: -// case TSHORT: -// t = types[TINT]; -// break; -// -// case TUCHAR: -// case TUSHORT: -// t = types[TUINT]; -// break; -// } - } else { - switch(n->type->etype) { - case TCHAR: - case TSHORT: - t = types[TINT]; - break; - - case TUCHAR: - case TUSHORT: - t = types[TUINT]; - break; - - case TFLOAT: - t = types[TDOUBLE]; - } - } - - if(t != T && !sametype(t, n->type)) { - n1 = new1(OXXX, Z, Z); - *n1 = *n; - n->op = OCAST; - n->left = n1; - n->right = Z; - n->type = t; - n->addable = 0; - } - return 0; -} - -int -tcomd(Node *n) -{ - Type *t; - int32 o; - - o = 0; - t = dotsearch(n->sym, n->left->type->link, n, &o); - if(t == T) { - diag(n, "not a member of struct/union: %F", n); - return 1; - } - makedot(n, t, o); - return 0; -} - -int -tcomx(Node *n) -{ - Type *t; - Node *l, *r, **ar, **al; - int e; - - e = 0; - if(n->type->etype != TSTRUCT) { - diag(n, "constructor must be a structure"); - return 1; - } - l = invert(n->left); - n->left = l; - al = &n->left; - for(t = n->type->link; t != T; t = t->down) { - if(l == Z) { - diag(n, "constructor list too short"); - return 1; - } - if(l->op == OLIST) { - r = l->left; - ar = &l->left; - al = &l->right; - l = l->right; - } else { - r = l; - ar = al; - l = Z; - } - if(tcom(r)) - e++; - typeext(t, r); - if(tcompat(n, t, r->type, tasign)) - e++; - constas(n, t, r->type); - if(!e && !sametype(t, r->type)) { - r = new1(OCAST, r, Z); - r->type = t; - *ar = r; - } - } - if(l != Z) { - diag(n, "constructor list too long"); - return 1; - } - return e; -} - -int -tlvalue(Node *n) -{ - - if(!n->addable) { - diag(n, "not an l-value"); - return 1; - } - return 0; -} - -/* - * general rewrite - * (IND(ADDR x)) ==> x - * (ADDR(IND x)) ==> x - * remove some zero operands - * remove no op casts - * evaluate constants - */ -void -ccom(Node *n) -{ - Node *l, *r; - int t; - -loop: - if(n == Z) - return; - l = n->left; - r = n->right; - switch(n->op) { - - case OAS: - case OASXOR: - case OASAND: - case OASOR: - case OASMOD: - case OASLMOD: - case OASLSHR: - case OASASHR: - case OASASHL: - case OASDIV: - case OASLDIV: - case OASMUL: - case OASLMUL: - case OASSUB: - case OASADD: - ccom(l); - ccom(r); - if(n->op == OASLSHR || n->op == OASASHR || n->op == OASASHL) - if(r->op == OCONST) { - t = n->type->width * 8; /* bits per byte */ - if(r->vconst >= t || r->vconst < 0) - warn(n, "stupid shift: %lld", r->vconst); - } - break; - - case OCAST: - ccom(l); - if(l->op == OCONST) { - evconst(n); - if(n->op == OCONST) - break; - } - if(nocast(l->type, n->type)) { - l->type = n->type; - *n = *l; - } - break; - - case OCOND: - ccom(l); - ccom(r); - if(l->op == OCONST) - if(vconst(l) == 0) - *n = *r->right; - else - *n = *r->left; - break; - - case OREGISTER: - case OINDREG: - case OCONST: - case ONAME: - break; - - case OADDR: - ccom(l); - l->etype = TVOID; - if(l->op == OIND) { - l->left->type = n->type; - *n = *l->left; - break; - } - goto common; - - case OIND: - ccom(l); - if(l->op == OADDR) { - l->left->type = n->type; - *n = *l->left; - break; - } - goto common; - - case OEQ: - case ONE: - - case OLE: - case OGE: - case OLT: - case OGT: - - case OLS: - case OHS: - case OLO: - case OHI: - ccom(l); - ccom(r); - if(compar(n, 0) || compar(n, 1)) - break; - relcon(l, r); - relcon(r, l); - goto common; - - case OASHR: - case OASHL: - case OLSHR: - ccom(l); - if(vconst(l) == 0 && !side(r)) { - *n = *l; - break; - } - ccom(r); - if(vconst(r) == 0) { - *n = *l; - break; - } - if(r->op == OCONST) { - t = n->type->width * 8; /* bits per byte */ - if(r->vconst >= t || r->vconst <= -t) - warn(n, "stupid shift: %lld", r->vconst); - } - goto common; - - case OMUL: - case OLMUL: - ccom(l); - t = vconst(l); - if(t == 0 && !side(r)) { - *n = *l; - break; - } - if(t == 1) { - *n = *r; - goto loop; - } - ccom(r); - t = vconst(r); - if(t == 0 && !side(l)) { - *n = *r; - break; - } - if(t == 1) { - *n = *l; - break; - } - goto common; - - case ODIV: - case OLDIV: - ccom(l); - if(vconst(l) == 0 && !side(r)) { - *n = *l; - break; - } - ccom(r); - t = vconst(r); - if(t == 0) { - diag(n, "divide check"); - *n = *r; - break; - } - if(t == 1) { - *n = *l; - break; - } - goto common; - - case OSUB: - ccom(r); - if(r->op == OCONST) { - if(typefd[r->type->etype]) { - n->op = OADD; - r->fconst = -r->fconst; - goto loop; - } else { - n->op = OADD; - r->vconst = -r->vconst; - goto loop; - } - } - ccom(l); - goto common; - - case OXOR: - case OOR: - case OADD: - ccom(l); - if(vconst(l) == 0) { - *n = *r; - goto loop; - } - ccom(r); - if(vconst(r) == 0) { - *n = *l; - break; - } - goto commute; - - case OAND: - ccom(l); - ccom(r); - if(vconst(l) == 0 && !side(r)) { - *n = *l; - break; - } - if(vconst(r) == 0 && !side(l)) { - *n = *r; - break; - } - - commute: - /* look for commutative constant */ - if(r->op == OCONST) { - if(l->op == n->op) { - if(l->left->op == OCONST) { - n->right = l->right; - l->right = r; - goto loop; - } - if(l->right->op == OCONST) { - n->right = l->left; - l->left = r; - goto loop; - } - } - } - if(l->op == OCONST) { - if(r->op == n->op) { - if(r->left->op == OCONST) { - n->left = r->right; - r->right = l; - goto loop; - } - if(r->right->op == OCONST) { - n->left = r->left; - r->left = l; - goto loop; - } - } - } - goto common; - - case OANDAND: - ccom(l); - if(vconst(l) == 0) { - *n = *l; - break; - } - ccom(r); - goto common; - - case OOROR: - ccom(l); - if(l->op == OCONST && l->vconst != 0) { - *n = *l; - n->vconst = 1; - break; - } - ccom(r); - goto common; - - default: - if(l != Z) - ccom(l); - if(r != Z) - ccom(r); - common: - if(l != Z) - if(l->op != OCONST) - break; - if(r != Z) - if(r->op != OCONST) - break; - evconst(n); - } -} - -/* OEQ, ONE, OLE, OLS, OLT, OLO, OGE, OHS, OGT, OHI */ -static char *cmps[12] = -{ - "==", "!=", "<=", "<=", "<", "<", ">=", ">=", ">", ">", -}; - -/* 128-bit numbers */ -typedef struct Big Big; -struct Big -{ - vlong a; - uvlong b; -}; -static int -cmp(Big x, Big y) -{ - if(x.a != y.a){ - if(x.a < y.a) - return -1; - return 1; - } - if(x.b != y.b){ - if(x.b < y.b) - return -1; - return 1; - } - return 0; -} -static Big -add(Big x, int y) -{ - uvlong ob; - - ob = x.b; - x.b += y; - if(y > 0 && x.b < ob) - x.a++; - if(y < 0 && x.b > ob) - x.a--; - return x; -} - -Big -big(vlong a, uvlong b) -{ - Big x; - - x.a = a; - x.b = b; - return x; -} - -int -compar(Node *n, int reverse) -{ - Big lo, hi, x; - int op; - char xbuf[40], cmpbuf[50]; - Node *l, *r; - Type *lt, *rt; - - /* - * The point of this function is to diagnose comparisons - * that can never be true or that look misleading because - * of the `usual arithmetic conversions'. As an example - * of the latter, if x is a ulong, then if(x <= -1) really means - * if(x <= 0xFFFFFFFF), while if(x <= -1LL) really means - * what it says (but 8c compiles it wrong anyway). - */ - - if(reverse){ - r = n->left; - l = n->right; - op = comrel[relindex(n->op)]; - }else{ - l = n->left; - r = n->right; - op = n->op; - } - - /* - * Skip over left casts to find out the original expression range. - */ - while(l->op == OCAST) - l = l->left; - if(l->op == OCONST) - return 0; - lt = l->type; - if(l->op == ONAME && l->sym->type){ - lt = l->sym->type; - if(lt->etype == TARRAY) - lt = lt->link; - } - if(lt == T) - return 0; - if(lt->etype == TXXX || lt->etype > TUVLONG) - return 0; - - /* - * Skip over the right casts to find the on-screen value. - */ - if(r->op != OCONST) - return 0; - while(r->oldop == OCAST && !r->xcast) - r = r->left; - rt = r->type; - if(rt == T) - return 0; - - x.b = r->vconst; - x.a = 0; - if((rt->etype&1) && r->vconst < 0) /* signed negative */ - x.a = ~0ULL; - - if((lt->etype&1)==0){ - /* unsigned */ - lo = big(0, 0); - if(lt->width == 8) - hi = big(0, ~0ULL); - else - hi = big(0, (1LL<<(l->type->width*8))-1); - }else{ - lo = big(~0ULL, -(1LL<<(l->type->width*8-1))); - hi = big(0, (1LL<<(l->type->width*8-1))-1); - } - - switch(op){ - case OLT: - case OLO: - case OGE: - case OHS: - if(cmp(x, lo) <= 0) - goto useless; - if(cmp(x, add(hi, 1)) >= 0) - goto useless; - break; - case OLE: - case OLS: - case OGT: - case OHI: - if(cmp(x, add(lo, -1)) <= 0) - goto useless; - if(cmp(x, hi) >= 0) - goto useless; - break; - case OEQ: - case ONE: - /* - * Don't warn about comparisons if the expression - * is as wide as the value: the compiler-supplied casts - * will make both outcomes possible. - */ - if(lt->width >= rt->width && debug['w'] < 2) - return 0; - if(cmp(x, lo) < 0 || cmp(x, hi) > 0) - goto useless; - break; - } - return 0; - -useless: - if((x.a==0 && x.b<=9) || (x.a==~0LL && x.b >= -9ULL)) - snprint(xbuf, sizeof xbuf, "%lld", x.b); - else if(x.a == 0) - snprint(xbuf, sizeof xbuf, "%#llux", x.b); - else - snprint(xbuf, sizeof xbuf, "%#llx", x.b); - if(reverse) - snprint(cmpbuf, sizeof cmpbuf, "%s %s %T", - xbuf, cmps[relindex(n->op)], lt); - else - snprint(cmpbuf, sizeof cmpbuf, "%T %s %s", - lt, cmps[relindex(n->op)], xbuf); - warn(n, "useless or misleading comparison: %s", cmpbuf); - return 0; -} - diff --git a/src/cmd/cc/com64.c b/src/cmd/cc/com64.c deleted file mode 100644 index fb7a3f750..000000000 --- a/src/cmd/cc/com64.c +++ /dev/null @@ -1,644 +0,0 @@ -// Inferno utils/cc/com64.c -// http://code.google.com/p/inferno-os/source/browse/utils/cc/com64.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" - -/* - * this is machine depend, but it is totally - * common on all of the 64-bit symulating machines. - */ - -#define FNX 100 /* botch -- redefinition */ - -Node* nodaddv; -Node* nodsubv; -Node* nodmulv; -Node* noddivv; -Node* noddivvu; -Node* nodmodv; -Node* nodmodvu; -Node* nodlshv; -Node* nodrshav; -Node* nodrshlv; -Node* nodandv; -Node* nodorv; -Node* nodxorv; -Node* nodnegv; -Node* nodcomv; - -Node* nodtestv; -Node* nodeqv; -Node* nodnev; -Node* nodlev; -Node* nodltv; -Node* nodgev; -Node* nodgtv; -Node* nodhiv; -Node* nodhsv; -Node* nodlov; -Node* nodlsv; - -Node* nodf2v; -Node* nodd2v; -Node* nodp2v; -Node* nodsi2v; -Node* nodui2v; -Node* nodsl2v; -Node* nodul2v; -Node* nodsh2v; -Node* noduh2v; -Node* nodsc2v; -Node* noduc2v; - -Node* nodv2f; -Node* nodv2d; -Node* nodv2ui; -Node* nodv2si; -Node* nodv2ul; -Node* nodv2sl; -Node* nodv2uh; -Node* nodv2sh; -Node* nodv2uc; -Node* nodv2sc; - -Node* nodvpp; -Node* nodppv; -Node* nodvmm; -Node* nodmmv; - -Node* nodvasop; - -char etconv[NTYPE]; /* for _vasop */ -Init initetconv[] = -{ - TCHAR, 1, 0, - TUCHAR, 2, 0, - TSHORT, 3, 0, - TUSHORT, 4, 0, - TLONG, 5, 0, - TULONG, 6, 0, - TVLONG, 7, 0, - TUVLONG, 8, 0, - TINT, 9, 0, - TUINT, 10, 0, - -1, 0, 0, -}; - -Node* -fvn(char *name, int type) -{ - Node *n; - - n = new(ONAME, Z, Z); - n->sym = slookup(name); - n->sym->sig = SIGINTERN; - if(fntypes[type] == 0) - fntypes[type] = typ(TFUNC, types[type]); - n->type = fntypes[type]; - n->etype = type; - n->class = CGLOBL; - n->addable = 10; - n->complex = 0; - return n; -} - -void -com64init(void) -{ - Init *p; - - nodaddv = fvn("_addv", TVLONG); - nodsubv = fvn("_subv", TVLONG); - nodmulv = fvn("_mulv", TVLONG); - noddivv = fvn("_divv", TVLONG); - noddivvu = fvn("_divvu", TVLONG); - nodmodv = fvn("_modv", TVLONG); - nodmodvu = fvn("_modvu", TVLONG); - nodlshv = fvn("_lshv", TVLONG); - nodrshav = fvn("_rshav", TVLONG); - nodrshlv = fvn("_rshlv", TVLONG); - nodandv = fvn("_andv", TVLONG); - nodorv = fvn("_orv", TVLONG); - nodxorv = fvn("_xorv", TVLONG); - nodnegv = fvn("_negv", TVLONG); - nodcomv = fvn("_comv", TVLONG); - - nodtestv = fvn("_testv", TLONG); - nodeqv = fvn("_eqv", TLONG); - nodnev = fvn("_nev", TLONG); - nodlev = fvn("_lev", TLONG); - nodltv = fvn("_ltv", TLONG); - nodgev = fvn("_gev", TLONG); - nodgtv = fvn("_gtv", TLONG); - nodhiv = fvn("_hiv", TLONG); - nodhsv = fvn("_hsv", TLONG); - nodlov = fvn("_lov", TLONG); - nodlsv = fvn("_lsv", TLONG); - - nodf2v = fvn("_f2v", TVLONG); - nodd2v = fvn("_d2v", TVLONG); - nodp2v = fvn("_p2v", TVLONG); - nodsi2v = fvn("_si2v", TVLONG); - nodui2v = fvn("_ui2v", TVLONG); - nodsl2v = fvn("_sl2v", TVLONG); - nodul2v = fvn("_ul2v", TVLONG); - nodsh2v = fvn("_sh2v", TVLONG); - noduh2v = fvn("_uh2v", TVLONG); - nodsc2v = fvn("_sc2v", TVLONG); - noduc2v = fvn("_uc2v", TVLONG); - - nodv2f = fvn("_v2f", TFLOAT); - nodv2d = fvn("_v2d", TDOUBLE); - nodv2sl = fvn("_v2sl", TLONG); - nodv2ul = fvn("_v2ul", TULONG); - nodv2si = fvn("_v2si", TINT); - nodv2ui = fvn("_v2ui", TUINT); - nodv2sh = fvn("_v2sh", TSHORT); - nodv2uh = fvn("_v2ul", TUSHORT); - nodv2sc = fvn("_v2sc", TCHAR); - nodv2uc = fvn("_v2uc", TUCHAR); - - nodvpp = fvn("_vpp", TVLONG); - nodppv = fvn("_ppv", TVLONG); - nodvmm = fvn("_vmm", TVLONG); - nodmmv = fvn("_mmv", TVLONG); - - nodvasop = fvn("_vasop", TVLONG); - - for(p = initetconv; p->code >= 0; p++) - etconv[p->code] = p->value; -} - -int -com64(Node *n) -{ - Node *l, *r, *a, *t; - int lv, rv; - - if(n->type == 0) - return 0; - - l = n->left; - r = n->right; - - lv = 0; - if(l && l->type && typev[l->type->etype]) - lv = 1; - rv = 0; - if(r && r->type && typev[r->type->etype]) - rv = 1; - - if(lv) { - switch(n->op) { - case OEQ: - a = nodeqv; - goto setbool; - case ONE: - a = nodnev; - goto setbool; - case OLE: - a = nodlev; - goto setbool; - case OLT: - a = nodltv; - goto setbool; - case OGE: - a = nodgev; - goto setbool; - case OGT: - a = nodgtv; - goto setbool; - case OHI: - a = nodhiv; - goto setbool; - case OHS: - a = nodhsv; - goto setbool; - case OLO: - a = nodlov; - goto setbool; - case OLS: - a = nodlsv; - goto setbool; - - case OANDAND: - case OOROR: - if(machcap(n)) - return 1; - - if(rv) { - r = new(OFUNC, nodtestv, r); - n->right = r; - r->complex = FNX; - r->op = OFUNC; - r->type = types[TLONG]; - } - - case OCOND: - case ONOT: - if(machcap(n)) - return 1; - - l = new(OFUNC, nodtestv, l); - n->left = l; - l->complex = FNX; - l->op = OFUNC; - l->type = types[TLONG]; - n->complex = FNX; - return 1; - } - } - - if(rv) { - if(machcap(n)) - return 1; - switch(n->op) { - case OANDAND: - case OOROR: - r = new(OFUNC, nodtestv, r); - n->right = r; - r->complex = FNX; - r->op = OFUNC; - r->type = types[TLONG]; - return 1; - } - } - - if(typev[n->type->etype]) { - if(machcap(n)) - return 1; - switch(n->op) { - default: - diag(n, "unknown vlong %O", n->op); - case OFUNC: - n->complex = FNX; - case ORETURN: - case OAS: - case OIND: - return 1; - case OADD: - a = nodaddv; - goto setbop; - case OSUB: - a = nodsubv; - goto setbop; - case OMUL: - case OLMUL: - a = nodmulv; - goto setbop; - case ODIV: - a = noddivv; - goto setbop; - case OLDIV: - a = noddivvu; - goto setbop; - case OMOD: - a = nodmodv; - goto setbop; - case OLMOD: - a = nodmodvu; - goto setbop; - case OASHL: - a = nodlshv; - goto setbop; - case OASHR: - a = nodrshav; - goto setbop; - case OLSHR: - a = nodrshlv; - goto setbop; - case OAND: - a = nodandv; - goto setbop; - case OOR: - a = nodorv; - goto setbop; - case OXOR: - a = nodxorv; - goto setbop; - case OPOSTINC: - a = nodvpp; - goto setvinc; - case OPOSTDEC: - a = nodvmm; - goto setvinc; - case OPREINC: - a = nodppv; - goto setvinc; - case OPREDEC: - a = nodmmv; - goto setvinc; - case ONEG: - a = nodnegv; - goto setfnx; - case OCOM: - a = nodcomv; - goto setfnx; - case OCAST: - switch(l->type->etype) { - case TCHAR: - a = nodsc2v; - goto setfnxl; - case TUCHAR: - a = noduc2v; - goto setfnxl; - case TSHORT: - a = nodsh2v; - goto setfnxl; - case TUSHORT: - a = noduh2v; - goto setfnxl; - case TINT: - a = nodsi2v; - goto setfnx; - case TUINT: - a = nodui2v; - goto setfnx; - case TLONG: - a = nodsl2v; - goto setfnx; - case TULONG: - a = nodul2v; - goto setfnx; - case TFLOAT: - a = nodf2v; - goto setfnx; - case TDOUBLE: - a = nodd2v; - goto setfnx; - case TIND: - a = nodp2v; - goto setfnx; - } - diag(n, "unknown %T->vlong cast", l->type); - return 1; - case OASADD: - a = nodaddv; - goto setasop; - case OASSUB: - a = nodsubv; - goto setasop; - case OASMUL: - case OASLMUL: - a = nodmulv; - goto setasop; - case OASDIV: - a = noddivv; - goto setasop; - case OASLDIV: - a = noddivvu; - goto setasop; - case OASMOD: - a = nodmodv; - goto setasop; - case OASLMOD: - a = nodmodvu; - goto setasop; - case OASASHL: - a = nodlshv; - goto setasop; - case OASASHR: - a = nodrshav; - goto setasop; - case OASLSHR: - a = nodrshlv; - goto setasop; - case OASAND: - a = nodandv; - goto setasop; - case OASOR: - a = nodorv; - goto setasop; - case OASXOR: - a = nodxorv; - goto setasop; - } - } - - if(typefd[n->type->etype] && l && l->op == OFUNC) { - switch(n->op) { - case OASADD: - case OASSUB: - case OASMUL: - case OASLMUL: - case OASDIV: - case OASLDIV: - case OASMOD: - case OASLMOD: - case OASASHL: - case OASASHR: - case OASLSHR: - case OASAND: - case OASOR: - case OASXOR: - if(l->right && typev[l->right->etype]) { - diag(n, "sorry float <asop> vlong not implemented\n"); - } - } - } - - if(n->op == OCAST) { - if(l->type && typev[l->type->etype]) { - if(machcap(n)) - return 1; - switch(n->type->etype) { - case TDOUBLE: - a = nodv2d; - goto setfnx; - case TFLOAT: - a = nodv2f; - goto setfnx; - case TLONG: - a = nodv2sl; - goto setfnx; - case TULONG: - a = nodv2ul; - goto setfnx; - case TINT: - a = nodv2si; - goto setfnx; - case TUINT: - a = nodv2ui; - goto setfnx; - case TSHORT: - a = nodv2sh; - goto setfnx; - case TUSHORT: - a = nodv2uh; - goto setfnx; - case TCHAR: - a = nodv2sc; - goto setfnx; - case TUCHAR: - a = nodv2uc; - goto setfnx; - case TIND: // small pun here - a = nodv2ul; - goto setfnx; - } - diag(n, "unknown vlong->%T cast", n->type); - return 1; - } - } - - return 0; - -setbop: - n->left = a; - n->right = new(OLIST, l, r); - n->complex = FNX; - n->op = OFUNC; - return 1; - -setfnxl: - l = new(OCAST, l, 0); - l->type = types[TLONG]; - l->complex = l->left->complex; - -setfnx: - n->left = a; - n->right = l; - n->complex = FNX; - n->op = OFUNC; - return 1; - -setvinc: - n->left = a; - l = new(OADDR, l, Z); - l->type = typ(TIND, l->left->type); - n->right = new(OLIST, l, r); - n->complex = FNX; - n->op = OFUNC; - return 1; - -setbool: - if(machcap(n)) - return 1; - n->left = a; - n->right = new(OLIST, l, r); - n->complex = FNX; - n->op = OFUNC; - n->type = types[TLONG]; - return 1; - -setasop: - if(l->op == OFUNC) { - l = l->right; - goto setasop; - } - - t = new(OCONST, 0, 0); - t->vconst = etconv[l->type->etype]; - t->type = types[TLONG]; - t->addable = 20; - r = new(OLIST, t, r); - - t = new(OADDR, a, 0); - t->type = typ(TIND, a->type); - r = new(OLIST, t, r); - - t = new(OADDR, l, 0); - t->type = typ(TIND, l->type); - r = new(OLIST, t, r); - - n->left = nodvasop; - n->right = r; - n->complex = FNX; - n->op = OFUNC; - - return 1; -} - -void -bool64(Node *n) -{ - Node *n1; - - if(machcap(Z)) - return; - if(typev[n->type->etype]) { - n1 = new(OXXX, 0, 0); - *n1 = *n; - - n->right = n1; - n->left = nodtestv; - n->complex = FNX; - n->addable = 0; - n->op = OFUNC; - n->type = types[TLONG]; - } -} - -/* - * more machine depend stuff. - * this is common for 8,16,32,64 bit machines. - * this is common for ieee machines. - */ -double -convvtof(vlong v) -{ - double d; - - d = v; /* BOTCH */ - return d; -} - -vlong -convftov(double d) -{ - vlong v; - - - v = d; /* BOTCH */ - return v; -} - -double -convftox(double d, int et) -{ - - if(!typefd[et]) - diag(Z, "bad type in castftox %s", tnames[et]); - return d; -} - -vlong -convvtox(vlong c, int et) -{ - int n; - - n = 8 * ewidth[et]; - c &= MASK(n); - if(!typeu[et]) - if(c & SIGN(n)) - c |= ~MASK(n); - return c; -} diff --git a/src/cmd/cc/dcl.c b/src/cmd/cc/dcl.c deleted file mode 100644 index d624bf247..000000000 --- a/src/cmd/cc/dcl.c +++ /dev/null @@ -1,1669 +0,0 @@ -// Inferno utils/cc/dcl.c -// http://code.google.com/p/inferno-os/source/browse/utils/cc/dcl.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" - -Node* -dodecl(void (*f)(int,Type*,Sym*), int c, Type *t, Node *n) -{ - Sym *s; - Node *n1; - int32 v; - - nearln = lineno; - lastfield = 0; - -loop: - if(n != Z) - switch(n->op) { - default: - diag(n, "unknown declarator: %O", n->op); - break; - - case OARRAY: - t = typ(TARRAY, t); - t->width = 0; - n1 = n->right; - n = n->left; - if(n1 != Z) { - complex(n1); - v = -1; - if(n1->op == OCONST) - v = n1->vconst; - if(v <= 0) { - diag(n, "array size must be a positive constant"); - v = 1; - } - t->width = v * t->link->width; - } - goto loop; - - case OIND: - t = typ(TIND, t); - t->garb = n->garb; - n = n->left; - goto loop; - - case OFUNC: - t = typ(TFUNC, t); - t->down = fnproto(n); - n = n->left; - goto loop; - - case OBIT: - n1 = n->right; - complex(n1); - lastfield = -1; - if(n1->op == OCONST) - lastfield = n1->vconst; - if(lastfield < 0) { - diag(n, "field width must be non-negative constant"); - lastfield = 1; - } - if(lastfield == 0) { - lastbit = 0; - firstbit = 1; - if(n->left != Z) { - diag(n, "zero width named field"); - lastfield = 1; - } - } - if(!typei[t->etype]) { - diag(n, "field type must be int-like"); - t = types[TINT]; - lastfield = 1; - } - if(lastfield > tfield->width*8) { - diag(n, "field width larger than field unit"); - lastfield = 1; - } - lastbit += lastfield; - if(lastbit > tfield->width*8) { - lastbit = lastfield; - firstbit = 1; - } - n = n->left; - goto loop; - - case ONAME: - if(f == NODECL) - break; - s = n->sym; - (*f)(c, t, s); - if(s->class == CLOCAL) - s = mkstatic(s); - firstbit = 0; - n->sym = s; - n->type = s->type; - n->xoffset = s->offset; - n->class = s->class; - n->etype = TVOID; - if(n->type != T) - n->etype = n->type->etype; - if(debug['d']) - dbgdecl(s); - acidvar(s); - godefvar(s); - s->varlineno = lineno; - break; - } - lastdcl = t; - return n; -} - -Sym* -mkstatic(Sym *s) -{ - Sym *s1; - - if(s->class != CLOCAL) - return s; - snprint(symb, NSYMB, "%s$%d", s->name, s->block); - s1 = lookup(); - if(s1->class != CSTATIC) { - s1->type = s->type; - s1->offset = s->offset; - s1->block = s->block; - s1->class = CSTATIC; - } - return s1; -} - -/* - * make a copy of a typedef - * the problem is to split out incomplete - * arrays so that it is in the variable - * rather than the typedef. - */ -Type* -tcopy(Type *t) -{ - Type *tl, *tx; - int et; - - if(t == T) - return t; - et = t->etype; - if(typesu[et]) - return t; - tl = tcopy(t->link); - if(tl != t->link || - (et == TARRAY && t->width == 0)) { - tx = copytyp(t); - tx->link = tl; - return tx; - } - return t; -} - -Node* -doinit(Sym *s, Type *t, int32 o, Node *a) -{ - Node *n; - - if(t == T) - return Z; - if(s->class == CEXTERN) { - s->class = CGLOBL; - if(debug['d']) - dbgdecl(s); - } - if(debug['i']) { - print("t = %T; o = %d; n = %s\n", t, o, s->name); - prtree(a, "doinit value"); - } - - - n = initlist; - if(a->op == OINIT) - a = a->left; - initlist = a; - - a = init1(s, t, o, 0); - if(initlist != Z) - diag(initlist, "more initializers than structure: %s", - s->name); - initlist = n; - - return a; -} - -/* - * get next major operator, - * dont advance initlist. - */ -Node* -peekinit(void) -{ - Node *a; - - a = initlist; - -loop: - if(a == Z) - return a; - if(a->op == OLIST) { - a = a->left; - goto loop; - } - return a; -} - -/* - * consume and return next element on - * initlist. expand strings. - */ -Node* -nextinit(void) -{ - Node *a, *b, *n; - - a = initlist; - n = Z; - - if(a == Z) - return a; - if(a->op == OLIST) { - n = a->right; - a = a->left; - } - if(a->op == OUSED) { - a = a->left; - b = new(OCONST, Z, Z); - b->type = a->type->link; - if(a->op == OSTRING) { - b->vconst = convvtox(*a->cstring, TCHAR); - a->cstring++; - } - if(a->op == OLSTRING) { - b->vconst = convvtox(*a->rstring, TUSHORT); - a->rstring++; - } - a->type->width -= b->type->width; - if(a->type->width <= 0) - initlist = n; - return b; - } - initlist = n; - return a; -} - -int -isstruct(Node *a, Type *t) -{ - Node *n; - - switch(a->op) { - case ODOTDOT: - n = a->left; - if(n && n->type && sametype(n->type, t)) - return 1; - case OSTRING: - case OLSTRING: - case OCONST: - case OINIT: - case OELEM: - return 0; - } - - n = new(ODOTDOT, Z, Z); - *n = *a; - - /* - * ODOTDOT is a flag for tcom - * a second tcom will not be performed - */ - a->op = ODOTDOT; - a->left = n; - a->right = Z; - - if(tcom(n)) - return 0; - - if(sametype(n->type, t)) - return 1; - return 0; -} - -Node* -init1(Sym *s, Type *t, int32 o, int exflag) -{ - Node *a, *l, *r, nod; - Type *t1; - int32 e, w, so, mw; - - a = peekinit(); - if(a == Z) - return Z; - - if(debug['i']) { - print("t = %T; o = %d; n = %s\n", t, o, s->name); - prtree(a, "init1 value"); - } - - if(exflag && a->op == OINIT) - return doinit(s, t, o, nextinit()); - - switch(t->etype) { - default: - diag(Z, "unknown type in initialization: %T to: %s", t, s->name); - return Z; - - case TCHAR: - case TUCHAR: - case TINT: - case TUINT: - case TSHORT: - case TUSHORT: - case TLONG: - case TULONG: - case TVLONG: - case TUVLONG: - case TFLOAT: - case TDOUBLE: - case TIND: - single: - if(a->op == OARRAY || a->op == OELEM) - return Z; - - a = nextinit(); - if(a == Z) - return Z; - - if(t->nbits) - diag(Z, "cannot initialize bitfields"); - if(s->class == CAUTO) { - l = new(ONAME, Z, Z); - l->sym = s; - l->type = t; - l->etype = TVOID; - if(s->type) - l->etype = s->type->etype; - l->xoffset = s->offset + o; - l->class = s->class; - - l = new(OASI, l, a); - return l; - } - - complex(a); - if(a->type == T) - return Z; - - if(a->op == OCONST) { - if(vconst(a) && t->etype == TIND && a->type && a->type->etype != TIND){ - diag(a, "initialize pointer to an integer: %s", s->name); - return Z; - } - if(!sametype(a->type, t)) { - /* hoop jumping to save malloc */ - if(nodcast == Z) - nodcast = new(OCAST, Z, Z); - nod = *nodcast; - nod.left = a; - nod.type = t; - nod.lineno = a->lineno; - complex(&nod); - if(nod.type) - *a = nod; - } - if(a->op != OCONST) { - diag(a, "initializer is not a constant: %s", - s->name); - return Z; - } - if(vconst(a) == 0) - return Z; - goto gext; - } - if(t->etype == TIND) { - while(a->op == OCAST) { - warn(a, "CAST in initialization ignored"); - a = a->left; - } - if(!sametype(t, a->type)) { - diag(a, "initialization of incompatible pointers: %s\n%T and %T", - s->name, t, a->type); - } - if(a->op == OADDR) - a = a->left; - goto gext; - } - - while(a->op == OCAST) - a = a->left; - if(a->op == OADDR) { - warn(a, "initialize pointer to an integer: %s", s->name); - a = a->left; - goto gext; - } - diag(a, "initializer is not a constant: %s", s->name); - return Z; - - gext: - gextern(s, a, o, t->width); - - return Z; - - case TARRAY: - w = t->link->width; - if(a->op == OSTRING || a->op == OLSTRING) - if(typei[t->link->etype]) { - /* - * get rid of null if sizes match exactly - */ - a = nextinit(); - mw = t->width/w; - so = a->type->width/a->type->link->width; - if(mw && so > mw) { - if(so != mw+1) - diag(a, "string initialization larger than array"); - a->type->width -= a->type->link->width; - } - - /* - * arrange strings to be expanded - * inside OINIT braces. - */ - a = new(OUSED, a, Z); - return doinit(s, t, o, a); - } - - mw = -w; - l = Z; - for(e=0;;) { - /* - * peek ahead for element initializer - */ - a = peekinit(); - if(a == Z) - break; - if(a->op == OELEM && t->link->etype != TSTRUCT) - break; - if(a->op == OARRAY) { - if(e && exflag) - break; - a = nextinit(); - r = a->left; - complex(r); - if(r->op != OCONST) { - diag(r, "initializer subscript must be constant"); - return Z; - } - e = r->vconst; - if(t->width != 0) - if(e < 0 || e*w >= t->width) { - diag(a, "initialization index out of range: %d", e); - continue; - } - } - - so = e*w; - if(so > mw) - mw = so; - if(t->width != 0) - if(mw >= t->width) - break; - r = init1(s, t->link, o+so, 1); - l = newlist(l, r); - e++; - } - if(t->width == 0) - t->width = mw+w; - return l; - - case TUNION: - case TSTRUCT: - /* - * peek ahead to find type of rhs. - * if its a structure, then treat - * this element as a variable - * rather than an aggregate. - */ - if(isstruct(a, t)) - goto single; - - if(t->width <= 0) { - diag(Z, "incomplete structure: %s", s->name); - return Z; - } - l = Z; - - again: - for(t1 = t->link; t1 != T; t1 = t1->down) { - if(a->op == OARRAY && t1->etype != TARRAY) - break; - if(a->op == OELEM) { - if(t1->sym != a->sym) - continue; - nextinit(); - } - r = init1(s, t1, o+t1->offset, 1); - l = newlist(l, r); - a = peekinit(); - if(a == Z) - break; - if(a->op == OELEM) - goto again; - } - if(a && a->op == OELEM) - diag(a, "structure element not found %F", a); - return l; - } -} - -Node* -newlist(Node *l, Node *r) -{ - if(r == Z) - return l; - if(l == Z) - return r; - return new(OLIST, l, r); -} - -void -sualign(Type *t) -{ - Type *l; - int32 o, w, maxal; - - o = 0; - maxal = 0; - switch(t->etype) { - - case TSTRUCT: - t->offset = 0; - w = 0; - for(l = t->link; l != T; l = l->down) { - if(l->nbits) { - if(l->shift <= 0) { - l->shift = -l->shift; - w = xround(w, tfield->width); - o = w; - w += tfield->width; - } - l->offset = o; - } else { - if(l->width <= 0) - if(l->down != T) - if(l->sym) - diag(Z, "incomplete structure element: %s", - l->sym->name); - else - diag(Z, "incomplete structure element"); - w = align(w, l, Ael1, &maxal); - l->offset = w; - w = align(w, l, Ael2, &maxal); - } - } - w = align(w, t, Asu2, &maxal); - t->width = w; - t->align = maxal; - acidtype(t); - godeftype(t); - return; - - case TUNION: - t->offset = 0; - w = 0; - for(l = t->link; l != T; l = l->down) { - if(l->width <= 0) - if(l->sym) - diag(Z, "incomplete union element: %s", - l->sym->name); - else - diag(Z, "incomplete union element"); - l->offset = 0; - l->shift = 0; - o = align(align(0, l, Ael1, &maxal), l, Ael2, &maxal); - if(o > w) - w = o; - } - w = align(w, t, Asu2, &maxal); - t->width = w; - t->align = maxal; - acidtype(t); - godeftype(t); - return; - - default: - diag(Z, "unknown type in sualign: %T", t); - break; - } -} - -int32 -xround(int32 v, int w) -{ - int r; - - if(w <= 0 || w > 8) { - diag(Z, "rounding by %d", w); - w = 1; - } - r = v%w; - if(r) - v += w-r; - return v; -} - -Type* -ofnproto(Node *n) -{ - Type *tl, *tr, *t; - - if(n == Z) - return T; - switch(n->op) { - case OLIST: - tl = ofnproto(n->left); - tr = ofnproto(n->right); - if(tl == T) - return tr; - tl->down = tr; - return tl; - - case ONAME: - t = copytyp(n->sym->type); - t->down = T; - return t; - } - return T; -} - -#define ANSIPROTO 1 -#define OLDPROTO 2 - -void -argmark(Node *n, int pass) -{ - Type *t; - - autoffset = align(0, thisfn->link, Aarg0, nil); - stkoff = 0; - for(; n->left != Z; n = n->left) { - if(n->op != OFUNC || n->left->op != ONAME) - continue; - walkparam(n->right, pass); - if(pass != 0 && anyproto(n->right) == OLDPROTO) { - t = typ(TFUNC, n->left->sym->type->link); - t->down = typ(TOLD, T); - t->down->down = ofnproto(n->right); - tmerge(t, n->left->sym); - n->left->sym->type = t; - } - break; - } - autoffset = 0; - stkoff = 0; -} - -void -walkparam(Node *n, int pass) -{ - Sym *s; - Node *n1; - - if(n != Z && n->op == OPROTO && n->left == Z && n->type == types[TVOID]) - return; - -loop: - if(n == Z) - return; - switch(n->op) { - default: - diag(n, "argument not a name/prototype: %O", n->op); - break; - - case OLIST: - walkparam(n->left, pass); - n = n->right; - goto loop; - - case OPROTO: - for(n1 = n; n1 != Z; n1=n1->left) - if(n1->op == ONAME) { - if(pass == 0) { - s = n1->sym; - push1(s); - s->offset = -1; - break; - } - dodecl(pdecl, CPARAM, n->type, n->left); - break; - } - if(n1) - break; - if(pass == 0) { - /* - * extension: - * allow no name in argument declaration - diag(Z, "no name in argument declaration"); - */ - break; - } - dodecl(NODECL, CPARAM, n->type, n->left); - pdecl(CPARAM, lastdcl, S); - break; - - case ODOTDOT: - break; - - case ONAME: - s = n->sym; - if(pass == 0) { - push1(s); - s->offset = -1; - break; - } - if(s->offset != -1) { - if(autoffset == 0) { - firstarg = s; - firstargtype = s->type; - } - autoffset = align(autoffset, s->type, Aarg1, nil); - s->offset = autoffset; - autoffset = align(autoffset, s->type, Aarg2, nil); - } else - dodecl(pdecl, CXXX, types[TINT], n); - break; - } -} - -void -markdcl(void) -{ - Decl *d; - - blockno++; - d = push(); - d->val = DMARK; - d->offset = autoffset; - d->block = autobn; - autobn = blockno; -} - -Node* -revertdcl(void) -{ - Decl *d; - Sym *s; - Node *n, *n1; - - n = Z; - for(;;) { - d = dclstack; - if(d == D) { - diag(Z, "pop off dcl stack"); - break; - } - dclstack = d->link; - s = d->sym; - switch(d->val) { - case DMARK: - autoffset = d->offset; - autobn = d->block; - return n; - - case DAUTO: - if(debug['d']) - print("revert1 \"%s\"\n", s->name); - if(s->aused == 0) { - nearln = s->varlineno; - if(s->class == CAUTO) - warn(Z, "auto declared and not used: %s", s->name); - if(s->class == CPARAM) - warn(Z, "param declared and not used: %s", s->name); - } - if(s->type && (s->type->garb & GVOLATILE)) { - n1 = new(ONAME, Z, Z); - n1->sym = s; - n1->type = s->type; - n1->etype = TVOID; - if(n1->type != T) - n1->etype = n1->type->etype; - n1->xoffset = s->offset; - n1->class = s->class; - - n1 = new(OADDR, n1, Z); - n1 = new(OUSED, n1, Z); - if(n == Z) - n = n1; - else - n = new(OLIST, n1, n); - } - s->type = d->type; - s->class = d->class; - s->offset = d->offset; - s->block = d->block; - s->varlineno = d->varlineno; - s->aused = d->aused; - break; - - case DSUE: - if(debug['d']) - print("revert2 \"%s\"\n", s->name); - s->suetag = d->type; - s->sueblock = d->block; - break; - - case DLABEL: - if(debug['d']) - print("revert3 \"%s\"\n", s->name); - if(s->label && s->label->addable == 0) - warn(s->label, "label declared and not used \"%s\"", s->name); - s->label = Z; - break; - } - } - return n; -} - -Type* -fnproto(Node *n) -{ - int r; - - r = anyproto(n->right); - if(r == 0 || (r & OLDPROTO)) { - if(r & ANSIPROTO) - diag(n, "mixed ansi/old function declaration: %F", n->left); - return T; - } - return fnproto1(n->right); -} - -int -anyproto(Node *n) -{ - int r; - - r = 0; - -loop: - if(n == Z) - return r; - switch(n->op) { - case OLIST: - r |= anyproto(n->left); - n = n->right; - goto loop; - - case ODOTDOT: - case OPROTO: - return r | ANSIPROTO; - } - return r | OLDPROTO; -} - -Type* -fnproto1(Node *n) -{ - Type *t; - - if(n == Z) - return T; - switch(n->op) { - case OLIST: - t = fnproto1(n->left); - if(t != T) - t->down = fnproto1(n->right); - return t; - - case OPROTO: - lastdcl = T; - dodecl(NODECL, CXXX, n->type, n->left); - t = typ(TXXX, T); - if(lastdcl != T) - *t = *paramconv(lastdcl, 1); - return t; - - case ONAME: - diag(n, "incomplete argument prototype"); - return typ(TINT, T); - - case ODOTDOT: - return typ(TDOT, T); - } - diag(n, "unknown op in fnproto"); - return T; -} - -void -dbgdecl(Sym *s) -{ - print("decl \"%s\": C=%s [B=%d:O=%d] T=%T\n", - s->name, cnames[s->class], s->block, s->offset, s->type); -} - -Decl* -push(void) -{ - Decl *d; - - d = alloc(sizeof(*d)); - d->link = dclstack; - dclstack = d; - return d; -} - -Decl* -push1(Sym *s) -{ - Decl *d; - - d = push(); - d->sym = s; - d->val = DAUTO; - d->type = s->type; - d->class = s->class; - d->offset = s->offset; - d->block = s->block; - d->varlineno = s->varlineno; - d->aused = s->aused; - return d; -} - -int -sametype(Type *t1, Type *t2) -{ - - if(t1 == t2) - return 1; - return rsametype(t1, t2, 5, 1); -} - -int -rsametype(Type *t1, Type *t2, int n, int f) -{ - int et; - - n--; - for(;;) { - if(t1 == t2) - return 1; - if(t1 == T || t2 == T) - return 0; - if(n <= 0) - return 1; - et = t1->etype; - if(et != t2->etype) - return 0; - if(et == TFUNC) { - if(!rsametype(t1->link, t2->link, n, 0)) - return 0; - t1 = t1->down; - t2 = t2->down; - while(t1 != T && t2 != T) { - if(t1->etype == TOLD) { - t1 = t1->down; - continue; - } - if(t2->etype == TOLD) { - t2 = t2->down; - continue; - } - while(t1 != T || t2 != T) { - if(!rsametype(t1, t2, n, 0)) - return 0; - t1 = t1->down; - t2 = t2->down; - } - break; - } - return 1; - } - if(et == TARRAY) - if(t1->width != t2->width && t1->width != 0 && t2->width != 0) - return 0; - if(typesu[et]) { - if(t1->link == T) - snap(t1); - if(t2->link == T) - snap(t2); - t1 = t1->link; - t2 = t2->link; - for(;;) { - if(t1 == t2) - return 1; - if(!rsametype(t1, t2, n, 0)) - return 0; - t1 = t1->down; - t2 = t2->down; - } - } - t1 = t1->link; - t2 = t2->link; - if((f || !debug['V']) && et == TIND) { - if(t1 != T && t1->etype == TVOID) - return 1; - if(t2 != T && t2->etype == TVOID) - return 1; - } - } -} - -typedef struct Typetab Typetab; - -struct Typetab{ - int n; - Type **a; -}; - -static int -sigind(Type *t, Typetab *tt) -{ - int n; - Type **a, **na, **p, **e; - - n = tt->n; - a = tt->a; - e = a+n; - /* linear search seems ok */ - for(p = a ; p < e; p++) - if(sametype(*p, t)) - return p-a; - if((n&15) == 0){ - na = malloc((n+16)*sizeof(Type*)); - memmove(na, a, n*sizeof(Type*)); - free(a); - a = tt->a = na; - } - a[tt->n++] = t; - return -1; -} - -static uint32 -signat(Type *t, Typetab *tt) -{ - int i; - Type *t1; - int32 s; - - s = 0; - for(; t; t=t->link) { - s = s*thash1 + thash[t->etype]; - if(t->garb&GINCOMPLETE) - return s; - switch(t->etype) { - default: - return s; - case TARRAY: - s = s*thash2 + 0; /* was t->width */ - break; - case TFUNC: - for(t1=t->down; t1; t1=t1->down) - s = s*thash3 + signat(t1, tt); - break; - case TSTRUCT: - case TUNION: - if((i = sigind(t, tt)) >= 0){ - s = s*thash2 + i; - return s; - } - for(t1=t->link; t1; t1=t1->down) - s = s*thash3 + signat(t1, tt); - return s; - case TIND: - break; - } - } - return s; -} - -uint32 -signature(Type *t) -{ - uint32 s; - Typetab tt; - - tt.n = 0; - tt.a = nil; - s = signat(t, &tt); - free(tt.a); - return s; -} - -uint32 -sign(Sym *s) -{ - uint32 v; - Type *t; - - if(s->sig == SIGINTERN) - return SIGNINTERN; - if((t = s->type) == T) - return 0; - v = signature(t); - if(v == 0) - v = SIGNINTERN; - return v; -} - -void -snap(Type *t) -{ - if(typesu[t->etype]) - if(t->link == T && t->tag && t->tag->suetag) { - t->link = t->tag->suetag->link; - t->width = t->tag->suetag->width; - } -} - -Type* -dotag(Sym *s, int et, int bn) -{ - Decl *d; - - if(bn != 0 && bn != s->sueblock) { - d = push(); - d->sym = s; - d->val = DSUE; - d->type = s->suetag; - d->block = s->sueblock; - s->suetag = T; - } - if(s->suetag == T) { - s->suetag = typ(et, T); - s->sueblock = autobn; - } - if(s->suetag->etype != et) - diag(Z, "tag used for more than one type: %s", - s->name); - if(s->suetag->tag == S) - s->suetag->tag = s; - return s->suetag; -} - -Node* -dcllabel(Sym *s, int f) -{ - Decl *d, d1; - Node *n; - - n = s->label; - if(n != Z) { - if(f) { - if(n->complex) - diag(Z, "label reused: %s", s->name); - n->complex = 1; // declared - } else - n->addable = 1; // used - return n; - } - - d = push(); - d->sym = s; - d->val = DLABEL; - dclstack = d->link; - - d1 = *firstdcl; - *firstdcl = *d; - *d = d1; - - firstdcl->link = d; - firstdcl = d; - - n = new(OXXX, Z, Z); - n->sym = s; - n->complex = f; - n->addable = !f; - s->label = n; - - if(debug['d']) - dbgdecl(s); - return n; -} - -Type* -paramconv(Type *t, int f) -{ - - switch(t->etype) { - case TUNION: - case TSTRUCT: - if(t->width <= 0) - diag(Z, "incomplete structure: %s", t->tag->name); - break; - - case TARRAY: - t = typ(TIND, t->link); - t->width = types[TIND]->width; - break; - - case TFUNC: - t = typ(TIND, t); - t->width = types[TIND]->width; - break; - - case TFLOAT: - if(!f) - t = types[TDOUBLE]; - break; - - case TCHAR: - case TSHORT: - if(!f) - t = types[TINT]; - break; - - case TUCHAR: - case TUSHORT: - if(!f) - t = types[TUINT]; - break; - } - return t; -} - -void -adecl(int c, Type *t, Sym *s) -{ - - if(c == CSTATIC) - c = CLOCAL; - if(t->etype == TFUNC) { - if(c == CXXX) - c = CEXTERN; - if(c == CLOCAL) - c = CSTATIC; - if(c == CAUTO || c == CEXREG) - diag(Z, "function cannot be %s %s", cnames[c], s->name); - } - if(c == CXXX) - c = CAUTO; - if(s) { - if(s->class == CSTATIC) - if(c == CEXTERN || c == CGLOBL) { - warn(Z, "just say static: %s", s->name); - c = CSTATIC; - } - if(s->class == CAUTO || s->class == CPARAM || s->class == CLOCAL) - if(s->block == autobn) - diag(Z, "auto redeclaration of: %s", s->name); - if(c != CPARAM) - push1(s); - s->block = autobn; - s->offset = 0; - s->type = t; - s->class = c; - s->aused = 0; - } - switch(c) { - case CAUTO: - autoffset = align(autoffset, t, Aaut3, nil); - stkoff = maxround(stkoff, autoffset); - s->offset = -autoffset; - break; - - case CPARAM: - if(autoffset == 0) { - firstarg = s; - firstargtype = t; - } - autoffset = align(autoffset, t, Aarg1, nil); - if(s) - s->offset = autoffset; - autoffset = align(autoffset, t, Aarg2, nil); - break; - } -} - -void -pdecl(int c, Type *t, Sym *s) -{ - if(s && s->offset != -1) { - diag(Z, "not a parameter: %s", s->name); - return; - } - t = paramconv(t, c==CPARAM); - if(c == CXXX) - c = CPARAM; - if(c != CPARAM) { - diag(Z, "parameter cannot have class: %s", s->name); - c = CPARAM; - } - adecl(c, t, s); -} - -void -xdecl(int c, Type *t, Sym *s) -{ - int32 o; - - o = 0; - switch(c) { - case CEXREG: - o = exreg(t); - if(o == 0) - c = CEXTERN; - if(s->class == CGLOBL) - c = CGLOBL; - break; - - case CEXTERN: - if(s->class == CGLOBL) - c = CGLOBL; - break; - - case CXXX: - c = CGLOBL; - if(s->class == CEXTERN) - s->class = CGLOBL; - break; - - case CAUTO: - diag(Z, "overspecified class: %s %s %s", s->name, cnames[c], cnames[s->class]); - c = CEXTERN; - break; - - case CTYPESTR: - if(!typesuv[t->etype]) { - diag(Z, "typestr must be struct/union: %s", s->name); - break; - } - dclfunct(t, s); - break; - } - - if(s->class == CSTATIC) - if(c == CEXTERN || c == CGLOBL) { - warn(Z, "overspecified class: %s %s %s", s->name, cnames[c], cnames[s->class]); - c = CSTATIC; - } - if(s->type != T) - if(s->class != c || !sametype(t, s->type) || t->etype == TENUM) { - diag(Z, "external redeclaration of: %s", s->name); - Bprint(&diagbuf, " %s %T %L\n", cnames[c], t, nearln); - Bprint(&diagbuf, " %s %T %L\n", cnames[s->class], s->type, s->varlineno); - } - tmerge(t, s); - s->type = t; - s->class = c; - s->block = 0; - s->offset = o; -} - -void -tmerge(Type *t1, Sym *s) -{ - Type *ta, *tb, *t2; - - t2 = s->type; - for(;;) { - if(t1 == T || t2 == T || t1 == t2) - break; - if(t1->etype != t2->etype) - break; - switch(t1->etype) { - case TFUNC: - ta = t1->down; - tb = t2->down; - if(ta == T) { - t1->down = tb; - break; - } - if(tb == T) - break; - while(ta != T && tb != T) { - if(ta == tb) - break; - /* ignore old-style flag */ - if(ta->etype == TOLD) { - ta = ta->down; - continue; - } - if(tb->etype == TOLD) { - tb = tb->down; - continue; - } - /* checking terminated by ... */ - if(ta->etype == TDOT && tb->etype == TDOT) { - ta = T; - tb = T; - break; - } - if(!sametype(ta, tb)) - break; - ta = ta->down; - tb = tb->down; - } - if(ta != tb) - diag(Z, "function inconsistently declared: %s", s->name); - - /* take new-style over old-style */ - ta = t1->down; - tb = t2->down; - if(ta != T && ta->etype == TOLD) - if(tb != T && tb->etype != TOLD) - t1->down = tb; - break; - - case TARRAY: - /* should we check array size change? */ - if(t2->width > t1->width) - t1->width = t2->width; - break; - - case TUNION: - case TSTRUCT: - return; - } - t1 = t1->link; - t2 = t2->link; - } -} - -void -edecl(int c, Type *t, Sym *s) -{ - Type *t1; - - if(s == S) { - if(!typesu[t->etype]) - diag(Z, "unnamed structure element must be struct/union"); - if(c != CXXX) - diag(Z, "unnamed structure element cannot have class"); - } else - if(c != CXXX) - diag(Z, "structure element cannot have class: %s", s->name); - t1 = t; - t = copytyp(t1); - t->sym = s; - t->down = T; - if(lastfield) { - t->shift = lastbit - lastfield; - t->nbits = lastfield; - if(firstbit) - t->shift = -t->shift; - if(typeu[t->etype]) - t->etype = tufield->etype; - else - t->etype = tfield->etype; - } - if(strf == T) - strf = t; - else - strl->down = t; - strl = t; -} - -/* - * this routine is very suspect. - * ansi requires the enum type to - * be represented as an 'int' - * this means that 0x81234567 - * would be illegal. this routine - * makes signed and unsigned go - * to unsigned. - */ -Type* -maxtype(Type *t1, Type *t2) -{ - - if(t1 == T) - return t2; - if(t2 == T) - return t1; - if(t1->etype > t2->etype) - return t1; - return t2; -} - -void -doenum(Sym *s, Node *n) -{ - - if(n) { - complex(n); - if(n->op != OCONST) { - diag(n, "enum not a constant: %s", s->name); - return; - } - en.cenum = n->type; - en.tenum = maxtype(en.cenum, en.tenum); - - if(!typefd[en.cenum->etype]) - en.lastenum = n->vconst; - else - en.floatenum = n->fconst; - } - if(dclstack) - push1(s); - xdecl(CXXX, types[TENUM], s); - - if(en.cenum == T) { - en.tenum = types[TINT]; - en.cenum = types[TINT]; - en.lastenum = 0; - } - s->tenum = en.cenum; - - if(!typefd[s->tenum->etype]) { - s->vconst = convvtox(en.lastenum, s->tenum->etype); - en.lastenum++; - } else { - s->fconst = en.floatenum; - en.floatenum++; - } - - if(debug['d']) - dbgdecl(s); - acidvar(s); - godefvar(s); -} - -void -symadjust(Sym *s, Node *n, int32 del) -{ - - switch(n->op) { - default: - if(n->left) - symadjust(s, n->left, del); - if(n->right) - symadjust(s, n->right, del); - return; - - case ONAME: - if(n->sym == s) - n->xoffset -= del; - return; - - case OCONST: - case OSTRING: - case OLSTRING: - case OINDREG: - case OREGISTER: - return; - } -} - -Node* -contig(Sym *s, Node *n, int32 v) -{ - Node *p, *r, *q, *m; - int32 w; - Type *zt; - - if(debug['i']) { - print("contig v = %d; s = %s\n", v, s->name); - prtree(n, "doinit value"); - } - - if(n == Z) - goto no; - w = s->type->width; - - /* - * nightmare: an automatic array whose size - * increases when it is initialized - */ - if(v != w) { - if(v != 0) - diag(n, "automatic adjustable array: %s", s->name); - v = s->offset; - autoffset = align(autoffset, s->type, Aaut3, nil); - s->offset = -autoffset; - stkoff = maxround(stkoff, autoffset); - symadjust(s, n, v - s->offset); - } - if(w <= ewidth[TIND]) - goto no; - if(n->op == OAS) - diag(Z, "oops in contig"); -/*ZZZ this appears incorrect -need to check if the list completely covers the data. -if not, bail - */ - if(n->op == OLIST) - goto no; - if(n->op == OASI) - if(n->left->type) - if(n->left->type->width == w) - goto no; - while(w & (ewidth[TIND]-1)) - w++; -/* - * insert the following code, where long becomes vlong if pointers are fat - * - *(long**)&X = (long*)((char*)X + sizeof(X)); - do { - *(long**)&X -= 1; - **(long**)&X = 0; - } while(*(long**)&X); - */ - - for(q=n; q->op != ONAME; q=q->left) - ; - - zt = ewidth[TIND] > ewidth[TLONG]? types[TVLONG]: types[TLONG]; - - p = new(ONAME, Z, Z); - *p = *q; - p->type = typ(TIND, zt); - p->xoffset = s->offset; - - r = new(ONAME, Z, Z); - *r = *p; - r = new(OPOSTDEC, r, Z); - - q = new(ONAME, Z, Z); - *q = *p; - q = new(OIND, q, Z); - - m = new(OCONST, Z, Z); - m->vconst = 0; - m->type = zt; - - q = new(OAS, q, m); - - r = new(OLIST, r, q); - - q = new(ONAME, Z, Z); - *q = *p; - r = new(ODWHILE, q, r); - - q = new(ONAME, Z, Z); - *q = *p; - q->type = q->type->link; - q->xoffset += w; - q = new(OADDR, q, 0); - - q = new(OASI, p, q); - r = new(OLIST, q, r); - - n = new(OLIST, r, n); - -no: - return n; -} diff --git a/src/cmd/cc/doc.go b/src/cmd/cc/doc.go deleted file mode 100644 index 51aa8b192..000000000 --- a/src/cmd/cc/doc.go +++ /dev/null @@ -1,11 +0,0 @@ -// Copyright 2009 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -/* - -This directory contains the portable section of the Plan 9 C compilers. -See ../6c, ../8c, and ../5c for more information. - -*/ -package documentation 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') - ; -} diff --git a/src/cmd/cc/funct.c b/src/cmd/cc/funct.c deleted file mode 100644 index 99477b2b2..000000000 --- a/src/cmd/cc/funct.c +++ /dev/null @@ -1,431 +0,0 @@ -// Inferno utils/cc/funct.c -// http://code.google.com/p/inferno-os/source/browse/utils/cc/funct.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" - -typedef struct Ftab Ftab; -struct Ftab -{ - char op; - char* name; - char typ; -}; -typedef struct Gtab Gtab; -struct Gtab -{ - char etype; - char* name; -}; - -Ftab ftabinit[OEND]; -Gtab gtabinit[NTYPE]; - -int -isfunct(Node *n) -{ - Type *t, *t1; - Funct *f; - Node *l; - Sym *s; - int o; - - o = n->op; - if(n->left == Z) - goto no; - t = n->left->type; - if(t == T) - goto no; - f = t->funct; - - switch(o) { - case OAS: // put cast on rhs - case OASI: - case OASADD: - case OASAND: - case OASASHL: - case OASASHR: - case OASDIV: - case OASLDIV: - case OASLMOD: - case OASLMUL: - case OASLSHR: - case OASMOD: - case OASMUL: - case OASOR: - case OASSUB: - case OASXOR: - if(n->right == Z) - goto no; - t1 = n->right->type; - if(t1 == T) - goto no; - if(t1->funct == f) - break; - - l = new(OXXX, Z, Z); - *l = *n->right; - - n->right->left = l; - n->right->right = Z; - n->right->type = t; - n->right->op = OCAST; - - if(!isfunct(n->right)) - prtree(n, "isfunc !"); - break; - - case OCAST: // t f(T) or T f(t) - t1 = n->type; - if(t1 == T) - goto no; - if(f != nil) { - s = f->castfr[t1->etype]; - if(s == S) - goto no; - n->right = n->left; - goto build; - } - f = t1->funct; - if(f != nil) { - s = f->castto[t->etype]; - if(s == S) - goto no; - n->right = n->left; - goto build; - } - goto no; - } - - if(f == nil) - goto no; - s = f->sym[o]; - if(s == S) - goto no; - - /* - * the answer is yes, - * now we rewrite the node - * and give diagnostics - */ - switch(o) { - default: - diag(n, "isfunct op missing %O\n", o); - goto bad; - - case OADD: // T f(T, T) - case OAND: - case OASHL: - case OASHR: - case ODIV: - case OLDIV: - case OLMOD: - case OLMUL: - case OLSHR: - case OMOD: - case OMUL: - case OOR: - case OSUB: - case OXOR: - - case OEQ: // int f(T, T) - case OGE: - case OGT: - case OHI: - case OHS: - case OLE: - case OLO: - case OLS: - case OLT: - case ONE: - if(n->right == Z) - goto bad; - t1 = n->right->type; - if(t1 == T) - goto bad; - if(t1->funct != f) - goto bad; - n->right = new(OLIST, n->left, n->right); - break; - - case OAS: // structure copies done by the compiler - case OASI: - goto no; - - case OASADD: // T f(T*, T) - case OASAND: - case OASASHL: - case OASASHR: - case OASDIV: - case OASLDIV: - case OASLMOD: - case OASLMUL: - case OASLSHR: - case OASMOD: - case OASMUL: - case OASOR: - case OASSUB: - case OASXOR: - if(n->right == Z) - goto bad; - t1 = n->right->type; - if(t1 == T) - goto bad; - if(t1->funct != f) - goto bad; - n->right = new(OLIST, new(OADDR, n->left, Z), n->right); - break; - - case OPOS: // T f(T) - case ONEG: - case ONOT: - case OCOM: - n->right = n->left; - break; - - - } - -build: - l = new(ONAME, Z, Z); - l->sym = s; - l->type = s->type; - l->etype = s->type->etype; - l->xoffset = s->offset; - l->class = s->class; - tcomo(l, 0); - - n->op = OFUNC; - n->left = l; - n->type = l->type->link; - if(tcompat(n, T, l->type, tfunct)) - goto bad; - if(tcoma(n->left, n->right, l->type->down, 1)) - goto bad; - return 1; - -no: - return 0; - -bad: - diag(n, "cant rewrite typestr for op %O\n", o); - prtree(n, "isfunct"); - n->type = T; - return 1; -} - -void -dclfunct(Type *t, Sym *s) -{ - Funct *f; - Node *n; - Type *f1, *f2, *f3, *f4; - int o, i, c; - char str[100]; - - if(t->funct) - return; - - // recognize generated tag of dorm _%d_ - if(t->tag == S) - goto bad; - for(i=0; c = t->tag->name[i]; i++) { - if(c == '_') { - if(i == 0 || t->tag->name[i+1] == 0) - continue; - break; - } - if(c < '0' || c > '9') - break; - } - if(c == 0) - goto bad; - - f = alloc(sizeof(*f)); - for(o=0; o<sizeof(f->sym); o++) - f->sym[o] = S; - - t->funct = f; - - f1 = typ(TFUNC, t); - f1->down = copytyp(t); - f1->down->down = t; - - f2 = typ(TFUNC, types[TINT]); - f2->down = copytyp(t); - f2->down->down = t; - - f3 = typ(TFUNC, t); - f3->down = typ(TIND, t); - f3->down->down = t; - - f4 = typ(TFUNC, t); - f4->down = t; - - for(i=0;; i++) { - o = ftabinit[i].op; - if(o == OXXX) - break; - sprint(str, "%s_%s_", t->tag->name, ftabinit[i].name); - n = new(ONAME, Z, Z); - n->sym = slookup(str); - f->sym[o] = n->sym; - switch(ftabinit[i].typ) { - default: - diag(Z, "dclfunct op missing %d\n", ftabinit[i].typ); - break; - - case 1: // T f(T,T) + - dodecl(xdecl, CEXTERN, f1, n); - break; - - case 2: // int f(T,T) == - dodecl(xdecl, CEXTERN, f2, n); - break; - - case 3: // void f(T*,T) += - dodecl(xdecl, CEXTERN, f3, n); - break; - - case 4: // T f(T) ~ - dodecl(xdecl, CEXTERN, f4, n); - break; - } - } - for(i=0;; i++) { - o = gtabinit[i].etype; - if(o == TXXX) - break; - - /* - * OCAST types T1 _T2_T1_(T2) - */ - sprint(str, "_%s%s_", gtabinit[i].name, t->tag->name); - n = new(ONAME, Z, Z); - n->sym = slookup(str); - f->castto[o] = n->sym; - - f1 = typ(TFUNC, t); - f1->down = types[o]; - dodecl(xdecl, CEXTERN, f1, n); - - sprint(str, "%s_%s_", t->tag->name, gtabinit[i].name); - n = new(ONAME, Z, Z); - n->sym = slookup(str); - f->castfr[o] = n->sym; - - f1 = typ(TFUNC, types[o]); - f1->down = t; - dodecl(xdecl, CEXTERN, f1, n); - } - return; -bad: - diag(Z, "dclfunct bad %T %s\n", t, s->name); -} - -Gtab gtabinit[NTYPE] = -{ - TCHAR, "c", - TUCHAR, "uc", - TSHORT, "h", - TUSHORT, "uh", - TINT, "i", - TUINT, "ui", - TLONG, "l", - TULONG, "ul", - TVLONG, "v", - TUVLONG, "uv", - TFLOAT, "f", - TDOUBLE, "d", - TXXX -}; - -Ftab ftabinit[OEND] = -{ - OADD, "add", 1, - OAND, "and", 1, - OASHL, "ashl", 1, - OASHR, "ashr", 1, - ODIV, "div", 1, - OLDIV, "ldiv", 1, - OLMOD, "lmod", 1, - OLMUL, "lmul", 1, - OLSHR, "lshr", 1, - OMOD, "mod", 1, - OMUL, "mul", 1, - OOR, "or", 1, - OSUB, "sub", 1, - OXOR, "xor", 1, - - OEQ, "eq", 2, - OGE, "ge", 2, - OGT, "gt", 2, - OHI, "hi", 2, - OHS, "hs", 2, - OLE, "le", 2, - OLO, "lo", 2, - OLS, "ls", 2, - OLT, "lt", 2, - ONE, "ne", 2, - - OASADD, "asadd", 3, - OASAND, "asand", 3, - OASASHL, "asashl", 3, - OASASHR, "asashr", 3, - OASDIV, "asdiv", 3, - OASLDIV, "asldiv", 3, - OASLMOD, "aslmod", 3, - OASLMUL, "aslmul", 3, - OASLSHR, "aslshr", 3, - OASMOD, "asmod", 3, - OASMUL, "asmul", 3, - OASOR, "asor", 3, - OASSUB, "assub", 3, - OASXOR, "asxor", 3, - - OPOS, "pos", 4, - ONEG, "neg", 4, - OCOM, "com", 4, - ONOT, "not", 4, - -// OPOSTDEC, -// OPOSTINC, -// OPREDEC, -// OPREINC, - - OXXX, -}; - -// Node* nodtestv; - -// Node* nodvpp; -// Node* nodppv; -// Node* nodvmm; -// Node* nodmmv; diff --git a/src/cmd/cc/godefs.c b/src/cmd/cc/godefs.c deleted file mode 100644 index 3ba979c8a..000000000 --- a/src/cmd/cc/godefs.c +++ /dev/null @@ -1,388 +0,0 @@ -// cmd/cc/godefs.cc -// -// derived from pickle.cc which itself was derived from acid.cc. -// -// 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-2011 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 int upper; - -static char *kwd[] = -{ - "_bool", - "_break", - "_byte", - "_case", - "_chan", - "_complex128", - "_complex64", - "_const", - "_continue", - "_default", - "_defer", - "_else", - "_fallthrough", - "_false", - "_float32", - "_float64", - "_for", - "_func", - "_go", - "_goto", - "_if", - "_import", - "_int", - "_int16", - "_int32", - "_int64", - "_int8", - "_interface", - "_intptr", - "_map", - "_package", - "_panic", - "_range", - "_return", - "_select", - "_string", - "_struct", - "_switch", - "_true", - "_type", - "_uint", - "_uint16", - "_uint32", - "_uint64", - "_uint8", - "_uintptr", - "_var", -}; - -static char* -pmap(char *s) -{ - int i, bot, top, mid; - - bot = -1; - top = nelem(kwd); - while(top - bot > 1){ - mid = (bot + top) / 2; - i = strcmp(kwd[mid]+1, s); - if(i == 0) - return kwd[mid]; - if(i < 0) - bot = mid; - else - top = mid; - } - - return s; -} - - -int -Uconv(Fmt *fp) -{ - char str[STRINGSZ+1]; - char *s, *n; - int i; - - str[0] = 0; - s = va_arg(fp->args, char*); - - // strip package name - n = strrchr(s, '.'); - if(n != nil) - s = n + 1; - - if(s && *s) { - if(upper) - str[0] = toupper(*s); - else - str[0] = tolower(*s); - for(i = 1; i < STRINGSZ && s[i] != 0; i++) - str[i] = tolower(s[i]); - str[i] = 0; - } - - return fmtstrcpy(fp, pmap(str)); -} - - -static Sym* -findsue(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; -} - -static void -printtypename(Type *t) -{ - Sym *s; - Type *t1; - int w; - char *n; - - for( ; t != nil; t = t->link) { - switch(t->etype) { - case TIND: - // Special handling of *void. - if(t->link != nil && t->link->etype==TVOID) { - Bprint(&outbuf, "unsafe.Pointer"); - return; - } - // *func == func - if(t->link != nil && t->link->etype==TFUNC) - continue; - Bprint(&outbuf, "*"); - continue; - case TARRAY: - w = t->width; - if(t->link && t->link->width) - w /= t->link->width; - Bprint(&outbuf, "[%d]", w); - continue; - } - break; - } - - if(t == nil) { - Bprint(&outbuf, "bad // should not happen"); - return; - } - - switch(t->etype) { - case TINT: - Bprint(&outbuf, "int"); - break; - case TUINT: - Bprint(&outbuf, "uint"); - break; - case TCHAR: - Bprint(&outbuf, "int8"); - break; - case TUCHAR: - Bprint(&outbuf, "uint8"); - break; - case TSHORT: - Bprint(&outbuf, "int16"); - break; - case TUSHORT: - Bprint(&outbuf, "uint16"); - break; - case TLONG: - Bprint(&outbuf, "int32"); - break; - case TULONG: - Bprint(&outbuf, "uint32"); - break; - case TVLONG: - Bprint(&outbuf, "int64"); - break; - case TUVLONG: - Bprint(&outbuf, "uint64"); - break; - case TFLOAT: - Bprint(&outbuf, "float32"); - break; - case TDOUBLE: - Bprint(&outbuf, "float64"); - break; - case TUNION: - case TSTRUCT: - s = findsue(t->link); - n = "bad"; - if(s != S) - n = s->name; - else if(t->tag) - n = t->tag->name; - if(strcmp(n, "String") == 0){ - Bprint(&outbuf, "string"); - } else if(strcmp(n, "Slice") == 0){ - Bprint(&outbuf, "[]byte"); - } else - Bprint(&outbuf, "%U", n); - break; - case TFUNC: - Bprint(&outbuf, "func("); - for(t1 = t->down; t1 != T; t1 = t1->down) { - if(t1->etype == TVOID) - break; - if(t1 != t->down) - Bprint(&outbuf, ", "); - printtypename(t1); - } - Bprint(&outbuf, ")"); - if(t->link && t->link->etype != TVOID) { - Bprint(&outbuf, " "); - printtypename(t->link); - } - break; - case TDOT: - Bprint(&outbuf, "...interface{}"); - break; - default: - Bprint(&outbuf, " weird<%T>", t); - } -} - -static int -dontrun(void) -{ - Io *i; - int n; - - if(!debug['q'] && !debug['Q']) - return 1; - if(debug['q'] + debug['Q'] > 1) { - n = 0; - for(i=iostack; i; i=i->link) - n++; - if(n > 1) - return 1; - } - - upper = debug['Q']; - return 0; -} - -void -godeftype(Type *t) -{ - Sym *s; - Type *l; - int gotone; - - if(dontrun()) - return; - - switch(t->etype) { - case TUNION: - case TSTRUCT: - s = findsue(t->link); - if(s == S) { - Bprint(&outbuf, "/* can't find %T */\n\n", t); - return; - } - - gotone = 0; // for unions, take first member of size equal to union - Bprint(&outbuf, "type %U struct {\n", s->name); - for(l = t->link; l != T; l = l->down) { - Bprint(&outbuf, "\t"); - if(t->etype == TUNION) { - if(!gotone && l->width == t->width) - gotone = 1; - else - Bprint(&outbuf, "// (union)\t"); - } - if(l->sym != nil) // not anonymous field - Bprint(&outbuf, "%U\t", l->sym->name); - printtypename(l); - Bprint(&outbuf, "\n"); - } - Bprint(&outbuf, "}\n\n"); - break; - - default: - Bprint(&outbuf, "/* %T */\n\n", t); - break; - } -} - -void -godefvar(Sym *s) -{ - Type *t, *t1; - char n; - - if(dontrun()) - return; - - t = s->type; - if(t == nil) - return; - - switch(t->etype) { - case TENUM: - if(!typefd[t->etype]) - Bprint(&outbuf, "const %U = %lld\n", s->name, s->vconst); - else - Bprint(&outbuf, "const %U = %f\n;", s->name, s->fconst); - break; - - case TFUNC: - Bprint(&outbuf, "func %U(", s->name); - n = 'a'; - for(t1 = t->down; t1 != T; t1 = t1->down) { - if(t1->etype == TVOID) - break; - if(t1 != t->down) - Bprint(&outbuf, ", "); - Bprint(&outbuf, "%c ", n++); - printtypename(t1); - } - Bprint(&outbuf, ")"); - if(t->link && t->link->etype != TVOID) { - Bprint(&outbuf, " "); - printtypename(t->link); - } - Bprint(&outbuf, "\n"); - break; - - default: - switch(s->class) { - case CTYPEDEF: - if(!typesu[t->etype]) { - Bprint(&outbuf, "// type %U\t", s->name); - printtypename(t); - Bprint(&outbuf, "\n"); - } - break; - case CSTATIC: - case CEXTERN: - case CGLOBL: - if(strchr(s->name, '$') != nil) // TODO(lvd) - break; - Bprint(&outbuf, "var %U\t", s->name); - printtypename(t); - Bprint(&outbuf, "\n"); - break; - } - break; - } -} diff --git a/src/cmd/cc/lex.c b/src/cmd/cc/lex.c deleted file mode 100644 index 15f2d374d..000000000 --- a/src/cmd/cc/lex.c +++ /dev/null @@ -1,1562 +0,0 @@ -// Inferno utils/cc/lex.c -// http://code.google.com/p/inferno-os/source/browse/utils/cc/lex.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" - -#ifndef CPP -#define CPP "cpp" -#endif - -int -systemtype(int sys) -{ -#ifdef _WIN32 - return sys&Windows; -#else - return sys&Plan9; -#endif -} - -int -pathchar(void) -{ - return '/'; -} - -/* - * known debug flags - * -a acid declaration output - * -A !B - * -B non ANSI - * -d print declarations - * -D name define - * -F format specification check - * -G print pgen stuff - * -g print cgen trees - * -i print initialization - * -I path include - * -l generate little-endian code - * -L print every NAME symbol - * -M constant multiplication - * -m print add/sub/mul trees - * -n print acid or godefs to file (%.c=%.acid) (with -a or -aa) - * -o file output file - * -p use standard cpp ANSI preprocessor (not on windows) - * -p something with peepholes - * -q print equivalent Go code for variables and types (lower-case identifiers) - * -Q print equivalent Go code for variables and types (upper-case identifiers) - * -r print registerization - * -s print structure offsets (with -a or -aa) - * -S print assembly - * -t print type trees - * -V enable void* conversion warnings - * -v verbose printing - * -w print warnings - * -X abort on error - * -. Inhibit search for includes in source directory - */ - -void -main(int argc, char *argv[]) -{ - char **defs, *p; - int c, ndef; - - ensuresymb(NSYMB); - memset(debug, 0, sizeof(debug)); - tinit(); - cinit(); - ginit(); - arginit(); - - tufield = simplet((1L<<tfield->etype) | BUNSIGNED); - ndef = 0; - defs = nil; - outfile = 0; - setinclude("."); - ARGBEGIN { - default: - c = ARGC(); - if(c >= 0 && c < sizeof(debug)) - debug[c]++; - break; - - case 'l': /* for little-endian mips */ - if(thechar != 'v'){ - print("can only use -l with vc"); - errorexit(); - } - thechar = '0'; - thestring = "spim"; - break; - - case 'o': - outfile = ARGF(); - break; - - case 'D': - p = ARGF(); - if(p) { - if(ndef%8 == 0) - defs = allocn(defs, ndef*sizeof(char *), - 8*sizeof(char *)); - defs[ndef++] = p; - dodefine(p); - } - break; - - case 'I': - p = ARGF(); - setinclude(p); - break; - } ARGEND - if(argc < 1 && outfile == 0) { - print("usage: %cc [-options] files\n", thechar); - errorexit(); - } - if(argc > 1){ - print("can't compile multiple files\n"); - errorexit(); - } - - if(argc == 0) - c = compile("stdin", defs, ndef); - else - c = compile(argv[0], defs, ndef); - - if(c) - errorexit(); - exits(0); -} - -int -compile(char *file, char **defs, int ndef) -{ - char *ofile; - char *p, **av, opt[256]; - int i, c, fd[2]; - static int first = 1; - - ofile = alloc(strlen(file)+10); - strcpy(ofile, file); - p = utfrrune(ofile, pathchar()); - if(p) { - *p++ = 0; - if(!debug['.']) - include[0] = strdup(ofile); - } else - p = ofile; - - if(outfile == 0) { - outfile = p; - if(outfile) { - if(p = utfrrune(outfile, '.')) - if(p[1] == 'c' && p[2] == 0) - p[0] = 0; - p = utfrune(outfile, 0); - if(debug['a'] && debug['n']) - strcat(p, ".acid"); - else if((debug['q'] || debug['Q']) && debug['n']) - strcat(p, ".go"); - else { - p[0] = '.'; - p[1] = thechar; - p[2] = 0; - } - } else - outfile = "/dev/null"; - } - - if (first) - Binit(&diagbuf, 1, OWRITE); - /* - * if we're writing acid to standard output, don't keep scratching - * outbuf. - */ - if((debug['a'] || debug['q'] || debug['Q']) && !debug['n']) { - if (first) { - outfile = 0; - Binit(&outbuf, dup(1, -1), OWRITE); - dup(2, 1); - } - } else { - c = create(outfile, OWRITE, 0664); - if(c < 0) { - diag(Z, "cannot open %s - %r", outfile); - outfile = 0; - errorexit(); - } - Binit(&outbuf, c, OWRITE); - outfile = strdup(outfile); - } - newio(); - first = 0; - - /* Use an ANSI preprocessor */ - if(debug['p']) { - if(systemtype(Windows)) { - diag(Z, "-p option not supported on windows"); - errorexit(); - } - if(access(file, AREAD) < 0) { - diag(Z, "%s does not exist", file); - errorexit(); - } - if(pipe(fd) < 0) { - diag(Z, "pipe failed"); - errorexit(); - } - switch(fork()) { - case -1: - diag(Z, "fork failed"); - errorexit(); - case 0: - close(fd[0]); - dup(fd[1], 1); - close(fd[1]); - av = alloc((ndef+ninclude+5)*sizeof(char *)); - av[0] = CPP; - i = 1; - if(debug['.']){ - sprint(opt, "-."); - av[i++] = strdup(opt); - } - if(debug['+']) { - sprint(opt, "-+"); - av[i++] = strdup(opt); - } - for(c = 0; c < ndef; c++) - av[i++] = smprint("-D%s", defs[c]); - for(c = 0; c < ninclude; c++) - av[i++] = smprint("-I%s", include[c]); - if(strcmp(file, "stdin") != 0) - av[i++] = file; - av[i] = 0; - if(debug['p'] > 1) { - for(c = 0; c < i; c++) - fprint(2, "%s ", av[c]); - fprint(2, "\n"); - } - exec(av[0], av); - fprint(2, "can't exec C preprocessor %s: %r\n", CPP); - errorexit(); - default: - close(fd[1]); - newfile(file, fd[0]); - break; - } - } else { - if(strcmp(file, "stdin") == 0) - newfile(file, 0); - else - newfile(file, -1); - } - yyparse(); - if(!debug['a'] && !debug['q'] && !debug['Q']) - gclean(); - return nerrors; -} - -void -errorexit(void) -{ - if(outfile) - remove(outfile); - exits("error"); -} - -void -pushio(void) -{ - Io *i; - - i = iostack; - if(i == I) { - yyerror("botch in pushio"); - errorexit(); - } - i->p = fi.p; - i->c = fi.c; -} - -void -newio(void) -{ - Io *i; - static int pushdepth = 0; - - i = iofree; - if(i == I) { - pushdepth++; - if(pushdepth > 1000) { - yyerror("macro/io expansion too deep"); - errorexit(); - } - i = alloc(sizeof(*i)); - } else - iofree = i->link; - i->c = 0; - i->f = -1; - ionext = i; -} - -void -newfile(char *s, int f) -{ - Io *i; - - if(debug['e']) - print("%L: %s\n", lineno, s); - - i = ionext; - i->link = iostack; - iostack = i; - i->f = f; - if(f < 0) - i->f = open(s, 0); - if(i->f < 0) { - yyerror("%cc: %r: %s", thechar, s); - errorexit(); - } - fi.c = 0; - linehist(s, 0); -} - -Sym* -slookup(char *s) -{ - ensuresymb(strlen(s)); - strcpy(symb, s); - return lookup(); -} - -Sym* -lookup(void) -{ - Sym *s; - uint32 h; - char *p; - int c, n; - char *r, *w; - - if((uchar)symb[0] == 0xc2 && (uchar)symb[1] == 0xb7) { - // turn leading · into ""· - h = strlen(symb); - ensuresymb(h+2); - memmove(symb+2, symb, h+1); - symb[0] = '"'; - symb[1] = '"'; - } - - // turn · into . - for(r=w=symb; *r; r++) { - if((uchar)*r == 0xc2 && (uchar)*(r+1) == 0xb7) { - *w++ = '.'; - r++; - }else - *w++ = *r; - } - *w = '\0'; - - h = 0; - for(p=symb; *p;) { - h = h * 3; - h += *p++; - } - n = (p - symb) + 1; - h &= 0xffffff; - h %= NHASH; - c = symb[0]; - for(s = hash[h]; s != S; s = s->link) { - if(s->name[0] != c) - continue; - if(strcmp(s->name, symb) == 0) - return s; - } - s = alloc(sizeof(*s)); - s->name = alloc(n); - memmove(s->name, symb, n); - s->link = hash[h]; - hash[h] = s; - syminit(s); - - return s; -} - -void -syminit(Sym *s) -{ - s->lexical = LNAME; - s->block = 0; - s->offset = 0; - s->type = T; - s->suetag = T; - s->class = CXXX; - s->aused = 0; - s->sig = SIGNONE; -} - -#define EOF (-1) -#define IGN (-2) -#define ESC (1<<20) -#define GETC() ((--fi.c < 0)? filbuf(): (*fi.p++ & 0xff)) - -enum -{ - Numdec = 1<<0, - Numlong = 1<<1, - Numuns = 1<<2, - Numvlong = 1<<3, - Numflt = 1<<4, -}; - -int32 -yylex(void) -{ - vlong vv; - int32 c, c1, t; - char *cp; - Rune rune; - Sym *s; - - if(peekc != IGN) { - c = peekc; - peekc = IGN; - goto l1; - } -l0: - c = GETC(); - -l1: - if(c >= Runeself) { - /* - * extension -- - * all multibyte runes are alpha - */ - cp = symb; - goto talph; - } - if(isspace(c)) { - if(c == '\n') - lineno++; - goto l0; - } - if(isalpha(c)) { - cp = symb; - if(c != 'L') - goto talph; - *cp++ = c; - c = GETC(); - if(c == '\'') { - /* L'x' */ - c = escchar('\'', 1, 0); - if(c == EOF) - c = '\''; - c1 = escchar('\'', 1, 0); - if(c1 != EOF) { - yyerror("missing '"); - peekc = c1; - } - yylval.vval = convvtox(c, TUSHORT); - return LUCONST; - } - if(c == '"') { - goto caselq; - } - goto talph; - } - if(isdigit(c)) - goto tnum; - switch(c) - { - - case EOF: - peekc = EOF; - return -1; - - case '_': - cp = symb; - goto talph; - - case '#': - domacro(); - goto l0; - - case '.': - c1 = GETC(); - if(isdigit(c1)) { - cp = symb; - *cp++ = c; - c = c1; - c1 = 0; - goto casedot; - } - break; - - case '"': - strcpy(symb, "\"<string>\""); - cp = alloc(0); - c1 = 0; - - /* "..." */ - for(;;) { - c = escchar('"', 0, 1); - if(c == EOF) - break; - if(c & ESC) { - cp = allocn(cp, c1, 1); - cp[c1++] = c; - } else { - rune = c; - c = runelen(rune); - cp = allocn(cp, c1, c); - runetochar(cp+c1, &rune); - c1 += c; - } - } - yylval.sval.l = c1; - do { - cp = allocn(cp, c1, 1); - cp[c1++] = 0; - } while(c1 & MAXALIGN); - yylval.sval.s = cp; - return LSTRING; - - caselq: - /* L"..." */ - strcpy(symb, "\"L<string>\""); - cp = alloc(0); - c1 = 0; - for(;;) { - c = escchar('"', 1, 0); - if(c == EOF) - break; - cp = allocn(cp, c1, sizeof(ushort)); - *(ushort*)(cp + c1) = c; - c1 += sizeof(ushort); - } - yylval.sval.l = c1; - do { - cp = allocn(cp, c1, sizeof(ushort)); - *(ushort*)(cp + c1) = 0; - c1 += sizeof(ushort); - } while(c1 & MAXALIGN); - yylval.sval.s = cp; - return LLSTRING; - - case '\'': - /* '.' */ - c = escchar('\'', 0, 0); - if(c == EOF) - c = '\''; - c1 = escchar('\'', 0, 0); - if(c1 != EOF) { - yyerror("missing '"); - peekc = c1; - } - vv = c; - yylval.vval = convvtox(vv, TUCHAR); - if(yylval.vval != vv) - yyerror("overflow in character constant: 0x%x", c); - else - if(c & 0x80){ - nearln = lineno; - warn(Z, "sign-extended character constant"); - } - yylval.vval = convvtox(vv, TCHAR); - return LCONST; - - case '/': - c1 = GETC(); - if(c1 == '*') { - for(;;) { - c = getr(); - while(c == '*') { - c = getr(); - if(c == '/') - goto l0; - } - if(c == EOF) { - yyerror("eof in comment"); - errorexit(); - } - } - } - if(c1 == '/') { - for(;;) { - c = getr(); - if(c == '\n') - goto l0; - if(c == EOF) { - yyerror("eof in comment"); - errorexit(); - } - } - } - if(c1 == '=') - return LDVE; - break; - - case '*': - c1 = GETC(); - if(c1 == '=') - return LMLE; - break; - - case '%': - c1 = GETC(); - if(c1 == '=') - return LMDE; - break; - - case '+': - c1 = GETC(); - if(c1 == '+') - return LPP; - if(c1 == '=') - return LPE; - break; - - case '-': - c1 = GETC(); - if(c1 == '-') - return LMM; - if(c1 == '=') - return LME; - if(c1 == '>') - return LMG; - break; - - case '>': - c1 = GETC(); - if(c1 == '>') { - c = LRSH; - c1 = GETC(); - if(c1 == '=') - return LRSHE; - break; - } - if(c1 == '=') - return LGE; - break; - - case '<': - c1 = GETC(); - if(c1 == '<') { - c = LLSH; - c1 = GETC(); - if(c1 == '=') - return LLSHE; - break; - } - if(c1 == '=') - return LLE; - break; - - case '=': - c1 = GETC(); - if(c1 == '=') - return LEQ; - break; - - case '!': - c1 = GETC(); - if(c1 == '=') - return LNE; - break; - - case '&': - c1 = GETC(); - if(c1 == '&') - return LANDAND; - if(c1 == '=') - return LANDE; - break; - - case '|': - c1 = GETC(); - if(c1 == '|') - return LOROR; - if(c1 == '=') - return LORE; - break; - - case '^': - c1 = GETC(); - if(c1 == '=') - return LXORE; - break; - - default: - return c; - } - peekc = c1; - return c; - -talph: - /* - * cp is set to symb and some - * prefix has been stored - */ - for(;;) { - if(c >= Runeself) { - for(c1=0;;) { - cp[c1++] = c; - if(fullrune(cp, c1)) - break; - c = GETC(); - } - cp += c1; - c = GETC(); - continue; - } - if(!isalnum(c) && c != '_') - break; - *cp++ = c; - c = GETC(); - } - *cp = 0; - if(debug['L']) - print("%L: %s\n", lineno, symb); - peekc = c; - s = lookup(); - if(s->macro) { - newio(); - cp = ionext->b; - macexpand(s, cp); - pushio(); - ionext->link = iostack; - iostack = ionext; - fi.p = cp; - fi.c = strlen(cp); - if(peekc != IGN) { - cp[fi.c++] = peekc; - cp[fi.c] = 0; - peekc = IGN; - } - goto l0; - } - yylval.sym = s; - if(s->class == CTYPEDEF || s->class == CTYPESTR) - return LTYPE; - return s->lexical; - -tnum: - c1 = 0; - cp = symb; - if(c != '0') { - c1 |= Numdec; - for(;;) { - *cp++ = c; - c = GETC(); - if(isdigit(c)) - continue; - goto dc; - } - } - *cp++ = c; - c = GETC(); - if(c == 'x' || c == 'X') - for(;;) { - *cp++ = c; - c = GETC(); - if(isdigit(c)) - continue; - if(c >= 'a' && c <= 'f') - continue; - if(c >= 'A' && c <= 'F') - continue; - if(cp == symb+2) - yyerror("malformed hex constant"); - goto ncu; - } - if(c < '0' || c > '7') - goto dc; - for(;;) { - if(c >= '0' && c <= '7') { - *cp++ = c; - c = GETC(); - continue; - } - goto ncu; - } - -dc: - if(c == '.') - goto casedot; - if(c == 'e' || c == 'E') - goto casee; - -ncu: - if((c == 'U' || c == 'u') && !(c1 & Numuns)) { - c = GETC(); - c1 |= Numuns; - goto ncu; - } - if((c == 'L' || c == 'l') && !(c1 & Numvlong)) { - c = GETC(); - if(c1 & Numlong) - c1 |= Numvlong; - c1 |= Numlong; - goto ncu; - } - *cp = 0; - peekc = c; - if(mpatov(symb, &yylval.vval)) - yyerror("overflow in constant"); - - vv = yylval.vval; - if(c1 & Numvlong) { - if((c1 & Numuns) || convvtox(vv, TVLONG) < 0) { - c = LUVLCONST; - t = TUVLONG; - goto nret; - } - c = LVLCONST; - t = TVLONG; - goto nret; - } - if(c1 & Numlong) { - if((c1 & Numuns) || convvtox(vv, TLONG) < 0) { - c = LULCONST; - t = TULONG; - goto nret; - } - c = LLCONST; - t = TLONG; - goto nret; - } - if((c1 & Numuns) || convvtox(vv, TINT) < 0) { - c = LUCONST; - t = TUINT; - goto nret; - } - c = LCONST; - t = TINT; - goto nret; - -nret: - yylval.vval = convvtox(vv, t); - if(yylval.vval != vv){ - nearln = lineno; - warn(Z, "truncated constant: %T %s", types[t], symb); - } - return c; - -casedot: - for(;;) { - *cp++ = c; - c = GETC(); - if(!isdigit(c)) - break; - } - if(c != 'e' && c != 'E') - goto caseout; - -casee: - *cp++ = 'e'; - c = GETC(); - if(c == '+' || c == '-') { - *cp++ = c; - c = GETC(); - } - if(!isdigit(c)) - yyerror("malformed fp constant exponent"); - while(isdigit(c)) { - *cp++ = c; - c = GETC(); - } - -caseout: - if(c == 'L' || c == 'l') { - c = GETC(); - c1 |= Numlong; - } else - if(c == 'F' || c == 'f') { - c = GETC(); - c1 |= Numflt; - } - *cp = 0; - peekc = c; - yylval.dval = strtod(symb, nil); - if(isInf(yylval.dval, 1) || isInf(yylval.dval, -1)) { - yyerror("overflow in float constant"); - yylval.dval = 0; - } - if(c1 & Numflt) - return LFCONST; - return LDCONST; -} - -/* - * convert a string, s, to vlong in *v - * return conversion overflow. - * required syntax is [0[x]]d* - */ -int -mpatov(char *s, vlong *v) -{ - vlong n, nn; - int c; - - n = 0; - c = *s; - if(c == '0') - goto oct; - while(c = *s++) { - if(c >= '0' && c <= '9') - nn = n*10 + c-'0'; - else - goto bad; - if(n < 0 && nn >= 0) - goto bad; - n = nn; - } - goto out; - -oct: - s++; - c = *s; - if(c == 'x' || c == 'X') - goto hex; - while(c = *s++) { - if(c >= '0' || c <= '7') - nn = n*8 + c-'0'; - else - goto bad; - if(n < 0 && nn >= 0) - goto bad; - n = nn; - } - goto out; - -hex: - s++; - while(c = *s++) { - if(c >= '0' && c <= '9') - c += 0-'0'; - else - if(c >= 'a' && c <= 'f') - c += 10-'a'; - else - if(c >= 'A' && c <= 'F') - c += 10-'A'; - else - goto bad; - nn = n*16 + c; - if(n < 0 && nn >= 0) - goto bad; - n = nn; - } -out: - *v = n; - return 0; - -bad: - *v = ~0; - return 1; -} - -int -getc(void) -{ - int c; - - if(peekc != IGN) { - c = peekc; - peekc = IGN; - } else - c = GETC(); - if(c == '\n') - lineno++; - if(c == EOF) { - yyerror("End of file"); - errorexit(); - } - return c; -} - -int32 -getr(void) -{ - int c, i; - char str[UTFmax+1]; - Rune rune; - - - c = getc(); - if(c < Runeself) - return c; - i = 0; - str[i++] = c; - -loop: - c = getc(); - str[i++] = c; - if(!fullrune(str, i)) - goto loop; - c = chartorune(&rune, str); - if(rune == Runeerror && c == 1) { - nearln = lineno; - diag(Z, "illegal rune in string"); - for(c=0; c<i; c++) - print(" %.2x", *(uchar*)(str+c)); - print("\n"); - } - return rune; -} - -int -getnsc(void) -{ - int c; - - if(peekc != IGN) { - c = peekc; - peekc = IGN; - } else - c = GETC(); - for(;;) { - if(!isspace(c)) - return c; - if(c == '\n') { - lineno++; - return c; - } - c = GETC(); - } -} - -void -unget(int c) -{ - - peekc = c; - if(c == '\n') - lineno--; -} - -int32 -escchar(int32 e, int longflg, int escflg) -{ - int32 c, l; - int i; - -loop: - c = getr(); - if(c == '\n') { - yyerror("newline in string"); - return EOF; - } - if(c != '\\') { - if(c == e) - c = EOF; - return c; - } - c = getr(); - if(c == 'x') { - /* - * note this is not ansi, - * supposed to only accept 2 hex - */ - i = 2; - if(longflg) - i = 4; - l = 0; - for(; i>0; i--) { - c = getc(); - if(c >= '0' && c <= '9') { - l = l*16 + c-'0'; - continue; - } - if(c >= 'a' && c <= 'f') { - l = l*16 + c-'a' + 10; - continue; - } - if(c >= 'A' && c <= 'F') { - l = l*16 + c-'A' + 10; - continue; - } - unget(c); - break; - } - if(escflg) - l |= ESC; - return l; - } - if(c >= '0' && c <= '7') { - /* - * note this is not ansi, - * supposed to only accept 3 oct - */ - i = 2; - if(longflg) - i = 5; - l = c - '0'; - for(; i>0; i--) { - c = getc(); - if(c >= '0' && c <= '7') { - l = l*8 + c-'0'; - continue; - } - unget(c); - } - if(escflg) - l |= ESC; - return l; - } - switch(c) - { - case '\n': goto loop; - case 'n': return '\n'; - case 't': return '\t'; - case 'b': return '\b'; - case 'r': return '\r'; - case 'f': return '\f'; - case 'a': return '\a'; - case 'v': return '\v'; - } - return c; -} - -struct -{ - char *name; - ushort lexical; - ushort type; -} itab[] = -{ - "auto", LAUTO, 0, - "break", LBREAK, 0, - "case", LCASE, 0, - "char", LCHAR, TCHAR, - "const", LCONSTNT, 0, - "continue", LCONTINUE, 0, - "default", LDEFAULT, 0, - "do", LDO, 0, - "double", LDOUBLE, TDOUBLE, - "else", LELSE, 0, - "enum", LENUM, 0, - "extern", LEXTERN, 0, - "float", LFLOAT, TFLOAT, - "for", LFOR, 0, - "goto", LGOTO, 0, - "if", LIF, 0, - "inline", LINLINE, 0, - "int", LINT, TINT, - "long", LLONG, TLONG, - "register", LREGISTER, 0, - "restrict", LRESTRICT, 0, - "return", LRETURN, 0, - "SET", LSET, 0, - "short", LSHORT, TSHORT, - "signed", LSIGNED, 0, - "signof", LSIGNOF, 0, - "sizeof", LSIZEOF, 0, - "static", LSTATIC, 0, - "struct", LSTRUCT, 0, - "switch", LSWITCH, 0, - "typedef", LTYPEDEF, 0, - "typestr", LTYPESTR, 0, - "union", LUNION, 0, - "unsigned", LUNSIGNED, 0, - "USED", LUSED, 0, - "void", LVOID, TVOID, - "volatile", LVOLATILE, 0, - "while", LWHILE, 0, - 0 -}; - -void -cinit(void) -{ - Sym *s; - int i; - Type *t; - - nerrors = 0; - lineno = 1; - iostack = I; - iofree = I; - peekc = IGN; - nhunk = 0; - - types[TXXX] = T; - types[TCHAR] = typ(TCHAR, T); - types[TUCHAR] = typ(TUCHAR, T); - types[TSHORT] = typ(TSHORT, T); - types[TUSHORT] = typ(TUSHORT, T); - types[TINT] = typ(TINT, T); - types[TUINT] = typ(TUINT, T); - types[TLONG] = typ(TLONG, T); - types[TULONG] = typ(TULONG, T); - types[TVLONG] = typ(TVLONG, T); - types[TUVLONG] = typ(TUVLONG, T); - types[TFLOAT] = typ(TFLOAT, T); - types[TDOUBLE] = typ(TDOUBLE, T); - types[TVOID] = typ(TVOID, T); - types[TENUM] = typ(TENUM, T); - types[TFUNC] = typ(TFUNC, types[TINT]); - types[TIND] = typ(TIND, types[TVOID]); - - for(i=0; i<NHASH; i++) - hash[i] = S; - for(i=0; itab[i].name; i++) { - s = slookup(itab[i].name); - s->lexical = itab[i].lexical; - if(itab[i].type != 0) - s->type = types[itab[i].type]; - } - blockno = 0; - autobn = 0; - autoffset = 0; - - t = typ(TARRAY, types[TCHAR]); - t->width = 0; - symstring = slookup(".string"); - symstring->class = CSTATIC; - symstring->type = t; - - t = typ(TARRAY, types[TCHAR]); - t->width = 0; - - nodproto = new(OPROTO, Z, Z); - dclstack = D; - - pathname = allocn(pathname, 0, 100); - if(getwd(pathname, 99) == 0) { - pathname = allocn(pathname, 100, 900); - if(getwd(pathname, 999) == 0) - strcpy(pathname, "/???"); - } - - fmtinstall('O', Oconv); - fmtinstall('T', Tconv); - fmtinstall('F', FNconv); - fmtinstall('L', Lconv); - fmtinstall('Q', Qconv); - fmtinstall('|', VBconv); - fmtinstall('U', Uconv); -} - -int -filbuf(void) -{ - Io *i; - -loop: - i = iostack; - if(i == I) - return EOF; - if(i->f < 0) - goto pop; - fi.c = read(i->f, i->b, BUFSIZ) - 1; - if(fi.c < 0) { - close(i->f); - linehist(0, 0); - goto pop; - } - fi.p = i->b + 1; - return i->b[0] & 0xff; - -pop: - iostack = i->link; - i->link = iofree; - iofree = i; - i = iostack; - if(i == I) - return EOF; - fi.p = i->p; - fi.c = i->c; - if(--fi.c < 0) - goto loop; - return *fi.p++ & 0xff; -} - -int -Oconv(Fmt *fp) -{ - int a; - - a = va_arg(fp->args, int); - if(a < OXXX || a > OEND) - return fmtprint(fp, "***badO %d***", a); - - return fmtstrcpy(fp, onames[a]); -} - -int -Lconv(Fmt *fp) -{ - char str[STRINGSZ], s[STRINGSZ]; - Hist *h; - struct - { - Hist* incl; /* start of this include file */ - int32 idel; /* delta line number to apply to include */ - Hist* line; /* start of this #line directive */ - int32 ldel; /* delta line number to apply to #line */ - } a[HISTSZ]; - int32 l, d; - int i, n; - - l = va_arg(fp->args, int32); - n = 0; - for(h = hist; h != H; h = h->link) { - if(l < h->line) - break; - if(h->name) { - if(h->offset != 0) { /* #line directive, not #pragma */ - if(n > 0 && n < HISTSZ && h->offset >= 0) { - a[n-1].line = h; - a[n-1].ldel = h->line - h->offset + 1; - } - } else { - if(n < HISTSZ) { /* beginning of file */ - a[n].incl = h; - a[n].idel = h->line; - a[n].line = 0; - } - n++; - } - continue; - } - n--; - if(n > 0 && n < HISTSZ) { - d = h->line - a[n].incl->line; - a[n-1].ldel += d; - a[n-1].idel += d; - } - } - if(n > HISTSZ) - n = HISTSZ; - str[0] = 0; - for(i=n-1; i>=0; i--) { - if(i != n-1) { - if(fp->flags & ~(FmtWidth|FmtPrec)) /* BUG ROB - was f3 */ - break; - strcat(str, " "); - } - if(a[i].line) - snprint(s, STRINGSZ, "%s:%d[%s:%d]", - a[i].line->name, l-a[i].ldel+1, - a[i].incl->name, l-a[i].idel+1); - else - snprint(s, STRINGSZ, "%s:%d", - a[i].incl->name, l-a[i].idel+1); - if(strlen(s)+strlen(str) >= STRINGSZ-10) - break; - strcat(str, s); - l = a[i].incl->line - 1; /* now print out start of this file */ - } - if(n == 0) - strcat(str, "<eof>"); - return fmtstrcpy(fp, str); -} - -int -Tconv(Fmt *fp) -{ - char str[STRINGSZ+20], s[STRINGSZ+20]; - Type *t, *t1; - int et; - int32 n; - - str[0] = 0; - for(t = va_arg(fp->args, Type*); t != T; t = t->link) { - et = t->etype; - if(str[0]) - strcat(str, " "); - if(t->garb&~GINCOMPLETE) { - sprint(s, "%s ", gnames[t->garb&~GINCOMPLETE]); - if(strlen(str) + strlen(s) < STRINGSZ) - strcat(str, s); - } - sprint(s, "%s", tnames[et]); - if(strlen(str) + strlen(s) < STRINGSZ) - strcat(str, s); - if(et == TFUNC && (t1 = t->down)) { - sprint(s, "(%T", t1); - if(strlen(str) + strlen(s) < STRINGSZ) - strcat(str, s); - while(t1 = t1->down) { - sprint(s, ", %T", t1); - if(strlen(str) + strlen(s) < STRINGSZ) - strcat(str, s); - } - if(strlen(str) + strlen(s) < STRINGSZ) - strcat(str, ")"); - } - if(et == TARRAY) { - n = t->width; - if(t->link && t->link->width) - n /= t->link->width; - sprint(s, "[%d]", n); - if(strlen(str) + strlen(s) < STRINGSZ) - strcat(str, s); - } - if(t->nbits) { - sprint(s, " %d:%d", t->shift, t->nbits); - if(strlen(str) + strlen(s) < STRINGSZ) - strcat(str, s); - } - if(typesu[et]) { - if(t->tag) { - strcat(str, " "); - if(strlen(str) + strlen(t->tag->name) < STRINGSZ) - strcat(str, t->tag->name); - } else - strcat(str, " {}"); - break; - } - } - return fmtstrcpy(fp, str); -} - -int -FNconv(Fmt *fp) -{ - char *str; - Node *n; - - n = va_arg(fp->args, Node*); - str = "<indirect>"; - if(n != Z && (n->op == ONAME || n->op == ODOT || n->op == OELEM)) - str = n->sym->name; - return fmtstrcpy(fp, str); -} - -int -Qconv(Fmt *fp) -{ - char str[STRINGSZ+20], *s; - int32 b; - int i; - - str[0] = 0; - for(b = va_arg(fp->args, int32); b;) { - i = bitno(b); - if(str[0]) - strcat(str, " "); - s = qnames[i]; - if(strlen(str) + strlen(s) >= STRINGSZ) - break; - strcat(str, s); - b &= ~(1L << i); - } - return fmtstrcpy(fp, str); -} - -int -VBconv(Fmt *fp) -{ - char str[STRINGSZ]; - int i, n, t, pc; - - n = va_arg(fp->args, int); - pc = 0; /* BUG: was printcol */ - i = 0; - while(pc < n) { - t = (pc+4) & ~3; - if(t <= n) { - str[i++] = '\t'; - pc = t; - continue; - } - str[i++] = ' '; - pc++; - } - str[i] = 0; - - return fmtstrcpy(fp, str); -} - -void -setinclude(char *p) -{ - int i; - - if(*p != 0) { - for(i=1; i < ninclude; i++) - if(strcmp(p, include[i]) == 0) - return; - - if(ninclude%8 == 0) - include = allocn(include, ninclude*sizeof(char *), - 8*sizeof(char *)); - include[ninclude++] = p; - } -} - -void* -alloc(int32 n) -{ - void *p; - - p = malloc(n); - if(p == nil) { - print("alloc out of mem\n"); - exits("alloc: out of mem"); - } - memset(p, 0, n); - return p; -} - -void* -allocn(void *p, int32 n, int32 d) -{ - if(p == nil) - return alloc(n+d); - p = realloc(p, n+d); - if(p == nil) { - print("allocn out of mem\n"); - exits("allocn: out of mem"); - } - if(d > 0) - memset((char*)p+n, 0, d); - return p; -} - -void -ensuresymb(int32 n) -{ - if(symb == nil) { - symb = alloc(NSYMB+1); - nsymb = NSYMB; - } - - if(n > nsymb) { - symb = allocn(symb, nsymb, n+1-nsymb); - nsymb = n; - } -} diff --git a/src/cmd/cc/lexbody b/src/cmd/cc/lexbody deleted file mode 100644 index f4cc19c2e..000000000 --- a/src/cmd/cc/lexbody +++ /dev/null @@ -1,769 +0,0 @@ -// Inferno utils/cc/lexbody -// http://code.google.com/p/inferno-os/source/browse/utils/cc/lexbody -// -// 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. - -/* - * common code for all the assemblers - */ - -void -pragpack(void) -{ - while(getnsc() != '\n') - ; -} - -void -pragvararg(void) -{ - while(getnsc() != '\n') - ; -} - -void -pragdynimport(void) -{ - while(getnsc() != '\n') - ; -} - -void -pragdynexport(void) -{ - while(getnsc() != '\n') - ; -} - -void -pragfpround(void) -{ - while(getnsc() != '\n') - ; -} - -void -pragtextflag(void) -{ - while(getnsc() != '\n') - ; -} - -void -pragprofile(void) -{ - while(getnsc() != '\n') - ; -} - -void -pragincomplete(void) -{ - while(getnsc() != '\n') - ; -} - -void* -alloc(int32 n) -{ - void *p; - - p = malloc(n); - if(p == nil) { - print("alloc out of mem\n"); - exits("alloc: out of mem"); - } - memset(p, 0, n); - return p; -} - -void* -allocn(void *p, int32 n, int32 d) -{ - if(p == nil) - return alloc(n+d); - p = realloc(p, n+d); - if(p == nil) { - print("allocn out of mem\n"); - exits("allocn: out of mem"); - } - if(d > 0) - memset((char*)p+n, 0, d); - return p; -} - -void -ensuresymb(int32 n) -{ - if(symb == nil) { - symb = alloc(NSYMB+1); - nsymb = NSYMB; - } - - if(n > nsymb) { - symb = allocn(symb, nsymb, n+1-nsymb); - nsymb = n; - } -} - -void -setinclude(char *p) -{ - int i; - - if(p == 0) - return; - for(i=1; i < ninclude; i++) - if(strcmp(p, include[i]) == 0) - return; - - if(ninclude%8 == 0) - include = allocn(include, ninclude*sizeof(char *), - 8*sizeof(char *)); - include[ninclude++] = p; -} - -void -errorexit(void) -{ - - if(outfile) - remove(outfile); - exits("error"); -} - -void -pushio(void) -{ - Io *i; - - i = iostack; - if(i == I) { - yyerror("botch in pushio"); - errorexit(); - } - i->p = fi.p; - i->c = fi.c; -} - -void -newio(void) -{ - Io *i; - static int pushdepth = 0; - - i = iofree; - if(i == I) { - pushdepth++; - if(pushdepth > 1000) { - yyerror("macro/io expansion too deep"); - errorexit(); - } - i = alloc(sizeof(*i)); - } else - iofree = i->link; - i->c = 0; - i->f = -1; - ionext = i; -} - -void -newfile(char *s, int f) -{ - Io *i; - - i = ionext; - i->link = iostack; - iostack = i; - i->f = f; - if(f < 0) - i->f = open(s, 0); - if(i->f < 0) { - yyerror("%ca: %r: %s", thechar, s); - errorexit(); - } - fi.c = 0; - linehist(s, 0); -} - -Sym* -slookup(char *s) -{ - ensuresymb(strlen(s)); - strcpy(symb, s); - return lookup(); -} - -Sym* -lookup(void) -{ - Sym *s; - int32 h; - char *p; - int c, l; - char *r, *w; - - if((uchar)symb[0] == 0xc2 && (uchar)symb[1] == 0xb7) { - // turn leading · into ""· - h = strlen(symb); - ensuresymb(h+2); - memmove(symb+2, symb, h+1); - symb[0] = '"'; - symb[1] = '"'; - } - - // turn · into . - for(r=w=symb; *r; r++) { - if((uchar)*r == 0xc2 && (uchar)*(r+1) == 0xb7) { - *w++ = '.'; - r++; - }else - *w++ = *r; - } - *w = '\0'; - - h = 0; - for(p=symb; c = *p; p++) - h = h+h+h + c; - l = (p - symb) + 1; - h &= 0xffffff; - h %= NHASH; - c = symb[0]; - for(s = hash[h]; s != S; s = s->link) { - if(s->name[0] != c) - continue; - if(memcmp(s->name, symb, l) == 0) - return s; - } - s = alloc(sizeof(*s)); - s->name = alloc(l); - memmove(s->name, symb, l); - - s->link = hash[h]; - hash[h] = s; - syminit(s); - return s; -} - -int -ISALPHA(int c) -{ - if(isalpha(c)) - return 1; - if(c >= Runeself) - return 1; - return 0; -} - -int32 -yylex(void) -{ - int c, c1; - char *cp; - Sym *s; - - c = peekc; - if(c != IGN) { - peekc = IGN; - goto l1; - } -l0: - c = GETC(); - -l1: - if(c == EOF) { - peekc = EOF; - return -1; - } - if(isspace(c)) { - if(c == '\n') { - lineno++; - return ';'; - } - goto l0; - } - if(ISALPHA(c)) - goto talph; - if(isdigit(c)) - goto tnum; - switch(c) - { - case '\n': - lineno++; - return ';'; - - case '#': - domacro(); - goto l0; - - case '.': - c = GETC(); - if(ISALPHA(c)) { - cp = symb; - *cp++ = '.'; - goto aloop; - } - if(isdigit(c)) { - cp = symb; - *cp++ = '.'; - goto casedot; - } - peekc = c; - return '.'; - - talph: - case '_': - case '@': - cp = symb; - - aloop: - *cp++ = c; - c = GETC(); - if(ISALPHA(c) || isdigit(c) || c == '_' || c == '$') - goto aloop; - *cp = 0; - peekc = c; - s = lookup(); - if(s->macro) { - newio(); - cp = ionext->b; - macexpand(s, cp); - pushio(); - ionext->link = iostack; - iostack = ionext; - fi.p = cp; - fi.c = strlen(cp); - if(peekc != IGN) { - cp[fi.c++] = peekc; - cp[fi.c] = 0; - peekc = IGN; - } - goto l0; - } - if(s->type == 0) - s->type = LNAME; - if(s->type == LNAME || - s->type == LVAR || - s->type == LLAB) { - yylval.sym = s; - return s->type; - } - yylval.lval = s->value; - return s->type; - - tnum: - cp = symb; - if(c != '0') - goto dc; - *cp++ = c; - c = GETC(); - c1 = 3; - if(c == 'x' || c == 'X') { - c1 = 4; - c = GETC(); - } else - if(c < '0' || c > '7') - goto dc; - yylval.lval = 0; - for(;;) { - if(c >= '0' && c <= '9') { - if(c > '7' && c1 == 3) - break; - yylval.lval <<= c1; - yylval.lval += c - '0'; - c = GETC(); - continue; - } - if(c1 == 3) - break; - if(c >= 'A' && c <= 'F') - c += 'a' - 'A'; - if(c >= 'a' && c <= 'f') { - yylval.lval <<= c1; - yylval.lval += c - 'a' + 10; - c = GETC(); - continue; - } - break; - } - goto ncu; - - dc: - for(;;) { - if(!isdigit(c)) - break; - *cp++ = c; - c = GETC(); - } - if(c == '.') - goto casedot; - if(c == 'e' || c == 'E') - goto casee; - *cp = 0; - if(sizeof(yylval.lval) == sizeof(vlong)) - yylval.lval = strtoll(symb, nil, 10); - else - yylval.lval = strtol(symb, nil, 10); - - ncu: - while(c == 'U' || c == 'u' || c == 'l' || c == 'L') - c = GETC(); - peekc = c; - return LCONST; - - casedot: - for(;;) { - *cp++ = c; - c = GETC(); - if(!isdigit(c)) - break; - } - if(c == 'e' || c == 'E') - goto casee; - goto caseout; - - casee: - *cp++ = 'e'; - c = GETC(); - if(c == '+' || c == '-') { - *cp++ = c; - c = GETC(); - } - while(isdigit(c)) { - *cp++ = c; - c = GETC(); - } - - caseout: - *cp = 0; - peekc = c; - if(FPCHIP) { - yylval.dval = atof(symb); - return LFCONST; - } - yyerror("assembler cannot interpret fp constants"); - yylval.lval = 1L; - return LCONST; - - case '"': - memcpy(yylval.sval, nullgen.sval, sizeof(yylval.sval)); - cp = yylval.sval; - c1 = 0; - for(;;) { - c = escchar('"'); - if(c == EOF) - break; - if(c1 < sizeof(yylval.sval)) - *cp++ = c; - c1++; - } - if(c1 > sizeof(yylval.sval)) - yyerror("string constant too long"); - return LSCONST; - - case '\'': - c = escchar('\''); - if(c == EOF) - c = '\''; - if(escchar('\'') != EOF) - yyerror("missing '"); - yylval.lval = c; - return LCONST; - - case '/': - c1 = GETC(); - if(c1 == '/') { - for(;;) { - c = GETC(); - if(c == '\n') - goto l1; - if(c == EOF) { - yyerror("eof in comment"); - errorexit(); - } - } - } - if(c1 == '*') { - for(;;) { - c = GETC(); - while(c == '*') { - c = GETC(); - if(c == '/') - goto l0; - } - if(c == EOF) { - yyerror("eof in comment"); - errorexit(); - } - if(c == '\n') - lineno++; - } - } - break; - - default: - return c; - } - peekc = c1; - return c; -} - -int -getc(void) -{ - int c; - - c = peekc; - if(c != IGN) { - peekc = IGN; - return c; - } - c = GETC(); - if(c == '\n') - lineno++; - if(c == EOF) { - yyerror("End of file"); - errorexit(); - } - return c; -} - -int -getnsc(void) -{ - int c; - - for(;;) { - c = getc(); - if(!isspace(c) || c == '\n') - return c; - } -} - -void -unget(int c) -{ - - peekc = c; - if(c == '\n') - lineno--; -} - -int -escchar(int e) -{ - int c, l; - -loop: - c = getc(); - if(c == '\n') { - yyerror("newline in string"); - return EOF; - } - if(c != '\\') { - if(c == e) - return EOF; - return c; - } - c = getc(); - if(c >= '0' && c <= '7') { - l = c - '0'; - c = getc(); - if(c >= '0' && c <= '7') { - l = l*8 + c-'0'; - c = getc(); - if(c >= '0' && c <= '7') { - l = l*8 + c-'0'; - return l; - } - } - peekc = c; - return l; - } - switch(c) - { - case '\n': goto loop; - case 'n': return '\n'; - case 't': return '\t'; - case 'b': return '\b'; - case 'r': return '\r'; - case 'f': return '\f'; - case 'a': return 0x07; - case 'v': return 0x0b; - case 'z': return 0x00; - } - return c; -} - -void -pinit(char *f) -{ - int i; - Sym *s; - - lineno = 1; - newio(); - newfile(f, -1); - pc = 0; - peekc = IGN; - sym = 1; - for(i=0; i<NSYM; i++) { - h[i].type = 0; - h[i].sym = S; - } - for(i=0; i<NHASH; i++) - for(s = hash[i]; s != S; s = s->link) - s->macro = 0; -} - -int -filbuf(void) -{ - Io *i; - -loop: - i = iostack; - if(i == I) - return EOF; - if(i->f < 0) - goto pop; - fi.c = read(i->f, i->b, BUFSIZ) - 1; - if(fi.c < 0) { - close(i->f); - linehist(0, 0); - goto pop; - } - fi.p = i->b + 1; - return i->b[0]; - -pop: - iostack = i->link; - i->link = iofree; - iofree = i; - i = iostack; - if(i == I) - return EOF; - fi.p = i->p; - fi.c = i->c; - if(--fi.c < 0) - goto loop; - return *fi.p++; -} - -void -yyerror(char *a, ...) -{ - char buf[200]; - va_list arg; - - /* - * hack to intercept message from yaccpar - */ - if(strcmp(a, "syntax error") == 0) { - yyerror("syntax error, last name: %s", symb); - return; - } - prfile(lineno); - va_start(arg, a); - vseprint(buf, buf+sizeof(buf), a, arg); - va_end(arg); - print("%s\n", buf); - nerrors++; - if(nerrors > 10) { - print("too many errors\n"); - errorexit(); - } -} - -void -prfile(int32 l) -{ - int i, n; - Hist a[HISTSZ], *h; - int32 d; - - n = 0; - for(h = hist; h != H; h = h->link) { - if(l < h->line) - break; - if(h->name) { - if(h->offset == 0) { - if(n >= 0 && n < HISTSZ) - a[n] = *h; - n++; - continue; - } - if(n > 0 && n < HISTSZ) - if(a[n-1].offset == 0) { - a[n] = *h; - n++; - } else - a[n-1] = *h; - continue; - } - n--; - if(n >= 0 && n < HISTSZ) { - d = h->line - a[n].line; - for(i=0; i<n; i++) - a[i].line += d; - } - } - if(n > HISTSZ) - n = HISTSZ; - for(i=0; i<n; i++) - print("%s:%ld ", a[i].name, (long)(l-a[i].line+a[i].offset+1)); -} - -void -ieeedtod(Ieee *ieee, double native) -{ - double fr, ho, f; - int exp; - - if(native < 0) { - ieeedtod(ieee, -native); - ieee->h |= 0x80000000L; - return; - } - if(native == 0) { - ieee->l = 0; - ieee->h = 0; - return; - } - fr = frexp(native, &exp); - f = 2097152L; /* shouldnt use fp constants here */ - fr = modf(fr*f, &ho); - ieee->h = ho; - ieee->h &= 0xfffffL; - ieee->h |= (exp+1022L) << 20; - f = 65536L; - fr = modf(fr*f, &ho); - ieee->l = ho; - ieee->l <<= 16; - ieee->l |= (int32)(fr*f); -} diff --git a/src/cmd/cc/mac.c b/src/cmd/cc/mac.c deleted file mode 100644 index 43ae214d7..000000000 --- a/src/cmd/cc/mac.c +++ /dev/null @@ -1,35 +0,0 @@ -// Inferno utils/cc/mac.c -// http://code.google.com/p/inferno-os/source/browse/utils/cc/mac.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 "macbody" diff --git a/src/cmd/cc/macbody b/src/cmd/cc/macbody deleted file mode 100644 index ed66361f1..000000000 --- a/src/cmd/cc/macbody +++ /dev/null @@ -1,852 +0,0 @@ -// Inferno utils/cc/macbody -// http://code.google.com/p/inferno-os/source/browse/utils/cc/macbody -// -// 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. - -#define VARMAC 0x80 - -int32 -getnsn(void) -{ - int32 n; - int c; - - c = getnsc(); - if(c < '0' || c > '9') - return -1; - n = 0; - while(c >= '0' && c <= '9') { - n = n*10 + c-'0'; - c = getc(); - } - unget(c); - return n; -} - -Sym* -getsym(void) -{ - int c; - char *cp; - - c = getnsc(); - if(!isalpha(c) && c != '_' && c < 0x80) { - unget(c); - return S; - } - for(cp = symb;;) { - if(cp <= symb+NSYMB-4) - *cp++ = c; - c = getc(); - if(isalnum(c) || c == '_' || c >= 0x80) - continue; - unget(c); - break; - } - *cp = 0; - if(cp > symb+NSYMB-4) - yyerror("symbol too large: %s", symb); - return lookup(); -} - -Sym* -getsymdots(int *dots) -{ - int c; - Sym *s; - - s = getsym(); - if(s != S) - return s; - - c = getnsc(); - if(c != '.'){ - unget(c); - return S; - } - if(getc() != '.' || getc() != '.') - yyerror("bad dots in macro"); - *dots = 1; - return slookup("__VA_ARGS__"); -} - -int -getcom(void) -{ - int c; - - for(;;) { - c = getnsc(); - if(c != '/') - break; - c = getc(); - if(c == '/') { - while(c != '\n') - c = getc(); - break; - } - if(c != '*') - break; - c = getc(); - for(;;) { - if(c == '*') { - c = getc(); - if(c != '/') - continue; - c = getc(); - break; - } - if(c == '\n') { - yyerror("comment across newline"); - break; - } - c = getc(); - } - if(c == '\n') - break; - } - return c; -} - -void -dodefine(char *cp) -{ - Sym *s; - char *p; - int32 l; - - ensuresymb(strlen(cp)); - strcpy(symb, cp); - p = strchr(symb, '='); - if(p) { - *p++ = 0; - s = lookup(); - l = strlen(p) + 2; /* +1 null, +1 nargs */ - s->macro = alloc(l); - strcpy(s->macro+1, p); - } else { - s = lookup(); - s->macro = "\0001"; /* \000 is nargs */ - } - if(debug['m']) - print("#define (-D) %s %s\n", s->name, s->macro+1); -} - -struct -{ - char *macname; - void (*macf)(void); -} mactab[] = -{ - "ifdef", 0, /* macif(0) */ - "ifndef", 0, /* macif(1) */ - "else", 0, /* macif(2) */ - - "line", maclin, - "define", macdef, - "include", macinc, - "undef", macund, - - "pragma", macprag, - "endif", macend, - 0 -}; - -void -domacro(void) -{ - int i; - Sym *s; - - s = getsym(); - if(s == S) - s = slookup("endif"); - for(i=0; mactab[i].macname; i++) - if(strcmp(s->name, mactab[i].macname) == 0) { - if(mactab[i].macf) - (*mactab[i].macf)(); - else - macif(i); - return; - } - yyerror("unknown #: %s", s->name); - macend(); -} - -void -macund(void) -{ - Sym *s; - - s = getsym(); - macend(); - if(s == S) { - yyerror("syntax in #undef"); - return; - } - s->macro = 0; -} - -#define NARG 25 -void -macdef(void) -{ - Sym *s, *a; - char *args[NARG], *np, *base; - int n, i, c, len, dots; - int ischr; - - s = getsym(); - if(s == S) - goto bad; - if(s->macro) - yyerror("macro redefined: %s", s->name); - c = getc(); - n = -1; - dots = 0; - if(c == '(') { - n++; - c = getnsc(); - if(c != ')') { - unget(c); - for(;;) { - a = getsymdots(&dots); - if(a == S) - goto bad; - if(n >= NARG) { - yyerror("too many arguments in #define: %s", s->name); - goto bad; - } - args[n++] = a->name; - c = getnsc(); - if(c == ')') - break; - if(c != ',' || dots) - goto bad; - } - } - c = getc(); - } - if(isspace(c)) - if(c != '\n') - c = getnsc(); - base = hunk; - len = 1; - ischr = 0; - for(;;) { - if(isalpha(c) || c == '_') { - np = symb; - *np++ = c; - c = getc(); - while(isalnum(c) || c == '_') { - *np++ = c; - c = getc(); - } - *np = 0; - for(i=0; i<n; i++) - if(strcmp(symb, args[i]) == 0) - break; - if(i >= n) { - i = strlen(symb); - base = allocn(base, len, i); - memcpy(base+len, symb, i); - len += i; - continue; - } - base = allocn(base, len, 2); - base[len++] = '#'; - base[len++] = 'a' + i; - continue; - } - if(ischr){ - if(c == '\\'){ - base = allocn(base, len, 1); - base[len++] = c; - c = getc(); - }else if(c == ischr) - ischr = 0; - }else{ - if(c == '"' || c == '\''){ - base = allocn(base, len, 1); - base[len++] = c; - ischr = c; - c = getc(); - continue; - } - if(c == '/') { - c = getc(); - if(c == '/'){ - c = getc(); - for(;;) { - if(c == '\n') - break; - c = getc(); - } - continue; - } - if(c == '*'){ - c = getc(); - for(;;) { - if(c == '*') { - c = getc(); - if(c != '/') - continue; - c = getc(); - break; - } - if(c == '\n') { - yyerror("comment and newline in define: %s", s->name); - break; - } - c = getc(); - } - continue; - } - base = allocn(base, len, 1); - base[len++] = '/'; - continue; - } - } - if(c == '\\') { - c = getc(); - if(c == '\n') { - c = getc(); - continue; - } - else if(c == '\r') { - c = getc(); - if(c == '\n') { - c = getc(); - continue; - } - } - base = allocn(base, len, 1); - base[len++] = '\\'; - continue; - } - if(c == '\n') - break; - if(c == '#') - if(n > 0) { - base = allocn(base, len, 1); - base[len++] = c; - } - base = allocn(base, len, 1); - base[len++] = c; - c = ((--fi.c < 0)? filbuf(): (*fi.p++ & 0xff)); - if(c == '\n') - lineno++; - if(c == -1) { - yyerror("eof in a macro: %s", s->name); - break; - } - } - do { - base = allocn(base, len, 1); - base[len++] = 0; - } while(len & 3); - - *base = n+1; - if(dots) - *base |= VARMAC; - s->macro = base; - if(debug['m']) - print("#define %s %s\n", s->name, s->macro+1); - return; - -bad: - if(s == S) - yyerror("syntax in #define"); - else - yyerror("syntax in #define: %s", s->name); - macend(); -} - -void -macexpand(Sym *s, char *b) -{ - char buf[2000]; - int n, l, c, nargs; - char *arg[NARG], *cp, *ob, *ecp, dots; - - ob = b; - if(*s->macro == 0) { - strcpy(b, s->macro+1); - if(debug['m']) - print("#expand %s %s\n", s->name, ob); - return; - } - - nargs = (char)(*s->macro & ~VARMAC) - 1; - dots = *s->macro & VARMAC; - - c = getnsc(); - if(c != '(') - goto bad; - n = 0; - c = getc(); - if(c != ')') { - unget(c); - l = 0; - cp = buf; - ecp = cp + sizeof(buf)-4; - arg[n++] = cp; - for(;;) { - if(cp >= ecp) - goto toobig; - c = getc(); - if(c == '"') - for(;;) { - if(cp >= ecp) - goto toobig; - *cp++ = c; - c = getc(); - if(c == '\\') { - *cp++ = c; - c = getc(); - continue; - } - if(c == '\n') - goto bad; - if(c == '"') - break; - } - if(c == '\'') - for(;;) { - if(cp >= ecp) - goto toobig; - *cp++ = c; - c = getc(); - if(c == '\\') { - *cp++ = c; - c = getc(); - continue; - } - if(c == '\n') - goto bad; - if(c == '\'') - break; - } - if(c == '/') { - c = getc(); - switch(c) { - case '*': - for(;;) { - c = getc(); - if(c == '*') { - c = getc(); - if(c == '/') - break; - } - } - *cp++ = ' '; - continue; - case '/': - while((c = getc()) != '\n') - ; - break; - default: - unget(c); - c = '/'; - } - } - if(l == 0) { - if(c == ',') { - if(n == nargs && dots) { - *cp++ = ','; - continue; - } - *cp++ = 0; - arg[n++] = cp; - if(n > nargs) - break; - continue; - } - if(c == ')') - break; - } - if(c == '\n') - c = ' '; - *cp++ = c; - if(c == '(') - l++; - if(c == ')') - l--; - } - *cp = 0; - } - if(n != nargs) { - yyerror("argument mismatch expanding: %s", s->name); - *b = 0; - return; - } - cp = s->macro+1; - for(;;) { - c = *cp++; - if(c == '\n') - c = ' '; - if(c != '#') { - *b++ = c; - if(c == 0) - break; - continue; - } - c = *cp++; - if(c == 0) - goto bad; - if(c == '#') { - *b++ = c; - continue; - } - c -= 'a'; - if(c < 0 || c >= n) - continue; - strcpy(b, arg[c]); - b += strlen(arg[c]); - } - *b = 0; - if(debug['m']) - print("#expand %s %s\n", s->name, ob); - return; - -bad: - yyerror("syntax in macro expansion: %s", s->name); - *b = 0; - return; - -toobig: - yyerror("too much text in macro expansion: %s", s->name); - *b = 0; -} - -void -macinc(void) -{ - int c0, c, i, f; - char str[STRINGSZ], *hp; - - c0 = getnsc(); - if(c0 != '"') { - c = c0; - if(c0 != '<') - goto bad; - c0 = '>'; - } - for(hp = str;;) { - c = getc(); - if(c == c0) - break; - if(c == '\n') - goto bad; - *hp++ = c; - } - *hp = 0; - - c = getcom(); - if(c != '\n') - goto bad; - - f = -1; - for(i=0; i<ninclude; i++) { - if(i == 0 && c0 == '>') - continue; - ensuresymb(strlen(include[i])+strlen(str)+2); - strcpy(symb, include[i]); - strcat(symb, "/"); - if(strcmp(symb, "./") == 0) - symb[0] = 0; - strcat(symb, str); - f = open(symb, OREAD); - if(f >= 0) - break; - } - if(f < 0) - strcpy(symb, str); - c = strlen(symb) + 1; - hp = alloc(c); - memcpy(hp, symb, c); - newio(); - pushio(); - newfile(hp, f); - return; - -bad: - unget(c); - yyerror("syntax in #include"); - macend(); -} - -void -maclin(void) -{ - char *cp; - int c; - int32 n; - - n = getnsn(); - c = getc(); - if(n < 0) - goto bad; - - for(;;) { - if(c == ' ' || c == '\t') { - c = getc(); - continue; - } - if(c == '"') - break; - if(c == '\n') { - strcpy(symb, "<noname>"); - goto nn; - } - goto bad; - } - cp = symb; - for(;;) { - c = getc(); - if(c == '"') - break; - *cp++ = c; - } - *cp = 0; - c = getcom(); - if(c != '\n') - goto bad; - -nn: - c = strlen(symb) + 1; - cp = alloc(c); - memcpy(cp, symb, c); - linehist(cp, n); - return; - -bad: - unget(c); - yyerror("syntax in #line"); - macend(); -} - -void -macif(int f) -{ - int c, l, bol; - Sym *s; - - if(f == 2) - goto skip; - s = getsym(); - if(s == S) - goto bad; - if(getcom() != '\n') - goto bad; - if((s->macro != 0) ^ f) - return; - -skip: - bol = 1; - l = 0; - for(;;) { - c = getc(); - if(c != '#') { - if(!isspace(c)) - bol = 0; - if(c == '\n') - bol = 1; - continue; - } - if(!bol) - continue; - s = getsym(); - if(s == S) - continue; - if(strcmp(s->name, "endif") == 0) { - if(l) { - l--; - continue; - } - macend(); - return; - } - if(strcmp(s->name, "ifdef") == 0 || strcmp(s->name, "ifndef") == 0) { - l++; - continue; - } - if(l == 0 && f != 2 && strcmp(s->name, "else") == 0) { - macend(); - return; - } - } - -bad: - yyerror("syntax in #if(n)def"); - macend(); -} - -void -macprag(void) -{ - Sym *s; - int c0, c; - char *hp; - Hist *h; - - s = getsym(); - - if(s && strcmp(s->name, "lib") == 0) - goto praglib; - if(s && strcmp(s->name, "pack") == 0) { - pragpack(); - return; - } - if(s && strcmp(s->name, "fpround") == 0) { - pragfpround(); - return; - } - if(s && strcmp(s->name, "textflag") == 0) { - pragtextflag(); - return; - } - if(s && strcmp(s->name, "varargck") == 0) { - pragvararg(); - return; - } - if(s && strcmp(s->name, "incomplete") == 0) { - pragincomplete(); - return; - } - if(s && strcmp(s->name, "dynimport") == 0) { - pragdynimport(); - return; - } - if(s && strcmp(s->name, "dynexport") == 0) { - pragdynexport(); - return; - } - while(getnsc() != '\n') - ; - return; - -praglib: - c0 = getnsc(); - if(c0 != '"') { - c = c0; - if(c0 != '<') - goto bad; - c0 = '>'; - } - for(hp = symb;;) { - c = getc(); - if(c == c0) - break; - if(c == '\n') - goto bad; - *hp++ = c; - } - *hp = 0; - c = getcom(); - if(c != '\n') - goto bad; - - /* - * put pragma-line in as a funny history - */ - c = strlen(symb) + 1; - hp = alloc(c); - memcpy(hp, symb, c); - - h = alloc(sizeof(Hist)); - h->name = hp; - h->line = lineno; - h->offset = -1; - h->link = H; - if(ehist == H) { - hist = h; - ehist = h; - return; - } - ehist->link = h; - ehist = h; - return; - -bad: - unget(c); - yyerror("syntax in #pragma lib"); - macend(); -} - -void -macend(void) -{ - int c; - - for(;;) { - c = getnsc(); - if(c < 0 || c == '\n') - return; - } -} - -void -linehist(char *f, int offset) -{ - Hist *h; - - /* - * overwrite the last #line directive if - * no alloc has happened since the last one - */ - if(newflag == 0 && ehist != H && offset != 0 && ehist->offset != 0) - if(f && ehist->name && strcmp(f, ehist->name) == 0) { - ehist->line = lineno; - ehist->offset = offset; - return; - } - - if(debug['f']) - if(f) { - if(offset) - print("%4d: %s (#line %d)\n", lineno, f, offset); - else - print("%4d: %s\n", lineno, f); - } else - print("%4d: <pop>\n", lineno); - newflag = 0; - - h = alloc(sizeof(Hist)); - h->name = f; - h->line = lineno; - h->offset = offset; - h->link = H; - if(ehist == H) { - hist = h; - ehist = h; - return; - } - ehist->link = h; - ehist = h; -} diff --git a/src/cmd/cc/omachcap.c b/src/cmd/cc/omachcap.c deleted file mode 100644 index f8fc1d88b..000000000 --- a/src/cmd/cc/omachcap.c +++ /dev/null @@ -1,40 +0,0 @@ -// Inferno utils/cc/machcap.c -// http://code.google.com/p/inferno-os/source/browse/utils/cc/machcap.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" - -/* default, like old cc */ -int -machcap(Node *n) -{ - USED(n); - return 0; -} diff --git a/src/cmd/cc/pgen.c b/src/cmd/cc/pgen.c deleted file mode 100644 index 0e5e8c059..000000000 --- a/src/cmd/cc/pgen.c +++ /dev/null @@ -1,594 +0,0 @@ -// Inferno utils/6c/sgen.c -// http://code.google.com/p/inferno-os/source/browse/utils/6c/sgen.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 "gc.h" - -vlong -argsize(void) -{ - Type *t; - int32 s; - -//print("t=%T\n", thisfn); - s = align(0, thisfn->link, Aarg0, nil); - for(t=thisfn->down; t!=T; t=t->down) { - switch(t->etype) { - case TVOID: - break; - case TDOT: - yyerror("function takes ... without textflag NOSPLIT"); - s += 64; - break; - default: - s = align(s, t, Aarg1, nil); - s = align(s, t, Aarg2, nil); - break; - } -//print(" %d %T\n", s, t); - } - if(thechar == '6') - s = (s+7) & ~7; - else - s = (s+3) & ~3; - return s; -} - -void -codgen(Node *n, Node *nn) -{ - Prog *sp; - Node *n1, nod, nod1; - - cursafe = 0; - curarg = 0; - maxargsafe = 0; - - /* - * isolate name - */ - for(n1 = nn;; n1 = n1->left) { - if(n1 == Z) { - diag(nn, "cant find function name"); - return; - } - if(n1->op == ONAME) - break; - } - nearln = nn->lineno; - - p = gtext(n1->sym, stkoff); - sp = p; - - /* - * isolate first argument - */ - if(REGARG >= 0) { - if(typesuv[thisfn->link->etype]) { - nod1 = *nodret->left; - nodreg(&nod, &nod1, REGARG); - gmove(&nod, &nod1); - } else - if(firstarg && typechlp[firstargtype->etype]) { - nod1 = *nodret->left; - nod1.sym = firstarg; - nod1.type = firstargtype; - nod1.xoffset = align(0, firstargtype, Aarg1, nil); - nod1.etype = firstargtype->etype; - nodreg(&nod, &nod1, REGARG); - gmove(&nod, &nod1); - } - } - - retok = 0; - - canreach = 1; - warnreach = 1; - gen(n); - if(canreach && thisfn->link->etype != TVOID) - diag(Z, "no return at end of function: %s", n1->sym->name); - noretval(3); - gbranch(ORETURN); - - if(!debug['N'] || debug['R'] || debug['P']) - regopt(sp); - - if(thechar=='6' || thechar=='7') /* [sic] */ - maxargsafe = xround(maxargsafe, 8); - sp->to.offset += maxargsafe; -} - -void -supgen(Node *n) -{ - int owarn; - long spc; - Prog *sp; - - if(n == Z) - return; - suppress++; - owarn = warnreach; - warnreach = 0; - spc = pc; - sp = lastp; - gen(n); - lastp = sp; - pc = spc; - sp->link = nil; - suppress--; - warnreach = owarn; -} - -void -gen(Node *n) -{ - Node *l, nod; - Prog *sp, *spc, *spb; - Case *cn; - long sbc, scc; - int snbreak, sncontin; - int f, o, oldreach; - -loop: - if(n == Z) - return; - nearln = n->lineno; - o = n->op; - if(debug['G']) - if(o != OLIST) - print("%L %O\n", nearln, o); - - if(!canreach) { - switch(o) { - case OLABEL: - case OCASE: - case OLIST: - case OBREAK: - case OFOR: - case OWHILE: - case ODWHILE: - /* all handled specially - see switch body below */ - break; - default: - if(warnreach) { - warn(n, "unreachable code %O", o); - warnreach = 0; - } - } - } - - switch(o) { - - default: - complex(n); - cgen(n, Z); - break; - - case OLIST: - gen(n->left); - - rloop: - n = n->right; - goto loop; - - case ORETURN: - canreach = 0; - warnreach = !suppress; - complex(n); - if(n->type == T) - break; - l = n->left; - if(l == Z) { - noretval(3); - gbranch(ORETURN); - break; - } - if(typecmplx[n->type->etype]) { - sugen(l, nodret, n->type->width); - noretval(3); - gbranch(ORETURN); - break; - } - regret(&nod, n); - cgen(l, &nod); - regfree(&nod); - if(typefd[n->type->etype]) - noretval(1); - else - noretval(2); - gbranch(ORETURN); - break; - - case OLABEL: - canreach = 1; - l = n->left; - if(l) { - l->pc = pc; - if(l->label) - patch(l->label, pc); - } - gbranch(OGOTO); /* prevent self reference in reg */ - patch(p, pc); - goto rloop; - - case OGOTO: - canreach = 0; - warnreach = !suppress; - n = n->left; - if(n == Z) - return; - if(n->complex == 0) { - diag(Z, "label undefined: %s", n->sym->name); - return; - } - if(suppress) - return; - gbranch(OGOTO); - if(n->pc) { - patch(p, n->pc); - return; - } - if(n->label) - patch(n->label, pc-1); - n->label = p; - return; - - case OCASE: - canreach = 1; - l = n->left; - if(cases == C) - diag(n, "case/default outside a switch"); - if(l == Z) { - cas(); - cases->val = 0; - cases->def = 1; - cases->label = pc; - cases->isv = 0; - goto rloop; - } - complex(l); - if(l->type == T) - goto rloop; - if(l->op == OCONST) - if(typeword[l->type->etype] && l->type->etype != TIND) { - cas(); - cases->val = l->vconst; - cases->def = 0; - cases->label = pc; - cases->isv = typev[l->type->etype]; - goto rloop; - } - diag(n, "case expression must be integer constant"); - goto rloop; - - case OSWITCH: - l = n->left; - complex(l); - if(l->type == T) - break; - if(!typeword[l->type->etype] || l->type->etype == TIND) { - diag(n, "switch expression must be integer"); - break; - } - - gbranch(OGOTO); /* entry */ - sp = p; - - cn = cases; - cases = C; - cas(); - - sbc = breakpc; - breakpc = pc; - snbreak = nbreak; - nbreak = 0; - gbranch(OGOTO); - spb = p; - - gen(n->right); /* body */ - if(canreach){ - gbranch(OGOTO); - patch(p, breakpc); - nbreak++; - } - - patch(sp, pc); - regalloc(&nod, l, Z); - /* always signed */ - if(typev[l->type->etype]) - nod.type = types[TVLONG]; - else - nod.type = types[TLONG]; - cgen(l, &nod); - doswit(&nod); - regfree(&nod); - patch(spb, pc); - - cases = cn; - breakpc = sbc; - canreach = nbreak!=0; - if(canreach == 0) - warnreach = !suppress; - nbreak = snbreak; - break; - - case OWHILE: - case ODWHILE: - l = n->left; - gbranch(OGOTO); /* entry */ - sp = p; - - scc = continpc; - continpc = pc; - gbranch(OGOTO); - spc = p; - - sbc = breakpc; - breakpc = pc; - snbreak = nbreak; - nbreak = 0; - gbranch(OGOTO); - spb = p; - - patch(spc, pc); - if(n->op == OWHILE) - patch(sp, pc); - bcomplex(l, Z); /* test */ - patch(p, breakpc); - if(l->op != OCONST || vconst(l) == 0) - nbreak++; - - if(n->op == ODWHILE) - patch(sp, pc); - gen(n->right); /* body */ - gbranch(OGOTO); - patch(p, continpc); - - patch(spb, pc); - continpc = scc; - breakpc = sbc; - canreach = nbreak!=0; - if(canreach == 0) - warnreach = !suppress; - nbreak = snbreak; - break; - - case OFOR: - l = n->left; - if(!canreach && l->right->left && warnreach) { - warn(n, "unreachable code FOR"); - warnreach = 0; - } - gen(l->right->left); /* init */ - gbranch(OGOTO); /* entry */ - sp = p; - - /* - * if there are no incoming labels in the - * body and the top's not reachable, warn - */ - if(!canreach && warnreach && deadheads(n)) { - warn(n, "unreachable code %O", o); - warnreach = 0; - } - - scc = continpc; - continpc = pc; - gbranch(OGOTO); - spc = p; - - sbc = breakpc; - breakpc = pc; - snbreak = nbreak; - nbreak = 0; - sncontin = ncontin; - ncontin = 0; - gbranch(OGOTO); - spb = p; - - patch(spc, pc); - gen(l->right->right); /* inc */ - patch(sp, pc); - if(l->left != Z) { /* test */ - bcomplex(l->left, Z); - patch(p, breakpc); - if(l->left->op != OCONST || vconst(l->left) == 0) - nbreak++; - } - canreach = 1; - gen(n->right); /* body */ - if(canreach){ - gbranch(OGOTO); - patch(p, continpc); - ncontin++; - } - if(!ncontin && l->right->right && warnreach) { - warn(l->right->right, "unreachable FOR inc"); - warnreach = 0; - } - - patch(spb, pc); - continpc = scc; - breakpc = sbc; - canreach = nbreak!=0; - if(canreach == 0) - warnreach = !suppress; - nbreak = snbreak; - ncontin = sncontin; - break; - - case OCONTINUE: - if(continpc < 0) { - diag(n, "continue not in a loop"); - break; - } - gbranch(OGOTO); - patch(p, continpc); - ncontin++; - canreach = 0; - warnreach = !suppress; - break; - - case OBREAK: - if(breakpc < 0) { - diag(n, "break not in a loop"); - break; - } - /* - * Don't complain about unreachable break statements. - * There are breaks hidden in yacc's output and some people - * write return; break; in their switch statements out of habit. - * However, don't confuse the analysis by inserting an - * unreachable reference to breakpc either. - */ - if(!canreach) - break; - gbranch(OGOTO); - patch(p, breakpc); - nbreak++; - canreach = 0; - warnreach = !suppress; - break; - - case OIF: - l = n->left; - if(bcomplex(l, n->right)) { - if(typefd[l->type->etype]) - f = !l->fconst; - else - f = !l->vconst; - if(debug['c']) - print("%L const if %s\n", nearln, f ? "false" : "true"); - if(f) { - canreach = 1; - supgen(n->right->left); - oldreach = canreach; - canreach = 1; - gen(n->right->right); - /* - * treat constant ifs as regular ifs for - * reachability warnings. - */ - if(!canreach && oldreach && debug['w'] < 2) - warnreach = 0; - } - else { - canreach = 1; - gen(n->right->left); - oldreach = canreach; - canreach = 1; - supgen(n->right->right); - /* - * treat constant ifs as regular ifs for - * reachability warnings. - */ - if(!oldreach && canreach && debug['w'] < 2) - warnreach = 0; - canreach = oldreach; - } - } - else { - sp = p; - canreach = 1; - if(n->right->left != Z) - gen(n->right->left); - oldreach = canreach; - canreach = 1; - if(n->right->right != Z) { - gbranch(OGOTO); - patch(sp, pc); - sp = p; - gen(n->right->right); - } - patch(sp, pc); - canreach = canreach || oldreach; - if(canreach == 0) - warnreach = !suppress; - } - break; - - case OSET: - case OUSED: - usedset(n->left, o); - break; - } -} - -void -usedset(Node *n, int o) -{ - if(n->op == OLIST) { - usedset(n->left, o); - usedset(n->right, o); - return; - } - complex(n); - switch(n->op) { - case OADDR: /* volatile */ - gins(ANOP, n, Z); - break; - case ONAME: - if(o == OSET) - gins(ANOP, Z, n); - else - gins(ANOP, n, Z); - break; - } -} - -int -bcomplex(Node *n, Node *c) -{ - Node *b, nod; - - complex(n); - if(n->type != T) - if(tcompat(n, T, n->type, tnot)) - n->type = T; - if(n->type == T) { - gbranch(OGOTO); - return 0; - } - if(c != Z && n->op == OCONST && deadheads(c)) - return 1; - if(typev[n->type->etype] && machcap(Z)) { - b = &nod; - b->op = ONE; - b->left = n; - b->right = new(0, Z, Z); - *b->right = *nodconst(0); - b->right->type = n->type; - b->type = types[TLONG]; - n = b; - } - bool64(n); - boolgen(n, 1, Z); - return 0; -} diff --git a/src/cmd/cc/pswt.c b/src/cmd/cc/pswt.c deleted file mode 100644 index 0e402dea7..000000000 --- a/src/cmd/cc/pswt.c +++ /dev/null @@ -1,168 +0,0 @@ -// Inferno utils/6c/swt.c -// http://code.google.com/p/inferno-os/source/browse/utils/6c/swt.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 "gc.h" - -int -swcmp(const void *a1, const void *a2) -{ - C1 *p1, *p2; - - p1 = (C1*)a1; - p2 = (C1*)a2; - if(p1->val < p2->val) - return -1; - return p1->val > p2->val; -} - -void -doswit(Node *n) -{ - Case *c; - C1 *q, *iq; - int32 def, nc, i, isv; - - def = 0; - nc = 0; - isv = 0; - for(c = cases; c->link != C; c = c->link) { - if(c->def) { - if(def) - diag(n, "more than one default in switch"); - def = c->label; - continue; - } - isv |= c->isv; - nc++; - } - if(isv && !typev[n->type->etype]) - warn(n, "32-bit switch expression with 64-bit case constant"); - - iq = alloc(nc*sizeof(C1)); - q = iq; - for(c = cases; c->link != C; c = c->link) { - if(c->def) - continue; - q->label = c->label; - if(isv) - q->val = c->val; - else - q->val = (int32)c->val; /* cast ensures correct value for 32-bit switch on 64-bit architecture */ - q++; - } - qsort(iq, nc, sizeof(C1), swcmp); - if(debug['W']) - for(i=0; i<nc; i++) - print("case %2d: = %.8llux\n", i, (vlong)iq[i].val); - for(i=0; i<nc-1; i++) - if(iq[i].val == iq[i+1].val) - diag(n, "duplicate cases in switch %lld", (vlong)iq[i].val); - if(def == 0) { - def = breakpc; - nbreak++; - } - swit1(iq, nc, def, n); -} - -void -cas(void) -{ - Case *c; - - c = alloc(sizeof(*c)); - c->link = cases; - cases = c; -} - -int32 -outlstring(ushort *s, int32 n) -{ - char buf[2]; - int c; - int32 r; - - if(suppress) - return nstring; - while(nstring & 1) - outstring("", 1); - r = nstring; - while(n > 0) { - c = *s++; - if(align(0, types[TCHAR], Aarg1, nil)) { - buf[0] = c>>8; - buf[1] = c; - } else { - buf[0] = c; - buf[1] = c>>8; - } - outstring(buf, 2); - n -= sizeof(ushort); - } - return r; -} - -void -nullwarn(Node *l, Node *r) -{ - warn(Z, "result of operation not used"); - if(l != Z) - cgen(l, Z); - if(r != Z) - cgen(r, Z); -} - -void -ieeedtod(Ieee *ieee, double native) -{ - double fr, ho, f; - int exp; - - if(native < 0) { - ieeedtod(ieee, -native); - ieee->h |= 0x80000000L; - return; - } - if(native == 0) { - ieee->l = 0; - ieee->h = 0; - return; - } - fr = frexp(native, &exp); - f = 2097152L; /* shouldnt use fp constants here */ - fr = modf(fr*f, &ho); - ieee->h = ho; - ieee->h &= 0xfffffL; - ieee->h |= (exp+1022L) << 20; - f = 65536L; - fr = modf(fr*f, &ho); - ieee->l = ho; - ieee->l <<= 16; - ieee->l |= (int32)(fr*f); -} diff --git a/src/cmd/cc/scon.c b/src/cmd/cc/scon.c deleted file mode 100644 index 193331f77..000000000 --- a/src/cmd/cc/scon.c +++ /dev/null @@ -1,637 +0,0 @@ -// Inferno utils/cc/scon.c -// http://code.google.com/p/inferno-os/source/browse/utils/cc/scon.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 Node* -acast(Type *t, Node *n) -{ - if(n->type->etype != t->etype || n->op == OBIT) { - n = new1(OCAST, n, Z); - if(nocast(n->left->type, t)) - *n = *n->left; - n->type = t; - } - return n; -} - - -void -evconst(Node *n) -{ - Node *l, *r; - int et, isf; - vlong v; - double d; - - if(n == Z || n->type == T) - return; - - et = n->type->etype; - isf = typefd[et]; - - l = n->left; - r = n->right; - - d = 0; - v = 0; - - switch(n->op) { - default: - return; - - case ONEG: - if(isf) - d = -l->fconst; - else - v = -l->vconst; - break; - - case OCOM: - v = ~l->vconst; - break; - - case OCAST: - if(et == TVOID) - return; - et = l->type->etype; - if(isf) { - if(typefd[et]) - d = l->fconst; - else - d = l->vconst; - } else { - if(typefd[et]) - v = l->fconst; - else - v = convvtox(l->vconst, n->type->etype); - } - break; - - case OCONST: - break; - - case OADD: - if(isf) - d = l->fconst + r->fconst; - else { - v = l->vconst + r->vconst; - } - break; - - case OSUB: - if(isf) - d = l->fconst - r->fconst; - else - v = l->vconst - r->vconst; - break; - - case OMUL: - if(isf) - d = l->fconst * r->fconst; - else { - v = l->vconst * r->vconst; - } - break; - - case OLMUL: - v = (uvlong)l->vconst * (uvlong)r->vconst; - break; - - - case ODIV: - if(vconst(r) == 0) { - warn(n, "divide by zero"); - return; - } - if(isf) - d = l->fconst / r->fconst; - else - v = l->vconst / r->vconst; - break; - - case OLDIV: - if(vconst(r) == 0) { - warn(n, "divide by zero"); - return; - } - v = (uvlong)l->vconst / (uvlong)r->vconst; - break; - - case OMOD: - if(vconst(r) == 0) { - warn(n, "modulo by zero"); - return; - } - v = l->vconst % r->vconst; - break; - - case OLMOD: - if(vconst(r) == 0) { - warn(n, "modulo by zero"); - return; - } - v = (uvlong)l->vconst % (uvlong)r->vconst; - break; - - case OAND: - v = l->vconst & r->vconst; - break; - - case OOR: - v = l->vconst | r->vconst; - break; - - case OXOR: - v = l->vconst ^ r->vconst; - break; - - case OLSHR: - v = (uvlong)l->vconst >> r->vconst; - break; - - case OASHR: - v = l->vconst >> r->vconst; - break; - - case OASHL: - v = l->vconst << r->vconst; - break; - - case OLO: - v = (uvlong)l->vconst < (uvlong)r->vconst; - break; - - case OLT: - if(typefd[l->type->etype]) - v = l->fconst < r->fconst; - else - v = l->vconst < r->vconst; - break; - - case OHI: - v = (uvlong)l->vconst > (uvlong)r->vconst; - break; - - case OGT: - if(typefd[l->type->etype]) - v = l->fconst > r->fconst; - else - v = l->vconst > r->vconst; - break; - - case OLS: - v = (uvlong)l->vconst <= (uvlong)r->vconst; - break; - - case OLE: - if(typefd[l->type->etype]) - v = l->fconst <= r->fconst; - else - v = l->vconst <= r->vconst; - break; - - case OHS: - v = (uvlong)l->vconst >= (uvlong)r->vconst; - break; - - case OGE: - if(typefd[l->type->etype]) - v = l->fconst >= r->fconst; - else - v = l->vconst >= r->vconst; - break; - - case OEQ: - if(typefd[l->type->etype]) - v = l->fconst == r->fconst; - else - v = l->vconst == r->vconst; - break; - - case ONE: - if(typefd[l->type->etype]) - v = l->fconst != r->fconst; - else - v = l->vconst != r->vconst; - break; - - case ONOT: - if(typefd[l->type->etype]) - v = !l->fconst; - else - v = !l->vconst; - break; - - case OANDAND: - if(typefd[l->type->etype]) - v = l->fconst && r->fconst; - else - v = l->vconst && r->vconst; - break; - - case OOROR: - if(typefd[l->type->etype]) - v = l->fconst || r->fconst; - else - v = l->vconst || r->vconst; - break; - } - if(isf) { - n->fconst = d; - } else { - n->vconst = convvtox(v, n->type->etype); - } - n->oldop = n->op; - n->op = OCONST; -} - -void -acom(Node *n) -{ - Type *t; - Node *l, *r; - int i; - - switch(n->op) - { - - case ONAME: - case OCONST: - case OSTRING: - case OINDREG: - case OREGISTER: - return; - - case ONEG: - l = n->left; - if(addo(n) && addo(l)) - break; - acom(l); - return; - - case OADD: - case OSUB: - case OMUL: - l = n->left; - r = n->right; - if(addo(n)) { - if(addo(r)) - break; - if(addo(l)) - break; - } - acom(l); - acom(r); - return; - - default: - l = n->left; - r = n->right; - if(l != Z) - acom(l); - if(r != Z) - acom(r); - return; - } - - /* bust terms out */ - t = n->type; - term[0].mult = 0; - term[0].node = Z; - nterm = 1; - acom1(1, n); - if(debug['m']) - for(i=0; i<nterm; i++) { - print("%d %3lld ", i, term[i].mult); - prtree1(term[i].node, 1, 0); - } - if(nterm < NTERM) - acom2(n, t); - n->type = t; -} - -int -acomcmp1(const void *a1, const void *a2) -{ - vlong c1, c2; - Term *t1, *t2; - - t1 = (Term*)a1; - t2 = (Term*)a2; - c1 = t1->mult; - if(c1 < 0) - c1 = -c1; - c2 = t2->mult; - if(c2 < 0) - c2 = -c2; - if(c1 > c2) - return 1; - if(c1 < c2) - return -1; - c1 = 1; - if(t1->mult < 0) - c1 = 0; - c2 = 1; - if(t2->mult < 0) - c2 = 0; - if(c2 -= c1) - return c2; - if(t2 > t1) - return 1; - return -1; -} - -int -acomcmp2(const void *a1, const void *a2) -{ - vlong c1, c2; - Term *t1, *t2; - - t1 = (Term*)a1; - t2 = (Term*)a2; - c1 = t1->mult; - c2 = t2->mult; - if(c1 > c2) - return 1; - if(c1 < c2) - return -1; - if(t2 > t1) - return 1; - return -1; -} - -void -acom2(Node *n, Type *t) -{ - Node *l, *r; - Term trm[NTERM]; - int et, nt, i, j; - vlong c1, c2; - - /* - * copy into automatic - */ - c2 = 0; - nt = nterm; - for(i=0; i<nt; i++) - trm[i] = term[i]; - /* - * recur on subtrees - */ - j = 0; - for(i=1; i<nt; i++) { - c1 = trm[i].mult; - if(c1 == 0) - continue; - l = trm[i].node; - if(l != Z) { - j = 1; - acom(l); - } - } - c1 = trm[0].mult; - if(j == 0) { - n->oldop = n->op; - n->op = OCONST; - n->vconst = c1; - return; - } - et = t->etype; - - /* - * prepare constant term, - * combine it with an addressing term - */ - if(c1 != 0) { - l = new1(OCONST, Z, Z); - l->type = t; - l->vconst = c1; - trm[0].mult = 1; - for(i=1; i<nt; i++) { - if(trm[i].mult != 1) - continue; - r = trm[i].node; - if(r->op != OADDR) - continue; - r->type = t; - l = new1(OADD, r, l); - l->type = t; - trm[i].mult = 0; - break; - } - trm[0].node = l; - } - /* - * look for factorable terms - * c1*i + c1*c2*j -> c1*(i + c2*j) - */ - qsort(trm+1, nt-1, sizeof(trm[0]), acomcmp1); - for(i=nt-1; i>=0; i--) { - c1 = trm[i].mult; - if(c1 < 0) - c1 = -c1; - if(c1 <= 1) - continue; - for(j=i+1; j<nt; j++) { - c2 = trm[j].mult; - if(c2 < 0) - c2 = -c2; - if(c2 <= 1) - continue; - if(c2 % c1) - continue; - r = trm[j].node; - if(r->type->etype != et) - r = acast(t, r); - c2 = trm[j].mult/trm[i].mult; - if(c2 != 1 && c2 != -1) { - r = new1(OMUL, r, new(OCONST, Z, Z)); - r->type = t; - r->right->type = t; - r->right->vconst = c2; - } - l = trm[i].node; - if(l->type->etype != et) - l = acast(t, l); - r = new1(OADD, l, r); - r->type = t; - if(c2 == -1) - r->op = OSUB; - trm[i].node = r; - trm[j].mult = 0; - } - } - if(debug['m']) { - print("\n"); - for(i=0; i<nt; i++) { - print("%d %3lld ", i, trm[i].mult); - prtree1(trm[i].node, 1, 0); - } - } - - /* - * put it all back together - */ - qsort(trm+1, nt-1, sizeof(trm[0]), acomcmp2); - l = Z; - for(i=nt-1; i>=0; i--) { - c1 = trm[i].mult; - if(c1 == 0) - continue; - r = trm[i].node; - if(r->type->etype != et || r->op == OBIT) - r = acast(t, r); - if(c1 != 1 && c1 != -1) { - r = new1(OMUL, r, new(OCONST, Z, Z)); - r->type = t; - r->right->type = t; - if(c1 < 0) { - r->right->vconst = -c1; - c1 = -1; - } else { - r->right->vconst = c1; - c1 = 1; - } - } - if(l == Z) { - l = r; - c2 = c1; - continue; - } - if(c1 < 0) - if(c2 < 0) - l = new1(OADD, l, r); - else - l = new1(OSUB, l, r); - else - if(c2 < 0) { - l = new1(OSUB, r, l); - c2 = 1; - } else - l = new1(OADD, l, r); - l->type = t; - } - if(c2 < 0) { - r = new1(OCONST, 0, 0); - r->vconst = 0; - r->type = t; - l = new1(OSUB, r, l); - l->type = t; - } - *n = *l; -} - -void -acom1(vlong v, Node *n) -{ - Node *l, *r; - - if(v == 0 || nterm >= NTERM) - return; - if(!addo(n)) { - if(n->op == OCONST) - if(!typefd[n->type->etype]) { - term[0].mult += v*n->vconst; - return; - } - term[nterm].mult = v; - term[nterm].node = n; - nterm++; - return; - } - switch(n->op) { - - case OCAST: - acom1(v, n->left); - break; - - case ONEG: - acom1(-v, n->left); - break; - - case OADD: - acom1(v, n->left); - acom1(v, n->right); - break; - - case OSUB: - acom1(v, n->left); - acom1(-v, n->right); - break; - - case OMUL: - l = n->left; - r = n->right; - if(l->op == OCONST) - if(!typefd[n->type->etype]) { - acom1(v*l->vconst, r); - break; - } - if(r->op == OCONST) - if(!typefd[n->type->etype]) { - acom1(v*r->vconst, l); - break; - } - break; - - default: - diag(n, "not addo"); - } -} - -int -addo(Node *n) -{ - - if(n != Z) - if(!typefd[n->type->etype]) - if(!typev[n->type->etype] || ewidth[TVLONG] == ewidth[TIND]) - switch(n->op) { - - case OCAST: - if(nilcast(n->left->type, n->type)) - return 1; - break; - - case ONEG: - case OADD: - case OSUB: - return 1; - - case OMUL: - if(n->left->op == OCONST) - return 1; - if(n->right->op == OCONST) - return 1; - } - return 0; -} diff --git a/src/cmd/cc/sub.c b/src/cmd/cc/sub.c deleted file mode 100644 index e5992e213..000000000 --- a/src/cmd/cc/sub.c +++ /dev/null @@ -1,2056 +0,0 @@ -// Inferno utils/cc/sub.c -// http://code.google.com/p/inferno-os/source/browse/utils/cc/sub.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" - -Node* -new(int t, Node *l, Node *r) -{ - Node *n; - - n = alloc(sizeof(*n)); - n->op = t; - n->left = l; - n->right = r; - if(l && t != OGOTO) - n->lineno = l->lineno; - else if(r) - n->lineno = r->lineno; - else - n->lineno = lineno; - newflag = 1; - return n; -} - -Node* -new1(int o, Node *l, Node *r) -{ - Node *n; - - n = new(o, l, r); - n->lineno = nearln; - return n; -} - -void -prtree(Node *n, char *s) -{ - - print(" == %s ==\n", s); - prtree1(n, 0, 0); - print("\n"); -} - -void -prtree1(Node *n, int d, int f) -{ - int i; - - if(f) - for(i=0; i<d; i++) - print(" "); - if(n == Z) { - print("Z\n"); - return; - } - if(n->op == OLIST) { - prtree1(n->left, d, 0); - prtree1(n->right, d, 1); - return; - } - d++; - print("%O", n->op); - i = 3; - switch(n->op) - { - case ONAME: - print(" \"%F\"", n); - print(" %d", n->xoffset); - i = 0; - break; - - case OINDREG: - print(" %d(R%d)", n->xoffset, n->reg); - i = 0; - break; - - case OREGISTER: - if(n->xoffset) - print(" %d+R%d", n->xoffset, n->reg); - else - print(" R%d", n->reg); - i = 0; - break; - - case OSTRING: - print(" \"%s\"", n->cstring); - i = 0; - break; - - case OLSTRING: - print(" \"%S\"", n->rstring); - i = 0; - break; - - case ODOT: - case OELEM: - print(" \"%F\"", n); - break; - - case OCONST: - if(typefd[n->type->etype]) - print(" \"%.8e\"", n->fconst); - else - print(" \"%lld\"", n->vconst); - i = 0; - break; - } - if(n->addable != 0) - print(" <%d>", n->addable); - if(n->type != T) - print(" %T", n->type); - if(n->complex != 0) - print(" (%d)", n->complex); - print(" %L\n", n->lineno); - if(i & 2) - prtree1(n->left, d, 1); - if(i & 1) - prtree1(n->right, d, 1); -} - -Type* -typ(int et, Type *d) -{ - Type *t; - - t = alloc(sizeof(*t)); - t->etype = et; - t->link = d; - t->down = T; - t->sym = S; - t->width = ewidth[et]; - t->offset = 0; - t->shift = 0; - t->nbits = 0; - t->garb = 0; - return t; -} - -Type* -copytyp(Type *t) -{ - Type *nt; - - nt = typ(TXXX, T); - *nt = *t; - return nt; -} - -Type* -garbt(Type *t, int32 b) -{ - Type *t1; - - if(b & BGARB) { - t1 = copytyp(t); - t1->garb = simpleg(b); - return t1; - } - return t; -} - -int -simpleg(int32 b) -{ - - b &= BGARB; - switch(b) { - case BCONSTNT: - return GCONSTNT; - case BVOLATILE: - return GVOLATILE; - case BVOLATILE|BCONSTNT: - return GCONSTNT|GVOLATILE; - } - return GXXX; -} - -int -simplec(int32 b) -{ - - b &= BCLASS; - switch(b) { - case 0: - case BREGISTER: - return CXXX; - case BAUTO: - case BAUTO|BREGISTER: - return CAUTO; - case BEXTERN: - return CEXTERN; - case BEXTERN|BREGISTER: - return CEXREG; - case BSTATIC: - return CSTATIC; - case BTYPEDEF: - return CTYPEDEF; - case BTYPESTR: - return CTYPESTR; - } - diag(Z, "illegal combination of classes %Q", b); - return CXXX; -} - -Type* -simplet(int32 b) -{ - - b &= ~BCLASS & ~BGARB; - switch(b) { - case BCHAR: - case BCHAR|BSIGNED: - return types[TCHAR]; - - case BCHAR|BUNSIGNED: - return types[TUCHAR]; - - case BSHORT: - case BSHORT|BINT: - case BSHORT|BSIGNED: - case BSHORT|BINT|BSIGNED: - return types[TSHORT]; - - case BUNSIGNED|BSHORT: - case BUNSIGNED|BSHORT|BINT: - return types[TUSHORT]; - - case 0: - case BINT: - case BINT|BSIGNED: - case BSIGNED: - return types[TINT]; - - case BUNSIGNED: - case BUNSIGNED|BINT: - return types[TUINT]; - - case BLONG: - case BLONG|BINT: - case BLONG|BSIGNED: - case BLONG|BINT|BSIGNED: - return types[TLONG]; - - case BUNSIGNED|BLONG: - case BUNSIGNED|BLONG|BINT: - return types[TULONG]; - - case BVLONG|BLONG: - case BVLONG|BLONG|BINT: - case BVLONG|BLONG|BSIGNED: - case BVLONG|BLONG|BINT|BSIGNED: - return types[TVLONG]; - - case BVLONG|BLONG|BUNSIGNED: - case BVLONG|BLONG|BINT|BUNSIGNED: - return types[TUVLONG]; - - case BFLOAT: - return types[TFLOAT]; - - case BDOUBLE: - case BDOUBLE|BLONG: - case BFLOAT|BLONG: - return types[TDOUBLE]; - - case BVOID: - return types[TVOID]; - } - - diag(Z, "illegal combination of types %Q", b); - return types[TINT]; -} - -int -stcompat(Node *n, Type *t1, Type *t2, int32 ttab[]) -{ - int i; - uint32 b; - - i = 0; - if(t2 != T) - i = t2->etype; - b = 1L << i; - i = 0; - if(t1 != T) - i = t1->etype; - if(b & ttab[i]) { - if(ttab == tasign) - if(b == BSTRUCT || b == BUNION) - if(!sametype(t1, t2)) - return 1; - if(n->op != OCAST) - if(b == BIND && i == TIND) - if(!sametype(t1, t2)) - return 1; - return 0; - } - return 1; -} - -int -tcompat(Node *n, Type *t1, Type *t2, int32 ttab[]) -{ - - if(stcompat(n, t1, t2, ttab)) { - if(t1 == T) - diag(n, "incompatible type: \"%T\" for op \"%O\"", - t2, n->op); - else - diag(n, "incompatible types: \"%T\" and \"%T\" for op \"%O\"", - t1, t2, n->op); - return 1; - } - return 0; -} - -void -makedot(Node *n, Type *t, int32 o) -{ - Node *n1, *n2; - - if(t->nbits) { - n1 = new(OXXX, Z, Z); - *n1 = *n; - n->op = OBIT; - n->left = n1; - n->right = Z; - n->type = t; - n->addable = n1->left->addable; - n = n1; - } - n->addable = n->left->addable; - if(n->addable == 0) { - n1 = new1(OCONST, Z, Z); - n1->vconst = o; - n1->type = types[TLONG]; - n->right = n1; - n->type = t; - return; - } - n->left->type = t; - if(o == 0) { - *n = *n->left; - return; - } - n->type = t; - n1 = new1(OCONST, Z, Z); - n1->vconst = o; - t = typ(TIND, t); - t->width = types[TIND]->width; - n1->type = t; - - n2 = new1(OADDR, n->left, Z); - n2->type = t; - - n1 = new1(OADD, n1, n2); - n1->type = t; - - n->op = OIND; - n->left = n1; - n->right = Z; -} - -Type* -dotsearch(Sym *s, Type *t, Node *n, int32 *off) -{ - Type *t1, *xt, *rt; - - xt = T; - - /* - * look it up by name - */ - for(t1 = t; t1 != T; t1 = t1->down) - if(t1->sym == s) { - if(xt != T) - goto ambig; - xt = t1; - } - - /* - * look it up by type - */ - if(s->class == CTYPEDEF || s->class == CTYPESTR) - for(t1 = t; t1 != T; t1 = t1->down) - if(t1->sym == S && typesu[t1->etype]) - if(sametype(s->type, t1)) { - if(xt != T) - goto ambig; - xt = t1; - } - if(xt != T) { - *off = xt->offset; - return xt; - } - - /* - * look it up in unnamed substructures - */ - for(t1 = t; t1 != T; t1 = t1->down) - if(t1->sym == S && typesu[t1->etype]){ - rt = dotsearch(s, t1->link, n, off); - if(rt != T) { - if(xt != T) - goto ambig; - xt = rt; - *off += t1->offset; - } - } - return xt; - -ambig: - diag(n, "ambiguous structure element: %s", s->name); - return xt; -} - -int32 -dotoffset(Type *st, Type *lt, Node *n) -{ - Type *t; - Sym *g; - int32 o, o1; - - o = -1; - /* - * first try matching at the top level - * for matching tag names - */ - g = st->tag; - if(g != S) - for(t=lt->link; t!=T; t=t->down) - if(t->sym == S) - if(g == t->tag) { - if(o >= 0) - goto ambig; - o = t->offset; - } - if(o >= 0) - return o; - - /* - * second try matching at the top level - * for similar types - */ - for(t=lt->link; t!=T; t=t->down) - if(t->sym == S) - if(sametype(st, t)) { - if(o >= 0) - goto ambig; - o = t->offset; - } - if(o >= 0) - return o; - - /* - * last try matching sub-levels - */ - for(t=lt->link; t!=T; t=t->down) - if(t->sym == S) - if(typesu[t->etype]) { - o1 = dotoffset(st, t, n); - if(o1 >= 0) { - if(o >= 0) - goto ambig; - o = o1 + t->offset; - } - } - return o; - -ambig: - diag(n, "ambiguous unnamed structure element"); - return o; -} - -/* - * look into tree for floating point constant expressions - */ -int -allfloat(Node *n, int flag) -{ - - if(n != Z) { - if(n->type->etype != TDOUBLE) - return 1; - switch(n->op) { - case OCONST: - if(flag) - n->type = types[TFLOAT]; - return 1; - case OADD: /* no need to get more exotic than this */ - case OSUB: - case OMUL: - case ODIV: - if(!allfloat(n->right, flag)) - break; - case OCAST: - if(!allfloat(n->left, flag)) - break; - if(flag) - n->type = types[TFLOAT]; - return 1; - } - } - return 0; -} - -void -constas(Node *n, Type *il, Type *ir) -{ - Type *l, *r; - - l = il; - r = ir; - - if(l == T) - return; - if(l->garb & GCONSTNT) { - warn(n, "assignment to a constant type (%T)", il); - return; - } - if(r == T) - return; - for(;;) { - if(l->etype != TIND || r->etype != TIND) - break; - l = l->link; - r = r->link; - if(l == T || r == T) - break; - if(r->garb & GCONSTNT) - if(!(l->garb & GCONSTNT)) { - warn(n, "assignment of a constant pointer type (%T)", ir); - break; - } - } -} - -void -typeext1(Type *st, Node *l) -{ - if(st->etype == TFLOAT && allfloat(l, 0)) - allfloat(l, 1); -} - -void -typeext(Type *st, Node *l) -{ - Type *lt; - Node *n1, *n2; - int32 o; - - lt = l->type; - if(lt == T) - return; - if(st->etype == TIND && vconst(l) == 0) { - l->type = st; - l->vconst = 0; - return; - } - typeext1(st, l); - - /* - * extension of C - * if assign of struct containing unnamed sub-struct - * to type of sub-struct, insert the DOT. - * if assign of *struct containing unnamed substruct - * to type of *sub-struct, insert the add-offset - */ - if(typesu[st->etype] && typesu[lt->etype]) { - o = dotoffset(st, lt, l); - if(o >= 0) { - n1 = new1(OXXX, Z, Z); - *n1 = *l; - l->op = ODOT; - l->left = n1; - l->right = Z; - makedot(l, st, o); - } - return; - } - if(st->etype == TIND && typesu[st->link->etype]) - if(lt->etype == TIND && typesu[lt->link->etype]) { - o = dotoffset(st->link, lt->link, l); - if(o >= 0) { - l->type = st; - if(o == 0) - return; - n1 = new1(OXXX, Z, Z); - *n1 = *l; - n2 = new1(OCONST, Z, Z); - n2->vconst = o; - n2->type = st; - l->op = OADD; - l->left = n1; - l->right = n2; - } - return; - } -} - -/* - * a cast that generates no code - * (same size move) - */ -int -nocast(Type *t1, Type *t2) -{ - int i, b; - - if(t1->nbits) - return 0; - i = 0; - if(t2 != T) - i = t2->etype; - b = 1<<i; - i = 0; - if(t1 != T) - i = t1->etype; - if(b & ncast[i]) - return 1; - return 0; -} - -/* - * a cast that has a noop semantic - * (small to large, convert) - */ -int -nilcast(Type *t1, Type *t2) -{ - int et1, et2; - - if(t1 == T) - return 0; - if(t1->nbits) - return 0; - if(t2 == T) - return 0; - et1 = t1->etype; - et2 = t2->etype; - if(et1 == et2) - return 1; - if(typefd[et1] && typefd[et2]) { - if(ewidth[et1] < ewidth[et2]) - return 1; - return 0; - } - if(typechlp[et1] && typechlp[et2]) { - if(ewidth[et1] < ewidth[et2]) - return 1; - return 0; - } - return 0; -} - -/* - * "the usual arithmetic conversions are performed" - */ -void -arith(Node *n, int f) -{ - Type *t1, *t2; - int i, j, k; - Node *n1; - int32 w; - - t1 = n->left->type; - if(n->right == Z) - t2 = t1; - else - t2 = n->right->type; - i = TXXX; - if(t1 != T) - i = t1->etype; - j = TXXX; - if(t2 != T) - j = t2->etype; - k = tab[i][j]; - if(k == TIND) { - if(i == TIND) - n->type = t1; - else - if(j == TIND) - n->type = t2; - } else { - /* convert up to at least int */ - if(f == 1) - while(k < TINT) - k += 2; - n->type = types[k]; - } - if(n->op == OSUB) - if(i == TIND && j == TIND) { - w = n->right->type->link->width; - if(w < 1 || n->left->type->link == T || n->left->type->link->width < 1) - goto bad; - n->type = types[ewidth[TIND] <= ewidth[TLONG]? TLONG: TVLONG]; - if(0 && ewidth[TIND] > ewidth[TLONG]){ - n1 = new1(OXXX, Z, Z); - *n1 = *n; - n->op = OCAST; - n->left = n1; - n->right = Z; - n->type = types[TLONG]; - } - if(w > 1) { - n1 = new1(OXXX, Z, Z); - *n1 = *n; - n->op = ODIV; - n->left = n1; - n1 = new1(OCONST, Z, Z); - n1->vconst = w; - n1->type = n->type; - n->right = n1; - w = vlog(n1); - if(w >= 0) { - n->op = OASHR; - n1->vconst = w; - } - } - return; - } - if(!sametype(n->type, n->left->type)) { - n->left = new1(OCAST, n->left, Z); - n->left->type = n->type; - if(n->type->etype == TIND) { - w = n->type->link->width; - if(w < 1) { - snap(n->type->link); - w = n->type->link->width; - if(w < 1) - goto bad; - } - if(w > 1) { - n1 = new1(OCONST, Z, Z); - n1->vconst = w; - n1->type = n->type; - n->left = new1(OMUL, n->left, n1); - n->left->type = n->type; - } - } - } - if(n->right != Z) - if(!sametype(n->type, n->right->type)) { - n->right = new1(OCAST, n->right, Z); - n->right->type = n->type; - if(n->type->etype == TIND) { - w = n->type->link->width; - if(w < 1) { - snap(n->type->link); - w = n->type->link->width; - if(w < 1) - goto bad; - } - if(w != 1) { - n1 = new1(OCONST, Z, Z); - n1->vconst = w; - n1->type = n->type; - n->right = new1(OMUL, n->right, n1); - n->right->type = n->type; - } - } - } - return; -bad: - diag(n, "pointer addition not fully declared: %T", n->type->link); -} - -/* - * try to rewrite shift & mask - */ -void -simplifyshift(Node *n) -{ - uint32 c3; - int o, s1, s2, c1, c2; - - if(!typechlp[n->type->etype]) - return; - switch(n->op) { - default: - return; - case OASHL: - s1 = 0; - break; - case OLSHR: - s1 = 1; - break; - case OASHR: - s1 = 2; - break; - } - if(n->right->op != OCONST) - return; - if(n->left->op != OAND) - return; - if(n->left->right->op != OCONST) - return; - switch(n->left->left->op) { - default: - return; - case OASHL: - s2 = 0; - break; - case OLSHR: - s2 = 1; - break; - case OASHR: - s2 = 2; - break; - } - if(n->left->left->right->op != OCONST) - return; - - c1 = n->right->vconst; - c2 = n->left->left->right->vconst; - c3 = n->left->right->vconst; - -/* - if(debug['h']) - print("%.3o %d %d %d #%.ux\n", - (s1<<3)|s2, c1, c2, topbit(c3), c3); -*/ - - o = n->op; - switch((s1<<3)|s2) { - case 000: /* (((e <<u c2) & c3) <<u c1) */ - c3 >>= c2; - c1 += c2; - if(c1 >= 32) - break; - goto rewrite1; - - case 002: /* (((e >>s c2) & c3) <<u c1) */ - if(topbit(c3) >= (32-c2)) - break; - case 001: /* (((e >>u c2) & c3) <<u c1) */ - if(c1 > c2) { - c3 <<= c2; - c1 -= c2; - o = OASHL; - goto rewrite1; - } - c3 <<= c1; - if(c1 == c2) - goto rewrite0; - c1 = c2-c1; - o = OLSHR; - goto rewrite2; - - case 022: /* (((e >>s c2) & c3) >>s c1) */ - if(c2 <= 0) - break; - case 012: /* (((e >>s c2) & c3) >>u c1) */ - if(topbit(c3) >= (32-c2)) - break; - goto s11; - case 021: /* (((e >>u c2) & c3) >>s c1) */ - if(topbit(c3) >= 31 && c2 <= 0) - break; - goto s11; - case 011: /* (((e >>u c2) & c3) >>u c1) */ - s11: - c3 <<= c2; - c1 += c2; - if(c1 >= 32) - break; - o = OLSHR; - goto rewrite1; - - case 020: /* (((e <<u c2) & c3) >>s c1) */ - if(topbit(c3) >= 31) - break; - case 010: /* (((e <<u c2) & c3) >>u c1) */ - c3 >>= c1; - if(c1 == c2) - goto rewrite0; - if(c1 > c2) { - c1 -= c2; - goto rewrite2; - } - c1 = c2 - c1; - o = OASHL; - goto rewrite2; - } - return; - -rewrite0: /* get rid of both shifts */ -if(debug['<'])prtree(n, "rewrite0"); - *n = *n->left; - n->left = n->left->left; - n->right->vconst = c3; - return; -rewrite1: /* get rid of lower shift */ -if(debug['<'])prtree(n, "rewrite1"); - n->left->left = n->left->left->left; - n->left->right->vconst = c3; - n->right->vconst = c1; - n->op = o; - return; -rewrite2: /* get rid of upper shift */ -if(debug['<'])prtree(n, "rewrite2"); - *n = *n->left; - n->right->vconst = c3; - n->left->right->vconst = c1; - n->left->op = o; -} - -int -side(Node *n) -{ - -loop: - if(n != Z) - switch(n->op) { - case OCAST: - case ONOT: - case OADDR: - case OIND: - n = n->left; - goto loop; - - case OCOND: - if(side(n->left)) - break; - n = n->right; - - case OEQ: - case ONE: - case OLT: - case OGE: - case OGT: - case OLE: - case OADD: - case OSUB: - case OMUL: - case OLMUL: - case ODIV: - case OLDIV: - case OLSHR: - case OASHL: - case OASHR: - case OAND: - case OOR: - case OXOR: - case OMOD: - case OLMOD: - case OANDAND: - case OOROR: - case OCOMMA: - case ODOT: - if(side(n->left)) - break; - n = n->right; - goto loop; - - case OSIGN: - case OSIZE: - case OCONST: - case OSTRING: - case OLSTRING: - case ONAME: - return 0; - } - return 1; -} - -int -vconst(Node *n) -{ - int i; - - if(n == Z) - goto no; - if(n->op != OCONST) - goto no; - if(n->type == T) - goto no; - switch(n->type->etype) - { - case TFLOAT: - case TDOUBLE: - i = 100; - if(n->fconst > i || n->fconst < -i) - goto no; - i = n->fconst; - if(i != n->fconst) - goto no; - return i; - - case TVLONG: - case TUVLONG: - i = n->vconst; - if(i != n->vconst) - goto no; - return i; - - case TCHAR: - case TUCHAR: - case TSHORT: - case TUSHORT: - case TINT: - case TUINT: - case TLONG: - case TULONG: - case TIND: - i = n->vconst; - if(i != n->vconst) - goto no; - return i; - } -no: - return -159; /* first uninteresting constant */ -} - -/* - * return log(n) if n is a power of 2 constant - */ -int -xlog2(uvlong v) -{ - int s, i; - uvlong m; - - s = 0; - m = MASK(8*sizeof(uvlong)); - for(i=32; i; i>>=1) { - m >>= i; - if(!(v & m)) { - v >>= i; - s += i; - } - } - if(v == 1) - return s; - return -1; -} - -int -vlog(Node *n) -{ - if(n->op != OCONST) - goto bad; - if(typefd[n->type->etype]) - goto bad; - - return xlog2(n->vconst); - -bad: - return -1; -} - -int -topbit(uint32 v) -{ - int i; - - for(i = -1; v; i++) - v >>= 1; - return i; -} - -/* - * try to cast a constant down - * rather than cast a variable up - * example: - * if(c == 'a') - */ -void -relcon(Node *l, Node *r) -{ - vlong v; - - if(l->op != OCONST) - return; - if(r->op != OCAST) - return; - if(!nilcast(r->left->type, r->type)) - return; - switch(r->type->etype) { - default: - return; - case TCHAR: - case TUCHAR: - case TSHORT: - case TUSHORT: - v = convvtox(l->vconst, r->type->etype); - if(v != l->vconst) - return; - break; - } - l->type = r->left->type; - *r = *r->left; -} - -int -relindex(int o) -{ - - switch(o) { - default: - diag(Z, "bad in relindex: %O", o); - case OEQ: return 0; - case ONE: return 1; - case OLE: return 2; - case OLS: return 3; - case OLT: return 4; - case OLO: return 5; - case OGE: return 6; - case OHS: return 7; - case OGT: return 8; - case OHI: return 9; - } -} - -Node* -invert(Node *n) -{ - Node *i; - - if(n == Z || n->op != OLIST) - return n; - i = n; - for(n = n->left; n != Z; n = n->left) { - if(n->op != OLIST) - break; - i->left = n->right; - n->right = i; - i = n; - } - i->left = n; - return i; -} - -int -bitno(int32 b) -{ - int i; - - for(i=0; i<32; i++) - if(b & (1L<<i)) - return i; - diag(Z, "bad in bitno"); - return 0; -} - -int32 -typebitor(int32 a, int32 b) -{ - int32 c; - - c = a | b; - if(a & b) - if((a & b) == BLONG) - c |= BVLONG; /* long long => vlong */ - else - warn(Z, "once is enough: %Q", a & b); - return c; -} - -void -diag(Node *n, char *fmt, ...) -{ - char buf[STRINGSZ]; - va_list arg; - - va_start(arg, fmt); - vseprint(buf, buf+sizeof(buf), fmt, arg); - va_end(arg); - Bprint(&diagbuf, "%L %s\n", (n==Z)? nearln: n->lineno, buf); - - if(debug['X']){ - Bflush(&diagbuf); - abort(); - } - if(n != Z) - if(debug['v']) - prtree(n, "diagnostic"); - - nerrors++; - if(nerrors > 10) { - Bprint(&diagbuf, "too many errors\n"); - errorexit(); - } -} - -void -warn(Node *n, char *fmt, ...) -{ - char buf[STRINGSZ]; - va_list arg; - - if(debug['w']) { - Bprint(&diagbuf, "warning: "); - va_start(arg, fmt); - vseprint(buf, buf+sizeof(buf), fmt, arg); - va_end(arg); - Bprint(&diagbuf, "%L %s\n", (n==Z)? nearln: n->lineno, buf); - - if(n != Z) - if(debug['v']) - prtree(n, "warning"); - } -} - -void -yyerror(char *fmt, ...) -{ - char buf[STRINGSZ]; - va_list arg; - - /* - * hack to intercept message from yaccpar - */ - if(strcmp(fmt, "syntax error") == 0) { - yyerror("syntax error, last name: %s", symb); - return; - } - va_start(arg, fmt); - vseprint(buf, buf+sizeof(buf), fmt, arg); - va_end(arg); - Bprint(&diagbuf, "%L %s\n", lineno, buf); - nerrors++; - if(nerrors > 10) { - Bprint(&diagbuf, "too many errors\n"); - errorexit(); - } -} - -void -fatal(Node *n, char *fmt, ...) -{ - char buf[STRINGSZ]; - va_list arg; - - va_start(arg, fmt); - vseprint(buf, buf+sizeof(buf), fmt, arg); - va_end(arg); - Bprint(&diagbuf, "%L %s\n", (n==Z)? nearln: n->lineno, buf); - - if(debug['X']){ - Bflush(&diagbuf); - abort(); - } - if(n != Z) - if(debug['v']) - prtree(n, "diagnostic"); - - nerrors++; - errorexit(); -} - -uint32 thash1 = 0x2edab8c9; -uint32 thash2 = 0x1dc74fb8; -uint32 thash3 = 0x1f241331; -uint32 thash[NALLTYPES]; -Init thashinit[] = -{ - TXXX, 0x17527bbd, 0, - TCHAR, 0x5cedd32b, 0, - TUCHAR, 0x552c4454, 0, - TSHORT, 0x63040b4b, 0, - TUSHORT, 0x32a45878, 0, - TINT, 0x4151d5bd, 0, - TUINT, 0x5ae707d6, 0, - TLONG, 0x5ef20f47, 0, - TULONG, 0x36d8eb8f, 0, - TVLONG, 0x6e5e9590, 0, - TUVLONG, 0x75910105, 0, - TFLOAT, 0x25fd7af1, 0, - TDOUBLE, 0x7c40a1b2, 0, - TIND, 0x1b832357, 0, - TFUNC, 0x6babc9cb, 0, - TARRAY, 0x7c50986d, 0, - TVOID, 0x44112eff, 0, - TSTRUCT, 0x7c2da3bf, 0, - TUNION, 0x3eb25e98, 0, - TENUM, 0x44b54f61, 0, - TFILE, 0x19242ac3, 0, - TOLD, 0x22b15988, 0, - TDOT, 0x0204f6b3, 0, - -1, 0, 0, -}; - -char* bnames[NALIGN]; -Init bnamesinit[] = -{ - Axxx, 0, "Axxx", - Ael1, 0, "el1", - Ael2, 0, "el2", - Asu2, 0, "su2", - Aarg0, 0, "arg0", - Aarg1, 0, "arg1", - Aarg2, 0, "arg2", - Aaut3, 0, "aut3", - -1, 0, 0, -}; - -char* tnames[NALLTYPES]; -Init tnamesinit[] = -{ - TXXX, 0, "TXXX", - TCHAR, 0, "CHAR", - TUCHAR, 0, "UCHAR", - TSHORT, 0, "SHORT", - TUSHORT, 0, "USHORT", - TINT, 0, "INT", - TUINT, 0, "UINT", - TLONG, 0, "LONG", - TULONG, 0, "ULONG", - TVLONG, 0, "VLONG", - TUVLONG, 0, "UVLONG", - TFLOAT, 0, "FLOAT", - TDOUBLE, 0, "DOUBLE", - TIND, 0, "IND", - TFUNC, 0, "FUNC", - TARRAY, 0, "ARRAY", - TVOID, 0, "VOID", - TSTRUCT, 0, "STRUCT", - TUNION, 0, "UNION", - TENUM, 0, "ENUM", - TFILE, 0, "FILE", - TOLD, 0, "OLD", - TDOT, 0, "DOT", - -1, 0, 0, -}; - -char* gnames[NGTYPES]; -Init gnamesinit[] = -{ - GXXX, 0, "GXXX", - GCONSTNT, 0, "CONST", - GVOLATILE, 0, "VOLATILE", - GVOLATILE|GCONSTNT, 0, "CONST-VOLATILE", - -1, 0, 0, -}; - -char* qnames[NALLTYPES]; -Init qnamesinit[] = -{ - TXXX, 0, "TXXX", - TCHAR, 0, "CHAR", - TUCHAR, 0, "UCHAR", - TSHORT, 0, "SHORT", - TUSHORT, 0, "USHORT", - TINT, 0, "INT", - TUINT, 0, "UINT", - TLONG, 0, "LONG", - TULONG, 0, "ULONG", - TVLONG, 0, "VLONG", - TUVLONG, 0, "UVLONG", - TFLOAT, 0, "FLOAT", - TDOUBLE, 0, "DOUBLE", - TIND, 0, "IND", - TFUNC, 0, "FUNC", - TARRAY, 0, "ARRAY", - TVOID, 0, "VOID", - TSTRUCT, 0, "STRUCT", - TUNION, 0, "UNION", - TENUM, 0, "ENUM", - - TAUTO, 0, "AUTO", - TEXTERN, 0, "EXTERN", - TSTATIC, 0, "STATIC", - TTYPEDEF, 0, "TYPEDEF", - TTYPESTR, 0, "TYPESTR", - TREGISTER, 0, "REGISTER", - TCONSTNT, 0, "CONSTNT", - TVOLATILE, 0, "VOLATILE", - TUNSIGNED, 0, "UNSIGNED", - TSIGNED, 0, "SIGNED", - TDOT, 0, "DOT", - TFILE, 0, "FILE", - TOLD, 0, "OLD", - -1, 0, 0, -}; -char* cnames[NCTYPES]; -Init cnamesinit[] = -{ - CXXX, 0, "CXXX", - CAUTO, 0, "AUTO", - CEXTERN, 0, "EXTERN", - CGLOBL, 0, "GLOBL", - CSTATIC, 0, "STATIC", - CLOCAL, 0, "LOCAL", - CTYPEDEF, 0, "TYPEDEF", - CTYPESTR, 0, "TYPESTR", - CPARAM, 0, "PARAM", - CSELEM, 0, "SELEM", - CLABEL, 0, "LABEL", - CEXREG, 0, "EXREG", - -1, 0, 0, -}; - -char* onames[OEND+1]; -Init onamesinit[] = -{ - OXXX, 0, "OXXX", - OADD, 0, "ADD", - OADDR, 0, "ADDR", - OAND, 0, "AND", - OANDAND, 0, "ANDAND", - OARRAY, 0, "ARRAY", - OAS, 0, "AS", - OASI, 0, "ASI", - OASADD, 0, "ASADD", - OASAND, 0, "ASAND", - OASASHL, 0, "ASASHL", - OASASHR, 0, "ASASHR", - OASDIV, 0, "ASDIV", - OASHL, 0, "ASHL", - OASHR, 0, "ASHR", - OASLDIV, 0, "ASLDIV", - OASLMOD, 0, "ASLMOD", - OASLMUL, 0, "ASLMUL", - OASLSHR, 0, "ASLSHR", - OASMOD, 0, "ASMOD", - OASMUL, 0, "ASMUL", - OASOR, 0, "ASOR", - OASSUB, 0, "ASSUB", - OASXOR, 0, "ASXOR", - OBIT, 0, "BIT", - OBREAK, 0, "BREAK", - OCASE, 0, "CASE", - OCAST, 0, "CAST", - OCOMMA, 0, "COMMA", - OCOND, 0, "COND", - OCONST, 0, "CONST", - OCONTINUE, 0, "CONTINUE", - ODIV, 0, "DIV", - ODOT, 0, "DOT", - ODOTDOT, 0, "DOTDOT", - ODWHILE, 0, "DWHILE", - OENUM, 0, "ENUM", - OEQ, 0, "EQ", - OEXREG, 0, "EXREG", - OFOR, 0, "FOR", - OFUNC, 0, "FUNC", - OGE, 0, "GE", - OGOTO, 0, "GOTO", - OGT, 0, "GT", - OHI, 0, "HI", - OHS, 0, "HS", - OIF, 0, "IF", - OIND, 0, "IND", - OINDREG, 0, "INDREG", - OINIT, 0, "INIT", - OLABEL, 0, "LABEL", - OLDIV, 0, "LDIV", - OLE, 0, "LE", - OLIST, 0, "LIST", - OLMOD, 0, "LMOD", - OLMUL, 0, "LMUL", - OLO, 0, "LO", - OLS, 0, "LS", - OLSHR, 0, "LSHR", - OLT, 0, "LT", - OMOD, 0, "MOD", - OMUL, 0, "MUL", - ONAME, 0, "NAME", - ONE, 0, "NE", - ONOT, 0, "NOT", - OOR, 0, "OR", - OOROR, 0, "OROR", - OPOSTDEC, 0, "POSTDEC", - OPOSTINC, 0, "POSTINC", - OPREDEC, 0, "PREDEC", - OPREINC, 0, "PREINC", - OPROTO, 0, "PROTO", - OREGISTER, 0, "REGISTER", - ORETURN, 0, "RETURN", - OSET, 0, "SET", - OSIGN, 0, "SIGN", - OSIZE, 0, "SIZE", - OSTRING, 0, "STRING", - OLSTRING, 0, "LSTRING", - OSTRUCT, 0, "STRUCT", - OSUB, 0, "SUB", - OSWITCH, 0, "SWITCH", - OUNION, 0, "UNION", - OUSED, 0, "USED", - OWHILE, 0, "WHILE", - OXOR, 0, "XOR", - OPOS, 0, "POS", - ONEG, 0, "NEG", - OCOM, 0, "COM", - OELEM, 0, "ELEM", - OTST, 0, "TST", - OINDEX, 0, "INDEX", - OFAS, 0, "FAS", - OREGPAIR, 0, "REGPAIR", - OEND, 0, "END", - -1, 0, 0, -}; - -/* OEQ, ONE, OLE, OLS, OLT, OLO, OGE, OHS, OGT, OHI */ -uchar comrel[12] = -{ - ONE, OEQ, OGT, OHI, OGE, OHS, OLT, OLO, OLE, OLS, -}; -uchar invrel[12] = -{ - OEQ, ONE, OGE, OHS, OGT, OHI, OLE, OLS, OLT, OLO, -}; -uchar logrel[12] = -{ - OEQ, ONE, OLS, OLS, OLO, OLO, OHS, OHS, OHI, OHI, -}; - -uchar typei[NTYPE]; -int typeiinit[] = -{ - TCHAR, TUCHAR, TSHORT, TUSHORT, TINT, TUINT, TLONG, TULONG, TVLONG, TUVLONG, -1, -}; -uchar typeu[NTYPE]; -int typeuinit[] = -{ - TUCHAR, TUSHORT, TUINT, TULONG, TUVLONG, TIND, -1, -}; - -uchar typesuv[NTYPE]; -int typesuvinit[] = -{ - TVLONG, TUVLONG, TSTRUCT, TUNION, -1, -}; - -uchar typeilp[NTYPE]; -int typeilpinit[] = -{ - TINT, TUINT, TLONG, TULONG, TIND, -1 -}; - -uchar typechl[NTYPE]; -uchar typechlv[NTYPE]; -uchar typechlvp[NTYPE]; -int typechlinit[] = -{ - TCHAR, TUCHAR, TSHORT, TUSHORT, TINT, TUINT, TLONG, TULONG, -1, -}; - -uchar typechlp[NTYPE]; -int typechlpinit[] = -{ - TCHAR, TUCHAR, TSHORT, TUSHORT, TINT, TUINT, TLONG, TULONG, TIND, -1, -}; - -uchar typechlpfd[NTYPE]; -int typechlpfdinit[] = -{ - TCHAR, TUCHAR, TSHORT, TUSHORT, TINT, TUINT, TLONG, TULONG, TFLOAT, TDOUBLE, TIND, -1, -}; - -uchar typec[NTYPE]; -int typecinit[] = -{ - TCHAR, TUCHAR, -1 -}; - -uchar typeh[NTYPE]; -int typehinit[] = -{ - TSHORT, TUSHORT, -1, -}; - -uchar typeil[NTYPE]; -int typeilinit[] = -{ - TINT, TUINT, TLONG, TULONG, -1, -}; - -uchar typev[NTYPE]; -int typevinit[] = -{ - TVLONG, TUVLONG, -1, -}; - -uchar typefd[NTYPE]; -int typefdinit[] = -{ - TFLOAT, TDOUBLE, -1, -}; - -uchar typeaf[NTYPE]; -int typeafinit[] = -{ - TFUNC, TARRAY, -1, -}; - -uchar typesu[NTYPE]; -int typesuinit[] = -{ - TSTRUCT, TUNION, -1, -}; - -int32 tasign[NTYPE]; -Init tasigninit[] = -{ - TCHAR, BNUMBER, 0, - TUCHAR, BNUMBER, 0, - TSHORT, BNUMBER, 0, - TUSHORT, BNUMBER, 0, - TINT, BNUMBER, 0, - TUINT, BNUMBER, 0, - TLONG, BNUMBER, 0, - TULONG, BNUMBER, 0, - TVLONG, BNUMBER, 0, - TUVLONG, BNUMBER, 0, - TFLOAT, BNUMBER, 0, - TDOUBLE, BNUMBER, 0, - TIND, BIND, 0, - TSTRUCT, BSTRUCT, 0, - TUNION, BUNION, 0, - -1, 0, 0, -}; - -int32 tasadd[NTYPE]; -Init tasaddinit[] = -{ - TCHAR, BNUMBER, 0, - TUCHAR, BNUMBER, 0, - TSHORT, BNUMBER, 0, - TUSHORT, BNUMBER, 0, - TINT, BNUMBER, 0, - TUINT, BNUMBER, 0, - TLONG, BNUMBER, 0, - TULONG, BNUMBER, 0, - TVLONG, BNUMBER, 0, - TUVLONG, BNUMBER, 0, - TFLOAT, BNUMBER, 0, - TDOUBLE, BNUMBER, 0, - TIND, BINTEGER, 0, - -1, 0, 0, -}; - -int32 tcast[NTYPE]; -Init tcastinit[] = -{ - TCHAR, BNUMBER|BIND|BVOID, 0, - TUCHAR, BNUMBER|BIND|BVOID, 0, - TSHORT, BNUMBER|BIND|BVOID, 0, - TUSHORT, BNUMBER|BIND|BVOID, 0, - TINT, BNUMBER|BIND|BVOID, 0, - TUINT, BNUMBER|BIND|BVOID, 0, - TLONG, BNUMBER|BIND|BVOID, 0, - TULONG, BNUMBER|BIND|BVOID, 0, - TVLONG, BNUMBER|BIND|BVOID, 0, - TUVLONG, BNUMBER|BIND|BVOID, 0, - TFLOAT, BNUMBER|BVOID, 0, - TDOUBLE, BNUMBER|BVOID, 0, - TIND, BINTEGER|BIND|BVOID, 0, - TVOID, BVOID, 0, - TSTRUCT, BSTRUCT|BVOID, 0, - TUNION, BUNION|BVOID, 0, - -1, 0, 0, -}; - -int32 tadd[NTYPE]; -Init taddinit[] = -{ - TCHAR, BNUMBER|BIND, 0, - TUCHAR, BNUMBER|BIND, 0, - TSHORT, BNUMBER|BIND, 0, - TUSHORT, BNUMBER|BIND, 0, - TINT, BNUMBER|BIND, 0, - TUINT, BNUMBER|BIND, 0, - TLONG, BNUMBER|BIND, 0, - TULONG, BNUMBER|BIND, 0, - TVLONG, BNUMBER|BIND, 0, - TUVLONG, BNUMBER|BIND, 0, - TFLOAT, BNUMBER, 0, - TDOUBLE, BNUMBER, 0, - TIND, BINTEGER, 0, - -1, 0, 0, -}; - -int32 tsub[NTYPE]; -Init tsubinit[] = -{ - TCHAR, BNUMBER, 0, - TUCHAR, BNUMBER, 0, - TSHORT, BNUMBER, 0, - TUSHORT, BNUMBER, 0, - TINT, BNUMBER, 0, - TUINT, BNUMBER, 0, - TLONG, BNUMBER, 0, - TULONG, BNUMBER, 0, - TVLONG, BNUMBER, 0, - TUVLONG, BNUMBER, 0, - TFLOAT, BNUMBER, 0, - TDOUBLE, BNUMBER, 0, - TIND, BINTEGER|BIND, 0, - -1, 0, 0, -}; - -int32 tmul[NTYPE]; -Init tmulinit[] = -{ - TCHAR, BNUMBER, 0, - TUCHAR, BNUMBER, 0, - TSHORT, BNUMBER, 0, - TUSHORT, BNUMBER, 0, - TINT, BNUMBER, 0, - TUINT, BNUMBER, 0, - TLONG, BNUMBER, 0, - TULONG, BNUMBER, 0, - TVLONG, BNUMBER, 0, - TUVLONG, BNUMBER, 0, - TFLOAT, BNUMBER, 0, - TDOUBLE, BNUMBER, 0, - -1, 0, 0, -}; - -int32 tand[NTYPE]; -Init tandinit[] = -{ - TCHAR, BINTEGER, 0, - TUCHAR, BINTEGER, 0, - TSHORT, BINTEGER, 0, - TUSHORT, BINTEGER, 0, - TINT, BNUMBER, 0, - TUINT, BNUMBER, 0, - TLONG, BINTEGER, 0, - TULONG, BINTEGER, 0, - TVLONG, BINTEGER, 0, - TUVLONG, BINTEGER, 0, - -1, 0, 0, -}; - -int32 trel[NTYPE]; -Init trelinit[] = -{ - TCHAR, BNUMBER, 0, - TUCHAR, BNUMBER, 0, - TSHORT, BNUMBER, 0, - TUSHORT, BNUMBER, 0, - TINT, BNUMBER, 0, - TUINT, BNUMBER, 0, - TLONG, BNUMBER, 0, - TULONG, BNUMBER, 0, - TVLONG, BNUMBER, 0, - TUVLONG, BNUMBER, 0, - TFLOAT, BNUMBER, 0, - TDOUBLE, BNUMBER, 0, - TIND, BIND, 0, - -1, 0, 0, -}; - -int32 tfunct[1] = -{ - BFUNC, -}; - -int32 tindir[1] = -{ - BIND, -}; - -int32 tdot[1] = -{ - BSTRUCT|BUNION, -}; - -int32 tnot[1] = -{ - BNUMBER|BIND, -}; - -int32 targ[1] = -{ - BNUMBER|BIND|BSTRUCT|BUNION, -}; - -uchar tab[NTYPE][NTYPE] = -{ -/*TXXX*/ { 0, - }, - -/*TCHAR*/ { 0, TCHAR, TUCHAR, TSHORT, TUSHORT, TINT, TUINT, TLONG, - TULONG, TVLONG, TUVLONG, TFLOAT, TDOUBLE, TIND, - }, -/*TUCHAR*/ { 0, TUCHAR, TUCHAR, TUSHORT, TUSHORT, TUINT, TUINT, TULONG, - TULONG, TUVLONG, TUVLONG, TFLOAT, TDOUBLE, TIND, - }, -/*TSHORT*/ { 0, TSHORT, TUSHORT, TSHORT, TUSHORT, TINT, TUINT, TLONG, - TULONG, TVLONG, TUVLONG, TFLOAT, TDOUBLE, TIND, - }, -/*TUSHORT*/ { 0, TUSHORT, TUSHORT, TUSHORT, TUSHORT, TUINT, TUINT, TULONG, - TULONG, TUVLONG, TUVLONG, TFLOAT, TDOUBLE, TIND, - }, -/*TINT*/ { 0, TINT, TUINT, TINT, TUINT, TINT, TUINT, TLONG, - TULONG, TVLONG, TUVLONG, TFLOAT, TDOUBLE, TIND, - }, -/*TUINT*/ { 0, TUINT, TUINT, TUINT, TUINT, TUINT, TUINT, TULONG, - TULONG, TUVLONG, TUVLONG, TFLOAT, TDOUBLE, TIND, - }, -/*TLONG*/ { 0, TLONG, TULONG, TLONG, TULONG, TLONG, TULONG, TLONG, - TULONG, TVLONG, TUVLONG, TFLOAT, TDOUBLE, TIND, - }, -/*TULONG*/ { 0, TULONG, TULONG, TULONG, TULONG, TULONG, TULONG, TULONG, - TULONG, TUVLONG, TUVLONG, TFLOAT, TDOUBLE, TIND, - }, -/*TVLONG*/ { 0, TVLONG, TUVLONG, TVLONG, TUVLONG, TVLONG, TUVLONG, TVLONG, - TUVLONG, TVLONG, TUVLONG, TFLOAT, TDOUBLE, TIND, - }, -/*TUVLONG*/ { 0, TUVLONG, TUVLONG, TUVLONG, TUVLONG, TUVLONG, TUVLONG, TUVLONG, - TUVLONG, TUVLONG, TUVLONG, TFLOAT, TDOUBLE, TIND, - }, -/*TFLOAT*/ { 0, TFLOAT, TFLOAT, TFLOAT, TFLOAT, TFLOAT, TFLOAT, TFLOAT, - TFLOAT, TFLOAT, TFLOAT, TFLOAT, TDOUBLE, TIND, - }, -/*TDOUBLE*/ { 0, TDOUBLE, TDOUBLE, TDOUBLE, TDOUBLE, TDOUBLE, TDOUBLE, TDOUBLE, - TDOUBLE, TDOUBLE, TDOUBLE, TFLOAT, TDOUBLE, TIND, - }, -/*TIND*/ { 0, TIND, TIND, TIND, TIND, TIND, TIND, TIND, - TIND, TIND, TIND, TIND, TIND, TIND, - }, -}; - -void -urk(char *name, int max, int i) -{ - if(i >= max) { - fprint(2, "bad tinit: %s %d>=%d\n", name, i, max); - exits("init"); - } -} - -void -tinit(void) -{ - int *ip; - Init *p; - - for(p=thashinit; p->code >= 0; p++) { - urk("thash", nelem(thash), p->code); - thash[p->code] = p->value; - } - for(p=bnamesinit; p->code >= 0; p++) { - urk("bnames", nelem(bnames), p->code); - bnames[p->code] = p->s; - } - for(p=tnamesinit; p->code >= 0; p++) { - urk("tnames", nelem(tnames), p->code); - tnames[p->code] = p->s; - } - for(p=gnamesinit; p->code >= 0; p++) { - urk("gnames", nelem(gnames), p->code); - gnames[p->code] = p->s; - } - for(p=qnamesinit; p->code >= 0; p++) { - urk("qnames", nelem(qnames), p->code); - qnames[p->code] = p->s; - } - for(p=cnamesinit; p->code >= 0; p++) { - urk("cnames", nelem(cnames), p->code); - cnames[p->code] = p->s; - } - for(p=onamesinit; p->code >= 0; p++) { - urk("onames", nelem(onames), p->code); - onames[p->code] = p->s; - } - for(ip=typeiinit; *ip>=0; ip++) { - urk("typei", nelem(typei), *ip); - typei[*ip] = 1; - } - for(ip=typeuinit; *ip>=0; ip++) { - urk("typeu", nelem(typeu), *ip); - typeu[*ip] = 1; - } - for(ip=typesuvinit; *ip>=0; ip++) { - urk("typesuv", nelem(typesuv), *ip); - typesuv[*ip] = 1; - } - for(ip=typeilpinit; *ip>=0; ip++) { - urk("typeilp", nelem(typeilp), *ip); - typeilp[*ip] = 1; - } - for(ip=typechlinit; *ip>=0; ip++) { - urk("typechl", nelem(typechl), *ip); - typechl[*ip] = 1; - typechlv[*ip] = 1; - typechlvp[*ip] = 1; - } - for(ip=typechlpinit; *ip>=0; ip++) { - urk("typechlp", nelem(typechlp), *ip); - typechlp[*ip] = 1; - typechlvp[*ip] = 1; - } - for(ip=typechlpfdinit; *ip>=0; ip++) { - urk("typechlpfd", nelem(typechlpfd), *ip); - typechlpfd[*ip] = 1; - } - for(ip=typecinit; *ip>=0; ip++) { - urk("typec", nelem(typec), *ip); - typec[*ip] = 1; - } - for(ip=typehinit; *ip>=0; ip++) { - urk("typeh", nelem(typeh), *ip); - typeh[*ip] = 1; - } - for(ip=typeilinit; *ip>=0; ip++) { - urk("typeil", nelem(typeil), *ip); - typeil[*ip] = 1; - } - for(ip=typevinit; *ip>=0; ip++) { - urk("typev", nelem(typev), *ip); - typev[*ip] = 1; - typechlv[*ip] = 1; - typechlvp[*ip] = 1; - } - for(ip=typefdinit; *ip>=0; ip++) { - urk("typefd", nelem(typefd), *ip); - typefd[*ip] = 1; - } - for(ip=typeafinit; *ip>=0; ip++) { - urk("typeaf", nelem(typeaf), *ip); - typeaf[*ip] = 1; - } - for(ip=typesuinit; *ip >= 0; ip++) { - urk("typesu", nelem(typesu), *ip); - typesu[*ip] = 1; - } - for(p=tasigninit; p->code >= 0; p++) { - urk("tasign", nelem(tasign), p->code); - tasign[p->code] = p->value; - } - for(p=tasaddinit; p->code >= 0; p++) { - urk("tasadd", nelem(tasadd), p->code); - tasadd[p->code] = p->value; - } - for(p=tcastinit; p->code >= 0; p++) { - urk("tcast", nelem(tcast), p->code); - tcast[p->code] = p->value; - } - for(p=taddinit; p->code >= 0; p++) { - urk("tadd", nelem(tadd), p->code); - tadd[p->code] = p->value; - } - for(p=tsubinit; p->code >= 0; p++) { - urk("tsub", nelem(tsub), p->code); - tsub[p->code] = p->value; - } - for(p=tmulinit; p->code >= 0; p++) { - urk("tmul", nelem(tmul), p->code); - tmul[p->code] = p->value; - } - for(p=tandinit; p->code >= 0; p++) { - urk("tand", nelem(tand), p->code); - tand[p->code] = p->value; - } - for(p=trelinit; p->code >= 0; p++) { - urk("trel", nelem(trel), p->code); - trel[p->code] = p->value; - } - - /* 32-bit defaults */ - typeword = typechlp; - typecmplx = typesuv; -} - -/* - * return 1 if it is impossible to jump into the middle of n. - */ -static int -deadhead(Node *n, int caseok) -{ -loop: - if(n == Z) - return 1; - switch(n->op) { - case OLIST: - if(!deadhead(n->left, caseok)) - return 0; - rloop: - n = n->right; - goto loop; - - case ORETURN: - break; - - case OLABEL: - return 0; - - case OGOTO: - break; - - case OCASE: - if(!caseok) - return 0; - goto rloop; - - case OSWITCH: - return deadhead(n->right, 1); - - case OWHILE: - case ODWHILE: - goto rloop; - - case OFOR: - goto rloop; - - case OCONTINUE: - break; - - case OBREAK: - break; - - case OIF: - return deadhead(n->right->left, caseok) && deadhead(n->right->right, caseok); - - case OSET: - case OUSED: - break; - } - return 1; -} - -int -deadheads(Node *c) -{ - return deadhead(c->left, 0) && deadhead(c->right, 0); -} - -int -mixedasop(Type *l, Type *r) -{ - return !typefd[l->etype] && typefd[r->etype]; -} |