github.com/xushiwei/go@v0.0.0-20130601165731-2b9d83f45bc9/src/cmd/cc/godefs.c (about)

     1  //   cmd/cc/godefs.cc
     2  //
     3  //   derived from pickle.cc which itself was derived from acid.cc.
     4  //
     5  //	Copyright © 1994-1999 Lucent Technologies Inc. All rights reserved.
     6  //	Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net)
     7  //	Portions Copyright © 1997-1999 Vita Nuova Limited
     8  //	Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com)
     9  //	Portions Copyright © 2004,2006 Bruce Ellis
    10  //	Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net)
    11  //	Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others
    12  //	Portions Copyright © 2009-2011 The Go Authors.	All rights reserved.
    13  //
    14  // Permission is hereby granted, free of charge, to any person obtaining a copy
    15  // of this software and associated documentation files (the "Software"), to deal
    16  // in the Software without restriction, including without limitation the rights
    17  // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
    18  // copies of the Software, and to permit persons to whom the Software is
    19  // furnished to do so, subject to the following conditions:
    20  //
    21  // The above copyright notice and this permission notice shall be included in
    22  // all copies or substantial portions of the Software.
    23  //
    24  // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
    25  // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
    26  // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
    27  // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
    28  // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
    29  // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
    30  // THE SOFTWARE.
    31  
    32  #include <u.h>
    33  #include "cc.h"
    34  
    35  static int upper;
    36  
    37  static char *kwd[] =
    38  {
    39  	"_bool",
    40  	"_break",
    41  	"_byte",
    42  	"_case",
    43  	"_chan",
    44  	"_complex128",
    45  	"_complex64",
    46  	"_const",
    47  	"_continue",
    48  	"_default",
    49  	"_defer",
    50  	"_else",
    51  	"_fallthrough",
    52  	"_false",
    53  	"_float32",
    54  	"_float64",
    55  	"_for",
    56  	"_func",
    57  	"_go",
    58  	"_goto",
    59  	"_if",
    60  	"_import",
    61  	"_int",
    62  	"_int16",
    63  	"_int32",
    64  	"_int64",
    65  	"_int8",
    66  	"_interface",
    67  	"_intptr",
    68  	"_map",
    69  	"_package",
    70  	"_panic",
    71  	"_range",
    72  	"_return",
    73  	"_select",
    74  	"_string",
    75  	"_struct",
    76  	"_switch",
    77  	"_true",
    78  	"_type",
    79  	"_uint",
    80  	"_uint16",
    81  	"_uint32",
    82  	"_uint64",
    83  	"_uint8",
    84  	"_uintptr",
    85  	"_var",
    86  };
    87  
    88  static char*
    89  pmap(char *s)
    90  {
    91  	int i, bot, top, mid;
    92  
    93  	bot = -1;
    94  	top = nelem(kwd);
    95  	while(top - bot > 1){
    96  		mid = (bot + top) / 2;
    97  		i = strcmp(kwd[mid]+1, s);
    98  		if(i == 0)
    99  			return kwd[mid];
   100  		if(i < 0)
   101  			bot = mid;
   102  		else
   103  			top = mid;
   104  	}
   105  
   106  	return s;
   107  }
   108  
   109  
   110  int
   111  Uconv(Fmt *fp)
   112  {
   113  	char str[STRINGSZ+1];
   114  	char *s, *n;
   115  	int i;
   116  
   117  	str[0] = 0;
   118  	s = va_arg(fp->args, char*);
   119  
   120  	// strip package name
   121  	n = strrchr(s, '.');
   122  	if(n != nil)
   123  		s = n + 1;
   124  
   125  	if(s && *s) {
   126  		if(upper)
   127  			str[0] = toupper((uchar)*s);
   128  		else
   129  			str[0] = tolower((uchar)*s);
   130  		for(i = 1; i < STRINGSZ && s[i] != 0; i++)
   131  			str[i] = tolower((uchar)s[i]);
   132  		str[i] = 0;
   133  	}
   134  
   135  	return fmtstrcpy(fp, pmap(str));
   136  }
   137  
   138  
   139  static Sym*
   140  findsue(Type *t)
   141  {
   142  	int h;
   143  	Sym *s;
   144  
   145  	if(t != T)
   146  	for(h=0; h<nelem(hash); h++)
   147  		for(s = hash[h]; s != S; s = s->link)
   148  			if(s->suetag && s->suetag->link == t)
   149  				return s;
   150  	return 0;
   151  }
   152  
   153  static void
   154  printtypename(Type *t)
   155  {
   156  	Sym *s;
   157  	Type *t1;
   158  	int w;
   159  	char *n;
   160  
   161  	for( ; t != nil; t = t->link) {
   162  		switch(t->etype) {
   163  		case TIND:
   164  			// Special handling of *void.
   165  			if(t->link != nil && t->link->etype==TVOID) {
   166  				Bprint(&outbuf, "unsafe.Pointer");
   167  				return;
   168  			}
   169  			// *func == func
   170  			if(t->link != nil && t->link->etype==TFUNC)
   171  				continue;
   172  			Bprint(&outbuf, "*");
   173  			continue;
   174  		case TARRAY:
   175  			w = t->width;
   176  			if(t->link && t->link->width)
   177  				w /= t->link->width;
   178  			Bprint(&outbuf, "[%d]", w);
   179  			continue;
   180  		}
   181  		break;
   182  	}
   183  
   184  	if(t == nil) {
   185  		Bprint(&outbuf, "bad // should not happen");
   186  		return;
   187  	}
   188  
   189  	switch(t->etype) {
   190  	case TINT:
   191  		Bprint(&outbuf, "int32");
   192  		break;
   193  	case TUINT:
   194  		Bprint(&outbuf, "uint32");
   195  		break;
   196  	case TCHAR:
   197  		Bprint(&outbuf, "int8");
   198  		break;
   199  	case TUCHAR:
   200  		Bprint(&outbuf, "uint8");
   201  		break;
   202  	case TSHORT:
   203  		Bprint(&outbuf, "int16");
   204  		break;
   205  	case TUSHORT:
   206  		Bprint(&outbuf, "uint16");
   207  		break;
   208  	case TLONG:
   209  		Bprint(&outbuf, "int32");
   210  		break;
   211  	case TULONG:
   212  		Bprint(&outbuf, "uint32");
   213  		break;
   214  	case TVLONG:
   215  		Bprint(&outbuf, "int64");
   216  		break;
   217  	case TUVLONG:
   218  		Bprint(&outbuf, "uint64");
   219  		break;
   220  	case TFLOAT:
   221  		Bprint(&outbuf, "float32");
   222  		break;
   223  	case TDOUBLE:
   224  		Bprint(&outbuf, "float64");
   225  		break;
   226  	case TUNION:
   227  	case TSTRUCT:
   228  		s = findsue(t->link);
   229  		n = "bad";
   230  		if(s != S)
   231  			n = s->name;
   232  		else if(t->tag)
   233  			n = t->tag->name;
   234  		if(strcmp(n, "String") == 0){
   235  			Bprint(&outbuf, "string");
   236  		} else if(strcmp(n, "Slice") == 0){
   237  			Bprint(&outbuf, "[]byte");
   238  		} else
   239  			Bprint(&outbuf, "%U", n);
   240  		break;
   241  	case TFUNC:
   242  		Bprint(&outbuf, "func(");
   243  		for(t1 = t->down; t1 != T; t1 = t1->down) {
   244  			if(t1->etype == TVOID)
   245  				break;
   246  			if(t1 != t->down)
   247  				Bprint(&outbuf, ", ");
   248  			printtypename(t1);
   249  		}
   250  		Bprint(&outbuf, ")");
   251  		if(t->link && t->link->etype != TVOID) {
   252  			Bprint(&outbuf, " ");
   253  			printtypename(t->link);
   254  		}
   255  		break;
   256  	case TDOT:
   257  		Bprint(&outbuf, "...interface{}");
   258  		break;
   259  	default:
   260  		Bprint(&outbuf, " weird<%T>", t);
   261  	}
   262  }
   263  
   264  static int
   265  dontrun(void)
   266  {
   267  	Io *i;
   268  	int n;
   269  
   270  	if(!debug['q'] && !debug['Q'])
   271  		return 1;
   272  	if(debug['q'] + debug['Q'] > 1) {
   273  		n = 0;
   274  		for(i=iostack; i; i=i->link)
   275  			n++;
   276  		if(n > 1)
   277  			return 1;
   278  	}
   279  
   280  	upper = debug['Q'];
   281  	return 0;
   282  }
   283  
   284  void
   285  godeftype(Type *t)
   286  {
   287  	Sym *s;
   288  	Type *l;
   289  	int gotone;
   290  
   291  	if(dontrun())
   292  		return;
   293  
   294  	switch(t->etype) {
   295  	case TUNION:
   296  	case TSTRUCT:
   297  		s = findsue(t->link);
   298  		if(s == S) {
   299  			Bprint(&outbuf, "/* can't find %T */\n\n", t);
   300  			return;
   301  		}
   302  
   303  		gotone = 0; // for unions, take first member of size equal to union
   304  		Bprint(&outbuf, "type %U struct {\n", s->name);
   305  		for(l = t->link; l != T; l = l->down) {
   306  			Bprint(&outbuf, "\t");
   307  			if(t->etype == TUNION) {
   308  				if(!gotone && l->width == t->width)
   309  					gotone = 1;
   310  				else
   311  					Bprint(&outbuf, "// (union)\t");
   312  			}
   313  			if(l->sym != nil)  // not anonymous field
   314  				Bprint(&outbuf, "%U\t", l->sym->name);
   315  			printtypename(l);
   316  			Bprint(&outbuf, "\n");
   317  		}
   318  		Bprint(&outbuf, "}\n\n");
   319  		break;
   320  
   321  	default:
   322  		Bprint(&outbuf, "/* %T */\n\n", t);
   323  		break;
   324  	}
   325  }
   326  
   327  void
   328  godefvar(Sym *s)
   329  {
   330  	Type *t, *t1;
   331  	char n;
   332  
   333  	if(dontrun())
   334  		return;
   335  
   336  	t = s->type;
   337  	if(t == nil)
   338  		return;
   339  
   340  	switch(t->etype) {
   341  	case TENUM:
   342  		if(!typefd[t->etype])
   343  			Bprint(&outbuf, "const %U = %lld\n", s->name, s->vconst);
   344  		else
   345  			Bprint(&outbuf, "const %U = %f\n;", s->name, s->fconst);
   346  		break;
   347  
   348  	case TFUNC:
   349  		Bprint(&outbuf, "func %U(", s->name);
   350  		n = 'a';
   351  		for(t1 = t->down; t1 != T; t1 = t1->down) {
   352  			if(t1->etype == TVOID)
   353  				break;
   354  			if(t1 != t->down)
   355  				Bprint(&outbuf, ", ");
   356  			Bprint(&outbuf, "%c ", n++);
   357  			printtypename(t1);
   358  		}
   359  		Bprint(&outbuf, ")");
   360  		if(t->link && t->link->etype != TVOID) {
   361  			Bprint(&outbuf, " ");
   362  			printtypename(t->link);
   363  		}
   364  		Bprint(&outbuf, "\n");
   365  		break;
   366  
   367  	default:
   368  		switch(s->class) {
   369  		case CTYPEDEF:
   370  			if(!typesu[t->etype]) {
   371  				Bprint(&outbuf, "// type %U\t", s->name);
   372  				printtypename(t);
   373  				Bprint(&outbuf, "\n");
   374  			}
   375  			break;
   376  		case CSTATIC:
   377  		case CEXTERN:
   378  		case CGLOBL:
   379  			if(strchr(s->name, '$') != nil)	 // TODO(lvd)
   380  			    break;
   381  			Bprint(&outbuf, "var %U\t", s->name);
   382  			printtypename(t);
   383  			Bprint(&outbuf, "\n");
   384  			break;
   385  		}
   386  		break;
   387  	}
   388  }