github.com/razvanm/vanadium-go-1.3@v0.0.0-20160721203343-4a65068e5915/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"/"nosplit" 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 if(n->implicit) { 814 if(n->etype == OADD) 815 fmtprint(f, "%N++", n->left); 816 else 817 fmtprint(f, "%N--", n->left); 818 break; 819 } 820 fmtprint(f, "%N %#O= %N", n->left, n->etype, n->right); 821 break; 822 823 case OAS2: 824 if(n->colas && !complexinit) { 825 fmtprint(f, "%,H := %,H", n->list, n->rlist); 826 break; 827 } 828 // fallthrough 829 case OAS2DOTTYPE: 830 case OAS2FUNC: 831 case OAS2MAPR: 832 case OAS2RECV: 833 fmtprint(f, "%,H = %,H", n->list, n->rlist); 834 break; 835 836 case ORETURN: 837 fmtprint(f, "return %,H", n->list); 838 break; 839 840 case ORETJMP: 841 fmtprint(f, "retjmp %S", n->sym); 842 break; 843 844 case OPROC: 845 fmtprint(f, "go %N", n->left); 846 break; 847 848 case ODEFER: 849 fmtprint(f, "defer %N", n->left); 850 break; 851 852 case OIF: 853 if(simpleinit) 854 fmtprint(f, "if %N; %N { %H }", n->ninit->n, n->ntest, n->nbody); 855 else 856 fmtprint(f, "if %N { %H }", n->ntest, n->nbody); 857 if(n->nelse) 858 fmtprint(f, " else { %H }", n->nelse); 859 break; 860 861 case OFOR: 862 if(fmtmode == FErr) { // TODO maybe only if FmtShort, same below 863 fmtstrcpy(f, "for loop"); 864 break; 865 } 866 867 fmtstrcpy(f, "for"); 868 if(simpleinit) 869 fmtprint(f, " %N;", n->ninit->n); 870 else if(n->nincr) 871 fmtstrcpy(f, " ;"); 872 873 if(n->ntest) 874 fmtprint(f, " %N", n->ntest); 875 876 if(n->nincr) 877 fmtprint(f, "; %N", n->nincr); 878 else if(simpleinit) 879 fmtstrcpy(f, ";"); 880 881 882 fmtprint(f, " { %H }", n->nbody); 883 break; 884 885 case ORANGE: 886 if(fmtmode == FErr) { 887 fmtstrcpy(f, "for loop"); 888 break; 889 } 890 891 if(n->list == nil) { 892 fmtprint(f, "for range %N { %H }", n->right, n->nbody); 893 break; 894 } 895 fmtprint(f, "for %,H = range %N { %H }", n->list, n->right, n->nbody); 896 break; 897 898 case OSELECT: 899 case OSWITCH: 900 if(fmtmode == FErr) { 901 fmtprint(f, "%O statement", n->op); 902 break; 903 } 904 905 fmtprint(f, "%#O", n->op); 906 if(simpleinit) 907 fmtprint(f, " %N;", n->ninit->n); 908 if(n->ntest) 909 fmtprint(f, "%N", n->ntest); 910 911 fmtprint(f, " { %H }", n->list); 912 break; 913 914 case OCASE: 915 case OXCASE: 916 if(n->list) 917 fmtprint(f, "case %,H: %H", n->list, n->nbody); 918 else 919 fmtprint(f, "default: %H", n->nbody); 920 break; 921 922 case OBREAK: 923 case OCONTINUE: 924 case OGOTO: 925 case OFALL: 926 case OXFALL: 927 if(n->left) 928 fmtprint(f, "%#O %N", n->op, n->left); 929 else 930 fmtprint(f, "%#O", n->op); 931 break; 932 933 case OEMPTY: 934 break; 935 936 case OLABEL: 937 fmtprint(f, "%N: ", n->left); 938 break; 939 940 } 941 ret: 942 943 if(extrablock) 944 fmtstrcpy(f, "}"); 945 946 return 0; 947 } 948 949 950 static int opprec[] = { 951 [OAPPEND] = 8, 952 [OARRAYBYTESTR] = 8, 953 [OARRAYLIT] = 8, 954 [OARRAYRUNESTR] = 8, 955 [OCALLFUNC] = 8, 956 [OCALLINTER] = 8, 957 [OCALLMETH] = 8, 958 [OCALL] = 8, 959 [OCAP] = 8, 960 [OCLOSE] = 8, 961 [OCONVIFACE] = 8, 962 [OCONVNOP] = 8, 963 [OCONV] = 8, 964 [OCOPY] = 8, 965 [ODELETE] = 8, 966 [OLEN] = 8, 967 [OLITERAL] = 8, 968 [OMAKESLICE] = 8, 969 [OMAKE] = 8, 970 [OMAPLIT] = 8, 971 [ONAME] = 8, 972 [ONEW] = 8, 973 [ONONAME] = 8, 974 [OPACK] = 8, 975 [OPANIC] = 8, 976 [OPAREN] = 8, 977 [OPRINTN] = 8, 978 [OPRINT] = 8, 979 [ORUNESTR] = 8, 980 [OSTRARRAYBYTE] = 8, 981 [OSTRARRAYRUNE] = 8, 982 [OSTRUCTLIT] = 8, 983 [OTARRAY] = 8, 984 [OTCHAN] = 8, 985 [OTFUNC] = 8, 986 [OTINTER] = 8, 987 [OTMAP] = 8, 988 [OTSTRUCT] = 8, 989 990 [OINDEXMAP] = 8, 991 [OINDEX] = 8, 992 [OSLICE] = 8, 993 [OSLICESTR] = 8, 994 [OSLICEARR] = 8, 995 [OSLICE3] = 8, 996 [OSLICE3ARR] = 8, 997 [ODOTINTER] = 8, 998 [ODOTMETH] = 8, 999 [ODOTPTR] = 8, 1000 [ODOTTYPE2] = 8, 1001 [ODOTTYPE] = 8, 1002 [ODOT] = 8, 1003 [OXDOT] = 8, 1004 [OCALLPART] = 8, 1005 1006 [OPLUS] = 7, 1007 [ONOT] = 7, 1008 [OCOM] = 7, 1009 [OMINUS] = 7, 1010 [OADDR] = 7, 1011 [OIND] = 7, 1012 [ORECV] = 7, 1013 1014 [OMUL] = 6, 1015 [ODIV] = 6, 1016 [OMOD] = 6, 1017 [OLSH] = 6, 1018 [ORSH] = 6, 1019 [OAND] = 6, 1020 [OANDNOT] = 6, 1021 1022 [OADD] = 5, 1023 [OSUB] = 5, 1024 [OOR] = 5, 1025 [OXOR] = 5, 1026 1027 [OEQ] = 4, 1028 [OLT] = 4, 1029 [OLE] = 4, 1030 [OGE] = 4, 1031 [OGT] = 4, 1032 [ONE] = 4, 1033 [OCMPSTR] = 4, 1034 [OCMPIFACE] = 4, 1035 1036 [OSEND] = 3, 1037 [OANDAND] = 2, 1038 [OOROR] = 1, 1039 1040 // Statements handled by stmtfmt 1041 [OAS] = -1, 1042 [OAS2] = -1, 1043 [OAS2DOTTYPE] = -1, 1044 [OAS2FUNC] = -1, 1045 [OAS2MAPR] = -1, 1046 [OAS2RECV] = -1, 1047 [OASOP] = -1, 1048 [OBREAK] = -1, 1049 [OCASE] = -1, 1050 [OCONTINUE] = -1, 1051 [ODCL] = -1, 1052 [ODCLFIELD] = -1, 1053 [ODEFER] = -1, 1054 [OEMPTY] = -1, 1055 [OFALL] = -1, 1056 [OFOR] = -1, 1057 [OGOTO] = -1, 1058 [OIF] = -1, 1059 [OLABEL] = -1, 1060 [OPROC] = -1, 1061 [ORANGE] = -1, 1062 [ORETURN] = -1, 1063 [OSELECT] = -1, 1064 [OSWITCH] = -1, 1065 [OXCASE] = -1, 1066 [OXFALL] = -1, 1067 1068 [OEND] = 0 1069 }; 1070 1071 static int 1072 exprfmt(Fmt *f, Node *n, int prec) 1073 { 1074 int nprec; 1075 int ptrlit; 1076 NodeList *l; 1077 1078 while(n && n->implicit && (n->op == OIND || n->op == OADDR)) 1079 n = n->left; 1080 1081 if(n == N) 1082 return fmtstrcpy(f, "<N>"); 1083 1084 nprec = opprec[n->op]; 1085 if(n->op == OTYPE && n->sym != S) 1086 nprec = 8; 1087 1088 if(prec > nprec) 1089 return fmtprint(f, "(%N)", n); 1090 1091 switch(n->op) { 1092 case OPAREN: 1093 return fmtprint(f, "(%N)", n->left); 1094 1095 case ODDDARG: 1096 return fmtprint(f, "... argument"); 1097 1098 case OREGISTER: 1099 return fmtprint(f, "%R", n->val.u.reg); 1100 1101 case OLITERAL: // this is a bit of a mess 1102 if(fmtmode == FErr && n->sym != S) 1103 return fmtprint(f, "%S", n->sym); 1104 if(n->val.ctype == CTNIL && n->orig != N && n->orig != n) 1105 return exprfmt(f, n->orig, prec); 1106 if(n->type != T && n->type != types[n->type->etype] && n->type != idealbool && n->type != idealstring) { 1107 // Need parens when type begins with what might 1108 // be misinterpreted as a unary operator: * or <-. 1109 if(isptr[n->type->etype] || (n->type->etype == TCHAN && n->type->chan == Crecv)) 1110 return fmtprint(f, "(%T)(%V)", n->type, &n->val); 1111 else 1112 return fmtprint(f, "%T(%V)", n->type, &n->val); 1113 } 1114 return fmtprint(f, "%V", &n->val); 1115 1116 case ONAME: 1117 // Special case: name used as local variable in export. 1118 // _ becomes ~b%d internally; print as _ for export 1119 if(fmtmode == FExp && n->sym && n->sym->name[0] == '~' && n->sym->name[1] == 'b') 1120 return fmtprint(f, "_"); 1121 if(fmtmode == FExp && n->sym && !isblank(n) && n->vargen > 0) 1122 return fmtprint(f, "%S·%d", n->sym, n->vargen); 1123 1124 // Special case: explicit name of func (*T) method(...) is turned into pkg.(*T).method, 1125 // but for export, this should be rendered as (*pkg.T).meth. 1126 // These nodes have the special property that they are names with a left OTYPE and a right ONAME. 1127 if(fmtmode == FExp && n->left && n->left->op == OTYPE && n->right && n->right->op == ONAME) { 1128 if(isptr[n->left->type->etype]) 1129 return fmtprint(f, "(%T).%hhS", n->left->type, n->right->sym); 1130 else 1131 return fmtprint(f, "%T.%hhS", n->left->type, n->right->sym); 1132 } 1133 //fallthrough 1134 case OPACK: 1135 case ONONAME: 1136 return fmtprint(f, "%S", n->sym); 1137 1138 case OTYPE: 1139 if(n->type == T && n->sym != S) 1140 return fmtprint(f, "%S", n->sym); 1141 return fmtprint(f, "%T", n->type); 1142 1143 case OTARRAY: 1144 if(n->left) 1145 return fmtprint(f, "[]%N", n->left); 1146 return fmtprint(f, "[]%N", n->right); // happens before typecheck 1147 1148 case OTMAP: 1149 return fmtprint(f, "map[%N]%N", n->left, n->right); 1150 1151 case OTCHAN: 1152 switch(n->etype) { 1153 case Crecv: 1154 return fmtprint(f, "<-chan %N", n->left); 1155 case Csend: 1156 return fmtprint(f, "chan<- %N", n->left); 1157 default: 1158 if(n->left != N && n->left->op == OTCHAN && n->left->sym == S && n->left->etype == Crecv) 1159 return fmtprint(f, "chan (%N)", n->left); 1160 else 1161 return fmtprint(f, "chan %N", n->left); 1162 } 1163 1164 case OTSTRUCT: 1165 return fmtprint(f, "<struct>"); 1166 1167 case OTINTER: 1168 return fmtprint(f, "<inter>"); 1169 1170 case OTFUNC: 1171 return fmtprint(f, "<func>"); 1172 1173 case OCLOSURE: 1174 if(fmtmode == FErr) 1175 return fmtstrcpy(f, "func literal"); 1176 if(n->nbody) 1177 return fmtprint(f, "%T { %H }", n->type, n->nbody); 1178 return fmtprint(f, "%T { %H }", n->type, n->closure->nbody); 1179 1180 case OCOMPLIT: 1181 ptrlit = n->right != N && n->right->implicit && n->right->type && isptr[n->right->type->etype]; 1182 if(fmtmode == FErr) { 1183 if(n->right != N && n->right->type != T && !n->implicit) { 1184 if(ptrlit) 1185 return fmtprint(f, "&%T literal", n->right->type->type); 1186 else 1187 return fmtprint(f, "%T literal", n->right->type); 1188 } 1189 return fmtstrcpy(f, "composite literal"); 1190 } 1191 if(fmtmode == FExp && ptrlit) 1192 // typecheck has overwritten OIND by OTYPE with pointer type. 1193 return fmtprint(f, "(&%T{ %,H })", n->right->type->type, n->list); 1194 return fmtprint(f, "(%N{ %,H })", n->right, n->list); 1195 1196 case OPTRLIT: 1197 if(fmtmode == FExp && n->left->implicit) 1198 return fmtprint(f, "%N", n->left); 1199 return fmtprint(f, "&%N", n->left); 1200 1201 case OSTRUCTLIT: 1202 if(fmtmode == FExp) { // requires special handling of field names 1203 if(n->implicit) 1204 fmtstrcpy(f, "{"); 1205 else 1206 fmtprint(f, "(%T{", n->type); 1207 for(l=n->list; l; l=l->next) { 1208 fmtprint(f, " %hhS:%N", l->n->left->sym, l->n->right); 1209 1210 if(l->next) 1211 fmtstrcpy(f, ","); 1212 else 1213 fmtstrcpy(f, " "); 1214 } 1215 if(!n->implicit) 1216 return fmtstrcpy(f, "})"); 1217 return fmtstrcpy(f, "}"); 1218 } 1219 // fallthrough 1220 1221 case OARRAYLIT: 1222 case OMAPLIT: 1223 if(fmtmode == FErr) 1224 return fmtprint(f, "%T literal", n->type); 1225 if(fmtmode == FExp && n->implicit) 1226 return fmtprint(f, "{ %,H }", n->list); 1227 return fmtprint(f, "(%T{ %,H })", n->type, n->list); 1228 1229 case OKEY: 1230 if(n->left && n->right) { 1231 if(fmtmode == FExp && n->left->type && n->left->type->etype == TFIELD) { 1232 // requires special handling of field names 1233 return fmtprint(f, "%hhS:%N", n->left->sym, n->right); 1234 } else 1235 return fmtprint(f, "%N:%N", n->left, n->right); 1236 } 1237 if(!n->left && n->right) 1238 return fmtprint(f, ":%N", n->right); 1239 if(n->left && !n->right) 1240 return fmtprint(f, "%N:", n->left); 1241 return fmtstrcpy(f, ":"); 1242 1243 case OXDOT: 1244 case ODOT: 1245 case ODOTPTR: 1246 case ODOTINTER: 1247 case ODOTMETH: 1248 case OCALLPART: 1249 exprfmt(f, n->left, nprec); 1250 if(n->right == N || n->right->sym == S) 1251 return fmtstrcpy(f, ".<nil>"); 1252 return fmtprint(f, ".%hhS", n->right->sym); 1253 1254 case ODOTTYPE: 1255 case ODOTTYPE2: 1256 exprfmt(f, n->left, nprec); 1257 if(n->right != N) 1258 return fmtprint(f, ".(%N)", n->right); 1259 return fmtprint(f, ".(%T)", n->type); 1260 1261 case OINDEX: 1262 case OINDEXMAP: 1263 case OSLICE: 1264 case OSLICESTR: 1265 case OSLICEARR: 1266 case OSLICE3: 1267 case OSLICE3ARR: 1268 exprfmt(f, n->left, nprec); 1269 return fmtprint(f, "[%N]", n->right); 1270 1271 case OCOPY: 1272 case OCOMPLEX: 1273 return fmtprint(f, "%#O(%N, %N)", n->op, n->left, n->right); 1274 1275 case OCONV: 1276 case OCONVIFACE: 1277 case OCONVNOP: 1278 case OARRAYBYTESTR: 1279 case OARRAYRUNESTR: 1280 case OSTRARRAYBYTE: 1281 case OSTRARRAYRUNE: 1282 case ORUNESTR: 1283 if(n->type == T || n->type->sym == S) 1284 return fmtprint(f, "(%T)(%N)", n->type, n->left); 1285 if(n->left) 1286 return fmtprint(f, "%T(%N)", n->type, n->left); 1287 return fmtprint(f, "%T(%,H)", n->type, n->list); 1288 1289 case OREAL: 1290 case OIMAG: 1291 case OAPPEND: 1292 case OCAP: 1293 case OCLOSE: 1294 case ODELETE: 1295 case OLEN: 1296 case OMAKE: 1297 case ONEW: 1298 case OPANIC: 1299 case ORECOVER: 1300 case OPRINT: 1301 case OPRINTN: 1302 if(n->left) 1303 return fmtprint(f, "%#O(%N)", n->op, n->left); 1304 if(n->isddd) 1305 return fmtprint(f, "%#O(%,H...)", n->op, n->list); 1306 return fmtprint(f, "%#O(%,H)", n->op, n->list); 1307 1308 case OCALL: 1309 case OCALLFUNC: 1310 case OCALLINTER: 1311 case OCALLMETH: 1312 exprfmt(f, n->left, nprec); 1313 if(n->isddd) 1314 return fmtprint(f, "(%,H...)", n->list); 1315 return fmtprint(f, "(%,H)", n->list); 1316 1317 case OMAKEMAP: 1318 case OMAKECHAN: 1319 case OMAKESLICE: 1320 if(n->list) // pre-typecheck 1321 return fmtprint(f, "make(%T, %,H)", n->type, n->list); 1322 if(n->right) 1323 return fmtprint(f, "make(%T, %N, %N)", n->type, n->left, n->right); 1324 if(n->left) 1325 return fmtprint(f, "make(%T, %N)", n->type, n->left); 1326 return fmtprint(f, "make(%T)", n->type); 1327 1328 // Unary 1329 case OPLUS: 1330 case OMINUS: 1331 case OADDR: 1332 case OCOM: 1333 case OIND: 1334 case ONOT: 1335 case ORECV: 1336 if(n->left->op == n->op) 1337 fmtprint(f, "%#O ", n->op); 1338 else 1339 fmtprint(f, "%#O", n->op); 1340 return exprfmt(f, n->left, nprec+1); 1341 1342 // Binary 1343 case OADD: 1344 case OAND: 1345 case OANDAND: 1346 case OANDNOT: 1347 case ODIV: 1348 case OEQ: 1349 case OGE: 1350 case OGT: 1351 case OLE: 1352 case OLT: 1353 case OLSH: 1354 case OMOD: 1355 case OMUL: 1356 case ONE: 1357 case OOR: 1358 case OOROR: 1359 case ORSH: 1360 case OSEND: 1361 case OSUB: 1362 case OXOR: 1363 exprfmt(f, n->left, nprec); 1364 fmtprint(f, " %#O ", n->op); 1365 exprfmt(f, n->right, nprec+1); 1366 return 0; 1367 1368 case OADDSTR: 1369 for(l=n->list; l; l=l->next) { 1370 if(l != n->list) 1371 fmtprint(f, " + "); 1372 exprfmt(f, l->n, nprec); 1373 } 1374 return 0; 1375 1376 case OCMPSTR: 1377 case OCMPIFACE: 1378 exprfmt(f, n->left, nprec); 1379 fmtprint(f, " %#O ", n->etype); 1380 exprfmt(f, n->right, nprec+1); 1381 return 0; 1382 } 1383 1384 return fmtprint(f, "<node %O>", n->op); 1385 } 1386 1387 static int 1388 nodefmt(Fmt *f, Node *n) 1389 { 1390 Type *t; 1391 1392 t = n->type; 1393 1394 // we almost always want the original, except in export mode for literals 1395 // this saves the importer some work, and avoids us having to redo some 1396 // special casing for package unsafe 1397 if((fmtmode != FExp || n->op != OLITERAL) && n->orig != N) 1398 n = n->orig; 1399 1400 if(f->flags&FmtLong && t != T) { 1401 if(t->etype == TNIL) 1402 return fmtprint(f, "nil"); 1403 else 1404 return fmtprint(f, "%N (type %T)", n, t); 1405 } 1406 1407 // TODO inlining produces expressions with ninits. we can't print these yet. 1408 1409 if(opprec[n->op] < 0) 1410 return stmtfmt(f, n); 1411 1412 return exprfmt(f, n, 0); 1413 } 1414 1415 static int dumpdepth; 1416 1417 static void 1418 indent(Fmt *fp) 1419 { 1420 int i; 1421 1422 fmtstrcpy(fp, "\n"); 1423 for(i = 0; i < dumpdepth; ++i) 1424 fmtstrcpy(fp, ". "); 1425 } 1426 1427 static int 1428 nodedump(Fmt *fp, Node *n) 1429 { 1430 int recur; 1431 1432 if(n == N) 1433 return 0; 1434 1435 recur = !(fp->flags&FmtShort); 1436 1437 if(recur) { 1438 indent(fp); 1439 if(dumpdepth > 10) 1440 return fmtstrcpy(fp, "..."); 1441 1442 if(n->ninit != nil) { 1443 fmtprint(fp, "%O-init%H", n->op, n->ninit); 1444 indent(fp); 1445 } 1446 } 1447 1448 // fmtprint(fp, "[%p]", n); 1449 1450 switch(n->op) { 1451 default: 1452 fmtprint(fp, "%O%J", n->op, n); 1453 break; 1454 case OREGISTER: 1455 case OINDREG: 1456 fmtprint(fp, "%O-%R%J", n->op, n->val.u.reg, n); 1457 break; 1458 case OLITERAL: 1459 fmtprint(fp, "%O-%V%J", n->op, &n->val, n); 1460 break; 1461 case ONAME: 1462 case ONONAME: 1463 if(n->sym != S) 1464 fmtprint(fp, "%O-%S%J", n->op, n->sym, n); 1465 else 1466 fmtprint(fp, "%O%J", n->op, n); 1467 if(recur && n->type == T && n->ntype) { 1468 indent(fp); 1469 fmtprint(fp, "%O-ntype%N", n->op, n->ntype); 1470 } 1471 break; 1472 case OASOP: 1473 fmtprint(fp, "%O-%O%J", n->op, n->etype, n); 1474 break; 1475 case OTYPE: 1476 fmtprint(fp, "%O %S%J type=%T", n->op, n->sym, n, n->type); 1477 if(recur && n->type == T && n->ntype) { 1478 indent(fp); 1479 fmtprint(fp, "%O-ntype%N", n->op, n->ntype); 1480 } 1481 break; 1482 } 1483 1484 if(n->sym != S && n->op != ONAME) 1485 fmtprint(fp, " %S G%d", n->sym, n->vargen); 1486 1487 if(n->type != T) 1488 fmtprint(fp, " %T", n->type); 1489 1490 if(recur) { 1491 if(n->left) 1492 fmtprint(fp, "%N", n->left); 1493 if(n->right) 1494 fmtprint(fp, "%N", n->right); 1495 if(n->list) { 1496 indent(fp); 1497 fmtprint(fp, "%O-list%H", n->op, n->list); 1498 } 1499 if(n->rlist) { 1500 indent(fp); 1501 fmtprint(fp, "%O-rlist%H", n->op, n->rlist); 1502 } 1503 if(n->ntest) { 1504 indent(fp); 1505 fmtprint(fp, "%O-test%N", n->op, n->ntest); 1506 } 1507 if(n->nbody) { 1508 indent(fp); 1509 fmtprint(fp, "%O-body%H", n->op, n->nbody); 1510 } 1511 if(n->nelse) { 1512 indent(fp); 1513 fmtprint(fp, "%O-else%H", n->op, n->nelse); 1514 } 1515 if(n->nincr) { 1516 indent(fp); 1517 fmtprint(fp, "%O-incr%N", n->op, n->nincr); 1518 } 1519 } 1520 1521 return 0; 1522 } 1523 1524 // Fmt "%S": syms 1525 // Flags: "%hS" suppresses qualifying with package 1526 static int 1527 Sconv(Fmt *fp) 1528 { 1529 Sym *s; 1530 int r, sm; 1531 unsigned long sf; 1532 1533 if(fp->flags&FmtLong) 1534 return linksymfmt(fp); 1535 1536 s = va_arg(fp->args, Sym*); 1537 if(s == S) 1538 return fmtstrcpy(fp, "<S>"); 1539 1540 if(s->name && s->name[0] == '_' && s->name[1] == '\0') 1541 return fmtstrcpy(fp, "_"); 1542 1543 sf = fp->flags; 1544 sm = setfmode(&fp->flags); 1545 r = symfmt(fp, s); 1546 fp->flags = sf; 1547 fmtmode = sm; 1548 return r; 1549 } 1550 1551 // Fmt "%T": types. 1552 // Flags: 'l' print definition, not name 1553 // 'h' omit 'func' and receiver from function types, short type names 1554 // 'u' package name, not prefix (FTypeId mode, sticky) 1555 static int 1556 Tconv(Fmt *fp) 1557 { 1558 Type *t; 1559 int r, sm; 1560 unsigned long sf; 1561 1562 t = va_arg(fp->args, Type*); 1563 if(t == T) 1564 return fmtstrcpy(fp, "<T>"); 1565 1566 if(t->trecur > 4) 1567 return fmtstrcpy(fp, "<...>"); 1568 1569 t->trecur++; 1570 sf = fp->flags; 1571 sm = setfmode(&fp->flags); 1572 1573 if(fmtmode == FTypeId && (sf&FmtUnsigned)) 1574 fmtpkgpfx++; 1575 if(fmtpkgpfx) 1576 fp->flags |= FmtUnsigned; 1577 1578 r = typefmt(fp, t); 1579 1580 if(fmtmode == FTypeId && (sf&FmtUnsigned)) 1581 fmtpkgpfx--; 1582 1583 fp->flags = sf; 1584 fmtmode = sm; 1585 t->trecur--; 1586 return r; 1587 } 1588 1589 // Fmt '%N': Nodes. 1590 // Flags: 'l' suffix with "(type %T)" where possible 1591 // '+h' in debug mode, don't recurse, no multiline output 1592 static int 1593 Nconv(Fmt *fp) 1594 { 1595 Node *n; 1596 int r, sm; 1597 unsigned long sf; 1598 1599 n = va_arg(fp->args, Node*); 1600 if(n == N) 1601 return fmtstrcpy(fp, "<N>"); 1602 sf = fp->flags; 1603 sm = setfmode(&fp->flags); 1604 1605 r = -1; 1606 switch(fmtmode) { 1607 case FErr: 1608 case FExp: 1609 r = nodefmt(fp, n); 1610 break; 1611 case FDbg: 1612 dumpdepth++; 1613 r = nodedump(fp, n); 1614 dumpdepth--; 1615 break; 1616 default: 1617 fatal("unhandled %%N mode"); 1618 } 1619 1620 fp->flags = sf; 1621 fmtmode = sm; 1622 return r; 1623 } 1624 1625 // Fmt '%H': NodeList. 1626 // Flags: all those of %N plus ',': separate with comma's instead of semicolons. 1627 static int 1628 Hconv(Fmt *fp) 1629 { 1630 NodeList *l; 1631 int r, sm; 1632 unsigned long sf; 1633 char *sep; 1634 1635 l = va_arg(fp->args, NodeList*); 1636 1637 if(l == nil && fmtmode == FDbg) 1638 return fmtstrcpy(fp, "<nil>"); 1639 1640 sf = fp->flags; 1641 sm = setfmode(&fp->flags); 1642 r = 0; 1643 sep = "; "; 1644 if(fmtmode == FDbg) 1645 sep = "\n"; 1646 else if(fp->flags & FmtComma) 1647 sep = ", "; 1648 1649 for(;l; l=l->next) { 1650 r += fmtprint(fp, "%N", l->n); 1651 if(l->next) 1652 r += fmtstrcpy(fp, sep); 1653 } 1654 1655 fp->flags = sf; 1656 fmtmode = sm; 1657 return r; 1658 } 1659 1660 void 1661 fmtinstallgo(void) 1662 { 1663 fmtmode = FErr; 1664 fmtinstall('E', Econv); // etype opcodes 1665 fmtinstall('J', Jconv); // all the node flags 1666 fmtinstall('H', Hconv); // node lists 1667 fmtinstall('L', Lconv); // line number 1668 fmtinstall('N', Nconv); // node pointer 1669 fmtinstall('O', Oconv); // node opcodes 1670 fmtinstall('S', Sconv); // sym pointer 1671 fmtinstall('T', Tconv); // type pointer 1672 fmtinstall('V', Vconv); // val pointer 1673 fmtinstall('Z', Zconv); // escaped string 1674 1675 // These are in mparith1.c 1676 fmtinstall('B', Bconv); // big numbers 1677 fmtinstall('F', Fconv); // big float numbers 1678 1679 } 1680 1681 void 1682 dumplist(char *s, NodeList *l) 1683 { 1684 print("%s%+H\n", s, l); 1685 } 1686 1687 void 1688 dump(char *s, Node *n) 1689 { 1690 print("%s [%p]%+N\n", s, n, n); 1691 }