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