1// Copyright 2009 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 typecheck 6 7import ( 8 "cmd/compile/internal/base" 9 "cmd/compile/internal/ir" 10 "cmd/compile/internal/types" 11 "cmd/internal/obj" 12) 13 14// LookupRuntime returns a function or variable declared in 15// _builtin/runtime.go. If types_ is non-empty, successive occurrences 16// of the "any" placeholder type will be substituted. 17func LookupRuntime(name string, types_ ...*types.Type) *ir.Name { 18 s := ir.Pkgs.Runtime.Lookup(name) 19 if s == nil || s.Def == nil { 20 base.Fatalf("LookupRuntime: can't find runtime.%s", name) 21 } 22 n := s.Def.(*ir.Name) 23 if len(types_) != 0 { 24 n = substArgTypes(n, types_...) 25 } 26 return n 27} 28 29// SubstArgTypes substitutes the given list of types for 30// successive occurrences of the "any" placeholder in the 31// type syntax expression n.Type. 32func substArgTypes(old *ir.Name, types_ ...*types.Type) *ir.Name { 33 for _, t := range types_ { 34 types.CalcSize(t) 35 } 36 n := ir.NewNameAt(old.Pos(), old.Sym(), types.SubstAny(old.Type(), &types_)) 37 n.Class = old.Class 38 n.Func = old.Func 39 if len(types_) > 0 { 40 base.Fatalf("SubstArgTypes: too many argument types") 41 } 42 return n 43} 44 45// AutoLabel generates a new Name node for use with 46// an automatically generated label. 47// prefix is a short mnemonic (e.g. ".s" for switch) 48// to help with debugging. 49// It should begin with "." to avoid conflicts with 50// user labels. 51func AutoLabel(prefix string) *types.Sym { 52 if prefix[0] != '.' { 53 base.Fatalf("autolabel prefix must start with '.', have %q", prefix) 54 } 55 fn := ir.CurFunc 56 if ir.CurFunc == nil { 57 base.Fatalf("autolabel outside function") 58 } 59 n := fn.Label 60 fn.Label++ 61 return LookupNum(prefix, int(n)) 62} 63 64func Lookup(name string) *types.Sym { 65 return types.LocalPkg.Lookup(name) 66} 67 68// InitRuntime loads the definitions for the low-level runtime functions, 69// so that the compiler can generate calls to them, 70// but does not make them visible to user code. 71func InitRuntime() { 72 base.Timer.Start("fe", "loadsys") 73 74 typs := runtimeTypes() 75 for _, d := range &runtimeDecls { 76 sym := ir.Pkgs.Runtime.Lookup(d.name) 77 typ := typs[d.typ] 78 switch d.tag { 79 case funcTag: 80 importfunc(sym, typ) 81 case varTag: 82 importvar(sym, typ) 83 default: 84 base.Fatalf("unhandled declaration tag %v", d.tag) 85 } 86 } 87} 88 89// LookupRuntimeFunc looks up Go function name in package runtime. This function 90// must follow the internal calling convention. 91func LookupRuntimeFunc(name string) *obj.LSym { 92 return LookupRuntimeABI(name, obj.ABIInternal) 93} 94 95// LookupRuntimeVar looks up a variable (or assembly function) name in package 96// runtime. If this is a function, it may have a special calling 97// convention. 98func LookupRuntimeVar(name string) *obj.LSym { 99 return LookupRuntimeABI(name, obj.ABI0) 100} 101 102// LookupRuntimeABI looks up a name in package runtime using the given ABI. 103func LookupRuntimeABI(name string, abi obj.ABI) *obj.LSym { 104 return base.PkgLinksym("runtime", name, abi) 105} 106 107// InitCoverage loads the definitions for routines called 108// by code coverage instrumentation (similar to InitRuntime above). 109func InitCoverage() { 110 typs := coverageTypes() 111 for _, d := range &coverageDecls { 112 sym := ir.Pkgs.Coverage.Lookup(d.name) 113 typ := typs[d.typ] 114 switch d.tag { 115 case funcTag: 116 importfunc(sym, typ) 117 case varTag: 118 importvar(sym, typ) 119 default: 120 base.Fatalf("unhandled declaration tag %v", d.tag) 121 } 122 } 123} 124 125// LookupCoverage looks up the Go function 'name' in package 126// runtime/coverage. This function must follow the internal calling 127// convention. 128func LookupCoverage(name string) *ir.Name { 129 sym := ir.Pkgs.Coverage.Lookup(name) 130 if sym == nil { 131 base.Fatalf("LookupCoverage: can't find runtime/coverage.%s", name) 132 } 133 return sym.Def.(*ir.Name) 134} 135