1// Copyright 2015 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 5package demangle 6 7import ( 8 "fmt" 9 "strings" 10) 11 12// AST is an abstract syntax tree representing a C++ declaration. 13// This is sufficient for the demangler but is by no means a general C++ AST. 14// This abstract syntax tree is only used for C++ symbols, not Rust symbols. 15type AST interface { 16 // Internal method to convert to demangled string. 17 print(*printState) 18 19 // Traverse each element of an AST. If the function returns 20 // false, traversal of children of that element is skipped. 21 Traverse(func(AST) bool) 22 23 // Copy an AST with possible transformations. 24 // If the skip function returns true, no copy is required. 25 // If the copy function returns nil, no copy is required. 26 // The Copy method will do the right thing if copy returns nil 27 // for some components of an AST but not others, so a good 28 // copy function will only return non-nil for AST values that 29 // need to change. 30 // Copy itself returns either a copy or nil. 31 Copy(copy func(AST) AST, skip func(AST) bool) AST 32 33 // Implement the fmt.GoStringer interface. 34 GoString() string 35 goString(indent int, field string) string 36} 37 38// ASTToString returns the demangled name of the AST. 39func ASTToString(a AST, options ...Option) string { 40 tparams := true 41 enclosingParams := true 42 llvmStyle := false 43 max := 0 44 for _, o := range options { 45 switch { 46 case o == NoTemplateParams: 47 tparams = false 48 case o == NoEnclosingParams: 49 enclosingParams = false 50 case o == LLVMStyle: 51 llvmStyle = true 52 case isMaxLength(o): 53 max = maxLength(o) 54 } 55 } 56 57 ps := printState{ 58 tparams: tparams, 59 enclosingParams: enclosingParams, 60 llvmStyle: llvmStyle, 61 max: max, 62 scopes: 1, 63 } 64 a.print(&ps) 65 s := ps.buf.String() 66 if max > 0 && len(s) > max { 67 s = s[:max] 68 } 69 return s 70} 71 72// The printState type holds information needed to print an AST. 73type printState struct { 74 tparams bool // whether to print template parameters 75 enclosingParams bool // whether to print enclosing parameters 76 llvmStyle bool 77 max int // maximum output length 78 79 // The scopes field is used to avoid unnecessary parentheses 80 // around expressions that use > (or >>). It is incremented if 81 // we output a parenthesis or something else that means that > 82 // or >> won't be treated as ending a template. It starts out 83 // as 1, and is set to 0 when we start writing template 84 // arguments. We add parentheses around expressions using > if 85 // scopes is 0. The effect is that an expression with > gets 86 // parentheses if used as a template argument that is not 87 // inside some other set of parentheses. 88 scopes int 89 90 buf strings.Builder 91 last byte // Last byte written to buffer. 92 93 // The inner field is a list of items to print for a type 94 // name. This is used by types to implement the inside-out 95 // C++ declaration syntax. 96 inner []AST 97 98 // The printing field is a list of items we are currently 99 // printing. This avoids endless recursion if a substitution 100 // reference creates a cycle in the graph. 101 printing []AST 102} 103 104// writeByte adds a byte to the string being printed. 105func (ps *printState) writeByte(b byte) { 106 ps.last = b 107 ps.buf.WriteByte(b) 108} 109 110// writeString adds a string to the string being printed. 111func (ps *printState) writeString(s string) { 112 if len(s) > 0 { 113 ps.last = s[len(s)-1] 114 } 115 ps.buf.WriteString(s) 116} 117 118// Print an AST. 119func (ps *printState) print(a AST) { 120 if ps.max > 0 && ps.buf.Len() > ps.max { 121 return 122 } 123 124 c := 0 125 for _, v := range ps.printing { 126 if v == a { 127 // We permit the type to appear once, and 128 // return without printing anything if we see 129 // it twice. This is for a case like 130 // _Z6outer2IsEPFilES1_, where the 131 // substitution is printed differently the 132 // second time because the set of inner types 133 // is different. 134 c++ 135 if c > 1 { 136 return 137 } 138 } 139 } 140 ps.printing = append(ps.printing, a) 141 142 a.print(ps) 143 144 ps.printing = ps.printing[:len(ps.printing)-1] 145} 146 147// printList prints a list of AST values separated by commas, 148// optionally skipping some. 149func (ps *printState) printList(args []AST, skip func(AST) bool) { 150 first := true 151 for _, a := range args { 152 if skip != nil && skip(a) { 153 continue 154 } 155 if !first { 156 ps.writeString(", ") 157 } 158 159 needsParen := false 160 if ps.llvmStyle { 161 if p, ok := a.(hasPrec); ok { 162 if p.prec() >= precComma { 163 needsParen = true 164 } 165 } 166 } 167 if needsParen { 168 ps.startScope('(') 169 } 170 171 ps.print(a) 172 173 if needsParen { 174 ps.endScope(')') 175 } 176 177 first = false 178 } 179} 180 181// startScope starts a scope. This is used to decide whether we need 182// to parenthesize an expression using > or >>. 183func (ps *printState) startScope(b byte) { 184 ps.scopes++ 185 ps.writeByte(b) 186} 187 188// endScope closes a scope. 189func (ps *printState) endScope(b byte) { 190 ps.scopes-- 191 ps.writeByte(b) 192} 193 194// precedence is used for operator precedence. This is used to avoid 195// unnecessary parentheses when printing expressions in the LLVM style. 196type precedence int 197 198// The precedence values, in order from high to low. 199const ( 200 precPrimary precedence = iota 201 precPostfix 202 precUnary 203 precCast 204 precPtrMem 205 precMul 206 precAdd 207 precShift 208 precSpaceship 209 precRel 210 precEqual 211 precAnd 212 precXor 213 precOr 214 precLogicalAnd 215 precLogicalOr 216 precCond 217 precAssign 218 precComma 219 precDefault 220) 221 222// hasPrec matches the AST nodes that have a prec method that returns 223// the node's precedence. 224type hasPrec interface { 225 prec() precedence 226} 227 228// Name is an unqualified name. 229type Name struct { 230 Name string 231} 232 233func (n *Name) print(ps *printState) { 234 ps.writeString(n.Name) 235} 236 237func (n *Name) Traverse(fn func(AST) bool) { 238 fn(n) 239} 240 241func (n *Name) Copy(fn func(AST) AST, skip func(AST) bool) AST { 242 if skip(n) { 243 return nil 244 } 245 return fn(n) 246} 247 248func (n *Name) GoString() string { 249 return n.goString(0, "Name: ") 250} 251 252func (n *Name) goString(indent int, field string) string { 253 return fmt.Sprintf("%*s%s%s", indent, "", field, n.Name) 254} 255 256func (n *Name) prec() precedence { 257 return precPrimary 258} 259 260// Typed is a typed name. 261type Typed struct { 262 Name AST 263 Type AST 264} 265 266func (t *Typed) print(ps *printState) { 267 // We are printing a typed name, so ignore the current set of 268 // inner names to print. Pass down our name as the one to use. 269 holdInner := ps.inner 270 defer func() { ps.inner = holdInner }() 271 272 ps.inner = []AST{t} 273 ps.print(t.Type) 274 if len(ps.inner) > 0 { 275 // The type did not print the name; print it now in 276 // the default location. 277 ps.writeByte(' ') 278 ps.print(t.Name) 279 } 280} 281 282func (t *Typed) printInner(ps *printState) { 283 ps.print(t.Name) 284} 285 286func (t *Typed) Traverse(fn func(AST) bool) { 287 if fn(t) { 288 t.Name.Traverse(fn) 289 t.Type.Traverse(fn) 290 } 291} 292 293func (t *Typed) Copy(fn func(AST) AST, skip func(AST) bool) AST { 294 if skip(t) { 295 return nil 296 } 297 name := t.Name.Copy(fn, skip) 298 typ := t.Type.Copy(fn, skip) 299 if name == nil && typ == nil { 300 return fn(t) 301 } 302 if name == nil { 303 name = t.Name 304 } 305 if typ == nil { 306 typ = t.Type 307 } 308 t = &Typed{Name: name, Type: typ} 309 if r := fn(t); r != nil { 310 return r 311 } 312 return t 313} 314 315func (t *Typed) GoString() string { 316 return t.goString(0, "") 317} 318 319func (t *Typed) goString(indent int, field string) string { 320 return fmt.Sprintf("%*s%sTyped:\n%s\n%s", indent, "", field, 321 t.Name.goString(indent+2, "Name: "), 322 t.Type.goString(indent+2, "Type: ")) 323} 324 325// Qualified is a name in a scope. 326type Qualified struct { 327 Scope AST 328 Name AST 329 330 // The LocalName field is true if this is parsed as a 331 // <local-name>. We shouldn't really need this, but in some 332 // cases (for the unary sizeof operator) the standard 333 // demangler prints a local name slightly differently. We 334 // keep track of this for compatibility. 335 LocalName bool // A full local name encoding 336} 337 338func (q *Qualified) print(ps *printState) { 339 ps.print(q.Scope) 340 ps.writeString("::") 341 ps.print(q.Name) 342} 343 344func (q *Qualified) Traverse(fn func(AST) bool) { 345 if fn(q) { 346 q.Scope.Traverse(fn) 347 q.Name.Traverse(fn) 348 } 349} 350 351func (q *Qualified) Copy(fn func(AST) AST, skip func(AST) bool) AST { 352 if skip(q) { 353 return nil 354 } 355 scope := q.Scope.Copy(fn, skip) 356 name := q.Name.Copy(fn, skip) 357 if scope == nil && name == nil { 358 return fn(q) 359 } 360 if scope == nil { 361 scope = q.Scope 362 } 363 if name == nil { 364 name = q.Name 365 } 366 q = &Qualified{Scope: scope, Name: name, LocalName: q.LocalName} 367 if r := fn(q); r != nil { 368 return r 369 } 370 return q 371} 372 373func (q *Qualified) GoString() string { 374 return q.goString(0, "") 375} 376 377func (q *Qualified) goString(indent int, field string) string { 378 s := "" 379 if q.LocalName { 380 s = " LocalName: true" 381 } 382 return fmt.Sprintf("%*s%sQualified:%s\n%s\n%s", indent, "", field, 383 s, q.Scope.goString(indent+2, "Scope: "), 384 q.Name.goString(indent+2, "Name: ")) 385} 386 387func (q *Qualified) prec() precedence { 388 return precPrimary 389} 390 391// Template is a template with arguments. 392type Template struct { 393 Name AST 394 Args []AST 395} 396 397func (t *Template) print(ps *printState) { 398 // Inner types apply to the template as a whole, they don't 399 // cross over into the template. 400 holdInner := ps.inner 401 defer func() { ps.inner = holdInner }() 402 403 ps.inner = nil 404 ps.print(t.Name) 405 406 if !ps.tparams { 407 // Do not print template parameters. 408 return 409 } 410 // We need an extra space after operator<. 411 if ps.last == '<' { 412 ps.writeByte(' ') 413 } 414 415 scopes := ps.scopes 416 ps.scopes = 0 417 418 ps.writeByte('<') 419 ps.printList(t.Args, ps.isEmpty) 420 if ps.last == '>' && !ps.llvmStyle { 421 // Avoid syntactic ambiguity in old versions of C++. 422 ps.writeByte(' ') 423 } 424 ps.writeByte('>') 425 426 ps.scopes = scopes 427} 428 429func (t *Template) Traverse(fn func(AST) bool) { 430 if fn(t) { 431 t.Name.Traverse(fn) 432 for _, a := range t.Args { 433 a.Traverse(fn) 434 } 435 } 436} 437 438func (t *Template) Copy(fn func(AST) AST, skip func(AST) bool) AST { 439 if skip(t) { 440 return nil 441 } 442 name := t.Name.Copy(fn, skip) 443 changed := name != nil 444 args := make([]AST, len(t.Args)) 445 for i, a := range t.Args { 446 ac := a.Copy(fn, skip) 447 if ac == nil { 448 args[i] = a 449 } else { 450 args[i] = ac 451 changed = true 452 } 453 } 454 if !changed { 455 return fn(t) 456 } 457 if name == nil { 458 name = t.Name 459 } 460 t = &Template{Name: name, Args: args} 461 if r := fn(t); r != nil { 462 return r 463 } 464 return t 465} 466 467func (t *Template) GoString() string { 468 return t.goString(0, "") 469} 470 471func (t *Template) goString(indent int, field string) string { 472 var args string 473 if len(t.Args) == 0 { 474 args = fmt.Sprintf("%*sArgs: nil", indent+2, "") 475 } else { 476 args = fmt.Sprintf("%*sArgs:", indent+2, "") 477 for i, a := range t.Args { 478 args += "\n" 479 args += a.goString(indent+4, fmt.Sprintf("%d: ", i)) 480 } 481 } 482 return fmt.Sprintf("%*s%sTemplate (%p):\n%s\n%s", indent, "", field, t, 483 t.Name.goString(indent+2, "Name: "), args) 484} 485 486// TemplateParam is a template parameter. The Template field is 487// filled in while parsing the demangled string. We don't normally 488// see these while printing--they are replaced by the simplify 489// function. 490type TemplateParam struct { 491 Index int 492 Template *Template 493} 494 495func (tp *TemplateParam) print(ps *printState) { 496 if tp.Template == nil { 497 panic("TemplateParam Template field is nil") 498 } 499 if tp.Index >= len(tp.Template.Args) { 500 panic("TemplateParam Index out of bounds") 501 } 502 ps.print(tp.Template.Args[tp.Index]) 503} 504 505func (tp *TemplateParam) Traverse(fn func(AST) bool) { 506 fn(tp) 507 // Don't traverse Template--it points elsewhere in the AST. 508} 509 510func (tp *TemplateParam) Copy(fn func(AST) AST, skip func(AST) bool) AST { 511 if skip(tp) { 512 return nil 513 } 514 return fn(tp) 515} 516 517func (tp *TemplateParam) GoString() string { 518 return tp.goString(0, "") 519} 520 521func (tp *TemplateParam) goString(indent int, field string) string { 522 return fmt.Sprintf("%*s%sTemplateParam: Template: %p; Index %d", indent, "", field, tp.Template, tp.Index) 523} 524 525// LambdaAuto is a lambda auto parameter. 526type LambdaAuto struct { 527 Index int 528} 529 530func (la *LambdaAuto) print(ps *printState) { 531 // We print the index plus 1 because that is what the standard 532 // demangler does. 533 if ps.llvmStyle { 534 ps.writeString("auto") 535 } else { 536 fmt.Fprintf(&ps.buf, "auto:%d", la.Index+1) 537 } 538} 539 540func (la *LambdaAuto) Traverse(fn func(AST) bool) { 541 fn(la) 542} 543 544func (la *LambdaAuto) Copy(fn func(AST) AST, skip func(AST) bool) AST { 545 if skip(la) { 546 return nil 547 } 548 return fn(la) 549} 550 551func (la *LambdaAuto) GoString() string { 552 return la.goString(0, "") 553} 554 555func (la *LambdaAuto) goString(indent int, field string) string { 556 return fmt.Sprintf("%*s%sLambdaAuto: Index %d", indent, "", field, la.Index) 557} 558 559// TemplateParamQualifiedArg is used when the mangled name includes 560// both the template parameter declaration and the template argument. 561// See https://github.com/itanium-cxx-abi/cxx-abi/issues/47. 562type TemplateParamQualifiedArg struct { 563 Param AST 564 Arg AST 565} 566 567func (tpqa *TemplateParamQualifiedArg) print(ps *printState) { 568 // We only demangle the actual template argument. 569 // That is what the LLVM demangler does. 570 // The parameter disambiguates the argument, 571 // but is hopefully not required by a human reader. 572 ps.print(tpqa.Arg) 573} 574 575func (tpqa *TemplateParamQualifiedArg) Traverse(fn func(AST) bool) { 576 if fn(tpqa) { 577 tpqa.Param.Traverse(fn) 578 tpqa.Arg.Traverse(fn) 579 } 580} 581 582func (tpqa *TemplateParamQualifiedArg) Copy(fn func(AST) AST, skip func(AST) bool) AST { 583 if skip(tpqa) { 584 return nil 585 } 586 param := tpqa.Param.Copy(fn, skip) 587 arg := tpqa.Arg.Copy(fn, skip) 588 if param == nil && arg == nil { 589 return fn(tpqa) 590 } 591 if param == nil { 592 param = tpqa.Param 593 } 594 if arg == nil { 595 arg = tpqa.Arg 596 } 597 tpqa = &TemplateParamQualifiedArg{Param: param, Arg: arg} 598 if r := fn(tpqa); r != nil { 599 return r 600 } 601 return tpqa 602} 603 604func (tpqa *TemplateParamQualifiedArg) GoString() string { 605 return tpqa.goString(0, "") 606} 607 608func (tpqa *TemplateParamQualifiedArg) goString(indent int, field string) string { 609 return fmt.Sprintf("%*s%sTemplateParamQualifiedArg:\n%s\n%s", indent, "", field, 610 tpqa.Param.goString(indent+2, "Param: "), 611 tpqa.Arg.goString(indent+2, "Arg: ")) 612} 613 614// Qualifiers is an ordered list of type qualifiers. 615type Qualifiers struct { 616 Qualifiers []AST 617} 618 619func (qs *Qualifiers) print(ps *printState) { 620 first := true 621 for _, q := range qs.Qualifiers { 622 if !first { 623 ps.writeByte(' ') 624 } 625 q.print(ps) 626 first = false 627 } 628} 629 630func (qs *Qualifiers) Traverse(fn func(AST) bool) { 631 if fn(qs) { 632 for _, q := range qs.Qualifiers { 633 q.Traverse(fn) 634 } 635 } 636} 637 638func (qs *Qualifiers) Copy(fn func(AST) AST, skip func(AST) bool) AST { 639 if skip(qs) { 640 return nil 641 } 642 changed := false 643 qualifiers := make([]AST, len(qs.Qualifiers)) 644 for i, q := range qs.Qualifiers { 645 qc := q.Copy(fn, skip) 646 if qc == nil { 647 qualifiers[i] = q 648 } else { 649 qualifiers[i] = qc 650 changed = true 651 } 652 } 653 if !changed { 654 return fn(qs) 655 } 656 qs = &Qualifiers{Qualifiers: qualifiers} 657 if r := fn(qs); r != nil { 658 return r 659 } 660 return qs 661} 662 663func (qs *Qualifiers) GoString() string { 664 return qs.goString(0, "") 665} 666 667func (qs *Qualifiers) goString(indent int, field string) string { 668 quals := fmt.Sprintf("%*s%s", indent, "", field) 669 for _, q := range qs.Qualifiers { 670 quals += "\n" 671 quals += q.goString(indent+2, "") 672 } 673 return quals 674} 675 676// Qualifier is a single type qualifier. 677type Qualifier struct { 678 Name string // qualifier name: const, volatile, etc. 679 Exprs []AST // can be non-nil for noexcept and throw 680} 681 682func (q *Qualifier) print(ps *printState) { 683 ps.writeString(q.Name) 684 if len(q.Exprs) > 0 { 685 ps.startScope('(') 686 first := true 687 for _, e := range q.Exprs { 688 if el, ok := e.(*ExprList); ok && len(el.Exprs) == 0 { 689 continue 690 } 691 if !first { 692 ps.writeString(", ") 693 } 694 ps.print(e) 695 first = false 696 } 697 ps.endScope(')') 698 } 699} 700 701func (q *Qualifier) Traverse(fn func(AST) bool) { 702 if fn(q) { 703 for _, e := range q.Exprs { 704 e.Traverse(fn) 705 } 706 } 707} 708 709func (q *Qualifier) Copy(fn func(AST) AST, skip func(AST) bool) AST { 710 if skip(q) { 711 return nil 712 } 713 exprs := make([]AST, len(q.Exprs)) 714 changed := false 715 for i, e := range q.Exprs { 716 ec := e.Copy(fn, skip) 717 if ec == nil { 718 exprs[i] = e 719 } else { 720 exprs[i] = ec 721 changed = true 722 } 723 } 724 if !changed { 725 return fn(q) 726 } 727 q = &Qualifier{Name: q.Name, Exprs: exprs} 728 if r := fn(q); r != nil { 729 return r 730 } 731 return q 732} 733 734func (q *Qualifier) GoString() string { 735 return q.goString(0, "Qualifier: ") 736} 737 738func (q *Qualifier) goString(indent int, field string) string { 739 qs := fmt.Sprintf("%*s%s%s", indent, "", field, q.Name) 740 if len(q.Exprs) > 0 { 741 for i, e := range q.Exprs { 742 qs += "\n" 743 qs += e.goString(indent+2, fmt.Sprintf("%d: ", i)) 744 } 745 } 746 return qs 747} 748 749// TypeWithQualifiers is a type with standard qualifiers. 750type TypeWithQualifiers struct { 751 Base AST 752 Qualifiers AST 753} 754 755func (twq *TypeWithQualifiers) print(ps *printState) { 756 // Give the base type a chance to print the inner types. 757 ps.inner = append(ps.inner, twq) 758 ps.print(twq.Base) 759 if len(ps.inner) > 0 { 760 // The qualifier wasn't printed by Base. 761 ps.writeByte(' ') 762 ps.print(twq.Qualifiers) 763 ps.inner = ps.inner[:len(ps.inner)-1] 764 } 765} 766 767// Print qualifiers as an inner type by just printing the qualifiers. 768func (twq *TypeWithQualifiers) printInner(ps *printState) { 769 ps.writeByte(' ') 770 ps.print(twq.Qualifiers) 771} 772 773func (twq *TypeWithQualifiers) Traverse(fn func(AST) bool) { 774 if fn(twq) { 775 twq.Base.Traverse(fn) 776 } 777} 778 779func (twq *TypeWithQualifiers) Copy(fn func(AST) AST, skip func(AST) bool) AST { 780 if skip(twq) { 781 return nil 782 } 783 base := twq.Base.Copy(fn, skip) 784 quals := twq.Qualifiers.Copy(fn, skip) 785 if base == nil && quals == nil { 786 return fn(twq) 787 } 788 if base == nil { 789 base = twq.Base 790 } 791 if quals == nil { 792 quals = twq.Qualifiers 793 } 794 twq = &TypeWithQualifiers{Base: base, Qualifiers: quals} 795 if r := fn(twq); r != nil { 796 return r 797 } 798 return twq 799} 800 801func (twq *TypeWithQualifiers) GoString() string { 802 return twq.goString(0, "") 803} 804 805func (twq *TypeWithQualifiers) goString(indent int, field string) string { 806 return fmt.Sprintf("%*s%sTypeWithQualifiers:\n%s\n%s", indent, "", field, 807 twq.Qualifiers.goString(indent+2, "Qualifiers: "), 808 twq.Base.goString(indent+2, "Base: ")) 809} 810 811// MethodWithQualifiers is a method with qualifiers. 812type MethodWithQualifiers struct { 813 Method AST 814 Qualifiers AST 815 RefQualifier string // "" or "&" or "&&" 816} 817 818func (mwq *MethodWithQualifiers) print(ps *printState) { 819 // Give the base type a chance to print the inner types. 820 ps.inner = append(ps.inner, mwq) 821 ps.print(mwq.Method) 822 if len(ps.inner) > 0 { 823 if mwq.Qualifiers != nil { 824 ps.writeByte(' ') 825 ps.print(mwq.Qualifiers) 826 } 827 if mwq.RefQualifier != "" { 828 ps.writeByte(' ') 829 ps.writeString(mwq.RefQualifier) 830 } 831 ps.inner = ps.inner[:len(ps.inner)-1] 832 } 833} 834 835func (mwq *MethodWithQualifiers) printInner(ps *printState) { 836 if mwq.Qualifiers != nil { 837 ps.writeByte(' ') 838 ps.print(mwq.Qualifiers) 839 } 840 if mwq.RefQualifier != "" { 841 ps.writeByte(' ') 842 ps.writeString(mwq.RefQualifier) 843 } 844} 845 846func (mwq *MethodWithQualifiers) Traverse(fn func(AST) bool) { 847 if fn(mwq) { 848 mwq.Method.Traverse(fn) 849 } 850} 851 852func (mwq *MethodWithQualifiers) Copy(fn func(AST) AST, skip func(AST) bool) AST { 853 if skip(mwq) { 854 return nil 855 } 856 method := mwq.Method.Copy(fn, skip) 857 var quals AST 858 if mwq.Qualifiers != nil { 859 quals = mwq.Qualifiers.Copy(fn, skip) 860 } 861 if method == nil && quals == nil { 862 return fn(mwq) 863 } 864 if method == nil { 865 method = mwq.Method 866 } 867 if quals == nil { 868 quals = mwq.Qualifiers 869 } 870 mwq = &MethodWithQualifiers{Method: method, Qualifiers: quals, RefQualifier: mwq.RefQualifier} 871 if r := fn(mwq); r != nil { 872 return r 873 } 874 return mwq 875} 876 877func (mwq *MethodWithQualifiers) GoString() string { 878 return mwq.goString(0, "") 879} 880 881func (mwq *MethodWithQualifiers) goString(indent int, field string) string { 882 var q string 883 if mwq.Qualifiers != nil { 884 q += "\n" + mwq.Qualifiers.goString(indent+2, "Qualifiers: ") 885 } 886 if mwq.RefQualifier != "" { 887 if q != "" { 888 q += "\n" 889 } 890 q += fmt.Sprintf("%*s%s%s", indent+2, "", "RefQualifier: ", mwq.RefQualifier) 891 } 892 return fmt.Sprintf("%*s%sMethodWithQualifiers:%s\n%s", indent, "", field, 893 q, mwq.Method.goString(indent+2, "Method: ")) 894} 895 896// BuiltinType is a builtin type, like "int". 897type BuiltinType struct { 898 Name string 899} 900 901func (bt *BuiltinType) print(ps *printState) { 902 name := bt.Name 903 if ps.llvmStyle && name == "decltype(nullptr)" { 904 name = "std::nullptr_t" 905 } 906 ps.writeString(name) 907} 908 909func (bt *BuiltinType) Traverse(fn func(AST) bool) { 910 fn(bt) 911} 912 913func (bt *BuiltinType) Copy(fn func(AST) AST, skip func(AST) bool) AST { 914 if skip(bt) { 915 return nil 916 } 917 return fn(bt) 918} 919 920func (bt *BuiltinType) GoString() string { 921 return bt.goString(0, "") 922} 923 924func (bt *BuiltinType) goString(indent int, field string) string { 925 return fmt.Sprintf("%*s%sBuiltinType: %s", indent, "", field, bt.Name) 926} 927 928func (bt *BuiltinType) prec() precedence { 929 return precPrimary 930} 931 932// printBase is common print code for types that are printed with a 933// simple suffix. 934func printBase(ps *printState, qual, base AST) { 935 ps.inner = append(ps.inner, qual) 936 ps.print(base) 937 if len(ps.inner) > 0 { 938 qual.(innerPrinter).printInner(ps) 939 ps.inner = ps.inner[:len(ps.inner)-1] 940 } 941} 942 943// PointerType is a pointer type. 944type PointerType struct { 945 Base AST 946} 947 948func (pt *PointerType) print(ps *printState) { 949 printBase(ps, pt, pt.Base) 950} 951 952func (pt *PointerType) printInner(ps *printState) { 953 ps.writeString("*") 954} 955 956func (pt *PointerType) Traverse(fn func(AST) bool) { 957 if fn(pt) { 958 pt.Base.Traverse(fn) 959 } 960} 961 962func (pt *PointerType) Copy(fn func(AST) AST, skip func(AST) bool) AST { 963 if skip(pt) { 964 return nil 965 } 966 base := pt.Base.Copy(fn, skip) 967 if base == nil { 968 return fn(pt) 969 } 970 pt = &PointerType{Base: base} 971 if r := fn(pt); r != nil { 972 return r 973 } 974 return pt 975} 976 977func (pt *PointerType) GoString() string { 978 return pt.goString(0, "") 979} 980 981func (pt *PointerType) goString(indent int, field string) string { 982 return fmt.Sprintf("%*s%sPointerType:\n%s", indent, "", field, 983 pt.Base.goString(indent+2, "")) 984} 985 986// ReferenceType is a reference type. 987type ReferenceType struct { 988 Base AST 989} 990 991func (rt *ReferenceType) print(ps *printState) { 992 printBase(ps, rt, rt.Base) 993} 994 995func (rt *ReferenceType) printInner(ps *printState) { 996 ps.writeString("&") 997} 998 999func (rt *ReferenceType) Traverse(fn func(AST) bool) { 1000 if fn(rt) { 1001 rt.Base.Traverse(fn) 1002 } 1003} 1004 1005func (rt *ReferenceType) Copy(fn func(AST) AST, skip func(AST) bool) AST { 1006 if skip(rt) { 1007 return nil 1008 } 1009 base := rt.Base.Copy(fn, skip) 1010 if base == nil { 1011 return fn(rt) 1012 } 1013 rt = &ReferenceType{Base: base} 1014 if r := fn(rt); r != nil { 1015 return r 1016 } 1017 return rt 1018} 1019 1020func (rt *ReferenceType) GoString() string { 1021 return rt.goString(0, "") 1022} 1023 1024func (rt *ReferenceType) goString(indent int, field string) string { 1025 return fmt.Sprintf("%*s%sReferenceType:\n%s", indent, "", field, 1026 rt.Base.goString(indent+2, "")) 1027} 1028 1029// RvalueReferenceType is an rvalue reference type. 1030type RvalueReferenceType struct { 1031 Base AST 1032} 1033 1034func (rt *RvalueReferenceType) print(ps *printState) { 1035 printBase(ps, rt, rt.Base) 1036} 1037 1038func (rt *RvalueReferenceType) printInner(ps *printState) { 1039 ps.writeString("&&") 1040} 1041 1042func (rt *RvalueReferenceType) Traverse(fn func(AST) bool) { 1043 if fn(rt) { 1044 rt.Base.Traverse(fn) 1045 } 1046} 1047 1048func (rt *RvalueReferenceType) Copy(fn func(AST) AST, skip func(AST) bool) AST { 1049 if skip(rt) { 1050 return nil 1051 } 1052 base := rt.Base.Copy(fn, skip) 1053 if base == nil { 1054 return fn(rt) 1055 } 1056 rt = &RvalueReferenceType{Base: base} 1057 if r := fn(rt); r != nil { 1058 return r 1059 } 1060 return rt 1061} 1062 1063func (rt *RvalueReferenceType) GoString() string { 1064 return rt.goString(0, "") 1065} 1066 1067func (rt *RvalueReferenceType) goString(indent int, field string) string { 1068 return fmt.Sprintf("%*s%sRvalueReferenceType:\n%s", indent, "", field, 1069 rt.Base.goString(indent+2, "")) 1070} 1071 1072// ComplexType is a complex type. 1073type ComplexType struct { 1074 Base AST 1075} 1076 1077func (ct *ComplexType) print(ps *printState) { 1078 printBase(ps, ct, ct.Base) 1079} 1080 1081func (ct *ComplexType) printInner(ps *printState) { 1082 ps.writeString(" _Complex") 1083} 1084 1085func (ct *ComplexType) Traverse(fn func(AST) bool) { 1086 if fn(ct) { 1087 ct.Base.Traverse(fn) 1088 } 1089} 1090 1091func (ct *ComplexType) Copy(fn func(AST) AST, skip func(AST) bool) AST { 1092 if skip(ct) { 1093 return nil 1094 } 1095 base := ct.Base.Copy(fn, skip) 1096 if base == nil { 1097 return fn(ct) 1098 } 1099 ct = &ComplexType{Base: base} 1100 if r := fn(ct); r != nil { 1101 return r 1102 } 1103 return ct 1104} 1105 1106func (ct *ComplexType) GoString() string { 1107 return ct.goString(0, "") 1108} 1109 1110func (ct *ComplexType) goString(indent int, field string) string { 1111 return fmt.Sprintf("%*s%sComplexType:\n%s", indent, "", field, 1112 ct.Base.goString(indent+2, "")) 1113} 1114 1115// ImaginaryType is an imaginary type. 1116type ImaginaryType struct { 1117 Base AST 1118} 1119 1120func (it *ImaginaryType) print(ps *printState) { 1121 printBase(ps, it, it.Base) 1122} 1123 1124func (it *ImaginaryType) printInner(ps *printState) { 1125 ps.writeString(" _Imaginary") 1126} 1127 1128func (it *ImaginaryType) Traverse(fn func(AST) bool) { 1129 if fn(it) { 1130 it.Base.Traverse(fn) 1131 } 1132} 1133 1134func (it *ImaginaryType) Copy(fn func(AST) AST, skip func(AST) bool) AST { 1135 if skip(it) { 1136 return nil 1137 } 1138 base := it.Base.Copy(fn, skip) 1139 if base == nil { 1140 return fn(it) 1141 } 1142 it = &ImaginaryType{Base: base} 1143 if r := fn(it); r != nil { 1144 return r 1145 } 1146 return it 1147} 1148 1149func (it *ImaginaryType) GoString() string { 1150 return it.goString(0, "") 1151} 1152 1153func (it *ImaginaryType) goString(indent int, field string) string { 1154 return fmt.Sprintf("%*s%sImaginaryType:\n%s", indent, "", field, 1155 it.Base.goString(indent+2, "")) 1156} 1157 1158// SuffixType is an type with an arbitrary suffix. 1159type SuffixType struct { 1160 Base AST 1161 Suffix string 1162} 1163 1164func (st *SuffixType) print(ps *printState) { 1165 printBase(ps, st, st.Base) 1166} 1167 1168func (st *SuffixType) printInner(ps *printState) { 1169 ps.writeByte(' ') 1170 ps.writeString(st.Suffix) 1171} 1172 1173func (st *SuffixType) Traverse(fn func(AST) bool) { 1174 if fn(st) { 1175 st.Base.Traverse(fn) 1176 } 1177} 1178 1179func (st *SuffixType) Copy(fn func(AST) AST, skip func(AST) bool) AST { 1180 if skip(st) { 1181 return nil 1182 } 1183 base := st.Base.Copy(fn, skip) 1184 if base == nil { 1185 return fn(st) 1186 } 1187 st = &SuffixType{Base: base, Suffix: st.Suffix} 1188 if r := fn(st); r != nil { 1189 return r 1190 } 1191 return st 1192} 1193 1194func (st *SuffixType) GoString() string { 1195 return st.goString(0, "") 1196} 1197 1198func (st *SuffixType) goString(indent int, field string) string { 1199 return fmt.Sprintf("%*s%sSuffixType: %s\n%s", indent, "", field, 1200 st.Suffix, st.Base.goString(indent+2, "Base: ")) 1201} 1202 1203// TransformedType is a builtin type with a template argument. 1204type TransformedType struct { 1205 Name string 1206 Base AST 1207} 1208 1209func (tt *TransformedType) print(ps *printState) { 1210 ps.writeString(tt.Name) 1211 ps.startScope('(') 1212 ps.print(tt.Base) 1213 ps.endScope(')') 1214} 1215 1216func (tt *TransformedType) Traverse(fn func(AST) bool) { 1217 if fn(tt) { 1218 tt.Base.Traverse(fn) 1219 } 1220} 1221 1222func (tt *TransformedType) Copy(fn func(AST) AST, skip func(AST) bool) AST { 1223 if skip(tt) { 1224 return nil 1225 } 1226 base := tt.Base.Copy(fn, skip) 1227 if base == nil { 1228 return fn(tt) 1229 } 1230 tt = &TransformedType{Name: tt.Name, Base: base} 1231 if r := fn(tt); r != nil { 1232 return r 1233 } 1234 return tt 1235} 1236 1237func (tt *TransformedType) GoString() string { 1238 return tt.goString(0, "") 1239} 1240 1241func (tt *TransformedType) goString(indent int, field string) string { 1242 return fmt.Sprintf("%*s%sTransformedType: %s\n%s", indent, "", field, 1243 tt.Name, tt.Base.goString(indent+2, "Base: ")) 1244} 1245 1246// VendorQualifier is a type qualified by a vendor-specific qualifier. 1247type VendorQualifier struct { 1248 Qualifier AST 1249 Type AST 1250} 1251 1252func (vq *VendorQualifier) print(ps *printState) { 1253 if ps.llvmStyle { 1254 ps.print(vq.Type) 1255 vq.printInner(ps) 1256 } else { 1257 ps.inner = append(ps.inner, vq) 1258 ps.print(vq.Type) 1259 if len(ps.inner) > 0 { 1260 ps.printOneInner(nil) 1261 } 1262 } 1263} 1264 1265func (vq *VendorQualifier) printInner(ps *printState) { 1266 ps.writeByte(' ') 1267 ps.print(vq.Qualifier) 1268} 1269 1270func (vq *VendorQualifier) Traverse(fn func(AST) bool) { 1271 if fn(vq) { 1272 vq.Qualifier.Traverse(fn) 1273 vq.Type.Traverse(fn) 1274 } 1275} 1276 1277func (vq *VendorQualifier) Copy(fn func(AST) AST, skip func(AST) bool) AST { 1278 if skip(vq) { 1279 return nil 1280 } 1281 qualifier := vq.Qualifier.Copy(fn, skip) 1282 typ := vq.Type.Copy(fn, skip) 1283 if qualifier == nil && typ == nil { 1284 return fn(vq) 1285 } 1286 if qualifier == nil { 1287 qualifier = vq.Qualifier 1288 } 1289 if typ == nil { 1290 typ = vq.Type 1291 } 1292 vq = &VendorQualifier{Qualifier: qualifier, Type: vq.Type} 1293 if r := fn(vq); r != nil { 1294 return r 1295 } 1296 return vq 1297} 1298 1299func (vq *VendorQualifier) GoString() string { 1300 return vq.goString(0, "") 1301} 1302 1303func (vq *VendorQualifier) goString(indent int, field string) string { 1304 return fmt.Sprintf("%*s%sVendorQualifier:\n%s\n%s", indent, "", field, 1305 vq.Qualifier.goString(indent+2, "Qualifier: "), 1306 vq.Type.goString(indent+2, "Type: ")) 1307} 1308 1309// ArrayType is an array type. 1310type ArrayType struct { 1311 Dimension AST 1312 Element AST 1313} 1314 1315func (at *ArrayType) print(ps *printState) { 1316 // Pass the array type down as an inner type so that we print 1317 // multi-dimensional arrays correctly. 1318 ps.inner = append(ps.inner, at) 1319 ps.print(at.Element) 1320 if ln := len(ps.inner); ln > 0 { 1321 ps.inner = ps.inner[:ln-1] 1322 at.printDimension(ps) 1323 } 1324} 1325 1326func (at *ArrayType) printInner(ps *printState) { 1327 at.printDimension(ps) 1328} 1329 1330// Print the array dimension. 1331func (at *ArrayType) printDimension(ps *printState) { 1332 space := " " 1333 for len(ps.inner) > 0 { 1334 // We haven't gotten to the real type yet. Use 1335 // parentheses around that type, except that if it is 1336 // an array type we print it as a multi-dimensional 1337 // array 1338 in := ps.inner[len(ps.inner)-1] 1339 if twq, ok := in.(*TypeWithQualifiers); ok { 1340 in = twq.Base 1341 } 1342 if _, ok := in.(*ArrayType); ok { 1343 if in == ps.inner[len(ps.inner)-1] { 1344 space = "" 1345 } 1346 ps.printOneInner(nil) 1347 } else { 1348 ps.writeByte(' ') 1349 ps.startScope('(') 1350 ps.printInner(false) 1351 ps.endScope(')') 1352 } 1353 } 1354 ps.writeString(space) 1355 ps.writeByte('[') 1356 ps.print(at.Dimension) 1357 ps.writeByte(']') 1358} 1359 1360func (at *ArrayType) Traverse(fn func(AST) bool) { 1361 if fn(at) { 1362 at.Dimension.Traverse(fn) 1363 at.Element.Traverse(fn) 1364 } 1365} 1366 1367func (at *ArrayType) Copy(fn func(AST) AST, skip func(AST) bool) AST { 1368 if skip(at) { 1369 return nil 1370 } 1371 dimension := at.Dimension.Copy(fn, skip) 1372 element := at.Element.Copy(fn, skip) 1373 if dimension == nil && element == nil { 1374 return fn(at) 1375 } 1376 if dimension == nil { 1377 dimension = at.Dimension 1378 } 1379 if element == nil { 1380 element = at.Element 1381 } 1382 at = &ArrayType{Dimension: dimension, Element: element} 1383 if r := fn(at); r != nil { 1384 return r 1385 } 1386 return at 1387} 1388 1389func (at *ArrayType) GoString() string { 1390 return at.goString(0, "") 1391} 1392 1393func (at *ArrayType) goString(indent int, field string) string { 1394 return fmt.Sprintf("%*s%sArrayType:\n%s\n%s", indent, "", field, 1395 at.Dimension.goString(indent+2, "Dimension: "), 1396 at.Element.goString(indent+2, "Element: ")) 1397} 1398 1399// FunctionType is a function type. 1400type FunctionType struct { 1401 Return AST 1402 Args []AST 1403 1404 // The forLocalName field reports whether this FunctionType 1405 // was created for a local name. With the default GNU demangling 1406 // output we don't print the return type in that case. 1407 ForLocalName bool 1408} 1409 1410func (ft *FunctionType) print(ps *printState) { 1411 retType := ft.Return 1412 if ft.ForLocalName && (!ps.enclosingParams || !ps.llvmStyle) { 1413 retType = nil 1414 } 1415 if retType != nil { 1416 // Pass the return type as an inner type in order to 1417 // print the arguments in the right location. 1418 ps.inner = append(ps.inner, ft) 1419 ps.print(retType) 1420 if len(ps.inner) == 0 { 1421 // Everything was printed. 1422 return 1423 } 1424 ps.inner = ps.inner[:len(ps.inner)-1] 1425 ps.writeByte(' ') 1426 } 1427 ft.printArgs(ps) 1428} 1429 1430func (ft *FunctionType) printInner(ps *printState) { 1431 ft.printArgs(ps) 1432} 1433 1434// printArgs prints the arguments of a function type. It looks at the 1435// inner types for spacing. 1436func (ft *FunctionType) printArgs(ps *printState) { 1437 paren := false 1438 space := false 1439 for i := len(ps.inner) - 1; i >= 0; i-- { 1440 switch ps.inner[i].(type) { 1441 case *PointerType, *ReferenceType, *RvalueReferenceType: 1442 paren = true 1443 case *TypeWithQualifiers, *ComplexType, *ImaginaryType, *PtrMem: 1444 space = true 1445 paren = true 1446 } 1447 if paren { 1448 break 1449 } 1450 } 1451 1452 if paren { 1453 if !space && (ps.last != '(' && ps.last != '*') { 1454 space = true 1455 } 1456 if space && ps.last != ' ' { 1457 ps.writeByte(' ') 1458 } 1459 ps.startScope('(') 1460 } 1461 1462 save := ps.printInner(true) 1463 1464 if paren { 1465 ps.endScope(')') 1466 } 1467 1468 ps.startScope('(') 1469 if !ft.ForLocalName || ps.enclosingParams { 1470 first := true 1471 for _, a := range ft.Args { 1472 if ps.isEmpty(a) { 1473 continue 1474 } 1475 if !first { 1476 ps.writeString(", ") 1477 } 1478 ps.print(a) 1479 first = false 1480 } 1481 } 1482 ps.endScope(')') 1483 1484 ps.inner = save 1485 ps.printInner(false) 1486} 1487 1488func (ft *FunctionType) Traverse(fn func(AST) bool) { 1489 if fn(ft) { 1490 if ft.Return != nil { 1491 ft.Return.Traverse(fn) 1492 } 1493 for _, a := range ft.Args { 1494 a.Traverse(fn) 1495 } 1496 } 1497} 1498 1499func (ft *FunctionType) Copy(fn func(AST) AST, skip func(AST) bool) AST { 1500 if skip(ft) { 1501 return nil 1502 } 1503 changed := false 1504 var ret AST 1505 if ft.Return != nil { 1506 ret = ft.Return.Copy(fn, skip) 1507 if ret == nil { 1508 ret = ft.Return 1509 } else { 1510 changed = true 1511 } 1512 } 1513 args := make([]AST, len(ft.Args)) 1514 for i, a := range ft.Args { 1515 ac := a.Copy(fn, skip) 1516 if ac == nil { 1517 args[i] = a 1518 } else { 1519 args[i] = ac 1520 changed = true 1521 } 1522 } 1523 if !changed { 1524 return fn(ft) 1525 } 1526 ft = &FunctionType{ 1527 Return: ret, 1528 Args: args, 1529 ForLocalName: ft.ForLocalName, 1530 } 1531 if r := fn(ft); r != nil { 1532 return r 1533 } 1534 return ft 1535} 1536 1537func (ft *FunctionType) GoString() string { 1538 return ft.goString(0, "") 1539} 1540 1541func (ft *FunctionType) goString(indent int, field string) string { 1542 var forLocalName string 1543 if ft.ForLocalName { 1544 forLocalName = " ForLocalName: true" 1545 } 1546 var r string 1547 if ft.Return == nil { 1548 r = fmt.Sprintf("%*sReturn: nil", indent+2, "") 1549 } else { 1550 r = ft.Return.goString(indent+2, "Return: ") 1551 } 1552 var args string 1553 if len(ft.Args) == 0 { 1554 args = fmt.Sprintf("%*sArgs: nil", indent+2, "") 1555 } else { 1556 args = fmt.Sprintf("%*sArgs:", indent+2, "") 1557 for i, a := range ft.Args { 1558 args += "\n" 1559 args += a.goString(indent+4, fmt.Sprintf("%d: ", i)) 1560 } 1561 } 1562 return fmt.Sprintf("%*s%sFunctionType:%s\n%s\n%s", indent, "", field, 1563 forLocalName, r, args) 1564} 1565 1566// FunctionParam is a parameter of a function, used for last-specified 1567// return type in a closure. 1568type FunctionParam struct { 1569 Index int 1570} 1571 1572func (fp *FunctionParam) print(ps *printState) { 1573 if fp.Index == 0 { 1574 ps.writeString("this") 1575 } else if ps.llvmStyle { 1576 if fp.Index == 1 { 1577 ps.writeString("fp") 1578 } else { 1579 fmt.Fprintf(&ps.buf, "fp%d", fp.Index-2) 1580 } 1581 } else { 1582 fmt.Fprintf(&ps.buf, "{parm#%d}", fp.Index) 1583 } 1584} 1585 1586func (fp *FunctionParam) Traverse(fn func(AST) bool) { 1587 fn(fp) 1588} 1589 1590func (fp *FunctionParam) Copy(fn func(AST) AST, skip func(AST) bool) AST { 1591 if skip(fp) { 1592 return nil 1593 } 1594 return fn(fp) 1595} 1596 1597func (fp *FunctionParam) GoString() string { 1598 return fp.goString(0, "") 1599} 1600 1601func (fp *FunctionParam) goString(indent int, field string) string { 1602 return fmt.Sprintf("%*s%sFunctionParam: %d", indent, "", field, fp.Index) 1603} 1604 1605func (fp *FunctionParam) prec() precedence { 1606 return precPrimary 1607} 1608 1609// PtrMem is a pointer-to-member expression. 1610type PtrMem struct { 1611 Class AST 1612 Member AST 1613} 1614 1615func (pm *PtrMem) print(ps *printState) { 1616 ps.inner = append(ps.inner, pm) 1617 ps.print(pm.Member) 1618 if len(ps.inner) > 0 { 1619 ps.printOneInner(nil) 1620 } 1621} 1622 1623func (pm *PtrMem) printInner(ps *printState) { 1624 if ps.last != '(' { 1625 ps.writeByte(' ') 1626 } 1627 ps.print(pm.Class) 1628 ps.writeString("::*") 1629} 1630 1631func (pm *PtrMem) Traverse(fn func(AST) bool) { 1632 if fn(pm) { 1633 pm.Class.Traverse(fn) 1634 pm.Member.Traverse(fn) 1635 } 1636} 1637 1638func (pm *PtrMem) Copy(fn func(AST) AST, skip func(AST) bool) AST { 1639 if skip(pm) { 1640 return nil 1641 } 1642 class := pm.Class.Copy(fn, skip) 1643 member := pm.Member.Copy(fn, skip) 1644 if class == nil && member == nil { 1645 return fn(pm) 1646 } 1647 if class == nil { 1648 class = pm.Class 1649 } 1650 if member == nil { 1651 member = pm.Member 1652 } 1653 pm = &PtrMem{Class: class, Member: member} 1654 if r := fn(pm); r != nil { 1655 return r 1656 } 1657 return pm 1658} 1659 1660func (pm *PtrMem) GoString() string { 1661 return pm.goString(0, "") 1662} 1663 1664func (pm *PtrMem) goString(indent int, field string) string { 1665 return fmt.Sprintf("%*s%sPtrMem:\n%s\n%s", indent, "", field, 1666 pm.Class.goString(indent+2, "Class: "), 1667 pm.Member.goString(indent+2, "Member: ")) 1668} 1669 1670// FixedType is a fixed numeric type of unknown size. 1671type FixedType struct { 1672 Base AST 1673 Accum bool 1674 Sat bool 1675} 1676 1677func (ft *FixedType) print(ps *printState) { 1678 if ft.Sat { 1679 ps.writeString("_Sat ") 1680 } 1681 if bt, ok := ft.Base.(*BuiltinType); ok && bt.Name == "int" { 1682 // The standard demangler skips printing "int". 1683 } else { 1684 ps.print(ft.Base) 1685 ps.writeByte(' ') 1686 } 1687 if ft.Accum { 1688 ps.writeString("_Accum") 1689 } else { 1690 ps.writeString("_Fract") 1691 } 1692} 1693 1694func (ft *FixedType) Traverse(fn func(AST) bool) { 1695 if fn(ft) { 1696 ft.Base.Traverse(fn) 1697 } 1698} 1699 1700func (ft *FixedType) Copy(fn func(AST) AST, skip func(AST) bool) AST { 1701 if skip(ft) { 1702 return nil 1703 } 1704 base := ft.Base.Copy(fn, skip) 1705 if base == nil { 1706 return fn(ft) 1707 } 1708 ft = &FixedType{Base: base, Accum: ft.Accum, Sat: ft.Sat} 1709 if r := fn(ft); r != nil { 1710 return r 1711 } 1712 return ft 1713} 1714 1715func (ft *FixedType) GoString() string { 1716 return ft.goString(0, "") 1717} 1718 1719func (ft *FixedType) goString(indent int, field string) string { 1720 return fmt.Sprintf("%*s%sFixedType: Accum: %t; Sat: %t\n%s", indent, "", field, 1721 ft.Accum, ft.Sat, 1722 ft.Base.goString(indent+2, "Base: ")) 1723} 1724 1725// BinaryFP is a binary floating-point type. 1726type BinaryFP struct { 1727 Bits int 1728} 1729 1730func (bfp *BinaryFP) print(ps *printState) { 1731 fmt.Fprintf(&ps.buf, "_Float%d", bfp.Bits) 1732} 1733 1734func (bfp *BinaryFP) Traverse(fn func(AST) bool) { 1735 fn(bfp) 1736} 1737 1738func (bfp *BinaryFP) Copy(fn func(AST) AST, skip func(AST) bool) AST { 1739 if skip(bfp) { 1740 return nil 1741 } 1742 return fn(bfp) 1743} 1744 1745func (bfp *BinaryFP) GoString() string { 1746 return bfp.goString(0, "") 1747} 1748 1749func (bfp *BinaryFP) goString(indent int, field string) string { 1750 return fmt.Sprintf("%*s%sBinaryFP: %d", indent, "", field, bfp.Bits) 1751} 1752 1753// BitIntType is the C++23 _BitInt(N) type. 1754type BitIntType struct { 1755 Size AST 1756 Signed bool 1757} 1758 1759func (bt *BitIntType) print(ps *printState) { 1760 if !bt.Signed { 1761 ps.writeString("unsigned ") 1762 } 1763 ps.writeString("_BitInt") 1764 ps.startScope('(') 1765 ps.print(bt.Size) 1766 ps.endScope(')') 1767} 1768 1769func (bt *BitIntType) Traverse(fn func(AST) bool) { 1770 if fn(bt) { 1771 bt.Size.Traverse(fn) 1772 } 1773} 1774 1775func (bt *BitIntType) Copy(fn func(AST) AST, skip func(AST) bool) AST { 1776 if skip(bt) { 1777 return nil 1778 } 1779 size := bt.Size.Copy(fn, skip) 1780 if size == nil { 1781 return fn(bt) 1782 } 1783 bt = &BitIntType{Size: size, Signed: bt.Signed} 1784 if r := fn(bt); r != nil { 1785 return r 1786 } 1787 return bt 1788} 1789 1790func (bt *BitIntType) GoString() string { 1791 return bt.goString(0, "") 1792} 1793 1794func (bt *BitIntType) goString(indent int, field string) string { 1795 return fmt.Sprintf("%*s%sBitIntType: Signed: %t\n%s", indent, "", field, 1796 bt.Signed, 1797 bt.Size.goString(indent+2, "Size: ")) 1798} 1799 1800// VectorType is a vector type. 1801type VectorType struct { 1802 Dimension AST 1803 Base AST 1804} 1805 1806func (vt *VectorType) print(ps *printState) { 1807 ps.inner = append(ps.inner, vt) 1808 ps.print(vt.Base) 1809 if len(ps.inner) > 0 { 1810 ps.printOneInner(nil) 1811 } 1812} 1813 1814func (vt *VectorType) printInner(ps *printState) { 1815 end := byte(')') 1816 if ps.llvmStyle { 1817 ps.writeString(" vector[") 1818 end = ']' 1819 } else { 1820 ps.writeString(" __vector(") 1821 } 1822 ps.print(vt.Dimension) 1823 ps.writeByte(end) 1824} 1825 1826func (vt *VectorType) Traverse(fn func(AST) bool) { 1827 if fn(vt) { 1828 vt.Dimension.Traverse(fn) 1829 vt.Base.Traverse(fn) 1830 } 1831} 1832 1833func (vt *VectorType) Copy(fn func(AST) AST, skip func(AST) bool) AST { 1834 if skip(vt) { 1835 return nil 1836 } 1837 dimension := vt.Dimension.Copy(fn, skip) 1838 base := vt.Base.Copy(fn, skip) 1839 if dimension == nil && base == nil { 1840 return fn(vt) 1841 } 1842 if dimension == nil { 1843 dimension = vt.Dimension 1844 } 1845 if base == nil { 1846 base = vt.Base 1847 } 1848 vt = &VectorType{Dimension: dimension, Base: base} 1849 if r := fn(vt); r != nil { 1850 return r 1851 } 1852 return vt 1853} 1854 1855func (vt *VectorType) GoString() string { 1856 return vt.goString(0, "") 1857} 1858 1859func (vt *VectorType) goString(indent int, field string) string { 1860 return fmt.Sprintf("%*s%sVectorType:\n%s\n%s", indent, "", field, 1861 vt.Dimension.goString(indent+2, "Dimension: "), 1862 vt.Base.goString(indent+2, "Base: ")) 1863} 1864 1865// ElaboratedType is an elaborated struct/union/enum type. 1866type ElaboratedType struct { 1867 Kind string 1868 Type AST 1869} 1870 1871func (et *ElaboratedType) print(ps *printState) { 1872 ps.writeString(et.Kind) 1873 ps.writeString(" ") 1874 et.Type.print(ps) 1875} 1876 1877func (et *ElaboratedType) Traverse(fn func(AST) bool) { 1878 if fn(et) { 1879 et.Type.Traverse(fn) 1880 } 1881} 1882 1883func (et *ElaboratedType) Copy(fn func(AST) AST, skip func(AST) bool) AST { 1884 if skip(et) { 1885 return nil 1886 } 1887 typ := et.Type.Copy(fn, skip) 1888 if typ == nil { 1889 return fn(et) 1890 } 1891 et = &ElaboratedType{Kind: et.Kind, Type: typ} 1892 if r := fn(et); r != nil { 1893 return r 1894 } 1895 return et 1896} 1897 1898func (et *ElaboratedType) GoString() string { 1899 return et.goString(0, "") 1900} 1901 1902func (et *ElaboratedType) goString(indent int, field string) string { 1903 return fmt.Sprintf("%*s%sElaboratedtype: Kind: %s\n%s", indent, "", field, 1904 et.Kind, et.Type.goString(indent+2, "Expr: ")) 1905} 1906 1907// Decltype is the decltype operator. 1908type Decltype struct { 1909 Expr AST 1910} 1911 1912func (dt *Decltype) print(ps *printState) { 1913 ps.writeString("decltype") 1914 if !ps.llvmStyle { 1915 ps.writeString(" ") 1916 } 1917 ps.startScope('(') 1918 ps.print(dt.Expr) 1919 ps.endScope(')') 1920} 1921 1922func (dt *Decltype) Traverse(fn func(AST) bool) { 1923 if fn(dt) { 1924 dt.Expr.Traverse(fn) 1925 } 1926} 1927 1928func (dt *Decltype) Copy(fn func(AST) AST, skip func(AST) bool) AST { 1929 if skip(dt) { 1930 return nil 1931 } 1932 expr := dt.Expr.Copy(fn, skip) 1933 if expr == nil { 1934 return fn(dt) 1935 } 1936 dt = &Decltype{Expr: expr} 1937 if r := fn(dt); r != nil { 1938 return r 1939 } 1940 return dt 1941} 1942 1943func (dt *Decltype) GoString() string { 1944 return dt.goString(0, "") 1945} 1946 1947func (dt *Decltype) goString(indent int, field string) string { 1948 return fmt.Sprintf("%*s%sDecltype:\n%s", indent, "", field, 1949 dt.Expr.goString(indent+2, "Expr: ")) 1950} 1951 1952// Operator is an operator. 1953type Operator struct { 1954 Name string 1955 precedence precedence 1956} 1957 1958func (op *Operator) print(ps *printState) { 1959 ps.writeString("operator") 1960 if isLower(op.Name[0]) { 1961 ps.writeByte(' ') 1962 } 1963 n := op.Name 1964 n = strings.TrimSuffix(n, " ") 1965 ps.writeString(n) 1966} 1967 1968func (op *Operator) Traverse(fn func(AST) bool) { 1969 fn(op) 1970} 1971 1972func (op *Operator) Copy(fn func(AST) AST, skip func(AST) bool) AST { 1973 if skip(op) { 1974 return nil 1975 } 1976 return fn(op) 1977} 1978 1979func (op *Operator) GoString() string { 1980 return op.goString(0, "") 1981} 1982 1983func (op *Operator) goString(indent int, field string) string { 1984 return fmt.Sprintf("%*s%sOperator: %s", indent, "", field, op.Name) 1985} 1986 1987func (op *Operator) prec() precedence { 1988 return op.precedence 1989} 1990 1991// Constructor is a constructor. 1992type Constructor struct { 1993 Name AST 1994 Base AST // base class of inheriting constructor 1995} 1996 1997func (c *Constructor) print(ps *printState) { 1998 ps.print(c.Name) 1999 // We don't include the base class in the demangled string. 2000} 2001 2002func (c *Constructor) Traverse(fn func(AST) bool) { 2003 if fn(c) { 2004 c.Name.Traverse(fn) 2005 if c.Base != nil { 2006 c.Base.Traverse(fn) 2007 } 2008 } 2009} 2010 2011func (c *Constructor) Copy(fn func(AST) AST, skip func(AST) bool) AST { 2012 if skip(c) { 2013 return nil 2014 } 2015 name := c.Name.Copy(fn, skip) 2016 var base AST 2017 if c.Base != nil { 2018 base = c.Base.Copy(fn, skip) 2019 } 2020 if name == nil && base == nil { 2021 return fn(c) 2022 } 2023 if name == nil { 2024 name = c.Name 2025 } 2026 if base == nil { 2027 base = c.Base 2028 } 2029 c = &Constructor{Name: name, Base: base} 2030 if r := fn(c); r != nil { 2031 return r 2032 } 2033 return c 2034} 2035 2036func (c *Constructor) GoString() string { 2037 return c.goString(0, "") 2038} 2039 2040func (c *Constructor) goString(indent int, field string) string { 2041 var sb strings.Builder 2042 fmt.Fprintf(&sb, "%*s%sConstructor:\n", indent, "", field) 2043 if c.Base != nil { 2044 fmt.Fprintf(&sb, "%s\n", c.Base.goString(indent+2, "Base: ")) 2045 } 2046 fmt.Fprintf(&sb, "%s", c.Name.goString(indent+2, "Name: ")) 2047 return sb.String() 2048} 2049 2050// Destructor is a destructor. 2051type Destructor struct { 2052 Name AST 2053} 2054 2055func (d *Destructor) print(ps *printState) { 2056 ps.writeByte('~') 2057 ps.print(d.Name) 2058} 2059 2060func (d *Destructor) Traverse(fn func(AST) bool) { 2061 if fn(d) { 2062 d.Name.Traverse(fn) 2063 } 2064} 2065 2066func (d *Destructor) Copy(fn func(AST) AST, skip func(AST) bool) AST { 2067 if skip(d) { 2068 return nil 2069 } 2070 name := d.Name.Copy(fn, skip) 2071 if name == nil { 2072 return fn(d) 2073 } 2074 d = &Destructor{Name: name} 2075 if r := fn(d); r != nil { 2076 return r 2077 } 2078 return d 2079} 2080 2081func (d *Destructor) GoString() string { 2082 return d.goString(0, "") 2083} 2084 2085func (d *Destructor) goString(indent int, field string) string { 2086 return fmt.Sprintf("%*s%sDestructor:\n%s", indent, "", field, d.Name.goString(indent+2, "Name: ")) 2087} 2088 2089// GlobalCDtor is a global constructor or destructor. 2090type GlobalCDtor struct { 2091 Ctor bool 2092 Key AST 2093} 2094 2095func (gcd *GlobalCDtor) print(ps *printState) { 2096 ps.writeString("global ") 2097 if gcd.Ctor { 2098 ps.writeString("constructors") 2099 } else { 2100 ps.writeString("destructors") 2101 } 2102 ps.writeString(" keyed to ") 2103 ps.print(gcd.Key) 2104} 2105 2106func (gcd *GlobalCDtor) Traverse(fn func(AST) bool) { 2107 if fn(gcd) { 2108 gcd.Key.Traverse(fn) 2109 } 2110} 2111 2112func (gcd *GlobalCDtor) Copy(fn func(AST) AST, skip func(AST) bool) AST { 2113 if skip(gcd) { 2114 return nil 2115 } 2116 key := gcd.Key.Copy(fn, skip) 2117 if key == nil { 2118 return fn(gcd) 2119 } 2120 gcd = &GlobalCDtor{Ctor: gcd.Ctor, Key: key} 2121 if r := fn(gcd); r != nil { 2122 return r 2123 } 2124 return gcd 2125} 2126 2127func (gcd *GlobalCDtor) GoString() string { 2128 return gcd.goString(0, "") 2129} 2130 2131func (gcd *GlobalCDtor) goString(indent int, field string) string { 2132 return fmt.Sprintf("%*s%sGlobalCDtor: Ctor: %t\n%s", indent, "", field, 2133 gcd.Ctor, gcd.Key.goString(indent+2, "Key: ")) 2134} 2135 2136// TaggedName is a name with an ABI tag. 2137type TaggedName struct { 2138 Name AST 2139 Tag AST 2140} 2141 2142func (t *TaggedName) print(ps *printState) { 2143 ps.print(t.Name) 2144 ps.writeString("[abi:") 2145 ps.print(t.Tag) 2146 ps.writeByte(']') 2147} 2148 2149func (t *TaggedName) Traverse(fn func(AST) bool) { 2150 if fn(t) { 2151 t.Name.Traverse(fn) 2152 t.Tag.Traverse(fn) 2153 } 2154} 2155 2156func (t *TaggedName) Copy(fn func(AST) AST, skip func(AST) bool) AST { 2157 if skip(t) { 2158 return nil 2159 } 2160 name := t.Name.Copy(fn, skip) 2161 tag := t.Tag.Copy(fn, skip) 2162 if name == nil && tag == nil { 2163 return fn(t) 2164 } 2165 if name == nil { 2166 name = t.Name 2167 } 2168 if tag == nil { 2169 tag = t.Tag 2170 } 2171 t = &TaggedName{Name: name, Tag: tag} 2172 if r := fn(t); r != nil { 2173 return r 2174 } 2175 return t 2176} 2177 2178func (t *TaggedName) GoString() string { 2179 return t.goString(0, "") 2180} 2181 2182func (t *TaggedName) goString(indent int, field string) string { 2183 return fmt.Sprintf("%*s%sTaggedName:\n%s\n%s", indent, "", field, 2184 t.Name.goString(indent+2, "Name: "), 2185 t.Tag.goString(indent+2, "Tag: ")) 2186} 2187 2188// PackExpansion is a pack expansion. The Pack field may be nil. 2189type PackExpansion struct { 2190 Base AST 2191 Pack *ArgumentPack 2192} 2193 2194func (pe *PackExpansion) print(ps *printState) { 2195 // We normally only get here if the simplify function was 2196 // unable to locate and expand the pack. 2197 if pe.Pack == nil { 2198 if ps.llvmStyle { 2199 ps.print(pe.Base) 2200 } else { 2201 parenthesize(ps, pe.Base) 2202 ps.writeString("...") 2203 } 2204 } else { 2205 ps.print(pe.Base) 2206 } 2207} 2208 2209func (pe *PackExpansion) Traverse(fn func(AST) bool) { 2210 if fn(pe) { 2211 pe.Base.Traverse(fn) 2212 // Don't traverse Template--it points elsewhere in the AST. 2213 } 2214} 2215 2216func (pe *PackExpansion) Copy(fn func(AST) AST, skip func(AST) bool) AST { 2217 if skip(pe) { 2218 return nil 2219 } 2220 base := pe.Base.Copy(fn, skip) 2221 if base == nil { 2222 return fn(pe) 2223 } 2224 pe = &PackExpansion{Base: base, Pack: pe.Pack} 2225 if r := fn(pe); r != nil { 2226 return r 2227 } 2228 return pe 2229} 2230 2231func (pe *PackExpansion) GoString() string { 2232 return pe.goString(0, "") 2233} 2234 2235func (pe *PackExpansion) goString(indent int, field string) string { 2236 return fmt.Sprintf("%*s%sPackExpansion: Pack: %p\n%s", indent, "", field, 2237 pe.Pack, pe.Base.goString(indent+2, "Base: ")) 2238} 2239 2240// ArgumentPack is an argument pack. 2241type ArgumentPack struct { 2242 Args []AST 2243} 2244 2245func (ap *ArgumentPack) print(ps *printState) { 2246 for i, a := range ap.Args { 2247 if i > 0 { 2248 ps.writeString(", ") 2249 } 2250 ps.print(a) 2251 } 2252} 2253 2254func (ap *ArgumentPack) Traverse(fn func(AST) bool) { 2255 if fn(ap) { 2256 for _, a := range ap.Args { 2257 a.Traverse(fn) 2258 } 2259 } 2260} 2261 2262func (ap *ArgumentPack) Copy(fn func(AST) AST, skip func(AST) bool) AST { 2263 if skip(ap) { 2264 return nil 2265 } 2266 args := make([]AST, len(ap.Args)) 2267 changed := false 2268 for i, a := range ap.Args { 2269 ac := a.Copy(fn, skip) 2270 if ac == nil { 2271 args[i] = a 2272 } else { 2273 args[i] = ac 2274 changed = true 2275 } 2276 } 2277 if !changed { 2278 return fn(ap) 2279 } 2280 ap = &ArgumentPack{Args: args} 2281 if r := fn(ap); r != nil { 2282 return r 2283 } 2284 return ap 2285} 2286 2287func (ap *ArgumentPack) GoString() string { 2288 return ap.goString(0, "") 2289} 2290 2291func (ap *ArgumentPack) goString(indent int, field string) string { 2292 if len(ap.Args) == 0 { 2293 return fmt.Sprintf("%*s%sArgumentPack: nil", indent, "", field) 2294 } 2295 s := fmt.Sprintf("%*s%sArgumentPack:", indent, "", field) 2296 for i, a := range ap.Args { 2297 s += "\n" 2298 s += a.goString(indent+2, fmt.Sprintf("%d: ", i)) 2299 } 2300 return s 2301} 2302 2303// SizeofPack is the sizeof operator applied to an argument pack. 2304type SizeofPack struct { 2305 Pack *ArgumentPack 2306} 2307 2308func (sp *SizeofPack) print(ps *printState) { 2309 if ps.llvmStyle { 2310 ps.writeString("sizeof...") 2311 ps.startScope('(') 2312 ps.print(sp.Pack) 2313 ps.endScope(')') 2314 } else { 2315 ps.writeString(fmt.Sprintf("%d", len(sp.Pack.Args))) 2316 } 2317} 2318 2319func (sp *SizeofPack) Traverse(fn func(AST) bool) { 2320 fn(sp) 2321 // Don't traverse the pack--it points elsewhere in the AST. 2322} 2323 2324func (sp *SizeofPack) Copy(fn func(AST) AST, skip func(AST) bool) AST { 2325 if skip(sp) { 2326 return nil 2327 } 2328 sp = &SizeofPack{Pack: sp.Pack} 2329 if r := fn(sp); r != nil { 2330 return r 2331 } 2332 return sp 2333} 2334 2335func (sp *SizeofPack) GoString() string { 2336 return sp.goString(0, "") 2337} 2338 2339func (sp *SizeofPack) goString(indent int, field string) string { 2340 return fmt.Sprintf("%*s%sSizeofPack: Pack: %p", indent, "", field, sp.Pack) 2341} 2342 2343// SizeofArgs is the size of a captured template parameter pack from 2344// an alias template. 2345type SizeofArgs struct { 2346 Args []AST 2347} 2348 2349func (sa *SizeofArgs) print(ps *printState) { 2350 c := 0 2351 for _, a := range sa.Args { 2352 if ap, ok := a.(*ArgumentPack); ok { 2353 c += len(ap.Args) 2354 } else if el, ok := a.(*ExprList); ok { 2355 c += len(el.Exprs) 2356 } else { 2357 c++ 2358 } 2359 } 2360 ps.writeString(fmt.Sprintf("%d", c)) 2361} 2362 2363func (sa *SizeofArgs) Traverse(fn func(AST) bool) { 2364 if fn(sa) { 2365 for _, a := range sa.Args { 2366 a.Traverse(fn) 2367 } 2368 } 2369} 2370 2371func (sa *SizeofArgs) Copy(fn func(AST) AST, skip func(AST) bool) AST { 2372 if skip(sa) { 2373 return nil 2374 } 2375 changed := false 2376 args := make([]AST, len(sa.Args)) 2377 for i, a := range sa.Args { 2378 ac := a.Copy(fn, skip) 2379 if ac == nil { 2380 args[i] = a 2381 } else { 2382 args[i] = ac 2383 changed = true 2384 } 2385 } 2386 if !changed { 2387 return fn(sa) 2388 } 2389 sa = &SizeofArgs{Args: args} 2390 if r := fn(sa); r != nil { 2391 return r 2392 } 2393 return sa 2394} 2395 2396func (sa *SizeofArgs) GoString() string { 2397 return sa.goString(0, "") 2398} 2399 2400func (sa *SizeofArgs) goString(indent int, field string) string { 2401 var args string 2402 if len(sa.Args) == 0 { 2403 args = fmt.Sprintf("%*sArgs: nil", indent+2, "") 2404 } else { 2405 args = fmt.Sprintf("%*sArgs:", indent+2, "") 2406 for i, a := range sa.Args { 2407 args += "\n" 2408 args += a.goString(indent+4, fmt.Sprintf("%d: ", i)) 2409 } 2410 } 2411 return fmt.Sprintf("%*s%sSizeofArgs:\n%s", indent, "", field, args) 2412} 2413 2414// TemplateParamName is the name of a template parameter that the 2415// demangler introduced for a lambda that has explicit template 2416// parameters. This is a prefix with an index. 2417type TemplateParamName struct { 2418 Prefix string 2419 Index int 2420} 2421 2422func (tpn *TemplateParamName) print(ps *printState) { 2423 ps.writeString(tpn.Prefix) 2424 if tpn.Index > 0 { 2425 ps.writeString(fmt.Sprintf("%d", tpn.Index-1)) 2426 } 2427} 2428 2429func (tpn *TemplateParamName) Traverse(fn func(AST) bool) { 2430 fn(tpn) 2431} 2432 2433func (tpn *TemplateParamName) Copy(fn func(AST) AST, skip func(AST) bool) AST { 2434 if skip(tpn) { 2435 return nil 2436 } 2437 return fn(tpn) 2438} 2439 2440func (tpn *TemplateParamName) GoString() string { 2441 return tpn.goString(0, "") 2442} 2443 2444func (tpn *TemplateParamName) goString(indent int, field string) string { 2445 name := tpn.Prefix 2446 if tpn.Index > 0 { 2447 name += fmt.Sprintf("%d", tpn.Index-1) 2448 } 2449 return fmt.Sprintf("%*s%sTemplateParamName: %s", indent, "", field, name) 2450} 2451 2452// TypeTemplateParam is a type template parameter that appears in a 2453// lambda with explicit template parameters. 2454type TypeTemplateParam struct { 2455 Name AST 2456} 2457 2458func (ttp *TypeTemplateParam) print(ps *printState) { 2459 ps.writeString("typename ") 2460 ps.printInner(false) 2461 ps.print(ttp.Name) 2462} 2463 2464func (ttp *TypeTemplateParam) Traverse(fn func(AST) bool) { 2465 if fn(ttp) { 2466 ttp.Name.Traverse(fn) 2467 } 2468} 2469 2470func (ttp *TypeTemplateParam) Copy(fn func(AST) AST, skip func(AST) bool) AST { 2471 if skip(ttp) { 2472 return nil 2473 } 2474 name := ttp.Name.Copy(fn, skip) 2475 if name == nil { 2476 return fn(ttp) 2477 } 2478 ttp = &TypeTemplateParam{Name: name} 2479 if r := fn(ttp); r != nil { 2480 return r 2481 } 2482 return ttp 2483} 2484 2485func (ttp *TypeTemplateParam) GoString() string { 2486 return ttp.goString(0, "") 2487} 2488 2489func (ttp *TypeTemplateParam) goString(indent int, field string) string { 2490 return fmt.Sprintf("%*s%sTypeTemplateParam:\n%s", indent, "", field, 2491 ttp.Name.goString(indent+2, "Name")) 2492} 2493 2494// NonTypeTemplateParam is a non-type template parameter that appears 2495// in a lambda with explicit template parameters. 2496type NonTypeTemplateParam struct { 2497 Name AST 2498 Type AST 2499} 2500 2501func (nttp *NonTypeTemplateParam) print(ps *printState) { 2502 ps.inner = append(ps.inner, nttp) 2503 ps.print(nttp.Type) 2504 if len(ps.inner) > 0 { 2505 ps.writeByte(' ') 2506 ps.print(nttp.Name) 2507 ps.inner = ps.inner[:len(ps.inner)-1] 2508 } 2509} 2510 2511func (nttp *NonTypeTemplateParam) printInner(ps *printState) { 2512 ps.print(nttp.Name) 2513} 2514 2515func (nttp *NonTypeTemplateParam) Traverse(fn func(AST) bool) { 2516 if fn(nttp) { 2517 nttp.Name.Traverse(fn) 2518 nttp.Type.Traverse(fn) 2519 } 2520} 2521 2522func (nttp *NonTypeTemplateParam) Copy(fn func(AST) AST, skip func(AST) bool) AST { 2523 if skip(nttp) { 2524 return nil 2525 } 2526 name := nttp.Name.Copy(fn, skip) 2527 typ := nttp.Type.Copy(fn, skip) 2528 if name == nil && typ == nil { 2529 return fn(nttp) 2530 } 2531 if name == nil { 2532 name = nttp.Name 2533 } 2534 if typ == nil { 2535 typ = nttp.Type 2536 } 2537 nttp = &NonTypeTemplateParam{Name: name, Type: typ} 2538 if r := fn(nttp); r != nil { 2539 return r 2540 } 2541 return nttp 2542} 2543 2544func (nttp *NonTypeTemplateParam) GoString() string { 2545 return nttp.goString(0, "") 2546} 2547 2548func (nttp *NonTypeTemplateParam) goString(indent int, field string) string { 2549 return fmt.Sprintf("%*s%sNonTypeTemplateParam:\n%s\n%s", indent, "", field, 2550 nttp.Name.goString(indent+2, "Name: "), 2551 nttp.Type.goString(indent+2, "Type: ")) 2552} 2553 2554// TemplateTemplateParam is a template template parameter that appears 2555// in a lambda with explicit template parameters. 2556type TemplateTemplateParam struct { 2557 Name AST 2558 Params []AST 2559 Constraint AST 2560} 2561 2562func (ttp *TemplateTemplateParam) print(ps *printState) { 2563 scopes := ps.scopes 2564 ps.scopes = 0 2565 2566 ps.writeString("template<") 2567 ps.printList(ttp.Params, nil) 2568 ps.writeString("> typename ") 2569 2570 ps.scopes = scopes 2571 2572 ps.print(ttp.Name) 2573 2574 if ttp.Constraint != nil { 2575 ps.writeString(" requires ") 2576 ps.print(ttp.Constraint) 2577 } 2578} 2579 2580func (ttp *TemplateTemplateParam) Traverse(fn func(AST) bool) { 2581 if fn(ttp) { 2582 ttp.Name.Traverse(fn) 2583 for _, param := range ttp.Params { 2584 param.Traverse(fn) 2585 } 2586 if ttp.Constraint != nil { 2587 ttp.Constraint.Traverse(fn) 2588 } 2589 } 2590} 2591 2592func (ttp *TemplateTemplateParam) Copy(fn func(AST) AST, skip func(AST) bool) AST { 2593 if skip(ttp) { 2594 return nil 2595 } 2596 2597 changed := false 2598 2599 name := ttp.Name.Copy(fn, skip) 2600 if name == nil { 2601 name = ttp.Name 2602 } else { 2603 changed = true 2604 } 2605 2606 params := make([]AST, len(ttp.Params)) 2607 for i, p := range ttp.Params { 2608 pc := p.Copy(fn, skip) 2609 if pc == nil { 2610 params[i] = p 2611 } else { 2612 params[i] = pc 2613 changed = true 2614 } 2615 } 2616 2617 var constraint AST 2618 if ttp.Constraint != nil { 2619 constraint = ttp.Constraint.Copy(fn, skip) 2620 if constraint == nil { 2621 constraint = ttp.Constraint 2622 } else { 2623 changed = true 2624 } 2625 } 2626 2627 if !changed { 2628 return fn(ttp) 2629 } 2630 2631 ttp = &TemplateTemplateParam{ 2632 Name: name, 2633 Params: params, 2634 Constraint: constraint, 2635 } 2636 if r := fn(ttp); r != nil { 2637 return r 2638 } 2639 return ttp 2640} 2641 2642func (ttp *TemplateTemplateParam) GoString() string { 2643 return ttp.goString(0, "") 2644} 2645 2646func (ttp *TemplateTemplateParam) goString(indent int, field string) string { 2647 var params strings.Builder 2648 fmt.Fprintf(¶ms, "%*sParams:", indent+2, "") 2649 for i, p := range ttp.Params { 2650 params.WriteByte('\n') 2651 params.WriteString(p.goString(indent+4, fmt.Sprintf("%d: ", i))) 2652 } 2653 var constraint string 2654 if ttp.Constraint == nil { 2655 constraint = fmt.Sprintf("%*sConstraint: nil", indent+2, "") 2656 } else { 2657 constraint = ttp.Constraint.goString(indent+2, "Constraint: ") 2658 } 2659 return fmt.Sprintf("%*s%sTemplateTemplateParam:\n%s\n%s\n%s", indent, "", field, 2660 ttp.Name.goString(indent+2, "Name: "), 2661 params.String(), 2662 constraint) 2663} 2664 2665// ConstrainedTypeTemplateParam is a constrained template type 2666// parameter declaration. 2667type ConstrainedTypeTemplateParam struct { 2668 Name AST 2669 Constraint AST 2670} 2671 2672func (cttp *ConstrainedTypeTemplateParam) print(ps *printState) { 2673 ps.inner = append(ps.inner, cttp) 2674 ps.print(cttp.Constraint) 2675 if len(ps.inner) > 0 { 2676 ps.writeByte(' ') 2677 ps.print(cttp.Name) 2678 ps.inner = ps.inner[:len(ps.inner)-1] 2679 } 2680} 2681 2682func (cttp *ConstrainedTypeTemplateParam) printInner(ps *printState) { 2683 ps.print(cttp.Name) 2684} 2685 2686func (cttp *ConstrainedTypeTemplateParam) Traverse(fn func(AST) bool) { 2687 if fn(cttp) { 2688 cttp.Name.Traverse(fn) 2689 cttp.Constraint.Traverse(fn) 2690 } 2691} 2692 2693func (cttp *ConstrainedTypeTemplateParam) Copy(fn func(AST) AST, skip func(AST) bool) AST { 2694 if skip(cttp) { 2695 return nil 2696 } 2697 name := cttp.Name.Copy(fn, skip) 2698 constraint := cttp.Constraint.Copy(fn, skip) 2699 if name == nil && constraint == nil { 2700 return fn(cttp) 2701 } 2702 if name == nil { 2703 name = cttp.Name 2704 } 2705 if constraint == nil { 2706 constraint = cttp.Constraint 2707 } 2708 cttp = &ConstrainedTypeTemplateParam{Name: name, Constraint: constraint} 2709 if r := fn(cttp); r != nil { 2710 return r 2711 } 2712 return cttp 2713} 2714 2715func (cttp *ConstrainedTypeTemplateParam) GoString() string { 2716 return cttp.goString(0, "") 2717} 2718 2719func (cttp *ConstrainedTypeTemplateParam) goString(indent int, field string) string { 2720 return fmt.Sprintf("%*s%sConstrainedTypeTemplateParam\n%s\n%s", indent, "", field, 2721 cttp.Name.goString(indent+2, "Name: "), 2722 cttp.Constraint.goString(indent+2, "Constraint: ")) 2723} 2724 2725// TemplateParamPack is a template parameter pack that appears in a 2726// lambda with explicit template parameters. 2727type TemplateParamPack struct { 2728 Param AST 2729} 2730 2731func (tpp *TemplateParamPack) print(ps *printState) { 2732 holdInner := ps.inner 2733 defer func() { ps.inner = holdInner }() 2734 2735 ps.inner = []AST{tpp} 2736 if nttp, ok := tpp.Param.(*NonTypeTemplateParam); ok { 2737 ps.print(nttp.Type) 2738 } else { 2739 ps.print(tpp.Param) 2740 } 2741 if len(ps.inner) > 0 { 2742 ps.writeString("...") 2743 } 2744} 2745 2746func (tpp *TemplateParamPack) printInner(ps *printState) { 2747 ps.writeString("...") 2748 if nttp, ok := tpp.Param.(*NonTypeTemplateParam); ok { 2749 ps.print(nttp.Name) 2750 } 2751} 2752 2753func (tpp *TemplateParamPack) Traverse(fn func(AST) bool) { 2754 if fn(tpp) { 2755 tpp.Param.Traverse(fn) 2756 } 2757} 2758 2759func (tpp *TemplateParamPack) Copy(fn func(AST) AST, skip func(AST) bool) AST { 2760 if skip(tpp) { 2761 return nil 2762 } 2763 param := tpp.Param.Copy(fn, skip) 2764 if param == nil { 2765 return fn(tpp) 2766 } 2767 tpp = &TemplateParamPack{Param: param} 2768 if r := fn(tpp); r != nil { 2769 return r 2770 } 2771 return tpp 2772} 2773 2774func (tpp *TemplateParamPack) GoString() string { 2775 return tpp.goString(0, "") 2776} 2777 2778func (tpp *TemplateParamPack) goString(indent int, field string) string { 2779 return fmt.Sprintf("%*s%sTemplateParamPack:\n%s", indent, "", field, 2780 tpp.Param.goString(indent+2, "Param: ")) 2781} 2782 2783// Cast is a type cast. 2784type Cast struct { 2785 To AST 2786} 2787 2788func (c *Cast) print(ps *printState) { 2789 ps.writeString("operator ") 2790 ps.print(c.To) 2791} 2792 2793func (c *Cast) Traverse(fn func(AST) bool) { 2794 if fn(c) { 2795 c.To.Traverse(fn) 2796 } 2797} 2798 2799func (c *Cast) Copy(fn func(AST) AST, skip func(AST) bool) AST { 2800 if skip(c) { 2801 return nil 2802 } 2803 to := c.To.Copy(fn, skip) 2804 if to == nil { 2805 return fn(c) 2806 } 2807 c = &Cast{To: to} 2808 if r := fn(c); r != nil { 2809 return r 2810 } 2811 return c 2812} 2813 2814func (c *Cast) GoString() string { 2815 return c.goString(0, "") 2816} 2817 2818func (c *Cast) goString(indent int, field string) string { 2819 return fmt.Sprintf("%*s%sCast\n%s", indent, "", field, 2820 c.To.goString(indent+2, "To: ")) 2821} 2822 2823func (c *Cast) prec() precedence { 2824 return precCast 2825} 2826 2827// The parenthesize function prints the string for val, wrapped in 2828// parentheses if necessary. 2829func parenthesize(ps *printState, val AST) { 2830 paren := false 2831 switch v := val.(type) { 2832 case *Name, *InitializerList: 2833 case *FunctionParam: 2834 if ps.llvmStyle { 2835 paren = true 2836 } 2837 case *Qualified: 2838 if v.LocalName { 2839 paren = true 2840 } 2841 default: 2842 paren = true 2843 } 2844 if paren { 2845 ps.startScope('(') 2846 } 2847 ps.print(val) 2848 if paren { 2849 ps.endScope(')') 2850 } 2851} 2852 2853// Nullary is an operator in an expression with no arguments, such as 2854// throw. 2855type Nullary struct { 2856 Op AST 2857} 2858 2859func (n *Nullary) print(ps *printState) { 2860 if op, ok := n.Op.(*Operator); ok { 2861 ps.writeString(op.Name) 2862 } else { 2863 ps.print(n.Op) 2864 } 2865} 2866 2867func (n *Nullary) Traverse(fn func(AST) bool) { 2868 if fn(n) { 2869 n.Op.Traverse(fn) 2870 } 2871} 2872 2873func (n *Nullary) Copy(fn func(AST) AST, skip func(AST) bool) AST { 2874 if skip(n) { 2875 return nil 2876 } 2877 op := n.Op.Copy(fn, skip) 2878 if op == nil { 2879 return fn(n) 2880 } 2881 n = &Nullary{Op: op} 2882 if r := fn(n); r != nil { 2883 return r 2884 } 2885 return n 2886} 2887 2888func (n *Nullary) GoString() string { 2889 return n.goString(0, "") 2890} 2891 2892func (n *Nullary) goString(indent int, field string) string { 2893 return fmt.Sprintf("%*s%sNullary:\n%s", indent, "", field, 2894 n.Op.goString(indent+2, "Op: ")) 2895} 2896 2897// Unary is a unary operation in an expression. 2898type Unary struct { 2899 Op AST 2900 Expr AST 2901 Suffix bool // true for ++ -- when used as postfix 2902 SizeofType bool // true for sizeof (type) 2903} 2904 2905func (u *Unary) print(ps *printState) { 2906 op, _ := u.Op.(*Operator) 2907 expr := u.Expr 2908 2909 // Don't print the argument list when taking the address of a 2910 // function. 2911 if !ps.llvmStyle { 2912 if op != nil && op.Name == "&" { 2913 if t, ok := expr.(*Typed); ok { 2914 if _, ok := t.Type.(*FunctionType); ok { 2915 expr = t.Name 2916 } 2917 } 2918 } 2919 } 2920 2921 if u.Suffix { 2922 if ps.llvmStyle { 2923 wantParens := true 2924 opPrec := precUnary 2925 if op != nil { 2926 opPrec = op.precedence 2927 } 2928 if p, ok := expr.(hasPrec); ok { 2929 if p.prec() < opPrec { 2930 wantParens = false 2931 } 2932 } 2933 if wantParens { 2934 ps.startScope('(') 2935 } 2936 ps.print(expr) 2937 if wantParens { 2938 ps.endScope(')') 2939 } 2940 } else { 2941 parenthesize(ps, expr) 2942 } 2943 } 2944 2945 if op != nil { 2946 ps.writeString(op.Name) 2947 if ps.llvmStyle && op.Name == "noexcept" { 2948 ps.writeByte(' ') 2949 } 2950 } else if c, ok := u.Op.(*Cast); ok { 2951 ps.startScope('(') 2952 ps.print(c.To) 2953 ps.endScope(')') 2954 } else { 2955 ps.print(u.Op) 2956 } 2957 2958 if !u.Suffix { 2959 isDelete := op != nil && (op.Name == "delete " || op.Name == "delete[] ") 2960 if op != nil && op.Name == "::" { 2961 // Don't use parentheses after ::. 2962 ps.print(expr) 2963 } else if u.SizeofType { 2964 // Always use parentheses for sizeof argument. 2965 ps.startScope('(') 2966 ps.print(expr) 2967 ps.endScope(')') 2968 } else if op != nil && op.Name == "__alignof__" { 2969 // Always use parentheses for __alignof__ argument. 2970 ps.startScope('(') 2971 ps.print(expr) 2972 ps.endScope(')') 2973 } else if ps.llvmStyle { 2974 var wantParens bool 2975 switch { 2976 case op == nil: 2977 wantParens = true 2978 case op.Name == `operator"" `: 2979 wantParens = false 2980 case op.Name == "&": 2981 wantParens = false 2982 case isDelete: 2983 wantParens = false 2984 case op.Name == "alignof ": 2985 wantParens = true 2986 case op.Name == "sizeof ": 2987 wantParens = true 2988 case op.Name == "typeid ": 2989 wantParens = true 2990 default: 2991 wantParens = true 2992 if p, ok := expr.(hasPrec); ok { 2993 if p.prec() < op.precedence { 2994 wantParens = false 2995 } 2996 } 2997 } 2998 if wantParens { 2999 ps.startScope('(') 3000 } 3001 ps.print(expr) 3002 if wantParens { 3003 ps.endScope(')') 3004 } 3005 } else { 3006 parenthesize(ps, expr) 3007 } 3008 } 3009} 3010 3011func (u *Unary) Traverse(fn func(AST) bool) { 3012 if fn(u) { 3013 u.Op.Traverse(fn) 3014 u.Expr.Traverse(fn) 3015 } 3016} 3017 3018func (u *Unary) Copy(fn func(AST) AST, skip func(AST) bool) AST { 3019 if skip(u) { 3020 return nil 3021 } 3022 op := u.Op.Copy(fn, skip) 3023 expr := u.Expr.Copy(fn, skip) 3024 if op == nil && expr == nil { 3025 return fn(u) 3026 } 3027 if op == nil { 3028 op = u.Op 3029 } 3030 if expr == nil { 3031 expr = u.Expr 3032 } 3033 u = &Unary{Op: op, Expr: expr, Suffix: u.Suffix, SizeofType: u.SizeofType} 3034 if r := fn(u); r != nil { 3035 return r 3036 } 3037 return u 3038} 3039 3040func (u *Unary) GoString() string { 3041 return u.goString(0, "") 3042} 3043 3044func (u *Unary) goString(indent int, field string) string { 3045 var s string 3046 if u.Suffix { 3047 s = " Suffix: true" 3048 } 3049 if u.SizeofType { 3050 s += " SizeofType: true" 3051 } 3052 return fmt.Sprintf("%*s%sUnary:%s\n%s\n%s", indent, "", field, 3053 s, u.Op.goString(indent+2, "Op: "), 3054 u.Expr.goString(indent+2, "Expr: ")) 3055} 3056 3057func (u *Unary) prec() precedence { 3058 if p, ok := u.Op.(hasPrec); ok { 3059 return p.prec() 3060 } 3061 return precDefault 3062} 3063 3064// isDesignatedInitializer reports whether x is a designated 3065// initializer. 3066func isDesignatedInitializer(x AST) bool { 3067 switch x := x.(type) { 3068 case *Binary: 3069 if op, ok := x.Op.(*Operator); ok { 3070 if op.Name == "]=" { 3071 return true 3072 } 3073 if op.Name != "=" { 3074 return false 3075 } 3076 if _, ok := x.Left.(*Literal); ok { 3077 return false 3078 } 3079 return true 3080 } 3081 case *Trinary: 3082 if op, ok := x.Op.(*Operator); ok { 3083 return op.Name == "[...]=" 3084 } 3085 } 3086 return false 3087} 3088 3089// Binary is a binary operation in an expression. 3090type Binary struct { 3091 Op AST 3092 Left AST 3093 Right AST 3094} 3095 3096func (b *Binary) print(ps *printState) { 3097 op, _ := b.Op.(*Operator) 3098 3099 if op != nil && strings.Contains(op.Name, "cast") { 3100 ps.writeString(op.Name) 3101 3102 scopes := ps.scopes 3103 ps.scopes = 0 3104 3105 ps.writeByte('<') 3106 ps.print(b.Left) 3107 ps.writeString(">") 3108 3109 ps.scopes = scopes 3110 3111 ps.startScope('(') 3112 ps.print(b.Right) 3113 ps.endScope(')') 3114 return 3115 } 3116 3117 if isDesignatedInitializer(b) { 3118 if op.Name == "=" { 3119 ps.writeByte('.') 3120 } else { 3121 ps.writeByte('[') 3122 } 3123 ps.print(b.Left) 3124 if op.Name == "]=" { 3125 ps.writeByte(']') 3126 } 3127 if isDesignatedInitializer(b.Right) { 3128 // Don't add anything between designated 3129 // initializer chains. 3130 ps.print(b.Right) 3131 } else { 3132 if ps.llvmStyle { 3133 ps.writeString(" = ") 3134 ps.print(b.Right) 3135 } else { 3136 ps.writeByte('=') 3137 parenthesize(ps, b.Right) 3138 } 3139 } 3140 return 3141 } 3142 3143 // Use an extra set of parentheses around an expression that 3144 // uses the greater-than operator, so that it does not get 3145 // confused with the '>' that ends template parameters. 3146 needsOuterParen := op != nil && (op.Name == ">" || op.Name == ">>") 3147 if ps.llvmStyle && ps.scopes > 0 { 3148 needsOuterParen = false 3149 } 3150 if needsOuterParen { 3151 ps.startScope('(') 3152 } 3153 3154 left := b.Left 3155 3156 skipParens := false 3157 addSpaces := ps.llvmStyle 3158 if ps.llvmStyle && op != nil { 3159 switch op.Name { 3160 case ".", "->", "->*": 3161 addSpaces = false 3162 } 3163 } 3164 3165 // For a function call in an expression, don't print the types 3166 // of the arguments unless there is a return type. 3167 if op != nil && op.Name == "()" { 3168 if ty, ok := b.Left.(*Typed); ok { 3169 if ft, ok := ty.Type.(*FunctionType); ok { 3170 if ft.Return == nil { 3171 left = ty.Name 3172 } else { 3173 skipParens = true 3174 } 3175 } else { 3176 left = ty.Name 3177 } 3178 } 3179 if ps.llvmStyle { 3180 skipParens = true 3181 } 3182 } 3183 3184 if skipParens { 3185 ps.print(left) 3186 } else if ps.llvmStyle { 3187 prec := precPrimary 3188 if p, ok := left.(hasPrec); ok { 3189 prec = p.prec() 3190 } 3191 needsParen := false 3192 if prec > b.prec() { 3193 needsParen = true 3194 } 3195 if needsParen { 3196 ps.startScope('(') 3197 } 3198 3199 ps.print(left) 3200 3201 if needsParen { 3202 ps.endScope(')') 3203 } 3204 } else { 3205 parenthesize(ps, left) 3206 } 3207 3208 if op != nil && op.Name == "[]" { 3209 ps.writeByte('[') 3210 ps.print(b.Right) 3211 ps.writeByte(']') 3212 return 3213 } 3214 3215 if op != nil { 3216 if op.Name != "()" { 3217 if addSpaces && op.Name != "," { 3218 ps.writeByte(' ') 3219 } 3220 ps.writeString(op.Name) 3221 if addSpaces { 3222 ps.writeByte(' ') 3223 } 3224 } 3225 } else { 3226 ps.print(b.Op) 3227 } 3228 3229 if ps.llvmStyle { 3230 prec := precPrimary 3231 if p, ok := b.Right.(hasPrec); ok { 3232 prec = p.prec() 3233 } 3234 needsParen := false 3235 if prec >= b.prec() { 3236 needsParen = true 3237 } 3238 if needsParen { 3239 ps.startScope('(') 3240 } 3241 3242 ps.print(b.Right) 3243 3244 if needsParen { 3245 ps.endScope(')') 3246 } 3247 } else { 3248 parenthesize(ps, b.Right) 3249 } 3250 3251 if needsOuterParen { 3252 ps.endScope(')') 3253 } 3254} 3255 3256func (b *Binary) Traverse(fn func(AST) bool) { 3257 if fn(b) { 3258 b.Op.Traverse(fn) 3259 b.Left.Traverse(fn) 3260 b.Right.Traverse(fn) 3261 } 3262} 3263 3264func (b *Binary) Copy(fn func(AST) AST, skip func(AST) bool) AST { 3265 if skip(b) { 3266 return nil 3267 } 3268 op := b.Op.Copy(fn, skip) 3269 left := b.Left.Copy(fn, skip) 3270 right := b.Right.Copy(fn, skip) 3271 if op == nil && left == nil && right == nil { 3272 return fn(b) 3273 } 3274 if op == nil { 3275 op = b.Op 3276 } 3277 if left == nil { 3278 left = b.Left 3279 } 3280 if right == nil { 3281 right = b.Right 3282 } 3283 b = &Binary{Op: op, Left: left, Right: right} 3284 if r := fn(b); r != nil { 3285 return r 3286 } 3287 return b 3288} 3289 3290func (b *Binary) GoString() string { 3291 return b.goString(0, "") 3292} 3293 3294func (b *Binary) goString(indent int, field string) string { 3295 return fmt.Sprintf("%*s%sBinary:\n%s\n%s\n%s", indent, "", field, 3296 b.Op.goString(indent+2, "Op: "), 3297 b.Left.goString(indent+2, "Left: "), 3298 b.Right.goString(indent+2, "Right: ")) 3299} 3300 3301func (b *Binary) prec() precedence { 3302 if p, ok := b.Op.(hasPrec); ok { 3303 return p.prec() 3304 } 3305 return precDefault 3306} 3307 3308// Trinary is the ?: trinary operation in an expression. 3309type Trinary struct { 3310 Op AST 3311 First AST 3312 Second AST 3313 Third AST 3314} 3315 3316func (t *Trinary) print(ps *printState) { 3317 if isDesignatedInitializer(t) { 3318 ps.writeByte('[') 3319 ps.print(t.First) 3320 ps.writeString(" ... ") 3321 ps.print(t.Second) 3322 ps.writeByte(']') 3323 if isDesignatedInitializer(t.Third) { 3324 // Don't add anything between designated 3325 // initializer chains. 3326 ps.print(t.Third) 3327 } else { 3328 if ps.llvmStyle { 3329 ps.writeString(" = ") 3330 ps.print(t.Third) 3331 } else { 3332 ps.writeByte('=') 3333 parenthesize(ps, t.Third) 3334 } 3335 } 3336 return 3337 } 3338 3339 if ps.llvmStyle { 3340 wantParens := true 3341 opPrec := precPrimary 3342 if op, ok := t.Op.(*Operator); ok { 3343 opPrec = op.precedence 3344 } 3345 if p, ok := t.First.(hasPrec); ok { 3346 if p.prec() < opPrec { 3347 wantParens = false 3348 } 3349 } 3350 if wantParens { 3351 ps.startScope('(') 3352 } 3353 ps.print(t.First) 3354 if wantParens { 3355 ps.endScope(')') 3356 } 3357 } else { 3358 parenthesize(ps, t.First) 3359 } 3360 3361 if ps.llvmStyle { 3362 ps.writeString(" ? ") 3363 } else { 3364 ps.writeByte('?') 3365 } 3366 3367 if ps.llvmStyle { 3368 wantParens := true 3369 if p, ok := t.Second.(hasPrec); ok { 3370 if p.prec() < precDefault { 3371 wantParens = false 3372 } 3373 } 3374 if wantParens { 3375 ps.startScope('(') 3376 } 3377 ps.print(t.Second) 3378 if wantParens { 3379 ps.endScope(')') 3380 } 3381 } else { 3382 parenthesize(ps, t.Second) 3383 } 3384 3385 ps.writeString(" : ") 3386 3387 if ps.llvmStyle { 3388 wantParens := true 3389 if p, ok := t.Third.(hasPrec); ok { 3390 if p.prec() < precAssign { 3391 wantParens = false 3392 } 3393 } 3394 if wantParens { 3395 ps.startScope('(') 3396 } 3397 ps.print(t.Third) 3398 if wantParens { 3399 ps.endScope(')') 3400 } 3401 } else { 3402 parenthesize(ps, t.Third) 3403 } 3404} 3405 3406func (t *Trinary) Traverse(fn func(AST) bool) { 3407 if fn(t) { 3408 t.Op.Traverse(fn) 3409 t.First.Traverse(fn) 3410 t.Second.Traverse(fn) 3411 t.Third.Traverse(fn) 3412 } 3413} 3414 3415func (t *Trinary) Copy(fn func(AST) AST, skip func(AST) bool) AST { 3416 if skip(t) { 3417 return nil 3418 } 3419 op := t.Op.Copy(fn, skip) 3420 first := t.First.Copy(fn, skip) 3421 second := t.Second.Copy(fn, skip) 3422 third := t.Third.Copy(fn, skip) 3423 if op == nil && first == nil && second == nil && third == nil { 3424 return fn(t) 3425 } 3426 if op == nil { 3427 op = t.Op 3428 } 3429 if first == nil { 3430 first = t.First 3431 } 3432 if second == nil { 3433 second = t.Second 3434 } 3435 if third == nil { 3436 third = t.Third 3437 } 3438 t = &Trinary{Op: op, First: first, Second: second, Third: third} 3439 if r := fn(t); r != nil { 3440 return r 3441 } 3442 return t 3443} 3444 3445func (t *Trinary) GoString() string { 3446 return t.goString(0, "") 3447} 3448 3449func (t *Trinary) goString(indent int, field string) string { 3450 return fmt.Sprintf("%*s%sTrinary:\n%s\n%s\n%s\n%s", indent, "", field, 3451 t.Op.goString(indent+2, "Op: "), 3452 t.First.goString(indent+2, "First: "), 3453 t.Second.goString(indent+2, "Second: "), 3454 t.Third.goString(indent+2, "Third: ")) 3455} 3456 3457// Fold is a C++17 fold-expression. Arg2 is nil for a unary operator. 3458type Fold struct { 3459 Left bool 3460 Op AST 3461 Arg1 AST 3462 Arg2 AST 3463} 3464 3465func (f *Fold) print(ps *printState) { 3466 op, _ := f.Op.(*Operator) 3467 printOp := func() { 3468 if op != nil { 3469 if ps.llvmStyle { 3470 ps.writeByte(' ') 3471 } 3472 ps.writeString(op.Name) 3473 if ps.llvmStyle { 3474 ps.writeByte(' ') 3475 } 3476 } else { 3477 ps.print(f.Op) 3478 } 3479 } 3480 foldParenthesize := func(a AST) { 3481 if ps.llvmStyle { 3482 prec := precDefault 3483 if p, ok := a.(hasPrec); ok { 3484 prec = p.prec() 3485 } 3486 needsParen := false 3487 if prec > precCast { 3488 needsParen = true 3489 } 3490 if needsParen { 3491 ps.startScope('(') 3492 } 3493 ps.print(a) 3494 if needsParen { 3495 ps.endScope(')') 3496 } 3497 } else { 3498 parenthesize(ps, a) 3499 } 3500 } 3501 3502 if f.Arg2 == nil { 3503 if f.Left { 3504 ps.startScope('(') 3505 ps.writeString("...") 3506 printOp() 3507 foldParenthesize(f.Arg1) 3508 ps.endScope(')') 3509 } else { 3510 ps.startScope('(') 3511 foldParenthesize(f.Arg1) 3512 printOp() 3513 ps.writeString("...") 3514 ps.endScope(')') 3515 } 3516 } else { 3517 ps.startScope('(') 3518 foldParenthesize(f.Arg1) 3519 printOp() 3520 ps.writeString("...") 3521 printOp() 3522 foldParenthesize(f.Arg2) 3523 ps.endScope(')') 3524 } 3525} 3526 3527func (f *Fold) Traverse(fn func(AST) bool) { 3528 if fn(f) { 3529 f.Op.Traverse(fn) 3530 f.Arg1.Traverse(fn) 3531 if f.Arg2 != nil { 3532 f.Arg2.Traverse(fn) 3533 } 3534 } 3535} 3536 3537func (f *Fold) Copy(fn func(AST) AST, skip func(AST) bool) AST { 3538 if skip(f) { 3539 return nil 3540 } 3541 op := f.Op.Copy(fn, skip) 3542 arg1 := f.Arg1.Copy(fn, skip) 3543 var arg2 AST 3544 if f.Arg2 != nil { 3545 arg2 = f.Arg2.Copy(fn, skip) 3546 } 3547 if op == nil && arg1 == nil && arg2 == nil { 3548 return fn(f) 3549 } 3550 if op == nil { 3551 op = f.Op 3552 } 3553 if arg1 == nil { 3554 arg1 = f.Arg1 3555 } 3556 if arg2 == nil { 3557 arg2 = f.Arg2 3558 } 3559 f = &Fold{Left: f.Left, Op: op, Arg1: arg1, Arg2: arg2} 3560 if r := fn(f); r != nil { 3561 return r 3562 } 3563 return f 3564} 3565 3566func (f *Fold) GoString() string { 3567 return f.goString(0, "") 3568} 3569 3570func (f *Fold) goString(indent int, field string) string { 3571 if f.Arg2 == nil { 3572 return fmt.Sprintf("%*s%sFold: Left: %t\n%s\n%s", indent, "", field, 3573 f.Left, f.Op.goString(indent+2, "Op: "), 3574 f.Arg1.goString(indent+2, "Arg1: ")) 3575 } else { 3576 return fmt.Sprintf("%*s%sFold: Left: %t\n%s\n%s\n%s", indent, "", field, 3577 f.Left, f.Op.goString(indent+2, "Op: "), 3578 f.Arg1.goString(indent+2, "Arg1: "), 3579 f.Arg2.goString(indent+2, "Arg2: ")) 3580 } 3581} 3582 3583// Subobject is a a reference to an offset in an expression. This is 3584// used for C++20 manglings of class types used as the type of 3585// non-type template arguments. 3586// 3587// See https://github.com/itanium-cxx-abi/cxx-abi/issues/47. 3588type Subobject struct { 3589 Type AST 3590 SubExpr AST 3591 Offset int 3592 Selectors []int 3593 PastEnd bool 3594} 3595 3596func (so *Subobject) print(ps *printState) { 3597 ps.print(so.SubExpr) 3598 ps.writeString(".<") 3599 ps.print(so.Type) 3600 ps.writeString(fmt.Sprintf(" at offset %d>", so.Offset)) 3601} 3602 3603func (so *Subobject) Traverse(fn func(AST) bool) { 3604 if fn(so) { 3605 so.Type.Traverse(fn) 3606 so.SubExpr.Traverse(fn) 3607 } 3608} 3609 3610func (so *Subobject) Copy(fn func(AST) AST, skip func(AST) bool) AST { 3611 if skip(so) { 3612 return nil 3613 } 3614 typ := so.Type.Copy(fn, skip) 3615 subExpr := so.SubExpr.Copy(fn, skip) 3616 if typ == nil && subExpr == nil { 3617 return nil 3618 } 3619 if typ == nil { 3620 typ = so.Type 3621 } 3622 if subExpr == nil { 3623 subExpr = so.SubExpr 3624 } 3625 so = &Subobject{ 3626 Type: typ, 3627 SubExpr: subExpr, 3628 Offset: so.Offset, 3629 Selectors: so.Selectors, 3630 PastEnd: so.PastEnd, 3631 } 3632 if r := fn(so); r != nil { 3633 return r 3634 } 3635 return so 3636} 3637 3638func (so *Subobject) GoString() string { 3639 return so.goString(0, "") 3640} 3641 3642func (so *Subobject) goString(indent int, field string) string { 3643 var selectors string 3644 for _, s := range so.Selectors { 3645 selectors += fmt.Sprintf(" %d", s) 3646 } 3647 return fmt.Sprintf("%*s%sSubobject:\n%s\n%s\n%*sOffset: %d\n%*sSelectors:%s\n%*sPastEnd: %t", 3648 indent, "", field, 3649 so.Type.goString(indent+2, "Type: "), 3650 so.SubExpr.goString(indent+2, "SubExpr: "), 3651 indent+2, "", so.Offset, 3652 indent+2, "", selectors, 3653 indent+2, "", so.PastEnd) 3654} 3655 3656// PtrMemCast is a conversion of an expression to a pointer-to-member 3657// type. This is used for C++20 manglings of class types used as the 3658// type of non-type template arguments. 3659// 3660// See https://github.com/itanium-cxx-abi/cxx-abi/issues/47. 3661type PtrMemCast struct { 3662 Type AST 3663 Expr AST 3664 Offset int 3665} 3666 3667func (pmc *PtrMemCast) print(ps *printState) { 3668 ps.startScope('(') 3669 ps.print(pmc.Type) 3670 ps.writeString(")(") 3671 ps.print(pmc.Expr) 3672 ps.endScope(')') 3673} 3674 3675func (pmc *PtrMemCast) Traverse(fn func(AST) bool) { 3676 if fn(pmc) { 3677 pmc.Type.Traverse(fn) 3678 pmc.Expr.Traverse(fn) 3679 } 3680} 3681 3682func (pmc *PtrMemCast) Copy(fn func(AST) AST, skip func(AST) bool) AST { 3683 if skip(pmc) { 3684 return nil 3685 } 3686 typ := pmc.Type.Copy(fn, skip) 3687 expr := pmc.Expr.Copy(fn, skip) 3688 if typ == nil && expr == nil { 3689 return nil 3690 } 3691 if typ == nil { 3692 typ = pmc.Type 3693 } 3694 if expr == nil { 3695 expr = pmc.Expr 3696 } 3697 pmc = &PtrMemCast{ 3698 Type: typ, 3699 Expr: expr, 3700 Offset: pmc.Offset, 3701 } 3702 if r := fn(pmc); r != nil { 3703 return r 3704 } 3705 return pmc 3706} 3707 3708func (pmc *PtrMemCast) GoString() string { 3709 return pmc.goString(0, "") 3710} 3711 3712func (pmc *PtrMemCast) goString(indent int, field string) string { 3713 return fmt.Sprintf("%*s%sPtrMemCast:\n%s\n%s\n%*sOffset: %d", 3714 indent, "", field, 3715 pmc.Type.goString(indent+2, "Type: "), 3716 pmc.Expr.goString(indent+2, "Expr: "), 3717 indent+2, "", pmc.Offset) 3718} 3719 3720// New is a use of operator new in an expression. 3721type New struct { 3722 Op AST 3723 Place AST 3724 Type AST 3725 Init AST 3726} 3727 3728func (n *New) print(ps *printState) { 3729 if !ps.llvmStyle { 3730 // Op doesn't really matter for printing--we always print "new". 3731 ps.writeString("new ") 3732 } else { 3733 op, _ := n.Op.(*Operator) 3734 if op != nil { 3735 ps.writeString(op.Name) 3736 if n.Place == nil { 3737 ps.writeByte(' ') 3738 } 3739 } else { 3740 ps.print(n.Op) 3741 } 3742 } 3743 if n.Place != nil { 3744 parenthesize(ps, n.Place) 3745 ps.writeByte(' ') 3746 } 3747 ps.print(n.Type) 3748 if n.Init != nil { 3749 parenthesize(ps, n.Init) 3750 } 3751} 3752 3753func (n *New) Traverse(fn func(AST) bool) { 3754 if fn(n) { 3755 n.Op.Traverse(fn) 3756 if n.Place != nil { 3757 n.Place.Traverse(fn) 3758 } 3759 n.Type.Traverse(fn) 3760 if n.Init != nil { 3761 n.Init.Traverse(fn) 3762 } 3763 } 3764} 3765 3766func (n *New) Copy(fn func(AST) AST, skip func(AST) bool) AST { 3767 if skip(n) { 3768 return nil 3769 } 3770 op := n.Op.Copy(fn, skip) 3771 var place AST 3772 if n.Place != nil { 3773 place = n.Place.Copy(fn, skip) 3774 } 3775 typ := n.Type.Copy(fn, skip) 3776 var ini AST 3777 if n.Init != nil { 3778 ini = n.Init.Copy(fn, skip) 3779 } 3780 if op == nil && place == nil && typ == nil && ini == nil { 3781 return fn(n) 3782 } 3783 if op == nil { 3784 op = n.Op 3785 } 3786 if place == nil { 3787 place = n.Place 3788 } 3789 if typ == nil { 3790 typ = n.Type 3791 } 3792 if ini == nil { 3793 ini = n.Init 3794 } 3795 n = &New{Op: op, Place: place, Type: typ, Init: ini} 3796 if r := fn(n); r != nil { 3797 return r 3798 } 3799 return n 3800} 3801 3802func (n *New) GoString() string { 3803 return n.goString(0, "") 3804} 3805 3806func (n *New) goString(indent int, field string) string { 3807 var place string 3808 if n.Place == nil { 3809 place = fmt.Sprintf("%*sPlace: nil", indent, "") 3810 } else { 3811 place = n.Place.goString(indent+2, "Place: ") 3812 } 3813 var ini string 3814 if n.Init == nil { 3815 ini = fmt.Sprintf("%*sInit: nil", indent, "") 3816 } else { 3817 ini = n.Init.goString(indent+2, "Init: ") 3818 } 3819 return fmt.Sprintf("%*s%sNew:\n%s\n%s\n%s\n%s", indent, "", field, 3820 n.Op.goString(indent+2, "Op: "), place, 3821 n.Type.goString(indent+2, "Type: "), ini) 3822} 3823 3824// Literal is a literal in an expression. 3825type Literal struct { 3826 Type AST 3827 Val string 3828 Neg bool 3829} 3830 3831// Suffixes to use for constants of the given integer type. 3832var builtinTypeSuffix = map[string]string{ 3833 "int": "", 3834 "unsigned int": "u", 3835 "long": "l", 3836 "unsigned long": "ul", 3837 "long long": "ll", 3838 "unsigned long long": "ull", 3839} 3840 3841// Builtin float types. 3842var builtinTypeFloat = map[string]bool{ 3843 "double": true, 3844 "long double": true, 3845 "float": true, 3846 "__float128": true, 3847 "half": true, 3848} 3849 3850func (l *Literal) print(ps *printState) { 3851 isFloat := false 3852 if b, ok := l.Type.(*BuiltinType); ok { 3853 if suffix, ok := builtinTypeSuffix[b.Name]; ok { 3854 if l.Neg { 3855 ps.writeByte('-') 3856 } 3857 ps.writeString(l.Val) 3858 ps.writeString(suffix) 3859 return 3860 } else if b.Name == "bool" && !l.Neg { 3861 switch l.Val { 3862 case "0": 3863 ps.writeString("false") 3864 return 3865 case "1": 3866 ps.writeString("true") 3867 return 3868 } 3869 } else if b.Name == "decltype(nullptr)" && (l.Val == "" || l.Val == "0") { 3870 if ps.llvmStyle { 3871 ps.writeString("nullptr") 3872 } else { 3873 ps.print(l.Type) 3874 } 3875 return 3876 } else { 3877 isFloat = builtinTypeFloat[b.Name] 3878 } 3879 } 3880 3881 ps.startScope('(') 3882 ps.print(l.Type) 3883 ps.endScope(')') 3884 3885 if isFloat { 3886 ps.writeByte('[') 3887 } 3888 if l.Neg { 3889 ps.writeByte('-') 3890 } 3891 ps.writeString(l.Val) 3892 if isFloat { 3893 ps.writeByte(']') 3894 } 3895} 3896 3897func (l *Literal) Traverse(fn func(AST) bool) { 3898 if fn(l) { 3899 l.Type.Traverse(fn) 3900 } 3901} 3902 3903func (l *Literal) Copy(fn func(AST) AST, skip func(AST) bool) AST { 3904 if skip(l) { 3905 return nil 3906 } 3907 typ := l.Type.Copy(fn, skip) 3908 if typ == nil { 3909 return fn(l) 3910 } 3911 l = &Literal{Type: typ, Val: l.Val, Neg: l.Neg} 3912 if r := fn(l); r != nil { 3913 return r 3914 } 3915 return l 3916} 3917 3918func (l *Literal) GoString() string { 3919 return l.goString(0, "") 3920} 3921 3922func (l *Literal) goString(indent int, field string) string { 3923 var neg string 3924 if l.Neg { 3925 neg = " Neg: true" 3926 } 3927 return fmt.Sprintf("%*s%sLiteral:%s\n%s\n%*sVal: %s", indent, "", field, 3928 neg, l.Type.goString(indent+2, "Type: "), 3929 indent+2, "", l.Val) 3930} 3931 3932func (l *Literal) prec() precedence { 3933 return precPrimary 3934} 3935 3936// StringLiteral is a string literal. 3937type StringLiteral struct { 3938 Type AST 3939} 3940 3941func (sl *StringLiteral) print(ps *printState) { 3942 ps.writeString(`"<`) 3943 sl.Type.print(ps) 3944 ps.writeString(`>"`) 3945} 3946 3947func (sl *StringLiteral) Traverse(fn func(AST) bool) { 3948 if fn(sl) { 3949 sl.Type.Traverse(fn) 3950 } 3951} 3952 3953func (sl *StringLiteral) Copy(fn func(AST) AST, skip func(AST) bool) AST { 3954 if skip(sl) { 3955 return nil 3956 } 3957 typ := sl.Type.Copy(fn, skip) 3958 if typ == nil { 3959 return fn(sl) 3960 } 3961 sl = &StringLiteral{Type: typ} 3962 if r := fn(sl); r != nil { 3963 return r 3964 } 3965 return sl 3966} 3967 3968func (sl *StringLiteral) GoString() string { 3969 return sl.goString(0, "") 3970} 3971 3972func (sl *StringLiteral) goString(indent int, field string) string { 3973 return fmt.Sprintf("%*s%sStringLiteral:\n%s", indent, "", field, 3974 sl.Type.goString(indent+2, "")) 3975} 3976 3977// LambdaExpr is a literal that is a lambda expression. 3978type LambdaExpr struct { 3979 Type AST 3980} 3981 3982func (le *LambdaExpr) print(ps *printState) { 3983 ps.writeString("[]") 3984 if cl, ok := le.Type.(*Closure); ok { 3985 cl.printTypes(ps) 3986 } 3987 ps.writeString("{...}") 3988} 3989 3990func (le *LambdaExpr) Traverse(fn func(AST) bool) { 3991 if fn(le) { 3992 le.Type.Traverse(fn) 3993 } 3994} 3995 3996func (le *LambdaExpr) Copy(fn func(AST) AST, skip func(AST) bool) AST { 3997 if skip(le) { 3998 return nil 3999 } 4000 typ := le.Type.Copy(fn, skip) 4001 if typ == nil { 4002 return fn(le) 4003 } 4004 le = &LambdaExpr{Type: typ} 4005 if r := fn(le); r != nil { 4006 return r 4007 } 4008 return le 4009} 4010 4011func (le *LambdaExpr) GoString() string { 4012 return le.goString(0, "") 4013} 4014 4015func (le *LambdaExpr) goString(indent int, field string) string { 4016 return fmt.Sprintf("%*s%sLambdaExpr:\n%s", indent, "", field, 4017 le.Type.goString(indent+2, "")) 4018} 4019 4020// ExprList is a list of expressions, typically arguments to a 4021// function call in an expression. 4022type ExprList struct { 4023 Exprs []AST 4024} 4025 4026func (el *ExprList) print(ps *printState) { 4027 ps.printList(el.Exprs, nil) 4028} 4029 4030func (el *ExprList) Traverse(fn func(AST) bool) { 4031 if fn(el) { 4032 for _, e := range el.Exprs { 4033 e.Traverse(fn) 4034 } 4035 } 4036} 4037 4038func (el *ExprList) Copy(fn func(AST) AST, skip func(AST) bool) AST { 4039 if skip(el) { 4040 return nil 4041 } 4042 exprs := make([]AST, len(el.Exprs)) 4043 changed := false 4044 for i, e := range el.Exprs { 4045 ec := e.Copy(fn, skip) 4046 if ec == nil { 4047 exprs[i] = e 4048 } else { 4049 exprs[i] = ec 4050 changed = true 4051 } 4052 } 4053 if !changed { 4054 return fn(el) 4055 } 4056 el = &ExprList{Exprs: exprs} 4057 if r := fn(el); r != nil { 4058 return r 4059 } 4060 return el 4061} 4062 4063func (el *ExprList) GoString() string { 4064 return el.goString(0, "") 4065} 4066 4067func (el *ExprList) goString(indent int, field string) string { 4068 if len(el.Exprs) == 0 { 4069 return fmt.Sprintf("%*s%sExprList: nil", indent, "", field) 4070 } 4071 s := fmt.Sprintf("%*s%sExprList:", indent, "", field) 4072 for i, e := range el.Exprs { 4073 s += "\n" 4074 s += e.goString(indent+2, fmt.Sprintf("%d: ", i)) 4075 } 4076 return s 4077} 4078 4079func (el *ExprList) prec() precedence { 4080 return precComma 4081} 4082 4083// InitializerList is an initializer list: an optional type with a 4084// list of expressions. 4085type InitializerList struct { 4086 Type AST 4087 Exprs AST 4088} 4089 4090func (il *InitializerList) print(ps *printState) { 4091 if il.Type != nil { 4092 ps.print(il.Type) 4093 } 4094 ps.writeByte('{') 4095 ps.print(il.Exprs) 4096 ps.writeByte('}') 4097} 4098 4099func (il *InitializerList) Traverse(fn func(AST) bool) { 4100 if fn(il) { 4101 if il.Type != nil { 4102 il.Type.Traverse(fn) 4103 } 4104 il.Exprs.Traverse(fn) 4105 } 4106} 4107 4108func (il *InitializerList) Copy(fn func(AST) AST, skip func(AST) bool) AST { 4109 if skip(il) { 4110 return nil 4111 } 4112 var typ AST 4113 if il.Type != nil { 4114 typ = il.Type.Copy(fn, skip) 4115 } 4116 exprs := il.Exprs.Copy(fn, skip) 4117 if typ == nil && exprs == nil { 4118 return fn(il) 4119 } 4120 if typ == nil { 4121 typ = il.Type 4122 } 4123 if exprs == nil { 4124 exprs = il.Exprs 4125 } 4126 il = &InitializerList{Type: typ, Exprs: exprs} 4127 if r := fn(il); r != nil { 4128 return r 4129 } 4130 return il 4131} 4132 4133func (il *InitializerList) GoString() string { 4134 return il.goString(0, "") 4135} 4136 4137func (il *InitializerList) goString(indent int, field string) string { 4138 var t string 4139 if il.Type == nil { 4140 t = fmt.Sprintf("%*sType: nil", indent+2, "") 4141 } else { 4142 t = il.Type.goString(indent+2, "Type: ") 4143 } 4144 return fmt.Sprintf("%*s%sInitializerList:\n%s\n%s", indent, "", field, 4145 t, il.Exprs.goString(indent+2, "Exprs: ")) 4146} 4147 4148// DefaultArg holds a default argument for a local name. 4149type DefaultArg struct { 4150 Num int 4151 Arg AST 4152} 4153 4154func (da *DefaultArg) print(ps *printState) { 4155 if !ps.llvmStyle { 4156 fmt.Fprintf(&ps.buf, "{default arg#%d}::", da.Num+1) 4157 } 4158 ps.print(da.Arg) 4159} 4160 4161func (da *DefaultArg) Traverse(fn func(AST) bool) { 4162 if fn(da) { 4163 da.Arg.Traverse(fn) 4164 } 4165} 4166 4167func (da *DefaultArg) Copy(fn func(AST) AST, skip func(AST) bool) AST { 4168 if skip(da) { 4169 return nil 4170 } 4171 arg := da.Arg.Copy(fn, skip) 4172 if arg == nil { 4173 return fn(da) 4174 } 4175 da = &DefaultArg{Num: da.Num, Arg: arg} 4176 if r := fn(da); r != nil { 4177 return r 4178 } 4179 return da 4180} 4181 4182func (da *DefaultArg) GoString() string { 4183 return da.goString(0, "") 4184} 4185 4186func (da *DefaultArg) goString(indent int, field string) string { 4187 return fmt.Sprintf("%*s%sDefaultArg: Num: %d\n%s", indent, "", field, da.Num, 4188 da.Arg.goString(indent+2, "Arg: ")) 4189} 4190 4191// Closure is a closure, or lambda expression. 4192type Closure struct { 4193 TemplateArgs []AST 4194 TemplateArgsConstraint AST 4195 Types []AST 4196 Num int 4197 CallConstraint AST 4198} 4199 4200func (cl *Closure) print(ps *printState) { 4201 if ps.llvmStyle { 4202 if cl.Num == 0 { 4203 ps.writeString("'lambda'") 4204 } else { 4205 ps.writeString(fmt.Sprintf("'lambda%d'", cl.Num-1)) 4206 } 4207 } else { 4208 ps.writeString("{lambda") 4209 } 4210 cl.printTypes(ps) 4211 if !ps.llvmStyle { 4212 ps.writeString(fmt.Sprintf("#%d}", cl.Num+1)) 4213 } 4214} 4215 4216func (cl *Closure) printTypes(ps *printState) { 4217 if len(cl.TemplateArgs) > 0 { 4218 scopes := ps.scopes 4219 ps.scopes = 0 4220 4221 ps.writeString("<") 4222 ps.printList(cl.TemplateArgs, nil) 4223 ps.writeString(">") 4224 4225 ps.scopes = scopes 4226 } 4227 4228 if cl.TemplateArgsConstraint != nil { 4229 ps.writeString(" requires ") 4230 ps.print(cl.TemplateArgsConstraint) 4231 ps.writeByte(' ') 4232 } 4233 4234 ps.startScope('(') 4235 ps.printList(cl.Types, nil) 4236 ps.endScope(')') 4237 4238 if cl.CallConstraint != nil { 4239 ps.writeString(" requires ") 4240 ps.print(cl.CallConstraint) 4241 } 4242} 4243 4244func (cl *Closure) Traverse(fn func(AST) bool) { 4245 if fn(cl) { 4246 for _, a := range cl.TemplateArgs { 4247 a.Traverse(fn) 4248 } 4249 if cl.TemplateArgsConstraint != nil { 4250 cl.TemplateArgsConstraint.Traverse(fn) 4251 } 4252 for _, t := range cl.Types { 4253 t.Traverse(fn) 4254 } 4255 if cl.CallConstraint != nil { 4256 cl.CallConstraint.Traverse(fn) 4257 } 4258 } 4259} 4260 4261func (cl *Closure) Copy(fn func(AST) AST, skip func(AST) bool) AST { 4262 if skip(cl) { 4263 return nil 4264 } 4265 changed := false 4266 4267 args := make([]AST, len(cl.TemplateArgs)) 4268 for i, a := range cl.TemplateArgs { 4269 ac := a.Copy(fn, skip) 4270 if ac == nil { 4271 args[i] = a 4272 } else { 4273 args[i] = ac 4274 changed = true 4275 } 4276 } 4277 4278 var templateArgsConstraint AST 4279 if cl.TemplateArgsConstraint != nil { 4280 templateArgsConstraint = cl.TemplateArgsConstraint.Copy(fn, skip) 4281 if templateArgsConstraint == nil { 4282 templateArgsConstraint = cl.TemplateArgsConstraint 4283 } else { 4284 changed = true 4285 } 4286 } 4287 4288 types := make([]AST, len(cl.Types)) 4289 for i, t := range cl.Types { 4290 tc := t.Copy(fn, skip) 4291 if tc == nil { 4292 types[i] = t 4293 } else { 4294 types[i] = tc 4295 changed = true 4296 } 4297 } 4298 4299 var callConstraint AST 4300 if cl.CallConstraint != nil { 4301 callConstraint = cl.CallConstraint.Copy(fn, skip) 4302 if callConstraint == nil { 4303 callConstraint = cl.CallConstraint 4304 } else { 4305 changed = true 4306 } 4307 } 4308 4309 if !changed { 4310 return fn(cl) 4311 } 4312 cl = &Closure{ 4313 TemplateArgs: args, 4314 TemplateArgsConstraint: templateArgsConstraint, 4315 Types: types, 4316 Num: cl.Num, 4317 CallConstraint: callConstraint, 4318 } 4319 if r := fn(cl); r != nil { 4320 return r 4321 } 4322 return cl 4323} 4324 4325func (cl *Closure) GoString() string { 4326 return cl.goString(0, "") 4327} 4328 4329func (cl *Closure) goString(indent int, field string) string { 4330 var args strings.Builder 4331 if len(cl.TemplateArgs) == 0 { 4332 fmt.Fprintf(&args, "%*sTemplateArgs: nil", indent+2, "") 4333 } else { 4334 fmt.Fprintf(&args, "%*sTemplateArgs:", indent+2, "") 4335 for i, a := range cl.TemplateArgs { 4336 args.WriteByte('\n') 4337 args.WriteString(a.goString(indent+4, fmt.Sprintf("%d: ", i))) 4338 } 4339 } 4340 4341 var templateArgsConstraint string 4342 if cl.TemplateArgsConstraint != nil { 4343 templateArgsConstraint = "\n" + cl.TemplateArgsConstraint.goString(indent+2, "TemplateArgsConstraint: ") 4344 } 4345 4346 var types strings.Builder 4347 if len(cl.Types) == 0 { 4348 fmt.Fprintf(&types, "%*sTypes: nil", indent+2, "") 4349 } else { 4350 fmt.Fprintf(&types, "%*sTypes:", indent+2, "") 4351 for i, t := range cl.Types { 4352 types.WriteByte('\n') 4353 types.WriteString(t.goString(indent+4, fmt.Sprintf("%d: ", i))) 4354 } 4355 } 4356 4357 var callConstraint string 4358 if cl.CallConstraint != nil { 4359 callConstraint = "\n" + cl.CallConstraint.goString(indent+2, "CallConstraint: ") 4360 } 4361 4362 return fmt.Sprintf("%*s%sClosure: Num: %d\n%s\n%s%s%s", indent, "", field, 4363 cl.Num, args.String(), templateArgsConstraint, types.String(), 4364 callConstraint) 4365} 4366 4367// StructuredBindings is a structured binding declaration. 4368type StructuredBindings struct { 4369 Bindings []AST 4370} 4371 4372func (sb *StructuredBindings) print(ps *printState) { 4373 ps.writeString("[") 4374 ps.printList(sb.Bindings, nil) 4375 ps.writeString("]") 4376} 4377 4378func (sb *StructuredBindings) Traverse(fn func(AST) bool) { 4379 if fn(sb) { 4380 for _, b := range sb.Bindings { 4381 b.Traverse(fn) 4382 } 4383 } 4384} 4385 4386func (sb *StructuredBindings) Copy(fn func(AST) AST, skip func(AST) bool) AST { 4387 if skip(sb) { 4388 return nil 4389 } 4390 changed := false 4391 bindings := make([]AST, len(sb.Bindings)) 4392 for i, b := range sb.Bindings { 4393 bc := b.Copy(fn, skip) 4394 if bc == nil { 4395 bindings[i] = b 4396 } else { 4397 bindings[i] = bc 4398 changed = true 4399 } 4400 } 4401 if !changed { 4402 return fn(sb) 4403 } 4404 sb = &StructuredBindings{Bindings: bindings} 4405 if r := fn(sb); r != nil { 4406 return r 4407 } 4408 return sb 4409} 4410 4411func (sb *StructuredBindings) GoString() string { 4412 return sb.goString(0, "") 4413} 4414 4415func (sb *StructuredBindings) goString(indent int, field string) string { 4416 var strb strings.Builder 4417 fmt.Fprintf(&strb, "%*s%sStructuredBinding:", indent, "", field) 4418 for _, b := range sb.Bindings { 4419 strb.WriteByte('\n') 4420 strb.WriteString(b.goString(indent+2, "")) 4421 } 4422 return strb.String() 4423} 4424 4425// UnnamedType is an unnamed type, that just has an index. 4426type UnnamedType struct { 4427 Num int 4428} 4429 4430func (ut *UnnamedType) print(ps *printState) { 4431 if ps.llvmStyle { 4432 if ut.Num == 0 { 4433 ps.writeString("'unnamed'") 4434 } else { 4435 ps.writeString(fmt.Sprintf("'unnamed%d'", ut.Num-1)) 4436 } 4437 } else { 4438 ps.writeString(fmt.Sprintf("{unnamed type#%d}", ut.Num+1)) 4439 } 4440} 4441 4442func (ut *UnnamedType) Traverse(fn func(AST) bool) { 4443 fn(ut) 4444} 4445 4446func (ut *UnnamedType) Copy(fn func(AST) AST, skip func(AST) bool) AST { 4447 if skip(ut) { 4448 return nil 4449 } 4450 return fn(ut) 4451} 4452 4453func (ut *UnnamedType) GoString() string { 4454 return ut.goString(0, "") 4455} 4456 4457func (ut *UnnamedType) goString(indent int, field string) string { 4458 return fmt.Sprintf("%*s%sUnnamedType: Num: %d", indent, "", field, ut.Num) 4459} 4460 4461// Clone is a clone of a function, with a distinguishing suffix. 4462type Clone struct { 4463 Base AST 4464 Suffix string 4465} 4466 4467func (c *Clone) print(ps *printState) { 4468 ps.print(c.Base) 4469 if ps.llvmStyle { 4470 ps.writeByte(' ') 4471 ps.startScope('(') 4472 ps.writeString(c.Suffix) 4473 ps.endScope(')') 4474 } else { 4475 ps.writeString(fmt.Sprintf(" [clone %s]", c.Suffix)) 4476 } 4477} 4478 4479func (c *Clone) Traverse(fn func(AST) bool) { 4480 if fn(c) { 4481 c.Base.Traverse(fn) 4482 } 4483} 4484 4485func (c *Clone) Copy(fn func(AST) AST, skip func(AST) bool) AST { 4486 if skip(c) { 4487 return nil 4488 } 4489 base := c.Base.Copy(fn, skip) 4490 if base == nil { 4491 return fn(c) 4492 } 4493 c = &Clone{Base: base, Suffix: c.Suffix} 4494 if r := fn(c); r != nil { 4495 return r 4496 } 4497 return c 4498} 4499 4500func (c *Clone) GoString() string { 4501 return c.goString(0, "") 4502} 4503 4504func (c *Clone) goString(indent int, field string) string { 4505 return fmt.Sprintf("%*s%sClone: Suffix: %s\n%s", indent, "", field, 4506 c.Suffix, c.Base.goString(indent+2, "Base: ")) 4507} 4508 4509// Special is a special symbol, printed as a prefix plus another 4510// value. 4511type Special struct { 4512 Prefix string 4513 Val AST 4514} 4515 4516func (s *Special) print(ps *printState) { 4517 prefix := s.Prefix 4518 if ps.llvmStyle { 4519 switch prefix { 4520 case "TLS wrapper function for ": 4521 prefix = "thread-local wrapper routine for " 4522 case "TLS init function for ": 4523 prefix = "thread-local initialization routine for " 4524 } 4525 } 4526 ps.writeString(prefix) 4527 ps.print(s.Val) 4528} 4529 4530func (s *Special) Traverse(fn func(AST) bool) { 4531 if fn(s) { 4532 s.Val.Traverse(fn) 4533 } 4534} 4535 4536func (s *Special) Copy(fn func(AST) AST, skip func(AST) bool) AST { 4537 if skip(s) { 4538 return nil 4539 } 4540 val := s.Val.Copy(fn, skip) 4541 if val == nil { 4542 return fn(s) 4543 } 4544 s = &Special{Prefix: s.Prefix, Val: val} 4545 if r := fn(s); r != nil { 4546 return r 4547 } 4548 return s 4549} 4550 4551func (s *Special) GoString() string { 4552 return s.goString(0, "") 4553} 4554 4555func (s *Special) goString(indent int, field string) string { 4556 return fmt.Sprintf("%*s%sSpecial: Prefix: %s\n%s", indent, "", field, 4557 s.Prefix, s.Val.goString(indent+2, "Val: ")) 4558} 4559 4560// Special2 is like special, but uses two values. 4561type Special2 struct { 4562 Prefix string 4563 Val1 AST 4564 Middle string 4565 Val2 AST 4566} 4567 4568func (s *Special2) print(ps *printState) { 4569 ps.writeString(s.Prefix) 4570 ps.print(s.Val1) 4571 ps.writeString(s.Middle) 4572 ps.print(s.Val2) 4573} 4574 4575func (s *Special2) Traverse(fn func(AST) bool) { 4576 if fn(s) { 4577 s.Val1.Traverse(fn) 4578 s.Val2.Traverse(fn) 4579 } 4580} 4581 4582func (s *Special2) Copy(fn func(AST) AST, skip func(AST) bool) AST { 4583 if skip(s) { 4584 return nil 4585 } 4586 val1 := s.Val1.Copy(fn, skip) 4587 val2 := s.Val2.Copy(fn, skip) 4588 if val1 == nil && val2 == nil { 4589 return fn(s) 4590 } 4591 if val1 == nil { 4592 val1 = s.Val1 4593 } 4594 if val2 == nil { 4595 val2 = s.Val2 4596 } 4597 s = &Special2{Prefix: s.Prefix, Val1: val1, Middle: s.Middle, Val2: val2} 4598 if r := fn(s); r != nil { 4599 return r 4600 } 4601 return s 4602} 4603 4604func (s *Special2) GoString() string { 4605 return s.goString(0, "") 4606} 4607 4608func (s *Special2) goString(indent int, field string) string { 4609 return fmt.Sprintf("%*s%sSpecial2: Prefix: %s\n%s\n%*sMiddle: %s\n%s", indent, "", field, 4610 s.Prefix, s.Val1.goString(indent+2, "Val1: "), 4611 indent+2, "", s.Middle, s.Val2.goString(indent+2, "Val2: ")) 4612} 4613 4614// EnableIf is used by clang for an enable_if attribute. 4615type EnableIf struct { 4616 Type AST 4617 Args []AST 4618} 4619 4620func (ei *EnableIf) print(ps *printState) { 4621 ps.print(ei.Type) 4622 ps.writeString(" [enable_if:") 4623 ps.printList(ei.Args, nil) 4624 ps.writeString("]") 4625} 4626 4627func (ei *EnableIf) Traverse(fn func(AST) bool) { 4628 if fn(ei) { 4629 ei.Type.Traverse(fn) 4630 for _, a := range ei.Args { 4631 a.Traverse(fn) 4632 } 4633 } 4634} 4635 4636func (ei *EnableIf) Copy(fn func(AST) AST, skip func(AST) bool) AST { 4637 if skip(ei) { 4638 return nil 4639 } 4640 typ := ei.Type.Copy(fn, skip) 4641 argsChanged := false 4642 args := make([]AST, len(ei.Args)) 4643 for i, a := range ei.Args { 4644 ac := a.Copy(fn, skip) 4645 if ac == nil { 4646 args[i] = a 4647 } else { 4648 args[i] = ac 4649 argsChanged = true 4650 } 4651 } 4652 if typ == nil && !argsChanged { 4653 return fn(ei) 4654 } 4655 if typ == nil { 4656 typ = ei.Type 4657 } 4658 ei = &EnableIf{Type: typ, Args: args} 4659 if r := fn(ei); r != nil { 4660 return r 4661 } 4662 return ei 4663} 4664 4665func (ei *EnableIf) GoString() string { 4666 return ei.goString(0, "") 4667} 4668 4669func (ei *EnableIf) goString(indent int, field string) string { 4670 var args string 4671 if len(ei.Args) == 0 { 4672 args = fmt.Sprintf("%*sArgs: nil", indent+2, "") 4673 } else { 4674 args = fmt.Sprintf("%*sArgs:", indent+2, "") 4675 for i, a := range ei.Args { 4676 args += "\n" 4677 args += a.goString(indent+4, fmt.Sprintf("%d: ", i)) 4678 } 4679 } 4680 return fmt.Sprintf("%*s%sEnableIf:\n%s\n%s", indent, "", field, 4681 ei.Type.goString(indent+2, "Type: "), args) 4682} 4683 4684// ModuleName is a C++20 module. 4685type ModuleName struct { 4686 Parent AST 4687 Name AST 4688 IsPartition bool 4689} 4690 4691func (mn *ModuleName) print(ps *printState) { 4692 if mn.Parent != nil { 4693 ps.print(mn.Parent) 4694 } 4695 if mn.IsPartition { 4696 ps.writeByte(':') 4697 } else if mn.Parent != nil { 4698 ps.writeByte('.') 4699 } 4700 ps.print(mn.Name) 4701} 4702 4703func (mn *ModuleName) Traverse(fn func(AST) bool) { 4704 if fn(mn) { 4705 mn.Parent.Traverse(fn) 4706 mn.Name.Traverse(fn) 4707 } 4708} 4709 4710func (mn *ModuleName) Copy(fn func(AST) AST, skip func(AST) bool) AST { 4711 if skip(mn) { 4712 return nil 4713 } 4714 var parent AST 4715 if mn.Parent != nil { 4716 parent = mn.Parent.Copy(fn, skip) 4717 } 4718 name := mn.Name.Copy(fn, skip) 4719 if parent == nil && name == nil { 4720 return fn(mn) 4721 } 4722 if parent == nil { 4723 parent = mn.Parent 4724 } 4725 if name == nil { 4726 name = mn.Name 4727 } 4728 mn = &ModuleName{Parent: parent, Name: name, IsPartition: mn.IsPartition} 4729 if r := fn(mn); r != nil { 4730 return r 4731 } 4732 return mn 4733} 4734 4735func (mn *ModuleName) GoString() string { 4736 return mn.goString(0, "") 4737} 4738 4739func (mn *ModuleName) goString(indent int, field string) string { 4740 var parent string 4741 if mn.Parent == nil { 4742 parent = fmt.Sprintf("%*sParent: nil", indent+2, "") 4743 } else { 4744 parent = mn.Parent.goString(indent+2, "Parent: ") 4745 } 4746 return fmt.Sprintf("%*s%sModuleName: IsPartition: %t\n%s\n%s", indent, "", field, 4747 mn.IsPartition, parent, 4748 mn.Name.goString(indent+2, "Name: ")) 4749} 4750 4751// ModuleEntity is a name inside a module. 4752type ModuleEntity struct { 4753 Module AST 4754 Name AST 4755} 4756 4757func (me *ModuleEntity) print(ps *printState) { 4758 ps.print(me.Name) 4759 ps.writeByte('@') 4760 ps.print(me.Module) 4761} 4762 4763func (me *ModuleEntity) Traverse(fn func(AST) bool) { 4764 if fn(me) { 4765 me.Module.Traverse(fn) 4766 me.Name.Traverse(fn) 4767 } 4768} 4769 4770func (me *ModuleEntity) Copy(fn func(AST) AST, skip func(AST) bool) AST { 4771 if skip(me) { 4772 return nil 4773 } 4774 module := me.Module.Copy(fn, skip) 4775 name := me.Name.Copy(fn, skip) 4776 if module == nil && name == nil { 4777 return fn(me) 4778 } 4779 if module == nil { 4780 module = me.Module 4781 } 4782 if name == nil { 4783 name = me.Name 4784 } 4785 me = &ModuleEntity{Module: module, Name: name} 4786 if r := fn(me); r != nil { 4787 return r 4788 } 4789 return me 4790} 4791 4792func (me *ModuleEntity) GoString() string { 4793 return me.goString(0, "") 4794} 4795 4796func (me *ModuleEntity) goString(indent int, field string) string { 4797 return fmt.Sprintf("%*s%sModuleEntity:\n%s\n%s", indent, "", field, 4798 me.Module.goString(indent+2, "Module: "), 4799 me.Name.goString(indent+2, "Name: ")) 4800} 4801 4802// Friend is a member like friend name. 4803type Friend struct { 4804 Name AST 4805} 4806 4807func (f *Friend) print(ps *printState) { 4808 ps.writeString("friend ") 4809 ps.print(f.Name) 4810} 4811 4812func (f *Friend) Traverse(fn func(AST) bool) { 4813 if fn(f) { 4814 f.Name.Traverse(fn) 4815 } 4816} 4817 4818func (f *Friend) Copy(fn func(AST) AST, skip func(AST) bool) AST { 4819 if skip(f) { 4820 return nil 4821 } 4822 name := f.Name.Copy(fn, skip) 4823 if name == nil { 4824 return fn(f) 4825 } 4826 f = &Friend{Name: name} 4827 if r := fn(f); r != nil { 4828 return r 4829 } 4830 return f 4831} 4832 4833func (f *Friend) GoString() string { 4834 return f.goString(0, "") 4835} 4836 4837func (f *Friend) goString(indent int, field string) string { 4838 return fmt.Sprintf("%*s%sFriend:\n%s", indent, "", field, 4839 f.Name.goString(indent+2, "Name: ")) 4840} 4841 4842// Constraint represents an AST with a constraint. 4843type Constraint struct { 4844 Name AST 4845 Requires AST 4846} 4847 4848func (c *Constraint) print(ps *printState) { 4849 ps.print(c.Name) 4850 ps.writeString(" requires ") 4851 ps.print(c.Requires) 4852} 4853 4854func (c *Constraint) Traverse(fn func(AST) bool) { 4855 if fn(c) { 4856 c.Name.Traverse(fn) 4857 c.Requires.Traverse(fn) 4858 } 4859} 4860 4861func (c *Constraint) Copy(fn func(AST) AST, skip func(AST) bool) AST { 4862 if skip(c) { 4863 return nil 4864 } 4865 name := c.Name.Copy(fn, skip) 4866 requires := c.Requires.Copy(fn, skip) 4867 if name == nil && requires == nil { 4868 return fn(c) 4869 } 4870 if name == nil { 4871 name = c.Name 4872 } 4873 if requires == nil { 4874 requires = c.Requires 4875 } 4876 c = &Constraint{Name: name, Requires: requires} 4877 if r := fn(c); r != nil { 4878 return r 4879 } 4880 return c 4881} 4882 4883func (c *Constraint) GoString() string { 4884 return c.goString(0, "") 4885} 4886 4887func (c *Constraint) goString(indent int, field string) string { 4888 return fmt.Sprintf("%*s%sConstraint:\n%s\n%s", indent, "", field, 4889 c.Name.goString(indent+2, "Name: "), 4890 c.Requires.goString(indent+2, "Requires: ")) 4891} 4892 4893// RequiresExpr is a C++20 requires expression. 4894type RequiresExpr struct { 4895 Params []AST 4896 Requirements []AST 4897} 4898 4899func (re *RequiresExpr) print(ps *printState) { 4900 ps.writeString("requires") 4901 if len(re.Params) > 0 { 4902 ps.writeByte(' ') 4903 ps.startScope('(') 4904 ps.printList(re.Params, nil) 4905 ps.endScope(')') 4906 } 4907 ps.writeByte(' ') 4908 ps.startScope('{') 4909 for _, req := range re.Requirements { 4910 ps.print(req) 4911 } 4912 ps.writeByte(' ') 4913 ps.endScope('}') 4914} 4915 4916func (re *RequiresExpr) Traverse(fn func(AST) bool) { 4917 if fn(re) { 4918 for _, p := range re.Params { 4919 p.Traverse(fn) 4920 } 4921 for _, r := range re.Requirements { 4922 r.Traverse(fn) 4923 } 4924 } 4925} 4926 4927func (re *RequiresExpr) Copy(fn func(AST) AST, skip func(AST) bool) AST { 4928 if skip(re) { 4929 return nil 4930 } 4931 4932 changed := false 4933 4934 var params []AST 4935 if len(re.Params) > 0 { 4936 params = make([]AST, len(re.Params)) 4937 for i, p := range re.Params { 4938 pc := p.Copy(fn, skip) 4939 if pc == nil { 4940 params[i] = p 4941 } else { 4942 params[i] = pc 4943 changed = true 4944 } 4945 } 4946 } 4947 4948 requirements := make([]AST, len(re.Requirements)) 4949 for i, r := range re.Requirements { 4950 rc := r.Copy(fn, skip) 4951 if rc == nil { 4952 requirements[i] = r 4953 } else { 4954 requirements[i] = rc 4955 changed = true 4956 } 4957 } 4958 4959 if !changed { 4960 return fn(re) 4961 } 4962 4963 re = &RequiresExpr{Params: params, Requirements: requirements} 4964 if r := fn(re); r != nil { 4965 return r 4966 } 4967 return re 4968} 4969 4970func (re *RequiresExpr) GoString() string { 4971 return re.goString(0, "") 4972} 4973 4974func (re *RequiresExpr) goString(indent int, field string) string { 4975 var params strings.Builder 4976 if len(re.Params) == 0 { 4977 fmt.Fprintf(¶ms, "%*sParams: nil", indent+2, "") 4978 } else { 4979 fmt.Fprintf(¶ms, "%*sParams:", indent+2, "") 4980 for i, p := range re.Params { 4981 params.WriteByte('\n') 4982 params.WriteString(p.goString(indent+4, fmt.Sprintf("%d: ", i))) 4983 } 4984 } 4985 4986 var requirements strings.Builder 4987 fmt.Fprintf(&requirements, "%*sRequirements:", indent+2, "") 4988 for i, r := range re.Requirements { 4989 requirements.WriteByte('\n') 4990 requirements.WriteString(r.goString(indent+4, fmt.Sprintf("%d: ", i))) 4991 } 4992 4993 return fmt.Sprintf("%*s%sRequirements:\n%s\n%s", indent, "", field, 4994 params.String(), requirements.String()) 4995} 4996 4997// ExprRequirement is a simple requirement in a requires expression. 4998// This is an arbitrary expression. 4999type ExprRequirement struct { 5000 Expr AST 5001 Noexcept bool 5002 TypeReq AST 5003} 5004 5005func (er *ExprRequirement) print(ps *printState) { 5006 ps.writeByte(' ') 5007 if er.Noexcept || er.TypeReq != nil { 5008 ps.startScope('{') 5009 } 5010 ps.print(er.Expr) 5011 if er.Noexcept || er.TypeReq != nil { 5012 ps.endScope('}') 5013 } 5014 if er.Noexcept { 5015 ps.writeString(" noexcept") 5016 } 5017 if er.TypeReq != nil { 5018 ps.writeString(" -> ") 5019 ps.print(er.TypeReq) 5020 } 5021 ps.writeByte(';') 5022} 5023 5024func (er *ExprRequirement) Traverse(fn func(AST) bool) { 5025 if fn(er) { 5026 er.Expr.Traverse(fn) 5027 if er.TypeReq != nil { 5028 er.TypeReq.Traverse(fn) 5029 } 5030 } 5031} 5032 5033func (er *ExprRequirement) Copy(fn func(AST) AST, skip func(AST) bool) AST { 5034 if skip(er) { 5035 return nil 5036 } 5037 expr := er.Expr.Copy(fn, skip) 5038 var typeReq AST 5039 if er.TypeReq != nil { 5040 typeReq = er.TypeReq.Copy(fn, skip) 5041 } 5042 if expr == nil && typeReq == nil { 5043 return fn(er) 5044 } 5045 if expr == nil { 5046 expr = er.Expr 5047 } 5048 if typeReq == nil { 5049 typeReq = er.TypeReq 5050 } 5051 er = &ExprRequirement{Expr: expr, TypeReq: typeReq} 5052 if r := fn(er); r != nil { 5053 return r 5054 } 5055 return er 5056} 5057 5058func (er *ExprRequirement) GoString() string { 5059 return er.goString(0, "") 5060} 5061 5062func (er *ExprRequirement) goString(indent int, field string) string { 5063 var typeReq string 5064 if er.TypeReq != nil { 5065 typeReq = "\n" + er.TypeReq.goString(indent+2, "TypeReq: ") 5066 } 5067 5068 return fmt.Sprintf("%*s%sExprRequirement: Noexcept: %t\n%s%s", indent, "", field, 5069 er.Noexcept, 5070 er.Expr.goString(indent+2, "Expr: "), 5071 typeReq) 5072} 5073 5074// TypeRequirement is a type requirement in a requires expression. 5075type TypeRequirement struct { 5076 Type AST 5077} 5078 5079func (tr *TypeRequirement) print(ps *printState) { 5080 ps.writeString(" typename ") 5081 ps.print(tr.Type) 5082 ps.writeByte(';') 5083} 5084 5085func (tr *TypeRequirement) Traverse(fn func(AST) bool) { 5086 if fn(tr) { 5087 tr.Type.Traverse(fn) 5088 } 5089} 5090 5091func (tr *TypeRequirement) Copy(fn func(AST) AST, skip func(AST) bool) AST { 5092 if skip(tr) { 5093 return nil 5094 } 5095 typ := tr.Type.Copy(fn, skip) 5096 if typ == nil { 5097 return fn(tr) 5098 } 5099 tr = &TypeRequirement{Type: typ} 5100 if r := fn(tr); r != nil { 5101 return r 5102 } 5103 return tr 5104} 5105 5106func (tr *TypeRequirement) GoString() string { 5107 return tr.goString(0, "") 5108} 5109 5110func (tr *TypeRequirement) goString(indent int, field string) string { 5111 return fmt.Sprintf("%*s%sTypeRequirement:\n%s", indent, "", field, 5112 tr.Type.goString(indent+2, "")) 5113} 5114 5115// NestedRequirement is a nested requirement in a requires expression. 5116type NestedRequirement struct { 5117 Constraint AST 5118} 5119 5120func (nr *NestedRequirement) print(ps *printState) { 5121 ps.writeString(" requires ") 5122 ps.print(nr.Constraint) 5123 ps.writeByte(';') 5124} 5125 5126func (nr *NestedRequirement) Traverse(fn func(AST) bool) { 5127 if fn(nr) { 5128 nr.Constraint.Traverse(fn) 5129 } 5130} 5131 5132func (nr *NestedRequirement) Copy(fn func(AST) AST, skip func(AST) bool) AST { 5133 if skip(nr) { 5134 return nil 5135 } 5136 constraint := nr.Constraint.Copy(fn, skip) 5137 if constraint == nil { 5138 return fn(nr) 5139 } 5140 nr = &NestedRequirement{Constraint: constraint} 5141 if r := fn(nr); r != nil { 5142 return r 5143 } 5144 return nr 5145} 5146 5147func (nr *NestedRequirement) GoString() string { 5148 return nr.goString(0, "") 5149} 5150 5151func (nr *NestedRequirement) goString(indent int, field string) string { 5152 return fmt.Sprintf("%*s%sNestedRequirement:\n%s", indent, "", field, 5153 nr.Constraint.goString(indent+2, "")) 5154} 5155 5156// ExplicitObjectParameter represents a C++23 explicit object parameter. 5157type ExplicitObjectParameter struct { 5158 Base AST 5159} 5160 5161func (eop *ExplicitObjectParameter) print(ps *printState) { 5162 ps.writeString("this ") 5163 ps.print(eop.Base) 5164} 5165 5166func (eop *ExplicitObjectParameter) Traverse(fn func(AST) bool) { 5167 if fn(eop) { 5168 eop.Base.Traverse(fn) 5169 } 5170} 5171 5172func (eop *ExplicitObjectParameter) Copy(fn func(AST) AST, skip func(AST) bool) AST { 5173 if skip(eop) { 5174 return nil 5175 } 5176 base := eop.Base.Copy(fn, skip) 5177 if base == nil { 5178 return fn(eop) 5179 } 5180 eop = &ExplicitObjectParameter{Base: base} 5181 if r := fn(eop); r != nil { 5182 return r 5183 } 5184 return eop 5185} 5186 5187func (eop *ExplicitObjectParameter) GoString() string { 5188 return eop.goString(0, "") 5189} 5190 5191func (eop *ExplicitObjectParameter) goString(indent int, field string) string { 5192 return fmt.Sprintf("%*s%sExplicitObjectParameter:\n%s", indent, "", field, 5193 eop.Base.goString(indent+2, "")) 5194} 5195 5196// Print the inner types. 5197func (ps *printState) printInner(prefixOnly bool) []AST { 5198 var save []AST 5199 var psave *[]AST 5200 if prefixOnly { 5201 psave = &save 5202 } 5203 for len(ps.inner) > 0 { 5204 ps.printOneInner(psave) 5205 } 5206 return save 5207} 5208 5209// innerPrinter is an interface for types that can print themselves as 5210// inner types. 5211type innerPrinter interface { 5212 printInner(*printState) 5213} 5214 5215// Print the most recent inner type. If save is not nil, only print 5216// prefixes. 5217func (ps *printState) printOneInner(save *[]AST) { 5218 if len(ps.inner) == 0 { 5219 panic("printOneInner called with no inner types") 5220 } 5221 ln := len(ps.inner) 5222 a := ps.inner[ln-1] 5223 ps.inner = ps.inner[:ln-1] 5224 5225 if save != nil { 5226 if _, ok := a.(*MethodWithQualifiers); ok { 5227 *save = append(*save, a) 5228 return 5229 } 5230 } 5231 5232 if ip, ok := a.(innerPrinter); ok { 5233 ip.printInner(ps) 5234 } else { 5235 ps.print(a) 5236 } 5237} 5238 5239// isEmpty returns whether printing a will not print anything. 5240func (ps *printState) isEmpty(a AST) bool { 5241 switch a := a.(type) { 5242 case *ArgumentPack: 5243 for _, a := range a.Args { 5244 if !ps.isEmpty(a) { 5245 return false 5246 } 5247 } 5248 return true 5249 case *ExprList: 5250 return len(a.Exprs) == 0 5251 case *PackExpansion: 5252 return a.Pack != nil && ps.isEmpty(a.Base) 5253 default: 5254 return false 5255 } 5256} 5257