github.com/golang-haiku/go-1.4.3@v0.0.0-20190609233734-1f5ae41cc308/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 }