GoPLS Viewer

Home|gopls/go/ssa/func.go
1// Copyright 2013 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
6
7// This file implements the Function type.
8
9import (
10    "bytes"
11    "fmt"
12    "go/ast"
13    "go/token"
14    "go/types"
15    "io"
16    "os"
17    "strings"
18
19    "golang.org/x/tools/internal/typeparams"
20)
21
22// Like ObjectOf, but panics instead of returning nil.
23// Only valid during f's create and build phases.
24func (f *FunctionobjectOf(id *ast.Identtypes.Object {
25    if o := f.info.ObjectOf(id); o != nil {
26        return o
27    }
28    panic(fmt.Sprintf("no types.Object for ast.Ident %s @ %s",
29        id.Namef.Prog.Fset.Position(id.Pos())))
30}
31
32// Like TypeOf, but panics instead of returning nil.
33// Only valid during f's create and build phases.
34func (f *FunctiontypeOf(e ast.Exprtypes.Type {
35    if T := f.info.TypeOf(e); T != nil {
36        return f.typ(T)
37    }
38    panic(fmt.Sprintf("no type for %T @ %s"ef.Prog.Fset.Position(e.Pos())))
39}
40
41// typ is the locally instantiated type of T. T==typ(T) if f is not an instantiation.
42func (f *Functiontyp(T types.Typetypes.Type {
43    return f.subst.typ(T)
44}
45
46// If id is an Instance, returns info.Instances[id].Type.
47// Otherwise returns f.typeOf(id).
48func (f *FunctioninstanceType(id *ast.Identtypes.Type {
49    if tok := typeparams.GetInstances(f.info)[id]; ok {
50        return t.Type
51    }
52    return f.typeOf(id)
53}
54
55// selection returns a *selection corresponding to f.info.Selections[selector]
56// with potential updates for type substitution.
57func (f *Functionselection(selector *ast.SelectorExpr) *selection {
58    sel := f.info.Selections[selector]
59    if sel == nil {
60        return nil
61    }
62
63    switch sel.Kind() {
64    case types.MethodExprtypes.MethodVal:
65        if recv := f.typ(sel.Recv()); recv != sel.Recv() {
66            // recv changed during type substitution.
67            pkg := f.declaredPackage().Pkg
68            objindexindirect := types.LookupFieldOrMethod(recvtruepkgsel.Obj().Name())
69
70            // sig replaces sel.Type(). See (types.Selection).Typ() for details.
71            sig := obj.Type().(*types.Signature)
72            sig = changeRecv(signewVar(sig.Recv().Name(), recv))
73            if sel.Kind() == types.MethodExpr {
74                sig = recvAsFirstArg(sig)
75            }
76            return &selection{
77                kind:     sel.Kind(),
78                recv:     recv,
79                typ:      sig,
80                obj:      obj,
81                index:    index,
82                indirectindirect,
83            }
84        }
85    }
86    return toSelection(sel)
87}
88
89// Destinations associated with unlabelled for/switch/select stmts.
90// We push/pop one of these as we enter/leave each construct and for
91// each BranchStmt we scan for the innermost target of the right type.
92type targets struct {
93    tail         *targets // rest of stack
94    _break       *BasicBlock
95    _continue    *BasicBlock
96    _fallthrough *BasicBlock
97}
98
99// Destinations associated with a labelled block.
100// We populate these as labels are encountered in forward gotos or
101// labelled statements.
102type lblock struct {
103    _goto     *BasicBlock
104    _break    *BasicBlock
105    _continue *BasicBlock
106}
107
108// labelledBlock returns the branch target associated with the
109// specified label, creating it if needed.
110func (f *FunctionlabelledBlock(label *ast.Ident) *lblock {
111    obj := f.objectOf(label)
112    lb := f.lblocks[obj]
113    if lb == nil {
114        lb = &lblock{_gotof.newBasicBlock(label.Name)}
115        if f.lblocks == nil {
116            f.lblocks = make(map[types.Object]*lblock)
117        }
118        f.lblocks[obj] = lb
119    }
120    return lb
121}
122
123// addParam adds a (non-escaping) parameter to f.Params of the
124// specified name, type and source position.
125func (f *FunctionaddParam(name stringtyp types.Typepos token.Pos) *Parameter {
126    v := &Parameter{
127        name:   name,
128        typ:    typ,
129        pos:    pos,
130        parentf,
131    }
132    f.Params = append(f.Paramsv)
133    return v
134}
135
136func (f *FunctionaddParamObj(obj types.Object) *Parameter {
137    name := obj.Name()
138    if name == "" {
139        name = fmt.Sprintf("arg%d"len(f.Params))
140    }
141    param := f.addParam(namef.typ(obj.Type()), obj.Pos())
142    param.object = obj
143    return param
144}
145
146// addSpilledParam declares a parameter that is pre-spilled to the
147// stack; the function body will load/store the spilled location.
148// Subsequent lifting will eliminate spills where possible.
149func (f *FunctionaddSpilledParam(obj types.Object) {
150    param := f.addParamObj(obj)
151    spill := &Alloc{Commentobj.Name()}
152    spill.setType(types.NewPointer(param.Type()))
153    spill.setPos(obj.Pos())
154    f.objects[obj] = spill
155    f.Locals = append(f.Localsspill)
156    f.emit(spill)
157    f.emit(&Store{AddrspillValparam})
158}
159
160// startBody initializes the function prior to generating SSA code for its body.
161// Precondition: f.Type() already set.
162func (f *FunctionstartBody() {
163    f.currentBlock = f.newBasicBlock("entry")
164    f.objects = make(map[types.Object]Value// needed for some synthetics, e.g. init
165}
166
167// createSyntacticParams populates f.Params and generates code (spills
168// and named result locals) for all the parameters declared in the
169// syntax.  In addition it populates the f.objects mapping.
170//
171// Preconditions:
172// f.startBody() was called. f.info != nil.
173// Postcondition:
174// len(f.Params) == len(f.Signature.Params) + (f.Signature.Recv() ? 1 : 0)
175func (f *FunctioncreateSyntacticParams(recv *ast.FieldListfunctype *ast.FuncType) {
176    // Receiver (at most one inner iteration).
177    if recv != nil {
178        for _field := range recv.List {
179            for _n := range field.Names {
180                f.addSpilledParam(f.info.Defs[n])
181            }
182            // Anonymous receiver?  No need to spill.
183            if field.Names == nil {
184                f.addParamObj(f.Signature.Recv())
185            }
186        }
187    }
188
189    // Parameters.
190    if functype.Params != nil {
191        n := len(f.Params// 1 if has recv, 0 otherwise
192        for _field := range functype.Params.List {
193            for _n := range field.Names {
194                f.addSpilledParam(f.info.Defs[n])
195            }
196            // Anonymous parameter?  No need to spill.
197            if field.Names == nil {
198                f.addParamObj(f.Signature.Params().At(len(f.Params) - n))
199            }
200        }
201    }
202
203    // Named results.
204    if functype.Results != nil {
205        for _field := range functype.Results.List {
206            // Implicit "var" decl of locals for named results.
207            for _n := range field.Names {
208                f.namedResults = append(f.namedResultsf.addLocalForIdent(n))
209            }
210        }
211    }
212}
213
214type setNumable interface {
215    setNum(int)
216}
217
218// numberRegisters assigns numbers to all SSA registers
219// (value-defining Instructions) in f, to aid debugging.
220// (Non-Instruction Values are named at construction.)
221func numberRegisters(f *Function) {
222    v := 0
223    for _b := range f.Blocks {
224        for _instr := range b.Instrs {
225            switch instr.(type) {
226            case Value:
227                instr.(setNumable).setNum(v)
228                v++
229            }
230        }
231    }
232}
233
234// buildReferrers populates the def/use information in all non-nil
235// Value.Referrers slice.
236// Precondition: all such slices are initially empty.
237func buildReferrers(f *Function) {
238    var rands []*Value
239    for _b := range f.Blocks {
240        for _instr := range b.Instrs {
241            rands = instr.Operands(rands[:0]) // recycle storage
242            for _rand := range rands {
243                if r := *randr != nil {
244                    if ref := r.Referrers(); ref != nil {
245                        *ref = append(*refinstr)
246                    }
247                }
248            }
249        }
250    }
251}
252
253// mayNeedRuntimeTypes returns all of the types in the body of fn that might need runtime types.
254//
255// EXCLUSIVE_LOCKS_ACQUIRED(meth.Prog.methodsMu)
256func mayNeedRuntimeTypes(fn *Function) []types.Type {
257    // Collect all types that may need rtypes, i.e. those that flow into an interface.
258    var ts []types.Type
259    for _bb := range fn.Blocks {
260        for _instr := range bb.Instrs {
261            if miok := instr.(*MakeInterface); ok {
262                ts = append(tsmi.X.Type())
263            }
264        }
265    }
266
267    // Types that contain a parameterized type are considered to not be runtime types.
268    if fn.typeparams.Len() == 0 {
269        return ts // No potentially parameterized types.
270    }
271    // Filter parameterized types, in place.
272    fn.Prog.methodsMu.Lock()
273    defer fn.Prog.methodsMu.Unlock()
274    filtered := ts[:0]
275    for _t := range ts {
276        if !fn.Prog.parameterized.isParameterized(t) {
277            filtered = append(filteredt)
278        }
279    }
280    return filtered
281}
282
283// finishBody() finalizes the contents of the function after SSA code generation of its body.
284//
285// The function is not done being built until done() is called.
286func (f *FunctionfinishBody() {
287    f.objects = nil
288    f.currentBlock = nil
289    f.lblocks = nil
290
291    // Don't pin the AST in memory (except in debug mode).
292    if n := f.syntaxn != nil && !f.debugInfo() {
293        f.syntax = extentNode{n.Pos(), n.End()}
294    }
295
296    // Remove from f.Locals any Allocs that escape to the heap.
297    j := 0
298    for _l := range f.Locals {
299        if !l.Heap {
300            f.Locals[j] = l
301            j++
302        }
303    }
304    // Nil out f.Locals[j:] to aid GC.
305    for i := ji < len(f.Locals); i++ {
306        f.Locals[i] = nil
307    }
308    f.Locals = f.Locals[:j]
309
310    optimizeBlocks(f)
311
312    buildReferrers(f)
313
314    buildDomTree(f)
315
316    if f.Prog.mode&NaiveForm == 0 {
317        // For debugging pre-state of lifting pass:
318        // numberRegisters(f)
319        // f.WriteTo(os.Stderr)
320        lift(f)
321    }
322
323    // clear remaining stateful variables
324    f.namedResults = nil // (used by lifting)
325    f.info = nil
326    f.subst = nil
327
328    numberRegisters(f// uses f.namedRegisters
329}
330
331// After this, function is done with BUILD phase.
332func (f *Functiondone() {
333    assert(f.parent == nil"done called on an anonymous function")
334
335    var visit func(*Function)
336    visit = func(f *Function) {
337        for _anon := range f.AnonFuncs {
338            visit(anon// anon is done building before f.
339        }
340
341        f.built = true // function is done with BUILD phase
342
343        if f.Prog.mode&PrintFunctions != 0 {
344            printMu.Lock()
345            f.WriteTo(os.Stdout)
346            printMu.Unlock()
347        }
348
349        if f.Prog.mode&SanityCheckFunctions != 0 {
350            mustSanityCheck(fnil)
351        }
352    }
353    visit(f)
354}
355
356// removeNilBlocks eliminates nils from f.Blocks and updates each
357// BasicBlock.Index.  Use this after any pass that may delete blocks.
358func (f *FunctionremoveNilBlocks() {
359    j := 0
360    for _b := range f.Blocks {
361        if b != nil {
362            b.Index = j
363            f.Blocks[j] = b
364            j++
365        }
366    }
367    // Nil out f.Blocks[j:] to aid GC.
368    for i := ji < len(f.Blocks); i++ {
369        f.Blocks[i] = nil
370    }
371    f.Blocks = f.Blocks[:j]
372}
373
374// SetDebugMode sets the debug mode for package pkg.  If true, all its
375// functions will include full debug info.  This greatly increases the
376// size of the instruction stream, and causes Functions to depend upon
377// the ASTs, potentially keeping them live in memory for longer.
378func (pkg *PackageSetDebugMode(debug bool) {
379    // TODO(adonovan): do we want ast.File granularity?
380    pkg.debug = debug
381}
382
383// debugInfo reports whether debug info is wanted for this function.
384func (f *FunctiondebugInfo() bool {
385    return f.Pkg != nil && f.Pkg.debug
386}
387
388// addNamedLocal creates a local variable, adds it to function f and
389// returns it.  Its name and type are taken from obj.  Subsequent
390// calls to f.lookup(obj) will return the same local.
391func (f *FunctionaddNamedLocal(obj types.Object) *Alloc {
392    l := f.addLocal(obj.Type(), obj.Pos())
393    l.Comment = obj.Name()
394    f.objects[obj] = l
395    return l
396}
397
398func (f *FunctionaddLocalForIdent(id *ast.Ident) *Alloc {
399    return f.addNamedLocal(f.info.Defs[id])
400}
401
402// addLocal creates an anonymous local variable of type typ, adds it
403// to function f and returns it.  pos is the optional source location.
404func (f *FunctionaddLocal(typ types.Typepos token.Pos) *Alloc {
405    typ = f.typ(typ)
406    v := &Alloc{}
407    v.setType(types.NewPointer(typ))
408    v.setPos(pos)
409    f.Locals = append(f.Localsv)
410    f.emit(v)
411    return v
412}
413
414// lookup returns the address of the named variable identified by obj
415// that is local to function f or one of its enclosing functions.
416// If escaping, the reference comes from a potentially escaping pointer
417// expression and the referent must be heap-allocated.
418func (f *Functionlookup(obj types.Objectescaping boolValue {
419    if vok := f.objects[obj]; ok {
420        if allocok := v.(*Alloc); ok && escaping {
421            alloc.Heap = true
422        }
423        return v // function-local var (address)
424    }
425
426    // Definition must be in an enclosing function;
427    // plumb it through intervening closures.
428    if f.parent == nil {
429        panic("no ssa.Value for " + obj.String())
430    }
431    outer := f.parent.lookup(objtrue// escaping
432    v := &FreeVar{
433        name:   obj.Name(),
434        typ:    outer.Type(),
435        pos:    outer.Pos(),
436        outer:  outer,
437        parentf,
438    }
439    f.objects[obj] = v
440    f.FreeVars = append(f.FreeVarsv)
441    return v
442}
443
444// emit emits the specified instruction to function f.
445func (f *Functionemit(instr InstructionValue {
446    return f.currentBlock.emit(instr)
447}
448
449// RelString returns the full name of this function, qualified by
450// package name, receiver type, etc.
451//
452// The specific formatting rules are not guaranteed and may change.
453//
454// Examples:
455//
456//    "math.IsNaN"                  // a package-level function
457//    "(*bytes.Buffer).Bytes"       // a declared method or a wrapper
458//    "(*bytes.Buffer).Bytes$thunk" // thunk (func wrapping method; receiver is param 0)
459//    "(*bytes.Buffer).Bytes$bound" // bound (func wrapping method; receiver supplied by closure)
460//    "main.main$1"                 // an anonymous function in main
461//    "main.init#1"                 // a declared init function
462//    "main.init"                   // the synthesized package initializer
463//
464// When these functions are referred to from within the same package
465// (i.e. from == f.Pkg.Object), they are rendered without the package path.
466// For example: "IsNaN", "(*Buffer).Bytes", etc.
467//
468// All non-synthetic functions have distinct package-qualified names.
469// (But two methods may have the same name "(T).f" if one is a synthetic
470// wrapper promoting a non-exported method "f" from another package; in
471// that case, the strings are equal but the identifiers "f" are distinct.)
472func (f *FunctionRelString(from *types.Packagestring {
473    // Anonymous?
474    if f.parent != nil {
475        // An anonymous function's Name() looks like "parentName$1",
476        // but its String() should include the type/package/etc.
477        parent := f.parent.RelString(from)
478        for ianon := range f.parent.AnonFuncs {
479            if anon == f {
480                return fmt.Sprintf("%s$%d"parent1+i)
481            }
482        }
483
484        return f.name // should never happen
485    }
486
487    // Method (declared or wrapper)?
488    if recv := f.Signature.Recv(); recv != nil {
489        return f.relMethod(fromrecv.Type())
490    }
491
492    // Thunk?
493    if f.method != nil {
494        return f.relMethod(fromf.method.recv)
495    }
496
497    // Bound?
498    if len(f.FreeVars) == 1 && strings.HasSuffix(f.name"$bound") {
499        return f.relMethod(fromf.FreeVars[0].Type())
500    }
501
502    // Package-level function?
503    // Prefix with package name for cross-package references only.
504    if p := f.relPkg(); p != nil && p != from {
505        return fmt.Sprintf("%s.%s"p.Path(), f.name)
506    }
507
508    // Unknown.
509    return f.name
510}
511
512func (f *FunctionrelMethod(from *types.Packagerecv types.Typestring {
513    return fmt.Sprintf("(%s).%s"relType(recvfrom), f.name)
514}
515
516// writeSignature writes to buf the signature sig in declaration syntax.
517func writeSignature(buf *bytes.Bufferfrom *types.Packagename stringsig *types.Signatureparams []*Parameter) {
518    buf.WriteString("func ")
519    if recv := sig.Recv(); recv != nil {
520        buf.WriteString("(")
521        if n := params[0].Name(); n != "" {
522            buf.WriteString(n)
523            buf.WriteString(" ")
524        }
525        types.WriteType(bufparams[0].Type(), types.RelativeTo(from))
526        buf.WriteString(") ")
527    }
528    buf.WriteString(name)
529    types.WriteSignature(bufsigtypes.RelativeTo(from))
530}
531
532// declaredPackage returns the package fn is declared in or nil if the
533// function is not declared in a package.
534func (fn *FunctiondeclaredPackage() *Package {
535    switch {
536    case fn.Pkg != nil:
537        return fn.Pkg // non-generic function
538    case fn.topLevelOrigin != nil:
539        return fn.topLevelOrigin.Pkg // instance of a named generic function
540    case fn.parent != nil:
541        return fn.parent.declaredPackage() // instance of an anonymous [generic] function
542    default:
543        return nil // function is not declared in a package, e.g. a wrapper.
544    }
545}
546
547// relPkg returns types.Package fn is printed in relationship to.
548func (fn *FunctionrelPkg() *types.Package {
549    if p := fn.declaredPackage(); p != nil {
550        return p.Pkg
551    }
552    return nil
553}
554
555var _ io.WriterTo = (*Function)(nil// *Function implements io.Writer
556
557func (f *FunctionWriteTo(w io.Writer) (int64error) {
558    var buf bytes.Buffer
559    WriteFunction(&buff)
560    nerr := w.Write(buf.Bytes())
561    return int64(n), err
562}
563
564// WriteFunction writes to buf a human-readable "disassembly" of f.
565func WriteFunction(buf *bytes.Bufferf *Function) {
566    fmt.Fprintf(buf"# Name: %s\n"f.String())
567    if f.Pkg != nil {
568        fmt.Fprintf(buf"# Package: %s\n"f.Pkg.Pkg.Path())
569    }
570    if syn := f.Syntheticsyn != "" {
571        fmt.Fprintln(buf"# Synthetic:"syn)
572    }
573    if pos := f.Pos(); pos.IsValid() {
574        fmt.Fprintf(buf"# Location: %s\n"f.Prog.Fset.Position(pos))
575    }
576
577    if f.parent != nil {
578        fmt.Fprintf(buf"# Parent: %s\n"f.parent.Name())
579    }
580
581    if f.Recover != nil {
582        fmt.Fprintf(buf"# Recover: %s\n"f.Recover)
583    }
584
585    from := f.relPkg()
586
587    if f.FreeVars != nil {
588        buf.WriteString("# Free variables:\n")
589        for ifv := range f.FreeVars {
590            fmt.Fprintf(buf"# % 3d:\t%s %s\n"ifv.Name(), relType(fv.Type(), from))
591        }
592    }
593
594    if len(f.Locals) > 0 {
595        buf.WriteString("# Locals:\n")
596        for il := range f.Locals {
597            fmt.Fprintf(buf"# % 3d:\t%s %s\n"il.Name(), relType(deref(l.Type()), from))
598        }
599    }
600    writeSignature(buffromf.Name(), f.Signaturef.Params)
601    buf.WriteString(":\n")
602
603    if f.Blocks == nil {
604        buf.WriteString("\t(external)\n")
605    }
606
607    // NB. column calculations are confused by non-ASCII
608    // characters and assume 8-space tabs.
609    const punchcard = 80 // for old time's sake.
610    const tabwidth = 8
611    for _b := range f.Blocks {
612        if b == nil {
613            // Corrupt CFG.
614            fmt.Fprintf(buf".nil:\n")
615            continue
616        }
617        n_ := fmt.Fprintf(buf"%d:"b.Index)
618        bmsg := fmt.Sprintf("%s P:%d S:%d"b.Commentlen(b.Preds), len(b.Succs))
619        fmt.Fprintf(buf"%*s%s\n"punchcard-1-n-len(bmsg), ""bmsg)
620
621        if false { // CFG debugging
622            fmt.Fprintf(buf"\t# CFG: %s --> %s --> %s\n"b.Predsbb.Succs)
623        }
624        for _instr := range b.Instrs {
625            buf.WriteString("\t")
626            switch v := instr.(type) {
627            case Value:
628                l := punchcard - tabwidth
629                // Left-align the instruction.
630                if name := v.Name(); name != "" {
631                    n_ := fmt.Fprintf(buf"%s = "name)
632                    l -= n
633                }
634                n_ := buf.WriteString(instr.String())
635                l -= n
636                // Right-align the type if there's space.
637                if t := v.Type(); t != nil {
638                    buf.WriteByte(' ')
639                    ts := relType(tfrom)
640                    l -= len(ts) + len("  "// (spaces before and after type)
641                    if l > 0 {
642                        fmt.Fprintf(buf"%*s"l"")
643                    }
644                    buf.WriteString(ts)
645                }
646            case nil:
647                // Be robust against bad transforms.
648                buf.WriteString("<deleted>")
649            default:
650                buf.WriteString(instr.String())
651            }
652            buf.WriteString("\n")
653        }
654    }
655    fmt.Fprintf(buf"\n")
656}
657
658// newBasicBlock adds to f a new basic block and returns it.  It does
659// not automatically become the current block for subsequent calls to emit.
660// comment is an optional string for more readable debugging output.
661func (f *FunctionnewBasicBlock(comment string) *BasicBlock {
662    b := &BasicBlock{
663        Index:   len(f.Blocks),
664        Commentcomment,
665        parent:  f,
666    }
667    b.Succs = b.succs2[:0]
668    f.Blocks = append(f.Blocksb)
669    return b
670}
671
672// NewFunction returns a new synthetic Function instance belonging to
673// prog, with its name and signature fields set as specified.
674//
675// The caller is responsible for initializing the remaining fields of
676// the function object, e.g. Pkg, Params, Blocks.
677//
678// It is practically impossible for clients to construct well-formed
679// SSA functions/packages/programs directly, so we assume this is the
680// job of the Builder alone.  NewFunction exists to provide clients a
681// little flexibility.  For example, analysis tools may wish to
682// construct fake Functions for the root of the callgraph, a fake
683// "reflect" package, etc.
684//
685// TODO(adonovan): think harder about the API here.
686func (prog *ProgramNewFunction(name stringsig *types.Signatureprovenance string) *Function {
687    return &Function{ProgprognamenameSignaturesigSyntheticprovenance}
688}
689
690type extentNode [2]token.Pos
691
692func (n extentNodePos() token.Pos { return n[0] }
693func (n extentNodeEnd() token.Pos { return n[1] }
694
695// Syntax returns an ast.Node whose Pos/End methods provide the
696// lexical extent of the function if it was defined by Go source code
697// (f.Synthetic==""), or nil otherwise.
698//
699// If f was built with debug information (see Package.SetDebugRef),
700// the result is the *ast.FuncDecl or *ast.FuncLit that declared the
701// function.  Otherwise, it is an opaque Node providing only position
702// information; this avoids pinning the AST in memory.
703func (f *FunctionSyntax() ast.Node { return f.syntax }
704
MembersX
Function.addLocalForIdent.f
WriteFunction.BlockStmt.RangeStmt_16678.i
Function.objectOf
Function.objectOf.id
Function.objectOf.o
Function.typeOf.T
buildReferrers.RangeStmt_6691.BlockStmt.RangeStmt_6722.BlockStmt.RangeStmt_6814.rand
mayNeedRuntimeTypes
WriteFunction.tabwidth
WriteFunction.syn
Function.newBasicBlock.f
Function.removeNilBlocks.j
Function.debugInfo
Function.addLocal
Function.lookup.f
Function.emit
writeSignature.from
extentNode.Pos.n
Function.selection
lblock
Function.addParam.pos
WriteFunction.RangeStmt_17286.BlockStmt.RangeStmt_17691.BlockStmt.BlockStmt.t
Function.Syntax.f
Function.addParamObj.obj
Function.createSyntacticParams.BlockStmt.n
Function.addNamedLocal.obj
Function.addNamedLocal.l
Function.WriteTo.n
extentNode.End.n
writeSignature.buf
Function.WriteTo.buf
Function.instanceType.f
Function.selection.BlockStmt.BlockStmt.indirect
mayNeedRuntimeTypes.ts
Function.removeNilBlocks.f
Function.RelString.p
Function.relMethod.recv
mayNeedRuntimeTypes.fn
WriteFunction.from
WriteFunction.punchcard
Function.newBasicBlock.b
extentNode.Pos
Function.selection.BlockStmt.BlockStmt.pkg
lblock._goto
Function.done
Function.removeNilBlocks
Function.addLocal.v
Function.RelString
Function.typeOf
targets.tail
Function.addParam.v
Function.addSpilledParam
Function.WriteTo
Function.newBasicBlock
Function.removeNilBlocks.RangeStmt_9631.b
Function.lookup.obj
Function.typeOf.f
Function.addParam
Function.addParamObj.param
Function.createSyntacticParams.BlockStmt.RangeStmt_5531.BlockStmt.RangeStmt_5579.n
mayNeedRuntimeTypes.RangeStmt_7286.BlockStmt.RangeStmt_7319.instr
Function.finishBody.i
Function.declaredPackage
Function.addNamedLocal
Function.WriteTo.w
Program.NewFunction
WriteFunction.RangeStmt_17286.BlockStmt.RangeStmt_17691.BlockStmt.BlockStmt.BlockStmt.ts
Function.labelledBlock.obj
Function.addParam.typ
Function.addSpilledParam.param
Function.finishBody.RangeStmt_8341.l
Function.relMethod.f
WriteFunction.RangeStmt_17286.BlockStmt.bmsg
Function.finishBody.n
Function.addLocal.typ
Function.RelString.from
WriteFunction.f
WriteFunction.RangeStmt_17286.BlockStmt.RangeStmt_17691.BlockStmt.BlockStmt._
Function.addSpilledParam.obj
Function.RelString.BlockStmt.parent
writeSignature.params
Function.lookup
Function.WriteTo.f
Function.relPkg
WriteFunction.RangeStmt_17286.b
Function.typ
Function.selection.BlockStmt.recv
Function.addParamObj.name
numberRegisters.v
numberRegisters.RangeStmt_6328.b
Function.finishBody
writeSignature.name
Function.selection.BlockStmt.BlockStmt.obj
targets._fallthrough
buildReferrers.RangeStmt_6691.BlockStmt.RangeStmt_6722.BlockStmt.RangeStmt_6814.BlockStmt.BlockStmt.ref
Package.SetDebugMode
Function.addLocalForIdent.id
Function.lookup.outer
Function.RelString.BlockStmt.RangeStmt_13663.i
Function.WriteTo.err
lblock._break
Function.addParamObj.f
Function.addSpilledParam.f
Function.done.BlockStmt.RangeStmt_9104.anon
Function.addLocal.pos
Function.lookup.escaping
WriteFunction.BlockStmt.RangeStmt_16857.l
Program.NewFunction.name
WriteFunction.RangeStmt_17286.BlockStmt.RangeStmt_17691.BlockStmt.BlockStmt.BlockStmt.n
Function.labelledBlock
Function.createSyntacticParams.BlockStmt.RangeStmt_5198.BlockStmt.RangeStmt_5235.n
Function.createSyntacticParams.BlockStmt.RangeStmt_5531.field
mayNeedRuntimeTypes.RangeStmt_7286.bb
Package.SetDebugMode.debug
Function.addLocal.f
Function.typ.f
numberRegisters.RangeStmt_6328.BlockStmt.RangeStmt_6359.instr
Package.SetDebugMode.pkg
WriteFunction.RangeStmt_17286.BlockStmt.RangeStmt_17691.BlockStmt.BlockStmt.n
Function.Syntax
io
Function.selection.BlockStmt.BlockStmt.index
Function.createSyntacticParams.BlockStmt.RangeStmt_5853.field
writeSignature.recv
WriteFunction.RangeStmt_17286.BlockStmt.RangeStmt_17691.instr
WriteFunction.RangeStmt_17286.BlockStmt.RangeStmt_17691.BlockStmt.BlockStmt.BlockStmt._
Program.NewFunction.prog
Program.NewFunction.sig
Function.typeOf.e
Function.labelledBlock.f
Function.addParam.f
Function.emit.instr
WriteFunction.buf
WriteFunction.RangeStmt_17286.BlockStmt._
WriteFunction.RangeStmt_17286.BlockStmt.n
Function.instanceType.id
targets._break
Function.createSyntacticParams.recv
buildReferrers.f
mayNeedRuntimeTypes.RangeStmt_7736.t
Function.debugInfo.f
Function.objectOf.f
Function.startBody.f
numberRegisters
buildReferrers.RangeStmt_6691.b
Function.RelString.f
Function.RelString.recv
Function.typ.T
setNumable
numberRegisters.f
writeSignature
WriteFunction.BlockStmt.RangeStmt_16678.fv
Function.newBasicBlock.comment
Function.labelledBlock.label
Function.createSyntacticParams
buildReferrers
Function.finishBody.j
Function.RelString.BlockStmt.RangeStmt_13663.anon
Program.NewFunction.provenance
Function.startBody
Function.createSyntacticParams.functype
writeSignature.sig
Function.relPkg.fn
extentNode
Function.lookup.v
writeSignature.BlockStmt.n
WriteFunction
Function.addNamedLocal.f
Function.relMethod.from
Function.selection.f
targets
Function.createSyntacticParams.BlockStmt.RangeStmt_5853.BlockStmt.RangeStmt_5957.n
buildReferrers.rands
buildReferrers.RangeStmt_6691.BlockStmt.RangeStmt_6722.BlockStmt.RangeStmt_6814.BlockStmt.r
Function.done.f
WriteFunction.BlockStmt.RangeStmt_16857.i
WriteFunction.RangeStmt_17286.BlockStmt.RangeStmt_17691.BlockStmt.BlockStmt.name
Function.instanceType
Function.addParam.name
Function.addParamObj
Function.declaredPackage.fn
Function.relPkg.p
WriteFunction.pos
Function.removeNilBlocks.i
Function.addLocalForIdent
Function.selection.selector
lblock._continue
Function.addSpilledParam.spill
Function.createSyntacticParams.f
Function.createSyntacticParams.BlockStmt.RangeStmt_5198.field
buildReferrers.RangeStmt_6691.BlockStmt.RangeStmt_6722.instr
Function.emit.f
extentNode.End
targets._continue
Function.finishBody.f
Function.relMethod
Members
X