github.com/razvanm/vanadium-go-1.3@v0.0.0-20160721203343-4a65068e5915/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  	int w;
   158  	char *n;
   159  
   160  	for( ; t != nil; t = t->link) {
   161  		switch(t->etype) {
   162  		case TIND:
   163  			// Special handling of *void.
   164  			if(t->link != nil && t->link->etype==TVOID) {
   165  				Bprint(&outbuf, "unsafe.Pointer");
   166  				return;
   167  			}
   168  			// *func == func
   169  			if(t->link != nil && t->link->etype==TFUNC)
   170  				continue;
   171  			Bprint(&outbuf, "*");
   172  			continue;
   173  		case TARRAY:
   174  			w = t->width;
   175  			if(t->link && t->link->width)
   176  				w /= t->link->width;
   177  			Bprint(&outbuf, "[%d]", w);
   178  			continue;
   179  		}
   180  		break;
   181  	}
   182  
   183  	if(t == nil) {
   184  		Bprint(&outbuf, "bad // should not happen");
   185  		return;
   186  	}
   187  
   188  	switch(t->etype) {
   189  	case TINT:
   190  	case TUINT:
   191  	case TCHAR:
   192  	case TUCHAR:
   193  	case TSHORT:
   194  	case TUSHORT:
   195  	case TLONG:
   196  	case TULONG:
   197  	case TVLONG:
   198  	case TUVLONG:
   199  	case TFLOAT:
   200  	case TDOUBLE:
   201  		// All names used in the runtime code should be typedefs.
   202  		if(t->tag != nil) {
   203  			if(strcmp(t->tag->name, "intgo") == 0)
   204  				Bprint(&outbuf, "int");
   205  			else if(strcmp(t->tag->name, "uintgo") == 0)
   206  				Bprint(&outbuf, "uint");
   207  			else
   208  				Bprint(&outbuf, "%s", t->tag->name);
   209  		} else	
   210  			Bprint(&outbuf, "C.%T", t);
   211  		break;
   212  	case TUNION:
   213  	case TSTRUCT:
   214  		s = findsue(t->link);
   215  		n = "bad";
   216  		if(s != S)
   217  			n = s->name;
   218  		else if(t->tag)
   219  			n = t->tag->name;
   220  		if(strcmp(n, "String") == 0)
   221  			Bprint(&outbuf, "string");
   222  		else if(strcmp(n, "Slice") == 0)
   223  			Bprint(&outbuf, "[]byte");
   224  		else if(strcmp(n, "Eface") == 0)
   225  			Bprint(&outbuf, "interface{}");
   226  		else
   227  			Bprint(&outbuf, "%U", n);
   228  		break;
   229  	case TFUNC:
   230  		// There's no equivalent to a C function in the Go world.
   231  		Bprint(&outbuf, "unsafe.Pointer");
   232  		break;
   233  	case TDOT:
   234  		Bprint(&outbuf, "...interface{}");
   235  		break;
   236  	default:
   237  		Bprint(&outbuf, " weird<%T>", t);
   238  	}
   239  }
   240  
   241  static int
   242  dontrun(void)
   243  {
   244  	Io *i;
   245  	int n;
   246  
   247  	if(!debug['q'] && !debug['Q'])
   248  		return 1;
   249  	if(debug['q'] + debug['Q'] > 1) {
   250  		n = 0;
   251  		for(i=iostack; i; i=i->link)
   252  			n++;
   253  		if(n > 1)
   254  			return 1;
   255  	}
   256  
   257  	upper = debug['Q'];
   258  	return 0;
   259  }
   260  
   261  void
   262  godeftype(Type *t)
   263  {
   264  	Sym *s;
   265  	Type *l;
   266  	int gotone;
   267  
   268  	if(dontrun())
   269  		return;
   270  
   271  	switch(t->etype) {
   272  	case TUNION:
   273  	case TSTRUCT:
   274  		s = findsue(t->link);
   275  		if(s == S) {
   276  			Bprint(&outbuf, "/* can't find %T */\n\n", t);
   277  			return;
   278  		}
   279  
   280  		gotone = 0; // for unions, take first member of size equal to union
   281  		Bprint(&outbuf, "type %U struct {\n", s->name);
   282  		for(l = t->link; l != T; l = l->down) {
   283  			Bprint(&outbuf, "\t");
   284  			if(t->etype == TUNION) {
   285  				if(!gotone && l->width == t->width)
   286  					gotone = 1;
   287  				else
   288  					Bprint(&outbuf, "// (union)\t");
   289  			}
   290  			if(l->sym != nil)  // not anonymous field
   291  				Bprint(&outbuf, "%U\t", l->sym->name);
   292  			printtypename(l);
   293  			Bprint(&outbuf, "\n");
   294  		}
   295  		Bprint(&outbuf, "}\n\n");
   296  		break;
   297  
   298  	default:
   299  		Bprint(&outbuf, "/* %T */\n\n", t);
   300  		break;
   301  	}
   302  }
   303  
   304  void
   305  godefvar(Sym *s)
   306  {
   307  	Type *t, *t1;
   308  	char n;
   309  
   310  	if(dontrun())
   311  		return;
   312  
   313  	t = s->type;
   314  	if(t == nil)
   315  		return;
   316  
   317  	switch(t->etype) {
   318  	case TENUM:
   319  		if(!typefd[t->etype])
   320  			Bprint(&outbuf, "const %s = %lld\n", s->name, s->vconst);
   321  		else
   322  			Bprint(&outbuf, "const %s = %f\n;", s->name, s->fconst);
   323  		break;
   324  
   325  	case TFUNC:
   326  		Bprint(&outbuf, "func %U(", s->name);
   327  		n = 'a';
   328  		for(t1 = t->down; t1 != T; t1 = t1->down) {
   329  			if(t1->etype == TVOID)
   330  				break;
   331  			if(t1 != t->down)
   332  				Bprint(&outbuf, ", ");
   333  			Bprint(&outbuf, "%c ", n++);
   334  			printtypename(t1);
   335  		}
   336  		Bprint(&outbuf, ")");
   337  		if(t->link && t->link->etype != TVOID) {
   338  			Bprint(&outbuf, " ");
   339  			printtypename(t->link);
   340  		}
   341  		Bprint(&outbuf, "\n");
   342  		break;
   343  
   344  	default:
   345  		switch(s->class) {
   346  		case CTYPEDEF:
   347  			if(!typesu[t->etype]) {
   348  				Bprint(&outbuf, "// type %U\t", s->name);
   349  				printtypename(t);
   350  				Bprint(&outbuf, "\n");
   351  			}
   352  			break;
   353  		case CSTATIC:
   354  		case CEXTERN:
   355  		case CGLOBL:
   356  			if(strchr(s->name, '$') != nil)
   357  				break;
   358  			if(strncmp(s->name, "go.weak.", 8) == 0)
   359  				break;
   360  			Bprint(&outbuf, "var %U\t", s->name);
   361  			printtypename(t);
   362  			Bprint(&outbuf, "\n");
   363  			break;
   364  		}
   365  		break;
   366  	}
   367  }