summaryrefslogtreecommitdiff
path: root/src/cmd/cc
diff options
context:
space:
mode:
authorOndřej Surý <ondrej@sury.org>2011-02-14 13:23:51 +0100
committerOndřej Surý <ondrej@sury.org>2011-02-14 13:23:51 +0100
commit758ff64c69e34965f8af5b2d6ffd65e8d7ab2150 (patch)
tree6d6b34f8c678862fe9b56c945a7b63f68502c245 /src/cmd/cc
parent3e45412327a2654a77944249962b3652e6142299 (diff)
downloadgolang-upstream/2011-02-01.1.tar.gz
Imported Upstream version 2011-02-01.1upstream/2011-02-01.1
Diffstat (limited to 'src/cmd/cc')
-rw-r--r--src/cmd/cc/Makefile2
-rw-r--r--src/cmd/cc/cc.h7
-rw-r--r--src/cmd/cc/dcl.c6
-rw-r--r--src/cmd/cc/dpchk.c1
-rw-r--r--src/cmd/cc/godefs.c387
-rw-r--r--src/cmd/cc/lex.c24
-rw-r--r--src/cmd/cc/lexbody43
-rw-r--r--src/cmd/cc/pgen.c3
-rw-r--r--src/cmd/cc/pickle.c298
9 files changed, 427 insertions, 344 deletions
diff --git a/src/cmd/cc/Makefile b/src/cmd/cc/Makefile
index 71f23383d..8327d9516 100644
--- a/src/cmd/cc/Makefile
+++ b/src/cmd/cc/Makefile
@@ -20,7 +20,7 @@ OFILES=\
mac.$O\
dcl.$O\
acid.$O\
- pickle.$O\
+ godefs.$O\
bits.$O\
com.$O\
scon.$O\
diff --git a/src/cmd/cc/cc.h b/src/cmd/cc/cc.h
index 3649bf5f6..8e8f6af44 100644
--- a/src/cmd/cc/cc.h
+++ b/src/cmd/cc/cc.h
@@ -59,7 +59,6 @@ typedef struct Bits Bits;
typedef struct Dynimp Dynimp;
typedef struct Dynexp Dynexp;
-#define NHUNK 50000L
#define BUFSIZ 8192
#define NSYMB 500
#define NHASH 1024
@@ -745,9 +744,11 @@ void acidtype(Type*);
void acidvar(Sym*);
/*
- * pickle.c
+ * godefs.c
*/
-void pickletype(Type*);
+int Uconv(Fmt*);
+void godeftype(Type*);
+void godefvar(Sym*);
/*
* bits.c
diff --git a/src/cmd/cc/dcl.c b/src/cmd/cc/dcl.c
index f629925d1..d7604b649 100644
--- a/src/cmd/cc/dcl.c
+++ b/src/cmd/cc/dcl.c
@@ -130,6 +130,7 @@ loop:
if(debug['d'])
dbgdecl(s);
acidvar(s);
+ godefvar(s);
s->varlineno = lineno;
break;
}
@@ -587,7 +588,7 @@ sualign(Type *t)
t->width = w;
t->align = maxal;
acidtype(t);
- pickletype(t);
+ godeftype(t);
return;
case TUNION:
@@ -610,7 +611,7 @@ sualign(Type *t)
t->width = w;
t->align = maxal;
acidtype(t);
- pickletype(t);
+ godeftype(t);
return;
default:
@@ -1538,6 +1539,7 @@ doenum(Sym *s, Node *n)
if(debug['d'])
dbgdecl(s);
acidvar(s);
+ godefvar(s);
}
void
diff --git a/src/cmd/cc/dpchk.c b/src/cmd/cc/dpchk.c
index 6eb5fb409..d78a72a2b 100644
--- a/src/cmd/cc/dpchk.c
+++ b/src/cmd/cc/dpchk.c
@@ -399,6 +399,7 @@ dpcheck(Node *n)
return;
i = l->param;
+ a = nil;
b = n->right;
a = Z;
while(i > 0) {
diff --git a/src/cmd/cc/godefs.c b/src/cmd/cc/godefs.c
new file mode 100644
index 000000000..9503cb2f2
--- /dev/null
+++ b/src/cmd/cc/godefs.c
@@ -0,0 +1,387 @@
+// 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 "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(", t);
+ 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
index 3b413c246..dba8ff634 100644
--- a/src/cmd/cc/lex.c
+++ b/src/cmd/cc/lex.c
@@ -59,15 +59,20 @@ pathchar(void)
* -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 to file (%.c=%.acid) (with -a or -aa)
+ * -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
@@ -121,7 +126,7 @@ main(int argc, char *argv[])
p = ARGF();
if(p) {
if(ndef%8 == 0)
- defs = allocn(defs, ndef*sizeof(char *),
+ defs = allocn(defs, ndef*sizeof(char *),
8*sizeof(char *));
defs[ndef++] = p;
dodefine(p);
@@ -147,7 +152,7 @@ main(int argc, char *argv[])
* if we're writing acid to standard output, don't compile
* concurrently, to avoid interleaving output.
*/
- if(((!debug['a'] && !debug['Z']) || debug['n']) &&
+ if(((!debug['a'] && !debug['q'] && !debug['Q']) || debug['n']) &&
(p = getenv("NPROC")) != nil)
nproc = atol(p); /* */
c = 0;
@@ -220,8 +225,8 @@ compile(char *file, char **defs, int ndef)
p = utfrune(outfile, 0);
if(debug['a'] && debug['n'])
strcat(p, ".acid");
- else if(debug['Z'] && debug['n'])
- strcat(p, "_pickle.c");
+ else if((debug['q'] || debug['Q']) && debug['n'])
+ strcat(p, ".go");
else {
p[0] = '.';
p[1] = thechar;
@@ -246,7 +251,7 @@ compile(char *file, char **defs, int ndef)
* if we're writing acid to standard output, don't keep scratching
* outbuf.
*/
- if((debug['a'] || debug['Z']) && !debug['n']) {
+ if((debug['a'] || debug['q'] || debug['Q']) && !debug['n']) {
if (first) {
outfile = 0;
Binit(&outbuf, dup(1, -1), OWRITE);
@@ -325,7 +330,7 @@ compile(char *file, char **defs, int ndef)
newfile(file, -1);
}
yyparse();
- if(!debug['a'] && !debug['Z'])
+ if(!debug['a'] && !debug['q'] && !debug['Q'])
gclean();
return nerrors;
}
@@ -1309,6 +1314,7 @@ cinit(void)
fmtinstall('L', Lconv);
fmtinstall('Q', Qconv);
fmtinstall('|', VBconv);
+ fmtinstall('U', Uconv);
}
int
@@ -1554,7 +1560,7 @@ setinclude(char *p)
return;
if(ninclude%8 == 0)
- include = allocn(include, ninclude*sizeof(char *),
+ include = allocn(include, ninclude*sizeof(char *),
8*sizeof(char *));
include[ninclude++] = p;
}
@@ -1595,7 +1601,7 @@ ensuresymb(int32 n)
if(symb == nil) {
symb = alloc(NSYMB+1);
nsymb = NSYMB;
- }
+ }
if(n > nsymb) {
symb = allocn(symb, nsymb, n+1-nsymb);
diff --git a/src/cmd/cc/lexbody b/src/cmd/cc/lexbody
index 0bccc1733..24f9bdc85 100644
--- a/src/cmd/cc/lexbody
+++ b/src/cmd/cc/lexbody
@@ -88,47 +88,32 @@ pragincomplete(void)
;
}
-void
-gethunk(void)
-{
- hunk = malloc(NHUNK);
- memset(hunk, 0, NHUNK);
- nhunk = NHUNK;
-}
-
void*
alloc(int32 n)
{
void *p;
- while((uintptr)hunk & MAXALIGN) {
- hunk++;
- nhunk--;
+ p = malloc(n);
+ if(p == nil) {
+ print("alloc out of mem\n");
+ exit(1);
}
- while(nhunk < n)
- gethunk();
- p = hunk;
- nhunk -= n;
- hunk += n;
+ memset(p, 0, n);
return p;
}
void*
-allocn(void *p, int32 on, int32 n)
+allocn(void *p, int32 n, int32 d)
{
- void *q;
-
- q = (uchar*)p + on;
- if(q != hunk || nhunk < n) {
- while(nhunk < on+n)
- gethunk();
- memmove(hunk, p, on);
- p = hunk;
- hunk += on;
- nhunk -= on;
+ if(p == nil)
+ return alloc(n+d);
+ p = realloc(p, n+d);
+ if(p == nil) {
+ print("allocn out of mem\n");
+ exit(1);
}
- hunk += n;
- nhunk -= n;
+ if(d > 0)
+ memset((char*)p+n, 0, d);
return p;
}
diff --git a/src/cmd/cc/pgen.c b/src/cmd/cc/pgen.c
index a9d7f1ef4..5d17cafc9 100644
--- a/src/cmd/cc/pgen.c
+++ b/src/cmd/cc/pgen.c
@@ -586,8 +586,7 @@ bcomplex(Node *n, Node *c)
*b->right = *nodconst(0);
b->right->type = n->type;
b->type = types[TLONG];
- cgen(b, Z);
- return 0;
+ n = b;
}
bool64(n);
boolgen(n, 1, Z);
diff --git a/src/cmd/cc/pickle.c b/src/cmd/cc/pickle.c
deleted file mode 100644
index 82cf5eb05..000000000
--- a/src/cmd/cc/pickle.c
+++ /dev/null
@@ -1,298 +0,0 @@
-// Inferno utils/cc/pickle.c
-// http://code.google.com/p/inferno-os/source/browse/utils/cc/pickle.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 "cc.h"
-
-static char *kwd[] =
-{
- "$adt", "$aggr", "$append", "$complex", "$defn",
- "$delete", "$do", "$else", "$eval", "$head", "$if",
- "$local", "$loop", "$return", "$tail", "$then",
- "$union", "$whatis", "$while",
-};
-static char picklestr[] = "\tbp = pickle(bp, ep, un, ";
-
-static char*
-pmap(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*
-picklesue(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*
-picklefun(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 picklechar[NTYPE];
-Init picklecinit[] =
-{
- 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
-pickleinit(void)
-{
- Init *p;
-
- for(p=picklecinit; p->code >= 0; p++)
- picklechar[p->code] = p->value;
-
- picklechar[TINT] = picklechar[TLONG];
- picklechar[TUINT] = picklechar[TULONG];
- if(types[TINT]->width != types[TLONG]->width) {
- picklechar[TINT] = picklechar[TSHORT];
- picklechar[TUINT] = picklechar[TUSHORT];
- if(types[TINT]->width != types[TSHORT]->width)
- warn(Z, "picklemember int not long or short");
- }
-
-}
-
-void
-picklemember(Type *t, int32 off)
-{
- Sym *s, *s1;
- static int picklecharinit = 0;
-
- if(picklecharinit == 0) {
- pickleinit();
- picklecharinit = 1;
- }
- s = t->sym;
- switch(t->etype) {
- default:
- Bprint(&outbuf, " T%d\n", t->etype);
- break;
-
- case TIND:
- if(s == S)
- Bprint(&outbuf,
- "%s\"p\", (char*)addr+%d+_i*%d);\n",
- picklestr, t->offset+off, t->width);
- else
- Bprint(&outbuf,
- "%s\"p\", &addr->%s);\n",
- picklestr, pmap(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:
- if(s == S)
- Bprint(&outbuf, "%s\"%c\", (char*)addr+%d+_i*%d);\n",
- picklestr, picklechar[t->etype], t->offset+off, t->width);
- else
- Bprint(&outbuf, "%s\"%c\", &addr->%s);\n",
- picklestr, picklechar[t->etype], pmap(s->name));
- break;
- case TARRAY:
- Bprint(&outbuf, "\tfor(_i = 0; _i < %d; _i++) {\n\t",
- t->width/t->link->width);
- picklemember(t->link, t->offset+off);
- Bprint(&outbuf, "\t}\n\t_i = 0;\n\tUSED(_i);\n");
- break;
-
- case TSTRUCT:
- case TUNION:
- s1 = picklesue(t->link);
- if(s1 == S)
- break;
- if(s == S) {
- Bprint(&outbuf, "\tbp = pickle_%s(bp, ep, un, (%s*)((char*)addr+%d+_i*%d));\n",
- pmap(s1->name), pmap(s1->name), t->offset+off, t->width);
- } else {
- Bprint(&outbuf, "\tbp = pickle_%s(bp, ep, un, &addr->%s);\n",
- pmap(s1->name), pmap(s->name));
- }
- break;
- }
-}
-
-void
-pickletype(Type *t)
-{
- Sym *s;
- Type *l;
- Io *i;
- int n;
- char *an;
-
- if(!debug['P'])
- return;
- if(debug['P'] > 1) {
- n = 0;
- for(i=iostack; i; i=i->link)
- n++;
- if(n > 1)
- return;
- }
- s = picklesue(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 = pmap(s->name);
-
- Bprint(&outbuf, "char *\npickle_%s(char *bp, char *ep, int un, %s *addr)\n{\n\tint _i = 0;\n\n\tUSED(_i);\n", an, an);
- for(l = t->link; l != T; l = l->down)
- picklemember(l, 0);
- Bprint(&outbuf, "\treturn bp;\n}\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
-picklevar(Sym *s)
-{
- int n;
- Io *i;
- Type *t;
- Sym *s1, *s2;
-
- if(!debug['P'] || debug['s'])
- return;
- if(debug['P'] > 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 = ", pmap(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 = picklesue(t->link);
- if(s1 == S)
- return;
- switch(s->class) {
- case CAUTO:
- case CPARAM:
- s2 = picklefun(thisfn);
- if(s2)
- Bprint(&outbuf, "complex %s %s:%s;\n",
- pmap(s1->name), pmap(s2->name), pmap(s->name));
- break;
-
- case CSTATIC:
- case CEXTERN:
- case CGLOBL:
- case CLOCAL:
- Bprint(&outbuf, "complex %s %s;\n",
- pmap(s1->name), pmap(s->name));
- break;
- }
-}