1
2
3
4
5
6
7
8
9
10
11
12
13 package demangle
14
15 import (
16 "errors"
17 "fmt"
18 "strings"
19 )
20
21
22
23 var ErrNotMangledName = errors.New("not a C++ or Rust mangled name")
24
25
26 type Option int
27
28 const (
29
30
31
32
33
34 NoParams Option = iota
35
36
37
38 NoTemplateParams
39
40
41
42
43 NoEnclosingParams
44
45
46
47 NoClones
48
49
50
51
52 NoRust
53
54
55 Verbose
56
57
58
59
60
61 LLVMStyle
62 )
63
64
65 const maxLengthShift = 16
66
67
68 const maxLengthMask = 0x1f << maxLengthShift
69
70
71
72
73
74
75 func MaxLength(pow int) Option {
76 if pow <= 0 || pow > 30 {
77 panic("demangle: invalid MaxLength value")
78 }
79 return Option(pow << maxLengthShift)
80 }
81
82
83 func isMaxLength(opt Option) bool {
84 return opt&maxLengthMask != 0
85 }
86
87
88 func maxLength(opt Option) int {
89 return 1 << ((opt & maxLengthMask) >> maxLengthShift)
90 }
91
92
93
94
95 func Filter(name string, options ...Option) string {
96 ret, err := ToString(name, options...)
97 if err != nil {
98 return name
99 }
100 return ret
101 }
102
103
104
105
106
107 func ToString(name string, options ...Option) (string, error) {
108 if strings.HasPrefix(name, "_R") {
109 return rustToString(name, options)
110 }
111
112
113
114
115
116 if strings.HasPrefix(name, "_ZN") {
117 rname := name
118 if pos := strings.LastIndex(rname, "E."); pos > 0 {
119 rname = rname[:pos+1]
120 }
121 if strings.HasSuffix(rname, "E") && len(rname) > 23 && rname[len(rname)-20:len(rname)-17] == "17h" {
122 noRust := false
123 for _, o := range options {
124 if o == NoRust {
125 noRust = true
126 break
127 }
128 }
129 if !noRust {
130 s, ok := oldRustToString(rname, options)
131 if ok {
132 return s, nil
133 }
134 }
135 }
136 }
137
138 a, err := ToAST(name, options...)
139 if err != nil {
140 return "", err
141 }
142 return ASTToString(a, options...), nil
143 }
144
145
146
147
148
149
150
151
152 func ToAST(name string, options ...Option) (AST, error) {
153 if strings.HasPrefix(name, "_Z") {
154 a, err := doDemangle(name[2:], options...)
155 return a, adjustErr(err, 2)
156 }
157
158 if strings.HasPrefix(name, "___Z") {
159
160 block := strings.LastIndex(name, "_block_invoke")
161 if block == -1 {
162 return nil, ErrNotMangledName
163 }
164 a, err := doDemangle(name[4:block], options...)
165 if err != nil {
166 return a, adjustErr(err, 4)
167 }
168 name = strings.TrimPrefix(name[block:], "_block_invoke")
169 if len(name) > 0 && name[0] == '_' {
170 name = name[1:]
171 }
172 for len(name) > 0 && isDigit(name[0]) {
173 name = name[1:]
174 }
175 if len(name) > 0 && name[0] != '.' {
176 return nil, errors.New("unparsed characters at end of mangled name")
177 }
178 a = &Special{Prefix: "invocation function for block in ", Val: a}
179 return a, nil
180 }
181
182 const prefix = "_GLOBAL_"
183 if strings.HasPrefix(name, prefix) {
184
185
186 i := 0
187 for i < len(options) {
188 if options[i] == NoParams {
189 options = append(options[:i], options[i+1:]...)
190 } else {
191 i++
192 }
193 }
194 a, err := globalCDtorName(name[len(prefix):], options...)
195 return a, adjustErr(err, len(prefix))
196 }
197
198 return nil, ErrNotMangledName
199 }
200
201
202
203 func globalCDtorName(name string, options ...Option) (AST, error) {
204 if len(name) < 4 {
205 return nil, ErrNotMangledName
206 }
207 switch name[0] {
208 case '.', '_', '$':
209 default:
210 return nil, ErrNotMangledName
211 }
212
213 var ctor bool
214 switch name[1] {
215 case 'I':
216 ctor = true
217 case 'D':
218 ctor = false
219 default:
220 return nil, ErrNotMangledName
221 }
222
223 if name[2] != '_' {
224 return nil, ErrNotMangledName
225 }
226
227 if !strings.HasPrefix(name[3:], "_Z") {
228 return &GlobalCDtor{Ctor: ctor, Key: &Name{Name: name}}, nil
229 } else {
230 a, err := doDemangle(name[5:], options...)
231 if err != nil {
232 return nil, adjustErr(err, 5)
233 }
234 return &GlobalCDtor{Ctor: ctor, Key: a}, nil
235 }
236 }
237
238
239 func doDemangle(name string, options ...Option) (ret AST, err error) {
240
241
242 defer func() {
243 if r := recover(); r != nil {
244 if de, ok := r.(demangleErr); ok {
245 ret = nil
246 err = de
247 return
248 }
249 panic(r)
250 }
251 }()
252
253 params := true
254 clones := true
255 verbose := false
256 for _, o := range options {
257 switch {
258 case o == NoParams:
259 params = false
260 clones = false
261 case o == NoClones:
262 clones = false
263 case o == Verbose:
264 verbose = true
265 case o == NoTemplateParams || o == NoEnclosingParams || o == LLVMStyle || isMaxLength(o):
266
267
268 case o == NoRust:
269
270 default:
271 return nil, fmt.Errorf("unrecognized demangler option %v", o)
272 }
273 }
274
275 st := &state{str: name, verbose: verbose}
276 a := st.encoding(params, notForLocalName)
277
278
279 if clones {
280 for len(st.str) > 1 && st.str[0] == '.' && (isLower(st.str[1]) || st.str[1] == '_' || isDigit(st.str[1])) {
281 a = st.cloneSuffix(a)
282 }
283 }
284
285 if clones && len(st.str) > 0 {
286 st.fail("unparsed characters at end of mangled name")
287 }
288
289 return a, nil
290 }
291
292
293 type state struct {
294 str string
295 verbose bool
296 off int
297 subs substitutions
298 templates []*Template
299
300
301
302 lambdaTemplateLevel int
303
304 parsingConstraint bool
305
306
307
308 typeTemplateParamCount int
309 nonTypeTemplateParamCount int
310 templateTemplateParamCount int
311 }
312
313
314 func (st *state) copy() *state {
315 n := new(state)
316 *n = *st
317 return n
318 }
319
320
321 func (st *state) fail(err string) {
322 panic(demangleErr{err: err, off: st.off})
323 }
324
325
326
327 func (st *state) failEarlier(err string, dec int) {
328 if st.off < dec {
329 panic("internal error")
330 }
331 panic(demangleErr{err: err, off: st.off - dec})
332 }
333
334
335 func (st *state) advance(add int) {
336 if len(st.str) < add {
337 panic("internal error")
338 }
339 st.str = st.str[add:]
340 st.off += add
341 }
342
343
344
345 func (st *state) checkChar(c byte) {
346 if len(st.str) == 0 || st.str[0] != c {
347 panic("internal error")
348 }
349 st.advance(1)
350 }
351
352
353
354 type demangleErr struct {
355 err string
356 off int
357 }
358
359
360 func (de demangleErr) Error() string {
361 return fmt.Sprintf("%s at %d", de.err, de.off)
362 }
363
364
365
366 func adjustErr(err error, adj int) error {
367 if err == nil {
368 return nil
369 }
370 if de, ok := err.(demangleErr); ok {
371 de.off += adj
372 return de
373 }
374 return err
375 }
376
377 type forLocalNameType int
378
379 const (
380 forLocalName forLocalNameType = iota
381 notForLocalName
382 )
383
384
385
386
387
388
389 func (st *state) encoding(params bool, local forLocalNameType) AST {
390 if len(st.str) < 1 {
391 st.fail("expected encoding")
392 }
393
394 if st.str[0] == 'G' || st.str[0] == 'T' {
395 return st.specialName()
396 }
397
398 a, explicitObjectParameter := st.name()
399 a = simplify(a)
400
401 if !params {
402
403
404
405
406
407 if mwq, ok := a.(*MethodWithQualifiers); ok {
408 a = mwq.Method
409 }
410
411
412
413
414
415
416 if q, ok := a.(*Qualified); ok && q.LocalName {
417 p := &q.Name
418 if da, ok := (*p).(*DefaultArg); ok {
419 p = &da.Arg
420 }
421 if mwq, ok := (*p).(*MethodWithQualifiers); ok {
422 *p = mwq.Method
423 }
424 }
425
426 return a
427 }
428
429 if len(st.str) == 0 || st.str[0] == 'E' {
430
431
432 return a
433 }
434
435 mwq, _ := a.(*MethodWithQualifiers)
436
437 var findTemplate func(AST) *Template
438 findTemplate = func(check AST) *Template {
439 switch check := check.(type) {
440 case *Template:
441 return check
442 case *Qualified:
443 if check.LocalName {
444 return findTemplate(check.Name)
445 } else if _, ok := check.Name.(*Constructor); ok {
446 return findTemplate(check.Name)
447 }
448 case *MethodWithQualifiers:
449 return findTemplate(check.Method)
450 case *Constructor:
451 if check.Base != nil {
452 return findTemplate(check.Base)
453 }
454 }
455 return nil
456 }
457
458 template := findTemplate(a)
459 var oldLambdaTemplateLevel int
460 if template != nil {
461 st.templates = append(st.templates, template)
462 oldLambdaTemplateLevel = st.lambdaTemplateLevel
463 st.lambdaTemplateLevel = 0
464 }
465
466
467
468
469 const enableIfPrefix = "Ua9enable_ifI"
470 var enableIfArgs []AST
471 if strings.HasPrefix(st.str, enableIfPrefix) {
472 st.advance(len(enableIfPrefix) - 1)
473 enableIfArgs = st.templateArgs()
474 }
475
476 ft := st.bareFunctionType(hasReturnType(a), explicitObjectParameter)
477
478 var constraint AST
479 if len(st.str) > 0 && st.str[0] == 'Q' {
480 constraint = st.constraintExpr()
481 }
482
483 if template != nil {
484 st.templates = st.templates[:len(st.templates)-1]
485 st.lambdaTemplateLevel = oldLambdaTemplateLevel
486 }
487
488 ft = simplify(ft)
489
490
491
492 if local == forLocalName {
493 if functype, ok := ft.(*FunctionType); ok {
494 functype.ForLocalName = true
495 }
496 }
497
498
499 if mwq != nil {
500 a = mwq.Method
501 mwq.Method = ft
502 ft = mwq
503 }
504 if q, ok := a.(*Qualified); ok && q.LocalName {
505 p := &q.Name
506 if da, ok := (*p).(*DefaultArg); ok {
507 p = &da.Arg
508 }
509 if mwq, ok := (*p).(*MethodWithQualifiers); ok {
510 *p = mwq.Method
511 mwq.Method = ft
512 ft = mwq
513 }
514 }
515
516 r := AST(&Typed{Name: a, Type: ft})
517
518 if len(enableIfArgs) > 0 {
519 r = &EnableIf{Type: r, Args: enableIfArgs}
520 }
521
522 if constraint != nil {
523 r = &Constraint{Name: r, Requires: constraint}
524 }
525
526 return r
527 }
528
529
530
531 func hasReturnType(a AST) bool {
532 switch a := a.(type) {
533 case *Qualified:
534 if a.LocalName {
535 return hasReturnType(a.Name)
536 }
537 return false
538 case *Template:
539 return !isCDtorConversion(a.Name)
540 case *TypeWithQualifiers:
541 return hasReturnType(a.Base)
542 case *MethodWithQualifiers:
543 return hasReturnType(a.Method)
544 default:
545 return false
546 }
547 }
548
549
550
551 func isCDtorConversion(a AST) bool {
552 switch a := a.(type) {
553 case *Qualified:
554 return isCDtorConversion(a.Name)
555 case *Constructor, *Destructor, *Cast:
556 return true
557 default:
558 return false
559 }
560 }
561
562
563
564
565 func (st *state) taggedName(a AST) AST {
566 for len(st.str) > 0 && st.str[0] == 'B' {
567 st.advance(1)
568 tag := st.sourceName()
569 a = &TaggedName{Name: a, Tag: tag}
570 }
571 return a
572 }
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589 func (st *state) name() (AST, bool) {
590 if len(st.str) < 1 {
591 st.fail("expected name")
592 }
593
594 var module AST
595 switch st.str[0] {
596 case 'N':
597 return st.nestedName()
598 case 'Z':
599 return st.localName()
600 case 'U':
601 a, isCast := st.unqualifiedName(nil)
602 if isCast {
603 st.setTemplate(a, nil)
604 }
605 return a, false
606 case 'S':
607 if len(st.str) < 2 {
608 st.advance(1)
609 st.fail("expected substitution index")
610 }
611 var a AST
612 isCast := false
613 subst := false
614 if st.str[1] == 't' {
615 st.advance(2)
616 a, isCast = st.unqualifiedName(nil)
617 a = &Qualified{Scope: &Name{Name: "std"}, Name: a, LocalName: false}
618 } else {
619 a = st.substitution(false)
620 if mn, ok := a.(*ModuleName); ok {
621 module = mn
622 break
623 }
624 subst = true
625 }
626 if len(st.str) > 0 && st.str[0] == 'I' {
627
628
629
630
631
632 if !subst {
633 st.subs.add(a)
634 }
635 args := st.templateArgs()
636 tmpl := &Template{Name: a, Args: args}
637 if isCast {
638 st.setTemplate(a, tmpl)
639 st.clearTemplateArgs(args)
640 isCast = false
641 }
642 a = tmpl
643 }
644 if isCast {
645 st.setTemplate(a, nil)
646 }
647 return a, false
648 }
649
650 a, isCast := st.unqualifiedName(module)
651 if len(st.str) > 0 && st.str[0] == 'I' {
652 st.subs.add(a)
653 args := st.templateArgs()
654 tmpl := &Template{Name: a, Args: args}
655 if isCast {
656 st.setTemplate(a, tmpl)
657 st.clearTemplateArgs(args)
658 isCast = false
659 }
660 a = tmpl
661 }
662 if isCast {
663 st.setTemplate(a, nil)
664 }
665 return a, false
666 }
667
668
669
670
671
672
673
674
675 func (st *state) nestedName() (AST, bool) {
676 st.checkChar('N')
677
678 var q AST
679 var r string
680
681 explicitObjectParameter := false
682 if len(st.str) > 0 && st.str[0] == 'H' {
683 st.advance(1)
684 explicitObjectParameter = true
685 } else {
686 q = st.cvQualifiers()
687 r = st.refQualifier()
688 }
689
690 a := st.prefix()
691
692 if q != nil || r != "" {
693 a = &MethodWithQualifiers{Method: a, Qualifiers: q, RefQualifier: r}
694 }
695 if len(st.str) == 0 || st.str[0] != 'E' {
696 st.fail("expected E after nested name")
697 }
698 st.advance(1)
699 return a, explicitObjectParameter
700 }
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717 func (st *state) prefix() AST {
718 var a AST
719
720
721 var last AST
722
723 var module AST
724
725 getLast := func(a AST) AST {
726 for {
727 if t, ok := a.(*Template); ok {
728 a = t.Name
729 } else if q, ok := a.(*Qualified); ok {
730 a = q.Name
731 } else if t, ok := a.(*TaggedName); ok {
732 a = t.Name
733 } else {
734 return a
735 }
736 }
737 }
738
739 var cast *Cast
740 for {
741 if len(st.str) == 0 {
742 st.fail("expected prefix")
743 }
744 var next AST
745
746 c := st.str[0]
747 if isDigit(c) || isLower(c) || c == 'U' || c == 'L' || c == 'F' || c == 'W' || (c == 'D' && len(st.str) > 1 && st.str[1] == 'C') {
748 un, isUnCast := st.unqualifiedName(module)
749 next = un
750 module = nil
751 if isUnCast {
752 if tn, ok := un.(*TaggedName); ok {
753 un = tn.Name
754 }
755 cast = un.(*Cast)
756 }
757 } else {
758 switch st.str[0] {
759 case 'C':
760 inheriting := false
761 st.advance(1)
762 if len(st.str) > 0 && st.str[0] == 'I' {
763 inheriting = true
764 st.advance(1)
765 }
766 if len(st.str) < 1 {
767 st.fail("expected constructor type")
768 }
769 if last == nil {
770 st.fail("constructor before name is seen")
771 }
772 st.advance(1)
773 var base AST
774 if inheriting {
775 base = st.demangleType(false)
776 }
777 next = &Constructor{
778 Name: getLast(last),
779 Base: base,
780 }
781 if len(st.str) > 0 && st.str[0] == 'B' {
782 next = st.taggedName(next)
783 }
784 case 'D':
785 if len(st.str) > 1 && (st.str[1] == 'T' || st.str[1] == 't') {
786 next = st.demangleType(false)
787 } else {
788 if len(st.str) < 2 {
789 st.fail("expected destructor type")
790 }
791 if last == nil {
792 st.fail("destructor before name is seen")
793 }
794 st.advance(2)
795 next = &Destructor{Name: getLast(last)}
796 if len(st.str) > 0 && st.str[0] == 'B' {
797 next = st.taggedName(next)
798 }
799 }
800 case 'S':
801 next = st.substitution(true)
802 if mn, ok := next.(*ModuleName); ok {
803 module = mn
804 next = nil
805 }
806 case 'I':
807 if a == nil {
808 st.fail("unexpected template arguments")
809 }
810 var args []AST
811 args = st.templateArgs()
812 tmpl := &Template{Name: a, Args: args}
813 if cast != nil {
814 st.setTemplate(cast, tmpl)
815 st.clearTemplateArgs(args)
816 cast = nil
817 }
818 a = nil
819 next = tmpl
820 case 'T':
821 next = st.templateParam()
822 case 'E':
823 if a == nil {
824 st.fail("expected prefix")
825 }
826 if cast != nil {
827 var toTmpl *Template
828 if castTempl, ok := cast.To.(*Template); ok {
829 toTmpl = castTempl
830 }
831 st.setTemplate(cast, toTmpl)
832 }
833 return a
834 case 'M':
835 if a == nil {
836 st.fail("unexpected lambda initializer")
837 }
838
839
840
841
842
843 st.advance(1)
844 continue
845 case 'J':
846
847
848
849
850
851 if a == nil {
852 st.fail("unexpected template arguments")
853 }
854 var args []AST
855 for len(st.str) == 0 || st.str[0] != 'E' {
856 arg := st.templateArg(nil)
857 args = append(args, arg)
858 }
859 st.advance(1)
860 tmpl := &Template{Name: a, Args: args}
861 if cast != nil {
862 st.setTemplate(cast, tmpl)
863 st.clearTemplateArgs(args)
864 cast = nil
865 }
866 a = nil
867 next = tmpl
868 default:
869 st.fail("unrecognized letter in prefix")
870 }
871 }
872
873 if next == nil {
874 continue
875 }
876
877 last = next
878 if a == nil {
879 a = next
880 } else {
881 a = &Qualified{Scope: a, Name: next, LocalName: false}
882 }
883
884 if c != 'S' && (len(st.str) == 0 || st.str[0] != 'E') {
885 st.subs.add(a)
886 }
887 }
888 }
889
890
891
892
893
894
895
896
897
898 func (st *state) unqualifiedName(module AST) (r AST, isCast bool) {
899 if len(st.str) < 1 {
900 st.fail("expected unqualified name")
901 }
902
903 module = st.moduleName(module)
904
905 friend := false
906 if len(st.str) > 0 && st.str[0] == 'F' {
907 st.advance(1)
908 friend = true
909 if len(st.str) < 1 {
910 st.fail("expected unqualified name")
911 }
912 }
913
914 var a AST
915 isCast = false
916 c := st.str[0]
917 if isDigit(c) {
918 a = st.sourceName()
919 } else if isLower(c) {
920 a, _ = st.operatorName(false)
921 if _, ok := a.(*Cast); ok {
922 isCast = true
923 }
924 if op, ok := a.(*Operator); ok && op.Name == `operator"" ` {
925 n := st.sourceName()
926 a = &Unary{Op: op, Expr: n, Suffix: false, SizeofType: false}
927 }
928 } else if c == 'D' && len(st.str) > 1 && st.str[1] == 'C' {
929 var bindings []AST
930 st.advance(2)
931 for {
932 binding := st.sourceName()
933 bindings = append(bindings, binding)
934 if len(st.str) > 0 && st.str[0] == 'E' {
935 st.advance(1)
936 break
937 }
938 }
939 a = &StructuredBindings{Bindings: bindings}
940 } else {
941 switch c {
942 case 'C', 'D':
943 st.fail("constructor/destructor not in nested name")
944 case 'L':
945 st.advance(1)
946 a = st.sourceName()
947 a = st.discriminator(a)
948 case 'U':
949 if len(st.str) < 2 {
950 st.advance(1)
951 st.fail("expected closure or unnamed type")
952 }
953 c := st.str[1]
954 switch c {
955 case 'b':
956 st.advance(2)
957 st.compactNumber()
958 a = &Name{Name: "'block-literal'"}
959 case 'l':
960 a = st.closureTypeName()
961 case 't':
962 a = st.unnamedTypeName()
963 default:
964 st.advance(1)
965 st.fail("expected closure or unnamed type")
966 }
967 default:
968 st.fail("expected unqualified name")
969 }
970 }
971
972 if module != nil {
973 a = &ModuleEntity{Module: module, Name: a}
974 }
975
976 if len(st.str) > 0 && st.str[0] == 'B' {
977 a = st.taggedName(a)
978 }
979
980 if friend {
981 a = &Friend{Name: a}
982 }
983
984 return a, isCast
985 }
986
987
988
989
990
991 func (st *state) sourceName() AST {
992 val := st.number()
993 if val <= 0 {
994 st.fail("expected positive number")
995 }
996 if len(st.str) < val {
997 st.fail("not enough characters for identifier")
998 }
999 id := st.str[:val]
1000 st.advance(val)
1001
1002
1003
1004 const anonPrefix = "_GLOBAL_"
1005 if strings.HasPrefix(id, anonPrefix) && len(id) > len(anonPrefix)+2 {
1006 c1 := id[len(anonPrefix)]
1007 c2 := id[len(anonPrefix)+1]
1008 if (c1 == '.' || c1 == '_' || c1 == '$') && c2 == 'N' {
1009 id = "(anonymous namespace)"
1010 }
1011 }
1012
1013 n := &Name{Name: id}
1014 return n
1015 }
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026 func (st *state) moduleName(parent AST) AST {
1027 ret := parent
1028 for len(st.str) > 0 && st.str[0] == 'W' {
1029 st.advance(1)
1030 isPartition := false
1031 if len(st.str) > 0 && st.str[0] == 'P' {
1032 st.advance(1)
1033 isPartition = true
1034 }
1035 name := st.sourceName()
1036 ret = &ModuleName{
1037 Parent: ret,
1038 Name: name,
1039 IsPartition: isPartition,
1040 }
1041 st.subs.add(ret)
1042 }
1043 return ret
1044 }
1045
1046
1047
1048
1049 func (st *state) number() int {
1050 neg := false
1051 if len(st.str) > 0 && st.str[0] == 'n' {
1052 neg = true
1053 st.advance(1)
1054 }
1055 if len(st.str) == 0 || !isDigit(st.str[0]) {
1056 st.fail("missing number")
1057 }
1058 val := 0
1059 for len(st.str) > 0 && isDigit(st.str[0]) {
1060
1061
1062 if val >= 0x80000000/10-10 {
1063 st.fail("numeric overflow")
1064 }
1065 val = val*10 + int(st.str[0]-'0')
1066 st.advance(1)
1067 }
1068 if neg {
1069 val = -val
1070 }
1071 return val
1072 }
1073
1074
1075
1076
1077
1078
1079 func (st *state) seqID(eofOK bool) int {
1080 if len(st.str) > 0 && st.str[0] == '_' {
1081 st.advance(1)
1082 return 0
1083 }
1084 id := 0
1085 for {
1086 if len(st.str) == 0 {
1087 if eofOK {
1088 return id + 1
1089 }
1090 st.fail("missing end to sequence ID")
1091 }
1092
1093 if id >= 0x80000000/36-36 {
1094 st.fail("sequence ID overflow")
1095 }
1096 c := st.str[0]
1097 if c == '_' {
1098 st.advance(1)
1099 return id + 1
1100 }
1101 if isDigit(c) {
1102 id = id*36 + int(c-'0')
1103 } else if isUpper(c) {
1104 id = id*36 + int(c-'A') + 10
1105 } else {
1106 st.fail("invalid character in sequence ID")
1107 }
1108 st.advance(1)
1109 }
1110 }
1111
1112
1113
1114 type operator struct {
1115 name string
1116 args int
1117 prec precedence
1118 }
1119
1120
1121
1122 var operators = map[string]operator{
1123 "aN": {"&=", 2, precAssign},
1124 "aS": {"=", 2, precAssign},
1125 "aa": {"&&", 2, precLogicalAnd},
1126 "ad": {"&", 1, precUnary},
1127 "an": {"&", 2, precAnd},
1128 "at": {"alignof ", 1, precUnary},
1129 "aw": {"co_await ", 1, precPrimary},
1130 "az": {"alignof ", 1, precUnary},
1131 "cc": {"const_cast", 2, precPostfix},
1132 "cl": {"()", 2, precPostfix},
1133
1134
1135 "cp": {"()", 2, precPostfix},
1136 "cm": {",", 2, precComma},
1137 "co": {"~", 1, precUnary},
1138 "dV": {"/=", 2, precAssign},
1139 "dX": {"[...]=", 3, precAssign},
1140 "da": {"delete[] ", 1, precUnary},
1141 "dc": {"dynamic_cast", 2, precPostfix},
1142 "de": {"*", 1, precUnary},
1143 "di": {"=", 2, precAssign},
1144 "dl": {"delete ", 1, precUnary},
1145 "ds": {".*", 2, precPtrMem},
1146 "dt": {".", 2, precPostfix},
1147 "dv": {"/", 2, precAssign},
1148 "dx": {"]=", 2, precAssign},
1149 "eO": {"^=", 2, precAssign},
1150 "eo": {"^", 2, precXor},
1151 "eq": {"==", 2, precEqual},
1152 "fl": {"...", 2, precPrimary},
1153 "fr": {"...", 2, precPrimary},
1154 "fL": {"...", 3, precPrimary},
1155 "fR": {"...", 3, precPrimary},
1156 "ge": {">=", 2, precRel},
1157 "gs": {"::", 1, precUnary},
1158 "gt": {">", 2, precRel},
1159 "ix": {"[]", 2, precPostfix},
1160 "lS": {"<<=", 2, precAssign},
1161 "le": {"<=", 2, precRel},
1162 "li": {`operator"" `, 1, precUnary},
1163 "ls": {"<<", 2, precShift},
1164 "lt": {"<", 2, precRel},
1165 "mI": {"-=", 2, precAssign},
1166 "mL": {"*=", 2, precAssign},
1167 "mi": {"-", 2, precAdd},
1168 "ml": {"*", 2, precMul},
1169 "mm": {"--", 1, precPostfix},
1170 "na": {"new[]", 3, precUnary},
1171 "ne": {"!=", 2, precEqual},
1172 "ng": {"-", 1, precUnary},
1173 "nt": {"!", 1, precUnary},
1174 "nw": {"new", 3, precUnary},
1175 "nx": {"noexcept", 1, precUnary},
1176 "oR": {"|=", 2, precAssign},
1177 "oo": {"||", 2, precLogicalOr},
1178 "or": {"|", 2, precOr},
1179 "pL": {"+=", 2, precAssign},
1180 "pl": {"+", 2, precAdd},
1181 "pm": {"->*", 2, precPtrMem},
1182 "pp": {"++", 1, precPostfix},
1183 "ps": {"+", 1, precUnary},
1184 "pt": {"->", 2, precPostfix},
1185 "qu": {"?", 3, precCond},
1186 "rM": {"%=", 2, precAssign},
1187 "rS": {">>=", 2, precAssign},
1188 "rc": {"reinterpret_cast", 2, precPostfix},
1189 "rm": {"%", 2, precMul},
1190 "rs": {">>", 2, precShift},
1191 "sP": {"sizeof...", 1, precUnary},
1192 "sZ": {"sizeof...", 1, precUnary},
1193 "sc": {"static_cast", 2, precPostfix},
1194 "ss": {"<=>", 2, precSpaceship},
1195 "st": {"sizeof ", 1, precUnary},
1196 "sz": {"sizeof ", 1, precUnary},
1197 "te": {"typeid ", 1, precPostfix},
1198 "ti": {"typeid ", 1, precPostfix},
1199 "tr": {"throw", 0, precPrimary},
1200 "tw": {"throw ", 1, precUnary},
1201 }
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211 func (st *state) operatorName(inExpression bool) (AST, int) {
1212 if len(st.str) < 2 {
1213 st.fail("missing operator code")
1214 }
1215 code := st.str[:2]
1216 st.advance(2)
1217 if code[0] == 'v' && isDigit(code[1]) {
1218 name := st.sourceName()
1219 return &Operator{Name: name.(*Name).Name}, int(code[1] - '0')
1220 } else if code == "cv" {
1221
1222
1223
1224 if !inExpression {
1225 st.templates = append(st.templates, nil)
1226 }
1227
1228 t := st.demangleType(!inExpression)
1229
1230 if !inExpression {
1231 st.templates = st.templates[:len(st.templates)-1]
1232 }
1233
1234 return &Cast{To: t}, 1
1235 } else if op, ok := operators[code]; ok {
1236 return &Operator{Name: op.name, precedence: op.prec}, op.args
1237 } else {
1238 st.failEarlier("unrecognized operator code", 2)
1239 panic("not reached")
1240 }
1241 }
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251 func (st *state) localName() (AST, bool) {
1252 st.checkChar('Z')
1253 fn := st.encoding(true, forLocalName)
1254 if len(st.str) == 0 || st.str[0] != 'E' {
1255 st.fail("expected E after local name")
1256 }
1257 st.advance(1)
1258 if len(st.str) > 0 && st.str[0] == 's' {
1259 st.advance(1)
1260 var n AST = &Name{Name: "string literal"}
1261 n = st.discriminator(n)
1262 return &Qualified{Scope: fn, Name: n, LocalName: true}, false
1263 } else {
1264 num := -1
1265 if len(st.str) > 0 && st.str[0] == 'd' {
1266
1267 st.advance(1)
1268 num = st.compactNumber()
1269 }
1270 n, explicitObjectParameter := st.name()
1271 n = st.discriminator(n)
1272 if num >= 0 {
1273 n = &DefaultArg{Num: num, Arg: n}
1274 }
1275 return &Qualified{Scope: fn, Name: n, LocalName: true}, explicitObjectParameter
1276 }
1277 }
1278
1279
1280 func (st *state) javaResource() AST {
1281 off := st.off
1282 ln := st.number()
1283 if ln <= 1 {
1284 st.failEarlier("java resource length less than 1", st.off-off)
1285 }
1286 if len(st.str) == 0 || st.str[0] != '_' {
1287 st.fail("expected _ after number")
1288 }
1289 st.advance(1)
1290 ln--
1291 if len(st.str) < ln {
1292 st.fail("not enough characters for java resource length")
1293 }
1294 str := st.str[:ln]
1295 final := ""
1296 st.advance(ln)
1297 for i := 0; i < len(str); i++ {
1298 if str[i] != '$' {
1299 final += string(str[i])
1300 } else {
1301 if len(str) <= i+1 {
1302 st.failEarlier("java resource escape at end of string", 1)
1303 }
1304 i++
1305 r, ok := map[byte]string{
1306 'S': "/",
1307 '_': ".",
1308 '$': "$",
1309 }[str[i]]
1310 if !ok {
1311 st.failEarlier("unrecognized java resource escape", ln-i-1)
1312 }
1313 final += r
1314 }
1315 }
1316 return &Special{Prefix: "java resource ", Val: &Name{Name: final}}
1317 }
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339 func (st *state) specialName() AST {
1340 if st.str[0] == 'T' {
1341 st.advance(1)
1342 if len(st.str) == 0 {
1343 st.fail("expected special name code")
1344 }
1345 c := st.str[0]
1346 st.advance(1)
1347 switch c {
1348 case 'V':
1349 t := st.demangleType(false)
1350 return &Special{Prefix: "vtable for ", Val: t}
1351 case 'T':
1352 t := st.demangleType(false)
1353 return &Special{Prefix: "VTT for ", Val: t}
1354 case 'I':
1355 t := st.demangleType(false)
1356 return &Special{Prefix: "typeinfo for ", Val: t}
1357 case 'S':
1358 t := st.demangleType(false)
1359 return &Special{Prefix: "typeinfo name for ", Val: t}
1360 case 'A':
1361 t := st.templateArg(nil)
1362 return &Special{Prefix: "template parameter object for ", Val: t}
1363 case 'h':
1364 st.callOffset('h')
1365 v := st.encoding(true, notForLocalName)
1366 return &Special{Prefix: "non-virtual thunk to ", Val: v}
1367 case 'v':
1368 st.callOffset('v')
1369 v := st.encoding(true, notForLocalName)
1370 return &Special{Prefix: "virtual thunk to ", Val: v}
1371 case 'c':
1372 st.callOffset(0)
1373 st.callOffset(0)
1374 v := st.encoding(true, notForLocalName)
1375 return &Special{Prefix: "covariant return thunk to ", Val: v}
1376 case 'C':
1377 derived := st.demangleType(false)
1378 off := st.off
1379 offset := st.number()
1380 if offset < 0 {
1381 st.failEarlier("expected positive offset", st.off-off)
1382 }
1383 if len(st.str) == 0 || st.str[0] != '_' {
1384 st.fail("expected _ after number")
1385 }
1386 st.advance(1)
1387 base := st.demangleType(false)
1388 return &Special2{Prefix: "construction vtable for ", Val1: base, Middle: "-in-", Val2: derived}
1389 case 'F':
1390 t := st.demangleType(false)
1391 return &Special{Prefix: "typeinfo fn for ", Val: t}
1392 case 'J':
1393 t := st.demangleType(false)
1394 return &Special{Prefix: "java Class for ", Val: t}
1395 case 'H':
1396 n, _ := st.name()
1397 return &Special{Prefix: "TLS init function for ", Val: n}
1398 case 'W':
1399 n, _ := st.name()
1400 return &Special{Prefix: "TLS wrapper function for ", Val: n}
1401 default:
1402 st.fail("unrecognized special T name code")
1403 panic("not reached")
1404 }
1405 } else {
1406 st.checkChar('G')
1407 if len(st.str) == 0 {
1408 st.fail("expected special name code")
1409 }
1410 c := st.str[0]
1411 st.advance(1)
1412 switch c {
1413 case 'V':
1414 n, _ := st.name()
1415 return &Special{Prefix: "guard variable for ", Val: n}
1416 case 'R':
1417 n, _ := st.name()
1418 st.seqID(true)
1419 return &Special{Prefix: "reference temporary for ", Val: n}
1420 case 'A':
1421 v := st.encoding(true, notForLocalName)
1422 return &Special{Prefix: "hidden alias for ", Val: v}
1423 case 'T':
1424 if len(st.str) == 0 {
1425 st.fail("expected special GT name code")
1426 }
1427 c := st.str[0]
1428 st.advance(1)
1429 v := st.encoding(true, notForLocalName)
1430 switch c {
1431 case 'n':
1432 return &Special{Prefix: "non-transaction clone for ", Val: v}
1433 default:
1434
1435
1436
1437
1438 fallthrough
1439 case 't':
1440 return &Special{Prefix: "transaction clone for ", Val: v}
1441 }
1442 case 'r':
1443 return st.javaResource()
1444 case 'I':
1445 module := st.moduleName(nil)
1446 if module == nil {
1447 st.fail("expected module after GI")
1448 }
1449 return &Special{Prefix: "initializer for module ", Val: module}
1450 default:
1451 st.fail("unrecognized special G name code")
1452 panic("not reached")
1453 }
1454 }
1455 }
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470 func (st *state) callOffset(c byte) {
1471 if c == 0 {
1472 if len(st.str) == 0 {
1473 st.fail("missing call offset")
1474 }
1475 c = st.str[0]
1476 st.advance(1)
1477 }
1478 switch c {
1479 case 'h':
1480 st.number()
1481 case 'v':
1482 st.number()
1483 if len(st.str) == 0 || st.str[0] != '_' {
1484 st.fail("expected _ after number")
1485 }
1486 st.advance(1)
1487 st.number()
1488 default:
1489 st.failEarlier("unrecognized call offset code", 1)
1490 }
1491 if len(st.str) == 0 || st.str[0] != '_' {
1492 st.fail("expected _ after call offset")
1493 }
1494 st.advance(1)
1495 }
1496
1497
1498 var builtinTypes = map[byte]string{
1499 'a': "signed char",
1500 'b': "bool",
1501 'c': "char",
1502 'd': "double",
1503 'e': "long double",
1504 'f': "float",
1505 'g': "__float128",
1506 'h': "unsigned char",
1507 'i': "int",
1508 'j': "unsigned int",
1509 'l': "long",
1510 'm': "unsigned long",
1511 'n': "__int128",
1512 'o': "unsigned __int128",
1513 's': "short",
1514 't': "unsigned short",
1515 'v': "void",
1516 'w': "wchar_t",
1517 'x': "long long",
1518 'y': "unsigned long long",
1519 'z': "...",
1520 }
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542 func (st *state) demangleType(isCast bool) AST {
1543 if len(st.str) == 0 {
1544 st.fail("expected type")
1545 }
1546
1547 addSubst := true
1548
1549 q := st.cvQualifiers()
1550 if q != nil {
1551 if len(st.str) == 0 {
1552 st.fail("expected type")
1553 }
1554
1555
1556
1557
1558 if st.str[0] == 'F' {
1559 addSubst = false
1560 }
1561 }
1562
1563 var ret AST
1564
1565
1566 var sub AST
1567
1568 if btype, ok := builtinTypes[st.str[0]]; ok {
1569 ret = &BuiltinType{Name: btype}
1570 st.advance(1)
1571 if q != nil {
1572 ret = &TypeWithQualifiers{Base: ret, Qualifiers: q}
1573 st.subs.add(ret)
1574 }
1575 return ret
1576 }
1577 c := st.str[0]
1578 switch c {
1579 case 'u':
1580 st.advance(1)
1581 ret = st.sourceName()
1582 if len(st.str) > 0 && st.str[0] == 'I' {
1583 st.advance(1)
1584 base := st.demangleType(false)
1585 if len(st.str) == 0 || st.str[0] != 'E' {
1586 st.fail("expected E after transformed type")
1587 }
1588 st.advance(1)
1589 ret = &TransformedType{Name: ret.(*Name).Name, Base: base}
1590 }
1591 case 'F':
1592 ret = st.functionType()
1593 case 'N', 'W', 'Z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
1594 ret, _ = st.name()
1595 case 'A':
1596 ret = st.arrayType(isCast)
1597 case 'M':
1598 ret = st.pointerToMemberType(isCast)
1599 case 'T':
1600 if len(st.str) > 1 && (st.str[1] == 's' || st.str[1] == 'u' || st.str[1] == 'e') {
1601 c = st.str[1]
1602 st.advance(2)
1603 ret, _ = st.name()
1604 var kind string
1605 switch c {
1606 case 's':
1607 kind = "struct"
1608 case 'u':
1609 kind = "union"
1610 case 'e':
1611 kind = "enum"
1612 }
1613 ret = &ElaboratedType{Kind: kind, Type: ret}
1614 break
1615 }
1616
1617 ret = st.templateParam()
1618 if len(st.str) > 0 && st.str[0] == 'I' {
1619
1620 if !isCast {
1621 st.subs.add(ret)
1622 args := st.templateArgs()
1623 ret = &Template{Name: ret, Args: args}
1624 } else {
1625 ret = st.demangleCastTemplateArgs(ret, true)
1626 }
1627 }
1628 case 'S':
1629
1630
1631 var c2 byte
1632 if len(st.str) > 1 {
1633 c2 = st.str[1]
1634 }
1635 if isDigit(c2) || c2 == '_' || isUpper(c2) {
1636 ret = st.substitution(false)
1637 if _, ok := ret.(*ModuleName); ok {
1638 ret, _ = st.unqualifiedName(ret)
1639 st.subs.add(ret)
1640 }
1641 if len(st.str) == 0 || st.str[0] != 'I' {
1642 addSubst = false
1643 } else {
1644
1645 if _, ok := ret.(*TemplateParam); !ok || !isCast {
1646 args := st.templateArgs()
1647 ret = &Template{Name: ret, Args: args}
1648 } else {
1649 next := st.demangleCastTemplateArgs(ret, false)
1650 if next == ret {
1651 addSubst = false
1652 }
1653 ret = next
1654 }
1655 }
1656 } else {
1657 ret, _ = st.name()
1658
1659
1660
1661 if ret == subAST[c2] || ret == verboseAST[c2] {
1662 addSubst = false
1663 }
1664 }
1665 case 'O', 'P', 'R', 'C', 'G':
1666 st.advance(1)
1667 t := st.demangleType(isCast)
1668 switch c {
1669 case 'O':
1670 ret = &RvalueReferenceType{Base: t}
1671 case 'P':
1672 ret = &PointerType{Base: t}
1673 case 'R':
1674 ret = &ReferenceType{Base: t}
1675 case 'C':
1676 ret = &ComplexType{Base: t}
1677 case 'G':
1678 ret = &ImaginaryType{Base: t}
1679 }
1680 case 'U':
1681 if len(st.str) < 2 {
1682 st.fail("expected source name or unnamed type")
1683 }
1684 switch st.str[1] {
1685 case 'l':
1686 ret = st.closureTypeName()
1687 addSubst = false
1688 case 't':
1689 ret = st.unnamedTypeName()
1690 addSubst = false
1691 default:
1692 st.advance(1)
1693 n := st.sourceName()
1694 if len(st.str) > 0 && st.str[0] == 'I' {
1695 args := st.templateArgs()
1696 n = &Template{Name: n, Args: args}
1697 }
1698 t := st.demangleType(isCast)
1699 ret = &VendorQualifier{Qualifier: n, Type: t}
1700 }
1701 case 'D':
1702 st.advance(1)
1703 if len(st.str) == 0 {
1704 st.fail("expected D code for type")
1705 }
1706 addSubst = false
1707 c2 := st.str[0]
1708 st.advance(1)
1709 switch c2 {
1710 case 'T', 't':
1711
1712 ret = st.expression()
1713 if len(st.str) == 0 || st.str[0] != 'E' {
1714 st.fail("expected E after expression in type")
1715 }
1716 st.advance(1)
1717 ret = &Decltype{Expr: ret}
1718 addSubst = true
1719
1720 case 'p':
1721 t := st.demangleType(isCast)
1722 pack := st.findArgumentPack(t)
1723 ret = &PackExpansion{Base: t, Pack: pack}
1724 addSubst = true
1725
1726 case 'a':
1727 ret = &Name{Name: "auto"}
1728 case 'c':
1729 ret = &Name{Name: "decltype(auto)"}
1730
1731 case 'f':
1732 ret = &BuiltinType{Name: "decimal32"}
1733 case 'd':
1734 ret = &BuiltinType{Name: "decimal64"}
1735 case 'e':
1736 ret = &BuiltinType{Name: "decimal128"}
1737 case 'h':
1738 ret = &BuiltinType{Name: "half"}
1739 case 'u':
1740 ret = &BuiltinType{Name: "char8_t"}
1741 case 's':
1742 ret = &BuiltinType{Name: "char16_t"}
1743 case 'i':
1744 ret = &BuiltinType{Name: "char32_t"}
1745 case 'n':
1746 ret = &BuiltinType{Name: "decltype(nullptr)"}
1747
1748 case 'F':
1749 accum := false
1750 bits := 0
1751 if len(st.str) > 0 && isDigit(st.str[0]) {
1752 accum = true
1753 bits = st.number()
1754 }
1755 if len(st.str) > 0 && st.str[0] == '_' {
1756 if bits == 0 {
1757 st.fail("expected non-zero number of bits")
1758 }
1759 st.advance(1)
1760 ret = &BinaryFP{Bits: bits}
1761 } else {
1762 base := st.demangleType(isCast)
1763 if len(st.str) > 0 && isDigit(st.str[0]) {
1764
1765 st.number()
1766 }
1767 sat := false
1768 if len(st.str) > 0 {
1769 if st.str[0] == 's' {
1770 sat = true
1771 }
1772 st.advance(1)
1773 }
1774 ret = &FixedType{Base: base, Accum: accum, Sat: sat}
1775 }
1776
1777 case 'v':
1778 ret = st.vectorType(isCast)
1779 addSubst = true
1780
1781 case 'B', 'U':
1782 signed := c2 == 'B'
1783 var size AST
1784 if len(st.str) > 0 && isDigit(st.str[0]) {
1785 bits := st.number()
1786 size = &Name{Name: fmt.Sprintf("%d", bits)}
1787 } else {
1788 size = st.expression()
1789 }
1790 if len(st.str) == 0 || st.str[0] != '_' {
1791 st.fail("expected _ after _BitInt size")
1792 }
1793 st.advance(1)
1794 ret = &BitIntType{Size: size, Signed: signed}
1795
1796 case 'k':
1797 constraint, _ := st.name()
1798 ret = &SuffixType{
1799 Base: constraint,
1800 Suffix: "auto",
1801 }
1802
1803 case 'K':
1804 constraint, _ := st.name()
1805 ret = &SuffixType{
1806 Base: constraint,
1807 Suffix: "decltype(auto)",
1808 }
1809
1810 default:
1811 st.fail("unrecognized D code in type")
1812 }
1813
1814 default:
1815 st.fail("unrecognized type code")
1816 }
1817
1818 if addSubst {
1819 if sub != nil {
1820 st.subs.add(sub)
1821 } else {
1822 st.subs.add(ret)
1823 }
1824 }
1825
1826 if q != nil {
1827 if _, ok := ret.(*FunctionType); ok {
1828 ret = &MethodWithQualifiers{Method: ret, Qualifiers: q, RefQualifier: ""}
1829 } else if mwq, ok := ret.(*MethodWithQualifiers); ok {
1830
1831
1832
1833 mwq.Qualifiers = mergeQualifiers(q, mwq.Qualifiers)
1834 } else {
1835
1836
1837 if qsub, ok := ret.(*TypeWithQualifiers); ok {
1838 q = mergeQualifiers(q, qsub.Qualifiers)
1839 ret = qsub.Base
1840 }
1841 ret = &TypeWithQualifiers{Base: ret, Qualifiers: q}
1842 }
1843 st.subs.add(ret)
1844 }
1845
1846 return ret
1847 }
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884 func (st *state) demangleCastTemplateArgs(tp AST, addSubst bool) AST {
1885 save := st.copy()
1886
1887 var args []AST
1888 failed := false
1889 func() {
1890 defer func() {
1891 if r := recover(); r != nil {
1892 if _, ok := r.(demangleErr); ok {
1893 failed = true
1894 } else {
1895 panic(r)
1896 }
1897 }
1898 }()
1899
1900 args = st.templateArgs()
1901 }()
1902
1903 if !failed && len(st.str) > 0 && st.str[0] == 'I' {
1904 if addSubst {
1905 st.subs.add(tp)
1906 }
1907 return &Template{Name: tp, Args: args}
1908 }
1909
1910
1911 *st = *save
1912 return tp
1913 }
1914
1915
1916 func mergeQualifiers(q1AST, q2AST AST) AST {
1917 if q1AST == nil {
1918 return q2AST
1919 }
1920 if q2AST == nil {
1921 return q1AST
1922 }
1923 q1 := q1AST.(*Qualifiers)
1924 m := make(map[string]bool)
1925 for _, qualAST := range q1.Qualifiers {
1926 qual := qualAST.(*Qualifier)
1927 if len(qual.Exprs) == 0 {
1928 m[qual.Name] = true
1929 }
1930 }
1931 rq := q1.Qualifiers
1932 for _, qualAST := range q2AST.(*Qualifiers).Qualifiers {
1933 qual := qualAST.(*Qualifier)
1934 if len(qual.Exprs) > 0 {
1935 rq = append(rq, qualAST)
1936 } else if !m[qual.Name] {
1937 rq = append(rq, qualAST)
1938 m[qual.Name] = true
1939 }
1940 }
1941 q1.Qualifiers = rq
1942 return q1
1943 }
1944
1945
1946
1947 var qualifiers = map[byte]string{
1948 'r': "restrict",
1949 'V': "volatile",
1950 'K': "const",
1951 }
1952
1953
1954
1955
1956 func (st *state) cvQualifiers() AST {
1957 var q []AST
1958 qualLoop:
1959 for len(st.str) > 0 {
1960 if qv, ok := qualifiers[st.str[0]]; ok {
1961 qual := &Qualifier{Name: qv}
1962 q = append([]AST{qual}, q...)
1963 st.advance(1)
1964 } else if len(st.str) > 1 && st.str[0] == 'D' {
1965 var qual AST
1966 switch st.str[1] {
1967 case 'x':
1968 qual = &Qualifier{Name: "transaction_safe"}
1969 st.advance(2)
1970 case 'o':
1971 qual = &Qualifier{Name: "noexcept"}
1972 st.advance(2)
1973 case 'O':
1974 st.advance(2)
1975 expr := st.expression()
1976 if len(st.str) == 0 || st.str[0] != 'E' {
1977 st.fail("expected E after computed noexcept expression")
1978 }
1979 st.advance(1)
1980 qual = &Qualifier{Name: "noexcept", Exprs: []AST{expr}}
1981 case 'w':
1982 st.advance(2)
1983 parmlist := st.parmlist(false)
1984 if len(st.str) == 0 || st.str[0] != 'E' {
1985 st.fail("expected E after throw parameter list")
1986 }
1987 st.advance(1)
1988 qual = &Qualifier{Name: "throw", Exprs: parmlist}
1989 default:
1990 break qualLoop
1991 }
1992 q = append([]AST{qual}, q...)
1993 } else {
1994 break
1995 }
1996 }
1997 if len(q) == 0 {
1998 return nil
1999 }
2000 return &Qualifiers{Qualifiers: q}
2001 }
2002
2003
2004
2005
2006
2007 func (st *state) refQualifier() string {
2008 if len(st.str) > 0 {
2009 switch st.str[0] {
2010 case 'R':
2011 st.advance(1)
2012 return "&"
2013 case 'O':
2014 st.advance(1)
2015 return "&&"
2016 }
2017 }
2018 return ""
2019 }
2020
2021
2022
2023
2024 func (st *state) parmlist(explicitObjectParameter bool) []AST {
2025 var ret []AST
2026 for {
2027 if len(st.str) < 1 {
2028 break
2029 }
2030 if st.str[0] == 'E' || st.str[0] == '.' {
2031 break
2032 }
2033 if (st.str[0] == 'R' || st.str[0] == 'O') && len(st.str) > 1 && st.str[1] == 'E' {
2034
2035 break
2036 }
2037 if st.str[0] == 'Q' {
2038
2039 break
2040 }
2041 ptype := st.demangleType(false)
2042
2043 if len(ret) == 0 && explicitObjectParameter {
2044 ptype = &ExplicitObjectParameter{Base: ptype}
2045 }
2046
2047 ret = append(ret, ptype)
2048 }
2049
2050
2051
2052
2053 if len(ret) == 0 {
2054 st.fail("expected at least one type in type list")
2055 }
2056
2057
2058 if len(ret) == 1 {
2059 if bt, ok := ret[0].(*BuiltinType); ok && bt.Name == "void" {
2060 ret = nil
2061 }
2062 }
2063
2064 return ret
2065 }
2066
2067
2068
2069
2070 func (st *state) functionType() AST {
2071 st.checkChar('F')
2072 if len(st.str) > 0 && st.str[0] == 'Y' {
2073
2074 st.advance(1)
2075 }
2076 ret := st.bareFunctionType(true, false)
2077 r := st.refQualifier()
2078 if r != "" {
2079 ret = &MethodWithQualifiers{Method: ret, Qualifiers: nil, RefQualifier: r}
2080 }
2081 if len(st.str) == 0 || st.str[0] != 'E' {
2082 st.fail("expected E after function type")
2083 }
2084 st.advance(1)
2085 return ret
2086 }
2087
2088
2089
2090
2091 func (st *state) bareFunctionType(hasReturnType, explicitObjectParameter bool) AST {
2092 if len(st.str) > 0 && st.str[0] == 'J' {
2093 hasReturnType = true
2094 st.advance(1)
2095 }
2096 var returnType AST
2097 if hasReturnType {
2098 returnType = st.demangleType(false)
2099 }
2100 types := st.parmlist(explicitObjectParameter)
2101 return &FunctionType{
2102 Return: returnType,
2103 Args: types,
2104 ForLocalName: false,
2105 }
2106 }
2107
2108
2109
2110
2111
2112 func (st *state) arrayType(isCast bool) AST {
2113 st.checkChar('A')
2114
2115 if len(st.str) == 0 {
2116 st.fail("missing array dimension")
2117 }
2118
2119 var dim AST
2120 if st.str[0] == '_' {
2121 dim = &Name{Name: ""}
2122 } else if isDigit(st.str[0]) {
2123 i := 1
2124 for len(st.str) > i && isDigit(st.str[i]) {
2125 i++
2126 }
2127 dim = &Name{Name: st.str[:i]}
2128 st.advance(i)
2129 } else {
2130 dim = st.expression()
2131 }
2132
2133 if len(st.str) == 0 || st.str[0] != '_' {
2134 st.fail("expected _ after dimension")
2135 }
2136 st.advance(1)
2137
2138 t := st.demangleType(isCast)
2139
2140 arr := &ArrayType{Dimension: dim, Element: t}
2141
2142
2143
2144 if q, ok := arr.Element.(*TypeWithQualifiers); ok {
2145 return &TypeWithQualifiers{Base: &ArrayType{Dimension: dim, Element: q.Base}, Qualifiers: q.Qualifiers}
2146 }
2147
2148 return arr
2149 }
2150
2151
2152
2153
2154
2155 func (st *state) vectorType(isCast bool) AST {
2156 if len(st.str) == 0 {
2157 st.fail("expected vector dimension")
2158 }
2159
2160 var dim AST
2161 if st.str[0] == '_' {
2162 st.advance(1)
2163 dim = st.expression()
2164 } else {
2165 num := st.number()
2166 dim = &Name{Name: fmt.Sprintf("%d", num)}
2167 }
2168
2169 if len(st.str) == 0 || st.str[0] != '_' {
2170 st.fail("expected _ after vector dimension")
2171 }
2172 st.advance(1)
2173
2174 t := st.demangleType(isCast)
2175
2176 return &VectorType{Dimension: dim, Base: t}
2177 }
2178
2179
2180
2181
2182 func (st *state) pointerToMemberType(isCast bool) AST {
2183 st.checkChar('M')
2184 cl := st.demangleType(false)
2185
2186
2187
2188
2189
2190
2191
2192
2193
2194
2195
2196
2197
2198
2199
2200
2201
2202
2203 mem := st.demangleType(isCast)
2204 return &PtrMem{Class: cl, Member: mem}
2205 }
2206
2207
2208
2209
2210 func (st *state) compactNumber() int {
2211 if len(st.str) == 0 {
2212 st.fail("missing index")
2213 }
2214 if st.str[0] == '_' {
2215 st.advance(1)
2216 return 0
2217 } else if st.str[0] == 'n' {
2218 st.fail("unexpected negative number")
2219 }
2220 n := st.number()
2221 if len(st.str) == 0 || st.str[0] != '_' {
2222 st.fail("missing underscore after number")
2223 }
2224 st.advance(1)
2225 return n + 1
2226 }
2227
2228
2229
2230
2231
2232
2233
2234
2235
2236
2237
2238
2239
2240 func (st *state) templateParam() AST {
2241 off := st.off
2242 str := st.str
2243 st.checkChar('T')
2244
2245 level := 0
2246 if len(st.str) > 0 && st.str[0] == 'L' {
2247 st.advance(1)
2248 level = st.compactNumber()
2249 }
2250
2251 n := st.compactNumber()
2252
2253
2254
2255 if st.parsingConstraint {
2256 return &Name{Name: str[:st.off-1-off]}
2257 }
2258
2259 if level >= len(st.templates) {
2260 if st.lambdaTemplateLevel > 0 && level == st.lambdaTemplateLevel-1 {
2261
2262
2263 return &LambdaAuto{Index: n}
2264 }
2265 st.failEarlier(fmt.Sprintf("template parameter is not in scope of template (level %d >= %d)", level, len(st.templates)), st.off-off)
2266 }
2267
2268 template := st.templates[level]
2269
2270 if template == nil {
2271
2272
2273
2274 return &TemplateParam{Index: n, Template: nil}
2275 }
2276
2277 if n >= len(template.Args) {
2278 if st.lambdaTemplateLevel > 0 && level == st.lambdaTemplateLevel-1 {
2279
2280
2281 return &LambdaAuto{Index: n}
2282 }
2283 st.failEarlier(fmt.Sprintf("template index out of range (%d >= %d)", n, len(template.Args)), st.off-off)
2284 }
2285
2286 return &TemplateParam{Index: n, Template: template}
2287 }
2288
2289
2290
2291
2292 func (st *state) setTemplate(a AST, tmpl *Template) {
2293 seen := make(map[AST]bool)
2294 a.Traverse(func(a AST) bool {
2295 switch a := a.(type) {
2296 case *TemplateParam:
2297 if a.Template != nil {
2298 if tmpl != nil {
2299 st.fail("duplicate template parameters")
2300 }
2301 return false
2302 }
2303 if tmpl == nil {
2304 st.fail("cast template parameter not in scope of template")
2305 }
2306 if a.Index >= len(tmpl.Args) {
2307 st.fail(fmt.Sprintf("cast template index out of range (%d >= %d)", a.Index, len(tmpl.Args)))
2308 }
2309 a.Template = tmpl
2310 return false
2311 case *Closure:
2312
2313
2314 return false
2315 default:
2316 if seen[a] {
2317 return false
2318 }
2319 seen[a] = true
2320 return true
2321 }
2322 })
2323 }
2324
2325
2326
2327
2328
2329 func (st *state) clearTemplateArgs(args []AST) {
2330 for _, a := range args {
2331 st.setTemplate(a, nil)
2332 }
2333 }
2334
2335
2336
2337
2338 func (st *state) templateArgs() []AST {
2339 if len(st.str) == 0 || (st.str[0] != 'I' && st.str[0] != 'J') {
2340 panic("internal error")
2341 }
2342 st.advance(1)
2343
2344 var ret []AST
2345 for len(st.str) == 0 || st.str[0] != 'E' {
2346 arg := st.templateArg(ret)
2347 ret = append(ret, arg)
2348
2349 if len(st.str) > 0 && st.str[0] == 'Q' {
2350
2351
2352 st.constraintExpr()
2353 if len(st.str) == 0 || st.str[0] != 'E' {
2354 st.fail("expected end of template arguments after constraint")
2355 }
2356 }
2357 }
2358 st.advance(1)
2359 return ret
2360 }
2361
2362
2363
2364
2365
2366
2367
2368
2369
2370 func (st *state) templateArg(prev []AST) AST {
2371 if len(st.str) == 0 {
2372 st.fail("missing template argument")
2373 }
2374 switch st.str[0] {
2375 case 'X':
2376 st.advance(1)
2377 expr := st.expression()
2378 if len(st.str) == 0 || st.str[0] != 'E' {
2379 st.fail("missing end of expression")
2380 }
2381 st.advance(1)
2382 return expr
2383
2384 case 'L':
2385 return st.exprPrimary()
2386
2387 case 'I', 'J':
2388 args := st.templateArgs()
2389 return &ArgumentPack{Args: args}
2390
2391 case 'T':
2392 var arg byte
2393 if len(st.str) > 1 {
2394 arg = st.str[1]
2395 }
2396 switch arg {
2397 case 'y', 'n', 't', 'p', 'k':
2398 off := st.off
2399
2400
2401
2402
2403 template := &Template{Args: prev}
2404 st.templates = append(st.templates, template)
2405
2406 param, _ := st.templateParamDecl()
2407
2408 st.templates = st.templates[:len(st.templates)-1]
2409
2410 if param == nil {
2411 st.failEarlier("expected template parameter as template argument", st.off-off)
2412 }
2413 arg := st.templateArg(nil)
2414 return &TemplateParamQualifiedArg{Param: param, Arg: arg}
2415 }
2416 return st.demangleType(false)
2417
2418 default:
2419 return st.demangleType(false)
2420 }
2421 }
2422
2423
2424 func (st *state) exprList(stop byte) AST {
2425 if len(st.str) > 0 && st.str[0] == stop {
2426 st.advance(1)
2427 return &ExprList{Exprs: nil}
2428 }
2429
2430 var exprs []AST
2431 for {
2432 e := st.expression()
2433 exprs = append(exprs, e)
2434 if len(st.str) > 0 && st.str[0] == stop {
2435 st.advance(1)
2436 break
2437 }
2438 }
2439 return &ExprList{Exprs: exprs}
2440 }
2441
2442
2443
2444
2445
2446
2447
2448
2449
2450
2451
2452
2453
2454
2455
2456
2457
2458
2459
2460
2461
2462
2463
2464
2465
2466
2467
2468
2469
2470
2471
2472
2473
2474
2475
2476
2477
2478
2479
2480
2481
2482
2483
2484
2485
2486
2487
2488
2489
2490
2491
2492
2493
2494
2495
2496
2497
2498
2499
2500
2501
2502
2503 func (st *state) expression() AST {
2504 if len(st.str) == 0 {
2505 st.fail("expected expression")
2506 }
2507 if st.str[0] == 'L' {
2508 return st.exprPrimary()
2509 } else if st.str[0] == 'T' {
2510 return st.templateParam()
2511 } else if st.str[0] == 's' && len(st.str) > 1 && st.str[1] == 'o' {
2512 st.advance(2)
2513 return st.subobject()
2514 } else if st.str[0] == 's' && len(st.str) > 1 && st.str[1] == 'r' {
2515 return st.unresolvedName()
2516 } else if st.str[0] == 's' && len(st.str) > 1 && st.str[1] == 'p' {
2517 st.advance(2)
2518 e := st.expression()
2519 pack := st.findArgumentPack(e)
2520 return &PackExpansion{Base: e, Pack: pack}
2521 } else if st.str[0] == 's' && len(st.str) > 1 && st.str[1] == 'Z' {
2522 st.advance(2)
2523 off := st.off
2524 e := st.expression()
2525 ap := st.findArgumentPack(e)
2526 if ap == nil {
2527 st.failEarlier("missing argument pack", st.off-off)
2528 }
2529 return &SizeofPack{Pack: ap}
2530 } else if st.str[0] == 's' && len(st.str) > 1 && st.str[1] == 'P' {
2531 st.advance(2)
2532 var args []AST
2533 for len(st.str) == 0 || st.str[0] != 'E' {
2534 arg := st.templateArg(nil)
2535 args = append(args, arg)
2536 }
2537 st.advance(1)
2538 return &SizeofArgs{Args: args}
2539 } else if st.str[0] == 'f' && len(st.str) > 1 && st.str[1] == 'p' {
2540 st.advance(2)
2541 if len(st.str) > 0 && st.str[0] == 'T' {
2542 st.advance(1)
2543 return &FunctionParam{Index: 0}
2544 } else {
2545
2546
2547 st.cvQualifiers()
2548 index := st.compactNumber()
2549 return &FunctionParam{Index: index + 1}
2550 }
2551 } else if st.str[0] == 'f' && len(st.str) > 2 && st.str[1] == 'L' && isDigit(st.str[2]) {
2552 st.advance(2)
2553
2554 st.number()
2555 if len(st.str) == 0 || st.str[0] != 'p' {
2556 st.fail("expected p after function parameter scope count")
2557 }
2558 st.advance(1)
2559
2560
2561 st.cvQualifiers()
2562 index := st.compactNumber()
2563 return &FunctionParam{Index: index + 1}
2564 } else if st.str[0] == 'm' && len(st.str) > 1 && st.str[1] == 'c' {
2565 st.advance(2)
2566 typ := st.demangleType(false)
2567 expr := st.expression()
2568 offset := 0
2569 if len(st.str) > 0 && (st.str[0] == 'n' || isDigit(st.str[0])) {
2570 offset = st.number()
2571 }
2572 if len(st.str) == 0 || st.str[0] != 'E' {
2573 st.fail("expected E after pointer-to-member conversion")
2574 }
2575 st.advance(1)
2576 return &PtrMemCast{
2577 Type: typ,
2578 Expr: expr,
2579 Offset: offset,
2580 }
2581 } else if isDigit(st.str[0]) || (st.str[0] == 'o' && len(st.str) > 1 && st.str[1] == 'n') {
2582 if st.str[0] == 'o' {
2583
2584 st.advance(2)
2585 }
2586 n, _ := st.unqualifiedName(nil)
2587 if len(st.str) > 0 && st.str[0] == 'I' {
2588 args := st.templateArgs()
2589 n = &Template{Name: n, Args: args}
2590 }
2591 return n
2592 } else if (st.str[0] == 'i' || st.str[0] == 't') && len(st.str) > 1 && st.str[1] == 'l' {
2593
2594 c := st.str[0]
2595 st.advance(2)
2596 var t AST
2597 if c == 't' {
2598 t = st.demangleType(false)
2599 }
2600 exprs := st.exprList('E')
2601 return &InitializerList{Type: t, Exprs: exprs}
2602 } else if st.str[0] == 's' && len(st.str) > 1 && st.str[1] == 't' {
2603 o, _ := st.operatorName(true)
2604 t := st.demangleType(false)
2605 return &Unary{Op: o, Expr: t, Suffix: false, SizeofType: true}
2606 } else if st.str[0] == 'u' {
2607 st.advance(1)
2608 name := st.sourceName()
2609
2610
2611 if n, ok := name.(*Name); ok && n.Name == "__uuidof" {
2612 if len(st.str) < 2 {
2613 st.fail("missing uuidof argument")
2614 }
2615 var operand AST
2616 if st.str[0] == 't' {
2617 st.advance(1)
2618 operand = st.demangleType(false)
2619 } else if st.str[0] == 'z' {
2620 st.advance(1)
2621 operand = st.expression()
2622 }
2623 if operand != nil {
2624 return &Binary{
2625 Op: &Operator{Name: "()"},
2626 Left: name,
2627 Right: &ExprList{
2628 Exprs: []AST{operand},
2629 },
2630 }
2631 }
2632 }
2633 var args []AST
2634 for {
2635 if len(st.str) == 0 {
2636 st.fail("missing argument in vendor extended expressoin")
2637 }
2638 if st.str[0] == 'E' {
2639 st.advance(1)
2640 break
2641 }
2642 arg := st.templateArg(nil)
2643 args = append(args, arg)
2644 }
2645 return &Binary{
2646 Op: &Operator{Name: "()"},
2647 Left: name,
2648 Right: &ExprList{Exprs: args},
2649 }
2650 } else if st.str[0] == 'r' && len(st.str) > 1 && (st.str[1] == 'q' || st.str[1] == 'Q') {
2651 return st.requiresExpr()
2652 } else {
2653 if len(st.str) < 2 {
2654 st.fail("missing operator code")
2655 }
2656 code := st.str[:2]
2657 o, args := st.operatorName(true)
2658 switch args {
2659 case 0:
2660 return &Nullary{Op: o}
2661
2662 case 1:
2663 suffix := false
2664 if code == "pp" || code == "mm" {
2665 if len(st.str) > 0 && st.str[0] == '_' {
2666 st.advance(1)
2667 } else {
2668 suffix = true
2669 }
2670 }
2671 var operand AST
2672 if _, ok := o.(*Cast); ok && len(st.str) > 0 && st.str[0] == '_' {
2673 st.advance(1)
2674 operand = st.exprList('E')
2675 } else {
2676 operand = st.expression()
2677 }
2678 return &Unary{Op: o, Expr: operand, Suffix: suffix, SizeofType: false}
2679
2680 case 2:
2681 var left, right AST
2682 if code == "sc" || code == "dc" || code == "cc" || code == "rc" {
2683 left = st.demangleType(false)
2684 } else if code[0] == 'f' {
2685 left, _ = st.operatorName(true)
2686 right = st.expression()
2687 return &Fold{Left: code[1] == 'l', Op: left, Arg1: right, Arg2: nil}
2688 } else if code == "di" {
2689 left, _ = st.unqualifiedName(nil)
2690 } else {
2691 left = st.expression()
2692 }
2693 if code == "cl" || code == "cp" {
2694 right = st.exprList('E')
2695 } else if code == "dt" || code == "pt" {
2696 if len(st.str) > 0 && st.str[0] == 'L' {
2697 right = st.exprPrimary()
2698 } else {
2699 right = st.unresolvedName()
2700 if len(st.str) > 0 && st.str[0] == 'I' {
2701 args := st.templateArgs()
2702 right = &Template{Name: right, Args: args}
2703 }
2704 }
2705 } else {
2706 right = st.expression()
2707 }
2708 return &Binary{Op: o, Left: left, Right: right}
2709
2710 case 3:
2711 if code[0] == 'n' {
2712 if code[1] != 'w' && code[1] != 'a' {
2713 panic("internal error")
2714 }
2715 place := st.exprList('_')
2716 if place.(*ExprList).Exprs == nil {
2717 place = nil
2718 }
2719 t := st.demangleType(false)
2720 var ini AST
2721 if len(st.str) > 0 && st.str[0] == 'E' {
2722 st.advance(1)
2723 } else if len(st.str) > 1 && st.str[0] == 'p' && st.str[1] == 'i' {
2724
2725 st.advance(2)
2726 ini = st.exprList('E')
2727 } else if len(st.str) > 1 && st.str[0] == 'i' && st.str[1] == 'l' {
2728
2729 ini = st.expression()
2730 } else {
2731 st.fail("unrecognized new initializer")
2732 }
2733 return &New{Op: o, Place: place, Type: t, Init: ini}
2734 } else if code[0] == 'f' {
2735 first, _ := st.operatorName(true)
2736 second := st.expression()
2737 third := st.expression()
2738 return &Fold{Left: code[1] == 'L', Op: first, Arg1: second, Arg2: third}
2739 } else {
2740 first := st.expression()
2741 second := st.expression()
2742 third := st.expression()
2743 return &Trinary{Op: o, First: first, Second: second, Third: third}
2744 }
2745
2746 default:
2747 st.fail(fmt.Sprintf("unsupported number of operator arguments: %d", args))
2748 panic("not reached")
2749 }
2750 }
2751 }
2752
2753
2754
2755
2756
2757 func (st *state) subobject() AST {
2758 typ := st.demangleType(false)
2759 expr := st.expression()
2760 offset := 0
2761 if len(st.str) > 0 && (st.str[0] == 'n' || isDigit(st.str[0])) {
2762 offset = st.number()
2763 }
2764 var selectors []int
2765 for len(st.str) > 0 && st.str[0] == '_' {
2766 st.advance(1)
2767 selector := 0
2768 if len(st.str) > 0 && (st.str[0] == 'n' || isDigit(st.str[0])) {
2769 selector = st.number()
2770 }
2771 selectors = append(selectors, selector)
2772 }
2773 pastEnd := false
2774 if len(st.str) > 0 && st.str[0] == 'p' {
2775 st.advance(1)
2776 pastEnd = true
2777 }
2778 if len(st.str) == 0 || st.str[0] != 'E' {
2779 st.fail("expected E after subobject")
2780 }
2781 st.advance(1)
2782 return &Subobject{
2783 Type: typ,
2784 SubExpr: expr,
2785 Offset: offset,
2786 Selectors: selectors,
2787 PastEnd: pastEnd,
2788 }
2789 }
2790
2791
2792
2793
2794
2795
2796
2797 func (st *state) unresolvedName() AST {
2798 if len(st.str) >= 2 && st.str[:2] == "gs" {
2799 st.advance(2)
2800 n := st.unresolvedName()
2801 return &Unary{
2802 Op: &Operator{Name: "::"},
2803 Expr: n,
2804 Suffix: false,
2805 SizeofType: false,
2806 }
2807 } else if len(st.str) >= 2 && st.str[:2] == "sr" {
2808 st.advance(2)
2809 if len(st.str) == 0 {
2810 st.fail("expected unresolved type")
2811 }
2812 switch st.str[0] {
2813 case 'T', 'D', 'S':
2814 t := st.demangleType(false)
2815 n := st.baseUnresolvedName()
2816 n = &Qualified{Scope: t, Name: n, LocalName: false}
2817 if len(st.str) > 0 && st.str[0] == 'I' {
2818 args := st.templateArgs()
2819 n = &Template{Name: n, Args: args}
2820 st.subs.add(n)
2821 }
2822 return n
2823 default:
2824 var s AST
2825 if st.str[0] == 'N' {
2826 st.advance(1)
2827 s = st.demangleType(false)
2828 }
2829 for len(st.str) == 0 || st.str[0] != 'E' {
2830
2831
2832 if s != nil && len(st.str) > 0 && !isDigit(st.str[0]) {
2833 if q, ok := s.(*Qualified); ok {
2834 a := q.Scope
2835 if t, ok := a.(*Template); ok {
2836 st.subs.add(t.Name)
2837 st.subs.add(t)
2838 } else {
2839 st.subs.add(a)
2840 }
2841 return s
2842 }
2843 }
2844 n := st.sourceName()
2845 if len(st.str) > 0 && st.str[0] == 'I' {
2846 st.subs.add(n)
2847 args := st.templateArgs()
2848 n = &Template{Name: n, Args: args}
2849 }
2850 if s == nil {
2851 s = n
2852 } else {
2853 s = &Qualified{Scope: s, Name: n, LocalName: false}
2854 }
2855 }
2856 if s == nil {
2857 st.fail("missing scope in unresolved name")
2858 }
2859 st.advance(1)
2860 n := st.baseUnresolvedName()
2861 return &Qualified{Scope: s, Name: n, LocalName: false}
2862 }
2863 } else {
2864 return st.baseUnresolvedName()
2865 }
2866 }
2867
2868
2869
2870
2871
2872
2873
2874
2875
2876 func (st *state) baseUnresolvedName() AST {
2877 var n AST
2878 if len(st.str) >= 2 && st.str[:2] == "on" {
2879 st.advance(2)
2880 n, _ = st.operatorName(true)
2881 } else if len(st.str) >= 2 && st.str[:2] == "dn" {
2882 st.advance(2)
2883 if len(st.str) > 0 && isDigit(st.str[0]) {
2884 n = st.sourceName()
2885 } else {
2886 n = st.demangleType(false)
2887 }
2888 n = &Destructor{Name: n}
2889 } else if len(st.str) > 0 && isDigit(st.str[0]) {
2890 n = st.sourceName()
2891 } else {
2892
2893
2894
2895 n, _ = st.operatorName(true)
2896 }
2897 if len(st.str) > 0 && st.str[0] == 'I' {
2898 args := st.templateArgs()
2899 n = &Template{Name: n, Args: args}
2900 }
2901 return n
2902 }
2903
2904
2905
2906
2907
2908
2909
2910
2911 func (st *state) requiresExpr() AST {
2912 st.checkChar('r')
2913 if len(st.str) == 0 || (st.str[0] != 'q' && st.str[0] != 'Q') {
2914 st.fail("expected q or Q in requires clause in expression")
2915 }
2916 kind := st.str[0]
2917 st.advance(1)
2918
2919 var params []AST
2920 if kind == 'Q' {
2921 for len(st.str) > 0 && st.str[0] != '_' {
2922 typ := st.demangleType(false)
2923 params = append(params, typ)
2924 }
2925 st.advance(1)
2926 }
2927
2928 var requirements []AST
2929 for len(st.str) > 0 && st.str[0] != 'E' {
2930 var req AST
2931 switch st.str[0] {
2932 case 'X':
2933 st.advance(1)
2934 expr := st.expression()
2935 var noexcept bool
2936 if len(st.str) > 0 && st.str[0] == 'N' {
2937 st.advance(1)
2938 noexcept = true
2939 }
2940 var typeReq AST
2941 if len(st.str) > 0 && st.str[0] == 'R' {
2942 st.advance(1)
2943 typeReq, _ = st.name()
2944 }
2945 req = &ExprRequirement{
2946 Expr: expr,
2947 Noexcept: noexcept,
2948 TypeReq: typeReq,
2949 }
2950
2951 case 'T':
2952 st.advance(1)
2953 typ := st.demangleType(false)
2954 req = &TypeRequirement{Type: typ}
2955
2956 case 'Q':
2957 st.advance(1)
2958
2959
2960 expr := st.expression()
2961 req = &NestedRequirement{Constraint: expr}
2962
2963 default:
2964 st.fail("unrecognized requirement code")
2965 }
2966
2967 requirements = append(requirements, req)
2968 }
2969
2970 if len(st.str) == 0 || st.str[0] != 'E' {
2971 st.fail("expected E after requirements")
2972 }
2973 st.advance(1)
2974
2975 return &RequiresExpr{
2976 Params: params,
2977 Requirements: requirements,
2978 }
2979 }
2980
2981
2982
2983
2984
2985
2986 func (st *state) exprPrimary() AST {
2987 st.checkChar('L')
2988 if len(st.str) == 0 {
2989 st.fail("expected primary expression")
2990
2991 }
2992
2993
2994
2995 var ret AST
2996 if st.str[0] == '_' || st.str[0] == 'Z' {
2997 if st.str[0] == '_' {
2998 st.advance(1)
2999 }
3000 if len(st.str) == 0 || st.str[0] != 'Z' {
3001 st.fail("expected mangled name")
3002 }
3003 st.advance(1)
3004 ret = st.encoding(true, notForLocalName)
3005 } else {
3006 t := st.demangleType(false)
3007
3008 isArrayType := func(typ AST) bool {
3009 if twq, ok := typ.(*TypeWithQualifiers); ok {
3010 typ = twq.Base
3011 }
3012 _, ok := typ.(*ArrayType)
3013 return ok
3014 }
3015
3016 neg := false
3017 if len(st.str) > 0 && st.str[0] == 'n' {
3018 neg = true
3019 st.advance(1)
3020 }
3021 if len(st.str) > 0 && st.str[0] == 'E' {
3022 if bt, ok := t.(*BuiltinType); ok && bt.Name == "decltype(nullptr)" {
3023
3024
3025
3026
3027 } else if cl, ok := t.(*Closure); ok {
3028
3029 st.advance(1)
3030 return &LambdaExpr{Type: cl}
3031 } else if isArrayType(t) {
3032 st.advance(1)
3033 return &StringLiteral{Type: t}
3034 } else {
3035 st.fail("missing literal value")
3036 }
3037 }
3038 i := 0
3039 for len(st.str) > i && st.str[i] != 'E' {
3040 i++
3041 }
3042 val := st.str[:i]
3043 st.advance(i)
3044 ret = &Literal{Type: t, Val: val, Neg: neg}
3045 }
3046 if len(st.str) == 0 || st.str[0] != 'E' {
3047 st.fail("expected E after literal")
3048 }
3049 st.advance(1)
3050 return ret
3051 }
3052
3053
3054
3055
3056
3057 func (st *state) discriminator(a AST) AST {
3058 if len(st.str) == 0 || st.str[0] != '_' {
3059
3060
3061 for i := 0; i < len(st.str); i++ {
3062 if !isDigit(st.str[i]) {
3063 return a
3064 }
3065 }
3066
3067 st.advance(len(st.str))
3068 return a
3069 }
3070 off := st.off
3071 st.advance(1)
3072 trailingUnderscore := false
3073 if len(st.str) > 0 && st.str[0] == '_' {
3074 st.advance(1)
3075 trailingUnderscore = true
3076 }
3077 d := st.number()
3078 if d < 0 {
3079 st.failEarlier("invalid negative discriminator", st.off-off)
3080 }
3081 if trailingUnderscore && d >= 10 {
3082 if len(st.str) == 0 || st.str[0] != '_' {
3083 st.fail("expected _ after discriminator >= 10")
3084 }
3085 st.advance(1)
3086 }
3087
3088
3089 return a
3090 }
3091
3092
3093
3094
3095
3096 func (st *state) closureTypeName() AST {
3097 st.checkChar('U')
3098 st.checkChar('l')
3099
3100 oldLambdaTemplateLevel := st.lambdaTemplateLevel
3101 st.lambdaTemplateLevel = len(st.templates) + 1
3102
3103 var templateArgs []AST
3104 var template *Template
3105 for len(st.str) > 1 && st.str[0] == 'T' {
3106 arg, templateVal := st.templateParamDecl()
3107 if arg == nil {
3108 break
3109 }
3110 templateArgs = append(templateArgs, arg)
3111 if template == nil {
3112 template = &Template{
3113 Name: &Name{Name: "lambda"},
3114 }
3115 st.templates = append(st.templates, template)
3116 }
3117 template.Args = append(template.Args, templateVal)
3118 }
3119
3120 var templateArgsConstraint AST
3121 if len(st.str) > 0 && st.str[0] == 'Q' {
3122 templateArgsConstraint = st.constraintExpr()
3123 }
3124
3125 types := st.parmlist(false)
3126
3127 st.lambdaTemplateLevel = oldLambdaTemplateLevel
3128
3129 if template != nil {
3130 st.templates = st.templates[:len(st.templates)-1]
3131 }
3132
3133 var callConstraint AST
3134 if len(st.str) > 0 && st.str[0] == 'Q' {
3135 callConstraint = st.constraintExpr()
3136 }
3137
3138 if len(st.str) == 0 || st.str[0] != 'E' {
3139 st.fail("expected E after closure type name")
3140 }
3141 st.advance(1)
3142 num := st.compactNumber()
3143 return &Closure{
3144 TemplateArgs: templateArgs,
3145 TemplateArgsConstraint: templateArgsConstraint,
3146 Types: types,
3147 Num: num,
3148 CallConstraint: callConstraint,
3149 }
3150 }
3151
3152
3153
3154
3155
3156
3157
3158
3159
3160
3161
3162
3163
3164 func (st *state) templateParamDecl() (AST, AST) {
3165 if len(st.str) < 2 || st.str[0] != 'T' {
3166 return nil, nil
3167 }
3168 mk := func(prefix string, p *int) AST {
3169 idx := *p
3170 (*p)++
3171 return &TemplateParamName{
3172 Prefix: prefix,
3173 Index: idx,
3174 }
3175 }
3176 switch st.str[1] {
3177 case 'y':
3178 st.advance(2)
3179 name := mk("$T", &st.typeTemplateParamCount)
3180 tp := &TypeTemplateParam{
3181 Name: name,
3182 }
3183 return tp, name
3184 case 'k':
3185
3186
3187
3188 hold := st.parsingConstraint
3189 st.parsingConstraint = true
3190 defer func() { st.parsingConstraint = hold }()
3191
3192 st.advance(2)
3193 constraint, _ := st.name()
3194 name := mk("$T", &st.typeTemplateParamCount)
3195 tp := &ConstrainedTypeTemplateParam{
3196 Name: name,
3197 Constraint: constraint,
3198 }
3199 return tp, name
3200 case 'n':
3201 st.advance(2)
3202 name := mk("$N", &st.nonTypeTemplateParamCount)
3203 typ := st.demangleType(false)
3204 tp := &NonTypeTemplateParam{
3205 Name: name,
3206 Type: typ,
3207 }
3208 return tp, name
3209 case 't':
3210 st.advance(2)
3211 name := mk("$TT", &st.templateTemplateParamCount)
3212 var params []AST
3213 var template *Template
3214 var constraint AST
3215 for {
3216 if len(st.str) == 0 {
3217 st.fail("expected closure template parameter")
3218 }
3219 if st.str[0] == 'E' {
3220 st.advance(1)
3221 break
3222 }
3223 off := st.off
3224 param, templateVal := st.templateParamDecl()
3225 if param == nil {
3226 st.failEarlier("expected closure template parameter", st.off-off)
3227 }
3228 params = append(params, param)
3229 if template == nil {
3230 template = &Template{
3231 Name: &Name{Name: "template_template"},
3232 }
3233 st.templates = append(st.templates, template)
3234 }
3235 template.Args = append(template.Args, templateVal)
3236
3237 if len(st.str) > 0 && st.str[0] == 'Q' {
3238
3239
3240 constraint = st.constraintExpr()
3241 if len(st.str) == 0 || st.str[0] != 'E' {
3242 st.fail("expected end of template template parameters after constraint")
3243 }
3244 }
3245 }
3246 if template != nil {
3247 st.templates = st.templates[:len(st.templates)-1]
3248 }
3249 tp := &TemplateTemplateParam{
3250 Name: name,
3251 Params: params,
3252 Constraint: constraint,
3253 }
3254 return tp, name
3255 case 'p':
3256 st.advance(2)
3257 off := st.off
3258 param, templateVal := st.templateParamDecl()
3259 if param == nil {
3260 st.failEarlier("expected lambda template parameter", st.off-off)
3261 }
3262 return &TemplateParamPack{Param: param}, templateVal
3263 default:
3264 return nil, nil
3265 }
3266 }
3267
3268
3269
3270
3271 func (st *state) unnamedTypeName() AST {
3272 st.checkChar('U')
3273 st.checkChar('t')
3274 num := st.compactNumber()
3275 ret := &UnnamedType{Num: num}
3276 st.subs.add(ret)
3277 return ret
3278 }
3279
3280
3281
3282 func (st *state) constraintExpr() AST {
3283 st.checkChar('Q')
3284
3285 hold := st.parsingConstraint
3286 st.parsingConstraint = true
3287 defer func() { st.parsingConstraint = hold }()
3288
3289 return st.expression()
3290 }
3291
3292
3293
3294 func (st *state) cloneSuffix(a AST) AST {
3295 i := 0
3296 if len(st.str) > 1 && st.str[0] == '.' && (isLower(st.str[1]) || isDigit(st.str[1]) || st.str[1] == '_') {
3297 i += 2
3298 for len(st.str) > i && (isLower(st.str[i]) || isDigit(st.str[i]) || st.str[i] == '_') {
3299 i++
3300 }
3301 }
3302 for len(st.str) > i+1 && st.str[i] == '.' && isDigit(st.str[i+1]) {
3303 i += 2
3304 for len(st.str) > i && isDigit(st.str[i]) {
3305 i++
3306 }
3307 }
3308 suffix := st.str[:i]
3309 st.advance(i)
3310 return &Clone{Base: a, Suffix: suffix}
3311 }
3312
3313
3314
3315 type substitutions []AST
3316
3317
3318 func (subs *substitutions) add(a AST) {
3319 *subs = append(*subs, a)
3320 }
3321
3322
3323 var subAST = map[byte]AST{
3324 't': &Name{Name: "std"},
3325 'a': &Qualified{Scope: &Name{Name: "std"}, Name: &Name{Name: "allocator"}},
3326 'b': &Qualified{Scope: &Name{Name: "std"}, Name: &Name{Name: "basic_string"}},
3327 's': &Qualified{Scope: &Name{Name: "std"}, Name: &Name{Name: "string"}},
3328 'i': &Qualified{Scope: &Name{Name: "std"}, Name: &Name{Name: "istream"}},
3329 'o': &Qualified{Scope: &Name{Name: "std"}, Name: &Name{Name: "ostream"}},
3330 'd': &Qualified{Scope: &Name{Name: "std"}, Name: &Name{Name: "iostream"}},
3331 }
3332
3333
3334
3335
3336 var verboseAST = map[byte]AST{
3337 't': &Name{Name: "std"},
3338 'a': &Qualified{Scope: &Name{Name: "std"}, Name: &Name{Name: "allocator"}},
3339 'b': &Qualified{Scope: &Name{Name: "std"}, Name: &Name{Name: "basic_string"}},
3340
3341
3342 's': &Template{
3343 Name: &Qualified{Scope: &Name{Name: "std"}, Name: &Name{Name: "basic_string"}},
3344 Args: []AST{
3345 &BuiltinType{Name: "char"},
3346 &Template{
3347 Name: &Qualified{Scope: &Name{Name: "std"}, Name: &Name{Name: "char_traits"}},
3348 Args: []AST{&BuiltinType{Name: "char"}}},
3349 &Template{
3350 Name: &Qualified{Scope: &Name{Name: "std"}, Name: &Name{Name: "allocator"}},
3351 Args: []AST{&BuiltinType{Name: "char"}}}}},
3352
3353 'i': &Template{
3354 Name: &Qualified{Scope: &Name{Name: "std"}, Name: &Name{Name: "basic_istream"}},
3355 Args: []AST{
3356 &BuiltinType{Name: "char"},
3357 &Template{
3358 Name: &Qualified{Scope: &Name{Name: "std"}, Name: &Name{Name: "char_traits"}},
3359 Args: []AST{&BuiltinType{Name: "char"}}}}},
3360
3361 'o': &Template{
3362 Name: &Qualified{Scope: &Name{Name: "std"}, Name: &Name{Name: "basic_ostream"}},
3363 Args: []AST{
3364 &BuiltinType{Name: "char"},
3365 &Template{
3366 Name: &Qualified{Scope: &Name{Name: "std"}, Name: &Name{Name: "char_traits"}},
3367 Args: []AST{&BuiltinType{Name: "char"}}}}},
3368
3369 'd': &Template{
3370 Name: &Qualified{Scope: &Name{Name: "std"}, Name: &Name{Name: "basic_iostream"}},
3371 Args: []AST{
3372 &BuiltinType{Name: "char"},
3373 &Template{
3374 Name: &Qualified{Scope: &Name{Name: "std"}, Name: &Name{Name: "char_traits"}},
3375 Args: []AST{&BuiltinType{Name: "char"}}}}},
3376 }
3377
3378
3379
3380
3381
3382
3383
3384
3385
3386
3387
3388
3389 func (st *state) substitution(forPrefix bool) AST {
3390 st.checkChar('S')
3391 if len(st.str) == 0 {
3392 st.fail("missing substitution index")
3393 }
3394 c := st.str[0]
3395 off := st.off
3396 if c == '_' || isDigit(c) || isUpper(c) {
3397 id := st.seqID(false)
3398 if id >= len(st.subs) {
3399 st.failEarlier(fmt.Sprintf("substitution index out of range (%d >= %d)", id, len(st.subs)), st.off-off)
3400 }
3401
3402 ret := st.subs[id]
3403
3404
3405
3406
3407
3408
3409
3410 copyTemplates := st.templates
3411 var oldLambdaTemplateLevel []int
3412
3413
3414 pushTemplate := func(template *Template) {
3415 copyTemplates = append(copyTemplates, template)
3416 oldLambdaTemplateLevel = append(oldLambdaTemplateLevel, st.lambdaTemplateLevel)
3417 st.lambdaTemplateLevel = 0
3418 }
3419 popTemplate := func() {
3420 copyTemplates = copyTemplates[:len(copyTemplates)-1]
3421 st.lambdaTemplateLevel = oldLambdaTemplateLevel[len(oldLambdaTemplateLevel)-1]
3422 oldLambdaTemplateLevel = oldLambdaTemplateLevel[:len(oldLambdaTemplateLevel)-1]
3423 }
3424
3425 copy := func(a AST) AST {
3426 var index int
3427 switch a := a.(type) {
3428 case *Typed:
3429
3430 if _, ok := a.Name.(*Template); ok {
3431 popTemplate()
3432 }
3433 return nil
3434 case *Closure:
3435
3436 st.lambdaTemplateLevel = oldLambdaTemplateLevel[len(oldLambdaTemplateLevel)-1]
3437 oldLambdaTemplateLevel = oldLambdaTemplateLevel[:len(oldLambdaTemplateLevel)-1]
3438 return nil
3439 case *TemplateParam:
3440 index = a.Index
3441 case *LambdaAuto:
3442
3443
3444
3445 index = a.Index
3446 default:
3447 return nil
3448 }
3449 if st.parsingConstraint {
3450
3451
3452 return &Name{Name: fmt.Sprintf("T%d", index)}
3453 }
3454 if st.lambdaTemplateLevel > 0 {
3455 if _, ok := a.(*LambdaAuto); ok {
3456 return nil
3457 }
3458 return &LambdaAuto{Index: index}
3459 }
3460 var template *Template
3461 if len(copyTemplates) > 0 {
3462 template = copyTemplates[len(copyTemplates)-1]
3463 } else if rt, ok := ret.(*Template); ok {
3464
3465
3466
3467
3468 template = rt
3469 } else {
3470 st.failEarlier("substituted template parameter not in scope of template", st.off-off)
3471 }
3472 if template == nil {
3473
3474
3475 return &TemplateParam{Index: index, Template: nil}
3476 }
3477
3478 if index >= len(template.Args) {
3479 st.failEarlier(fmt.Sprintf("substituted template index out of range (%d >= %d)", index, len(template.Args)), st.off-off)
3480 }
3481
3482 return &TemplateParam{Index: index, Template: template}
3483 }
3484 seen := make(map[AST]bool)
3485 skip := func(a AST) bool {
3486 switch a := a.(type) {
3487 case *Typed:
3488 if template, ok := a.Name.(*Template); ok {
3489
3490 pushTemplate(template)
3491 }
3492 return false
3493 case *Closure:
3494
3495 oldLambdaTemplateLevel = append(oldLambdaTemplateLevel, st.lambdaTemplateLevel)
3496 st.lambdaTemplateLevel = len(copyTemplates) + 1
3497 return false
3498 case *TemplateParam, *LambdaAuto:
3499 return false
3500 }
3501 if seen[a] {
3502 return true
3503 }
3504 seen[a] = true
3505 return false
3506 }
3507
3508 if c := ret.Copy(copy, skip); c != nil {
3509 return c
3510 }
3511
3512 return ret
3513 } else {
3514 st.advance(1)
3515 m := subAST
3516 if st.verbose {
3517 m = verboseAST
3518 }
3519
3520
3521 if forPrefix && len(st.str) > 0 && (st.str[0] == 'C' || st.str[0] == 'D') {
3522 m = verboseAST
3523 }
3524 a, ok := m[c]
3525 if !ok {
3526 st.failEarlier("unrecognized substitution code", 1)
3527 }
3528
3529 if len(st.str) > 0 && st.str[0] == 'B' {
3530 a = st.taggedName(a)
3531 st.subs.add(a)
3532 }
3533
3534 return a
3535 }
3536 }
3537
3538
3539 func isDigit(c byte) bool {
3540 return c >= '0' && c <= '9'
3541 }
3542
3543
3544 func isUpper(c byte) bool {
3545 return c >= 'A' && c <= 'Z'
3546 }
3547
3548
3549 func isLower(c byte) bool {
3550 return c >= 'a' && c <= 'z'
3551 }
3552
3553
3554
3555 func simplify(a AST) AST {
3556 seen := make(map[AST]bool)
3557 skip := func(a AST) bool {
3558 if seen[a] {
3559 return true
3560 }
3561 seen[a] = true
3562 return false
3563 }
3564 if r := a.Copy(simplifyOne, skip); r != nil {
3565 return r
3566 }
3567 return a
3568 }
3569
3570
3571
3572 func simplifyOne(a AST) AST {
3573 switch a := a.(type) {
3574 case *TemplateParam:
3575 if a.Template != nil && a.Index < len(a.Template.Args) {
3576 return a.Template.Args[a.Index]
3577 }
3578 case *MethodWithQualifiers:
3579 if m, ok := a.Method.(*MethodWithQualifiers); ok {
3580 ref := a.RefQualifier
3581 if ref == "" {
3582 ref = m.RefQualifier
3583 } else if m.RefQualifier != "" {
3584 if ref == "&" || m.RefQualifier == "&" {
3585 ref = "&"
3586 }
3587 }
3588 return &MethodWithQualifiers{Method: m.Method, Qualifiers: mergeQualifiers(a.Qualifiers, m.Qualifiers), RefQualifier: ref}
3589 }
3590 if t, ok := a.Method.(*TypeWithQualifiers); ok {
3591 return &MethodWithQualifiers{Method: t.Base, Qualifiers: mergeQualifiers(a.Qualifiers, t.Qualifiers), RefQualifier: a.RefQualifier}
3592 }
3593 case *TypeWithQualifiers:
3594 if ft, ok := a.Base.(*FunctionType); ok {
3595 return &MethodWithQualifiers{Method: ft, Qualifiers: a.Qualifiers, RefQualifier: ""}
3596 }
3597 if t, ok := a.Base.(*TypeWithQualifiers); ok {
3598 return &TypeWithQualifiers{Base: t.Base, Qualifiers: mergeQualifiers(a.Qualifiers, t.Qualifiers)}
3599 }
3600 if m, ok := a.Base.(*MethodWithQualifiers); ok {
3601 return &MethodWithQualifiers{Method: m.Method, Qualifiers: mergeQualifiers(a.Qualifiers, m.Qualifiers), RefQualifier: m.RefQualifier}
3602 }
3603 case *ReferenceType:
3604 if rt, ok := a.Base.(*ReferenceType); ok {
3605 return rt
3606 }
3607 if rrt, ok := a.Base.(*RvalueReferenceType); ok {
3608 return &ReferenceType{Base: rrt.Base}
3609 }
3610 case *RvalueReferenceType:
3611 if rrt, ok := a.Base.(*RvalueReferenceType); ok {
3612 return rrt
3613 }
3614 if rt, ok := a.Base.(*ReferenceType); ok {
3615 return rt
3616 }
3617 case *ArrayType:
3618
3619
3620 if q, ok := a.Element.(*TypeWithQualifiers); ok {
3621 return &TypeWithQualifiers{
3622 Base: &ArrayType{Dimension: a.Dimension, Element: q.Base},
3623 Qualifiers: q.Qualifiers,
3624 }
3625 }
3626 case *PackExpansion:
3627
3628
3629 if a.Pack != nil {
3630 exprs := make([]AST, len(a.Pack.Args))
3631 for i, arg := range a.Pack.Args {
3632 copy := func(sub AST) AST {
3633
3634
3635 if sub == a.Pack {
3636 return arg
3637 }
3638
3639 return nil
3640 }
3641
3642 seen := make(map[AST]bool)
3643 skip := func(sub AST) bool {
3644
3645
3646 if _, ok := sub.(*PackExpansion); ok {
3647 return true
3648 }
3649 if seen[sub] {
3650 return true
3651 }
3652 seen[sub] = true
3653 return false
3654 }
3655
3656 b := a.Base.Copy(copy, skip)
3657 if b == nil {
3658 b = a.Base
3659 }
3660 exprs[i] = simplify(b)
3661 }
3662 return &ExprList{Exprs: exprs}
3663 }
3664 }
3665 return nil
3666 }
3667
3668
3669
3670 func (st *state) findArgumentPack(a AST) *ArgumentPack {
3671 seen := make(map[AST]bool)
3672 var ret *ArgumentPack
3673 a.Traverse(func(a AST) bool {
3674 if ret != nil {
3675 return false
3676 }
3677 switch a := a.(type) {
3678 case *TemplateParam:
3679 if a.Template == nil || a.Index >= len(a.Template.Args) {
3680 return true
3681 }
3682 if pack, ok := a.Template.Args[a.Index].(*ArgumentPack); ok {
3683 ret = pack
3684 return false
3685 }
3686 case *PackExpansion, *Closure, *Name:
3687 return false
3688 case *TaggedName, *Operator, *BuiltinType, *FunctionParam:
3689 return false
3690 case *UnnamedType, *FixedType, *DefaultArg:
3691 return false
3692 }
3693 if seen[a] {
3694 return false
3695 }
3696 seen[a] = true
3697 return true
3698 })
3699 return ret
3700 }
3701
View as plain text