GoPLS Viewer

Home|gopls/go/ssa/builder_generic_test.go
1// Copyright 2022 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 ssa_test
6
7import (
8    "fmt"
9    "go/parser"
10    "go/token"
11    "reflect"
12    "sort"
13    "testing"
14
15    "golang.org/x/tools/go/expect"
16    "golang.org/x/tools/go/loader"
17    "golang.org/x/tools/go/ssa"
18    "golang.org/x/tools/internal/typeparams"
19)
20
21// TestGenericBodies tests that bodies of generic functions and methods containing
22// different constructs can be built in BuilderMode(0).
23//
24// Each test specifies the contents of package containing a single go file.
25// Each call print(arg0, arg1, ...) to the builtin print function
26// in ssa is correlated a comment at the end of the line of the form:
27//
28//    //@ types(a, b, c)
29//
30// where a, b and c are the types of the arguments to the print call
31// serialized using go/types.Type.String().
32// See x/tools/go/expect for details on the syntax.
33func TestGenericBodies(t *testing.T) {
34    if !typeparams.Enabled {
35        t.Skip("TestGenericBodies requires type parameters")
36    }
37    for _test := range []struct {
38        pkg      string // name of the package.
39        contents string // contents of the Go package.
40    }{
41        {
42            pkg"p",
43            contents`
44            package p
45
46            func f(x int) {
47                var i interface{}
48                print(i, 0) //@ types("interface{}", int)
49                print()     //@ types()
50                print(x)    //@ types(int)
51            }
52            `,
53        },
54        {
55            pkg"q",
56            contents`
57            package q
58
59            func f[T any](x T) {
60                print(x) //@ types(T)
61            }
62            `,
63        },
64        {
65            pkg"r",
66            contents`
67            package r
68
69            func f[T ~int]() {
70                var x T
71                print(x) //@ types(T)
72            }
73            `,
74        },
75        {
76            pkg"s",
77            contents`
78            package s
79
80            func a[T ~[4]byte](x T) {
81                for k, v := range x {
82                    print(x, k, v) //@ types(T, int, byte)
83                }
84            }
85            func b[T ~*[4]byte](x T) {
86                for k, v := range x {
87                    print(x, k, v) //@ types(T, int, byte)
88                }
89            }
90            func c[T ~[]byte](x T) {
91                for k, v := range x {
92                    print(x, k, v) //@ types(T, int, byte)
93                }
94            }
95            func d[T ~string](x T) {
96                for k, v := range x {
97                    print(x, k, v) //@ types(T, int, rune)
98                }
99            }
100            func e[T ~map[int]string](x T) {
101                for k, v := range x {
102                    print(x, k, v) //@ types(T, int, string)
103                }
104            }
105            func f[T ~chan string](x T) {
106                for v := range x {
107                    print(x, v) //@ types(T, string)
108                }
109            }
110
111            func From() {
112                type A [4]byte
113                print(a[A]) //@ types("func(x s.A)")
114
115                type B *[4]byte
116                print(b[B]) //@ types("func(x s.B)")
117
118                type C []byte
119                print(c[C]) //@ types("func(x s.C)")
120
121                type D string
122                print(d[D]) //@ types("func(x s.D)")
123
124                type E map[int]string
125                print(e[E]) //@ types("func(x s.E)")
126
127                type F chan string
128                print(f[F]) //@ types("func(x s.F)")
129            }
130            `,
131        },
132        {
133            pkg"t",
134            contents`
135            package t
136
137            func f[S any, T ~chan S](x T) {
138                for v := range x {
139                    print(x, v) //@ types(T, S)
140                }
141            }
142
143            func From() {
144                type F chan string
145                print(f[string, F]) //@ types("func(x t.F)")
146            }
147            `,
148        },
149        {
150            pkg"u",
151            contents`
152            package u
153
154            func fibonacci[T ~chan int](c, quit T) {
155                x, y := 0, 1
156                for {
157                    select {
158                    case c <- x:
159                        x, y = y, x+y
160                    case <-quit:
161                        print(c, quit, x, y) //@ types(T, T, int, int)
162                        return
163                    }
164                }
165            }
166            func start[T ~chan int](c, quit T) {
167                go func() {
168                    for i := 0; i < 10; i++ {
169                        print(<-c) //@ types(int)
170                    }
171                    quit <- 0
172                }()
173            }
174            func From() {
175                type F chan int
176                c := make(F)
177                quit := make(F)
178                print(start[F], c, quit)     //@ types("func(c u.F, quit u.F)", "u.F", "u.F")
179                print(fibonacci[F], c, quit) //@ types("func(c u.F, quit u.F)", "u.F", "u.F")
180            }
181            `,
182        },
183        {
184            pkg"v",
185            contents`
186            package v
187
188            func f[T ~struct{ x int; y string }](i int) T {
189                u := []T{ T{0, "lorem"},  T{1, "ipsum"}}
190                return u[i]
191            }
192            func From() {
193                type S struct{ x int; y string }
194                print(f[S])     //@ types("func(i int) v.S")
195            }
196            `,
197        },
198        {
199            pkg"w",
200            contents`
201            package w
202
203            func f[T ~[4]int8](x T, l, h int) []int8 {
204                return x[l:h]
205            }
206            func g[T ~*[4]int16](x T, l, h int) []int16 {
207                return x[l:h]
208            }
209            func h[T ~[]int32](x T, l, h int) T {
210                return x[l:h]
211            }
212            func From() {
213                type F [4]int8
214                type G *[4]int16
215                type H []int32
216                print(f[F](F{}, 0, 0))  //@ types("[]int8")
217                print(g[G](nil, 0, 0)) //@ types("[]int16")
218                print(h[H](nil, 0, 0)) //@ types("w.H")
219            }
220            `,
221        },
222        {
223            pkg"x",
224            contents`
225            package x
226
227            func h[E any, T ~[]E](x T, l, h int) []E {
228                s := x[l:h]
229                print(s) //@ types("T")
230                return s
231            }
232            func From() {
233                type H []int32
234                print(h[int32, H](nil, 0, 0)) //@ types("[]int32")
235            }
236            `,
237        },
238        {
239            pkg"y",
240            contents`
241            package y
242
243            // Test "make" builtin with different forms on core types and
244            // when capacities are constants or variable.
245            func h[E any, T ~[]E](m, n int) {
246                print(make(T, 3))    //@ types(T)
247                print(make(T, 3, 5)) //@ types(T)
248                print(make(T, m))    //@ types(T)
249                print(make(T, m, n)) //@ types(T)
250            }
251            func i[K comparable, E any, T ~map[K]E](m int) {
252                print(make(T))    //@ types(T)
253                print(make(T, 5)) //@ types(T)
254                print(make(T, m)) //@ types(T)
255            }
256            func j[E any, T ~chan E](m int) {
257                print(make(T))    //@ types(T)
258                print(make(T, 6)) //@ types(T)
259                print(make(T, m)) //@ types(T)
260            }
261            func From() {
262                type H []int32
263                h[int32, H](3, 4)
264                type I map[int8]H
265                i[int8, H, I](5)
266                type J chan I
267                j[I, J](6)
268            }
269            `,
270        },
271        {
272            pkg"z",
273            contents`
274            package z
275
276            func h[T ~[4]int](x T) {
277                print(len(x), cap(x)) //@ types(int, int)
278            }
279            func i[T ~[4]byte | []int | ~chan uint8](x T) {
280                print(len(x), cap(x)) //@ types(int, int)
281            }
282            func j[T ~[4]int | any | map[string]int]() {
283                print(new(T)) //@ types("*T")
284            }
285            func k[T ~[4]int | any | map[string]int](x T) {
286                print(x) //@ types(T)
287                panic(x)
288            }
289            `,
290        },
291        {
292            pkg"a",
293            contents`
294            package a
295
296            func f[E any, F ~func() E](x F) {
297                print(x, x()) //@ types(F, E)
298            }
299            func From() {
300                type T func() int
301                f[int, T](func() int { return 0 })
302                f[int, func() int](func() int { return 1 })
303            }
304            `,
305        },
306        {
307            pkg"b",
308            contents`
309            package b
310
311            func f[E any, M ~map[string]E](m M) {
312                y, ok := m["lorem"]
313                print(m, y, ok) //@ types(M, E, bool)
314            }
315            func From() {
316                type O map[string][]int
317                f(O{"lorem": []int{0, 1, 2, 3}})
318            }
319            `,
320        },
321        {
322            pkg"c",
323            contents`
324            package c
325
326            func a[T interface{ []int64 | [5]int64 }](x T) int64 {
327                print(x, x[2], x[3]) //@ types(T, int64, int64)
328                x[2] = 5
329                return x[3]
330            }
331            func b[T interface{ []byte | string }](x T) byte {
332                print(x, x[3]) //@ types(T, byte)
333                return x[3]
334            }
335            func c[T interface{ []byte }](x T) byte {
336                print(x, x[2], x[3]) //@ types(T, byte, byte)
337                x[2] = 'b'
338                return x[3]
339            }
340            func d[T interface{ map[int]int64 }](x T) int64 {
341                print(x, x[2], x[3]) //@ types(T, int64, int64)
342                x[2] = 43
343                return x[3]
344            }
345            func e[T ~string](t T) {
346                print(t, t[0]) //@ types(T, uint8)
347            }
348            func f[T ~string|[]byte](t T) {
349                print(t, t[0]) //@ types(T, uint8)
350            }
351            func g[T []byte](t T) {
352                print(t, t[0]) //@ types(T, byte)
353            }
354            func h[T ~[4]int|[]int](t T) {
355                print(t, t[0]) //@ types(T, int)
356            }
357            func i[T ~[4]int|*[4]int|[]int](t T) {
358                print(t, t[0]) //@ types(T, int)
359            }
360            func j[T ~[4]int|*[4]int|[]int](t T) {
361                print(t, &t[0]) //@ types(T, "*int")
362            }
363            `,
364        },
365        {
366            pkg"d",
367            contents`
368            package d
369
370            type MyInt int
371            type Other int
372            type MyInterface interface{ foo() }
373
374            // ChangeType tests
375            func ct0(x int) { v := MyInt(x);  print(x, v) /*@ types(int, "d.MyInt")*/ }
376            func ct1[T MyInt | Other, S int ](x S) { v := T(x);  print(x, v) /*@ types(S, T)*/ }
377            func ct2[T int, S MyInt | int ](x S) { v := T(x); print(x, v) /*@ types(S, T)*/ }
378            func ct3[T MyInt | Other, S MyInt | int ](x S) { v := T(x) ; print(x, v) /*@ types(S, T)*/ }
379
380            // Convert tests
381            func co0[T int | int8](x MyInt) { v := T(x); print(x, v) /*@ types("d.MyInt", T)*/}
382            func co1[T int | int8](x T) { v := MyInt(x); print(x, v) /*@ types(T, "d.MyInt")*/ }
383            func co2[S, T int | int8](x T) { v := S(x); print(x, v) /*@ types(T, S)*/ }
384
385            // MakeInterface tests
386            func mi0[T MyInterface](x T) { v := MyInterface(x); print(x, v) /*@ types(T, "d.MyInterface")*/ }
387
388            // NewConst tests
389            func nc0[T any]() { v := (*T)(nil); print(v) /*@ types("*T")*/}
390
391            // SliceToArrayPointer
392            func sl0[T *[4]int | *[2]int](x []int) { v := T(x); print(x, v) /*@ types("[]int", T)*/ }
393            func sl1[T *[4]int | *[2]int, S []int](x S) { v := T(x); print(x, v) /*@ types(S, T)*/ }
394            `,
395        },
396        {
397            pkg"e",
398            contents`
399            package e
400
401            func c[T interface{ foo() string }](x T) {
402                print(x, x.foo, x.foo())  /*@ types(T, "func() string", string)*/
403            }
404            `,
405        },
406        {
407            pkg"f",
408            contents`package f
409
410            func eq[T comparable](t T, i interface{}) bool {
411                return t == i
412            }
413            `,
414        },
415        {
416            pkg"g",
417            contents`package g
418            type S struct{ f int }
419            func c[P *S]() []P { return []P{{f: 1}} }
420            `,
421        },
422        {
423            pkg"h",
424            contents`package h
425            func sign[bytes []byte | string](s bytes) (bool, bool) {
426                neg := false
427                if len(s) > 0 && (s[0] == '-' || s[0] == '+') {
428                    neg = s[0] == '-'
429                    s = s[1:]
430                }
431                return !neg, len(s) > 0
432            }`,
433        },
434        {
435            pkg"i",
436            contents`package i
437            func digits[bytes []byte | string](s bytes) bool {
438                for _, c := range []byte(s) {
439                    if c < '0' || '9' < c {
440                        return false
441                    }
442                }
443                return true
444            }`,
445        },
446        {
447            pkg"j",
448            contents`
449            package j
450
451            type E interface{}
452
453            func Foo[T E, PT interface{ *T }]() T {
454                pt := PT(new(T))
455                x := *pt
456                print(x)  /*@ types(T)*/
457                return x
458            }
459            `,
460        },
461    } {
462        test := test
463        t.Run(test.pkg, func(t *testing.T) {
464            // Parse
465            conf := loader.Config{ParserModeparser.ParseComments}
466            fname := test.pkg + ".go"
467            ferr := conf.ParseFile(fnametest.contents)
468            if err != nil {
469                t.Fatalf("parse: %v"err)
470            }
471            conf.CreateFromFiles(test.pkgf)
472
473            // Load
474            lprogerr := conf.Load()
475            if err != nil {
476                t.Fatalf("Load: %v"err)
477            }
478
479            // Create and build SSA
480            prog := ssa.NewProgram(lprog.Fsetssa.SanityCheckFunctions)
481            for _info := range lprog.AllPackages {
482                if info.TransitivelyErrorFree {
483                    prog.CreatePackage(info.Pkginfo.Files, &info.Infoinfo.Importable)
484                }
485            }
486            p := prog.Package(lprog.Package(test.pkg).Pkg)
487            p.Build()
488
489            // Collect calls to the builtin print function.
490            probes := make(map[*ssa.CallCommon]bool)
491            for _mem := range p.Members {
492                if fnok := mem.(*ssa.Function); ok {
493                    for _bb := range fn.Blocks {
494                        for _i := range bb.Instrs {
495                            if iok := i.(ssa.CallInstruction); ok {
496                                call := i.Common()
497                                if bok := call.Value.(*ssa.Builtin); ok && b.Name() == "print" {
498                                    probes[i.Common()] = true
499                                }
500                            }
501                        }
502                    }
503                }
504            }
505
506            // Collect all notes in f, i.e. comments starting with "//@ types".
507            noteserr := expect.ExtractGo(prog.Fsetf)
508            if err != nil {
509                t.Errorf("expect.ExtractGo: %v"err)
510            }
511
512            // Matches each probe with a note that has the same line.
513            sameLine := func(xy token.Posbool {
514                xp := prog.Fset.Position(x)
515                yp := prog.Fset.Position(y)
516                return xp.Filename == yp.Filename && xp.Line == yp.Line
517            }
518            expectations := make(map[*ssa.CallCommon]*expect.Note)
519            for call := range probes {
520                var match *expect.Note
521                for _note := range notes {
522                    if note.Name == "types" && sameLine(call.Pos(), note.Pos) {
523                        match = note // first match is good enough.
524                        break
525                    }
526                }
527                if match != nil {
528                    expectations[call] = match
529                } else {
530                    t.Errorf("Unmatched probe: %v"call)
531                }
532            }
533
534            // Check each expectation.
535            for callnote := range expectations {
536                var args []string
537                for _a := range call.Args {
538                    args = append(argsa.Type().String())
539                }
540                if gotwant := fmt.Sprint(args), fmt.Sprint(note.Args); got != want {
541                    t.Errorf("Arguments to print() were expected to be %q. got %q"wantgot)
542                }
543            }
544        })
545    }
546}
547
548// TestInstructionString tests serializing instructions via Instruction.String().
549func TestInstructionString(t *testing.T) {
550    if !typeparams.Enabled {
551        t.Skip("TestInstructionString requires type parameters")
552    }
553    // Tests (ssa.Instruction).String(). Instructions are from a single go file.
554    // The Instructions tested are those that match a comment of the form:
555    //
556    //    //@ instrs(f, kind, strs...)
557    //
558    // where f is the name of the function, kind is the type of the instructions matched
559    // within the function, and tests that the String() value for all of the instructions
560    // matched of String() is strs (in some order).
561    // See x/tools/go/expect for details on the syntax.
562
563    const contents = `
564    package p
565
566    //@ instrs("f", "*ssa.TypeAssert")
567    //@ instrs("f", "*ssa.Call", "print(nil:interface{}, 0:int)")
568    func f(x int) { // non-generic smoke test.
569        var i interface{}
570        print(i, 0)
571    }
572
573    //@ instrs("h", "*ssa.Alloc", "local T (u)")
574    //@ instrs("h", "*ssa.FieldAddr", "&t0.x [#0]")
575    func h[T ~struct{ x string }]() T {
576        u := T{"lorem"}
577        return u
578    }
579
580    //@ instrs("c", "*ssa.TypeAssert", "typeassert t0.(interface{})")
581    //@ instrs("c", "*ssa.Call", "invoke x.foo()")
582    func c[T interface{ foo() string }](x T) {
583        _ = x.foo
584        _ = x.foo()
585    }
586
587    //@ instrs("d", "*ssa.TypeAssert", "typeassert t0.(interface{})")
588    //@ instrs("d", "*ssa.Call", "invoke x.foo()")
589    func d[T interface{ foo() string; comparable }](x T) {
590        _ = x.foo
591        _ = x.foo()
592    }
593    `
594
595    // Parse
596    conf := loader.Config{ParserModeparser.ParseComments}
597    const fname = "p.go"
598    ferr := conf.ParseFile(fnamecontents)
599    if err != nil {
600        t.Fatalf("parse: %v"err)
601    }
602    conf.CreateFromFiles("p"f)
603
604    // Load
605    lprogerr := conf.Load()
606    if err != nil {
607        t.Fatalf("Load: %v"err)
608    }
609
610    // Create and build SSA
611    prog := ssa.NewProgram(lprog.Fsetssa.SanityCheckFunctions)
612    for _info := range lprog.AllPackages {
613        if info.TransitivelyErrorFree {
614            prog.CreatePackage(info.Pkginfo.Files, &info.Infoinfo.Importable)
615        }
616    }
617    p := prog.Package(lprog.Package("p").Pkg)
618    p.Build()
619
620    // Collect all notes in f, i.e. comments starting with "//@ instr".
621    noteserr := expect.ExtractGo(prog.Fsetf)
622    if err != nil {
623        t.Errorf("expect.ExtractGo: %v"err)
624    }
625
626    // Expectation is a {function, type string} -> {want, matches}
627    // where matches is all Instructions.String() that match the key.
628    // Each expecation is that some permutation of matches is wants.
629    type expKey struct {
630        function string
631        kind     string
632    }
633    type expValue struct {
634        wants   []string
635        matches []string
636    }
637    expectations := make(map[expKey]*expValue)
638    for _note := range notes {
639        if note.Name == "instrs" {
640            if len(note.Args) < 2 {
641                t.Error("Had @instrs annotation without at least 2 arguments")
642                continue
643            }
644            fnkind := fmt.Sprint(note.Args[0]), fmt.Sprint(note.Args[1])
645            var wants []string
646            for _arg := range note.Args[2:] {
647                wants = append(wantsfmt.Sprint(arg))
648            }
649            expectations[expKey{fnkind}] = &expValue{wantsnil}
650        }
651    }
652
653    // Collect all Instructions that match the expectations.
654    for _mem := range p.Members {
655        if fnok := mem.(*ssa.Function); ok {
656            for _bb := range fn.Blocks {
657                for _i := range bb.Instrs {
658                    kind := fmt.Sprintf("%T"i)
659                    if e := expectations[expKey{fn.Name(), kind}]; e != nil {
660                        e.matches = append(e.matchesi.String())
661                    }
662                }
663            }
664        }
665    }
666
667    // Check each expectation.
668    for keyvalue := range expectations {
669        if _ok := p.Members[key.function]; !ok {
670            t.Errorf("Expectation on %s does not match a member in %s"key.functionp.Pkg.Name())
671        }
672        gotwant := value.matchesvalue.wants
673        sort.Strings(got)
674        sort.Strings(want)
675        if !reflect.DeepEqual(wantgot) {
676            t.Errorf("Within %s wanted instructions of kind %s: %q. got %q"key.functionkey.kindwantgot)
677        }
678    }
679}
680
MembersX
TestGenericBodies.RangeStmt_1060.BlockStmt.BlockStmt.RangeStmt_10654.BlockStmt.BlockStmt.RangeStmt_10734.BlockStmt.RangeStmt_10771.BlockStmt.BlockStmt.call
TestGenericBodies.RangeStmt_1060.BlockStmt.BlockStmt.RangeStmt_11513.BlockStmt.RangeStmt_11571.note
TestInstructionString.t
TestInstructionString.contents
TestInstructionString.lprog
TestInstructionString.expKey.function
TestInstructionString.expectations
TestGenericBodies.RangeStmt_1060.BlockStmt.BlockStmt.f
TestGenericBodies.RangeStmt_1060.BlockStmt.BlockStmt.probes
TestInstructionString.conf
TestInstructionString.RangeStmt_15277.mem
TestGenericBodies.t
TestGenericBodies.RangeStmt_1060.test
TestGenericBodies.RangeStmt_1060.BlockStmt.BlockStmt.BlockStmt.yp
TestInstructionString.err
TestInstructionString.expValue
parser
ssa
TestGenericBodies.RangeStmt_1060.BlockStmt.BlockStmt.RangeStmt_10654.mem
TestInstructionString
TestInstructionString.expKey
TestInstructionString.expValue.wants
TestInstructionString.RangeStmt_14807.BlockStmt.BlockStmt.kind
sort
TestGenericBodies
TestGenericBodies.RangeStmt_1060.BlockStmt.BlockStmt.conf
TestGenericBodies.RangeStmt_1060.BlockStmt.BlockStmt.lprog
TestInstructionString.RangeStmt_14807.BlockStmt.BlockStmt.fn
TestGenericBodies.RangeStmt_1060.BlockStmt.BlockStmt.RangeStmt_11895.call
TestInstructionString.RangeStmt_14807.BlockStmt.BlockStmt.RangeStmt_15068.arg
TestInstructionString.RangeStmt_15618.value
TestInstructionString.RangeStmt_15618.key
reflect
TestGenericBodies.RangeStmt_1060.BlockStmt.BlockStmt.BlockStmt.xp
TestGenericBodies.RangeStmt_1060.BlockStmt.BlockStmt.expectations
TestInstructionString.RangeStmt_15277.BlockStmt.BlockStmt.RangeStmt_15353.bb
TestGenericBodies.RangeStmt_1060.BlockStmt.BlockStmt.RangeStmt_10654.BlockStmt.BlockStmt.RangeStmt_10734.bb
TestInstructionString.expKey.kind
TestInstructionString.RangeStmt_14807.BlockStmt.BlockStmt.wants
TestInstructionString.RangeStmt_15277.BlockStmt.BlockStmt.RangeStmt_15353.BlockStmt.RangeStmt_15388.i
TestInstructionString.RangeStmt_15618.BlockStmt.got
expect
TestGenericBodies.RangeStmt_1060.BlockStmt.BlockStmt.RangeStmt_10329.info
TestGenericBodies.RangeStmt_1060.BlockStmt.BlockStmt.RangeStmt_10654.BlockStmt.BlockStmt.RangeStmt_10734.BlockStmt.RangeStmt_10771.i
TestGenericBodies.RangeStmt_1060.BlockStmt.BlockStmt.RangeStmt_11895.BlockStmt.args
TestGenericBodies.RangeStmt_1060.BlockStmt.BlockStmt.RangeStmt_11895.BlockStmt.want
TestInstructionString.p
TestInstructionString.RangeStmt_15618.BlockStmt.want
TestGenericBodies.RangeStmt_1060.BlockStmt.BlockStmt.RangeStmt_11513.BlockStmt.match
TestGenericBodies.RangeStmt_1060.BlockStmt.BlockStmt.RangeStmt_11895.BlockStmt.RangeStmt_11960.a
TestInstructionString.prog
TestInstructionString.RangeStmt_14053.info
TestInstructionString.RangeStmt_15277.BlockStmt.BlockStmt.RangeStmt_15353.BlockStmt.RangeStmt_15388.BlockStmt.kind
loader
TestGenericBodies.RangeStmt_1060.BlockStmt.test
TestGenericBodies.RangeStmt_1060.BlockStmt.BlockStmt.notes
TestGenericBodies.RangeStmt_1060.BlockStmt.BlockStmt.RangeStmt_11895.note
TestGenericBodies.RangeStmt_1060.BlockStmt.BlockStmt.RangeStmt_11895.BlockStmt.got
TestInstructionString.expValue.matches
TestGenericBodies.RangeStmt_1060.BlockStmt.BlockStmt.p
TestInstructionString.fname
TestInstructionString.f
TestInstructionString.RangeStmt_14807.note
testing
TestGenericBodies.RangeStmt_1060.BlockStmt.BlockStmt.err
TestGenericBodies.RangeStmt_1060.BlockStmt.BlockStmt.prog
TestGenericBodies.RangeStmt_1060.BlockStmt.BlockStmt.RangeStmt_11513.call
TestInstructionString.notes
Members
X