summaryrefslogtreecommitdiff
path: root/src/cmd/cc
diff options
context:
space:
mode:
authorOndřej Surý <ondrej@sury.org>2011-09-13 13:11:55 +0200
committerOndřej Surý <ondrej@sury.org>2011-09-13 13:11:55 +0200
commit80f18fc933cf3f3e829c5455a1023d69f7b86e52 (patch)
tree4b825dc642cb6eb9a060e54bf8d69288fbee4904 /src/cmd/cc
parent28592ee1ea1f5cdffcf85472f9de0285d928cf12 (diff)
downloadgolang-80f18fc933cf3f3e829c5455a1023d69f7b86e52.tar.gz
Imported Upstream version 60
Diffstat (limited to 'src/cmd/cc')
-rw-r--r--src/cmd/cc/Makefile36
-rw-r--r--src/cmd/cc/acid.c344
-rw-r--r--src/cmd/cc/bits.c120
-rw-r--r--src/cmd/cc/cc.h831
-rw-r--r--src/cmd/cc/cc.y1215
-rw-r--r--src/cmd/cc/com.c1385
-rw-r--r--src/cmd/cc/com64.c644
-rw-r--r--src/cmd/cc/dcl.c1669
-rw-r--r--src/cmd/cc/doc.go11
-rw-r--r--src/cmd/cc/dpchk.c724
-rw-r--r--src/cmd/cc/funct.c431
-rw-r--r--src/cmd/cc/godefs.c388
-rw-r--r--src/cmd/cc/lex.c1562
-rw-r--r--src/cmd/cc/lexbody769
-rw-r--r--src/cmd/cc/mac.c35
-rw-r--r--src/cmd/cc/macbody852
-rw-r--r--src/cmd/cc/omachcap.c40
-rw-r--r--src/cmd/cc/pgen.c594
-rw-r--r--src/cmd/cc/pswt.c168
-rw-r--r--src/cmd/cc/scon.c637
-rw-r--r--src/cmd/cc/sub.c2056
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];
-}