]> Cypherpunks.ru repositories - gostls13.git/blob - src/cmd/compile/internal/types/pkg.go
cmd/compile: move and rename mkpkg to types.NewPkg
[gostls13.git] / src / cmd / compile / internal / types / pkg.go
1 // Copyright 2017 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 types
6
7 import (
8         "cmd/internal/obj"
9         "cmd/internal/objabi"
10 )
11
12 type Pkg struct {
13         Name     string // package name, e.g. "sys"
14         Path     string // string literal used in import statement, e.g. "runtime/internal/sys"
15         Pathsym  *obj.LSym
16         Prefix   string // escaped path for use in symbol table
17         Imported bool   // export data of this package was parsed
18         Direct   bool   // imported directly
19         Syms     map[string]*Sym
20 }
21
22 var PkgMap = make(map[string]*Pkg)
23 var PkgList []*Pkg
24
25 func NewPkg(path string) *Pkg {
26         if p := PkgMap[path]; p != nil {
27                 return p
28         }
29
30         p := new(Pkg)
31         p.Path = path
32         p.Prefix = objabi.PathToPrefix(path)
33         p.Syms = make(map[string]*Sym)
34         PkgMap[path] = p
35         PkgList = append(PkgList, p)
36         return p
37 }
38
39 var Nopkg = &Pkg{
40         Syms: make(map[string]*Sym),
41 }
42
43 func (pkg *Pkg) Lookup(name string) *Sym {
44         s, _ := pkg.LookupOK(name)
45         return s
46 }
47
48 var InitSyms []*Sym
49
50 // LookupOK looks up name in pkg and reports whether it previously existed.
51 func (pkg *Pkg) LookupOK(name string) (s *Sym, existed bool) {
52         if pkg == nil {
53                 pkg = Nopkg
54         }
55         if s := pkg.Syms[name]; s != nil {
56                 return s, true
57         }
58
59         s = &Sym{
60                 Name: name,
61                 Pkg:  pkg,
62         }
63         if name == "init" {
64                 InitSyms = append(InitSyms, s)
65         }
66         pkg.Syms[name] = s
67         return s, false
68 }
69
70 func (pkg *Pkg) LookupBytes(name []byte) *Sym {
71         if pkg == nil {
72                 pkg = Nopkg
73         }
74         if s := pkg.Syms[string(name)]; s != nil {
75                 return s
76         }
77         str := InternString(name)
78         return pkg.Lookup(str)
79 }
80
81 var internedStrings = map[string]string{}
82
83 func InternString(b []byte) string {
84         s, ok := internedStrings[string(b)] // string(b) here doesn't allocate
85         if !ok {
86                 s = string(b)
87                 internedStrings[s] = s
88         }
89         return s
90 }