diff options
Diffstat (limited to 'src/cmd/cc')
-rw-r--r-- | src/cmd/cc/Makefile | 2 | ||||
-rw-r--r-- | src/cmd/cc/cc.h | 7 | ||||
-rw-r--r-- | src/cmd/cc/dcl.c | 6 | ||||
-rw-r--r-- | src/cmd/cc/dpchk.c | 1 | ||||
-rw-r--r-- | src/cmd/cc/godefs.c | 387 | ||||
-rw-r--r-- | src/cmd/cc/lex.c | 24 | ||||
-rw-r--r-- | src/cmd/cc/lexbody | 43 | ||||
-rw-r--r-- | src/cmd/cc/pgen.c | 3 | ||||
-rw-r--r-- | src/cmd/cc/pickle.c | 298 |
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; - } -} |