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 }