github.com/hongwozai/go-src-1.4.3@v0.0.0-20191127132709-dc3fce3dbccb/src/cmd/cc/acid.c (about)

     1  // Inferno utils/cc/acid.c
     2  // http://code.google.com/p/inferno-os/source/browse/utils/cc/acid.c
     3  //
     4  //	Copyright © 1994-1999 Lucent Technologies Inc.  All rights reserved.
     5  //	Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net)
     6  //	Portions Copyright © 1997-1999 Vita Nuova Limited
     7  //	Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com)
     8  //	Portions Copyright © 2004,2006 Bruce Ellis
     9  //	Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net)
    10  //	Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others
    11  //	Portions Copyright © 2009 The Go Authors.  All rights reserved.
    12  //
    13  // Permission is hereby granted, free of charge, to any person obtaining a copy
    14  // of this software and associated documentation files (the "Software"), to deal
    15  // in the Software without restriction, including without limitation the rights
    16  // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
    17  // copies of the Software, and to permit persons to whom the Software is
    18  // furnished to do so, subject to the following conditions:
    19  //
    20  // The above copyright notice and this permission notice shall be included in
    21  // all copies or substantial portions of the Software.
    22  //
    23  // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
    24  // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
    25  // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
    26  // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
    27  // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
    28  // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
    29  // THE SOFTWARE.
    30  
    31  #include <u.h>
    32  #include "cc.h"
    33  
    34  static char *kwd[] =
    35  {
    36  	"$adt", "$aggr", "$append", "$complex", "$defn",
    37  	"$delete", "$do", "$else", "$eval", "$head", "$if",
    38  	"$local", "$loop", "$return", "$tail", "$then",
    39  	"$union", "$whatis", "$while",
    40  };
    41  
    42  char*
    43  amap(char *s)
    44  {
    45  	int i, bot, top, new;
    46  
    47  	bot = 0;
    48  	top = bot + nelem(kwd) - 1;
    49  	while(bot <= top){
    50  		new = bot + (top - bot)/2;
    51  		i = strcmp(kwd[new]+1, s);
    52  		if(i == 0)
    53  			return kwd[new];
    54  
    55  		if(i < 0)
    56  			bot = new + 1;
    57  		else
    58  			top = new - 1;
    59  	}
    60  	return s;
    61  }
    62  
    63  Sym*
    64  acidsue(Type *t)
    65  {
    66  	int h;
    67  	Sym *s;
    68  
    69  	if(t != T)
    70  	for(h=0; h<nelem(hash); h++)
    71  		for(s = hash[h]; s != S; s = s->link)
    72  			if(s->suetag && s->suetag->link == t)
    73  				return s;
    74  	return 0;
    75  }
    76  
    77  Sym*
    78  acidfun(Type *t)
    79  {
    80  	int h;
    81  	Sym *s;
    82  
    83  	for(h=0; h<nelem(hash); h++)
    84  		for(s = hash[h]; s != S; s = s->link)
    85  			if(s->type == t)
    86  				return s;
    87  	return 0;
    88  }
    89  
    90  char	acidchar[NTYPE];
    91  Init	acidcinit[] =
    92  {
    93  	TCHAR,		'C',	0,
    94  	TUCHAR,		'b',	0,
    95  	TSHORT,		'd',	0,
    96  	TUSHORT,	'u',	0,
    97  	TLONG,		'D',	0,
    98  	TULONG,		'U',	0,
    99  	TVLONG,		'V',	0,
   100  	TUVLONG,	'W',	0,
   101  	TFLOAT,		'f',	0,
   102  	TDOUBLE,	'F',	0,
   103  	TARRAY,		'a',	0,
   104  	TIND,		'X',	0,
   105  	-1,		0,	0,
   106  };
   107  
   108  static void
   109  acidinit(void)
   110  {
   111  	Init *p;
   112  
   113  	for(p=acidcinit; p->code >= 0; p++)
   114  		acidchar[p->code] = p->value;
   115  
   116  	acidchar[TINT] = acidchar[TLONG];
   117  	acidchar[TUINT] = acidchar[TULONG];
   118  	if(types[TINT]->width != types[TLONG]->width) {
   119  		acidchar[TINT] = acidchar[TSHORT];
   120  		acidchar[TUINT] = acidchar[TUSHORT];
   121  		if(types[TINT]->width != types[TSHORT]->width)
   122  			warn(Z, "acidmember int not long or short");
   123  	}
   124  	if(types[TIND]->width == types[TUVLONG]->width)
   125  		acidchar[TIND] = 'Y';
   126  	
   127  }
   128  
   129  void
   130  acidmember(Type *t, int32 off, int flag)
   131  {
   132  	Sym *s, *s1;
   133  	Type *l;
   134  	static int acidcharinit = 0;
   135  
   136  	if(acidcharinit == 0) {
   137  		acidinit();
   138  		acidcharinit = 1;
   139  	}
   140  	s = t->sym;
   141  	switch(t->etype) {
   142  	default:
   143  		Bprint(&outbuf, "	T%d\n", t->etype);
   144  		break;
   145  
   146  	case TIND:
   147  		if(s == S)
   148  			break;
   149  		l = t->link;
   150  		if(flag) { 
   151  			if(typesu[l->etype]) {
   152  				s1 = acidsue(l->link);
   153  				if(s1 != S) {
   154  					Bprint(&outbuf, "	'A' %s %d %s;\n",
   155  						amap(s1->name),
   156  						t->offset+off, amap(s->name));
   157  					break;
   158  				}
   159  			}
   160  		} else {
   161  			l = t->link;
   162  			s1 = S;
   163  			if(typesu[l->etype])
   164  				s1 = acidsue(l->link);
   165  			if(s1 != S) {
   166  				Bprint(&outbuf,
   167  					"\tprint(indent, \"%s\t(%s)\", addr.%s\\X, \"\\n\");\n",
   168  					amap(s->name), amap(s1->name), amap(s->name));
   169  			} else {
   170  				Bprint(&outbuf,
   171  					"\tprint(indent, \"%s\t\", addr.%s\\X, \"\\n\");\n",
   172  					amap(s->name), amap(s->name));
   173  			}
   174  			break;
   175  		}
   176  
   177  	case TINT:
   178  	case TUINT:
   179  	case TCHAR:
   180  	case TUCHAR:
   181  	case TSHORT:
   182  	case TUSHORT:
   183  	case TLONG:
   184  	case TULONG:
   185  	case TVLONG:
   186  	case TUVLONG:
   187  	case TFLOAT:
   188  	case TDOUBLE:
   189  	case TARRAY:
   190  		if(s == S)
   191  			break;
   192  		if(flag) {
   193  			Bprint(&outbuf, "	'%c' %d %s;\n",
   194  			acidchar[t->etype], t->offset+off, amap(s->name));
   195  		} else {
   196  			Bprint(&outbuf, "\tprint(indent, \"%s\t\", addr.%s, \"\\n\");\n",
   197  				amap(s->name), amap(s->name));
   198  		}
   199  		break;
   200  
   201  	case TSTRUCT:
   202  	case TUNION:
   203  		s1 = acidsue(t->link);
   204  		if(s1 == S)
   205  			break;
   206  		if(flag) {
   207  			if(s == S) {
   208  				Bprint(&outbuf, "	{\n");
   209  				for(l = t->link; l != T; l = l->down)
   210  					acidmember(l, t->offset+off, flag);
   211  				Bprint(&outbuf, "	};\n");
   212  			} else {
   213  				Bprint(&outbuf, "	%s %d %s;\n",
   214  					amap(s1->name),
   215  					t->offset+off, amap(s->name));
   216  			}
   217  		} else {
   218  			if(s != S) {
   219  				Bprint(&outbuf, "\tprint(indent, \"%s %s {\\n\");\n",
   220  					amap(s1->name), amap(s->name));
   221  				Bprint(&outbuf, "\tindent_%s(addr.%s, indent+\"\\t\");\n",
   222  					amap(s1->name), amap(s->name));
   223  				Bprint(&outbuf, "\tprint(indent, \"}\\n\");\n");
   224  			} else {
   225  				Bprint(&outbuf, "\tprint(indent, \"%s {\\n\");\n",
   226  					amap(s1->name));
   227  				Bprint(&outbuf, "\tindent_%s(addr+%d, indent+\"\\t\");\n",
   228  					amap(s1->name), t->offset+off);
   229  				Bprint(&outbuf, "\tprint(indent, \"}\\n\");\n");
   230  			}
   231  		}
   232  		break;
   233  	}
   234  }
   235  
   236  void
   237  acidtype(Type *t)
   238  {
   239  	Sym *s;
   240  	Type *l;
   241  	Io *i;
   242  	int n;
   243  	char *an;
   244  
   245  	if(!debug['a'])
   246  		return;
   247  	if(debug['a'] > 1) {
   248  		n = 0;
   249  		for(i=iostack; i; i=i->link)
   250  			n++;
   251  		if(n > 1)
   252  			return;
   253  	}
   254  	s = acidsue(t->link);
   255  	if(s == S)
   256  		return;
   257  	switch(t->etype) {
   258  	default:
   259  		Bprint(&outbuf, "T%d\n", t->etype);
   260  		return;
   261  
   262  	case TUNION:
   263  	case TSTRUCT:
   264  		if(debug['s'])
   265  			goto asmstr;
   266  		an = amap(s->name);
   267  		Bprint(&outbuf, "sizeof%s = %d;\n", an, t->width);
   268  		Bprint(&outbuf, "aggr %s\n{\n", an);
   269  		for(l = t->link; l != T; l = l->down)
   270  			acidmember(l, 0, 1);
   271  		Bprint(&outbuf, "};\n\n");
   272  
   273  		Bprint(&outbuf, "defn\n%s(addr) {\n\tindent_%s(addr, \"\\t\");\n}\n", an, an);
   274  		Bprint(&outbuf, "defn\nindent_%s(addr, indent) {\n\tcomplex %s addr;\n", an, an);
   275  		for(l = t->link; l != T; l = l->down)
   276  			acidmember(l, 0, 0);
   277  		Bprint(&outbuf, "};\n\n");
   278  		break;
   279  	asmstr:
   280  		if(s == S)
   281  			break;
   282  		for(l = t->link; l != T; l = l->down)
   283  			if(l->sym != S)
   284  				Bprint(&outbuf, "#define\t%s.%s\t%d\n",
   285  					s->name,
   286  					l->sym->name,
   287  					l->offset);
   288  		break;
   289  	}
   290  }
   291  
   292  void
   293  acidvar(Sym *s)
   294  {
   295  	int n;
   296  	Io *i;
   297  	Type *t;
   298  	Sym *s1, *s2;
   299  
   300  	if(!debug['a'] || debug['s'])
   301  		return;
   302  	if(debug['a'] > 1) {
   303  		n = 0;
   304  		for(i=iostack; i; i=i->link)
   305  			n++;
   306  		if(n > 1)
   307  			return;
   308  	}
   309  	t = s->type;
   310  	while(t && t->etype == TIND)
   311  		t = t->link;
   312  	if(t == T)
   313  		return;
   314  	if(t->etype == TENUM) {
   315  		Bprint(&outbuf, "%s = ", amap(s->name));
   316  		if(!typefd[t->etype])
   317  			Bprint(&outbuf, "%lld;\n", s->vconst);
   318  		else
   319  			Bprint(&outbuf, "%f\n;", s->fconst);
   320  		return;
   321  	}
   322  	if(!typesu[t->etype])
   323  		return;
   324  	s1 = acidsue(t->link);
   325  	if(s1 == S)
   326  		return;
   327  	switch(s->class) {
   328  	case CAUTO:
   329  	case CPARAM:
   330  		s2 = acidfun(thisfn);
   331  		if(s2)
   332  			Bprint(&outbuf, "complex %s %s:%s;\n",
   333  				amap(s1->name), amap(s2->name), amap(s->name));
   334  		break;
   335  	
   336  	case CSTATIC:
   337  	case CEXTERN:
   338  	case CGLOBL:
   339  	case CLOCAL:
   340  		Bprint(&outbuf, "complex %s %s;\n",
   341  			amap(s1->name), amap(s->name));
   342  		break;
   343  	}
   344  }