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