Source file src/cmd/compile/internal/typecheck/syms.go

     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  
     5  package typecheck
     6  
     7  import (
     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.
    17  func 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.
    32  func 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.
    51  func 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  
    64  func 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.
    71  func 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.
    91  func 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.
    98  func 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.
   103  func 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).
   109  func 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.
   128  func 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  

View as plain text