github.com/xushiwei/go@v0.0.0-20130601165731-2b9d83f45bc9/src/cmd/gc/fmt.c (about) 1 // Copyright 2011 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 #include <u.h> 6 #include <libc.h> 7 #include "go.h" 8 #include "opnames.h" 9 10 // 11 // Format conversions 12 // %L int Line numbers 13 // 14 // %E int etype values (aka 'Kind') 15 // 16 // %O int Node Opcodes 17 // Flags: "%#O": print go syntax. (automatic unless fmtmode == FDbg) 18 // 19 // %J Node* Node details 20 // Flags: "%hJ" supresses things not relevant until walk. 21 // 22 // %V Val* Constant values 23 // 24 // %S Sym* Symbols 25 // Flags: +,- #: mode (see below) 26 // "%hS" unqualified identifier in any mode 27 // "%hhS" in export mode: unqualified identifier if exported, qualified if not 28 // 29 // %T Type* Types 30 // Flags: +,- #: mode (see below) 31 // 'l' definition instead of name. 32 // 'h' omit "func" and receiver in function types 33 // 'u' (only in -/Sym mode) print type identifiers wit package name instead of prefix. 34 // 35 // %N Node* Nodes 36 // Flags: +,- #: mode (see below) 37 // 'h' (only in +/debug mode) suppress recursion 38 // 'l' (only in Error mode) print "foo (type Bar)" 39 // 40 // %H NodeList* NodeLists 41 // Flags: those of %N 42 // ',' separate items with ',' instead of ';' 43 // 44 // %Z Strlit* String literals 45 // 46 // In mparith1.c: 47 // %B Mpint* Big integers 48 // %F Mpflt* Big floats 49 // 50 // %S, %T and %N obey use the following flags to set the format mode: 51 enum { 52 FErr, // error mode (default) 53 FDbg, // "%+N" debug mode 54 FExp, // "%#N" export mode 55 FTypeId, // "%-N" turning-types-into-symbols-mode: identical types give identical strings 56 }; 57 static int fmtmode; 58 static int fmtpkgpfx; // %uT stickyness 59 // 60 // E.g. for %S: %+S %#S %-S print an identifier properly qualified for debug/export/internal mode. 61 // 62 // The mode flags +, - and # are sticky, meaning they persist through 63 // recursions of %N, %T and %S, but not the h and l flags. The u flag is 64 // sticky only on %T recursions and only used in %-/Sym mode. 65 66 // 67 // Useful format combinations: 68 // 69 // %+N %+H multiline recursive debug dump of node/nodelist 70 // %+hN %+hH non recursive debug dump 71 // 72 // %#N %#T export format 73 // %#lT type definition instead of name 74 // %#hT omit"func" and receiver in function signature 75 // 76 // %lN "foo (type Bar)" for error messages 77 // 78 // %-T type identifiers 79 // %-hT type identifiers without "func" and arg names in type signatures (methodsym) 80 // %-uT type identifiers with package name instead of prefix (typesym, dcommontype, typehash) 81 // 82 83 84 static int 85 setfmode(unsigned long *flags) 86 { 87 int fm; 88 89 fm = fmtmode; 90 if(*flags & FmtSign) 91 fmtmode = FDbg; 92 else if(*flags & FmtSharp) 93 fmtmode = FExp; 94 else if(*flags & FmtLeft) 95 fmtmode = FTypeId; 96 97 *flags &= ~(FmtSharp|FmtLeft|FmtSign); 98 return fm; 99 } 100 101 // Fmt "%L": Linenumbers 102 static int 103 Lconv(Fmt *fp) 104 { 105 struct 106 { 107 Hist* incl; /* start of this include file */ 108 int32 idel; /* delta line number to apply to include */ 109 Hist* line; /* start of this #line directive */ 110 int32 ldel; /* delta line number to apply to #line */ 111 } a[HISTSZ]; 112 int32 lno, d; 113 int i, n; 114 Hist *h; 115 116 lno = va_arg(fp->args, int32); 117 118 n = 0; 119 for(h=hist; h!=H; h=h->link) { 120 if(h->offset < 0) 121 continue; 122 if(lno < h->line) 123 break; 124 if(h->name) { 125 if(h->offset > 0) { 126 // #line directive 127 if(n > 0 && n < HISTSZ) { 128 a[n-1].line = h; 129 a[n-1].ldel = h->line - h->offset + 1; 130 } 131 } else { 132 // beginning of file 133 if(n < HISTSZ) { 134 a[n].incl = h; 135 a[n].idel = h->line; 136 a[n].line = 0; 137 } 138 n++; 139 } 140 continue; 141 } 142 n--; 143 if(n > 0 && n < HISTSZ) { 144 d = h->line - a[n].incl->line; 145 a[n-1].ldel += d; 146 a[n-1].idel += d; 147 } 148 } 149 150 if(n > HISTSZ) 151 n = HISTSZ; 152 153 for(i=n-1; i>=0; i--) { 154 if(i != n-1) { 155 if(fp->flags & ~(FmtWidth|FmtPrec)) 156 break; 157 fmtprint(fp, " "); 158 } 159 if(debug['L'] || (fp->flags&FmtLong)) 160 fmtprint(fp, "%s/", pathname); 161 if(a[i].line) 162 fmtprint(fp, "%s:%d[%s:%d]", 163 a[i].line->name, lno-a[i].ldel+1, 164 a[i].incl->name, lno-a[i].idel+1); 165 else 166 fmtprint(fp, "%s:%d", 167 a[i].incl->name, lno-a[i].idel+1); 168 lno = a[i].incl->line - 1; // now print out start of this file 169 } 170 if(n == 0) 171 fmtprint(fp, "<unknown line number>"); 172 173 return 0; 174 } 175 176 static char* 177 goopnames[] = 178 { 179 [OADDR] = "&", 180 [OADD] = "+", 181 [OADDSTR] = "+", 182 [OANDAND] = "&&", 183 [OANDNOT] = "&^", 184 [OAND] = "&", 185 [OAPPEND] = "append", 186 [OAS] = "=", 187 [OAS2] = "=", 188 [OBREAK] = "break", 189 [OCALL] = "function call", // not actual syntax 190 [OCAP] = "cap", 191 [OCASE] = "case", 192 [OCLOSE] = "close", 193 [OCOMPLEX] = "complex", 194 [OCOM] = "^", 195 [OCONTINUE] = "continue", 196 [OCOPY] = "copy", 197 [ODEC] = "--", 198 [ODELETE] = "delete", 199 [ODEFER] = "defer", 200 [ODIV] = "/", 201 [OEQ] = "==", 202 [OFALL] = "fallthrough", 203 [OFOR] = "for", 204 [OGE] = ">=", 205 [OGOTO] = "goto", 206 [OGT] = ">", 207 [OIF] = "if", 208 [OIMAG] = "imag", 209 [OINC] = "++", 210 [OIND] = "*", 211 [OLEN] = "len", 212 [OLE] = "<=", 213 [OLSH] = "<<", 214 [OLT] = "<", 215 [OMAKE] = "make", 216 [OMINUS] = "-", 217 [OMOD] = "%", 218 [OMUL] = "*", 219 [ONEW] = "new", 220 [ONE] = "!=", 221 [ONOT] = "!", 222 [OOROR] = "||", 223 [OOR] = "|", 224 [OPANIC] = "panic", 225 [OPLUS] = "+", 226 [OPRINTN] = "println", 227 [OPRINT] = "print", 228 [ORANGE] = "range", 229 [OREAL] = "real", 230 [ORECV] = "<-", 231 [ORECOVER] = "recover", 232 [ORETURN] = "return", 233 [ORSH] = ">>", 234 [OSELECT] = "select", 235 [OSEND] = "<-", 236 [OSUB] = "-", 237 [OSWITCH] = "switch", 238 [OXOR] = "^", 239 }; 240 241 // Fmt "%O": Node opcodes 242 static int 243 Oconv(Fmt *fp) 244 { 245 int o; 246 247 o = va_arg(fp->args, int); 248 if((fp->flags & FmtSharp) || fmtmode != FDbg) 249 if(o >= 0 && o < nelem(goopnames) && goopnames[o] != nil) 250 return fmtstrcpy(fp, goopnames[o]); 251 252 if(o >= 0 && o < nelem(opnames) && opnames[o] != nil) 253 return fmtstrcpy(fp, opnames[o]); 254 255 return fmtprint(fp, "O-%d", o); 256 } 257 258 static const char* classnames[] = { 259 "Pxxx", 260 "PEXTERN", 261 "PAUTO", 262 "PPARAM", 263 "PPARAMOUT", 264 "PPARAMREF", 265 "PFUNC", 266 }; 267 268 // Fmt "%J": Node details. 269 static int 270 Jconv(Fmt *fp) 271 { 272 Node *n; 273 char *s; 274 int c; 275 276 n = va_arg(fp->args, Node*); 277 278 c = fp->flags&FmtShort; 279 280 if(!c && n->ullman != 0) 281 fmtprint(fp, " u(%d)", n->ullman); 282 283 if(!c && n->addable != 0) 284 fmtprint(fp, " a(%d)", n->addable); 285 286 if(!c && n->vargen != 0) 287 fmtprint(fp, " g(%d)", n->vargen); 288 289 if(n->lineno != 0) 290 fmtprint(fp, " l(%d)", n->lineno); 291 292 if(!c && n->xoffset != BADWIDTH) 293 fmtprint(fp, " x(%lld%+lld)", n->xoffset, n->stkdelta); 294 295 if(n->class != 0) { 296 s = ""; 297 if(n->class & PHEAP) s = ",heap"; 298 if((n->class & ~PHEAP) < nelem(classnames)) 299 fmtprint(fp, " class(%s%s)", classnames[n->class&~PHEAP], s); 300 else 301 fmtprint(fp, " class(%d?%s)", n->class&~PHEAP, s); 302 } 303 304 if(n->colas != 0) 305 fmtprint(fp, " colas(%d)", n->colas); 306 307 if(n->funcdepth != 0) 308 fmtprint(fp, " f(%d)", n->funcdepth); 309 310 switch(n->esc) { 311 case EscUnknown: 312 break; 313 case EscHeap: 314 fmtprint(fp, " esc(h)"); 315 break; 316 case EscScope: 317 fmtprint(fp, " esc(s)"); 318 break; 319 case EscNone: 320 fmtprint(fp, " esc(no)"); 321 break; 322 case EscNever: 323 if(!c) 324 fmtprint(fp, " esc(N)"); 325 break; 326 default: 327 fmtprint(fp, " esc(%d)", n->esc); 328 break; 329 } 330 331 if(n->escloopdepth) 332 fmtprint(fp, " ld(%d)", n->escloopdepth); 333 334 if(!c && n->typecheck != 0) 335 fmtprint(fp, " tc(%d)", n->typecheck); 336 337 if(!c && n->dodata != 0) 338 fmtprint(fp, " dd(%d)", n->dodata); 339 340 if(n->isddd != 0) 341 fmtprint(fp, " isddd(%d)", n->isddd); 342 343 if(n->implicit != 0) 344 fmtprint(fp, " implicit(%d)", n->implicit); 345 346 if(n->embedded != 0) 347 fmtprint(fp, " embedded(%d)", n->embedded); 348 349 if(!c && n->used != 0) 350 fmtprint(fp, " used(%d)", n->used); 351 return 0; 352 } 353 354 // Fmt "%V": Values 355 static int 356 Vconv(Fmt *fp) 357 { 358 Val *v; 359 vlong x; 360 361 v = va_arg(fp->args, Val*); 362 363 switch(v->ctype) { 364 case CTINT: 365 if((fp->flags & FmtSharp) || fmtmode == FExp) 366 return fmtprint(fp, "%#B", v->u.xval); 367 return fmtprint(fp, "%B", v->u.xval); 368 case CTRUNE: 369 x = mpgetfix(v->u.xval); 370 if(' ' <= x && x < 0x80 && x != '\\' && x != '\'') 371 return fmtprint(fp, "'%c'", (int)x); 372 if(0 <= x && x < (1<<16)) 373 return fmtprint(fp, "'\\u%04ux'", (int)x); 374 if(0 <= x && x <= Runemax) 375 return fmtprint(fp, "'\\U%08llux'", x); 376 return fmtprint(fp, "('\\x00' + %B)", v->u.xval); 377 case CTFLT: 378 if((fp->flags & FmtSharp) || fmtmode == FExp) 379 return fmtprint(fp, "%F", v->u.fval); 380 return fmtprint(fp, "%#F", v->u.fval); 381 case CTCPLX: 382 if((fp->flags & FmtSharp) || fmtmode == FExp) 383 return fmtprint(fp, "(%F+%Fi)", &v->u.cval->real, &v->u.cval->imag); 384 if(mpcmpfltc(&v->u.cval->real, 0) == 0) 385 return fmtprint(fp, "%#Fi", &v->u.cval->imag); 386 if(mpcmpfltc(&v->u.cval->imag, 0) == 0) 387 return fmtprint(fp, "%#F", &v->u.cval->real); 388 if(mpcmpfltc(&v->u.cval->imag, 0) < 0) 389 return fmtprint(fp, "(%#F%#Fi)", &v->u.cval->real, &v->u.cval->imag); 390 return fmtprint(fp, "(%#F+%#Fi)", &v->u.cval->real, &v->u.cval->imag); 391 case CTSTR: 392 return fmtprint(fp, "\"%Z\"", v->u.sval); 393 case CTBOOL: 394 if( v->u.bval) 395 return fmtstrcpy(fp, "true"); 396 return fmtstrcpy(fp, "false"); 397 case CTNIL: 398 return fmtstrcpy(fp, "nil"); 399 } 400 return fmtprint(fp, "<ctype=%d>", v->ctype); 401 } 402 403 // Fmt "%Z": escaped string literals 404 static int 405 Zconv(Fmt *fp) 406 { 407 Rune r; 408 Strlit *sp; 409 char *s, *se; 410 int n; 411 412 sp = va_arg(fp->args, Strlit*); 413 if(sp == nil) 414 return fmtstrcpy(fp, "<nil>"); 415 416 s = sp->s; 417 se = s + sp->len; 418 while(s < se) { 419 n = chartorune(&r, s); 420 s += n; 421 switch(r) { 422 case Runeerror: 423 if(n == 1) { 424 fmtprint(fp, "\\x%02x", (uchar)*(s-1)); 425 break; 426 } 427 // fall through 428 default: 429 if(r < ' ') { 430 fmtprint(fp, "\\x%02x", r); 431 break; 432 } 433 fmtrune(fp, r); 434 break; 435 case '\t': 436 fmtstrcpy(fp, "\\t"); 437 break; 438 case '\n': 439 fmtstrcpy(fp, "\\n"); 440 break; 441 case '\"': 442 case '\\': 443 fmtrune(fp, '\\'); 444 fmtrune(fp, r); 445 break; 446 case 0xFEFF: // BOM, basically disallowed in source code 447 fmtstrcpy(fp, "\\uFEFF"); 448 break; 449 } 450 } 451 return 0; 452 } 453 454 /* 455 s%,%,\n%g 456 s%\n+%\n%g 457 s%^[ ]*T%%g 458 s%,.*%%g 459 s%.+% [T&] = "&",%g 460 s%^ ........*\]%&~%g 461 s%~ %%g 462 */ 463 464 static char* 465 etnames[] = 466 { 467 [TINT] = "INT", 468 [TUINT] = "UINT", 469 [TINT8] = "INT8", 470 [TUINT8] = "UINT8", 471 [TINT16] = "INT16", 472 [TUINT16] = "UINT16", 473 [TINT32] = "INT32", 474 [TUINT32] = "UINT32", 475 [TINT64] = "INT64", 476 [TUINT64] = "UINT64", 477 [TUINTPTR] = "UINTPTR", 478 [TFLOAT32] = "FLOAT32", 479 [TFLOAT64] = "FLOAT64", 480 [TCOMPLEX64] = "COMPLEX64", 481 [TCOMPLEX128] = "COMPLEX128", 482 [TBOOL] = "BOOL", 483 [TPTR32] = "PTR32", 484 [TPTR64] = "PTR64", 485 [TFUNC] = "FUNC", 486 [TARRAY] = "ARRAY", 487 [TSTRUCT] = "STRUCT", 488 [TCHAN] = "CHAN", 489 [TMAP] = "MAP", 490 [TINTER] = "INTER", 491 [TFORW] = "FORW", 492 [TFIELD] = "FIELD", 493 [TSTRING] = "STRING", 494 [TANY] = "ANY", 495 }; 496 497 // Fmt "%E": etype 498 static int 499 Econv(Fmt *fp) 500 { 501 int et; 502 503 et = va_arg(fp->args, int); 504 if(et >= 0 && et < nelem(etnames) && etnames[et] != nil) 505 return fmtstrcpy(fp, etnames[et]); 506 return fmtprint(fp, "E-%d", et); 507 } 508 509 // Fmt "%S": syms 510 static int 511 symfmt(Fmt *fp, Sym *s) 512 { 513 char *p; 514 515 if(s->pkg && !(fp->flags&FmtShort)) { 516 switch(fmtmode) { 517 case FErr: // This is for the user 518 if(s->pkg == localpkg) 519 return fmtstrcpy(fp, s->name); 520 // If the name was used by multiple packages, display the full path, 521 if(s->pkg->name && pkglookup(s->pkg->name, nil)->npkg > 1) 522 return fmtprint(fp, "\"%Z\".%s", s->pkg->path, s->name); 523 return fmtprint(fp, "%s.%s", s->pkg->name, s->name); 524 case FDbg: 525 return fmtprint(fp, "%s.%s", s->pkg->name, s->name); 526 case FTypeId: 527 if(fp->flags&FmtUnsigned) 528 return fmtprint(fp, "%s.%s", s->pkg->name, s->name); // dcommontype, typehash 529 return fmtprint(fp, "%s.%s", s->pkg->prefix, s->name); // (methodsym), typesym, weaksym 530 case FExp: 531 if(s->name && s->name[0] == '.') 532 fatal("exporting synthetic symbol %s", s->name); 533 if(s->pkg != builtinpkg) 534 return fmtprint(fp, "@\"%Z\".%s", s->pkg->path, s->name); 535 } 536 } 537 538 if(fp->flags&FmtByte) { // FmtByte (hh) implies FmtShort (h) 539 // skip leading "type." in method name 540 p = utfrrune(s->name, '.'); 541 if(p) 542 p++; 543 else 544 p = s->name; 545 546 // exportname needs to see the name without the prefix too. 547 if((fmtmode == FExp && !exportname(p)) || fmtmode == FDbg) 548 return fmtprint(fp, "@\"%Z\".%s", s->pkg->path, p); 549 550 return fmtstrcpy(fp, p); 551 } 552 553 return fmtstrcpy(fp, s->name); 554 } 555 556 static char* 557 basicnames[] = 558 { 559 [TINT] = "int", 560 [TUINT] = "uint", 561 [TINT8] = "int8", 562 [TUINT8] = "uint8", 563 [TINT16] = "int16", 564 [TUINT16] = "uint16", 565 [TINT32] = "int32", 566 [TUINT32] = "uint32", 567 [TINT64] = "int64", 568 [TUINT64] = "uint64", 569 [TUINTPTR] = "uintptr", 570 [TFLOAT32] = "float32", 571 [TFLOAT64] = "float64", 572 [TCOMPLEX64] = "complex64", 573 [TCOMPLEX128] = "complex128", 574 [TBOOL] = "bool", 575 [TANY] = "any", 576 [TSTRING] = "string", 577 [TNIL] = "nil", 578 [TIDEAL] = "ideal", 579 [TBLANK] = "blank", 580 }; 581 582 static int 583 typefmt(Fmt *fp, Type *t) 584 { 585 Type *t1; 586 Sym *s; 587 588 if(t == T) 589 return fmtstrcpy(fp, "<T>"); 590 591 if (t == bytetype || t == runetype) { 592 // in %-T mode collapse rune and byte with their originals. 593 if(fmtmode != FTypeId) 594 return fmtprint(fp, "%hS", t->sym); 595 t = types[t->etype]; 596 } 597 598 if(t == errortype) 599 return fmtstrcpy(fp, "error"); 600 601 // Unless the 'l' flag was specified, if the type has a name, just print that name. 602 if(!(fp->flags&FmtLong) && t->sym && t->etype != TFIELD && t != types[t->etype]) { 603 switch(fmtmode) { 604 case FTypeId: 605 if(fp->flags&FmtShort) 606 return fmtprint(fp, "%hS", t->sym); 607 if(fp->flags&FmtUnsigned) 608 return fmtprint(fp, "%uS", t->sym); 609 // fallthrough 610 case FExp: 611 if(t->sym->pkg == localpkg && t->vargen) 612 return fmtprint(fp, "%S·%d", t->sym, t->vargen); 613 break; 614 } 615 return fmtprint(fp, "%S", t->sym); 616 } 617 618 if(t->etype < nelem(basicnames) && basicnames[t->etype] != nil) { 619 if(fmtmode == FErr && (t == idealbool || t == idealstring)) 620 fmtstrcpy(fp, "ideal "); 621 return fmtstrcpy(fp, basicnames[t->etype]); 622 } 623 624 if(fmtmode == FDbg) 625 fmtprint(fp, "%E-", t->etype); 626 627 switch(t->etype) { 628 case TPTR32: 629 case TPTR64: 630 if(fmtmode == FTypeId && (fp->flags&FmtShort)) 631 return fmtprint(fp, "*%hT", t->type); 632 return fmtprint(fp, "*%T", t->type); 633 634 case TARRAY: 635 if(t->bound >= 0) 636 return fmtprint(fp, "[%lld]%T", t->bound, t->type); 637 if(t->bound == -100) 638 return fmtprint(fp, "[...]%T", t->type); 639 return fmtprint(fp, "[]%T", t->type); 640 641 case TCHAN: 642 switch(t->chan) { 643 case Crecv: 644 return fmtprint(fp, "<-chan %T", t->type); 645 case Csend: 646 return fmtprint(fp, "chan<- %T", t->type); 647 } 648 649 if(t->type != T && t->type->etype == TCHAN && t->type->sym == S && t->type->chan == Crecv) 650 return fmtprint(fp, "chan (%T)", t->type); 651 return fmtprint(fp, "chan %T", t->type); 652 653 case TMAP: 654 return fmtprint(fp, "map[%T]%T", t->down, t->type); 655 656 case TINTER: 657 fmtstrcpy(fp, "interface {"); 658 for(t1=t->type; t1!=T; t1=t1->down) 659 if(exportname(t1->sym->name)) { 660 if(t1->down) 661 fmtprint(fp, " %hS%hT;", t1->sym, t1->type); 662 else 663 fmtprint(fp, " %hS%hT ", t1->sym, t1->type); 664 } else { 665 // non-exported method names must be qualified 666 if(t1->down) 667 fmtprint(fp, " %uS%hT;", t1->sym, t1->type); 668 else 669 fmtprint(fp, " %uS%hT ", t1->sym, t1->type); 670 } 671 fmtstrcpy(fp, "}"); 672 return 0; 673 674 case TFUNC: 675 if(fp->flags & FmtShort) { 676 fmtprint(fp, "%T", getinargx(t)); 677 } else { 678 if(t->thistuple) 679 fmtprint(fp, "method%T func%T", getthisx(t), getinargx(t)); 680 else 681 fmtprint(fp, "func%T", getinargx(t)); 682 } 683 switch(t->outtuple) { 684 case 0: 685 break; 686 case 1: 687 if(fmtmode != FExp) { 688 fmtprint(fp, " %T", getoutargx(t)->type->type); // struct->field->field's type 689 break; 690 } 691 default: 692 fmtprint(fp, " %T", getoutargx(t)); 693 break; 694 } 695 return 0; 696 697 case TSTRUCT: 698 if(t->funarg) { 699 fmtstrcpy(fp, "("); 700 if(fmtmode == FTypeId || fmtmode == FErr) { // no argument names on function signature, and no "noescape" tags 701 for(t1=t->type; t1!=T; t1=t1->down) 702 if(t1->down) 703 fmtprint(fp, "%hT, ", t1); 704 else 705 fmtprint(fp, "%hT", t1); 706 } else { 707 for(t1=t->type; t1!=T; t1=t1->down) 708 if(t1->down) 709 fmtprint(fp, "%T, ", t1); 710 else 711 fmtprint(fp, "%T", t1); 712 } 713 fmtstrcpy(fp, ")"); 714 } else { 715 fmtstrcpy(fp, "struct {"); 716 for(t1=t->type; t1!=T; t1=t1->down) 717 if(t1->down) 718 fmtprint(fp, " %lT;", t1); 719 else 720 fmtprint(fp, " %lT ", t1); 721 fmtstrcpy(fp, "}"); 722 } 723 return 0; 724 725 case TFIELD: 726 if(!(fp->flags&FmtShort)) { 727 s = t->sym; 728 729 // Take the name from the original, lest we substituted it with ~anon%d 730 if ((fmtmode == FErr || fmtmode == FExp) && t->nname != N) { 731 if(t->nname->orig != N) { 732 s = t->nname->orig->sym; 733 if(s != S && s->name[0] == '~') 734 s = S; 735 } else 736 s = S; 737 } 738 739 if(s != S && !t->embedded) { 740 if(t->funarg) 741 fmtprint(fp, "%N ", t->nname); 742 else if(fp->flags&FmtLong) 743 fmtprint(fp, "%hhS ", s); // qualify non-exported names (used on structs, not on funarg) 744 else 745 fmtprint(fp, "%S ", s); 746 } else if(fmtmode == FExp) { 747 // TODO(rsc) this breaks on the eliding of unused arguments in the backend 748 // when this is fixed, the special case in dcl.c checkarglist can go. 749 //if(t->funarg) 750 // fmtstrcpy(fp, "_ "); 751 //else 752 fmtstrcpy(fp, "? "); 753 } 754 } 755 756 if(t->isddd) 757 fmtprint(fp, "...%T", t->type->type); 758 else 759 fmtprint(fp, "%T", t->type); 760 761 if(!(fp->flags&FmtShort) && t->note) 762 fmtprint(fp, " \"%Z\"", t->note); 763 return 0; 764 765 case TFORW: 766 if(t->sym) 767 return fmtprint(fp, "undefined %S", t->sym); 768 return fmtstrcpy(fp, "undefined"); 769 770 case TUNSAFEPTR: 771 if(fmtmode == FExp) 772 return fmtprint(fp, "@\"unsafe\".Pointer"); 773 return fmtprint(fp, "unsafe.Pointer"); 774 } 775 776 if(fmtmode == FExp) 777 fatal("missing %E case during export", t->etype); 778 // Don't know how to handle - fall back to detailed prints. 779 return fmtprint(fp, "%E <%S> %T", t->etype, t->sym, t->type); 780 } 781 782 // Statements which may be rendered with a simplestmt as init. 783 static int 784 stmtwithinit(int op) 785 { 786 switch(op) { 787 case OIF: 788 case OFOR: 789 case OSWITCH: 790 return 1; 791 } 792 return 0; 793 } 794 795 static int 796 stmtfmt(Fmt *f, Node *n) 797 { 798 int complexinit, simpleinit, extrablock; 799 800 // some statements allow for an init, but at most one, 801 // but we may have an arbitrary number added, eg by typecheck 802 // and inlining. If it doesn't fit the syntax, emit an enclosing 803 // block starting with the init statements. 804 805 // if we can just say "for" n->ninit; ... then do so 806 simpleinit = n->ninit && !n->ninit->next && !n->ninit->n->ninit && stmtwithinit(n->op); 807 // otherwise, print the inits as separate statements 808 complexinit = n->ninit && !simpleinit && (fmtmode != FErr); 809 // but if it was for if/for/switch, put in an extra surrounding block to limit the scope 810 extrablock = complexinit && stmtwithinit(n->op); 811 812 if(extrablock) 813 fmtstrcpy(f, "{"); 814 815 if(complexinit) 816 fmtprint(f, " %H; ", n->ninit); 817 818 switch(n->op){ 819 case ODCL: 820 if(fmtmode == FExp) { 821 switch(n->left->class&~PHEAP) { 822 case PPARAM: 823 case PPARAMOUT: 824 case PAUTO: 825 fmtprint(f, "var %N %T", n->left, n->left->type); 826 goto ret; 827 } 828 } 829 fmtprint(f, "var %S %T", n->left->sym, n->left->type); 830 break; 831 832 case ODCLFIELD: 833 if(n->left) 834 fmtprint(f, "%N %N", n->left, n->right); 835 else 836 fmtprint(f, "%N", n->right); 837 break; 838 839 case OAS: 840 // Don't export "v = <N>" initializing statements, hope they're always 841 // preceded by the DCL which will be re-parsed and typecheck to reproduce 842 // the "v = <N>" again. 843 if(fmtmode == FExp && n->right == N) 844 break; 845 846 if(n->colas && !complexinit) 847 fmtprint(f, "%N := %N", n->left, n->right); 848 else 849 fmtprint(f, "%N = %N", n->left, n->right); 850 break; 851 852 case OASOP: 853 fmtprint(f, "%N %#O= %N", n->left, n->etype, n->right); 854 break; 855 856 case OAS2: 857 if(n->colas && !complexinit) { 858 fmtprint(f, "%,H := %,H", n->list, n->rlist); 859 break; 860 } 861 // fallthrough 862 case OAS2DOTTYPE: 863 case OAS2FUNC: 864 case OAS2MAPR: 865 case OAS2RECV: 866 fmtprint(f, "%,H = %,H", n->list, n->rlist); 867 break; 868 869 case ORETURN: 870 fmtprint(f, "return %,H", n->list); 871 break; 872 873 case OPROC: 874 fmtprint(f, "go %N", n->left); 875 break; 876 877 case ODEFER: 878 fmtprint(f, "defer %N", n->left); 879 break; 880 881 case OIF: 882 if(simpleinit) 883 fmtprint(f, "if %N; %N { %H }", n->ninit->n, n->ntest, n->nbody); 884 else 885 fmtprint(f, "if %N { %H }", n->ntest, n->nbody); 886 if(n->nelse) 887 fmtprint(f, " else { %H }", n->nelse); 888 break; 889 890 case OFOR: 891 if(fmtmode == FErr) { // TODO maybe only if FmtShort, same below 892 fmtstrcpy(f, "for loop"); 893 break; 894 } 895 896 fmtstrcpy(f, "for"); 897 if(simpleinit) 898 fmtprint(f, " %N;", n->ninit->n); 899 else if(n->nincr) 900 fmtstrcpy(f, " ;"); 901 902 if(n->ntest) 903 fmtprint(f, " %N", n->ntest); 904 905 if(n->nincr) 906 fmtprint(f, "; %N", n->nincr); 907 else if(simpleinit) 908 fmtstrcpy(f, ";"); 909 910 911 fmtprint(f, " { %H }", n->nbody); 912 break; 913 914 case ORANGE: 915 if(fmtmode == FErr) { 916 fmtstrcpy(f, "for loop"); 917 break; 918 } 919 920 fmtprint(f, "for %,H = range %N { %H }", n->list, n->right, n->nbody); 921 break; 922 923 case OSELECT: 924 case OSWITCH: 925 if(fmtmode == FErr) { 926 fmtprint(f, "%O statement", n->op); 927 break; 928 } 929 930 fmtprint(f, "%#O", n->op); 931 if(simpleinit) 932 fmtprint(f, " %N;", n->ninit->n); 933 if(n->ntest) 934 fmtprint(f, "%N", n->ntest); 935 936 fmtprint(f, " { %H }", n->list); 937 break; 938 939 case OCASE: 940 case OXCASE: 941 if(n->list) 942 fmtprint(f, "case %,H: %H", n->list, n->nbody); 943 else 944 fmtprint(f, "default: %H", n->nbody); 945 break; 946 947 case OBREAK: 948 case OCONTINUE: 949 case OGOTO: 950 case OFALL: 951 case OXFALL: 952 if(n->left) 953 fmtprint(f, "%#O %N", n->op, n->left); 954 else 955 fmtprint(f, "%#O", n->op); 956 break; 957 958 case OEMPTY: 959 break; 960 961 case OLABEL: 962 fmtprint(f, "%N: ", n->left); 963 break; 964 965 } 966 ret: 967 968 if(extrablock) 969 fmtstrcpy(f, "}"); 970 971 return 0; 972 } 973 974 975 static int opprec[] = { 976 [OAPPEND] = 8, 977 [OARRAYBYTESTR] = 8, 978 [OARRAYLIT] = 8, 979 [OARRAYRUNESTR] = 8, 980 [OCALLFUNC] = 8, 981 [OCALLINTER] = 8, 982 [OCALLMETH] = 8, 983 [OCALL] = 8, 984 [OCAP] = 8, 985 [OCLOSE] = 8, 986 [OCONVIFACE] = 8, 987 [OCONVNOP] = 8, 988 [OCONV] = 8, 989 [OCOPY] = 8, 990 [ODELETE] = 8, 991 [OLEN] = 8, 992 [OLITERAL] = 8, 993 [OMAKESLICE] = 8, 994 [OMAKE] = 8, 995 [OMAPLIT] = 8, 996 [ONAME] = 8, 997 [ONEW] = 8, 998 [ONONAME] = 8, 999 [OPACK] = 8, 1000 [OPANIC] = 8, 1001 [OPAREN] = 8, 1002 [OPRINTN] = 8, 1003 [OPRINT] = 8, 1004 [ORUNESTR] = 8, 1005 [OSTRARRAYBYTE] = 8, 1006 [OSTRARRAYRUNE] = 8, 1007 [OSTRUCTLIT] = 8, 1008 [OTARRAY] = 8, 1009 [OTCHAN] = 8, 1010 [OTFUNC] = 8, 1011 [OTINTER] = 8, 1012 [OTMAP] = 8, 1013 [OTPAREN] = 8, 1014 [OTSTRUCT] = 8, 1015 1016 [OINDEXMAP] = 8, 1017 [OINDEX] = 8, 1018 [OSLICE] = 8, 1019 [OSLICESTR] = 8, 1020 [OSLICEARR] = 8, 1021 [ODOTINTER] = 8, 1022 [ODOTMETH] = 8, 1023 [ODOTPTR] = 8, 1024 [ODOTTYPE2] = 8, 1025 [ODOTTYPE] = 8, 1026 [ODOT] = 8, 1027 [OXDOT] = 8, 1028 [OCALLPART] = 8, 1029 1030 [OPLUS] = 7, 1031 [ONOT] = 7, 1032 [OCOM] = 7, 1033 [OMINUS] = 7, 1034 [OADDR] = 7, 1035 [OIND] = 7, 1036 [ORECV] = 7, 1037 1038 [OMUL] = 6, 1039 [ODIV] = 6, 1040 [OMOD] = 6, 1041 [OLSH] = 6, 1042 [ORSH] = 6, 1043 [OAND] = 6, 1044 [OANDNOT] = 6, 1045 1046 [OADD] = 5, 1047 [OSUB] = 5, 1048 [OOR] = 5, 1049 [OXOR] = 5, 1050 1051 [OEQ] = 4, 1052 [OLT] = 4, 1053 [OLE] = 4, 1054 [OGE] = 4, 1055 [OGT] = 4, 1056 [ONE] = 4, 1057 [OCMPSTR] = 4, 1058 [OCMPIFACE] = 4, 1059 1060 [OSEND] = 3, 1061 [OANDAND] = 2, 1062 [OOROR] = 1, 1063 1064 // Statements handled by stmtfmt 1065 [OAS] = -1, 1066 [OAS2] = -1, 1067 [OAS2DOTTYPE] = -1, 1068 [OAS2FUNC] = -1, 1069 [OAS2MAPR] = -1, 1070 [OAS2RECV] = -1, 1071 [OASOP] = -1, 1072 [OBREAK] = -1, 1073 [OCASE] = -1, 1074 [OCONTINUE] = -1, 1075 [ODCL] = -1, 1076 [ODCLFIELD] = -1, 1077 [ODEFER] = -1, 1078 [OEMPTY] = -1, 1079 [OFALL] = -1, 1080 [OFOR] = -1, 1081 [OIF] = -1, 1082 [OLABEL] = -1, 1083 [OPROC] = -1, 1084 [ORANGE] = -1, 1085 [ORETURN] = -1, 1086 [OSELECT] = -1, 1087 [OSWITCH] = -1, 1088 [OXCASE] = -1, 1089 [OXFALL] = -1, 1090 1091 [OEND] = 0 1092 }; 1093 1094 static int 1095 exprfmt(Fmt *f, Node *n, int prec) 1096 { 1097 int nprec; 1098 int ptrlit; 1099 NodeList *l; 1100 1101 while(n && n->implicit && (n->op == OIND || n->op == OADDR)) 1102 n = n->left; 1103 1104 if(n == N) 1105 return fmtstrcpy(f, "<N>"); 1106 1107 nprec = opprec[n->op]; 1108 if(n->op == OTYPE && n->sym != S) 1109 nprec = 8; 1110 1111 if(prec > nprec) 1112 return fmtprint(f, "(%N)", n); 1113 1114 switch(n->op) { 1115 case OPAREN: 1116 return fmtprint(f, "(%N)", n->left); 1117 1118 case ODDDARG: 1119 return fmtprint(f, "... argument"); 1120 1121 case OREGISTER: 1122 return fmtprint(f, "%R", n->val.u.reg); 1123 1124 case OLITERAL: // this is a bit of a mess 1125 if(fmtmode == FErr && n->sym != S) 1126 return fmtprint(f, "%S", n->sym); 1127 if(n->val.ctype == CTNIL && n->orig != N && n->orig != n) 1128 return exprfmt(f, n->orig, prec); 1129 if(n->type != T && n->type != types[n->type->etype] && n->type != idealbool && n->type != idealstring) { 1130 // Need parens when type begins with what might 1131 // be misinterpreted as a unary operator: * or <-. 1132 if(isptr[n->type->etype] || (n->type->etype == TCHAN && n->type->chan == Crecv)) 1133 return fmtprint(f, "(%T)(%V)", n->type, &n->val); 1134 else 1135 return fmtprint(f, "%T(%V)", n->type, &n->val); 1136 } 1137 return fmtprint(f, "%V", &n->val); 1138 1139 case ONAME: 1140 // Special case: name used as local variable in export. 1141 switch(n->class&~PHEAP){ 1142 case PAUTO: 1143 case PPARAM: 1144 case PPARAMOUT: 1145 if(fmtmode == FExp && n->sym && !isblanksym(n->sym) && n->vargen > 0) 1146 return fmtprint(f, "%S·%d", n->sym, n->vargen); 1147 } 1148 1149 // Special case: explicit name of func (*T) method(...) is turned into pkg.(*T).method, 1150 // but for export, this should be rendered as (*pkg.T).meth. 1151 // These nodes have the special property that they are names with a left OTYPE and a right ONAME. 1152 if(fmtmode == FExp && n->left && n->left->op == OTYPE && n->right && n->right->op == ONAME) { 1153 if(isptr[n->left->type->etype]) 1154 return fmtprint(f, "(%T).%hhS", n->left->type, n->right->sym); 1155 else 1156 return fmtprint(f, "%T.%hhS", n->left->type, n->right->sym); 1157 } 1158 //fallthrough 1159 case OPACK: 1160 case ONONAME: 1161 return fmtprint(f, "%S", n->sym); 1162 1163 case OTYPE: 1164 if(n->type == T && n->sym != S) 1165 return fmtprint(f, "%S", n->sym); 1166 return fmtprint(f, "%T", n->type); 1167 1168 case OTARRAY: 1169 if(n->left) 1170 return fmtprint(f, "[]%N", n->left); 1171 return fmtprint(f, "[]%N", n->right); // happens before typecheck 1172 1173 case OTPAREN: 1174 return fmtprint(f, "(%N)", n->left); 1175 1176 case OTMAP: 1177 return fmtprint(f, "map[%N]%N", n->left, n->right); 1178 1179 case OTCHAN: 1180 switch(n->etype) { 1181 case Crecv: 1182 return fmtprint(f, "<-chan %N", n->left); 1183 case Csend: 1184 return fmtprint(f, "chan<- %N", n->left); 1185 default: 1186 if(n->left != N && n->left->op == TCHAN && n->left->sym == S && n->left->etype == Crecv) 1187 return fmtprint(f, "chan (%N)", n->left); 1188 else 1189 return fmtprint(f, "chan %N", n->left); 1190 } 1191 1192 case OTSTRUCT: 1193 return fmtprint(f, "<struct>"); 1194 1195 case OTINTER: 1196 return fmtprint(f, "<inter>"); 1197 1198 case OTFUNC: 1199 return fmtprint(f, "<func>"); 1200 1201 case OCLOSURE: 1202 if(fmtmode == FErr) 1203 return fmtstrcpy(f, "func literal"); 1204 if(n->nbody) 1205 return fmtprint(f, "%T { %H }", n->type, n->nbody); 1206 return fmtprint(f, "%T { %H }", n->type, n->closure->nbody); 1207 1208 case OCOMPLIT: 1209 ptrlit = n->right != N && n->right->implicit && n->right->type && isptr[n->right->type->etype]; 1210 if(fmtmode == FErr) { 1211 if(n->right != N && n->right->type != T && !n->implicit) { 1212 if(ptrlit) 1213 return fmtprint(f, "&%T literal", n->right->type->type); 1214 else 1215 return fmtprint(f, "%T literal", n->right->type); 1216 } 1217 return fmtstrcpy(f, "composite literal"); 1218 } 1219 if(fmtmode == FExp && ptrlit) 1220 // typecheck has overwritten OIND by OTYPE with pointer type. 1221 return fmtprint(f, "&%T{ %,H }", n->right->type->type, n->list); 1222 return fmtprint(f, "(%N{ %,H })", n->right, n->list); 1223 1224 case OPTRLIT: 1225 if(fmtmode == FExp && n->left->implicit) 1226 return fmtprint(f, "%N", n->left); 1227 return fmtprint(f, "&%N", n->left); 1228 1229 case OSTRUCTLIT: 1230 if(fmtmode == FExp) { // requires special handling of field names 1231 if(n->implicit) 1232 fmtstrcpy(f, "{"); 1233 else 1234 fmtprint(f, "(%T{", n->type); 1235 for(l=n->list; l; l=l->next) { 1236 fmtprint(f, " %hhS:%N", l->n->left->sym, l->n->right); 1237 1238 if(l->next) 1239 fmtstrcpy(f, ","); 1240 else 1241 fmtstrcpy(f, " "); 1242 } 1243 if(!n->implicit) 1244 return fmtstrcpy(f, "})"); 1245 return fmtstrcpy(f, "}"); 1246 } 1247 // fallthrough 1248 1249 case OARRAYLIT: 1250 case OMAPLIT: 1251 if(fmtmode == FErr) 1252 return fmtprint(f, "%T literal", n->type); 1253 if(fmtmode == FExp && n->implicit) 1254 return fmtprint(f, "{ %,H }", n->list); 1255 return fmtprint(f, "(%T{ %,H })", n->type, n->list); 1256 1257 case OKEY: 1258 if(n->left && n->right) { 1259 if(fmtmode == FExp && n->left->type && n->left->type->etype == TFIELD) { 1260 // requires special handling of field names 1261 return fmtprint(f, "%hhS:%N", n->left->sym, n->right); 1262 } else 1263 return fmtprint(f, "%N:%N", n->left, n->right); 1264 } 1265 if(!n->left && n->right) 1266 return fmtprint(f, ":%N", n->right); 1267 if(n->left && !n->right) 1268 return fmtprint(f, "%N:", n->left); 1269 return fmtstrcpy(f, ":"); 1270 1271 case OXDOT: 1272 case ODOT: 1273 case ODOTPTR: 1274 case ODOTINTER: 1275 case ODOTMETH: 1276 case OCALLPART: 1277 exprfmt(f, n->left, nprec); 1278 if(n->right == N || n->right->sym == S) 1279 return fmtstrcpy(f, ".<nil>"); 1280 return fmtprint(f, ".%hhS", n->right->sym); 1281 1282 case ODOTTYPE: 1283 case ODOTTYPE2: 1284 exprfmt(f, n->left, nprec); 1285 if(n->right != N) 1286 return fmtprint(f, ".(%N)", n->right); 1287 return fmtprint(f, ".(%T)", n->type); 1288 1289 case OINDEX: 1290 case OINDEXMAP: 1291 case OSLICE: 1292 case OSLICESTR: 1293 case OSLICEARR: 1294 exprfmt(f, n->left, nprec); 1295 return fmtprint(f, "[%N]", n->right); 1296 1297 case OCOPY: 1298 case OCOMPLEX: 1299 return fmtprint(f, "%#O(%N, %N)", n->op, n->left, n->right); 1300 1301 case OCONV: 1302 case OCONVIFACE: 1303 case OCONVNOP: 1304 case OARRAYBYTESTR: 1305 case OARRAYRUNESTR: 1306 case OSTRARRAYBYTE: 1307 case OSTRARRAYRUNE: 1308 case ORUNESTR: 1309 if(n->type == T || n->type->sym == S) 1310 return fmtprint(f, "(%T)(%N)", n->type, n->left); 1311 if(n->left) 1312 return fmtprint(f, "%T(%N)", n->type, n->left); 1313 return fmtprint(f, "%T(%,H)", n->type, n->list); 1314 1315 case OREAL: 1316 case OIMAG: 1317 case OAPPEND: 1318 case OCAP: 1319 case OCLOSE: 1320 case ODELETE: 1321 case OLEN: 1322 case OMAKE: 1323 case ONEW: 1324 case OPANIC: 1325 case ORECOVER: 1326 case OPRINT: 1327 case OPRINTN: 1328 if(n->left) 1329 return fmtprint(f, "%#O(%N)", n->op, n->left); 1330 if(n->isddd) 1331 return fmtprint(f, "%#O(%,H...)", n->op, n->list); 1332 return fmtprint(f, "%#O(%,H)", n->op, n->list); 1333 1334 case OCALL: 1335 case OCALLFUNC: 1336 case OCALLINTER: 1337 case OCALLMETH: 1338 exprfmt(f, n->left, nprec); 1339 if(n->isddd) 1340 return fmtprint(f, "(%,H...)", n->list); 1341 return fmtprint(f, "(%,H)", n->list); 1342 1343 case OMAKEMAP: 1344 case OMAKECHAN: 1345 case OMAKESLICE: 1346 if(n->list) // pre-typecheck 1347 return fmtprint(f, "make(%T, %,H)", n->type, n->list); 1348 if(n->right) 1349 return fmtprint(f, "make(%T, %N, %N)", n->type, n->left, n->right); 1350 if(n->left) 1351 return fmtprint(f, "make(%T, %N)", n->type, n->left); 1352 return fmtprint(f, "make(%T)", n->type); 1353 1354 // Unary 1355 case OPLUS: 1356 case OMINUS: 1357 case OADDR: 1358 case OCOM: 1359 case OIND: 1360 case ONOT: 1361 case ORECV: 1362 if(n->left->op == n->op) 1363 fmtprint(f, "%#O ", n->op); 1364 else 1365 fmtprint(f, "%#O", n->op); 1366 return exprfmt(f, n->left, nprec+1); 1367 1368 // Binary 1369 case OADD: 1370 case OADDSTR: 1371 case OAND: 1372 case OANDAND: 1373 case OANDNOT: 1374 case ODIV: 1375 case OEQ: 1376 case OGE: 1377 case OGT: 1378 case OLE: 1379 case OLT: 1380 case OLSH: 1381 case OMOD: 1382 case OMUL: 1383 case ONE: 1384 case OOR: 1385 case OOROR: 1386 case ORSH: 1387 case OSEND: 1388 case OSUB: 1389 case OXOR: 1390 exprfmt(f, n->left, nprec); 1391 fmtprint(f, " %#O ", n->op); 1392 exprfmt(f, n->right, nprec+1); 1393 return 0; 1394 1395 case OCMPSTR: 1396 case OCMPIFACE: 1397 exprfmt(f, n->left, nprec); 1398 fmtprint(f, " %#O ", n->etype); 1399 exprfmt(f, n->right, nprec+1); 1400 return 0; 1401 } 1402 1403 return fmtprint(f, "<node %O>", n->op); 1404 } 1405 1406 static int 1407 nodefmt(Fmt *f, Node *n) 1408 { 1409 Type *t; 1410 1411 t = n->type; 1412 1413 // we almost always want the original, except in export mode for literals 1414 // this saves the importer some work, and avoids us having to redo some 1415 // special casing for package unsafe 1416 if((fmtmode != FExp || n->op != OLITERAL) && n->orig != N) 1417 n = n->orig; 1418 1419 if(f->flags&FmtLong && t != T) { 1420 if(t->etype == TNIL) 1421 return fmtprint(f, "nil"); 1422 else 1423 return fmtprint(f, "%N (type %T)", n, t); 1424 } 1425 1426 // TODO inlining produces expressions with ninits. we can't print these yet. 1427 1428 if(opprec[n->op] < 0) 1429 return stmtfmt(f, n); 1430 1431 return exprfmt(f, n, 0); 1432 } 1433 1434 static int dumpdepth; 1435 1436 static void 1437 indent(Fmt *fp) 1438 { 1439 int i; 1440 1441 fmtstrcpy(fp, "\n"); 1442 for(i = 0; i < dumpdepth; ++i) 1443 fmtstrcpy(fp, ". "); 1444 } 1445 1446 static int 1447 nodedump(Fmt *fp, Node *n) 1448 { 1449 int recur; 1450 1451 if(n == N) 1452 return 0; 1453 1454 recur = !(fp->flags&FmtShort); 1455 1456 if(recur) { 1457 indent(fp); 1458 if(dumpdepth > 10) 1459 return fmtstrcpy(fp, "..."); 1460 1461 if(n->ninit != nil) { 1462 fmtprint(fp, "%O-init%H", n->op, n->ninit); 1463 indent(fp); 1464 } 1465 } 1466 1467 // fmtprint(fp, "[%p]", n); 1468 1469 switch(n->op) { 1470 default: 1471 fmtprint(fp, "%O%J", n->op, n); 1472 break; 1473 case OREGISTER: 1474 case OINDREG: 1475 fmtprint(fp, "%O-%R%J", n->op, n->val.u.reg, n); 1476 break; 1477 case OLITERAL: 1478 fmtprint(fp, "%O-%V%J", n->op, &n->val, n); 1479 break; 1480 case ONAME: 1481 case ONONAME: 1482 if(n->sym != S) 1483 fmtprint(fp, "%O-%S%J", n->op, n->sym, n); 1484 else 1485 fmtprint(fp, "%O%J", n->op, n); 1486 if(recur && n->type == T && n->ntype) { 1487 indent(fp); 1488 fmtprint(fp, "%O-ntype%N", n->op, n->ntype); 1489 } 1490 break; 1491 case OASOP: 1492 fmtprint(fp, "%O-%O%J", n->op, n->etype, n); 1493 break; 1494 case OTYPE: 1495 fmtprint(fp, "%O %S%J type=%T", n->op, n->sym, n, n->type); 1496 if(recur && n->type == T && n->ntype) { 1497 indent(fp); 1498 fmtprint(fp, "%O-ntype%N", n->op, n->ntype); 1499 } 1500 break; 1501 } 1502 1503 if(n->sym != S && n->op != ONAME) 1504 fmtprint(fp, " %S G%d", n->sym, n->vargen); 1505 1506 if(n->type != T) 1507 fmtprint(fp, " %T", n->type); 1508 1509 if(recur) { 1510 if(n->left) 1511 fmtprint(fp, "%N", n->left); 1512 if(n->right) 1513 fmtprint(fp, "%N", n->right); 1514 if(n->list) { 1515 indent(fp); 1516 fmtprint(fp, "%O-list%H", n->op, n->list); 1517 } 1518 if(n->rlist) { 1519 indent(fp); 1520 fmtprint(fp, "%O-rlist%H", n->op, n->rlist); 1521 } 1522 if(n->ntest) { 1523 indent(fp); 1524 fmtprint(fp, "%O-test%N", n->op, n->ntest); 1525 } 1526 if(n->nbody) { 1527 indent(fp); 1528 fmtprint(fp, "%O-body%H", n->op, n->nbody); 1529 } 1530 if(n->nelse) { 1531 indent(fp); 1532 fmtprint(fp, "%O-else%H", n->op, n->nelse); 1533 } 1534 if(n->nincr) { 1535 indent(fp); 1536 fmtprint(fp, "%O-incr%N", n->op, n->nincr); 1537 } 1538 } 1539 1540 return 0; 1541 } 1542 1543 // Fmt "%S": syms 1544 // Flags: "%hS" suppresses qualifying with package 1545 static int 1546 Sconv(Fmt *fp) 1547 { 1548 Sym *s; 1549 int r, sm; 1550 unsigned long sf; 1551 1552 s = va_arg(fp->args, Sym*); 1553 if(s == S) 1554 return fmtstrcpy(fp, "<S>"); 1555 1556 if(s->name && s->name[0] == '_' && s->name[1] == '\0') 1557 return fmtstrcpy(fp, "_"); 1558 1559 sf = fp->flags; 1560 sm = setfmode(&fp->flags); 1561 r = symfmt(fp, s); 1562 fp->flags = sf; 1563 fmtmode = sm; 1564 return r; 1565 } 1566 1567 // Fmt "%T": types. 1568 // Flags: 'l' print definition, not name 1569 // 'h' omit 'func' and receiver from function types, short type names 1570 // 'u' package name, not prefix (FTypeId mode, sticky) 1571 static int 1572 Tconv(Fmt *fp) 1573 { 1574 Type *t; 1575 int r, sm; 1576 unsigned long sf; 1577 1578 t = va_arg(fp->args, Type*); 1579 if(t == T) 1580 return fmtstrcpy(fp, "<T>"); 1581 1582 if(t->trecur > 4) 1583 return fmtstrcpy(fp, "<...>"); 1584 1585 t->trecur++; 1586 sf = fp->flags; 1587 sm = setfmode(&fp->flags); 1588 1589 if(fmtmode == FTypeId && (sf&FmtUnsigned)) 1590 fmtpkgpfx++; 1591 if(fmtpkgpfx) 1592 fp->flags |= FmtUnsigned; 1593 1594 r = typefmt(fp, t); 1595 1596 if(fmtmode == FTypeId && (sf&FmtUnsigned)) 1597 fmtpkgpfx--; 1598 1599 fp->flags = sf; 1600 fmtmode = sm; 1601 t->trecur--; 1602 return r; 1603 } 1604 1605 // Fmt '%N': Nodes. 1606 // Flags: 'l' suffix with "(type %T)" where possible 1607 // '+h' in debug mode, don't recurse, no multiline output 1608 static int 1609 Nconv(Fmt *fp) 1610 { 1611 Node *n; 1612 int r, sm; 1613 unsigned long sf; 1614 1615 n = va_arg(fp->args, Node*); 1616 if(n == N) 1617 return fmtstrcpy(fp, "<N>"); 1618 sf = fp->flags; 1619 sm = setfmode(&fp->flags); 1620 1621 r = -1; 1622 switch(fmtmode) { 1623 case FErr: 1624 case FExp: 1625 r = nodefmt(fp, n); 1626 break; 1627 case FDbg: 1628 dumpdepth++; 1629 r = nodedump(fp, n); 1630 dumpdepth--; 1631 break; 1632 default: 1633 fatal("unhandled %%N mode"); 1634 } 1635 1636 fp->flags = sf; 1637 fmtmode = sm; 1638 return r; 1639 } 1640 1641 // Fmt '%H': NodeList. 1642 // Flags: all those of %N plus ',': separate with comma's instead of semicolons. 1643 static int 1644 Hconv(Fmt *fp) 1645 { 1646 NodeList *l; 1647 int r, sm; 1648 unsigned long sf; 1649 char *sep; 1650 1651 l = va_arg(fp->args, NodeList*); 1652 1653 if(l == nil && fmtmode == FDbg) 1654 return fmtstrcpy(fp, "<nil>"); 1655 1656 sf = fp->flags; 1657 sm = setfmode(&fp->flags); 1658 r = 0; 1659 sep = "; "; 1660 if(fmtmode == FDbg) 1661 sep = "\n"; 1662 else if(fp->flags & FmtComma) 1663 sep = ", "; 1664 1665 for(;l; l=l->next) { 1666 r += fmtprint(fp, "%N", l->n); 1667 if(l->next) 1668 r += fmtstrcpy(fp, sep); 1669 } 1670 1671 fp->flags = sf; 1672 fmtmode = sm; 1673 return r; 1674 } 1675 1676 void 1677 fmtinstallgo(void) 1678 { 1679 fmtmode = FErr; 1680 fmtinstall('E', Econv); // etype opcodes 1681 fmtinstall('J', Jconv); // all the node flags 1682 fmtinstall('H', Hconv); // node lists 1683 fmtinstall('L', Lconv); // line number 1684 fmtinstall('N', Nconv); // node pointer 1685 fmtinstall('O', Oconv); // node opcodes 1686 fmtinstall('S', Sconv); // sym pointer 1687 fmtinstall('T', Tconv); // type pointer 1688 fmtinstall('V', Vconv); // val pointer 1689 fmtinstall('Z', Zconv); // escaped string 1690 1691 // These are in mparith1.c 1692 fmtinstall('B', Bconv); // big numbers 1693 fmtinstall('F', Fconv); // big float numbers 1694 1695 } 1696 1697 void 1698 dumplist(char *s, NodeList *l) 1699 { 1700 print("%s%+H\n", s, l); 1701 } 1702 1703 void 1704 dump(char *s, Node *n) 1705 { 1706 print("%s [%p]%+N\n", s, n, n); 1707 }