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 }