diff --git a/Dockerfile b/Dockerfile
index d11ce97..2745c6f 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -7,7 +7,7 @@ RUN apt-get update && apt-get install bzip2 zip unzip && cp -r /usr/local/go /us
ENV GOROOT_BOOTSTRAP=/usr/local/gobt
ADD . /wide/gogogo/src/github.com/b3log/wide
-ADD vendor/* /go/src/
+ADD vendor/ /go/src/
RUN go install github.com/visualfc/gotools github.com/nsf/gocode github.com/bradfitz/goimports
RUN useradd wide && useradd runner
diff --git a/vendor/github.com/visualfc/gotools/astview/astdoc.go b/vendor/github.com/visualfc/gotools/astview/astdoc.go
new file mode 100644
index 0000000..ae44d3f
--- /dev/null
+++ b/vendor/github.com/visualfc/gotools/astview/astdoc.go
@@ -0,0 +1,685 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package doc extracts source code documentation from a Go AST.
+package astview
+
+import (
+ "go/ast"
+ "go/token"
+ "regexp"
+ "sort"
+ "strconv"
+)
+
+// ----------------------------------------------------------------------------
+
+type typeDoc struct {
+ // len(decl.Specs) == 1, and the element type is *ast.TypeSpec
+ // if the type declaration hasn't been seen yet, decl is nil
+ decl *ast.GenDecl
+ // values, factory functions, and methods associated with the type
+ values []*ast.GenDecl // consts and vars
+ factories map[string]*ast.FuncDecl
+ methods map[string]*ast.FuncDecl
+}
+
+// docReader accumulates documentation for a single package.
+// It modifies the AST: Comments (declaration documentation)
+// that have been collected by the DocReader are set to nil
+// in the respective AST nodes so that they are not printed
+// twice (once when printing the documentation and once when
+// printing the corresponding AST node).
+//
+type docReader struct {
+ doc *ast.CommentGroup // package documentation, if any
+ pkgName string
+ showAll bool
+ values []*ast.GenDecl // consts and vars
+ types map[string]*typeDoc
+ funcs map[string]*ast.FuncDecl
+ imports map[string]int
+ bugs []*ast.CommentGroup
+}
+
+func (doc *docReader) init(pkgName string, showAll bool) {
+ doc.pkgName = pkgName
+ doc.showAll = showAll
+ doc.imports = make(map[string]int)
+ doc.types = make(map[string]*typeDoc)
+ doc.funcs = make(map[string]*ast.FuncDecl)
+}
+
+func (doc *docReader) addDoc(comments *ast.CommentGroup) {
+ if doc.doc == nil {
+ // common case: just one package comment
+ doc.doc = comments
+ return
+ }
+
+ // More than one package comment: Usually there will be only
+ // one file with a package comment, but it's better to collect
+ // all comments than drop them on the floor.
+ // (This code isn't particularly clever - no amortized doubling is
+ // used - but this situation occurs rarely and is not time-critical.)
+ n1 := len(doc.doc.List)
+ n2 := len(comments.List)
+ list := make([]*ast.Comment, n1+1+n2) // + 1 for separator line
+ copy(list, doc.doc.List)
+ list[n1] = &ast.Comment{token.NoPos, "//"} // separator line
+ copy(list[n1+1:], comments.List)
+ doc.doc = &ast.CommentGroup{list}
+}
+
+func (doc *docReader) addType(decl *ast.GenDecl) {
+ spec := decl.Specs[0].(*ast.TypeSpec)
+ typ := doc.lookupTypeDoc(spec.Name.Name)
+ // typ should always be != nil since declared types
+ // are always named - be conservative and check
+ if typ != nil {
+ // a type should be added at most once, so typ.decl
+ // should be nil - if it isn't, simply overwrite it
+ typ.decl = decl
+ }
+}
+
+func (doc *docReader) lookupTypeDoc(name string) *typeDoc {
+ if name == "" {
+ return nil // no type docs for anonymous types
+ }
+ if tdoc, found := doc.types[name]; found {
+ return tdoc
+ }
+ // type wasn't found - add one without declaration
+ tdoc := &typeDoc{nil, nil, make(map[string]*ast.FuncDecl), make(map[string]*ast.FuncDecl)}
+ doc.types[name] = tdoc
+ return tdoc
+}
+
+func docBaseTypeName(typ ast.Expr, showAll bool) string {
+ switch t := typ.(type) {
+ case *ast.Ident:
+ // if the type is not exported, the effect to
+ // a client is as if there were no type name
+ if showAll || t.IsExported() {
+ return t.Name
+ }
+ case *ast.StarExpr:
+ return docBaseTypeName(t.X, showAll)
+ }
+ return ""
+}
+
+func (doc *docReader) addValue(decl *ast.GenDecl) {
+ // determine if decl should be associated with a type
+ // Heuristic: For each typed entry, determine the type name, if any.
+ // If there is exactly one type name that is sufficiently
+ // frequent, associate the decl with the respective type.
+ domName := ""
+ domFreq := 0
+ prev := ""
+ for _, s := range decl.Specs {
+ if v, ok := s.(*ast.ValueSpec); ok {
+ name := ""
+ switch {
+ case v.Type != nil:
+ // a type is present; determine its name
+ name = docBaseTypeName(v.Type, doc.showAll)
+ case decl.Tok == token.CONST:
+ // no type is present but we have a constant declaration;
+ // use the previous type name (w/o more type information
+ // we cannot handle the case of unnamed variables with
+ // initializer expressions except for some trivial cases)
+ name = prev
+ }
+ if name != "" {
+ // entry has a named type
+ if domName != "" && domName != name {
+ // more than one type name - do not associate
+ // with any type
+ domName = ""
+ break
+ }
+ domName = name
+ domFreq++
+ }
+ prev = name
+ }
+ }
+
+ // determine values list
+ const threshold = 0.75
+ values := &doc.values
+ if domName != "" && domFreq >= int(float64(len(decl.Specs))*threshold) {
+ // typed entries are sufficiently frequent
+ typ := doc.lookupTypeDoc(domName)
+ if typ != nil {
+ values = &typ.values // associate with that type
+ }
+ }
+
+ *values = append(*values, decl)
+}
+
+// Helper function to set the table entry for function f. Makes sure that
+// at least one f with associated documentation is stored in table, if there
+// are multiple f's with the same name.
+func setFunc(table map[string]*ast.FuncDecl, f *ast.FuncDecl) {
+ name := f.Name.Name
+ if g, exists := table[name]; exists && g.Doc != nil {
+ // a function with the same name has already been registered;
+ // since it has documentation, assume f is simply another
+ // implementation and ignore it
+ // TODO(gri) consider collecting all functions, or at least
+ // all comments
+ return
+ }
+ // function doesn't exist or has no documentation; use f
+ table[name] = f
+}
+
+func (doc *docReader) addFunc(fun *ast.FuncDecl) {
+ name := fun.Name.Name
+
+ // determine if it should be associated with a type
+ if fun.Recv != nil {
+ // method
+ typ := doc.lookupTypeDoc(docBaseTypeName(fun.Recv.List[0].Type, doc.showAll))
+ if typ != nil {
+ // exported receiver type
+ setFunc(typ.methods, fun)
+ }
+ // otherwise don't show the method
+ // TODO(gri): There may be exported methods of non-exported types
+ // that can be called because of exported values (consts, vars, or
+ // function results) of that type. Could determine if that is the
+ // case and then show those methods in an appropriate section.
+ return
+ }
+
+ // perhaps a factory function
+ // determine result type, if any
+ if fun.Type.Results.NumFields() >= 1 {
+ res := fun.Type.Results.List[0]
+ if len(res.Names) <= 1 {
+ // exactly one (named or anonymous) result associated
+ // with the first type in result signature (there may
+ // be more than one result)
+ tname := docBaseTypeName(res.Type, doc.showAll)
+ typ := doc.lookupTypeDoc(tname)
+ if typ != nil {
+ // named and exported result type
+
+ // Work-around for failure of heuristic: In package os
+ // too many functions are considered factory functions
+ // for the Error type. Eliminate manually for now as
+ // this appears to be the only important case in the
+ // current library where the heuristic fails.
+ if doc.pkgName == "os" && tname == "Error" &&
+ name != "NewError" && name != "NewSyscallError" {
+ // not a factory function for os.Error
+ setFunc(doc.funcs, fun) // treat as ordinary function
+ return
+ }
+
+ setFunc(typ.factories, fun)
+ return
+ }
+ }
+ }
+
+ // ordinary function
+ setFunc(doc.funcs, fun)
+}
+
+func (doc *docReader) addDecl(decl ast.Decl) {
+ switch d := decl.(type) {
+ case *ast.GenDecl:
+ if len(d.Specs) > 0 {
+ switch d.Tok {
+ case token.IMPORT:
+ // imports are handled individually
+ for _, spec := range d.Specs {
+ if s, ok := spec.(*ast.ImportSpec); ok {
+ if import_, err := strconv.Unquote(s.Path.Value); err == nil {
+ doc.imports[import_] = 1
+ }
+ }
+ }
+ case token.CONST, token.VAR:
+ // constants and variables are always handled as a group
+ doc.addValue(d)
+ case token.TYPE:
+ // types are handled individually
+ for _, spec := range d.Specs {
+ // make a (fake) GenDecl node for this TypeSpec
+ // (we need to do this here - as opposed to just
+ // for printing - so we don't lose the GenDecl
+ // documentation)
+ //
+ // TODO(gri): Consider just collecting the TypeSpec
+ // node (and copy in the GenDecl.doc if there is no
+ // doc in the TypeSpec - this is currently done in
+ // makeTypeDocs below). Simpler data structures, but
+ // would lose GenDecl documentation if the TypeSpec
+ // has documentation as well.
+ doc.addType(&ast.GenDecl{d.Doc, d.Pos(), token.TYPE, token.NoPos, []ast.Spec{spec}, token.NoPos})
+ // A new GenDecl node is created, no need to nil out d.Doc.
+ }
+ }
+ }
+ case *ast.FuncDecl:
+ doc.addFunc(d)
+ }
+}
+
+func copyCommentList(list []*ast.Comment) []*ast.Comment {
+ return append([]*ast.Comment(nil), list...)
+}
+
+var (
+ bug_markers = regexp.MustCompile("^/[/*][ \t]*BUG\\(.*\\):[ \t]*") // BUG(uid):
+ bug_content = regexp.MustCompile("[^ \n\r\t]+") // at least one non-whitespace char
+)
+
+// addFile adds the AST for a source file to the docReader.
+// Adding the same AST multiple times is a no-op.
+//
+func (doc *docReader) addFile(src *ast.File) {
+ // add package documentation
+ if src.Doc != nil {
+ doc.addDoc(src.Doc)
+ src.Doc = nil // doc consumed - remove from ast.File node
+ }
+
+ // add all declarations
+ for _, decl := range src.Decls {
+ doc.addDecl(decl)
+ }
+
+ // collect BUG(...) comments
+ for _, c := range src.Comments {
+ text := c.List[0].Text
+ if m := bug_markers.FindStringIndex(text); m != nil {
+ // found a BUG comment; maybe empty
+ if btxt := text[m[1]:]; bug_content.MatchString(btxt) {
+ // non-empty BUG comment; collect comment without BUG prefix
+ list := copyCommentList(c.List)
+ list[0].Text = text[m[1]:]
+ doc.bugs = append(doc.bugs, &ast.CommentGroup{list})
+ }
+ }
+ }
+ src.Comments = nil // consumed unassociated comments - remove from ast.File node
+}
+
+func NewFileDoc(file *ast.File, showAll bool) *PackageDoc {
+ var r docReader
+ r.init(file.Name.Name, showAll)
+ r.addFile(file)
+ return r.newDoc("", nil)
+}
+
+func NewPackageDoc(pkg *ast.Package, importpath string, showAll bool) *PackageDoc {
+ var r docReader
+ r.init(pkg.Name, showAll)
+ filenames := make([]string, len(pkg.Files))
+ i := 0
+ for filename, f := range pkg.Files {
+ r.addFile(f)
+ filenames[i] = filename
+ i++
+ }
+ return r.newDoc(importpath, filenames)
+}
+
+// ----------------------------------------------------------------------------
+// Conversion to external representation
+
+// ValueDoc is the documentation for a group of declared
+// values, either vars or consts.
+//
+type ValueDoc struct {
+ Doc string
+ Decl *ast.GenDecl
+ order int
+}
+
+type sortValueDoc []*ValueDoc
+
+func (p sortValueDoc) Len() int { return len(p) }
+func (p sortValueDoc) Swap(i, j int) { p[i], p[j] = p[j], p[i] }
+
+func declName(d *ast.GenDecl) string {
+ if len(d.Specs) != 1 {
+ return ""
+ }
+
+ switch v := d.Specs[0].(type) {
+ case *ast.ValueSpec:
+ return v.Names[0].Name
+ case *ast.TypeSpec:
+ return v.Name.Name
+ }
+
+ return ""
+}
+
+func (p sortValueDoc) Less(i, j int) bool {
+ // sort by name
+ // pull blocks (name = "") up to top
+ // in original order
+ if ni, nj := declName(p[i].Decl), declName(p[j].Decl); ni != nj {
+ return ni < nj
+ }
+ return p[i].order < p[j].order
+}
+
+func makeValueDocs(list []*ast.GenDecl, tok token.Token) []*ValueDoc {
+ d := make([]*ValueDoc, len(list)) // big enough in any case
+ n := 0
+ for i, decl := range list {
+ if decl.Tok == tok {
+ d[n] = &ValueDoc{decl.Doc.Text(), decl, i}
+ n++
+ decl.Doc = nil // doc consumed - removed from AST
+ }
+ }
+ d = d[0:n]
+ sort.Sort(sortValueDoc(d))
+ return d
+}
+
+// FuncDoc is the documentation for a func declaration,
+// either a top-level function or a method function.
+//
+type FuncDoc struct {
+ Doc string
+ Recv ast.Expr // TODO(rsc): Would like string here
+ Name string
+ Decl *ast.FuncDecl
+}
+
+type sortFuncDoc []*FuncDoc
+
+func (p sortFuncDoc) Len() int { return len(p) }
+func (p sortFuncDoc) Swap(i, j int) { p[i], p[j] = p[j], p[i] }
+func (p sortFuncDoc) Less(i, j int) bool { return p[i].Name < p[j].Name }
+
+func makeFuncDocs(m map[string]*ast.FuncDecl) []*FuncDoc {
+ d := make([]*FuncDoc, len(m))
+ i := 0
+ for _, f := range m {
+ doc := new(FuncDoc)
+ doc.Doc = f.Doc.Text()
+ f.Doc = nil // doc consumed - remove from ast.FuncDecl node
+ if f.Recv != nil {
+ doc.Recv = f.Recv.List[0].Type
+ }
+ doc.Name = f.Name.Name
+ doc.Decl = f
+ d[i] = doc
+ i++
+ }
+ sort.Sort(sortFuncDoc(d))
+ return d
+}
+
+// TypeDoc is the documentation for a declared type.
+// Consts and Vars are sorted lists of constants and variables of (mostly) that type.
+// Factories is a sorted list of factory functions that return that type.
+// Methods is a sorted list of method functions on that type.
+type TypeDoc struct {
+ Doc string
+ Type *ast.TypeSpec
+ Consts []*ValueDoc
+ Vars []*ValueDoc
+ Funcs []*FuncDoc
+ Methods []*FuncDoc
+ Decl *ast.GenDecl
+ order int
+}
+
+type sortTypeDoc []*TypeDoc
+
+func (p sortTypeDoc) Len() int { return len(p) }
+func (p sortTypeDoc) Swap(i, j int) { p[i], p[j] = p[j], p[i] }
+func (p sortTypeDoc) Less(i, j int) bool {
+ // sort by name
+ // pull blocks (name = "") up to top
+ // in original order
+ if ni, nj := p[i].Type.Name.Name, p[j].Type.Name.Name; ni != nj {
+ return ni < nj
+ }
+ return p[i].order < p[j].order
+}
+
+// NOTE(rsc): This would appear not to be correct for type ( )
+// blocks, but the doc extractor above has split them into
+// individual declarations.
+func (doc *docReader) makeTypeDocs(m map[string]*typeDoc) []*TypeDoc {
+ d := make([]*TypeDoc, len(m))
+ i := 0
+ for _, old := range m {
+ // all typeDocs should have a declaration associated with
+ // them after processing an entire package - be conservative
+ // and check
+ if decl := old.decl; decl != nil {
+ typespec := decl.Specs[0].(*ast.TypeSpec)
+ t := new(TypeDoc)
+ doc := typespec.Doc
+ typespec.Doc = nil // doc consumed - remove from ast.TypeSpec node
+ if doc == nil {
+ // no doc associated with the spec, use the declaration doc, if any
+ doc = decl.Doc
+ }
+ decl.Doc = nil // doc consumed - remove from ast.Decl node
+ t.Doc = doc.Text()
+ t.Type = typespec
+ t.Consts = makeValueDocs(old.values, token.CONST)
+ t.Vars = makeValueDocs(old.values, token.VAR)
+ t.Funcs = makeFuncDocs(old.factories)
+ t.Methods = makeFuncDocs(old.methods)
+ t.Decl = old.decl
+ t.order = i
+ d[i] = t
+ i++
+ } else {
+ // no corresponding type declaration found - move any associated
+ // values, factory functions, and methods back to the top-level
+ // so that they are not lost (this should only happen if a package
+ // file containing the explicit type declaration is missing or if
+ // an unqualified type name was used after a "." import)
+ // 1) move values
+ doc.values = append(doc.values, old.values...)
+ // 2) move factory functions
+ for name, f := range old.factories {
+ doc.funcs[name] = f
+ }
+ // 3) move methods
+ for name, f := range old.methods {
+ // don't overwrite functions with the same name
+ if _, found := doc.funcs[name]; !found {
+ doc.funcs[name] = f
+ }
+ }
+ }
+ }
+ d = d[0:i] // some types may have been ignored
+ sort.Sort(sortTypeDoc(d))
+ return d
+}
+
+func makeBugDocs(list []*ast.CommentGroup) []string {
+ d := make([]string, len(list))
+ for i, g := range list {
+ d[i] = g.Text()
+ }
+ return d
+}
+
+// PackageDoc is the documentation for an entire package.
+//
+type PackageDoc struct {
+ PackageName string
+ ImportPath string
+ Imports []string
+ Filenames []string
+ Doc string
+ Consts []*ValueDoc
+ Types []*TypeDoc
+ Vars []*ValueDoc
+ Funcs []*FuncDoc
+ Factorys []*FuncDoc
+ Bugs []string
+}
+
+// newDoc returns the accumulated documentation for the package.
+//
+func (doc *docReader) newDoc(importpath string, filenames []string) *PackageDoc {
+ p := new(PackageDoc)
+ p.PackageName = doc.pkgName
+ p.ImportPath = importpath
+ sort.Strings(filenames)
+ p.Filenames = filenames
+ p.Doc = doc.doc.Text()
+ p.Imports = sortedKeys(doc.imports)
+ // makeTypeDocs may extend the list of doc.values and
+ // doc.funcs and thus must be called before any other
+ // function consuming those lists
+ p.Types = doc.makeTypeDocs(doc.types)
+ p.Consts = makeValueDocs(doc.values, token.CONST)
+ p.Vars = makeValueDocs(doc.values, token.VAR)
+ p.Funcs = makeFuncDocs(doc.funcs)
+ p.Bugs = makeBugDocs(doc.bugs)
+
+ for _, d := range p.Types {
+ switch d.Type.Type.(type) {
+ case *ast.StructType:
+ p.Factorys = append(p.Factorys, d.Funcs...)
+ d.Funcs = make([]*FuncDoc, 0)
+ case *ast.InterfaceType:
+ p.Factorys = append(p.Factorys, d.Funcs...)
+ d.Funcs = make([]*FuncDoc, 0)
+ default:
+ p.Vars = append(p.Vars, d.Vars...)
+ d.Vars = make([]*ValueDoc, 0)
+ p.Consts = append(p.Consts, d.Consts...)
+ d.Consts = make([]*ValueDoc, 0)
+ }
+ }
+ return p
+}
+
+func sortedKeys(m map[string]int) []string {
+ list := make([]string, len(m))
+ i := 0
+ for key := range m {
+ list[i] = key
+ i++
+ }
+ sort.Strings(list)
+ return list
+}
+
+// ----------------------------------------------------------------------------
+// Filtering by name
+
+type Filter func(string) bool
+
+func matchFields(fields *ast.FieldList, f Filter) bool {
+ if fields != nil {
+ for _, field := range fields.List {
+ for _, name := range field.Names {
+ if f(name.Name) {
+ return true
+ }
+ }
+ }
+ }
+ return false
+}
+
+func matchDecl(d *ast.GenDecl, f Filter) bool {
+ for _, d := range d.Specs {
+ switch v := d.(type) {
+ case *ast.ValueSpec:
+ for _, name := range v.Names {
+ if f(name.Name) {
+ return true
+ }
+ }
+ case *ast.TypeSpec:
+ if f(v.Name.Name) {
+ return true
+ }
+ switch t := v.Type.(type) {
+ case *ast.StructType:
+ if matchFields(t.Fields, f) {
+ return true
+ }
+ case *ast.InterfaceType:
+ if matchFields(t.Methods, f) {
+ return true
+ }
+ }
+ }
+ }
+ return false
+}
+
+func filterValueDocs(a []*ValueDoc, f Filter) []*ValueDoc {
+ w := 0
+ for _, vd := range a {
+ if matchDecl(vd.Decl, f) {
+ a[w] = vd
+ w++
+ }
+ }
+ return a[0:w]
+}
+
+func filterFuncDocs(a []*FuncDoc, f Filter) []*FuncDoc {
+ w := 0
+ for _, fd := range a {
+ if f(fd.Name) {
+ a[w] = fd
+ w++
+ }
+ }
+ return a[0:w]
+}
+
+func filterTypeDocs(a []*TypeDoc, f Filter) []*TypeDoc {
+ w := 0
+ for _, td := range a {
+ n := 0 // number of matches
+ if matchDecl(td.Decl, f) {
+ n = 1
+ } else {
+ // type name doesn't match, but we may have matching consts, vars, factories or methods
+ td.Consts = filterValueDocs(td.Consts, f)
+ td.Vars = filterValueDocs(td.Vars, f)
+ td.Funcs = filterFuncDocs(td.Funcs, f)
+ td.Methods = filterFuncDocs(td.Methods, f)
+ n += len(td.Consts) + len(td.Vars) + len(td.Funcs) + len(td.Methods)
+ }
+ if n > 0 {
+ a[w] = td
+ w++
+ }
+ }
+ return a[0:w]
+}
+
+// Filter eliminates documentation for names that don't pass through the filter f.
+// TODO: Recognize "Type.Method" as a name.
+//
+func (p *PackageDoc) Filter(f Filter) {
+ p.Consts = filterValueDocs(p.Consts, f)
+ p.Vars = filterValueDocs(p.Vars, f)
+ p.Types = filterTypeDocs(p.Types, f)
+ p.Funcs = filterFuncDocs(p.Funcs, f)
+ p.Doc = "" // don't show top-level package doc
+}
diff --git a/vendor/github.com/visualfc/gotools/astview/astview.go b/vendor/github.com/visualfc/gotools/astview/astview.go
new file mode 100644
index 0000000..af07319
--- /dev/null
+++ b/vendor/github.com/visualfc/gotools/astview/astview.go
@@ -0,0 +1,346 @@
+// Copyright 2011-2015 visualfc . All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package astview
+
+import (
+ "fmt"
+ "go/ast"
+ "go/parser"
+ "go/token"
+ "io"
+ "io/ioutil"
+ "os"
+ "strings"
+
+ "github.com/visualfc/gotools/command"
+
+ "golang.org/x/tools/go/types"
+)
+
+var Command = &command.Command{
+ Run: runAstView,
+ UsageLine: "astview [-stdin] files...",
+ Short: "print go files astview",
+ Long: `print go files astview`,
+}
+
+var astViewStdin bool
+
+func init() {
+ Command.Flag.BoolVar(&astViewStdin, "stdin", false, "input from stdin")
+}
+
+func runAstView(cmd *command.Command, args []string) error {
+ if len(args) == 0 {
+ cmd.Usage()
+ return os.ErrInvalid
+ }
+ if astViewStdin {
+ view, err := NewFilePackageSource(args[0], os.Stdin, true)
+ if err != nil {
+ fmt.Fprintf(os.Stderr, "astview: %s", err)
+ command.SetExitStatus(3)
+ command.Exit()
+ }
+ view.PrintTree(os.Stdout)
+ } else {
+ err := PrintFilesTree(args, os.Stdout, true)
+ if err != nil {
+ fmt.Fprintf(os.Stderr, "astview:%s", err)
+ command.SetExitStatus(3)
+ command.Exit()
+ }
+ }
+ return nil
+}
+
+const (
+ tag_package = "p"
+ tag_imports_folder = "+m"
+ tag_import = "mm"
+ tag_type = "t"
+ tag_struct = "s"
+ tag_interface = "i"
+ tag_value = "v"
+ tag_const = "c"
+ tag_func = "f"
+ tag_value_folder = "+v"
+ tag_const_folder = "+c"
+ tag_func_folder = "+f"
+ tag_factor_folder = "+tf"
+ tag_type_method = "tm"
+ tag_type_factor = "tf"
+ tag_type_value = "tv"
+)
+
+type PackageView struct {
+ fset *token.FileSet
+ pdoc *PackageDoc
+ pkg *ast.Package
+ expr bool
+}
+
+var AllFiles []string
+
+func (p *PackageView) posFileIndex(pos token.Position) int {
+ var index = -1
+ for i := 0; i < len(AllFiles); i++ {
+ if AllFiles[i] == pos.Filename {
+ index = i
+ break
+ }
+ }
+ if index == -1 {
+ AllFiles = append(AllFiles, pos.Filename)
+ index = len(AllFiles) - 1
+ }
+ return index
+}
+
+func (p *PackageView) posText(pos token.Position) (s string) {
+ index := p.posFileIndex(pos)
+ return fmt.Sprintf("%d:%d:%d", index, pos.Line, pos.Column)
+}
+
+func NewFilePackage(filename string) (*PackageView, error) {
+ p := new(PackageView)
+ p.fset = token.NewFileSet()
+ file, err := parser.ParseFile(p.fset, filename, nil, parser.AllErrors)
+ if file == nil {
+ return nil, err
+ }
+ m := make(map[string]*ast.File)
+ m[filename] = file
+ pkg, err := ast.NewPackage(p.fset, m, nil, nil)
+ if err != nil {
+ return nil, err
+ }
+ p.pkg = pkg
+ p.pdoc = NewPackageDoc(pkg, pkg.Name, true)
+ return p, nil
+}
+
+func NewPackageView(pkg *ast.Package, fset *token.FileSet, expr bool) (*PackageView, error) {
+ p := new(PackageView)
+ p.fset = fset
+ p.pkg = pkg
+ p.pdoc = NewPackageDoc(pkg, pkg.Name, true)
+ p.expr = expr
+ return p, nil
+}
+
+func ParseFiles(fset *token.FileSet, filenames []string, mode parser.Mode) (pkgs map[string]*ast.Package, pkgsfiles []string, first error) {
+ pkgs = make(map[string]*ast.Package)
+ for _, filename := range filenames {
+ if src, err := parser.ParseFile(fset, filename, nil, mode); src != nil {
+ name := src.Name.Name
+ pkg, found := pkgs[name]
+ if !found {
+ pkg = &ast.Package{
+ Name: name,
+ Files: make(map[string]*ast.File),
+ }
+ pkgs[name] = pkg
+ }
+ pkg.Files[filename] = src
+ pkgsfiles = append(pkgsfiles, filename)
+ } else {
+ first = err
+ return
+ }
+ }
+ return
+}
+
+func PrintFilesTree(filenames []string, w io.Writer, expr bool) error {
+ fset := token.NewFileSet()
+ pkgs, pkgsfiles, err := ParseFiles(fset, filenames, parser.AllErrors)
+ if err != nil {
+ return err
+ }
+ AllFiles = pkgsfiles
+ for i := 0; i < len(AllFiles); i++ {
+ fmt.Fprintf(w, "@%s\n", AllFiles[i])
+ }
+ for _, pkg := range pkgs {
+ view, err := NewPackageView(pkg, fset, expr)
+ if err != nil {
+ return err
+ }
+ view.PrintTree(w)
+ }
+ return nil
+}
+
+func NewFilePackageSource(filename string, f *os.File, expr bool) (*PackageView, error) {
+ src, err := ioutil.ReadAll(f)
+ if err != nil {
+ return nil, err
+ }
+ p := new(PackageView)
+ p.fset = token.NewFileSet()
+ p.expr = expr
+ file, err := parser.ParseFile(p.fset, filename, src, 0)
+ if err != nil {
+ return nil, err
+ }
+ m := make(map[string]*ast.File)
+ m[filename] = file
+ pkg, err := ast.NewPackage(p.fset, m, nil, nil)
+ if err != nil {
+ return nil, err
+ }
+
+ p.pdoc = NewPackageDoc(pkg, pkg.Name, true)
+ return p, nil
+}
+
+func (p *PackageView) printFuncsHelper(w io.Writer, funcs []*FuncDoc, level int, tag string, tag_folder string) {
+ for _, f := range funcs {
+ pos := p.fset.Position(f.Decl.Pos())
+ if p.expr {
+ fmt.Fprintf(w, "%d,%s,%s,%s@%s\n", level, tag, f.Name, p.posText(pos), types.ExprString(f.Decl.Type))
+ } else {
+ fmt.Fprintf(w, "%d,%s,%s,%s\n", level, tag, f.Name, p.posText(pos))
+ }
+ }
+}
+
+func (p *PackageView) PrintVars(w io.Writer, vars []*ValueDoc, level int, tag string, tag_folder string) {
+ if len(tag_folder) > 0 && len(vars) > 0 {
+ if tag_folder == tag_value_folder {
+ fmt.Fprintf(w, "%d,%s,Variables\n", level, tag_folder)
+ } else if tag_folder == tag_const_folder {
+ fmt.Fprintf(w, "%d,%s,Constants\n", level, tag_folder)
+ }
+ level++
+ }
+ for _, v := range vars {
+ if v.Decl == nil {
+ continue
+ }
+ for _, s := range v.Decl.Specs {
+ if m, ok := s.(*ast.ValueSpec); ok {
+ pos := p.fset.Position(m.Pos())
+ for i := 0; i < len(m.Names); i++ {
+ if p.expr && m.Type != nil {
+ fmt.Fprintf(w, "%d,%s,%s,%s@%s\n", level, tag, m.Names[i], p.posText(pos), types.ExprString(m.Type))
+ } else {
+ fmt.Fprintf(w, "%d,%s,%s,%s\n", level, tag, m.Names[i], p.posText(pos))
+ }
+ }
+ }
+ }
+ }
+}
+func (p *PackageView) PrintTypes(w io.Writer, types []*TypeDoc, level int) {
+ for _, d := range types {
+ if d.Decl == nil {
+ continue
+ }
+ typespec := d.Decl.Specs[0].(*ast.TypeSpec)
+ var tag = tag_type
+ if _, ok := typespec.Type.(*ast.InterfaceType); ok {
+ tag = tag_interface
+ } else if _, ok := typespec.Type.(*ast.StructType); ok {
+ tag = tag_struct
+ }
+ pos := p.fset.Position(d.Decl.Pos())
+ fmt.Fprintf(w, "%d,%s,%s,%s\n", level, tag, d.Type.Name, p.posText(pos))
+ p.printFuncsHelper(w, d.Funcs, level+1, tag_type_factor, "")
+ p.printFuncsHelper(w, d.Methods, level+1, tag_type_method, "")
+ p.PrintTypeFields(w, d.Decl, level+1)
+ //p.PrintVars(w, d.Consts, level+1, tag_const, "")
+ //p.PrintVars(w, d.Vars, level+1, tag_value, "")
+ }
+}
+
+func (p *PackageView) PrintTypeFields(w io.Writer, decl *ast.GenDecl, level int) {
+ spec, ok := decl.Specs[0].(*ast.TypeSpec)
+ if ok == false {
+ return
+ }
+ switch d := spec.Type.(type) {
+ case *ast.StructType:
+ for _, list := range d.Fields.List {
+ if list.Names == nil {
+ continue
+ }
+ for _, m := range list.Names {
+ pos := p.fset.Position(m.Pos())
+ if list.Type != nil {
+ fmt.Fprintf(w, "%d,%s,%s,%s@%s\n", level, tag_type_value, m.Name, p.posText(pos), types.ExprString(list.Type))
+ } else {
+ fmt.Fprintf(w, "%d,%s,%s,%s\n", level, tag_type_value, m.Name, p.posText(pos))
+ }
+ }
+ }
+ case *ast.InterfaceType:
+ for _, list := range d.Methods.List {
+ if list.Names == nil {
+ continue
+ }
+ for _, m := range list.Names {
+ pos := p.fset.Position(m.Pos())
+ fmt.Fprintf(w, "%d,%s,%s,%s\n", level, tag_type_method, m.Name, p.posText(pos))
+ }
+ }
+ }
+}
+
+func (p *PackageView) PrintHeader(w io.Writer, level int) {
+ fmt.Fprintf(w, "%d,%s,%s\n", level, tag_package, p.pdoc.PackageName)
+}
+
+func (p *PackageView) PrintImports(w io.Writer, level int, tag, tag_folder string) {
+ if tag_folder != "" && len(p.pdoc.Imports) > 0 {
+ fmt.Fprintf(w, "%d,%s,%s\n", level, tag_folder, "Imports")
+ level++
+ }
+ for _, name := range p.pdoc.Imports {
+ vname := "\"" + name + "\""
+ var ps []string
+ for _, file := range p.pkg.Files {
+ for _, v := range file.Imports {
+ if v.Path.Value == vname {
+ pos := p.fset.Position(v.Pos())
+ ps = append(ps, p.posText(pos))
+ }
+ }
+ }
+ fmt.Fprintf(w, "%d,%s,%s,%s\n", level, tag, name, strings.Join(ps, ";"))
+ }
+}
+
+func (p *PackageView) PrintFuncs(w io.Writer, level int, tag_folder string) {
+ hasFolder := false
+ if len(p.pdoc.Funcs) > 0 || len(p.pdoc.Factorys) > 0 {
+ hasFolder = true
+ }
+ if !hasFolder {
+ return
+ }
+ if len(tag_folder) > 0 {
+ fmt.Fprintf(w, "%d,%s,Functions\n", level, tag_folder)
+ level++
+ }
+ p.printFuncsHelper(w, p.pdoc.Factorys, level, tag_type_factor, tag_func_folder)
+ p.printFuncsHelper(w, p.pdoc.Funcs, level, tag_func, tag_func_folder)
+}
+
+func (p *PackageView) PrintPackage(w io.Writer, level int) {
+ p.PrintHeader(w, level)
+ level++
+ p.PrintImports(w, level, tag_import, tag_imports_folder)
+ p.PrintVars(w, p.pdoc.Vars, level, tag_value, tag_value_folder)
+ p.PrintVars(w, p.pdoc.Consts, level, tag_const, tag_const_folder)
+ p.PrintFuncs(w, level, tag_func_folder)
+ p.PrintTypes(w, p.pdoc.Types, level)
+}
+
+// level,tag,pos@info
+func (p *PackageView) PrintTree(w io.Writer) {
+ p.PrintPackage(w, 0)
+}
diff --git a/vendor/github.com/visualfc/gotools/command/command.go b/vendor/github.com/visualfc/gotools/command/command.go
new file mode 100644
index 0000000..a20a3fb
--- /dev/null
+++ b/vendor/github.com/visualfc/gotools/command/command.go
@@ -0,0 +1,343 @@
+// Copyright 2011 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//modify 2013-2014 visualfc
+
+package command
+
+import (
+ "bytes"
+ "flag"
+ "fmt"
+ "io"
+ "log"
+ "os"
+ "strings"
+ "sync"
+ "text/template"
+ "unicode"
+ "unicode/utf8"
+)
+
+// A Command is an implementation of a go command
+// like go build or go fix.
+type Command struct {
+ // Run runs the command.
+ // The args are the arguments after the command name.
+ Run func(cmd *Command, args []string) error
+
+ // UsageLine is the one-line usage message.
+ // The first word in the line is taken to be the command name.
+ UsageLine string
+
+ // Short is the short description shown in the 'go help' output.
+ Short string
+
+ // Long is the long message shown in the 'go help ' output.
+ Long string
+
+ // Flag is a set of flags specific to this command.
+ Flag flag.FlagSet
+
+ // CustomFlags indicates that the command will do its own
+ // flag parsing.
+ CustomFlags bool
+
+ Stdin io.Reader
+ Stdout io.Writer
+ Stderr io.Writer
+}
+
+// Name returns the command's name: the first word in the usage line.
+func (c *Command) Name() string {
+ name := c.UsageLine
+ i := strings.Index(name, " ")
+ if i >= 0 {
+ name = name[:i]
+ }
+ return name
+}
+
+func (c *Command) Usage() {
+ fmt.Fprintf(os.Stderr, "usage: %s %s\n", AppName, c.UsageLine)
+ c.Flag.SetOutput(os.Stderr)
+ c.Flag.PrintDefaults()
+ //fmt.Fprintf(os.Stderr, "%s\n", strings.TrimSpace(c.Long))
+ os.Exit(2)
+}
+
+func (c *Command) PrintUsage() {
+ fmt.Fprintf(Stderr, "usage: %s %s\n", AppName, c.UsageLine)
+ c.Flag.SetOutput(Stderr)
+ c.Flag.PrintDefaults()
+}
+
+// Runnable reports whether the command can be run; otherwise
+// it is a documentation pseudo-command such as importpath.
+func (c *Command) Runnable() bool {
+ return c.Run != nil
+}
+
+func (c *Command) Println(args ...interface{}) {
+ fmt.Fprintln(c.Stdout, args...)
+}
+
+func (c *Command) Printf(format string, args ...interface{}) {
+ fmt.Fprintf(c.Stdout, format, args...)
+}
+
+var commands []*Command
+
+func Register(cmd *Command) {
+ commands = append(commands, cmd)
+}
+
+func CommandList() (cmds []string) {
+ for _, cmd := range commands {
+ cmds = append(cmds, cmd.Name())
+ }
+ return
+}
+
+var exitStatus = 0
+var exitMu sync.Mutex
+
+func SetExitStatus(n int) {
+ exitMu.Lock()
+ if exitStatus < n {
+ exitStatus = n
+ }
+ exitMu.Unlock()
+}
+
+var (
+ Stdout io.Writer = os.Stdout
+ Stderr io.Writer = os.Stderr
+ Stdin io.Reader = os.Stdin
+)
+
+func RunArgs(arguments []string, stdin io.Reader, stdout io.Writer, stderr io.Writer) error {
+ flag.CommandLine.Parse(arguments)
+ args := flag.Args()
+ if len(args) < 1 {
+ printUsage(os.Stderr)
+ return os.ErrInvalid
+ }
+
+ if len(args) == 1 && strings.TrimSpace(args[0]) == "" {
+ printUsage(os.Stderr)
+ return os.ErrInvalid
+ }
+
+ if args[0] == "help" {
+ if !help(args[1:]) {
+ return os.ErrInvalid
+ }
+ return nil
+ }
+
+ for _, cmd := range commands {
+ if cmd.Name() == args[0] && cmd.Run != nil {
+ cmd.Flag.Usage = func() { cmd.Usage() }
+ if cmd.CustomFlags {
+ args = args[1:]
+ } else {
+ cmd.Flag.Parse(args[1:])
+ args = cmd.Flag.Args()
+ }
+ cmd.Stdin = stdin
+ cmd.Stdout = stdout
+ cmd.Stderr = stderr
+ return cmd.Run(cmd, args)
+ }
+ }
+
+ fmt.Fprintf(os.Stderr, "%s: unknown subcommand %q\nRun '%s help' for usage.\n",
+ AppName, args[0], AppName)
+ return os.ErrInvalid
+}
+
+func Main() {
+ flag.Usage = usage
+ flag.Parse()
+ log.SetFlags(0)
+
+ args := flag.Args()
+ if len(args) < 1 {
+ usage()
+ }
+
+ if len(args) == 1 && strings.TrimSpace(args[0]) == "" {
+ usage()
+ }
+
+ if args[0] == "help" {
+ if !help(args[1:]) {
+ os.Exit(2)
+ }
+ return
+ }
+
+ for _, cmd := range commands {
+ if cmd.Name() == args[0] && cmd.Run != nil {
+ cmd.Flag.Usage = func() { cmd.Usage() }
+ if cmd.CustomFlags {
+ args = args[1:]
+ } else {
+ cmd.Flag.Parse(args[1:])
+ args = cmd.Flag.Args()
+ }
+ cmd.Stdin = Stdin
+ cmd.Stdout = Stdout
+ cmd.Stderr = Stderr
+ cmd.Run(cmd, args)
+ Exit()
+ return
+ }
+ }
+
+ fmt.Fprintf(os.Stderr, "%s: unknown subcommand %q\nRun '%s help' for usage.\n",
+ AppName, args[0], AppName)
+ SetExitStatus(2)
+ Exit()
+}
+
+var AppInfo string = "LiteIDE golang tool."
+var AppName string = "tools"
+
+var usageTemplate = `
+Usage:
+
+ {{AppName}} command [arguments]
+
+The commands are:
+{{range .}}{{if .Runnable}}
+ {{.Name | printf "%-11s"}} {{.Short}}{{end}}{{end}}
+
+Use "{{AppName}} help [command]" for more information about a command.
+
+Additional help topics:
+{{range .}}{{if not .Runnable}}
+ {{.Name | printf "%-11s"}} {{.Short}}{{end}}{{end}}
+
+Use "{{AppName}} help [topic]" for more information about that topic.
+
+`
+
+var helpTemplate = `{{if .Runnable}}usage: {{AppName}} {{.UsageLine}}
+
+{{end}}{{.Long | trim}}
+`
+
+var documentationTemplate = `//
+/*
+{{range .}}{{if .Short}}{{.Short | capitalize}}
+
+{{end}}{{if .Runnable}}Usage:
+
+ {{AppName}} {{.UsageLine}}
+
+{{end}}{{.Long | trim}}
+
+
+{{end}}*/
+package main
+`
+
+// tmpl executes the given template text on data, writing the result to w.
+func tmpl(w io.Writer, text string, data interface{}) {
+ t := template.New("top")
+ t.Funcs(template.FuncMap{"trim": strings.TrimSpace, "capitalize": capitalize})
+ template.Must(t.Parse(text))
+ if err := t.Execute(w, data); err != nil {
+ panic(err)
+ }
+}
+
+func capitalize(s string) string {
+ if s == "" {
+ return s
+ }
+ r, n := utf8.DecodeRuneInString(s)
+ return string(unicode.ToTitle(r)) + s[n:]
+}
+
+func printUsage(w io.Writer) {
+ if len(AppInfo) > 0 {
+ fmt.Fprintln(w, AppInfo)
+ }
+ tmpl(w, strings.Replace(usageTemplate, "{{AppName}}", AppName, -1), commands)
+}
+
+func usage() {
+ printUsage(os.Stderr)
+ os.Exit(2)
+}
+
+// help implements the 'help' command.
+func help(args []string) bool {
+ if len(args) == 0 {
+ printUsage(os.Stdout)
+ // not exit 2: succeeded at 'go help'.
+ return true
+ }
+ if len(args) != 1 {
+ fmt.Fprintf(os.Stderr, "usage: %s help command\n\nToo many arguments given.\n", AppName)
+ return false
+ }
+
+ arg := args[0]
+
+ // 'go help documentation' generates doc.go.
+ if arg == "documentation" {
+ buf := new(bytes.Buffer)
+ printUsage(buf)
+ usage := &Command{Long: buf.String()}
+ tmpl(os.Stdout, strings.Replace(documentationTemplate, "{{AppName}}", AppName, -1), append([]*Command{usage}, commands...))
+ return false
+ }
+
+ for _, cmd := range commands {
+ if cmd.Name() == arg {
+ tmpl(os.Stdout, strings.Replace(helpTemplate, "{{AppName}}", AppName, -1), cmd)
+ // not exit 2: succeeded at 'go help cmd'.
+ return true
+ }
+ }
+
+ fmt.Fprintf(os.Stderr, "Unknown help topic %#q. Run '%s help'.\n", arg, AppName)
+ //os.Exit(2) // failed at 'go help cmd'
+ return false
+}
+
+var atexitFuncs []func()
+
+func Atexit(f func()) {
+ atexitFuncs = append(atexitFuncs, f)
+}
+
+func Exit() {
+ for _, f := range atexitFuncs {
+ f()
+ }
+ os.Exit(exitStatus)
+}
+
+func Fatalf(format string, args ...interface{}) {
+ Errorf(format, args...)
+ Exit()
+}
+
+func Errorf(format string, args ...interface{}) {
+ log.Printf(format, args...)
+ SetExitStatus(1)
+}
+
+var logf = log.Printf
+
+func ExitIfErrors() {
+ if exitStatus != 0 {
+ Exit()
+ }
+}
diff --git a/vendor/github.com/visualfc/gotools/command/version.go b/vendor/github.com/visualfc/gotools/command/version.go
new file mode 100644
index 0000000..0a88780
--- /dev/null
+++ b/vendor/github.com/visualfc/gotools/command/version.go
@@ -0,0 +1,33 @@
+// Copyright 2011-2015 visualfc . All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package command
+
+import (
+ "os"
+ "runtime"
+)
+
+func init() {
+ Register(cmdVersion)
+}
+
+var AppVersion string = "1.0"
+
+var cmdVersion = &Command{
+ Run: runVersion,
+ UsageLine: "version",
+ Short: "print tool version",
+ Long: `Version prints the version.`,
+}
+
+func runVersion(cmd *Command, args []string) error {
+ if len(args) != 0 {
+ cmd.PrintUsage()
+ return os.ErrInvalid
+ }
+
+ cmd.Printf("%s version %s [%s %s/%s]\n", AppName, AppVersion, runtime.Version(), runtime.GOOS, runtime.GOARCH)
+ return nil
+}
diff --git a/vendor/github.com/visualfc/gotools/docview/dirtrees.go b/vendor/github.com/visualfc/gotools/docview/dirtrees.go
new file mode 100644
index 0000000..2293e00
--- /dev/null
+++ b/vendor/github.com/visualfc/gotools/docview/dirtrees.go
@@ -0,0 +1,352 @@
+// Copyright 2010 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// This file contains the code dealing with package directory trees.
+
+package docview
+
+import (
+ "bytes"
+ "go/doc"
+ "go/parser"
+ "go/token"
+ "log"
+ "os"
+ "path/filepath"
+ "strings"
+ "unicode"
+)
+
+type Directory struct {
+ Depth int
+ Path string // includes Name
+ Name string
+ Text string // package documentation, if any
+ Dirs []*Directory // subdirectories
+}
+
+//func isGoFile(fi os.FileInfo) bool {
+// name := fi.Name()
+// return !fi.IsDir() &&
+// len(name) > 0 && name[0] != '.' && // ignore .files
+// filepath.Ext(name) == ".go"
+//}
+
+func isGoFile(f os.FileInfo) bool {
+ // ignore non-Go files
+ name := f.Name()
+ return !f.IsDir() && !strings.HasPrefix(name, ".") && strings.HasSuffix(name, ".go")
+}
+
+func isPkgFile(fi os.FileInfo) bool {
+ return isGoFile(fi) &&
+ !strings.HasSuffix(fi.Name(), "_test.go") // ignore test files
+}
+
+func isPkgDir(fi os.FileInfo) bool {
+ name := fi.Name()
+ return fi.IsDir() && len(name) > 0 &&
+ name[0] != '_' && name[0] != '.' // ignore _files and .files
+}
+
+func firstSentence(s string) string {
+ i := -1 // index+1 of first terminator (punctuation ending a sentence)
+ j := -1 // index+1 of first terminator followed by white space
+ prev := 'A'
+ for k, ch := range s {
+ k1 := k + 1
+ if ch == '.' || ch == '!' || ch == '?' {
+ if i < 0 {
+ i = k1 // first terminator
+ }
+ if k1 < len(s) && s[k1] <= ' ' {
+ if j < 0 {
+ j = k1 // first terminator followed by white space
+ }
+ if !unicode.IsUpper(prev) {
+ j = k1
+ break
+ }
+ }
+ }
+ prev = ch
+ }
+
+ if j < 0 {
+ // use the next best terminator
+ j = i
+ if j < 0 {
+ // no terminator at all, use the entire string
+ j = len(s)
+ }
+ }
+
+ return s[0:j]
+}
+
+type treeBuilder struct {
+ pathFilter func(string) bool
+ maxDepth int
+}
+
+func (b *treeBuilder) newDirTree(fset *token.FileSet, path, name string, depth int) *Directory {
+ if b.pathFilter != nil && !b.pathFilter(path) {
+ return nil
+ }
+
+ if depth >= b.maxDepth {
+ // return a dummy directory so that the parent directory
+ // doesn't get discarded just because we reached the max
+ // directory depth
+ return &Directory{depth, path, name, "", nil}
+ }
+
+ list, err := fs.ReadDir(path)
+ if err != nil {
+ // newDirTree is called with a path that should be a package
+ // directory; errors here should not happen, but if they do,
+ // we want to know about them
+ log.Printf("ReadDir(%s): %s", path, err)
+ }
+
+ // determine number of subdirectories and if there are package files
+ ndirs := 0
+ hasPkgFiles := false
+ var synopses [4]string // prioritized package documentation (0 == highest priority)
+ for _, d := range list {
+ switch {
+ case isPkgDir(d):
+ ndirs++
+ case isPkgFile(d):
+ // looks like a package file, but may just be a file ending in ".go";
+ // don't just count it yet (otherwise we may end up with hasPkgFiles even
+ // though the directory doesn't contain any real package files - was bug)
+ if synopses[0] == "" {
+ // no "optimal" package synopsis yet; continue to collect synopses
+ //file, err := parseFile(fset, filepath.Join(path, d.Name()),
+ //parser.ParseComments|parser.PackageClauseOnly)
+ file, err := parser.ParseFile(fset, filepath.Join(path, d.Name()), nil,
+ parser.ParseComments|parser.PackageClauseOnly)
+
+ if err == nil {
+ hasPkgFiles = true
+ if file.Doc != nil {
+ // prioritize documentation
+ i := -1
+ switch file.Name.Name {
+ case name:
+ i = 0 // normal case: directory name matches package name
+ case fakePkgName:
+ i = 1 // synopses for commands
+ case "main":
+ i = 2 // directory contains a main package
+ default:
+ i = 3 // none of the above
+ }
+ if 0 <= i && i < len(synopses) && synopses[i] == "" {
+ synopses[i] = doc.Synopsis(file.Doc.Text())
+ }
+ }
+ }
+ }
+ }
+ }
+
+ // create subdirectory tree
+ var dirs []*Directory
+ if ndirs > 0 {
+ dirs = make([]*Directory, ndirs)
+ i := 0
+ for _, d := range list {
+ if isPkgDir(d) {
+ name := d.Name()
+ dd := b.newDirTree(fset, filepath.Join(path, name), name, depth+1)
+ if dd != nil {
+ dirs[i] = dd
+ i++
+ }
+ }
+ }
+ dirs = dirs[0:i]
+ }
+
+ // if there are no package files and no subdirectories
+ // containing package files, ignore the directory
+ if !hasPkgFiles && len(dirs) == 0 {
+ return nil
+ }
+
+ // select the highest-priority synopsis for the directory entry, if any
+ synopsis := ""
+ for _, synopsis = range synopses {
+ if synopsis != "" {
+ break
+ }
+ }
+
+ return &Directory{depth, path, name, synopsis, dirs}
+}
+
+// newDirectory creates a new package directory tree with at most maxDepth
+// levels, anchored at root. The result tree is pruned such that it only
+// contains directories that contain package files or that contain
+// subdirectories containing package files (transitively). If a non-nil
+// pathFilter is provided, directory paths additionally must be accepted
+// by the filter (i.e., pathFilter(path) must be true). If a value >= 0 is
+// provided for maxDepth, nodes at larger depths are pruned as well; they
+// are assumed to contain package files even if their contents are not known
+// (i.e., in this case the tree may contain directories w/o any package files).
+//
+func newDirectory(root string, pathFilter func(string) bool, maxDepth int) *Directory {
+ // The root could be a symbolic link so use Stat not Lstat.
+ d, err := fs.Stat(root)
+ // If we fail here, report detailed error messages; otherwise
+ // is is hard to see why a directory tree was not built.
+ switch {
+ case err != nil:
+ log.Printf("newDirectory(%s): %s", root, err)
+ return nil
+ case !isPkgDir(d):
+ log.Printf("newDirectory(%s): not a package directory", root)
+ return nil
+ }
+ if maxDepth < 0 {
+ maxDepth = 1e6 // "infinity"
+ }
+ b := treeBuilder{pathFilter, maxDepth}
+ // the file set provided is only for local parsing, no position
+ // information escapes and thus we don't need to save the set
+ return b.newDirTree(token.NewFileSet(), root, d.Name(), 0)
+}
+
+func (dir *Directory) writeLeafs(buf *bytes.Buffer) {
+ if dir != nil {
+ if len(dir.Dirs) == 0 {
+ buf.WriteString(dir.Path)
+ buf.WriteByte('\n')
+ return
+ }
+
+ for _, d := range dir.Dirs {
+ d.writeLeafs(buf)
+ }
+ }
+}
+
+func (dir *Directory) walk(c chan<- *Directory, skipRoot bool) {
+ if dir != nil {
+ if !skipRoot {
+ c <- dir
+ }
+ for _, d := range dir.Dirs {
+ d.walk(c, false)
+ }
+ }
+}
+
+func (dir *Directory) iter(skipRoot bool) <-chan *Directory {
+ c := make(chan *Directory)
+ go func() {
+ dir.walk(c, skipRoot)
+ close(c)
+ }()
+ return c
+}
+
+func (dir *Directory) lookupLocal(name string) *Directory {
+ for _, d := range dir.Dirs {
+ if d.Name == name {
+ return d
+ }
+ }
+ return nil
+}
+
+// lookup looks for the *Directory for a given path, relative to dir.
+func (dir *Directory) lookup(path string) *Directory {
+ d := strings.Split(dir.Path, string(filepath.Separator))
+ p := strings.Split(path, string(filepath.Separator))
+ i := 0
+ for i < len(d) {
+ if i >= len(p) || d[i] != p[i] {
+ return nil
+ }
+ i++
+ }
+ for dir != nil && i < len(p) {
+ dir = dir.lookupLocal(p[i])
+ i++
+ }
+ return dir
+}
+
+// DirEntry describes a directory entry. The Depth and Height values
+// are useful for presenting an entry in an indented fashion.
+//
+type DirEntry struct {
+ Depth int // >= 0
+ Height int // = DirList.MaxHeight - Depth, > 0
+ Path string // includes Name, relative to DirList root
+ Name string
+ Synopsis string
+}
+
+type DirList struct {
+ MaxHeight int // directory tree height, > 0
+ List []DirEntry
+}
+
+// listing creates a (linear) directory listing from a directory tree.
+// If skipRoot is set, the root directory itself is excluded from the list.
+//
+func (root *Directory) listing(skipRoot bool) *DirList {
+ if root == nil {
+ return nil
+ }
+
+ // determine number of entries n and maximum height
+ n := 0
+ minDepth := 1 << 30 // infinity
+ maxDepth := 0
+ for d := range root.iter(skipRoot) {
+ n++
+ if minDepth > d.Depth {
+ minDepth = d.Depth
+ }
+ if maxDepth < d.Depth {
+ maxDepth = d.Depth
+ }
+ }
+ maxHeight := maxDepth - minDepth + 1
+
+ if n == 0 {
+ return nil
+ }
+
+ // create list
+ list := make([]DirEntry, n)
+ i := 0
+ for d := range root.iter(skipRoot) {
+ p := &list[i]
+ p.Depth = d.Depth - minDepth
+ p.Height = maxHeight - p.Depth
+ // the path is relative to root.Path - remove the root.Path
+ // prefix (the prefix should always be present but avoid
+ // crashes and check)
+ path := d.Path
+ if strings.HasPrefix(d.Path, root.Path) {
+ path = d.Path[len(root.Path):]
+ }
+ // remove trailing separator if any - path must be relative
+ if len(path) > 0 && path[0] == filepath.Separator {
+ path = path[1:]
+ }
+ p.Path = filepath.ToSlash(path)
+ p.Name = d.Name
+ p.Synopsis = d.Text
+ i++
+ }
+
+ return &DirList{maxHeight, list}
+}
diff --git a/vendor/github.com/visualfc/gotools/docview/docview.go b/vendor/github.com/visualfc/gotools/docview/docview.go
new file mode 100644
index 0000000..85d96b6
--- /dev/null
+++ b/vendor/github.com/visualfc/gotools/docview/docview.go
@@ -0,0 +1,407 @@
+// Copyright 2011-2015 visualfc . All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package docview
+
+import (
+ "bytes"
+ "fmt"
+ "go/build"
+ "io"
+ "log"
+ "os"
+ "path/filepath"
+ "runtime"
+ "strconv"
+ "strings"
+ "text/template"
+ "time"
+
+ "github.com/visualfc/gotools/command"
+)
+
+var Command = &command.Command{
+ Run: runDocView,
+ UsageLine: "docview [-mode] [-list|-find]",
+ Short: "golang docview util",
+ Long: `golang docview util`,
+}
+
+var goroot = runtime.GOROOT()
+
+var docViewFind string
+var docViewList string
+var docViewMode string
+
+func init() {
+ Command.Flag.StringVar(&docViewFind, "find", "", "find package list, :pkg flag is best match")
+ Command.Flag.StringVar(&docViewList, "list", "", "Print go packages list [pkg|cmd]")
+ Command.Flag.StringVar(&docViewMode, "mode", "text", "Print mode [text|html|lite]")
+}
+
+func runDocView(cmd *command.Command, args []string) error {
+ if docViewFind == "" && docViewList == "" {
+ cmd.Usage()
+ return os.ErrInvalid
+ }
+
+ var template string
+ var info *Info
+ if len(docViewList) > 0 {
+ pkgPath := filepath.Join(goroot, "src", docViewList)
+ if docViewList == "pkg" {
+ _, err := os.Stat(pkgPath)
+ if err != nil {
+ pkgPath = filepath.Join(goroot, "src")
+ }
+ }
+ info = NewListInfo(pkgPath)
+ if info != nil {
+ if docViewList == "pkg" {
+ var filterList []DirEntry
+ for _, v := range info.Dirs.List {
+ if v.Path == "cmd" {
+ continue
+ }
+ if strings.HasPrefix(v.Path, "cmd/") {
+ continue
+ }
+ if strings.Contains(v.Path, "/testdata") {
+ continue
+ }
+ filterList = append(filterList, v)
+ }
+ info.Dirs.List = filterList
+ } else if docViewList == "cmd" {
+ var filterList []DirEntry
+ for _, v := range info.Dirs.List {
+ if strings.Contains(v.Path, "/") {
+ continue
+ }
+ if strings.Contains(v.Path, "internal") {
+ continue
+ }
+ filterList = append(filterList, v)
+ }
+ info.Dirs.List = filterList
+ }
+ }
+ switch docViewMode {
+ case "html":
+ template = listHTML
+ case "lite":
+ template = listLite
+ case "text":
+ template = listText
+ default:
+ template = listText
+ }
+ } else if len(docViewFind) > 0 {
+ dir := NewSourceDir(goroot)
+ info = dir.FindInfo(docViewFind)
+ switch docViewMode {
+ case "html":
+ template = findHTML
+ case "lite":
+ template = findLite
+ case "text":
+ template = findText
+ default:
+ template = findText
+ }
+ }
+ if info == nil {
+ fmt.Fprintf(os.Stderr, "\n")
+ command.SetExitStatus(3)
+ command.Exit()
+ }
+ contents := info.GetPkgList(docViewMode, template)
+ fmt.Fprintf(os.Stdout, "%s", contents)
+ return nil
+}
+
+var (
+ fs FileSystem = OS // the underlying file system
+)
+
+// Fake package file and name for commands. Contains the command documentation.
+const fakePkgFile = "doc.go"
+const fakePkgName = "documentation"
+
+func textFmt(w io.Writer, format string, x ...interface{}) {
+ var buf bytes.Buffer
+ fmt.Fprint(&buf, x)
+ template.HTMLEscape(w, buf.Bytes())
+}
+
+func pathEscFmt(w io.Writer, format string, x ...interface{}) {
+ switch v := x[0].(type) {
+ case []byte:
+ template.HTMLEscape(w, v)
+ case string:
+ template.HTMLEscape(w, []byte(filepath.ToSlash(v)))
+ default:
+ var buf bytes.Buffer
+ fmt.Fprint(&buf, x)
+ template.HTMLEscape(w, buf.Bytes())
+ }
+}
+
+func htmlEscFmt(w io.Writer, format string, x ...interface{}) {
+ switch v := x[0].(type) {
+ case int:
+ template.HTMLEscape(w, []byte(strconv.Itoa(v)))
+ case []byte:
+ template.HTMLEscape(w, v)
+ case string:
+ template.HTMLEscape(w, []byte(v))
+ default:
+ var buf bytes.Buffer
+ fmt.Fprint(&buf, x)
+ template.HTMLEscape(w, buf.Bytes())
+ }
+}
+
+// Template formatter for "padding" format.
+func paddingFmt(w io.Writer, format string, x ...interface{}) {
+ for i := x[0].(int); i > 0; i-- {
+ fmt.Fprint(w, ` `)
+ }
+}
+
+// Template formatter for "time" format.
+func timeFmt(w io.Writer, format string, x ...interface{}) {
+ template.HTMLEscape(w, []byte(time.Unix(x[0].(int64)/1e9, 0).String()))
+}
+
+var fmap = template.FuncMap{
+ "repeat": strings.Repeat,
+}
+
+func readTemplateData(name, data string) *template.Template {
+ return template.Must(template.New(name).Funcs(fmap).Parse(data))
+}
+
+func readTemplateFile(name, path string) *template.Template {
+ return template.Must(template.New(name).Funcs(fmap).ParseFiles(path))
+}
+
+func applyTemplate(t *template.Template, name string, data interface{}) []byte {
+ var buf bytes.Buffer
+ if err := t.Execute(&buf, data); err != nil {
+ log.Printf("%s.Execute: %s", name, err)
+ }
+ return buf.Bytes()
+}
+
+type Info struct {
+ Find string
+ Best *DirEntry
+ Dirs *DirList
+}
+
+type GodocDir struct {
+ pkg *Directory
+ cmd *Directory
+ gopath []*Directory
+}
+
+func NewSourceDir(goroot string) *GodocDir {
+ pkgPath := filepath.Join(goroot, "src/pkg")
+ _, err := os.Stat(pkgPath)
+ var cmd *Directory
+ if err != nil {
+ pkgPath = filepath.Join(goroot, "src")
+ } else {
+ cmd = newDirectory(filepath.Join(goroot, "src", "cmd"), nil, -1)
+ }
+ pkg := newDirectory(pkgPath, nil, -1)
+ ctx := build.Default
+ ctx.GOROOT = ""
+ var gopath []*Directory
+ for _, v := range ctx.SrcDirs() {
+ gopath = append(gopath, newDirectory(v, nil, -1))
+ }
+ return &GodocDir{pkg, cmd, gopath}
+}
+
+func (dir *GodocDir) FindInfo(name string) *Info {
+ max1, best1, list1 := FindDir(dir.pkg, name)
+ max2, best2, list2 := FindDir(dir.cmd, name)
+ var maxHeight int
+ if max1 >= max2 {
+ maxHeight = max1
+ } else {
+ maxHeight = max2
+ }
+ var best *DirEntry
+ if best1 != nil {
+ best = best1
+ if best2 != nil {
+ list2 = append(list2, *best2)
+ }
+ } else {
+ best = best2
+ }
+ var list []DirEntry
+ list = append(list, list1...)
+ list = append(list, list2...)
+ for _, v := range dir.gopath {
+ max3, best3, list3 := FindDir(v, name)
+ if max3 > maxHeight {
+ maxHeight = max3
+ }
+ if best == nil {
+ best = best3
+ }
+ list = append(list, list3...)
+ }
+ return &Info{name, best, &DirList{maxHeight, list}}
+}
+
+func FindDir(dir *Directory, pkgname string) (maxHeight int, best *DirEntry, list []DirEntry) {
+ if dir == nil {
+ return
+ }
+ dirList := dir.listing(true)
+ max := len(dirList.List)
+ maxHeight = dirList.MaxHeight
+
+ for i := 0; i < max; i++ {
+ name := dirList.List[i].Name
+ path := filepath.ToSlash(dirList.List[i].Path)
+ if name == pkgname || path == pkgname {
+ best = &dirList.List[i]
+ } else if strings.Contains(path, pkgname) {
+ list = append(list, dirList.List[i])
+ }
+ }
+ return
+}
+
+func appendList(list1, list2 []DirEntry) []DirEntry {
+ list := list1
+ max := len(list2)
+ for i := 0; i < max; i++ {
+ list = append(list, list2[i])
+ }
+ return list
+}
+
+func NewListInfo(root string) *Info {
+ dir := newDirectory(root, nil, -1)
+ if dir == nil {
+ return nil
+ }
+ return &Info{"", nil, dir.listing(true)}
+}
+
+func FindPkgInfo(root string, pkgname string) *Info {
+ dir := newDirectory(root, nil, -1)
+ if dir == nil {
+ return nil
+ }
+ dirList := dir.listing(true)
+ if pkgname == "*" {
+ return &Info{pkgname, nil, dirList}
+ }
+ var best DirEntry
+ var list []DirEntry
+ max := len(dirList.List)
+ for i := 0; i < max; i++ {
+ name := dirList.List[i].Name
+ path := filepath.ToSlash(dirList.List[i].Path)
+ if name == pkgname || path == pkgname {
+ best = dirList.List[i]
+ } else if strings.Contains(path, pkgname) {
+ list = append(list, dirList.List[i])
+ }
+ }
+ return &Info{pkgname, &best, &DirList{dirList.MaxHeight, list}}
+}
+
+func (info *Info) GetPkgList(name, templateData string) []byte {
+ data := readTemplateData(name, templateData)
+ return applyTemplate(data, "pkglist", info)
+}
+
+var listHTML = `
+
+Need more packages? The
+Package Dashboard
+provides a list of goinstallable packages.
+
+Subdirectories
+
+{{with .Dirs}}
+
+
+
+ Name
+
+ Synopsis
+
+ {{range .List}}
+
+ {{repeat " " .Depth}}
+ {{html .Name}}
+
+ {{html .Synopsis}}
+
+ {{end}}
+
+
+{{end}}`
+
+var listText = `$list
+{{with .Dirs}}
+{{range .List}}{{.Path }}
+{{end}}
+{{end}}`
+
+var listLite = `$list{{with .Dirs}}{{range .List}},{{.Path}}{{end}}{{end}}`
+
+var findHTML = `
+
+Need more packages? The
+Package Dashboard
+provides a list of goinstallable packages.
+
+Subdirectories
+
+
+ Best
+
+ Synopsis
+ {{with .Best}}
+
+ {{.Path}}
+
+ {{html .Synopsis}}
+
+ {{end}}
+ {{with .Dirs}}
+
+ Match
+
+ Synopsis
+
+ {{range .List}}
+
+ {{.Path}}
+
+ {{html .Synopsis}}
+
+ {{end}}
+
+
+{{end}}`
+
+var findText = `$best
+{{with .Best}}{{.Path}}{{end}}
+$list
+{{with .Dirs}}{{range .List}}{{.Path}}
+{{end}}{{end}}`
+
+var findLite = `$find,{{with .Best}}{{.Path}}{{end}}{{with .Dirs}}{{range .List}},{{.Path}}{{end}}{{end}}`
diff --git a/vendor/github.com/visualfc/gotools/docview/docx.go b/vendor/github.com/visualfc/gotools/docview/docx.go
new file mode 100644
index 0000000..01a9355
--- /dev/null
+++ b/vendor/github.com/visualfc/gotools/docview/docx.go
@@ -0,0 +1,668 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package doc extracts source code documentation from a Go AST.
+package docview
+
+import (
+ "go/ast"
+ "go/token"
+ "regexp"
+ "sort"
+ "strconv"
+)
+
+// ----------------------------------------------------------------------------
+
+type typeDoc struct {
+ // len(decl.Specs) == 1, and the element type is *ast.TypeSpec
+ // if the type declaration hasn't been seen yet, decl is nil
+ decl *ast.GenDecl
+ // values, factory functions, and methods associated with the type
+ values []*ast.GenDecl // consts and vars
+ factories map[string]*ast.FuncDecl
+ methods map[string]*ast.FuncDecl
+}
+
+// docReader accumulates documentation for a single package.
+// It modifies the AST: Comments (declaration documentation)
+// that have been collected by the DocReader are set to nil
+// in the respective AST nodes so that they are not printed
+// twice (once when printing the documentation and once when
+// printing the corresponding AST node).
+//
+type docReader struct {
+ doc *ast.CommentGroup // package documentation, if any
+ pkgName string
+ showAll bool
+ values []*ast.GenDecl // consts and vars
+ types map[string]*typeDoc
+ funcs map[string]*ast.FuncDecl
+ imports map[string]int
+ bugs []*ast.CommentGroup
+}
+
+func (doc *docReader) init(pkgName string, showAll bool) {
+ doc.pkgName = pkgName
+ doc.showAll = showAll
+ doc.imports = make(map[string]int)
+ doc.types = make(map[string]*typeDoc)
+ doc.funcs = make(map[string]*ast.FuncDecl)
+}
+
+func (doc *docReader) addDoc(comments *ast.CommentGroup) {
+ if doc.doc == nil {
+ // common case: just one package comment
+ doc.doc = comments
+ return
+ }
+
+ // More than one package comment: Usually there will be only
+ // one file with a package comment, but it's better to collect
+ // all comments than drop them on the floor.
+ // (This code isn't particularly clever - no amortized doubling is
+ // used - but this situation occurs rarely and is not time-critical.)
+ n1 := len(doc.doc.List)
+ n2 := len(comments.List)
+ list := make([]*ast.Comment, n1+1+n2) // + 1 for separator line
+ copy(list, doc.doc.List)
+ list[n1] = &ast.Comment{token.NoPos, "//"} // separator line
+ copy(list[n1+1:], comments.List)
+ doc.doc = &ast.CommentGroup{list}
+}
+
+func (doc *docReader) addType(decl *ast.GenDecl) {
+ spec := decl.Specs[0].(*ast.TypeSpec)
+ typ := doc.lookupTypeDoc(spec.Name.Name)
+ // typ should always be != nil since declared types
+ // are always named - be conservative and check
+ if typ != nil {
+ // a type should be added at most once, so typ.decl
+ // should be nil - if it isn't, simply overwrite it
+ typ.decl = decl
+ }
+}
+
+func (doc *docReader) lookupTypeDoc(name string) *typeDoc {
+ if name == "" {
+ return nil // no type docs for anonymous types
+ }
+ if tdoc, found := doc.types[name]; found {
+ return tdoc
+ }
+ // type wasn't found - add one without declaration
+ tdoc := &typeDoc{nil, nil, make(map[string]*ast.FuncDecl), make(map[string]*ast.FuncDecl)}
+ doc.types[name] = tdoc
+ return tdoc
+}
+
+func docBaseTypeName(typ ast.Expr, showAll bool) string {
+ switch t := typ.(type) {
+ case *ast.Ident:
+ // if the type is not exported, the effect to
+ // a client is as if there were no type name
+ if showAll || t.IsExported() {
+ return t.Name
+ }
+ case *ast.StarExpr:
+ return docBaseTypeName(t.X, showAll)
+ }
+ return ""
+}
+
+func (doc *docReader) addValue(decl *ast.GenDecl) {
+ // determine if decl should be associated with a type
+ // Heuristic: For each typed entry, determine the type name, if any.
+ // If there is exactly one type name that is sufficiently
+ // frequent, associate the decl with the respective type.
+ domName := ""
+ domFreq := 0
+ prev := ""
+ for _, s := range decl.Specs {
+ if v, ok := s.(*ast.ValueSpec); ok {
+ name := ""
+ switch {
+ case v.Type != nil:
+ // a type is present; determine its name
+ name = docBaseTypeName(v.Type, doc.showAll)
+ case decl.Tok == token.CONST:
+ // no type is present but we have a constant declaration;
+ // use the previous type name (w/o more type information
+ // we cannot handle the case of unnamed variables with
+ // initializer expressions except for some trivial cases)
+ name = prev
+ }
+ if name != "" {
+ // entry has a named type
+ if domName != "" && domName != name {
+ // more than one type name - do not associate
+ // with any type
+ domName = ""
+ break
+ }
+ domName = name
+ domFreq++
+ }
+ prev = name
+ }
+ }
+
+ // determine values list
+ const threshold = 0.75
+ values := &doc.values
+ if domName != "" && domFreq >= int(float64(len(decl.Specs))*threshold) {
+ // typed entries are sufficiently frequent
+ typ := doc.lookupTypeDoc(domName)
+ if typ != nil {
+ values = &typ.values // associate with that type
+ }
+ }
+
+ *values = append(*values, decl)
+}
+
+// Helper function to set the table entry for function f. Makes sure that
+// at least one f with associated documentation is stored in table, if there
+// are multiple f's with the same name.
+func setFunc(table map[string]*ast.FuncDecl, f *ast.FuncDecl) {
+ name := f.Name.Name
+ if g, exists := table[name]; exists && g.Doc != nil {
+ // a function with the same name has already been registered;
+ // since it has documentation, assume f is simply another
+ // implementation and ignore it
+ // TODO(gri) consider collecting all functions, or at least
+ // all comments
+ return
+ }
+ // function doesn't exist or has no documentation; use f
+ table[name] = f
+}
+
+func (doc *docReader) addFunc(fun *ast.FuncDecl) {
+ name := fun.Name.Name
+
+ // determine if it should be associated with a type
+ if fun.Recv != nil {
+ // method
+ typ := doc.lookupTypeDoc(docBaseTypeName(fun.Recv.List[0].Type, doc.showAll))
+ if typ != nil {
+ // exported receiver type
+ setFunc(typ.methods, fun)
+ }
+ // otherwise don't show the method
+ // TODO(gri): There may be exported methods of non-exported types
+ // that can be called because of exported values (consts, vars, or
+ // function results) of that type. Could determine if that is the
+ // case and then show those methods in an appropriate section.
+ return
+ }
+
+ // perhaps a factory function
+ // determine result type, if any
+ if fun.Type.Results.NumFields() >= 1 {
+ res := fun.Type.Results.List[0]
+ if len(res.Names) <= 1 {
+ // exactly one (named or anonymous) result associated
+ // with the first type in result signature (there may
+ // be more than one result)
+ tname := docBaseTypeName(res.Type, doc.showAll)
+ typ := doc.lookupTypeDoc(tname)
+ if typ != nil {
+ // named and exported result type
+
+ // Work-around for failure of heuristic: In package os
+ // too many functions are considered factory functions
+ // for the Error type. Eliminate manually for now as
+ // this appears to be the only important case in the
+ // current library where the heuristic fails.
+ if doc.pkgName == "os" && tname == "Error" &&
+ name != "NewError" && name != "NewSyscallError" {
+ // not a factory function for os.Error
+ setFunc(doc.funcs, fun) // treat as ordinary function
+ return
+ }
+
+ setFunc(typ.factories, fun)
+ return
+ }
+ }
+ }
+
+ // ordinary function
+ setFunc(doc.funcs, fun)
+}
+
+func (doc *docReader) addDecl(decl ast.Decl) {
+ switch d := decl.(type) {
+ case *ast.GenDecl:
+ if len(d.Specs) > 0 {
+ switch d.Tok {
+ case token.IMPORT:
+ // imports are handled individually
+ for _, spec := range d.Specs {
+ if s, ok := spec.(*ast.ImportSpec); ok {
+ if import_, err := strconv.Unquote(s.Path.Value); err == nil {
+ doc.imports[import_] = 1
+ }
+ }
+ }
+ case token.CONST, token.VAR:
+ // constants and variables are always handled as a group
+ doc.addValue(d)
+ case token.TYPE:
+ // types are handled individually
+ for _, spec := range d.Specs {
+ // make a (fake) GenDecl node for this TypeSpec
+ // (we need to do this here - as opposed to just
+ // for printing - so we don't lose the GenDecl
+ // documentation)
+ //
+ // TODO(gri): Consider just collecting the TypeSpec
+ // node (and copy in the GenDecl.doc if there is no
+ // doc in the TypeSpec - this is currently done in
+ // makeTypeDocs below). Simpler data structures, but
+ // would lose GenDecl documentation if the TypeSpec
+ // has documentation as well.
+ doc.addType(&ast.GenDecl{d.Doc, d.Pos(), token.TYPE, token.NoPos, []ast.Spec{spec}, token.NoPos})
+ // A new GenDecl node is created, no need to nil out d.Doc.
+ }
+ }
+ }
+ case *ast.FuncDecl:
+ doc.addFunc(d)
+ }
+}
+
+func copyCommentList(list []*ast.Comment) []*ast.Comment {
+ return append([]*ast.Comment(nil), list...)
+}
+
+var (
+ bug_markers = regexp.MustCompile("^/[/*][ \t]*BUG\\(.*\\):[ \t]*") // BUG(uid):
+ bug_content = regexp.MustCompile("[^ \n\r\t]+") // at least one non-whitespace char
+)
+
+// addFile adds the AST for a source file to the docReader.
+// Adding the same AST multiple times is a no-op.
+//
+func (doc *docReader) addFile(src *ast.File) {
+ // add package documentation
+ if src.Doc != nil {
+ doc.addDoc(src.Doc)
+ src.Doc = nil // doc consumed - remove from ast.File node
+ }
+
+ // add all declarations
+ for _, decl := range src.Decls {
+ doc.addDecl(decl)
+ }
+
+ // collect BUG(...) comments
+ for _, c := range src.Comments {
+ text := c.List[0].Text
+ if m := bug_markers.FindStringIndex(text); m != nil {
+ // found a BUG comment; maybe empty
+ if btxt := text[m[1]:]; bug_content.MatchString(btxt) {
+ // non-empty BUG comment; collect comment without BUG prefix
+ list := copyCommentList(c.List)
+ list[0].Text = text[m[1]:]
+ doc.bugs = append(doc.bugs, &ast.CommentGroup{list})
+ }
+ }
+ }
+ src.Comments = nil // consumed unassociated comments - remove from ast.File node
+}
+
+func NewFileDoc(file *ast.File, showAll bool) *PackageDoc {
+ var r docReader
+ r.init(file.Name.Name, showAll)
+ r.addFile(file)
+ return r.newDoc("", nil)
+}
+
+func NewPackageDoc(pkg *ast.Package, importpath string, showAll bool) *PackageDoc {
+ var r docReader
+ r.init(pkg.Name, showAll)
+ filenames := make([]string, len(pkg.Files))
+ i := 0
+ for filename, f := range pkg.Files {
+ r.addFile(f)
+ filenames[i] = filename
+ i++
+ }
+ return r.newDoc(importpath, filenames)
+}
+
+// ----------------------------------------------------------------------------
+// Conversion to external representation
+
+// ValueDoc is the documentation for a group of declared
+// values, either vars or consts.
+//
+type ValueDoc struct {
+ Doc string
+ Decl *ast.GenDecl
+ order int
+}
+
+type sortValueDoc []*ValueDoc
+
+func (p sortValueDoc) Len() int { return len(p) }
+func (p sortValueDoc) Swap(i, j int) { p[i], p[j] = p[j], p[i] }
+
+func declName(d *ast.GenDecl) string {
+ if len(d.Specs) != 1 {
+ return ""
+ }
+
+ switch v := d.Specs[0].(type) {
+ case *ast.ValueSpec:
+ return v.Names[0].Name
+ case *ast.TypeSpec:
+ return v.Name.Name
+ }
+
+ return ""
+}
+
+func (p sortValueDoc) Less(i, j int) bool {
+ // sort by name
+ // pull blocks (name = "") up to top
+ // in original order
+ if ni, nj := declName(p[i].Decl), declName(p[j].Decl); ni != nj {
+ return ni < nj
+ }
+ return p[i].order < p[j].order
+}
+
+func makeValueDocs(list []*ast.GenDecl, tok token.Token) []*ValueDoc {
+ d := make([]*ValueDoc, len(list)) // big enough in any case
+ n := 0
+ for i, decl := range list {
+ if decl.Tok == tok {
+ d[n] = &ValueDoc{decl.Doc.Text(), decl, i}
+ n++
+ decl.Doc = nil // doc consumed - removed from AST
+ }
+ }
+ d = d[0:n]
+ sort.Sort(sortValueDoc(d))
+ return d
+}
+
+// FuncDoc is the documentation for a func declaration,
+// either a top-level function or a method function.
+//
+type FuncDoc struct {
+ Doc string
+ Recv ast.Expr // TODO(rsc): Would like string here
+ Name string
+ Decl *ast.FuncDecl
+}
+
+type sortFuncDoc []*FuncDoc
+
+func (p sortFuncDoc) Len() int { return len(p) }
+func (p sortFuncDoc) Swap(i, j int) { p[i], p[j] = p[j], p[i] }
+func (p sortFuncDoc) Less(i, j int) bool { return p[i].Name < p[j].Name }
+
+func makeFuncDocs(m map[string]*ast.FuncDecl) []*FuncDoc {
+ d := make([]*FuncDoc, len(m))
+ i := 0
+ for _, f := range m {
+ doc := new(FuncDoc)
+ doc.Doc = f.Doc.Text()
+ f.Doc = nil // doc consumed - remove from ast.FuncDecl node
+ if f.Recv != nil {
+ doc.Recv = f.Recv.List[0].Type
+ }
+ doc.Name = f.Name.Name
+ doc.Decl = f
+ d[i] = doc
+ i++
+ }
+ sort.Sort(sortFuncDoc(d))
+ return d
+}
+
+// TypeDoc is the documentation for a declared type.
+// Consts and Vars are sorted lists of constants and variables of (mostly) that type.
+// Factories is a sorted list of factory functions that return that type.
+// Methods is a sorted list of method functions on that type.
+type TypeDoc struct {
+ Doc string
+ Type *ast.TypeSpec
+ Consts []*ValueDoc
+ Vars []*ValueDoc
+ Funcs []*FuncDoc
+ Methods []*FuncDoc
+ Decl *ast.GenDecl
+ order int
+}
+
+type sortTypeDoc []*TypeDoc
+
+func (p sortTypeDoc) Len() int { return len(p) }
+func (p sortTypeDoc) Swap(i, j int) { p[i], p[j] = p[j], p[i] }
+func (p sortTypeDoc) Less(i, j int) bool {
+ // sort by name
+ // pull blocks (name = "") up to top
+ // in original order
+ if ni, nj := p[i].Type.Name.Name, p[j].Type.Name.Name; ni != nj {
+ return ni < nj
+ }
+ return p[i].order < p[j].order
+}
+
+// NOTE(rsc): This would appear not to be correct for type ( )
+// blocks, but the doc extractor above has split them into
+// individual declarations.
+func (doc *docReader) makeTypeDocs(m map[string]*typeDoc) []*TypeDoc {
+ d := make([]*TypeDoc, len(m))
+ i := 0
+ for _, old := range m {
+ // all typeDocs should have a declaration associated with
+ // them after processing an entire package - be conservative
+ // and check
+ if decl := old.decl; decl != nil {
+ typespec := decl.Specs[0].(*ast.TypeSpec)
+ t := new(TypeDoc)
+ doc := typespec.Doc
+ typespec.Doc = nil // doc consumed - remove from ast.TypeSpec node
+ if doc == nil {
+ // no doc associated with the spec, use the declaration doc, if any
+ doc = decl.Doc
+ }
+ decl.Doc = nil // doc consumed - remove from ast.Decl node
+ t.Doc = doc.Text()
+ t.Type = typespec
+ t.Consts = makeValueDocs(old.values, token.CONST)
+ t.Vars = makeValueDocs(old.values, token.VAR)
+ t.Funcs = makeFuncDocs(old.factories)
+ t.Methods = makeFuncDocs(old.methods)
+ t.Decl = old.decl
+ t.order = i
+ d[i] = t
+ i++
+ } else {
+ // no corresponding type declaration found - move any associated
+ // values, factory functions, and methods back to the top-level
+ // so that they are not lost (this should only happen if a package
+ // file containing the explicit type declaration is missing or if
+ // an unqualified type name was used after a "." import)
+ // 1) move values
+ doc.values = append(doc.values, old.values...)
+ // 2) move factory functions
+ for name, f := range old.factories {
+ doc.funcs[name] = f
+ }
+ // 3) move methods
+ for name, f := range old.methods {
+ // don't overwrite functions with the same name
+ if _, found := doc.funcs[name]; !found {
+ doc.funcs[name] = f
+ }
+ }
+ }
+ }
+ d = d[0:i] // some types may have been ignored
+ sort.Sort(sortTypeDoc(d))
+ return d
+}
+
+func makeBugDocs(list []*ast.CommentGroup) []string {
+ d := make([]string, len(list))
+ for i, g := range list {
+ d[i] = g.Text()
+ }
+ return d
+}
+
+// PackageDoc is the documentation for an entire package.
+//
+type PackageDoc struct {
+ PackageName string
+ ImportPath string
+ Imports []string
+ Filenames []string
+ Doc string
+ Consts []*ValueDoc
+ Types []*TypeDoc
+ Vars []*ValueDoc
+ Funcs []*FuncDoc
+ Bugs []string
+}
+
+// newDoc returns the accumulated documentation for the package.
+//
+func (doc *docReader) newDoc(importpath string, filenames []string) *PackageDoc {
+ p := new(PackageDoc)
+ p.PackageName = doc.pkgName
+ p.ImportPath = importpath
+ sort.Strings(filenames)
+ p.Filenames = filenames
+ p.Doc = doc.doc.Text()
+ p.Imports = sortedKeys(doc.imports)
+ // makeTypeDocs may extend the list of doc.values and
+ // doc.funcs and thus must be called before any other
+ // function consuming those lists
+ p.Types = doc.makeTypeDocs(doc.types)
+ p.Consts = makeValueDocs(doc.values, token.CONST)
+ p.Vars = makeValueDocs(doc.values, token.VAR)
+ p.Funcs = makeFuncDocs(doc.funcs)
+ p.Bugs = makeBugDocs(doc.bugs)
+ return p
+}
+
+func sortedKeys(m map[string]int) []string {
+ list := make([]string, len(m))
+ i := 0
+ for key := range m {
+ list[i] = key
+ i++
+ }
+ sort.Strings(list)
+ return list
+}
+
+// ----------------------------------------------------------------------------
+// Filtering by name
+
+type Filter func(string) bool
+
+func matchFields(fields *ast.FieldList, f Filter) bool {
+ if fields != nil {
+ for _, field := range fields.List {
+ for _, name := range field.Names {
+ if f(name.Name) {
+ return true
+ }
+ }
+ }
+ }
+ return false
+}
+
+func matchDecl(d *ast.GenDecl, f Filter) bool {
+ for _, d := range d.Specs {
+ switch v := d.(type) {
+ case *ast.ValueSpec:
+ for _, name := range v.Names {
+ if f(name.Name) {
+ return true
+ }
+ }
+ case *ast.TypeSpec:
+ if f(v.Name.Name) {
+ return true
+ }
+ switch t := v.Type.(type) {
+ case *ast.StructType:
+ if matchFields(t.Fields, f) {
+ return true
+ }
+ case *ast.InterfaceType:
+ if matchFields(t.Methods, f) {
+ return true
+ }
+ }
+ }
+ }
+ return false
+}
+
+func filterValueDocs(a []*ValueDoc, f Filter) []*ValueDoc {
+ w := 0
+ for _, vd := range a {
+ if matchDecl(vd.Decl, f) {
+ a[w] = vd
+ w++
+ }
+ }
+ return a[0:w]
+}
+
+func filterFuncDocs(a []*FuncDoc, f Filter) []*FuncDoc {
+ w := 0
+ for _, fd := range a {
+ if f(fd.Name) {
+ a[w] = fd
+ w++
+ }
+ }
+ return a[0:w]
+}
+
+func filterTypeDocs(a []*TypeDoc, f Filter) []*TypeDoc {
+ w := 0
+ for _, td := range a {
+ n := 0 // number of matches
+ if matchDecl(td.Decl, f) {
+ n = 1
+ } else {
+ // type name doesn't match, but we may have matching consts, vars, factories or methods
+ td.Consts = filterValueDocs(td.Consts, f)
+ td.Vars = filterValueDocs(td.Vars, f)
+ td.Funcs = filterFuncDocs(td.Funcs, f)
+ td.Methods = filterFuncDocs(td.Methods, f)
+ n += len(td.Consts) + len(td.Vars) + len(td.Funcs) + len(td.Methods)
+ }
+ if n > 0 {
+ a[w] = td
+ w++
+ }
+ }
+ return a[0:w]
+}
+
+// Filter eliminates documentation for names that don't pass through the filter f.
+// TODO: Recognize "Type.Method" as a name.
+//
+func (p *PackageDoc) Filter(f Filter) {
+ p.Consts = filterValueDocs(p.Consts, f)
+ p.Vars = filterValueDocs(p.Vars, f)
+ p.Types = filterTypeDocs(p.Types, f)
+ p.Funcs = filterFuncDocs(p.Funcs, f)
+ p.Doc = "" // don't show top-level package doc
+}
diff --git a/vendor/github.com/visualfc/gotools/docview/filesystem.go b/vendor/github.com/visualfc/gotools/docview/filesystem.go
new file mode 100644
index 0000000..dc60649
--- /dev/null
+++ b/vendor/github.com/visualfc/gotools/docview/filesystem.go
@@ -0,0 +1,70 @@
+// Copyright 2011 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// This file defines types for abstract file system access and
+// provides an implementation accessing the file system of the
+// underlying OS.
+
+package docview
+
+import (
+ "fmt"
+ "io"
+ "io/ioutil"
+ "os"
+)
+
+// The FileSystem interface specifies the methods godoc is using
+// to access the file system for which it serves documentation.
+type FileSystem interface {
+ Open(path string) (io.ReadCloser, error)
+ Lstat(path string) (os.FileInfo, error)
+ Stat(path string) (os.FileInfo, error)
+ ReadDir(path string) ([]os.FileInfo, error)
+}
+
+// ReadFile reads the file named by path from fs and returns the contents.
+func ReadFile(fs FileSystem, path string) ([]byte, error) {
+ rc, err := fs.Open(path)
+ if err != nil {
+ return nil, err
+ }
+ defer rc.Close()
+ return ioutil.ReadAll(rc)
+}
+
+// ----------------------------------------------------------------------------
+// OS-specific FileSystem implementation
+
+var OS FileSystem = osFS{}
+
+// osFS is the OS-specific implementation of FileSystem
+type osFS struct{}
+
+func (osFS) Open(path string) (io.ReadCloser, error) {
+ f, err := os.Open(path)
+ if err != nil {
+ return nil, err
+ }
+ fi, err := f.Stat()
+ if err != nil {
+ return nil, err
+ }
+ if fi.IsDir() {
+ return nil, fmt.Errorf("Open: %s is a directory", path)
+ }
+ return f, nil
+}
+
+func (osFS) Lstat(path string) (os.FileInfo, error) {
+ return os.Lstat(path)
+}
+
+func (osFS) Stat(path string) (os.FileInfo, error) {
+ return os.Stat(path)
+}
+
+func (osFS) ReadDir(path string) ([]os.FileInfo, error) {
+ return ioutil.ReadDir(path) // is sorted
+}
diff --git a/vendor/github.com/visualfc/gotools/finddoc/finddoc.go b/vendor/github.com/visualfc/gotools/finddoc/finddoc.go
new file mode 100644
index 0000000..dfe2b75
--- /dev/null
+++ b/vendor/github.com/visualfc/gotools/finddoc/finddoc.go
@@ -0,0 +1,609 @@
+// Copyright 2013 The rspace Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Doc is a simple document printer that produces the doc comments for its
+// argument symbols, plus a link to the full documentation and a pointer to
+// the source. It has a more Go-like UI than godoc. It can also search for
+// symbols by looking in all packages, and case is ignored. For instance:
+// doc isupper
+// will find unicode.IsUpper.
+//
+// The -pkg flag retrieves package-level doc comments only.
+//
+// Usage:
+// doc pkg.name # "doc io.Writer"
+// doc pkg name # "doc fmt Printf"
+// doc name # "doc isupper" (finds unicode.IsUpper)
+// doc -pkg pkg # "doc fmt"
+//
+// The pkg is the last element of the package path;
+// no slashes (ast.Node not go/ast.Node).
+//
+// Flags
+// -c(onst) -f(unc) -i(nterface) -m(ethod) -s(truct) -t(ype) -v(ar)
+// restrict hits to declarations of the corresponding kind.
+// Flags
+// -doc -src -url
+// restrict printing to the documentation, source path, or godoc URL.
+package finddoc
+
+import (
+ "bytes"
+ "fmt"
+ "go/ast"
+ "go/parser"
+ "go/printer"
+ "go/token"
+ "os"
+ "path"
+ "path/filepath"
+ "regexp"
+ "runtime"
+ "strings"
+
+ "github.com/visualfc/gotools/command"
+ _ "golang.org/x/tools/go/gcimporter"
+ "golang.org/x/tools/go/types"
+)
+
+const usageDoc = `Find documentation for names.
+usage:
+ doc pkg.name # "doc io.Writer"
+ doc pkg name # "doc fmt Printf"
+ doc name # "doc isupper" finds unicode.IsUpper
+ doc -pkg pkg # "doc fmt"
+ doc -r expr # "doc -r '.*exported'"
+pkg is the last component of any package, e.g. fmt, parser
+name is the name of an exported symbol; case is ignored in matches.
+
+The name may also be a regular expression to select which names
+to match. In regular expression searches, case is ignored and
+the pattern must match the entire name, so ".?print" will match
+Print, Fprint and Sprint but not Fprintf.
+
+Flags
+ -c(onst) -f(unc) -i(nterface) -m(ethod) -s(truct) -t(ype) -v(ar)
+restrict hits to declarations of the corresponding kind.
+Flags
+ -doc -src -url
+restrict printing to the documentation, source path, or godoc URL.
+Flag
+ -r
+takes a single argument (no package), a name or regular expression
+to search for in all packages.
+`
+
+var Command = &command.Command{
+ Run: runDoc,
+ UsageLine: "finddoc [pkg.name|pkg name|-pkg name]",
+ Short: "golang doc lookup",
+ Long: usageDoc,
+}
+
+var (
+ // If none is set, all are set.
+ docFlag bool
+ srcFlag bool
+ urlFlag bool
+ regexpFlag bool
+ matchWordFlag bool
+ matchCaseFlag bool
+ constantFlag bool
+ functionFlag bool
+ interfaceFlag bool
+ methodFlag bool
+ packageFlag bool
+ structFlag bool
+ typeFlag bool
+ variableFlag bool
+ urlHeadTag string
+)
+
+func init() {
+ Command.Flag.BoolVar(&docFlag, "doc", false, "restrict output to documentation only")
+ Command.Flag.BoolVar(&srcFlag, "src", false, "restrict output to source file only")
+ Command.Flag.BoolVar(&urlFlag, "url", false, "restrict output to godoc URL only")
+ Command.Flag.BoolVar(®expFlag, "r", false, "single argument is a regular expression for a name")
+ Command.Flag.BoolVar(&matchWordFlag, "word", false, "search match whole word")
+ Command.Flag.BoolVar(&matchCaseFlag, "case", false, "search match case")
+
+ Command.Flag.BoolVar(&constantFlag, "const", false, "show doc for consts only")
+ Command.Flag.BoolVar(&functionFlag, "func", false, "show doc for funcs only")
+ Command.Flag.BoolVar(&interfaceFlag, "interface", false, "show doc for interfaces only")
+ Command.Flag.BoolVar(&methodFlag, "method", false, "show doc for methods only")
+ Command.Flag.BoolVar(&packageFlag, "package", false, "show top-level package doc only")
+ Command.Flag.BoolVar(&structFlag, "struct", false, "show doc for structs only")
+ Command.Flag.BoolVar(&typeFlag, "type", false, "show doc for types only")
+ Command.Flag.BoolVar(&variableFlag, "var", false, "show doc for vars only")
+
+ Command.Flag.BoolVar(&constantFlag, "c", false, "alias for -const")
+ Command.Flag.BoolVar(&functionFlag, "f", false, "alias for -func")
+ Command.Flag.BoolVar(&interfaceFlag, "i", false, "alias for -interface")
+ Command.Flag.BoolVar(&methodFlag, "m", false, "alias for -method")
+ Command.Flag.BoolVar(&packageFlag, "pkg", false, "alias for -package")
+ Command.Flag.BoolVar(&structFlag, "s", false, "alias for -struct")
+ Command.Flag.BoolVar(&typeFlag, "t", false, "alias for -type")
+ Command.Flag.BoolVar(&variableFlag, "v", false, "alias for -var")
+
+ Command.Flag.StringVar(&urlHeadTag, "urltag", "", "url head tag, liteide provate")
+}
+
+func runDoc(cmd *command.Command, args []string) error {
+ if !(constantFlag || functionFlag || interfaceFlag || methodFlag || packageFlag || structFlag || typeFlag || variableFlag) { // none set
+ constantFlag = true
+ functionFlag = true
+ methodFlag = true
+ // Not package! It's special.
+ typeFlag = true
+ variableFlag = true
+ }
+ if !(docFlag || srcFlag || urlFlag) {
+ docFlag = true
+ srcFlag = true
+ urlFlag = true
+ }
+ var pkg, name string
+ switch len(args) {
+ case 1:
+ if packageFlag {
+ pkg = args[0]
+ } else if regexpFlag {
+ name = args[0]
+ } else if strings.Contains(args[0], ".") {
+ pkg, name = split(args[0])
+ } else {
+ name = args[0]
+ }
+ case 2:
+ if packageFlag {
+ cmd.Usage()
+ }
+ pkg, name = args[0], args[1]
+ default:
+ cmd.Usage()
+ return os.ErrInvalid
+ }
+ if strings.Contains(pkg, "/") {
+ fmt.Fprintf(os.Stderr, "doc: package name cannot contain slash (TODO)\n")
+ os.Exit(2)
+ }
+ for _, path := range Paths(pkg) {
+ lookInDirectory(path, name)
+ }
+ return nil
+}
+
+var slash = string(filepath.Separator)
+var slashDot = string(filepath.Separator) + "."
+var goRootSrcPkg = filepath.Join(runtime.GOROOT(), "src", "pkg")
+var goRootSrcCmd = filepath.Join(runtime.GOROOT(), "src", "cmd")
+var goPaths = SplitGopath()
+
+func split(arg string) (pkg, name string) {
+ dot := strings.IndexRune(arg, '.') // We know there's one there.
+ return arg[0:dot], arg[dot+1:]
+}
+
+func Paths(pkg string) []string {
+ pkgs := pathsFor(runtime.GOROOT(), pkg)
+ for _, root := range goPaths {
+ pkgs = append(pkgs, pathsFor(root, pkg)...)
+ }
+ return pkgs
+}
+
+func SplitGopath() []string {
+ gopath := os.Getenv("GOPATH")
+ if gopath == "" {
+ return nil
+ }
+ return strings.Split(gopath, string(os.PathListSeparator))
+}
+
+// pathsFor recursively walks the tree looking for possible directories for the package:
+// those whose basename is pkg.
+func pathsFor(root, pkg string) []string {
+ root = path.Join(root, "src")
+ pkgPaths := make([]string, 0, 10)
+ visit := func(pathName string, f os.FileInfo, err error) error {
+ if err != nil {
+ return nil
+ }
+ // One package per directory. Ignore the files themselves.
+ if !f.IsDir() {
+ return nil
+ }
+ // No .hg or other dot nonsense please.
+ if strings.Contains(pathName, slashDot) {
+ return filepath.SkipDir
+ }
+ // Is the last element of the path correct
+ if pkg == "" || filepath.Base(pathName) == pkg {
+ pkgPaths = append(pkgPaths, pathName)
+ }
+ return nil
+ }
+
+ filepath.Walk(root, visit)
+ return pkgPaths
+}
+
+// lookInDirectory looks in the package (if any) in the directory for the named exported identifier.
+func lookInDirectory(directory, name string) {
+ fset := token.NewFileSet()
+ pkgs, _ := parser.ParseDir(fset, directory, nil, parser.ParseComments) // Ignore the error.
+ for _, pkg := range pkgs {
+ if pkg.Name == "main" || strings.HasSuffix(pkg.Name, "_test") {
+ continue
+ }
+ doPackage(pkg, fset, name)
+ }
+}
+
+// prefixDirectory places the directory name on the beginning of each name in the list.
+func prefixDirectory(directory string, names []string) {
+ if directory != "." {
+ for i, name := range names {
+ names[i] = filepath.Join(directory, name)
+ }
+ }
+}
+
+// File is a wrapper for the state of a file used in the parser.
+// The parse tree walkers are all methods of this type.
+type File struct {
+ fset *token.FileSet
+ name string // Name of file.
+ ident string // Identifier we are searching for.
+ lowerIdent string // lower ident
+ regexp *regexp.Regexp
+ pathPrefix string // Prefix from GOROOT/GOPATH.
+ urlPrefix string // Start of corresponding URL for golang.org or godoc.org.
+ file *ast.File
+ comments ast.CommentMap
+ defs map[*ast.Ident]types.Object
+ doPrint bool
+ found bool
+ allFiles []*File // All files in the package.
+}
+
+// doPackage analyzes the single package constructed from the named files, looking for
+// the definition of ident.
+func doPackage(pkg *ast.Package, fset *token.FileSet, ident string) {
+ var files []*File
+ found := false
+ for name, astFile := range pkg.Files {
+ if packageFlag && astFile.Doc == nil {
+ continue
+ }
+ file := &File{
+ fset: fset,
+ name: name,
+ ident: ident,
+ lowerIdent: strings.ToLower(ident),
+ file: astFile,
+ comments: ast.NewCommentMap(fset, astFile, astFile.Comments),
+ }
+ if regexpFlag && regexp.QuoteMeta(ident) != ident {
+ // It's a regular expression.
+ var err error
+ file.regexp, err = regexp.Compile("^(?i:" + ident + ")$")
+ if err != nil {
+ fmt.Fprintf(os.Stderr, "regular expression `%s`:", err)
+ os.Exit(2)
+ }
+ }
+ switch {
+ case strings.HasPrefix(name, goRootSrcPkg):
+ file.urlPrefix = "http://golang.org/pkg"
+ file.pathPrefix = goRootSrcPkg
+ case strings.HasPrefix(name, goRootSrcCmd):
+ file.urlPrefix = "http://golang.org/cmd"
+ file.pathPrefix = goRootSrcCmd
+ default:
+ file.urlPrefix = "http://godoc.org"
+ for _, path := range goPaths {
+ p := filepath.Join(path, "src")
+ if strings.HasPrefix(name, p) {
+ file.pathPrefix = p
+ break
+ }
+ }
+ }
+ file.urlPrefix = urlHeadTag + file.urlPrefix
+ files = append(files, file)
+ if found {
+ continue
+ }
+ file.doPrint = false
+ if packageFlag {
+ file.pkgComments()
+ } else {
+ ast.Walk(file, file.file)
+ if file.found {
+ found = true
+ }
+ }
+ }
+
+ if !found {
+ return
+ }
+
+ // By providing the Context with our own error function, it will continue
+ // past the first error. There is no need for that function to do anything.
+ config := types.Config{
+ Error: func(error) {},
+ }
+ info := &types.Info{
+ Defs: make(map[*ast.Ident]types.Object),
+ }
+ path := ""
+ var astFiles []*ast.File
+ for name, astFile := range pkg.Files {
+ if path == "" {
+ path = name
+ }
+ astFiles = append(astFiles, astFile)
+ }
+ config.Check(path, fset, astFiles, info) // Ignore errors.
+
+ // We need to search all files for methods, so record the full list in each file.
+ for _, file := range files {
+ file.allFiles = files
+ }
+ for _, file := range files {
+ file.doPrint = true
+ file.defs = info.Defs
+ if packageFlag {
+ file.pkgComments()
+ } else {
+ ast.Walk(file, file.file)
+ }
+ }
+}
+
+// Visit implements the ast.Visitor interface.
+func (f *File) Visit(node ast.Node) ast.Visitor {
+ switch n := node.(type) {
+ case *ast.GenDecl:
+ // Variables, constants, types.
+ for _, spec := range n.Specs {
+ switch spec := spec.(type) {
+ case *ast.ValueSpec:
+ if constantFlag && n.Tok == token.CONST || variableFlag && n.Tok == token.VAR {
+ for _, ident := range spec.Names {
+ if f.match(ident.Name) {
+ f.printNode(n, ident, f.nameURL(ident.Name))
+ break
+ }
+ }
+ }
+ case *ast.TypeSpec:
+ // If there is only one Spec, there are probably no parens and the
+ // comment we want appears before the type keyword, bound to
+ // the GenDecl. If the Specs are parenthesized, the comment we want
+ // is bound to the Spec. Hence we dig into the GenDecl to the Spec,
+ // but only if there are no parens.
+ node := ast.Node(n)
+ if n.Lparen.IsValid() {
+ node = spec
+ }
+ if f.match(spec.Name.Name) {
+ if typeFlag {
+ f.printNode(node, spec.Name, f.nameURL(spec.Name.Name))
+ } else {
+ switch spec.Type.(type) {
+ case *ast.InterfaceType:
+ if interfaceFlag {
+ f.printNode(node, spec.Name, f.nameURL(spec.Name.Name))
+ }
+ case *ast.StructType:
+ if structFlag {
+ f.printNode(node, spec.Name, f.nameURL(spec.Name.Name))
+ }
+ }
+ }
+ if f.doPrint && f.defs[spec.Name] != nil && f.defs[spec.Name].Type() != nil {
+ ms := types.NewMethodSet(f.defs[spec.Name].Type()) //.Type().MethodSet()
+ if ms.Len() == 0 {
+ ms = types.NewMethodSet(types.NewPointer(f.defs[spec.Name].Type())) //.MethodSet()
+ }
+ f.methodSet(ms)
+ }
+ }
+ case *ast.ImportSpec:
+ continue // Don't care.
+ }
+ }
+ case *ast.FuncDecl:
+ // Methods, top-level functions.
+ if f.match(n.Name.Name) {
+ n.Body = nil // Do not print the function body.
+ if methodFlag && n.Recv != nil {
+ f.printNode(n, n.Name, f.methodURL(n.Recv.List[0].Type, n.Name.Name))
+ } else if functionFlag && n.Recv == nil {
+ f.printNode(n, n.Name, f.nameURL(n.Name.Name))
+ }
+ }
+ }
+ return f
+}
+
+func (f *File) match(name string) bool {
+ // name must be exported.
+ if !ast.IsExported(name) {
+ return false
+ }
+ if f.regexp == nil {
+ if matchWordFlag {
+ if matchCaseFlag {
+ return name == f.ident
+ }
+ return strings.ToLower(name) == f.lowerIdent
+ } else {
+ if matchCaseFlag {
+ return strings.Contains(name, f.ident)
+ }
+ return strings.Contains(strings.ToLower(name), f.lowerIdent)
+ }
+ }
+ return f.regexp.MatchString(name)
+}
+
+func (f *File) printNode(node, ident ast.Node, url string) {
+ if !f.doPrint {
+ f.found = true
+ return
+ }
+ fmt.Printf("%s%s%s", url, f.sourcePos(f.fset.Position(ident.Pos())), f.docs(node))
+}
+
+func (f *File) docs(node ast.Node) []byte {
+ if !docFlag {
+ return nil
+ }
+ commentedNode := printer.CommentedNode{Node: node}
+ if comments := f.comments.Filter(node).Comments(); comments != nil {
+ commentedNode.Comments = comments
+ }
+ var b bytes.Buffer
+ printer.Fprint(&b, f.fset, &commentedNode)
+ b.Write([]byte("\n\n")) // Add a blank line between entries if we print documentation.
+ return b.Bytes()
+}
+
+func (f *File) pkgComments() {
+ doc := f.file.Doc
+ if doc == nil {
+ return
+ }
+ url := ""
+ if urlFlag {
+ url = f.packageURL() + "\n"
+ }
+ docText := ""
+ if docFlag {
+ docText = fmt.Sprintf("package %s\n%s\n\n", f.file.Name.Name, doc.Text())
+ }
+ fmt.Printf("%s%s%s", url, f.sourcePos(f.fset.Position(doc.Pos())), docText)
+}
+
+func (f *File) packageURL() string {
+ s := strings.TrimPrefix(f.name, f.pathPrefix)
+ // Now we have a path with a final file name. Drop it.
+ if i := strings.LastIndex(s, slash); i > 0 {
+ s = s[:i+1]
+ }
+ return f.urlPrefix + s
+}
+
+func (f *File) packageName() string {
+ s := strings.TrimPrefix(f.name, f.pathPrefix)
+ // Now we have a path with a final file name. Drop it.
+ if i := strings.LastIndex(s, slash); i > 0 {
+ s = s[:i+1]
+ }
+ s = strings.Trim(s, slash)
+ return filepath.ToSlash(s)
+}
+
+func (f *File) sourcePos(posn token.Position) string {
+ if !srcFlag {
+ return ""
+ }
+ return fmt.Sprintf("%s:%d:\n", posn.Filename, posn.Line)
+}
+
+func (f *File) nameURL(name string) string {
+ if !urlFlag {
+ return ""
+ }
+ return fmt.Sprintf("%s#%s\n", f.packageURL(), name)
+}
+
+func (f *File) methodURL(typ ast.Expr, name string) string {
+ if !urlFlag {
+ return ""
+ }
+ var b bytes.Buffer
+ printer.Fprint(&b, f.fset, typ)
+ typeName := b.Bytes()
+ if len(typeName) > 0 && typeName[0] == '*' {
+ typeName = typeName[1:]
+ }
+ return fmt.Sprintf("%s#%s.%s\n", f.packageURL(), typeName, name)
+}
+
+// Here follows the code to find and print a method (actually a method set, because
+// we want to do only one redundant tree walk, not one per method).
+// It should be much easier than walking the whole tree again, but that's what we must do.
+// TODO.
+
+type method struct {
+ index int // Which doc to write. (Keeps the results sorted)
+ *types.Selection
+}
+
+type methodVisitor struct {
+ *File
+ methods []method
+ docs []string
+}
+
+func (f *File) methodSet(set *types.MethodSet) {
+ // Build the set of things we're looking for.
+ methods := make([]method, 0, set.Len())
+ docs := make([]string, set.Len())
+ for i := 0; i < set.Len(); i++ {
+ if ast.IsExported(set.At(i).Obj().Name()) {
+ m := method{
+ i,
+ set.At(i),
+ }
+ methods = append(methods, m)
+ }
+ }
+ if len(methods) == 0 {
+ return
+ }
+ // Collect the docs.
+ for _, file := range f.allFiles {
+ visitor := &methodVisitor{
+ File: file,
+ methods: methods,
+ docs: docs,
+ }
+ ast.Walk(visitor, file.file)
+ methods = visitor.methods
+ }
+ // Print them in order. The incoming method set is sorted by name.
+ for _, doc := range docs {
+ if doc != "" {
+ fmt.Print(doc)
+ }
+ }
+}
+
+// Visit implements the ast.Visitor interface.
+func (visitor *methodVisitor) Visit(node ast.Node) ast.Visitor {
+ switch n := node.(type) {
+ case *ast.FuncDecl:
+ for i, method := range visitor.methods {
+ // If this is the right one, the position of the name of its identifier will match.
+ if method.Obj().Pos() == n.Name.Pos() {
+ n.Body = nil // TODO. Ugly - don't print the function body.
+ visitor.docs[method.index] = fmt.Sprintf("%s", visitor.File.docs(n))
+ // If this was the last method, we're done.
+ if len(visitor.methods) == 1 {
+ return nil
+ }
+ // Drop this one from the list.
+ visitor.methods = append(visitor.methods[:i], visitor.methods[i+1:]...)
+ return visitor
+ }
+ }
+ }
+ return visitor
+}
diff --git a/vendor/github.com/visualfc/gotools/goapi/goapi.go b/vendor/github.com/visualfc/gotools/goapi/goapi.go
new file mode 100644
index 0000000..92721cc
--- /dev/null
+++ b/vendor/github.com/visualfc/gotools/goapi/goapi.go
@@ -0,0 +1,3774 @@
+// Copyright 2011 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Api computes the exported API of a set of Go packages.
+
+//modify 2013-2014 visualfc
+
+package goapi
+
+import (
+ "bufio"
+ "bytes"
+ "fmt"
+ "go/ast"
+ "go/build"
+ "go/doc"
+ "go/parser"
+ "go/printer"
+ "go/token"
+ "io"
+ "io/ioutil"
+ "log"
+ "os"
+ "os/exec"
+ "path"
+ "path/filepath"
+ "regexp"
+ "sort"
+ "strconv"
+ "strings"
+ "time"
+
+ "github.com/visualfc/gotools/command"
+)
+
+var Command = &command.Command{
+ Run: runApi,
+ UsageLine: "goapi",
+ Short: "golang api util",
+ Long: `golang api util`,
+}
+
+var apiVerbose bool
+var apiAllmethods bool
+var apiAlldecls bool
+var apiShowpos bool
+var apiSeparate string
+var apiImportParser bool
+var apiDefaultCtx bool
+var apiCustomCtx string
+var apiLookupInfo string
+var apiLookupStdin bool
+var apiOutput string
+
+func init() {
+ Command.Flag.BoolVar(&apiVerbose, "v", false, "verbose debugging")
+ Command.Flag.BoolVar(&apiAllmethods, "e", true, "extract for all embedded methods")
+ Command.Flag.BoolVar(&apiAlldecls, "a", false, "extract for all declarations")
+ Command.Flag.BoolVar(&apiShowpos, "pos", false, "addition token position")
+ Command.Flag.StringVar(&apiSeparate, "sep", ", ", "setup separators")
+ Command.Flag.BoolVar(&apiImportParser, "dep", true, "parser package imports")
+ Command.Flag.BoolVar(&apiDefaultCtx, "default_ctx", true, "extract for default context")
+ Command.Flag.StringVar(&apiCustomCtx, "custom_ctx", "", "optional comma-separated list of -[-cgo] to override default contexts.")
+ Command.Flag.StringVar(&apiLookupInfo, "cursor_info", "", "lookup cursor node info\"file.go:pos\"")
+ Command.Flag.BoolVar(&apiLookupStdin, "cursor_std", false, "cursor_info use stdin")
+ Command.Flag.StringVar(&apiOutput, "o", "", "output file")
+}
+
+func runApi(cmd *command.Command, args []string) error {
+ if len(args) == 0 && apiLookupInfo == "" {
+ cmd.Usage()
+ return os.ErrInvalid
+ }
+ if apiVerbose {
+ now := time.Now()
+ defer func() {
+ log.Println("time", time.Now().Sub(now))
+ }()
+ }
+
+ var pkgs []string
+ if len(args) > 0 {
+ if args[0] == "std" || args[0] == "all" {
+ out, err := exec.Command("go", "list", "-e", args[0]).Output()
+ if err != nil {
+ log.Fatal(err)
+ }
+ pkgs = strings.Fields(string(out))
+ } else {
+ pkgs = args
+ }
+ }
+ var curinfo CursorInfo
+ if apiLookupInfo != "" {
+ pos := strings.Index(apiLookupInfo, ":")
+ if pos != -1 {
+ curinfo.file = (apiLookupInfo)[:pos]
+ if i, err := strconv.Atoi((apiLookupInfo)[pos+1:]); err == nil {
+ curinfo.pos = token.Pos(i)
+ }
+ }
+ }
+
+ if len(pkgs) == 1 && curinfo.pos != token.NoPos {
+ curinfo.pkg = pkgs[0]
+ }
+
+ if apiLookupStdin {
+ src, err := ioutil.ReadAll(os.Stdin)
+ if err == nil {
+ curinfo.src = src
+ curinfo.std = true
+ }
+ }
+
+ if apiCustomCtx != "" {
+ apiDefaultCtx = false
+ setCustomContexts()
+ }
+
+ var features []string
+ w := NewWalker()
+ if curinfo.pkg != "" {
+ w.cursorInfo = &curinfo
+ }
+ w.sep = apiSeparate
+
+ if apiDefaultCtx {
+ w.context = &build.Default
+
+ for _, pkg := range pkgs {
+ w.wantedPkg[pkg] = true
+ }
+
+ for _, pkg := range pkgs {
+ w.WalkPackage(pkg)
+ }
+ if w.cursorInfo != nil {
+ goto lookup
+ } else {
+ var file io.Writer
+ if apiOutput != "" {
+ var err error
+ file, err = os.Create(apiOutput)
+ if err != nil {
+ log.Fatal(err)
+ }
+ } else {
+ file = os.Stdout
+ }
+ bw := bufio.NewWriter(file)
+ defer bw.Flush()
+ for _, p := range w.packageMap {
+ if w.wantedPkg[p.name] {
+ for _, f := range p.Features() {
+ fmt.Fprintf(bw, "%s\n", f)
+ }
+ }
+ }
+ return nil
+ }
+ features = w.Features("")
+ } else {
+ for _, c := range contexts {
+ c.Compiler = build.Default.Compiler
+ }
+
+ for _, pkg := range pkgs {
+ w.wantedPkg[pkg] = true
+ }
+
+ var featureCtx = make(map[string]map[string]bool) // feature -> context name -> true
+ for _, context := range contexts {
+ w.context = context
+ w.ctxName = contextName(w.context) + ":"
+
+ for _, pkg := range pkgs {
+ w.WalkPackage(pkg)
+ }
+ if w.cursorInfo != nil && w.cursorInfo.info != nil {
+ goto lookup
+ }
+ }
+
+ for pkg, p := range w.packageMap {
+ if w.wantedPkg[p.name] {
+ pos := strings.Index(pkg, ":")
+ if pos == -1 {
+ continue
+ }
+ ctxName := pkg[:pos]
+ for _, f := range p.Features() {
+ if featureCtx[f] == nil {
+ featureCtx[f] = make(map[string]bool)
+ }
+ featureCtx[f][ctxName] = true
+ }
+ }
+ }
+
+ for f, cmap := range featureCtx {
+ if len(cmap) == len(contexts) {
+ features = append(features, f)
+ continue
+ }
+ comma := strings.Index(f, ",")
+ for cname := range cmap {
+ f2 := fmt.Sprintf("%s (%s)%s", f[:comma], cname, f[comma:])
+ features = append(features, f2)
+ }
+ }
+ sort.Strings(features)
+ }
+
+lookup:
+ if w.cursorInfo != nil {
+ info := w.cursorInfo.info
+ if info == nil {
+ os.Exit(1)
+ return os.ErrInvalid
+ }
+ // fmt.Println("kind,", info.Kind)
+ // fmt.Println("name,", info.Name)
+ // if info.Type != "" {
+ // fmt.Println("type,", strings.TrimLeft(info.Type, "*"))
+ // }
+ if info.Name == info.Type || info.Type == "" {
+ fmt.Printf("info, %s, %s\n", info.Kind, info.Name)
+ } else {
+ fmt.Printf("info, %s, %s, %s\n", info.Kind, info.Name, info.Type)
+ }
+ if info.Kind == KindImport || info.Kind == KindPackage {
+ if p := w.findPackage(info.Name); p != nil {
+ fmt.Println("help,", p.name)
+ }
+ }
+ if info.T != nil {
+ for _, text := range []string{info.Name, info.Type} {
+ typ := strings.TrimLeft(text, "*")
+ pos := strings.Index(typ, ".")
+ if pos != -1 {
+ if p := w.findPackage(typ[:pos]); p != nil {
+ fmt.Println("help,", p.name+typ[pos:])
+ break
+ }
+ }
+ }
+ fmt.Println("pos,", w.fset.Position(info.T.Pos()))
+ }
+ return nil
+ }
+
+ fail := false
+ defer func() {
+ if fail {
+ os.Exit(1)
+ }
+ }()
+
+ bw := bufio.NewWriter(os.Stdout)
+ defer bw.Flush()
+
+ for _, f := range features {
+ fmt.Fprintf(bw, "%s\n", f)
+ }
+ return nil
+}
+
+type CursorInfo struct {
+ pkg string
+ file string
+ pos token.Pos
+ src []byte
+ std bool
+ info *TypeInfo
+}
+
+// contexts are the default contexts which are scanned, unless
+// overridden by the -contexts flag.
+var contexts = []*build.Context{
+ {GOOS: "linux", GOARCH: "386", CgoEnabled: true},
+ {GOOS: "linux", GOARCH: "386"},
+ {GOOS: "linux", GOARCH: "amd64", CgoEnabled: true},
+ {GOOS: "linux", GOARCH: "amd64"},
+ {GOOS: "linux", GOARCH: "arm"},
+ {GOOS: "darwin", GOARCH: "386", CgoEnabled: true},
+ {GOOS: "darwin", GOARCH: "386"},
+ {GOOS: "darwin", GOARCH: "amd64", CgoEnabled: true},
+ {GOOS: "darwin", GOARCH: "amd64"},
+ {GOOS: "windows", GOARCH: "amd64"},
+ {GOOS: "windows", GOARCH: "386"},
+ {GOOS: "freebsd", GOARCH: "amd64"},
+ {GOOS: "freebsd", GOARCH: "386"},
+}
+
+func contextName(c *build.Context) string {
+ s := c.GOOS + "-" + c.GOARCH
+ if c.CgoEnabled {
+ return s + "-cgo"
+ }
+ return s
+}
+
+func osArchName(c *build.Context) string {
+ return c.GOOS + "-" + c.GOARCH
+}
+
+func parseContext(c string) *build.Context {
+ parts := strings.Split(c, "-")
+ if len(parts) < 2 {
+ log.Fatalf("bad context: %q", c)
+ }
+ bc := &build.Context{
+ GOOS: parts[0],
+ GOARCH: parts[1],
+ }
+ if len(parts) == 3 {
+ if parts[2] == "cgo" {
+ bc.CgoEnabled = true
+ } else {
+ log.Fatalf("bad context: %q", c)
+ }
+ }
+ return bc
+}
+
+func setCustomContexts() {
+ contexts = []*build.Context{}
+ for _, c := range strings.Split(apiCustomCtx, ",") {
+ contexts = append(contexts, parseContext(c))
+ }
+}
+
+func set(items []string) map[string]bool {
+ s := make(map[string]bool)
+ for _, v := range items {
+ s[v] = true
+ }
+ return s
+}
+
+var spaceParensRx = regexp.MustCompile(` \(\S+?\)`)
+
+func featureWithoutContext(f string) string {
+ if !strings.Contains(f, "(") {
+ return f
+ }
+ return spaceParensRx.ReplaceAllString(f, "")
+}
+
+func compareAPI(w io.Writer, features, required, optional, exception []string, allowNew bool) (ok bool) {
+ ok = true
+
+ optionalSet := set(optional)
+ exceptionSet := set(exception)
+ featureSet := set(features)
+
+ sort.Strings(features)
+ sort.Strings(required)
+
+ take := func(sl *[]string) string {
+ s := (*sl)[0]
+ *sl = (*sl)[1:]
+ return s
+ }
+
+ for len(required) > 0 || len(features) > 0 {
+ switch {
+ case len(features) == 0 || (len(required) > 0 && required[0] < features[0]):
+ feature := take(&required)
+ if exceptionSet[feature] {
+ fmt.Fprintf(w, "~%s\n", feature)
+ } else if featureSet[featureWithoutContext(feature)] {
+ // okay.
+ } else {
+ fmt.Fprintf(w, "-%s\n", feature)
+ ok = false // broke compatibility
+ }
+ case len(required) == 0 || (len(features) > 0 && required[0] > features[0]):
+ newFeature := take(&features)
+ if optionalSet[newFeature] {
+ // Known added feature to the upcoming release.
+ // Delete it from the map so we can detect any upcoming features
+ // which were never seen. (so we can clean up the nextFile)
+ delete(optionalSet, newFeature)
+ } else {
+ fmt.Fprintf(w, "+%s\n", newFeature)
+ if !allowNew {
+ ok = false // we're in lock-down mode for next release
+ }
+ }
+ default:
+ take(&required)
+ take(&features)
+ }
+ }
+
+ // In next file, but not in API.
+ var missing []string
+ for feature := range optionalSet {
+ missing = append(missing, feature)
+ }
+ sort.Strings(missing)
+ for _, feature := range missing {
+ fmt.Fprintf(w, "±%s\n", feature)
+ }
+ return
+}
+
+func fileFeatures(filename string) []string {
+ bs, err := ioutil.ReadFile(filename)
+ if err != nil {
+ log.Fatalf("Error reading file %s: %v", filename, err)
+ }
+ text := strings.TrimSpace(string(bs))
+ if text == "" {
+ return nil
+ }
+ return strings.Split(text, "\n")
+}
+
+func isExtract(name string) bool {
+ if apiAlldecls {
+ return true
+ }
+ return ast.IsExported(name)
+}
+
+// pkgSymbol represents a symbol in a package
+type pkgSymbol struct {
+ pkg string // "net/http"
+ symbol string // "RoundTripper"
+}
+
+//expression kind
+type Kind int
+
+const (
+ KindBuiltin Kind = iota
+ KindPackage
+ KindImport
+ KindVar
+ KindConst
+ KindInterface
+ KindParam
+ KindStruct
+ KindMethod
+ KindField
+ KindType
+ KindFunc
+ KindChan
+ KindArray
+ KindMap
+ KindSlice
+ KindLabel
+ KindBranch
+)
+
+func (k Kind) String() string {
+ switch k {
+ case KindBuiltin:
+ return "builtin"
+ case KindPackage:
+ return "package"
+ case KindImport:
+ return "import"
+ case KindVar:
+ return "var"
+ case KindConst:
+ return "const"
+ case KindParam:
+ return "param"
+ case KindInterface:
+ return "interface"
+ case KindStruct:
+ return "struct"
+ case KindMethod:
+ return "method"
+ case KindField:
+ return "field"
+ case KindType:
+ return "type"
+ case KindFunc:
+ return "func"
+ case KindChan:
+ return "chan"
+ case KindMap:
+ return "map"
+ case KindArray:
+ return "array"
+ case KindSlice:
+ return "slice"
+ case KindLabel:
+ return "label"
+ case KindBranch:
+ return "branch"
+ }
+ return fmt.Sprint("unknown-kind")
+}
+
+//expression type
+type TypeInfo struct {
+ Kind Kind
+ Name string
+ Type string
+ X ast.Expr
+ T ast.Expr
+}
+
+type ExprType struct {
+ X ast.Expr
+ T string
+}
+
+type Package struct {
+ dpkg *doc.Package
+ apkg *ast.Package
+ interfaceMethods map[string]([]typeMethod)
+ interfaces map[string]*ast.InterfaceType //interface
+ structs map[string]*ast.StructType //struct
+ types map[string]ast.Expr //type
+ functions map[string]typeMethod //function
+ consts map[string]*ExprType //const => type
+ vars map[string]*ExprType //var => type
+ name string
+ dir string
+ sep string
+ deps []string
+ features map[string](token.Pos) // set
+}
+
+func NewPackage() *Package {
+ return &Package{
+ interfaceMethods: make(map[string]([]typeMethod)),
+ interfaces: make(map[string]*ast.InterfaceType),
+ structs: make(map[string]*ast.StructType),
+ types: make(map[string]ast.Expr),
+ functions: make(map[string]typeMethod),
+ consts: make(map[string]*ExprType),
+ vars: make(map[string]*ExprType),
+ features: make(map[string](token.Pos)),
+ sep: ", ",
+ }
+}
+
+func (p *Package) Features() (fs []string) {
+ for f, ps := range p.features {
+ if apiShowpos {
+ fs = append(fs, f+p.sep+strconv.Itoa(int(ps)))
+ } else {
+ fs = append(fs, f)
+ }
+ }
+ sort.Strings(fs)
+ return
+}
+
+func (p *Package) findType(name string) ast.Expr {
+ for k, v := range p.interfaces {
+ if k == name {
+ return v
+ }
+ }
+ for k, v := range p.structs {
+ if k == name {
+ return v
+ }
+ }
+ for k, v := range p.types {
+ if k == name {
+ return v
+ }
+ }
+ return nil
+}
+
+func funcRetType(ft *ast.FuncType, index int) ast.Expr {
+ if ft.Results != nil {
+ pos := 0
+ for _, fi := range ft.Results.List {
+ if fi.Names == nil {
+ if pos == index {
+ return fi.Type
+ }
+ pos++
+ } else {
+ for _ = range fi.Names {
+ if pos == index {
+ return fi.Type
+ }
+ pos++
+ }
+ }
+ }
+ }
+ return nil
+}
+
+func findFunction(funcs []*doc.Func, name string) (*ast.Ident, *ast.FuncType) {
+ for _, f := range funcs {
+ if f.Name == name {
+ return &ast.Ident{Name: name, NamePos: f.Decl.Pos()}, f.Decl.Type
+ }
+ }
+ return nil, nil
+}
+
+func (p *Package) findSelectorType(name string) ast.Expr {
+ if t, ok := p.vars[name]; ok {
+ return &ast.Ident{
+ NamePos: t.X.Pos(),
+ Name: t.T,
+ }
+ }
+ if t, ok := p.consts[name]; ok {
+ return &ast.Ident{
+ NamePos: t.X.Pos(),
+ Name: t.T,
+ }
+ }
+ if t, ok := p.functions[name]; ok {
+ return t.ft
+ }
+ for k, v := range p.structs {
+ if k == name {
+ return &ast.Ident{
+ NamePos: v.Pos(),
+ Name: name,
+ }
+ }
+ }
+ for k, v := range p.interfaces {
+ if k == name {
+ return &ast.Ident{
+ NamePos: v.Pos(),
+ Name: name,
+ }
+ }
+ }
+ for k, v := range p.types {
+ if k == name {
+ return v
+ }
+ }
+ return nil
+}
+
+func (p *Package) findCallFunc(name string) ast.Expr {
+ if fn, ok := p.functions[name]; ok {
+ return fn.ft
+ }
+ if s, ok := p.structs[name]; ok {
+ return s
+ }
+ if t, ok := p.types[name]; ok {
+ return t
+ }
+ if v, ok := p.vars[name]; ok {
+ if strings.HasPrefix(v.T, "func(") {
+ e, err := parser.ParseExpr(v.T + "{}")
+ if err == nil {
+ return e
+ }
+ }
+ }
+ return nil
+}
+
+func (p *Package) findCallType(name string, index int) ast.Expr {
+ if fn, ok := p.functions[name]; ok {
+ return funcRetType(fn.ft, index)
+ }
+ if s, ok := p.structs[name]; ok {
+ return &ast.Ident{
+ NamePos: s.Pos(),
+ Name: name,
+ }
+ }
+ if t, ok := p.types[name]; ok {
+ return &ast.Ident{
+ NamePos: t.Pos(),
+ Name: name,
+ }
+ }
+ return nil
+}
+
+func (p *Package) findMethod(typ, name string) (*ast.Ident, *ast.FuncType) {
+ if t, ok := p.interfaces[typ]; ok && t.Methods != nil {
+ for _, fd := range t.Methods.List {
+ switch ft := fd.Type.(type) {
+ case *ast.FuncType:
+ for _, ident := range fd.Names {
+ if ident.Name == name {
+ return ident, ft
+ }
+ }
+ }
+ }
+ }
+ for k, v := range p.interfaceMethods {
+ if k == typ {
+ for _, m := range v {
+ if m.name == name {
+ return &ast.Ident{Name: name, NamePos: m.pos}, m.ft
+ }
+ }
+ }
+ }
+ if p.dpkg == nil {
+ return nil, nil
+ }
+ for _, t := range p.dpkg.Types {
+ if t.Name == typ {
+ return findFunction(t.Methods, name)
+ }
+ }
+ return nil, nil
+}
+
+type Walker struct {
+ context *build.Context
+ fset *token.FileSet
+ scope []string
+ // features map[string](token.Pos) // set
+ lastConstType string
+ curPackageName string
+ sep string
+ ctxName string
+ curPackage *Package
+ constDep map[string]*ExprType // key's const identifier has type of future value const identifier
+ packageState map[string]loadState
+ packageMap map[string]*Package
+ interfaces map[pkgSymbol]*ast.InterfaceType
+ selectorFullPkg map[string]string // "http" => "net/http", updated by imports
+ wantedPkg map[string]bool // packages requested on the command line
+ cursorInfo *CursorInfo
+ localvar map[string]*ExprType
+}
+
+func NewWalker() *Walker {
+ return &Walker{
+ fset: token.NewFileSet(),
+ // features: make(map[string]token.Pos),
+ packageState: make(map[string]loadState),
+ interfaces: make(map[pkgSymbol]*ast.InterfaceType),
+ packageMap: make(map[string]*Package),
+ selectorFullPkg: make(map[string]string),
+ wantedPkg: make(map[string]bool),
+ localvar: make(map[string]*ExprType),
+ sep: ", ",
+ }
+}
+
+// loadState is the state of a package's parsing.
+type loadState int
+
+const (
+ notLoaded loadState = iota
+ loading
+ loaded
+)
+
+func (w *Walker) Features(ctx string) (fs []string) {
+ for pkg, p := range w.packageMap {
+ if w.wantedPkg[p.name] {
+ if ctx == "" || strings.HasPrefix(pkg, ctx) {
+ fs = append(fs, p.Features()...)
+ }
+ }
+ }
+ sort.Strings(fs)
+ return
+}
+
+// fileDeps returns the imports in a file.
+func fileDeps(f *ast.File) (pkgs []string) {
+ for _, is := range f.Imports {
+ fpkg, err := strconv.Unquote(is.Path.Value)
+ if err != nil {
+ log.Fatalf("error unquoting import string %q: %v", is.Path.Value, err)
+ }
+ if fpkg != "C" {
+ pkgs = append(pkgs, fpkg)
+ }
+ }
+ return
+}
+
+func (w *Walker) findPackage(pkg string) *Package {
+ if full, ok := w.selectorFullPkg[pkg]; ok {
+ if w.ctxName != "" {
+ ctxName := w.ctxName + full
+ for k, v := range w.packageMap {
+ if k == ctxName {
+ return v
+ }
+ }
+ }
+ for k, v := range w.packageMap {
+ if k == full {
+ return v
+ }
+ }
+ }
+ return nil
+}
+
+func (w *Walker) findPackageOSArch(pkg string) *Package {
+ if full, ok := w.selectorFullPkg[pkg]; ok {
+ ctxName := osArchName(w.context) + ":" + full
+ for k, v := range w.packageMap {
+ if k == ctxName {
+ return v
+ }
+ }
+ }
+ return nil
+}
+
+// WalkPackage walks all files in package `name'.
+// WalkPackage does nothing if the package has already been loaded.
+
+func (w *Walker) WalkPackage(pkg string) {
+ if build.IsLocalImport(pkg) {
+ wd, err := os.Getwd()
+ if err != nil {
+ if apiVerbose {
+ log.Println(err)
+ }
+ return
+ }
+ dir := filepath.Clean(filepath.Join(wd, pkg))
+ bp, err := w.context.ImportDir(dir, 0)
+ if err != nil {
+ if apiVerbose {
+ log.Println(err)
+ }
+ return
+ }
+ if w.wantedPkg[pkg] == true {
+ w.wantedPkg[bp.Name] = true
+ delete(w.wantedPkg, pkg)
+ }
+ if w.cursorInfo != nil && w.cursorInfo.pkg == pkg {
+ w.cursorInfo.pkg = bp.Name
+ }
+ w.WalkPackageDir(bp.Name, bp.Dir, bp)
+ } else if filepath.IsAbs(pkg) {
+ bp, err := build.ImportDir(pkg, 0)
+ if err != nil {
+ if apiVerbose {
+ log.Println(err)
+ }
+ }
+ if w.wantedPkg[pkg] == true {
+ w.wantedPkg[bp.Name] = true
+ delete(w.wantedPkg, pkg)
+ }
+ if w.cursorInfo != nil && w.cursorInfo.pkg == pkg {
+ w.cursorInfo.pkg = bp.Name
+ }
+
+ w.WalkPackageDir(bp.Name, bp.Dir, bp)
+ } else {
+ bp, err := build.Import(pkg, "", build.FindOnly)
+ if err != nil {
+ if apiVerbose {
+ log.Println(err)
+ }
+ return
+ }
+ w.WalkPackageDir(pkg, bp.Dir, nil)
+ }
+}
+
+func (w *Walker) WalkPackageDir(name string, dir string, bp *build.Package) {
+ ctxName := w.ctxName + name
+ curName := name
+ switch w.packageState[ctxName] {
+ case loading:
+ log.Fatalf("import cycle loading package %q?", name)
+ return
+ case loaded:
+ return
+ }
+ w.packageState[ctxName] = loading
+ w.selectorFullPkg[name] = name
+
+ defer func() {
+ w.packageState[ctxName] = loaded
+ }()
+
+ sname := name[strings.LastIndexAny(name, ".-/\\")+1:]
+
+ apkg := &ast.Package{
+ Files: make(map[string]*ast.File),
+ }
+ if bp == nil {
+ bp, _ = w.context.ImportDir(dir, 0)
+ }
+ if bp == nil {
+ return
+ }
+ if w.ctxName != "" {
+ isCgo := (len(bp.CgoFiles) > 0) && w.context.CgoEnabled
+ if isCgo {
+ curName = ctxName
+ } else {
+ isOSArch := false
+ for _, file := range bp.GoFiles {
+ if isOSArchFile(w.context, file) {
+ isOSArch = true
+ break
+ }
+ }
+ var p *Package
+ if isOSArch {
+ curName = osArchName(w.context) + ":" + name
+ p = w.findPackageOSArch(name)
+ } else {
+ curName = name
+ p = w.findPackage(name)
+ }
+ if p != nil {
+ if apiImportParser {
+ for _, dep := range p.deps {
+ if _, ok := w.packageState[dep]; ok {
+ continue
+ }
+ w.WalkPackage(dep)
+ }
+ }
+ w.packageMap[ctxName] = p
+ return
+ }
+ }
+ }
+
+ files := append(append([]string{}, bp.GoFiles...), bp.CgoFiles...)
+
+ if w.cursorInfo != nil && w.cursorInfo.pkg == name {
+ files = append(files, bp.TestGoFiles...)
+ for _, v := range bp.XTestGoFiles {
+ if v == w.cursorInfo.file {
+ var xbp build.Package
+ xbp.Name = name + "_test"
+ xbp.GoFiles = append(xbp.GoFiles, bp.XTestGoFiles...)
+ w.cursorInfo.pkg = xbp.Name
+ w.WalkPackageDir(xbp.Name, dir, &xbp)
+ break
+ }
+ }
+ }
+
+ if len(files) == 0 {
+ if apiVerbose {
+ log.Println("no Go source files in", bp.Dir)
+ }
+ return
+ }
+ var deps []string
+
+ for _, file := range files {
+ var src interface{} = nil
+ if w.cursorInfo != nil &&
+ w.cursorInfo.pkg == name &&
+ w.cursorInfo.file == file &&
+ w.cursorInfo.std {
+ src = w.cursorInfo.src
+ }
+ f, err := parser.ParseFile(w.fset, filepath.Join(dir, file), src, 0)
+ if err != nil {
+ if apiVerbose {
+ log.Printf("error parsing package %s, file %s: %v", name, file, err)
+ }
+ }
+
+ if sname != f.Name.Name {
+ continue
+ }
+ apkg.Files[file] = f
+ if apiImportParser {
+ deps = fileDeps(f)
+ for _, dep := range deps {
+ if _, ok := w.packageState[dep]; ok {
+ continue
+ }
+ w.WalkPackage(dep)
+ }
+ }
+ if apiShowpos && w.wantedPkg[name] {
+ tf := w.fset.File(f.Pos())
+ if tf != nil {
+ fmt.Printf("pos %s%s%s%s%d%s%d\n", name, w.sep, filepath.Join(dir, file), w.sep, tf.Base(), w.sep, tf.Size())
+ }
+ }
+ }
+ /* else {
+ fdir, err := os.Open(dir)
+ if err != nil {
+ log.Fatalln(err)
+ }
+ infos, err := fdir.Readdir(-1)
+ fdir.Close()
+ if err != nil {
+ log.Fatalln(err)
+ }
+
+ for _, info := range infos {
+ if info.IsDir() {
+ continue
+ }
+ file := info.Name()
+ if strings.HasPrefix(file, "_") || strings.HasSuffix(file, "_test.go") {
+ continue
+ }
+ if strings.HasSuffix(file, ".go") {
+ f, err := parser.ParseFile(w.fset, filepath.Join(dir, file), nil, 0)
+ if err != nil {
+ if apiVerbose {
+ log.Printf("error parsing package %s, file %s: %v", name, file, err)
+ }
+ continue
+ }
+ if f.Name.Name != sname {
+ continue
+ }
+
+ apkg.Files[file] = f
+ if apiImportParser {
+ for _, dep := range fileDeps(f) {
+ w.WalkPackage(dep)
+ }
+ }
+ if apiShowpos && w.wantedPkg[name] {
+ tf := w.fset.File(f.Pos())
+ if tf != nil {
+ fmt.Printf("pos %s%s%s%s%d:%d\n", name, w.sep, filepath.Join(dir, file), w.sep, tf.Base(), tf.Base()+tf.Size())
+ }
+ }
+ }
+ }
+ }*/
+ if curName != ctxName {
+ w.packageState[curName] = loading
+
+ defer func() {
+ w.packageState[curName] = loaded
+ }()
+ }
+
+ if apiVerbose {
+ log.Printf("package %s => %s, %v", ctxName, curName, w.wantedPkg[curName])
+ }
+ pop := w.pushScope("pkg " + name)
+ defer pop()
+
+ w.curPackageName = curName
+ w.constDep = map[string]*ExprType{}
+ w.curPackage = NewPackage()
+ w.curPackage.apkg = apkg
+ w.curPackage.name = name
+ w.curPackage.dir = dir
+ w.curPackage.deps = deps
+ w.curPackage.sep = w.sep
+ w.packageMap[curName] = w.curPackage
+ w.packageMap[ctxName] = w.curPackage
+
+ for _, afile := range apkg.Files {
+ w.recordTypes(afile)
+ }
+
+ // Register all function declarations first.
+ for _, afile := range apkg.Files {
+ for _, di := range afile.Decls {
+ if d, ok := di.(*ast.FuncDecl); ok {
+ if !w.isExtract(d.Name.Name) {
+ continue
+ }
+ w.peekFuncDecl(d)
+ }
+ }
+ }
+
+ for _, afile := range apkg.Files {
+ w.walkFile(afile)
+ }
+
+ w.resolveConstantDeps()
+
+ if w.cursorInfo != nil && w.cursorInfo.pkg == name {
+ for k, v := range apkg.Files {
+ if k == w.cursorInfo.file {
+ f := w.fset.File(v.Pos())
+ if f == nil {
+ log.Fatalf("error fset postion %v", v.Pos())
+ }
+ info, err := w.lookupFile(v, token.Pos(f.Base())+w.cursorInfo.pos-1)
+ if err != nil {
+ log.Fatalln("lookup error,", err)
+ } else {
+ if info != nil && info.Kind == KindImport {
+ for _, is := range v.Imports {
+ fpath, err := strconv.Unquote(is.Path.Value)
+ if err == nil {
+ if info.Name == path.Base(fpath) {
+ info.T = is.Path
+ }
+ }
+ }
+ }
+ w.cursorInfo.info = info
+ }
+ break
+ }
+ }
+ return
+ }
+
+ // Now that we're done walking types, vars and consts
+ // in the *ast.Package, use go/doc to do the rest
+ // (functions and methods). This is done here because
+ // go/doc is destructive. We can't use the
+ // *ast.Package after this.
+ var mode doc.Mode
+ if apiAllmethods {
+ mode |= doc.AllMethods
+ }
+ if apiAlldecls && w.wantedPkg[w.ctxName] {
+ mode |= doc.AllDecls
+ }
+
+ dpkg := doc.New(apkg, name, mode)
+ w.curPackage.dpkg = dpkg
+
+ if w.wantedPkg[name] != true {
+ return
+ }
+
+ for _, t := range dpkg.Types {
+ // Move funcs up to the top-level, not hiding in the Types.
+ dpkg.Funcs = append(dpkg.Funcs, t.Funcs...)
+
+ for _, m := range t.Methods {
+ w.walkFuncDecl(m.Decl)
+ }
+ }
+
+ for _, f := range dpkg.Funcs {
+ w.walkFuncDecl(f.Decl)
+ }
+}
+
+// pushScope enters a new scope (walking a package, type, node, etc)
+// and returns a function that will leave the scope (with sanity checking
+// for mismatched pushes & pops)
+func (w *Walker) pushScope(name string) (popFunc func()) {
+ w.scope = append(w.scope, name)
+ return func() {
+ if len(w.scope) == 0 {
+ log.Fatalf("attempt to leave scope %q with empty scope list", name)
+ }
+ if w.scope[len(w.scope)-1] != name {
+ log.Fatalf("attempt to leave scope %q, but scope is currently %#v", name, w.scope)
+ }
+ w.scope = w.scope[:len(w.scope)-1]
+ }
+}
+
+func (w *Walker) recordTypes(file *ast.File) {
+ cur := w.curPackage
+ for _, di := range file.Decls {
+ switch d := di.(type) {
+ case *ast.GenDecl:
+ switch d.Tok {
+ case token.TYPE:
+ for _, sp := range d.Specs {
+ ts := sp.(*ast.TypeSpec)
+ name := ts.Name.Name
+ switch t := ts.Type.(type) {
+ case *ast.InterfaceType:
+ if isExtract(name) {
+ w.noteInterface(name, t)
+ }
+ cur.interfaces[name] = t
+ case *ast.StructType:
+ cur.structs[name] = t
+ default:
+ cur.types[name] = ts.Type
+ }
+ }
+ }
+ }
+ }
+}
+
+func inRange(node ast.Node, p token.Pos) bool {
+ if node == nil {
+ return false
+ }
+ return p >= node.Pos() && p <= node.End()
+}
+
+func (w *Walker) lookupLabel(body *ast.BlockStmt, name string) (*TypeInfo, error) {
+ for _, stmt := range body.List {
+ switch v := stmt.(type) {
+ case *ast.BlockStmt:
+ return w.lookupLabel(v, name)
+ case *ast.LabeledStmt:
+ return &TypeInfo{Kind: KindLabel, Name: v.Label.Name, Type: "branch", T: v.Label}, nil
+ }
+ }
+ return nil, nil
+}
+
+func (w *Walker) lookupFile(file *ast.File, p token.Pos) (*TypeInfo, error) {
+ if inRange(file.Name, p) {
+ return &TypeInfo{Kind: KindPackage, X: file.Name, Name: file.Name.Name, Type: file.Name.Name, T: file.Name}, nil
+ }
+ for _, di := range file.Decls {
+ switch d := di.(type) {
+ case *ast.GenDecl:
+ if inRange(d, p) {
+ return w.lookupDecl(d, p, false)
+ }
+ case *ast.FuncDecl:
+ if inRange(d, p) {
+ info, err := w.lookupDecl(d, p, false)
+ if info != nil && info.Kind == KindBranch {
+ return w.lookupLabel(d.Body, info.Name)
+ }
+ return info, err
+ }
+ if d.Body != nil && inRange(d.Body, p) {
+ return w.lookupStmt(d.Body, p)
+ }
+ default:
+ return nil, fmt.Errorf("un parser decl %T", di)
+ }
+ }
+ return nil, fmt.Errorf("un find cursor %v", w.fset.Position(p))
+}
+
+func (w *Walker) isExtract(name string) bool {
+ if w.wantedPkg[w.curPackageName] || apiAlldecls {
+ return true
+ }
+ return ast.IsExported(name)
+}
+
+func (w *Walker) isType(typ string) *ExprType {
+ pos := strings.Index(typ, ".")
+ if pos != -1 {
+ pkg := typ[:pos]
+ typ = typ[pos+1:]
+ if p := w.findPackage(pkg); p != nil {
+ if t, ok := p.types[typ]; ok {
+ if r := w.isType(typ); r != nil {
+ return r
+ }
+ return &ExprType{X: t, T: w.pkgRetType(pkg, w.nodeString(t))}
+ }
+ }
+ return nil
+ }
+ if t, ok := w.curPackage.types[typ]; ok {
+ if r := w.isType(w.nodeString(t)); r != nil {
+ return r
+ }
+ return &ExprType{X: t, T: w.nodeString(t)}
+ }
+ return nil
+}
+
+func (w *Walker) lookupStmt(vi ast.Stmt, p token.Pos) (*TypeInfo, error) {
+ if vi == nil {
+ return nil, nil
+ }
+ switch v := vi.(type) {
+ case *ast.BadStmt:
+ //
+ case *ast.EmptyStmt:
+ //
+ case *ast.LabeledStmt:
+ if inRange(v.Label, p) {
+ return &TypeInfo{Kind: KindLabel, Name: v.Label.Name}, nil
+ }
+ return w.lookupStmt(v.Stmt, p)
+ //
+ case *ast.DeclStmt:
+ return w.lookupDecl(v.Decl, p, true)
+ case *ast.AssignStmt:
+ if len(v.Lhs) == len(v.Rhs) {
+ for i := 0; i < len(v.Lhs); i++ {
+ switch lt := v.Lhs[i].(type) {
+ case *ast.Ident:
+ typ, err := w.varValueType(v.Rhs[i], 0)
+ if err == nil && v.Tok == token.DEFINE {
+ w.localvar[lt.Name] = &ExprType{T: typ, X: lt}
+ } else if apiVerbose {
+ log.Println(err)
+ }
+ }
+ if inRange(v.Lhs[i], p) {
+ return w.lookupExprInfo(v.Lhs[i], p)
+ } else if inRange(v.Rhs[i], p) {
+ return w.lookupExprInfo(v.Rhs[i], p)
+ }
+ if fl, ok := v.Rhs[i].(*ast.FuncLit); ok {
+ if inRange(fl, p) {
+ return w.lookupStmt(fl.Body, p)
+ }
+ }
+ }
+ } else if len(v.Rhs) == 1 {
+ for i := 0; i < len(v.Lhs); i++ {
+ switch lt := v.Lhs[i].(type) {
+ case *ast.Ident:
+ typ, err := w.varValueType(v.Rhs[0], i)
+ if err == nil && v.Tok == token.DEFINE {
+ w.localvar[lt.Name] = &ExprType{T: typ, X: lt}
+ } else if apiVerbose {
+ log.Println(err)
+ }
+ }
+ if inRange(v.Lhs[i], p) {
+ return w.lookupExprInfo(v.Lhs[i], p)
+ } else if inRange(v.Rhs[0], p) {
+ return w.lookupExprInfo(v.Rhs[0], p)
+ }
+ if fl, ok := v.Rhs[0].(*ast.FuncLit); ok {
+ if inRange(fl, p) {
+ return w.lookupStmt(fl.Body, p)
+ }
+ }
+ }
+ }
+ return nil, nil
+ case *ast.ExprStmt:
+ return w.lookupExprInfo(v.X, p)
+ case *ast.BlockStmt:
+ for _, st := range v.List {
+ if inRange(st, p) {
+ return w.lookupStmt(st, p)
+ }
+ _, err := w.lookupStmt(st, p)
+ if err != nil {
+ log.Println(err)
+ }
+ }
+ case *ast.IfStmt:
+ if inRange(v.Init, p) {
+ return w.lookupStmt(v.Init, p)
+ } else {
+ w.lookupStmt(v.Init, p)
+ }
+ if inRange(v.Cond, p) {
+ return w.lookupExprInfo(v.Cond, p)
+ } else if inRange(v.Body, p) {
+ return w.lookupStmt(v.Body, p)
+ } else if inRange(v.Else, p) {
+ return w.lookupStmt(v.Else, p)
+ }
+ case *ast.SendStmt:
+ if inRange(v.Chan, p) {
+ return w.lookupExprInfo(v.Chan, p)
+ } else if inRange(v.Value, p) {
+ return w.lookupExprInfo(v.Value, p)
+ }
+ case *ast.IncDecStmt:
+ return w.lookupExprInfo(v.X, p)
+ case *ast.GoStmt:
+ return w.lookupExprInfo(v.Call, p)
+ case *ast.DeferStmt:
+ return w.lookupExprInfo(v.Call, p)
+ case *ast.ReturnStmt:
+ for _, r := range v.Results {
+ if inRange(r, p) {
+ return w.lookupExprInfo(r, p)
+ }
+ }
+ case *ast.BranchStmt:
+ if inRange(v.Label, p) {
+ return &TypeInfo{Kind: KindBranch, Name: v.Label.Name, Type: "label", T: v.Label}, nil
+ }
+ //
+ case *ast.CaseClause:
+ for _, r := range v.List {
+ if inRange(r, p) {
+ return w.lookupExprInfo(r, p)
+ }
+ }
+ for _, body := range v.Body {
+ if inRange(body, p) {
+ return w.lookupStmt(body, p)
+ } else {
+ w.lookupStmt(body, p)
+ }
+ }
+ case *ast.SwitchStmt:
+ if inRange(v.Init, p) {
+ return w.lookupStmt(v.Init, p)
+ } else {
+ w.lookupStmt(v.Init, p)
+ }
+ if inRange(v.Tag, p) {
+ return w.lookupExprInfo(v.Tag, p)
+ } else if inRange(v.Body, p) {
+ return w.lookupStmt(v.Body, p)
+ }
+ case *ast.TypeSwitchStmt:
+ if inRange(v.Assign, p) {
+ return w.lookupStmt(v.Assign, p)
+ } else {
+ w.lookupStmt(v.Assign, p)
+ }
+ if inRange(v.Init, p) {
+ return w.lookupStmt(v.Init, p)
+ } else {
+ w.lookupStmt(v.Init, p)
+ }
+ var vs string
+ if as, ok := v.Assign.(*ast.AssignStmt); ok {
+ if len(as.Lhs) == 1 {
+ vs = w.nodeString(as.Lhs[0])
+ }
+ }
+ if inRange(v.Body, p) {
+ for _, s := range v.Body.List {
+ if inRange(s, p) {
+ switch cs := s.(type) {
+ case *ast.CaseClause:
+ for _, r := range cs.List {
+ if inRange(r, p) {
+ return w.lookupExprInfo(r, p)
+ } else if vs != "" {
+ typ, err := w.varValueType(r, 0)
+ if err == nil {
+ w.localvar[vs] = &ExprType{T: typ, X: r}
+ }
+ }
+ }
+ for _, body := range cs.Body {
+ if inRange(body, p) {
+ return w.lookupStmt(body, p)
+ } else {
+ w.lookupStmt(body, p)
+ }
+ }
+ default:
+ return w.lookupStmt(cs, p)
+ }
+ }
+ }
+ }
+ case *ast.CommClause:
+ if inRange(v.Comm, p) {
+ return w.lookupStmt(v.Comm, p)
+ }
+ for _, body := range v.Body {
+ if inRange(body, p) {
+ return w.lookupStmt(body, p)
+ }
+ }
+ case *ast.SelectStmt:
+ if inRange(v.Body, p) {
+ return w.lookupStmt(v.Body, p)
+ }
+ case *ast.ForStmt:
+ if inRange(v.Init, p) {
+ return w.lookupStmt(v.Init, p)
+ } else {
+ w.lookupStmt(v.Init, p)
+ }
+ if inRange(v.Cond, p) {
+ return w.lookupExprInfo(v.Cond, p)
+ } else if inRange(v.Body, p) {
+ return w.lookupStmt(v.Body, p)
+ } else if inRange(v.Post, p) {
+ return w.lookupStmt(v.Post, p)
+ }
+ case *ast.RangeStmt:
+ if inRange(v.X, p) {
+ return w.lookupExprInfo(v.X, p)
+ } else if inRange(v.Key, p) {
+ return &TypeInfo{Kind: KindBuiltin, Name: w.nodeString(v.Key), Type: "int"}, nil
+ } else if inRange(v.Value, p) {
+ typ, err := w.lookupExprInfo(v.X, p)
+ if typ != nil {
+ typ.Name = w.nodeString(v.Value)
+ return typ, err
+ }
+ } else {
+ typ, err := w.varValueType(v.X, 0)
+ //check is type
+ if t := w.isType(typ); t != nil {
+ typ = t.T
+ }
+ if err == nil {
+ var kt, vt string
+ if strings.HasPrefix(typ, "[]") {
+ kt = "int"
+ vt = typ[2:]
+ } else if strings.HasPrefix(typ, "map[") {
+ node, err := parser.ParseExpr(typ + "{}")
+ if err == nil {
+ if cl, ok := node.(*ast.CompositeLit); ok {
+ if m, ok := cl.Type.(*ast.MapType); ok {
+ kt = w.nodeString(w.namelessType(m.Key))
+ vt = w.nodeString(w.namelessType(m.Value))
+ }
+ }
+ }
+ }
+ if inRange(v.Key, p) {
+ return &TypeInfo{Kind: KindVar, X: v.Key, Name: w.nodeString(v.Key), T: v.X, Type: kt}, nil
+ } else if inRange(v.Value, p) {
+ return &TypeInfo{Kind: KindVar, X: v.Value, Name: w.nodeString(v.Value), T: v.X, Type: vt}, nil
+ }
+ if key, ok := v.Key.(*ast.Ident); ok {
+ w.localvar[key.Name] = &ExprType{T: kt, X: v.Key}
+ }
+ if value, ok := v.Value.(*ast.Ident); ok {
+ w.localvar[value.Name] = &ExprType{T: vt, X: v.Value}
+ }
+ }
+ }
+ if inRange(v.Body, p) {
+ return w.lookupStmt(v.Body, p)
+ }
+ }
+ return nil, nil //fmt.Errorf("not lookup stmt %v %T", vi, vi)
+}
+
+func (w *Walker) lookupVar(vs *ast.ValueSpec, p token.Pos, local bool) (*TypeInfo, error) {
+ if inRange(vs.Type, p) {
+ return w.lookupExprInfo(vs.Type, p)
+ }
+ for _, v := range vs.Values {
+ if inRange(v, p) {
+ return w.lookupExprInfo(v, p)
+ }
+ }
+ if vs.Type != nil {
+ typ := w.nodeString(vs.Type)
+ for _, ident := range vs.Names {
+ if local {
+ w.localvar[ident.Name] = &ExprType{T: typ, X: ident}
+ }
+ if inRange(ident, p) {
+ return &TypeInfo{Kind: KindVar, X: ident, Name: ident.Name, T: vs.Type, Type: typ}, nil
+ }
+ }
+ } else if len(vs.Names) == len(vs.Values) {
+ for n, ident := range vs.Names {
+ typ := ""
+ if !local {
+ if t, ok := w.curPackage.vars[ident.Name]; ok {
+ typ = t.T
+ }
+ } else {
+ typ, err := w.varValueType(vs.Values[n], n)
+ if err != nil {
+ if apiVerbose {
+ log.Printf("unknown type of variable2 %q, type %T, error = %v, pos=%s",
+ ident.Name, vs.Values[n], err, w.fset.Position(vs.Pos()))
+ }
+ typ = "unknown-type"
+ }
+ w.localvar[ident.Name] = &ExprType{T: typ, X: ident}
+ }
+ if inRange(ident, p) {
+ return &TypeInfo{Kind: KindVar, X: ident, Name: ident.Name, T: ident, Type: typ}, nil
+ }
+ }
+ } else if len(vs.Values) == 1 {
+ for n, ident := range vs.Names {
+ typ := ""
+ if !local {
+ if t, ok := w.curPackage.vars[ident.Name]; ok {
+ typ = t.T
+ }
+ } else {
+ typ, err := w.varValueType(vs.Values[0], n)
+ if err != nil {
+ if apiVerbose {
+ log.Printf("unknown type of variable3 %q, type %T, error = %v, pos=%s",
+ ident.Name, vs.Values[0], err, w.fset.Position(vs.Pos()))
+ }
+ typ = "unknown-type"
+ }
+ w.localvar[ident.Name] = &ExprType{T: typ, X: ident}
+ }
+ if inRange(ident, p) {
+ return &TypeInfo{Kind: KindVar, X: ident, Name: ident.Name, T: ident, Type: typ}, nil
+ }
+ }
+ }
+ return nil, fmt.Errorf("not lookup var local:%v value:%v type:s%T", local, w.nodeString(vs), vs)
+}
+
+func (w *Walker) lookupConst(vs *ast.ValueSpec, p token.Pos, local bool) (*TypeInfo, error) {
+ if inRange(vs.Type, p) {
+ return w.lookupExprInfo(vs.Type, p)
+ }
+ for _, ident := range vs.Names {
+ typ := ""
+ if !local {
+ if t, ok := w.curPackage.consts[ident.Name]; ok {
+ typ = t.T
+ }
+ } else {
+ litType := ""
+ if vs.Type != nil {
+ litType = w.nodeString(vs.Type)
+ } else {
+ litType = w.lastConstType
+ if vs.Values != nil {
+ if len(vs.Values) != 1 {
+ if apiVerbose {
+ log.Printf("const %q, values: %#v", ident.Name, vs.Values)
+ }
+ return nil, nil
+ }
+ var err error
+ litType, err = w.constValueType(vs.Values[0])
+ if err != nil {
+ if apiVerbose {
+ log.Printf("unknown kind in const %q (%T): %v", ident.Name, vs.Values[0], err)
+ }
+ litType = "unknown-type"
+ }
+ }
+ }
+ w.lastConstType = litType
+ typ = litType
+ w.localvar[ident.Name] = &ExprType{T: typ, X: ident}
+ }
+ if inRange(ident, p) {
+ return &TypeInfo{Kind: KindConst, X: ident, Name: ident.Name, T: ident, Type: typ}, nil
+ }
+ }
+ return nil, nil
+}
+
+func (w *Walker) lookupType(ts *ast.TypeSpec, p token.Pos, local bool) (*TypeInfo, error) {
+ switch t := ts.Type.(type) {
+ case *ast.StructType:
+ if inRange(t.Fields, p) {
+ for _, fd := range t.Fields.List {
+ if inRange(fd.Type, p) {
+ return w.lookupExprInfo(fd.Type, p)
+ }
+ for _, ident := range fd.Names {
+ if inRange(ident, p) {
+ return &TypeInfo{Kind: KindField, X: ident, Name: ts.Name.Name + "." + ident.Name, T: fd.Type, Type: w.nodeString(w.namelessType(fd.Type))}, nil
+ }
+ }
+ }
+ }
+ return &TypeInfo{Kind: KindStruct, X: ts.Name, Name: ts.Name.Name, T: ts.Type, Type: "struct"}, nil
+ case *ast.InterfaceType:
+ if inRange(t.Methods, p) {
+ for _, fd := range t.Methods.List {
+ for _, ident := range fd.Names {
+ if inRange(ident, p) {
+ return &TypeInfo{Kind: KindMethod, X: ident, Name: ts.Name.Name + "." + ident.Name, T: ident, Type: w.nodeString(w.namelessType(fd.Type))}, nil
+ }
+ }
+ if inRange(fd.Type, p) {
+ return w.lookupExprInfo(fd.Type, p)
+ }
+ }
+ }
+ return &TypeInfo{Kind: KindInterface, X: ts.Name, Name: ts.Name.Name, T: ts.Type, Type: "interface"}, nil
+ default:
+ return &TypeInfo{Kind: KindType, X: ts.Name, Name: ts.Name.Name, T: ts.Type, Type: w.nodeString(w.namelessType(ts.Type))}, nil
+ }
+ return nil, nil
+}
+
+func (w *Walker) lookupDecl(di ast.Decl, p token.Pos, local bool) (*TypeInfo, error) {
+ switch d := di.(type) {
+ case *ast.GenDecl:
+ switch d.Tok {
+ case token.IMPORT:
+ for _, sp := range d.Specs {
+ is := sp.(*ast.ImportSpec)
+ fpath, err := strconv.Unquote(is.Path.Value)
+ if err != nil {
+ return nil, err
+ }
+ name := path.Base(fpath)
+ if is.Name != nil {
+ name = is.Name.Name
+ }
+ if inRange(sp, p) {
+ return &TypeInfo{Kind: KindImport, X: is.Name, Name: name, T: is.Name, Type: fpath}, nil
+ }
+ }
+ case token.CONST:
+ for _, sp := range d.Specs {
+ if inRange(sp, p) {
+ return w.lookupConst(sp.(*ast.ValueSpec), p, local)
+ } else {
+ w.lookupConst(sp.(*ast.ValueSpec), p, local)
+ }
+ }
+ return nil, nil
+ case token.TYPE:
+ for _, sp := range d.Specs {
+ if inRange(sp, p) {
+ return w.lookupType(sp.(*ast.TypeSpec), p, local)
+ } else {
+ w.lookupType(sp.(*ast.TypeSpec), p, local)
+ }
+ }
+ case token.VAR:
+ for _, sp := range d.Specs {
+ if inRange(sp, p) {
+ return w.lookupVar(sp.(*ast.ValueSpec), p, local)
+ } else {
+ w.lookupVar(sp.(*ast.ValueSpec), p, local)
+ }
+ }
+ return nil, nil
+ default:
+ return nil, fmt.Errorf("unknown token type %d %T in GenDecl", d.Tok, d)
+ }
+ case *ast.FuncDecl:
+ if d.Type.Params != nil {
+ for _, fd := range d.Type.Params.List {
+ if inRange(fd, p) {
+ return w.lookupExprInfo(fd.Type, p)
+ }
+ for _, ident := range fd.Names {
+ if inRange(ident, p) {
+ info, err := w.lookupExprInfo(fd.Type, p)
+ if err == nil {
+ return &TypeInfo{Kind: KindParam, X: ident, Name: ident.Name, T: info.T, Type: info.Type}, nil
+ }
+ }
+ typ, err := w.varValueType(fd.Type, 0)
+ if err == nil {
+ w.localvar[ident.Name] = &ExprType{T: typ, X: ident}
+ } else if apiVerbose {
+ log.Println(err)
+ }
+ }
+ }
+ }
+ if d.Type.Results != nil {
+ for _, fd := range d.Type.Results.List {
+ if inRange(fd, p) {
+ return w.lookupExprInfo(fd.Type, p)
+ }
+ for _, ident := range fd.Names {
+ typ, err := w.varValueType(fd.Type, 0)
+ if err == nil {
+ w.localvar[ident.Name] = &ExprType{T: typ, X: ident}
+ }
+ }
+ }
+ }
+ if d.Recv != nil {
+ for _, fd := range d.Recv.List {
+ if inRange(fd, p) {
+ return w.lookupExprInfo(fd.Type, p)
+ }
+ for _, ident := range fd.Names {
+ w.localvar[ident.Name] = &ExprType{T: w.nodeString(fd.Type), X: ident}
+ }
+ }
+ }
+ if inRange(d.Body, p) {
+ return w.lookupStmt(d.Body, p)
+ }
+ var fname = d.Name.Name
+ kind := KindFunc
+ if d.Recv != nil {
+ recvTypeName, imp := baseTypeName(d.Recv.List[0].Type)
+ if imp {
+ return nil, nil
+ }
+ fname = recvTypeName + "." + d.Name.Name
+ kind = KindMethod
+ }
+ return &TypeInfo{Kind: kind, X: d.Name, Name: fname, T: d.Type, Type: w.nodeString(w.namelessType(d.Type))}, nil
+ default:
+ return nil, fmt.Errorf("unhandled %T, %#v\n", di, di)
+ }
+ return nil, fmt.Errorf("not lookupDecl %v %T", w.nodeString(di), di)
+}
+
+func (w *Walker) lookupExprInfo(vi ast.Expr, p token.Pos) (*TypeInfo, error) {
+ _, info, err := w.lookupExpr(vi, p)
+ return info, err
+}
+
+// lookupExpr , return name,info,error
+func (w *Walker) lookupExpr(vi ast.Expr, p token.Pos) (string, *TypeInfo, error) {
+ if apiVerbose {
+ log.Printf("lookup expr %v %T", w.nodeString(vi), vi)
+ }
+ switch v := vi.(type) {
+ case *ast.BasicLit:
+ litType, ok := varType[v.Kind]
+ if !ok {
+ return "", nil, fmt.Errorf("unknown basic literal kind %#v", v)
+ }
+ name := v.Value
+ if len(name) >= 128 {
+ name = name[:128] + "..."
+ }
+ return litType, &TypeInfo{Kind: KindBuiltin, X: v, Name: name, T: v, Type: litType}, nil
+ case *ast.StarExpr:
+ s, info, err := w.lookupExpr(v.X, p)
+ if err != nil {
+ return "", nil, err
+ }
+ return "*" + s, &TypeInfo{Kind: info.Kind, X: v, Name: "*" + info.Name, T: info.T, Type: "*" + info.Type}, err
+ case *ast.InterfaceType:
+ return "interface{}", &TypeInfo{Kind: KindInterface, X: v, Name: w.nodeString(v), T: v, Type: "interface{}"}, nil
+ case *ast.Ellipsis:
+ s, info, err := w.lookupExpr(v.Elt, p)
+ if err != nil {
+ return "", nil, err
+ }
+ return "[]" + s, &TypeInfo{Kind: KindArray, X: v.Elt, Name: "..." + s, T: info.T, Type: "[]" + info.Type}, nil
+ case *ast.KeyValueExpr:
+ if inRange(v.Key, p) {
+ return w.lookupExpr(v.Key, p)
+ } else if inRange(v.Value, p) {
+ return w.lookupExpr(v.Value, p)
+ }
+ case *ast.CompositeLit:
+ typ, err := w.varValueType(v.Type, 0)
+ if err == nil {
+ typ = strings.TrimLeft(typ, "*")
+ if strings.HasPrefix(typ, "[]") {
+ typ = strings.TrimLeft(typ[2:], "*")
+ }
+ pos := strings.Index(typ, ".")
+ var pt *Package = w.curPackage
+ var pkgdot string
+ if pos != -1 {
+ pkg := typ[:pos]
+ typ = typ[pos+1:]
+ pt = w.findPackage(pkg)
+ if pt != nil {
+ pkgdot = pkg + "."
+ }
+ }
+ if pt != nil {
+ if ss, ok := pt.structs[typ]; ok {
+ for _, elt := range v.Elts {
+ if inRange(elt, p) {
+ if cl, ok := elt.(*ast.CompositeLit); ok {
+ for _, elt := range cl.Elts {
+ if inRange(elt, p) {
+ if kv, ok := elt.(*ast.KeyValueExpr); ok {
+ if inRange(kv.Key, p) {
+ n, t := w.findStructField(ss, w.nodeString(kv.Key))
+ if n != nil {
+ return pkgdot + typ + "." + w.nodeString(kv.Key), &TypeInfo{Kind: KindField, X: kv.Key, Name: pkgdot + typ + "." + w.nodeString(kv.Key), T: n, Type: w.nodeString(w.namelessType(t))}, nil
+ }
+ } else if inRange(kv.Value, p) {
+ return w.lookupExpr(kv.Value, p)
+ }
+ }
+ }
+ }
+ }
+ if kv, ok := elt.(*ast.KeyValueExpr); ok {
+ if inRange(kv.Key, p) {
+ n, t := w.findStructField(ss, w.nodeString(kv.Key))
+ if n != nil {
+ return typ + "." + w.nodeString(kv.Key), &TypeInfo{Kind: KindField, X: kv.Key, Name: typ + "." + w.nodeString(kv.Key), T: n, Type: w.nodeString(w.namelessType(t))}, nil
+ }
+ } else if inRange(kv.Value, p) {
+ return w.lookupExpr(kv.Value, p)
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ for _, elt := range v.Elts {
+ if inRange(elt, p) {
+ return w.lookupExpr(elt, p)
+ }
+ }
+ return w.lookupExpr(v.Type, p)
+ case *ast.UnaryExpr:
+ s, info, err := w.lookupExpr(v.X, p)
+ return v.Op.String() + s, info, err
+ case *ast.TypeAssertExpr:
+ if inRange(v.X, p) {
+ return w.lookupExpr(v.X, p)
+ }
+ return w.lookupExpr(v.Type, p)
+ case *ast.BinaryExpr:
+ if inRange(v.X, p) {
+ return w.lookupExpr(v.X, p)
+ } else if inRange(v.Y, p) {
+ return w.lookupExpr(v.Y, p)
+ }
+ return "", nil, nil
+ case *ast.CallExpr:
+ for _, arg := range v.Args {
+ if inRange(arg, p) {
+ return w.lookupExpr(arg, p)
+ }
+ }
+ switch ft := v.Fun.(type) {
+ case *ast.Ident:
+ if typ, ok := w.localvar[ft.Name]; ok {
+ return ft.Name, &TypeInfo{Kind: KindVar, X: ft, Name: ft.Name, T: typ.X, Type: typ.T}, nil
+ }
+ if typ, ok := w.curPackage.vars[ft.Name]; ok {
+ return ft.Name, &TypeInfo{Kind: KindVar, X: v, Name: ft.Name, T: typ.X, Type: typ.T}, nil
+ }
+ if typ, ok := w.curPackage.functions[ft.Name]; ok {
+ return ft.Name, &TypeInfo{Kind: KindFunc, X: ft, Name: ft.Name, T: typ.ft, Type: typ.sig}, nil
+ }
+ if typ, ok := w.curPackage.interfaces[ft.Name]; ok {
+ return ft.Name, &TypeInfo{Kind: KindInterface, X: ft, Name: ft.Name, T: typ, Type: w.nodeString(w.namelessType(typ))}, nil
+ }
+ if typ, ok := w.curPackage.interfaces[ft.Name]; ok {
+ return ft.Name, &TypeInfo{Kind: KindInterface, X: ft, Name: ft.Name, T: typ, Type: w.nodeString(w.namelessType(typ))}, nil
+ }
+ if typ, ok := w.curPackage.structs[ft.Name]; ok {
+ return ft.Name, &TypeInfo{Kind: KindStruct, X: ft, Name: ft.Name, T: typ, Type: w.nodeString(w.namelessType(typ))}, nil
+ }
+ if typ, ok := w.curPackage.types[ft.Name]; ok {
+ return ft.Name, &TypeInfo{Kind: KindType, X: ft, Name: ft.Name, T: typ, Type: w.nodeString(w.namelessType(typ))}, nil
+ }
+ if isBuiltinType(ft.Name) {
+ return ft.Name, &TypeInfo{Kind: KindBuiltin, X: ft, Name: ft.Name}, nil
+ }
+ return "", nil, fmt.Errorf("lookup unknown ident %v", v)
+ case *ast.FuncLit:
+ if inRange(ft.Body, p) {
+ info, err := w.lookupStmt(ft.Body, p)
+ if err == nil {
+ return "", info, nil
+ }
+ return "", nil, err
+ }
+ return w.lookupExpr(ft.Type, p)
+ case *ast.ParenExpr:
+ return w.lookupExpr(ft.X, p)
+ case *ast.SelectorExpr:
+ switch st := ft.X.(type) {
+ case *ast.Ident:
+ if inRange(st, p) {
+ return w.lookupExpr(st, p)
+ }
+ s, info, err := w.lookupExpr(st, p)
+ if err != nil {
+ return "", nil, err
+ }
+ typ := info.Type
+ if typ == "" {
+ typ = s
+ }
+ fname := typ + "." + ft.Sel.Name
+ typ = strings.TrimLeft(typ, "*")
+ if fn, ok := w.curPackage.functions[fname]; ok {
+ return fname, &TypeInfo{Kind: KindMethod, X: st, Name: fname, T: fn.ft, Type: w.nodeString(w.namelessType(fn.ft))}, nil
+ }
+ info, e := w.lookupFunction(typ, ft.Sel.Name)
+ if e != nil {
+ return "", nil, e
+ }
+ return fname, info, nil
+ case *ast.SelectorExpr:
+ if inRange(st.X, p) {
+ return w.lookupExpr(st.X, p)
+ }
+ if inRange(st, p) {
+ return w.lookupExpr(st, p)
+ }
+ typ, err := w.varValueType(st, 0)
+ if err != nil {
+ return "", nil, err
+ }
+ /*
+ typ = strings.TrimLeft(typ, "*")
+ if t := w.curPackage.findType(typ); t != nil {
+ if ss, ok := t.(*ast.StructType); ok {
+ for _, fi := range ss.Fields.List {
+ for _, n := range fi.Names {
+ if n.Name == st.Sel.Name {
+ //return fname, &TypeInfo{Kind: KindField, X: n, Name: fname, T: fi.Type, Type: w.nodeString(w.namelessType(fi.Type))}, nil
+ typ = w.nodeString(w.namelessType(fi.Type))
+ }
+ }
+ }
+ }
+ }
+ */
+ info, e := w.lookupFunction(typ, ft.Sel.Name)
+ if e != nil {
+ return "", nil, e
+ }
+ return typ + "." + st.Sel.Name, info, nil
+ case *ast.CallExpr:
+ if inRange(st, p) {
+ return w.lookupExpr(st, p)
+ }
+ if info, err := w.lookupExprInfo(st, p); err == nil {
+ if fn, ok := info.X.(*ast.FuncType); ok {
+ if fn.Results.NumFields() == 1 {
+ info, err := w.lookupFunction(w.nodeString(fn.Results.List[0].Type), ft.Sel.Name)
+ if err == nil {
+ return info.Name, info, err
+ }
+ return "", nil, err
+ }
+ }
+ }
+ //w.lookupFunction(w.nodeString(info.X))
+ typ, err := w.varValueType(st, 0)
+ if err != nil {
+ return "", nil, err
+ }
+ info, e := w.lookupFunction(typ, ft.Sel.Name)
+ if e != nil {
+ return "", nil, e
+ }
+ return typ + "." + ft.Sel.Name, info, nil
+ case *ast.TypeAssertExpr:
+ if inRange(st.X, p) {
+ return w.lookupExpr(st.X, p)
+ }
+ typ := w.nodeString(w.namelessType(st.Type))
+ info, e := w.lookupFunction(typ, ft.Sel.Name)
+ if e != nil {
+ return "", nil, e
+ }
+ return typ + "." + ft.Sel.Name, info, nil
+ default:
+ return "", nil, fmt.Errorf("not find select %v %T", v, st)
+ }
+ }
+ return "", nil, fmt.Errorf("not find call %v %T", w.nodeString(v), v.Fun)
+ case *ast.SelectorExpr:
+ switch st := v.X.(type) {
+ case *ast.Ident:
+ if inRange(st, p) {
+ return w.lookupExpr(st, p)
+ }
+ info, err := w.lookupSelector(st.Name, v.Sel.Name)
+ if err != nil {
+ return "", nil, err
+ }
+ return st.Name + "." + v.Sel.Name, info, nil
+ // case *ast.CallExpr:
+ // typ, err := w.varValueType(v.X, index)
+ // if err == nil {
+ // if strings.HasPrefix(typ, "*") {
+ // typ = typ[1:]
+ // }
+ // t := w.curPackage.findType(typ)
+ // if st, ok := t.(*ast.StructType); ok {
+ // for _, fi := range st.Fields.List {
+ // for _, n := range fi.Names {
+ // if n.Name == v.Sel.Name {
+ // return w.varValueType(fi.Type, index)
+ // }
+ // }
+ // }
+ // }
+ // }
+ case *ast.SelectorExpr:
+ if inRange(st.X, p) {
+ return w.lookupExpr(st.X, p)
+ }
+
+ if inRange(st, p) {
+ return w.lookupExpr(st, p)
+ }
+
+ typ, err := w.varValueType(st, 0)
+ if err == nil {
+ info, err := w.lookupSelector(typ, v.Sel.Name)
+ if err != nil {
+ return "", nil, err
+ }
+ return typ + v.Sel.Name, info, nil
+ }
+ // case *ast.IndexExpr:
+ // typ, err := w.varValueType(st.X, 0)
+ // log.Println(typ, err)
+ // if err == nil {
+ // if strings.HasPrefix(typ, "[]") {
+ // return w.varSelectorType(typ[2:], v.Sel.Name)
+ // }
+ // }
+ }
+ return "", nil, fmt.Errorf("unknown lookup selector expr: %T %s.%s", v.X, w.nodeString(v.X), v.Sel)
+
+ // s, info, err := w.lookupExpr(v.X, p)
+ // if err != nil {
+ // return "", "", err
+ // }
+ // if strings.HasPrefix(s, "*") {
+ // s = s[1:]
+ // }
+ // if inRange(v.X, p) {
+ // return s, info, err
+ // }
+ // t := w.curPackage.findType(s)
+ // fname := s + "." + v.Sel.Name
+ // if st, ok := t.(*ast.StructType); ok {
+ // for _, fi := range st.Fields.List {
+ // for _, n := range fi.Names {
+ // if n.Name == v.Sel.Name {
+ // return fname, fmt.Sprintf("var,%s,%s,%s", fname, w.nodeString(w.namelessType(fi.Type)), w.fset.Position(n.Pos())), nil
+ // }
+ // }
+ // }
+ // }
+ // log.Println(">>", s)
+ // info, e := w.lookupSelector(s, v.Sel.Name)
+ // return fname, info, e
+ case *ast.Ident:
+ if typ, ok := w.localvar[v.Name]; ok {
+ return typ.T, &TypeInfo{Kind: KindVar, X: v, Name: v.Name, T: typ.X, Type: typ.T}, nil
+ }
+ if typ, ok := w.curPackage.interfaces[v.Name]; ok {
+ return v.Name, &TypeInfo{Kind: KindInterface, X: v, Name: v.Name, T: typ, Type: "interface"}, nil
+ }
+ if typ, ok := w.curPackage.structs[v.Name]; ok {
+ return v.Name, &TypeInfo{Kind: KindStruct, X: v, Name: v.Name, T: typ, Type: "struct"}, nil
+ }
+ if typ, ok := w.curPackage.types[v.Name]; ok {
+ return v.Name, &TypeInfo{Kind: KindType, X: v, Name: v.Name, T: typ, Type: v.Name}, nil
+ }
+ if typ, ok := w.curPackage.vars[v.Name]; ok {
+ return v.Name, &TypeInfo{Kind: KindVar, X: v, Name: v.Name, T: typ.X, Type: typ.T}, nil
+ }
+ if typ, ok := w.curPackage.consts[v.Name]; ok {
+ return v.Name, &TypeInfo{Kind: KindConst, X: v, Name: v.Name, T: typ.X, Type: typ.T}, nil
+ }
+ if typ, ok := w.curPackage.functions[v.Name]; ok {
+ return v.Name, &TypeInfo{Kind: KindFunc, X: typ.ft, Name: v.Name, T: typ.ft, Type: typ.sig}, nil
+ }
+ if p := w.findPackage(v.Name); p != nil {
+ return v.Name, &TypeInfo{Kind: KindImport, X: v, Name: v.Name, Type: p.name}, nil
+ }
+ if isBuiltinType(v.Name) {
+ return v.Name, &TypeInfo{Kind: KindBuiltin, Name: v.Name}, nil
+ }
+ return "", nil, fmt.Errorf("lookup unknown ident %v", v)
+ //return v.Name, &TypeInfo{Kind: KindVar, X: v, Name: v.Name, T: v, Type: v.Name}, nil
+ case *ast.IndexExpr:
+ if inRange(v.Index, p) {
+ return w.lookupExpr(v.Index, p)
+ }
+ return w.lookupExpr(v.X, p)
+ case *ast.ParenExpr:
+ return w.lookupExpr(v.X, p)
+ case *ast.FuncLit:
+ if inRange(v.Type, p) {
+ return w.lookupExpr(v.Type, p)
+ } else {
+ w.lookupExpr(v.Type, p)
+ }
+ typ, err := w.varValueType(v.Type, 0)
+ if err != nil {
+ return "", nil, err
+ }
+ info, e := w.lookupStmt(v.Body, p)
+ if e != nil {
+ return "", nil, err
+ }
+ return typ, info, nil
+ case *ast.FuncType:
+ if v.Params != nil {
+ for _, fd := range v.Params.List {
+ if inRange(fd, p) {
+ return w.lookupExpr(fd.Type, p)
+ }
+ for _, ident := range fd.Names {
+ typ, err := w.varValueType(fd.Type, 0)
+ if err == nil {
+ w.localvar[ident.Name] = &ExprType{T: typ, X: ident}
+ }
+ }
+ }
+ }
+ if v.Results != nil {
+ for _, fd := range v.Results.List {
+ if inRange(fd, p) {
+ return w.lookupExpr(fd.Type, p)
+ }
+ for _, ident := range fd.Names {
+ typ, err := w.varValueType(fd.Type, 0)
+ if err == nil {
+ w.localvar[ident.Name] = &ExprType{T: typ, X: ident}
+ }
+ }
+ }
+ }
+ return "", nil, nil
+ case *ast.ArrayType:
+ s, info, err := w.lookupExpr(v.Elt, p)
+ if err != nil {
+ return "", nil, err
+ }
+ return "[]" + s, &TypeInfo{Kind: KindArray, Name: "[]" + info.Name, Type: "[]" + info.Type, T: info.T}, nil
+ case *ast.SliceExpr:
+ if inRange(v.High, p) {
+ return w.lookupExpr(v.High, p)
+ } else if inRange(v.Low, p) {
+ return w.lookupExpr(v.Low, p)
+ }
+ return w.lookupExpr(v.X, p)
+ case *ast.MapType:
+ if inRange(v.Key, p) {
+ return w.lookupExpr(v.Key, p)
+ } else if inRange(v.Value, p) {
+ return w.lookupExpr(v.Value, p)
+ }
+ typ, err := w.varValueType(v, 0)
+ if err != nil {
+ return "", nil, err
+ }
+ return typ, &TypeInfo{Kind: KindMap, X: v, Name: w.nodeString(v), T: v, Type: typ}, nil
+ case *ast.ChanType:
+ if inRange(v.Value, p) {
+ return w.lookupExpr(v.Value, p)
+ }
+ typ, err := w.varValueType(v, 0)
+ if err != nil {
+ return "", nil, err
+ }
+ return typ, &TypeInfo{Kind: KindChan, X: v, Name: w.nodeString(v), T: v, Type: typ}, nil
+ default:
+ return "", nil, fmt.Errorf("not lookupExpr %v %T", w.nodeString(v), v)
+ }
+ return "", nil, fmt.Errorf("not lookupExpr %v %T", w.nodeString(vi), vi)
+}
+
+func (w *Walker) walkFile(file *ast.File) {
+ // Not entering a scope here; file boundaries aren't interesting.
+ for _, di := range file.Decls {
+ switch d := di.(type) {
+ case *ast.GenDecl:
+ switch d.Tok {
+ case token.IMPORT:
+ for _, sp := range d.Specs {
+ is := sp.(*ast.ImportSpec)
+ fpath, err := strconv.Unquote(is.Path.Value)
+ if err != nil {
+ log.Fatal(err)
+ }
+ //name := path.Base(fpath)
+ name := fpath
+ if i := strings.LastIndexAny(name, ".-/\\"); i > 0 {
+ name = name[i+1:]
+ }
+ if is.Name != nil {
+ name = is.Name.Name
+ }
+ w.selectorFullPkg[name] = fpath
+ }
+ case token.CONST:
+ for _, sp := range d.Specs {
+ w.walkConst(sp.(*ast.ValueSpec))
+ }
+ case token.TYPE:
+ for _, sp := range d.Specs {
+ w.walkTypeSpec(sp.(*ast.TypeSpec))
+ }
+ case token.VAR:
+ for _, sp := range d.Specs {
+ w.walkVar(sp.(*ast.ValueSpec))
+ }
+ default:
+ log.Fatalf("unknown token type %d in GenDecl", d.Tok)
+ }
+ case *ast.FuncDecl:
+ // Ignore. Handled in subsequent pass, by go/doc.
+ default:
+ log.Printf("unhandled %T, %#v\n", di, di)
+ printer.Fprint(os.Stderr, w.fset, di)
+ os.Stderr.Write([]byte("\n"))
+ }
+ }
+}
+
+var constType = map[token.Token]string{
+ token.INT: "ideal-int",
+ token.FLOAT: "ideal-float",
+ token.STRING: "ideal-string",
+ token.CHAR: "ideal-char",
+ token.IMAG: "ideal-imag",
+}
+
+var varType = map[token.Token]string{
+ token.INT: "int",
+ token.FLOAT: "float64",
+ token.STRING: "string",
+ token.CHAR: "rune",
+ token.IMAG: "complex128",
+}
+
+var builtinTypes = []string{
+ "bool", "byte", "complex64", "complex128", "error", "float32", "float64",
+ "int", "int8", "int16", "int32", "int64", "rune", "string",
+ "uint", "uint8", "uint16", "uint32", "uint64", "uintptr",
+}
+
+func isBuiltinType(typ string) bool {
+ for _, v := range builtinTypes {
+ if v == typ {
+ return true
+ }
+ }
+ return false
+}
+
+func constTypePriority(typ string) int {
+ switch typ {
+ case "complex128":
+ return 100
+ case "ideal-imag":
+ return 99
+ case "complex64":
+ return 98
+ case "float64":
+ return 97
+ case "ideal-float":
+ return 96
+ case "float32":
+ return 95
+ case "int64":
+ return 94
+ case "int", "uint", "uintptr":
+ return 93
+ case "ideal-int":
+ return 92
+ case "int16", "uint16", "int8", "uint8", "byte":
+ return 91
+ case "ideal-char":
+ return 90
+ }
+ return 101
+}
+
+func (w *Walker) constRealType(typ string) string {
+ pos := strings.Index(typ, ".")
+ if pos >= 0 {
+ pkg := typ[:pos]
+ if pkg == "C" {
+ return "int"
+ }
+ typ = typ[pos+1:]
+ if p := w.findPackage(pkg); p != nil {
+ ret := p.findType(typ)
+ if ret != nil {
+ return w.nodeString(w.namelessType(ret))
+ }
+ }
+ } else {
+ ret := w.curPackage.findType(typ)
+ if ret != nil {
+ return w.nodeString(w.namelessType(ret))
+ }
+ }
+ return typ
+}
+
+func (w *Walker) constValueType(vi interface{}) (string, error) {
+ switch v := vi.(type) {
+ case *ast.BasicLit:
+ litType, ok := constType[v.Kind]
+ if !ok {
+ return "", fmt.Errorf("unknown basic literal kind %#v", v)
+ }
+ return litType, nil
+ case *ast.UnaryExpr:
+ return w.constValueType(v.X)
+ case *ast.SelectorExpr:
+ lhs := w.nodeString(v.X)
+ rhs := w.nodeString(v.Sel)
+ //if CGO
+ if lhs == "C" {
+ return lhs + "." + rhs, nil
+ }
+ if p := w.findPackage(lhs); p != nil {
+ if ret, ok := p.consts[rhs]; ok {
+ return w.pkgRetType(p.name, ret.T), nil
+ }
+ }
+ return "", fmt.Errorf("unknown constant reference to %s.%s", lhs, rhs)
+ case *ast.Ident:
+ if v.Name == "iota" {
+ return "ideal-int", nil // hack.
+ }
+ if v.Name == "false" || v.Name == "true" {
+ return "bool", nil
+ }
+ if t, ok := w.curPackage.consts[v.Name]; ok {
+ return t.T, nil
+ }
+ return constDepPrefix + v.Name, nil
+ case *ast.BinaryExpr:
+ //== > < ! != >= <=
+ if v.Op == token.EQL || v.Op == token.LSS || v.Op == token.GTR || v.Op == token.NOT ||
+ v.Op == token.NEQ || v.Op == token.LEQ || v.Op == token.GEQ {
+ return "bool", nil
+ }
+ left, err := w.constValueType(v.X)
+ if err != nil {
+ return "", err
+ }
+ if v.Op == token.SHL || v.Op == token.SHR {
+ return left, err
+ }
+ right, err := w.constValueType(v.Y)
+ if err != nil {
+ return "", err
+ }
+ //const left != right , one or two is ideal-
+ if left != right {
+ if strings.HasPrefix(left, constDepPrefix) && strings.HasPrefix(right, constDepPrefix) {
+ // Just pick one.
+ // e.g. text/scanner GoTokens const-dependency:ScanIdents, const-dependency:ScanFloats
+ return left, nil
+ }
+ lp := constTypePriority(w.constRealType(left))
+ rp := constTypePriority(w.constRealType(right))
+ if lp >= rp {
+ return left, nil
+ } else {
+ return right, nil
+ }
+ return "", fmt.Errorf("in BinaryExpr, unhandled type mismatch; left=%q, right=%q", left, right)
+ }
+ return left, nil
+ case *ast.CallExpr:
+ // Not a call, but a type conversion.
+ typ := w.nodeString(v.Fun)
+ switch typ {
+ case "complex":
+ return "complex128", nil
+ case "real", "imag":
+ return "float64", nil
+ }
+ return typ, nil
+ case *ast.ParenExpr:
+ return w.constValueType(v.X)
+ }
+ return "", fmt.Errorf("unknown const value type %T", vi)
+}
+
+func (w *Walker) pkgRetType(pkg, ret string) string {
+ pkg = pkg[strings.LastIndex(pkg, "/")+1:]
+ if strings.HasPrefix(ret, "[]") {
+ return "[]" + w.pkgRetType(pkg, ret[2:])
+ }
+ if strings.HasPrefix(ret, "*") {
+ return "*" + w.pkgRetType(pkg, ret[1:])
+ }
+ if ast.IsExported(ret) {
+ return pkg + "." + ret
+ }
+ return ret
+}
+
+func (w *Walker) findStructFieldType(st ast.Expr, name string) ast.Expr {
+ _, expr := w.findStructField(st, name)
+ return expr
+}
+
+func (w *Walker) findStructFieldFunction(st ast.Expr, name string) (*TypeInfo, error) {
+ if s, ok := st.(*ast.StructType); ok {
+ for _, fi := range s.Fields.List {
+ typ := fi.Type
+ if fi.Names == nil {
+ switch v := typ.(type) {
+ case *ast.Ident:
+ if t := w.curPackage.findType(v.Name); t != nil {
+ return w.lookupFunction(v.Name, name)
+ }
+ case *ast.SelectorExpr:
+ pt := w.nodeString(typ)
+ pos := strings.Index(pt, ".")
+ if pos != -1 {
+ if p := w.findPackage(pt[:pos]); p != nil {
+ if t := p.findType(pt[pos+1:]); t != nil {
+ return w.lookupFunction(pt, name)
+ }
+ }
+ }
+ case *ast.StarExpr:
+ return w.findStructFieldFunction(v.X, name)
+ default:
+ if apiVerbose {
+ log.Printf("unable to handle embedded %T", typ)
+ }
+ }
+ }
+ }
+ }
+ return nil, nil
+}
+
+func (w *Walker) findStructField(st ast.Expr, name string) (*ast.Ident, ast.Expr) {
+ if s, ok := st.(*ast.StructType); ok {
+ for _, fi := range s.Fields.List {
+ typ := fi.Type
+ for _, n := range fi.Names {
+ if n.Name == name {
+ return n, fi.Type
+ }
+ }
+ if fi.Names == nil {
+ switch v := typ.(type) {
+ case *ast.Ident:
+ if t := w.curPackage.findType(v.Name); t != nil {
+ if v.Name == name {
+ return v, v
+ }
+ id, expr := w.findStructField(t, name)
+ if id != nil {
+ return id, expr
+ }
+ }
+ case *ast.StarExpr:
+ switch vv := v.X.(type) {
+ case *ast.Ident:
+ if t := w.curPackage.findType(vv.Name); t != nil {
+ if vv.Name == name {
+ return vv, v.X
+ }
+ id, expr := w.findStructField(t, name)
+ if id != nil {
+ return id, expr
+ }
+ }
+ case *ast.SelectorExpr:
+ pt := w.nodeString(typ)
+ pos := strings.Index(pt, ".")
+ if pos != -1 {
+ if p := w.findPackage(pt[:pos]); p != nil {
+ if t := p.findType(pt[pos+1:]); t != nil {
+ return w.findStructField(t, name)
+ }
+ }
+ }
+ default:
+ if apiVerbose {
+ log.Printf("unable to handle embedded starexpr before %T", typ)
+ }
+ }
+ case *ast.SelectorExpr:
+ pt := w.nodeString(typ)
+ pos := strings.Index(pt, ".")
+ if pos != -1 {
+ if p := w.findPackage(pt[:pos]); p != nil {
+ if t := p.findType(pt[pos+1:]); t != nil {
+ return w.findStructField(t, name)
+ }
+ }
+ }
+ default:
+ if apiVerbose {
+ log.Printf("unable to handle embedded %T", typ)
+ }
+ }
+ }
+ }
+ }
+ return nil, nil
+}
+
+func (w *Walker) lookupFunction(name, sel string) (*TypeInfo, error) {
+ name = strings.TrimLeft(name, "*")
+ if p := w.findPackage(name); p != nil {
+ fn := p.findCallFunc(sel)
+ if fn != nil {
+ return &TypeInfo{Kind: KindFunc, X: fn, Name: name + "." + sel, T: fn, Type: w.nodeString(w.namelessType(fn))}, nil
+ }
+ }
+ pos := strings.Index(name, ".")
+ if pos != -1 {
+ pkg := name[:pos]
+ typ := name[pos+1:]
+ if p := w.findPackage(pkg); p != nil {
+ if ident, fn := p.findMethod(typ, sel); fn != nil {
+ return &TypeInfo{Kind: KindMethod, X: fn, Name: name + "." + sel, T: ident, Type: w.nodeString(w.namelessType(fn))}, nil
+ }
+ }
+ return nil, fmt.Errorf("not lookup pkg type function pkg: %s, %s. %s. %s", name, pkg, typ, sel)
+ }
+
+ //find local var.func()
+ if ns, nt, n := w.resolveName(name); n >= 0 {
+ var vt string
+ if nt != nil {
+ vt = w.nodeString(w.namelessType(nt))
+ } else if ns != nil {
+ typ, err := w.varValueType(ns, n)
+ if err == nil {
+ vt = typ
+ }
+ } else {
+ typ := w.curPackage.findSelectorType(name)
+ if typ != nil {
+ vt = w.nodeString(w.namelessType(typ))
+ }
+ }
+ if strings.HasPrefix(vt, "*") {
+ vt = vt[1:]
+ }
+ if vt == "error" && sel == "Error" {
+ return &TypeInfo{Kind: KindBuiltin, Name: "error.Error", Type: "()string"}, nil
+ }
+ if fn, ok := w.curPackage.functions[vt+"."+sel]; ok {
+ return &TypeInfo{Kind: KindMethod, X: fn.ft, Name: name + "." + sel, T: fn.ft, Type: w.nodeString(w.namelessType(fn))}, nil
+ }
+ }
+ if typ, ok := w.curPackage.structs[name]; ok {
+ if fn, ok := w.curPackage.functions[name+"."+sel]; ok {
+ return &TypeInfo{Kind: KindMethod, X: fn.ft, Name: name + "." + sel, T: fn.ft, Type: w.nodeString(w.namelessType(fn.ft))}, nil
+ }
+ if info, err := w.findStructFieldFunction(typ, sel); err == nil {
+ return info, nil
+ }
+ // struct field is type function
+ if ft := w.findStructFieldType(typ, sel); ft != nil {
+ typ, err := w.varValueType(ft, 0)
+ if err != nil {
+ typ = w.nodeString(ft)
+ }
+ return &TypeInfo{Kind: KindField, X: ft, Name: name + "." + sel, T: ft, Type: typ}, nil
+ }
+ }
+
+ if ident, fn := w.curPackage.findMethod(name, sel); ident != nil && fn != nil {
+ return &TypeInfo{Kind: KindMethod, X: fn, Name: name + "." + sel, T: ident, Type: w.nodeString(w.namelessType(fn))}, nil
+ }
+
+ if p := w.findPackage(name); p != nil {
+ fn := p.findCallFunc(sel)
+ if fn != nil {
+ return &TypeInfo{Kind: KindFunc, X: fn, Name: name + "." + sel, T: fn, Type: w.nodeString(w.namelessType(fn))}, nil
+ }
+ return nil, fmt.Errorf("not find pkg func0 %v.%v", p.name, sel)
+ }
+ return nil, fmt.Errorf("not lookup func %v.%v", name, sel)
+}
+
+func (w *Walker) varFunctionType(name, sel string, index int) (string, error) {
+ name = strings.TrimLeft(name, "*")
+ pos := strings.Index(name, ".")
+ if pos != -1 {
+ pkg := name[:pos]
+ typ := name[pos+1:]
+
+ if p := w.findPackage(pkg); p != nil {
+ _, fn := p.findMethod(typ, sel)
+ if fn != nil {
+ ret := funcRetType(fn, index)
+ if ret != nil {
+ return w.pkgRetType(p.name, w.nodeString(w.namelessType(ret))), nil
+ }
+ }
+ }
+ return "", fmt.Errorf("unknown pkg type function pkg: %s.%s.%s", pkg, typ, sel)
+ }
+ //find local var
+ if v, ok := w.localvar[name]; ok {
+ vt := v.T
+ if strings.HasPrefix(vt, "*") {
+ vt = vt[1:]
+ }
+ if vt == "error" && sel == "Error" {
+ return "string", nil
+ }
+ typ, err := w.varFunctionType(vt, sel, 0)
+ if err == nil {
+ return typ, nil
+ }
+ }
+ //find global var.func()
+ if ns, nt, n := w.resolveName(name); n >= 0 {
+ var vt string
+ if nt != nil {
+ vt = w.nodeString(w.namelessType(nt))
+ } else if ns != nil {
+ typ, err := w.varValueType(ns, n)
+ if err == nil {
+ vt = typ
+ }
+ } else {
+ typ := w.curPackage.findSelectorType(name)
+ if typ != nil {
+ vt = w.nodeString(w.namelessType(typ))
+ }
+ }
+ if strings.HasPrefix(vt, "*") {
+ vt = vt[1:]
+ }
+ if vt == "error" && sel == "Error" {
+ return "string", nil
+ }
+ if fn, ok := w.curPackage.functions[vt+"."+sel]; ok {
+ return w.nodeString(w.namelessType(funcRetType(fn.ft, index))), nil
+ }
+ }
+ if typ, ok := w.curPackage.structs[name]; ok {
+ if ft := w.findStructFieldType(typ, sel); ft != nil {
+ return w.varValueType(ft, index)
+ }
+ }
+ //find pkg.func()
+ if p := w.findPackage(name); p != nil {
+ typ := p.findCallType(sel, index)
+ if typ != nil {
+ return w.pkgRetType(p.name, w.nodeString(w.namelessType(typ))), nil
+ }
+ //log.Println("->", p.functions)
+ return "", fmt.Errorf("not find pkg func1 %v . %v", p.name, sel)
+ }
+ return "", fmt.Errorf("not find func %v.%v", name, sel)
+}
+
+func (w *Walker) lookupSelector(name string, sel string) (*TypeInfo, error) {
+ name = strings.TrimLeft(name, "*")
+ pos := strings.Index(name, ".")
+ if pos != -1 {
+ pkg := name[:pos]
+ typ := name[pos+1:]
+ if p := w.findPackage(pkg); p != nil {
+ t := p.findType(typ)
+ if t != nil {
+ typ := w.findStructFieldType(t, sel)
+ if typ != nil {
+ return &TypeInfo{Kind: KindField, X: typ, Name: name + "." + sel, T: typ, Type: w.pkgRetType(p.name, w.nodeString(w.namelessType(typ)))}, nil
+ }
+ }
+ }
+ return nil, fmt.Errorf("lookup unknown pkg type selector pkg: %s.%s %s", pkg, typ, sel)
+ }
+
+ if lv, ok := w.localvar[name]; ok {
+ return w.lookupSelector(lv.T, sel)
+ }
+
+ vs, vt, n := w.resolveName(name)
+ if n >= 0 {
+ var typ string
+ if vt != nil {
+ typ = w.nodeString(w.namelessType(vt))
+ } else {
+ typ, _ = w.varValueType(vs, n)
+ }
+ if strings.HasPrefix(typ, "*") {
+ typ = typ[1:]
+ }
+ //typ is type, find real type
+ for k, v := range w.curPackage.types {
+ if k == typ {
+ typ = w.nodeString(w.namelessType(v))
+ }
+ }
+ pos := strings.Index(typ, ".")
+ if pos == -1 {
+ t := w.curPackage.findType(typ)
+ if t != nil {
+ typ := w.findStructFieldType(t, sel)
+ if typ != nil {
+ return &TypeInfo{Kind: KindField, X: typ, Name: name + "." + sel, T: typ, Type: w.nodeString(w.namelessType(typ))}, nil
+ }
+ }
+ } else {
+ name := typ[:pos]
+ typ = typ[pos+1:]
+ if p := w.findPackage(name); p != nil {
+ t := p.findType(typ)
+ if t != nil {
+ typ := w.findStructFieldType(t, sel)
+ if typ != nil {
+ return &TypeInfo{Kind: KindField, X: typ, Name: name + "." + sel, T: typ, Type: w.nodeString(w.namelessType(typ))}, nil
+ }
+ }
+ }
+ }
+ }
+ if p := w.findPackage(name); p != nil {
+ typ := p.findSelectorType(sel)
+ if typ != nil {
+ return &TypeInfo{Kind: KindType, X: typ, Name: name + "." + sel, T: typ, Type: w.pkgRetType(p.name, w.nodeString(w.namelessType(typ)))}, nil
+ }
+ }
+ t := w.curPackage.findType(name)
+ if t != nil {
+ typ := w.findStructFieldType(t, sel)
+ if typ != nil {
+ return &TypeInfo{Kind: KindField, X: typ, Name: name + "." + sel, T: typ, Type: w.nodeString(w.namelessType(typ))}, nil
+ }
+ }
+ if t, ok := w.curPackage.types[name]; ok {
+ return w.lookupSelector(w.nodeString(t), sel)
+ }
+ return nil, fmt.Errorf("unknown selector expr ident: %s.%s", name, sel)
+}
+
+func (w *Walker) varSelectorType(name string, sel string) (string, error) {
+ name = strings.TrimLeft(name, "*")
+ pos := strings.Index(name, ".")
+ if pos != -1 {
+ pkg := name[:pos]
+ typ := name[pos+1:]
+ if p := w.findPackage(pkg); p != nil {
+ t := p.findType(typ)
+ if t != nil {
+ typ := w.findStructFieldType(t, sel)
+ if typ != nil {
+ return w.pkgRetType(pkg, w.nodeString(w.namelessType(typ))), nil
+ }
+ }
+ }
+ return "", fmt.Errorf("unknown pkg type selector pkg: %s.%s.%s", pkg, typ, sel)
+ }
+ //check local
+ if lv, ok := w.localvar[name]; ok {
+ return w.varSelectorType(lv.T, sel)
+ }
+ //check struct
+ if t := w.curPackage.findType(name); t != nil {
+ typ := w.findStructFieldType(t, sel)
+ if typ != nil {
+ return w.nodeString(w.namelessType(typ)), nil
+ }
+ }
+ //check var
+ vs, vt, n := w.resolveName(name)
+ if n >= 0 {
+ var typ string
+ if vt != nil {
+ typ = w.nodeString(w.namelessType(vt))
+ } else {
+ typ, _ = w.varValueType(vs, n)
+ }
+ if strings.HasPrefix(typ, "*") {
+ typ = typ[1:]
+ }
+ //typ is type, find real type
+ for k, v := range w.curPackage.types {
+ if k == typ {
+ typ = w.nodeString(w.namelessType(v))
+ }
+ }
+ pos := strings.Index(typ, ".")
+ if pos == -1 {
+ t := w.curPackage.findType(typ)
+ if t != nil {
+ typ := w.findStructFieldType(t, sel)
+ if typ != nil {
+ return w.nodeString(w.namelessType(typ)), nil
+ }
+ }
+ } else {
+ name := typ[:pos]
+ typ = typ[pos+1:]
+ if p := w.findPackage(name); p != nil {
+ t := p.findType(typ)
+ if t != nil {
+ typ := w.findStructFieldType(t, sel)
+ if typ != nil {
+ return w.nodeString(w.namelessType(typ)), nil
+ }
+ }
+ }
+ }
+ }
+
+ if p := w.findPackage(name); p != nil {
+ typ := p.findSelectorType(sel)
+ if typ != nil {
+ return w.pkgRetType(p.name, w.nodeString(w.namelessType(typ))), nil
+ }
+ }
+ return "", fmt.Errorf("unknown var selector expr ident: %s.%s", name, sel)
+}
+
+func (w *Walker) varValueType(vi ast.Expr, index int) (string, error) {
+ if vi == nil {
+ return "", nil
+ }
+ switch v := vi.(type) {
+ case *ast.BasicLit:
+ litType, ok := varType[v.Kind]
+ if !ok {
+ return "", fmt.Errorf("unknown basic literal kind %#v", v)
+ }
+ return litType, nil
+ case *ast.CompositeLit:
+ return w.nodeString(v.Type), nil
+ case *ast.FuncLit:
+ return w.nodeString(w.namelessType(v.Type)), nil
+ case *ast.InterfaceType:
+ return w.nodeString(v), nil
+ case *ast.Ellipsis:
+ typ, err := w.varValueType(v.Elt, index)
+ if err != nil {
+ return "", err
+ }
+ return "[]" + typ, nil
+ case *ast.StarExpr:
+ typ, err := w.varValueType(v.X, index)
+ if err != nil {
+ return "", err
+ }
+ return "*" + typ, err
+ case *ast.UnaryExpr:
+ if v.Op == token.AND {
+ typ, err := w.varValueType(v.X, index)
+ return "*" + typ, err
+ }
+ return "", fmt.Errorf("unknown unary expr: %#v", v)
+ case *ast.SelectorExpr:
+ switch st := v.X.(type) {
+ case *ast.Ident:
+ return w.varSelectorType(st.Name, v.Sel.Name)
+ case *ast.CallExpr:
+ typ, err := w.varValueType(v.X, index)
+ if err == nil {
+ if strings.HasPrefix(typ, "*") {
+ typ = typ[1:]
+ }
+ t := w.curPackage.findType(typ)
+ if st, ok := t.(*ast.StructType); ok {
+ for _, fi := range st.Fields.List {
+ for _, n := range fi.Names {
+ if n.Name == v.Sel.Name {
+ return w.varValueType(fi.Type, index)
+ }
+ }
+ }
+ }
+ }
+ case *ast.SelectorExpr:
+ typ, err := w.varValueType(v.X, index)
+ if err == nil {
+ return w.varSelectorType(typ, v.Sel.Name)
+ }
+ case *ast.IndexExpr:
+ typ, err := w.varValueType(st.X, index)
+ if err == nil {
+ if strings.HasPrefix(typ, "[]") {
+ return w.varSelectorType(typ[2:], v.Sel.Name)
+ }
+ }
+ case *ast.CompositeLit:
+ typ, err := w.varValueType(st.Type, 0)
+ if err == nil {
+ //log.Println(typ, v.Sel.Name)
+ t, err := w.varSelectorType(typ, v.Sel.Name)
+ if err == nil {
+ return t, nil
+ }
+ }
+ }
+ return "", fmt.Errorf("var unknown selector expr: %T %s.%s", v.X, w.nodeString(v.X), v.Sel)
+ case *ast.Ident:
+ if v.Name == "true" || v.Name == "false" {
+ return "bool", nil
+ }
+ if isBuiltinType(v.Name) {
+ return v.Name, nil
+ }
+ if lv, ok := w.localvar[v.Name]; ok {
+ return lv.T, nil
+ }
+ vt := w.curPackage.findType(v.Name)
+ if vt != nil {
+ if _, ok := vt.(*ast.StructType); ok {
+ return v.Name, nil
+ }
+ return w.nodeString(vt), nil
+ }
+ vs, _, n := w.resolveName(v.Name)
+ if n >= 0 {
+ return w.varValueType(vs, n)
+ }
+ return "", fmt.Errorf("unresolved identifier: %q", v.Name)
+ case *ast.BinaryExpr:
+ //== > < ! != >= <=
+ if v.Op == token.EQL || v.Op == token.LSS || v.Op == token.GTR || v.Op == token.NOT ||
+ v.Op == token.NEQ || v.Op == token.LEQ || v.Op == token.GEQ {
+ return "bool", nil
+ }
+ left, err := w.varValueType(v.X, index)
+ if err != nil {
+ return "", err
+ }
+ right, err := w.varValueType(v.Y, index)
+ if err != nil {
+ return "", err
+ }
+ if left != right {
+ return "", fmt.Errorf("in BinaryExpr, unhandled type mismatch; left=%q, right=%q", left, right)
+ }
+ return left, nil
+ case *ast.ParenExpr:
+ return w.varValueType(v.X, index)
+ case *ast.CallExpr:
+ switch ft := v.Fun.(type) {
+ case *ast.ArrayType:
+ return w.nodeString(v.Fun), nil
+ case *ast.Ident:
+ switch ft.Name {
+ case "make":
+ return w.nodeString(w.namelessType(v.Args[0])), nil
+ case "new":
+ return "*" + w.nodeString(w.namelessType(v.Args[0])), nil
+ case "append":
+ return w.varValueType(v.Args[0], 0)
+ case "recover":
+ return "interface{}", nil
+ case "len", "cap", "copy":
+ return "int", nil
+ case "complex":
+ return "complex128", nil
+ case "real":
+ return "float64", nil
+ case "imag":
+ return "float64", nil
+ }
+ if isBuiltinType(ft.Name) {
+ return ft.Name, nil
+ }
+ typ := w.curPackage.findCallType(ft.Name, index)
+ if typ != nil {
+ return w.nodeString(w.namelessType(typ)), nil
+ }
+ //if local var type
+ if fn, ok := w.localvar[ft.Name]; ok {
+ typ := fn.T
+ if strings.HasPrefix(typ, "func(") {
+ expr, err := parser.ParseExpr(typ + "{}")
+ if err == nil {
+ if fl, ok := expr.(*ast.FuncLit); ok {
+ retType := funcRetType(fl.Type, index)
+ if retType != nil {
+ return w.nodeString(w.namelessType(retType)), nil
+ }
+ }
+ }
+ }
+ }
+ //if var is func() type
+ vs, _, n := w.resolveName(ft.Name)
+ if n >= 0 {
+ if vs != nil {
+ typ, err := w.varValueType(vs, n)
+ if err == nil {
+ if strings.HasPrefix(typ, "func(") {
+ expr, err := parser.ParseExpr(typ + "{}")
+ if err == nil {
+ if fl, ok := expr.(*ast.FuncLit); ok {
+ retType := funcRetType(fl.Type, index)
+ if retType != nil {
+ return w.nodeString(w.namelessType(retType)), nil
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ return "", fmt.Errorf("unknown funcion %s %s", w.curPackageName, ft.Name)
+ case *ast.SelectorExpr:
+ typ, err := w.varValueType(ft.X, index)
+ if err == nil {
+ if strings.HasPrefix(typ, "*") {
+ typ = typ[1:]
+ }
+ retType := w.curPackage.findCallType(typ+"."+ft.Sel.Name, index)
+ if retType != nil {
+ return w.nodeString(w.namelessType(retType)), nil
+ }
+ }
+ switch st := ft.X.(type) {
+ case *ast.Ident:
+ return w.varFunctionType(st.Name, ft.Sel.Name, index)
+ case *ast.CallExpr:
+ typ, err := w.varValueType(st, 0)
+ if err != nil {
+ return "", err
+ }
+ return w.varFunctionType(typ, ft.Sel.Name, index)
+ case *ast.SelectorExpr:
+ typ, err := w.varValueType(st, index)
+ if err == nil {
+ return w.varFunctionType(typ, ft.Sel.Name, index)
+ }
+ case *ast.IndexExpr:
+ typ, err := w.varValueType(st.X, index)
+ if err == nil {
+ if strings.HasPrefix(typ, "[]") {
+ return w.varFunctionType(typ[2:], ft.Sel.Name, index)
+ }
+ }
+ case *ast.TypeAssertExpr:
+ typ := w.nodeString(w.namelessType(st.Type))
+ typ = strings.TrimLeft(typ, "*")
+ return w.varFunctionType(typ, ft.Sel.Name, index)
+ }
+ return "", fmt.Errorf("unknown var function selector %v %T", w.nodeString(ft.X), ft.X)
+ case *ast.FuncLit:
+ retType := funcRetType(ft.Type, index)
+ if retType != nil {
+ return w.nodeString(w.namelessType(retType)), nil
+ }
+ case *ast.CallExpr:
+ typ, err := w.varValueType(v.Fun, 0)
+ if err == nil && strings.HasPrefix(typ, "func(") {
+ expr, err := parser.ParseExpr(typ + "{}")
+ if err == nil {
+ if fl, ok := expr.(*ast.FuncLit); ok {
+ retType := funcRetType(fl.Type, index)
+ if retType != nil {
+ return w.nodeString(w.namelessType(retType)), nil
+ }
+ }
+ }
+ }
+ }
+ return "", fmt.Errorf("not a known function %T %v", v.Fun, w.nodeString(v.Fun))
+ case *ast.MapType:
+ return fmt.Sprintf("map[%s](%s)", w.nodeString(w.namelessType(v.Key)), w.nodeString(w.namelessType(v.Value))), nil
+ case *ast.ArrayType:
+ return fmt.Sprintf("[]%s", w.nodeString(w.namelessType(v.Elt))), nil
+ case *ast.FuncType:
+ return w.nodeString(w.namelessType(v)), nil
+ case *ast.IndexExpr:
+ typ, err := w.varValueType(v.X, index)
+ typ = strings.TrimLeft(typ, "*")
+ if err == nil {
+ if index == 0 {
+ return typ, nil
+ } else if index == 1 {
+ return "bool", nil
+ }
+ if strings.HasPrefix(typ, "[]") {
+ return typ[2:], nil
+ } else if strings.HasPrefix(typ, "map[") {
+ node, err := parser.ParseExpr(typ + "{}")
+ if err == nil {
+ if cl, ok := node.(*ast.CompositeLit); ok {
+ if m, ok := cl.Type.(*ast.MapType); ok {
+ return w.nodeString(w.namelessType(m.Value)), nil
+ }
+ }
+ }
+ }
+ }
+ return "", fmt.Errorf("unknown index %v %v %v %v", typ, v.X, index, err)
+ case *ast.SliceExpr:
+ return w.varValueType(v.X, index)
+ case *ast.ChanType:
+ typ, err := w.varValueType(v.Value, index)
+ if err == nil {
+ if v.Dir == ast.RECV {
+ return "<-chan " + typ, nil
+ } else if v.Dir == ast.SEND {
+ return "chan<- " + typ, nil
+ }
+ return "chan " + typ, nil
+ }
+ case *ast.TypeAssertExpr:
+ if index == 1 {
+ return "bool", nil
+ }
+ return w.nodeString(w.namelessType(v.Type)), nil
+ default:
+ return "", fmt.Errorf("unknown value type %v %T", w.nodeString(vi), vi)
+ }
+ //panic("unreachable")
+ return "", fmt.Errorf("unreachable value type %v %T", vi, vi)
+}
+
+// resolveName finds a top-level node named name and returns the node
+// v and its type t, if known.
+func (w *Walker) resolveName(name string) (v ast.Expr, t interface{}, n int) {
+ for _, file := range w.curPackage.apkg.Files {
+ for _, di := range file.Decls {
+ switch d := di.(type) {
+ case *ast.GenDecl:
+ switch d.Tok {
+ case token.VAR:
+ for _, sp := range d.Specs {
+ vs := sp.(*ast.ValueSpec)
+ for i, vname := range vs.Names {
+ if vname.Name == name {
+ if len(vs.Values) == 1 {
+ return vs.Values[0], vs.Type, i
+ }
+ return nil, vs.Type, i
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ return nil, nil, -1
+}
+
+// constDepPrefix is a magic prefix that is used by constValueType
+// and walkConst to signal that a type isn't known yet. These are
+// resolved at the end of walking of a package's files.
+const constDepPrefix = "const-dependency:"
+
+func (w *Walker) walkConst(vs *ast.ValueSpec) {
+ for _, ident := range vs.Names {
+ if !w.isExtract(ident.Name) {
+ continue
+ }
+ litType := ""
+ if vs.Type != nil {
+ litType = w.nodeString(vs.Type)
+ } else {
+ litType = w.lastConstType
+ if vs.Values != nil {
+ if len(vs.Values) != 1 {
+ log.Fatalf("const %q, values: %#v", ident.Name, vs.Values)
+ }
+ var err error
+ litType, err = w.constValueType(vs.Values[0])
+ if err != nil {
+ if apiVerbose {
+ log.Printf("unknown kind in const %q (%T): %v", ident.Name, vs.Values[0], err)
+ }
+ litType = "unknown-type"
+ }
+ }
+ }
+ if strings.HasPrefix(litType, constDepPrefix) {
+ dep := litType[len(constDepPrefix):]
+ w.constDep[ident.Name] = &ExprType{T: dep, X: ident}
+ continue
+ }
+ if litType == "" {
+ if apiVerbose {
+ log.Printf("unknown kind in const %q", ident.Name)
+ }
+ continue
+ }
+ w.lastConstType = litType
+
+ w.curPackage.consts[ident.Name] = &ExprType{T: litType, X: ident}
+
+ if isExtract(ident.Name) {
+ w.emitFeature(fmt.Sprintf("const %s %s", ident, litType), ident.Pos())
+ }
+ }
+}
+
+func (w *Walker) resolveConstantDeps() {
+ var findConstType func(string) string
+ findConstType = func(ident string) string {
+ if dep, ok := w.constDep[ident]; ok {
+ return findConstType(dep.T)
+ }
+ if t, ok := w.curPackage.consts[ident]; ok {
+ return t.T
+ }
+ return ""
+ }
+ for ident, info := range w.constDep {
+ if !isExtract(ident) {
+ continue
+ }
+ t := findConstType(ident)
+ if t == "" {
+ if apiVerbose {
+ log.Printf("failed to resolve constant %q", ident)
+ }
+ continue
+ }
+ w.curPackage.consts[ident] = &ExprType{T: t, X: info.X}
+ w.emitFeature(fmt.Sprintf("const %s %s", ident, t), info.X.Pos())
+ }
+}
+
+func (w *Walker) walkVar(vs *ast.ValueSpec) {
+ if vs.Type != nil {
+ typ := w.nodeString(vs.Type)
+ for _, ident := range vs.Names {
+ w.curPackage.vars[ident.Name] = &ExprType{T: typ, X: ident}
+ if isExtract(ident.Name) {
+ w.emitFeature(fmt.Sprintf("var %s %s", ident, typ), ident.Pos())
+ }
+ }
+ } else if len(vs.Names) == len(vs.Values) {
+ for n, ident := range vs.Names {
+ if !w.isExtract(ident.Name) {
+ continue
+ }
+ typ, err := w.varValueType(vs.Values[n], n)
+ if err != nil {
+ if apiVerbose {
+ log.Printf("unknown type of variable0 %q, type %T, error = %v, pos=%s",
+ ident.Name, vs.Values[n], err, w.fset.Position(vs.Pos()))
+ }
+ typ = "unknown-type"
+ }
+ w.curPackage.vars[ident.Name] = &ExprType{T: typ, X: ident}
+ if isExtract(ident.Name) {
+ w.emitFeature(fmt.Sprintf("var %s %s", ident, typ), ident.Pos())
+ }
+ }
+ } else if len(vs.Values) == 1 {
+ for n, ident := range vs.Names {
+ if !w.isExtract(ident.Name) {
+ continue
+ }
+ typ, err := w.varValueType(vs.Values[0], n)
+ if err != nil {
+ if apiVerbose {
+ log.Printf("unknown type of variable1 %q, type %T, error = %v, pos=%s",
+ ident.Name, vs.Values[0], err, w.fset.Position(vs.Pos()))
+ }
+ typ = "unknown-type"
+ }
+ w.curPackage.vars[ident.Name] = &ExprType{T: typ, X: ident}
+ if isExtract(ident.Name) {
+ w.emitFeature(fmt.Sprintf("var %s %s", ident, typ), ident.Pos())
+ }
+ }
+ }
+}
+
+func (w *Walker) nodeString(node interface{}) string {
+ if node == nil {
+ return ""
+ }
+ var b bytes.Buffer
+ printer.Fprint(&b, w.fset, node)
+ return b.String()
+}
+
+func (w *Walker) nodeDebug(node interface{}) string {
+ if node == nil {
+ return ""
+ }
+ var b bytes.Buffer
+ ast.Fprint(&b, w.fset, node, nil)
+ return b.String()
+}
+
+func (w *Walker) noteInterface(name string, it *ast.InterfaceType) {
+ w.interfaces[pkgSymbol{w.curPackageName, name}] = it
+}
+
+func (w *Walker) walkTypeSpec(ts *ast.TypeSpec) {
+ name := ts.Name.Name
+ if !isExtract(name) {
+ return
+ }
+ switch t := ts.Type.(type) {
+ case *ast.StructType:
+ w.walkStructType(name, t)
+ case *ast.InterfaceType:
+ w.walkInterfaceType(name, t)
+ default:
+ w.emitFeature(fmt.Sprintf("type %s %s", name, w.nodeString(ts.Type)), t.Pos()-token.Pos(len(name)+1))
+ }
+}
+
+func (w *Walker) walkStructType(name string, t *ast.StructType) {
+ typeStruct := fmt.Sprintf("type %s struct", name)
+ w.emitFeature(typeStruct, t.Pos()-token.Pos(len(name)+1))
+ pop := w.pushScope(typeStruct)
+ defer pop()
+ for _, f := range t.Fields.List {
+ typ := f.Type
+ for _, name := range f.Names {
+ if isExtract(name.Name) {
+ w.emitFeature(fmt.Sprintf("%s %s", name, w.nodeString(w.namelessType(typ))), name.Pos())
+ }
+ }
+ if f.Names == nil {
+ switch v := typ.(type) {
+ case *ast.Ident:
+ if isExtract(v.Name) {
+ w.emitFeature(fmt.Sprintf("embedded %s", v.Name), v.Pos())
+ }
+ case *ast.StarExpr:
+ switch vv := v.X.(type) {
+ case *ast.Ident:
+ if isExtract(vv.Name) {
+ w.emitFeature(fmt.Sprintf("embedded *%s", vv.Name), vv.Pos())
+ }
+ case *ast.SelectorExpr:
+ w.emitFeature(fmt.Sprintf("embedded %s", w.nodeString(typ)), v.Pos())
+ default:
+ log.Fatalf("unable to handle embedded starexpr before %T", typ)
+ }
+ case *ast.SelectorExpr:
+ w.emitFeature(fmt.Sprintf("embedded %s", w.nodeString(typ)), v.Pos())
+ default:
+ if apiVerbose {
+ log.Printf("unable to handle embedded %T", typ)
+ }
+ }
+ }
+ }
+}
+
+// typeMethod is a method of an interface.
+type typeMethod struct {
+ name string // "Read"
+ sig string // "([]byte) (int, error)", from funcSigString
+ ft *ast.FuncType
+ pos token.Pos
+ recv ast.Expr
+}
+
+// interfaceMethods returns the expanded list of exported methods for an interface.
+// The boolean complete reports whether the list contains all methods (that is, the
+// interface has no unexported methods).
+// pkg is the complete package name ("net/http")
+// iname is the interface name.
+func (w *Walker) interfaceMethods(pkg, iname string) (methods []typeMethod, complete bool) {
+ t, ok := w.interfaces[pkgSymbol{pkg, iname}]
+ if !ok {
+ if apiVerbose {
+ log.Printf("failed to find interface %s.%s", pkg, iname)
+ }
+ return
+ }
+
+ complete = true
+ for _, f := range t.Methods.List {
+ typ := f.Type
+ switch tv := typ.(type) {
+ case *ast.FuncType:
+ for _, mname := range f.Names {
+ if isExtract(mname.Name) {
+ ft := typ.(*ast.FuncType)
+ methods = append(methods, typeMethod{
+ name: mname.Name,
+ sig: w.funcSigString(ft),
+ ft: ft,
+ pos: f.Pos(),
+ })
+ } else {
+ complete = false
+ }
+ }
+ case *ast.Ident:
+ embedded := typ.(*ast.Ident).Name
+ if embedded == "error" {
+ methods = append(methods, typeMethod{
+ name: "Error",
+ sig: "() string",
+ ft: &ast.FuncType{
+ Params: nil,
+ Results: &ast.FieldList{
+ List: []*ast.Field{
+ &ast.Field{
+ Type: &ast.Ident{
+ Name: "string",
+ },
+ },
+ },
+ },
+ },
+ pos: f.Pos(),
+ })
+ continue
+ }
+ if !isExtract(embedded) {
+ log.Fatalf("unexported embedded interface %q in exported interface %s.%s; confused",
+ embedded, pkg, iname)
+ }
+ m, c := w.interfaceMethods(pkg, embedded)
+ methods = append(methods, m...)
+ complete = complete && c
+ case *ast.SelectorExpr:
+ lhs := w.nodeString(tv.X)
+ rhs := w.nodeString(tv.Sel)
+ fpkg, ok := w.selectorFullPkg[lhs]
+ if !ok {
+ log.Fatalf("can't resolve selector %q in interface %s.%s", lhs, pkg, iname)
+ }
+ m, c := w.interfaceMethods(fpkg, rhs)
+ methods = append(methods, m...)
+ complete = complete && c
+ default:
+ log.Fatalf("unknown type %T in interface field", typ)
+ }
+ }
+ return
+}
+
+func (w *Walker) walkInterfaceType(name string, t *ast.InterfaceType) {
+ methNames := []string{}
+ pop := w.pushScope("type " + name + " interface")
+ methods, complete := w.interfaceMethods(w.curPackageName, name)
+ w.packageMap[w.curPackageName].interfaceMethods[name] = methods
+ for _, m := range methods {
+ methNames = append(methNames, m.name)
+ w.emitFeature(fmt.Sprintf("%s%s", m.name, m.sig), m.pos)
+ }
+ if !complete {
+ // The method set has unexported methods, so all the
+ // implementations are provided by the same package,
+ // so the method set can be extended. Instead of recording
+ // the full set of names (below), record only that there were
+ // unexported methods. (If the interface shrinks, we will notice
+ // because a method signature emitted during the last loop,
+ // will disappear.)
+ w.emitFeature("unexported methods", 0)
+ }
+ pop()
+
+ if !complete {
+ return
+ }
+
+ sort.Strings(methNames)
+ if len(methNames) == 0 {
+ w.emitFeature(fmt.Sprintf("type %s interface {}", name), t.Pos()-token.Pos(len(name)+1))
+ } else {
+ w.emitFeature(fmt.Sprintf("type %s interface { %s }", name, strings.Join(methNames, ", ")), t.Pos()-token.Pos(len(name)+1))
+ }
+}
+
+func baseTypeName(x ast.Expr) (name string, imported bool) {
+ switch t := x.(type) {
+ case *ast.Ident:
+ return t.Name, false
+ case *ast.SelectorExpr:
+ if _, ok := t.X.(*ast.Ident); ok {
+ // only possible for qualified type names;
+ // assume type is imported
+ return t.Sel.Name, true
+ }
+ case *ast.StarExpr:
+ return baseTypeName(t.X)
+ }
+ return
+}
+
+func (w *Walker) peekFuncDecl(f *ast.FuncDecl) {
+ var fname = f.Name.Name
+ var recv ast.Expr
+ if f.Recv != nil {
+ recvTypeName, imp := baseTypeName(f.Recv.List[0].Type)
+ if imp {
+ return
+ }
+ fname = recvTypeName + "." + f.Name.Name
+ recv = f.Recv.List[0].Type
+ }
+ // Record return type for later use.
+ //if f.Type.Results != nil && len(f.Type.Results.List) >= 1 {
+ // record all function
+ w.curPackage.functions[fname] = typeMethod{
+ name: fname,
+ sig: w.funcSigString(f.Type),
+ ft: f.Type,
+ pos: f.Pos(),
+ recv: recv,
+ }
+ //}
+}
+
+func (w *Walker) walkFuncDecl(f *ast.FuncDecl) {
+ if !w.isExtract(f.Name.Name) {
+ return
+ }
+ if f.Recv != nil {
+ // Method.
+ recvType := w.nodeString(f.Recv.List[0].Type)
+ keep := isExtract(recvType) ||
+ (strings.HasPrefix(recvType, "*") &&
+ isExtract(recvType[1:]))
+ if !keep {
+ return
+ }
+ w.emitFeature(fmt.Sprintf("method (%s) %s%s", recvType, f.Name.Name, w.funcSigString(f.Type)), f.Name.Pos())
+ return
+ }
+ // Else, a function
+ w.emitFeature(fmt.Sprintf("func %s%s", f.Name.Name, w.funcSigString(f.Type)), f.Name.Pos())
+}
+
+func (w *Walker) funcSigString(ft *ast.FuncType) string {
+ var b bytes.Buffer
+ writeField := func(b *bytes.Buffer, f *ast.Field) {
+ if n := len(f.Names); n > 1 {
+ for i := 0; i < n; i++ {
+ if i > 0 {
+ b.WriteString(", ")
+ }
+ b.WriteString(w.nodeString(w.namelessType(f.Type)))
+ }
+ } else {
+ b.WriteString(w.nodeString(w.namelessType(f.Type)))
+ }
+ }
+ b.WriteByte('(')
+ if ft.Params != nil {
+ for i, f := range ft.Params.List {
+ if i > 0 {
+ b.WriteString(", ")
+ }
+ writeField(&b, f)
+ }
+ }
+ b.WriteByte(')')
+ if ft.Results != nil {
+ nr := 0
+ for _, f := range ft.Results.List {
+ if n := len(f.Names); n > 1 {
+ nr += n
+ } else {
+ nr++
+ }
+ }
+ if nr > 0 {
+ b.WriteByte(' ')
+ if nr > 1 {
+ b.WriteByte('(')
+ }
+ for i, f := range ft.Results.List {
+ if i > 0 {
+ b.WriteString(", ")
+ }
+ writeField(&b, f)
+ }
+ if nr > 1 {
+ b.WriteByte(')')
+ }
+ }
+ }
+ return b.String()
+}
+
+// namelessType returns a type node that lacks any variable names.
+func (w *Walker) namelessType(t interface{}) interface{} {
+ ft, ok := t.(*ast.FuncType)
+ if !ok {
+ return t
+ }
+ return &ast.FuncType{
+ Params: w.namelessFieldList(ft.Params),
+ Results: w.namelessFieldList(ft.Results),
+ }
+}
+
+// namelessFieldList returns a deep clone of fl, with the cloned fields
+// lacking names.
+func (w *Walker) namelessFieldList(fl *ast.FieldList) *ast.FieldList {
+ fl2 := &ast.FieldList{}
+ if fl != nil {
+ for _, f := range fl.List {
+ n := len(f.Names)
+ if n >= 1 {
+ for i := 0; i < n; i++ {
+ fl2.List = append(fl2.List, w.namelessField(f))
+ }
+ } else {
+ fl2.List = append(fl2.List, w.namelessField(f))
+ }
+ }
+ }
+ return fl2
+}
+
+// namelessField clones f, but not preserving the names of fields.
+// (comments and tags are also ignored)
+func (w *Walker) namelessField(f *ast.Field) *ast.Field {
+ return &ast.Field{
+ Type: f.Type,
+ }
+}
+
+func (w *Walker) emitFeature(feature string, pos token.Pos) {
+ if !w.wantedPkg[w.curPackage.name] {
+ return
+ }
+ more := strings.Index(feature, "\n")
+ if more != -1 {
+ if len(feature) <= 1024 {
+ feature = strings.Replace(feature, "\n", " ", 1)
+ feature = strings.Replace(feature, "\n", ";", -1)
+ feature = strings.Replace(feature, "\t", " ", -1)
+ } else {
+ feature = feature[:more] + " ...more"
+ if apiVerbose {
+ log.Printf("feature contains newlines: %v, %s", feature, w.fset.Position(pos))
+ }
+ }
+ }
+ f := strings.Join(w.scope, w.sep) + w.sep + feature
+
+ if _, dup := w.curPackage.features[f]; dup {
+ return
+ }
+ w.curPackage.features[f] = pos
+}
+
+func strListContains(l []string, s string) bool {
+ for _, v := range l {
+ if v == s {
+ return true
+ }
+ }
+ return false
+}
+
+const goosList = "darwin freebsd linux netbsd openbsd plan9 windows "
+const goarchList = "386 amd64 arm "
+
+// goodOSArchFile returns false if the name contains a $GOOS or $GOARCH
+// suffix which does not match the current system.
+// The recognized name formats are:
+//
+// name_$(GOOS).*
+// name_$(GOARCH).*
+// name_$(GOOS)_$(GOARCH).*
+// name_$(GOOS)_test.*
+// name_$(GOARCH)_test.*
+// name_$(GOOS)_$(GOARCH)_test.*
+//
+func isOSArchFile(ctxt *build.Context, name string) bool {
+ if dot := strings.Index(name, "."); dot != -1 {
+ name = name[:dot]
+ }
+ l := strings.Split(name, "_")
+ if n := len(l); n > 0 && l[n-1] == "test" {
+ l = l[:n-1]
+ }
+ n := len(l)
+ if n >= 2 && knownOS[l[n-2]] && knownArch[l[n-1]] {
+ return l[n-2] == ctxt.GOOS && l[n-1] == ctxt.GOARCH
+ }
+ if n >= 1 && knownOS[l[n-1]] {
+ return l[n-1] == ctxt.GOOS
+ }
+ if n >= 1 && knownArch[l[n-1]] {
+ return l[n-1] == ctxt.GOARCH
+ }
+ return false
+}
+
+var knownOS = make(map[string]bool)
+var knownArch = make(map[string]bool)
+
+func init() {
+ for _, v := range strings.Fields(goosList) {
+ knownOS[v] = true
+ }
+ for _, v := range strings.Fields(goarchList) {
+ knownArch[v] = true
+ }
+}
diff --git a/vendor/github.com/visualfc/gotools/goimports/fix.go b/vendor/github.com/visualfc/gotools/goimports/fix.go
new file mode 100644
index 0000000..0fabc77
--- /dev/null
+++ b/vendor/github.com/visualfc/gotools/goimports/fix.go
@@ -0,0 +1,394 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package goimports
+
+import (
+ "fmt"
+ "go/ast"
+ "go/build"
+ "go/parser"
+ "go/token"
+ "os"
+ "path"
+ "path/filepath"
+ "strings"
+ "sync"
+
+ "github.com/visualfc/gotools/stdlib"
+
+ "golang.org/x/tools/go/ast/astutil"
+)
+
+// importToGroup is a list of functions which map from an import path to
+// a group number.
+var importToGroup = []func(importPath string) (num int, ok bool){
+ func(importPath string) (num int, ok bool) {
+ if strings.HasPrefix(importPath, "appengine") {
+ return 2, true
+ }
+ return
+ },
+ func(importPath string) (num int, ok bool) {
+ if strings.Contains(importPath, ".") {
+ return 1, true
+ }
+ return
+ },
+}
+
+func importGroup(importPath string) int {
+ for _, fn := range importToGroup {
+ if n, ok := fn(importPath); ok {
+ return n
+ }
+ }
+ return 0
+}
+
+func fixImports(fset *token.FileSet, f *ast.File) (added []string, err error) {
+ // refs are a set of possible package references currently unsatisfied by imports.
+ // first key: either base package (e.g. "fmt") or renamed package
+ // second key: referenced package symbol (e.g. "Println")
+ refs := make(map[string]map[string]bool)
+
+ // decls are the current package imports. key is base package or renamed package.
+ decls := make(map[string]*ast.ImportSpec)
+
+ // collect potential uses of packages.
+ var visitor visitFn
+ visitor = visitFn(func(node ast.Node) ast.Visitor {
+ if node == nil {
+ return visitor
+ }
+ switch v := node.(type) {
+ case *ast.ImportSpec:
+ if v.Name != nil {
+ decls[v.Name.Name] = v
+ } else {
+ local := importPathToName(strings.Trim(v.Path.Value, `\"`))
+ decls[local] = v
+ }
+ case *ast.SelectorExpr:
+ xident, ok := v.X.(*ast.Ident)
+ if !ok {
+ break
+ }
+ if xident.Obj != nil {
+ // if the parser can resolve it, it's not a package ref
+ break
+ }
+ pkgName := xident.Name
+ if refs[pkgName] == nil {
+ refs[pkgName] = make(map[string]bool)
+ }
+ if decls[pkgName] == nil {
+ refs[pkgName][v.Sel.Name] = true
+ }
+ }
+ return visitor
+ })
+ ast.Walk(visitor, f)
+
+ // Search for imports matching potential package references.
+ searches := 0
+ type result struct {
+ ipath string
+ name string
+ err error
+ }
+ results := make(chan result)
+ for pkgName, symbols := range refs {
+ if len(symbols) == 0 {
+ continue // skip over packages already imported
+ }
+ go func(pkgName string, symbols map[string]bool) {
+ ipath, rename, err := findImport(pkgName, symbols)
+ r := result{ipath: ipath, err: err}
+ if rename {
+ r.name = pkgName
+ }
+ results <- r
+ }(pkgName, symbols)
+ searches++
+ }
+ for i := 0; i < searches; i++ {
+ result := <-results
+ if result.err != nil {
+ return nil, result.err
+ }
+ if result.ipath != "" {
+ if result.name != "" {
+ astutil.AddNamedImport(fset, f, result.name, result.ipath)
+ } else {
+ astutil.AddImport(fset, f, result.ipath)
+ }
+ added = append(added, result.ipath)
+ }
+ }
+
+ // Nil out any unused ImportSpecs, to be removed in following passes
+ unusedImport := map[string]bool{}
+ for pkg, is := range decls {
+ if refs[pkg] == nil && pkg != "_" && pkg != "." {
+ unusedImport[strings.Trim(is.Path.Value, `"`)] = true
+ }
+ }
+ for ipath := range unusedImport {
+ if ipath == "C" {
+ // Don't remove cgo stuff.
+ continue
+ }
+ astutil.DeleteImport(fset, f, ipath)
+ }
+
+ return added, nil
+}
+
+// importPathToName returns the package name for the given import path.
+var importPathToName = importPathToNameGoPath
+
+// importPathToNameBasic assumes the package name is the base of import path.
+func importPathToNameBasic(importPath string) (packageName string) {
+ return path.Base(importPath)
+}
+
+// importPathToNameGoPath finds out the actual package name, as declared in its .go files.
+// If there's a problem, it falls back to using importPathToNameBasic.
+func importPathToNameGoPath(importPath string) (packageName string) {
+ if stdlib.IsStdPkg(importPath) {
+ return path.Base(importPath)
+ }
+ if buildPkg, err := build.Import(importPath, "", 0); err == nil {
+ return buildPkg.Name
+ } else {
+ return importPathToNameBasic(importPath)
+ }
+}
+
+type pkg struct {
+ importpath string // full pkg import path, e.g. "net/http"
+ dir string // absolute file path to pkg directory e.g. "/usr/lib/go/src/fmt"
+}
+
+var pkgIndexOnce sync.Once
+
+var pkgIndex struct {
+ sync.Mutex
+ m map[string][]pkg // shortname => []pkg, e.g "http" => "net/http"
+}
+
+// gate is a semaphore for limiting concurrency.
+type gate chan struct{}
+
+func (g gate) enter() { g <- struct{}{} }
+func (g gate) leave() { <-g }
+
+// fsgate protects the OS & filesystem from too much concurrency.
+// Too much disk I/O -> too many threads -> swapping and bad scheduling.
+var fsgate = make(gate, 8)
+
+func loadPkgIndex() {
+ pkgIndex.Lock()
+ pkgIndex.m = make(map[string][]pkg)
+ pkgIndex.Unlock()
+
+ var wg sync.WaitGroup
+ for _, path := range build.Default.SrcDirs() {
+ fsgate.enter()
+ f, err := os.Open(path)
+ if err != nil {
+ fsgate.leave()
+ fmt.Fprint(os.Stderr, err)
+ continue
+ }
+ children, err := f.Readdir(-1)
+ f.Close()
+ fsgate.leave()
+ if err != nil {
+ fmt.Fprint(os.Stderr, err)
+ continue
+ }
+ for _, child := range children {
+ if child.IsDir() {
+ wg.Add(1)
+ go func(path, name string) {
+ defer wg.Done()
+ loadPkg(&wg, path, name)
+ }(path, child.Name())
+ }
+ }
+ }
+ wg.Wait()
+}
+
+func loadPkg(wg *sync.WaitGroup, root, pkgrelpath string) {
+ importpath := filepath.ToSlash(pkgrelpath)
+ dir := filepath.Join(root, importpath)
+
+ fsgate.enter()
+ defer fsgate.leave()
+ pkgDir, err := os.Open(dir)
+ if err != nil {
+ return
+ }
+ children, err := pkgDir.Readdir(-1)
+ pkgDir.Close()
+ if err != nil {
+ return
+ }
+ // hasGo tracks whether a directory actually appears to be a
+ // Go source code directory. If $GOPATH == $HOME, and
+ // $HOME/src has lots of other large non-Go projects in it,
+ // then the calls to importPathToName below can be expensive.
+ hasGo := false
+ for _, child := range children {
+ name := child.Name()
+ if name == "" {
+ continue
+ }
+ if c := name[0]; c == '.' || ('0' <= c && c <= '9') {
+ continue
+ }
+ if strings.HasSuffix(name, ".go") {
+ hasGo = true
+ }
+ if child.IsDir() {
+ wg.Add(1)
+ go func(root, name string) {
+ defer wg.Done()
+ loadPkg(wg, root, name)
+ }(root, filepath.Join(importpath, name))
+ }
+ }
+ if hasGo {
+ shortName := importPathToName(importpath)
+ pkgIndex.Lock()
+ pkgIndex.m[shortName] = append(pkgIndex.m[shortName], pkg{
+ importpath: importpath,
+ dir: dir,
+ })
+ pkgIndex.Unlock()
+ }
+
+}
+
+// loadExports returns a list exports for a package.
+var loadExports = loadExportsGoPath
+
+func loadExportsGoPath(dir string) map[string]bool {
+ exports := make(map[string]bool)
+ buildPkg, err := build.ImportDir(dir, 0)
+ if err != nil {
+ if strings.Contains(err.Error(), "no buildable Go source files in") {
+ return nil
+ }
+ fmt.Fprintf(os.Stderr, "could not import %q: %v\n", dir, err)
+ return nil
+ }
+ fset := token.NewFileSet()
+ for _, files := range [...][]string{buildPkg.GoFiles, buildPkg.CgoFiles} {
+ for _, file := range files {
+ f, err := parser.ParseFile(fset, filepath.Join(dir, file), nil, 0)
+ if err != nil {
+ fmt.Fprintf(os.Stderr, "could not parse %q: %v\n", file, err)
+ continue
+ }
+ for name := range f.Scope.Objects {
+ if ast.IsExported(name) {
+ exports[name] = true
+ }
+ }
+ }
+ }
+ return exports
+}
+
+// findImport searches for a package with the given symbols.
+// If no package is found, findImport returns "".
+// Declared as a variable rather than a function so goimports can be easily
+// extended by adding a file with an init function.
+var findImport = findImportGoPath
+
+func findImportGoPath(pkgName string, symbols map[string]bool) (string, bool, error) {
+ // Fast path for the standard library.
+ // In the common case we hopefully never have to scan the GOPATH, which can
+ // be slow with moving disks.
+ if pkg, rename, ok := findImportStdlib(pkgName, symbols); ok {
+ return pkg, rename, nil
+ }
+
+ // TODO(sameer): look at the import lines for other Go files in the
+ // local directory, since the user is likely to import the same packages
+ // in the current Go file. Return rename=true when the other Go files
+ // use a renamed package that's also used in the current file.
+
+ pkgIndexOnce.Do(loadPkgIndex)
+
+ // Collect exports for packages with matching names.
+ var wg sync.WaitGroup
+ var pkgsMu sync.Mutex // guards pkgs
+ // full importpath => exported symbol => True
+ // e.g. "net/http" => "Client" => True
+ pkgs := make(map[string]map[string]bool)
+ pkgIndex.Lock()
+ for _, pkg := range pkgIndex.m[pkgName] {
+ wg.Add(1)
+ go func(importpath, dir string) {
+ defer wg.Done()
+ exports := loadExports(dir)
+ if exports != nil {
+ pkgsMu.Lock()
+ pkgs[importpath] = exports
+ pkgsMu.Unlock()
+ }
+ }(pkg.importpath, pkg.dir)
+ }
+ pkgIndex.Unlock()
+ wg.Wait()
+
+ // Filter out packages missing required exported symbols.
+ for symbol := range symbols {
+ for importpath, exports := range pkgs {
+ if !exports[symbol] {
+ delete(pkgs, importpath)
+ }
+ }
+ }
+ if len(pkgs) == 0 {
+ return "", false, nil
+ }
+
+ // If there are multiple candidate packages, the shortest one wins.
+ // This is a heuristic to prefer the standard library (e.g. "bytes")
+ // over e.g. "github.com/foo/bar/bytes".
+ shortest := ""
+ for importPath := range pkgs {
+ if shortest == "" || len(importPath) < len(shortest) {
+ shortest = importPath
+ }
+ }
+ return shortest, false, nil
+}
+
+type visitFn func(node ast.Node) ast.Visitor
+
+func (fn visitFn) Visit(node ast.Node) ast.Visitor {
+ return fn(node)
+}
+
+func findImportStdlib(shortPkg string, symbols map[string]bool) (importPath string, rename, ok bool) {
+ for symbol := range symbols {
+ path := stdlib.Symbols[shortPkg+"."+symbol]
+ if path == "" {
+ return "", false, false
+ }
+ if importPath != "" && importPath != path {
+ // Ambiguous. Symbols pointed to different things.
+ return "", false, false
+ }
+ importPath = path
+ }
+ return importPath, false, importPath != ""
+}
diff --git a/vendor/github.com/visualfc/gotools/goimports/goimports.go b/vendor/github.com/visualfc/gotools/goimports/goimports.go
new file mode 100644
index 0000000..0a9b108
--- /dev/null
+++ b/vendor/github.com/visualfc/gotools/goimports/goimports.go
@@ -0,0 +1,206 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package goimports
+
+import (
+ "bytes"
+ "fmt"
+ "go/parser"
+ "go/printer"
+ "go/scanner"
+ "go/token"
+ "io"
+ "io/ioutil"
+ "os"
+ "os/exec"
+ "path/filepath"
+ "runtime"
+ "strings"
+ "sync"
+
+ "github.com/visualfc/gotools/command"
+)
+
+var Command = &command.Command{
+ Run: runGoimports,
+ UsageLine: "goimports [flags] [path ...]",
+ Short: "updates go import lines",
+ Long: `goimports updates your Go import lines, adding missing ones and removing unreferenced ones. `,
+}
+
+var (
+ goimportsList bool
+ goimportsWrite bool
+ goimportsDiff bool
+ goimportsAllErrors bool
+
+ // layout control
+ goimportsComments bool
+ goimportsTabWidth int
+ goimportsTabIndent bool
+)
+
+//func init
+func init() {
+ Command.Flag.BoolVar(&goimportsList, "l", false, "list files whose formatting differs from goimport's")
+ Command.Flag.BoolVar(&goimportsWrite, "w", false, "write result to (source) file instead of stdout")
+ Command.Flag.BoolVar(&goimportsDiff, "d", false, "display diffs instead of rewriting files")
+ Command.Flag.BoolVar(&goimportsAllErrors, "e", false, "report all errors (not just the first 10 on different lines)")
+
+ // layout control
+ Command.Flag.BoolVar(&goimportsComments, "comments", true, "print comments")
+ Command.Flag.IntVar(&goimportsTabWidth, "tabwidth", 8, "tab width")
+ Command.Flag.BoolVar(&goimportsTabIndent, "tabs", true, "indent with tabs")
+}
+
+var (
+ fileSet = token.NewFileSet() // per process FileSet
+ exitCode = 0
+
+ initModesOnce sync.Once // guards calling initModes
+ parserMode parser.Mode
+ printerMode printer.Mode
+ options *Options
+)
+
+func report(err error) {
+ scanner.PrintError(os.Stderr, err)
+ exitCode = 2
+}
+
+func runGoimports(cmd *command.Command, args []string) error {
+ runtime.GOMAXPROCS(runtime.NumCPU())
+
+ if goimportsTabWidth < 0 {
+ fmt.Fprintf(os.Stderr, "negative tabwidth %d\n", goimportsTabWidth)
+ exitCode = 2
+ os.Exit(exitCode)
+ return os.ErrInvalid
+ }
+
+ options = &Options{
+ TabWidth: goimportsTabWidth,
+ TabIndent: goimportsTabIndent,
+ Comments: goimportsComments,
+ AllErrors: goimportsAllErrors,
+ Fragment: true,
+ }
+
+ if len(args) == 0 {
+ if err := processFile("", os.Stdin, os.Stdout, true); err != nil {
+ report(err)
+ }
+ } else {
+ for _, path := range args {
+ switch dir, err := os.Stat(path); {
+ case err != nil:
+ report(err)
+ case dir.IsDir():
+ walkDir(path)
+ default:
+ if err := processFile(path, nil, os.Stdout, false); err != nil {
+ report(err)
+ }
+ }
+ }
+ }
+ os.Exit(exitCode)
+ return nil
+}
+
+func isGoFile(f os.FileInfo) bool {
+ // ignore non-Go files
+ name := f.Name()
+ return !f.IsDir() && !strings.HasPrefix(name, ".") && strings.HasSuffix(name, ".go")
+}
+
+func processFile(filename string, in io.Reader, out io.Writer, stdin bool) error {
+ if in == nil {
+ f, err := os.Open(filename)
+ if err != nil {
+ return err
+ }
+ defer f.Close()
+ in = f
+ }
+
+ src, err := ioutil.ReadAll(in)
+ if err != nil {
+ return err
+ }
+
+ res, err := Process(filename, src, options)
+ if err != nil {
+ return err
+ }
+
+ if !bytes.Equal(src, res) {
+ // formatting has changed
+ if goimportsList {
+ fmt.Fprintln(out, filename)
+ }
+ if goimportsWrite {
+ err = ioutil.WriteFile(filename, res, 0)
+ if err != nil {
+ return err
+ }
+ }
+ if goimportsDiff {
+ data, err := diff(src, res)
+ if err != nil {
+ return fmt.Errorf("computing diff: %s", err)
+ }
+ fmt.Printf("diff %s gofmt/%s\n", filename, filename)
+ out.Write(data)
+ }
+ }
+
+ if !goimportsList && !goimportsWrite && !goimportsDiff {
+ _, err = out.Write(res)
+ }
+
+ return err
+}
+
+func visitFile(path string, f os.FileInfo, err error) error {
+ if err == nil && isGoFile(f) {
+ err = processFile(path, nil, os.Stdout, false)
+ }
+ if err != nil {
+ report(err)
+ }
+ return nil
+}
+
+func walkDir(path string) {
+ filepath.Walk(path, visitFile)
+}
+
+func diff(b1, b2 []byte) (data []byte, err error) {
+ f1, err := ioutil.TempFile("", "gofmt")
+ if err != nil {
+ return
+ }
+ defer os.Remove(f1.Name())
+ defer f1.Close()
+
+ f2, err := ioutil.TempFile("", "gofmt")
+ if err != nil {
+ return
+ }
+ defer os.Remove(f2.Name())
+ defer f2.Close()
+
+ f1.Write(b1)
+ f2.Write(b2)
+
+ data, err = exec.Command("diff", "-u", f1.Name(), f2.Name()).CombinedOutput()
+ if len(data) > 0 {
+ // diff exits with a non-zero status when the files don't match.
+ // Ignore that failure as long as we get output.
+ err = nil
+ }
+ return
+}
diff --git a/vendor/github.com/visualfc/gotools/goimports/imports.go b/vendor/github.com/visualfc/gotools/goimports/imports.go
new file mode 100644
index 0000000..161b5c0
--- /dev/null
+++ b/vendor/github.com/visualfc/gotools/goimports/imports.go
@@ -0,0 +1,281 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package imports implements a Go pretty-printer (like package "go/format")
+// that also adds or removes import statements as necessary.
+package goimports
+
+import (
+ "bufio"
+ "bytes"
+ "fmt"
+ "go/ast"
+ "go/format"
+ "go/parser"
+ "go/printer"
+ "go/token"
+ "io"
+ "regexp"
+ "strconv"
+ "strings"
+
+ "golang.org/x/tools/go/ast/astutil"
+)
+
+// Options specifies options for processing files.
+type Options struct {
+ Fragment bool // Accept fragment of a source file (no package statement)
+ AllErrors bool // Report all errors (not just the first 10 on different lines)
+
+ Comments bool // Print comments (true if nil *Options provided)
+ TabIndent bool // Use tabs for indent (true if nil *Options provided)
+ Format bool
+ TabWidth int // Tab width (8 if nil *Options provided)
+}
+
+// Process formats and adjusts imports for the provided file.
+// If opt is nil the defaults are used.
+func Process(filename string, src []byte, opt *Options) ([]byte, error) {
+ if opt == nil {
+ opt = &Options{Comments: true, TabIndent: true, TabWidth: 8}
+ }
+
+ fileSet := token.NewFileSet()
+ file, adjust, err := goImportParse(fileSet, filename, src, opt)
+ if err != nil {
+ return nil, err
+ }
+
+ _, err = fixImports(fileSet, file)
+ if err != nil {
+ return nil, err
+ }
+
+ sortImports(fileSet, file)
+ imps := astutil.Imports(fileSet, file)
+
+ var spacesBefore []string // import paths we need spaces before
+ for _, impSection := range imps {
+ // Within each block of contiguous imports, see if any
+ // import lines are in different group numbers. If so,
+ // we'll need to put a space between them so it's
+ // compatible with gofmt.
+ lastGroup := -1
+ for _, importSpec := range impSection {
+ importPath, _ := strconv.Unquote(importSpec.Path.Value)
+ groupNum := importGroup(importPath)
+ if groupNum != lastGroup && lastGroup != -1 {
+ spacesBefore = append(spacesBefore, importPath)
+ }
+ lastGroup = groupNum
+ }
+
+ }
+
+ printerMode := printer.UseSpaces
+ if opt.TabIndent {
+ printerMode |= printer.TabIndent
+ }
+ printConfig := &printer.Config{Mode: printerMode, Tabwidth: opt.TabWidth}
+
+ var buf bytes.Buffer
+ err = printConfig.Fprint(&buf, fileSet, file)
+ if err != nil {
+ return nil, err
+ }
+ out := buf.Bytes()
+ if adjust != nil {
+ out = adjust(src, out)
+ }
+ if len(spacesBefore) > 0 {
+ out = addImportSpaces(bytes.NewReader(out), spacesBefore)
+ }
+ if opt.Format {
+ out, err = format.Source(out)
+ if err != nil {
+ return nil, err
+ }
+ }
+ return out, nil
+}
+
+// parse parses src, which was read from filename,
+// as a Go source file or statement list.
+func goImportParse(fset *token.FileSet, filename string, src []byte, opt *Options) (*ast.File, func(orig, src []byte) []byte, error) {
+ parserMode := parser.Mode(0)
+ if opt.Comments {
+ parserMode |= parser.ParseComments
+ }
+ if opt.AllErrors {
+ parserMode |= parser.AllErrors
+ }
+
+ // Try as whole source file.
+ file, err := parser.ParseFile(fset, filename, src, parserMode)
+ if err == nil {
+ return file, nil, nil
+ }
+ // If the error is that the source file didn't begin with a
+ // package line and we accept fragmented input, fall through to
+ // try as a source fragment. Stop and return on any other error.
+ if !opt.Fragment || !strings.Contains(err.Error(), "expected 'package'") {
+ return nil, nil, err
+ }
+
+ // If this is a declaration list, make it a source file
+ // by inserting a package clause.
+ // Insert using a ;, not a newline, so that the line numbers
+ // in psrc match the ones in src.
+ psrc := append([]byte("package main;"), src...)
+ file, err = parser.ParseFile(fset, filename, psrc, parserMode)
+ if err == nil {
+ // If a main function exists, we will assume this is a main
+ // package and leave the file.
+ if containsMainFunc(file) {
+ return file, nil, nil
+ }
+
+ adjust := func(orig, src []byte) []byte {
+ // Remove the package clause.
+ // Gofmt has turned the ; into a \n.
+ src = src[len("package main\n"):]
+ return matchSpace(orig, src)
+ }
+ return file, adjust, nil
+ }
+ // If the error is that the source file didn't begin with a
+ // declaration, fall through to try as a statement list.
+ // Stop and return on any other error.
+ if !strings.Contains(err.Error(), "expected declaration") {
+ return nil, nil, err
+ }
+
+ // If this is a statement list, make it a source file
+ // by inserting a package clause and turning the list
+ // into a function body. This handles expressions too.
+ // Insert using a ;, not a newline, so that the line numbers
+ // in fsrc match the ones in src.
+ fsrc := append(append([]byte("package p; func _() {"), src...), '}')
+ file, err = parser.ParseFile(fset, filename, fsrc, parserMode)
+ if err == nil {
+ adjust := func(orig, src []byte) []byte {
+ // Remove the wrapping.
+ // Gofmt has turned the ; into a \n\n.
+ src = src[len("package p\n\nfunc _() {"):]
+ src = src[:len(src)-len("}\n")]
+ // Gofmt has also indented the function body one level.
+ // Remove that indent.
+ src = bytes.Replace(src, []byte("\n\t"), []byte("\n"), -1)
+ return matchSpace(orig, src)
+ }
+ return file, adjust, nil
+ }
+
+ // Failed, and out of options.
+ return nil, nil, err
+}
+
+// containsMainFunc checks if a file contains a function declaration with the
+// function signature 'func main()'
+func containsMainFunc(file *ast.File) bool {
+ for _, decl := range file.Decls {
+ if f, ok := decl.(*ast.FuncDecl); ok {
+ if f.Name.Name != "main" {
+ continue
+ }
+
+ if len(f.Type.Params.List) != 0 {
+ continue
+ }
+
+ if f.Type.Results != nil && len(f.Type.Results.List) != 0 {
+ continue
+ }
+
+ return true
+ }
+ }
+
+ return false
+}
+
+func cutSpace(b []byte) (before, middle, after []byte) {
+ i := 0
+ for i < len(b) && (b[i] == ' ' || b[i] == '\t' || b[i] == '\n') {
+ i++
+ }
+ j := len(b)
+ for j > 0 && (b[j-1] == ' ' || b[j-1] == '\t' || b[j-1] == '\n') {
+ j--
+ }
+ if i <= j {
+ return b[:i], b[i:j], b[j:]
+ }
+ return nil, nil, b[j:]
+}
+
+// matchSpace reformats src to use the same space context as orig.
+// 1) If orig begins with blank lines, matchSpace inserts them at the beginning of src.
+// 2) matchSpace copies the indentation of the first non-blank line in orig
+// to every non-blank line in src.
+// 3) matchSpace copies the trailing space from orig and uses it in place
+// of src's trailing space.
+func matchSpace(orig []byte, src []byte) []byte {
+ before, _, after := cutSpace(orig)
+ i := bytes.LastIndex(before, []byte{'\n'})
+ before, indent := before[:i+1], before[i+1:]
+
+ _, src, _ = cutSpace(src)
+
+ var b bytes.Buffer
+ b.Write(before)
+ for len(src) > 0 {
+ line := src
+ if i := bytes.IndexByte(line, '\n'); i >= 0 {
+ line, src = line[:i+1], line[i+1:]
+ } else {
+ src = nil
+ }
+ if len(line) > 0 && line[0] != '\n' { // not blank
+ b.Write(indent)
+ }
+ b.Write(line)
+ }
+ b.Write(after)
+ return b.Bytes()
+}
+
+var impLine = regexp.MustCompile(`^\s+(?:[\w\.]+\s+)?"(.+)"`)
+
+func addImportSpaces(r io.Reader, breaks []string) []byte {
+ var out bytes.Buffer
+ sc := bufio.NewScanner(r)
+ inImports := false
+ done := false
+ for sc.Scan() {
+ s := sc.Text()
+
+ if !inImports && !done && strings.HasPrefix(s, "import") {
+ inImports = true
+ }
+ if inImports && (strings.HasPrefix(s, "var") ||
+ strings.HasPrefix(s, "func") ||
+ strings.HasPrefix(s, "const") ||
+ strings.HasPrefix(s, "type")) {
+ done = true
+ inImports = false
+ }
+ if inImports && len(breaks) > 0 {
+ if m := impLine.FindStringSubmatch(s); m != nil {
+ if m[1] == string(breaks[0]) {
+ out.WriteByte('\n')
+ breaks = breaks[1:]
+ }
+ }
+ }
+
+ fmt.Fprintln(&out, s)
+ }
+ return out.Bytes()
+}
diff --git a/vendor/github.com/visualfc/gotools/goimports/sortimports.go b/vendor/github.com/visualfc/gotools/goimports/sortimports.go
new file mode 100644
index 0000000..35eaac7
--- /dev/null
+++ b/vendor/github.com/visualfc/gotools/goimports/sortimports.go
@@ -0,0 +1,214 @@
+// +build go1.2
+
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Hacked up copy of go/ast/import.go
+
+package goimports
+
+import (
+ "go/ast"
+ "go/token"
+ "sort"
+ "strconv"
+)
+
+// sortImports sorts runs of consecutive import lines in import blocks in f.
+// It also removes duplicate imports when it is possible to do so without data loss.
+func sortImports(fset *token.FileSet, f *ast.File) {
+ for i, d := range f.Decls {
+ d, ok := d.(*ast.GenDecl)
+ if !ok || d.Tok != token.IMPORT {
+ // Not an import declaration, so we're done.
+ // Imports are always first.
+ break
+ }
+
+ if len(d.Specs) == 0 {
+ // Empty import block, remove it.
+ f.Decls = append(f.Decls[:i], f.Decls[i+1:]...)
+ }
+
+ if !d.Lparen.IsValid() {
+ // Not a block: sorted by default.
+ continue
+ }
+
+ // Identify and sort runs of specs on successive lines.
+ i := 0
+ specs := d.Specs[:0]
+ for j, s := range d.Specs {
+ if j > i && fset.Position(s.Pos()).Line > 1+fset.Position(d.Specs[j-1].End()).Line {
+ // j begins a new run. End this one.
+ specs = append(specs, sortSpecs(fset, f, d.Specs[i:j])...)
+ i = j
+ }
+ }
+ specs = append(specs, sortSpecs(fset, f, d.Specs[i:])...)
+ d.Specs = specs
+
+ // Deduping can leave a blank line before the rparen; clean that up.
+ if len(d.Specs) > 0 {
+ lastSpec := d.Specs[len(d.Specs)-1]
+ lastLine := fset.Position(lastSpec.Pos()).Line
+ if rParenLine := fset.Position(d.Rparen).Line; rParenLine > lastLine+1 {
+ fset.File(d.Rparen).MergeLine(rParenLine - 1)
+ }
+ }
+ }
+}
+
+func importPath(s ast.Spec) string {
+ t, err := strconv.Unquote(s.(*ast.ImportSpec).Path.Value)
+ if err == nil {
+ return t
+ }
+ return ""
+}
+
+func importName(s ast.Spec) string {
+ n := s.(*ast.ImportSpec).Name
+ if n == nil {
+ return ""
+ }
+ return n.Name
+}
+
+func importComment(s ast.Spec) string {
+ c := s.(*ast.ImportSpec).Comment
+ if c == nil {
+ return ""
+ }
+ return c.Text()
+}
+
+// collapse indicates whether prev may be removed, leaving only next.
+func collapse(prev, next ast.Spec) bool {
+ if importPath(next) != importPath(prev) || importName(next) != importName(prev) {
+ return false
+ }
+ return prev.(*ast.ImportSpec).Comment == nil
+}
+
+type posSpan struct {
+ Start token.Pos
+ End token.Pos
+}
+
+func sortSpecs(fset *token.FileSet, f *ast.File, specs []ast.Spec) []ast.Spec {
+ // Can't short-circuit here even if specs are already sorted,
+ // since they might yet need deduplication.
+ // A lone import, however, may be safely ignored.
+ if len(specs) <= 1 {
+ return specs
+ }
+
+ // Record positions for specs.
+ pos := make([]posSpan, len(specs))
+ for i, s := range specs {
+ pos[i] = posSpan{s.Pos(), s.End()}
+ }
+
+ // Identify comments in this range.
+ // Any comment from pos[0].Start to the final line counts.
+ lastLine := fset.Position(pos[len(pos)-1].End).Line
+ cstart := len(f.Comments)
+ cend := len(f.Comments)
+ for i, g := range f.Comments {
+ if g.Pos() < pos[0].Start {
+ continue
+ }
+ if i < cstart {
+ cstart = i
+ }
+ if fset.Position(g.End()).Line > lastLine {
+ cend = i
+ break
+ }
+ }
+ comments := f.Comments[cstart:cend]
+
+ // Assign each comment to the import spec preceding it.
+ importComment := map[*ast.ImportSpec][]*ast.CommentGroup{}
+ specIndex := 0
+ for _, g := range comments {
+ for specIndex+1 < len(specs) && pos[specIndex+1].Start <= g.Pos() {
+ specIndex++
+ }
+ s := specs[specIndex].(*ast.ImportSpec)
+ importComment[s] = append(importComment[s], g)
+ }
+
+ // Sort the import specs by import path.
+ // Remove duplicates, when possible without data loss.
+ // Reassign the import paths to have the same position sequence.
+ // Reassign each comment to abut the end of its spec.
+ // Sort the comments by new position.
+ sort.Sort(byImportSpec(specs))
+
+ // Dedup. Thanks to our sorting, we can just consider
+ // adjacent pairs of imports.
+ deduped := specs[:0]
+ for i, s := range specs {
+ if i == len(specs)-1 || !collapse(s, specs[i+1]) {
+ deduped = append(deduped, s)
+ } else {
+ p := s.Pos()
+ fset.File(p).MergeLine(fset.Position(p).Line)
+ }
+ }
+ specs = deduped
+
+ // Fix up comment positions
+ for i, s := range specs {
+ s := s.(*ast.ImportSpec)
+ if s.Name != nil {
+ s.Name.NamePos = pos[i].Start
+ }
+ s.Path.ValuePos = pos[i].Start
+ s.EndPos = pos[i].End
+ for _, g := range importComment[s] {
+ for _, c := range g.List {
+ c.Slash = pos[i].End
+ }
+ }
+ }
+
+ sort.Sort(byCommentPos(comments))
+
+ return specs
+}
+
+type byImportSpec []ast.Spec // slice of *ast.ImportSpec
+
+func (x byImportSpec) Len() int { return len(x) }
+func (x byImportSpec) Swap(i, j int) { x[i], x[j] = x[j], x[i] }
+func (x byImportSpec) Less(i, j int) bool {
+ ipath := importPath(x[i])
+ jpath := importPath(x[j])
+
+ igroup := importGroup(ipath)
+ jgroup := importGroup(jpath)
+ if igroup != jgroup {
+ return igroup < jgroup
+ }
+
+ if ipath != jpath {
+ return ipath < jpath
+ }
+ iname := importName(x[i])
+ jname := importName(x[j])
+
+ if iname != jname {
+ return iname < jname
+ }
+ return importComment(x[i]) < importComment(x[j])
+}
+
+type byCommentPos []*ast.CommentGroup
+
+func (x byCommentPos) Len() int { return len(x) }
+func (x byCommentPos) Swap(i, j int) { x[i], x[j] = x[j], x[i] }
+func (x byCommentPos) Less(i, j int) bool { return x[i].Pos() < x[j].Pos() }
diff --git a/vendor/github.com/visualfc/gotools/goimports/sortimports_compat.go b/vendor/github.com/visualfc/gotools/goimports/sortimports_compat.go
new file mode 100644
index 0000000..1624ce8
--- /dev/null
+++ b/vendor/github.com/visualfc/gotools/goimports/sortimports_compat.go
@@ -0,0 +1,14 @@
+// +build !go1.2
+
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package goimports
+
+import "go/ast"
+
+// Go 1.1 users don't get fancy package grouping.
+// But this is still gofmt-compliant:
+
+var sortImports = ast.SortImports
diff --git a/vendor/github.com/visualfc/gotools/gopresent/gopresent.go b/vendor/github.com/visualfc/gotools/gopresent/gopresent.go
new file mode 100644
index 0000000..e0242a2
--- /dev/null
+++ b/vendor/github.com/visualfc/gotools/gopresent/gopresent.go
@@ -0,0 +1,383 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//modify 2013-2014 visualfc
+
+package gopresent
+
+import (
+ "fmt"
+ "html/template"
+ "io"
+ "os"
+ "path/filepath"
+
+ "github.com/visualfc/gotools/command"
+ "golang.org/x/tools/present"
+)
+
+var Command = &command.Command{
+ Run: runPresent,
+ UsageLine: "gopresent",
+ Short: "golang present util",
+ Long: `golang present util`,
+}
+
+var presentVerifyOnly bool
+var presentInput string
+var presentStdout bool
+var presentOutput string
+
+func init() {
+ Command.Flag.BoolVar(&presentVerifyOnly, "v", false, "verify present only")
+ Command.Flag.BoolVar(&presentStdout, "stdout", false, "output use std output")
+ Command.Flag.StringVar(&presentInput, "i", "", "input golang present file")
+ Command.Flag.StringVar(&presentOutput, "o", "", "output html file name")
+}
+
+func runPresent(cmd *command.Command, args []string) error {
+ if presentInput == "" || !isDoc(presentInput) {
+ cmd.Usage()
+ return os.ErrInvalid
+ }
+
+ if presentVerifyOnly {
+ err := VerifyDoc(presentInput)
+ if err != nil {
+ fmt.Fprintf(os.Stderr, "present:%s", err)
+ command.SetExitStatus(3)
+ command.Exit()
+ }
+ return nil
+ }
+ w := os.Stdout
+ if !presentStdout {
+ if presentOutput == "" {
+ presentOutput = presentInput + ".html"
+ }
+ ext := filepath.Ext(presentOutput)
+ if ext != ".htm" && ext != ".html" {
+ presentOutput += ".html"
+ }
+ var err error
+ w, err = os.Create(presentOutput)
+ if err != nil {
+ fmt.Fprintf(os.Stderr, "present:%s", err)
+ command.SetExitStatus(3)
+ command.Exit()
+ }
+ }
+ err := RenderDoc(w, presentInput)
+ if err != nil {
+ fmt.Fprintf(os.Stderr, "present:%s", err)
+ command.SetExitStatus(3)
+ command.Exit()
+ }
+ return nil
+}
+
+var extensions = map[string]string{
+ ".slide": "slides.tmpl",
+ ".article": "article.tmpl",
+}
+
+var extensions_tmpl = map[string]string{
+ ".slide": slides_tmpl,
+ ".article": article_tmpl,
+}
+
+func isDoc(path string) bool {
+ _, ok := extensions[filepath.Ext(path)]
+ return ok
+}
+
+func VerifyDoc(docFile string) error {
+ doc, err := parse(docFile, 0)
+ if err != nil {
+ return err
+ }
+ dir := filepath.Dir(docFile)
+ return verify_doc(dir, doc)
+}
+
+// renderDoc reads the present file, builds its template representation,
+// and executes the template, sending output to w.
+func renderDoc(w io.Writer, base, docFile string) error {
+ // Read the input and build the doc structure.
+ doc, err := parse(docFile, 0)
+ if err != nil {
+ return err
+ }
+
+ // Find which template should be executed.
+ ext := filepath.Ext(docFile)
+ contentTmpl, ok := extensions[ext]
+ if !ok {
+ return fmt.Errorf("no template for extension %v", ext)
+ }
+
+ // Locate the template file.
+ actionTmpl := filepath.Join(base, "templates/action.tmpl")
+ contentTmpl = filepath.Join(base, "templates", contentTmpl)
+
+ // Read and parse the input.
+ tmpl := present.Template()
+ tmpl = tmpl.Funcs(template.FuncMap{"playable": playable})
+ if _, err := tmpl.ParseFiles(actionTmpl, contentTmpl); err != nil {
+ return err
+ }
+ // Execute the template.
+ return doc.Render(w, tmpl)
+}
+
+func RenderDoc(w io.Writer, docFile string) error {
+ // Read the input and build the doc structure.
+ doc, err := parse(docFile, 0)
+ if err != nil {
+ return err
+ }
+
+ // Find which template should be executed.
+ ext := filepath.Ext(docFile)
+ contentTmpl, ok := extensions_tmpl[ext]
+ if !ok {
+ return fmt.Errorf("no template for extension %v", ext)
+ }
+
+ // Locate the template file.
+ actionTmpl := action_tmpl //filepath.Join(base, "templates/action.tmpl")
+ // Read and parse the input.
+ tmpl := present.Template()
+ tmpl = tmpl.Funcs(template.FuncMap{"playable": playable})
+ if tmpl, err = tmpl.New("action").Parse(actionTmpl); err != nil {
+ return err
+ }
+ if tmpl, err = tmpl.New("content").Parse(contentTmpl); err != nil {
+ return err
+ }
+
+ // Execute the template.
+ return doc.Render(w, tmpl)
+}
+
+func parse(name string, mode present.ParseMode) (*present.Doc, error) {
+ f, err := os.Open(name)
+ if err != nil {
+ return nil, err
+ }
+ defer f.Close()
+ return present.Parse(f, name, 0)
+}
+
+func playable(c present.Code) bool {
+ return present.PlayEnabled && c.Play
+}
+
+func isSkipURL(url string) bool {
+ if filepath.HasPrefix(url, "http://") {
+ return true
+ }
+ if filepath.HasPrefix(url, "https://") {
+ return true
+ }
+ return false
+}
+
+func verify_path(root string, url string) error {
+ if isSkipURL(url) {
+ return nil
+ }
+ path := url
+ if !filepath.IsAbs(url) {
+ path = filepath.Join(root, path)
+ }
+ _, err := os.Stat(path)
+ if err != nil {
+ return err
+ }
+ return nil
+}
+
+func verify_doc(root string, doc *present.Doc) error {
+ for _, section := range doc.Sections {
+ for _, elem := range section.Elem {
+ switch i := elem.(type) {
+ case present.Image:
+ if err := verify_path(root, i.URL); err != nil {
+ return fmt.Errorf("! .image %s not exist", i.URL)
+ }
+ }
+ }
+ }
+ return nil
+}
+
+var action_tmpl = `
+{/*
+This is the action template.
+It determines how the formatting actions are rendered.
+*/}
+
+{{define "section"}}
+ {{.FormattedNumber}} {{.Title}}
+ {{range .Elem}}{{elem $.Template .}}{{end}}
+{{end}}
+
+{{define "list"}}
+
+ {{range .Bullet}}
+ {{style .}}
+ {{end}}
+
+{{end}}
+
+{{define "text"}}
+ {{if .Pre}}
+ {{range .Lines}}{{.}}{{end}}
+ {{else}}
+
+ {{range $i, $l := .Lines}}{{if $i}}{{template "newline"}}
+ {{end}}{{style $l}}{{end}}
+
+ {{end}}
+{{end}}
+
+{{define "code"}}
+ {{.Text}}
+{{end}}
+
+{{define "image"}}
+
+
+
+{{end}}
+
+{{define "iframe"}}
+
+{{end}}
+
+{{define "link"}}{{style .Label}}
{{end}}
+
+{{define "html"}}{{.HTML}}{{end}}
+`
+
+var article_tmpl = `
+{/* This is the article template. It defines how articles are formatted. */}
+
+{{define "root"}}
+
+
+
+ {{.Title}}
+
+
+
+
+
+
+
+
{{.Title}}
+ {{with .Subtitle}}{{.}}{{end}}
+
+
+
+
+
+ {{with .Sections}}
+
+ {{template "TOC" .}}
+
+ {{end}}
+
+ {{range .Sections}}
+ {{elem $.Template .}}
+ {{end}}{{/* of Section block */}}
+
+
Authors
+ {{range .Authors}}
+
+ {{range .Elem}}{{elem $.Template .}}{{end}}
+
+ {{end}}
+
+
+
+
+
+{{end}}
+
+{{define "TOC"}}
+
+ {{range .}}
+ {{.Title}}
+ {{with .Sections}}{{template "TOC" .}}{{end}}
+ {{end}}
+
+{{end}}
+
+{{define "newline"}}
+{{/* No automatic line break. Paragraphs are free-form. */}}
+{{end}}
+`
+
+var slides_tmpl = `
+{/* This is the slide template. It defines how presentations are formatted. */}
+
+{{define "root"}}
+
+
+
+ {{.Title}}
+
+
+
+
+
+
+
+
+
+ {{.Title}}
+ {{with .Subtitle}}{{.}} {{end}}
+ {{if not .Time.IsZero}}{{.Time.Format "2 January 2006"}} {{end}}
+ {{range .Authors}}
+
+ {{range .TextElem}}{{elem $.Template .}}{{end}}
+
+ {{end}}
+
+
+ {{range $i, $s := .Sections}}
+
+
+ {{if $s.Elem}}
+ {{$s.Title}}
+ {{range $s.Elem}}{{elem $.Template .}}{{end}}
+ {{else}}
+ {{$s.Title}}
+ {{end}}
+
+
+ {{end}}{{/* of Slide block */}}
+
+
+ Thank you
+ {{range .Authors}}
+
+ {{range .Elem}}{{elem $.Template .}}{{end}}
+
+ {{end}}
+
+
+
+ {{if .PlayEnabled}}
+
+ {{end}}
+
+{{end}}
+
+{{define "newline"}}
+
+{{end}}
+`
diff --git a/vendor/github.com/visualfc/gotools/jsonfmt/jsonfmt.go b/vendor/github.com/visualfc/gotools/jsonfmt/jsonfmt.go
new file mode 100644
index 0000000..f9657ef
--- /dev/null
+++ b/vendor/github.com/visualfc/gotools/jsonfmt/jsonfmt.go
@@ -0,0 +1,206 @@
+// Copyright 2011-2015 visualfc . All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package jsonfmt
+
+import (
+ "bytes"
+ "encoding/json"
+ "fmt"
+ "io"
+ "io/ioutil"
+ "os"
+ "os/exec"
+ "path/filepath"
+ "strings"
+
+ "github.com/visualfc/gotools/command"
+)
+
+var Command = &command.Command{
+ Run: runJsonFmt,
+ UsageLine: "jsonfmt",
+ Short: "json format util",
+ Long: `json format util.`,
+}
+
+var (
+ jsonFmtList bool
+ jsonFmtCompact bool
+ jsonFmtWrite bool
+ jsonFmtDiff bool
+ jsonTabWidth int
+ jsonTabIndent bool
+)
+
+func init() {
+ Command.Flag.BoolVar(&jsonFmtList, "l", false, "list files whose formatting differs")
+ Command.Flag.BoolVar(&jsonFmtCompact, "c", false, "compact json")
+ Command.Flag.BoolVar(&jsonFmtWrite, "w", false, "write result to (source) file instead of stdout")
+ Command.Flag.BoolVar(&jsonFmtDiff, "d", false, "display diffs instead of rewriting files")
+ Command.Flag.IntVar(&jsonTabWidth, "tabwidth", 4, "tab width")
+ Command.Flag.BoolVar(&jsonTabIndent, "tabs", false, "indent with tabs")
+}
+
+func runJsonFmt(cmd *command.Command, args []string) error {
+ opt := &JsonFmtOption{}
+ opt.List = jsonFmtList
+ opt.Compact = jsonFmtCompact
+ opt.IndentTab = jsonTabIndent
+ opt.TabWidth = jsonTabWidth
+ opt.Write = jsonFmtWrite
+ opt.Diff = jsonFmtDiff
+
+ if len(args) == 0 {
+ if err := processJsonFile("", os.Stdin, os.Stdout, true, opt); err != nil {
+ reportJsonError(err)
+ }
+ } else {
+ for _, path := range args {
+ switch dir, err := os.Stat(path); {
+ case err != nil:
+ reportJsonError(err)
+ case dir.IsDir():
+ filepath.Walk(path, func(path string, f os.FileInfo, err error) error {
+ if err == nil && isJsonFile(f) {
+ err = processJsonFile(path, nil, os.Stdout, false, opt)
+ }
+ if err != nil {
+ reportJsonError(err)
+ }
+ return nil
+ })
+ default:
+ if err := processJsonFile(path, nil, os.Stdout, false, opt); err != nil {
+ reportJsonError(err)
+ }
+ }
+ }
+ }
+ return nil
+}
+
+type JsonFmtOption struct {
+ List bool
+ Compact bool
+ Format bool
+ Write bool
+ Diff bool
+ IndentTab bool
+ TabWidth int
+}
+
+func isJsonFile(f os.FileInfo) bool {
+ // ignore non-Go files
+ name := f.Name()
+ return !f.IsDir() && !strings.HasPrefix(name, ".") && strings.HasSuffix(name, ".json")
+}
+
+func reportJsonError(err error) {
+ fmt.Fprintf(os.Stderr, "%s\n", err)
+ os.Exit(2)
+}
+
+func processJson(filename string, src []byte, opt *JsonFmtOption) ([]byte, error) {
+ if opt.Compact {
+ var out bytes.Buffer
+ err := json.Compact(&out, src)
+ if err != nil {
+ return nil, err
+ }
+ return out.Bytes(), nil
+ } else {
+ var out bytes.Buffer
+ var err error
+ if opt.IndentTab {
+ err = json.Indent(&out, src, "", "\t")
+ } else {
+ var indent string
+ for i := 0; i < opt.TabWidth; i++ {
+ indent += " "
+ }
+ err = json.Indent(&out, src, "", indent)
+ }
+ if err != nil {
+ return nil, err
+ }
+ return out.Bytes(), nil
+ }
+ return src, nil
+}
+
+func processJsonFile(filename string, in io.Reader, out io.Writer, stdin bool, opt *JsonFmtOption) error {
+ if in == nil {
+ f, err := os.Open(filename)
+ if err != nil {
+ return err
+ }
+ defer f.Close()
+ in = f
+ }
+
+ src, err := ioutil.ReadAll(in)
+ if err != nil {
+ return err
+ }
+
+ res, err := processJson(filename, src, opt)
+ if err != nil {
+ return err
+ }
+
+ if !bytes.Equal(src, res) {
+ // formatting has changed
+ if opt.List {
+ fmt.Fprintln(out, filename)
+ }
+ if opt.Write {
+ err = ioutil.WriteFile(filename, res, 0)
+ if err != nil {
+ return err
+ }
+ }
+ if opt.Diff {
+ data, err := diffJson(src, res)
+ if err != nil {
+ return fmt.Errorf("computing diff: %s", err)
+ }
+ fmt.Printf("diff %s json/%s\n", filename, filename)
+ out.Write(data)
+ }
+ }
+
+ if !opt.List && !opt.Write && !opt.Diff {
+ _, err = out.Write(res)
+ }
+
+ return err
+}
+
+func diffJson(b1, b2 []byte) (data []byte, err error) {
+ f1, err := ioutil.TempFile("", "json")
+ if err != nil {
+ return
+ }
+ defer os.Remove(f1.Name())
+ defer f1.Close()
+
+ f2, err := ioutil.TempFile("", "json")
+ if err != nil {
+ return
+ }
+ defer os.Remove(f2.Name())
+ defer f2.Close()
+
+ f1.Write(b1)
+ f2.Write(b2)
+
+ data, err = exec.Command("diff", "-u", f1.Name(), f2.Name()).CombinedOutput()
+ if len(data) > 0 {
+ // diff exits with a non-zero status when the files don't match.
+ // Ignore that failure as long as we get output.
+ err = nil
+ }
+ return
+}
diff --git a/vendor/github.com/visualfc/gotools/oracle/oracle.go b/vendor/github.com/visualfc/gotools/oracle/oracle.go
new file mode 100644
index 0000000..eff6fae
--- /dev/null
+++ b/vendor/github.com/visualfc/gotools/oracle/oracle.go
@@ -0,0 +1,105 @@
+// Copyright 2011-2015 visualfc . All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package oracle
+
+import (
+ "fmt"
+ "go/build"
+ "log"
+ "os"
+ "runtime"
+
+ "github.com/visualfc/gotools/command"
+
+ "golang.org/x/tools/oracle"
+)
+
+//The mode argument determines the query to perform:
+
+// callees show possible targets of selected function call
+// callers show possible callers of selected function
+// callgraph show complete callgraph of program
+// callstack show path from callgraph root to selected function
+// describe describe selected syntax: definition, methods, etc
+// freevars show free variables of selection
+// implements show 'implements' relation for selected type
+// peers show send/receive corresponding to selected channel op
+// referrers show all refs to entity denoted by selected identifier
+// what show basic information about the selected syntax node
+
+var Command = &command.Command{
+ Run: runOracle,
+ UsageLine: "oracle",
+ Short: "golang oracle util",
+ Long: `golang oracle util.`,
+}
+
+var (
+ oraclePos string
+ oracleReflect bool
+)
+
+func init() {
+ Command.Flag.StringVar(&oraclePos, "pos", "", "filename:#offset")
+ Command.Flag.BoolVar(&oracleReflect, "reflect", false, "Analyze reflection soundly (slow).")
+}
+
+func runOracle(cmd *command.Command, args []string) error {
+ if len(args) < 2 {
+ cmd.Usage()
+ return os.ErrInvalid
+ }
+ if os.Getenv("GOMAXPROCS") == "" {
+ n := runtime.NumCPU()
+ if n < 4 {
+ n = 4
+ }
+ runtime.GOMAXPROCS(n)
+ }
+ mode := args[0]
+ args = args[1:]
+ if args[0] == "." {
+ pkgPath, err := os.Getwd()
+ if err != nil {
+ log.Fatalln(err)
+ }
+ pkg, err := build.Default.ImportDir(pkgPath, 0)
+ if err != nil {
+ log.Fatalln(err)
+ }
+ args = pkg.GoFiles
+ //log.Println(pkg.ImportPath)
+ if pkg.ImportPath != "." && pkg.ImportPath != "" {
+ args = []string{pkg.ImportPath}
+ }
+ }
+ query := oracle.Query{
+ Mode: mode,
+ Pos: oraclePos,
+ Build: &build.Default,
+ Scope: args,
+ PTALog: nil,
+ Reflection: oracleReflect,
+ }
+
+ if err := oracle.Run(&query); err != nil {
+ fmt.Fprintf(os.Stderr, "oracle: %s.\n", err)
+ return err
+ }
+
+ if mode == "referrers" {
+ ref := query.Serial().Referrers
+ if ref != nil {
+ fmt.Fprintln(os.Stdout, ref.Desc)
+ fmt.Fprintln(os.Stdout, ref.ObjPos)
+ for _, v := range ref.Refs {
+ fmt.Fprintln(os.Stdout, v)
+ }
+ }
+ } else {
+ query.WriteTo(os.Stdout)
+ }
+ return nil
+}
diff --git a/vendor/github.com/visualfc/gotools/pkgs/pkgs.go b/vendor/github.com/visualfc/gotools/pkgs/pkgs.go
new file mode 100644
index 0000000..fe47e5c
--- /dev/null
+++ b/vendor/github.com/visualfc/gotools/pkgs/pkgs.go
@@ -0,0 +1,379 @@
+// Copyright 2011-2015 visualfc . All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package pkgs
+
+import (
+ "encoding/json"
+ "fmt"
+ "go/build"
+ "os"
+ "path/filepath"
+ "runtime"
+ "sort"
+ "strings"
+ "sync"
+
+ "github.com/visualfc/gotools/command"
+ "github.com/visualfc/gotools/goapi"
+)
+
+var Command = &command.Command{
+ Run: runPkgs,
+ UsageLine: "pkgs",
+ Short: "print liteide_stub version",
+ Long: `Version prints the liteide_stub version.`,
+}
+
+var (
+ pkgsList bool
+ pkgsJson bool
+ pkgsFind string
+ pkgsStd bool
+ pkgsPkgOnly bool
+ pkgsSkipGoroot bool
+)
+
+func init() {
+ Command.Flag.BoolVar(&pkgsList, "list", false, "list all package")
+ Command.Flag.BoolVar(&pkgsJson, "json", false, "json format")
+ Command.Flag.BoolVar(&pkgsStd, "std", false, "std library")
+ Command.Flag.BoolVar(&pkgsPkgOnly, "pkg", false, "pkg only")
+ Command.Flag.BoolVar(&pkgsSkipGoroot, "skip_goroot", false, "skip goroot")
+ Command.Flag.StringVar(&pkgsFind, "find", "", "find package by name")
+}
+
+func runPkgs(cmd *command.Command, args []string) error {
+ runtime.GOMAXPROCS(runtime.NumCPU())
+ if len(args) != 0 {
+ cmd.Usage()
+ return os.ErrInvalid
+ }
+ //pkgIndexOnce.Do(loadPkgsList)
+ var pp PathPkgsIndex
+ pp.LoadIndex()
+ pp.Sort()
+ if pkgsList {
+ for _, pi := range pp.indexs {
+ for _, pkg := range pi.pkgs {
+ if pkgsPkgOnly && pkg.IsCommand() {
+ continue
+ }
+ if pkgsJson {
+ var p GoPackage
+ p.copyBuild(pkg)
+ b, err := json.MarshalIndent(&p, "", "\t")
+ if err == nil {
+ cmd.Stdout.Write(b)
+ cmd.Stdout.Write([]byte{'\n'})
+ }
+ } else {
+ cmd.Println(pkg.ImportPath)
+ }
+ }
+ }
+ } else if pkgsFind != "" {
+ for _, pi := range pp.indexs {
+ for _, pkg := range pi.pkgs {
+ if pkg.Name == pkgsFind {
+ if pkgsPkgOnly && pkg.IsCommand() {
+ continue
+ }
+ if pkgsJson {
+ var p GoPackage
+ p.copyBuild(pkg)
+ b, err := json.MarshalIndent(p, "", "\t")
+ if err == nil {
+ cmd.Stdout.Write(b)
+ cmd.Stdout.Write([]byte{'\n'})
+ }
+ } else {
+ cmd.Println(pkg.Name)
+ }
+ break
+ }
+ }
+ }
+ }
+ return nil
+}
+
+// A Package describes a single package found in a directory.
+type GoPackage struct {
+ // Note: These fields are part of the go command's public API.
+ // See list.go. It is okay to add fields, but not to change or
+ // remove existing ones. Keep in sync with list.go
+ Dir string `json:",omitempty"` // directory containing package sources
+ ImportPath string `json:",omitempty"` // import path of package in dir
+ Name string `json:",omitempty"` // package name
+ Doc string `json:",omitempty"` // package documentation string
+ Target string `json:",omitempty"` // install path
+ Goroot bool `json:",omitempty"` // is this package found in the Go root?
+ Standard bool `json:",omitempty"` // is this package part of the standard Go library?
+ Stale bool `json:",omitempty"` // would 'go install' do anything for this package?
+ Root string `json:",omitempty"` // Go root or Go path dir containing this package
+ ConflictDir string `json:",omitempty"` // Dir is hidden by this other directory
+
+ // Source files
+ GoFiles []string `json:",omitempty"` // .go source files (excluding CgoFiles, TestGoFiles, XTestGoFiles)
+ CgoFiles []string `json:",omitempty"` // .go sources files that import "C"
+ IgnoredGoFiles []string `json:",omitempty"` // .go sources ignored due to build constraints
+ CFiles []string `json:",omitempty"` // .c source files
+ CXXFiles []string `json:",omitempty"` // .cc, .cpp and .cxx source files
+ MFiles []string `json:",omitempty"` // .m source files
+ HFiles []string `json:",omitempty"` // .h, .hh, .hpp and .hxx source files
+ SFiles []string `json:",omitempty"` // .s source files
+ SwigFiles []string `json:",omitempty"` // .swig files
+ SwigCXXFiles []string `json:",omitempty"` // .swigcxx files
+ SysoFiles []string `json:",omitempty"` // .syso system object files added to package
+
+ // Cgo directives
+ CgoCFLAGS []string `json:",omitempty"` // cgo: flags for C compiler
+ CgoCPPFLAGS []string `json:",omitempty"` // cgo: flags for C preprocessor
+ CgoCXXFLAGS []string `json:",omitempty"` // cgo: flags for C++ compiler
+ CgoLDFLAGS []string `json:",omitempty"` // cgo: flags for linker
+ CgoPkgConfig []string `json:",omitempty"` // cgo: pkg-config names
+
+ // Dependency information
+ Imports []string `json:",omitempty"` // import paths used by this package
+ Deps []string `json:",omitempty"` // all (recursively) imported dependencies
+
+ // Error information
+ Incomplete bool `json:",omitempty"` // was there an error loading this package or dependencies?
+
+ // Test information
+ TestGoFiles []string `json:",omitempty"` // _test.go files in package
+ TestImports []string `json:",omitempty"` // imports from TestGoFiles
+ XTestGoFiles []string `json:",omitempty"` // _test.go files outside package
+ XTestImports []string `json:",omitempty"` // imports from XTestGoFiles
+
+ // Unexported fields are not part of the public API.
+ build *build.Package
+ pkgdir string // overrides build.PkgDir
+ imports []*goapi.Package
+ deps []*goapi.Package
+ gofiles []string // GoFiles+CgoFiles+TestGoFiles+XTestGoFiles files, absolute paths
+ sfiles []string
+ allgofiles []string // gofiles + IgnoredGoFiles, absolute paths
+ target string // installed file for this package (may be executable)
+ fake bool // synthesized package
+ forceBuild bool // this package must be rebuilt
+ forceLibrary bool // this package is a library (even if named "main")
+ cmdline bool // defined by files listed on command line
+ local bool // imported via local path (./ or ../)
+ localPrefix string // interpret ./ and ../ imports relative to this prefix
+ exeName string // desired name for temporary executable
+ coverMode string // preprocess Go source files with the coverage tool in this mode
+ coverVars map[string]*CoverVar // variables created by coverage analysis
+ omitDWARF bool // tell linker not to write DWARF information
+}
+
+// CoverVar holds the name of the generated coverage variables targeting the named file.
+type CoverVar struct {
+ File string // local file name
+ Var string // name of count struct
+}
+
+func (p *GoPackage) copyBuild(pp *build.Package) {
+ p.build = pp
+
+ p.Dir = pp.Dir
+ p.ImportPath = pp.ImportPath
+ p.Name = pp.Name
+ p.Doc = pp.Doc
+ p.Root = pp.Root
+ p.ConflictDir = pp.ConflictDir
+ // TODO? Target
+ p.Goroot = pp.Goroot
+ p.Standard = p.Goroot && p.ImportPath != "" && !strings.Contains(p.ImportPath, ".")
+ p.GoFiles = pp.GoFiles
+ p.CgoFiles = pp.CgoFiles
+ p.IgnoredGoFiles = pp.IgnoredGoFiles
+ p.CFiles = pp.CFiles
+ p.CXXFiles = pp.CXXFiles
+ p.MFiles = pp.MFiles
+ p.HFiles = pp.HFiles
+ p.SFiles = pp.SFiles
+ p.SwigFiles = pp.SwigFiles
+ p.SwigCXXFiles = pp.SwigCXXFiles
+ p.SysoFiles = pp.SysoFiles
+ p.CgoCFLAGS = pp.CgoCFLAGS
+ p.CgoCPPFLAGS = pp.CgoCPPFLAGS
+ p.CgoCXXFLAGS = pp.CgoCXXFLAGS
+ p.CgoLDFLAGS = pp.CgoLDFLAGS
+ p.CgoPkgConfig = pp.CgoPkgConfig
+ p.Imports = pp.Imports
+ p.TestGoFiles = pp.TestGoFiles
+ p.TestImports = pp.TestImports
+ p.XTestGoFiles = pp.XTestGoFiles
+ p.XTestImports = pp.XTestImports
+}
+
+type PathPkgsIndex struct {
+ indexs []*PkgsIndex
+}
+
+func (p *PathPkgsIndex) LoadIndex() {
+ var wg sync.WaitGroup
+ var context = build.Default
+ if pkgsStd {
+ context.GOPATH = ""
+ }
+ var srcDirs []string
+ goroot := context.GOROOT
+ gopath := context.GOPATH
+ context.GOPATH = ""
+
+ if !pkgsSkipGoroot {
+ //go1.4 go/src/
+ //go1.3 go/src/pkg; go/src/cmd
+ _, err := os.Stat(filepath.Join(goroot, "src/pkg/runtime"))
+ if err == nil {
+ for _, v := range context.SrcDirs() {
+ if strings.HasSuffix(v, "pkg") {
+ srcDirs = append(srcDirs, v[:len(v)-3]+"cmd")
+ }
+ srcDirs = append(srcDirs, v)
+ }
+ } else {
+ srcDirs = append(srcDirs, filepath.Join(goroot, "src"))
+ }
+ }
+
+ context.GOPATH = gopath
+ context.GOROOT = ""
+ for _, v := range context.SrcDirs() {
+ srcDirs = append(srcDirs, v)
+ }
+ context.GOROOT = goroot
+ for _, path := range srcDirs {
+ pi := &PkgsIndex{}
+ p.indexs = append(p.indexs, pi)
+ pkgsGate.enter()
+ f, err := os.Open(path)
+ if err != nil {
+ pkgsGate.leave()
+ fmt.Fprint(os.Stderr, err)
+ continue
+ }
+ children, err := f.Readdir(-1)
+ f.Close()
+ pkgsGate.leave()
+ if err != nil {
+ fmt.Fprint(os.Stderr, err)
+ continue
+ }
+ for _, child := range children {
+ if child.IsDir() {
+ wg.Add(1)
+ go func(path, name string) {
+ defer wg.Done()
+ pi.loadPkgsPath(&wg, path, name)
+ }(path, child.Name())
+ }
+ }
+ }
+ wg.Wait()
+}
+
+func (p *PathPkgsIndex) Sort() {
+ for _, v := range p.indexs {
+ v.sort()
+ }
+}
+
+type PkgsIndex struct {
+ sync.Mutex
+ pkgs []*build.Package
+}
+
+func (p *PkgsIndex) sort() {
+ sort.Sort(PkgSlice(p.pkgs))
+}
+
+type PkgSlice []*build.Package
+
+func (p PkgSlice) Len() int {
+ return len([]*build.Package(p))
+}
+
+func (p PkgSlice) Less(i, j int) bool {
+ if p[i].IsCommand() && !p[j].IsCommand() {
+ return true
+ } else if !p[i].IsCommand() && p[j].IsCommand() {
+ return false
+ }
+ return p[i].ImportPath < p[j].ImportPath
+}
+
+func (p PkgSlice) Swap(i, j int) {
+ p[i], p[j] = p[j], p[i]
+}
+
+// pkgsgate protects the OS & filesystem from too much concurrency.
+// Too much disk I/O -> too many threads -> swapping and bad scheduling.
+// gate is a semaphore for limiting concurrency.
+type gate chan struct{}
+
+func (g gate) enter() { g <- struct{}{} }
+func (g gate) leave() { <-g }
+
+var pkgsGate = make(gate, 8)
+
+func (p *PkgsIndex) loadPkgsPath(wg *sync.WaitGroup, root, pkgrelpath string) {
+ importpath := filepath.ToSlash(pkgrelpath)
+ dir := filepath.Join(root, importpath)
+
+ pkgsGate.enter()
+ defer pkgsGate.leave()
+ pkgDir, err := os.Open(dir)
+ if err != nil {
+ return
+ }
+ children, err := pkgDir.Readdir(-1)
+ pkgDir.Close()
+ if err != nil {
+ return
+ }
+ // hasGo tracks whether a directory actually appears to be a
+ // Go source code directory. If $GOPATH == $HOME, and
+ // $HOME/src has lots of other large non-Go projects in it,
+ // then the calls to importPathToName below can be expensive.
+ hasGo := false
+ for _, child := range children {
+ name := child.Name()
+ if name == "" {
+ continue
+ }
+ if c := name[0]; c == '.' || ('0' <= c && c <= '9') {
+ continue
+ }
+ if strings.HasSuffix(name, ".go") {
+ hasGo = true
+ }
+ if child.IsDir() {
+ if strings.HasPrefix(name, ".") || strings.HasPrefix(name, "_") || name == "testdata" {
+ continue
+ }
+ wg.Add(1)
+ go func(root, name string) {
+ defer wg.Done()
+ p.loadPkgsPath(wg, root, name)
+ }(root, filepath.Join(importpath, name))
+ }
+ }
+ if hasGo {
+ buildPkg, err := build.ImportDir(dir, 0)
+ if err == nil {
+ if buildPkg.ImportPath == "." {
+ buildPkg.ImportPath = filepath.ToSlash(pkgrelpath)
+ buildPkg.Root = root
+ buildPkg.Goroot = true
+ }
+ p.Lock()
+ p.pkgs = append(p.pkgs, buildPkg)
+ p.Unlock()
+ }
+ }
+}
diff --git a/vendor/github.com/visualfc/gotools/runcmd/runcmd.go b/vendor/github.com/visualfc/gotools/runcmd/runcmd.go
new file mode 100644
index 0000000..6560d62
--- /dev/null
+++ b/vendor/github.com/visualfc/gotools/runcmd/runcmd.go
@@ -0,0 +1,87 @@
+// Copyright 2011-2015 visualfc . All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package runcmd
+
+import (
+ "fmt"
+ "os"
+ "os/exec"
+ "strings"
+
+ "github.com/visualfc/gotools/command"
+)
+
+var Command = &command.Command{
+ Run: runCmd,
+ UsageLine: "runcmd [-w work_path] [arguments...]",
+ Short: "run program",
+ Long: `run program and arguments`,
+}
+
+var execWorkPath string
+var execWaitEnter bool
+
+func init() {
+ Command.Flag.StringVar(&execWorkPath, "w", "", "work path")
+ Command.Flag.BoolVar(&execWaitEnter, "e", true, "wait enter and continue")
+}
+
+func runCmd(cmd *command.Command, args []string) error {
+ if len(args) == 0 {
+ cmd.Usage()
+ return os.ErrInvalid
+ }
+ if execWorkPath == "" {
+ var err error
+ execWorkPath, err = os.Getwd()
+ if err != nil {
+ fmt.Fprintf(os.Stderr, "liteide_stub exec: os.Getwd() false\n")
+ command.SetExitStatus(3)
+ command.Exit()
+ return err
+ }
+ }
+ fileName := args[0]
+
+ filePath, err := exec.LookPath(fileName)
+ if err != nil {
+ filePath, err = exec.LookPath("./" + fileName)
+ }
+ if err != nil {
+ fmt.Fprintf(os.Stderr, "liteide_stub exec: file %s not found\n", fileName)
+ command.SetExitStatus(3)
+ command.Exit()
+ }
+
+ fmt.Println("Starting Process", filePath, strings.Join(args[1:], " "), "...")
+
+ command := exec.Command(filePath, args[1:]...)
+ command.Dir = execWorkPath
+ command.Stdin = os.Stdin
+ command.Stdout = os.Stdout
+ command.Stderr = os.Stderr
+
+ err = command.Run()
+
+ if err != nil {
+ fmt.Println("\nEnd Process", err)
+ } else {
+ fmt.Println("\nEnd Process", "exit status 0")
+ }
+
+ exitWaitEnter()
+ return nil
+}
+
+func exitWaitEnter() {
+ if !execWaitEnter {
+ return
+ }
+ fmt.Println("\nPress enter key to continue")
+ var s = [256]byte{}
+ os.Stdin.Read(s[:])
+ command.SetExitStatus(0)
+ command.Exit()
+}
diff --git a/vendor/github.com/visualfc/gotools/stdlib/go13.go b/vendor/github.com/visualfc/gotools/stdlib/go13.go
new file mode 100644
index 0000000..d81ad91
--- /dev/null
+++ b/vendor/github.com/visualfc/gotools/stdlib/go13.go
@@ -0,0 +1,19 @@
+// +build !go1.4
+
+package stdlib
+
+import (
+ "go/build"
+ "os"
+ "path/filepath"
+)
+
+func ImportStdPkg(context *build.Context, path string, mode build.ImportMode) (*build.Package, error) {
+ realpath := filepath.Join(context.GOROOT, "src", "pkg", path)
+ if _, err := os.Stat(realpath); err != nil {
+ realpath = filepath.Join(context.GOROOT, "src", path)
+ }
+ pkg, err := context.ImportDir(realpath, 0)
+ pkg.ImportPath = path
+ return pkg, err
+}
diff --git a/vendor/github.com/visualfc/gotools/stdlib/go14.go b/vendor/github.com/visualfc/gotools/stdlib/go14.go
new file mode 100644
index 0000000..9bd79d2
--- /dev/null
+++ b/vendor/github.com/visualfc/gotools/stdlib/go14.go
@@ -0,0 +1,19 @@
+// +build go1.4
+
+package stdlib
+
+import (
+ "go/build"
+ "os"
+ "path/filepath"
+)
+
+func ImportStdPkg(context *build.Context, path string, mode build.ImportMode) (*build.Package, error) {
+ realpath := filepath.Join(context.GOROOT, "src", path)
+ if _, err := os.Stat(realpath); err != nil {
+ realpath = filepath.Join(context.GOROOT, "src/pkg", path)
+ }
+ pkg, err := context.ImportDir(realpath, 0)
+ pkg.ImportPath = path
+ return pkg, err
+}
diff --git a/vendor/github.com/visualfc/gotools/stdlib/mkpkglist.go b/vendor/github.com/visualfc/gotools/stdlib/mkpkglist.go
new file mode 100644
index 0000000..ea408ae
--- /dev/null
+++ b/vendor/github.com/visualfc/gotools/stdlib/mkpkglist.go
@@ -0,0 +1,168 @@
+// +build ignore
+
+package main
+
+import (
+ "fmt"
+ "strings"
+)
+
+var pkgList = `
+cmd/cgo
+cmd/fix
+cmd/go
+cmd/gofmt
+cmd/yacc
+archive/tar
+archive/zip
+bufio
+bytes
+compress/bzip2
+compress/flate
+compress/gzip
+compress/lzw
+compress/zlib
+container/heap
+container/list
+container/ring
+crypto
+crypto/aes
+crypto/cipher
+crypto/des
+crypto/dsa
+crypto/ecdsa
+crypto/elliptic
+crypto/hmac
+crypto/md5
+crypto/rand
+crypto/rc4
+crypto/rsa
+crypto/sha1
+crypto/sha256
+crypto/sha512
+crypto/subtle
+crypto/tls
+crypto/x509
+crypto/x509/pkix
+database/sql
+database/sql/driver
+debug/dwarf
+debug/elf
+debug/gosym
+debug/macho
+debug/pe
+encoding
+encoding/ascii85
+encoding/asn1
+encoding/base32
+encoding/base64
+encoding/binary
+encoding/csv
+encoding/gob
+encoding/hex
+encoding/json
+encoding/pem
+encoding/xml
+errors
+expvar
+flag
+fmt
+go/ast
+go/build
+go/doc
+go/format
+go/parser
+go/printer
+go/scanner
+go/token
+hash
+hash/adler32
+hash/crc32
+hash/crc64
+hash/fnv
+html
+html/template
+image
+image/color
+image/color/palette
+image/draw
+image/gif
+image/jpeg
+image/png
+index/suffixarray
+io
+io/ioutil
+log
+log/syslog
+math
+math/big
+math/cmplx
+math/rand
+mime
+mime/multipart
+net
+net/http
+net/http/cgi
+net/http/cookiejar
+net/http/fcgi
+net/http/httptest
+net/http/httputil
+net/http/pprof
+net/mail
+net/rpc
+net/rpc/jsonrpc
+net/smtp
+net/textproto
+net/url
+os
+os/exec
+os/signal
+os/user
+path
+path/filepath
+reflect
+regexp
+regexp/syntax
+runtime
+runtime/cgo
+runtime/debug
+runtime/pprof
+runtime/race
+sort
+strconv
+strings
+sync
+sync/atomic
+syscall
+testing
+testing/iotest
+testing/quick
+text/scanner
+text/tabwriter
+text/template
+text/template/parse
+time
+unicode
+unicode/utf16
+unicode/utf8
+unsafe
+`
+
+func main() {
+ //fmt.Println(pkgList)
+ var list []string
+ index := 0
+ for _, v := range strings.Split(pkgList, "\n") {
+ v = strings.TrimSpace(v)
+ if v == "" {
+ continue
+ }
+ v = "\"" + v + "\""
+ if index%4 == 0 && index != 0 {
+ v = "\n" + v
+ }
+ list = append(list, v)
+ index++
+ }
+ fmt.Println(strings.Join(list, ","))
+}
diff --git a/vendor/github.com/visualfc/gotools/stdlib/mkstdlib.go b/vendor/github.com/visualfc/gotools/stdlib/mkstdlib.go
new file mode 100644
index 0000000..7118f2d
--- /dev/null
+++ b/vendor/github.com/visualfc/gotools/stdlib/mkstdlib.go
@@ -0,0 +1,91 @@
+// +build ignore
+
+// mkstdlib generates the zstdlib.go file, containing the Go standard
+// library API symbols. It's baked into the binary to avoid scanning
+// GOPATH in the common case.
+package main
+
+import (
+ "bufio"
+ "bytes"
+ "fmt"
+ "go/format"
+ "io"
+ "log"
+ "os"
+ "path"
+ "path/filepath"
+ "regexp"
+ "sort"
+ "strings"
+)
+
+func mustOpen(name string) io.Reader {
+ f, err := os.Open(name)
+ if err != nil {
+ log.Fatal(err)
+ }
+ return f
+}
+
+func api(base string) string {
+ return filepath.Join(os.Getenv("GOROOT"), "api", base)
+}
+
+var sym = regexp.MustCompile(`^pkg (\S+).*?, (?:var|func|type|const) ([A-Z]\w*)`)
+
+func main() {
+ var buf bytes.Buffer
+ outf := func(format string, args ...interface{}) {
+ fmt.Fprintf(&buf, format, args...)
+ }
+ outf("// AUTO-GENERATED BY mkstdlib.go\n\n")
+ outf("package imports\n")
+ outf("var stdlib = map[string]string{\n")
+ f := io.MultiReader(
+ mustOpen(api("go1.txt")),
+ mustOpen(api("go1.1.txt")),
+ mustOpen(api("go1.2.txt")),
+ mustOpen(api("go1.3.txt")),
+ )
+ sc := bufio.NewScanner(f)
+ fullImport := map[string]string{} // "zip.NewReader" => "archive/zip"
+ ambiguous := map[string]bool{}
+ var keys []string
+ for sc.Scan() {
+ l := sc.Text()
+ has := func(v string) bool { return strings.Contains(l, v) }
+ if has("struct, ") || has("interface, ") || has(", method (") {
+ continue
+ }
+ if m := sym.FindStringSubmatch(l); m != nil {
+ full := m[1]
+ key := path.Base(full) + "." + m[2]
+ if exist, ok := fullImport[key]; ok {
+ if exist != full {
+ ambiguous[key] = true
+ }
+ } else {
+ fullImport[key] = full
+ keys = append(keys, key)
+ }
+ }
+ }
+ if err := sc.Err(); err != nil {
+ log.Fatal(err)
+ }
+ sort.Strings(keys)
+ for _, key := range keys {
+ if ambiguous[key] {
+ outf("\t// %q is ambiguous\n", key)
+ } else {
+ outf("\t%q: %q,\n", key, fullImport[key])
+ }
+ }
+ outf("}\n")
+ fmtbuf, err := format.Source(buf.Bytes())
+ if err != nil {
+ log.Fatal(err)
+ }
+ os.Stdout.Write(fmtbuf)
+}
diff --git a/vendor/github.com/visualfc/gotools/stdlib/pkglist.go b/vendor/github.com/visualfc/gotools/stdlib/pkglist.go
new file mode 100644
index 0000000..2dc4164
--- /dev/null
+++ b/vendor/github.com/visualfc/gotools/stdlib/pkglist.go
@@ -0,0 +1,48 @@
+package stdlib
+
+var Packages = []string{
+ "cmd/cgo", "cmd/fix", "cmd/go", "cmd/gofmt",
+ "cmd/yacc", "archive/tar", "archive/zip", "bufio",
+ "bytes", "compress/bzip2", "compress/flate", "compress/gzip",
+ "compress/lzw", "compress/zlib", "container/heap", "container/list",
+ "container/ring", "crypto", "crypto/aes", "crypto/cipher",
+ "crypto/des", "crypto/dsa", "crypto/ecdsa", "crypto/elliptic",
+ "crypto/hmac", "crypto/md5", "crypto/rand", "crypto/rc4",
+ "crypto/rsa", "crypto/sha1", "crypto/sha256", "crypto/sha512",
+ "crypto/subtle", "crypto/tls", "crypto/x509", "crypto/x509/pkix",
+ "database/sql", "database/sql/driver", "debug/dwarf", "debug/elf",
+ "debug/gosym", "debug/macho", "debug/pe", "encoding",
+ "encoding/ascii85", "encoding/asn1", "encoding/base32", "encoding/base64",
+ "encoding/binary", "encoding/csv", "encoding/gob", "encoding/hex",
+ "encoding/json", "encoding/pem", "encoding/xml", "errors",
+ "expvar", "flag", "fmt", "go/ast",
+ "go/build", "go/doc", "go/format", "go/parser",
+ "go/printer", "go/scanner", "go/token", "hash",
+ "hash/adler32", "hash/crc32", "hash/crc64", "hash/fnv",
+ "html", "html/template", "image", "image/color",
+ "image/color/palette", "image/draw", "image/gif", "image/jpeg",
+ "image/png", "index/suffixarray", "io", "io/ioutil",
+ "log", "log/syslog", "math", "math/big",
+ "math/cmplx", "math/rand", "mime", "mime/multipart",
+ "net", "net/http", "net/http/cgi", "net/http/cookiejar",
+ "net/http/fcgi", "net/http/httptest", "net/http/httputil", "net/http/pprof",
+ "net/mail", "net/rpc", "net/rpc/jsonrpc", "net/smtp",
+ "net/textproto", "net/url", "os", "os/exec",
+ "os/signal", "os/user", "path", "path/filepath",
+ "reflect", "regexp", "regexp/syntax", "runtime",
+ "runtime/cgo", "runtime/debug", "runtime/pprof", "runtime/race",
+ "sort", "strconv", "strings", "sync",
+ "sync/atomic", "syscall", "testing", "testing/iotest",
+ "testing/quick", "text/scanner", "text/tabwriter", "text/template",
+ "text/template/parse", "time", "unicode", "unicode/utf16",
+ "unicode/utf8", "unsafe",
+}
+
+func IsStdPkg(pkg string) bool {
+ for _, v := range Packages {
+ if v == pkg {
+ return true
+ }
+ }
+ return false
+}
diff --git a/vendor/github.com/visualfc/gotools/stdlib/zstdlib.go b/vendor/github.com/visualfc/gotools/stdlib/zstdlib.go
new file mode 100644
index 0000000..ab4ec64
--- /dev/null
+++ b/vendor/github.com/visualfc/gotools/stdlib/zstdlib.go
@@ -0,0 +1,8479 @@
+// AUTO-GENERATED BY mkstdlib.go
+
+package stdlib
+
+var Symbols = map[string]string{
+ "adler32.Checksum": "hash/adler32",
+ "adler32.New": "hash/adler32",
+ "adler32.Size": "hash/adler32",
+ "aes.BlockSize": "crypto/aes",
+ "aes.KeySizeError": "crypto/aes",
+ "aes.NewCipher": "crypto/aes",
+ "ascii85.CorruptInputError": "encoding/ascii85",
+ "ascii85.Decode": "encoding/ascii85",
+ "ascii85.Encode": "encoding/ascii85",
+ "ascii85.MaxEncodedLen": "encoding/ascii85",
+ "ascii85.NewDecoder": "encoding/ascii85",
+ "ascii85.NewEncoder": "encoding/ascii85",
+ "asn1.BitString": "encoding/asn1",
+ "asn1.Enumerated": "encoding/asn1",
+ "asn1.Flag": "encoding/asn1",
+ "asn1.Marshal": "encoding/asn1",
+ "asn1.ObjectIdentifier": "encoding/asn1",
+ "asn1.RawContent": "encoding/asn1",
+ "asn1.RawValue": "encoding/asn1",
+ "asn1.StructuralError": "encoding/asn1",
+ "asn1.SyntaxError": "encoding/asn1",
+ "asn1.Unmarshal": "encoding/asn1",
+ "asn1.UnmarshalWithParams": "encoding/asn1",
+ "ast.ArrayType": "go/ast",
+ "ast.AssignStmt": "go/ast",
+ "ast.Bad": "go/ast",
+ "ast.BadDecl": "go/ast",
+ "ast.BadExpr": "go/ast",
+ "ast.BadStmt": "go/ast",
+ "ast.BasicLit": "go/ast",
+ "ast.BinaryExpr": "go/ast",
+ "ast.BlockStmt": "go/ast",
+ "ast.BranchStmt": "go/ast",
+ "ast.CallExpr": "go/ast",
+ "ast.CaseClause": "go/ast",
+ "ast.ChanDir": "go/ast",
+ "ast.ChanType": "go/ast",
+ "ast.CommClause": "go/ast",
+ "ast.Comment": "go/ast",
+ "ast.CommentGroup": "go/ast",
+ "ast.CommentMap": "go/ast",
+ "ast.CompositeLit": "go/ast",
+ "ast.Con": "go/ast",
+ "ast.DeclStmt": "go/ast",
+ "ast.DeferStmt": "go/ast",
+ "ast.Ellipsis": "go/ast",
+ "ast.EmptyStmt": "go/ast",
+ "ast.ExprStmt": "go/ast",
+ "ast.Field": "go/ast",
+ "ast.FieldFilter": "go/ast",
+ "ast.FieldList": "go/ast",
+ "ast.File": "go/ast",
+ "ast.FileExports": "go/ast",
+ "ast.Filter": "go/ast",
+ "ast.FilterDecl": "go/ast",
+ "ast.FilterFile": "go/ast",
+ "ast.FilterFuncDuplicates": "go/ast",
+ "ast.FilterImportDuplicates": "go/ast",
+ "ast.FilterPackage": "go/ast",
+ "ast.FilterUnassociatedComments": "go/ast",
+ "ast.ForStmt": "go/ast",
+ "ast.Fprint": "go/ast",
+ "ast.Fun": "go/ast",
+ "ast.FuncDecl": "go/ast",
+ "ast.FuncLit": "go/ast",
+ "ast.FuncType": "go/ast",
+ "ast.GenDecl": "go/ast",
+ "ast.GoStmt": "go/ast",
+ "ast.Ident": "go/ast",
+ "ast.IfStmt": "go/ast",
+ "ast.ImportSpec": "go/ast",
+ "ast.Importer": "go/ast",
+ "ast.IncDecStmt": "go/ast",
+ "ast.IndexExpr": "go/ast",
+ "ast.Inspect": "go/ast",
+ "ast.InterfaceType": "go/ast",
+ "ast.IsExported": "go/ast",
+ "ast.KeyValueExpr": "go/ast",
+ "ast.LabeledStmt": "go/ast",
+ "ast.Lbl": "go/ast",
+ "ast.MapType": "go/ast",
+ "ast.MergeMode": "go/ast",
+ "ast.MergePackageFiles": "go/ast",
+ "ast.NewCommentMap": "go/ast",
+ "ast.NewIdent": "go/ast",
+ "ast.NewObj": "go/ast",
+ "ast.NewPackage": "go/ast",
+ "ast.NewScope": "go/ast",
+ "ast.Node": "go/ast",
+ "ast.NotNilFilter": "go/ast",
+ "ast.ObjKind": "go/ast",
+ "ast.Object": "go/ast",
+ "ast.Package": "go/ast",
+ "ast.PackageExports": "go/ast",
+ "ast.ParenExpr": "go/ast",
+ "ast.Pkg": "go/ast",
+ "ast.Print": "go/ast",
+ "ast.RECV": "go/ast",
+ "ast.RangeStmt": "go/ast",
+ "ast.ReturnStmt": "go/ast",
+ "ast.SEND": "go/ast",
+ "ast.Scope": "go/ast",
+ "ast.SelectStmt": "go/ast",
+ "ast.SelectorExpr": "go/ast",
+ "ast.SendStmt": "go/ast",
+ "ast.SliceExpr": "go/ast",
+ "ast.SortImports": "go/ast",
+ "ast.StarExpr": "go/ast",
+ "ast.StructType": "go/ast",
+ "ast.SwitchStmt": "go/ast",
+ "ast.Typ": "go/ast",
+ "ast.TypeAssertExpr": "go/ast",
+ "ast.TypeSpec": "go/ast",
+ "ast.TypeSwitchStmt": "go/ast",
+ "ast.UnaryExpr": "go/ast",
+ "ast.ValueSpec": "go/ast",
+ "ast.Var": "go/ast",
+ "ast.Visitor": "go/ast",
+ "ast.Walk": "go/ast",
+ "atomic.AddInt32": "sync/atomic",
+ "atomic.AddInt64": "sync/atomic",
+ "atomic.AddUint32": "sync/atomic",
+ "atomic.AddUint64": "sync/atomic",
+ "atomic.AddUintptr": "sync/atomic",
+ "atomic.CompareAndSwapInt32": "sync/atomic",
+ "atomic.CompareAndSwapInt64": "sync/atomic",
+ "atomic.CompareAndSwapPointer": "sync/atomic",
+ "atomic.CompareAndSwapUint32": "sync/atomic",
+ "atomic.CompareAndSwapUint64": "sync/atomic",
+ "atomic.CompareAndSwapUintptr": "sync/atomic",
+ "atomic.LoadInt32": "sync/atomic",
+ "atomic.LoadInt64": "sync/atomic",
+ "atomic.LoadPointer": "sync/atomic",
+ "atomic.LoadUint32": "sync/atomic",
+ "atomic.LoadUint64": "sync/atomic",
+ "atomic.LoadUintptr": "sync/atomic",
+ "atomic.StoreInt32": "sync/atomic",
+ "atomic.StoreInt64": "sync/atomic",
+ "atomic.StorePointer": "sync/atomic",
+ "atomic.StoreUint32": "sync/atomic",
+ "atomic.StoreUint64": "sync/atomic",
+ "atomic.StoreUintptr": "sync/atomic",
+ "atomic.SwapInt32": "sync/atomic",
+ "atomic.SwapInt64": "sync/atomic",
+ "atomic.SwapPointer": "sync/atomic",
+ "atomic.SwapUint32": "sync/atomic",
+ "atomic.SwapUint64": "sync/atomic",
+ "atomic.SwapUintptr": "sync/atomic",
+ "base32.CorruptInputError": "encoding/base32",
+ "base32.Encoding": "encoding/base32",
+ "base32.HexEncoding": "encoding/base32",
+ "base32.NewDecoder": "encoding/base32",
+ "base32.NewEncoder": "encoding/base32",
+ "base32.NewEncoding": "encoding/base32",
+ "base32.StdEncoding": "encoding/base32",
+ "base64.CorruptInputError": "encoding/base64",
+ "base64.Encoding": "encoding/base64",
+ "base64.NewDecoder": "encoding/base64",
+ "base64.NewEncoder": "encoding/base64",
+ "base64.NewEncoding": "encoding/base64",
+ "base64.StdEncoding": "encoding/base64",
+ "base64.URLEncoding": "encoding/base64",
+ "big.Int": "math/big",
+ "big.MaxBase": "math/big",
+ "big.NewInt": "math/big",
+ "big.NewRat": "math/big",
+ "big.Rat": "math/big",
+ "big.Word": "math/big",
+ "binary.BigEndian": "encoding/binary",
+ "binary.ByteOrder": "encoding/binary",
+ "binary.LittleEndian": "encoding/binary",
+ "binary.MaxVarintLen16": "encoding/binary",
+ "binary.MaxVarintLen32": "encoding/binary",
+ "binary.MaxVarintLen64": "encoding/binary",
+ "binary.PutUvarint": "encoding/binary",
+ "binary.PutVarint": "encoding/binary",
+ "binary.Read": "encoding/binary",
+ "binary.ReadUvarint": "encoding/binary",
+ "binary.ReadVarint": "encoding/binary",
+ "binary.Size": "encoding/binary",
+ "binary.Uvarint": "encoding/binary",
+ "binary.Varint": "encoding/binary",
+ "binary.Write": "encoding/binary",
+ "bufio.ErrAdvanceTooFar": "bufio",
+ "bufio.ErrBufferFull": "bufio",
+ "bufio.ErrInvalidUnreadByte": "bufio",
+ "bufio.ErrInvalidUnreadRune": "bufio",
+ "bufio.ErrNegativeAdvance": "bufio",
+ "bufio.ErrNegativeCount": "bufio",
+ "bufio.ErrTooLong": "bufio",
+ "bufio.MaxScanTokenSize": "bufio",
+ "bufio.NewReadWriter": "bufio",
+ "bufio.NewReader": "bufio",
+ "bufio.NewReaderSize": "bufio",
+ "bufio.NewScanner": "bufio",
+ "bufio.NewWriter": "bufio",
+ "bufio.NewWriterSize": "bufio",
+ "bufio.ReadWriter": "bufio",
+ "bufio.Reader": "bufio",
+ "bufio.ScanBytes": "bufio",
+ "bufio.ScanLines": "bufio",
+ "bufio.ScanRunes": "bufio",
+ "bufio.ScanWords": "bufio",
+ "bufio.Scanner": "bufio",
+ "bufio.SplitFunc": "bufio",
+ "bufio.Writer": "bufio",
+ "build.AllowBinary": "go/build",
+ "build.ArchChar": "go/build",
+ "build.Context": "go/build",
+ "build.Default": "go/build",
+ "build.FindOnly": "go/build",
+ "build.Import": "go/build",
+ "build.ImportDir": "go/build",
+ "build.ImportMode": "go/build",
+ "build.IsLocalImport": "go/build",
+ "build.NoGoError": "go/build",
+ "build.Package": "go/build",
+ "build.ToolDir": "go/build",
+ "bytes.Buffer": "bytes",
+ "bytes.Compare": "bytes",
+ "bytes.Contains": "bytes",
+ "bytes.Count": "bytes",
+ "bytes.Equal": "bytes",
+ "bytes.EqualFold": "bytes",
+ "bytes.ErrTooLarge": "bytes",
+ "bytes.Fields": "bytes",
+ "bytes.FieldsFunc": "bytes",
+ "bytes.HasPrefix": "bytes",
+ "bytes.HasSuffix": "bytes",
+ "bytes.Index": "bytes",
+ "bytes.IndexAny": "bytes",
+ "bytes.IndexByte": "bytes",
+ "bytes.IndexFunc": "bytes",
+ "bytes.IndexRune": "bytes",
+ "bytes.Join": "bytes",
+ "bytes.LastIndex": "bytes",
+ "bytes.LastIndexAny": "bytes",
+ "bytes.LastIndexFunc": "bytes",
+ "bytes.Map": "bytes",
+ "bytes.MinRead": "bytes",
+ "bytes.NewBuffer": "bytes",
+ "bytes.NewBufferString": "bytes",
+ "bytes.NewReader": "bytes",
+ "bytes.Reader": "bytes",
+ "bytes.Repeat": "bytes",
+ "bytes.Replace": "bytes",
+ "bytes.Runes": "bytes",
+ "bytes.Split": "bytes",
+ "bytes.SplitAfter": "bytes",
+ "bytes.SplitAfterN": "bytes",
+ "bytes.SplitN": "bytes",
+ "bytes.Title": "bytes",
+ "bytes.ToLower": "bytes",
+ "bytes.ToLowerSpecial": "bytes",
+ "bytes.ToTitle": "bytes",
+ "bytes.ToTitleSpecial": "bytes",
+ "bytes.ToUpper": "bytes",
+ "bytes.ToUpperSpecial": "bytes",
+ "bytes.Trim": "bytes",
+ "bytes.TrimFunc": "bytes",
+ "bytes.TrimLeft": "bytes",
+ "bytes.TrimLeftFunc": "bytes",
+ "bytes.TrimPrefix": "bytes",
+ "bytes.TrimRight": "bytes",
+ "bytes.TrimRightFunc": "bytes",
+ "bytes.TrimSpace": "bytes",
+ "bytes.TrimSuffix": "bytes",
+ "bzip2.NewReader": "compress/bzip2",
+ "bzip2.StructuralError": "compress/bzip2",
+ "cgi.Handler": "net/http/cgi",
+ "cgi.Request": "net/http/cgi",
+ "cgi.RequestFromMap": "net/http/cgi",
+ "cgi.Serve": "net/http/cgi",
+ "cipher.AEAD": "crypto/cipher",
+ "cipher.Block": "crypto/cipher",
+ "cipher.BlockMode": "crypto/cipher",
+ "cipher.NewCBCDecrypter": "crypto/cipher",
+ "cipher.NewCBCEncrypter": "crypto/cipher",
+ "cipher.NewCFBDecrypter": "crypto/cipher",
+ "cipher.NewCFBEncrypter": "crypto/cipher",
+ "cipher.NewCTR": "crypto/cipher",
+ "cipher.NewGCM": "crypto/cipher",
+ "cipher.NewOFB": "crypto/cipher",
+ "cipher.Stream": "crypto/cipher",
+ "cipher.StreamReader": "crypto/cipher",
+ "cipher.StreamWriter": "crypto/cipher",
+ "cmplx.Abs": "math/cmplx",
+ "cmplx.Acos": "math/cmplx",
+ "cmplx.Acosh": "math/cmplx",
+ "cmplx.Asin": "math/cmplx",
+ "cmplx.Asinh": "math/cmplx",
+ "cmplx.Atan": "math/cmplx",
+ "cmplx.Atanh": "math/cmplx",
+ "cmplx.Conj": "math/cmplx",
+ "cmplx.Cos": "math/cmplx",
+ "cmplx.Cosh": "math/cmplx",
+ "cmplx.Cot": "math/cmplx",
+ "cmplx.Exp": "math/cmplx",
+ "cmplx.Inf": "math/cmplx",
+ "cmplx.IsInf": "math/cmplx",
+ "cmplx.IsNaN": "math/cmplx",
+ "cmplx.Log": "math/cmplx",
+ "cmplx.Log10": "math/cmplx",
+ "cmplx.NaN": "math/cmplx",
+ "cmplx.Phase": "math/cmplx",
+ "cmplx.Polar": "math/cmplx",
+ "cmplx.Pow": "math/cmplx",
+ "cmplx.Rect": "math/cmplx",
+ "cmplx.Sin": "math/cmplx",
+ "cmplx.Sinh": "math/cmplx",
+ "cmplx.Sqrt": "math/cmplx",
+ "cmplx.Tan": "math/cmplx",
+ "cmplx.Tanh": "math/cmplx",
+ "color.Alpha": "image/color",
+ "color.Alpha16": "image/color",
+ "color.Alpha16Model": "image/color",
+ "color.AlphaModel": "image/color",
+ "color.Black": "image/color",
+ "color.Color": "image/color",
+ "color.Gray": "image/color",
+ "color.Gray16": "image/color",
+ "color.Gray16Model": "image/color",
+ "color.GrayModel": "image/color",
+ "color.Model": "image/color",
+ "color.ModelFunc": "image/color",
+ "color.NRGBA": "image/color",
+ "color.NRGBA64": "image/color",
+ "color.NRGBA64Model": "image/color",
+ "color.NRGBAModel": "image/color",
+ "color.Opaque": "image/color",
+ "color.Palette": "image/color",
+ "color.RGBA": "image/color",
+ "color.RGBA64": "image/color",
+ "color.RGBA64Model": "image/color",
+ "color.RGBAModel": "image/color",
+ "color.RGBToYCbCr": "image/color",
+ "color.Transparent": "image/color",
+ "color.White": "image/color",
+ "color.YCbCr": "image/color",
+ "color.YCbCrModel": "image/color",
+ "color.YCbCrToRGB": "image/color",
+ "cookiejar.Jar": "net/http/cookiejar",
+ "cookiejar.New": "net/http/cookiejar",
+ "cookiejar.Options": "net/http/cookiejar",
+ "cookiejar.PublicSuffixList": "net/http/cookiejar",
+ "crc32.Castagnoli": "hash/crc32",
+ "crc32.Checksum": "hash/crc32",
+ "crc32.ChecksumIEEE": "hash/crc32",
+ "crc32.IEEE": "hash/crc32",
+ "crc32.IEEETable": "hash/crc32",
+ "crc32.Koopman": "hash/crc32",
+ "crc32.MakeTable": "hash/crc32",
+ "crc32.New": "hash/crc32",
+ "crc32.NewIEEE": "hash/crc32",
+ "crc32.Size": "hash/crc32",
+ "crc32.Table": "hash/crc32",
+ "crc32.Update": "hash/crc32",
+ "crc64.Checksum": "hash/crc64",
+ "crc64.ECMA": "hash/crc64",
+ "crc64.ISO": "hash/crc64",
+ "crc64.MakeTable": "hash/crc64",
+ "crc64.New": "hash/crc64",
+ "crc64.Size": "hash/crc64",
+ "crc64.Table": "hash/crc64",
+ "crc64.Update": "hash/crc64",
+ "crypto.Hash": "crypto",
+ "crypto.MD4": "crypto",
+ "crypto.MD5": "crypto",
+ "crypto.MD5SHA1": "crypto",
+ "crypto.PrivateKey": "crypto",
+ "crypto.PublicKey": "crypto",
+ "crypto.RIPEMD160": "crypto",
+ "crypto.RegisterHash": "crypto",
+ "crypto.SHA1": "crypto",
+ "crypto.SHA224": "crypto",
+ "crypto.SHA256": "crypto",
+ "crypto.SHA384": "crypto",
+ "crypto.SHA512": "crypto",
+ "csv.ErrBareQuote": "encoding/csv",
+ "csv.ErrFieldCount": "encoding/csv",
+ "csv.ErrQuote": "encoding/csv",
+ "csv.ErrTrailingComma": "encoding/csv",
+ "csv.NewReader": "encoding/csv",
+ "csv.NewWriter": "encoding/csv",
+ "csv.ParseError": "encoding/csv",
+ "csv.Reader": "encoding/csv",
+ "csv.Writer": "encoding/csv",
+ "debug.FreeOSMemory": "runtime/debug",
+ "debug.GCStats": "runtime/debug",
+ "debug.PrintStack": "runtime/debug",
+ "debug.ReadGCStats": "runtime/debug",
+ "debug.SetGCPercent": "runtime/debug",
+ "debug.SetMaxStack": "runtime/debug",
+ "debug.SetMaxThreads": "runtime/debug",
+ "debug.SetPanicOnFault": "runtime/debug",
+ "debug.Stack": "runtime/debug",
+ "debug.WriteHeapDump": "runtime/debug",
+ "des.BlockSize": "crypto/des",
+ "des.KeySizeError": "crypto/des",
+ "des.NewCipher": "crypto/des",
+ "des.NewTripleDESCipher": "crypto/des",
+ "doc.AllDecls": "go/doc",
+ "doc.AllMethods": "go/doc",
+ "doc.Example": "go/doc",
+ "doc.Examples": "go/doc",
+ "doc.Filter": "go/doc",
+ "doc.Func": "go/doc",
+ "doc.IllegalPrefixes": "go/doc",
+ "doc.Mode": "go/doc",
+ "doc.New": "go/doc",
+ "doc.Note": "go/doc",
+ "doc.Package": "go/doc",
+ "doc.Synopsis": "go/doc",
+ "doc.ToHTML": "go/doc",
+ "doc.ToText": "go/doc",
+ "doc.Type": "go/doc",
+ "doc.Value": "go/doc",
+ "draw.Draw": "image/draw",
+ "draw.DrawMask": "image/draw",
+ "draw.Drawer": "image/draw",
+ "draw.FloydSteinberg": "image/draw",
+ "draw.Image": "image/draw",
+ "draw.Op": "image/draw",
+ "draw.Over": "image/draw",
+ "draw.Quantizer": "image/draw",
+ "draw.Src": "image/draw",
+ "driver.Bool": "database/sql/driver",
+ "driver.ColumnConverter": "database/sql/driver",
+ "driver.Conn": "database/sql/driver",
+ "driver.DefaultParameterConverter": "database/sql/driver",
+ "driver.Driver": "database/sql/driver",
+ "driver.ErrBadConn": "database/sql/driver",
+ "driver.ErrSkip": "database/sql/driver",
+ "driver.Execer": "database/sql/driver",
+ "driver.Int32": "database/sql/driver",
+ "driver.IsScanValue": "database/sql/driver",
+ "driver.IsValue": "database/sql/driver",
+ "driver.NotNull": "database/sql/driver",
+ "driver.Null": "database/sql/driver",
+ "driver.Queryer": "database/sql/driver",
+ "driver.Result": "database/sql/driver",
+ "driver.ResultNoRows": "database/sql/driver",
+ "driver.Rows": "database/sql/driver",
+ "driver.RowsAffected": "database/sql/driver",
+ "driver.Stmt": "database/sql/driver",
+ "driver.String": "database/sql/driver",
+ "driver.Tx": "database/sql/driver",
+ "driver.Value": "database/sql/driver",
+ "driver.ValueConverter": "database/sql/driver",
+ "driver.Valuer": "database/sql/driver",
+ "dsa.ErrInvalidPublicKey": "crypto/dsa",
+ "dsa.GenerateKey": "crypto/dsa",
+ "dsa.GenerateParameters": "crypto/dsa",
+ "dsa.L1024N160": "crypto/dsa",
+ "dsa.L2048N224": "crypto/dsa",
+ "dsa.L2048N256": "crypto/dsa",
+ "dsa.L3072N256": "crypto/dsa",
+ "dsa.ParameterSizes": "crypto/dsa",
+ "dsa.Parameters": "crypto/dsa",
+ "dsa.PrivateKey": "crypto/dsa",
+ "dsa.PublicKey": "crypto/dsa",
+ "dsa.Sign": "crypto/dsa",
+ "dsa.Verify": "crypto/dsa",
+ "dwarf.AddrType": "debug/dwarf",
+ "dwarf.ArrayType": "debug/dwarf",
+ "dwarf.Attr": "debug/dwarf",
+ "dwarf.AttrAbstractOrigin": "debug/dwarf",
+ "dwarf.AttrAccessibility": "debug/dwarf",
+ "dwarf.AttrAddrClass": "debug/dwarf",
+ "dwarf.AttrAllocated": "debug/dwarf",
+ "dwarf.AttrArtificial": "debug/dwarf",
+ "dwarf.AttrAssociated": "debug/dwarf",
+ "dwarf.AttrBaseTypes": "debug/dwarf",
+ "dwarf.AttrBitOffset": "debug/dwarf",
+ "dwarf.AttrBitSize": "debug/dwarf",
+ "dwarf.AttrByteSize": "debug/dwarf",
+ "dwarf.AttrCallColumn": "debug/dwarf",
+ "dwarf.AttrCallFile": "debug/dwarf",
+ "dwarf.AttrCallLine": "debug/dwarf",
+ "dwarf.AttrCalling": "debug/dwarf",
+ "dwarf.AttrCommonRef": "debug/dwarf",
+ "dwarf.AttrCompDir": "debug/dwarf",
+ "dwarf.AttrConstValue": "debug/dwarf",
+ "dwarf.AttrContainingType": "debug/dwarf",
+ "dwarf.AttrCount": "debug/dwarf",
+ "dwarf.AttrDataLocation": "debug/dwarf",
+ "dwarf.AttrDataMemberLoc": "debug/dwarf",
+ "dwarf.AttrDeclColumn": "debug/dwarf",
+ "dwarf.AttrDeclFile": "debug/dwarf",
+ "dwarf.AttrDeclLine": "debug/dwarf",
+ "dwarf.AttrDeclaration": "debug/dwarf",
+ "dwarf.AttrDefaultValue": "debug/dwarf",
+ "dwarf.AttrDescription": "debug/dwarf",
+ "dwarf.AttrDiscr": "debug/dwarf",
+ "dwarf.AttrDiscrList": "debug/dwarf",
+ "dwarf.AttrDiscrValue": "debug/dwarf",
+ "dwarf.AttrEncoding": "debug/dwarf",
+ "dwarf.AttrEntrypc": "debug/dwarf",
+ "dwarf.AttrExtension": "debug/dwarf",
+ "dwarf.AttrExternal": "debug/dwarf",
+ "dwarf.AttrFrameBase": "debug/dwarf",
+ "dwarf.AttrFriend": "debug/dwarf",
+ "dwarf.AttrHighpc": "debug/dwarf",
+ "dwarf.AttrIdentifierCase": "debug/dwarf",
+ "dwarf.AttrImport": "debug/dwarf",
+ "dwarf.AttrInline": "debug/dwarf",
+ "dwarf.AttrIsOptional": "debug/dwarf",
+ "dwarf.AttrLanguage": "debug/dwarf",
+ "dwarf.AttrLocation": "debug/dwarf",
+ "dwarf.AttrLowerBound": "debug/dwarf",
+ "dwarf.AttrLowpc": "debug/dwarf",
+ "dwarf.AttrMacroInfo": "debug/dwarf",
+ "dwarf.AttrName": "debug/dwarf",
+ "dwarf.AttrNamelistItem": "debug/dwarf",
+ "dwarf.AttrOrdering": "debug/dwarf",
+ "dwarf.AttrPriority": "debug/dwarf",
+ "dwarf.AttrProducer": "debug/dwarf",
+ "dwarf.AttrPrototyped": "debug/dwarf",
+ "dwarf.AttrRanges": "debug/dwarf",
+ "dwarf.AttrReturnAddr": "debug/dwarf",
+ "dwarf.AttrSegment": "debug/dwarf",
+ "dwarf.AttrSibling": "debug/dwarf",
+ "dwarf.AttrSpecification": "debug/dwarf",
+ "dwarf.AttrStartScope": "debug/dwarf",
+ "dwarf.AttrStaticLink": "debug/dwarf",
+ "dwarf.AttrStmtList": "debug/dwarf",
+ "dwarf.AttrStride": "debug/dwarf",
+ "dwarf.AttrStrideSize": "debug/dwarf",
+ "dwarf.AttrStringLength": "debug/dwarf",
+ "dwarf.AttrTrampoline": "debug/dwarf",
+ "dwarf.AttrType": "debug/dwarf",
+ "dwarf.AttrUpperBound": "debug/dwarf",
+ "dwarf.AttrUseLocation": "debug/dwarf",
+ "dwarf.AttrUseUTF8": "debug/dwarf",
+ "dwarf.AttrVarParam": "debug/dwarf",
+ "dwarf.AttrVirtuality": "debug/dwarf",
+ "dwarf.AttrVisibility": "debug/dwarf",
+ "dwarf.AttrVtableElemLoc": "debug/dwarf",
+ "dwarf.BasicType": "debug/dwarf",
+ "dwarf.BoolType": "debug/dwarf",
+ "dwarf.CharType": "debug/dwarf",
+ "dwarf.CommonType": "debug/dwarf",
+ "dwarf.ComplexType": "debug/dwarf",
+ "dwarf.Data": "debug/dwarf",
+ "dwarf.DecodeError": "debug/dwarf",
+ "dwarf.DotDotDotType": "debug/dwarf",
+ "dwarf.Entry": "debug/dwarf",
+ "dwarf.EnumType": "debug/dwarf",
+ "dwarf.EnumValue": "debug/dwarf",
+ "dwarf.Field": "debug/dwarf",
+ "dwarf.FloatType": "debug/dwarf",
+ "dwarf.FuncType": "debug/dwarf",
+ "dwarf.IntType": "debug/dwarf",
+ "dwarf.New": "debug/dwarf",
+ "dwarf.Offset": "debug/dwarf",
+ "dwarf.PtrType": "debug/dwarf",
+ "dwarf.QualType": "debug/dwarf",
+ "dwarf.Reader": "debug/dwarf",
+ "dwarf.StructField": "debug/dwarf",
+ "dwarf.StructType": "debug/dwarf",
+ "dwarf.Tag": "debug/dwarf",
+ "dwarf.TagAccessDeclaration": "debug/dwarf",
+ "dwarf.TagArrayType": "debug/dwarf",
+ "dwarf.TagBaseType": "debug/dwarf",
+ "dwarf.TagCatchDwarfBlock": "debug/dwarf",
+ "dwarf.TagClassType": "debug/dwarf",
+ "dwarf.TagCommonDwarfBlock": "debug/dwarf",
+ "dwarf.TagCommonInclusion": "debug/dwarf",
+ "dwarf.TagCompileUnit": "debug/dwarf",
+ "dwarf.TagCondition": "debug/dwarf",
+ "dwarf.TagConstType": "debug/dwarf",
+ "dwarf.TagConstant": "debug/dwarf",
+ "dwarf.TagDwarfProcedure": "debug/dwarf",
+ "dwarf.TagEntryPoint": "debug/dwarf",
+ "dwarf.TagEnumerationType": "debug/dwarf",
+ "dwarf.TagEnumerator": "debug/dwarf",
+ "dwarf.TagFileType": "debug/dwarf",
+ "dwarf.TagFormalParameter": "debug/dwarf",
+ "dwarf.TagFriend": "debug/dwarf",
+ "dwarf.TagImportedDeclaration": "debug/dwarf",
+ "dwarf.TagImportedModule": "debug/dwarf",
+ "dwarf.TagImportedUnit": "debug/dwarf",
+ "dwarf.TagInheritance": "debug/dwarf",
+ "dwarf.TagInlinedSubroutine": "debug/dwarf",
+ "dwarf.TagInterfaceType": "debug/dwarf",
+ "dwarf.TagLabel": "debug/dwarf",
+ "dwarf.TagLexDwarfBlock": "debug/dwarf",
+ "dwarf.TagMember": "debug/dwarf",
+ "dwarf.TagModule": "debug/dwarf",
+ "dwarf.TagMutableType": "debug/dwarf",
+ "dwarf.TagNamelist": "debug/dwarf",
+ "dwarf.TagNamelistItem": "debug/dwarf",
+ "dwarf.TagNamespace": "debug/dwarf",
+ "dwarf.TagPackedType": "debug/dwarf",
+ "dwarf.TagPartialUnit": "debug/dwarf",
+ "dwarf.TagPointerType": "debug/dwarf",
+ "dwarf.TagPtrToMemberType": "debug/dwarf",
+ "dwarf.TagReferenceType": "debug/dwarf",
+ "dwarf.TagRestrictType": "debug/dwarf",
+ "dwarf.TagRvalueReferenceType": "debug/dwarf",
+ "dwarf.TagSetType": "debug/dwarf",
+ "dwarf.TagSharedType": "debug/dwarf",
+ "dwarf.TagStringType": "debug/dwarf",
+ "dwarf.TagStructType": "debug/dwarf",
+ "dwarf.TagSubprogram": "debug/dwarf",
+ "dwarf.TagSubrangeType": "debug/dwarf",
+ "dwarf.TagSubroutineType": "debug/dwarf",
+ "dwarf.TagTemplateAlias": "debug/dwarf",
+ "dwarf.TagTemplateTypeParameter": "debug/dwarf",
+ "dwarf.TagTemplateValueParameter": "debug/dwarf",
+ "dwarf.TagThrownType": "debug/dwarf",
+ "dwarf.TagTryDwarfBlock": "debug/dwarf",
+ "dwarf.TagTypeUnit": "debug/dwarf",
+ "dwarf.TagTypedef": "debug/dwarf",
+ "dwarf.TagUnionType": "debug/dwarf",
+ "dwarf.TagUnspecifiedParameters": "debug/dwarf",
+ "dwarf.TagUnspecifiedType": "debug/dwarf",
+ "dwarf.TagVariable": "debug/dwarf",
+ "dwarf.TagVariant": "debug/dwarf",
+ "dwarf.TagVariantPart": "debug/dwarf",
+ "dwarf.TagVolatileType": "debug/dwarf",
+ "dwarf.TagWithStmt": "debug/dwarf",
+ "dwarf.Type": "debug/dwarf",
+ "dwarf.TypedefType": "debug/dwarf",
+ "dwarf.UcharType": "debug/dwarf",
+ "dwarf.UintType": "debug/dwarf",
+ "dwarf.VoidType": "debug/dwarf",
+ "ecdsa.GenerateKey": "crypto/ecdsa",
+ "ecdsa.PrivateKey": "crypto/ecdsa",
+ "ecdsa.PublicKey": "crypto/ecdsa",
+ "ecdsa.Sign": "crypto/ecdsa",
+ "ecdsa.Verify": "crypto/ecdsa",
+ "elf.ARM_MAGIC_TRAMP_NUMBER": "debug/elf",
+ "elf.Class": "debug/elf",
+ "elf.DF_BIND_NOW": "debug/elf",
+ "elf.DF_ORIGIN": "debug/elf",
+ "elf.DF_STATIC_TLS": "debug/elf",
+ "elf.DF_SYMBOLIC": "debug/elf",
+ "elf.DF_TEXTREL": "debug/elf",
+ "elf.DT_BIND_NOW": "debug/elf",
+ "elf.DT_DEBUG": "debug/elf",
+ "elf.DT_ENCODING": "debug/elf",
+ "elf.DT_FINI": "debug/elf",
+ "elf.DT_FINI_ARRAY": "debug/elf",
+ "elf.DT_FINI_ARRAYSZ": "debug/elf",
+ "elf.DT_FLAGS": "debug/elf",
+ "elf.DT_HASH": "debug/elf",
+ "elf.DT_HIOS": "debug/elf",
+ "elf.DT_HIPROC": "debug/elf",
+ "elf.DT_INIT": "debug/elf",
+ "elf.DT_INIT_ARRAY": "debug/elf",
+ "elf.DT_INIT_ARRAYSZ": "debug/elf",
+ "elf.DT_JMPREL": "debug/elf",
+ "elf.DT_LOOS": "debug/elf",
+ "elf.DT_LOPROC": "debug/elf",
+ "elf.DT_NEEDED": "debug/elf",
+ "elf.DT_NULL": "debug/elf",
+ "elf.DT_PLTGOT": "debug/elf",
+ "elf.DT_PLTREL": "debug/elf",
+ "elf.DT_PLTRELSZ": "debug/elf",
+ "elf.DT_PREINIT_ARRAY": "debug/elf",
+ "elf.DT_PREINIT_ARRAYSZ": "debug/elf",
+ "elf.DT_REL": "debug/elf",
+ "elf.DT_RELA": "debug/elf",
+ "elf.DT_RELAENT": "debug/elf",
+ "elf.DT_RELASZ": "debug/elf",
+ "elf.DT_RELENT": "debug/elf",
+ "elf.DT_RELSZ": "debug/elf",
+ "elf.DT_RPATH": "debug/elf",
+ "elf.DT_RUNPATH": "debug/elf",
+ "elf.DT_SONAME": "debug/elf",
+ "elf.DT_STRSZ": "debug/elf",
+ "elf.DT_STRTAB": "debug/elf",
+ "elf.DT_SYMBOLIC": "debug/elf",
+ "elf.DT_SYMENT": "debug/elf",
+ "elf.DT_SYMTAB": "debug/elf",
+ "elf.DT_TEXTREL": "debug/elf",
+ "elf.DT_VERNEED": "debug/elf",
+ "elf.DT_VERNEEDNUM": "debug/elf",
+ "elf.DT_VERSYM": "debug/elf",
+ "elf.Data": "debug/elf",
+ "elf.Dyn32": "debug/elf",
+ "elf.Dyn64": "debug/elf",
+ "elf.DynFlag": "debug/elf",
+ "elf.DynTag": "debug/elf",
+ "elf.EI_ABIVERSION": "debug/elf",
+ "elf.EI_CLASS": "debug/elf",
+ "elf.EI_DATA": "debug/elf",
+ "elf.EI_NIDENT": "debug/elf",
+ "elf.EI_OSABI": "debug/elf",
+ "elf.EI_PAD": "debug/elf",
+ "elf.EI_VERSION": "debug/elf",
+ "elf.ELFCLASS32": "debug/elf",
+ "elf.ELFCLASS64": "debug/elf",
+ "elf.ELFCLASSNONE": "debug/elf",
+ "elf.ELFDATA2LSB": "debug/elf",
+ "elf.ELFDATA2MSB": "debug/elf",
+ "elf.ELFDATANONE": "debug/elf",
+ "elf.ELFMAG": "debug/elf",
+ "elf.ELFOSABI_86OPEN": "debug/elf",
+ "elf.ELFOSABI_AIX": "debug/elf",
+ "elf.ELFOSABI_ARM": "debug/elf",
+ "elf.ELFOSABI_FREEBSD": "debug/elf",
+ "elf.ELFOSABI_HPUX": "debug/elf",
+ "elf.ELFOSABI_HURD": "debug/elf",
+ "elf.ELFOSABI_IRIX": "debug/elf",
+ "elf.ELFOSABI_LINUX": "debug/elf",
+ "elf.ELFOSABI_MODESTO": "debug/elf",
+ "elf.ELFOSABI_NETBSD": "debug/elf",
+ "elf.ELFOSABI_NONE": "debug/elf",
+ "elf.ELFOSABI_NSK": "debug/elf",
+ "elf.ELFOSABI_OPENBSD": "debug/elf",
+ "elf.ELFOSABI_OPENVMS": "debug/elf",
+ "elf.ELFOSABI_SOLARIS": "debug/elf",
+ "elf.ELFOSABI_STANDALONE": "debug/elf",
+ "elf.ELFOSABI_TRU64": "debug/elf",
+ "elf.EM_386": "debug/elf",
+ "elf.EM_486": "debug/elf",
+ "elf.EM_68HC12": "debug/elf",
+ "elf.EM_68K": "debug/elf",
+ "elf.EM_860": "debug/elf",
+ "elf.EM_88K": "debug/elf",
+ "elf.EM_960": "debug/elf",
+ "elf.EM_ALPHA": "debug/elf",
+ "elf.EM_ALPHA_STD": "debug/elf",
+ "elf.EM_ARC": "debug/elf",
+ "elf.EM_ARM": "debug/elf",
+ "elf.EM_COLDFIRE": "debug/elf",
+ "elf.EM_FR20": "debug/elf",
+ "elf.EM_H8S": "debug/elf",
+ "elf.EM_H8_300": "debug/elf",
+ "elf.EM_H8_300H": "debug/elf",
+ "elf.EM_H8_500": "debug/elf",
+ "elf.EM_IA_64": "debug/elf",
+ "elf.EM_M32": "debug/elf",
+ "elf.EM_ME16": "debug/elf",
+ "elf.EM_MIPS": "debug/elf",
+ "elf.EM_MIPS_RS3_LE": "debug/elf",
+ "elf.EM_MIPS_RS4_BE": "debug/elf",
+ "elf.EM_MIPS_X": "debug/elf",
+ "elf.EM_MMA": "debug/elf",
+ "elf.EM_NCPU": "debug/elf",
+ "elf.EM_NDR1": "debug/elf",
+ "elf.EM_NONE": "debug/elf",
+ "elf.EM_PARISC": "debug/elf",
+ "elf.EM_PCP": "debug/elf",
+ "elf.EM_PPC": "debug/elf",
+ "elf.EM_PPC64": "debug/elf",
+ "elf.EM_RCE": "debug/elf",
+ "elf.EM_RH32": "debug/elf",
+ "elf.EM_S370": "debug/elf",
+ "elf.EM_S390": "debug/elf",
+ "elf.EM_SH": "debug/elf",
+ "elf.EM_SPARC": "debug/elf",
+ "elf.EM_SPARC32PLUS": "debug/elf",
+ "elf.EM_SPARCV9": "debug/elf",
+ "elf.EM_ST100": "debug/elf",
+ "elf.EM_STARCORE": "debug/elf",
+ "elf.EM_TINYJ": "debug/elf",
+ "elf.EM_TRICORE": "debug/elf",
+ "elf.EM_V800": "debug/elf",
+ "elf.EM_VPP500": "debug/elf",
+ "elf.EM_X86_64": "debug/elf",
+ "elf.ET_CORE": "debug/elf",
+ "elf.ET_DYN": "debug/elf",
+ "elf.ET_EXEC": "debug/elf",
+ "elf.ET_HIOS": "debug/elf",
+ "elf.ET_HIPROC": "debug/elf",
+ "elf.ET_LOOS": "debug/elf",
+ "elf.ET_LOPROC": "debug/elf",
+ "elf.ET_NONE": "debug/elf",
+ "elf.ET_REL": "debug/elf",
+ "elf.EV_CURRENT": "debug/elf",
+ "elf.EV_NONE": "debug/elf",
+ "elf.File": "debug/elf",
+ "elf.FileHeader": "debug/elf",
+ "elf.FormatError": "debug/elf",
+ "elf.Header32": "debug/elf",
+ "elf.Header64": "debug/elf",
+ "elf.ImportedSymbol": "debug/elf",
+ "elf.Machine": "debug/elf",
+ "elf.NT_FPREGSET": "debug/elf",
+ "elf.NT_PRPSINFO": "debug/elf",
+ "elf.NT_PRSTATUS": "debug/elf",
+ "elf.NType": "debug/elf",
+ "elf.NewFile": "debug/elf",
+ "elf.OSABI": "debug/elf",
+ "elf.Open": "debug/elf",
+ "elf.PF_MASKOS": "debug/elf",
+ "elf.PF_MASKPROC": "debug/elf",
+ "elf.PF_R": "debug/elf",
+ "elf.PF_W": "debug/elf",
+ "elf.PF_X": "debug/elf",
+ "elf.PT_DYNAMIC": "debug/elf",
+ "elf.PT_HIOS": "debug/elf",
+ "elf.PT_HIPROC": "debug/elf",
+ "elf.PT_INTERP": "debug/elf",
+ "elf.PT_LOAD": "debug/elf",
+ "elf.PT_LOOS": "debug/elf",
+ "elf.PT_LOPROC": "debug/elf",
+ "elf.PT_NOTE": "debug/elf",
+ "elf.PT_NULL": "debug/elf",
+ "elf.PT_PHDR": "debug/elf",
+ "elf.PT_SHLIB": "debug/elf",
+ "elf.PT_TLS": "debug/elf",
+ "elf.Prog": "debug/elf",
+ "elf.Prog32": "debug/elf",
+ "elf.Prog64": "debug/elf",
+ "elf.ProgFlag": "debug/elf",
+ "elf.ProgHeader": "debug/elf",
+ "elf.ProgType": "debug/elf",
+ "elf.R_386": "debug/elf",
+ "elf.R_386_32": "debug/elf",
+ "elf.R_386_COPY": "debug/elf",
+ "elf.R_386_GLOB_DAT": "debug/elf",
+ "elf.R_386_GOT32": "debug/elf",
+ "elf.R_386_GOTOFF": "debug/elf",
+ "elf.R_386_GOTPC": "debug/elf",
+ "elf.R_386_JMP_SLOT": "debug/elf",
+ "elf.R_386_NONE": "debug/elf",
+ "elf.R_386_PC32": "debug/elf",
+ "elf.R_386_PLT32": "debug/elf",
+ "elf.R_386_RELATIVE": "debug/elf",
+ "elf.R_386_TLS_DTPMOD32": "debug/elf",
+ "elf.R_386_TLS_DTPOFF32": "debug/elf",
+ "elf.R_386_TLS_GD": "debug/elf",
+ "elf.R_386_TLS_GD_32": "debug/elf",
+ "elf.R_386_TLS_GD_CALL": "debug/elf",
+ "elf.R_386_TLS_GD_POP": "debug/elf",
+ "elf.R_386_TLS_GD_PUSH": "debug/elf",
+ "elf.R_386_TLS_GOTIE": "debug/elf",
+ "elf.R_386_TLS_IE": "debug/elf",
+ "elf.R_386_TLS_IE_32": "debug/elf",
+ "elf.R_386_TLS_LDM": "debug/elf",
+ "elf.R_386_TLS_LDM_32": "debug/elf",
+ "elf.R_386_TLS_LDM_CALL": "debug/elf",
+ "elf.R_386_TLS_LDM_POP": "debug/elf",
+ "elf.R_386_TLS_LDM_PUSH": "debug/elf",
+ "elf.R_386_TLS_LDO_32": "debug/elf",
+ "elf.R_386_TLS_LE": "debug/elf",
+ "elf.R_386_TLS_LE_32": "debug/elf",
+ "elf.R_386_TLS_TPOFF": "debug/elf",
+ "elf.R_386_TLS_TPOFF32": "debug/elf",
+ "elf.R_ALPHA": "debug/elf",
+ "elf.R_ALPHA_BRADDR": "debug/elf",
+ "elf.R_ALPHA_COPY": "debug/elf",
+ "elf.R_ALPHA_GLOB_DAT": "debug/elf",
+ "elf.R_ALPHA_GPDISP": "debug/elf",
+ "elf.R_ALPHA_GPREL32": "debug/elf",
+ "elf.R_ALPHA_GPRELHIGH": "debug/elf",
+ "elf.R_ALPHA_GPRELLOW": "debug/elf",
+ "elf.R_ALPHA_GPVALUE": "debug/elf",
+ "elf.R_ALPHA_HINT": "debug/elf",
+ "elf.R_ALPHA_IMMED_BR_HI32": "debug/elf",
+ "elf.R_ALPHA_IMMED_GP_16": "debug/elf",
+ "elf.R_ALPHA_IMMED_GP_HI32": "debug/elf",
+ "elf.R_ALPHA_IMMED_LO32": "debug/elf",
+ "elf.R_ALPHA_IMMED_SCN_HI32": "debug/elf",
+ "elf.R_ALPHA_JMP_SLOT": "debug/elf",
+ "elf.R_ALPHA_LITERAL": "debug/elf",
+ "elf.R_ALPHA_LITUSE": "debug/elf",
+ "elf.R_ALPHA_NONE": "debug/elf",
+ "elf.R_ALPHA_OP_PRSHIFT": "debug/elf",
+ "elf.R_ALPHA_OP_PSUB": "debug/elf",
+ "elf.R_ALPHA_OP_PUSH": "debug/elf",
+ "elf.R_ALPHA_OP_STORE": "debug/elf",
+ "elf.R_ALPHA_REFLONG": "debug/elf",
+ "elf.R_ALPHA_REFQUAD": "debug/elf",
+ "elf.R_ALPHA_RELATIVE": "debug/elf",
+ "elf.R_ALPHA_SREL16": "debug/elf",
+ "elf.R_ALPHA_SREL32": "debug/elf",
+ "elf.R_ALPHA_SREL64": "debug/elf",
+ "elf.R_ARM": "debug/elf",
+ "elf.R_ARM_ABS12": "debug/elf",
+ "elf.R_ARM_ABS16": "debug/elf",
+ "elf.R_ARM_ABS32": "debug/elf",
+ "elf.R_ARM_ABS8": "debug/elf",
+ "elf.R_ARM_AMP_VCALL9": "debug/elf",
+ "elf.R_ARM_COPY": "debug/elf",
+ "elf.R_ARM_GLOB_DAT": "debug/elf",
+ "elf.R_ARM_GNU_VTENTRY": "debug/elf",
+ "elf.R_ARM_GNU_VTINHERIT": "debug/elf",
+ "elf.R_ARM_GOT32": "debug/elf",
+ "elf.R_ARM_GOTOFF": "debug/elf",
+ "elf.R_ARM_GOTPC": "debug/elf",
+ "elf.R_ARM_JUMP_SLOT": "debug/elf",
+ "elf.R_ARM_NONE": "debug/elf",
+ "elf.R_ARM_PC13": "debug/elf",
+ "elf.R_ARM_PC24": "debug/elf",
+ "elf.R_ARM_PLT32": "debug/elf",
+ "elf.R_ARM_RABS32": "debug/elf",
+ "elf.R_ARM_RBASE": "debug/elf",
+ "elf.R_ARM_REL32": "debug/elf",
+ "elf.R_ARM_RELATIVE": "debug/elf",
+ "elf.R_ARM_RPC24": "debug/elf",
+ "elf.R_ARM_RREL32": "debug/elf",
+ "elf.R_ARM_RSBREL32": "debug/elf",
+ "elf.R_ARM_SBREL32": "debug/elf",
+ "elf.R_ARM_SWI24": "debug/elf",
+ "elf.R_ARM_THM_ABS5": "debug/elf",
+ "elf.R_ARM_THM_PC22": "debug/elf",
+ "elf.R_ARM_THM_PC8": "debug/elf",
+ "elf.R_ARM_THM_RPC22": "debug/elf",
+ "elf.R_ARM_THM_SWI8": "debug/elf",
+ "elf.R_ARM_THM_XPC22": "debug/elf",
+ "elf.R_ARM_XPC25": "debug/elf",
+ "elf.R_INFO": "debug/elf",
+ "elf.R_INFO32": "debug/elf",
+ "elf.R_PPC": "debug/elf",
+ "elf.R_PPC_ADDR14": "debug/elf",
+ "elf.R_PPC_ADDR14_BRNTAKEN": "debug/elf",
+ "elf.R_PPC_ADDR14_BRTAKEN": "debug/elf",
+ "elf.R_PPC_ADDR16": "debug/elf",
+ "elf.R_PPC_ADDR16_HA": "debug/elf",
+ "elf.R_PPC_ADDR16_HI": "debug/elf",
+ "elf.R_PPC_ADDR16_LO": "debug/elf",
+ "elf.R_PPC_ADDR24": "debug/elf",
+ "elf.R_PPC_ADDR32": "debug/elf",
+ "elf.R_PPC_COPY": "debug/elf",
+ "elf.R_PPC_DTPMOD32": "debug/elf",
+ "elf.R_PPC_DTPREL16": "debug/elf",
+ "elf.R_PPC_DTPREL16_HA": "debug/elf",
+ "elf.R_PPC_DTPREL16_HI": "debug/elf",
+ "elf.R_PPC_DTPREL16_LO": "debug/elf",
+ "elf.R_PPC_DTPREL32": "debug/elf",
+ "elf.R_PPC_EMB_BIT_FLD": "debug/elf",
+ "elf.R_PPC_EMB_MRKREF": "debug/elf",
+ "elf.R_PPC_EMB_NADDR16": "debug/elf",
+ "elf.R_PPC_EMB_NADDR16_HA": "debug/elf",
+ "elf.R_PPC_EMB_NADDR16_HI": "debug/elf",
+ "elf.R_PPC_EMB_NADDR16_LO": "debug/elf",
+ "elf.R_PPC_EMB_NADDR32": "debug/elf",
+ "elf.R_PPC_EMB_RELSDA": "debug/elf",
+ "elf.R_PPC_EMB_RELSEC16": "debug/elf",
+ "elf.R_PPC_EMB_RELST_HA": "debug/elf",
+ "elf.R_PPC_EMB_RELST_HI": "debug/elf",
+ "elf.R_PPC_EMB_RELST_LO": "debug/elf",
+ "elf.R_PPC_EMB_SDA21": "debug/elf",
+ "elf.R_PPC_EMB_SDA2I16": "debug/elf",
+ "elf.R_PPC_EMB_SDA2REL": "debug/elf",
+ "elf.R_PPC_EMB_SDAI16": "debug/elf",
+ "elf.R_PPC_GLOB_DAT": "debug/elf",
+ "elf.R_PPC_GOT16": "debug/elf",
+ "elf.R_PPC_GOT16_HA": "debug/elf",
+ "elf.R_PPC_GOT16_HI": "debug/elf",
+ "elf.R_PPC_GOT16_LO": "debug/elf",
+ "elf.R_PPC_GOT_TLSGD16": "debug/elf",
+ "elf.R_PPC_GOT_TLSGD16_HA": "debug/elf",
+ "elf.R_PPC_GOT_TLSGD16_HI": "debug/elf",
+ "elf.R_PPC_GOT_TLSGD16_LO": "debug/elf",
+ "elf.R_PPC_GOT_TLSLD16": "debug/elf",
+ "elf.R_PPC_GOT_TLSLD16_HA": "debug/elf",
+ "elf.R_PPC_GOT_TLSLD16_HI": "debug/elf",
+ "elf.R_PPC_GOT_TLSLD16_LO": "debug/elf",
+ "elf.R_PPC_GOT_TPREL16": "debug/elf",
+ "elf.R_PPC_GOT_TPREL16_HA": "debug/elf",
+ "elf.R_PPC_GOT_TPREL16_HI": "debug/elf",
+ "elf.R_PPC_GOT_TPREL16_LO": "debug/elf",
+ "elf.R_PPC_JMP_SLOT": "debug/elf",
+ "elf.R_PPC_LOCAL24PC": "debug/elf",
+ "elf.R_PPC_NONE": "debug/elf",
+ "elf.R_PPC_PLT16_HA": "debug/elf",
+ "elf.R_PPC_PLT16_HI": "debug/elf",
+ "elf.R_PPC_PLT16_LO": "debug/elf",
+ "elf.R_PPC_PLT32": "debug/elf",
+ "elf.R_PPC_PLTREL24": "debug/elf",
+ "elf.R_PPC_PLTREL32": "debug/elf",
+ "elf.R_PPC_REL14": "debug/elf",
+ "elf.R_PPC_REL14_BRNTAKEN": "debug/elf",
+ "elf.R_PPC_REL14_BRTAKEN": "debug/elf",
+ "elf.R_PPC_REL24": "debug/elf",
+ "elf.R_PPC_REL32": "debug/elf",
+ "elf.R_PPC_RELATIVE": "debug/elf",
+ "elf.R_PPC_SDAREL16": "debug/elf",
+ "elf.R_PPC_SECTOFF": "debug/elf",
+ "elf.R_PPC_SECTOFF_HA": "debug/elf",
+ "elf.R_PPC_SECTOFF_HI": "debug/elf",
+ "elf.R_PPC_SECTOFF_LO": "debug/elf",
+ "elf.R_PPC_TLS": "debug/elf",
+ "elf.R_PPC_TPREL16": "debug/elf",
+ "elf.R_PPC_TPREL16_HA": "debug/elf",
+ "elf.R_PPC_TPREL16_HI": "debug/elf",
+ "elf.R_PPC_TPREL16_LO": "debug/elf",
+ "elf.R_PPC_TPREL32": "debug/elf",
+ "elf.R_PPC_UADDR16": "debug/elf",
+ "elf.R_PPC_UADDR32": "debug/elf",
+ "elf.R_SPARC": "debug/elf",
+ "elf.R_SPARC_10": "debug/elf",
+ "elf.R_SPARC_11": "debug/elf",
+ "elf.R_SPARC_13": "debug/elf",
+ "elf.R_SPARC_16": "debug/elf",
+ "elf.R_SPARC_22": "debug/elf",
+ "elf.R_SPARC_32": "debug/elf",
+ "elf.R_SPARC_5": "debug/elf",
+ "elf.R_SPARC_6": "debug/elf",
+ "elf.R_SPARC_64": "debug/elf",
+ "elf.R_SPARC_7": "debug/elf",
+ "elf.R_SPARC_8": "debug/elf",
+ "elf.R_SPARC_COPY": "debug/elf",
+ "elf.R_SPARC_DISP16": "debug/elf",
+ "elf.R_SPARC_DISP32": "debug/elf",
+ "elf.R_SPARC_DISP64": "debug/elf",
+ "elf.R_SPARC_DISP8": "debug/elf",
+ "elf.R_SPARC_GLOB_DAT": "debug/elf",
+ "elf.R_SPARC_GLOB_JMP": "debug/elf",
+ "elf.R_SPARC_GOT10": "debug/elf",
+ "elf.R_SPARC_GOT13": "debug/elf",
+ "elf.R_SPARC_GOT22": "debug/elf",
+ "elf.R_SPARC_H44": "debug/elf",
+ "elf.R_SPARC_HH22": "debug/elf",
+ "elf.R_SPARC_HI22": "debug/elf",
+ "elf.R_SPARC_HIPLT22": "debug/elf",
+ "elf.R_SPARC_HIX22": "debug/elf",
+ "elf.R_SPARC_HM10": "debug/elf",
+ "elf.R_SPARC_JMP_SLOT": "debug/elf",
+ "elf.R_SPARC_L44": "debug/elf",
+ "elf.R_SPARC_LM22": "debug/elf",
+ "elf.R_SPARC_LO10": "debug/elf",
+ "elf.R_SPARC_LOPLT10": "debug/elf",
+ "elf.R_SPARC_LOX10": "debug/elf",
+ "elf.R_SPARC_M44": "debug/elf",
+ "elf.R_SPARC_NONE": "debug/elf",
+ "elf.R_SPARC_OLO10": "debug/elf",
+ "elf.R_SPARC_PC10": "debug/elf",
+ "elf.R_SPARC_PC22": "debug/elf",
+ "elf.R_SPARC_PCPLT10": "debug/elf",
+ "elf.R_SPARC_PCPLT22": "debug/elf",
+ "elf.R_SPARC_PCPLT32": "debug/elf",
+ "elf.R_SPARC_PC_HH22": "debug/elf",
+ "elf.R_SPARC_PC_HM10": "debug/elf",
+ "elf.R_SPARC_PC_LM22": "debug/elf",
+ "elf.R_SPARC_PLT32": "debug/elf",
+ "elf.R_SPARC_PLT64": "debug/elf",
+ "elf.R_SPARC_REGISTER": "debug/elf",
+ "elf.R_SPARC_RELATIVE": "debug/elf",
+ "elf.R_SPARC_UA16": "debug/elf",
+ "elf.R_SPARC_UA32": "debug/elf",
+ "elf.R_SPARC_UA64": "debug/elf",
+ "elf.R_SPARC_WDISP16": "debug/elf",
+ "elf.R_SPARC_WDISP19": "debug/elf",
+ "elf.R_SPARC_WDISP22": "debug/elf",
+ "elf.R_SPARC_WDISP30": "debug/elf",
+ "elf.R_SPARC_WPLT30": "debug/elf",
+ "elf.R_SYM32": "debug/elf",
+ "elf.R_SYM64": "debug/elf",
+ "elf.R_TYPE32": "debug/elf",
+ "elf.R_TYPE64": "debug/elf",
+ "elf.R_X86_64": "debug/elf",
+ "elf.R_X86_64_16": "debug/elf",
+ "elf.R_X86_64_32": "debug/elf",
+ "elf.R_X86_64_32S": "debug/elf",
+ "elf.R_X86_64_64": "debug/elf",
+ "elf.R_X86_64_8": "debug/elf",
+ "elf.R_X86_64_COPY": "debug/elf",
+ "elf.R_X86_64_DTPMOD64": "debug/elf",
+ "elf.R_X86_64_DTPOFF32": "debug/elf",
+ "elf.R_X86_64_DTPOFF64": "debug/elf",
+ "elf.R_X86_64_GLOB_DAT": "debug/elf",
+ "elf.R_X86_64_GOT32": "debug/elf",
+ "elf.R_X86_64_GOTPCREL": "debug/elf",
+ "elf.R_X86_64_GOTTPOFF": "debug/elf",
+ "elf.R_X86_64_JMP_SLOT": "debug/elf",
+ "elf.R_X86_64_NONE": "debug/elf",
+ "elf.R_X86_64_PC16": "debug/elf",
+ "elf.R_X86_64_PC32": "debug/elf",
+ "elf.R_X86_64_PC8": "debug/elf",
+ "elf.R_X86_64_PLT32": "debug/elf",
+ "elf.R_X86_64_RELATIVE": "debug/elf",
+ "elf.R_X86_64_TLSGD": "debug/elf",
+ "elf.R_X86_64_TLSLD": "debug/elf",
+ "elf.R_X86_64_TPOFF32": "debug/elf",
+ "elf.R_X86_64_TPOFF64": "debug/elf",
+ "elf.Rel32": "debug/elf",
+ "elf.Rel64": "debug/elf",
+ "elf.Rela32": "debug/elf",
+ "elf.Rela64": "debug/elf",
+ "elf.SHF_ALLOC": "debug/elf",
+ "elf.SHF_EXECINSTR": "debug/elf",
+ "elf.SHF_GROUP": "debug/elf",
+ "elf.SHF_INFO_LINK": "debug/elf",
+ "elf.SHF_LINK_ORDER": "debug/elf",
+ "elf.SHF_MASKOS": "debug/elf",
+ "elf.SHF_MASKPROC": "debug/elf",
+ "elf.SHF_MERGE": "debug/elf",
+ "elf.SHF_OS_NONCONFORMING": "debug/elf",
+ "elf.SHF_STRINGS": "debug/elf",
+ "elf.SHF_TLS": "debug/elf",
+ "elf.SHF_WRITE": "debug/elf",
+ "elf.SHN_ABS": "debug/elf",
+ "elf.SHN_COMMON": "debug/elf",
+ "elf.SHN_HIOS": "debug/elf",
+ "elf.SHN_HIPROC": "debug/elf",
+ "elf.SHN_HIRESERVE": "debug/elf",
+ "elf.SHN_LOOS": "debug/elf",
+ "elf.SHN_LOPROC": "debug/elf",
+ "elf.SHN_LORESERVE": "debug/elf",
+ "elf.SHN_UNDEF": "debug/elf",
+ "elf.SHN_XINDEX": "debug/elf",
+ "elf.SHT_DYNAMIC": "debug/elf",
+ "elf.SHT_DYNSYM": "debug/elf",
+ "elf.SHT_FINI_ARRAY": "debug/elf",
+ "elf.SHT_GNU_ATTRIBUTES": "debug/elf",
+ "elf.SHT_GNU_HASH": "debug/elf",
+ "elf.SHT_GNU_LIBLIST": "debug/elf",
+ "elf.SHT_GNU_VERDEF": "debug/elf",
+ "elf.SHT_GNU_VERNEED": "debug/elf",
+ "elf.SHT_GNU_VERSYM": "debug/elf",
+ "elf.SHT_GROUP": "debug/elf",
+ "elf.SHT_HASH": "debug/elf",
+ "elf.SHT_HIOS": "debug/elf",
+ "elf.SHT_HIPROC": "debug/elf",
+ "elf.SHT_HIUSER": "debug/elf",
+ "elf.SHT_INIT_ARRAY": "debug/elf",
+ "elf.SHT_LOOS": "debug/elf",
+ "elf.SHT_LOPROC": "debug/elf",
+ "elf.SHT_LOUSER": "debug/elf",
+ "elf.SHT_NOBITS": "debug/elf",
+ "elf.SHT_NOTE": "debug/elf",
+ "elf.SHT_NULL": "debug/elf",
+ "elf.SHT_PREINIT_ARRAY": "debug/elf",
+ "elf.SHT_PROGBITS": "debug/elf",
+ "elf.SHT_REL": "debug/elf",
+ "elf.SHT_RELA": "debug/elf",
+ "elf.SHT_SHLIB": "debug/elf",
+ "elf.SHT_STRTAB": "debug/elf",
+ "elf.SHT_SYMTAB": "debug/elf",
+ "elf.SHT_SYMTAB_SHNDX": "debug/elf",
+ "elf.STB_GLOBAL": "debug/elf",
+ "elf.STB_HIOS": "debug/elf",
+ "elf.STB_HIPROC": "debug/elf",
+ "elf.STB_LOCAL": "debug/elf",
+ "elf.STB_LOOS": "debug/elf",
+ "elf.STB_LOPROC": "debug/elf",
+ "elf.STB_WEAK": "debug/elf",
+ "elf.STT_COMMON": "debug/elf",
+ "elf.STT_FILE": "debug/elf",
+ "elf.STT_FUNC": "debug/elf",
+ "elf.STT_HIOS": "debug/elf",
+ "elf.STT_HIPROC": "debug/elf",
+ "elf.STT_LOOS": "debug/elf",
+ "elf.STT_LOPROC": "debug/elf",
+ "elf.STT_NOTYPE": "debug/elf",
+ "elf.STT_OBJECT": "debug/elf",
+ "elf.STT_SECTION": "debug/elf",
+ "elf.STT_TLS": "debug/elf",
+ "elf.STV_DEFAULT": "debug/elf",
+ "elf.STV_HIDDEN": "debug/elf",
+ "elf.STV_INTERNAL": "debug/elf",
+ "elf.STV_PROTECTED": "debug/elf",
+ "elf.ST_BIND": "debug/elf",
+ "elf.ST_INFO": "debug/elf",
+ "elf.ST_TYPE": "debug/elf",
+ "elf.ST_VISIBILITY": "debug/elf",
+ "elf.Section": "debug/elf",
+ "elf.Section32": "debug/elf",
+ "elf.Section64": "debug/elf",
+ "elf.SectionFlag": "debug/elf",
+ "elf.SectionHeader": "debug/elf",
+ "elf.SectionIndex": "debug/elf",
+ "elf.SectionType": "debug/elf",
+ "elf.Sym32": "debug/elf",
+ "elf.Sym32Size": "debug/elf",
+ "elf.Sym64": "debug/elf",
+ "elf.Sym64Size": "debug/elf",
+ "elf.SymBind": "debug/elf",
+ "elf.SymType": "debug/elf",
+ "elf.SymVis": "debug/elf",
+ "elf.Symbol": "debug/elf",
+ "elf.Type": "debug/elf",
+ "elf.Version": "debug/elf",
+ "elliptic.Curve": "crypto/elliptic",
+ "elliptic.CurveParams": "crypto/elliptic",
+ "elliptic.GenerateKey": "crypto/elliptic",
+ "elliptic.Marshal": "crypto/elliptic",
+ "elliptic.P224": "crypto/elliptic",
+ "elliptic.P256": "crypto/elliptic",
+ "elliptic.P384": "crypto/elliptic",
+ "elliptic.P521": "crypto/elliptic",
+ "elliptic.Unmarshal": "crypto/elliptic",
+ "encoding.BinaryMarshaler": "encoding",
+ "encoding.BinaryUnmarshaler": "encoding",
+ "encoding.TextMarshaler": "encoding",
+ "encoding.TextUnmarshaler": "encoding",
+ "errors.New": "errors",
+ "exec.Cmd": "os/exec",
+ "exec.Command": "os/exec",
+ "exec.ErrNotFound": "os/exec",
+ "exec.Error": "os/exec",
+ "exec.ExitError": "os/exec",
+ "exec.LookPath": "os/exec",
+ "expvar.Do": "expvar",
+ "expvar.Float": "expvar",
+ "expvar.Func": "expvar",
+ "expvar.Get": "expvar",
+ "expvar.Int": "expvar",
+ "expvar.KeyValue": "expvar",
+ "expvar.Map": "expvar",
+ "expvar.NewFloat": "expvar",
+ "expvar.NewInt": "expvar",
+ "expvar.NewMap": "expvar",
+ "expvar.NewString": "expvar",
+ "expvar.Publish": "expvar",
+ "expvar.String": "expvar",
+ "expvar.Var": "expvar",
+ "fcgi.Serve": "net/http/fcgi",
+ "filepath.Abs": "path/filepath",
+ "filepath.Base": "path/filepath",
+ "filepath.Clean": "path/filepath",
+ "filepath.Dir": "path/filepath",
+ "filepath.ErrBadPattern": "path/filepath",
+ "filepath.EvalSymlinks": "path/filepath",
+ "filepath.Ext": "path/filepath",
+ "filepath.FromSlash": "path/filepath",
+ "filepath.Glob": "path/filepath",
+ "filepath.HasPrefix": "path/filepath",
+ "filepath.IsAbs": "path/filepath",
+ "filepath.Join": "path/filepath",
+ "filepath.ListSeparator": "path/filepath",
+ "filepath.Match": "path/filepath",
+ "filepath.Rel": "path/filepath",
+ "filepath.Separator": "path/filepath",
+ "filepath.SkipDir": "path/filepath",
+ "filepath.Split": "path/filepath",
+ "filepath.SplitList": "path/filepath",
+ "filepath.ToSlash": "path/filepath",
+ "filepath.VolumeName": "path/filepath",
+ "filepath.Walk": "path/filepath",
+ "filepath.WalkFunc": "path/filepath",
+ "flag.Arg": "flag",
+ "flag.Args": "flag",
+ "flag.Bool": "flag",
+ "flag.BoolVar": "flag",
+ "flag.CommandLine": "flag",
+ "flag.ContinueOnError": "flag",
+ "flag.Duration": "flag",
+ "flag.DurationVar": "flag",
+ "flag.ErrHelp": "flag",
+ "flag.ErrorHandling": "flag",
+ "flag.ExitOnError": "flag",
+ "flag.Flag": "flag",
+ "flag.FlagSet": "flag",
+ "flag.Float64": "flag",
+ "flag.Float64Var": "flag",
+ "flag.Getter": "flag",
+ "flag.Int": "flag",
+ "flag.Int64": "flag",
+ "flag.Int64Var": "flag",
+ "flag.IntVar": "flag",
+ "flag.Lookup": "flag",
+ "flag.NArg": "flag",
+ "flag.NFlag": "flag",
+ "flag.NewFlagSet": "flag",
+ "flag.PanicOnError": "flag",
+ "flag.Parse": "flag",
+ "flag.Parsed": "flag",
+ "flag.PrintDefaults": "flag",
+ "flag.Set": "flag",
+ "flag.String": "flag",
+ "flag.StringVar": "flag",
+ "flag.Uint": "flag",
+ "flag.Uint64": "flag",
+ "flag.Uint64Var": "flag",
+ "flag.UintVar": "flag",
+ "flag.Usage": "flag",
+ "flag.Value": "flag",
+ "flag.Var": "flag",
+ "flag.Visit": "flag",
+ "flag.VisitAll": "flag",
+ "flate.BestCompression": "compress/flate",
+ "flate.BestSpeed": "compress/flate",
+ "flate.CorruptInputError": "compress/flate",
+ "flate.DefaultCompression": "compress/flate",
+ "flate.InternalError": "compress/flate",
+ "flate.NewReader": "compress/flate",
+ "flate.NewReaderDict": "compress/flate",
+ "flate.NewWriter": "compress/flate",
+ "flate.NewWriterDict": "compress/flate",
+ "flate.NoCompression": "compress/flate",
+ "flate.ReadError": "compress/flate",
+ "flate.Reader": "compress/flate",
+ "flate.WriteError": "compress/flate",
+ "flate.Writer": "compress/flate",
+ "fmt.Errorf": "fmt",
+ "fmt.Formatter": "fmt",
+ "fmt.Fprint": "fmt",
+ "fmt.Fprintf": "fmt",
+ "fmt.Fprintln": "fmt",
+ "fmt.Fscan": "fmt",
+ "fmt.Fscanf": "fmt",
+ "fmt.Fscanln": "fmt",
+ "fmt.GoStringer": "fmt",
+ "fmt.Print": "fmt",
+ "fmt.Printf": "fmt",
+ "fmt.Println": "fmt",
+ "fmt.Scan": "fmt",
+ "fmt.ScanState": "fmt",
+ "fmt.Scanf": "fmt",
+ "fmt.Scanln": "fmt",
+ "fmt.Scanner": "fmt",
+ "fmt.Sprint": "fmt",
+ "fmt.Sprintf": "fmt",
+ "fmt.Sprintln": "fmt",
+ "fmt.Sscan": "fmt",
+ "fmt.Sscanf": "fmt",
+ "fmt.Sscanln": "fmt",
+ "fmt.State": "fmt",
+ "fmt.Stringer": "fmt",
+ "fnv.New32": "hash/fnv",
+ "fnv.New32a": "hash/fnv",
+ "fnv.New64": "hash/fnv",
+ "fnv.New64a": "hash/fnv",
+ "format.Node": "go/format",
+ "format.Source": "go/format",
+ "gif.Decode": "image/gif",
+ "gif.DecodeAll": "image/gif",
+ "gif.DecodeConfig": "image/gif",
+ "gif.Encode": "image/gif",
+ "gif.EncodeAll": "image/gif",
+ "gif.GIF": "image/gif",
+ "gif.Options": "image/gif",
+ "gob.CommonType": "encoding/gob",
+ "gob.Decoder": "encoding/gob",
+ "gob.Encoder": "encoding/gob",
+ "gob.GobDecoder": "encoding/gob",
+ "gob.GobEncoder": "encoding/gob",
+ "gob.NewDecoder": "encoding/gob",
+ "gob.NewEncoder": "encoding/gob",
+ "gob.Register": "encoding/gob",
+ "gob.RegisterName": "encoding/gob",
+ "gosym.DecodingError": "debug/gosym",
+ "gosym.Func": "debug/gosym",
+ "gosym.LineTable": "debug/gosym",
+ "gosym.NewLineTable": "debug/gosym",
+ "gosym.NewTable": "debug/gosym",
+ "gosym.Obj": "debug/gosym",
+ "gosym.Sym": "debug/gosym",
+ "gosym.Table": "debug/gosym",
+ "gosym.UnknownFileError": "debug/gosym",
+ "gosym.UnknownLineError": "debug/gosym",
+ "gzip.BestCompression": "compress/gzip",
+ "gzip.BestSpeed": "compress/gzip",
+ "gzip.DefaultCompression": "compress/gzip",
+ "gzip.ErrChecksum": "compress/gzip",
+ "gzip.ErrHeader": "compress/gzip",
+ "gzip.Header": "compress/gzip",
+ "gzip.NewReader": "compress/gzip",
+ "gzip.NewWriter": "compress/gzip",
+ "gzip.NewWriterLevel": "compress/gzip",
+ "gzip.NoCompression": "compress/gzip",
+ "gzip.Reader": "compress/gzip",
+ "gzip.Writer": "compress/gzip",
+ "hash.Hash": "hash",
+ "hash.Hash32": "hash",
+ "hash.Hash64": "hash",
+ "heap.Fix": "container/heap",
+ "heap.Init": "container/heap",
+ "heap.Interface": "container/heap",
+ "heap.Pop": "container/heap",
+ "heap.Push": "container/heap",
+ "heap.Remove": "container/heap",
+ "hex.Decode": "encoding/hex",
+ "hex.DecodeString": "encoding/hex",
+ "hex.DecodedLen": "encoding/hex",
+ "hex.Dump": "encoding/hex",
+ "hex.Dumper": "encoding/hex",
+ "hex.Encode": "encoding/hex",
+ "hex.EncodeToString": "encoding/hex",
+ "hex.EncodedLen": "encoding/hex",
+ "hex.ErrLength": "encoding/hex",
+ "hex.InvalidByteError": "encoding/hex",
+ "hmac.Equal": "crypto/hmac",
+ "hmac.New": "crypto/hmac",
+ "html.EscapeString": "html",
+ "html.UnescapeString": "html",
+ "http.CanonicalHeaderKey": "net/http",
+ "http.Client": "net/http",
+ "http.CloseNotifier": "net/http",
+ "http.ConnState": "net/http",
+ "http.Cookie": "net/http",
+ "http.CookieJar": "net/http",
+ "http.DefaultClient": "net/http",
+ "http.DefaultMaxHeaderBytes": "net/http",
+ "http.DefaultMaxIdleConnsPerHost": "net/http",
+ "http.DefaultServeMux": "net/http",
+ "http.DefaultTransport": "net/http",
+ "http.DetectContentType": "net/http",
+ "http.Dir": "net/http",
+ "http.ErrBodyNotAllowed": "net/http",
+ "http.ErrBodyReadAfterClose": "net/http",
+ "http.ErrContentLength": "net/http",
+ "http.ErrHandlerTimeout": "net/http",
+ "http.ErrHeaderTooLong": "net/http",
+ "http.ErrHijacked": "net/http",
+ "http.ErrLineTooLong": "net/http",
+ "http.ErrMissingBoundary": "net/http",
+ "http.ErrMissingContentLength": "net/http",
+ "http.ErrMissingFile": "net/http",
+ "http.ErrNoCookie": "net/http",
+ "http.ErrNoLocation": "net/http",
+ "http.ErrNotMultipart": "net/http",
+ "http.ErrNotSupported": "net/http",
+ "http.ErrShortBody": "net/http",
+ "http.ErrUnexpectedTrailer": "net/http",
+ "http.ErrWriteAfterFlush": "net/http",
+ "http.Error": "net/http",
+ "http.File": "net/http",
+ "http.FileServer": "net/http",
+ "http.FileSystem": "net/http",
+ "http.Flusher": "net/http",
+ "http.Get": "net/http",
+ "http.Handle": "net/http",
+ "http.HandleFunc": "net/http",
+ "http.Handler": "net/http",
+ "http.HandlerFunc": "net/http",
+ "http.Head": "net/http",
+ "http.Header": "net/http",
+ "http.Hijacker": "net/http",
+ "http.ListenAndServe": "net/http",
+ "http.ListenAndServeTLS": "net/http",
+ "http.MaxBytesReader": "net/http",
+ "http.NewFileTransport": "net/http",
+ "http.NewRequest": "net/http",
+ "http.NewServeMux": "net/http",
+ "http.NotFound": "net/http",
+ "http.NotFoundHandler": "net/http",
+ "http.ParseHTTPVersion": "net/http",
+ "http.ParseTime": "net/http",
+ "http.Post": "net/http",
+ "http.PostForm": "net/http",
+ "http.ProtocolError": "net/http",
+ "http.ProxyFromEnvironment": "net/http",
+ "http.ProxyURL": "net/http",
+ "http.ReadRequest": "net/http",
+ "http.ReadResponse": "net/http",
+ "http.Redirect": "net/http",
+ "http.RedirectHandler": "net/http",
+ "http.Request": "net/http",
+ "http.Response": "net/http",
+ "http.ResponseWriter": "net/http",
+ "http.RoundTripper": "net/http",
+ "http.Serve": "net/http",
+ "http.ServeContent": "net/http",
+ "http.ServeFile": "net/http",
+ "http.ServeMux": "net/http",
+ "http.Server": "net/http",
+ "http.SetCookie": "net/http",
+ "http.StateActive": "net/http",
+ "http.StateClosed": "net/http",
+ "http.StateHijacked": "net/http",
+ "http.StateIdle": "net/http",
+ "http.StateNew": "net/http",
+ "http.StatusAccepted": "net/http",
+ "http.StatusBadGateway": "net/http",
+ "http.StatusBadRequest": "net/http",
+ "http.StatusConflict": "net/http",
+ "http.StatusContinue": "net/http",
+ "http.StatusCreated": "net/http",
+ "http.StatusExpectationFailed": "net/http",
+ "http.StatusForbidden": "net/http",
+ "http.StatusFound": "net/http",
+ "http.StatusGatewayTimeout": "net/http",
+ "http.StatusGone": "net/http",
+ "http.StatusHTTPVersionNotSupported": "net/http",
+ "http.StatusInternalServerError": "net/http",
+ "http.StatusLengthRequired": "net/http",
+ "http.StatusMethodNotAllowed": "net/http",
+ "http.StatusMovedPermanently": "net/http",
+ "http.StatusMultipleChoices": "net/http",
+ "http.StatusNoContent": "net/http",
+ "http.StatusNonAuthoritativeInfo": "net/http",
+ "http.StatusNotAcceptable": "net/http",
+ "http.StatusNotFound": "net/http",
+ "http.StatusNotImplemented": "net/http",
+ "http.StatusNotModified": "net/http",
+ "http.StatusOK": "net/http",
+ "http.StatusPartialContent": "net/http",
+ "http.StatusPaymentRequired": "net/http",
+ "http.StatusPreconditionFailed": "net/http",
+ "http.StatusProxyAuthRequired": "net/http",
+ "http.StatusRequestEntityTooLarge": "net/http",
+ "http.StatusRequestTimeout": "net/http",
+ "http.StatusRequestURITooLong": "net/http",
+ "http.StatusRequestedRangeNotSatisfiable": "net/http",
+ "http.StatusResetContent": "net/http",
+ "http.StatusSeeOther": "net/http",
+ "http.StatusServiceUnavailable": "net/http",
+ "http.StatusSwitchingProtocols": "net/http",
+ "http.StatusTeapot": "net/http",
+ "http.StatusTemporaryRedirect": "net/http",
+ "http.StatusText": "net/http",
+ "http.StatusUnauthorized": "net/http",
+ "http.StatusUnsupportedMediaType": "net/http",
+ "http.StatusUseProxy": "net/http",
+ "http.StripPrefix": "net/http",
+ "http.TimeFormat": "net/http",
+ "http.TimeoutHandler": "net/http",
+ "http.Transport": "net/http",
+ "httptest.DefaultRemoteAddr": "net/http/httptest",
+ "httptest.NewRecorder": "net/http/httptest",
+ "httptest.NewServer": "net/http/httptest",
+ "httptest.NewTLSServer": "net/http/httptest",
+ "httptest.NewUnstartedServer": "net/http/httptest",
+ "httptest.ResponseRecorder": "net/http/httptest",
+ "httptest.Server": "net/http/httptest",
+ "httputil.ClientConn": "net/http/httputil",
+ "httputil.DumpRequest": "net/http/httputil",
+ "httputil.DumpRequestOut": "net/http/httputil",
+ "httputil.DumpResponse": "net/http/httputil",
+ "httputil.ErrClosed": "net/http/httputil",
+ "httputil.ErrLineTooLong": "net/http/httputil",
+ "httputil.ErrPersistEOF": "net/http/httputil",
+ "httputil.ErrPipeline": "net/http/httputil",
+ "httputil.NewChunkedReader": "net/http/httputil",
+ "httputil.NewChunkedWriter": "net/http/httputil",
+ "httputil.NewClientConn": "net/http/httputil",
+ "httputil.NewProxyClientConn": "net/http/httputil",
+ "httputil.NewServerConn": "net/http/httputil",
+ "httputil.NewSingleHostReverseProxy": "net/http/httputil",
+ "httputil.ReverseProxy": "net/http/httputil",
+ "httputil.ServerConn": "net/http/httputil",
+ "image.Alpha": "image",
+ "image.Alpha16": "image",
+ "image.Black": "image",
+ "image.Config": "image",
+ "image.Decode": "image",
+ "image.DecodeConfig": "image",
+ "image.ErrFormat": "image",
+ "image.Gray": "image",
+ "image.Gray16": "image",
+ "image.Image": "image",
+ "image.NRGBA": "image",
+ "image.NRGBA64": "image",
+ "image.NewAlpha": "image",
+ "image.NewAlpha16": "image",
+ "image.NewGray": "image",
+ "image.NewGray16": "image",
+ "image.NewNRGBA": "image",
+ "image.NewNRGBA64": "image",
+ "image.NewPaletted": "image",
+ "image.NewRGBA": "image",
+ "image.NewRGBA64": "image",
+ "image.NewUniform": "image",
+ "image.NewYCbCr": "image",
+ "image.Opaque": "image",
+ "image.Paletted": "image",
+ "image.PalettedImage": "image",
+ "image.Point": "image",
+ "image.Pt": "image",
+ "image.RGBA": "image",
+ "image.RGBA64": "image",
+ "image.Rect": "image",
+ "image.Rectangle": "image",
+ "image.RegisterFormat": "image",
+ "image.Transparent": "image",
+ "image.Uniform": "image",
+ "image.White": "image",
+ "image.YCbCr": "image",
+ "image.YCbCrSubsampleRatio": "image",
+ "image.YCbCrSubsampleRatio420": "image",
+ "image.YCbCrSubsampleRatio422": "image",
+ "image.YCbCrSubsampleRatio440": "image",
+ "image.YCbCrSubsampleRatio444": "image",
+ "image.ZP": "image",
+ "image.ZR": "image",
+ "io.ByteReader": "io",
+ "io.ByteScanner": "io",
+ "io.ByteWriter": "io",
+ "io.Closer": "io",
+ "io.Copy": "io",
+ "io.CopyN": "io",
+ "io.EOF": "io",
+ "io.ErrClosedPipe": "io",
+ "io.ErrNoProgress": "io",
+ "io.ErrShortBuffer": "io",
+ "io.ErrShortWrite": "io",
+ "io.ErrUnexpectedEOF": "io",
+ "io.LimitReader": "io",
+ "io.LimitedReader": "io",
+ "io.MultiReader": "io",
+ "io.MultiWriter": "io",
+ "io.NewSectionReader": "io",
+ "io.Pipe": "io",
+ "io.PipeReader": "io",
+ "io.PipeWriter": "io",
+ "io.ReadAtLeast": "io",
+ "io.ReadCloser": "io",
+ "io.ReadFull": "io",
+ "io.ReadSeeker": "io",
+ "io.ReadWriteCloser": "io",
+ "io.ReadWriteSeeker": "io",
+ "io.ReadWriter": "io",
+ "io.Reader": "io",
+ "io.ReaderAt": "io",
+ "io.ReaderFrom": "io",
+ "io.RuneReader": "io",
+ "io.RuneScanner": "io",
+ "io.SectionReader": "io",
+ "io.Seeker": "io",
+ "io.TeeReader": "io",
+ "io.WriteCloser": "io",
+ "io.WriteSeeker": "io",
+ "io.WriteString": "io",
+ "io.Writer": "io",
+ "io.WriterAt": "io",
+ "io.WriterTo": "io",
+ "iotest.DataErrReader": "testing/iotest",
+ "iotest.ErrTimeout": "testing/iotest",
+ "iotest.HalfReader": "testing/iotest",
+ "iotest.NewReadLogger": "testing/iotest",
+ "iotest.NewWriteLogger": "testing/iotest",
+ "iotest.OneByteReader": "testing/iotest",
+ "iotest.TimeoutReader": "testing/iotest",
+ "iotest.TruncateWriter": "testing/iotest",
+ "ioutil.Discard": "io/ioutil",
+ "ioutil.NopCloser": "io/ioutil",
+ "ioutil.ReadAll": "io/ioutil",
+ "ioutil.ReadDir": "io/ioutil",
+ "ioutil.ReadFile": "io/ioutil",
+ "ioutil.TempDir": "io/ioutil",
+ "ioutil.TempFile": "io/ioutil",
+ "ioutil.WriteFile": "io/ioutil",
+ "jpeg.Decode": "image/jpeg",
+ "jpeg.DecodeConfig": "image/jpeg",
+ "jpeg.DefaultQuality": "image/jpeg",
+ "jpeg.Encode": "image/jpeg",
+ "jpeg.FormatError": "image/jpeg",
+ "jpeg.Options": "image/jpeg",
+ "jpeg.Reader": "image/jpeg",
+ "jpeg.UnsupportedError": "image/jpeg",
+ "json.Compact": "encoding/json",
+ "json.Decoder": "encoding/json",
+ "json.Encoder": "encoding/json",
+ "json.HTMLEscape": "encoding/json",
+ "json.Indent": "encoding/json",
+ "json.InvalidUTF8Error": "encoding/json",
+ "json.InvalidUnmarshalError": "encoding/json",
+ "json.Marshal": "encoding/json",
+ "json.MarshalIndent": "encoding/json",
+ "json.Marshaler": "encoding/json",
+ "json.MarshalerError": "encoding/json",
+ "json.NewDecoder": "encoding/json",
+ "json.NewEncoder": "encoding/json",
+ "json.Number": "encoding/json",
+ "json.RawMessage": "encoding/json",
+ "json.SyntaxError": "encoding/json",
+ "json.Unmarshal": "encoding/json",
+ "json.UnmarshalFieldError": "encoding/json",
+ "json.UnmarshalTypeError": "encoding/json",
+ "json.Unmarshaler": "encoding/json",
+ "json.UnsupportedTypeError": "encoding/json",
+ "json.UnsupportedValueError": "encoding/json",
+ "jsonrpc.Dial": "net/rpc/jsonrpc",
+ "jsonrpc.NewClient": "net/rpc/jsonrpc",
+ "jsonrpc.NewClientCodec": "net/rpc/jsonrpc",
+ "jsonrpc.NewServerCodec": "net/rpc/jsonrpc",
+ "jsonrpc.ServeConn": "net/rpc/jsonrpc",
+ "list.Element": "container/list",
+ "list.List": "container/list",
+ "list.New": "container/list",
+ "log.Fatal": "log",
+ "log.Fatalf": "log",
+ "log.Fatalln": "log",
+ "log.Flags": "log",
+ "log.Ldate": "log",
+ "log.Llongfile": "log",
+ "log.Lmicroseconds": "log",
+ "log.Logger": "log",
+ "log.Lshortfile": "log",
+ "log.LstdFlags": "log",
+ "log.Ltime": "log",
+ "log.New": "log",
+ "log.Panic": "log",
+ "log.Panicf": "log",
+ "log.Panicln": "log",
+ "log.Prefix": "log",
+ "log.Print": "log",
+ "log.Printf": "log",
+ "log.Println": "log",
+ "log.SetFlags": "log",
+ "log.SetOutput": "log",
+ "log.SetPrefix": "log",
+ "lzw.LSB": "compress/lzw",
+ "lzw.MSB": "compress/lzw",
+ "lzw.NewReader": "compress/lzw",
+ "lzw.NewWriter": "compress/lzw",
+ "lzw.Order": "compress/lzw",
+ "macho.Cpu": "debug/macho",
+ "macho.Cpu386": "debug/macho",
+ "macho.CpuAmd64": "debug/macho",
+ "macho.CpuArm": "debug/macho",
+ "macho.CpuPpc": "debug/macho",
+ "macho.CpuPpc64": "debug/macho",
+ "macho.Dylib": "debug/macho",
+ "macho.DylibCmd": "debug/macho",
+ "macho.Dysymtab": "debug/macho",
+ "macho.DysymtabCmd": "debug/macho",
+ "macho.ErrNotFat": "debug/macho",
+ "macho.FatArch": "debug/macho",
+ "macho.FatArchHeader": "debug/macho",
+ "macho.FatFile": "debug/macho",
+ "macho.File": "debug/macho",
+ "macho.FileHeader": "debug/macho",
+ "macho.FormatError": "debug/macho",
+ "macho.Load": "debug/macho",
+ "macho.LoadBytes": "debug/macho",
+ "macho.LoadCmd": "debug/macho",
+ "macho.LoadCmdDylib": "debug/macho",
+ "macho.LoadCmdDylinker": "debug/macho",
+ "macho.LoadCmdDysymtab": "debug/macho",
+ "macho.LoadCmdSegment": "debug/macho",
+ "macho.LoadCmdSegment64": "debug/macho",
+ "macho.LoadCmdSymtab": "debug/macho",
+ "macho.LoadCmdThread": "debug/macho",
+ "macho.LoadCmdUnixThread": "debug/macho",
+ "macho.Magic32": "debug/macho",
+ "macho.Magic64": "debug/macho",
+ "macho.MagicFat": "debug/macho",
+ "macho.NewFatFile": "debug/macho",
+ "macho.NewFile": "debug/macho",
+ "macho.Nlist32": "debug/macho",
+ "macho.Nlist64": "debug/macho",
+ "macho.Open": "debug/macho",
+ "macho.OpenFat": "debug/macho",
+ "macho.Regs386": "debug/macho",
+ "macho.RegsAMD64": "debug/macho",
+ "macho.Section": "debug/macho",
+ "macho.Section32": "debug/macho",
+ "macho.Section64": "debug/macho",
+ "macho.SectionHeader": "debug/macho",
+ "macho.Segment": "debug/macho",
+ "macho.Segment32": "debug/macho",
+ "macho.Segment64": "debug/macho",
+ "macho.SegmentHeader": "debug/macho",
+ "macho.Symbol": "debug/macho",
+ "macho.Symtab": "debug/macho",
+ "macho.SymtabCmd": "debug/macho",
+ "macho.Thread": "debug/macho",
+ "macho.Type": "debug/macho",
+ "macho.TypeBundle": "debug/macho",
+ "macho.TypeDylib": "debug/macho",
+ "macho.TypeExec": "debug/macho",
+ "macho.TypeObj": "debug/macho",
+ "mail.Address": "net/mail",
+ "mail.ErrHeaderNotPresent": "net/mail",
+ "mail.Header": "net/mail",
+ "mail.Message": "net/mail",
+ "mail.ParseAddress": "net/mail",
+ "mail.ParseAddressList": "net/mail",
+ "mail.ReadMessage": "net/mail",
+ "math.Abs": "math",
+ "math.Acos": "math",
+ "math.Acosh": "math",
+ "math.Asin": "math",
+ "math.Asinh": "math",
+ "math.Atan": "math",
+ "math.Atan2": "math",
+ "math.Atanh": "math",
+ "math.Cbrt": "math",
+ "math.Ceil": "math",
+ "math.Copysign": "math",
+ "math.Cos": "math",
+ "math.Cosh": "math",
+ "math.Dim": "math",
+ "math.E": "math",
+ "math.Erf": "math",
+ "math.Erfc": "math",
+ "math.Exp": "math",
+ "math.Exp2": "math",
+ "math.Expm1": "math",
+ "math.Float32bits": "math",
+ "math.Float32frombits": "math",
+ "math.Float64bits": "math",
+ "math.Float64frombits": "math",
+ "math.Floor": "math",
+ "math.Frexp": "math",
+ "math.Gamma": "math",
+ "math.Hypot": "math",
+ "math.Ilogb": "math",
+ "math.Inf": "math",
+ "math.IsInf": "math",
+ "math.IsNaN": "math",
+ "math.J0": "math",
+ "math.J1": "math",
+ "math.Jn": "math",
+ "math.Ldexp": "math",
+ "math.Lgamma": "math",
+ "math.Ln10": "math",
+ "math.Ln2": "math",
+ "math.Log": "math",
+ "math.Log10": "math",
+ "math.Log10E": "math",
+ "math.Log1p": "math",
+ "math.Log2": "math",
+ "math.Log2E": "math",
+ "math.Logb": "math",
+ "math.Max": "math",
+ "math.MaxFloat32": "math",
+ "math.MaxFloat64": "math",
+ "math.MaxInt16": "math",
+ "math.MaxInt32": "math",
+ "math.MaxInt64": "math",
+ "math.MaxInt8": "math",
+ "math.MaxUint16": "math",
+ "math.MaxUint32": "math",
+ "math.MaxUint64": "math",
+ "math.MaxUint8": "math",
+ "math.Min": "math",
+ "math.MinInt16": "math",
+ "math.MinInt32": "math",
+ "math.MinInt64": "math",
+ "math.MinInt8": "math",
+ "math.Mod": "math",
+ "math.Modf": "math",
+ "math.NaN": "math",
+ "math.Nextafter": "math",
+ "math.Phi": "math",
+ "math.Pi": "math",
+ "math.Pow": "math",
+ "math.Pow10": "math",
+ "math.Remainder": "math",
+ "math.Signbit": "math",
+ "math.Sin": "math",
+ "math.Sincos": "math",
+ "math.Sinh": "math",
+ "math.SmallestNonzeroFloat32": "math",
+ "math.SmallestNonzeroFloat64": "math",
+ "math.Sqrt": "math",
+ "math.Sqrt2": "math",
+ "math.SqrtE": "math",
+ "math.SqrtPhi": "math",
+ "math.SqrtPi": "math",
+ "math.Tan": "math",
+ "math.Tanh": "math",
+ "math.Trunc": "math",
+ "math.Y0": "math",
+ "math.Y1": "math",
+ "math.Yn": "math",
+ "md5.BlockSize": "crypto/md5",
+ "md5.New": "crypto/md5",
+ "md5.Size": "crypto/md5",
+ "md5.Sum": "crypto/md5",
+ "mime.AddExtensionType": "mime",
+ "mime.FormatMediaType": "mime",
+ "mime.ParseMediaType": "mime",
+ "mime.TypeByExtension": "mime",
+ "multipart.File": "mime/multipart",
+ "multipart.FileHeader": "mime/multipart",
+ "multipart.Form": "mime/multipart",
+ "multipart.NewReader": "mime/multipart",
+ "multipart.NewWriter": "mime/multipart",
+ "multipart.Part": "mime/multipart",
+ "multipart.Reader": "mime/multipart",
+ "multipart.Writer": "mime/multipart",
+ "net.Addr": "net",
+ "net.AddrError": "net",
+ "net.CIDRMask": "net",
+ "net.Conn": "net",
+ "net.DNSConfigError": "net",
+ "net.DNSError": "net",
+ "net.Dial": "net",
+ "net.DialIP": "net",
+ "net.DialTCP": "net",
+ "net.DialTimeout": "net",
+ "net.DialUDP": "net",
+ "net.DialUnix": "net",
+ "net.Dialer": "net",
+ "net.ErrWriteToConnected": "net",
+ "net.Error": "net",
+ "net.FileConn": "net",
+ "net.FileListener": "net",
+ "net.FilePacketConn": "net",
+ "net.FlagBroadcast": "net",
+ "net.FlagLoopback": "net",
+ "net.FlagMulticast": "net",
+ "net.FlagPointToPoint": "net",
+ "net.FlagUp": "net",
+ "net.Flags": "net",
+ "net.HardwareAddr": "net",
+ "net.IP": "net",
+ "net.IPAddr": "net",
+ "net.IPConn": "net",
+ "net.IPMask": "net",
+ "net.IPNet": "net",
+ "net.IPv4": "net",
+ "net.IPv4Mask": "net",
+ "net.IPv4allrouter": "net",
+ "net.IPv4allsys": "net",
+ "net.IPv4bcast": "net",
+ "net.IPv4len": "net",
+ "net.IPv4zero": "net",
+ "net.IPv6interfacelocalallnodes": "net",
+ "net.IPv6len": "net",
+ "net.IPv6linklocalallnodes": "net",
+ "net.IPv6linklocalallrouters": "net",
+ "net.IPv6loopback": "net",
+ "net.IPv6unspecified": "net",
+ "net.IPv6zero": "net",
+ "net.Interface": "net",
+ "net.InterfaceAddrs": "net",
+ "net.InterfaceByIndex": "net",
+ "net.InterfaceByName": "net",
+ "net.Interfaces": "net",
+ "net.InvalidAddrError": "net",
+ "net.JoinHostPort": "net",
+ "net.Listen": "net",
+ "net.ListenIP": "net",
+ "net.ListenMulticastUDP": "net",
+ "net.ListenPacket": "net",
+ "net.ListenTCP": "net",
+ "net.ListenUDP": "net",
+ "net.ListenUnix": "net",
+ "net.ListenUnixgram": "net",
+ "net.Listener": "net",
+ "net.LookupAddr": "net",
+ "net.LookupCNAME": "net",
+ "net.LookupHost": "net",
+ "net.LookupIP": "net",
+ "net.LookupMX": "net",
+ "net.LookupNS": "net",
+ "net.LookupPort": "net",
+ "net.LookupSRV": "net",
+ "net.LookupTXT": "net",
+ "net.MX": "net",
+ "net.NS": "net",
+ "net.OpError": "net",
+ "net.PacketConn": "net",
+ "net.ParseCIDR": "net",
+ "net.ParseError": "net",
+ "net.ParseIP": "net",
+ "net.ParseMAC": "net",
+ "net.Pipe": "net",
+ "net.ResolveIPAddr": "net",
+ "net.ResolveTCPAddr": "net",
+ "net.ResolveUDPAddr": "net",
+ "net.ResolveUnixAddr": "net",
+ "net.SRV": "net",
+ "net.SplitHostPort": "net",
+ "net.TCPAddr": "net",
+ "net.TCPConn": "net",
+ "net.TCPListener": "net",
+ "net.UDPAddr": "net",
+ "net.UDPConn": "net",
+ "net.UnixAddr": "net",
+ "net.UnixConn": "net",
+ "net.UnixListener": "net",
+ "net.UnknownNetworkError": "net",
+ "os.Args": "os",
+ "os.Chdir": "os",
+ "os.Chmod": "os",
+ "os.Chown": "os",
+ "os.Chtimes": "os",
+ "os.Clearenv": "os",
+ "os.Create": "os",
+ "os.DevNull": "os",
+ "os.Environ": "os",
+ "os.ErrExist": "os",
+ "os.ErrInvalid": "os",
+ "os.ErrNotExist": "os",
+ "os.ErrPermission": "os",
+ "os.Exit": "os",
+ "os.Expand": "os",
+ "os.ExpandEnv": "os",
+ "os.File": "os",
+ "os.FileInfo": "os",
+ "os.FileMode": "os",
+ "os.FindProcess": "os",
+ "os.Getegid": "os",
+ "os.Getenv": "os",
+ "os.Geteuid": "os",
+ "os.Getgid": "os",
+ "os.Getgroups": "os",
+ "os.Getpagesize": "os",
+ "os.Getpid": "os",
+ "os.Getppid": "os",
+ "os.Getuid": "os",
+ "os.Getwd": "os",
+ "os.Hostname": "os",
+ "os.Interrupt": "os",
+ "os.IsExist": "os",
+ "os.IsNotExist": "os",
+ "os.IsPathSeparator": "os",
+ "os.IsPermission": "os",
+ "os.Kill": "os",
+ "os.Lchown": "os",
+ "os.Link": "os",
+ "os.LinkError": "os",
+ "os.Lstat": "os",
+ "os.Mkdir": "os",
+ "os.MkdirAll": "os",
+ "os.ModeAppend": "os",
+ "os.ModeCharDevice": "os",
+ "os.ModeDevice": "os",
+ "os.ModeDir": "os",
+ "os.ModeExclusive": "os",
+ "os.ModeNamedPipe": "os",
+ "os.ModePerm": "os",
+ "os.ModeSetgid": "os",
+ "os.ModeSetuid": "os",
+ "os.ModeSocket": "os",
+ "os.ModeSticky": "os",
+ "os.ModeSymlink": "os",
+ "os.ModeTemporary": "os",
+ "os.ModeType": "os",
+ "os.NewFile": "os",
+ "os.NewSyscallError": "os",
+ "os.O_APPEND": "os",
+ "os.O_CREATE": "os",
+ "os.O_EXCL": "os",
+ "os.O_RDONLY": "os",
+ "os.O_RDWR": "os",
+ "os.O_SYNC": "os",
+ "os.O_TRUNC": "os",
+ "os.O_WRONLY": "os",
+ "os.Open": "os",
+ "os.OpenFile": "os",
+ "os.PathError": "os",
+ "os.PathListSeparator": "os",
+ "os.PathSeparator": "os",
+ "os.Pipe": "os",
+ "os.ProcAttr": "os",
+ "os.Process": "os",
+ "os.ProcessState": "os",
+ "os.Readlink": "os",
+ "os.Remove": "os",
+ "os.RemoveAll": "os",
+ "os.Rename": "os",
+ "os.SEEK_CUR": "os",
+ "os.SEEK_END": "os",
+ "os.SEEK_SET": "os",
+ "os.SameFile": "os",
+ "os.Setenv": "os",
+ "os.Signal": "os",
+ "os.StartProcess": "os",
+ "os.Stat": "os",
+ "os.Stderr": "os",
+ "os.Stdin": "os",
+ "os.Stdout": "os",
+ "os.Symlink": "os",
+ "os.SyscallError": "os",
+ "os.TempDir": "os",
+ "os.Truncate": "os",
+ "palette.Plan9": "image/color/palette",
+ "palette.WebSafe": "image/color/palette",
+ "parse.ActionNode": "text/template/parse",
+ "parse.BoolNode": "text/template/parse",
+ "parse.BranchNode": "text/template/parse",
+ "parse.ChainNode": "text/template/parse",
+ "parse.CommandNode": "text/template/parse",
+ "parse.DotNode": "text/template/parse",
+ "parse.FieldNode": "text/template/parse",
+ "parse.IdentifierNode": "text/template/parse",
+ "parse.IfNode": "text/template/parse",
+ "parse.IsEmptyTree": "text/template/parse",
+ "parse.ListNode": "text/template/parse",
+ "parse.New": "text/template/parse",
+ "parse.NewIdentifier": "text/template/parse",
+ "parse.NilNode": "text/template/parse",
+ "parse.Node": "text/template/parse",
+ "parse.NodeAction": "text/template/parse",
+ "parse.NodeBool": "text/template/parse",
+ "parse.NodeChain": "text/template/parse",
+ "parse.NodeCommand": "text/template/parse",
+ "parse.NodeDot": "text/template/parse",
+ "parse.NodeField": "text/template/parse",
+ "parse.NodeIdentifier": "text/template/parse",
+ "parse.NodeIf": "text/template/parse",
+ "parse.NodeList": "text/template/parse",
+ "parse.NodeNil": "text/template/parse",
+ "parse.NodeNumber": "text/template/parse",
+ "parse.NodePipe": "text/template/parse",
+ "parse.NodeRange": "text/template/parse",
+ "parse.NodeString": "text/template/parse",
+ "parse.NodeTemplate": "text/template/parse",
+ "parse.NodeText": "text/template/parse",
+ "parse.NodeType": "text/template/parse",
+ "parse.NodeVariable": "text/template/parse",
+ "parse.NodeWith": "text/template/parse",
+ "parse.NumberNode": "text/template/parse",
+ "parse.Parse": "text/template/parse",
+ "parse.PipeNode": "text/template/parse",
+ "parse.Pos": "text/template/parse",
+ "parse.RangeNode": "text/template/parse",
+ "parse.StringNode": "text/template/parse",
+ "parse.TemplateNode": "text/template/parse",
+ "parse.TextNode": "text/template/parse",
+ "parse.Tree": "text/template/parse",
+ "parse.VariableNode": "text/template/parse",
+ "parse.WithNode": "text/template/parse",
+ "parser.AllErrors": "go/parser",
+ "parser.DeclarationErrors": "go/parser",
+ "parser.ImportsOnly": "go/parser",
+ "parser.Mode": "go/parser",
+ "parser.PackageClauseOnly": "go/parser",
+ "parser.ParseComments": "go/parser",
+ "parser.ParseDir": "go/parser",
+ "parser.ParseExpr": "go/parser",
+ "parser.ParseFile": "go/parser",
+ "parser.SpuriousErrors": "go/parser",
+ "parser.Trace": "go/parser",
+ "path.Base": "path",
+ "path.Clean": "path",
+ "path.Dir": "path",
+ "path.ErrBadPattern": "path",
+ "path.Ext": "path",
+ "path.IsAbs": "path",
+ "path.Join": "path",
+ "path.Match": "path",
+ "path.Split": "path",
+ "pe.COFFSymbol": "debug/pe",
+ "pe.COFFSymbolSize": "debug/pe",
+ "pe.DataDirectory": "debug/pe",
+ "pe.File": "debug/pe",
+ "pe.FileHeader": "debug/pe",
+ "pe.FormatError": "debug/pe",
+ "pe.IMAGE_FILE_MACHINE_AM33": "debug/pe",
+ "pe.IMAGE_FILE_MACHINE_AMD64": "debug/pe",
+ "pe.IMAGE_FILE_MACHINE_ARM": "debug/pe",
+ "pe.IMAGE_FILE_MACHINE_EBC": "debug/pe",
+ "pe.IMAGE_FILE_MACHINE_I386": "debug/pe",
+ "pe.IMAGE_FILE_MACHINE_IA64": "debug/pe",
+ "pe.IMAGE_FILE_MACHINE_M32R": "debug/pe",
+ "pe.IMAGE_FILE_MACHINE_MIPS16": "debug/pe",
+ "pe.IMAGE_FILE_MACHINE_MIPSFPU": "debug/pe",
+ "pe.IMAGE_FILE_MACHINE_MIPSFPU16": "debug/pe",
+ "pe.IMAGE_FILE_MACHINE_POWERPC": "debug/pe",
+ "pe.IMAGE_FILE_MACHINE_POWERPCFP": "debug/pe",
+ "pe.IMAGE_FILE_MACHINE_R4000": "debug/pe",
+ "pe.IMAGE_FILE_MACHINE_SH3": "debug/pe",
+ "pe.IMAGE_FILE_MACHINE_SH3DSP": "debug/pe",
+ "pe.IMAGE_FILE_MACHINE_SH4": "debug/pe",
+ "pe.IMAGE_FILE_MACHINE_SH5": "debug/pe",
+ "pe.IMAGE_FILE_MACHINE_THUMB": "debug/pe",
+ "pe.IMAGE_FILE_MACHINE_UNKNOWN": "debug/pe",
+ "pe.IMAGE_FILE_MACHINE_WCEMIPSV2": "debug/pe",
+ "pe.ImportDirectory": "debug/pe",
+ "pe.NewFile": "debug/pe",
+ "pe.Open": "debug/pe",
+ "pe.OptionalHeader32": "debug/pe",
+ "pe.OptionalHeader64": "debug/pe",
+ "pe.Section": "debug/pe",
+ "pe.SectionHeader": "debug/pe",
+ "pe.SectionHeader32": "debug/pe",
+ "pe.Symbol": "debug/pe",
+ "pem.Block": "encoding/pem",
+ "pem.Decode": "encoding/pem",
+ "pem.Encode": "encoding/pem",
+ "pem.EncodeToMemory": "encoding/pem",
+ "pkix.AlgorithmIdentifier": "crypto/x509/pkix",
+ "pkix.AttributeTypeAndValue": "crypto/x509/pkix",
+ "pkix.AttributeTypeAndValueSET": "crypto/x509/pkix",
+ "pkix.CertificateList": "crypto/x509/pkix",
+ "pkix.Extension": "crypto/x509/pkix",
+ "pkix.Name": "crypto/x509/pkix",
+ "pkix.RDNSequence": "crypto/x509/pkix",
+ "pkix.RelativeDistinguishedNameSET": "crypto/x509/pkix",
+ "pkix.RevokedCertificate": "crypto/x509/pkix",
+ "pkix.TBSCertificateList": "crypto/x509/pkix",
+ "plan9obj.File": "debug/plan9obj",
+ "plan9obj.FileHeader": "debug/plan9obj",
+ "plan9obj.Magic386": "debug/plan9obj",
+ "plan9obj.Magic64": "debug/plan9obj",
+ "plan9obj.MagicAMD64": "debug/plan9obj",
+ "plan9obj.MagicARM": "debug/plan9obj",
+ "plan9obj.NewFile": "debug/plan9obj",
+ "plan9obj.Open": "debug/plan9obj",
+ "plan9obj.Section": "debug/plan9obj",
+ "plan9obj.SectionHeader": "debug/plan9obj",
+ "plan9obj.Sym": "debug/plan9obj",
+ "png.Decode": "image/png",
+ "png.DecodeConfig": "image/png",
+ "png.Encode": "image/png",
+ "png.FormatError": "image/png",
+ "png.UnsupportedError": "image/png",
+ "pprof.Cmdline": "net/http/pprof",
+ "pprof.Handler": "net/http/pprof",
+ "pprof.Index": "net/http/pprof",
+ "pprof.Lookup": "runtime/pprof",
+ "pprof.NewProfile": "runtime/pprof",
+ // "pprof.Profile" is ambiguous
+ "pprof.Profiles": "runtime/pprof",
+ "pprof.StartCPUProfile": "runtime/pprof",
+ "pprof.StopCPUProfile": "runtime/pprof",
+ "pprof.Symbol": "net/http/pprof",
+ "pprof.WriteHeapProfile": "runtime/pprof",
+ "printer.CommentedNode": "go/printer",
+ "printer.Config": "go/printer",
+ "printer.Fprint": "go/printer",
+ "printer.Mode": "go/printer",
+ "printer.RawFormat": "go/printer",
+ "printer.SourcePos": "go/printer",
+ "printer.TabIndent": "go/printer",
+ "printer.UseSpaces": "go/printer",
+ "quick.Check": "testing/quick",
+ "quick.CheckEqual": "testing/quick",
+ "quick.CheckEqualError": "testing/quick",
+ "quick.CheckError": "testing/quick",
+ "quick.Config": "testing/quick",
+ "quick.Generator": "testing/quick",
+ "quick.SetupError": "testing/quick",
+ "quick.Value": "testing/quick",
+ "rand.ExpFloat64": "math/rand",
+ "rand.Float32": "math/rand",
+ "rand.Float64": "math/rand",
+ // "rand.Int" is ambiguous
+ "rand.Int31": "math/rand",
+ "rand.Int31n": "math/rand",
+ "rand.Int63": "math/rand",
+ "rand.Int63n": "math/rand",
+ "rand.Intn": "math/rand",
+ "rand.New": "math/rand",
+ "rand.NewSource": "math/rand",
+ "rand.NewZipf": "math/rand",
+ "rand.NormFloat64": "math/rand",
+ "rand.Perm": "math/rand",
+ "rand.Prime": "crypto/rand",
+ "rand.Rand": "math/rand",
+ "rand.Read": "crypto/rand",
+ "rand.Reader": "crypto/rand",
+ "rand.Seed": "math/rand",
+ "rand.Source": "math/rand",
+ "rand.Uint32": "math/rand",
+ "rand.Zipf": "math/rand",
+ "rc4.Cipher": "crypto/rc4",
+ "rc4.KeySizeError": "crypto/rc4",
+ "rc4.NewCipher": "crypto/rc4",
+ "reflect.Append": "reflect",
+ "reflect.AppendSlice": "reflect",
+ "reflect.Array": "reflect",
+ "reflect.Bool": "reflect",
+ "reflect.BothDir": "reflect",
+ "reflect.Chan": "reflect",
+ "reflect.ChanDir": "reflect",
+ "reflect.ChanOf": "reflect",
+ "reflect.Complex128": "reflect",
+ "reflect.Complex64": "reflect",
+ "reflect.Copy": "reflect",
+ "reflect.DeepEqual": "reflect",
+ "reflect.Float32": "reflect",
+ "reflect.Float64": "reflect",
+ "reflect.Func": "reflect",
+ "reflect.Indirect": "reflect",
+ "reflect.Int": "reflect",
+ "reflect.Int16": "reflect",
+ "reflect.Int32": "reflect",
+ "reflect.Int64": "reflect",
+ "reflect.Int8": "reflect",
+ "reflect.Interface": "reflect",
+ "reflect.Invalid": "reflect",
+ "reflect.Kind": "reflect",
+ "reflect.MakeChan": "reflect",
+ "reflect.MakeFunc": "reflect",
+ "reflect.MakeMap": "reflect",
+ "reflect.MakeSlice": "reflect",
+ "reflect.Map": "reflect",
+ "reflect.MapOf": "reflect",
+ "reflect.Method": "reflect",
+ "reflect.New": "reflect",
+ "reflect.NewAt": "reflect",
+ "reflect.Ptr": "reflect",
+ "reflect.PtrTo": "reflect",
+ "reflect.RecvDir": "reflect",
+ "reflect.Select": "reflect",
+ "reflect.SelectCase": "reflect",
+ "reflect.SelectDefault": "reflect",
+ "reflect.SelectDir": "reflect",
+ "reflect.SelectRecv": "reflect",
+ "reflect.SelectSend": "reflect",
+ "reflect.SendDir": "reflect",
+ "reflect.Slice": "reflect",
+ "reflect.SliceHeader": "reflect",
+ "reflect.SliceOf": "reflect",
+ "reflect.String": "reflect",
+ "reflect.StringHeader": "reflect",
+ "reflect.Struct": "reflect",
+ "reflect.StructField": "reflect",
+ "reflect.StructTag": "reflect",
+ "reflect.TypeOf": "reflect",
+ "reflect.Uint": "reflect",
+ "reflect.Uint16": "reflect",
+ "reflect.Uint32": "reflect",
+ "reflect.Uint64": "reflect",
+ "reflect.Uint8": "reflect",
+ "reflect.Uintptr": "reflect",
+ "reflect.UnsafePointer": "reflect",
+ "reflect.Value": "reflect",
+ "reflect.ValueError": "reflect",
+ "reflect.ValueOf": "reflect",
+ "reflect.Zero": "reflect",
+ "regexp.Compile": "regexp",
+ "regexp.CompilePOSIX": "regexp",
+ "regexp.Match": "regexp",
+ "regexp.MatchReader": "regexp",
+ "regexp.MatchString": "regexp",
+ "regexp.MustCompile": "regexp",
+ "regexp.MustCompilePOSIX": "regexp",
+ "regexp.QuoteMeta": "regexp",
+ "regexp.Regexp": "regexp",
+ "ring.New": "container/ring",
+ "ring.Ring": "container/ring",
+ "rpc.Accept": "net/rpc",
+ "rpc.Call": "net/rpc",
+ "rpc.Client": "net/rpc",
+ "rpc.ClientCodec": "net/rpc",
+ "rpc.DefaultDebugPath": "net/rpc",
+ "rpc.DefaultRPCPath": "net/rpc",
+ "rpc.DefaultServer": "net/rpc",
+ "rpc.Dial": "net/rpc",
+ "rpc.DialHTTP": "net/rpc",
+ "rpc.DialHTTPPath": "net/rpc",
+ "rpc.ErrShutdown": "net/rpc",
+ "rpc.HandleHTTP": "net/rpc",
+ "rpc.NewClient": "net/rpc",
+ "rpc.NewClientWithCodec": "net/rpc",
+ "rpc.NewServer": "net/rpc",
+ "rpc.Register": "net/rpc",
+ "rpc.RegisterName": "net/rpc",
+ "rpc.Request": "net/rpc",
+ "rpc.Response": "net/rpc",
+ "rpc.ServeCodec": "net/rpc",
+ "rpc.ServeConn": "net/rpc",
+ "rpc.ServeRequest": "net/rpc",
+ "rpc.Server": "net/rpc",
+ "rpc.ServerCodec": "net/rpc",
+ "rpc.ServerError": "net/rpc",
+ "rsa.CRTValue": "crypto/rsa",
+ "rsa.DecryptOAEP": "crypto/rsa",
+ "rsa.DecryptPKCS1v15": "crypto/rsa",
+ "rsa.DecryptPKCS1v15SessionKey": "crypto/rsa",
+ "rsa.EncryptOAEP": "crypto/rsa",
+ "rsa.EncryptPKCS1v15": "crypto/rsa",
+ "rsa.ErrDecryption": "crypto/rsa",
+ "rsa.ErrMessageTooLong": "crypto/rsa",
+ "rsa.ErrVerification": "crypto/rsa",
+ "rsa.GenerateKey": "crypto/rsa",
+ "rsa.GenerateMultiPrimeKey": "crypto/rsa",
+ "rsa.PSSOptions": "crypto/rsa",
+ "rsa.PSSSaltLengthAuto": "crypto/rsa",
+ "rsa.PSSSaltLengthEqualsHash": "crypto/rsa",
+ "rsa.PrecomputedValues": "crypto/rsa",
+ "rsa.PrivateKey": "crypto/rsa",
+ "rsa.PublicKey": "crypto/rsa",
+ "rsa.SignPKCS1v15": "crypto/rsa",
+ "rsa.SignPSS": "crypto/rsa",
+ "rsa.VerifyPKCS1v15": "crypto/rsa",
+ "rsa.VerifyPSS": "crypto/rsa",
+ "runtime.BlockProfile": "runtime",
+ "runtime.BlockProfileRecord": "runtime",
+ "runtime.Breakpoint": "runtime",
+ "runtime.CPUProfile": "runtime",
+ "runtime.Caller": "runtime",
+ "runtime.Callers": "runtime",
+ "runtime.Compiler": "runtime",
+ "runtime.Error": "runtime",
+ "runtime.Func": "runtime",
+ "runtime.FuncForPC": "runtime",
+ "runtime.GC": "runtime",
+ "runtime.GOARCH": "runtime",
+ "runtime.GOMAXPROCS": "runtime",
+ "runtime.GOOS": "runtime",
+ "runtime.GOROOT": "runtime",
+ "runtime.Goexit": "runtime",
+ "runtime.GoroutineProfile": "runtime",
+ "runtime.Gosched": "runtime",
+ "runtime.LockOSThread": "runtime",
+ "runtime.MemProfile": "runtime",
+ "runtime.MemProfileRate": "runtime",
+ "runtime.MemProfileRecord": "runtime",
+ "runtime.MemStats": "runtime",
+ "runtime.NumCPU": "runtime",
+ "runtime.NumCgoCall": "runtime",
+ "runtime.NumGoroutine": "runtime",
+ "runtime.ReadMemStats": "runtime",
+ "runtime.SetBlockProfileRate": "runtime",
+ "runtime.SetCPUProfileRate": "runtime",
+ "runtime.SetFinalizer": "runtime",
+ "runtime.Stack": "runtime",
+ "runtime.StackRecord": "runtime",
+ "runtime.ThreadCreateProfile": "runtime",
+ "runtime.TypeAssertionError": "runtime",
+ "runtime.UnlockOSThread": "runtime",
+ "runtime.Version": "runtime",
+ "scanner.Char": "text/scanner",
+ "scanner.Comment": "text/scanner",
+ "scanner.EOF": "text/scanner",
+ "scanner.Error": "go/scanner",
+ "scanner.ErrorHandler": "go/scanner",
+ "scanner.ErrorList": "go/scanner",
+ "scanner.Float": "text/scanner",
+ "scanner.GoTokens": "text/scanner",
+ "scanner.GoWhitespace": "text/scanner",
+ "scanner.Ident": "text/scanner",
+ "scanner.Int": "text/scanner",
+ "scanner.Mode": "go/scanner",
+ "scanner.Position": "text/scanner",
+ "scanner.PrintError": "go/scanner",
+ "scanner.RawString": "text/scanner",
+ "scanner.ScanChars": "text/scanner",
+ // "scanner.ScanComments" is ambiguous
+ "scanner.ScanFloats": "text/scanner",
+ "scanner.ScanIdents": "text/scanner",
+ "scanner.ScanInts": "text/scanner",
+ "scanner.ScanRawStrings": "text/scanner",
+ "scanner.ScanStrings": "text/scanner",
+ // "scanner.Scanner" is ambiguous
+ "scanner.SkipComments": "text/scanner",
+ "scanner.String": "text/scanner",
+ "scanner.TokenString": "text/scanner",
+ "sha1.BlockSize": "crypto/sha1",
+ "sha1.New": "crypto/sha1",
+ "sha1.Size": "crypto/sha1",
+ "sha1.Sum": "crypto/sha1",
+ "sha256.BlockSize": "crypto/sha256",
+ "sha256.New": "crypto/sha256",
+ "sha256.New224": "crypto/sha256",
+ "sha256.Size": "crypto/sha256",
+ "sha256.Size224": "crypto/sha256",
+ "sha256.Sum224": "crypto/sha256",
+ "sha256.Sum256": "crypto/sha256",
+ "sha512.BlockSize": "crypto/sha512",
+ "sha512.New": "crypto/sha512",
+ "sha512.New384": "crypto/sha512",
+ "sha512.Size": "crypto/sha512",
+ "sha512.Size384": "crypto/sha512",
+ "sha512.Sum384": "crypto/sha512",
+ "sha512.Sum512": "crypto/sha512",
+ "signal.Notify": "os/signal",
+ "signal.Stop": "os/signal",
+ "smtp.Auth": "net/smtp",
+ "smtp.CRAMMD5Auth": "net/smtp",
+ "smtp.Client": "net/smtp",
+ "smtp.Dial": "net/smtp",
+ "smtp.NewClient": "net/smtp",
+ "smtp.PlainAuth": "net/smtp",
+ "smtp.SendMail": "net/smtp",
+ "smtp.ServerInfo": "net/smtp",
+ "sort.Float64Slice": "sort",
+ "sort.Float64s": "sort",
+ "sort.Float64sAreSorted": "sort",
+ "sort.IntSlice": "sort",
+ "sort.Interface": "sort",
+ "sort.Ints": "sort",
+ "sort.IntsAreSorted": "sort",
+ "sort.IsSorted": "sort",
+ "sort.Reverse": "sort",
+ "sort.Search": "sort",
+ "sort.SearchFloat64s": "sort",
+ "sort.SearchInts": "sort",
+ "sort.SearchStrings": "sort",
+ "sort.Sort": "sort",
+ "sort.Stable": "sort",
+ "sort.StringSlice": "sort",
+ "sort.Strings": "sort",
+ "sort.StringsAreSorted": "sort",
+ "sql.DB": "database/sql",
+ "sql.ErrNoRows": "database/sql",
+ "sql.ErrTxDone": "database/sql",
+ "sql.NullBool": "database/sql",
+ "sql.NullFloat64": "database/sql",
+ "sql.NullInt64": "database/sql",
+ "sql.NullString": "database/sql",
+ "sql.Open": "database/sql",
+ "sql.RawBytes": "database/sql",
+ "sql.Register": "database/sql",
+ "sql.Result": "database/sql",
+ "sql.Row": "database/sql",
+ "sql.Rows": "database/sql",
+ "sql.Scanner": "database/sql",
+ "sql.Stmt": "database/sql",
+ "sql.Tx": "database/sql",
+ "strconv.AppendBool": "strconv",
+ "strconv.AppendFloat": "strconv",
+ "strconv.AppendInt": "strconv",
+ "strconv.AppendQuote": "strconv",
+ "strconv.AppendQuoteRune": "strconv",
+ "strconv.AppendQuoteRuneToASCII": "strconv",
+ "strconv.AppendQuoteToASCII": "strconv",
+ "strconv.AppendUint": "strconv",
+ "strconv.Atoi": "strconv",
+ "strconv.CanBackquote": "strconv",
+ "strconv.ErrRange": "strconv",
+ "strconv.ErrSyntax": "strconv",
+ "strconv.FormatBool": "strconv",
+ "strconv.FormatFloat": "strconv",
+ "strconv.FormatInt": "strconv",
+ "strconv.FormatUint": "strconv",
+ "strconv.IntSize": "strconv",
+ "strconv.IsPrint": "strconv",
+ "strconv.Itoa": "strconv",
+ "strconv.NumError": "strconv",
+ "strconv.ParseBool": "strconv",
+ "strconv.ParseFloat": "strconv",
+ "strconv.ParseInt": "strconv",
+ "strconv.ParseUint": "strconv",
+ "strconv.Quote": "strconv",
+ "strconv.QuoteRune": "strconv",
+ "strconv.QuoteRuneToASCII": "strconv",
+ "strconv.QuoteToASCII": "strconv",
+ "strconv.Unquote": "strconv",
+ "strconv.UnquoteChar": "strconv",
+ "strings.Contains": "strings",
+ "strings.ContainsAny": "strings",
+ "strings.ContainsRune": "strings",
+ "strings.Count": "strings",
+ "strings.EqualFold": "strings",
+ "strings.Fields": "strings",
+ "strings.FieldsFunc": "strings",
+ "strings.HasPrefix": "strings",
+ "strings.HasSuffix": "strings",
+ "strings.Index": "strings",
+ "strings.IndexAny": "strings",
+ "strings.IndexByte": "strings",
+ "strings.IndexFunc": "strings",
+ "strings.IndexRune": "strings",
+ "strings.Join": "strings",
+ "strings.LastIndex": "strings",
+ "strings.LastIndexAny": "strings",
+ "strings.LastIndexFunc": "strings",
+ "strings.Map": "strings",
+ "strings.NewReader": "strings",
+ "strings.NewReplacer": "strings",
+ "strings.Reader": "strings",
+ "strings.Repeat": "strings",
+ "strings.Replace": "strings",
+ "strings.Replacer": "strings",
+ "strings.Split": "strings",
+ "strings.SplitAfter": "strings",
+ "strings.SplitAfterN": "strings",
+ "strings.SplitN": "strings",
+ "strings.Title": "strings",
+ "strings.ToLower": "strings",
+ "strings.ToLowerSpecial": "strings",
+ "strings.ToTitle": "strings",
+ "strings.ToTitleSpecial": "strings",
+ "strings.ToUpper": "strings",
+ "strings.ToUpperSpecial": "strings",
+ "strings.Trim": "strings",
+ "strings.TrimFunc": "strings",
+ "strings.TrimLeft": "strings",
+ "strings.TrimLeftFunc": "strings",
+ "strings.TrimPrefix": "strings",
+ "strings.TrimRight": "strings",
+ "strings.TrimRightFunc": "strings",
+ "strings.TrimSpace": "strings",
+ "strings.TrimSuffix": "strings",
+ "subtle.ConstantTimeByteEq": "crypto/subtle",
+ "subtle.ConstantTimeCompare": "crypto/subtle",
+ "subtle.ConstantTimeCopy": "crypto/subtle",
+ "subtle.ConstantTimeEq": "crypto/subtle",
+ "subtle.ConstantTimeLessOrEq": "crypto/subtle",
+ "subtle.ConstantTimeSelect": "crypto/subtle",
+ "suffixarray.Index": "index/suffixarray",
+ "suffixarray.New": "index/suffixarray",
+ "sync.Cond": "sync",
+ "sync.Locker": "sync",
+ "sync.Mutex": "sync",
+ "sync.NewCond": "sync",
+ "sync.Once": "sync",
+ "sync.Pool": "sync",
+ "sync.RWMutex": "sync",
+ "sync.WaitGroup": "sync",
+ "syntax.ClassNL": "regexp/syntax",
+ "syntax.Compile": "regexp/syntax",
+ "syntax.DotNL": "regexp/syntax",
+ "syntax.EmptyBeginLine": "regexp/syntax",
+ "syntax.EmptyBeginText": "regexp/syntax",
+ "syntax.EmptyEndLine": "regexp/syntax",
+ "syntax.EmptyEndText": "regexp/syntax",
+ "syntax.EmptyNoWordBoundary": "regexp/syntax",
+ "syntax.EmptyOp": "regexp/syntax",
+ "syntax.EmptyOpContext": "regexp/syntax",
+ "syntax.EmptyWordBoundary": "regexp/syntax",
+ "syntax.ErrInternalError": "regexp/syntax",
+ "syntax.ErrInvalidCharClass": "regexp/syntax",
+ "syntax.ErrInvalidCharRange": "regexp/syntax",
+ "syntax.ErrInvalidEscape": "regexp/syntax",
+ "syntax.ErrInvalidNamedCapture": "regexp/syntax",
+ "syntax.ErrInvalidPerlOp": "regexp/syntax",
+ "syntax.ErrInvalidRepeatOp": "regexp/syntax",
+ "syntax.ErrInvalidRepeatSize": "regexp/syntax",
+ "syntax.ErrInvalidUTF8": "regexp/syntax",
+ "syntax.ErrMissingBracket": "regexp/syntax",
+ "syntax.ErrMissingParen": "regexp/syntax",
+ "syntax.ErrMissingRepeatArgument": "regexp/syntax",
+ "syntax.ErrTrailingBackslash": "regexp/syntax",
+ "syntax.ErrUnexpectedParen": "regexp/syntax",
+ "syntax.Error": "regexp/syntax",
+ "syntax.ErrorCode": "regexp/syntax",
+ "syntax.Flags": "regexp/syntax",
+ "syntax.FoldCase": "regexp/syntax",
+ "syntax.Inst": "regexp/syntax",
+ "syntax.InstAlt": "regexp/syntax",
+ "syntax.InstAltMatch": "regexp/syntax",
+ "syntax.InstCapture": "regexp/syntax",
+ "syntax.InstEmptyWidth": "regexp/syntax",
+ "syntax.InstFail": "regexp/syntax",
+ "syntax.InstMatch": "regexp/syntax",
+ "syntax.InstNop": "regexp/syntax",
+ "syntax.InstOp": "regexp/syntax",
+ "syntax.InstRune": "regexp/syntax",
+ "syntax.InstRune1": "regexp/syntax",
+ "syntax.InstRuneAny": "regexp/syntax",
+ "syntax.InstRuneAnyNotNL": "regexp/syntax",
+ "syntax.IsWordChar": "regexp/syntax",
+ "syntax.Literal": "regexp/syntax",
+ "syntax.MatchNL": "regexp/syntax",
+ "syntax.NonGreedy": "regexp/syntax",
+ "syntax.OneLine": "regexp/syntax",
+ "syntax.Op": "regexp/syntax",
+ "syntax.OpAlternate": "regexp/syntax",
+ "syntax.OpAnyChar": "regexp/syntax",
+ "syntax.OpAnyCharNotNL": "regexp/syntax",
+ "syntax.OpBeginLine": "regexp/syntax",
+ "syntax.OpBeginText": "regexp/syntax",
+ "syntax.OpCapture": "regexp/syntax",
+ "syntax.OpCharClass": "regexp/syntax",
+ "syntax.OpConcat": "regexp/syntax",
+ "syntax.OpEmptyMatch": "regexp/syntax",
+ "syntax.OpEndLine": "regexp/syntax",
+ "syntax.OpEndText": "regexp/syntax",
+ "syntax.OpLiteral": "regexp/syntax",
+ "syntax.OpNoMatch": "regexp/syntax",
+ "syntax.OpNoWordBoundary": "regexp/syntax",
+ "syntax.OpPlus": "regexp/syntax",
+ "syntax.OpQuest": "regexp/syntax",
+ "syntax.OpRepeat": "regexp/syntax",
+ "syntax.OpStar": "regexp/syntax",
+ "syntax.OpWordBoundary": "regexp/syntax",
+ "syntax.POSIX": "regexp/syntax",
+ "syntax.Parse": "regexp/syntax",
+ "syntax.Perl": "regexp/syntax",
+ "syntax.PerlX": "regexp/syntax",
+ "syntax.Prog": "regexp/syntax",
+ "syntax.Regexp": "regexp/syntax",
+ "syntax.Simple": "regexp/syntax",
+ "syntax.UnicodeGroups": "regexp/syntax",
+ "syntax.WasDollar": "regexp/syntax",
+ "syscall.AF_ALG": "syscall",
+ "syscall.AF_APPLETALK": "syscall",
+ "syscall.AF_ARP": "syscall",
+ "syscall.AF_ASH": "syscall",
+ "syscall.AF_ATM": "syscall",
+ "syscall.AF_ATMPVC": "syscall",
+ "syscall.AF_ATMSVC": "syscall",
+ "syscall.AF_AX25": "syscall",
+ "syscall.AF_BLUETOOTH": "syscall",
+ "syscall.AF_BRIDGE": "syscall",
+ "syscall.AF_CAIF": "syscall",
+ "syscall.AF_CAN": "syscall",
+ "syscall.AF_CCITT": "syscall",
+ "syscall.AF_CHAOS": "syscall",
+ "syscall.AF_CNT": "syscall",
+ "syscall.AF_COIP": "syscall",
+ "syscall.AF_DATAKIT": "syscall",
+ "syscall.AF_DECnet": "syscall",
+ "syscall.AF_DLI": "syscall",
+ "syscall.AF_E164": "syscall",
+ "syscall.AF_ECMA": "syscall",
+ "syscall.AF_ECONET": "syscall",
+ "syscall.AF_ENCAP": "syscall",
+ "syscall.AF_FILE": "syscall",
+ "syscall.AF_HYLINK": "syscall",
+ "syscall.AF_IEEE80211": "syscall",
+ "syscall.AF_IEEE802154": "syscall",
+ "syscall.AF_IMPLINK": "syscall",
+ "syscall.AF_INET": "syscall",
+ "syscall.AF_INET6": "syscall",
+ "syscall.AF_INET6_SDP": "syscall",
+ "syscall.AF_INET_SDP": "syscall",
+ "syscall.AF_IPX": "syscall",
+ "syscall.AF_IRDA": "syscall",
+ "syscall.AF_ISDN": "syscall",
+ "syscall.AF_ISO": "syscall",
+ "syscall.AF_IUCV": "syscall",
+ "syscall.AF_KEY": "syscall",
+ "syscall.AF_LAT": "syscall",
+ "syscall.AF_LINK": "syscall",
+ "syscall.AF_LLC": "syscall",
+ "syscall.AF_LOCAL": "syscall",
+ "syscall.AF_MAX": "syscall",
+ "syscall.AF_MPLS": "syscall",
+ "syscall.AF_NATM": "syscall",
+ "syscall.AF_NDRV": "syscall",
+ "syscall.AF_NETBEUI": "syscall",
+ "syscall.AF_NETBIOS": "syscall",
+ "syscall.AF_NETGRAPH": "syscall",
+ "syscall.AF_NETLINK": "syscall",
+ "syscall.AF_NETROM": "syscall",
+ "syscall.AF_NS": "syscall",
+ "syscall.AF_OROUTE": "syscall",
+ "syscall.AF_OSI": "syscall",
+ "syscall.AF_PACKET": "syscall",
+ "syscall.AF_PHONET": "syscall",
+ "syscall.AF_PPP": "syscall",
+ "syscall.AF_PPPOX": "syscall",
+ "syscall.AF_PUP": "syscall",
+ "syscall.AF_RDS": "syscall",
+ "syscall.AF_RESERVED_36": "syscall",
+ "syscall.AF_ROSE": "syscall",
+ "syscall.AF_ROUTE": "syscall",
+ "syscall.AF_RXRPC": "syscall",
+ "syscall.AF_SCLUSTER": "syscall",
+ "syscall.AF_SECURITY": "syscall",
+ "syscall.AF_SIP": "syscall",
+ "syscall.AF_SLOW": "syscall",
+ "syscall.AF_SNA": "syscall",
+ "syscall.AF_SYSTEM": "syscall",
+ "syscall.AF_TIPC": "syscall",
+ "syscall.AF_UNIX": "syscall",
+ "syscall.AF_UNSPEC": "syscall",
+ "syscall.AF_VENDOR00": "syscall",
+ "syscall.AF_VENDOR01": "syscall",
+ "syscall.AF_VENDOR02": "syscall",
+ "syscall.AF_VENDOR03": "syscall",
+ "syscall.AF_VENDOR04": "syscall",
+ "syscall.AF_VENDOR05": "syscall",
+ "syscall.AF_VENDOR06": "syscall",
+ "syscall.AF_VENDOR07": "syscall",
+ "syscall.AF_VENDOR08": "syscall",
+ "syscall.AF_VENDOR09": "syscall",
+ "syscall.AF_VENDOR10": "syscall",
+ "syscall.AF_VENDOR11": "syscall",
+ "syscall.AF_VENDOR12": "syscall",
+ "syscall.AF_VENDOR13": "syscall",
+ "syscall.AF_VENDOR14": "syscall",
+ "syscall.AF_VENDOR15": "syscall",
+ "syscall.AF_VENDOR16": "syscall",
+ "syscall.AF_VENDOR17": "syscall",
+ "syscall.AF_VENDOR18": "syscall",
+ "syscall.AF_VENDOR19": "syscall",
+ "syscall.AF_VENDOR20": "syscall",
+ "syscall.AF_VENDOR21": "syscall",
+ "syscall.AF_VENDOR22": "syscall",
+ "syscall.AF_VENDOR23": "syscall",
+ "syscall.AF_VENDOR24": "syscall",
+ "syscall.AF_VENDOR25": "syscall",
+ "syscall.AF_VENDOR26": "syscall",
+ "syscall.AF_VENDOR27": "syscall",
+ "syscall.AF_VENDOR28": "syscall",
+ "syscall.AF_VENDOR29": "syscall",
+ "syscall.AF_VENDOR30": "syscall",
+ "syscall.AF_VENDOR31": "syscall",
+ "syscall.AF_VENDOR32": "syscall",
+ "syscall.AF_VENDOR33": "syscall",
+ "syscall.AF_VENDOR34": "syscall",
+ "syscall.AF_VENDOR35": "syscall",
+ "syscall.AF_VENDOR36": "syscall",
+ "syscall.AF_VENDOR37": "syscall",
+ "syscall.AF_VENDOR38": "syscall",
+ "syscall.AF_VENDOR39": "syscall",
+ "syscall.AF_VENDOR40": "syscall",
+ "syscall.AF_VENDOR41": "syscall",
+ "syscall.AF_VENDOR42": "syscall",
+ "syscall.AF_VENDOR43": "syscall",
+ "syscall.AF_VENDOR44": "syscall",
+ "syscall.AF_VENDOR45": "syscall",
+ "syscall.AF_VENDOR46": "syscall",
+ "syscall.AF_VENDOR47": "syscall",
+ "syscall.AF_WANPIPE": "syscall",
+ "syscall.AF_X25": "syscall",
+ "syscall.AI_CANONNAME": "syscall",
+ "syscall.AI_NUMERICHOST": "syscall",
+ "syscall.AI_PASSIVE": "syscall",
+ "syscall.APPLICATION_ERROR": "syscall",
+ "syscall.ARPHRD_ADAPT": "syscall",
+ "syscall.ARPHRD_APPLETLK": "syscall",
+ "syscall.ARPHRD_ARCNET": "syscall",
+ "syscall.ARPHRD_ASH": "syscall",
+ "syscall.ARPHRD_ATM": "syscall",
+ "syscall.ARPHRD_AX25": "syscall",
+ "syscall.ARPHRD_BIF": "syscall",
+ "syscall.ARPHRD_CHAOS": "syscall",
+ "syscall.ARPHRD_CISCO": "syscall",
+ "syscall.ARPHRD_CSLIP": "syscall",
+ "syscall.ARPHRD_CSLIP6": "syscall",
+ "syscall.ARPHRD_DDCMP": "syscall",
+ "syscall.ARPHRD_DLCI": "syscall",
+ "syscall.ARPHRD_ECONET": "syscall",
+ "syscall.ARPHRD_EETHER": "syscall",
+ "syscall.ARPHRD_ETHER": "syscall",
+ "syscall.ARPHRD_EUI64": "syscall",
+ "syscall.ARPHRD_FCAL": "syscall",
+ "syscall.ARPHRD_FCFABRIC": "syscall",
+ "syscall.ARPHRD_FCPL": "syscall",
+ "syscall.ARPHRD_FCPP": "syscall",
+ "syscall.ARPHRD_FDDI": "syscall",
+ "syscall.ARPHRD_FRAD": "syscall",
+ "syscall.ARPHRD_FRELAY": "syscall",
+ "syscall.ARPHRD_HDLC": "syscall",
+ "syscall.ARPHRD_HIPPI": "syscall",
+ "syscall.ARPHRD_HWX25": "syscall",
+ "syscall.ARPHRD_IEEE1394": "syscall",
+ "syscall.ARPHRD_IEEE802": "syscall",
+ "syscall.ARPHRD_IEEE80211": "syscall",
+ "syscall.ARPHRD_IEEE80211_PRISM": "syscall",
+ "syscall.ARPHRD_IEEE80211_RADIOTAP": "syscall",
+ "syscall.ARPHRD_IEEE802154": "syscall",
+ "syscall.ARPHRD_IEEE802154_PHY": "syscall",
+ "syscall.ARPHRD_IEEE802_TR": "syscall",
+ "syscall.ARPHRD_INFINIBAND": "syscall",
+ "syscall.ARPHRD_IPDDP": "syscall",
+ "syscall.ARPHRD_IPGRE": "syscall",
+ "syscall.ARPHRD_IRDA": "syscall",
+ "syscall.ARPHRD_LAPB": "syscall",
+ "syscall.ARPHRD_LOCALTLK": "syscall",
+ "syscall.ARPHRD_LOOPBACK": "syscall",
+ "syscall.ARPHRD_METRICOM": "syscall",
+ "syscall.ARPHRD_NETROM": "syscall",
+ "syscall.ARPHRD_NONE": "syscall",
+ "syscall.ARPHRD_PIMREG": "syscall",
+ "syscall.ARPHRD_PPP": "syscall",
+ "syscall.ARPHRD_PRONET": "syscall",
+ "syscall.ARPHRD_RAWHDLC": "syscall",
+ "syscall.ARPHRD_ROSE": "syscall",
+ "syscall.ARPHRD_RSRVD": "syscall",
+ "syscall.ARPHRD_SIT": "syscall",
+ "syscall.ARPHRD_SKIP": "syscall",
+ "syscall.ARPHRD_SLIP": "syscall",
+ "syscall.ARPHRD_SLIP6": "syscall",
+ "syscall.ARPHRD_STRIP": "syscall",
+ "syscall.ARPHRD_TUNNEL": "syscall",
+ "syscall.ARPHRD_TUNNEL6": "syscall",
+ "syscall.ARPHRD_VOID": "syscall",
+ "syscall.ARPHRD_X25": "syscall",
+ "syscall.AUTHTYPE_CLIENT": "syscall",
+ "syscall.AUTHTYPE_SERVER": "syscall",
+ "syscall.Accept": "syscall",
+ "syscall.Accept4": "syscall",
+ "syscall.AcceptEx": "syscall",
+ "syscall.Access": "syscall",
+ "syscall.Acct": "syscall",
+ "syscall.AddrinfoW": "syscall",
+ "syscall.Adjtime": "syscall",
+ "syscall.Adjtimex": "syscall",
+ "syscall.AttachLsf": "syscall",
+ "syscall.B0": "syscall",
+ "syscall.B1000000": "syscall",
+ "syscall.B110": "syscall",
+ "syscall.B115200": "syscall",
+ "syscall.B1152000": "syscall",
+ "syscall.B1200": "syscall",
+ "syscall.B134": "syscall",
+ "syscall.B14400": "syscall",
+ "syscall.B150": "syscall",
+ "syscall.B1500000": "syscall",
+ "syscall.B1800": "syscall",
+ "syscall.B19200": "syscall",
+ "syscall.B200": "syscall",
+ "syscall.B2000000": "syscall",
+ "syscall.B230400": "syscall",
+ "syscall.B2400": "syscall",
+ "syscall.B2500000": "syscall",
+ "syscall.B28800": "syscall",
+ "syscall.B300": "syscall",
+ "syscall.B3000000": "syscall",
+ "syscall.B3500000": "syscall",
+ "syscall.B38400": "syscall",
+ "syscall.B4000000": "syscall",
+ "syscall.B460800": "syscall",
+ "syscall.B4800": "syscall",
+ "syscall.B50": "syscall",
+ "syscall.B500000": "syscall",
+ "syscall.B57600": "syscall",
+ "syscall.B576000": "syscall",
+ "syscall.B600": "syscall",
+ "syscall.B7200": "syscall",
+ "syscall.B75": "syscall",
+ "syscall.B76800": "syscall",
+ "syscall.B921600": "syscall",
+ "syscall.B9600": "syscall",
+ "syscall.BASE_PROTOCOL": "syscall",
+ "syscall.BIOCFEEDBACK": "syscall",
+ "syscall.BIOCFLUSH": "syscall",
+ "syscall.BIOCGBLEN": "syscall",
+ "syscall.BIOCGDIRECTION": "syscall",
+ "syscall.BIOCGDIRFILT": "syscall",
+ "syscall.BIOCGDLT": "syscall",
+ "syscall.BIOCGDLTLIST": "syscall",
+ "syscall.BIOCGETBUFMODE": "syscall",
+ "syscall.BIOCGETIF": "syscall",
+ "syscall.BIOCGETZMAX": "syscall",
+ "syscall.BIOCGFEEDBACK": "syscall",
+ "syscall.BIOCGFILDROP": "syscall",
+ "syscall.BIOCGHDRCMPLT": "syscall",
+ "syscall.BIOCGRSIG": "syscall",
+ "syscall.BIOCGRTIMEOUT": "syscall",
+ "syscall.BIOCGSEESENT": "syscall",
+ "syscall.BIOCGSTATS": "syscall",
+ "syscall.BIOCGSTATSOLD": "syscall",
+ "syscall.BIOCGTSTAMP": "syscall",
+ "syscall.BIOCIMMEDIATE": "syscall",
+ "syscall.BIOCLOCK": "syscall",
+ "syscall.BIOCPROMISC": "syscall",
+ "syscall.BIOCROTZBUF": "syscall",
+ "syscall.BIOCSBLEN": "syscall",
+ "syscall.BIOCSDIRECTION": "syscall",
+ "syscall.BIOCSDIRFILT": "syscall",
+ "syscall.BIOCSDLT": "syscall",
+ "syscall.BIOCSETBUFMODE": "syscall",
+ "syscall.BIOCSETF": "syscall",
+ "syscall.BIOCSETFNR": "syscall",
+ "syscall.BIOCSETIF": "syscall",
+ "syscall.BIOCSETWF": "syscall",
+ "syscall.BIOCSETZBUF": "syscall",
+ "syscall.BIOCSFEEDBACK": "syscall",
+ "syscall.BIOCSFILDROP": "syscall",
+ "syscall.BIOCSHDRCMPLT": "syscall",
+ "syscall.BIOCSRSIG": "syscall",
+ "syscall.BIOCSRTIMEOUT": "syscall",
+ "syscall.BIOCSSEESENT": "syscall",
+ "syscall.BIOCSTCPF": "syscall",
+ "syscall.BIOCSTSTAMP": "syscall",
+ "syscall.BIOCSUDPF": "syscall",
+ "syscall.BIOCVERSION": "syscall",
+ "syscall.BPF_A": "syscall",
+ "syscall.BPF_ABS": "syscall",
+ "syscall.BPF_ADD": "syscall",
+ "syscall.BPF_ALIGNMENT": "syscall",
+ "syscall.BPF_ALIGNMENT32": "syscall",
+ "syscall.BPF_ALU": "syscall",
+ "syscall.BPF_AND": "syscall",
+ "syscall.BPF_B": "syscall",
+ "syscall.BPF_BUFMODE_BUFFER": "syscall",
+ "syscall.BPF_BUFMODE_ZBUF": "syscall",
+ "syscall.BPF_DFLTBUFSIZE": "syscall",
+ "syscall.BPF_DIRECTION_IN": "syscall",
+ "syscall.BPF_DIRECTION_OUT": "syscall",
+ "syscall.BPF_DIV": "syscall",
+ "syscall.BPF_H": "syscall",
+ "syscall.BPF_IMM": "syscall",
+ "syscall.BPF_IND": "syscall",
+ "syscall.BPF_JA": "syscall",
+ "syscall.BPF_JEQ": "syscall",
+ "syscall.BPF_JGE": "syscall",
+ "syscall.BPF_JGT": "syscall",
+ "syscall.BPF_JMP": "syscall",
+ "syscall.BPF_JSET": "syscall",
+ "syscall.BPF_K": "syscall",
+ "syscall.BPF_LD": "syscall",
+ "syscall.BPF_LDX": "syscall",
+ "syscall.BPF_LEN": "syscall",
+ "syscall.BPF_LSH": "syscall",
+ "syscall.BPF_MAJOR_VERSION": "syscall",
+ "syscall.BPF_MAXBUFSIZE": "syscall",
+ "syscall.BPF_MAXINSNS": "syscall",
+ "syscall.BPF_MEM": "syscall",
+ "syscall.BPF_MEMWORDS": "syscall",
+ "syscall.BPF_MINBUFSIZE": "syscall",
+ "syscall.BPF_MINOR_VERSION": "syscall",
+ "syscall.BPF_MISC": "syscall",
+ "syscall.BPF_MSH": "syscall",
+ "syscall.BPF_MUL": "syscall",
+ "syscall.BPF_NEG": "syscall",
+ "syscall.BPF_OR": "syscall",
+ "syscall.BPF_RELEASE": "syscall",
+ "syscall.BPF_RET": "syscall",
+ "syscall.BPF_RSH": "syscall",
+ "syscall.BPF_ST": "syscall",
+ "syscall.BPF_STX": "syscall",
+ "syscall.BPF_SUB": "syscall",
+ "syscall.BPF_TAX": "syscall",
+ "syscall.BPF_TXA": "syscall",
+ "syscall.BPF_T_BINTIME": "syscall",
+ "syscall.BPF_T_BINTIME_FAST": "syscall",
+ "syscall.BPF_T_BINTIME_MONOTONIC": "syscall",
+ "syscall.BPF_T_BINTIME_MONOTONIC_FAST": "syscall",
+ "syscall.BPF_T_FAST": "syscall",
+ "syscall.BPF_T_FLAG_MASK": "syscall",
+ "syscall.BPF_T_FORMAT_MASK": "syscall",
+ "syscall.BPF_T_MICROTIME": "syscall",
+ "syscall.BPF_T_MICROTIME_FAST": "syscall",
+ "syscall.BPF_T_MICROTIME_MONOTONIC": "syscall",
+ "syscall.BPF_T_MICROTIME_MONOTONIC_FAST": "syscall",
+ "syscall.BPF_T_MONOTONIC": "syscall",
+ "syscall.BPF_T_MONOTONIC_FAST": "syscall",
+ "syscall.BPF_T_NANOTIME": "syscall",
+ "syscall.BPF_T_NANOTIME_FAST": "syscall",
+ "syscall.BPF_T_NANOTIME_MONOTONIC": "syscall",
+ "syscall.BPF_T_NANOTIME_MONOTONIC_FAST": "syscall",
+ "syscall.BPF_T_NONE": "syscall",
+ "syscall.BPF_T_NORMAL": "syscall",
+ "syscall.BPF_W": "syscall",
+ "syscall.BPF_X": "syscall",
+ "syscall.BRKINT": "syscall",
+ "syscall.Bind": "syscall",
+ "syscall.BindToDevice": "syscall",
+ "syscall.BpfBuflen": "syscall",
+ "syscall.BpfDatalink": "syscall",
+ "syscall.BpfHdr": "syscall",
+ "syscall.BpfHeadercmpl": "syscall",
+ "syscall.BpfInsn": "syscall",
+ "syscall.BpfInterface": "syscall",
+ "syscall.BpfJump": "syscall",
+ "syscall.BpfProgram": "syscall",
+ "syscall.BpfStat": "syscall",
+ "syscall.BpfStats": "syscall",
+ "syscall.BpfStmt": "syscall",
+ "syscall.BpfTimeout": "syscall",
+ "syscall.BpfTimeval": "syscall",
+ "syscall.BpfVersion": "syscall",
+ "syscall.BpfZbuf": "syscall",
+ "syscall.BpfZbufHeader": "syscall",
+ "syscall.ByHandleFileInformation": "syscall",
+ "syscall.BytePtrFromString": "syscall",
+ "syscall.ByteSliceFromString": "syscall",
+ "syscall.CCR0_FLUSH": "syscall",
+ "syscall.CERT_CHAIN_POLICY_AUTHENTICODE": "syscall",
+ "syscall.CERT_CHAIN_POLICY_AUTHENTICODE_TS": "syscall",
+ "syscall.CERT_CHAIN_POLICY_BASE": "syscall",
+ "syscall.CERT_CHAIN_POLICY_BASIC_CONSTRAINTS": "syscall",
+ "syscall.CERT_CHAIN_POLICY_EV": "syscall",
+ "syscall.CERT_CHAIN_POLICY_MICROSOFT_ROOT": "syscall",
+ "syscall.CERT_CHAIN_POLICY_NT_AUTH": "syscall",
+ "syscall.CERT_CHAIN_POLICY_SSL": "syscall",
+ "syscall.CERT_E_CN_NO_MATCH": "syscall",
+ "syscall.CERT_E_EXPIRED": "syscall",
+ "syscall.CERT_E_PURPOSE": "syscall",
+ "syscall.CERT_E_ROLE": "syscall",
+ "syscall.CERT_E_UNTRUSTEDROOT": "syscall",
+ "syscall.CERT_STORE_ADD_ALWAYS": "syscall",
+ "syscall.CERT_STORE_DEFER_CLOSE_UNTIL_LAST_FREE_FLAG": "syscall",
+ "syscall.CERT_STORE_PROV_MEMORY": "syscall",
+ "syscall.CERT_TRUST_HAS_EXCLUDED_NAME_CONSTRAINT": "syscall",
+ "syscall.CERT_TRUST_HAS_NOT_DEFINED_NAME_CONSTRAINT": "syscall",
+ "syscall.CERT_TRUST_HAS_NOT_PERMITTED_NAME_CONSTRAINT": "syscall",
+ "syscall.CERT_TRUST_HAS_NOT_SUPPORTED_CRITICAL_EXT": "syscall",
+ "syscall.CERT_TRUST_HAS_NOT_SUPPORTED_NAME_CONSTRAINT": "syscall",
+ "syscall.CERT_TRUST_INVALID_BASIC_CONSTRAINTS": "syscall",
+ "syscall.CERT_TRUST_INVALID_EXTENSION": "syscall",
+ "syscall.CERT_TRUST_INVALID_NAME_CONSTRAINTS": "syscall",
+ "syscall.CERT_TRUST_INVALID_POLICY_CONSTRAINTS": "syscall",
+ "syscall.CERT_TRUST_IS_CYCLIC": "syscall",
+ "syscall.CERT_TRUST_IS_EXPLICIT_DISTRUST": "syscall",
+ "syscall.CERT_TRUST_IS_NOT_SIGNATURE_VALID": "syscall",
+ "syscall.CERT_TRUST_IS_NOT_TIME_VALID": "syscall",
+ "syscall.CERT_TRUST_IS_NOT_VALID_FOR_USAGE": "syscall",
+ "syscall.CERT_TRUST_IS_OFFLINE_REVOCATION": "syscall",
+ "syscall.CERT_TRUST_IS_REVOKED": "syscall",
+ "syscall.CERT_TRUST_IS_UNTRUSTED_ROOT": "syscall",
+ "syscall.CERT_TRUST_NO_ERROR": "syscall",
+ "syscall.CERT_TRUST_NO_ISSUANCE_CHAIN_POLICY": "syscall",
+ "syscall.CERT_TRUST_REVOCATION_STATUS_UNKNOWN": "syscall",
+ "syscall.CFLUSH": "syscall",
+ "syscall.CLOCAL": "syscall",
+ "syscall.CLONE_CHILD_CLEARTID": "syscall",
+ "syscall.CLONE_CHILD_SETTID": "syscall",
+ "syscall.CLONE_CSIGNAL": "syscall",
+ "syscall.CLONE_DETACHED": "syscall",
+ "syscall.CLONE_FILES": "syscall",
+ "syscall.CLONE_FS": "syscall",
+ "syscall.CLONE_IO": "syscall",
+ "syscall.CLONE_NEWIPC": "syscall",
+ "syscall.CLONE_NEWNET": "syscall",
+ "syscall.CLONE_NEWNS": "syscall",
+ "syscall.CLONE_NEWPID": "syscall",
+ "syscall.CLONE_NEWUSER": "syscall",
+ "syscall.CLONE_NEWUTS": "syscall",
+ "syscall.CLONE_PARENT": "syscall",
+ "syscall.CLONE_PARENT_SETTID": "syscall",
+ "syscall.CLONE_PID": "syscall",
+ "syscall.CLONE_PTRACE": "syscall",
+ "syscall.CLONE_SETTLS": "syscall",
+ "syscall.CLONE_SIGHAND": "syscall",
+ "syscall.CLONE_SYSVSEM": "syscall",
+ "syscall.CLONE_THREAD": "syscall",
+ "syscall.CLONE_UNTRACED": "syscall",
+ "syscall.CLONE_VFORK": "syscall",
+ "syscall.CLONE_VM": "syscall",
+ "syscall.CPUID_CFLUSH": "syscall",
+ "syscall.CREAD": "syscall",
+ "syscall.CREATE_ALWAYS": "syscall",
+ "syscall.CREATE_NEW": "syscall",
+ "syscall.CREATE_NEW_PROCESS_GROUP": "syscall",
+ "syscall.CREATE_UNICODE_ENVIRONMENT": "syscall",
+ "syscall.CRYPT_DEFAULT_CONTAINER_OPTIONAL": "syscall",
+ "syscall.CRYPT_DELETEKEYSET": "syscall",
+ "syscall.CRYPT_MACHINE_KEYSET": "syscall",
+ "syscall.CRYPT_NEWKEYSET": "syscall",
+ "syscall.CRYPT_SILENT": "syscall",
+ "syscall.CRYPT_VERIFYCONTEXT": "syscall",
+ "syscall.CS5": "syscall",
+ "syscall.CS6": "syscall",
+ "syscall.CS7": "syscall",
+ "syscall.CS8": "syscall",
+ "syscall.CSIZE": "syscall",
+ "syscall.CSTART": "syscall",
+ "syscall.CSTATUS": "syscall",
+ "syscall.CSTOP": "syscall",
+ "syscall.CSTOPB": "syscall",
+ "syscall.CSUSP": "syscall",
+ "syscall.CTL_MAXNAME": "syscall",
+ "syscall.CTL_NET": "syscall",
+ "syscall.CTL_QUERY": "syscall",
+ "syscall.CTRL_BREAK_EVENT": "syscall",
+ "syscall.CTRL_C_EVENT": "syscall",
+ "syscall.CancelIo": "syscall",
+ "syscall.CancelIoEx": "syscall",
+ "syscall.CertAddCertificateContextToStore": "syscall",
+ "syscall.CertChainContext": "syscall",
+ "syscall.CertChainElement": "syscall",
+ "syscall.CertChainPara": "syscall",
+ "syscall.CertChainPolicyPara": "syscall",
+ "syscall.CertChainPolicyStatus": "syscall",
+ "syscall.CertCloseStore": "syscall",
+ "syscall.CertContext": "syscall",
+ "syscall.CertCreateCertificateContext": "syscall",
+ "syscall.CertEnhKeyUsage": "syscall",
+ "syscall.CertEnumCertificatesInStore": "syscall",
+ "syscall.CertFreeCertificateChain": "syscall",
+ "syscall.CertFreeCertificateContext": "syscall",
+ "syscall.CertGetCertificateChain": "syscall",
+ "syscall.CertOpenStore": "syscall",
+ "syscall.CertOpenSystemStore": "syscall",
+ "syscall.CertRevocationInfo": "syscall",
+ "syscall.CertSimpleChain": "syscall",
+ "syscall.CertTrustStatus": "syscall",
+ "syscall.CertUsageMatch": "syscall",
+ "syscall.CertVerifyCertificateChainPolicy": "syscall",
+ "syscall.Chdir": "syscall",
+ "syscall.CheckBpfVersion": "syscall",
+ "syscall.Chflags": "syscall",
+ "syscall.Chmod": "syscall",
+ "syscall.Chown": "syscall",
+ "syscall.Chroot": "syscall",
+ "syscall.Clearenv": "syscall",
+ "syscall.Close": "syscall",
+ "syscall.CloseHandle": "syscall",
+ "syscall.CloseOnExec": "syscall",
+ "syscall.Closesocket": "syscall",
+ "syscall.CmsgLen": "syscall",
+ "syscall.CmsgSpace": "syscall",
+ "syscall.Cmsghdr": "syscall",
+ "syscall.CommandLineToArgv": "syscall",
+ "syscall.ComputerName": "syscall",
+ "syscall.Connect": "syscall",
+ "syscall.ConnectEx": "syscall",
+ "syscall.ConvertSidToStringSid": "syscall",
+ "syscall.ConvertStringSidToSid": "syscall",
+ "syscall.CopySid": "syscall",
+ "syscall.Creat": "syscall",
+ "syscall.CreateDirectory": "syscall",
+ "syscall.CreateFile": "syscall",
+ "syscall.CreateFileMapping": "syscall",
+ "syscall.CreateIoCompletionPort": "syscall",
+ "syscall.CreatePipe": "syscall",
+ "syscall.CreateProcess": "syscall",
+ "syscall.Credential": "syscall",
+ "syscall.CryptAcquireContext": "syscall",
+ "syscall.CryptGenRandom": "syscall",
+ "syscall.CryptReleaseContext": "syscall",
+ "syscall.DIOCBSFLUSH": "syscall",
+ "syscall.DIOCOSFPFLUSH": "syscall",
+ "syscall.DLL": "syscall",
+ "syscall.DLLError": "syscall",
+ "syscall.DLT_A429": "syscall",
+ "syscall.DLT_A653_ICM": "syscall",
+ "syscall.DLT_AIRONET_HEADER": "syscall",
+ "syscall.DLT_AOS": "syscall",
+ "syscall.DLT_APPLE_IP_OVER_IEEE1394": "syscall",
+ "syscall.DLT_ARCNET": "syscall",
+ "syscall.DLT_ARCNET_LINUX": "syscall",
+ "syscall.DLT_ATM_CLIP": "syscall",
+ "syscall.DLT_ATM_RFC1483": "syscall",
+ "syscall.DLT_AURORA": "syscall",
+ "syscall.DLT_AX25": "syscall",
+ "syscall.DLT_AX25_KISS": "syscall",
+ "syscall.DLT_BACNET_MS_TP": "syscall",
+ "syscall.DLT_BLUETOOTH_HCI_H4": "syscall",
+ "syscall.DLT_BLUETOOTH_HCI_H4_WITH_PHDR": "syscall",
+ "syscall.DLT_CAN20B": "syscall",
+ "syscall.DLT_CAN_SOCKETCAN": "syscall",
+ "syscall.DLT_CHAOS": "syscall",
+ "syscall.DLT_CHDLC": "syscall",
+ "syscall.DLT_CISCO_IOS": "syscall",
+ "syscall.DLT_C_HDLC": "syscall",
+ "syscall.DLT_C_HDLC_WITH_DIR": "syscall",
+ "syscall.DLT_DBUS": "syscall",
+ "syscall.DLT_DECT": "syscall",
+ "syscall.DLT_DOCSIS": "syscall",
+ "syscall.DLT_DVB_CI": "syscall",
+ "syscall.DLT_ECONET": "syscall",
+ "syscall.DLT_EN10MB": "syscall",
+ "syscall.DLT_EN3MB": "syscall",
+ "syscall.DLT_ENC": "syscall",
+ "syscall.DLT_ERF": "syscall",
+ "syscall.DLT_ERF_ETH": "syscall",
+ "syscall.DLT_ERF_POS": "syscall",
+ "syscall.DLT_FC_2": "syscall",
+ "syscall.DLT_FC_2_WITH_FRAME_DELIMS": "syscall",
+ "syscall.DLT_FDDI": "syscall",
+ "syscall.DLT_FLEXRAY": "syscall",
+ "syscall.DLT_FRELAY": "syscall",
+ "syscall.DLT_FRELAY_WITH_DIR": "syscall",
+ "syscall.DLT_GCOM_SERIAL": "syscall",
+ "syscall.DLT_GCOM_T1E1": "syscall",
+ "syscall.DLT_GPF_F": "syscall",
+ "syscall.DLT_GPF_T": "syscall",
+ "syscall.DLT_GPRS_LLC": "syscall",
+ "syscall.DLT_GSMTAP_ABIS": "syscall",
+ "syscall.DLT_GSMTAP_UM": "syscall",
+ "syscall.DLT_HDLC": "syscall",
+ "syscall.DLT_HHDLC": "syscall",
+ "syscall.DLT_HIPPI": "syscall",
+ "syscall.DLT_IBM_SN": "syscall",
+ "syscall.DLT_IBM_SP": "syscall",
+ "syscall.DLT_IEEE802": "syscall",
+ "syscall.DLT_IEEE802_11": "syscall",
+ "syscall.DLT_IEEE802_11_RADIO": "syscall",
+ "syscall.DLT_IEEE802_11_RADIO_AVS": "syscall",
+ "syscall.DLT_IEEE802_15_4": "syscall",
+ "syscall.DLT_IEEE802_15_4_LINUX": "syscall",
+ "syscall.DLT_IEEE802_15_4_NOFCS": "syscall",
+ "syscall.DLT_IEEE802_15_4_NONASK_PHY": "syscall",
+ "syscall.DLT_IEEE802_16_MAC_CPS": "syscall",
+ "syscall.DLT_IEEE802_16_MAC_CPS_RADIO": "syscall",
+ "syscall.DLT_IPFILTER": "syscall",
+ "syscall.DLT_IPMB": "syscall",
+ "syscall.DLT_IPMB_LINUX": "syscall",
+ "syscall.DLT_IPNET": "syscall",
+ "syscall.DLT_IPOIB": "syscall",
+ "syscall.DLT_IPV4": "syscall",
+ "syscall.DLT_IPV6": "syscall",
+ "syscall.DLT_IP_OVER_FC": "syscall",
+ "syscall.DLT_JUNIPER_ATM1": "syscall",
+ "syscall.DLT_JUNIPER_ATM2": "syscall",
+ "syscall.DLT_JUNIPER_ATM_CEMIC": "syscall",
+ "syscall.DLT_JUNIPER_CHDLC": "syscall",
+ "syscall.DLT_JUNIPER_ES": "syscall",
+ "syscall.DLT_JUNIPER_ETHER": "syscall",
+ "syscall.DLT_JUNIPER_FIBRECHANNEL": "syscall",
+ "syscall.DLT_JUNIPER_FRELAY": "syscall",
+ "syscall.DLT_JUNIPER_GGSN": "syscall",
+ "syscall.DLT_JUNIPER_ISM": "syscall",
+ "syscall.DLT_JUNIPER_MFR": "syscall",
+ "syscall.DLT_JUNIPER_MLFR": "syscall",
+ "syscall.DLT_JUNIPER_MLPPP": "syscall",
+ "syscall.DLT_JUNIPER_MONITOR": "syscall",
+ "syscall.DLT_JUNIPER_PIC_PEER": "syscall",
+ "syscall.DLT_JUNIPER_PPP": "syscall",
+ "syscall.DLT_JUNIPER_PPPOE": "syscall",
+ "syscall.DLT_JUNIPER_PPPOE_ATM": "syscall",
+ "syscall.DLT_JUNIPER_SERVICES": "syscall",
+ "syscall.DLT_JUNIPER_SRX_E2E": "syscall",
+ "syscall.DLT_JUNIPER_ST": "syscall",
+ "syscall.DLT_JUNIPER_VP": "syscall",
+ "syscall.DLT_JUNIPER_VS": "syscall",
+ "syscall.DLT_LAPB_WITH_DIR": "syscall",
+ "syscall.DLT_LAPD": "syscall",
+ "syscall.DLT_LIN": "syscall",
+ "syscall.DLT_LINUX_EVDEV": "syscall",
+ "syscall.DLT_LINUX_IRDA": "syscall",
+ "syscall.DLT_LINUX_LAPD": "syscall",
+ "syscall.DLT_LINUX_PPP_WITHDIRECTION": "syscall",
+ "syscall.DLT_LINUX_SLL": "syscall",
+ "syscall.DLT_LOOP": "syscall",
+ "syscall.DLT_LTALK": "syscall",
+ "syscall.DLT_MATCHING_MAX": "syscall",
+ "syscall.DLT_MATCHING_MIN": "syscall",
+ "syscall.DLT_MFR": "syscall",
+ "syscall.DLT_MOST": "syscall",
+ "syscall.DLT_MPEG_2_TS": "syscall",
+ "syscall.DLT_MPLS": "syscall",
+ "syscall.DLT_MTP2": "syscall",
+ "syscall.DLT_MTP2_WITH_PHDR": "syscall",
+ "syscall.DLT_MTP3": "syscall",
+ "syscall.DLT_MUX27010": "syscall",
+ "syscall.DLT_NETANALYZER": "syscall",
+ "syscall.DLT_NETANALYZER_TRANSPARENT": "syscall",
+ "syscall.DLT_NFC_LLCP": "syscall",
+ "syscall.DLT_NFLOG": "syscall",
+ "syscall.DLT_NG40": "syscall",
+ "syscall.DLT_NULL": "syscall",
+ "syscall.DLT_PCI_EXP": "syscall",
+ "syscall.DLT_PFLOG": "syscall",
+ "syscall.DLT_PFSYNC": "syscall",
+ "syscall.DLT_PPI": "syscall",
+ "syscall.DLT_PPP": "syscall",
+ "syscall.DLT_PPP_BSDOS": "syscall",
+ "syscall.DLT_PPP_ETHER": "syscall",
+ "syscall.DLT_PPP_PPPD": "syscall",
+ "syscall.DLT_PPP_SERIAL": "syscall",
+ "syscall.DLT_PPP_WITH_DIR": "syscall",
+ "syscall.DLT_PPP_WITH_DIRECTION": "syscall",
+ "syscall.DLT_PRISM_HEADER": "syscall",
+ "syscall.DLT_PRONET": "syscall",
+ "syscall.DLT_RAIF1": "syscall",
+ "syscall.DLT_RAW": "syscall",
+ "syscall.DLT_RAWAF_MASK": "syscall",
+ "syscall.DLT_RIO": "syscall",
+ "syscall.DLT_SCCP": "syscall",
+ "syscall.DLT_SITA": "syscall",
+ "syscall.DLT_SLIP": "syscall",
+ "syscall.DLT_SLIP_BSDOS": "syscall",
+ "syscall.DLT_STANAG_5066_D_PDU": "syscall",
+ "syscall.DLT_SUNATM": "syscall",
+ "syscall.DLT_SYMANTEC_FIREWALL": "syscall",
+ "syscall.DLT_TZSP": "syscall",
+ "syscall.DLT_USB": "syscall",
+ "syscall.DLT_USB_LINUX": "syscall",
+ "syscall.DLT_USB_LINUX_MMAPPED": "syscall",
+ "syscall.DLT_USER0": "syscall",
+ "syscall.DLT_USER1": "syscall",
+ "syscall.DLT_USER10": "syscall",
+ "syscall.DLT_USER11": "syscall",
+ "syscall.DLT_USER12": "syscall",
+ "syscall.DLT_USER13": "syscall",
+ "syscall.DLT_USER14": "syscall",
+ "syscall.DLT_USER15": "syscall",
+ "syscall.DLT_USER2": "syscall",
+ "syscall.DLT_USER3": "syscall",
+ "syscall.DLT_USER4": "syscall",
+ "syscall.DLT_USER5": "syscall",
+ "syscall.DLT_USER6": "syscall",
+ "syscall.DLT_USER7": "syscall",
+ "syscall.DLT_USER8": "syscall",
+ "syscall.DLT_USER9": "syscall",
+ "syscall.DLT_WIHART": "syscall",
+ "syscall.DLT_X2E_SERIAL": "syscall",
+ "syscall.DLT_X2E_XORAYA": "syscall",
+ "syscall.DNSMXData": "syscall",
+ "syscall.DNSPTRData": "syscall",
+ "syscall.DNSRecord": "syscall",
+ "syscall.DNSSRVData": "syscall",
+ "syscall.DNSTXTData": "syscall",
+ "syscall.DNS_TYPE_A": "syscall",
+ "syscall.DNS_TYPE_A6": "syscall",
+ "syscall.DNS_TYPE_AAAA": "syscall",
+ "syscall.DNS_TYPE_ADDRS": "syscall",
+ "syscall.DNS_TYPE_AFSDB": "syscall",
+ "syscall.DNS_TYPE_ALL": "syscall",
+ "syscall.DNS_TYPE_ANY": "syscall",
+ "syscall.DNS_TYPE_ATMA": "syscall",
+ "syscall.DNS_TYPE_AXFR": "syscall",
+ "syscall.DNS_TYPE_CERT": "syscall",
+ "syscall.DNS_TYPE_CNAME": "syscall",
+ "syscall.DNS_TYPE_DHCID": "syscall",
+ "syscall.DNS_TYPE_DNAME": "syscall",
+ "syscall.DNS_TYPE_DNSKEY": "syscall",
+ "syscall.DNS_TYPE_DS": "syscall",
+ "syscall.DNS_TYPE_EID": "syscall",
+ "syscall.DNS_TYPE_GID": "syscall",
+ "syscall.DNS_TYPE_GPOS": "syscall",
+ "syscall.DNS_TYPE_HINFO": "syscall",
+ "syscall.DNS_TYPE_ISDN": "syscall",
+ "syscall.DNS_TYPE_IXFR": "syscall",
+ "syscall.DNS_TYPE_KEY": "syscall",
+ "syscall.DNS_TYPE_KX": "syscall",
+ "syscall.DNS_TYPE_LOC": "syscall",
+ "syscall.DNS_TYPE_MAILA": "syscall",
+ "syscall.DNS_TYPE_MAILB": "syscall",
+ "syscall.DNS_TYPE_MB": "syscall",
+ "syscall.DNS_TYPE_MD": "syscall",
+ "syscall.DNS_TYPE_MF": "syscall",
+ "syscall.DNS_TYPE_MG": "syscall",
+ "syscall.DNS_TYPE_MINFO": "syscall",
+ "syscall.DNS_TYPE_MR": "syscall",
+ "syscall.DNS_TYPE_MX": "syscall",
+ "syscall.DNS_TYPE_NAPTR": "syscall",
+ "syscall.DNS_TYPE_NBSTAT": "syscall",
+ "syscall.DNS_TYPE_NIMLOC": "syscall",
+ "syscall.DNS_TYPE_NS": "syscall",
+ "syscall.DNS_TYPE_NSAP": "syscall",
+ "syscall.DNS_TYPE_NSAPPTR": "syscall",
+ "syscall.DNS_TYPE_NSEC": "syscall",
+ "syscall.DNS_TYPE_NULL": "syscall",
+ "syscall.DNS_TYPE_NXT": "syscall",
+ "syscall.DNS_TYPE_OPT": "syscall",
+ "syscall.DNS_TYPE_PTR": "syscall",
+ "syscall.DNS_TYPE_PX": "syscall",
+ "syscall.DNS_TYPE_RP": "syscall",
+ "syscall.DNS_TYPE_RRSIG": "syscall",
+ "syscall.DNS_TYPE_RT": "syscall",
+ "syscall.DNS_TYPE_SIG": "syscall",
+ "syscall.DNS_TYPE_SINK": "syscall",
+ "syscall.DNS_TYPE_SOA": "syscall",
+ "syscall.DNS_TYPE_SRV": "syscall",
+ "syscall.DNS_TYPE_TEXT": "syscall",
+ "syscall.DNS_TYPE_TKEY": "syscall",
+ "syscall.DNS_TYPE_TSIG": "syscall",
+ "syscall.DNS_TYPE_UID": "syscall",
+ "syscall.DNS_TYPE_UINFO": "syscall",
+ "syscall.DNS_TYPE_UNSPEC": "syscall",
+ "syscall.DNS_TYPE_WINS": "syscall",
+ "syscall.DNS_TYPE_WINSR": "syscall",
+ "syscall.DNS_TYPE_WKS": "syscall",
+ "syscall.DNS_TYPE_X25": "syscall",
+ "syscall.DT_BLK": "syscall",
+ "syscall.DT_CHR": "syscall",
+ "syscall.DT_DIR": "syscall",
+ "syscall.DT_FIFO": "syscall",
+ "syscall.DT_LNK": "syscall",
+ "syscall.DT_REG": "syscall",
+ "syscall.DT_SOCK": "syscall",
+ "syscall.DT_UNKNOWN": "syscall",
+ "syscall.DT_WHT": "syscall",
+ "syscall.DUPLICATE_CLOSE_SOURCE": "syscall",
+ "syscall.DUPLICATE_SAME_ACCESS": "syscall",
+ "syscall.DeleteFile": "syscall",
+ "syscall.DetachLsf": "syscall",
+ "syscall.Dirent": "syscall",
+ "syscall.DnsQuery": "syscall",
+ "syscall.DnsRecordListFree": "syscall",
+ "syscall.Dup": "syscall",
+ "syscall.Dup2": "syscall",
+ "syscall.Dup3": "syscall",
+ "syscall.DuplicateHandle": "syscall",
+ "syscall.E2BIG": "syscall",
+ "syscall.EACCES": "syscall",
+ "syscall.EADDRINUSE": "syscall",
+ "syscall.EADDRNOTAVAIL": "syscall",
+ "syscall.EADV": "syscall",
+ "syscall.EAFNOSUPPORT": "syscall",
+ "syscall.EAGAIN": "syscall",
+ "syscall.EALREADY": "syscall",
+ "syscall.EAUTH": "syscall",
+ "syscall.EBADARCH": "syscall",
+ "syscall.EBADE": "syscall",
+ "syscall.EBADEXEC": "syscall",
+ "syscall.EBADF": "syscall",
+ "syscall.EBADFD": "syscall",
+ "syscall.EBADMACHO": "syscall",
+ "syscall.EBADMSG": "syscall",
+ "syscall.EBADR": "syscall",
+ "syscall.EBADRPC": "syscall",
+ "syscall.EBADRQC": "syscall",
+ "syscall.EBADSLT": "syscall",
+ "syscall.EBFONT": "syscall",
+ "syscall.EBUSY": "syscall",
+ "syscall.ECANCELED": "syscall",
+ "syscall.ECAPMODE": "syscall",
+ "syscall.ECHILD": "syscall",
+ "syscall.ECHO": "syscall",
+ "syscall.ECHOCTL": "syscall",
+ "syscall.ECHOE": "syscall",
+ "syscall.ECHOK": "syscall",
+ "syscall.ECHOKE": "syscall",
+ "syscall.ECHONL": "syscall",
+ "syscall.ECHOPRT": "syscall",
+ "syscall.ECHRNG": "syscall",
+ "syscall.ECOMM": "syscall",
+ "syscall.ECONNABORTED": "syscall",
+ "syscall.ECONNREFUSED": "syscall",
+ "syscall.ECONNRESET": "syscall",
+ "syscall.EDEADLK": "syscall",
+ "syscall.EDEADLOCK": "syscall",
+ "syscall.EDESTADDRREQ": "syscall",
+ "syscall.EDEVERR": "syscall",
+ "syscall.EDOM": "syscall",
+ "syscall.EDOOFUS": "syscall",
+ "syscall.EDOTDOT": "syscall",
+ "syscall.EDQUOT": "syscall",
+ "syscall.EEXIST": "syscall",
+ "syscall.EFAULT": "syscall",
+ "syscall.EFBIG": "syscall",
+ "syscall.EFER_LMA": "syscall",
+ "syscall.EFER_LME": "syscall",
+ "syscall.EFER_NXE": "syscall",
+ "syscall.EFER_SCE": "syscall",
+ "syscall.EFTYPE": "syscall",
+ "syscall.EHOSTDOWN": "syscall",
+ "syscall.EHOSTUNREACH": "syscall",
+ "syscall.EHWPOISON": "syscall",
+ "syscall.EIDRM": "syscall",
+ "syscall.EILSEQ": "syscall",
+ "syscall.EINPROGRESS": "syscall",
+ "syscall.EINTR": "syscall",
+ "syscall.EINVAL": "syscall",
+ "syscall.EIO": "syscall",
+ "syscall.EIPSEC": "syscall",
+ "syscall.EISCONN": "syscall",
+ "syscall.EISDIR": "syscall",
+ "syscall.EISNAM": "syscall",
+ "syscall.EKEYEXPIRED": "syscall",
+ "syscall.EKEYREJECTED": "syscall",
+ "syscall.EKEYREVOKED": "syscall",
+ "syscall.EL2HLT": "syscall",
+ "syscall.EL2NSYNC": "syscall",
+ "syscall.EL3HLT": "syscall",
+ "syscall.EL3RST": "syscall",
+ "syscall.ELAST": "syscall",
+ "syscall.ELF_NGREG": "syscall",
+ "syscall.ELF_PRARGSZ": "syscall",
+ "syscall.ELIBACC": "syscall",
+ "syscall.ELIBBAD": "syscall",
+ "syscall.ELIBEXEC": "syscall",
+ "syscall.ELIBMAX": "syscall",
+ "syscall.ELIBSCN": "syscall",
+ "syscall.ELNRNG": "syscall",
+ "syscall.ELOOP": "syscall",
+ "syscall.EMEDIUMTYPE": "syscall",
+ "syscall.EMFILE": "syscall",
+ "syscall.EMLINK": "syscall",
+ "syscall.EMSGSIZE": "syscall",
+ "syscall.EMT_TAGOVF": "syscall",
+ "syscall.EMULTIHOP": "syscall",
+ "syscall.EMUL_ENABLED": "syscall",
+ "syscall.EMUL_LINUX": "syscall",
+ "syscall.EMUL_LINUX32": "syscall",
+ "syscall.EMUL_MAXID": "syscall",
+ "syscall.EMUL_NATIVE": "syscall",
+ "syscall.ENAMETOOLONG": "syscall",
+ "syscall.ENAVAIL": "syscall",
+ "syscall.ENDRUNDISC": "syscall",
+ "syscall.ENEEDAUTH": "syscall",
+ "syscall.ENETDOWN": "syscall",
+ "syscall.ENETRESET": "syscall",
+ "syscall.ENETUNREACH": "syscall",
+ "syscall.ENFILE": "syscall",
+ "syscall.ENOANO": "syscall",
+ "syscall.ENOATTR": "syscall",
+ "syscall.ENOBUFS": "syscall",
+ "syscall.ENOCSI": "syscall",
+ "syscall.ENODATA": "syscall",
+ "syscall.ENODEV": "syscall",
+ "syscall.ENOENT": "syscall",
+ "syscall.ENOEXEC": "syscall",
+ "syscall.ENOKEY": "syscall",
+ "syscall.ENOLCK": "syscall",
+ "syscall.ENOLINK": "syscall",
+ "syscall.ENOMEDIUM": "syscall",
+ "syscall.ENOMEM": "syscall",
+ "syscall.ENOMSG": "syscall",
+ "syscall.ENONET": "syscall",
+ "syscall.ENOPKG": "syscall",
+ "syscall.ENOPOLICY": "syscall",
+ "syscall.ENOPROTOOPT": "syscall",
+ "syscall.ENOSPC": "syscall",
+ "syscall.ENOSR": "syscall",
+ "syscall.ENOSTR": "syscall",
+ "syscall.ENOSYS": "syscall",
+ "syscall.ENOTBLK": "syscall",
+ "syscall.ENOTCAPABLE": "syscall",
+ "syscall.ENOTCONN": "syscall",
+ "syscall.ENOTDIR": "syscall",
+ "syscall.ENOTEMPTY": "syscall",
+ "syscall.ENOTNAM": "syscall",
+ "syscall.ENOTRECOVERABLE": "syscall",
+ "syscall.ENOTSOCK": "syscall",
+ "syscall.ENOTSUP": "syscall",
+ "syscall.ENOTTY": "syscall",
+ "syscall.ENOTUNIQ": "syscall",
+ "syscall.ENXIO": "syscall",
+ "syscall.EN_SW_CTL_INF": "syscall",
+ "syscall.EN_SW_CTL_PREC": "syscall",
+ "syscall.EN_SW_CTL_ROUND": "syscall",
+ "syscall.EN_SW_DATACHAIN": "syscall",
+ "syscall.EN_SW_DENORM": "syscall",
+ "syscall.EN_SW_INVOP": "syscall",
+ "syscall.EN_SW_OVERFLOW": "syscall",
+ "syscall.EN_SW_PRECLOSS": "syscall",
+ "syscall.EN_SW_UNDERFLOW": "syscall",
+ "syscall.EN_SW_ZERODIV": "syscall",
+ "syscall.EOPNOTSUPP": "syscall",
+ "syscall.EOVERFLOW": "syscall",
+ "syscall.EOWNERDEAD": "syscall",
+ "syscall.EPERM": "syscall",
+ "syscall.EPFNOSUPPORT": "syscall",
+ "syscall.EPIPE": "syscall",
+ "syscall.EPOLLERR": "syscall",
+ "syscall.EPOLLET": "syscall",
+ "syscall.EPOLLHUP": "syscall",
+ "syscall.EPOLLIN": "syscall",
+ "syscall.EPOLLMSG": "syscall",
+ "syscall.EPOLLONESHOT": "syscall",
+ "syscall.EPOLLOUT": "syscall",
+ "syscall.EPOLLPRI": "syscall",
+ "syscall.EPOLLRDBAND": "syscall",
+ "syscall.EPOLLRDHUP": "syscall",
+ "syscall.EPOLLRDNORM": "syscall",
+ "syscall.EPOLLWRBAND": "syscall",
+ "syscall.EPOLLWRNORM": "syscall",
+ "syscall.EPOLL_CLOEXEC": "syscall",
+ "syscall.EPOLL_CTL_ADD": "syscall",
+ "syscall.EPOLL_CTL_DEL": "syscall",
+ "syscall.EPOLL_CTL_MOD": "syscall",
+ "syscall.EPOLL_NONBLOCK": "syscall",
+ "syscall.EPROCLIM": "syscall",
+ "syscall.EPROCUNAVAIL": "syscall",
+ "syscall.EPROGMISMATCH": "syscall",
+ "syscall.EPROGUNAVAIL": "syscall",
+ "syscall.EPROTO": "syscall",
+ "syscall.EPROTONOSUPPORT": "syscall",
+ "syscall.EPROTOTYPE": "syscall",
+ "syscall.EPWROFF": "syscall",
+ "syscall.ERANGE": "syscall",
+ "syscall.EREMCHG": "syscall",
+ "syscall.EREMOTE": "syscall",
+ "syscall.EREMOTEIO": "syscall",
+ "syscall.ERESTART": "syscall",
+ "syscall.ERFKILL": "syscall",
+ "syscall.EROFS": "syscall",
+ "syscall.ERPCMISMATCH": "syscall",
+ "syscall.ERROR_ACCESS_DENIED": "syscall",
+ "syscall.ERROR_ALREADY_EXISTS": "syscall",
+ "syscall.ERROR_BROKEN_PIPE": "syscall",
+ "syscall.ERROR_BUFFER_OVERFLOW": "syscall",
+ "syscall.ERROR_ENVVAR_NOT_FOUND": "syscall",
+ "syscall.ERROR_FILE_EXISTS": "syscall",
+ "syscall.ERROR_FILE_NOT_FOUND": "syscall",
+ "syscall.ERROR_HANDLE_EOF": "syscall",
+ "syscall.ERROR_INSUFFICIENT_BUFFER": "syscall",
+ "syscall.ERROR_IO_PENDING": "syscall",
+ "syscall.ERROR_MOD_NOT_FOUND": "syscall",
+ "syscall.ERROR_MORE_DATA": "syscall",
+ "syscall.ERROR_NETNAME_DELETED": "syscall",
+ "syscall.ERROR_NOT_FOUND": "syscall",
+ "syscall.ERROR_NO_MORE_FILES": "syscall",
+ "syscall.ERROR_OPERATION_ABORTED": "syscall",
+ "syscall.ERROR_PATH_NOT_FOUND": "syscall",
+ "syscall.ERROR_PROC_NOT_FOUND": "syscall",
+ "syscall.ESHLIBVERS": "syscall",
+ "syscall.ESHUTDOWN": "syscall",
+ "syscall.ESOCKTNOSUPPORT": "syscall",
+ "syscall.ESPIPE": "syscall",
+ "syscall.ESRCH": "syscall",
+ "syscall.ESRMNT": "syscall",
+ "syscall.ESTALE": "syscall",
+ "syscall.ESTRPIPE": "syscall",
+ "syscall.ETHERCAP_JUMBO_MTU": "syscall",
+ "syscall.ETHERCAP_VLAN_HWTAGGING": "syscall",
+ "syscall.ETHERCAP_VLAN_MTU": "syscall",
+ "syscall.ETHERMIN": "syscall",
+ "syscall.ETHERMTU": "syscall",
+ "syscall.ETHERMTU_JUMBO": "syscall",
+ "syscall.ETHERTYPE_8023": "syscall",
+ "syscall.ETHERTYPE_AARP": "syscall",
+ "syscall.ETHERTYPE_ACCTON": "syscall",
+ "syscall.ETHERTYPE_AEONIC": "syscall",
+ "syscall.ETHERTYPE_ALPHA": "syscall",
+ "syscall.ETHERTYPE_AMBER": "syscall",
+ "syscall.ETHERTYPE_AMOEBA": "syscall",
+ "syscall.ETHERTYPE_AOE": "syscall",
+ "syscall.ETHERTYPE_APOLLO": "syscall",
+ "syscall.ETHERTYPE_APOLLODOMAIN": "syscall",
+ "syscall.ETHERTYPE_APPLETALK": "syscall",
+ "syscall.ETHERTYPE_APPLITEK": "syscall",
+ "syscall.ETHERTYPE_ARGONAUT": "syscall",
+ "syscall.ETHERTYPE_ARP": "syscall",
+ "syscall.ETHERTYPE_AT": "syscall",
+ "syscall.ETHERTYPE_ATALK": "syscall",
+ "syscall.ETHERTYPE_ATOMIC": "syscall",
+ "syscall.ETHERTYPE_ATT": "syscall",
+ "syscall.ETHERTYPE_ATTSTANFORD": "syscall",
+ "syscall.ETHERTYPE_AUTOPHON": "syscall",
+ "syscall.ETHERTYPE_AXIS": "syscall",
+ "syscall.ETHERTYPE_BCLOOP": "syscall",
+ "syscall.ETHERTYPE_BOFL": "syscall",
+ "syscall.ETHERTYPE_CABLETRON": "syscall",
+ "syscall.ETHERTYPE_CHAOS": "syscall",
+ "syscall.ETHERTYPE_COMDESIGN": "syscall",
+ "syscall.ETHERTYPE_COMPUGRAPHIC": "syscall",
+ "syscall.ETHERTYPE_COUNTERPOINT": "syscall",
+ "syscall.ETHERTYPE_CRONUS": "syscall",
+ "syscall.ETHERTYPE_CRONUSVLN": "syscall",
+ "syscall.ETHERTYPE_DCA": "syscall",
+ "syscall.ETHERTYPE_DDE": "syscall",
+ "syscall.ETHERTYPE_DEBNI": "syscall",
+ "syscall.ETHERTYPE_DECAM": "syscall",
+ "syscall.ETHERTYPE_DECCUST": "syscall",
+ "syscall.ETHERTYPE_DECDIAG": "syscall",
+ "syscall.ETHERTYPE_DECDNS": "syscall",
+ "syscall.ETHERTYPE_DECDTS": "syscall",
+ "syscall.ETHERTYPE_DECEXPER": "syscall",
+ "syscall.ETHERTYPE_DECLAST": "syscall",
+ "syscall.ETHERTYPE_DECLTM": "syscall",
+ "syscall.ETHERTYPE_DECMUMPS": "syscall",
+ "syscall.ETHERTYPE_DECNETBIOS": "syscall",
+ "syscall.ETHERTYPE_DELTACON": "syscall",
+ "syscall.ETHERTYPE_DIDDLE": "syscall",
+ "syscall.ETHERTYPE_DLOG1": "syscall",
+ "syscall.ETHERTYPE_DLOG2": "syscall",
+ "syscall.ETHERTYPE_DN": "syscall",
+ "syscall.ETHERTYPE_DOGFIGHT": "syscall",
+ "syscall.ETHERTYPE_DSMD": "syscall",
+ "syscall.ETHERTYPE_ECMA": "syscall",
+ "syscall.ETHERTYPE_ENCRYPT": "syscall",
+ "syscall.ETHERTYPE_ES": "syscall",
+ "syscall.ETHERTYPE_EXCELAN": "syscall",
+ "syscall.ETHERTYPE_EXPERDATA": "syscall",
+ "syscall.ETHERTYPE_FLIP": "syscall",
+ "syscall.ETHERTYPE_FLOWCONTROL": "syscall",
+ "syscall.ETHERTYPE_FRARP": "syscall",
+ "syscall.ETHERTYPE_GENDYN": "syscall",
+ "syscall.ETHERTYPE_HAYES": "syscall",
+ "syscall.ETHERTYPE_HIPPI_FP": "syscall",
+ "syscall.ETHERTYPE_HITACHI": "syscall",
+ "syscall.ETHERTYPE_HP": "syscall",
+ "syscall.ETHERTYPE_IEEEPUP": "syscall",
+ "syscall.ETHERTYPE_IEEEPUPAT": "syscall",
+ "syscall.ETHERTYPE_IMLBL": "syscall",
+ "syscall.ETHERTYPE_IMLBLDIAG": "syscall",
+ "syscall.ETHERTYPE_IP": "syscall",
+ "syscall.ETHERTYPE_IPAS": "syscall",
+ "syscall.ETHERTYPE_IPV6": "syscall",
+ "syscall.ETHERTYPE_IPX": "syscall",
+ "syscall.ETHERTYPE_IPXNEW": "syscall",
+ "syscall.ETHERTYPE_KALPANA": "syscall",
+ "syscall.ETHERTYPE_LANBRIDGE": "syscall",
+ "syscall.ETHERTYPE_LANPROBE": "syscall",
+ "syscall.ETHERTYPE_LAT": "syscall",
+ "syscall.ETHERTYPE_LBACK": "syscall",
+ "syscall.ETHERTYPE_LITTLE": "syscall",
+ "syscall.ETHERTYPE_LLDP": "syscall",
+ "syscall.ETHERTYPE_LOGICRAFT": "syscall",
+ "syscall.ETHERTYPE_LOOPBACK": "syscall",
+ "syscall.ETHERTYPE_MATRA": "syscall",
+ "syscall.ETHERTYPE_MAX": "syscall",
+ "syscall.ETHERTYPE_MERIT": "syscall",
+ "syscall.ETHERTYPE_MICP": "syscall",
+ "syscall.ETHERTYPE_MOPDL": "syscall",
+ "syscall.ETHERTYPE_MOPRC": "syscall",
+ "syscall.ETHERTYPE_MOTOROLA": "syscall",
+ "syscall.ETHERTYPE_MPLS": "syscall",
+ "syscall.ETHERTYPE_MPLS_MCAST": "syscall",
+ "syscall.ETHERTYPE_MUMPS": "syscall",
+ "syscall.ETHERTYPE_NBPCC": "syscall",
+ "syscall.ETHERTYPE_NBPCLAIM": "syscall",
+ "syscall.ETHERTYPE_NBPCLREQ": "syscall",
+ "syscall.ETHERTYPE_NBPCLRSP": "syscall",
+ "syscall.ETHERTYPE_NBPCREQ": "syscall",
+ "syscall.ETHERTYPE_NBPCRSP": "syscall",
+ "syscall.ETHERTYPE_NBPDG": "syscall",
+ "syscall.ETHERTYPE_NBPDGB": "syscall",
+ "syscall.ETHERTYPE_NBPDLTE": "syscall",
+ "syscall.ETHERTYPE_NBPRAR": "syscall",
+ "syscall.ETHERTYPE_NBPRAS": "syscall",
+ "syscall.ETHERTYPE_NBPRST": "syscall",
+ "syscall.ETHERTYPE_NBPSCD": "syscall",
+ "syscall.ETHERTYPE_NBPVCD": "syscall",
+ "syscall.ETHERTYPE_NBS": "syscall",
+ "syscall.ETHERTYPE_NCD": "syscall",
+ "syscall.ETHERTYPE_NESTAR": "syscall",
+ "syscall.ETHERTYPE_NETBEUI": "syscall",
+ "syscall.ETHERTYPE_NOVELL": "syscall",
+ "syscall.ETHERTYPE_NS": "syscall",
+ "syscall.ETHERTYPE_NSAT": "syscall",
+ "syscall.ETHERTYPE_NSCOMPAT": "syscall",
+ "syscall.ETHERTYPE_NTRAILER": "syscall",
+ "syscall.ETHERTYPE_OS9": "syscall",
+ "syscall.ETHERTYPE_OS9NET": "syscall",
+ "syscall.ETHERTYPE_PACER": "syscall",
+ "syscall.ETHERTYPE_PAE": "syscall",
+ "syscall.ETHERTYPE_PCS": "syscall",
+ "syscall.ETHERTYPE_PLANNING": "syscall",
+ "syscall.ETHERTYPE_PPP": "syscall",
+ "syscall.ETHERTYPE_PPPOE": "syscall",
+ "syscall.ETHERTYPE_PPPOEDISC": "syscall",
+ "syscall.ETHERTYPE_PRIMENTS": "syscall",
+ "syscall.ETHERTYPE_PUP": "syscall",
+ "syscall.ETHERTYPE_PUPAT": "syscall",
+ "syscall.ETHERTYPE_QINQ": "syscall",
+ "syscall.ETHERTYPE_RACAL": "syscall",
+ "syscall.ETHERTYPE_RATIONAL": "syscall",
+ "syscall.ETHERTYPE_RAWFR": "syscall",
+ "syscall.ETHERTYPE_RCL": "syscall",
+ "syscall.ETHERTYPE_RDP": "syscall",
+ "syscall.ETHERTYPE_RETIX": "syscall",
+ "syscall.ETHERTYPE_REVARP": "syscall",
+ "syscall.ETHERTYPE_SCA": "syscall",
+ "syscall.ETHERTYPE_SECTRA": "syscall",
+ "syscall.ETHERTYPE_SECUREDATA": "syscall",
+ "syscall.ETHERTYPE_SGITW": "syscall",
+ "syscall.ETHERTYPE_SG_BOUNCE": "syscall",
+ "syscall.ETHERTYPE_SG_DIAG": "syscall",
+ "syscall.ETHERTYPE_SG_NETGAMES": "syscall",
+ "syscall.ETHERTYPE_SG_RESV": "syscall",
+ "syscall.ETHERTYPE_SIMNET": "syscall",
+ "syscall.ETHERTYPE_SLOW": "syscall",
+ "syscall.ETHERTYPE_SLOWPROTOCOLS": "syscall",
+ "syscall.ETHERTYPE_SNA": "syscall",
+ "syscall.ETHERTYPE_SNMP": "syscall",
+ "syscall.ETHERTYPE_SONIX": "syscall",
+ "syscall.ETHERTYPE_SPIDER": "syscall",
+ "syscall.ETHERTYPE_SPRITE": "syscall",
+ "syscall.ETHERTYPE_STP": "syscall",
+ "syscall.ETHERTYPE_TALARIS": "syscall",
+ "syscall.ETHERTYPE_TALARISMC": "syscall",
+ "syscall.ETHERTYPE_TCPCOMP": "syscall",
+ "syscall.ETHERTYPE_TCPSM": "syscall",
+ "syscall.ETHERTYPE_TEC": "syscall",
+ "syscall.ETHERTYPE_TIGAN": "syscall",
+ "syscall.ETHERTYPE_TRAIL": "syscall",
+ "syscall.ETHERTYPE_TRANSETHER": "syscall",
+ "syscall.ETHERTYPE_TYMSHARE": "syscall",
+ "syscall.ETHERTYPE_UBBST": "syscall",
+ "syscall.ETHERTYPE_UBDEBUG": "syscall",
+ "syscall.ETHERTYPE_UBDIAGLOOP": "syscall",
+ "syscall.ETHERTYPE_UBDL": "syscall",
+ "syscall.ETHERTYPE_UBNIU": "syscall",
+ "syscall.ETHERTYPE_UBNMC": "syscall",
+ "syscall.ETHERTYPE_VALID": "syscall",
+ "syscall.ETHERTYPE_VARIAN": "syscall",
+ "syscall.ETHERTYPE_VAXELN": "syscall",
+ "syscall.ETHERTYPE_VEECO": "syscall",
+ "syscall.ETHERTYPE_VEXP": "syscall",
+ "syscall.ETHERTYPE_VGLAB": "syscall",
+ "syscall.ETHERTYPE_VINES": "syscall",
+ "syscall.ETHERTYPE_VINESECHO": "syscall",
+ "syscall.ETHERTYPE_VINESLOOP": "syscall",
+ "syscall.ETHERTYPE_VITAL": "syscall",
+ "syscall.ETHERTYPE_VLAN": "syscall",
+ "syscall.ETHERTYPE_VLTLMAN": "syscall",
+ "syscall.ETHERTYPE_VPROD": "syscall",
+ "syscall.ETHERTYPE_VURESERVED": "syscall",
+ "syscall.ETHERTYPE_WATERLOO": "syscall",
+ "syscall.ETHERTYPE_WELLFLEET": "syscall",
+ "syscall.ETHERTYPE_X25": "syscall",
+ "syscall.ETHERTYPE_X75": "syscall",
+ "syscall.ETHERTYPE_XNSSM": "syscall",
+ "syscall.ETHERTYPE_XTP": "syscall",
+ "syscall.ETHER_ADDR_LEN": "syscall",
+ "syscall.ETHER_ALIGN": "syscall",
+ "syscall.ETHER_CRC_LEN": "syscall",
+ "syscall.ETHER_CRC_POLY_BE": "syscall",
+ "syscall.ETHER_CRC_POLY_LE": "syscall",
+ "syscall.ETHER_HDR_LEN": "syscall",
+ "syscall.ETHER_MAX_DIX_LEN": "syscall",
+ "syscall.ETHER_MAX_LEN": "syscall",
+ "syscall.ETHER_MAX_LEN_JUMBO": "syscall",
+ "syscall.ETHER_MIN_LEN": "syscall",
+ "syscall.ETHER_PPPOE_ENCAP_LEN": "syscall",
+ "syscall.ETHER_TYPE_LEN": "syscall",
+ "syscall.ETHER_VLAN_ENCAP_LEN": "syscall",
+ "syscall.ETH_P_1588": "syscall",
+ "syscall.ETH_P_8021Q": "syscall",
+ "syscall.ETH_P_802_2": "syscall",
+ "syscall.ETH_P_802_3": "syscall",
+ "syscall.ETH_P_AARP": "syscall",
+ "syscall.ETH_P_ALL": "syscall",
+ "syscall.ETH_P_AOE": "syscall",
+ "syscall.ETH_P_ARCNET": "syscall",
+ "syscall.ETH_P_ARP": "syscall",
+ "syscall.ETH_P_ATALK": "syscall",
+ "syscall.ETH_P_ATMFATE": "syscall",
+ "syscall.ETH_P_ATMMPOA": "syscall",
+ "syscall.ETH_P_AX25": "syscall",
+ "syscall.ETH_P_BPQ": "syscall",
+ "syscall.ETH_P_CAIF": "syscall",
+ "syscall.ETH_P_CAN": "syscall",
+ "syscall.ETH_P_CONTROL": "syscall",
+ "syscall.ETH_P_CUST": "syscall",
+ "syscall.ETH_P_DDCMP": "syscall",
+ "syscall.ETH_P_DEC": "syscall",
+ "syscall.ETH_P_DIAG": "syscall",
+ "syscall.ETH_P_DNA_DL": "syscall",
+ "syscall.ETH_P_DNA_RC": "syscall",
+ "syscall.ETH_P_DNA_RT": "syscall",
+ "syscall.ETH_P_DSA": "syscall",
+ "syscall.ETH_P_ECONET": "syscall",
+ "syscall.ETH_P_EDSA": "syscall",
+ "syscall.ETH_P_FCOE": "syscall",
+ "syscall.ETH_P_FIP": "syscall",
+ "syscall.ETH_P_HDLC": "syscall",
+ "syscall.ETH_P_IEEE802154": "syscall",
+ "syscall.ETH_P_IEEEPUP": "syscall",
+ "syscall.ETH_P_IEEEPUPAT": "syscall",
+ "syscall.ETH_P_IP": "syscall",
+ "syscall.ETH_P_IPV6": "syscall",
+ "syscall.ETH_P_IPX": "syscall",
+ "syscall.ETH_P_IRDA": "syscall",
+ "syscall.ETH_P_LAT": "syscall",
+ "syscall.ETH_P_LINK_CTL": "syscall",
+ "syscall.ETH_P_LOCALTALK": "syscall",
+ "syscall.ETH_P_LOOP": "syscall",
+ "syscall.ETH_P_MOBITEX": "syscall",
+ "syscall.ETH_P_MPLS_MC": "syscall",
+ "syscall.ETH_P_MPLS_UC": "syscall",
+ "syscall.ETH_P_PAE": "syscall",
+ "syscall.ETH_P_PAUSE": "syscall",
+ "syscall.ETH_P_PHONET": "syscall",
+ "syscall.ETH_P_PPPTALK": "syscall",
+ "syscall.ETH_P_PPP_DISC": "syscall",
+ "syscall.ETH_P_PPP_MP": "syscall",
+ "syscall.ETH_P_PPP_SES": "syscall",
+ "syscall.ETH_P_PUP": "syscall",
+ "syscall.ETH_P_PUPAT": "syscall",
+ "syscall.ETH_P_RARP": "syscall",
+ "syscall.ETH_P_SCA": "syscall",
+ "syscall.ETH_P_SLOW": "syscall",
+ "syscall.ETH_P_SNAP": "syscall",
+ "syscall.ETH_P_TEB": "syscall",
+ "syscall.ETH_P_TIPC": "syscall",
+ "syscall.ETH_P_TRAILER": "syscall",
+ "syscall.ETH_P_TR_802_2": "syscall",
+ "syscall.ETH_P_WAN_PPP": "syscall",
+ "syscall.ETH_P_WCCP": "syscall",
+ "syscall.ETH_P_X25": "syscall",
+ "syscall.ETIME": "syscall",
+ "syscall.ETIMEDOUT": "syscall",
+ "syscall.ETOOMANYREFS": "syscall",
+ "syscall.ETXTBSY": "syscall",
+ "syscall.EUCLEAN": "syscall",
+ "syscall.EUNATCH": "syscall",
+ "syscall.EUSERS": "syscall",
+ "syscall.EVFILT_AIO": "syscall",
+ "syscall.EVFILT_FS": "syscall",
+ "syscall.EVFILT_LIO": "syscall",
+ "syscall.EVFILT_MACHPORT": "syscall",
+ "syscall.EVFILT_PROC": "syscall",
+ "syscall.EVFILT_READ": "syscall",
+ "syscall.EVFILT_SIGNAL": "syscall",
+ "syscall.EVFILT_SYSCOUNT": "syscall",
+ "syscall.EVFILT_THREADMARKER": "syscall",
+ "syscall.EVFILT_TIMER": "syscall",
+ "syscall.EVFILT_USER": "syscall",
+ "syscall.EVFILT_VM": "syscall",
+ "syscall.EVFILT_VNODE": "syscall",
+ "syscall.EVFILT_WRITE": "syscall",
+ "syscall.EV_ADD": "syscall",
+ "syscall.EV_CLEAR": "syscall",
+ "syscall.EV_DELETE": "syscall",
+ "syscall.EV_DISABLE": "syscall",
+ "syscall.EV_DISPATCH": "syscall",
+ "syscall.EV_DROP": "syscall",
+ "syscall.EV_ENABLE": "syscall",
+ "syscall.EV_EOF": "syscall",
+ "syscall.EV_ERROR": "syscall",
+ "syscall.EV_FLAG0": "syscall",
+ "syscall.EV_FLAG1": "syscall",
+ "syscall.EV_ONESHOT": "syscall",
+ "syscall.EV_OOBAND": "syscall",
+ "syscall.EV_POLL": "syscall",
+ "syscall.EV_RECEIPT": "syscall",
+ "syscall.EV_SYSFLAGS": "syscall",
+ "syscall.EWINDOWS": "syscall",
+ "syscall.EWOULDBLOCK": "syscall",
+ "syscall.EXDEV": "syscall",
+ "syscall.EXFULL": "syscall",
+ "syscall.EXTA": "syscall",
+ "syscall.EXTB": "syscall",
+ "syscall.EXTPROC": "syscall",
+ "syscall.Environ": "syscall",
+ "syscall.EpollCreate": "syscall",
+ "syscall.EpollCreate1": "syscall",
+ "syscall.EpollCtl": "syscall",
+ "syscall.EpollEvent": "syscall",
+ "syscall.EpollWait": "syscall",
+ "syscall.Errno": "syscall",
+ "syscall.EscapeArg": "syscall",
+ "syscall.Exchangedata": "syscall",
+ "syscall.Exec": "syscall",
+ "syscall.Exit": "syscall",
+ "syscall.ExitProcess": "syscall",
+ "syscall.FD_CLOEXEC": "syscall",
+ "syscall.FD_SETSIZE": "syscall",
+ "syscall.FILE_ACTION_ADDED": "syscall",
+ "syscall.FILE_ACTION_MODIFIED": "syscall",
+ "syscall.FILE_ACTION_REMOVED": "syscall",
+ "syscall.FILE_ACTION_RENAMED_NEW_NAME": "syscall",
+ "syscall.FILE_ACTION_RENAMED_OLD_NAME": "syscall",
+ "syscall.FILE_APPEND_DATA": "syscall",
+ "syscall.FILE_ATTRIBUTE_ARCHIVE": "syscall",
+ "syscall.FILE_ATTRIBUTE_DIRECTORY": "syscall",
+ "syscall.FILE_ATTRIBUTE_HIDDEN": "syscall",
+ "syscall.FILE_ATTRIBUTE_NORMAL": "syscall",
+ "syscall.FILE_ATTRIBUTE_READONLY": "syscall",
+ "syscall.FILE_ATTRIBUTE_SYSTEM": "syscall",
+ "syscall.FILE_BEGIN": "syscall",
+ "syscall.FILE_CURRENT": "syscall",
+ "syscall.FILE_END": "syscall",
+ "syscall.FILE_FLAG_BACKUP_SEMANTICS": "syscall",
+ "syscall.FILE_FLAG_OVERLAPPED": "syscall",
+ "syscall.FILE_LIST_DIRECTORY": "syscall",
+ "syscall.FILE_MAP_COPY": "syscall",
+ "syscall.FILE_MAP_EXECUTE": "syscall",
+ "syscall.FILE_MAP_READ": "syscall",
+ "syscall.FILE_MAP_WRITE": "syscall",
+ "syscall.FILE_NOTIFY_CHANGE_ATTRIBUTES": "syscall",
+ "syscall.FILE_NOTIFY_CHANGE_CREATION": "syscall",
+ "syscall.FILE_NOTIFY_CHANGE_DIR_NAME": "syscall",
+ "syscall.FILE_NOTIFY_CHANGE_FILE_NAME": "syscall",
+ "syscall.FILE_NOTIFY_CHANGE_LAST_ACCESS": "syscall",
+ "syscall.FILE_NOTIFY_CHANGE_LAST_WRITE": "syscall",
+ "syscall.FILE_NOTIFY_CHANGE_SIZE": "syscall",
+ "syscall.FILE_SHARE_DELETE": "syscall",
+ "syscall.FILE_SHARE_READ": "syscall",
+ "syscall.FILE_SHARE_WRITE": "syscall",
+ "syscall.FILE_SKIP_COMPLETION_PORT_ON_SUCCESS": "syscall",
+ "syscall.FILE_SKIP_SET_EVENT_ON_HANDLE": "syscall",
+ "syscall.FILE_TYPE_CHAR": "syscall",
+ "syscall.FILE_TYPE_DISK": "syscall",
+ "syscall.FILE_TYPE_PIPE": "syscall",
+ "syscall.FILE_TYPE_REMOTE": "syscall",
+ "syscall.FILE_TYPE_UNKNOWN": "syscall",
+ "syscall.FILE_WRITE_ATTRIBUTES": "syscall",
+ "syscall.FLUSHO": "syscall",
+ "syscall.FORMAT_MESSAGE_ALLOCATE_BUFFER": "syscall",
+ "syscall.FORMAT_MESSAGE_ARGUMENT_ARRAY": "syscall",
+ "syscall.FORMAT_MESSAGE_FROM_HMODULE": "syscall",
+ "syscall.FORMAT_MESSAGE_FROM_STRING": "syscall",
+ "syscall.FORMAT_MESSAGE_FROM_SYSTEM": "syscall",
+ "syscall.FORMAT_MESSAGE_IGNORE_INSERTS": "syscall",
+ "syscall.FORMAT_MESSAGE_MAX_WIDTH_MASK": "syscall",
+ "syscall.F_ADDFILESIGS": "syscall",
+ "syscall.F_ADDSIGS": "syscall",
+ "syscall.F_ALLOCATEALL": "syscall",
+ "syscall.F_ALLOCATECONTIG": "syscall",
+ "syscall.F_CANCEL": "syscall",
+ "syscall.F_CHKCLEAN": "syscall",
+ "syscall.F_CLOSEM": "syscall",
+ "syscall.F_DUP2FD": "syscall",
+ "syscall.F_DUP2FD_CLOEXEC": "syscall",
+ "syscall.F_DUPFD": "syscall",
+ "syscall.F_DUPFD_CLOEXEC": "syscall",
+ "syscall.F_EXLCK": "syscall",
+ "syscall.F_FLUSH_DATA": "syscall",
+ "syscall.F_FREEZE_FS": "syscall",
+ "syscall.F_FSCTL": "syscall",
+ "syscall.F_FSDIRMASK": "syscall",
+ "syscall.F_FSIN": "syscall",
+ "syscall.F_FSINOUT": "syscall",
+ "syscall.F_FSOUT": "syscall",
+ "syscall.F_FSPRIV": "syscall",
+ "syscall.F_FSVOID": "syscall",
+ "syscall.F_FULLFSYNC": "syscall",
+ "syscall.F_GETFD": "syscall",
+ "syscall.F_GETFL": "syscall",
+ "syscall.F_GETLEASE": "syscall",
+ "syscall.F_GETLK": "syscall",
+ "syscall.F_GETLK64": "syscall",
+ "syscall.F_GETLKPID": "syscall",
+ "syscall.F_GETNOSIGPIPE": "syscall",
+ "syscall.F_GETOWN": "syscall",
+ "syscall.F_GETOWN_EX": "syscall",
+ "syscall.F_GETPATH": "syscall",
+ "syscall.F_GETPATH_MTMINFO": "syscall",
+ "syscall.F_GETPIPE_SZ": "syscall",
+ "syscall.F_GETPROTECTIONCLASS": "syscall",
+ "syscall.F_GETSIG": "syscall",
+ "syscall.F_GLOBAL_NOCACHE": "syscall",
+ "syscall.F_LOCK": "syscall",
+ "syscall.F_LOG2PHYS": "syscall",
+ "syscall.F_LOG2PHYS_EXT": "syscall",
+ "syscall.F_MARKDEPENDENCY": "syscall",
+ "syscall.F_MAXFD": "syscall",
+ "syscall.F_NOCACHE": "syscall",
+ "syscall.F_NODIRECT": "syscall",
+ "syscall.F_NOTIFY": "syscall",
+ "syscall.F_OGETLK": "syscall",
+ "syscall.F_OK": "syscall",
+ "syscall.F_OSETLK": "syscall",
+ "syscall.F_OSETLKW": "syscall",
+ "syscall.F_PARAM_MASK": "syscall",
+ "syscall.F_PARAM_MAX": "syscall",
+ "syscall.F_PATHPKG_CHECK": "syscall",
+ "syscall.F_PEOFPOSMODE": "syscall",
+ "syscall.F_PREALLOCATE": "syscall",
+ "syscall.F_RDADVISE": "syscall",
+ "syscall.F_RDAHEAD": "syscall",
+ "syscall.F_RDLCK": "syscall",
+ "syscall.F_READAHEAD": "syscall",
+ "syscall.F_READBOOTSTRAP": "syscall",
+ "syscall.F_SETBACKINGSTORE": "syscall",
+ "syscall.F_SETFD": "syscall",
+ "syscall.F_SETFL": "syscall",
+ "syscall.F_SETLEASE": "syscall",
+ "syscall.F_SETLK": "syscall",
+ "syscall.F_SETLK64": "syscall",
+ "syscall.F_SETLKW": "syscall",
+ "syscall.F_SETLKW64": "syscall",
+ "syscall.F_SETLK_REMOTE": "syscall",
+ "syscall.F_SETNOSIGPIPE": "syscall",
+ "syscall.F_SETOWN": "syscall",
+ "syscall.F_SETOWN_EX": "syscall",
+ "syscall.F_SETPIPE_SZ": "syscall",
+ "syscall.F_SETPROTECTIONCLASS": "syscall",
+ "syscall.F_SETSIG": "syscall",
+ "syscall.F_SETSIZE": "syscall",
+ "syscall.F_SHLCK": "syscall",
+ "syscall.F_TEST": "syscall",
+ "syscall.F_THAW_FS": "syscall",
+ "syscall.F_TLOCK": "syscall",
+ "syscall.F_ULOCK": "syscall",
+ "syscall.F_UNLCK": "syscall",
+ "syscall.F_UNLCKSYS": "syscall",
+ "syscall.F_VOLPOSMODE": "syscall",
+ "syscall.F_WRITEBOOTSTRAP": "syscall",
+ "syscall.F_WRLCK": "syscall",
+ "syscall.Faccessat": "syscall",
+ "syscall.Fallocate": "syscall",
+ "syscall.Fbootstraptransfer_t": "syscall",
+ "syscall.Fchdir": "syscall",
+ "syscall.Fchflags": "syscall",
+ "syscall.Fchmod": "syscall",
+ "syscall.Fchmodat": "syscall",
+ "syscall.Fchown": "syscall",
+ "syscall.Fchownat": "syscall",
+ "syscall.FcntlFlock": "syscall",
+ "syscall.FdSet": "syscall",
+ "syscall.Fdatasync": "syscall",
+ "syscall.FileNotifyInformation": "syscall",
+ "syscall.Filetime": "syscall",
+ "syscall.FindClose": "syscall",
+ "syscall.FindFirstFile": "syscall",
+ "syscall.FindNextFile": "syscall",
+ "syscall.Flock": "syscall",
+ "syscall.Flock_t": "syscall",
+ "syscall.FlushBpf": "syscall",
+ "syscall.FlushFileBuffers": "syscall",
+ "syscall.FlushViewOfFile": "syscall",
+ "syscall.ForkExec": "syscall",
+ "syscall.ForkLock": "syscall",
+ "syscall.FormatMessage": "syscall",
+ "syscall.Fpathconf": "syscall",
+ "syscall.FreeAddrInfoW": "syscall",
+ "syscall.FreeEnvironmentStrings": "syscall",
+ "syscall.FreeLibrary": "syscall",
+ "syscall.Fsid": "syscall",
+ "syscall.Fstat": "syscall",
+ "syscall.Fstatfs": "syscall",
+ "syscall.Fstore_t": "syscall",
+ "syscall.Fsync": "syscall",
+ "syscall.Ftruncate": "syscall",
+ "syscall.Futimes": "syscall",
+ "syscall.Futimesat": "syscall",
+ "syscall.GENERIC_ALL": "syscall",
+ "syscall.GENERIC_EXECUTE": "syscall",
+ "syscall.GENERIC_READ": "syscall",
+ "syscall.GENERIC_WRITE": "syscall",
+ "syscall.GUID": "syscall",
+ "syscall.GetAcceptExSockaddrs": "syscall",
+ "syscall.GetAdaptersInfo": "syscall",
+ "syscall.GetAddrInfoW": "syscall",
+ "syscall.GetCommandLine": "syscall",
+ "syscall.GetComputerName": "syscall",
+ "syscall.GetConsoleMode": "syscall",
+ "syscall.GetCurrentDirectory": "syscall",
+ "syscall.GetCurrentProcess": "syscall",
+ "syscall.GetEnvironmentStrings": "syscall",
+ "syscall.GetEnvironmentVariable": "syscall",
+ "syscall.GetExitCodeProcess": "syscall",
+ "syscall.GetFileAttributes": "syscall",
+ "syscall.GetFileAttributesEx": "syscall",
+ "syscall.GetFileExInfoStandard": "syscall",
+ "syscall.GetFileExMaxInfoLevel": "syscall",
+ "syscall.GetFileInformationByHandle": "syscall",
+ "syscall.GetFileType": "syscall",
+ "syscall.GetFullPathName": "syscall",
+ "syscall.GetHostByName": "syscall",
+ "syscall.GetIfEntry": "syscall",
+ "syscall.GetLastError": "syscall",
+ "syscall.GetLengthSid": "syscall",
+ "syscall.GetLongPathName": "syscall",
+ "syscall.GetProcAddress": "syscall",
+ "syscall.GetProcessTimes": "syscall",
+ "syscall.GetProtoByName": "syscall",
+ "syscall.GetQueuedCompletionStatus": "syscall",
+ "syscall.GetServByName": "syscall",
+ "syscall.GetShortPathName": "syscall",
+ "syscall.GetStartupInfo": "syscall",
+ "syscall.GetStdHandle": "syscall",
+ "syscall.GetSystemTimeAsFileTime": "syscall",
+ "syscall.GetTempPath": "syscall",
+ "syscall.GetTimeZoneInformation": "syscall",
+ "syscall.GetTokenInformation": "syscall",
+ "syscall.GetUserNameEx": "syscall",
+ "syscall.GetUserProfileDirectory": "syscall",
+ "syscall.GetVersion": "syscall",
+ "syscall.Getcwd": "syscall",
+ "syscall.Getdents": "syscall",
+ "syscall.Getdirentries": "syscall",
+ "syscall.Getdtablesize": "syscall",
+ "syscall.Getegid": "syscall",
+ "syscall.Getenv": "syscall",
+ "syscall.Geteuid": "syscall",
+ "syscall.Getfsstat": "syscall",
+ "syscall.Getgid": "syscall",
+ "syscall.Getgroups": "syscall",
+ "syscall.Getpagesize": "syscall",
+ "syscall.Getpeername": "syscall",
+ "syscall.Getpgid": "syscall",
+ "syscall.Getpgrp": "syscall",
+ "syscall.Getpid": "syscall",
+ "syscall.Getppid": "syscall",
+ "syscall.Getpriority": "syscall",
+ "syscall.Getrlimit": "syscall",
+ "syscall.Getrusage": "syscall",
+ "syscall.Getsid": "syscall",
+ "syscall.Getsockname": "syscall",
+ "syscall.Getsockopt": "syscall",
+ "syscall.GetsockoptByte": "syscall",
+ "syscall.GetsockoptICMPv6Filter": "syscall",
+ "syscall.GetsockoptIPMreq": "syscall",
+ "syscall.GetsockoptIPMreqn": "syscall",
+ "syscall.GetsockoptIPv6MTUInfo": "syscall",
+ "syscall.GetsockoptIPv6Mreq": "syscall",
+ "syscall.GetsockoptInet4Addr": "syscall",
+ "syscall.GetsockoptInt": "syscall",
+ "syscall.GetsockoptUcred": "syscall",
+ "syscall.Gettid": "syscall",
+ "syscall.Gettimeofday": "syscall",
+ "syscall.Getuid": "syscall",
+ "syscall.Getwd": "syscall",
+ "syscall.Getxattr": "syscall",
+ "syscall.HANDLE_FLAG_INHERIT": "syscall",
+ "syscall.HKEY_CLASSES_ROOT": "syscall",
+ "syscall.HKEY_CURRENT_CONFIG": "syscall",
+ "syscall.HKEY_CURRENT_USER": "syscall",
+ "syscall.HKEY_DYN_DATA": "syscall",
+ "syscall.HKEY_LOCAL_MACHINE": "syscall",
+ "syscall.HKEY_PERFORMANCE_DATA": "syscall",
+ "syscall.HKEY_USERS": "syscall",
+ "syscall.HUPCL": "syscall",
+ "syscall.Handle": "syscall",
+ "syscall.Hostent": "syscall",
+ "syscall.ICANON": "syscall",
+ "syscall.ICMP6_FILTER": "syscall",
+ "syscall.ICMPV6_FILTER": "syscall",
+ "syscall.ICMPv6Filter": "syscall",
+ "syscall.ICRNL": "syscall",
+ "syscall.IEXTEN": "syscall",
+ "syscall.IFAN_ARRIVAL": "syscall",
+ "syscall.IFAN_DEPARTURE": "syscall",
+ "syscall.IFA_ADDRESS": "syscall",
+ "syscall.IFA_ANYCAST": "syscall",
+ "syscall.IFA_BROADCAST": "syscall",
+ "syscall.IFA_CACHEINFO": "syscall",
+ "syscall.IFA_F_DADFAILED": "syscall",
+ "syscall.IFA_F_DEPRECATED": "syscall",
+ "syscall.IFA_F_HOMEADDRESS": "syscall",
+ "syscall.IFA_F_NODAD": "syscall",
+ "syscall.IFA_F_OPTIMISTIC": "syscall",
+ "syscall.IFA_F_PERMANENT": "syscall",
+ "syscall.IFA_F_SECONDARY": "syscall",
+ "syscall.IFA_F_TEMPORARY": "syscall",
+ "syscall.IFA_F_TENTATIVE": "syscall",
+ "syscall.IFA_LABEL": "syscall",
+ "syscall.IFA_LOCAL": "syscall",
+ "syscall.IFA_MAX": "syscall",
+ "syscall.IFA_MULTICAST": "syscall",
+ "syscall.IFA_ROUTE": "syscall",
+ "syscall.IFA_UNSPEC": "syscall",
+ "syscall.IFF_ALLMULTI": "syscall",
+ "syscall.IFF_ALTPHYS": "syscall",
+ "syscall.IFF_AUTOMEDIA": "syscall",
+ "syscall.IFF_BROADCAST": "syscall",
+ "syscall.IFF_CANTCHANGE": "syscall",
+ "syscall.IFF_CANTCONFIG": "syscall",
+ "syscall.IFF_DEBUG": "syscall",
+ "syscall.IFF_DRV_OACTIVE": "syscall",
+ "syscall.IFF_DRV_RUNNING": "syscall",
+ "syscall.IFF_DYING": "syscall",
+ "syscall.IFF_DYNAMIC": "syscall",
+ "syscall.IFF_LINK0": "syscall",
+ "syscall.IFF_LINK1": "syscall",
+ "syscall.IFF_LINK2": "syscall",
+ "syscall.IFF_LOOPBACK": "syscall",
+ "syscall.IFF_MASTER": "syscall",
+ "syscall.IFF_MONITOR": "syscall",
+ "syscall.IFF_MULTICAST": "syscall",
+ "syscall.IFF_NOARP": "syscall",
+ "syscall.IFF_NOTRAILERS": "syscall",
+ "syscall.IFF_NO_PI": "syscall",
+ "syscall.IFF_OACTIVE": "syscall",
+ "syscall.IFF_ONE_QUEUE": "syscall",
+ "syscall.IFF_POINTOPOINT": "syscall",
+ "syscall.IFF_POINTTOPOINT": "syscall",
+ "syscall.IFF_PORTSEL": "syscall",
+ "syscall.IFF_PPROMISC": "syscall",
+ "syscall.IFF_PROMISC": "syscall",
+ "syscall.IFF_RENAMING": "syscall",
+ "syscall.IFF_RUNNING": "syscall",
+ "syscall.IFF_SIMPLEX": "syscall",
+ "syscall.IFF_SLAVE": "syscall",
+ "syscall.IFF_SMART": "syscall",
+ "syscall.IFF_STATICARP": "syscall",
+ "syscall.IFF_TAP": "syscall",
+ "syscall.IFF_TUN": "syscall",
+ "syscall.IFF_TUN_EXCL": "syscall",
+ "syscall.IFF_UP": "syscall",
+ "syscall.IFF_VNET_HDR": "syscall",
+ "syscall.IFLA_ADDRESS": "syscall",
+ "syscall.IFLA_BROADCAST": "syscall",
+ "syscall.IFLA_COST": "syscall",
+ "syscall.IFLA_IFALIAS": "syscall",
+ "syscall.IFLA_IFNAME": "syscall",
+ "syscall.IFLA_LINK": "syscall",
+ "syscall.IFLA_LINKINFO": "syscall",
+ "syscall.IFLA_LINKMODE": "syscall",
+ "syscall.IFLA_MAP": "syscall",
+ "syscall.IFLA_MASTER": "syscall",
+ "syscall.IFLA_MAX": "syscall",
+ "syscall.IFLA_MTU": "syscall",
+ "syscall.IFLA_NET_NS_PID": "syscall",
+ "syscall.IFLA_OPERSTATE": "syscall",
+ "syscall.IFLA_PRIORITY": "syscall",
+ "syscall.IFLA_PROTINFO": "syscall",
+ "syscall.IFLA_QDISC": "syscall",
+ "syscall.IFLA_STATS": "syscall",
+ "syscall.IFLA_TXQLEN": "syscall",
+ "syscall.IFLA_UNSPEC": "syscall",
+ "syscall.IFLA_WEIGHT": "syscall",
+ "syscall.IFLA_WIRELESS": "syscall",
+ "syscall.IFNAMSIZ": "syscall",
+ "syscall.IFT_1822": "syscall",
+ "syscall.IFT_A12MPPSWITCH": "syscall",
+ "syscall.IFT_AAL2": "syscall",
+ "syscall.IFT_AAL5": "syscall",
+ "syscall.IFT_ADSL": "syscall",
+ "syscall.IFT_AFLANE8023": "syscall",
+ "syscall.IFT_AFLANE8025": "syscall",
+ "syscall.IFT_ARAP": "syscall",
+ "syscall.IFT_ARCNET": "syscall",
+ "syscall.IFT_ARCNETPLUS": "syscall",
+ "syscall.IFT_ASYNC": "syscall",
+ "syscall.IFT_ATM": "syscall",
+ "syscall.IFT_ATMDXI": "syscall",
+ "syscall.IFT_ATMFUNI": "syscall",
+ "syscall.IFT_ATMIMA": "syscall",
+ "syscall.IFT_ATMLOGICAL": "syscall",
+ "syscall.IFT_ATMRADIO": "syscall",
+ "syscall.IFT_ATMSUBINTERFACE": "syscall",
+ "syscall.IFT_ATMVCIENDPT": "syscall",
+ "syscall.IFT_ATMVIRTUAL": "syscall",
+ "syscall.IFT_BGPPOLICYACCOUNTING": "syscall",
+ "syscall.IFT_BLUETOOTH": "syscall",
+ "syscall.IFT_BRIDGE": "syscall",
+ "syscall.IFT_BSC": "syscall",
+ "syscall.IFT_CARP": "syscall",
+ "syscall.IFT_CCTEMUL": "syscall",
+ "syscall.IFT_CELLULAR": "syscall",
+ "syscall.IFT_CEPT": "syscall",
+ "syscall.IFT_CES": "syscall",
+ "syscall.IFT_CHANNEL": "syscall",
+ "syscall.IFT_CNR": "syscall",
+ "syscall.IFT_COFFEE": "syscall",
+ "syscall.IFT_COMPOSITELINK": "syscall",
+ "syscall.IFT_DCN": "syscall",
+ "syscall.IFT_DIGITALPOWERLINE": "syscall",
+ "syscall.IFT_DIGITALWRAPPEROVERHEADCHANNEL": "syscall",
+ "syscall.IFT_DLSW": "syscall",
+ "syscall.IFT_DOCSCABLEDOWNSTREAM": "syscall",
+ "syscall.IFT_DOCSCABLEMACLAYER": "syscall",
+ "syscall.IFT_DOCSCABLEUPSTREAM": "syscall",
+ "syscall.IFT_DOCSCABLEUPSTREAMCHANNEL": "syscall",
+ "syscall.IFT_DS0": "syscall",
+ "syscall.IFT_DS0BUNDLE": "syscall",
+ "syscall.IFT_DS1FDL": "syscall",
+ "syscall.IFT_DS3": "syscall",
+ "syscall.IFT_DTM": "syscall",
+ "syscall.IFT_DUMMY": "syscall",
+ "syscall.IFT_DVBASILN": "syscall",
+ "syscall.IFT_DVBASIOUT": "syscall",
+ "syscall.IFT_DVBRCCDOWNSTREAM": "syscall",
+ "syscall.IFT_DVBRCCMACLAYER": "syscall",
+ "syscall.IFT_DVBRCCUPSTREAM": "syscall",
+ "syscall.IFT_ECONET": "syscall",
+ "syscall.IFT_ENC": "syscall",
+ "syscall.IFT_EON": "syscall",
+ "syscall.IFT_EPLRS": "syscall",
+ "syscall.IFT_ESCON": "syscall",
+ "syscall.IFT_ETHER": "syscall",
+ "syscall.IFT_FAITH": "syscall",
+ "syscall.IFT_FAST": "syscall",
+ "syscall.IFT_FASTETHER": "syscall",
+ "syscall.IFT_FASTETHERFX": "syscall",
+ "syscall.IFT_FDDI": "syscall",
+ "syscall.IFT_FIBRECHANNEL": "syscall",
+ "syscall.IFT_FRAMERELAYINTERCONNECT": "syscall",
+ "syscall.IFT_FRAMERELAYMPI": "syscall",
+ "syscall.IFT_FRDLCIENDPT": "syscall",
+ "syscall.IFT_FRELAY": "syscall",
+ "syscall.IFT_FRELAYDCE": "syscall",
+ "syscall.IFT_FRF16MFRBUNDLE": "syscall",
+ "syscall.IFT_FRFORWARD": "syscall",
+ "syscall.IFT_G703AT2MB": "syscall",
+ "syscall.IFT_G703AT64K": "syscall",
+ "syscall.IFT_GIF": "syscall",
+ "syscall.IFT_GIGABITETHERNET": "syscall",
+ "syscall.IFT_GR303IDT": "syscall",
+ "syscall.IFT_GR303RDT": "syscall",
+ "syscall.IFT_H323GATEKEEPER": "syscall",
+ "syscall.IFT_H323PROXY": "syscall",
+ "syscall.IFT_HDH1822": "syscall",
+ "syscall.IFT_HDLC": "syscall",
+ "syscall.IFT_HDSL2": "syscall",
+ "syscall.IFT_HIPERLAN2": "syscall",
+ "syscall.IFT_HIPPI": "syscall",
+ "syscall.IFT_HIPPIINTERFACE": "syscall",
+ "syscall.IFT_HOSTPAD": "syscall",
+ "syscall.IFT_HSSI": "syscall",
+ "syscall.IFT_HY": "syscall",
+ "syscall.IFT_IBM370PARCHAN": "syscall",
+ "syscall.IFT_IDSL": "syscall",
+ "syscall.IFT_IEEE1394": "syscall",
+ "syscall.IFT_IEEE80211": "syscall",
+ "syscall.IFT_IEEE80212": "syscall",
+ "syscall.IFT_IEEE8023ADLAG": "syscall",
+ "syscall.IFT_IFGSN": "syscall",
+ "syscall.IFT_IMT": "syscall",
+ "syscall.IFT_INFINIBAND": "syscall",
+ "syscall.IFT_INTERLEAVE": "syscall",
+ "syscall.IFT_IP": "syscall",
+ "syscall.IFT_IPFORWARD": "syscall",
+ "syscall.IFT_IPOVERATM": "syscall",
+ "syscall.IFT_IPOVERCDLC": "syscall",
+ "syscall.IFT_IPOVERCLAW": "syscall",
+ "syscall.IFT_IPSWITCH": "syscall",
+ "syscall.IFT_IPXIP": "syscall",
+ "syscall.IFT_ISDN": "syscall",
+ "syscall.IFT_ISDNBASIC": "syscall",
+ "syscall.IFT_ISDNPRIMARY": "syscall",
+ "syscall.IFT_ISDNS": "syscall",
+ "syscall.IFT_ISDNU": "syscall",
+ "syscall.IFT_ISO88022LLC": "syscall",
+ "syscall.IFT_ISO88023": "syscall",
+ "syscall.IFT_ISO88024": "syscall",
+ "syscall.IFT_ISO88025": "syscall",
+ "syscall.IFT_ISO88025CRFPINT": "syscall",
+ "syscall.IFT_ISO88025DTR": "syscall",
+ "syscall.IFT_ISO88025FIBER": "syscall",
+ "syscall.IFT_ISO88026": "syscall",
+ "syscall.IFT_ISUP": "syscall",
+ "syscall.IFT_L2VLAN": "syscall",
+ "syscall.IFT_L3IPVLAN": "syscall",
+ "syscall.IFT_L3IPXVLAN": "syscall",
+ "syscall.IFT_LAPB": "syscall",
+ "syscall.IFT_LAPD": "syscall",
+ "syscall.IFT_LAPF": "syscall",
+ "syscall.IFT_LINEGROUP": "syscall",
+ "syscall.IFT_LOCALTALK": "syscall",
+ "syscall.IFT_LOOP": "syscall",
+ "syscall.IFT_MEDIAMAILOVERIP": "syscall",
+ "syscall.IFT_MFSIGLINK": "syscall",
+ "syscall.IFT_MIOX25": "syscall",
+ "syscall.IFT_MODEM": "syscall",
+ "syscall.IFT_MPC": "syscall",
+ "syscall.IFT_MPLS": "syscall",
+ "syscall.IFT_MPLSTUNNEL": "syscall",
+ "syscall.IFT_MSDSL": "syscall",
+ "syscall.IFT_MVL": "syscall",
+ "syscall.IFT_MYRINET": "syscall",
+ "syscall.IFT_NFAS": "syscall",
+ "syscall.IFT_NSIP": "syscall",
+ "syscall.IFT_OPTICALCHANNEL": "syscall",
+ "syscall.IFT_OPTICALTRANSPORT": "syscall",
+ "syscall.IFT_OTHER": "syscall",
+ "syscall.IFT_P10": "syscall",
+ "syscall.IFT_P80": "syscall",
+ "syscall.IFT_PARA": "syscall",
+ "syscall.IFT_PDP": "syscall",
+ "syscall.IFT_PFLOG": "syscall",
+ "syscall.IFT_PFLOW": "syscall",
+ "syscall.IFT_PFSYNC": "syscall",
+ "syscall.IFT_PLC": "syscall",
+ "syscall.IFT_PON155": "syscall",
+ "syscall.IFT_PON622": "syscall",
+ "syscall.IFT_POS": "syscall",
+ "syscall.IFT_PPP": "syscall",
+ "syscall.IFT_PPPMULTILINKBUNDLE": "syscall",
+ "syscall.IFT_PROPATM": "syscall",
+ "syscall.IFT_PROPBWAP2MP": "syscall",
+ "syscall.IFT_PROPCNLS": "syscall",
+ "syscall.IFT_PROPDOCSWIRELESSDOWNSTREAM": "syscall",
+ "syscall.IFT_PROPDOCSWIRELESSMACLAYER": "syscall",
+ "syscall.IFT_PROPDOCSWIRELESSUPSTREAM": "syscall",
+ "syscall.IFT_PROPMUX": "syscall",
+ "syscall.IFT_PROPVIRTUAL": "syscall",
+ "syscall.IFT_PROPWIRELESSP2P": "syscall",
+ "syscall.IFT_PTPSERIAL": "syscall",
+ "syscall.IFT_PVC": "syscall",
+ "syscall.IFT_Q2931": "syscall",
+ "syscall.IFT_QLLC": "syscall",
+ "syscall.IFT_RADIOMAC": "syscall",
+ "syscall.IFT_RADSL": "syscall",
+ "syscall.IFT_REACHDSL": "syscall",
+ "syscall.IFT_RFC1483": "syscall",
+ "syscall.IFT_RS232": "syscall",
+ "syscall.IFT_RSRB": "syscall",
+ "syscall.IFT_SDLC": "syscall",
+ "syscall.IFT_SDSL": "syscall",
+ "syscall.IFT_SHDSL": "syscall",
+ "syscall.IFT_SIP": "syscall",
+ "syscall.IFT_SIPSIG": "syscall",
+ "syscall.IFT_SIPTG": "syscall",
+ "syscall.IFT_SLIP": "syscall",
+ "syscall.IFT_SMDSDXI": "syscall",
+ "syscall.IFT_SMDSICIP": "syscall",
+ "syscall.IFT_SONET": "syscall",
+ "syscall.IFT_SONETOVERHEADCHANNEL": "syscall",
+ "syscall.IFT_SONETPATH": "syscall",
+ "syscall.IFT_SONETVT": "syscall",
+ "syscall.IFT_SRP": "syscall",
+ "syscall.IFT_SS7SIGLINK": "syscall",
+ "syscall.IFT_STACKTOSTACK": "syscall",
+ "syscall.IFT_STARLAN": "syscall",
+ "syscall.IFT_STF": "syscall",
+ "syscall.IFT_T1": "syscall",
+ "syscall.IFT_TDLC": "syscall",
+ "syscall.IFT_TELINK": "syscall",
+ "syscall.IFT_TERMPAD": "syscall",
+ "syscall.IFT_TR008": "syscall",
+ "syscall.IFT_TRANSPHDLC": "syscall",
+ "syscall.IFT_TUNNEL": "syscall",
+ "syscall.IFT_ULTRA": "syscall",
+ "syscall.IFT_USB": "syscall",
+ "syscall.IFT_V11": "syscall",
+ "syscall.IFT_V35": "syscall",
+ "syscall.IFT_V36": "syscall",
+ "syscall.IFT_V37": "syscall",
+ "syscall.IFT_VDSL": "syscall",
+ "syscall.IFT_VIRTUALIPADDRESS": "syscall",
+ "syscall.IFT_VIRTUALTG": "syscall",
+ "syscall.IFT_VOICEDID": "syscall",
+ "syscall.IFT_VOICEEM": "syscall",
+ "syscall.IFT_VOICEEMFGD": "syscall",
+ "syscall.IFT_VOICEENCAP": "syscall",
+ "syscall.IFT_VOICEFGDEANA": "syscall",
+ "syscall.IFT_VOICEFXO": "syscall",
+ "syscall.IFT_VOICEFXS": "syscall",
+ "syscall.IFT_VOICEOVERATM": "syscall",
+ "syscall.IFT_VOICEOVERCABLE": "syscall",
+ "syscall.IFT_VOICEOVERFRAMERELAY": "syscall",
+ "syscall.IFT_VOICEOVERIP": "syscall",
+ "syscall.IFT_X213": "syscall",
+ "syscall.IFT_X25": "syscall",
+ "syscall.IFT_X25DDN": "syscall",
+ "syscall.IFT_X25HUNTGROUP": "syscall",
+ "syscall.IFT_X25MLP": "syscall",
+ "syscall.IFT_X25PLE": "syscall",
+ "syscall.IFT_XETHER": "syscall",
+ "syscall.IGNBRK": "syscall",
+ "syscall.IGNCR": "syscall",
+ "syscall.IGNORE": "syscall",
+ "syscall.IGNPAR": "syscall",
+ "syscall.IMAXBEL": "syscall",
+ "syscall.INFINITE": "syscall",
+ "syscall.INLCR": "syscall",
+ "syscall.INPCK": "syscall",
+ "syscall.INVALID_FILE_ATTRIBUTES": "syscall",
+ "syscall.IN_ACCESS": "syscall",
+ "syscall.IN_ALL_EVENTS": "syscall",
+ "syscall.IN_ATTRIB": "syscall",
+ "syscall.IN_CLASSA_HOST": "syscall",
+ "syscall.IN_CLASSA_MAX": "syscall",
+ "syscall.IN_CLASSA_NET": "syscall",
+ "syscall.IN_CLASSA_NSHIFT": "syscall",
+ "syscall.IN_CLASSB_HOST": "syscall",
+ "syscall.IN_CLASSB_MAX": "syscall",
+ "syscall.IN_CLASSB_NET": "syscall",
+ "syscall.IN_CLASSB_NSHIFT": "syscall",
+ "syscall.IN_CLASSC_HOST": "syscall",
+ "syscall.IN_CLASSC_NET": "syscall",
+ "syscall.IN_CLASSC_NSHIFT": "syscall",
+ "syscall.IN_CLASSD_HOST": "syscall",
+ "syscall.IN_CLASSD_NET": "syscall",
+ "syscall.IN_CLASSD_NSHIFT": "syscall",
+ "syscall.IN_CLOEXEC": "syscall",
+ "syscall.IN_CLOSE": "syscall",
+ "syscall.IN_CLOSE_NOWRITE": "syscall",
+ "syscall.IN_CLOSE_WRITE": "syscall",
+ "syscall.IN_CREATE": "syscall",
+ "syscall.IN_DELETE": "syscall",
+ "syscall.IN_DELETE_SELF": "syscall",
+ "syscall.IN_DONT_FOLLOW": "syscall",
+ "syscall.IN_EXCL_UNLINK": "syscall",
+ "syscall.IN_IGNORED": "syscall",
+ "syscall.IN_ISDIR": "syscall",
+ "syscall.IN_LINKLOCALNETNUM": "syscall",
+ "syscall.IN_LOOPBACKNET": "syscall",
+ "syscall.IN_MASK_ADD": "syscall",
+ "syscall.IN_MODIFY": "syscall",
+ "syscall.IN_MOVE": "syscall",
+ "syscall.IN_MOVED_FROM": "syscall",
+ "syscall.IN_MOVED_TO": "syscall",
+ "syscall.IN_MOVE_SELF": "syscall",
+ "syscall.IN_NONBLOCK": "syscall",
+ "syscall.IN_ONESHOT": "syscall",
+ "syscall.IN_ONLYDIR": "syscall",
+ "syscall.IN_OPEN": "syscall",
+ "syscall.IN_Q_OVERFLOW": "syscall",
+ "syscall.IN_RFC3021_HOST": "syscall",
+ "syscall.IN_RFC3021_MASK": "syscall",
+ "syscall.IN_RFC3021_NET": "syscall",
+ "syscall.IN_RFC3021_NSHIFT": "syscall",
+ "syscall.IN_UNMOUNT": "syscall",
+ "syscall.IOC_IN": "syscall",
+ "syscall.IOC_INOUT": "syscall",
+ "syscall.IOC_OUT": "syscall",
+ "syscall.IOC_VENDOR": "syscall",
+ "syscall.IOC_WS2": "syscall",
+ "syscall.IPMreq": "syscall",
+ "syscall.IPMreqn": "syscall",
+ "syscall.IPPROTO_3PC": "syscall",
+ "syscall.IPPROTO_ADFS": "syscall",
+ "syscall.IPPROTO_AH": "syscall",
+ "syscall.IPPROTO_AHIP": "syscall",
+ "syscall.IPPROTO_APES": "syscall",
+ "syscall.IPPROTO_ARGUS": "syscall",
+ "syscall.IPPROTO_AX25": "syscall",
+ "syscall.IPPROTO_BHA": "syscall",
+ "syscall.IPPROTO_BLT": "syscall",
+ "syscall.IPPROTO_BRSATMON": "syscall",
+ "syscall.IPPROTO_CARP": "syscall",
+ "syscall.IPPROTO_CFTP": "syscall",
+ "syscall.IPPROTO_CHAOS": "syscall",
+ "syscall.IPPROTO_CMTP": "syscall",
+ "syscall.IPPROTO_COMP": "syscall",
+ "syscall.IPPROTO_CPHB": "syscall",
+ "syscall.IPPROTO_CPNX": "syscall",
+ "syscall.IPPROTO_DCCP": "syscall",
+ "syscall.IPPROTO_DDP": "syscall",
+ "syscall.IPPROTO_DGP": "syscall",
+ "syscall.IPPROTO_DIVERT": "syscall",
+ "syscall.IPPROTO_DIVERT_INIT": "syscall",
+ "syscall.IPPROTO_DIVERT_RESP": "syscall",
+ "syscall.IPPROTO_DONE": "syscall",
+ "syscall.IPPROTO_DSTOPTS": "syscall",
+ "syscall.IPPROTO_EGP": "syscall",
+ "syscall.IPPROTO_EMCON": "syscall",
+ "syscall.IPPROTO_ENCAP": "syscall",
+ "syscall.IPPROTO_EON": "syscall",
+ "syscall.IPPROTO_ESP": "syscall",
+ "syscall.IPPROTO_ETHERIP": "syscall",
+ "syscall.IPPROTO_FRAGMENT": "syscall",
+ "syscall.IPPROTO_GGP": "syscall",
+ "syscall.IPPROTO_GMTP": "syscall",
+ "syscall.IPPROTO_GRE": "syscall",
+ "syscall.IPPROTO_HELLO": "syscall",
+ "syscall.IPPROTO_HMP": "syscall",
+ "syscall.IPPROTO_HOPOPTS": "syscall",
+ "syscall.IPPROTO_ICMP": "syscall",
+ "syscall.IPPROTO_ICMPV6": "syscall",
+ "syscall.IPPROTO_IDP": "syscall",
+ "syscall.IPPROTO_IDPR": "syscall",
+ "syscall.IPPROTO_IDRP": "syscall",
+ "syscall.IPPROTO_IGMP": "syscall",
+ "syscall.IPPROTO_IGP": "syscall",
+ "syscall.IPPROTO_IGRP": "syscall",
+ "syscall.IPPROTO_IL": "syscall",
+ "syscall.IPPROTO_INLSP": "syscall",
+ "syscall.IPPROTO_INP": "syscall",
+ "syscall.IPPROTO_IP": "syscall",
+ "syscall.IPPROTO_IPCOMP": "syscall",
+ "syscall.IPPROTO_IPCV": "syscall",
+ "syscall.IPPROTO_IPEIP": "syscall",
+ "syscall.IPPROTO_IPIP": "syscall",
+ "syscall.IPPROTO_IPPC": "syscall",
+ "syscall.IPPROTO_IPV4": "syscall",
+ "syscall.IPPROTO_IPV6": "syscall",
+ "syscall.IPPROTO_IPV6_ICMP": "syscall",
+ "syscall.IPPROTO_IRTP": "syscall",
+ "syscall.IPPROTO_KRYPTOLAN": "syscall",
+ "syscall.IPPROTO_LARP": "syscall",
+ "syscall.IPPROTO_LEAF1": "syscall",
+ "syscall.IPPROTO_LEAF2": "syscall",
+ "syscall.IPPROTO_MAX": "syscall",
+ "syscall.IPPROTO_MAXID": "syscall",
+ "syscall.IPPROTO_MEAS": "syscall",
+ "syscall.IPPROTO_MH": "syscall",
+ "syscall.IPPROTO_MHRP": "syscall",
+ "syscall.IPPROTO_MICP": "syscall",
+ "syscall.IPPROTO_MOBILE": "syscall",
+ "syscall.IPPROTO_MPLS": "syscall",
+ "syscall.IPPROTO_MTP": "syscall",
+ "syscall.IPPROTO_MUX": "syscall",
+ "syscall.IPPROTO_ND": "syscall",
+ "syscall.IPPROTO_NHRP": "syscall",
+ "syscall.IPPROTO_NONE": "syscall",
+ "syscall.IPPROTO_NSP": "syscall",
+ "syscall.IPPROTO_NVPII": "syscall",
+ "syscall.IPPROTO_OLD_DIVERT": "syscall",
+ "syscall.IPPROTO_OSPFIGP": "syscall",
+ "syscall.IPPROTO_PFSYNC": "syscall",
+ "syscall.IPPROTO_PGM": "syscall",
+ "syscall.IPPROTO_PIGP": "syscall",
+ "syscall.IPPROTO_PIM": "syscall",
+ "syscall.IPPROTO_PRM": "syscall",
+ "syscall.IPPROTO_PUP": "syscall",
+ "syscall.IPPROTO_PVP": "syscall",
+ "syscall.IPPROTO_RAW": "syscall",
+ "syscall.IPPROTO_RCCMON": "syscall",
+ "syscall.IPPROTO_RDP": "syscall",
+ "syscall.IPPROTO_ROUTING": "syscall",
+ "syscall.IPPROTO_RSVP": "syscall",
+ "syscall.IPPROTO_RVD": "syscall",
+ "syscall.IPPROTO_SATEXPAK": "syscall",
+ "syscall.IPPROTO_SATMON": "syscall",
+ "syscall.IPPROTO_SCCSP": "syscall",
+ "syscall.IPPROTO_SCTP": "syscall",
+ "syscall.IPPROTO_SDRP": "syscall",
+ "syscall.IPPROTO_SEND": "syscall",
+ "syscall.IPPROTO_SEP": "syscall",
+ "syscall.IPPROTO_SKIP": "syscall",
+ "syscall.IPPROTO_SPACER": "syscall",
+ "syscall.IPPROTO_SRPC": "syscall",
+ "syscall.IPPROTO_ST": "syscall",
+ "syscall.IPPROTO_SVMTP": "syscall",
+ "syscall.IPPROTO_SWIPE": "syscall",
+ "syscall.IPPROTO_TCF": "syscall",
+ "syscall.IPPROTO_TCP": "syscall",
+ "syscall.IPPROTO_TLSP": "syscall",
+ "syscall.IPPROTO_TP": "syscall",
+ "syscall.IPPROTO_TPXX": "syscall",
+ "syscall.IPPROTO_TRUNK1": "syscall",
+ "syscall.IPPROTO_TRUNK2": "syscall",
+ "syscall.IPPROTO_TTP": "syscall",
+ "syscall.IPPROTO_UDP": "syscall",
+ "syscall.IPPROTO_UDPLITE": "syscall",
+ "syscall.IPPROTO_VINES": "syscall",
+ "syscall.IPPROTO_VISA": "syscall",
+ "syscall.IPPROTO_VMTP": "syscall",
+ "syscall.IPPROTO_VRRP": "syscall",
+ "syscall.IPPROTO_WBEXPAK": "syscall",
+ "syscall.IPPROTO_WBMON": "syscall",
+ "syscall.IPPROTO_WSN": "syscall",
+ "syscall.IPPROTO_XNET": "syscall",
+ "syscall.IPPROTO_XTP": "syscall",
+ "syscall.IPV6_2292DSTOPTS": "syscall",
+ "syscall.IPV6_2292HOPLIMIT": "syscall",
+ "syscall.IPV6_2292HOPOPTS": "syscall",
+ "syscall.IPV6_2292NEXTHOP": "syscall",
+ "syscall.IPV6_2292PKTINFO": "syscall",
+ "syscall.IPV6_2292PKTOPTIONS": "syscall",
+ "syscall.IPV6_2292RTHDR": "syscall",
+ "syscall.IPV6_ADDRFORM": "syscall",
+ "syscall.IPV6_ADD_MEMBERSHIP": "syscall",
+ "syscall.IPV6_AUTHHDR": "syscall",
+ "syscall.IPV6_AUTH_LEVEL": "syscall",
+ "syscall.IPV6_AUTOFLOWLABEL": "syscall",
+ "syscall.IPV6_BINDANY": "syscall",
+ "syscall.IPV6_BINDV6ONLY": "syscall",
+ "syscall.IPV6_BOUND_IF": "syscall",
+ "syscall.IPV6_CHECKSUM": "syscall",
+ "syscall.IPV6_DEFAULT_MULTICAST_HOPS": "syscall",
+ "syscall.IPV6_DEFAULT_MULTICAST_LOOP": "syscall",
+ "syscall.IPV6_DEFHLIM": "syscall",
+ "syscall.IPV6_DONTFRAG": "syscall",
+ "syscall.IPV6_DROP_MEMBERSHIP": "syscall",
+ "syscall.IPV6_DSTOPTS": "syscall",
+ "syscall.IPV6_ESP_NETWORK_LEVEL": "syscall",
+ "syscall.IPV6_ESP_TRANS_LEVEL": "syscall",
+ "syscall.IPV6_FAITH": "syscall",
+ "syscall.IPV6_FLOWINFO_MASK": "syscall",
+ "syscall.IPV6_FLOWLABEL_MASK": "syscall",
+ "syscall.IPV6_FRAGTTL": "syscall",
+ "syscall.IPV6_FW_ADD": "syscall",
+ "syscall.IPV6_FW_DEL": "syscall",
+ "syscall.IPV6_FW_FLUSH": "syscall",
+ "syscall.IPV6_FW_GET": "syscall",
+ "syscall.IPV6_FW_ZERO": "syscall",
+ "syscall.IPV6_HLIMDEC": "syscall",
+ "syscall.IPV6_HOPLIMIT": "syscall",
+ "syscall.IPV6_HOPOPTS": "syscall",
+ "syscall.IPV6_IPCOMP_LEVEL": "syscall",
+ "syscall.IPV6_IPSEC_POLICY": "syscall",
+ "syscall.IPV6_JOIN_ANYCAST": "syscall",
+ "syscall.IPV6_JOIN_GROUP": "syscall",
+ "syscall.IPV6_LEAVE_ANYCAST": "syscall",
+ "syscall.IPV6_LEAVE_GROUP": "syscall",
+ "syscall.IPV6_MAXHLIM": "syscall",
+ "syscall.IPV6_MAXOPTHDR": "syscall",
+ "syscall.IPV6_MAXPACKET": "syscall",
+ "syscall.IPV6_MAX_GROUP_SRC_FILTER": "syscall",
+ "syscall.IPV6_MAX_MEMBERSHIPS": "syscall",
+ "syscall.IPV6_MAX_SOCK_SRC_FILTER": "syscall",
+ "syscall.IPV6_MIN_MEMBERSHIPS": "syscall",
+ "syscall.IPV6_MMTU": "syscall",
+ "syscall.IPV6_MSFILTER": "syscall",
+ "syscall.IPV6_MTU": "syscall",
+ "syscall.IPV6_MTU_DISCOVER": "syscall",
+ "syscall.IPV6_MULTICAST_HOPS": "syscall",
+ "syscall.IPV6_MULTICAST_IF": "syscall",
+ "syscall.IPV6_MULTICAST_LOOP": "syscall",
+ "syscall.IPV6_NEXTHOP": "syscall",
+ "syscall.IPV6_OPTIONS": "syscall",
+ "syscall.IPV6_PATHMTU": "syscall",
+ "syscall.IPV6_PIPEX": "syscall",
+ "syscall.IPV6_PKTINFO": "syscall",
+ "syscall.IPV6_PMTUDISC_DO": "syscall",
+ "syscall.IPV6_PMTUDISC_DONT": "syscall",
+ "syscall.IPV6_PMTUDISC_PROBE": "syscall",
+ "syscall.IPV6_PMTUDISC_WANT": "syscall",
+ "syscall.IPV6_PORTRANGE": "syscall",
+ "syscall.IPV6_PORTRANGE_DEFAULT": "syscall",
+ "syscall.IPV6_PORTRANGE_HIGH": "syscall",
+ "syscall.IPV6_PORTRANGE_LOW": "syscall",
+ "syscall.IPV6_PREFER_TEMPADDR": "syscall",
+ "syscall.IPV6_RECVDSTOPTS": "syscall",
+ "syscall.IPV6_RECVDSTPORT": "syscall",
+ "syscall.IPV6_RECVERR": "syscall",
+ "syscall.IPV6_RECVHOPLIMIT": "syscall",
+ "syscall.IPV6_RECVHOPOPTS": "syscall",
+ "syscall.IPV6_RECVPATHMTU": "syscall",
+ "syscall.IPV6_RECVPKTINFO": "syscall",
+ "syscall.IPV6_RECVRTHDR": "syscall",
+ "syscall.IPV6_RECVTCLASS": "syscall",
+ "syscall.IPV6_ROUTER_ALERT": "syscall",
+ "syscall.IPV6_RTABLE": "syscall",
+ "syscall.IPV6_RTHDR": "syscall",
+ "syscall.IPV6_RTHDRDSTOPTS": "syscall",
+ "syscall.IPV6_RTHDR_LOOSE": "syscall",
+ "syscall.IPV6_RTHDR_STRICT": "syscall",
+ "syscall.IPV6_RTHDR_TYPE_0": "syscall",
+ "syscall.IPV6_RXDSTOPTS": "syscall",
+ "syscall.IPV6_RXHOPOPTS": "syscall",
+ "syscall.IPV6_SOCKOPT_RESERVED1": "syscall",
+ "syscall.IPV6_TCLASS": "syscall",
+ "syscall.IPV6_UNICAST_HOPS": "syscall",
+ "syscall.IPV6_USE_MIN_MTU": "syscall",
+ "syscall.IPV6_V6ONLY": "syscall",
+ "syscall.IPV6_VERSION": "syscall",
+ "syscall.IPV6_VERSION_MASK": "syscall",
+ "syscall.IPV6_XFRM_POLICY": "syscall",
+ "syscall.IP_ADD_MEMBERSHIP": "syscall",
+ "syscall.IP_ADD_SOURCE_MEMBERSHIP": "syscall",
+ "syscall.IP_AUTH_LEVEL": "syscall",
+ "syscall.IP_BINDANY": "syscall",
+ "syscall.IP_BLOCK_SOURCE": "syscall",
+ "syscall.IP_BOUND_IF": "syscall",
+ "syscall.IP_DEFAULT_MULTICAST_LOOP": "syscall",
+ "syscall.IP_DEFAULT_MULTICAST_TTL": "syscall",
+ "syscall.IP_DF": "syscall",
+ "syscall.IP_DIVERTFL": "syscall",
+ "syscall.IP_DONTFRAG": "syscall",
+ "syscall.IP_DROP_MEMBERSHIP": "syscall",
+ "syscall.IP_DROP_SOURCE_MEMBERSHIP": "syscall",
+ "syscall.IP_DUMMYNET3": "syscall",
+ "syscall.IP_DUMMYNET_CONFIGURE": "syscall",
+ "syscall.IP_DUMMYNET_DEL": "syscall",
+ "syscall.IP_DUMMYNET_FLUSH": "syscall",
+ "syscall.IP_DUMMYNET_GET": "syscall",
+ "syscall.IP_EF": "syscall",
+ "syscall.IP_ERRORMTU": "syscall",
+ "syscall.IP_ESP_NETWORK_LEVEL": "syscall",
+ "syscall.IP_ESP_TRANS_LEVEL": "syscall",
+ "syscall.IP_FAITH": "syscall",
+ "syscall.IP_FREEBIND": "syscall",
+ "syscall.IP_FW3": "syscall",
+ "syscall.IP_FW_ADD": "syscall",
+ "syscall.IP_FW_DEL": "syscall",
+ "syscall.IP_FW_FLUSH": "syscall",
+ "syscall.IP_FW_GET": "syscall",
+ "syscall.IP_FW_NAT_CFG": "syscall",
+ "syscall.IP_FW_NAT_DEL": "syscall",
+ "syscall.IP_FW_NAT_GET_CONFIG": "syscall",
+ "syscall.IP_FW_NAT_GET_LOG": "syscall",
+ "syscall.IP_FW_RESETLOG": "syscall",
+ "syscall.IP_FW_TABLE_ADD": "syscall",
+ "syscall.IP_FW_TABLE_DEL": "syscall",
+ "syscall.IP_FW_TABLE_FLUSH": "syscall",
+ "syscall.IP_FW_TABLE_GETSIZE": "syscall",
+ "syscall.IP_FW_TABLE_LIST": "syscall",
+ "syscall.IP_FW_ZERO": "syscall",
+ "syscall.IP_HDRINCL": "syscall",
+ "syscall.IP_IPCOMP_LEVEL": "syscall",
+ "syscall.IP_IPSECFLOWINFO": "syscall",
+ "syscall.IP_IPSEC_LOCAL_AUTH": "syscall",
+ "syscall.IP_IPSEC_LOCAL_CRED": "syscall",
+ "syscall.IP_IPSEC_LOCAL_ID": "syscall",
+ "syscall.IP_IPSEC_POLICY": "syscall",
+ "syscall.IP_IPSEC_REMOTE_AUTH": "syscall",
+ "syscall.IP_IPSEC_REMOTE_CRED": "syscall",
+ "syscall.IP_IPSEC_REMOTE_ID": "syscall",
+ "syscall.IP_MAXPACKET": "syscall",
+ "syscall.IP_MAX_GROUP_SRC_FILTER": "syscall",
+ "syscall.IP_MAX_MEMBERSHIPS": "syscall",
+ "syscall.IP_MAX_SOCK_MUTE_FILTER": "syscall",
+ "syscall.IP_MAX_SOCK_SRC_FILTER": "syscall",
+ "syscall.IP_MAX_SOURCE_FILTER": "syscall",
+ "syscall.IP_MF": "syscall",
+ "syscall.IP_MINFRAGSIZE": "syscall",
+ "syscall.IP_MINTTL": "syscall",
+ "syscall.IP_MIN_MEMBERSHIPS": "syscall",
+ "syscall.IP_MSFILTER": "syscall",
+ "syscall.IP_MSS": "syscall",
+ "syscall.IP_MTU": "syscall",
+ "syscall.IP_MTU_DISCOVER": "syscall",
+ "syscall.IP_MULTICAST_IF": "syscall",
+ "syscall.IP_MULTICAST_IFINDEX": "syscall",
+ "syscall.IP_MULTICAST_LOOP": "syscall",
+ "syscall.IP_MULTICAST_TTL": "syscall",
+ "syscall.IP_MULTICAST_VIF": "syscall",
+ "syscall.IP_NAT__XXX": "syscall",
+ "syscall.IP_OFFMASK": "syscall",
+ "syscall.IP_OLD_FW_ADD": "syscall",
+ "syscall.IP_OLD_FW_DEL": "syscall",
+ "syscall.IP_OLD_FW_FLUSH": "syscall",
+ "syscall.IP_OLD_FW_GET": "syscall",
+ "syscall.IP_OLD_FW_RESETLOG": "syscall",
+ "syscall.IP_OLD_FW_ZERO": "syscall",
+ "syscall.IP_ONESBCAST": "syscall",
+ "syscall.IP_OPTIONS": "syscall",
+ "syscall.IP_ORIGDSTADDR": "syscall",
+ "syscall.IP_PASSSEC": "syscall",
+ "syscall.IP_PIPEX": "syscall",
+ "syscall.IP_PKTINFO": "syscall",
+ "syscall.IP_PKTOPTIONS": "syscall",
+ "syscall.IP_PMTUDISC": "syscall",
+ "syscall.IP_PMTUDISC_DO": "syscall",
+ "syscall.IP_PMTUDISC_DONT": "syscall",
+ "syscall.IP_PMTUDISC_PROBE": "syscall",
+ "syscall.IP_PMTUDISC_WANT": "syscall",
+ "syscall.IP_PORTRANGE": "syscall",
+ "syscall.IP_PORTRANGE_DEFAULT": "syscall",
+ "syscall.IP_PORTRANGE_HIGH": "syscall",
+ "syscall.IP_PORTRANGE_LOW": "syscall",
+ "syscall.IP_RECVDSTADDR": "syscall",
+ "syscall.IP_RECVDSTPORT": "syscall",
+ "syscall.IP_RECVERR": "syscall",
+ "syscall.IP_RECVIF": "syscall",
+ "syscall.IP_RECVOPTS": "syscall",
+ "syscall.IP_RECVORIGDSTADDR": "syscall",
+ "syscall.IP_RECVPKTINFO": "syscall",
+ "syscall.IP_RECVRETOPTS": "syscall",
+ "syscall.IP_RECVRTABLE": "syscall",
+ "syscall.IP_RECVTOS": "syscall",
+ "syscall.IP_RECVTTL": "syscall",
+ "syscall.IP_RETOPTS": "syscall",
+ "syscall.IP_RF": "syscall",
+ "syscall.IP_ROUTER_ALERT": "syscall",
+ "syscall.IP_RSVP_OFF": "syscall",
+ "syscall.IP_RSVP_ON": "syscall",
+ "syscall.IP_RSVP_VIF_OFF": "syscall",
+ "syscall.IP_RSVP_VIF_ON": "syscall",
+ "syscall.IP_RTABLE": "syscall",
+ "syscall.IP_SENDSRCADDR": "syscall",
+ "syscall.IP_STRIPHDR": "syscall",
+ "syscall.IP_TOS": "syscall",
+ "syscall.IP_TRAFFIC_MGT_BACKGROUND": "syscall",
+ "syscall.IP_TRANSPARENT": "syscall",
+ "syscall.IP_TTL": "syscall",
+ "syscall.IP_UNBLOCK_SOURCE": "syscall",
+ "syscall.IP_XFRM_POLICY": "syscall",
+ "syscall.IPv6MTUInfo": "syscall",
+ "syscall.IPv6Mreq": "syscall",
+ "syscall.ISIG": "syscall",
+ "syscall.ISTRIP": "syscall",
+ "syscall.IUCLC": "syscall",
+ "syscall.IUTF8": "syscall",
+ "syscall.IXANY": "syscall",
+ "syscall.IXOFF": "syscall",
+ "syscall.IXON": "syscall",
+ "syscall.IfAddrmsg": "syscall",
+ "syscall.IfAnnounceMsghdr": "syscall",
+ "syscall.IfData": "syscall",
+ "syscall.IfInfomsg": "syscall",
+ "syscall.IfMsghdr": "syscall",
+ "syscall.IfaMsghdr": "syscall",
+ "syscall.IfmaMsghdr": "syscall",
+ "syscall.IfmaMsghdr2": "syscall",
+ "syscall.ImplementsGetwd": "syscall",
+ "syscall.Inet4Pktinfo": "syscall",
+ "syscall.Inet6Pktinfo": "syscall",
+ "syscall.InotifyAddWatch": "syscall",
+ "syscall.InotifyEvent": "syscall",
+ "syscall.InotifyInit": "syscall",
+ "syscall.InotifyInit1": "syscall",
+ "syscall.InotifyRmWatch": "syscall",
+ "syscall.InterfaceAddrMessage": "syscall",
+ "syscall.InterfaceAnnounceMessage": "syscall",
+ "syscall.InterfaceInfo": "syscall",
+ "syscall.InterfaceMessage": "syscall",
+ "syscall.InterfaceMulticastAddrMessage": "syscall",
+ "syscall.InvalidHandle": "syscall",
+ "syscall.Ioperm": "syscall",
+ "syscall.Iopl": "syscall",
+ "syscall.Iovec": "syscall",
+ "syscall.IpAdapterInfo": "syscall",
+ "syscall.IpAddrString": "syscall",
+ "syscall.IpAddressString": "syscall",
+ "syscall.IpMaskString": "syscall",
+ "syscall.Issetugid": "syscall",
+ "syscall.KEY_ALL_ACCESS": "syscall",
+ "syscall.KEY_CREATE_LINK": "syscall",
+ "syscall.KEY_CREATE_SUB_KEY": "syscall",
+ "syscall.KEY_ENUMERATE_SUB_KEYS": "syscall",
+ "syscall.KEY_EXECUTE": "syscall",
+ "syscall.KEY_NOTIFY": "syscall",
+ "syscall.KEY_QUERY_VALUE": "syscall",
+ "syscall.KEY_READ": "syscall",
+ "syscall.KEY_SET_VALUE": "syscall",
+ "syscall.KEY_WOW64_32KEY": "syscall",
+ "syscall.KEY_WOW64_64KEY": "syscall",
+ "syscall.KEY_WRITE": "syscall",
+ "syscall.Kevent": "syscall",
+ "syscall.Kevent_t": "syscall",
+ "syscall.Kill": "syscall",
+ "syscall.Klogctl": "syscall",
+ "syscall.Kqueue": "syscall",
+ "syscall.LANG_ENGLISH": "syscall",
+ "syscall.LAYERED_PROTOCOL": "syscall",
+ "syscall.LCNT_OVERLOAD_FLUSH": "syscall",
+ "syscall.LINUX_REBOOT_CMD_CAD_OFF": "syscall",
+ "syscall.LINUX_REBOOT_CMD_CAD_ON": "syscall",
+ "syscall.LINUX_REBOOT_CMD_HALT": "syscall",
+ "syscall.LINUX_REBOOT_CMD_KEXEC": "syscall",
+ "syscall.LINUX_REBOOT_CMD_POWER_OFF": "syscall",
+ "syscall.LINUX_REBOOT_CMD_RESTART": "syscall",
+ "syscall.LINUX_REBOOT_CMD_RESTART2": "syscall",
+ "syscall.LINUX_REBOOT_CMD_SW_SUSPEND": "syscall",
+ "syscall.LINUX_REBOOT_MAGIC1": "syscall",
+ "syscall.LINUX_REBOOT_MAGIC2": "syscall",
+ "syscall.LOCK_EX": "syscall",
+ "syscall.LOCK_NB": "syscall",
+ "syscall.LOCK_SH": "syscall",
+ "syscall.LOCK_UN": "syscall",
+ "syscall.LazyDLL": "syscall",
+ "syscall.LazyProc": "syscall",
+ "syscall.Lchown": "syscall",
+ "syscall.Linger": "syscall",
+ "syscall.Link": "syscall",
+ "syscall.Listen": "syscall",
+ "syscall.Listxattr": "syscall",
+ "syscall.LoadCancelIoEx": "syscall",
+ "syscall.LoadConnectEx": "syscall",
+ "syscall.LoadDLL": "syscall",
+ "syscall.LoadGetAddrInfo": "syscall",
+ "syscall.LoadLibrary": "syscall",
+ "syscall.LoadSetFileCompletionNotificationModes": "syscall",
+ "syscall.LocalFree": "syscall",
+ "syscall.Log2phys_t": "syscall",
+ "syscall.LookupAccountName": "syscall",
+ "syscall.LookupAccountSid": "syscall",
+ "syscall.LookupSID": "syscall",
+ "syscall.LsfJump": "syscall",
+ "syscall.LsfSocket": "syscall",
+ "syscall.LsfStmt": "syscall",
+ "syscall.Lstat": "syscall",
+ "syscall.MADV_AUTOSYNC": "syscall",
+ "syscall.MADV_CAN_REUSE": "syscall",
+ "syscall.MADV_CORE": "syscall",
+ "syscall.MADV_DOFORK": "syscall",
+ "syscall.MADV_DONTFORK": "syscall",
+ "syscall.MADV_DONTNEED": "syscall",
+ "syscall.MADV_FREE": "syscall",
+ "syscall.MADV_FREE_REUSABLE": "syscall",
+ "syscall.MADV_FREE_REUSE": "syscall",
+ "syscall.MADV_HUGEPAGE": "syscall",
+ "syscall.MADV_HWPOISON": "syscall",
+ "syscall.MADV_MERGEABLE": "syscall",
+ "syscall.MADV_NOCORE": "syscall",
+ "syscall.MADV_NOHUGEPAGE": "syscall",
+ "syscall.MADV_NORMAL": "syscall",
+ "syscall.MADV_NOSYNC": "syscall",
+ "syscall.MADV_PROTECT": "syscall",
+ "syscall.MADV_RANDOM": "syscall",
+ "syscall.MADV_REMOVE": "syscall",
+ "syscall.MADV_SEQUENTIAL": "syscall",
+ "syscall.MADV_SPACEAVAIL": "syscall",
+ "syscall.MADV_UNMERGEABLE": "syscall",
+ "syscall.MADV_WILLNEED": "syscall",
+ "syscall.MADV_ZERO_WIRED_PAGES": "syscall",
+ "syscall.MAP_32BIT": "syscall",
+ "syscall.MAP_ALIGNED_SUPER": "syscall",
+ "syscall.MAP_ALIGNMENT_16MB": "syscall",
+ "syscall.MAP_ALIGNMENT_1TB": "syscall",
+ "syscall.MAP_ALIGNMENT_256TB": "syscall",
+ "syscall.MAP_ALIGNMENT_4GB": "syscall",
+ "syscall.MAP_ALIGNMENT_64KB": "syscall",
+ "syscall.MAP_ALIGNMENT_64PB": "syscall",
+ "syscall.MAP_ALIGNMENT_MASK": "syscall",
+ "syscall.MAP_ALIGNMENT_SHIFT": "syscall",
+ "syscall.MAP_ANON": "syscall",
+ "syscall.MAP_ANONYMOUS": "syscall",
+ "syscall.MAP_COPY": "syscall",
+ "syscall.MAP_DENYWRITE": "syscall",
+ "syscall.MAP_EXECUTABLE": "syscall",
+ "syscall.MAP_FILE": "syscall",
+ "syscall.MAP_FIXED": "syscall",
+ "syscall.MAP_FLAGMASK": "syscall",
+ "syscall.MAP_GROWSDOWN": "syscall",
+ "syscall.MAP_HASSEMAPHORE": "syscall",
+ "syscall.MAP_HUGETLB": "syscall",
+ "syscall.MAP_INHERIT": "syscall",
+ "syscall.MAP_INHERIT_COPY": "syscall",
+ "syscall.MAP_INHERIT_DEFAULT": "syscall",
+ "syscall.MAP_INHERIT_DONATE_COPY": "syscall",
+ "syscall.MAP_INHERIT_NONE": "syscall",
+ "syscall.MAP_INHERIT_SHARE": "syscall",
+ "syscall.MAP_JIT": "syscall",
+ "syscall.MAP_LOCKED": "syscall",
+ "syscall.MAP_NOCACHE": "syscall",
+ "syscall.MAP_NOCORE": "syscall",
+ "syscall.MAP_NOEXTEND": "syscall",
+ "syscall.MAP_NONBLOCK": "syscall",
+ "syscall.MAP_NORESERVE": "syscall",
+ "syscall.MAP_NOSYNC": "syscall",
+ "syscall.MAP_POPULATE": "syscall",
+ "syscall.MAP_PREFAULT_READ": "syscall",
+ "syscall.MAP_PRIVATE": "syscall",
+ "syscall.MAP_RENAME": "syscall",
+ "syscall.MAP_RESERVED0080": "syscall",
+ "syscall.MAP_RESERVED0100": "syscall",
+ "syscall.MAP_SHARED": "syscall",
+ "syscall.MAP_STACK": "syscall",
+ "syscall.MAP_TRYFIXED": "syscall",
+ "syscall.MAP_TYPE": "syscall",
+ "syscall.MAP_WIRED": "syscall",
+ "syscall.MAXLEN_IFDESCR": "syscall",
+ "syscall.MAXLEN_PHYSADDR": "syscall",
+ "syscall.MAX_ADAPTER_ADDRESS_LENGTH": "syscall",
+ "syscall.MAX_ADAPTER_DESCRIPTION_LENGTH": "syscall",
+ "syscall.MAX_ADAPTER_NAME_LENGTH": "syscall",
+ "syscall.MAX_COMPUTERNAME_LENGTH": "syscall",
+ "syscall.MAX_INTERFACE_NAME_LEN": "syscall",
+ "syscall.MAX_LONG_PATH": "syscall",
+ "syscall.MAX_PATH": "syscall",
+ "syscall.MAX_PROTOCOL_CHAIN": "syscall",
+ "syscall.MCL_CURRENT": "syscall",
+ "syscall.MCL_FUTURE": "syscall",
+ "syscall.MNT_DETACH": "syscall",
+ "syscall.MNT_EXPIRE": "syscall",
+ "syscall.MNT_FORCE": "syscall",
+ "syscall.MSG_BCAST": "syscall",
+ "syscall.MSG_CMSG_CLOEXEC": "syscall",
+ "syscall.MSG_COMPAT": "syscall",
+ "syscall.MSG_CONFIRM": "syscall",
+ "syscall.MSG_CONTROLMBUF": "syscall",
+ "syscall.MSG_CTRUNC": "syscall",
+ "syscall.MSG_DONTROUTE": "syscall",
+ "syscall.MSG_DONTWAIT": "syscall",
+ "syscall.MSG_EOF": "syscall",
+ "syscall.MSG_EOR": "syscall",
+ "syscall.MSG_ERRQUEUE": "syscall",
+ "syscall.MSG_FASTOPEN": "syscall",
+ "syscall.MSG_FIN": "syscall",
+ "syscall.MSG_FLUSH": "syscall",
+ "syscall.MSG_HAVEMORE": "syscall",
+ "syscall.MSG_HOLD": "syscall",
+ "syscall.MSG_IOVUSRSPACE": "syscall",
+ "syscall.MSG_LENUSRSPACE": "syscall",
+ "syscall.MSG_MCAST": "syscall",
+ "syscall.MSG_MORE": "syscall",
+ "syscall.MSG_NAMEMBUF": "syscall",
+ "syscall.MSG_NBIO": "syscall",
+ "syscall.MSG_NEEDSA": "syscall",
+ "syscall.MSG_NOSIGNAL": "syscall",
+ "syscall.MSG_NOTIFICATION": "syscall",
+ "syscall.MSG_OOB": "syscall",
+ "syscall.MSG_PEEK": "syscall",
+ "syscall.MSG_PROXY": "syscall",
+ "syscall.MSG_RCVMORE": "syscall",
+ "syscall.MSG_RST": "syscall",
+ "syscall.MSG_SEND": "syscall",
+ "syscall.MSG_SYN": "syscall",
+ "syscall.MSG_TRUNC": "syscall",
+ "syscall.MSG_TRYHARD": "syscall",
+ "syscall.MSG_USERFLAGS": "syscall",
+ "syscall.MSG_WAITALL": "syscall",
+ "syscall.MSG_WAITFORONE": "syscall",
+ "syscall.MSG_WAITSTREAM": "syscall",
+ "syscall.MS_ACTIVE": "syscall",
+ "syscall.MS_ASYNC": "syscall",
+ "syscall.MS_BIND": "syscall",
+ "syscall.MS_DEACTIVATE": "syscall",
+ "syscall.MS_DIRSYNC": "syscall",
+ "syscall.MS_INVALIDATE": "syscall",
+ "syscall.MS_I_VERSION": "syscall",
+ "syscall.MS_KERNMOUNT": "syscall",
+ "syscall.MS_KILLPAGES": "syscall",
+ "syscall.MS_MANDLOCK": "syscall",
+ "syscall.MS_MGC_MSK": "syscall",
+ "syscall.MS_MGC_VAL": "syscall",
+ "syscall.MS_MOVE": "syscall",
+ "syscall.MS_NOATIME": "syscall",
+ "syscall.MS_NODEV": "syscall",
+ "syscall.MS_NODIRATIME": "syscall",
+ "syscall.MS_NOEXEC": "syscall",
+ "syscall.MS_NOSUID": "syscall",
+ "syscall.MS_NOUSER": "syscall",
+ "syscall.MS_POSIXACL": "syscall",
+ "syscall.MS_PRIVATE": "syscall",
+ "syscall.MS_RDONLY": "syscall",
+ "syscall.MS_REC": "syscall",
+ "syscall.MS_RELATIME": "syscall",
+ "syscall.MS_REMOUNT": "syscall",
+ "syscall.MS_RMT_MASK": "syscall",
+ "syscall.MS_SHARED": "syscall",
+ "syscall.MS_SILENT": "syscall",
+ "syscall.MS_SLAVE": "syscall",
+ "syscall.MS_STRICTATIME": "syscall",
+ "syscall.MS_SYNC": "syscall",
+ "syscall.MS_SYNCHRONOUS": "syscall",
+ "syscall.MS_UNBINDABLE": "syscall",
+ "syscall.Madvise": "syscall",
+ "syscall.MapViewOfFile": "syscall",
+ "syscall.MaxTokenInfoClass": "syscall",
+ "syscall.Mclpool": "syscall",
+ "syscall.MibIfRow": "syscall",
+ "syscall.Mkdir": "syscall",
+ "syscall.Mkdirat": "syscall",
+ "syscall.Mkfifo": "syscall",
+ "syscall.Mknod": "syscall",
+ "syscall.Mknodat": "syscall",
+ "syscall.Mlock": "syscall",
+ "syscall.Mlockall": "syscall",
+ "syscall.Mmap": "syscall",
+ "syscall.Mount": "syscall",
+ "syscall.MoveFile": "syscall",
+ "syscall.Mprotect": "syscall",
+ "syscall.Msghdr": "syscall",
+ "syscall.Munlock": "syscall",
+ "syscall.Munlockall": "syscall",
+ "syscall.Munmap": "syscall",
+ "syscall.MustLoadDLL": "syscall",
+ "syscall.NAME_MAX": "syscall",
+ "syscall.NETLINK_ADD_MEMBERSHIP": "syscall",
+ "syscall.NETLINK_AUDIT": "syscall",
+ "syscall.NETLINK_BROADCAST_ERROR": "syscall",
+ "syscall.NETLINK_CONNECTOR": "syscall",
+ "syscall.NETLINK_DNRTMSG": "syscall",
+ "syscall.NETLINK_DROP_MEMBERSHIP": "syscall",
+ "syscall.NETLINK_ECRYPTFS": "syscall",
+ "syscall.NETLINK_FIB_LOOKUP": "syscall",
+ "syscall.NETLINK_FIREWALL": "syscall",
+ "syscall.NETLINK_GENERIC": "syscall",
+ "syscall.NETLINK_INET_DIAG": "syscall",
+ "syscall.NETLINK_IP6_FW": "syscall",
+ "syscall.NETLINK_ISCSI": "syscall",
+ "syscall.NETLINK_KOBJECT_UEVENT": "syscall",
+ "syscall.NETLINK_NETFILTER": "syscall",
+ "syscall.NETLINK_NFLOG": "syscall",
+ "syscall.NETLINK_NO_ENOBUFS": "syscall",
+ "syscall.NETLINK_PKTINFO": "syscall",
+ "syscall.NETLINK_RDMA": "syscall",
+ "syscall.NETLINK_ROUTE": "syscall",
+ "syscall.NETLINK_SCSITRANSPORT": "syscall",
+ "syscall.NETLINK_SELINUX": "syscall",
+ "syscall.NETLINK_UNUSED": "syscall",
+ "syscall.NETLINK_USERSOCK": "syscall",
+ "syscall.NETLINK_XFRM": "syscall",
+ "syscall.NET_RT_DUMP": "syscall",
+ "syscall.NET_RT_DUMP2": "syscall",
+ "syscall.NET_RT_FLAGS": "syscall",
+ "syscall.NET_RT_IFLIST": "syscall",
+ "syscall.NET_RT_IFLIST2": "syscall",
+ "syscall.NET_RT_IFLISTL": "syscall",
+ "syscall.NET_RT_IFMALIST": "syscall",
+ "syscall.NET_RT_MAXID": "syscall",
+ "syscall.NET_RT_OIFLIST": "syscall",
+ "syscall.NET_RT_OOIFLIST": "syscall",
+ "syscall.NET_RT_STAT": "syscall",
+ "syscall.NET_RT_STATS": "syscall",
+ "syscall.NET_RT_TABLE": "syscall",
+ "syscall.NET_RT_TRASH": "syscall",
+ "syscall.NLA_ALIGNTO": "syscall",
+ "syscall.NLA_F_NESTED": "syscall",
+ "syscall.NLA_F_NET_BYTEORDER": "syscall",
+ "syscall.NLA_HDRLEN": "syscall",
+ "syscall.NLMSG_ALIGNTO": "syscall",
+ "syscall.NLMSG_DONE": "syscall",
+ "syscall.NLMSG_ERROR": "syscall",
+ "syscall.NLMSG_HDRLEN": "syscall",
+ "syscall.NLMSG_MIN_TYPE": "syscall",
+ "syscall.NLMSG_NOOP": "syscall",
+ "syscall.NLMSG_OVERRUN": "syscall",
+ "syscall.NLM_F_ACK": "syscall",
+ "syscall.NLM_F_APPEND": "syscall",
+ "syscall.NLM_F_ATOMIC": "syscall",
+ "syscall.NLM_F_CREATE": "syscall",
+ "syscall.NLM_F_DUMP": "syscall",
+ "syscall.NLM_F_ECHO": "syscall",
+ "syscall.NLM_F_EXCL": "syscall",
+ "syscall.NLM_F_MATCH": "syscall",
+ "syscall.NLM_F_MULTI": "syscall",
+ "syscall.NLM_F_REPLACE": "syscall",
+ "syscall.NLM_F_REQUEST": "syscall",
+ "syscall.NLM_F_ROOT": "syscall",
+ "syscall.NOFLSH": "syscall",
+ "syscall.NOTE_ABSOLUTE": "syscall",
+ "syscall.NOTE_ATTRIB": "syscall",
+ "syscall.NOTE_CHILD": "syscall",
+ "syscall.NOTE_DELETE": "syscall",
+ "syscall.NOTE_EOF": "syscall",
+ "syscall.NOTE_EXEC": "syscall",
+ "syscall.NOTE_EXIT": "syscall",
+ "syscall.NOTE_EXITSTATUS": "syscall",
+ "syscall.NOTE_EXTEND": "syscall",
+ "syscall.NOTE_FFAND": "syscall",
+ "syscall.NOTE_FFCOPY": "syscall",
+ "syscall.NOTE_FFCTRLMASK": "syscall",
+ "syscall.NOTE_FFLAGSMASK": "syscall",
+ "syscall.NOTE_FFNOP": "syscall",
+ "syscall.NOTE_FFOR": "syscall",
+ "syscall.NOTE_FORK": "syscall",
+ "syscall.NOTE_LINK": "syscall",
+ "syscall.NOTE_LOWAT": "syscall",
+ "syscall.NOTE_NONE": "syscall",
+ "syscall.NOTE_NSECONDS": "syscall",
+ "syscall.NOTE_PCTRLMASK": "syscall",
+ "syscall.NOTE_PDATAMASK": "syscall",
+ "syscall.NOTE_REAP": "syscall",
+ "syscall.NOTE_RENAME": "syscall",
+ "syscall.NOTE_RESOURCEEND": "syscall",
+ "syscall.NOTE_REVOKE": "syscall",
+ "syscall.NOTE_SECONDS": "syscall",
+ "syscall.NOTE_SIGNAL": "syscall",
+ "syscall.NOTE_TRACK": "syscall",
+ "syscall.NOTE_TRACKERR": "syscall",
+ "syscall.NOTE_TRIGGER": "syscall",
+ "syscall.NOTE_TRUNCATE": "syscall",
+ "syscall.NOTE_USECONDS": "syscall",
+ "syscall.NOTE_VM_ERROR": "syscall",
+ "syscall.NOTE_VM_PRESSURE": "syscall",
+ "syscall.NOTE_VM_PRESSURE_SUDDEN_TERMINATE": "syscall",
+ "syscall.NOTE_VM_PRESSURE_TERMINATE": "syscall",
+ "syscall.NOTE_WRITE": "syscall",
+ "syscall.NameCanonical": "syscall",
+ "syscall.NameCanonicalEx": "syscall",
+ "syscall.NameDisplay": "syscall",
+ "syscall.NameDnsDomain": "syscall",
+ "syscall.NameFullyQualifiedDN": "syscall",
+ "syscall.NameSamCompatible": "syscall",
+ "syscall.NameServicePrincipal": "syscall",
+ "syscall.NameUniqueId": "syscall",
+ "syscall.NameUnknown": "syscall",
+ "syscall.NameUserPrincipal": "syscall",
+ "syscall.Nanosleep": "syscall",
+ "syscall.NetApiBufferFree": "syscall",
+ "syscall.NetGetJoinInformation": "syscall",
+ "syscall.NetSetupDomainName": "syscall",
+ "syscall.NetSetupUnjoined": "syscall",
+ "syscall.NetSetupUnknownStatus": "syscall",
+ "syscall.NetSetupWorkgroupName": "syscall",
+ "syscall.NetUserGetInfo": "syscall",
+ "syscall.NetlinkMessage": "syscall",
+ "syscall.NetlinkRIB": "syscall",
+ "syscall.NetlinkRouteAttr": "syscall",
+ "syscall.NetlinkRouteRequest": "syscall",
+ "syscall.NewCallback": "syscall",
+ "syscall.NewCallbackCDecl": "syscall",
+ "syscall.NewLazyDLL": "syscall",
+ "syscall.NlAttr": "syscall",
+ "syscall.NlMsgerr": "syscall",
+ "syscall.NlMsghdr": "syscall",
+ "syscall.NsecToFiletime": "syscall",
+ "syscall.NsecToTimespec": "syscall",
+ "syscall.NsecToTimeval": "syscall",
+ "syscall.Ntohs": "syscall",
+ "syscall.OCRNL": "syscall",
+ "syscall.OFDEL": "syscall",
+ "syscall.OFILL": "syscall",
+ "syscall.OFIOGETBMAP": "syscall",
+ "syscall.OID_PKIX_KP_SERVER_AUTH": "syscall",
+ "syscall.OID_SERVER_GATED_CRYPTO": "syscall",
+ "syscall.OID_SGC_NETSCAPE": "syscall",
+ "syscall.OLCUC": "syscall",
+ "syscall.ONLCR": "syscall",
+ "syscall.ONLRET": "syscall",
+ "syscall.ONOCR": "syscall",
+ "syscall.ONOEOT": "syscall",
+ "syscall.OPEN_ALWAYS": "syscall",
+ "syscall.OPEN_EXISTING": "syscall",
+ "syscall.OPOST": "syscall",
+ "syscall.O_ACCMODE": "syscall",
+ "syscall.O_ALERT": "syscall",
+ "syscall.O_ALT_IO": "syscall",
+ "syscall.O_APPEND": "syscall",
+ "syscall.O_ASYNC": "syscall",
+ "syscall.O_CLOEXEC": "syscall",
+ "syscall.O_CREAT": "syscall",
+ "syscall.O_DIRECT": "syscall",
+ "syscall.O_DIRECTORY": "syscall",
+ "syscall.O_DSYNC": "syscall",
+ "syscall.O_EVTONLY": "syscall",
+ "syscall.O_EXCL": "syscall",
+ "syscall.O_EXEC": "syscall",
+ "syscall.O_EXLOCK": "syscall",
+ "syscall.O_FSYNC": "syscall",
+ "syscall.O_LARGEFILE": "syscall",
+ "syscall.O_NDELAY": "syscall",
+ "syscall.O_NOATIME": "syscall",
+ "syscall.O_NOCTTY": "syscall",
+ "syscall.O_NOFOLLOW": "syscall",
+ "syscall.O_NONBLOCK": "syscall",
+ "syscall.O_NOSIGPIPE": "syscall",
+ "syscall.O_POPUP": "syscall",
+ "syscall.O_RDONLY": "syscall",
+ "syscall.O_RDWR": "syscall",
+ "syscall.O_RSYNC": "syscall",
+ "syscall.O_SHLOCK": "syscall",
+ "syscall.O_SYMLINK": "syscall",
+ "syscall.O_SYNC": "syscall",
+ "syscall.O_TRUNC": "syscall",
+ "syscall.O_TTY_INIT": "syscall",
+ "syscall.O_WRONLY": "syscall",
+ "syscall.Open": "syscall",
+ "syscall.OpenCurrentProcessToken": "syscall",
+ "syscall.OpenProcess": "syscall",
+ "syscall.OpenProcessToken": "syscall",
+ "syscall.Openat": "syscall",
+ "syscall.Overlapped": "syscall",
+ "syscall.PACKET_ADD_MEMBERSHIP": "syscall",
+ "syscall.PACKET_BROADCAST": "syscall",
+ "syscall.PACKET_DROP_MEMBERSHIP": "syscall",
+ "syscall.PACKET_FASTROUTE": "syscall",
+ "syscall.PACKET_HOST": "syscall",
+ "syscall.PACKET_LOOPBACK": "syscall",
+ "syscall.PACKET_MR_ALLMULTI": "syscall",
+ "syscall.PACKET_MR_MULTICAST": "syscall",
+ "syscall.PACKET_MR_PROMISC": "syscall",
+ "syscall.PACKET_MULTICAST": "syscall",
+ "syscall.PACKET_OTHERHOST": "syscall",
+ "syscall.PACKET_OUTGOING": "syscall",
+ "syscall.PACKET_RECV_OUTPUT": "syscall",
+ "syscall.PACKET_RX_RING": "syscall",
+ "syscall.PACKET_STATISTICS": "syscall",
+ "syscall.PAGE_EXECUTE_READ": "syscall",
+ "syscall.PAGE_EXECUTE_READWRITE": "syscall",
+ "syscall.PAGE_EXECUTE_WRITECOPY": "syscall",
+ "syscall.PAGE_READONLY": "syscall",
+ "syscall.PAGE_READWRITE": "syscall",
+ "syscall.PAGE_WRITECOPY": "syscall",
+ "syscall.PARENB": "syscall",
+ "syscall.PARMRK": "syscall",
+ "syscall.PARODD": "syscall",
+ "syscall.PENDIN": "syscall",
+ "syscall.PFL_HIDDEN": "syscall",
+ "syscall.PFL_MATCHES_PROTOCOL_ZERO": "syscall",
+ "syscall.PFL_MULTIPLE_PROTO_ENTRIES": "syscall",
+ "syscall.PFL_NETWORKDIRECT_PROVIDER": "syscall",
+ "syscall.PFL_RECOMMENDED_PROTO_ENTRY": "syscall",
+ "syscall.PF_FLUSH": "syscall",
+ "syscall.PKCS_7_ASN_ENCODING": "syscall",
+ "syscall.PMC5_PIPELINE_FLUSH": "syscall",
+ "syscall.PRIO_PGRP": "syscall",
+ "syscall.PRIO_PROCESS": "syscall",
+ "syscall.PRIO_USER": "syscall",
+ "syscall.PRI_IOFLUSH": "syscall",
+ "syscall.PROCESS_QUERY_INFORMATION": "syscall",
+ "syscall.PROCESS_TERMINATE": "syscall",
+ "syscall.PROT_EXEC": "syscall",
+ "syscall.PROT_GROWSDOWN": "syscall",
+ "syscall.PROT_GROWSUP": "syscall",
+ "syscall.PROT_NONE": "syscall",
+ "syscall.PROT_READ": "syscall",
+ "syscall.PROT_WRITE": "syscall",
+ "syscall.PROV_DH_SCHANNEL": "syscall",
+ "syscall.PROV_DSS": "syscall",
+ "syscall.PROV_DSS_DH": "syscall",
+ "syscall.PROV_EC_ECDSA_FULL": "syscall",
+ "syscall.PROV_EC_ECDSA_SIG": "syscall",
+ "syscall.PROV_EC_ECNRA_FULL": "syscall",
+ "syscall.PROV_EC_ECNRA_SIG": "syscall",
+ "syscall.PROV_FORTEZZA": "syscall",
+ "syscall.PROV_INTEL_SEC": "syscall",
+ "syscall.PROV_MS_EXCHANGE": "syscall",
+ "syscall.PROV_REPLACE_OWF": "syscall",
+ "syscall.PROV_RNG": "syscall",
+ "syscall.PROV_RSA_AES": "syscall",
+ "syscall.PROV_RSA_FULL": "syscall",
+ "syscall.PROV_RSA_SCHANNEL": "syscall",
+ "syscall.PROV_RSA_SIG": "syscall",
+ "syscall.PROV_SPYRUS_LYNKS": "syscall",
+ "syscall.PROV_SSL": "syscall",
+ "syscall.PR_CAPBSET_DROP": "syscall",
+ "syscall.PR_CAPBSET_READ": "syscall",
+ "syscall.PR_CLEAR_SECCOMP_FILTER": "syscall",
+ "syscall.PR_ENDIAN_BIG": "syscall",
+ "syscall.PR_ENDIAN_LITTLE": "syscall",
+ "syscall.PR_ENDIAN_PPC_LITTLE": "syscall",
+ "syscall.PR_FPEMU_NOPRINT": "syscall",
+ "syscall.PR_FPEMU_SIGFPE": "syscall",
+ "syscall.PR_FP_EXC_ASYNC": "syscall",
+ "syscall.PR_FP_EXC_DISABLED": "syscall",
+ "syscall.PR_FP_EXC_DIV": "syscall",
+ "syscall.PR_FP_EXC_INV": "syscall",
+ "syscall.PR_FP_EXC_NONRECOV": "syscall",
+ "syscall.PR_FP_EXC_OVF": "syscall",
+ "syscall.PR_FP_EXC_PRECISE": "syscall",
+ "syscall.PR_FP_EXC_RES": "syscall",
+ "syscall.PR_FP_EXC_SW_ENABLE": "syscall",
+ "syscall.PR_FP_EXC_UND": "syscall",
+ "syscall.PR_GET_DUMPABLE": "syscall",
+ "syscall.PR_GET_ENDIAN": "syscall",
+ "syscall.PR_GET_FPEMU": "syscall",
+ "syscall.PR_GET_FPEXC": "syscall",
+ "syscall.PR_GET_KEEPCAPS": "syscall",
+ "syscall.PR_GET_NAME": "syscall",
+ "syscall.PR_GET_PDEATHSIG": "syscall",
+ "syscall.PR_GET_SECCOMP": "syscall",
+ "syscall.PR_GET_SECCOMP_FILTER": "syscall",
+ "syscall.PR_GET_SECUREBITS": "syscall",
+ "syscall.PR_GET_TIMERSLACK": "syscall",
+ "syscall.PR_GET_TIMING": "syscall",
+ "syscall.PR_GET_TSC": "syscall",
+ "syscall.PR_GET_UNALIGN": "syscall",
+ "syscall.PR_MCE_KILL": "syscall",
+ "syscall.PR_MCE_KILL_CLEAR": "syscall",
+ "syscall.PR_MCE_KILL_DEFAULT": "syscall",
+ "syscall.PR_MCE_KILL_EARLY": "syscall",
+ "syscall.PR_MCE_KILL_GET": "syscall",
+ "syscall.PR_MCE_KILL_LATE": "syscall",
+ "syscall.PR_MCE_KILL_SET": "syscall",
+ "syscall.PR_SECCOMP_FILTER_EVENT": "syscall",
+ "syscall.PR_SECCOMP_FILTER_SYSCALL": "syscall",
+ "syscall.PR_SET_DUMPABLE": "syscall",
+ "syscall.PR_SET_ENDIAN": "syscall",
+ "syscall.PR_SET_FPEMU": "syscall",
+ "syscall.PR_SET_FPEXC": "syscall",
+ "syscall.PR_SET_KEEPCAPS": "syscall",
+ "syscall.PR_SET_NAME": "syscall",
+ "syscall.PR_SET_PDEATHSIG": "syscall",
+ "syscall.PR_SET_PTRACER": "syscall",
+ "syscall.PR_SET_SECCOMP": "syscall",
+ "syscall.PR_SET_SECCOMP_FILTER": "syscall",
+ "syscall.PR_SET_SECUREBITS": "syscall",
+ "syscall.PR_SET_TIMERSLACK": "syscall",
+ "syscall.PR_SET_TIMING": "syscall",
+ "syscall.PR_SET_TSC": "syscall",
+ "syscall.PR_SET_UNALIGN": "syscall",
+ "syscall.PR_TASK_PERF_EVENTS_DISABLE": "syscall",
+ "syscall.PR_TASK_PERF_EVENTS_ENABLE": "syscall",
+ "syscall.PR_TIMING_STATISTICAL": "syscall",
+ "syscall.PR_TIMING_TIMESTAMP": "syscall",
+ "syscall.PR_TSC_ENABLE": "syscall",
+ "syscall.PR_TSC_SIGSEGV": "syscall",
+ "syscall.PR_UNALIGN_NOPRINT": "syscall",
+ "syscall.PR_UNALIGN_SIGBUS": "syscall",
+ "syscall.PTRACE_ARCH_PRCTL": "syscall",
+ "syscall.PTRACE_ATTACH": "syscall",
+ "syscall.PTRACE_CONT": "syscall",
+ "syscall.PTRACE_DETACH": "syscall",
+ "syscall.PTRACE_EVENT_CLONE": "syscall",
+ "syscall.PTRACE_EVENT_EXEC": "syscall",
+ "syscall.PTRACE_EVENT_EXIT": "syscall",
+ "syscall.PTRACE_EVENT_FORK": "syscall",
+ "syscall.PTRACE_EVENT_VFORK": "syscall",
+ "syscall.PTRACE_EVENT_VFORK_DONE": "syscall",
+ "syscall.PTRACE_GETCRUNCHREGS": "syscall",
+ "syscall.PTRACE_GETEVENTMSG": "syscall",
+ "syscall.PTRACE_GETFPREGS": "syscall",
+ "syscall.PTRACE_GETFPXREGS": "syscall",
+ "syscall.PTRACE_GETHBPREGS": "syscall",
+ "syscall.PTRACE_GETREGS": "syscall",
+ "syscall.PTRACE_GETREGSET": "syscall",
+ "syscall.PTRACE_GETSIGINFO": "syscall",
+ "syscall.PTRACE_GETVFPREGS": "syscall",
+ "syscall.PTRACE_GETWMMXREGS": "syscall",
+ "syscall.PTRACE_GET_THREAD_AREA": "syscall",
+ "syscall.PTRACE_KILL": "syscall",
+ "syscall.PTRACE_OLDSETOPTIONS": "syscall",
+ "syscall.PTRACE_O_MASK": "syscall",
+ "syscall.PTRACE_O_TRACECLONE": "syscall",
+ "syscall.PTRACE_O_TRACEEXEC": "syscall",
+ "syscall.PTRACE_O_TRACEEXIT": "syscall",
+ "syscall.PTRACE_O_TRACEFORK": "syscall",
+ "syscall.PTRACE_O_TRACESYSGOOD": "syscall",
+ "syscall.PTRACE_O_TRACEVFORK": "syscall",
+ "syscall.PTRACE_O_TRACEVFORKDONE": "syscall",
+ "syscall.PTRACE_PEEKDATA": "syscall",
+ "syscall.PTRACE_PEEKTEXT": "syscall",
+ "syscall.PTRACE_PEEKUSR": "syscall",
+ "syscall.PTRACE_POKEDATA": "syscall",
+ "syscall.PTRACE_POKETEXT": "syscall",
+ "syscall.PTRACE_POKEUSR": "syscall",
+ "syscall.PTRACE_SETCRUNCHREGS": "syscall",
+ "syscall.PTRACE_SETFPREGS": "syscall",
+ "syscall.PTRACE_SETFPXREGS": "syscall",
+ "syscall.PTRACE_SETHBPREGS": "syscall",
+ "syscall.PTRACE_SETOPTIONS": "syscall",
+ "syscall.PTRACE_SETREGS": "syscall",
+ "syscall.PTRACE_SETREGSET": "syscall",
+ "syscall.PTRACE_SETSIGINFO": "syscall",
+ "syscall.PTRACE_SETVFPREGS": "syscall",
+ "syscall.PTRACE_SETWMMXREGS": "syscall",
+ "syscall.PTRACE_SET_SYSCALL": "syscall",
+ "syscall.PTRACE_SET_THREAD_AREA": "syscall",
+ "syscall.PTRACE_SINGLEBLOCK": "syscall",
+ "syscall.PTRACE_SINGLESTEP": "syscall",
+ "syscall.PTRACE_SYSCALL": "syscall",
+ "syscall.PTRACE_SYSEMU": "syscall",
+ "syscall.PTRACE_SYSEMU_SINGLESTEP": "syscall",
+ "syscall.PTRACE_TRACEME": "syscall",
+ "syscall.PT_ATTACH": "syscall",
+ "syscall.PT_ATTACHEXC": "syscall",
+ "syscall.PT_CONTINUE": "syscall",
+ "syscall.PT_DATA_ADDR": "syscall",
+ "syscall.PT_DENY_ATTACH": "syscall",
+ "syscall.PT_DETACH": "syscall",
+ "syscall.PT_FIRSTMACH": "syscall",
+ "syscall.PT_FORCEQUOTA": "syscall",
+ "syscall.PT_KILL": "syscall",
+ "syscall.PT_MASK": "syscall",
+ "syscall.PT_READ_D": "syscall",
+ "syscall.PT_READ_I": "syscall",
+ "syscall.PT_READ_U": "syscall",
+ "syscall.PT_SIGEXC": "syscall",
+ "syscall.PT_STEP": "syscall",
+ "syscall.PT_TEXT_ADDR": "syscall",
+ "syscall.PT_TEXT_END_ADDR": "syscall",
+ "syscall.PT_THUPDATE": "syscall",
+ "syscall.PT_TRACE_ME": "syscall",
+ "syscall.PT_WRITE_D": "syscall",
+ "syscall.PT_WRITE_I": "syscall",
+ "syscall.PT_WRITE_U": "syscall",
+ "syscall.ParseDirent": "syscall",
+ "syscall.ParseNetlinkMessage": "syscall",
+ "syscall.ParseNetlinkRouteAttr": "syscall",
+ "syscall.ParseRoutingMessage": "syscall",
+ "syscall.ParseRoutingSockaddr": "syscall",
+ "syscall.ParseSocketControlMessage": "syscall",
+ "syscall.ParseUnixCredentials": "syscall",
+ "syscall.ParseUnixRights": "syscall",
+ "syscall.PathMax": "syscall",
+ "syscall.Pathconf": "syscall",
+ "syscall.Pause": "syscall",
+ "syscall.Pipe": "syscall",
+ "syscall.Pipe2": "syscall",
+ "syscall.PivotRoot": "syscall",
+ "syscall.PostQueuedCompletionStatus": "syscall",
+ "syscall.Pread": "syscall",
+ "syscall.Proc": "syscall",
+ "syscall.ProcAttr": "syscall",
+ "syscall.ProcessInformation": "syscall",
+ "syscall.Protoent": "syscall",
+ "syscall.PtraceAttach": "syscall",
+ "syscall.PtraceCont": "syscall",
+ "syscall.PtraceDetach": "syscall",
+ "syscall.PtraceGetEventMsg": "syscall",
+ "syscall.PtraceGetRegs": "syscall",
+ "syscall.PtracePeekData": "syscall",
+ "syscall.PtracePeekText": "syscall",
+ "syscall.PtracePokeData": "syscall",
+ "syscall.PtracePokeText": "syscall",
+ "syscall.PtraceRegs": "syscall",
+ "syscall.PtraceSetOptions": "syscall",
+ "syscall.PtraceSetRegs": "syscall",
+ "syscall.PtraceSingleStep": "syscall",
+ "syscall.PtraceSyscall": "syscall",
+ "syscall.Pwrite": "syscall",
+ "syscall.REG_BINARY": "syscall",
+ "syscall.REG_DWORD": "syscall",
+ "syscall.REG_DWORD_BIG_ENDIAN": "syscall",
+ "syscall.REG_DWORD_LITTLE_ENDIAN": "syscall",
+ "syscall.REG_EXPAND_SZ": "syscall",
+ "syscall.REG_FULL_RESOURCE_DESCRIPTOR": "syscall",
+ "syscall.REG_LINK": "syscall",
+ "syscall.REG_MULTI_SZ": "syscall",
+ "syscall.REG_NONE": "syscall",
+ "syscall.REG_QWORD": "syscall",
+ "syscall.REG_QWORD_LITTLE_ENDIAN": "syscall",
+ "syscall.REG_RESOURCE_LIST": "syscall",
+ "syscall.REG_RESOURCE_REQUIREMENTS_LIST": "syscall",
+ "syscall.REG_SZ": "syscall",
+ "syscall.RLIMIT_AS": "syscall",
+ "syscall.RLIMIT_CORE": "syscall",
+ "syscall.RLIMIT_CPU": "syscall",
+ "syscall.RLIMIT_DATA": "syscall",
+ "syscall.RLIMIT_FSIZE": "syscall",
+ "syscall.RLIMIT_NOFILE": "syscall",
+ "syscall.RLIMIT_STACK": "syscall",
+ "syscall.RLIM_INFINITY": "syscall",
+ "syscall.RTAX_ADVMSS": "syscall",
+ "syscall.RTAX_AUTHOR": "syscall",
+ "syscall.RTAX_BRD": "syscall",
+ "syscall.RTAX_CWND": "syscall",
+ "syscall.RTAX_DST": "syscall",
+ "syscall.RTAX_FEATURES": "syscall",
+ "syscall.RTAX_FEATURE_ALLFRAG": "syscall",
+ "syscall.RTAX_FEATURE_ECN": "syscall",
+ "syscall.RTAX_FEATURE_SACK": "syscall",
+ "syscall.RTAX_FEATURE_TIMESTAMP": "syscall",
+ "syscall.RTAX_GATEWAY": "syscall",
+ "syscall.RTAX_GENMASK": "syscall",
+ "syscall.RTAX_HOPLIMIT": "syscall",
+ "syscall.RTAX_IFA": "syscall",
+ "syscall.RTAX_IFP": "syscall",
+ "syscall.RTAX_INITCWND": "syscall",
+ "syscall.RTAX_INITRWND": "syscall",
+ "syscall.RTAX_LABEL": "syscall",
+ "syscall.RTAX_LOCK": "syscall",
+ "syscall.RTAX_MAX": "syscall",
+ "syscall.RTAX_MTU": "syscall",
+ "syscall.RTAX_NETMASK": "syscall",
+ "syscall.RTAX_REORDERING": "syscall",
+ "syscall.RTAX_RTO_MIN": "syscall",
+ "syscall.RTAX_RTT": "syscall",
+ "syscall.RTAX_RTTVAR": "syscall",
+ "syscall.RTAX_SRC": "syscall",
+ "syscall.RTAX_SRCMASK": "syscall",
+ "syscall.RTAX_SSTHRESH": "syscall",
+ "syscall.RTAX_TAG": "syscall",
+ "syscall.RTAX_UNSPEC": "syscall",
+ "syscall.RTAX_WINDOW": "syscall",
+ "syscall.RTA_ALIGNTO": "syscall",
+ "syscall.RTA_AUTHOR": "syscall",
+ "syscall.RTA_BRD": "syscall",
+ "syscall.RTA_CACHEINFO": "syscall",
+ "syscall.RTA_DST": "syscall",
+ "syscall.RTA_FLOW": "syscall",
+ "syscall.RTA_GATEWAY": "syscall",
+ "syscall.RTA_GENMASK": "syscall",
+ "syscall.RTA_IFA": "syscall",
+ "syscall.RTA_IFP": "syscall",
+ "syscall.RTA_IIF": "syscall",
+ "syscall.RTA_LABEL": "syscall",
+ "syscall.RTA_MAX": "syscall",
+ "syscall.RTA_METRICS": "syscall",
+ "syscall.RTA_MULTIPATH": "syscall",
+ "syscall.RTA_NETMASK": "syscall",
+ "syscall.RTA_OIF": "syscall",
+ "syscall.RTA_PREFSRC": "syscall",
+ "syscall.RTA_PRIORITY": "syscall",
+ "syscall.RTA_SRC": "syscall",
+ "syscall.RTA_SRCMASK": "syscall",
+ "syscall.RTA_TABLE": "syscall",
+ "syscall.RTA_TAG": "syscall",
+ "syscall.RTA_UNSPEC": "syscall",
+ "syscall.RTCF_DIRECTSRC": "syscall",
+ "syscall.RTCF_DOREDIRECT": "syscall",
+ "syscall.RTCF_LOG": "syscall",
+ "syscall.RTCF_MASQ": "syscall",
+ "syscall.RTCF_NAT": "syscall",
+ "syscall.RTCF_VALVE": "syscall",
+ "syscall.RTF_ADDRCLASSMASK": "syscall",
+ "syscall.RTF_ADDRCONF": "syscall",
+ "syscall.RTF_ALLONLINK": "syscall",
+ "syscall.RTF_ANNOUNCE": "syscall",
+ "syscall.RTF_BLACKHOLE": "syscall",
+ "syscall.RTF_BROADCAST": "syscall",
+ "syscall.RTF_CACHE": "syscall",
+ "syscall.RTF_CLONED": "syscall",
+ "syscall.RTF_CLONING": "syscall",
+ "syscall.RTF_CONDEMNED": "syscall",
+ "syscall.RTF_DEFAULT": "syscall",
+ "syscall.RTF_DELCLONE": "syscall",
+ "syscall.RTF_DONE": "syscall",
+ "syscall.RTF_DYNAMIC": "syscall",
+ "syscall.RTF_FLOW": "syscall",
+ "syscall.RTF_FMASK": "syscall",
+ "syscall.RTF_GATEWAY": "syscall",
+ "syscall.RTF_GWFLAG_COMPAT": "syscall",
+ "syscall.RTF_HOST": "syscall",
+ "syscall.RTF_IFREF": "syscall",
+ "syscall.RTF_IFSCOPE": "syscall",
+ "syscall.RTF_INTERFACE": "syscall",
+ "syscall.RTF_IRTT": "syscall",
+ "syscall.RTF_LINKRT": "syscall",
+ "syscall.RTF_LLDATA": "syscall",
+ "syscall.RTF_LLINFO": "syscall",
+ "syscall.RTF_LOCAL": "syscall",
+ "syscall.RTF_MASK": "syscall",
+ "syscall.RTF_MODIFIED": "syscall",
+ "syscall.RTF_MPATH": "syscall",
+ "syscall.RTF_MPLS": "syscall",
+ "syscall.RTF_MSS": "syscall",
+ "syscall.RTF_MTU": "syscall",
+ "syscall.RTF_MULTICAST": "syscall",
+ "syscall.RTF_NAT": "syscall",
+ "syscall.RTF_NOFORWARD": "syscall",
+ "syscall.RTF_NONEXTHOP": "syscall",
+ "syscall.RTF_NOPMTUDISC": "syscall",
+ "syscall.RTF_PERMANENT_ARP": "syscall",
+ "syscall.RTF_PINNED": "syscall",
+ "syscall.RTF_POLICY": "syscall",
+ "syscall.RTF_PRCLONING": "syscall",
+ "syscall.RTF_PROTO1": "syscall",
+ "syscall.RTF_PROTO2": "syscall",
+ "syscall.RTF_PROTO3": "syscall",
+ "syscall.RTF_REINSTATE": "syscall",
+ "syscall.RTF_REJECT": "syscall",
+ "syscall.RTF_RNH_LOCKED": "syscall",
+ "syscall.RTF_SOURCE": "syscall",
+ "syscall.RTF_SRC": "syscall",
+ "syscall.RTF_STATIC": "syscall",
+ "syscall.RTF_STICKY": "syscall",
+ "syscall.RTF_THROW": "syscall",
+ "syscall.RTF_TUNNEL": "syscall",
+ "syscall.RTF_UP": "syscall",
+ "syscall.RTF_USETRAILERS": "syscall",
+ "syscall.RTF_WASCLONED": "syscall",
+ "syscall.RTF_WINDOW": "syscall",
+ "syscall.RTF_XRESOLVE": "syscall",
+ "syscall.RTM_ADD": "syscall",
+ "syscall.RTM_BASE": "syscall",
+ "syscall.RTM_CHANGE": "syscall",
+ "syscall.RTM_CHGADDR": "syscall",
+ "syscall.RTM_DELACTION": "syscall",
+ "syscall.RTM_DELADDR": "syscall",
+ "syscall.RTM_DELADDRLABEL": "syscall",
+ "syscall.RTM_DELETE": "syscall",
+ "syscall.RTM_DELLINK": "syscall",
+ "syscall.RTM_DELMADDR": "syscall",
+ "syscall.RTM_DELNEIGH": "syscall",
+ "syscall.RTM_DELQDISC": "syscall",
+ "syscall.RTM_DELROUTE": "syscall",
+ "syscall.RTM_DELRULE": "syscall",
+ "syscall.RTM_DELTCLASS": "syscall",
+ "syscall.RTM_DELTFILTER": "syscall",
+ "syscall.RTM_DESYNC": "syscall",
+ "syscall.RTM_F_CLONED": "syscall",
+ "syscall.RTM_F_EQUALIZE": "syscall",
+ "syscall.RTM_F_NOTIFY": "syscall",
+ "syscall.RTM_F_PREFIX": "syscall",
+ "syscall.RTM_GET": "syscall",
+ "syscall.RTM_GET2": "syscall",
+ "syscall.RTM_GETACTION": "syscall",
+ "syscall.RTM_GETADDR": "syscall",
+ "syscall.RTM_GETADDRLABEL": "syscall",
+ "syscall.RTM_GETANYCAST": "syscall",
+ "syscall.RTM_GETDCB": "syscall",
+ "syscall.RTM_GETLINK": "syscall",
+ "syscall.RTM_GETMULTICAST": "syscall",
+ "syscall.RTM_GETNEIGH": "syscall",
+ "syscall.RTM_GETNEIGHTBL": "syscall",
+ "syscall.RTM_GETQDISC": "syscall",
+ "syscall.RTM_GETROUTE": "syscall",
+ "syscall.RTM_GETRULE": "syscall",
+ "syscall.RTM_GETTCLASS": "syscall",
+ "syscall.RTM_GETTFILTER": "syscall",
+ "syscall.RTM_IEEE80211": "syscall",
+ "syscall.RTM_IFANNOUNCE": "syscall",
+ "syscall.RTM_IFINFO": "syscall",
+ "syscall.RTM_IFINFO2": "syscall",
+ "syscall.RTM_LLINFO_UPD": "syscall",
+ "syscall.RTM_LOCK": "syscall",
+ "syscall.RTM_LOSING": "syscall",
+ "syscall.RTM_MAX": "syscall",
+ "syscall.RTM_MAXSIZE": "syscall",
+ "syscall.RTM_MISS": "syscall",
+ "syscall.RTM_NEWACTION": "syscall",
+ "syscall.RTM_NEWADDR": "syscall",
+ "syscall.RTM_NEWADDRLABEL": "syscall",
+ "syscall.RTM_NEWLINK": "syscall",
+ "syscall.RTM_NEWMADDR": "syscall",
+ "syscall.RTM_NEWMADDR2": "syscall",
+ "syscall.RTM_NEWNDUSEROPT": "syscall",
+ "syscall.RTM_NEWNEIGH": "syscall",
+ "syscall.RTM_NEWNEIGHTBL": "syscall",
+ "syscall.RTM_NEWPREFIX": "syscall",
+ "syscall.RTM_NEWQDISC": "syscall",
+ "syscall.RTM_NEWROUTE": "syscall",
+ "syscall.RTM_NEWRULE": "syscall",
+ "syscall.RTM_NEWTCLASS": "syscall",
+ "syscall.RTM_NEWTFILTER": "syscall",
+ "syscall.RTM_NR_FAMILIES": "syscall",
+ "syscall.RTM_NR_MSGTYPES": "syscall",
+ "syscall.RTM_OIFINFO": "syscall",
+ "syscall.RTM_OLDADD": "syscall",
+ "syscall.RTM_OLDDEL": "syscall",
+ "syscall.RTM_OOIFINFO": "syscall",
+ "syscall.RTM_REDIRECT": "syscall",
+ "syscall.RTM_RESOLVE": "syscall",
+ "syscall.RTM_RTTUNIT": "syscall",
+ "syscall.RTM_SETDCB": "syscall",
+ "syscall.RTM_SETGATE": "syscall",
+ "syscall.RTM_SETLINK": "syscall",
+ "syscall.RTM_SETNEIGHTBL": "syscall",
+ "syscall.RTM_VERSION": "syscall",
+ "syscall.RTNH_ALIGNTO": "syscall",
+ "syscall.RTNH_F_DEAD": "syscall",
+ "syscall.RTNH_F_ONLINK": "syscall",
+ "syscall.RTNH_F_PERVASIVE": "syscall",
+ "syscall.RTNLGRP_IPV4_IFADDR": "syscall",
+ "syscall.RTNLGRP_IPV4_MROUTE": "syscall",
+ "syscall.RTNLGRP_IPV4_ROUTE": "syscall",
+ "syscall.RTNLGRP_IPV4_RULE": "syscall",
+ "syscall.RTNLGRP_IPV6_IFADDR": "syscall",
+ "syscall.RTNLGRP_IPV6_IFINFO": "syscall",
+ "syscall.RTNLGRP_IPV6_MROUTE": "syscall",
+ "syscall.RTNLGRP_IPV6_PREFIX": "syscall",
+ "syscall.RTNLGRP_IPV6_ROUTE": "syscall",
+ "syscall.RTNLGRP_IPV6_RULE": "syscall",
+ "syscall.RTNLGRP_LINK": "syscall",
+ "syscall.RTNLGRP_ND_USEROPT": "syscall",
+ "syscall.RTNLGRP_NEIGH": "syscall",
+ "syscall.RTNLGRP_NONE": "syscall",
+ "syscall.RTNLGRP_NOTIFY": "syscall",
+ "syscall.RTNLGRP_TC": "syscall",
+ "syscall.RTN_ANYCAST": "syscall",
+ "syscall.RTN_BLACKHOLE": "syscall",
+ "syscall.RTN_BROADCAST": "syscall",
+ "syscall.RTN_LOCAL": "syscall",
+ "syscall.RTN_MAX": "syscall",
+ "syscall.RTN_MULTICAST": "syscall",
+ "syscall.RTN_NAT": "syscall",
+ "syscall.RTN_PROHIBIT": "syscall",
+ "syscall.RTN_THROW": "syscall",
+ "syscall.RTN_UNICAST": "syscall",
+ "syscall.RTN_UNREACHABLE": "syscall",
+ "syscall.RTN_UNSPEC": "syscall",
+ "syscall.RTN_XRESOLVE": "syscall",
+ "syscall.RTPROT_BIRD": "syscall",
+ "syscall.RTPROT_BOOT": "syscall",
+ "syscall.RTPROT_DHCP": "syscall",
+ "syscall.RTPROT_DNROUTED": "syscall",
+ "syscall.RTPROT_GATED": "syscall",
+ "syscall.RTPROT_KERNEL": "syscall",
+ "syscall.RTPROT_MRT": "syscall",
+ "syscall.RTPROT_NTK": "syscall",
+ "syscall.RTPROT_RA": "syscall",
+ "syscall.RTPROT_REDIRECT": "syscall",
+ "syscall.RTPROT_STATIC": "syscall",
+ "syscall.RTPROT_UNSPEC": "syscall",
+ "syscall.RTPROT_XORP": "syscall",
+ "syscall.RTPROT_ZEBRA": "syscall",
+ "syscall.RTV_EXPIRE": "syscall",
+ "syscall.RTV_HOPCOUNT": "syscall",
+ "syscall.RTV_MTU": "syscall",
+ "syscall.RTV_RPIPE": "syscall",
+ "syscall.RTV_RTT": "syscall",
+ "syscall.RTV_RTTVAR": "syscall",
+ "syscall.RTV_SPIPE": "syscall",
+ "syscall.RTV_SSTHRESH": "syscall",
+ "syscall.RTV_WEIGHT": "syscall",
+ "syscall.RT_CACHING_CONTEXT": "syscall",
+ "syscall.RT_CLASS_DEFAULT": "syscall",
+ "syscall.RT_CLASS_LOCAL": "syscall",
+ "syscall.RT_CLASS_MAIN": "syscall",
+ "syscall.RT_CLASS_MAX": "syscall",
+ "syscall.RT_CLASS_UNSPEC": "syscall",
+ "syscall.RT_DEFAULT_FIB": "syscall",
+ "syscall.RT_NORTREF": "syscall",
+ "syscall.RT_SCOPE_HOST": "syscall",
+ "syscall.RT_SCOPE_LINK": "syscall",
+ "syscall.RT_SCOPE_NOWHERE": "syscall",
+ "syscall.RT_SCOPE_SITE": "syscall",
+ "syscall.RT_SCOPE_UNIVERSE": "syscall",
+ "syscall.RT_TABLEID_MAX": "syscall",
+ "syscall.RT_TABLE_COMPAT": "syscall",
+ "syscall.RT_TABLE_DEFAULT": "syscall",
+ "syscall.RT_TABLE_LOCAL": "syscall",
+ "syscall.RT_TABLE_MAIN": "syscall",
+ "syscall.RT_TABLE_MAX": "syscall",
+ "syscall.RT_TABLE_UNSPEC": "syscall",
+ "syscall.RUSAGE_CHILDREN": "syscall",
+ "syscall.RUSAGE_SELF": "syscall",
+ "syscall.RUSAGE_THREAD": "syscall",
+ "syscall.Radvisory_t": "syscall",
+ "syscall.RawSockaddr": "syscall",
+ "syscall.RawSockaddrAny": "syscall",
+ "syscall.RawSockaddrDatalink": "syscall",
+ "syscall.RawSockaddrInet4": "syscall",
+ "syscall.RawSockaddrInet6": "syscall",
+ "syscall.RawSockaddrLinklayer": "syscall",
+ "syscall.RawSockaddrNetlink": "syscall",
+ "syscall.RawSockaddrUnix": "syscall",
+ "syscall.RawSyscall": "syscall",
+ "syscall.RawSyscall6": "syscall",
+ "syscall.Read": "syscall",
+ "syscall.ReadConsole": "syscall",
+ "syscall.ReadDirectoryChanges": "syscall",
+ "syscall.ReadDirent": "syscall",
+ "syscall.ReadFile": "syscall",
+ "syscall.Readlink": "syscall",
+ "syscall.Reboot": "syscall",
+ "syscall.Recvfrom": "syscall",
+ "syscall.Recvmsg": "syscall",
+ "syscall.RegCloseKey": "syscall",
+ "syscall.RegEnumKeyEx": "syscall",
+ "syscall.RegOpenKeyEx": "syscall",
+ "syscall.RegQueryInfoKey": "syscall",
+ "syscall.RegQueryValueEx": "syscall",
+ "syscall.RemoveDirectory": "syscall",
+ "syscall.Removexattr": "syscall",
+ "syscall.Rename": "syscall",
+ "syscall.Renameat": "syscall",
+ "syscall.Revoke": "syscall",
+ "syscall.Rlimit": "syscall",
+ "syscall.Rmdir": "syscall",
+ "syscall.RouteMessage": "syscall",
+ "syscall.RouteRIB": "syscall",
+ "syscall.RtAttr": "syscall",
+ "syscall.RtGenmsg": "syscall",
+ "syscall.RtMetrics": "syscall",
+ "syscall.RtMsg": "syscall",
+ "syscall.RtMsghdr": "syscall",
+ "syscall.RtNexthop": "syscall",
+ "syscall.Rusage": "syscall",
+ "syscall.SCM_BINTIME": "syscall",
+ "syscall.SCM_CREDENTIALS": "syscall",
+ "syscall.SCM_CREDS": "syscall",
+ "syscall.SCM_RIGHTS": "syscall",
+ "syscall.SCM_TIMESTAMP": "syscall",
+ "syscall.SCM_TIMESTAMPING": "syscall",
+ "syscall.SCM_TIMESTAMPNS": "syscall",
+ "syscall.SCM_TIMESTAMP_MONOTONIC": "syscall",
+ "syscall.SHUT_RD": "syscall",
+ "syscall.SHUT_RDWR": "syscall",
+ "syscall.SHUT_WR": "syscall",
+ "syscall.SID": "syscall",
+ "syscall.SIDAndAttributes": "syscall",
+ "syscall.SIGABRT": "syscall",
+ "syscall.SIGALRM": "syscall",
+ "syscall.SIGBUS": "syscall",
+ "syscall.SIGCHLD": "syscall",
+ "syscall.SIGCLD": "syscall",
+ "syscall.SIGCONT": "syscall",
+ "syscall.SIGEMT": "syscall",
+ "syscall.SIGFPE": "syscall",
+ "syscall.SIGHUP": "syscall",
+ "syscall.SIGILL": "syscall",
+ "syscall.SIGINFO": "syscall",
+ "syscall.SIGINT": "syscall",
+ "syscall.SIGIO": "syscall",
+ "syscall.SIGIOT": "syscall",
+ "syscall.SIGKILL": "syscall",
+ "syscall.SIGLIBRT": "syscall",
+ "syscall.SIGLWP": "syscall",
+ "syscall.SIGPIPE": "syscall",
+ "syscall.SIGPOLL": "syscall",
+ "syscall.SIGPROF": "syscall",
+ "syscall.SIGPWR": "syscall",
+ "syscall.SIGQUIT": "syscall",
+ "syscall.SIGSEGV": "syscall",
+ "syscall.SIGSTKFLT": "syscall",
+ "syscall.SIGSTOP": "syscall",
+ "syscall.SIGSYS": "syscall",
+ "syscall.SIGTERM": "syscall",
+ "syscall.SIGTHR": "syscall",
+ "syscall.SIGTRAP": "syscall",
+ "syscall.SIGTSTP": "syscall",
+ "syscall.SIGTTIN": "syscall",
+ "syscall.SIGTTOU": "syscall",
+ "syscall.SIGUNUSED": "syscall",
+ "syscall.SIGURG": "syscall",
+ "syscall.SIGUSR1": "syscall",
+ "syscall.SIGUSR2": "syscall",
+ "syscall.SIGVTALRM": "syscall",
+ "syscall.SIGWINCH": "syscall",
+ "syscall.SIGXCPU": "syscall",
+ "syscall.SIGXFSZ": "syscall",
+ "syscall.SIOCADDDLCI": "syscall",
+ "syscall.SIOCADDMULTI": "syscall",
+ "syscall.SIOCADDRT": "syscall",
+ "syscall.SIOCAIFADDR": "syscall",
+ "syscall.SIOCAIFGROUP": "syscall",
+ "syscall.SIOCALIFADDR": "syscall",
+ "syscall.SIOCARPIPLL": "syscall",
+ "syscall.SIOCATMARK": "syscall",
+ "syscall.SIOCAUTOADDR": "syscall",
+ "syscall.SIOCAUTONETMASK": "syscall",
+ "syscall.SIOCBRDGADD": "syscall",
+ "syscall.SIOCBRDGADDS": "syscall",
+ "syscall.SIOCBRDGARL": "syscall",
+ "syscall.SIOCBRDGDADDR": "syscall",
+ "syscall.SIOCBRDGDEL": "syscall",
+ "syscall.SIOCBRDGDELS": "syscall",
+ "syscall.SIOCBRDGFLUSH": "syscall",
+ "syscall.SIOCBRDGFRL": "syscall",
+ "syscall.SIOCBRDGGCACHE": "syscall",
+ "syscall.SIOCBRDGGFD": "syscall",
+ "syscall.SIOCBRDGGHT": "syscall",
+ "syscall.SIOCBRDGGIFFLGS": "syscall",
+ "syscall.SIOCBRDGGMA": "syscall",
+ "syscall.SIOCBRDGGPARAM": "syscall",
+ "syscall.SIOCBRDGGPRI": "syscall",
+ "syscall.SIOCBRDGGRL": "syscall",
+ "syscall.SIOCBRDGGSIFS": "syscall",
+ "syscall.SIOCBRDGGTO": "syscall",
+ "syscall.SIOCBRDGIFS": "syscall",
+ "syscall.SIOCBRDGRTS": "syscall",
+ "syscall.SIOCBRDGSADDR": "syscall",
+ "syscall.SIOCBRDGSCACHE": "syscall",
+ "syscall.SIOCBRDGSFD": "syscall",
+ "syscall.SIOCBRDGSHT": "syscall",
+ "syscall.SIOCBRDGSIFCOST": "syscall",
+ "syscall.SIOCBRDGSIFFLGS": "syscall",
+ "syscall.SIOCBRDGSIFPRIO": "syscall",
+ "syscall.SIOCBRDGSMA": "syscall",
+ "syscall.SIOCBRDGSPRI": "syscall",
+ "syscall.SIOCBRDGSPROTO": "syscall",
+ "syscall.SIOCBRDGSTO": "syscall",
+ "syscall.SIOCBRDGSTXHC": "syscall",
+ "syscall.SIOCDARP": "syscall",
+ "syscall.SIOCDELDLCI": "syscall",
+ "syscall.SIOCDELMULTI": "syscall",
+ "syscall.SIOCDELRT": "syscall",
+ "syscall.SIOCDEVPRIVATE": "syscall",
+ "syscall.SIOCDIFADDR": "syscall",
+ "syscall.SIOCDIFGROUP": "syscall",
+ "syscall.SIOCDIFPHYADDR": "syscall",
+ "syscall.SIOCDLIFADDR": "syscall",
+ "syscall.SIOCDRARP": "syscall",
+ "syscall.SIOCGARP": "syscall",
+ "syscall.SIOCGDRVSPEC": "syscall",
+ "syscall.SIOCGETKALIVE": "syscall",
+ "syscall.SIOCGETLABEL": "syscall",
+ "syscall.SIOCGETPFLOW": "syscall",
+ "syscall.SIOCGETPFSYNC": "syscall",
+ "syscall.SIOCGETSGCNT": "syscall",
+ "syscall.SIOCGETVIFCNT": "syscall",
+ "syscall.SIOCGETVLAN": "syscall",
+ "syscall.SIOCGHIWAT": "syscall",
+ "syscall.SIOCGIFADDR": "syscall",
+ "syscall.SIOCGIFADDRPREF": "syscall",
+ "syscall.SIOCGIFALIAS": "syscall",
+ "syscall.SIOCGIFALTMTU": "syscall",
+ "syscall.SIOCGIFASYNCMAP": "syscall",
+ "syscall.SIOCGIFBOND": "syscall",
+ "syscall.SIOCGIFBR": "syscall",
+ "syscall.SIOCGIFBRDADDR": "syscall",
+ "syscall.SIOCGIFCAP": "syscall",
+ "syscall.SIOCGIFCONF": "syscall",
+ "syscall.SIOCGIFCOUNT": "syscall",
+ "syscall.SIOCGIFDATA": "syscall",
+ "syscall.SIOCGIFDESCR": "syscall",
+ "syscall.SIOCGIFDEVMTU": "syscall",
+ "syscall.SIOCGIFDLT": "syscall",
+ "syscall.SIOCGIFDSTADDR": "syscall",
+ "syscall.SIOCGIFENCAP": "syscall",
+ "syscall.SIOCGIFFIB": "syscall",
+ "syscall.SIOCGIFFLAGS": "syscall",
+ "syscall.SIOCGIFGATTR": "syscall",
+ "syscall.SIOCGIFGENERIC": "syscall",
+ "syscall.SIOCGIFGMEMB": "syscall",
+ "syscall.SIOCGIFGROUP": "syscall",
+ "syscall.SIOCGIFHARDMTU": "syscall",
+ "syscall.SIOCGIFHWADDR": "syscall",
+ "syscall.SIOCGIFINDEX": "syscall",
+ "syscall.SIOCGIFKPI": "syscall",
+ "syscall.SIOCGIFMAC": "syscall",
+ "syscall.SIOCGIFMAP": "syscall",
+ "syscall.SIOCGIFMEDIA": "syscall",
+ "syscall.SIOCGIFMEM": "syscall",
+ "syscall.SIOCGIFMETRIC": "syscall",
+ "syscall.SIOCGIFMTU": "syscall",
+ "syscall.SIOCGIFNAME": "syscall",
+ "syscall.SIOCGIFNETMASK": "syscall",
+ "syscall.SIOCGIFPDSTADDR": "syscall",
+ "syscall.SIOCGIFPFLAGS": "syscall",
+ "syscall.SIOCGIFPHYS": "syscall",
+ "syscall.SIOCGIFPRIORITY": "syscall",
+ "syscall.SIOCGIFPSRCADDR": "syscall",
+ "syscall.SIOCGIFRDOMAIN": "syscall",
+ "syscall.SIOCGIFRTLABEL": "syscall",
+ "syscall.SIOCGIFSLAVE": "syscall",
+ "syscall.SIOCGIFSTATUS": "syscall",
+ "syscall.SIOCGIFTIMESLOT": "syscall",
+ "syscall.SIOCGIFTXQLEN": "syscall",
+ "syscall.SIOCGIFVLAN": "syscall",
+ "syscall.SIOCGIFWAKEFLAGS": "syscall",
+ "syscall.SIOCGIFXFLAGS": "syscall",
+ "syscall.SIOCGLIFADDR": "syscall",
+ "syscall.SIOCGLIFPHYADDR": "syscall",
+ "syscall.SIOCGLIFPHYRTABLE": "syscall",
+ "syscall.SIOCGLIFPHYTTL": "syscall",
+ "syscall.SIOCGLINKSTR": "syscall",
+ "syscall.SIOCGLOWAT": "syscall",
+ "syscall.SIOCGPGRP": "syscall",
+ "syscall.SIOCGPRIVATE_0": "syscall",
+ "syscall.SIOCGPRIVATE_1": "syscall",
+ "syscall.SIOCGRARP": "syscall",
+ "syscall.SIOCGSPPPPARAMS": "syscall",
+ "syscall.SIOCGSTAMP": "syscall",
+ "syscall.SIOCGSTAMPNS": "syscall",
+ "syscall.SIOCGVH": "syscall",
+ "syscall.SIOCGVNETID": "syscall",
+ "syscall.SIOCIFCREATE": "syscall",
+ "syscall.SIOCIFCREATE2": "syscall",
+ "syscall.SIOCIFDESTROY": "syscall",
+ "syscall.SIOCIFGCLONERS": "syscall",
+ "syscall.SIOCINITIFADDR": "syscall",
+ "syscall.SIOCPROTOPRIVATE": "syscall",
+ "syscall.SIOCRSLVMULTI": "syscall",
+ "syscall.SIOCRTMSG": "syscall",
+ "syscall.SIOCSARP": "syscall",
+ "syscall.SIOCSDRVSPEC": "syscall",
+ "syscall.SIOCSETKALIVE": "syscall",
+ "syscall.SIOCSETLABEL": "syscall",
+ "syscall.SIOCSETPFLOW": "syscall",
+ "syscall.SIOCSETPFSYNC": "syscall",
+ "syscall.SIOCSETVLAN": "syscall",
+ "syscall.SIOCSHIWAT": "syscall",
+ "syscall.SIOCSIFADDR": "syscall",
+ "syscall.SIOCSIFADDRPREF": "syscall",
+ "syscall.SIOCSIFALTMTU": "syscall",
+ "syscall.SIOCSIFASYNCMAP": "syscall",
+ "syscall.SIOCSIFBOND": "syscall",
+ "syscall.SIOCSIFBR": "syscall",
+ "syscall.SIOCSIFBRDADDR": "syscall",
+ "syscall.SIOCSIFCAP": "syscall",
+ "syscall.SIOCSIFDESCR": "syscall",
+ "syscall.SIOCSIFDSTADDR": "syscall",
+ "syscall.SIOCSIFENCAP": "syscall",
+ "syscall.SIOCSIFFIB": "syscall",
+ "syscall.SIOCSIFFLAGS": "syscall",
+ "syscall.SIOCSIFGATTR": "syscall",
+ "syscall.SIOCSIFGENERIC": "syscall",
+ "syscall.SIOCSIFHWADDR": "syscall",
+ "syscall.SIOCSIFHWBROADCAST": "syscall",
+ "syscall.SIOCSIFKPI": "syscall",
+ "syscall.SIOCSIFLINK": "syscall",
+ "syscall.SIOCSIFLLADDR": "syscall",
+ "syscall.SIOCSIFMAC": "syscall",
+ "syscall.SIOCSIFMAP": "syscall",
+ "syscall.SIOCSIFMEDIA": "syscall",
+ "syscall.SIOCSIFMEM": "syscall",
+ "syscall.SIOCSIFMETRIC": "syscall",
+ "syscall.SIOCSIFMTU": "syscall",
+ "syscall.SIOCSIFNAME": "syscall",
+ "syscall.SIOCSIFNETMASK": "syscall",
+ "syscall.SIOCSIFPFLAGS": "syscall",
+ "syscall.SIOCSIFPHYADDR": "syscall",
+ "syscall.SIOCSIFPHYS": "syscall",
+ "syscall.SIOCSIFPRIORITY": "syscall",
+ "syscall.SIOCSIFRDOMAIN": "syscall",
+ "syscall.SIOCSIFRTLABEL": "syscall",
+ "syscall.SIOCSIFRVNET": "syscall",
+ "syscall.SIOCSIFSLAVE": "syscall",
+ "syscall.SIOCSIFTIMESLOT": "syscall",
+ "syscall.SIOCSIFTXQLEN": "syscall",
+ "syscall.SIOCSIFVLAN": "syscall",
+ "syscall.SIOCSIFVNET": "syscall",
+ "syscall.SIOCSIFXFLAGS": "syscall",
+ "syscall.SIOCSLIFPHYADDR": "syscall",
+ "syscall.SIOCSLIFPHYRTABLE": "syscall",
+ "syscall.SIOCSLIFPHYTTL": "syscall",
+ "syscall.SIOCSLINKSTR": "syscall",
+ "syscall.SIOCSLOWAT": "syscall",
+ "syscall.SIOCSPGRP": "syscall",
+ "syscall.SIOCSRARP": "syscall",
+ "syscall.SIOCSSPPPPARAMS": "syscall",
+ "syscall.SIOCSVH": "syscall",
+ "syscall.SIOCSVNETID": "syscall",
+ "syscall.SIOCZIFDATA": "syscall",
+ "syscall.SIO_GET_EXTENSION_FUNCTION_POINTER": "syscall",
+ "syscall.SIO_GET_INTERFACE_LIST": "syscall",
+ "syscall.SIO_KEEPALIVE_VALS": "syscall",
+ "syscall.SOCK_CLOEXEC": "syscall",
+ "syscall.SOCK_DCCP": "syscall",
+ "syscall.SOCK_DGRAM": "syscall",
+ "syscall.SOCK_FLAGS_MASK": "syscall",
+ "syscall.SOCK_MAXADDRLEN": "syscall",
+ "syscall.SOCK_NONBLOCK": "syscall",
+ "syscall.SOCK_NOSIGPIPE": "syscall",
+ "syscall.SOCK_PACKET": "syscall",
+ "syscall.SOCK_RAW": "syscall",
+ "syscall.SOCK_RDM": "syscall",
+ "syscall.SOCK_SEQPACKET": "syscall",
+ "syscall.SOCK_STREAM": "syscall",
+ "syscall.SOL_AAL": "syscall",
+ "syscall.SOL_ATM": "syscall",
+ "syscall.SOL_DECNET": "syscall",
+ "syscall.SOL_ICMPV6": "syscall",
+ "syscall.SOL_IP": "syscall",
+ "syscall.SOL_IPV6": "syscall",
+ "syscall.SOL_IRDA": "syscall",
+ "syscall.SOL_PACKET": "syscall",
+ "syscall.SOL_RAW": "syscall",
+ "syscall.SOL_SOCKET": "syscall",
+ "syscall.SOL_TCP": "syscall",
+ "syscall.SOL_X25": "syscall",
+ "syscall.SOMAXCONN": "syscall",
+ "syscall.SO_ACCEPTCONN": "syscall",
+ "syscall.SO_ACCEPTFILTER": "syscall",
+ "syscall.SO_ATTACH_FILTER": "syscall",
+ "syscall.SO_BINDANY": "syscall",
+ "syscall.SO_BINDTODEVICE": "syscall",
+ "syscall.SO_BINTIME": "syscall",
+ "syscall.SO_BROADCAST": "syscall",
+ "syscall.SO_BSDCOMPAT": "syscall",
+ "syscall.SO_DEBUG": "syscall",
+ "syscall.SO_DETACH_FILTER": "syscall",
+ "syscall.SO_DOMAIN": "syscall",
+ "syscall.SO_DONTROUTE": "syscall",
+ "syscall.SO_DONTTRUNC": "syscall",
+ "syscall.SO_ERROR": "syscall",
+ "syscall.SO_KEEPALIVE": "syscall",
+ "syscall.SO_LABEL": "syscall",
+ "syscall.SO_LINGER": "syscall",
+ "syscall.SO_LINGER_SEC": "syscall",
+ "syscall.SO_LISTENINCQLEN": "syscall",
+ "syscall.SO_LISTENQLEN": "syscall",
+ "syscall.SO_LISTENQLIMIT": "syscall",
+ "syscall.SO_MARK": "syscall",
+ "syscall.SO_NETPROC": "syscall",
+ "syscall.SO_NKE": "syscall",
+ "syscall.SO_NOADDRERR": "syscall",
+ "syscall.SO_NOHEADER": "syscall",
+ "syscall.SO_NOSIGPIPE": "syscall",
+ "syscall.SO_NOTIFYCONFLICT": "syscall",
+ "syscall.SO_NO_CHECK": "syscall",
+ "syscall.SO_NO_DDP": "syscall",
+ "syscall.SO_NO_OFFLOAD": "syscall",
+ "syscall.SO_NP_EXTENSIONS": "syscall",
+ "syscall.SO_NREAD": "syscall",
+ "syscall.SO_NWRITE": "syscall",
+ "syscall.SO_OOBINLINE": "syscall",
+ "syscall.SO_OVERFLOWED": "syscall",
+ "syscall.SO_PASSCRED": "syscall",
+ "syscall.SO_PASSSEC": "syscall",
+ "syscall.SO_PEERCRED": "syscall",
+ "syscall.SO_PEERLABEL": "syscall",
+ "syscall.SO_PEERNAME": "syscall",
+ "syscall.SO_PEERSEC": "syscall",
+ "syscall.SO_PRIORITY": "syscall",
+ "syscall.SO_PROTOCOL": "syscall",
+ "syscall.SO_PROTOTYPE": "syscall",
+ "syscall.SO_RANDOMPORT": "syscall",
+ "syscall.SO_RCVBUF": "syscall",
+ "syscall.SO_RCVBUFFORCE": "syscall",
+ "syscall.SO_RCVLOWAT": "syscall",
+ "syscall.SO_RCVTIMEO": "syscall",
+ "syscall.SO_RESTRICTIONS": "syscall",
+ "syscall.SO_RESTRICT_DENYIN": "syscall",
+ "syscall.SO_RESTRICT_DENYOUT": "syscall",
+ "syscall.SO_RESTRICT_DENYSET": "syscall",
+ "syscall.SO_REUSEADDR": "syscall",
+ "syscall.SO_REUSEPORT": "syscall",
+ "syscall.SO_REUSESHAREUID": "syscall",
+ "syscall.SO_RTABLE": "syscall",
+ "syscall.SO_RXQ_OVFL": "syscall",
+ "syscall.SO_SECURITY_AUTHENTICATION": "syscall",
+ "syscall.SO_SECURITY_ENCRYPTION_NETWORK": "syscall",
+ "syscall.SO_SECURITY_ENCRYPTION_TRANSPORT": "syscall",
+ "syscall.SO_SETFIB": "syscall",
+ "syscall.SO_SNDBUF": "syscall",
+ "syscall.SO_SNDBUFFORCE": "syscall",
+ "syscall.SO_SNDLOWAT": "syscall",
+ "syscall.SO_SNDTIMEO": "syscall",
+ "syscall.SO_SPLICE": "syscall",
+ "syscall.SO_TIMESTAMP": "syscall",
+ "syscall.SO_TIMESTAMPING": "syscall",
+ "syscall.SO_TIMESTAMPNS": "syscall",
+ "syscall.SO_TIMESTAMP_MONOTONIC": "syscall",
+ "syscall.SO_TYPE": "syscall",
+ "syscall.SO_UPCALLCLOSEWAIT": "syscall",
+ "syscall.SO_UPDATE_ACCEPT_CONTEXT": "syscall",
+ "syscall.SO_UPDATE_CONNECT_CONTEXT": "syscall",
+ "syscall.SO_USELOOPBACK": "syscall",
+ "syscall.SO_USER_COOKIE": "syscall",
+ "syscall.SO_VENDOR": "syscall",
+ "syscall.SO_WANTMORE": "syscall",
+ "syscall.SO_WANTOOBFLAG": "syscall",
+ "syscall.SSLExtraCertChainPolicyPara": "syscall",
+ "syscall.STANDARD_RIGHTS_ALL": "syscall",
+ "syscall.STANDARD_RIGHTS_EXECUTE": "syscall",
+ "syscall.STANDARD_RIGHTS_READ": "syscall",
+ "syscall.STANDARD_RIGHTS_REQUIRED": "syscall",
+ "syscall.STANDARD_RIGHTS_WRITE": "syscall",
+ "syscall.STARTF_USESHOWWINDOW": "syscall",
+ "syscall.STARTF_USESTDHANDLES": "syscall",
+ "syscall.STD_ERROR_HANDLE": "syscall",
+ "syscall.STD_INPUT_HANDLE": "syscall",
+ "syscall.STD_OUTPUT_HANDLE": "syscall",
+ "syscall.SUBLANG_ENGLISH_US": "syscall",
+ "syscall.SW_FORCEMINIMIZE": "syscall",
+ "syscall.SW_HIDE": "syscall",
+ "syscall.SW_MAXIMIZE": "syscall",
+ "syscall.SW_MINIMIZE": "syscall",
+ "syscall.SW_NORMAL": "syscall",
+ "syscall.SW_RESTORE": "syscall",
+ "syscall.SW_SHOW": "syscall",
+ "syscall.SW_SHOWDEFAULT": "syscall",
+ "syscall.SW_SHOWMAXIMIZED": "syscall",
+ "syscall.SW_SHOWMINIMIZED": "syscall",
+ "syscall.SW_SHOWMINNOACTIVE": "syscall",
+ "syscall.SW_SHOWNA": "syscall",
+ "syscall.SW_SHOWNOACTIVATE": "syscall",
+ "syscall.SW_SHOWNORMAL": "syscall",
+ "syscall.SYNCHRONIZE": "syscall",
+ "syscall.SYSCTL_VERSION": "syscall",
+ "syscall.SYSCTL_VERS_0": "syscall",
+ "syscall.SYSCTL_VERS_1": "syscall",
+ "syscall.SYSCTL_VERS_MASK": "syscall",
+ "syscall.SYS_ABORT2": "syscall",
+ "syscall.SYS_ACCEPT": "syscall",
+ "syscall.SYS_ACCEPT4": "syscall",
+ "syscall.SYS_ACCEPT_NOCANCEL": "syscall",
+ "syscall.SYS_ACCESS": "syscall",
+ "syscall.SYS_ACCESS_EXTENDED": "syscall",
+ "syscall.SYS_ACCT": "syscall",
+ "syscall.SYS_ADD_KEY": "syscall",
+ "syscall.SYS_ADD_PROFIL": "syscall",
+ "syscall.SYS_ADJFREQ": "syscall",
+ "syscall.SYS_ADJTIME": "syscall",
+ "syscall.SYS_ADJTIMEX": "syscall",
+ "syscall.SYS_AFS_SYSCALL": "syscall",
+ "syscall.SYS_AIO_CANCEL": "syscall",
+ "syscall.SYS_AIO_ERROR": "syscall",
+ "syscall.SYS_AIO_FSYNC": "syscall",
+ "syscall.SYS_AIO_READ": "syscall",
+ "syscall.SYS_AIO_RETURN": "syscall",
+ "syscall.SYS_AIO_SUSPEND": "syscall",
+ "syscall.SYS_AIO_SUSPEND_NOCANCEL": "syscall",
+ "syscall.SYS_AIO_WRITE": "syscall",
+ "syscall.SYS_ALARM": "syscall",
+ "syscall.SYS_ARCH_PRCTL": "syscall",
+ "syscall.SYS_ARM_FADVISE64_64": "syscall",
+ "syscall.SYS_ARM_SYNC_FILE_RANGE": "syscall",
+ "syscall.SYS_ATGETMSG": "syscall",
+ "syscall.SYS_ATPGETREQ": "syscall",
+ "syscall.SYS_ATPGETRSP": "syscall",
+ "syscall.SYS_ATPSNDREQ": "syscall",
+ "syscall.SYS_ATPSNDRSP": "syscall",
+ "syscall.SYS_ATPUTMSG": "syscall",
+ "syscall.SYS_ATSOCKET": "syscall",
+ "syscall.SYS_AUDIT": "syscall",
+ "syscall.SYS_AUDITCTL": "syscall",
+ "syscall.SYS_AUDITON": "syscall",
+ "syscall.SYS_AUDIT_SESSION_JOIN": "syscall",
+ "syscall.SYS_AUDIT_SESSION_PORT": "syscall",
+ "syscall.SYS_AUDIT_SESSION_SELF": "syscall",
+ "syscall.SYS_BDFLUSH": "syscall",
+ "syscall.SYS_BIND": "syscall",
+ "syscall.SYS_BINDAT": "syscall",
+ "syscall.SYS_BREAK": "syscall",
+ "syscall.SYS_BRK": "syscall",
+ "syscall.SYS_BSDTHREAD_CREATE": "syscall",
+ "syscall.SYS_BSDTHREAD_REGISTER": "syscall",
+ "syscall.SYS_BSDTHREAD_TERMINATE": "syscall",
+ "syscall.SYS_CAPGET": "syscall",
+ "syscall.SYS_CAPSET": "syscall",
+ "syscall.SYS_CAP_ENTER": "syscall",
+ "syscall.SYS_CAP_FCNTLS_GET": "syscall",
+ "syscall.SYS_CAP_FCNTLS_LIMIT": "syscall",
+ "syscall.SYS_CAP_GETMODE": "syscall",
+ "syscall.SYS_CAP_GETRIGHTS": "syscall",
+ "syscall.SYS_CAP_IOCTLS_GET": "syscall",
+ "syscall.SYS_CAP_IOCTLS_LIMIT": "syscall",
+ "syscall.SYS_CAP_NEW": "syscall",
+ "syscall.SYS_CAP_RIGHTS_GET": "syscall",
+ "syscall.SYS_CAP_RIGHTS_LIMIT": "syscall",
+ "syscall.SYS_CHDIR": "syscall",
+ "syscall.SYS_CHFLAGS": "syscall",
+ "syscall.SYS_CHFLAGSAT": "syscall",
+ "syscall.SYS_CHMOD": "syscall",
+ "syscall.SYS_CHMOD_EXTENDED": "syscall",
+ "syscall.SYS_CHOWN": "syscall",
+ "syscall.SYS_CHOWN32": "syscall",
+ "syscall.SYS_CHROOT": "syscall",
+ "syscall.SYS_CHUD": "syscall",
+ "syscall.SYS_CLOCK_ADJTIME": "syscall",
+ "syscall.SYS_CLOCK_GETCPUCLOCKID2": "syscall",
+ "syscall.SYS_CLOCK_GETRES": "syscall",
+ "syscall.SYS_CLOCK_GETTIME": "syscall",
+ "syscall.SYS_CLOCK_NANOSLEEP": "syscall",
+ "syscall.SYS_CLOCK_SETTIME": "syscall",
+ "syscall.SYS_CLONE": "syscall",
+ "syscall.SYS_CLOSE": "syscall",
+ "syscall.SYS_CLOSEFROM": "syscall",
+ "syscall.SYS_CLOSE_NOCANCEL": "syscall",
+ "syscall.SYS_CONNECT": "syscall",
+ "syscall.SYS_CONNECTAT": "syscall",
+ "syscall.SYS_CONNECT_NOCANCEL": "syscall",
+ "syscall.SYS_COPYFILE": "syscall",
+ "syscall.SYS_CPUSET": "syscall",
+ "syscall.SYS_CPUSET_GETAFFINITY": "syscall",
+ "syscall.SYS_CPUSET_GETID": "syscall",
+ "syscall.SYS_CPUSET_SETAFFINITY": "syscall",
+ "syscall.SYS_CPUSET_SETID": "syscall",
+ "syscall.SYS_CREAT": "syscall",
+ "syscall.SYS_CREATE_MODULE": "syscall",
+ "syscall.SYS_CSOPS": "syscall",
+ "syscall.SYS_DELETE": "syscall",
+ "syscall.SYS_DELETE_MODULE": "syscall",
+ "syscall.SYS_DUP": "syscall",
+ "syscall.SYS_DUP2": "syscall",
+ "syscall.SYS_DUP3": "syscall",
+ "syscall.SYS_EACCESS": "syscall",
+ "syscall.SYS_EPOLL_CREATE": "syscall",
+ "syscall.SYS_EPOLL_CREATE1": "syscall",
+ "syscall.SYS_EPOLL_CTL": "syscall",
+ "syscall.SYS_EPOLL_CTL_OLD": "syscall",
+ "syscall.SYS_EPOLL_PWAIT": "syscall",
+ "syscall.SYS_EPOLL_WAIT": "syscall",
+ "syscall.SYS_EPOLL_WAIT_OLD": "syscall",
+ "syscall.SYS_EVENTFD": "syscall",
+ "syscall.SYS_EVENTFD2": "syscall",
+ "syscall.SYS_EXCHANGEDATA": "syscall",
+ "syscall.SYS_EXECVE": "syscall",
+ "syscall.SYS_EXIT": "syscall",
+ "syscall.SYS_EXIT_GROUP": "syscall",
+ "syscall.SYS_EXTATTRCTL": "syscall",
+ "syscall.SYS_EXTATTR_DELETE_FD": "syscall",
+ "syscall.SYS_EXTATTR_DELETE_FILE": "syscall",
+ "syscall.SYS_EXTATTR_DELETE_LINK": "syscall",
+ "syscall.SYS_EXTATTR_GET_FD": "syscall",
+ "syscall.SYS_EXTATTR_GET_FILE": "syscall",
+ "syscall.SYS_EXTATTR_GET_LINK": "syscall",
+ "syscall.SYS_EXTATTR_LIST_FD": "syscall",
+ "syscall.SYS_EXTATTR_LIST_FILE": "syscall",
+ "syscall.SYS_EXTATTR_LIST_LINK": "syscall",
+ "syscall.SYS_EXTATTR_SET_FD": "syscall",
+ "syscall.SYS_EXTATTR_SET_FILE": "syscall",
+ "syscall.SYS_EXTATTR_SET_LINK": "syscall",
+ "syscall.SYS_FACCESSAT": "syscall",
+ "syscall.SYS_FADVISE64": "syscall",
+ "syscall.SYS_FADVISE64_64": "syscall",
+ "syscall.SYS_FALLOCATE": "syscall",
+ "syscall.SYS_FANOTIFY_INIT": "syscall",
+ "syscall.SYS_FANOTIFY_MARK": "syscall",
+ "syscall.SYS_FCHDIR": "syscall",
+ "syscall.SYS_FCHFLAGS": "syscall",
+ "syscall.SYS_FCHMOD": "syscall",
+ "syscall.SYS_FCHMODAT": "syscall",
+ "syscall.SYS_FCHMOD_EXTENDED": "syscall",
+ "syscall.SYS_FCHOWN": "syscall",
+ "syscall.SYS_FCHOWN32": "syscall",
+ "syscall.SYS_FCHOWNAT": "syscall",
+ "syscall.SYS_FCHROOT": "syscall",
+ "syscall.SYS_FCNTL": "syscall",
+ "syscall.SYS_FCNTL64": "syscall",
+ "syscall.SYS_FCNTL_NOCANCEL": "syscall",
+ "syscall.SYS_FDATASYNC": "syscall",
+ "syscall.SYS_FEXECVE": "syscall",
+ "syscall.SYS_FFCLOCK_GETCOUNTER": "syscall",
+ "syscall.SYS_FFCLOCK_GETESTIMATE": "syscall",
+ "syscall.SYS_FFCLOCK_SETESTIMATE": "syscall",
+ "syscall.SYS_FFSCTL": "syscall",
+ "syscall.SYS_FGETATTRLIST": "syscall",
+ "syscall.SYS_FGETXATTR": "syscall",
+ "syscall.SYS_FHOPEN": "syscall",
+ "syscall.SYS_FHSTAT": "syscall",
+ "syscall.SYS_FHSTATFS": "syscall",
+ "syscall.SYS_FILEPORT_MAKEFD": "syscall",
+ "syscall.SYS_FILEPORT_MAKEPORT": "syscall",
+ "syscall.SYS_FKTRACE": "syscall",
+ "syscall.SYS_FLISTXATTR": "syscall",
+ "syscall.SYS_FLOCK": "syscall",
+ "syscall.SYS_FORK": "syscall",
+ "syscall.SYS_FPATHCONF": "syscall",
+ "syscall.SYS_FREEBSD6_FTRUNCATE": "syscall",
+ "syscall.SYS_FREEBSD6_LSEEK": "syscall",
+ "syscall.SYS_FREEBSD6_MMAP": "syscall",
+ "syscall.SYS_FREEBSD6_PREAD": "syscall",
+ "syscall.SYS_FREEBSD6_PWRITE": "syscall",
+ "syscall.SYS_FREEBSD6_TRUNCATE": "syscall",
+ "syscall.SYS_FREMOVEXATTR": "syscall",
+ "syscall.SYS_FSCTL": "syscall",
+ "syscall.SYS_FSETATTRLIST": "syscall",
+ "syscall.SYS_FSETXATTR": "syscall",
+ "syscall.SYS_FSGETPATH": "syscall",
+ "syscall.SYS_FSTAT": "syscall",
+ "syscall.SYS_FSTAT64": "syscall",
+ "syscall.SYS_FSTAT64_EXTENDED": "syscall",
+ "syscall.SYS_FSTATAT": "syscall",
+ "syscall.SYS_FSTATAT64": "syscall",
+ "syscall.SYS_FSTATFS": "syscall",
+ "syscall.SYS_FSTATFS64": "syscall",
+ "syscall.SYS_FSTATV": "syscall",
+ "syscall.SYS_FSTATVFS1": "syscall",
+ "syscall.SYS_FSTAT_EXTENDED": "syscall",
+ "syscall.SYS_FSYNC": "syscall",
+ "syscall.SYS_FSYNC_NOCANCEL": "syscall",
+ "syscall.SYS_FSYNC_RANGE": "syscall",
+ "syscall.SYS_FTIME": "syscall",
+ "syscall.SYS_FTRUNCATE": "syscall",
+ "syscall.SYS_FTRUNCATE64": "syscall",
+ "syscall.SYS_FUTEX": "syscall",
+ "syscall.SYS_FUTIMENS": "syscall",
+ "syscall.SYS_FUTIMES": "syscall",
+ "syscall.SYS_FUTIMESAT": "syscall",
+ "syscall.SYS_GETATTRLIST": "syscall",
+ "syscall.SYS_GETAUDIT": "syscall",
+ "syscall.SYS_GETAUDIT_ADDR": "syscall",
+ "syscall.SYS_GETAUID": "syscall",
+ "syscall.SYS_GETCONTEXT": "syscall",
+ "syscall.SYS_GETCPU": "syscall",
+ "syscall.SYS_GETCWD": "syscall",
+ "syscall.SYS_GETDENTS": "syscall",
+ "syscall.SYS_GETDENTS64": "syscall",
+ "syscall.SYS_GETDIRENTRIES": "syscall",
+ "syscall.SYS_GETDIRENTRIES64": "syscall",
+ "syscall.SYS_GETDIRENTRIESATTR": "syscall",
+ "syscall.SYS_GETDTABLECOUNT": "syscall",
+ "syscall.SYS_GETDTABLESIZE": "syscall",
+ "syscall.SYS_GETEGID": "syscall",
+ "syscall.SYS_GETEGID32": "syscall",
+ "syscall.SYS_GETEUID": "syscall",
+ "syscall.SYS_GETEUID32": "syscall",
+ "syscall.SYS_GETFH": "syscall",
+ "syscall.SYS_GETFSSTAT": "syscall",
+ "syscall.SYS_GETFSSTAT64": "syscall",
+ "syscall.SYS_GETGID": "syscall",
+ "syscall.SYS_GETGID32": "syscall",
+ "syscall.SYS_GETGROUPS": "syscall",
+ "syscall.SYS_GETGROUPS32": "syscall",
+ "syscall.SYS_GETHOSTUUID": "syscall",
+ "syscall.SYS_GETITIMER": "syscall",
+ "syscall.SYS_GETLCID": "syscall",
+ "syscall.SYS_GETLOGIN": "syscall",
+ "syscall.SYS_GETLOGINCLASS": "syscall",
+ "syscall.SYS_GETPEERNAME": "syscall",
+ "syscall.SYS_GETPGID": "syscall",
+ "syscall.SYS_GETPGRP": "syscall",
+ "syscall.SYS_GETPID": "syscall",
+ "syscall.SYS_GETPMSG": "syscall",
+ "syscall.SYS_GETPPID": "syscall",
+ "syscall.SYS_GETPRIORITY": "syscall",
+ "syscall.SYS_GETRESGID": "syscall",
+ "syscall.SYS_GETRESGID32": "syscall",
+ "syscall.SYS_GETRESUID": "syscall",
+ "syscall.SYS_GETRESUID32": "syscall",
+ "syscall.SYS_GETRLIMIT": "syscall",
+ "syscall.SYS_GETRTABLE": "syscall",
+ "syscall.SYS_GETRUSAGE": "syscall",
+ "syscall.SYS_GETSGROUPS": "syscall",
+ "syscall.SYS_GETSID": "syscall",
+ "syscall.SYS_GETSOCKNAME": "syscall",
+ "syscall.SYS_GETSOCKOPT": "syscall",
+ "syscall.SYS_GETTHRID": "syscall",
+ "syscall.SYS_GETTID": "syscall",
+ "syscall.SYS_GETTIMEOFDAY": "syscall",
+ "syscall.SYS_GETUID": "syscall",
+ "syscall.SYS_GETUID32": "syscall",
+ "syscall.SYS_GETVFSSTAT": "syscall",
+ "syscall.SYS_GETWGROUPS": "syscall",
+ "syscall.SYS_GETXATTR": "syscall",
+ "syscall.SYS_GET_KERNEL_SYMS": "syscall",
+ "syscall.SYS_GET_MEMPOLICY": "syscall",
+ "syscall.SYS_GET_ROBUST_LIST": "syscall",
+ "syscall.SYS_GET_THREAD_AREA": "syscall",
+ "syscall.SYS_GTTY": "syscall",
+ "syscall.SYS_IDENTITYSVC": "syscall",
+ "syscall.SYS_IDLE": "syscall",
+ "syscall.SYS_INITGROUPS": "syscall",
+ "syscall.SYS_INIT_MODULE": "syscall",
+ "syscall.SYS_INOTIFY_ADD_WATCH": "syscall",
+ "syscall.SYS_INOTIFY_INIT": "syscall",
+ "syscall.SYS_INOTIFY_INIT1": "syscall",
+ "syscall.SYS_INOTIFY_RM_WATCH": "syscall",
+ "syscall.SYS_IOCTL": "syscall",
+ "syscall.SYS_IOPERM": "syscall",
+ "syscall.SYS_IOPL": "syscall",
+ "syscall.SYS_IOPOLICYSYS": "syscall",
+ "syscall.SYS_IOPRIO_GET": "syscall",
+ "syscall.SYS_IOPRIO_SET": "syscall",
+ "syscall.SYS_IO_CANCEL": "syscall",
+ "syscall.SYS_IO_DESTROY": "syscall",
+ "syscall.SYS_IO_GETEVENTS": "syscall",
+ "syscall.SYS_IO_SETUP": "syscall",
+ "syscall.SYS_IO_SUBMIT": "syscall",
+ "syscall.SYS_IPC": "syscall",
+ "syscall.SYS_ISSETUGID": "syscall",
+ "syscall.SYS_JAIL": "syscall",
+ "syscall.SYS_JAIL_ATTACH": "syscall",
+ "syscall.SYS_JAIL_GET": "syscall",
+ "syscall.SYS_JAIL_REMOVE": "syscall",
+ "syscall.SYS_JAIL_SET": "syscall",
+ "syscall.SYS_KDEBUG_TRACE": "syscall",
+ "syscall.SYS_KENV": "syscall",
+ "syscall.SYS_KEVENT": "syscall",
+ "syscall.SYS_KEVENT64": "syscall",
+ "syscall.SYS_KEXEC_LOAD": "syscall",
+ "syscall.SYS_KEYCTL": "syscall",
+ "syscall.SYS_KILL": "syscall",
+ "syscall.SYS_KLDFIND": "syscall",
+ "syscall.SYS_KLDFIRSTMOD": "syscall",
+ "syscall.SYS_KLDLOAD": "syscall",
+ "syscall.SYS_KLDNEXT": "syscall",
+ "syscall.SYS_KLDSTAT": "syscall",
+ "syscall.SYS_KLDSYM": "syscall",
+ "syscall.SYS_KLDUNLOAD": "syscall",
+ "syscall.SYS_KLDUNLOADF": "syscall",
+ "syscall.SYS_KQUEUE": "syscall",
+ "syscall.SYS_KQUEUE1": "syscall",
+ "syscall.SYS_KTIMER_CREATE": "syscall",
+ "syscall.SYS_KTIMER_DELETE": "syscall",
+ "syscall.SYS_KTIMER_GETOVERRUN": "syscall",
+ "syscall.SYS_KTIMER_GETTIME": "syscall",
+ "syscall.SYS_KTIMER_SETTIME": "syscall",
+ "syscall.SYS_KTRACE": "syscall",
+ "syscall.SYS_LCHFLAGS": "syscall",
+ "syscall.SYS_LCHMOD": "syscall",
+ "syscall.SYS_LCHOWN": "syscall",
+ "syscall.SYS_LCHOWN32": "syscall",
+ "syscall.SYS_LGETFH": "syscall",
+ "syscall.SYS_LGETXATTR": "syscall",
+ "syscall.SYS_LINK": "syscall",
+ "syscall.SYS_LINKAT": "syscall",
+ "syscall.SYS_LIO_LISTIO": "syscall",
+ "syscall.SYS_LISTEN": "syscall",
+ "syscall.SYS_LISTXATTR": "syscall",
+ "syscall.SYS_LLISTXATTR": "syscall",
+ "syscall.SYS_LOCK": "syscall",
+ "syscall.SYS_LOOKUP_DCOOKIE": "syscall",
+ "syscall.SYS_LPATHCONF": "syscall",
+ "syscall.SYS_LREMOVEXATTR": "syscall",
+ "syscall.SYS_LSEEK": "syscall",
+ "syscall.SYS_LSETXATTR": "syscall",
+ "syscall.SYS_LSTAT": "syscall",
+ "syscall.SYS_LSTAT64": "syscall",
+ "syscall.SYS_LSTAT64_EXTENDED": "syscall",
+ "syscall.SYS_LSTATV": "syscall",
+ "syscall.SYS_LSTAT_EXTENDED": "syscall",
+ "syscall.SYS_LUTIMES": "syscall",
+ "syscall.SYS_MAC_SYSCALL": "syscall",
+ "syscall.SYS_MADVISE": "syscall",
+ "syscall.SYS_MADVISE1": "syscall",
+ "syscall.SYS_MAXSYSCALL": "syscall",
+ "syscall.SYS_MBIND": "syscall",
+ "syscall.SYS_MIGRATE_PAGES": "syscall",
+ "syscall.SYS_MINCORE": "syscall",
+ "syscall.SYS_MINHERIT": "syscall",
+ "syscall.SYS_MKCOMPLEX": "syscall",
+ "syscall.SYS_MKDIR": "syscall",
+ "syscall.SYS_MKDIRAT": "syscall",
+ "syscall.SYS_MKDIR_EXTENDED": "syscall",
+ "syscall.SYS_MKFIFO": "syscall",
+ "syscall.SYS_MKFIFOAT": "syscall",
+ "syscall.SYS_MKFIFO_EXTENDED": "syscall",
+ "syscall.SYS_MKNOD": "syscall",
+ "syscall.SYS_MKNODAT": "syscall",
+ "syscall.SYS_MLOCK": "syscall",
+ "syscall.SYS_MLOCKALL": "syscall",
+ "syscall.SYS_MMAP": "syscall",
+ "syscall.SYS_MMAP2": "syscall",
+ "syscall.SYS_MODCTL": "syscall",
+ "syscall.SYS_MODFIND": "syscall",
+ "syscall.SYS_MODFNEXT": "syscall",
+ "syscall.SYS_MODIFY_LDT": "syscall",
+ "syscall.SYS_MODNEXT": "syscall",
+ "syscall.SYS_MODSTAT": "syscall",
+ "syscall.SYS_MODWATCH": "syscall",
+ "syscall.SYS_MOUNT": "syscall",
+ "syscall.SYS_MOVE_PAGES": "syscall",
+ "syscall.SYS_MPROTECT": "syscall",
+ "syscall.SYS_MPX": "syscall",
+ "syscall.SYS_MQUERY": "syscall",
+ "syscall.SYS_MQ_GETSETATTR": "syscall",
+ "syscall.SYS_MQ_NOTIFY": "syscall",
+ "syscall.SYS_MQ_OPEN": "syscall",
+ "syscall.SYS_MQ_TIMEDRECEIVE": "syscall",
+ "syscall.SYS_MQ_TIMEDSEND": "syscall",
+ "syscall.SYS_MQ_UNLINK": "syscall",
+ "syscall.SYS_MREMAP": "syscall",
+ "syscall.SYS_MSGCTL": "syscall",
+ "syscall.SYS_MSGGET": "syscall",
+ "syscall.SYS_MSGRCV": "syscall",
+ "syscall.SYS_MSGRCV_NOCANCEL": "syscall",
+ "syscall.SYS_MSGSND": "syscall",
+ "syscall.SYS_MSGSND_NOCANCEL": "syscall",
+ "syscall.SYS_MSGSYS": "syscall",
+ "syscall.SYS_MSYNC": "syscall",
+ "syscall.SYS_MSYNC_NOCANCEL": "syscall",
+ "syscall.SYS_MUNLOCK": "syscall",
+ "syscall.SYS_MUNLOCKALL": "syscall",
+ "syscall.SYS_MUNMAP": "syscall",
+ "syscall.SYS_NAME_TO_HANDLE_AT": "syscall",
+ "syscall.SYS_NANOSLEEP": "syscall",
+ "syscall.SYS_NEWFSTATAT": "syscall",
+ "syscall.SYS_NFSCLNT": "syscall",
+ "syscall.SYS_NFSSERVCTL": "syscall",
+ "syscall.SYS_NFSSVC": "syscall",
+ "syscall.SYS_NFSTAT": "syscall",
+ "syscall.SYS_NICE": "syscall",
+ "syscall.SYS_NLSTAT": "syscall",
+ "syscall.SYS_NMOUNT": "syscall",
+ "syscall.SYS_NSTAT": "syscall",
+ "syscall.SYS_NTP_ADJTIME": "syscall",
+ "syscall.SYS_NTP_GETTIME": "syscall",
+ "syscall.SYS_OABI_SYSCALL_BASE": "syscall",
+ "syscall.SYS_OBREAK": "syscall",
+ "syscall.SYS_OLDFSTAT": "syscall",
+ "syscall.SYS_OLDLSTAT": "syscall",
+ "syscall.SYS_OLDOLDUNAME": "syscall",
+ "syscall.SYS_OLDSTAT": "syscall",
+ "syscall.SYS_OLDUNAME": "syscall",
+ "syscall.SYS_OPEN": "syscall",
+ "syscall.SYS_OPENAT": "syscall",
+ "syscall.SYS_OPENBSD_POLL": "syscall",
+ "syscall.SYS_OPEN_BY_HANDLE_AT": "syscall",
+ "syscall.SYS_OPEN_EXTENDED": "syscall",
+ "syscall.SYS_OPEN_NOCANCEL": "syscall",
+ "syscall.SYS_OVADVISE": "syscall",
+ "syscall.SYS_PACCEPT": "syscall",
+ "syscall.SYS_PATHCONF": "syscall",
+ "syscall.SYS_PAUSE": "syscall",
+ "syscall.SYS_PCICONFIG_IOBASE": "syscall",
+ "syscall.SYS_PCICONFIG_READ": "syscall",
+ "syscall.SYS_PCICONFIG_WRITE": "syscall",
+ "syscall.SYS_PDFORK": "syscall",
+ "syscall.SYS_PDGETPID": "syscall",
+ "syscall.SYS_PDKILL": "syscall",
+ "syscall.SYS_PERF_EVENT_OPEN": "syscall",
+ "syscall.SYS_PERSONALITY": "syscall",
+ "syscall.SYS_PID_HIBERNATE": "syscall",
+ "syscall.SYS_PID_RESUME": "syscall",
+ "syscall.SYS_PID_SHUTDOWN_SOCKETS": "syscall",
+ "syscall.SYS_PID_SUSPEND": "syscall",
+ "syscall.SYS_PIPE": "syscall",
+ "syscall.SYS_PIPE2": "syscall",
+ "syscall.SYS_PIVOT_ROOT": "syscall",
+ "syscall.SYS_PMC_CONTROL": "syscall",
+ "syscall.SYS_PMC_GET_INFO": "syscall",
+ "syscall.SYS_POLL": "syscall",
+ "syscall.SYS_POLLTS": "syscall",
+ "syscall.SYS_POLL_NOCANCEL": "syscall",
+ "syscall.SYS_POSIX_FADVISE": "syscall",
+ "syscall.SYS_POSIX_FALLOCATE": "syscall",
+ "syscall.SYS_POSIX_OPENPT": "syscall",
+ "syscall.SYS_POSIX_SPAWN": "syscall",
+ "syscall.SYS_PPOLL": "syscall",
+ "syscall.SYS_PRCTL": "syscall",
+ "syscall.SYS_PREAD": "syscall",
+ "syscall.SYS_PREAD64": "syscall",
+ "syscall.SYS_PREADV": "syscall",
+ "syscall.SYS_PREAD_NOCANCEL": "syscall",
+ "syscall.SYS_PRLIMIT64": "syscall",
+ "syscall.SYS_PROCCTL": "syscall",
+ "syscall.SYS_PROCESS_POLICY": "syscall",
+ "syscall.SYS_PROCESS_VM_READV": "syscall",
+ "syscall.SYS_PROCESS_VM_WRITEV": "syscall",
+ "syscall.SYS_PROC_INFO": "syscall",
+ "syscall.SYS_PROF": "syscall",
+ "syscall.SYS_PROFIL": "syscall",
+ "syscall.SYS_PSELECT": "syscall",
+ "syscall.SYS_PSELECT6": "syscall",
+ "syscall.SYS_PSET_ASSIGN": "syscall",
+ "syscall.SYS_PSET_CREATE": "syscall",
+ "syscall.SYS_PSET_DESTROY": "syscall",
+ "syscall.SYS_PSYNCH_CVBROAD": "syscall",
+ "syscall.SYS_PSYNCH_CVCLRPREPOST": "syscall",
+ "syscall.SYS_PSYNCH_CVSIGNAL": "syscall",
+ "syscall.SYS_PSYNCH_CVWAIT": "syscall",
+ "syscall.SYS_PSYNCH_MUTEXDROP": "syscall",
+ "syscall.SYS_PSYNCH_MUTEXWAIT": "syscall",
+ "syscall.SYS_PSYNCH_RW_DOWNGRADE": "syscall",
+ "syscall.SYS_PSYNCH_RW_LONGRDLOCK": "syscall",
+ "syscall.SYS_PSYNCH_RW_RDLOCK": "syscall",
+ "syscall.SYS_PSYNCH_RW_UNLOCK": "syscall",
+ "syscall.SYS_PSYNCH_RW_UNLOCK2": "syscall",
+ "syscall.SYS_PSYNCH_RW_UPGRADE": "syscall",
+ "syscall.SYS_PSYNCH_RW_WRLOCK": "syscall",
+ "syscall.SYS_PSYNCH_RW_YIELDWRLOCK": "syscall",
+ "syscall.SYS_PTRACE": "syscall",
+ "syscall.SYS_PUTPMSG": "syscall",
+ "syscall.SYS_PWRITE": "syscall",
+ "syscall.SYS_PWRITE64": "syscall",
+ "syscall.SYS_PWRITEV": "syscall",
+ "syscall.SYS_PWRITE_NOCANCEL": "syscall",
+ "syscall.SYS_QUERY_MODULE": "syscall",
+ "syscall.SYS_QUOTACTL": "syscall",
+ "syscall.SYS_RASCTL": "syscall",
+ "syscall.SYS_RCTL_ADD_RULE": "syscall",
+ "syscall.SYS_RCTL_GET_LIMITS": "syscall",
+ "syscall.SYS_RCTL_GET_RACCT": "syscall",
+ "syscall.SYS_RCTL_GET_RULES": "syscall",
+ "syscall.SYS_RCTL_REMOVE_RULE": "syscall",
+ "syscall.SYS_READ": "syscall",
+ "syscall.SYS_READAHEAD": "syscall",
+ "syscall.SYS_READDIR": "syscall",
+ "syscall.SYS_READLINK": "syscall",
+ "syscall.SYS_READLINKAT": "syscall",
+ "syscall.SYS_READV": "syscall",
+ "syscall.SYS_READV_NOCANCEL": "syscall",
+ "syscall.SYS_READ_NOCANCEL": "syscall",
+ "syscall.SYS_REBOOT": "syscall",
+ "syscall.SYS_RECV": "syscall",
+ "syscall.SYS_RECVFROM": "syscall",
+ "syscall.SYS_RECVFROM_NOCANCEL": "syscall",
+ "syscall.SYS_RECVMMSG": "syscall",
+ "syscall.SYS_RECVMSG": "syscall",
+ "syscall.SYS_RECVMSG_NOCANCEL": "syscall",
+ "syscall.SYS_REMAP_FILE_PAGES": "syscall",
+ "syscall.SYS_REMOVEXATTR": "syscall",
+ "syscall.SYS_RENAME": "syscall",
+ "syscall.SYS_RENAMEAT": "syscall",
+ "syscall.SYS_REQUEST_KEY": "syscall",
+ "syscall.SYS_RESTART_SYSCALL": "syscall",
+ "syscall.SYS_REVOKE": "syscall",
+ "syscall.SYS_RFORK": "syscall",
+ "syscall.SYS_RMDIR": "syscall",
+ "syscall.SYS_RTPRIO": "syscall",
+ "syscall.SYS_RTPRIO_THREAD": "syscall",
+ "syscall.SYS_RT_SIGACTION": "syscall",
+ "syscall.SYS_RT_SIGPENDING": "syscall",
+ "syscall.SYS_RT_SIGPROCMASK": "syscall",
+ "syscall.SYS_RT_SIGQUEUEINFO": "syscall",
+ "syscall.SYS_RT_SIGRETURN": "syscall",
+ "syscall.SYS_RT_SIGSUSPEND": "syscall",
+ "syscall.SYS_RT_SIGTIMEDWAIT": "syscall",
+ "syscall.SYS_RT_TGSIGQUEUEINFO": "syscall",
+ "syscall.SYS_SBRK": "syscall",
+ "syscall.SYS_SCHED_GETAFFINITY": "syscall",
+ "syscall.SYS_SCHED_GETPARAM": "syscall",
+ "syscall.SYS_SCHED_GETSCHEDULER": "syscall",
+ "syscall.SYS_SCHED_GET_PRIORITY_MAX": "syscall",
+ "syscall.SYS_SCHED_GET_PRIORITY_MIN": "syscall",
+ "syscall.SYS_SCHED_RR_GET_INTERVAL": "syscall",
+ "syscall.SYS_SCHED_SETAFFINITY": "syscall",
+ "syscall.SYS_SCHED_SETPARAM": "syscall",
+ "syscall.SYS_SCHED_SETSCHEDULER": "syscall",
+ "syscall.SYS_SCHED_YIELD": "syscall",
+ "syscall.SYS_SCTP_GENERIC_RECVMSG": "syscall",
+ "syscall.SYS_SCTP_GENERIC_SENDMSG": "syscall",
+ "syscall.SYS_SCTP_GENERIC_SENDMSG_IOV": "syscall",
+ "syscall.SYS_SCTP_PEELOFF": "syscall",
+ "syscall.SYS_SEARCHFS": "syscall",
+ "syscall.SYS_SECURITY": "syscall",
+ "syscall.SYS_SELECT": "syscall",
+ "syscall.SYS_SELECT_NOCANCEL": "syscall",
+ "syscall.SYS_SEMCONFIG": "syscall",
+ "syscall.SYS_SEMCTL": "syscall",
+ "syscall.SYS_SEMGET": "syscall",
+ "syscall.SYS_SEMOP": "syscall",
+ "syscall.SYS_SEMSYS": "syscall",
+ "syscall.SYS_SEMTIMEDOP": "syscall",
+ "syscall.SYS_SEM_CLOSE": "syscall",
+ "syscall.SYS_SEM_DESTROY": "syscall",
+ "syscall.SYS_SEM_GETVALUE": "syscall",
+ "syscall.SYS_SEM_INIT": "syscall",
+ "syscall.SYS_SEM_OPEN": "syscall",
+ "syscall.SYS_SEM_POST": "syscall",
+ "syscall.SYS_SEM_TRYWAIT": "syscall",
+ "syscall.SYS_SEM_UNLINK": "syscall",
+ "syscall.SYS_SEM_WAIT": "syscall",
+ "syscall.SYS_SEM_WAIT_NOCANCEL": "syscall",
+ "syscall.SYS_SEND": "syscall",
+ "syscall.SYS_SENDFILE": "syscall",
+ "syscall.SYS_SENDFILE64": "syscall",
+ "syscall.SYS_SENDMMSG": "syscall",
+ "syscall.SYS_SENDMSG": "syscall",
+ "syscall.SYS_SENDMSG_NOCANCEL": "syscall",
+ "syscall.SYS_SENDTO": "syscall",
+ "syscall.SYS_SENDTO_NOCANCEL": "syscall",
+ "syscall.SYS_SETATTRLIST": "syscall",
+ "syscall.SYS_SETAUDIT": "syscall",
+ "syscall.SYS_SETAUDIT_ADDR": "syscall",
+ "syscall.SYS_SETAUID": "syscall",
+ "syscall.SYS_SETCONTEXT": "syscall",
+ "syscall.SYS_SETDOMAINNAME": "syscall",
+ "syscall.SYS_SETEGID": "syscall",
+ "syscall.SYS_SETEUID": "syscall",
+ "syscall.SYS_SETFIB": "syscall",
+ "syscall.SYS_SETFSGID": "syscall",
+ "syscall.SYS_SETFSGID32": "syscall",
+ "syscall.SYS_SETFSUID": "syscall",
+ "syscall.SYS_SETFSUID32": "syscall",
+ "syscall.SYS_SETGID": "syscall",
+ "syscall.SYS_SETGID32": "syscall",
+ "syscall.SYS_SETGROUPS": "syscall",
+ "syscall.SYS_SETGROUPS32": "syscall",
+ "syscall.SYS_SETHOSTNAME": "syscall",
+ "syscall.SYS_SETITIMER": "syscall",
+ "syscall.SYS_SETLCID": "syscall",
+ "syscall.SYS_SETLOGIN": "syscall",
+ "syscall.SYS_SETLOGINCLASS": "syscall",
+ "syscall.SYS_SETNS": "syscall",
+ "syscall.SYS_SETPGID": "syscall",
+ "syscall.SYS_SETPRIORITY": "syscall",
+ "syscall.SYS_SETPRIVEXEC": "syscall",
+ "syscall.SYS_SETREGID": "syscall",
+ "syscall.SYS_SETREGID32": "syscall",
+ "syscall.SYS_SETRESGID": "syscall",
+ "syscall.SYS_SETRESGID32": "syscall",
+ "syscall.SYS_SETRESUID": "syscall",
+ "syscall.SYS_SETRESUID32": "syscall",
+ "syscall.SYS_SETREUID": "syscall",
+ "syscall.SYS_SETREUID32": "syscall",
+ "syscall.SYS_SETRLIMIT": "syscall",
+ "syscall.SYS_SETRTABLE": "syscall",
+ "syscall.SYS_SETSGROUPS": "syscall",
+ "syscall.SYS_SETSID": "syscall",
+ "syscall.SYS_SETSOCKOPT": "syscall",
+ "syscall.SYS_SETTID": "syscall",
+ "syscall.SYS_SETTID_WITH_PID": "syscall",
+ "syscall.SYS_SETTIMEOFDAY": "syscall",
+ "syscall.SYS_SETUID": "syscall",
+ "syscall.SYS_SETUID32": "syscall",
+ "syscall.SYS_SETWGROUPS": "syscall",
+ "syscall.SYS_SETXATTR": "syscall",
+ "syscall.SYS_SET_MEMPOLICY": "syscall",
+ "syscall.SYS_SET_ROBUST_LIST": "syscall",
+ "syscall.SYS_SET_THREAD_AREA": "syscall",
+ "syscall.SYS_SET_TID_ADDRESS": "syscall",
+ "syscall.SYS_SGETMASK": "syscall",
+ "syscall.SYS_SHARED_REGION_CHECK_NP": "syscall",
+ "syscall.SYS_SHARED_REGION_MAP_AND_SLIDE_NP": "syscall",
+ "syscall.SYS_SHMAT": "syscall",
+ "syscall.SYS_SHMCTL": "syscall",
+ "syscall.SYS_SHMDT": "syscall",
+ "syscall.SYS_SHMGET": "syscall",
+ "syscall.SYS_SHMSYS": "syscall",
+ "syscall.SYS_SHM_OPEN": "syscall",
+ "syscall.SYS_SHM_UNLINK": "syscall",
+ "syscall.SYS_SHUTDOWN": "syscall",
+ "syscall.SYS_SIGACTION": "syscall",
+ "syscall.SYS_SIGALTSTACK": "syscall",
+ "syscall.SYS_SIGNAL": "syscall",
+ "syscall.SYS_SIGNALFD": "syscall",
+ "syscall.SYS_SIGNALFD4": "syscall",
+ "syscall.SYS_SIGPENDING": "syscall",
+ "syscall.SYS_SIGPROCMASK": "syscall",
+ "syscall.SYS_SIGQUEUE": "syscall",
+ "syscall.SYS_SIGQUEUEINFO": "syscall",
+ "syscall.SYS_SIGRETURN": "syscall",
+ "syscall.SYS_SIGSUSPEND": "syscall",
+ "syscall.SYS_SIGSUSPEND_NOCANCEL": "syscall",
+ "syscall.SYS_SIGTIMEDWAIT": "syscall",
+ "syscall.SYS_SIGWAIT": "syscall",
+ "syscall.SYS_SIGWAITINFO": "syscall",
+ "syscall.SYS_SOCKET": "syscall",
+ "syscall.SYS_SOCKETCALL": "syscall",
+ "syscall.SYS_SOCKETPAIR": "syscall",
+ "syscall.SYS_SPLICE": "syscall",
+ "syscall.SYS_SSETMASK": "syscall",
+ "syscall.SYS_SSTK": "syscall",
+ "syscall.SYS_STACK_SNAPSHOT": "syscall",
+ "syscall.SYS_STAT": "syscall",
+ "syscall.SYS_STAT64": "syscall",
+ "syscall.SYS_STAT64_EXTENDED": "syscall",
+ "syscall.SYS_STATFS": "syscall",
+ "syscall.SYS_STATFS64": "syscall",
+ "syscall.SYS_STATV": "syscall",
+ "syscall.SYS_STATVFS1": "syscall",
+ "syscall.SYS_STAT_EXTENDED": "syscall",
+ "syscall.SYS_STIME": "syscall",
+ "syscall.SYS_STTY": "syscall",
+ "syscall.SYS_SWAPCONTEXT": "syscall",
+ "syscall.SYS_SWAPCTL": "syscall",
+ "syscall.SYS_SWAPOFF": "syscall",
+ "syscall.SYS_SWAPON": "syscall",
+ "syscall.SYS_SYMLINK": "syscall",
+ "syscall.SYS_SYMLINKAT": "syscall",
+ "syscall.SYS_SYNC": "syscall",
+ "syscall.SYS_SYNCFS": "syscall",
+ "syscall.SYS_SYNC_FILE_RANGE": "syscall",
+ "syscall.SYS_SYSARCH": "syscall",
+ "syscall.SYS_SYSCALL": "syscall",
+ "syscall.SYS_SYSCALL_BASE": "syscall",
+ "syscall.SYS_SYSFS": "syscall",
+ "syscall.SYS_SYSINFO": "syscall",
+ "syscall.SYS_SYSLOG": "syscall",
+ "syscall.SYS_TEE": "syscall",
+ "syscall.SYS_TGKILL": "syscall",
+ "syscall.SYS_THREAD_SELFID": "syscall",
+ "syscall.SYS_THR_CREATE": "syscall",
+ "syscall.SYS_THR_EXIT": "syscall",
+ "syscall.SYS_THR_KILL": "syscall",
+ "syscall.SYS_THR_KILL2": "syscall",
+ "syscall.SYS_THR_NEW": "syscall",
+ "syscall.SYS_THR_SELF": "syscall",
+ "syscall.SYS_THR_SET_NAME": "syscall",
+ "syscall.SYS_THR_SUSPEND": "syscall",
+ "syscall.SYS_THR_WAKE": "syscall",
+ "syscall.SYS_TIME": "syscall",
+ "syscall.SYS_TIMERFD_CREATE": "syscall",
+ "syscall.SYS_TIMERFD_GETTIME": "syscall",
+ "syscall.SYS_TIMERFD_SETTIME": "syscall",
+ "syscall.SYS_TIMER_CREATE": "syscall",
+ "syscall.SYS_TIMER_DELETE": "syscall",
+ "syscall.SYS_TIMER_GETOVERRUN": "syscall",
+ "syscall.SYS_TIMER_GETTIME": "syscall",
+ "syscall.SYS_TIMER_SETTIME": "syscall",
+ "syscall.SYS_TIMES": "syscall",
+ "syscall.SYS_TKILL": "syscall",
+ "syscall.SYS_TRUNCATE": "syscall",
+ "syscall.SYS_TRUNCATE64": "syscall",
+ "syscall.SYS_TUXCALL": "syscall",
+ "syscall.SYS_UGETRLIMIT": "syscall",
+ "syscall.SYS_ULIMIT": "syscall",
+ "syscall.SYS_UMASK": "syscall",
+ "syscall.SYS_UMASK_EXTENDED": "syscall",
+ "syscall.SYS_UMOUNT": "syscall",
+ "syscall.SYS_UMOUNT2": "syscall",
+ "syscall.SYS_UNAME": "syscall",
+ "syscall.SYS_UNDELETE": "syscall",
+ "syscall.SYS_UNLINK": "syscall",
+ "syscall.SYS_UNLINKAT": "syscall",
+ "syscall.SYS_UNMOUNT": "syscall",
+ "syscall.SYS_UNSHARE": "syscall",
+ "syscall.SYS_USELIB": "syscall",
+ "syscall.SYS_USTAT": "syscall",
+ "syscall.SYS_UTIME": "syscall",
+ "syscall.SYS_UTIMENSAT": "syscall",
+ "syscall.SYS_UTIMES": "syscall",
+ "syscall.SYS_UTRACE": "syscall",
+ "syscall.SYS_UUIDGEN": "syscall",
+ "syscall.SYS_VADVISE": "syscall",
+ "syscall.SYS_VFORK": "syscall",
+ "syscall.SYS_VHANGUP": "syscall",
+ "syscall.SYS_VM86": "syscall",
+ "syscall.SYS_VM86OLD": "syscall",
+ "syscall.SYS_VMSPLICE": "syscall",
+ "syscall.SYS_VM_PRESSURE_MONITOR": "syscall",
+ "syscall.SYS_VSERVER": "syscall",
+ "syscall.SYS_WAIT4": "syscall",
+ "syscall.SYS_WAIT4_NOCANCEL": "syscall",
+ "syscall.SYS_WAIT6": "syscall",
+ "syscall.SYS_WAITEVENT": "syscall",
+ "syscall.SYS_WAITID": "syscall",
+ "syscall.SYS_WAITID_NOCANCEL": "syscall",
+ "syscall.SYS_WAITPID": "syscall",
+ "syscall.SYS_WATCHEVENT": "syscall",
+ "syscall.SYS_WORKQ_KERNRETURN": "syscall",
+ "syscall.SYS_WORKQ_OPEN": "syscall",
+ "syscall.SYS_WRITE": "syscall",
+ "syscall.SYS_WRITEV": "syscall",
+ "syscall.SYS_WRITEV_NOCANCEL": "syscall",
+ "syscall.SYS_WRITE_NOCANCEL": "syscall",
+ "syscall.SYS_YIELD": "syscall",
+ "syscall.SYS__LLSEEK": "syscall",
+ "syscall.SYS__LWP_CONTINUE": "syscall",
+ "syscall.SYS__LWP_CREATE": "syscall",
+ "syscall.SYS__LWP_CTL": "syscall",
+ "syscall.SYS__LWP_DETACH": "syscall",
+ "syscall.SYS__LWP_EXIT": "syscall",
+ "syscall.SYS__LWP_GETNAME": "syscall",
+ "syscall.SYS__LWP_GETPRIVATE": "syscall",
+ "syscall.SYS__LWP_KILL": "syscall",
+ "syscall.SYS__LWP_PARK": "syscall",
+ "syscall.SYS__LWP_SELF": "syscall",
+ "syscall.SYS__LWP_SETNAME": "syscall",
+ "syscall.SYS__LWP_SETPRIVATE": "syscall",
+ "syscall.SYS__LWP_SUSPEND": "syscall",
+ "syscall.SYS__LWP_UNPARK": "syscall",
+ "syscall.SYS__LWP_UNPARK_ALL": "syscall",
+ "syscall.SYS__LWP_WAIT": "syscall",
+ "syscall.SYS__LWP_WAKEUP": "syscall",
+ "syscall.SYS__NEWSELECT": "syscall",
+ "syscall.SYS__PSET_BIND": "syscall",
+ "syscall.SYS__SCHED_GETAFFINITY": "syscall",
+ "syscall.SYS__SCHED_GETPARAM": "syscall",
+ "syscall.SYS__SCHED_SETAFFINITY": "syscall",
+ "syscall.SYS__SCHED_SETPARAM": "syscall",
+ "syscall.SYS__SYSCTL": "syscall",
+ "syscall.SYS__UMTX_LOCK": "syscall",
+ "syscall.SYS__UMTX_OP": "syscall",
+ "syscall.SYS__UMTX_UNLOCK": "syscall",
+ "syscall.SYS___ACL_ACLCHECK_FD": "syscall",
+ "syscall.SYS___ACL_ACLCHECK_FILE": "syscall",
+ "syscall.SYS___ACL_ACLCHECK_LINK": "syscall",
+ "syscall.SYS___ACL_DELETE_FD": "syscall",
+ "syscall.SYS___ACL_DELETE_FILE": "syscall",
+ "syscall.SYS___ACL_DELETE_LINK": "syscall",
+ "syscall.SYS___ACL_GET_FD": "syscall",
+ "syscall.SYS___ACL_GET_FILE": "syscall",
+ "syscall.SYS___ACL_GET_LINK": "syscall",
+ "syscall.SYS___ACL_SET_FD": "syscall",
+ "syscall.SYS___ACL_SET_FILE": "syscall",
+ "syscall.SYS___ACL_SET_LINK": "syscall",
+ "syscall.SYS___CLONE": "syscall",
+ "syscall.SYS___DISABLE_THREADSIGNAL": "syscall",
+ "syscall.SYS___GETCWD": "syscall",
+ "syscall.SYS___GETLOGIN": "syscall",
+ "syscall.SYS___GET_TCB": "syscall",
+ "syscall.SYS___MAC_EXECVE": "syscall",
+ "syscall.SYS___MAC_GETFSSTAT": "syscall",
+ "syscall.SYS___MAC_GET_FD": "syscall",
+ "syscall.SYS___MAC_GET_FILE": "syscall",
+ "syscall.SYS___MAC_GET_LCID": "syscall",
+ "syscall.SYS___MAC_GET_LCTX": "syscall",
+ "syscall.SYS___MAC_GET_LINK": "syscall",
+ "syscall.SYS___MAC_GET_MOUNT": "syscall",
+ "syscall.SYS___MAC_GET_PID": "syscall",
+ "syscall.SYS___MAC_GET_PROC": "syscall",
+ "syscall.SYS___MAC_MOUNT": "syscall",
+ "syscall.SYS___MAC_SET_FD": "syscall",
+ "syscall.SYS___MAC_SET_FILE": "syscall",
+ "syscall.SYS___MAC_SET_LCTX": "syscall",
+ "syscall.SYS___MAC_SET_LINK": "syscall",
+ "syscall.SYS___MAC_SET_PROC": "syscall",
+ "syscall.SYS___MAC_SYSCALL": "syscall",
+ "syscall.SYS___OLD_SEMWAIT_SIGNAL": "syscall",
+ "syscall.SYS___OLD_SEMWAIT_SIGNAL_NOCANCEL": "syscall",
+ "syscall.SYS___POSIX_CHOWN": "syscall",
+ "syscall.SYS___POSIX_FCHOWN": "syscall",
+ "syscall.SYS___POSIX_LCHOWN": "syscall",
+ "syscall.SYS___POSIX_RENAME": "syscall",
+ "syscall.SYS___PTHREAD_CANCELED": "syscall",
+ "syscall.SYS___PTHREAD_CHDIR": "syscall",
+ "syscall.SYS___PTHREAD_FCHDIR": "syscall",
+ "syscall.SYS___PTHREAD_KILL": "syscall",
+ "syscall.SYS___PTHREAD_MARKCANCEL": "syscall",
+ "syscall.SYS___PTHREAD_SIGMASK": "syscall",
+ "syscall.SYS___QUOTACTL": "syscall",
+ "syscall.SYS___SEMCTL": "syscall",
+ "syscall.SYS___SEMWAIT_SIGNAL": "syscall",
+ "syscall.SYS___SEMWAIT_SIGNAL_NOCANCEL": "syscall",
+ "syscall.SYS___SETLOGIN": "syscall",
+ "syscall.SYS___SETUGID": "syscall",
+ "syscall.SYS___SET_TCB": "syscall",
+ "syscall.SYS___SIGACTION_SIGTRAMP": "syscall",
+ "syscall.SYS___SIGTIMEDWAIT": "syscall",
+ "syscall.SYS___SIGWAIT": "syscall",
+ "syscall.SYS___SIGWAIT_NOCANCEL": "syscall",
+ "syscall.SYS___SYSCTL": "syscall",
+ "syscall.SYS___TFORK": "syscall",
+ "syscall.SYS___THREXIT": "syscall",
+ "syscall.SYS___THRSIGDIVERT": "syscall",
+ "syscall.SYS___THRSLEEP": "syscall",
+ "syscall.SYS___THRWAKEUP": "syscall",
+ "syscall.S_ARCH1": "syscall",
+ "syscall.S_ARCH2": "syscall",
+ "syscall.S_BLKSIZE": "syscall",
+ "syscall.S_IEXEC": "syscall",
+ "syscall.S_IFBLK": "syscall",
+ "syscall.S_IFCHR": "syscall",
+ "syscall.S_IFDIR": "syscall",
+ "syscall.S_IFIFO": "syscall",
+ "syscall.S_IFLNK": "syscall",
+ "syscall.S_IFMT": "syscall",
+ "syscall.S_IFREG": "syscall",
+ "syscall.S_IFSOCK": "syscall",
+ "syscall.S_IFWHT": "syscall",
+ "syscall.S_IREAD": "syscall",
+ "syscall.S_IRGRP": "syscall",
+ "syscall.S_IROTH": "syscall",
+ "syscall.S_IRUSR": "syscall",
+ "syscall.S_IRWXG": "syscall",
+ "syscall.S_IRWXO": "syscall",
+ "syscall.S_IRWXU": "syscall",
+ "syscall.S_ISGID": "syscall",
+ "syscall.S_ISTXT": "syscall",
+ "syscall.S_ISUID": "syscall",
+ "syscall.S_ISVTX": "syscall",
+ "syscall.S_IWGRP": "syscall",
+ "syscall.S_IWOTH": "syscall",
+ "syscall.S_IWRITE": "syscall",
+ "syscall.S_IWUSR": "syscall",
+ "syscall.S_IXGRP": "syscall",
+ "syscall.S_IXOTH": "syscall",
+ "syscall.S_IXUSR": "syscall",
+ "syscall.S_LOGIN_SET": "syscall",
+ "syscall.SecurityAttributes": "syscall",
+ "syscall.Seek": "syscall",
+ "syscall.Select": "syscall",
+ "syscall.Sendfile": "syscall",
+ "syscall.Sendmsg": "syscall",
+ "syscall.SendmsgN": "syscall",
+ "syscall.Sendto": "syscall",
+ "syscall.Servent": "syscall",
+ "syscall.SetBpf": "syscall",
+ "syscall.SetBpfBuflen": "syscall",
+ "syscall.SetBpfDatalink": "syscall",
+ "syscall.SetBpfHeadercmpl": "syscall",
+ "syscall.SetBpfImmediate": "syscall",
+ "syscall.SetBpfInterface": "syscall",
+ "syscall.SetBpfPromisc": "syscall",
+ "syscall.SetBpfTimeout": "syscall",
+ "syscall.SetCurrentDirectory": "syscall",
+ "syscall.SetEndOfFile": "syscall",
+ "syscall.SetEnvironmentVariable": "syscall",
+ "syscall.SetFileAttributes": "syscall",
+ "syscall.SetFileCompletionNotificationModes": "syscall",
+ "syscall.SetFilePointer": "syscall",
+ "syscall.SetFileTime": "syscall",
+ "syscall.SetHandleInformation": "syscall",
+ "syscall.SetKevent": "syscall",
+ "syscall.SetLsfPromisc": "syscall",
+ "syscall.SetNonblock": "syscall",
+ "syscall.Setdomainname": "syscall",
+ "syscall.Setegid": "syscall",
+ "syscall.Setenv": "syscall",
+ "syscall.Seteuid": "syscall",
+ "syscall.Setfsgid": "syscall",
+ "syscall.Setfsuid": "syscall",
+ "syscall.Setgid": "syscall",
+ "syscall.Setgroups": "syscall",
+ "syscall.Sethostname": "syscall",
+ "syscall.Setlogin": "syscall",
+ "syscall.Setpgid": "syscall",
+ "syscall.Setpriority": "syscall",
+ "syscall.Setprivexec": "syscall",
+ "syscall.Setregid": "syscall",
+ "syscall.Setresgid": "syscall",
+ "syscall.Setresuid": "syscall",
+ "syscall.Setreuid": "syscall",
+ "syscall.Setrlimit": "syscall",
+ "syscall.Setsid": "syscall",
+ "syscall.Setsockopt": "syscall",
+ "syscall.SetsockoptByte": "syscall",
+ "syscall.SetsockoptICMPv6Filter": "syscall",
+ "syscall.SetsockoptIPMreq": "syscall",
+ "syscall.SetsockoptIPMreqn": "syscall",
+ "syscall.SetsockoptIPv6Mreq": "syscall",
+ "syscall.SetsockoptInet4Addr": "syscall",
+ "syscall.SetsockoptInt": "syscall",
+ "syscall.SetsockoptLinger": "syscall",
+ "syscall.SetsockoptString": "syscall",
+ "syscall.SetsockoptTimeval": "syscall",
+ "syscall.Settimeofday": "syscall",
+ "syscall.Setuid": "syscall",
+ "syscall.Setxattr": "syscall",
+ "syscall.Shutdown": "syscall",
+ "syscall.SidTypeAlias": "syscall",
+ "syscall.SidTypeComputer": "syscall",
+ "syscall.SidTypeDeletedAccount": "syscall",
+ "syscall.SidTypeDomain": "syscall",
+ "syscall.SidTypeGroup": "syscall",
+ "syscall.SidTypeInvalid": "syscall",
+ "syscall.SidTypeLabel": "syscall",
+ "syscall.SidTypeUnknown": "syscall",
+ "syscall.SidTypeUser": "syscall",
+ "syscall.SidTypeWellKnownGroup": "syscall",
+ "syscall.Signal": "syscall",
+ "syscall.SizeofBpfHdr": "syscall",
+ "syscall.SizeofBpfInsn": "syscall",
+ "syscall.SizeofBpfProgram": "syscall",
+ "syscall.SizeofBpfStat": "syscall",
+ "syscall.SizeofBpfVersion": "syscall",
+ "syscall.SizeofBpfZbuf": "syscall",
+ "syscall.SizeofBpfZbufHeader": "syscall",
+ "syscall.SizeofCmsghdr": "syscall",
+ "syscall.SizeofICMPv6Filter": "syscall",
+ "syscall.SizeofIPMreq": "syscall",
+ "syscall.SizeofIPMreqn": "syscall",
+ "syscall.SizeofIPv6MTUInfo": "syscall",
+ "syscall.SizeofIPv6Mreq": "syscall",
+ "syscall.SizeofIfAddrmsg": "syscall",
+ "syscall.SizeofIfAnnounceMsghdr": "syscall",
+ "syscall.SizeofIfData": "syscall",
+ "syscall.SizeofIfInfomsg": "syscall",
+ "syscall.SizeofIfMsghdr": "syscall",
+ "syscall.SizeofIfaMsghdr": "syscall",
+ "syscall.SizeofIfmaMsghdr": "syscall",
+ "syscall.SizeofIfmaMsghdr2": "syscall",
+ "syscall.SizeofInet4Pktinfo": "syscall",
+ "syscall.SizeofInet6Pktinfo": "syscall",
+ "syscall.SizeofInotifyEvent": "syscall",
+ "syscall.SizeofLinger": "syscall",
+ "syscall.SizeofMsghdr": "syscall",
+ "syscall.SizeofNlAttr": "syscall",
+ "syscall.SizeofNlMsgerr": "syscall",
+ "syscall.SizeofNlMsghdr": "syscall",
+ "syscall.SizeofRtAttr": "syscall",
+ "syscall.SizeofRtGenmsg": "syscall",
+ "syscall.SizeofRtMetrics": "syscall",
+ "syscall.SizeofRtMsg": "syscall",
+ "syscall.SizeofRtMsghdr": "syscall",
+ "syscall.SizeofRtNexthop": "syscall",
+ "syscall.SizeofSockFilter": "syscall",
+ "syscall.SizeofSockFprog": "syscall",
+ "syscall.SizeofSockaddrAny": "syscall",
+ "syscall.SizeofSockaddrDatalink": "syscall",
+ "syscall.SizeofSockaddrInet4": "syscall",
+ "syscall.SizeofSockaddrInet6": "syscall",
+ "syscall.SizeofSockaddrLinklayer": "syscall",
+ "syscall.SizeofSockaddrNetlink": "syscall",
+ "syscall.SizeofSockaddrUnix": "syscall",
+ "syscall.SizeofTCPInfo": "syscall",
+ "syscall.SizeofUcred": "syscall",
+ "syscall.SlicePtrFromStrings": "syscall",
+ "syscall.SockFilter": "syscall",
+ "syscall.SockFprog": "syscall",
+ "syscall.SockaddrDatalink": "syscall",
+ "syscall.SockaddrGen": "syscall",
+ "syscall.SockaddrInet4": "syscall",
+ "syscall.SockaddrInet6": "syscall",
+ "syscall.SockaddrLinklayer": "syscall",
+ "syscall.SockaddrNetlink": "syscall",
+ "syscall.SockaddrUnix": "syscall",
+ "syscall.Socket": "syscall",
+ "syscall.SocketControlMessage": "syscall",
+ "syscall.SocketDisableIPv6": "syscall",
+ "syscall.Socketpair": "syscall",
+ "syscall.Splice": "syscall",
+ "syscall.StartProcess": "syscall",
+ "syscall.StartupInfo": "syscall",
+ "syscall.Stat": "syscall",
+ "syscall.Stat_t": "syscall",
+ "syscall.Statfs": "syscall",
+ "syscall.Statfs_t": "syscall",
+ "syscall.Stderr": "syscall",
+ "syscall.Stdin": "syscall",
+ "syscall.Stdout": "syscall",
+ "syscall.StringBytePtr": "syscall",
+ "syscall.StringByteSlice": "syscall",
+ "syscall.StringSlicePtr": "syscall",
+ "syscall.StringToSid": "syscall",
+ "syscall.StringToUTF16": "syscall",
+ "syscall.StringToUTF16Ptr": "syscall",
+ "syscall.Symlink": "syscall",
+ "syscall.Sync": "syscall",
+ "syscall.SyncFileRange": "syscall",
+ "syscall.SysProcAttr": "syscall",
+ "syscall.Syscall": "syscall",
+ "syscall.Syscall12": "syscall",
+ "syscall.Syscall15": "syscall",
+ "syscall.Syscall6": "syscall",
+ "syscall.Syscall9": "syscall",
+ "syscall.Sysctl": "syscall",
+ "syscall.SysctlUint32": "syscall",
+ "syscall.Sysctlnode": "syscall",
+ "syscall.Sysinfo": "syscall",
+ "syscall.Sysinfo_t": "syscall",
+ "syscall.Systemtime": "syscall",
+ "syscall.TCGETS": "syscall",
+ "syscall.TCIFLUSH": "syscall",
+ "syscall.TCIOFLUSH": "syscall",
+ "syscall.TCOFLUSH": "syscall",
+ "syscall.TCPInfo": "syscall",
+ "syscall.TCPKeepalive": "syscall",
+ "syscall.TCP_CA_NAME_MAX": "syscall",
+ "syscall.TCP_CONGCTL": "syscall",
+ "syscall.TCP_CONGESTION": "syscall",
+ "syscall.TCP_CONNECTIONTIMEOUT": "syscall",
+ "syscall.TCP_CORK": "syscall",
+ "syscall.TCP_DEFER_ACCEPT": "syscall",
+ "syscall.TCP_INFO": "syscall",
+ "syscall.TCP_KEEPALIVE": "syscall",
+ "syscall.TCP_KEEPCNT": "syscall",
+ "syscall.TCP_KEEPIDLE": "syscall",
+ "syscall.TCP_KEEPINIT": "syscall",
+ "syscall.TCP_KEEPINTVL": "syscall",
+ "syscall.TCP_LINGER2": "syscall",
+ "syscall.TCP_MAXBURST": "syscall",
+ "syscall.TCP_MAXHLEN": "syscall",
+ "syscall.TCP_MAXOLEN": "syscall",
+ "syscall.TCP_MAXSEG": "syscall",
+ "syscall.TCP_MAXWIN": "syscall",
+ "syscall.TCP_MAX_SACK": "syscall",
+ "syscall.TCP_MAX_WINSHIFT": "syscall",
+ "syscall.TCP_MD5SIG": "syscall",
+ "syscall.TCP_MD5SIG_MAXKEYLEN": "syscall",
+ "syscall.TCP_MINMSS": "syscall",
+ "syscall.TCP_MINMSSOVERLOAD": "syscall",
+ "syscall.TCP_MSS": "syscall",
+ "syscall.TCP_NODELAY": "syscall",
+ "syscall.TCP_NOOPT": "syscall",
+ "syscall.TCP_NOPUSH": "syscall",
+ "syscall.TCP_NSTATES": "syscall",
+ "syscall.TCP_QUICKACK": "syscall",
+ "syscall.TCP_RXT_CONNDROPTIME": "syscall",
+ "syscall.TCP_RXT_FINDROP": "syscall",
+ "syscall.TCP_SACK_ENABLE": "syscall",
+ "syscall.TCP_SYNCNT": "syscall",
+ "syscall.TCP_VENDOR": "syscall",
+ "syscall.TCP_WINDOW_CLAMP": "syscall",
+ "syscall.TCSAFLUSH": "syscall",
+ "syscall.TCSETS": "syscall",
+ "syscall.TF_DISCONNECT": "syscall",
+ "syscall.TF_REUSE_SOCKET": "syscall",
+ "syscall.TF_USE_DEFAULT_WORKER": "syscall",
+ "syscall.TF_USE_KERNEL_APC": "syscall",
+ "syscall.TF_USE_SYSTEM_THREAD": "syscall",
+ "syscall.TF_WRITE_BEHIND": "syscall",
+ "syscall.TIME_ZONE_ID_DAYLIGHT": "syscall",
+ "syscall.TIME_ZONE_ID_STANDARD": "syscall",
+ "syscall.TIME_ZONE_ID_UNKNOWN": "syscall",
+ "syscall.TIOCCBRK": "syscall",
+ "syscall.TIOCCDTR": "syscall",
+ "syscall.TIOCCONS": "syscall",
+ "syscall.TIOCDCDTIMESTAMP": "syscall",
+ "syscall.TIOCDRAIN": "syscall",
+ "syscall.TIOCDSIMICROCODE": "syscall",
+ "syscall.TIOCEXCL": "syscall",
+ "syscall.TIOCEXT": "syscall",
+ "syscall.TIOCFLAG_CDTRCTS": "syscall",
+ "syscall.TIOCFLAG_CLOCAL": "syscall",
+ "syscall.TIOCFLAG_CRTSCTS": "syscall",
+ "syscall.TIOCFLAG_MDMBUF": "syscall",
+ "syscall.TIOCFLAG_PPS": "syscall",
+ "syscall.TIOCFLAG_SOFTCAR": "syscall",
+ "syscall.TIOCFLUSH": "syscall",
+ "syscall.TIOCGDEV": "syscall",
+ "syscall.TIOCGDRAINWAIT": "syscall",
+ "syscall.TIOCGETA": "syscall",
+ "syscall.TIOCGETD": "syscall",
+ "syscall.TIOCGFLAGS": "syscall",
+ "syscall.TIOCGICOUNT": "syscall",
+ "syscall.TIOCGLCKTRMIOS": "syscall",
+ "syscall.TIOCGLINED": "syscall",
+ "syscall.TIOCGPGRP": "syscall",
+ "syscall.TIOCGPTN": "syscall",
+ "syscall.TIOCGQSIZE": "syscall",
+ "syscall.TIOCGRANTPT": "syscall",
+ "syscall.TIOCGRS485": "syscall",
+ "syscall.TIOCGSERIAL": "syscall",
+ "syscall.TIOCGSID": "syscall",
+ "syscall.TIOCGSIZE": "syscall",
+ "syscall.TIOCGSOFTCAR": "syscall",
+ "syscall.TIOCGTSTAMP": "syscall",
+ "syscall.TIOCGWINSZ": "syscall",
+ "syscall.TIOCINQ": "syscall",
+ "syscall.TIOCIXOFF": "syscall",
+ "syscall.TIOCIXON": "syscall",
+ "syscall.TIOCLINUX": "syscall",
+ "syscall.TIOCMBIC": "syscall",
+ "syscall.TIOCMBIS": "syscall",
+ "syscall.TIOCMGDTRWAIT": "syscall",
+ "syscall.TIOCMGET": "syscall",
+ "syscall.TIOCMIWAIT": "syscall",
+ "syscall.TIOCMODG": "syscall",
+ "syscall.TIOCMODS": "syscall",
+ "syscall.TIOCMSDTRWAIT": "syscall",
+ "syscall.TIOCMSET": "syscall",
+ "syscall.TIOCM_CAR": "syscall",
+ "syscall.TIOCM_CD": "syscall",
+ "syscall.TIOCM_CTS": "syscall",
+ "syscall.TIOCM_DCD": "syscall",
+ "syscall.TIOCM_DSR": "syscall",
+ "syscall.TIOCM_DTR": "syscall",
+ "syscall.TIOCM_LE": "syscall",
+ "syscall.TIOCM_RI": "syscall",
+ "syscall.TIOCM_RNG": "syscall",
+ "syscall.TIOCM_RTS": "syscall",
+ "syscall.TIOCM_SR": "syscall",
+ "syscall.TIOCM_ST": "syscall",
+ "syscall.TIOCNOTTY": "syscall",
+ "syscall.TIOCNXCL": "syscall",
+ "syscall.TIOCOUTQ": "syscall",
+ "syscall.TIOCPKT": "syscall",
+ "syscall.TIOCPKT_DATA": "syscall",
+ "syscall.TIOCPKT_DOSTOP": "syscall",
+ "syscall.TIOCPKT_FLUSHREAD": "syscall",
+ "syscall.TIOCPKT_FLUSHWRITE": "syscall",
+ "syscall.TIOCPKT_IOCTL": "syscall",
+ "syscall.TIOCPKT_NOSTOP": "syscall",
+ "syscall.TIOCPKT_START": "syscall",
+ "syscall.TIOCPKT_STOP": "syscall",
+ "syscall.TIOCPTMASTER": "syscall",
+ "syscall.TIOCPTMGET": "syscall",
+ "syscall.TIOCPTSNAME": "syscall",
+ "syscall.TIOCPTYGNAME": "syscall",
+ "syscall.TIOCPTYGRANT": "syscall",
+ "syscall.TIOCPTYUNLK": "syscall",
+ "syscall.TIOCRCVFRAME": "syscall",
+ "syscall.TIOCREMOTE": "syscall",
+ "syscall.TIOCSBRK": "syscall",
+ "syscall.TIOCSCONS": "syscall",
+ "syscall.TIOCSCTTY": "syscall",
+ "syscall.TIOCSDRAINWAIT": "syscall",
+ "syscall.TIOCSDTR": "syscall",
+ "syscall.TIOCSERCONFIG": "syscall",
+ "syscall.TIOCSERGETLSR": "syscall",
+ "syscall.TIOCSERGETMULTI": "syscall",
+ "syscall.TIOCSERGSTRUCT": "syscall",
+ "syscall.TIOCSERGWILD": "syscall",
+ "syscall.TIOCSERSETMULTI": "syscall",
+ "syscall.TIOCSERSWILD": "syscall",
+ "syscall.TIOCSER_TEMT": "syscall",
+ "syscall.TIOCSETA": "syscall",
+ "syscall.TIOCSETAF": "syscall",
+ "syscall.TIOCSETAW": "syscall",
+ "syscall.TIOCSETD": "syscall",
+ "syscall.TIOCSFLAGS": "syscall",
+ "syscall.TIOCSIG": "syscall",
+ "syscall.TIOCSLCKTRMIOS": "syscall",
+ "syscall.TIOCSLINED": "syscall",
+ "syscall.TIOCSPGRP": "syscall",
+ "syscall.TIOCSPTLCK": "syscall",
+ "syscall.TIOCSQSIZE": "syscall",
+ "syscall.TIOCSRS485": "syscall",
+ "syscall.TIOCSSERIAL": "syscall",
+ "syscall.TIOCSSIZE": "syscall",
+ "syscall.TIOCSSOFTCAR": "syscall",
+ "syscall.TIOCSTART": "syscall",
+ "syscall.TIOCSTAT": "syscall",
+ "syscall.TIOCSTI": "syscall",
+ "syscall.TIOCSTOP": "syscall",
+ "syscall.TIOCSTSTAMP": "syscall",
+ "syscall.TIOCSWINSZ": "syscall",
+ "syscall.TIOCTIMESTAMP": "syscall",
+ "syscall.TIOCUCNTL": "syscall",
+ "syscall.TIOCVHANGUP": "syscall",
+ "syscall.TIOCXMTFRAME": "syscall",
+ "syscall.TOKEN_ADJUST_DEFAULT": "syscall",
+ "syscall.TOKEN_ADJUST_GROUPS": "syscall",
+ "syscall.TOKEN_ADJUST_PRIVILEGES": "syscall",
+ "syscall.TOKEN_ALL_ACCESS": "syscall",
+ "syscall.TOKEN_ASSIGN_PRIMARY": "syscall",
+ "syscall.TOKEN_DUPLICATE": "syscall",
+ "syscall.TOKEN_EXECUTE": "syscall",
+ "syscall.TOKEN_IMPERSONATE": "syscall",
+ "syscall.TOKEN_QUERY": "syscall",
+ "syscall.TOKEN_QUERY_SOURCE": "syscall",
+ "syscall.TOKEN_READ": "syscall",
+ "syscall.TOKEN_WRITE": "syscall",
+ "syscall.TOSTOP": "syscall",
+ "syscall.TRUNCATE_EXISTING": "syscall",
+ "syscall.TUNATTACHFILTER": "syscall",
+ "syscall.TUNDETACHFILTER": "syscall",
+ "syscall.TUNGETFEATURES": "syscall",
+ "syscall.TUNGETIFF": "syscall",
+ "syscall.TUNGETSNDBUF": "syscall",
+ "syscall.TUNGETVNETHDRSZ": "syscall",
+ "syscall.TUNSETDEBUG": "syscall",
+ "syscall.TUNSETGROUP": "syscall",
+ "syscall.TUNSETIFF": "syscall",
+ "syscall.TUNSETLINK": "syscall",
+ "syscall.TUNSETNOCSUM": "syscall",
+ "syscall.TUNSETOFFLOAD": "syscall",
+ "syscall.TUNSETOWNER": "syscall",
+ "syscall.TUNSETPERSIST": "syscall",
+ "syscall.TUNSETSNDBUF": "syscall",
+ "syscall.TUNSETTXFILTER": "syscall",
+ "syscall.TUNSETVNETHDRSZ": "syscall",
+ "syscall.Tee": "syscall",
+ "syscall.TerminateProcess": "syscall",
+ "syscall.Termios": "syscall",
+ "syscall.Tgkill": "syscall",
+ "syscall.Time": "syscall",
+ "syscall.Time_t": "syscall",
+ "syscall.Times": "syscall",
+ "syscall.Timespec": "syscall",
+ "syscall.TimespecToNsec": "syscall",
+ "syscall.Timeval": "syscall",
+ "syscall.Timeval32": "syscall",
+ "syscall.TimevalToNsec": "syscall",
+ "syscall.Timex": "syscall",
+ "syscall.Timezoneinformation": "syscall",
+ "syscall.Tms": "syscall",
+ "syscall.Token": "syscall",
+ "syscall.TokenAccessInformation": "syscall",
+ "syscall.TokenAuditPolicy": "syscall",
+ "syscall.TokenDefaultDacl": "syscall",
+ "syscall.TokenElevation": "syscall",
+ "syscall.TokenElevationType": "syscall",
+ "syscall.TokenGroups": "syscall",
+ "syscall.TokenGroupsAndPrivileges": "syscall",
+ "syscall.TokenHasRestrictions": "syscall",
+ "syscall.TokenImpersonationLevel": "syscall",
+ "syscall.TokenIntegrityLevel": "syscall",
+ "syscall.TokenLinkedToken": "syscall",
+ "syscall.TokenLogonSid": "syscall",
+ "syscall.TokenMandatoryPolicy": "syscall",
+ "syscall.TokenOrigin": "syscall",
+ "syscall.TokenOwner": "syscall",
+ "syscall.TokenPrimaryGroup": "syscall",
+ "syscall.TokenPrivileges": "syscall",
+ "syscall.TokenRestrictedSids": "syscall",
+ "syscall.TokenSandBoxInert": "syscall",
+ "syscall.TokenSessionId": "syscall",
+ "syscall.TokenSessionReference": "syscall",
+ "syscall.TokenSource": "syscall",
+ "syscall.TokenStatistics": "syscall",
+ "syscall.TokenType": "syscall",
+ "syscall.TokenUIAccess": "syscall",
+ "syscall.TokenUser": "syscall",
+ "syscall.TokenVirtualizationAllowed": "syscall",
+ "syscall.TokenVirtualizationEnabled": "syscall",
+ "syscall.Tokenprimarygroup": "syscall",
+ "syscall.Tokenuser": "syscall",
+ "syscall.TranslateAccountName": "syscall",
+ "syscall.TranslateName": "syscall",
+ "syscall.TransmitFile": "syscall",
+ "syscall.TransmitFileBuffers": "syscall",
+ "syscall.Truncate": "syscall",
+ "syscall.USAGE_MATCH_TYPE_AND": "syscall",
+ "syscall.USAGE_MATCH_TYPE_OR": "syscall",
+ "syscall.UTF16FromString": "syscall",
+ "syscall.UTF16PtrFromString": "syscall",
+ "syscall.UTF16ToString": "syscall",
+ "syscall.Ucred": "syscall",
+ "syscall.Umask": "syscall",
+ "syscall.Uname": "syscall",
+ "syscall.Undelete": "syscall",
+ "syscall.UnixCredentials": "syscall",
+ "syscall.UnixRights": "syscall",
+ "syscall.Unlink": "syscall",
+ "syscall.Unlinkat": "syscall",
+ "syscall.UnmapViewOfFile": "syscall",
+ "syscall.Unmount": "syscall",
+ "syscall.Unshare": "syscall",
+ "syscall.UserInfo10": "syscall",
+ "syscall.Ustat": "syscall",
+ "syscall.Ustat_t": "syscall",
+ "syscall.Utimbuf": "syscall",
+ "syscall.Utime": "syscall",
+ "syscall.Utimes": "syscall",
+ "syscall.UtimesNano": "syscall",
+ "syscall.Utsname": "syscall",
+ "syscall.VDISCARD": "syscall",
+ "syscall.VDSUSP": "syscall",
+ "syscall.VEOF": "syscall",
+ "syscall.VEOL": "syscall",
+ "syscall.VEOL2": "syscall",
+ "syscall.VERASE": "syscall",
+ "syscall.VERASE2": "syscall",
+ "syscall.VINTR": "syscall",
+ "syscall.VKILL": "syscall",
+ "syscall.VLNEXT": "syscall",
+ "syscall.VMIN": "syscall",
+ "syscall.VQUIT": "syscall",
+ "syscall.VREPRINT": "syscall",
+ "syscall.VSTART": "syscall",
+ "syscall.VSTATUS": "syscall",
+ "syscall.VSTOP": "syscall",
+ "syscall.VSUSP": "syscall",
+ "syscall.VSWTC": "syscall",
+ "syscall.VT0": "syscall",
+ "syscall.VT1": "syscall",
+ "syscall.VTDLY": "syscall",
+ "syscall.VTIME": "syscall",
+ "syscall.VWERASE": "syscall",
+ "syscall.VirtualLock": "syscall",
+ "syscall.VirtualUnlock": "syscall",
+ "syscall.WAIT_ABANDONED": "syscall",
+ "syscall.WAIT_FAILED": "syscall",
+ "syscall.WAIT_OBJECT_0": "syscall",
+ "syscall.WAIT_TIMEOUT": "syscall",
+ "syscall.WALL": "syscall",
+ "syscall.WALLSIG": "syscall",
+ "syscall.WALTSIG": "syscall",
+ "syscall.WCLONE": "syscall",
+ "syscall.WCONTINUED": "syscall",
+ "syscall.WCOREFLAG": "syscall",
+ "syscall.WEXITED": "syscall",
+ "syscall.WLINUXCLONE": "syscall",
+ "syscall.WNOHANG": "syscall",
+ "syscall.WNOTHREAD": "syscall",
+ "syscall.WNOWAIT": "syscall",
+ "syscall.WNOZOMBIE": "syscall",
+ "syscall.WOPTSCHECKED": "syscall",
+ "syscall.WORDSIZE": "syscall",
+ "syscall.WSABuf": "syscall",
+ "syscall.WSACleanup": "syscall",
+ "syscall.WSADESCRIPTION_LEN": "syscall",
+ "syscall.WSAData": "syscall",
+ "syscall.WSAEACCES": "syscall",
+ "syscall.WSAECONNRESET": "syscall",
+ "syscall.WSAEnumProtocols": "syscall",
+ "syscall.WSAID_CONNECTEX": "syscall",
+ "syscall.WSAIoctl": "syscall",
+ "syscall.WSAPROTOCOL_LEN": "syscall",
+ "syscall.WSAProtocolChain": "syscall",
+ "syscall.WSAProtocolInfo": "syscall",
+ "syscall.WSARecv": "syscall",
+ "syscall.WSARecvFrom": "syscall",
+ "syscall.WSASYS_STATUS_LEN": "syscall",
+ "syscall.WSASend": "syscall",
+ "syscall.WSASendTo": "syscall",
+ "syscall.WSASendto": "syscall",
+ "syscall.WSAStartup": "syscall",
+ "syscall.WSTOPPED": "syscall",
+ "syscall.WTRAPPED": "syscall",
+ "syscall.WUNTRACED": "syscall",
+ "syscall.Wait4": "syscall",
+ "syscall.WaitForSingleObject": "syscall",
+ "syscall.WaitStatus": "syscall",
+ "syscall.Win32FileAttributeData": "syscall",
+ "syscall.Win32finddata": "syscall",
+ "syscall.Write": "syscall",
+ "syscall.WriteConsole": "syscall",
+ "syscall.WriteFile": "syscall",
+ "syscall.X509_ASN_ENCODING": "syscall",
+ "syscall.XCASE": "syscall",
+ "syscall.XP1_CONNECTIONLESS": "syscall",
+ "syscall.XP1_CONNECT_DATA": "syscall",
+ "syscall.XP1_DISCONNECT_DATA": "syscall",
+ "syscall.XP1_EXPEDITED_DATA": "syscall",
+ "syscall.XP1_GRACEFUL_CLOSE": "syscall",
+ "syscall.XP1_GUARANTEED_DELIVERY": "syscall",
+ "syscall.XP1_GUARANTEED_ORDER": "syscall",
+ "syscall.XP1_IFS_HANDLES": "syscall",
+ "syscall.XP1_MESSAGE_ORIENTED": "syscall",
+ "syscall.XP1_MULTIPOINT_CONTROL_PLANE": "syscall",
+ "syscall.XP1_MULTIPOINT_DATA_PLANE": "syscall",
+ "syscall.XP1_PARTIAL_MESSAGE": "syscall",
+ "syscall.XP1_PSEUDO_STREAM": "syscall",
+ "syscall.XP1_QOS_SUPPORTED": "syscall",
+ "syscall.XP1_SAN_SUPPORT_SDP": "syscall",
+ "syscall.XP1_SUPPORT_BROADCAST": "syscall",
+ "syscall.XP1_SUPPORT_MULTIPOINT": "syscall",
+ "syscall.XP1_UNI_RECV": "syscall",
+ "syscall.XP1_UNI_SEND": "syscall",
+ "syslog.Dial": "log/syslog",
+ "syslog.LOG_ALERT": "log/syslog",
+ "syslog.LOG_AUTH": "log/syslog",
+ "syslog.LOG_AUTHPRIV": "log/syslog",
+ "syslog.LOG_CRIT": "log/syslog",
+ "syslog.LOG_CRON": "log/syslog",
+ "syslog.LOG_DAEMON": "log/syslog",
+ "syslog.LOG_DEBUG": "log/syslog",
+ "syslog.LOG_EMERG": "log/syslog",
+ "syslog.LOG_ERR": "log/syslog",
+ "syslog.LOG_FTP": "log/syslog",
+ "syslog.LOG_INFO": "log/syslog",
+ "syslog.LOG_KERN": "log/syslog",
+ "syslog.LOG_LOCAL0": "log/syslog",
+ "syslog.LOG_LOCAL1": "log/syslog",
+ "syslog.LOG_LOCAL2": "log/syslog",
+ "syslog.LOG_LOCAL3": "log/syslog",
+ "syslog.LOG_LOCAL4": "log/syslog",
+ "syslog.LOG_LOCAL5": "log/syslog",
+ "syslog.LOG_LOCAL6": "log/syslog",
+ "syslog.LOG_LOCAL7": "log/syslog",
+ "syslog.LOG_LPR": "log/syslog",
+ "syslog.LOG_MAIL": "log/syslog",
+ "syslog.LOG_NEWS": "log/syslog",
+ "syslog.LOG_NOTICE": "log/syslog",
+ "syslog.LOG_SYSLOG": "log/syslog",
+ "syslog.LOG_USER": "log/syslog",
+ "syslog.LOG_UUCP": "log/syslog",
+ "syslog.LOG_WARNING": "log/syslog",
+ "syslog.New": "log/syslog",
+ "syslog.NewLogger": "log/syslog",
+ "syslog.Priority": "log/syslog",
+ "syslog.Writer": "log/syslog",
+ "tabwriter.AlignRight": "text/tabwriter",
+ "tabwriter.Debug": "text/tabwriter",
+ "tabwriter.DiscardEmptyColumns": "text/tabwriter",
+ "tabwriter.Escape": "text/tabwriter",
+ "tabwriter.FilterHTML": "text/tabwriter",
+ "tabwriter.NewWriter": "text/tabwriter",
+ "tabwriter.StripEscape": "text/tabwriter",
+ "tabwriter.TabIndent": "text/tabwriter",
+ "tabwriter.Writer": "text/tabwriter",
+ "tar.ErrFieldTooLong": "archive/tar",
+ "tar.ErrHeader": "archive/tar",
+ "tar.ErrWriteAfterClose": "archive/tar",
+ "tar.ErrWriteTooLong": "archive/tar",
+ "tar.FileInfoHeader": "archive/tar",
+ "tar.Header": "archive/tar",
+ "tar.NewReader": "archive/tar",
+ "tar.NewWriter": "archive/tar",
+ "tar.Reader": "archive/tar",
+ "tar.TypeBlock": "archive/tar",
+ "tar.TypeChar": "archive/tar",
+ "tar.TypeCont": "archive/tar",
+ "tar.TypeDir": "archive/tar",
+ "tar.TypeFifo": "archive/tar",
+ "tar.TypeGNULongLink": "archive/tar",
+ "tar.TypeGNULongName": "archive/tar",
+ "tar.TypeGNUSparse": "archive/tar",
+ "tar.TypeLink": "archive/tar",
+ "tar.TypeReg": "archive/tar",
+ "tar.TypeRegA": "archive/tar",
+ "tar.TypeSymlink": "archive/tar",
+ "tar.TypeXGlobalHeader": "archive/tar",
+ "tar.TypeXHeader": "archive/tar",
+ "tar.Writer": "archive/tar",
+ "template.CSS": "html/template",
+ "template.ErrAmbigContext": "html/template",
+ "template.ErrBadHTML": "html/template",
+ "template.ErrBranchEnd": "html/template",
+ "template.ErrEndContext": "html/template",
+ "template.ErrNoSuchTemplate": "html/template",
+ "template.ErrOutputContext": "html/template",
+ "template.ErrPartialCharset": "html/template",
+ "template.ErrPartialEscape": "html/template",
+ "template.ErrRangeLoopReentry": "html/template",
+ "template.ErrSlashAmbig": "html/template",
+ "template.Error": "html/template",
+ "template.ErrorCode": "html/template",
+ // "template.FuncMap" is ambiguous
+ "template.HTML": "html/template",
+ "template.HTMLAttr": "html/template",
+ // "template.HTMLEscape" is ambiguous
+ // "template.HTMLEscapeString" is ambiguous
+ // "template.HTMLEscaper" is ambiguous
+ "template.JS": "html/template",
+ // "template.JSEscape" is ambiguous
+ // "template.JSEscapeString" is ambiguous
+ // "template.JSEscaper" is ambiguous
+ "template.JSStr": "html/template",
+ // "template.Must" is ambiguous
+ // "template.New" is ambiguous
+ "template.OK": "html/template",
+ // "template.ParseFiles" is ambiguous
+ // "template.ParseGlob" is ambiguous
+ // "template.Template" is ambiguous
+ "template.URL": "html/template",
+ // "template.URLQueryEscaper" is ambiguous
+ "testing.AllocsPerRun": "testing",
+ "testing.B": "testing",
+ "testing.Benchmark": "testing",
+ "testing.BenchmarkResult": "testing",
+ "testing.Cover": "testing",
+ "testing.CoverBlock": "testing",
+ "testing.InternalBenchmark": "testing",
+ "testing.InternalExample": "testing",
+ "testing.InternalTest": "testing",
+ "testing.Main": "testing",
+ "testing.PB": "testing",
+ "testing.RegisterCover": "testing",
+ "testing.RunBenchmarks": "testing",
+ "testing.RunExamples": "testing",
+ "testing.RunTests": "testing",
+ "testing.Short": "testing",
+ "testing.T": "testing",
+ "testing.Verbose": "testing",
+ "textproto.CanonicalMIMEHeaderKey": "net/textproto",
+ "textproto.Conn": "net/textproto",
+ "textproto.Dial": "net/textproto",
+ "textproto.Error": "net/textproto",
+ "textproto.MIMEHeader": "net/textproto",
+ "textproto.NewConn": "net/textproto",
+ "textproto.NewReader": "net/textproto",
+ "textproto.NewWriter": "net/textproto",
+ "textproto.Pipeline": "net/textproto",
+ "textproto.ProtocolError": "net/textproto",
+ "textproto.Reader": "net/textproto",
+ "textproto.TrimBytes": "net/textproto",
+ "textproto.TrimString": "net/textproto",
+ "textproto.Writer": "net/textproto",
+ "time.ANSIC": "time",
+ "time.After": "time",
+ "time.AfterFunc": "time",
+ "time.April": "time",
+ "time.August": "time",
+ "time.Date": "time",
+ "time.December": "time",
+ "time.Duration": "time",
+ "time.February": "time",
+ "time.FixedZone": "time",
+ "time.Friday": "time",
+ "time.Hour": "time",
+ "time.January": "time",
+ "time.July": "time",
+ "time.June": "time",
+ "time.Kitchen": "time",
+ "time.LoadLocation": "time",
+ "time.Local": "time",
+ "time.Location": "time",
+ "time.March": "time",
+ "time.May": "time",
+ "time.Microsecond": "time",
+ "time.Millisecond": "time",
+ "time.Minute": "time",
+ "time.Monday": "time",
+ "time.Month": "time",
+ "time.Nanosecond": "time",
+ "time.NewTicker": "time",
+ "time.NewTimer": "time",
+ "time.November": "time",
+ "time.Now": "time",
+ "time.October": "time",
+ "time.Parse": "time",
+ "time.ParseDuration": "time",
+ "time.ParseError": "time",
+ "time.ParseInLocation": "time",
+ "time.RFC1123": "time",
+ "time.RFC1123Z": "time",
+ "time.RFC3339": "time",
+ "time.RFC3339Nano": "time",
+ "time.RFC822": "time",
+ "time.RFC822Z": "time",
+ "time.RFC850": "time",
+ "time.RubyDate": "time",
+ "time.Saturday": "time",
+ "time.Second": "time",
+ "time.September": "time",
+ "time.Since": "time",
+ "time.Sleep": "time",
+ "time.Stamp": "time",
+ "time.StampMicro": "time",
+ "time.StampMilli": "time",
+ "time.StampNano": "time",
+ "time.Sunday": "time",
+ "time.Thursday": "time",
+ "time.Tick": "time",
+ "time.Ticker": "time",
+ "time.Time": "time",
+ "time.Timer": "time",
+ "time.Tuesday": "time",
+ "time.UTC": "time",
+ "time.Unix": "time",
+ "time.UnixDate": "time",
+ "time.Wednesday": "time",
+ "time.Weekday": "time",
+ "tls.Certificate": "crypto/tls",
+ "tls.Client": "crypto/tls",
+ "tls.ClientAuthType": "crypto/tls",
+ "tls.ClientSessionCache": "crypto/tls",
+ "tls.ClientSessionState": "crypto/tls",
+ "tls.Config": "crypto/tls",
+ "tls.Conn": "crypto/tls",
+ "tls.ConnectionState": "crypto/tls",
+ "tls.CurveID": "crypto/tls",
+ "tls.CurveP256": "crypto/tls",
+ "tls.CurveP384": "crypto/tls",
+ "tls.CurveP521": "crypto/tls",
+ "tls.Dial": "crypto/tls",
+ "tls.DialWithDialer": "crypto/tls",
+ "tls.Listen": "crypto/tls",
+ "tls.LoadX509KeyPair": "crypto/tls",
+ "tls.NewLRUClientSessionCache": "crypto/tls",
+ "tls.NewListener": "crypto/tls",
+ "tls.NoClientCert": "crypto/tls",
+ "tls.RequestClientCert": "crypto/tls",
+ "tls.RequireAndVerifyClientCert": "crypto/tls",
+ "tls.RequireAnyClientCert": "crypto/tls",
+ "tls.Server": "crypto/tls",
+ "tls.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA": "crypto/tls",
+ "tls.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256": "crypto/tls",
+ "tls.TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA": "crypto/tls",
+ "tls.TLS_ECDHE_ECDSA_WITH_RC4_128_SHA": "crypto/tls",
+ "tls.TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA": "crypto/tls",
+ "tls.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA": "crypto/tls",
+ "tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256": "crypto/tls",
+ "tls.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA": "crypto/tls",
+ "tls.TLS_ECDHE_RSA_WITH_RC4_128_SHA": "crypto/tls",
+ "tls.TLS_RSA_WITH_3DES_EDE_CBC_SHA": "crypto/tls",
+ "tls.TLS_RSA_WITH_AES_128_CBC_SHA": "crypto/tls",
+ "tls.TLS_RSA_WITH_AES_256_CBC_SHA": "crypto/tls",
+ "tls.TLS_RSA_WITH_RC4_128_SHA": "crypto/tls",
+ "tls.VerifyClientCertIfGiven": "crypto/tls",
+ "tls.VersionSSL30": "crypto/tls",
+ "tls.VersionTLS10": "crypto/tls",
+ "tls.VersionTLS11": "crypto/tls",
+ "tls.VersionTLS12": "crypto/tls",
+ "tls.X509KeyPair": "crypto/tls",
+ "token.ADD": "go/token",
+ "token.ADD_ASSIGN": "go/token",
+ "token.AND": "go/token",
+ "token.AND_ASSIGN": "go/token",
+ "token.AND_NOT": "go/token",
+ "token.AND_NOT_ASSIGN": "go/token",
+ "token.ARROW": "go/token",
+ "token.ASSIGN": "go/token",
+ "token.BREAK": "go/token",
+ "token.CASE": "go/token",
+ "token.CHAN": "go/token",
+ "token.CHAR": "go/token",
+ "token.COLON": "go/token",
+ "token.COMMA": "go/token",
+ "token.COMMENT": "go/token",
+ "token.CONST": "go/token",
+ "token.CONTINUE": "go/token",
+ "token.DEC": "go/token",
+ "token.DEFAULT": "go/token",
+ "token.DEFER": "go/token",
+ "token.DEFINE": "go/token",
+ "token.ELLIPSIS": "go/token",
+ "token.ELSE": "go/token",
+ "token.EOF": "go/token",
+ "token.EQL": "go/token",
+ "token.FALLTHROUGH": "go/token",
+ "token.FLOAT": "go/token",
+ "token.FOR": "go/token",
+ "token.FUNC": "go/token",
+ "token.File": "go/token",
+ "token.FileSet": "go/token",
+ "token.GEQ": "go/token",
+ "token.GO": "go/token",
+ "token.GOTO": "go/token",
+ "token.GTR": "go/token",
+ "token.HighestPrec": "go/token",
+ "token.IDENT": "go/token",
+ "token.IF": "go/token",
+ "token.ILLEGAL": "go/token",
+ "token.IMAG": "go/token",
+ "token.IMPORT": "go/token",
+ "token.INC": "go/token",
+ "token.INT": "go/token",
+ "token.INTERFACE": "go/token",
+ "token.LAND": "go/token",
+ "token.LBRACE": "go/token",
+ "token.LBRACK": "go/token",
+ "token.LEQ": "go/token",
+ "token.LOR": "go/token",
+ "token.LPAREN": "go/token",
+ "token.LSS": "go/token",
+ "token.Lookup": "go/token",
+ "token.LowestPrec": "go/token",
+ "token.MAP": "go/token",
+ "token.MUL": "go/token",
+ "token.MUL_ASSIGN": "go/token",
+ "token.NEQ": "go/token",
+ "token.NOT": "go/token",
+ "token.NewFileSet": "go/token",
+ "token.NoPos": "go/token",
+ "token.OR": "go/token",
+ "token.OR_ASSIGN": "go/token",
+ "token.PACKAGE": "go/token",
+ "token.PERIOD": "go/token",
+ "token.Pos": "go/token",
+ "token.Position": "go/token",
+ "token.QUO": "go/token",
+ "token.QUO_ASSIGN": "go/token",
+ "token.RANGE": "go/token",
+ "token.RBRACE": "go/token",
+ "token.RBRACK": "go/token",
+ "token.REM": "go/token",
+ "token.REM_ASSIGN": "go/token",
+ "token.RETURN": "go/token",
+ "token.RPAREN": "go/token",
+ "token.SELECT": "go/token",
+ "token.SEMICOLON": "go/token",
+ "token.SHL": "go/token",
+ "token.SHL_ASSIGN": "go/token",
+ "token.SHR": "go/token",
+ "token.SHR_ASSIGN": "go/token",
+ "token.STRING": "go/token",
+ "token.STRUCT": "go/token",
+ "token.SUB": "go/token",
+ "token.SUB_ASSIGN": "go/token",
+ "token.SWITCH": "go/token",
+ "token.TYPE": "go/token",
+ "token.Token": "go/token",
+ "token.UnaryPrec": "go/token",
+ "token.VAR": "go/token",
+ "token.XOR": "go/token",
+ "token.XOR_ASSIGN": "go/token",
+ "unicode.ASCII_Hex_Digit": "unicode",
+ "unicode.Arabic": "unicode",
+ "unicode.Armenian": "unicode",
+ "unicode.Avestan": "unicode",
+ "unicode.AzeriCase": "unicode",
+ "unicode.Balinese": "unicode",
+ "unicode.Bamum": "unicode",
+ "unicode.Batak": "unicode",
+ "unicode.Bengali": "unicode",
+ "unicode.Bidi_Control": "unicode",
+ "unicode.Bopomofo": "unicode",
+ "unicode.Brahmi": "unicode",
+ "unicode.Braille": "unicode",
+ "unicode.Buginese": "unicode",
+ "unicode.Buhid": "unicode",
+ "unicode.C": "unicode",
+ "unicode.Canadian_Aboriginal": "unicode",
+ "unicode.Carian": "unicode",
+ "unicode.CaseRange": "unicode",
+ "unicode.CaseRanges": "unicode",
+ "unicode.Categories": "unicode",
+ "unicode.Cc": "unicode",
+ "unicode.Cf": "unicode",
+ "unicode.Chakma": "unicode",
+ "unicode.Cham": "unicode",
+ "unicode.Cherokee": "unicode",
+ "unicode.Co": "unicode",
+ "unicode.Common": "unicode",
+ "unicode.Coptic": "unicode",
+ "unicode.Cs": "unicode",
+ "unicode.Cuneiform": "unicode",
+ "unicode.Cypriot": "unicode",
+ "unicode.Cyrillic": "unicode",
+ "unicode.Dash": "unicode",
+ "unicode.Deprecated": "unicode",
+ "unicode.Deseret": "unicode",
+ "unicode.Devanagari": "unicode",
+ "unicode.Diacritic": "unicode",
+ "unicode.Digit": "unicode",
+ "unicode.Egyptian_Hieroglyphs": "unicode",
+ "unicode.Ethiopic": "unicode",
+ "unicode.Extender": "unicode",
+ "unicode.FoldCategory": "unicode",
+ "unicode.FoldScript": "unicode",
+ "unicode.Georgian": "unicode",
+ "unicode.Glagolitic": "unicode",
+ "unicode.Gothic": "unicode",
+ "unicode.GraphicRanges": "unicode",
+ "unicode.Greek": "unicode",
+ "unicode.Gujarati": "unicode",
+ "unicode.Gurmukhi": "unicode",
+ "unicode.Han": "unicode",
+ "unicode.Hangul": "unicode",
+ "unicode.Hanunoo": "unicode",
+ "unicode.Hebrew": "unicode",
+ "unicode.Hex_Digit": "unicode",
+ "unicode.Hiragana": "unicode",
+ "unicode.Hyphen": "unicode",
+ "unicode.IDS_Binary_Operator": "unicode",
+ "unicode.IDS_Trinary_Operator": "unicode",
+ "unicode.Ideographic": "unicode",
+ "unicode.Imperial_Aramaic": "unicode",
+ "unicode.In": "unicode",
+ "unicode.Inherited": "unicode",
+ "unicode.Inscriptional_Pahlavi": "unicode",
+ "unicode.Inscriptional_Parthian": "unicode",
+ "unicode.Is": "unicode",
+ "unicode.IsControl": "unicode",
+ "unicode.IsDigit": "unicode",
+ "unicode.IsGraphic": "unicode",
+ "unicode.IsLetter": "unicode",
+ "unicode.IsLower": "unicode",
+ "unicode.IsMark": "unicode",
+ "unicode.IsNumber": "unicode",
+ "unicode.IsOneOf": "unicode",
+ "unicode.IsPrint": "unicode",
+ "unicode.IsPunct": "unicode",
+ "unicode.IsSpace": "unicode",
+ "unicode.IsSymbol": "unicode",
+ "unicode.IsTitle": "unicode",
+ "unicode.IsUpper": "unicode",
+ "unicode.Javanese": "unicode",
+ "unicode.Join_Control": "unicode",
+ "unicode.Kaithi": "unicode",
+ "unicode.Kannada": "unicode",
+ "unicode.Katakana": "unicode",
+ "unicode.Kayah_Li": "unicode",
+ "unicode.Kharoshthi": "unicode",
+ "unicode.Khmer": "unicode",
+ "unicode.L": "unicode",
+ "unicode.Lao": "unicode",
+ "unicode.Latin": "unicode",
+ "unicode.Lepcha": "unicode",
+ "unicode.Letter": "unicode",
+ "unicode.Limbu": "unicode",
+ "unicode.Linear_B": "unicode",
+ "unicode.Lisu": "unicode",
+ "unicode.Ll": "unicode",
+ "unicode.Lm": "unicode",
+ "unicode.Lo": "unicode",
+ "unicode.Logical_Order_Exception": "unicode",
+ "unicode.Lower": "unicode",
+ "unicode.LowerCase": "unicode",
+ "unicode.Lt": "unicode",
+ "unicode.Lu": "unicode",
+ "unicode.Lycian": "unicode",
+ "unicode.Lydian": "unicode",
+ "unicode.M": "unicode",
+ "unicode.Malayalam": "unicode",
+ "unicode.Mandaic": "unicode",
+ "unicode.Mark": "unicode",
+ "unicode.MaxASCII": "unicode",
+ "unicode.MaxCase": "unicode",
+ "unicode.MaxLatin1": "unicode",
+ "unicode.MaxRune": "unicode",
+ "unicode.Mc": "unicode",
+ "unicode.Me": "unicode",
+ "unicode.Meetei_Mayek": "unicode",
+ "unicode.Meroitic_Cursive": "unicode",
+ "unicode.Meroitic_Hieroglyphs": "unicode",
+ "unicode.Miao": "unicode",
+ "unicode.Mn": "unicode",
+ "unicode.Mongolian": "unicode",
+ "unicode.Myanmar": "unicode",
+ "unicode.N": "unicode",
+ "unicode.Nd": "unicode",
+ "unicode.New_Tai_Lue": "unicode",
+ "unicode.Nko": "unicode",
+ "unicode.Nl": "unicode",
+ "unicode.No": "unicode",
+ "unicode.Noncharacter_Code_Point": "unicode",
+ "unicode.Number": "unicode",
+ "unicode.Ogham": "unicode",
+ "unicode.Ol_Chiki": "unicode",
+ "unicode.Old_Italic": "unicode",
+ "unicode.Old_Persian": "unicode",
+ "unicode.Old_South_Arabian": "unicode",
+ "unicode.Old_Turkic": "unicode",
+ "unicode.Oriya": "unicode",
+ "unicode.Osmanya": "unicode",
+ "unicode.Other": "unicode",
+ "unicode.Other_Alphabetic": "unicode",
+ "unicode.Other_Default_Ignorable_Code_Point": "unicode",
+ "unicode.Other_Grapheme_Extend": "unicode",
+ "unicode.Other_ID_Continue": "unicode",
+ "unicode.Other_ID_Start": "unicode",
+ "unicode.Other_Lowercase": "unicode",
+ "unicode.Other_Math": "unicode",
+ "unicode.Other_Uppercase": "unicode",
+ "unicode.P": "unicode",
+ "unicode.Pattern_Syntax": "unicode",
+ "unicode.Pattern_White_Space": "unicode",
+ "unicode.Pc": "unicode",
+ "unicode.Pd": "unicode",
+ "unicode.Pe": "unicode",
+ "unicode.Pf": "unicode",
+ "unicode.Phags_Pa": "unicode",
+ "unicode.Phoenician": "unicode",
+ "unicode.Pi": "unicode",
+ "unicode.Po": "unicode",
+ "unicode.PrintRanges": "unicode",
+ "unicode.Properties": "unicode",
+ "unicode.Ps": "unicode",
+ "unicode.Punct": "unicode",
+ "unicode.Quotation_Mark": "unicode",
+ "unicode.Radical": "unicode",
+ "unicode.Range16": "unicode",
+ "unicode.Range32": "unicode",
+ "unicode.RangeTable": "unicode",
+ "unicode.Rejang": "unicode",
+ "unicode.ReplacementChar": "unicode",
+ "unicode.Runic": "unicode",
+ "unicode.S": "unicode",
+ "unicode.STerm": "unicode",
+ "unicode.Samaritan": "unicode",
+ "unicode.Saurashtra": "unicode",
+ "unicode.Sc": "unicode",
+ "unicode.Scripts": "unicode",
+ "unicode.Sharada": "unicode",
+ "unicode.Shavian": "unicode",
+ "unicode.SimpleFold": "unicode",
+ "unicode.Sinhala": "unicode",
+ "unicode.Sk": "unicode",
+ "unicode.Sm": "unicode",
+ "unicode.So": "unicode",
+ "unicode.Soft_Dotted": "unicode",
+ "unicode.Sora_Sompeng": "unicode",
+ "unicode.Space": "unicode",
+ "unicode.SpecialCase": "unicode",
+ "unicode.Sundanese": "unicode",
+ "unicode.Syloti_Nagri": "unicode",
+ "unicode.Symbol": "unicode",
+ "unicode.Syriac": "unicode",
+ "unicode.Tagalog": "unicode",
+ "unicode.Tagbanwa": "unicode",
+ "unicode.Tai_Le": "unicode",
+ "unicode.Tai_Tham": "unicode",
+ "unicode.Tai_Viet": "unicode",
+ "unicode.Takri": "unicode",
+ "unicode.Tamil": "unicode",
+ "unicode.Telugu": "unicode",
+ "unicode.Terminal_Punctuation": "unicode",
+ "unicode.Thaana": "unicode",
+ "unicode.Thai": "unicode",
+ "unicode.Tibetan": "unicode",
+ "unicode.Tifinagh": "unicode",
+ "unicode.Title": "unicode",
+ "unicode.TitleCase": "unicode",
+ "unicode.To": "unicode",
+ "unicode.ToLower": "unicode",
+ "unicode.ToTitle": "unicode",
+ "unicode.ToUpper": "unicode",
+ "unicode.TurkishCase": "unicode",
+ "unicode.Ugaritic": "unicode",
+ "unicode.Unified_Ideograph": "unicode",
+ "unicode.Upper": "unicode",
+ "unicode.UpperCase": "unicode",
+ "unicode.UpperLower": "unicode",
+ "unicode.Vai": "unicode",
+ "unicode.Variation_Selector": "unicode",
+ "unicode.Version": "unicode",
+ "unicode.White_Space": "unicode",
+ "unicode.Yi": "unicode",
+ "unicode.Z": "unicode",
+ "unicode.Zl": "unicode",
+ "unicode.Zp": "unicode",
+ "unicode.Zs": "unicode",
+ "url.Error": "net/url",
+ "url.EscapeError": "net/url",
+ "url.Parse": "net/url",
+ "url.ParseQuery": "net/url",
+ "url.ParseRequestURI": "net/url",
+ "url.QueryEscape": "net/url",
+ "url.QueryUnescape": "net/url",
+ "url.URL": "net/url",
+ "url.User": "net/url",
+ "url.UserPassword": "net/url",
+ "url.Userinfo": "net/url",
+ "url.Values": "net/url",
+ "user.Current": "os/user",
+ "user.Lookup": "os/user",
+ "user.LookupId": "os/user",
+ "user.UnknownUserError": "os/user",
+ "user.UnknownUserIdError": "os/user",
+ "user.User": "os/user",
+ "utf16.Decode": "unicode/utf16",
+ "utf16.DecodeRune": "unicode/utf16",
+ "utf16.Encode": "unicode/utf16",
+ "utf16.EncodeRune": "unicode/utf16",
+ "utf16.IsSurrogate": "unicode/utf16",
+ "utf8.DecodeLastRune": "unicode/utf8",
+ "utf8.DecodeLastRuneInString": "unicode/utf8",
+ "utf8.DecodeRune": "unicode/utf8",
+ "utf8.DecodeRuneInString": "unicode/utf8",
+ "utf8.EncodeRune": "unicode/utf8",
+ "utf8.FullRune": "unicode/utf8",
+ "utf8.FullRuneInString": "unicode/utf8",
+ "utf8.MaxRune": "unicode/utf8",
+ "utf8.RuneCount": "unicode/utf8",
+ "utf8.RuneCountInString": "unicode/utf8",
+ "utf8.RuneError": "unicode/utf8",
+ "utf8.RuneLen": "unicode/utf8",
+ "utf8.RuneSelf": "unicode/utf8",
+ "utf8.RuneStart": "unicode/utf8",
+ "utf8.UTFMax": "unicode/utf8",
+ "utf8.Valid": "unicode/utf8",
+ "utf8.ValidRune": "unicode/utf8",
+ "utf8.ValidString": "unicode/utf8",
+ "x509.CANotAuthorizedForThisName": "crypto/x509",
+ "x509.CertPool": "crypto/x509",
+ "x509.Certificate": "crypto/x509",
+ "x509.CertificateInvalidError": "crypto/x509",
+ "x509.CertificateRequest": "crypto/x509",
+ "x509.ConstraintViolationError": "crypto/x509",
+ "x509.CreateCertificate": "crypto/x509",
+ "x509.CreateCertificateRequest": "crypto/x509",
+ "x509.DSA": "crypto/x509",
+ "x509.DSAWithSHA1": "crypto/x509",
+ "x509.DSAWithSHA256": "crypto/x509",
+ "x509.DecryptPEMBlock": "crypto/x509",
+ "x509.ECDSA": "crypto/x509",
+ "x509.ECDSAWithSHA1": "crypto/x509",
+ "x509.ECDSAWithSHA256": "crypto/x509",
+ "x509.ECDSAWithSHA384": "crypto/x509",
+ "x509.ECDSAWithSHA512": "crypto/x509",
+ "x509.EncryptPEMBlock": "crypto/x509",
+ "x509.ErrUnsupportedAlgorithm": "crypto/x509",
+ "x509.Expired": "crypto/x509",
+ "x509.ExtKeyUsage": "crypto/x509",
+ "x509.ExtKeyUsageAny": "crypto/x509",
+ "x509.ExtKeyUsageClientAuth": "crypto/x509",
+ "x509.ExtKeyUsageCodeSigning": "crypto/x509",
+ "x509.ExtKeyUsageEmailProtection": "crypto/x509",
+ "x509.ExtKeyUsageIPSECEndSystem": "crypto/x509",
+ "x509.ExtKeyUsageIPSECTunnel": "crypto/x509",
+ "x509.ExtKeyUsageIPSECUser": "crypto/x509",
+ "x509.ExtKeyUsageMicrosoftServerGatedCrypto": "crypto/x509",
+ "x509.ExtKeyUsageNetscapeServerGatedCrypto": "crypto/x509",
+ "x509.ExtKeyUsageOCSPSigning": "crypto/x509",
+ "x509.ExtKeyUsageServerAuth": "crypto/x509",
+ "x509.ExtKeyUsageTimeStamping": "crypto/x509",
+ "x509.HostnameError": "crypto/x509",
+ "x509.IncompatibleUsage": "crypto/x509",
+ "x509.IncorrectPasswordError": "crypto/x509",
+ "x509.InvalidReason": "crypto/x509",
+ "x509.IsEncryptedPEMBlock": "crypto/x509",
+ "x509.KeyUsage": "crypto/x509",
+ "x509.KeyUsageCRLSign": "crypto/x509",
+ "x509.KeyUsageCertSign": "crypto/x509",
+ "x509.KeyUsageContentCommitment": "crypto/x509",
+ "x509.KeyUsageDataEncipherment": "crypto/x509",
+ "x509.KeyUsageDecipherOnly": "crypto/x509",
+ "x509.KeyUsageDigitalSignature": "crypto/x509",
+ "x509.KeyUsageEncipherOnly": "crypto/x509",
+ "x509.KeyUsageKeyAgreement": "crypto/x509",
+ "x509.KeyUsageKeyEncipherment": "crypto/x509",
+ "x509.MD2WithRSA": "crypto/x509",
+ "x509.MD5WithRSA": "crypto/x509",
+ "x509.MarshalECPrivateKey": "crypto/x509",
+ "x509.MarshalPKCS1PrivateKey": "crypto/x509",
+ "x509.MarshalPKIXPublicKey": "crypto/x509",
+ "x509.NewCertPool": "crypto/x509",
+ "x509.NotAuthorizedToSign": "crypto/x509",
+ "x509.PEMCipher": "crypto/x509",
+ "x509.PEMCipher3DES": "crypto/x509",
+ "x509.PEMCipherAES128": "crypto/x509",
+ "x509.PEMCipherAES192": "crypto/x509",
+ "x509.PEMCipherAES256": "crypto/x509",
+ "x509.PEMCipherDES": "crypto/x509",
+ "x509.ParseCRL": "crypto/x509",
+ "x509.ParseCertificate": "crypto/x509",
+ "x509.ParseCertificateRequest": "crypto/x509",
+ "x509.ParseCertificates": "crypto/x509",
+ "x509.ParseDERCRL": "crypto/x509",
+ "x509.ParseECPrivateKey": "crypto/x509",
+ "x509.ParsePKCS1PrivateKey": "crypto/x509",
+ "x509.ParsePKCS8PrivateKey": "crypto/x509",
+ "x509.ParsePKIXPublicKey": "crypto/x509",
+ "x509.PublicKeyAlgorithm": "crypto/x509",
+ "x509.RSA": "crypto/x509",
+ "x509.SHA1WithRSA": "crypto/x509",
+ "x509.SHA256WithRSA": "crypto/x509",
+ "x509.SHA384WithRSA": "crypto/x509",
+ "x509.SHA512WithRSA": "crypto/x509",
+ "x509.SignatureAlgorithm": "crypto/x509",
+ "x509.SystemRootsError": "crypto/x509",
+ "x509.TooManyIntermediates": "crypto/x509",
+ "x509.UnhandledCriticalExtension": "crypto/x509",
+ "x509.UnknownAuthorityError": "crypto/x509",
+ "x509.UnknownPublicKeyAlgorithm": "crypto/x509",
+ "x509.UnknownSignatureAlgorithm": "crypto/x509",
+ "x509.VerifyOptions": "crypto/x509",
+ "xml.Attr": "encoding/xml",
+ "xml.CharData": "encoding/xml",
+ "xml.Comment": "encoding/xml",
+ "xml.CopyToken": "encoding/xml",
+ "xml.Decoder": "encoding/xml",
+ "xml.Directive": "encoding/xml",
+ "xml.Encoder": "encoding/xml",
+ "xml.EndElement": "encoding/xml",
+ "xml.Escape": "encoding/xml",
+ "xml.EscapeText": "encoding/xml",
+ "xml.HTMLAutoClose": "encoding/xml",
+ "xml.HTMLEntity": "encoding/xml",
+ "xml.Header": "encoding/xml",
+ "xml.Marshal": "encoding/xml",
+ "xml.MarshalIndent": "encoding/xml",
+ "xml.Marshaler": "encoding/xml",
+ "xml.MarshalerAttr": "encoding/xml",
+ "xml.Name": "encoding/xml",
+ "xml.NewDecoder": "encoding/xml",
+ "xml.NewEncoder": "encoding/xml",
+ "xml.ProcInst": "encoding/xml",
+ "xml.StartElement": "encoding/xml",
+ "xml.SyntaxError": "encoding/xml",
+ "xml.TagPathError": "encoding/xml",
+ "xml.Token": "encoding/xml",
+ "xml.Unmarshal": "encoding/xml",
+ "xml.UnmarshalError": "encoding/xml",
+ "xml.Unmarshaler": "encoding/xml",
+ "xml.UnmarshalerAttr": "encoding/xml",
+ "xml.UnsupportedTypeError": "encoding/xml",
+ "zip.Compressor": "archive/zip",
+ "zip.Decompressor": "archive/zip",
+ "zip.Deflate": "archive/zip",
+ "zip.ErrAlgorithm": "archive/zip",
+ "zip.ErrChecksum": "archive/zip",
+ "zip.ErrFormat": "archive/zip",
+ "zip.File": "archive/zip",
+ "zip.FileHeader": "archive/zip",
+ "zip.FileInfoHeader": "archive/zip",
+ "zip.NewReader": "archive/zip",
+ "zip.NewWriter": "archive/zip",
+ "zip.OpenReader": "archive/zip",
+ "zip.ReadCloser": "archive/zip",
+ "zip.Reader": "archive/zip",
+ "zip.RegisterCompressor": "archive/zip",
+ "zip.RegisterDecompressor": "archive/zip",
+ "zip.Store": "archive/zip",
+ "zip.Writer": "archive/zip",
+ "zlib.BestCompression": "compress/zlib",
+ "zlib.BestSpeed": "compress/zlib",
+ "zlib.DefaultCompression": "compress/zlib",
+ "zlib.ErrChecksum": "compress/zlib",
+ "zlib.ErrDictionary": "compress/zlib",
+ "zlib.ErrHeader": "compress/zlib",
+ "zlib.NewReader": "compress/zlib",
+ "zlib.NewReaderDict": "compress/zlib",
+ "zlib.NewWriter": "compress/zlib",
+ "zlib.NewWriterLevel": "compress/zlib",
+ "zlib.NewWriterLevelDict": "compress/zlib",
+ "zlib.NoCompression": "compress/zlib",
+ "zlib.Writer": "compress/zlib",
+}
diff --git a/vendor/github.com/visualfc/gotools/types/types.go b/vendor/github.com/visualfc/gotools/types/types.go
new file mode 100644
index 0000000..1605adb
--- /dev/null
+++ b/vendor/github.com/visualfc/gotools/types/types.go
@@ -0,0 +1,1064 @@
+// Copyright 2011-2015 visualfc . All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package types
+
+import (
+ "bytes"
+ "fmt"
+ "go/ast"
+ "go/build"
+ "go/parser"
+ "go/printer"
+ "go/token"
+ "io/ioutil"
+ "log"
+ "os"
+ "path/filepath"
+ "regexp"
+ "sort"
+ "strconv"
+ "strings"
+ "time"
+
+ "github.com/visualfc/gotools/command"
+ "github.com/visualfc/gotools/stdlib"
+ "golang.org/x/tools/go/buildutil"
+ "golang.org/x/tools/go/gcimporter"
+ "golang.org/x/tools/go/types"
+)
+
+var Command = &command.Command{
+ Run: runTypes,
+ UsageLine: "types",
+ Short: "golang type util",
+ Long: `golang type util`,
+}
+
+var (
+ typesVerbose bool
+ typesAllowBinary bool
+ typesFilePos string
+ typesFileStdin bool
+ typesFindUse bool
+ typesFindDef bool
+ typesFindUseAll bool
+ typesFindInfo bool
+ typesFindDoc bool
+)
+
+//func init
+func init() {
+ Command.Flag.BoolVar(&typesVerbose, "v", false, "verbose debugging")
+ Command.Flag.BoolVar(&typesAllowBinary, "b", false, "import can be satisfied by a compiled package object without corresponding sources.")
+ Command.Flag.StringVar(&typesFilePos, "pos", "", "file position \"file.go:pos\"")
+ Command.Flag.BoolVar(&typesFileStdin, "stdin", false, "input file use stdin")
+ Command.Flag.BoolVar(&typesFindInfo, "info", false, "find cursor info")
+ Command.Flag.BoolVar(&typesFindDef, "def", false, "find cursor define")
+ Command.Flag.BoolVar(&typesFindUse, "use", false, "find cursor usages")
+ Command.Flag.BoolVar(&typesFindUseAll, "all", false, "find cursor all usages in GOPATH")
+ Command.Flag.BoolVar(&typesFindDoc, "doc", false, "find cursor def doc")
+}
+
+type ObjKind int
+
+const (
+ ObjNone ObjKind = iota
+ ObjPkgName
+ ObjTypeName
+ ObjInterface
+ ObjStruct
+ ObjConst
+ ObjVar
+ ObjField
+ ObjFunc
+ ObjMethod
+ ObjLabel
+ ObjBuiltin
+ ObjNil
+)
+
+var ObjKindName = []string{"none", "package",
+ "type", "interface", "struct",
+ "const", "var", "field",
+ "func", "method",
+ "label", "builtin", "nil"}
+
+func (k ObjKind) String() string {
+ if k >= 0 && int(k) < len(ObjKindName) {
+ return ObjKindName[k]
+ }
+ return "unkwnown"
+}
+
+var builtinInfoMap = map[string]string{
+ "append": "func append(slice []Type, elems ...Type) []Type",
+ "copy": "func copy(dst, src []Type) int",
+ "delete": "func delete(m map[Type]Type1, key Type)",
+ "len": "func len(v Type) int",
+ "cap": "func cap(v Type) int",
+ "make": "func make(Type, size IntegerType) Type",
+ "new": "func new(Type) *Type",
+ "complex": "func complex(r, i FloatType) ComplexType",
+ "real": "func real(c ComplexType) FloatType",
+ "imag": "func imag(c ComplexType) FloatType",
+ "close": "func close(c chan<- Type)",
+ "panic": "func panic(v interface{})",
+ "recover": "func recover() interface{}",
+ "print": "func print(args ...Type)",
+ "println": "func println(args ...Type)",
+ "error": "type error interface {Error() string}",
+}
+
+func builtinInfo(id string) string {
+ if info, ok := builtinInfoMap[id]; ok {
+ return "builtin " + info
+ }
+ return "builtin " + id
+}
+
+func simpleObjInfo(obj types.Object) string {
+ pkg := obj.Pkg()
+ s := simpleType(obj.String())
+ if pkg != nil && pkg.Name() == "main" {
+ return strings.Replace(s, simpleType(pkg.Path())+".", "", -1)
+ }
+ return s
+}
+
+func simpleType(src string) string {
+ re, _ := regexp.Compile("[\\w\\./]+")
+ return re.ReplaceAllStringFunc(src, func(s string) string {
+ r := s
+ if i := strings.LastIndex(s, "/"); i != -1 {
+ r = s[i+1:]
+ }
+ if strings.Count(r, ".") > 1 {
+ r = r[strings.Index(r, ".")+1:]
+ }
+ return r
+ })
+}
+
+func runTypes(cmd *command.Command, args []string) error {
+ if len(args) < 1 {
+ cmd.Usage()
+ return nil
+ }
+ if typesVerbose {
+ now := time.Now()
+ defer func() {
+ log.Println("time", time.Now().Sub(now))
+ }()
+ }
+ w := NewPkgWalker(&build.Default)
+ var cursor *FileCursor
+ if typesFilePos != "" {
+ var cursorInfo FileCursor
+ pos := strings.Index(typesFilePos, ":")
+ if pos != -1 {
+ cursorInfo.fileName = typesFilePos[:pos]
+ if i, err := strconv.Atoi(typesFilePos[pos+1:]); err == nil {
+ cursorInfo.cursorPos = i
+ }
+ }
+ if typesFileStdin {
+ src, err := ioutil.ReadAll(os.Stdin)
+ if err == nil {
+ cursorInfo.src = src
+ }
+ }
+ cursor = &cursorInfo
+ }
+ for _, pkgName := range args {
+ if pkgName == "." {
+ pkgPath, err := os.Getwd()
+ if err != nil {
+ log.Fatalln(err)
+ }
+ pkgName = pkgPath
+ }
+ conf := &PkgConfig{IgnoreFuncBodies: true, AllowBinary: true, WithTestFiles: true}
+ if cursor != nil {
+ conf.Cursor = cursor
+ conf.IgnoreFuncBodies = false
+ conf.Info = &types.Info{
+ Uses: make(map[*ast.Ident]types.Object),
+ Defs: make(map[*ast.Ident]types.Object),
+ Selections: make(map[*ast.SelectorExpr]*types.Selection),
+ //Types: make(map[ast.Expr]types.TypeAndValue),
+ //Scopes : make(map[ast.Node]*types.Scope)
+ //Implicits : make(map[ast.Node]types.Object)
+ }
+ conf.XInfo = &types.Info{
+ Uses: make(map[*ast.Ident]types.Object),
+ Defs: make(map[*ast.Ident]types.Object),
+ Selections: make(map[*ast.SelectorExpr]*types.Selection),
+ }
+ }
+ pkg, err := w.Import("", pkgName, conf)
+ if pkg == nil {
+ log.Fatalln("error import path", err)
+ }
+ if cursor != nil && (typesFindInfo || typesFindDef || typesFindUse) {
+ w.LookupCursor(pkg, conf, cursor)
+ }
+ }
+ return nil
+}
+
+type FileCursor struct {
+ pkg string
+ fileName string
+ fileDir string
+ cursorPos int
+ pos token.Pos
+ src interface{}
+ xtest bool
+}
+
+type PkgConfig struct {
+ IgnoreFuncBodies bool
+ AllowBinary bool
+ WithTestFiles bool
+ Cursor *FileCursor
+ Pkg *types.Package
+ XPkg *types.Package
+ Info *types.Info
+ XInfo *types.Info
+ Files map[string]*ast.File
+ TestFiles map[string]*ast.File
+ XTestFiles map[string]*ast.File
+}
+
+func NewPkgWalker(context *build.Context) *PkgWalker {
+ return &PkgWalker{
+ context: context,
+ fset: token.NewFileSet(),
+ parsedFileCache: map[string]*ast.File{},
+ imported: map[string]*types.Package{"unsafe": types.Unsafe},
+ gcimporter: map[string]*types.Package{"unsafe": types.Unsafe},
+ }
+}
+
+type PkgWalker struct {
+ fset *token.FileSet
+ context *build.Context
+ current *types.Package
+ importing types.Package
+ parsedFileCache map[string]*ast.File
+ imported map[string]*types.Package // packages already imported
+ gcimporter map[string]*types.Package
+}
+
+func contains(list []string, s string) bool {
+ for _, t := range list {
+ if t == s {
+ return true
+ }
+ }
+ return false
+}
+
+func (w *PkgWalker) isBinaryPkg(pkg string) bool {
+ return stdlib.IsStdPkg(pkg)
+}
+
+func (w *PkgWalker) importPath(path string, mode build.ImportMode) (*build.Package, error) {
+ if filepath.IsAbs(path) {
+ return w.context.ImportDir(path, 0)
+ }
+ if stdlib.IsStdPkg(path) {
+ return stdlib.ImportStdPkg(w.context, path, mode)
+ }
+ return w.context.Import(path, "", mode)
+}
+
+func (w *PkgWalker) Import(parentDir string, name string, conf *PkgConfig) (pkg *types.Package, err error) {
+ defer func() {
+ err := recover()
+ if err != nil && typesVerbose {
+ log.Println(err)
+ }
+ }()
+
+ if strings.HasPrefix(name, ".") && parentDir != "" {
+ name = filepath.Join(parentDir, name)
+ }
+ pkg = w.imported[name]
+ if pkg != nil {
+ if pkg == &w.importing {
+ return nil, fmt.Errorf("cycle importing package %q", name)
+ }
+ return pkg, nil
+ }
+
+ if typesVerbose {
+ log.Println("parser pkg", name)
+ }
+
+ bp, err := w.importPath(name, 0)
+ if err != nil {
+ return nil, err
+ }
+
+ checkName := name
+
+ if bp.ImportPath == "." {
+ checkName = bp.Name
+ } else {
+ checkName = bp.ImportPath
+ }
+
+ if err != nil {
+ return nil, err
+ //if _, nogo := err.(*build.NoGoError); nogo {
+ // return
+ //}
+ //return
+ //log.Fatalf("pkg %q, dir %q: ScanDir: %v", name, info.Dir, err)
+ }
+
+ filenames := append(append([]string{}, bp.GoFiles...), bp.CgoFiles...)
+ if conf.WithTestFiles {
+ filenames = append(filenames, bp.TestGoFiles...)
+ }
+
+ if name == "runtime" {
+ n := fmt.Sprintf("zgoos_%s.go", w.context.GOOS)
+ if !contains(filenames, n) {
+ filenames = append(filenames, n)
+ }
+
+ n = fmt.Sprintf("zgoarch_%s.go", w.context.GOARCH)
+ if !contains(filenames, n) {
+ filenames = append(filenames, n)
+ }
+ }
+
+ parserFiles := func(filenames []string, cursor *FileCursor, xtest bool) (files []*ast.File) {
+ for _, file := range filenames {
+ var f *ast.File
+ if cursor != nil && cursor.fileName == file {
+ f, err = w.parseFile(bp.Dir, file, cursor.src)
+ cursor.pos = token.Pos(w.fset.File(f.Pos()).Base()) + token.Pos(cursor.cursorPos)
+ cursor.fileDir = bp.Dir
+ cursor.xtest = xtest
+ } else {
+ f, err = w.parseFile(bp.Dir, file, nil)
+ }
+ if err != nil && typesVerbose {
+ log.Printf("error parsing package %s: %s\n", name, err)
+ }
+ files = append(files, f)
+ }
+ return
+ }
+ files := parserFiles(filenames, conf.Cursor, false)
+ xfiles := parserFiles(bp.XTestGoFiles, conf.Cursor, true)
+
+ typesConf := types.Config{
+ IgnoreFuncBodies: conf.IgnoreFuncBodies,
+ FakeImportC: true,
+ Packages: w.gcimporter,
+ Import: func(imports map[string]*types.Package, name string) (pkg *types.Package, err error) {
+ if pkg != nil {
+ return pkg, nil
+ }
+ if conf.AllowBinary && w.isBinaryPkg(name) {
+ pkg = w.gcimporter[name]
+ if pkg != nil && pkg.Complete() {
+ return
+ }
+ pkg, err = gcimporter.Import(imports, name)
+ if pkg != nil && pkg.Complete() {
+ w.gcimporter[name] = pkg
+ return
+ }
+ }
+ return w.Import(bp.Dir, name, &PkgConfig{IgnoreFuncBodies: true, AllowBinary: true, WithTestFiles: false})
+ },
+ Error: func(err error) {
+ if typesVerbose {
+ log.Println(err)
+ }
+ },
+ }
+ if pkg == nil {
+ pkg, err = typesConf.Check(checkName, w.fset, files, conf.Info)
+ conf.Pkg = pkg
+ }
+ w.imported[name] = pkg
+
+ if len(xfiles) > 0 {
+ xpkg, _ := typesConf.Check(checkName+"_test", w.fset, xfiles, conf.XInfo)
+ w.imported[checkName+"_test"] = xpkg
+ conf.XPkg = xpkg
+ }
+ return
+}
+
+func (w *PkgWalker) parseFile(dir, file string, src interface{}) (*ast.File, error) {
+ filename := filepath.Join(dir, file)
+ f, _ := w.parsedFileCache[filename]
+ if f != nil {
+ return f, nil
+ }
+
+ var err error
+
+ // generate missing context-dependent files.
+ if w.context != nil && file == fmt.Sprintf("zgoos_%s.go", w.context.GOOS) {
+ src := fmt.Sprintf("package runtime; const theGoos = `%s`", w.context.GOOS)
+ f, err = parser.ParseFile(w.fset, filename, src, 0)
+ if err != nil {
+ log.Fatalf("incorrect generated file: %s", err)
+ }
+ }
+
+ if w.context != nil && file == fmt.Sprintf("zgoarch_%s.go", w.context.GOARCH) {
+ src := fmt.Sprintf("package runtime; const theGoarch = `%s`", w.context.GOARCH)
+ f, err = parser.ParseFile(w.fset, filename, src, 0)
+ if err != nil {
+ log.Fatalf("incorrect generated file: %s", err)
+ }
+ }
+
+ if f == nil {
+ flag := parser.AllErrors
+ if typesFindDoc {
+ flag |= parser.ParseComments
+ }
+ f, err = parser.ParseFile(w.fset, filename, src, flag)
+ if err != nil {
+ return f, err
+ }
+ }
+
+ w.parsedFileCache[filename] = f
+ return f, nil
+}
+
+func (w *PkgWalker) LookupCursor(pkg *types.Package, conf *PkgConfig, cursor *FileCursor) {
+ is := w.CheckIsImport(cursor)
+ if is != nil {
+ if cursor.xtest {
+ w.LookupImport(conf.XPkg, conf.XInfo, cursor, is)
+ } else {
+ w.LookupImport(conf.Pkg, conf.Info, cursor, is)
+ }
+ } else {
+ w.LookupObjects(conf, cursor)
+ }
+}
+
+func (w *PkgWalker) LookupImport(pkg *types.Package, pkgInfo *types.Info, cursor *FileCursor, is *ast.ImportSpec) {
+ fpath, err := strconv.Unquote(is.Path.Value)
+ if err != nil {
+ return
+ }
+
+ if typesFindDef {
+ fmt.Println(w.fset.Position(is.Pos()))
+ }
+
+ fbase := fpath
+ pos := strings.LastIndexAny(fpath, "./-\\")
+ if pos != -1 {
+ fbase = fpath[pos+1:]
+ }
+
+ var fname string
+ if is.Name != nil {
+ fname = is.Name.Name
+ } else {
+ fname = fbase
+ }
+
+ if typesFindInfo {
+ if fname == fpath {
+ fmt.Printf("package %s\n", fname)
+ } else {
+ fmt.Printf("package %s (\"%s\")\n", fname, fpath)
+ }
+ }
+
+ if !typesFindUse {
+ return
+ }
+
+ fid := pkg.Path() + "." + fname
+ var usages []int
+ for id, obj := range pkgInfo.Uses {
+ if obj != nil && obj.Id() == fid { //!= nil && cursorObj.Pos() == obj.Pos() {
+ usages = append(usages, int(id.Pos()))
+ }
+ }
+ (sort.IntSlice(usages)).Sort()
+ for _, pos := range usages {
+ fmt.Println(w.fset.Position(token.Pos(pos)))
+ }
+}
+
+func parserObjKind(obj types.Object) (ObjKind, error) {
+ var kind ObjKind
+ switch t := obj.(type) {
+ case *types.PkgName:
+ kind = ObjPkgName
+ case *types.Const:
+ kind = ObjConst
+ case *types.TypeName:
+ kind = ObjTypeName
+ switch t.Type().Underlying().(type) {
+ case *types.Interface:
+ kind = ObjInterface
+ case *types.Struct:
+ kind = ObjStruct
+ }
+ case *types.Var:
+ kind = ObjVar
+ if t.IsField() {
+ kind = ObjField
+ }
+ case *types.Func:
+ kind = ObjFunc
+ if sig, ok := t.Type().(*types.Signature); ok {
+ if sig.Recv() != nil {
+ kind = ObjMethod
+ }
+ }
+ case *types.Label:
+ kind = ObjLabel
+ case *types.Builtin:
+ kind = ObjBuiltin
+ case *types.Nil:
+ kind = ObjNil
+ default:
+ return ObjNone, fmt.Errorf("unknown obj type %T", obj)
+ }
+ return kind, nil
+}
+
+func (w *PkgWalker) LookupStructFromField(info *types.Info, cursorPkg *types.Package, cursorObj types.Object, cursorPos token.Pos) types.Object {
+ if info == nil {
+ conf := &PkgConfig{
+ IgnoreFuncBodies: true,
+ AllowBinary: true,
+ WithTestFiles: true,
+ Info: &types.Info{
+ Defs: make(map[*ast.Ident]types.Object),
+ },
+ }
+ w.imported[cursorPkg.Path()] = nil
+ pkg, _ := w.Import("", cursorPkg.Path(), conf)
+ if pkg != nil {
+ info = conf.Info
+ }
+ }
+ for _, obj := range info.Defs {
+ if obj == nil {
+ continue
+ }
+ if _, ok := obj.(*types.TypeName); ok {
+ if t, ok := obj.Type().Underlying().(*types.Struct); ok {
+ for i := 0; i < t.NumFields(); i++ {
+ if t.Field(i).Pos() == cursorPos {
+ return obj
+ }
+ }
+ }
+ }
+ }
+ return nil
+}
+
+func (w *PkgWalker) lookupNamedField(named *types.Named, name string) *types.Named {
+ if istruct, ok := named.Underlying().(*types.Struct); ok {
+ for i := 0; i < istruct.NumFields(); i++ {
+ field := istruct.Field(i)
+ if field.Anonymous() {
+ fieldType := orgType(field.Type())
+ if typ, ok := fieldType.(*types.Named); ok {
+ if na := w.lookupNamedField(typ, name); na != nil {
+ return na
+ }
+ }
+ } else {
+ if field.Name() == name {
+ return named
+ }
+ }
+ }
+ }
+ return nil
+}
+
+func (w *PkgWalker) lookupNamedMethod(named *types.Named, name string) (types.Object, *types.Named) {
+ if iface, ok := named.Underlying().(*types.Interface); ok {
+ for i := 0; i < iface.NumMethods(); i++ {
+ fn := iface.Method(i)
+ if fn.Name() == name {
+ return fn, named
+ }
+ }
+ for i := 0; i < iface.NumEmbeddeds(); i++ {
+ if obj, na := w.lookupNamedMethod(iface.Embedded(i), name); obj != nil {
+ return obj, na
+ }
+ }
+ return nil, nil
+ }
+ if istruct, ok := named.Underlying().(*types.Struct); ok {
+ for i := 0; i < named.NumMethods(); i++ {
+ fn := named.Method(i)
+ if fn.Name() == name {
+ return fn, named
+ }
+ }
+ for i := 0; i < istruct.NumFields(); i++ {
+ field := istruct.Field(i)
+ if !field.Anonymous() {
+ continue
+ }
+ if typ, ok := field.Type().(*types.Named); ok {
+ if obj, na := w.lookupNamedMethod(typ, name); obj != nil {
+ return obj, na
+ }
+ }
+ }
+ }
+ return nil, nil
+}
+
+func IsSamePkg(a, b *types.Package) bool {
+ if a == b {
+ return true
+ }
+ if a == nil || b == nil {
+ return false
+ }
+ return a.Path() == b.Path()
+}
+
+func IsSameObject(a, b types.Object) bool {
+ if a == b {
+ return true
+ }
+ if a == nil || b == nil {
+ return false
+ }
+ var apath string
+ var bpath string
+ if a.Pkg() != nil {
+ apath = a.Pkg().Path()
+ }
+ if b.Pkg() != nil {
+ bpath = b.Pkg().Path()
+ }
+ if apath != bpath {
+ return false
+ }
+ if a.Id() != b.Id() {
+ return false
+ }
+ return a.String() == b.String()
+}
+
+func orgType(typ types.Type) types.Type {
+ if pt, ok := typ.(*types.Pointer); ok {
+ return pt.Elem()
+ }
+ return typ
+}
+
+func (w *PkgWalker) LookupObjects(conf *PkgConfig, cursor *FileCursor) {
+ var cursorObj types.Object
+ var cursorSelection *types.Selection
+ var cursorObjIsDef bool
+ //lookup defs
+
+ var pkg *types.Package
+ var pkgInfo *types.Info
+ if cursor.xtest {
+ pkgInfo = conf.XInfo
+ pkg = conf.XPkg
+ } else {
+ pkgInfo = conf.Info
+ pkg = conf.Pkg
+ }
+
+ _ = cursorObjIsDef
+ if cursorObj == nil {
+ for sel, obj := range pkgInfo.Selections {
+ if cursor.pos >= sel.Sel.Pos() && cursor.pos <= sel.Sel.End() {
+ cursorObj = obj.Obj()
+ cursorSelection = obj
+ break
+ }
+ }
+ }
+ if cursorObj == nil {
+ for id, obj := range pkgInfo.Defs {
+ if cursor.pos >= id.Pos() && cursor.pos <= id.End() {
+ cursorObj = obj
+ cursorObjIsDef = true
+ break
+ }
+ }
+ }
+ _ = cursorSelection
+ if cursorObj == nil {
+ for id, obj := range pkgInfo.Uses {
+ if cursor.pos >= id.Pos() && cursor.pos <= id.End() {
+ cursorObj = obj
+ break
+ }
+ }
+ }
+ if cursorObj == nil {
+ return
+ }
+ kind, err := parserObjKind(cursorObj)
+ if err != nil {
+ log.Fatalln(err)
+ }
+
+ if kind == ObjField {
+ if cursorObj.(*types.Var).Anonymous() {
+ typ := orgType(cursorObj.Type())
+ if named, ok := typ.(*types.Named); ok {
+ cursorObj = named.Obj()
+ }
+ }
+ }
+ cursorPkg := cursorObj.Pkg()
+ cursorPos := cursorObj.Pos()
+ //var fieldTypeInfo *types.Info
+ var fieldTypeObj types.Object
+ // if cursorPkg == pkg {
+ // fieldTypeInfo = pkgInfo
+ // }
+ cursorIsInterfaceMethod := false
+ var cursorInterfaceTypeName string
+ if kind == ObjMethod && cursorSelection != nil && cursorSelection.Recv() != nil {
+ sig := cursorObj.(*types.Func).Type().Underlying().(*types.Signature)
+ if _, ok := sig.Recv().Type().Underlying().(*types.Interface); ok {
+ if named, ok := cursorSelection.Recv().(*types.Named); ok {
+ obj, typ := w.lookupNamedMethod(named, cursorObj.Name())
+ if obj != nil {
+ cursorObj = obj
+ }
+ if typ != nil {
+ cursorPkg = typ.Obj().Pkg()
+ cursorInterfaceTypeName = typ.Obj().Name()
+ }
+ cursorIsInterfaceMethod = true
+ }
+ }
+ } else if kind == ObjField && cursorSelection != nil {
+ if recv := cursorSelection.Recv(); recv != nil {
+ typ := orgType(recv)
+ if typ != nil {
+ if name, ok := typ.(*types.Named); ok {
+ fieldTypeObj = name.Obj()
+ na := w.lookupNamedField(name, cursorObj.Name())
+ if na != nil {
+ fieldTypeObj = na.Obj()
+ }
+ }
+ }
+ }
+ }
+ if cursorPkg != nil && cursorPkg != pkg &&
+ kind != ObjPkgName && w.isBinaryPkg(cursorPkg.Path()) {
+ conf := &PkgConfig{
+ IgnoreFuncBodies: true,
+ AllowBinary: true,
+ WithTestFiles: true,
+ Info: &types.Info{
+ Defs: make(map[*ast.Ident]types.Object),
+ },
+ }
+ pkg, _ := w.Import("", cursorPkg.Path(), conf)
+ if pkg != nil {
+ if cursorIsInterfaceMethod {
+ for _, obj := range conf.Info.Defs {
+ if obj == nil {
+ continue
+ }
+ if fn, ok := obj.(*types.Func); ok {
+ if fn.Name() == cursorObj.Name() {
+ if sig, ok := fn.Type().Underlying().(*types.Signature); ok {
+ if named, ok := sig.Recv().Type().(*types.Named); ok {
+ if named.Obj() != nil && named.Obj().Name() == cursorInterfaceTypeName {
+ cursorPos = obj.Pos()
+ break
+ }
+ }
+ }
+ }
+ }
+ }
+ } else if kind == ObjField && fieldTypeObj != nil {
+ for _, obj := range conf.Info.Defs {
+ if obj == nil {
+ continue
+ }
+ if _, ok := obj.(*types.TypeName); ok {
+ if IsSameObject(fieldTypeObj, obj) {
+ if t, ok := obj.Type().Underlying().(*types.Struct); ok {
+ for i := 0; i < t.NumFields(); i++ {
+ if t.Field(i).Id() == cursorObj.Id() {
+ cursorPos = t.Field(i).Pos()
+ break
+ }
+ }
+ }
+ break
+ }
+ }
+ }
+ } else {
+ for k, v := range conf.Info.Defs {
+ if k != nil && v != nil && IsSameObject(v, cursorObj) {
+ cursorPos = k.Pos()
+ break
+ }
+ }
+ }
+ }
+ // if kind == ObjField || cursorIsInterfaceMethod {
+ // fieldTypeInfo = conf.Info
+ // }
+ }
+ // if kind == ObjField {
+ // fieldTypeObj = w.LookupStructFromField(fieldTypeInfo, cursorPkg, cursorObj, cursorPos)
+ // }
+ if typesFindDef {
+ fmt.Println(w.fset.Position(cursorPos))
+ }
+ if typesFindInfo {
+ if kind == ObjField && fieldTypeObj != nil {
+ typeName := fieldTypeObj.Name()
+ if fieldTypeObj.Pkg() != nil && fieldTypeObj.Pkg() != pkg {
+ typeName = fieldTypeObj.Pkg().Name() + "." + fieldTypeObj.Name()
+ }
+ fmt.Println(typeName, simpleObjInfo(cursorObj))
+ } else if kind == ObjBuiltin {
+ fmt.Println(builtinInfo(cursorObj.Name()))
+ } else if kind == ObjPkgName {
+ fmt.Println(cursorObj.String())
+ } else if cursorIsInterfaceMethod {
+ fmt.Println(strings.Replace(simpleObjInfo(cursorObj), "(interface)", cursorPkg.Name()+"."+cursorInterfaceTypeName, 1))
+ } else {
+ fmt.Println(simpleObjInfo(cursorObj))
+ }
+ }
+
+ if typesFindDoc && typesFindDef {
+ pos := w.fset.Position(cursorPos)
+ file := w.parsedFileCache[pos.Filename]
+ if file != nil {
+ line := pos.Line
+ var group *ast.CommentGroup
+ for _, v := range file.Comments {
+ lastLine := w.fset.Position(v.End()).Line
+ if lastLine == line || lastLine == line-1 {
+ group = v
+ } else if lastLine > line {
+ break
+ }
+ }
+ if group != nil {
+ fmt.Println(group.Text())
+ }
+ }
+ }
+ if !typesFindUse {
+ return
+ }
+
+ var usages []int
+ if kind == ObjPkgName {
+ for id, obj := range pkgInfo.Uses {
+ if obj != nil && obj.Id() == cursorObj.Id() { //!= nil && cursorObj.Pos() == obj.Pos() {
+ usages = append(usages, int(id.Pos()))
+ }
+ }
+ } else {
+ // for id, obj := range pkgInfo.Defs {
+ // if obj == cursorObj { //!= nil && cursorObj.Pos() == obj.Pos() {
+ // usages = append(usages, int(id.Pos()))
+ // }
+ // }
+ for id, obj := range pkgInfo.Uses {
+ if obj == cursorObj { //!= nil && cursorObj.Pos() == obj.Pos() {
+ usages = append(usages, int(id.Pos()))
+ }
+ }
+ }
+ var pkg_path string
+ var xpkg_path string
+ if conf.Pkg != nil {
+ pkg_path = conf.Pkg.Path()
+ }
+ if conf.XPkg != nil {
+ xpkg_path = conf.XPkg.Path()
+ }
+
+ if cursorPkg != nil && (cursorPkg.Path() == pkg_path ||
+ cursorPkg.Path() == xpkg_path) {
+ usages = append(usages, int(cursorPos))
+ }
+
+ (sort.IntSlice(usages)).Sort()
+ for _, pos := range usages {
+ fmt.Println(w.fset.Position(token.Pos(pos)))
+ }
+ //check look for current pkg.object on pkg_test
+ if typesFindUseAll || IsSamePkg(cursorPkg, conf.Pkg) {
+ var addInfo *types.Info
+ if conf.Cursor.xtest {
+ addInfo = conf.Info
+ } else {
+ addInfo = conf.XInfo
+ }
+ if addInfo != nil && cursorPkg != nil {
+ var usages []int
+ // for id, obj := range addInfo.Defs {
+ // if id != nil && obj != nil && obj.Id() == cursorObj.Id() {
+ // usages = append(usages, int(id.Pos()))
+ // }
+ // }
+ for k, v := range addInfo.Uses {
+ if k != nil && v != nil && IsSameObject(v, cursorObj) {
+ usages = append(usages, int(k.Pos()))
+ }
+ }
+ (sort.IntSlice(usages)).Sort()
+ for _, pos := range usages {
+ fmt.Println(w.fset.Position(token.Pos(pos)))
+ }
+ }
+ }
+ if !typesFindUseAll {
+ return
+ }
+
+ if cursorPkg == nil {
+ return
+ }
+
+ var find_def_pkg string
+ var uses_paths []string
+ if cursorPkg.Path() != pkg_path && cursorPkg.Path() != xpkg_path {
+ find_def_pkg = cursorPkg.Path()
+ uses_paths = append(uses_paths, cursorPkg.Path())
+ }
+
+ buildutil.ForEachPackage(&build.Default, func(importPath string, err error) {
+ if err != nil {
+ return
+ }
+ if importPath == conf.Pkg.Path() {
+ return
+ }
+ bp, err := w.importPath(importPath, 0)
+ if err != nil {
+ return
+ }
+ find := false
+ if bp.ImportPath == cursorPkg.Path() {
+ find = true
+ } else {
+ for _, v := range bp.Imports {
+ if v == cursorObj.Pkg().Path() {
+ find = true
+ break
+ }
+ }
+ }
+ if find {
+ for _, v := range uses_paths {
+ if v == bp.ImportPath {
+ return
+ }
+ }
+ uses_paths = append(uses_paths, bp.ImportPath)
+ }
+ })
+
+ w.imported = make(map[string]*types.Package)
+ for _, v := range uses_paths {
+ conf := &PkgConfig{
+ IgnoreFuncBodies: false,
+ AllowBinary: true,
+ WithTestFiles: true,
+ Info: &types.Info{
+ Uses: make(map[*ast.Ident]types.Object),
+ },
+ XInfo: &types.Info{
+ Uses: make(map[*ast.Ident]types.Object),
+ },
+ }
+ w.imported[v] = nil
+ var usages []int
+ vpkg, _ := w.Import("", v, conf)
+ if vpkg != nil && vpkg != pkg {
+ if conf.Info != nil {
+ for k, v := range conf.Info.Uses {
+ if k != nil && v != nil && IsSameObject(v, cursorObj) {
+ usages = append(usages, int(k.Pos()))
+ }
+ }
+ }
+ if conf.XInfo != nil {
+ for k, v := range conf.XInfo.Uses {
+ if k != nil && v != nil && IsSameObject(v, cursorObj) {
+ usages = append(usages, int(k.Pos()))
+ }
+ }
+ }
+ }
+ if v == find_def_pkg {
+ usages = append(usages, int(cursorPos))
+ }
+ (sort.IntSlice(usages)).Sort()
+ for _, pos := range usages {
+ fmt.Println(w.fset.Position(token.Pos(pos)))
+ }
+ }
+}
+
+func (w *PkgWalker) CheckIsImport(cursor *FileCursor) *ast.ImportSpec {
+ if cursor.fileDir == "" {
+ return nil
+ }
+ file, _ := w.parseFile(cursor.fileDir, cursor.fileName, cursor.src)
+ if file == nil {
+ return nil
+ }
+ for _, is := range file.Imports {
+ if inRange(is, cursor.pos) {
+ return is
+ }
+ }
+ return nil
+}
+
+func inRange(node ast.Node, p token.Pos) bool {
+ if node == nil {
+ return false
+ }
+ return p >= node.Pos() && p <= node.End()
+}
+
+func (w *PkgWalker) nodeString(node interface{}) string {
+ if node == nil {
+ return ""
+ }
+ var b bytes.Buffer
+ printer.Fprint(&b, w.fset, node)
+ return b.String()
+}
diff --git a/vendor/golang.org/x/tools/LICENSE b/vendor/golang.org/x/tools/LICENSE
new file mode 100644
index 0000000..6a66aea
--- /dev/null
+++ b/vendor/golang.org/x/tools/LICENSE
@@ -0,0 +1,27 @@
+Copyright (c) 2009 The Go Authors. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+ * Redistributions of source code must retain the above copyright
+notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above
+copyright notice, this list of conditions and the following disclaimer
+in the documentation and/or other materials provided with the
+distribution.
+ * Neither the name of Google Inc. nor the names of its
+contributors may be used to endorse or promote products derived from
+this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/vendor/golang.org/x/tools/PATENTS b/vendor/golang.org/x/tools/PATENTS
new file mode 100644
index 0000000..7330990
--- /dev/null
+++ b/vendor/golang.org/x/tools/PATENTS
@@ -0,0 +1,22 @@
+Additional IP Rights Grant (Patents)
+
+"This implementation" means the copyrightable works distributed by
+Google as part of the Go project.
+
+Google hereby grants to You a perpetual, worldwide, non-exclusive,
+no-charge, royalty-free, irrevocable (except as stated in this section)
+patent license to make, have made, use, offer to sell, sell, import,
+transfer and otherwise run, modify and propagate the contents of this
+implementation of Go, where such license applies only to those patent
+claims, both currently owned or controlled by Google and acquired in
+the future, licensable by Google that are necessarily infringed by this
+implementation of Go. This grant does not include claims that would be
+infringed only as a consequence of further modification of this
+implementation. If you or your agent or exclusive licensee institute or
+order or agree to the institution of patent litigation against any
+entity (including a cross-claim or counterclaim in a lawsuit) alleging
+that this implementation of Go or any code incorporated within this
+implementation of Go constitutes direct or contributory patent
+infringement, or inducement of patent infringement, then any patent
+rights granted to you under this License for this implementation of Go
+shall terminate as of the date such litigation is filed.
diff --git a/vendor/golang.org/x/tools/container/intsets/sparse.go b/vendor/golang.org/x/tools/container/intsets/sparse.go
new file mode 100644
index 0000000..8847feb
--- /dev/null
+++ b/vendor/golang.org/x/tools/container/intsets/sparse.go
@@ -0,0 +1,967 @@
+// Copyright 2014 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package intsets provides Sparse, a compact and fast representation
+// for sparse sets of int values.
+//
+// The time complexity of the operations Len, Insert, Remove and Has
+// is in O(n) but in practice those methods are faster and more
+// space-efficient than equivalent operations on sets based on the Go
+// map type. The IsEmpty, Min, Max, Clear and TakeMin operations
+// require constant time.
+//
+package intsets // import "golang.org/x/tools/container/intsets"
+
+// TODO(adonovan):
+// - Add InsertAll(...int), RemoveAll(...int)
+// - Add 'bool changed' results for {Intersection,Difference}With too.
+//
+// TODO(adonovan): implement Dense, a dense bit vector with a similar API.
+// The space usage would be proportional to Max(), not Len(), and the
+// implementation would be based upon big.Int.
+//
+// TODO(adonovan): experiment with making the root block indirect (nil
+// iff IsEmpty). This would reduce the memory usage when empty and
+// might simplify the aliasing invariants.
+//
+// TODO(adonovan): opt: make UnionWith and Difference faster.
+// These are the hot-spots for go/pointer.
+
+import (
+ "bytes"
+ "fmt"
+)
+
+// A Sparse is a set of int values.
+// Sparse operations (even queries) are not concurrency-safe.
+//
+// The zero value for Sparse is a valid empty set.
+//
+// Sparse sets must be copied using the Copy method, not by assigning
+// a Sparse value.
+//
+type Sparse struct {
+ // An uninitialized Sparse represents an empty set.
+ // An empty set may also be represented by
+ // root.next == root.prev == &root.
+ // In a non-empty set, root.next points to the first block and
+ // root.prev to the last.
+ // root.offset and root.bits are unused.
+ root block
+}
+
+type word uintptr
+
+const (
+ _m = ^word(0)
+ bitsPerWord = 8 << (_m>>8&1 + _m>>16&1 + _m>>32&1)
+ bitsPerBlock = 256 // optimal value for go/pointer solver performance
+ wordsPerBlock = bitsPerBlock / bitsPerWord
+)
+
+// Limit values of implementation-specific int type.
+const (
+ MaxInt = int(^uint(0) >> 1)
+ MinInt = -MaxInt - 1
+)
+
+// -- block ------------------------------------------------------------
+
+// A set is represented as a circular doubly-linked list of blocks,
+// each containing an offset and a bit array of fixed size
+// bitsPerBlock; the blocks are ordered by increasing offset.
+//
+// The set contains an element x iff the block whose offset is x - (x
+// mod bitsPerBlock) has the bit (x mod bitsPerBlock) set, where mod
+// is the Euclidean remainder.
+//
+// A block may only be empty transiently.
+//
+type block struct {
+ offset int // offset mod bitsPerBlock == 0
+ bits [wordsPerBlock]word // contains at least one set bit
+ next, prev *block // doubly-linked list of blocks
+}
+
+// wordMask returns the word index (in block.bits)
+// and single-bit mask for the block's ith bit.
+func wordMask(i uint) (w uint, mask word) {
+ w = i / bitsPerWord
+ mask = 1 << (i % bitsPerWord)
+ return
+}
+
+// insert sets the block b's ith bit and
+// returns true if it was not already set.
+//
+func (b *block) insert(i uint) bool {
+ w, mask := wordMask(i)
+ if b.bits[w]&mask == 0 {
+ b.bits[w] |= mask
+ return true
+ }
+ return false
+}
+
+// remove clears the block's ith bit and
+// returns true if the bit was previously set.
+// NB: may leave the block empty.
+//
+func (b *block) remove(i uint) bool {
+ w, mask := wordMask(i)
+ if b.bits[w]&mask != 0 {
+ b.bits[w] &^= mask
+ return true
+ }
+ return false
+}
+
+// has reports whether the block's ith bit is set.
+func (b *block) has(i uint) bool {
+ w, mask := wordMask(i)
+ return b.bits[w]&mask != 0
+}
+
+// empty reports whether b.len()==0, but more efficiently.
+func (b *block) empty() bool {
+ for _, w := range b.bits {
+ if w != 0 {
+ return false
+ }
+ }
+ return true
+}
+
+// len returns the number of set bits in block b.
+func (b *block) len() int {
+ var l int
+ for _, w := range b.bits {
+ l += popcount(w)
+ }
+ return l
+}
+
+// max returns the maximum element of the block.
+// The block must not be empty.
+//
+func (b *block) max() int {
+ bi := b.offset + bitsPerBlock
+ // Decrement bi by number of high zeros in last.bits.
+ for i := len(b.bits) - 1; i >= 0; i-- {
+ if w := b.bits[i]; w != 0 {
+ return bi - nlz(w) - 1
+ }
+ bi -= bitsPerWord
+ }
+ panic("BUG: empty block")
+}
+
+// min returns the minimum element of the block,
+// and also removes it if take is set.
+// The block must not be initially empty.
+// NB: may leave the block empty.
+//
+func (b *block) min(take bool) int {
+ for i, w := range b.bits {
+ if w != 0 {
+ tz := ntz(w)
+ if take {
+ b.bits[i] = w &^ (1 << uint(tz))
+ }
+ return b.offset + int(i*bitsPerWord) + tz
+ }
+ }
+ panic("BUG: empty block")
+}
+
+// forEach calls f for each element of block b.
+// f must not mutate b's enclosing Sparse.
+func (b *block) forEach(f func(int)) {
+ for i, w := range b.bits {
+ offset := b.offset + i*bitsPerWord
+ for bi := 0; w != 0 && bi < bitsPerWord; bi++ {
+ if w&1 != 0 {
+ f(offset)
+ }
+ offset++
+ w >>= 1
+ }
+ }
+}
+
+// offsetAndBitIndex returns the offset of the block that would
+// contain x and the bit index of x within that block.
+//
+func offsetAndBitIndex(x int) (int, uint) {
+ mod := x % bitsPerBlock
+ if mod < 0 {
+ // Euclidean (non-negative) remainder
+ mod += bitsPerBlock
+ }
+ return x - mod, uint(mod)
+}
+
+// -- Sparse --------------------------------------------------------------
+
+// start returns the root's next block, which is the root block
+// (if s.IsEmpty()) or the first true block otherwise.
+// start has the side effect of ensuring that s is properly
+// initialized.
+//
+func (s *Sparse) start() *block {
+ root := &s.root
+ if root.next == nil {
+ root.next = root
+ root.prev = root
+ } else if root.next.prev != root {
+ // Copying a Sparse x leads to pernicious corruption: the
+ // new Sparse y shares the old linked list, but iteration
+ // on y will never encounter &y.root so it goes into a
+ // loop. Fail fast before this occurs.
+ panic("A Sparse has been copied without (*Sparse).Copy()")
+ }
+
+ return root.next
+}
+
+// IsEmpty reports whether the set s is empty.
+func (s *Sparse) IsEmpty() bool {
+ return s.start() == &s.root
+}
+
+// Len returns the number of elements in the set s.
+func (s *Sparse) Len() int {
+ var l int
+ for b := s.start(); b != &s.root; b = b.next {
+ l += b.len()
+ }
+ return l
+}
+
+// Max returns the maximum element of the set s, or MinInt if s is empty.
+func (s *Sparse) Max() int {
+ if s.IsEmpty() {
+ return MinInt
+ }
+ return s.root.prev.max()
+}
+
+// Min returns the minimum element of the set s, or MaxInt if s is empty.
+func (s *Sparse) Min() int {
+ if s.IsEmpty() {
+ return MaxInt
+ }
+ return s.root.next.min(false)
+}
+
+// block returns the block that would contain offset,
+// or nil if s contains no such block.
+//
+func (s *Sparse) block(offset int) *block {
+ b := s.start()
+ for b != &s.root && b.offset <= offset {
+ if b.offset == offset {
+ return b
+ }
+ b = b.next
+ }
+ return nil
+}
+
+// Insert adds x to the set s, and reports whether the set grew.
+func (s *Sparse) Insert(x int) bool {
+ offset, i := offsetAndBitIndex(x)
+ b := s.start()
+ for b != &s.root && b.offset <= offset {
+ if b.offset == offset {
+ return b.insert(i)
+ }
+ b = b.next
+ }
+
+ // Insert new block before b.
+ new := &block{offset: offset}
+ new.next = b
+ new.prev = b.prev
+ new.prev.next = new
+ new.next.prev = new
+ return new.insert(i)
+}
+
+func (s *Sparse) removeBlock(b *block) {
+ b.prev.next = b.next
+ b.next.prev = b.prev
+}
+
+// Remove removes x from the set s, and reports whether the set shrank.
+func (s *Sparse) Remove(x int) bool {
+ offset, i := offsetAndBitIndex(x)
+ if b := s.block(offset); b != nil {
+ if !b.remove(i) {
+ return false
+ }
+ if b.empty() {
+ s.removeBlock(b)
+ }
+ return true
+ }
+ return false
+}
+
+// Clear removes all elements from the set s.
+func (s *Sparse) Clear() {
+ s.root.next = &s.root
+ s.root.prev = &s.root
+}
+
+// If set s is non-empty, TakeMin sets *p to the minimum element of
+// the set s, removes that element from the set and returns true.
+// Otherwise, it returns false and *p is undefined.
+//
+// This method may be used for iteration over a worklist like so:
+//
+// var x int
+// for worklist.TakeMin(&x) { use(x) }
+//
+func (s *Sparse) TakeMin(p *int) bool {
+ head := s.start()
+ if head == &s.root {
+ return false
+ }
+ *p = head.min(true)
+ if head.empty() {
+ s.removeBlock(head)
+ }
+ return true
+}
+
+// Has reports whether x is an element of the set s.
+func (s *Sparse) Has(x int) bool {
+ offset, i := offsetAndBitIndex(x)
+ if b := s.block(offset); b != nil {
+ return b.has(i)
+ }
+ return false
+}
+
+// forEach applies function f to each element of the set s in order.
+//
+// f must not mutate s. Consequently, forEach is not safe to expose
+// to clients. In any case, using "range s.AppendTo()" allows more
+// natural control flow with continue/break/return.
+//
+func (s *Sparse) forEach(f func(int)) {
+ for b := s.start(); b != &s.root; b = b.next {
+ b.forEach(f)
+ }
+}
+
+// Copy sets s to the value of x.
+func (s *Sparse) Copy(x *Sparse) {
+ if s == x {
+ return
+ }
+
+ xb := x.start()
+ sb := s.start()
+ for xb != &x.root {
+ if sb == &s.root {
+ sb = s.insertBlockBefore(sb)
+ }
+ sb.offset = xb.offset
+ sb.bits = xb.bits
+ xb = xb.next
+ sb = sb.next
+ }
+ s.discardTail(sb)
+}
+
+// insertBlockBefore returns a new block, inserting it before next.
+func (s *Sparse) insertBlockBefore(next *block) *block {
+ b := new(block)
+ b.next = next
+ b.prev = next.prev
+ b.prev.next = b
+ next.prev = b
+ return b
+}
+
+// discardTail removes block b and all its successors from s.
+func (s *Sparse) discardTail(b *block) {
+ if b != &s.root {
+ b.prev.next = &s.root
+ s.root.prev = b.prev
+ }
+}
+
+// IntersectionWith sets s to the intersection s ∩ x.
+func (s *Sparse) IntersectionWith(x *Sparse) {
+ if s == x {
+ return
+ }
+
+ xb := x.start()
+ sb := s.start()
+ for xb != &x.root && sb != &s.root {
+ switch {
+ case xb.offset < sb.offset:
+ xb = xb.next
+
+ case xb.offset > sb.offset:
+ sb = sb.next
+ s.removeBlock(sb.prev)
+
+ default:
+ var sum word
+ for i := range sb.bits {
+ r := xb.bits[i] & sb.bits[i]
+ sb.bits[i] = r
+ sum |= r
+ }
+ if sum != 0 {
+ sb = sb.next
+ } else {
+ // sb will be overwritten or removed
+ }
+
+ xb = xb.next
+ }
+ }
+
+ s.discardTail(sb)
+}
+
+// Intersection sets s to the intersection x ∩ y.
+func (s *Sparse) Intersection(x, y *Sparse) {
+ switch {
+ case s == x:
+ s.IntersectionWith(y)
+ return
+ case s == y:
+ s.IntersectionWith(x)
+ return
+ case x == y:
+ s.Copy(x)
+ return
+ }
+
+ xb := x.start()
+ yb := y.start()
+ sb := s.start()
+ for xb != &x.root && yb != &y.root {
+ switch {
+ case xb.offset < yb.offset:
+ xb = xb.next
+ continue
+ case xb.offset > yb.offset:
+ yb = yb.next
+ continue
+ }
+
+ if sb == &s.root {
+ sb = s.insertBlockBefore(sb)
+ }
+ sb.offset = xb.offset
+
+ var sum word
+ for i := range sb.bits {
+ r := xb.bits[i] & yb.bits[i]
+ sb.bits[i] = r
+ sum |= r
+ }
+ if sum != 0 {
+ sb = sb.next
+ } else {
+ // sb will be overwritten or removed
+ }
+
+ xb = xb.next
+ yb = yb.next
+ }
+
+ s.discardTail(sb)
+}
+
+// Intersects reports whether s ∩ x ≠ ∅.
+func (s *Sparse) Intersects(x *Sparse) bool {
+ sb := s.start()
+ xb := x.start()
+ for sb != &s.root && xb != &x.root {
+ switch {
+ case xb.offset < sb.offset:
+ xb = xb.next
+ case xb.offset > sb.offset:
+ sb = sb.next
+ default:
+ for i := range sb.bits {
+ if sb.bits[i]&xb.bits[i] != 0 {
+ return true
+ }
+ }
+ sb = sb.next
+ xb = xb.next
+ }
+ }
+ return false
+}
+
+// UnionWith sets s to the union s ∪ x, and reports whether s grew.
+func (s *Sparse) UnionWith(x *Sparse) bool {
+ if s == x {
+ return false
+ }
+
+ var changed bool
+ xb := x.start()
+ sb := s.start()
+ for xb != &x.root {
+ if sb != &s.root && sb.offset == xb.offset {
+ for i := range xb.bits {
+ if sb.bits[i] != xb.bits[i] {
+ sb.bits[i] |= xb.bits[i]
+ changed = true
+ }
+ }
+ xb = xb.next
+ } else if sb == &s.root || sb.offset > xb.offset {
+ sb = s.insertBlockBefore(sb)
+ sb.offset = xb.offset
+ sb.bits = xb.bits
+ changed = true
+
+ xb = xb.next
+ }
+ sb = sb.next
+ }
+ return changed
+}
+
+// Union sets s to the union x ∪ y.
+func (s *Sparse) Union(x, y *Sparse) {
+ switch {
+ case x == y:
+ s.Copy(x)
+ return
+ case s == x:
+ s.UnionWith(y)
+ return
+ case s == y:
+ s.UnionWith(x)
+ return
+ }
+
+ xb := x.start()
+ yb := y.start()
+ sb := s.start()
+ for xb != &x.root || yb != &y.root {
+ if sb == &s.root {
+ sb = s.insertBlockBefore(sb)
+ }
+ switch {
+ case yb == &y.root || (xb != &x.root && xb.offset < yb.offset):
+ sb.offset = xb.offset
+ sb.bits = xb.bits
+ xb = xb.next
+
+ case xb == &x.root || (yb != &y.root && yb.offset < xb.offset):
+ sb.offset = yb.offset
+ sb.bits = yb.bits
+ yb = yb.next
+
+ default:
+ sb.offset = xb.offset
+ for i := range xb.bits {
+ sb.bits[i] = xb.bits[i] | yb.bits[i]
+ }
+ xb = xb.next
+ yb = yb.next
+ }
+ sb = sb.next
+ }
+
+ s.discardTail(sb)
+}
+
+// DifferenceWith sets s to the difference s ∖ x.
+func (s *Sparse) DifferenceWith(x *Sparse) {
+ if s == x {
+ s.Clear()
+ return
+ }
+
+ xb := x.start()
+ sb := s.start()
+ for xb != &x.root && sb != &s.root {
+ switch {
+ case xb.offset > sb.offset:
+ sb = sb.next
+
+ case xb.offset < sb.offset:
+ xb = xb.next
+
+ default:
+ var sum word
+ for i := range sb.bits {
+ r := sb.bits[i] & ^xb.bits[i]
+ sb.bits[i] = r
+ sum |= r
+ }
+ sb = sb.next
+ xb = xb.next
+
+ if sum == 0 {
+ s.removeBlock(sb.prev)
+ }
+ }
+ }
+}
+
+// Difference sets s to the difference x ∖ y.
+func (s *Sparse) Difference(x, y *Sparse) {
+ switch {
+ case x == y:
+ s.Clear()
+ return
+ case s == x:
+ s.DifferenceWith(y)
+ return
+ case s == y:
+ var y2 Sparse
+ y2.Copy(y)
+ s.Difference(x, &y2)
+ return
+ }
+
+ xb := x.start()
+ yb := y.start()
+ sb := s.start()
+ for xb != &x.root && yb != &y.root {
+ if xb.offset > yb.offset {
+ // y has block, x has none
+ yb = yb.next
+ continue
+ }
+
+ if sb == &s.root {
+ sb = s.insertBlockBefore(sb)
+ }
+ sb.offset = xb.offset
+
+ switch {
+ case xb.offset < yb.offset:
+ // x has block, y has none
+ sb.bits = xb.bits
+
+ sb = sb.next
+
+ default:
+ // x and y have corresponding blocks
+ var sum word
+ for i := range sb.bits {
+ r := xb.bits[i] & ^yb.bits[i]
+ sb.bits[i] = r
+ sum |= r
+ }
+ if sum != 0 {
+ sb = sb.next
+ } else {
+ // sb will be overwritten or removed
+ }
+
+ yb = yb.next
+ }
+ xb = xb.next
+ }
+
+ for xb != &x.root {
+ if sb == &s.root {
+ sb = s.insertBlockBefore(sb)
+ }
+ sb.offset = xb.offset
+ sb.bits = xb.bits
+ sb = sb.next
+
+ xb = xb.next
+ }
+
+ s.discardTail(sb)
+}
+
+// SymmetricDifferenceWith sets s to the symmetric difference s ∆ x.
+func (s *Sparse) SymmetricDifferenceWith(x *Sparse) {
+ if s == x {
+ s.Clear()
+ return
+ }
+
+ sb := s.start()
+ xb := x.start()
+ for xb != &x.root && sb != &s.root {
+ switch {
+ case sb.offset < xb.offset:
+ sb = sb.next
+ case xb.offset < sb.offset:
+ nb := s.insertBlockBefore(sb)
+ nb.offset = xb.offset
+ nb.bits = xb.bits
+ xb = xb.next
+ default:
+ var sum word
+ for i := range sb.bits {
+ r := sb.bits[i] ^ xb.bits[i]
+ sb.bits[i] = r
+ sum |= r
+ }
+ sb = sb.next
+ xb = xb.next
+ if sum == 0 {
+ s.removeBlock(sb.prev)
+ }
+ }
+ }
+
+ for xb != &x.root { // append the tail of x to s
+ sb = s.insertBlockBefore(sb)
+ sb.offset = xb.offset
+ sb.bits = xb.bits
+ sb = sb.next
+ xb = xb.next
+ }
+}
+
+// SymmetricDifference sets s to the symmetric difference x ∆ y.
+func (s *Sparse) SymmetricDifference(x, y *Sparse) {
+ switch {
+ case x == y:
+ s.Clear()
+ return
+ case s == x:
+ s.SymmetricDifferenceWith(y)
+ return
+ case s == y:
+ s.SymmetricDifferenceWith(x)
+ return
+ }
+
+ sb := s.start()
+ xb := x.start()
+ yb := y.start()
+ for xb != &x.root && yb != &y.root {
+ if sb == &s.root {
+ sb = s.insertBlockBefore(sb)
+ }
+ switch {
+ case yb.offset < xb.offset:
+ sb.offset = yb.offset
+ sb.bits = yb.bits
+ sb = sb.next
+ yb = yb.next
+ case xb.offset < yb.offset:
+ sb.offset = xb.offset
+ sb.bits = xb.bits
+ sb = sb.next
+ xb = xb.next
+ default:
+ var sum word
+ for i := range sb.bits {
+ r := xb.bits[i] ^ yb.bits[i]
+ sb.bits[i] = r
+ sum |= r
+ }
+ if sum != 0 {
+ sb.offset = xb.offset
+ sb = sb.next
+ }
+ xb = xb.next
+ yb = yb.next
+ }
+ }
+
+ for xb != &x.root { // append the tail of x to s
+ if sb == &s.root {
+ sb = s.insertBlockBefore(sb)
+ }
+ sb.offset = xb.offset
+ sb.bits = xb.bits
+ sb = sb.next
+ xb = xb.next
+ }
+
+ for yb != &y.root { // append the tail of y to s
+ if sb == &s.root {
+ sb = s.insertBlockBefore(sb)
+ }
+ sb.offset = yb.offset
+ sb.bits = yb.bits
+ sb = sb.next
+ yb = yb.next
+ }
+
+ s.discardTail(sb)
+}
+
+// SubsetOf reports whether s ∖ x = ∅.
+func (s *Sparse) SubsetOf(x *Sparse) bool {
+ if s == x {
+ return true
+ }
+
+ sb := s.start()
+ xb := x.start()
+ for sb != &s.root {
+ switch {
+ case xb == &x.root || xb.offset > sb.offset:
+ return false
+ case xb.offset < sb.offset:
+ xb = xb.next
+ default:
+ for i := range sb.bits {
+ if sb.bits[i]&^xb.bits[i] != 0 {
+ return false
+ }
+ }
+ sb = sb.next
+ xb = xb.next
+ }
+ }
+ return true
+}
+
+// Equals reports whether the sets s and t have the same elements.
+func (s *Sparse) Equals(t *Sparse) bool {
+ if s == t {
+ return true
+ }
+ sb := s.start()
+ tb := t.start()
+ for {
+ switch {
+ case sb == &s.root && tb == &t.root:
+ return true
+ case sb == &s.root || tb == &t.root:
+ return false
+ case sb.offset != tb.offset:
+ return false
+ case sb.bits != tb.bits:
+ return false
+ }
+
+ sb = sb.next
+ tb = tb.next
+ }
+}
+
+// String returns a human-readable description of the set s.
+func (s *Sparse) String() string {
+ var buf bytes.Buffer
+ buf.WriteByte('{')
+ s.forEach(func(x int) {
+ if buf.Len() > 1 {
+ buf.WriteByte(' ')
+ }
+ fmt.Fprintf(&buf, "%d", x)
+ })
+ buf.WriteByte('}')
+ return buf.String()
+}
+
+// BitString returns the set as a string of 1s and 0s denoting the sum
+// of the i'th powers of 2, for each i in s. A radix point, always
+// preceded by a digit, appears if the sum is non-integral.
+//
+// Examples:
+// {}.BitString() = "0"
+// {4,5}.BitString() = "110000"
+// {-3}.BitString() = "0.001"
+// {-3,0,4,5}.BitString() = "110001.001"
+//
+func (s *Sparse) BitString() string {
+ if s.IsEmpty() {
+ return "0"
+ }
+
+ min, max := s.Min(), s.Max()
+ var nbytes int
+ if max > 0 {
+ nbytes = max
+ }
+ nbytes++ // zero bit
+ radix := nbytes
+ if min < 0 {
+ nbytes += len(".") - min
+ }
+
+ b := make([]byte, nbytes)
+ for i := range b {
+ b[i] = '0'
+ }
+ if radix < nbytes {
+ b[radix] = '.'
+ }
+ s.forEach(func(x int) {
+ if x >= 0 {
+ x += len(".")
+ }
+ b[radix-x] = '1'
+ })
+ return string(b)
+}
+
+// GoString returns a string showing the internal representation of
+// the set s.
+//
+func (s *Sparse) GoString() string {
+ var buf bytes.Buffer
+ for b := s.start(); b != &s.root; b = b.next {
+ fmt.Fprintf(&buf, "block %p {offset=%d next=%p prev=%p",
+ b, b.offset, b.next, b.prev)
+ for _, w := range b.bits {
+ fmt.Fprintf(&buf, " 0%016x", w)
+ }
+ fmt.Fprintf(&buf, "}\n")
+ }
+ return buf.String()
+}
+
+// AppendTo returns the result of appending the elements of s to slice
+// in order.
+func (s *Sparse) AppendTo(slice []int) []int {
+ s.forEach(func(x int) {
+ slice = append(slice, x)
+ })
+ return slice
+}
+
+// -- Testing/debugging ------------------------------------------------
+
+// check returns an error if the representation invariants of s are violated.
+func (s *Sparse) check() error {
+ if !s.root.empty() {
+ return fmt.Errorf("non-empty root block")
+ }
+ if s.root.offset != 0 {
+ return fmt.Errorf("root block has non-zero offset %d", s.root.offset)
+ }
+ for b := s.start(); b != &s.root; b = b.next {
+ if b.offset%bitsPerBlock != 0 {
+ return fmt.Errorf("bad offset modulo: %d", b.offset)
+ }
+ if b.empty() {
+ return fmt.Errorf("empty block")
+ }
+ if b.prev.next != b {
+ return fmt.Errorf("bad prev.next link")
+ }
+ if b.next.prev != b {
+ return fmt.Errorf("bad next.prev link")
+ }
+ if b.prev != &s.root {
+ if b.offset <= b.prev.offset {
+ return fmt.Errorf("bad offset order: b.offset=%d, prev.offset=%d",
+ b.offset, b.prev.offset)
+ }
+ }
+ }
+ return nil
+}
diff --git a/vendor/golang.org/x/tools/container/intsets/util.go b/vendor/golang.org/x/tools/container/intsets/util.go
new file mode 100644
index 0000000..76e682c
--- /dev/null
+++ b/vendor/golang.org/x/tools/container/intsets/util.go
@@ -0,0 +1,75 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package intsets
+
+var a [1 << 8]byte
+
+func init() {
+ for i := range a {
+ var n byte
+ for x := i; x != 0; x >>= 1 {
+ if x&1 != 0 {
+ n++
+ }
+ }
+ a[i] = n
+ }
+}
+
+// popcount returns the population count (number of set bits) of x.
+func popcount(x word) int {
+ return int(a[byte(x>>(0*8))] +
+ a[byte(x>>(1*8))] +
+ a[byte(x>>(2*8))] +
+ a[byte(x>>(3*8))] +
+ a[byte(x>>(4*8))] +
+ a[byte(x>>(5*8))] +
+ a[byte(x>>(6*8))] +
+ a[byte(x>>(7*8))])
+}
+
+// nlz returns the number of leading zeros of x.
+// From Hacker's Delight, fig 5.11.
+func nlz(x word) int {
+ x |= (x >> 1)
+ x |= (x >> 2)
+ x |= (x >> 4)
+ x |= (x >> 8)
+ x |= (x >> 16)
+ x |= (x >> 32)
+ return popcount(^x)
+}
+
+// ntz returns the number of trailing zeros of x.
+// From Hacker's Delight, fig 5.13.
+func ntz(x word) int {
+ if x == 0 {
+ return bitsPerWord
+ }
+ n := 1
+ if bitsPerWord == 64 {
+ if (x & 0xffffffff) == 0 {
+ n = n + 32
+ x = x >> 32
+ }
+ }
+ if (x & 0x0000ffff) == 0 {
+ n = n + 16
+ x = x >> 16
+ }
+ if (x & 0x000000ff) == 0 {
+ n = n + 8
+ x = x >> 8
+ }
+ if (x & 0x0000000f) == 0 {
+ n = n + 4
+ x = x >> 4
+ }
+ if (x & 0x00000003) == 0 {
+ n = n + 2
+ x = x >> 2
+ }
+ return n - int(x&1)
+}
diff --git a/vendor/golang.org/x/tools/go/ast/astutil/enclosing.go b/vendor/golang.org/x/tools/go/ast/astutil/enclosing.go
new file mode 100644
index 0000000..2de739e
--- /dev/null
+++ b/vendor/golang.org/x/tools/go/ast/astutil/enclosing.go
@@ -0,0 +1,625 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package astutil
+
+// This file defines utilities for working with source positions.
+
+import (
+ "fmt"
+ "go/ast"
+ "go/token"
+ "sort"
+)
+
+// PathEnclosingInterval returns the node that encloses the source
+// interval [start, end), and all its ancestors up to the AST root.
+//
+// The definition of "enclosing" used by this function considers
+// additional whitespace abutting a node to be enclosed by it.
+// In this example:
+//
+// z := x + y // add them
+// <-A->
+// <----B----->
+//
+// the ast.BinaryExpr(+) node is considered to enclose interval B
+// even though its [Pos()..End()) is actually only interval A.
+// This behaviour makes user interfaces more tolerant of imperfect
+// input.
+//
+// This function treats tokens as nodes, though they are not included
+// in the result. e.g. PathEnclosingInterval("+") returns the
+// enclosing ast.BinaryExpr("x + y").
+//
+// If start==end, the 1-char interval following start is used instead.
+//
+// The 'exact' result is true if the interval contains only path[0]
+// and perhaps some adjacent whitespace. It is false if the interval
+// overlaps multiple children of path[0], or if it contains only
+// interior whitespace of path[0].
+// In this example:
+//
+// z := x + y // add them
+// <--C--> <---E-->
+// ^
+// D
+//
+// intervals C, D and E are inexact. C is contained by the
+// z-assignment statement, because it spans three of its children (:=,
+// x, +). So too is the 1-char interval D, because it contains only
+// interior whitespace of the assignment. E is considered interior
+// whitespace of the BlockStmt containing the assignment.
+//
+// Precondition: [start, end) both lie within the same file as root.
+// TODO(adonovan): return (nil, false) in this case and remove precond.
+// Requires FileSet; see loader.tokenFileContainsPos.
+//
+// Postcondition: path is never nil; it always contains at least 'root'.
+//
+func PathEnclosingInterval(root *ast.File, start, end token.Pos) (path []ast.Node, exact bool) {
+ // fmt.Printf("EnclosingInterval %d %d\n", start, end) // debugging
+
+ // Precondition: node.[Pos..End) and adjoining whitespace contain [start, end).
+ var visit func(node ast.Node) bool
+ visit = func(node ast.Node) bool {
+ path = append(path, node)
+
+ nodePos := node.Pos()
+ nodeEnd := node.End()
+
+ // fmt.Printf("visit(%T, %d, %d)\n", node, nodePos, nodeEnd) // debugging
+
+ // Intersect [start, end) with interval of node.
+ if start < nodePos {
+ start = nodePos
+ }
+ if end > nodeEnd {
+ end = nodeEnd
+ }
+
+ // Find sole child that contains [start, end).
+ children := childrenOf(node)
+ l := len(children)
+ for i, child := range children {
+ // [childPos, childEnd) is unaugmented interval of child.
+ childPos := child.Pos()
+ childEnd := child.End()
+
+ // [augPos, augEnd) is whitespace-augmented interval of child.
+ augPos := childPos
+ augEnd := childEnd
+ if i > 0 {
+ augPos = children[i-1].End() // start of preceding whitespace
+ }
+ if i < l-1 {
+ nextChildPos := children[i+1].Pos()
+ // Does [start, end) lie between child and next child?
+ if start >= augEnd && end <= nextChildPos {
+ return false // inexact match
+ }
+ augEnd = nextChildPos // end of following whitespace
+ }
+
+ // fmt.Printf("\tchild %d: [%d..%d)\tcontains interval [%d..%d)?\n",
+ // i, augPos, augEnd, start, end) // debugging
+
+ // Does augmented child strictly contain [start, end)?
+ if augPos <= start && end <= augEnd {
+ _, isToken := child.(tokenNode)
+ return isToken || visit(child)
+ }
+
+ // Does [start, end) overlap multiple children?
+ // i.e. left-augmented child contains start
+ // but LR-augmented child does not contain end.
+ if start < childEnd && end > augEnd {
+ break
+ }
+ }
+
+ // No single child contained [start, end),
+ // so node is the result. Is it exact?
+
+ // (It's tempting to put this condition before the
+ // child loop, but it gives the wrong result in the
+ // case where a node (e.g. ExprStmt) and its sole
+ // child have equal intervals.)
+ if start == nodePos && end == nodeEnd {
+ return true // exact match
+ }
+
+ return false // inexact: overlaps multiple children
+ }
+
+ if start > end {
+ start, end = end, start
+ }
+
+ if start < root.End() && end > root.Pos() {
+ if start == end {
+ end = start + 1 // empty interval => interval of size 1
+ }
+ exact = visit(root)
+
+ // Reverse the path:
+ for i, l := 0, len(path); i < l/2; i++ {
+ path[i], path[l-1-i] = path[l-1-i], path[i]
+ }
+ } else {
+ // Selection lies within whitespace preceding the
+ // first (or following the last) declaration in the file.
+ // The result nonetheless always includes the ast.File.
+ path = append(path, root)
+ }
+
+ return
+}
+
+// tokenNode is a dummy implementation of ast.Node for a single token.
+// They are used transiently by PathEnclosingInterval but never escape
+// this package.
+//
+type tokenNode struct {
+ pos token.Pos
+ end token.Pos
+}
+
+func (n tokenNode) Pos() token.Pos {
+ return n.pos
+}
+
+func (n tokenNode) End() token.Pos {
+ return n.end
+}
+
+func tok(pos token.Pos, len int) ast.Node {
+ return tokenNode{pos, pos + token.Pos(len)}
+}
+
+// childrenOf returns the direct non-nil children of ast.Node n.
+// It may include fake ast.Node implementations for bare tokens.
+// it is not safe to call (e.g.) ast.Walk on such nodes.
+//
+func childrenOf(n ast.Node) []ast.Node {
+ var children []ast.Node
+
+ // First add nodes for all true subtrees.
+ ast.Inspect(n, func(node ast.Node) bool {
+ if node == n { // push n
+ return true // recur
+ }
+ if node != nil { // push child
+ children = append(children, node)
+ }
+ return false // no recursion
+ })
+
+ // Then add fake Nodes for bare tokens.
+ switch n := n.(type) {
+ case *ast.ArrayType:
+ children = append(children,
+ tok(n.Lbrack, len("[")),
+ tok(n.Elt.End(), len("]")))
+
+ case *ast.AssignStmt:
+ children = append(children,
+ tok(n.TokPos, len(n.Tok.String())))
+
+ case *ast.BasicLit:
+ children = append(children,
+ tok(n.ValuePos, len(n.Value)))
+
+ case *ast.BinaryExpr:
+ children = append(children, tok(n.OpPos, len(n.Op.String())))
+
+ case *ast.BlockStmt:
+ children = append(children,
+ tok(n.Lbrace, len("{")),
+ tok(n.Rbrace, len("}")))
+
+ case *ast.BranchStmt:
+ children = append(children,
+ tok(n.TokPos, len(n.Tok.String())))
+
+ case *ast.CallExpr:
+ children = append(children,
+ tok(n.Lparen, len("(")),
+ tok(n.Rparen, len(")")))
+ if n.Ellipsis != 0 {
+ children = append(children, tok(n.Ellipsis, len("...")))
+ }
+
+ case *ast.CaseClause:
+ if n.List == nil {
+ children = append(children,
+ tok(n.Case, len("default")))
+ } else {
+ children = append(children,
+ tok(n.Case, len("case")))
+ }
+ children = append(children, tok(n.Colon, len(":")))
+
+ case *ast.ChanType:
+ switch n.Dir {
+ case ast.RECV:
+ children = append(children, tok(n.Begin, len("<-chan")))
+ case ast.SEND:
+ children = append(children, tok(n.Begin, len("chan<-")))
+ case ast.RECV | ast.SEND:
+ children = append(children, tok(n.Begin, len("chan")))
+ }
+
+ case *ast.CommClause:
+ if n.Comm == nil {
+ children = append(children,
+ tok(n.Case, len("default")))
+ } else {
+ children = append(children,
+ tok(n.Case, len("case")))
+ }
+ children = append(children, tok(n.Colon, len(":")))
+
+ case *ast.Comment:
+ // nop
+
+ case *ast.CommentGroup:
+ // nop
+
+ case *ast.CompositeLit:
+ children = append(children,
+ tok(n.Lbrace, len("{")),
+ tok(n.Rbrace, len("{")))
+
+ case *ast.DeclStmt:
+ // nop
+
+ case *ast.DeferStmt:
+ children = append(children,
+ tok(n.Defer, len("defer")))
+
+ case *ast.Ellipsis:
+ children = append(children,
+ tok(n.Ellipsis, len("...")))
+
+ case *ast.EmptyStmt:
+ // nop
+
+ case *ast.ExprStmt:
+ // nop
+
+ case *ast.Field:
+ // TODO(adonovan): Field.{Doc,Comment,Tag}?
+
+ case *ast.FieldList:
+ children = append(children,
+ tok(n.Opening, len("(")),
+ tok(n.Closing, len(")")))
+
+ case *ast.File:
+ // TODO test: Doc
+ children = append(children,
+ tok(n.Package, len("package")))
+
+ case *ast.ForStmt:
+ children = append(children,
+ tok(n.For, len("for")))
+
+ case *ast.FuncDecl:
+ // TODO(adonovan): FuncDecl.Comment?
+
+ // Uniquely, FuncDecl breaks the invariant that
+ // preorder traversal yields tokens in lexical order:
+ // in fact, FuncDecl.Recv precedes FuncDecl.Type.Func.
+ //
+ // As a workaround, we inline the case for FuncType
+ // here and order things correctly.
+ //
+ children = nil // discard ast.Walk(FuncDecl) info subtrees
+ children = append(children, tok(n.Type.Func, len("func")))
+ if n.Recv != nil {
+ children = append(children, n.Recv)
+ }
+ children = append(children, n.Name)
+ if n.Type.Params != nil {
+ children = append(children, n.Type.Params)
+ }
+ if n.Type.Results != nil {
+ children = append(children, n.Type.Results)
+ }
+ if n.Body != nil {
+ children = append(children, n.Body)
+ }
+
+ case *ast.FuncLit:
+ // nop
+
+ case *ast.FuncType:
+ if n.Func != 0 {
+ children = append(children,
+ tok(n.Func, len("func")))
+ }
+
+ case *ast.GenDecl:
+ children = append(children,
+ tok(n.TokPos, len(n.Tok.String())))
+ if n.Lparen != 0 {
+ children = append(children,
+ tok(n.Lparen, len("(")),
+ tok(n.Rparen, len(")")))
+ }
+
+ case *ast.GoStmt:
+ children = append(children,
+ tok(n.Go, len("go")))
+
+ case *ast.Ident:
+ children = append(children,
+ tok(n.NamePos, len(n.Name)))
+
+ case *ast.IfStmt:
+ children = append(children,
+ tok(n.If, len("if")))
+
+ case *ast.ImportSpec:
+ // TODO(adonovan): ImportSpec.{Doc,EndPos}?
+
+ case *ast.IncDecStmt:
+ children = append(children,
+ tok(n.TokPos, len(n.Tok.String())))
+
+ case *ast.IndexExpr:
+ children = append(children,
+ tok(n.Lbrack, len("{")),
+ tok(n.Rbrack, len("}")))
+
+ case *ast.InterfaceType:
+ children = append(children,
+ tok(n.Interface, len("interface")))
+
+ case *ast.KeyValueExpr:
+ children = append(children,
+ tok(n.Colon, len(":")))
+
+ case *ast.LabeledStmt:
+ children = append(children,
+ tok(n.Colon, len(":")))
+
+ case *ast.MapType:
+ children = append(children,
+ tok(n.Map, len("map")))
+
+ case *ast.ParenExpr:
+ children = append(children,
+ tok(n.Lparen, len("(")),
+ tok(n.Rparen, len(")")))
+
+ case *ast.RangeStmt:
+ children = append(children,
+ tok(n.For, len("for")),
+ tok(n.TokPos, len(n.Tok.String())))
+
+ case *ast.ReturnStmt:
+ children = append(children,
+ tok(n.Return, len("return")))
+
+ case *ast.SelectStmt:
+ children = append(children,
+ tok(n.Select, len("select")))
+
+ case *ast.SelectorExpr:
+ // nop
+
+ case *ast.SendStmt:
+ children = append(children,
+ tok(n.Arrow, len("<-")))
+
+ case *ast.SliceExpr:
+ children = append(children,
+ tok(n.Lbrack, len("[")),
+ tok(n.Rbrack, len("]")))
+
+ case *ast.StarExpr:
+ children = append(children, tok(n.Star, len("*")))
+
+ case *ast.StructType:
+ children = append(children, tok(n.Struct, len("struct")))
+
+ case *ast.SwitchStmt:
+ children = append(children, tok(n.Switch, len("switch")))
+
+ case *ast.TypeAssertExpr:
+ children = append(children,
+ tok(n.Lparen-1, len(".")),
+ tok(n.Lparen, len("(")),
+ tok(n.Rparen, len(")")))
+
+ case *ast.TypeSpec:
+ // TODO(adonovan): TypeSpec.{Doc,Comment}?
+
+ case *ast.TypeSwitchStmt:
+ children = append(children, tok(n.Switch, len("switch")))
+
+ case *ast.UnaryExpr:
+ children = append(children, tok(n.OpPos, len(n.Op.String())))
+
+ case *ast.ValueSpec:
+ // TODO(adonovan): ValueSpec.{Doc,Comment}?
+
+ default:
+ // Includes *ast.BadDecl, *ast.BadExpr, *ast.BadStmt.
+ panic(fmt.Sprintf("unexpected node type %T", n))
+ }
+
+ // TODO(adonovan): opt: merge the logic of ast.Inspect() into
+ // the switch above so we can make interleaved callbacks for
+ // both Nodes and Tokens in the right order and avoid the need
+ // to sort.
+ sort.Sort(byPos(children))
+
+ return children
+}
+
+type byPos []ast.Node
+
+func (sl byPos) Len() int {
+ return len(sl)
+}
+func (sl byPos) Less(i, j int) bool {
+ return sl[i].Pos() < sl[j].Pos()
+}
+func (sl byPos) Swap(i, j int) {
+ sl[i], sl[j] = sl[j], sl[i]
+}
+
+// NodeDescription returns a description of the concrete type of n suitable
+// for a user interface.
+//
+// TODO(adonovan): in some cases (e.g. Field, FieldList, Ident,
+// StarExpr) we could be much more specific given the path to the AST
+// root. Perhaps we should do that.
+//
+func NodeDescription(n ast.Node) string {
+ switch n := n.(type) {
+ case *ast.ArrayType:
+ return "array type"
+ case *ast.AssignStmt:
+ return "assignment"
+ case *ast.BadDecl:
+ return "bad declaration"
+ case *ast.BadExpr:
+ return "bad expression"
+ case *ast.BadStmt:
+ return "bad statement"
+ case *ast.BasicLit:
+ return "basic literal"
+ case *ast.BinaryExpr:
+ return fmt.Sprintf("binary %s operation", n.Op)
+ case *ast.BlockStmt:
+ return "block"
+ case *ast.BranchStmt:
+ switch n.Tok {
+ case token.BREAK:
+ return "break statement"
+ case token.CONTINUE:
+ return "continue statement"
+ case token.GOTO:
+ return "goto statement"
+ case token.FALLTHROUGH:
+ return "fall-through statement"
+ }
+ case *ast.CallExpr:
+ return "function call (or conversion)"
+ case *ast.CaseClause:
+ return "case clause"
+ case *ast.ChanType:
+ return "channel type"
+ case *ast.CommClause:
+ return "communication clause"
+ case *ast.Comment:
+ return "comment"
+ case *ast.CommentGroup:
+ return "comment group"
+ case *ast.CompositeLit:
+ return "composite literal"
+ case *ast.DeclStmt:
+ return NodeDescription(n.Decl) + " statement"
+ case *ast.DeferStmt:
+ return "defer statement"
+ case *ast.Ellipsis:
+ return "ellipsis"
+ case *ast.EmptyStmt:
+ return "empty statement"
+ case *ast.ExprStmt:
+ return "expression statement"
+ case *ast.Field:
+ // Can be any of these:
+ // struct {x, y int} -- struct field(s)
+ // struct {T} -- anon struct field
+ // interface {I} -- interface embedding
+ // interface {f()} -- interface method
+ // func (A) func(B) C -- receiver, param(s), result(s)
+ return "field/method/parameter"
+ case *ast.FieldList:
+ return "field/method/parameter list"
+ case *ast.File:
+ return "source file"
+ case *ast.ForStmt:
+ return "for loop"
+ case *ast.FuncDecl:
+ return "function declaration"
+ case *ast.FuncLit:
+ return "function literal"
+ case *ast.FuncType:
+ return "function type"
+ case *ast.GenDecl:
+ switch n.Tok {
+ case token.IMPORT:
+ return "import declaration"
+ case token.CONST:
+ return "constant declaration"
+ case token.TYPE:
+ return "type declaration"
+ case token.VAR:
+ return "variable declaration"
+ }
+ case *ast.GoStmt:
+ return "go statement"
+ case *ast.Ident:
+ return "identifier"
+ case *ast.IfStmt:
+ return "if statement"
+ case *ast.ImportSpec:
+ return "import specification"
+ case *ast.IncDecStmt:
+ if n.Tok == token.INC {
+ return "increment statement"
+ }
+ return "decrement statement"
+ case *ast.IndexExpr:
+ return "index expression"
+ case *ast.InterfaceType:
+ return "interface type"
+ case *ast.KeyValueExpr:
+ return "key/value association"
+ case *ast.LabeledStmt:
+ return "statement label"
+ case *ast.MapType:
+ return "map type"
+ case *ast.Package:
+ return "package"
+ case *ast.ParenExpr:
+ return "parenthesized " + NodeDescription(n.X)
+ case *ast.RangeStmt:
+ return "range loop"
+ case *ast.ReturnStmt:
+ return "return statement"
+ case *ast.SelectStmt:
+ return "select statement"
+ case *ast.SelectorExpr:
+ return "selector"
+ case *ast.SendStmt:
+ return "channel send"
+ case *ast.SliceExpr:
+ return "slice expression"
+ case *ast.StarExpr:
+ return "*-operation" // load/store expr or pointer type
+ case *ast.StructType:
+ return "struct type"
+ case *ast.SwitchStmt:
+ return "switch statement"
+ case *ast.TypeAssertExpr:
+ return "type assertion"
+ case *ast.TypeSpec:
+ return "type specification"
+ case *ast.TypeSwitchStmt:
+ return "type switch"
+ case *ast.UnaryExpr:
+ return fmt.Sprintf("unary %s operation", n.Op)
+ case *ast.ValueSpec:
+ return "value specification"
+
+ }
+ panic(fmt.Sprintf("unexpected node type: %T", n))
+}
diff --git a/vendor/golang.org/x/tools/go/ast/astutil/imports.go b/vendor/golang.org/x/tools/go/ast/astutil/imports.go
new file mode 100644
index 0000000..7f9b162
--- /dev/null
+++ b/vendor/golang.org/x/tools/go/ast/astutil/imports.go
@@ -0,0 +1,359 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package astutil contains common utilities for working with the Go AST.
+package astutil // import "golang.org/x/tools/go/ast/astutil"
+
+import (
+ "fmt"
+ "go/ast"
+ "go/token"
+ "strconv"
+ "strings"
+)
+
+// AddImport adds the import path to the file f, if absent.
+func AddImport(fset *token.FileSet, f *ast.File, ipath string) (added bool) {
+ return AddNamedImport(fset, f, "", ipath)
+}
+
+// AddNamedImport adds the import path to the file f, if absent.
+// If name is not empty, it is used to rename the import.
+//
+// For example, calling
+// AddNamedImport(fset, f, "pathpkg", "path")
+// adds
+// import pathpkg "path"
+func AddNamedImport(fset *token.FileSet, f *ast.File, name, ipath string) (added bool) {
+ if imports(f, ipath) {
+ return false
+ }
+
+ newImport := &ast.ImportSpec{
+ Path: &ast.BasicLit{
+ Kind: token.STRING,
+ Value: strconv.Quote(ipath),
+ },
+ }
+ if name != "" {
+ newImport.Name = &ast.Ident{Name: name}
+ }
+
+ // Find an import decl to add to.
+ // The goal is to find an existing import
+ // whose import path has the longest shared
+ // prefix with ipath.
+ var (
+ bestMatch = -1 // length of longest shared prefix
+ lastImport = -1 // index in f.Decls of the file's final import decl
+ impDecl *ast.GenDecl // import decl containing the best match
+ impIndex = -1 // spec index in impDecl containing the best match
+ )
+ for i, decl := range f.Decls {
+ gen, ok := decl.(*ast.GenDecl)
+ if ok && gen.Tok == token.IMPORT {
+ lastImport = i
+ // Do not add to import "C", to avoid disrupting the
+ // association with its doc comment, breaking cgo.
+ if declImports(gen, "C") {
+ continue
+ }
+
+ // Match an empty import decl if that's all that is available.
+ if len(gen.Specs) == 0 && bestMatch == -1 {
+ impDecl = gen
+ }
+
+ // Compute longest shared prefix with imports in this group.
+ for j, spec := range gen.Specs {
+ impspec := spec.(*ast.ImportSpec)
+ n := matchLen(importPath(impspec), ipath)
+ if n > bestMatch {
+ bestMatch = n
+ impDecl = gen
+ impIndex = j
+ }
+ }
+ }
+ }
+
+ // If no import decl found, add one after the last import.
+ if impDecl == nil {
+ impDecl = &ast.GenDecl{
+ Tok: token.IMPORT,
+ }
+ if lastImport >= 0 {
+ impDecl.TokPos = f.Decls[lastImport].End()
+ } else {
+ // There are no existing imports.
+ // Our new import goes after the package declaration and after
+ // the comment, if any, that starts on the same line as the
+ // package declaration.
+ impDecl.TokPos = f.Package
+
+ file := fset.File(f.Package)
+ pkgLine := file.Line(f.Package)
+ for _, c := range f.Comments {
+ if file.Line(c.Pos()) > pkgLine {
+ break
+ }
+ impDecl.TokPos = c.End()
+ }
+ }
+ f.Decls = append(f.Decls, nil)
+ copy(f.Decls[lastImport+2:], f.Decls[lastImport+1:])
+ f.Decls[lastImport+1] = impDecl
+ }
+
+ // Insert new import at insertAt.
+ insertAt := 0
+ if impIndex >= 0 {
+ // insert after the found import
+ insertAt = impIndex + 1
+ }
+ impDecl.Specs = append(impDecl.Specs, nil)
+ copy(impDecl.Specs[insertAt+1:], impDecl.Specs[insertAt:])
+ impDecl.Specs[insertAt] = newImport
+ pos := impDecl.Pos()
+ if insertAt > 0 {
+ // Assign same position as the previous import,
+ // so that the sorter sees it as being in the same block.
+ pos = impDecl.Specs[insertAt-1].Pos()
+ }
+ if newImport.Name != nil {
+ newImport.Name.NamePos = pos
+ }
+ newImport.Path.ValuePos = pos
+ newImport.EndPos = pos
+
+ // Clean up parens. impDecl contains at least one spec.
+ if len(impDecl.Specs) == 1 {
+ // Remove unneeded parens.
+ impDecl.Lparen = token.NoPos
+ } else if !impDecl.Lparen.IsValid() {
+ // impDecl needs parens added.
+ impDecl.Lparen = impDecl.Specs[0].Pos()
+ }
+
+ f.Imports = append(f.Imports, newImport)
+ return true
+}
+
+// DeleteImport deletes the import path from the file f, if present.
+func DeleteImport(fset *token.FileSet, f *ast.File, path string) (deleted bool) {
+ var delspecs []*ast.ImportSpec
+
+ // Find the import nodes that import path, if any.
+ for i := 0; i < len(f.Decls); i++ {
+ decl := f.Decls[i]
+ gen, ok := decl.(*ast.GenDecl)
+ if !ok || gen.Tok != token.IMPORT {
+ continue
+ }
+ for j := 0; j < len(gen.Specs); j++ {
+ spec := gen.Specs[j]
+ impspec := spec.(*ast.ImportSpec)
+ if importPath(impspec) != path {
+ continue
+ }
+
+ // We found an import spec that imports path.
+ // Delete it.
+ delspecs = append(delspecs, impspec)
+ deleted = true
+ copy(gen.Specs[j:], gen.Specs[j+1:])
+ gen.Specs = gen.Specs[:len(gen.Specs)-1]
+
+ // If this was the last import spec in this decl,
+ // delete the decl, too.
+ if len(gen.Specs) == 0 {
+ copy(f.Decls[i:], f.Decls[i+1:])
+ f.Decls = f.Decls[:len(f.Decls)-1]
+ i--
+ break
+ } else if len(gen.Specs) == 1 {
+ gen.Lparen = token.NoPos // drop parens
+ }
+ if j > 0 {
+ lastImpspec := gen.Specs[j-1].(*ast.ImportSpec)
+ lastLine := fset.Position(lastImpspec.Path.ValuePos).Line
+ line := fset.Position(impspec.Path.ValuePos).Line
+
+ // We deleted an entry but now there may be
+ // a blank line-sized hole where the import was.
+ if line-lastLine > 1 {
+ // There was a blank line immediately preceding the deleted import,
+ // so there's no need to close the hole.
+ // Do nothing.
+ } else {
+ // There was no blank line. Close the hole.
+ fset.File(gen.Rparen).MergeLine(line)
+ }
+ }
+ j--
+ }
+ }
+
+ // Delete them from f.Imports.
+ for i := 0; i < len(f.Imports); i++ {
+ imp := f.Imports[i]
+ for j, del := range delspecs {
+ if imp == del {
+ copy(f.Imports[i:], f.Imports[i+1:])
+ f.Imports = f.Imports[:len(f.Imports)-1]
+ copy(delspecs[j:], delspecs[j+1:])
+ delspecs = delspecs[:len(delspecs)-1]
+ i--
+ break
+ }
+ }
+ }
+
+ if len(delspecs) > 0 {
+ panic(fmt.Sprintf("deleted specs from Decls but not Imports: %v", delspecs))
+ }
+
+ return
+}
+
+// RewriteImport rewrites any import of path oldPath to path newPath.
+func RewriteImport(fset *token.FileSet, f *ast.File, oldPath, newPath string) (rewrote bool) {
+ for _, imp := range f.Imports {
+ if importPath(imp) == oldPath {
+ rewrote = true
+ // record old End, because the default is to compute
+ // it using the length of imp.Path.Value.
+ imp.EndPos = imp.End()
+ imp.Path.Value = strconv.Quote(newPath)
+ }
+ }
+ return
+}
+
+// UsesImport reports whether a given import is used.
+func UsesImport(f *ast.File, path string) (used bool) {
+ spec := importSpec(f, path)
+ if spec == nil {
+ return
+ }
+
+ name := spec.Name.String()
+ switch name {
+ case "":
+ // If the package name is not explicitly specified,
+ // make an educated guess. This is not guaranteed to be correct.
+ lastSlash := strings.LastIndex(path, "/")
+ if lastSlash == -1 {
+ name = path
+ } else {
+ name = path[lastSlash+1:]
+ }
+ case "_", ".":
+ // Not sure if this import is used - err on the side of caution.
+ return true
+ }
+
+ ast.Walk(visitFn(func(n ast.Node) {
+ sel, ok := n.(*ast.SelectorExpr)
+ if ok && isTopName(sel.X, name) {
+ used = true
+ }
+ }), f)
+
+ return
+}
+
+type visitFn func(node ast.Node)
+
+func (fn visitFn) Visit(node ast.Node) ast.Visitor {
+ fn(node)
+ return fn
+}
+
+// imports returns true if f imports path.
+func imports(f *ast.File, path string) bool {
+ return importSpec(f, path) != nil
+}
+
+// importSpec returns the import spec if f imports path,
+// or nil otherwise.
+func importSpec(f *ast.File, path string) *ast.ImportSpec {
+ for _, s := range f.Imports {
+ if importPath(s) == path {
+ return s
+ }
+ }
+ return nil
+}
+
+// importPath returns the unquoted import path of s,
+// or "" if the path is not properly quoted.
+func importPath(s *ast.ImportSpec) string {
+ t, err := strconv.Unquote(s.Path.Value)
+ if err == nil {
+ return t
+ }
+ return ""
+}
+
+// declImports reports whether gen contains an import of path.
+func declImports(gen *ast.GenDecl, path string) bool {
+ if gen.Tok != token.IMPORT {
+ return false
+ }
+ for _, spec := range gen.Specs {
+ impspec := spec.(*ast.ImportSpec)
+ if importPath(impspec) == path {
+ return true
+ }
+ }
+ return false
+}
+
+// matchLen returns the length of the longest path segment prefix shared by x and y.
+func matchLen(x, y string) int {
+ n := 0
+ for i := 0; i < len(x) && i < len(y) && x[i] == y[i]; i++ {
+ if x[i] == '/' {
+ n++
+ }
+ }
+ return n
+}
+
+// isTopName returns true if n is a top-level unresolved identifier with the given name.
+func isTopName(n ast.Expr, name string) bool {
+ id, ok := n.(*ast.Ident)
+ return ok && id.Name == name && id.Obj == nil
+}
+
+// Imports returns the file imports grouped by paragraph.
+func Imports(fset *token.FileSet, f *ast.File) [][]*ast.ImportSpec {
+ var groups [][]*ast.ImportSpec
+
+ for _, decl := range f.Decls {
+ genDecl, ok := decl.(*ast.GenDecl)
+ if !ok || genDecl.Tok != token.IMPORT {
+ break
+ }
+
+ group := []*ast.ImportSpec{}
+
+ var lastLine int
+ for _, spec := range genDecl.Specs {
+ importSpec := spec.(*ast.ImportSpec)
+ pos := importSpec.Path.ValuePos
+ line := fset.Position(pos).Line
+ if lastLine > 0 && pos > 0 && line-lastLine > 1 {
+ groups = append(groups, group)
+ group = []*ast.ImportSpec{}
+ }
+ group = append(group, importSpec)
+ lastLine = line
+ }
+ groups = append(groups, group)
+ }
+
+ return groups
+}
diff --git a/vendor/golang.org/x/tools/go/ast/astutil/util.go b/vendor/golang.org/x/tools/go/ast/astutil/util.go
new file mode 100644
index 0000000..7630629
--- /dev/null
+++ b/vendor/golang.org/x/tools/go/ast/astutil/util.go
@@ -0,0 +1,14 @@
+package astutil
+
+import "go/ast"
+
+// Unparen returns e with any enclosing parentheses stripped.
+func Unparen(e ast.Expr) ast.Expr {
+ for {
+ p, ok := e.(*ast.ParenExpr)
+ if !ok {
+ return e
+ }
+ e = p.X
+ }
+}
diff --git a/vendor/golang.org/x/tools/go/buildutil/allpackages.go b/vendor/golang.org/x/tools/go/buildutil/allpackages.go
new file mode 100644
index 0000000..0f909ee
--- /dev/null
+++ b/vendor/golang.org/x/tools/go/buildutil/allpackages.go
@@ -0,0 +1,123 @@
+// Copyright 2014 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package buildutil provides utilities related to the go/build
+// package in the standard library.
+//
+// All I/O is done via the build.Context file system interface, which must
+// be concurrency-safe.
+package buildutil // import "golang.org/x/tools/go/buildutil"
+
+import (
+ "go/build"
+ "os"
+ "path/filepath"
+ "sort"
+ "strings"
+ "sync"
+)
+
+// AllPackages returns the import path of each Go package in any source
+// directory of the specified build context (e.g. $GOROOT or an element
+// of $GOPATH). Errors are ignored. The results are sorted.
+//
+// The result may include import paths for directories that contain no
+// *.go files, such as "archive" (in $GOROOT/src).
+//
+// All I/O is done via the build.Context file system interface,
+// which must be concurrency-safe.
+//
+func AllPackages(ctxt *build.Context) []string {
+ var list []string
+ ForEachPackage(ctxt, func(pkg string, _ error) {
+ list = append(list, pkg)
+ })
+ sort.Strings(list)
+ return list
+}
+
+// ForEachPackage calls the found function with the import path of
+// each Go package it finds in any source directory of the specified
+// build context (e.g. $GOROOT or an element of $GOPATH).
+//
+// If the package directory exists but could not be read, the second
+// argument to the found function provides the error.
+//
+// All I/O is done via the build.Context file system interface,
+// which must be concurrency-safe.
+//
+func ForEachPackage(ctxt *build.Context, found func(importPath string, err error)) {
+ // We use a counting semaphore to limit
+ // the number of parallel calls to ReadDir.
+ sema := make(chan bool, 20)
+
+ ch := make(chan item)
+
+ var wg sync.WaitGroup
+ for _, root := range ctxt.SrcDirs() {
+ root := root
+ wg.Add(1)
+ go func() {
+ allPackages(ctxt, sema, root, ch)
+ wg.Done()
+ }()
+ }
+ go func() {
+ wg.Wait()
+ close(ch)
+ }()
+
+ // All calls to found occur in the caller's goroutine.
+ for i := range ch {
+ found(i.importPath, i.err)
+ }
+}
+
+type item struct {
+ importPath string
+ err error // (optional)
+}
+
+func allPackages(ctxt *build.Context, sema chan bool, root string, ch chan<- item) {
+ root = filepath.Clean(root) + string(os.PathSeparator)
+
+ var wg sync.WaitGroup
+
+ var walkDir func(dir string)
+ walkDir = func(dir string) {
+ // Avoid .foo, _foo, and testdata directory trees.
+ base := filepath.Base(dir)
+ if base == "" || base[0] == '.' || base[0] == '_' || base == "testdata" {
+ return
+ }
+
+ pkg := filepath.ToSlash(strings.TrimPrefix(dir, root))
+
+ // Prune search if we encounter any of these import paths.
+ switch pkg {
+ case "builtin":
+ return
+ }
+
+ sema <- true
+ files, err := ReadDir(ctxt, dir)
+ <-sema
+ if pkg != "" || err != nil {
+ ch <- item{pkg, err}
+ }
+ for _, fi := range files {
+ fi := fi
+ if fi.IsDir() {
+ wg.Add(1)
+ go func() {
+ walkDir(filepath.Join(dir, fi.Name()))
+ wg.Done()
+ }()
+ }
+ }
+ }
+
+ walkDir(root)
+ wg.Wait()
+}
diff --git a/vendor/golang.org/x/tools/go/buildutil/fakecontext.go b/vendor/golang.org/x/tools/go/buildutil/fakecontext.go
new file mode 100644
index 0000000..24cbcbe
--- /dev/null
+++ b/vendor/golang.org/x/tools/go/buildutil/fakecontext.go
@@ -0,0 +1,108 @@
+package buildutil
+
+import (
+ "fmt"
+ "go/build"
+ "io"
+ "io/ioutil"
+ "os"
+ "path"
+ "path/filepath"
+ "sort"
+ "strings"
+ "time"
+)
+
+// FakeContext returns a build.Context for the fake file tree specified
+// by pkgs, which maps package import paths to a mapping from file base
+// names to contents.
+//
+// The fake Context has a GOROOT of "/go" and no GOPATH, and overrides
+// the necessary file access methods to read from memory instead of the
+// real file system.
+//
+// Unlike a real file tree, the fake one has only two levels---packages
+// and files---so ReadDir("/go/src/") returns all packages under
+// /go/src/ including, for instance, "math" and "math/big".
+// ReadDir("/go/src/math/big") would return all the files in the
+// "math/big" package.
+//
+func FakeContext(pkgs map[string]map[string]string) *build.Context {
+ clean := func(filename string) string {
+ f := path.Clean(filepath.ToSlash(filename))
+ // Removing "/go/src" while respecting segment
+ // boundaries has this unfortunate corner case:
+ if f == "/go/src" {
+ return ""
+ }
+ return strings.TrimPrefix(f, "/go/src/")
+ }
+
+ ctxt := build.Default // copy
+ ctxt.GOROOT = "/go"
+ ctxt.GOPATH = ""
+ ctxt.IsDir = func(dir string) bool {
+ dir = clean(dir)
+ if dir == "" {
+ return true // needed by (*build.Context).SrcDirs
+ }
+ return pkgs[dir] != nil
+ }
+ ctxt.ReadDir = func(dir string) ([]os.FileInfo, error) {
+ dir = clean(dir)
+ var fis []os.FileInfo
+ if dir == "" {
+ // enumerate packages
+ for importPath := range pkgs {
+ fis = append(fis, fakeDirInfo(importPath))
+ }
+ } else {
+ // enumerate files of package
+ for basename := range pkgs[dir] {
+ fis = append(fis, fakeFileInfo(basename))
+ }
+ }
+ sort.Sort(byName(fis))
+ return fis, nil
+ }
+ ctxt.OpenFile = func(filename string) (io.ReadCloser, error) {
+ filename = clean(filename)
+ dir, base := path.Split(filename)
+ content, ok := pkgs[path.Clean(dir)][base]
+ if !ok {
+ return nil, fmt.Errorf("file not found: %s", filename)
+ }
+ return ioutil.NopCloser(strings.NewReader(content)), nil
+ }
+ ctxt.IsAbsPath = func(path string) bool {
+ path = filepath.ToSlash(path)
+ // Don't rely on the default (filepath.Path) since on
+ // Windows, it reports virtual paths as non-absolute.
+ return strings.HasPrefix(path, "/")
+ }
+ return &ctxt
+}
+
+type byName []os.FileInfo
+
+func (s byName) Len() int { return len(s) }
+func (s byName) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
+func (s byName) Less(i, j int) bool { return s[i].Name() < s[j].Name() }
+
+type fakeFileInfo string
+
+func (fi fakeFileInfo) Name() string { return string(fi) }
+func (fakeFileInfo) Sys() interface{} { return nil }
+func (fakeFileInfo) ModTime() time.Time { return time.Time{} }
+func (fakeFileInfo) IsDir() bool { return false }
+func (fakeFileInfo) Size() int64 { return 0 }
+func (fakeFileInfo) Mode() os.FileMode { return 0644 }
+
+type fakeDirInfo string
+
+func (fd fakeDirInfo) Name() string { return string(fd) }
+func (fakeDirInfo) Sys() interface{} { return nil }
+func (fakeDirInfo) ModTime() time.Time { return time.Time{} }
+func (fakeDirInfo) IsDir() bool { return true }
+func (fakeDirInfo) Size() int64 { return 0 }
+func (fakeDirInfo) Mode() os.FileMode { return 0755 }
diff --git a/vendor/golang.org/x/tools/go/buildutil/tags.go b/vendor/golang.org/x/tools/go/buildutil/tags.go
new file mode 100644
index 0000000..9735094
--- /dev/null
+++ b/vendor/golang.org/x/tools/go/buildutil/tags.go
@@ -0,0 +1,73 @@
+package buildutil
+
+// This logic was copied from stringsFlag from $GOROOT/src/cmd/go/build.go.
+
+import "fmt"
+
+const TagsFlagDoc = "a list of `build tags` to consider satisfied during the build. " +
+ "For more information about build tags, see the description of " +
+ "build constraints in the documentation for the go/build package"
+
+// TagsFlag is an implementation of the flag.Value interface that parses
+// a flag value in the same manner as go build's -tags flag and
+// populates a []string slice.
+//
+// See $GOROOT/src/go/build/doc.go for description of build tags.
+// See $GOROOT/src/cmd/go/doc.go for description of 'go build -tags' flag.
+//
+// Example:
+// flag.Var((*buildutil.TagsFlag)(&build.Default.BuildTags), "tags", buildutil.TagsDoc)
+type TagsFlag []string
+
+func (v *TagsFlag) Set(s string) error {
+ var err error
+ *v, err = splitQuotedFields(s)
+ if *v == nil {
+ *v = []string{}
+ }
+ return err
+}
+
+func splitQuotedFields(s string) ([]string, error) {
+ // Split fields allowing '' or "" around elements.
+ // Quotes further inside the string do not count.
+ var f []string
+ for len(s) > 0 {
+ for len(s) > 0 && isSpaceByte(s[0]) {
+ s = s[1:]
+ }
+ if len(s) == 0 {
+ break
+ }
+ // Accepted quoted string. No unescaping inside.
+ if s[0] == '"' || s[0] == '\'' {
+ quote := s[0]
+ s = s[1:]
+ i := 0
+ for i < len(s) && s[i] != quote {
+ i++
+ }
+ if i >= len(s) {
+ return nil, fmt.Errorf("unterminated %c string", quote)
+ }
+ f = append(f, s[:i])
+ s = s[i+1:]
+ continue
+ }
+ i := 0
+ for i < len(s) && !isSpaceByte(s[i]) {
+ i++
+ }
+ f = append(f, s[:i])
+ s = s[i:]
+ }
+ return f, nil
+}
+
+func (v *TagsFlag) String() string {
+ return ""
+}
+
+func isSpaceByte(c byte) bool {
+ return c == ' ' || c == '\t' || c == '\n' || c == '\r'
+}
diff --git a/vendor/golang.org/x/tools/go/buildutil/util.go b/vendor/golang.org/x/tools/go/buildutil/util.go
new file mode 100644
index 0000000..60eeae2
--- /dev/null
+++ b/vendor/golang.org/x/tools/go/buildutil/util.go
@@ -0,0 +1,158 @@
+// Copyright 2014 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package buildutil
+
+import (
+ "fmt"
+ "go/ast"
+ "go/build"
+ "go/parser"
+ "go/token"
+ "io"
+ "io/ioutil"
+ "os"
+ "path"
+ "path/filepath"
+ "strings"
+)
+
+// ParseFile behaves like parser.ParseFile,
+// but uses the build context's file system interface, if any.
+//
+// If file is not absolute (as defined by IsAbsPath), the (dir, file)
+// components are joined using JoinPath; dir must be absolute.
+//
+// The displayPath function, if provided, is used to transform the
+// filename that will be attached to the ASTs.
+//
+// TODO(adonovan): call this from go/loader.parseFiles when the tree thaws.
+//
+func ParseFile(fset *token.FileSet, ctxt *build.Context, displayPath func(string) string, dir string, file string, mode parser.Mode) (*ast.File, error) {
+ if !IsAbsPath(ctxt, file) {
+ file = JoinPath(ctxt, dir, file)
+ }
+ rd, err := OpenFile(ctxt, file)
+ if err != nil {
+ return nil, err
+ }
+ defer rd.Close() // ignore error
+ if displayPath != nil {
+ file = displayPath(file)
+ }
+ return parser.ParseFile(fset, file, rd, mode)
+}
+
+// ContainingPackage returns the package containing filename.
+//
+// If filename is not absolute, it is interpreted relative to working directory dir.
+// All I/O is via the build context's file system interface, if any.
+//
+// The '...Files []string' fields of the resulting build.Package are not
+// populated (build.FindOnly mode).
+//
+// TODO(adonovan): call this from oracle when the tree thaws.
+//
+func ContainingPackage(ctxt *build.Context, dir, filename string) (*build.Package, error) {
+ if !IsAbsPath(ctxt, filename) {
+ filename = JoinPath(ctxt, dir, filename)
+ }
+
+ // We must not assume the file tree uses
+ // "/" always,
+ // `\` always,
+ // or os.PathSeparator (which varies by platform),
+ // but to make any progress, we are forced to assume that
+ // paths will not use `\` unless the PathSeparator
+ // is also `\`, thus we can rely on filepath.ToSlash for some sanity.
+
+ dirSlash := path.Dir(filepath.ToSlash(filename)) + "/"
+
+ // We assume that no source root (GOPATH[i] or GOROOT) contains any other.
+ for _, srcdir := range ctxt.SrcDirs() {
+ srcdirSlash := filepath.ToSlash(srcdir) + "/"
+ if strings.HasPrefix(dirSlash, srcdirSlash) {
+ importPath := dirSlash[len(srcdirSlash) : len(dirSlash)-len("/")]
+ return ctxt.Import(importPath, dir, build.FindOnly)
+ }
+ }
+
+ return nil, fmt.Errorf("can't find package containing %s", filename)
+}
+
+// -- Effective methods of file system interface -------------------------
+
+// (go/build.Context defines these as methods, but does not export them.)
+
+// TODO(adonovan): HasSubdir?
+
+// FileExists returns true if the specified file exists,
+// using the build context's file system interface.
+func FileExists(ctxt *build.Context, path string) bool {
+ if ctxt.OpenFile != nil {
+ r, err := ctxt.OpenFile(path)
+ if err != nil {
+ return false
+ }
+ r.Close() // ignore error
+ return true
+ }
+ _, err := os.Stat(path)
+ return err == nil
+}
+
+// OpenFile behaves like os.Open,
+// but uses the build context's file system interface, if any.
+func OpenFile(ctxt *build.Context, path string) (io.ReadCloser, error) {
+ if ctxt.OpenFile != nil {
+ return ctxt.OpenFile(path)
+ }
+ return os.Open(path)
+}
+
+// IsAbsPath behaves like filepath.IsAbs,
+// but uses the build context's file system interface, if any.
+func IsAbsPath(ctxt *build.Context, path string) bool {
+ if ctxt.IsAbsPath != nil {
+ return ctxt.IsAbsPath(path)
+ }
+ return filepath.IsAbs(path)
+}
+
+// JoinPath behaves like filepath.Join,
+// but uses the build context's file system interface, if any.
+func JoinPath(ctxt *build.Context, path ...string) string {
+ if ctxt.JoinPath != nil {
+ return ctxt.JoinPath(path...)
+ }
+ return filepath.Join(path...)
+}
+
+// IsDir behaves like os.Stat plus IsDir,
+// but uses the build context's file system interface, if any.
+func IsDir(ctxt *build.Context, path string) bool {
+ if ctxt.IsDir != nil {
+ return ctxt.IsDir(path)
+ }
+ fi, err := os.Stat(path)
+ return err == nil && fi.IsDir()
+}
+
+// ReadDir behaves like ioutil.ReadDir,
+// but uses the build context's file system interface, if any.
+func ReadDir(ctxt *build.Context, path string) ([]os.FileInfo, error) {
+ if ctxt.ReadDir != nil {
+ return ctxt.ReadDir(path)
+ }
+ return ioutil.ReadDir(path)
+}
+
+// SplitPathList behaves like filepath.SplitList,
+// but uses the build context's file system interface, if any.
+func SplitPathList(ctxt *build.Context, s string) []string {
+ if ctxt.SplitPathList != nil {
+ return ctxt.SplitPathList(s)
+ }
+ return filepath.SplitList(s)
+}
diff --git a/vendor/golang.org/x/tools/go/callgraph/callgraph.go b/vendor/golang.org/x/tools/go/callgraph/callgraph.go
new file mode 100644
index 0000000..707a319
--- /dev/null
+++ b/vendor/golang.org/x/tools/go/callgraph/callgraph.go
@@ -0,0 +1,129 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+/*
+
+Package callgraph defines the call graph and various algorithms
+and utilities to operate on it.
+
+A call graph is a labelled directed graph whose nodes represent
+functions and whose edge labels represent syntactic function call
+sites. The presence of a labelled edge (caller, site, callee)
+indicates that caller may call callee at the specified call site.
+
+A call graph is a multigraph: it may contain multiple edges (caller,
+*, callee) connecting the same pair of nodes, so long as the edges
+differ by label; this occurs when one function calls another function
+from multiple call sites. Also, it may contain multiple edges
+(caller, site, *) that differ only by callee; this indicates a
+polymorphic call.
+
+A SOUND call graph is one that overapproximates the dynamic calling
+behaviors of the program in all possible executions. One call graph
+is more PRECISE than another if it is a smaller overapproximation of
+the dynamic behavior.
+
+All call graphs have a synthetic root node which is responsible for
+calling main() and init().
+
+Calls to built-in functions (e.g. panic, println) are not represented
+in the call graph; they are treated like built-in operators of the
+language.
+
+*/
+package callgraph // import "golang.org/x/tools/go/callgraph"
+
+// TODO(adonovan): add a function to eliminate wrappers from the
+// callgraph, preserving topology.
+// More generally, we could eliminate "uninteresting" nodes such as
+// nodes from packages we don't care about.
+
+import (
+ "fmt"
+ "go/token"
+
+ "golang.org/x/tools/go/ssa"
+)
+
+// A Graph represents a call graph.
+//
+// A graph may contain nodes that are not reachable from the root.
+// If the call graph is sound, such nodes indicate unreachable
+// functions.
+//
+type Graph struct {
+ Root *Node // the distinguished root node
+ Nodes map[*ssa.Function]*Node // all nodes by function
+}
+
+// New returns a new Graph with the specified root node.
+func New(root *ssa.Function) *Graph {
+ g := &Graph{Nodes: make(map[*ssa.Function]*Node)}
+ g.Root = g.CreateNode(root)
+ return g
+}
+
+// CreateNode returns the Node for fn, creating it if not present.
+func (g *Graph) CreateNode(fn *ssa.Function) *Node {
+ n, ok := g.Nodes[fn]
+ if !ok {
+ n = &Node{Func: fn, ID: len(g.Nodes)}
+ g.Nodes[fn] = n
+ }
+ return n
+}
+
+// A Node represents a node in a call graph.
+type Node struct {
+ Func *ssa.Function // the function this node represents
+ ID int // 0-based sequence number
+ In []*Edge // unordered set of incoming call edges (n.In[*].Callee == n)
+ Out []*Edge // unordered set of outgoing call edges (n.Out[*].Caller == n)
+}
+
+func (n *Node) String() string {
+ return fmt.Sprintf("n%d:%s", n.ID, n.Func)
+}
+
+// A Edge represents an edge in the call graph.
+//
+// Site is nil for edges originating in synthetic or intrinsic
+// functions, e.g. reflect.Call or the root of the call graph.
+type Edge struct {
+ Caller *Node
+ Site ssa.CallInstruction
+ Callee *Node
+}
+
+func (e Edge) String() string {
+ return fmt.Sprintf("%s --> %s", e.Caller, e.Callee)
+}
+
+func (e Edge) Description() string {
+ var prefix string
+ switch e.Site.(type) {
+ case nil:
+ return "synthetic call"
+ case *ssa.Go:
+ prefix = "concurrent "
+ case *ssa.Defer:
+ prefix = "deferred "
+ }
+ return prefix + e.Site.Common().Description()
+}
+
+func (e Edge) Pos() token.Pos {
+ if e.Site == nil {
+ return token.NoPos
+ }
+ return e.Site.Pos()
+}
+
+// AddEdge adds the edge (caller, site, callee) to the call graph.
+// Elimination of duplicate edges is the caller's responsibility.
+func AddEdge(caller *Node, site ssa.CallInstruction, callee *Node) {
+ e := &Edge{caller, site, callee}
+ callee.In = append(callee.In, e)
+ caller.Out = append(caller.Out, e)
+}
diff --git a/vendor/golang.org/x/tools/go/callgraph/util.go b/vendor/golang.org/x/tools/go/callgraph/util.go
new file mode 100644
index 0000000..a8f8903
--- /dev/null
+++ b/vendor/golang.org/x/tools/go/callgraph/util.go
@@ -0,0 +1,181 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package callgraph
+
+import "golang.org/x/tools/go/ssa"
+
+// This file provides various utilities over call graphs, such as
+// visitation and path search.
+
+// CalleesOf returns a new set containing all direct callees of the
+// caller node.
+//
+func CalleesOf(caller *Node) map[*Node]bool {
+ callees := make(map[*Node]bool)
+ for _, e := range caller.Out {
+ callees[e.Callee] = true
+ }
+ return callees
+}
+
+// GraphVisitEdges visits all the edges in graph g in depth-first order.
+// The edge function is called for each edge in postorder. If it
+// returns non-nil, visitation stops and GraphVisitEdges returns that
+// value.
+//
+func GraphVisitEdges(g *Graph, edge func(*Edge) error) error {
+ seen := make(map[*Node]bool)
+ var visit func(n *Node) error
+ visit = func(n *Node) error {
+ if !seen[n] {
+ seen[n] = true
+ for _, e := range n.Out {
+ if err := visit(e.Callee); err != nil {
+ return err
+ }
+ if err := edge(e); err != nil {
+ return err
+ }
+ }
+ }
+ return nil
+ }
+ for _, n := range g.Nodes {
+ if err := visit(n); err != nil {
+ return err
+ }
+ }
+ return nil
+}
+
+// PathSearch finds an arbitrary path starting at node start and
+// ending at some node for which isEnd() returns true. On success,
+// PathSearch returns the path as an ordered list of edges; on
+// failure, it returns nil.
+//
+func PathSearch(start *Node, isEnd func(*Node) bool) []*Edge {
+ stack := make([]*Edge, 0, 32)
+ seen := make(map[*Node]bool)
+ var search func(n *Node) []*Edge
+ search = func(n *Node) []*Edge {
+ if !seen[n] {
+ seen[n] = true
+ if isEnd(n) {
+ return stack
+ }
+ for _, e := range n.Out {
+ stack = append(stack, e) // push
+ if found := search(e.Callee); found != nil {
+ return found
+ }
+ stack = stack[:len(stack)-1] // pop
+ }
+ }
+ return nil
+ }
+ return search(start)
+}
+
+// DeleteSyntheticNodes removes from call graph g all nodes for
+// synthetic functions (except g.Root and package initializers),
+// preserving the topology. In effect, calls to synthetic wrappers
+// are "inlined".
+//
+func (g *Graph) DeleteSyntheticNodes() {
+ // Measurements on the standard library and go.tools show that
+ // resulting graph has ~15% fewer nodes and 4-8% fewer edges
+ // than the input.
+ //
+ // Inlining a wrapper of in-degree m, out-degree n adds m*n
+ // and removes m+n edges. Since most wrappers are monomorphic
+ // (n=1) this results in a slight reduction. Polymorphic
+ // wrappers (n>1), e.g. from embedding an interface value
+ // inside a struct to satisfy some interface, cause an
+ // increase in the graph, but they seem to be uncommon.
+
+ // Hash all existing edges to avoid creating duplicates.
+ edges := make(map[Edge]bool)
+ for _, cgn := range g.Nodes {
+ for _, e := range cgn.Out {
+ edges[*e] = true
+ }
+ }
+ for fn, cgn := range g.Nodes {
+ if cgn == g.Root || fn.Synthetic == "" || isInit(cgn.Func) {
+ continue // keep
+ }
+ for _, eIn := range cgn.In {
+ for _, eOut := range cgn.Out {
+ newEdge := Edge{eIn.Caller, eIn.Site, eOut.Callee}
+ if edges[newEdge] {
+ continue // don't add duplicate
+ }
+ AddEdge(eIn.Caller, eIn.Site, eOut.Callee)
+ edges[newEdge] = true
+ }
+ }
+ g.DeleteNode(cgn)
+ }
+}
+
+func isInit(fn *ssa.Function) bool {
+ return fn.Pkg != nil && fn.Pkg.Func("init") == fn
+}
+
+// DeleteNode removes node n and its edges from the graph g.
+// (NB: not efficient for batch deletion.)
+func (g *Graph) DeleteNode(n *Node) {
+ n.deleteIns()
+ n.deleteOuts()
+ delete(g.Nodes, n.Func)
+}
+
+// deleteIns deletes all incoming edges to n.
+func (n *Node) deleteIns() {
+ for _, e := range n.In {
+ removeOutEdge(e)
+ }
+ n.In = nil
+}
+
+// deleteOuts deletes all outgoing edges from n.
+func (n *Node) deleteOuts() {
+ for _, e := range n.Out {
+ removeInEdge(e)
+ }
+ n.Out = nil
+}
+
+// removeOutEdge removes edge.Caller's outgoing edge 'edge'.
+func removeOutEdge(edge *Edge) {
+ caller := edge.Caller
+ n := len(caller.Out)
+ for i, e := range caller.Out {
+ if e == edge {
+ // Replace it with the final element and shrink the slice.
+ caller.Out[i] = caller.Out[n-1]
+ caller.Out[n-1] = nil // aid GC
+ caller.Out = caller.Out[:n-1]
+ return
+ }
+ }
+ panic("edge not found: " + edge.String())
+}
+
+// removeInEdge removes edge.Callee's incoming edge 'edge'.
+func removeInEdge(edge *Edge) {
+ caller := edge.Callee
+ n := len(caller.In)
+ for i, e := range caller.In {
+ if e == edge {
+ // Replace it with the final element and shrink the slice.
+ caller.In[i] = caller.In[n-1]
+ caller.In[n-1] = nil // aid GC
+ caller.In = caller.In[:n-1]
+ return
+ }
+ }
+ panic("edge not found: " + edge.String())
+}
diff --git a/vendor/golang.org/x/tools/go/exact/exact.go b/vendor/golang.org/x/tools/go/exact/exact.go
new file mode 100644
index 0000000..51c4906
--- /dev/null
+++ b/vendor/golang.org/x/tools/go/exact/exact.go
@@ -0,0 +1,920 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package exact implements Values representing untyped
+// Go constants and the corresponding operations. Values
+// and operations have unlimited precision.
+//
+// A special Unknown value may be used when a value
+// is unknown due to an error. Operations on unknown
+// values produce unknown values unless specified
+// otherwise.
+//
+package exact // import "golang.org/x/tools/go/exact"
+
+import (
+ "fmt"
+ "go/token"
+ "math/big"
+ "strconv"
+)
+
+// Kind specifies the kind of value represented by a Value.
+type Kind int
+
+// Implementation note: Kinds must be enumerated in
+// order of increasing "complexity" (used by match).
+
+const (
+ // unknown values
+ Unknown Kind = iota
+
+ // non-numeric values
+ Bool
+ String
+
+ // numeric values
+ Int
+ Float
+ Complex
+)
+
+// A Value represents a mathematically exact value of a given Kind.
+type Value interface {
+ // Kind returns the value kind; it is always the smallest
+ // kind in which the value can be represented exactly.
+ Kind() Kind
+
+ // String returns a human-readable form of the value.
+ String() string
+
+ // Prevent external implementations.
+ implementsValue()
+}
+
+// ----------------------------------------------------------------------------
+// Implementations
+
+type (
+ unknownVal struct{}
+ boolVal bool
+ stringVal string
+ int64Val int64
+ intVal struct{ val *big.Int }
+ floatVal struct{ val *big.Rat }
+ complexVal struct{ re, im *big.Rat }
+)
+
+func (unknownVal) Kind() Kind { return Unknown }
+func (boolVal) Kind() Kind { return Bool }
+func (stringVal) Kind() Kind { return String }
+func (int64Val) Kind() Kind { return Int }
+func (intVal) Kind() Kind { return Int }
+func (floatVal) Kind() Kind { return Float }
+func (complexVal) Kind() Kind { return Complex }
+
+func (unknownVal) String() string { return "unknown" }
+func (x boolVal) String() string { return fmt.Sprintf("%v", bool(x)) }
+func (x stringVal) String() string { return strconv.Quote(string(x)) }
+func (x int64Val) String() string { return strconv.FormatInt(int64(x), 10) }
+func (x intVal) String() string { return x.val.String() }
+func (x floatVal) String() string { return x.val.String() }
+func (x complexVal) String() string { return fmt.Sprintf("(%s + %si)", x.re, x.im) }
+
+func (unknownVal) implementsValue() {}
+func (boolVal) implementsValue() {}
+func (stringVal) implementsValue() {}
+func (int64Val) implementsValue() {}
+func (intVal) implementsValue() {}
+func (floatVal) implementsValue() {}
+func (complexVal) implementsValue() {}
+
+// int64 bounds
+var (
+ minInt64 = big.NewInt(-1 << 63)
+ maxInt64 = big.NewInt(1<<63 - 1)
+)
+
+func normInt(x *big.Int) Value {
+ if minInt64.Cmp(x) <= 0 && x.Cmp(maxInt64) <= 0 {
+ return int64Val(x.Int64())
+ }
+ return intVal{x}
+}
+
+func normFloat(x *big.Rat) Value {
+ if x.IsInt() {
+ return normInt(x.Num())
+ }
+ return floatVal{x}
+}
+
+func normComplex(re, im *big.Rat) Value {
+ if im.Sign() == 0 {
+ return normFloat(re)
+ }
+ return complexVal{re, im}
+}
+
+// ----------------------------------------------------------------------------
+// Factories
+
+// MakeUnknown returns the Unknown value.
+func MakeUnknown() Value { return unknownVal{} }
+
+// MakeBool returns the Bool value for x.
+func MakeBool(b bool) Value { return boolVal(b) }
+
+// MakeString returns the String value for x.
+func MakeString(s string) Value { return stringVal(s) }
+
+// MakeInt64 returns the Int value for x.
+func MakeInt64(x int64) Value { return int64Val(x) }
+
+// MakeUint64 returns the Int value for x.
+func MakeUint64(x uint64) Value { return normInt(new(big.Int).SetUint64(x)) }
+
+// MakeFloat64 returns the numeric value for x.
+// If x is not finite, the result is unknown.
+func MakeFloat64(x float64) Value {
+ if f := new(big.Rat).SetFloat64(x); f != nil {
+ return normFloat(f)
+ }
+ return unknownVal{}
+}
+
+// MakeFromLiteral returns the corresponding integer, floating-point,
+// imaginary, character, or string value for a Go literal string. The
+// result is nil if the literal string is invalid.
+func MakeFromLiteral(lit string, tok token.Token) Value {
+ switch tok {
+ case token.INT:
+ if x, err := strconv.ParseInt(lit, 0, 64); err == nil {
+ return int64Val(x)
+ }
+ if x, ok := new(big.Int).SetString(lit, 0); ok {
+ return intVal{x}
+ }
+
+ case token.FLOAT:
+ if x, ok := new(big.Rat).SetString(lit); ok {
+ return normFloat(x)
+ }
+
+ case token.IMAG:
+ if n := len(lit); n > 0 && lit[n-1] == 'i' {
+ if im, ok := new(big.Rat).SetString(lit[0 : n-1]); ok {
+ return normComplex(big.NewRat(0, 1), im)
+ }
+ }
+
+ case token.CHAR:
+ if n := len(lit); n >= 2 {
+ if code, _, _, err := strconv.UnquoteChar(lit[1:n-1], '\''); err == nil {
+ return int64Val(code)
+ }
+ }
+
+ case token.STRING:
+ if s, err := strconv.Unquote(lit); err == nil {
+ return stringVal(s)
+ }
+ }
+
+ return nil
+}
+
+// ----------------------------------------------------------------------------
+// Accessors
+//
+// For unknown arguments the result is the zero value for the respective
+// accessor type, except for Sign, where the result is 1.
+
+// BoolVal returns the Go boolean value of x, which must be a Bool or an Unknown.
+// If x is Unknown, the result is false.
+func BoolVal(x Value) bool {
+ switch x := x.(type) {
+ case boolVal:
+ return bool(x)
+ case unknownVal:
+ return false
+ }
+ panic(fmt.Sprintf("%v not a Bool", x))
+}
+
+// StringVal returns the Go string value of x, which must be a String or an Unknown.
+// If x is Unknown, the result is "".
+func StringVal(x Value) string {
+ switch x := x.(type) {
+ case stringVal:
+ return string(x)
+ case unknownVal:
+ return ""
+ }
+ panic(fmt.Sprintf("%v not a String", x))
+}
+
+// Int64Val returns the Go int64 value of x and whether the result is exact;
+// x must be an Int or an Unknown. If the result is not exact, its value is undefined.
+// If x is Unknown, the result is (0, false).
+func Int64Val(x Value) (int64, bool) {
+ switch x := x.(type) {
+ case int64Val:
+ return int64(x), true
+ case intVal:
+ return x.val.Int64(), x.val.BitLen() <= 63
+ case unknownVal:
+ return 0, false
+ }
+ panic(fmt.Sprintf("%v not an Int", x))
+}
+
+// Uint64Val returns the Go uint64 value of x and whether the result is exact;
+// x must be an Int or an Unknown. If the result is not exact, its value is undefined.
+// If x is Unknown, the result is (0, false).
+func Uint64Val(x Value) (uint64, bool) {
+ switch x := x.(type) {
+ case int64Val:
+ return uint64(x), x >= 0
+ case intVal:
+ return x.val.Uint64(), x.val.Sign() >= 0 && x.val.BitLen() <= 64
+ case unknownVal:
+ return 0, false
+ }
+ panic(fmt.Sprintf("%v not an Int", x))
+}
+
+// Float32Val is like Float64Val but for float32 instead of float64.
+func Float32Val(x Value) (float32, bool) {
+ switch x := x.(type) {
+ case int64Val:
+ f := float32(x)
+ return f, int64Val(f) == x
+ case intVal:
+ return ratToFloat32(new(big.Rat).SetFrac(x.val, int1))
+ case floatVal:
+ return ratToFloat32(x.val)
+ case unknownVal:
+ return 0, false
+ }
+ panic(fmt.Sprintf("%v not a Float", x))
+}
+
+// Float64Val returns the nearest Go float64 value of x and whether the result is exact;
+// x must be numeric but not Complex, or Unknown. For values too small (too close to 0)
+// to represent as float64, Float64Val silently underflows to 0. The result sign always
+// matches the sign of x, even for 0.
+// If x is Unknown, the result is (0, false).
+func Float64Val(x Value) (float64, bool) {
+ switch x := x.(type) {
+ case int64Val:
+ f := float64(int64(x))
+ return f, int64Val(f) == x
+ case intVal:
+ return new(big.Rat).SetFrac(x.val, int1).Float64()
+ case floatVal:
+ return x.val.Float64()
+ case unknownVal:
+ return 0, false
+ }
+ panic(fmt.Sprintf("%v not a Float", x))
+}
+
+// BitLen returns the number of bits required to represent
+// the absolute value x in binary representation; x must be an Int or an Unknown.
+// If x is Unknown, the result is 0.
+func BitLen(x Value) int {
+ switch x := x.(type) {
+ case int64Val:
+ return new(big.Int).SetInt64(int64(x)).BitLen()
+ case intVal:
+ return x.val.BitLen()
+ case unknownVal:
+ return 0
+ }
+ panic(fmt.Sprintf("%v not an Int", x))
+}
+
+// Sign returns -1, 0, or 1 depending on whether x < 0, x == 0, or x > 0;
+// x must be numeric or Unknown. For complex values x, the sign is 0 if x == 0,
+// otherwise it is != 0. If x is Unknown, the result is 1.
+func Sign(x Value) int {
+ switch x := x.(type) {
+ case int64Val:
+ switch {
+ case x < 0:
+ return -1
+ case x > 0:
+ return 1
+ }
+ return 0
+ case intVal:
+ return x.val.Sign()
+ case floatVal:
+ return x.val.Sign()
+ case complexVal:
+ return x.re.Sign() | x.im.Sign()
+ case unknownVal:
+ return 1 // avoid spurious division by zero errors
+ }
+ panic(fmt.Sprintf("%v not numeric", x))
+}
+
+// ----------------------------------------------------------------------------
+// Support for serializing/deserializing integers
+
+const (
+ // Compute the size of a Word in bytes.
+ _m = ^big.Word(0)
+ _log = _m>>8&1 + _m>>16&1 + _m>>32&1
+ wordSize = 1 << _log
+)
+
+// Bytes returns the bytes for the absolute value of x in little-
+// endian binary representation; x must be an Int.
+func Bytes(x Value) []byte {
+ var val *big.Int
+ switch x := x.(type) {
+ case int64Val:
+ val = new(big.Int).SetInt64(int64(x))
+ case intVal:
+ val = x.val
+ default:
+ panic(fmt.Sprintf("%v not an Int", x))
+ }
+
+ words := val.Bits()
+ bytes := make([]byte, len(words)*wordSize)
+
+ i := 0
+ for _, w := range words {
+ for j := 0; j < wordSize; j++ {
+ bytes[i] = byte(w)
+ w >>= 8
+ i++
+ }
+ }
+ // remove leading 0's
+ for i > 0 && bytes[i-1] == 0 {
+ i--
+ }
+
+ return bytes[:i]
+}
+
+// MakeFromBytes returns the Int value given the bytes of its little-endian
+// binary representation. An empty byte slice argument represents 0.
+func MakeFromBytes(bytes []byte) Value {
+ words := make([]big.Word, (len(bytes)+(wordSize-1))/wordSize)
+
+ i := 0
+ var w big.Word
+ var s uint
+ for _, b := range bytes {
+ w |= big.Word(b) << s
+ if s += 8; s == wordSize*8 {
+ words[i] = w
+ i++
+ w = 0
+ s = 0
+ }
+ }
+ // store last word
+ if i < len(words) {
+ words[i] = w
+ i++
+ }
+ // remove leading 0's
+ for i > 0 && words[i-1] == 0 {
+ i--
+ }
+
+ return normInt(new(big.Int).SetBits(words[:i]))
+}
+
+// ----------------------------------------------------------------------------
+// Support for disassembling fractions
+
+// Num returns the numerator of x; x must be Int, Float, or Unknown.
+// If x is Unknown, the result is Unknown, otherwise it is an Int
+// with the same sign as x.
+func Num(x Value) Value {
+ switch x := x.(type) {
+ case unknownVal, int64Val, intVal:
+ return x
+ case floatVal:
+ return normInt(x.val.Num())
+ }
+ panic(fmt.Sprintf("%v not Int or Float", x))
+}
+
+// Denom returns the denominator of x; x must be Int, Float, or Unknown.
+// If x is Unknown, the result is Unknown, otherwise it is an Int >= 1.
+func Denom(x Value) Value {
+ switch x := x.(type) {
+ case unknownVal:
+ return x
+ case int64Val, intVal:
+ return int64Val(1)
+ case floatVal:
+ return normInt(x.val.Denom())
+ }
+ panic(fmt.Sprintf("%v not Int or Float", x))
+}
+
+// ----------------------------------------------------------------------------
+// Support for assembling/disassembling complex numbers
+
+// MakeImag returns the numeric value x*i (possibly 0);
+// x must be Int, Float, or Unknown.
+// If x is Unknown, the result is Unknown.
+func MakeImag(x Value) Value {
+ var im *big.Rat
+ switch x := x.(type) {
+ case unknownVal:
+ return x
+ case int64Val:
+ im = big.NewRat(int64(x), 1)
+ case intVal:
+ im = new(big.Rat).SetFrac(x.val, int1)
+ case floatVal:
+ im = x.val
+ default:
+ panic(fmt.Sprintf("%v not Int or Float", x))
+ }
+ return normComplex(rat0, im)
+}
+
+// Real returns the real part of x, which must be a numeric or unknown value.
+// If x is Unknown, the result is Unknown.
+func Real(x Value) Value {
+ switch x := x.(type) {
+ case unknownVal, int64Val, intVal, floatVal:
+ return x
+ case complexVal:
+ return normFloat(x.re)
+ }
+ panic(fmt.Sprintf("%v not numeric", x))
+}
+
+// Imag returns the imaginary part of x, which must be a numeric or unknown value.
+// If x is Unknown, the result is Unknown.
+func Imag(x Value) Value {
+ switch x := x.(type) {
+ case unknownVal:
+ return x
+ case int64Val, intVal, floatVal:
+ return int64Val(0)
+ case complexVal:
+ return normFloat(x.im)
+ }
+ panic(fmt.Sprintf("%v not numeric", x))
+}
+
+// ----------------------------------------------------------------------------
+// Operations
+
+// is32bit reports whether x can be represented using 32 bits.
+func is32bit(x int64) bool {
+ const s = 32
+ return -1<<(s-1) <= x && x <= 1<<(s-1)-1
+}
+
+// is63bit reports whether x can be represented using 63 bits.
+func is63bit(x int64) bool {
+ const s = 63
+ return -1<<(s-1) <= x && x <= 1<<(s-1)-1
+}
+
+// UnaryOp returns the result of the unary expression op y.
+// The operation must be defined for the operand.
+// If size >= 0 it specifies the ^ (xor) result size in bytes.
+// If y is Unknown, the result is Unknown.
+//
+func UnaryOp(op token.Token, y Value, size int) Value {
+ switch op {
+ case token.ADD:
+ switch y.(type) {
+ case unknownVal, int64Val, intVal, floatVal, complexVal:
+ return y
+ }
+
+ case token.SUB:
+ switch y := y.(type) {
+ case unknownVal:
+ return y
+ case int64Val:
+ if z := -y; z != y {
+ return z // no overflow
+ }
+ return normInt(new(big.Int).Neg(big.NewInt(int64(y))))
+ case intVal:
+ return normInt(new(big.Int).Neg(y.val))
+ case floatVal:
+ return normFloat(new(big.Rat).Neg(y.val))
+ case complexVal:
+ return normComplex(new(big.Rat).Neg(y.re), new(big.Rat).Neg(y.im))
+ }
+
+ case token.XOR:
+ var z big.Int
+ switch y := y.(type) {
+ case unknownVal:
+ return y
+ case int64Val:
+ z.Not(big.NewInt(int64(y)))
+ case intVal:
+ z.Not(y.val)
+ default:
+ goto Error
+ }
+ // For unsigned types, the result will be negative and
+ // thus "too large": We must limit the result size to
+ // the type's size.
+ if size >= 0 {
+ s := uint(size) * 8
+ z.AndNot(&z, new(big.Int).Lsh(big.NewInt(-1), s)) // z &^= (-1)< ord(y) {
+ y, x = match(y, x)
+ return x, y
+ }
+ // ord(x) <= ord(y)
+
+ switch x := x.(type) {
+ case unknownVal:
+ return x, x
+
+ case boolVal, stringVal, complexVal:
+ return x, y
+
+ case int64Val:
+ switch y := y.(type) {
+ case int64Val:
+ return x, y
+ case intVal:
+ return intVal{big.NewInt(int64(x))}, y
+ case floatVal:
+ return floatVal{big.NewRat(int64(x), 1)}, y
+ case complexVal:
+ return complexVal{big.NewRat(int64(x), 1), rat0}, y
+ }
+
+ case intVal:
+ switch y := y.(type) {
+ case intVal:
+ return x, y
+ case floatVal:
+ return floatVal{new(big.Rat).SetFrac(x.val, int1)}, y
+ case complexVal:
+ return complexVal{new(big.Rat).SetFrac(x.val, int1), rat0}, y
+ }
+
+ case floatVal:
+ switch y := y.(type) {
+ case floatVal:
+ return x, y
+ case complexVal:
+ return complexVal{x.val, rat0}, y
+ }
+ }
+
+ panic("unreachable")
+}
+
+// BinaryOp returns the result of the binary expression x op y.
+// The operation must be defined for the operands. If one of the
+// operands is Unknown, the result is Unknown.
+// To force integer division of Int operands, use op == token.QUO_ASSIGN
+// instead of token.QUO; the result is guaranteed to be Int in this case.
+// Division by zero leads to a run-time panic.
+//
+func BinaryOp(x Value, op token.Token, y Value) Value {
+ x, y = match(x, y)
+
+ switch x := x.(type) {
+ case unknownVal:
+ return x
+
+ case boolVal:
+ y := y.(boolVal)
+ switch op {
+ case token.LAND:
+ return x && y
+ case token.LOR:
+ return x || y
+ }
+
+ case int64Val:
+ a := int64(x)
+ b := int64(y.(int64Val))
+ var c int64
+ switch op {
+ case token.ADD:
+ if !is63bit(a) || !is63bit(b) {
+ return normInt(new(big.Int).Add(big.NewInt(a), big.NewInt(b)))
+ }
+ c = a + b
+ case token.SUB:
+ if !is63bit(a) || !is63bit(b) {
+ return normInt(new(big.Int).Sub(big.NewInt(a), big.NewInt(b)))
+ }
+ c = a - b
+ case token.MUL:
+ if !is32bit(a) || !is32bit(b) {
+ return normInt(new(big.Int).Mul(big.NewInt(a), big.NewInt(b)))
+ }
+ c = a * b
+ case token.QUO:
+ return normFloat(new(big.Rat).SetFrac(big.NewInt(a), big.NewInt(b)))
+ case token.QUO_ASSIGN: // force integer division
+ c = a / b
+ case token.REM:
+ c = a % b
+ case token.AND:
+ c = a & b
+ case token.OR:
+ c = a | b
+ case token.XOR:
+ c = a ^ b
+ case token.AND_NOT:
+ c = a &^ b
+ default:
+ goto Error
+ }
+ return int64Val(c)
+
+ case intVal:
+ a := x.val
+ b := y.(intVal).val
+ var c big.Int
+ switch op {
+ case token.ADD:
+ c.Add(a, b)
+ case token.SUB:
+ c.Sub(a, b)
+ case token.MUL:
+ c.Mul(a, b)
+ case token.QUO:
+ return normFloat(new(big.Rat).SetFrac(a, b))
+ case token.QUO_ASSIGN: // force integer division
+ c.Quo(a, b)
+ case token.REM:
+ c.Rem(a, b)
+ case token.AND:
+ c.And(a, b)
+ case token.OR:
+ c.Or(a, b)
+ case token.XOR:
+ c.Xor(a, b)
+ case token.AND_NOT:
+ c.AndNot(a, b)
+ default:
+ goto Error
+ }
+ return normInt(&c)
+
+ case floatVal:
+ a := x.val
+ b := y.(floatVal).val
+ var c big.Rat
+ switch op {
+ case token.ADD:
+ c.Add(a, b)
+ case token.SUB:
+ c.Sub(a, b)
+ case token.MUL:
+ c.Mul(a, b)
+ case token.QUO:
+ c.Quo(a, b)
+ default:
+ goto Error
+ }
+ return normFloat(&c)
+
+ case complexVal:
+ y := y.(complexVal)
+ a, b := x.re, x.im
+ c, d := y.re, y.im
+ var re, im big.Rat
+ switch op {
+ case token.ADD:
+ // (a+c) + i(b+d)
+ re.Add(a, c)
+ im.Add(b, d)
+ case token.SUB:
+ // (a-c) + i(b-d)
+ re.Sub(a, c)
+ im.Sub(b, d)
+ case token.MUL:
+ // (ac-bd) + i(bc+ad)
+ var ac, bd, bc, ad big.Rat
+ ac.Mul(a, c)
+ bd.Mul(b, d)
+ bc.Mul(b, c)
+ ad.Mul(a, d)
+ re.Sub(&ac, &bd)
+ im.Add(&bc, &ad)
+ case token.QUO:
+ // (ac+bd)/s + i(bc-ad)/s, with s = cc + dd
+ var ac, bd, bc, ad, s, cc, dd big.Rat
+ ac.Mul(a, c)
+ bd.Mul(b, d)
+ bc.Mul(b, c)
+ ad.Mul(a, d)
+ cc.Mul(c, c)
+ dd.Mul(d, d)
+ s.Add(&cc, &dd)
+ re.Add(&ac, &bd)
+ re.Quo(&re, &s)
+ im.Sub(&bc, &ad)
+ im.Quo(&im, &s)
+ default:
+ goto Error
+ }
+ return normComplex(&re, &im)
+
+ case stringVal:
+ if op == token.ADD {
+ return x + y.(stringVal)
+ }
+ }
+
+Error:
+ panic(fmt.Sprintf("invalid binary operation %v %s %v", x, op, y))
+}
+
+// Shift returns the result of the shift expression x op s
+// with op == token.SHL or token.SHR (<< or >>). x must be
+// an Int or an Unknown. If x is Unknown, the result is x.
+//
+func Shift(x Value, op token.Token, s uint) Value {
+ switch x := x.(type) {
+ case unknownVal:
+ return x
+
+ case int64Val:
+ if s == 0 {
+ return x
+ }
+ switch op {
+ case token.SHL:
+ z := big.NewInt(int64(x))
+ return normInt(z.Lsh(z, s))
+ case token.SHR:
+ return x >> s
+ }
+
+ case intVal:
+ if s == 0 {
+ return x
+ }
+ var z big.Int
+ switch op {
+ case token.SHL:
+ return normInt(z.Lsh(x.val, s))
+ case token.SHR:
+ return normInt(z.Rsh(x.val, s))
+ }
+ }
+
+ panic(fmt.Sprintf("invalid shift %v %s %d", x, op, s))
+}
+
+func cmpZero(x int, op token.Token) bool {
+ switch op {
+ case token.EQL:
+ return x == 0
+ case token.NEQ:
+ return x != 0
+ case token.LSS:
+ return x < 0
+ case token.LEQ:
+ return x <= 0
+ case token.GTR:
+ return x > 0
+ case token.GEQ:
+ return x >= 0
+ }
+ panic("unreachable")
+}
+
+// Compare returns the result of the comparison x op y.
+// The comparison must be defined for the operands.
+// If one of the operands is Unknown, the result is
+// false.
+//
+func Compare(x Value, op token.Token, y Value) bool {
+ x, y = match(x, y)
+
+ switch x := x.(type) {
+ case unknownVal:
+ return false
+
+ case boolVal:
+ y := y.(boolVal)
+ switch op {
+ case token.EQL:
+ return x == y
+ case token.NEQ:
+ return x != y
+ }
+
+ case int64Val:
+ y := y.(int64Val)
+ switch op {
+ case token.EQL:
+ return x == y
+ case token.NEQ:
+ return x != y
+ case token.LSS:
+ return x < y
+ case token.LEQ:
+ return x <= y
+ case token.GTR:
+ return x > y
+ case token.GEQ:
+ return x >= y
+ }
+
+ case intVal:
+ return cmpZero(x.val.Cmp(y.(intVal).val), op)
+
+ case floatVal:
+ return cmpZero(x.val.Cmp(y.(floatVal).val), op)
+
+ case complexVal:
+ y := y.(complexVal)
+ re := x.re.Cmp(y.re)
+ im := x.im.Cmp(y.im)
+ switch op {
+ case token.EQL:
+ return re == 0 && im == 0
+ case token.NEQ:
+ return re != 0 || im != 0
+ }
+
+ case stringVal:
+ y := y.(stringVal)
+ switch op {
+ case token.EQL:
+ return x == y
+ case token.NEQ:
+ return x != y
+ case token.LSS:
+ return x < y
+ case token.LEQ:
+ return x <= y
+ case token.GTR:
+ return x > y
+ case token.GEQ:
+ return x >= y
+ }
+ }
+
+ panic(fmt.Sprintf("invalid comparison %v %s %v", x, op, y))
+}
diff --git a/vendor/golang.org/x/tools/go/exact/go13.go b/vendor/golang.org/x/tools/go/exact/go13.go
new file mode 100644
index 0000000..1016c14
--- /dev/null
+++ b/vendor/golang.org/x/tools/go/exact/go13.go
@@ -0,0 +1,24 @@
+// Copyright 2014 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build !go1.4
+
+package exact
+
+import (
+ "math"
+ "math/big"
+)
+
+func ratToFloat32(x *big.Rat) (float32, bool) {
+ // Before 1.4, there's no Rat.Float32.
+ // Emulate it, albeit at the cost of
+ // imprecision in corner cases.
+ x64, exact := x.Float64()
+ x32 := float32(x64)
+ if math.IsInf(float64(x32), 0) {
+ exact = false
+ }
+ return x32, exact
+}
diff --git a/vendor/golang.org/x/tools/go/exact/go14.go b/vendor/golang.org/x/tools/go/exact/go14.go
new file mode 100644
index 0000000..b86e5d2
--- /dev/null
+++ b/vendor/golang.org/x/tools/go/exact/go14.go
@@ -0,0 +1,13 @@
+// Copyright 2014 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build go1.4
+
+package exact
+
+import "math/big"
+
+func ratToFloat32(x *big.Rat) (float32, bool) {
+ return x.Float32()
+}
diff --git a/vendor/golang.org/x/tools/go/gcimporter/exportdata.go b/vendor/golang.org/x/tools/go/gcimporter/exportdata.go
new file mode 100644
index 0000000..657742b
--- /dev/null
+++ b/vendor/golang.org/x/tools/go/gcimporter/exportdata.go
@@ -0,0 +1,108 @@
+// Copyright 2011 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// This file implements FindExportData.
+
+package gcimporter
+
+import (
+ "bufio"
+ "errors"
+ "fmt"
+ "io"
+ "strconv"
+ "strings"
+)
+
+func readGopackHeader(r *bufio.Reader) (name string, size int, err error) {
+ // See $GOROOT/include/ar.h.
+ hdr := make([]byte, 16+12+6+6+8+10+2)
+ _, err = io.ReadFull(r, hdr)
+ if err != nil {
+ return
+ }
+ // leave for debugging
+ if false {
+ fmt.Printf("header: %s", hdr)
+ }
+ s := strings.TrimSpace(string(hdr[16+12+6+6+8:][:10]))
+ size, err = strconv.Atoi(s)
+ if err != nil || hdr[len(hdr)-2] != '`' || hdr[len(hdr)-1] != '\n' {
+ err = errors.New("invalid archive header")
+ return
+ }
+ name = strings.TrimSpace(string(hdr[:16]))
+ return
+}
+
+// FindExportData positions the reader r at the beginning of the
+// export data section of an underlying GC-created object/archive
+// file by reading from it. The reader must be positioned at the
+// start of the file before calling this function.
+//
+func FindExportData(r *bufio.Reader) (err error) {
+ // Read first line to make sure this is an object file.
+ line, err := r.ReadSlice('\n')
+ if err != nil {
+ return
+ }
+ if string(line) == "!\n" {
+ // Archive file. Scan to __.PKGDEF.
+ var name string
+ var size int
+ if name, size, err = readGopackHeader(r); err != nil {
+ return
+ }
+
+ // Optional leading __.GOSYMDEF or __.SYMDEF.
+ // Read and discard.
+ if name == "__.SYMDEF" || name == "__.GOSYMDEF" {
+ const block = 4096
+ tmp := make([]byte, block)
+ for size > 0 {
+ n := size
+ if n > block {
+ n = block
+ }
+ if _, err = io.ReadFull(r, tmp[:n]); err != nil {
+ return
+ }
+ size -= n
+ }
+
+ if name, size, err = readGopackHeader(r); err != nil {
+ return
+ }
+ }
+
+ // First real entry should be __.PKGDEF.
+ if name != "__.PKGDEF" {
+ err = errors.New("go archive is missing __.PKGDEF")
+ return
+ }
+
+ // Read first line of __.PKGDEF data, so that line
+ // is once again the first line of the input.
+ if line, err = r.ReadSlice('\n'); err != nil {
+ return
+ }
+ }
+
+ // Now at __.PKGDEF in archive or still at beginning of file.
+ // Either way, line should begin with "go object ".
+ if !strings.HasPrefix(string(line), "go object ") {
+ err = errors.New("not a go object file")
+ return
+ }
+
+ // Skip over object header to export data.
+ // Begins after first line with $$.
+ for line[0] != '$' {
+ if line, err = r.ReadSlice('\n'); err != nil {
+ return
+ }
+ }
+
+ return
+}
diff --git a/vendor/golang.org/x/tools/go/gcimporter/gcimporter.go b/vendor/golang.org/x/tools/go/gcimporter/gcimporter.go
new file mode 100644
index 0000000..031e870
--- /dev/null
+++ b/vendor/golang.org/x/tools/go/gcimporter/gcimporter.go
@@ -0,0 +1,995 @@
+// Copyright 2011 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package gcimporter implements Import for gc-generated object files.
+// Importing this package installs Import as go/types.DefaultImport.
+package gcimporter // import "golang.org/x/tools/go/gcimporter"
+
+import (
+ "bufio"
+ "errors"
+ "fmt"
+ "go/build"
+ "go/token"
+ "io"
+ "os"
+ "path/filepath"
+ "sort"
+ "strconv"
+ "strings"
+ "text/scanner"
+
+ "golang.org/x/tools/go/exact"
+ "golang.org/x/tools/go/types"
+)
+
+// debugging/development support
+const debug = false
+
+func init() {
+ types.DefaultImport = Import
+}
+
+var pkgExts = [...]string{".a", ".5", ".6", ".7", ".8", ".9"}
+
+// FindPkg returns the filename and unique package id for an import
+// path based on package information provided by build.Import (using
+// the build.Default build.Context).
+// If no file was found, an empty filename is returned.
+//
+func FindPkg(path, srcDir string) (filename, id string) {
+ if len(path) == 0 {
+ return
+ }
+
+ id = path
+ var noext string
+ switch {
+ default:
+ // "x" -> "$GOPATH/pkg/$GOOS_$GOARCH/x.ext", "x"
+ // Don't require the source files to be present.
+ bp, _ := build.Import(path, srcDir, build.FindOnly|build.AllowBinary)
+ if bp.PkgObj == "" {
+ return
+ }
+ noext = strings.TrimSuffix(bp.PkgObj, ".a")
+
+ case build.IsLocalImport(path):
+ // "./x" -> "/this/directory/x.ext", "/this/directory/x"
+ noext = filepath.Join(srcDir, path)
+ id = noext
+
+ case filepath.IsAbs(path):
+ // for completeness only - go/build.Import
+ // does not support absolute imports
+ // "/x" -> "/x.ext", "/x"
+ noext = path
+ }
+
+ // try extensions
+ for _, ext := range pkgExts {
+ filename = noext + ext
+ if f, err := os.Stat(filename); err == nil && !f.IsDir() {
+ return
+ }
+ }
+
+ filename = "" // not found
+ return
+}
+
+// ImportData imports a package by reading the gc-generated export data,
+// adds the corresponding package object to the packages map indexed by id,
+// and returns the object.
+//
+// The packages map must contains all packages already imported. The data
+// reader position must be the beginning of the export data section. The
+// filename is only used in error messages.
+//
+// If packages[id] contains the completely imported package, that package
+// can be used directly, and there is no need to call this function (but
+// there is also no harm but for extra time used).
+//
+func ImportData(packages map[string]*types.Package, filename, id string, data io.Reader) (pkg *types.Package, err error) {
+ // support for parser error handling
+ defer func() {
+ switch r := recover().(type) {
+ case nil:
+ // nothing to do
+ case importError:
+ err = r
+ default:
+ panic(r) // internal error
+ }
+ }()
+
+ var p parser
+ p.init(filename, id, data, packages)
+ pkg = p.parseExport()
+
+ return
+}
+
+// Import imports a gc-generated package given its import path, adds the
+// corresponding package object to the packages map, and returns the object.
+// Local import paths are interpreted relative to the current working directory.
+// The packages map must contains all packages already imported.
+//
+func Import(packages map[string]*types.Package, path string) (pkg *types.Package, err error) {
+ if path == "unsafe" {
+ return types.Unsafe, nil
+ }
+
+ srcDir := "."
+ if build.IsLocalImport(path) {
+ srcDir, err = os.Getwd()
+ if err != nil {
+ return
+ }
+ }
+
+ filename, id := FindPkg(path, srcDir)
+ if filename == "" {
+ err = fmt.Errorf("can't find import: %s", id)
+ return
+ }
+
+ // no need to re-import if the package was imported completely before
+ if pkg = packages[id]; pkg != nil && pkg.Complete() {
+ return
+ }
+
+ // open file
+ f, err := os.Open(filename)
+ if err != nil {
+ return
+ }
+ defer func() {
+ f.Close()
+ if err != nil {
+ // add file name to error
+ err = fmt.Errorf("reading export data: %s: %v", filename, err)
+ }
+ }()
+
+ buf := bufio.NewReader(f)
+ if err = FindExportData(buf); err != nil {
+ return
+ }
+
+ pkg, err = ImportData(packages, filename, id, buf)
+
+ return
+}
+
+// ----------------------------------------------------------------------------
+// Parser
+
+// TODO(gri) Imported objects don't have position information.
+// Ideally use the debug table line info; alternatively
+// create some fake position (or the position of the
+// import). That way error messages referring to imported
+// objects can print meaningful information.
+
+// parser parses the exports inside a gc compiler-produced
+// object/archive file and populates its scope with the results.
+type parser struct {
+ scanner scanner.Scanner
+ tok rune // current token
+ lit string // literal string; only valid for Ident, Int, String tokens
+ id string // package id of imported package
+ sharedPkgs map[string]*types.Package // package id -> package object (across importer)
+ localPkgs map[string]*types.Package // package id -> package object (just this package)
+}
+
+func (p *parser) init(filename, id string, src io.Reader, packages map[string]*types.Package) {
+ p.scanner.Init(src)
+ p.scanner.Error = func(_ *scanner.Scanner, msg string) { p.error(msg) }
+ p.scanner.Mode = scanner.ScanIdents | scanner.ScanInts | scanner.ScanChars | scanner.ScanStrings | scanner.ScanComments | scanner.SkipComments
+ p.scanner.Whitespace = 1<<'\t' | 1<<' '
+ p.scanner.Filename = filename // for good error messages
+ p.next()
+ p.id = id
+ p.sharedPkgs = packages
+ if debug {
+ // check consistency of packages map
+ for _, pkg := range packages {
+ if pkg.Name() == "" {
+ fmt.Printf("no package name for %s\n", pkg.Path())
+ }
+ }
+ }
+}
+
+func (p *parser) next() {
+ p.tok = p.scanner.Scan()
+ switch p.tok {
+ case scanner.Ident, scanner.Int, scanner.Char, scanner.String, '·':
+ p.lit = p.scanner.TokenText()
+ default:
+ p.lit = ""
+ }
+ if debug {
+ fmt.Printf("%s: %q -> %q\n", scanner.TokenString(p.tok), p.scanner.TokenText(), p.lit)
+ }
+}
+
+func declTypeName(pkg *types.Package, name string) *types.TypeName {
+ scope := pkg.Scope()
+ if obj := scope.Lookup(name); obj != nil {
+ return obj.(*types.TypeName)
+ }
+ obj := types.NewTypeName(token.NoPos, pkg, name, nil)
+ // a named type may be referred to before the underlying type
+ // is known - set it up
+ types.NewNamed(obj, nil, nil)
+ scope.Insert(obj)
+ return obj
+}
+
+// ----------------------------------------------------------------------------
+// Error handling
+
+// Internal errors are boxed as importErrors.
+type importError struct {
+ pos scanner.Position
+ err error
+}
+
+func (e importError) Error() string {
+ return fmt.Sprintf("import error %s (byte offset = %d): %s", e.pos, e.pos.Offset, e.err)
+}
+
+func (p *parser) error(err interface{}) {
+ if s, ok := err.(string); ok {
+ err = errors.New(s)
+ }
+ // panic with a runtime.Error if err is not an error
+ panic(importError{p.scanner.Pos(), err.(error)})
+}
+
+func (p *parser) errorf(format string, args ...interface{}) {
+ p.error(fmt.Sprintf(format, args...))
+}
+
+func (p *parser) expect(tok rune) string {
+ lit := p.lit
+ if p.tok != tok {
+ p.errorf("expected %s, got %s (%s)", scanner.TokenString(tok), scanner.TokenString(p.tok), lit)
+ }
+ p.next()
+ return lit
+}
+
+func (p *parser) expectSpecial(tok string) {
+ sep := 'x' // not white space
+ i := 0
+ for i < len(tok) && p.tok == rune(tok[i]) && sep > ' ' {
+ sep = p.scanner.Peek() // if sep <= ' ', there is white space before the next token
+ p.next()
+ i++
+ }
+ if i < len(tok) {
+ p.errorf("expected %q, got %q", tok, tok[0:i])
+ }
+}
+
+func (p *parser) expectKeyword(keyword string) {
+ lit := p.expect(scanner.Ident)
+ if lit != keyword {
+ p.errorf("expected keyword %s, got %q", keyword, lit)
+ }
+}
+
+// ----------------------------------------------------------------------------
+// Qualified and unqualified names
+
+// PackageId = string_lit .
+//
+func (p *parser) parsePackageId() string {
+ id, err := strconv.Unquote(p.expect(scanner.String))
+ if err != nil {
+ p.error(err)
+ }
+ // id == "" stands for the imported package id
+ // (only known at time of package installation)
+ if id == "" {
+ id = p.id
+ }
+ return id
+}
+
+// PackageName = ident .
+//
+func (p *parser) parsePackageName() string {
+ return p.expect(scanner.Ident)
+}
+
+// dotIdentifier = ( ident | '·' ) { ident | int | '·' } .
+func (p *parser) parseDotIdent() string {
+ ident := ""
+ if p.tok != scanner.Int {
+ sep := 'x' // not white space
+ for (p.tok == scanner.Ident || p.tok == scanner.Int || p.tok == '·') && sep > ' ' {
+ ident += p.lit
+ sep = p.scanner.Peek() // if sep <= ' ', there is white space before the next token
+ p.next()
+ }
+ }
+ if ident == "" {
+ p.expect(scanner.Ident) // use expect() for error handling
+ }
+ return ident
+}
+
+// QualifiedName = "@" PackageId "." ( "?" | dotIdentifier ) .
+//
+func (p *parser) parseQualifiedName() (id, name string) {
+ p.expect('@')
+ id = p.parsePackageId()
+ p.expect('.')
+ // Per rev f280b8a485fd (10/2/2013), qualified names may be used for anonymous fields.
+ if p.tok == '?' {
+ p.next()
+ } else {
+ name = p.parseDotIdent()
+ }
+ return
+}
+
+// getPkg returns the package for a given id. If the package is
+// not found but we have a package name, create the package and
+// add it to the p.localPkgs and p.sharedPkgs maps.
+//
+// id identifies a package, usually by a canonical package path like
+// "encoding/json" but possibly by a non-canonical import path like
+// "./json".
+//
+func (p *parser) getPkg(id, name string) *types.Package {
+ // package unsafe is not in the packages maps - handle explicitly
+ if id == "unsafe" {
+ return types.Unsafe
+ }
+
+ pkg := p.localPkgs[id]
+ if pkg == nil && name != "" {
+ // first import of id from this package
+ pkg = p.sharedPkgs[id]
+ if pkg == nil {
+ // first import of id by this importer
+ pkg = types.NewPackage(id, name)
+ p.sharedPkgs[id] = pkg
+ }
+
+ if p.localPkgs == nil {
+ p.localPkgs = make(map[string]*types.Package)
+ }
+ p.localPkgs[id] = pkg
+ }
+ return pkg
+}
+
+// parseExportedName is like parseQualifiedName, but
+// the package id is resolved to an imported *types.Package.
+//
+func (p *parser) parseExportedName() (pkg *types.Package, name string) {
+ id, name := p.parseQualifiedName()
+ pkg = p.getPkg(id, "")
+ if pkg == nil {
+ p.errorf("%s package not found", id)
+ }
+ return
+}
+
+// ----------------------------------------------------------------------------
+// Types
+
+// BasicType = identifier .
+//
+func (p *parser) parseBasicType() types.Type {
+ id := p.expect(scanner.Ident)
+ obj := types.Universe.Lookup(id)
+ if obj, ok := obj.(*types.TypeName); ok {
+ return obj.Type()
+ }
+ p.errorf("not a basic type: %s", id)
+ return nil
+}
+
+// ArrayType = "[" int_lit "]" Type .
+//
+func (p *parser) parseArrayType() types.Type {
+ // "[" already consumed and lookahead known not to be "]"
+ lit := p.expect(scanner.Int)
+ p.expect(']')
+ elem := p.parseType()
+ n, err := strconv.ParseInt(lit, 10, 64)
+ if err != nil {
+ p.error(err)
+ }
+ return types.NewArray(elem, n)
+}
+
+// MapType = "map" "[" Type "]" Type .
+//
+func (p *parser) parseMapType() types.Type {
+ p.expectKeyword("map")
+ p.expect('[')
+ key := p.parseType()
+ p.expect(']')
+ elem := p.parseType()
+ return types.NewMap(key, elem)
+}
+
+// Name = identifier | "?" | QualifiedName .
+//
+// If materializePkg is set, the returned package is guaranteed to be set.
+// For fully qualified names, the returned package may be a fake package
+// (without name, scope, and not in the p.imports map), created for the
+// sole purpose of providing a package path. Fake packages are created
+// when the package id is not found in the p.imports map; in that case
+// we cannot create a real package because we don't have a package name.
+// For non-qualified names, the returned package is the imported package.
+//
+func (p *parser) parseName(materializePkg bool) (pkg *types.Package, name string) {
+ switch p.tok {
+ case scanner.Ident:
+ pkg = p.sharedPkgs[p.id]
+ name = p.lit
+ p.next()
+ case '?':
+ // anonymous
+ pkg = p.sharedPkgs[p.id]
+ p.next()
+ case '@':
+ // exported name prefixed with package path
+ var id string
+ id, name = p.parseQualifiedName()
+ if materializePkg {
+ // we don't have a package name - if the package
+ // doesn't exist yet, create a fake package instead
+ pkg = p.getPkg(id, "")
+ if pkg == nil {
+ pkg = types.NewPackage(id, "")
+ }
+ }
+ default:
+ p.error("name expected")
+ }
+ return
+}
+
+func deref(typ types.Type) types.Type {
+ if p, _ := typ.(*types.Pointer); p != nil {
+ return p.Elem()
+ }
+ return typ
+}
+
+// Field = Name Type [ string_lit ] .
+//
+func (p *parser) parseField() (*types.Var, string) {
+ pkg, name := p.parseName(true)
+ typ := p.parseType()
+ anonymous := false
+ if name == "" {
+ // anonymous field - typ must be T or *T and T must be a type name
+ switch typ := deref(typ).(type) {
+ case *types.Basic: // basic types are named types
+ pkg = nil
+ name = typ.Name()
+ case *types.Named:
+ name = typ.Obj().Name()
+ default:
+ p.errorf("anonymous field expected")
+ }
+ anonymous = true
+ }
+ tag := ""
+ if p.tok == scanner.String {
+ s := p.expect(scanner.String)
+ var err error
+ tag, err = strconv.Unquote(s)
+ if err != nil {
+ p.errorf("invalid struct tag %s: %s", s, err)
+ }
+ }
+ return types.NewField(token.NoPos, pkg, name, typ, anonymous), tag
+}
+
+// StructType = "struct" "{" [ FieldList ] "}" .
+// FieldList = Field { ";" Field } .
+//
+func (p *parser) parseStructType() types.Type {
+ var fields []*types.Var
+ var tags []string
+
+ p.expectKeyword("struct")
+ p.expect('{')
+ for i := 0; p.tok != '}' && p.tok != scanner.EOF; i++ {
+ if i > 0 {
+ p.expect(';')
+ }
+ fld, tag := p.parseField()
+ if tag != "" && tags == nil {
+ tags = make([]string, i)
+ }
+ if tags != nil {
+ tags = append(tags, tag)
+ }
+ fields = append(fields, fld)
+ }
+ p.expect('}')
+
+ return types.NewStruct(fields, tags)
+}
+
+// Parameter = ( identifier | "?" ) [ "..." ] Type [ string_lit ] .
+//
+func (p *parser) parseParameter() (par *types.Var, isVariadic bool) {
+ _, name := p.parseName(false)
+ // remove gc-specific parameter numbering
+ if i := strings.Index(name, "·"); i >= 0 {
+ name = name[:i]
+ }
+ if p.tok == '.' {
+ p.expectSpecial("...")
+ isVariadic = true
+ }
+ typ := p.parseType()
+ if isVariadic {
+ typ = types.NewSlice(typ)
+ }
+ // ignore argument tag (e.g. "noescape")
+ if p.tok == scanner.String {
+ p.next()
+ }
+ // TODO(gri) should we provide a package?
+ par = types.NewVar(token.NoPos, nil, name, typ)
+ return
+}
+
+// Parameters = "(" [ ParameterList ] ")" .
+// ParameterList = { Parameter "," } Parameter .
+//
+func (p *parser) parseParameters() (list []*types.Var, isVariadic bool) {
+ p.expect('(')
+ for p.tok != ')' && p.tok != scanner.EOF {
+ if len(list) > 0 {
+ p.expect(',')
+ }
+ par, variadic := p.parseParameter()
+ list = append(list, par)
+ if variadic {
+ if isVariadic {
+ p.error("... not on final argument")
+ }
+ isVariadic = true
+ }
+ }
+ p.expect(')')
+
+ return
+}
+
+// Signature = Parameters [ Result ] .
+// Result = Type | Parameters .
+//
+func (p *parser) parseSignature(recv *types.Var) *types.Signature {
+ params, isVariadic := p.parseParameters()
+
+ // optional result type
+ var results []*types.Var
+ if p.tok == '(' {
+ var variadic bool
+ results, variadic = p.parseParameters()
+ if variadic {
+ p.error("... not permitted on result type")
+ }
+ }
+
+ return types.NewSignature(recv, types.NewTuple(params...), types.NewTuple(results...), isVariadic)
+}
+
+// InterfaceType = "interface" "{" [ MethodList ] "}" .
+// MethodList = Method { ";" Method } .
+// Method = Name Signature .
+//
+// The methods of embedded interfaces are always "inlined"
+// by the compiler and thus embedded interfaces are never
+// visible in the export data.
+//
+func (p *parser) parseInterfaceType() types.Type {
+ var methods []*types.Func
+
+ p.expectKeyword("interface")
+ p.expect('{')
+ for i := 0; p.tok != '}' && p.tok != scanner.EOF; i++ {
+ if i > 0 {
+ p.expect(';')
+ }
+ pkg, name := p.parseName(true)
+ sig := p.parseSignature(nil)
+ methods = append(methods, types.NewFunc(token.NoPos, pkg, name, sig))
+ }
+ p.expect('}')
+
+ // Complete requires the type's embedded interfaces to be fully defined,
+ // but we do not define any
+ return types.NewInterface(methods, nil).Complete()
+}
+
+// ChanType = ( "chan" [ "<-" ] | "<-" "chan" ) Type .
+//
+func (p *parser) parseChanType() types.Type {
+ dir := types.SendRecv
+ if p.tok == scanner.Ident {
+ p.expectKeyword("chan")
+ if p.tok == '<' {
+ p.expectSpecial("<-")
+ dir = types.SendOnly
+ }
+ } else {
+ p.expectSpecial("<-")
+ p.expectKeyword("chan")
+ dir = types.RecvOnly
+ }
+ elem := p.parseType()
+ return types.NewChan(dir, elem)
+}
+
+// Type =
+// BasicType | TypeName | ArrayType | SliceType | StructType |
+// PointerType | FuncType | InterfaceType | MapType | ChanType |
+// "(" Type ")" .
+//
+// BasicType = ident .
+// TypeName = ExportedName .
+// SliceType = "[" "]" Type .
+// PointerType = "*" Type .
+// FuncType = "func" Signature .
+//
+func (p *parser) parseType() types.Type {
+ switch p.tok {
+ case scanner.Ident:
+ switch p.lit {
+ default:
+ return p.parseBasicType()
+ case "struct":
+ return p.parseStructType()
+ case "func":
+ // FuncType
+ p.next()
+ return p.parseSignature(nil)
+ case "interface":
+ return p.parseInterfaceType()
+ case "map":
+ return p.parseMapType()
+ case "chan":
+ return p.parseChanType()
+ }
+ case '@':
+ // TypeName
+ pkg, name := p.parseExportedName()
+ return declTypeName(pkg, name).Type()
+ case '[':
+ p.next() // look ahead
+ if p.tok == ']' {
+ // SliceType
+ p.next()
+ return types.NewSlice(p.parseType())
+ }
+ return p.parseArrayType()
+ case '*':
+ // PointerType
+ p.next()
+ return types.NewPointer(p.parseType())
+ case '<':
+ return p.parseChanType()
+ case '(':
+ // "(" Type ")"
+ p.next()
+ typ := p.parseType()
+ p.expect(')')
+ return typ
+ }
+ p.errorf("expected type, got %s (%q)", scanner.TokenString(p.tok), p.lit)
+ return nil
+}
+
+// ----------------------------------------------------------------------------
+// Declarations
+
+// ImportDecl = "import" PackageName PackageId .
+//
+func (p *parser) parseImportDecl() {
+ p.expectKeyword("import")
+ name := p.parsePackageName()
+ p.getPkg(p.parsePackageId(), name)
+}
+
+// int_lit = [ "+" | "-" ] { "0" ... "9" } .
+//
+func (p *parser) parseInt() string {
+ s := ""
+ switch p.tok {
+ case '-':
+ s = "-"
+ p.next()
+ case '+':
+ p.next()
+ }
+ return s + p.expect(scanner.Int)
+}
+
+// number = int_lit [ "p" int_lit ] .
+//
+func (p *parser) parseNumber() (typ *types.Basic, val exact.Value) {
+ // mantissa
+ mant := exact.MakeFromLiteral(p.parseInt(), token.INT)
+ if mant == nil {
+ panic("invalid mantissa")
+ }
+
+ if p.lit == "p" {
+ // exponent (base 2)
+ p.next()
+ exp, err := strconv.ParseInt(p.parseInt(), 10, 0)
+ if err != nil {
+ p.error(err)
+ }
+ if exp < 0 {
+ denom := exact.MakeInt64(1)
+ denom = exact.Shift(denom, token.SHL, uint(-exp))
+ typ = types.Typ[types.UntypedFloat]
+ val = exact.BinaryOp(mant, token.QUO, denom)
+ return
+ }
+ if exp > 0 {
+ mant = exact.Shift(mant, token.SHL, uint(exp))
+ }
+ typ = types.Typ[types.UntypedFloat]
+ val = mant
+ return
+ }
+
+ typ = types.Typ[types.UntypedInt]
+ val = mant
+ return
+}
+
+// ConstDecl = "const" ExportedName [ Type ] "=" Literal .
+// Literal = bool_lit | int_lit | float_lit | complex_lit | rune_lit | string_lit .
+// bool_lit = "true" | "false" .
+// complex_lit = "(" float_lit "+" float_lit "i" ")" .
+// rune_lit = "(" int_lit "+" int_lit ")" .
+// string_lit = `"` { unicode_char } `"` .
+//
+func (p *parser) parseConstDecl() {
+ p.expectKeyword("const")
+ pkg, name := p.parseExportedName()
+
+ var typ0 types.Type
+ if p.tok != '=' {
+ typ0 = p.parseType()
+ }
+
+ p.expect('=')
+ var typ types.Type
+ var val exact.Value
+ switch p.tok {
+ case scanner.Ident:
+ // bool_lit
+ if p.lit != "true" && p.lit != "false" {
+ p.error("expected true or false")
+ }
+ typ = types.Typ[types.UntypedBool]
+ val = exact.MakeBool(p.lit == "true")
+ p.next()
+
+ case '-', scanner.Int:
+ // int_lit
+ typ, val = p.parseNumber()
+
+ case '(':
+ // complex_lit or rune_lit
+ p.next()
+ if p.tok == scanner.Char {
+ p.next()
+ p.expect('+')
+ typ = types.Typ[types.UntypedRune]
+ _, val = p.parseNumber()
+ p.expect(')')
+ break
+ }
+ _, re := p.parseNumber()
+ p.expect('+')
+ _, im := p.parseNumber()
+ p.expectKeyword("i")
+ p.expect(')')
+ typ = types.Typ[types.UntypedComplex]
+ val = exact.BinaryOp(re, token.ADD, exact.MakeImag(im))
+
+ case scanner.Char:
+ // rune_lit
+ typ = types.Typ[types.UntypedRune]
+ val = exact.MakeFromLiteral(p.lit, token.CHAR)
+ p.next()
+
+ case scanner.String:
+ // string_lit
+ typ = types.Typ[types.UntypedString]
+ val = exact.MakeFromLiteral(p.lit, token.STRING)
+ p.next()
+
+ default:
+ p.errorf("expected literal got %s", scanner.TokenString(p.tok))
+ }
+
+ if typ0 == nil {
+ typ0 = typ
+ }
+
+ pkg.Scope().Insert(types.NewConst(token.NoPos, pkg, name, typ0, val))
+}
+
+// TypeDecl = "type" ExportedName Type .
+//
+func (p *parser) parseTypeDecl() {
+ p.expectKeyword("type")
+ pkg, name := p.parseExportedName()
+ obj := declTypeName(pkg, name)
+
+ // The type object may have been imported before and thus already
+ // have a type associated with it. We still need to parse the type
+ // structure, but throw it away if the object already has a type.
+ // This ensures that all imports refer to the same type object for
+ // a given type declaration.
+ typ := p.parseType()
+
+ if name := obj.Type().(*types.Named); name.Underlying() == nil {
+ name.SetUnderlying(typ)
+ }
+}
+
+// VarDecl = "var" ExportedName Type .
+//
+func (p *parser) parseVarDecl() {
+ p.expectKeyword("var")
+ pkg, name := p.parseExportedName()
+ typ := p.parseType()
+ pkg.Scope().Insert(types.NewVar(token.NoPos, pkg, name, typ))
+}
+
+// Func = Signature [ Body ] .
+// Body = "{" ... "}" .
+//
+func (p *parser) parseFunc(recv *types.Var) *types.Signature {
+ sig := p.parseSignature(recv)
+ if p.tok == '{' {
+ p.next()
+ for i := 1; i > 0; p.next() {
+ switch p.tok {
+ case '{':
+ i++
+ case '}':
+ i--
+ }
+ }
+ }
+ return sig
+}
+
+// MethodDecl = "func" Receiver Name Func .
+// Receiver = "(" ( identifier | "?" ) [ "*" ] ExportedName ")" .
+//
+func (p *parser) parseMethodDecl() {
+ // "func" already consumed
+ p.expect('(')
+ recv, _ := p.parseParameter() // receiver
+ p.expect(')')
+
+ // determine receiver base type object
+ base := deref(recv.Type()).(*types.Named)
+
+ // parse method name, signature, and possibly inlined body
+ _, name := p.parseName(true)
+ sig := p.parseFunc(recv)
+
+ // methods always belong to the same package as the base type object
+ pkg := base.Obj().Pkg()
+
+ // add method to type unless type was imported before
+ // and method exists already
+ // TODO(gri) This leads to a quadratic algorithm - ok for now because method counts are small.
+ base.AddMethod(types.NewFunc(token.NoPos, pkg, name, sig))
+}
+
+// FuncDecl = "func" ExportedName Func .
+//
+func (p *parser) parseFuncDecl() {
+ // "func" already consumed
+ pkg, name := p.parseExportedName()
+ typ := p.parseFunc(nil)
+ pkg.Scope().Insert(types.NewFunc(token.NoPos, pkg, name, typ))
+}
+
+// Decl = [ ImportDecl | ConstDecl | TypeDecl | VarDecl | FuncDecl | MethodDecl ] "\n" .
+//
+func (p *parser) parseDecl() {
+ if p.tok == scanner.Ident {
+ switch p.lit {
+ case "import":
+ p.parseImportDecl()
+ case "const":
+ p.parseConstDecl()
+ case "type":
+ p.parseTypeDecl()
+ case "var":
+ p.parseVarDecl()
+ case "func":
+ p.next() // look ahead
+ if p.tok == '(' {
+ p.parseMethodDecl()
+ } else {
+ p.parseFuncDecl()
+ }
+ }
+ }
+ p.expect('\n')
+}
+
+// ----------------------------------------------------------------------------
+// Export
+
+// Export = "PackageClause { Decl } "$$" .
+// PackageClause = "package" PackageName [ "safe" ] "\n" .
+//
+func (p *parser) parseExport() *types.Package {
+ p.expectKeyword("package")
+ name := p.parsePackageName()
+ if p.tok == scanner.Ident && p.lit == "safe" {
+ // package was compiled with -u option - ignore
+ p.next()
+ }
+ p.expect('\n')
+
+ pkg := p.getPkg(p.id, name)
+
+ for p.tok != '$' && p.tok != scanner.EOF {
+ p.parseDecl()
+ }
+
+ if ch := p.scanner.Peek(); p.tok != '$' || ch != '$' {
+ // don't call next()/expect() since reading past the
+ // export data may cause scanner errors (e.g. NUL chars)
+ p.errorf("expected '$$', got %s %c", scanner.TokenString(p.tok), ch)
+ }
+
+ if n := p.scanner.ErrorCount; n != 0 {
+ p.errorf("expected no scanner errors, got %d", n)
+ }
+
+ // Record all referenced packages as imports.
+ var imports []*types.Package
+ for id, pkg2 := range p.localPkgs {
+ if id == p.id {
+ continue // avoid self-edge
+ }
+ imports = append(imports, pkg2)
+ }
+ sort.Sort(byPath(imports))
+ pkg.SetImports(imports)
+
+ // package was imported completely and without errors
+ pkg.MarkComplete()
+
+ return pkg
+}
+
+type byPath []*types.Package
+
+func (a byPath) Len() int { return len(a) }
+func (a byPath) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
+func (a byPath) Less(i, j int) bool { return a[i].Path() < a[j].Path() }
diff --git a/vendor/golang.org/x/tools/go/loader/cgo.go b/vendor/golang.org/x/tools/go/loader/cgo.go
new file mode 100644
index 0000000..299e725
--- /dev/null
+++ b/vendor/golang.org/x/tools/go/loader/cgo.go
@@ -0,0 +1,199 @@
+package loader
+
+// This file handles cgo preprocessing of files containing `import "C"`.
+//
+// DESIGN
+//
+// The approach taken is to run the cgo processor on the package's
+// CgoFiles and parse the output, faking the filenames of the
+// resulting ASTs so that the synthetic file containing the C types is
+// called "C" (e.g. "~/go/src/net/C") and the preprocessed files
+// have their original names (e.g. "~/go/src/net/cgo_unix.go"),
+// not the names of the actual temporary files.
+//
+// The advantage of this approach is its fidelity to 'go build'. The
+// downside is that the token.Position.Offset for each AST node is
+// incorrect, being an offset within the temporary file. Line numbers
+// should still be correct because of the //line comments.
+//
+// The logic of this file is mostly plundered from the 'go build'
+// tool, which also invokes the cgo preprocessor.
+//
+//
+// REJECTED ALTERNATIVE
+//
+// An alternative approach that we explored is to extend go/types'
+// Importer mechanism to provide the identity of the importing package
+// so that each time `import "C"` appears it resolves to a different
+// synthetic package containing just the objects needed in that case.
+// The loader would invoke cgo but parse only the cgo_types.go file
+// defining the package-level objects, discarding the other files
+// resulting from preprocessing.
+//
+// The benefit of this approach would have been that source-level
+// syntax information would correspond exactly to the original cgo
+// file, with no preprocessing involved, making source tools like
+// godoc, oracle, and eg happy. However, the approach was rejected
+// due to the additional complexity it would impose on go/types. (It
+// made for a beautiful demo, though.)
+//
+// cgo files, despite their *.go extension, are not legal Go source
+// files per the specification since they may refer to unexported
+// members of package "C" such as C.int. Also, a function such as
+// C.getpwent has in effect two types, one matching its C type and one
+// which additionally returns (errno C.int). The cgo preprocessor
+// uses name mangling to distinguish these two functions in the
+// processed code, but go/types would need to duplicate this logic in
+// its handling of function calls, analogous to the treatment of map
+// lookups in which y=m[k] and y,ok=m[k] are both legal.
+
+import (
+ "fmt"
+ "go/ast"
+ "go/build"
+ "go/parser"
+ "go/token"
+ "io/ioutil"
+ "log"
+ "os"
+ "os/exec"
+ "path/filepath"
+ "regexp"
+ "strings"
+)
+
+// processCgoFiles invokes the cgo preprocessor on bp.CgoFiles, parses
+// the output and returns the resulting ASTs.
+//
+func processCgoFiles(bp *build.Package, fset *token.FileSet, DisplayPath func(path string) string, mode parser.Mode) ([]*ast.File, error) {
+ tmpdir, err := ioutil.TempDir("", strings.Replace(bp.ImportPath, "/", "_", -1)+"_C")
+ if err != nil {
+ return nil, err
+ }
+ defer os.RemoveAll(tmpdir)
+
+ pkgdir := bp.Dir
+ if DisplayPath != nil {
+ pkgdir = DisplayPath(pkgdir)
+ }
+
+ cgoFiles, cgoDisplayFiles, err := runCgo(bp, pkgdir, tmpdir)
+ if err != nil {
+ return nil, err
+ }
+ var files []*ast.File
+ for i := range cgoFiles {
+ rd, err := os.Open(cgoFiles[i])
+ if err != nil {
+ return nil, err
+ }
+ defer rd.Close()
+ display := filepath.Join(bp.Dir, cgoDisplayFiles[i])
+ f, err := parser.ParseFile(fset, display, rd, mode)
+ if err != nil {
+ return nil, err
+ }
+ files = append(files, f)
+ }
+ return files, nil
+}
+
+var cgoRe = regexp.MustCompile(`[/\\:]`)
+
+// runCgo invokes the cgo preprocessor on bp.CgoFiles and returns two
+// lists of files: the resulting processed files (in temporary
+// directory tmpdir) and the corresponding names of the unprocessed files.
+//
+// runCgo is adapted from (*builder).cgo in
+// $GOROOT/src/cmd/go/build.go, but these features are unsupported:
+// pkg-config, Objective C, CGOPKGPATH, CGO_FLAGS.
+//
+func runCgo(bp *build.Package, pkgdir, tmpdir string) (files, displayFiles []string, err error) {
+ cgoCPPFLAGS, _, _, _ := cflags(bp, true)
+ _, cgoexeCFLAGS, _, _ := cflags(bp, false)
+
+ if len(bp.CgoPkgConfig) > 0 {
+ return nil, nil, fmt.Errorf("cgo pkg-config not supported")
+ }
+
+ // Allows including _cgo_export.h from .[ch] files in the package.
+ cgoCPPFLAGS = append(cgoCPPFLAGS, "-I", tmpdir)
+
+ // _cgo_gotypes.go (displayed "C") contains the type definitions.
+ files = append(files, filepath.Join(tmpdir, "_cgo_gotypes.go"))
+ displayFiles = append(displayFiles, "C")
+ for _, fn := range bp.CgoFiles {
+ // "foo.cgo1.go" (displayed "foo.go") is the processed Go source.
+ f := cgoRe.ReplaceAllString(fn[:len(fn)-len("go")], "_")
+ files = append(files, filepath.Join(tmpdir, f+"cgo1.go"))
+ displayFiles = append(displayFiles, fn)
+ }
+
+ var cgoflags []string
+ if bp.Goroot && bp.ImportPath == "runtime/cgo" {
+ cgoflags = append(cgoflags, "-import_runtime_cgo=false")
+ }
+ if bp.Goroot && bp.ImportPath == "runtime/race" || bp.ImportPath == "runtime/cgo" {
+ cgoflags = append(cgoflags, "-import_syscall=false")
+ }
+
+ args := stringList(
+ "go", "tool", "cgo", "-objdir", tmpdir, cgoflags, "--",
+ cgoCPPFLAGS, cgoexeCFLAGS, bp.CgoFiles,
+ )
+ if false {
+ log.Printf("Running cgo for package %q: %s (dir=%s)", bp.ImportPath, args, pkgdir)
+ }
+ cmd := exec.Command(args[0], args[1:]...)
+ cmd.Dir = pkgdir
+ cmd.Stdout = os.Stderr
+ cmd.Stderr = os.Stderr
+ if err := cmd.Run(); err != nil {
+ return nil, nil, fmt.Errorf("cgo failed: %s: %s", args, err)
+ }
+
+ return files, displayFiles, nil
+}
+
+// -- unmodified from 'go build' ---------------------------------------
+
+// Return the flags to use when invoking the C or C++ compilers, or cgo.
+func cflags(p *build.Package, def bool) (cppflags, cflags, cxxflags, ldflags []string) {
+ var defaults string
+ if def {
+ defaults = "-g -O2"
+ }
+
+ cppflags = stringList(envList("CGO_CPPFLAGS", ""), p.CgoCPPFLAGS)
+ cflags = stringList(envList("CGO_CFLAGS", defaults), p.CgoCFLAGS)
+ cxxflags = stringList(envList("CGO_CXXFLAGS", defaults), p.CgoCXXFLAGS)
+ ldflags = stringList(envList("CGO_LDFLAGS", defaults), p.CgoLDFLAGS)
+ return
+}
+
+// envList returns the value of the given environment variable broken
+// into fields, using the default value when the variable is empty.
+func envList(key, def string) []string {
+ v := os.Getenv(key)
+ if v == "" {
+ v = def
+ }
+ return strings.Fields(v)
+}
+
+// stringList's arguments should be a sequence of string or []string values.
+// stringList flattens them into a single []string.
+func stringList(args ...interface{}) []string {
+ var x []string
+ for _, arg := range args {
+ switch arg := arg.(type) {
+ case []string:
+ x = append(x, arg...)
+ case string:
+ x = append(x, arg)
+ default:
+ panic("stringList: invalid argument")
+ }
+ }
+ return x
+}
diff --git a/vendor/golang.org/x/tools/go/loader/doc.go b/vendor/golang.org/x/tools/go/loader/doc.go
new file mode 100644
index 0000000..1ff4b15
--- /dev/null
+++ b/vendor/golang.org/x/tools/go/loader/doc.go
@@ -0,0 +1,189 @@
+// Copyright 2015 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package loader loads a complete Go program from source code, parsing
+// and type-checking the initial packages plus their transitive closure
+// of dependencies. The ASTs and the derived facts are retained for
+// later use.
+//
+// THIS INTERFACE IS EXPERIMENTAL AND IS LIKELY TO CHANGE.
+//
+// The package defines two primary types: Config, which specifies a
+// set of initial packages to load and various other options; and
+// Program, which is the result of successfully loading the packages
+// specified by a configuration.
+//
+// The configuration can be set directly, but *Config provides various
+// convenience methods to simplify the common cases, each of which can
+// be called any number of times. Finally, these are followed by a
+// call to Load() to actually load and type-check the program.
+//
+// var conf loader.Config
+//
+// // Use the command-line arguments to specify
+// // a set of initial packages to load from source.
+// // See FromArgsUsage for help.
+// rest, err := conf.FromArgs(os.Args[1:], wantTests)
+//
+// // Parse the specified files and create an ad hoc package with path "foo".
+// // All files must have the same 'package' declaration.
+// conf.CreateFromFilenames("foo", "foo.go", "bar.go")
+//
+// // Create an ad hoc package with path "foo" from
+// // the specified already-parsed files.
+// // All ASTs must have the same 'package' declaration.
+// conf.CreateFromFiles("foo", parsedFiles)
+//
+// // Add "runtime" to the set of packages to be loaded.
+// conf.Import("runtime")
+//
+// // Adds "fmt" and "fmt_test" to the set of packages
+// // to be loaded. "fmt" will include *_test.go files.
+// conf.ImportWithTests("fmt")
+//
+// // Finally, load all the packages specified by the configuration.
+// prog, err := conf.Load()
+//
+// See examples_test.go for examples of API usage.
+//
+//
+// CONCEPTS AND TERMINOLOGY
+//
+// An AD HOC package is one specified as a set of source files on the
+// command line. In the simplest case, it may consist of a single file
+// such as $GOROOT/src/net/http/triv.go.
+//
+// EXTERNAL TEST packages are those comprised of a set of *_test.go
+// files all with the same 'package foo_test' declaration, all in the
+// same directory. (go/build.Package calls these files XTestFiles.)
+//
+// An IMPORTABLE package is one that can be referred to by some import
+// spec. The Path() of each importable package is unique within a
+// Program.
+//
+// ad hoc packages and external test packages are NON-IMPORTABLE. The
+// Path() of an ad hoc package is inferred from the package
+// declarations of its files and is therefore not a unique package key.
+// For example, Config.CreatePkgs may specify two initial ad hoc
+// packages both called "main".
+//
+// An AUGMENTED package is an importable package P plus all the
+// *_test.go files with same 'package foo' declaration as P.
+// (go/build.Package calls these files TestFiles.)
+//
+// The INITIAL packages are those specified in the configuration. A
+// DEPENDENCY is a package loaded to satisfy an import in an initial
+// package or another dependency.
+//
+package loader
+
+// IMPLEMENTATION NOTES
+//
+// 'go test', in-package test files, and import cycles
+// ---------------------------------------------------
+//
+// An external test package may depend upon members of the augmented
+// package that are not in the unaugmented package, such as functions
+// that expose internals. (See bufio/export_test.go for an example.)
+// So, the loader must ensure that for each external test package
+// it loads, it also augments the corresponding non-test package.
+//
+// The import graph over n unaugmented packages must be acyclic; the
+// import graph over n-1 unaugmented packages plus one augmented
+// package must also be acyclic. ('go test' relies on this.) But the
+// import graph over n augmented packages may contain cycles.
+//
+// First, all the (unaugmented) non-test packages and their
+// dependencies are imported in the usual way; the loader reports an
+// error if it detects an import cycle.
+//
+// Then, each package P for which testing is desired is augmented by
+// the list P' of its in-package test files, by calling
+// (*types.Checker).Files. This arrangement ensures that P' may
+// reference definitions within P, but P may not reference definitions
+// within P'. Furthermore, P' may import any other package, including
+// ones that depend upon P, without an import cycle error.
+//
+// Consider two packages A and B, both of which have lists of
+// in-package test files we'll call A' and B', and which have the
+// following import graph edges:
+// B imports A
+// B' imports A
+// A' imports B
+// This last edge would be expected to create an error were it not
+// for the special type-checking discipline above.
+// Cycles of size greater than two are possible. For example:
+// compress/bzip2/bzip2_test.go (package bzip2) imports "io/ioutil"
+// io/ioutil/tempfile_test.go (package ioutil) imports "regexp"
+// regexp/exec_test.go (package regexp) imports "compress/bzip2"
+//
+//
+// Concurrency
+// -----------
+//
+// Let us define the import dependency graph as follows. Each node is a
+// list of files passed to (Checker).Files at once. Many of these lists
+// are the production code of an importable Go package, so those nodes
+// are labelled by the package's import path. The remaining nodes are
+// ad hoc packages and lists of in-package *_test.go files that augment
+// an importable package; those nodes have no label.
+//
+// The edges of the graph represent import statements appearing within a
+// file. An edge connects a node (a list of files) to the node it
+// imports, which is importable and thus always labelled.
+//
+// Loading is controlled by this dependency graph.
+//
+// To reduce I/O latency, we start loading a package's dependencies
+// asynchronously as soon as we've parsed its files and enumerated its
+// imports (scanImports). This performs a preorder traversal of the
+// import dependency graph.
+//
+// To exploit hardware parallelism, we type-check unrelated packages in
+// parallel, where "unrelated" means not ordered by the partial order of
+// the import dependency graph.
+//
+// We use a concurrency-safe blocking cache (importer.imported) to
+// record the results of type-checking, whether success or failure. An
+// entry is created in this cache by startLoad the first time the
+// package is imported. The first goroutine to request an entry becomes
+// responsible for completing the task and broadcasting completion to
+// subsequent requestors, which block until then.
+//
+// Type checking occurs in (parallel) postorder: we cannot type-check a
+// set of files until we have loaded and type-checked all of their
+// immediate dependencies (and thus all of their transitive
+// dependencies). If the input were guaranteed free of import cycles,
+// this would be trivial: we could simply wait for completion of the
+// dependencies and then invoke the typechecker.
+//
+// But as we saw in the 'go test' section above, some cycles in the
+// import graph over packages are actually legal, so long as the
+// cycle-forming edge originates in the in-package test files that
+// augment the package. This explains why the nodes of the import
+// dependency graph are not packages, but lists of files: the unlabelled
+// nodes avoid the cycles. Consider packages A and B where B imports A
+// and A's in-package tests AT import B. The naively constructed import
+// graph over packages would contain a cycle (A+AT) --> B --> (A+AT) but
+// the graph over lists of files is AT --> B --> A, where AT is an
+// unlabelled node.
+//
+// Awaiting completion of the dependencies in a cyclic graph would
+// deadlock, so we must materialize the import dependency graph (as
+// importer.graph) and check whether each import edge forms a cycle. If
+// x imports y, and the graph already contains a path from y to x, then
+// there is an import cycle, in which case the processing of x must not
+// wait for the completion of processing of y.
+//
+// When the type-checker makes a callback (doImport) to the loader for a
+// given import edge, there are two possible cases. In the normal case,
+// the dependency has already been completely type-checked; doImport
+// does a cache lookup and returns it. In the cyclic case, the entry in
+// the cache is still necessarily incomplete, indicating a cycle. We
+// perform the cycle check again to obtain the error message, and return
+// the error.
+//
+// The result of using concurrency is about a 2.5x speedup for stdlib_test.
+
+// TODO(adonovan): overhaul the package documentation.
diff --git a/vendor/golang.org/x/tools/go/loader/loader.go b/vendor/golang.org/x/tools/go/loader/loader.go
new file mode 100644
index 0000000..bbacc5b
--- /dev/null
+++ b/vendor/golang.org/x/tools/go/loader/loader.go
@@ -0,0 +1,966 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package loader
+
+// See doc.go for package documentation and implementation notes.
+
+import (
+ "errors"
+ "fmt"
+ "go/ast"
+ "go/build"
+ "go/parser"
+ "go/token"
+ "os"
+ "sort"
+ "strings"
+ "sync"
+ "time"
+
+ "golang.org/x/tools/go/ast/astutil"
+ "golang.org/x/tools/go/types"
+)
+
+const trace = false // show timing info for type-checking
+
+// Config specifies the configuration for loading a whole program from
+// Go source code.
+// The zero value for Config is a ready-to-use default configuration.
+type Config struct {
+ // Fset is the file set for the parser to use when loading the
+ // program. If nil, it may be lazily initialized by any
+ // method of Config.
+ Fset *token.FileSet
+
+ // ParserMode specifies the mode to be used by the parser when
+ // loading source packages.
+ ParserMode parser.Mode
+
+ // TypeChecker contains options relating to the type checker.
+ //
+ // The supplied IgnoreFuncBodies is not used; the effective
+ // value comes from the TypeCheckFuncBodies func below.
+ // The supplied Import function is not used either.
+ TypeChecker types.Config
+
+ // TypeCheckFuncBodies is a predicate over package import
+ // paths. A package for which the predicate is false will
+ // have its package-level declarations type checked, but not
+ // its function bodies; this can be used to quickly load
+ // dependencies from source. If nil, all func bodies are type
+ // checked.
+ TypeCheckFuncBodies func(string) bool
+
+ // If Build is non-nil, it is used to locate source packages.
+ // Otherwise &build.Default is used.
+ //
+ // By default, cgo is invoked to preprocess Go files that
+ // import the fake package "C". This behaviour can be
+ // disabled by setting CGO_ENABLED=0 in the environment prior
+ // to startup, or by setting Build.CgoEnabled=false.
+ Build *build.Context
+
+ // The current directory, used for resolving relative package
+ // references such as "./go/loader". If empty, os.Getwd will be
+ // used instead.
+ Cwd string
+
+ // If DisplayPath is non-nil, it is used to transform each
+ // file name obtained from Build.Import(). This can be used
+ // to prevent a virtualized build.Config's file names from
+ // leaking into the user interface.
+ DisplayPath func(path string) string
+
+ // If AllowErrors is true, Load will return a Program even
+ // if some of the its packages contained I/O, parser or type
+ // errors; such errors are accessible via PackageInfo.Errors. If
+ // false, Load will fail if any package had an error.
+ AllowErrors bool
+
+ // CreatePkgs specifies a list of non-importable initial
+ // packages to create. The resulting packages will appear in
+ // the corresponding elements of the Program.Created slice.
+ CreatePkgs []PkgSpec
+
+ // ImportPkgs specifies a set of initial packages to load from
+ // source. The map keys are package import paths, used to
+ // locate the package relative to $GOROOT.
+ //
+ // The map value indicates whether to load tests. If true, Load
+ // will add and type-check two lists of files to the package:
+ // non-test files followed by in-package *_test.go files. In
+ // addition, it will append the external test package (if any)
+ // to Program.Created.
+ ImportPkgs map[string]bool
+
+ // FindPackage is called during Load to create the build.Package
+ // for a given import path. If nil, a default implementation
+ // based on ctxt.Import is used. A client may use this hook to
+ // adapt to a proprietary build system that does not follow the
+ // "go build" layout conventions, for example.
+ //
+ // It must be safe to call concurrently from multiple goroutines.
+ FindPackage func(ctxt *build.Context, importPath string) (*build.Package, error)
+}
+
+// A PkgSpec specifies a non-importable package to be created by Load.
+// Files are processed first, but typically only one of Files and
+// Filenames is provided. The path needn't be globally unique.
+//
+type PkgSpec struct {
+ Path string // import path ("" => use package declaration)
+ Files []*ast.File // ASTs of already-parsed files
+ Filenames []string // names of files to be parsed
+}
+
+// A Program is a Go program loaded from source as specified by a Config.
+type Program struct {
+ Fset *token.FileSet // the file set for this program
+
+ // Created[i] contains the initial package whose ASTs or
+ // filenames were supplied by Config.CreatePkgs[i], followed by
+ // the external test package, if any, of each package in
+ // Config.ImportPkgs ordered by ImportPath.
+ Created []*PackageInfo
+
+ // Imported contains the initially imported packages,
+ // as specified by Config.ImportPkgs.
+ Imported map[string]*PackageInfo
+
+ // AllPackages contains the PackageInfo of every package
+ // encountered by Load: all initial packages and all
+ // dependencies, including incomplete ones.
+ AllPackages map[*types.Package]*PackageInfo
+
+ // importMap is the canonical mapping of import paths to
+ // packages. It contains all Imported initial packages, but not
+ // Created ones, and all imported dependencies.
+ importMap map[string]*types.Package
+}
+
+// PackageInfo holds the ASTs and facts derived by the type-checker
+// for a single package.
+//
+// Not mutated once exposed via the API.
+//
+type PackageInfo struct {
+ Pkg *types.Package
+ Importable bool // true if 'import "Pkg.Path()"' would resolve to this
+ TransitivelyErrorFree bool // true if Pkg and all its dependencies are free of errors
+ Files []*ast.File // syntax trees for the package's files
+ Errors []error // non-nil if the package had errors
+ types.Info // type-checker deductions.
+
+ checker *types.Checker // transient type-checker state
+ errorFunc func(error)
+}
+
+func (info *PackageInfo) String() string { return info.Pkg.Path() }
+
+func (info *PackageInfo) appendError(err error) {
+ if info.errorFunc != nil {
+ info.errorFunc(err)
+ } else {
+ fmt.Fprintln(os.Stderr, err)
+ }
+ info.Errors = append(info.Errors, err)
+}
+
+func (conf *Config) fset() *token.FileSet {
+ if conf.Fset == nil {
+ conf.Fset = token.NewFileSet()
+ }
+ return conf.Fset
+}
+
+// ParseFile is a convenience function (intended for testing) that invokes
+// the parser using the Config's FileSet, which is initialized if nil.
+//
+// src specifies the parser input as a string, []byte, or io.Reader, and
+// filename is its apparent name. If src is nil, the contents of
+// filename are read from the file system.
+//
+func (conf *Config) ParseFile(filename string, src interface{}) (*ast.File, error) {
+ // TODO(adonovan): use conf.build() etc like parseFiles does.
+ return parser.ParseFile(conf.fset(), filename, src, conf.ParserMode)
+}
+
+// FromArgsUsage is a partial usage message that applications calling
+// FromArgs may wish to include in their -help output.
+const FromArgsUsage = `
+ is a list of arguments denoting a set of initial packages.
+It may take one of two forms:
+
+1. A list of *.go source files.
+
+ All of the specified files are loaded, parsed and type-checked
+ as a single package. All the files must belong to the same directory.
+
+2. A list of import paths, each denoting a package.
+
+ The package's directory is found relative to the $GOROOT and
+ $GOPATH using similar logic to 'go build', and the *.go files in
+ that directory are loaded, parsed and type-checked as a single
+ package.
+
+ In addition, all *_test.go files in the directory are then loaded
+ and parsed. Those files whose package declaration equals that of
+ the non-*_test.go files are included in the primary package. Test
+ files whose package declaration ends with "_test" are type-checked
+ as another package, the 'external' test package, so that a single
+ import path may denote two packages. (Whether this behaviour is
+ enabled is tool-specific, and may depend on additional flags.)
+
+A '--' argument terminates the list of packages.
+`
+
+// FromArgs interprets args as a set of initial packages to load from
+// source and updates the configuration. It returns the list of
+// unconsumed arguments.
+//
+// It is intended for use in command-line interfaces that require a
+// set of initial packages to be specified; see FromArgsUsage message
+// for details.
+//
+// Only superficial errors are reported at this stage; errors dependent
+// on I/O are detected during Load.
+//
+func (conf *Config) FromArgs(args []string, xtest bool) ([]string, error) {
+ var rest []string
+ for i, arg := range args {
+ if arg == "--" {
+ rest = args[i+1:]
+ args = args[:i]
+ break // consume "--" and return the remaining args
+ }
+ }
+
+ if len(args) > 0 && strings.HasSuffix(args[0], ".go") {
+ // Assume args is a list of a *.go files
+ // denoting a single ad hoc package.
+ for _, arg := range args {
+ if !strings.HasSuffix(arg, ".go") {
+ return nil, fmt.Errorf("named files must be .go files: %s", arg)
+ }
+ }
+ conf.CreateFromFilenames("", args...)
+ } else {
+ // Assume args are directories each denoting a
+ // package and (perhaps) an external test, iff xtest.
+ for _, arg := range args {
+ if xtest {
+ conf.ImportWithTests(arg)
+ } else {
+ conf.Import(arg)
+ }
+ }
+ }
+
+ return rest, nil
+}
+
+// CreateFromFilenames is a convenience function that adds
+// a conf.CreatePkgs entry to create a package of the specified *.go
+// files.
+//
+func (conf *Config) CreateFromFilenames(path string, filenames ...string) {
+ conf.CreatePkgs = append(conf.CreatePkgs, PkgSpec{Path: path, Filenames: filenames})
+}
+
+// CreateFromFiles is a convenience function that adds a conf.CreatePkgs
+// entry to create package of the specified path and parsed files.
+//
+func (conf *Config) CreateFromFiles(path string, files ...*ast.File) {
+ conf.CreatePkgs = append(conf.CreatePkgs, PkgSpec{Path: path, Files: files})
+}
+
+// ImportWithTests is a convenience function that adds path to
+// ImportPkgs, the set of initial source packages located relative to
+// $GOPATH. The package will be augmented by any *_test.go files in
+// its directory that contain a "package x" (not "package x_test")
+// declaration.
+//
+// In addition, if any *_test.go files contain a "package x_test"
+// declaration, an additional package comprising just those files will
+// be added to CreatePkgs.
+//
+func (conf *Config) ImportWithTests(path string) { conf.addImport(path, true) }
+
+// Import is a convenience function that adds path to ImportPkgs, the
+// set of initial packages that will be imported from source.
+//
+func (conf *Config) Import(path string) { conf.addImport(path, false) }
+
+func (conf *Config) addImport(path string, tests bool) {
+ if path == "C" || path == "unsafe" {
+ return // ignore; not a real package
+ }
+ if conf.ImportPkgs == nil {
+ conf.ImportPkgs = make(map[string]bool)
+ }
+ conf.ImportPkgs[path] = conf.ImportPkgs[path] || tests
+}
+
+// PathEnclosingInterval returns the PackageInfo and ast.Node that
+// contain source interval [start, end), and all the node's ancestors
+// up to the AST root. It searches all ast.Files of all packages in prog.
+// exact is defined as for astutil.PathEnclosingInterval.
+//
+// The zero value is returned if not found.
+//
+func (prog *Program) PathEnclosingInterval(start, end token.Pos) (pkg *PackageInfo, path []ast.Node, exact bool) {
+ for _, info := range prog.AllPackages {
+ for _, f := range info.Files {
+ if f.Pos() == token.NoPos {
+ // This can happen if the parser saw
+ // too many errors and bailed out.
+ // (Use parser.AllErrors to prevent that.)
+ continue
+ }
+ if !tokenFileContainsPos(prog.Fset.File(f.Pos()), start) {
+ continue
+ }
+ if path, exact := astutil.PathEnclosingInterval(f, start, end); path != nil {
+ return info, path, exact
+ }
+ }
+ }
+ return nil, nil, false
+}
+
+// InitialPackages returns a new slice containing the set of initial
+// packages (Created + Imported) in unspecified order.
+//
+func (prog *Program) InitialPackages() []*PackageInfo {
+ infos := make([]*PackageInfo, 0, len(prog.Created)+len(prog.Imported))
+ infos = append(infos, prog.Created...)
+ for _, info := range prog.Imported {
+ infos = append(infos, info)
+ }
+ return infos
+}
+
+// Package returns the ASTs and results of type checking for the
+// specified package.
+func (prog *Program) Package(path string) *PackageInfo {
+ if info, ok := prog.AllPackages[prog.importMap[path]]; ok {
+ return info
+ }
+ for _, info := range prog.Created {
+ if path == info.Pkg.Path() {
+ return info
+ }
+ }
+ return nil
+}
+
+// ---------- Implementation ----------
+
+// importer holds the working state of the algorithm.
+type importer struct {
+ conf *Config // the client configuration
+ start time.Time // for logging
+
+ progMu sync.Mutex // guards prog
+ prog *Program // the resulting program
+
+ importedMu sync.Mutex // guards imported
+ imported map[string]*importInfo // all imported packages (incl. failures) by import path
+
+ // import dependency graph: graph[x][y] => x imports y
+ //
+ // Since non-importable packages cannot be cyclic, we ignore
+ // their imports, thus we only need the subgraph over importable
+ // packages. Nodes are identified by their import paths.
+ graphMu sync.Mutex
+ graph map[string]map[string]bool
+}
+
+// importInfo tracks the success or failure of a single import.
+//
+// Upon completion, exactly one of info and err is non-nil:
+// info on successful creation of a package, err otherwise.
+// A successful package may still contain type errors.
+//
+type importInfo struct {
+ path string // import path
+ mu sync.Mutex // guards the following fields prior to completion
+ info *PackageInfo // results of typechecking (including errors)
+ err error // reason for failure to create a package
+ complete sync.Cond // complete condition is that one of info, err is non-nil.
+}
+
+// awaitCompletion blocks until ii is complete,
+// i.e. the info and err fields are safe to inspect without a lock.
+// It is concurrency-safe and idempotent.
+func (ii *importInfo) awaitCompletion() {
+ ii.mu.Lock()
+ for ii.info == nil && ii.err == nil {
+ ii.complete.Wait()
+ }
+ ii.mu.Unlock()
+}
+
+// Complete marks ii as complete.
+// Its info and err fields will not be subsequently updated.
+func (ii *importInfo) Complete(info *PackageInfo, err error) {
+ if info == nil && err == nil {
+ panic("Complete(nil, nil)")
+ }
+ ii.mu.Lock()
+ ii.info = info
+ ii.err = err
+ ii.complete.Broadcast()
+ ii.mu.Unlock()
+}
+
+// Load creates the initial packages specified by conf.{Create,Import}Pkgs,
+// loading their dependencies packages as needed.
+//
+// On success, Load returns a Program containing a PackageInfo for
+// each package. On failure, it returns an error.
+//
+// If AllowErrors is true, Load will return a Program even if some
+// packages contained I/O, parser or type errors, or if dependencies
+// were missing. (Such errors are accessible via PackageInfo.Errors. If
+// false, Load will fail if any package had an error.
+//
+// It is an error if no packages were loaded.
+//
+func (conf *Config) Load() (*Program, error) {
+ // Create a simple default error handler for parse/type errors.
+ if conf.TypeChecker.Error == nil {
+ conf.TypeChecker.Error = func(e error) { fmt.Fprintln(os.Stderr, e) }
+ }
+
+ // Set default working directory for relative package references.
+ if conf.Cwd == "" {
+ var err error
+ conf.Cwd, err = os.Getwd()
+ if err != nil {
+ return nil, err
+ }
+ }
+
+ // Install default FindPackage hook using go/build logic.
+ if conf.FindPackage == nil {
+ conf.FindPackage = func(ctxt *build.Context, path string) (*build.Package, error) {
+ // TODO(adonovan): cache calls to build.Import
+ // so we don't do it three times per test package.
+ bp, err := ctxt.Import(path, conf.Cwd, 0)
+ if _, ok := err.(*build.NoGoError); ok {
+ return bp, nil // empty directory is not an error
+ }
+ return bp, err
+ }
+ }
+
+ prog := &Program{
+ Fset: conf.fset(),
+ Imported: make(map[string]*PackageInfo),
+ importMap: make(map[string]*types.Package),
+ AllPackages: make(map[*types.Package]*PackageInfo),
+ }
+
+ imp := importer{
+ conf: conf,
+ prog: prog,
+ imported: make(map[string]*importInfo),
+ start: time.Now(),
+ graph: make(map[string]map[string]bool),
+ }
+
+ // -- loading proper (concurrent phase) --------------------------------
+
+ var errpkgs []string // packages that contained errors
+
+ // Load the initially imported packages and their dependencies,
+ // in parallel.
+ for _, ii := range imp.loadAll("", conf.ImportPkgs) {
+ if ii.err != nil {
+ conf.TypeChecker.Error(ii.err) // failed to create package
+ errpkgs = append(errpkgs, ii.path)
+ continue
+ }
+ prog.Imported[ii.info.Pkg.Path()] = ii.info
+ }
+
+ // Augment the designated initial packages by their tests.
+ // Dependencies are loaded in parallel.
+ var xtestPkgs []*build.Package
+ for path, augment := range conf.ImportPkgs {
+ if !augment {
+ continue
+ }
+
+ bp, err := conf.FindPackage(conf.build(), path)
+ if err != nil {
+ // Package not found, or can't even parse package declaration.
+ // Already reported by previous loop; ignore it.
+ continue
+ }
+
+ // Needs external test package?
+ if len(bp.XTestGoFiles) > 0 {
+ xtestPkgs = append(xtestPkgs, bp)
+ }
+
+ imp.importedMu.Lock() // (unnecessary, we're sequential here)
+ ii, ok := imp.imported[path]
+ // Paranoid checks added due to issue #11012.
+ if !ok {
+ // Unreachable.
+ // The previous loop called loadAll and thus
+ // startLoad for each path in ImportPkgs, which
+ // populates imp.imported[path] with a non-zero value.
+ panic(fmt.Sprintf("imported[%q] not found", path))
+ }
+ if ii == nil {
+ // Unreachable.
+ // The ii values in this loop are the same as in
+ // the previous loop, which enforced the invariant
+ // that at least one of ii.err and ii.info is non-nil.
+ panic(fmt.Sprintf("imported[%q] == nil", path))
+ }
+ if ii.err != nil {
+ // The sole possible cause is failure of the
+ // FindPackage call in (*importer).load,
+ // but we rechecked that condition above.
+ // Perhaps the state of the file system changed
+ // in between? Seems unlikely.
+ panic(fmt.Sprintf("imported[%q].err = %v", path, ii.err))
+ }
+ if ii.info == nil {
+ // Unreachable.
+ // Complete has this postcondition:
+ // ii.err != nil || ii.info != nil
+ // and we know that ii.err == nil here.
+ panic(fmt.Sprintf("imported[%q].info = nil", path))
+ }
+ info := ii.info
+ imp.importedMu.Unlock()
+
+ // Parse the in-package test files.
+ files, errs := imp.conf.parsePackageFiles(bp, 't')
+ for _, err := range errs {
+ info.appendError(err)
+ }
+
+ // The test files augmenting package P cannot be imported,
+ // but may import packages that import P,
+ // so we must disable the cycle check.
+ imp.addFiles(info, files, false)
+ }
+
+ createPkg := func(path string, files []*ast.File, errs []error) {
+ info := imp.newPackageInfo(path)
+ for _, err := range errs {
+ info.appendError(err)
+ }
+
+ // Ad hoc packages are non-importable,
+ // so no cycle check is needed.
+ // addFiles loads dependencies in parallel.
+ imp.addFiles(info, files, false)
+ prog.Created = append(prog.Created, info)
+ }
+
+ // Create packages specified by conf.CreatePkgs.
+ for _, cp := range conf.CreatePkgs {
+ files, errs := parseFiles(conf.fset(), conf.build(), nil, ".", cp.Filenames, conf.ParserMode)
+ files = append(files, cp.Files...)
+
+ path := cp.Path
+ if path == "" {
+ if len(files) > 0 {
+ path = files[0].Name.Name
+ } else {
+ path = "(unnamed)"
+ }
+ }
+ createPkg(path, files, errs)
+ }
+
+ // Create external test packages.
+ sort.Sort(byImportPath(xtestPkgs))
+ for _, bp := range xtestPkgs {
+ files, errs := imp.conf.parsePackageFiles(bp, 'x')
+ createPkg(bp.ImportPath+"_test", files, errs)
+ }
+
+ // -- finishing up (sequential) ----------------------------------------
+
+ if len(prog.Imported)+len(prog.Created) == 0 {
+ return nil, errors.New("no initial packages were loaded")
+ }
+
+ // Create infos for indirectly imported packages.
+ // e.g. incomplete packages without syntax, loaded from export data.
+ for _, obj := range prog.importMap {
+ info := prog.AllPackages[obj]
+ if info == nil {
+ prog.AllPackages[obj] = &PackageInfo{Pkg: obj, Importable: true}
+ } else {
+ // finished
+ info.checker = nil
+ info.errorFunc = nil
+ }
+ }
+
+ if !conf.AllowErrors {
+ // Report errors in indirectly imported packages.
+ for _, info := range prog.AllPackages {
+ if len(info.Errors) > 0 {
+ errpkgs = append(errpkgs, info.Pkg.Path())
+ }
+ }
+ if errpkgs != nil {
+ var more string
+ if len(errpkgs) > 3 {
+ more = fmt.Sprintf(" and %d more", len(errpkgs)-3)
+ errpkgs = errpkgs[:3]
+ }
+ return nil, fmt.Errorf("couldn't load packages due to errors: %s%s",
+ strings.Join(errpkgs, ", "), more)
+ }
+ }
+
+ markErrorFreePackages(prog.AllPackages)
+
+ return prog, nil
+}
+
+type byImportPath []*build.Package
+
+func (b byImportPath) Len() int { return len(b) }
+func (b byImportPath) Less(i, j int) bool { return b[i].ImportPath < b[j].ImportPath }
+func (b byImportPath) Swap(i, j int) { b[i], b[j] = b[j], b[i] }
+
+// markErrorFreePackages sets the TransitivelyErrorFree flag on all
+// applicable packages.
+func markErrorFreePackages(allPackages map[*types.Package]*PackageInfo) {
+ // Build the transpose of the import graph.
+ importedBy := make(map[*types.Package]map[*types.Package]bool)
+ for P := range allPackages {
+ for _, Q := range P.Imports() {
+ clients, ok := importedBy[Q]
+ if !ok {
+ clients = make(map[*types.Package]bool)
+ importedBy[Q] = clients
+ }
+ clients[P] = true
+ }
+ }
+
+ // Find all packages reachable from some error package.
+ reachable := make(map[*types.Package]bool)
+ var visit func(*types.Package)
+ visit = func(p *types.Package) {
+ if !reachable[p] {
+ reachable[p] = true
+ for q := range importedBy[p] {
+ visit(q)
+ }
+ }
+ }
+ for _, info := range allPackages {
+ if len(info.Errors) > 0 {
+ visit(info.Pkg)
+ }
+ }
+
+ // Mark the others as "transitively error-free".
+ for _, info := range allPackages {
+ if !reachable[info.Pkg] {
+ info.TransitivelyErrorFree = true
+ }
+ }
+}
+
+// build returns the effective build context.
+func (conf *Config) build() *build.Context {
+ if conf.Build != nil {
+ return conf.Build
+ }
+ return &build.Default
+}
+
+// parsePackageFiles enumerates the files belonging to package path,
+// then loads, parses and returns them, plus a list of I/O or parse
+// errors that were encountered.
+//
+// 'which' indicates which files to include:
+// 'g': include non-test *.go source files (GoFiles + processed CgoFiles)
+// 't': include in-package *_test.go source files (TestGoFiles)
+// 'x': include external *_test.go source files. (XTestGoFiles)
+//
+func (conf *Config) parsePackageFiles(bp *build.Package, which rune) ([]*ast.File, []error) {
+ var filenames []string
+ switch which {
+ case 'g':
+ filenames = bp.GoFiles
+ case 't':
+ filenames = bp.TestGoFiles
+ case 'x':
+ filenames = bp.XTestGoFiles
+ default:
+ panic(which)
+ }
+
+ files, errs := parseFiles(conf.fset(), conf.build(), conf.DisplayPath, bp.Dir, filenames, conf.ParserMode)
+
+ // Preprocess CgoFiles and parse the outputs (sequentially).
+ if which == 'g' && bp.CgoFiles != nil {
+ cgofiles, err := processCgoFiles(bp, conf.fset(), conf.DisplayPath, conf.ParserMode)
+ if err != nil {
+ errs = append(errs, err)
+ } else {
+ files = append(files, cgofiles...)
+ }
+ }
+
+ return files, errs
+}
+
+// doImport imports the package denoted by path.
+// It implements the types.Importer signature.
+//
+// imports is the type-checker's package canonicalization map.
+//
+// It returns an error if a package could not be created
+// (e.g. go/build or parse error), but type errors are reported via
+// the types.Config.Error callback (the first of which is also saved
+// in the package's PackageInfo).
+//
+// Idempotent.
+//
+func (imp *importer) doImport(from *PackageInfo, to string) (*types.Package, error) {
+ // Package unsafe is handled specially, and has no PackageInfo.
+ // TODO(adonovan): move this check into go/types?
+ if to == "unsafe" {
+ return types.Unsafe, nil
+ }
+ if to == "C" {
+ // This should be unreachable, but ad hoc packages are
+ // not currently subject to cgo preprocessing.
+ // See https://github.com/golang/go/issues/11627.
+ return nil, fmt.Errorf(`the loader doesn't cgo-process ad hoc packages like %q; see Go issue 11627`,
+ from.Pkg.Path())
+ }
+
+ imp.importedMu.Lock()
+ ii := imp.imported[to]
+ imp.importedMu.Unlock()
+ if ii == nil {
+ panic("internal error: unexpected import: " + to)
+ }
+ if ii.err != nil {
+ return nil, ii.err
+ }
+ if ii.info != nil {
+ return ii.info.Pkg, nil
+ }
+
+ // Import of incomplete package: this indicates a cycle.
+ fromPath := from.Pkg.Path()
+ if cycle := imp.findPath(to, fromPath); cycle != nil {
+ cycle = append([]string{fromPath}, cycle...)
+ return nil, fmt.Errorf("import cycle: %s", strings.Join(cycle, " -> "))
+ }
+
+ panic("internal error: import of incomplete (yet acyclic) package: " + fromPath)
+}
+
+// loadAll loads, parses, and type-checks the specified packages in
+// parallel and returns their completed importInfos in unspecified order.
+//
+// fromPath is the import path of the importing package, if it is
+// importable, "" otherwise. It is used for cycle detection.
+//
+func (imp *importer) loadAll(fromPath string, paths map[string]bool) []*importInfo {
+ result := make([]*importInfo, 0, len(paths))
+ for path := range paths {
+ result = append(result, imp.startLoad(path))
+ }
+
+ if fromPath != "" {
+ // We're loading a set of imports.
+ //
+ // We must record graph edges from the importing package
+ // to its dependencies, and check for cycles.
+ imp.graphMu.Lock()
+ deps, ok := imp.graph[fromPath]
+ if !ok {
+ deps = make(map[string]bool)
+ imp.graph[fromPath] = deps
+ }
+ for path := range paths {
+ deps[path] = true
+ }
+ imp.graphMu.Unlock()
+ }
+
+ for _, ii := range result {
+ if fromPath != "" {
+ if cycle := imp.findPath(ii.path, fromPath); cycle != nil {
+ // Cycle-forming import: we must not await its
+ // completion since it would deadlock.
+ //
+ // We don't record the error in ii since
+ // the error is really associated with the
+ // cycle-forming edge, not the package itself.
+ // (Also it would complicate the
+ // invariants of importPath completion.)
+ if trace {
+ fmt.Fprintln(os.Stderr, "import cycle: %q", cycle)
+ }
+ continue
+ }
+ }
+ ii.awaitCompletion()
+ }
+ return result
+}
+
+// findPath returns an arbitrary path from 'from' to 'to' in the import
+// graph, or nil if there was none.
+func (imp *importer) findPath(from, to string) []string {
+ imp.graphMu.Lock()
+ defer imp.graphMu.Unlock()
+
+ seen := make(map[string]bool)
+ var search func(stack []string, importPath string) []string
+ search = func(stack []string, importPath string) []string {
+ if !seen[importPath] {
+ seen[importPath] = true
+ stack = append(stack, importPath)
+ if importPath == to {
+ return stack
+ }
+ for x := range imp.graph[importPath] {
+ if p := search(stack, x); p != nil {
+ return p
+ }
+ }
+ }
+ return nil
+ }
+ return search(make([]string, 0, 20), from)
+}
+
+// startLoad initiates the loading, parsing and type-checking of the
+// specified package and its dependencies, if it has not already begun.
+//
+// It returns an importInfo, not necessarily in a completed state. The
+// caller must call awaitCompletion() before accessing its info and err
+// fields.
+//
+// startLoad is concurrency-safe and idempotent.
+//
+func (imp *importer) startLoad(path string) *importInfo {
+ imp.importedMu.Lock()
+ ii, ok := imp.imported[path]
+ if !ok {
+ ii = &importInfo{path: path}
+ ii.complete.L = &ii.mu
+ imp.imported[path] = ii
+ go func() {
+ ii.Complete(imp.load(path))
+ }()
+ }
+ imp.importedMu.Unlock()
+
+ return ii
+}
+
+// load implements package loading by parsing Go source files
+// located by go/build.
+//
+func (imp *importer) load(path string) (*PackageInfo, error) {
+ bp, err := imp.conf.FindPackage(imp.conf.build(), path)
+ if err != nil {
+ return nil, err // package not found
+ }
+ info := imp.newPackageInfo(bp.ImportPath)
+ info.Importable = true
+ files, errs := imp.conf.parsePackageFiles(bp, 'g')
+ for _, err := range errs {
+ info.appendError(err)
+ }
+
+ imp.addFiles(info, files, true)
+
+ imp.progMu.Lock()
+ imp.prog.importMap[path] = info.Pkg
+ imp.progMu.Unlock()
+
+ return info, nil
+}
+
+// addFiles adds and type-checks the specified files to info, loading
+// their dependencies if needed. The order of files determines the
+// package initialization order. It may be called multiple times on the
+// same package. Errors are appended to the info.Errors field.
+//
+// cycleCheck determines whether the imports within files create
+// dependency edges that should be checked for potential cycles.
+//
+func (imp *importer) addFiles(info *PackageInfo, files []*ast.File, cycleCheck bool) {
+ info.Files = append(info.Files, files...)
+
+ // Ensure the dependencies are loaded, in parallel.
+ var fromPath string
+ if cycleCheck {
+ fromPath = info.Pkg.Path()
+ }
+ imp.loadAll(fromPath, scanImports(files))
+
+ if trace {
+ fmt.Fprintf(os.Stderr, "%s: start %q (%d)\n",
+ time.Since(imp.start), info.Pkg.Path(), len(files))
+ }
+
+ // Ignore the returned (first) error since we
+ // already collect them all in the PackageInfo.
+ info.checker.Files(files)
+
+ if trace {
+ fmt.Fprintf(os.Stderr, "%s: stop %q\n",
+ time.Since(imp.start), info.Pkg.Path())
+ }
+}
+
+func (imp *importer) newPackageInfo(path string) *PackageInfo {
+ pkg := types.NewPackage(path, "")
+ info := &PackageInfo{
+ Pkg: pkg,
+ Info: types.Info{
+ Types: make(map[ast.Expr]types.TypeAndValue),
+ Defs: make(map[*ast.Ident]types.Object),
+ Uses: make(map[*ast.Ident]types.Object),
+ Implicits: make(map[ast.Node]types.Object),
+ Scopes: make(map[ast.Node]*types.Scope),
+ Selections: make(map[*ast.SelectorExpr]*types.Selection),
+ },
+ errorFunc: imp.conf.TypeChecker.Error,
+ }
+
+ // Copy the types.Config so we can vary it across PackageInfos.
+ tc := imp.conf.TypeChecker
+ tc.IgnoreFuncBodies = false
+ if f := imp.conf.TypeCheckFuncBodies; f != nil {
+ tc.IgnoreFuncBodies = !f(path)
+ }
+ tc.Import = func(_ map[string]*types.Package, to string) (*types.Package, error) {
+ return imp.doImport(info, to)
+ }
+ tc.Error = info.appendError // appendError wraps the user's Error function
+
+ info.checker = types.NewChecker(&tc, imp.conf.fset(), pkg, &info.Info)
+ imp.progMu.Lock()
+ imp.prog.AllPackages[pkg] = info
+ imp.progMu.Unlock()
+ return info
+}
diff --git a/vendor/golang.org/x/tools/go/loader/util.go b/vendor/golang.org/x/tools/go/loader/util.go
new file mode 100644
index 0000000..0404e99
--- /dev/null
+++ b/vendor/golang.org/x/tools/go/loader/util.go
@@ -0,0 +1,124 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package loader
+
+import (
+ "go/ast"
+ "go/build"
+ "go/parser"
+ "go/token"
+ "io"
+ "os"
+ "strconv"
+ "sync"
+
+ "golang.org/x/tools/go/buildutil"
+)
+
+// We use a counting semaphore to limit
+// the number of parallel I/O calls per process.
+var sema = make(chan bool, 10)
+
+// parseFiles parses the Go source files within directory dir and
+// returns the ASTs of the ones that could be at least partially parsed,
+// along with a list of I/O and parse errors encountered.
+//
+// I/O is done via ctxt, which may specify a virtual file system.
+// displayPath is used to transform the filenames attached to the ASTs.
+//
+func parseFiles(fset *token.FileSet, ctxt *build.Context, displayPath func(string) string, dir string, files []string, mode parser.Mode) ([]*ast.File, []error) {
+ if displayPath == nil {
+ displayPath = func(path string) string { return path }
+ }
+ var wg sync.WaitGroup
+ n := len(files)
+ parsed := make([]*ast.File, n)
+ errors := make([]error, n)
+ for i, file := range files {
+ if !buildutil.IsAbsPath(ctxt, file) {
+ file = buildutil.JoinPath(ctxt, dir, file)
+ }
+ wg.Add(1)
+ go func(i int, file string) {
+ sema <- true // wait
+ defer func() {
+ wg.Done()
+ <-sema // signal
+ }()
+ var rd io.ReadCloser
+ var err error
+ if ctxt.OpenFile != nil {
+ rd, err = ctxt.OpenFile(file)
+ } else {
+ rd, err = os.Open(file)
+ }
+ if err != nil {
+ errors[i] = err // open failed
+ return
+ }
+
+ // ParseFile may return both an AST and an error.
+ parsed[i], errors[i] = parser.ParseFile(fset, displayPath(file), rd, mode)
+ rd.Close()
+ }(i, file)
+ }
+ wg.Wait()
+
+ // Eliminate nils, preserving order.
+ var o int
+ for _, f := range parsed {
+ if f != nil {
+ parsed[o] = f
+ o++
+ }
+ }
+ parsed = parsed[:o]
+
+ o = 0
+ for _, err := range errors {
+ if err != nil {
+ errors[o] = err
+ o++
+ }
+ }
+ errors = errors[:o]
+
+ return parsed, errors
+}
+
+// scanImports returns the set of all package import paths from all
+// import specs in the specified files.
+func scanImports(files []*ast.File) map[string]bool {
+ imports := make(map[string]bool)
+ for _, f := range files {
+ for _, decl := range f.Decls {
+ if decl, ok := decl.(*ast.GenDecl); ok && decl.Tok == token.IMPORT {
+ for _, spec := range decl.Specs {
+ spec := spec.(*ast.ImportSpec)
+
+ // NB: do not assume the program is well-formed!
+ path, err := strconv.Unquote(spec.Path.Value)
+ if err != nil {
+ continue // quietly ignore the error
+ }
+ if path == "C" || path == "unsafe" {
+ continue // skip pseudo packages
+ }
+ imports[path] = true
+ }
+ }
+ }
+ }
+ return imports
+}
+
+// ---------- Internal helpers ----------
+
+// TODO(adonovan): make this a method: func (*token.File) Contains(token.Pos)
+func tokenFileContainsPos(f *token.File, pos token.Pos) bool {
+ p := int(pos)
+ base := f.Base()
+ return base <= p && p < base+f.Size()
+}
diff --git a/vendor/golang.org/x/tools/go/pointer/TODO b/vendor/golang.org/x/tools/go/pointer/TODO
new file mode 100644
index 0000000..f95e706
--- /dev/null
+++ b/vendor/golang.org/x/tools/go/pointer/TODO
@@ -0,0 +1,33 @@
+-*- text -*-
+
+Pointer analysis to-do list
+===========================
+
+CONSTRAINT GENERATION:
+- support reflection:
+ - a couple of operators are missing
+ - reflect.Values may contain lvalues (CanAddr)
+- implement native intrinsics. These vary by platform.
+- add to pts(a.panic) a label representing all runtime panics, e.g.
+ runtime.{TypeAssertionError,errorString,errorCString}.
+
+OPTIMISATIONS
+- pre-solver:
+ pointer equivalence: extend HVN to HRU
+ location equivalence
+- solver: HCD, LCD.
+- experiment with map+slice worklist in lieu of bitset.
+ It may have faster insert.
+
+MISC:
+- Test on all platforms.
+ Currently we assume these go/build tags: linux, amd64, !cgo.
+
+MAINTAINABILITY
+- Think about ways to make debugging this code easier. PTA logs
+ routinely exceed a million lines and require training to read.
+
+BUGS:
+- There's a crash bug in stdlib_test + reflection, rVCallConstraint.
+
+
diff --git a/vendor/golang.org/x/tools/go/pointer/analysis.go b/vendor/golang.org/x/tools/go/pointer/analysis.go
new file mode 100644
index 0000000..d02e536
--- /dev/null
+++ b/vendor/golang.org/x/tools/go/pointer/analysis.go
@@ -0,0 +1,447 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package pointer
+
+// This file defines the main datatypes and Analyze function of the pointer analysis.
+
+import (
+ "fmt"
+ "go/token"
+ "io"
+ "os"
+ "reflect"
+ "runtime"
+ "runtime/debug"
+ "sort"
+
+ "golang.org/x/tools/go/callgraph"
+ "golang.org/x/tools/go/ssa"
+ "golang.org/x/tools/go/types"
+ "golang.org/x/tools/go/types/typeutil"
+)
+
+const (
+ // optimization options; enable all when committing
+ optRenumber = true // enable renumbering optimization (makes logs hard to read)
+ optHVN = true // enable pointer equivalence via Hash-Value Numbering
+
+ // debugging options; disable all when committing
+ debugHVN = false // enable assertions in HVN
+ debugHVNVerbose = false // enable extra HVN logging
+ debugHVNCrossCheck = false // run solver with/without HVN and compare (caveats below)
+ debugTimers = false // show running time of each phase
+)
+
+// object.flags bitmask values.
+const (
+ otTagged = 1 << iota // type-tagged object
+ otIndirect // type-tagged object with indirect payload
+ otFunction // function object
+)
+
+// An object represents a contiguous block of memory to which some
+// (generalized) pointer may point.
+//
+// (Note: most variables called 'obj' are not *objects but nodeids
+// such that a.nodes[obj].obj != nil.)
+//
+type object struct {
+ // flags is a bitset of the node type (ot*) flags defined above.
+ flags uint32
+
+ // Number of following nodes belonging to the same "object"
+ // allocation. Zero for all other nodes.
+ size uint32
+
+ // data describes this object; it has one of these types:
+ //
+ // ssa.Value for an object allocated by an SSA operation.
+ // types.Type for an rtype instance object or *rtype-tagged object.
+ // string for an instrinsic object, e.g. the array behind os.Args.
+ // nil for an object allocated by an instrinsic.
+ // (cgn provides the identity of the intrinsic.)
+ data interface{}
+
+ // The call-graph node (=context) in which this object was allocated.
+ // May be nil for global objects: Global, Const, some Functions.
+ cgn *cgnode
+}
+
+// nodeid denotes a node.
+// It is an index within analysis.nodes.
+// We use small integers, not *node pointers, for many reasons:
+// - they are smaller on 64-bit systems.
+// - sets of them can be represented compactly in bitvectors or BDDs.
+// - order matters; a field offset can be computed by simple addition.
+type nodeid uint32
+
+// A node is an equivalence class of memory locations.
+// Nodes may be pointers, pointed-to locations, neither, or both.
+//
+// Nodes that are pointed-to locations ("labels") have an enclosing
+// object (see analysis.enclosingObject).
+//
+type node struct {
+ // If non-nil, this node is the start of an object
+ // (addressable memory location).
+ // The following obj.size nodes implicitly belong to the object;
+ // they locate their object by scanning back.
+ obj *object
+
+ // The type of the field denoted by this node. Non-aggregate,
+ // unless this is an tagged.T node (i.e. the thing
+ // pointed to by an interface) in which case typ is that type.
+ typ types.Type
+
+ // subelement indicates which directly embedded subelement of
+ // an object of aggregate type (struct, tuple, array) this is.
+ subelement *fieldInfo // e.g. ".a.b[*].c"
+
+ // Solver state for the canonical node of this pointer-
+ // equivalence class. Each node is created with its own state
+ // but they become shared after HVN.
+ solve *solverState
+}
+
+// An analysis instance holds the state of a single pointer analysis problem.
+type analysis struct {
+ config *Config // the client's control/observer interface
+ prog *ssa.Program // the program being analyzed
+ log io.Writer // log stream; nil to disable
+ panicNode nodeid // sink for panic, source for recover
+ nodes []*node // indexed by nodeid
+ flattenMemo map[types.Type][]*fieldInfo // memoization of flatten()
+ trackTypes map[types.Type]bool // memoization of shouldTrack()
+ constraints []constraint // set of constraints
+ cgnodes []*cgnode // all cgnodes
+ genq []*cgnode // queue of functions to generate constraints for
+ intrinsics map[*ssa.Function]intrinsic // non-nil values are summaries for intrinsic fns
+ globalval map[ssa.Value]nodeid // node for each global ssa.Value
+ globalobj map[ssa.Value]nodeid // maps v to sole member of pts(v), if singleton
+ localval map[ssa.Value]nodeid // node for each local ssa.Value
+ localobj map[ssa.Value]nodeid // maps v to sole member of pts(v), if singleton
+ atFuncs map[*ssa.Function]bool // address-taken functions (for presolver)
+ mapValues []nodeid // values of makemap objects (indirect in HVN)
+ work nodeset // solver's worklist
+ result *Result // results of the analysis
+ track track // pointerlike types whose aliasing we track
+ deltaSpace []int // working space for iterating over PTS deltas
+
+ // Reflection & intrinsics:
+ hasher typeutil.Hasher // cache of type hashes
+ reflectValueObj types.Object // type symbol for reflect.Value (if present)
+ reflectValueCall *ssa.Function // (reflect.Value).Call
+ reflectRtypeObj types.Object // *types.TypeName for reflect.rtype (if present)
+ reflectRtypePtr *types.Pointer // *reflect.rtype
+ reflectType *types.Named // reflect.Type
+ rtypes typeutil.Map // nodeid of canonical *rtype-tagged object for type T
+ reflectZeros typeutil.Map // nodeid of canonical T-tagged object for zero value
+ runtimeSetFinalizer *ssa.Function // runtime.SetFinalizer
+}
+
+// enclosingObj returns the first node of the addressable memory
+// object that encloses node id. Panic ensues if that node does not
+// belong to any object.
+func (a *analysis) enclosingObj(id nodeid) nodeid {
+ // Find previous node with obj != nil.
+ for i := id; i >= 0; i-- {
+ n := a.nodes[i]
+ if obj := n.obj; obj != nil {
+ if i+nodeid(obj.size) <= id {
+ break // out of bounds
+ }
+ return i
+ }
+ }
+ panic("node has no enclosing object")
+}
+
+// labelFor returns the Label for node id.
+// Panic ensues if that node is not addressable.
+func (a *analysis) labelFor(id nodeid) *Label {
+ return &Label{
+ obj: a.nodes[a.enclosingObj(id)].obj,
+ subelement: a.nodes[id].subelement,
+ }
+}
+
+func (a *analysis) warnf(pos token.Pos, format string, args ...interface{}) {
+ msg := fmt.Sprintf(format, args...)
+ if a.log != nil {
+ fmt.Fprintf(a.log, "%s: warning: %s\n", a.prog.Fset.Position(pos), msg)
+ }
+ a.result.Warnings = append(a.result.Warnings, Warning{pos, msg})
+}
+
+// computeTrackBits sets a.track to the necessary 'track' bits for the pointer queries.
+func (a *analysis) computeTrackBits() {
+ var queryTypes []types.Type
+ for v := range a.config.Queries {
+ queryTypes = append(queryTypes, v.Type())
+ }
+ for v := range a.config.IndirectQueries {
+ queryTypes = append(queryTypes, mustDeref(v.Type()))
+ }
+ for _, t := range queryTypes {
+ switch t.Underlying().(type) {
+ case *types.Chan:
+ a.track |= trackChan
+ case *types.Map:
+ a.track |= trackMap
+ case *types.Pointer:
+ a.track |= trackPtr
+ case *types.Slice:
+ a.track |= trackSlice
+ case *types.Interface:
+ a.track = trackAll
+ return
+ }
+ if rVObj := a.reflectValueObj; rVObj != nil && types.Identical(t, rVObj.Type()) {
+ a.track = trackAll
+ return
+ }
+ }
+}
+
+// Analyze runs the pointer analysis with the scope and options
+// specified by config, and returns the (synthetic) root of the callgraph.
+//
+// Pointer analysis of a transitively closed well-typed program should
+// always succeed. An error can occur only due to an internal bug.
+//
+func Analyze(config *Config) (result *Result, err error) {
+ if config.Mains == nil {
+ return nil, fmt.Errorf("no main/test packages to analyze (check $GOROOT/$GOPATH)")
+ }
+ defer func() {
+ if p := recover(); p != nil {
+ err = fmt.Errorf("internal error in pointer analysis: %v (please report this bug)", p)
+ fmt.Fprintln(os.Stderr, "Internal panic in pointer analysis:")
+ debug.PrintStack()
+ }
+ }()
+
+ a := &analysis{
+ config: config,
+ log: config.Log,
+ prog: config.prog(),
+ globalval: make(map[ssa.Value]nodeid),
+ globalobj: make(map[ssa.Value]nodeid),
+ flattenMemo: make(map[types.Type][]*fieldInfo),
+ trackTypes: make(map[types.Type]bool),
+ atFuncs: make(map[*ssa.Function]bool),
+ hasher: typeutil.MakeHasher(),
+ intrinsics: make(map[*ssa.Function]intrinsic),
+ result: &Result{
+ Queries: make(map[ssa.Value]Pointer),
+ IndirectQueries: make(map[ssa.Value]Pointer),
+ },
+ deltaSpace: make([]int, 0, 100),
+ }
+
+ if false {
+ a.log = os.Stderr // for debugging crashes; extremely verbose
+ }
+
+ if a.log != nil {
+ fmt.Fprintln(a.log, "==== Starting analysis")
+ }
+
+ // Pointer analysis requires a complete program for soundness.
+ // Check to prevent accidental misconfiguration.
+ for _, pkg := range a.prog.AllPackages() {
+ // (This only checks that the package scope is complete,
+ // not that func bodies exist, but it's a good signal.)
+ if !pkg.Object.Complete() {
+ return nil, fmt.Errorf(`pointer analysis requires a complete program yet package %q was incomplete`, pkg.Object.Path())
+ }
+ }
+
+ if reflect := a.prog.ImportedPackage("reflect"); reflect != nil {
+ rV := reflect.Object.Scope().Lookup("Value")
+ a.reflectValueObj = rV
+ a.reflectValueCall = a.prog.LookupMethod(rV.Type(), nil, "Call")
+ a.reflectType = reflect.Object.Scope().Lookup("Type").Type().(*types.Named)
+ a.reflectRtypeObj = reflect.Object.Scope().Lookup("rtype")
+ a.reflectRtypePtr = types.NewPointer(a.reflectRtypeObj.Type())
+
+ // Override flattening of reflect.Value, treating it like a basic type.
+ tReflectValue := a.reflectValueObj.Type()
+ a.flattenMemo[tReflectValue] = []*fieldInfo{{typ: tReflectValue}}
+
+ // Override shouldTrack of reflect.Value and *reflect.rtype.
+ // Always track pointers of these types.
+ a.trackTypes[tReflectValue] = true
+ a.trackTypes[a.reflectRtypePtr] = true
+
+ a.rtypes.SetHasher(a.hasher)
+ a.reflectZeros.SetHasher(a.hasher)
+ }
+ if runtime := a.prog.ImportedPackage("runtime"); runtime != nil {
+ a.runtimeSetFinalizer = runtime.Func("SetFinalizer")
+ }
+ a.computeTrackBits()
+
+ a.generate()
+ a.showCounts()
+
+ if optRenumber {
+ a.renumber()
+ }
+
+ N := len(a.nodes) // excludes solver-created nodes
+
+ if optHVN {
+ if debugHVNCrossCheck {
+ // Cross-check: run the solver once without
+ // optimization, once with, and compare the
+ // solutions.
+ savedConstraints := a.constraints
+
+ a.solve()
+ a.dumpSolution("A.pts", N)
+
+ // Restore.
+ a.constraints = savedConstraints
+ for _, n := range a.nodes {
+ n.solve = new(solverState)
+ }
+ a.nodes = a.nodes[:N]
+
+ // rtypes is effectively part of the solver state.
+ a.rtypes = typeutil.Map{}
+ a.rtypes.SetHasher(a.hasher)
+ }
+
+ a.hvn()
+ }
+
+ if debugHVNCrossCheck {
+ runtime.GC()
+ runtime.GC()
+ }
+
+ a.solve()
+
+ // Compare solutions.
+ if optHVN && debugHVNCrossCheck {
+ a.dumpSolution("B.pts", N)
+
+ if !diff("A.pts", "B.pts") {
+ return nil, fmt.Errorf("internal error: optimization changed solution")
+ }
+ }
+
+ // Create callgraph.Nodes in deterministic order.
+ if cg := a.result.CallGraph; cg != nil {
+ for _, caller := range a.cgnodes {
+ cg.CreateNode(caller.fn)
+ }
+ }
+
+ // Add dynamic edges to call graph.
+ var space [100]int
+ for _, caller := range a.cgnodes {
+ for _, site := range caller.sites {
+ for _, callee := range a.nodes[site.targets].solve.pts.AppendTo(space[:0]) {
+ a.callEdge(caller, site, nodeid(callee))
+ }
+ }
+ }
+
+ return a.result, nil
+}
+
+// callEdge is called for each edge in the callgraph.
+// calleeid is the callee's object node (has otFunction flag).
+//
+func (a *analysis) callEdge(caller *cgnode, site *callsite, calleeid nodeid) {
+ obj := a.nodes[calleeid].obj
+ if obj.flags&otFunction == 0 {
+ panic(fmt.Sprintf("callEdge %s -> n%d: not a function object", site, calleeid))
+ }
+ callee := obj.cgn
+
+ if cg := a.result.CallGraph; cg != nil {
+ // TODO(adonovan): opt: I would expect duplicate edges
+ // (to wrappers) to arise due to the elimination of
+ // context information, but I haven't observed any.
+ // Understand this better.
+ callgraph.AddEdge(cg.CreateNode(caller.fn), site.instr, cg.CreateNode(callee.fn))
+ }
+
+ if a.log != nil {
+ fmt.Fprintf(a.log, "\tcall edge %s -> %s\n", site, callee)
+ }
+
+ // Warn about calls to non-intrinsic external functions.
+ // TODO(adonovan): de-dup these messages.
+ if fn := callee.fn; fn.Blocks == nil && a.findIntrinsic(fn) == nil {
+ a.warnf(site.pos(), "unsound call to unknown intrinsic: %s", fn)
+ a.warnf(fn.Pos(), " (declared here)")
+ }
+}
+
+// dumpSolution writes the PTS solution to the specified file.
+//
+// It only dumps the nodes that existed before solving. The order in
+// which solver-created nodes are created depends on pre-solver
+// optimization, so we can't include them in the cross-check.
+//
+func (a *analysis) dumpSolution(filename string, N int) {
+ f, err := os.Create(filename)
+ if err != nil {
+ panic(err)
+ }
+ for id, n := range a.nodes[:N] {
+ if _, err := fmt.Fprintf(f, "pts(n%d) = {", id); err != nil {
+ panic(err)
+ }
+ var sep string
+ for _, l := range n.solve.pts.AppendTo(a.deltaSpace) {
+ if l >= N {
+ break
+ }
+ fmt.Fprintf(f, "%s%d", sep, l)
+ sep = " "
+ }
+ fmt.Fprintf(f, "} : %s\n", n.typ)
+ }
+ if err := f.Close(); err != nil {
+ panic(err)
+ }
+}
+
+// showCounts logs the size of the constraint system. A typical
+// optimized distribution is 65% copy, 13% load, 11% addr, 5%
+// offsetAddr, 4% store, 2% others.
+//
+func (a *analysis) showCounts() {
+ if a.log != nil {
+ counts := make(map[reflect.Type]int)
+ for _, c := range a.constraints {
+ counts[reflect.TypeOf(c)]++
+ }
+ fmt.Fprintf(a.log, "# constraints:\t%d\n", len(a.constraints))
+ var lines []string
+ for t, n := range counts {
+ line := fmt.Sprintf("%7d (%2d%%)\t%s", n, 100*n/len(a.constraints), t)
+ lines = append(lines, line)
+ }
+ sort.Sort(sort.Reverse(sort.StringSlice(lines)))
+ for _, line := range lines {
+ fmt.Fprintf(a.log, "\t%s\n", line)
+ }
+
+ fmt.Fprintf(a.log, "# nodes:\t%d\n", len(a.nodes))
+
+ // Show number of pointer equivalence classes.
+ m := make(map[*solverState]bool)
+ for _, n := range a.nodes {
+ m[n.solve] = true
+ }
+ fmt.Fprintf(a.log, "# ptsets:\t%d\n", len(m))
+ }
+}
diff --git a/vendor/golang.org/x/tools/go/pointer/api.go b/vendor/golang.org/x/tools/go/pointer/api.go
new file mode 100644
index 0000000..8f9ae0a
--- /dev/null
+++ b/vendor/golang.org/x/tools/go/pointer/api.go
@@ -0,0 +1,245 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package pointer
+
+import (
+ "bytes"
+ "fmt"
+ "go/token"
+ "io"
+
+ "golang.org/x/tools/container/intsets"
+ "golang.org/x/tools/go/callgraph"
+ "golang.org/x/tools/go/ssa"
+ "golang.org/x/tools/go/types/typeutil"
+)
+
+// A Config formulates a pointer analysis problem for Analyze().
+type Config struct {
+ // Mains contains the set of 'main' packages to analyze
+ // Clients must provide the analysis with at least one
+ // package defining a main() function.
+ //
+ // Non-main packages in the ssa.Program that are not
+ // dependencies of any main package may still affect the
+ // analysis result, because they contribute runtime types and
+ // thus methods.
+ // TODO(adonovan): investigate whether this is desirable.
+ Mains []*ssa.Package
+
+ // Reflection determines whether to handle reflection
+ // operators soundly, which is currently rather slow since it
+ // causes constraint to be generated during solving
+ // proportional to the number of constraint variables, which
+ // has not yet been reduced by presolver optimisation.
+ Reflection bool
+
+ // BuildCallGraph determines whether to construct a callgraph.
+ // If enabled, the graph will be available in Result.CallGraph.
+ BuildCallGraph bool
+
+ // The client populates Queries[v] or IndirectQueries[v]
+ // for each ssa.Value v of interest, to request that the
+ // points-to sets pts(v) or pts(*v) be computed. If the
+ // client needs both points-to sets, v may appear in both
+ // maps.
+ //
+ // (IndirectQueries is typically used for Values corresponding
+ // to source-level lvalues, e.g. an *ssa.Global.)
+ //
+ // The analysis populates the corresponding
+ // Result.{Indirect,}Queries map when it creates the pointer
+ // variable for v or *v. Upon completion the client can
+ // inspect that map for the results.
+ //
+ // TODO(adonovan): this API doesn't scale well for batch tools
+ // that want to dump the entire solution. Perhaps optionally
+ // populate a map[*ssa.DebugRef]Pointer in the Result, one
+ // entry per source expression.
+ //
+ Queries map[ssa.Value]struct{}
+ IndirectQueries map[ssa.Value]struct{}
+
+ // If Log is non-nil, log messages are written to it.
+ // Logging is extremely verbose.
+ Log io.Writer
+}
+
+type track uint32
+
+const (
+ trackChan track = 1 << iota // track 'chan' references
+ trackMap // track 'map' references
+ trackPtr // track regular pointers
+ trackSlice // track slice references
+
+ trackAll = ^track(0)
+)
+
+// AddQuery adds v to Config.Queries.
+// Precondition: CanPoint(v.Type()).
+// TODO(adonovan): consider returning a new Pointer for this query,
+// which will be initialized during analysis. That avoids the needs
+// for the corresponding ssa.Value-keyed maps in Config and Result.
+func (c *Config) AddQuery(v ssa.Value) {
+ if !CanPoint(v.Type()) {
+ panic(fmt.Sprintf("%s is not a pointer-like value: %s", v, v.Type()))
+ }
+ if c.Queries == nil {
+ c.Queries = make(map[ssa.Value]struct{})
+ }
+ c.Queries[v] = struct{}{}
+}
+
+// AddQuery adds v to Config.IndirectQueries.
+// Precondition: CanPoint(v.Type().Underlying().(*types.Pointer).Elem()).
+func (c *Config) AddIndirectQuery(v ssa.Value) {
+ if c.IndirectQueries == nil {
+ c.IndirectQueries = make(map[ssa.Value]struct{})
+ }
+ if !CanPoint(mustDeref(v.Type())) {
+ panic(fmt.Sprintf("%s is not the address of a pointer-like value: %s", v, v.Type()))
+ }
+ c.IndirectQueries[v] = struct{}{}
+}
+
+func (c *Config) prog() *ssa.Program {
+ for _, main := range c.Mains {
+ return main.Prog
+ }
+ panic("empty scope")
+}
+
+type Warning struct {
+ Pos token.Pos
+ Message string
+}
+
+// A Result contains the results of a pointer analysis.
+//
+// See Config for how to request the various Result components.
+//
+type Result struct {
+ CallGraph *callgraph.Graph // discovered call graph
+ Queries map[ssa.Value]Pointer // pts(v) for each v in Config.Queries.
+ IndirectQueries map[ssa.Value]Pointer // pts(*v) for each v in Config.IndirectQueries.
+ Warnings []Warning // warnings of unsoundness
+}
+
+// A Pointer is an equivalence class of pointer-like values.
+//
+// A Pointer doesn't have a unique type because pointers of distinct
+// types may alias the same object.
+//
+type Pointer struct {
+ a *analysis
+ n nodeid
+}
+
+// A PointsToSet is a set of labels (locations or allocations).
+type PointsToSet struct {
+ a *analysis // may be nil if pts is nil
+ pts *nodeset
+}
+
+func (s PointsToSet) String() string {
+ var buf bytes.Buffer
+ buf.WriteByte('[')
+ if s.pts != nil {
+ var space [50]int
+ for i, l := range s.pts.AppendTo(space[:0]) {
+ if i > 0 {
+ buf.WriteString(", ")
+ }
+ buf.WriteString(s.a.labelFor(nodeid(l)).String())
+ }
+ }
+ buf.WriteByte(']')
+ return buf.String()
+}
+
+// PointsTo returns the set of labels that this points-to set
+// contains.
+func (s PointsToSet) Labels() []*Label {
+ var labels []*Label
+ if s.pts != nil {
+ var space [50]int
+ for _, l := range s.pts.AppendTo(space[:0]) {
+ labels = append(labels, s.a.labelFor(nodeid(l)))
+ }
+ }
+ return labels
+}
+
+// If this PointsToSet came from a Pointer of interface kind
+// or a reflect.Value, DynamicTypes returns the set of dynamic
+// types that it may contain. (For an interface, they will
+// always be concrete types.)
+//
+// The result is a mapping whose keys are the dynamic types to which
+// it may point. For each pointer-like key type, the corresponding
+// map value is the PointsToSet for pointers of that type.
+//
+// The result is empty unless CanHaveDynamicTypes(T).
+//
+func (s PointsToSet) DynamicTypes() *typeutil.Map {
+ var tmap typeutil.Map
+ tmap.SetHasher(s.a.hasher)
+ if s.pts != nil {
+ var space [50]int
+ for _, x := range s.pts.AppendTo(space[:0]) {
+ ifaceObjId := nodeid(x)
+ if !s.a.isTaggedObject(ifaceObjId) {
+ continue // !CanHaveDynamicTypes(tDyn)
+ }
+ tDyn, v, indirect := s.a.taggedValue(ifaceObjId)
+ if indirect {
+ panic("indirect tagged object") // implement later
+ }
+ pts, ok := tmap.At(tDyn).(PointsToSet)
+ if !ok {
+ pts = PointsToSet{s.a, new(nodeset)}
+ tmap.Set(tDyn, pts)
+ }
+ pts.pts.addAll(&s.a.nodes[v].solve.pts)
+ }
+ }
+ return &tmap
+}
+
+// Intersects reports whether this points-to set and the
+// argument points-to set contain common members.
+func (x PointsToSet) Intersects(y PointsToSet) bool {
+ if x.pts == nil || y.pts == nil {
+ return false
+ }
+ // This takes Θ(|x|+|y|) time.
+ var z intsets.Sparse
+ z.Intersection(&x.pts.Sparse, &y.pts.Sparse)
+ return !z.IsEmpty()
+}
+
+func (p Pointer) String() string {
+ return fmt.Sprintf("n%d", p.n)
+}
+
+// PointsTo returns the points-to set of this pointer.
+func (p Pointer) PointsTo() PointsToSet {
+ if p.n == 0 {
+ return PointsToSet{}
+ }
+ return PointsToSet{p.a, &p.a.nodes[p.n].solve.pts}
+}
+
+// MayAlias reports whether the receiver pointer may alias
+// the argument pointer.
+func (p Pointer) MayAlias(q Pointer) bool {
+ return p.PointsTo().Intersects(q.PointsTo())
+}
+
+// DynamicTypes returns p.PointsTo().DynamicTypes().
+func (p Pointer) DynamicTypes() *typeutil.Map {
+ return p.PointsTo().DynamicTypes()
+}
diff --git a/vendor/golang.org/x/tools/go/pointer/callgraph.go b/vendor/golang.org/x/tools/go/pointer/callgraph.go
new file mode 100644
index 0000000..48e152e
--- /dev/null
+++ b/vendor/golang.org/x/tools/go/pointer/callgraph.go
@@ -0,0 +1,61 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package pointer
+
+// This file defines the internal (context-sensitive) call graph.
+
+import (
+ "fmt"
+ "go/token"
+
+ "golang.org/x/tools/go/ssa"
+)
+
+type cgnode struct {
+ fn *ssa.Function
+ obj nodeid // start of this contour's object block
+ sites []*callsite // ordered list of callsites within this function
+ callersite *callsite // where called from, if known; nil for shared contours
+}
+
+// contour returns a description of this node's contour.
+func (n *cgnode) contour() string {
+ if n.callersite == nil {
+ return "shared contour"
+ }
+ if n.callersite.instr != nil {
+ return fmt.Sprintf("as called from %s", n.callersite.instr.Parent())
+ }
+ return fmt.Sprintf("as called from intrinsic (targets=n%d)", n.callersite.targets)
+}
+
+func (n *cgnode) String() string {
+ return fmt.Sprintf("cg%d:%s", n.obj, n.fn)
+}
+
+// A callsite represents a single call site within a cgnode;
+// it is implicitly context-sensitive.
+// callsites never represent calls to built-ins;
+// they are handled as intrinsics.
+//
+type callsite struct {
+ targets nodeid // pts(·) contains objects for dynamically called functions
+ instr ssa.CallInstruction // the call instruction; nil for synthetic/intrinsic
+}
+
+func (c *callsite) String() string {
+ if c.instr != nil {
+ return c.instr.Common().Description()
+ }
+ return "synthetic function call"
+}
+
+// pos returns the source position of this callsite, or token.NoPos if implicit.
+func (c *callsite) pos() token.Pos {
+ if c.instr != nil {
+ return c.instr.Pos()
+ }
+ return token.NoPos
+}
diff --git a/vendor/golang.org/x/tools/go/pointer/constraint.go b/vendor/golang.org/x/tools/go/pointer/constraint.go
new file mode 100644
index 0000000..e6371cc
--- /dev/null
+++ b/vendor/golang.org/x/tools/go/pointer/constraint.go
@@ -0,0 +1,151 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package pointer
+
+import (
+ "golang.org/x/tools/go/types"
+)
+
+type constraint interface {
+ // For a complex constraint, returns the nodeid of the pointer
+ // to which it is attached. For addr and copy, returns dst.
+ ptr() nodeid
+
+ // renumber replaces each nodeid n in the constraint by mapping[n].
+ renumber(mapping []nodeid)
+
+ // presolve is a hook for constraint-specific behaviour during
+ // pre-solver optimization. Typical implementations mark as
+ // indirect the set of nodes to which the solver will add copy
+ // edges or PTS labels.
+ presolve(h *hvn)
+
+ // solve is called for complex constraints when the pts for
+ // the node to which they are attached has changed.
+ solve(a *analysis, delta *nodeset)
+
+ String() string
+}
+
+// dst = &src
+// pts(dst) ⊇ {src}
+// A base constraint used to initialize the solver's pt sets
+type addrConstraint struct {
+ dst nodeid // (ptr)
+ src nodeid
+}
+
+func (c *addrConstraint) ptr() nodeid { return c.dst }
+func (c *addrConstraint) renumber(mapping []nodeid) {
+ c.dst = mapping[c.dst]
+ c.src = mapping[c.src]
+}
+
+// dst = src
+// A simple constraint represented directly as a copyTo graph edge.
+type copyConstraint struct {
+ dst nodeid // (ptr)
+ src nodeid
+}
+
+func (c *copyConstraint) ptr() nodeid { return c.dst }
+func (c *copyConstraint) renumber(mapping []nodeid) {
+ c.dst = mapping[c.dst]
+ c.src = mapping[c.src]
+}
+
+// dst = src[offset]
+// A complex constraint attached to src (the pointer)
+type loadConstraint struct {
+ offset uint32
+ dst nodeid
+ src nodeid // (ptr)
+}
+
+func (c *loadConstraint) ptr() nodeid { return c.src }
+func (c *loadConstraint) renumber(mapping []nodeid) {
+ c.dst = mapping[c.dst]
+ c.src = mapping[c.src]
+}
+
+// dst[offset] = src
+// A complex constraint attached to dst (the pointer)
+type storeConstraint struct {
+ offset uint32
+ dst nodeid // (ptr)
+ src nodeid
+}
+
+func (c *storeConstraint) ptr() nodeid { return c.dst }
+func (c *storeConstraint) renumber(mapping []nodeid) {
+ c.dst = mapping[c.dst]
+ c.src = mapping[c.src]
+}
+
+// dst = &src.f or dst = &src[0]
+// A complex constraint attached to dst (the pointer)
+type offsetAddrConstraint struct {
+ offset uint32
+ dst nodeid
+ src nodeid // (ptr)
+}
+
+func (c *offsetAddrConstraint) ptr() nodeid { return c.src }
+func (c *offsetAddrConstraint) renumber(mapping []nodeid) {
+ c.dst = mapping[c.dst]
+ c.src = mapping[c.src]
+}
+
+// dst = src.(typ) where typ is an interface
+// A complex constraint attached to src (the interface).
+// No representation change: pts(dst) and pts(src) contains tagged objects.
+type typeFilterConstraint struct {
+ typ types.Type // an interface type
+ dst nodeid
+ src nodeid // (ptr)
+}
+
+func (c *typeFilterConstraint) ptr() nodeid { return c.src }
+func (c *typeFilterConstraint) renumber(mapping []nodeid) {
+ c.dst = mapping[c.dst]
+ c.src = mapping[c.src]
+}
+
+// dst = src.(typ) where typ is a concrete type
+// A complex constraint attached to src (the interface).
+//
+// If exact, only tagged objects identical to typ are untagged.
+// If !exact, tagged objects assignable to typ are untagged too.
+// The latter is needed for various reflect operators, e.g. Send.
+//
+// This entails a representation change:
+// pts(src) contains tagged objects,
+// pts(dst) contains their payloads.
+type untagConstraint struct {
+ typ types.Type // a concrete type
+ dst nodeid
+ src nodeid // (ptr)
+ exact bool
+}
+
+func (c *untagConstraint) ptr() nodeid { return c.src }
+func (c *untagConstraint) renumber(mapping []nodeid) {
+ c.dst = mapping[c.dst]
+ c.src = mapping[c.src]
+}
+
+// src.method(params...)
+// A complex constraint attached to iface.
+type invokeConstraint struct {
+ method *types.Func // the abstract method
+ iface nodeid // (ptr) the interface
+ params nodeid // the start of the identity/params/results block
+}
+
+func (c *invokeConstraint) ptr() nodeid { return c.iface }
+func (c *invokeConstraint) renumber(mapping []nodeid) {
+ c.iface = mapping[c.iface]
+ c.params = mapping[c.params]
+}
diff --git a/vendor/golang.org/x/tools/go/pointer/doc.go b/vendor/golang.org/x/tools/go/pointer/doc.go
new file mode 100644
index 0000000..22e569c
--- /dev/null
+++ b/vendor/golang.org/x/tools/go/pointer/doc.go
@@ -0,0 +1,610 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+/*
+
+Package pointer implements Andersen's analysis, an inclusion-based
+pointer analysis algorithm first described in (Andersen, 1994).
+
+A pointer analysis relates every pointer expression in a whole program
+to the set of memory locations to which it might point. This
+information can be used to construct a call graph of the program that
+precisely represents the destinations of dynamic function and method
+calls. It can also be used to determine, for example, which pairs of
+channel operations operate on the same channel.
+
+The package allows the client to request a set of expressions of
+interest for which the points-to information will be returned once the
+analysis is complete. In addition, the client may request that a
+callgraph is constructed. The example program in example_test.go
+demonstrates both of these features. Clients should not request more
+information than they need since it may increase the cost of the
+analysis significantly.
+
+
+CLASSIFICATION
+
+Our algorithm is INCLUSION-BASED: the points-to sets for x and y will
+be related by pts(y) ⊇ pts(x) if the program contains the statement
+y = x.
+
+It is FLOW-INSENSITIVE: it ignores all control flow constructs and the
+order of statements in a program. It is therefore a "MAY ALIAS"
+analysis: its facts are of the form "P may/may not point to L",
+not "P must point to L".
+
+It is FIELD-SENSITIVE: it builds separate points-to sets for distinct
+fields, such as x and y in struct { x, y *int }.
+
+It is mostly CONTEXT-INSENSITIVE: most functions are analyzed once,
+so values can flow in at one call to the function and return out at
+another. Only some smaller functions are analyzed with consideration
+of their calling context.
+
+It has a CONTEXT-SENSITIVE HEAP: objects are named by both allocation
+site and context, so the objects returned by two distinct calls to f:
+ func f() *T { return new(T) }
+are distinguished up to the limits of the calling context.
+
+It is a WHOLE PROGRAM analysis: it requires SSA-form IR for the
+complete Go program and summaries for native code.
+
+See the (Hind, PASTE'01) survey paper for an explanation of these terms.
+
+
+SOUNDNESS
+
+The analysis is fully sound when invoked on pure Go programs that do not
+use reflection or unsafe.Pointer conversions. In other words, if there
+is any possible execution of the program in which pointer P may point to
+object O, the analysis will report that fact.
+
+
+REFLECTION
+
+By default, the "reflect" library is ignored by the analysis, as if all
+its functions were no-ops, but if the client enables the Reflection flag,
+the analysis will make a reasonable attempt to model the effects of
+calls into this library. However, this comes at a significant
+performance cost, and not all features of that library are yet
+implemented. In addition, some simplifying approximations must be made
+to ensure that the analysis terminates; for example, reflection can be
+used to construct an infinite set of types and values of those types,
+but the analysis arbitrarily bounds the depth of such types.
+
+Most but not all reflection operations are supported.
+In particular, addressable reflect.Values are not yet implemented, so
+operations such as (reflect.Value).Set have no analytic effect.
+
+
+UNSAFE POINTER CONVERSIONS
+
+The pointer analysis makes no attempt to understand aliasing between the
+operand x and result y of an unsafe.Pointer conversion:
+ y = (*T)(unsafe.Pointer(x))
+It is as if the conversion allocated an entirely new object:
+ y = new(T)
+
+
+NATIVE CODE
+
+The analysis cannot model the aliasing effects of functions written in
+languages other than Go, such as runtime intrinsics in C or assembly, or
+code accessed via cgo. The result is as if such functions are no-ops.
+However, various important intrinsics are understood by the analysis,
+along with built-ins such as append.
+
+The analysis currently provides no way for users to specify the aliasing
+effects of native code.
+
+------------------------------------------------------------------------
+
+IMPLEMENTATION
+
+The remaining documentation is intended for package maintainers and
+pointer analysis specialists. Maintainers should have a solid
+understanding of the referenced papers (especially those by H&L and PKH)
+before making making significant changes.
+
+The implementation is similar to that described in (Pearce et al,
+PASTE'04). Unlike many algorithms which interleave constraint
+generation and solving, constructing the callgraph as they go, this
+implementation for the most part observes a phase ordering (generation
+before solving), with only simple (copy) constraints being generated
+during solving. (The exception is reflection, which creates various
+constraints during solving as new types flow to reflect.Value
+operations.) This improves the traction of presolver optimisations,
+but imposes certain restrictions, e.g. potential context sensitivity
+is limited since all variants must be created a priori.
+
+
+TERMINOLOGY
+
+A type is said to be "pointer-like" if it is a reference to an object.
+Pointer-like types include pointers and also interfaces, maps, channels,
+functions and slices.
+
+We occasionally use C's x->f notation to distinguish the case where x
+is a struct pointer from x.f where is a struct value.
+
+Pointer analysis literature (and our comments) often uses the notation
+dst=*src+offset to mean something different than what it means in Go.
+It means: for each node index p in pts(src), the node index p+offset is
+in pts(dst). Similarly *dst+offset=src is used for store constraints
+and dst=src+offset for offset-address constraints.
+
+
+NODES
+
+Nodes are the key datastructure of the analysis, and have a dual role:
+they represent both constraint variables (equivalence classes of
+pointers) and members of points-to sets (things that can be pointed
+at, i.e. "labels").
+
+Nodes are naturally numbered. The numbering enables compact
+representations of sets of nodes such as bitvectors (or BDDs); and the
+ordering enables a very cheap way to group related nodes together. For
+example, passing n parameters consists of generating n parallel
+constraints from caller+i to callee+i for 0<=i y is added.
+
+ ChangeInterface is a simple copy because the representation of
+ tagged objects is independent of the interface type (in contrast
+ to the "method tables" approach used by the gc runtime).
+
+ y := Invoke x.m(...) is implemented by allocating contiguous P/R
+ blocks for the callsite and adding a dynamic rule triggered by each
+ tagged object added to pts(x). The rule adds param/results copy
+ edges to/from each discovered concrete method.
+
+ (Q. Why do we model an interface as a pointer to a pair of type and
+ value, rather than as a pair of a pointer to type and a pointer to
+ value?
+ A. Control-flow joins would merge interfaces ({T1}, {V1}) and ({T2},
+ {V2}) to make ({T1,T2}, {V1,V2}), leading to the infeasible and
+ type-unsafe combination (T1,V2). Treating the value and its concrete
+ type as inseparable makes the analysis type-safe.)
+
+reflect.Value
+ A reflect.Value is modelled very similar to an interface{}, i.e. as
+ a pointer exclusively to tagged objects, but with two generalizations.
+
+ 1) a reflect.Value that represents an lvalue points to an indirect
+ (obj.flags ⊇ {otIndirect}) tagged object, which has a similar
+ layout to an tagged object except that the value is a pointer to
+ the dynamic type. Indirect tagged objects preserve the correct
+ aliasing so that mutations made by (reflect.Value).Set can be
+ observed.
+
+ Indirect objects only arise when an lvalue is derived from an
+ rvalue by indirection, e.g. the following code:
+
+ type S struct { X T }
+ var s S
+ var i interface{} = &s // i points to a *S-tagged object (from MakeInterface)
+ v1 := reflect.ValueOf(i) // v1 points to same *S-tagged object as i
+ v2 := v1.Elem() // v2 points to an indirect S-tagged object, pointing to s
+ v3 := v2.FieldByName("X") // v3 points to an indirect int-tagged object, pointing to s.X
+ v3.Set(y) // pts(s.X) ⊇ pts(y)
+
+ Whether indirect or not, the concrete type of the tagged object
+ corresponds to the user-visible dynamic type, and the existence
+ of a pointer is an implementation detail.
+
+ (NB: indirect tagged objects are not yet implemented)
+
+ 2) The dynamic type tag of a tagged object pointed to by a
+ reflect.Value may be an interface type; it need not be concrete.
+
+ This arises in code such as this:
+ tEface := reflect.TypeOf(new(interface{}).Elem() // interface{}
+ eface := reflect.Zero(tEface)
+ pts(eface) is a singleton containing an interface{}-tagged
+ object. That tagged object's payload is an interface{} value,
+ i.e. the pts of the payload contains only concrete-tagged
+ objects, although in this example it's the zero interface{} value,
+ so its pts is empty.
+
+reflect.Type
+ Just as in the real "reflect" library, we represent a reflect.Type
+ as an interface whose sole implementation is the concrete type,
+ *reflect.rtype. (This choice is forced on us by go/types: clients
+ cannot fabricate types with arbitrary method sets.)
+
+ rtype instances are canonical: there is at most one per dynamic
+ type. (rtypes are in fact large structs but since identity is all
+ that matters, we represent them by a single node.)
+
+ The payload of each *rtype-tagged object is an *rtype pointer that
+ points to exactly one such canonical rtype object. We exploit this
+ by setting the node.typ of the payload to the dynamic type, not
+ '*rtype'. This saves us an indirection in each resolution rule. As
+ an optimisation, *rtype-tagged objects are canonicalized too.
+
+
+Aggregate types:
+
+Aggregate types are treated as if all directly contained
+aggregates are recursively flattened out.
+
+Structs
+ *ssa.Field y = x.f creates a simple edge to y from x's node at f's offset.
+
+ *ssa.FieldAddr y = &x->f requires a dynamic closure rule to create
+ simple edges for each struct discovered in pts(x).
+
+ The nodes of a struct consist of a special 'identity' node (whose
+ type is that of the struct itself), followed by the nodes for all
+ the struct's fields, recursively flattened out. A pointer to the
+ struct is a pointer to its identity node. That node allows us to
+ distinguish a pointer to a struct from a pointer to its first field.
+
+ Field offsets are logical field offsets (plus one for the identity
+ node), so the sizes of the fields can be ignored by the analysis.
+
+ (The identity node is non-traditional but enables the distiction
+ described above, which is valuable for code comprehension tools.
+ Typical pointer analyses for C, whose purpose is compiler
+ optimization, must soundly model unsafe.Pointer (void*) conversions,
+ and this requires fidelity to the actual memory layout using physical
+ field offsets.)
+
+ *ssa.Field y = x.f creates a simple edge to y from x's node at f's offset.
+
+ *ssa.FieldAddr y = &x->f requires a dynamic closure rule to create
+ simple edges for each struct discovered in pts(x).
+
+Arrays
+ We model an array by an identity node (whose type is that of the
+ array itself) followed by a node representing all the elements of
+ the array; the analysis does not distinguish elements with different
+ indices. Effectively, an array is treated like struct{elem T}, a
+ load y=x[i] like y=x.elem, and a store x[i]=y like x.elem=y; the
+ index i is ignored.
+
+ A pointer to an array is pointer to its identity node. (A slice is
+ also a pointer to an array's identity node.) The identity node
+ allows us to distinguish a pointer to an array from a pointer to one
+ of its elements, but it is rather costly because it introduces more
+ offset constraints into the system. Furthermore, sound treatment of
+ unsafe.Pointer would require us to dispense with this node.
+
+ Arrays may be allocated by Alloc, by make([]T), by calls to append,
+ and via reflection.
+
+Tuples (T, ...)
+ Tuples are treated like structs with naturally numbered fields.
+ *ssa.Extract is analogous to *ssa.Field.
+
+ However, tuples have no identity field since by construction, they
+ cannot be address-taken.
+
+
+FUNCTION CALLS
+
+ There are three kinds of function call:
+ (1) static "call"-mode calls of functions.
+ (2) dynamic "call"-mode calls of functions.
+ (3) dynamic "invoke"-mode calls of interface methods.
+ Cases 1 and 2 apply equally to methods and standalone functions.
+
+ Static calls.
+ A static call consists three steps:
+ - finding the function object of the callee;
+ - creating copy edges from the actual parameter value nodes to the
+ P-block in the function object (this includes the receiver if
+ the callee is a method);
+ - creating copy edges from the R-block in the function object to
+ the value nodes for the result of the call.
+
+ A static function call is little more than two struct value copies
+ between the P/R blocks of caller and callee:
+
+ callee.P = caller.P
+ caller.R = callee.R
+
+ Context sensitivity
+
+ Static calls (alone) may be treated context sensitively,
+ i.e. each callsite may cause a distinct re-analysis of the
+ callee, improving precision. Our current context-sensitivity
+ policy treats all intrinsics and getter/setter methods in this
+ manner since such functions are small and seem like an obvious
+ source of spurious confluences, though this has not yet been
+ evaluated.
+
+ Dynamic function calls
+
+ Dynamic calls work in a similar manner except that the creation of
+ copy edges occurs dynamically, in a similar fashion to a pair of
+ struct copies in which the callee is indirect:
+
+ callee->P = caller.P
+ caller.R = callee->R
+
+ (Recall that the function object's P- and R-blocks are contiguous.)
+
+ Interface method invocation
+
+ For invoke-mode calls, we create a params/results block for the
+ callsite and attach a dynamic closure rule to the interface. For
+ each new tagged object that flows to the interface, we look up
+ the concrete method, find its function object, and connect its P/R
+ blocks to the callsite's P/R blocks, adding copy edges to the graph
+ during solving.
+
+ Recording call targets
+
+ The analysis notifies its clients of each callsite it encounters,
+ passing a CallSite interface. Among other things, the CallSite
+ contains a synthetic constraint variable ("targets") whose
+ points-to solution includes the set of all function objects to
+ which the call may dispatch.
+
+ It is via this mechanism that the callgraph is made available.
+ Clients may also elect to be notified of callgraph edges directly;
+ internally this just iterates all "targets" variables' pts(·)s.
+
+
+PRESOLVER
+
+We implement Hash-Value Numbering (HVN), a pre-solver constraint
+optimization described in Hardekopf & Lin, SAS'07. This is documented
+in more detail in hvn.go. We intend to add its cousins HR and HU in
+future.
+
+
+SOLVER
+
+The solver is currently a naive Andersen-style implementation; it does
+not perform online cycle detection, though we plan to add solver
+optimisations such as Hybrid- and Lazy- Cycle Detection from (Hardekopf
+& Lin, PLDI'07).
+
+It uses difference propagation (Pearce et al, SQC'04) to avoid
+redundant re-triggering of closure rules for values already seen.
+
+Points-to sets are represented using sparse bit vectors (similar to
+those used in LLVM and gcc), which are more space- and time-efficient
+than sets based on Go's built-in map type or dense bit vectors.
+
+Nodes are permuted prior to solving so that object nodes (which may
+appear in points-to sets) are lower numbered than non-object (var)
+nodes. This improves the density of the set over which the PTSs
+range, and thus the efficiency of the representation.
+
+Partly thanks to avoiding map iteration, the execution of the solver is
+100% deterministic, a great help during debugging.
+
+
+FURTHER READING
+
+Andersen, L. O. 1994. Program analysis and specialization for the C
+programming language. Ph.D. dissertation. DIKU, University of
+Copenhagen.
+
+David J. Pearce, Paul H. J. Kelly, and Chris Hankin. 2004. Efficient
+field-sensitive pointer analysis for C. In Proceedings of the 5th ACM
+SIGPLAN-SIGSOFT workshop on Program analysis for software tools and
+engineering (PASTE '04). ACM, New York, NY, USA, 37-42.
+http://doi.acm.org/10.1145/996821.996835
+
+David J. Pearce, Paul H. J. Kelly, and Chris Hankin. 2004. Online
+Cycle Detection and Difference Propagation: Applications to Pointer
+Analysis. Software Quality Control 12, 4 (December 2004), 311-337.
+http://dx.doi.org/10.1023/B:SQJO.0000039791.93071.a2
+
+David Grove and Craig Chambers. 2001. A framework for call graph
+construction algorithms. ACM Trans. Program. Lang. Syst. 23, 6
+(November 2001), 685-746.
+http://doi.acm.org/10.1145/506315.506316
+
+Ben Hardekopf and Calvin Lin. 2007. The ant and the grasshopper: fast
+and accurate pointer analysis for millions of lines of code. In
+Proceedings of the 2007 ACM SIGPLAN conference on Programming language
+design and implementation (PLDI '07). ACM, New York, NY, USA, 290-299.
+http://doi.acm.org/10.1145/1250734.1250767
+
+Ben Hardekopf and Calvin Lin. 2007. Exploiting pointer and location
+equivalence to optimize pointer analysis. In Proceedings of the 14th
+international conference on Static Analysis (SAS'07), Hanne Riis
+Nielson and Gilberto Filé (Eds.). Springer-Verlag, Berlin, Heidelberg,
+265-280.
+
+Atanas Rountev and Satish Chandra. 2000. Off-line variable substitution
+for scaling points-to analysis. In Proceedings of the ACM SIGPLAN 2000
+conference on Programming language design and implementation (PLDI '00).
+ACM, New York, NY, USA, 47-56. DOI=10.1145/349299.349310
+http://doi.acm.org/10.1145/349299.349310
+
+*/
+package pointer // import "golang.org/x/tools/go/pointer"
diff --git a/vendor/golang.org/x/tools/go/pointer/gen.go b/vendor/golang.org/x/tools/go/pointer/gen.go
new file mode 100644
index 0000000..6c256ac
--- /dev/null
+++ b/vendor/golang.org/x/tools/go/pointer/gen.go
@@ -0,0 +1,1292 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package pointer
+
+// This file defines the constraint generation phase.
+
+// TODO(adonovan): move the constraint definitions and the store() etc
+// functions which add them (and are also used by the solver) into a
+// new file, constraints.go.
+
+import (
+ "fmt"
+ "go/token"
+
+ "golang.org/x/tools/go/callgraph"
+ "golang.org/x/tools/go/ssa"
+ "golang.org/x/tools/go/types"
+)
+
+var (
+ tEface = types.NewInterface(nil, nil).Complete()
+ tInvalid = types.Typ[types.Invalid]
+ tUnsafePtr = types.Typ[types.UnsafePointer]
+)
+
+// ---------- Node creation ----------
+
+// nextNode returns the index of the next unused node.
+func (a *analysis) nextNode() nodeid {
+ return nodeid(len(a.nodes))
+}
+
+// addNodes creates nodes for all scalar elements in type typ, and
+// returns the id of the first one, or zero if the type was
+// analytically uninteresting.
+//
+// comment explains the origin of the nodes, as a debugging aid.
+//
+func (a *analysis) addNodes(typ types.Type, comment string) nodeid {
+ id := a.nextNode()
+ for _, fi := range a.flatten(typ) {
+ a.addOneNode(fi.typ, comment, fi)
+ }
+ if id == a.nextNode() {
+ return 0 // type contained no pointers
+ }
+ return id
+}
+
+// addOneNode creates a single node with type typ, and returns its id.
+//
+// typ should generally be scalar (except for tagged.T nodes
+// and struct/array identity nodes). Use addNodes for non-scalar types.
+//
+// comment explains the origin of the nodes, as a debugging aid.
+// subelement indicates the subelement, e.g. ".a.b[*].c".
+//
+func (a *analysis) addOneNode(typ types.Type, comment string, subelement *fieldInfo) nodeid {
+ id := a.nextNode()
+ a.nodes = append(a.nodes, &node{typ: typ, subelement: subelement, solve: new(solverState)})
+ if a.log != nil {
+ fmt.Fprintf(a.log, "\tcreate n%d %s for %s%s\n",
+ id, typ, comment, subelement.path())
+ }
+ return id
+}
+
+// setValueNode associates node id with the value v.
+// cgn identifies the context iff v is a local variable.
+//
+func (a *analysis) setValueNode(v ssa.Value, id nodeid, cgn *cgnode) {
+ if cgn != nil {
+ a.localval[v] = id
+ } else {
+ a.globalval[v] = id
+ }
+ if a.log != nil {
+ fmt.Fprintf(a.log, "\tval[%s] = n%d (%T)\n", v.Name(), id, v)
+ }
+
+ // Due to context-sensitivity, we may encounter the same Value
+ // in many contexts. We merge them to a canonical node, since
+ // that's what all clients want.
+
+ // Record the (v, id) relation if the client has queried pts(v).
+ if _, ok := a.config.Queries[v]; ok {
+ t := v.Type()
+ ptr, ok := a.result.Queries[v]
+ if !ok {
+ // First time? Create the canonical query node.
+ ptr = Pointer{a, a.addNodes(t, "query")}
+ a.result.Queries[v] = ptr
+ }
+ a.result.Queries[v] = ptr
+ a.copy(ptr.n, id, a.sizeof(t))
+ }
+
+ // Record the (*v, id) relation if the client has queried pts(*v).
+ if _, ok := a.config.IndirectQueries[v]; ok {
+ t := v.Type()
+ ptr, ok := a.result.IndirectQueries[v]
+ if !ok {
+ // First time? Create the canonical indirect query node.
+ ptr = Pointer{a, a.addNodes(v.Type(), "query.indirect")}
+ a.result.IndirectQueries[v] = ptr
+ }
+ a.genLoad(cgn, ptr.n, v, 0, a.sizeof(t))
+ }
+}
+
+// endObject marks the end of a sequence of calls to addNodes denoting
+// a single object allocation.
+//
+// obj is the start node of the object, from a prior call to nextNode.
+// Its size, flags and optional data will be updated.
+//
+func (a *analysis) endObject(obj nodeid, cgn *cgnode, data interface{}) *object {
+ // Ensure object is non-empty by padding;
+ // the pad will be the object node.
+ size := uint32(a.nextNode() - obj)
+ if size == 0 {
+ a.addOneNode(tInvalid, "padding", nil)
+ }
+ objNode := a.nodes[obj]
+ o := &object{
+ size: size, // excludes padding
+ cgn: cgn,
+ data: data,
+ }
+ objNode.obj = o
+
+ return o
+}
+
+// makeFunctionObject creates and returns a new function object
+// (contour) for fn, and returns the id of its first node. It also
+// enqueues fn for subsequent constraint generation.
+//
+// For a context-sensitive contour, callersite identifies the sole
+// callsite; for shared contours, caller is nil.
+//
+func (a *analysis) makeFunctionObject(fn *ssa.Function, callersite *callsite) nodeid {
+ if a.log != nil {
+ fmt.Fprintf(a.log, "\t---- makeFunctionObject %s\n", fn)
+ }
+
+ // obj is the function object (identity, params, results).
+ obj := a.nextNode()
+ cgn := a.makeCGNode(fn, obj, callersite)
+ sig := fn.Signature
+ a.addOneNode(sig, "func.cgnode", nil) // (scalar with Signature type)
+ if recv := sig.Recv(); recv != nil {
+ a.addNodes(recv.Type(), "func.recv")
+ }
+ a.addNodes(sig.Params(), "func.params")
+ a.addNodes(sig.Results(), "func.results")
+ a.endObject(obj, cgn, fn).flags |= otFunction
+
+ if a.log != nil {
+ fmt.Fprintf(a.log, "\t----\n")
+ }
+
+ // Queue it up for constraint processing.
+ a.genq = append(a.genq, cgn)
+
+ return obj
+}
+
+// makeTagged creates a tagged object of type typ.
+func (a *analysis) makeTagged(typ types.Type, cgn *cgnode, data interface{}) nodeid {
+ obj := a.addOneNode(typ, "tagged.T", nil) // NB: type may be non-scalar!
+ a.addNodes(typ, "tagged.v")
+ a.endObject(obj, cgn, data).flags |= otTagged
+ return obj
+}
+
+// makeRtype returns the canonical tagged object of type *rtype whose
+// payload points to the sole rtype object for T.
+//
+// TODO(adonovan): move to reflect.go; it's part of the solver really.
+//
+func (a *analysis) makeRtype(T types.Type) nodeid {
+ if v := a.rtypes.At(T); v != nil {
+ return v.(nodeid)
+ }
+
+ // Create the object for the reflect.rtype itself, which is
+ // ordinarily a large struct but here a single node will do.
+ obj := a.nextNode()
+ a.addOneNode(T, "reflect.rtype", nil)
+ a.endObject(obj, nil, T)
+
+ id := a.makeTagged(a.reflectRtypePtr, nil, T)
+ a.nodes[id+1].typ = T // trick (each *rtype tagged object is a singleton)
+ a.addressOf(a.reflectRtypePtr, id+1, obj)
+
+ a.rtypes.Set(T, id)
+ return id
+}
+
+// rtypeValue returns the type of the *reflect.rtype-tagged object obj.
+func (a *analysis) rtypeTaggedValue(obj nodeid) types.Type {
+ tDyn, t, _ := a.taggedValue(obj)
+ if tDyn != a.reflectRtypePtr {
+ panic(fmt.Sprintf("not a *reflect.rtype-tagged object: obj=n%d tag=%v payload=n%d", obj, tDyn, t))
+ }
+ return a.nodes[t].typ
+}
+
+// valueNode returns the id of the value node for v, creating it (and
+// the association) as needed. It may return zero for uninteresting
+// values containing no pointers.
+//
+func (a *analysis) valueNode(v ssa.Value) nodeid {
+ // Value nodes for locals are created en masse by genFunc.
+ if id, ok := a.localval[v]; ok {
+ return id
+ }
+
+ // Value nodes for globals are created on demand.
+ id, ok := a.globalval[v]
+ if !ok {
+ var comment string
+ if a.log != nil {
+ comment = v.String()
+ }
+ id = a.addNodes(v.Type(), comment)
+ if obj := a.objectNode(nil, v); obj != 0 {
+ a.addressOf(v.Type(), id, obj)
+ }
+ a.setValueNode(v, id, nil)
+ }
+ return id
+}
+
+// valueOffsetNode ascertains the node for tuple/struct value v,
+// then returns the node for its subfield #index.
+//
+func (a *analysis) valueOffsetNode(v ssa.Value, index int) nodeid {
+ id := a.valueNode(v)
+ if id == 0 {
+ panic(fmt.Sprintf("cannot offset within n0: %s = %s", v.Name(), v))
+ }
+ return id + nodeid(a.offsetOf(v.Type(), index))
+}
+
+// isTaggedObject reports whether object obj is a tagged object.
+func (a *analysis) isTaggedObject(obj nodeid) bool {
+ return a.nodes[obj].obj.flags&otTagged != 0
+}
+
+// taggedValue returns the dynamic type tag, the (first node of the)
+// payload, and the indirect flag of the tagged object starting at id.
+// Panic ensues if !isTaggedObject(id).
+//
+func (a *analysis) taggedValue(obj nodeid) (tDyn types.Type, v nodeid, indirect bool) {
+ n := a.nodes[obj]
+ flags := n.obj.flags
+ if flags&otTagged == 0 {
+ panic(fmt.Sprintf("not a tagged object: n%d", obj))
+ }
+ return n.typ, obj + 1, flags&otIndirect != 0
+}
+
+// funcParams returns the first node of the params (P) block of the
+// function whose object node (obj.flags&otFunction) is id.
+//
+func (a *analysis) funcParams(id nodeid) nodeid {
+ n := a.nodes[id]
+ if n.obj == nil || n.obj.flags&otFunction == 0 {
+ panic(fmt.Sprintf("funcParams(n%d): not a function object block", id))
+ }
+ return id + 1
+}
+
+// funcResults returns the first node of the results (R) block of the
+// function whose object node (obj.flags&otFunction) is id.
+//
+func (a *analysis) funcResults(id nodeid) nodeid {
+ n := a.nodes[id]
+ if n.obj == nil || n.obj.flags&otFunction == 0 {
+ panic(fmt.Sprintf("funcResults(n%d): not a function object block", id))
+ }
+ sig := n.typ.(*types.Signature)
+ id += 1 + nodeid(a.sizeof(sig.Params()))
+ if sig.Recv() != nil {
+ id += nodeid(a.sizeof(sig.Recv().Type()))
+ }
+ return id
+}
+
+// ---------- Constraint creation ----------
+
+// copy creates a constraint of the form dst = src.
+// sizeof is the width (in logical fields) of the copied type.
+//
+func (a *analysis) copy(dst, src nodeid, sizeof uint32) {
+ if src == dst || sizeof == 0 {
+ return // trivial
+ }
+ if src == 0 || dst == 0 {
+ panic(fmt.Sprintf("ill-typed copy dst=n%d src=n%d", dst, src))
+ }
+ for i := uint32(0); i < sizeof; i++ {
+ a.addConstraint(©Constraint{dst, src})
+ src++
+ dst++
+ }
+}
+
+// addressOf creates a constraint of the form id = &obj.
+// T is the type of the address.
+func (a *analysis) addressOf(T types.Type, id, obj nodeid) {
+ if id == 0 {
+ panic("addressOf: zero id")
+ }
+ if obj == 0 {
+ panic("addressOf: zero obj")
+ }
+ if a.shouldTrack(T) {
+ a.addConstraint(&addrConstraint{id, obj})
+ }
+}
+
+// load creates a load constraint of the form dst = src[offset].
+// offset is the pointer offset in logical fields.
+// sizeof is the width (in logical fields) of the loaded type.
+//
+func (a *analysis) load(dst, src nodeid, offset, sizeof uint32) {
+ if dst == 0 {
+ return // load of non-pointerlike value
+ }
+ if src == 0 && dst == 0 {
+ return // non-pointerlike operation
+ }
+ if src == 0 || dst == 0 {
+ panic(fmt.Sprintf("ill-typed load dst=n%d src=n%d", dst, src))
+ }
+ for i := uint32(0); i < sizeof; i++ {
+ a.addConstraint(&loadConstraint{offset, dst, src})
+ offset++
+ dst++
+ }
+}
+
+// store creates a store constraint of the form dst[offset] = src.
+// offset is the pointer offset in logical fields.
+// sizeof is the width (in logical fields) of the stored type.
+//
+func (a *analysis) store(dst, src nodeid, offset uint32, sizeof uint32) {
+ if src == 0 {
+ return // store of non-pointerlike value
+ }
+ if src == 0 && dst == 0 {
+ return // non-pointerlike operation
+ }
+ if src == 0 || dst == 0 {
+ panic(fmt.Sprintf("ill-typed store dst=n%d src=n%d", dst, src))
+ }
+ for i := uint32(0); i < sizeof; i++ {
+ a.addConstraint(&storeConstraint{offset, dst, src})
+ offset++
+ src++
+ }
+}
+
+// offsetAddr creates an offsetAddr constraint of the form dst = &src.#offset.
+// offset is the field offset in logical fields.
+// T is the type of the address.
+//
+func (a *analysis) offsetAddr(T types.Type, dst, src nodeid, offset uint32) {
+ if !a.shouldTrack(T) {
+ return
+ }
+ if offset == 0 {
+ // Simplify dst = &src->f0
+ // to dst = src
+ // (NB: this optimisation is defeated by the identity
+ // field prepended to struct and array objects.)
+ a.copy(dst, src, 1)
+ } else {
+ a.addConstraint(&offsetAddrConstraint{offset, dst, src})
+ }
+}
+
+// typeAssert creates a typeFilter or untag constraint of the form dst = src.(T):
+// typeFilter for an interface, untag for a concrete type.
+// The exact flag is specified as for untagConstraint.
+//
+func (a *analysis) typeAssert(T types.Type, dst, src nodeid, exact bool) {
+ if isInterface(T) {
+ a.addConstraint(&typeFilterConstraint{T, dst, src})
+ } else {
+ a.addConstraint(&untagConstraint{T, dst, src, exact})
+ }
+}
+
+// addConstraint adds c to the constraint set.
+func (a *analysis) addConstraint(c constraint) {
+ a.constraints = append(a.constraints, c)
+ if a.log != nil {
+ fmt.Fprintf(a.log, "\t%s\n", c)
+ }
+}
+
+// copyElems generates load/store constraints for *dst = *src,
+// where src and dst are slices or *arrays.
+//
+func (a *analysis) copyElems(cgn *cgnode, typ types.Type, dst, src ssa.Value) {
+ tmp := a.addNodes(typ, "copy")
+ sz := a.sizeof(typ)
+ a.genLoad(cgn, tmp, src, 1, sz)
+ a.genStore(cgn, dst, tmp, 1, sz)
+}
+
+// ---------- Constraint generation ----------
+
+// genConv generates constraints for the conversion operation conv.
+func (a *analysis) genConv(conv *ssa.Convert, cgn *cgnode) {
+ res := a.valueNode(conv)
+ if res == 0 {
+ return // result is non-pointerlike
+ }
+
+ tSrc := conv.X.Type()
+ tDst := conv.Type()
+
+ switch utSrc := tSrc.Underlying().(type) {
+ case *types.Slice:
+ // []byte/[]rune -> string?
+ return
+
+ case *types.Pointer:
+ // *T -> unsafe.Pointer?
+ if tDst.Underlying() == tUnsafePtr {
+ return // we don't model unsafe aliasing (unsound)
+ }
+
+ case *types.Basic:
+ switch tDst.Underlying().(type) {
+ case *types.Pointer:
+ // Treat unsafe.Pointer->*T conversions like
+ // new(T) and create an unaliased object.
+ if utSrc == tUnsafePtr {
+ obj := a.addNodes(mustDeref(tDst), "unsafe.Pointer conversion")
+ a.endObject(obj, cgn, conv)
+ a.addressOf(tDst, res, obj)
+ return
+ }
+
+ case *types.Slice:
+ // string -> []byte/[]rune (or named aliases)?
+ if utSrc.Info()&types.IsString != 0 {
+ obj := a.addNodes(sliceToArray(tDst), "convert")
+ a.endObject(obj, cgn, conv)
+ a.addressOf(tDst, res, obj)
+ return
+ }
+
+ case *types.Basic:
+ // All basic-to-basic type conversions are no-ops.
+ // This includes uintptr<->unsafe.Pointer conversions,
+ // which we (unsoundly) ignore.
+ return
+ }
+ }
+
+ panic(fmt.Sprintf("illegal *ssa.Convert %s -> %s: %s", tSrc, tDst, conv.Parent()))
+}
+
+// genAppend generates constraints for a call to append.
+func (a *analysis) genAppend(instr *ssa.Call, cgn *cgnode) {
+ // Consider z = append(x, y). y is optional.
+ // This may allocate a new [1]T array; call its object w.
+ // We get the following constraints:
+ // z = x
+ // z = &w
+ // *z = *y
+
+ x := instr.Call.Args[0]
+
+ z := instr
+ a.copy(a.valueNode(z), a.valueNode(x), 1) // z = x
+
+ if len(instr.Call.Args) == 1 {
+ return // no allocation for z = append(x) or _ = append(x).
+ }
+
+ // TODO(adonovan): test append([]byte, ...string) []byte.
+
+ y := instr.Call.Args[1]
+ tArray := sliceToArray(instr.Call.Args[0].Type())
+
+ var w nodeid
+ w = a.nextNode()
+ a.addNodes(tArray, "append")
+ a.endObject(w, cgn, instr)
+
+ a.copyElems(cgn, tArray.Elem(), z, y) // *z = *y
+ a.addressOf(instr.Type(), a.valueNode(z), w) // z = &w
+}
+
+// genBuiltinCall generates contraints for a call to a built-in.
+func (a *analysis) genBuiltinCall(instr ssa.CallInstruction, cgn *cgnode) {
+ call := instr.Common()
+ switch call.Value.(*ssa.Builtin).Name() {
+ case "append":
+ // Safe cast: append cannot appear in a go or defer statement.
+ a.genAppend(instr.(*ssa.Call), cgn)
+
+ case "copy":
+ tElem := call.Args[0].Type().Underlying().(*types.Slice).Elem()
+ a.copyElems(cgn, tElem, call.Args[0], call.Args[1])
+
+ case "panic":
+ a.copy(a.panicNode, a.valueNode(call.Args[0]), 1)
+
+ case "recover":
+ if v := instr.Value(); v != nil {
+ a.copy(a.valueNode(v), a.panicNode, 1)
+ }
+
+ case "print":
+ // In the tests, the probe might be the sole reference
+ // to its arg, so make sure we create nodes for it.
+ if len(call.Args) > 0 {
+ a.valueNode(call.Args[0])
+ }
+
+ case "ssa:wrapnilchk":
+ a.copy(a.valueNode(instr.Value()), a.valueNode(call.Args[0]), 1)
+
+ default:
+ // No-ops: close len cap real imag complex print println delete.
+ }
+}
+
+// shouldUseContext defines the context-sensitivity policy. It
+// returns true if we should analyse all static calls to fn anew.
+//
+// Obviously this interface rather limits how much freedom we have to
+// choose a policy. The current policy, rather arbitrarily, is true
+// for intrinsics and accessor methods (actually: short, single-block,
+// call-free functions). This is just a starting point.
+//
+func (a *analysis) shouldUseContext(fn *ssa.Function) bool {
+ if a.findIntrinsic(fn) != nil {
+ return true // treat intrinsics context-sensitively
+ }
+ if len(fn.Blocks) != 1 {
+ return false // too expensive
+ }
+ blk := fn.Blocks[0]
+ if len(blk.Instrs) > 10 {
+ return false // too expensive
+ }
+ if fn.Synthetic != "" && (fn.Pkg == nil || fn != fn.Pkg.Func("init")) {
+ return true // treat synthetic wrappers context-sensitively
+ }
+ for _, instr := range blk.Instrs {
+ switch instr := instr.(type) {
+ case ssa.CallInstruction:
+ // Disallow function calls (except to built-ins)
+ // because of the danger of unbounded recursion.
+ if _, ok := instr.Common().Value.(*ssa.Builtin); !ok {
+ return false
+ }
+ }
+ }
+ return true
+}
+
+// genStaticCall generates constraints for a statically dispatched function call.
+func (a *analysis) genStaticCall(caller *cgnode, site *callsite, call *ssa.CallCommon, result nodeid) {
+ fn := call.StaticCallee()
+
+ // Special cases for inlined intrinsics.
+ switch fn {
+ case a.runtimeSetFinalizer:
+ // Inline SetFinalizer so the call appears direct.
+ site.targets = a.addOneNode(tInvalid, "SetFinalizer.targets", nil)
+ a.addConstraint(&runtimeSetFinalizerConstraint{
+ targets: site.targets,
+ x: a.valueNode(call.Args[0]),
+ f: a.valueNode(call.Args[1]),
+ })
+ return
+
+ case a.reflectValueCall:
+ // Inline (reflect.Value).Call so the call appears direct.
+ dotdotdot := false
+ ret := reflectCallImpl(a, caller, site, a.valueNode(call.Args[0]), a.valueNode(call.Args[1]), dotdotdot)
+ if result != 0 {
+ a.addressOf(fn.Signature.Results().At(0).Type(), result, ret)
+ }
+ return
+ }
+
+ // Ascertain the context (contour/cgnode) for a particular call.
+ var obj nodeid
+ if a.shouldUseContext(fn) {
+ obj = a.makeFunctionObject(fn, site) // new contour
+ } else {
+ obj = a.objectNode(nil, fn) // shared contour
+ }
+ a.callEdge(caller, site, obj)
+
+ sig := call.Signature()
+
+ // Copy receiver, if any.
+ params := a.funcParams(obj)
+ args := call.Args
+ if sig.Recv() != nil {
+ sz := a.sizeof(sig.Recv().Type())
+ a.copy(params, a.valueNode(args[0]), sz)
+ params += nodeid(sz)
+ args = args[1:]
+ }
+
+ // Copy actual parameters into formal params block.
+ // Must loop, since the actuals aren't contiguous.
+ for i, arg := range args {
+ sz := a.sizeof(sig.Params().At(i).Type())
+ a.copy(params, a.valueNode(arg), sz)
+ params += nodeid(sz)
+ }
+
+ // Copy formal results block to actual result.
+ if result != 0 {
+ a.copy(result, a.funcResults(obj), a.sizeof(sig.Results()))
+ }
+}
+
+// genDynamicCall generates constraints for a dynamic function call.
+func (a *analysis) genDynamicCall(caller *cgnode, site *callsite, call *ssa.CallCommon, result nodeid) {
+ // pts(targets) will be the set of possible call targets.
+ site.targets = a.valueNode(call.Value)
+
+ // We add dynamic closure rules that store the arguments into
+ // the P-block and load the results from the R-block of each
+ // function discovered in pts(targets).
+
+ sig := call.Signature()
+ var offset uint32 = 1 // P/R block starts at offset 1
+ for i, arg := range call.Args {
+ sz := a.sizeof(sig.Params().At(i).Type())
+ a.genStore(caller, call.Value, a.valueNode(arg), offset, sz)
+ offset += sz
+ }
+ if result != 0 {
+ a.genLoad(caller, result, call.Value, offset, a.sizeof(sig.Results()))
+ }
+}
+
+// genInvoke generates constraints for a dynamic method invocation.
+func (a *analysis) genInvoke(caller *cgnode, site *callsite, call *ssa.CallCommon, result nodeid) {
+ if call.Value.Type() == a.reflectType {
+ a.genInvokeReflectType(caller, site, call, result)
+ return
+ }
+
+ sig := call.Signature()
+
+ // Allocate a contiguous targets/params/results block for this call.
+ block := a.nextNode()
+ // pts(targets) will be the set of possible call targets
+ site.targets = a.addOneNode(sig, "invoke.targets", nil)
+ p := a.addNodes(sig.Params(), "invoke.params")
+ r := a.addNodes(sig.Results(), "invoke.results")
+
+ // Copy the actual parameters into the call's params block.
+ for i, n := 0, sig.Params().Len(); i < n; i++ {
+ sz := a.sizeof(sig.Params().At(i).Type())
+ a.copy(p, a.valueNode(call.Args[i]), sz)
+ p += nodeid(sz)
+ }
+ // Copy the call's results block to the actual results.
+ if result != 0 {
+ a.copy(result, r, a.sizeof(sig.Results()))
+ }
+
+ // We add a dynamic invoke constraint that will connect the
+ // caller's and the callee's P/R blocks for each discovered
+ // call target.
+ a.addConstraint(&invokeConstraint{call.Method, a.valueNode(call.Value), block})
+}
+
+// genInvokeReflectType is a specialization of genInvoke where the
+// receiver type is a reflect.Type, under the assumption that there
+// can be at most one implementation of this interface, *reflect.rtype.
+//
+// (Though this may appear to be an instance of a pattern---method
+// calls on interfaces known to have exactly one implementation---in
+// practice it occurs rarely, so we special case for reflect.Type.)
+//
+// In effect we treat this:
+// var rt reflect.Type = ...
+// rt.F()
+// as this:
+// rt.(*reflect.rtype).F()
+//
+func (a *analysis) genInvokeReflectType(caller *cgnode, site *callsite, call *ssa.CallCommon, result nodeid) {
+ // Unpack receiver into rtype
+ rtype := a.addOneNode(a.reflectRtypePtr, "rtype.recv", nil)
+ recv := a.valueNode(call.Value)
+ a.typeAssert(a.reflectRtypePtr, rtype, recv, true)
+
+ // Look up the concrete method.
+ fn := a.prog.LookupMethod(a.reflectRtypePtr, call.Method.Pkg(), call.Method.Name())
+
+ obj := a.makeFunctionObject(fn, site) // new contour for this call
+ a.callEdge(caller, site, obj)
+
+ // From now on, it's essentially a static call, but little is
+ // gained by factoring together the code for both cases.
+
+ sig := fn.Signature // concrete method
+ targets := a.addOneNode(sig, "call.targets", nil)
+ a.addressOf(sig, targets, obj) // (a singleton)
+
+ // Copy receiver.
+ params := a.funcParams(obj)
+ a.copy(params, rtype, 1)
+ params++
+
+ // Copy actual parameters into formal P-block.
+ // Must loop, since the actuals aren't contiguous.
+ for i, arg := range call.Args {
+ sz := a.sizeof(sig.Params().At(i).Type())
+ a.copy(params, a.valueNode(arg), sz)
+ params += nodeid(sz)
+ }
+
+ // Copy formal R-block to actual R-block.
+ if result != 0 {
+ a.copy(result, a.funcResults(obj), a.sizeof(sig.Results()))
+ }
+}
+
+// genCall generates constraints for call instruction instr.
+func (a *analysis) genCall(caller *cgnode, instr ssa.CallInstruction) {
+ call := instr.Common()
+
+ // Intrinsic implementations of built-in functions.
+ if _, ok := call.Value.(*ssa.Builtin); ok {
+ a.genBuiltinCall(instr, caller)
+ return
+ }
+
+ var result nodeid
+ if v := instr.Value(); v != nil {
+ result = a.valueNode(v)
+ }
+
+ site := &callsite{instr: instr}
+ if call.StaticCallee() != nil {
+ a.genStaticCall(caller, site, call, result)
+ } else if call.IsInvoke() {
+ a.genInvoke(caller, site, call, result)
+ } else {
+ a.genDynamicCall(caller, site, call, result)
+ }
+
+ caller.sites = append(caller.sites, site)
+
+ if a.log != nil {
+ // TODO(adonovan): debug: improve log message.
+ fmt.Fprintf(a.log, "\t%s to targets %s from %s\n", site, site.targets, caller)
+ }
+}
+
+// objectNode returns the object to which v points, if known.
+// In other words, if the points-to set of v is a singleton, it
+// returns the sole label, zero otherwise.
+//
+// We exploit this information to make the generated constraints less
+// dynamic. For example, a complex load constraint can be replaced by
+// a simple copy constraint when the sole destination is known a priori.
+//
+// Some SSA instructions always have singletons points-to sets:
+// Alloc, Function, Global, MakeChan, MakeClosure, MakeInterface, MakeMap, MakeSlice.
+// Others may be singletons depending on their operands:
+// FreeVar, Const, Convert, FieldAddr, IndexAddr, Slice.
+//
+// Idempotent. Objects are created as needed, possibly via recursion
+// down the SSA value graph, e.g IndexAddr(FieldAddr(Alloc))).
+//
+func (a *analysis) objectNode(cgn *cgnode, v ssa.Value) nodeid {
+ switch v.(type) {
+ case *ssa.Global, *ssa.Function, *ssa.Const, *ssa.FreeVar:
+ // Global object.
+ obj, ok := a.globalobj[v]
+ if !ok {
+ switch v := v.(type) {
+ case *ssa.Global:
+ obj = a.nextNode()
+ a.addNodes(mustDeref(v.Type()), "global")
+ a.endObject(obj, nil, v)
+
+ case *ssa.Function:
+ obj = a.makeFunctionObject(v, nil)
+
+ case *ssa.Const:
+ // not addressable
+
+ case *ssa.FreeVar:
+ // not addressable
+ }
+
+ if a.log != nil {
+ fmt.Fprintf(a.log, "\tglobalobj[%s] = n%d\n", v, obj)
+ }
+ a.globalobj[v] = obj
+ }
+ return obj
+ }
+
+ // Local object.
+ obj, ok := a.localobj[v]
+ if !ok {
+ switch v := v.(type) {
+ case *ssa.Alloc:
+ obj = a.nextNode()
+ a.addNodes(mustDeref(v.Type()), "alloc")
+ a.endObject(obj, cgn, v)
+
+ case *ssa.MakeSlice:
+ obj = a.nextNode()
+ a.addNodes(sliceToArray(v.Type()), "makeslice")
+ a.endObject(obj, cgn, v)
+
+ case *ssa.MakeChan:
+ obj = a.nextNode()
+ a.addNodes(v.Type().Underlying().(*types.Chan).Elem(), "makechan")
+ a.endObject(obj, cgn, v)
+
+ case *ssa.MakeMap:
+ obj = a.nextNode()
+ tmap := v.Type().Underlying().(*types.Map)
+ a.addNodes(tmap.Key(), "makemap.key")
+ elem := a.addNodes(tmap.Elem(), "makemap.value")
+
+ // To update the value field, MapUpdate
+ // generates store-with-offset constraints which
+ // the presolver can't model, so we must mark
+ // those nodes indirect.
+ for id, end := elem, elem+nodeid(a.sizeof(tmap.Elem())); id < end; id++ {
+ a.mapValues = append(a.mapValues, id)
+ }
+ a.endObject(obj, cgn, v)
+
+ case *ssa.MakeInterface:
+ tConc := v.X.Type()
+ obj = a.makeTagged(tConc, cgn, v)
+
+ // Copy the value into it, if nontrivial.
+ if x := a.valueNode(v.X); x != 0 {
+ a.copy(obj+1, x, a.sizeof(tConc))
+ }
+
+ case *ssa.FieldAddr:
+ if xobj := a.objectNode(cgn, v.X); xobj != 0 {
+ obj = xobj + nodeid(a.offsetOf(mustDeref(v.X.Type()), v.Field))
+ }
+
+ case *ssa.IndexAddr:
+ if xobj := a.objectNode(cgn, v.X); xobj != 0 {
+ obj = xobj + 1
+ }
+
+ case *ssa.Slice:
+ obj = a.objectNode(cgn, v.X)
+
+ case *ssa.Convert:
+ // TODO(adonovan): opt: handle these cases too:
+ // - unsafe.Pointer->*T conversion acts like Alloc
+ // - string->[]byte/[]rune conversion acts like MakeSlice
+ }
+
+ if a.log != nil {
+ fmt.Fprintf(a.log, "\tlocalobj[%s] = n%d\n", v.Name(), obj)
+ }
+ a.localobj[v] = obj
+ }
+ return obj
+}
+
+// genLoad generates constraints for result = *(ptr + val).
+func (a *analysis) genLoad(cgn *cgnode, result nodeid, ptr ssa.Value, offset, sizeof uint32) {
+ if obj := a.objectNode(cgn, ptr); obj != 0 {
+ // Pre-apply loadConstraint.solve().
+ a.copy(result, obj+nodeid(offset), sizeof)
+ } else {
+ a.load(result, a.valueNode(ptr), offset, sizeof)
+ }
+}
+
+// genOffsetAddr generates constraints for a 'v=ptr.field' (FieldAddr)
+// or 'v=ptr[*]' (IndexAddr) instruction v.
+func (a *analysis) genOffsetAddr(cgn *cgnode, v ssa.Value, ptr nodeid, offset uint32) {
+ dst := a.valueNode(v)
+ if obj := a.objectNode(cgn, v); obj != 0 {
+ // Pre-apply offsetAddrConstraint.solve().
+ a.addressOf(v.Type(), dst, obj)
+ } else {
+ a.offsetAddr(v.Type(), dst, ptr, offset)
+ }
+}
+
+// genStore generates constraints for *(ptr + offset) = val.
+func (a *analysis) genStore(cgn *cgnode, ptr ssa.Value, val nodeid, offset, sizeof uint32) {
+ if obj := a.objectNode(cgn, ptr); obj != 0 {
+ // Pre-apply storeConstraint.solve().
+ a.copy(obj+nodeid(offset), val, sizeof)
+ } else {
+ a.store(a.valueNode(ptr), val, offset, sizeof)
+ }
+}
+
+// genInstr generates constraints for instruction instr in context cgn.
+func (a *analysis) genInstr(cgn *cgnode, instr ssa.Instruction) {
+ if a.log != nil {
+ var prefix string
+ if val, ok := instr.(ssa.Value); ok {
+ prefix = val.Name() + " = "
+ }
+ fmt.Fprintf(a.log, "; %s%s\n", prefix, instr)
+ }
+
+ switch instr := instr.(type) {
+ case *ssa.DebugRef:
+ // no-op.
+
+ case *ssa.UnOp:
+ switch instr.Op {
+ case token.ARROW: // <-x
+ // We can ignore instr.CommaOk because the node we're
+ // altering is always at zero offset relative to instr
+ tElem := instr.X.Type().Underlying().(*types.Chan).Elem()
+ a.genLoad(cgn, a.valueNode(instr), instr.X, 0, a.sizeof(tElem))
+
+ case token.MUL: // *x
+ a.genLoad(cgn, a.valueNode(instr), instr.X, 0, a.sizeof(instr.Type()))
+
+ default:
+ // NOT, SUB, XOR: no-op.
+ }
+
+ case *ssa.BinOp:
+ // All no-ops.
+
+ case ssa.CallInstruction: // *ssa.Call, *ssa.Go, *ssa.Defer
+ a.genCall(cgn, instr)
+
+ case *ssa.ChangeType:
+ a.copy(a.valueNode(instr), a.valueNode(instr.X), 1)
+
+ case *ssa.Convert:
+ a.genConv(instr, cgn)
+
+ case *ssa.Extract:
+ a.copy(a.valueNode(instr),
+ a.valueOffsetNode(instr.Tuple, instr.Index),
+ a.sizeof(instr.Type()))
+
+ case *ssa.FieldAddr:
+ a.genOffsetAddr(cgn, instr, a.valueNode(instr.X),
+ a.offsetOf(mustDeref(instr.X.Type()), instr.Field))
+
+ case *ssa.IndexAddr:
+ a.genOffsetAddr(cgn, instr, a.valueNode(instr.X), 1)
+
+ case *ssa.Field:
+ a.copy(a.valueNode(instr),
+ a.valueOffsetNode(instr.X, instr.Field),
+ a.sizeof(instr.Type()))
+
+ case *ssa.Index:
+ a.copy(a.valueNode(instr), 1+a.valueNode(instr.X), a.sizeof(instr.Type()))
+
+ case *ssa.Select:
+ recv := a.valueOffsetNode(instr, 2) // instr : (index, recvOk, recv0, ... recv_n-1)
+ for _, st := range instr.States {
+ elemSize := a.sizeof(st.Chan.Type().Underlying().(*types.Chan).Elem())
+ switch st.Dir {
+ case types.RecvOnly:
+ a.genLoad(cgn, recv, st.Chan, 0, elemSize)
+ recv += nodeid(elemSize)
+
+ case types.SendOnly:
+ a.genStore(cgn, st.Chan, a.valueNode(st.Send), 0, elemSize)
+ }
+ }
+
+ case *ssa.Return:
+ results := a.funcResults(cgn.obj)
+ for _, r := range instr.Results {
+ sz := a.sizeof(r.Type())
+ a.copy(results, a.valueNode(r), sz)
+ results += nodeid(sz)
+ }
+
+ case *ssa.Send:
+ a.genStore(cgn, instr.Chan, a.valueNode(instr.X), 0, a.sizeof(instr.X.Type()))
+
+ case *ssa.Store:
+ a.genStore(cgn, instr.Addr, a.valueNode(instr.Val), 0, a.sizeof(instr.Val.Type()))
+
+ case *ssa.Alloc, *ssa.MakeSlice, *ssa.MakeChan, *ssa.MakeMap, *ssa.MakeInterface:
+ v := instr.(ssa.Value)
+ a.addressOf(v.Type(), a.valueNode(v), a.objectNode(cgn, v))
+
+ case *ssa.ChangeInterface:
+ a.copy(a.valueNode(instr), a.valueNode(instr.X), 1)
+
+ case *ssa.TypeAssert:
+ a.typeAssert(instr.AssertedType, a.valueNode(instr), a.valueNode(instr.X), true)
+
+ case *ssa.Slice:
+ a.copy(a.valueNode(instr), a.valueNode(instr.X), 1)
+
+ case *ssa.If, *ssa.Jump:
+ // no-op.
+
+ case *ssa.Phi:
+ sz := a.sizeof(instr.Type())
+ for _, e := range instr.Edges {
+ a.copy(a.valueNode(instr), a.valueNode(e), sz)
+ }
+
+ case *ssa.MakeClosure:
+ fn := instr.Fn.(*ssa.Function)
+ a.copy(a.valueNode(instr), a.valueNode(fn), 1)
+ // Free variables are treated like global variables.
+ for i, b := range instr.Bindings {
+ a.copy(a.valueNode(fn.FreeVars[i]), a.valueNode(b), a.sizeof(b.Type()))
+ }
+
+ case *ssa.RunDefers:
+ // The analysis is flow insensitive, so we just "call"
+ // defers as we encounter them.
+
+ case *ssa.Range:
+ // Do nothing. Next{Iter: *ssa.Range} handles this case.
+
+ case *ssa.Next:
+ if !instr.IsString { // map
+ // Assumes that Next is always directly applied to a Range result.
+ theMap := instr.Iter.(*ssa.Range).X
+ tMap := theMap.Type().Underlying().(*types.Map)
+ ksize := a.sizeof(tMap.Key())
+ vsize := a.sizeof(tMap.Elem())
+
+ // Load from the map's (k,v) into the tuple's (ok, k, v).
+ a.genLoad(cgn, a.valueNode(instr)+1, theMap, 0, ksize+vsize)
+ }
+
+ case *ssa.Lookup:
+ if tMap, ok := instr.X.Type().Underlying().(*types.Map); ok {
+ // CommaOk can be ignored: field 0 is a no-op.
+ ksize := a.sizeof(tMap.Key())
+ vsize := a.sizeof(tMap.Elem())
+ a.genLoad(cgn, a.valueNode(instr), instr.X, ksize, vsize)
+ }
+
+ case *ssa.MapUpdate:
+ tmap := instr.Map.Type().Underlying().(*types.Map)
+ ksize := a.sizeof(tmap.Key())
+ vsize := a.sizeof(tmap.Elem())
+ a.genStore(cgn, instr.Map, a.valueNode(instr.Key), 0, ksize)
+ a.genStore(cgn, instr.Map, a.valueNode(instr.Value), ksize, vsize)
+
+ case *ssa.Panic:
+ a.copy(a.panicNode, a.valueNode(instr.X), 1)
+
+ default:
+ panic(fmt.Sprintf("unimplemented: %T", instr))
+ }
+}
+
+func (a *analysis) makeCGNode(fn *ssa.Function, obj nodeid, callersite *callsite) *cgnode {
+ cgn := &cgnode{fn: fn, obj: obj, callersite: callersite}
+ a.cgnodes = append(a.cgnodes, cgn)
+ return cgn
+}
+
+// genRootCalls generates the synthetic root of the callgraph and the
+// initial calls from it to the analysis scope, such as main, a test
+// or a library.
+//
+func (a *analysis) genRootCalls() *cgnode {
+ r := a.prog.NewFunction("", new(types.Signature), "root of callgraph")
+ root := a.makeCGNode(r, 0, nil)
+
+ // TODO(adonovan): make an ssa utility to construct an actual
+ // root function so we don't need to special-case site-less
+ // call edges.
+
+ // For each main package, call main.init(), main.main().
+ for _, mainPkg := range a.config.Mains {
+ main := mainPkg.Func("main")
+ if main == nil {
+ panic(fmt.Sprintf("%s has no main function", mainPkg))
+ }
+
+ targets := a.addOneNode(main.Signature, "root.targets", nil)
+ site := &callsite{targets: targets}
+ root.sites = append(root.sites, site)
+ for _, fn := range [2]*ssa.Function{mainPkg.Func("init"), main} {
+ if a.log != nil {
+ fmt.Fprintf(a.log, "\troot call to %s:\n", fn)
+ }
+ a.copy(targets, a.valueNode(fn), 1)
+ }
+ }
+
+ return root
+}
+
+// genFunc generates constraints for function fn.
+func (a *analysis) genFunc(cgn *cgnode) {
+ fn := cgn.fn
+
+ impl := a.findIntrinsic(fn)
+
+ if a.log != nil {
+ fmt.Fprintf(a.log, "\n\n==== Generating constraints for %s, %s\n", cgn, cgn.contour())
+
+ // Hack: don't display body if intrinsic.
+ if impl != nil {
+ fn2 := *cgn.fn // copy
+ fn2.Locals = nil
+ fn2.Blocks = nil
+ fn2.WriteTo(a.log)
+ } else {
+ cgn.fn.WriteTo(a.log)
+ }
+ }
+
+ if impl != nil {
+ impl(a, cgn)
+ return
+ }
+
+ if fn.Blocks == nil {
+ // External function with no intrinsic treatment.
+ // We'll warn about calls to such functions at the end.
+ return
+ }
+
+ if a.log != nil {
+ fmt.Fprintln(a.log, "; Creating nodes for local values")
+ }
+
+ a.localval = make(map[ssa.Value]nodeid)
+ a.localobj = make(map[ssa.Value]nodeid)
+
+ // The value nodes for the params are in the func object block.
+ params := a.funcParams(cgn.obj)
+ for _, p := range fn.Params {
+ a.setValueNode(p, params, cgn)
+ params += nodeid(a.sizeof(p.Type()))
+ }
+
+ // Free variables have global cardinality:
+ // the outer function sets them with MakeClosure;
+ // the inner function accesses them with FreeVar.
+ //
+ // TODO(adonovan): treat free vars context-sensitively.
+
+ // Create value nodes for all value instructions
+ // since SSA may contain forward references.
+ var space [10]*ssa.Value
+ for _, b := range fn.Blocks {
+ for _, instr := range b.Instrs {
+ switch instr := instr.(type) {
+ case *ssa.Range:
+ // do nothing: it has a funky type,
+ // and *ssa.Next does all the work.
+
+ case ssa.Value:
+ var comment string
+ if a.log != nil {
+ comment = instr.Name()
+ }
+ id := a.addNodes(instr.Type(), comment)
+ a.setValueNode(instr, id, cgn)
+ }
+
+ // Record all address-taken functions (for presolver).
+ rands := instr.Operands(space[:0])
+ if call, ok := instr.(ssa.CallInstruction); ok && !call.Common().IsInvoke() {
+ // Skip CallCommon.Value in "call" mode.
+ // TODO(adonovan): fix: relies on unspecified ordering. Specify it.
+ rands = rands[1:]
+ }
+ for _, rand := range rands {
+ if atf, ok := (*rand).(*ssa.Function); ok {
+ a.atFuncs[atf] = true
+ }
+ }
+ }
+ }
+
+ // Generate constraints for instructions.
+ for _, b := range fn.Blocks {
+ for _, instr := range b.Instrs {
+ a.genInstr(cgn, instr)
+ }
+ }
+
+ a.localval = nil
+ a.localobj = nil
+}
+
+// genMethodsOf generates nodes and constraints for all methods of type T.
+func (a *analysis) genMethodsOf(T types.Type) {
+ itf := isInterface(T)
+
+ // TODO(adonovan): can we skip this entirely if itf is true?
+ // I think so, but the answer may depend on reflection.
+ mset := a.prog.MethodSets.MethodSet(T)
+ for i, n := 0, mset.Len(); i < n; i++ {
+ m := a.prog.Method(mset.At(i))
+ a.valueNode(m)
+
+ if !itf {
+ // Methods of concrete types are address-taken functions.
+ a.atFuncs[m] = true
+ }
+ }
+}
+
+// generate generates offline constraints for the entire program.
+func (a *analysis) generate() {
+ start("Constraint generation")
+ if a.log != nil {
+ fmt.Fprintln(a.log, "==== Generating constraints")
+ }
+
+ // Create a dummy node since we use the nodeid 0 for
+ // non-pointerlike variables.
+ a.addNodes(tInvalid, "(zero)")
+
+ // Create the global node for panic values.
+ a.panicNode = a.addNodes(tEface, "panic")
+
+ // Create nodes and constraints for all methods of reflect.rtype.
+ // (Shared contours are used by dynamic calls to reflect.Type
+ // methods---typically just String().)
+ if rtype := a.reflectRtypePtr; rtype != nil {
+ a.genMethodsOf(rtype)
+ }
+
+ root := a.genRootCalls()
+
+ if a.config.BuildCallGraph {
+ a.result.CallGraph = callgraph.New(root.fn)
+ }
+
+ // Create nodes and constraints for all methods of all types
+ // that are dynamically accessible via reflection or interfaces.
+ for _, T := range a.prog.RuntimeTypes() {
+ a.genMethodsOf(T)
+ }
+
+ // Generate constraints for entire program.
+ for len(a.genq) > 0 {
+ cgn := a.genq[0]
+ a.genq = a.genq[1:]
+ a.genFunc(cgn)
+ }
+
+ // The runtime magically allocates os.Args; so should we.
+ if os := a.prog.ImportedPackage("os"); os != nil {
+ // In effect: os.Args = new([1]string)[:]
+ T := types.NewSlice(types.Typ[types.String])
+ obj := a.addNodes(sliceToArray(T), "")
+ a.endObject(obj, nil, "")
+ a.addressOf(T, a.objectNode(nil, os.Var("Args")), obj)
+ }
+
+ // Discard generation state, to avoid confusion after node renumbering.
+ a.panicNode = 0
+ a.globalval = nil
+ a.localval = nil
+ a.localobj = nil
+
+ stop("Constraint generation")
+}
diff --git a/vendor/golang.org/x/tools/go/pointer/hvn.go b/vendor/golang.org/x/tools/go/pointer/hvn.go
new file mode 100644
index 0000000..a3ef1f3
--- /dev/null
+++ b/vendor/golang.org/x/tools/go/pointer/hvn.go
@@ -0,0 +1,969 @@
+package pointer
+
+// This file implements Hash-Value Numbering (HVN), a pre-solver
+// constraint optimization described in Hardekopf & Lin, SAS'07 (see
+// doc.go) that analyses the graph topology to determine which sets of
+// variables are "pointer equivalent" (PE), i.e. must have identical
+// points-to sets in the solution.
+//
+// A separate ("offline") graph is constructed. Its nodes are those of
+// the main-graph, plus an additional node *X for each pointer node X.
+// With this graph we can reason about the unknown points-to set of
+// dereferenced pointers. (We do not generalize this to represent
+// unknown fields x->f, perhaps because such fields would be numerous,
+// though it might be worth an experiment.)
+//
+// Nodes whose points-to relations are not entirely captured by the
+// graph are marked as "indirect": the *X nodes, the parameters of
+// address-taken functions (which includes all functions in method
+// sets), or nodes updated by the solver rules for reflection, etc.
+//
+// All addr (y=&x) nodes are initially assigned a pointer-equivalence
+// (PE) label equal to x's nodeid in the main graph. (These are the
+// only PE labels that are less than len(a.nodes).)
+//
+// All offsetAddr (y=&x.f) constraints are initially assigned a PE
+// label; such labels are memoized, keyed by (x, f), so that equivalent
+// nodes y as assigned the same label.
+//
+// Then we process each strongly connected component (SCC) of the graph
+// in topological order, assigning it a PE label based on the set P of
+// PE labels that flow to it from its immediate dependencies.
+//
+// If any node in P is "indirect", the entire SCC is assigned a fresh PE
+// label. Otherwise:
+//
+// |P|=0 if P is empty, all nodes in the SCC are non-pointers (e.g.
+// uninitialized variables, or formal params of dead functions)
+// and the SCC is assigned the PE label of zero.
+//
+// |P|=1 if P is a singleton, the SCC is assigned the same label as the
+// sole element of P.
+//
+// |P|>1 if P contains multiple labels, a unique label representing P is
+// invented and recorded in an hash table, so that other
+// equivalent SCCs may also be assigned this label, akin to
+// conventional hash-value numbering in a compiler.
+//
+// Finally, a renumbering is computed such that each node is replaced by
+// the lowest-numbered node with the same PE label. All constraints are
+// renumbered, and any resulting duplicates are eliminated.
+//
+// The only nodes that are not renumbered are the objects x in addr
+// (y=&x) constraints, since the ids of these nodes (and fields derived
+// from them via offsetAddr rules) are the elements of all points-to
+// sets, so they must remain as they are if we want the same solution.
+//
+// The solverStates (node.solve) for nodes in the same equivalence class
+// are linked together so that all nodes in the class have the same
+// solution. This avoids the need to renumber nodeids buried in
+// Queries, cgnodes, etc (like (*analysis).renumber() does) since only
+// the solution is needed.
+//
+// The result of HVN is that the number of distinct nodes and
+// constraints is reduced, but the solution is identical (almost---see
+// CROSS-CHECK below). In particular, both linear and cyclic chains of
+// copies are each replaced by a single node.
+//
+// Nodes and constraints created "online" (e.g. while solving reflection
+// constraints) are not subject to this optimization.
+//
+// PERFORMANCE
+//
+// In two benchmarks (oracle and godoc), HVN eliminates about two thirds
+// of nodes, the majority accounted for by non-pointers: nodes of
+// non-pointer type, pointers that remain nil, formal parameters of dead
+// functions, nodes of untracked types, etc. It also reduces the number
+// of constraints, also by about two thirds, and the solving time by
+// 30--42%, although we must pay about 15% for the running time of HVN
+// itself. The benefit is greater for larger applications.
+//
+// There are many possible optimizations to improve the performance:
+// * Use fewer than 1:1 onodes to main graph nodes: many of the onodes
+// we create are not needed.
+// * HU (HVN with Union---see paper): coalesce "union" peLabels when
+// their expanded-out sets are equal.
+// * HR (HVN with deReference---see paper): this will require that we
+// apply HVN until fixed point, which may need more bookkeeping of the
+// correspondance of main nodes to onodes.
+// * Location Equivalence (see paper): have points-to sets contain not
+// locations but location-equivalence class labels, each representing
+// a set of locations.
+// * HVN with field-sensitive ref: model each of the fields of a
+// pointer-to-struct.
+//
+// CROSS-CHECK
+//
+// To verify the soundness of the optimization, when the
+// debugHVNCrossCheck option is enabled, we run the solver twice, once
+// before and once after running HVN, dumping the solution to disk, and
+// then we compare the results. If they are not identical, the analysis
+// panics.
+//
+// The solution dumped to disk includes only the N*N submatrix of the
+// complete solution where N is the number of nodes after generation.
+// In other words, we ignore pointer variables and objects created by
+// the solver itself, since their numbering depends on the solver order,
+// which is affected by the optimization. In any case, that's the only
+// part the client cares about.
+//
+// The cross-check is too strict and may fail spuriously. Although the
+// H&L paper describing HVN states that the solutions obtained should be
+// identical, this is not the case in practice because HVN can collapse
+// cycles involving *p even when pts(p)={}. Consider this example
+// distilled from testdata/hello.go:
+//
+// var x T
+// func f(p **T) {
+// t0 = *p
+// ...
+// t1 = φ(t0, &x)
+// *p = t1
+// }
+//
+// If f is dead code, we get:
+// unoptimized: pts(p)={} pts(t0)={} pts(t1)={&x}
+// optimized: pts(p)={} pts(t0)=pts(t1)=pts(*p)={&x}
+//
+// It's hard to argue that this is a bug: the result is sound and the
+// loss of precision is inconsequential---f is dead code, after all.
+// But unfortunately it limits the usefulness of the cross-check since
+// failures must be carefully analyzed. Ben Hardekopf suggests (in
+// personal correspondence) some approaches to mitigating it:
+//
+// If there is a node with an HVN points-to set that is a superset
+// of the NORM points-to set, then either it's a bug or it's a
+// result of this issue. If it's a result of this issue, then in
+// the offline constraint graph there should be a REF node inside
+// some cycle that reaches this node, and in the NORM solution the
+// pointer being dereferenced by that REF node should be the empty
+// set. If that isn't true then this is a bug. If it is true, then
+// you can further check that in the NORM solution the "extra"
+// points-to info in the HVN solution does in fact come from that
+// purported cycle (if it doesn't, then this is still a bug). If
+// you're doing the further check then you'll need to do it for
+// each "extra" points-to element in the HVN points-to set.
+//
+// There are probably ways to optimize these checks by taking
+// advantage of graph properties. For example, extraneous points-to
+// info will flow through the graph and end up in many
+// nodes. Rather than checking every node with extra info, you
+// could probably work out the "origin point" of the extra info and
+// just check there. Note that the check in the first bullet is
+// looking for soundness bugs, while the check in the second bullet
+// is looking for precision bugs; depending on your needs, you may
+// care more about one than the other.
+//
+// which we should evaluate. The cross-check is nonetheless invaluable
+// for all but one of the programs in the pointer_test suite.
+
+import (
+ "fmt"
+ "io"
+ "reflect"
+
+ "golang.org/x/tools/container/intsets"
+ "golang.org/x/tools/go/types"
+)
+
+// A peLabel is a pointer-equivalence label: two nodes with the same
+// peLabel have identical points-to solutions.
+//
+// The numbers are allocated consecutively like so:
+// 0 not a pointer
+// 1..N-1 addrConstraints (equals the constraint's .src field, hence sparse)
+// ... offsetAddr constraints
+// ... SCCs (with indirect nodes or multiple inputs)
+//
+// Each PE label denotes a set of pointers containing a single addr, a
+// single offsetAddr, or some set of other PE labels.
+//
+type peLabel int
+
+type hvn struct {
+ a *analysis
+ N int // len(a.nodes) immediately after constraint generation
+ log io.Writer // (optional) log of HVN lemmas
+ onodes []*onode // nodes of the offline graph
+ label peLabel // the next available PE label
+ hvnLabel map[string]peLabel // hash-value numbering (PE label) for each set of onodeids
+ stack []onodeid // DFS stack
+ index int32 // next onode.index, from Tarjan's SCC algorithm
+
+ // For each distinct offsetAddrConstraint (src, offset) pair,
+ // offsetAddrLabels records a unique PE label >= N.
+ offsetAddrLabels map[offsetAddr]peLabel
+}
+
+// The index of an node in the offline graph.
+// (Currently the first N align with the main nodes,
+// but this may change with HRU.)
+type onodeid uint32
+
+// An onode is a node in the offline constraint graph.
+// (Where ambiguous, members of analysis.nodes are referred to as
+// "main graph" nodes.)
+//
+// Edges in the offline constraint graph (edges and implicit) point to
+// the source, i.e. against the flow of values: they are dependencies.
+// Implicit edges are used for SCC computation, but not for gathering
+// incoming labels.
+//
+type onode struct {
+ rep onodeid // index of representative of SCC in offline constraint graph
+
+ edges intsets.Sparse // constraint edges X-->Y (this onode is X)
+ implicit intsets.Sparse // implicit edges *X-->*Y (this onode is X)
+ peLabels intsets.Sparse // set of peLabels are pointer-equivalent to this one
+ indirect bool // node has points-to relations not represented in graph
+
+ // Tarjan's SCC algorithm
+ index, lowlink int32 // Tarjan numbering
+ scc int32 // -ve => on stack; 0 => unvisited; +ve => node is root of a found SCC
+}
+
+type offsetAddr struct {
+ ptr nodeid
+ offset uint32
+}
+
+// nextLabel issues the next unused pointer-equivalence label.
+func (h *hvn) nextLabel() peLabel {
+ h.label++
+ return h.label
+}
+
+// ref(X) returns the index of the onode for *X.
+func (h *hvn) ref(id onodeid) onodeid {
+ return id + onodeid(len(h.a.nodes))
+}
+
+// hvn computes pointer-equivalence labels (peLabels) using the Hash-based
+// Value Numbering (HVN) algorithm described in Hardekopf & Lin, SAS'07.
+//
+func (a *analysis) hvn() {
+ start("HVN")
+
+ if a.log != nil {
+ fmt.Fprintf(a.log, "\n\n==== Pointer equivalence optimization\n\n")
+ }
+
+ h := hvn{
+ a: a,
+ N: len(a.nodes),
+ log: a.log,
+ hvnLabel: make(map[string]peLabel),
+ offsetAddrLabels: make(map[offsetAddr]peLabel),
+ }
+
+ if h.log != nil {
+ fmt.Fprintf(h.log, "\nCreating offline graph nodes...\n")
+ }
+
+ // Create offline nodes. The first N nodes correspond to main
+ // graph nodes; the next N are their corresponding ref() nodes.
+ h.onodes = make([]*onode, 2*h.N)
+ for id := range a.nodes {
+ id := onodeid(id)
+ h.onodes[id] = &onode{}
+ h.onodes[h.ref(id)] = &onode{indirect: true}
+ }
+
+ // Each node initially represents just itself.
+ for id, o := range h.onodes {
+ o.rep = onodeid(id)
+ }
+
+ h.markIndirectNodes()
+
+ // Reserve the first N PE labels for addrConstraints.
+ h.label = peLabel(h.N)
+
+ // Add offline constraint edges.
+ if h.log != nil {
+ fmt.Fprintf(h.log, "\nAdding offline graph edges...\n")
+ }
+ for _, c := range a.constraints {
+ if debugHVNVerbose && h.log != nil {
+ fmt.Fprintf(h.log, "; %s\n", c)
+ }
+ c.presolve(&h)
+ }
+
+ // Find and collapse SCCs.
+ if h.log != nil {
+ fmt.Fprintf(h.log, "\nFinding SCCs...\n")
+ }
+ h.index = 1
+ for id, o := range h.onodes {
+ if id > 0 && o.index == 0 {
+ // Start depth-first search at each unvisited node.
+ h.visit(onodeid(id))
+ }
+ }
+
+ // Dump the solution
+ // (NB: somewhat redundant with logging from simplify().)
+ if debugHVNVerbose && h.log != nil {
+ fmt.Fprintf(h.log, "\nPointer equivalences:\n")
+ for id, o := range h.onodes {
+ if id == 0 {
+ continue
+ }
+ if id == int(h.N) {
+ fmt.Fprintf(h.log, "---\n")
+ }
+ fmt.Fprintf(h.log, "o%d\t", id)
+ if o.rep != onodeid(id) {
+ fmt.Fprintf(h.log, "rep=o%d", o.rep)
+ } else {
+ fmt.Fprintf(h.log, "p%d", o.peLabels.Min())
+ if o.indirect {
+ fmt.Fprint(h.log, " indirect")
+ }
+ }
+ fmt.Fprintln(h.log)
+ }
+ }
+
+ // Simplify the main constraint graph
+ h.simplify()
+
+ a.showCounts()
+
+ stop("HVN")
+}
+
+// ---- constraint-specific rules ----
+
+// dst := &src
+func (c *addrConstraint) presolve(h *hvn) {
+ // Each object (src) is an initial PE label.
+ label := peLabel(c.src) // label < N
+ if debugHVNVerbose && h.log != nil {
+ // duplicate log messages are possible
+ fmt.Fprintf(h.log, "\tcreate p%d: {&n%d}\n", label, c.src)
+ }
+ odst := onodeid(c.dst)
+ osrc := onodeid(c.src)
+
+ // Assign dst this label.
+ h.onodes[odst].peLabels.Insert(int(label))
+ if debugHVNVerbose && h.log != nil {
+ fmt.Fprintf(h.log, "\to%d has p%d\n", odst, label)
+ }
+
+ h.addImplicitEdge(h.ref(odst), osrc) // *dst ~~> src.
+}
+
+// dst = src
+func (c *copyConstraint) presolve(h *hvn) {
+ odst := onodeid(c.dst)
+ osrc := onodeid(c.src)
+ h.addEdge(odst, osrc) // dst --> src
+ h.addImplicitEdge(h.ref(odst), h.ref(osrc)) // *dst ~~> *src
+}
+
+// dst = *src + offset
+func (c *loadConstraint) presolve(h *hvn) {
+ odst := onodeid(c.dst)
+ osrc := onodeid(c.src)
+ if c.offset == 0 {
+ h.addEdge(odst, h.ref(osrc)) // dst --> *src
+ } else {
+ // We don't interpret load-with-offset, e.g. results
+ // of map value lookup, R-block of dynamic call, slice
+ // copy/append, reflection.
+ h.markIndirect(odst, "load with offset")
+ }
+}
+
+// *dst + offset = src
+func (c *storeConstraint) presolve(h *hvn) {
+ odst := onodeid(c.dst)
+ osrc := onodeid(c.src)
+ if c.offset == 0 {
+ h.onodes[h.ref(odst)].edges.Insert(int(osrc)) // *dst --> src
+ if debugHVNVerbose && h.log != nil {
+ fmt.Fprintf(h.log, "\to%d --> o%d\n", h.ref(odst), osrc)
+ }
+ } else {
+ // We don't interpret store-with-offset.
+ // See discussion of soundness at markIndirectNodes.
+ }
+}
+
+// dst = &src.offset
+func (c *offsetAddrConstraint) presolve(h *hvn) {
+ // Give each distinct (addr, offset) pair a fresh PE label.
+ // The cache performs CSE, effectively.
+ key := offsetAddr{c.src, c.offset}
+ label, ok := h.offsetAddrLabels[key]
+ if !ok {
+ label = h.nextLabel()
+ h.offsetAddrLabels[key] = label
+ if debugHVNVerbose && h.log != nil {
+ fmt.Fprintf(h.log, "\tcreate p%d: {&n%d.#%d}\n",
+ label, c.src, c.offset)
+ }
+ }
+
+ // Assign dst this label.
+ h.onodes[c.dst].peLabels.Insert(int(label))
+ if debugHVNVerbose && h.log != nil {
+ fmt.Fprintf(h.log, "\to%d has p%d\n", c.dst, label)
+ }
+}
+
+// dst = src.(typ) where typ is an interface
+func (c *typeFilterConstraint) presolve(h *hvn) {
+ h.markIndirect(onodeid(c.dst), "typeFilter result")
+}
+
+// dst = src.(typ) where typ is concrete
+func (c *untagConstraint) presolve(h *hvn) {
+ odst := onodeid(c.dst)
+ for end := odst + onodeid(h.a.sizeof(c.typ)); odst < end; odst++ {
+ h.markIndirect(odst, "untag result")
+ }
+}
+
+// dst = src.method(c.params...)
+func (c *invokeConstraint) presolve(h *hvn) {
+ // All methods are address-taken functions, so
+ // their formal P-blocks were already marked indirect.
+
+ // Mark the caller's targets node as indirect.
+ sig := c.method.Type().(*types.Signature)
+ id := c.params
+ h.markIndirect(onodeid(c.params), "invoke targets node")
+ id++
+
+ id += nodeid(h.a.sizeof(sig.Params()))
+
+ // Mark the caller's R-block as indirect.
+ end := id + nodeid(h.a.sizeof(sig.Results()))
+ for id < end {
+ h.markIndirect(onodeid(id), "invoke R-block")
+ id++
+ }
+}
+
+// markIndirectNodes marks as indirect nodes whose points-to relations
+// are not entirely captured by the offline graph, including:
+//
+// (a) All address-taken nodes (including the following nodes within
+// the same object). This is described in the paper.
+//
+// The most subtle cause of indirect nodes is the generation of
+// store-with-offset constraints since the offline graph doesn't
+// represent them. A global audit of constraint generation reveals the
+// following uses of store-with-offset:
+//
+// (b) genDynamicCall, for P-blocks of dynamically called functions,
+// to which dynamic copy edges will be added to them during
+// solving: from storeConstraint for standalone functions,
+// and from invokeConstraint for methods.
+// All such P-blocks must be marked indirect.
+// (c) MakeUpdate, to update the value part of a map object.
+// All MakeMap objects's value parts must be marked indirect.
+// (d) copyElems, to update the destination array.
+// All array elements must be marked indirect.
+//
+// Not all indirect marking happens here. ref() nodes are marked
+// indirect at construction, and each constraint's presolve() method may
+// mark additional nodes.
+//
+func (h *hvn) markIndirectNodes() {
+ // (a) all address-taken nodes, plus all nodes following them
+ // within the same object, since these may be indirectly
+ // stored or address-taken.
+ for _, c := range h.a.constraints {
+ if c, ok := c.(*addrConstraint); ok {
+ start := h.a.enclosingObj(c.src)
+ end := start + nodeid(h.a.nodes[start].obj.size)
+ for id := c.src; id < end; id++ {
+ h.markIndirect(onodeid(id), "A-T object")
+ }
+ }
+ }
+
+ // (b) P-blocks of all address-taken functions.
+ for id := 0; id < h.N; id++ {
+ obj := h.a.nodes[id].obj
+
+ // TODO(adonovan): opt: if obj.cgn.fn is a method and
+ // obj.cgn is not its shared contour, this is an
+ // "inlined" static method call. We needn't consider it
+ // address-taken since no invokeConstraint will affect it.
+
+ if obj != nil && obj.flags&otFunction != 0 && h.a.atFuncs[obj.cgn.fn] {
+ // address-taken function
+ if debugHVNVerbose && h.log != nil {
+ fmt.Fprintf(h.log, "n%d is address-taken: %s\n", id, obj.cgn.fn)
+ }
+ h.markIndirect(onodeid(id), "A-T func identity")
+ id++
+ sig := obj.cgn.fn.Signature
+ psize := h.a.sizeof(sig.Params())
+ if sig.Recv() != nil {
+ psize += h.a.sizeof(sig.Recv().Type())
+ }
+ for end := id + int(psize); id < end; id++ {
+ h.markIndirect(onodeid(id), "A-T func P-block")
+ }
+ id--
+ continue
+ }
+ }
+
+ // (c) all map objects' value fields.
+ for _, id := range h.a.mapValues {
+ h.markIndirect(onodeid(id), "makemap.value")
+ }
+
+ // (d) all array element objects.
+ // TODO(adonovan): opt: can we do better?
+ for id := 0; id < h.N; id++ {
+ // Identity node for an object of array type?
+ if tArray, ok := h.a.nodes[id].typ.(*types.Array); ok {
+ // Mark the array element nodes indirect.
+ // (Skip past the identity field.)
+ for _ = range h.a.flatten(tArray.Elem()) {
+ id++
+ h.markIndirect(onodeid(id), "array elem")
+ }
+ }
+ }
+}
+
+func (h *hvn) markIndirect(oid onodeid, comment string) {
+ h.onodes[oid].indirect = true
+ if debugHVNVerbose && h.log != nil {
+ fmt.Fprintf(h.log, "\to%d is indirect: %s\n", oid, comment)
+ }
+}
+
+// Adds an edge dst-->src.
+// Note the unusual convention: edges are dependency (contraflow) edges.
+func (h *hvn) addEdge(odst, osrc onodeid) {
+ h.onodes[odst].edges.Insert(int(osrc))
+ if debugHVNVerbose && h.log != nil {
+ fmt.Fprintf(h.log, "\to%d --> o%d\n", odst, osrc)
+ }
+}
+
+func (h *hvn) addImplicitEdge(odst, osrc onodeid) {
+ h.onodes[odst].implicit.Insert(int(osrc))
+ if debugHVNVerbose && h.log != nil {
+ fmt.Fprintf(h.log, "\to%d ~~> o%d\n", odst, osrc)
+ }
+}
+
+// visit implements the depth-first search of Tarjan's SCC algorithm.
+// Precondition: x is canonical.
+func (h *hvn) visit(x onodeid) {
+ h.checkCanonical(x)
+ xo := h.onodes[x]
+ xo.index = h.index
+ xo.lowlink = h.index
+ h.index++
+
+ h.stack = append(h.stack, x) // push
+ assert(xo.scc == 0, "node revisited")
+ xo.scc = -1
+
+ var deps []int
+ deps = xo.edges.AppendTo(deps)
+ deps = xo.implicit.AppendTo(deps)
+
+ for _, y := range deps {
+ // Loop invariant: x is canonical.
+
+ y := h.find(onodeid(y))
+
+ if x == y {
+ continue // nodes already coalesced
+ }
+
+ xo := h.onodes[x]
+ yo := h.onodes[y]
+
+ switch {
+ case yo.scc > 0:
+ // y is already a collapsed SCC
+
+ case yo.scc < 0:
+ // y is on the stack, and thus in the current SCC.
+ if yo.index < xo.lowlink {
+ xo.lowlink = yo.index
+ }
+
+ default:
+ // y is unvisited; visit it now.
+ h.visit(y)
+ // Note: x and y are now non-canonical.
+
+ x = h.find(onodeid(x))
+
+ if yo.lowlink < xo.lowlink {
+ xo.lowlink = yo.lowlink
+ }
+ }
+ }
+ h.checkCanonical(x)
+
+ // Is x the root of an SCC?
+ if xo.lowlink == xo.index {
+ // Coalesce all nodes in the SCC.
+ if debugHVNVerbose && h.log != nil {
+ fmt.Fprintf(h.log, "scc o%d\n", x)
+ }
+ for {
+ // Pop y from stack.
+ i := len(h.stack) - 1
+ y := h.stack[i]
+ h.stack = h.stack[:i]
+
+ h.checkCanonical(x)
+ xo := h.onodes[x]
+ h.checkCanonical(y)
+ yo := h.onodes[y]
+
+ if xo == yo {
+ // SCC is complete.
+ xo.scc = 1
+ h.labelSCC(x)
+ break
+ }
+ h.coalesce(x, y)
+ }
+ }
+}
+
+// Precondition: x is canonical.
+func (h *hvn) labelSCC(x onodeid) {
+ h.checkCanonical(x)
+ xo := h.onodes[x]
+ xpe := &xo.peLabels
+
+ // All indirect nodes get new labels.
+ if xo.indirect {
+ label := h.nextLabel()
+ if debugHVNVerbose && h.log != nil {
+ fmt.Fprintf(h.log, "\tcreate p%d: indirect SCC\n", label)
+ fmt.Fprintf(h.log, "\to%d has p%d\n", x, label)
+ }
+
+ // Remove pre-labeling, in case a direct pre-labeled node was
+ // merged with an indirect one.
+ xpe.Clear()
+ xpe.Insert(int(label))
+
+ return
+ }
+
+ // Invariant: all peLabels sets are non-empty.
+ // Those that are logically empty contain zero as their sole element.
+ // No other sets contains zero.
+
+ // Find all labels coming in to the coalesced SCC node.
+ for _, y := range xo.edges.AppendTo(nil) {
+ y := h.find(onodeid(y))
+ if y == x {
+ continue // already coalesced
+ }
+ ype := &h.onodes[y].peLabels
+ if debugHVNVerbose && h.log != nil {
+ fmt.Fprintf(h.log, "\tedge from o%d = %s\n", y, ype)
+ }
+
+ if ype.IsEmpty() {
+ if debugHVNVerbose && h.log != nil {
+ fmt.Fprintf(h.log, "\tnode has no PE label\n")
+ }
+ }
+ assert(!ype.IsEmpty(), "incoming node has no PE label")
+
+ if ype.Has(0) {
+ // {0} represents a non-pointer.
+ assert(ype.Len() == 1, "PE set contains {0, ...}")
+ } else {
+ xpe.UnionWith(ype)
+ }
+ }
+
+ switch xpe.Len() {
+ case 0:
+ // SCC has no incoming non-zero PE labels: it is a non-pointer.
+ xpe.Insert(0)
+
+ case 1:
+ // already a singleton
+
+ default:
+ // SCC has multiple incoming non-zero PE labels.
+ // Find the canonical label representing this set.
+ // We use String() as a fingerprint consistent with Equals().
+ key := xpe.String()
+ label, ok := h.hvnLabel[key]
+ if !ok {
+ label = h.nextLabel()
+ if debugHVNVerbose && h.log != nil {
+ fmt.Fprintf(h.log, "\tcreate p%d: union %s\n", label, xpe.String())
+ }
+ h.hvnLabel[key] = label
+ }
+ xpe.Clear()
+ xpe.Insert(int(label))
+ }
+
+ if debugHVNVerbose && h.log != nil {
+ fmt.Fprintf(h.log, "\to%d has p%d\n", x, xpe.Min())
+ }
+}
+
+// coalesce combines two nodes in the offline constraint graph.
+// Precondition: x and y are canonical.
+func (h *hvn) coalesce(x, y onodeid) {
+ xo := h.onodes[x]
+ yo := h.onodes[y]
+
+ // x becomes y's canonical representative.
+ yo.rep = x
+
+ if debugHVNVerbose && h.log != nil {
+ fmt.Fprintf(h.log, "\tcoalesce o%d into o%d\n", y, x)
+ }
+
+ // x accumulates y's edges.
+ xo.edges.UnionWith(&yo.edges)
+ yo.edges.Clear()
+
+ // x accumulates y's implicit edges.
+ xo.implicit.UnionWith(&yo.implicit)
+ yo.implicit.Clear()
+
+ // x accumulates y's pointer-equivalence labels.
+ xo.peLabels.UnionWith(&yo.peLabels)
+ yo.peLabels.Clear()
+
+ // x accumulates y's indirect flag.
+ if yo.indirect {
+ xo.indirect = true
+ }
+}
+
+// simplify computes a degenerate renumbering of nodeids from the PE
+// labels assigned by the hvn, and uses it to simplify the main
+// constraint graph, eliminating non-pointer nodes and duplicate
+// constraints.
+//
+func (h *hvn) simplify() {
+ // canon maps each peLabel to its canonical main node.
+ canon := make([]nodeid, h.label)
+ for i := range canon {
+ canon[i] = nodeid(h.N) // indicates "unset"
+ }
+
+ // mapping maps each main node index to the index of the canonical node.
+ mapping := make([]nodeid, len(h.a.nodes))
+
+ for id := range h.a.nodes {
+ id := nodeid(id)
+ if id == 0 {
+ canon[0] = 0
+ mapping[0] = 0
+ continue
+ }
+ oid := h.find(onodeid(id))
+ peLabels := &h.onodes[oid].peLabels
+ assert(peLabels.Len() == 1, "PE class is not a singleton")
+ label := peLabel(peLabels.Min())
+
+ canonId := canon[label]
+ if canonId == nodeid(h.N) {
+ // id becomes the representative of the PE label.
+ canonId = id
+ canon[label] = canonId
+
+ if h.a.log != nil {
+ fmt.Fprintf(h.a.log, "\tpts(n%d) is canonical : \t(%s)\n",
+ id, h.a.nodes[id].typ)
+ }
+
+ } else {
+ // Link the solver states for the two nodes.
+ assert(h.a.nodes[canonId].solve != nil, "missing solver state")
+ h.a.nodes[id].solve = h.a.nodes[canonId].solve
+
+ if h.a.log != nil {
+ // TODO(adonovan): debug: reorganize the log so it prints
+ // one line:
+ // pe y = x1, ..., xn
+ // for each canonical y. Requires allocation.
+ fmt.Fprintf(h.a.log, "\tpts(n%d) = pts(n%d) : %s\n",
+ id, canonId, h.a.nodes[id].typ)
+ }
+ }
+
+ mapping[id] = canonId
+ }
+
+ // Renumber the constraints, eliminate duplicates, and eliminate
+ // any containing non-pointers (n0).
+ addrs := make(map[addrConstraint]bool)
+ copys := make(map[copyConstraint]bool)
+ loads := make(map[loadConstraint]bool)
+ stores := make(map[storeConstraint]bool)
+ offsetAddrs := make(map[offsetAddrConstraint]bool)
+ untags := make(map[untagConstraint]bool)
+ typeFilters := make(map[typeFilterConstraint]bool)
+ invokes := make(map[invokeConstraint]bool)
+
+ nbefore := len(h.a.constraints)
+ cc := h.a.constraints[:0] // in-situ compaction
+ for _, c := range h.a.constraints {
+ // Renumber.
+ switch c := c.(type) {
+ case *addrConstraint:
+ // Don't renumber c.src since it is the label of
+ // an addressable object and will appear in PT sets.
+ c.dst = mapping[c.dst]
+ default:
+ c.renumber(mapping)
+ }
+
+ if c.ptr() == 0 {
+ continue // skip: constraint attached to non-pointer
+ }
+
+ var dup bool
+ switch c := c.(type) {
+ case *addrConstraint:
+ _, dup = addrs[*c]
+ addrs[*c] = true
+
+ case *copyConstraint:
+ if c.src == c.dst {
+ continue // skip degenerate copies
+ }
+ if c.src == 0 {
+ continue // skip copy from non-pointer
+ }
+ _, dup = copys[*c]
+ copys[*c] = true
+
+ case *loadConstraint:
+ if c.src == 0 {
+ continue // skip load from non-pointer
+ }
+ _, dup = loads[*c]
+ loads[*c] = true
+
+ case *storeConstraint:
+ if c.src == 0 {
+ continue // skip store from non-pointer
+ }
+ _, dup = stores[*c]
+ stores[*c] = true
+
+ case *offsetAddrConstraint:
+ if c.src == 0 {
+ continue // skip offset from non-pointer
+ }
+ _, dup = offsetAddrs[*c]
+ offsetAddrs[*c] = true
+
+ case *untagConstraint:
+ if c.src == 0 {
+ continue // skip untag of non-pointer
+ }
+ _, dup = untags[*c]
+ untags[*c] = true
+
+ case *typeFilterConstraint:
+ if c.src == 0 {
+ continue // skip filter of non-pointer
+ }
+ _, dup = typeFilters[*c]
+ typeFilters[*c] = true
+
+ case *invokeConstraint:
+ if c.params == 0 {
+ panic("non-pointer invoke.params")
+ }
+ if c.iface == 0 {
+ continue // skip invoke on non-pointer
+ }
+ _, dup = invokes[*c]
+ invokes[*c] = true
+
+ default:
+ // We don't bother de-duping advanced constraints
+ // (e.g. reflection) since they are uncommon.
+
+ // Eliminate constraints containing non-pointer nodeids.
+ //
+ // We use reflection to find the fields to avoid
+ // adding yet another method to constraint.
+ //
+ // TODO(adonovan): experiment with a constraint
+ // method that returns a slice of pointers to
+ // nodeids fields to enable uniform iteration;
+ // the renumber() method could be removed and
+ // implemented using the new one.
+ //
+ // TODO(adonovan): opt: this is unsound since
+ // some constraints still have an effect if one
+ // of the operands is zero: rVCall, rVMapIndex,
+ // rvSetMapIndex. Handle them specially.
+ rtNodeid := reflect.TypeOf(nodeid(0))
+ x := reflect.ValueOf(c).Elem()
+ for i, nf := 0, x.NumField(); i < nf; i++ {
+ f := x.Field(i)
+ if f.Type() == rtNodeid {
+ if f.Uint() == 0 {
+ dup = true // skip it
+ break
+ }
+ }
+ }
+ }
+ if dup {
+ continue // skip duplicates
+ }
+
+ cc = append(cc, c)
+ }
+ h.a.constraints = cc
+
+ if h.log != nil {
+ fmt.Fprintf(h.log, "#constraints: was %d, now %d\n", nbefore, len(h.a.constraints))
+ }
+}
+
+// find returns the canonical onodeid for x.
+// (The onodes form a disjoint set forest.)
+func (h *hvn) find(x onodeid) onodeid {
+ // TODO(adonovan): opt: this is a CPU hotspot. Try "union by rank".
+ xo := h.onodes[x]
+ rep := xo.rep
+ if rep != x {
+ rep = h.find(rep) // simple path compression
+ xo.rep = rep
+ }
+ return rep
+}
+
+func (h *hvn) checkCanonical(x onodeid) {
+ if debugHVN {
+ assert(x == h.find(x), "not canonical")
+ }
+}
+
+func assert(p bool, msg string) {
+ if debugHVN && !p {
+ panic("assertion failed: " + msg)
+ }
+}
diff --git a/vendor/golang.org/x/tools/go/pointer/intrinsics.go b/vendor/golang.org/x/tools/go/pointer/intrinsics.go
new file mode 100644
index 0000000..251c0e2
--- /dev/null
+++ b/vendor/golang.org/x/tools/go/pointer/intrinsics.go
@@ -0,0 +1,380 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package pointer
+
+// This package defines the treatment of intrinsics, i.e. library
+// functions requiring special analytical treatment.
+//
+// Most of these are C or assembly functions, but even some Go
+// functions require may special treatment if the analysis completely
+// replaces the implementation of an API such as reflection.
+
+// TODO(adonovan): support a means of writing analytic summaries in
+// the target code, so that users can summarise the effects of their
+// own C functions using a snippet of Go.
+
+import (
+ "fmt"
+
+ "golang.org/x/tools/go/ssa"
+ "golang.org/x/tools/go/types"
+)
+
+// Instances of 'intrinsic' generate analysis constraints for calls to
+// intrinsic functions.
+// Implementations may exploit information from the calling site
+// via cgn.callersite; for shared contours this is nil.
+type intrinsic func(a *analysis, cgn *cgnode)
+
+// Initialized in explicit init() to defeat (spurious) initialization
+// cycle error.
+var intrinsicsByName = make(map[string]intrinsic)
+
+func init() {
+ // Key strings are from Function.String().
+ // That little dot ۰ is an Arabic zero numeral (U+06F0),
+ // categories [Nd].
+ for name, fn := range map[string]intrinsic{
+ // Other packages.
+ "bytes.Equal": ext۰NoEffect,
+ "bytes.IndexByte": ext۰NoEffect,
+ "crypto/aes.decryptBlockAsm": ext۰NoEffect,
+ "crypto/aes.encryptBlockAsm": ext۰NoEffect,
+ "crypto/aes.expandKeyAsm": ext۰NoEffect,
+ "crypto/aes.hasAsm": ext۰NoEffect,
+ "crypto/md5.block": ext۰NoEffect,
+ "crypto/rc4.xorKeyStream": ext۰NoEffect,
+ "crypto/sha1.block": ext۰NoEffect,
+ "crypto/sha256.block": ext۰NoEffect,
+ "hash/crc32.castagnoliSSE42": ext۰NoEffect,
+ "hash/crc32.haveSSE42": ext۰NoEffect,
+ "math.Abs": ext۰NoEffect,
+ "math.Acos": ext۰NoEffect,
+ "math.Asin": ext۰NoEffect,
+ "math.Atan": ext۰NoEffect,
+ "math.Atan2": ext۰NoEffect,
+ "math.Ceil": ext۰NoEffect,
+ "math.Cos": ext۰NoEffect,
+ "math.Dim": ext۰NoEffect,
+ "math.Exp": ext۰NoEffect,
+ "math.Exp2": ext۰NoEffect,
+ "math.Expm1": ext۰NoEffect,
+ "math.Float32bits": ext۰NoEffect,
+ "math.Float32frombits": ext۰NoEffect,
+ "math.Float64bits": ext۰NoEffect,
+ "math.Float64frombits": ext۰NoEffect,
+ "math.Floor": ext۰NoEffect,
+ "math.Frexp": ext۰NoEffect,
+ "math.Hypot": ext۰NoEffect,
+ "math.Ldexp": ext۰NoEffect,
+ "math.Log": ext۰NoEffect,
+ "math.Log10": ext۰NoEffect,
+ "math.Log1p": ext۰NoEffect,
+ "math.Log2": ext۰NoEffect,
+ "math.Max": ext۰NoEffect,
+ "math.Min": ext۰NoEffect,
+ "math.Mod": ext۰NoEffect,
+ "math.Modf": ext۰NoEffect,
+ "math.Remainder": ext۰NoEffect,
+ "math.Sin": ext۰NoEffect,
+ "math.Sincos": ext۰NoEffect,
+ "math.Sqrt": ext۰NoEffect,
+ "math.Tan": ext۰NoEffect,
+ "math.Trunc": ext۰NoEffect,
+ "math/big.addMulVVW": ext۰NoEffect,
+ "math/big.addVV": ext۰NoEffect,
+ "math/big.addVW": ext۰NoEffect,
+ "math/big.bitLen": ext۰NoEffect,
+ "math/big.divWVW": ext۰NoEffect,
+ "math/big.divWW": ext۰NoEffect,
+ "math/big.mulAddVWW": ext۰NoEffect,
+ "math/big.mulWW": ext۰NoEffect,
+ "math/big.shlVU": ext۰NoEffect,
+ "math/big.shrVU": ext۰NoEffect,
+ "math/big.subVV": ext۰NoEffect,
+ "math/big.subVW": ext۰NoEffect,
+ "net.runtime_Semacquire": ext۰NoEffect,
+ "net.runtime_Semrelease": ext۰NoEffect,
+ "net.runtime_pollClose": ext۰NoEffect,
+ "net.runtime_pollOpen": ext۰NoEffect,
+ "net.runtime_pollReset": ext۰NoEffect,
+ "net.runtime_pollServerInit": ext۰NoEffect,
+ "net.runtime_pollSetDeadline": ext۰NoEffect,
+ "net.runtime_pollUnblock": ext۰NoEffect,
+ "net.runtime_pollWait": ext۰NoEffect,
+ "net.runtime_pollWaitCanceled": ext۰NoEffect,
+ "os.epipecheck": ext۰NoEffect,
+ "runtime.BlockProfile": ext۰NoEffect,
+ "runtime.Breakpoint": ext۰NoEffect,
+ "runtime.CPUProfile": ext۰NoEffect, // good enough
+ "runtime.Caller": ext۰NoEffect,
+ "runtime.Callers": ext۰NoEffect, // good enough
+ "runtime.FuncForPC": ext۰NoEffect,
+ "runtime.GC": ext۰NoEffect,
+ "runtime.GOMAXPROCS": ext۰NoEffect,
+ "runtime.Goexit": ext۰NoEffect,
+ "runtime.GoroutineProfile": ext۰NoEffect,
+ "runtime.Gosched": ext۰NoEffect,
+ "runtime.MemProfile": ext۰NoEffect,
+ "runtime.NumCPU": ext۰NoEffect,
+ "runtime.NumGoroutine": ext۰NoEffect,
+ "runtime.ReadMemStats": ext۰NoEffect,
+ "runtime.SetBlockProfileRate": ext۰NoEffect,
+ "runtime.SetCPUProfileRate": ext۰NoEffect,
+ "runtime.SetFinalizer": ext۰runtime۰SetFinalizer,
+ "runtime.Stack": ext۰NoEffect,
+ "runtime.ThreadCreateProfile": ext۰NoEffect,
+ "runtime.cstringToGo": ext۰NoEffect,
+ "runtime.funcentry_go": ext۰NoEffect,
+ "runtime.funcline_go": ext۰NoEffect,
+ "runtime.funcname_go": ext۰NoEffect,
+ "runtime.getgoroot": ext۰NoEffect,
+ "runtime/pprof.runtime_cyclesPerSecond": ext۰NoEffect,
+ "strings.IndexByte": ext۰NoEffect,
+ "sync.runtime_Semacquire": ext۰NoEffect,
+ "sync.runtime_Semrelease": ext۰NoEffect,
+ "sync.runtime_Syncsemacquire": ext۰NoEffect,
+ "sync.runtime_Syncsemcheck": ext۰NoEffect,
+ "sync.runtime_Syncsemrelease": ext۰NoEffect,
+ "sync.runtime_procPin": ext۰NoEffect,
+ "sync.runtime_procUnpin": ext۰NoEffect,
+ "sync.runtime_registerPool": ext۰NoEffect,
+ "sync/atomic.AddInt32": ext۰NoEffect,
+ "sync/atomic.AddInt64": ext۰NoEffect,
+ "sync/atomic.AddUint32": ext۰NoEffect,
+ "sync/atomic.AddUint64": ext۰NoEffect,
+ "sync/atomic.AddUintptr": ext۰NoEffect,
+ "sync/atomic.CompareAndSwapInt32": ext۰NoEffect,
+ "sync/atomic.CompareAndSwapUint32": ext۰NoEffect,
+ "sync/atomic.CompareAndSwapUint64": ext۰NoEffect,
+ "sync/atomic.CompareAndSwapUintptr": ext۰NoEffect,
+ "sync/atomic.LoadInt32": ext۰NoEffect,
+ "sync/atomic.LoadInt64": ext۰NoEffect,
+ "sync/atomic.LoadPointer": ext۰NoEffect, // ignore unsafe.Pointers
+ "sync/atomic.LoadUint32": ext۰NoEffect,
+ "sync/atomic.LoadUint64": ext۰NoEffect,
+ "sync/atomic.LoadUintptr": ext۰NoEffect,
+ "sync/atomic.StoreInt32": ext۰NoEffect,
+ "sync/atomic.StorePointer": ext۰NoEffect, // ignore unsafe.Pointers
+ "sync/atomic.StoreUint32": ext۰NoEffect,
+ "sync/atomic.StoreUintptr": ext۰NoEffect,
+ "syscall.Close": ext۰NoEffect,
+ "syscall.Exit": ext۰NoEffect,
+ "syscall.Getpid": ext۰NoEffect,
+ "syscall.Getwd": ext۰NoEffect,
+ "syscall.Kill": ext۰NoEffect,
+ "syscall.RawSyscall": ext۰NoEffect,
+ "syscall.RawSyscall6": ext۰NoEffect,
+ "syscall.Syscall": ext۰NoEffect,
+ "syscall.Syscall6": ext۰NoEffect,
+ "syscall.runtime_AfterFork": ext۰NoEffect,
+ "syscall.runtime_BeforeFork": ext۰NoEffect,
+ "syscall.setenv_c": ext۰NoEffect,
+ "time.Sleep": ext۰NoEffect,
+ "time.now": ext۰NoEffect,
+ "time.startTimer": ext۰time۰startTimer,
+ "time.stopTimer": ext۰NoEffect,
+ } {
+ intrinsicsByName[name] = fn
+ }
+}
+
+// findIntrinsic returns the constraint generation function for an
+// intrinsic function fn, or nil if the function should be handled normally.
+//
+func (a *analysis) findIntrinsic(fn *ssa.Function) intrinsic {
+ // Consult the *Function-keyed cache.
+ // A cached nil indicates a normal non-intrinsic function.
+ impl, ok := a.intrinsics[fn]
+ if !ok {
+ impl = intrinsicsByName[fn.String()] // may be nil
+
+ if a.isReflect(fn) {
+ if !a.config.Reflection {
+ impl = ext۰NoEffect // reflection disabled
+ } else if impl == nil {
+ // Ensure all "reflect" code is treated intrinsically.
+ impl = ext۰NotYetImplemented
+ }
+ }
+
+ a.intrinsics[fn] = impl
+ }
+ return impl
+}
+
+// isReflect reports whether fn belongs to the "reflect" package.
+func (a *analysis) isReflect(fn *ssa.Function) bool {
+ if a.reflectValueObj == nil {
+ return false // "reflect" package not loaded
+ }
+ reflectPackage := a.reflectValueObj.Pkg()
+ if fn.Pkg != nil && fn.Pkg.Object == reflectPackage {
+ return true
+ }
+ // Synthetic wrappers have a nil Pkg, so they slip through the
+ // previous check. Check the receiver package.
+ // TODO(adonovan): should synthetic wrappers have a non-nil Pkg?
+ if recv := fn.Signature.Recv(); recv != nil {
+ if named, ok := deref(recv.Type()).(*types.Named); ok {
+ if named.Obj().Pkg() == reflectPackage {
+ return true // e.g. wrapper of (reflect.Value).f
+ }
+ }
+ }
+ return false
+}
+
+// A trivial intrinsic suitable for any function that does not:
+// 1) induce aliases between its arguments or any global variables;
+// 2) call any functions; or
+// 3) create any labels.
+//
+// Many intrinsics (such as CompareAndSwapInt32) have a fourth kind of
+// effect: loading or storing through a pointer. Though these could
+// be significant, we deliberately ignore them because they are
+// generally not worth the effort.
+//
+// We sometimes violate condition #3 if the function creates only
+// non-function labels, as the control-flow graph is still sound.
+//
+func ext۰NoEffect(a *analysis, cgn *cgnode) {}
+
+func ext۰NotYetImplemented(a *analysis, cgn *cgnode) {
+ fn := cgn.fn
+ a.warnf(fn.Pos(), "unsound: intrinsic treatment of %s not yet implemented", fn)
+}
+
+// ---------- func runtime.SetFinalizer(x, f interface{}) ----------
+
+// runtime.SetFinalizer(x, f)
+type runtimeSetFinalizerConstraint struct {
+ targets nodeid // (indirect)
+ f nodeid // (ptr)
+ x nodeid
+}
+
+func (c *runtimeSetFinalizerConstraint) ptr() nodeid { return c.f }
+func (c *runtimeSetFinalizerConstraint) presolve(h *hvn) {
+ h.markIndirect(onodeid(c.targets), "SetFinalizer.targets")
+}
+func (c *runtimeSetFinalizerConstraint) renumber(mapping []nodeid) {
+ c.targets = mapping[c.targets]
+ c.f = mapping[c.f]
+ c.x = mapping[c.x]
+}
+
+func (c *runtimeSetFinalizerConstraint) String() string {
+ return fmt.Sprintf("runtime.SetFinalizer(n%d, n%d)", c.x, c.f)
+}
+
+func (c *runtimeSetFinalizerConstraint) solve(a *analysis, delta *nodeset) {
+ for _, fObj := range delta.AppendTo(a.deltaSpace) {
+ tDyn, f, indirect := a.taggedValue(nodeid(fObj))
+ if indirect {
+ // TODO(adonovan): we'll need to implement this
+ // when we start creating indirect tagged objects.
+ panic("indirect tagged object")
+ }
+
+ tSig, ok := tDyn.Underlying().(*types.Signature)
+ if !ok {
+ continue // not a function
+ }
+ if tSig.Recv() != nil {
+ panic(tSig)
+ }
+ if tSig.Params().Len() != 1 {
+ continue // not a unary function
+ }
+
+ // Extract x to tmp.
+ tx := tSig.Params().At(0).Type()
+ tmp := a.addNodes(tx, "SetFinalizer.tmp")
+ a.typeAssert(tx, tmp, c.x, false)
+
+ // Call f(tmp).
+ a.store(f, tmp, 1, a.sizeof(tx))
+
+ // Add dynamic call target.
+ if a.onlineCopy(c.targets, f) {
+ a.addWork(c.targets)
+ }
+ }
+}
+
+func ext۰runtime۰SetFinalizer(a *analysis, cgn *cgnode) {
+ // This is the shared contour, used for dynamic calls.
+ targets := a.addOneNode(tInvalid, "SetFinalizer.targets", nil)
+ cgn.sites = append(cgn.sites, &callsite{targets: targets})
+ params := a.funcParams(cgn.obj)
+ a.addConstraint(&runtimeSetFinalizerConstraint{
+ targets: targets,
+ x: params,
+ f: params + 1,
+ })
+}
+
+// ---------- func time.startTimer(t *runtimeTimer) ----------
+
+// time.StartTimer(t)
+type timeStartTimerConstraint struct {
+ targets nodeid // (indirect)
+ t nodeid // (ptr)
+}
+
+func (c *timeStartTimerConstraint) ptr() nodeid { return c.t }
+func (c *timeStartTimerConstraint) presolve(h *hvn) {
+ h.markIndirect(onodeid(c.targets), "StartTimer.targets")
+}
+func (c *timeStartTimerConstraint) renumber(mapping []nodeid) {
+ c.targets = mapping[c.targets]
+ c.t = mapping[c.t]
+}
+
+func (c *timeStartTimerConstraint) String() string {
+ return fmt.Sprintf("time.startTimer(n%d)", c.t)
+}
+
+func (c *timeStartTimerConstraint) solve(a *analysis, delta *nodeset) {
+ for _, tObj := range delta.AppendTo(a.deltaSpace) {
+ t := nodeid(tObj)
+
+ // We model startTimer as if it was defined thus:
+ // func startTimer(t *runtimeTimer) { t.f(t.arg) }
+
+ // We hard-code the field offsets of time.runtimeTimer:
+ // type runtimeTimer struct {
+ // 0 __identity__
+ // 1 i int32
+ // 2 when int64
+ // 3 period int64
+ // 4 f func(int64, interface{})
+ // 5 arg interface{}
+ // }
+ f := t + 4
+ arg := t + 5
+
+ // store t.arg to t.f.params[0]
+ // (offset 1 => skip identity)
+ a.store(f, arg, 1, 1)
+
+ // Add dynamic call target.
+ if a.onlineCopy(c.targets, f) {
+ a.addWork(c.targets)
+ }
+ }
+}
+
+func ext۰time۰startTimer(a *analysis, cgn *cgnode) {
+ // This is the shared contour, used for dynamic calls.
+ targets := a.addOneNode(tInvalid, "startTimer.targets", nil)
+ cgn.sites = append(cgn.sites, &callsite{targets: targets})
+ params := a.funcParams(cgn.obj)
+ a.addConstraint(&timeStartTimerConstraint{
+ targets: targets,
+ t: params,
+ })
+}
diff --git a/vendor/golang.org/x/tools/go/pointer/labels.go b/vendor/golang.org/x/tools/go/pointer/labels.go
new file mode 100644
index 0000000..cf6ef20
--- /dev/null
+++ b/vendor/golang.org/x/tools/go/pointer/labels.go
@@ -0,0 +1,152 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package pointer
+
+import (
+ "fmt"
+ "go/token"
+ "strings"
+
+ "golang.org/x/tools/go/ssa"
+ "golang.org/x/tools/go/types"
+)
+
+// A Label is an entity that may be pointed to by a pointer, map,
+// channel, 'func', slice or interface.
+//
+// Labels include:
+// - functions
+// - globals
+// - tagged objects, representing interfaces and reflect.Values
+// - arrays created by conversions (e.g. []byte("foo"), []byte(s))
+// - stack- and heap-allocated variables (including composite literals)
+// - channels, maps and arrays created by make()
+// - intrinsic or reflective operations that allocate (e.g. append, reflect.New)
+// - intrinsic objects, e.g. the initial array behind os.Args.
+// - and their subelements, e.g. "alloc.y[*].z"
+//
+// Labels are so varied that they defy good generalizations;
+// some have no value, no callgraph node, or no position.
+// Many objects have types that are inexpressible in Go:
+// maps, channels, functions, tagged objects.
+//
+// At most one of Value() or ReflectType() may return non-nil.
+//
+type Label struct {
+ obj *object // the addressable memory location containing this label
+ subelement *fieldInfo // subelement path within obj, e.g. ".a.b[*].c"
+}
+
+// Value returns the ssa.Value that allocated this label's object, if any.
+func (l Label) Value() ssa.Value {
+ val, _ := l.obj.data.(ssa.Value)
+ return val
+}
+
+// ReflectType returns the type represented by this label if it is an
+// reflect.rtype instance object or *reflect.rtype-tagged object.
+//
+func (l Label) ReflectType() types.Type {
+ rtype, _ := l.obj.data.(types.Type)
+ return rtype
+}
+
+// Path returns the path to the subelement of the object containing
+// this label. For example, ".x[*].y".
+//
+func (l Label) Path() string {
+ return l.subelement.path()
+}
+
+// Pos returns the position of this label, if known, zero otherwise.
+func (l Label) Pos() token.Pos {
+ switch data := l.obj.data.(type) {
+ case ssa.Value:
+ return data.Pos()
+ case types.Type:
+ if nt, ok := deref(data).(*types.Named); ok {
+ return nt.Obj().Pos()
+ }
+ }
+ if cgn := l.obj.cgn; cgn != nil {
+ return cgn.fn.Pos()
+ }
+ return token.NoPos
+}
+
+// String returns the printed form of this label.
+//
+// Examples: Object type:
+// x (a variable)
+// (sync.Mutex).Lock (a function)
+// convert (array created by conversion)
+// makemap (map allocated via make)
+// makechan (channel allocated via make)
+// makeinterface (tagged object allocated by makeinterface)
+// (allocation in instrinsic)
+// sync.Mutex (a reflect.rtype instance)
+// (an intrinsic object)
+//
+// Labels within compound objects have subelement paths:
+// x.y[*].z (a struct variable, x)
+// append.y[*].z (array allocated by append)
+// makeslice.y[*].z (array allocated via make)
+//
+// TODO(adonovan): expose func LabelString(*types.Package, Label).
+//
+func (l Label) String() string {
+ var s string
+ switch v := l.obj.data.(type) {
+ case types.Type:
+ return v.String()
+
+ case string:
+ s = v // an intrinsic object (e.g. os.Args[*])
+
+ case nil:
+ if l.obj.cgn != nil {
+ // allocation by intrinsic or reflective operation
+ s = fmt.Sprintf("", l.obj.cgn.fn)
+ } else {
+ s = "" // should be unreachable
+ }
+
+ case *ssa.Function:
+ s = v.String()
+
+ case *ssa.Global:
+ s = v.String()
+
+ case *ssa.Const:
+ s = v.Name()
+
+ case *ssa.Alloc:
+ s = v.Comment
+ if s == "" {
+ s = "alloc"
+ }
+
+ case *ssa.Call:
+ // Currently only calls to append can allocate objects.
+ if v.Call.Value.(*ssa.Builtin).Object().Name() != "append" {
+ panic("unhandled *ssa.Call label: " + v.Name())
+ }
+ s = "append"
+
+ case *ssa.MakeMap, *ssa.MakeChan, *ssa.MakeSlice, *ssa.Convert:
+ s = strings.ToLower(strings.TrimPrefix(fmt.Sprintf("%T", v), "*ssa."))
+
+ case *ssa.MakeInterface:
+ // MakeInterface is usually implicit in Go source (so
+ // Pos()==0), and tagged objects may be allocated
+ // synthetically (so no *MakeInterface data).
+ s = "makeinterface:" + v.X.Type().String()
+
+ default:
+ panic(fmt.Sprintf("unhandled object data type: %T", v))
+ }
+
+ return s + l.subelement.path()
+}
diff --git a/vendor/golang.org/x/tools/go/pointer/opt.go b/vendor/golang.org/x/tools/go/pointer/opt.go
new file mode 100644
index 0000000..2620cc0
--- /dev/null
+++ b/vendor/golang.org/x/tools/go/pointer/opt.go
@@ -0,0 +1,125 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package pointer
+
+// This file implements renumbering, a pre-solver optimization to
+// improve the efficiency of the solver's points-to set representation.
+//
+// TODO(adonovan): rename file "renumber.go"
+
+import "fmt"
+
+// renumber permutes a.nodes so that all nodes within an addressable
+// object appear before all non-addressable nodes, maintaining the
+// order of nodes within the same object (as required by offsetAddr).
+//
+// renumber must update every nodeid in the analysis (constraints,
+// Pointers, callgraph, etc) to reflect the new ordering.
+//
+// This is an optimisation to increase the locality and efficiency of
+// sparse representations of points-to sets. (Typically only about
+// 20% of nodes are within an object.)
+//
+// NB: nodes added during solving (e.g. for reflection, SetFinalizer)
+// will be appended to the end.
+//
+// Renumbering makes the PTA log inscrutable. To aid debugging, later
+// phases (e.g. HVN) must not rely on it having occurred.
+//
+func (a *analysis) renumber() {
+ if a.log != nil {
+ fmt.Fprintf(a.log, "\n\n==== Renumbering\n\n")
+ }
+
+ N := nodeid(len(a.nodes))
+ newNodes := make([]*node, N, N)
+ renumbering := make([]nodeid, N, N) // maps old to new
+
+ var i, j nodeid
+
+ // The zero node is special.
+ newNodes[j] = a.nodes[i]
+ renumbering[i] = j
+ i++
+ j++
+
+ // Pass 1: object nodes.
+ for i < N {
+ obj := a.nodes[i].obj
+ if obj == nil {
+ i++
+ continue
+ }
+
+ end := i + nodeid(obj.size)
+ for i < end {
+ newNodes[j] = a.nodes[i]
+ renumbering[i] = j
+ i++
+ j++
+ }
+ }
+ nobj := j
+
+ // Pass 2: non-object nodes.
+ for i = 1; i < N; {
+ obj := a.nodes[i].obj
+ if obj != nil {
+ i += nodeid(obj.size)
+ continue
+ }
+
+ newNodes[j] = a.nodes[i]
+ renumbering[i] = j
+ i++
+ j++
+ }
+
+ if j != N {
+ panic(fmt.Sprintf("internal error: j=%d, N=%d", j, N))
+ }
+
+ // Log the remapping table.
+ if a.log != nil {
+ fmt.Fprintf(a.log, "Renumbering nodes to improve density:\n")
+ fmt.Fprintf(a.log, "(%d object nodes of %d total)\n", nobj, N)
+ for old, new := range renumbering {
+ fmt.Fprintf(a.log, "\tn%d -> n%d\n", old, new)
+ }
+ }
+
+ // Now renumber all existing nodeids to use the new node permutation.
+ // It is critical that all reachable nodeids are accounted for!
+
+ // Renumber nodeids in queried Pointers.
+ for v, ptr := range a.result.Queries {
+ ptr.n = renumbering[ptr.n]
+ a.result.Queries[v] = ptr
+ }
+ for v, ptr := range a.result.IndirectQueries {
+ ptr.n = renumbering[ptr.n]
+ a.result.IndirectQueries[v] = ptr
+ }
+
+ // Renumber nodeids in global objects.
+ for v, id := range a.globalobj {
+ a.globalobj[v] = renumbering[id]
+ }
+
+ // Renumber nodeids in constraints.
+ for _, c := range a.constraints {
+ c.renumber(renumbering)
+ }
+
+ // Renumber nodeids in the call graph.
+ for _, cgn := range a.cgnodes {
+ cgn.obj = renumbering[cgn.obj]
+ for _, site := range cgn.sites {
+ site.targets = renumbering[site.targets]
+ }
+ }
+
+ a.nodes = newNodes
+}
diff --git a/vendor/golang.org/x/tools/go/pointer/print.go b/vendor/golang.org/x/tools/go/pointer/print.go
new file mode 100644
index 0000000..4f2f4c7
--- /dev/null
+++ b/vendor/golang.org/x/tools/go/pointer/print.go
@@ -0,0 +1,43 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package pointer
+
+import "fmt"
+
+func (c *addrConstraint) String() string {
+ return fmt.Sprintf("addr n%d <- {&n%d}", c.dst, c.src)
+}
+
+func (c *copyConstraint) String() string {
+ return fmt.Sprintf("copy n%d <- n%d", c.dst, c.src)
+}
+
+func (c *loadConstraint) String() string {
+ return fmt.Sprintf("load n%d <- n%d[%d]", c.dst, c.src, c.offset)
+}
+
+func (c *storeConstraint) String() string {
+ return fmt.Sprintf("store n%d[%d] <- n%d", c.dst, c.offset, c.src)
+}
+
+func (c *offsetAddrConstraint) String() string {
+ return fmt.Sprintf("offsetAddr n%d <- n%d.#%d", c.dst, c.src, c.offset)
+}
+
+func (c *typeFilterConstraint) String() string {
+ return fmt.Sprintf("typeFilter n%d <- n%d.(%s)", c.dst, c.src, c.typ)
+}
+
+func (c *untagConstraint) String() string {
+ return fmt.Sprintf("untag n%d <- n%d.(%s)", c.dst, c.src, c.typ)
+}
+
+func (c *invokeConstraint) String() string {
+ return fmt.Sprintf("invoke n%d.%s(n%d ...)", c.iface, c.method.Name(), c.params)
+}
+
+func (n nodeid) String() string {
+ return fmt.Sprintf("n%d", n)
+}
diff --git a/vendor/golang.org/x/tools/go/pointer/reflect.go b/vendor/golang.org/x/tools/go/pointer/reflect.go
new file mode 100644
index 0000000..466995c
--- /dev/null
+++ b/vendor/golang.org/x/tools/go/pointer/reflect.go
@@ -0,0 +1,1971 @@
+package pointer
+
+// This file implements the generation and resolution rules for
+// constraints arising from the use of reflection in the target
+// program. See doc.go for explanation of the representation.
+//
+// For consistency, the names of all parameters match those of the
+// actual functions in the "reflect" package.
+//
+// To avoid proliferation of equivalent labels, intrinsics should
+// memoize as much as possible, like TypeOf and Zero do for their
+// tagged objects.
+//
+// TODO(adonovan): this file is rather subtle. Explain how we derive
+// the implementation of each reflect operator from its spec,
+// including the subtleties of reflect.flag{Addr,RO,Indir}.
+// [Hint: our implementation is as if reflect.flagIndir was always
+// true, i.e. reflect.Values are pointers to tagged objects, there is
+// no inline allocation optimization; and indirect tagged objects (not
+// yet implemented) correspond to reflect.Values with
+// reflect.flagAddr.]
+// A picture would help too.
+//
+// TODO(adonovan): try factoring up the common parts of the majority of
+// these constraints that are single input, single output.
+
+import (
+ "fmt"
+ "reflect"
+
+ "golang.org/x/tools/go/exact"
+ "golang.org/x/tools/go/ssa"
+ "golang.org/x/tools/go/types"
+)
+
+func init() {
+ for name, fn := range map[string]intrinsic{
+ // reflect.Value methods.
+ "(reflect.Value).Addr": ext۰reflect۰Value۰Addr,
+ "(reflect.Value).Bool": ext۰NoEffect,
+ "(reflect.Value).Bytes": ext۰reflect۰Value۰Bytes,
+ "(reflect.Value).Call": ext۰reflect۰Value۰Call,
+ "(reflect.Value).CallSlice": ext۰reflect۰Value۰CallSlice,
+ "(reflect.Value).CanAddr": ext۰NoEffect,
+ "(reflect.Value).CanInterface": ext۰NoEffect,
+ "(reflect.Value).CanSet": ext۰NoEffect,
+ "(reflect.Value).Cap": ext۰NoEffect,
+ "(reflect.Value).Close": ext۰NoEffect,
+ "(reflect.Value).Complex": ext۰NoEffect,
+ "(reflect.Value).Convert": ext۰reflect۰Value۰Convert,
+ "(reflect.Value).Elem": ext۰reflect۰Value۰Elem,
+ "(reflect.Value).Field": ext۰reflect۰Value۰Field,
+ "(reflect.Value).FieldByIndex": ext۰reflect۰Value۰FieldByIndex,
+ "(reflect.Value).FieldByName": ext۰reflect۰Value۰FieldByName,
+ "(reflect.Value).FieldByNameFunc": ext۰reflect۰Value۰FieldByNameFunc,
+ "(reflect.Value).Float": ext۰NoEffect,
+ "(reflect.Value).Index": ext۰reflect۰Value۰Index,
+ "(reflect.Value).Int": ext۰NoEffect,
+ "(reflect.Value).Interface": ext۰reflect۰Value۰Interface,
+ "(reflect.Value).InterfaceData": ext۰NoEffect,
+ "(reflect.Value).IsNil": ext۰NoEffect,
+ "(reflect.Value).IsValid": ext۰NoEffect,
+ "(reflect.Value).Kind": ext۰NoEffect,
+ "(reflect.Value).Len": ext۰NoEffect,
+ "(reflect.Value).MapIndex": ext۰reflect۰Value۰MapIndex,
+ "(reflect.Value).MapKeys": ext۰reflect۰Value۰MapKeys,
+ "(reflect.Value).Method": ext۰reflect۰Value۰Method,
+ "(reflect.Value).MethodByName": ext۰reflect۰Value۰MethodByName,
+ "(reflect.Value).NumField": ext۰NoEffect,
+ "(reflect.Value).NumMethod": ext۰NoEffect,
+ "(reflect.Value).OverflowComplex": ext۰NoEffect,
+ "(reflect.Value).OverflowFloat": ext۰NoEffect,
+ "(reflect.Value).OverflowInt": ext۰NoEffect,
+ "(reflect.Value).OverflowUint": ext۰NoEffect,
+ "(reflect.Value).Pointer": ext۰NoEffect,
+ "(reflect.Value).Recv": ext۰reflect۰Value۰Recv,
+ "(reflect.Value).Send": ext۰reflect۰Value۰Send,
+ "(reflect.Value).Set": ext۰reflect۰Value۰Set,
+ "(reflect.Value).SetBool": ext۰NoEffect,
+ "(reflect.Value).SetBytes": ext۰reflect۰Value۰SetBytes,
+ "(reflect.Value).SetComplex": ext۰NoEffect,
+ "(reflect.Value).SetFloat": ext۰NoEffect,
+ "(reflect.Value).SetInt": ext۰NoEffect,
+ "(reflect.Value).SetLen": ext۰NoEffect,
+ "(reflect.Value).SetMapIndex": ext۰reflect۰Value۰SetMapIndex,
+ "(reflect.Value).SetPointer": ext۰reflect۰Value۰SetPointer,
+ "(reflect.Value).SetString": ext۰NoEffect,
+ "(reflect.Value).SetUint": ext۰NoEffect,
+ "(reflect.Value).Slice": ext۰reflect۰Value۰Slice,
+ "(reflect.Value).String": ext۰NoEffect,
+ "(reflect.Value).TryRecv": ext۰reflect۰Value۰Recv,
+ "(reflect.Value).TrySend": ext۰reflect۰Value۰Send,
+ "(reflect.Value).Type": ext۰NoEffect,
+ "(reflect.Value).Uint": ext۰NoEffect,
+ "(reflect.Value).UnsafeAddr": ext۰NoEffect,
+
+ // Standalone reflect.* functions.
+ "reflect.Append": ext۰reflect۰Append,
+ "reflect.AppendSlice": ext۰reflect۰AppendSlice,
+ "reflect.Copy": ext۰reflect۰Copy,
+ "reflect.ChanOf": ext۰reflect۰ChanOf,
+ "reflect.DeepEqual": ext۰NoEffect,
+ "reflect.Indirect": ext۰reflect۰Indirect,
+ "reflect.MakeChan": ext۰reflect۰MakeChan,
+ "reflect.MakeFunc": ext۰reflect۰MakeFunc,
+ "reflect.MakeMap": ext۰reflect۰MakeMap,
+ "reflect.MakeSlice": ext۰reflect۰MakeSlice,
+ "reflect.MapOf": ext۰reflect۰MapOf,
+ "reflect.New": ext۰reflect۰New,
+ "reflect.NewAt": ext۰reflect۰NewAt,
+ "reflect.PtrTo": ext۰reflect۰PtrTo,
+ "reflect.Select": ext۰reflect۰Select,
+ "reflect.SliceOf": ext۰reflect۰SliceOf,
+ "reflect.TypeOf": ext۰reflect۰TypeOf,
+ "reflect.ValueOf": ext۰reflect۰ValueOf,
+ "reflect.Zero": ext۰reflect۰Zero,
+ "reflect.init": ext۰NoEffect,
+
+ // *reflect.rtype methods
+ "(*reflect.rtype).Align": ext۰NoEffect,
+ "(*reflect.rtype).AssignableTo": ext۰NoEffect,
+ "(*reflect.rtype).Bits": ext۰NoEffect,
+ "(*reflect.rtype).ChanDir": ext۰NoEffect,
+ "(*reflect.rtype).ConvertibleTo": ext۰NoEffect,
+ "(*reflect.rtype).Elem": ext۰reflect۰rtype۰Elem,
+ "(*reflect.rtype).Field": ext۰reflect۰rtype۰Field,
+ "(*reflect.rtype).FieldAlign": ext۰NoEffect,
+ "(*reflect.rtype).FieldByIndex": ext۰reflect۰rtype۰FieldByIndex,
+ "(*reflect.rtype).FieldByName": ext۰reflect۰rtype۰FieldByName,
+ "(*reflect.rtype).FieldByNameFunc": ext۰reflect۰rtype۰FieldByNameFunc,
+ "(*reflect.rtype).Implements": ext۰NoEffect,
+ "(*reflect.rtype).In": ext۰reflect۰rtype۰In,
+ "(*reflect.rtype).IsVariadic": ext۰NoEffect,
+ "(*reflect.rtype).Key": ext۰reflect۰rtype۰Key,
+ "(*reflect.rtype).Kind": ext۰NoEffect,
+ "(*reflect.rtype).Len": ext۰NoEffect,
+ "(*reflect.rtype).Method": ext۰reflect۰rtype۰Method,
+ "(*reflect.rtype).MethodByName": ext۰reflect۰rtype۰MethodByName,
+ "(*reflect.rtype).Name": ext۰NoEffect,
+ "(*reflect.rtype).NumField": ext۰NoEffect,
+ "(*reflect.rtype).NumIn": ext۰NoEffect,
+ "(*reflect.rtype).NumMethod": ext۰NoEffect,
+ "(*reflect.rtype).NumOut": ext۰NoEffect,
+ "(*reflect.rtype).Out": ext۰reflect۰rtype۰Out,
+ "(*reflect.rtype).PkgPath": ext۰NoEffect,
+ "(*reflect.rtype).Size": ext۰NoEffect,
+ "(*reflect.rtype).String": ext۰NoEffect,
+ } {
+ intrinsicsByName[name] = fn
+ }
+}
+
+// -------------------- (reflect.Value) --------------------
+
+func ext۰reflect۰Value۰Addr(a *analysis, cgn *cgnode) {} // TODO(adonovan)
+
+// ---------- func (Value).Bytes() Value ----------
+
+// result = v.Bytes()
+type rVBytesConstraint struct {
+ v nodeid // (ptr)
+ result nodeid // (indirect)
+}
+
+func (c *rVBytesConstraint) ptr() nodeid { return c.v }
+func (c *rVBytesConstraint) presolve(h *hvn) {
+ h.markIndirect(onodeid(c.result), "rVBytes.result")
+}
+func (c *rVBytesConstraint) renumber(mapping []nodeid) {
+ c.v = mapping[c.v]
+ c.result = mapping[c.result]
+}
+
+func (c *rVBytesConstraint) String() string {
+ return fmt.Sprintf("n%d = reflect n%d.Bytes()", c.result, c.v)
+}
+
+func (c *rVBytesConstraint) solve(a *analysis, delta *nodeset) {
+ changed := false
+ for _, x := range delta.AppendTo(a.deltaSpace) {
+ vObj := nodeid(x)
+ tDyn, slice, indirect := a.taggedValue(vObj)
+ if indirect {
+ // TODO(adonovan): we'll need to implement this
+ // when we start creating indirect tagged objects.
+ panic("indirect tagged object")
+ }
+
+ tSlice, ok := tDyn.Underlying().(*types.Slice)
+ if ok && types.Identical(tSlice.Elem(), types.Typ[types.Uint8]) {
+ if a.onlineCopy(c.result, slice) {
+ changed = true
+ }
+ }
+ }
+ if changed {
+ a.addWork(c.result)
+ }
+}
+
+func ext۰reflect۰Value۰Bytes(a *analysis, cgn *cgnode) {
+ a.addConstraint(&rVBytesConstraint{
+ v: a.funcParams(cgn.obj),
+ result: a.funcResults(cgn.obj),
+ })
+}
+
+// ---------- func (Value).Call(in []Value) []Value ----------
+
+// result = v.Call(in)
+type rVCallConstraint struct {
+ cgn *cgnode
+ targets nodeid // (indirect)
+ v nodeid // (ptr)
+ arg nodeid // = in[*]
+ result nodeid // (indirect)
+ dotdotdot bool // interpret last arg as a "..." slice
+}
+
+func (c *rVCallConstraint) ptr() nodeid { return c.v }
+func (c *rVCallConstraint) presolve(h *hvn) {
+ h.markIndirect(onodeid(c.targets), "rVCall.targets")
+ h.markIndirect(onodeid(c.result), "rVCall.result")
+}
+func (c *rVCallConstraint) renumber(mapping []nodeid) {
+ c.targets = mapping[c.targets]
+ c.v = mapping[c.v]
+ c.arg = mapping[c.arg]
+ c.result = mapping[c.result]
+}
+
+func (c *rVCallConstraint) String() string {
+ return fmt.Sprintf("n%d = reflect n%d.Call(n%d)", c.result, c.v, c.arg)
+}
+
+func (c *rVCallConstraint) solve(a *analysis, delta *nodeset) {
+ if c.targets == 0 {
+ panic("no targets")
+ }
+
+ changed := false
+ for _, x := range delta.AppendTo(a.deltaSpace) {
+ vObj := nodeid(x)
+ tDyn, fn, indirect := a.taggedValue(vObj)
+ if indirect {
+ // TODO(adonovan): we'll need to implement this
+ // when we start creating indirect tagged objects.
+ panic("indirect tagged object")
+ }
+
+ tSig, ok := tDyn.Underlying().(*types.Signature)
+ if !ok {
+ continue // not a function
+ }
+ if tSig.Recv() != nil {
+ panic(tSig) // TODO(adonovan): rethink when we implement Method()
+ }
+
+ // Add dynamic call target.
+ if a.onlineCopy(c.targets, fn) {
+ a.addWork(c.targets)
+ // TODO(adonovan): is 'else continue' a sound optimisation here?
+ }
+
+ // Allocate a P/R block.
+ tParams := tSig.Params()
+ tResults := tSig.Results()
+ params := a.addNodes(tParams, "rVCall.params")
+ results := a.addNodes(tResults, "rVCall.results")
+
+ // Make a dynamic call to 'fn'.
+ a.store(fn, params, 1, a.sizeof(tParams))
+ a.load(results, fn, 1+a.sizeof(tParams), a.sizeof(tResults))
+
+ // Populate P by type-asserting each actual arg (all merged in c.arg).
+ for i, n := 0, tParams.Len(); i < n; i++ {
+ T := tParams.At(i).Type()
+ a.typeAssert(T, params, c.arg, false)
+ params += nodeid(a.sizeof(T))
+ }
+
+ // Use R by tagging and copying each actual result to c.result.
+ for i, n := 0, tResults.Len(); i < n; i++ {
+ T := tResults.At(i).Type()
+ // Convert from an arbitrary type to a reflect.Value
+ // (like MakeInterface followed by reflect.ValueOf).
+ if isInterface(T) {
+ // (don't tag)
+ if a.onlineCopy(c.result, results) {
+ changed = true
+ }
+ } else {
+ obj := a.makeTagged(T, c.cgn, nil)
+ a.onlineCopyN(obj+1, results, a.sizeof(T))
+ if a.addLabel(c.result, obj) { // (true)
+ changed = true
+ }
+ }
+ results += nodeid(a.sizeof(T))
+ }
+ }
+ if changed {
+ a.addWork(c.result)
+ }
+}
+
+// Common code for direct (inlined) and indirect calls to (reflect.Value).Call.
+func reflectCallImpl(a *analysis, cgn *cgnode, site *callsite, recv, arg nodeid, dotdotdot bool) nodeid {
+ // Allocate []reflect.Value array for the result.
+ ret := a.nextNode()
+ a.addNodes(types.NewArray(a.reflectValueObj.Type(), 1), "rVCall.ret")
+ a.endObject(ret, cgn, nil)
+
+ // pts(targets) will be the set of possible call targets.
+ site.targets = a.addOneNode(tInvalid, "rvCall.targets", nil)
+
+ // All arguments are merged since they arrive in a slice.
+ argelts := a.addOneNode(a.reflectValueObj.Type(), "rVCall.args", nil)
+ a.load(argelts, arg, 1, 1) // slice elements
+
+ a.addConstraint(&rVCallConstraint{
+ cgn: cgn,
+ targets: site.targets,
+ v: recv,
+ arg: argelts,
+ result: ret + 1, // results go into elements of ret
+ dotdotdot: dotdotdot,
+ })
+ return ret
+}
+
+func reflectCall(a *analysis, cgn *cgnode, dotdotdot bool) {
+ // This is the shared contour implementation of (reflect.Value).Call
+ // and CallSlice, as used by indirect calls (rare).
+ // Direct calls are inlined in gen.go, eliding the
+ // intermediate cgnode for Call.
+ site := new(callsite)
+ cgn.sites = append(cgn.sites, site)
+ recv := a.funcParams(cgn.obj)
+ arg := recv + 1
+ ret := reflectCallImpl(a, cgn, site, recv, arg, dotdotdot)
+ a.addressOf(cgn.fn.Signature.Results().At(0).Type(), a.funcResults(cgn.obj), ret)
+}
+
+func ext۰reflect۰Value۰Call(a *analysis, cgn *cgnode) {
+ reflectCall(a, cgn, false)
+}
+
+func ext۰reflect۰Value۰CallSlice(a *analysis, cgn *cgnode) {
+ // TODO(adonovan): implement. Also, inline direct calls in gen.go too.
+ if false {
+ reflectCall(a, cgn, true)
+ }
+}
+
+func ext۰reflect۰Value۰Convert(a *analysis, cgn *cgnode) {} // TODO(adonovan)
+
+// ---------- func (Value).Elem() Value ----------
+
+// result = v.Elem()
+type rVElemConstraint struct {
+ cgn *cgnode
+ v nodeid // (ptr)
+ result nodeid // (indirect)
+}
+
+func (c *rVElemConstraint) ptr() nodeid { return c.v }
+func (c *rVElemConstraint) presolve(h *hvn) {
+ h.markIndirect(onodeid(c.result), "rVElem.result")
+}
+func (c *rVElemConstraint) renumber(mapping []nodeid) {
+ c.v = mapping[c.v]
+ c.result = mapping[c.result]
+}
+
+func (c *rVElemConstraint) String() string {
+ return fmt.Sprintf("n%d = reflect n%d.Elem()", c.result, c.v)
+}
+
+func (c *rVElemConstraint) solve(a *analysis, delta *nodeset) {
+ changed := false
+ for _, x := range delta.AppendTo(a.deltaSpace) {
+ vObj := nodeid(x)
+ tDyn, payload, indirect := a.taggedValue(vObj)
+ if indirect {
+ // TODO(adonovan): we'll need to implement this
+ // when we start creating indirect tagged objects.
+ panic("indirect tagged object")
+ }
+
+ switch t := tDyn.Underlying().(type) {
+ case *types.Interface:
+ if a.onlineCopy(c.result, payload) {
+ changed = true
+ }
+
+ case *types.Pointer:
+ obj := a.makeTagged(t.Elem(), c.cgn, nil)
+ a.load(obj+1, payload, 0, a.sizeof(t.Elem()))
+ if a.addLabel(c.result, obj) {
+ changed = true
+ }
+ }
+ }
+ if changed {
+ a.addWork(c.result)
+ }
+}
+
+func ext۰reflect۰Value۰Elem(a *analysis, cgn *cgnode) {
+ a.addConstraint(&rVElemConstraint{
+ cgn: cgn,
+ v: a.funcParams(cgn.obj),
+ result: a.funcResults(cgn.obj),
+ })
+}
+
+func ext۰reflect۰Value۰Field(a *analysis, cgn *cgnode) {} // TODO(adonovan)
+func ext۰reflect۰Value۰FieldByIndex(a *analysis, cgn *cgnode) {} // TODO(adonovan)
+func ext۰reflect۰Value۰FieldByName(a *analysis, cgn *cgnode) {} // TODO(adonovan)
+func ext۰reflect۰Value۰FieldByNameFunc(a *analysis, cgn *cgnode) {} // TODO(adonovan)
+
+// ---------- func (Value).Index() Value ----------
+
+// result = v.Index()
+type rVIndexConstraint struct {
+ cgn *cgnode
+ v nodeid // (ptr)
+ result nodeid // (indirect)
+}
+
+func (c *rVIndexConstraint) ptr() nodeid { return c.v }
+func (c *rVIndexConstraint) presolve(h *hvn) {
+ h.markIndirect(onodeid(c.result), "rVIndex.result")
+}
+func (c *rVIndexConstraint) renumber(mapping []nodeid) {
+ c.v = mapping[c.v]
+ c.result = mapping[c.result]
+}
+
+func (c *rVIndexConstraint) String() string {
+ return fmt.Sprintf("n%d = reflect n%d.Index()", c.result, c.v)
+}
+
+func (c *rVIndexConstraint) solve(a *analysis, delta *nodeset) {
+ changed := false
+ for _, x := range delta.AppendTo(a.deltaSpace) {
+ vObj := nodeid(x)
+ tDyn, payload, indirect := a.taggedValue(vObj)
+ if indirect {
+ // TODO(adonovan): we'll need to implement this
+ // when we start creating indirect tagged objects.
+ panic("indirect tagged object")
+ }
+
+ var res nodeid
+ switch t := tDyn.Underlying().(type) {
+ case *types.Array:
+ res = a.makeTagged(t.Elem(), c.cgn, nil)
+ a.onlineCopyN(res+1, payload+1, a.sizeof(t.Elem()))
+
+ case *types.Slice:
+ res = a.makeTagged(t.Elem(), c.cgn, nil)
+ a.load(res+1, payload, 1, a.sizeof(t.Elem()))
+
+ case *types.Basic:
+ if t.Kind() == types.String {
+ res = a.makeTagged(types.Typ[types.Rune], c.cgn, nil)
+ }
+ }
+ if res != 0 && a.addLabel(c.result, res) {
+ changed = true
+ }
+ }
+ if changed {
+ a.addWork(c.result)
+ }
+}
+
+func ext۰reflect۰Value۰Index(a *analysis, cgn *cgnode) {
+ a.addConstraint(&rVIndexConstraint{
+ cgn: cgn,
+ v: a.funcParams(cgn.obj),
+ result: a.funcResults(cgn.obj),
+ })
+}
+
+// ---------- func (Value).Interface() Value ----------
+
+// result = v.Interface()
+type rVInterfaceConstraint struct {
+ v nodeid // (ptr)
+ result nodeid // (indirect)
+}
+
+func (c *rVInterfaceConstraint) ptr() nodeid { return c.v }
+func (c *rVInterfaceConstraint) presolve(h *hvn) {
+ h.markIndirect(onodeid(c.result), "rVInterface.result")
+}
+func (c *rVInterfaceConstraint) renumber(mapping []nodeid) {
+ c.v = mapping[c.v]
+ c.result = mapping[c.result]
+}
+
+func (c *rVInterfaceConstraint) String() string {
+ return fmt.Sprintf("n%d = reflect n%d.Interface()", c.result, c.v)
+}
+
+func (c *rVInterfaceConstraint) solve(a *analysis, delta *nodeset) {
+ changed := false
+ for _, x := range delta.AppendTo(a.deltaSpace) {
+ vObj := nodeid(x)
+ tDyn, payload, indirect := a.taggedValue(vObj)
+ if indirect {
+ // TODO(adonovan): we'll need to implement this
+ // when we start creating indirect tagged objects.
+ panic("indirect tagged object")
+ }
+
+ if isInterface(tDyn) {
+ if a.onlineCopy(c.result, payload) {
+ a.addWork(c.result)
+ }
+ } else {
+ if a.addLabel(c.result, vObj) {
+ changed = true
+ }
+ }
+ }
+ if changed {
+ a.addWork(c.result)
+ }
+}
+
+func ext۰reflect۰Value۰Interface(a *analysis, cgn *cgnode) {
+ a.addConstraint(&rVInterfaceConstraint{
+ v: a.funcParams(cgn.obj),
+ result: a.funcResults(cgn.obj),
+ })
+}
+
+// ---------- func (Value).MapIndex(Value) Value ----------
+
+// result = v.MapIndex(_)
+type rVMapIndexConstraint struct {
+ cgn *cgnode
+ v nodeid // (ptr)
+ result nodeid // (indirect)
+}
+
+func (c *rVMapIndexConstraint) ptr() nodeid { return c.v }
+func (c *rVMapIndexConstraint) presolve(h *hvn) {
+ h.markIndirect(onodeid(c.result), "rVMapIndex.result")
+}
+func (c *rVMapIndexConstraint) renumber(mapping []nodeid) {
+ c.v = mapping[c.v]
+ c.result = mapping[c.result]
+}
+
+func (c *rVMapIndexConstraint) String() string {
+ return fmt.Sprintf("n%d = reflect n%d.MapIndex(_)", c.result, c.v)
+}
+
+func (c *rVMapIndexConstraint) solve(a *analysis, delta *nodeset) {
+ changed := false
+ for _, x := range delta.AppendTo(a.deltaSpace) {
+ vObj := nodeid(x)
+ tDyn, m, indirect := a.taggedValue(vObj)
+ tMap, _ := tDyn.Underlying().(*types.Map)
+ if tMap == nil {
+ continue // not a map
+ }
+ if indirect {
+ // TODO(adonovan): we'll need to implement this
+ // when we start creating indirect tagged objects.
+ panic("indirect tagged object")
+ }
+
+ obj := a.makeTagged(tMap.Elem(), c.cgn, nil)
+ a.load(obj+1, m, a.sizeof(tMap.Key()), a.sizeof(tMap.Elem()))
+ if a.addLabel(c.result, obj) {
+ changed = true
+ }
+ }
+ if changed {
+ a.addWork(c.result)
+ }
+}
+
+func ext۰reflect۰Value۰MapIndex(a *analysis, cgn *cgnode) {
+ a.addConstraint(&rVMapIndexConstraint{
+ cgn: cgn,
+ v: a.funcParams(cgn.obj),
+ result: a.funcResults(cgn.obj),
+ })
+}
+
+// ---------- func (Value).MapKeys() []Value ----------
+
+// result = v.MapKeys()
+type rVMapKeysConstraint struct {
+ cgn *cgnode
+ v nodeid // (ptr)
+ result nodeid // (indirect)
+}
+
+func (c *rVMapKeysConstraint) ptr() nodeid { return c.v }
+func (c *rVMapKeysConstraint) presolve(h *hvn) {
+ h.markIndirect(onodeid(c.result), "rVMapKeys.result")
+}
+func (c *rVMapKeysConstraint) renumber(mapping []nodeid) {
+ c.v = mapping[c.v]
+ c.result = mapping[c.result]
+}
+
+func (c *rVMapKeysConstraint) String() string {
+ return fmt.Sprintf("n%d = reflect n%d.MapKeys()", c.result, c.v)
+}
+
+func (c *rVMapKeysConstraint) solve(a *analysis, delta *nodeset) {
+ changed := false
+ for _, x := range delta.AppendTo(a.deltaSpace) {
+ vObj := nodeid(x)
+ tDyn, m, indirect := a.taggedValue(vObj)
+ tMap, _ := tDyn.Underlying().(*types.Map)
+ if tMap == nil {
+ continue // not a map
+ }
+ if indirect {
+ // TODO(adonovan): we'll need to implement this
+ // when we start creating indirect tagged objects.
+ panic("indirect tagged object")
+ }
+
+ kObj := a.makeTagged(tMap.Key(), c.cgn, nil)
+ a.load(kObj+1, m, 0, a.sizeof(tMap.Key()))
+ if a.addLabel(c.result, kObj) {
+ changed = true
+ }
+ }
+ if changed {
+ a.addWork(c.result)
+ }
+}
+
+func ext۰reflect۰Value۰MapKeys(a *analysis, cgn *cgnode) {
+ // Allocate an array for the result.
+ obj := a.nextNode()
+ T := types.NewSlice(a.reflectValueObj.Type())
+ a.addNodes(sliceToArray(T), "reflect.MapKeys result")
+ a.endObject(obj, cgn, nil)
+ a.addressOf(T, a.funcResults(cgn.obj), obj)
+
+ a.addConstraint(&rVMapKeysConstraint{
+ cgn: cgn,
+ v: a.funcParams(cgn.obj),
+ result: obj + 1, // result is stored in array elems
+ })
+}
+
+func ext۰reflect۰Value۰Method(a *analysis, cgn *cgnode) {} // TODO(adonovan)
+func ext۰reflect۰Value۰MethodByName(a *analysis, cgn *cgnode) {} // TODO(adonovan)
+
+// ---------- func (Value).Recv(Value) Value ----------
+
+// result, _ = v.Recv()
+type rVRecvConstraint struct {
+ cgn *cgnode
+ v nodeid // (ptr)
+ result nodeid // (indirect)
+}
+
+func (c *rVRecvConstraint) ptr() nodeid { return c.v }
+func (c *rVRecvConstraint) presolve(h *hvn) {
+ h.markIndirect(onodeid(c.result), "rVRecv.result")
+}
+func (c *rVRecvConstraint) renumber(mapping []nodeid) {
+ c.v = mapping[c.v]
+ c.result = mapping[c.result]
+}
+
+func (c *rVRecvConstraint) String() string {
+ return fmt.Sprintf("n%d = reflect n%d.Recv()", c.result, c.v)
+}
+
+func (c *rVRecvConstraint) solve(a *analysis, delta *nodeset) {
+ changed := false
+ for _, x := range delta.AppendTo(a.deltaSpace) {
+ vObj := nodeid(x)
+ tDyn, ch, indirect := a.taggedValue(vObj)
+ tChan, _ := tDyn.Underlying().(*types.Chan)
+ if tChan == nil {
+ continue // not a channel
+ }
+ if indirect {
+ // TODO(adonovan): we'll need to implement this
+ // when we start creating indirect tagged objects.
+ panic("indirect tagged object")
+ }
+
+ tElem := tChan.Elem()
+ elemObj := a.makeTagged(tElem, c.cgn, nil)
+ a.load(elemObj+1, ch, 0, a.sizeof(tElem))
+ if a.addLabel(c.result, elemObj) {
+ changed = true
+ }
+ }
+ if changed {
+ a.addWork(c.result)
+ }
+}
+
+func ext۰reflect۰Value۰Recv(a *analysis, cgn *cgnode) {
+ a.addConstraint(&rVRecvConstraint{
+ cgn: cgn,
+ v: a.funcParams(cgn.obj),
+ result: a.funcResults(cgn.obj),
+ })
+}
+
+// ---------- func (Value).Send(Value) ----------
+
+// v.Send(x)
+type rVSendConstraint struct {
+ cgn *cgnode
+ v nodeid // (ptr)
+ x nodeid
+}
+
+func (c *rVSendConstraint) ptr() nodeid { return c.v }
+func (c *rVSendConstraint) presolve(*hvn) {}
+func (c *rVSendConstraint) renumber(mapping []nodeid) {
+ c.v = mapping[c.v]
+ c.x = mapping[c.x]
+}
+
+func (c *rVSendConstraint) String() string {
+ return fmt.Sprintf("reflect n%d.Send(n%d)", c.v, c.x)
+}
+
+func (c *rVSendConstraint) solve(a *analysis, delta *nodeset) {
+ for _, x := range delta.AppendTo(a.deltaSpace) {
+ vObj := nodeid(x)
+ tDyn, ch, indirect := a.taggedValue(vObj)
+ tChan, _ := tDyn.Underlying().(*types.Chan)
+ if tChan == nil {
+ continue // not a channel
+ }
+ if indirect {
+ // TODO(adonovan): we'll need to implement this
+ // when we start creating indirect tagged objects.
+ panic("indirect tagged object")
+ }
+
+ // Extract x's payload to xtmp, then store to channel.
+ tElem := tChan.Elem()
+ xtmp := a.addNodes(tElem, "Send.xtmp")
+ a.typeAssert(tElem, xtmp, c.x, false)
+ a.store(ch, xtmp, 0, a.sizeof(tElem))
+ }
+}
+
+func ext۰reflect۰Value۰Send(a *analysis, cgn *cgnode) {
+ params := a.funcParams(cgn.obj)
+ a.addConstraint(&rVSendConstraint{
+ cgn: cgn,
+ v: params,
+ x: params + 1,
+ })
+}
+
+func ext۰reflect۰Value۰Set(a *analysis, cgn *cgnode) {} // TODO(adonovan)
+
+// ---------- func (Value).SetBytes(x []byte) ----------
+
+// v.SetBytes(x)
+type rVSetBytesConstraint struct {
+ cgn *cgnode
+ v nodeid // (ptr)
+ x nodeid
+}
+
+func (c *rVSetBytesConstraint) ptr() nodeid { return c.v }
+func (c *rVSetBytesConstraint) presolve(*hvn) {}
+func (c *rVSetBytesConstraint) renumber(mapping []nodeid) {
+ c.v = mapping[c.v]
+ c.x = mapping[c.x]
+}
+
+func (c *rVSetBytesConstraint) String() string {
+ return fmt.Sprintf("reflect n%d.SetBytes(n%d)", c.v, c.x)
+}
+
+func (c *rVSetBytesConstraint) solve(a *analysis, delta *nodeset) {
+ for _, x := range delta.AppendTo(a.deltaSpace) {
+ vObj := nodeid(x)
+ tDyn, slice, indirect := a.taggedValue(vObj)
+ if indirect {
+ // TODO(adonovan): we'll need to implement this
+ // when we start creating indirect tagged objects.
+ panic("indirect tagged object")
+ }
+
+ tSlice, ok := tDyn.Underlying().(*types.Slice)
+ if ok && types.Identical(tSlice.Elem(), types.Typ[types.Uint8]) {
+ if a.onlineCopy(slice, c.x) {
+ a.addWork(slice)
+ }
+ }
+ }
+}
+
+func ext۰reflect۰Value۰SetBytes(a *analysis, cgn *cgnode) {
+ params := a.funcParams(cgn.obj)
+ a.addConstraint(&rVSetBytesConstraint{
+ cgn: cgn,
+ v: params,
+ x: params + 1,
+ })
+}
+
+// ---------- func (Value).SetMapIndex(k Value, v Value) ----------
+
+// v.SetMapIndex(key, val)
+type rVSetMapIndexConstraint struct {
+ cgn *cgnode
+ v nodeid // (ptr)
+ key nodeid
+ val nodeid
+}
+
+func (c *rVSetMapIndexConstraint) ptr() nodeid { return c.v }
+func (c *rVSetMapIndexConstraint) presolve(*hvn) {}
+func (c *rVSetMapIndexConstraint) renumber(mapping []nodeid) {
+ c.v = mapping[c.v]
+ c.key = mapping[c.key]
+ c.val = mapping[c.val]
+}
+
+func (c *rVSetMapIndexConstraint) String() string {
+ return fmt.Sprintf("reflect n%d.SetMapIndex(n%d, n%d)", c.v, c.key, c.val)
+}
+
+func (c *rVSetMapIndexConstraint) solve(a *analysis, delta *nodeset) {
+ for _, x := range delta.AppendTo(a.deltaSpace) {
+ vObj := nodeid(x)
+ tDyn, m, indirect := a.taggedValue(vObj)
+ tMap, _ := tDyn.Underlying().(*types.Map)
+ if tMap == nil {
+ continue // not a map
+ }
+ if indirect {
+ // TODO(adonovan): we'll need to implement this
+ // when we start creating indirect tagged objects.
+ panic("indirect tagged object")
+ }
+
+ keysize := a.sizeof(tMap.Key())
+
+ // Extract key's payload to keytmp, then store to map key.
+ keytmp := a.addNodes(tMap.Key(), "SetMapIndex.keytmp")
+ a.typeAssert(tMap.Key(), keytmp, c.key, false)
+ a.store(m, keytmp, 0, keysize)
+
+ // Extract val's payload to vtmp, then store to map value.
+ valtmp := a.addNodes(tMap.Elem(), "SetMapIndex.valtmp")
+ a.typeAssert(tMap.Elem(), valtmp, c.val, false)
+ a.store(m, valtmp, keysize, a.sizeof(tMap.Elem()))
+ }
+}
+
+func ext۰reflect۰Value۰SetMapIndex(a *analysis, cgn *cgnode) {
+ params := a.funcParams(cgn.obj)
+ a.addConstraint(&rVSetMapIndexConstraint{
+ cgn: cgn,
+ v: params,
+ key: params + 1,
+ val: params + 2,
+ })
+}
+
+func ext۰reflect۰Value۰SetPointer(a *analysis, cgn *cgnode) {} // TODO(adonovan)
+
+// ---------- func (Value).Slice(v Value, i, j int) Value ----------
+
+// result = v.Slice(_, _)
+type rVSliceConstraint struct {
+ cgn *cgnode
+ v nodeid // (ptr)
+ result nodeid // (indirect)
+}
+
+func (c *rVSliceConstraint) ptr() nodeid { return c.v }
+func (c *rVSliceConstraint) presolve(h *hvn) {
+ h.markIndirect(onodeid(c.result), "rVSlice.result")
+}
+func (c *rVSliceConstraint) renumber(mapping []nodeid) {
+ c.v = mapping[c.v]
+ c.result = mapping[c.result]
+}
+
+func (c *rVSliceConstraint) String() string {
+ return fmt.Sprintf("n%d = reflect n%d.Slice(_, _)", c.result, c.v)
+}
+
+func (c *rVSliceConstraint) solve(a *analysis, delta *nodeset) {
+ changed := false
+ for _, x := range delta.AppendTo(a.deltaSpace) {
+ vObj := nodeid(x)
+ tDyn, payload, indirect := a.taggedValue(vObj)
+ if indirect {
+ // TODO(adonovan): we'll need to implement this
+ // when we start creating indirect tagged objects.
+ panic("indirect tagged object")
+ }
+
+ var res nodeid
+ switch t := tDyn.Underlying().(type) {
+ case *types.Pointer:
+ if tArr, ok := t.Elem().Underlying().(*types.Array); ok {
+ // pointer to array
+ res = a.makeTagged(types.NewSlice(tArr.Elem()), c.cgn, nil)
+ if a.onlineCopy(res+1, payload) {
+ a.addWork(res + 1)
+ }
+ }
+
+ case *types.Array:
+ // TODO(adonovan): implement addressable
+ // arrays when we do indirect tagged objects.
+
+ case *types.Slice:
+ res = vObj
+
+ case *types.Basic:
+ if t == types.Typ[types.String] {
+ res = vObj
+ }
+ }
+
+ if res != 0 && a.addLabel(c.result, res) {
+ changed = true
+ }
+ }
+ if changed {
+ a.addWork(c.result)
+ }
+}
+
+func ext۰reflect۰Value۰Slice(a *analysis, cgn *cgnode) {
+ a.addConstraint(&rVSliceConstraint{
+ cgn: cgn,
+ v: a.funcParams(cgn.obj),
+ result: a.funcResults(cgn.obj),
+ })
+}
+
+// -------------------- Standalone reflect functions --------------------
+
+func ext۰reflect۰Append(a *analysis, cgn *cgnode) {} // TODO(adonovan)
+func ext۰reflect۰AppendSlice(a *analysis, cgn *cgnode) {} // TODO(adonovan)
+func ext۰reflect۰Copy(a *analysis, cgn *cgnode) {} // TODO(adonovan)
+
+// ---------- func ChanOf(ChanDir, Type) Type ----------
+
+// result = ChanOf(dir, t)
+type reflectChanOfConstraint struct {
+ cgn *cgnode
+ t nodeid // (ptr)
+ result nodeid // (indirect)
+ dirs []types.ChanDir
+}
+
+func (c *reflectChanOfConstraint) ptr() nodeid { return c.t }
+func (c *reflectChanOfConstraint) presolve(h *hvn) {
+ h.markIndirect(onodeid(c.result), "reflectChanOf.result")
+}
+func (c *reflectChanOfConstraint) renumber(mapping []nodeid) {
+ c.t = mapping[c.t]
+ c.result = mapping[c.result]
+}
+
+func (c *reflectChanOfConstraint) String() string {
+ return fmt.Sprintf("n%d = reflect.ChanOf(n%d)", c.result, c.t)
+}
+
+func (c *reflectChanOfConstraint) solve(a *analysis, delta *nodeset) {
+ changed := false
+ for _, x := range delta.AppendTo(a.deltaSpace) {
+ tObj := nodeid(x)
+ T := a.rtypeTaggedValue(tObj)
+
+ if typeTooHigh(T) {
+ continue
+ }
+
+ for _, dir := range c.dirs {
+ if a.addLabel(c.result, a.makeRtype(types.NewChan(dir, T))) {
+ changed = true
+ }
+ }
+ }
+ if changed {
+ a.addWork(c.result)
+ }
+}
+
+// dirMap maps reflect.ChanDir to the set of channel types generated by ChanOf.
+var dirMap = [...][]types.ChanDir{
+ 0: {types.SendOnly, types.RecvOnly, types.SendRecv}, // unknown
+ reflect.RecvDir: {types.RecvOnly},
+ reflect.SendDir: {types.SendOnly},
+ reflect.BothDir: {types.SendRecv},
+}
+
+func ext۰reflect۰ChanOf(a *analysis, cgn *cgnode) {
+ // If we have access to the callsite,
+ // and the channel argument is a constant (as is usual),
+ // only generate the requested direction.
+ var dir reflect.ChanDir // unknown
+ if site := cgn.callersite; site != nil {
+ if c, ok := site.instr.Common().Args[0].(*ssa.Const); ok {
+ v, _ := exact.Int64Val(c.Value)
+ if 0 <= v && v <= int64(reflect.BothDir) {
+ dir = reflect.ChanDir(v)
+ }
+ }
+ }
+
+ params := a.funcParams(cgn.obj)
+ a.addConstraint(&reflectChanOfConstraint{
+ cgn: cgn,
+ t: params + 1,
+ result: a.funcResults(cgn.obj),
+ dirs: dirMap[dir],
+ })
+}
+
+// ---------- func Indirect(v Value) Value ----------
+
+// result = Indirect(v)
+type reflectIndirectConstraint struct {
+ cgn *cgnode
+ v nodeid // (ptr)
+ result nodeid // (indirect)
+}
+
+func (c *reflectIndirectConstraint) ptr() nodeid { return c.v }
+func (c *reflectIndirectConstraint) presolve(h *hvn) {
+ h.markIndirect(onodeid(c.result), "reflectIndirect.result")
+}
+func (c *reflectIndirectConstraint) renumber(mapping []nodeid) {
+ c.v = mapping[c.v]
+ c.result = mapping[c.result]
+}
+
+func (c *reflectIndirectConstraint) String() string {
+ return fmt.Sprintf("n%d = reflect.Indirect(n%d)", c.result, c.v)
+}
+
+func (c *reflectIndirectConstraint) solve(a *analysis, delta *nodeset) {
+ changed := false
+ for _, x := range delta.AppendTo(a.deltaSpace) {
+ vObj := nodeid(x)
+ tDyn, _, _ := a.taggedValue(vObj)
+ var res nodeid
+ if tPtr, ok := tDyn.Underlying().(*types.Pointer); ok {
+ // load the payload of the pointer's tagged object
+ // into a new tagged object
+ res = a.makeTagged(tPtr.Elem(), c.cgn, nil)
+ a.load(res+1, vObj+1, 0, a.sizeof(tPtr.Elem()))
+ } else {
+ res = vObj
+ }
+
+ if a.addLabel(c.result, res) {
+ changed = true
+ }
+ }
+ if changed {
+ a.addWork(c.result)
+ }
+}
+
+func ext۰reflect۰Indirect(a *analysis, cgn *cgnode) {
+ a.addConstraint(&reflectIndirectConstraint{
+ cgn: cgn,
+ v: a.funcParams(cgn.obj),
+ result: a.funcResults(cgn.obj),
+ })
+}
+
+// ---------- func MakeChan(Type) Value ----------
+
+// result = MakeChan(typ)
+type reflectMakeChanConstraint struct {
+ cgn *cgnode
+ typ nodeid // (ptr)
+ result nodeid // (indirect)
+}
+
+func (c *reflectMakeChanConstraint) ptr() nodeid { return c.typ }
+func (c *reflectMakeChanConstraint) presolve(h *hvn) {
+ h.markIndirect(onodeid(c.result), "reflectMakeChan.result")
+}
+func (c *reflectMakeChanConstraint) renumber(mapping []nodeid) {
+ c.typ = mapping[c.typ]
+ c.result = mapping[c.result]
+}
+
+func (c *reflectMakeChanConstraint) String() string {
+ return fmt.Sprintf("n%d = reflect.MakeChan(n%d)", c.result, c.typ)
+}
+
+func (c *reflectMakeChanConstraint) solve(a *analysis, delta *nodeset) {
+ changed := false
+ for _, x := range delta.AppendTo(a.deltaSpace) {
+ typObj := nodeid(x)
+ T := a.rtypeTaggedValue(typObj)
+ tChan, ok := T.Underlying().(*types.Chan)
+ if !ok || tChan.Dir() != types.SendRecv {
+ continue // not a bidirectional channel type
+ }
+
+ obj := a.nextNode()
+ a.addNodes(tChan.Elem(), "reflect.MakeChan.value")
+ a.endObject(obj, c.cgn, nil)
+
+ // put its address in a new T-tagged object
+ id := a.makeTagged(T, c.cgn, nil)
+ a.addLabel(id+1, obj)
+
+ // flow the T-tagged object to the result
+ if a.addLabel(c.result, id) {
+ changed = true
+ }
+ }
+ if changed {
+ a.addWork(c.result)
+ }
+}
+
+func ext۰reflect۰MakeChan(a *analysis, cgn *cgnode) {
+ a.addConstraint(&reflectMakeChanConstraint{
+ cgn: cgn,
+ typ: a.funcParams(cgn.obj),
+ result: a.funcResults(cgn.obj),
+ })
+}
+
+func ext۰reflect۰MakeFunc(a *analysis, cgn *cgnode) {} // TODO(adonovan)
+
+// ---------- func MakeMap(Type) Value ----------
+
+// result = MakeMap(typ)
+type reflectMakeMapConstraint struct {
+ cgn *cgnode
+ typ nodeid // (ptr)
+ result nodeid // (indirect)
+}
+
+func (c *reflectMakeMapConstraint) ptr() nodeid { return c.typ }
+func (c *reflectMakeMapConstraint) presolve(h *hvn) {
+ h.markIndirect(onodeid(c.result), "reflectMakeMap.result")
+}
+func (c *reflectMakeMapConstraint) renumber(mapping []nodeid) {
+ c.typ = mapping[c.typ]
+ c.result = mapping[c.result]
+}
+
+func (c *reflectMakeMapConstraint) String() string {
+ return fmt.Sprintf("n%d = reflect.MakeMap(n%d)", c.result, c.typ)
+}
+
+func (c *reflectMakeMapConstraint) solve(a *analysis, delta *nodeset) {
+ changed := false
+ for _, x := range delta.AppendTo(a.deltaSpace) {
+ typObj := nodeid(x)
+ T := a.rtypeTaggedValue(typObj)
+ tMap, ok := T.Underlying().(*types.Map)
+ if !ok {
+ continue // not a map type
+ }
+
+ mapObj := a.nextNode()
+ a.addNodes(tMap.Key(), "reflect.MakeMap.key")
+ a.addNodes(tMap.Elem(), "reflect.MakeMap.value")
+ a.endObject(mapObj, c.cgn, nil)
+
+ // put its address in a new T-tagged object
+ id := a.makeTagged(T, c.cgn, nil)
+ a.addLabel(id+1, mapObj)
+
+ // flow the T-tagged object to the result
+ if a.addLabel(c.result, id) {
+ changed = true
+ }
+ }
+ if changed {
+ a.addWork(c.result)
+ }
+}
+
+func ext۰reflect۰MakeMap(a *analysis, cgn *cgnode) {
+ a.addConstraint(&reflectMakeMapConstraint{
+ cgn: cgn,
+ typ: a.funcParams(cgn.obj),
+ result: a.funcResults(cgn.obj),
+ })
+}
+
+// ---------- func MakeSlice(Type) Value ----------
+
+// result = MakeSlice(typ)
+type reflectMakeSliceConstraint struct {
+ cgn *cgnode
+ typ nodeid // (ptr)
+ result nodeid // (indirect)
+}
+
+func (c *reflectMakeSliceConstraint) ptr() nodeid { return c.typ }
+func (c *reflectMakeSliceConstraint) presolve(h *hvn) {
+ h.markIndirect(onodeid(c.result), "reflectMakeSlice.result")
+}
+func (c *reflectMakeSliceConstraint) renumber(mapping []nodeid) {
+ c.typ = mapping[c.typ]
+ c.result = mapping[c.result]
+}
+
+func (c *reflectMakeSliceConstraint) String() string {
+ return fmt.Sprintf("n%d = reflect.MakeSlice(n%d)", c.result, c.typ)
+}
+
+func (c *reflectMakeSliceConstraint) solve(a *analysis, delta *nodeset) {
+ changed := false
+ for _, x := range delta.AppendTo(a.deltaSpace) {
+ typObj := nodeid(x)
+ T := a.rtypeTaggedValue(typObj)
+ if _, ok := T.Underlying().(*types.Slice); !ok {
+ continue // not a slice type
+ }
+
+ obj := a.nextNode()
+ a.addNodes(sliceToArray(T), "reflect.MakeSlice")
+ a.endObject(obj, c.cgn, nil)
+
+ // put its address in a new T-tagged object
+ id := a.makeTagged(T, c.cgn, nil)
+ a.addLabel(id+1, obj)
+
+ // flow the T-tagged object to the result
+ if a.addLabel(c.result, id) {
+ changed = true
+ }
+ }
+ if changed {
+ a.addWork(c.result)
+ }
+}
+
+func ext۰reflect۰MakeSlice(a *analysis, cgn *cgnode) {
+ a.addConstraint(&reflectMakeSliceConstraint{
+ cgn: cgn,
+ typ: a.funcParams(cgn.obj),
+ result: a.funcResults(cgn.obj),
+ })
+}
+
+func ext۰reflect۰MapOf(a *analysis, cgn *cgnode) {} // TODO(adonovan)
+
+// ---------- func New(Type) Value ----------
+
+// result = New(typ)
+type reflectNewConstraint struct {
+ cgn *cgnode
+ typ nodeid // (ptr)
+ result nodeid // (indirect)
+}
+
+func (c *reflectNewConstraint) ptr() nodeid { return c.typ }
+func (c *reflectNewConstraint) presolve(h *hvn) {
+ h.markIndirect(onodeid(c.result), "reflectNew.result")
+}
+func (c *reflectNewConstraint) renumber(mapping []nodeid) {
+ c.typ = mapping[c.typ]
+ c.result = mapping[c.result]
+}
+
+func (c *reflectNewConstraint) String() string {
+ return fmt.Sprintf("n%d = reflect.New(n%d)", c.result, c.typ)
+}
+
+func (c *reflectNewConstraint) solve(a *analysis, delta *nodeset) {
+ changed := false
+ for _, x := range delta.AppendTo(a.deltaSpace) {
+ typObj := nodeid(x)
+ T := a.rtypeTaggedValue(typObj)
+
+ // allocate new T object
+ newObj := a.nextNode()
+ a.addNodes(T, "reflect.New")
+ a.endObject(newObj, c.cgn, nil)
+
+ // put its address in a new *T-tagged object
+ id := a.makeTagged(types.NewPointer(T), c.cgn, nil)
+ a.addLabel(id+1, newObj)
+
+ // flow the pointer to the result
+ if a.addLabel(c.result, id) {
+ changed = true
+ }
+ }
+ if changed {
+ a.addWork(c.result)
+ }
+}
+
+func ext۰reflect۰New(a *analysis, cgn *cgnode) {
+ a.addConstraint(&reflectNewConstraint{
+ cgn: cgn,
+ typ: a.funcParams(cgn.obj),
+ result: a.funcResults(cgn.obj),
+ })
+}
+
+func ext۰reflect۰NewAt(a *analysis, cgn *cgnode) {
+ ext۰reflect۰New(a, cgn)
+
+ // TODO(adonovan): also report dynamic calls to unsound intrinsics.
+ if site := cgn.callersite; site != nil {
+ a.warnf(site.pos(), "unsound: %s contains a reflect.NewAt() call", site.instr.Parent())
+ }
+}
+
+// ---------- func PtrTo(Type) Type ----------
+
+// result = PtrTo(t)
+type reflectPtrToConstraint struct {
+ cgn *cgnode
+ t nodeid // (ptr)
+ result nodeid // (indirect)
+}
+
+func (c *reflectPtrToConstraint) ptr() nodeid { return c.t }
+func (c *reflectPtrToConstraint) presolve(h *hvn) {
+ h.markIndirect(onodeid(c.result), "reflectPtrTo.result")
+}
+func (c *reflectPtrToConstraint) renumber(mapping []nodeid) {
+ c.t = mapping[c.t]
+ c.result = mapping[c.result]
+}
+
+func (c *reflectPtrToConstraint) String() string {
+ return fmt.Sprintf("n%d = reflect.PtrTo(n%d)", c.result, c.t)
+}
+
+func (c *reflectPtrToConstraint) solve(a *analysis, delta *nodeset) {
+ changed := false
+ for _, x := range delta.AppendTo(a.deltaSpace) {
+ tObj := nodeid(x)
+ T := a.rtypeTaggedValue(tObj)
+
+ if typeTooHigh(T) {
+ continue
+ }
+
+ if a.addLabel(c.result, a.makeRtype(types.NewPointer(T))) {
+ changed = true
+ }
+ }
+ if changed {
+ a.addWork(c.result)
+ }
+}
+
+func ext۰reflect۰PtrTo(a *analysis, cgn *cgnode) {
+ a.addConstraint(&reflectPtrToConstraint{
+ cgn: cgn,
+ t: a.funcParams(cgn.obj),
+ result: a.funcResults(cgn.obj),
+ })
+}
+
+func ext۰reflect۰Select(a *analysis, cgn *cgnode) {} // TODO(adonovan)
+
+// ---------- func SliceOf(Type) Type ----------
+
+// result = SliceOf(t)
+type reflectSliceOfConstraint struct {
+ cgn *cgnode
+ t nodeid // (ptr)
+ result nodeid // (indirect)
+}
+
+func (c *reflectSliceOfConstraint) ptr() nodeid { return c.t }
+func (c *reflectSliceOfConstraint) presolve(h *hvn) {
+ h.markIndirect(onodeid(c.result), "reflectSliceOf.result")
+}
+func (c *reflectSliceOfConstraint) renumber(mapping []nodeid) {
+ c.t = mapping[c.t]
+ c.result = mapping[c.result]
+}
+
+func (c *reflectSliceOfConstraint) String() string {
+ return fmt.Sprintf("n%d = reflect.SliceOf(n%d)", c.result, c.t)
+}
+
+func (c *reflectSliceOfConstraint) solve(a *analysis, delta *nodeset) {
+ changed := false
+ for _, x := range delta.AppendTo(a.deltaSpace) {
+ tObj := nodeid(x)
+ T := a.rtypeTaggedValue(tObj)
+
+ if typeTooHigh(T) {
+ continue
+ }
+
+ if a.addLabel(c.result, a.makeRtype(types.NewSlice(T))) {
+ changed = true
+ }
+ }
+ if changed {
+ a.addWork(c.result)
+ }
+}
+
+func ext۰reflect۰SliceOf(a *analysis, cgn *cgnode) {
+ a.addConstraint(&reflectSliceOfConstraint{
+ cgn: cgn,
+ t: a.funcParams(cgn.obj),
+ result: a.funcResults(cgn.obj),
+ })
+}
+
+// ---------- func TypeOf(v Value) Type ----------
+
+// result = TypeOf(i)
+type reflectTypeOfConstraint struct {
+ cgn *cgnode
+ i nodeid // (ptr)
+ result nodeid // (indirect)
+}
+
+func (c *reflectTypeOfConstraint) ptr() nodeid { return c.i }
+func (c *reflectTypeOfConstraint) presolve(h *hvn) {
+ h.markIndirect(onodeid(c.result), "reflectTypeOf.result")
+}
+func (c *reflectTypeOfConstraint) renumber(mapping []nodeid) {
+ c.i = mapping[c.i]
+ c.result = mapping[c.result]
+}
+
+func (c *reflectTypeOfConstraint) String() string {
+ return fmt.Sprintf("n%d = reflect.TypeOf(n%d)", c.result, c.i)
+}
+
+func (c *reflectTypeOfConstraint) solve(a *analysis, delta *nodeset) {
+ changed := false
+ for _, x := range delta.AppendTo(a.deltaSpace) {
+ iObj := nodeid(x)
+ tDyn, _, _ := a.taggedValue(iObj)
+ if a.addLabel(c.result, a.makeRtype(tDyn)) {
+ changed = true
+ }
+ }
+ if changed {
+ a.addWork(c.result)
+ }
+}
+
+func ext۰reflect۰TypeOf(a *analysis, cgn *cgnode) {
+ a.addConstraint(&reflectTypeOfConstraint{
+ cgn: cgn,
+ i: a.funcParams(cgn.obj),
+ result: a.funcResults(cgn.obj),
+ })
+}
+
+// ---------- func ValueOf(interface{}) Value ----------
+
+func ext۰reflect۰ValueOf(a *analysis, cgn *cgnode) {
+ // TODO(adonovan): when we start creating indirect tagged
+ // objects, we'll need to handle them specially here since
+ // they must never appear in the PTS of an interface{}.
+ a.copy(a.funcResults(cgn.obj), a.funcParams(cgn.obj), 1)
+}
+
+// ---------- func Zero(Type) Value ----------
+
+// result = Zero(typ)
+type reflectZeroConstraint struct {
+ cgn *cgnode
+ typ nodeid // (ptr)
+ result nodeid // (indirect)
+}
+
+func (c *reflectZeroConstraint) ptr() nodeid { return c.typ }
+func (c *reflectZeroConstraint) presolve(h *hvn) {
+ h.markIndirect(onodeid(c.result), "reflectZero.result")
+}
+func (c *reflectZeroConstraint) renumber(mapping []nodeid) {
+ c.typ = mapping[c.typ]
+ c.result = mapping[c.result]
+}
+
+func (c *reflectZeroConstraint) String() string {
+ return fmt.Sprintf("n%d = reflect.Zero(n%d)", c.result, c.typ)
+}
+
+func (c *reflectZeroConstraint) solve(a *analysis, delta *nodeset) {
+ changed := false
+ for _, x := range delta.AppendTo(a.deltaSpace) {
+ typObj := nodeid(x)
+ T := a.rtypeTaggedValue(typObj)
+
+ // TODO(adonovan): if T is an interface type, we need
+ // to create an indirect tagged object containing
+ // new(T). To avoid updates of such shared values,
+ // we'll need another flag on indirect tagged objects
+ // that marks whether they are addressable or
+ // readonly, just like the reflect package does.
+
+ // memoize using a.reflectZeros[T]
+ var id nodeid
+ if z := a.reflectZeros.At(T); false && z != nil {
+ id = z.(nodeid)
+ } else {
+ id = a.makeTagged(T, c.cgn, nil)
+ a.reflectZeros.Set(T, id)
+ }
+ if a.addLabel(c.result, id) {
+ changed = true
+ }
+ }
+ if changed {
+ a.addWork(c.result)
+ }
+}
+
+func ext۰reflect۰Zero(a *analysis, cgn *cgnode) {
+ a.addConstraint(&reflectZeroConstraint{
+ cgn: cgn,
+ typ: a.funcParams(cgn.obj),
+ result: a.funcResults(cgn.obj),
+ })
+}
+
+// -------------------- (*reflect.rtype) methods --------------------
+
+// ---------- func (*rtype) Elem() Type ----------
+
+// result = Elem(t)
+type rtypeElemConstraint struct {
+ cgn *cgnode
+ t nodeid // (ptr)
+ result nodeid // (indirect)
+}
+
+func (c *rtypeElemConstraint) ptr() nodeid { return c.t }
+func (c *rtypeElemConstraint) presolve(h *hvn) {
+ h.markIndirect(onodeid(c.result), "rtypeElem.result")
+}
+func (c *rtypeElemConstraint) renumber(mapping []nodeid) {
+ c.t = mapping[c.t]
+ c.result = mapping[c.result]
+}
+
+func (c *rtypeElemConstraint) String() string {
+ return fmt.Sprintf("n%d = (*reflect.rtype).Elem(n%d)", c.result, c.t)
+}
+
+func (c *rtypeElemConstraint) solve(a *analysis, delta *nodeset) {
+ // Implemented by *types.{Map,Chan,Array,Slice,Pointer}.
+ type hasElem interface {
+ Elem() types.Type
+ }
+ changed := false
+ for _, x := range delta.AppendTo(a.deltaSpace) {
+ tObj := nodeid(x)
+ T := a.nodes[tObj].obj.data.(types.Type)
+ if tHasElem, ok := T.Underlying().(hasElem); ok {
+ if a.addLabel(c.result, a.makeRtype(tHasElem.Elem())) {
+ changed = true
+ }
+ }
+ }
+ if changed {
+ a.addWork(c.result)
+ }
+}
+
+func ext۰reflect۰rtype۰Elem(a *analysis, cgn *cgnode) {
+ a.addConstraint(&rtypeElemConstraint{
+ cgn: cgn,
+ t: a.funcParams(cgn.obj),
+ result: a.funcResults(cgn.obj),
+ })
+}
+
+// ---------- func (*rtype) Field(int) StructField ----------
+// ---------- func (*rtype) FieldByName(string) (StructField, bool) ----------
+
+// result = FieldByName(t, name)
+// result = Field(t, _)
+type rtypeFieldByNameConstraint struct {
+ cgn *cgnode
+ name string // name of field; "" for unknown
+ t nodeid // (ptr)
+ result nodeid // (indirect)
+}
+
+func (c *rtypeFieldByNameConstraint) ptr() nodeid { return c.t }
+func (c *rtypeFieldByNameConstraint) presolve(h *hvn) {
+ h.markIndirect(onodeid(c.result+3), "rtypeFieldByName.result.Type")
+}
+func (c *rtypeFieldByNameConstraint) renumber(mapping []nodeid) {
+ c.t = mapping[c.t]
+ c.result = mapping[c.result]
+}
+
+func (c *rtypeFieldByNameConstraint) String() string {
+ return fmt.Sprintf("n%d = (*reflect.rtype).FieldByName(n%d, %q)", c.result, c.t, c.name)
+}
+
+func (c *rtypeFieldByNameConstraint) solve(a *analysis, delta *nodeset) {
+ // type StructField struct {
+ // 0 __identity__
+ // 1 Name string
+ // 2 PkgPath string
+ // 3 Type Type
+ // 4 Tag StructTag
+ // 5 Offset uintptr
+ // 6 Index []int
+ // 7 Anonymous bool
+ // }
+
+ for _, x := range delta.AppendTo(a.deltaSpace) {
+ tObj := nodeid(x)
+ T := a.nodes[tObj].obj.data.(types.Type)
+ tStruct, ok := T.Underlying().(*types.Struct)
+ if !ok {
+ continue // not a struct type
+ }
+
+ n := tStruct.NumFields()
+ for i := 0; i < n; i++ {
+ f := tStruct.Field(i)
+ if c.name == "" || c.name == f.Name() {
+
+ // a.offsetOf(Type) is 3.
+ if id := c.result + 3; a.addLabel(id, a.makeRtype(f.Type())) {
+ a.addWork(id)
+ }
+ // TODO(adonovan): StructField.Index should be non-nil.
+ }
+ }
+ }
+}
+
+func ext۰reflect۰rtype۰FieldByName(a *analysis, cgn *cgnode) {
+ // If we have access to the callsite,
+ // and the argument is a string constant,
+ // return only that field.
+ var name string
+ if site := cgn.callersite; site != nil {
+ if c, ok := site.instr.Common().Args[0].(*ssa.Const); ok {
+ name = exact.StringVal(c.Value)
+ }
+ }
+
+ a.addConstraint(&rtypeFieldByNameConstraint{
+ cgn: cgn,
+ name: name,
+ t: a.funcParams(cgn.obj),
+ result: a.funcResults(cgn.obj),
+ })
+}
+
+func ext۰reflect۰rtype۰Field(a *analysis, cgn *cgnode) {
+ // No-one ever calls Field with a constant argument,
+ // so we don't specialize that case.
+ a.addConstraint(&rtypeFieldByNameConstraint{
+ cgn: cgn,
+ t: a.funcParams(cgn.obj),
+ result: a.funcResults(cgn.obj),
+ })
+}
+
+func ext۰reflect۰rtype۰FieldByIndex(a *analysis, cgn *cgnode) {} // TODO(adonovan)
+func ext۰reflect۰rtype۰FieldByNameFunc(a *analysis, cgn *cgnode) {} // TODO(adonovan)
+
+// ---------- func (*rtype) In/Out(i int) Type ----------
+
+// result = In/Out(t, i)
+type rtypeInOutConstraint struct {
+ cgn *cgnode
+ t nodeid // (ptr)
+ result nodeid // (indirect)
+ out bool
+ i int // -ve if not a constant
+}
+
+func (c *rtypeInOutConstraint) ptr() nodeid { return c.t }
+func (c *rtypeInOutConstraint) presolve(h *hvn) {
+ h.markIndirect(onodeid(c.result), "rtypeInOut.result")
+}
+func (c *rtypeInOutConstraint) renumber(mapping []nodeid) {
+ c.t = mapping[c.t]
+ c.result = mapping[c.result]
+}
+
+func (c *rtypeInOutConstraint) String() string {
+ return fmt.Sprintf("n%d = (*reflect.rtype).InOut(n%d, %d)", c.result, c.t, c.i)
+}
+
+func (c *rtypeInOutConstraint) solve(a *analysis, delta *nodeset) {
+ changed := false
+ for _, x := range delta.AppendTo(a.deltaSpace) {
+ tObj := nodeid(x)
+ T := a.nodes[tObj].obj.data.(types.Type)
+ sig, ok := T.Underlying().(*types.Signature)
+ if !ok {
+ continue // not a func type
+ }
+
+ tuple := sig.Params()
+ if c.out {
+ tuple = sig.Results()
+ }
+ for i, n := 0, tuple.Len(); i < n; i++ {
+ if c.i < 0 || c.i == i {
+ if a.addLabel(c.result, a.makeRtype(tuple.At(i).Type())) {
+ changed = true
+ }
+ }
+ }
+ }
+ if changed {
+ a.addWork(c.result)
+ }
+}
+
+func ext۰reflect۰rtype۰InOut(a *analysis, cgn *cgnode, out bool) {
+ // If we have access to the callsite,
+ // and the argument is an int constant,
+ // return only that parameter.
+ index := -1
+ if site := cgn.callersite; site != nil {
+ if c, ok := site.instr.Common().Args[0].(*ssa.Const); ok {
+ v, _ := exact.Int64Val(c.Value)
+ index = int(v)
+ }
+ }
+ a.addConstraint(&rtypeInOutConstraint{
+ cgn: cgn,
+ t: a.funcParams(cgn.obj),
+ result: a.funcResults(cgn.obj),
+ out: out,
+ i: index,
+ })
+}
+
+func ext۰reflect۰rtype۰In(a *analysis, cgn *cgnode) {
+ ext۰reflect۰rtype۰InOut(a, cgn, false)
+}
+
+func ext۰reflect۰rtype۰Out(a *analysis, cgn *cgnode) {
+ ext۰reflect۰rtype۰InOut(a, cgn, true)
+}
+
+// ---------- func (*rtype) Key() Type ----------
+
+// result = Key(t)
+type rtypeKeyConstraint struct {
+ cgn *cgnode
+ t nodeid // (ptr)
+ result nodeid // (indirect)
+}
+
+func (c *rtypeKeyConstraint) ptr() nodeid { return c.t }
+func (c *rtypeKeyConstraint) presolve(h *hvn) {
+ h.markIndirect(onodeid(c.result), "rtypeKey.result")
+}
+func (c *rtypeKeyConstraint) renumber(mapping []nodeid) {
+ c.t = mapping[c.t]
+ c.result = mapping[c.result]
+}
+
+func (c *rtypeKeyConstraint) String() string {
+ return fmt.Sprintf("n%d = (*reflect.rtype).Key(n%d)", c.result, c.t)
+}
+
+func (c *rtypeKeyConstraint) solve(a *analysis, delta *nodeset) {
+ changed := false
+ for _, x := range delta.AppendTo(a.deltaSpace) {
+ tObj := nodeid(x)
+ T := a.nodes[tObj].obj.data.(types.Type)
+ if tMap, ok := T.Underlying().(*types.Map); ok {
+ if a.addLabel(c.result, a.makeRtype(tMap.Key())) {
+ changed = true
+ }
+ }
+ }
+ if changed {
+ a.addWork(c.result)
+ }
+}
+
+func ext۰reflect۰rtype۰Key(a *analysis, cgn *cgnode) {
+ a.addConstraint(&rtypeKeyConstraint{
+ cgn: cgn,
+ t: a.funcParams(cgn.obj),
+ result: a.funcResults(cgn.obj),
+ })
+}
+
+// ---------- func (*rtype) Method(int) (Method, bool) ----------
+// ---------- func (*rtype) MethodByName(string) (Method, bool) ----------
+
+// result = MethodByName(t, name)
+// result = Method(t, _)
+type rtypeMethodByNameConstraint struct {
+ cgn *cgnode
+ name string // name of method; "" for unknown
+ t nodeid // (ptr)
+ result nodeid // (indirect)
+}
+
+func (c *rtypeMethodByNameConstraint) ptr() nodeid { return c.t }
+func (c *rtypeMethodByNameConstraint) presolve(h *hvn) {
+ h.markIndirect(onodeid(c.result+3), "rtypeMethodByName.result.Type")
+ h.markIndirect(onodeid(c.result+4), "rtypeMethodByName.result.Func")
+}
+func (c *rtypeMethodByNameConstraint) renumber(mapping []nodeid) {
+ c.t = mapping[c.t]
+ c.result = mapping[c.result]
+}
+
+func (c *rtypeMethodByNameConstraint) String() string {
+ return fmt.Sprintf("n%d = (*reflect.rtype).MethodByName(n%d, %q)", c.result, c.t, c.name)
+}
+
+// changeRecv returns sig with Recv prepended to Params().
+func changeRecv(sig *types.Signature) *types.Signature {
+ params := sig.Params()
+ n := params.Len()
+ p2 := make([]*types.Var, n+1)
+ p2[0] = sig.Recv()
+ for i := 0; i < n; i++ {
+ p2[i+1] = params.At(i)
+ }
+ return types.NewSignature(nil, types.NewTuple(p2...), sig.Results(), sig.Variadic())
+}
+
+func (c *rtypeMethodByNameConstraint) solve(a *analysis, delta *nodeset) {
+ for _, x := range delta.AppendTo(a.deltaSpace) {
+ tObj := nodeid(x)
+ T := a.nodes[tObj].obj.data.(types.Type)
+
+ isIface := isInterface(T)
+
+ // We don't use Lookup(c.name) when c.name != "" to avoid
+ // ambiguity: >1 unexported methods could match.
+ mset := a.prog.MethodSets.MethodSet(T)
+ for i, n := 0, mset.Len(); i < n; i++ {
+ sel := mset.At(i)
+ if c.name == "" || c.name == sel.Obj().Name() {
+ // type Method struct {
+ // 0 __identity__
+ // 1 Name string
+ // 2 PkgPath string
+ // 3 Type Type
+ // 4 Func Value
+ // 5 Index int
+ // }
+
+ var sig *types.Signature
+ var fn *ssa.Function
+ if isIface {
+ sig = sel.Type().(*types.Signature)
+ } else {
+ fn = a.prog.Method(sel)
+ // move receiver to params[0]
+ sig = changeRecv(fn.Signature)
+ }
+
+ // a.offsetOf(Type) is 3.
+ if id := c.result + 3; a.addLabel(id, a.makeRtype(sig)) {
+ a.addWork(id)
+ }
+ if fn != nil {
+ // a.offsetOf(Func) is 4.
+ if id := c.result + 4; a.addLabel(id, a.objectNode(nil, fn)) {
+ a.addWork(id)
+ }
+ }
+ }
+ }
+ }
+}
+
+func ext۰reflect۰rtype۰MethodByName(a *analysis, cgn *cgnode) {
+ // If we have access to the callsite,
+ // and the argument is a string constant,
+ // return only that method.
+ var name string
+ if site := cgn.callersite; site != nil {
+ if c, ok := site.instr.Common().Args[0].(*ssa.Const); ok {
+ name = exact.StringVal(c.Value)
+ }
+ }
+
+ a.addConstraint(&rtypeMethodByNameConstraint{
+ cgn: cgn,
+ name: name,
+ t: a.funcParams(cgn.obj),
+ result: a.funcResults(cgn.obj),
+ })
+}
+
+func ext۰reflect۰rtype۰Method(a *analysis, cgn *cgnode) {
+ // No-one ever calls Method with a constant argument,
+ // so we don't specialize that case.
+ a.addConstraint(&rtypeMethodByNameConstraint{
+ cgn: cgn,
+ t: a.funcParams(cgn.obj),
+ result: a.funcResults(cgn.obj),
+ })
+}
+
+// typeHeight returns the "height" of the type, which is roughly
+// speaking the number of chan, map, pointer and slice type constructors
+// at the root of T; these are the four type kinds that can be created
+// via reflection. Chan and map constructors are counted as double the
+// height of slice and pointer constructors since they are less often
+// deeply nested.
+//
+// The solver rules for type constructors must somehow bound the set of
+// types they create to ensure termination of the algorithm in cases
+// where the output of a type constructor flows to its input, e.g.
+//
+// func f(t reflect.Type) {
+// f(reflect.PtrTo(t))
+// }
+//
+// It does this by limiting the type height to k, but this still leaves
+// a potentially exponential (4^k) number of of types that may be
+// enumerated in pathological cases.
+//
+func typeHeight(T types.Type) int {
+ switch T := T.(type) {
+ case *types.Chan:
+ return 2 + typeHeight(T.Elem())
+ case *types.Map:
+ k := typeHeight(T.Key())
+ v := typeHeight(T.Elem())
+ if v > k {
+ k = v // max(k, v)
+ }
+ return 2 + k
+ case *types.Slice:
+ return 1 + typeHeight(T.Elem())
+ case *types.Pointer:
+ return 1 + typeHeight(T.Elem())
+ }
+ return 0
+}
+
+func typeTooHigh(T types.Type) bool {
+ return typeHeight(T) > 3
+}
diff --git a/vendor/golang.org/x/tools/go/pointer/solve.go b/vendor/golang.org/x/tools/go/pointer/solve.go
new file mode 100644
index 0000000..ad1a65f
--- /dev/null
+++ b/vendor/golang.org/x/tools/go/pointer/solve.go
@@ -0,0 +1,371 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package pointer
+
+// This file defines a naive Andersen-style solver for the inclusion
+// constraint system.
+
+import (
+ "fmt"
+
+ "golang.org/x/tools/go/types"
+)
+
+type solverState struct {
+ complex []constraint // complex constraints attached to this node
+ copyTo nodeset // simple copy constraint edges
+ pts nodeset // points-to set of this node
+ prevPTS nodeset // pts(n) in previous iteration (for difference propagation)
+}
+
+func (a *analysis) solve() {
+ start("Solving")
+ if a.log != nil {
+ fmt.Fprintf(a.log, "\n\n==== Solving constraints\n\n")
+ }
+
+ // Solver main loop.
+ var delta nodeset
+ for {
+ // Add new constraints to the graph:
+ // static constraints from SSA on round 1,
+ // dynamic constraints from reflection thereafter.
+ a.processNewConstraints()
+
+ var x int
+ if !a.work.TakeMin(&x) {
+ break // empty
+ }
+ id := nodeid(x)
+ if a.log != nil {
+ fmt.Fprintf(a.log, "\tnode n%d\n", id)
+ }
+
+ n := a.nodes[id]
+
+ // Difference propagation.
+ delta.Difference(&n.solve.pts.Sparse, &n.solve.prevPTS.Sparse)
+ if delta.IsEmpty() {
+ continue
+ }
+ if a.log != nil {
+ fmt.Fprintf(a.log, "\t\tpts(n%d : %s) = %s + %s\n",
+ id, n.typ, &delta, &n.solve.prevPTS)
+ }
+ n.solve.prevPTS.Copy(&n.solve.pts.Sparse)
+
+ // Apply all resolution rules attached to n.
+ a.solveConstraints(n, &delta)
+
+ if a.log != nil {
+ fmt.Fprintf(a.log, "\t\tpts(n%d) = %s\n", id, &n.solve.pts)
+ }
+ }
+
+ if !a.nodes[0].solve.pts.IsEmpty() {
+ panic(fmt.Sprintf("pts(0) is nonempty: %s", &a.nodes[0].solve.pts))
+ }
+
+ // Release working state (but keep final PTS).
+ for _, n := range a.nodes {
+ n.solve.complex = nil
+ n.solve.copyTo.Clear()
+ n.solve.prevPTS.Clear()
+ }
+
+ if a.log != nil {
+ fmt.Fprintf(a.log, "Solver done\n")
+
+ // Dump solution.
+ for i, n := range a.nodes {
+ if !n.solve.pts.IsEmpty() {
+ fmt.Fprintf(a.log, "pts(n%d) = %s : %s\n", i, &n.solve.pts, n.typ)
+ }
+ }
+ }
+ stop("Solving")
+}
+
+// processNewConstraints takes the new constraints from a.constraints
+// and adds them to the graph, ensuring
+// that new constraints are applied to pre-existing labels and
+// that pre-existing constraints are applied to new labels.
+//
+func (a *analysis) processNewConstraints() {
+ // Take the slice of new constraints.
+ // (May grow during call to solveConstraints.)
+ constraints := a.constraints
+ a.constraints = nil
+
+ // Initialize points-to sets from addr-of (base) constraints.
+ for _, c := range constraints {
+ if c, ok := c.(*addrConstraint); ok {
+ dst := a.nodes[c.dst]
+ dst.solve.pts.add(c.src)
+
+ // Populate the worklist with nodes that point to
+ // something initially (due to addrConstraints) and
+ // have other constraints attached.
+ // (A no-op in round 1.)
+ if !dst.solve.copyTo.IsEmpty() || len(dst.solve.complex) > 0 {
+ a.addWork(c.dst)
+ }
+ }
+ }
+
+ // Attach simple (copy) and complex constraints to nodes.
+ var stale nodeset
+ for _, c := range constraints {
+ var id nodeid
+ switch c := c.(type) {
+ case *addrConstraint:
+ // base constraints handled in previous loop
+ continue
+ case *copyConstraint:
+ // simple (copy) constraint
+ id = c.src
+ a.nodes[id].solve.copyTo.add(c.dst)
+ default:
+ // complex constraint
+ id = c.ptr()
+ solve := a.nodes[id].solve
+ solve.complex = append(solve.complex, c)
+ }
+
+ if n := a.nodes[id]; !n.solve.pts.IsEmpty() {
+ if !n.solve.prevPTS.IsEmpty() {
+ stale.add(id)
+ }
+ a.addWork(id)
+ }
+ }
+ // Apply new constraints to pre-existing PTS labels.
+ var space [50]int
+ for _, id := range stale.AppendTo(space[:0]) {
+ n := a.nodes[nodeid(id)]
+ a.solveConstraints(n, &n.solve.prevPTS)
+ }
+}
+
+// solveConstraints applies each resolution rule attached to node n to
+// the set of labels delta. It may generate new constraints in
+// a.constraints.
+//
+func (a *analysis) solveConstraints(n *node, delta *nodeset) {
+ if delta.IsEmpty() {
+ return
+ }
+
+ // Process complex constraints dependent on n.
+ for _, c := range n.solve.complex {
+ if a.log != nil {
+ fmt.Fprintf(a.log, "\t\tconstraint %s\n", c)
+ }
+ c.solve(a, delta)
+ }
+
+ // Process copy constraints.
+ var copySeen nodeset
+ for _, x := range n.solve.copyTo.AppendTo(a.deltaSpace) {
+ mid := nodeid(x)
+ if copySeen.add(mid) {
+ if a.nodes[mid].solve.pts.addAll(delta) {
+ a.addWork(mid)
+ }
+ }
+ }
+}
+
+// addLabel adds label to the points-to set of ptr and reports whether the set grew.
+func (a *analysis) addLabel(ptr, label nodeid) bool {
+ b := a.nodes[ptr].solve.pts.add(label)
+ if b && a.log != nil {
+ fmt.Fprintf(a.log, "\t\tpts(n%d) += n%d\n", ptr, label)
+ }
+ return b
+}
+
+func (a *analysis) addWork(id nodeid) {
+ a.work.Insert(int(id))
+ if a.log != nil {
+ fmt.Fprintf(a.log, "\t\twork: n%d\n", id)
+ }
+}
+
+// onlineCopy adds a copy edge. It is called online, i.e. during
+// solving, so it adds edges and pts members directly rather than by
+// instantiating a 'constraint'.
+//
+// The size of the copy is implicitly 1.
+// It returns true if pts(dst) changed.
+//
+func (a *analysis) onlineCopy(dst, src nodeid) bool {
+ if dst != src {
+ if nsrc := a.nodes[src]; nsrc.solve.copyTo.add(dst) {
+ if a.log != nil {
+ fmt.Fprintf(a.log, "\t\t\tdynamic copy n%d <- n%d\n", dst, src)
+ }
+ // TODO(adonovan): most calls to onlineCopy
+ // are followed by addWork, possibly batched
+ // via a 'changed' flag; see if there's a
+ // noticeable penalty to calling addWork here.
+ return a.nodes[dst].solve.pts.addAll(&nsrc.solve.pts)
+ }
+ }
+ return false
+}
+
+// Returns sizeof.
+// Implicitly adds nodes to worklist.
+//
+// TODO(adonovan): now that we support a.copy() during solving, we
+// could eliminate onlineCopyN, but it's much slower. Investigate.
+//
+func (a *analysis) onlineCopyN(dst, src nodeid, sizeof uint32) uint32 {
+ for i := uint32(0); i < sizeof; i++ {
+ if a.onlineCopy(dst, src) {
+ a.addWork(dst)
+ }
+ src++
+ dst++
+ }
+ return sizeof
+}
+
+func (c *loadConstraint) solve(a *analysis, delta *nodeset) {
+ var changed bool
+ for _, x := range delta.AppendTo(a.deltaSpace) {
+ k := nodeid(x)
+ koff := k + nodeid(c.offset)
+ if a.onlineCopy(c.dst, koff) {
+ changed = true
+ }
+ }
+ if changed {
+ a.addWork(c.dst)
+ }
+}
+
+func (c *storeConstraint) solve(a *analysis, delta *nodeset) {
+ for _, x := range delta.AppendTo(a.deltaSpace) {
+ k := nodeid(x)
+ koff := k + nodeid(c.offset)
+ if a.onlineCopy(koff, c.src) {
+ a.addWork(koff)
+ }
+ }
+}
+
+func (c *offsetAddrConstraint) solve(a *analysis, delta *nodeset) {
+ dst := a.nodes[c.dst]
+ for _, x := range delta.AppendTo(a.deltaSpace) {
+ k := nodeid(x)
+ if dst.solve.pts.add(k + nodeid(c.offset)) {
+ a.addWork(c.dst)
+ }
+ }
+}
+
+func (c *typeFilterConstraint) solve(a *analysis, delta *nodeset) {
+ for _, x := range delta.AppendTo(a.deltaSpace) {
+ ifaceObj := nodeid(x)
+ tDyn, _, indirect := a.taggedValue(ifaceObj)
+ if indirect {
+ // TODO(adonovan): we'll need to implement this
+ // when we start creating indirect tagged objects.
+ panic("indirect tagged object")
+ }
+
+ if types.AssignableTo(tDyn, c.typ) {
+ if a.addLabel(c.dst, ifaceObj) {
+ a.addWork(c.dst)
+ }
+ }
+ }
+}
+
+func (c *untagConstraint) solve(a *analysis, delta *nodeset) {
+ predicate := types.AssignableTo
+ if c.exact {
+ predicate = types.Identical
+ }
+ for _, x := range delta.AppendTo(a.deltaSpace) {
+ ifaceObj := nodeid(x)
+ tDyn, v, indirect := a.taggedValue(ifaceObj)
+ if indirect {
+ // TODO(adonovan): we'll need to implement this
+ // when we start creating indirect tagged objects.
+ panic("indirect tagged object")
+ }
+
+ if predicate(tDyn, c.typ) {
+ // Copy payload sans tag to dst.
+ //
+ // TODO(adonovan): opt: if tDyn is
+ // nonpointerlike we can skip this entire
+ // constraint, perhaps. We only care about
+ // pointers among the fields.
+ a.onlineCopyN(c.dst, v, a.sizeof(tDyn))
+ }
+ }
+}
+
+func (c *invokeConstraint) solve(a *analysis, delta *nodeset) {
+ for _, x := range delta.AppendTo(a.deltaSpace) {
+ ifaceObj := nodeid(x)
+ tDyn, v, indirect := a.taggedValue(ifaceObj)
+ if indirect {
+ // TODO(adonovan): we may need to implement this if
+ // we ever apply invokeConstraints to reflect.Value PTSs,
+ // e.g. for (reflect.Value).Call.
+ panic("indirect tagged object")
+ }
+
+ // Look up the concrete method.
+ fn := a.prog.LookupMethod(tDyn, c.method.Pkg(), c.method.Name())
+ if fn == nil {
+ panic(fmt.Sprintf("n%d: no ssa.Function for %s", c.iface, c.method))
+ }
+ sig := fn.Signature
+
+ fnObj := a.globalobj[fn] // dynamic calls use shared contour
+ if fnObj == 0 {
+ // a.objectNode(fn) was not called during gen phase.
+ panic(fmt.Sprintf("a.globalobj[%s]==nil", fn))
+ }
+
+ // Make callsite's fn variable point to identity of
+ // concrete method. (There's no need to add it to
+ // worklist since it never has attached constraints.)
+ a.addLabel(c.params, fnObj)
+
+ // Extract value and connect to method's receiver.
+ // Copy payload to method's receiver param (arg0).
+ arg0 := a.funcParams(fnObj)
+ recvSize := a.sizeof(sig.Recv().Type())
+ a.onlineCopyN(arg0, v, recvSize)
+
+ src := c.params + 1 // skip past identity
+ dst := arg0 + nodeid(recvSize)
+
+ // Copy caller's argument block to method formal parameters.
+ paramsSize := a.sizeof(sig.Params())
+ a.onlineCopyN(dst, src, paramsSize)
+ src += nodeid(paramsSize)
+ dst += nodeid(paramsSize)
+
+ // Copy method results to caller's result block.
+ resultsSize := a.sizeof(sig.Results())
+ a.onlineCopyN(src, dst, resultsSize)
+ }
+}
+
+func (c *addrConstraint) solve(a *analysis, delta *nodeset) {
+ panic("addr is not a complex constraint")
+}
+
+func (c *copyConstraint) solve(a *analysis, delta *nodeset) {
+ panic("copy is not a complex constraint")
+}
diff --git a/vendor/golang.org/x/tools/go/pointer/util.go b/vendor/golang.org/x/tools/go/pointer/util.go
new file mode 100644
index 0000000..d4ccbb5
--- /dev/null
+++ b/vendor/golang.org/x/tools/go/pointer/util.go
@@ -0,0 +1,314 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package pointer
+
+import (
+ "bytes"
+ "fmt"
+ "log"
+ "os"
+ "os/exec"
+ "runtime"
+ "time"
+
+ "golang.org/x/tools/container/intsets"
+ "golang.org/x/tools/go/types"
+)
+
+// CanPoint reports whether the type T is pointerlike,
+// for the purposes of this analysis.
+func CanPoint(T types.Type) bool {
+ switch T := T.(type) {
+ case *types.Named:
+ if obj := T.Obj(); obj.Name() == "Value" && obj.Pkg().Path() == "reflect" {
+ return true // treat reflect.Value like interface{}
+ }
+ return CanPoint(T.Underlying())
+
+ case *types.Pointer, *types.Interface, *types.Map, *types.Chan, *types.Signature, *types.Slice:
+ return true
+ }
+
+ return false // array struct tuple builtin basic
+}
+
+// CanHaveDynamicTypes reports whether the type T can "hold" dynamic types,
+// i.e. is an interface (incl. reflect.Type) or a reflect.Value.
+//
+func CanHaveDynamicTypes(T types.Type) bool {
+ switch T := T.(type) {
+ case *types.Named:
+ if obj := T.Obj(); obj.Name() == "Value" && obj.Pkg().Path() == "reflect" {
+ return true // reflect.Value
+ }
+ return CanHaveDynamicTypes(T.Underlying())
+ case *types.Interface:
+ return true
+ }
+ return false
+}
+
+func isInterface(T types.Type) bool { return types.IsInterface(T) }
+
+// mustDeref returns the element type of its argument, which must be a
+// pointer; panic ensues otherwise.
+func mustDeref(typ types.Type) types.Type {
+ return typ.Underlying().(*types.Pointer).Elem()
+}
+
+// deref returns a pointer's element type; otherwise it returns typ.
+func deref(typ types.Type) types.Type {
+ if p, ok := typ.Underlying().(*types.Pointer); ok {
+ return p.Elem()
+ }
+ return typ
+}
+
+// A fieldInfo describes one subelement (node) of the flattening-out
+// of a type T: the subelement's type and its path from the root of T.
+//
+// For example, for this type:
+// type line struct{ points []struct{x, y int} }
+// flatten() of the inner struct yields the following []fieldInfo:
+// struct{ x, y int } ""
+// int ".x"
+// int ".y"
+// and flatten(line) yields:
+// struct{ points []struct{x, y int} } ""
+// struct{ x, y int } ".points[*]"
+// int ".points[*].x
+// int ".points[*].y"
+//
+type fieldInfo struct {
+ typ types.Type
+
+ // op and tail describe the path to the element (e.g. ".a#2.b[*].c").
+ op interface{} // *Array: true; *Tuple: int; *Struct: *types.Var; *Named: nil
+ tail *fieldInfo
+}
+
+// path returns a user-friendly string describing the subelement path.
+//
+func (fi *fieldInfo) path() string {
+ var buf bytes.Buffer
+ for p := fi; p != nil; p = p.tail {
+ switch op := p.op.(type) {
+ case bool:
+ fmt.Fprintf(&buf, "[*]")
+ case int:
+ fmt.Fprintf(&buf, "#%d", op)
+ case *types.Var:
+ fmt.Fprintf(&buf, ".%s", op.Name())
+ }
+ }
+ return buf.String()
+}
+
+// flatten returns a list of directly contained fields in the preorder
+// traversal of the type tree of t. The resulting elements are all
+// scalars (basic types or pointerlike types), except for struct/array
+// "identity" nodes, whose type is that of the aggregate.
+//
+// reflect.Value is considered pointerlike, similar to interface{}.
+//
+// Callers must not mutate the result.
+//
+func (a *analysis) flatten(t types.Type) []*fieldInfo {
+ fl, ok := a.flattenMemo[t]
+ if !ok {
+ switch t := t.(type) {
+ case *types.Named:
+ u := t.Underlying()
+ if isInterface(u) {
+ // Debuggability hack: don't remove
+ // the named type from interfaces as
+ // they're very verbose.
+ fl = append(fl, &fieldInfo{typ: t})
+ } else {
+ fl = a.flatten(u)
+ }
+
+ case *types.Basic,
+ *types.Signature,
+ *types.Chan,
+ *types.Map,
+ *types.Interface,
+ *types.Slice,
+ *types.Pointer:
+ fl = append(fl, &fieldInfo{typ: t})
+
+ case *types.Array:
+ fl = append(fl, &fieldInfo{typ: t}) // identity node
+ for _, fi := range a.flatten(t.Elem()) {
+ fl = append(fl, &fieldInfo{typ: fi.typ, op: true, tail: fi})
+ }
+
+ case *types.Struct:
+ fl = append(fl, &fieldInfo{typ: t}) // identity node
+ for i, n := 0, t.NumFields(); i < n; i++ {
+ f := t.Field(i)
+ for _, fi := range a.flatten(f.Type()) {
+ fl = append(fl, &fieldInfo{typ: fi.typ, op: f, tail: fi})
+ }
+ }
+
+ case *types.Tuple:
+ // No identity node: tuples are never address-taken.
+ n := t.Len()
+ if n == 1 {
+ // Don't add a fieldInfo link for singletons,
+ // e.g. in params/results.
+ fl = append(fl, a.flatten(t.At(0).Type())...)
+ } else {
+ for i := 0; i < n; i++ {
+ f := t.At(i)
+ for _, fi := range a.flatten(f.Type()) {
+ fl = append(fl, &fieldInfo{typ: fi.typ, op: i, tail: fi})
+ }
+ }
+ }
+
+ default:
+ panic(t)
+ }
+
+ a.flattenMemo[t] = fl
+ }
+
+ return fl
+}
+
+// sizeof returns the number of pointerlike abstractions (nodes) in the type t.
+func (a *analysis) sizeof(t types.Type) uint32 {
+ return uint32(len(a.flatten(t)))
+}
+
+// shouldTrack reports whether object type T contains (recursively)
+// any fields whose addresses should be tracked.
+func (a *analysis) shouldTrack(T types.Type) bool {
+ if a.track == trackAll {
+ return true // fast path
+ }
+ track, ok := a.trackTypes[T]
+ if !ok {
+ a.trackTypes[T] = true // break cycles conservatively
+ // NB: reflect.Value, reflect.Type are pre-populated to true.
+ for _, fi := range a.flatten(T) {
+ switch ft := fi.typ.Underlying().(type) {
+ case *types.Interface, *types.Signature:
+ track = true // needed for callgraph
+ case *types.Basic:
+ // no-op
+ case *types.Chan:
+ track = a.track&trackChan != 0 || a.shouldTrack(ft.Elem())
+ case *types.Map:
+ track = a.track&trackMap != 0 || a.shouldTrack(ft.Key()) || a.shouldTrack(ft.Elem())
+ case *types.Slice:
+ track = a.track&trackSlice != 0 || a.shouldTrack(ft.Elem())
+ case *types.Pointer:
+ track = a.track&trackPtr != 0 || a.shouldTrack(ft.Elem())
+ case *types.Array, *types.Struct:
+ // No need to look at field types since they will follow (flattened).
+ default:
+ // Includes *types.Tuple, which are never address-taken.
+ panic(ft)
+ }
+ if track {
+ break
+ }
+ }
+ a.trackTypes[T] = track
+ if !track && a.log != nil {
+ fmt.Fprintf(a.log, "\ttype not tracked: %s\n", T)
+ }
+ }
+ return track
+}
+
+// offsetOf returns the (abstract) offset of field index within struct
+// or tuple typ.
+func (a *analysis) offsetOf(typ types.Type, index int) uint32 {
+ var offset uint32
+ switch t := typ.Underlying().(type) {
+ case *types.Tuple:
+ for i := 0; i < index; i++ {
+ offset += a.sizeof(t.At(i).Type())
+ }
+ case *types.Struct:
+ offset++ // the node for the struct itself
+ for i := 0; i < index; i++ {
+ offset += a.sizeof(t.Field(i).Type())
+ }
+ default:
+ panic(fmt.Sprintf("offsetOf(%s : %T)", typ, typ))
+ }
+ return offset
+}
+
+// sliceToArray returns the type representing the arrays to which
+// slice type slice points.
+func sliceToArray(slice types.Type) *types.Array {
+ return types.NewArray(slice.Underlying().(*types.Slice).Elem(), 1)
+}
+
+// Node set -------------------------------------------------------------------
+
+type nodeset struct {
+ intsets.Sparse
+}
+
+func (ns *nodeset) String() string {
+ var buf bytes.Buffer
+ buf.WriteRune('{')
+ var space [50]int
+ for i, n := range ns.AppendTo(space[:0]) {
+ if i > 0 {
+ buf.WriteString(", ")
+ }
+ buf.WriteRune('n')
+ fmt.Fprintf(&buf, "%d", n)
+ }
+ buf.WriteRune('}')
+ return buf.String()
+}
+
+func (ns *nodeset) add(n nodeid) bool {
+ return ns.Sparse.Insert(int(n))
+}
+
+func (x *nodeset) addAll(y *nodeset) bool {
+ return x.UnionWith(&y.Sparse)
+}
+
+// Profiling & debugging -------------------------------------------------------
+
+var timers = make(map[string]time.Time)
+
+func start(name string) {
+ if debugTimers {
+ timers[name] = time.Now()
+ log.Printf("%s...\n", name)
+ }
+}
+
+func stop(name string) {
+ if debugTimers {
+ log.Printf("%s took %s\n", name, time.Since(timers[name]))
+ }
+}
+
+// diff runs the command "diff a b" and reports its success.
+func diff(a, b string) bool {
+ var cmd *exec.Cmd
+ switch runtime.GOOS {
+ case "plan9":
+ cmd = exec.Command("/bin/diff", "-c", a, b)
+ default:
+ cmd = exec.Command("/usr/bin/diff", "-u", a, b)
+ }
+ cmd.Stdout = os.Stderr
+ cmd.Stderr = os.Stderr
+ return cmd.Run() == nil
+}
diff --git a/vendor/golang.org/x/tools/go/ssa/blockopt.go b/vendor/golang.org/x/tools/go/ssa/blockopt.go
new file mode 100644
index 0000000..e79260a
--- /dev/null
+++ b/vendor/golang.org/x/tools/go/ssa/blockopt.go
@@ -0,0 +1,187 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package ssa
+
+// Simple block optimizations to simplify the control flow graph.
+
+// TODO(adonovan): opt: instead of creating several "unreachable" blocks
+// per function in the Builder, reuse a single one (e.g. at Blocks[1])
+// to reduce garbage.
+
+import (
+ "fmt"
+ "os"
+)
+
+// If true, perform sanity checking and show progress at each
+// successive iteration of optimizeBlocks. Very verbose.
+const debugBlockOpt = false
+
+// markReachable sets Index=-1 for all blocks reachable from b.
+func markReachable(b *BasicBlock) {
+ b.Index = -1
+ for _, succ := range b.Succs {
+ if succ.Index == 0 {
+ markReachable(succ)
+ }
+ }
+}
+
+// deleteUnreachableBlocks marks all reachable blocks of f and
+// eliminates (nils) all others, including possibly cyclic subgraphs.
+//
+func deleteUnreachableBlocks(f *Function) {
+ const white, black = 0, -1
+ // We borrow b.Index temporarily as the mark bit.
+ for _, b := range f.Blocks {
+ b.Index = white
+ }
+ markReachable(f.Blocks[0])
+ if f.Recover != nil {
+ markReachable(f.Recover)
+ }
+ for i, b := range f.Blocks {
+ if b.Index == white {
+ for _, c := range b.Succs {
+ if c.Index == black {
+ c.removePred(b) // delete white->black edge
+ }
+ }
+ if debugBlockOpt {
+ fmt.Fprintln(os.Stderr, "unreachable", b)
+ }
+ f.Blocks[i] = nil // delete b
+ }
+ }
+ f.removeNilBlocks()
+}
+
+// jumpThreading attempts to apply simple jump-threading to block b,
+// in which a->b->c become a->c if b is just a Jump.
+// The result is true if the optimization was applied.
+//
+func jumpThreading(f *Function, b *BasicBlock) bool {
+ if b.Index == 0 {
+ return false // don't apply to entry block
+ }
+ if b.Instrs == nil {
+ return false
+ }
+ if _, ok := b.Instrs[0].(*Jump); !ok {
+ return false // not just a jump
+ }
+ c := b.Succs[0]
+ if c == b {
+ return false // don't apply to degenerate jump-to-self.
+ }
+ if c.hasPhi() {
+ return false // not sound without more effort
+ }
+ for j, a := range b.Preds {
+ a.replaceSucc(b, c)
+
+ // If a now has two edges to c, replace its degenerate If by Jump.
+ if len(a.Succs) == 2 && a.Succs[0] == c && a.Succs[1] == c {
+ jump := new(Jump)
+ jump.setBlock(a)
+ a.Instrs[len(a.Instrs)-1] = jump
+ a.Succs = a.Succs[:1]
+ c.removePred(b)
+ } else {
+ if j == 0 {
+ c.replacePred(b, a)
+ } else {
+ c.Preds = append(c.Preds, a)
+ }
+ }
+
+ if debugBlockOpt {
+ fmt.Fprintln(os.Stderr, "jumpThreading", a, b, c)
+ }
+ }
+ f.Blocks[b.Index] = nil // delete b
+ return true
+}
+
+// fuseBlocks attempts to apply the block fusion optimization to block
+// a, in which a->b becomes ab if len(a.Succs)==len(b.Preds)==1.
+// The result is true if the optimization was applied.
+//
+func fuseBlocks(f *Function, a *BasicBlock) bool {
+ if len(a.Succs) != 1 {
+ return false
+ }
+ b := a.Succs[0]
+ if len(b.Preds) != 1 {
+ return false
+ }
+
+ // Degenerate &&/|| ops may result in a straight-line CFG
+ // containing φ-nodes. (Ideally we'd replace such them with
+ // their sole operand but that requires Referrers, built later.)
+ if b.hasPhi() {
+ return false // not sound without further effort
+ }
+
+ // Eliminate jump at end of A, then copy all of B across.
+ a.Instrs = append(a.Instrs[:len(a.Instrs)-1], b.Instrs...)
+ for _, instr := range b.Instrs {
+ instr.setBlock(a)
+ }
+
+ // A inherits B's successors
+ a.Succs = append(a.succs2[:0], b.Succs...)
+
+ // Fix up Preds links of all successors of B.
+ for _, c := range b.Succs {
+ c.replacePred(b, a)
+ }
+
+ if debugBlockOpt {
+ fmt.Fprintln(os.Stderr, "fuseBlocks", a, b)
+ }
+
+ f.Blocks[b.Index] = nil // delete b
+ return true
+}
+
+// optimizeBlocks() performs some simple block optimizations on a
+// completed function: dead block elimination, block fusion, jump
+// threading.
+//
+func optimizeBlocks(f *Function) {
+ deleteUnreachableBlocks(f)
+
+ // Loop until no further progress.
+ changed := true
+ for changed {
+ changed = false
+
+ if debugBlockOpt {
+ f.WriteTo(os.Stderr)
+ mustSanityCheck(f, nil)
+ }
+
+ for _, b := range f.Blocks {
+ // f.Blocks will temporarily contain nils to indicate
+ // deleted blocks; we remove them at the end.
+ if b == nil {
+ continue
+ }
+
+ // Fuse blocks. b->c becomes bc.
+ if fuseBlocks(f, b) {
+ changed = true
+ }
+
+ // a->b->c becomes a->c if b contains only a Jump.
+ if jumpThreading(f, b) {
+ changed = true
+ continue // (b was disconnected)
+ }
+ }
+ }
+ f.removeNilBlocks()
+}
diff --git a/vendor/golang.org/x/tools/go/ssa/builder.go b/vendor/golang.org/x/tools/go/ssa/builder.go
new file mode 100644
index 0000000..5b8ce0e
--- /dev/null
+++ b/vendor/golang.org/x/tools/go/ssa/builder.go
@@ -0,0 +1,2370 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package ssa
+
+// This file implements the BUILD phase of SSA construction.
+//
+// SSA construction has two phases, CREATE and BUILD. In the CREATE phase
+// (create.go), all packages are constructed and type-checked and
+// definitions of all package members are created, method-sets are
+// computed, and wrapper methods are synthesized.
+// ssa.Packages are created in arbitrary order.
+//
+// In the BUILD phase (builder.go), the builder traverses the AST of
+// each Go source function and generates SSA instructions for the
+// function body. Initializer expressions for package-level variables
+// are emitted to the package's init() function in the order specified
+// by go/types.Info.InitOrder, then code for each function in the
+// package is generated in lexical order.
+// The BUILD phases for distinct packages are independent and are
+// executed in parallel.
+//
+// TODO(adonovan): indeed, building functions is now embarrassingly parallel.
+// Audit for concurrency then benchmark using more goroutines.
+//
+// The builder's and Program's indices (maps) are populated and
+// mutated during the CREATE phase, but during the BUILD phase they
+// remain constant. The sole exception is Prog.methodSets and its
+// related maps, which are protected by a dedicated mutex.
+
+import (
+ "fmt"
+ "go/ast"
+ "go/token"
+ "os"
+ "sync"
+ "sync/atomic"
+
+ "golang.org/x/tools/go/exact"
+ "golang.org/x/tools/go/types"
+)
+
+type opaqueType struct {
+ types.Type
+ name string
+}
+
+func (t *opaqueType) String() string { return t.name }
+
+var (
+ varOk = newVar("ok", tBool)
+ varIndex = newVar("index", tInt)
+
+ // Type constants.
+ tBool = types.Typ[types.Bool]
+ tByte = types.Typ[types.Byte]
+ tInt = types.Typ[types.Int]
+ tInvalid = types.Typ[types.Invalid]
+ tString = types.Typ[types.String]
+ tUntypedNil = types.Typ[types.UntypedNil]
+ tRangeIter = &opaqueType{nil, "iter"} // the type of all "range" iterators
+ tEface = new(types.Interface)
+
+ // SSA Value constants.
+ vZero = intConst(0)
+ vOne = intConst(1)
+ vTrue = NewConst(exact.MakeBool(true), tBool)
+)
+
+// builder holds state associated with the package currently being built.
+// Its methods contain all the logic for AST-to-SSA conversion.
+type builder struct{}
+
+// cond emits to fn code to evaluate boolean condition e and jump
+// to t or f depending on its value, performing various simplifications.
+//
+// Postcondition: fn.currentBlock is nil.
+//
+func (b *builder) cond(fn *Function, e ast.Expr, t, f *BasicBlock) {
+ switch e := e.(type) {
+ case *ast.ParenExpr:
+ b.cond(fn, e.X, t, f)
+ return
+
+ case *ast.BinaryExpr:
+ switch e.Op {
+ case token.LAND:
+ ltrue := fn.newBasicBlock("cond.true")
+ b.cond(fn, e.X, ltrue, f)
+ fn.currentBlock = ltrue
+ b.cond(fn, e.Y, t, f)
+ return
+
+ case token.LOR:
+ lfalse := fn.newBasicBlock("cond.false")
+ b.cond(fn, e.X, t, lfalse)
+ fn.currentBlock = lfalse
+ b.cond(fn, e.Y, t, f)
+ return
+ }
+
+ case *ast.UnaryExpr:
+ if e.Op == token.NOT {
+ b.cond(fn, e.X, f, t)
+ return
+ }
+ }
+
+ // A traditional compiler would simplify "if false" (etc) here
+ // but we do not, for better fidelity to the source code.
+ //
+ // The value of a constant condition may be platform-specific,
+ // and may cause blocks that are reachable in some configuration
+ // to be hidden from subsequent analyses such as bug-finding tools.
+ emitIf(fn, b.expr(fn, e), t, f)
+}
+
+// logicalBinop emits code to fn to evaluate e, a &&- or
+// ||-expression whose reified boolean value is wanted.
+// The value is returned.
+//
+func (b *builder) logicalBinop(fn *Function, e *ast.BinaryExpr) Value {
+ rhs := fn.newBasicBlock("binop.rhs")
+ done := fn.newBasicBlock("binop.done")
+
+ // T(e) = T(e.X) = T(e.Y) after untyped constants have been
+ // eliminated.
+ // TODO(adonovan): not true; MyBool==MyBool yields UntypedBool.
+ t := fn.Pkg.typeOf(e)
+
+ var short Value // value of the short-circuit path
+ switch e.Op {
+ case token.LAND:
+ b.cond(fn, e.X, rhs, done)
+ short = NewConst(exact.MakeBool(false), t)
+
+ case token.LOR:
+ b.cond(fn, e.X, done, rhs)
+ short = NewConst(exact.MakeBool(true), t)
+ }
+
+ // Is rhs unreachable?
+ if rhs.Preds == nil {
+ // Simplify false&&y to false, true||y to true.
+ fn.currentBlock = done
+ return short
+ }
+
+ // Is done unreachable?
+ if done.Preds == nil {
+ // Simplify true&&y (or false||y) to y.
+ fn.currentBlock = rhs
+ return b.expr(fn, e.Y)
+ }
+
+ // All edges from e.X to done carry the short-circuit value.
+ var edges []Value
+ for _ = range done.Preds {
+ edges = append(edges, short)
+ }
+
+ // The edge from e.Y to done carries the value of e.Y.
+ fn.currentBlock = rhs
+ edges = append(edges, b.expr(fn, e.Y))
+ emitJump(fn, done)
+ fn.currentBlock = done
+
+ phi := &Phi{Edges: edges, Comment: e.Op.String()}
+ phi.pos = e.OpPos
+ phi.typ = t
+ return done.emit(phi)
+}
+
+// exprN lowers a multi-result expression e to SSA form, emitting code
+// to fn and returning a single Value whose type is a *types.Tuple.
+// The caller must access the components via Extract.
+//
+// Multi-result expressions include CallExprs in a multi-value
+// assignment or return statement, and "value,ok" uses of
+// TypeAssertExpr, IndexExpr (when X is a map), and UnaryExpr (when Op
+// is token.ARROW).
+//
+func (b *builder) exprN(fn *Function, e ast.Expr) Value {
+ typ := fn.Pkg.typeOf(e).(*types.Tuple)
+ switch e := e.(type) {
+ case *ast.ParenExpr:
+ return b.exprN(fn, e.X)
+
+ case *ast.CallExpr:
+ // Currently, no built-in function nor type conversion
+ // has multiple results, so we can avoid some of the
+ // cases for single-valued CallExpr.
+ var c Call
+ b.setCall(fn, e, &c.Call)
+ c.typ = typ
+ return fn.emit(&c)
+
+ case *ast.IndexExpr:
+ mapt := fn.Pkg.typeOf(e.X).Underlying().(*types.Map)
+ lookup := &Lookup{
+ X: b.expr(fn, e.X),
+ Index: emitConv(fn, b.expr(fn, e.Index), mapt.Key()),
+ CommaOk: true,
+ }
+ lookup.setType(typ)
+ lookup.setPos(e.Lbrack)
+ return fn.emit(lookup)
+
+ case *ast.TypeAssertExpr:
+ return emitTypeTest(fn, b.expr(fn, e.X), typ.At(0).Type(), e.Lparen)
+
+ case *ast.UnaryExpr: // must be receive <-
+ unop := &UnOp{
+ Op: token.ARROW,
+ X: b.expr(fn, e.X),
+ CommaOk: true,
+ }
+ unop.setType(typ)
+ unop.setPos(e.OpPos)
+ return fn.emit(unop)
+ }
+ panic(fmt.Sprintf("exprN(%T) in %s", e, fn))
+}
+
+// builtin emits to fn SSA instructions to implement a call to the
+// built-in function obj with the specified arguments
+// and return type. It returns the value defined by the result.
+//
+// The result is nil if no special handling was required; in this case
+// the caller should treat this like an ordinary library function
+// call.
+//
+func (b *builder) builtin(fn *Function, obj *types.Builtin, args []ast.Expr, typ types.Type, pos token.Pos) Value {
+ switch obj.Name() {
+ case "make":
+ switch typ.Underlying().(type) {
+ case *types.Slice:
+ n := b.expr(fn, args[1])
+ m := n
+ if len(args) == 3 {
+ m = b.expr(fn, args[2])
+ }
+ if m, ok := m.(*Const); ok {
+ // treat make([]T, n, m) as new([m]T)[:n]
+ cap, _ := exact.Int64Val(m.Value)
+ at := types.NewArray(typ.Underlying().(*types.Slice).Elem(), cap)
+ alloc := emitNew(fn, at, pos)
+ alloc.Comment = "makeslice"
+ v := &Slice{
+ X: alloc,
+ High: n,
+ }
+ v.setPos(pos)
+ v.setType(typ)
+ return fn.emit(v)
+ }
+ v := &MakeSlice{
+ Len: n,
+ Cap: m,
+ }
+ v.setPos(pos)
+ v.setType(typ)
+ return fn.emit(v)
+
+ case *types.Map:
+ var res Value
+ if len(args) == 2 {
+ res = b.expr(fn, args[1])
+ }
+ v := &MakeMap{Reserve: res}
+ v.setPos(pos)
+ v.setType(typ)
+ return fn.emit(v)
+
+ case *types.Chan:
+ var sz Value = vZero
+ if len(args) == 2 {
+ sz = b.expr(fn, args[1])
+ }
+ v := &MakeChan{Size: sz}
+ v.setPos(pos)
+ v.setType(typ)
+ return fn.emit(v)
+ }
+
+ case "new":
+ alloc := emitNew(fn, deref(typ), pos)
+ alloc.Comment = "new"
+ return alloc
+
+ case "len", "cap":
+ // Special case: len or cap of an array or *array is
+ // based on the type, not the value which may be nil.
+ // We must still evaluate the value, though. (If it
+ // was side-effect free, the whole call would have
+ // been constant-folded.)
+ t := deref(fn.Pkg.typeOf(args[0])).Underlying()
+ if at, ok := t.(*types.Array); ok {
+ b.expr(fn, args[0]) // for effects only
+ return intConst(at.Len())
+ }
+ // Otherwise treat as normal.
+
+ case "panic":
+ fn.emit(&Panic{
+ X: emitConv(fn, b.expr(fn, args[0]), tEface),
+ pos: pos,
+ })
+ fn.currentBlock = fn.newBasicBlock("unreachable")
+ return vTrue // any non-nil Value will do
+ }
+ return nil // treat all others as a regular function call
+}
+
+// addr lowers a single-result addressable expression e to SSA form,
+// emitting code to fn and returning the location (an lvalue) defined
+// by the expression.
+//
+// If escaping is true, addr marks the base variable of the
+// addressable expression e as being a potentially escaping pointer
+// value. For example, in this code:
+//
+// a := A{
+// b: [1]B{B{c: 1}}
+// }
+// return &a.b[0].c
+//
+// the application of & causes a.b[0].c to have its address taken,
+// which means that ultimately the local variable a must be
+// heap-allocated. This is a simple but very conservative escape
+// analysis.
+//
+// Operations forming potentially escaping pointers include:
+// - &x, including when implicit in method call or composite literals.
+// - a[:] iff a is an array (not *array)
+// - references to variables in lexically enclosing functions.
+//
+func (b *builder) addr(fn *Function, e ast.Expr, escaping bool) lvalue {
+ switch e := e.(type) {
+ case *ast.Ident:
+ if isBlankIdent(e) {
+ return blank{}
+ }
+ obj := fn.Pkg.objectOf(e)
+ v := fn.Prog.packageLevelValue(obj) // var (address)
+ if v == nil {
+ v = fn.lookup(obj, escaping)
+ }
+ return &address{addr: v, pos: e.Pos(), expr: e}
+
+ case *ast.CompositeLit:
+ t := deref(fn.Pkg.typeOf(e))
+ var v *Alloc
+ if escaping {
+ v = emitNew(fn, t, e.Lbrace)
+ } else {
+ v = fn.addLocal(t, e.Lbrace)
+ }
+ v.Comment = "complit"
+ var sb storebuf
+ b.compLit(fn, v, e, true, &sb)
+ sb.emit(fn)
+ return &address{addr: v, pos: e.Lbrace, expr: e}
+
+ case *ast.ParenExpr:
+ return b.addr(fn, e.X, escaping)
+
+ case *ast.SelectorExpr:
+ sel, ok := fn.Pkg.info.Selections[e]
+ if !ok {
+ // qualified identifier
+ return b.addr(fn, e.Sel, escaping)
+ }
+ if sel.Kind() != types.FieldVal {
+ panic(sel)
+ }
+ wantAddr := true
+ v := b.receiver(fn, e.X, wantAddr, escaping, sel)
+ last := len(sel.Index()) - 1
+ return &address{
+ addr: emitFieldSelection(fn, v, sel.Index()[last], true, e.Sel),
+ pos: e.Sel.Pos(),
+ expr: e.Sel,
+ }
+
+ case *ast.IndexExpr:
+ var x Value
+ var et types.Type
+ switch t := fn.Pkg.typeOf(e.X).Underlying().(type) {
+ case *types.Array:
+ x = b.addr(fn, e.X, escaping).address(fn)
+ et = types.NewPointer(t.Elem())
+ case *types.Pointer: // *array
+ x = b.expr(fn, e.X)
+ et = types.NewPointer(t.Elem().Underlying().(*types.Array).Elem())
+ case *types.Slice:
+ x = b.expr(fn, e.X)
+ et = types.NewPointer(t.Elem())
+ case *types.Map:
+ return &element{
+ m: b.expr(fn, e.X),
+ k: emitConv(fn, b.expr(fn, e.Index), t.Key()),
+ t: t.Elem(),
+ pos: e.Lbrack,
+ }
+ default:
+ panic("unexpected container type in IndexExpr: " + t.String())
+ }
+ v := &IndexAddr{
+ X: x,
+ Index: emitConv(fn, b.expr(fn, e.Index), tInt),
+ }
+ v.setPos(e.Lbrack)
+ v.setType(et)
+ return &address{addr: fn.emit(v), pos: e.Lbrack, expr: e}
+
+ case *ast.StarExpr:
+ return &address{addr: b.expr(fn, e.X), pos: e.Star, expr: e}
+ }
+
+ panic(fmt.Sprintf("unexpected address expression: %T", e))
+}
+
+type store struct {
+ lhs lvalue
+ rhs Value
+}
+
+type storebuf struct{ stores []store }
+
+func (sb *storebuf) store(lhs lvalue, rhs Value) {
+ sb.stores = append(sb.stores, store{lhs, rhs})
+}
+
+func (sb *storebuf) emit(fn *Function) {
+ for _, s := range sb.stores {
+ s.lhs.store(fn, s.rhs)
+ }
+}
+
+// assign emits to fn code to initialize the lvalue loc with the value
+// of expression e. If isZero is true, assign assumes that loc holds
+// the zero value for its type.
+//
+// This is equivalent to loc.store(fn, b.expr(fn, e)), but may generate
+// better code in some cases, e.g., for composite literals in an
+// addressable location.
+//
+// If sb is not nil, assign generates code to evaluate expression e, but
+// not to update loc. Instead, the necessary stores are appended to the
+// storebuf sb so that they can be executed later. This allows correct
+// in-place update of existing variables when the RHS is a composite
+// literal that may reference parts of the LHS.
+//
+func (b *builder) assign(fn *Function, loc lvalue, e ast.Expr, isZero bool, sb *storebuf) {
+ // Can we initialize it in place?
+ if e, ok := unparen(e).(*ast.CompositeLit); ok {
+ // A CompositeLit never evaluates to a pointer,
+ // so if the type of the location is a pointer,
+ // an &-operation is implied.
+ if _, ok := loc.(blank); !ok { // avoid calling blank.typ()
+ if isPointer(loc.typ()) {
+ ptr := b.addr(fn, e, true).address(fn)
+ // copy address
+ if sb != nil {
+ sb.store(loc, ptr)
+ } else {
+ loc.store(fn, ptr)
+ }
+ return
+ }
+ }
+
+ if _, ok := loc.(*address); ok {
+ if isInterface(loc.typ()) {
+ // e.g. var x interface{} = T{...}
+ // Can't in-place initialize an interface value.
+ // Fall back to copying.
+ } else {
+ // x = T{...} or x := T{...}
+ addr := loc.address(fn)
+ if sb != nil {
+ b.compLit(fn, addr, e, isZero, sb)
+ } else {
+ var sb storebuf
+ b.compLit(fn, addr, e, isZero, &sb)
+ sb.emit(fn)
+ }
+
+ // Subtle: emit debug ref for aggregate types only;
+ // slice and map are handled by store ops in compLit.
+ switch loc.typ().Underlying().(type) {
+ case *types.Struct, *types.Array:
+ emitDebugRef(fn, e, addr, true)
+ }
+
+ return
+ }
+ }
+ }
+
+ // simple case: just copy
+ rhs := b.expr(fn, e)
+ if sb != nil {
+ sb.store(loc, rhs)
+ } else {
+ loc.store(fn, rhs)
+ }
+}
+
+// expr lowers a single-result expression e to SSA form, emitting code
+// to fn and returning the Value defined by the expression.
+//
+func (b *builder) expr(fn *Function, e ast.Expr) Value {
+ e = unparen(e)
+
+ tv := fn.Pkg.info.Types[e]
+
+ // Is expression a constant?
+ if tv.Value != nil {
+ return NewConst(tv.Value, tv.Type)
+ }
+
+ var v Value
+ if tv.Addressable() {
+ // Prefer pointer arithmetic ({Index,Field}Addr) followed
+ // by Load over subelement extraction (e.g. Index, Field),
+ // to avoid large copies.
+ v = b.addr(fn, e, false).load(fn)
+ } else {
+ v = b.expr0(fn, e, tv)
+ }
+ if fn.debugInfo() {
+ emitDebugRef(fn, e, v, false)
+ }
+ return v
+}
+
+func (b *builder) expr0(fn *Function, e ast.Expr, tv types.TypeAndValue) Value {
+ switch e := e.(type) {
+ case *ast.BasicLit:
+ panic("non-constant BasicLit") // unreachable
+
+ case *ast.FuncLit:
+ fn2 := &Function{
+ name: fmt.Sprintf("%s$%d", fn.Name(), 1+len(fn.AnonFuncs)),
+ Signature: fn.Pkg.typeOf(e.Type).Underlying().(*types.Signature),
+ pos: e.Type.Func,
+ parent: fn,
+ Pkg: fn.Pkg,
+ Prog: fn.Prog,
+ syntax: e,
+ }
+ fn.AnonFuncs = append(fn.AnonFuncs, fn2)
+ b.buildFunction(fn2)
+ if fn2.FreeVars == nil {
+ return fn2
+ }
+ v := &MakeClosure{Fn: fn2}
+ v.setType(tv.Type)
+ for _, fv := range fn2.FreeVars {
+ v.Bindings = append(v.Bindings, fv.outer)
+ fv.outer = nil
+ }
+ return fn.emit(v)
+
+ case *ast.TypeAssertExpr: // single-result form only
+ return emitTypeAssert(fn, b.expr(fn, e.X), tv.Type, e.Lparen)
+
+ case *ast.CallExpr:
+ if fn.Pkg.info.Types[e.Fun].IsType() {
+ // Explicit type conversion, e.g. string(x) or big.Int(x)
+ x := b.expr(fn, e.Args[0])
+ y := emitConv(fn, x, tv.Type)
+ if y != x {
+ switch y := y.(type) {
+ case *Convert:
+ y.pos = e.Lparen
+ case *ChangeType:
+ y.pos = e.Lparen
+ case *MakeInterface:
+ y.pos = e.Lparen
+ }
+ }
+ return y
+ }
+ // Call to "intrinsic" built-ins, e.g. new, make, panic.
+ if id, ok := unparen(e.Fun).(*ast.Ident); ok {
+ if obj, ok := fn.Pkg.info.Uses[id].(*types.Builtin); ok {
+ if v := b.builtin(fn, obj, e.Args, tv.Type, e.Lparen); v != nil {
+ return v
+ }
+ }
+ }
+ // Regular function call.
+ var v Call
+ b.setCall(fn, e, &v.Call)
+ v.setType(tv.Type)
+ return fn.emit(&v)
+
+ case *ast.UnaryExpr:
+ switch e.Op {
+ case token.AND: // &X --- potentially escaping.
+ addr := b.addr(fn, e.X, true)
+ if _, ok := unparen(e.X).(*ast.StarExpr); ok {
+ // &*p must panic if p is nil (http://golang.org/s/go12nil).
+ // For simplicity, we'll just (suboptimally) rely
+ // on the side effects of a load.
+ // TODO(adonovan): emit dedicated nilcheck.
+ addr.load(fn)
+ }
+ return addr.address(fn)
+ case token.ADD:
+ return b.expr(fn, e.X)
+ case token.NOT, token.ARROW, token.SUB, token.XOR: // ! <- - ^
+ v := &UnOp{
+ Op: e.Op,
+ X: b.expr(fn, e.X),
+ }
+ v.setPos(e.OpPos)
+ v.setType(tv.Type)
+ return fn.emit(v)
+ default:
+ panic(e.Op)
+ }
+
+ case *ast.BinaryExpr:
+ switch e.Op {
+ case token.LAND, token.LOR:
+ return b.logicalBinop(fn, e)
+ case token.SHL, token.SHR:
+ fallthrough
+ case token.ADD, token.SUB, token.MUL, token.QUO, token.REM, token.AND, token.OR, token.XOR, token.AND_NOT:
+ return emitArith(fn, e.Op, b.expr(fn, e.X), b.expr(fn, e.Y), tv.Type, e.OpPos)
+
+ case token.EQL, token.NEQ, token.GTR, token.LSS, token.LEQ, token.GEQ:
+ cmp := emitCompare(fn, e.Op, b.expr(fn, e.X), b.expr(fn, e.Y), e.OpPos)
+ // The type of x==y may be UntypedBool.
+ return emitConv(fn, cmp, DefaultType(tv.Type))
+ default:
+ panic("illegal op in BinaryExpr: " + e.Op.String())
+ }
+
+ case *ast.SliceExpr:
+ var low, high, max Value
+ var x Value
+ switch fn.Pkg.typeOf(e.X).Underlying().(type) {
+ case *types.Array:
+ // Potentially escaping.
+ x = b.addr(fn, e.X, true).address(fn)
+ case *types.Basic, *types.Slice, *types.Pointer: // *array
+ x = b.expr(fn, e.X)
+ default:
+ panic("unreachable")
+ }
+ if e.High != nil {
+ high = b.expr(fn, e.High)
+ }
+ if e.Low != nil {
+ low = b.expr(fn, e.Low)
+ }
+ if e.Slice3 {
+ max = b.expr(fn, e.Max)
+ }
+ v := &Slice{
+ X: x,
+ Low: low,
+ High: high,
+ Max: max,
+ }
+ v.setPos(e.Lbrack)
+ v.setType(tv.Type)
+ return fn.emit(v)
+
+ case *ast.Ident:
+ obj := fn.Pkg.info.Uses[e]
+ // Universal built-in or nil?
+ switch obj := obj.(type) {
+ case *types.Builtin:
+ return &Builtin{name: obj.Name(), sig: tv.Type.(*types.Signature)}
+ case *types.Nil:
+ return nilConst(tv.Type)
+ }
+ // Package-level func or var?
+ if v := fn.Prog.packageLevelValue(obj); v != nil {
+ if _, ok := obj.(*types.Var); ok {
+ return emitLoad(fn, v) // var (address)
+ }
+ return v // (func)
+ }
+ // Local var.
+ return emitLoad(fn, fn.lookup(obj, false)) // var (address)
+
+ case *ast.SelectorExpr:
+ sel, ok := fn.Pkg.info.Selections[e]
+ if !ok {
+ // qualified identifier
+ return b.expr(fn, e.Sel)
+ }
+ switch sel.Kind() {
+ case types.MethodExpr:
+ // (*T).f or T.f, the method f from the method-set of type T.
+ // The result is a "thunk".
+ return emitConv(fn, makeThunk(fn.Prog, sel), tv.Type)
+
+ case types.MethodVal:
+ // e.f where e is an expression and f is a method.
+ // The result is a "bound".
+ obj := sel.Obj().(*types.Func)
+ rt := recvType(obj)
+ wantAddr := isPointer(rt)
+ escaping := true
+ v := b.receiver(fn, e.X, wantAddr, escaping, sel)
+ if isInterface(rt) {
+ // If v has interface type I,
+ // we must emit a check that v is non-nil.
+ // We use: typeassert v.(I).
+ emitTypeAssert(fn, v, rt, token.NoPos)
+ }
+ c := &MakeClosure{
+ Fn: makeBound(fn.Prog, obj),
+ Bindings: []Value{v},
+ }
+ c.setPos(e.Sel.Pos())
+ c.setType(tv.Type)
+ return fn.emit(c)
+
+ case types.FieldVal:
+ indices := sel.Index()
+ last := len(indices) - 1
+ v := b.expr(fn, e.X)
+ v = emitImplicitSelections(fn, v, indices[:last])
+ v = emitFieldSelection(fn, v, indices[last], false, e.Sel)
+ return v
+ }
+
+ panic("unexpected expression-relative selector")
+
+ case *ast.IndexExpr:
+ switch t := fn.Pkg.typeOf(e.X).Underlying().(type) {
+ case *types.Array:
+ // Non-addressable array (in a register).
+ v := &Index{
+ X: b.expr(fn, e.X),
+ Index: emitConv(fn, b.expr(fn, e.Index), tInt),
+ }
+ v.setPos(e.Lbrack)
+ v.setType(t.Elem())
+ return fn.emit(v)
+
+ case *types.Map:
+ // Maps are not addressable.
+ mapt := fn.Pkg.typeOf(e.X).Underlying().(*types.Map)
+ v := &Lookup{
+ X: b.expr(fn, e.X),
+ Index: emitConv(fn, b.expr(fn, e.Index), mapt.Key()),
+ }
+ v.setPos(e.Lbrack)
+ v.setType(mapt.Elem())
+ return fn.emit(v)
+
+ case *types.Basic: // => string
+ // Strings are not addressable.
+ v := &Lookup{
+ X: b.expr(fn, e.X),
+ Index: b.expr(fn, e.Index),
+ }
+ v.setPos(e.Lbrack)
+ v.setType(tByte)
+ return fn.emit(v)
+
+ case *types.Slice, *types.Pointer: // *array
+ // Addressable slice/array; use IndexAddr and Load.
+ return b.addr(fn, e, false).load(fn)
+
+ default:
+ panic("unexpected container type in IndexExpr: " + t.String())
+ }
+
+ case *ast.CompositeLit, *ast.StarExpr:
+ // Addressable types (lvalues)
+ return b.addr(fn, e, false).load(fn)
+ }
+
+ panic(fmt.Sprintf("unexpected expr: %T", e))
+}
+
+// stmtList emits to fn code for all statements in list.
+func (b *builder) stmtList(fn *Function, list []ast.Stmt) {
+ for _, s := range list {
+ b.stmt(fn, s)
+ }
+}
+
+// receiver emits to fn code for expression e in the "receiver"
+// position of selection e.f (where f may be a field or a method) and
+// returns the effective receiver after applying the implicit field
+// selections of sel.
+//
+// wantAddr requests that the result is an an address. If
+// !sel.Indirect(), this may require that e be built in addr() mode; it
+// must thus be addressable.
+//
+// escaping is defined as per builder.addr().
+//
+func (b *builder) receiver(fn *Function, e ast.Expr, wantAddr, escaping bool, sel *types.Selection) Value {
+ var v Value
+ if wantAddr && !sel.Indirect() && !isPointer(fn.Pkg.typeOf(e)) {
+ v = b.addr(fn, e, escaping).address(fn)
+ } else {
+ v = b.expr(fn, e)
+ }
+
+ last := len(sel.Index()) - 1
+ v = emitImplicitSelections(fn, v, sel.Index()[:last])
+ if !wantAddr && isPointer(v.Type()) {
+ v = emitLoad(fn, v)
+ }
+ return v
+}
+
+// setCallFunc populates the function parts of a CallCommon structure
+// (Func, Method, Recv, Args[0]) based on the kind of invocation
+// occurring in e.
+//
+func (b *builder) setCallFunc(fn *Function, e *ast.CallExpr, c *CallCommon) {
+ c.pos = e.Lparen
+
+ // Is this a method call?
+ if selector, ok := unparen(e.Fun).(*ast.SelectorExpr); ok {
+ sel, ok := fn.Pkg.info.Selections[selector]
+ if ok && sel.Kind() == types.MethodVal {
+ obj := sel.Obj().(*types.Func)
+ recv := recvType(obj)
+ wantAddr := isPointer(recv)
+ escaping := true
+ v := b.receiver(fn, selector.X, wantAddr, escaping, sel)
+ if isInterface(recv) {
+ // Invoke-mode call.
+ c.Value = v
+ c.Method = obj
+ } else {
+ // "Call"-mode call.
+ c.Value = fn.Prog.declaredFunc(obj)
+ c.Args = append(c.Args, v)
+ }
+ return
+ }
+
+ // sel.Kind()==MethodExpr indicates T.f() or (*T).f():
+ // a statically dispatched call to the method f in the
+ // method-set of T or *T. T may be an interface.
+ //
+ // e.Fun would evaluate to a concrete method, interface
+ // wrapper function, or promotion wrapper.
+ //
+ // For now, we evaluate it in the usual way.
+ //
+ // TODO(adonovan): opt: inline expr() here, to make the
+ // call static and to avoid generation of wrappers.
+ // It's somewhat tricky as it may consume the first
+ // actual parameter if the call is "invoke" mode.
+ //
+ // Examples:
+ // type T struct{}; func (T) f() {} // "call" mode
+ // type T interface { f() } // "invoke" mode
+ //
+ // type S struct{ T }
+ //
+ // var s S
+ // S.f(s)
+ // (*S).f(&s)
+ //
+ // Suggested approach:
+ // - consume the first actual parameter expression
+ // and build it with b.expr().
+ // - apply implicit field selections.
+ // - use MethodVal logic to populate fields of c.
+ }
+
+ // Evaluate the function operand in the usual way.
+ c.Value = b.expr(fn, e.Fun)
+}
+
+// emitCallArgs emits to f code for the actual parameters of call e to
+// a (possibly built-in) function of effective type sig.
+// The argument values are appended to args, which is then returned.
+//
+func (b *builder) emitCallArgs(fn *Function, sig *types.Signature, e *ast.CallExpr, args []Value) []Value {
+ // f(x, y, z...): pass slice z straight through.
+ if e.Ellipsis != 0 {
+ for i, arg := range e.Args {
+ v := emitConv(fn, b.expr(fn, arg), sig.Params().At(i).Type())
+ args = append(args, v)
+ }
+ return args
+ }
+
+ offset := len(args) // 1 if call has receiver, 0 otherwise
+
+ // Evaluate actual parameter expressions.
+ //
+ // If this is a chained call of the form f(g()) where g has
+ // multiple return values (MRV), they are flattened out into
+ // args; a suffix of them may end up in a varargs slice.
+ for _, arg := range e.Args {
+ v := b.expr(fn, arg)
+ if ttuple, ok := v.Type().(*types.Tuple); ok { // MRV chain
+ for i, n := 0, ttuple.Len(); i < n; i++ {
+ args = append(args, emitExtract(fn, v, i))
+ }
+ } else {
+ args = append(args, v)
+ }
+ }
+
+ // Actual->formal assignability conversions for normal parameters.
+ np := sig.Params().Len() // number of normal parameters
+ if sig.Variadic() {
+ np--
+ }
+ for i := 0; i < np; i++ {
+ args[offset+i] = emitConv(fn, args[offset+i], sig.Params().At(i).Type())
+ }
+
+ // Actual->formal assignability conversions for variadic parameter,
+ // and construction of slice.
+ if sig.Variadic() {
+ varargs := args[offset+np:]
+ st := sig.Params().At(np).Type().(*types.Slice)
+ vt := st.Elem()
+ if len(varargs) == 0 {
+ args = append(args, nilConst(st))
+ } else {
+ // Replace a suffix of args with a slice containing it.
+ at := types.NewArray(vt, int64(len(varargs)))
+ a := emitNew(fn, at, token.NoPos)
+ a.setPos(e.Rparen)
+ a.Comment = "varargs"
+ for i, arg := range varargs {
+ iaddr := &IndexAddr{
+ X: a,
+ Index: intConst(int64(i)),
+ }
+ iaddr.setType(types.NewPointer(vt))
+ fn.emit(iaddr)
+ emitStore(fn, iaddr, arg, arg.Pos())
+ }
+ s := &Slice{X: a}
+ s.setType(st)
+ args[offset+np] = fn.emit(s)
+ args = args[:offset+np+1]
+ }
+ }
+ return args
+}
+
+// setCall emits to fn code to evaluate all the parameters of a function
+// call e, and populates *c with those values.
+//
+func (b *builder) setCall(fn *Function, e *ast.CallExpr, c *CallCommon) {
+ // First deal with the f(...) part and optional receiver.
+ b.setCallFunc(fn, e, c)
+
+ // Then append the other actual parameters.
+ sig, _ := fn.Pkg.typeOf(e.Fun).Underlying().(*types.Signature)
+ if sig == nil {
+ panic(fmt.Sprintf("no signature for call of %s", e.Fun))
+ }
+ c.Args = b.emitCallArgs(fn, sig, e, c.Args)
+}
+
+// assignOp emits to fn code to perform loc += incr or loc -= incr.
+func (b *builder) assignOp(fn *Function, loc lvalue, incr Value, op token.Token) {
+ oldv := loc.load(fn)
+ loc.store(fn, emitArith(fn, op, oldv, emitConv(fn, incr, oldv.Type()), loc.typ(), token.NoPos))
+}
+
+// localValueSpec emits to fn code to define all of the vars in the
+// function-local ValueSpec, spec.
+//
+func (b *builder) localValueSpec(fn *Function, spec *ast.ValueSpec) {
+ switch {
+ case len(spec.Values) == len(spec.Names):
+ // e.g. var x, y = 0, 1
+ // 1:1 assignment
+ for i, id := range spec.Names {
+ if !isBlankIdent(id) {
+ fn.addLocalForIdent(id)
+ }
+ lval := b.addr(fn, id, false) // non-escaping
+ b.assign(fn, lval, spec.Values[i], true, nil)
+ }
+
+ case len(spec.Values) == 0:
+ // e.g. var x, y int
+ // Locals are implicitly zero-initialized.
+ for _, id := range spec.Names {
+ if !isBlankIdent(id) {
+ lhs := fn.addLocalForIdent(id)
+ if fn.debugInfo() {
+ emitDebugRef(fn, id, lhs, true)
+ }
+ }
+ }
+
+ default:
+ // e.g. var x, y = pos()
+ tuple := b.exprN(fn, spec.Values[0])
+ for i, id := range spec.Names {
+ if !isBlankIdent(id) {
+ fn.addLocalForIdent(id)
+ lhs := b.addr(fn, id, false) // non-escaping
+ lhs.store(fn, emitExtract(fn, tuple, i))
+ }
+ }
+ }
+}
+
+// assignStmt emits code to fn for a parallel assignment of rhss to lhss.
+// isDef is true if this is a short variable declaration (:=).
+//
+// Note the similarity with localValueSpec.
+//
+func (b *builder) assignStmt(fn *Function, lhss, rhss []ast.Expr, isDef bool) {
+ // Side effects of all LHSs and RHSs must occur in left-to-right order.
+ lvals := make([]lvalue, len(lhss))
+ isZero := make([]bool, len(lhss))
+ for i, lhs := range lhss {
+ var lval lvalue = blank{}
+ if !isBlankIdent(lhs) {
+ if isDef {
+ if obj := fn.Pkg.info.Defs[lhs.(*ast.Ident)]; obj != nil {
+ fn.addNamedLocal(obj)
+ isZero[i] = true
+ }
+ }
+ lval = b.addr(fn, lhs, false) // non-escaping
+ }
+ lvals[i] = lval
+ }
+ if len(lhss) == len(rhss) {
+ // Simple assignment: x = f() (!isDef)
+ // Parallel assignment: x, y = f(), g() (!isDef)
+ // or short var decl: x, y := f(), g() (isDef)
+ //
+ // In all cases, the RHSs may refer to the LHSs,
+ // so we need a storebuf.
+ var sb storebuf
+ for i := range rhss {
+ b.assign(fn, lvals[i], rhss[i], isZero[i], &sb)
+ }
+ sb.emit(fn)
+ } else {
+ // e.g. x, y = pos()
+ tuple := b.exprN(fn, rhss[0])
+ for i, lval := range lvals {
+ lval.store(fn, emitExtract(fn, tuple, i))
+ }
+ }
+}
+
+// arrayLen returns the length of the array whose composite literal elements are elts.
+func (b *builder) arrayLen(fn *Function, elts []ast.Expr) int64 {
+ var max int64 = -1
+ var i int64 = -1
+ for _, e := range elts {
+ if kv, ok := e.(*ast.KeyValueExpr); ok {
+ i = b.expr(fn, kv.Key).(*Const).Int64()
+ } else {
+ i++
+ }
+ if i > max {
+ max = i
+ }
+ }
+ return max + 1
+}
+
+// compLit emits to fn code to initialize a composite literal e at
+// address addr with type typ.
+//
+// Nested composite literals are recursively initialized in place
+// where possible. If isZero is true, compLit assumes that addr
+// holds the zero value for typ.
+//
+// Because the elements of a composite literal may refer to the
+// variables being updated, as in the second line below,
+// x := T{a: 1}
+// x = T{a: x.a}
+// all the reads must occur before all the writes. Thus all stores to
+// loc are emitted to the storebuf sb for later execution.
+//
+// A CompositeLit may have pointer type only in the recursive (nested)
+// case when the type name is implicit. e.g. in []*T{{}}, the inner
+// literal has type *T behaves like &T{}.
+// In that case, addr must hold a T, not a *T.
+//
+func (b *builder) compLit(fn *Function, addr Value, e *ast.CompositeLit, isZero bool, sb *storebuf) {
+ typ := deref(fn.Pkg.typeOf(e))
+ switch t := typ.Underlying().(type) {
+ case *types.Struct:
+ if !isZero && len(e.Elts) != t.NumFields() {
+ // memclear
+ sb.store(&address{addr, e.Lbrace, nil},
+ zeroValue(fn, deref(addr.Type())))
+ isZero = true
+ }
+ for i, e := range e.Elts {
+ fieldIndex := i
+ pos := e.Pos()
+ if kv, ok := e.(*ast.KeyValueExpr); ok {
+ fname := kv.Key.(*ast.Ident).Name
+ for i, n := 0, t.NumFields(); i < n; i++ {
+ sf := t.Field(i)
+ if sf.Name() == fname {
+ fieldIndex = i
+ pos = kv.Colon
+ e = kv.Value
+ break
+ }
+ }
+ }
+ sf := t.Field(fieldIndex)
+ faddr := &FieldAddr{
+ X: addr,
+ Field: fieldIndex,
+ }
+ faddr.setType(types.NewPointer(sf.Type()))
+ fn.emit(faddr)
+ b.assign(fn, &address{addr: faddr, pos: pos, expr: e}, e, isZero, sb)
+ }
+
+ case *types.Array, *types.Slice:
+ var at *types.Array
+ var array Value
+ switch t := t.(type) {
+ case *types.Slice:
+ at = types.NewArray(t.Elem(), b.arrayLen(fn, e.Elts))
+ alloc := emitNew(fn, at, e.Lbrace)
+ alloc.Comment = "slicelit"
+ array = alloc
+ case *types.Array:
+ at = t
+ array = addr
+
+ if !isZero && int64(len(e.Elts)) != at.Len() {
+ // memclear
+ sb.store(&address{array, e.Lbrace, nil},
+ zeroValue(fn, deref(array.Type())))
+ }
+ }
+
+ var idx *Const
+ for _, e := range e.Elts {
+ pos := e.Pos()
+ if kv, ok := e.(*ast.KeyValueExpr); ok {
+ idx = b.expr(fn, kv.Key).(*Const)
+ pos = kv.Colon
+ e = kv.Value
+ } else {
+ var idxval int64
+ if idx != nil {
+ idxval = idx.Int64() + 1
+ }
+ idx = intConst(idxval)
+ }
+ iaddr := &IndexAddr{
+ X: array,
+ Index: idx,
+ }
+ iaddr.setType(types.NewPointer(at.Elem()))
+ fn.emit(iaddr)
+ if t != at { // slice
+ // backing array is unaliased => storebuf not needed.
+ b.assign(fn, &address{addr: iaddr, pos: pos, expr: e}, e, true, nil)
+ } else {
+ b.assign(fn, &address{addr: iaddr, pos: pos, expr: e}, e, true, sb)
+ }
+ }
+
+ if t != at { // slice
+ s := &Slice{X: array}
+ s.setPos(e.Lbrace)
+ s.setType(typ)
+ sb.store(&address{addr: addr, pos: e.Lbrace, expr: e}, fn.emit(s))
+ }
+
+ case *types.Map:
+ m := &MakeMap{Reserve: intConst(int64(len(e.Elts)))}
+ m.setPos(e.Lbrace)
+ m.setType(typ)
+ fn.emit(m)
+ for _, e := range e.Elts {
+ e := e.(*ast.KeyValueExpr)
+ loc := element{
+ m: m,
+ k: emitConv(fn, b.expr(fn, e.Key), t.Key()),
+ t: t.Elem(),
+ pos: e.Colon,
+ }
+
+ // We call assign() only because it takes care
+ // of any &-operation required in the recursive
+ // case, e.g.,
+ // map[int]*struct{}{0: {}} implies &struct{}{}.
+ // In-place update is of course impossible,
+ // and no storebuf is needed.
+ b.assign(fn, &loc, e.Value, true, nil)
+ }
+ sb.store(&address{addr: addr, pos: e.Lbrace, expr: e}, m)
+
+ default:
+ panic("unexpected CompositeLit type: " + t.String())
+ }
+}
+
+// switchStmt emits to fn code for the switch statement s, optionally
+// labelled by label.
+//
+func (b *builder) switchStmt(fn *Function, s *ast.SwitchStmt, label *lblock) {
+ // We treat SwitchStmt like a sequential if-else chain.
+ // Multiway dispatch can be recovered later by ssautil.Switches()
+ // to those cases that are free of side effects.
+ if s.Init != nil {
+ b.stmt(fn, s.Init)
+ }
+ var tag Value = vTrue
+ if s.Tag != nil {
+ tag = b.expr(fn, s.Tag)
+ }
+ done := fn.newBasicBlock("switch.done")
+ if label != nil {
+ label._break = done
+ }
+ // We pull the default case (if present) down to the end.
+ // But each fallthrough label must point to the next
+ // body block in source order, so we preallocate a
+ // body block (fallthru) for the next case.
+ // Unfortunately this makes for a confusing block order.
+ var dfltBody *[]ast.Stmt
+ var dfltFallthrough *BasicBlock
+ var fallthru, dfltBlock *BasicBlock
+ ncases := len(s.Body.List)
+ for i, clause := range s.Body.List {
+ body := fallthru
+ if body == nil {
+ body = fn.newBasicBlock("switch.body") // first case only
+ }
+
+ // Preallocate body block for the next case.
+ fallthru = done
+ if i+1 < ncases {
+ fallthru = fn.newBasicBlock("switch.body")
+ }
+
+ cc := clause.(*ast.CaseClause)
+ if cc.List == nil {
+ // Default case.
+ dfltBody = &cc.Body
+ dfltFallthrough = fallthru
+ dfltBlock = body
+ continue
+ }
+
+ var nextCond *BasicBlock
+ for _, cond := range cc.List {
+ nextCond = fn.newBasicBlock("switch.next")
+ // TODO(adonovan): opt: when tag==vTrue, we'd
+ // get better code if we use b.cond(cond)
+ // instead of BinOp(EQL, tag, b.expr(cond))
+ // followed by If. Don't forget conversions
+ // though.
+ cond := emitCompare(fn, token.EQL, tag, b.expr(fn, cond), token.NoPos)
+ emitIf(fn, cond, body, nextCond)
+ fn.currentBlock = nextCond
+ }
+ fn.currentBlock = body
+ fn.targets = &targets{
+ tail: fn.targets,
+ _break: done,
+ _fallthrough: fallthru,
+ }
+ b.stmtList(fn, cc.Body)
+ fn.targets = fn.targets.tail
+ emitJump(fn, done)
+ fn.currentBlock = nextCond
+ }
+ if dfltBlock != nil {
+ emitJump(fn, dfltBlock)
+ fn.currentBlock = dfltBlock
+ fn.targets = &targets{
+ tail: fn.targets,
+ _break: done,
+ _fallthrough: dfltFallthrough,
+ }
+ b.stmtList(fn, *dfltBody)
+ fn.targets = fn.targets.tail
+ }
+ emitJump(fn, done)
+ fn.currentBlock = done
+}
+
+// typeSwitchStmt emits to fn code for the type switch statement s, optionally
+// labelled by label.
+//
+func (b *builder) typeSwitchStmt(fn *Function, s *ast.TypeSwitchStmt, label *lblock) {
+ // We treat TypeSwitchStmt like a sequential if-else chain.
+ // Multiway dispatch can be recovered later by ssautil.Switches().
+
+ // Typeswitch lowering:
+ //
+ // var x X
+ // switch y := x.(type) {
+ // case T1, T2: S1 // >1 (y := x)
+ // case nil: SN // nil (y := x)
+ // default: SD // 0 types (y := x)
+ // case T3: S3 // 1 type (y := x.(T3))
+ // }
+ //
+ // ...s.Init...
+ // x := eval x
+ // .caseT1:
+ // t1, ok1 := typeswitch,ok x
+ // if ok1 then goto S1 else goto .caseT2
+ // .caseT2:
+ // t2, ok2 := typeswitch,ok x
+ // if ok2 then goto S1 else goto .caseNil
+ // .S1:
+ // y := x
+ // ...S1...
+ // goto done
+ // .caseNil:
+ // if t2, ok2 := typeswitch,ok x
+ // if x == nil then goto SN else goto .caseT3
+ // .SN:
+ // y := x
+ // ...SN...
+ // goto done
+ // .caseT3:
+ // t3, ok3 := typeswitch,ok x
+ // if ok3 then goto S3 else goto default
+ // .S3:
+ // y := t3
+ // ...S3...
+ // goto done
+ // .default:
+ // y := x
+ // ...SD...
+ // goto done
+ // .done:
+
+ if s.Init != nil {
+ b.stmt(fn, s.Init)
+ }
+
+ var x Value
+ switch ass := s.Assign.(type) {
+ case *ast.ExprStmt: // x.(type)
+ x = b.expr(fn, unparen(ass.X).(*ast.TypeAssertExpr).X)
+ case *ast.AssignStmt: // y := x.(type)
+ x = b.expr(fn, unparen(ass.Rhs[0]).(*ast.TypeAssertExpr).X)
+ }
+
+ done := fn.newBasicBlock("typeswitch.done")
+ if label != nil {
+ label._break = done
+ }
+ var default_ *ast.CaseClause
+ for _, clause := range s.Body.List {
+ cc := clause.(*ast.CaseClause)
+ if cc.List == nil {
+ default_ = cc
+ continue
+ }
+ body := fn.newBasicBlock("typeswitch.body")
+ var next *BasicBlock
+ var casetype types.Type
+ var ti Value // ti, ok := typeassert,ok x
+ for _, cond := range cc.List {
+ next = fn.newBasicBlock("typeswitch.next")
+ casetype = fn.Pkg.typeOf(cond)
+ var condv Value
+ if casetype == tUntypedNil {
+ condv = emitCompare(fn, token.EQL, x, nilConst(x.Type()), token.NoPos)
+ ti = x
+ } else {
+ yok := emitTypeTest(fn, x, casetype, cc.Case)
+ ti = emitExtract(fn, yok, 0)
+ condv = emitExtract(fn, yok, 1)
+ }
+ emitIf(fn, condv, body, next)
+ fn.currentBlock = next
+ }
+ if len(cc.List) != 1 {
+ ti = x
+ }
+ fn.currentBlock = body
+ b.typeCaseBody(fn, cc, ti, done)
+ fn.currentBlock = next
+ }
+ if default_ != nil {
+ b.typeCaseBody(fn, default_, x, done)
+ } else {
+ emitJump(fn, done)
+ }
+ fn.currentBlock = done
+}
+
+func (b *builder) typeCaseBody(fn *Function, cc *ast.CaseClause, x Value, done *BasicBlock) {
+ if obj := fn.Pkg.info.Implicits[cc]; obj != nil {
+ // In a switch y := x.(type), each case clause
+ // implicitly declares a distinct object y.
+ // In a single-type case, y has that type.
+ // In multi-type cases, 'case nil' and default,
+ // y has the same type as the interface operand.
+ emitStore(fn, fn.addNamedLocal(obj), x, obj.Pos())
+ }
+ fn.targets = &targets{
+ tail: fn.targets,
+ _break: done,
+ }
+ b.stmtList(fn, cc.Body)
+ fn.targets = fn.targets.tail
+ emitJump(fn, done)
+}
+
+// selectStmt emits to fn code for the select statement s, optionally
+// labelled by label.
+//
+func (b *builder) selectStmt(fn *Function, s *ast.SelectStmt, label *lblock) {
+ // A blocking select of a single case degenerates to a
+ // simple send or receive.
+ // TODO(adonovan): opt: is this optimization worth its weight?
+ if len(s.Body.List) == 1 {
+ clause := s.Body.List[0].(*ast.CommClause)
+ if clause.Comm != nil {
+ b.stmt(fn, clause.Comm)
+ done := fn.newBasicBlock("select.done")
+ if label != nil {
+ label._break = done
+ }
+ fn.targets = &targets{
+ tail: fn.targets,
+ _break: done,
+ }
+ b.stmtList(fn, clause.Body)
+ fn.targets = fn.targets.tail
+ emitJump(fn, done)
+ fn.currentBlock = done
+ return
+ }
+ }
+
+ // First evaluate all channels in all cases, and find
+ // the directions of each state.
+ var states []*SelectState
+ blocking := true
+ debugInfo := fn.debugInfo()
+ for _, clause := range s.Body.List {
+ var st *SelectState
+ switch comm := clause.(*ast.CommClause).Comm.(type) {
+ case nil: // default case
+ blocking = false
+ continue
+
+ case *ast.SendStmt: // ch<- i
+ ch := b.expr(fn, comm.Chan)
+ st = &SelectState{
+ Dir: types.SendOnly,
+ Chan: ch,
+ Send: emitConv(fn, b.expr(fn, comm.Value),
+ ch.Type().Underlying().(*types.Chan).Elem()),
+ Pos: comm.Arrow,
+ }
+ if debugInfo {
+ st.DebugNode = comm
+ }
+
+ case *ast.AssignStmt: // x := <-ch
+ recv := unparen(comm.Rhs[0]).(*ast.UnaryExpr)
+ st = &SelectState{
+ Dir: types.RecvOnly,
+ Chan: b.expr(fn, recv.X),
+ Pos: recv.OpPos,
+ }
+ if debugInfo {
+ st.DebugNode = recv
+ }
+
+ case *ast.ExprStmt: // <-ch
+ recv := unparen(comm.X).(*ast.UnaryExpr)
+ st = &SelectState{
+ Dir: types.RecvOnly,
+ Chan: b.expr(fn, recv.X),
+ Pos: recv.OpPos,
+ }
+ if debugInfo {
+ st.DebugNode = recv
+ }
+ }
+ states = append(states, st)
+ }
+
+ // We dispatch on the (fair) result of Select using a
+ // sequential if-else chain, in effect:
+ //
+ // idx, recvOk, r0...r_n-1 := select(...)
+ // if idx == 0 { // receive on channel 0 (first receive => r0)
+ // x, ok := r0, recvOk
+ // ...state0...
+ // } else if v == 1 { // send on channel 1
+ // ...state1...
+ // } else {
+ // ...default...
+ // }
+ sel := &Select{
+ States: states,
+ Blocking: blocking,
+ }
+ sel.setPos(s.Select)
+ var vars []*types.Var
+ vars = append(vars, varIndex, varOk)
+ for _, st := range states {
+ if st.Dir == types.RecvOnly {
+ tElem := st.Chan.Type().Underlying().(*types.Chan).Elem()
+ vars = append(vars, anonVar(tElem))
+ }
+ }
+ sel.setType(types.NewTuple(vars...))
+
+ fn.emit(sel)
+ idx := emitExtract(fn, sel, 0)
+
+ done := fn.newBasicBlock("select.done")
+ if label != nil {
+ label._break = done
+ }
+
+ var defaultBody *[]ast.Stmt
+ state := 0
+ r := 2 // index in 'sel' tuple of value; increments if st.Dir==RECV
+ for _, cc := range s.Body.List {
+ clause := cc.(*ast.CommClause)
+ if clause.Comm == nil {
+ defaultBody = &clause.Body
+ continue
+ }
+ body := fn.newBasicBlock("select.body")
+ next := fn.newBasicBlock("select.next")
+ emitIf(fn, emitCompare(fn, token.EQL, idx, intConst(int64(state)), token.NoPos), body, next)
+ fn.currentBlock = body
+ fn.targets = &targets{
+ tail: fn.targets,
+ _break: done,
+ }
+ switch comm := clause.Comm.(type) {
+ case *ast.ExprStmt: // <-ch
+ if debugInfo {
+ v := emitExtract(fn, sel, r)
+ emitDebugRef(fn, states[state].DebugNode.(ast.Expr), v, false)
+ }
+ r++
+
+ case *ast.AssignStmt: // x := <-states[state].Chan
+ if comm.Tok == token.DEFINE {
+ fn.addLocalForIdent(comm.Lhs[0].(*ast.Ident))
+ }
+ x := b.addr(fn, comm.Lhs[0], false) // non-escaping
+ v := emitExtract(fn, sel, r)
+ if debugInfo {
+ emitDebugRef(fn, states[state].DebugNode.(ast.Expr), v, false)
+ }
+ x.store(fn, v)
+
+ if len(comm.Lhs) == 2 { // x, ok := ...
+ if comm.Tok == token.DEFINE {
+ fn.addLocalForIdent(comm.Lhs[1].(*ast.Ident))
+ }
+ ok := b.addr(fn, comm.Lhs[1], false) // non-escaping
+ ok.store(fn, emitExtract(fn, sel, 1))
+ }
+ r++
+ }
+ b.stmtList(fn, clause.Body)
+ fn.targets = fn.targets.tail
+ emitJump(fn, done)
+ fn.currentBlock = next
+ state++
+ }
+ if defaultBody != nil {
+ fn.targets = &targets{
+ tail: fn.targets,
+ _break: done,
+ }
+ b.stmtList(fn, *defaultBody)
+ fn.targets = fn.targets.tail
+ } else {
+ // A blocking select must match some case.
+ // (This should really be a runtime.errorString, not a string.)
+ fn.emit(&Panic{
+ X: emitConv(fn, stringConst("blocking select matched no case"), tEface),
+ })
+ fn.currentBlock = fn.newBasicBlock("unreachable")
+ }
+ emitJump(fn, done)
+ fn.currentBlock = done
+}
+
+// forStmt emits to fn code for the for statement s, optionally
+// labelled by label.
+//
+func (b *builder) forStmt(fn *Function, s *ast.ForStmt, label *lblock) {
+ // ...init...
+ // jump loop
+ // loop:
+ // if cond goto body else done
+ // body:
+ // ...body...
+ // jump post
+ // post: (target of continue)
+ // ...post...
+ // jump loop
+ // done: (target of break)
+ if s.Init != nil {
+ b.stmt(fn, s.Init)
+ }
+ body := fn.newBasicBlock("for.body")
+ done := fn.newBasicBlock("for.done") // target of 'break'
+ loop := body // target of back-edge
+ if s.Cond != nil {
+ loop = fn.newBasicBlock("for.loop")
+ }
+ cont := loop // target of 'continue'
+ if s.Post != nil {
+ cont = fn.newBasicBlock("for.post")
+ }
+ if label != nil {
+ label._break = done
+ label._continue = cont
+ }
+ emitJump(fn, loop)
+ fn.currentBlock = loop
+ if loop != body {
+ b.cond(fn, s.Cond, body, done)
+ fn.currentBlock = body
+ }
+ fn.targets = &targets{
+ tail: fn.targets,
+ _break: done,
+ _continue: cont,
+ }
+ b.stmt(fn, s.Body)
+ fn.targets = fn.targets.tail
+ emitJump(fn, cont)
+
+ if s.Post != nil {
+ fn.currentBlock = cont
+ b.stmt(fn, s.Post)
+ emitJump(fn, loop) // back-edge
+ }
+ fn.currentBlock = done
+}
+
+// rangeIndexed emits to fn the header for an integer-indexed loop
+// over array, *array or slice value x.
+// The v result is defined only if tv is non-nil.
+// forPos is the position of the "for" token.
+//
+func (b *builder) rangeIndexed(fn *Function, x Value, tv types.Type, pos token.Pos) (k, v Value, loop, done *BasicBlock) {
+ //
+ // length = len(x)
+ // index = -1
+ // loop: (target of continue)
+ // index++
+ // if index < length goto body else done
+ // body:
+ // k = index
+ // v = x[index]
+ // ...body...
+ // jump loop
+ // done: (target of break)
+
+ // Determine number of iterations.
+ var length Value
+ if arr, ok := deref(x.Type()).Underlying().(*types.Array); ok {
+ // For array or *array, the number of iterations is
+ // known statically thanks to the type. We avoid a
+ // data dependence upon x, permitting later dead-code
+ // elimination if x is pure, static unrolling, etc.
+ // Ranging over a nil *array may have >0 iterations.
+ // We still generate code for x, in case it has effects.
+ length = intConst(arr.Len())
+ } else {
+ // length = len(x).
+ var c Call
+ c.Call.Value = makeLen(x.Type())
+ c.Call.Args = []Value{x}
+ c.setType(tInt)
+ length = fn.emit(&c)
+ }
+
+ index := fn.addLocal(tInt, token.NoPos)
+ emitStore(fn, index, intConst(-1), pos)
+
+ loop = fn.newBasicBlock("rangeindex.loop")
+ emitJump(fn, loop)
+ fn.currentBlock = loop
+
+ incr := &BinOp{
+ Op: token.ADD,
+ X: emitLoad(fn, index),
+ Y: vOne,
+ }
+ incr.setType(tInt)
+ emitStore(fn, index, fn.emit(incr), pos)
+
+ body := fn.newBasicBlock("rangeindex.body")
+ done = fn.newBasicBlock("rangeindex.done")
+ emitIf(fn, emitCompare(fn, token.LSS, incr, length, token.NoPos), body, done)
+ fn.currentBlock = body
+
+ k = emitLoad(fn, index)
+ if tv != nil {
+ switch t := x.Type().Underlying().(type) {
+ case *types.Array:
+ instr := &Index{
+ X: x,
+ Index: k,
+ }
+ instr.setType(t.Elem())
+ v = fn.emit(instr)
+
+ case *types.Pointer: // *array
+ instr := &IndexAddr{
+ X: x,
+ Index: k,
+ }
+ instr.setType(types.NewPointer(t.Elem().Underlying().(*types.Array).Elem()))
+ v = emitLoad(fn, fn.emit(instr))
+
+ case *types.Slice:
+ instr := &IndexAddr{
+ X: x,
+ Index: k,
+ }
+ instr.setType(types.NewPointer(t.Elem()))
+ v = emitLoad(fn, fn.emit(instr))
+
+ default:
+ panic("rangeIndexed x:" + t.String())
+ }
+ }
+ return
+}
+
+// rangeIter emits to fn the header for a loop using
+// Range/Next/Extract to iterate over map or string value x.
+// tk and tv are the types of the key/value results k and v, or nil
+// if the respective component is not wanted.
+//
+func (b *builder) rangeIter(fn *Function, x Value, tk, tv types.Type, pos token.Pos) (k, v Value, loop, done *BasicBlock) {
+ //
+ // it = range x
+ // loop: (target of continue)
+ // okv = next it (ok, key, value)
+ // ok = extract okv #0
+ // if ok goto body else done
+ // body:
+ // k = extract okv #1
+ // v = extract okv #2
+ // ...body...
+ // jump loop
+ // done: (target of break)
+ //
+
+ if tk == nil {
+ tk = tInvalid
+ }
+ if tv == nil {
+ tv = tInvalid
+ }
+
+ rng := &Range{X: x}
+ rng.setPos(pos)
+ rng.setType(tRangeIter)
+ it := fn.emit(rng)
+
+ loop = fn.newBasicBlock("rangeiter.loop")
+ emitJump(fn, loop)
+ fn.currentBlock = loop
+
+ _, isString := x.Type().Underlying().(*types.Basic)
+
+ okv := &Next{
+ Iter: it,
+ IsString: isString,
+ }
+ okv.setType(types.NewTuple(
+ varOk,
+ newVar("k", tk),
+ newVar("v", tv),
+ ))
+ fn.emit(okv)
+
+ body := fn.newBasicBlock("rangeiter.body")
+ done = fn.newBasicBlock("rangeiter.done")
+ emitIf(fn, emitExtract(fn, okv, 0), body, done)
+ fn.currentBlock = body
+
+ if tk != tInvalid {
+ k = emitExtract(fn, okv, 1)
+ }
+ if tv != tInvalid {
+ v = emitExtract(fn, okv, 2)
+ }
+ return
+}
+
+// rangeChan emits to fn the header for a loop that receives from
+// channel x until it fails.
+// tk is the channel's element type, or nil if the k result is
+// not wanted
+// pos is the position of the '=' or ':=' token.
+//
+func (b *builder) rangeChan(fn *Function, x Value, tk types.Type, pos token.Pos) (k Value, loop, done *BasicBlock) {
+ //
+ // loop: (target of continue)
+ // ko = <-x (key, ok)
+ // ok = extract ko #1
+ // if ok goto body else done
+ // body:
+ // k = extract ko #0
+ // ...
+ // goto loop
+ // done: (target of break)
+
+ loop = fn.newBasicBlock("rangechan.loop")
+ emitJump(fn, loop)
+ fn.currentBlock = loop
+ recv := &UnOp{
+ Op: token.ARROW,
+ X: x,
+ CommaOk: true,
+ }
+ recv.setPos(pos)
+ recv.setType(types.NewTuple(
+ newVar("k", x.Type().Underlying().(*types.Chan).Elem()),
+ varOk,
+ ))
+ ko := fn.emit(recv)
+ body := fn.newBasicBlock("rangechan.body")
+ done = fn.newBasicBlock("rangechan.done")
+ emitIf(fn, emitExtract(fn, ko, 1), body, done)
+ fn.currentBlock = body
+ if tk != nil {
+ k = emitExtract(fn, ko, 0)
+ }
+ return
+}
+
+// rangeStmt emits to fn code for the range statement s, optionally
+// labelled by label.
+//
+func (b *builder) rangeStmt(fn *Function, s *ast.RangeStmt, label *lblock) {
+ var tk, tv types.Type
+ if s.Key != nil && !isBlankIdent(s.Key) {
+ tk = fn.Pkg.typeOf(s.Key)
+ }
+ if s.Value != nil && !isBlankIdent(s.Value) {
+ tv = fn.Pkg.typeOf(s.Value)
+ }
+
+ // If iteration variables are defined (:=), this
+ // occurs once outside the loop.
+ //
+ // Unlike a short variable declaration, a RangeStmt
+ // using := never redeclares an existing variable; it
+ // always creates a new one.
+ if s.Tok == token.DEFINE {
+ if tk != nil {
+ fn.addLocalForIdent(s.Key.(*ast.Ident))
+ }
+ if tv != nil {
+ fn.addLocalForIdent(s.Value.(*ast.Ident))
+ }
+ }
+
+ x := b.expr(fn, s.X)
+
+ var k, v Value
+ var loop, done *BasicBlock
+ switch rt := x.Type().Underlying().(type) {
+ case *types.Slice, *types.Array, *types.Pointer: // *array
+ k, v, loop, done = b.rangeIndexed(fn, x, tv, s.For)
+
+ case *types.Chan:
+ k, loop, done = b.rangeChan(fn, x, tk, s.For)
+
+ case *types.Map, *types.Basic: // string
+ k, v, loop, done = b.rangeIter(fn, x, tk, tv, s.For)
+
+ default:
+ panic("Cannot range over: " + rt.String())
+ }
+
+ // Evaluate both LHS expressions before we update either.
+ var kl, vl lvalue
+ if tk != nil {
+ kl = b.addr(fn, s.Key, false) // non-escaping
+ }
+ if tv != nil {
+ vl = b.addr(fn, s.Value, false) // non-escaping
+ }
+ if tk != nil {
+ kl.store(fn, k)
+ }
+ if tv != nil {
+ vl.store(fn, v)
+ }
+
+ if label != nil {
+ label._break = done
+ label._continue = loop
+ }
+
+ fn.targets = &targets{
+ tail: fn.targets,
+ _break: done,
+ _continue: loop,
+ }
+ b.stmt(fn, s.Body)
+ fn.targets = fn.targets.tail
+ emitJump(fn, loop) // back-edge
+ fn.currentBlock = done
+}
+
+// stmt lowers statement s to SSA form, emitting code to fn.
+func (b *builder) stmt(fn *Function, _s ast.Stmt) {
+ // The label of the current statement. If non-nil, its _goto
+ // target is always set; its _break and _continue are set only
+ // within the body of switch/typeswitch/select/for/range.
+ // It is effectively an additional default-nil parameter of stmt().
+ var label *lblock
+start:
+ switch s := _s.(type) {
+ case *ast.EmptyStmt:
+ // ignore. (Usually removed by gofmt.)
+
+ case *ast.DeclStmt: // Con, Var or Typ
+ d := s.Decl.(*ast.GenDecl)
+ if d.Tok == token.VAR {
+ for _, spec := range d.Specs {
+ if vs, ok := spec.(*ast.ValueSpec); ok {
+ b.localValueSpec(fn, vs)
+ }
+ }
+ }
+
+ case *ast.LabeledStmt:
+ label = fn.labelledBlock(s.Label)
+ emitJump(fn, label._goto)
+ fn.currentBlock = label._goto
+ _s = s.Stmt
+ goto start // effectively: tailcall stmt(fn, s.Stmt, label)
+
+ case *ast.ExprStmt:
+ b.expr(fn, s.X)
+
+ case *ast.SendStmt:
+ fn.emit(&Send{
+ Chan: b.expr(fn, s.Chan),
+ X: emitConv(fn, b.expr(fn, s.Value),
+ fn.Pkg.typeOf(s.Chan).Underlying().(*types.Chan).Elem()),
+ pos: s.Arrow,
+ })
+
+ case *ast.IncDecStmt:
+ op := token.ADD
+ if s.Tok == token.DEC {
+ op = token.SUB
+ }
+ loc := b.addr(fn, s.X, false)
+ b.assignOp(fn, loc, NewConst(exact.MakeInt64(1), loc.typ()), op)
+
+ case *ast.AssignStmt:
+ switch s.Tok {
+ case token.ASSIGN, token.DEFINE:
+ b.assignStmt(fn, s.Lhs, s.Rhs, s.Tok == token.DEFINE)
+
+ default: // +=, etc.
+ op := s.Tok + token.ADD - token.ADD_ASSIGN
+ b.assignOp(fn, b.addr(fn, s.Lhs[0], false), b.expr(fn, s.Rhs[0]), op)
+ }
+
+ case *ast.GoStmt:
+ // The "intrinsics" new/make/len/cap are forbidden here.
+ // panic is treated like an ordinary function call.
+ v := Go{pos: s.Go}
+ b.setCall(fn, s.Call, &v.Call)
+ fn.emit(&v)
+
+ case *ast.DeferStmt:
+ // The "intrinsics" new/make/len/cap are forbidden here.
+ // panic is treated like an ordinary function call.
+ v := Defer{pos: s.Defer}
+ b.setCall(fn, s.Call, &v.Call)
+ fn.emit(&v)
+
+ // A deferred call can cause recovery from panic,
+ // and control resumes at the Recover block.
+ createRecoverBlock(fn)
+
+ case *ast.ReturnStmt:
+ var results []Value
+ if len(s.Results) == 1 && fn.Signature.Results().Len() > 1 {
+ // Return of one expression in a multi-valued function.
+ tuple := b.exprN(fn, s.Results[0])
+ ttuple := tuple.Type().(*types.Tuple)
+ for i, n := 0, ttuple.Len(); i < n; i++ {
+ results = append(results,
+ emitConv(fn, emitExtract(fn, tuple, i),
+ fn.Signature.Results().At(i).Type()))
+ }
+ } else {
+ // 1:1 return, or no-arg return in non-void function.
+ for i, r := range s.Results {
+ v := emitConv(fn, b.expr(fn, r), fn.Signature.Results().At(i).Type())
+ results = append(results, v)
+ }
+ }
+ if fn.namedResults != nil {
+ // Function has named result parameters (NRPs).
+ // Perform parallel assignment of return operands to NRPs.
+ for i, r := range results {
+ emitStore(fn, fn.namedResults[i], r, s.Return)
+ }
+ }
+ // Run function calls deferred in this
+ // function when explicitly returning from it.
+ fn.emit(new(RunDefers))
+ if fn.namedResults != nil {
+ // Reload NRPs to form the result tuple.
+ results = results[:0]
+ for _, r := range fn.namedResults {
+ results = append(results, emitLoad(fn, r))
+ }
+ }
+ fn.emit(&Return{Results: results, pos: s.Return})
+ fn.currentBlock = fn.newBasicBlock("unreachable")
+
+ case *ast.BranchStmt:
+ var block *BasicBlock
+ switch s.Tok {
+ case token.BREAK:
+ if s.Label != nil {
+ block = fn.labelledBlock(s.Label)._break
+ } else {
+ for t := fn.targets; t != nil && block == nil; t = t.tail {
+ block = t._break
+ }
+ }
+
+ case token.CONTINUE:
+ if s.Label != nil {
+ block = fn.labelledBlock(s.Label)._continue
+ } else {
+ for t := fn.targets; t != nil && block == nil; t = t.tail {
+ block = t._continue
+ }
+ }
+
+ case token.FALLTHROUGH:
+ for t := fn.targets; t != nil && block == nil; t = t.tail {
+ block = t._fallthrough
+ }
+
+ case token.GOTO:
+ block = fn.labelledBlock(s.Label)._goto
+ }
+ emitJump(fn, block)
+ fn.currentBlock = fn.newBasicBlock("unreachable")
+
+ case *ast.BlockStmt:
+ b.stmtList(fn, s.List)
+
+ case *ast.IfStmt:
+ if s.Init != nil {
+ b.stmt(fn, s.Init)
+ }
+ then := fn.newBasicBlock("if.then")
+ done := fn.newBasicBlock("if.done")
+ els := done
+ if s.Else != nil {
+ els = fn.newBasicBlock("if.else")
+ }
+ b.cond(fn, s.Cond, then, els)
+ fn.currentBlock = then
+ b.stmt(fn, s.Body)
+ emitJump(fn, done)
+
+ if s.Else != nil {
+ fn.currentBlock = els
+ b.stmt(fn, s.Else)
+ emitJump(fn, done)
+ }
+
+ fn.currentBlock = done
+
+ case *ast.SwitchStmt:
+ b.switchStmt(fn, s, label)
+
+ case *ast.TypeSwitchStmt:
+ b.typeSwitchStmt(fn, s, label)
+
+ case *ast.SelectStmt:
+ b.selectStmt(fn, s, label)
+
+ case *ast.ForStmt:
+ b.forStmt(fn, s, label)
+
+ case *ast.RangeStmt:
+ b.rangeStmt(fn, s, label)
+
+ default:
+ panic(fmt.Sprintf("unexpected statement kind: %T", s))
+ }
+}
+
+// buildFunction builds SSA code for the body of function fn. Idempotent.
+func (b *builder) buildFunction(fn *Function) {
+ if fn.Blocks != nil {
+ return // building already started
+ }
+
+ var recvField *ast.FieldList
+ var body *ast.BlockStmt
+ var functype *ast.FuncType
+ switch n := fn.syntax.(type) {
+ case nil:
+ return // not a Go source function. (Synthetic, or from object file.)
+ case *ast.FuncDecl:
+ functype = n.Type
+ recvField = n.Recv
+ body = n.Body
+ case *ast.FuncLit:
+ functype = n.Type
+ body = n.Body
+ default:
+ panic(n)
+ }
+
+ if body == nil {
+ // External function.
+ if fn.Params == nil {
+ // This condition ensures we add a non-empty
+ // params list once only, but we may attempt
+ // the degenerate empty case repeatedly.
+ // TODO(adonovan): opt: don't do that.
+
+ // We set Function.Params even though there is no body
+ // code to reference them. This simplifies clients.
+ if recv := fn.Signature.Recv(); recv != nil {
+ fn.addParamObj(recv)
+ }
+ params := fn.Signature.Params()
+ for i, n := 0, params.Len(); i < n; i++ {
+ fn.addParamObj(params.At(i))
+ }
+ }
+ return
+ }
+ if fn.Prog.mode&LogSource != 0 {
+ defer logStack("build function %s @ %s", fn, fn.Prog.Fset.Position(fn.pos))()
+ }
+ fn.startBody()
+ fn.createSyntacticParams(recvField, functype)
+ b.stmt(fn, body)
+ if cb := fn.currentBlock; cb != nil && (cb == fn.Blocks[0] || cb == fn.Recover || cb.Preds != nil) {
+ // Control fell off the end of the function's body block.
+ //
+ // Block optimizations eliminate the current block, if
+ // unreachable. It is a builder invariant that
+ // if this no-arg return is ill-typed for
+ // fn.Signature.Results, this block must be
+ // unreachable. The sanity checker checks this.
+ fn.emit(new(RunDefers))
+ fn.emit(new(Return))
+ }
+ fn.finishBody()
+}
+
+// buildFuncDecl builds SSA code for the function or method declared
+// by decl in package pkg.
+//
+func (b *builder) buildFuncDecl(pkg *Package, decl *ast.FuncDecl) {
+ id := decl.Name
+ if isBlankIdent(id) {
+ return // discard
+ }
+ fn := pkg.values[pkg.info.Defs[id]].(*Function)
+ if decl.Recv == nil && id.Name == "init" {
+ var v Call
+ v.Call.Value = fn
+ v.setType(types.NewTuple())
+ pkg.init.emit(&v)
+ }
+ b.buildFunction(fn)
+}
+
+// BuildAll calls Package.Build() for each package in prog.
+// Building occurs in parallel unless the BuildSerially mode flag was set.
+//
+// BuildAll is intended for whole-program analysis; a typical compiler
+// need only build a single package.
+//
+// BuildAll is idempotent and thread-safe.
+//
+// TODO(adonovan): rename to Build.
+//
+func (prog *Program) BuildAll() {
+ var wg sync.WaitGroup
+ for _, p := range prog.packages {
+ if prog.mode&BuildSerially != 0 {
+ p.Build()
+ } else {
+ wg.Add(1)
+ go func(p *Package) {
+ p.Build()
+ wg.Done()
+ }(p)
+ }
+ }
+ wg.Wait()
+}
+
+// Build builds SSA code for all functions and vars in package p.
+//
+// Precondition: CreatePackage must have been called for all of p's
+// direct imports (and hence its direct imports must have been
+// error-free).
+//
+// Build is idempotent and thread-safe.
+//
+func (p *Package) Build() {
+ if !atomic.CompareAndSwapInt32(&p.started, 0, 1) {
+ return // already started
+ }
+ if p.info == nil {
+ return // synthetic package, e.g. "testmain"
+ }
+ if p.files == nil {
+ p.info = nil
+ return // package loaded from export data
+ }
+
+ // Ensure we have runtime type info for all exported members.
+ // TODO(adonovan): ideally belongs in memberFromObject, but
+ // that would require package creation in topological order.
+ for name, mem := range p.Members {
+ if ast.IsExported(name) {
+ p.Prog.needMethodsOf(mem.Type())
+ }
+ }
+ if p.Prog.mode&LogSource != 0 {
+ defer logStack("build %s", p)()
+ }
+ init := p.init
+ init.startBody()
+
+ var done *BasicBlock
+
+ if p.Prog.mode&BareInits == 0 {
+ // Make init() skip if package is already initialized.
+ initguard := p.Var("init$guard")
+ doinit := init.newBasicBlock("init.start")
+ done = init.newBasicBlock("init.done")
+ emitIf(init, emitLoad(init, initguard), done, doinit)
+ init.currentBlock = doinit
+ emitStore(init, initguard, vTrue, token.NoPos)
+
+ // Call the init() function of each package we import.
+ for _, pkg := range p.Object.Imports() {
+ prereq := p.Prog.packages[pkg]
+ if prereq == nil {
+ panic(fmt.Sprintf("Package(%q).Build(): unsatisfied import: Program.CreatePackage(%q) was not called", p.Object.Path(), pkg.Path()))
+ }
+ var v Call
+ v.Call.Value = prereq.init
+ v.Call.pos = init.pos
+ v.setType(types.NewTuple())
+ init.emit(&v)
+ }
+ }
+
+ var b builder
+
+ // Initialize package-level vars in correct order.
+ for _, varinit := range p.info.InitOrder {
+ if init.Prog.mode&LogSource != 0 {
+ fmt.Fprintf(os.Stderr, "build global initializer %v @ %s\n",
+ varinit.Lhs, p.Prog.Fset.Position(varinit.Rhs.Pos()))
+ }
+ if len(varinit.Lhs) == 1 {
+ // 1:1 initialization: var x, y = a(), b()
+ var lval lvalue
+ if v := varinit.Lhs[0]; v.Name() != "_" {
+ lval = &address{addr: p.values[v].(*Global), pos: v.Pos()}
+ } else {
+ lval = blank{}
+ }
+ b.assign(init, lval, varinit.Rhs, true, nil)
+ } else {
+ // n:1 initialization: var x, y := f()
+ tuple := b.exprN(init, varinit.Rhs)
+ for i, v := range varinit.Lhs {
+ if v.Name() == "_" {
+ continue
+ }
+ emitStore(init, p.values[v].(*Global), emitExtract(init, tuple, i), v.Pos())
+ }
+ }
+ }
+
+ // Build all package-level functions, init functions
+ // and methods, including unreachable/blank ones.
+ // We build them in source order, but it's not significant.
+ for _, file := range p.files {
+ for _, decl := range file.Decls {
+ if decl, ok := decl.(*ast.FuncDecl); ok {
+ b.buildFuncDecl(p, decl)
+ }
+ }
+ }
+
+ // Finish up init().
+ if p.Prog.mode&BareInits == 0 {
+ emitJump(init, done)
+ init.currentBlock = done
+ }
+ init.emit(new(Return))
+ init.finishBody()
+
+ p.info = nil // We no longer need ASTs or go/types deductions.
+
+ if p.Prog.mode&SanityCheckFunctions != 0 {
+ sanityCheckPackage(p)
+ }
+}
+
+// Like ObjectOf, but panics instead of returning nil.
+// Only valid during p's create and build phases.
+func (p *Package) objectOf(id *ast.Ident) types.Object {
+ if o := p.info.ObjectOf(id); o != nil {
+ return o
+ }
+ panic(fmt.Sprintf("no types.Object for ast.Ident %s @ %s",
+ id.Name, p.Prog.Fset.Position(id.Pos())))
+}
+
+// Like TypeOf, but panics instead of returning nil.
+// Only valid during p's create and build phases.
+func (p *Package) typeOf(e ast.Expr) types.Type {
+ if T := p.info.TypeOf(e); T != nil {
+ return T
+ }
+ panic(fmt.Sprintf("no type for %T @ %s",
+ e, p.Prog.Fset.Position(e.Pos())))
+}
diff --git a/vendor/golang.org/x/tools/go/ssa/const.go b/vendor/golang.org/x/tools/go/ssa/const.go
new file mode 100644
index 0000000..304096e
--- /dev/null
+++ b/vendor/golang.org/x/tools/go/ssa/const.go
@@ -0,0 +1,168 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package ssa
+
+// This file defines the Const SSA value type.
+
+import (
+ "fmt"
+ "go/token"
+ "strconv"
+
+ "golang.org/x/tools/go/exact"
+ "golang.org/x/tools/go/types"
+)
+
+// NewConst returns a new constant of the specified value and type.
+// val must be valid according to the specification of Const.Value.
+//
+func NewConst(val exact.Value, typ types.Type) *Const {
+ return &Const{typ, val}
+}
+
+// intConst returns an 'int' constant that evaluates to i.
+// (i is an int64 in case the host is narrower than the target.)
+func intConst(i int64) *Const {
+ return NewConst(exact.MakeInt64(i), tInt)
+}
+
+// nilConst returns a nil constant of the specified type, which may
+// be any reference type, including interfaces.
+//
+func nilConst(typ types.Type) *Const {
+ return NewConst(nil, typ)
+}
+
+// stringConst returns a 'string' constant that evaluates to s.
+func stringConst(s string) *Const {
+ return NewConst(exact.MakeString(s), tString)
+}
+
+// zeroConst returns a new "zero" constant of the specified type,
+// which must not be an array or struct type: the zero values of
+// aggregates are well-defined but cannot be represented by Const.
+//
+func zeroConst(t types.Type) *Const {
+ switch t := t.(type) {
+ case *types.Basic:
+ switch {
+ case t.Info()&types.IsBoolean != 0:
+ return NewConst(exact.MakeBool(false), t)
+ case t.Info()&types.IsNumeric != 0:
+ return NewConst(exact.MakeInt64(0), t)
+ case t.Info()&types.IsString != 0:
+ return NewConst(exact.MakeString(""), t)
+ case t.Kind() == types.UnsafePointer:
+ fallthrough
+ case t.Kind() == types.UntypedNil:
+ return nilConst(t)
+ default:
+ panic(fmt.Sprint("zeroConst for unexpected type:", t))
+ }
+ case *types.Pointer, *types.Slice, *types.Interface, *types.Chan, *types.Map, *types.Signature:
+ return nilConst(t)
+ case *types.Named:
+ return NewConst(zeroConst(t.Underlying()).Value, t)
+ case *types.Array, *types.Struct, *types.Tuple:
+ panic(fmt.Sprint("zeroConst applied to aggregate:", t))
+ }
+ panic(fmt.Sprint("zeroConst: unexpected ", t))
+}
+
+func (c *Const) RelString(from *types.Package) string {
+ var s string
+ if c.Value == nil {
+ s = "nil"
+ } else if c.Value.Kind() == exact.String {
+ s = exact.StringVal(c.Value)
+ const max = 20
+ // TODO(adonovan): don't cut a rune in half.
+ if len(s) > max {
+ s = s[:max-3] + "..." // abbreviate
+ }
+ s = strconv.Quote(s)
+ } else {
+ s = c.Value.String()
+ }
+ return s + ":" + relType(c.Type(), from)
+}
+
+func (c *Const) Name() string {
+ return c.RelString(nil)
+}
+
+func (c *Const) String() string {
+ return c.Name()
+}
+
+func (c *Const) Type() types.Type {
+ return c.typ
+}
+
+func (c *Const) Referrers() *[]Instruction {
+ return nil
+}
+
+func (c *Const) Parent() *Function { return nil }
+
+func (c *Const) Pos() token.Pos {
+ return token.NoPos
+}
+
+// IsNil returns true if this constant represents a typed or untyped nil value.
+func (c *Const) IsNil() bool {
+ return c.Value == nil
+}
+
+// Int64 returns the numeric value of this constant truncated to fit
+// a signed 64-bit integer.
+//
+func (c *Const) Int64() int64 {
+ switch x := c.Value; x.Kind() {
+ case exact.Int:
+ if i, ok := exact.Int64Val(x); ok {
+ return i
+ }
+ return 0
+ case exact.Float:
+ f, _ := exact.Float64Val(x)
+ return int64(f)
+ }
+ panic(fmt.Sprintf("unexpected constant value: %T", c.Value))
+}
+
+// Uint64 returns the numeric value of this constant truncated to fit
+// an unsigned 64-bit integer.
+//
+func (c *Const) Uint64() uint64 {
+ switch x := c.Value; x.Kind() {
+ case exact.Int:
+ if u, ok := exact.Uint64Val(x); ok {
+ return u
+ }
+ return 0
+ case exact.Float:
+ f, _ := exact.Float64Val(x)
+ return uint64(f)
+ }
+ panic(fmt.Sprintf("unexpected constant value: %T", c.Value))
+}
+
+// Float64 returns the numeric value of this constant truncated to fit
+// a float64.
+//
+func (c *Const) Float64() float64 {
+ f, _ := exact.Float64Val(c.Value)
+ return f
+}
+
+// Complex128 returns the complex value of this constant truncated to
+// fit a complex128.
+//
+func (c *Const) Complex128() complex128 {
+ re, _ := exact.Float64Val(exact.Real(c.Value))
+ im, _ := exact.Float64Val(exact.Imag(c.Value))
+ return complex(re, im)
+}
diff --git a/vendor/golang.org/x/tools/go/ssa/create.go b/vendor/golang.org/x/tools/go/ssa/create.go
new file mode 100644
index 0000000..88226ae
--- /dev/null
+++ b/vendor/golang.org/x/tools/go/ssa/create.go
@@ -0,0 +1,257 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package ssa
+
+// This file implements the CREATE phase of SSA construction.
+// See builder.go for explanation.
+
+import (
+ "fmt"
+ "go/ast"
+ "go/token"
+ "os"
+ "sync"
+
+ "golang.org/x/tools/go/types"
+ "golang.org/x/tools/go/types/typeutil"
+)
+
+// NewProgram returns a new SSA Program.
+//
+// mode controls diagnostics and checking during SSA construction.
+//
+func NewProgram(fset *token.FileSet, mode BuilderMode) *Program {
+ prog := &Program{
+ Fset: fset,
+ imported: make(map[string]*Package),
+ packages: make(map[*types.Package]*Package),
+ thunks: make(map[selectionKey]*Function),
+ bounds: make(map[*types.Func]*Function),
+ mode: mode,
+ }
+
+ h := typeutil.MakeHasher() // protected by methodsMu, in effect
+ prog.methodSets.SetHasher(h)
+ prog.canon.SetHasher(h)
+
+ return prog
+}
+
+// memberFromObject populates package pkg with a member for the
+// typechecker object obj.
+//
+// For objects from Go source code, syntax is the associated syntax
+// tree (for funcs and vars only); it will be used during the build
+// phase.
+//
+func memberFromObject(pkg *Package, obj types.Object, syntax ast.Node) {
+ name := obj.Name()
+ switch obj := obj.(type) {
+ case *types.TypeName:
+ pkg.Members[name] = &Type{
+ object: obj,
+ pkg: pkg,
+ }
+
+ case *types.Const:
+ c := &NamedConst{
+ object: obj,
+ Value: NewConst(obj.Val(), obj.Type()),
+ pkg: pkg,
+ }
+ pkg.values[obj] = c.Value
+ pkg.Members[name] = c
+
+ case *types.Var:
+ g := &Global{
+ Pkg: pkg,
+ name: name,
+ object: obj,
+ typ: types.NewPointer(obj.Type()), // address
+ pos: obj.Pos(),
+ }
+ pkg.values[obj] = g
+ pkg.Members[name] = g
+
+ case *types.Func:
+ sig := obj.Type().(*types.Signature)
+ if sig.Recv() == nil && name == "init" {
+ pkg.ninit++
+ name = fmt.Sprintf("init#%d", pkg.ninit)
+ }
+ fn := &Function{
+ name: name,
+ object: obj,
+ Signature: sig,
+ syntax: syntax,
+ pos: obj.Pos(),
+ Pkg: pkg,
+ Prog: pkg.Prog,
+ }
+ if syntax == nil {
+ fn.Synthetic = "loaded from gc object file"
+ }
+
+ pkg.values[obj] = fn
+ if sig.Recv() == nil {
+ pkg.Members[name] = fn // package-level function
+ }
+
+ default: // (incl. *types.Package)
+ panic("unexpected Object type: " + obj.String())
+ }
+}
+
+// membersFromDecl populates package pkg with members for each
+// typechecker object (var, func, const or type) associated with the
+// specified decl.
+//
+func membersFromDecl(pkg *Package, decl ast.Decl) {
+ switch decl := decl.(type) {
+ case *ast.GenDecl: // import, const, type or var
+ switch decl.Tok {
+ case token.CONST:
+ for _, spec := range decl.Specs {
+ for _, id := range spec.(*ast.ValueSpec).Names {
+ if !isBlankIdent(id) {
+ memberFromObject(pkg, pkg.info.Defs[id], nil)
+ }
+ }
+ }
+
+ case token.VAR:
+ for _, spec := range decl.Specs {
+ for _, id := range spec.(*ast.ValueSpec).Names {
+ if !isBlankIdent(id) {
+ memberFromObject(pkg, pkg.info.Defs[id], spec)
+ }
+ }
+ }
+
+ case token.TYPE:
+ for _, spec := range decl.Specs {
+ id := spec.(*ast.TypeSpec).Name
+ if !isBlankIdent(id) {
+ memberFromObject(pkg, pkg.info.Defs[id], nil)
+ }
+ }
+ }
+
+ case *ast.FuncDecl:
+ id := decl.Name
+ if !isBlankIdent(id) {
+ memberFromObject(pkg, pkg.info.Defs[id], decl)
+ }
+ }
+}
+
+// CreatePackage constructs and returns an SSA Package from the
+// specified type-checked, error-free file ASTs, and populates its
+// Members mapping.
+//
+// importable determines whether this package should be returned by a
+// subsequent call to ImportedPackage(pkg.Path()).
+//
+// The real work of building SSA form for each function is not done
+// until a subsequent call to Package.Build().
+//
+func (prog *Program) CreatePackage(pkg *types.Package, files []*ast.File, info *types.Info, importable bool) *Package {
+ p := &Package{
+ Prog: prog,
+ Members: make(map[string]Member),
+ values: make(map[types.Object]Value),
+ Object: pkg,
+ info: info, // transient (CREATE and BUILD phases)
+ files: files, // transient (CREATE and BUILD phases)
+ }
+
+ // Add init() function.
+ p.init = &Function{
+ name: "init",
+ Signature: new(types.Signature),
+ Synthetic: "package initializer",
+ Pkg: p,
+ Prog: prog,
+ }
+ p.Members[p.init.name] = p.init
+
+ // CREATE phase.
+ // Allocate all package members: vars, funcs, consts and types.
+ if len(files) > 0 {
+ // Go source package.
+ for _, file := range files {
+ for _, decl := range file.Decls {
+ membersFromDecl(p, decl)
+ }
+ }
+ } else {
+ // GC-compiled binary package.
+ // No code.
+ // No position information.
+ scope := p.Object.Scope()
+ for _, name := range scope.Names() {
+ obj := scope.Lookup(name)
+ memberFromObject(p, obj, nil)
+ if obj, ok := obj.(*types.TypeName); ok {
+ named := obj.Type().(*types.Named)
+ for i, n := 0, named.NumMethods(); i < n; i++ {
+ memberFromObject(p, named.Method(i), nil)
+ }
+ }
+ }
+ }
+
+ if prog.mode&BareInits == 0 {
+ // Add initializer guard variable.
+ initguard := &Global{
+ Pkg: p,
+ name: "init$guard",
+ typ: types.NewPointer(tBool),
+ }
+ p.Members[initguard.Name()] = initguard
+ }
+
+ if prog.mode&GlobalDebug != 0 {
+ p.SetDebugMode(true)
+ }
+
+ if prog.mode&PrintPackages != 0 {
+ printMu.Lock()
+ p.WriteTo(os.Stdout)
+ printMu.Unlock()
+ }
+
+ if importable {
+ prog.imported[p.Object.Path()] = p
+ }
+ prog.packages[p.Object] = p
+
+ return p
+}
+
+// printMu serializes printing of Packages/Functions to stdout.
+var printMu sync.Mutex
+
+// AllPackages returns a new slice containing all packages in the
+// program prog in unspecified order.
+//
+func (prog *Program) AllPackages() []*Package {
+ pkgs := make([]*Package, 0, len(prog.packages))
+ for _, pkg := range prog.packages {
+ pkgs = append(pkgs, pkg)
+ }
+ return pkgs
+}
+
+// ImportedPackage returns the importable SSA Package whose import
+// path is path, or nil if no such SSA package has been created.
+//
+// Not all packages are importable. For example, no import
+// declaration can resolve to the x_test package created by 'go test'
+// or the ad-hoc main package created 'go build foo.go'.
+//
+func (prog *Program) ImportedPackage(path string) *Package {
+ return prog.imported[path]
+}
diff --git a/vendor/golang.org/x/tools/go/ssa/doc.go b/vendor/golang.org/x/tools/go/ssa/doc.go
new file mode 100644
index 0000000..2aa04f4
--- /dev/null
+++ b/vendor/golang.org/x/tools/go/ssa/doc.go
@@ -0,0 +1,123 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package ssa defines a representation of the elements of Go programs
+// (packages, types, functions, variables and constants) using a
+// static single-assignment (SSA) form intermediate representation
+// (IR) for the bodies of functions.
+//
+// THIS INTERFACE IS EXPERIMENTAL AND IS LIKELY TO CHANGE.
+//
+// For an introduction to SSA form, see
+// http://en.wikipedia.org/wiki/Static_single_assignment_form.
+// This page provides a broader reading list:
+// http://www.dcs.gla.ac.uk/~jsinger/ssa.html.
+//
+// The level of abstraction of the SSA form is intentionally close to
+// the source language to facilitate construction of source analysis
+// tools. It is not intended for machine code generation.
+//
+// All looping, branching and switching constructs are replaced with
+// unstructured control flow. Higher-level control flow constructs
+// such as multi-way branch can be reconstructed as needed; see
+// ssautil.Switches() for an example.
+//
+// To construct an SSA-form program, call ssautil.CreateProgram on a
+// loader.Program, a set of type-checked packages created from
+// parsed Go source files. The resulting ssa.Program contains all the
+// packages and their members, but SSA code is not created for
+// function bodies until a subsequent call to (*Package).Build.
+//
+// The builder initially builds a naive SSA form in which all local
+// variables are addresses of stack locations with explicit loads and
+// stores. Registerisation of eligible locals and φ-node insertion
+// using dominance and dataflow are then performed as a second pass
+// called "lifting" to improve the accuracy and performance of
+// subsequent analyses; this pass can be skipped by setting the
+// NaiveForm builder flag.
+//
+// The primary interfaces of this package are:
+//
+// - Member: a named member of a Go package.
+// - Value: an expression that yields a value.
+// - Instruction: a statement that consumes values and performs computation.
+// - Node: a Value or Instruction (emphasizing its membership in the SSA value graph)
+//
+// A computation that yields a result implements both the Value and
+// Instruction interfaces. The following table shows for each
+// concrete type which of these interfaces it implements.
+//
+// Value? Instruction? Member?
+// *Alloc ✔ ✔
+// *BinOp ✔ ✔
+// *Builtin ✔
+// *Call ✔ ✔
+// *ChangeInterface ✔ ✔
+// *ChangeType ✔ ✔
+// *Const ✔
+// *Convert ✔ ✔
+// *DebugRef ✔
+// *Defer ✔
+// *Extract ✔ ✔
+// *Field ✔ ✔
+// *FieldAddr ✔ ✔
+// *FreeVar ✔
+// *Function ✔ ✔ (func)
+// *Global ✔ ✔ (var)
+// *Go ✔
+// *If ✔
+// *Index ✔ ✔
+// *IndexAddr ✔ ✔
+// *Jump ✔
+// *Lookup ✔ ✔
+// *MakeChan ✔ ✔
+// *MakeClosure ✔ ✔
+// *MakeInterface ✔ ✔
+// *MakeMap ✔ ✔
+// *MakeSlice ✔ ✔
+// *MapUpdate ✔
+// *NamedConst ✔ (const)
+// *Next ✔ ✔
+// *Panic ✔
+// *Parameter ✔
+// *Phi ✔ ✔
+// *Range ✔ ✔
+// *Return ✔
+// *RunDefers ✔
+// *Select ✔ ✔
+// *Send ✔
+// *Slice ✔ ✔
+// *Store ✔
+// *Type ✔ (type)
+// *TypeAssert ✔ ✔
+// *UnOp ✔ ✔
+//
+// Other key types in this package include: Program, Package, Function
+// and BasicBlock.
+//
+// The program representation constructed by this package is fully
+// resolved internally, i.e. it does not rely on the names of Values,
+// Packages, Functions, Types or BasicBlocks for the correct
+// interpretation of the program. Only the identities of objects and
+// the topology of the SSA and type graphs are semantically
+// significant. (There is one exception: Ids, used to identify field
+// and method names, contain strings.) Avoidance of name-based
+// operations simplifies the implementation of subsequent passes and
+// can make them very efficient. Many objects are nonetheless named
+// to aid in debugging, but it is not essential that the names be
+// either accurate or unambiguous. The public API exposes a number of
+// name-based maps for client convenience.
+//
+// The ssa/ssautil package provides various utilities that depend only
+// on the public API of this package.
+//
+// TODO(adonovan): Consider the exceptional control-flow implications
+// of defer and recover().
+//
+// TODO(adonovan): write a how-to document for all the various cases
+// of trying to determine corresponding elements across the four
+// domains of source locations, ast.Nodes, types.Objects,
+// ssa.Values/Instructions.
+//
+package ssa // import "golang.org/x/tools/go/ssa"
diff --git a/vendor/golang.org/x/tools/go/ssa/dom.go b/vendor/golang.org/x/tools/go/ssa/dom.go
new file mode 100644
index 0000000..12ef430
--- /dev/null
+++ b/vendor/golang.org/x/tools/go/ssa/dom.go
@@ -0,0 +1,341 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package ssa
+
+// This file defines algorithms related to dominance.
+
+// Dominator tree construction ----------------------------------------
+//
+// We use the algorithm described in Lengauer & Tarjan. 1979. A fast
+// algorithm for finding dominators in a flowgraph.
+// http://doi.acm.org/10.1145/357062.357071
+//
+// We also apply the optimizations to SLT described in Georgiadis et
+// al, Finding Dominators in Practice, JGAA 2006,
+// http://jgaa.info/accepted/2006/GeorgiadisTarjanWerneck2006.10.1.pdf
+// to avoid the need for buckets of size > 1.
+
+import (
+ "bytes"
+ "fmt"
+ "math/big"
+ "os"
+ "sort"
+)
+
+// Idom returns the block that immediately dominates b:
+// its parent in the dominator tree, if any.
+// Neither the entry node (b.Index==0) nor recover node
+// (b==b.Parent().Recover()) have a parent.
+//
+func (b *BasicBlock) Idom() *BasicBlock { return b.dom.idom }
+
+// Dominees returns the list of blocks that b immediately dominates:
+// its children in the dominator tree.
+//
+func (b *BasicBlock) Dominees() []*BasicBlock { return b.dom.children }
+
+// Dominates reports whether b dominates c.
+func (b *BasicBlock) Dominates(c *BasicBlock) bool {
+ return b.dom.pre <= c.dom.pre && c.dom.post <= b.dom.post
+}
+
+type byDomPreorder []*BasicBlock
+
+func (a byDomPreorder) Len() int { return len(a) }
+func (a byDomPreorder) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
+func (a byDomPreorder) Less(i, j int) bool { return a[i].dom.pre < a[j].dom.pre }
+
+// DomPreorder returns a new slice containing the blocks of f in
+// dominator tree preorder.
+//
+func (f *Function) DomPreorder() []*BasicBlock {
+ n := len(f.Blocks)
+ order := make(byDomPreorder, n, n)
+ copy(order, f.Blocks)
+ sort.Sort(order)
+ return order
+}
+
+// domInfo contains a BasicBlock's dominance information.
+type domInfo struct {
+ idom *BasicBlock // immediate dominator (parent in domtree)
+ children []*BasicBlock // nodes immediately dominated by this one
+ pre, post int32 // pre- and post-order numbering within domtree
+}
+
+// ltState holds the working state for Lengauer-Tarjan algorithm
+// (during which domInfo.pre is repurposed for CFG DFS preorder number).
+type ltState struct {
+ // Each slice is indexed by b.Index.
+ sdom []*BasicBlock // b's semidominator
+ parent []*BasicBlock // b's parent in DFS traversal of CFG
+ ancestor []*BasicBlock // b's ancestor with least sdom
+}
+
+// dfs implements the depth-first search part of the LT algorithm.
+func (lt *ltState) dfs(v *BasicBlock, i int32, preorder []*BasicBlock) int32 {
+ preorder[i] = v
+ v.dom.pre = i // For now: DFS preorder of spanning tree of CFG
+ i++
+ lt.sdom[v.Index] = v
+ lt.link(nil, v)
+ for _, w := range v.Succs {
+ if lt.sdom[w.Index] == nil {
+ lt.parent[w.Index] = v
+ i = lt.dfs(w, i, preorder)
+ }
+ }
+ return i
+}
+
+// eval implements the EVAL part of the LT algorithm.
+func (lt *ltState) eval(v *BasicBlock) *BasicBlock {
+ // TODO(adonovan): opt: do path compression per simple LT.
+ u := v
+ for ; lt.ancestor[v.Index] != nil; v = lt.ancestor[v.Index] {
+ if lt.sdom[v.Index].dom.pre < lt.sdom[u.Index].dom.pre {
+ u = v
+ }
+ }
+ return u
+}
+
+// link implements the LINK part of the LT algorithm.
+func (lt *ltState) link(v, w *BasicBlock) {
+ lt.ancestor[w.Index] = v
+}
+
+// buildDomTree computes the dominator tree of f using the LT algorithm.
+// Precondition: all blocks are reachable (e.g. optimizeBlocks has been run).
+//
+func buildDomTree(f *Function) {
+ // The step numbers refer to the original LT paper; the
+ // reordering is due to Georgiadis.
+
+ // Clear any previous domInfo.
+ for _, b := range f.Blocks {
+ b.dom = domInfo{}
+ }
+
+ n := len(f.Blocks)
+ // Allocate space for 5 contiguous [n]*BasicBlock arrays:
+ // sdom, parent, ancestor, preorder, buckets.
+ space := make([]*BasicBlock, 5*n, 5*n)
+ lt := ltState{
+ sdom: space[0:n],
+ parent: space[n : 2*n],
+ ancestor: space[2*n : 3*n],
+ }
+
+ // Step 1. Number vertices by depth-first preorder.
+ preorder := space[3*n : 4*n]
+ root := f.Blocks[0]
+ prenum := lt.dfs(root, 0, preorder)
+ recover := f.Recover
+ if recover != nil {
+ lt.dfs(recover, prenum, preorder)
+ }
+
+ buckets := space[4*n : 5*n]
+ copy(buckets, preorder)
+
+ // In reverse preorder...
+ for i := int32(n) - 1; i > 0; i-- {
+ w := preorder[i]
+
+ // Step 3. Implicitly define the immediate dominator of each node.
+ for v := buckets[i]; v != w; v = buckets[v.dom.pre] {
+ u := lt.eval(v)
+ if lt.sdom[u.Index].dom.pre < i {
+ v.dom.idom = u
+ } else {
+ v.dom.idom = w
+ }
+ }
+
+ // Step 2. Compute the semidominators of all nodes.
+ lt.sdom[w.Index] = lt.parent[w.Index]
+ for _, v := range w.Preds {
+ u := lt.eval(v)
+ if lt.sdom[u.Index].dom.pre < lt.sdom[w.Index].dom.pre {
+ lt.sdom[w.Index] = lt.sdom[u.Index]
+ }
+ }
+
+ lt.link(lt.parent[w.Index], w)
+
+ if lt.parent[w.Index] == lt.sdom[w.Index] {
+ w.dom.idom = lt.parent[w.Index]
+ } else {
+ buckets[i] = buckets[lt.sdom[w.Index].dom.pre]
+ buckets[lt.sdom[w.Index].dom.pre] = w
+ }
+ }
+
+ // The final 'Step 3' is now outside the loop.
+ for v := buckets[0]; v != root; v = buckets[v.dom.pre] {
+ v.dom.idom = root
+ }
+
+ // Step 4. Explicitly define the immediate dominator of each
+ // node, in preorder.
+ for _, w := range preorder[1:] {
+ if w == root || w == recover {
+ w.dom.idom = nil
+ } else {
+ if w.dom.idom != lt.sdom[w.Index] {
+ w.dom.idom = w.dom.idom.dom.idom
+ }
+ // Calculate Children relation as inverse of Idom.
+ w.dom.idom.dom.children = append(w.dom.idom.dom.children, w)
+ }
+ }
+
+ pre, post := numberDomTree(root, 0, 0)
+ if recover != nil {
+ numberDomTree(recover, pre, post)
+ }
+
+ // printDomTreeDot(os.Stderr, f) // debugging
+ // printDomTreeText(os.Stderr, root, 0) // debugging
+
+ if f.Prog.mode&SanityCheckFunctions != 0 {
+ sanityCheckDomTree(f)
+ }
+}
+
+// numberDomTree sets the pre- and post-order numbers of a depth-first
+// traversal of the dominator tree rooted at v. These are used to
+// answer dominance queries in constant time.
+//
+func numberDomTree(v *BasicBlock, pre, post int32) (int32, int32) {
+ v.dom.pre = pre
+ pre++
+ for _, child := range v.dom.children {
+ pre, post = numberDomTree(child, pre, post)
+ }
+ v.dom.post = post
+ post++
+ return pre, post
+}
+
+// Testing utilities ----------------------------------------
+
+// sanityCheckDomTree checks the correctness of the dominator tree
+// computed by the LT algorithm by comparing against the dominance
+// relation computed by a naive Kildall-style forward dataflow
+// analysis (Algorithm 10.16 from the "Dragon" book).
+//
+func sanityCheckDomTree(f *Function) {
+ n := len(f.Blocks)
+
+ // D[i] is the set of blocks that dominate f.Blocks[i],
+ // represented as a bit-set of block indices.
+ D := make([]big.Int, n)
+
+ one := big.NewInt(1)
+
+ // all is the set of all blocks; constant.
+ var all big.Int
+ all.Set(one).Lsh(&all, uint(n)).Sub(&all, one)
+
+ // Initialization.
+ for i, b := range f.Blocks {
+ if i == 0 || b == f.Recover {
+ // A root is dominated only by itself.
+ D[i].SetBit(&D[0], 0, 1)
+ } else {
+ // All other blocks are (initially) dominated
+ // by every block.
+ D[i].Set(&all)
+ }
+ }
+
+ // Iteration until fixed point.
+ for changed := true; changed; {
+ changed = false
+ for i, b := range f.Blocks {
+ if i == 0 || b == f.Recover {
+ continue
+ }
+ // Compute intersection across predecessors.
+ var x big.Int
+ x.Set(&all)
+ for _, pred := range b.Preds {
+ x.And(&x, &D[pred.Index])
+ }
+ x.SetBit(&x, i, 1) // a block always dominates itself.
+ if D[i].Cmp(&x) != 0 {
+ D[i].Set(&x)
+ changed = true
+ }
+ }
+ }
+
+ // Check the entire relation. O(n^2).
+ // The Recover block (if any) must be treated specially so we skip it.
+ ok := true
+ for i := 0; i < n; i++ {
+ for j := 0; j < n; j++ {
+ b, c := f.Blocks[i], f.Blocks[j]
+ if c == f.Recover {
+ continue
+ }
+ actual := b.Dominates(c)
+ expected := D[j].Bit(i) == 1
+ if actual != expected {
+ fmt.Fprintf(os.Stderr, "dominates(%s, %s)==%t, want %t\n", b, c, actual, expected)
+ ok = false
+ }
+ }
+ }
+
+ preorder := f.DomPreorder()
+ for _, b := range f.Blocks {
+ if got := preorder[b.dom.pre]; got != b {
+ fmt.Fprintf(os.Stderr, "preorder[%d]==%s, want %s\n", b.dom.pre, got, b)
+ ok = false
+ }
+ }
+
+ if !ok {
+ panic("sanityCheckDomTree failed for " + f.String())
+ }
+
+}
+
+// Printing functions ----------------------------------------
+
+// printDomTree prints the dominator tree as text, using indentation.
+func printDomTreeText(buf *bytes.Buffer, v *BasicBlock, indent int) {
+ fmt.Fprintf(buf, "%*s%s\n", 4*indent, "", v)
+ for _, child := range v.dom.children {
+ printDomTreeText(buf, child, indent+1)
+ }
+}
+
+// printDomTreeDot prints the dominator tree of f in AT&T GraphViz
+// (.dot) format.
+func printDomTreeDot(buf *bytes.Buffer, f *Function) {
+ fmt.Fprintln(buf, "//", f)
+ fmt.Fprintln(buf, "digraph domtree {")
+ for i, b := range f.Blocks {
+ v := b.dom
+ fmt.Fprintf(buf, "\tn%d [label=\"%s (%d, %d)\",shape=\"rectangle\"];\n", v.pre, b, v.pre, v.post)
+ // TODO(adonovan): improve appearance of edges
+ // belonging to both dominator tree and CFG.
+
+ // Dominator tree edge.
+ if i != 0 {
+ fmt.Fprintf(buf, "\tn%d -> n%d [style=\"solid\",weight=100];\n", v.idom.dom.pre, v.pre)
+ }
+ // CFG edges.
+ for _, pred := range b.Preds {
+ fmt.Fprintf(buf, "\tn%d -> n%d [style=\"dotted\",weight=0];\n", pred.dom.pre, v.pre)
+ }
+ }
+ fmt.Fprintln(buf, "}")
+}
diff --git a/vendor/golang.org/x/tools/go/ssa/emit.go b/vendor/golang.org/x/tools/go/ssa/emit.go
new file mode 100644
index 0000000..fa9646b
--- /dev/null
+++ b/vendor/golang.org/x/tools/go/ssa/emit.go
@@ -0,0 +1,469 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package ssa
+
+// Helpers for emitting SSA instructions.
+
+import (
+ "fmt"
+ "go/ast"
+ "go/token"
+
+ "golang.org/x/tools/go/types"
+)
+
+// emitNew emits to f a new (heap Alloc) instruction allocating an
+// object of type typ. pos is the optional source location.
+//
+func emitNew(f *Function, typ types.Type, pos token.Pos) *Alloc {
+ v := &Alloc{Heap: true}
+ v.setType(types.NewPointer(typ))
+ v.setPos(pos)
+ f.emit(v)
+ return v
+}
+
+// emitLoad emits to f an instruction to load the address addr into a
+// new temporary, and returns the value so defined.
+//
+func emitLoad(f *Function, addr Value) *UnOp {
+ v := &UnOp{Op: token.MUL, X: addr}
+ v.setType(deref(addr.Type()))
+ f.emit(v)
+ return v
+}
+
+// emitDebugRef emits to f a DebugRef pseudo-instruction associating
+// expression e with value v.
+//
+func emitDebugRef(f *Function, e ast.Expr, v Value, isAddr bool) {
+ if !f.debugInfo() {
+ return // debugging not enabled
+ }
+ if v == nil || e == nil {
+ panic("nil")
+ }
+ var obj types.Object
+ e = unparen(e)
+ if id, ok := e.(*ast.Ident); ok {
+ if isBlankIdent(id) {
+ return
+ }
+ obj = f.Pkg.objectOf(id)
+ switch obj.(type) {
+ case *types.Nil, *types.Const, *types.Builtin:
+ return
+ }
+ }
+ f.emit(&DebugRef{
+ X: v,
+ Expr: e,
+ IsAddr: isAddr,
+ object: obj,
+ })
+}
+
+// emitArith emits to f code to compute the binary operation op(x, y)
+// where op is an eager shift, logical or arithmetic operation.
+// (Use emitCompare() for comparisons and Builder.logicalBinop() for
+// non-eager operations.)
+//
+func emitArith(f *Function, op token.Token, x, y Value, t types.Type, pos token.Pos) Value {
+ switch op {
+ case token.SHL, token.SHR:
+ x = emitConv(f, x, t)
+ // y may be signed or an 'untyped' constant.
+ // TODO(adonovan): whence signed values?
+ if b, ok := y.Type().Underlying().(*types.Basic); ok && b.Info()&types.IsUnsigned == 0 {
+ y = emitConv(f, y, types.Typ[types.Uint64])
+ }
+
+ case token.ADD, token.SUB, token.MUL, token.QUO, token.REM, token.AND, token.OR, token.XOR, token.AND_NOT:
+ x = emitConv(f, x, t)
+ y = emitConv(f, y, t)
+
+ default:
+ panic("illegal op in emitArith: " + op.String())
+
+ }
+ v := &BinOp{
+ Op: op,
+ X: x,
+ Y: y,
+ }
+ v.setPos(pos)
+ v.setType(t)
+ return f.emit(v)
+}
+
+// emitCompare emits to f code compute the boolean result of
+// comparison comparison 'x op y'.
+//
+func emitCompare(f *Function, op token.Token, x, y Value, pos token.Pos) Value {
+ xt := x.Type().Underlying()
+ yt := y.Type().Underlying()
+
+ // Special case to optimise a tagless SwitchStmt so that
+ // these are equivalent
+ // switch { case e: ...}
+ // switch true { case e: ... }
+ // if e==true { ... }
+ // even in the case when e's type is an interface.
+ // TODO(adonovan): opt: generalise to x==true, false!=y, etc.
+ if x == vTrue && op == token.EQL {
+ if yt, ok := yt.(*types.Basic); ok && yt.Info()&types.IsBoolean != 0 {
+ return y
+ }
+ }
+
+ if types.Identical(xt, yt) {
+ // no conversion necessary
+ } else if _, ok := xt.(*types.Interface); ok {
+ y = emitConv(f, y, x.Type())
+ } else if _, ok := yt.(*types.Interface); ok {
+ x = emitConv(f, x, y.Type())
+ } else if _, ok := x.(*Const); ok {
+ x = emitConv(f, x, y.Type())
+ } else if _, ok := y.(*Const); ok {
+ y = emitConv(f, y, x.Type())
+ } else {
+ // other cases, e.g. channels. No-op.
+ }
+
+ v := &BinOp{
+ Op: op,
+ X: x,
+ Y: y,
+ }
+ v.setPos(pos)
+ v.setType(tBool)
+ return f.emit(v)
+}
+
+// isValuePreserving returns true if a conversion from ut_src to
+// ut_dst is value-preserving, i.e. just a change of type.
+// Precondition: neither argument is a named type.
+//
+func isValuePreserving(ut_src, ut_dst types.Type) bool {
+ // Identical underlying types?
+ if types.Identical(ut_dst, ut_src) {
+ return true
+ }
+
+ switch ut_dst.(type) {
+ case *types.Chan:
+ // Conversion between channel types?
+ _, ok := ut_src.(*types.Chan)
+ return ok
+
+ case *types.Pointer:
+ // Conversion between pointers with identical base types?
+ _, ok := ut_src.(*types.Pointer)
+ return ok
+ }
+ return false
+}
+
+// emitConv emits to f code to convert Value val to exactly type typ,
+// and returns the converted value. Implicit conversions are required
+// by language assignability rules in assignments, parameter passing,
+// etc. Conversions cannot fail dynamically.
+//
+func emitConv(f *Function, val Value, typ types.Type) Value {
+ t_src := val.Type()
+
+ // Identical types? Conversion is a no-op.
+ if types.Identical(t_src, typ) {
+ return val
+ }
+
+ ut_dst := typ.Underlying()
+ ut_src := t_src.Underlying()
+
+ // Just a change of type, but not value or representation?
+ if isValuePreserving(ut_src, ut_dst) {
+ c := &ChangeType{X: val}
+ c.setType(typ)
+ return f.emit(c)
+ }
+
+ // Conversion to, or construction of a value of, an interface type?
+ if _, ok := ut_dst.(*types.Interface); ok {
+ // Assignment from one interface type to another?
+ if _, ok := ut_src.(*types.Interface); ok {
+ c := &ChangeInterface{X: val}
+ c.setType(typ)
+ return f.emit(c)
+ }
+
+ // Untyped nil constant? Return interface-typed nil constant.
+ if ut_src == tUntypedNil {
+ return nilConst(typ)
+ }
+
+ // Convert (non-nil) "untyped" literals to their default type.
+ if t, ok := ut_src.(*types.Basic); ok && t.Info()&types.IsUntyped != 0 {
+ val = emitConv(f, val, DefaultType(ut_src))
+ }
+
+ f.Pkg.Prog.needMethodsOf(val.Type())
+ mi := &MakeInterface{X: val}
+ mi.setType(typ)
+ return f.emit(mi)
+ }
+
+ // Conversion of a compile-time constant value?
+ if c, ok := val.(*Const); ok {
+ if _, ok := ut_dst.(*types.Basic); ok || c.IsNil() {
+ // Conversion of a compile-time constant to
+ // another constant type results in a new
+ // constant of the destination type and
+ // (initially) the same abstract value.
+ // We don't truncate the value yet.
+ return NewConst(c.Value, typ)
+ }
+
+ // We're converting from constant to non-constant type,
+ // e.g. string -> []byte/[]rune.
+ }
+
+ // A representation-changing conversion?
+ // At least one of {ut_src,ut_dst} must be *Basic.
+ // (The other may be []byte or []rune.)
+ _, ok1 := ut_src.(*types.Basic)
+ _, ok2 := ut_dst.(*types.Basic)
+ if ok1 || ok2 {
+ c := &Convert{X: val}
+ c.setType(typ)
+ return f.emit(c)
+ }
+
+ panic(fmt.Sprintf("in %s: cannot convert %s (%s) to %s", f, val, val.Type(), typ))
+}
+
+// emitStore emits to f an instruction to store value val at location
+// addr, applying implicit conversions as required by assignability rules.
+//
+func emitStore(f *Function, addr, val Value, pos token.Pos) *Store {
+ s := &Store{
+ Addr: addr,
+ Val: emitConv(f, val, deref(addr.Type())),
+ pos: pos,
+ }
+ f.emit(s)
+ return s
+}
+
+// emitJump emits to f a jump to target, and updates the control-flow graph.
+// Postcondition: f.currentBlock is nil.
+//
+func emitJump(f *Function, target *BasicBlock) {
+ b := f.currentBlock
+ b.emit(new(Jump))
+ addEdge(b, target)
+ f.currentBlock = nil
+}
+
+// emitIf emits to f a conditional jump to tblock or fblock based on
+// cond, and updates the control-flow graph.
+// Postcondition: f.currentBlock is nil.
+//
+func emitIf(f *Function, cond Value, tblock, fblock *BasicBlock) {
+ b := f.currentBlock
+ b.emit(&If{Cond: cond})
+ addEdge(b, tblock)
+ addEdge(b, fblock)
+ f.currentBlock = nil
+}
+
+// emitExtract emits to f an instruction to extract the index'th
+// component of tuple. It returns the extracted value.
+//
+func emitExtract(f *Function, tuple Value, index int) Value {
+ e := &Extract{Tuple: tuple, Index: index}
+ e.setType(tuple.Type().(*types.Tuple).At(index).Type())
+ return f.emit(e)
+}
+
+// emitTypeAssert emits to f a type assertion value := x.(t) and
+// returns the value. x.Type() must be an interface.
+//
+func emitTypeAssert(f *Function, x Value, t types.Type, pos token.Pos) Value {
+ a := &TypeAssert{X: x, AssertedType: t}
+ a.setPos(pos)
+ a.setType(t)
+ return f.emit(a)
+}
+
+// emitTypeTest emits to f a type test value,ok := x.(t) and returns
+// a (value, ok) tuple. x.Type() must be an interface.
+//
+func emitTypeTest(f *Function, x Value, t types.Type, pos token.Pos) Value {
+ a := &TypeAssert{
+ X: x,
+ AssertedType: t,
+ CommaOk: true,
+ }
+ a.setPos(pos)
+ a.setType(types.NewTuple(
+ newVar("value", t),
+ varOk,
+ ))
+ return f.emit(a)
+}
+
+// emitTailCall emits to f a function call in tail position. The
+// caller is responsible for all fields of 'call' except its type.
+// Intended for wrapper methods.
+// Precondition: f does/will not use deferred procedure calls.
+// Postcondition: f.currentBlock is nil.
+//
+func emitTailCall(f *Function, call *Call) {
+ tresults := f.Signature.Results()
+ nr := tresults.Len()
+ if nr == 1 {
+ call.typ = tresults.At(0).Type()
+ } else {
+ call.typ = tresults
+ }
+ tuple := f.emit(call)
+ var ret Return
+ switch nr {
+ case 0:
+ // no-op
+ case 1:
+ ret.Results = []Value{tuple}
+ default:
+ for i := 0; i < nr; i++ {
+ v := emitExtract(f, tuple, i)
+ // TODO(adonovan): in principle, this is required:
+ // v = emitConv(f, o.Type, f.Signature.Results[i].Type)
+ // but in practice emitTailCall is only used when
+ // the types exactly match.
+ ret.Results = append(ret.Results, v)
+ }
+ }
+ f.emit(&ret)
+ f.currentBlock = nil
+}
+
+// emitImplicitSelections emits to f code to apply the sequence of
+// implicit field selections specified by indices to base value v, and
+// returns the selected value.
+//
+// If v is the address of a struct, the result will be the address of
+// a field; if it is the value of a struct, the result will be the
+// value of a field.
+//
+func emitImplicitSelections(f *Function, v Value, indices []int) Value {
+ for _, index := range indices {
+ fld := deref(v.Type()).Underlying().(*types.Struct).Field(index)
+
+ if isPointer(v.Type()) {
+ instr := &FieldAddr{
+ X: v,
+ Field: index,
+ }
+ instr.setType(types.NewPointer(fld.Type()))
+ v = f.emit(instr)
+ // Load the field's value iff indirectly embedded.
+ if isPointer(fld.Type()) {
+ v = emitLoad(f, v)
+ }
+ } else {
+ instr := &Field{
+ X: v,
+ Field: index,
+ }
+ instr.setType(fld.Type())
+ v = f.emit(instr)
+ }
+ }
+ return v
+}
+
+// emitFieldSelection emits to f code to select the index'th field of v.
+//
+// If wantAddr, the input must be a pointer-to-struct and the result
+// will be the field's address; otherwise the result will be the
+// field's value.
+// Ident id is used for position and debug info.
+//
+func emitFieldSelection(f *Function, v Value, index int, wantAddr bool, id *ast.Ident) Value {
+ fld := deref(v.Type()).Underlying().(*types.Struct).Field(index)
+ if isPointer(v.Type()) {
+ instr := &FieldAddr{
+ X: v,
+ Field: index,
+ }
+ instr.setPos(id.Pos())
+ instr.setType(types.NewPointer(fld.Type()))
+ v = f.emit(instr)
+ // Load the field's value iff we don't want its address.
+ if !wantAddr {
+ v = emitLoad(f, v)
+ }
+ } else {
+ instr := &Field{
+ X: v,
+ Field: index,
+ }
+ instr.setPos(id.Pos())
+ instr.setType(fld.Type())
+ v = f.emit(instr)
+ }
+ emitDebugRef(f, id, v, wantAddr)
+ return v
+}
+
+// zeroValue emits to f code to produce a zero value of type t,
+// and returns it.
+//
+func zeroValue(f *Function, t types.Type) Value {
+ switch t.Underlying().(type) {
+ case *types.Struct, *types.Array:
+ return emitLoad(f, f.addLocal(t, token.NoPos))
+ default:
+ return zeroConst(t)
+ }
+}
+
+// createRecoverBlock emits to f a block of code to return after a
+// recovered panic, and sets f.Recover to it.
+//
+// If f's result parameters are named, the code loads and returns
+// their current values, otherwise it returns the zero values of their
+// type.
+//
+// Idempotent.
+//
+func createRecoverBlock(f *Function) {
+ if f.Recover != nil {
+ return // already created
+ }
+ saved := f.currentBlock
+
+ f.Recover = f.newBasicBlock("recover")
+ f.currentBlock = f.Recover
+
+ var results []Value
+ if f.namedResults != nil {
+ // Reload NRPs to form value tuple.
+ for _, r := range f.namedResults {
+ results = append(results, emitLoad(f, r))
+ }
+ } else {
+ R := f.Signature.Results()
+ for i, n := 0, R.Len(); i < n; i++ {
+ T := R.At(i).Type()
+
+ // Return zero value of each result type.
+ results = append(results, zeroValue(f, T))
+ }
+ }
+ f.emit(&Return{Results: results})
+
+ f.currentBlock = saved
+}
diff --git a/vendor/golang.org/x/tools/go/ssa/func.go b/vendor/golang.org/x/tools/go/ssa/func.go
new file mode 100644
index 0000000..a9c0f75
--- /dev/null
+++ b/vendor/golang.org/x/tools/go/ssa/func.go
@@ -0,0 +1,690 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package ssa
+
+// This file implements the Function and BasicBlock types.
+
+import (
+ "bytes"
+ "fmt"
+ "go/ast"
+ "go/token"
+ "io"
+ "os"
+ "strings"
+
+ "golang.org/x/tools/go/types"
+)
+
+// addEdge adds a control-flow graph edge from from to to.
+func addEdge(from, to *BasicBlock) {
+ from.Succs = append(from.Succs, to)
+ to.Preds = append(to.Preds, from)
+}
+
+// Parent returns the function that contains block b.
+func (b *BasicBlock) Parent() *Function { return b.parent }
+
+// String returns a human-readable label of this block.
+// It is not guaranteed unique within the function.
+//
+func (b *BasicBlock) String() string {
+ return fmt.Sprintf("%d", b.Index)
+}
+
+// emit appends an instruction to the current basic block.
+// If the instruction defines a Value, it is returned.
+//
+func (b *BasicBlock) emit(i Instruction) Value {
+ i.setBlock(b)
+ b.Instrs = append(b.Instrs, i)
+ v, _ := i.(Value)
+ return v
+}
+
+// predIndex returns the i such that b.Preds[i] == c or panics if
+// there is none.
+func (b *BasicBlock) predIndex(c *BasicBlock) int {
+ for i, pred := range b.Preds {
+ if pred == c {
+ return i
+ }
+ }
+ panic(fmt.Sprintf("no edge %s -> %s", c, b))
+}
+
+// hasPhi returns true if b.Instrs contains φ-nodes.
+func (b *BasicBlock) hasPhi() bool {
+ _, ok := b.Instrs[0].(*Phi)
+ return ok
+}
+
+// phis returns the prefix of b.Instrs containing all the block's φ-nodes.
+func (b *BasicBlock) phis() []Instruction {
+ for i, instr := range b.Instrs {
+ if _, ok := instr.(*Phi); !ok {
+ return b.Instrs[:i]
+ }
+ }
+ return nil // unreachable in well-formed blocks
+}
+
+// replacePred replaces all occurrences of p in b's predecessor list with q.
+// Ordinarily there should be at most one.
+//
+func (b *BasicBlock) replacePred(p, q *BasicBlock) {
+ for i, pred := range b.Preds {
+ if pred == p {
+ b.Preds[i] = q
+ }
+ }
+}
+
+// replaceSucc replaces all occurrences of p in b's successor list with q.
+// Ordinarily there should be at most one.
+//
+func (b *BasicBlock) replaceSucc(p, q *BasicBlock) {
+ for i, succ := range b.Succs {
+ if succ == p {
+ b.Succs[i] = q
+ }
+ }
+}
+
+// removePred removes all occurrences of p in b's
+// predecessor list and φ-nodes.
+// Ordinarily there should be at most one.
+//
+func (b *BasicBlock) removePred(p *BasicBlock) {
+ phis := b.phis()
+
+ // We must preserve edge order for φ-nodes.
+ j := 0
+ for i, pred := range b.Preds {
+ if pred != p {
+ b.Preds[j] = b.Preds[i]
+ // Strike out φ-edge too.
+ for _, instr := range phis {
+ phi := instr.(*Phi)
+ phi.Edges[j] = phi.Edges[i]
+ }
+ j++
+ }
+ }
+ // Nil out b.Preds[j:] and φ-edges[j:] to aid GC.
+ for i := j; i < len(b.Preds); i++ {
+ b.Preds[i] = nil
+ for _, instr := range phis {
+ instr.(*Phi).Edges[i] = nil
+ }
+ }
+ b.Preds = b.Preds[:j]
+ for _, instr := range phis {
+ phi := instr.(*Phi)
+ phi.Edges = phi.Edges[:j]
+ }
+}
+
+// Destinations associated with unlabelled for/switch/select stmts.
+// We push/pop one of these as we enter/leave each construct and for
+// each BranchStmt we scan for the innermost target of the right type.
+//
+type targets struct {
+ tail *targets // rest of stack
+ _break *BasicBlock
+ _continue *BasicBlock
+ _fallthrough *BasicBlock
+}
+
+// Destinations associated with a labelled block.
+// We populate these as labels are encountered in forward gotos or
+// labelled statements.
+//
+type lblock struct {
+ _goto *BasicBlock
+ _break *BasicBlock
+ _continue *BasicBlock
+}
+
+// labelledBlock returns the branch target associated with the
+// specified label, creating it if needed.
+//
+func (f *Function) labelledBlock(label *ast.Ident) *lblock {
+ lb := f.lblocks[label.Obj]
+ if lb == nil {
+ lb = &lblock{_goto: f.newBasicBlock(label.Name)}
+ if f.lblocks == nil {
+ f.lblocks = make(map[*ast.Object]*lblock)
+ }
+ f.lblocks[label.Obj] = lb
+ }
+ return lb
+}
+
+// addParam adds a (non-escaping) parameter to f.Params of the
+// specified name, type and source position.
+//
+func (f *Function) addParam(name string, typ types.Type, pos token.Pos) *Parameter {
+ v := &Parameter{
+ name: name,
+ typ: typ,
+ pos: pos,
+ parent: f,
+ }
+ f.Params = append(f.Params, v)
+ return v
+}
+
+func (f *Function) addParamObj(obj types.Object) *Parameter {
+ name := obj.Name()
+ if name == "" {
+ name = fmt.Sprintf("arg%d", len(f.Params))
+ }
+ param := f.addParam(name, obj.Type(), obj.Pos())
+ param.object = obj
+ return param
+}
+
+// addSpilledParam declares a parameter that is pre-spilled to the
+// stack; the function body will load/store the spilled location.
+// Subsequent lifting will eliminate spills where possible.
+//
+func (f *Function) addSpilledParam(obj types.Object) {
+ param := f.addParamObj(obj)
+ spill := &Alloc{Comment: obj.Name()}
+ spill.setType(types.NewPointer(obj.Type()))
+ spill.setPos(obj.Pos())
+ f.objects[obj] = spill
+ f.Locals = append(f.Locals, spill)
+ f.emit(spill)
+ f.emit(&Store{Addr: spill, Val: param})
+}
+
+// startBody initializes the function prior to generating SSA code for its body.
+// Precondition: f.Type() already set.
+//
+func (f *Function) startBody() {
+ f.currentBlock = f.newBasicBlock("entry")
+ f.objects = make(map[types.Object]Value) // needed for some synthetics, e.g. init
+}
+
+// createSyntacticParams populates f.Params and generates code (spills
+// and named result locals) for all the parameters declared in the
+// syntax. In addition it populates the f.objects mapping.
+//
+// Preconditions:
+// f.startBody() was called.
+// Postcondition:
+// len(f.Params) == len(f.Signature.Params) + (f.Signature.Recv() ? 1 : 0)
+//
+func (f *Function) createSyntacticParams(recv *ast.FieldList, functype *ast.FuncType) {
+ // Receiver (at most one inner iteration).
+ if recv != nil {
+ for _, field := range recv.List {
+ for _, n := range field.Names {
+ f.addSpilledParam(f.Pkg.info.Defs[n])
+ }
+ // Anonymous receiver? No need to spill.
+ if field.Names == nil {
+ f.addParamObj(f.Signature.Recv())
+ }
+ }
+ }
+
+ // Parameters.
+ if functype.Params != nil {
+ n := len(f.Params) // 1 if has recv, 0 otherwise
+ for _, field := range functype.Params.List {
+ for _, n := range field.Names {
+ f.addSpilledParam(f.Pkg.info.Defs[n])
+ }
+ // Anonymous parameter? No need to spill.
+ if field.Names == nil {
+ f.addParamObj(f.Signature.Params().At(len(f.Params) - n))
+ }
+ }
+ }
+
+ // Named results.
+ if functype.Results != nil {
+ for _, field := range functype.Results.List {
+ // Implicit "var" decl of locals for named results.
+ for _, n := range field.Names {
+ f.namedResults = append(f.namedResults, f.addLocalForIdent(n))
+ }
+ }
+ }
+}
+
+// numberRegisters assigns numbers to all SSA registers
+// (value-defining Instructions) in f, to aid debugging.
+// (Non-Instruction Values are named at construction.)
+//
+func numberRegisters(f *Function) {
+ v := 0
+ for _, b := range f.Blocks {
+ for _, instr := range b.Instrs {
+ switch instr.(type) {
+ case Value:
+ instr.(interface {
+ setNum(int)
+ }).setNum(v)
+ v++
+ }
+ }
+ }
+}
+
+// buildReferrers populates the def/use information in all non-nil
+// Value.Referrers slice.
+// Precondition: all such slices are initially empty.
+func buildReferrers(f *Function) {
+ var rands []*Value
+ for _, b := range f.Blocks {
+ for _, instr := range b.Instrs {
+ rands = instr.Operands(rands[:0]) // recycle storage
+ for _, rand := range rands {
+ if r := *rand; r != nil {
+ if ref := r.Referrers(); ref != nil {
+ *ref = append(*ref, instr)
+ }
+ }
+ }
+ }
+ }
+}
+
+// finishBody() finalizes the function after SSA code generation of its body.
+func (f *Function) finishBody() {
+ f.objects = nil
+ f.currentBlock = nil
+ f.lblocks = nil
+
+ // Don't pin the AST in memory (except in debug mode).
+ if n := f.syntax; n != nil && !f.debugInfo() {
+ f.syntax = extentNode{n.Pos(), n.End()}
+ }
+
+ // Remove from f.Locals any Allocs that escape to the heap.
+ j := 0
+ for _, l := range f.Locals {
+ if !l.Heap {
+ f.Locals[j] = l
+ j++
+ }
+ }
+ // Nil out f.Locals[j:] to aid GC.
+ for i := j; i < len(f.Locals); i++ {
+ f.Locals[i] = nil
+ }
+ f.Locals = f.Locals[:j]
+
+ optimizeBlocks(f)
+
+ buildReferrers(f)
+
+ buildDomTree(f)
+
+ if f.Prog.mode&NaiveForm == 0 {
+ // For debugging pre-state of lifting pass:
+ // numberRegisters(f)
+ // f.WriteTo(os.Stderr)
+ lift(f)
+ }
+
+ f.namedResults = nil // (used by lifting)
+
+ numberRegisters(f)
+
+ if f.Prog.mode&PrintFunctions != 0 {
+ printMu.Lock()
+ f.WriteTo(os.Stdout)
+ printMu.Unlock()
+ }
+
+ if f.Prog.mode&SanityCheckFunctions != 0 {
+ mustSanityCheck(f, nil)
+ }
+}
+
+// removeNilBlocks eliminates nils from f.Blocks and updates each
+// BasicBlock.Index. Use this after any pass that may delete blocks.
+//
+func (f *Function) removeNilBlocks() {
+ j := 0
+ for _, b := range f.Blocks {
+ if b != nil {
+ b.Index = j
+ f.Blocks[j] = b
+ j++
+ }
+ }
+ // Nil out f.Blocks[j:] to aid GC.
+ for i := j; i < len(f.Blocks); i++ {
+ f.Blocks[i] = nil
+ }
+ f.Blocks = f.Blocks[:j]
+}
+
+// SetDebugMode sets the debug mode for package pkg. If true, all its
+// functions will include full debug info. This greatly increases the
+// size of the instruction stream, and causes Functions to depend upon
+// the ASTs, potentially keeping them live in memory for longer.
+//
+func (pkg *Package) SetDebugMode(debug bool) {
+ // TODO(adonovan): do we want ast.File granularity?
+ pkg.debug = debug
+}
+
+// debugInfo reports whether debug info is wanted for this function.
+func (f *Function) debugInfo() bool {
+ return f.Pkg != nil && f.Pkg.debug
+}
+
+// addNamedLocal creates a local variable, adds it to function f and
+// returns it. Its name and type are taken from obj. Subsequent
+// calls to f.lookup(obj) will return the same local.
+//
+func (f *Function) addNamedLocal(obj types.Object) *Alloc {
+ l := f.addLocal(obj.Type(), obj.Pos())
+ l.Comment = obj.Name()
+ f.objects[obj] = l
+ return l
+}
+
+func (f *Function) addLocalForIdent(id *ast.Ident) *Alloc {
+ return f.addNamedLocal(f.Pkg.info.Defs[id])
+}
+
+// addLocal creates an anonymous local variable of type typ, adds it
+// to function f and returns it. pos is the optional source location.
+//
+func (f *Function) addLocal(typ types.Type, pos token.Pos) *Alloc {
+ v := &Alloc{}
+ v.setType(types.NewPointer(typ))
+ v.setPos(pos)
+ f.Locals = append(f.Locals, v)
+ f.emit(v)
+ return v
+}
+
+// lookup returns the address of the named variable identified by obj
+// that is local to function f or one of its enclosing functions.
+// If escaping, the reference comes from a potentially escaping pointer
+// expression and the referent must be heap-allocated.
+//
+func (f *Function) lookup(obj types.Object, escaping bool) Value {
+ if v, ok := f.objects[obj]; ok {
+ if alloc, ok := v.(*Alloc); ok && escaping {
+ alloc.Heap = true
+ }
+ return v // function-local var (address)
+ }
+
+ // Definition must be in an enclosing function;
+ // plumb it through intervening closures.
+ if f.parent == nil {
+ panic("no ssa.Value for " + obj.String())
+ }
+ outer := f.parent.lookup(obj, true) // escaping
+ v := &FreeVar{
+ name: obj.Name(),
+ typ: outer.Type(),
+ pos: outer.Pos(),
+ outer: outer,
+ parent: f,
+ }
+ f.objects[obj] = v
+ f.FreeVars = append(f.FreeVars, v)
+ return v
+}
+
+// emit emits the specified instruction to function f.
+func (f *Function) emit(instr Instruction) Value {
+ return f.currentBlock.emit(instr)
+}
+
+// RelString returns the full name of this function, qualified by
+// package name, receiver type, etc.
+//
+// The specific formatting rules are not guaranteed and may change.
+//
+// Examples:
+// "math.IsNaN" // a package-level function
+// "(*bytes.Buffer).Bytes" // a declared method or a wrapper
+// "(*bytes.Buffer).Bytes$thunk" // thunk (func wrapping method; receiver is param 0)
+// "(*bytes.Buffer).Bytes$bound" // bound (func wrapping method; receiver supplied by closure)
+// "main.main$1" // an anonymous function in main
+// "main.init#1" // a declared init function
+// "main.init" // the synthesized package initializer
+//
+// When these functions are referred to from within the same package
+// (i.e. from == f.Pkg.Object), they are rendered without the package path.
+// For example: "IsNaN", "(*Buffer).Bytes", etc.
+//
+// All non-synthetic functions have distinct package-qualified names.
+// (But two methods may have the same name "(T).f" if one is a synthetic
+// wrapper promoting a non-exported method "f" from another package; in
+// that case, the strings are equal but the identifiers "f" are distinct.)
+//
+func (f *Function) RelString(from *types.Package) string {
+ // Anonymous?
+ if f.parent != nil {
+ // An anonymous function's Name() looks like "parentName$1",
+ // but its String() should include the type/package/etc.
+ parent := f.parent.RelString(from)
+ for i, anon := range f.parent.AnonFuncs {
+ if anon == f {
+ return fmt.Sprintf("%s$%d", parent, 1+i)
+ }
+ }
+
+ return f.name // should never happen
+ }
+
+ // Method (declared or wrapper)?
+ if recv := f.Signature.Recv(); recv != nil {
+ return f.relMethod(from, recv.Type())
+ }
+
+ // Thunk?
+ if f.method != nil {
+ return f.relMethod(from, f.method.Recv())
+ }
+
+ // Bound?
+ if len(f.FreeVars) == 1 && strings.HasSuffix(f.name, "$bound") {
+ return f.relMethod(from, f.FreeVars[0].Type())
+ }
+
+ // Package-level function?
+ // Prefix with package name for cross-package references only.
+ if p := f.pkgobj(); p != nil && p != from {
+ return fmt.Sprintf("%s.%s", p.Path(), f.name)
+ }
+
+ // Unknown.
+ return f.name
+}
+
+func (f *Function) relMethod(from *types.Package, recv types.Type) string {
+ return fmt.Sprintf("(%s).%s", relType(recv, from), f.name)
+}
+
+// writeSignature writes to buf the signature sig in declaration syntax.
+func writeSignature(buf *bytes.Buffer, from *types.Package, name string, sig *types.Signature, params []*Parameter) {
+ buf.WriteString("func ")
+ if recv := sig.Recv(); recv != nil {
+ buf.WriteString("(")
+ if n := params[0].Name(); n != "" {
+ buf.WriteString(n)
+ buf.WriteString(" ")
+ }
+ types.WriteType(buf, params[0].Type(), types.RelativeTo(from))
+ buf.WriteString(") ")
+ }
+ buf.WriteString(name)
+ types.WriteSignature(buf, sig, types.RelativeTo(from))
+}
+
+func (f *Function) pkgobj() *types.Package {
+ if f.Pkg != nil {
+ return f.Pkg.Object
+ }
+ return nil
+}
+
+var _ io.WriterTo = (*Function)(nil) // *Function implements io.Writer
+
+func (f *Function) WriteTo(w io.Writer) (int64, error) {
+ var buf bytes.Buffer
+ WriteFunction(&buf, f)
+ n, err := w.Write(buf.Bytes())
+ return int64(n), err
+}
+
+// WriteFunction writes to buf a human-readable "disassembly" of f.
+func WriteFunction(buf *bytes.Buffer, f *Function) {
+ fmt.Fprintf(buf, "# Name: %s\n", f.String())
+ if f.Pkg != nil {
+ fmt.Fprintf(buf, "# Package: %s\n", f.Pkg.Object.Path())
+ }
+ if syn := f.Synthetic; syn != "" {
+ fmt.Fprintln(buf, "# Synthetic:", syn)
+ }
+ if pos := f.Pos(); pos.IsValid() {
+ fmt.Fprintf(buf, "# Location: %s\n", f.Prog.Fset.Position(pos))
+ }
+
+ if f.parent != nil {
+ fmt.Fprintf(buf, "# Parent: %s\n", f.parent.Name())
+ }
+
+ if f.Recover != nil {
+ fmt.Fprintf(buf, "# Recover: %s\n", f.Recover)
+ }
+
+ from := f.pkgobj()
+
+ if f.FreeVars != nil {
+ buf.WriteString("# Free variables:\n")
+ for i, fv := range f.FreeVars {
+ fmt.Fprintf(buf, "# % 3d:\t%s %s\n", i, fv.Name(), relType(fv.Type(), from))
+ }
+ }
+
+ if len(f.Locals) > 0 {
+ buf.WriteString("# Locals:\n")
+ for i, l := range f.Locals {
+ fmt.Fprintf(buf, "# % 3d:\t%s %s\n", i, l.Name(), relType(deref(l.Type()), from))
+ }
+ }
+ writeSignature(buf, from, f.Name(), f.Signature, f.Params)
+ buf.WriteString(":\n")
+
+ if f.Blocks == nil {
+ buf.WriteString("\t(external)\n")
+ }
+
+ // NB. column calculations are confused by non-ASCII
+ // characters and assume 8-space tabs.
+ const punchcard = 80 // for old time's sake.
+ const tabwidth = 8
+ for _, b := range f.Blocks {
+ if b == nil {
+ // Corrupt CFG.
+ fmt.Fprintf(buf, ".nil:\n")
+ continue
+ }
+ n, _ := fmt.Fprintf(buf, "%d:", b.Index)
+ bmsg := fmt.Sprintf("%s P:%d S:%d", b.Comment, len(b.Preds), len(b.Succs))
+ fmt.Fprintf(buf, "%*s%s\n", punchcard-1-n-len(bmsg), "", bmsg)
+
+ if false { // CFG debugging
+ fmt.Fprintf(buf, "\t# CFG: %s --> %s --> %s\n", b.Preds, b, b.Succs)
+ }
+ for _, instr := range b.Instrs {
+ buf.WriteString("\t")
+ switch v := instr.(type) {
+ case Value:
+ l := punchcard - tabwidth
+ // Left-align the instruction.
+ if name := v.Name(); name != "" {
+ n, _ := fmt.Fprintf(buf, "%s = ", name)
+ l -= n
+ }
+ n, _ := buf.WriteString(instr.String())
+ l -= n
+ // Right-align the type if there's space.
+ if t := v.Type(); t != nil {
+ buf.WriteByte(' ')
+ ts := relType(t, from)
+ l -= len(ts) + len(" ") // (spaces before and after type)
+ if l > 0 {
+ fmt.Fprintf(buf, "%*s", l, "")
+ }
+ buf.WriteString(ts)
+ }
+ case nil:
+ // Be robust against bad transforms.
+ buf.WriteString("")
+ default:
+ buf.WriteString(instr.String())
+ }
+ buf.WriteString("\n")
+ }
+ }
+ fmt.Fprintf(buf, "\n")
+}
+
+// newBasicBlock adds to f a new basic block and returns it. It does
+// not automatically become the current block for subsequent calls to emit.
+// comment is an optional string for more readable debugging output.
+//
+func (f *Function) newBasicBlock(comment string) *BasicBlock {
+ b := &BasicBlock{
+ Index: len(f.Blocks),
+ Comment: comment,
+ parent: f,
+ }
+ b.Succs = b.succs2[:0]
+ f.Blocks = append(f.Blocks, b)
+ return b
+}
+
+// NewFunction returns a new synthetic Function instance belonging to
+// prog, with its name and signature fields set as specified.
+//
+// The caller is responsible for initializing the remaining fields of
+// the function object, e.g. Pkg, Params, Blocks.
+//
+// It is practically impossible for clients to construct well-formed
+// SSA functions/packages/programs directly, so we assume this is the
+// job of the Builder alone. NewFunction exists to provide clients a
+// little flexibility. For example, analysis tools may wish to
+// construct fake Functions for the root of the callgraph, a fake
+// "reflect" package, etc.
+//
+// TODO(adonovan): think harder about the API here.
+//
+func (prog *Program) NewFunction(name string, sig *types.Signature, provenance string) *Function {
+ return &Function{Prog: prog, name: name, Signature: sig, Synthetic: provenance}
+}
+
+type extentNode [2]token.Pos
+
+func (n extentNode) Pos() token.Pos { return n[0] }
+func (n extentNode) End() token.Pos { return n[1] }
+
+// Syntax returns an ast.Node whose Pos/End methods provide the
+// lexical extent of the function if it was defined by Go source code
+// (f.Synthetic==""), or nil otherwise.
+//
+// If f was built with debug information (see Package.SetDebugRef),
+// the result is the *ast.FuncDecl or *ast.FuncLit that declared the
+// function. Otherwise, it is an opaque Node providing only position
+// information; this avoids pinning the AST in memory.
+//
+func (f *Function) Syntax() ast.Node { return f.syntax }
diff --git a/vendor/golang.org/x/tools/go/ssa/lift.go b/vendor/golang.org/x/tools/go/ssa/lift.go
new file mode 100644
index 0000000..3771f61
--- /dev/null
+++ b/vendor/golang.org/x/tools/go/ssa/lift.go
@@ -0,0 +1,599 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package ssa
+
+// This file defines the lifting pass which tries to "lift" Alloc
+// cells (new/local variables) into SSA registers, replacing loads
+// with the dominating stored value, eliminating loads and stores, and
+// inserting φ-nodes as needed.
+
+// Cited papers and resources:
+//
+// Ron Cytron et al. 1991. Efficiently computing SSA form...
+// http://doi.acm.org/10.1145/115372.115320
+//
+// Cooper, Harvey, Kennedy. 2001. A Simple, Fast Dominance Algorithm.
+// Software Practice and Experience 2001, 4:1-10.
+// http://www.hipersoft.rice.edu/grads/publications/dom14.pdf
+//
+// Daniel Berlin, llvmdev mailing list, 2012.
+// http://lists.cs.uiuc.edu/pipermail/llvmdev/2012-January/046638.html
+// (Be sure to expand the whole thread.)
+
+// TODO(adonovan): opt: there are many optimizations worth evaluating, and
+// the conventional wisdom for SSA construction is that a simple
+// algorithm well engineered often beats those of better asymptotic
+// complexity on all but the most egregious inputs.
+//
+// Danny Berlin suggests that the Cooper et al. algorithm for
+// computing the dominance frontier is superior to Cytron et al.
+// Furthermore he recommends that rather than computing the DF for the
+// whole function then renaming all alloc cells, it may be cheaper to
+// compute the DF for each alloc cell separately and throw it away.
+//
+// Consider exploiting liveness information to avoid creating dead
+// φ-nodes which we then immediately remove.
+//
+// Integrate lifting with scalar replacement of aggregates (SRA) since
+// the two are synergistic.
+//
+// Also see many other "TODO: opt" suggestions in the code.
+
+import (
+ "fmt"
+ "go/token"
+ "math/big"
+ "os"
+
+ "golang.org/x/tools/go/types"
+)
+
+// If true, perform sanity checking and show diagnostic information at
+// each step of lifting. Very verbose.
+const debugLifting = false
+
+// domFrontier maps each block to the set of blocks in its dominance
+// frontier. The outer slice is conceptually a map keyed by
+// Block.Index. The inner slice is conceptually a set, possibly
+// containing duplicates.
+//
+// TODO(adonovan): opt: measure impact of dups; consider a packed bit
+// representation, e.g. big.Int, and bitwise parallel operations for
+// the union step in the Children loop.
+//
+// domFrontier's methods mutate the slice's elements but not its
+// length, so their receivers needn't be pointers.
+//
+type domFrontier [][]*BasicBlock
+
+func (df domFrontier) add(u, v *BasicBlock) {
+ p := &df[u.Index]
+ *p = append(*p, v)
+}
+
+// build builds the dominance frontier df for the dominator (sub)tree
+// rooted at u, using the Cytron et al. algorithm.
+//
+// TODO(adonovan): opt: consider Berlin approach, computing pruned SSA
+// by pruning the entire IDF computation, rather than merely pruning
+// the DF -> IDF step.
+func (df domFrontier) build(u *BasicBlock) {
+ // Encounter each node u in postorder of dom tree.
+ for _, child := range u.dom.children {
+ df.build(child)
+ }
+ for _, vb := range u.Succs {
+ if v := vb.dom; v.idom != u {
+ df.add(u, vb)
+ }
+ }
+ for _, w := range u.dom.children {
+ for _, vb := range df[w.Index] {
+ // TODO(adonovan): opt: use word-parallel bitwise union.
+ if v := vb.dom; v.idom != u {
+ df.add(u, vb)
+ }
+ }
+ }
+}
+
+func buildDomFrontier(fn *Function) domFrontier {
+ df := make(domFrontier, len(fn.Blocks))
+ df.build(fn.Blocks[0])
+ if fn.Recover != nil {
+ df.build(fn.Recover)
+ }
+ return df
+}
+
+func removeInstr(refs []Instruction, instr Instruction) []Instruction {
+ i := 0
+ for _, ref := range refs {
+ if ref == instr {
+ continue
+ }
+ refs[i] = ref
+ i++
+ }
+ for j := i; j != len(refs); j++ {
+ refs[j] = nil // aid GC
+ }
+ return refs[:i]
+}
+
+// lift attempts to replace local and new Allocs accessed only with
+// load/store by SSA registers, inserting φ-nodes where necessary.
+// The result is a program in classical pruned SSA form.
+//
+// Preconditions:
+// - fn has no dead blocks (blockopt has run).
+// - Def/use info (Operands and Referrers) is up-to-date.
+// - The dominator tree is up-to-date.
+//
+func lift(fn *Function) {
+ // TODO(adonovan): opt: lots of little optimizations may be
+ // worthwhile here, especially if they cause us to avoid
+ // buildDomFrontier. For example:
+ //
+ // - Alloc never loaded? Eliminate.
+ // - Alloc never stored? Replace all loads with a zero constant.
+ // - Alloc stored once? Replace loads with dominating store;
+ // don't forget that an Alloc is itself an effective store
+ // of zero.
+ // - Alloc used only within a single block?
+ // Use degenerate algorithm avoiding φ-nodes.
+ // - Consider synergy with scalar replacement of aggregates (SRA).
+ // e.g. *(&x.f) where x is an Alloc.
+ // Perhaps we'd get better results if we generated this as x.f
+ // i.e. Field(x, .f) instead of Load(FieldIndex(x, .f)).
+ // Unclear.
+ //
+ // But we will start with the simplest correct code.
+ df := buildDomFrontier(fn)
+
+ if debugLifting {
+ title := false
+ for i, blocks := range df {
+ if blocks != nil {
+ if !title {
+ fmt.Fprintf(os.Stderr, "Dominance frontier of %s:\n", fn)
+ title = true
+ }
+ fmt.Fprintf(os.Stderr, "\t%s: %s\n", fn.Blocks[i], blocks)
+ }
+ }
+ }
+
+ newPhis := make(newPhiMap)
+
+ // During this pass we will replace some BasicBlock.Instrs
+ // (allocs, loads and stores) with nil, keeping a count in
+ // BasicBlock.gaps. At the end we will reset Instrs to the
+ // concatenation of all non-dead newPhis and non-nil Instrs
+ // for the block, reusing the original array if space permits.
+
+ // While we're here, we also eliminate 'rundefers'
+ // instructions in functions that contain no 'defer'
+ // instructions.
+ usesDefer := false
+
+ // Determine which allocs we can lift and number them densely.
+ // The renaming phase uses this numbering for compact maps.
+ numAllocs := 0
+ for _, b := range fn.Blocks {
+ b.gaps = 0
+ b.rundefers = 0
+ for _, instr := range b.Instrs {
+ switch instr := instr.(type) {
+ case *Alloc:
+ index := -1
+ if liftAlloc(df, instr, newPhis) {
+ index = numAllocs
+ numAllocs++
+ }
+ instr.index = index
+ case *Defer:
+ usesDefer = true
+ case *RunDefers:
+ b.rundefers++
+ }
+ }
+ }
+
+ // renaming maps an alloc (keyed by index) to its replacement
+ // value. Initially the renaming contains nil, signifying the
+ // zero constant of the appropriate type; we construct the
+ // Const lazily at most once on each path through the domtree.
+ // TODO(adonovan): opt: cache per-function not per subtree.
+ renaming := make([]Value, numAllocs)
+
+ // Renaming.
+ rename(fn.Blocks[0], renaming, newPhis)
+
+ // Eliminate dead new phis, then prepend the live ones to each block.
+ for _, b := range fn.Blocks {
+
+ // Compress the newPhis slice to eliminate unused phis.
+ // TODO(adonovan): opt: compute liveness to avoid
+ // placing phis in blocks for which the alloc cell is
+ // not live.
+ nps := newPhis[b]
+ j := 0
+ for _, np := range nps {
+ if !phiIsLive(np.phi) {
+ // discard it, first removing it from referrers
+ for _, newval := range np.phi.Edges {
+ if refs := newval.Referrers(); refs != nil {
+ *refs = removeInstr(*refs, np.phi)
+ }
+ }
+ continue
+ }
+ nps[j] = np
+ j++
+ }
+ nps = nps[:j]
+
+ rundefersToKill := b.rundefers
+ if usesDefer {
+ rundefersToKill = 0
+ }
+
+ if j+b.gaps+rundefersToKill == 0 {
+ continue // fast path: no new phis or gaps
+ }
+
+ // Compact nps + non-nil Instrs into a new slice.
+ // TODO(adonovan): opt: compact in situ if there is
+ // sufficient space or slack in the slice.
+ dst := make([]Instruction, len(b.Instrs)+j-b.gaps-rundefersToKill)
+ for i, np := range nps {
+ dst[i] = np.phi
+ }
+ for _, instr := range b.Instrs {
+ if instr == nil {
+ continue
+ }
+ if !usesDefer {
+ if _, ok := instr.(*RunDefers); ok {
+ continue
+ }
+ }
+ dst[j] = instr
+ j++
+ }
+ for i, np := range nps {
+ dst[i] = np.phi
+ }
+ b.Instrs = dst
+ }
+
+ // Remove any fn.Locals that were lifted.
+ j := 0
+ for _, l := range fn.Locals {
+ if l.index < 0 {
+ fn.Locals[j] = l
+ j++
+ }
+ }
+ // Nil out fn.Locals[j:] to aid GC.
+ for i := j; i < len(fn.Locals); i++ {
+ fn.Locals[i] = nil
+ }
+ fn.Locals = fn.Locals[:j]
+}
+
+func phiIsLive(phi *Phi) bool {
+ for _, instr := range *phi.Referrers() {
+ if instr == phi {
+ continue // self-refs don't count
+ }
+ if _, ok := instr.(*DebugRef); ok {
+ continue // debug refs don't count
+ }
+ return true
+ }
+ return false
+}
+
+type blockSet struct{ big.Int } // (inherit methods from Int)
+
+// add adds b to the set and returns true if the set changed.
+func (s *blockSet) add(b *BasicBlock) bool {
+ i := b.Index
+ if s.Bit(i) != 0 {
+ return false
+ }
+ s.SetBit(&s.Int, i, 1)
+ return true
+}
+
+// take removes an arbitrary element from a set s and
+// returns its index, or returns -1 if empty.
+func (s *blockSet) take() int {
+ l := s.BitLen()
+ for i := 0; i < l; i++ {
+ if s.Bit(i) == 1 {
+ s.SetBit(&s.Int, i, 0)
+ return i
+ }
+ }
+ return -1
+}
+
+// newPhi is a pair of a newly introduced φ-node and the lifted Alloc
+// it replaces.
+type newPhi struct {
+ phi *Phi
+ alloc *Alloc
+}
+
+// newPhiMap records for each basic block, the set of newPhis that
+// must be prepended to the block.
+type newPhiMap map[*BasicBlock][]newPhi
+
+// liftAlloc determines whether alloc can be lifted into registers,
+// and if so, it populates newPhis with all the φ-nodes it may require
+// and returns true.
+//
+func liftAlloc(df domFrontier, alloc *Alloc, newPhis newPhiMap) bool {
+ // Don't lift aggregates into registers, because we don't have
+ // a way to express their zero-constants.
+ switch deref(alloc.Type()).Underlying().(type) {
+ case *types.Array, *types.Struct:
+ return false
+ }
+
+ // Don't lift named return values in functions that defer
+ // calls that may recover from panic.
+ if fn := alloc.Parent(); fn.Recover != nil {
+ for _, nr := range fn.namedResults {
+ if nr == alloc {
+ return false
+ }
+ }
+ }
+
+ // Compute defblocks, the set of blocks containing a
+ // definition of the alloc cell.
+ var defblocks blockSet
+ for _, instr := range *alloc.Referrers() {
+ // Bail out if we discover the alloc is not liftable;
+ // the only operations permitted to use the alloc are
+ // loads/stores into the cell, and DebugRef.
+ switch instr := instr.(type) {
+ case *Store:
+ if instr.Val == alloc {
+ return false // address used as value
+ }
+ if instr.Addr != alloc {
+ panic("Alloc.Referrers is inconsistent")
+ }
+ defblocks.add(instr.Block())
+ case *UnOp:
+ if instr.Op != token.MUL {
+ return false // not a load
+ }
+ if instr.X != alloc {
+ panic("Alloc.Referrers is inconsistent")
+ }
+ case *DebugRef:
+ // ok
+ default:
+ return false // some other instruction
+ }
+ }
+ // The Alloc itself counts as a (zero) definition of the cell.
+ defblocks.add(alloc.Block())
+
+ if debugLifting {
+ fmt.Fprintln(os.Stderr, "\tlifting ", alloc, alloc.Name())
+ }
+
+ fn := alloc.Parent()
+
+ // Φ-insertion.
+ //
+ // What follows is the body of the main loop of the insert-φ
+ // function described by Cytron et al, but instead of using
+ // counter tricks, we just reset the 'hasAlready' and 'work'
+ // sets each iteration. These are bitmaps so it's pretty cheap.
+ //
+ // TODO(adonovan): opt: recycle slice storage for W,
+ // hasAlready, defBlocks across liftAlloc calls.
+ var hasAlready blockSet
+
+ // Initialize W and work to defblocks.
+ var work blockSet = defblocks // blocks seen
+ var W blockSet // blocks to do
+ W.Set(&defblocks.Int)
+
+ // Traverse iterated dominance frontier, inserting φ-nodes.
+ for i := W.take(); i != -1; i = W.take() {
+ u := fn.Blocks[i]
+ for _, v := range df[u.Index] {
+ if hasAlready.add(v) {
+ // Create φ-node.
+ // It will be prepended to v.Instrs later, if needed.
+ phi := &Phi{
+ Edges: make([]Value, len(v.Preds)),
+ Comment: alloc.Comment,
+ }
+ phi.pos = alloc.Pos()
+ phi.setType(deref(alloc.Type()))
+ phi.block = v
+ if debugLifting {
+ fmt.Fprintf(os.Stderr, "\tplace %s = %s at block %s\n", phi.Name(), phi, v)
+ }
+ newPhis[v] = append(newPhis[v], newPhi{phi, alloc})
+
+ if work.add(v) {
+ W.add(v)
+ }
+ }
+ }
+ }
+
+ return true
+}
+
+// replaceAll replaces all intraprocedural uses of x with y,
+// updating x.Referrers and y.Referrers.
+// Precondition: x.Referrers() != nil, i.e. x must be local to some function.
+//
+func replaceAll(x, y Value) {
+ var rands []*Value
+ pxrefs := x.Referrers()
+ pyrefs := y.Referrers()
+ for _, instr := range *pxrefs {
+ rands = instr.Operands(rands[:0]) // recycle storage
+ for _, rand := range rands {
+ if *rand != nil {
+ if *rand == x {
+ *rand = y
+ }
+ }
+ }
+ if pyrefs != nil {
+ *pyrefs = append(*pyrefs, instr) // dups ok
+ }
+ }
+ *pxrefs = nil // x is now unreferenced
+}
+
+// renamed returns the value to which alloc is being renamed,
+// constructing it lazily if it's the implicit zero initialization.
+//
+func renamed(renaming []Value, alloc *Alloc) Value {
+ v := renaming[alloc.index]
+ if v == nil {
+ v = zeroConst(deref(alloc.Type()))
+ renaming[alloc.index] = v
+ }
+ return v
+}
+
+// rename implements the (Cytron et al) SSA renaming algorithm, a
+// preorder traversal of the dominator tree replacing all loads of
+// Alloc cells with the value stored to that cell by the dominating
+// store instruction. For lifting, we need only consider loads,
+// stores and φ-nodes.
+//
+// renaming is a map from *Alloc (keyed by index number) to its
+// dominating stored value; newPhis[x] is the set of new φ-nodes to be
+// prepended to block x.
+//
+func rename(u *BasicBlock, renaming []Value, newPhis newPhiMap) {
+ // Each φ-node becomes the new name for its associated Alloc.
+ for _, np := range newPhis[u] {
+ phi := np.phi
+ alloc := np.alloc
+ renaming[alloc.index] = phi
+ }
+
+ // Rename loads and stores of allocs.
+ for i, instr := range u.Instrs {
+ switch instr := instr.(type) {
+ case *Alloc:
+ if instr.index >= 0 { // store of zero to Alloc cell
+ // Replace dominated loads by the zero value.
+ renaming[instr.index] = nil
+ if debugLifting {
+ fmt.Fprintf(os.Stderr, "\tkill alloc %s\n", instr)
+ }
+ // Delete the Alloc.
+ u.Instrs[i] = nil
+ u.gaps++
+ }
+
+ case *Store:
+ if alloc, ok := instr.Addr.(*Alloc); ok && alloc.index >= 0 { // store to Alloc cell
+ // Replace dominated loads by the stored value.
+ renaming[alloc.index] = instr.Val
+ if debugLifting {
+ fmt.Fprintf(os.Stderr, "\tkill store %s; new value: %s\n",
+ instr, instr.Val.Name())
+ }
+ // Remove the store from the referrer list of the stored value.
+ if refs := instr.Val.Referrers(); refs != nil {
+ *refs = removeInstr(*refs, instr)
+ }
+ // Delete the Store.
+ u.Instrs[i] = nil
+ u.gaps++
+ }
+
+ case *UnOp:
+ if instr.Op == token.MUL {
+ if alloc, ok := instr.X.(*Alloc); ok && alloc.index >= 0 { // load of Alloc cell
+ newval := renamed(renaming, alloc)
+ if debugLifting {
+ fmt.Fprintf(os.Stderr, "\tupdate load %s = %s with %s\n",
+ instr.Name(), instr, newval.Name())
+ }
+ // Replace all references to
+ // the loaded value by the
+ // dominating stored value.
+ replaceAll(instr, newval)
+ // Delete the Load.
+ u.Instrs[i] = nil
+ u.gaps++
+ }
+ }
+
+ case *DebugRef:
+ if alloc, ok := instr.X.(*Alloc); ok && alloc.index >= 0 { // ref of Alloc cell
+ if instr.IsAddr {
+ instr.X = renamed(renaming, alloc)
+ instr.IsAddr = false
+
+ // Add DebugRef to instr.X's referrers.
+ if refs := instr.X.Referrers(); refs != nil {
+ *refs = append(*refs, instr)
+ }
+ } else {
+ // A source expression denotes the address
+ // of an Alloc that was optimized away.
+ instr.X = nil
+
+ // Delete the DebugRef.
+ u.Instrs[i] = nil
+ u.gaps++
+ }
+ }
+ }
+ }
+
+ // For each φ-node in a CFG successor, rename the edge.
+ for _, v := range u.Succs {
+ phis := newPhis[v]
+ if len(phis) == 0 {
+ continue
+ }
+ i := v.predIndex(u)
+ for _, np := range phis {
+ phi := np.phi
+ alloc := np.alloc
+ newval := renamed(renaming, alloc)
+ if debugLifting {
+ fmt.Fprintf(os.Stderr, "\tsetphi %s edge %s -> %s (#%d) (alloc=%s) := %s\n",
+ phi.Name(), u, v, i, alloc.Name(), newval.Name())
+ }
+ phi.Edges[i] = newval
+ if prefs := newval.Referrers(); prefs != nil {
+ *prefs = append(*prefs, phi)
+ }
+ }
+ }
+
+ // Continue depth-first recursion over domtree, pushing a
+ // fresh copy of the renaming map for each subtree.
+ for _, v := range u.dom.children {
+ // TODO(adonovan): opt: avoid copy on final iteration; use destructive update.
+ r := make([]Value, len(renaming))
+ copy(r, renaming)
+ rename(v, r, newPhis)
+ }
+}
diff --git a/vendor/golang.org/x/tools/go/ssa/lvalue.go b/vendor/golang.org/x/tools/go/ssa/lvalue.go
new file mode 100644
index 0000000..4284b1c
--- /dev/null
+++ b/vendor/golang.org/x/tools/go/ssa/lvalue.go
@@ -0,0 +1,121 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package ssa
+
+// lvalues are the union of addressable expressions and map-index
+// expressions.
+
+import (
+ "go/ast"
+ "go/token"
+
+ "golang.org/x/tools/go/types"
+)
+
+// An lvalue represents an assignable location that may appear on the
+// left-hand side of an assignment. This is a generalization of a
+// pointer to permit updates to elements of maps.
+//
+type lvalue interface {
+ store(fn *Function, v Value) // stores v into the location
+ load(fn *Function) Value // loads the contents of the location
+ address(fn *Function) Value // address of the location
+ typ() types.Type // returns the type of the location
+}
+
+// An address is an lvalue represented by a true pointer.
+type address struct {
+ addr Value
+ pos token.Pos // source position
+ expr ast.Expr // source syntax of the value (not address) [debug mode]
+}
+
+func (a *address) load(fn *Function) Value {
+ load := emitLoad(fn, a.addr)
+ load.pos = a.pos
+ return load
+}
+
+func (a *address) store(fn *Function, v Value) {
+ store := emitStore(fn, a.addr, v, a.pos)
+ if a.expr != nil {
+ // store.Val is v, converted for assignability.
+ emitDebugRef(fn, a.expr, store.Val, false)
+ }
+}
+
+func (a *address) address(fn *Function) Value {
+ if a.expr != nil {
+ emitDebugRef(fn, a.expr, a.addr, true)
+ }
+ return a.addr
+}
+
+func (a *address) typ() types.Type {
+ return deref(a.addr.Type())
+}
+
+// An element is an lvalue represented by m[k], the location of an
+// element of a map or string. These locations are not addressable
+// since pointers cannot be formed from them, but they do support
+// load(), and in the case of maps, store().
+//
+type element struct {
+ m, k Value // map or string
+ t types.Type // map element type or string byte type
+ pos token.Pos // source position of colon ({k:v}) or lbrack (m[k]=v)
+}
+
+func (e *element) load(fn *Function) Value {
+ l := &Lookup{
+ X: e.m,
+ Index: e.k,
+ }
+ l.setPos(e.pos)
+ l.setType(e.t)
+ return fn.emit(l)
+}
+
+func (e *element) store(fn *Function, v Value) {
+ up := &MapUpdate{
+ Map: e.m,
+ Key: e.k,
+ Value: emitConv(fn, v, e.t),
+ }
+ up.pos = e.pos
+ fn.emit(up)
+}
+
+func (e *element) address(fn *Function) Value {
+ panic("map/string elements are not addressable")
+}
+
+func (e *element) typ() types.Type {
+ return e.t
+}
+
+// A blank is a dummy variable whose name is "_".
+// It is not reified: loads are illegal and stores are ignored.
+//
+type blank struct{}
+
+func (bl blank) load(fn *Function) Value {
+ panic("blank.load is illegal")
+}
+
+func (bl blank) store(fn *Function, v Value) {
+ // no-op
+}
+
+func (bl blank) address(fn *Function) Value {
+ panic("blank var is not addressable")
+}
+
+func (bl blank) typ() types.Type {
+ // This should be the type of the blank Ident; the typechecker
+ // doesn't provide this yet, but fortunately, we don't need it
+ // yet either.
+ panic("blank.typ is unimplemented")
+}
diff --git a/vendor/golang.org/x/tools/go/ssa/methods.go b/vendor/golang.org/x/tools/go/ssa/methods.go
new file mode 100644
index 0000000..12534de
--- /dev/null
+++ b/vendor/golang.org/x/tools/go/ssa/methods.go
@@ -0,0 +1,243 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package ssa
+
+// This file defines utilities for population of method sets.
+
+import (
+ "fmt"
+
+ "golang.org/x/tools/go/types"
+)
+
+// Method returns the Function implementing method sel, building
+// wrapper methods on demand. It returns nil if sel denotes an
+// abstract (interface) method.
+//
+// Precondition: sel.Kind() == MethodVal.
+//
+// TODO(adonovan): rename this to MethodValue because of the
+// precondition, and for consistency with functions in source.go.
+//
+// Thread-safe.
+//
+// EXCLUSIVE_LOCKS_ACQUIRED(prog.methodsMu)
+//
+func (prog *Program) Method(sel *types.Selection) *Function {
+ if sel.Kind() != types.MethodVal {
+ panic(fmt.Sprintf("Method(%s) kind != MethodVal", sel))
+ }
+ T := sel.Recv()
+ if isInterface(T) {
+ return nil // abstract method
+ }
+ if prog.mode&LogSource != 0 {
+ defer logStack("Method %s %v", T, sel)()
+ }
+
+ prog.methodsMu.Lock()
+ defer prog.methodsMu.Unlock()
+
+ return prog.addMethod(prog.createMethodSet(T), sel)
+}
+
+// LookupMethod returns the implementation of the method of type T
+// identified by (pkg, name). It returns nil if the method exists but
+// is abstract, and panics if T has no such method.
+//
+func (prog *Program) LookupMethod(T types.Type, pkg *types.Package, name string) *Function {
+ sel := prog.MethodSets.MethodSet(T).Lookup(pkg, name)
+ if sel == nil {
+ panic(fmt.Sprintf("%s has no method %s", T, types.Id(pkg, name)))
+ }
+ return prog.Method(sel)
+}
+
+// methodSet contains the (concrete) methods of a non-interface type.
+type methodSet struct {
+ mapping map[string]*Function // populated lazily
+ complete bool // mapping contains all methods
+}
+
+// Precondition: !isInterface(T).
+// EXCLUSIVE_LOCKS_REQUIRED(prog.methodsMu)
+func (prog *Program) createMethodSet(T types.Type) *methodSet {
+ mset, ok := prog.methodSets.At(T).(*methodSet)
+ if !ok {
+ mset = &methodSet{mapping: make(map[string]*Function)}
+ prog.methodSets.Set(T, mset)
+ }
+ return mset
+}
+
+// EXCLUSIVE_LOCKS_REQUIRED(prog.methodsMu)
+func (prog *Program) addMethod(mset *methodSet, sel *types.Selection) *Function {
+ if sel.Kind() == types.MethodExpr {
+ panic(sel)
+ }
+ id := sel.Obj().Id()
+ fn := mset.mapping[id]
+ if fn == nil {
+ obj := sel.Obj().(*types.Func)
+
+ needsPromotion := len(sel.Index()) > 1
+ needsIndirection := !isPointer(recvType(obj)) && isPointer(sel.Recv())
+ if needsPromotion || needsIndirection {
+ fn = makeWrapper(prog, sel)
+ } else {
+ fn = prog.declaredFunc(obj)
+ }
+ if fn.Signature.Recv() == nil {
+ panic(fn) // missing receiver
+ }
+ mset.mapping[id] = fn
+ }
+ return fn
+}
+
+// RuntimeTypes returns a new unordered slice containing all
+// concrete types in the program for which a complete (non-empty)
+// method set is required at run-time.
+//
+// Thread-safe.
+//
+// EXCLUSIVE_LOCKS_ACQUIRED(prog.methodsMu)
+//
+func (prog *Program) RuntimeTypes() []types.Type {
+ prog.methodsMu.Lock()
+ defer prog.methodsMu.Unlock()
+
+ var res []types.Type
+ prog.methodSets.Iterate(func(T types.Type, v interface{}) {
+ if v.(*methodSet).complete {
+ res = append(res, T)
+ }
+ })
+ return res
+}
+
+// declaredFunc returns the concrete function/method denoted by obj.
+// Panic ensues if there is none.
+//
+func (prog *Program) declaredFunc(obj *types.Func) *Function {
+ if v := prog.packageLevelValue(obj); v != nil {
+ return v.(*Function)
+ }
+ panic("no concrete method: " + obj.String())
+}
+
+// needMethodsOf ensures that runtime type information (including the
+// complete method set) is available for the specified type T and all
+// its subcomponents.
+//
+// needMethodsOf must be called for at least every type that is an
+// operand of some MakeInterface instruction, and for the type of
+// every exported package member.
+//
+// Precondition: T is not a method signature (*Signature with Recv()!=nil).
+//
+// Thread-safe. (Called via emitConv from multiple builder goroutines.)
+//
+// TODO(adonovan): make this faster. It accounts for 20% of SSA build time.
+//
+// EXCLUSIVE_LOCKS_ACQUIRED(prog.methodsMu)
+//
+func (prog *Program) needMethodsOf(T types.Type) {
+ prog.methodsMu.Lock()
+ prog.needMethods(T, false)
+ prog.methodsMu.Unlock()
+}
+
+// Precondition: T is not a method signature (*Signature with Recv()!=nil).
+// Recursive case: skip => don't create methods for T.
+//
+// EXCLUSIVE_LOCKS_REQUIRED(prog.methodsMu)
+//
+func (prog *Program) needMethods(T types.Type, skip bool) {
+ // Each package maintains its own set of types it has visited.
+ if prevSkip, ok := prog.runtimeTypes.At(T).(bool); ok {
+ // needMethods(T) was previously called
+ if !prevSkip || skip {
+ return // already seen, with same or false 'skip' value
+ }
+ }
+ prog.runtimeTypes.Set(T, skip)
+
+ tmset := prog.MethodSets.MethodSet(T)
+
+ if !skip && !isInterface(T) && tmset.Len() > 0 {
+ // Create methods of T.
+ mset := prog.createMethodSet(T)
+ if !mset.complete {
+ mset.complete = true
+ n := tmset.Len()
+ for i := 0; i < n; i++ {
+ prog.addMethod(mset, tmset.At(i))
+ }
+ }
+ }
+
+ // Recursion over signatures of each method.
+ for i := 0; i < tmset.Len(); i++ {
+ sig := tmset.At(i).Type().(*types.Signature)
+ prog.needMethods(sig.Params(), false)
+ prog.needMethods(sig.Results(), false)
+ }
+
+ switch t := T.(type) {
+ case *types.Basic:
+ // nop
+
+ case *types.Interface:
+ // nop---handled by recursion over method set.
+
+ case *types.Pointer:
+ prog.needMethods(t.Elem(), false)
+
+ case *types.Slice:
+ prog.needMethods(t.Elem(), false)
+
+ case *types.Chan:
+ prog.needMethods(t.Elem(), false)
+
+ case *types.Map:
+ prog.needMethods(t.Key(), false)
+ prog.needMethods(t.Elem(), false)
+
+ case *types.Signature:
+ if t.Recv() != nil {
+ panic(fmt.Sprintf("Signature %s has Recv %s", t, t.Recv()))
+ }
+ prog.needMethods(t.Params(), false)
+ prog.needMethods(t.Results(), false)
+
+ case *types.Named:
+ // A pointer-to-named type can be derived from a named
+ // type via reflection. It may have methods too.
+ prog.needMethods(types.NewPointer(T), false)
+
+ // Consider 'type T struct{S}' where S has methods.
+ // Reflection provides no way to get from T to struct{S},
+ // only to S, so the method set of struct{S} is unwanted,
+ // so set 'skip' flag during recursion.
+ prog.needMethods(t.Underlying(), true)
+
+ case *types.Array:
+ prog.needMethods(t.Elem(), false)
+
+ case *types.Struct:
+ for i, n := 0, t.NumFields(); i < n; i++ {
+ prog.needMethods(t.Field(i).Type(), false)
+ }
+
+ case *types.Tuple:
+ for i, n := 0, t.Len(); i < n; i++ {
+ prog.needMethods(t.At(i).Type(), false)
+ }
+
+ default:
+ panic(T)
+ }
+}
diff --git a/vendor/golang.org/x/tools/go/ssa/mode.go b/vendor/golang.org/x/tools/go/ssa/mode.go
new file mode 100644
index 0000000..bbd613a
--- /dev/null
+++ b/vendor/golang.org/x/tools/go/ssa/mode.go
@@ -0,0 +1,107 @@
+// Copyright 2015 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package ssa
+
+// This file defines the BuilderMode type and its command-line flag.
+
+import (
+ "bytes"
+ "flag"
+ "fmt"
+)
+
+// BuilderMode is a bitmask of options for diagnostics and checking.
+type BuilderMode uint
+
+const (
+ PrintPackages BuilderMode = 1 << iota // Print package inventory to stdout
+ PrintFunctions // Print function SSA code to stdout
+ LogSource // Log source locations as SSA builder progresses
+ SanityCheckFunctions // Perform sanity checking of function bodies
+ NaiveForm // Build naïve SSA form: don't replace local loads/stores with registers
+ BuildSerially // Build packages serially, not in parallel.
+ GlobalDebug // Enable debug info for all packages
+ BareInits // Build init functions without guards or calls to dependent inits
+)
+
+const modeFlagUsage = `Options controlling the SSA builder.
+The value is a sequence of zero or more of these letters:
+C perform sanity [C]hecking of the SSA form.
+D include [D]ebug info for every function.
+P print [P]ackage inventory.
+F print [F]unction SSA code.
+S log [S]ource locations as SSA builder progresses.
+L build distinct packages seria[L]ly instead of in parallel.
+N build [N]aive SSA form: don't replace local loads/stores with registers.
+I build bare [I]nit functions: no init guards or calls to dependent inits.
+`
+
+// BuilderModeFlag creates a new command line flag of type BuilderMode,
+// adds it to the specified flag set, and returns it.
+//
+// Example:
+// var ssabuild = BuilderModeFlag(flag.CommandLine, "ssabuild", 0)
+//
+func BuilderModeFlag(set *flag.FlagSet, name string, value BuilderMode) *BuilderMode {
+ set.Var((*builderModeValue)(&value), name, modeFlagUsage)
+ return &value
+}
+
+type builderModeValue BuilderMode // satisfies flag.Value and flag.Getter.
+
+func (v *builderModeValue) Set(s string) error {
+ var mode BuilderMode
+ for _, c := range s {
+ switch c {
+ case 'D':
+ mode |= GlobalDebug
+ case 'P':
+ mode |= PrintPackages
+ case 'F':
+ mode |= PrintFunctions
+ case 'S':
+ mode |= LogSource | BuildSerially
+ case 'C':
+ mode |= SanityCheckFunctions
+ case 'N':
+ mode |= NaiveForm
+ case 'L':
+ mode |= BuildSerially
+ default:
+ return fmt.Errorf("unknown BuilderMode option: %q", c)
+ }
+ }
+ *v = builderModeValue(mode)
+ return nil
+}
+
+func (v *builderModeValue) Get() interface{} { return BuilderMode(*v) }
+
+func (v *builderModeValue) String() string {
+ mode := BuilderMode(*v)
+ var buf bytes.Buffer
+ if mode&GlobalDebug != 0 {
+ buf.WriteByte('D')
+ }
+ if mode&PrintPackages != 0 {
+ buf.WriteByte('P')
+ }
+ if mode&PrintFunctions != 0 {
+ buf.WriteByte('F')
+ }
+ if mode&LogSource != 0 {
+ buf.WriteByte('S')
+ }
+ if mode&SanityCheckFunctions != 0 {
+ buf.WriteByte('C')
+ }
+ if mode&NaiveForm != 0 {
+ buf.WriteByte('N')
+ }
+ if mode&BuildSerially != 0 {
+ buf.WriteByte('L')
+ }
+ return buf.String()
+}
diff --git a/vendor/golang.org/x/tools/go/ssa/print.go b/vendor/golang.org/x/tools/go/ssa/print.go
new file mode 100644
index 0000000..88c31f6
--- /dev/null
+++ b/vendor/golang.org/x/tools/go/ssa/print.go
@@ -0,0 +1,427 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package ssa
+
+// This file implements the String() methods for all Value and
+// Instruction types.
+
+import (
+ "bytes"
+ "fmt"
+ "io"
+ "reflect"
+ "sort"
+
+ "golang.org/x/tools/go/types"
+ "golang.org/x/tools/go/types/typeutil"
+)
+
+// relName returns the name of v relative to i.
+// In most cases, this is identical to v.Name(), but references to
+// Functions (including methods) and Globals use RelString and
+// all types are displayed with relType, so that only cross-package
+// references are package-qualified.
+//
+func relName(v Value, i Instruction) string {
+ var from *types.Package
+ if i != nil {
+ from = i.Parent().pkgobj()
+ }
+ switch v := v.(type) {
+ case Member: // *Function or *Global
+ return v.RelString(from)
+ case *Const:
+ return v.RelString(from)
+ }
+ return v.Name()
+}
+
+func relType(t types.Type, from *types.Package) string {
+ return types.TypeString(t, types.RelativeTo(from))
+}
+
+func relString(m Member, from *types.Package) string {
+ // NB: not all globals have an Object (e.g. init$guard),
+ // so use Package().Object not Object.Package().
+ if obj := m.Package().Object; obj != nil && obj != from {
+ return fmt.Sprintf("%s.%s", obj.Path(), m.Name())
+ }
+ return m.Name()
+}
+
+// Value.String()
+//
+// This method is provided only for debugging.
+// It never appears in disassembly, which uses Value.Name().
+
+func (v *Parameter) String() string {
+ from := v.Parent().pkgobj()
+ return fmt.Sprintf("parameter %s : %s", v.Name(), relType(v.Type(), from))
+}
+
+func (v *FreeVar) String() string {
+ from := v.Parent().pkgobj()
+ return fmt.Sprintf("freevar %s : %s", v.Name(), relType(v.Type(), from))
+}
+
+func (v *Builtin) String() string {
+ return fmt.Sprintf("builtin %s", v.Name())
+}
+
+// Instruction.String()
+
+func (v *Alloc) String() string {
+ op := "local"
+ if v.Heap {
+ op = "new"
+ }
+ from := v.Parent().pkgobj()
+ return fmt.Sprintf("%s %s (%s)", op, relType(deref(v.Type()), from), v.Comment)
+}
+
+func (v *Phi) String() string {
+ var b bytes.Buffer
+ b.WriteString("phi [")
+ for i, edge := range v.Edges {
+ if i > 0 {
+ b.WriteString(", ")
+ }
+ // Be robust against malformed CFG.
+ block := -1
+ if v.block != nil && i < len(v.block.Preds) {
+ block = v.block.Preds[i].Index
+ }
+ fmt.Fprintf(&b, "%d: ", block)
+ edgeVal := "" // be robust
+ if edge != nil {
+ edgeVal = relName(edge, v)
+ }
+ b.WriteString(edgeVal)
+ }
+ b.WriteString("]")
+ if v.Comment != "" {
+ b.WriteString(" #")
+ b.WriteString(v.Comment)
+ }
+ return b.String()
+}
+
+func printCall(v *CallCommon, prefix string, instr Instruction) string {
+ var b bytes.Buffer
+ b.WriteString(prefix)
+ if !v.IsInvoke() {
+ b.WriteString(relName(v.Value, instr))
+ } else {
+ fmt.Fprintf(&b, "invoke %s.%s", relName(v.Value, instr), v.Method.Name())
+ }
+ b.WriteString("(")
+ for i, arg := range v.Args {
+ if i > 0 {
+ b.WriteString(", ")
+ }
+ b.WriteString(relName(arg, instr))
+ }
+ if v.Signature().Variadic() {
+ b.WriteString("...")
+ }
+ b.WriteString(")")
+ return b.String()
+}
+
+func (c *CallCommon) String() string {
+ return printCall(c, "", nil)
+}
+
+func (v *Call) String() string {
+ return printCall(&v.Call, "", v)
+}
+
+func (v *BinOp) String() string {
+ return fmt.Sprintf("%s %s %s", relName(v.X, v), v.Op.String(), relName(v.Y, v))
+}
+
+func (v *UnOp) String() string {
+ return fmt.Sprintf("%s%s%s", v.Op, relName(v.X, v), commaOk(v.CommaOk))
+}
+
+func printConv(prefix string, v, x Value) string {
+ from := v.Parent().pkgobj()
+ return fmt.Sprintf("%s %s <- %s (%s)",
+ prefix,
+ relType(v.Type(), from),
+ relType(x.Type(), from),
+ relName(x, v.(Instruction)))
+}
+
+func (v *ChangeType) String() string { return printConv("changetype", v, v.X) }
+func (v *Convert) String() string { return printConv("convert", v, v.X) }
+func (v *ChangeInterface) String() string { return printConv("change interface", v, v.X) }
+func (v *MakeInterface) String() string { return printConv("make", v, v.X) }
+
+func (v *MakeClosure) String() string {
+ var b bytes.Buffer
+ fmt.Fprintf(&b, "make closure %s", relName(v.Fn, v))
+ if v.Bindings != nil {
+ b.WriteString(" [")
+ for i, c := range v.Bindings {
+ if i > 0 {
+ b.WriteString(", ")
+ }
+ b.WriteString(relName(c, v))
+ }
+ b.WriteString("]")
+ }
+ return b.String()
+}
+
+func (v *MakeSlice) String() string {
+ from := v.Parent().pkgobj()
+ return fmt.Sprintf("make %s %s %s",
+ relType(v.Type(), from),
+ relName(v.Len, v),
+ relName(v.Cap, v))
+}
+
+func (v *Slice) String() string {
+ var b bytes.Buffer
+ b.WriteString("slice ")
+ b.WriteString(relName(v.X, v))
+ b.WriteString("[")
+ if v.Low != nil {
+ b.WriteString(relName(v.Low, v))
+ }
+ b.WriteString(":")
+ if v.High != nil {
+ b.WriteString(relName(v.High, v))
+ }
+ if v.Max != nil {
+ b.WriteString(":")
+ b.WriteString(relName(v.Max, v))
+ }
+ b.WriteString("]")
+ return b.String()
+}
+
+func (v *MakeMap) String() string {
+ res := ""
+ if v.Reserve != nil {
+ res = relName(v.Reserve, v)
+ }
+ from := v.Parent().pkgobj()
+ return fmt.Sprintf("make %s %s", relType(v.Type(), from), res)
+}
+
+func (v *MakeChan) String() string {
+ from := v.Parent().pkgobj()
+ return fmt.Sprintf("make %s %s", relType(v.Type(), from), relName(v.Size, v))
+}
+
+func (v *FieldAddr) String() string {
+ st := deref(v.X.Type()).Underlying().(*types.Struct)
+ // Be robust against a bad index.
+ name := "?"
+ if 0 <= v.Field && v.Field < st.NumFields() {
+ name = st.Field(v.Field).Name()
+ }
+ return fmt.Sprintf("&%s.%s [#%d]", relName(v.X, v), name, v.Field)
+}
+
+func (v *Field) String() string {
+ st := v.X.Type().Underlying().(*types.Struct)
+ // Be robust against a bad index.
+ name := "?"
+ if 0 <= v.Field && v.Field < st.NumFields() {
+ name = st.Field(v.Field).Name()
+ }
+ return fmt.Sprintf("%s.%s [#%d]", relName(v.X, v), name, v.Field)
+}
+
+func (v *IndexAddr) String() string {
+ return fmt.Sprintf("&%s[%s]", relName(v.X, v), relName(v.Index, v))
+}
+
+func (v *Index) String() string {
+ return fmt.Sprintf("%s[%s]", relName(v.X, v), relName(v.Index, v))
+}
+
+func (v *Lookup) String() string {
+ return fmt.Sprintf("%s[%s]%s", relName(v.X, v), relName(v.Index, v), commaOk(v.CommaOk))
+}
+
+func (v *Range) String() string {
+ return "range " + relName(v.X, v)
+}
+
+func (v *Next) String() string {
+ return "next " + relName(v.Iter, v)
+}
+
+func (v *TypeAssert) String() string {
+ from := v.Parent().pkgobj()
+ return fmt.Sprintf("typeassert%s %s.(%s)", commaOk(v.CommaOk), relName(v.X, v), relType(v.AssertedType, from))
+}
+
+func (v *Extract) String() string {
+ return fmt.Sprintf("extract %s #%d", relName(v.Tuple, v), v.Index)
+}
+
+func (s *Jump) String() string {
+ // Be robust against malformed CFG.
+ block := -1
+ if s.block != nil && len(s.block.Succs) == 1 {
+ block = s.block.Succs[0].Index
+ }
+ return fmt.Sprintf("jump %d", block)
+}
+
+func (s *If) String() string {
+ // Be robust against malformed CFG.
+ tblock, fblock := -1, -1
+ if s.block != nil && len(s.block.Succs) == 2 {
+ tblock = s.block.Succs[0].Index
+ fblock = s.block.Succs[1].Index
+ }
+ return fmt.Sprintf("if %s goto %d else %d", relName(s.Cond, s), tblock, fblock)
+}
+
+func (s *Go) String() string {
+ return printCall(&s.Call, "go ", s)
+}
+
+func (s *Panic) String() string {
+ return "panic " + relName(s.X, s)
+}
+
+func (s *Return) String() string {
+ var b bytes.Buffer
+ b.WriteString("return")
+ for i, r := range s.Results {
+ if i == 0 {
+ b.WriteString(" ")
+ } else {
+ b.WriteString(", ")
+ }
+ b.WriteString(relName(r, s))
+ }
+ return b.String()
+}
+
+func (*RunDefers) String() string {
+ return "rundefers"
+}
+
+func (s *Send) String() string {
+ return fmt.Sprintf("send %s <- %s", relName(s.Chan, s), relName(s.X, s))
+}
+
+func (s *Defer) String() string {
+ return printCall(&s.Call, "defer ", s)
+}
+
+func (s *Select) String() string {
+ var b bytes.Buffer
+ for i, st := range s.States {
+ if i > 0 {
+ b.WriteString(", ")
+ }
+ if st.Dir == types.RecvOnly {
+ b.WriteString("<-")
+ b.WriteString(relName(st.Chan, s))
+ } else {
+ b.WriteString(relName(st.Chan, s))
+ b.WriteString("<-")
+ b.WriteString(relName(st.Send, s))
+ }
+ }
+ non := ""
+ if !s.Blocking {
+ non = "non"
+ }
+ return fmt.Sprintf("select %sblocking [%s]", non, b.String())
+}
+
+func (s *Store) String() string {
+ return fmt.Sprintf("*%s = %s", relName(s.Addr, s), relName(s.Val, s))
+}
+
+func (s *MapUpdate) String() string {
+ return fmt.Sprintf("%s[%s] = %s", relName(s.Map, s), relName(s.Key, s), relName(s.Value, s))
+}
+
+func (s *DebugRef) String() string {
+ p := s.Parent().Prog.Fset.Position(s.Pos())
+ var descr interface{}
+ if s.object != nil {
+ descr = s.object // e.g. "var x int"
+ } else {
+ descr = reflect.TypeOf(s.Expr) // e.g. "*ast.CallExpr"
+ }
+ var addr string
+ if s.IsAddr {
+ addr = "address of "
+ }
+ return fmt.Sprintf("; %s%s @ %d:%d is %s", addr, descr, p.Line, p.Column, s.X.Name())
+}
+
+func (p *Package) String() string {
+ return "package " + p.Object.Path()
+}
+
+var _ io.WriterTo = (*Package)(nil) // *Package implements io.Writer
+
+func (p *Package) WriteTo(w io.Writer) (int64, error) {
+ var buf bytes.Buffer
+ WritePackage(&buf, p)
+ n, err := w.Write(buf.Bytes())
+ return int64(n), err
+}
+
+// WritePackage writes to buf a human-readable summary of p.
+func WritePackage(buf *bytes.Buffer, p *Package) {
+ fmt.Fprintf(buf, "%s:\n", p)
+
+ var names []string
+ maxname := 0
+ for name := range p.Members {
+ if l := len(name); l > maxname {
+ maxname = l
+ }
+ names = append(names, name)
+ }
+
+ from := p.Object
+ sort.Strings(names)
+ for _, name := range names {
+ switch mem := p.Members[name].(type) {
+ case *NamedConst:
+ fmt.Fprintf(buf, " const %-*s %s = %s\n",
+ maxname, name, mem.Name(), mem.Value.RelString(from))
+
+ case *Function:
+ fmt.Fprintf(buf, " func %-*s %s\n",
+ maxname, name, relType(mem.Type(), from))
+
+ case *Type:
+ fmt.Fprintf(buf, " type %-*s %s\n",
+ maxname, name, relType(mem.Type().Underlying(), from))
+ for _, meth := range typeutil.IntuitiveMethodSet(mem.Type(), &p.Prog.MethodSets) {
+ fmt.Fprintf(buf, " %s\n", types.SelectionString(meth, types.RelativeTo(from)))
+ }
+
+ case *Global:
+ fmt.Fprintf(buf, " var %-*s %s\n",
+ maxname, name, relType(mem.Type().(*types.Pointer).Elem(), from))
+ }
+ }
+
+ fmt.Fprintf(buf, "\n")
+}
+
+func commaOk(x bool) string {
+ if x {
+ return ",ok"
+ }
+ return ""
+}
diff --git a/vendor/golang.org/x/tools/go/ssa/sanity.go b/vendor/golang.org/x/tools/go/ssa/sanity.go
new file mode 100644
index 0000000..b0593d0
--- /dev/null
+++ b/vendor/golang.org/x/tools/go/ssa/sanity.go
@@ -0,0 +1,520 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package ssa
+
+// An optional pass for sanity-checking invariants of the SSA representation.
+// Currently it checks CFG invariants but little at the instruction level.
+
+import (
+ "fmt"
+ "io"
+ "os"
+ "strings"
+
+ "golang.org/x/tools/go/types"
+)
+
+type sanity struct {
+ reporter io.Writer
+ fn *Function
+ block *BasicBlock
+ instrs map[Instruction]struct{}
+ insane bool
+}
+
+// sanityCheck performs integrity checking of the SSA representation
+// of the function fn and returns true if it was valid. Diagnostics
+// are written to reporter if non-nil, os.Stderr otherwise. Some
+// diagnostics are only warnings and do not imply a negative result.
+//
+// Sanity-checking is intended to facilitate the debugging of code
+// transformation passes.
+//
+func sanityCheck(fn *Function, reporter io.Writer) bool {
+ if reporter == nil {
+ reporter = os.Stderr
+ }
+ return (&sanity{reporter: reporter}).checkFunction(fn)
+}
+
+// mustSanityCheck is like sanityCheck but panics instead of returning
+// a negative result.
+//
+func mustSanityCheck(fn *Function, reporter io.Writer) {
+ if !sanityCheck(fn, reporter) {
+ fn.WriteTo(os.Stderr)
+ panic("SanityCheck failed")
+ }
+}
+
+func (s *sanity) diagnostic(prefix, format string, args ...interface{}) {
+ fmt.Fprintf(s.reporter, "%s: function %s", prefix, s.fn)
+ if s.block != nil {
+ fmt.Fprintf(s.reporter, ", block %s", s.block)
+ }
+ io.WriteString(s.reporter, ": ")
+ fmt.Fprintf(s.reporter, format, args...)
+ io.WriteString(s.reporter, "\n")
+}
+
+func (s *sanity) errorf(format string, args ...interface{}) {
+ s.insane = true
+ s.diagnostic("Error", format, args...)
+}
+
+func (s *sanity) warnf(format string, args ...interface{}) {
+ s.diagnostic("Warning", format, args...)
+}
+
+// findDuplicate returns an arbitrary basic block that appeared more
+// than once in blocks, or nil if all were unique.
+func findDuplicate(blocks []*BasicBlock) *BasicBlock {
+ if len(blocks) < 2 {
+ return nil
+ }
+ if blocks[0] == blocks[1] {
+ return blocks[0]
+ }
+ // Slow path:
+ m := make(map[*BasicBlock]bool)
+ for _, b := range blocks {
+ if m[b] {
+ return b
+ }
+ m[b] = true
+ }
+ return nil
+}
+
+func (s *sanity) checkInstr(idx int, instr Instruction) {
+ switch instr := instr.(type) {
+ case *If, *Jump, *Return, *Panic:
+ s.errorf("control flow instruction not at end of block")
+ case *Phi:
+ if idx == 0 {
+ // It suffices to apply this check to just the first phi node.
+ if dup := findDuplicate(s.block.Preds); dup != nil {
+ s.errorf("phi node in block with duplicate predecessor %s", dup)
+ }
+ } else {
+ prev := s.block.Instrs[idx-1]
+ if _, ok := prev.(*Phi); !ok {
+ s.errorf("Phi instruction follows a non-Phi: %T", prev)
+ }
+ }
+ if ne, np := len(instr.Edges), len(s.block.Preds); ne != np {
+ s.errorf("phi node has %d edges but %d predecessors", ne, np)
+
+ } else {
+ for i, e := range instr.Edges {
+ if e == nil {
+ s.errorf("phi node '%s' has no value for edge #%d from %s", instr.Comment, i, s.block.Preds[i])
+ }
+ }
+ }
+
+ case *Alloc:
+ if !instr.Heap {
+ found := false
+ for _, l := range s.fn.Locals {
+ if l == instr {
+ found = true
+ break
+ }
+ }
+ if !found {
+ s.errorf("local alloc %s = %s does not appear in Function.Locals", instr.Name(), instr)
+ }
+ }
+
+ case *BinOp:
+ case *Call:
+ case *ChangeInterface:
+ case *ChangeType:
+ case *Convert:
+ if _, ok := instr.X.Type().Underlying().(*types.Basic); !ok {
+ if _, ok := instr.Type().Underlying().(*types.Basic); !ok {
+ s.errorf("convert %s -> %s: at least one type must be basic", instr.X.Type(), instr.Type())
+ }
+ }
+
+ case *Defer:
+ case *Extract:
+ case *Field:
+ case *FieldAddr:
+ case *Go:
+ case *Index:
+ case *IndexAddr:
+ case *Lookup:
+ case *MakeChan:
+ case *MakeClosure:
+ numFree := len(instr.Fn.(*Function).FreeVars)
+ numBind := len(instr.Bindings)
+ if numFree != numBind {
+ s.errorf("MakeClosure has %d Bindings for function %s with %d free vars",
+ numBind, instr.Fn, numFree)
+
+ }
+ if recv := instr.Type().(*types.Signature).Recv(); recv != nil {
+ s.errorf("MakeClosure's type includes receiver %s", recv.Type())
+ }
+
+ case *MakeInterface:
+ case *MakeMap:
+ case *MakeSlice:
+ case *MapUpdate:
+ case *Next:
+ case *Range:
+ case *RunDefers:
+ case *Select:
+ case *Send:
+ case *Slice:
+ case *Store:
+ case *TypeAssert:
+ case *UnOp:
+ case *DebugRef:
+ // TODO(adonovan): implement checks.
+ default:
+ panic(fmt.Sprintf("Unknown instruction type: %T", instr))
+ }
+
+ if call, ok := instr.(CallInstruction); ok {
+ if call.Common().Signature() == nil {
+ s.errorf("nil signature: %s", call)
+ }
+ }
+
+ // Check that value-defining instructions have valid types
+ // and a valid referrer list.
+ if v, ok := instr.(Value); ok {
+ t := v.Type()
+ if t == nil {
+ s.errorf("no type: %s = %s", v.Name(), v)
+ } else if t == tRangeIter {
+ // not a proper type; ignore.
+ } else if b, ok := t.Underlying().(*types.Basic); ok && b.Info()&types.IsUntyped != 0 {
+ s.errorf("instruction has 'untyped' result: %s = %s : %s", v.Name(), v, t)
+ }
+ s.checkReferrerList(v)
+ }
+
+ // Untyped constants are legal as instruction Operands(),
+ // for example:
+ // _ = "foo"[0]
+ // or:
+ // if wordsize==64 {...}
+
+ // All other non-Instruction Values can be found via their
+ // enclosing Function or Package.
+}
+
+func (s *sanity) checkFinalInstr(idx int, instr Instruction) {
+ switch instr := instr.(type) {
+ case *If:
+ if nsuccs := len(s.block.Succs); nsuccs != 2 {
+ s.errorf("If-terminated block has %d successors; expected 2", nsuccs)
+ return
+ }
+ if s.block.Succs[0] == s.block.Succs[1] {
+ s.errorf("If-instruction has same True, False target blocks: %s", s.block.Succs[0])
+ return
+ }
+
+ case *Jump:
+ if nsuccs := len(s.block.Succs); nsuccs != 1 {
+ s.errorf("Jump-terminated block has %d successors; expected 1", nsuccs)
+ return
+ }
+
+ case *Return:
+ if nsuccs := len(s.block.Succs); nsuccs != 0 {
+ s.errorf("Return-terminated block has %d successors; expected none", nsuccs)
+ return
+ }
+ if na, nf := len(instr.Results), s.fn.Signature.Results().Len(); nf != na {
+ s.errorf("%d-ary return in %d-ary function", na, nf)
+ }
+
+ case *Panic:
+ if nsuccs := len(s.block.Succs); nsuccs != 0 {
+ s.errorf("Panic-terminated block has %d successors; expected none", nsuccs)
+ return
+ }
+
+ default:
+ s.errorf("non-control flow instruction at end of block")
+ }
+}
+
+func (s *sanity) checkBlock(b *BasicBlock, index int) {
+ s.block = b
+
+ if b.Index != index {
+ s.errorf("block has incorrect Index %d", b.Index)
+ }
+ if b.parent != s.fn {
+ s.errorf("block has incorrect parent %s", b.parent)
+ }
+
+ // Check all blocks are reachable.
+ // (The entry block is always implicitly reachable,
+ // as is the Recover block, if any.)
+ if (index > 0 && b != b.parent.Recover) && len(b.Preds) == 0 {
+ s.warnf("unreachable block")
+ if b.Instrs == nil {
+ // Since this block is about to be pruned,
+ // tolerating transient problems in it
+ // simplifies other optimizations.
+ return
+ }
+ }
+
+ // Check predecessor and successor relations are dual,
+ // and that all blocks in CFG belong to same function.
+ for _, a := range b.Preds {
+ found := false
+ for _, bb := range a.Succs {
+ if bb == b {
+ found = true
+ break
+ }
+ }
+ if !found {
+ s.errorf("expected successor edge in predecessor %s; found only: %s", a, a.Succs)
+ }
+ if a.parent != s.fn {
+ s.errorf("predecessor %s belongs to different function %s", a, a.parent)
+ }
+ }
+ for _, c := range b.Succs {
+ found := false
+ for _, bb := range c.Preds {
+ if bb == b {
+ found = true
+ break
+ }
+ }
+ if !found {
+ s.errorf("expected predecessor edge in successor %s; found only: %s", c, c.Preds)
+ }
+ if c.parent != s.fn {
+ s.errorf("successor %s belongs to different function %s", c, c.parent)
+ }
+ }
+
+ // Check each instruction is sane.
+ n := len(b.Instrs)
+ if n == 0 {
+ s.errorf("basic block contains no instructions")
+ }
+ var rands [10]*Value // reuse storage
+ for j, instr := range b.Instrs {
+ if instr == nil {
+ s.errorf("nil instruction at index %d", j)
+ continue
+ }
+ if b2 := instr.Block(); b2 == nil {
+ s.errorf("nil Block() for instruction at index %d", j)
+ continue
+ } else if b2 != b {
+ s.errorf("wrong Block() (%s) for instruction at index %d ", b2, j)
+ continue
+ }
+ if j < n-1 {
+ s.checkInstr(j, instr)
+ } else {
+ s.checkFinalInstr(j, instr)
+ }
+
+ // Check Instruction.Operands.
+ operands:
+ for i, op := range instr.Operands(rands[:0]) {
+ if op == nil {
+ s.errorf("nil operand pointer %d of %s", i, instr)
+ continue
+ }
+ val := *op
+ if val == nil {
+ continue // a nil operand is ok
+ }
+
+ // Check that "untyped" types only appear on constant operands.
+ if _, ok := (*op).(*Const); !ok {
+ if basic, ok := (*op).Type().(*types.Basic); ok {
+ if basic.Info()&types.IsUntyped != 0 {
+ s.errorf("operand #%d of %s is untyped: %s", i, instr, basic)
+ }
+ }
+ }
+
+ // Check that Operands that are also Instructions belong to same function.
+ // TODO(adonovan): also check their block dominates block b.
+ if val, ok := val.(Instruction); ok {
+ if val.Parent() != s.fn {
+ s.errorf("operand %d of %s is an instruction (%s) from function %s", i, instr, val, val.Parent())
+ }
+ }
+
+ // Check that each function-local operand of
+ // instr refers back to instr. (NB: quadratic)
+ switch val := val.(type) {
+ case *Const, *Global, *Builtin:
+ continue // not local
+ case *Function:
+ if val.parent == nil {
+ continue // only anon functions are local
+ }
+ }
+
+ // TODO(adonovan): check val.Parent() != nil <=> val.Referrers() is defined.
+
+ if refs := val.Referrers(); refs != nil {
+ for _, ref := range *refs {
+ if ref == instr {
+ continue operands
+ }
+ }
+ s.errorf("operand %d of %s (%s) does not refer to us", i, instr, val)
+ } else {
+ s.errorf("operand %d of %s (%s) has no referrers", i, instr, val)
+ }
+ }
+ }
+}
+
+func (s *sanity) checkReferrerList(v Value) {
+ refs := v.Referrers()
+ if refs == nil {
+ s.errorf("%s has missing referrer list", v.Name())
+ return
+ }
+ for i, ref := range *refs {
+ if _, ok := s.instrs[ref]; !ok {
+ s.errorf("%s.Referrers()[%d] = %s is not an instruction belonging to this function", v.Name(), i, ref)
+ }
+ }
+}
+
+func (s *sanity) checkFunction(fn *Function) bool {
+ // TODO(adonovan): check Function invariants:
+ // - check params match signature
+ // - check transient fields are nil
+ // - warn if any fn.Locals do not appear among block instructions.
+ s.fn = fn
+ if fn.Prog == nil {
+ s.errorf("nil Prog")
+ }
+
+ fn.String() // must not crash
+ fn.RelString(fn.pkgobj()) // must not crash
+
+ // All functions have a package, except delegates (which are
+ // shared across packages, or duplicated as weak symbols in a
+ // separate-compilation model), and error.Error.
+ if fn.Pkg == nil {
+ if strings.HasPrefix(fn.Synthetic, "wrapper ") ||
+ strings.HasPrefix(fn.Synthetic, "bound ") ||
+ strings.HasPrefix(fn.Synthetic, "thunk ") ||
+ strings.HasSuffix(fn.name, "Error") {
+ // ok
+ } else {
+ s.errorf("nil Pkg")
+ }
+ }
+ if src, syn := fn.Synthetic == "", fn.Syntax() != nil; src != syn {
+ s.errorf("got fromSource=%t, hasSyntax=%t; want same values", src, syn)
+ }
+ for i, l := range fn.Locals {
+ if l.Parent() != fn {
+ s.errorf("Local %s at index %d has wrong parent", l.Name(), i)
+ }
+ if l.Heap {
+ s.errorf("Local %s at index %d has Heap flag set", l.Name(), i)
+ }
+ }
+ // Build the set of valid referrers.
+ s.instrs = make(map[Instruction]struct{})
+ for _, b := range fn.Blocks {
+ for _, instr := range b.Instrs {
+ s.instrs[instr] = struct{}{}
+ }
+ }
+ for i, p := range fn.Params {
+ if p.Parent() != fn {
+ s.errorf("Param %s at index %d has wrong parent", p.Name(), i)
+ }
+ s.checkReferrerList(p)
+ }
+ for i, fv := range fn.FreeVars {
+ if fv.Parent() != fn {
+ s.errorf("FreeVar %s at index %d has wrong parent", fv.Name(), i)
+ }
+ s.checkReferrerList(fv)
+ }
+
+ if fn.Blocks != nil && len(fn.Blocks) == 0 {
+ // Function _had_ blocks (so it's not external) but
+ // they were "optimized" away, even the entry block.
+ s.errorf("Blocks slice is non-nil but empty")
+ }
+ for i, b := range fn.Blocks {
+ if b == nil {
+ s.warnf("nil *BasicBlock at f.Blocks[%d]", i)
+ continue
+ }
+ s.checkBlock(b, i)
+ }
+ if fn.Recover != nil && fn.Blocks[fn.Recover.Index] != fn.Recover {
+ s.errorf("Recover block is not in Blocks slice")
+ }
+
+ s.block = nil
+ for i, anon := range fn.AnonFuncs {
+ if anon.Parent() != fn {
+ s.errorf("AnonFuncs[%d]=%s but %s.Parent()=%s", i, anon, anon, anon.Parent())
+ }
+ }
+ s.fn = nil
+ return !s.insane
+}
+
+// sanityCheckPackage checks invariants of packages upon creation.
+// It does not require that the package is built.
+// Unlike sanityCheck (for functions), it just panics at the first error.
+func sanityCheckPackage(pkg *Package) {
+ if pkg.Object == nil {
+ panic(fmt.Sprintf("Package %s has no Object", pkg))
+ }
+ pkg.String() // must not crash
+
+ for name, mem := range pkg.Members {
+ if name != mem.Name() {
+ panic(fmt.Sprintf("%s: %T.Name() = %s, want %s",
+ pkg.Object.Path(), mem, mem.Name(), name))
+ }
+ obj := mem.Object()
+ if obj == nil {
+ // This check is sound because fields
+ // {Global,Function}.object have type
+ // types.Object. (If they were declared as
+ // *types.{Var,Func}, we'd have a non-empty
+ // interface containing a nil pointer.)
+
+ continue // not all members have typechecker objects
+ }
+ if obj.Name() != name {
+ if obj.Name() == "init" && strings.HasPrefix(mem.Name(), "init#") {
+ // Ok. The name of a declared init function varies between
+ // its types.Func ("init") and its ssa.Function ("init#%d").
+ } else {
+ panic(fmt.Sprintf("%s: %T.Object().Name() = %s, want %s",
+ pkg.Object.Path(), mem, obj.Name(), name))
+ }
+ }
+ if obj.Pos() != mem.Pos() {
+ panic(fmt.Sprintf("%s Pos=%d obj.Pos=%d", mem, mem.Pos(), obj.Pos()))
+ }
+ }
+}
diff --git a/vendor/golang.org/x/tools/go/ssa/source.go b/vendor/golang.org/x/tools/go/ssa/source.go
new file mode 100644
index 0000000..84e6f1d
--- /dev/null
+++ b/vendor/golang.org/x/tools/go/ssa/source.go
@@ -0,0 +1,294 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package ssa
+
+// This file defines utilities for working with source positions
+// or source-level named entities ("objects").
+
+// TODO(adonovan): test that {Value,Instruction}.Pos() positions match
+// the originating syntax, as specified.
+
+import (
+ "go/ast"
+ "go/token"
+
+ "golang.org/x/tools/go/types"
+)
+
+// EnclosingFunction returns the function that contains the syntax
+// node denoted by path.
+//
+// Syntax associated with package-level variable specifications is
+// enclosed by the package's init() function.
+//
+// Returns nil if not found; reasons might include:
+// - the node is not enclosed by any function.
+// - the node is within an anonymous function (FuncLit) and
+// its SSA function has not been created yet
+// (pkg.Build() has not yet been called).
+//
+func EnclosingFunction(pkg *Package, path []ast.Node) *Function {
+ // Start with package-level function...
+ fn := findEnclosingPackageLevelFunction(pkg, path)
+ if fn == nil {
+ return nil // not in any function
+ }
+
+ // ...then walk down the nested anonymous functions.
+ n := len(path)
+outer:
+ for i := range path {
+ if lit, ok := path[n-1-i].(*ast.FuncLit); ok {
+ for _, anon := range fn.AnonFuncs {
+ if anon.Pos() == lit.Type.Func {
+ fn = anon
+ continue outer
+ }
+ }
+ // SSA function not found:
+ // - package not yet built, or maybe
+ // - builder skipped FuncLit in dead block
+ // (in principle; but currently the Builder
+ // generates even dead FuncLits).
+ return nil
+ }
+ }
+ return fn
+}
+
+// HasEnclosingFunction returns true if the AST node denoted by path
+// is contained within the declaration of some function or
+// package-level variable.
+//
+// Unlike EnclosingFunction, the behaviour of this function does not
+// depend on whether SSA code for pkg has been built, so it can be
+// used to quickly reject check inputs that will cause
+// EnclosingFunction to fail, prior to SSA building.
+//
+func HasEnclosingFunction(pkg *Package, path []ast.Node) bool {
+ return findEnclosingPackageLevelFunction(pkg, path) != nil
+}
+
+// findEnclosingPackageLevelFunction returns the Function
+// corresponding to the package-level function enclosing path.
+//
+func findEnclosingPackageLevelFunction(pkg *Package, path []ast.Node) *Function {
+ if n := len(path); n >= 2 { // [... {Gen,Func}Decl File]
+ switch decl := path[n-2].(type) {
+ case *ast.GenDecl:
+ if decl.Tok == token.VAR && n >= 3 {
+ // Package-level 'var' initializer.
+ return pkg.init
+ }
+
+ case *ast.FuncDecl:
+ if decl.Recv == nil && decl.Name.Name == "init" {
+ // Explicit init() function.
+ for _, b := range pkg.init.Blocks {
+ for _, instr := range b.Instrs {
+ if instr, ok := instr.(*Call); ok {
+ if callee, ok := instr.Call.Value.(*Function); ok && callee.Pkg == pkg && callee.Pos() == decl.Name.NamePos {
+ return callee
+ }
+ }
+ }
+ }
+ // Hack: return non-nil when SSA is not yet
+ // built so that HasEnclosingFunction works.
+ return pkg.init
+ }
+ // Declared function/method.
+ return findNamedFunc(pkg, decl.Name.NamePos)
+ }
+ }
+ return nil // not in any function
+}
+
+// findNamedFunc returns the named function whose FuncDecl.Ident is at
+// position pos.
+//
+func findNamedFunc(pkg *Package, pos token.Pos) *Function {
+ // Look at all package members and method sets of named types.
+ // Not very efficient.
+ for _, mem := range pkg.Members {
+ switch mem := mem.(type) {
+ case *Function:
+ if mem.Pos() == pos {
+ return mem
+ }
+ case *Type:
+ mset := pkg.Prog.MethodSets.MethodSet(types.NewPointer(mem.Type()))
+ for i, n := 0, mset.Len(); i < n; i++ {
+ // Don't call Program.Method: avoid creating wrappers.
+ obj := mset.At(i).Obj().(*types.Func)
+ if obj.Pos() == pos {
+ return pkg.values[obj].(*Function)
+ }
+ }
+ }
+ }
+ return nil
+}
+
+// ValueForExpr returns the SSA Value that corresponds to non-constant
+// expression e.
+//
+// It returns nil if no value was found, e.g.
+// - the expression is not lexically contained within f;
+// - f was not built with debug information; or
+// - e is a constant expression. (For efficiency, no debug
+// information is stored for constants. Use
+// go/types.Info.Types[e].Value instead.)
+// - e is a reference to nil or a built-in function.
+// - the value was optimised away.
+//
+// If e is an addressable expression used in an lvalue context,
+// value is the address denoted by e, and isAddr is true.
+//
+// The types of e (or &e, if isAddr) and the result are equal
+// (modulo "untyped" bools resulting from comparisons).
+//
+// (Tip: to find the ssa.Value given a source position, use
+// importer.PathEnclosingInterval to locate the ast.Node, then
+// EnclosingFunction to locate the Function, then ValueForExpr to find
+// the ssa.Value.)
+//
+func (f *Function) ValueForExpr(e ast.Expr) (value Value, isAddr bool) {
+ if f.debugInfo() { // (opt)
+ e = unparen(e)
+ for _, b := range f.Blocks {
+ for _, instr := range b.Instrs {
+ if ref, ok := instr.(*DebugRef); ok {
+ if ref.Expr == e {
+ return ref.X, ref.IsAddr
+ }
+ }
+ }
+ }
+ }
+ return
+}
+
+// --- Lookup functions for source-level named entities (types.Objects) ---
+
+// Package returns the SSA Package corresponding to the specified
+// type-checker package object.
+// It returns nil if no such SSA package has been created.
+//
+func (prog *Program) Package(obj *types.Package) *Package {
+ return prog.packages[obj]
+}
+
+// packageLevelValue returns the package-level value corresponding to
+// the specified named object, which may be a package-level const
+// (*Const), var (*Global) or func (*Function) of some package in
+// prog. It returns nil if the object is not found.
+//
+func (prog *Program) packageLevelValue(obj types.Object) Value {
+ if pkg, ok := prog.packages[obj.Pkg()]; ok {
+ return pkg.values[obj]
+ }
+ return nil
+}
+
+// FuncValue returns the concrete Function denoted by the source-level
+// named function obj, or nil if obj denotes an interface method.
+//
+// TODO(adonovan): check the invariant that obj.Type() matches the
+// result's Signature, both in the params/results and in the receiver.
+//
+func (prog *Program) FuncValue(obj *types.Func) *Function {
+ fn, _ := prog.packageLevelValue(obj).(*Function)
+ return fn
+}
+
+// ConstValue returns the SSA Value denoted by the source-level named
+// constant obj.
+//
+func (prog *Program) ConstValue(obj *types.Const) *Const {
+ // TODO(adonovan): opt: share (don't reallocate)
+ // Consts for const objects and constant ast.Exprs.
+
+ // Universal constant? {true,false,nil}
+ if obj.Parent() == types.Universe {
+ return NewConst(obj.Val(), obj.Type())
+ }
+ // Package-level named constant?
+ if v := prog.packageLevelValue(obj); v != nil {
+ return v.(*Const)
+ }
+ return NewConst(obj.Val(), obj.Type())
+}
+
+// VarValue returns the SSA Value that corresponds to a specific
+// identifier denoting the source-level named variable obj.
+//
+// VarValue returns nil if a local variable was not found, perhaps
+// because its package was not built, the debug information was not
+// requested during SSA construction, or the value was optimized away.
+//
+// ref is the path to an ast.Ident (e.g. from PathEnclosingInterval),
+// and that ident must resolve to obj.
+//
+// pkg is the package enclosing the reference. (A reference to a var
+// always occurs within a function, so we need to know where to find it.)
+//
+// If the identifier is a field selector and its base expression is
+// non-addressable, then VarValue returns the value of that field.
+// For example:
+// func f() struct {x int}
+// f().x // VarValue(x) returns a *Field instruction of type int
+//
+// All other identifiers denote addressable locations (variables).
+// For them, VarValue may return either the variable's address or its
+// value, even when the expression is evaluated only for its value; the
+// situation is reported by isAddr, the second component of the result.
+//
+// If !isAddr, the returned value is the one associated with the
+// specific identifier. For example,
+// var x int // VarValue(x) returns Const 0 here
+// x = 1 // VarValue(x) returns Const 1 here
+//
+// It is not specified whether the value or the address is returned in
+// any particular case, as it may depend upon optimizations performed
+// during SSA code generation, such as registerization, constant
+// folding, avoidance of materialization of subexpressions, etc.
+//
+func (prog *Program) VarValue(obj *types.Var, pkg *Package, ref []ast.Node) (value Value, isAddr bool) {
+ // All references to a var are local to some function, possibly init.
+ fn := EnclosingFunction(pkg, ref)
+ if fn == nil {
+ return // e.g. def of struct field; SSA not built?
+ }
+
+ id := ref[0].(*ast.Ident)
+
+ // Defining ident of a parameter?
+ if id.Pos() == obj.Pos() {
+ for _, param := range fn.Params {
+ if param.Object() == obj {
+ return param, false
+ }
+ }
+ }
+
+ // Other ident?
+ for _, b := range fn.Blocks {
+ for _, instr := range b.Instrs {
+ if dr, ok := instr.(*DebugRef); ok {
+ if dr.Pos() == id.Pos() {
+ return dr.X, dr.IsAddr
+ }
+ }
+ }
+ }
+
+ // Defining ident of package-level var?
+ if v := prog.packageLevelValue(obj); v != nil {
+ return v.(*Global), true
+ }
+
+ return // e.g. debug info not requested, or var optimized away
+}
diff --git a/vendor/golang.org/x/tools/go/ssa/ssa.go b/vendor/golang.org/x/tools/go/ssa/ssa.go
new file mode 100644
index 0000000..f4c64bb
--- /dev/null
+++ b/vendor/golang.org/x/tools/go/ssa/ssa.go
@@ -0,0 +1,1700 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package ssa
+
+// This package defines a high-level intermediate representation for
+// Go programs using static single-assignment (SSA) form.
+
+import (
+ "fmt"
+ "go/ast"
+ "go/token"
+ "sync"
+
+ "golang.org/x/tools/go/exact"
+ "golang.org/x/tools/go/types"
+ "golang.org/x/tools/go/types/typeutil"
+)
+
+// A Program is a partial or complete Go program converted to SSA form.
+type Program struct {
+ Fset *token.FileSet // position information for the files of this Program
+ imported map[string]*Package // all importable Packages, keyed by import path
+ packages map[*types.Package]*Package // all loaded Packages, keyed by object
+ mode BuilderMode // set of mode bits for SSA construction
+ MethodSets typeutil.MethodSetCache // cache of type-checker's method-sets
+
+ methodsMu sync.Mutex // guards the following maps:
+ methodSets typeutil.Map // maps type to its concrete methodSet
+ runtimeTypes typeutil.Map // types for which rtypes are needed
+ canon typeutil.Map // type canonicalization map
+ bounds map[*types.Func]*Function // bounds for curried x.Method closures
+ thunks map[selectionKey]*Function // thunks for T.Method expressions
+}
+
+// A Package is a single analyzed Go package containing Members for
+// all package-level functions, variables, constants and types it
+// declares. These may be accessed directly via Members, or via the
+// type-specific accessor methods Func, Type, Var and Const.
+//
+// Members also contains entries for "init" (the synthetic package
+// initializer) and "init#%d", the nth declared init function,
+// and unspecified other things too.
+//
+type Package struct {
+ Prog *Program // the owning program
+ Object *types.Package // the type checker's package object for this package
+ Members map[string]Member // all package members keyed by name (incl. init and init#%d)
+ values map[types.Object]Value // package members (incl. types and methods), keyed by object
+ init *Function // Func("init"); the package's init function
+ debug bool // include full debug info in this package
+
+ // The following fields are set transiently, then cleared
+ // after building.
+ started int32 // atomically tested and set at start of build phase
+ ninit int32 // number of init functions
+ info *types.Info // package type information
+ files []*ast.File // package ASTs
+}
+
+// A Member is a member of a Go package, implemented by *NamedConst,
+// *Global, *Function, or *Type; they are created by package-level
+// const, var, func and type declarations respectively.
+//
+type Member interface {
+ Name() string // declared name of the package member
+ String() string // package-qualified name of the package member
+ RelString(*types.Package) string // like String, but relative refs are unqualified
+ Object() types.Object // typechecker's object for this member, if any
+ Pos() token.Pos // position of member's declaration, if known
+ Type() types.Type // type of the package member
+ Token() token.Token // token.{VAR,FUNC,CONST,TYPE}
+ Package() *Package // the containing package
+}
+
+// A Type is a Member of a Package representing a package-level named type.
+//
+// Type() returns a *types.Named.
+//
+type Type struct {
+ object *types.TypeName
+ pkg *Package
+}
+
+// A NamedConst is a Member of a Package representing a package-level
+// named constant.
+//
+// Pos() returns the position of the declaring ast.ValueSpec.Names[*]
+// identifier.
+//
+// NB: a NamedConst is not a Value; it contains a constant Value, which
+// it augments with the name and position of its 'const' declaration.
+//
+type NamedConst struct {
+ object *types.Const
+ Value *Const
+ pos token.Pos
+ pkg *Package
+}
+
+// A Value is an SSA value that can be referenced by an instruction.
+type Value interface {
+ // Name returns the name of this value, and determines how
+ // this Value appears when used as an operand of an
+ // Instruction.
+ //
+ // This is the same as the source name for Parameters,
+ // Builtins, Functions, FreeVars, Globals.
+ // For constants, it is a representation of the constant's value
+ // and type. For all other Values this is the name of the
+ // virtual register defined by the instruction.
+ //
+ // The name of an SSA Value is not semantically significant,
+ // and may not even be unique within a function.
+ Name() string
+
+ // If this value is an Instruction, String returns its
+ // disassembled form; otherwise it returns unspecified
+ // human-readable information about the Value, such as its
+ // kind, name and type.
+ String() string
+
+ // Type returns the type of this value. Many instructions
+ // (e.g. IndexAddr) change their behaviour depending on the
+ // types of their operands.
+ Type() types.Type
+
+ // Parent returns the function to which this Value belongs.
+ // It returns nil for named Functions, Builtin, Const and Global.
+ Parent() *Function
+
+ // Referrers returns the list of instructions that have this
+ // value as one of their operands; it may contain duplicates
+ // if an instruction has a repeated operand.
+ //
+ // Referrers actually returns a pointer through which the
+ // caller may perform mutations to the object's state.
+ //
+ // Referrers is currently only defined if Parent()!=nil,
+ // i.e. for the function-local values FreeVar, Parameter,
+ // Functions (iff anonymous) and all value-defining instructions.
+ // It returns nil for named Functions, Builtin, Const and Global.
+ //
+ // Instruction.Operands contains the inverse of this relation.
+ Referrers() *[]Instruction
+
+ // Pos returns the location of the AST token most closely
+ // associated with the operation that gave rise to this value,
+ // or token.NoPos if it was not explicit in the source.
+ //
+ // For each ast.Node type, a particular token is designated as
+ // the closest location for the expression, e.g. the Lparen
+ // for an *ast.CallExpr. This permits a compact but
+ // approximate mapping from Values to source positions for use
+ // in diagnostic messages, for example.
+ //
+ // (Do not use this position to determine which Value
+ // corresponds to an ast.Expr; use Function.ValueForExpr
+ // instead. NB: it requires that the function was built with
+ // debug information.)
+ Pos() token.Pos
+}
+
+// An Instruction is an SSA instruction that computes a new Value or
+// has some effect.
+//
+// An Instruction that defines a value (e.g. BinOp) also implements
+// the Value interface; an Instruction that only has an effect (e.g. Store)
+// does not.
+//
+type Instruction interface {
+ // String returns the disassembled form of this value.
+ //
+ // Examples of Instructions that are Values:
+ // "x + y" (BinOp)
+ // "len([])" (Call)
+ // Note that the name of the Value is not printed.
+ //
+ // Examples of Instructions that are not Values:
+ // "return x" (Return)
+ // "*y = x" (Store)
+ //
+ // (The separation Value.Name() from Value.String() is useful
+ // for some analyses which distinguish the operation from the
+ // value it defines, e.g., 'y = local int' is both an allocation
+ // of memory 'local int' and a definition of a pointer y.)
+ String() string
+
+ // Parent returns the function to which this instruction
+ // belongs.
+ Parent() *Function
+
+ // Block returns the basic block to which this instruction
+ // belongs.
+ Block() *BasicBlock
+
+ // setBlock sets the basic block to which this instruction belongs.
+ setBlock(*BasicBlock)
+
+ // Operands returns the operands of this instruction: the
+ // set of Values it references.
+ //
+ // Specifically, it appends their addresses to rands, a
+ // user-provided slice, and returns the resulting slice,
+ // permitting avoidance of memory allocation.
+ //
+ // The operands are appended in undefined order, but the order
+ // is consistent for a given Instruction; the addresses are
+ // always non-nil but may point to a nil Value. Clients may
+ // store through the pointers, e.g. to effect a value
+ // renaming.
+ //
+ // Value.Referrers is a subset of the inverse of this
+ // relation. (Referrers are not tracked for all types of
+ // Values.)
+ Operands(rands []*Value) []*Value
+
+ // Pos returns the location of the AST token most closely
+ // associated with the operation that gave rise to this
+ // instruction, or token.NoPos if it was not explicit in the
+ // source.
+ //
+ // For each ast.Node type, a particular token is designated as
+ // the closest location for the expression, e.g. the Go token
+ // for an *ast.GoStmt. This permits a compact but approximate
+ // mapping from Instructions to source positions for use in
+ // diagnostic messages, for example.
+ //
+ // (Do not use this position to determine which Instruction
+ // corresponds to an ast.Expr; see the notes for Value.Pos.
+ // This position may be used to determine which non-Value
+ // Instruction corresponds to some ast.Stmts, but not all: If
+ // and Jump instructions have no Pos(), for example.)
+ Pos() token.Pos
+}
+
+// A Node is a node in the SSA value graph. Every concrete type that
+// implements Node is also either a Value, an Instruction, or both.
+//
+// Node contains the methods common to Value and Instruction, plus the
+// Operands and Referrers methods generalized to return nil for
+// non-Instructions and non-Values, respectively.
+//
+// Node is provided to simplify SSA graph algorithms. Clients should
+// use the more specific and informative Value or Instruction
+// interfaces where appropriate.
+//
+type Node interface {
+ // Common methods:
+ String() string
+ Pos() token.Pos
+ Parent() *Function
+
+ // Partial methods:
+ Operands(rands []*Value) []*Value // nil for non-Instructions
+ Referrers() *[]Instruction // nil for non-Values
+}
+
+// Function represents the parameters, results, and code of a function
+// or method.
+//
+// If Blocks is nil, this indicates an external function for which no
+// Go source code is available. In this case, FreeVars and Locals
+// are nil too. Clients performing whole-program analysis must
+// handle external functions specially.
+//
+// Blocks contains the function's control-flow graph (CFG).
+// Blocks[0] is the function entry point; block order is not otherwise
+// semantically significant, though it may affect the readability of
+// the disassembly.
+// To iterate over the blocks in dominance order, use DomPreorder().
+//
+// Recover is an optional second entry point to which control resumes
+// after a recovered panic. The Recover block may contain only a return
+// statement, preceded by a load of the function's named return
+// parameters, if any.
+//
+// A nested function (Parent()!=nil) that refers to one or more
+// lexically enclosing local variables ("free variables") has FreeVars.
+// Such functions cannot be called directly but require a
+// value created by MakeClosure which, via its Bindings, supplies
+// values for these parameters.
+//
+// If the function is a method (Signature.Recv() != nil) then the first
+// element of Params is the receiver parameter.
+//
+// A Go package may declare many functions called "init".
+// For each one, Object().Name() returns "init" but Name() returns
+// "init#1", etc, in declaration order.
+//
+// Pos() returns the declaring ast.FuncLit.Type.Func or the position
+// of the ast.FuncDecl.Name, if the function was explicit in the
+// source. Synthetic wrappers, for which Synthetic != "", may share
+// the same position as the function they wrap.
+// Syntax.Pos() always returns the position of the declaring "func" token.
+//
+// Type() returns the function's Signature.
+//
+type Function struct {
+ name string
+ object types.Object // a declared *types.Func or one of its wrappers
+ method *types.Selection // info about provenance of synthetic methods
+ Signature *types.Signature
+ pos token.Pos
+
+ Synthetic string // provenance of synthetic function; "" for true source functions
+ syntax ast.Node // *ast.Func{Decl,Lit}; replaced with simple ast.Node after build, unless debug mode
+ parent *Function // enclosing function if anon; nil if global
+ Pkg *Package // enclosing package; nil for shared funcs (wrappers and error.Error)
+ Prog *Program // enclosing program
+ Params []*Parameter // function parameters; for methods, includes receiver
+ FreeVars []*FreeVar // free variables whose values must be supplied by closure
+ Locals []*Alloc // local variables of this function
+ Blocks []*BasicBlock // basic blocks of the function; nil => external
+ Recover *BasicBlock // optional; control transfers here after recovered panic
+ AnonFuncs []*Function // anonymous functions directly beneath this one
+ referrers []Instruction // referring instructions (iff Parent() != nil)
+
+ // The following fields are set transiently during building,
+ // then cleared.
+ currentBlock *BasicBlock // where to emit code
+ objects map[types.Object]Value // addresses of local variables
+ namedResults []*Alloc // tuple of named results
+ targets *targets // linked stack of branch targets
+ lblocks map[*ast.Object]*lblock // labelled blocks
+}
+
+// BasicBlock represents an SSA basic block.
+//
+// The final element of Instrs is always an explicit transfer of
+// control (If, Jump, Return, or Panic).
+//
+// A block may contain no Instructions only if it is unreachable,
+// i.e., Preds is nil. Empty blocks are typically pruned.
+//
+// BasicBlocks and their Preds/Succs relation form a (possibly cyclic)
+// graph independent of the SSA Value graph: the control-flow graph or
+// CFG. It is illegal for multiple edges to exist between the same
+// pair of blocks.
+//
+// Each BasicBlock is also a node in the dominator tree of the CFG.
+// The tree may be navigated using Idom()/Dominees() and queried using
+// Dominates().
+//
+// The order of Preds and Succs is significant (to Phi and If
+// instructions, respectively).
+//
+type BasicBlock struct {
+ Index int // index of this block within Parent().Blocks
+ Comment string // optional label; no semantic significance
+ parent *Function // parent function
+ Instrs []Instruction // instructions in order
+ Preds, Succs []*BasicBlock // predecessors and successors
+ succs2 [2]*BasicBlock // initial space for Succs
+ dom domInfo // dominator tree info
+ gaps int // number of nil Instrs (transient)
+ rundefers int // number of rundefers (transient)
+}
+
+// Pure values ----------------------------------------
+
+// A FreeVar represents a free variable of the function to which it
+// belongs.
+//
+// FreeVars are used to implement anonymous functions, whose free
+// variables are lexically captured in a closure formed by
+// MakeClosure. The value of such a free var is an Alloc or another
+// FreeVar and is considered a potentially escaping heap address, with
+// pointer type.
+//
+// FreeVars are also used to implement bound method closures. Such a
+// free var represents the receiver value and may be of any type that
+// has concrete methods.
+//
+// Pos() returns the position of the value that was captured, which
+// belongs to an enclosing function.
+//
+type FreeVar struct {
+ name string
+ typ types.Type
+ pos token.Pos
+ parent *Function
+ referrers []Instruction
+
+ // Transiently needed during building.
+ outer Value // the Value captured from the enclosing context.
+}
+
+// A Parameter represents an input parameter of a function.
+//
+type Parameter struct {
+ name string
+ object types.Object // a *types.Var; nil for non-source locals
+ typ types.Type
+ pos token.Pos
+ parent *Function
+ referrers []Instruction
+}
+
+// A Const represents the value of a constant expression.
+//
+// The underlying type of a constant may be any boolean, numeric, or
+// string type. In addition, a Const may represent the nil value of
+// any reference type---interface, map, channel, pointer, slice, or
+// function---but not "untyped nil".
+//
+// All source-level constant expressions are represented by a Const
+// of the same type and value.
+//
+// Value holds the exact value of the constant, independent of its
+// Type(), using the same representation as package go/exact uses for
+// constants, or nil for a typed nil value.
+//
+// Pos() returns token.NoPos.
+//
+// Example printed form:
+// 42:int
+// "hello":untyped string
+// 3+4i:MyComplex
+//
+type Const struct {
+ typ types.Type
+ Value exact.Value
+}
+
+// A Global is a named Value holding the address of a package-level
+// variable.
+//
+// Pos() returns the position of the ast.ValueSpec.Names[*]
+// identifier.
+//
+type Global struct {
+ name string
+ object types.Object // a *types.Var; may be nil for synthetics e.g. init$guard
+ typ types.Type
+ pos token.Pos
+
+ Pkg *Package
+}
+
+// A Builtin represents a specific use of a built-in function, e.g. len.
+//
+// Builtins are immutable values. Builtins do not have addresses.
+// Builtins can only appear in CallCommon.Func.
+//
+// Name() indicates the function: one of the built-in functions from the
+// Go spec (excluding "make" and "new") or one of these ssa-defined
+// intrinsics:
+//
+// // wrapnilchk returns ptr if non-nil, panics otherwise.
+// // (For use in indirection wrappers.)
+// func ssa:wrapnilchk(ptr *T, recvType, methodName string) *T
+//
+// Object() returns a *types.Builtin for built-ins defined by the spec,
+// nil for others.
+//
+// Type() returns a *types.Signature representing the effective
+// signature of the built-in for this call.
+//
+type Builtin struct {
+ name string
+ sig *types.Signature
+}
+
+// Value-defining instructions ----------------------------------------
+
+// The Alloc instruction reserves space for a variable of the given type,
+// zero-initializes it, and yields its address.
+//
+// Alloc values are always addresses, and have pointer types, so the
+// type of the allocated variable is actually
+// Type().Underlying().(*types.Pointer).Elem().
+//
+// If Heap is false, Alloc allocates space in the function's
+// activation record (frame); we refer to an Alloc(Heap=false) as a
+// "local" alloc. Each local Alloc returns the same address each time
+// it is executed within the same activation; the space is
+// re-initialized to zero.
+//
+// If Heap is true, Alloc allocates space in the heap; we
+// refer to an Alloc(Heap=true) as a "new" alloc. Each new Alloc
+// returns a different address each time it is executed.
+//
+// When Alloc is applied to a channel, map or slice type, it returns
+// the address of an uninitialized (nil) reference of that kind; store
+// the result of MakeSlice, MakeMap or MakeChan in that location to
+// instantiate these types.
+//
+// Pos() returns the ast.CompositeLit.Lbrace for a composite literal,
+// or the ast.CallExpr.Rparen for a call to new() or for a call that
+// allocates a varargs slice.
+//
+// Example printed form:
+// t0 = local int
+// t1 = new int
+//
+type Alloc struct {
+ register
+ Comment string
+ Heap bool
+ index int // dense numbering; for lifting
+}
+
+// The Phi instruction represents an SSA φ-node, which combines values
+// that differ across incoming control-flow edges and yields a new
+// value. Within a block, all φ-nodes must appear before all non-φ
+// nodes.
+//
+// Pos() returns the position of the && or || for short-circuit
+// control-flow joins, or that of the *Alloc for φ-nodes inserted
+// during SSA renaming.
+//
+// Example printed form:
+// t2 = phi [0: t0, 1: t1]
+//
+type Phi struct {
+ register
+ Comment string // a hint as to its purpose
+ Edges []Value // Edges[i] is value for Block().Preds[i]
+}
+
+// The Call instruction represents a function or method call.
+//
+// The Call instruction yields the function result if there is exactly
+// one. Otherwise it returns a tuple, the components of which are
+// accessed via Extract.
+//
+// See CallCommon for generic function call documentation.
+//
+// Pos() returns the ast.CallExpr.Lparen, if explicit in the source.
+//
+// Example printed form:
+// t2 = println(t0, t1)
+// t4 = t3()
+// t7 = invoke t5.Println(...t6)
+//
+type Call struct {
+ register
+ Call CallCommon
+}
+
+// The BinOp instruction yields the result of binary operation X Op Y.
+//
+// Pos() returns the ast.BinaryExpr.OpPos, if explicit in the source.
+//
+// Example printed form:
+// t1 = t0 + 1:int
+//
+type BinOp struct {
+ register
+ // One of:
+ // ADD SUB MUL QUO REM + - * / %
+ // AND OR XOR SHL SHR AND_NOT & | ^ << >> &~
+ // EQL LSS GTR NEQ LEQ GEQ == != < <= < >=
+ Op token.Token
+ X, Y Value
+}
+
+// The UnOp instruction yields the result of Op X.
+// ARROW is channel receive.
+// MUL is pointer indirection (load).
+// XOR is bitwise complement.
+// SUB is negation.
+// NOT is logical negation.
+//
+// If CommaOk and Op=ARROW, the result is a 2-tuple of the value above
+// and a boolean indicating the success of the receive. The
+// components of the tuple are accessed using Extract.
+//
+// Pos() returns the ast.UnaryExpr.OpPos, if explicit in the source.
+// For receive operations (ARROW) implicit in ranging over a channel,
+// Pos() returns the ast.RangeStmt.For.
+// For implicit memory loads (STAR), Pos() returns the position of the
+// most closely associated source-level construct; the details are not
+// specified.
+//
+// Example printed form:
+// t0 = *x
+// t2 = <-t1,ok
+//
+type UnOp struct {
+ register
+ Op token.Token // One of: NOT SUB ARROW MUL XOR ! - <- * ^
+ X Value
+ CommaOk bool
+}
+
+// The ChangeType instruction applies to X a value-preserving type
+// change to Type().
+//
+// Type changes are permitted:
+// - between a named type and its underlying type.
+// - between two named types of the same underlying type.
+// - between (possibly named) pointers to identical base types.
+// - from a bidirectional channel to a read- or write-channel,
+// optionally adding/removing a name.
+//
+// This operation cannot fail dynamically.
+//
+// Pos() returns the ast.CallExpr.Lparen, if the instruction arose
+// from an explicit conversion in the source.
+//
+// Example printed form:
+// t1 = changetype *int <- IntPtr (t0)
+//
+type ChangeType struct {
+ register
+ X Value
+}
+
+// The Convert instruction yields the conversion of value X to type
+// Type(). One or both of those types is basic (but possibly named).
+//
+// A conversion may change the value and representation of its operand.
+// Conversions are permitted:
+// - between real numeric types.
+// - between complex numeric types.
+// - between string and []byte or []rune.
+// - between pointers and unsafe.Pointer.
+// - between unsafe.Pointer and uintptr.
+// - from (Unicode) integer to (UTF-8) string.
+// A conversion may imply a type name change also.
+//
+// This operation cannot fail dynamically.
+//
+// Conversions of untyped string/number/bool constants to a specific
+// representation are eliminated during SSA construction.
+//
+// Pos() returns the ast.CallExpr.Lparen, if the instruction arose
+// from an explicit conversion in the source.
+//
+// Example printed form:
+// t1 = convert []byte <- string (t0)
+//
+type Convert struct {
+ register
+ X Value
+}
+
+// ChangeInterface constructs a value of one interface type from a
+// value of another interface type known to be assignable to it.
+// This operation cannot fail.
+//
+// Pos() returns the ast.CallExpr.Lparen if the instruction arose from
+// an explicit T(e) conversion; the ast.TypeAssertExpr.Lparen if the
+// instruction arose from an explicit e.(T) operation; or token.NoPos
+// otherwise.
+//
+// Example printed form:
+// t1 = change interface interface{} <- I (t0)
+//
+type ChangeInterface struct {
+ register
+ X Value
+}
+
+// MakeInterface constructs an instance of an interface type from a
+// value of a concrete type.
+//
+// Use Program.MethodSets.MethodSet(X.Type()) to find the method-set
+// of X, and Program.Method(m) to find the implementation of a method.
+//
+// To construct the zero value of an interface type T, use:
+// NewConst(exact.MakeNil(), T, pos)
+//
+// Pos() returns the ast.CallExpr.Lparen, if the instruction arose
+// from an explicit conversion in the source.
+//
+// Example printed form:
+// t1 = make interface{} <- int (42:int)
+// t2 = make Stringer <- t0
+//
+type MakeInterface struct {
+ register
+ X Value
+}
+
+// The MakeClosure instruction yields a closure value whose code is
+// Fn and whose free variables' values are supplied by Bindings.
+//
+// Type() returns a (possibly named) *types.Signature.
+//
+// Pos() returns the ast.FuncLit.Type.Func for a function literal
+// closure or the ast.SelectorExpr.Sel for a bound method closure.
+//
+// Example printed form:
+// t0 = make closure anon@1.2 [x y z]
+// t1 = make closure bound$(main.I).add [i]
+//
+type MakeClosure struct {
+ register
+ Fn Value // always a *Function
+ Bindings []Value // values for each free variable in Fn.FreeVars
+}
+
+// The MakeMap instruction creates a new hash-table-based map object
+// and yields a value of kind map.
+//
+// Type() returns a (possibly named) *types.Map.
+//
+// Pos() returns the ast.CallExpr.Lparen, if created by make(map), or
+// the ast.CompositeLit.Lbrack if created by a literal.
+//
+// Example printed form:
+// t1 = make map[string]int t0
+// t1 = make StringIntMap t0
+//
+type MakeMap struct {
+ register
+ Reserve Value // initial space reservation; nil => default
+}
+
+// The MakeChan instruction creates a new channel object and yields a
+// value of kind chan.
+//
+// Type() returns a (possibly named) *types.Chan.
+//
+// Pos() returns the ast.CallExpr.Lparen for the make(chan) that
+// created it.
+//
+// Example printed form:
+// t0 = make chan int 0
+// t0 = make IntChan 0
+//
+type MakeChan struct {
+ register
+ Size Value // int; size of buffer; zero => synchronous.
+}
+
+// The MakeSlice instruction yields a slice of length Len backed by a
+// newly allocated array of length Cap.
+//
+// Both Len and Cap must be non-nil Values of integer type.
+//
+// (Alloc(types.Array) followed by Slice will not suffice because
+// Alloc can only create arrays of constant length.)
+//
+// Type() returns a (possibly named) *types.Slice.
+//
+// Pos() returns the ast.CallExpr.Lparen for the make([]T) that
+// created it.
+//
+// Example printed form:
+// t1 = make []string 1:int t0
+// t1 = make StringSlice 1:int t0
+//
+type MakeSlice struct {
+ register
+ Len Value
+ Cap Value
+}
+
+// The Slice instruction yields a slice of an existing string, slice
+// or *array X between optional integer bounds Low and High.
+//
+// Dynamically, this instruction panics if X evaluates to a nil *array
+// pointer.
+//
+// Type() returns string if the type of X was string, otherwise a
+// *types.Slice with the same element type as X.
+//
+// Pos() returns the ast.SliceExpr.Lbrack if created by a x[:] slice
+// operation, the ast.CompositeLit.Lbrace if created by a literal, or
+// NoPos if not explicit in the source (e.g. a variadic argument slice).
+//
+// Example printed form:
+// t1 = slice t0[1:]
+//
+type Slice struct {
+ register
+ X Value // slice, string, or *array
+ Low, High, Max Value // each may be nil
+}
+
+// The FieldAddr instruction yields the address of Field of *struct X.
+//
+// The field is identified by its index within the field list of the
+// struct type of X.
+//
+// Dynamically, this instruction panics if X evaluates to a nil
+// pointer.
+//
+// Type() returns a (possibly named) *types.Pointer.
+//
+// Pos() returns the position of the ast.SelectorExpr.Sel for the
+// field, if explicit in the source.
+//
+// Example printed form:
+// t1 = &t0.name [#1]
+//
+type FieldAddr struct {
+ register
+ X Value // *struct
+ Field int // index into X.Type().Deref().(*types.Struct).Fields
+}
+
+// The Field instruction yields the Field of struct X.
+//
+// The field is identified by its index within the field list of the
+// struct type of X; by using numeric indices we avoid ambiguity of
+// package-local identifiers and permit compact representations.
+//
+// Pos() returns the position of the ast.SelectorExpr.Sel for the
+// field, if explicit in the source.
+//
+// Example printed form:
+// t1 = t0.name [#1]
+//
+type Field struct {
+ register
+ X Value // struct
+ Field int // index into X.Type().(*types.Struct).Fields
+}
+
+// The IndexAddr instruction yields the address of the element at
+// index Index of collection X. Index is an integer expression.
+//
+// The elements of maps and strings are not addressable; use Lookup or
+// MapUpdate instead.
+//
+// Dynamically, this instruction panics if X evaluates to a nil *array
+// pointer.
+//
+// Type() returns a (possibly named) *types.Pointer.
+//
+// Pos() returns the ast.IndexExpr.Lbrack for the index operation, if
+// explicit in the source.
+//
+// Example printed form:
+// t2 = &t0[t1]
+//
+type IndexAddr struct {
+ register
+ X Value // slice or *array,
+ Index Value // numeric index
+}
+
+// The Index instruction yields element Index of array X.
+//
+// Pos() returns the ast.IndexExpr.Lbrack for the index operation, if
+// explicit in the source.
+//
+// Example printed form:
+// t2 = t0[t1]
+//
+type Index struct {
+ register
+ X Value // array
+ Index Value // integer index
+}
+
+// The Lookup instruction yields element Index of collection X, a map
+// or string. Index is an integer expression if X is a string or the
+// appropriate key type if X is a map.
+//
+// If CommaOk, the result is a 2-tuple of the value above and a
+// boolean indicating the result of a map membership test for the key.
+// The components of the tuple are accessed using Extract.
+//
+// Pos() returns the ast.IndexExpr.Lbrack, if explicit in the source.
+//
+// Example printed form:
+// t2 = t0[t1]
+// t5 = t3[t4],ok
+//
+type Lookup struct {
+ register
+ X Value // string or map
+ Index Value // numeric or key-typed index
+ CommaOk bool // return a value,ok pair
+}
+
+// SelectState is a helper for Select.
+// It represents one goal state and its corresponding communication.
+//
+type SelectState struct {
+ Dir types.ChanDir // direction of case (SendOnly or RecvOnly)
+ Chan Value // channel to use (for send or receive)
+ Send Value // value to send (for send)
+ Pos token.Pos // position of token.ARROW
+ DebugNode ast.Node // ast.SendStmt or ast.UnaryExpr(<-) [debug mode]
+}
+
+// The Select instruction tests whether (or blocks until) one
+// of the specified sent or received states is entered.
+//
+// Let n be the number of States for which Dir==RECV and T_i (0<=i string iterator; false => map iterator.
+}
+
+// The TypeAssert instruction tests whether interface value X has type
+// AssertedType.
+//
+// If !CommaOk, on success it returns v, the result of the conversion
+// (defined below); on failure it panics.
+//
+// If CommaOk: on success it returns a pair (v, true) where v is the
+// result of the conversion; on failure it returns (z, false) where z
+// is AssertedType's zero value. The components of the pair must be
+// accessed using the Extract instruction.
+//
+// If AssertedType is a concrete type, TypeAssert checks whether the
+// dynamic type in interface X is equal to it, and if so, the result
+// of the conversion is a copy of the value in the interface.
+//
+// If AssertedType is an interface, TypeAssert checks whether the
+// dynamic type of the interface is assignable to it, and if so, the
+// result of the conversion is a copy of the interface value X.
+// If AssertedType is a superinterface of X.Type(), the operation will
+// fail iff the operand is nil. (Contrast with ChangeInterface, which
+// performs no nil-check.)
+//
+// Type() reflects the actual type of the result, possibly a
+// 2-types.Tuple; AssertedType is the asserted type.
+//
+// Pos() returns the ast.CallExpr.Lparen if the instruction arose from
+// an explicit T(e) conversion; the ast.TypeAssertExpr.Lparen if the
+// instruction arose from an explicit e.(T) operation; or the
+// ast.CaseClause.Case if the instruction arose from a case of a
+// type-switch statement.
+//
+// Example printed form:
+// t1 = typeassert t0.(int)
+// t3 = typeassert,ok t2.(T)
+//
+type TypeAssert struct {
+ register
+ X Value
+ AssertedType types.Type
+ CommaOk bool
+}
+
+// The Extract instruction yields component Index of Tuple.
+//
+// This is used to access the results of instructions with multiple
+// return values, such as Call, TypeAssert, Next, UnOp(ARROW) and
+// IndexExpr(Map).
+//
+// Example printed form:
+// t1 = extract t0 #1
+//
+type Extract struct {
+ register
+ Tuple Value
+ Index int
+}
+
+// Instructions executed for effect. They do not yield a value. --------------------
+
+// The Jump instruction transfers control to the sole successor of its
+// owning block.
+//
+// A Jump must be the last instruction of its containing BasicBlock.
+//
+// Pos() returns NoPos.
+//
+// Example printed form:
+// jump done
+//
+type Jump struct {
+ anInstruction
+}
+
+// The If instruction transfers control to one of the two successors
+// of its owning block, depending on the boolean Cond: the first if
+// true, the second if false.
+//
+// An If instruction must be the last instruction of its containing
+// BasicBlock.
+//
+// Pos() returns NoPos.
+//
+// Example printed form:
+// if t0 goto done else body
+//
+type If struct {
+ anInstruction
+ Cond Value
+}
+
+// The Return instruction returns values and control back to the calling
+// function.
+//
+// len(Results) is always equal to the number of results in the
+// function's signature.
+//
+// If len(Results) > 1, Return returns a tuple value with the specified
+// components which the caller must access using Extract instructions.
+//
+// There is no instruction to return a ready-made tuple like those
+// returned by a "value,ok"-mode TypeAssert, Lookup or UnOp(ARROW) or
+// a tail-call to a function with multiple result parameters.
+//
+// Return must be the last instruction of its containing BasicBlock.
+// Such a block has no successors.
+//
+// Pos() returns the ast.ReturnStmt.Return, if explicit in the source.
+//
+// Example printed form:
+// return
+// return nil:I, 2:int
+//
+type Return struct {
+ anInstruction
+ Results []Value
+ pos token.Pos
+}
+
+// The RunDefers instruction pops and invokes the entire stack of
+// procedure calls pushed by Defer instructions in this function.
+//
+// It is legal to encounter multiple 'rundefers' instructions in a
+// single control-flow path through a function; this is useful in
+// the combined init() function, for example.
+//
+// Pos() returns NoPos.
+//
+// Example printed form:
+// rundefers
+//
+type RunDefers struct {
+ anInstruction
+}
+
+// The Panic instruction initiates a panic with value X.
+//
+// A Panic instruction must be the last instruction of its containing
+// BasicBlock, which must have no successors.
+//
+// NB: 'go panic(x)' and 'defer panic(x)' do not use this instruction;
+// they are treated as calls to a built-in function.
+//
+// Pos() returns the ast.CallExpr.Lparen if this panic was explicit
+// in the source.
+//
+// Example printed form:
+// panic t0
+//
+type Panic struct {
+ anInstruction
+ X Value // an interface{}
+ pos token.Pos
+}
+
+// The Go instruction creates a new goroutine and calls the specified
+// function within it.
+//
+// See CallCommon for generic function call documentation.
+//
+// Pos() returns the ast.GoStmt.Go.
+//
+// Example printed form:
+// go println(t0, t1)
+// go t3()
+// go invoke t5.Println(...t6)
+//
+type Go struct {
+ anInstruction
+ Call CallCommon
+ pos token.Pos
+}
+
+// The Defer instruction pushes the specified call onto a stack of
+// functions to be called by a RunDefers instruction or by a panic.
+//
+// See CallCommon for generic function call documentation.
+//
+// Pos() returns the ast.DeferStmt.Defer.
+//
+// Example printed form:
+// defer println(t0, t1)
+// defer t3()
+// defer invoke t5.Println(...t6)
+//
+type Defer struct {
+ anInstruction
+ Call CallCommon
+ pos token.Pos
+}
+
+// The Send instruction sends X on channel Chan.
+//
+// Pos() returns the ast.SendStmt.Arrow, if explicit in the source.
+//
+// Example printed form:
+// send t0 <- t1
+//
+type Send struct {
+ anInstruction
+ Chan, X Value
+ pos token.Pos
+}
+
+// The Store instruction stores Val at address Addr.
+// Stores can be of arbitrary types.
+//
+// Pos() returns the position of the source-level construct most closely
+// associated with the memory store operation.
+// Since implicit memory stores are numerous and varied and depend upon
+// implementation choices, the details are not specified.
+//
+// Example printed form:
+// *x = y
+//
+type Store struct {
+ anInstruction
+ Addr Value
+ Val Value
+ pos token.Pos
+}
+
+// The MapUpdate instruction updates the association of Map[Key] to
+// Value.
+//
+// Pos() returns the ast.KeyValueExpr.Colon or ast.IndexExpr.Lbrack,
+// if explicit in the source.
+//
+// Example printed form:
+// t0[t1] = t2
+//
+type MapUpdate struct {
+ anInstruction
+ Map Value
+ Key Value
+ Value Value
+ pos token.Pos
+}
+
+// A DebugRef instruction maps a source-level expression Expr to the
+// SSA value X that represents the value (!IsAddr) or address (IsAddr)
+// of that expression.
+//
+// DebugRef is a pseudo-instruction: it has no dynamic effect.
+//
+// Pos() returns Expr.Pos(), the start position of the source-level
+// expression. This is not the same as the "designated" token as
+// documented at Value.Pos(). e.g. CallExpr.Pos() does not return the
+// position of the ("designated") Lparen token.
+//
+// If Expr is an *ast.Ident denoting a var or func, Object() returns
+// the object; though this information can be obtained from the type
+// checker, including it here greatly facilitates debugging.
+// For non-Ident expressions, Object() returns nil.
+//
+// DebugRefs are generated only for functions built with debugging
+// enabled; see Package.SetDebugMode() and the GlobalDebug builder
+// mode flag.
+//
+// DebugRefs are not emitted for ast.Idents referring to constants or
+// predeclared identifiers, since they are trivial and numerous.
+// Nor are they emitted for ast.ParenExprs.
+//
+// (By representing these as instructions, rather than out-of-band,
+// consistency is maintained during transformation passes by the
+// ordinary SSA renaming machinery.)
+//
+// Example printed form:
+// ; *ast.CallExpr @ 102:9 is t5
+// ; var x float64 @ 109:72 is x
+// ; address of *ast.CompositeLit @ 216:10 is t0
+//
+type DebugRef struct {
+ anInstruction
+ Expr ast.Expr // the referring expression (never *ast.ParenExpr)
+ object types.Object // the identity of the source var/func
+ IsAddr bool // Expr is addressable and X is the address it denotes
+ X Value // the value or address of Expr
+}
+
+// Embeddable mix-ins and helpers for common parts of other structs. -----------
+
+// register is a mix-in embedded by all SSA values that are also
+// instructions, i.e. virtual registers, and provides a uniform
+// implementation of most of the Value interface: Value.Name() is a
+// numbered register (e.g. "t0"); the other methods are field accessors.
+//
+// Temporary names are automatically assigned to each register on
+// completion of building a function in SSA form.
+//
+// Clients must not assume that the 'id' value (and the Name() derived
+// from it) is unique within a function. As always in this API,
+// semantics are determined only by identity; names exist only to
+// facilitate debugging.
+//
+type register struct {
+ anInstruction
+ num int // "name" of virtual register, e.g. "t0". Not guaranteed unique.
+ typ types.Type // type of virtual register
+ pos token.Pos // position of source expression, or NoPos
+ referrers []Instruction
+}
+
+// anInstruction is a mix-in embedded by all Instructions.
+// It provides the implementations of the Block and setBlock methods.
+type anInstruction struct {
+ block *BasicBlock // the basic block of this instruction
+}
+
+// CallCommon is contained by Go, Defer and Call to hold the
+// common parts of a function or method call.
+//
+// Each CallCommon exists in one of two modes, function call and
+// interface method invocation, or "call" and "invoke" for short.
+//
+// 1. "call" mode: when Method is nil (!IsInvoke), a CallCommon
+// represents an ordinary function call of the value in Value,
+// which may be a *Builtin, a *Function or any other value of kind
+// 'func'.
+//
+// Value may be one of:
+// (a) a *Function, indicating a statically dispatched call
+// to a package-level function, an anonymous function, or
+// a method of a named type.
+// (b) a *MakeClosure, indicating an immediately applied
+// function literal with free variables.
+// (c) a *Builtin, indicating a statically dispatched call
+// to a built-in function.
+// (d) any other value, indicating a dynamically dispatched
+// function call.
+// StaticCallee returns the identity of the callee in cases
+// (a) and (b), nil otherwise.
+//
+// Args contains the arguments to the call. If Value is a method,
+// Args[0] contains the receiver parameter.
+//
+// Example printed form:
+// t2 = println(t0, t1)
+// go t3()
+// defer t5(...t6)
+//
+// 2. "invoke" mode: when Method is non-nil (IsInvoke), a CallCommon
+// represents a dynamically dispatched call to an interface method.
+// In this mode, Value is the interface value and Method is the
+// interface's abstract method. Note: an abstract method may be
+// shared by multiple interfaces due to embedding; Value.Type()
+// provides the specific interface used for this call.
+//
+// Value is implicitly supplied to the concrete method implementation
+// as the receiver parameter; in other words, Args[0] holds not the
+// receiver but the first true argument.
+//
+// Example printed form:
+// t1 = invoke t0.String()
+// go invoke t3.Run(t2)
+// defer invoke t4.Handle(...t5)
+//
+// For all calls to variadic functions (Signature().Variadic()),
+// the last element of Args is a slice.
+//
+type CallCommon struct {
+ Value Value // receiver (invoke mode) or func value (call mode)
+ Method *types.Func // abstract method (invoke mode)
+ Args []Value // actual parameters (in static method call, includes receiver)
+ pos token.Pos // position of CallExpr.Lparen, iff explicit in source
+}
+
+// IsInvoke returns true if this call has "invoke" (not "call") mode.
+func (c *CallCommon) IsInvoke() bool {
+ return c.Method != nil
+}
+
+func (c *CallCommon) Pos() token.Pos { return c.pos }
+
+// Signature returns the signature of the called function.
+//
+// For an "invoke"-mode call, the signature of the interface method is
+// returned.
+//
+// In either "call" or "invoke" mode, if the callee is a method, its
+// receiver is represented by sig.Recv, not sig.Params().At(0).
+//
+func (c *CallCommon) Signature() *types.Signature {
+ if c.Method != nil {
+ return c.Method.Type().(*types.Signature)
+ }
+ return c.Value.Type().Underlying().(*types.Signature)
+}
+
+// StaticCallee returns the callee if this is a trivially static
+// "call"-mode call to a function.
+func (c *CallCommon) StaticCallee() *Function {
+ switch fn := c.Value.(type) {
+ case *Function:
+ return fn
+ case *MakeClosure:
+ return fn.Fn.(*Function)
+ }
+ return nil
+}
+
+// Description returns a description of the mode of this call suitable
+// for a user interface, e.g., "static method call".
+func (c *CallCommon) Description() string {
+ switch fn := c.Value.(type) {
+ case *Builtin:
+ return "built-in function call"
+ case *MakeClosure:
+ return "static function closure call"
+ case *Function:
+ if fn.Signature.Recv() != nil {
+ return "static method call"
+ }
+ return "static function call"
+ }
+ if c.IsInvoke() {
+ return "dynamic method call" // ("invoke" mode)
+ }
+ return "dynamic function call"
+}
+
+// The CallInstruction interface, implemented by *Go, *Defer and *Call,
+// exposes the common parts of function-calling instructions,
+// yet provides a way back to the Value defined by *Call alone.
+//
+type CallInstruction interface {
+ Instruction
+ Common() *CallCommon // returns the common parts of the call
+ Value() *Call // returns the result value of the call (*Call) or nil (*Go, *Defer)
+}
+
+func (s *Call) Common() *CallCommon { return &s.Call }
+func (s *Defer) Common() *CallCommon { return &s.Call }
+func (s *Go) Common() *CallCommon { return &s.Call }
+
+func (s *Call) Value() *Call { return s }
+func (s *Defer) Value() *Call { return nil }
+func (s *Go) Value() *Call { return nil }
+
+func (v *Builtin) Type() types.Type { return v.sig }
+func (v *Builtin) Name() string { return v.name }
+func (*Builtin) Referrers() *[]Instruction { return nil }
+func (v *Builtin) Pos() token.Pos { return token.NoPos }
+func (v *Builtin) Object() types.Object { return types.Universe.Lookup(v.name) }
+func (v *Builtin) Parent() *Function { return nil }
+
+func (v *FreeVar) Type() types.Type { return v.typ }
+func (v *FreeVar) Name() string { return v.name }
+func (v *FreeVar) Referrers() *[]Instruction { return &v.referrers }
+func (v *FreeVar) Pos() token.Pos { return v.pos }
+func (v *FreeVar) Parent() *Function { return v.parent }
+
+func (v *Global) Type() types.Type { return v.typ }
+func (v *Global) Name() string { return v.name }
+func (v *Global) Parent() *Function { return nil }
+func (v *Global) Pos() token.Pos { return v.pos }
+func (v *Global) Referrers() *[]Instruction { return nil }
+func (v *Global) Token() token.Token { return token.VAR }
+func (v *Global) Object() types.Object { return v.object }
+func (v *Global) String() string { return v.RelString(nil) }
+func (v *Global) Package() *Package { return v.Pkg }
+func (v *Global) RelString(from *types.Package) string { return relString(v, from) }
+
+func (v *Function) Name() string { return v.name }
+func (v *Function) Type() types.Type { return v.Signature }
+func (v *Function) Pos() token.Pos { return v.pos }
+func (v *Function) Token() token.Token { return token.FUNC }
+func (v *Function) Object() types.Object { return v.object }
+func (v *Function) String() string { return v.RelString(nil) }
+func (v *Function) Package() *Package { return v.Pkg }
+func (v *Function) Parent() *Function { return v.parent }
+func (v *Function) Referrers() *[]Instruction {
+ if v.parent != nil {
+ return &v.referrers
+ }
+ return nil
+}
+
+func (v *Parameter) Type() types.Type { return v.typ }
+func (v *Parameter) Name() string { return v.name }
+func (v *Parameter) Object() types.Object { return v.object }
+func (v *Parameter) Referrers() *[]Instruction { return &v.referrers }
+func (v *Parameter) Pos() token.Pos { return v.pos }
+func (v *Parameter) Parent() *Function { return v.parent }
+
+func (v *Alloc) Type() types.Type { return v.typ }
+func (v *Alloc) Referrers() *[]Instruction { return &v.referrers }
+func (v *Alloc) Pos() token.Pos { return v.pos }
+
+func (v *register) Type() types.Type { return v.typ }
+func (v *register) setType(typ types.Type) { v.typ = typ }
+func (v *register) Name() string { return fmt.Sprintf("t%d", v.num) }
+func (v *register) setNum(num int) { v.num = num }
+func (v *register) Referrers() *[]Instruction { return &v.referrers }
+func (v *register) Pos() token.Pos { return v.pos }
+func (v *register) setPos(pos token.Pos) { v.pos = pos }
+
+func (v *anInstruction) Parent() *Function { return v.block.parent }
+func (v *anInstruction) Block() *BasicBlock { return v.block }
+func (v *anInstruction) setBlock(block *BasicBlock) { v.block = block }
+func (v *anInstruction) Referrers() *[]Instruction { return nil }
+
+func (t *Type) Name() string { return t.object.Name() }
+func (t *Type) Pos() token.Pos { return t.object.Pos() }
+func (t *Type) Type() types.Type { return t.object.Type() }
+func (t *Type) Token() token.Token { return token.TYPE }
+func (t *Type) Object() types.Object { return t.object }
+func (t *Type) String() string { return t.RelString(nil) }
+func (t *Type) Package() *Package { return t.pkg }
+func (t *Type) RelString(from *types.Package) string { return relString(t, from) }
+
+func (c *NamedConst) Name() string { return c.object.Name() }
+func (c *NamedConst) Pos() token.Pos { return c.object.Pos() }
+func (c *NamedConst) String() string { return c.RelString(nil) }
+func (c *NamedConst) Type() types.Type { return c.object.Type() }
+func (c *NamedConst) Token() token.Token { return token.CONST }
+func (c *NamedConst) Object() types.Object { return c.object }
+func (c *NamedConst) Package() *Package { return c.pkg }
+func (c *NamedConst) RelString(from *types.Package) string { return relString(c, from) }
+
+// Func returns the package-level function of the specified name,
+// or nil if not found.
+//
+func (p *Package) Func(name string) (f *Function) {
+ f, _ = p.Members[name].(*Function)
+ return
+}
+
+// Var returns the package-level variable of the specified name,
+// or nil if not found.
+//
+func (p *Package) Var(name string) (g *Global) {
+ g, _ = p.Members[name].(*Global)
+ return
+}
+
+// Const returns the package-level constant of the specified name,
+// or nil if not found.
+//
+func (p *Package) Const(name string) (c *NamedConst) {
+ c, _ = p.Members[name].(*NamedConst)
+ return
+}
+
+// Type returns the package-level type of the specified name,
+// or nil if not found.
+//
+func (p *Package) Type(name string) (t *Type) {
+ t, _ = p.Members[name].(*Type)
+ return
+}
+
+func (v *Call) Pos() token.Pos { return v.Call.pos }
+func (s *Defer) Pos() token.Pos { return s.pos }
+func (s *Go) Pos() token.Pos { return s.pos }
+func (s *MapUpdate) Pos() token.Pos { return s.pos }
+func (s *Panic) Pos() token.Pos { return s.pos }
+func (s *Return) Pos() token.Pos { return s.pos }
+func (s *Send) Pos() token.Pos { return s.pos }
+func (s *Store) Pos() token.Pos { return s.pos }
+func (s *If) Pos() token.Pos { return token.NoPos }
+func (s *Jump) Pos() token.Pos { return token.NoPos }
+func (s *RunDefers) Pos() token.Pos { return token.NoPos }
+func (s *DebugRef) Pos() token.Pos { return s.Expr.Pos() }
+
+// Operands.
+
+func (v *Alloc) Operands(rands []*Value) []*Value {
+ return rands
+}
+
+func (v *BinOp) Operands(rands []*Value) []*Value {
+ return append(rands, &v.X, &v.Y)
+}
+
+func (c *CallCommon) Operands(rands []*Value) []*Value {
+ rands = append(rands, &c.Value)
+ for i := range c.Args {
+ rands = append(rands, &c.Args[i])
+ }
+ return rands
+}
+
+func (s *Go) Operands(rands []*Value) []*Value {
+ return s.Call.Operands(rands)
+}
+
+func (s *Call) Operands(rands []*Value) []*Value {
+ return s.Call.Operands(rands)
+}
+
+func (s *Defer) Operands(rands []*Value) []*Value {
+ return s.Call.Operands(rands)
+}
+
+func (v *ChangeInterface) Operands(rands []*Value) []*Value {
+ return append(rands, &v.X)
+}
+
+func (v *ChangeType) Operands(rands []*Value) []*Value {
+ return append(rands, &v.X)
+}
+
+func (v *Convert) Operands(rands []*Value) []*Value {
+ return append(rands, &v.X)
+}
+
+func (s *DebugRef) Operands(rands []*Value) []*Value {
+ return append(rands, &s.X)
+}
+
+func (v *Extract) Operands(rands []*Value) []*Value {
+ return append(rands, &v.Tuple)
+}
+
+func (v *Field) Operands(rands []*Value) []*Value {
+ return append(rands, &v.X)
+}
+
+func (v *FieldAddr) Operands(rands []*Value) []*Value {
+ return append(rands, &v.X)
+}
+
+func (s *If) Operands(rands []*Value) []*Value {
+ return append(rands, &s.Cond)
+}
+
+func (v *Index) Operands(rands []*Value) []*Value {
+ return append(rands, &v.X, &v.Index)
+}
+
+func (v *IndexAddr) Operands(rands []*Value) []*Value {
+ return append(rands, &v.X, &v.Index)
+}
+
+func (*Jump) Operands(rands []*Value) []*Value {
+ return rands
+}
+
+func (v *Lookup) Operands(rands []*Value) []*Value {
+ return append(rands, &v.X, &v.Index)
+}
+
+func (v *MakeChan) Operands(rands []*Value) []*Value {
+ return append(rands, &v.Size)
+}
+
+func (v *MakeClosure) Operands(rands []*Value) []*Value {
+ rands = append(rands, &v.Fn)
+ for i := range v.Bindings {
+ rands = append(rands, &v.Bindings[i])
+ }
+ return rands
+}
+
+func (v *MakeInterface) Operands(rands []*Value) []*Value {
+ return append(rands, &v.X)
+}
+
+func (v *MakeMap) Operands(rands []*Value) []*Value {
+ return append(rands, &v.Reserve)
+}
+
+func (v *MakeSlice) Operands(rands []*Value) []*Value {
+ return append(rands, &v.Len, &v.Cap)
+}
+
+func (v *MapUpdate) Operands(rands []*Value) []*Value {
+ return append(rands, &v.Map, &v.Key, &v.Value)
+}
+
+func (v *Next) Operands(rands []*Value) []*Value {
+ return append(rands, &v.Iter)
+}
+
+func (s *Panic) Operands(rands []*Value) []*Value {
+ return append(rands, &s.X)
+}
+
+func (v *Phi) Operands(rands []*Value) []*Value {
+ for i := range v.Edges {
+ rands = append(rands, &v.Edges[i])
+ }
+ return rands
+}
+
+func (v *Range) Operands(rands []*Value) []*Value {
+ return append(rands, &v.X)
+}
+
+func (s *Return) Operands(rands []*Value) []*Value {
+ for i := range s.Results {
+ rands = append(rands, &s.Results[i])
+ }
+ return rands
+}
+
+func (*RunDefers) Operands(rands []*Value) []*Value {
+ return rands
+}
+
+func (v *Select) Operands(rands []*Value) []*Value {
+ for i := range v.States {
+ rands = append(rands, &v.States[i].Chan, &v.States[i].Send)
+ }
+ return rands
+}
+
+func (s *Send) Operands(rands []*Value) []*Value {
+ return append(rands, &s.Chan, &s.X)
+}
+
+func (v *Slice) Operands(rands []*Value) []*Value {
+ return append(rands, &v.X, &v.Low, &v.High, &v.Max)
+}
+
+func (s *Store) Operands(rands []*Value) []*Value {
+ return append(rands, &s.Addr, &s.Val)
+}
+
+func (v *TypeAssert) Operands(rands []*Value) []*Value {
+ return append(rands, &v.X)
+}
+
+func (v *UnOp) Operands(rands []*Value) []*Value {
+ return append(rands, &v.X)
+}
+
+// Non-Instruction Values:
+func (v *Builtin) Operands(rands []*Value) []*Value { return rands }
+func (v *FreeVar) Operands(rands []*Value) []*Value { return rands }
+func (v *Const) Operands(rands []*Value) []*Value { return rands }
+func (v *Function) Operands(rands []*Value) []*Value { return rands }
+func (v *Global) Operands(rands []*Value) []*Value { return rands }
+func (v *Parameter) Operands(rands []*Value) []*Value { return rands }
diff --git a/vendor/golang.org/x/tools/go/ssa/ssautil/load.go b/vendor/golang.org/x/tools/go/ssa/ssautil/load.go
new file mode 100644
index 0000000..c2b8ce1
--- /dev/null
+++ b/vendor/golang.org/x/tools/go/ssa/ssautil/load.go
@@ -0,0 +1,95 @@
+// Copyright 2015 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package ssautil
+
+// This file defines utility functions for constructing programs in SSA form.
+
+import (
+ "go/ast"
+ "go/token"
+
+ "golang.org/x/tools/go/loader"
+ "golang.org/x/tools/go/ssa"
+ "golang.org/x/tools/go/types"
+)
+
+// CreateProgram returns a new program in SSA form, given a program
+// loaded from source. An SSA package is created for each transitively
+// error-free package of lprog.
+//
+// Code for bodies of functions is not built until BuildAll() is called
+// on the result.
+//
+// mode controls diagnostics and checking during SSA construction.
+//
+func CreateProgram(lprog *loader.Program, mode ssa.BuilderMode) *ssa.Program {
+ prog := ssa.NewProgram(lprog.Fset, mode)
+
+ for _, info := range lprog.AllPackages {
+ if info.TransitivelyErrorFree {
+ prog.CreatePackage(info.Pkg, info.Files, &info.Info, info.Importable)
+ }
+ }
+
+ return prog
+}
+
+// BuildPackage builds an SSA program with IR for a single package.
+//
+// It populates pkg by type-checking the specified file ASTs. All
+// dependencies are loaded using the importer specified by tc, which
+// typically loads compiler export data; SSA code cannot be built for
+// those packages. BuildPackage then constructs an ssa.Program with all
+// dependency packages created, and builds and returns the SSA package
+// corresponding to pkg.
+//
+// The caller must have set pkg.Path() to the import path.
+//
+// The operation fails if there were any type-checking or import errors.
+//
+// See ../ssa/example_test.go for an example.
+//
+func BuildPackage(tc *types.Config, fset *token.FileSet, pkg *types.Package, files []*ast.File, mode ssa.BuilderMode) (*ssa.Package, *types.Info, error) {
+ if fset == nil {
+ panic("no token.FileSet")
+ }
+ if pkg.Path() == "" {
+ panic("package has no import path")
+ }
+
+ info := &types.Info{
+ Types: make(map[ast.Expr]types.TypeAndValue),
+ Defs: make(map[*ast.Ident]types.Object),
+ Uses: make(map[*ast.Ident]types.Object),
+ Implicits: make(map[ast.Node]types.Object),
+ Scopes: make(map[ast.Node]*types.Scope),
+ Selections: make(map[*ast.SelectorExpr]*types.Selection),
+ }
+ if err := types.NewChecker(tc, fset, pkg, info).Files(files); err != nil {
+ return nil, nil, err
+ }
+
+ prog := ssa.NewProgram(fset, mode)
+
+ // Create SSA packages for all imports.
+ // Order is not significant.
+ created := make(map[*types.Package]bool)
+ var createAll func(pkgs []*types.Package)
+ createAll = func(pkgs []*types.Package) {
+ for _, p := range pkgs {
+ if !created[p] {
+ created[p] = true
+ prog.CreatePackage(p, nil, nil, true)
+ createAll(p.Imports())
+ }
+ }
+ }
+ createAll(pkg.Imports())
+
+ // Create and build the primary package.
+ ssapkg := prog.CreatePackage(pkg, files, info, false)
+ ssapkg.Build()
+ return ssapkg, info, nil
+}
diff --git a/vendor/golang.org/x/tools/go/ssa/ssautil/switch.go b/vendor/golang.org/x/tools/go/ssa/ssautil/switch.go
new file mode 100644
index 0000000..70fff9c
--- /dev/null
+++ b/vendor/golang.org/x/tools/go/ssa/ssautil/switch.go
@@ -0,0 +1,234 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package ssautil
+
+// This file implements discovery of switch and type-switch constructs
+// from low-level control flow.
+//
+// Many techniques exist for compiling a high-level switch with
+// constant cases to efficient machine code. The optimal choice will
+// depend on the data type, the specific case values, the code in the
+// body of each case, and the hardware.
+// Some examples:
+// - a lookup table (for a switch that maps constants to constants)
+// - a computed goto
+// - a binary tree
+// - a perfect hash
+// - a two-level switch (to partition constant strings by their first byte).
+
+import (
+ "bytes"
+ "fmt"
+ "go/token"
+
+ "golang.org/x/tools/go/ssa"
+ "golang.org/x/tools/go/types"
+)
+
+// A ConstCase represents a single constant comparison.
+// It is part of a Switch.
+type ConstCase struct {
+ Block *ssa.BasicBlock // block performing the comparison
+ Body *ssa.BasicBlock // body of the case
+ Value *ssa.Const // case comparand
+}
+
+// A TypeCase represents a single type assertion.
+// It is part of a Switch.
+type TypeCase struct {
+ Block *ssa.BasicBlock // block performing the type assert
+ Body *ssa.BasicBlock // body of the case
+ Type types.Type // case type
+ Binding ssa.Value // value bound by this case
+}
+
+// A Switch is a logical high-level control flow operation
+// (a multiway branch) discovered by analysis of a CFG containing
+// only if/else chains. It is not part of the ssa.Instruction set.
+//
+// One of ConstCases and TypeCases has length >= 2;
+// the other is nil.
+//
+// In a value switch, the list of cases may contain duplicate constants.
+// A type switch may contain duplicate types, or types assignable
+// to an interface type also in the list.
+// TODO(adonovan): eliminate such duplicates.
+//
+type Switch struct {
+ Start *ssa.BasicBlock // block containing start of if/else chain
+ X ssa.Value // the switch operand
+ ConstCases []ConstCase // ordered list of constant comparisons
+ TypeCases []TypeCase // ordered list of type assertions
+ Default *ssa.BasicBlock // successor if all comparisons fail
+}
+
+func (sw *Switch) String() string {
+ // We represent each block by the String() of its
+ // first Instruction, e.g. "print(42:int)".
+ var buf bytes.Buffer
+ if sw.ConstCases != nil {
+ fmt.Fprintf(&buf, "switch %s {\n", sw.X.Name())
+ for _, c := range sw.ConstCases {
+ fmt.Fprintf(&buf, "case %s: %s\n", c.Value, c.Body.Instrs[0])
+ }
+ } else {
+ fmt.Fprintf(&buf, "switch %s.(type) {\n", sw.X.Name())
+ for _, c := range sw.TypeCases {
+ fmt.Fprintf(&buf, "case %s %s: %s\n",
+ c.Binding.Name(), c.Type, c.Body.Instrs[0])
+ }
+ }
+ if sw.Default != nil {
+ fmt.Fprintf(&buf, "default: %s\n", sw.Default.Instrs[0])
+ }
+ fmt.Fprintf(&buf, "}")
+ return buf.String()
+}
+
+// Switches examines the control-flow graph of fn and returns the
+// set of inferred value and type switches. A value switch tests an
+// ssa.Value for equality against two or more compile-time constant
+// values. Switches involving link-time constants (addresses) are
+// ignored. A type switch type-asserts an ssa.Value against two or
+// more types.
+//
+// The switches are returned in dominance order.
+//
+// The resulting switches do not necessarily correspond to uses of the
+// 'switch' keyword in the source: for example, a single source-level
+// switch statement with non-constant cases may result in zero, one or
+// many Switches, one per plural sequence of constant cases.
+// Switches may even be inferred from if/else- or goto-based control flow.
+// (In general, the control flow constructs of the source program
+// cannot be faithfully reproduced from the SSA representation.)
+//
+func Switches(fn *ssa.Function) []Switch {
+ // Traverse the CFG in dominance order, so we don't
+ // enter an if/else-chain in the middle.
+ var switches []Switch
+ seen := make(map[*ssa.BasicBlock]bool) // TODO(adonovan): opt: use ssa.blockSet
+ for _, b := range fn.DomPreorder() {
+ if x, k := isComparisonBlock(b); x != nil {
+ // Block b starts a switch.
+ sw := Switch{Start: b, X: x}
+ valueSwitch(&sw, k, seen)
+ if len(sw.ConstCases) > 1 {
+ switches = append(switches, sw)
+ }
+ }
+
+ if y, x, T := isTypeAssertBlock(b); y != nil {
+ // Block b starts a type switch.
+ sw := Switch{Start: b, X: x}
+ typeSwitch(&sw, y, T, seen)
+ if len(sw.TypeCases) > 1 {
+ switches = append(switches, sw)
+ }
+ }
+ }
+ return switches
+}
+
+func valueSwitch(sw *Switch, k *ssa.Const, seen map[*ssa.BasicBlock]bool) {
+ b := sw.Start
+ x := sw.X
+ for x == sw.X {
+ if seen[b] {
+ break
+ }
+ seen[b] = true
+
+ sw.ConstCases = append(sw.ConstCases, ConstCase{
+ Block: b,
+ Body: b.Succs[0],
+ Value: k,
+ })
+ b = b.Succs[1]
+ if len(b.Instrs) > 2 {
+ // Block b contains not just 'if x == k',
+ // so it may have side effects that
+ // make it unsafe to elide.
+ break
+ }
+ if len(b.Preds) != 1 {
+ // Block b has multiple predecessors,
+ // so it cannot be treated as a case.
+ break
+ }
+ x, k = isComparisonBlock(b)
+ }
+ sw.Default = b
+}
+
+func typeSwitch(sw *Switch, y ssa.Value, T types.Type, seen map[*ssa.BasicBlock]bool) {
+ b := sw.Start
+ x := sw.X
+ for x == sw.X {
+ if seen[b] {
+ break
+ }
+ seen[b] = true
+
+ sw.TypeCases = append(sw.TypeCases, TypeCase{
+ Block: b,
+ Body: b.Succs[0],
+ Type: T,
+ Binding: y,
+ })
+ b = b.Succs[1]
+ if len(b.Instrs) > 4 {
+ // Block b contains not just
+ // {TypeAssert; Extract #0; Extract #1; If}
+ // so it may have side effects that
+ // make it unsafe to elide.
+ break
+ }
+ if len(b.Preds) != 1 {
+ // Block b has multiple predecessors,
+ // so it cannot be treated as a case.
+ break
+ }
+ y, x, T = isTypeAssertBlock(b)
+ }
+ sw.Default = b
+}
+
+// isComparisonBlock returns the operands (v, k) if a block ends with
+// a comparison v==k, where k is a compile-time constant.
+//
+func isComparisonBlock(b *ssa.BasicBlock) (v ssa.Value, k *ssa.Const) {
+ if n := len(b.Instrs); n >= 2 {
+ if i, ok := b.Instrs[n-1].(*ssa.If); ok {
+ if binop, ok := i.Cond.(*ssa.BinOp); ok && binop.Block() == b && binop.Op == token.EQL {
+ if k, ok := binop.Y.(*ssa.Const); ok {
+ return binop.X, k
+ }
+ if k, ok := binop.X.(*ssa.Const); ok {
+ return binop.Y, k
+ }
+ }
+ }
+ }
+ return
+}
+
+// isTypeAssertBlock returns the operands (y, x, T) if a block ends with
+// a type assertion "if y, ok := x.(T); ok {".
+//
+func isTypeAssertBlock(b *ssa.BasicBlock) (y, x ssa.Value, T types.Type) {
+ if n := len(b.Instrs); n >= 4 {
+ if i, ok := b.Instrs[n-1].(*ssa.If); ok {
+ if ext1, ok := i.Cond.(*ssa.Extract); ok && ext1.Block() == b && ext1.Index == 1 {
+ if ta, ok := ext1.Tuple.(*ssa.TypeAssert); ok && ta.Block() == b {
+ // hack: relies upon instruction ordering.
+ if ext0, ok := b.Instrs[n-3].(*ssa.Extract); ok {
+ return ext0, ta.X, ta.AssertedType
+ }
+ }
+ }
+ }
+ }
+ return
+}
diff --git a/vendor/golang.org/x/tools/go/ssa/ssautil/visit.go b/vendor/golang.org/x/tools/go/ssa/ssautil/visit.go
new file mode 100644
index 0000000..30843c3
--- /dev/null
+++ b/vendor/golang.org/x/tools/go/ssa/ssautil/visit.go
@@ -0,0 +1,66 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package ssautil // import "golang.org/x/tools/go/ssa/ssautil"
+
+import "golang.org/x/tools/go/ssa"
+
+// This file defines utilities for visiting the SSA representation of
+// a Program.
+//
+// TODO(adonovan): test coverage.
+
+// AllFunctions finds and returns the set of functions potentially
+// needed by program prog, as determined by a simple linker-style
+// reachability algorithm starting from the members and method-sets of
+// each package. The result may include anonymous functions and
+// synthetic wrappers.
+//
+// Precondition: all packages are built.
+//
+func AllFunctions(prog *ssa.Program) map[*ssa.Function]bool {
+ visit := visitor{
+ prog: prog,
+ seen: make(map[*ssa.Function]bool),
+ }
+ visit.program()
+ return visit.seen
+}
+
+type visitor struct {
+ prog *ssa.Program
+ seen map[*ssa.Function]bool
+}
+
+func (visit *visitor) program() {
+ for _, pkg := range visit.prog.AllPackages() {
+ for _, mem := range pkg.Members {
+ if fn, ok := mem.(*ssa.Function); ok {
+ visit.function(fn)
+ }
+ }
+ }
+ for _, T := range visit.prog.RuntimeTypes() {
+ mset := visit.prog.MethodSets.MethodSet(T)
+ for i, n := 0, mset.Len(); i < n; i++ {
+ visit.function(visit.prog.Method(mset.At(i)))
+ }
+ }
+}
+
+func (visit *visitor) function(fn *ssa.Function) {
+ if !visit.seen[fn] {
+ visit.seen[fn] = true
+ var buf [10]*ssa.Value // avoid alloc in common case
+ for _, b := range fn.Blocks {
+ for _, instr := range b.Instrs {
+ for _, op := range instr.Operands(buf[:0]) {
+ if fn, ok := (*op).(*ssa.Function); ok {
+ visit.function(fn)
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/vendor/golang.org/x/tools/go/ssa/testmain.go b/vendor/golang.org/x/tools/go/ssa/testmain.go
new file mode 100644
index 0000000..a7b1242
--- /dev/null
+++ b/vendor/golang.org/x/tools/go/ssa/testmain.go
@@ -0,0 +1,296 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package ssa
+
+// CreateTestMainPackage synthesizes a main package that runs all the
+// tests of the supplied packages.
+// It is closely coupled to $GOROOT/src/cmd/go/test.go and $GOROOT/src/testing.
+
+import (
+ "go/ast"
+ "go/token"
+ "os"
+ "sort"
+ "strings"
+
+ "golang.org/x/tools/go/exact"
+ "golang.org/x/tools/go/types"
+)
+
+// FindTests returns the list of packages that define at least one Test,
+// Example or Benchmark function (as defined by "go test"), and the
+// lists of all such functions.
+//
+func FindTests(pkgs []*Package) (testpkgs []*Package, tests, benchmarks, examples []*Function) {
+ if len(pkgs) == 0 {
+ return
+ }
+ prog := pkgs[0].Prog
+
+ // The first two of these may be nil: if the program doesn't import "testing",
+ // it can't contain any tests, but it may yet contain Examples.
+ var testSig *types.Signature // func(*testing.T)
+ var benchmarkSig *types.Signature // func(*testing.B)
+ var exampleSig = types.NewSignature(nil, nil, nil, false) // func()
+
+ // Obtain the types from the parameters of testing.Main().
+ if testingPkg := prog.ImportedPackage("testing"); testingPkg != nil {
+ params := testingPkg.Func("Main").Signature.Params()
+ testSig = funcField(params.At(1).Type())
+ benchmarkSig = funcField(params.At(2).Type())
+ }
+
+ seen := make(map[*Package]bool)
+ for _, pkg := range pkgs {
+ if pkg.Prog != prog {
+ panic("wrong Program")
+ }
+
+ // TODO(adonovan): use a stable order, e.g. lexical.
+ for _, mem := range pkg.Members {
+ if f, ok := mem.(*Function); ok &&
+ ast.IsExported(f.Name()) &&
+ strings.HasSuffix(prog.Fset.Position(f.Pos()).Filename, "_test.go") {
+
+ switch {
+ case testSig != nil && isTestSig(f, "Test", testSig):
+ tests = append(tests, f)
+ case benchmarkSig != nil && isTestSig(f, "Benchmark", benchmarkSig):
+ benchmarks = append(benchmarks, f)
+ case isTestSig(f, "Example", exampleSig):
+ examples = append(examples, f)
+ default:
+ continue
+ }
+
+ if !seen[pkg] {
+ seen[pkg] = true
+ testpkgs = append(testpkgs, pkg)
+ }
+ }
+ }
+ }
+ return
+}
+
+// Like isTest, but checks the signature too.
+func isTestSig(f *Function, prefix string, sig *types.Signature) bool {
+ return isTest(f.Name(), prefix) && types.Identical(f.Signature, sig)
+}
+
+// If non-nil, testMainStartBodyHook is called immediately after
+// startBody for main.init and main.main, making it easy for users to
+// add custom imports and initialization steps for proprietary build
+// systems that don't exactly follow 'go test' conventions.
+var testMainStartBodyHook func(*Function)
+
+// CreateTestMainPackage creates and returns a synthetic "main"
+// package that runs all the tests of the supplied packages, similar
+// to the one that would be created by the 'go test' tool.
+//
+// It returns nil if the program contains no tests.
+//
+func (prog *Program) CreateTestMainPackage(pkgs ...*Package) *Package {
+ pkgs, tests, benchmarks, examples := FindTests(pkgs)
+ if len(pkgs) == 0 {
+ return nil
+ }
+
+ testmain := &Package{
+ Prog: prog,
+ Members: make(map[string]Member),
+ values: make(map[types.Object]Value),
+ Object: types.NewPackage("test$main", "main"),
+ }
+
+ // Build package's init function.
+ init := &Function{
+ name: "init",
+ Signature: new(types.Signature),
+ Synthetic: "package initializer",
+ Pkg: testmain,
+ Prog: prog,
+ }
+ init.startBody()
+
+ if testMainStartBodyHook != nil {
+ testMainStartBodyHook(init)
+ }
+
+ // Initialize packages to test.
+ var pkgpaths []string
+ for _, pkg := range pkgs {
+ var v Call
+ v.Call.Value = pkg.init
+ v.setType(types.NewTuple())
+ init.emit(&v)
+
+ pkgpaths = append(pkgpaths, pkg.Object.Path())
+ }
+ sort.Strings(pkgpaths)
+ init.emit(new(Return))
+ init.finishBody()
+ testmain.init = init
+ testmain.Object.MarkComplete()
+ testmain.Members[init.name] = init
+
+ // For debugging convenience, define an unexported const
+ // that enumerates the packages.
+ packagesConst := types.NewConst(token.NoPos, testmain.Object, "packages", tString,
+ exact.MakeString(strings.Join(pkgpaths, " ")))
+ memberFromObject(testmain, packagesConst, nil)
+
+ // Create main *types.Func and *ssa.Function
+ mainFunc := types.NewFunc(token.NoPos, testmain.Object, "main", new(types.Signature))
+ memberFromObject(testmain, mainFunc, nil)
+ main := testmain.Func("main")
+ main.Synthetic = "test main function"
+
+ main.startBody()
+
+ if testMainStartBodyHook != nil {
+ testMainStartBodyHook(main)
+ }
+
+ if testingPkg := prog.ImportedPackage("testing"); testingPkg != nil {
+ testingMain := testingPkg.Func("Main")
+ testingMainParams := testingMain.Signature.Params()
+
+ // The generated code is as if compiled from this:
+ //
+ // func main() {
+ // match := func(_, _ string) (bool, error) { return true, nil }
+ // tests := []testing.InternalTest{{"TestFoo", TestFoo}, ...}
+ // benchmarks := []testing.InternalBenchmark{...}
+ // examples := []testing.InternalExample{...}
+ // testing.Main(match, tests, benchmarks, examples)
+ // }
+
+ matcher := &Function{
+ name: "matcher",
+ Signature: testingMainParams.At(0).Type().(*types.Signature),
+ Synthetic: "test matcher predicate",
+ parent: main,
+ Pkg: testmain,
+ Prog: prog,
+ }
+ main.AnonFuncs = append(main.AnonFuncs, matcher)
+ matcher.startBody()
+ matcher.emit(&Return{Results: []Value{vTrue, nilConst(types.Universe.Lookup("error").Type())}})
+ matcher.finishBody()
+
+ // Emit call: testing.Main(matcher, tests, benchmarks, examples).
+ var c Call
+ c.Call.Value = testingMain
+ c.Call.Args = []Value{
+ matcher,
+ testMainSlice(main, tests, testingMainParams.At(1).Type()),
+ testMainSlice(main, benchmarks, testingMainParams.At(2).Type()),
+ testMainSlice(main, examples, testingMainParams.At(3).Type()),
+ }
+ emitTailCall(main, &c)
+ } else {
+ // The program does not import "testing", but FindTests
+ // returned non-nil, which must mean there were Examples
+ // but no Tests or Benchmarks.
+ // We'll simply call them from testmain.main; this will
+ // ensure they don't panic, but will not check any
+ // "Output:" comments.
+ for _, eg := range examples {
+ var c Call
+ c.Call.Value = eg
+ c.setType(types.NewTuple())
+ main.emit(&c)
+ }
+ main.emit(&Return{})
+ main.currentBlock = nil
+ }
+
+ main.finishBody()
+
+ testmain.Members["main"] = main
+
+ if prog.mode&PrintPackages != 0 {
+ printMu.Lock()
+ testmain.WriteTo(os.Stdout)
+ printMu.Unlock()
+ }
+
+ if prog.mode&SanityCheckFunctions != 0 {
+ sanityCheckPackage(testmain)
+ }
+
+ prog.packages[testmain.Object] = testmain
+
+ return testmain
+}
+
+// testMainSlice emits to fn code to construct a slice of type slice
+// (one of []testing.Internal{Test,Benchmark,Example}) for all
+// functions in testfuncs. It returns the slice value.
+//
+func testMainSlice(fn *Function, testfuncs []*Function, slice types.Type) Value {
+ if testfuncs == nil {
+ return nilConst(slice)
+ }
+
+ tElem := slice.(*types.Slice).Elem()
+ tPtrString := types.NewPointer(tString)
+ tPtrElem := types.NewPointer(tElem)
+ tPtrFunc := types.NewPointer(funcField(slice))
+
+ // Emit: array = new [n]testing.InternalTest
+ tArray := types.NewArray(tElem, int64(len(testfuncs)))
+ array := emitNew(fn, tArray, token.NoPos)
+ array.Comment = "test main"
+ for i, testfunc := range testfuncs {
+ // Emit: pitem = &array[i]
+ ia := &IndexAddr{X: array, Index: intConst(int64(i))}
+ ia.setType(tPtrElem)
+ pitem := fn.emit(ia)
+
+ // Emit: pname = &pitem.Name
+ fa := &FieldAddr{X: pitem, Field: 0} // .Name
+ fa.setType(tPtrString)
+ pname := fn.emit(fa)
+
+ // Emit: *pname = "testfunc"
+ emitStore(fn, pname, stringConst(testfunc.Name()), token.NoPos)
+
+ // Emit: pfunc = &pitem.F
+ fa = &FieldAddr{X: pitem, Field: 1} // .F
+ fa.setType(tPtrFunc)
+ pfunc := fn.emit(fa)
+
+ // Emit: *pfunc = testfunc
+ emitStore(fn, pfunc, testfunc, token.NoPos)
+ }
+
+ // Emit: slice array[:]
+ sl := &Slice{X: array}
+ sl.setType(slice)
+ return fn.emit(sl)
+}
+
+// Given the type of one of the three slice parameters of testing.Main,
+// returns the function type.
+func funcField(slice types.Type) *types.Signature {
+ return slice.(*types.Slice).Elem().Underlying().(*types.Struct).Field(1).Type().(*types.Signature)
+}
+
+// Plundered from $GOROOT/src/cmd/go/test.go
+
+// isTest tells whether name looks like a test (or benchmark, according to prefix).
+// It is a Test (say) if there is a character after Test that is not a lower-case letter.
+// We don't want TesticularCancer.
+func isTest(name, prefix string) bool {
+ if !strings.HasPrefix(name, prefix) {
+ return false
+ }
+ if len(name) == len(prefix) { // "Test" is ok
+ return true
+ }
+ return ast.IsExported(name[len(prefix):])
+}
diff --git a/vendor/golang.org/x/tools/go/ssa/util.go b/vendor/golang.org/x/tools/go/ssa/util.go
new file mode 100644
index 0000000..4f9d43d
--- /dev/null
+++ b/vendor/golang.org/x/tools/go/ssa/util.go
@@ -0,0 +1,119 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package ssa
+
+// This file defines a number of miscellaneous utility functions.
+
+import (
+ "fmt"
+ "go/ast"
+ "go/token"
+ "io"
+ "os"
+
+ "golang.org/x/tools/go/ast/astutil"
+ "golang.org/x/tools/go/types"
+)
+
+//// AST utilities
+
+func unparen(e ast.Expr) ast.Expr { return astutil.Unparen(e) }
+
+// isBlankIdent returns true iff e is an Ident with name "_".
+// They have no associated types.Object, and thus no type.
+//
+func isBlankIdent(e ast.Expr) bool {
+ id, ok := e.(*ast.Ident)
+ return ok && id.Name == "_"
+}
+
+//// Type utilities. Some of these belong in go/types.
+
+// isPointer returns true for types whose underlying type is a pointer.
+func isPointer(typ types.Type) bool {
+ _, ok := typ.Underlying().(*types.Pointer)
+ return ok
+}
+
+func isInterface(T types.Type) bool { return types.IsInterface(T) }
+
+// deref returns a pointer's element type; otherwise it returns typ.
+func deref(typ types.Type) types.Type {
+ if p, ok := typ.Underlying().(*types.Pointer); ok {
+ return p.Elem()
+ }
+ return typ
+}
+
+// recvType returns the receiver type of method obj.
+func recvType(obj *types.Func) types.Type {
+ return obj.Type().(*types.Signature).Recv().Type()
+}
+
+// DefaultType returns the default "typed" type for an "untyped" type;
+// it returns the incoming type for all other types. The default type
+// for untyped nil is untyped nil.
+//
+// Exported to ssa/interp.
+//
+// TODO(gri): this is a copy of go/types.defaultType; export that function.
+//
+func DefaultType(typ types.Type) types.Type {
+ if t, ok := typ.(*types.Basic); ok {
+ k := t.Kind()
+ switch k {
+ case types.UntypedBool:
+ k = types.Bool
+ case types.UntypedInt:
+ k = types.Int
+ case types.UntypedRune:
+ k = types.Rune
+ case types.UntypedFloat:
+ k = types.Float64
+ case types.UntypedComplex:
+ k = types.Complex128
+ case types.UntypedString:
+ k = types.String
+ }
+ typ = types.Typ[k]
+ }
+ return typ
+}
+
+// logStack prints the formatted "start" message to stderr and
+// returns a closure that prints the corresponding "end" message.
+// Call using 'defer logStack(...)()' to show builder stack on panic.
+// Don't forget trailing parens!
+//
+func logStack(format string, args ...interface{}) func() {
+ msg := fmt.Sprintf(format, args...)
+ io.WriteString(os.Stderr, msg)
+ io.WriteString(os.Stderr, "\n")
+ return func() {
+ io.WriteString(os.Stderr, msg)
+ io.WriteString(os.Stderr, " end\n")
+ }
+}
+
+// newVar creates a 'var' for use in a types.Tuple.
+func newVar(name string, typ types.Type) *types.Var {
+ return types.NewParam(token.NoPos, nil, name, typ)
+}
+
+// anonVar creates an anonymous 'var' for use in a types.Tuple.
+func anonVar(typ types.Type) *types.Var {
+ return newVar("", typ)
+}
+
+var lenResults = types.NewTuple(anonVar(tInt))
+
+// makeLen returns the len builtin specialized to type func(T)int.
+func makeLen(T types.Type) *Builtin {
+ lenParams := types.NewTuple(anonVar(T))
+ return &Builtin{
+ name: "len",
+ sig: types.NewSignature(nil, lenParams, lenResults, false),
+ }
+}
diff --git a/vendor/golang.org/x/tools/go/ssa/wrappers.go b/vendor/golang.org/x/tools/go/ssa/wrappers.go
new file mode 100644
index 0000000..ff1eac5
--- /dev/null
+++ b/vendor/golang.org/x/tools/go/ssa/wrappers.go
@@ -0,0 +1,294 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package ssa
+
+// This file defines synthesis of Functions that delegate to declared
+// methods; they come in three kinds:
+//
+// (1) wrappers: methods that wrap declared methods, performing
+// implicit pointer indirections and embedded field selections.
+//
+// (2) thunks: funcs that wrap declared methods. Like wrappers,
+// thunks perform indirections and field selections. The thunk's
+// first parameter is used as the receiver for the method call.
+//
+// (3) bounds: funcs that wrap declared methods. The bound's sole
+// free variable, supplied by a closure, is used as the receiver
+// for the method call. No indirections or field selections are
+// performed since they can be done before the call.
+
+import (
+ "fmt"
+
+ "golang.org/x/tools/go/types"
+)
+
+// -- wrappers -----------------------------------------------------------
+
+// makeWrapper returns a synthetic method that delegates to the
+// declared method denoted by meth.Obj(), first performing any
+// necessary pointer indirections or field selections implied by meth.
+//
+// The resulting method's receiver type is meth.Recv().
+//
+// This function is versatile but quite subtle! Consider the
+// following axes of variation when making changes:
+// - optional receiver indirection
+// - optional implicit field selections
+// - meth.Obj() may denote a concrete or an interface method
+// - the result may be a thunk or a wrapper.
+//
+// EXCLUSIVE_LOCKS_REQUIRED(prog.methodsMu)
+//
+func makeWrapper(prog *Program, sel *types.Selection) *Function {
+ obj := sel.Obj().(*types.Func) // the declared function
+ sig := sel.Type().(*types.Signature) // type of this wrapper
+
+ var recv *types.Var // wrapper's receiver or thunk's params[0]
+ name := obj.Name()
+ var description string
+ var start int // first regular param
+ if sel.Kind() == types.MethodExpr {
+ name += "$thunk"
+ description = "thunk"
+ recv = sig.Params().At(0)
+ start = 1
+ } else {
+ description = "wrapper"
+ recv = sig.Recv()
+ }
+
+ description = fmt.Sprintf("%s for %s", description, sel.Obj())
+ if prog.mode&LogSource != 0 {
+ defer logStack("make %s to (%s)", description, recv.Type())()
+ }
+ fn := &Function{
+ name: name,
+ method: sel,
+ object: obj,
+ Signature: sig,
+ Synthetic: description,
+ Prog: prog,
+ pos: obj.Pos(),
+ }
+ fn.startBody()
+ fn.addSpilledParam(recv)
+ createParams(fn, start)
+
+ indices := sel.Index()
+
+ var v Value = fn.Locals[0] // spilled receiver
+ if isPointer(sel.Recv()) {
+ v = emitLoad(fn, v)
+
+ // For simple indirection wrappers, perform an informative nil-check:
+ // "value method (T).f called using nil *T pointer"
+ if len(indices) == 1 && !isPointer(recvType(obj)) {
+ var c Call
+ c.Call.Value = &Builtin{
+ name: "ssa:wrapnilchk",
+ sig: types.NewSignature(nil,
+ types.NewTuple(anonVar(sel.Recv()), anonVar(tString), anonVar(tString)),
+ types.NewTuple(anonVar(sel.Recv())), false),
+ }
+ c.Call.Args = []Value{
+ v,
+ stringConst(deref(sel.Recv()).String()),
+ stringConst(sel.Obj().Name()),
+ }
+ c.setType(v.Type())
+ v = fn.emit(&c)
+ }
+ }
+
+ // Invariant: v is a pointer, either
+ // value of *A receiver param, or
+ // address of A spilled receiver.
+
+ // We use pointer arithmetic (FieldAddr possibly followed by
+ // Load) in preference to value extraction (Field possibly
+ // preceded by Load).
+
+ v = emitImplicitSelections(fn, v, indices[:len(indices)-1])
+
+ // Invariant: v is a pointer, either
+ // value of implicit *C field, or
+ // address of implicit C field.
+
+ var c Call
+ if r := recvType(obj); !isInterface(r) { // concrete method
+ if !isPointer(r) {
+ v = emitLoad(fn, v)
+ }
+ c.Call.Value = prog.declaredFunc(obj)
+ c.Call.Args = append(c.Call.Args, v)
+ } else {
+ c.Call.Method = obj
+ c.Call.Value = emitLoad(fn, v)
+ }
+ for _, arg := range fn.Params[1:] {
+ c.Call.Args = append(c.Call.Args, arg)
+ }
+ emitTailCall(fn, &c)
+ fn.finishBody()
+ return fn
+}
+
+// createParams creates parameters for wrapper method fn based on its
+// Signature.Params, which do not include the receiver.
+// start is the index of the first regular parameter to use.
+//
+func createParams(fn *Function, start int) {
+ var last *Parameter
+ tparams := fn.Signature.Params()
+ for i, n := start, tparams.Len(); i < n; i++ {
+ last = fn.addParamObj(tparams.At(i))
+ }
+ if fn.Signature.Variadic() {
+ last.typ = types.NewSlice(last.typ)
+ }
+}
+
+// -- bounds -----------------------------------------------------------
+
+// makeBound returns a bound method wrapper (or "bound"), a synthetic
+// function that delegates to a concrete or interface method denoted
+// by obj. The resulting function has no receiver, but has one free
+// variable which will be used as the method's receiver in the
+// tail-call.
+//
+// Use MakeClosure with such a wrapper to construct a bound method
+// closure. e.g.:
+//
+// type T int or: type T interface { meth() }
+// func (t T) meth()
+// var t T
+// f := t.meth
+// f() // calls t.meth()
+//
+// f is a closure of a synthetic wrapper defined as if by:
+//
+// f := func() { return t.meth() }
+//
+// Unlike makeWrapper, makeBound need perform no indirection or field
+// selections because that can be done before the closure is
+// constructed.
+//
+// EXCLUSIVE_LOCKS_ACQUIRED(meth.Prog.methodsMu)
+//
+func makeBound(prog *Program, obj *types.Func) *Function {
+ prog.methodsMu.Lock()
+ defer prog.methodsMu.Unlock()
+ fn, ok := prog.bounds[obj]
+ if !ok {
+ description := fmt.Sprintf("bound method wrapper for %s", obj)
+ if prog.mode&LogSource != 0 {
+ defer logStack("%s", description)()
+ }
+ fn = &Function{
+ name: obj.Name() + "$bound",
+ object: obj,
+ Signature: changeRecv(obj.Type().(*types.Signature), nil), // drop receiver
+ Synthetic: description,
+ Prog: prog,
+ pos: obj.Pos(),
+ }
+
+ fv := &FreeVar{name: "recv", typ: recvType(obj), parent: fn}
+ fn.FreeVars = []*FreeVar{fv}
+ fn.startBody()
+ createParams(fn, 0)
+ var c Call
+
+ if !isInterface(recvType(obj)) { // concrete
+ c.Call.Value = prog.declaredFunc(obj)
+ c.Call.Args = []Value{fv}
+ } else {
+ c.Call.Value = fv
+ c.Call.Method = obj
+ }
+ for _, arg := range fn.Params {
+ c.Call.Args = append(c.Call.Args, arg)
+ }
+ emitTailCall(fn, &c)
+ fn.finishBody()
+
+ prog.bounds[obj] = fn
+ }
+ return fn
+}
+
+// -- thunks -----------------------------------------------------------
+
+// makeThunk returns a thunk, a synthetic function that delegates to a
+// concrete or interface method denoted by sel.Obj(). The resulting
+// function has no receiver, but has an additional (first) regular
+// parameter.
+//
+// Precondition: sel.Kind() == types.MethodExpr.
+//
+// type T int or: type T interface { meth() }
+// func (t T) meth()
+// f := T.meth
+// var t T
+// f(t) // calls t.meth()
+//
+// f is a synthetic wrapper defined as if by:
+//
+// f := func(t T) { return t.meth() }
+//
+// TODO(adonovan): opt: currently the stub is created even when used
+// directly in a function call: C.f(i, 0). This is less efficient
+// than inlining the stub.
+//
+// EXCLUSIVE_LOCKS_ACQUIRED(meth.Prog.methodsMu)
+//
+func makeThunk(prog *Program, sel *types.Selection) *Function {
+ if sel.Kind() != types.MethodExpr {
+ panic(sel)
+ }
+
+ key := selectionKey{
+ kind: sel.Kind(),
+ recv: sel.Recv(),
+ obj: sel.Obj(),
+ index: fmt.Sprint(sel.Index()),
+ indirect: sel.Indirect(),
+ }
+
+ prog.methodsMu.Lock()
+ defer prog.methodsMu.Unlock()
+
+ // Canonicalize key.recv to avoid constructing duplicate thunks.
+ canonRecv, ok := prog.canon.At(key.recv).(types.Type)
+ if !ok {
+ canonRecv = key.recv
+ prog.canon.Set(key.recv, canonRecv)
+ }
+ key.recv = canonRecv
+
+ fn, ok := prog.thunks[key]
+ if !ok {
+ fn = makeWrapper(prog, sel)
+ if fn.Signature.Recv() != nil {
+ panic(fn) // unexpected receiver
+ }
+ prog.thunks[key] = fn
+ }
+ return fn
+}
+
+func changeRecv(s *types.Signature, recv *types.Var) *types.Signature {
+ return types.NewSignature(recv, s.Params(), s.Results(), s.Variadic())
+}
+
+// selectionKey is like types.Selection but a usable map key.
+type selectionKey struct {
+ kind types.SelectionKind
+ recv types.Type // canonicalized via Program.canon
+ obj types.Object
+ index string
+ indirect bool
+}
diff --git a/vendor/golang.org/x/tools/go/types/api.go b/vendor/golang.org/x/tools/go/types/api.go
new file mode 100644
index 0000000..5344a39
--- /dev/null
+++ b/vendor/golang.org/x/tools/go/types/api.go
@@ -0,0 +1,365 @@
+// Copyright 2012 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package types declares the data types and implements
+// the algorithms for type-checking of Go packages.
+// Use Check and Config.Check to invoke the type-checker.
+//
+// Type-checking consists of several interdependent phases:
+//
+// Name resolution maps each identifier (ast.Ident) in the program to the
+// language object (Object) it denotes.
+// Use Info.{Defs,Uses,Implicits} for the results of name resolution.
+//
+// Constant folding computes the exact constant value (exact.Value) for
+// every expression (ast.Expr) that is a compile-time constant.
+// Use Info.Types[expr].Value for the results of constant folding.
+//
+// Type inference computes the type (Type) of every expression (ast.Expr)
+// and checks for compliance with the language specification.
+// Use Info.Types[expr].Type for the results of type inference.
+//
+package types // import "golang.org/x/tools/go/types"
+
+import (
+ "bytes"
+ "fmt"
+ "go/ast"
+ "go/token"
+
+ "golang.org/x/tools/go/exact"
+)
+
+// Check type-checks a package and returns the resulting complete package
+// object, or a nil package and the first error. The package is specified
+// by a list of *ast.Files and corresponding file set, and the import path
+// the package is identified with. The clean path must not be empty or dot (".").
+//
+// For more control over type-checking and results, use Config.Check.
+func Check(path string, fset *token.FileSet, files []*ast.File) (*Package, error) {
+ var conf Config
+ pkg, err := conf.Check(path, fset, files, nil)
+ if err != nil {
+ return nil, err
+ }
+ return pkg, nil
+}
+
+// An Error describes a type-checking error; it implements the error interface.
+// A "soft" error is an error that still permits a valid interpretation of a
+// package (such as "unused variable"); "hard" errors may lead to unpredictable
+// behavior if ignored.
+type Error struct {
+ Fset *token.FileSet // file set for interpretation of Pos
+ Pos token.Pos // error position
+ Msg string // error message
+ Soft bool // if set, error is "soft"
+}
+
+// Error returns an error string formatted as follows:
+// filename:line:column: message
+func (err Error) Error() string {
+ return fmt.Sprintf("%s: %s", err.Fset.Position(err.Pos), err.Msg)
+}
+
+// An importer resolves import paths to Packages.
+// The imports map records packages already known,
+// indexed by package path. The type-checker
+// will invoke Import with Config.Packages.
+// An importer must determine the canonical package path and
+// check imports to see if it is already present in the map.
+// If so, the Importer can return the map entry. Otherwise,
+// the importer must load the package data for the given path
+// into a new *Package, record it in imports map, and return
+// the package.
+// TODO(gri) Need to be clearer about requirements of completeness.
+type Importer func(map[string]*Package, string) (*Package, error)
+
+// A Config specifies the configuration for type checking.
+// The zero value for Config is a ready-to-use default configuration.
+type Config struct {
+ // If IgnoreFuncBodies is set, function bodies are not
+ // type-checked.
+ IgnoreFuncBodies bool
+
+ // If FakeImportC is set, `import "C"` (for packages requiring Cgo)
+ // declares an empty "C" package and errors are omitted for qualified
+ // identifiers referring to package C (which won't find an object).
+ // This feature is intended for the standard library cmd/api tool.
+ //
+ // Caution: Effects may be unpredictable due to follow-up errors.
+ // Do not use casually!
+ FakeImportC bool
+
+ // Packages is used to look up (and thus canonicalize) packages by
+ // package path. If Packages is nil, it is set to a new empty map.
+ // During type-checking, imported packages are added to the map.
+ Packages map[string]*Package
+
+ // If Error != nil, it is called with each error found
+ // during type checking; err has dynamic type Error.
+ // Secondary errors (for instance, to enumerate all types
+ // involved in an invalid recursive type declaration) have
+ // error strings that start with a '\t' character.
+ // If Error == nil, type-checking stops with the first
+ // error found.
+ Error func(err error)
+
+ // If Import != nil, it is called for each imported package.
+ // Otherwise, DefaultImport is called.
+ Import Importer
+
+ // If Sizes != nil, it provides the sizing functions for package unsafe.
+ // Otherwise &StdSizes{WordSize: 8, MaxAlign: 8} is used instead.
+ Sizes Sizes
+
+ // If DisableUnusedImportCheck is set, packages are not checked
+ // for unused imports.
+ DisableUnusedImportCheck bool
+}
+
+// DefaultImport is the default importer invoked if Config.Import == nil.
+// The declaration:
+//
+// import _ "golang.org/x/tools/go/gcimporter"
+//
+// in a client of go/types will initialize DefaultImport to gcimporter.Import.
+var DefaultImport Importer
+
+// Info holds result type information for a type-checked package.
+// Only the information for which a map is provided is collected.
+// If the package has type errors, the collected information may
+// be incomplete.
+type Info struct {
+ // Types maps expressions to their types, and for constant
+ // expressions, their values. Invalid expressions are omitted.
+ //
+ // For (possibly parenthesized) identifiers denoting built-in
+ // functions, the recorded signatures are call-site specific:
+ // if the call result is not a constant, the recorded type is
+ // an argument-specific signature. Otherwise, the recorded type
+ // is invalid.
+ //
+ // Identifiers on the lhs of declarations (i.e., the identifiers
+ // which are being declared) are collected in the Defs map.
+ // Identifiers denoting packages are collected in the Uses maps.
+ Types map[ast.Expr]TypeAndValue
+
+ // Defs maps identifiers to the objects they define (including
+ // package names, dots "." of dot-imports, and blank "_" identifiers).
+ // For identifiers that do not denote objects (e.g., the package name
+ // in package clauses, or symbolic variables t in t := x.(type) of
+ // type switch headers), the corresponding objects are nil.
+ //
+ // For an anonymous field, Defs returns the field *Var it defines.
+ //
+ // Invariant: Defs[id] == nil || Defs[id].Pos() == id.Pos()
+ Defs map[*ast.Ident]Object
+
+ // Uses maps identifiers to the objects they denote.
+ //
+ // For an anonymous field, Uses returns the *TypeName it denotes.
+ //
+ // Invariant: Uses[id].Pos() != id.Pos()
+ Uses map[*ast.Ident]Object
+
+ // Implicits maps nodes to their implicitly declared objects, if any.
+ // The following node and object types may appear:
+ //
+ // node declared object
+ //
+ // *ast.ImportSpec *PkgName for dot-imports and imports without renames
+ // *ast.CaseClause type-specific *Var for each type switch case clause (incl. default)
+ // *ast.Field anonymous struct field or parameter *Var
+ //
+ Implicits map[ast.Node]Object
+
+ // Selections maps selector expressions (excluding qualified identifiers)
+ // to their corresponding selections.
+ Selections map[*ast.SelectorExpr]*Selection
+
+ // Scopes maps ast.Nodes to the scopes they define. Package scopes are not
+ // associated with a specific node but with all files belonging to a package.
+ // Thus, the package scope can be found in the type-checked Package object.
+ // Scopes nest, with the Universe scope being the outermost scope, enclosing
+ // the package scope, which contains (one or more) files scopes, which enclose
+ // function scopes which in turn enclose statement and function literal scopes.
+ // Note that even though package-level functions are declared in the package
+ // scope, the function scopes are embedded in the file scope of the file
+ // containing the function declaration.
+ //
+ // The following node types may appear in Scopes:
+ //
+ // *ast.File
+ // *ast.FuncType
+ // *ast.BlockStmt
+ // *ast.IfStmt
+ // *ast.SwitchStmt
+ // *ast.TypeSwitchStmt
+ // *ast.CaseClause
+ // *ast.CommClause
+ // *ast.ForStmt
+ // *ast.RangeStmt
+ //
+ Scopes map[ast.Node]*Scope
+
+ // InitOrder is the list of package-level initializers in the order in which
+ // they must be executed. Initializers referring to variables related by an
+ // initialization dependency appear in topological order, the others appear
+ // in source order. Variables without an initialization expression do not
+ // appear in this list.
+ InitOrder []*Initializer
+}
+
+// TypeOf returns the type of expression e, or nil if not found.
+// Precondition: the Types, Uses and Defs maps are populated.
+//
+func (info *Info) TypeOf(e ast.Expr) Type {
+ if t, ok := info.Types[e]; ok {
+ return t.Type
+ }
+ if id, _ := e.(*ast.Ident); id != nil {
+ if obj := info.ObjectOf(id); obj != nil {
+ return obj.Type()
+ }
+ }
+ return nil
+}
+
+// ObjectOf returns the object denoted by the specified id,
+// or nil if not found.
+//
+// If id is an anonymous struct field, ObjectOf returns the field (*Var)
+// it uses, not the type (*TypeName) it defines.
+//
+// Precondition: the Uses and Defs maps are populated.
+//
+func (info *Info) ObjectOf(id *ast.Ident) Object {
+ if obj, _ := info.Defs[id]; obj != nil {
+ return obj
+ }
+ return info.Uses[id]
+}
+
+// TypeAndValue reports the type and value (for constants)
+// of the corresponding expression.
+type TypeAndValue struct {
+ mode operandMode
+ Type Type
+ Value exact.Value
+}
+
+// TODO(gri) Consider eliminating the IsVoid predicate. Instead, report
+// "void" values as regular values but with the empty tuple type.
+
+// IsVoid reports whether the corresponding expression
+// is a function call without results.
+func (tv TypeAndValue) IsVoid() bool {
+ return tv.mode == novalue
+}
+
+// IsType reports whether the corresponding expression specifies a type.
+func (tv TypeAndValue) IsType() bool {
+ return tv.mode == typexpr
+}
+
+// IsBuiltin reports whether the corresponding expression denotes
+// a (possibly parenthesized) built-in function.
+func (tv TypeAndValue) IsBuiltin() bool {
+ return tv.mode == builtin
+}
+
+// IsValue reports whether the corresponding expression is a value.
+// Builtins are not considered values. Constant values have a non-
+// nil Value.
+func (tv TypeAndValue) IsValue() bool {
+ switch tv.mode {
+ case constant, variable, mapindex, value, commaok:
+ return true
+ }
+ return false
+}
+
+// IsNil reports whether the corresponding expression denotes the
+// predeclared value nil.
+func (tv TypeAndValue) IsNil() bool {
+ return tv.mode == value && tv.Type == Typ[UntypedNil]
+}
+
+// Addressable reports whether the corresponding expression
+// is addressable (http://golang.org/ref/spec#Address_operators).
+func (tv TypeAndValue) Addressable() bool {
+ return tv.mode == variable
+}
+
+// Assignable reports whether the corresponding expression
+// is assignable to (provided a value of the right type).
+func (tv TypeAndValue) Assignable() bool {
+ return tv.mode == variable || tv.mode == mapindex
+}
+
+// HasOk reports whether the corresponding expression may be
+// used on the lhs of a comma-ok assignment.
+func (tv TypeAndValue) HasOk() bool {
+ return tv.mode == commaok || tv.mode == mapindex
+}
+
+// An Initializer describes a package-level variable, or a list of variables in case
+// of a multi-valued initialization expression, and the corresponding initialization
+// expression.
+type Initializer struct {
+ Lhs []*Var // var Lhs = Rhs
+ Rhs ast.Expr
+}
+
+func (init *Initializer) String() string {
+ var buf bytes.Buffer
+ for i, lhs := range init.Lhs {
+ if i > 0 {
+ buf.WriteString(", ")
+ }
+ buf.WriteString(lhs.Name())
+ }
+ buf.WriteString(" = ")
+ WriteExpr(&buf, init.Rhs)
+ return buf.String()
+}
+
+// Check type-checks a package and returns the resulting package object,
+// the first error if any, and if info != nil, additional type information.
+// The package is marked as complete if no errors occurred, otherwise it is
+// incomplete. See Config.Error for controlling behavior in the presence of
+// errors.
+//
+// The package is specified by a list of *ast.Files and corresponding
+// file set, and the package path the package is identified with.
+// The clean path must not be empty or dot (".").
+func (conf *Config) Check(path string, fset *token.FileSet, files []*ast.File, info *Info) (*Package, error) {
+ pkg := NewPackage(path, "")
+ return pkg, NewChecker(conf, fset, pkg, info).Files(files)
+}
+
+// AssertableTo reports whether a value of type V can be asserted to have type T.
+func AssertableTo(V *Interface, T Type) bool {
+ m, _ := assertableTo(V, T)
+ return m == nil
+}
+
+// AssignableTo reports whether a value of type V is assignable to a variable of type T.
+func AssignableTo(V, T Type) bool {
+ x := operand{mode: value, typ: V}
+ return x.assignableTo(nil, T) // config not needed for non-constant x
+}
+
+// ConvertibleTo reports whether a value of type V is convertible to a value of type T.
+func ConvertibleTo(V, T Type) bool {
+ x := operand{mode: value, typ: V}
+ return x.convertibleTo(nil, T) // config not needed for non-constant x
+}
+
+// Implements reports whether type V implements interface T.
+func Implements(V Type, T *Interface) bool {
+ f, _ := MissingMethod(V, T, true)
+ return f == nil
+}
diff --git a/vendor/golang.org/x/tools/go/types/assignments.go b/vendor/golang.org/x/tools/go/types/assignments.go
new file mode 100644
index 0000000..93b842e
--- /dev/null
+++ b/vendor/golang.org/x/tools/go/types/assignments.go
@@ -0,0 +1,328 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// This file implements initialization and assignment checks.
+
+package types
+
+import (
+ "go/ast"
+ "go/token"
+)
+
+// assignment reports whether x can be assigned to a variable of type T,
+// if necessary by attempting to convert untyped values to the appropriate
+// type. If x.mode == invalid upon return, then assignment has already
+// issued an error message and the caller doesn't have to report another.
+// Use T == nil to indicate assignment to an untyped blank identifier.
+//
+// TODO(gri) Should find a better way to handle in-band errors.
+//
+func (check *Checker) assignment(x *operand, T Type) bool {
+ switch x.mode {
+ case invalid:
+ return true // error reported before
+ case constant, variable, mapindex, value, commaok:
+ // ok
+ default:
+ unreachable()
+ }
+
+ // x must be a single value
+ // (tuple types are never named - no need for underlying type)
+ if t, _ := x.typ.(*Tuple); t != nil {
+ assert(t.Len() > 1)
+ check.errorf(x.pos(), "%d-valued expression %s used as single value", t.Len(), x)
+ x.mode = invalid
+ return false
+ }
+
+ if isUntyped(x.typ) {
+ target := T
+ // spec: "If an untyped constant is assigned to a variable of interface
+ // type or the blank identifier, the constant is first converted to type
+ // bool, rune, int, float64, complex128 or string respectively, depending
+ // on whether the value is a boolean, rune, integer, floating-point, complex,
+ // or string constant."
+ if T == nil || IsInterface(T) {
+ if T == nil && x.typ == Typ[UntypedNil] {
+ check.errorf(x.pos(), "use of untyped nil")
+ x.mode = invalid
+ return false
+ }
+ target = defaultType(x.typ)
+ }
+ check.convertUntyped(x, target)
+ if x.mode == invalid {
+ return false
+ }
+ }
+
+ // spec: "If a left-hand side is the blank identifier, any typed or
+ // non-constant value except for the predeclared identifier nil may
+ // be assigned to it."
+ return T == nil || x.assignableTo(check.conf, T)
+}
+
+func (check *Checker) initConst(lhs *Const, x *operand) {
+ if x.mode == invalid || x.typ == Typ[Invalid] || lhs.typ == Typ[Invalid] {
+ if lhs.typ == nil {
+ lhs.typ = Typ[Invalid]
+ }
+ return
+ }
+
+ // rhs must be a constant
+ if x.mode != constant {
+ check.errorf(x.pos(), "%s is not constant", x)
+ if lhs.typ == nil {
+ lhs.typ = Typ[Invalid]
+ }
+ return
+ }
+ assert(isConstType(x.typ))
+
+ // If the lhs doesn't have a type yet, use the type of x.
+ if lhs.typ == nil {
+ lhs.typ = x.typ
+ }
+
+ if !check.assignment(x, lhs.typ) {
+ if x.mode != invalid {
+ check.errorf(x.pos(), "cannot define constant %s (type %s) as %s", lhs.Name(), lhs.typ, x)
+ }
+ return
+ }
+
+ lhs.val = x.val
+}
+
+// If result is set, lhs is a function result parameter and x is a return result.
+func (check *Checker) initVar(lhs *Var, x *operand, result bool) Type {
+ if x.mode == invalid || x.typ == Typ[Invalid] || lhs.typ == Typ[Invalid] {
+ if lhs.typ == nil {
+ lhs.typ = Typ[Invalid]
+ }
+ return nil
+ }
+
+ // If the lhs doesn't have a type yet, use the type of x.
+ if lhs.typ == nil {
+ typ := x.typ
+ if isUntyped(typ) {
+ // convert untyped types to default types
+ if typ == Typ[UntypedNil] {
+ check.errorf(x.pos(), "use of untyped nil")
+ lhs.typ = Typ[Invalid]
+ return nil
+ }
+ typ = defaultType(typ)
+ }
+ lhs.typ = typ
+ }
+
+ if !check.assignment(x, lhs.typ) {
+ if x.mode != invalid {
+ if result {
+ // don't refer to lhs.name because it may be an anonymous result parameter
+ check.errorf(x.pos(), "cannot return %s as value of type %s", x, lhs.typ)
+ } else {
+ check.errorf(x.pos(), "cannot initialize %s with %s", lhs, x)
+ }
+ }
+ return nil
+ }
+
+ return x.typ
+}
+
+func (check *Checker) assignVar(lhs ast.Expr, x *operand) Type {
+ if x.mode == invalid || x.typ == Typ[Invalid] {
+ return nil
+ }
+
+ // Determine if the lhs is a (possibly parenthesized) identifier.
+ ident, _ := unparen(lhs).(*ast.Ident)
+
+ // Don't evaluate lhs if it is the blank identifier.
+ if ident != nil && ident.Name == "_" {
+ check.recordDef(ident, nil)
+ if !check.assignment(x, nil) {
+ assert(x.mode == invalid)
+ x.typ = nil
+ }
+ return x.typ
+ }
+
+ // If the lhs is an identifier denoting a variable v, this assignment
+ // is not a 'use' of v. Remember current value of v.used and restore
+ // after evaluating the lhs via check.expr.
+ var v *Var
+ var v_used bool
+ if ident != nil {
+ if _, obj := check.scope.LookupParent(ident.Name, token.NoPos); obj != nil {
+ v, _ = obj.(*Var)
+ if v != nil {
+ v_used = v.used
+ }
+ }
+ }
+
+ var z operand
+ check.expr(&z, lhs)
+ if v != nil {
+ v.used = v_used // restore v.used
+ }
+
+ if z.mode == invalid || z.typ == Typ[Invalid] {
+ return nil
+ }
+
+ // spec: "Each left-hand side operand must be addressable, a map index
+ // expression, or the blank identifier. Operands may be parenthesized."
+ switch z.mode {
+ case invalid:
+ return nil
+ case variable, mapindex:
+ // ok
+ default:
+ check.errorf(z.pos(), "cannot assign to %s", &z)
+ return nil
+ }
+
+ if !check.assignment(x, z.typ) {
+ if x.mode != invalid {
+ check.errorf(x.pos(), "cannot assign %s to %s", x, &z)
+ }
+ return nil
+ }
+
+ return x.typ
+}
+
+// If returnPos is valid, initVars is called to type-check the assignment of
+// return expressions, and returnPos is the position of the return statement.
+func (check *Checker) initVars(lhs []*Var, rhs []ast.Expr, returnPos token.Pos) {
+ l := len(lhs)
+ get, r, commaOk := unpack(func(x *operand, i int) { check.expr(x, rhs[i]) }, len(rhs), l == 2 && !returnPos.IsValid())
+ if get == nil || l != r {
+ // invalidate lhs and use rhs
+ for _, obj := range lhs {
+ if obj.typ == nil {
+ obj.typ = Typ[Invalid]
+ }
+ }
+ if get == nil {
+ return // error reported by unpack
+ }
+ check.useGetter(get, r)
+ if returnPos.IsValid() {
+ check.errorf(returnPos, "wrong number of return values (want %d, got %d)", l, r)
+ return
+ }
+ check.errorf(rhs[0].Pos(), "assignment count mismatch (%d vs %d)", l, r)
+ return
+ }
+
+ var x operand
+ if commaOk {
+ var a [2]Type
+ for i := range a {
+ get(&x, i)
+ a[i] = check.initVar(lhs[i], &x, returnPos.IsValid())
+ }
+ check.recordCommaOkTypes(rhs[0], a)
+ return
+ }
+
+ for i, lhs := range lhs {
+ get(&x, i)
+ check.initVar(lhs, &x, returnPos.IsValid())
+ }
+}
+
+func (check *Checker) assignVars(lhs, rhs []ast.Expr) {
+ l := len(lhs)
+ get, r, commaOk := unpack(func(x *operand, i int) { check.expr(x, rhs[i]) }, len(rhs), l == 2)
+ if get == nil {
+ return // error reported by unpack
+ }
+ if l != r {
+ check.useGetter(get, r)
+ check.errorf(rhs[0].Pos(), "assignment count mismatch (%d vs %d)", l, r)
+ return
+ }
+
+ var x operand
+ if commaOk {
+ var a [2]Type
+ for i := range a {
+ get(&x, i)
+ a[i] = check.assignVar(lhs[i], &x)
+ }
+ check.recordCommaOkTypes(rhs[0], a)
+ return
+ }
+
+ for i, lhs := range lhs {
+ get(&x, i)
+ check.assignVar(lhs, &x)
+ }
+}
+
+func (check *Checker) shortVarDecl(pos token.Pos, lhs, rhs []ast.Expr) {
+ scope := check.scope
+
+ // collect lhs variables
+ var newVars []*Var
+ var lhsVars = make([]*Var, len(lhs))
+ for i, lhs := range lhs {
+ var obj *Var
+ if ident, _ := lhs.(*ast.Ident); ident != nil {
+ // Use the correct obj if the ident is redeclared. The
+ // variable's scope starts after the declaration; so we
+ // must use Scope.Lookup here and call Scope.Insert
+ // (via check.declare) later.
+ name := ident.Name
+ if alt := scope.Lookup(name); alt != nil {
+ // redeclared object must be a variable
+ if alt, _ := alt.(*Var); alt != nil {
+ obj = alt
+ } else {
+ check.errorf(lhs.Pos(), "cannot assign to %s", lhs)
+ }
+ check.recordUse(ident, alt)
+ } else {
+ // declare new variable, possibly a blank (_) variable
+ obj = NewVar(ident.Pos(), check.pkg, name, nil)
+ if name != "_" {
+ newVars = append(newVars, obj)
+ }
+ check.recordDef(ident, obj)
+ }
+ } else {
+ check.errorf(lhs.Pos(), "cannot declare %s", lhs)
+ }
+ if obj == nil {
+ obj = NewVar(lhs.Pos(), check.pkg, "_", nil) // dummy variable
+ }
+ lhsVars[i] = obj
+ }
+
+ check.initVars(lhsVars, rhs, token.NoPos)
+
+ // declare new variables
+ if len(newVars) > 0 {
+ // spec: "The scope of a constant or variable identifier declared inside
+ // a function begins at the end of the ConstSpec or VarSpec (ShortVarDecl
+ // for short variable declarations) and ends at the end of the innermost
+ // containing block."
+ scopePos := rhs[len(rhs)-1].End()
+ for _, obj := range newVars {
+ check.declare(scope, nil, obj, scopePos) // recordObject already called
+ }
+ } else {
+ check.softErrorf(pos, "no new variables on left side of :=")
+ }
+}
diff --git a/vendor/golang.org/x/tools/go/types/builtins.go b/vendor/golang.org/x/tools/go/types/builtins.go
new file mode 100644
index 0000000..f45f930
--- /dev/null
+++ b/vendor/golang.org/x/tools/go/types/builtins.go
@@ -0,0 +1,628 @@
+// Copyright 2012 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// This file implements typechecking of builtin function calls.
+
+package types
+
+import (
+ "go/ast"
+ "go/token"
+
+ "golang.org/x/tools/go/exact"
+)
+
+// builtin type-checks a call to the built-in specified by id and
+// returns true if the call is valid, with *x holding the result;
+// but x.expr is not set. If the call is invalid, the result is
+// false, and *x is undefined.
+//
+func (check *Checker) builtin(x *operand, call *ast.CallExpr, id builtinId) (_ bool) {
+ // append is the only built-in that permits the use of ... for the last argument
+ bin := predeclaredFuncs[id]
+ if call.Ellipsis.IsValid() && id != _Append {
+ check.invalidOp(call.Ellipsis, "invalid use of ... with built-in %s", bin.name)
+ check.use(call.Args...)
+ return
+ }
+
+ // For len(x) and cap(x) we need to know if x contains any function calls or
+ // receive operations. Save/restore current setting and set hasCallOrRecv to
+ // false for the evaluation of x so that we can check it afterwards.
+ // Note: We must do this _before_ calling unpack because unpack evaluates the
+ // first argument before we even call arg(x, 0)!
+ if id == _Len || id == _Cap {
+ defer func(b bool) {
+ check.hasCallOrRecv = b
+ }(check.hasCallOrRecv)
+ check.hasCallOrRecv = false
+ }
+
+ // determine actual arguments
+ var arg getter
+ nargs := len(call.Args)
+ switch id {
+ default:
+ // make argument getter
+ arg, nargs, _ = unpack(func(x *operand, i int) { check.expr(x, call.Args[i]) }, nargs, false)
+ if arg == nil {
+ return
+ }
+ // evaluate first argument, if present
+ if nargs > 0 {
+ arg(x, 0)
+ if x.mode == invalid {
+ return
+ }
+ }
+ case _Make, _New, _Offsetof, _Trace:
+ // arguments require special handling
+ }
+
+ // check argument count
+ {
+ msg := ""
+ if nargs < bin.nargs {
+ msg = "not enough"
+ } else if !bin.variadic && nargs > bin.nargs {
+ msg = "too many"
+ }
+ if msg != "" {
+ check.invalidOp(call.Rparen, "%s arguments for %s (expected %d, found %d)", msg, call, bin.nargs, nargs)
+ return
+ }
+ }
+
+ switch id {
+ case _Append:
+ // append(s S, x ...T) S, where T is the element type of S
+ // spec: "The variadic function append appends zero or more values x to s of type
+ // S, which must be a slice type, and returns the resulting slice, also of type S.
+ // The values x are passed to a parameter of type ...T where T is the element type
+ // of S and the respective parameter passing rules apply."
+ S := x.typ
+ var T Type
+ if s, _ := S.Underlying().(*Slice); s != nil {
+ T = s.elem
+ } else {
+ check.invalidArg(x.pos(), "%s is not a slice", x)
+ return
+ }
+
+ // remember arguments that have been evaluated already
+ alist := []operand{*x}
+
+ // spec: "As a special case, append also accepts a first argument assignable
+ // to type []byte with a second argument of string type followed by ... .
+ // This form appends the bytes of the string.
+ if nargs == 2 && call.Ellipsis.IsValid() && x.assignableTo(check.conf, NewSlice(universeByte)) {
+ arg(x, 1)
+ if x.mode == invalid {
+ return
+ }
+ if isString(x.typ) {
+ if check.Types != nil {
+ sig := makeSig(S, S, x.typ)
+ sig.variadic = true
+ check.recordBuiltinType(call.Fun, sig)
+ }
+ x.mode = value
+ x.typ = S
+ break
+ }
+ alist = append(alist, *x)
+ // fallthrough
+ }
+
+ // check general case by creating custom signature
+ sig := makeSig(S, S, NewSlice(T)) // []T required for variadic signature
+ sig.variadic = true
+ check.arguments(x, call, sig, func(x *operand, i int) {
+ // only evaluate arguments that have not been evaluated before
+ if i < len(alist) {
+ *x = alist[i]
+ return
+ }
+ arg(x, i)
+ }, nargs)
+ // ok to continue even if check.arguments reported errors
+
+ x.mode = value
+ x.typ = S
+ if check.Types != nil {
+ check.recordBuiltinType(call.Fun, sig)
+ }
+
+ case _Cap, _Len:
+ // cap(x)
+ // len(x)
+ mode := invalid
+ var typ Type
+ var val exact.Value
+ switch typ = implicitArrayDeref(x.typ.Underlying()); t := typ.(type) {
+ case *Basic:
+ if isString(t) && id == _Len {
+ if x.mode == constant {
+ mode = constant
+ val = exact.MakeInt64(int64(len(exact.StringVal(x.val))))
+ } else {
+ mode = value
+ }
+ }
+
+ case *Array:
+ mode = value
+ // spec: "The expressions len(s) and cap(s) are constants
+ // if the type of s is an array or pointer to an array and
+ // the expression s does not contain channel receives or
+ // function calls; in this case s is not evaluated."
+ if !check.hasCallOrRecv {
+ mode = constant
+ val = exact.MakeInt64(t.len)
+ }
+
+ case *Slice, *Chan:
+ mode = value
+
+ case *Map:
+ if id == _Len {
+ mode = value
+ }
+ }
+
+ if mode == invalid {
+ check.invalidArg(x.pos(), "%s for %s", x, bin.name)
+ return
+ }
+
+ x.mode = mode
+ x.typ = Typ[Int]
+ x.val = val
+ if check.Types != nil && mode != constant {
+ check.recordBuiltinType(call.Fun, makeSig(x.typ, typ))
+ }
+
+ case _Close:
+ // close(c)
+ c, _ := x.typ.Underlying().(*Chan)
+ if c == nil {
+ check.invalidArg(x.pos(), "%s is not a channel", x)
+ return
+ }
+ if c.dir == RecvOnly {
+ check.invalidArg(x.pos(), "%s must not be a receive-only channel", x)
+ return
+ }
+
+ x.mode = novalue
+ if check.Types != nil {
+ check.recordBuiltinType(call.Fun, makeSig(nil, c))
+ }
+
+ case _Complex:
+ // complex(x, y realT) complexT
+ if !check.complexArg(x) {
+ return
+ }
+
+ var y operand
+ arg(&y, 1)
+ if y.mode == invalid {
+ return
+ }
+ if !check.complexArg(&y) {
+ return
+ }
+
+ check.convertUntyped(x, y.typ)
+ if x.mode == invalid {
+ return
+ }
+ check.convertUntyped(&y, x.typ)
+ if y.mode == invalid {
+ return
+ }
+
+ if !Identical(x.typ, y.typ) {
+ check.invalidArg(x.pos(), "mismatched types %s and %s", x.typ, y.typ)
+ return
+ }
+
+ if x.mode == constant && y.mode == constant {
+ x.val = exact.BinaryOp(x.val, token.ADD, exact.MakeImag(y.val))
+ } else {
+ x.mode = value
+ }
+
+ realT := x.typ
+ complexT := Typ[Invalid]
+ switch realT.Underlying().(*Basic).kind {
+ case Float32:
+ complexT = Typ[Complex64]
+ case Float64:
+ complexT = Typ[Complex128]
+ case UntypedInt, UntypedRune, UntypedFloat:
+ if x.mode == constant {
+ realT = defaultType(realT).(*Basic)
+ complexT = Typ[UntypedComplex]
+ } else {
+ // untyped but not constant; probably because one
+ // operand is a non-constant shift of untyped lhs
+ realT = Typ[Float64]
+ complexT = Typ[Complex128]
+ }
+ default:
+ check.invalidArg(x.pos(), "float32 or float64 arguments expected")
+ return
+ }
+
+ x.typ = complexT
+ if check.Types != nil && x.mode != constant {
+ check.recordBuiltinType(call.Fun, makeSig(complexT, realT, realT))
+ }
+
+ if x.mode != constant {
+ // The arguments have now their final types, which at run-
+ // time will be materialized. Update the expression trees.
+ // If the current types are untyped, the materialized type
+ // is the respective default type.
+ // (If the result is constant, the arguments are never
+ // materialized and there is nothing to do.)
+ check.updateExprType(x.expr, realT, true)
+ check.updateExprType(y.expr, realT, true)
+ }
+
+ case _Copy:
+ // copy(x, y []T) int
+ var dst Type
+ if t, _ := x.typ.Underlying().(*Slice); t != nil {
+ dst = t.elem
+ }
+
+ var y operand
+ arg(&y, 1)
+ if y.mode == invalid {
+ return
+ }
+ var src Type
+ switch t := y.typ.Underlying().(type) {
+ case *Basic:
+ if isString(y.typ) {
+ src = universeByte
+ }
+ case *Slice:
+ src = t.elem
+ }
+
+ if dst == nil || src == nil {
+ check.invalidArg(x.pos(), "copy expects slice arguments; found %s and %s", x, &y)
+ return
+ }
+
+ if !Identical(dst, src) {
+ check.invalidArg(x.pos(), "arguments to copy %s and %s have different element types %s and %s", x, &y, dst, src)
+ return
+ }
+
+ if check.Types != nil {
+ check.recordBuiltinType(call.Fun, makeSig(Typ[Int], x.typ, y.typ))
+ }
+ x.mode = value
+ x.typ = Typ[Int]
+
+ case _Delete:
+ // delete(m, k)
+ m, _ := x.typ.Underlying().(*Map)
+ if m == nil {
+ check.invalidArg(x.pos(), "%s is not a map", x)
+ return
+ }
+ arg(x, 1) // k
+ if x.mode == invalid {
+ return
+ }
+
+ if !x.assignableTo(check.conf, m.key) {
+ check.invalidArg(x.pos(), "%s is not assignable to %s", x, m.key)
+ return
+ }
+
+ x.mode = novalue
+ if check.Types != nil {
+ check.recordBuiltinType(call.Fun, makeSig(nil, m, m.key))
+ }
+
+ case _Imag, _Real:
+ // imag(complexT) realT
+ // real(complexT) realT
+ if !isComplex(x.typ) {
+ check.invalidArg(x.pos(), "%s must be a complex number", x)
+ return
+ }
+ if x.mode == constant {
+ if id == _Real {
+ x.val = exact.Real(x.val)
+ } else {
+ x.val = exact.Imag(x.val)
+ }
+ } else {
+ x.mode = value
+ }
+ var k BasicKind
+ switch x.typ.Underlying().(*Basic).kind {
+ case Complex64:
+ k = Float32
+ case Complex128:
+ k = Float64
+ case UntypedComplex:
+ k = UntypedFloat
+ default:
+ unreachable()
+ }
+
+ if check.Types != nil && x.mode != constant {
+ check.recordBuiltinType(call.Fun, makeSig(Typ[k], x.typ))
+ }
+ x.typ = Typ[k]
+
+ case _Make:
+ // make(T, n)
+ // make(T, n, m)
+ // (no argument evaluated yet)
+ arg0 := call.Args[0]
+ T := check.typ(arg0)
+ if T == Typ[Invalid] {
+ return
+ }
+
+ var min int // minimum number of arguments
+ switch T.Underlying().(type) {
+ case *Slice:
+ min = 2
+ case *Map, *Chan:
+ min = 1
+ default:
+ check.invalidArg(arg0.Pos(), "cannot make %s; type must be slice, map, or channel", arg0)
+ return
+ }
+ if nargs < min || min+1 < nargs {
+ check.errorf(call.Pos(), "%s expects %d or %d arguments; found %d", call, min, min+1, nargs)
+ return
+ }
+ var sizes []int64 // constant integer arguments, if any
+ for _, arg := range call.Args[1:] {
+ if s, ok := check.index(arg, -1); ok && s >= 0 {
+ sizes = append(sizes, s)
+ }
+ }
+ if len(sizes) == 2 && sizes[0] > sizes[1] {
+ check.invalidArg(call.Args[1].Pos(), "length and capacity swapped")
+ // safe to continue
+ }
+ x.mode = value
+ x.typ = T
+ if check.Types != nil {
+ params := [...]Type{T, Typ[Int], Typ[Int]}
+ check.recordBuiltinType(call.Fun, makeSig(x.typ, params[:1+len(sizes)]...))
+ }
+
+ case _New:
+ // new(T)
+ // (no argument evaluated yet)
+ T := check.typ(call.Args[0])
+ if T == Typ[Invalid] {
+ return
+ }
+
+ x.mode = value
+ x.typ = &Pointer{base: T}
+ if check.Types != nil {
+ check.recordBuiltinType(call.Fun, makeSig(x.typ, T))
+ }
+
+ case _Panic:
+ // panic(x)
+ T := new(Interface)
+ if !check.assignment(x, T) {
+ assert(x.mode == invalid)
+ return
+ }
+
+ x.mode = novalue
+ if check.Types != nil {
+ check.recordBuiltinType(call.Fun, makeSig(nil, T))
+ }
+
+ case _Print, _Println:
+ // print(x, y, ...)
+ // println(x, y, ...)
+ var params []Type
+ if nargs > 0 {
+ params = make([]Type, nargs)
+ for i := 0; i < nargs; i++ {
+ if i > 0 {
+ arg(x, i) // first argument already evaluated
+ }
+ if !check.assignment(x, nil) {
+ assert(x.mode == invalid)
+ return
+ }
+ params[i] = x.typ
+ }
+ }
+
+ x.mode = novalue
+ if check.Types != nil {
+ check.recordBuiltinType(call.Fun, makeSig(nil, params...))
+ }
+
+ case _Recover:
+ // recover() interface{}
+ x.mode = value
+ x.typ = new(Interface)
+ if check.Types != nil {
+ check.recordBuiltinType(call.Fun, makeSig(x.typ))
+ }
+
+ case _Alignof:
+ // unsafe.Alignof(x T) uintptr
+ if !check.assignment(x, nil) {
+ assert(x.mode == invalid)
+ return
+ }
+
+ x.mode = constant
+ x.val = exact.MakeInt64(check.conf.alignof(x.typ))
+ x.typ = Typ[Uintptr]
+ // result is constant - no need to record signature
+
+ case _Offsetof:
+ // unsafe.Offsetof(x T) uintptr, where x must be a selector
+ // (no argument evaluated yet)
+ arg0 := call.Args[0]
+ selx, _ := unparen(arg0).(*ast.SelectorExpr)
+ if selx == nil {
+ check.invalidArg(arg0.Pos(), "%s is not a selector expression", arg0)
+ check.use(arg0)
+ return
+ }
+
+ check.expr(x, selx.X)
+ if x.mode == invalid {
+ return
+ }
+
+ base := derefStructPtr(x.typ)
+ sel := selx.Sel.Name
+ obj, index, indirect := LookupFieldOrMethod(base, false, check.pkg, sel)
+ switch obj.(type) {
+ case nil:
+ check.invalidArg(x.pos(), "%s has no single field %s", base, sel)
+ return
+ case *Func:
+ // TODO(gri) Using derefStructPtr may result in methods being found
+ // that don't actually exist. An error either way, but the error
+ // message is confusing. See: http://play.golang.org/p/al75v23kUy ,
+ // but go/types reports: "invalid argument: x.m is a method value".
+ check.invalidArg(arg0.Pos(), "%s is a method value", arg0)
+ return
+ }
+ if indirect {
+ check.invalidArg(x.pos(), "field %s is embedded via a pointer in %s", sel, base)
+ return
+ }
+
+ // TODO(gri) Should we pass x.typ instead of base (and indirect report if derefStructPtr indirected)?
+ check.recordSelection(selx, FieldVal, base, obj, index, false)
+
+ offs := check.conf.offsetof(base, index)
+ x.mode = constant
+ x.val = exact.MakeInt64(offs)
+ x.typ = Typ[Uintptr]
+ // result is constant - no need to record signature
+
+ case _Sizeof:
+ // unsafe.Sizeof(x T) uintptr
+ if !check.assignment(x, nil) {
+ assert(x.mode == invalid)
+ return
+ }
+
+ x.mode = constant
+ x.val = exact.MakeInt64(check.conf.sizeof(x.typ))
+ x.typ = Typ[Uintptr]
+ // result is constant - no need to record signature
+
+ case _Assert:
+ // assert(pred) causes a typechecker error if pred is false.
+ // The result of assert is the value of pred if there is no error.
+ // Note: assert is only available in self-test mode.
+ if x.mode != constant || !isBoolean(x.typ) {
+ check.invalidArg(x.pos(), "%s is not a boolean constant", x)
+ return
+ }
+ if x.val.Kind() != exact.Bool {
+ check.errorf(x.pos(), "internal error: value of %s should be a boolean constant", x)
+ return
+ }
+ if !exact.BoolVal(x.val) {
+ check.errorf(call.Pos(), "%s failed", call)
+ // compile-time assertion failure - safe to continue
+ }
+ // result is constant - no need to record signature
+
+ case _Trace:
+ // trace(x, y, z, ...) dumps the positions, expressions, and
+ // values of its arguments. The result of trace is the value
+ // of the first argument.
+ // Note: trace is only available in self-test mode.
+ // (no argument evaluated yet)
+ if nargs == 0 {
+ check.dump("%s: trace() without arguments", call.Pos())
+ x.mode = novalue
+ break
+ }
+ var t operand
+ x1 := x
+ for _, arg := range call.Args {
+ check.rawExpr(x1, arg, nil) // permit trace for types, e.g.: new(trace(T))
+ check.dump("%s: %s", x1.pos(), x1)
+ x1 = &t // use incoming x only for first argument
+ }
+ // trace is only available in test mode - no need to record signature
+
+ default:
+ unreachable()
+ }
+
+ return true
+}
+
+// makeSig makes a signature for the given argument and result types.
+// Default types are used for untyped arguments, and res may be nil.
+func makeSig(res Type, args ...Type) *Signature {
+ list := make([]*Var, len(args))
+ for i, param := range args {
+ list[i] = NewVar(token.NoPos, nil, "", defaultType(param))
+ }
+ params := NewTuple(list...)
+ var result *Tuple
+ if res != nil {
+ assert(!isUntyped(res))
+ result = NewTuple(NewVar(token.NoPos, nil, "", res))
+ }
+ return &Signature{params: params, results: result}
+}
+
+// implicitArrayDeref returns A if typ is of the form *A and A is an array;
+// otherwise it returns typ.
+//
+func implicitArrayDeref(typ Type) Type {
+ if p, ok := typ.(*Pointer); ok {
+ if a, ok := p.base.Underlying().(*Array); ok {
+ return a
+ }
+ }
+ return typ
+}
+
+// unparen returns e with any enclosing parentheses stripped.
+func unparen(e ast.Expr) ast.Expr {
+ for {
+ p, ok := e.(*ast.ParenExpr)
+ if !ok {
+ return e
+ }
+ e = p.X
+ }
+}
+
+func (check *Checker) complexArg(x *operand) bool {
+ t, _ := x.typ.Underlying().(*Basic)
+ if t != nil && (t.info&IsFloat != 0 || t.kind == UntypedInt || t.kind == UntypedRune) {
+ return true
+ }
+ check.invalidArg(x.pos(), "%s must be a float32, float64, or an untyped non-complex numeric constant", x)
+ return false
+}
diff --git a/vendor/golang.org/x/tools/go/types/call.go b/vendor/golang.org/x/tools/go/types/call.go
new file mode 100644
index 0000000..1e94212
--- /dev/null
+++ b/vendor/golang.org/x/tools/go/types/call.go
@@ -0,0 +1,441 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// This file implements typechecking of call and selector expressions.
+
+package types
+
+import (
+ "go/ast"
+ "go/token"
+)
+
+func (check *Checker) call(x *operand, e *ast.CallExpr) exprKind {
+ check.exprOrType(x, e.Fun)
+
+ switch x.mode {
+ case invalid:
+ check.use(e.Args...)
+ x.mode = invalid
+ x.expr = e
+ return statement
+
+ case typexpr:
+ // conversion
+ T := x.typ
+ x.mode = invalid
+ switch n := len(e.Args); n {
+ case 0:
+ check.errorf(e.Rparen, "missing argument in conversion to %s", T)
+ case 1:
+ check.expr(x, e.Args[0])
+ if x.mode != invalid {
+ check.conversion(x, T)
+ }
+ default:
+ check.errorf(e.Args[n-1].Pos(), "too many arguments in conversion to %s", T)
+ }
+ x.expr = e
+ return conversion
+
+ case builtin:
+ id := x.id
+ if !check.builtin(x, e, id) {
+ x.mode = invalid
+ }
+ x.expr = e
+ // a non-constant result implies a function call
+ if x.mode != invalid && x.mode != constant {
+ check.hasCallOrRecv = true
+ }
+ return predeclaredFuncs[id].kind
+
+ default:
+ // function/method call
+ sig, _ := x.typ.Underlying().(*Signature)
+ if sig == nil {
+ check.invalidOp(x.pos(), "cannot call non-function %s", x)
+ x.mode = invalid
+ x.expr = e
+ return statement
+ }
+
+ arg, n, _ := unpack(func(x *operand, i int) { check.expr(x, e.Args[i]) }, len(e.Args), false)
+ if arg == nil {
+ x.mode = invalid
+ x.expr = e
+ return statement
+ }
+
+ check.arguments(x, e, sig, arg, n)
+
+ // determine result
+ switch sig.results.Len() {
+ case 0:
+ x.mode = novalue
+ case 1:
+ x.mode = value
+ x.typ = sig.results.vars[0].typ // unpack tuple
+ default:
+ x.mode = value
+ x.typ = sig.results
+ }
+ x.expr = e
+ check.hasCallOrRecv = true
+
+ return statement
+ }
+}
+
+// use type-checks each argument.
+// Useful to make sure expressions are evaluated
+// (and variables are "used") in the presence of other errors.
+func (check *Checker) use(arg ...ast.Expr) {
+ var x operand
+ for _, e := range arg {
+ check.rawExpr(&x, e, nil)
+ }
+}
+
+// useGetter is like use, but takes a getter instead of a list of expressions.
+// It should be called instead of use if a getter is present to avoid repeated
+// evaluation of the first argument (since the getter was likely obtained via
+// unpack, which may have evaluated the first argument already).
+func (check *Checker) useGetter(get getter, n int) {
+ var x operand
+ for i := 0; i < n; i++ {
+ get(&x, i)
+ }
+}
+
+// A getter sets x as the i'th operand, where 0 <= i < n and n is the total
+// number of operands (context-specific, and maintained elsewhere). A getter
+// type-checks the i'th operand; the details of the actual check are getter-
+// specific.
+type getter func(x *operand, i int)
+
+// unpack takes a getter get and a number of operands n. If n == 1, unpack
+// calls the incoming getter for the first operand. If that operand is
+// invalid, unpack returns (nil, 0, false). Otherwise, if that operand is a
+// function call, or a comma-ok expression and allowCommaOk is set, the result
+// is a new getter and operand count providing access to the function results,
+// or comma-ok values, respectively. The third result value reports if it
+// is indeed the comma-ok case. In all other cases, the incoming getter and
+// operand count are returned unchanged, and the third result value is false.
+//
+// In other words, if there's exactly one operand that - after type-checking
+// by calling get - stands for multiple operands, the resulting getter provides
+// access to those operands instead.
+//
+// If the returned getter is called at most once for a given operand index i
+// (including i == 0), that operand is guaranteed to cause only one call of
+// the incoming getter with that i.
+//
+func unpack(get getter, n int, allowCommaOk bool) (getter, int, bool) {
+ if n == 1 {
+ // possibly result of an n-valued function call or comma,ok value
+ var x0 operand
+ get(&x0, 0)
+ if x0.mode == invalid {
+ return nil, 0, false
+ }
+
+ if t, ok := x0.typ.(*Tuple); ok {
+ // result of an n-valued function call
+ return func(x *operand, i int) {
+ x.mode = value
+ x.expr = x0.expr
+ x.typ = t.At(i).typ
+ }, t.Len(), false
+ }
+
+ if x0.mode == mapindex || x0.mode == commaok {
+ // comma-ok value
+ if allowCommaOk {
+ a := [2]Type{x0.typ, Typ[UntypedBool]}
+ return func(x *operand, i int) {
+ x.mode = value
+ x.expr = x0.expr
+ x.typ = a[i]
+ }, 2, true
+ }
+ x0.mode = value
+ }
+
+ // single value
+ return func(x *operand, i int) {
+ if i != 0 {
+ unreachable()
+ }
+ *x = x0
+ }, 1, false
+ }
+
+ // zero or multiple values
+ return get, n, false
+}
+
+// arguments checks argument passing for the call with the given signature.
+// The arg function provides the operand for the i'th argument.
+func (check *Checker) arguments(x *operand, call *ast.CallExpr, sig *Signature, arg getter, n int) {
+ if call.Ellipsis.IsValid() {
+ // last argument is of the form x...
+ if len(call.Args) == 1 && n > 1 {
+ // f()... is not permitted if f() is multi-valued
+ check.errorf(call.Ellipsis, "cannot use ... with %d-valued expression %s", n, call.Args[0])
+ check.useGetter(arg, n)
+ return
+ }
+ if !sig.variadic {
+ check.errorf(call.Ellipsis, "cannot use ... in call to non-variadic %s", call.Fun)
+ check.useGetter(arg, n)
+ return
+ }
+ }
+
+ // evaluate arguments
+ for i := 0; i < n; i++ {
+ arg(x, i)
+ if x.mode != invalid {
+ var ellipsis token.Pos
+ if i == n-1 && call.Ellipsis.IsValid() {
+ ellipsis = call.Ellipsis
+ }
+ check.argument(sig, i, x, ellipsis)
+ }
+ }
+
+ // check argument count
+ if sig.variadic {
+ // a variadic function accepts an "empty"
+ // last argument: count one extra
+ n++
+ }
+ if n < sig.params.Len() {
+ check.errorf(call.Rparen, "too few arguments in call to %s", call.Fun)
+ // ok to continue
+ }
+}
+
+// argument checks passing of argument x to the i'th parameter of the given signature.
+// If ellipsis is valid, the argument is followed by ... at that position in the call.
+func (check *Checker) argument(sig *Signature, i int, x *operand, ellipsis token.Pos) {
+ n := sig.params.Len()
+
+ // determine parameter type
+ var typ Type
+ switch {
+ case i < n:
+ typ = sig.params.vars[i].typ
+ case sig.variadic:
+ typ = sig.params.vars[n-1].typ
+ if debug {
+ if _, ok := typ.(*Slice); !ok {
+ check.dump("%s: expected unnamed slice type, got %s", sig.params.vars[n-1].Pos(), typ)
+ }
+ }
+ default:
+ check.errorf(x.pos(), "too many arguments")
+ return
+ }
+
+ if ellipsis.IsValid() {
+ // argument is of the form x...
+ if i != n-1 {
+ check.errorf(ellipsis, "can only use ... with matching parameter")
+ return
+ }
+ switch t := x.typ.Underlying().(type) {
+ case *Slice:
+ // ok
+ case *Tuple:
+ check.errorf(ellipsis, "cannot use ... with %d-valued expression %s", t.Len(), x)
+ return
+ default:
+ check.errorf(x.pos(), "cannot use %s as parameter of type %s", x, typ)
+ return
+ }
+ } else if sig.variadic && i >= n-1 {
+ // use the variadic parameter slice's element type
+ typ = typ.(*Slice).elem
+ }
+
+ if !check.assignment(x, typ) && x.mode != invalid {
+ check.errorf(x.pos(), "cannot pass argument %s to parameter of type %s", x, typ)
+ }
+}
+
+func (check *Checker) selector(x *operand, e *ast.SelectorExpr) {
+ // these must be declared before the "goto Error" statements
+ var (
+ obj Object
+ index []int
+ indirect bool
+ )
+
+ sel := e.Sel.Name
+ // If the identifier refers to a package, handle everything here
+ // so we don't need a "package" mode for operands: package names
+ // can only appear in qualified identifiers which are mapped to
+ // selector expressions.
+ if ident, ok := e.X.(*ast.Ident); ok {
+ _, obj := check.scope.LookupParent(ident.Name, check.pos)
+ if pkg, _ := obj.(*PkgName); pkg != nil {
+ assert(pkg.pkg == check.pkg)
+ check.recordUse(ident, pkg)
+ pkg.used = true
+ exp := pkg.imported.scope.Lookup(sel)
+ if exp == nil {
+ if !pkg.imported.fake {
+ check.errorf(e.Pos(), "%s not declared by package %s", sel, ident)
+ }
+ goto Error
+ }
+ if !exp.Exported() {
+ check.errorf(e.Pos(), "%s not exported by package %s", sel, ident)
+ // ok to continue
+ }
+ check.recordUse(e.Sel, exp)
+ // Simplified version of the code for *ast.Idents:
+ // - imported objects are always fully initialized
+ switch exp := exp.(type) {
+ case *Const:
+ assert(exp.Val() != nil)
+ x.mode = constant
+ x.typ = exp.typ
+ x.val = exp.val
+ case *TypeName:
+ x.mode = typexpr
+ x.typ = exp.typ
+ case *Var:
+ x.mode = variable
+ x.typ = exp.typ
+ case *Func:
+ x.mode = value
+ x.typ = exp.typ
+ case *Builtin:
+ x.mode = builtin
+ x.typ = exp.typ
+ x.id = exp.id
+ default:
+ unreachable()
+ }
+ x.expr = e
+ return
+ }
+ }
+
+ check.exprOrType(x, e.X)
+ if x.mode == invalid {
+ goto Error
+ }
+
+ obj, index, indirect = LookupFieldOrMethod(x.typ, x.mode == variable, check.pkg, sel)
+ if obj == nil {
+ switch {
+ case index != nil:
+ // TODO(gri) should provide actual type where the conflict happens
+ check.invalidOp(e.Pos(), "ambiguous selector %s", sel)
+ case indirect:
+ check.invalidOp(e.Pos(), "%s is not in method set of %s", sel, x.typ)
+ default:
+ check.invalidOp(e.Pos(), "%s has no field or method %s", x, sel)
+ }
+ goto Error
+ }
+
+ if x.mode == typexpr {
+ // method expression
+ m, _ := obj.(*Func)
+ if m == nil {
+ check.invalidOp(e.Pos(), "%s has no method %s", x, sel)
+ goto Error
+ }
+
+ check.recordSelection(e, MethodExpr, x.typ, m, index, indirect)
+
+ // the receiver type becomes the type of the first function
+ // argument of the method expression's function type
+ var params []*Var
+ sig := m.typ.(*Signature)
+ if sig.params != nil {
+ params = sig.params.vars
+ }
+ x.mode = value
+ x.typ = &Signature{
+ params: NewTuple(append([]*Var{NewVar(token.NoPos, check.pkg, "", x.typ)}, params...)...),
+ results: sig.results,
+ variadic: sig.variadic,
+ }
+
+ check.addDeclDep(m)
+
+ } else {
+ // regular selector
+ switch obj := obj.(type) {
+ case *Var:
+ check.recordSelection(e, FieldVal, x.typ, obj, index, indirect)
+ if x.mode == variable || indirect {
+ x.mode = variable
+ } else {
+ x.mode = value
+ }
+ x.typ = obj.typ
+
+ case *Func:
+ // TODO(gri) If we needed to take into account the receiver's
+ // addressability, should we report the type &(x.typ) instead?
+ check.recordSelection(e, MethodVal, x.typ, obj, index, indirect)
+
+ if debug {
+ // Verify that LookupFieldOrMethod and MethodSet.Lookup agree.
+ typ := x.typ
+ if x.mode == variable {
+ // If typ is not an (unnamed) pointer or an interface,
+ // use *typ instead, because the method set of *typ
+ // includes the methods of typ.
+ // Variables are addressable, so we can always take their
+ // address.
+ if _, ok := typ.(*Pointer); !ok && !IsInterface(typ) {
+ typ = &Pointer{base: typ}
+ }
+ }
+ // If we created a synthetic pointer type above, we will throw
+ // away the method set computed here after use.
+ // TODO(gri) Method set computation should probably always compute
+ // both, the value and the pointer receiver method set and represent
+ // them in a single structure.
+ // TODO(gri) Consider also using a method set cache for the lifetime
+ // of checker once we rely on MethodSet lookup instead of individual
+ // lookup.
+ mset := NewMethodSet(typ)
+ if m := mset.Lookup(check.pkg, sel); m == nil || m.obj != obj {
+ check.dump("%s: (%s).%v -> %s", e.Pos(), typ, obj.name, m)
+ check.dump("%s\n", mset)
+ panic("method sets and lookup don't agree")
+ }
+ }
+
+ x.mode = value
+
+ // remove receiver
+ sig := *obj.typ.(*Signature)
+ sig.recv = nil
+ x.typ = &sig
+
+ check.addDeclDep(obj)
+
+ default:
+ unreachable()
+ }
+ }
+
+ // everything went well
+ x.expr = e
+ return
+
+Error:
+ x.mode = invalid
+ x.expr = e
+}
diff --git a/vendor/golang.org/x/tools/go/types/check.go b/vendor/golang.org/x/tools/go/types/check.go
new file mode 100644
index 0000000..964d2bd
--- /dev/null
+++ b/vendor/golang.org/x/tools/go/types/check.go
@@ -0,0 +1,364 @@
+// Copyright 2011 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// This file implements the Check function, which drives type-checking.
+
+package types
+
+import (
+ "go/ast"
+ "go/token"
+
+ "golang.org/x/tools/go/exact"
+)
+
+// debugging/development support
+const (
+ debug = false // leave on during development
+ trace = false // turn on for detailed type resolution traces
+)
+
+// If Strict is set, the type-checker enforces additional
+// rules not specified by the Go 1 spec, but which will
+// catch guaranteed run-time errors if the respective
+// code is executed. In other words, programs passing in
+// Strict mode are Go 1 compliant, but not all Go 1 programs
+// will pass in Strict mode. The additional rules are:
+//
+// - A type assertion x.(T) where T is an interface type
+// is invalid if any (statically known) method that exists
+// for both x and T have different signatures.
+//
+const strict = false
+
+// exprInfo stores information about an untyped expression.
+type exprInfo struct {
+ isLhs bool // expression is lhs operand of a shift with delayed type-check
+ mode operandMode
+ typ *Basic
+ val exact.Value // constant value; or nil (if not a constant)
+}
+
+// funcInfo stores the information required for type-checking a function.
+type funcInfo struct {
+ name string // for debugging/tracing only
+ decl *declInfo // for cycle detection
+ sig *Signature
+ body *ast.BlockStmt
+}
+
+// A context represents the context within which an object is type-checked.
+type context struct {
+ decl *declInfo // package-level declaration whose init expression/function body is checked
+ scope *Scope // top-most scope for lookups
+ iota exact.Value // value of iota in a constant declaration; nil otherwise
+ sig *Signature // function signature if inside a function; nil otherwise
+ hasLabel bool // set if a function makes use of labels (only ~1% of functions); unused outside functions
+ hasCallOrRecv bool // set if an expression contains a function call or channel receive operation
+}
+
+// A Checker maintains the state of the type checker.
+// It must be created with NewChecker.
+type Checker struct {
+ // package information
+ // (initialized by NewChecker, valid for the life-time of checker)
+ conf *Config
+ fset *token.FileSet
+ pkg *Package
+ *Info
+ objMap map[Object]*declInfo // maps package-level object to declaration info
+
+ // information collected during type-checking of a set of package files
+ // (initialized by Files, valid only for the duration of check.Files;
+ // maps and lists are allocated on demand)
+ files []*ast.File // package files
+ unusedDotImports map[*Scope]map[*Package]token.Pos // positions of unused dot-imported packages for each file scope
+
+ firstErr error // first error encountered
+ methods map[string][]*Func // maps type names to associated methods
+ untyped map[ast.Expr]exprInfo // map of expressions without final type
+ funcs []funcInfo // list of functions to type-check
+ delayed []func() // delayed checks requiring fully setup types
+
+ // context within which the current object is type-checked
+ // (valid only for the duration of type-checking a specific object)
+ context
+ pos token.Pos // if valid, identifiers are looked up as if at position pos (used by Eval)
+
+ // debugging
+ indent int // indentation for tracing
+}
+
+// addUnusedImport adds the position of a dot-imported package
+// pkg to the map of dot imports for the given file scope.
+func (check *Checker) addUnusedDotImport(scope *Scope, pkg *Package, pos token.Pos) {
+ mm := check.unusedDotImports
+ if mm == nil {
+ mm = make(map[*Scope]map[*Package]token.Pos)
+ check.unusedDotImports = mm
+ }
+ m := mm[scope]
+ if m == nil {
+ m = make(map[*Package]token.Pos)
+ mm[scope] = m
+ }
+ m[pkg] = pos
+}
+
+// addDeclDep adds the dependency edge (check.decl -> to) if check.decl exists
+func (check *Checker) addDeclDep(to Object) {
+ from := check.decl
+ if from == nil {
+ return // not in a package-level init expression
+ }
+ if _, found := check.objMap[to]; !found {
+ return // to is not a package-level object
+ }
+ from.addDep(to)
+}
+
+func (check *Checker) assocMethod(tname string, meth *Func) {
+ m := check.methods
+ if m == nil {
+ m = make(map[string][]*Func)
+ check.methods = m
+ }
+ m[tname] = append(m[tname], meth)
+}
+
+func (check *Checker) rememberUntyped(e ast.Expr, lhs bool, mode operandMode, typ *Basic, val exact.Value) {
+ m := check.untyped
+ if m == nil {
+ m = make(map[ast.Expr]exprInfo)
+ check.untyped = m
+ }
+ m[e] = exprInfo{lhs, mode, typ, val}
+}
+
+func (check *Checker) later(name string, decl *declInfo, sig *Signature, body *ast.BlockStmt) {
+ check.funcs = append(check.funcs, funcInfo{name, decl, sig, body})
+}
+
+func (check *Checker) delay(f func()) {
+ check.delayed = append(check.delayed, f)
+}
+
+// NewChecker returns a new Checker instance for a given package.
+// Package files may be added incrementally via checker.Files.
+func NewChecker(conf *Config, fset *token.FileSet, pkg *Package, info *Info) *Checker {
+ // make sure we have a configuration
+ if conf == nil {
+ conf = new(Config)
+ }
+
+ // make sure we have a package canonicalization map
+ if conf.Packages == nil {
+ conf.Packages = make(map[string]*Package)
+ }
+
+ // make sure we have an info struct
+ if info == nil {
+ info = new(Info)
+ }
+
+ return &Checker{
+ conf: conf,
+ fset: fset,
+ pkg: pkg,
+ Info: info,
+ objMap: make(map[Object]*declInfo),
+ }
+}
+
+// initFiles initializes the files-specific portion of checker.
+// The provided files must all belong to the same package.
+func (check *Checker) initFiles(files []*ast.File) {
+ // start with a clean slate (check.Files may be called multiple times)
+ check.files = nil
+ check.unusedDotImports = nil
+
+ check.firstErr = nil
+ check.methods = nil
+ check.untyped = nil
+ check.funcs = nil
+ check.delayed = nil
+
+ // determine package name and collect valid files
+ pkg := check.pkg
+ for _, file := range files {
+ switch name := file.Name.Name; pkg.name {
+ case "":
+ if name != "_" {
+ pkg.name = name
+ } else {
+ check.errorf(file.Name.Pos(), "invalid package name _")
+ }
+ fallthrough
+
+ case name:
+ check.files = append(check.files, file)
+
+ default:
+ check.errorf(file.Package, "package %s; expected %s", name, pkg.name)
+ // ignore this file
+ }
+ }
+}
+
+// A bailout panic is used for early termination.
+type bailout struct{}
+
+func (check *Checker) handleBailout(err *error) {
+ switch p := recover().(type) {
+ case nil, bailout:
+ // normal return or early exit
+ *err = check.firstErr
+ default:
+ // re-panic
+ panic(p)
+ }
+}
+
+// Files checks the provided files as part of the checker's package.
+func (check *Checker) Files(files []*ast.File) (err error) {
+ defer check.handleBailout(&err)
+
+ check.initFiles(files)
+
+ check.collectObjects()
+
+ check.packageObjects(check.resolveOrder())
+
+ check.functionBodies()
+
+ check.initOrder()
+
+ if !check.conf.DisableUnusedImportCheck {
+ check.unusedImports()
+ }
+
+ // perform delayed checks
+ for _, f := range check.delayed {
+ f()
+ }
+
+ check.recordUntyped()
+
+ check.pkg.complete = true
+ return
+}
+
+func (check *Checker) recordUntyped() {
+ if !debug && check.Types == nil {
+ return // nothing to do
+ }
+
+ for x, info := range check.untyped {
+ if debug && isTyped(info.typ) {
+ check.dump("%s: %s (type %s) is typed", x.Pos(), x, info.typ)
+ unreachable()
+ }
+ check.recordTypeAndValue(x, info.mode, info.typ, info.val)
+ }
+}
+
+func (check *Checker) recordTypeAndValue(x ast.Expr, mode operandMode, typ Type, val exact.Value) {
+ assert(x != nil)
+ assert(typ != nil)
+ if mode == invalid {
+ return // omit
+ }
+ assert(typ != nil)
+ if mode == constant {
+ assert(val != nil)
+ assert(typ == Typ[Invalid] || isConstType(typ))
+ }
+ if m := check.Types; m != nil {
+ m[x] = TypeAndValue{mode, typ, val}
+ }
+}
+
+func (check *Checker) recordBuiltinType(f ast.Expr, sig *Signature) {
+ // f must be a (possibly parenthesized) identifier denoting a built-in
+ // (built-ins in package unsafe always produce a constant result and
+ // we don't record their signatures, so we don't see qualified idents
+ // here): record the signature for f and possible children.
+ for {
+ check.recordTypeAndValue(f, builtin, sig, nil)
+ switch p := f.(type) {
+ case *ast.Ident:
+ return // we're done
+ case *ast.ParenExpr:
+ f = p.X
+ default:
+ unreachable()
+ }
+ }
+}
+
+func (check *Checker) recordCommaOkTypes(x ast.Expr, a [2]Type) {
+ assert(x != nil)
+ if a[0] == nil || a[1] == nil {
+ return
+ }
+ assert(isTyped(a[0]) && isTyped(a[1]) && isBoolean(a[1]))
+ if m := check.Types; m != nil {
+ for {
+ tv := m[x]
+ assert(tv.Type != nil) // should have been recorded already
+ pos := x.Pos()
+ tv.Type = NewTuple(
+ NewVar(pos, check.pkg, "", a[0]),
+ NewVar(pos, check.pkg, "", a[1]),
+ )
+ m[x] = tv
+ // if x is a parenthesized expression (p.X), update p.X
+ p, _ := x.(*ast.ParenExpr)
+ if p == nil {
+ break
+ }
+ x = p.X
+ }
+ }
+}
+
+func (check *Checker) recordDef(id *ast.Ident, obj Object) {
+ assert(id != nil)
+ if m := check.Defs; m != nil {
+ m[id] = obj
+ }
+}
+
+func (check *Checker) recordUse(id *ast.Ident, obj Object) {
+ assert(id != nil)
+ assert(obj != nil)
+ if m := check.Uses; m != nil {
+ m[id] = obj
+ }
+}
+
+func (check *Checker) recordImplicit(node ast.Node, obj Object) {
+ assert(node != nil)
+ assert(obj != nil)
+ if m := check.Implicits; m != nil {
+ m[node] = obj
+ }
+}
+
+func (check *Checker) recordSelection(x *ast.SelectorExpr, kind SelectionKind, recv Type, obj Object, index []int, indirect bool) {
+ assert(obj != nil && (recv == nil || len(index) > 0))
+ check.recordUse(x.Sel, obj)
+ // TODO(gri) Should we also call recordTypeAndValue?
+ if m := check.Selections; m != nil {
+ m[x] = &Selection{kind, recv, obj, index, indirect}
+ }
+}
+
+func (check *Checker) recordScope(node ast.Node, scope *Scope) {
+ assert(node != nil)
+ assert(scope != nil)
+ if m := check.Scopes; m != nil {
+ m[node] = scope
+ }
+}
diff --git a/vendor/golang.org/x/tools/go/types/conversions.go b/vendor/golang.org/x/tools/go/types/conversions.go
new file mode 100644
index 0000000..6e279ca
--- /dev/null
+++ b/vendor/golang.org/x/tools/go/types/conversions.go
@@ -0,0 +1,146 @@
+// Copyright 2012 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// This file implements typechecking of conversions.
+
+package types
+
+import "golang.org/x/tools/go/exact"
+
+// Conversion type-checks the conversion T(x).
+// The result is in x.
+func (check *Checker) conversion(x *operand, T Type) {
+ constArg := x.mode == constant
+
+ var ok bool
+ switch {
+ case constArg && isConstType(T):
+ // constant conversion
+ switch t := T.Underlying().(*Basic); {
+ case representableConst(x.val, check.conf, t.kind, &x.val):
+ ok = true
+ case isInteger(x.typ) && isString(t):
+ codepoint := int64(-1)
+ if i, ok := exact.Int64Val(x.val); ok {
+ codepoint = i
+ }
+ // If codepoint < 0 the absolute value is too large (or unknown) for
+ // conversion. This is the same as converting any other out-of-range
+ // value - let string(codepoint) do the work.
+ x.val = exact.MakeString(string(codepoint))
+ ok = true
+ }
+ case x.convertibleTo(check.conf, T):
+ // non-constant conversion
+ x.mode = value
+ ok = true
+ }
+
+ if !ok {
+ check.errorf(x.pos(), "cannot convert %s to %s", x, T)
+ x.mode = invalid
+ return
+ }
+
+ // The conversion argument types are final. For untyped values the
+ // conversion provides the type, per the spec: "A constant may be
+ // given a type explicitly by a constant declaration or conversion,...".
+ final := x.typ
+ if isUntyped(x.typ) {
+ final = T
+ // - For conversions to interfaces, use the argument's default type.
+ // - For conversions of untyped constants to non-constant types, also
+ // use the default type (e.g., []byte("foo") should report string
+ // not []byte as type for the constant "foo").
+ // - Keep untyped nil for untyped nil arguments.
+ if IsInterface(T) || constArg && !isConstType(T) {
+ final = defaultType(x.typ)
+ }
+ check.updateExprType(x.expr, final, true)
+ }
+
+ x.typ = T
+}
+
+func (x *operand) convertibleTo(conf *Config, T Type) bool {
+ // "x is assignable to T"
+ if x.assignableTo(conf, T) {
+ return true
+ }
+
+ // "x's type and T have identical underlying types"
+ V := x.typ
+ Vu := V.Underlying()
+ Tu := T.Underlying()
+ if Identical(Vu, Tu) {
+ return true
+ }
+
+ // "x's type and T are unnamed pointer types and their pointer base types have identical underlying types"
+ if V, ok := V.(*Pointer); ok {
+ if T, ok := T.(*Pointer); ok {
+ if Identical(V.base.Underlying(), T.base.Underlying()) {
+ return true
+ }
+ }
+ }
+
+ // "x's type and T are both integer or floating point types"
+ if (isInteger(V) || isFloat(V)) && (isInteger(T) || isFloat(T)) {
+ return true
+ }
+
+ // "x's type and T are both complex types"
+ if isComplex(V) && isComplex(T) {
+ return true
+ }
+
+ // "x is an integer or a slice of bytes or runes and T is a string type"
+ if (isInteger(V) || isBytesOrRunes(Vu)) && isString(T) {
+ return true
+ }
+
+ // "x is a string and T is a slice of bytes or runes"
+ if isString(V) && isBytesOrRunes(Tu) {
+ return true
+ }
+
+ // package unsafe:
+ // "any pointer or value of underlying type uintptr can be converted into a unsafe.Pointer"
+ if (isPointer(Vu) || isUintptr(Vu)) && isUnsafePointer(T) {
+ return true
+ }
+ // "and vice versa"
+ if isUnsafePointer(V) && (isPointer(Tu) || isUintptr(Tu)) {
+ return true
+ }
+
+ return false
+}
+
+func isUintptr(typ Type) bool {
+ t, ok := typ.Underlying().(*Basic)
+ return ok && t.kind == Uintptr
+}
+
+func isUnsafePointer(typ Type) bool {
+ // TODO(gri): Is this (typ.Underlying() instead of just typ) correct?
+ // The spec does not say so, but gc claims it is. See also
+ // issue 6326.
+ t, ok := typ.Underlying().(*Basic)
+ return ok && t.kind == UnsafePointer
+}
+
+func isPointer(typ Type) bool {
+ _, ok := typ.Underlying().(*Pointer)
+ return ok
+}
+
+func isBytesOrRunes(typ Type) bool {
+ if s, ok := typ.(*Slice); ok {
+ t, ok := s.elem.Underlying().(*Basic)
+ return ok && (t.kind == Byte || t.kind == Rune)
+ }
+ return false
+}
diff --git a/vendor/golang.org/x/tools/go/types/decl.go b/vendor/golang.org/x/tools/go/types/decl.go
new file mode 100644
index 0000000..9eba85c
--- /dev/null
+++ b/vendor/golang.org/x/tools/go/types/decl.go
@@ -0,0 +1,431 @@
+// Copyright 2014 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package types
+
+import (
+ "go/ast"
+ "go/token"
+
+ "golang.org/x/tools/go/exact"
+)
+
+func (check *Checker) reportAltDecl(obj Object) {
+ if pos := obj.Pos(); pos.IsValid() {
+ // We use "other" rather than "previous" here because
+ // the first declaration seen may not be textually
+ // earlier in the source.
+ check.errorf(pos, "\tother declaration of %s", obj.Name()) // secondary error, \t indented
+ }
+}
+
+func (check *Checker) declare(scope *Scope, id *ast.Ident, obj Object, pos token.Pos) {
+ // spec: "The blank identifier, represented by the underscore
+ // character _, may be used in a declaration like any other
+ // identifier but the declaration does not introduce a new
+ // binding."
+ if obj.Name() != "_" {
+ if alt := scope.Insert(obj); alt != nil {
+ check.errorf(obj.Pos(), "%s redeclared in this block", obj.Name())
+ check.reportAltDecl(alt)
+ return
+ }
+ obj.setScopePos(pos)
+ }
+ if id != nil {
+ check.recordDef(id, obj)
+ }
+}
+
+// objDecl type-checks the declaration of obj in its respective (file) context.
+// See check.typ for the details on def and path.
+func (check *Checker) objDecl(obj Object, def *Named, path []*TypeName) {
+ if obj.Type() != nil {
+ return // already checked - nothing to do
+ }
+
+ if trace {
+ check.trace(obj.Pos(), "-- declaring %s", obj.Name())
+ check.indent++
+ defer func() {
+ check.indent--
+ check.trace(obj.Pos(), "=> %s", obj)
+ }()
+ }
+
+ d := check.objMap[obj]
+ if d == nil {
+ check.dump("%s: %s should have been declared", obj.Pos(), obj.Name())
+ unreachable()
+ }
+
+ // save/restore current context and setup object context
+ defer func(ctxt context) {
+ check.context = ctxt
+ }(check.context)
+ check.context = context{
+ scope: d.file,
+ }
+
+ // Const and var declarations must not have initialization
+ // cycles. We track them by remembering the current declaration
+ // in check.decl. Initialization expressions depending on other
+ // consts, vars, or functions, add dependencies to the current
+ // check.decl.
+ switch obj := obj.(type) {
+ case *Const:
+ check.decl = d // new package-level const decl
+ check.constDecl(obj, d.typ, d.init)
+ case *Var:
+ check.decl = d // new package-level var decl
+ check.varDecl(obj, d.lhs, d.typ, d.init)
+ case *TypeName:
+ // invalid recursive types are detected via path
+ check.typeDecl(obj, d.typ, def, path)
+ case *Func:
+ // functions may be recursive - no need to track dependencies
+ check.funcDecl(obj, d)
+ default:
+ unreachable()
+ }
+}
+
+func (check *Checker) constDecl(obj *Const, typ, init ast.Expr) {
+ assert(obj.typ == nil)
+
+ if obj.visited {
+ obj.typ = Typ[Invalid]
+ return
+ }
+ obj.visited = true
+
+ // use the correct value of iota
+ assert(check.iota == nil)
+ check.iota = obj.val
+ defer func() { check.iota = nil }()
+
+ // provide valid constant value under all circumstances
+ obj.val = exact.MakeUnknown()
+
+ // determine type, if any
+ if typ != nil {
+ t := check.typ(typ)
+ if !isConstType(t) {
+ check.errorf(typ.Pos(), "invalid constant type %s", t)
+ obj.typ = Typ[Invalid]
+ return
+ }
+ obj.typ = t
+ }
+
+ // check initialization
+ var x operand
+ if init != nil {
+ check.expr(&x, init)
+ }
+ check.initConst(obj, &x)
+}
+
+func (check *Checker) varDecl(obj *Var, lhs []*Var, typ, init ast.Expr) {
+ assert(obj.typ == nil)
+
+ if obj.visited {
+ obj.typ = Typ[Invalid]
+ return
+ }
+ obj.visited = true
+
+ // var declarations cannot use iota
+ assert(check.iota == nil)
+
+ // determine type, if any
+ if typ != nil {
+ obj.typ = check.typ(typ)
+ }
+
+ // check initialization
+ if init == nil {
+ if typ == nil {
+ // error reported before by arityMatch
+ obj.typ = Typ[Invalid]
+ }
+ return
+ }
+
+ if lhs == nil || len(lhs) == 1 {
+ assert(lhs == nil || lhs[0] == obj)
+ var x operand
+ check.expr(&x, init)
+ check.initVar(obj, &x, false)
+ return
+ }
+
+ if debug {
+ // obj must be one of lhs
+ found := false
+ for _, lhs := range lhs {
+ if obj == lhs {
+ found = true
+ break
+ }
+ }
+ if !found {
+ panic("inconsistent lhs")
+ }
+ }
+ check.initVars(lhs, []ast.Expr{init}, token.NoPos)
+}
+
+// underlying returns the underlying type of typ; possibly by following
+// forward chains of named types. Such chains only exist while named types
+// are incomplete.
+func underlying(typ Type) Type {
+ for {
+ n, _ := typ.(*Named)
+ if n == nil {
+ break
+ }
+ typ = n.underlying
+ }
+ return typ
+}
+
+func (n *Named) setUnderlying(typ Type) {
+ if n != nil {
+ n.underlying = typ
+ }
+}
+
+func (check *Checker) typeDecl(obj *TypeName, typ ast.Expr, def *Named, path []*TypeName) {
+ assert(obj.typ == nil)
+
+ // type declarations cannot use iota
+ assert(check.iota == nil)
+
+ named := &Named{obj: obj}
+ def.setUnderlying(named)
+ obj.typ = named // make sure recursive type declarations terminate
+
+ // determine underlying type of named
+ check.typExpr(typ, named, append(path, obj))
+
+ // The underlying type of named may be itself a named type that is
+ // incomplete:
+ //
+ // type (
+ // A B
+ // B *C
+ // C A
+ // )
+ //
+ // The type of C is the (named) type of A which is incomplete,
+ // and which has as its underlying type the named type B.
+ // Determine the (final, unnamed) underlying type by resolving
+ // any forward chain (they always end in an unnamed type).
+ named.underlying = underlying(named.underlying)
+
+ // check and add associated methods
+ // TODO(gri) It's easy to create pathological cases where the
+ // current approach is incorrect: In general we need to know
+ // and add all methods _before_ type-checking the type.
+ // See http://play.golang.org/p/WMpE0q2wK8
+ check.addMethodDecls(obj)
+}
+
+func (check *Checker) addMethodDecls(obj *TypeName) {
+ // get associated methods
+ methods := check.methods[obj.name]
+ if len(methods) == 0 {
+ return // no methods
+ }
+ delete(check.methods, obj.name)
+
+ // use an objset to check for name conflicts
+ var mset objset
+
+ // spec: "If the base type is a struct type, the non-blank method
+ // and field names must be distinct."
+ base := obj.typ.(*Named)
+ if t, _ := base.underlying.(*Struct); t != nil {
+ for _, fld := range t.fields {
+ if fld.name != "_" {
+ assert(mset.insert(fld) == nil)
+ }
+ }
+ }
+
+ // Checker.Files may be called multiple times; additional package files
+ // may add methods to already type-checked types. Add pre-existing methods
+ // so that we can detect redeclarations.
+ for _, m := range base.methods {
+ assert(m.name != "_")
+ assert(mset.insert(m) == nil)
+ }
+
+ // type-check methods
+ for _, m := range methods {
+ // spec: "For a base type, the non-blank names of methods bound
+ // to it must be unique."
+ if m.name != "_" {
+ if alt := mset.insert(m); alt != nil {
+ switch alt.(type) {
+ case *Var:
+ check.errorf(m.pos, "field and method with the same name %s", m.name)
+ case *Func:
+ check.errorf(m.pos, "method %s already declared for %s", m.name, base)
+ default:
+ unreachable()
+ }
+ check.reportAltDecl(alt)
+ continue
+ }
+ }
+ check.objDecl(m, nil, nil)
+ // methods with blank _ names cannot be found - don't keep them
+ if m.name != "_" {
+ base.methods = append(base.methods, m)
+ }
+ }
+}
+
+func (check *Checker) funcDecl(obj *Func, decl *declInfo) {
+ assert(obj.typ == nil)
+
+ // func declarations cannot use iota
+ assert(check.iota == nil)
+
+ sig := new(Signature)
+ obj.typ = sig // guard against cycles
+ fdecl := decl.fdecl
+ check.funcType(sig, fdecl.Recv, fdecl.Type)
+ if sig.recv == nil && obj.name == "init" && (sig.params.Len() > 0 || sig.results.Len() > 0) {
+ check.errorf(fdecl.Pos(), "func init must have no arguments and no return values")
+ // ok to continue
+ }
+
+ // function body must be type-checked after global declarations
+ // (functions implemented elsewhere have no body)
+ if !check.conf.IgnoreFuncBodies && fdecl.Body != nil {
+ check.later(obj.name, decl, sig, fdecl.Body)
+ }
+}
+
+func (check *Checker) declStmt(decl ast.Decl) {
+ pkg := check.pkg
+
+ switch d := decl.(type) {
+ case *ast.BadDecl:
+ // ignore
+
+ case *ast.GenDecl:
+ var last *ast.ValueSpec // last ValueSpec with type or init exprs seen
+ for iota, spec := range d.Specs {
+ switch s := spec.(type) {
+ case *ast.ValueSpec:
+ switch d.Tok {
+ case token.CONST:
+ // determine which init exprs to use
+ switch {
+ case s.Type != nil || len(s.Values) > 0:
+ last = s
+ case last == nil:
+ last = new(ast.ValueSpec) // make sure last exists
+ }
+
+ // declare all constants
+ lhs := make([]*Const, len(s.Names))
+ for i, name := range s.Names {
+ obj := NewConst(name.Pos(), pkg, name.Name, nil, exact.MakeInt64(int64(iota)))
+ lhs[i] = obj
+
+ var init ast.Expr
+ if i < len(last.Values) {
+ init = last.Values[i]
+ }
+
+ check.constDecl(obj, last.Type, init)
+ }
+
+ check.arityMatch(s, last)
+
+ // spec: "The scope of a constant or variable identifier declared
+ // inside a function begins at the end of the ConstSpec or VarSpec
+ // (ShortVarDecl for short variable declarations) and ends at the
+ // end of the innermost containing block."
+ scopePos := s.End()
+ for i, name := range s.Names {
+ check.declare(check.scope, name, lhs[i], scopePos)
+ }
+
+ case token.VAR:
+ lhs0 := make([]*Var, len(s.Names))
+ for i, name := range s.Names {
+ lhs0[i] = NewVar(name.Pos(), pkg, name.Name, nil)
+ }
+
+ // initialize all variables
+ for i, obj := range lhs0 {
+ var lhs []*Var
+ var init ast.Expr
+ switch len(s.Values) {
+ case len(s.Names):
+ // lhs and rhs match
+ init = s.Values[i]
+ case 1:
+ // rhs is expected to be a multi-valued expression
+ lhs = lhs0
+ init = s.Values[0]
+ default:
+ if i < len(s.Values) {
+ init = s.Values[i]
+ }
+ }
+ check.varDecl(obj, lhs, s.Type, init)
+ if len(s.Values) == 1 {
+ // If we have a single lhs variable we are done either way.
+ // If we have a single rhs expression, it must be a multi-
+ // valued expression, in which case handling the first lhs
+ // variable will cause all lhs variables to have a type
+ // assigned, and we are done as well.
+ if debug {
+ for _, obj := range lhs0 {
+ assert(obj.typ != nil)
+ }
+ }
+ break
+ }
+ }
+
+ check.arityMatch(s, nil)
+
+ // declare all variables
+ // (only at this point are the variable scopes (parents) set)
+ scopePos := s.End() // see constant declarations
+ for i, name := range s.Names {
+ // see constant declarations
+ check.declare(check.scope, name, lhs0[i], scopePos)
+ }
+
+ default:
+ check.invalidAST(s.Pos(), "invalid token %s", d.Tok)
+ }
+
+ case *ast.TypeSpec:
+ obj := NewTypeName(s.Name.Pos(), pkg, s.Name.Name, nil)
+ // spec: "The scope of a type identifier declared inside a function
+ // begins at the identifier in the TypeSpec and ends at the end of
+ // the innermost containing block."
+ scopePos := s.Name.Pos()
+ check.declare(check.scope, s.Name, obj, scopePos)
+ check.typeDecl(obj, s.Type, nil, nil)
+
+ default:
+ check.invalidAST(s.Pos(), "const, type, or var declaration expected")
+ }
+ }
+
+ default:
+ check.invalidAST(d.Pos(), "unknown ast.Decl node %T", d)
+ }
+}
diff --git a/vendor/golang.org/x/tools/go/types/errors.go b/vendor/golang.org/x/tools/go/types/errors.go
new file mode 100644
index 0000000..0c0049b
--- /dev/null
+++ b/vendor/golang.org/x/tools/go/types/errors.go
@@ -0,0 +1,103 @@
+// Copyright 2012 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// This file implements various error reporters.
+
+package types
+
+import (
+ "fmt"
+ "go/ast"
+ "go/token"
+ "strings"
+)
+
+func assert(p bool) {
+ if !p {
+ panic("assertion failed")
+ }
+}
+
+func unreachable() {
+ panic("unreachable")
+}
+
+func (check *Checker) qualifier(pkg *Package) string {
+ if pkg != check.pkg {
+ return pkg.path
+ }
+ return ""
+}
+
+func (check *Checker) sprintf(format string, args ...interface{}) string {
+ for i, arg := range args {
+ switch a := arg.(type) {
+ case nil:
+ arg = ""
+ case operand:
+ panic("internal error: should always pass *operand")
+ case *operand:
+ arg = operandString(a, check.qualifier)
+ case token.Pos:
+ arg = check.fset.Position(a).String()
+ case ast.Expr:
+ arg = ExprString(a)
+ case Object:
+ arg = ObjectString(a, check.qualifier)
+ case Type:
+ arg = TypeString(a, check.qualifier)
+ }
+ args[i] = arg
+ }
+ return fmt.Sprintf(format, args...)
+}
+
+func (check *Checker) trace(pos token.Pos, format string, args ...interface{}) {
+ fmt.Printf("%s:\t%s%s\n",
+ check.fset.Position(pos),
+ strings.Repeat(". ", check.indent),
+ check.sprintf(format, args...),
+ )
+}
+
+// dump is only needed for debugging
+func (check *Checker) dump(format string, args ...interface{}) {
+ fmt.Println(check.sprintf(format, args...))
+}
+
+func (check *Checker) err(pos token.Pos, msg string, soft bool) {
+ err := Error{check.fset, pos, msg, soft}
+ if check.firstErr == nil {
+ check.firstErr = err
+ }
+ f := check.conf.Error
+ if f == nil {
+ panic(bailout{}) // report only first error
+ }
+ f(err)
+}
+
+func (check *Checker) error(pos token.Pos, msg string) {
+ check.err(pos, msg, false)
+}
+
+func (check *Checker) errorf(pos token.Pos, format string, args ...interface{}) {
+ check.err(pos, check.sprintf(format, args...), false)
+}
+
+func (check *Checker) softErrorf(pos token.Pos, format string, args ...interface{}) {
+ check.err(pos, check.sprintf(format, args...), true)
+}
+
+func (check *Checker) invalidAST(pos token.Pos, format string, args ...interface{}) {
+ check.errorf(pos, "invalid AST: "+format, args...)
+}
+
+func (check *Checker) invalidArg(pos token.Pos, format string, args ...interface{}) {
+ check.errorf(pos, "invalid argument: "+format, args...)
+}
+
+func (check *Checker) invalidOp(pos token.Pos, format string, args ...interface{}) {
+ check.errorf(pos, "invalid operation: "+format, args...)
+}
diff --git a/vendor/golang.org/x/tools/go/types/eval.go b/vendor/golang.org/x/tools/go/types/eval.go
new file mode 100644
index 0000000..c09f2a3
--- /dev/null
+++ b/vendor/golang.org/x/tools/go/types/eval.go
@@ -0,0 +1,87 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package types
+
+import (
+ "fmt"
+ "go/parser"
+ "go/token"
+)
+
+// Eval returns the type and, if constant, the value for the
+// expression expr, evaluated at position pos of package pkg,
+// which must have been derived from type-checking an AST with
+// complete position information relative to the provided file
+// set.
+//
+// If the expression contains function literals, their bodies
+// are ignored (i.e., the bodies are not type-checked).
+//
+// If pkg == nil, the Universe scope is used and the provided
+// position pos is ignored. If pkg != nil, and pos is invalid,
+// the package scope is used. Otherwise, pos must belong to the
+// package.
+//
+// An error is returned if pos is not within the package or
+// if the node cannot be evaluated.
+//
+// Note: Eval should not be used instead of running Check to compute
+// types and values, but in addition to Check. Eval will re-evaluate
+// its argument each time, and it also does not know about the context
+// in which an expression is used (e.g., an assignment). Thus, top-
+// level untyped constants will return an untyped type rather then the
+// respective context-specific type.
+//
+func Eval(fset *token.FileSet, pkg *Package, pos token.Pos, expr string) (tv TypeAndValue, err error) {
+ // determine scope
+ var scope *Scope
+ if pkg == nil {
+ scope = Universe
+ pos = token.NoPos
+ } else if !pos.IsValid() {
+ scope = pkg.scope
+ } else {
+ // The package scope extent (position information) may be
+ // incorrect (files spread accross a wide range of fset
+ // positions) - ignore it and just consider its children
+ // (file scopes).
+ for _, fscope := range pkg.scope.children {
+ if scope = fscope.Innermost(pos); scope != nil {
+ break
+ }
+ }
+ if scope == nil || debug {
+ s := scope
+ for s != nil && s != pkg.scope {
+ s = s.parent
+ }
+ // s == nil || s == pkg.scope
+ if s == nil {
+ return TypeAndValue{}, fmt.Errorf("no position %s found in package %s", fset.Position(pos), pkg.name)
+ }
+ }
+ }
+
+ // parse expressions
+ // BUG(gri) In case of type-checking errors below, the type checker
+ // doesn't have the correct file set for expr. The correct
+ // solution requires a ParseExpr that uses the incoming
+ // file set fset.
+ node, err := parser.ParseExpr(expr)
+ if err != nil {
+ return TypeAndValue{}, err
+ }
+
+ // initialize checker
+ check := NewChecker(nil, fset, pkg, nil)
+ check.scope = scope
+ check.pos = pos
+ defer check.handleBailout(&err)
+
+ // evaluate node
+ var x operand
+ check.rawExpr(&x, node, nil)
+ return TypeAndValue{x.mode, x.typ, x.val}, err
+}
diff --git a/vendor/golang.org/x/tools/go/types/expr.go b/vendor/golang.org/x/tools/go/types/expr.go
new file mode 100644
index 0000000..6efc7b4
--- /dev/null
+++ b/vendor/golang.org/x/tools/go/types/expr.go
@@ -0,0 +1,1497 @@
+// Copyright 2012 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// This file implements typechecking of expressions.
+
+package types
+
+import (
+ "fmt"
+ "go/ast"
+ "go/token"
+ "math"
+
+ "golang.org/x/tools/go/exact"
+)
+
+/*
+Basic algorithm:
+
+Expressions are checked recursively, top down. Expression checker functions
+are generally of the form:
+
+ func f(x *operand, e *ast.Expr, ...)
+
+where e is the expression to be checked, and x is the result of the check.
+The check performed by f may fail in which case x.mode == invalid, and
+related error messages will have been issued by f.
+
+If a hint argument is present, it is the composite literal element type
+of an outer composite literal; it is used to type-check composite literal
+elements that have no explicit type specification in the source
+(e.g.: []T{{...}, {...}}, the hint is the type T in this case).
+
+All expressions are checked via rawExpr, which dispatches according
+to expression kind. Upon returning, rawExpr is recording the types and
+constant values for all expressions that have an untyped type (those types
+may change on the way up in the expression tree). Usually these are constants,
+but the results of comparisons or non-constant shifts of untyped constants
+may also be untyped, but not constant.
+
+Untyped expressions may eventually become fully typed (i.e., not untyped),
+typically when the value is assigned to a variable, or is used otherwise.
+The updateExprType method is used to record this final type and update
+the recorded types: the type-checked expression tree is again traversed down,
+and the new type is propagated as needed. Untyped constant expression values
+that become fully typed must now be representable by the full type (constant
+sub-expression trees are left alone except for their roots). This mechanism
+ensures that a client sees the actual (run-time) type an untyped value would
+have. It also permits type-checking of lhs shift operands "as if the shift
+were not present": when updateExprType visits an untyped lhs shift operand
+and assigns it it's final type, that type must be an integer type, and a
+constant lhs must be representable as an integer.
+
+When an expression gets its final type, either on the way out from rawExpr,
+on the way down in updateExprType, or at the end of the type checker run,
+the type (and constant value, if any) is recorded via Info.Types, if present.
+*/
+
+type opPredicates map[token.Token]func(Type) bool
+
+var unaryOpPredicates = opPredicates{
+ token.ADD: isNumeric,
+ token.SUB: isNumeric,
+ token.XOR: isInteger,
+ token.NOT: isBoolean,
+}
+
+func (check *Checker) op(m opPredicates, x *operand, op token.Token) bool {
+ if pred := m[op]; pred != nil {
+ if !pred(x.typ) {
+ check.invalidOp(x.pos(), "operator %s not defined for %s", op, x)
+ return false
+ }
+ } else {
+ check.invalidAST(x.pos(), "unknown operator %s", op)
+ return false
+ }
+ return true
+}
+
+// The unary expression e may be nil. It's passed in for better error messages only.
+func (check *Checker) unary(x *operand, e *ast.UnaryExpr, op token.Token) {
+ switch op {
+ case token.AND:
+ // spec: "As an exception to the addressability
+ // requirement x may also be a composite literal."
+ if _, ok := unparen(x.expr).(*ast.CompositeLit); !ok && x.mode != variable {
+ check.invalidOp(x.pos(), "cannot take address of %s", x)
+ x.mode = invalid
+ return
+ }
+ x.mode = value
+ x.typ = &Pointer{base: x.typ}
+ return
+
+ case token.ARROW:
+ typ, ok := x.typ.Underlying().(*Chan)
+ if !ok {
+ check.invalidOp(x.pos(), "cannot receive from non-channel %s", x)
+ x.mode = invalid
+ return
+ }
+ if typ.dir == SendOnly {
+ check.invalidOp(x.pos(), "cannot receive from send-only channel %s", x)
+ x.mode = invalid
+ return
+ }
+ x.mode = commaok
+ x.typ = typ.elem
+ check.hasCallOrRecv = true
+ return
+ }
+
+ if !check.op(unaryOpPredicates, x, op) {
+ x.mode = invalid
+ return
+ }
+
+ if x.mode == constant {
+ typ := x.typ.Underlying().(*Basic)
+ size := -1
+ if isUnsigned(typ) {
+ size = int(check.conf.sizeof(typ))
+ }
+ x.val = exact.UnaryOp(op, x.val, size)
+ // Typed constants must be representable in
+ // their type after each constant operation.
+ if isTyped(typ) {
+ if e != nil {
+ x.expr = e // for better error message
+ }
+ check.representable(x, typ)
+ }
+ return
+ }
+
+ x.mode = value
+ // x.typ remains unchanged
+}
+
+func isShift(op token.Token) bool {
+ return op == token.SHL || op == token.SHR
+}
+
+func isComparison(op token.Token) bool {
+ // Note: tokens are not ordered well to make this much easier
+ switch op {
+ case token.EQL, token.NEQ, token.LSS, token.LEQ, token.GTR, token.GEQ:
+ return true
+ }
+ return false
+}
+
+func fitsFloat32(x exact.Value) bool {
+ f32, _ := exact.Float32Val(x)
+ f := float64(f32)
+ return !math.IsInf(f, 0)
+}
+
+func roundFloat32(x exact.Value) exact.Value {
+ f32, _ := exact.Float32Val(x)
+ f := float64(f32)
+ if !math.IsInf(f, 0) {
+ return exact.MakeFloat64(f)
+ }
+ return nil
+}
+
+func fitsFloat64(x exact.Value) bool {
+ f, _ := exact.Float64Val(x)
+ return !math.IsInf(f, 0)
+}
+
+func roundFloat64(x exact.Value) exact.Value {
+ f, _ := exact.Float64Val(x)
+ if !math.IsInf(f, 0) {
+ return exact.MakeFloat64(f)
+ }
+ return nil
+}
+
+// representableConst reports whether x can be represented as
+// value of the given basic type kind and for the configuration
+// provided (only needed for int/uint sizes).
+//
+// If rounded != nil, *rounded is set to the rounded value of x for
+// representable floating-point values; it is left alone otherwise.
+// It is ok to provide the addressof the first argument for rounded.
+func representableConst(x exact.Value, conf *Config, as BasicKind, rounded *exact.Value) bool {
+ switch x.Kind() {
+ case exact.Unknown:
+ return true
+
+ case exact.Bool:
+ return as == Bool || as == UntypedBool
+
+ case exact.Int:
+ if x, ok := exact.Int64Val(x); ok {
+ switch as {
+ case Int:
+ var s = uint(conf.sizeof(Typ[as])) * 8
+ return int64(-1)<<(s-1) <= x && x <= int64(1)<<(s-1)-1
+ case Int8:
+ const s = 8
+ return -1<<(s-1) <= x && x <= 1<<(s-1)-1
+ case Int16:
+ const s = 16
+ return -1<<(s-1) <= x && x <= 1<<(s-1)-1
+ case Int32:
+ const s = 32
+ return -1<<(s-1) <= x && x <= 1<<(s-1)-1
+ case Int64:
+ return true
+ case Uint, Uintptr:
+ if s := uint(conf.sizeof(Typ[as])) * 8; s < 64 {
+ return 0 <= x && x <= int64(1)<= 0 && n <= int(s)
+ case Uint64:
+ return exact.Sign(x) >= 0 && n <= 64
+ case Float32, Complex64:
+ if rounded == nil {
+ return fitsFloat32(x)
+ }
+ r := roundFloat32(x)
+ if r != nil {
+ *rounded = r
+ return true
+ }
+ case Float64, Complex128:
+ if rounded == nil {
+ return fitsFloat64(x)
+ }
+ r := roundFloat64(x)
+ if r != nil {
+ *rounded = r
+ return true
+ }
+ case UntypedInt, UntypedFloat, UntypedComplex:
+ return true
+ }
+
+ case exact.Float:
+ switch as {
+ case Float32, Complex64:
+ if rounded == nil {
+ return fitsFloat32(x)
+ }
+ r := roundFloat32(x)
+ if r != nil {
+ *rounded = r
+ return true
+ }
+ case Float64, Complex128:
+ if rounded == nil {
+ return fitsFloat64(x)
+ }
+ r := roundFloat64(x)
+ if r != nil {
+ *rounded = r
+ return true
+ }
+ case UntypedFloat, UntypedComplex:
+ return true
+ }
+
+ case exact.Complex:
+ switch as {
+ case Complex64:
+ if rounded == nil {
+ return fitsFloat32(exact.Real(x)) && fitsFloat32(exact.Imag(x))
+ }
+ re := roundFloat32(exact.Real(x))
+ im := roundFloat32(exact.Imag(x))
+ if re != nil && im != nil {
+ *rounded = exact.BinaryOp(re, token.ADD, exact.MakeImag(im))
+ return true
+ }
+ case Complex128:
+ if rounded == nil {
+ return fitsFloat64(exact.Real(x)) && fitsFloat64(exact.Imag(x))
+ }
+ re := roundFloat64(exact.Real(x))
+ im := roundFloat64(exact.Imag(x))
+ if re != nil && im != nil {
+ *rounded = exact.BinaryOp(re, token.ADD, exact.MakeImag(im))
+ return true
+ }
+ case UntypedComplex:
+ return true
+ }
+
+ case exact.String:
+ return as == String || as == UntypedString
+
+ default:
+ unreachable()
+ }
+
+ return false
+}
+
+// representable checks that a constant operand is representable in the given basic type.
+func (check *Checker) representable(x *operand, typ *Basic) {
+ assert(x.mode == constant)
+ if !representableConst(x.val, check.conf, typ.kind, &x.val) {
+ var msg string
+ if isNumeric(x.typ) && isNumeric(typ) {
+ // numeric conversion : error msg
+ //
+ // integer -> integer : overflows
+ // integer -> float : overflows (actually not possible)
+ // float -> integer : truncated
+ // float -> float : overflows
+ //
+ if !isInteger(x.typ) && isInteger(typ) {
+ msg = "%s truncated to %s"
+ } else {
+ msg = "%s overflows %s"
+ }
+ } else {
+ msg = "cannot convert %s to %s"
+ }
+ check.errorf(x.pos(), msg, x, typ)
+ x.mode = invalid
+ }
+}
+
+// updateExprType updates the type of x to typ and invokes itself
+// recursively for the operands of x, depending on expression kind.
+// If typ is still an untyped and not the final type, updateExprType
+// only updates the recorded untyped type for x and possibly its
+// operands. Otherwise (i.e., typ is not an untyped type anymore,
+// or it is the final type for x), the type and value are recorded.
+// Also, if x is a constant, it must be representable as a value of typ,
+// and if x is the (formerly untyped) lhs operand of a non-constant
+// shift, it must be an integer value.
+//
+func (check *Checker) updateExprType(x ast.Expr, typ Type, final bool) {
+ old, found := check.untyped[x]
+ if !found {
+ return // nothing to do
+ }
+
+ // update operands of x if necessary
+ switch x := x.(type) {
+ case *ast.BadExpr,
+ *ast.FuncLit,
+ *ast.CompositeLit,
+ *ast.IndexExpr,
+ *ast.SliceExpr,
+ *ast.TypeAssertExpr,
+ *ast.StarExpr,
+ *ast.KeyValueExpr,
+ *ast.ArrayType,
+ *ast.StructType,
+ *ast.FuncType,
+ *ast.InterfaceType,
+ *ast.MapType,
+ *ast.ChanType:
+ // These expression are never untyped - nothing to do.
+ // The respective sub-expressions got their final types
+ // upon assignment or use.
+ if debug {
+ check.dump("%s: found old type(%s): %s (new: %s)", x.Pos(), x, old.typ, typ)
+ unreachable()
+ }
+ return
+
+ case *ast.CallExpr:
+ // Resulting in an untyped constant (e.g., built-in complex).
+ // The respective calls take care of calling updateExprType
+ // for the arguments if necessary.
+
+ case *ast.Ident, *ast.BasicLit, *ast.SelectorExpr:
+ // An identifier denoting a constant, a constant literal,
+ // or a qualified identifier (imported untyped constant).
+ // No operands to take care of.
+
+ case *ast.ParenExpr:
+ check.updateExprType(x.X, typ, final)
+
+ case *ast.UnaryExpr:
+ // If x is a constant, the operands were constants.
+ // They don't need to be updated since they never
+ // get "materialized" into a typed value; and they
+ // will be processed at the end of the type check.
+ if old.val != nil {
+ break
+ }
+ check.updateExprType(x.X, typ, final)
+
+ case *ast.BinaryExpr:
+ if old.val != nil {
+ break // see comment for unary expressions
+ }
+ if isComparison(x.Op) {
+ // The result type is independent of operand types
+ // and the operand types must have final types.
+ } else if isShift(x.Op) {
+ // The result type depends only on lhs operand.
+ // The rhs type was updated when checking the shift.
+ check.updateExprType(x.X, typ, final)
+ } else {
+ // The operand types match the result type.
+ check.updateExprType(x.X, typ, final)
+ check.updateExprType(x.Y, typ, final)
+ }
+
+ default:
+ unreachable()
+ }
+
+ // If the new type is not final and still untyped, just
+ // update the recorded type.
+ if !final && isUntyped(typ) {
+ old.typ = typ.Underlying().(*Basic)
+ check.untyped[x] = old
+ return
+ }
+
+ // Otherwise we have the final (typed or untyped type).
+ // Remove it from the map of yet untyped expressions.
+ delete(check.untyped, x)
+
+ // If x is the lhs of a shift, its final type must be integer.
+ // We already know from the shift check that it is representable
+ // as an integer if it is a constant.
+ if old.isLhs && !isInteger(typ) {
+ check.invalidOp(x.Pos(), "shifted operand %s (type %s) must be integer", x, typ)
+ return
+ }
+
+ // Everything's fine, record final type and value for x.
+ check.recordTypeAndValue(x, old.mode, typ, old.val)
+}
+
+// updateExprVal updates the value of x to val.
+func (check *Checker) updateExprVal(x ast.Expr, val exact.Value) {
+ if info, ok := check.untyped[x]; ok {
+ info.val = val
+ check.untyped[x] = info
+ }
+}
+
+// convertUntyped attempts to set the type of an untyped value to the target type.
+func (check *Checker) convertUntyped(x *operand, target Type) {
+ if x.mode == invalid || isTyped(x.typ) || target == Typ[Invalid] {
+ return
+ }
+
+ // TODO(gri) Sloppy code - clean up. This function is central
+ // to assignment and expression checking.
+
+ if isUntyped(target) {
+ // both x and target are untyped
+ xkind := x.typ.(*Basic).kind
+ tkind := target.(*Basic).kind
+ if isNumeric(x.typ) && isNumeric(target) {
+ if xkind < tkind {
+ x.typ = target
+ check.updateExprType(x.expr, target, false)
+ }
+ } else if xkind != tkind {
+ goto Error
+ }
+ return
+ }
+
+ // typed target
+ switch t := target.Underlying().(type) {
+ case *Basic:
+ if x.mode == constant {
+ check.representable(x, t)
+ if x.mode == invalid {
+ return
+ }
+ // expression value may have been rounded - update if needed
+ // TODO(gri) A floating-point value may silently underflow to
+ // zero. If it was negative, the sign is lost. See issue 6898.
+ check.updateExprVal(x.expr, x.val)
+ } else {
+ // Non-constant untyped values may appear as the
+ // result of comparisons (untyped bool), intermediate
+ // (delayed-checked) rhs operands of shifts, and as
+ // the value nil.
+ switch x.typ.(*Basic).kind {
+ case UntypedBool:
+ if !isBoolean(target) {
+ goto Error
+ }
+ case UntypedInt, UntypedRune, UntypedFloat, UntypedComplex:
+ if !isNumeric(target) {
+ goto Error
+ }
+ case UntypedString:
+ // Non-constant untyped string values are not
+ // permitted by the spec and should not occur.
+ unreachable()
+ case UntypedNil:
+ // Unsafe.Pointer is a basic type that includes nil.
+ if !hasNil(target) {
+ goto Error
+ }
+ default:
+ goto Error
+ }
+ }
+ case *Interface:
+ if !x.isNil() && !t.Empty() /* empty interfaces are ok */ {
+ goto Error
+ }
+ // Update operand types to the default type rather then
+ // the target (interface) type: values must have concrete
+ // dynamic types. If the value is nil, keep it untyped
+ // (this is important for tools such as go vet which need
+ // the dynamic type for argument checking of say, print
+ // functions)
+ if x.isNil() {
+ target = Typ[UntypedNil]
+ } else {
+ // cannot assign untyped values to non-empty interfaces
+ if !t.Empty() {
+ goto Error
+ }
+ target = defaultType(x.typ)
+ }
+ case *Pointer, *Signature, *Slice, *Map, *Chan:
+ if !x.isNil() {
+ goto Error
+ }
+ // keep nil untyped - see comment for interfaces, above
+ target = Typ[UntypedNil]
+ default:
+ goto Error
+ }
+
+ x.typ = target
+ check.updateExprType(x.expr, target, true) // UntypedNils are final
+ return
+
+Error:
+ check.errorf(x.pos(), "cannot convert %s to %s", x, target)
+ x.mode = invalid
+}
+
+func (check *Checker) comparison(x, y *operand, op token.Token) {
+ // spec: "In any comparison, the first operand must be assignable
+ // to the type of the second operand, or vice versa."
+ err := ""
+ if x.assignableTo(check.conf, y.typ) || y.assignableTo(check.conf, x.typ) {
+ defined := false
+ switch op {
+ case token.EQL, token.NEQ:
+ // spec: "The equality operators == and != apply to operands that are comparable."
+ defined = Comparable(x.typ) || x.isNil() && hasNil(y.typ) || y.isNil() && hasNil(x.typ)
+ case token.LSS, token.LEQ, token.GTR, token.GEQ:
+ // spec: The ordering operators <, <=, >, and >= apply to operands that are ordered."
+ defined = isOrdered(x.typ)
+ default:
+ unreachable()
+ }
+ if !defined {
+ typ := x.typ
+ if x.isNil() {
+ typ = y.typ
+ }
+ err = check.sprintf("operator %s not defined for %s", op, typ)
+ }
+ } else {
+ err = check.sprintf("mismatched types %s and %s", x.typ, y.typ)
+ }
+
+ if err != "" {
+ check.errorf(x.pos(), "cannot compare %s %s %s (%s)", x.expr, op, y.expr, err)
+ x.mode = invalid
+ return
+ }
+
+ if x.mode == constant && y.mode == constant {
+ x.val = exact.MakeBool(exact.Compare(x.val, op, y.val))
+ // The operands are never materialized; no need to update
+ // their types.
+ } else {
+ x.mode = value
+ // The operands have now their final types, which at run-
+ // time will be materialized. Update the expression trees.
+ // If the current types are untyped, the materialized type
+ // is the respective default type.
+ check.updateExprType(x.expr, defaultType(x.typ), true)
+ check.updateExprType(y.expr, defaultType(y.typ), true)
+ }
+
+ // spec: "Comparison operators compare two operands and yield
+ // an untyped boolean value."
+ x.typ = Typ[UntypedBool]
+}
+
+func (check *Checker) shift(x, y *operand, op token.Token) {
+ untypedx := isUntyped(x.typ)
+
+ // The lhs must be of integer type or be representable
+ // as an integer; otherwise the shift has no chance.
+ if !x.isInteger() {
+ check.invalidOp(x.pos(), "shifted operand %s must be integer", x)
+ x.mode = invalid
+ return
+ }
+
+ // spec: "The right operand in a shift expression must have unsigned
+ // integer type or be an untyped constant that can be converted to
+ // unsigned integer type."
+ switch {
+ case isInteger(y.typ) && isUnsigned(y.typ):
+ // nothing to do
+ case isUntyped(y.typ):
+ check.convertUntyped(y, Typ[UntypedInt])
+ if y.mode == invalid {
+ x.mode = invalid
+ return
+ }
+ default:
+ check.invalidOp(y.pos(), "shift count %s must be unsigned integer", y)
+ x.mode = invalid
+ return
+ }
+
+ if x.mode == constant {
+ if y.mode == constant {
+ // rhs must be an integer value
+ if !y.isInteger() {
+ check.invalidOp(y.pos(), "shift count %s must be unsigned integer", y)
+ x.mode = invalid
+ return
+ }
+ // rhs must be within reasonable bounds
+ const stupidShift = 1023 - 1 + 52 // so we can express smallestFloat64
+ s, ok := exact.Uint64Val(y.val)
+ if !ok || s > stupidShift {
+ check.invalidOp(y.pos(), "stupid shift count %s", y)
+ x.mode = invalid
+ return
+ }
+ // The lhs is representable as an integer but may not be an integer
+ // (e.g., 2.0, an untyped float) - this can only happen for untyped
+ // non-integer numeric constants. Correct the type so that the shift
+ // result is of integer type.
+ if !isInteger(x.typ) {
+ x.typ = Typ[UntypedInt]
+ }
+ x.val = exact.Shift(x.val, op, uint(s))
+ return
+ }
+
+ // non-constant shift with constant lhs
+ if untypedx {
+ // spec: "If the left operand of a non-constant shift
+ // expression is an untyped constant, the type of the
+ // constant is what it would be if the shift expression
+ // were replaced by its left operand alone.".
+ //
+ // Delay operand checking until we know the final type:
+ // The lhs expression must be in the untyped map, mark
+ // the entry as lhs shift operand.
+ info, found := check.untyped[x.expr]
+ assert(found)
+ info.isLhs = true
+ check.untyped[x.expr] = info
+ // keep x's type
+ x.mode = value
+ return
+ }
+ }
+
+ // constant rhs must be >= 0
+ if y.mode == constant && exact.Sign(y.val) < 0 {
+ check.invalidOp(y.pos(), "shift count %s must not be negative", y)
+ }
+
+ // non-constant shift - lhs must be an integer
+ if !isInteger(x.typ) {
+ check.invalidOp(x.pos(), "shifted operand %s must be integer", x)
+ x.mode = invalid
+ return
+ }
+
+ x.mode = value
+}
+
+var binaryOpPredicates = opPredicates{
+ token.ADD: func(typ Type) bool { return isNumeric(typ) || isString(typ) },
+ token.SUB: isNumeric,
+ token.MUL: isNumeric,
+ token.QUO: isNumeric,
+ token.REM: isInteger,
+
+ token.AND: isInteger,
+ token.OR: isInteger,
+ token.XOR: isInteger,
+ token.AND_NOT: isInteger,
+
+ token.LAND: isBoolean,
+ token.LOR: isBoolean,
+}
+
+// The binary expression e may be nil. It's passed in for better error messages only.
+func (check *Checker) binary(x *operand, e *ast.BinaryExpr, lhs, rhs ast.Expr, op token.Token) {
+ var y operand
+
+ check.expr(x, lhs)
+ check.expr(&y, rhs)
+
+ if x.mode == invalid {
+ return
+ }
+ if y.mode == invalid {
+ x.mode = invalid
+ x.expr = y.expr
+ return
+ }
+
+ if isShift(op) {
+ check.shift(x, &y, op)
+ return
+ }
+
+ check.convertUntyped(x, y.typ)
+ if x.mode == invalid {
+ return
+ }
+ check.convertUntyped(&y, x.typ)
+ if y.mode == invalid {
+ x.mode = invalid
+ return
+ }
+
+ if isComparison(op) {
+ check.comparison(x, &y, op)
+ return
+ }
+
+ if !Identical(x.typ, y.typ) {
+ // only report an error if we have valid types
+ // (otherwise we had an error reported elsewhere already)
+ if x.typ != Typ[Invalid] && y.typ != Typ[Invalid] {
+ check.invalidOp(x.pos(), "mismatched types %s and %s", x.typ, y.typ)
+ }
+ x.mode = invalid
+ return
+ }
+
+ if !check.op(binaryOpPredicates, x, op) {
+ x.mode = invalid
+ return
+ }
+
+ if (op == token.QUO || op == token.REM) && (x.mode == constant || isInteger(x.typ)) && y.mode == constant && exact.Sign(y.val) == 0 {
+ check.invalidOp(y.pos(), "division by zero")
+ x.mode = invalid
+ return
+ }
+
+ if x.mode == constant && y.mode == constant {
+ typ := x.typ.Underlying().(*Basic)
+ // force integer division of integer operands
+ if op == token.QUO && isInteger(typ) {
+ op = token.QUO_ASSIGN
+ }
+ x.val = exact.BinaryOp(x.val, op, y.val)
+ // Typed constants must be representable in
+ // their type after each constant operation.
+ if isTyped(typ) {
+ if e != nil {
+ x.expr = e // for better error message
+ }
+ check.representable(x, typ)
+ }
+ return
+ }
+
+ x.mode = value
+ // x.typ is unchanged
+}
+
+// index checks an index expression for validity.
+// If max >= 0, it is the upper bound for index.
+// If index is valid and the result i >= 0, then i is the constant value of index.
+func (check *Checker) index(index ast.Expr, max int64) (i int64, valid bool) {
+ var x operand
+ check.expr(&x, index)
+ if x.mode == invalid {
+ return
+ }
+
+ // an untyped constant must be representable as Int
+ check.convertUntyped(&x, Typ[Int])
+ if x.mode == invalid {
+ return
+ }
+
+ // the index must be of integer type
+ if !isInteger(x.typ) {
+ check.invalidArg(x.pos(), "index %s must be integer", &x)
+ return
+ }
+
+ // a constant index i must be in bounds
+ if x.mode == constant {
+ if exact.Sign(x.val) < 0 {
+ check.invalidArg(x.pos(), "index %s must not be negative", &x)
+ return
+ }
+ i, valid = exact.Int64Val(x.val)
+ if !valid || max >= 0 && i >= max {
+ check.errorf(x.pos(), "index %s is out of bounds", &x)
+ return i, false
+ }
+ // 0 <= i [ && i < max ]
+ return i, true
+ }
+
+ return -1, true
+}
+
+// indexElts checks the elements (elts) of an array or slice composite literal
+// against the literal's element type (typ), and the element indices against
+// the literal length if known (length >= 0). It returns the length of the
+// literal (maximum index value + 1).
+//
+func (check *Checker) indexedElts(elts []ast.Expr, typ Type, length int64) int64 {
+ visited := make(map[int64]bool, len(elts))
+ var index, max int64
+ for _, e := range elts {
+ // determine and check index
+ validIndex := false
+ eval := e
+ if kv, _ := e.(*ast.KeyValueExpr); kv != nil {
+ if i, ok := check.index(kv.Key, length); ok {
+ if i >= 0 {
+ index = i
+ validIndex = true
+ } else {
+ check.errorf(e.Pos(), "index %s must be integer constant", kv.Key)
+ }
+ }
+ eval = kv.Value
+ } else if length >= 0 && index >= length {
+ check.errorf(e.Pos(), "index %d is out of bounds (>= %d)", index, length)
+ } else {
+ validIndex = true
+ }
+
+ // if we have a valid index, check for duplicate entries
+ if validIndex {
+ if visited[index] {
+ check.errorf(e.Pos(), "duplicate index %d in array or slice literal", index)
+ }
+ visited[index] = true
+ }
+ index++
+ if index > max {
+ max = index
+ }
+
+ // check element against composite literal element type
+ var x operand
+ check.exprWithHint(&x, eval, typ)
+ if !check.assignment(&x, typ) && x.mode != invalid {
+ check.errorf(x.pos(), "cannot use %s as %s value in array or slice literal", &x, typ)
+ }
+ }
+ return max
+}
+
+// exprKind describes the kind of an expression; the kind
+// determines if an expression is valid in 'statement context'.
+type exprKind int
+
+const (
+ conversion exprKind = iota
+ expression
+ statement
+)
+
+// rawExpr typechecks expression e and initializes x with the expression
+// value or type. If an error occurred, x.mode is set to invalid.
+// If hint != nil, it is the type of a composite literal element.
+//
+func (check *Checker) rawExpr(x *operand, e ast.Expr, hint Type) exprKind {
+ if trace {
+ check.trace(e.Pos(), "%s", e)
+ check.indent++
+ defer func() {
+ check.indent--
+ check.trace(e.Pos(), "=> %s", x)
+ }()
+ }
+
+ kind := check.exprInternal(x, e, hint)
+
+ // convert x into a user-friendly set of values
+ // TODO(gri) this code can be simplified
+ var typ Type
+ var val exact.Value
+ switch x.mode {
+ case invalid:
+ typ = Typ[Invalid]
+ case novalue:
+ typ = (*Tuple)(nil)
+ case constant:
+ typ = x.typ
+ val = x.val
+ default:
+ typ = x.typ
+ }
+ assert(x.expr != nil && typ != nil)
+
+ if isUntyped(typ) {
+ // delay type and value recording until we know the type
+ // or until the end of type checking
+ check.rememberUntyped(x.expr, false, x.mode, typ.(*Basic), val)
+ } else {
+ check.recordTypeAndValue(e, x.mode, typ, val)
+ }
+
+ return kind
+}
+
+// exprInternal contains the core of type checking of expressions.
+// Must only be called by rawExpr.
+//
+func (check *Checker) exprInternal(x *operand, e ast.Expr, hint Type) exprKind {
+ // make sure x has a valid state in case of bailout
+ // (was issue 5770)
+ x.mode = invalid
+ x.typ = Typ[Invalid]
+
+ switch e := e.(type) {
+ case *ast.BadExpr:
+ goto Error // error was reported before
+
+ case *ast.Ident:
+ check.ident(x, e, nil, nil)
+
+ case *ast.Ellipsis:
+ // ellipses are handled explicitly where they are legal
+ // (array composite literals and parameter lists)
+ check.error(e.Pos(), "invalid use of '...'")
+ goto Error
+
+ case *ast.BasicLit:
+ x.setConst(e.Kind, e.Value)
+ if x.mode == invalid {
+ check.invalidAST(e.Pos(), "invalid literal %v", e.Value)
+ goto Error
+ }
+
+ case *ast.FuncLit:
+ if sig, ok := check.typ(e.Type).(*Signature); ok {
+ // Anonymous functions are considered part of the
+ // init expression/func declaration which contains
+ // them: use existing package-level declaration info.
+ check.funcBody(check.decl, "", sig, e.Body)
+ x.mode = value
+ x.typ = sig
+ } else {
+ check.invalidAST(e.Pos(), "invalid function literal %s", e)
+ goto Error
+ }
+
+ case *ast.CompositeLit:
+ typ := hint
+ openArray := false
+ if e.Type != nil {
+ // [...]T array types may only appear with composite literals.
+ // Check for them here so we don't have to handle ... in general.
+ typ = nil
+ if atyp, _ := e.Type.(*ast.ArrayType); atyp != nil && atyp.Len != nil {
+ if ellip, _ := atyp.Len.(*ast.Ellipsis); ellip != nil && ellip.Elt == nil {
+ // We have an "open" [...]T array type.
+ // Create a new ArrayType with unknown length (-1)
+ // and finish setting it up after analyzing the literal.
+ typ = &Array{len: -1, elem: check.typ(atyp.Elt)}
+ openArray = true
+ }
+ }
+ if typ == nil {
+ typ = check.typ(e.Type)
+ }
+ }
+ if typ == nil {
+ // TODO(gri) provide better error messages depending on context
+ check.error(e.Pos(), "missing type in composite literal")
+ goto Error
+ }
+
+ switch typ, _ := deref(typ); utyp := typ.Underlying().(type) {
+ case *Struct:
+ if len(e.Elts) == 0 {
+ break
+ }
+ fields := utyp.fields
+ if _, ok := e.Elts[0].(*ast.KeyValueExpr); ok {
+ // all elements must have keys
+ visited := make([]bool, len(fields))
+ for _, e := range e.Elts {
+ kv, _ := e.(*ast.KeyValueExpr)
+ if kv == nil {
+ check.error(e.Pos(), "mixture of field:value and value elements in struct literal")
+ continue
+ }
+ key, _ := kv.Key.(*ast.Ident)
+ if key == nil {
+ check.errorf(kv.Pos(), "invalid field name %s in struct literal", kv.Key)
+ continue
+ }
+ i := fieldIndex(utyp.fields, check.pkg, key.Name)
+ if i < 0 {
+ check.errorf(kv.Pos(), "unknown field %s in struct literal", key.Name)
+ continue
+ }
+ fld := fields[i]
+ check.recordUse(key, fld)
+ // 0 <= i < len(fields)
+ if visited[i] {
+ check.errorf(kv.Pos(), "duplicate field name %s in struct literal", key.Name)
+ continue
+ }
+ visited[i] = true
+ check.expr(x, kv.Value)
+ etyp := fld.typ
+ if !check.assignment(x, etyp) {
+ if x.mode != invalid {
+ check.errorf(x.pos(), "cannot use %s as %s value in struct literal", x, etyp)
+ }
+ continue
+ }
+ }
+ } else {
+ // no element must have a key
+ for i, e := range e.Elts {
+ if kv, _ := e.(*ast.KeyValueExpr); kv != nil {
+ check.error(kv.Pos(), "mixture of field:value and value elements in struct literal")
+ continue
+ }
+ check.expr(x, e)
+ if i >= len(fields) {
+ check.error(x.pos(), "too many values in struct literal")
+ break // cannot continue
+ }
+ // i < len(fields)
+ fld := fields[i]
+ if !fld.Exported() && fld.pkg != check.pkg {
+ check.errorf(x.pos(), "implicit assignment to unexported field %s in %s literal", fld.name, typ)
+ continue
+ }
+ etyp := fld.typ
+ if !check.assignment(x, etyp) {
+ if x.mode != invalid {
+ check.errorf(x.pos(), "cannot use %s as %s value in struct literal", x, etyp)
+ }
+ continue
+ }
+ }
+ if len(e.Elts) < len(fields) {
+ check.error(e.Rbrace, "too few values in struct literal")
+ // ok to continue
+ }
+ }
+
+ case *Array:
+ n := check.indexedElts(e.Elts, utyp.elem, utyp.len)
+ // if we have an "open" [...]T array, set the length now that we know it
+ if openArray {
+ utyp.len = n
+ }
+
+ case *Slice:
+ check.indexedElts(e.Elts, utyp.elem, -1)
+
+ case *Map:
+ visited := make(map[interface{}][]Type, len(e.Elts))
+ for _, e := range e.Elts {
+ kv, _ := e.(*ast.KeyValueExpr)
+ if kv == nil {
+ check.error(e.Pos(), "missing key in map literal")
+ continue
+ }
+ check.exprWithHint(x, kv.Key, utyp.key)
+ if !check.assignment(x, utyp.key) {
+ if x.mode != invalid {
+ check.errorf(x.pos(), "cannot use %s as %s key in map literal", x, utyp.key)
+ }
+ continue
+ }
+ if x.mode == constant {
+ duplicate := false
+ // if the key is of interface type, the type is also significant when checking for duplicates
+ if _, ok := utyp.key.Underlying().(*Interface); ok {
+ for _, vtyp := range visited[x.val] {
+ if Identical(vtyp, x.typ) {
+ duplicate = true
+ break
+ }
+ }
+ visited[x.val] = append(visited[x.val], x.typ)
+ } else {
+ _, duplicate = visited[x.val]
+ visited[x.val] = nil
+ }
+ if duplicate {
+ check.errorf(x.pos(), "duplicate key %s in map literal", x.val)
+ continue
+ }
+ }
+ check.exprWithHint(x, kv.Value, utyp.elem)
+ if !check.assignment(x, utyp.elem) {
+ if x.mode != invalid {
+ check.errorf(x.pos(), "cannot use %s as %s value in map literal", x, utyp.elem)
+ }
+ continue
+ }
+ }
+
+ default:
+ // if utyp is invalid, an error was reported before
+ if utyp != Typ[Invalid] {
+ check.errorf(e.Pos(), "invalid composite literal type %s", typ)
+ goto Error
+ }
+ }
+
+ x.mode = value
+ x.typ = typ
+
+ case *ast.ParenExpr:
+ kind := check.rawExpr(x, e.X, nil)
+ x.expr = e
+ return kind
+
+ case *ast.SelectorExpr:
+ check.selector(x, e)
+
+ case *ast.IndexExpr:
+ check.expr(x, e.X)
+ if x.mode == invalid {
+ goto Error
+ }
+
+ valid := false
+ length := int64(-1) // valid if >= 0
+ switch typ := x.typ.Underlying().(type) {
+ case *Basic:
+ if isString(typ) {
+ valid = true
+ if x.mode == constant {
+ length = int64(len(exact.StringVal(x.val)))
+ }
+ // an indexed string always yields a byte value
+ // (not a constant) even if the string and the
+ // index are constant
+ x.mode = value
+ x.typ = universeByte // use 'byte' name
+ }
+
+ case *Array:
+ valid = true
+ length = typ.len
+ if x.mode != variable {
+ x.mode = value
+ }
+ x.typ = typ.elem
+
+ case *Pointer:
+ if typ, _ := typ.base.Underlying().(*Array); typ != nil {
+ valid = true
+ length = typ.len
+ x.mode = variable
+ x.typ = typ.elem
+ }
+
+ case *Slice:
+ valid = true
+ x.mode = variable
+ x.typ = typ.elem
+
+ case *Map:
+ var key operand
+ check.expr(&key, e.Index)
+ if !check.assignment(&key, typ.key) {
+ if key.mode != invalid {
+ check.invalidOp(key.pos(), "cannot use %s as map index of type %s", &key, typ.key)
+ }
+ goto Error
+ }
+ x.mode = mapindex
+ x.typ = typ.elem
+ x.expr = e
+ return expression
+ }
+
+ if !valid {
+ check.invalidOp(x.pos(), "cannot index %s", x)
+ goto Error
+ }
+
+ if e.Index == nil {
+ check.invalidAST(e.Pos(), "missing index for %s", x)
+ goto Error
+ }
+
+ check.index(e.Index, length)
+ // ok to continue
+
+ case *ast.SliceExpr:
+ check.expr(x, e.X)
+ if x.mode == invalid {
+ goto Error
+ }
+
+ valid := false
+ length := int64(-1) // valid if >= 0
+ switch typ := x.typ.Underlying().(type) {
+ case *Basic:
+ if isString(typ) {
+ if slice3(e) {
+ check.invalidOp(x.pos(), "3-index slice of string")
+ goto Error
+ }
+ valid = true
+ if x.mode == constant {
+ length = int64(len(exact.StringVal(x.val)))
+ }
+ // spec: "For untyped string operands the result
+ // is a non-constant value of type string."
+ if typ.kind == UntypedString {
+ x.typ = Typ[String]
+ }
+ }
+
+ case *Array:
+ valid = true
+ length = typ.len
+ if x.mode != variable {
+ check.invalidOp(x.pos(), "cannot slice %s (value not addressable)", x)
+ goto Error
+ }
+ x.typ = &Slice{elem: typ.elem}
+
+ case *Pointer:
+ if typ, _ := typ.base.Underlying().(*Array); typ != nil {
+ valid = true
+ length = typ.len
+ x.typ = &Slice{elem: typ.elem}
+ }
+
+ case *Slice:
+ valid = true
+ // x.typ doesn't change
+ }
+
+ if !valid {
+ check.invalidOp(x.pos(), "cannot slice %s", x)
+ goto Error
+ }
+
+ x.mode = value
+
+ // spec: "Only the first index may be omitted; it defaults to 0."
+ if slice3(e) && (e.High == nil || sliceMax(e) == nil) {
+ check.error(e.Rbrack, "2nd and 3rd index required in 3-index slice")
+ goto Error
+ }
+
+ // check indices
+ var ind [3]int64
+ for i, expr := range []ast.Expr{e.Low, e.High, sliceMax(e)} {
+ x := int64(-1)
+ switch {
+ case expr != nil:
+ // The "capacity" is only known statically for strings, arrays,
+ // and pointers to arrays, and it is the same as the length for
+ // those types.
+ max := int64(-1)
+ if length >= 0 {
+ max = length + 1
+ }
+ if t, ok := check.index(expr, max); ok && t >= 0 {
+ x = t
+ }
+ case i == 0:
+ // default is 0 for the first index
+ x = 0
+ case length >= 0:
+ // default is length (== capacity) otherwise
+ x = length
+ }
+ ind[i] = x
+ }
+
+ // constant indices must be in range
+ // (check.index already checks that existing indices >= 0)
+ L:
+ for i, x := range ind[:len(ind)-1] {
+ if x > 0 {
+ for _, y := range ind[i+1:] {
+ if y >= 0 && x > y {
+ check.errorf(e.Rbrack, "invalid slice indices: %d > %d", x, y)
+ break L // only report one error, ok to continue
+ }
+ }
+ }
+ }
+
+ case *ast.TypeAssertExpr:
+ check.expr(x, e.X)
+ if x.mode == invalid {
+ goto Error
+ }
+ xtyp, _ := x.typ.Underlying().(*Interface)
+ if xtyp == nil {
+ check.invalidOp(x.pos(), "%s is not an interface", x)
+ goto Error
+ }
+ // x.(type) expressions are handled explicitly in type switches
+ if e.Type == nil {
+ check.invalidAST(e.Pos(), "use of .(type) outside type switch")
+ goto Error
+ }
+ T := check.typ(e.Type)
+ if T == Typ[Invalid] {
+ goto Error
+ }
+ check.typeAssertion(x.pos(), x, xtyp, T)
+ x.mode = commaok
+ x.typ = T
+
+ case *ast.CallExpr:
+ return check.call(x, e)
+
+ case *ast.StarExpr:
+ check.exprOrType(x, e.X)
+ switch x.mode {
+ case invalid:
+ goto Error
+ case typexpr:
+ x.typ = &Pointer{base: x.typ}
+ default:
+ if typ, ok := x.typ.Underlying().(*Pointer); ok {
+ x.mode = variable
+ x.typ = typ.base
+ } else {
+ check.invalidOp(x.pos(), "cannot indirect %s", x)
+ goto Error
+ }
+ }
+
+ case *ast.UnaryExpr:
+ check.expr(x, e.X)
+ if x.mode == invalid {
+ goto Error
+ }
+ check.unary(x, e, e.Op)
+ if x.mode == invalid {
+ goto Error
+ }
+ if e.Op == token.ARROW {
+ x.expr = e
+ return statement // receive operations may appear in statement context
+ }
+
+ case *ast.BinaryExpr:
+ check.binary(x, e, e.X, e.Y, e.Op)
+ if x.mode == invalid {
+ goto Error
+ }
+
+ case *ast.KeyValueExpr:
+ // key:value expressions are handled in composite literals
+ check.invalidAST(e.Pos(), "no key:value expected")
+ goto Error
+
+ case *ast.ArrayType, *ast.StructType, *ast.FuncType,
+ *ast.InterfaceType, *ast.MapType, *ast.ChanType:
+ x.mode = typexpr
+ x.typ = check.typ(e)
+ // Note: rawExpr (caller of exprInternal) will call check.recordTypeAndValue
+ // even though check.typ has already called it. This is fine as both
+ // times the same expression and type are recorded. It is also not a
+ // performance issue because we only reach here for composite literal
+ // types, which are comparatively rare.
+
+ default:
+ panic(fmt.Sprintf("%s: unknown expression type %T", check.fset.Position(e.Pos()), e))
+ }
+
+ // everything went well
+ x.expr = e
+ return expression
+
+Error:
+ x.mode = invalid
+ x.expr = e
+ return statement // avoid follow-up errors
+}
+
+// typeAssertion checks that x.(T) is legal; xtyp must be the type of x.
+func (check *Checker) typeAssertion(pos token.Pos, x *operand, xtyp *Interface, T Type) {
+ method, wrongType := assertableTo(xtyp, T)
+ if method == nil {
+ return
+ }
+
+ var msg string
+ if wrongType {
+ msg = "wrong type for method"
+ } else {
+ msg = "missing method"
+ }
+ check.errorf(pos, "%s cannot have dynamic type %s (%s %s)", x, T, msg, method.name)
+}
+
+// expr typechecks expression e and initializes x with the expression value.
+// If an error occurred, x.mode is set to invalid.
+//
+func (check *Checker) expr(x *operand, e ast.Expr) {
+ check.rawExpr(x, e, nil)
+ var msg string
+ switch x.mode {
+ default:
+ return
+ case novalue:
+ msg = "used as value"
+ case builtin:
+ msg = "must be called"
+ case typexpr:
+ msg = "is not an expression"
+ }
+ check.errorf(x.pos(), "%s %s", x, msg)
+ x.mode = invalid
+}
+
+// exprWithHint typechecks expression e and initializes x with the expression value.
+// If an error occurred, x.mode is set to invalid.
+// If hint != nil, it is the type of a composite literal element.
+//
+func (check *Checker) exprWithHint(x *operand, e ast.Expr, hint Type) {
+ assert(hint != nil)
+ check.rawExpr(x, e, hint)
+ var msg string
+ switch x.mode {
+ default:
+ return
+ case novalue:
+ msg = "used as value"
+ case builtin:
+ msg = "must be called"
+ case typexpr:
+ msg = "is not an expression"
+ }
+ check.errorf(x.pos(), "%s %s", x, msg)
+ x.mode = invalid
+}
+
+// exprOrType typechecks expression or type e and initializes x with the expression value or type.
+// If an error occurred, x.mode is set to invalid.
+//
+func (check *Checker) exprOrType(x *operand, e ast.Expr) {
+ check.rawExpr(x, e, nil)
+ if x.mode == novalue {
+ check.errorf(x.pos(), "%s used as value or type", x)
+ x.mode = invalid
+ }
+}
diff --git a/vendor/golang.org/x/tools/go/types/exprstring.go b/vendor/golang.org/x/tools/go/types/exprstring.go
new file mode 100644
index 0000000..370bdf3
--- /dev/null
+++ b/vendor/golang.org/x/tools/go/types/exprstring.go
@@ -0,0 +1,220 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// This file implements printing of expressions.
+
+package types
+
+import (
+ "bytes"
+ "go/ast"
+)
+
+// ExprString returns the (possibly simplified) string representation for x.
+func ExprString(x ast.Expr) string {
+ var buf bytes.Buffer
+ WriteExpr(&buf, x)
+ return buf.String()
+}
+
+// WriteExpr writes the (possibly simplified) string representation for x to buf.
+func WriteExpr(buf *bytes.Buffer, x ast.Expr) {
+ // The AST preserves source-level parentheses so there is
+ // no need to introduce them here to correct for different
+ // operator precedences. (This assumes that the AST was
+ // generated by a Go parser.)
+
+ switch x := x.(type) {
+ default:
+ buf.WriteString("(bad expr)") // nil, ast.BadExpr, ast.KeyValueExpr
+
+ case *ast.Ident:
+ buf.WriteString(x.Name)
+
+ case *ast.Ellipsis:
+ buf.WriteString("...")
+ if x.Elt != nil {
+ WriteExpr(buf, x.Elt)
+ }
+
+ case *ast.BasicLit:
+ buf.WriteString(x.Value)
+
+ case *ast.FuncLit:
+ buf.WriteByte('(')
+ WriteExpr(buf, x.Type)
+ buf.WriteString(" literal)") // simplified
+
+ case *ast.CompositeLit:
+ buf.WriteByte('(')
+ WriteExpr(buf, x.Type)
+ buf.WriteString(" literal)") // simplified
+
+ case *ast.ParenExpr:
+ buf.WriteByte('(')
+ WriteExpr(buf, x.X)
+ buf.WriteByte(')')
+
+ case *ast.SelectorExpr:
+ WriteExpr(buf, x.X)
+ buf.WriteByte('.')
+ buf.WriteString(x.Sel.Name)
+
+ case *ast.IndexExpr:
+ WriteExpr(buf, x.X)
+ buf.WriteByte('[')
+ WriteExpr(buf, x.Index)
+ buf.WriteByte(']')
+
+ case *ast.SliceExpr:
+ WriteExpr(buf, x.X)
+ buf.WriteByte('[')
+ if x.Low != nil {
+ WriteExpr(buf, x.Low)
+ }
+ buf.WriteByte(':')
+ if x.High != nil {
+ WriteExpr(buf, x.High)
+ }
+ if x.Slice3 {
+ buf.WriteByte(':')
+ if x.Max != nil {
+ WriteExpr(buf, x.Max)
+ }
+ }
+ buf.WriteByte(']')
+
+ case *ast.TypeAssertExpr:
+ WriteExpr(buf, x.X)
+ buf.WriteString(".(")
+ WriteExpr(buf, x.Type)
+ buf.WriteByte(')')
+
+ case *ast.CallExpr:
+ WriteExpr(buf, x.Fun)
+ buf.WriteByte('(')
+ for i, arg := range x.Args {
+ if i > 0 {
+ buf.WriteString(", ")
+ }
+ WriteExpr(buf, arg)
+ }
+ if x.Ellipsis.IsValid() {
+ buf.WriteString("...")
+ }
+ buf.WriteByte(')')
+
+ case *ast.StarExpr:
+ buf.WriteByte('*')
+ WriteExpr(buf, x.X)
+
+ case *ast.UnaryExpr:
+ buf.WriteString(x.Op.String())
+ WriteExpr(buf, x.X)
+
+ case *ast.BinaryExpr:
+ WriteExpr(buf, x.X)
+ buf.WriteByte(' ')
+ buf.WriteString(x.Op.String())
+ buf.WriteByte(' ')
+ WriteExpr(buf, x.Y)
+
+ case *ast.ArrayType:
+ buf.WriteByte('[')
+ if x.Len != nil {
+ WriteExpr(buf, x.Len)
+ }
+ buf.WriteByte(']')
+ WriteExpr(buf, x.Elt)
+
+ case *ast.StructType:
+ buf.WriteString("struct{")
+ writeFieldList(buf, x.Fields, "; ", false)
+ buf.WriteByte('}')
+
+ case *ast.FuncType:
+ buf.WriteString("func")
+ writeSigExpr(buf, x)
+
+ case *ast.InterfaceType:
+ buf.WriteString("interface{")
+ writeFieldList(buf, x.Methods, "; ", true)
+ buf.WriteByte('}')
+
+ case *ast.MapType:
+ buf.WriteString("map[")
+ WriteExpr(buf, x.Key)
+ buf.WriteByte(']')
+ WriteExpr(buf, x.Value)
+
+ case *ast.ChanType:
+ var s string
+ switch x.Dir {
+ case ast.SEND:
+ s = "chan<- "
+ case ast.RECV:
+ s = "<-chan "
+ default:
+ s = "chan "
+ }
+ buf.WriteString(s)
+ WriteExpr(buf, x.Value)
+ }
+}
+
+func writeSigExpr(buf *bytes.Buffer, sig *ast.FuncType) {
+ buf.WriteByte('(')
+ writeFieldList(buf, sig.Params, ", ", false)
+ buf.WriteByte(')')
+
+ res := sig.Results
+ n := res.NumFields()
+ if n == 0 {
+ // no result
+ return
+ }
+
+ buf.WriteByte(' ')
+ if n == 1 && len(res.List[0].Names) == 0 {
+ // single unnamed result
+ WriteExpr(buf, res.List[0].Type)
+ return
+ }
+
+ // multiple or named result(s)
+ buf.WriteByte('(')
+ writeFieldList(buf, res, ", ", false)
+ buf.WriteByte(')')
+}
+
+func writeFieldList(buf *bytes.Buffer, fields *ast.FieldList, sep string, iface bool) {
+ for i, f := range fields.List {
+ if i > 0 {
+ buf.WriteString(sep)
+ }
+
+ // field list names
+ for i, name := range f.Names {
+ if i > 0 {
+ buf.WriteString(", ")
+ }
+ buf.WriteString(name.Name)
+ }
+
+ // types of interface methods consist of signatures only
+ if sig, _ := f.Type.(*ast.FuncType); sig != nil && iface {
+ writeSigExpr(buf, sig)
+ continue
+ }
+
+ // named fields are separated with a blank from the field type
+ if len(f.Names) > 0 {
+ buf.WriteByte(' ')
+ }
+
+ WriteExpr(buf, f.Type)
+
+ // ignore tag
+ }
+}
diff --git a/vendor/golang.org/x/tools/go/types/go11.go b/vendor/golang.org/x/tools/go/types/go11.go
new file mode 100644
index 0000000..cf41cab
--- /dev/null
+++ b/vendor/golang.org/x/tools/go/types/go11.go
@@ -0,0 +1,17 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build !go1.2
+
+package types
+
+import "go/ast"
+
+func slice3(x *ast.SliceExpr) bool {
+ return false
+}
+
+func sliceMax(x *ast.SliceExpr) ast.Expr {
+ return nil
+}
diff --git a/vendor/golang.org/x/tools/go/types/go12.go b/vendor/golang.org/x/tools/go/types/go12.go
new file mode 100644
index 0000000..2017442
--- /dev/null
+++ b/vendor/golang.org/x/tools/go/types/go12.go
@@ -0,0 +1,17 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build go1.2
+
+package types
+
+import "go/ast"
+
+func slice3(x *ast.SliceExpr) bool {
+ return x.Slice3
+}
+
+func sliceMax(x *ast.SliceExpr) ast.Expr {
+ return x.Max
+}
diff --git a/vendor/golang.org/x/tools/go/types/initorder.go b/vendor/golang.org/x/tools/go/types/initorder.go
new file mode 100644
index 0000000..0fd567b
--- /dev/null
+++ b/vendor/golang.org/x/tools/go/types/initorder.go
@@ -0,0 +1,222 @@
+// Copyright 2014 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package types
+
+import (
+ "container/heap"
+ "fmt"
+)
+
+// initOrder computes the Info.InitOrder for package variables.
+func (check *Checker) initOrder() {
+ // An InitOrder may already have been computed if a package is
+ // built from several calls to (*Checker).Files. Clear it.
+ check.Info.InitOrder = check.Info.InitOrder[:0]
+
+ // compute the object dependency graph and
+ // initialize a priority queue with the list
+ // of graph nodes
+ pq := nodeQueue(dependencyGraph(check.objMap))
+ heap.Init(&pq)
+
+ const debug = false
+ if debug {
+ fmt.Printf("package %s: object dependency graph\n", check.pkg.Name())
+ for _, n := range pq {
+ for _, o := range n.out {
+ fmt.Printf("\t%s -> %s\n", n.obj.Name(), o.obj.Name())
+ }
+ }
+ fmt.Println()
+ fmt.Printf("package %s: initialization order\n", check.pkg.Name())
+ }
+
+ // determine initialization order by removing the highest priority node
+ // (the one with the fewest dependencies) and its edges from the graph,
+ // repeatedly, until there are no nodes left.
+ // In a valid Go program, those nodes always have zero dependencies (after
+ // removing all incoming dependencies), otherwise there are initialization
+ // cycles.
+ mark := 0
+ emitted := make(map[*declInfo]bool)
+ for len(pq) > 0 {
+ // get the next node
+ n := heap.Pop(&pq).(*objNode)
+
+ // if n still depends on other nodes, we have a cycle
+ if n.in > 0 {
+ mark++ // mark nodes using a different value each time
+ cycle := findPath(n, n, mark)
+ if i := valIndex(cycle); i >= 0 {
+ check.reportCycle(cycle, i)
+ }
+ // ok to continue, but the variable initialization order
+ // will be incorrect at this point since it assumes no
+ // cycle errors
+ }
+
+ // reduce dependency count of all dependent nodes
+ // and update priority queue
+ for _, out := range n.out {
+ out.in--
+ heap.Fix(&pq, out.index)
+ }
+
+ // record the init order for variables with initializers only
+ v, _ := n.obj.(*Var)
+ info := check.objMap[v]
+ if v == nil || !info.hasInitializer() {
+ continue
+ }
+
+ // n:1 variable declarations such as: a, b = f()
+ // introduce a node for each lhs variable (here: a, b);
+ // but they all have the same initializer - emit only
+ // one, for the first variable seen
+ if emitted[info] {
+ continue // initializer already emitted, if any
+ }
+ emitted[info] = true
+
+ infoLhs := info.lhs // possibly nil (see declInfo.lhs field comment)
+ if infoLhs == nil {
+ infoLhs = []*Var{v}
+ }
+ init := &Initializer{infoLhs, info.init}
+ check.Info.InitOrder = append(check.Info.InitOrder, init)
+
+ if debug {
+ fmt.Printf("\t%s\n", init)
+ }
+ }
+
+ if debug {
+ fmt.Println()
+ }
+}
+
+// findPath returns the (reversed) list of nodes z, ... c, b, a,
+// such that there is a path (list of edges) from a to z.
+// If there is no such path, the result is nil.
+// Nodes marked with the value mark are considered "visited";
+// unvisited nodes are marked during the graph search.
+func findPath(a, z *objNode, mark int) []*objNode {
+ if a.mark == mark {
+ return nil // node already seen
+ }
+ a.mark = mark
+
+ for _, n := range a.out {
+ if n == z {
+ return []*objNode{z}
+ }
+ if P := findPath(n, z, mark); P != nil {
+ return append(P, n)
+ }
+ }
+
+ return nil
+}
+
+// valIndex returns the index of the first constant or variable in a,
+// if any; or a value < 0.
+func valIndex(a []*objNode) int {
+ for i, n := range a {
+ switch n.obj.(type) {
+ case *Const, *Var:
+ return i
+ }
+ }
+ return -1
+}
+
+// reportCycle reports an error for the cycle starting at i.
+func (check *Checker) reportCycle(cycle []*objNode, i int) {
+ obj := cycle[i].obj
+ check.errorf(obj.Pos(), "initialization cycle for %s", obj.Name())
+ // print cycle
+ for _ = range cycle {
+ check.errorf(obj.Pos(), "\t%s refers to", obj.Name()) // secondary error, \t indented
+ i++
+ if i >= len(cycle) {
+ i = 0
+ }
+ obj = cycle[i].obj
+ }
+ check.errorf(obj.Pos(), "\t%s", obj.Name())
+}
+
+// An objNode represents a node in the object dependency graph.
+// Each node b in a.out represents an edge a->b indicating that
+// b depends on a.
+// Nodes may be marked for cycle detection. A node n is marked
+// if n.mark corresponds to the current mark value.
+type objNode struct {
+ obj Object // object represented by this node
+ in int // number of nodes this node depends on
+ out []*objNode // list of nodes that depend on this node
+ index int // node index in list of nodes
+ mark int // for cycle detection
+}
+
+// dependencyGraph computes the transposed object dependency graph
+// from the given objMap. The transposed graph is returned as a list
+// of nodes; an edge d->n indicates that node n depends on node d.
+func dependencyGraph(objMap map[Object]*declInfo) []*objNode {
+ // M maps each object to its corresponding node
+ M := make(map[Object]*objNode, len(objMap))
+ for obj := range objMap {
+ M[obj] = &objNode{obj: obj}
+ }
+
+ // G is the graph of nodes n
+ G := make([]*objNode, len(M))
+ i := 0
+ for obj, n := range M {
+ deps := objMap[obj].deps
+ n.in = len(deps)
+ for d := range deps {
+ d := M[d] // node n depends on node d
+ d.out = append(d.out, n) // add edge d->n
+ }
+
+ G[i] = n
+ n.index = i
+ i++
+ }
+
+ return G
+}
+
+// nodeQueue implements the container/heap interface;
+// a nodeQueue may be used as a priority queue.
+type nodeQueue []*objNode
+
+func (a nodeQueue) Len() int { return len(a) }
+
+func (a nodeQueue) Swap(i, j int) {
+ x, y := a[i], a[j]
+ a[i], a[j] = y, x
+ x.index, y.index = j, i
+}
+
+func (a nodeQueue) Less(i, j int) bool {
+ x, y := a[i], a[j]
+ // nodes are prioritized by number of incoming dependencies (1st key)
+ // and source order (2nd key)
+ return x.in < y.in || x.in == y.in && x.obj.order() < y.obj.order()
+}
+
+func (a *nodeQueue) Push(x interface{}) {
+ panic("unreachable")
+}
+
+func (a *nodeQueue) Pop() interface{} {
+ n := len(*a)
+ x := (*a)[n-1]
+ x.index = -1 // for safety
+ *a = (*a)[:n-1]
+ return x
+}
diff --git a/vendor/golang.org/x/tools/go/types/labels.go b/vendor/golang.org/x/tools/go/types/labels.go
new file mode 100644
index 0000000..7364d4d
--- /dev/null
+++ b/vendor/golang.org/x/tools/go/types/labels.go
@@ -0,0 +1,268 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package types
+
+import (
+ "go/ast"
+ "go/token"
+)
+
+// labels checks correct label use in body.
+func (check *Checker) labels(body *ast.BlockStmt) {
+ // set of all labels in this body
+ all := NewScope(nil, body.Pos(), body.End(), "label")
+
+ fwdJumps := check.blockBranches(all, nil, nil, body.List)
+
+ // If there are any forward jumps left, no label was found for
+ // the corresponding goto statements. Either those labels were
+ // never defined, or they are inside blocks and not reachable
+ // for the respective gotos.
+ for _, jmp := range fwdJumps {
+ var msg string
+ name := jmp.Label.Name
+ if alt := all.Lookup(name); alt != nil {
+ msg = "goto %s jumps into block"
+ alt.(*Label).used = true // avoid another error
+ } else {
+ msg = "label %s not declared"
+ }
+ check.errorf(jmp.Label.Pos(), msg, name)
+ }
+
+ // spec: "It is illegal to define a label that is never used."
+ for _, obj := range all.elems {
+ if lbl := obj.(*Label); !lbl.used {
+ check.softErrorf(lbl.pos, "label %s declared but not used", lbl.name)
+ }
+ }
+}
+
+// A block tracks label declarations in a block and its enclosing blocks.
+type block struct {
+ parent *block // enclosing block
+ lstmt *ast.LabeledStmt // labeled statement to which this block belongs, or nil
+ labels map[string]*ast.LabeledStmt // allocated lazily
+}
+
+// insert records a new label declaration for the current block.
+// The label must not have been declared before in any block.
+func (b *block) insert(s *ast.LabeledStmt) {
+ name := s.Label.Name
+ if debug {
+ assert(b.gotoTarget(name) == nil)
+ }
+ labels := b.labels
+ if labels == nil {
+ labels = make(map[string]*ast.LabeledStmt)
+ b.labels = labels
+ }
+ labels[name] = s
+}
+
+// gotoTarget returns the labeled statement in the current
+// or an enclosing block with the given label name, or nil.
+func (b *block) gotoTarget(name string) *ast.LabeledStmt {
+ for s := b; s != nil; s = s.parent {
+ if t := s.labels[name]; t != nil {
+ return t
+ }
+ }
+ return nil
+}
+
+// enclosingTarget returns the innermost enclosing labeled
+// statement with the given label name, or nil.
+func (b *block) enclosingTarget(name string) *ast.LabeledStmt {
+ for s := b; s != nil; s = s.parent {
+ if t := s.lstmt; t != nil && t.Label.Name == name {
+ return t
+ }
+ }
+ return nil
+}
+
+// blockBranches processes a block's statement list and returns the set of outgoing forward jumps.
+// all is the scope of all declared labels, parent the set of labels declared in the immediately
+// enclosing block, and lstmt is the labeled statement this block is associated with (or nil).
+func (check *Checker) blockBranches(all *Scope, parent *block, lstmt *ast.LabeledStmt, list []ast.Stmt) []*ast.BranchStmt {
+ b := &block{parent: parent, lstmt: lstmt}
+
+ var (
+ varDeclPos token.Pos
+ fwdJumps, badJumps []*ast.BranchStmt
+ )
+
+ // All forward jumps jumping over a variable declaration are possibly
+ // invalid (they may still jump out of the block and be ok).
+ // recordVarDecl records them for the given position.
+ recordVarDecl := func(pos token.Pos) {
+ varDeclPos = pos
+ badJumps = append(badJumps[:0], fwdJumps...) // copy fwdJumps to badJumps
+ }
+
+ jumpsOverVarDecl := func(jmp *ast.BranchStmt) bool {
+ if varDeclPos.IsValid() {
+ for _, bad := range badJumps {
+ if jmp == bad {
+ return true
+ }
+ }
+ }
+ return false
+ }
+
+ blockBranches := func(lstmt *ast.LabeledStmt, list []ast.Stmt) {
+ // Unresolved forward jumps inside the nested block
+ // become forward jumps in the current block.
+ fwdJumps = append(fwdJumps, check.blockBranches(all, b, lstmt, list)...)
+ }
+
+ var stmtBranches func(ast.Stmt)
+ stmtBranches = func(s ast.Stmt) {
+ switch s := s.(type) {
+ case *ast.DeclStmt:
+ if d, _ := s.Decl.(*ast.GenDecl); d != nil && d.Tok == token.VAR {
+ recordVarDecl(d.Pos())
+ }
+
+ case *ast.LabeledStmt:
+ // declare non-blank label
+ if name := s.Label.Name; name != "_" {
+ lbl := NewLabel(s.Label.Pos(), check.pkg, name)
+ if alt := all.Insert(lbl); alt != nil {
+ check.softErrorf(lbl.pos, "label %s already declared", name)
+ check.reportAltDecl(alt)
+ // ok to continue
+ } else {
+ b.insert(s)
+ check.recordDef(s.Label, lbl)
+ }
+ // resolve matching forward jumps and remove them from fwdJumps
+ i := 0
+ for _, jmp := range fwdJumps {
+ if jmp.Label.Name == name {
+ // match
+ lbl.used = true
+ check.recordUse(jmp.Label, lbl)
+ if jumpsOverVarDecl(jmp) {
+ check.softErrorf(
+ jmp.Label.Pos(),
+ "goto %s jumps over variable declaration at line %d",
+ name,
+ check.fset.Position(varDeclPos).Line,
+ )
+ // ok to continue
+ }
+ } else {
+ // no match - record new forward jump
+ fwdJumps[i] = jmp
+ i++
+ }
+ }
+ fwdJumps = fwdJumps[:i]
+ lstmt = s
+ }
+ stmtBranches(s.Stmt)
+
+ case *ast.BranchStmt:
+ if s.Label == nil {
+ return // checked in 1st pass (check.stmt)
+ }
+
+ // determine and validate target
+ name := s.Label.Name
+ switch s.Tok {
+ case token.BREAK:
+ // spec: "If there is a label, it must be that of an enclosing
+ // "for", "switch", or "select" statement, and that is the one
+ // whose execution terminates."
+ valid := false
+ if t := b.enclosingTarget(name); t != nil {
+ switch t.Stmt.(type) {
+ case *ast.SwitchStmt, *ast.TypeSwitchStmt, *ast.SelectStmt, *ast.ForStmt, *ast.RangeStmt:
+ valid = true
+ }
+ }
+ if !valid {
+ check.errorf(s.Label.Pos(), "invalid break label %s", name)
+ return
+ }
+
+ case token.CONTINUE:
+ // spec: "If there is a label, it must be that of an enclosing
+ // "for" statement, and that is the one whose execution advances."
+ valid := false
+ if t := b.enclosingTarget(name); t != nil {
+ switch t.Stmt.(type) {
+ case *ast.ForStmt, *ast.RangeStmt:
+ valid = true
+ }
+ }
+ if !valid {
+ check.errorf(s.Label.Pos(), "invalid continue label %s", name)
+ return
+ }
+
+ case token.GOTO:
+ if b.gotoTarget(name) == nil {
+ // label may be declared later - add branch to forward jumps
+ fwdJumps = append(fwdJumps, s)
+ return
+ }
+
+ default:
+ check.invalidAST(s.Pos(), "branch statement: %s %s", s.Tok, name)
+ return
+ }
+
+ // record label use
+ obj := all.Lookup(name)
+ obj.(*Label).used = true
+ check.recordUse(s.Label, obj)
+
+ case *ast.AssignStmt:
+ if s.Tok == token.DEFINE {
+ recordVarDecl(s.Pos())
+ }
+
+ case *ast.BlockStmt:
+ blockBranches(lstmt, s.List)
+
+ case *ast.IfStmt:
+ stmtBranches(s.Body)
+ if s.Else != nil {
+ stmtBranches(s.Else)
+ }
+
+ case *ast.CaseClause:
+ blockBranches(nil, s.Body)
+
+ case *ast.SwitchStmt:
+ stmtBranches(s.Body)
+
+ case *ast.TypeSwitchStmt:
+ stmtBranches(s.Body)
+
+ case *ast.CommClause:
+ blockBranches(nil, s.Body)
+
+ case *ast.SelectStmt:
+ stmtBranches(s.Body)
+
+ case *ast.ForStmt:
+ stmtBranches(s.Body)
+
+ case *ast.RangeStmt:
+ stmtBranches(s.Body)
+ }
+ }
+
+ for _, s := range list {
+ stmtBranches(s)
+ }
+
+ return fwdJumps
+}
diff --git a/vendor/golang.org/x/tools/go/types/lookup.go b/vendor/golang.org/x/tools/go/types/lookup.go
new file mode 100644
index 0000000..3caca55
--- /dev/null
+++ b/vendor/golang.org/x/tools/go/types/lookup.go
@@ -0,0 +1,341 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// This file implements various field and method lookup functions.
+
+package types
+
+// LookupFieldOrMethod looks up a field or method with given package and name
+// in T and returns the corresponding *Var or *Func, an index sequence, and a
+// bool indicating if there were any pointer indirections on the path to the
+// field or method. If addressable is set, T is the type of an addressable
+// variable (only matters for method lookups).
+//
+// The last index entry is the field or method index in the (possibly embedded)
+// type where the entry was found, either:
+//
+// 1) the list of declared methods of a named type; or
+// 2) the list of all methods (method set) of an interface type; or
+// 3) the list of fields of a struct type.
+//
+// The earlier index entries are the indices of the anonymous struct fields
+// traversed to get to the found entry, starting at depth 0.
+//
+// If no entry is found, a nil object is returned. In this case, the returned
+// index and indirect values have the following meaning:
+//
+// - If index != nil, the index sequence points to an ambiguous entry
+// (the same name appeared more than once at the same embedding level).
+//
+// - If indirect is set, a method with a pointer receiver type was found
+// but there was no pointer on the path from the actual receiver type to
+// the method's formal receiver base type, nor was the receiver addressable.
+//
+func LookupFieldOrMethod(T Type, addressable bool, pkg *Package, name string) (obj Object, index []int, indirect bool) {
+ // Methods cannot be associated to a named pointer type
+ // (spec: "The type denoted by T is called the receiver base type;
+ // it must not be a pointer or interface type and it must be declared
+ // in the same package as the method.").
+ // Thus, if we have a named pointer type, proceed with the underlying
+ // pointer type but discard the result if it is a method since we would
+ // not have found it for T (see also issue 8590).
+ if t, _ := T.(*Named); t != nil {
+ if p, _ := t.underlying.(*Pointer); p != nil {
+ obj, index, indirect = lookupFieldOrMethod(p, false, pkg, name)
+ if _, ok := obj.(*Func); ok {
+ return nil, nil, false
+ }
+ return
+ }
+ }
+
+ return lookupFieldOrMethod(T, addressable, pkg, name)
+}
+
+// TODO(gri) The named type consolidation and seen maps below must be
+// indexed by unique keys for a given type. Verify that named
+// types always have only one representation (even when imported
+// indirectly via different packages.)
+
+func lookupFieldOrMethod(T Type, addressable bool, pkg *Package, name string) (obj Object, index []int, indirect bool) {
+ // WARNING: The code in this function is extremely subtle - do not modify casually!
+ // This function and NewMethodSet should be kept in sync.
+
+ if name == "_" {
+ return // blank fields/methods are never found
+ }
+
+ typ, isPtr := deref(T)
+ named, _ := typ.(*Named)
+
+ // *typ where typ is an interface has no methods.
+ if isPtr {
+ utyp := typ
+ if named != nil {
+ utyp = named.underlying
+ }
+ if _, ok := utyp.(*Interface); ok {
+ return
+ }
+ }
+
+ // Start with typ as single entry at shallowest depth.
+ // If typ is not a named type, insert a nil type instead.
+ current := []embeddedType{{named, nil, isPtr, false}}
+
+ // named types that we have seen already, allocated lazily
+ var seen map[*Named]bool
+
+ // search current depth
+ for len(current) > 0 {
+ var next []embeddedType // embedded types found at current depth
+
+ // look for (pkg, name) in all types at current depth
+ for _, e := range current {
+ // The very first time only, e.typ may be nil.
+ // In this case, we don't have a named type and
+ // we simply continue with the underlying type.
+ if e.typ != nil {
+ if seen[e.typ] {
+ // We have seen this type before, at a more shallow depth
+ // (note that multiples of this type at the current depth
+ // were consolidated before). The type at that depth shadows
+ // this same type at the current depth, so we can ignore
+ // this one.
+ continue
+ }
+ if seen == nil {
+ seen = make(map[*Named]bool)
+ }
+ seen[e.typ] = true
+
+ // look for a matching attached method
+ if i, m := lookupMethod(e.typ.methods, pkg, name); m != nil {
+ // potential match
+ assert(m.typ != nil)
+ index = concat(e.index, i)
+ if obj != nil || e.multiples {
+ return nil, index, false // collision
+ }
+ obj = m
+ indirect = e.indirect
+ continue // we can't have a matching field or interface method
+ }
+
+ // continue with underlying type
+ typ = e.typ.underlying
+ }
+
+ switch t := typ.(type) {
+ case *Struct:
+ // look for a matching field and collect embedded types
+ for i, f := range t.fields {
+ if f.sameId(pkg, name) {
+ assert(f.typ != nil)
+ index = concat(e.index, i)
+ if obj != nil || e.multiples {
+ return nil, index, false // collision
+ }
+ obj = f
+ indirect = e.indirect
+ continue // we can't have a matching interface method
+ }
+ // Collect embedded struct fields for searching the next
+ // lower depth, but only if we have not seen a match yet
+ // (if we have a match it is either the desired field or
+ // we have a name collision on the same depth; in either
+ // case we don't need to look further).
+ // Embedded fields are always of the form T or *T where
+ // T is a named type. If e.typ appeared multiple times at
+ // this depth, f.typ appears multiple times at the next
+ // depth.
+ if obj == nil && f.anonymous {
+ // Ignore embedded basic types - only user-defined
+ // named types can have methods or struct fields.
+ typ, isPtr := deref(f.typ)
+ if t, _ := typ.(*Named); t != nil {
+ next = append(next, embeddedType{t, concat(e.index, i), e.indirect || isPtr, e.multiples})
+ }
+ }
+ }
+
+ case *Interface:
+ // look for a matching method
+ // TODO(gri) t.allMethods is sorted - use binary search
+ if i, m := lookupMethod(t.allMethods, pkg, name); m != nil {
+ assert(m.typ != nil)
+ index = concat(e.index, i)
+ if obj != nil || e.multiples {
+ return nil, index, false // collision
+ }
+ obj = m
+ indirect = e.indirect
+ }
+ }
+ }
+
+ if obj != nil {
+ // found a potential match
+ // spec: "A method call x.m() is valid if the method set of (the type of) x
+ // contains m and the argument list can be assigned to the parameter
+ // list of m. If x is addressable and &x's method set contains m, x.m()
+ // is shorthand for (&x).m()".
+ if f, _ := obj.(*Func); f != nil && ptrRecv(f) && !indirect && !addressable {
+ return nil, nil, true // pointer/addressable receiver required
+ }
+ return
+ }
+
+ current = consolidateMultiples(next)
+ }
+
+ return nil, nil, false // not found
+}
+
+// embeddedType represents an embedded named type
+type embeddedType struct {
+ typ *Named // nil means use the outer typ variable instead
+ index []int // embedded field indices, starting with index at depth 0
+ indirect bool // if set, there was a pointer indirection on the path to this field
+ multiples bool // if set, typ appears multiple times at this depth
+}
+
+// consolidateMultiples collects multiple list entries with the same type
+// into a single entry marked as containing multiples. The result is the
+// consolidated list.
+func consolidateMultiples(list []embeddedType) []embeddedType {
+ if len(list) <= 1 {
+ return list // at most one entry - nothing to do
+ }
+
+ n := 0 // number of entries w/ unique type
+ prev := make(map[*Named]int) // index at which type was previously seen
+ for _, e := range list {
+ if i, found := prev[e.typ]; found {
+ list[i].multiples = true
+ // ignore this entry
+ } else {
+ prev[e.typ] = n
+ list[n] = e
+ n++
+ }
+ }
+ return list[:n]
+}
+
+// MissingMethod returns (nil, false) if V implements T, otherwise it
+// returns a missing method required by T and whether it is missing or
+// just has the wrong type.
+//
+// For non-interface types V, or if static is set, V implements T if all
+// methods of T are present in V. Otherwise (V is an interface and static
+// is not set), MissingMethod only checks that methods of T which are also
+// present in V have matching types (e.g., for a type assertion x.(T) where
+// x is of interface type V).
+//
+func MissingMethod(V Type, T *Interface, static bool) (method *Func, wrongType bool) {
+ // fast path for common case
+ if T.Empty() {
+ return
+ }
+
+ // TODO(gri) Consider using method sets here. Might be more efficient.
+
+ if ityp, _ := V.Underlying().(*Interface); ityp != nil {
+ // TODO(gri) allMethods is sorted - can do this more efficiently
+ for _, m := range T.allMethods {
+ _, obj := lookupMethod(ityp.allMethods, m.pkg, m.name)
+ switch {
+ case obj == nil:
+ if static {
+ return m, false
+ }
+ case !Identical(obj.Type(), m.typ):
+ return m, true
+ }
+ }
+ return
+ }
+
+ // A concrete type implements T if it implements all methods of T.
+ for _, m := range T.allMethods {
+ obj, _, _ := lookupFieldOrMethod(V, false, m.pkg, m.name)
+
+ f, _ := obj.(*Func)
+ if f == nil {
+ return m, false
+ }
+
+ if !Identical(f.typ, m.typ) {
+ return m, true
+ }
+ }
+
+ return
+}
+
+// assertableTo reports whether a value of type V can be asserted to have type T.
+// It returns (nil, false) as affirmative answer. Otherwise it returns a missing
+// method required by V and whether it is missing or just has the wrong type.
+func assertableTo(V *Interface, T Type) (method *Func, wrongType bool) {
+ // no static check is required if T is an interface
+ // spec: "If T is an interface type, x.(T) asserts that the
+ // dynamic type of x implements the interface T."
+ if _, ok := T.Underlying().(*Interface); ok && !strict {
+ return
+ }
+ return MissingMethod(T, V, false)
+}
+
+// deref dereferences typ if it is a *Pointer and returns its base and true.
+// Otherwise it returns (typ, false).
+func deref(typ Type) (Type, bool) {
+ if p, _ := typ.(*Pointer); p != nil {
+ return p.base, true
+ }
+ return typ, false
+}
+
+// derefStructPtr dereferences typ if it is a (named or unnamed) pointer to a
+// (named or unnamed) struct and returns its base. Otherwise it returns typ.
+func derefStructPtr(typ Type) Type {
+ if p, _ := typ.Underlying().(*Pointer); p != nil {
+ if _, ok := p.base.Underlying().(*Struct); ok {
+ return p.base
+ }
+ }
+ return typ
+}
+
+// concat returns the result of concatenating list and i.
+// The result does not share its underlying array with list.
+func concat(list []int, i int) []int {
+ var t []int
+ t = append(t, list...)
+ return append(t, i)
+}
+
+// fieldIndex returns the index for the field with matching package and name, or a value < 0.
+func fieldIndex(fields []*Var, pkg *Package, name string) int {
+ if name != "_" {
+ for i, f := range fields {
+ if f.sameId(pkg, name) {
+ return i
+ }
+ }
+ }
+ return -1
+}
+
+// lookupMethod returns the index of and method with matching package and name, or (-1, nil).
+func lookupMethod(methods []*Func, pkg *Package, name string) (int, *Func) {
+ if name != "_" {
+ for i, m := range methods {
+ if m.sameId(pkg, name) {
+ return i, m
+ }
+ }
+ }
+ return -1, nil
+}
diff --git a/vendor/golang.org/x/tools/go/types/methodset.go b/vendor/golang.org/x/tools/go/types/methodset.go
new file mode 100644
index 0000000..8aff6f9
--- /dev/null
+++ b/vendor/golang.org/x/tools/go/types/methodset.go
@@ -0,0 +1,271 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// This file implements method sets.
+
+package types
+
+import (
+ "bytes"
+ "fmt"
+ "sort"
+)
+
+// A MethodSet is an ordered set of concrete or abstract (interface) methods;
+// a method is a MethodVal selection, and they are ordered by ascending m.Obj().Id().
+// The zero value for a MethodSet is a ready-to-use empty method set.
+type MethodSet struct {
+ list []*Selection
+}
+
+func (s *MethodSet) String() string {
+ if s.Len() == 0 {
+ return "MethodSet {}"
+ }
+
+ var buf bytes.Buffer
+ fmt.Fprintln(&buf, "MethodSet {")
+ for _, f := range s.list {
+ fmt.Fprintf(&buf, "\t%s\n", f)
+ }
+ fmt.Fprintln(&buf, "}")
+ return buf.String()
+}
+
+// Len returns the number of methods in s.
+func (s *MethodSet) Len() int { return len(s.list) }
+
+// At returns the i'th method in s for 0 <= i < s.Len().
+func (s *MethodSet) At(i int) *Selection { return s.list[i] }
+
+// Lookup returns the method with matching package and name, or nil if not found.
+func (s *MethodSet) Lookup(pkg *Package, name string) *Selection {
+ if s.Len() == 0 {
+ return nil
+ }
+
+ key := Id(pkg, name)
+ i := sort.Search(len(s.list), func(i int) bool {
+ m := s.list[i]
+ return m.obj.Id() >= key
+ })
+ if i < len(s.list) {
+ m := s.list[i]
+ if m.obj.Id() == key {
+ return m
+ }
+ }
+ return nil
+}
+
+// Shared empty method set.
+var emptyMethodSet MethodSet
+
+// NewMethodSet returns the method set for the given type T. It
+// always returns a non-nil method set, even if it is empty.
+//
+// A MethodSetCache handles repeat queries more efficiently.
+//
+func NewMethodSet(T Type) *MethodSet {
+ // WARNING: The code in this function is extremely subtle - do not modify casually!
+ // This function and lookupFieldOrMethod should be kept in sync.
+
+ // method set up to the current depth, allocated lazily
+ var base methodSet
+
+ typ, isPtr := deref(T)
+ named, _ := typ.(*Named)
+
+ // *typ where typ is an interface has no methods.
+ if isPtr {
+ utyp := typ
+ if named != nil {
+ utyp = named.underlying
+ }
+ if _, ok := utyp.(*Interface); ok {
+ return &emptyMethodSet
+ }
+ }
+
+ // Start with typ as single entry at shallowest depth.
+ // If typ is not a named type, insert a nil type instead.
+ current := []embeddedType{{named, nil, isPtr, false}}
+
+ // named types that we have seen already, allocated lazily
+ var seen map[*Named]bool
+
+ // collect methods at current depth
+ for len(current) > 0 {
+ var next []embeddedType // embedded types found at current depth
+
+ // field and method sets at current depth, allocated lazily
+ var fset fieldSet
+ var mset methodSet
+
+ for _, e := range current {
+ // The very first time only, e.typ may be nil.
+ // In this case, we don't have a named type and
+ // we simply continue with the underlying type.
+ if e.typ != nil {
+ if seen[e.typ] {
+ // We have seen this type before, at a more shallow depth
+ // (note that multiples of this type at the current depth
+ // were consolidated before). The type at that depth shadows
+ // this same type at the current depth, so we can ignore
+ // this one.
+ continue
+ }
+ if seen == nil {
+ seen = make(map[*Named]bool)
+ }
+ seen[e.typ] = true
+
+ mset = mset.add(e.typ.methods, e.index, e.indirect, e.multiples)
+
+ // continue with underlying type
+ typ = e.typ.underlying
+ }
+
+ switch t := typ.(type) {
+ case *Struct:
+ for i, f := range t.fields {
+ fset = fset.add(f, e.multiples)
+
+ // Embedded fields are always of the form T or *T where
+ // T is a named type. If typ appeared multiple times at
+ // this depth, f.Type appears multiple times at the next
+ // depth.
+ if f.anonymous {
+ // Ignore embedded basic types - only user-defined
+ // named types can have methods or struct fields.
+ typ, isPtr := deref(f.typ)
+ if t, _ := typ.(*Named); t != nil {
+ next = append(next, embeddedType{t, concat(e.index, i), e.indirect || isPtr, e.multiples})
+ }
+ }
+ }
+
+ case *Interface:
+ mset = mset.add(t.allMethods, e.index, true, e.multiples)
+ }
+ }
+
+ // Add methods and collisions at this depth to base if no entries with matching
+ // names exist already.
+ for k, m := range mset {
+ if _, found := base[k]; !found {
+ // Fields collide with methods of the same name at this depth.
+ if _, found := fset[k]; found {
+ m = nil // collision
+ }
+ if base == nil {
+ base = make(methodSet)
+ }
+ base[k] = m
+ }
+ }
+
+ // Multiple fields with matching names collide at this depth and shadow all
+ // entries further down; add them as collisions to base if no entries with
+ // matching names exist already.
+ for k, f := range fset {
+ if f == nil {
+ if _, found := base[k]; !found {
+ if base == nil {
+ base = make(methodSet)
+ }
+ base[k] = nil // collision
+ }
+ }
+ }
+
+ current = consolidateMultiples(next)
+ }
+
+ if len(base) == 0 {
+ return &emptyMethodSet
+ }
+
+ // collect methods
+ var list []*Selection
+ for _, m := range base {
+ if m != nil {
+ m.recv = T
+ list = append(list, m)
+ }
+ }
+ sort.Sort(byUniqueName(list))
+ return &MethodSet{list}
+}
+
+// A fieldSet is a set of fields and name collisions.
+// A collision indicates that multiple fields with the
+// same unique id appeared.
+type fieldSet map[string]*Var // a nil entry indicates a name collision
+
+// Add adds field f to the field set s.
+// If multiples is set, f appears multiple times
+// and is treated as a collision.
+func (s fieldSet) add(f *Var, multiples bool) fieldSet {
+ if s == nil {
+ s = make(fieldSet)
+ }
+ key := f.Id()
+ // if f is not in the set, add it
+ if !multiples {
+ if _, found := s[key]; !found {
+ s[key] = f
+ return s
+ }
+ }
+ s[key] = nil // collision
+ return s
+}
+
+// A methodSet is a set of methods and name collisions.
+// A collision indicates that multiple methods with the
+// same unique id appeared.
+type methodSet map[string]*Selection // a nil entry indicates a name collision
+
+// Add adds all functions in list to the method set s.
+// If multiples is set, every function in list appears multiple times
+// and is treated as a collision.
+func (s methodSet) add(list []*Func, index []int, indirect bool, multiples bool) methodSet {
+ if len(list) == 0 {
+ return s
+ }
+ if s == nil {
+ s = make(methodSet)
+ }
+ for i, f := range list {
+ key := f.Id()
+ // if f is not in the set, add it
+ if !multiples {
+ // TODO(gri) A found method may not be added because it's not in the method set
+ // (!indirect && ptrRecv(f)). A 2nd method on the same level may be in the method
+ // set and may not collide with the first one, thus leading to a false positive.
+ // Is that possible? Investigate.
+ if _, found := s[key]; !found && (indirect || !ptrRecv(f)) {
+ s[key] = &Selection{MethodVal, nil, f, concat(index, i), indirect}
+ continue
+ }
+ }
+ s[key] = nil // collision
+ }
+ return s
+}
+
+// ptrRecv reports whether the receiver is of the form *T.
+// The receiver must exist.
+func ptrRecv(f *Func) bool {
+ _, isPtr := deref(f.typ.(*Signature).recv.typ)
+ return isPtr
+}
+
+// byUniqueName function lists can be sorted by their unique names.
+type byUniqueName []*Selection
+
+func (a byUniqueName) Len() int { return len(a) }
+func (a byUniqueName) Less(i, j int) bool { return a[i].obj.Id() < a[j].obj.Id() }
+func (a byUniqueName) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
diff --git a/vendor/golang.org/x/tools/go/types/object.go b/vendor/golang.org/x/tools/go/types/object.go
new file mode 100644
index 0000000..a9b6c43
--- /dev/null
+++ b/vendor/golang.org/x/tools/go/types/object.go
@@ -0,0 +1,361 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package types
+
+import (
+ "bytes"
+ "fmt"
+ "go/ast"
+ "go/token"
+
+ "golang.org/x/tools/go/exact"
+)
+
+// TODO(gri) Document factory, accessor methods, and fields. General clean-up.
+
+// An Object describes a named language entity such as a package,
+// constant, type, variable, function (incl. methods), or label.
+// All objects implement the Object interface.
+//
+type Object interface {
+ Parent() *Scope // scope in which this object is declared
+ Pos() token.Pos // position of object identifier in declaration
+ Pkg() *Package // nil for objects in the Universe scope and labels
+ Name() string // package local object name
+ Type() Type // object type
+ Exported() bool // reports whether the name starts with a capital letter
+ Id() string // object id (see Id below)
+
+ // String returns a human-readable string of the object.
+ String() string
+
+ // order reflects a package-level object's source order: if object
+ // a is before object b in the source, then a.order() < b.order().
+ // order returns a value > 0 for package-level objects; it returns
+ // 0 for all other objects (including objects in file scopes).
+ order() uint32
+
+ // setOrder sets the order number of the object. It must be > 0.
+ setOrder(uint32)
+
+ // setParent sets the parent scope of the object.
+ setParent(*Scope)
+
+ // sameId reports whether obj.Id() and Id(pkg, name) are the same.
+ sameId(pkg *Package, name string) bool
+
+ // scopePos returns the start position of the scope of this Object
+ scopePos() token.Pos
+
+ // setScopePos sets the start position of the scope for this Object.
+ setScopePos(pos token.Pos)
+}
+
+// Id returns name if it is exported, otherwise it
+// returns the name qualified with the package path.
+func Id(pkg *Package, name string) string {
+ if ast.IsExported(name) {
+ return name
+ }
+ // unexported names need the package path for differentiation
+ // (if there's no package, make sure we don't start with '.'
+ // as that may change the order of methods between a setup
+ // inside a package and outside a package - which breaks some
+ // tests)
+ path := "_"
+ // TODO(gri): shouldn't !ast.IsExported(name) => pkg != nil be an precondition?
+ // if pkg == nil {
+ // panic("nil package in lookup of unexported name")
+ // }
+ if pkg != nil {
+ path = pkg.path
+ if path == "" {
+ path = "_"
+ }
+ }
+ return path + "." + name
+}
+
+// An object implements the common parts of an Object.
+type object struct {
+ parent *Scope
+ pos token.Pos
+ pkg *Package
+ name string
+ typ Type
+ order_ uint32
+ scopePos_ token.Pos
+}
+
+func (obj *object) Parent() *Scope { return obj.parent }
+func (obj *object) Pos() token.Pos { return obj.pos }
+func (obj *object) Pkg() *Package { return obj.pkg }
+func (obj *object) Name() string { return obj.name }
+func (obj *object) Type() Type { return obj.typ }
+func (obj *object) Exported() bool { return ast.IsExported(obj.name) }
+func (obj *object) Id() string { return Id(obj.pkg, obj.name) }
+func (obj *object) String() string { panic("abstract") }
+func (obj *object) order() uint32 { return obj.order_ }
+func (obj *object) scopePos() token.Pos { return obj.scopePos_ }
+
+func (obj *object) setParent(parent *Scope) { obj.parent = parent }
+func (obj *object) setOrder(order uint32) { assert(order > 0); obj.order_ = order }
+func (obj *object) setScopePos(pos token.Pos) { obj.scopePos_ = pos }
+
+func (obj *object) sameId(pkg *Package, name string) bool {
+ // spec:
+ // "Two identifiers are different if they are spelled differently,
+ // or if they appear in different packages and are not exported.
+ // Otherwise, they are the same."
+ if name != obj.name {
+ return false
+ }
+ // obj.Name == name
+ if obj.Exported() {
+ return true
+ }
+ // not exported, so packages must be the same (pkg == nil for
+ // fields in Universe scope; this can only happen for types
+ // introduced via Eval)
+ if pkg == nil || obj.pkg == nil {
+ return pkg == obj.pkg
+ }
+ // pkg != nil && obj.pkg != nil
+ return pkg.path == obj.pkg.path
+}
+
+// A PkgName represents an imported Go package.
+type PkgName struct {
+ object
+ imported *Package
+ used bool // set if the package was used
+}
+
+func NewPkgName(pos token.Pos, pkg *Package, name string, imported *Package) *PkgName {
+ return &PkgName{object{nil, pos, pkg, name, Typ[Invalid], 0, token.NoPos}, imported, false}
+}
+
+// Imported returns the package that was imported.
+// It is distinct from Pkg(), which is the package containing the import statement.
+func (obj *PkgName) Imported() *Package { return obj.imported }
+
+// A Const represents a declared constant.
+type Const struct {
+ object
+ val exact.Value
+ visited bool // for initialization cycle detection
+}
+
+func NewConst(pos token.Pos, pkg *Package, name string, typ Type, val exact.Value) *Const {
+ return &Const{object{nil, pos, pkg, name, typ, 0, token.NoPos}, val, false}
+}
+
+func (obj *Const) Val() exact.Value { return obj.val }
+
+// A TypeName represents a declared type.
+type TypeName struct {
+ object
+}
+
+func NewTypeName(pos token.Pos, pkg *Package, name string, typ Type) *TypeName {
+ return &TypeName{object{nil, pos, pkg, name, typ, 0, token.NoPos}}
+}
+
+// A Variable represents a declared variable (including function parameters and results, and struct fields).
+type Var struct {
+ object
+ anonymous bool // if set, the variable is an anonymous struct field, and name is the type name
+ visited bool // for initialization cycle detection
+ isField bool // var is struct field
+ used bool // set if the variable was used
+}
+
+func NewVar(pos token.Pos, pkg *Package, name string, typ Type) *Var {
+ return &Var{object: object{nil, pos, pkg, name, typ, 0, token.NoPos}}
+}
+
+func NewParam(pos token.Pos, pkg *Package, name string, typ Type) *Var {
+ return &Var{object: object{nil, pos, pkg, name, typ, 0, token.NoPos}, used: true} // parameters are always 'used'
+}
+
+func NewField(pos token.Pos, pkg *Package, name string, typ Type, anonymous bool) *Var {
+ return &Var{object: object{nil, pos, pkg, name, typ, 0, token.NoPos}, anonymous: anonymous, isField: true}
+}
+
+func (obj *Var) Anonymous() bool { return obj.anonymous }
+
+func (obj *Var) IsField() bool { return obj.isField }
+
+// A Func represents a declared function, concrete method, or abstract
+// (interface) method. Its Type() is always a *Signature.
+// An abstract method may belong to many interfaces due to embedding.
+type Func struct {
+ object
+}
+
+func NewFunc(pos token.Pos, pkg *Package, name string, sig *Signature) *Func {
+ // don't store a nil signature
+ var typ Type
+ if sig != nil {
+ typ = sig
+ }
+ return &Func{object{nil, pos, pkg, name, typ, 0, token.NoPos}}
+}
+
+// FullName returns the package- or receiver-type-qualified name of
+// function or method obj.
+func (obj *Func) FullName() string {
+ var buf bytes.Buffer
+ writeFuncName(&buf, obj, nil)
+ return buf.String()
+}
+
+func (obj *Func) Scope() *Scope {
+ return obj.typ.(*Signature).scope
+}
+
+// A Label represents a declared label.
+type Label struct {
+ object
+ used bool // set if the label was used
+}
+
+func NewLabel(pos token.Pos, pkg *Package, name string) *Label {
+ return &Label{object{pos: pos, pkg: pkg, name: name, typ: Typ[Invalid]}, false}
+}
+
+// A Builtin represents a built-in function.
+// Builtins don't have a valid type.
+type Builtin struct {
+ object
+ id builtinId
+}
+
+func newBuiltin(id builtinId) *Builtin {
+ return &Builtin{object{name: predeclaredFuncs[id].name, typ: Typ[Invalid]}, id}
+}
+
+// Nil represents the predeclared value nil.
+type Nil struct {
+ object
+}
+
+func writeObject(buf *bytes.Buffer, obj Object, qf Qualifier) {
+ typ := obj.Type()
+ switch obj := obj.(type) {
+ case *PkgName:
+ fmt.Fprintf(buf, "package %s", obj.Name())
+ if path := obj.imported.path; path != "" && path != obj.name {
+ fmt.Fprintf(buf, " (%q)", path)
+ }
+ return
+
+ case *Const:
+ buf.WriteString("const")
+
+ case *TypeName:
+ buf.WriteString("type")
+ typ = typ.Underlying()
+
+ case *Var:
+ if obj.isField {
+ buf.WriteString("field")
+ } else {
+ buf.WriteString("var")
+ }
+
+ case *Func:
+ buf.WriteString("func ")
+ writeFuncName(buf, obj, qf)
+ if typ != nil {
+ WriteSignature(buf, typ.(*Signature), qf)
+ }
+ return
+
+ case *Label:
+ buf.WriteString("label")
+ typ = nil
+
+ case *Builtin:
+ buf.WriteString("builtin")
+ typ = nil
+
+ case *Nil:
+ buf.WriteString("nil")
+ return
+
+ default:
+ panic(fmt.Sprintf("writeObject(%T)", obj))
+ }
+
+ buf.WriteByte(' ')
+
+ // For package-level objects, qualify the name.
+ if obj.Pkg() != nil && obj.Pkg().scope.Lookup(obj.Name()) == obj {
+ writePackage(buf, obj.Pkg(), qf)
+ }
+ buf.WriteString(obj.Name())
+ if typ != nil {
+ buf.WriteByte(' ')
+ WriteType(buf, typ, qf)
+ }
+}
+
+func writePackage(buf *bytes.Buffer, pkg *Package, qf Qualifier) {
+ if pkg == nil {
+ return
+ }
+ var s string
+ if qf != nil {
+ s = qf(pkg)
+ } else {
+ s = pkg.Path()
+ }
+ if s != "" {
+ buf.WriteString(s)
+ buf.WriteByte('.')
+ }
+}
+
+// ObjectString returns the string form of obj.
+// The Qualifier controls the printing of
+// package-level objects, and may be nil.
+func ObjectString(obj Object, qf Qualifier) string {
+ var buf bytes.Buffer
+ writeObject(&buf, obj, qf)
+ return buf.String()
+}
+
+func (obj *PkgName) String() string { return ObjectString(obj, nil) }
+func (obj *Const) String() string { return ObjectString(obj, nil) }
+func (obj *TypeName) String() string { return ObjectString(obj, nil) }
+func (obj *Var) String() string { return ObjectString(obj, nil) }
+func (obj *Func) String() string { return ObjectString(obj, nil) }
+func (obj *Label) String() string { return ObjectString(obj, nil) }
+func (obj *Builtin) String() string { return ObjectString(obj, nil) }
+func (obj *Nil) String() string { return ObjectString(obj, nil) }
+
+func writeFuncName(buf *bytes.Buffer, f *Func, qf Qualifier) {
+ if f.typ != nil {
+ sig := f.typ.(*Signature)
+ if recv := sig.Recv(); recv != nil {
+ buf.WriteByte('(')
+ if _, ok := recv.Type().(*Interface); ok {
+ // gcimporter creates abstract methods of
+ // named interfaces using the interface type
+ // (not the named type) as the receiver.
+ // Don't print it in full.
+ buf.WriteString("interface")
+ } else {
+ WriteType(buf, recv.Type(), qf)
+ }
+ buf.WriteByte(')')
+ buf.WriteByte('.')
+ } else if f.pkg != nil {
+ writePackage(buf, f.pkg, qf)
+ }
+ }
+ buf.WriteString(f.name)
+}
diff --git a/vendor/golang.org/x/tools/go/types/objset.go b/vendor/golang.org/x/tools/go/types/objset.go
new file mode 100644
index 0000000..55eb74a
--- /dev/null
+++ b/vendor/golang.org/x/tools/go/types/objset.go
@@ -0,0 +1,31 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// This file implements objsets.
+//
+// An objset is similar to a Scope but objset elements
+// are identified by their unique id, instead of their
+// object name.
+
+package types
+
+// An objset is a set of objects identified by their unique id.
+// The zero value for objset is a ready-to-use empty objset.
+type objset map[string]Object // initialized lazily
+
+// insert attempts to insert an object obj into objset s.
+// If s already contains an alternative object alt with
+// the same name, insert leaves s unchanged and returns alt.
+// Otherwise it inserts obj and returns nil.
+func (s *objset) insert(obj Object) Object {
+ id := obj.Id()
+ if alt := (*s)[id]; alt != nil {
+ return alt
+ }
+ if *s == nil {
+ *s = make(map[string]Object)
+ }
+ (*s)[id] = obj
+ return nil
+}
diff --git a/vendor/golang.org/x/tools/go/types/operand.go b/vendor/golang.org/x/tools/go/types/operand.go
new file mode 100644
index 0000000..d52b30e
--- /dev/null
+++ b/vendor/golang.org/x/tools/go/types/operand.go
@@ -0,0 +1,288 @@
+// Copyright 2012 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// This file defines operands and associated operations.
+
+package types
+
+import (
+ "bytes"
+ "go/ast"
+ "go/token"
+
+ "golang.org/x/tools/go/exact"
+)
+
+// An operandMode specifies the (addressing) mode of an operand.
+type operandMode byte
+
+const (
+ invalid operandMode = iota // operand is invalid
+ novalue // operand represents no value (result of a function call w/o result)
+ builtin // operand is a built-in function
+ typexpr // operand is a type
+ constant // operand is a constant; the operand's typ is a Basic type
+ variable // operand is an addressable variable
+ mapindex // operand is a map index expression (acts like a variable on lhs, commaok on rhs of an assignment)
+ value // operand is a computed value
+ commaok // like value, but operand may be used in a comma,ok expression
+)
+
+var operandModeString = [...]string{
+ invalid: "invalid operand",
+ novalue: "no value",
+ builtin: "built-in",
+ typexpr: "type",
+ constant: "constant",
+ variable: "variable",
+ mapindex: "map index expression",
+ value: "value",
+ commaok: "comma, ok expression",
+}
+
+// An operand represents an intermediate value during type checking.
+// Operands have an (addressing) mode, the expression evaluating to
+// the operand, the operand's type, a value for constants, and an id
+// for built-in functions.
+// The zero value of operand is a ready to use invalid operand.
+//
+type operand struct {
+ mode operandMode
+ expr ast.Expr
+ typ Type
+ val exact.Value
+ id builtinId
+}
+
+// pos returns the position of the expression corresponding to x.
+// If x is invalid the position is token.NoPos.
+//
+func (x *operand) pos() token.Pos {
+ // x.expr may not be set if x is invalid
+ if x.expr == nil {
+ return token.NoPos
+ }
+ return x.expr.Pos()
+}
+
+// Operand string formats
+// (not all "untyped" cases can appear due to the type system,
+// but they fall out naturally here)
+//
+// mode format
+//
+// invalid ( )
+// novalue ( )
+// builtin ( )
+// typexpr ( )
+//
+// constant ( )
+// constant ( of type )
+// constant ( )
+// constant ( of type )
+//
+// variable ( )
+// variable ( of type )
+//
+// mapindex ( )
+// mapindex ( of type )
+//
+// value ( )
+// value ( of type )
+//
+// commaok ( )
+// commaok ( of type )
+//
+func operandString(x *operand, qf Qualifier) string {
+ var buf bytes.Buffer
+
+ var expr string
+ if x.expr != nil {
+ expr = ExprString(x.expr)
+ } else {
+ switch x.mode {
+ case builtin:
+ expr = predeclaredFuncs[x.id].name
+ case typexpr:
+ expr = TypeString(x.typ, qf)
+ case constant:
+ expr = x.val.String()
+ }
+ }
+
+ // (
+ if expr != "" {
+ buf.WriteString(expr)
+ buf.WriteString(" (")
+ }
+
+ //
+ hasType := false
+ switch x.mode {
+ case invalid, novalue, builtin, typexpr:
+ // no type
+ default:
+ // has type
+ if isUntyped(x.typ) {
+ buf.WriteString(x.typ.(*Basic).name)
+ buf.WriteByte(' ')
+ break
+ }
+ hasType = true
+ }
+
+ //
+ buf.WriteString(operandModeString[x.mode])
+
+ //
+ if x.mode == constant {
+ if s := x.val.String(); s != expr {
+ buf.WriteByte(' ')
+ buf.WriteString(s)
+ }
+ }
+
+ //
+ if hasType {
+ if x.typ != Typ[Invalid] {
+ buf.WriteString(" of type ")
+ WriteType(&buf, x.typ, qf)
+ } else {
+ buf.WriteString(" with invalid type")
+ }
+ }
+
+ // )
+ if expr != "" {
+ buf.WriteByte(')')
+ }
+
+ return buf.String()
+}
+
+func (x *operand) String() string {
+ return operandString(x, nil)
+}
+
+// setConst sets x to the untyped constant for literal lit.
+func (x *operand) setConst(tok token.Token, lit string) {
+ val := exact.MakeFromLiteral(lit, tok)
+ if val == nil {
+ // TODO(gri) Should we make it an unknown constant instead?
+ x.mode = invalid
+ return
+ }
+
+ var kind BasicKind
+ switch tok {
+ case token.INT:
+ kind = UntypedInt
+ case token.FLOAT:
+ kind = UntypedFloat
+ case token.IMAG:
+ kind = UntypedComplex
+ case token.CHAR:
+ kind = UntypedRune
+ case token.STRING:
+ kind = UntypedString
+ }
+
+ x.mode = constant
+ x.typ = Typ[kind]
+ x.val = val
+}
+
+// isNil reports whether x is the nil value.
+func (x *operand) isNil() bool {
+ return x.mode == value && x.typ == Typ[UntypedNil]
+}
+
+// TODO(gri) The functions operand.assignableTo, checker.convertUntyped,
+// checker.representable, and checker.assignment are
+// overlapping in functionality. Need to simplify and clean up.
+
+// assignableTo reports whether x is assignable to a variable of type T.
+func (x *operand) assignableTo(conf *Config, T Type) bool {
+ if x.mode == invalid || T == Typ[Invalid] {
+ return true // avoid spurious errors
+ }
+
+ V := x.typ
+
+ // x's type is identical to T
+ if Identical(V, T) {
+ return true
+ }
+
+ Vu := V.Underlying()
+ Tu := T.Underlying()
+
+ // T is an interface type and x implements T
+ // (Do this check first as it might succeed early.)
+ if Ti, ok := Tu.(*Interface); ok {
+ if Implements(x.typ, Ti) {
+ return true
+ }
+ }
+
+ // x's type V and T have identical underlying types
+ // and at least one of V or T is not a named type
+ if Identical(Vu, Tu) && (!isNamed(V) || !isNamed(T)) {
+ return true
+ }
+
+ // x is a bidirectional channel value, T is a channel
+ // type, x's type V and T have identical element types,
+ // and at least one of V or T is not a named type
+ if Vc, ok := Vu.(*Chan); ok && Vc.dir == SendRecv {
+ if Tc, ok := Tu.(*Chan); ok && Identical(Vc.elem, Tc.elem) {
+ return !isNamed(V) || !isNamed(T)
+ }
+ }
+
+ // x is the predeclared identifier nil and T is a pointer,
+ // function, slice, map, channel, or interface type
+ if x.isNil() {
+ switch t := Tu.(type) {
+ case *Basic:
+ if t.kind == UnsafePointer {
+ return true
+ }
+ case *Pointer, *Signature, *Slice, *Map, *Chan, *Interface:
+ return true
+ }
+ return false
+ }
+
+ // x is an untyped constant representable by a value of type T
+ // TODO(gri) This is borrowing from checker.convertUntyped and
+ // checker.representable. Need to clean up.
+ if isUntyped(Vu) {
+ switch t := Tu.(type) {
+ case *Basic:
+ if x.mode == constant {
+ return representableConst(x.val, conf, t.kind, nil)
+ }
+ // The result of a comparison is an untyped boolean,
+ // but may not be a constant.
+ if Vb, _ := Vu.(*Basic); Vb != nil {
+ return Vb.kind == UntypedBool && isBoolean(Tu)
+ }
+ case *Interface:
+ return x.isNil() || t.Empty()
+ case *Pointer, *Signature, *Slice, *Map, *Chan:
+ return x.isNil()
+ }
+ }
+
+ return false
+}
+
+// isInteger reports whether x is a value of integer type
+// or an untyped constant representable as an integer.
+func (x *operand) isInteger() bool {
+ return x.mode == invalid ||
+ isInteger(x.typ) ||
+ isUntyped(x.typ) && x.mode == constant && representableConst(x.val, nil, UntypedInt, nil) // no *Config required for UntypedInt
+}
diff --git a/vendor/golang.org/x/tools/go/types/ordering.go b/vendor/golang.org/x/tools/go/types/ordering.go
new file mode 100644
index 0000000..6bb98f2
--- /dev/null
+++ b/vendor/golang.org/x/tools/go/types/ordering.go
@@ -0,0 +1,127 @@
+// Copyright 2014 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// This file implements resolveOrder.
+
+package types
+
+import (
+ "go/ast"
+ "sort"
+)
+
+// resolveOrder computes the order in which package-level objects
+// must be type-checked.
+//
+// Interface types appear first in the list, sorted topologically
+// by dependencies on embedded interfaces that are also declared
+// in this package, followed by all other objects sorted in source
+// order.
+//
+// TODO(gri) Consider sorting all types by dependencies here, and
+// in the process check _and_ report type cycles. This may simplify
+// the full type-checking phase.
+//
+func (check *Checker) resolveOrder() []Object {
+ var ifaces, others []Object
+
+ // collect interface types with their dependencies, and all other objects
+ for obj := range check.objMap {
+ if ityp := check.interfaceFor(obj); ityp != nil {
+ ifaces = append(ifaces, obj)
+ // determine dependencies on embedded interfaces
+ for _, f := range ityp.Methods.List {
+ if len(f.Names) == 0 {
+ // Embedded interface: The type must be a (possibly
+ // qualified) identifier denoting another interface.
+ // Imported interfaces are already fully resolved,
+ // so we can ignore qualified identifiers.
+ if ident, _ := f.Type.(*ast.Ident); ident != nil {
+ embedded := check.pkg.scope.Lookup(ident.Name)
+ if check.interfaceFor(embedded) != nil {
+ check.objMap[obj].addDep(embedded)
+ }
+ }
+ }
+ }
+ } else {
+ others = append(others, obj)
+ }
+ }
+
+ // final object order
+ var order []Object
+
+ // sort interface types topologically by dependencies,
+ // and in source order if there are no dependencies
+ sort.Sort(inSourceOrder(ifaces))
+ if debug {
+ for _, obj := range ifaces {
+ assert(check.objMap[obj].mark == 0)
+ }
+ }
+ for _, obj := range ifaces {
+ check.appendInPostOrder(&order, obj)
+ }
+
+ // sort everything else in source order
+ sort.Sort(inSourceOrder(others))
+
+ return append(order, others...)
+}
+
+// interfaceFor returns the AST interface denoted by obj, or nil.
+func (check *Checker) interfaceFor(obj Object) *ast.InterfaceType {
+ tname, _ := obj.(*TypeName)
+ if tname == nil {
+ return nil // not a type
+ }
+ d := check.objMap[obj]
+ if d == nil {
+ check.dump("%s: %s should have been declared", obj.Pos(), obj.Name())
+ unreachable()
+ }
+ if d.typ == nil {
+ return nil // invalid AST - ignore (will be handled later)
+ }
+ ityp, _ := d.typ.(*ast.InterfaceType)
+ return ityp
+}
+
+func (check *Checker) appendInPostOrder(order *[]Object, obj Object) {
+ d := check.objMap[obj]
+ if d.mark != 0 {
+ // We've already seen this object; either because it's
+ // already added to order, or because we have a cycle.
+ // In both cases we stop. Cycle errors are reported
+ // when type-checking types.
+ return
+ }
+ d.mark = 1
+
+ for _, obj := range orderedSetObjects(d.deps) {
+ check.appendInPostOrder(order, obj)
+ }
+
+ *order = append(*order, obj)
+}
+
+func orderedSetObjects(set map[Object]bool) []Object {
+ list := make([]Object, len(set))
+ i := 0
+ for obj := range set {
+ // we don't care about the map element value
+ list[i] = obj
+ i++
+ }
+ sort.Sort(inSourceOrder(list))
+ return list
+}
+
+// inSourceOrder implements the sort.Sort interface.
+type inSourceOrder []Object
+
+func (a inSourceOrder) Len() int { return len(a) }
+func (a inSourceOrder) Less(i, j int) bool { return a[i].order() < a[j].order() }
+func (a inSourceOrder) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
diff --git a/vendor/golang.org/x/tools/go/types/package.go b/vendor/golang.org/x/tools/go/types/package.go
new file mode 100644
index 0000000..48fe839
--- /dev/null
+++ b/vendor/golang.org/x/tools/go/types/package.go
@@ -0,0 +1,65 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package types
+
+import (
+ "fmt"
+ "go/token"
+)
+
+// A Package describes a Go package.
+type Package struct {
+ path string
+ name string
+ scope *Scope
+ complete bool
+ imports []*Package
+ fake bool // scope lookup errors are silently dropped if package is fake (internal use only)
+}
+
+// NewPackage returns a new Package for the given package path and name;
+// the name must not be the blank identifier.
+// The package is not complete and contains no explicit imports.
+func NewPackage(path, name string) *Package {
+ if name == "_" {
+ panic("invalid package name _")
+ }
+ scope := NewScope(Universe, token.NoPos, token.NoPos, fmt.Sprintf("package %q", path))
+ return &Package{path: path, name: name, scope: scope}
+}
+
+// Path returns the package path.
+func (pkg *Package) Path() string { return pkg.path }
+
+// Name returns the package name.
+func (pkg *Package) Name() string { return pkg.name }
+
+// Scope returns the (complete or incomplete) package scope
+// holding the objects declared at package level (TypeNames,
+// Consts, Vars, and Funcs).
+func (pkg *Package) Scope() *Scope { return pkg.scope }
+
+// A package is complete if its scope contains (at least) all
+// exported objects; otherwise it is incomplete.
+func (pkg *Package) Complete() bool { return pkg.complete }
+
+// MarkComplete marks a package as complete.
+func (pkg *Package) MarkComplete() { pkg.complete = true }
+
+// Imports returns the list of packages directly imported by
+// pkg; the list is in source order. Package unsafe is excluded.
+//
+// If pkg was loaded from export data, Imports includes packages that
+// provide package-level objects referenced by pkg. This may be more or
+// less than the set of packages directly imported by pkg's source code.
+func (pkg *Package) Imports() []*Package { return pkg.imports }
+
+// SetImports sets the list of explicitly imported packages to list.
+// It is the caller's responsibility to make sure list elements are unique.
+func (pkg *Package) SetImports(list []*Package) { pkg.imports = list }
+
+func (pkg *Package) String() string {
+ return fmt.Sprintf("package %s (%q)", pkg.name, pkg.path)
+}
diff --git a/vendor/golang.org/x/tools/go/types/predicates.go b/vendor/golang.org/x/tools/go/types/predicates.go
new file mode 100644
index 0000000..993c6d2
--- /dev/null
+++ b/vendor/golang.org/x/tools/go/types/predicates.go
@@ -0,0 +1,309 @@
+// Copyright 2012 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// This file implements commonly used type predicates.
+
+package types
+
+import "sort"
+
+func isNamed(typ Type) bool {
+ if _, ok := typ.(*Basic); ok {
+ return ok
+ }
+ _, ok := typ.(*Named)
+ return ok
+}
+
+func isBoolean(typ Type) bool {
+ t, ok := typ.Underlying().(*Basic)
+ return ok && t.info&IsBoolean != 0
+}
+
+func isInteger(typ Type) bool {
+ t, ok := typ.Underlying().(*Basic)
+ return ok && t.info&IsInteger != 0
+}
+
+func isUnsigned(typ Type) bool {
+ t, ok := typ.Underlying().(*Basic)
+ return ok && t.info&IsUnsigned != 0
+}
+
+func isFloat(typ Type) bool {
+ t, ok := typ.Underlying().(*Basic)
+ return ok && t.info&IsFloat != 0
+}
+
+func isComplex(typ Type) bool {
+ t, ok := typ.Underlying().(*Basic)
+ return ok && t.info&IsComplex != 0
+}
+
+func isNumeric(typ Type) bool {
+ t, ok := typ.Underlying().(*Basic)
+ return ok && t.info&IsNumeric != 0
+}
+
+func isString(typ Type) bool {
+ t, ok := typ.Underlying().(*Basic)
+ return ok && t.info&IsString != 0
+}
+
+func isTyped(typ Type) bool {
+ t, ok := typ.Underlying().(*Basic)
+ return !ok || t.info&IsUntyped == 0
+}
+
+func isUntyped(typ Type) bool {
+ t, ok := typ.Underlying().(*Basic)
+ return ok && t.info&IsUntyped != 0
+}
+
+func isOrdered(typ Type) bool {
+ t, ok := typ.Underlying().(*Basic)
+ return ok && t.info&IsOrdered != 0
+}
+
+func isConstType(typ Type) bool {
+ t, ok := typ.Underlying().(*Basic)
+ return ok && t.info&IsConstType != 0
+}
+
+// IsInterface reports whether typ is an interface type.
+func IsInterface(typ Type) bool {
+ _, ok := typ.Underlying().(*Interface)
+ return ok
+}
+
+// Comparable reports whether values of type T are comparable.
+func Comparable(T Type) bool {
+ switch t := T.Underlying().(type) {
+ case *Basic:
+ // assume invalid types to be comparable
+ // to avoid follow-up errors
+ return t.kind != UntypedNil
+ case *Pointer, *Interface, *Chan:
+ return true
+ case *Struct:
+ for _, f := range t.fields {
+ if !Comparable(f.typ) {
+ return false
+ }
+ }
+ return true
+ case *Array:
+ return Comparable(t.elem)
+ }
+ return false
+}
+
+// hasNil reports whether a type includes the nil value.
+func hasNil(typ Type) bool {
+ switch t := typ.Underlying().(type) {
+ case *Basic:
+ return t.kind == UnsafePointer
+ case *Slice, *Pointer, *Signature, *Interface, *Map, *Chan:
+ return true
+ }
+ return false
+}
+
+// Identical reports whether x and y are identical.
+func Identical(x, y Type) bool {
+ return identical(x, y, nil)
+}
+
+// An ifacePair is a node in a stack of interface type pairs compared for identity.
+type ifacePair struct {
+ x, y *Interface
+ prev *ifacePair
+}
+
+func (p *ifacePair) identical(q *ifacePair) bool {
+ return p.x == q.x && p.y == q.y || p.x == q.y && p.y == q.x
+}
+
+func identical(x, y Type, p *ifacePair) bool {
+ if x == y {
+ return true
+ }
+
+ switch x := x.(type) {
+ case *Basic:
+ // Basic types are singletons except for the rune and byte
+ // aliases, thus we cannot solely rely on the x == y check
+ // above.
+ if y, ok := y.(*Basic); ok {
+ return x.kind == y.kind
+ }
+
+ case *Array:
+ // Two array types are identical if they have identical element types
+ // and the same array length.
+ if y, ok := y.(*Array); ok {
+ return x.len == y.len && identical(x.elem, y.elem, p)
+ }
+
+ case *Slice:
+ // Two slice types are identical if they have identical element types.
+ if y, ok := y.(*Slice); ok {
+ return identical(x.elem, y.elem, p)
+ }
+
+ case *Struct:
+ // Two struct types are identical if they have the same sequence of fields,
+ // and if corresponding fields have the same names, and identical types,
+ // and identical tags. Two anonymous fields are considered to have the same
+ // name. Lower-case field names from different packages are always different.
+ if y, ok := y.(*Struct); ok {
+ if x.NumFields() == y.NumFields() {
+ for i, f := range x.fields {
+ g := y.fields[i]
+ if f.anonymous != g.anonymous ||
+ x.Tag(i) != y.Tag(i) ||
+ !f.sameId(g.pkg, g.name) ||
+ !identical(f.typ, g.typ, p) {
+ return false
+ }
+ }
+ return true
+ }
+ }
+
+ case *Pointer:
+ // Two pointer types are identical if they have identical base types.
+ if y, ok := y.(*Pointer); ok {
+ return identical(x.base, y.base, p)
+ }
+
+ case *Tuple:
+ // Two tuples types are identical if they have the same number of elements
+ // and corresponding elements have identical types.
+ if y, ok := y.(*Tuple); ok {
+ if x.Len() == y.Len() {
+ if x != nil {
+ for i, v := range x.vars {
+ w := y.vars[i]
+ if !identical(v.typ, w.typ, p) {
+ return false
+ }
+ }
+ }
+ return true
+ }
+ }
+
+ case *Signature:
+ // Two function types are identical if they have the same number of parameters
+ // and result values, corresponding parameter and result types are identical,
+ // and either both functions are variadic or neither is. Parameter and result
+ // names are not required to match.
+ if y, ok := y.(*Signature); ok {
+ return x.variadic == y.variadic &&
+ identical(x.params, y.params, p) &&
+ identical(x.results, y.results, p)
+ }
+
+ case *Interface:
+ // Two interface types are identical if they have the same set of methods with
+ // the same names and identical function types. Lower-case method names from
+ // different packages are always different. The order of the methods is irrelevant.
+ if y, ok := y.(*Interface); ok {
+ a := x.allMethods
+ b := y.allMethods
+ if len(a) == len(b) {
+ // Interface types are the only types where cycles can occur
+ // that are not "terminated" via named types; and such cycles
+ // can only be created via method parameter types that are
+ // anonymous interfaces (directly or indirectly) embedding
+ // the current interface. Example:
+ //
+ // type T interface {
+ // m() interface{T}
+ // }
+ //
+ // If two such (differently named) interfaces are compared,
+ // endless recursion occurs if the cycle is not detected.
+ //
+ // If x and y were compared before, they must be equal
+ // (if they were not, the recursion would have stopped);
+ // search the ifacePair stack for the same pair.
+ //
+ // This is a quadratic algorithm, but in practice these stacks
+ // are extremely short (bounded by the nesting depth of interface
+ // type declarations that recur via parameter types, an extremely
+ // rare occurrence). An alternative implementation might use a
+ // "visited" map, but that is probably less efficient overall.
+ q := &ifacePair{x, y, p}
+ for p != nil {
+ if p.identical(q) {
+ return true // same pair was compared before
+ }
+ p = p.prev
+ }
+ if debug {
+ assert(sort.IsSorted(byUniqueMethodName(a)))
+ assert(sort.IsSorted(byUniqueMethodName(b)))
+ }
+ for i, f := range a {
+ g := b[i]
+ if f.Id() != g.Id() || !identical(f.typ, g.typ, q) {
+ return false
+ }
+ }
+ return true
+ }
+ }
+
+ case *Map:
+ // Two map types are identical if they have identical key and value types.
+ if y, ok := y.(*Map); ok {
+ return identical(x.key, y.key, p) && identical(x.elem, y.elem, p)
+ }
+
+ case *Chan:
+ // Two channel types are identical if they have identical value types
+ // and the same direction.
+ if y, ok := y.(*Chan); ok {
+ return x.dir == y.dir && identical(x.elem, y.elem, p)
+ }
+
+ case *Named:
+ // Two named types are identical if their type names originate
+ // in the same type declaration.
+ if y, ok := y.(*Named); ok {
+ return x.obj == y.obj
+ }
+
+ default:
+ unreachable()
+ }
+
+ return false
+}
+
+// defaultType returns the default "typed" type for an "untyped" type;
+// it returns the incoming type for all other types. The default type
+// for untyped nil is untyped nil.
+//
+func defaultType(typ Type) Type {
+ if t, ok := typ.(*Basic); ok {
+ switch t.kind {
+ case UntypedBool:
+ return Typ[Bool]
+ case UntypedInt:
+ return Typ[Int]
+ case UntypedRune:
+ return universeRune // use 'rune' name
+ case UntypedFloat:
+ return Typ[Float64]
+ case UntypedComplex:
+ return Typ[Complex128]
+ case UntypedString:
+ return Typ[String]
+ }
+ }
+ return typ
+}
diff --git a/vendor/golang.org/x/tools/go/types/resolver.go b/vendor/golang.org/x/tools/go/types/resolver.go
new file mode 100644
index 0000000..374ffc2
--- /dev/null
+++ b/vendor/golang.org/x/tools/go/types/resolver.go
@@ -0,0 +1,453 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package types
+
+import (
+ "errors"
+ "fmt"
+ "go/ast"
+ "go/token"
+ pathLib "path"
+ "strconv"
+ "strings"
+ "unicode"
+
+ "golang.org/x/tools/go/exact"
+)
+
+// A declInfo describes a package-level const, type, var, or func declaration.
+type declInfo struct {
+ file *Scope // scope of file containing this declaration
+ lhs []*Var // lhs of n:1 variable declarations, or nil
+ typ ast.Expr // type, or nil
+ init ast.Expr // init expression, or nil
+ fdecl *ast.FuncDecl // func declaration, or nil
+
+ deps map[Object]bool // type and init dependencies; lazily allocated
+ mark int // for dependency analysis
+}
+
+// hasInitializer reports whether the declared object has an initialization
+// expression or function body.
+func (d *declInfo) hasInitializer() bool {
+ return d.init != nil || d.fdecl != nil && d.fdecl.Body != nil
+}
+
+// addDep adds obj as a dependency to d.
+func (d *declInfo) addDep(obj Object) {
+ m := d.deps
+ if m == nil {
+ m = make(map[Object]bool)
+ d.deps = m
+ }
+ m[obj] = true
+}
+
+// arityMatch checks that the lhs and rhs of a const or var decl
+// have the appropriate number of names and init exprs. For const
+// decls, init is the value spec providing the init exprs; for
+// var decls, init is nil (the init exprs are in s in this case).
+func (check *Checker) arityMatch(s, init *ast.ValueSpec) {
+ l := len(s.Names)
+ r := len(s.Values)
+ if init != nil {
+ r = len(init.Values)
+ }
+
+ switch {
+ case init == nil && r == 0:
+ // var decl w/o init expr
+ if s.Type == nil {
+ check.errorf(s.Pos(), "missing type or init expr")
+ }
+ case l < r:
+ if l < len(s.Values) {
+ // init exprs from s
+ n := s.Values[l]
+ check.errorf(n.Pos(), "extra init expr %s", n)
+ // TODO(gri) avoid declared but not used error here
+ } else {
+ // init exprs "inherited"
+ check.errorf(s.Pos(), "extra init expr at %s", init.Pos())
+ // TODO(gri) avoid declared but not used error here
+ }
+ case l > r && (init != nil || r != 1):
+ n := s.Names[r]
+ check.errorf(n.Pos(), "missing init expr for %s", n)
+ }
+}
+
+func validatedImportPath(path string) (string, error) {
+ s, err := strconv.Unquote(path)
+ if err != nil {
+ return "", err
+ }
+ if s == "" {
+ return "", fmt.Errorf("empty string")
+ }
+ const illegalChars = `!"#$%&'()*,:;<=>?[\]^{|}` + "`\uFFFD"
+ for _, r := range s {
+ if !unicode.IsGraphic(r) || unicode.IsSpace(r) || strings.ContainsRune(illegalChars, r) {
+ return s, fmt.Errorf("invalid character %#U", r)
+ }
+ }
+ return s, nil
+}
+
+// declarePkgObj declares obj in the package scope, records its ident -> obj mapping,
+// and updates check.objMap. The object must not be a function or method.
+func (check *Checker) declarePkgObj(ident *ast.Ident, obj Object, d *declInfo) {
+ assert(ident.Name == obj.Name())
+
+ // spec: "A package-scope or file-scope identifier with name init
+ // may only be declared to be a function with this (func()) signature."
+ if ident.Name == "init" {
+ check.errorf(ident.Pos(), "cannot declare init - must be func")
+ return
+ }
+
+ check.declare(check.pkg.scope, ident, obj, token.NoPos)
+ check.objMap[obj] = d
+ obj.setOrder(uint32(len(check.objMap)))
+}
+
+// filename returns a filename suitable for debugging output.
+func (check *Checker) filename(fileNo int) string {
+ file := check.files[fileNo]
+ if pos := file.Pos(); pos.IsValid() {
+ return check.fset.File(pos).Name()
+ }
+ return fmt.Sprintf("file[%d]", fileNo)
+}
+
+// collectObjects collects all file and package objects and inserts them
+// into their respective scopes. It also performs imports and associates
+// methods with receiver base type names.
+func (check *Checker) collectObjects() {
+ pkg := check.pkg
+
+ importer := check.conf.Import
+ if importer == nil {
+ if DefaultImport != nil {
+ importer = DefaultImport
+ } else {
+ // Panic if we encounter an import.
+ importer = func(map[string]*Package, string) (*Package, error) {
+ panic(`no Config.Import or DefaultImport (missing import _ "golang.org/x/tools/go/gcimporter"?)`)
+ }
+ }
+ }
+
+ // pkgImports is the set of packages already imported by any package file seen
+ // so far. Used to avoid duplicate entries in pkg.imports. Allocate and populate
+ // it (pkg.imports may not be empty if we are checking test files incrementally).
+ var pkgImports = make(map[*Package]bool)
+ for _, imp := range pkg.imports {
+ pkgImports[imp] = true
+ }
+
+ for fileNo, file := range check.files {
+ // The package identifier denotes the current package,
+ // but there is no corresponding package object.
+ check.recordDef(file.Name, nil)
+
+ // Use the actual source file extent rather than *ast.File extent since the
+ // latter doesn't include comments which appear at the start or end of the file.
+ // Be conservative and use the *ast.File extent if we don't have a *token.File.
+ pos, end := file.Pos(), file.End()
+ if f := check.fset.File(file.Pos()); f != nil {
+ pos, end = token.Pos(f.Base()), token.Pos(f.Base()+f.Size())
+ }
+ fileScope := NewScope(check.pkg.scope, pos, end, check.filename(fileNo))
+ check.recordScope(file, fileScope)
+
+ for _, decl := range file.Decls {
+ switch d := decl.(type) {
+ case *ast.BadDecl:
+ // ignore
+
+ case *ast.GenDecl:
+ var last *ast.ValueSpec // last ValueSpec with type or init exprs seen
+ for iota, spec := range d.Specs {
+ switch s := spec.(type) {
+ case *ast.ImportSpec:
+ // import package
+ var imp *Package
+ path, err := validatedImportPath(s.Path.Value)
+ if err != nil {
+ check.errorf(s.Path.Pos(), "invalid import path (%s)", err)
+ continue
+ }
+ if path == "C" && check.conf.FakeImportC {
+ // TODO(gri) shouldn't create a new one each time
+ imp = NewPackage("C", "C")
+ imp.fake = true
+ } else {
+ var err error
+ imp, err = importer(check.conf.Packages, path)
+ if imp == nil && err == nil {
+ err = errors.New("Config.Import returned nil but no error")
+ }
+ if err != nil {
+ check.errorf(s.Path.Pos(), "could not import %s (%s)", path, err)
+ continue
+ }
+ }
+
+ // add package to list of explicit imports
+ // (this functionality is provided as a convenience
+ // for clients; it is not needed for type-checking)
+ if !pkgImports[imp] {
+ pkgImports[imp] = true
+ if imp != Unsafe {
+ pkg.imports = append(pkg.imports, imp)
+ }
+ }
+
+ // local name overrides imported package name
+ name := imp.name
+ if s.Name != nil {
+ name = s.Name.Name
+ if name == "init" {
+ check.errorf(s.Name.Pos(), "cannot declare init - must be func")
+ continue
+ }
+ }
+
+ obj := NewPkgName(s.Pos(), pkg, name, imp)
+ if s.Name != nil {
+ // in a dot-import, the dot represents the package
+ check.recordDef(s.Name, obj)
+ } else {
+ check.recordImplicit(s, obj)
+ }
+
+ // add import to file scope
+ if name == "." {
+ // merge imported scope with file scope
+ for _, obj := range imp.scope.elems {
+ // A package scope may contain non-exported objects,
+ // do not import them!
+ if obj.Exported() {
+ // TODO(gri) When we import a package, we create
+ // a new local package object. We should do the
+ // same for each dot-imported object. That way
+ // they can have correct position information.
+ // (We must not modify their existing position
+ // information because the same package - found
+ // via Config.Packages - may be dot-imported in
+ // another package!)
+ check.declare(fileScope, nil, obj, token.NoPos)
+ check.recordImplicit(s, obj)
+ }
+ }
+ // add position to set of dot-import positions for this file
+ // (this is only needed for "imported but not used" errors)
+ check.addUnusedDotImport(fileScope, imp, s.Pos())
+ } else {
+ // declare imported package object in file scope
+ check.declare(fileScope, nil, obj, token.NoPos)
+ }
+
+ case *ast.ValueSpec:
+ switch d.Tok {
+ case token.CONST:
+ // determine which initialization expressions to use
+ switch {
+ case s.Type != nil || len(s.Values) > 0:
+ last = s
+ case last == nil:
+ last = new(ast.ValueSpec) // make sure last exists
+ }
+
+ // declare all constants
+ for i, name := range s.Names {
+ obj := NewConst(name.Pos(), pkg, name.Name, nil, exact.MakeInt64(int64(iota)))
+
+ var init ast.Expr
+ if i < len(last.Values) {
+ init = last.Values[i]
+ }
+
+ d := &declInfo{file: fileScope, typ: last.Type, init: init}
+ check.declarePkgObj(name, obj, d)
+ }
+
+ check.arityMatch(s, last)
+
+ case token.VAR:
+ lhs := make([]*Var, len(s.Names))
+ // If there's exactly one rhs initializer, use
+ // the same declInfo d1 for all lhs variables
+ // so that each lhs variable depends on the same
+ // rhs initializer (n:1 var declaration).
+ var d1 *declInfo
+ if len(s.Values) == 1 {
+ // The lhs elements are only set up after the for loop below,
+ // but that's ok because declareVar only collects the declInfo
+ // for a later phase.
+ d1 = &declInfo{file: fileScope, lhs: lhs, typ: s.Type, init: s.Values[0]}
+ }
+
+ // declare all variables
+ for i, name := range s.Names {
+ obj := NewVar(name.Pos(), pkg, name.Name, nil)
+ lhs[i] = obj
+
+ d := d1
+ if d == nil {
+ // individual assignments
+ var init ast.Expr
+ if i < len(s.Values) {
+ init = s.Values[i]
+ }
+ d = &declInfo{file: fileScope, typ: s.Type, init: init}
+ }
+
+ check.declarePkgObj(name, obj, d)
+ }
+
+ check.arityMatch(s, nil)
+
+ default:
+ check.invalidAST(s.Pos(), "invalid token %s", d.Tok)
+ }
+
+ case *ast.TypeSpec:
+ obj := NewTypeName(s.Name.Pos(), pkg, s.Name.Name, nil)
+ check.declarePkgObj(s.Name, obj, &declInfo{file: fileScope, typ: s.Type})
+
+ default:
+ check.invalidAST(s.Pos(), "unknown ast.Spec node %T", s)
+ }
+ }
+
+ case *ast.FuncDecl:
+ name := d.Name.Name
+ obj := NewFunc(d.Name.Pos(), pkg, name, nil)
+ if d.Recv == nil {
+ // regular function
+ if name == "init" {
+ // don't declare init functions in the package scope - they are invisible
+ obj.parent = pkg.scope
+ check.recordDef(d.Name, obj)
+ // init functions must have a body
+ if d.Body == nil {
+ check.softErrorf(obj.pos, "missing function body")
+ }
+ } else {
+ check.declare(pkg.scope, d.Name, obj, token.NoPos)
+ }
+ } else {
+ // method
+ check.recordDef(d.Name, obj)
+ // Associate method with receiver base type name, if possible.
+ // Ignore methods that have an invalid receiver, or a blank _
+ // receiver name. They will be type-checked later, with regular
+ // functions.
+ if list := d.Recv.List; len(list) > 0 {
+ typ := list[0].Type
+ if ptr, _ := typ.(*ast.StarExpr); ptr != nil {
+ typ = ptr.X
+ }
+ if base, _ := typ.(*ast.Ident); base != nil && base.Name != "_" {
+ check.assocMethod(base.Name, obj)
+ }
+ }
+ }
+ info := &declInfo{file: fileScope, fdecl: d}
+ check.objMap[obj] = info
+ obj.setOrder(uint32(len(check.objMap)))
+
+ default:
+ check.invalidAST(d.Pos(), "unknown ast.Decl node %T", d)
+ }
+ }
+ }
+
+ // verify that objects in package and file scopes have different names
+ for _, scope := range check.pkg.scope.children /* file scopes */ {
+ for _, obj := range scope.elems {
+ if alt := pkg.scope.Lookup(obj.Name()); alt != nil {
+ if pkg, ok := obj.(*PkgName); ok {
+ check.errorf(alt.Pos(), "%s already declared through import of %s", alt.Name(), pkg.Imported())
+ check.reportAltDecl(pkg)
+ } else {
+ check.errorf(alt.Pos(), "%s already declared through dot-import of %s", alt.Name(), obj.Pkg())
+ // TODO(gri) dot-imported objects don't have a position; reportAltDecl won't print anything
+ check.reportAltDecl(obj)
+ }
+ }
+ }
+ }
+}
+
+// packageObjects typechecks all package objects in objList, but not function bodies.
+func (check *Checker) packageObjects(objList []Object) {
+ // add new methods to already type-checked types (from a prior Checker.Files call)
+ for _, obj := range objList {
+ if obj, _ := obj.(*TypeName); obj != nil && obj.typ != nil {
+ check.addMethodDecls(obj)
+ }
+ }
+
+ // pre-allocate space for type declaration paths so that the underlying array is reused
+ typePath := make([]*TypeName, 0, 8)
+
+ for _, obj := range objList {
+ check.objDecl(obj, nil, typePath)
+ }
+
+ // At this point we may have a non-empty check.methods map; this means that not all
+ // entries were deleted at the end of typeDecl because the respective receiver base
+ // types were not found. In that case, an error was reported when declaring those
+ // methods. We can now safely discard this map.
+ check.methods = nil
+}
+
+// functionBodies typechecks all function bodies.
+func (check *Checker) functionBodies() {
+ for _, f := range check.funcs {
+ check.funcBody(f.decl, f.name, f.sig, f.body)
+ }
+}
+
+// unusedImports checks for unused imports.
+func (check *Checker) unusedImports() {
+ // if function bodies are not checked, packages' uses are likely missing - don't check
+ if check.conf.IgnoreFuncBodies {
+ return
+ }
+
+ // spec: "It is illegal (...) to directly import a package without referring to
+ // any of its exported identifiers. To import a package solely for its side-effects
+ // (initialization), use the blank identifier as explicit package name."
+
+ // check use of regular imported packages
+ for _, scope := range check.pkg.scope.children /* file scopes */ {
+ for _, obj := range scope.elems {
+ if obj, ok := obj.(*PkgName); ok {
+ // Unused "blank imports" are automatically ignored
+ // since _ identifiers are not entered into scopes.
+ if !obj.used {
+ path := obj.imported.path
+ base := pathLib.Base(path)
+ if obj.name == base {
+ check.softErrorf(obj.pos, "%q imported but not used", path)
+ } else {
+ check.softErrorf(obj.pos, "%q imported but not used as %s", path, obj.name)
+ }
+ }
+ }
+ }
+ }
+
+ // check use of dot-imported packages
+ for _, unusedDotImports := range check.unusedDotImports {
+ for pkg, pos := range unusedDotImports {
+ check.softErrorf(pos, "%q imported but not used", pkg.path)
+ }
+ }
+}
diff --git a/vendor/golang.org/x/tools/go/types/return.go b/vendor/golang.org/x/tools/go/types/return.go
new file mode 100644
index 0000000..6628985
--- /dev/null
+++ b/vendor/golang.org/x/tools/go/types/return.go
@@ -0,0 +1,185 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// This file implements isTerminating.
+
+package types
+
+import (
+ "go/ast"
+ "go/token"
+)
+
+// isTerminating reports if s is a terminating statement.
+// If s is labeled, label is the label name; otherwise s
+// is "".
+func (check *Checker) isTerminating(s ast.Stmt, label string) bool {
+ switch s := s.(type) {
+ default:
+ unreachable()
+
+ case *ast.BadStmt, *ast.DeclStmt, *ast.EmptyStmt, *ast.SendStmt,
+ *ast.IncDecStmt, *ast.AssignStmt, *ast.GoStmt, *ast.DeferStmt,
+ *ast.RangeStmt:
+ // no chance
+
+ case *ast.LabeledStmt:
+ return check.isTerminating(s.Stmt, s.Label.Name)
+
+ case *ast.ExprStmt:
+ // the predeclared (possibly parenthesized) panic() function is terminating
+ if call, _ := unparen(s.X).(*ast.CallExpr); call != nil {
+ if id, _ := call.Fun.(*ast.Ident); id != nil {
+ if _, obj := check.scope.LookupParent(id.Name, token.NoPos); obj != nil {
+ if b, _ := obj.(*Builtin); b != nil && b.id == _Panic {
+ return true
+ }
+ }
+ }
+ }
+
+ case *ast.ReturnStmt:
+ return true
+
+ case *ast.BranchStmt:
+ if s.Tok == token.GOTO || s.Tok == token.FALLTHROUGH {
+ return true
+ }
+
+ case *ast.BlockStmt:
+ return check.isTerminatingList(s.List, "")
+
+ case *ast.IfStmt:
+ if s.Else != nil &&
+ check.isTerminating(s.Body, "") &&
+ check.isTerminating(s.Else, "") {
+ return true
+ }
+
+ case *ast.SwitchStmt:
+ return check.isTerminatingSwitch(s.Body, label)
+
+ case *ast.TypeSwitchStmt:
+ return check.isTerminatingSwitch(s.Body, label)
+
+ case *ast.SelectStmt:
+ for _, s := range s.Body.List {
+ cc := s.(*ast.CommClause)
+ if !check.isTerminatingList(cc.Body, "") || hasBreakList(cc.Body, label, true) {
+ return false
+ }
+
+ }
+ return true
+
+ case *ast.ForStmt:
+ if s.Cond == nil && !hasBreak(s.Body, label, true) {
+ return true
+ }
+ }
+
+ return false
+}
+
+func (check *Checker) isTerminatingList(list []ast.Stmt, label string) bool {
+ n := len(list)
+ return n > 0 && check.isTerminating(list[n-1], label)
+}
+
+func (check *Checker) isTerminatingSwitch(body *ast.BlockStmt, label string) bool {
+ hasDefault := false
+ for _, s := range body.List {
+ cc := s.(*ast.CaseClause)
+ if cc.List == nil {
+ hasDefault = true
+ }
+ if !check.isTerminatingList(cc.Body, "") || hasBreakList(cc.Body, label, true) {
+ return false
+ }
+ }
+ return hasDefault
+}
+
+// TODO(gri) For nested breakable statements, the current implementation of hasBreak
+// will traverse the same subtree repeatedly, once for each label. Replace
+// with a single-pass label/break matching phase.
+
+// hasBreak reports if s is or contains a break statement
+// referring to the label-ed statement or implicit-ly the
+// closest outer breakable statement.
+func hasBreak(s ast.Stmt, label string, implicit bool) bool {
+ switch s := s.(type) {
+ default:
+ unreachable()
+
+ case *ast.BadStmt, *ast.DeclStmt, *ast.EmptyStmt, *ast.ExprStmt,
+ *ast.SendStmt, *ast.IncDecStmt, *ast.AssignStmt, *ast.GoStmt,
+ *ast.DeferStmt, *ast.ReturnStmt:
+ // no chance
+
+ case *ast.LabeledStmt:
+ return hasBreak(s.Stmt, label, implicit)
+
+ case *ast.BranchStmt:
+ if s.Tok == token.BREAK {
+ if s.Label == nil {
+ return implicit
+ }
+ if s.Label.Name == label {
+ return true
+ }
+ }
+
+ case *ast.BlockStmt:
+ return hasBreakList(s.List, label, implicit)
+
+ case *ast.IfStmt:
+ if hasBreak(s.Body, label, implicit) ||
+ s.Else != nil && hasBreak(s.Else, label, implicit) {
+ return true
+ }
+
+ case *ast.CaseClause:
+ return hasBreakList(s.Body, label, implicit)
+
+ case *ast.SwitchStmt:
+ if label != "" && hasBreak(s.Body, label, false) {
+ return true
+ }
+
+ case *ast.TypeSwitchStmt:
+ if label != "" && hasBreak(s.Body, label, false) {
+ return true
+ }
+
+ case *ast.CommClause:
+ return hasBreakList(s.Body, label, implicit)
+
+ case *ast.SelectStmt:
+ if label != "" && hasBreak(s.Body, label, false) {
+ return true
+ }
+
+ case *ast.ForStmt:
+ if label != "" && hasBreak(s.Body, label, false) {
+ return true
+ }
+
+ case *ast.RangeStmt:
+ if label != "" && hasBreak(s.Body, label, false) {
+ return true
+ }
+ }
+
+ return false
+}
+
+func hasBreakList(list []ast.Stmt, label string, implicit bool) bool {
+ for _, s := range list {
+ if hasBreak(s, label, implicit) {
+ return true
+ }
+ }
+ return false
+}
diff --git a/vendor/golang.org/x/tools/go/types/scope.go b/vendor/golang.org/x/tools/go/types/scope.go
new file mode 100644
index 0000000..3502840
--- /dev/null
+++ b/vendor/golang.org/x/tools/go/types/scope.go
@@ -0,0 +1,190 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// This file implements Scopes.
+
+package types
+
+import (
+ "bytes"
+ "fmt"
+ "go/token"
+ "io"
+ "sort"
+ "strings"
+)
+
+// TODO(gri) Provide scopes with a name or other mechanism so that
+// objects can use that information for better printing.
+
+// A Scope maintains a set of objects and links to its containing
+// (parent) and contained (children) scopes. Objects may be inserted
+// and looked up by name. The zero value for Scope is a ready-to-use
+// empty scope.
+type Scope struct {
+ parent *Scope
+ children []*Scope
+ elems map[string]Object // lazily allocated
+ pos, end token.Pos // scope extent; may be invalid
+ comment string // for debugging only
+}
+
+// NewScope returns a new, empty scope contained in the given parent
+// scope, if any. The comment is for debugging only.
+func NewScope(parent *Scope, pos, end token.Pos, comment string) *Scope {
+ s := &Scope{parent, nil, nil, pos, end, comment}
+ // don't add children to Universe scope!
+ if parent != nil && parent != Universe {
+ parent.children = append(parent.children, s)
+ }
+ return s
+}
+
+// Parent returns the scope's containing (parent) scope.
+func (s *Scope) Parent() *Scope { return s.parent }
+
+// Len() returns the number of scope elements.
+func (s *Scope) Len() int { return len(s.elems) }
+
+// Names returns the scope's element names in sorted order.
+func (s *Scope) Names() []string {
+ names := make([]string, len(s.elems))
+ i := 0
+ for name := range s.elems {
+ names[i] = name
+ i++
+ }
+ sort.Strings(names)
+ return names
+}
+
+// NumChildren() returns the number of scopes nested in s.
+func (s *Scope) NumChildren() int { return len(s.children) }
+
+// Child returns the i'th child scope for 0 <= i < NumChildren().
+func (s *Scope) Child(i int) *Scope { return s.children[i] }
+
+// Lookup returns the object in scope s with the given name if such an
+// object exists; otherwise the result is nil.
+func (s *Scope) Lookup(name string) Object {
+ return s.elems[name]
+}
+
+// LookupParent follows the parent chain of scopes starting with s until
+// it finds a scope where Lookup(name) returns a non-nil object, and then
+// returns that scope and object. If a valid position pos is provided,
+// only objects that were declared at or before pos are considered.
+// If no such scope and object exists, the result is (nil, nil).
+//
+// Note that obj.Parent() may be different from the returned scope if the
+// object was inserted into the scope and already had a parent at that
+// time (see Insert, below). This can only happen for dot-imported objects
+// whose scope is the scope of the package that exported them.
+func (s *Scope) LookupParent(name string, pos token.Pos) (*Scope, Object) {
+ for ; s != nil; s = s.parent {
+ if obj := s.elems[name]; obj != nil && (!pos.IsValid() || obj.scopePos() <= pos) {
+ return s, obj
+ }
+ }
+ return nil, nil
+}
+
+// Insert attempts to insert an object obj into scope s.
+// If s already contains an alternative object alt with
+// the same name, Insert leaves s unchanged and returns alt.
+// Otherwise it inserts obj, sets the object's parent scope
+// if not already set, and returns nil.
+func (s *Scope) Insert(obj Object) Object {
+ name := obj.Name()
+ if alt := s.elems[name]; alt != nil {
+ return alt
+ }
+ if s.elems == nil {
+ s.elems = make(map[string]Object)
+ }
+ s.elems[name] = obj
+ if obj.Parent() == nil {
+ obj.setParent(s)
+ }
+ return nil
+}
+
+// Pos and End describe the scope's source code extent [pos, end).
+// The results are guaranteed to be valid only if the type-checked
+// AST has complete position information. The extent is undefined
+// for Universe and package scopes.
+func (s *Scope) Pos() token.Pos { return s.pos }
+func (s *Scope) End() token.Pos { return s.end }
+
+// Contains returns true if pos is within the scope's extent.
+// The result is guaranteed to be valid only if the type-checked
+// AST has complete position information.
+func (s *Scope) Contains(pos token.Pos) bool {
+ return s.pos <= pos && pos < s.end
+}
+
+// Innermost returns the innermost (child) scope containing
+// pos. If pos is not within any scope, the result is nil.
+// The result is also nil for the Universe scope.
+// The result is guaranteed to be valid only if the type-checked
+// AST has complete position information.
+func (s *Scope) Innermost(pos token.Pos) *Scope {
+ // Package scopes do not have extents since they may be
+ // discontiguous, so iterate over the package's files.
+ if s.parent == Universe {
+ for _, s := range s.children {
+ if inner := s.Innermost(pos); inner != nil {
+ return inner
+ }
+ }
+ }
+
+ if s.Contains(pos) {
+ for _, s := range s.children {
+ if s.Contains(pos) {
+ return s.Innermost(pos)
+ }
+ }
+ return s
+ }
+ return nil
+}
+
+// WriteTo writes a string representation of the scope to w,
+// with the scope elements sorted by name.
+// The level of indentation is controlled by n >= 0, with
+// n == 0 for no indentation.
+// If recurse is set, it also writes nested (children) scopes.
+func (s *Scope) WriteTo(w io.Writer, n int, recurse bool) {
+ const ind = ". "
+ indn := strings.Repeat(ind, n)
+
+ fmt.Fprintf(w, "%s%s scope %p {", indn, s.comment, s)
+ if len(s.elems) == 0 {
+ fmt.Fprintf(w, "}\n")
+ return
+ }
+
+ fmt.Fprintln(w)
+ indn1 := indn + ind
+ for _, name := range s.Names() {
+ fmt.Fprintf(w, "%s%s\n", indn1, s.elems[name])
+ }
+
+ if recurse {
+ for _, s := range s.children {
+ fmt.Fprintln(w)
+ s.WriteTo(w, n+1, recurse)
+ }
+ }
+
+ fmt.Fprintf(w, "%s}", indn)
+}
+
+// String returns a string representation of the scope, for debugging.
+func (s *Scope) String() string {
+ var buf bytes.Buffer
+ s.WriteTo(&buf, 0, false)
+ return buf.String()
+}
diff --git a/vendor/golang.org/x/tools/go/types/selection.go b/vendor/golang.org/x/tools/go/types/selection.go
new file mode 100644
index 0000000..124e0d3
--- /dev/null
+++ b/vendor/golang.org/x/tools/go/types/selection.go
@@ -0,0 +1,143 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// This file implements Selections.
+
+package types
+
+import (
+ "bytes"
+ "fmt"
+)
+
+// SelectionKind describes the kind of a selector expression x.f
+// (excluding qualified identifiers).
+type SelectionKind int
+
+const (
+ FieldVal SelectionKind = iota // x.f is a struct field selector
+ MethodVal // x.f is a method selector
+ MethodExpr // x.f is a method expression
+)
+
+// A Selection describes a selector expression x.f.
+// For the declarations:
+//
+// type T struct{ x int; E }
+// type E struct{}
+// func (e E) m() {}
+// var p *T
+//
+// the following relations exist:
+//
+// Selector Kind Recv Obj Type Index Indirect
+//
+// p.x FieldVal T x int {0} true
+// p.m MethodVal *T m func (e *T) m() {1, 0} true
+// T.m MethodExpr T m func m(_ T) {1, 0} false
+//
+type Selection struct {
+ kind SelectionKind
+ recv Type // type of x
+ obj Object // object denoted by x.f
+ index []int // path from x to x.f
+ indirect bool // set if there was any pointer indirection on the path
+}
+
+// Kind returns the selection kind.
+func (s *Selection) Kind() SelectionKind { return s.kind }
+
+// Recv returns the type of x in x.f.
+func (s *Selection) Recv() Type { return s.recv }
+
+// Obj returns the object denoted by x.f; a *Var for
+// a field selection, and a *Func in all other cases.
+func (s *Selection) Obj() Object { return s.obj }
+
+// Type returns the type of x.f, which may be different from the type of f.
+// See Selection for more information.
+func (s *Selection) Type() Type {
+ switch s.kind {
+ case MethodVal:
+ // The type of x.f is a method with its receiver type set
+ // to the type of x.
+ sig := *s.obj.(*Func).typ.(*Signature)
+ recv := *sig.recv
+ recv.typ = s.recv
+ sig.recv = &recv
+ return &sig
+
+ case MethodExpr:
+ // The type of x.f is a function (without receiver)
+ // and an additional first argument with the same type as x.
+ // TODO(gri) Similar code is already in call.go - factor!
+ // TODO(gri) Compute this eagerly to avoid allocations.
+ sig := *s.obj.(*Func).typ.(*Signature)
+ arg0 := *sig.recv
+ sig.recv = nil
+ arg0.typ = s.recv
+ var params []*Var
+ if sig.params != nil {
+ params = sig.params.vars
+ }
+ sig.params = NewTuple(append([]*Var{&arg0}, params...)...)
+ return &sig
+ }
+
+ // In all other cases, the type of x.f is the type of x.
+ return s.obj.Type()
+}
+
+// Index describes the path from x to f in x.f.
+// The last index entry is the field or method index of the type declaring f;
+// either:
+//
+// 1) the list of declared methods of a named type; or
+// 2) the list of methods of an interface type; or
+// 3) the list of fields of a struct type.
+//
+// The earlier index entries are the indices of the embedded fields implicitly
+// traversed to get from (the type of) x to f, starting at embedding depth 0.
+func (s *Selection) Index() []int { return s.index }
+
+// Indirect reports whether any pointer indirection was required to get from
+// x to f in x.f.
+func (s *Selection) Indirect() bool { return s.indirect }
+
+func (s *Selection) String() string { return SelectionString(s, nil) }
+
+// SelectionString returns the string form of s.
+// The Qualifier controls the printing of
+// package-level objects, and may be nil.
+//
+// Examples:
+// "field (T) f int"
+// "method (T) f(X) Y"
+// "method expr (T) f(X) Y"
+//
+func SelectionString(s *Selection, qf Qualifier) string {
+ var k string
+ switch s.kind {
+ case FieldVal:
+ k = "field "
+ case MethodVal:
+ k = "method "
+ case MethodExpr:
+ k = "method expr "
+ default:
+ unreachable()
+ }
+ var buf bytes.Buffer
+ buf.WriteString(k)
+ buf.WriteByte('(')
+ WriteType(&buf, s.Recv(), qf)
+ fmt.Fprintf(&buf, ") %s", s.obj.Name())
+ if T := s.Type(); s.kind == FieldVal {
+ buf.WriteByte(' ')
+ WriteType(&buf, T, qf)
+ } else {
+ WriteSignature(&buf, T.(*Signature), qf)
+ }
+ return buf.String()
+}
diff --git a/vendor/golang.org/x/tools/go/types/sizes.go b/vendor/golang.org/x/tools/go/types/sizes.go
new file mode 100644
index 0000000..56fb310
--- /dev/null
+++ b/vendor/golang.org/x/tools/go/types/sizes.go
@@ -0,0 +1,211 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// This file implements Sizes.
+
+package types
+
+// Sizes defines the sizing functions for package unsafe.
+type Sizes interface {
+ // Alignof returns the alignment of a variable of type T.
+ // Alignof must implement the alignment guarantees required by the spec.
+ Alignof(T Type) int64
+
+ // Offsetsof returns the offsets of the given struct fields, in bytes.
+ // Offsetsof must implement the offset guarantees required by the spec.
+ Offsetsof(fields []*Var) []int64
+
+ // Sizeof returns the size of a variable of type T.
+ // Sizeof must implement the size guarantees required by the spec.
+ Sizeof(T Type) int64
+}
+
+// StdSizes is a convenience type for creating commonly used Sizes.
+// It makes the following simplifying assumptions:
+//
+// - The size of explicitly sized basic types (int16, etc.) is the
+// specified size.
+// - The size of strings and interfaces is 2*WordSize.
+// - The size of slices is 3*WordSize.
+// - The size of an array of n elements corresponds to the size of
+// a struct of n consecutive fields of the array's element type.
+// - The size of a struct is the offset of the last field plus that
+// field's size. As with all element types, if the struct is used
+// in an array its size must first be aligned to a multiple of the
+// struct's alignment.
+// - All other types have size WordSize.
+// - Arrays and structs are aligned per spec definition; all other
+// types are naturally aligned with a maximum alignment MaxAlign.
+//
+// *StdSizes implements Sizes.
+//
+type StdSizes struct {
+ WordSize int64 // word size in bytes - must be >= 4 (32bits)
+ MaxAlign int64 // maximum alignment in bytes - must be >= 1
+}
+
+func (s *StdSizes) Alignof(T Type) int64 {
+ // For arrays and structs, alignment is defined in terms
+ // of alignment of the elements and fields, respectively.
+ switch t := T.Underlying().(type) {
+ case *Array:
+ // spec: "For a variable x of array type: unsafe.Alignof(x)
+ // is the same as unsafe.Alignof(x[0]), but at least 1."
+ return s.Alignof(t.elem)
+ case *Struct:
+ // spec: "For a variable x of struct type: unsafe.Alignof(x)
+ // is the largest of the values unsafe.Alignof(x.f) for each
+ // field f of x, but at least 1."
+ max := int64(1)
+ for _, f := range t.fields {
+ if a := s.Alignof(f.typ); a > max {
+ max = a
+ }
+ }
+ return max
+ }
+ a := s.Sizeof(T) // may be 0
+ // spec: "For a variable x of any type: unsafe.Alignof(x) is at least 1."
+ if a < 1 {
+ return 1
+ }
+ if a > s.MaxAlign {
+ return s.MaxAlign
+ }
+ return a
+}
+
+func (s *StdSizes) Offsetsof(fields []*Var) []int64 {
+ offsets := make([]int64, len(fields))
+ var o int64
+ for i, f := range fields {
+ a := s.Alignof(f.typ)
+ o = align(o, a)
+ offsets[i] = o
+ o += s.Sizeof(f.typ)
+ }
+ return offsets
+}
+
+var basicSizes = [...]byte{
+ Bool: 1,
+ Int8: 1,
+ Int16: 2,
+ Int32: 4,
+ Int64: 8,
+ Uint8: 1,
+ Uint16: 2,
+ Uint32: 4,
+ Uint64: 8,
+ Float32: 4,
+ Float64: 8,
+ Complex64: 8,
+ Complex128: 16,
+}
+
+func (s *StdSizes) Sizeof(T Type) int64 {
+ switch t := T.Underlying().(type) {
+ case *Basic:
+ assert(isTyped(T))
+ k := t.kind
+ if int(k) < len(basicSizes) {
+ if s := basicSizes[k]; s > 0 {
+ return int64(s)
+ }
+ }
+ if k == String {
+ return s.WordSize * 2
+ }
+ case *Array:
+ n := t.len
+ if n == 0 {
+ return 0
+ }
+ a := s.Alignof(t.elem)
+ z := s.Sizeof(t.elem)
+ return align(z, a)*(n-1) + z
+ case *Slice:
+ return s.WordSize * 3
+ case *Struct:
+ n := t.NumFields()
+ if n == 0 {
+ return 0
+ }
+ offsets := t.offsets
+ if t.offsets == nil {
+ // compute offsets on demand
+ offsets = s.Offsetsof(t.fields)
+ t.offsets = offsets
+ }
+ return offsets[n-1] + s.Sizeof(t.fields[n-1].typ)
+ case *Interface:
+ return s.WordSize * 2
+ }
+ return s.WordSize // catch-all
+}
+
+// stdSizes is used if Config.Sizes == nil.
+var stdSizes = StdSizes{8, 8}
+
+func (conf *Config) alignof(T Type) int64 {
+ if s := conf.Sizes; s != nil {
+ if a := s.Alignof(T); a >= 1 {
+ return a
+ }
+ panic("Config.Sizes.Alignof returned an alignment < 1")
+ }
+ return stdSizes.Alignof(T)
+}
+
+func (conf *Config) offsetsof(T *Struct) []int64 {
+ offsets := T.offsets
+ if offsets == nil && T.NumFields() > 0 {
+ // compute offsets on demand
+ if s := conf.Sizes; s != nil {
+ offsets = s.Offsetsof(T.fields)
+ // sanity checks
+ if len(offsets) != T.NumFields() {
+ panic("Config.Sizes.Offsetsof returned the wrong number of offsets")
+ }
+ for _, o := range offsets {
+ if o < 0 {
+ panic("Config.Sizes.Offsetsof returned an offset < 0")
+ }
+ }
+ } else {
+ offsets = stdSizes.Offsetsof(T.fields)
+ }
+ T.offsets = offsets
+ }
+ return offsets
+}
+
+// offsetof returns the offset of the field specified via
+// the index sequence relative to typ. All embedded fields
+// must be structs (rather than pointer to structs).
+func (conf *Config) offsetof(typ Type, index []int) int64 {
+ var o int64
+ for _, i := range index {
+ s := typ.Underlying().(*Struct)
+ o += conf.offsetsof(s)[i]
+ typ = s.fields[i].typ
+ }
+ return o
+}
+
+func (conf *Config) sizeof(T Type) int64 {
+ if s := conf.Sizes; s != nil {
+ if z := s.Sizeof(T); z >= 0 {
+ return z
+ }
+ panic("Config.Sizes.Sizeof returned a size < 0")
+ }
+ return stdSizes.Sizeof(T)
+}
+
+// align returns the smallest y >= x such that y % a == 0.
+func align(x, a int64) int64 {
+ y := x + a - 1
+ return y - y%a
+}
diff --git a/vendor/golang.org/x/tools/go/types/stmt.go b/vendor/golang.org/x/tools/go/types/stmt.go
new file mode 100644
index 0000000..eeb2c31
--- /dev/null
+++ b/vendor/golang.org/x/tools/go/types/stmt.go
@@ -0,0 +1,745 @@
+// Copyright 2012 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// This file implements typechecking of statements.
+
+package types
+
+import (
+ "fmt"
+ "go/ast"
+ "go/token"
+
+ "golang.org/x/tools/go/exact"
+)
+
+func (check *Checker) funcBody(decl *declInfo, name string, sig *Signature, body *ast.BlockStmt) {
+ if trace {
+ if name == "" {
+ name = ""
+ }
+ fmt.Printf("--- %s: %s {\n", name, sig)
+ defer fmt.Println("--- ")
+ }
+
+ // set function scope extent
+ sig.scope.pos = body.Pos()
+ sig.scope.end = body.End()
+
+ // save/restore current context and setup function context
+ // (and use 0 indentation at function start)
+ defer func(ctxt context, indent int) {
+ check.context = ctxt
+ check.indent = indent
+ }(check.context, check.indent)
+ check.context = context{
+ decl: decl,
+ scope: sig.scope,
+ sig: sig,
+ }
+ check.indent = 0
+
+ check.stmtList(0, body.List)
+
+ if check.hasLabel {
+ check.labels(body)
+ }
+
+ if sig.results.Len() > 0 && !check.isTerminating(body, "") {
+ check.error(body.Rbrace, "missing return")
+ }
+
+ // spec: "Implementation restriction: A compiler may make it illegal to
+ // declare a variable inside a function body if the variable is never used."
+ // (One could check each scope after use, but that distributes this check
+ // over several places because CloseScope is not always called explicitly.)
+ check.usage(sig.scope)
+}
+
+func (check *Checker) usage(scope *Scope) {
+ for _, obj := range scope.elems {
+ if v, _ := obj.(*Var); v != nil && !v.used {
+ check.softErrorf(v.pos, "%s declared but not used", v.name)
+ }
+ }
+ for _, scope := range scope.children {
+ check.usage(scope)
+ }
+}
+
+// stmtContext is a bitset describing which
+// control-flow statements are permissible.
+type stmtContext uint
+
+const (
+ breakOk stmtContext = 1 << iota
+ continueOk
+ fallthroughOk
+)
+
+func (check *Checker) simpleStmt(s ast.Stmt) {
+ if s != nil {
+ check.stmt(0, s)
+ }
+}
+
+func (check *Checker) stmtList(ctxt stmtContext, list []ast.Stmt) {
+ ok := ctxt&fallthroughOk != 0
+ inner := ctxt &^ fallthroughOk
+ for i, s := range list {
+ inner := inner
+ if ok && i+1 == len(list) {
+ inner |= fallthroughOk
+ }
+ check.stmt(inner, s)
+ }
+}
+
+func (check *Checker) multipleDefaults(list []ast.Stmt) {
+ var first ast.Stmt
+ for _, s := range list {
+ var d ast.Stmt
+ switch c := s.(type) {
+ case *ast.CaseClause:
+ if len(c.List) == 0 {
+ d = s
+ }
+ case *ast.CommClause:
+ if c.Comm == nil {
+ d = s
+ }
+ default:
+ check.invalidAST(s.Pos(), "case/communication clause expected")
+ }
+ if d != nil {
+ if first != nil {
+ check.errorf(d.Pos(), "multiple defaults (first at %s)", first.Pos())
+ } else {
+ first = d
+ }
+ }
+ }
+}
+
+func (check *Checker) openScope(s ast.Stmt, comment string) {
+ scope := NewScope(check.scope, s.Pos(), s.End(), comment)
+ check.recordScope(s, scope)
+ check.scope = scope
+}
+
+func (check *Checker) closeScope() {
+ check.scope = check.scope.Parent()
+}
+
+func assignOp(op token.Token) token.Token {
+ // token_test.go verifies the token ordering this function relies on
+ if token.ADD_ASSIGN <= op && op <= token.AND_NOT_ASSIGN {
+ return op + (token.ADD - token.ADD_ASSIGN)
+ }
+ return token.ILLEGAL
+}
+
+func (check *Checker) suspendedCall(keyword string, call *ast.CallExpr) {
+ var x operand
+ var msg string
+ switch check.rawExpr(&x, call, nil) {
+ case conversion:
+ msg = "requires function call, not conversion"
+ case expression:
+ msg = "discards result of"
+ case statement:
+ return
+ default:
+ unreachable()
+ }
+ check.errorf(x.pos(), "%s %s %s", keyword, msg, &x)
+}
+
+func (check *Checker) caseValues(x operand /* copy argument (not *operand!) */, values []ast.Expr) {
+ // No duplicate checking for now. See issue 4524.
+ for _, e := range values {
+ var y operand
+ check.expr(&y, e)
+ if y.mode == invalid {
+ return
+ }
+ // TODO(gri) The convertUntyped call pair below appears in other places. Factor!
+ // Order matters: By comparing y against x, error positions are at the case values.
+ check.convertUntyped(&y, x.typ)
+ if y.mode == invalid {
+ return
+ }
+ check.convertUntyped(&x, y.typ)
+ if x.mode == invalid {
+ return
+ }
+ check.comparison(&y, &x, token.EQL)
+ }
+}
+
+func (check *Checker) caseTypes(x *operand, xtyp *Interface, types []ast.Expr, seen map[Type]token.Pos) (T Type) {
+L:
+ for _, e := range types {
+ T = check.typOrNil(e)
+ if T == Typ[Invalid] {
+ continue
+ }
+ // complain about duplicate types
+ // TODO(gri) use a type hash to avoid quadratic algorithm
+ for t, pos := range seen {
+ if T == nil && t == nil || T != nil && t != nil && Identical(T, t) {
+ // talk about "case" rather than "type" because of nil case
+ check.error(e.Pos(), "duplicate case in type switch")
+ check.errorf(pos, "\tprevious case %s", T) // secondary error, \t indented
+ continue L
+ }
+ }
+ seen[T] = e.Pos()
+ if T != nil {
+ check.typeAssertion(e.Pos(), x, xtyp, T)
+ }
+ }
+ return
+}
+
+// stmt typechecks statement s.
+func (check *Checker) stmt(ctxt stmtContext, s ast.Stmt) {
+ // statements cannot use iota in general
+ // (constant declarations set it explicitly)
+ assert(check.iota == nil)
+
+ // statements must end with the same top scope as they started with
+ if debug {
+ defer func(scope *Scope) {
+ // don't check if code is panicking
+ if p := recover(); p != nil {
+ panic(p)
+ }
+ assert(scope == check.scope)
+ }(check.scope)
+ }
+
+ inner := ctxt &^ fallthroughOk
+ switch s := s.(type) {
+ case *ast.BadStmt, *ast.EmptyStmt:
+ // ignore
+
+ case *ast.DeclStmt:
+ check.declStmt(s.Decl)
+
+ case *ast.LabeledStmt:
+ check.hasLabel = true
+ check.stmt(ctxt, s.Stmt)
+
+ case *ast.ExprStmt:
+ // spec: "With the exception of specific built-in functions,
+ // function and method calls and receive operations can appear
+ // in statement context. Such statements may be parenthesized."
+ var x operand
+ kind := check.rawExpr(&x, s.X, nil)
+ var msg string
+ switch x.mode {
+ default:
+ if kind == statement {
+ return
+ }
+ msg = "is not used"
+ case builtin:
+ msg = "must be called"
+ case typexpr:
+ msg = "is not an expression"
+ }
+ check.errorf(x.pos(), "%s %s", &x, msg)
+
+ case *ast.SendStmt:
+ var ch, x operand
+ check.expr(&ch, s.Chan)
+ check.expr(&x, s.Value)
+ if ch.mode == invalid || x.mode == invalid {
+ return
+ }
+ if tch, ok := ch.typ.Underlying().(*Chan); !ok || tch.dir == RecvOnly || !check.assignment(&x, tch.elem) {
+ if x.mode != invalid {
+ check.invalidOp(ch.pos(), "cannot send %s to channel %s", &x, &ch)
+ }
+ }
+
+ case *ast.IncDecStmt:
+ var op token.Token
+ switch s.Tok {
+ case token.INC:
+ op = token.ADD
+ case token.DEC:
+ op = token.SUB
+ default:
+ check.invalidAST(s.TokPos, "unknown inc/dec operation %s", s.Tok)
+ return
+ }
+ var x operand
+ Y := &ast.BasicLit{ValuePos: s.X.Pos(), Kind: token.INT, Value: "1"} // use x's position
+ check.binary(&x, nil, s.X, Y, op)
+ if x.mode == invalid {
+ return
+ }
+ check.assignVar(s.X, &x)
+
+ case *ast.AssignStmt:
+ switch s.Tok {
+ case token.ASSIGN, token.DEFINE:
+ if len(s.Lhs) == 0 {
+ check.invalidAST(s.Pos(), "missing lhs in assignment")
+ return
+ }
+ if s.Tok == token.DEFINE {
+ check.shortVarDecl(s.TokPos, s.Lhs, s.Rhs)
+ } else {
+ // regular assignment
+ check.assignVars(s.Lhs, s.Rhs)
+ }
+
+ default:
+ // assignment operations
+ if len(s.Lhs) != 1 || len(s.Rhs) != 1 {
+ check.errorf(s.TokPos, "assignment operation %s requires single-valued expressions", s.Tok)
+ return
+ }
+ op := assignOp(s.Tok)
+ if op == token.ILLEGAL {
+ check.invalidAST(s.TokPos, "unknown assignment operation %s", s.Tok)
+ return
+ }
+ var x operand
+ check.binary(&x, nil, s.Lhs[0], s.Rhs[0], op)
+ if x.mode == invalid {
+ return
+ }
+ check.assignVar(s.Lhs[0], &x)
+ }
+
+ case *ast.GoStmt:
+ check.suspendedCall("go", s.Call)
+
+ case *ast.DeferStmt:
+ check.suspendedCall("defer", s.Call)
+
+ case *ast.ReturnStmt:
+ res := check.sig.results
+ if res.Len() > 0 {
+ // function returns results
+ // (if one, say the first, result parameter is named, all of them are named)
+ if len(s.Results) == 0 && res.vars[0].name != "" {
+ // spec: "Implementation restriction: A compiler may disallow an empty expression
+ // list in a "return" statement if a different entity (constant, type, or variable)
+ // with the same name as a result parameter is in scope at the place of the return."
+ for _, obj := range res.vars {
+ if _, alt := check.scope.LookupParent(obj.name, check.pos); alt != nil && alt != obj {
+ check.errorf(s.Pos(), "result parameter %s not in scope at return", obj.name)
+ check.errorf(alt.Pos(), "\tinner declaration of %s", obj)
+ // ok to continue
+ }
+ }
+ } else {
+ // return has results or result parameters are unnamed
+ check.initVars(res.vars, s.Results, s.Return)
+ }
+ } else if len(s.Results) > 0 {
+ check.error(s.Results[0].Pos(), "no result values expected")
+ check.use(s.Results...)
+ }
+
+ case *ast.BranchStmt:
+ if s.Label != nil {
+ check.hasLabel = true
+ return // checked in 2nd pass (check.labels)
+ }
+ switch s.Tok {
+ case token.BREAK:
+ if ctxt&breakOk == 0 {
+ check.error(s.Pos(), "break not in for, switch, or select statement")
+ }
+ case token.CONTINUE:
+ if ctxt&continueOk == 0 {
+ check.error(s.Pos(), "continue not in for statement")
+ }
+ case token.FALLTHROUGH:
+ if ctxt&fallthroughOk == 0 {
+ check.error(s.Pos(), "fallthrough statement out of place")
+ }
+ default:
+ check.invalidAST(s.Pos(), "branch statement: %s", s.Tok)
+ }
+
+ case *ast.BlockStmt:
+ check.openScope(s, "block")
+ defer check.closeScope()
+
+ check.stmtList(inner, s.List)
+
+ case *ast.IfStmt:
+ check.openScope(s, "if")
+ defer check.closeScope()
+
+ check.simpleStmt(s.Init)
+ var x operand
+ check.expr(&x, s.Cond)
+ if x.mode != invalid && !isBoolean(x.typ) {
+ check.error(s.Cond.Pos(), "non-boolean condition in if statement")
+ }
+ check.stmt(inner, s.Body)
+ if s.Else != nil {
+ check.stmt(inner, s.Else)
+ }
+
+ case *ast.SwitchStmt:
+ inner |= breakOk
+ check.openScope(s, "switch")
+ defer check.closeScope()
+
+ check.simpleStmt(s.Init)
+ var x operand
+ if s.Tag != nil {
+ check.expr(&x, s.Tag)
+ } else {
+ // spec: "A missing switch expression is
+ // equivalent to the boolean value true."
+ x.mode = constant
+ x.typ = Typ[Bool]
+ x.val = exact.MakeBool(true)
+ x.expr = &ast.Ident{NamePos: s.Body.Lbrace, Name: "true"}
+ }
+
+ check.multipleDefaults(s.Body.List)
+
+ for i, c := range s.Body.List {
+ clause, _ := c.(*ast.CaseClause)
+ if clause == nil {
+ check.invalidAST(c.Pos(), "incorrect expression switch case")
+ continue
+ }
+ if x.mode != invalid {
+ check.caseValues(x, clause.List)
+ }
+ check.openScope(clause, "case")
+ inner := inner
+ if i+1 < len(s.Body.List) {
+ inner |= fallthroughOk
+ }
+ check.stmtList(inner, clause.Body)
+ check.closeScope()
+ }
+
+ case *ast.TypeSwitchStmt:
+ inner |= breakOk
+ check.openScope(s, "type switch")
+ defer check.closeScope()
+
+ check.simpleStmt(s.Init)
+
+ // A type switch guard must be of the form:
+ //
+ // TypeSwitchGuard = [ identifier ":=" ] PrimaryExpr "." "(" "type" ")" .
+ //
+ // The parser is checking syntactic correctness;
+ // remaining syntactic errors are considered AST errors here.
+ // TODO(gri) better factoring of error handling (invalid ASTs)
+ //
+ var lhs *ast.Ident // lhs identifier or nil
+ var rhs ast.Expr
+ switch guard := s.Assign.(type) {
+ case *ast.ExprStmt:
+ rhs = guard.X
+ case *ast.AssignStmt:
+ if len(guard.Lhs) != 1 || guard.Tok != token.DEFINE || len(guard.Rhs) != 1 {
+ check.invalidAST(s.Pos(), "incorrect form of type switch guard")
+ return
+ }
+
+ lhs, _ = guard.Lhs[0].(*ast.Ident)
+ if lhs == nil {
+ check.invalidAST(s.Pos(), "incorrect form of type switch guard")
+ return
+ }
+
+ if lhs.Name == "_" {
+ // _ := x.(type) is an invalid short variable declaration
+ check.softErrorf(lhs.Pos(), "no new variable on left side of :=")
+ lhs = nil // avoid declared but not used error below
+ } else {
+ check.recordDef(lhs, nil) // lhs variable is implicitly declared in each cause clause
+ }
+
+ rhs = guard.Rhs[0]
+
+ default:
+ check.invalidAST(s.Pos(), "incorrect form of type switch guard")
+ return
+ }
+
+ // rhs must be of the form: expr.(type) and expr must be an interface
+ expr, _ := rhs.(*ast.TypeAssertExpr)
+ if expr == nil || expr.Type != nil {
+ check.invalidAST(s.Pos(), "incorrect form of type switch guard")
+ return
+ }
+ var x operand
+ check.expr(&x, expr.X)
+ if x.mode == invalid {
+ return
+ }
+ xtyp, _ := x.typ.Underlying().(*Interface)
+ if xtyp == nil {
+ check.errorf(x.pos(), "%s is not an interface", &x)
+ return
+ }
+
+ check.multipleDefaults(s.Body.List)
+
+ var lhsVars []*Var // list of implicitly declared lhs variables
+ seen := make(map[Type]token.Pos) // map of seen types to positions
+ for _, s := range s.Body.List {
+ clause, _ := s.(*ast.CaseClause)
+ if clause == nil {
+ check.invalidAST(s.Pos(), "incorrect type switch case")
+ continue
+ }
+ // Check each type in this type switch case.
+ T := check.caseTypes(&x, xtyp, clause.List, seen)
+ check.openScope(clause, "case")
+ // If lhs exists, declare a corresponding variable in the case-local scope.
+ if lhs != nil {
+ // spec: "The TypeSwitchGuard may include a short variable declaration.
+ // When that form is used, the variable is declared at the beginning of
+ // the implicit block in each clause. In clauses with a case listing
+ // exactly one type, the variable has that type; otherwise, the variable
+ // has the type of the expression in the TypeSwitchGuard."
+ if len(clause.List) != 1 || T == nil {
+ T = x.typ
+ }
+ obj := NewVar(lhs.Pos(), check.pkg, lhs.Name, T)
+ scopePos := clause.End()
+ if len(clause.Body) > 0 {
+ scopePos = clause.Body[0].Pos()
+ }
+ check.declare(check.scope, nil, obj, scopePos)
+ check.recordImplicit(clause, obj)
+ // For the "declared but not used" error, all lhs variables act as
+ // one; i.e., if any one of them is 'used', all of them are 'used'.
+ // Collect them for later analysis.
+ lhsVars = append(lhsVars, obj)
+ }
+ check.stmtList(inner, clause.Body)
+ check.closeScope()
+ }
+
+ // If lhs exists, we must have at least one lhs variable that was used.
+ if lhs != nil {
+ var used bool
+ for _, v := range lhsVars {
+ if v.used {
+ used = true
+ }
+ v.used = true // avoid usage error when checking entire function
+ }
+ if !used {
+ check.softErrorf(lhs.Pos(), "%s declared but not used", lhs.Name)
+ }
+ }
+
+ case *ast.SelectStmt:
+ inner |= breakOk
+
+ check.multipleDefaults(s.Body.List)
+
+ for _, s := range s.Body.List {
+ clause, _ := s.(*ast.CommClause)
+ if clause == nil {
+ continue // error reported before
+ }
+
+ // clause.Comm must be a SendStmt, RecvStmt, or default case
+ valid := false
+ var rhs ast.Expr // rhs of RecvStmt, or nil
+ switch s := clause.Comm.(type) {
+ case nil, *ast.SendStmt:
+ valid = true
+ case *ast.AssignStmt:
+ if len(s.Rhs) == 1 {
+ rhs = s.Rhs[0]
+ }
+ case *ast.ExprStmt:
+ rhs = s.X
+ }
+
+ // if present, rhs must be a receive operation
+ if rhs != nil {
+ if x, _ := unparen(rhs).(*ast.UnaryExpr); x != nil && x.Op == token.ARROW {
+ valid = true
+ }
+ }
+
+ if !valid {
+ check.error(clause.Comm.Pos(), "select case must be send or receive (possibly with assignment)")
+ continue
+ }
+
+ check.openScope(s, "case")
+ if clause.Comm != nil {
+ check.stmt(inner, clause.Comm)
+ }
+ check.stmtList(inner, clause.Body)
+ check.closeScope()
+ }
+
+ case *ast.ForStmt:
+ inner |= breakOk | continueOk
+ check.openScope(s, "for")
+ defer check.closeScope()
+
+ check.simpleStmt(s.Init)
+ if s.Cond != nil {
+ var x operand
+ check.expr(&x, s.Cond)
+ if x.mode != invalid && !isBoolean(x.typ) {
+ check.error(s.Cond.Pos(), "non-boolean condition in for statement")
+ }
+ }
+ check.simpleStmt(s.Post)
+ // spec: "The init statement may be a short variable
+ // declaration, but the post statement must not."
+ if s, _ := s.Post.(*ast.AssignStmt); s != nil && s.Tok == token.DEFINE {
+ check.softErrorf(s.Pos(), "cannot declare in post statement")
+ check.use(s.Lhs...) // avoid follow-up errors
+ }
+ check.stmt(inner, s.Body)
+
+ case *ast.RangeStmt:
+ inner |= breakOk | continueOk
+ check.openScope(s, "for")
+ defer check.closeScope()
+
+ // check expression to iterate over
+ var x operand
+ check.expr(&x, s.X)
+
+ // determine key/value types
+ var key, val Type
+ if x.mode != invalid {
+ switch typ := x.typ.Underlying().(type) {
+ case *Basic:
+ if isString(typ) {
+ key = Typ[Int]
+ val = universeRune // use 'rune' name
+ }
+ case *Array:
+ key = Typ[Int]
+ val = typ.elem
+ case *Slice:
+ key = Typ[Int]
+ val = typ.elem
+ case *Pointer:
+ if typ, _ := typ.base.Underlying().(*Array); typ != nil {
+ key = Typ[Int]
+ val = typ.elem
+ }
+ case *Map:
+ key = typ.key
+ val = typ.elem
+ case *Chan:
+ key = typ.elem
+ val = Typ[Invalid]
+ if typ.dir == SendOnly {
+ check.errorf(x.pos(), "cannot range over send-only channel %s", &x)
+ // ok to continue
+ }
+ if s.Value != nil {
+ check.errorf(s.Value.Pos(), "iteration over %s permits only one iteration variable", &x)
+ // ok to continue
+ }
+ }
+ }
+
+ if key == nil {
+ check.errorf(x.pos(), "cannot range over %s", &x)
+ // ok to continue
+ }
+
+ // check assignment to/declaration of iteration variables
+ // (irregular assignment, cannot easily map to existing assignment checks)
+
+ // lhs expressions and initialization value (rhs) types
+ lhs := [2]ast.Expr{s.Key, s.Value}
+ rhs := [2]Type{key, val} // key, val may be nil
+
+ if s.Tok == token.DEFINE {
+ // short variable declaration; variable scope starts after the range clause
+ // (the for loop opens a new scope, so variables on the lhs never redeclare
+ // previously declared variables)
+ var vars []*Var
+ for i, lhs := range lhs {
+ if lhs == nil {
+ continue
+ }
+
+ // determine lhs variable
+ var obj *Var
+ if ident, _ := lhs.(*ast.Ident); ident != nil {
+ // declare new variable
+ name := ident.Name
+ obj = NewVar(ident.Pos(), check.pkg, name, nil)
+ check.recordDef(ident, obj)
+ // _ variables don't count as new variables
+ if name != "_" {
+ vars = append(vars, obj)
+ }
+ } else {
+ check.errorf(lhs.Pos(), "cannot declare %s", lhs)
+ obj = NewVar(lhs.Pos(), check.pkg, "_", nil) // dummy variable
+ }
+
+ // initialize lhs variable
+ if typ := rhs[i]; typ != nil {
+ x.mode = value
+ x.expr = lhs // we don't have a better rhs expression to use here
+ x.typ = typ
+ check.initVar(obj, &x, false)
+ } else {
+ obj.typ = Typ[Invalid]
+ obj.used = true // don't complain about unused variable
+ }
+ }
+
+ // declare variables
+ if len(vars) > 0 {
+ for _, obj := range vars {
+ // spec: "The scope of a constant or variable identifier declared inside
+ // a function begins at the end of the ConstSpec or VarSpec (ShortVarDecl
+ // for short variable declarations) and ends at the end of the innermost
+ // containing block."
+ scopePos := s.End()
+ check.declare(check.scope, nil /* recordDef already called */, obj, scopePos)
+ }
+ } else {
+ check.error(s.TokPos, "no new variables on left side of :=")
+ }
+ } else {
+ // ordinary assignment
+ for i, lhs := range lhs {
+ if lhs == nil {
+ continue
+ }
+ if typ := rhs[i]; typ != nil {
+ x.mode = value
+ x.expr = lhs // we don't have a better rhs expression to use here
+ x.typ = typ
+ check.assignVar(lhs, &x)
+ }
+ }
+ }
+
+ check.stmt(inner, s.Body)
+
+ default:
+ check.error(s.Pos(), "invalid statement")
+ }
+}
diff --git a/vendor/golang.org/x/tools/go/types/type.go b/vendor/golang.org/x/tools/go/types/type.go
new file mode 100644
index 0000000..1df8b45
--- /dev/null
+++ b/vendor/golang.org/x/tools/go/types/type.go
@@ -0,0 +1,454 @@
+// Copyright 2011 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package types
+
+import "sort"
+
+// TODO(gri) Revisit factory functions - make sure they have all relevant parameters.
+
+// A Type represents a type of Go.
+// All types implement the Type interface.
+type Type interface {
+ // Underlying returns the underlying type of a type.
+ Underlying() Type
+
+ // String returns a string representation of a type.
+ String() string
+}
+
+// BasicKind describes the kind of basic type.
+type BasicKind int
+
+const (
+ Invalid BasicKind = iota // type is invalid
+
+ // predeclared types
+ Bool
+ Int
+ Int8
+ Int16
+ Int32
+ Int64
+ Uint
+ Uint8
+ Uint16
+ Uint32
+ Uint64
+ Uintptr
+ Float32
+ Float64
+ Complex64
+ Complex128
+ String
+ UnsafePointer
+
+ // types for untyped values
+ UntypedBool
+ UntypedInt
+ UntypedRune
+ UntypedFloat
+ UntypedComplex
+ UntypedString
+ UntypedNil
+
+ // aliases
+ Byte = Uint8
+ Rune = Int32
+)
+
+// BasicInfo is a set of flags describing properties of a basic type.
+type BasicInfo int
+
+// Properties of basic types.
+const (
+ IsBoolean BasicInfo = 1 << iota
+ IsInteger
+ IsUnsigned
+ IsFloat
+ IsComplex
+ IsString
+ IsUntyped
+
+ IsOrdered = IsInteger | IsFloat | IsString
+ IsNumeric = IsInteger | IsFloat | IsComplex
+ IsConstType = IsBoolean | IsNumeric | IsString
+)
+
+// A Basic represents a basic type.
+type Basic struct {
+ kind BasicKind
+ info BasicInfo
+ name string
+}
+
+// Kind returns the kind of basic type b.
+func (b *Basic) Kind() BasicKind { return b.kind }
+
+// Info returns information about properties of basic type b.
+func (b *Basic) Info() BasicInfo { return b.info }
+
+// Name returns the name of basic type b.
+func (b *Basic) Name() string { return b.name }
+
+// An Array represents an array type.
+type Array struct {
+ len int64
+ elem Type
+}
+
+// NewArray returns a new array type for the given element type and length.
+func NewArray(elem Type, len int64) *Array { return &Array{len, elem} }
+
+// Len returns the length of array a.
+func (a *Array) Len() int64 { return a.len }
+
+// Elem returns element type of array a.
+func (a *Array) Elem() Type { return a.elem }
+
+// A Slice represents a slice type.
+type Slice struct {
+ elem Type
+}
+
+// NewSlice returns a new slice type for the given element type.
+func NewSlice(elem Type) *Slice { return &Slice{elem} }
+
+// Elem returns the element type of slice s.
+func (s *Slice) Elem() Type { return s.elem }
+
+// A Struct represents a struct type.
+type Struct struct {
+ fields []*Var
+ tags []string // field tags; nil if there are no tags
+ // TODO(gri) access to offsets is not threadsafe - fix this
+ offsets []int64 // field offsets in bytes, lazily initialized
+}
+
+// NewStruct returns a new struct with the given fields and corresponding field tags.
+// If a field with index i has a tag, tags[i] must be that tag, but len(tags) may be
+// only as long as required to hold the tag with the largest index i. Consequently,
+// if no field has a tag, tags may be nil.
+func NewStruct(fields []*Var, tags []string) *Struct {
+ var fset objset
+ for _, f := range fields {
+ if f.name != "_" && fset.insert(f) != nil {
+ panic("multiple fields with the same name")
+ }
+ }
+ if len(tags) > len(fields) {
+ panic("more tags than fields")
+ }
+ return &Struct{fields: fields, tags: tags}
+}
+
+// NumFields returns the number of fields in the struct (including blank and anonymous fields).
+func (s *Struct) NumFields() int { return len(s.fields) }
+
+// Field returns the i'th field for 0 <= i < NumFields().
+func (s *Struct) Field(i int) *Var { return s.fields[i] }
+
+// Tag returns the i'th field tag for 0 <= i < NumFields().
+func (s *Struct) Tag(i int) string {
+ if i < len(s.tags) {
+ return s.tags[i]
+ }
+ return ""
+}
+
+// A Pointer represents a pointer type.
+type Pointer struct {
+ base Type // element type
+}
+
+// NewPointer returns a new pointer type for the given element (base) type.
+func NewPointer(elem Type) *Pointer { return &Pointer{base: elem} }
+
+// Elem returns the element type for the given pointer p.
+func (p *Pointer) Elem() Type { return p.base }
+
+// A Tuple represents an ordered list of variables; a nil *Tuple is a valid (empty) tuple.
+// Tuples are used as components of signatures and to represent the type of multiple
+// assignments; they are not first class types of Go.
+type Tuple struct {
+ vars []*Var
+}
+
+// NewTuple returns a new tuple for the given variables.
+func NewTuple(x ...*Var) *Tuple {
+ if len(x) > 0 {
+ return &Tuple{x}
+ }
+ return nil
+}
+
+// Len returns the number variables of tuple t.
+func (t *Tuple) Len() int {
+ if t != nil {
+ return len(t.vars)
+ }
+ return 0
+}
+
+// At returns the i'th variable of tuple t.
+func (t *Tuple) At(i int) *Var { return t.vars[i] }
+
+// A Signature represents a (non-builtin) function or method type.
+type Signature struct {
+ // We need to keep the scope in Signature (rather than passing it around
+ // and store it in the Func Object) because when type-checking a function
+ // literal we call the general type checker which returns a general Type.
+ // We then unpack the *Signature and use the scope for the literal body.
+ scope *Scope // function scope, present for package-local signatures
+ recv *Var // nil if not a method
+ params *Tuple // (incoming) parameters from left to right; or nil
+ results *Tuple // (outgoing) results from left to right; or nil
+ variadic bool // true if the last parameter's type is of the form ...T (or string, for append built-in only)
+}
+
+// NewSignature returns a new function type for the given receiver, parameters,
+// and results, either of which may be nil. If variadic is set, the function
+// is variadic, it must have at least one parameter, and the last parameter
+// must be of unnamed slice type.
+func NewSignature(recv *Var, params, results *Tuple, variadic bool) *Signature {
+ if variadic {
+ n := params.Len()
+ if n == 0 {
+ panic("types.NewSignature: variadic function must have at least one parameter")
+ }
+ if _, ok := params.At(n - 1).typ.(*Slice); !ok {
+ panic("types.NewSignature: variadic parameter must be of unnamed slice type")
+ }
+ }
+ return &Signature{nil, recv, params, results, variadic}
+}
+
+// Recv returns the receiver of signature s (if a method), or nil if a
+// function.
+//
+// For an abstract method, Recv returns the enclosing interface either
+// as a *Named or an *Interface. Due to embedding, an interface may
+// contain methods whose receiver type is a different interface.
+func (s *Signature) Recv() *Var { return s.recv }
+
+// Params returns the parameters of signature s, or nil.
+func (s *Signature) Params() *Tuple { return s.params }
+
+// Results returns the results of signature s, or nil.
+func (s *Signature) Results() *Tuple { return s.results }
+
+// Variadic reports whether the signature s is variadic.
+func (s *Signature) Variadic() bool { return s.variadic }
+
+// An Interface represents an interface type.
+type Interface struct {
+ methods []*Func // ordered list of explicitly declared methods
+ embeddeds []*Named // ordered list of explicitly embedded types
+
+ allMethods []*Func // ordered list of methods declared with or embedded in this interface (TODO(gri): replace with mset)
+}
+
+// NewInterface returns a new interface for the given methods and embedded types.
+func NewInterface(methods []*Func, embeddeds []*Named) *Interface {
+ typ := new(Interface)
+
+ var mset objset
+ for _, m := range methods {
+ if mset.insert(m) != nil {
+ panic("multiple methods with the same name")
+ }
+ // set receiver
+ // TODO(gri) Ideally, we should use a named type here instead of
+ // typ, for less verbose printing of interface method signatures.
+ m.typ.(*Signature).recv = NewVar(m.pos, m.pkg, "", typ)
+ }
+ sort.Sort(byUniqueMethodName(methods))
+
+ if embeddeds == nil {
+ sort.Sort(byUniqueTypeName(embeddeds))
+ }
+
+ typ.methods = methods
+ typ.embeddeds = embeddeds
+ return typ
+}
+
+// NumExplicitMethods returns the number of explicitly declared methods of interface t.
+func (t *Interface) NumExplicitMethods() int { return len(t.methods) }
+
+// ExplicitMethod returns the i'th explicitly declared method of interface t for 0 <= i < t.NumExplicitMethods().
+// The methods are ordered by their unique Id.
+func (t *Interface) ExplicitMethod(i int) *Func { return t.methods[i] }
+
+// NumEmbeddeds returns the number of embedded types in interface t.
+func (t *Interface) NumEmbeddeds() int { return len(t.embeddeds) }
+
+// Embedded returns the i'th embedded type of interface t for 0 <= i < t.NumEmbeddeds().
+// The types are ordered by the corresponding TypeName's unique Id.
+func (t *Interface) Embedded(i int) *Named { return t.embeddeds[i] }
+
+// NumMethods returns the total number of methods of interface t.
+func (t *Interface) NumMethods() int { return len(t.allMethods) }
+
+// Method returns the i'th method of interface t for 0 <= i < t.NumMethods().
+// The methods are ordered by their unique Id.
+func (t *Interface) Method(i int) *Func { return t.allMethods[i] }
+
+// Empty returns true if t is the empty interface.
+func (t *Interface) Empty() bool { return len(t.allMethods) == 0 }
+
+// Complete computes the interface's method set. It must be called by users of
+// NewInterface after the interface's embedded types are fully defined and
+// before using the interface type in any way other than to form other types.
+// Complete returns the receiver.
+func (t *Interface) Complete() *Interface {
+ if t.allMethods != nil {
+ return t
+ }
+
+ var allMethods []*Func
+ if t.embeddeds == nil {
+ if t.methods == nil {
+ allMethods = make([]*Func, 0, 1)
+ } else {
+ allMethods = t.methods
+ }
+ } else {
+ allMethods = append(allMethods, t.methods...)
+ for _, et := range t.embeddeds {
+ it := et.Underlying().(*Interface)
+ it.Complete()
+ for _, tm := range it.allMethods {
+ // Make a copy of the method and adjust its receiver type.
+ newm := *tm
+ newmtyp := *tm.typ.(*Signature)
+ newm.typ = &newmtyp
+ newmtyp.recv = NewVar(newm.pos, newm.pkg, "", t)
+ allMethods = append(allMethods, &newm)
+ }
+ }
+ sort.Sort(byUniqueMethodName(allMethods))
+ }
+ t.allMethods = allMethods
+
+ return t
+}
+
+// A Map represents a map type.
+type Map struct {
+ key, elem Type
+}
+
+// NewMap returns a new map for the given key and element types.
+func NewMap(key, elem Type) *Map {
+ return &Map{key, elem}
+}
+
+// Key returns the key type of map m.
+func (m *Map) Key() Type { return m.key }
+
+// Elem returns the element type of map m.
+func (m *Map) Elem() Type { return m.elem }
+
+// A Chan represents a channel type.
+type Chan struct {
+ dir ChanDir
+ elem Type
+}
+
+// A ChanDir value indicates a channel direction.
+type ChanDir int
+
+// The direction of a channel is indicated by one of the following constants.
+const (
+ SendRecv ChanDir = iota
+ SendOnly
+ RecvOnly
+)
+
+// NewChan returns a new channel type for the given direction and element type.
+func NewChan(dir ChanDir, elem Type) *Chan {
+ return &Chan{dir, elem}
+}
+
+// Dir returns the direction of channel c.
+func (c *Chan) Dir() ChanDir { return c.dir }
+
+// Elem returns the element type of channel c.
+func (c *Chan) Elem() Type { return c.elem }
+
+// A Named represents a named type.
+type Named struct {
+ obj *TypeName // corresponding declared object
+ underlying Type // possibly a *Named during setup; never a *Named once set up completely
+ methods []*Func // methods declared for this type (not the method set of this type)
+}
+
+// NewNamed returns a new named type for the given type name, underlying type, and associated methods.
+// The underlying type must not be a *Named.
+func NewNamed(obj *TypeName, underlying Type, methods []*Func) *Named {
+ if _, ok := underlying.(*Named); ok {
+ panic("types.NewNamed: underlying type must not be *Named")
+ }
+ typ := &Named{obj: obj, underlying: underlying, methods: methods}
+ if obj.typ == nil {
+ obj.typ = typ
+ }
+ return typ
+}
+
+// TypeName returns the type name for the named type t.
+func (t *Named) Obj() *TypeName { return t.obj }
+
+// NumMethods returns the number of explicit methods whose receiver is named type t.
+func (t *Named) NumMethods() int { return len(t.methods) }
+
+// Method returns the i'th method of named type t for 0 <= i < t.NumMethods().
+func (t *Named) Method(i int) *Func { return t.methods[i] }
+
+// SetUnderlying sets the underlying type and marks t as complete.
+// TODO(gri) determine if there's a better solution rather than providing this function
+func (t *Named) SetUnderlying(underlying Type) {
+ if underlying == nil {
+ panic("types.Named.SetUnderlying: underlying type must not be nil")
+ }
+ if _, ok := underlying.(*Named); ok {
+ panic("types.Named.SetUnderlying: underlying type must not be *Named")
+ }
+ t.underlying = underlying
+}
+
+// AddMethod adds method m unless it is already in the method list.
+// TODO(gri) find a better solution instead of providing this function
+func (t *Named) AddMethod(m *Func) {
+ if i, _ := lookupMethod(t.methods, m.pkg, m.name); i < 0 {
+ t.methods = append(t.methods, m)
+ }
+}
+
+// Implementations for Type methods.
+
+func (t *Basic) Underlying() Type { return t }
+func (t *Array) Underlying() Type { return t }
+func (t *Slice) Underlying() Type { return t }
+func (t *Struct) Underlying() Type { return t }
+func (t *Pointer) Underlying() Type { return t }
+func (t *Tuple) Underlying() Type { return t }
+func (t *Signature) Underlying() Type { return t }
+func (t *Interface) Underlying() Type { return t }
+func (t *Map) Underlying() Type { return t }
+func (t *Chan) Underlying() Type { return t }
+func (t *Named) Underlying() Type { return t.underlying }
+
+func (t *Basic) String() string { return TypeString(t, nil) }
+func (t *Array) String() string { return TypeString(t, nil) }
+func (t *Slice) String() string { return TypeString(t, nil) }
+func (t *Struct) String() string { return TypeString(t, nil) }
+func (t *Pointer) String() string { return TypeString(t, nil) }
+func (t *Tuple) String() string { return TypeString(t, nil) }
+func (t *Signature) String() string { return TypeString(t, nil) }
+func (t *Interface) String() string { return TypeString(t, nil) }
+func (t *Map) String() string { return TypeString(t, nil) }
+func (t *Chan) String() string { return TypeString(t, nil) }
+func (t *Named) String() string { return TypeString(t, nil) }
diff --git a/vendor/golang.org/x/tools/go/types/typestring.go b/vendor/golang.org/x/tools/go/types/typestring.go
new file mode 100644
index 0000000..abee8ab
--- /dev/null
+++ b/vendor/golang.org/x/tools/go/types/typestring.go
@@ -0,0 +1,292 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// This file implements printing of types.
+
+package types
+
+import (
+ "bytes"
+ "fmt"
+)
+
+// A Qualifier controls how named package-level objects are printed in
+// calls to TypeString, ObjectString, and SelectionString.
+//
+// These three formatting routines call the Qualifier for each
+// package-level object O, and if the Qualifier returns a non-empty
+// string p, the object is printed in the form p.O.
+// If it returns an empty string, only the object name O is printed.
+//
+// Using a nil Qualifier is equivalent to using (*Package).Path: the
+// object is qualified by the import path, e.g., "encoding/json.Marshal".
+//
+type Qualifier func(*Package) string
+
+// RelativeTo(pkg) returns a Qualifier that fully qualifies members of
+// all packages other than pkg.
+func RelativeTo(pkg *Package) Qualifier {
+ if pkg == nil {
+ return nil
+ }
+ return func(other *Package) string {
+ if pkg == other {
+ return "" // same package; unqualified
+ }
+ return other.Path()
+ }
+}
+
+// If GcCompatibilityMode is set, printing of types is modified
+// to match the representation of some types in the gc compiler:
+//
+// - byte and rune lose their alias name and simply stand for
+// uint8 and int32 respectively
+// - embedded interfaces get flattened (the embedding info is lost,
+// and certain recursive interface types cannot be printed anymore)
+//
+// This makes it easier to compare packages computed with the type-
+// checker vs packages imported from gc export data.
+//
+// Caution: This flag affects all uses of WriteType, globally.
+// It is only provided for testing in conjunction with
+// gc-generated data. It may be removed at any time.
+var GcCompatibilityMode bool
+
+// TypeString returns the string representation of typ.
+// The Qualifier controls the printing of
+// package-level objects, and may be nil.
+func TypeString(typ Type, qf Qualifier) string {
+ var buf bytes.Buffer
+ WriteType(&buf, typ, qf)
+ return buf.String()
+}
+
+// WriteType writes the string representation of typ to buf.
+// The Qualifier controls the printing of
+// package-level objects, and may be nil.
+func WriteType(buf *bytes.Buffer, typ Type, qf Qualifier) {
+ writeType(buf, typ, qf, make([]Type, 8))
+}
+
+func writeType(buf *bytes.Buffer, typ Type, qf Qualifier, visited []Type) {
+ // Theoretically, this is a quadratic lookup algorithm, but in
+ // practice deeply nested composite types with unnamed component
+ // types are uncommon. This code is likely more efficient than
+ // using a map.
+ for _, t := range visited {
+ if t == typ {
+ fmt.Fprintf(buf, "○%T", typ) // cycle to typ
+ return
+ }
+ }
+ visited = append(visited, typ)
+
+ switch t := typ.(type) {
+ case nil:
+ buf.WriteString("")
+
+ case *Basic:
+ if t.kind == UnsafePointer {
+ buf.WriteString("unsafe.")
+ }
+ if GcCompatibilityMode {
+ // forget the alias names
+ switch t.kind {
+ case Byte:
+ t = Typ[Uint8]
+ case Rune:
+ t = Typ[Int32]
+ }
+ }
+ buf.WriteString(t.name)
+
+ case *Array:
+ fmt.Fprintf(buf, "[%d]", t.len)
+ writeType(buf, t.elem, qf, visited)
+
+ case *Slice:
+ buf.WriteString("[]")
+ writeType(buf, t.elem, qf, visited)
+
+ case *Struct:
+ buf.WriteString("struct{")
+ for i, f := range t.fields {
+ if i > 0 {
+ buf.WriteString("; ")
+ }
+ if !f.anonymous {
+ buf.WriteString(f.name)
+ buf.WriteByte(' ')
+ }
+ writeType(buf, f.typ, qf, visited)
+ if tag := t.Tag(i); tag != "" {
+ fmt.Fprintf(buf, " %q", tag)
+ }
+ }
+ buf.WriteByte('}')
+
+ case *Pointer:
+ buf.WriteByte('*')
+ writeType(buf, t.base, qf, visited)
+
+ case *Tuple:
+ writeTuple(buf, t, false, qf, visited)
+
+ case *Signature:
+ buf.WriteString("func")
+ writeSignature(buf, t, qf, visited)
+
+ case *Interface:
+ // We write the source-level methods and embedded types rather
+ // than the actual method set since resolved method signatures
+ // may have non-printable cycles if parameters have anonymous
+ // interface types that (directly or indirectly) embed the
+ // current interface. For instance, consider the result type
+ // of m:
+ //
+ // type T interface{
+ // m() interface{ T }
+ // }
+ //
+ buf.WriteString("interface{")
+ if GcCompatibilityMode {
+ // print flattened interface
+ // (useful to compare against gc-generated interfaces)
+ for i, m := range t.allMethods {
+ if i > 0 {
+ buf.WriteString("; ")
+ }
+ buf.WriteString(m.name)
+ writeSignature(buf, m.typ.(*Signature), qf, visited)
+ }
+ } else {
+ // print explicit interface methods and embedded types
+ for i, m := range t.methods {
+ if i > 0 {
+ buf.WriteString("; ")
+ }
+ buf.WriteString(m.name)
+ writeSignature(buf, m.typ.(*Signature), qf, visited)
+ }
+ for i, typ := range t.embeddeds {
+ if i > 0 || len(t.methods) > 0 {
+ buf.WriteString("; ")
+ }
+ writeType(buf, typ, qf, visited)
+ }
+ }
+ buf.WriteByte('}')
+
+ case *Map:
+ buf.WriteString("map[")
+ writeType(buf, t.key, qf, visited)
+ buf.WriteByte(']')
+ writeType(buf, t.elem, qf, visited)
+
+ case *Chan:
+ var s string
+ var parens bool
+ switch t.dir {
+ case SendRecv:
+ s = "chan "
+ // chan (<-chan T) requires parentheses
+ if c, _ := t.elem.(*Chan); c != nil && c.dir == RecvOnly {
+ parens = true
+ }
+ case SendOnly:
+ s = "chan<- "
+ case RecvOnly:
+ s = "<-chan "
+ default:
+ panic("unreachable")
+ }
+ buf.WriteString(s)
+ if parens {
+ buf.WriteByte('(')
+ }
+ writeType(buf, t.elem, qf, visited)
+ if parens {
+ buf.WriteByte(')')
+ }
+
+ case *Named:
+ s := ""
+ if obj := t.obj; obj != nil {
+ if obj.pkg != nil {
+ writePackage(buf, obj.pkg, qf)
+ }
+ // TODO(gri): function-local named types should be displayed
+ // differently from named types at package level to avoid
+ // ambiguity.
+ s = obj.name
+ }
+ buf.WriteString(s)
+
+ default:
+ // For externally defined implementations of Type.
+ buf.WriteString(t.String())
+ }
+}
+
+func writeTuple(buf *bytes.Buffer, tup *Tuple, variadic bool, qf Qualifier, visited []Type) {
+ buf.WriteByte('(')
+ if tup != nil {
+ for i, v := range tup.vars {
+ if i > 0 {
+ buf.WriteString(", ")
+ }
+ if v.name != "" {
+ buf.WriteString(v.name)
+ buf.WriteByte(' ')
+ }
+ typ := v.typ
+ if variadic && i == len(tup.vars)-1 {
+ if s, ok := typ.(*Slice); ok {
+ buf.WriteString("...")
+ typ = s.elem
+ } else {
+ // special case:
+ // append(s, "foo"...) leads to signature func([]byte, string...)
+ if t, ok := typ.Underlying().(*Basic); !ok || t.kind != String {
+ panic("internal error: string type expected")
+ }
+ writeType(buf, typ, qf, visited)
+ buf.WriteString("...")
+ continue
+ }
+ }
+ writeType(buf, typ, qf, visited)
+ }
+ }
+ buf.WriteByte(')')
+}
+
+// WriteSignature writes the representation of the signature sig to buf,
+// without a leading "func" keyword.
+// The Qualifier controls the printing of
+// package-level objects, and may be nil.
+func WriteSignature(buf *bytes.Buffer, sig *Signature, qf Qualifier) {
+ writeSignature(buf, sig, qf, make([]Type, 8))
+}
+
+func writeSignature(buf *bytes.Buffer, sig *Signature, qf Qualifier, visited []Type) {
+ writeTuple(buf, sig.params, sig.variadic, qf, visited)
+
+ n := sig.results.Len()
+ if n == 0 {
+ // no result
+ return
+ }
+
+ buf.WriteByte(' ')
+ if n == 1 && sig.results.vars[0].name == "" {
+ // single unnamed result
+ writeType(buf, sig.results.vars[0].typ, qf, visited)
+ return
+ }
+
+ // multiple or named result(s)
+ writeTuple(buf, sig.results, false, qf, visited)
+}
diff --git a/vendor/golang.org/x/tools/go/types/typeutil/imports.go b/vendor/golang.org/x/tools/go/types/typeutil/imports.go
new file mode 100644
index 0000000..967fe1e
--- /dev/null
+++ b/vendor/golang.org/x/tools/go/types/typeutil/imports.go
@@ -0,0 +1,31 @@
+// Copyright 2014 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package typeutil
+
+import "golang.org/x/tools/go/types"
+
+// Dependencies returns all dependencies of the specified packages.
+//
+// Dependent packages appear in topological order: if package P imports
+// package Q, Q appears earlier than P in the result.
+// The algorithm follows import statements in the order they
+// appear in the source code, so the result is a total order.
+//
+func Dependencies(pkgs ...*types.Package) []*types.Package {
+ var result []*types.Package
+ seen := make(map[*types.Package]bool)
+ var visit func(pkgs []*types.Package)
+ visit = func(pkgs []*types.Package) {
+ for _, p := range pkgs {
+ if !seen[p] {
+ seen[p] = true
+ visit(p.Imports())
+ result = append(result, p)
+ }
+ }
+ }
+ visit(pkgs)
+ return result
+}
diff --git a/vendor/golang.org/x/tools/go/types/typeutil/map.go b/vendor/golang.org/x/tools/go/types/typeutil/map.go
new file mode 100644
index 0000000..b3a04cc
--- /dev/null
+++ b/vendor/golang.org/x/tools/go/types/typeutil/map.go
@@ -0,0 +1,314 @@
+// Copyright 2014 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package typeutil defines various utilities for types, such as Map,
+// a mapping from types.Type to interface{} values.
+package typeutil // import "golang.org/x/tools/go/types/typeutil"
+
+import (
+ "bytes"
+ "fmt"
+ "reflect"
+
+ "golang.org/x/tools/go/types"
+)
+
+// Map is a hash-table-based mapping from types (types.Type) to
+// arbitrary interface{} values. The concrete types that implement
+// the Type interface are pointers. Since they are not canonicalized,
+// == cannot be used to check for equivalence, and thus we cannot
+// simply use a Go map.
+//
+// Just as with map[K]V, a nil *Map is a valid empty map.
+//
+// Not thread-safe.
+//
+type Map struct {
+ hasher Hasher // shared by many Maps
+ table map[uint32][]entry // maps hash to bucket; entry.key==nil means unused
+ length int // number of map entries
+}
+
+// entry is an entry (key/value association) in a hash bucket.
+type entry struct {
+ key types.Type
+ value interface{}
+}
+
+// SetHasher sets the hasher used by Map.
+//
+// All Hashers are functionally equivalent but contain internal state
+// used to cache the results of hashing previously seen types.
+//
+// A single Hasher created by MakeHasher() may be shared among many
+// Maps. This is recommended if the instances have many keys in
+// common, as it will amortize the cost of hash computation.
+//
+// A Hasher may grow without bound as new types are seen. Even when a
+// type is deleted from the map, the Hasher never shrinks, since other
+// types in the map may reference the deleted type indirectly.
+//
+// Hashers are not thread-safe, and read-only operations such as
+// Map.Lookup require updates to the hasher, so a full Mutex lock (not a
+// read-lock) is require around all Map operations if a shared
+// hasher is accessed from multiple threads.
+//
+// If SetHasher is not called, the Map will create a private hasher at
+// the first call to Insert.
+//
+func (m *Map) SetHasher(hasher Hasher) {
+ m.hasher = hasher
+}
+
+// Delete removes the entry with the given key, if any.
+// It returns true if the entry was found.
+//
+func (m *Map) Delete(key types.Type) bool {
+ if m != nil && m.table != nil {
+ hash := m.hasher.Hash(key)
+ bucket := m.table[hash]
+ for i, e := range bucket {
+ if e.key != nil && types.Identical(key, e.key) {
+ // We can't compact the bucket as it
+ // would disturb iterators.
+ bucket[i] = entry{}
+ m.length--
+ return true
+ }
+ }
+ }
+ return false
+}
+
+// At returns the map entry for the given key.
+// The result is nil if the entry is not present.
+//
+func (m *Map) At(key types.Type) interface{} {
+ if m != nil && m.table != nil {
+ for _, e := range m.table[m.hasher.Hash(key)] {
+ if e.key != nil && types.Identical(key, e.key) {
+ return e.value
+ }
+ }
+ }
+ return nil
+}
+
+// Set sets the map entry for key to val,
+// and returns the previous entry, if any.
+func (m *Map) Set(key types.Type, value interface{}) (prev interface{}) {
+ if m.table != nil {
+ hash := m.hasher.Hash(key)
+ bucket := m.table[hash]
+ var hole *entry
+ for i, e := range bucket {
+ if e.key == nil {
+ hole = &bucket[i]
+ } else if types.Identical(key, e.key) {
+ prev = e.value
+ bucket[i].value = value
+ return
+ }
+ }
+
+ if hole != nil {
+ *hole = entry{key, value} // overwrite deleted entry
+ } else {
+ m.table[hash] = append(bucket, entry{key, value})
+ }
+ } else {
+ if m.hasher.memo == nil {
+ m.hasher = MakeHasher()
+ }
+ hash := m.hasher.Hash(key)
+ m.table = map[uint32][]entry{hash: {entry{key, value}}}
+ }
+
+ m.length++
+ return
+}
+
+// Len returns the number of map entries.
+func (m *Map) Len() int {
+ if m != nil {
+ return m.length
+ }
+ return 0
+}
+
+// Iterate calls function f on each entry in the map in unspecified order.
+//
+// If f should mutate the map, Iterate provides the same guarantees as
+// Go maps: if f deletes a map entry that Iterate has not yet reached,
+// f will not be invoked for it, but if f inserts a map entry that
+// Iterate has not yet reached, whether or not f will be invoked for
+// it is unspecified.
+//
+func (m *Map) Iterate(f func(key types.Type, value interface{})) {
+ if m != nil {
+ for _, bucket := range m.table {
+ for _, e := range bucket {
+ if e.key != nil {
+ f(e.key, e.value)
+ }
+ }
+ }
+ }
+}
+
+// Keys returns a new slice containing the set of map keys.
+// The order is unspecified.
+func (m *Map) Keys() []types.Type {
+ keys := make([]types.Type, 0, m.Len())
+ m.Iterate(func(key types.Type, _ interface{}) {
+ keys = append(keys, key)
+ })
+ return keys
+}
+
+func (m *Map) toString(values bool) string {
+ if m == nil {
+ return "{}"
+ }
+ var buf bytes.Buffer
+ fmt.Fprint(&buf, "{")
+ sep := ""
+ m.Iterate(func(key types.Type, value interface{}) {
+ fmt.Fprint(&buf, sep)
+ sep = ", "
+ fmt.Fprint(&buf, key)
+ if values {
+ fmt.Fprintf(&buf, ": %q", value)
+ }
+ })
+ fmt.Fprint(&buf, "}")
+ return buf.String()
+}
+
+// String returns a string representation of the map's entries.
+// Values are printed using fmt.Sprintf("%v", v).
+// Order is unspecified.
+//
+func (m *Map) String() string {
+ return m.toString(true)
+}
+
+// KeysString returns a string representation of the map's key set.
+// Order is unspecified.
+//
+func (m *Map) KeysString() string {
+ return m.toString(false)
+}
+
+////////////////////////////////////////////////////////////////////////
+// Hasher
+
+// A Hasher maps each type to its hash value.
+// For efficiency, a hasher uses memoization; thus its memory
+// footprint grows monotonically over time.
+// Hashers are not thread-safe.
+// Hashers have reference semantics.
+// Call MakeHasher to create a Hasher.
+type Hasher struct {
+ memo map[types.Type]uint32
+}
+
+// MakeHasher returns a new Hasher instance.
+func MakeHasher() Hasher {
+ return Hasher{make(map[types.Type]uint32)}
+}
+
+// Hash computes a hash value for the given type t such that
+// Identical(t, t') => Hash(t) == Hash(t').
+func (h Hasher) Hash(t types.Type) uint32 {
+ hash, ok := h.memo[t]
+ if !ok {
+ hash = h.hashFor(t)
+ h.memo[t] = hash
+ }
+ return hash
+}
+
+// hashString computes the Fowler–Noll–Vo hash of s.
+func hashString(s string) uint32 {
+ var h uint32
+ for i := 0; i < len(s); i++ {
+ h ^= uint32(s[i])
+ h *= 16777619
+ }
+ return h
+}
+
+// hashFor computes the hash of t.
+func (h Hasher) hashFor(t types.Type) uint32 {
+ // See Identical for rationale.
+ switch t := t.(type) {
+ case *types.Basic:
+ return uint32(t.Kind())
+
+ case *types.Array:
+ return 9043 + 2*uint32(t.Len()) + 3*h.Hash(t.Elem())
+
+ case *types.Slice:
+ return 9049 + 2*h.Hash(t.Elem())
+
+ case *types.Struct:
+ var hash uint32 = 9059
+ for i, n := 0, t.NumFields(); i < n; i++ {
+ f := t.Field(i)
+ if f.Anonymous() {
+ hash += 8861
+ }
+ hash += hashString(t.Tag(i))
+ hash += hashString(f.Name()) // (ignore f.Pkg)
+ hash += h.Hash(f.Type())
+ }
+ return hash
+
+ case *types.Pointer:
+ return 9067 + 2*h.Hash(t.Elem())
+
+ case *types.Signature:
+ var hash uint32 = 9091
+ if t.Variadic() {
+ hash *= 8863
+ }
+ return hash + 3*h.hashTuple(t.Params()) + 5*h.hashTuple(t.Results())
+
+ case *types.Interface:
+ var hash uint32 = 9103
+ for i, n := 0, t.NumMethods(); i < n; i++ {
+ // See go/types.identicalMethods for rationale.
+ // Method order is not significant.
+ // Ignore m.Pkg().
+ m := t.Method(i)
+ hash += 3*hashString(m.Name()) + 5*h.Hash(m.Type())
+ }
+ return hash
+
+ case *types.Map:
+ return 9109 + 2*h.Hash(t.Key()) + 3*h.Hash(t.Elem())
+
+ case *types.Chan:
+ return 9127 + 2*uint32(t.Dir()) + 3*h.Hash(t.Elem())
+
+ case *types.Named:
+ // Not safe with a copying GC; objects may move.
+ return uint32(reflect.ValueOf(t.Obj()).Pointer())
+
+ case *types.Tuple:
+ return h.hashTuple(t)
+ }
+ panic(t)
+}
+
+func (h Hasher) hashTuple(tuple *types.Tuple) uint32 {
+ // See go/types.identicalTypes for rationale.
+ n := tuple.Len()
+ var hash uint32 = 9137 + 2*uint32(n)
+ for i := 0; i < n; i++ {
+ hash += 3 * h.Hash(tuple.At(i).Type())
+ }
+ return hash
+}
diff --git a/vendor/golang.org/x/tools/go/types/typeutil/methodsetcache.go b/vendor/golang.org/x/tools/go/types/typeutil/methodsetcache.go
new file mode 100644
index 0000000..daad644
--- /dev/null
+++ b/vendor/golang.org/x/tools/go/types/typeutil/methodsetcache.go
@@ -0,0 +1,73 @@
+// Copyright 2014 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// This file implements a cache of method sets.
+
+package typeutil
+
+import (
+ "sync"
+
+ "golang.org/x/tools/go/types"
+)
+
+// A MethodSetCache records the method set of each type T for which
+// MethodSet(T) is called so that repeat queries are fast.
+// The zero value is a ready-to-use cache instance.
+type MethodSetCache struct {
+ mu sync.Mutex
+ named map[*types.Named]struct{ value, pointer *types.MethodSet } // method sets for named N and *N
+ others map[types.Type]*types.MethodSet // all other types
+}
+
+// MethodSet returns the method set of type T. It is thread-safe.
+//
+// If cache is nil, this function is equivalent to types.NewMethodSet(T).
+// Utility functions can thus expose an optional *MethodSetCache
+// parameter to clients that care about performance.
+//
+func (cache *MethodSetCache) MethodSet(T types.Type) *types.MethodSet {
+ if cache == nil {
+ return types.NewMethodSet(T)
+ }
+ cache.mu.Lock()
+ defer cache.mu.Unlock()
+
+ switch T := T.(type) {
+ case *types.Named:
+ return cache.lookupNamed(T).value
+
+ case *types.Pointer:
+ if N, ok := T.Elem().(*types.Named); ok {
+ return cache.lookupNamed(N).pointer
+ }
+ }
+
+ // all other types
+ // (The map uses pointer equivalence, not type identity.)
+ mset := cache.others[T]
+ if mset == nil {
+ mset = types.NewMethodSet(T)
+ if cache.others == nil {
+ cache.others = make(map[types.Type]*types.MethodSet)
+ }
+ cache.others[T] = mset
+ }
+ return mset
+}
+
+func (cache *MethodSetCache) lookupNamed(named *types.Named) struct{ value, pointer *types.MethodSet } {
+ if cache.named == nil {
+ cache.named = make(map[*types.Named]struct{ value, pointer *types.MethodSet })
+ }
+ // Avoid recomputing mset(*T) for each distinct Pointer
+ // instance whose underlying type is a named type.
+ msets, ok := cache.named[named]
+ if !ok {
+ msets.value = types.NewMethodSet(named)
+ msets.pointer = types.NewMethodSet(types.NewPointer(named))
+ cache.named[named] = msets
+ }
+ return msets
+}
diff --git a/vendor/golang.org/x/tools/go/types/typeutil/ui.go b/vendor/golang.org/x/tools/go/types/typeutil/ui.go
new file mode 100644
index 0000000..20c5249
--- /dev/null
+++ b/vendor/golang.org/x/tools/go/types/typeutil/ui.go
@@ -0,0 +1,38 @@
+// Copyright 2014 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package typeutil
+
+// This file defines utilities for user interfaces that display types.
+
+import "golang.org/x/tools/go/types"
+
+// IntuitiveMethodSet returns the intuitive method set of a type, T.
+//
+// The result contains MethodSet(T) and additionally, if T is a
+// concrete type, methods belonging to *T if there is no identically
+// named method on T itself. This corresponds to user intuition about
+// method sets; this function is intended only for user interfaces.
+//
+// The order of the result is as for types.MethodSet(T).
+//
+func IntuitiveMethodSet(T types.Type, msets *MethodSetCache) []*types.Selection {
+ var result []*types.Selection
+ mset := msets.MethodSet(T)
+ if _, ok := T.Underlying().(*types.Interface); ok {
+ for i, n := 0, mset.Len(); i < n; i++ {
+ result = append(result, mset.At(i))
+ }
+ } else {
+ pmset := msets.MethodSet(types.NewPointer(T))
+ for i, n := 0, pmset.Len(); i < n; i++ {
+ meth := pmset.At(i)
+ if m := mset.Lookup(meth.Obj().Pkg(), meth.Obj().Name()); m != nil {
+ meth = m
+ }
+ result = append(result, meth)
+ }
+ }
+ return result
+}
diff --git a/vendor/golang.org/x/tools/go/types/typexpr.go b/vendor/golang.org/x/tools/go/types/typexpr.go
new file mode 100644
index 0000000..bd2d7ba
--- /dev/null
+++ b/vendor/golang.org/x/tools/go/types/typexpr.go
@@ -0,0 +1,713 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// This file implements type-checking of identifiers and type expressions.
+
+package types
+
+import (
+ "go/ast"
+ "go/token"
+ "sort"
+ "strconv"
+
+ "golang.org/x/tools/go/exact"
+)
+
+// ident type-checks identifier e and initializes x with the value or type of e.
+// If an error occurred, x.mode is set to invalid.
+// For the meaning of def and path, see check.typ, below.
+//
+func (check *Checker) ident(x *operand, e *ast.Ident, def *Named, path []*TypeName) {
+ x.mode = invalid
+ x.expr = e
+
+ scope, obj := check.scope.LookupParent(e.Name, check.pos)
+ if obj == nil {
+ if e.Name == "_" {
+ check.errorf(e.Pos(), "cannot use _ as value or type")
+ } else {
+ check.errorf(e.Pos(), "undeclared name: %s", e.Name)
+ }
+ return
+ }
+ check.recordUse(e, obj)
+
+ check.objDecl(obj, def, path)
+ typ := obj.Type()
+ assert(typ != nil)
+
+ // The object may be dot-imported: If so, remove its package from
+ // the map of unused dot imports for the respective file scope.
+ // (This code is only needed for dot-imports. Without them,
+ // we only have to mark variables, see *Var case below).
+ if pkg := obj.Pkg(); pkg != check.pkg && pkg != nil {
+ delete(check.unusedDotImports[scope], pkg)
+ }
+
+ switch obj := obj.(type) {
+ case *PkgName:
+ check.errorf(e.Pos(), "use of package %s not in selector", obj.name)
+ return
+
+ case *Const:
+ check.addDeclDep(obj)
+ if typ == Typ[Invalid] {
+ return
+ }
+ if obj == universeIota {
+ if check.iota == nil {
+ check.errorf(e.Pos(), "cannot use iota outside constant declaration")
+ return
+ }
+ x.val = check.iota
+ } else {
+ x.val = obj.val
+ }
+ assert(x.val != nil)
+ x.mode = constant
+
+ case *TypeName:
+ x.mode = typexpr
+ // check for cycle
+ // (it's ok to iterate forward because each named type appears at most once in path)
+ for i, prev := range path {
+ if prev == obj {
+ check.errorf(obj.pos, "illegal cycle in declaration of %s", obj.name)
+ // print cycle
+ for _, obj := range path[i:] {
+ check.errorf(obj.Pos(), "\t%s refers to", obj.Name()) // secondary error, \t indented
+ }
+ check.errorf(obj.Pos(), "\t%s", obj.Name())
+ // maintain x.mode == typexpr despite error
+ typ = Typ[Invalid]
+ break
+ }
+ }
+
+ case *Var:
+ if obj.pkg == check.pkg {
+ obj.used = true
+ }
+ check.addDeclDep(obj)
+ if typ == Typ[Invalid] {
+ return
+ }
+ x.mode = variable
+
+ case *Func:
+ check.addDeclDep(obj)
+ x.mode = value
+
+ case *Builtin:
+ x.id = obj.id
+ x.mode = builtin
+
+ case *Nil:
+ x.mode = value
+
+ default:
+ unreachable()
+ }
+
+ x.typ = typ
+}
+
+// typExpr type-checks the type expression e and returns its type, or Typ[Invalid].
+// If def != nil, e is the type specification for the named type def, declared
+// in a type declaration, and def.underlying will be set to the type of e before
+// any components of e are type-checked. Path contains the path of named types
+// referring to this type.
+//
+func (check *Checker) typExpr(e ast.Expr, def *Named, path []*TypeName) (T Type) {
+ if trace {
+ check.trace(e.Pos(), "%s", e)
+ check.indent++
+ defer func() {
+ check.indent--
+ check.trace(e.Pos(), "=> %s", T)
+ }()
+ }
+
+ T = check.typExprInternal(e, def, path)
+ assert(isTyped(T))
+ check.recordTypeAndValue(e, typexpr, T, nil)
+
+ return
+}
+
+func (check *Checker) typ(e ast.Expr) Type {
+ return check.typExpr(e, nil, nil)
+}
+
+// funcType type-checks a function or method type.
+func (check *Checker) funcType(sig *Signature, recvPar *ast.FieldList, ftyp *ast.FuncType) {
+ scope := NewScope(check.scope, token.NoPos, token.NoPos, "function")
+ check.recordScope(ftyp, scope)
+
+ recvList, _ := check.collectParams(scope, recvPar, false)
+ params, variadic := check.collectParams(scope, ftyp.Params, true)
+ results, _ := check.collectParams(scope, ftyp.Results, false)
+
+ if recvPar != nil {
+ // recv parameter list present (may be empty)
+ // spec: "The receiver is specified via an extra parameter section preceeding the
+ // method name. That parameter section must declare a single parameter, the receiver."
+ var recv *Var
+ switch len(recvList) {
+ case 0:
+ check.error(recvPar.Pos(), "method is missing receiver")
+ recv = NewParam(0, nil, "", Typ[Invalid]) // ignore recv below
+ default:
+ // more than one receiver
+ check.error(recvList[len(recvList)-1].Pos(), "method must have exactly one receiver")
+ fallthrough // continue with first receiver
+ case 1:
+ recv = recvList[0]
+ }
+ // spec: "The receiver type must be of the form T or *T where T is a type name."
+ // (ignore invalid types - error was reported before)
+ if t, _ := deref(recv.typ); t != Typ[Invalid] {
+ var err string
+ if T, _ := t.(*Named); T != nil {
+ // spec: "The type denoted by T is called the receiver base type; it must not
+ // be a pointer or interface type and it must be declared in the same package
+ // as the method."
+ if T.obj.pkg != check.pkg {
+ err = "type not defined in this package"
+ } else {
+ // TODO(gri) This is not correct if the underlying type is unknown yet.
+ switch u := T.underlying.(type) {
+ case *Basic:
+ // unsafe.Pointer is treated like a regular pointer
+ if u.kind == UnsafePointer {
+ err = "unsafe.Pointer"
+ }
+ case *Pointer, *Interface:
+ err = "pointer or interface type"
+ }
+ }
+ } else {
+ err = "basic or unnamed type"
+ }
+ if err != "" {
+ check.errorf(recv.pos, "invalid receiver %s (%s)", recv.typ, err)
+ // ok to continue
+ }
+ }
+ sig.recv = recv
+ }
+
+ sig.scope = scope
+ sig.params = NewTuple(params...)
+ sig.results = NewTuple(results...)
+ sig.variadic = variadic
+}
+
+// typExprInternal drives type checking of types.
+// Must only be called by typExpr.
+//
+func (check *Checker) typExprInternal(e ast.Expr, def *Named, path []*TypeName) Type {
+ switch e := e.(type) {
+ case *ast.BadExpr:
+ // ignore - error reported before
+
+ case *ast.Ident:
+ var x operand
+ check.ident(&x, e, def, path)
+
+ switch x.mode {
+ case typexpr:
+ typ := x.typ
+ def.setUnderlying(typ)
+ return typ
+ case invalid:
+ // ignore - error reported before
+ case novalue:
+ check.errorf(x.pos(), "%s used as type", &x)
+ default:
+ check.errorf(x.pos(), "%s is not a type", &x)
+ }
+
+ case *ast.SelectorExpr:
+ var x operand
+ check.selector(&x, e)
+
+ switch x.mode {
+ case typexpr:
+ typ := x.typ
+ def.setUnderlying(typ)
+ return typ
+ case invalid:
+ // ignore - error reported before
+ case novalue:
+ check.errorf(x.pos(), "%s used as type", &x)
+ default:
+ check.errorf(x.pos(), "%s is not a type", &x)
+ }
+
+ case *ast.ParenExpr:
+ return check.typExpr(e.X, def, path)
+
+ case *ast.ArrayType:
+ if e.Len != nil {
+ typ := new(Array)
+ def.setUnderlying(typ)
+ typ.len = check.arrayLength(e.Len)
+ typ.elem = check.typExpr(e.Elt, nil, path)
+ return typ
+
+ } else {
+ typ := new(Slice)
+ def.setUnderlying(typ)
+ typ.elem = check.typ(e.Elt)
+ return typ
+ }
+
+ case *ast.StructType:
+ typ := new(Struct)
+ def.setUnderlying(typ)
+ check.structType(typ, e, path)
+ return typ
+
+ case *ast.StarExpr:
+ typ := new(Pointer)
+ def.setUnderlying(typ)
+ typ.base = check.typ(e.X)
+ return typ
+
+ case *ast.FuncType:
+ typ := new(Signature)
+ def.setUnderlying(typ)
+ check.funcType(typ, nil, e)
+ return typ
+
+ case *ast.InterfaceType:
+ typ := new(Interface)
+ def.setUnderlying(typ)
+ check.interfaceType(typ, e, def, path)
+ return typ
+
+ case *ast.MapType:
+ typ := new(Map)
+ def.setUnderlying(typ)
+
+ typ.key = check.typ(e.Key)
+ typ.elem = check.typ(e.Value)
+
+ // spec: "The comparison operators == and != must be fully defined
+ // for operands of the key type; thus the key type must not be a
+ // function, map, or slice."
+ //
+ // Delay this check because it requires fully setup types;
+ // it is safe to continue in any case (was issue 6667).
+ check.delay(func() {
+ if !Comparable(typ.key) {
+ check.errorf(e.Key.Pos(), "invalid map key type %s", typ.key)
+ }
+ })
+
+ return typ
+
+ case *ast.ChanType:
+ typ := new(Chan)
+ def.setUnderlying(typ)
+
+ dir := SendRecv
+ switch e.Dir {
+ case ast.SEND | ast.RECV:
+ // nothing to do
+ case ast.SEND:
+ dir = SendOnly
+ case ast.RECV:
+ dir = RecvOnly
+ default:
+ check.invalidAST(e.Pos(), "unknown channel direction %d", e.Dir)
+ // ok to continue
+ }
+
+ typ.dir = dir
+ typ.elem = check.typ(e.Value)
+ return typ
+
+ default:
+ check.errorf(e.Pos(), "%s is not a type", e)
+ }
+
+ typ := Typ[Invalid]
+ def.setUnderlying(typ)
+ return typ
+}
+
+// typeOrNil type-checks the type expression (or nil value) e
+// and returns the typ of e, or nil.
+// If e is neither a type nor nil, typOrNil returns Typ[Invalid].
+//
+func (check *Checker) typOrNil(e ast.Expr) Type {
+ var x operand
+ check.rawExpr(&x, e, nil)
+ switch x.mode {
+ case invalid:
+ // ignore - error reported before
+ case novalue:
+ check.errorf(x.pos(), "%s used as type", &x)
+ case typexpr:
+ return x.typ
+ case value:
+ if x.isNil() {
+ return nil
+ }
+ fallthrough
+ default:
+ check.errorf(x.pos(), "%s is not a type", &x)
+ }
+ return Typ[Invalid]
+}
+
+func (check *Checker) arrayLength(e ast.Expr) int64 {
+ var x operand
+ check.expr(&x, e)
+ if x.mode != constant {
+ if x.mode != invalid {
+ check.errorf(x.pos(), "array length %s must be constant", &x)
+ }
+ return 0
+ }
+ if !x.isInteger() {
+ check.errorf(x.pos(), "array length %s must be integer", &x)
+ return 0
+ }
+ n, ok := exact.Int64Val(x.val)
+ if !ok || n < 0 {
+ check.errorf(x.pos(), "invalid array length %s", &x)
+ return 0
+ }
+ return n
+}
+
+func (check *Checker) collectParams(scope *Scope, list *ast.FieldList, variadicOk bool) (params []*Var, variadic bool) {
+ if list == nil {
+ return
+ }
+
+ var named, anonymous bool
+ for i, field := range list.List {
+ ftype := field.Type
+ if t, _ := ftype.(*ast.Ellipsis); t != nil {
+ ftype = t.Elt
+ if variadicOk && i == len(list.List)-1 {
+ variadic = true
+ } else {
+ check.invalidAST(field.Pos(), "... not permitted")
+ // ignore ... and continue
+ }
+ }
+ typ := check.typ(ftype)
+ // The parser ensures that f.Tag is nil and we don't
+ // care if a constructed AST contains a non-nil tag.
+ if len(field.Names) > 0 {
+ // named parameter
+ for _, name := range field.Names {
+ if name.Name == "" {
+ check.invalidAST(name.Pos(), "anonymous parameter")
+ // ok to continue
+ }
+ par := NewParam(name.Pos(), check.pkg, name.Name, typ)
+ check.declare(scope, name, par, scope.pos)
+ params = append(params, par)
+ }
+ named = true
+ } else {
+ // anonymous parameter
+ par := NewParam(ftype.Pos(), check.pkg, "", typ)
+ check.recordImplicit(field, par)
+ params = append(params, par)
+ anonymous = true
+ }
+ }
+
+ if named && anonymous {
+ check.invalidAST(list.Pos(), "list contains both named and anonymous parameters")
+ // ok to continue
+ }
+
+ // For a variadic function, change the last parameter's type from T to []T.
+ if variadic && len(params) > 0 {
+ last := params[len(params)-1]
+ last.typ = &Slice{elem: last.typ}
+ }
+
+ return
+}
+
+func (check *Checker) declareInSet(oset *objset, pos token.Pos, obj Object) bool {
+ if alt := oset.insert(obj); alt != nil {
+ check.errorf(pos, "%s redeclared", obj.Name())
+ check.reportAltDecl(alt)
+ return false
+ }
+ return true
+}
+
+func (check *Checker) interfaceType(iface *Interface, ityp *ast.InterfaceType, def *Named, path []*TypeName) {
+ // empty interface: common case
+ if ityp.Methods == nil {
+ return
+ }
+
+ // The parser ensures that field tags are nil and we don't
+ // care if a constructed AST contains non-nil tags.
+
+ // use named receiver type if available (for better error messages)
+ var recvTyp Type = iface
+ if def != nil {
+ recvTyp = def
+ }
+
+ // Phase 1: Collect explicitly declared methods, the corresponding
+ // signature (AST) expressions, and the list of embedded
+ // type (AST) expressions. Do not resolve signatures or
+ // embedded types yet to avoid cycles referring to this
+ // interface.
+
+ var (
+ mset objset
+ signatures []ast.Expr // list of corresponding method signatures
+ embedded []ast.Expr // list of embedded types
+ )
+ for _, f := range ityp.Methods.List {
+ if len(f.Names) > 0 {
+ // The parser ensures that there's only one method
+ // and we don't care if a constructed AST has more.
+ name := f.Names[0]
+ pos := name.Pos()
+ // spec: "As with all method sets, in an interface type,
+ // each method must have a unique non-blank name."
+ if name.Name == "_" {
+ check.errorf(pos, "invalid method name _")
+ continue
+ }
+ // Don't type-check signature yet - use an
+ // empty signature now and update it later.
+ // Since we know the receiver, set it up now
+ // (required to avoid crash in ptrRecv; see
+ // e.g. test case for issue 6638).
+ // TODO(gri) Consider marking methods signatures
+ // as incomplete, for better error messages. See
+ // also the T4 and T5 tests in testdata/cycles2.src.
+ sig := new(Signature)
+ sig.recv = NewVar(pos, check.pkg, "", recvTyp)
+ m := NewFunc(pos, check.pkg, name.Name, sig)
+ if check.declareInSet(&mset, pos, m) {
+ iface.methods = append(iface.methods, m)
+ iface.allMethods = append(iface.allMethods, m)
+ signatures = append(signatures, f.Type)
+ check.recordDef(name, m)
+ }
+ } else {
+ // embedded type
+ embedded = append(embedded, f.Type)
+ }
+ }
+
+ // Phase 2: Resolve embedded interfaces. Because an interface must not
+ // embed itself (directly or indirectly), each embedded interface
+ // can be fully resolved without depending on any method of this
+ // interface (if there is a cycle or another error, the embedded
+ // type resolves to an invalid type and is ignored).
+ // In particular, the list of methods for each embedded interface
+ // must be complete (it cannot depend on this interface), and so
+ // those methods can be added to the list of all methods of this
+ // interface.
+
+ for _, e := range embedded {
+ pos := e.Pos()
+ typ := check.typExpr(e, nil, path)
+ // Determine underlying embedded (possibly incomplete) type
+ // by following its forward chain.
+ named, _ := typ.(*Named)
+ under := underlying(named)
+ embed, _ := under.(*Interface)
+ if embed == nil {
+ if typ != Typ[Invalid] {
+ check.errorf(pos, "%s is not an interface", typ)
+ }
+ continue
+ }
+ iface.embeddeds = append(iface.embeddeds, named)
+ // collect embedded methods
+ for _, m := range embed.allMethods {
+ if check.declareInSet(&mset, pos, m) {
+ iface.allMethods = append(iface.allMethods, m)
+ }
+ }
+ }
+
+ // Phase 3: At this point all methods have been collected for this interface.
+ // It is now safe to type-check the signatures of all explicitly
+ // declared methods, even if they refer to this interface via a cycle
+ // and embed the methods of this interface in a parameter of interface
+ // type.
+
+ for i, m := range iface.methods {
+ expr := signatures[i]
+ typ := check.typ(expr)
+ sig, _ := typ.(*Signature)
+ if sig == nil {
+ if typ != Typ[Invalid] {
+ check.invalidAST(expr.Pos(), "%s is not a method signature", typ)
+ }
+ continue // keep method with empty method signature
+ }
+ // update signature, but keep recv that was set up before
+ old := m.typ.(*Signature)
+ sig.recv = old.recv
+ *old = *sig // update signature (don't replace it!)
+ }
+
+ // TODO(gri) The list of explicit methods is only sorted for now to
+ // produce the same Interface as NewInterface. We may be able to
+ // claim source order in the future. Revisit.
+ sort.Sort(byUniqueMethodName(iface.methods))
+
+ // TODO(gri) The list of embedded types is only sorted for now to
+ // produce the same Interface as NewInterface. We may be able to
+ // claim source order in the future. Revisit.
+ sort.Sort(byUniqueTypeName(iface.embeddeds))
+
+ sort.Sort(byUniqueMethodName(iface.allMethods))
+}
+
+// byUniqueTypeName named type lists can be sorted by their unique type names.
+type byUniqueTypeName []*Named
+
+func (a byUniqueTypeName) Len() int { return len(a) }
+func (a byUniqueTypeName) Less(i, j int) bool { return a[i].obj.Id() < a[j].obj.Id() }
+func (a byUniqueTypeName) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
+
+// byUniqueMethodName method lists can be sorted by their unique method names.
+type byUniqueMethodName []*Func
+
+func (a byUniqueMethodName) Len() int { return len(a) }
+func (a byUniqueMethodName) Less(i, j int) bool { return a[i].Id() < a[j].Id() }
+func (a byUniqueMethodName) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
+
+func (check *Checker) tag(t *ast.BasicLit) string {
+ if t != nil {
+ if t.Kind == token.STRING {
+ if val, err := strconv.Unquote(t.Value); err == nil {
+ return val
+ }
+ }
+ check.invalidAST(t.Pos(), "incorrect tag syntax: %q", t.Value)
+ }
+ return ""
+}
+
+func (check *Checker) structType(styp *Struct, e *ast.StructType, path []*TypeName) {
+ list := e.Fields
+ if list == nil {
+ return
+ }
+
+ // struct fields and tags
+ var fields []*Var
+ var tags []string
+
+ // for double-declaration checks
+ var fset objset
+
+ // current field typ and tag
+ var typ Type
+ var tag string
+ // anonymous != nil indicates an anonymous field.
+ add := func(field *ast.Field, ident *ast.Ident, anonymous *TypeName, pos token.Pos) {
+ if tag != "" && tags == nil {
+ tags = make([]string, len(fields))
+ }
+ if tags != nil {
+ tags = append(tags, tag)
+ }
+
+ name := ident.Name
+ fld := NewField(pos, check.pkg, name, typ, anonymous != nil)
+ // spec: "Within a struct, non-blank field names must be unique."
+ if name == "_" || check.declareInSet(&fset, pos, fld) {
+ fields = append(fields, fld)
+ check.recordDef(ident, fld)
+ }
+ if anonymous != nil {
+ check.recordUse(ident, anonymous)
+ }
+ }
+
+ for _, f := range list.List {
+ typ = check.typExpr(f.Type, nil, path)
+ tag = check.tag(f.Tag)
+ if len(f.Names) > 0 {
+ // named fields
+ for _, name := range f.Names {
+ add(f, name, nil, name.Pos())
+ }
+ } else {
+ // anonymous field
+ name := anonymousFieldIdent(f.Type)
+ pos := f.Type.Pos()
+ t, isPtr := deref(typ)
+ switch t := t.(type) {
+ case *Basic:
+ if t == Typ[Invalid] {
+ // error was reported before
+ continue
+ }
+ // unsafe.Pointer is treated like a regular pointer
+ if t.kind == UnsafePointer {
+ check.errorf(pos, "anonymous field type cannot be unsafe.Pointer")
+ continue
+ }
+ add(f, name, Universe.Lookup(t.name).(*TypeName), pos)
+
+ case *Named:
+ // spec: "An embedded type must be specified as a type name
+ // T or as a pointer to a non-interface type name *T, and T
+ // itself may not be a pointer type."
+ switch u := t.underlying.(type) {
+ case *Basic:
+ // unsafe.Pointer is treated like a regular pointer
+ if u.kind == UnsafePointer {
+ check.errorf(pos, "anonymous field type cannot be unsafe.Pointer")
+ continue
+ }
+ case *Pointer:
+ check.errorf(pos, "anonymous field type cannot be a pointer")
+ continue
+ case *Interface:
+ if isPtr {
+ check.errorf(pos, "anonymous field type cannot be a pointer to an interface")
+ continue
+ }
+ }
+ add(f, name, t.obj, pos)
+
+ default:
+ check.invalidAST(pos, "anonymous field type %s must be named", typ)
+ }
+ }
+ }
+
+ styp.fields = fields
+ styp.tags = tags
+}
+
+func anonymousFieldIdent(e ast.Expr) *ast.Ident {
+ switch e := e.(type) {
+ case *ast.Ident:
+ return e
+ case *ast.StarExpr:
+ return anonymousFieldIdent(e.X)
+ case *ast.SelectorExpr:
+ return e.Sel
+ }
+ return nil // invalid anonymous field
+}
diff --git a/vendor/golang.org/x/tools/go/types/universe.go b/vendor/golang.org/x/tools/go/types/universe.go
new file mode 100644
index 0000000..12a34ef
--- /dev/null
+++ b/vendor/golang.org/x/tools/go/types/universe.go
@@ -0,0 +1,224 @@
+// Copyright 2011 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// This file sets up the universe scope and the unsafe package.
+
+package types
+
+import (
+ "go/token"
+ "strings"
+
+ "golang.org/x/tools/go/exact"
+)
+
+var (
+ Universe *Scope
+ Unsafe *Package
+ universeIota *Const
+ universeByte *Basic // uint8 alias, but has name "byte"
+ universeRune *Basic // int32 alias, but has name "rune"
+)
+
+var Typ = []*Basic{
+ Invalid: {Invalid, 0, "invalid type"},
+
+ Bool: {Bool, IsBoolean, "bool"},
+ Int: {Int, IsInteger, "int"},
+ Int8: {Int8, IsInteger, "int8"},
+ Int16: {Int16, IsInteger, "int16"},
+ Int32: {Int32, IsInteger, "int32"},
+ Int64: {Int64, IsInteger, "int64"},
+ Uint: {Uint, IsInteger | IsUnsigned, "uint"},
+ Uint8: {Uint8, IsInteger | IsUnsigned, "uint8"},
+ Uint16: {Uint16, IsInteger | IsUnsigned, "uint16"},
+ Uint32: {Uint32, IsInteger | IsUnsigned, "uint32"},
+ Uint64: {Uint64, IsInteger | IsUnsigned, "uint64"},
+ Uintptr: {Uintptr, IsInteger | IsUnsigned, "uintptr"},
+ Float32: {Float32, IsFloat, "float32"},
+ Float64: {Float64, IsFloat, "float64"},
+ Complex64: {Complex64, IsComplex, "complex64"},
+ Complex128: {Complex128, IsComplex, "complex128"},
+ String: {String, IsString, "string"},
+ UnsafePointer: {UnsafePointer, 0, "Pointer"},
+
+ UntypedBool: {UntypedBool, IsBoolean | IsUntyped, "untyped bool"},
+ UntypedInt: {UntypedInt, IsInteger | IsUntyped, "untyped int"},
+ UntypedRune: {UntypedRune, IsInteger | IsUntyped, "untyped rune"},
+ UntypedFloat: {UntypedFloat, IsFloat | IsUntyped, "untyped float"},
+ UntypedComplex: {UntypedComplex, IsComplex | IsUntyped, "untyped complex"},
+ UntypedString: {UntypedString, IsString | IsUntyped, "untyped string"},
+ UntypedNil: {UntypedNil, IsUntyped, "untyped nil"},
+}
+
+var aliases = [...]*Basic{
+ {Byte, IsInteger | IsUnsigned, "byte"},
+ {Rune, IsInteger, "rune"},
+}
+
+func defPredeclaredTypes() {
+ for _, t := range Typ {
+ def(NewTypeName(token.NoPos, nil, t.name, t))
+ }
+ for _, t := range aliases {
+ def(NewTypeName(token.NoPos, nil, t.name, t))
+ }
+
+ // Error has a nil package in its qualified name since it is in no package
+ res := NewVar(token.NoPos, nil, "", Typ[String])
+ sig := &Signature{results: NewTuple(res)}
+ err := NewFunc(token.NoPos, nil, "Error", sig)
+ typ := &Named{underlying: NewInterface([]*Func{err}, nil).Complete()}
+ sig.recv = NewVar(token.NoPos, nil, "", typ)
+ def(NewTypeName(token.NoPos, nil, "error", typ))
+}
+
+var predeclaredConsts = [...]struct {
+ name string
+ kind BasicKind
+ val exact.Value
+}{
+ {"true", UntypedBool, exact.MakeBool(true)},
+ {"false", UntypedBool, exact.MakeBool(false)},
+ {"iota", UntypedInt, exact.MakeInt64(0)},
+}
+
+func defPredeclaredConsts() {
+ for _, c := range predeclaredConsts {
+ def(NewConst(token.NoPos, nil, c.name, Typ[c.kind], c.val))
+ }
+}
+
+func defPredeclaredNil() {
+ def(&Nil{object{name: "nil", typ: Typ[UntypedNil]}})
+}
+
+// A builtinId is the id of a builtin function.
+type builtinId int
+
+const (
+ // universe scope
+ _Append builtinId = iota
+ _Cap
+ _Close
+ _Complex
+ _Copy
+ _Delete
+ _Imag
+ _Len
+ _Make
+ _New
+ _Panic
+ _Print
+ _Println
+ _Real
+ _Recover
+
+ // package unsafe
+ _Alignof
+ _Offsetof
+ _Sizeof
+
+ // testing support
+ _Assert
+ _Trace
+)
+
+var predeclaredFuncs = [...]struct {
+ name string
+ nargs int
+ variadic bool
+ kind exprKind
+}{
+ _Append: {"append", 1, true, expression},
+ _Cap: {"cap", 1, false, expression},
+ _Close: {"close", 1, false, statement},
+ _Complex: {"complex", 2, false, expression},
+ _Copy: {"copy", 2, false, statement},
+ _Delete: {"delete", 2, false, statement},
+ _Imag: {"imag", 1, false, expression},
+ _Len: {"len", 1, false, expression},
+ _Make: {"make", 1, true, expression},
+ _New: {"new", 1, false, expression},
+ _Panic: {"panic", 1, false, statement},
+ _Print: {"print", 0, true, statement},
+ _Println: {"println", 0, true, statement},
+ _Real: {"real", 1, false, expression},
+ _Recover: {"recover", 0, false, statement},
+
+ _Alignof: {"Alignof", 1, false, expression},
+ _Offsetof: {"Offsetof", 1, false, expression},
+ _Sizeof: {"Sizeof", 1, false, expression},
+
+ _Assert: {"assert", 1, false, statement},
+ _Trace: {"trace", 0, true, statement},
+}
+
+func defPredeclaredFuncs() {
+ for i := range predeclaredFuncs {
+ id := builtinId(i)
+ if id == _Assert || id == _Trace {
+ continue // only define these in testing environment
+ }
+ def(newBuiltin(id))
+ }
+}
+
+// DefPredeclaredTestFuncs defines the assert and trace built-ins.
+// These built-ins are intended for debugging and testing of this
+// package only.
+func DefPredeclaredTestFuncs() {
+ if Universe.Lookup("assert") != nil {
+ return // already defined
+ }
+ def(newBuiltin(_Assert))
+ def(newBuiltin(_Trace))
+}
+
+func init() {
+ Universe = NewScope(nil, token.NoPos, token.NoPos, "universe")
+ Unsafe = NewPackage("unsafe", "unsafe")
+ Unsafe.complete = true
+
+ defPredeclaredTypes()
+ defPredeclaredConsts()
+ defPredeclaredNil()
+ defPredeclaredFuncs()
+
+ universeIota = Universe.Lookup("iota").(*Const)
+ universeByte = Universe.Lookup("byte").(*TypeName).typ.(*Basic)
+ universeRune = Universe.Lookup("rune").(*TypeName).typ.(*Basic)
+}
+
+// Objects with names containing blanks are internal and not entered into
+// a scope. Objects with exported names are inserted in the unsafe package
+// scope; other objects are inserted in the universe scope.
+//
+func def(obj Object) {
+ name := obj.Name()
+ if strings.Index(name, " ") >= 0 {
+ return // nothing to do
+ }
+ // fix Obj link for named types
+ if typ, ok := obj.Type().(*Named); ok {
+ typ.obj = obj.(*TypeName)
+ }
+ // exported identifiers go into package unsafe
+ scope := Universe
+ if obj.Exported() {
+ scope = Unsafe.scope
+ // set Pkg field
+ switch obj := obj.(type) {
+ case *TypeName:
+ obj.pkg = Unsafe
+ case *Builtin:
+ obj.pkg = Unsafe
+ default:
+ unreachable()
+ }
+ }
+ if scope.Insert(obj) != nil {
+ panic("internal error: double declaration")
+ }
+}
diff --git a/vendor/golang.org/x/tools/imports/fix.go b/vendor/golang.org/x/tools/imports/fix.go
new file mode 100644
index 0000000..22fde6c
--- /dev/null
+++ b/vendor/golang.org/x/tools/imports/fix.go
@@ -0,0 +1,387 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package imports
+
+import (
+ "fmt"
+ "go/ast"
+ "go/build"
+ "go/parser"
+ "go/token"
+ "os"
+ "path"
+ "path/filepath"
+ "strings"
+ "sync"
+
+ "golang.org/x/tools/go/ast/astutil"
+)
+
+// importToGroup is a list of functions which map from an import path to
+// a group number.
+var importToGroup = []func(importPath string) (num int, ok bool){
+ func(importPath string) (num int, ok bool) {
+ if strings.HasPrefix(importPath, "appengine") {
+ return 2, true
+ }
+ return
+ },
+ func(importPath string) (num int, ok bool) {
+ if strings.Contains(importPath, ".") {
+ return 1, true
+ }
+ return
+ },
+}
+
+func importGroup(importPath string) int {
+ for _, fn := range importToGroup {
+ if n, ok := fn(importPath); ok {
+ return n
+ }
+ }
+ return 0
+}
+
+func fixImports(fset *token.FileSet, f *ast.File) (added []string, err error) {
+ // refs are a set of possible package references currently unsatisfied by imports.
+ // first key: either base package (e.g. "fmt") or renamed package
+ // second key: referenced package symbol (e.g. "Println")
+ refs := make(map[string]map[string]bool)
+
+ // decls are the current package imports. key is base package or renamed package.
+ decls := make(map[string]*ast.ImportSpec)
+
+ // collect potential uses of packages.
+ var visitor visitFn
+ visitor = visitFn(func(node ast.Node) ast.Visitor {
+ if node == nil {
+ return visitor
+ }
+ switch v := node.(type) {
+ case *ast.ImportSpec:
+ if v.Name != nil {
+ decls[v.Name.Name] = v
+ } else {
+ local := importPathToName(strings.Trim(v.Path.Value, `\"`))
+ decls[local] = v
+ }
+ case *ast.SelectorExpr:
+ xident, ok := v.X.(*ast.Ident)
+ if !ok {
+ break
+ }
+ if xident.Obj != nil {
+ // if the parser can resolve it, it's not a package ref
+ break
+ }
+ pkgName := xident.Name
+ if refs[pkgName] == nil {
+ refs[pkgName] = make(map[string]bool)
+ }
+ if decls[pkgName] == nil {
+ refs[pkgName][v.Sel.Name] = true
+ }
+ }
+ return visitor
+ })
+ ast.Walk(visitor, f)
+
+ // Search for imports matching potential package references.
+ searches := 0
+ type result struct {
+ ipath string
+ name string
+ err error
+ }
+ results := make(chan result)
+ for pkgName, symbols := range refs {
+ if len(symbols) == 0 {
+ continue // skip over packages already imported
+ }
+ go func(pkgName string, symbols map[string]bool) {
+ ipath, rename, err := findImport(pkgName, symbols)
+ r := result{ipath: ipath, err: err}
+ if rename {
+ r.name = pkgName
+ }
+ results <- r
+ }(pkgName, symbols)
+ searches++
+ }
+ for i := 0; i < searches; i++ {
+ result := <-results
+ if result.err != nil {
+ return nil, result.err
+ }
+ if result.ipath != "" {
+ if result.name != "" {
+ astutil.AddNamedImport(fset, f, result.name, result.ipath)
+ } else {
+ astutil.AddImport(fset, f, result.ipath)
+ }
+ added = append(added, result.ipath)
+ }
+ }
+
+ // Nil out any unused ImportSpecs, to be removed in following passes
+ unusedImport := map[string]bool{}
+ for pkg, is := range decls {
+ if refs[pkg] == nil && pkg != "_" && pkg != "." {
+ unusedImport[strings.Trim(is.Path.Value, `"`)] = true
+ }
+ }
+ for ipath := range unusedImport {
+ if ipath == "C" {
+ // Don't remove cgo stuff.
+ continue
+ }
+ astutil.DeleteImport(fset, f, ipath)
+ }
+
+ return added, nil
+}
+
+// importPathToName returns the package name for the given import path.
+var importPathToName = importPathToNameGoPath
+
+// importPathToNameBasic assumes the package name is the base of import path.
+func importPathToNameBasic(importPath string) (packageName string) {
+ return path.Base(importPath)
+}
+
+// importPathToNameGoPath finds out the actual package name, as declared in its .go files.
+// If there's a problem, it falls back to using importPathToNameBasic.
+func importPathToNameGoPath(importPath string) (packageName string) {
+ if buildPkg, err := build.Import(importPath, "", 0); err == nil {
+ return buildPkg.Name
+ } else {
+ return importPathToNameBasic(importPath)
+ }
+}
+
+type pkg struct {
+ importpath string // full pkg import path, e.g. "net/http"
+ dir string // absolute file path to pkg directory e.g. "/usr/lib/go/src/fmt"
+}
+
+var pkgIndexOnce sync.Once
+
+var pkgIndex struct {
+ sync.Mutex
+ m map[string][]pkg // shortname => []pkg, e.g "http" => "net/http"
+}
+
+// gate is a semaphore for limiting concurrency.
+type gate chan struct{}
+
+func (g gate) enter() { g <- struct{}{} }
+func (g gate) leave() { <-g }
+
+// fsgate protects the OS & filesystem from too much concurrency.
+// Too much disk I/O -> too many threads -> swapping and bad scheduling.
+var fsgate = make(gate, 8)
+
+func loadPkgIndex() {
+ pkgIndex.Lock()
+ pkgIndex.m = make(map[string][]pkg)
+ pkgIndex.Unlock()
+
+ var wg sync.WaitGroup
+ for _, path := range build.Default.SrcDirs() {
+ fsgate.enter()
+ f, err := os.Open(path)
+ if err != nil {
+ fsgate.leave()
+ fmt.Fprint(os.Stderr, err)
+ continue
+ }
+ children, err := f.Readdir(-1)
+ f.Close()
+ fsgate.leave()
+ if err != nil {
+ fmt.Fprint(os.Stderr, err)
+ continue
+ }
+ for _, child := range children {
+ if child.IsDir() {
+ wg.Add(1)
+ go func(path, name string) {
+ defer wg.Done()
+ loadPkg(&wg, path, name)
+ }(path, child.Name())
+ }
+ }
+ }
+ wg.Wait()
+}
+
+func loadPkg(wg *sync.WaitGroup, root, pkgrelpath string) {
+ importpath := filepath.ToSlash(pkgrelpath)
+ dir := filepath.Join(root, importpath)
+
+ fsgate.enter()
+ defer fsgate.leave()
+ pkgDir, err := os.Open(dir)
+ if err != nil {
+ return
+ }
+ children, err := pkgDir.Readdir(-1)
+ pkgDir.Close()
+ if err != nil {
+ return
+ }
+ // hasGo tracks whether a directory actually appears to be a
+ // Go source code directory. If $GOPATH == $HOME, and
+ // $HOME/src has lots of other large non-Go projects in it,
+ // then the calls to importPathToName below can be expensive.
+ hasGo := false
+ for _, child := range children {
+ // Avoid .foo, _foo, and testdata directory trees.
+ name := child.Name()
+ if name == "" || name[0] == '.' || name[0] == '_' || name == "testdata" {
+ continue
+ }
+ if strings.HasSuffix(name, ".go") {
+ hasGo = true
+ }
+ if child.IsDir() {
+ wg.Add(1)
+ go func(root, name string) {
+ defer wg.Done()
+ loadPkg(wg, root, name)
+ }(root, filepath.Join(importpath, name))
+ }
+ }
+ if hasGo {
+ shortName := importPathToName(importpath)
+ pkgIndex.Lock()
+ pkgIndex.m[shortName] = append(pkgIndex.m[shortName], pkg{
+ importpath: importpath,
+ dir: dir,
+ })
+ pkgIndex.Unlock()
+ }
+
+}
+
+// loadExports returns a list exports for a package.
+var loadExports = loadExportsGoPath
+
+func loadExportsGoPath(dir string) map[string]bool {
+ exports := make(map[string]bool)
+ buildPkg, err := build.ImportDir(dir, 0)
+ if err != nil {
+ if strings.Contains(err.Error(), "no buildable Go source files in") {
+ return nil
+ }
+ fmt.Fprintf(os.Stderr, "could not import %q: %v\n", dir, err)
+ return nil
+ }
+ fset := token.NewFileSet()
+ for _, files := range [...][]string{buildPkg.GoFiles, buildPkg.CgoFiles} {
+ for _, file := range files {
+ f, err := parser.ParseFile(fset, filepath.Join(dir, file), nil, 0)
+ if err != nil {
+ fmt.Fprintf(os.Stderr, "could not parse %q: %v\n", file, err)
+ continue
+ }
+ for name := range f.Scope.Objects {
+ if ast.IsExported(name) {
+ exports[name] = true
+ }
+ }
+ }
+ }
+ return exports
+}
+
+// findImport searches for a package with the given symbols.
+// If no package is found, findImport returns "".
+// Declared as a variable rather than a function so goimports can be easily
+// extended by adding a file with an init function.
+var findImport = findImportGoPath
+
+func findImportGoPath(pkgName string, symbols map[string]bool) (string, bool, error) {
+ // Fast path for the standard library.
+ // In the common case we hopefully never have to scan the GOPATH, which can
+ // be slow with moving disks.
+ if pkg, rename, ok := findImportStdlib(pkgName, symbols); ok {
+ return pkg, rename, nil
+ }
+
+ // TODO(sameer): look at the import lines for other Go files in the
+ // local directory, since the user is likely to import the same packages
+ // in the current Go file. Return rename=true when the other Go files
+ // use a renamed package that's also used in the current file.
+
+ pkgIndexOnce.Do(loadPkgIndex)
+
+ // Collect exports for packages with matching names.
+ var wg sync.WaitGroup
+ var pkgsMu sync.Mutex // guards pkgs
+ // full importpath => exported symbol => True
+ // e.g. "net/http" => "Client" => True
+ pkgs := make(map[string]map[string]bool)
+ pkgIndex.Lock()
+ for _, pkg := range pkgIndex.m[pkgName] {
+ wg.Add(1)
+ go func(importpath, dir string) {
+ defer wg.Done()
+ exports := loadExports(dir)
+ if exports != nil {
+ pkgsMu.Lock()
+ pkgs[importpath] = exports
+ pkgsMu.Unlock()
+ }
+ }(pkg.importpath, pkg.dir)
+ }
+ pkgIndex.Unlock()
+ wg.Wait()
+
+ // Filter out packages missing required exported symbols.
+ for symbol := range symbols {
+ for importpath, exports := range pkgs {
+ if !exports[symbol] {
+ delete(pkgs, importpath)
+ }
+ }
+ }
+ if len(pkgs) == 0 {
+ return "", false, nil
+ }
+
+ // If there are multiple candidate packages, the shortest one wins.
+ // This is a heuristic to prefer the standard library (e.g. "bytes")
+ // over e.g. "github.com/foo/bar/bytes".
+ shortest := ""
+ for importPath := range pkgs {
+ if shortest == "" || len(importPath) < len(shortest) {
+ shortest = importPath
+ }
+ }
+ return shortest, false, nil
+}
+
+type visitFn func(node ast.Node) ast.Visitor
+
+func (fn visitFn) Visit(node ast.Node) ast.Visitor {
+ return fn(node)
+}
+
+func findImportStdlib(shortPkg string, symbols map[string]bool) (importPath string, rename, ok bool) {
+ for symbol := range symbols {
+ path := stdlib[shortPkg+"."+symbol]
+ if path == "" {
+ return "", false, false
+ }
+ if importPath != "" && importPath != path {
+ // Ambiguous. Symbols pointed to different things.
+ return "", false, false
+ }
+ importPath = path
+ }
+ return importPath, false, importPath != ""
+}
diff --git a/vendor/golang.org/x/tools/imports/imports.go b/vendor/golang.org/x/tools/imports/imports.go
new file mode 100644
index 0000000..e30946b
--- /dev/null
+++ b/vendor/golang.org/x/tools/imports/imports.go
@@ -0,0 +1,279 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package imports implements a Go pretty-printer (like package "go/format")
+// that also adds or removes import statements as necessary.
+package imports // import "golang.org/x/tools/imports"
+
+import (
+ "bufio"
+ "bytes"
+ "fmt"
+ "go/ast"
+ "go/format"
+ "go/parser"
+ "go/printer"
+ "go/token"
+ "io"
+ "regexp"
+ "strconv"
+ "strings"
+
+ "golang.org/x/tools/go/ast/astutil"
+)
+
+// Options specifies options for processing files.
+type Options struct {
+ Fragment bool // Accept fragment of a source file (no package statement)
+ AllErrors bool // Report all errors (not just the first 10 on different lines)
+
+ Comments bool // Print comments (true if nil *Options provided)
+ TabIndent bool // Use tabs for indent (true if nil *Options provided)
+ TabWidth int // Tab width (8 if nil *Options provided)
+}
+
+// Process formats and adjusts imports for the provided file.
+// If opt is nil the defaults are used.
+func Process(filename string, src []byte, opt *Options) ([]byte, error) {
+ if opt == nil {
+ opt = &Options{Comments: true, TabIndent: true, TabWidth: 8}
+ }
+
+ fileSet := token.NewFileSet()
+ file, adjust, err := parse(fileSet, filename, src, opt)
+ if err != nil {
+ return nil, err
+ }
+
+ _, err = fixImports(fileSet, file)
+ if err != nil {
+ return nil, err
+ }
+
+ sortImports(fileSet, file)
+ imps := astutil.Imports(fileSet, file)
+
+ var spacesBefore []string // import paths we need spaces before
+ for _, impSection := range imps {
+ // Within each block of contiguous imports, see if any
+ // import lines are in different group numbers. If so,
+ // we'll need to put a space between them so it's
+ // compatible with gofmt.
+ lastGroup := -1
+ for _, importSpec := range impSection {
+ importPath, _ := strconv.Unquote(importSpec.Path.Value)
+ groupNum := importGroup(importPath)
+ if groupNum != lastGroup && lastGroup != -1 {
+ spacesBefore = append(spacesBefore, importPath)
+ }
+ lastGroup = groupNum
+ }
+
+ }
+
+ printerMode := printer.UseSpaces
+ if opt.TabIndent {
+ printerMode |= printer.TabIndent
+ }
+ printConfig := &printer.Config{Mode: printerMode, Tabwidth: opt.TabWidth}
+
+ var buf bytes.Buffer
+ err = printConfig.Fprint(&buf, fileSet, file)
+ if err != nil {
+ return nil, err
+ }
+ out := buf.Bytes()
+ if adjust != nil {
+ out = adjust(src, out)
+ }
+ if len(spacesBefore) > 0 {
+ out = addImportSpaces(bytes.NewReader(out), spacesBefore)
+ }
+
+ out, err = format.Source(out)
+ if err != nil {
+ return nil, err
+ }
+ return out, nil
+}
+
+// parse parses src, which was read from filename,
+// as a Go source file or statement list.
+func parse(fset *token.FileSet, filename string, src []byte, opt *Options) (*ast.File, func(orig, src []byte) []byte, error) {
+ parserMode := parser.Mode(0)
+ if opt.Comments {
+ parserMode |= parser.ParseComments
+ }
+ if opt.AllErrors {
+ parserMode |= parser.AllErrors
+ }
+
+ // Try as whole source file.
+ file, err := parser.ParseFile(fset, filename, src, parserMode)
+ if err == nil {
+ return file, nil, nil
+ }
+ // If the error is that the source file didn't begin with a
+ // package line and we accept fragmented input, fall through to
+ // try as a source fragment. Stop and return on any other error.
+ if !opt.Fragment || !strings.Contains(err.Error(), "expected 'package'") {
+ return nil, nil, err
+ }
+
+ // If this is a declaration list, make it a source file
+ // by inserting a package clause.
+ // Insert using a ;, not a newline, so that the line numbers
+ // in psrc match the ones in src.
+ psrc := append([]byte("package main;"), src...)
+ file, err = parser.ParseFile(fset, filename, psrc, parserMode)
+ if err == nil {
+ // If a main function exists, we will assume this is a main
+ // package and leave the file.
+ if containsMainFunc(file) {
+ return file, nil, nil
+ }
+
+ adjust := func(orig, src []byte) []byte {
+ // Remove the package clause.
+ // Gofmt has turned the ; into a \n.
+ src = src[len("package main\n"):]
+ return matchSpace(orig, src)
+ }
+ return file, adjust, nil
+ }
+ // If the error is that the source file didn't begin with a
+ // declaration, fall through to try as a statement list.
+ // Stop and return on any other error.
+ if !strings.Contains(err.Error(), "expected declaration") {
+ return nil, nil, err
+ }
+
+ // If this is a statement list, make it a source file
+ // by inserting a package clause and turning the list
+ // into a function body. This handles expressions too.
+ // Insert using a ;, not a newline, so that the line numbers
+ // in fsrc match the ones in src.
+ fsrc := append(append([]byte("package p; func _() {"), src...), '}')
+ file, err = parser.ParseFile(fset, filename, fsrc, parserMode)
+ if err == nil {
+ adjust := func(orig, src []byte) []byte {
+ // Remove the wrapping.
+ // Gofmt has turned the ; into a \n\n.
+ src = src[len("package p\n\nfunc _() {"):]
+ src = src[:len(src)-len("}\n")]
+ // Gofmt has also indented the function body one level.
+ // Remove that indent.
+ src = bytes.Replace(src, []byte("\n\t"), []byte("\n"), -1)
+ return matchSpace(orig, src)
+ }
+ return file, adjust, nil
+ }
+
+ // Failed, and out of options.
+ return nil, nil, err
+}
+
+// containsMainFunc checks if a file contains a function declaration with the
+// function signature 'func main()'
+func containsMainFunc(file *ast.File) bool {
+ for _, decl := range file.Decls {
+ if f, ok := decl.(*ast.FuncDecl); ok {
+ if f.Name.Name != "main" {
+ continue
+ }
+
+ if len(f.Type.Params.List) != 0 {
+ continue
+ }
+
+ if f.Type.Results != nil && len(f.Type.Results.List) != 0 {
+ continue
+ }
+
+ return true
+ }
+ }
+
+ return false
+}
+
+func cutSpace(b []byte) (before, middle, after []byte) {
+ i := 0
+ for i < len(b) && (b[i] == ' ' || b[i] == '\t' || b[i] == '\n') {
+ i++
+ }
+ j := len(b)
+ for j > 0 && (b[j-1] == ' ' || b[j-1] == '\t' || b[j-1] == '\n') {
+ j--
+ }
+ if i <= j {
+ return b[:i], b[i:j], b[j:]
+ }
+ return nil, nil, b[j:]
+}
+
+// matchSpace reformats src to use the same space context as orig.
+// 1) If orig begins with blank lines, matchSpace inserts them at the beginning of src.
+// 2) matchSpace copies the indentation of the first non-blank line in orig
+// to every non-blank line in src.
+// 3) matchSpace copies the trailing space from orig and uses it in place
+// of src's trailing space.
+func matchSpace(orig []byte, src []byte) []byte {
+ before, _, after := cutSpace(orig)
+ i := bytes.LastIndex(before, []byte{'\n'})
+ before, indent := before[:i+1], before[i+1:]
+
+ _, src, _ = cutSpace(src)
+
+ var b bytes.Buffer
+ b.Write(before)
+ for len(src) > 0 {
+ line := src
+ if i := bytes.IndexByte(line, '\n'); i >= 0 {
+ line, src = line[:i+1], line[i+1:]
+ } else {
+ src = nil
+ }
+ if len(line) > 0 && line[0] != '\n' { // not blank
+ b.Write(indent)
+ }
+ b.Write(line)
+ }
+ b.Write(after)
+ return b.Bytes()
+}
+
+var impLine = regexp.MustCompile(`^\s+(?:[\w\.]+\s+)?"(.+)"`)
+
+func addImportSpaces(r io.Reader, breaks []string) []byte {
+ var out bytes.Buffer
+ sc := bufio.NewScanner(r)
+ inImports := false
+ done := false
+ for sc.Scan() {
+ s := sc.Text()
+
+ if !inImports && !done && strings.HasPrefix(s, "import") {
+ inImports = true
+ }
+ if inImports && (strings.HasPrefix(s, "var") ||
+ strings.HasPrefix(s, "func") ||
+ strings.HasPrefix(s, "const") ||
+ strings.HasPrefix(s, "type")) {
+ done = true
+ inImports = false
+ }
+ if inImports && len(breaks) > 0 {
+ if m := impLine.FindStringSubmatch(s); m != nil {
+ if m[1] == string(breaks[0]) {
+ out.WriteByte('\n')
+ breaks = breaks[1:]
+ }
+ }
+ }
+
+ fmt.Fprintln(&out, s)
+ }
+ return out.Bytes()
+}
diff --git a/vendor/golang.org/x/tools/imports/mkindex.go b/vendor/golang.org/x/tools/imports/mkindex.go
new file mode 100644
index 0000000..755e239
--- /dev/null
+++ b/vendor/golang.org/x/tools/imports/mkindex.go
@@ -0,0 +1,173 @@
+// +build ignore
+
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Command mkindex creates the file "pkgindex.go" containing an index of the Go
+// standard library. The file is intended to be built as part of the imports
+// package, so that the package may be used in environments where a GOROOT is
+// not available (such as App Engine).
+package main
+
+import (
+ "bytes"
+ "fmt"
+ "go/ast"
+ "go/build"
+ "go/format"
+ "go/parser"
+ "go/token"
+ "io/ioutil"
+ "log"
+ "os"
+ "path"
+ "path/filepath"
+ "strings"
+)
+
+var (
+ pkgIndex = make(map[string][]pkg)
+ exports = make(map[string]map[string]bool)
+)
+
+func main() {
+ // Don't use GOPATH.
+ ctx := build.Default
+ ctx.GOPATH = ""
+
+ // Populate pkgIndex global from GOROOT.
+ for _, path := range ctx.SrcDirs() {
+ f, err := os.Open(path)
+ if err != nil {
+ log.Print(err)
+ continue
+ }
+ children, err := f.Readdir(-1)
+ f.Close()
+ if err != nil {
+ log.Print(err)
+ continue
+ }
+ for _, child := range children {
+ if child.IsDir() {
+ loadPkg(path, child.Name())
+ }
+ }
+ }
+ // Populate exports global.
+ for _, ps := range pkgIndex {
+ for _, p := range ps {
+ e := loadExports(p.dir)
+ if e != nil {
+ exports[p.dir] = e
+ }
+ }
+ }
+
+ // Construct source file.
+ var buf bytes.Buffer
+ fmt.Fprint(&buf, pkgIndexHead)
+ fmt.Fprintf(&buf, "var pkgIndexMaster = %#v\n", pkgIndex)
+ fmt.Fprintf(&buf, "var exportsMaster = %#v\n", exports)
+ src := buf.Bytes()
+
+ // Replace main.pkg type name with pkg.
+ src = bytes.Replace(src, []byte("main.pkg"), []byte("pkg"), -1)
+ // Replace actual GOROOT with "/go".
+ src = bytes.Replace(src, []byte(ctx.GOROOT), []byte("/go"), -1)
+ // Add some line wrapping.
+ src = bytes.Replace(src, []byte("}, "), []byte("},\n"), -1)
+ src = bytes.Replace(src, []byte("true, "), []byte("true,\n"), -1)
+
+ var err error
+ src, err = format.Source(src)
+ if err != nil {
+ log.Fatal(err)
+ }
+
+ // Write out source file.
+ err = ioutil.WriteFile("pkgindex.go", src, 0644)
+ if err != nil {
+ log.Fatal(err)
+ }
+}
+
+const pkgIndexHead = `package imports
+
+func init() {
+ pkgIndexOnce.Do(func() {
+ pkgIndex.m = pkgIndexMaster
+ })
+ loadExports = func(dir string) map[string]bool {
+ return exportsMaster[dir]
+ }
+}
+`
+
+type pkg struct {
+ importpath string // full pkg import path, e.g. "net/http"
+ dir string // absolute file path to pkg directory e.g. "/usr/lib/go/src/fmt"
+}
+
+var fset = token.NewFileSet()
+
+func loadPkg(root, importpath string) {
+ shortName := path.Base(importpath)
+ if shortName == "testdata" {
+ return
+ }
+
+ dir := filepath.Join(root, importpath)
+ pkgIndex[shortName] = append(pkgIndex[shortName], pkg{
+ importpath: importpath,
+ dir: dir,
+ })
+
+ pkgDir, err := os.Open(dir)
+ if err != nil {
+ return
+ }
+ children, err := pkgDir.Readdir(-1)
+ pkgDir.Close()
+ if err != nil {
+ return
+ }
+ for _, child := range children {
+ name := child.Name()
+ if name == "" {
+ continue
+ }
+ if c := name[0]; c == '.' || ('0' <= c && c <= '9') {
+ continue
+ }
+ if child.IsDir() {
+ loadPkg(root, filepath.Join(importpath, name))
+ }
+ }
+}
+
+func loadExports(dir string) map[string]bool {
+ exports := make(map[string]bool)
+ buildPkg, err := build.ImportDir(dir, 0)
+ if err != nil {
+ if strings.Contains(err.Error(), "no buildable Go source files in") {
+ return nil
+ }
+ log.Printf("could not import %q: %v", dir, err)
+ return nil
+ }
+ for _, file := range buildPkg.GoFiles {
+ f, err := parser.ParseFile(fset, filepath.Join(dir, file), nil, 0)
+ if err != nil {
+ log.Printf("could not parse %q: %v", file, err)
+ continue
+ }
+ for name := range f.Scope.Objects {
+ if ast.IsExported(name) {
+ exports[name] = true
+ }
+ }
+ }
+ return exports
+}
diff --git a/vendor/golang.org/x/tools/imports/mkstdlib.go b/vendor/golang.org/x/tools/imports/mkstdlib.go
new file mode 100644
index 0000000..c43d325
--- /dev/null
+++ b/vendor/golang.org/x/tools/imports/mkstdlib.go
@@ -0,0 +1,90 @@
+// +build ignore
+
+// mkstdlib generates the zstdlib.go file, containing the Go standard
+// library API symbols. It's baked into the binary to avoid scanning
+// GOPATH in the common case.
+package main
+
+import (
+ "bufio"
+ "bytes"
+ "fmt"
+ "go/format"
+ "io"
+ "log"
+ "os"
+ "path"
+ "path/filepath"
+ "regexp"
+ "sort"
+ "strings"
+)
+
+func mustOpen(name string) io.Reader {
+ f, err := os.Open(name)
+ if err != nil {
+ log.Fatal(err)
+ }
+ return f
+}
+
+func api(base string) string {
+ return filepath.Join(os.Getenv("GOROOT"), "api", base)
+}
+
+var sym = regexp.MustCompile(`^pkg (\S+).*?, (?:var|func|type|const) ([A-Z]\w*)`)
+
+func main() {
+ var buf bytes.Buffer
+ outf := func(format string, args ...interface{}) {
+ fmt.Fprintf(&buf, format, args...)
+ }
+ outf("// AUTO-GENERATED BY mkstdlib.go\n\n")
+ outf("package imports\n")
+ outf("var stdlib = map[string]string{\n")
+ f := io.MultiReader(
+ mustOpen(api("go1.txt")),
+ mustOpen(api("go1.1.txt")),
+ mustOpen(api("go1.2.txt")),
+ )
+ sc := bufio.NewScanner(f)
+ fullImport := map[string]string{} // "zip.NewReader" => "archive/zip"
+ ambiguous := map[string]bool{}
+ var keys []string
+ for sc.Scan() {
+ l := sc.Text()
+ has := func(v string) bool { return strings.Contains(l, v) }
+ if has("struct, ") || has("interface, ") || has(", method (") {
+ continue
+ }
+ if m := sym.FindStringSubmatch(l); m != nil {
+ full := m[1]
+ key := path.Base(full) + "." + m[2]
+ if exist, ok := fullImport[key]; ok {
+ if exist != full {
+ ambiguous[key] = true
+ }
+ } else {
+ fullImport[key] = full
+ keys = append(keys, key)
+ }
+ }
+ }
+ if err := sc.Err(); err != nil {
+ log.Fatal(err)
+ }
+ sort.Strings(keys)
+ for _, key := range keys {
+ if ambiguous[key] {
+ outf("\t// %q is ambiguous\n", key)
+ } else {
+ outf("\t%q: %q,\n", key, fullImport[key])
+ }
+ }
+ outf("}\n")
+ fmtbuf, err := format.Source(buf.Bytes())
+ if err != nil {
+ log.Fatal(err)
+ }
+ os.Stdout.Write(fmtbuf)
+}
diff --git a/vendor/golang.org/x/tools/imports/sortimports.go b/vendor/golang.org/x/tools/imports/sortimports.go
new file mode 100644
index 0000000..68b3dc4
--- /dev/null
+++ b/vendor/golang.org/x/tools/imports/sortimports.go
@@ -0,0 +1,214 @@
+// +build go1.2
+
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Hacked up copy of go/ast/import.go
+
+package imports
+
+import (
+ "go/ast"
+ "go/token"
+ "sort"
+ "strconv"
+)
+
+// sortImports sorts runs of consecutive import lines in import blocks in f.
+// It also removes duplicate imports when it is possible to do so without data loss.
+func sortImports(fset *token.FileSet, f *ast.File) {
+ for i, d := range f.Decls {
+ d, ok := d.(*ast.GenDecl)
+ if !ok || d.Tok != token.IMPORT {
+ // Not an import declaration, so we're done.
+ // Imports are always first.
+ break
+ }
+
+ if len(d.Specs) == 0 {
+ // Empty import block, remove it.
+ f.Decls = append(f.Decls[:i], f.Decls[i+1:]...)
+ }
+
+ if !d.Lparen.IsValid() {
+ // Not a block: sorted by default.
+ continue
+ }
+
+ // Identify and sort runs of specs on successive lines.
+ i := 0
+ specs := d.Specs[:0]
+ for j, s := range d.Specs {
+ if j > i && fset.Position(s.Pos()).Line > 1+fset.Position(d.Specs[j-1].End()).Line {
+ // j begins a new run. End this one.
+ specs = append(specs, sortSpecs(fset, f, d.Specs[i:j])...)
+ i = j
+ }
+ }
+ specs = append(specs, sortSpecs(fset, f, d.Specs[i:])...)
+ d.Specs = specs
+
+ // Deduping can leave a blank line before the rparen; clean that up.
+ if len(d.Specs) > 0 {
+ lastSpec := d.Specs[len(d.Specs)-1]
+ lastLine := fset.Position(lastSpec.Pos()).Line
+ if rParenLine := fset.Position(d.Rparen).Line; rParenLine > lastLine+1 {
+ fset.File(d.Rparen).MergeLine(rParenLine - 1)
+ }
+ }
+ }
+}
+
+func importPath(s ast.Spec) string {
+ t, err := strconv.Unquote(s.(*ast.ImportSpec).Path.Value)
+ if err == nil {
+ return t
+ }
+ return ""
+}
+
+func importName(s ast.Spec) string {
+ n := s.(*ast.ImportSpec).Name
+ if n == nil {
+ return ""
+ }
+ return n.Name
+}
+
+func importComment(s ast.Spec) string {
+ c := s.(*ast.ImportSpec).Comment
+ if c == nil {
+ return ""
+ }
+ return c.Text()
+}
+
+// collapse indicates whether prev may be removed, leaving only next.
+func collapse(prev, next ast.Spec) bool {
+ if importPath(next) != importPath(prev) || importName(next) != importName(prev) {
+ return false
+ }
+ return prev.(*ast.ImportSpec).Comment == nil
+}
+
+type posSpan struct {
+ Start token.Pos
+ End token.Pos
+}
+
+func sortSpecs(fset *token.FileSet, f *ast.File, specs []ast.Spec) []ast.Spec {
+ // Can't short-circuit here even if specs are already sorted,
+ // since they might yet need deduplication.
+ // A lone import, however, may be safely ignored.
+ if len(specs) <= 1 {
+ return specs
+ }
+
+ // Record positions for specs.
+ pos := make([]posSpan, len(specs))
+ for i, s := range specs {
+ pos[i] = posSpan{s.Pos(), s.End()}
+ }
+
+ // Identify comments in this range.
+ // Any comment from pos[0].Start to the final line counts.
+ lastLine := fset.Position(pos[len(pos)-1].End).Line
+ cstart := len(f.Comments)
+ cend := len(f.Comments)
+ for i, g := range f.Comments {
+ if g.Pos() < pos[0].Start {
+ continue
+ }
+ if i < cstart {
+ cstart = i
+ }
+ if fset.Position(g.End()).Line > lastLine {
+ cend = i
+ break
+ }
+ }
+ comments := f.Comments[cstart:cend]
+
+ // Assign each comment to the import spec preceding it.
+ importComment := map[*ast.ImportSpec][]*ast.CommentGroup{}
+ specIndex := 0
+ for _, g := range comments {
+ for specIndex+1 < len(specs) && pos[specIndex+1].Start <= g.Pos() {
+ specIndex++
+ }
+ s := specs[specIndex].(*ast.ImportSpec)
+ importComment[s] = append(importComment[s], g)
+ }
+
+ // Sort the import specs by import path.
+ // Remove duplicates, when possible without data loss.
+ // Reassign the import paths to have the same position sequence.
+ // Reassign each comment to abut the end of its spec.
+ // Sort the comments by new position.
+ sort.Sort(byImportSpec(specs))
+
+ // Dedup. Thanks to our sorting, we can just consider
+ // adjacent pairs of imports.
+ deduped := specs[:0]
+ for i, s := range specs {
+ if i == len(specs)-1 || !collapse(s, specs[i+1]) {
+ deduped = append(deduped, s)
+ } else {
+ p := s.Pos()
+ fset.File(p).MergeLine(fset.Position(p).Line)
+ }
+ }
+ specs = deduped
+
+ // Fix up comment positions
+ for i, s := range specs {
+ s := s.(*ast.ImportSpec)
+ if s.Name != nil {
+ s.Name.NamePos = pos[i].Start
+ }
+ s.Path.ValuePos = pos[i].Start
+ s.EndPos = pos[i].End
+ for _, g := range importComment[s] {
+ for _, c := range g.List {
+ c.Slash = pos[i].End
+ }
+ }
+ }
+
+ sort.Sort(byCommentPos(comments))
+
+ return specs
+}
+
+type byImportSpec []ast.Spec // slice of *ast.ImportSpec
+
+func (x byImportSpec) Len() int { return len(x) }
+func (x byImportSpec) Swap(i, j int) { x[i], x[j] = x[j], x[i] }
+func (x byImportSpec) Less(i, j int) bool {
+ ipath := importPath(x[i])
+ jpath := importPath(x[j])
+
+ igroup := importGroup(ipath)
+ jgroup := importGroup(jpath)
+ if igroup != jgroup {
+ return igroup < jgroup
+ }
+
+ if ipath != jpath {
+ return ipath < jpath
+ }
+ iname := importName(x[i])
+ jname := importName(x[j])
+
+ if iname != jname {
+ return iname < jname
+ }
+ return importComment(x[i]) < importComment(x[j])
+}
+
+type byCommentPos []*ast.CommentGroup
+
+func (x byCommentPos) Len() int { return len(x) }
+func (x byCommentPos) Swap(i, j int) { x[i], x[j] = x[j], x[i] }
+func (x byCommentPos) Less(i, j int) bool { return x[i].Pos() < x[j].Pos() }
diff --git a/vendor/golang.org/x/tools/imports/sortimports_compat.go b/vendor/golang.org/x/tools/imports/sortimports_compat.go
new file mode 100644
index 0000000..295f237
--- /dev/null
+++ b/vendor/golang.org/x/tools/imports/sortimports_compat.go
@@ -0,0 +1,14 @@
+// +build !go1.2
+
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package imports
+
+import "go/ast"
+
+// Go 1.1 users don't get fancy package grouping.
+// But this is still gofmt-compliant:
+
+var sortImports = ast.SortImports
diff --git a/vendor/golang.org/x/tools/imports/zstdlib.go b/vendor/golang.org/x/tools/imports/zstdlib.go
new file mode 100644
index 0000000..6cdc033
--- /dev/null
+++ b/vendor/golang.org/x/tools/imports/zstdlib.go
@@ -0,0 +1,8374 @@
+// AUTO-GENERATED BY mkstdlib.go
+
+package imports
+
+var stdlib = map[string]string{
+ "adler32.Checksum": "hash/adler32",
+ "adler32.New": "hash/adler32",
+ "adler32.Size": "hash/adler32",
+ "aes.BlockSize": "crypto/aes",
+ "aes.KeySizeError": "crypto/aes",
+ "aes.NewCipher": "crypto/aes",
+ "ascii85.CorruptInputError": "encoding/ascii85",
+ "ascii85.Decode": "encoding/ascii85",
+ "ascii85.Encode": "encoding/ascii85",
+ "ascii85.MaxEncodedLen": "encoding/ascii85",
+ "ascii85.NewDecoder": "encoding/ascii85",
+ "ascii85.NewEncoder": "encoding/ascii85",
+ "asn1.BitString": "encoding/asn1",
+ "asn1.Enumerated": "encoding/asn1",
+ "asn1.Flag": "encoding/asn1",
+ "asn1.Marshal": "encoding/asn1",
+ "asn1.ObjectIdentifier": "encoding/asn1",
+ "asn1.RawContent": "encoding/asn1",
+ "asn1.RawValue": "encoding/asn1",
+ "asn1.StructuralError": "encoding/asn1",
+ "asn1.SyntaxError": "encoding/asn1",
+ "asn1.Unmarshal": "encoding/asn1",
+ "asn1.UnmarshalWithParams": "encoding/asn1",
+ "ast.ArrayType": "go/ast",
+ "ast.AssignStmt": "go/ast",
+ "ast.Bad": "go/ast",
+ "ast.BadDecl": "go/ast",
+ "ast.BadExpr": "go/ast",
+ "ast.BadStmt": "go/ast",
+ "ast.BasicLit": "go/ast",
+ "ast.BinaryExpr": "go/ast",
+ "ast.BlockStmt": "go/ast",
+ "ast.BranchStmt": "go/ast",
+ "ast.CallExpr": "go/ast",
+ "ast.CaseClause": "go/ast",
+ "ast.ChanDir": "go/ast",
+ "ast.ChanType": "go/ast",
+ "ast.CommClause": "go/ast",
+ "ast.Comment": "go/ast",
+ "ast.CommentGroup": "go/ast",
+ "ast.CommentMap": "go/ast",
+ "ast.CompositeLit": "go/ast",
+ "ast.Con": "go/ast",
+ "ast.DeclStmt": "go/ast",
+ "ast.DeferStmt": "go/ast",
+ "ast.Ellipsis": "go/ast",
+ "ast.EmptyStmt": "go/ast",
+ "ast.ExprStmt": "go/ast",
+ "ast.Field": "go/ast",
+ "ast.FieldFilter": "go/ast",
+ "ast.FieldList": "go/ast",
+ "ast.File": "go/ast",
+ "ast.FileExports": "go/ast",
+ "ast.Filter": "go/ast",
+ "ast.FilterDecl": "go/ast",
+ "ast.FilterFile": "go/ast",
+ "ast.FilterFuncDuplicates": "go/ast",
+ "ast.FilterImportDuplicates": "go/ast",
+ "ast.FilterPackage": "go/ast",
+ "ast.FilterUnassociatedComments": "go/ast",
+ "ast.ForStmt": "go/ast",
+ "ast.Fprint": "go/ast",
+ "ast.Fun": "go/ast",
+ "ast.FuncDecl": "go/ast",
+ "ast.FuncLit": "go/ast",
+ "ast.FuncType": "go/ast",
+ "ast.GenDecl": "go/ast",
+ "ast.GoStmt": "go/ast",
+ "ast.Ident": "go/ast",
+ "ast.IfStmt": "go/ast",
+ "ast.ImportSpec": "go/ast",
+ "ast.Importer": "go/ast",
+ "ast.IncDecStmt": "go/ast",
+ "ast.IndexExpr": "go/ast",
+ "ast.Inspect": "go/ast",
+ "ast.InterfaceType": "go/ast",
+ "ast.IsExported": "go/ast",
+ "ast.KeyValueExpr": "go/ast",
+ "ast.LabeledStmt": "go/ast",
+ "ast.Lbl": "go/ast",
+ "ast.MapType": "go/ast",
+ "ast.MergeMode": "go/ast",
+ "ast.MergePackageFiles": "go/ast",
+ "ast.NewCommentMap": "go/ast",
+ "ast.NewIdent": "go/ast",
+ "ast.NewObj": "go/ast",
+ "ast.NewPackage": "go/ast",
+ "ast.NewScope": "go/ast",
+ "ast.Node": "go/ast",
+ "ast.NotNilFilter": "go/ast",
+ "ast.ObjKind": "go/ast",
+ "ast.Object": "go/ast",
+ "ast.Package": "go/ast",
+ "ast.PackageExports": "go/ast",
+ "ast.ParenExpr": "go/ast",
+ "ast.Pkg": "go/ast",
+ "ast.Print": "go/ast",
+ "ast.RECV": "go/ast",
+ "ast.RangeStmt": "go/ast",
+ "ast.ReturnStmt": "go/ast",
+ "ast.SEND": "go/ast",
+ "ast.Scope": "go/ast",
+ "ast.SelectStmt": "go/ast",
+ "ast.SelectorExpr": "go/ast",
+ "ast.SendStmt": "go/ast",
+ "ast.SliceExpr": "go/ast",
+ "ast.SortImports": "go/ast",
+ "ast.StarExpr": "go/ast",
+ "ast.StructType": "go/ast",
+ "ast.SwitchStmt": "go/ast",
+ "ast.Typ": "go/ast",
+ "ast.TypeAssertExpr": "go/ast",
+ "ast.TypeSpec": "go/ast",
+ "ast.TypeSwitchStmt": "go/ast",
+ "ast.UnaryExpr": "go/ast",
+ "ast.ValueSpec": "go/ast",
+ "ast.Var": "go/ast",
+ "ast.Visitor": "go/ast",
+ "ast.Walk": "go/ast",
+ "atomic.AddInt32": "sync/atomic",
+ "atomic.AddInt64": "sync/atomic",
+ "atomic.AddUint32": "sync/atomic",
+ "atomic.AddUint64": "sync/atomic",
+ "atomic.AddUintptr": "sync/atomic",
+ "atomic.CompareAndSwapInt32": "sync/atomic",
+ "atomic.CompareAndSwapInt64": "sync/atomic",
+ "atomic.CompareAndSwapPointer": "sync/atomic",
+ "atomic.CompareAndSwapUint32": "sync/atomic",
+ "atomic.CompareAndSwapUint64": "sync/atomic",
+ "atomic.CompareAndSwapUintptr": "sync/atomic",
+ "atomic.LoadInt32": "sync/atomic",
+ "atomic.LoadInt64": "sync/atomic",
+ "atomic.LoadPointer": "sync/atomic",
+ "atomic.LoadUint32": "sync/atomic",
+ "atomic.LoadUint64": "sync/atomic",
+ "atomic.LoadUintptr": "sync/atomic",
+ "atomic.StoreInt32": "sync/atomic",
+ "atomic.StoreInt64": "sync/atomic",
+ "atomic.StorePointer": "sync/atomic",
+ "atomic.StoreUint32": "sync/atomic",
+ "atomic.StoreUint64": "sync/atomic",
+ "atomic.StoreUintptr": "sync/atomic",
+ "atomic.SwapInt32": "sync/atomic",
+ "atomic.SwapInt64": "sync/atomic",
+ "atomic.SwapPointer": "sync/atomic",
+ "atomic.SwapUint32": "sync/atomic",
+ "atomic.SwapUint64": "sync/atomic",
+ "atomic.SwapUintptr": "sync/atomic",
+ "base32.CorruptInputError": "encoding/base32",
+ "base32.Encoding": "encoding/base32",
+ "base32.HexEncoding": "encoding/base32",
+ "base32.NewDecoder": "encoding/base32",
+ "base32.NewEncoder": "encoding/base32",
+ "base32.NewEncoding": "encoding/base32",
+ "base32.StdEncoding": "encoding/base32",
+ "base64.CorruptInputError": "encoding/base64",
+ "base64.Encoding": "encoding/base64",
+ "base64.NewDecoder": "encoding/base64",
+ "base64.NewEncoder": "encoding/base64",
+ "base64.NewEncoding": "encoding/base64",
+ "base64.StdEncoding": "encoding/base64",
+ "base64.URLEncoding": "encoding/base64",
+ "big.Int": "math/big",
+ "big.MaxBase": "math/big",
+ "big.NewInt": "math/big",
+ "big.NewRat": "math/big",
+ "big.Rat": "math/big",
+ "big.Word": "math/big",
+ "binary.BigEndian": "encoding/binary",
+ "binary.ByteOrder": "encoding/binary",
+ "binary.LittleEndian": "encoding/binary",
+ "binary.MaxVarintLen16": "encoding/binary",
+ "binary.MaxVarintLen32": "encoding/binary",
+ "binary.MaxVarintLen64": "encoding/binary",
+ "binary.PutUvarint": "encoding/binary",
+ "binary.PutVarint": "encoding/binary",
+ "binary.Read": "encoding/binary",
+ "binary.ReadUvarint": "encoding/binary",
+ "binary.ReadVarint": "encoding/binary",
+ "binary.Size": "encoding/binary",
+ "binary.Uvarint": "encoding/binary",
+ "binary.Varint": "encoding/binary",
+ "binary.Write": "encoding/binary",
+ "bufio.ErrAdvanceTooFar": "bufio",
+ "bufio.ErrBufferFull": "bufio",
+ "bufio.ErrInvalidUnreadByte": "bufio",
+ "bufio.ErrInvalidUnreadRune": "bufio",
+ "bufio.ErrNegativeAdvance": "bufio",
+ "bufio.ErrNegativeCount": "bufio",
+ "bufio.ErrTooLong": "bufio",
+ "bufio.MaxScanTokenSize": "bufio",
+ "bufio.NewReadWriter": "bufio",
+ "bufio.NewReader": "bufio",
+ "bufio.NewReaderSize": "bufio",
+ "bufio.NewScanner": "bufio",
+ "bufio.NewWriter": "bufio",
+ "bufio.NewWriterSize": "bufio",
+ "bufio.ReadWriter": "bufio",
+ "bufio.Reader": "bufio",
+ "bufio.ScanBytes": "bufio",
+ "bufio.ScanLines": "bufio",
+ "bufio.ScanRunes": "bufio",
+ "bufio.ScanWords": "bufio",
+ "bufio.Scanner": "bufio",
+ "bufio.SplitFunc": "bufio",
+ "bufio.Writer": "bufio",
+ "build.AllowBinary": "go/build",
+ "build.ArchChar": "go/build",
+ "build.Context": "go/build",
+ "build.Default": "go/build",
+ "build.FindOnly": "go/build",
+ "build.Import": "go/build",
+ "build.ImportDir": "go/build",
+ "build.ImportMode": "go/build",
+ "build.IsLocalImport": "go/build",
+ "build.NoGoError": "go/build",
+ "build.Package": "go/build",
+ "build.ToolDir": "go/build",
+ "bytes.Buffer": "bytes",
+ "bytes.Compare": "bytes",
+ "bytes.Contains": "bytes",
+ "bytes.Count": "bytes",
+ "bytes.Equal": "bytes",
+ "bytes.EqualFold": "bytes",
+ "bytes.ErrTooLarge": "bytes",
+ "bytes.Fields": "bytes",
+ "bytes.FieldsFunc": "bytes",
+ "bytes.HasPrefix": "bytes",
+ "bytes.HasSuffix": "bytes",
+ "bytes.Index": "bytes",
+ "bytes.IndexAny": "bytes",
+ "bytes.IndexByte": "bytes",
+ "bytes.IndexFunc": "bytes",
+ "bytes.IndexRune": "bytes",
+ "bytes.Join": "bytes",
+ "bytes.LastIndex": "bytes",
+ "bytes.LastIndexAny": "bytes",
+ "bytes.LastIndexFunc": "bytes",
+ "bytes.Map": "bytes",
+ "bytes.MinRead": "bytes",
+ "bytes.NewBuffer": "bytes",
+ "bytes.NewBufferString": "bytes",
+ "bytes.NewReader": "bytes",
+ "bytes.Reader": "bytes",
+ "bytes.Repeat": "bytes",
+ "bytes.Replace": "bytes",
+ "bytes.Runes": "bytes",
+ "bytes.Split": "bytes",
+ "bytes.SplitAfter": "bytes",
+ "bytes.SplitAfterN": "bytes",
+ "bytes.SplitN": "bytes",
+ "bytes.Title": "bytes",
+ "bytes.ToLower": "bytes",
+ "bytes.ToLowerSpecial": "bytes",
+ "bytes.ToTitle": "bytes",
+ "bytes.ToTitleSpecial": "bytes",
+ "bytes.ToUpper": "bytes",
+ "bytes.ToUpperSpecial": "bytes",
+ "bytes.Trim": "bytes",
+ "bytes.TrimFunc": "bytes",
+ "bytes.TrimLeft": "bytes",
+ "bytes.TrimLeftFunc": "bytes",
+ "bytes.TrimPrefix": "bytes",
+ "bytes.TrimRight": "bytes",
+ "bytes.TrimRightFunc": "bytes",
+ "bytes.TrimSpace": "bytes",
+ "bytes.TrimSuffix": "bytes",
+ "bzip2.NewReader": "compress/bzip2",
+ "bzip2.StructuralError": "compress/bzip2",
+ "cgi.Handler": "net/http/cgi",
+ "cgi.Request": "net/http/cgi",
+ "cgi.RequestFromMap": "net/http/cgi",
+ "cgi.Serve": "net/http/cgi",
+ "cipher.AEAD": "crypto/cipher",
+ "cipher.Block": "crypto/cipher",
+ "cipher.BlockMode": "crypto/cipher",
+ "cipher.NewCBCDecrypter": "crypto/cipher",
+ "cipher.NewCBCEncrypter": "crypto/cipher",
+ "cipher.NewCFBDecrypter": "crypto/cipher",
+ "cipher.NewCFBEncrypter": "crypto/cipher",
+ "cipher.NewCTR": "crypto/cipher",
+ "cipher.NewGCM": "crypto/cipher",
+ "cipher.NewOFB": "crypto/cipher",
+ "cipher.Stream": "crypto/cipher",
+ "cipher.StreamReader": "crypto/cipher",
+ "cipher.StreamWriter": "crypto/cipher",
+ "cmplx.Abs": "math/cmplx",
+ "cmplx.Acos": "math/cmplx",
+ "cmplx.Acosh": "math/cmplx",
+ "cmplx.Asin": "math/cmplx",
+ "cmplx.Asinh": "math/cmplx",
+ "cmplx.Atan": "math/cmplx",
+ "cmplx.Atanh": "math/cmplx",
+ "cmplx.Conj": "math/cmplx",
+ "cmplx.Cos": "math/cmplx",
+ "cmplx.Cosh": "math/cmplx",
+ "cmplx.Cot": "math/cmplx",
+ "cmplx.Exp": "math/cmplx",
+ "cmplx.Inf": "math/cmplx",
+ "cmplx.IsInf": "math/cmplx",
+ "cmplx.IsNaN": "math/cmplx",
+ "cmplx.Log": "math/cmplx",
+ "cmplx.Log10": "math/cmplx",
+ "cmplx.NaN": "math/cmplx",
+ "cmplx.Phase": "math/cmplx",
+ "cmplx.Polar": "math/cmplx",
+ "cmplx.Pow": "math/cmplx",
+ "cmplx.Rect": "math/cmplx",
+ "cmplx.Sin": "math/cmplx",
+ "cmplx.Sinh": "math/cmplx",
+ "cmplx.Sqrt": "math/cmplx",
+ "cmplx.Tan": "math/cmplx",
+ "cmplx.Tanh": "math/cmplx",
+ "color.Alpha": "image/color",
+ "color.Alpha16": "image/color",
+ "color.Alpha16Model": "image/color",
+ "color.AlphaModel": "image/color",
+ "color.Black": "image/color",
+ "color.Color": "image/color",
+ "color.Gray": "image/color",
+ "color.Gray16": "image/color",
+ "color.Gray16Model": "image/color",
+ "color.GrayModel": "image/color",
+ "color.Model": "image/color",
+ "color.ModelFunc": "image/color",
+ "color.NRGBA": "image/color",
+ "color.NRGBA64": "image/color",
+ "color.NRGBA64Model": "image/color",
+ "color.NRGBAModel": "image/color",
+ "color.Opaque": "image/color",
+ "color.Palette": "image/color",
+ "color.RGBA": "image/color",
+ "color.RGBA64": "image/color",
+ "color.RGBA64Model": "image/color",
+ "color.RGBAModel": "image/color",
+ "color.RGBToYCbCr": "image/color",
+ "color.Transparent": "image/color",
+ "color.White": "image/color",
+ "color.YCbCr": "image/color",
+ "color.YCbCrModel": "image/color",
+ "color.YCbCrToRGB": "image/color",
+ "cookiejar.Jar": "net/http/cookiejar",
+ "cookiejar.New": "net/http/cookiejar",
+ "cookiejar.Options": "net/http/cookiejar",
+ "cookiejar.PublicSuffixList": "net/http/cookiejar",
+ "crc32.Castagnoli": "hash/crc32",
+ "crc32.Checksum": "hash/crc32",
+ "crc32.ChecksumIEEE": "hash/crc32",
+ "crc32.IEEE": "hash/crc32",
+ "crc32.IEEETable": "hash/crc32",
+ "crc32.Koopman": "hash/crc32",
+ "crc32.MakeTable": "hash/crc32",
+ "crc32.New": "hash/crc32",
+ "crc32.NewIEEE": "hash/crc32",
+ "crc32.Size": "hash/crc32",
+ "crc32.Table": "hash/crc32",
+ "crc32.Update": "hash/crc32",
+ "crc64.Checksum": "hash/crc64",
+ "crc64.ECMA": "hash/crc64",
+ "crc64.ISO": "hash/crc64",
+ "crc64.MakeTable": "hash/crc64",
+ "crc64.New": "hash/crc64",
+ "crc64.Size": "hash/crc64",
+ "crc64.Table": "hash/crc64",
+ "crc64.Update": "hash/crc64",
+ "crypto.Hash": "crypto",
+ "crypto.MD4": "crypto",
+ "crypto.MD5": "crypto",
+ "crypto.MD5SHA1": "crypto",
+ "crypto.PrivateKey": "crypto",
+ "crypto.PublicKey": "crypto",
+ "crypto.RIPEMD160": "crypto",
+ "crypto.RegisterHash": "crypto",
+ "crypto.SHA1": "crypto",
+ "crypto.SHA224": "crypto",
+ "crypto.SHA256": "crypto",
+ "crypto.SHA384": "crypto",
+ "crypto.SHA512": "crypto",
+ "csv.ErrBareQuote": "encoding/csv",
+ "csv.ErrFieldCount": "encoding/csv",
+ "csv.ErrQuote": "encoding/csv",
+ "csv.ErrTrailingComma": "encoding/csv",
+ "csv.NewReader": "encoding/csv",
+ "csv.NewWriter": "encoding/csv",
+ "csv.ParseError": "encoding/csv",
+ "csv.Reader": "encoding/csv",
+ "csv.Writer": "encoding/csv",
+ "debug.FreeOSMemory": "runtime/debug",
+ "debug.GCStats": "runtime/debug",
+ "debug.PrintStack": "runtime/debug",
+ "debug.ReadGCStats": "runtime/debug",
+ "debug.SetGCPercent": "runtime/debug",
+ "debug.SetMaxStack": "runtime/debug",
+ "debug.SetMaxThreads": "runtime/debug",
+ "debug.Stack": "runtime/debug",
+ "des.BlockSize": "crypto/des",
+ "des.KeySizeError": "crypto/des",
+ "des.NewCipher": "crypto/des",
+ "des.NewTripleDESCipher": "crypto/des",
+ "doc.AllDecls": "go/doc",
+ "doc.AllMethods": "go/doc",
+ "doc.Example": "go/doc",
+ "doc.Examples": "go/doc",
+ "doc.Filter": "go/doc",
+ "doc.Func": "go/doc",
+ "doc.IllegalPrefixes": "go/doc",
+ "doc.Mode": "go/doc",
+ "doc.New": "go/doc",
+ "doc.Note": "go/doc",
+ "doc.Package": "go/doc",
+ "doc.Synopsis": "go/doc",
+ "doc.ToHTML": "go/doc",
+ "doc.ToText": "go/doc",
+ "doc.Type": "go/doc",
+ "doc.Value": "go/doc",
+ "draw.Draw": "image/draw",
+ "draw.DrawMask": "image/draw",
+ "draw.Drawer": "image/draw",
+ "draw.FloydSteinberg": "image/draw",
+ "draw.Image": "image/draw",
+ "draw.Op": "image/draw",
+ "draw.Over": "image/draw",
+ "draw.Quantizer": "image/draw",
+ "draw.Src": "image/draw",
+ "driver.Bool": "database/sql/driver",
+ "driver.ColumnConverter": "database/sql/driver",
+ "driver.Conn": "database/sql/driver",
+ "driver.DefaultParameterConverter": "database/sql/driver",
+ "driver.Driver": "database/sql/driver",
+ "driver.ErrBadConn": "database/sql/driver",
+ "driver.ErrSkip": "database/sql/driver",
+ "driver.Execer": "database/sql/driver",
+ "driver.Int32": "database/sql/driver",
+ "driver.IsScanValue": "database/sql/driver",
+ "driver.IsValue": "database/sql/driver",
+ "driver.NotNull": "database/sql/driver",
+ "driver.Null": "database/sql/driver",
+ "driver.Queryer": "database/sql/driver",
+ "driver.Result": "database/sql/driver",
+ "driver.ResultNoRows": "database/sql/driver",
+ "driver.Rows": "database/sql/driver",
+ "driver.RowsAffected": "database/sql/driver",
+ "driver.Stmt": "database/sql/driver",
+ "driver.String": "database/sql/driver",
+ "driver.Tx": "database/sql/driver",
+ "driver.Value": "database/sql/driver",
+ "driver.ValueConverter": "database/sql/driver",
+ "driver.Valuer": "database/sql/driver",
+ "dsa.ErrInvalidPublicKey": "crypto/dsa",
+ "dsa.GenerateKey": "crypto/dsa",
+ "dsa.GenerateParameters": "crypto/dsa",
+ "dsa.L1024N160": "crypto/dsa",
+ "dsa.L2048N224": "crypto/dsa",
+ "dsa.L2048N256": "crypto/dsa",
+ "dsa.L3072N256": "crypto/dsa",
+ "dsa.ParameterSizes": "crypto/dsa",
+ "dsa.Parameters": "crypto/dsa",
+ "dsa.PrivateKey": "crypto/dsa",
+ "dsa.PublicKey": "crypto/dsa",
+ "dsa.Sign": "crypto/dsa",
+ "dsa.Verify": "crypto/dsa",
+ "dwarf.AddrType": "debug/dwarf",
+ "dwarf.ArrayType": "debug/dwarf",
+ "dwarf.Attr": "debug/dwarf",
+ "dwarf.AttrAbstractOrigin": "debug/dwarf",
+ "dwarf.AttrAccessibility": "debug/dwarf",
+ "dwarf.AttrAddrClass": "debug/dwarf",
+ "dwarf.AttrAllocated": "debug/dwarf",
+ "dwarf.AttrArtificial": "debug/dwarf",
+ "dwarf.AttrAssociated": "debug/dwarf",
+ "dwarf.AttrBaseTypes": "debug/dwarf",
+ "dwarf.AttrBitOffset": "debug/dwarf",
+ "dwarf.AttrBitSize": "debug/dwarf",
+ "dwarf.AttrByteSize": "debug/dwarf",
+ "dwarf.AttrCallColumn": "debug/dwarf",
+ "dwarf.AttrCallFile": "debug/dwarf",
+ "dwarf.AttrCallLine": "debug/dwarf",
+ "dwarf.AttrCalling": "debug/dwarf",
+ "dwarf.AttrCommonRef": "debug/dwarf",
+ "dwarf.AttrCompDir": "debug/dwarf",
+ "dwarf.AttrConstValue": "debug/dwarf",
+ "dwarf.AttrContainingType": "debug/dwarf",
+ "dwarf.AttrCount": "debug/dwarf",
+ "dwarf.AttrDataLocation": "debug/dwarf",
+ "dwarf.AttrDataMemberLoc": "debug/dwarf",
+ "dwarf.AttrDeclColumn": "debug/dwarf",
+ "dwarf.AttrDeclFile": "debug/dwarf",
+ "dwarf.AttrDeclLine": "debug/dwarf",
+ "dwarf.AttrDeclaration": "debug/dwarf",
+ "dwarf.AttrDefaultValue": "debug/dwarf",
+ "dwarf.AttrDescription": "debug/dwarf",
+ "dwarf.AttrDiscr": "debug/dwarf",
+ "dwarf.AttrDiscrList": "debug/dwarf",
+ "dwarf.AttrDiscrValue": "debug/dwarf",
+ "dwarf.AttrEncoding": "debug/dwarf",
+ "dwarf.AttrEntrypc": "debug/dwarf",
+ "dwarf.AttrExtension": "debug/dwarf",
+ "dwarf.AttrExternal": "debug/dwarf",
+ "dwarf.AttrFrameBase": "debug/dwarf",
+ "dwarf.AttrFriend": "debug/dwarf",
+ "dwarf.AttrHighpc": "debug/dwarf",
+ "dwarf.AttrIdentifierCase": "debug/dwarf",
+ "dwarf.AttrImport": "debug/dwarf",
+ "dwarf.AttrInline": "debug/dwarf",
+ "dwarf.AttrIsOptional": "debug/dwarf",
+ "dwarf.AttrLanguage": "debug/dwarf",
+ "dwarf.AttrLocation": "debug/dwarf",
+ "dwarf.AttrLowerBound": "debug/dwarf",
+ "dwarf.AttrLowpc": "debug/dwarf",
+ "dwarf.AttrMacroInfo": "debug/dwarf",
+ "dwarf.AttrName": "debug/dwarf",
+ "dwarf.AttrNamelistItem": "debug/dwarf",
+ "dwarf.AttrOrdering": "debug/dwarf",
+ "dwarf.AttrPriority": "debug/dwarf",
+ "dwarf.AttrProducer": "debug/dwarf",
+ "dwarf.AttrPrototyped": "debug/dwarf",
+ "dwarf.AttrRanges": "debug/dwarf",
+ "dwarf.AttrReturnAddr": "debug/dwarf",
+ "dwarf.AttrSegment": "debug/dwarf",
+ "dwarf.AttrSibling": "debug/dwarf",
+ "dwarf.AttrSpecification": "debug/dwarf",
+ "dwarf.AttrStartScope": "debug/dwarf",
+ "dwarf.AttrStaticLink": "debug/dwarf",
+ "dwarf.AttrStmtList": "debug/dwarf",
+ "dwarf.AttrStride": "debug/dwarf",
+ "dwarf.AttrStrideSize": "debug/dwarf",
+ "dwarf.AttrStringLength": "debug/dwarf",
+ "dwarf.AttrTrampoline": "debug/dwarf",
+ "dwarf.AttrType": "debug/dwarf",
+ "dwarf.AttrUpperBound": "debug/dwarf",
+ "dwarf.AttrUseLocation": "debug/dwarf",
+ "dwarf.AttrUseUTF8": "debug/dwarf",
+ "dwarf.AttrVarParam": "debug/dwarf",
+ "dwarf.AttrVirtuality": "debug/dwarf",
+ "dwarf.AttrVisibility": "debug/dwarf",
+ "dwarf.AttrVtableElemLoc": "debug/dwarf",
+ "dwarf.BasicType": "debug/dwarf",
+ "dwarf.BoolType": "debug/dwarf",
+ "dwarf.CharType": "debug/dwarf",
+ "dwarf.CommonType": "debug/dwarf",
+ "dwarf.ComplexType": "debug/dwarf",
+ "dwarf.Data": "debug/dwarf",
+ "dwarf.DecodeError": "debug/dwarf",
+ "dwarf.DotDotDotType": "debug/dwarf",
+ "dwarf.Entry": "debug/dwarf",
+ "dwarf.EnumType": "debug/dwarf",
+ "dwarf.EnumValue": "debug/dwarf",
+ "dwarf.Field": "debug/dwarf",
+ "dwarf.FloatType": "debug/dwarf",
+ "dwarf.FuncType": "debug/dwarf",
+ "dwarf.IntType": "debug/dwarf",
+ "dwarf.New": "debug/dwarf",
+ "dwarf.Offset": "debug/dwarf",
+ "dwarf.PtrType": "debug/dwarf",
+ "dwarf.QualType": "debug/dwarf",
+ "dwarf.Reader": "debug/dwarf",
+ "dwarf.StructField": "debug/dwarf",
+ "dwarf.StructType": "debug/dwarf",
+ "dwarf.Tag": "debug/dwarf",
+ "dwarf.TagAccessDeclaration": "debug/dwarf",
+ "dwarf.TagArrayType": "debug/dwarf",
+ "dwarf.TagBaseType": "debug/dwarf",
+ "dwarf.TagCatchDwarfBlock": "debug/dwarf",
+ "dwarf.TagClassType": "debug/dwarf",
+ "dwarf.TagCommonDwarfBlock": "debug/dwarf",
+ "dwarf.TagCommonInclusion": "debug/dwarf",
+ "dwarf.TagCompileUnit": "debug/dwarf",
+ "dwarf.TagConstType": "debug/dwarf",
+ "dwarf.TagConstant": "debug/dwarf",
+ "dwarf.TagDwarfProcedure": "debug/dwarf",
+ "dwarf.TagEntryPoint": "debug/dwarf",
+ "dwarf.TagEnumerationType": "debug/dwarf",
+ "dwarf.TagEnumerator": "debug/dwarf",
+ "dwarf.TagFileType": "debug/dwarf",
+ "dwarf.TagFormalParameter": "debug/dwarf",
+ "dwarf.TagFriend": "debug/dwarf",
+ "dwarf.TagImportedDeclaration": "debug/dwarf",
+ "dwarf.TagImportedModule": "debug/dwarf",
+ "dwarf.TagImportedUnit": "debug/dwarf",
+ "dwarf.TagInheritance": "debug/dwarf",
+ "dwarf.TagInlinedSubroutine": "debug/dwarf",
+ "dwarf.TagInterfaceType": "debug/dwarf",
+ "dwarf.TagLabel": "debug/dwarf",
+ "dwarf.TagLexDwarfBlock": "debug/dwarf",
+ "dwarf.TagMember": "debug/dwarf",
+ "dwarf.TagModule": "debug/dwarf",
+ "dwarf.TagMutableType": "debug/dwarf",
+ "dwarf.TagNamelist": "debug/dwarf",
+ "dwarf.TagNamelistItem": "debug/dwarf",
+ "dwarf.TagNamespace": "debug/dwarf",
+ "dwarf.TagPackedType": "debug/dwarf",
+ "dwarf.TagPartialUnit": "debug/dwarf",
+ "dwarf.TagPointerType": "debug/dwarf",
+ "dwarf.TagPtrToMemberType": "debug/dwarf",
+ "dwarf.TagReferenceType": "debug/dwarf",
+ "dwarf.TagRestrictType": "debug/dwarf",
+ "dwarf.TagSetType": "debug/dwarf",
+ "dwarf.TagStringType": "debug/dwarf",
+ "dwarf.TagStructType": "debug/dwarf",
+ "dwarf.TagSubprogram": "debug/dwarf",
+ "dwarf.TagSubrangeType": "debug/dwarf",
+ "dwarf.TagSubroutineType": "debug/dwarf",
+ "dwarf.TagTemplateTypeParameter": "debug/dwarf",
+ "dwarf.TagTemplateValueParameter": "debug/dwarf",
+ "dwarf.TagThrownType": "debug/dwarf",
+ "dwarf.TagTryDwarfBlock": "debug/dwarf",
+ "dwarf.TagTypedef": "debug/dwarf",
+ "dwarf.TagUnionType": "debug/dwarf",
+ "dwarf.TagUnspecifiedParameters": "debug/dwarf",
+ "dwarf.TagUnspecifiedType": "debug/dwarf",
+ "dwarf.TagVariable": "debug/dwarf",
+ "dwarf.TagVariant": "debug/dwarf",
+ "dwarf.TagVariantPart": "debug/dwarf",
+ "dwarf.TagVolatileType": "debug/dwarf",
+ "dwarf.TagWithStmt": "debug/dwarf",
+ "dwarf.Type": "debug/dwarf",
+ "dwarf.TypedefType": "debug/dwarf",
+ "dwarf.UcharType": "debug/dwarf",
+ "dwarf.UintType": "debug/dwarf",
+ "dwarf.VoidType": "debug/dwarf",
+ "ecdsa.GenerateKey": "crypto/ecdsa",
+ "ecdsa.PrivateKey": "crypto/ecdsa",
+ "ecdsa.PublicKey": "crypto/ecdsa",
+ "ecdsa.Sign": "crypto/ecdsa",
+ "ecdsa.Verify": "crypto/ecdsa",
+ "elf.ARM_MAGIC_TRAMP_NUMBER": "debug/elf",
+ "elf.Class": "debug/elf",
+ "elf.DF_BIND_NOW": "debug/elf",
+ "elf.DF_ORIGIN": "debug/elf",
+ "elf.DF_STATIC_TLS": "debug/elf",
+ "elf.DF_SYMBOLIC": "debug/elf",
+ "elf.DF_TEXTREL": "debug/elf",
+ "elf.DT_BIND_NOW": "debug/elf",
+ "elf.DT_DEBUG": "debug/elf",
+ "elf.DT_ENCODING": "debug/elf",
+ "elf.DT_FINI": "debug/elf",
+ "elf.DT_FINI_ARRAY": "debug/elf",
+ "elf.DT_FINI_ARRAYSZ": "debug/elf",
+ "elf.DT_FLAGS": "debug/elf",
+ "elf.DT_HASH": "debug/elf",
+ "elf.DT_HIOS": "debug/elf",
+ "elf.DT_HIPROC": "debug/elf",
+ "elf.DT_INIT": "debug/elf",
+ "elf.DT_INIT_ARRAY": "debug/elf",
+ "elf.DT_INIT_ARRAYSZ": "debug/elf",
+ "elf.DT_JMPREL": "debug/elf",
+ "elf.DT_LOOS": "debug/elf",
+ "elf.DT_LOPROC": "debug/elf",
+ "elf.DT_NEEDED": "debug/elf",
+ "elf.DT_NULL": "debug/elf",
+ "elf.DT_PLTGOT": "debug/elf",
+ "elf.DT_PLTREL": "debug/elf",
+ "elf.DT_PLTRELSZ": "debug/elf",
+ "elf.DT_PREINIT_ARRAY": "debug/elf",
+ "elf.DT_PREINIT_ARRAYSZ": "debug/elf",
+ "elf.DT_REL": "debug/elf",
+ "elf.DT_RELA": "debug/elf",
+ "elf.DT_RELAENT": "debug/elf",
+ "elf.DT_RELASZ": "debug/elf",
+ "elf.DT_RELENT": "debug/elf",
+ "elf.DT_RELSZ": "debug/elf",
+ "elf.DT_RPATH": "debug/elf",
+ "elf.DT_RUNPATH": "debug/elf",
+ "elf.DT_SONAME": "debug/elf",
+ "elf.DT_STRSZ": "debug/elf",
+ "elf.DT_STRTAB": "debug/elf",
+ "elf.DT_SYMBOLIC": "debug/elf",
+ "elf.DT_SYMENT": "debug/elf",
+ "elf.DT_SYMTAB": "debug/elf",
+ "elf.DT_TEXTREL": "debug/elf",
+ "elf.DT_VERNEED": "debug/elf",
+ "elf.DT_VERNEEDNUM": "debug/elf",
+ "elf.DT_VERSYM": "debug/elf",
+ "elf.Data": "debug/elf",
+ "elf.Dyn32": "debug/elf",
+ "elf.Dyn64": "debug/elf",
+ "elf.DynFlag": "debug/elf",
+ "elf.DynTag": "debug/elf",
+ "elf.EI_ABIVERSION": "debug/elf",
+ "elf.EI_CLASS": "debug/elf",
+ "elf.EI_DATA": "debug/elf",
+ "elf.EI_NIDENT": "debug/elf",
+ "elf.EI_OSABI": "debug/elf",
+ "elf.EI_PAD": "debug/elf",
+ "elf.EI_VERSION": "debug/elf",
+ "elf.ELFCLASS32": "debug/elf",
+ "elf.ELFCLASS64": "debug/elf",
+ "elf.ELFCLASSNONE": "debug/elf",
+ "elf.ELFDATA2LSB": "debug/elf",
+ "elf.ELFDATA2MSB": "debug/elf",
+ "elf.ELFDATANONE": "debug/elf",
+ "elf.ELFMAG": "debug/elf",
+ "elf.ELFOSABI_86OPEN": "debug/elf",
+ "elf.ELFOSABI_AIX": "debug/elf",
+ "elf.ELFOSABI_ARM": "debug/elf",
+ "elf.ELFOSABI_FREEBSD": "debug/elf",
+ "elf.ELFOSABI_HPUX": "debug/elf",
+ "elf.ELFOSABI_HURD": "debug/elf",
+ "elf.ELFOSABI_IRIX": "debug/elf",
+ "elf.ELFOSABI_LINUX": "debug/elf",
+ "elf.ELFOSABI_MODESTO": "debug/elf",
+ "elf.ELFOSABI_NETBSD": "debug/elf",
+ "elf.ELFOSABI_NONE": "debug/elf",
+ "elf.ELFOSABI_NSK": "debug/elf",
+ "elf.ELFOSABI_OPENBSD": "debug/elf",
+ "elf.ELFOSABI_OPENVMS": "debug/elf",
+ "elf.ELFOSABI_SOLARIS": "debug/elf",
+ "elf.ELFOSABI_STANDALONE": "debug/elf",
+ "elf.ELFOSABI_TRU64": "debug/elf",
+ "elf.EM_386": "debug/elf",
+ "elf.EM_486": "debug/elf",
+ "elf.EM_68HC12": "debug/elf",
+ "elf.EM_68K": "debug/elf",
+ "elf.EM_860": "debug/elf",
+ "elf.EM_88K": "debug/elf",
+ "elf.EM_960": "debug/elf",
+ "elf.EM_ALPHA": "debug/elf",
+ "elf.EM_ALPHA_STD": "debug/elf",
+ "elf.EM_ARC": "debug/elf",
+ "elf.EM_ARM": "debug/elf",
+ "elf.EM_COLDFIRE": "debug/elf",
+ "elf.EM_FR20": "debug/elf",
+ "elf.EM_H8S": "debug/elf",
+ "elf.EM_H8_300": "debug/elf",
+ "elf.EM_H8_300H": "debug/elf",
+ "elf.EM_H8_500": "debug/elf",
+ "elf.EM_IA_64": "debug/elf",
+ "elf.EM_M32": "debug/elf",
+ "elf.EM_ME16": "debug/elf",
+ "elf.EM_MIPS": "debug/elf",
+ "elf.EM_MIPS_RS3_LE": "debug/elf",
+ "elf.EM_MIPS_RS4_BE": "debug/elf",
+ "elf.EM_MIPS_X": "debug/elf",
+ "elf.EM_MMA": "debug/elf",
+ "elf.EM_NCPU": "debug/elf",
+ "elf.EM_NDR1": "debug/elf",
+ "elf.EM_NONE": "debug/elf",
+ "elf.EM_PARISC": "debug/elf",
+ "elf.EM_PCP": "debug/elf",
+ "elf.EM_PPC": "debug/elf",
+ "elf.EM_PPC64": "debug/elf",
+ "elf.EM_RCE": "debug/elf",
+ "elf.EM_RH32": "debug/elf",
+ "elf.EM_S370": "debug/elf",
+ "elf.EM_S390": "debug/elf",
+ "elf.EM_SH": "debug/elf",
+ "elf.EM_SPARC": "debug/elf",
+ "elf.EM_SPARC32PLUS": "debug/elf",
+ "elf.EM_SPARCV9": "debug/elf",
+ "elf.EM_ST100": "debug/elf",
+ "elf.EM_STARCORE": "debug/elf",
+ "elf.EM_TINYJ": "debug/elf",
+ "elf.EM_TRICORE": "debug/elf",
+ "elf.EM_V800": "debug/elf",
+ "elf.EM_VPP500": "debug/elf",
+ "elf.EM_X86_64": "debug/elf",
+ "elf.ET_CORE": "debug/elf",
+ "elf.ET_DYN": "debug/elf",
+ "elf.ET_EXEC": "debug/elf",
+ "elf.ET_HIOS": "debug/elf",
+ "elf.ET_HIPROC": "debug/elf",
+ "elf.ET_LOOS": "debug/elf",
+ "elf.ET_LOPROC": "debug/elf",
+ "elf.ET_NONE": "debug/elf",
+ "elf.ET_REL": "debug/elf",
+ "elf.EV_CURRENT": "debug/elf",
+ "elf.EV_NONE": "debug/elf",
+ "elf.File": "debug/elf",
+ "elf.FileHeader": "debug/elf",
+ "elf.FormatError": "debug/elf",
+ "elf.Header32": "debug/elf",
+ "elf.Header64": "debug/elf",
+ "elf.ImportedSymbol": "debug/elf",
+ "elf.Machine": "debug/elf",
+ "elf.NT_FPREGSET": "debug/elf",
+ "elf.NT_PRPSINFO": "debug/elf",
+ "elf.NT_PRSTATUS": "debug/elf",
+ "elf.NType": "debug/elf",
+ "elf.NewFile": "debug/elf",
+ "elf.OSABI": "debug/elf",
+ "elf.Open": "debug/elf",
+ "elf.PF_MASKOS": "debug/elf",
+ "elf.PF_MASKPROC": "debug/elf",
+ "elf.PF_R": "debug/elf",
+ "elf.PF_W": "debug/elf",
+ "elf.PF_X": "debug/elf",
+ "elf.PT_DYNAMIC": "debug/elf",
+ "elf.PT_HIOS": "debug/elf",
+ "elf.PT_HIPROC": "debug/elf",
+ "elf.PT_INTERP": "debug/elf",
+ "elf.PT_LOAD": "debug/elf",
+ "elf.PT_LOOS": "debug/elf",
+ "elf.PT_LOPROC": "debug/elf",
+ "elf.PT_NOTE": "debug/elf",
+ "elf.PT_NULL": "debug/elf",
+ "elf.PT_PHDR": "debug/elf",
+ "elf.PT_SHLIB": "debug/elf",
+ "elf.PT_TLS": "debug/elf",
+ "elf.Prog": "debug/elf",
+ "elf.Prog32": "debug/elf",
+ "elf.Prog64": "debug/elf",
+ "elf.ProgFlag": "debug/elf",
+ "elf.ProgHeader": "debug/elf",
+ "elf.ProgType": "debug/elf",
+ "elf.R_386": "debug/elf",
+ "elf.R_386_32": "debug/elf",
+ "elf.R_386_COPY": "debug/elf",
+ "elf.R_386_GLOB_DAT": "debug/elf",
+ "elf.R_386_GOT32": "debug/elf",
+ "elf.R_386_GOTOFF": "debug/elf",
+ "elf.R_386_GOTPC": "debug/elf",
+ "elf.R_386_JMP_SLOT": "debug/elf",
+ "elf.R_386_NONE": "debug/elf",
+ "elf.R_386_PC32": "debug/elf",
+ "elf.R_386_PLT32": "debug/elf",
+ "elf.R_386_RELATIVE": "debug/elf",
+ "elf.R_386_TLS_DTPMOD32": "debug/elf",
+ "elf.R_386_TLS_DTPOFF32": "debug/elf",
+ "elf.R_386_TLS_GD": "debug/elf",
+ "elf.R_386_TLS_GD_32": "debug/elf",
+ "elf.R_386_TLS_GD_CALL": "debug/elf",
+ "elf.R_386_TLS_GD_POP": "debug/elf",
+ "elf.R_386_TLS_GD_PUSH": "debug/elf",
+ "elf.R_386_TLS_GOTIE": "debug/elf",
+ "elf.R_386_TLS_IE": "debug/elf",
+ "elf.R_386_TLS_IE_32": "debug/elf",
+ "elf.R_386_TLS_LDM": "debug/elf",
+ "elf.R_386_TLS_LDM_32": "debug/elf",
+ "elf.R_386_TLS_LDM_CALL": "debug/elf",
+ "elf.R_386_TLS_LDM_POP": "debug/elf",
+ "elf.R_386_TLS_LDM_PUSH": "debug/elf",
+ "elf.R_386_TLS_LDO_32": "debug/elf",
+ "elf.R_386_TLS_LE": "debug/elf",
+ "elf.R_386_TLS_LE_32": "debug/elf",
+ "elf.R_386_TLS_TPOFF": "debug/elf",
+ "elf.R_386_TLS_TPOFF32": "debug/elf",
+ "elf.R_ALPHA": "debug/elf",
+ "elf.R_ALPHA_BRADDR": "debug/elf",
+ "elf.R_ALPHA_COPY": "debug/elf",
+ "elf.R_ALPHA_GLOB_DAT": "debug/elf",
+ "elf.R_ALPHA_GPDISP": "debug/elf",
+ "elf.R_ALPHA_GPREL32": "debug/elf",
+ "elf.R_ALPHA_GPRELHIGH": "debug/elf",
+ "elf.R_ALPHA_GPRELLOW": "debug/elf",
+ "elf.R_ALPHA_GPVALUE": "debug/elf",
+ "elf.R_ALPHA_HINT": "debug/elf",
+ "elf.R_ALPHA_IMMED_BR_HI32": "debug/elf",
+ "elf.R_ALPHA_IMMED_GP_16": "debug/elf",
+ "elf.R_ALPHA_IMMED_GP_HI32": "debug/elf",
+ "elf.R_ALPHA_IMMED_LO32": "debug/elf",
+ "elf.R_ALPHA_IMMED_SCN_HI32": "debug/elf",
+ "elf.R_ALPHA_JMP_SLOT": "debug/elf",
+ "elf.R_ALPHA_LITERAL": "debug/elf",
+ "elf.R_ALPHA_LITUSE": "debug/elf",
+ "elf.R_ALPHA_NONE": "debug/elf",
+ "elf.R_ALPHA_OP_PRSHIFT": "debug/elf",
+ "elf.R_ALPHA_OP_PSUB": "debug/elf",
+ "elf.R_ALPHA_OP_PUSH": "debug/elf",
+ "elf.R_ALPHA_OP_STORE": "debug/elf",
+ "elf.R_ALPHA_REFLONG": "debug/elf",
+ "elf.R_ALPHA_REFQUAD": "debug/elf",
+ "elf.R_ALPHA_RELATIVE": "debug/elf",
+ "elf.R_ALPHA_SREL16": "debug/elf",
+ "elf.R_ALPHA_SREL32": "debug/elf",
+ "elf.R_ALPHA_SREL64": "debug/elf",
+ "elf.R_ARM": "debug/elf",
+ "elf.R_ARM_ABS12": "debug/elf",
+ "elf.R_ARM_ABS16": "debug/elf",
+ "elf.R_ARM_ABS32": "debug/elf",
+ "elf.R_ARM_ABS8": "debug/elf",
+ "elf.R_ARM_AMP_VCALL9": "debug/elf",
+ "elf.R_ARM_COPY": "debug/elf",
+ "elf.R_ARM_GLOB_DAT": "debug/elf",
+ "elf.R_ARM_GNU_VTENTRY": "debug/elf",
+ "elf.R_ARM_GNU_VTINHERIT": "debug/elf",
+ "elf.R_ARM_GOT32": "debug/elf",
+ "elf.R_ARM_GOTOFF": "debug/elf",
+ "elf.R_ARM_GOTPC": "debug/elf",
+ "elf.R_ARM_JUMP_SLOT": "debug/elf",
+ "elf.R_ARM_NONE": "debug/elf",
+ "elf.R_ARM_PC13": "debug/elf",
+ "elf.R_ARM_PC24": "debug/elf",
+ "elf.R_ARM_PLT32": "debug/elf",
+ "elf.R_ARM_RABS32": "debug/elf",
+ "elf.R_ARM_RBASE": "debug/elf",
+ "elf.R_ARM_REL32": "debug/elf",
+ "elf.R_ARM_RELATIVE": "debug/elf",
+ "elf.R_ARM_RPC24": "debug/elf",
+ "elf.R_ARM_RREL32": "debug/elf",
+ "elf.R_ARM_RSBREL32": "debug/elf",
+ "elf.R_ARM_SBREL32": "debug/elf",
+ "elf.R_ARM_SWI24": "debug/elf",
+ "elf.R_ARM_THM_ABS5": "debug/elf",
+ "elf.R_ARM_THM_PC22": "debug/elf",
+ "elf.R_ARM_THM_PC8": "debug/elf",
+ "elf.R_ARM_THM_RPC22": "debug/elf",
+ "elf.R_ARM_THM_SWI8": "debug/elf",
+ "elf.R_ARM_THM_XPC22": "debug/elf",
+ "elf.R_ARM_XPC25": "debug/elf",
+ "elf.R_INFO": "debug/elf",
+ "elf.R_INFO32": "debug/elf",
+ "elf.R_PPC": "debug/elf",
+ "elf.R_PPC_ADDR14": "debug/elf",
+ "elf.R_PPC_ADDR14_BRNTAKEN": "debug/elf",
+ "elf.R_PPC_ADDR14_BRTAKEN": "debug/elf",
+ "elf.R_PPC_ADDR16": "debug/elf",
+ "elf.R_PPC_ADDR16_HA": "debug/elf",
+ "elf.R_PPC_ADDR16_HI": "debug/elf",
+ "elf.R_PPC_ADDR16_LO": "debug/elf",
+ "elf.R_PPC_ADDR24": "debug/elf",
+ "elf.R_PPC_ADDR32": "debug/elf",
+ "elf.R_PPC_COPY": "debug/elf",
+ "elf.R_PPC_DTPMOD32": "debug/elf",
+ "elf.R_PPC_DTPREL16": "debug/elf",
+ "elf.R_PPC_DTPREL16_HA": "debug/elf",
+ "elf.R_PPC_DTPREL16_HI": "debug/elf",
+ "elf.R_PPC_DTPREL16_LO": "debug/elf",
+ "elf.R_PPC_DTPREL32": "debug/elf",
+ "elf.R_PPC_EMB_BIT_FLD": "debug/elf",
+ "elf.R_PPC_EMB_MRKREF": "debug/elf",
+ "elf.R_PPC_EMB_NADDR16": "debug/elf",
+ "elf.R_PPC_EMB_NADDR16_HA": "debug/elf",
+ "elf.R_PPC_EMB_NADDR16_HI": "debug/elf",
+ "elf.R_PPC_EMB_NADDR16_LO": "debug/elf",
+ "elf.R_PPC_EMB_NADDR32": "debug/elf",
+ "elf.R_PPC_EMB_RELSDA": "debug/elf",
+ "elf.R_PPC_EMB_RELSEC16": "debug/elf",
+ "elf.R_PPC_EMB_RELST_HA": "debug/elf",
+ "elf.R_PPC_EMB_RELST_HI": "debug/elf",
+ "elf.R_PPC_EMB_RELST_LO": "debug/elf",
+ "elf.R_PPC_EMB_SDA21": "debug/elf",
+ "elf.R_PPC_EMB_SDA2I16": "debug/elf",
+ "elf.R_PPC_EMB_SDA2REL": "debug/elf",
+ "elf.R_PPC_EMB_SDAI16": "debug/elf",
+ "elf.R_PPC_GLOB_DAT": "debug/elf",
+ "elf.R_PPC_GOT16": "debug/elf",
+ "elf.R_PPC_GOT16_HA": "debug/elf",
+ "elf.R_PPC_GOT16_HI": "debug/elf",
+ "elf.R_PPC_GOT16_LO": "debug/elf",
+ "elf.R_PPC_GOT_TLSGD16": "debug/elf",
+ "elf.R_PPC_GOT_TLSGD16_HA": "debug/elf",
+ "elf.R_PPC_GOT_TLSGD16_HI": "debug/elf",
+ "elf.R_PPC_GOT_TLSGD16_LO": "debug/elf",
+ "elf.R_PPC_GOT_TLSLD16": "debug/elf",
+ "elf.R_PPC_GOT_TLSLD16_HA": "debug/elf",
+ "elf.R_PPC_GOT_TLSLD16_HI": "debug/elf",
+ "elf.R_PPC_GOT_TLSLD16_LO": "debug/elf",
+ "elf.R_PPC_GOT_TPREL16": "debug/elf",
+ "elf.R_PPC_GOT_TPREL16_HA": "debug/elf",
+ "elf.R_PPC_GOT_TPREL16_HI": "debug/elf",
+ "elf.R_PPC_GOT_TPREL16_LO": "debug/elf",
+ "elf.R_PPC_JMP_SLOT": "debug/elf",
+ "elf.R_PPC_LOCAL24PC": "debug/elf",
+ "elf.R_PPC_NONE": "debug/elf",
+ "elf.R_PPC_PLT16_HA": "debug/elf",
+ "elf.R_PPC_PLT16_HI": "debug/elf",
+ "elf.R_PPC_PLT16_LO": "debug/elf",
+ "elf.R_PPC_PLT32": "debug/elf",
+ "elf.R_PPC_PLTREL24": "debug/elf",
+ "elf.R_PPC_PLTREL32": "debug/elf",
+ "elf.R_PPC_REL14": "debug/elf",
+ "elf.R_PPC_REL14_BRNTAKEN": "debug/elf",
+ "elf.R_PPC_REL14_BRTAKEN": "debug/elf",
+ "elf.R_PPC_REL24": "debug/elf",
+ "elf.R_PPC_REL32": "debug/elf",
+ "elf.R_PPC_RELATIVE": "debug/elf",
+ "elf.R_PPC_SDAREL16": "debug/elf",
+ "elf.R_PPC_SECTOFF": "debug/elf",
+ "elf.R_PPC_SECTOFF_HA": "debug/elf",
+ "elf.R_PPC_SECTOFF_HI": "debug/elf",
+ "elf.R_PPC_SECTOFF_LO": "debug/elf",
+ "elf.R_PPC_TLS": "debug/elf",
+ "elf.R_PPC_TPREL16": "debug/elf",
+ "elf.R_PPC_TPREL16_HA": "debug/elf",
+ "elf.R_PPC_TPREL16_HI": "debug/elf",
+ "elf.R_PPC_TPREL16_LO": "debug/elf",
+ "elf.R_PPC_TPREL32": "debug/elf",
+ "elf.R_PPC_UADDR16": "debug/elf",
+ "elf.R_PPC_UADDR32": "debug/elf",
+ "elf.R_SPARC": "debug/elf",
+ "elf.R_SPARC_10": "debug/elf",
+ "elf.R_SPARC_11": "debug/elf",
+ "elf.R_SPARC_13": "debug/elf",
+ "elf.R_SPARC_16": "debug/elf",
+ "elf.R_SPARC_22": "debug/elf",
+ "elf.R_SPARC_32": "debug/elf",
+ "elf.R_SPARC_5": "debug/elf",
+ "elf.R_SPARC_6": "debug/elf",
+ "elf.R_SPARC_64": "debug/elf",
+ "elf.R_SPARC_7": "debug/elf",
+ "elf.R_SPARC_8": "debug/elf",
+ "elf.R_SPARC_COPY": "debug/elf",
+ "elf.R_SPARC_DISP16": "debug/elf",
+ "elf.R_SPARC_DISP32": "debug/elf",
+ "elf.R_SPARC_DISP64": "debug/elf",
+ "elf.R_SPARC_DISP8": "debug/elf",
+ "elf.R_SPARC_GLOB_DAT": "debug/elf",
+ "elf.R_SPARC_GLOB_JMP": "debug/elf",
+ "elf.R_SPARC_GOT10": "debug/elf",
+ "elf.R_SPARC_GOT13": "debug/elf",
+ "elf.R_SPARC_GOT22": "debug/elf",
+ "elf.R_SPARC_H44": "debug/elf",
+ "elf.R_SPARC_HH22": "debug/elf",
+ "elf.R_SPARC_HI22": "debug/elf",
+ "elf.R_SPARC_HIPLT22": "debug/elf",
+ "elf.R_SPARC_HIX22": "debug/elf",
+ "elf.R_SPARC_HM10": "debug/elf",
+ "elf.R_SPARC_JMP_SLOT": "debug/elf",
+ "elf.R_SPARC_L44": "debug/elf",
+ "elf.R_SPARC_LM22": "debug/elf",
+ "elf.R_SPARC_LO10": "debug/elf",
+ "elf.R_SPARC_LOPLT10": "debug/elf",
+ "elf.R_SPARC_LOX10": "debug/elf",
+ "elf.R_SPARC_M44": "debug/elf",
+ "elf.R_SPARC_NONE": "debug/elf",
+ "elf.R_SPARC_OLO10": "debug/elf",
+ "elf.R_SPARC_PC10": "debug/elf",
+ "elf.R_SPARC_PC22": "debug/elf",
+ "elf.R_SPARC_PCPLT10": "debug/elf",
+ "elf.R_SPARC_PCPLT22": "debug/elf",
+ "elf.R_SPARC_PCPLT32": "debug/elf",
+ "elf.R_SPARC_PC_HH22": "debug/elf",
+ "elf.R_SPARC_PC_HM10": "debug/elf",
+ "elf.R_SPARC_PC_LM22": "debug/elf",
+ "elf.R_SPARC_PLT32": "debug/elf",
+ "elf.R_SPARC_PLT64": "debug/elf",
+ "elf.R_SPARC_REGISTER": "debug/elf",
+ "elf.R_SPARC_RELATIVE": "debug/elf",
+ "elf.R_SPARC_UA16": "debug/elf",
+ "elf.R_SPARC_UA32": "debug/elf",
+ "elf.R_SPARC_UA64": "debug/elf",
+ "elf.R_SPARC_WDISP16": "debug/elf",
+ "elf.R_SPARC_WDISP19": "debug/elf",
+ "elf.R_SPARC_WDISP22": "debug/elf",
+ "elf.R_SPARC_WDISP30": "debug/elf",
+ "elf.R_SPARC_WPLT30": "debug/elf",
+ "elf.R_SYM32": "debug/elf",
+ "elf.R_SYM64": "debug/elf",
+ "elf.R_TYPE32": "debug/elf",
+ "elf.R_TYPE64": "debug/elf",
+ "elf.R_X86_64": "debug/elf",
+ "elf.R_X86_64_16": "debug/elf",
+ "elf.R_X86_64_32": "debug/elf",
+ "elf.R_X86_64_32S": "debug/elf",
+ "elf.R_X86_64_64": "debug/elf",
+ "elf.R_X86_64_8": "debug/elf",
+ "elf.R_X86_64_COPY": "debug/elf",
+ "elf.R_X86_64_DTPMOD64": "debug/elf",
+ "elf.R_X86_64_DTPOFF32": "debug/elf",
+ "elf.R_X86_64_DTPOFF64": "debug/elf",
+ "elf.R_X86_64_GLOB_DAT": "debug/elf",
+ "elf.R_X86_64_GOT32": "debug/elf",
+ "elf.R_X86_64_GOTPCREL": "debug/elf",
+ "elf.R_X86_64_GOTTPOFF": "debug/elf",
+ "elf.R_X86_64_JMP_SLOT": "debug/elf",
+ "elf.R_X86_64_NONE": "debug/elf",
+ "elf.R_X86_64_PC16": "debug/elf",
+ "elf.R_X86_64_PC32": "debug/elf",
+ "elf.R_X86_64_PC8": "debug/elf",
+ "elf.R_X86_64_PLT32": "debug/elf",
+ "elf.R_X86_64_RELATIVE": "debug/elf",
+ "elf.R_X86_64_TLSGD": "debug/elf",
+ "elf.R_X86_64_TLSLD": "debug/elf",
+ "elf.R_X86_64_TPOFF32": "debug/elf",
+ "elf.R_X86_64_TPOFF64": "debug/elf",
+ "elf.Rel32": "debug/elf",
+ "elf.Rel64": "debug/elf",
+ "elf.Rela32": "debug/elf",
+ "elf.Rela64": "debug/elf",
+ "elf.SHF_ALLOC": "debug/elf",
+ "elf.SHF_EXECINSTR": "debug/elf",
+ "elf.SHF_GROUP": "debug/elf",
+ "elf.SHF_INFO_LINK": "debug/elf",
+ "elf.SHF_LINK_ORDER": "debug/elf",
+ "elf.SHF_MASKOS": "debug/elf",
+ "elf.SHF_MASKPROC": "debug/elf",
+ "elf.SHF_MERGE": "debug/elf",
+ "elf.SHF_OS_NONCONFORMING": "debug/elf",
+ "elf.SHF_STRINGS": "debug/elf",
+ "elf.SHF_TLS": "debug/elf",
+ "elf.SHF_WRITE": "debug/elf",
+ "elf.SHN_ABS": "debug/elf",
+ "elf.SHN_COMMON": "debug/elf",
+ "elf.SHN_HIOS": "debug/elf",
+ "elf.SHN_HIPROC": "debug/elf",
+ "elf.SHN_HIRESERVE": "debug/elf",
+ "elf.SHN_LOOS": "debug/elf",
+ "elf.SHN_LOPROC": "debug/elf",
+ "elf.SHN_LORESERVE": "debug/elf",
+ "elf.SHN_UNDEF": "debug/elf",
+ "elf.SHN_XINDEX": "debug/elf",
+ "elf.SHT_DYNAMIC": "debug/elf",
+ "elf.SHT_DYNSYM": "debug/elf",
+ "elf.SHT_FINI_ARRAY": "debug/elf",
+ "elf.SHT_GNU_ATTRIBUTES": "debug/elf",
+ "elf.SHT_GNU_HASH": "debug/elf",
+ "elf.SHT_GNU_LIBLIST": "debug/elf",
+ "elf.SHT_GNU_VERDEF": "debug/elf",
+ "elf.SHT_GNU_VERNEED": "debug/elf",
+ "elf.SHT_GNU_VERSYM": "debug/elf",
+ "elf.SHT_GROUP": "debug/elf",
+ "elf.SHT_HASH": "debug/elf",
+ "elf.SHT_HIOS": "debug/elf",
+ "elf.SHT_HIPROC": "debug/elf",
+ "elf.SHT_HIUSER": "debug/elf",
+ "elf.SHT_INIT_ARRAY": "debug/elf",
+ "elf.SHT_LOOS": "debug/elf",
+ "elf.SHT_LOPROC": "debug/elf",
+ "elf.SHT_LOUSER": "debug/elf",
+ "elf.SHT_NOBITS": "debug/elf",
+ "elf.SHT_NOTE": "debug/elf",
+ "elf.SHT_NULL": "debug/elf",
+ "elf.SHT_PREINIT_ARRAY": "debug/elf",
+ "elf.SHT_PROGBITS": "debug/elf",
+ "elf.SHT_REL": "debug/elf",
+ "elf.SHT_RELA": "debug/elf",
+ "elf.SHT_SHLIB": "debug/elf",
+ "elf.SHT_STRTAB": "debug/elf",
+ "elf.SHT_SYMTAB": "debug/elf",
+ "elf.SHT_SYMTAB_SHNDX": "debug/elf",
+ "elf.STB_GLOBAL": "debug/elf",
+ "elf.STB_HIOS": "debug/elf",
+ "elf.STB_HIPROC": "debug/elf",
+ "elf.STB_LOCAL": "debug/elf",
+ "elf.STB_LOOS": "debug/elf",
+ "elf.STB_LOPROC": "debug/elf",
+ "elf.STB_WEAK": "debug/elf",
+ "elf.STT_COMMON": "debug/elf",
+ "elf.STT_FILE": "debug/elf",
+ "elf.STT_FUNC": "debug/elf",
+ "elf.STT_HIOS": "debug/elf",
+ "elf.STT_HIPROC": "debug/elf",
+ "elf.STT_LOOS": "debug/elf",
+ "elf.STT_LOPROC": "debug/elf",
+ "elf.STT_NOTYPE": "debug/elf",
+ "elf.STT_OBJECT": "debug/elf",
+ "elf.STT_SECTION": "debug/elf",
+ "elf.STT_TLS": "debug/elf",
+ "elf.STV_DEFAULT": "debug/elf",
+ "elf.STV_HIDDEN": "debug/elf",
+ "elf.STV_INTERNAL": "debug/elf",
+ "elf.STV_PROTECTED": "debug/elf",
+ "elf.ST_BIND": "debug/elf",
+ "elf.ST_INFO": "debug/elf",
+ "elf.ST_TYPE": "debug/elf",
+ "elf.ST_VISIBILITY": "debug/elf",
+ "elf.Section": "debug/elf",
+ "elf.Section32": "debug/elf",
+ "elf.Section64": "debug/elf",
+ "elf.SectionFlag": "debug/elf",
+ "elf.SectionHeader": "debug/elf",
+ "elf.SectionIndex": "debug/elf",
+ "elf.SectionType": "debug/elf",
+ "elf.Sym32": "debug/elf",
+ "elf.Sym32Size": "debug/elf",
+ "elf.Sym64": "debug/elf",
+ "elf.Sym64Size": "debug/elf",
+ "elf.SymBind": "debug/elf",
+ "elf.SymType": "debug/elf",
+ "elf.SymVis": "debug/elf",
+ "elf.Symbol": "debug/elf",
+ "elf.Type": "debug/elf",
+ "elf.Version": "debug/elf",
+ "elliptic.Curve": "crypto/elliptic",
+ "elliptic.CurveParams": "crypto/elliptic",
+ "elliptic.GenerateKey": "crypto/elliptic",
+ "elliptic.Marshal": "crypto/elliptic",
+ "elliptic.P224": "crypto/elliptic",
+ "elliptic.P256": "crypto/elliptic",
+ "elliptic.P384": "crypto/elliptic",
+ "elliptic.P521": "crypto/elliptic",
+ "elliptic.Unmarshal": "crypto/elliptic",
+ "encoding.BinaryMarshaler": "encoding",
+ "encoding.BinaryUnmarshaler": "encoding",
+ "encoding.TextMarshaler": "encoding",
+ "encoding.TextUnmarshaler": "encoding",
+ "errors.New": "errors",
+ "exec.Cmd": "os/exec",
+ "exec.Command": "os/exec",
+ "exec.ErrNotFound": "os/exec",
+ "exec.Error": "os/exec",
+ "exec.ExitError": "os/exec",
+ "exec.LookPath": "os/exec",
+ "expvar.Do": "expvar",
+ "expvar.Float": "expvar",
+ "expvar.Func": "expvar",
+ "expvar.Get": "expvar",
+ "expvar.Int": "expvar",
+ "expvar.KeyValue": "expvar",
+ "expvar.Map": "expvar",
+ "expvar.NewFloat": "expvar",
+ "expvar.NewInt": "expvar",
+ "expvar.NewMap": "expvar",
+ "expvar.NewString": "expvar",
+ "expvar.Publish": "expvar",
+ "expvar.String": "expvar",
+ "expvar.Var": "expvar",
+ "fcgi.Serve": "net/http/fcgi",
+ "filepath.Abs": "path/filepath",
+ "filepath.Base": "path/filepath",
+ "filepath.Clean": "path/filepath",
+ "filepath.Dir": "path/filepath",
+ "filepath.ErrBadPattern": "path/filepath",
+ "filepath.EvalSymlinks": "path/filepath",
+ "filepath.Ext": "path/filepath",
+ "filepath.FromSlash": "path/filepath",
+ "filepath.Glob": "path/filepath",
+ "filepath.HasPrefix": "path/filepath",
+ "filepath.IsAbs": "path/filepath",
+ "filepath.Join": "path/filepath",
+ "filepath.ListSeparator": "path/filepath",
+ "filepath.Match": "path/filepath",
+ "filepath.Rel": "path/filepath",
+ "filepath.Separator": "path/filepath",
+ "filepath.SkipDir": "path/filepath",
+ "filepath.Split": "path/filepath",
+ "filepath.SplitList": "path/filepath",
+ "filepath.ToSlash": "path/filepath",
+ "filepath.VolumeName": "path/filepath",
+ "filepath.Walk": "path/filepath",
+ "filepath.WalkFunc": "path/filepath",
+ "flag.Arg": "flag",
+ "flag.Args": "flag",
+ "flag.Bool": "flag",
+ "flag.BoolVar": "flag",
+ "flag.CommandLine": "flag",
+ "flag.ContinueOnError": "flag",
+ "flag.Duration": "flag",
+ "flag.DurationVar": "flag",
+ "flag.ErrHelp": "flag",
+ "flag.ErrorHandling": "flag",
+ "flag.ExitOnError": "flag",
+ "flag.Flag": "flag",
+ "flag.FlagSet": "flag",
+ "flag.Float64": "flag",
+ "flag.Float64Var": "flag",
+ "flag.Getter": "flag",
+ "flag.Int": "flag",
+ "flag.Int64": "flag",
+ "flag.Int64Var": "flag",
+ "flag.IntVar": "flag",
+ "flag.Lookup": "flag",
+ "flag.NArg": "flag",
+ "flag.NFlag": "flag",
+ "flag.NewFlagSet": "flag",
+ "flag.PanicOnError": "flag",
+ "flag.Parse": "flag",
+ "flag.Parsed": "flag",
+ "flag.PrintDefaults": "flag",
+ "flag.Set": "flag",
+ "flag.String": "flag",
+ "flag.StringVar": "flag",
+ "flag.Uint": "flag",
+ "flag.Uint64": "flag",
+ "flag.Uint64Var": "flag",
+ "flag.UintVar": "flag",
+ "flag.Usage": "flag",
+ "flag.Value": "flag",
+ "flag.Var": "flag",
+ "flag.Visit": "flag",
+ "flag.VisitAll": "flag",
+ "flate.BestCompression": "compress/flate",
+ "flate.BestSpeed": "compress/flate",
+ "flate.CorruptInputError": "compress/flate",
+ "flate.DefaultCompression": "compress/flate",
+ "flate.InternalError": "compress/flate",
+ "flate.NewReader": "compress/flate",
+ "flate.NewReaderDict": "compress/flate",
+ "flate.NewWriter": "compress/flate",
+ "flate.NewWriterDict": "compress/flate",
+ "flate.NoCompression": "compress/flate",
+ "flate.ReadError": "compress/flate",
+ "flate.Reader": "compress/flate",
+ "flate.WriteError": "compress/flate",
+ "flate.Writer": "compress/flate",
+ "fmt.Errorf": "fmt",
+ "fmt.Formatter": "fmt",
+ "fmt.Fprint": "fmt",
+ "fmt.Fprintf": "fmt",
+ "fmt.Fprintln": "fmt",
+ "fmt.Fscan": "fmt",
+ "fmt.Fscanf": "fmt",
+ "fmt.Fscanln": "fmt",
+ "fmt.GoStringer": "fmt",
+ "fmt.Print": "fmt",
+ "fmt.Printf": "fmt",
+ "fmt.Println": "fmt",
+ "fmt.Scan": "fmt",
+ "fmt.ScanState": "fmt",
+ "fmt.Scanf": "fmt",
+ "fmt.Scanln": "fmt",
+ "fmt.Scanner": "fmt",
+ "fmt.Sprint": "fmt",
+ "fmt.Sprintf": "fmt",
+ "fmt.Sprintln": "fmt",
+ "fmt.Sscan": "fmt",
+ "fmt.Sscanf": "fmt",
+ "fmt.Sscanln": "fmt",
+ "fmt.State": "fmt",
+ "fmt.Stringer": "fmt",
+ "fnv.New32": "hash/fnv",
+ "fnv.New32a": "hash/fnv",
+ "fnv.New64": "hash/fnv",
+ "fnv.New64a": "hash/fnv",
+ "format.Node": "go/format",
+ "format.Source": "go/format",
+ "gif.Decode": "image/gif",
+ "gif.DecodeAll": "image/gif",
+ "gif.DecodeConfig": "image/gif",
+ "gif.Encode": "image/gif",
+ "gif.EncodeAll": "image/gif",
+ "gif.GIF": "image/gif",
+ "gif.Options": "image/gif",
+ "gob.CommonType": "encoding/gob",
+ "gob.Decoder": "encoding/gob",
+ "gob.Encoder": "encoding/gob",
+ "gob.GobDecoder": "encoding/gob",
+ "gob.GobEncoder": "encoding/gob",
+ "gob.NewDecoder": "encoding/gob",
+ "gob.NewEncoder": "encoding/gob",
+ "gob.Register": "encoding/gob",
+ "gob.RegisterName": "encoding/gob",
+ "gosym.DecodingError": "debug/gosym",
+ "gosym.Func": "debug/gosym",
+ "gosym.LineTable": "debug/gosym",
+ "gosym.NewLineTable": "debug/gosym",
+ "gosym.NewTable": "debug/gosym",
+ "gosym.Obj": "debug/gosym",
+ "gosym.Sym": "debug/gosym",
+ "gosym.Table": "debug/gosym",
+ "gosym.UnknownFileError": "debug/gosym",
+ "gosym.UnknownLineError": "debug/gosym",
+ "gzip.BestCompression": "compress/gzip",
+ "gzip.BestSpeed": "compress/gzip",
+ "gzip.DefaultCompression": "compress/gzip",
+ "gzip.ErrChecksum": "compress/gzip",
+ "gzip.ErrHeader": "compress/gzip",
+ "gzip.Header": "compress/gzip",
+ "gzip.NewReader": "compress/gzip",
+ "gzip.NewWriter": "compress/gzip",
+ "gzip.NewWriterLevel": "compress/gzip",
+ "gzip.NoCompression": "compress/gzip",
+ "gzip.Reader": "compress/gzip",
+ "gzip.Writer": "compress/gzip",
+ "hash.Hash": "hash",
+ "hash.Hash32": "hash",
+ "hash.Hash64": "hash",
+ "heap.Fix": "container/heap",
+ "heap.Init": "container/heap",
+ "heap.Interface": "container/heap",
+ "heap.Pop": "container/heap",
+ "heap.Push": "container/heap",
+ "heap.Remove": "container/heap",
+ "hex.Decode": "encoding/hex",
+ "hex.DecodeString": "encoding/hex",
+ "hex.DecodedLen": "encoding/hex",
+ "hex.Dump": "encoding/hex",
+ "hex.Dumper": "encoding/hex",
+ "hex.Encode": "encoding/hex",
+ "hex.EncodeToString": "encoding/hex",
+ "hex.EncodedLen": "encoding/hex",
+ "hex.ErrLength": "encoding/hex",
+ "hex.InvalidByteError": "encoding/hex",
+ "hmac.Equal": "crypto/hmac",
+ "hmac.New": "crypto/hmac",
+ "html.EscapeString": "html",
+ "html.UnescapeString": "html",
+ "http.CanonicalHeaderKey": "net/http",
+ "http.Client": "net/http",
+ "http.CloseNotifier": "net/http",
+ "http.Cookie": "net/http",
+ "http.CookieJar": "net/http",
+ "http.DefaultClient": "net/http",
+ "http.DefaultMaxHeaderBytes": "net/http",
+ "http.DefaultMaxIdleConnsPerHost": "net/http",
+ "http.DefaultServeMux": "net/http",
+ "http.DefaultTransport": "net/http",
+ "http.DetectContentType": "net/http",
+ "http.Dir": "net/http",
+ "http.ErrBodyNotAllowed": "net/http",
+ "http.ErrBodyReadAfterClose": "net/http",
+ "http.ErrContentLength": "net/http",
+ "http.ErrHandlerTimeout": "net/http",
+ "http.ErrHeaderTooLong": "net/http",
+ "http.ErrHijacked": "net/http",
+ "http.ErrLineTooLong": "net/http",
+ "http.ErrMissingBoundary": "net/http",
+ "http.ErrMissingContentLength": "net/http",
+ "http.ErrMissingFile": "net/http",
+ "http.ErrNoCookie": "net/http",
+ "http.ErrNoLocation": "net/http",
+ "http.ErrNotMultipart": "net/http",
+ "http.ErrNotSupported": "net/http",
+ "http.ErrShortBody": "net/http",
+ "http.ErrUnexpectedTrailer": "net/http",
+ "http.ErrWriteAfterFlush": "net/http",
+ "http.Error": "net/http",
+ "http.File": "net/http",
+ "http.FileServer": "net/http",
+ "http.FileSystem": "net/http",
+ "http.Flusher": "net/http",
+ "http.Get": "net/http",
+ "http.Handle": "net/http",
+ "http.HandleFunc": "net/http",
+ "http.Handler": "net/http",
+ "http.HandlerFunc": "net/http",
+ "http.Head": "net/http",
+ "http.Header": "net/http",
+ "http.Hijacker": "net/http",
+ "http.ListenAndServe": "net/http",
+ "http.ListenAndServeTLS": "net/http",
+ "http.MaxBytesReader": "net/http",
+ "http.NewFileTransport": "net/http",
+ "http.NewRequest": "net/http",
+ "http.NewServeMux": "net/http",
+ "http.NotFound": "net/http",
+ "http.NotFoundHandler": "net/http",
+ "http.ParseHTTPVersion": "net/http",
+ "http.ParseTime": "net/http",
+ "http.Post": "net/http",
+ "http.PostForm": "net/http",
+ "http.ProtocolError": "net/http",
+ "http.ProxyFromEnvironment": "net/http",
+ "http.ProxyURL": "net/http",
+ "http.ReadRequest": "net/http",
+ "http.ReadResponse": "net/http",
+ "http.Redirect": "net/http",
+ "http.RedirectHandler": "net/http",
+ "http.Request": "net/http",
+ "http.Response": "net/http",
+ "http.ResponseWriter": "net/http",
+ "http.RoundTripper": "net/http",
+ "http.Serve": "net/http",
+ "http.ServeContent": "net/http",
+ "http.ServeFile": "net/http",
+ "http.ServeMux": "net/http",
+ "http.Server": "net/http",
+ "http.SetCookie": "net/http",
+ "http.StatusAccepted": "net/http",
+ "http.StatusBadGateway": "net/http",
+ "http.StatusBadRequest": "net/http",
+ "http.StatusConflict": "net/http",
+ "http.StatusContinue": "net/http",
+ "http.StatusCreated": "net/http",
+ "http.StatusExpectationFailed": "net/http",
+ "http.StatusForbidden": "net/http",
+ "http.StatusFound": "net/http",
+ "http.StatusGatewayTimeout": "net/http",
+ "http.StatusGone": "net/http",
+ "http.StatusHTTPVersionNotSupported": "net/http",
+ "http.StatusInternalServerError": "net/http",
+ "http.StatusLengthRequired": "net/http",
+ "http.StatusMethodNotAllowed": "net/http",
+ "http.StatusMovedPermanently": "net/http",
+ "http.StatusMultipleChoices": "net/http",
+ "http.StatusNoContent": "net/http",
+ "http.StatusNonAuthoritativeInfo": "net/http",
+ "http.StatusNotAcceptable": "net/http",
+ "http.StatusNotFound": "net/http",
+ "http.StatusNotImplemented": "net/http",
+ "http.StatusNotModified": "net/http",
+ "http.StatusOK": "net/http",
+ "http.StatusPartialContent": "net/http",
+ "http.StatusPaymentRequired": "net/http",
+ "http.StatusPreconditionFailed": "net/http",
+ "http.StatusProxyAuthRequired": "net/http",
+ "http.StatusRequestEntityTooLarge": "net/http",
+ "http.StatusRequestTimeout": "net/http",
+ "http.StatusRequestURITooLong": "net/http",
+ "http.StatusRequestedRangeNotSatisfiable": "net/http",
+ "http.StatusResetContent": "net/http",
+ "http.StatusSeeOther": "net/http",
+ "http.StatusServiceUnavailable": "net/http",
+ "http.StatusSwitchingProtocols": "net/http",
+ "http.StatusTeapot": "net/http",
+ "http.StatusTemporaryRedirect": "net/http",
+ "http.StatusText": "net/http",
+ "http.StatusUnauthorized": "net/http",
+ "http.StatusUnsupportedMediaType": "net/http",
+ "http.StatusUseProxy": "net/http",
+ "http.StripPrefix": "net/http",
+ "http.TimeFormat": "net/http",
+ "http.TimeoutHandler": "net/http",
+ "http.Transport": "net/http",
+ "httptest.DefaultRemoteAddr": "net/http/httptest",
+ "httptest.NewRecorder": "net/http/httptest",
+ "httptest.NewServer": "net/http/httptest",
+ "httptest.NewTLSServer": "net/http/httptest",
+ "httptest.NewUnstartedServer": "net/http/httptest",
+ "httptest.ResponseRecorder": "net/http/httptest",
+ "httptest.Server": "net/http/httptest",
+ "httputil.ClientConn": "net/http/httputil",
+ "httputil.DumpRequest": "net/http/httputil",
+ "httputil.DumpRequestOut": "net/http/httputil",
+ "httputil.DumpResponse": "net/http/httputil",
+ "httputil.ErrClosed": "net/http/httputil",
+ "httputil.ErrLineTooLong": "net/http/httputil",
+ "httputil.ErrPersistEOF": "net/http/httputil",
+ "httputil.ErrPipeline": "net/http/httputil",
+ "httputil.NewChunkedReader": "net/http/httputil",
+ "httputil.NewChunkedWriter": "net/http/httputil",
+ "httputil.NewClientConn": "net/http/httputil",
+ "httputil.NewProxyClientConn": "net/http/httputil",
+ "httputil.NewServerConn": "net/http/httputil",
+ "httputil.NewSingleHostReverseProxy": "net/http/httputil",
+ "httputil.ReverseProxy": "net/http/httputil",
+ "httputil.ServerConn": "net/http/httputil",
+ "image.Alpha": "image",
+ "image.Alpha16": "image",
+ "image.Black": "image",
+ "image.Config": "image",
+ "image.Decode": "image",
+ "image.DecodeConfig": "image",
+ "image.ErrFormat": "image",
+ "image.Gray": "image",
+ "image.Gray16": "image",
+ "image.Image": "image",
+ "image.NRGBA": "image",
+ "image.NRGBA64": "image",
+ "image.NewAlpha": "image",
+ "image.NewAlpha16": "image",
+ "image.NewGray": "image",
+ "image.NewGray16": "image",
+ "image.NewNRGBA": "image",
+ "image.NewNRGBA64": "image",
+ "image.NewPaletted": "image",
+ "image.NewRGBA": "image",
+ "image.NewRGBA64": "image",
+ "image.NewUniform": "image",
+ "image.NewYCbCr": "image",
+ "image.Opaque": "image",
+ "image.Paletted": "image",
+ "image.PalettedImage": "image",
+ "image.Point": "image",
+ "image.Pt": "image",
+ "image.RGBA": "image",
+ "image.RGBA64": "image",
+ "image.Rect": "image",
+ "image.Rectangle": "image",
+ "image.RegisterFormat": "image",
+ "image.Transparent": "image",
+ "image.Uniform": "image",
+ "image.White": "image",
+ "image.YCbCr": "image",
+ "image.YCbCrSubsampleRatio": "image",
+ "image.YCbCrSubsampleRatio420": "image",
+ "image.YCbCrSubsampleRatio422": "image",
+ "image.YCbCrSubsampleRatio440": "image",
+ "image.YCbCrSubsampleRatio444": "image",
+ "image.ZP": "image",
+ "image.ZR": "image",
+ "io.ByteReader": "io",
+ "io.ByteScanner": "io",
+ "io.ByteWriter": "io",
+ "io.Closer": "io",
+ "io.Copy": "io",
+ "io.CopyN": "io",
+ "io.EOF": "io",
+ "io.ErrClosedPipe": "io",
+ "io.ErrNoProgress": "io",
+ "io.ErrShortBuffer": "io",
+ "io.ErrShortWrite": "io",
+ "io.ErrUnexpectedEOF": "io",
+ "io.LimitReader": "io",
+ "io.LimitedReader": "io",
+ "io.MultiReader": "io",
+ "io.MultiWriter": "io",
+ "io.NewSectionReader": "io",
+ "io.Pipe": "io",
+ "io.PipeReader": "io",
+ "io.PipeWriter": "io",
+ "io.ReadAtLeast": "io",
+ "io.ReadCloser": "io",
+ "io.ReadFull": "io",
+ "io.ReadSeeker": "io",
+ "io.ReadWriteCloser": "io",
+ "io.ReadWriteSeeker": "io",
+ "io.ReadWriter": "io",
+ "io.Reader": "io",
+ "io.ReaderAt": "io",
+ "io.ReaderFrom": "io",
+ "io.RuneReader": "io",
+ "io.RuneScanner": "io",
+ "io.SectionReader": "io",
+ "io.Seeker": "io",
+ "io.TeeReader": "io",
+ "io.WriteCloser": "io",
+ "io.WriteSeeker": "io",
+ "io.WriteString": "io",
+ "io.Writer": "io",
+ "io.WriterAt": "io",
+ "io.WriterTo": "io",
+ "iotest.DataErrReader": "testing/iotest",
+ "iotest.ErrTimeout": "testing/iotest",
+ "iotest.HalfReader": "testing/iotest",
+ "iotest.NewReadLogger": "testing/iotest",
+ "iotest.NewWriteLogger": "testing/iotest",
+ "iotest.OneByteReader": "testing/iotest",
+ "iotest.TimeoutReader": "testing/iotest",
+ "iotest.TruncateWriter": "testing/iotest",
+ "ioutil.Discard": "io/ioutil",
+ "ioutil.NopCloser": "io/ioutil",
+ "ioutil.ReadAll": "io/ioutil",
+ "ioutil.ReadDir": "io/ioutil",
+ "ioutil.ReadFile": "io/ioutil",
+ "ioutil.TempDir": "io/ioutil",
+ "ioutil.TempFile": "io/ioutil",
+ "ioutil.WriteFile": "io/ioutil",
+ "jpeg.Decode": "image/jpeg",
+ "jpeg.DecodeConfig": "image/jpeg",
+ "jpeg.DefaultQuality": "image/jpeg",
+ "jpeg.Encode": "image/jpeg",
+ "jpeg.FormatError": "image/jpeg",
+ "jpeg.Options": "image/jpeg",
+ "jpeg.Reader": "image/jpeg",
+ "jpeg.UnsupportedError": "image/jpeg",
+ "json.Compact": "encoding/json",
+ "json.Decoder": "encoding/json",
+ "json.Encoder": "encoding/json",
+ "json.HTMLEscape": "encoding/json",
+ "json.Indent": "encoding/json",
+ "json.InvalidUTF8Error": "encoding/json",
+ "json.InvalidUnmarshalError": "encoding/json",
+ "json.Marshal": "encoding/json",
+ "json.MarshalIndent": "encoding/json",
+ "json.Marshaler": "encoding/json",
+ "json.MarshalerError": "encoding/json",
+ "json.NewDecoder": "encoding/json",
+ "json.NewEncoder": "encoding/json",
+ "json.Number": "encoding/json",
+ "json.RawMessage": "encoding/json",
+ "json.SyntaxError": "encoding/json",
+ "json.Unmarshal": "encoding/json",
+ "json.UnmarshalFieldError": "encoding/json",
+ "json.UnmarshalTypeError": "encoding/json",
+ "json.Unmarshaler": "encoding/json",
+ "json.UnsupportedTypeError": "encoding/json",
+ "json.UnsupportedValueError": "encoding/json",
+ "jsonrpc.Dial": "net/rpc/jsonrpc",
+ "jsonrpc.NewClient": "net/rpc/jsonrpc",
+ "jsonrpc.NewClientCodec": "net/rpc/jsonrpc",
+ "jsonrpc.NewServerCodec": "net/rpc/jsonrpc",
+ "jsonrpc.ServeConn": "net/rpc/jsonrpc",
+ "list.Element": "container/list",
+ "list.List": "container/list",
+ "list.New": "container/list",
+ "log.Fatal": "log",
+ "log.Fatalf": "log",
+ "log.Fatalln": "log",
+ "log.Flags": "log",
+ "log.Ldate": "log",
+ "log.Llongfile": "log",
+ "log.Lmicroseconds": "log",
+ "log.Logger": "log",
+ "log.Lshortfile": "log",
+ "log.LstdFlags": "log",
+ "log.Ltime": "log",
+ "log.New": "log",
+ "log.Panic": "log",
+ "log.Panicf": "log",
+ "log.Panicln": "log",
+ "log.Prefix": "log",
+ "log.Print": "log",
+ "log.Printf": "log",
+ "log.Println": "log",
+ "log.SetFlags": "log",
+ "log.SetOutput": "log",
+ "log.SetPrefix": "log",
+ "lzw.LSB": "compress/lzw",
+ "lzw.MSB": "compress/lzw",
+ "lzw.NewReader": "compress/lzw",
+ "lzw.NewWriter": "compress/lzw",
+ "lzw.Order": "compress/lzw",
+ "macho.Cpu": "debug/macho",
+ "macho.Cpu386": "debug/macho",
+ "macho.CpuAmd64": "debug/macho",
+ "macho.Dylib": "debug/macho",
+ "macho.DylibCmd": "debug/macho",
+ "macho.Dysymtab": "debug/macho",
+ "macho.DysymtabCmd": "debug/macho",
+ "macho.File": "debug/macho",
+ "macho.FileHeader": "debug/macho",
+ "macho.FormatError": "debug/macho",
+ "macho.Load": "debug/macho",
+ "macho.LoadBytes": "debug/macho",
+ "macho.LoadCmd": "debug/macho",
+ "macho.LoadCmdDylib": "debug/macho",
+ "macho.LoadCmdDylinker": "debug/macho",
+ "macho.LoadCmdDysymtab": "debug/macho",
+ "macho.LoadCmdSegment": "debug/macho",
+ "macho.LoadCmdSegment64": "debug/macho",
+ "macho.LoadCmdSymtab": "debug/macho",
+ "macho.LoadCmdThread": "debug/macho",
+ "macho.LoadCmdUnixThread": "debug/macho",
+ "macho.Magic32": "debug/macho",
+ "macho.Magic64": "debug/macho",
+ "macho.NewFile": "debug/macho",
+ "macho.Nlist32": "debug/macho",
+ "macho.Nlist64": "debug/macho",
+ "macho.Open": "debug/macho",
+ "macho.Regs386": "debug/macho",
+ "macho.RegsAMD64": "debug/macho",
+ "macho.Section": "debug/macho",
+ "macho.Section32": "debug/macho",
+ "macho.Section64": "debug/macho",
+ "macho.SectionHeader": "debug/macho",
+ "macho.Segment": "debug/macho",
+ "macho.Segment32": "debug/macho",
+ "macho.Segment64": "debug/macho",
+ "macho.SegmentHeader": "debug/macho",
+ "macho.Symbol": "debug/macho",
+ "macho.Symtab": "debug/macho",
+ "macho.SymtabCmd": "debug/macho",
+ "macho.Thread": "debug/macho",
+ "macho.Type": "debug/macho",
+ "macho.TypeExec": "debug/macho",
+ "macho.TypeObj": "debug/macho",
+ "mail.Address": "net/mail",
+ "mail.ErrHeaderNotPresent": "net/mail",
+ "mail.Header": "net/mail",
+ "mail.Message": "net/mail",
+ "mail.ParseAddress": "net/mail",
+ "mail.ParseAddressList": "net/mail",
+ "mail.ReadMessage": "net/mail",
+ "math.Abs": "math",
+ "math.Acos": "math",
+ "math.Acosh": "math",
+ "math.Asin": "math",
+ "math.Asinh": "math",
+ "math.Atan": "math",
+ "math.Atan2": "math",
+ "math.Atanh": "math",
+ "math.Cbrt": "math",
+ "math.Ceil": "math",
+ "math.Copysign": "math",
+ "math.Cos": "math",
+ "math.Cosh": "math",
+ "math.Dim": "math",
+ "math.E": "math",
+ "math.Erf": "math",
+ "math.Erfc": "math",
+ "math.Exp": "math",
+ "math.Exp2": "math",
+ "math.Expm1": "math",
+ "math.Float32bits": "math",
+ "math.Float32frombits": "math",
+ "math.Float64bits": "math",
+ "math.Float64frombits": "math",
+ "math.Floor": "math",
+ "math.Frexp": "math",
+ "math.Gamma": "math",
+ "math.Hypot": "math",
+ "math.Ilogb": "math",
+ "math.Inf": "math",
+ "math.IsInf": "math",
+ "math.IsNaN": "math",
+ "math.J0": "math",
+ "math.J1": "math",
+ "math.Jn": "math",
+ "math.Ldexp": "math",
+ "math.Lgamma": "math",
+ "math.Ln10": "math",
+ "math.Ln2": "math",
+ "math.Log": "math",
+ "math.Log10": "math",
+ "math.Log10E": "math",
+ "math.Log1p": "math",
+ "math.Log2": "math",
+ "math.Log2E": "math",
+ "math.Logb": "math",
+ "math.Max": "math",
+ "math.MaxFloat32": "math",
+ "math.MaxFloat64": "math",
+ "math.MaxInt16": "math",
+ "math.MaxInt32": "math",
+ "math.MaxInt64": "math",
+ "math.MaxInt8": "math",
+ "math.MaxUint16": "math",
+ "math.MaxUint32": "math",
+ "math.MaxUint64": "math",
+ "math.MaxUint8": "math",
+ "math.Min": "math",
+ "math.MinInt16": "math",
+ "math.MinInt32": "math",
+ "math.MinInt64": "math",
+ "math.MinInt8": "math",
+ "math.Mod": "math",
+ "math.Modf": "math",
+ "math.NaN": "math",
+ "math.Nextafter": "math",
+ "math.Phi": "math",
+ "math.Pi": "math",
+ "math.Pow": "math",
+ "math.Pow10": "math",
+ "math.Remainder": "math",
+ "math.Signbit": "math",
+ "math.Sin": "math",
+ "math.Sincos": "math",
+ "math.Sinh": "math",
+ "math.SmallestNonzeroFloat32": "math",
+ "math.SmallestNonzeroFloat64": "math",
+ "math.Sqrt": "math",
+ "math.Sqrt2": "math",
+ "math.SqrtE": "math",
+ "math.SqrtPhi": "math",
+ "math.SqrtPi": "math",
+ "math.Tan": "math",
+ "math.Tanh": "math",
+ "math.Trunc": "math",
+ "math.Y0": "math",
+ "math.Y1": "math",
+ "math.Yn": "math",
+ "md5.BlockSize": "crypto/md5",
+ "md5.New": "crypto/md5",
+ "md5.Size": "crypto/md5",
+ "md5.Sum": "crypto/md5",
+ "mime.AddExtensionType": "mime",
+ "mime.FormatMediaType": "mime",
+ "mime.ParseMediaType": "mime",
+ "mime.TypeByExtension": "mime",
+ "multipart.File": "mime/multipart",
+ "multipart.FileHeader": "mime/multipart",
+ "multipart.Form": "mime/multipart",
+ "multipart.NewReader": "mime/multipart",
+ "multipart.NewWriter": "mime/multipart",
+ "multipart.Part": "mime/multipart",
+ "multipart.Reader": "mime/multipart",
+ "multipart.Writer": "mime/multipart",
+ "net.Addr": "net",
+ "net.AddrError": "net",
+ "net.CIDRMask": "net",
+ "net.Conn": "net",
+ "net.DNSConfigError": "net",
+ "net.DNSError": "net",
+ "net.Dial": "net",
+ "net.DialIP": "net",
+ "net.DialTCP": "net",
+ "net.DialTimeout": "net",
+ "net.DialUDP": "net",
+ "net.DialUnix": "net",
+ "net.Dialer": "net",
+ "net.ErrWriteToConnected": "net",
+ "net.Error": "net",
+ "net.FileConn": "net",
+ "net.FileListener": "net",
+ "net.FilePacketConn": "net",
+ "net.FlagBroadcast": "net",
+ "net.FlagLoopback": "net",
+ "net.FlagMulticast": "net",
+ "net.FlagPointToPoint": "net",
+ "net.FlagUp": "net",
+ "net.Flags": "net",
+ "net.HardwareAddr": "net",
+ "net.IP": "net",
+ "net.IPAddr": "net",
+ "net.IPConn": "net",
+ "net.IPMask": "net",
+ "net.IPNet": "net",
+ "net.IPv4": "net",
+ "net.IPv4Mask": "net",
+ "net.IPv4allrouter": "net",
+ "net.IPv4allsys": "net",
+ "net.IPv4bcast": "net",
+ "net.IPv4len": "net",
+ "net.IPv4zero": "net",
+ "net.IPv6interfacelocalallnodes": "net",
+ "net.IPv6len": "net",
+ "net.IPv6linklocalallnodes": "net",
+ "net.IPv6linklocalallrouters": "net",
+ "net.IPv6loopback": "net",
+ "net.IPv6unspecified": "net",
+ "net.IPv6zero": "net",
+ "net.Interface": "net",
+ "net.InterfaceAddrs": "net",
+ "net.InterfaceByIndex": "net",
+ "net.InterfaceByName": "net",
+ "net.Interfaces": "net",
+ "net.InvalidAddrError": "net",
+ "net.JoinHostPort": "net",
+ "net.Listen": "net",
+ "net.ListenIP": "net",
+ "net.ListenMulticastUDP": "net",
+ "net.ListenPacket": "net",
+ "net.ListenTCP": "net",
+ "net.ListenUDP": "net",
+ "net.ListenUnix": "net",
+ "net.ListenUnixgram": "net",
+ "net.Listener": "net",
+ "net.LookupAddr": "net",
+ "net.LookupCNAME": "net",
+ "net.LookupHost": "net",
+ "net.LookupIP": "net",
+ "net.LookupMX": "net",
+ "net.LookupNS": "net",
+ "net.LookupPort": "net",
+ "net.LookupSRV": "net",
+ "net.LookupTXT": "net",
+ "net.MX": "net",
+ "net.NS": "net",
+ "net.OpError": "net",
+ "net.PacketConn": "net",
+ "net.ParseCIDR": "net",
+ "net.ParseError": "net",
+ "net.ParseIP": "net",
+ "net.ParseMAC": "net",
+ "net.Pipe": "net",
+ "net.ResolveIPAddr": "net",
+ "net.ResolveTCPAddr": "net",
+ "net.ResolveUDPAddr": "net",
+ "net.ResolveUnixAddr": "net",
+ "net.SRV": "net",
+ "net.SplitHostPort": "net",
+ "net.TCPAddr": "net",
+ "net.TCPConn": "net",
+ "net.TCPListener": "net",
+ "net.UDPAddr": "net",
+ "net.UDPConn": "net",
+ "net.UnixAddr": "net",
+ "net.UnixConn": "net",
+ "net.UnixListener": "net",
+ "net.UnknownNetworkError": "net",
+ "os.Args": "os",
+ "os.Chdir": "os",
+ "os.Chmod": "os",
+ "os.Chown": "os",
+ "os.Chtimes": "os",
+ "os.Clearenv": "os",
+ "os.Create": "os",
+ "os.DevNull": "os",
+ "os.Environ": "os",
+ "os.ErrExist": "os",
+ "os.ErrInvalid": "os",
+ "os.ErrNotExist": "os",
+ "os.ErrPermission": "os",
+ "os.Exit": "os",
+ "os.Expand": "os",
+ "os.ExpandEnv": "os",
+ "os.File": "os",
+ "os.FileInfo": "os",
+ "os.FileMode": "os",
+ "os.FindProcess": "os",
+ "os.Getegid": "os",
+ "os.Getenv": "os",
+ "os.Geteuid": "os",
+ "os.Getgid": "os",
+ "os.Getgroups": "os",
+ "os.Getpagesize": "os",
+ "os.Getpid": "os",
+ "os.Getppid": "os",
+ "os.Getuid": "os",
+ "os.Getwd": "os",
+ "os.Hostname": "os",
+ "os.Interrupt": "os",
+ "os.IsExist": "os",
+ "os.IsNotExist": "os",
+ "os.IsPathSeparator": "os",
+ "os.IsPermission": "os",
+ "os.Kill": "os",
+ "os.Lchown": "os",
+ "os.Link": "os",
+ "os.LinkError": "os",
+ "os.Lstat": "os",
+ "os.Mkdir": "os",
+ "os.MkdirAll": "os",
+ "os.ModeAppend": "os",
+ "os.ModeCharDevice": "os",
+ "os.ModeDevice": "os",
+ "os.ModeDir": "os",
+ "os.ModeExclusive": "os",
+ "os.ModeNamedPipe": "os",
+ "os.ModePerm": "os",
+ "os.ModeSetgid": "os",
+ "os.ModeSetuid": "os",
+ "os.ModeSocket": "os",
+ "os.ModeSticky": "os",
+ "os.ModeSymlink": "os",
+ "os.ModeTemporary": "os",
+ "os.ModeType": "os",
+ "os.NewFile": "os",
+ "os.NewSyscallError": "os",
+ "os.O_APPEND": "os",
+ "os.O_CREATE": "os",
+ "os.O_EXCL": "os",
+ "os.O_RDONLY": "os",
+ "os.O_RDWR": "os",
+ "os.O_SYNC": "os",
+ "os.O_TRUNC": "os",
+ "os.O_WRONLY": "os",
+ "os.Open": "os",
+ "os.OpenFile": "os",
+ "os.PathError": "os",
+ "os.PathListSeparator": "os",
+ "os.PathSeparator": "os",
+ "os.Pipe": "os",
+ "os.ProcAttr": "os",
+ "os.Process": "os",
+ "os.ProcessState": "os",
+ "os.Readlink": "os",
+ "os.Remove": "os",
+ "os.RemoveAll": "os",
+ "os.Rename": "os",
+ "os.SEEK_CUR": "os",
+ "os.SEEK_END": "os",
+ "os.SEEK_SET": "os",
+ "os.SameFile": "os",
+ "os.Setenv": "os",
+ "os.Signal": "os",
+ "os.StartProcess": "os",
+ "os.Stat": "os",
+ "os.Stderr": "os",
+ "os.Stdin": "os",
+ "os.Stdout": "os",
+ "os.Symlink": "os",
+ "os.SyscallError": "os",
+ "os.TempDir": "os",
+ "os.Truncate": "os",
+ "palette.Plan9": "image/color/palette",
+ "palette.WebSafe": "image/color/palette",
+ "parse.ActionNode": "text/template/parse",
+ "parse.BoolNode": "text/template/parse",
+ "parse.BranchNode": "text/template/parse",
+ "parse.ChainNode": "text/template/parse",
+ "parse.CommandNode": "text/template/parse",
+ "parse.DotNode": "text/template/parse",
+ "parse.FieldNode": "text/template/parse",
+ "parse.IdentifierNode": "text/template/parse",
+ "parse.IfNode": "text/template/parse",
+ "parse.IsEmptyTree": "text/template/parse",
+ "parse.ListNode": "text/template/parse",
+ "parse.New": "text/template/parse",
+ "parse.NewIdentifier": "text/template/parse",
+ "parse.NilNode": "text/template/parse",
+ "parse.Node": "text/template/parse",
+ "parse.NodeAction": "text/template/parse",
+ "parse.NodeBool": "text/template/parse",
+ "parse.NodeChain": "text/template/parse",
+ "parse.NodeCommand": "text/template/parse",
+ "parse.NodeDot": "text/template/parse",
+ "parse.NodeField": "text/template/parse",
+ "parse.NodeIdentifier": "text/template/parse",
+ "parse.NodeIf": "text/template/parse",
+ "parse.NodeList": "text/template/parse",
+ "parse.NodeNil": "text/template/parse",
+ "parse.NodeNumber": "text/template/parse",
+ "parse.NodePipe": "text/template/parse",
+ "parse.NodeRange": "text/template/parse",
+ "parse.NodeString": "text/template/parse",
+ "parse.NodeTemplate": "text/template/parse",
+ "parse.NodeText": "text/template/parse",
+ "parse.NodeType": "text/template/parse",
+ "parse.NodeVariable": "text/template/parse",
+ "parse.NodeWith": "text/template/parse",
+ "parse.NumberNode": "text/template/parse",
+ "parse.Parse": "text/template/parse",
+ "parse.PipeNode": "text/template/parse",
+ "parse.Pos": "text/template/parse",
+ "parse.RangeNode": "text/template/parse",
+ "parse.StringNode": "text/template/parse",
+ "parse.TemplateNode": "text/template/parse",
+ "parse.TextNode": "text/template/parse",
+ "parse.Tree": "text/template/parse",
+ "parse.VariableNode": "text/template/parse",
+ "parse.WithNode": "text/template/parse",
+ "parser.AllErrors": "go/parser",
+ "parser.DeclarationErrors": "go/parser",
+ "parser.ImportsOnly": "go/parser",
+ "parser.Mode": "go/parser",
+ "parser.PackageClauseOnly": "go/parser",
+ "parser.ParseComments": "go/parser",
+ "parser.ParseDir": "go/parser",
+ "parser.ParseExpr": "go/parser",
+ "parser.ParseFile": "go/parser",
+ "parser.SpuriousErrors": "go/parser",
+ "parser.Trace": "go/parser",
+ "path.Base": "path",
+ "path.Clean": "path",
+ "path.Dir": "path",
+ "path.ErrBadPattern": "path",
+ "path.Ext": "path",
+ "path.IsAbs": "path",
+ "path.Join": "path",
+ "path.Match": "path",
+ "path.Split": "path",
+ "pe.COFFSymbol": "debug/pe",
+ "pe.COFFSymbolSize": "debug/pe",
+ "pe.File": "debug/pe",
+ "pe.FileHeader": "debug/pe",
+ "pe.FormatError": "debug/pe",
+ "pe.IMAGE_FILE_MACHINE_AM33": "debug/pe",
+ "pe.IMAGE_FILE_MACHINE_AMD64": "debug/pe",
+ "pe.IMAGE_FILE_MACHINE_ARM": "debug/pe",
+ "pe.IMAGE_FILE_MACHINE_EBC": "debug/pe",
+ "pe.IMAGE_FILE_MACHINE_I386": "debug/pe",
+ "pe.IMAGE_FILE_MACHINE_IA64": "debug/pe",
+ "pe.IMAGE_FILE_MACHINE_M32R": "debug/pe",
+ "pe.IMAGE_FILE_MACHINE_MIPS16": "debug/pe",
+ "pe.IMAGE_FILE_MACHINE_MIPSFPU": "debug/pe",
+ "pe.IMAGE_FILE_MACHINE_MIPSFPU16": "debug/pe",
+ "pe.IMAGE_FILE_MACHINE_POWERPC": "debug/pe",
+ "pe.IMAGE_FILE_MACHINE_POWERPCFP": "debug/pe",
+ "pe.IMAGE_FILE_MACHINE_R4000": "debug/pe",
+ "pe.IMAGE_FILE_MACHINE_SH3": "debug/pe",
+ "pe.IMAGE_FILE_MACHINE_SH3DSP": "debug/pe",
+ "pe.IMAGE_FILE_MACHINE_SH4": "debug/pe",
+ "pe.IMAGE_FILE_MACHINE_SH5": "debug/pe",
+ "pe.IMAGE_FILE_MACHINE_THUMB": "debug/pe",
+ "pe.IMAGE_FILE_MACHINE_UNKNOWN": "debug/pe",
+ "pe.IMAGE_FILE_MACHINE_WCEMIPSV2": "debug/pe",
+ "pe.ImportDirectory": "debug/pe",
+ "pe.NewFile": "debug/pe",
+ "pe.Open": "debug/pe",
+ "pe.Section": "debug/pe",
+ "pe.SectionHeader": "debug/pe",
+ "pe.SectionHeader32": "debug/pe",
+ "pe.Symbol": "debug/pe",
+ "pem.Block": "encoding/pem",
+ "pem.Decode": "encoding/pem",
+ "pem.Encode": "encoding/pem",
+ "pem.EncodeToMemory": "encoding/pem",
+ "pkix.AlgorithmIdentifier": "crypto/x509/pkix",
+ "pkix.AttributeTypeAndValue": "crypto/x509/pkix",
+ "pkix.CertificateList": "crypto/x509/pkix",
+ "pkix.Extension": "crypto/x509/pkix",
+ "pkix.Name": "crypto/x509/pkix",
+ "pkix.RDNSequence": "crypto/x509/pkix",
+ "pkix.RelativeDistinguishedNameSET": "crypto/x509/pkix",
+ "pkix.RevokedCertificate": "crypto/x509/pkix",
+ "pkix.TBSCertificateList": "crypto/x509/pkix",
+ "png.Decode": "image/png",
+ "png.DecodeConfig": "image/png",
+ "png.Encode": "image/png",
+ "png.FormatError": "image/png",
+ "png.UnsupportedError": "image/png",
+ "pprof.Cmdline": "net/http/pprof",
+ "pprof.Handler": "net/http/pprof",
+ "pprof.Index": "net/http/pprof",
+ "pprof.Lookup": "runtime/pprof",
+ "pprof.NewProfile": "runtime/pprof",
+ // "pprof.Profile" is ambiguous
+ "pprof.Profiles": "runtime/pprof",
+ "pprof.StartCPUProfile": "runtime/pprof",
+ "pprof.StopCPUProfile": "runtime/pprof",
+ "pprof.Symbol": "net/http/pprof",
+ "pprof.WriteHeapProfile": "runtime/pprof",
+ "printer.CommentedNode": "go/printer",
+ "printer.Config": "go/printer",
+ "printer.Fprint": "go/printer",
+ "printer.Mode": "go/printer",
+ "printer.RawFormat": "go/printer",
+ "printer.SourcePos": "go/printer",
+ "printer.TabIndent": "go/printer",
+ "printer.UseSpaces": "go/printer",
+ "quick.Check": "testing/quick",
+ "quick.CheckEqual": "testing/quick",
+ "quick.CheckEqualError": "testing/quick",
+ "quick.CheckError": "testing/quick",
+ "quick.Config": "testing/quick",
+ "quick.Generator": "testing/quick",
+ "quick.SetupError": "testing/quick",
+ "quick.Value": "testing/quick",
+ "rand.ExpFloat64": "math/rand",
+ "rand.Float32": "math/rand",
+ "rand.Float64": "math/rand",
+ // "rand.Int" is ambiguous
+ "rand.Int31": "math/rand",
+ "rand.Int31n": "math/rand",
+ "rand.Int63": "math/rand",
+ "rand.Int63n": "math/rand",
+ "rand.Intn": "math/rand",
+ "rand.New": "math/rand",
+ "rand.NewSource": "math/rand",
+ "rand.NewZipf": "math/rand",
+ "rand.NormFloat64": "math/rand",
+ "rand.Perm": "math/rand",
+ "rand.Prime": "crypto/rand",
+ "rand.Rand": "math/rand",
+ "rand.Read": "crypto/rand",
+ "rand.Reader": "crypto/rand",
+ "rand.Seed": "math/rand",
+ "rand.Source": "math/rand",
+ "rand.Uint32": "math/rand",
+ "rand.Zipf": "math/rand",
+ "rc4.Cipher": "crypto/rc4",
+ "rc4.KeySizeError": "crypto/rc4",
+ "rc4.NewCipher": "crypto/rc4",
+ "reflect.Append": "reflect",
+ "reflect.AppendSlice": "reflect",
+ "reflect.Array": "reflect",
+ "reflect.Bool": "reflect",
+ "reflect.BothDir": "reflect",
+ "reflect.Chan": "reflect",
+ "reflect.ChanDir": "reflect",
+ "reflect.ChanOf": "reflect",
+ "reflect.Complex128": "reflect",
+ "reflect.Complex64": "reflect",
+ "reflect.Copy": "reflect",
+ "reflect.DeepEqual": "reflect",
+ "reflect.Float32": "reflect",
+ "reflect.Float64": "reflect",
+ "reflect.Func": "reflect",
+ "reflect.Indirect": "reflect",
+ "reflect.Int": "reflect",
+ "reflect.Int16": "reflect",
+ "reflect.Int32": "reflect",
+ "reflect.Int64": "reflect",
+ "reflect.Int8": "reflect",
+ "reflect.Interface": "reflect",
+ "reflect.Invalid": "reflect",
+ "reflect.Kind": "reflect",
+ "reflect.MakeChan": "reflect",
+ "reflect.MakeFunc": "reflect",
+ "reflect.MakeMap": "reflect",
+ "reflect.MakeSlice": "reflect",
+ "reflect.Map": "reflect",
+ "reflect.MapOf": "reflect",
+ "reflect.Method": "reflect",
+ "reflect.New": "reflect",
+ "reflect.NewAt": "reflect",
+ "reflect.Ptr": "reflect",
+ "reflect.PtrTo": "reflect",
+ "reflect.RecvDir": "reflect",
+ "reflect.Select": "reflect",
+ "reflect.SelectCase": "reflect",
+ "reflect.SelectDefault": "reflect",
+ "reflect.SelectDir": "reflect",
+ "reflect.SelectRecv": "reflect",
+ "reflect.SelectSend": "reflect",
+ "reflect.SendDir": "reflect",
+ "reflect.Slice": "reflect",
+ "reflect.SliceHeader": "reflect",
+ "reflect.SliceOf": "reflect",
+ "reflect.String": "reflect",
+ "reflect.StringHeader": "reflect",
+ "reflect.Struct": "reflect",
+ "reflect.StructField": "reflect",
+ "reflect.StructTag": "reflect",
+ "reflect.TypeOf": "reflect",
+ "reflect.Uint": "reflect",
+ "reflect.Uint16": "reflect",
+ "reflect.Uint32": "reflect",
+ "reflect.Uint64": "reflect",
+ "reflect.Uint8": "reflect",
+ "reflect.Uintptr": "reflect",
+ "reflect.UnsafePointer": "reflect",
+ "reflect.Value": "reflect",
+ "reflect.ValueError": "reflect",
+ "reflect.ValueOf": "reflect",
+ "reflect.Zero": "reflect",
+ "regexp.Compile": "regexp",
+ "regexp.CompilePOSIX": "regexp",
+ "regexp.Match": "regexp",
+ "regexp.MatchReader": "regexp",
+ "regexp.MatchString": "regexp",
+ "regexp.MustCompile": "regexp",
+ "regexp.MustCompilePOSIX": "regexp",
+ "regexp.QuoteMeta": "regexp",
+ "regexp.Regexp": "regexp",
+ "ring.New": "container/ring",
+ "ring.Ring": "container/ring",
+ "rpc.Accept": "net/rpc",
+ "rpc.Call": "net/rpc",
+ "rpc.Client": "net/rpc",
+ "rpc.ClientCodec": "net/rpc",
+ "rpc.DefaultDebugPath": "net/rpc",
+ "rpc.DefaultRPCPath": "net/rpc",
+ "rpc.DefaultServer": "net/rpc",
+ "rpc.Dial": "net/rpc",
+ "rpc.DialHTTP": "net/rpc",
+ "rpc.DialHTTPPath": "net/rpc",
+ "rpc.ErrShutdown": "net/rpc",
+ "rpc.HandleHTTP": "net/rpc",
+ "rpc.NewClient": "net/rpc",
+ "rpc.NewClientWithCodec": "net/rpc",
+ "rpc.NewServer": "net/rpc",
+ "rpc.Register": "net/rpc",
+ "rpc.RegisterName": "net/rpc",
+ "rpc.Request": "net/rpc",
+ "rpc.Response": "net/rpc",
+ "rpc.ServeCodec": "net/rpc",
+ "rpc.ServeConn": "net/rpc",
+ "rpc.ServeRequest": "net/rpc",
+ "rpc.Server": "net/rpc",
+ "rpc.ServerCodec": "net/rpc",
+ "rpc.ServerError": "net/rpc",
+ "rsa.CRTValue": "crypto/rsa",
+ "rsa.DecryptOAEP": "crypto/rsa",
+ "rsa.DecryptPKCS1v15": "crypto/rsa",
+ "rsa.DecryptPKCS1v15SessionKey": "crypto/rsa",
+ "rsa.EncryptOAEP": "crypto/rsa",
+ "rsa.EncryptPKCS1v15": "crypto/rsa",
+ "rsa.ErrDecryption": "crypto/rsa",
+ "rsa.ErrMessageTooLong": "crypto/rsa",
+ "rsa.ErrVerification": "crypto/rsa",
+ "rsa.GenerateKey": "crypto/rsa",
+ "rsa.GenerateMultiPrimeKey": "crypto/rsa",
+ "rsa.PSSOptions": "crypto/rsa",
+ "rsa.PSSSaltLengthAuto": "crypto/rsa",
+ "rsa.PSSSaltLengthEqualsHash": "crypto/rsa",
+ "rsa.PrecomputedValues": "crypto/rsa",
+ "rsa.PrivateKey": "crypto/rsa",
+ "rsa.PublicKey": "crypto/rsa",
+ "rsa.SignPKCS1v15": "crypto/rsa",
+ "rsa.SignPSS": "crypto/rsa",
+ "rsa.VerifyPKCS1v15": "crypto/rsa",
+ "rsa.VerifyPSS": "crypto/rsa",
+ "runtime.BlockProfile": "runtime",
+ "runtime.BlockProfileRecord": "runtime",
+ "runtime.Breakpoint": "runtime",
+ "runtime.CPUProfile": "runtime",
+ "runtime.Caller": "runtime",
+ "runtime.Callers": "runtime",
+ "runtime.Compiler": "runtime",
+ "runtime.Error": "runtime",
+ "runtime.Func": "runtime",
+ "runtime.FuncForPC": "runtime",
+ "runtime.GC": "runtime",
+ "runtime.GOARCH": "runtime",
+ "runtime.GOMAXPROCS": "runtime",
+ "runtime.GOOS": "runtime",
+ "runtime.GOROOT": "runtime",
+ "runtime.Goexit": "runtime",
+ "runtime.GoroutineProfile": "runtime",
+ "runtime.Gosched": "runtime",
+ "runtime.LockOSThread": "runtime",
+ "runtime.MemProfile": "runtime",
+ "runtime.MemProfileRate": "runtime",
+ "runtime.MemProfileRecord": "runtime",
+ "runtime.MemStats": "runtime",
+ "runtime.NumCPU": "runtime",
+ "runtime.NumCgoCall": "runtime",
+ "runtime.NumGoroutine": "runtime",
+ "runtime.ReadMemStats": "runtime",
+ "runtime.SetBlockProfileRate": "runtime",
+ "runtime.SetCPUProfileRate": "runtime",
+ "runtime.SetFinalizer": "runtime",
+ "runtime.Stack": "runtime",
+ "runtime.StackRecord": "runtime",
+ "runtime.ThreadCreateProfile": "runtime",
+ "runtime.TypeAssertionError": "runtime",
+ "runtime.UnlockOSThread": "runtime",
+ "runtime.Version": "runtime",
+ "scanner.Char": "text/scanner",
+ "scanner.Comment": "text/scanner",
+ "scanner.EOF": "text/scanner",
+ "scanner.Error": "go/scanner",
+ "scanner.ErrorHandler": "go/scanner",
+ "scanner.ErrorList": "go/scanner",
+ "scanner.Float": "text/scanner",
+ "scanner.GoTokens": "text/scanner",
+ "scanner.GoWhitespace": "text/scanner",
+ "scanner.Ident": "text/scanner",
+ "scanner.Int": "text/scanner",
+ "scanner.Mode": "go/scanner",
+ "scanner.Position": "text/scanner",
+ "scanner.PrintError": "go/scanner",
+ "scanner.RawString": "text/scanner",
+ "scanner.ScanChars": "text/scanner",
+ // "scanner.ScanComments" is ambiguous
+ "scanner.ScanFloats": "text/scanner",
+ "scanner.ScanIdents": "text/scanner",
+ "scanner.ScanInts": "text/scanner",
+ "scanner.ScanRawStrings": "text/scanner",
+ "scanner.ScanStrings": "text/scanner",
+ // "scanner.Scanner" is ambiguous
+ "scanner.SkipComments": "text/scanner",
+ "scanner.String": "text/scanner",
+ "scanner.TokenString": "text/scanner",
+ "sha1.BlockSize": "crypto/sha1",
+ "sha1.New": "crypto/sha1",
+ "sha1.Size": "crypto/sha1",
+ "sha1.Sum": "crypto/sha1",
+ "sha256.BlockSize": "crypto/sha256",
+ "sha256.New": "crypto/sha256",
+ "sha256.New224": "crypto/sha256",
+ "sha256.Size": "crypto/sha256",
+ "sha256.Size224": "crypto/sha256",
+ "sha256.Sum224": "crypto/sha256",
+ "sha256.Sum256": "crypto/sha256",
+ "sha512.BlockSize": "crypto/sha512",
+ "sha512.New": "crypto/sha512",
+ "sha512.New384": "crypto/sha512",
+ "sha512.Size": "crypto/sha512",
+ "sha512.Size384": "crypto/sha512",
+ "sha512.Sum384": "crypto/sha512",
+ "sha512.Sum512": "crypto/sha512",
+ "signal.Notify": "os/signal",
+ "signal.Stop": "os/signal",
+ "smtp.Auth": "net/smtp",
+ "smtp.CRAMMD5Auth": "net/smtp",
+ "smtp.Client": "net/smtp",
+ "smtp.Dial": "net/smtp",
+ "smtp.NewClient": "net/smtp",
+ "smtp.PlainAuth": "net/smtp",
+ "smtp.SendMail": "net/smtp",
+ "smtp.ServerInfo": "net/smtp",
+ "sort.Float64Slice": "sort",
+ "sort.Float64s": "sort",
+ "sort.Float64sAreSorted": "sort",
+ "sort.IntSlice": "sort",
+ "sort.Interface": "sort",
+ "sort.Ints": "sort",
+ "sort.IntsAreSorted": "sort",
+ "sort.IsSorted": "sort",
+ "sort.Reverse": "sort",
+ "sort.Search": "sort",
+ "sort.SearchFloat64s": "sort",
+ "sort.SearchInts": "sort",
+ "sort.SearchStrings": "sort",
+ "sort.Sort": "sort",
+ "sort.Stable": "sort",
+ "sort.StringSlice": "sort",
+ "sort.Strings": "sort",
+ "sort.StringsAreSorted": "sort",
+ "sql.DB": "database/sql",
+ "sql.ErrNoRows": "database/sql",
+ "sql.ErrTxDone": "database/sql",
+ "sql.NullBool": "database/sql",
+ "sql.NullFloat64": "database/sql",
+ "sql.NullInt64": "database/sql",
+ "sql.NullString": "database/sql",
+ "sql.Open": "database/sql",
+ "sql.RawBytes": "database/sql",
+ "sql.Register": "database/sql",
+ "sql.Result": "database/sql",
+ "sql.Row": "database/sql",
+ "sql.Rows": "database/sql",
+ "sql.Scanner": "database/sql",
+ "sql.Stmt": "database/sql",
+ "sql.Tx": "database/sql",
+ "strconv.AppendBool": "strconv",
+ "strconv.AppendFloat": "strconv",
+ "strconv.AppendInt": "strconv",
+ "strconv.AppendQuote": "strconv",
+ "strconv.AppendQuoteRune": "strconv",
+ "strconv.AppendQuoteRuneToASCII": "strconv",
+ "strconv.AppendQuoteToASCII": "strconv",
+ "strconv.AppendUint": "strconv",
+ "strconv.Atoi": "strconv",
+ "strconv.CanBackquote": "strconv",
+ "strconv.ErrRange": "strconv",
+ "strconv.ErrSyntax": "strconv",
+ "strconv.FormatBool": "strconv",
+ "strconv.FormatFloat": "strconv",
+ "strconv.FormatInt": "strconv",
+ "strconv.FormatUint": "strconv",
+ "strconv.IntSize": "strconv",
+ "strconv.IsPrint": "strconv",
+ "strconv.Itoa": "strconv",
+ "strconv.NumError": "strconv",
+ "strconv.ParseBool": "strconv",
+ "strconv.ParseFloat": "strconv",
+ "strconv.ParseInt": "strconv",
+ "strconv.ParseUint": "strconv",
+ "strconv.Quote": "strconv",
+ "strconv.QuoteRune": "strconv",
+ "strconv.QuoteRuneToASCII": "strconv",
+ "strconv.QuoteToASCII": "strconv",
+ "strconv.Unquote": "strconv",
+ "strconv.UnquoteChar": "strconv",
+ "strings.Contains": "strings",
+ "strings.ContainsAny": "strings",
+ "strings.ContainsRune": "strings",
+ "strings.Count": "strings",
+ "strings.EqualFold": "strings",
+ "strings.Fields": "strings",
+ "strings.FieldsFunc": "strings",
+ "strings.HasPrefix": "strings",
+ "strings.HasSuffix": "strings",
+ "strings.Index": "strings",
+ "strings.IndexAny": "strings",
+ "strings.IndexByte": "strings",
+ "strings.IndexFunc": "strings",
+ "strings.IndexRune": "strings",
+ "strings.Join": "strings",
+ "strings.LastIndex": "strings",
+ "strings.LastIndexAny": "strings",
+ "strings.LastIndexFunc": "strings",
+ "strings.Map": "strings",
+ "strings.NewReader": "strings",
+ "strings.NewReplacer": "strings",
+ "strings.Reader": "strings",
+ "strings.Repeat": "strings",
+ "strings.Replace": "strings",
+ "strings.Replacer": "strings",
+ "strings.Split": "strings",
+ "strings.SplitAfter": "strings",
+ "strings.SplitAfterN": "strings",
+ "strings.SplitN": "strings",
+ "strings.Title": "strings",
+ "strings.ToLower": "strings",
+ "strings.ToLowerSpecial": "strings",
+ "strings.ToTitle": "strings",
+ "strings.ToTitleSpecial": "strings",
+ "strings.ToUpper": "strings",
+ "strings.ToUpperSpecial": "strings",
+ "strings.Trim": "strings",
+ "strings.TrimFunc": "strings",
+ "strings.TrimLeft": "strings",
+ "strings.TrimLeftFunc": "strings",
+ "strings.TrimPrefix": "strings",
+ "strings.TrimRight": "strings",
+ "strings.TrimRightFunc": "strings",
+ "strings.TrimSpace": "strings",
+ "strings.TrimSuffix": "strings",
+ "subtle.ConstantTimeByteEq": "crypto/subtle",
+ "subtle.ConstantTimeCompare": "crypto/subtle",
+ "subtle.ConstantTimeCopy": "crypto/subtle",
+ "subtle.ConstantTimeEq": "crypto/subtle",
+ "subtle.ConstantTimeLessOrEq": "crypto/subtle",
+ "subtle.ConstantTimeSelect": "crypto/subtle",
+ "suffixarray.Index": "index/suffixarray",
+ "suffixarray.New": "index/suffixarray",
+ "sync.Cond": "sync",
+ "sync.Locker": "sync",
+ "sync.Mutex": "sync",
+ "sync.NewCond": "sync",
+ "sync.Once": "sync",
+ "sync.RWMutex": "sync",
+ "sync.WaitGroup": "sync",
+ "syntax.ClassNL": "regexp/syntax",
+ "syntax.Compile": "regexp/syntax",
+ "syntax.DotNL": "regexp/syntax",
+ "syntax.EmptyBeginLine": "regexp/syntax",
+ "syntax.EmptyBeginText": "regexp/syntax",
+ "syntax.EmptyEndLine": "regexp/syntax",
+ "syntax.EmptyEndText": "regexp/syntax",
+ "syntax.EmptyNoWordBoundary": "regexp/syntax",
+ "syntax.EmptyOp": "regexp/syntax",
+ "syntax.EmptyOpContext": "regexp/syntax",
+ "syntax.EmptyWordBoundary": "regexp/syntax",
+ "syntax.ErrInternalError": "regexp/syntax",
+ "syntax.ErrInvalidCharClass": "regexp/syntax",
+ "syntax.ErrInvalidCharRange": "regexp/syntax",
+ "syntax.ErrInvalidEscape": "regexp/syntax",
+ "syntax.ErrInvalidNamedCapture": "regexp/syntax",
+ "syntax.ErrInvalidPerlOp": "regexp/syntax",
+ "syntax.ErrInvalidRepeatOp": "regexp/syntax",
+ "syntax.ErrInvalidRepeatSize": "regexp/syntax",
+ "syntax.ErrInvalidUTF8": "regexp/syntax",
+ "syntax.ErrMissingBracket": "regexp/syntax",
+ "syntax.ErrMissingParen": "regexp/syntax",
+ "syntax.ErrMissingRepeatArgument": "regexp/syntax",
+ "syntax.ErrTrailingBackslash": "regexp/syntax",
+ "syntax.ErrUnexpectedParen": "regexp/syntax",
+ "syntax.Error": "regexp/syntax",
+ "syntax.ErrorCode": "regexp/syntax",
+ "syntax.Flags": "regexp/syntax",
+ "syntax.FoldCase": "regexp/syntax",
+ "syntax.Inst": "regexp/syntax",
+ "syntax.InstAlt": "regexp/syntax",
+ "syntax.InstAltMatch": "regexp/syntax",
+ "syntax.InstCapture": "regexp/syntax",
+ "syntax.InstEmptyWidth": "regexp/syntax",
+ "syntax.InstFail": "regexp/syntax",
+ "syntax.InstMatch": "regexp/syntax",
+ "syntax.InstNop": "regexp/syntax",
+ "syntax.InstOp": "regexp/syntax",
+ "syntax.InstRune": "regexp/syntax",
+ "syntax.InstRune1": "regexp/syntax",
+ "syntax.InstRuneAny": "regexp/syntax",
+ "syntax.InstRuneAnyNotNL": "regexp/syntax",
+ "syntax.IsWordChar": "regexp/syntax",
+ "syntax.Literal": "regexp/syntax",
+ "syntax.MatchNL": "regexp/syntax",
+ "syntax.NonGreedy": "regexp/syntax",
+ "syntax.OneLine": "regexp/syntax",
+ "syntax.Op": "regexp/syntax",
+ "syntax.OpAlternate": "regexp/syntax",
+ "syntax.OpAnyChar": "regexp/syntax",
+ "syntax.OpAnyCharNotNL": "regexp/syntax",
+ "syntax.OpBeginLine": "regexp/syntax",
+ "syntax.OpBeginText": "regexp/syntax",
+ "syntax.OpCapture": "regexp/syntax",
+ "syntax.OpCharClass": "regexp/syntax",
+ "syntax.OpConcat": "regexp/syntax",
+ "syntax.OpEmptyMatch": "regexp/syntax",
+ "syntax.OpEndLine": "regexp/syntax",
+ "syntax.OpEndText": "regexp/syntax",
+ "syntax.OpLiteral": "regexp/syntax",
+ "syntax.OpNoMatch": "regexp/syntax",
+ "syntax.OpNoWordBoundary": "regexp/syntax",
+ "syntax.OpPlus": "regexp/syntax",
+ "syntax.OpQuest": "regexp/syntax",
+ "syntax.OpRepeat": "regexp/syntax",
+ "syntax.OpStar": "regexp/syntax",
+ "syntax.OpWordBoundary": "regexp/syntax",
+ "syntax.POSIX": "regexp/syntax",
+ "syntax.Parse": "regexp/syntax",
+ "syntax.Perl": "regexp/syntax",
+ "syntax.PerlX": "regexp/syntax",
+ "syntax.Prog": "regexp/syntax",
+ "syntax.Regexp": "regexp/syntax",
+ "syntax.Simple": "regexp/syntax",
+ "syntax.UnicodeGroups": "regexp/syntax",
+ "syntax.WasDollar": "regexp/syntax",
+ "syscall.AF_ALG": "syscall",
+ "syscall.AF_APPLETALK": "syscall",
+ "syscall.AF_ARP": "syscall",
+ "syscall.AF_ASH": "syscall",
+ "syscall.AF_ATM": "syscall",
+ "syscall.AF_ATMPVC": "syscall",
+ "syscall.AF_ATMSVC": "syscall",
+ "syscall.AF_AX25": "syscall",
+ "syscall.AF_BLUETOOTH": "syscall",
+ "syscall.AF_BRIDGE": "syscall",
+ "syscall.AF_CAIF": "syscall",
+ "syscall.AF_CAN": "syscall",
+ "syscall.AF_CCITT": "syscall",
+ "syscall.AF_CHAOS": "syscall",
+ "syscall.AF_CNT": "syscall",
+ "syscall.AF_COIP": "syscall",
+ "syscall.AF_DATAKIT": "syscall",
+ "syscall.AF_DECnet": "syscall",
+ "syscall.AF_DLI": "syscall",
+ "syscall.AF_E164": "syscall",
+ "syscall.AF_ECMA": "syscall",
+ "syscall.AF_ECONET": "syscall",
+ "syscall.AF_ENCAP": "syscall",
+ "syscall.AF_FILE": "syscall",
+ "syscall.AF_HYLINK": "syscall",
+ "syscall.AF_IEEE80211": "syscall",
+ "syscall.AF_IEEE802154": "syscall",
+ "syscall.AF_IMPLINK": "syscall",
+ "syscall.AF_INET": "syscall",
+ "syscall.AF_INET6": "syscall",
+ "syscall.AF_IPX": "syscall",
+ "syscall.AF_IRDA": "syscall",
+ "syscall.AF_ISDN": "syscall",
+ "syscall.AF_ISO": "syscall",
+ "syscall.AF_IUCV": "syscall",
+ "syscall.AF_KEY": "syscall",
+ "syscall.AF_LAT": "syscall",
+ "syscall.AF_LINK": "syscall",
+ "syscall.AF_LLC": "syscall",
+ "syscall.AF_LOCAL": "syscall",
+ "syscall.AF_MAX": "syscall",
+ "syscall.AF_MPLS": "syscall",
+ "syscall.AF_NATM": "syscall",
+ "syscall.AF_NDRV": "syscall",
+ "syscall.AF_NETBEUI": "syscall",
+ "syscall.AF_NETBIOS": "syscall",
+ "syscall.AF_NETGRAPH": "syscall",
+ "syscall.AF_NETLINK": "syscall",
+ "syscall.AF_NETROM": "syscall",
+ "syscall.AF_NS": "syscall",
+ "syscall.AF_OROUTE": "syscall",
+ "syscall.AF_OSI": "syscall",
+ "syscall.AF_PACKET": "syscall",
+ "syscall.AF_PHONET": "syscall",
+ "syscall.AF_PPP": "syscall",
+ "syscall.AF_PPPOX": "syscall",
+ "syscall.AF_PUP": "syscall",
+ "syscall.AF_RDS": "syscall",
+ "syscall.AF_RESERVED_36": "syscall",
+ "syscall.AF_ROSE": "syscall",
+ "syscall.AF_ROUTE": "syscall",
+ "syscall.AF_RXRPC": "syscall",
+ "syscall.AF_SCLUSTER": "syscall",
+ "syscall.AF_SECURITY": "syscall",
+ "syscall.AF_SIP": "syscall",
+ "syscall.AF_SLOW": "syscall",
+ "syscall.AF_SNA": "syscall",
+ "syscall.AF_SYSTEM": "syscall",
+ "syscall.AF_TIPC": "syscall",
+ "syscall.AF_UNIX": "syscall",
+ "syscall.AF_UNSPEC": "syscall",
+ "syscall.AF_VENDOR00": "syscall",
+ "syscall.AF_VENDOR01": "syscall",
+ "syscall.AF_VENDOR02": "syscall",
+ "syscall.AF_VENDOR03": "syscall",
+ "syscall.AF_VENDOR04": "syscall",
+ "syscall.AF_VENDOR05": "syscall",
+ "syscall.AF_VENDOR06": "syscall",
+ "syscall.AF_VENDOR07": "syscall",
+ "syscall.AF_VENDOR08": "syscall",
+ "syscall.AF_VENDOR09": "syscall",
+ "syscall.AF_VENDOR10": "syscall",
+ "syscall.AF_VENDOR11": "syscall",
+ "syscall.AF_VENDOR12": "syscall",
+ "syscall.AF_VENDOR13": "syscall",
+ "syscall.AF_VENDOR14": "syscall",
+ "syscall.AF_VENDOR15": "syscall",
+ "syscall.AF_VENDOR16": "syscall",
+ "syscall.AF_VENDOR17": "syscall",
+ "syscall.AF_VENDOR18": "syscall",
+ "syscall.AF_VENDOR19": "syscall",
+ "syscall.AF_VENDOR20": "syscall",
+ "syscall.AF_VENDOR21": "syscall",
+ "syscall.AF_VENDOR22": "syscall",
+ "syscall.AF_VENDOR23": "syscall",
+ "syscall.AF_VENDOR24": "syscall",
+ "syscall.AF_VENDOR25": "syscall",
+ "syscall.AF_VENDOR26": "syscall",
+ "syscall.AF_VENDOR27": "syscall",
+ "syscall.AF_VENDOR28": "syscall",
+ "syscall.AF_VENDOR29": "syscall",
+ "syscall.AF_VENDOR30": "syscall",
+ "syscall.AF_VENDOR31": "syscall",
+ "syscall.AF_VENDOR32": "syscall",
+ "syscall.AF_VENDOR33": "syscall",
+ "syscall.AF_VENDOR34": "syscall",
+ "syscall.AF_VENDOR35": "syscall",
+ "syscall.AF_VENDOR36": "syscall",
+ "syscall.AF_VENDOR37": "syscall",
+ "syscall.AF_VENDOR38": "syscall",
+ "syscall.AF_VENDOR39": "syscall",
+ "syscall.AF_VENDOR40": "syscall",
+ "syscall.AF_VENDOR41": "syscall",
+ "syscall.AF_VENDOR42": "syscall",
+ "syscall.AF_VENDOR43": "syscall",
+ "syscall.AF_VENDOR44": "syscall",
+ "syscall.AF_VENDOR45": "syscall",
+ "syscall.AF_VENDOR46": "syscall",
+ "syscall.AF_VENDOR47": "syscall",
+ "syscall.AF_WANPIPE": "syscall",
+ "syscall.AF_X25": "syscall",
+ "syscall.AI_CANONNAME": "syscall",
+ "syscall.AI_NUMERICHOST": "syscall",
+ "syscall.AI_PASSIVE": "syscall",
+ "syscall.APPLICATION_ERROR": "syscall",
+ "syscall.ARPHRD_ADAPT": "syscall",
+ "syscall.ARPHRD_APPLETLK": "syscall",
+ "syscall.ARPHRD_ARCNET": "syscall",
+ "syscall.ARPHRD_ASH": "syscall",
+ "syscall.ARPHRD_ATM": "syscall",
+ "syscall.ARPHRD_AX25": "syscall",
+ "syscall.ARPHRD_BIF": "syscall",
+ "syscall.ARPHRD_CHAOS": "syscall",
+ "syscall.ARPHRD_CISCO": "syscall",
+ "syscall.ARPHRD_CSLIP": "syscall",
+ "syscall.ARPHRD_CSLIP6": "syscall",
+ "syscall.ARPHRD_DDCMP": "syscall",
+ "syscall.ARPHRD_DLCI": "syscall",
+ "syscall.ARPHRD_ECONET": "syscall",
+ "syscall.ARPHRD_EETHER": "syscall",
+ "syscall.ARPHRD_ETHER": "syscall",
+ "syscall.ARPHRD_EUI64": "syscall",
+ "syscall.ARPHRD_FCAL": "syscall",
+ "syscall.ARPHRD_FCFABRIC": "syscall",
+ "syscall.ARPHRD_FCPL": "syscall",
+ "syscall.ARPHRD_FCPP": "syscall",
+ "syscall.ARPHRD_FDDI": "syscall",
+ "syscall.ARPHRD_FRAD": "syscall",
+ "syscall.ARPHRD_FRELAY": "syscall",
+ "syscall.ARPHRD_HDLC": "syscall",
+ "syscall.ARPHRD_HIPPI": "syscall",
+ "syscall.ARPHRD_HWX25": "syscall",
+ "syscall.ARPHRD_IEEE1394": "syscall",
+ "syscall.ARPHRD_IEEE802": "syscall",
+ "syscall.ARPHRD_IEEE80211": "syscall",
+ "syscall.ARPHRD_IEEE80211_PRISM": "syscall",
+ "syscall.ARPHRD_IEEE80211_RADIOTAP": "syscall",
+ "syscall.ARPHRD_IEEE802154": "syscall",
+ "syscall.ARPHRD_IEEE802154_PHY": "syscall",
+ "syscall.ARPHRD_IEEE802_TR": "syscall",
+ "syscall.ARPHRD_INFINIBAND": "syscall",
+ "syscall.ARPHRD_IPDDP": "syscall",
+ "syscall.ARPHRD_IPGRE": "syscall",
+ "syscall.ARPHRD_IRDA": "syscall",
+ "syscall.ARPHRD_LAPB": "syscall",
+ "syscall.ARPHRD_LOCALTLK": "syscall",
+ "syscall.ARPHRD_LOOPBACK": "syscall",
+ "syscall.ARPHRD_METRICOM": "syscall",
+ "syscall.ARPHRD_NETROM": "syscall",
+ "syscall.ARPHRD_NONE": "syscall",
+ "syscall.ARPHRD_PIMREG": "syscall",
+ "syscall.ARPHRD_PPP": "syscall",
+ "syscall.ARPHRD_PRONET": "syscall",
+ "syscall.ARPHRD_RAWHDLC": "syscall",
+ "syscall.ARPHRD_ROSE": "syscall",
+ "syscall.ARPHRD_RSRVD": "syscall",
+ "syscall.ARPHRD_SIT": "syscall",
+ "syscall.ARPHRD_SKIP": "syscall",
+ "syscall.ARPHRD_SLIP": "syscall",
+ "syscall.ARPHRD_SLIP6": "syscall",
+ "syscall.ARPHRD_STRIP": "syscall",
+ "syscall.ARPHRD_TUNNEL": "syscall",
+ "syscall.ARPHRD_TUNNEL6": "syscall",
+ "syscall.ARPHRD_VOID": "syscall",
+ "syscall.ARPHRD_X25": "syscall",
+ "syscall.AUTHTYPE_CLIENT": "syscall",
+ "syscall.AUTHTYPE_SERVER": "syscall",
+ "syscall.Accept": "syscall",
+ "syscall.Accept4": "syscall",
+ "syscall.AcceptEx": "syscall",
+ "syscall.Access": "syscall",
+ "syscall.Acct": "syscall",
+ "syscall.AddrinfoW": "syscall",
+ "syscall.Adjtime": "syscall",
+ "syscall.Adjtimex": "syscall",
+ "syscall.AttachLsf": "syscall",
+ "syscall.B0": "syscall",
+ "syscall.B1000000": "syscall",
+ "syscall.B110": "syscall",
+ "syscall.B115200": "syscall",
+ "syscall.B1152000": "syscall",
+ "syscall.B1200": "syscall",
+ "syscall.B134": "syscall",
+ "syscall.B14400": "syscall",
+ "syscall.B150": "syscall",
+ "syscall.B1500000": "syscall",
+ "syscall.B1800": "syscall",
+ "syscall.B19200": "syscall",
+ "syscall.B200": "syscall",
+ "syscall.B2000000": "syscall",
+ "syscall.B230400": "syscall",
+ "syscall.B2400": "syscall",
+ "syscall.B2500000": "syscall",
+ "syscall.B28800": "syscall",
+ "syscall.B300": "syscall",
+ "syscall.B3000000": "syscall",
+ "syscall.B3500000": "syscall",
+ "syscall.B38400": "syscall",
+ "syscall.B4000000": "syscall",
+ "syscall.B460800": "syscall",
+ "syscall.B4800": "syscall",
+ "syscall.B50": "syscall",
+ "syscall.B500000": "syscall",
+ "syscall.B57600": "syscall",
+ "syscall.B576000": "syscall",
+ "syscall.B600": "syscall",
+ "syscall.B7200": "syscall",
+ "syscall.B75": "syscall",
+ "syscall.B76800": "syscall",
+ "syscall.B921600": "syscall",
+ "syscall.B9600": "syscall",
+ "syscall.BASE_PROTOCOL": "syscall",
+ "syscall.BIOCFEEDBACK": "syscall",
+ "syscall.BIOCFLUSH": "syscall",
+ "syscall.BIOCGBLEN": "syscall",
+ "syscall.BIOCGDIRECTION": "syscall",
+ "syscall.BIOCGDIRFILT": "syscall",
+ "syscall.BIOCGDLT": "syscall",
+ "syscall.BIOCGDLTLIST": "syscall",
+ "syscall.BIOCGETBUFMODE": "syscall",
+ "syscall.BIOCGETIF": "syscall",
+ "syscall.BIOCGETZMAX": "syscall",
+ "syscall.BIOCGFEEDBACK": "syscall",
+ "syscall.BIOCGFILDROP": "syscall",
+ "syscall.BIOCGHDRCMPLT": "syscall",
+ "syscall.BIOCGRSIG": "syscall",
+ "syscall.BIOCGRTIMEOUT": "syscall",
+ "syscall.BIOCGSEESENT": "syscall",
+ "syscall.BIOCGSTATS": "syscall",
+ "syscall.BIOCGSTATSOLD": "syscall",
+ "syscall.BIOCGTSTAMP": "syscall",
+ "syscall.BIOCIMMEDIATE": "syscall",
+ "syscall.BIOCLOCK": "syscall",
+ "syscall.BIOCPROMISC": "syscall",
+ "syscall.BIOCROTZBUF": "syscall",
+ "syscall.BIOCSBLEN": "syscall",
+ "syscall.BIOCSDIRECTION": "syscall",
+ "syscall.BIOCSDIRFILT": "syscall",
+ "syscall.BIOCSDLT": "syscall",
+ "syscall.BIOCSETBUFMODE": "syscall",
+ "syscall.BIOCSETF": "syscall",
+ "syscall.BIOCSETFNR": "syscall",
+ "syscall.BIOCSETIF": "syscall",
+ "syscall.BIOCSETWF": "syscall",
+ "syscall.BIOCSETZBUF": "syscall",
+ "syscall.BIOCSFEEDBACK": "syscall",
+ "syscall.BIOCSFILDROP": "syscall",
+ "syscall.BIOCSHDRCMPLT": "syscall",
+ "syscall.BIOCSRSIG": "syscall",
+ "syscall.BIOCSRTIMEOUT": "syscall",
+ "syscall.BIOCSSEESENT": "syscall",
+ "syscall.BIOCSTCPF": "syscall",
+ "syscall.BIOCSTSTAMP": "syscall",
+ "syscall.BIOCSUDPF": "syscall",
+ "syscall.BIOCVERSION": "syscall",
+ "syscall.BPF_A": "syscall",
+ "syscall.BPF_ABS": "syscall",
+ "syscall.BPF_ADD": "syscall",
+ "syscall.BPF_ALIGNMENT": "syscall",
+ "syscall.BPF_ALIGNMENT32": "syscall",
+ "syscall.BPF_ALU": "syscall",
+ "syscall.BPF_AND": "syscall",
+ "syscall.BPF_B": "syscall",
+ "syscall.BPF_BUFMODE_BUFFER": "syscall",
+ "syscall.BPF_BUFMODE_ZBUF": "syscall",
+ "syscall.BPF_DFLTBUFSIZE": "syscall",
+ "syscall.BPF_DIRECTION_IN": "syscall",
+ "syscall.BPF_DIRECTION_OUT": "syscall",
+ "syscall.BPF_DIV": "syscall",
+ "syscall.BPF_H": "syscall",
+ "syscall.BPF_IMM": "syscall",
+ "syscall.BPF_IND": "syscall",
+ "syscall.BPF_JA": "syscall",
+ "syscall.BPF_JEQ": "syscall",
+ "syscall.BPF_JGE": "syscall",
+ "syscall.BPF_JGT": "syscall",
+ "syscall.BPF_JMP": "syscall",
+ "syscall.BPF_JSET": "syscall",
+ "syscall.BPF_K": "syscall",
+ "syscall.BPF_LD": "syscall",
+ "syscall.BPF_LDX": "syscall",
+ "syscall.BPF_LEN": "syscall",
+ "syscall.BPF_LSH": "syscall",
+ "syscall.BPF_MAJOR_VERSION": "syscall",
+ "syscall.BPF_MAXBUFSIZE": "syscall",
+ "syscall.BPF_MAXINSNS": "syscall",
+ "syscall.BPF_MEM": "syscall",
+ "syscall.BPF_MEMWORDS": "syscall",
+ "syscall.BPF_MINBUFSIZE": "syscall",
+ "syscall.BPF_MINOR_VERSION": "syscall",
+ "syscall.BPF_MISC": "syscall",
+ "syscall.BPF_MSH": "syscall",
+ "syscall.BPF_MUL": "syscall",
+ "syscall.BPF_NEG": "syscall",
+ "syscall.BPF_OR": "syscall",
+ "syscall.BPF_RELEASE": "syscall",
+ "syscall.BPF_RET": "syscall",
+ "syscall.BPF_RSH": "syscall",
+ "syscall.BPF_ST": "syscall",
+ "syscall.BPF_STX": "syscall",
+ "syscall.BPF_SUB": "syscall",
+ "syscall.BPF_TAX": "syscall",
+ "syscall.BPF_TXA": "syscall",
+ "syscall.BPF_T_BINTIME": "syscall",
+ "syscall.BPF_T_BINTIME_FAST": "syscall",
+ "syscall.BPF_T_BINTIME_MONOTONIC": "syscall",
+ "syscall.BPF_T_BINTIME_MONOTONIC_FAST": "syscall",
+ "syscall.BPF_T_FAST": "syscall",
+ "syscall.BPF_T_FLAG_MASK": "syscall",
+ "syscall.BPF_T_FORMAT_MASK": "syscall",
+ "syscall.BPF_T_MICROTIME": "syscall",
+ "syscall.BPF_T_MICROTIME_FAST": "syscall",
+ "syscall.BPF_T_MICROTIME_MONOTONIC": "syscall",
+ "syscall.BPF_T_MICROTIME_MONOTONIC_FAST": "syscall",
+ "syscall.BPF_T_MONOTONIC": "syscall",
+ "syscall.BPF_T_MONOTONIC_FAST": "syscall",
+ "syscall.BPF_T_NANOTIME": "syscall",
+ "syscall.BPF_T_NANOTIME_FAST": "syscall",
+ "syscall.BPF_T_NANOTIME_MONOTONIC": "syscall",
+ "syscall.BPF_T_NANOTIME_MONOTONIC_FAST": "syscall",
+ "syscall.BPF_T_NONE": "syscall",
+ "syscall.BPF_T_NORMAL": "syscall",
+ "syscall.BPF_W": "syscall",
+ "syscall.BPF_X": "syscall",
+ "syscall.BRKINT": "syscall",
+ "syscall.Bind": "syscall",
+ "syscall.BindToDevice": "syscall",
+ "syscall.BpfBuflen": "syscall",
+ "syscall.BpfDatalink": "syscall",
+ "syscall.BpfHdr": "syscall",
+ "syscall.BpfHeadercmpl": "syscall",
+ "syscall.BpfInsn": "syscall",
+ "syscall.BpfInterface": "syscall",
+ "syscall.BpfJump": "syscall",
+ "syscall.BpfProgram": "syscall",
+ "syscall.BpfStat": "syscall",
+ "syscall.BpfStats": "syscall",
+ "syscall.BpfStmt": "syscall",
+ "syscall.BpfTimeout": "syscall",
+ "syscall.BpfTimeval": "syscall",
+ "syscall.BpfVersion": "syscall",
+ "syscall.BpfZbuf": "syscall",
+ "syscall.BpfZbufHeader": "syscall",
+ "syscall.ByHandleFileInformation": "syscall",
+ "syscall.BytePtrFromString": "syscall",
+ "syscall.ByteSliceFromString": "syscall",
+ "syscall.CCR0_FLUSH": "syscall",
+ "syscall.CERT_CHAIN_POLICY_AUTHENTICODE": "syscall",
+ "syscall.CERT_CHAIN_POLICY_AUTHENTICODE_TS": "syscall",
+ "syscall.CERT_CHAIN_POLICY_BASE": "syscall",
+ "syscall.CERT_CHAIN_POLICY_BASIC_CONSTRAINTS": "syscall",
+ "syscall.CERT_CHAIN_POLICY_EV": "syscall",
+ "syscall.CERT_CHAIN_POLICY_MICROSOFT_ROOT": "syscall",
+ "syscall.CERT_CHAIN_POLICY_NT_AUTH": "syscall",
+ "syscall.CERT_CHAIN_POLICY_SSL": "syscall",
+ "syscall.CERT_E_CN_NO_MATCH": "syscall",
+ "syscall.CERT_E_EXPIRED": "syscall",
+ "syscall.CERT_E_PURPOSE": "syscall",
+ "syscall.CERT_E_ROLE": "syscall",
+ "syscall.CERT_E_UNTRUSTEDROOT": "syscall",
+ "syscall.CERT_STORE_ADD_ALWAYS": "syscall",
+ "syscall.CERT_STORE_DEFER_CLOSE_UNTIL_LAST_FREE_FLAG": "syscall",
+ "syscall.CERT_STORE_PROV_MEMORY": "syscall",
+ "syscall.CERT_TRUST_HAS_EXCLUDED_NAME_CONSTRAINT": "syscall",
+ "syscall.CERT_TRUST_HAS_NOT_DEFINED_NAME_CONSTRAINT": "syscall",
+ "syscall.CERT_TRUST_HAS_NOT_PERMITTED_NAME_CONSTRAINT": "syscall",
+ "syscall.CERT_TRUST_HAS_NOT_SUPPORTED_CRITICAL_EXT": "syscall",
+ "syscall.CERT_TRUST_HAS_NOT_SUPPORTED_NAME_CONSTRAINT": "syscall",
+ "syscall.CERT_TRUST_INVALID_BASIC_CONSTRAINTS": "syscall",
+ "syscall.CERT_TRUST_INVALID_EXTENSION": "syscall",
+ "syscall.CERT_TRUST_INVALID_NAME_CONSTRAINTS": "syscall",
+ "syscall.CERT_TRUST_INVALID_POLICY_CONSTRAINTS": "syscall",
+ "syscall.CERT_TRUST_IS_CYCLIC": "syscall",
+ "syscall.CERT_TRUST_IS_EXPLICIT_DISTRUST": "syscall",
+ "syscall.CERT_TRUST_IS_NOT_SIGNATURE_VALID": "syscall",
+ "syscall.CERT_TRUST_IS_NOT_TIME_VALID": "syscall",
+ "syscall.CERT_TRUST_IS_NOT_VALID_FOR_USAGE": "syscall",
+ "syscall.CERT_TRUST_IS_OFFLINE_REVOCATION": "syscall",
+ "syscall.CERT_TRUST_IS_REVOKED": "syscall",
+ "syscall.CERT_TRUST_IS_UNTRUSTED_ROOT": "syscall",
+ "syscall.CERT_TRUST_NO_ERROR": "syscall",
+ "syscall.CERT_TRUST_NO_ISSUANCE_CHAIN_POLICY": "syscall",
+ "syscall.CERT_TRUST_REVOCATION_STATUS_UNKNOWN": "syscall",
+ "syscall.CFLUSH": "syscall",
+ "syscall.CLOCAL": "syscall",
+ "syscall.CLONE_CHILD_CLEARTID": "syscall",
+ "syscall.CLONE_CHILD_SETTID": "syscall",
+ "syscall.CLONE_DETACHED": "syscall",
+ "syscall.CLONE_FILES": "syscall",
+ "syscall.CLONE_FS": "syscall",
+ "syscall.CLONE_IO": "syscall",
+ "syscall.CLONE_NEWIPC": "syscall",
+ "syscall.CLONE_NEWNET": "syscall",
+ "syscall.CLONE_NEWNS": "syscall",
+ "syscall.CLONE_NEWPID": "syscall",
+ "syscall.CLONE_NEWUSER": "syscall",
+ "syscall.CLONE_NEWUTS": "syscall",
+ "syscall.CLONE_PARENT": "syscall",
+ "syscall.CLONE_PARENT_SETTID": "syscall",
+ "syscall.CLONE_PTRACE": "syscall",
+ "syscall.CLONE_SETTLS": "syscall",
+ "syscall.CLONE_SIGHAND": "syscall",
+ "syscall.CLONE_SYSVSEM": "syscall",
+ "syscall.CLONE_THREAD": "syscall",
+ "syscall.CLONE_UNTRACED": "syscall",
+ "syscall.CLONE_VFORK": "syscall",
+ "syscall.CLONE_VM": "syscall",
+ "syscall.CPUID_CFLUSH": "syscall",
+ "syscall.CREAD": "syscall",
+ "syscall.CREATE_ALWAYS": "syscall",
+ "syscall.CREATE_NEW": "syscall",
+ "syscall.CREATE_NEW_PROCESS_GROUP": "syscall",
+ "syscall.CREATE_UNICODE_ENVIRONMENT": "syscall",
+ "syscall.CRYPT_DEFAULT_CONTAINER_OPTIONAL": "syscall",
+ "syscall.CRYPT_DELETEKEYSET": "syscall",
+ "syscall.CRYPT_MACHINE_KEYSET": "syscall",
+ "syscall.CRYPT_NEWKEYSET": "syscall",
+ "syscall.CRYPT_SILENT": "syscall",
+ "syscall.CRYPT_VERIFYCONTEXT": "syscall",
+ "syscall.CS5": "syscall",
+ "syscall.CS6": "syscall",
+ "syscall.CS7": "syscall",
+ "syscall.CS8": "syscall",
+ "syscall.CSIZE": "syscall",
+ "syscall.CSTART": "syscall",
+ "syscall.CSTATUS": "syscall",
+ "syscall.CSTOP": "syscall",
+ "syscall.CSTOPB": "syscall",
+ "syscall.CSUSP": "syscall",
+ "syscall.CTL_MAXNAME": "syscall",
+ "syscall.CTL_NET": "syscall",
+ "syscall.CTL_QUERY": "syscall",
+ "syscall.CTRL_BREAK_EVENT": "syscall",
+ "syscall.CTRL_C_EVENT": "syscall",
+ "syscall.CancelIo": "syscall",
+ "syscall.CancelIoEx": "syscall",
+ "syscall.CertAddCertificateContextToStore": "syscall",
+ "syscall.CertChainContext": "syscall",
+ "syscall.CertChainElement": "syscall",
+ "syscall.CertChainPara": "syscall",
+ "syscall.CertChainPolicyPara": "syscall",
+ "syscall.CertChainPolicyStatus": "syscall",
+ "syscall.CertCloseStore": "syscall",
+ "syscall.CertContext": "syscall",
+ "syscall.CertCreateCertificateContext": "syscall",
+ "syscall.CertEnhKeyUsage": "syscall",
+ "syscall.CertEnumCertificatesInStore": "syscall",
+ "syscall.CertFreeCertificateChain": "syscall",
+ "syscall.CertFreeCertificateContext": "syscall",
+ "syscall.CertGetCertificateChain": "syscall",
+ "syscall.CertOpenStore": "syscall",
+ "syscall.CertOpenSystemStore": "syscall",
+ "syscall.CertRevocationInfo": "syscall",
+ "syscall.CertSimpleChain": "syscall",
+ "syscall.CertTrustStatus": "syscall",
+ "syscall.CertUsageMatch": "syscall",
+ "syscall.CertVerifyCertificateChainPolicy": "syscall",
+ "syscall.Chdir": "syscall",
+ "syscall.CheckBpfVersion": "syscall",
+ "syscall.Chflags": "syscall",
+ "syscall.Chmod": "syscall",
+ "syscall.Chown": "syscall",
+ "syscall.Chroot": "syscall",
+ "syscall.Clearenv": "syscall",
+ "syscall.Close": "syscall",
+ "syscall.CloseHandle": "syscall",
+ "syscall.CloseOnExec": "syscall",
+ "syscall.Closesocket": "syscall",
+ "syscall.CmsgLen": "syscall",
+ "syscall.CmsgSpace": "syscall",
+ "syscall.Cmsghdr": "syscall",
+ "syscall.CommandLineToArgv": "syscall",
+ "syscall.ComputerName": "syscall",
+ "syscall.Connect": "syscall",
+ "syscall.ConnectEx": "syscall",
+ "syscall.ConvertSidToStringSid": "syscall",
+ "syscall.ConvertStringSidToSid": "syscall",
+ "syscall.CopySid": "syscall",
+ "syscall.Creat": "syscall",
+ "syscall.CreateDirectory": "syscall",
+ "syscall.CreateFile": "syscall",
+ "syscall.CreateFileMapping": "syscall",
+ "syscall.CreateIoCompletionPort": "syscall",
+ "syscall.CreatePipe": "syscall",
+ "syscall.CreateProcess": "syscall",
+ "syscall.Credential": "syscall",
+ "syscall.CryptAcquireContext": "syscall",
+ "syscall.CryptGenRandom": "syscall",
+ "syscall.CryptReleaseContext": "syscall",
+ "syscall.DIOCBSFLUSH": "syscall",
+ "syscall.DIOCOSFPFLUSH": "syscall",
+ "syscall.DLL": "syscall",
+ "syscall.DLLError": "syscall",
+ "syscall.DLT_A429": "syscall",
+ "syscall.DLT_A653_ICM": "syscall",
+ "syscall.DLT_AIRONET_HEADER": "syscall",
+ "syscall.DLT_AOS": "syscall",
+ "syscall.DLT_APPLE_IP_OVER_IEEE1394": "syscall",
+ "syscall.DLT_ARCNET": "syscall",
+ "syscall.DLT_ARCNET_LINUX": "syscall",
+ "syscall.DLT_ATM_CLIP": "syscall",
+ "syscall.DLT_ATM_RFC1483": "syscall",
+ "syscall.DLT_AURORA": "syscall",
+ "syscall.DLT_AX25": "syscall",
+ "syscall.DLT_AX25_KISS": "syscall",
+ "syscall.DLT_BACNET_MS_TP": "syscall",
+ "syscall.DLT_BLUETOOTH_HCI_H4": "syscall",
+ "syscall.DLT_BLUETOOTH_HCI_H4_WITH_PHDR": "syscall",
+ "syscall.DLT_CAN20B": "syscall",
+ "syscall.DLT_CAN_SOCKETCAN": "syscall",
+ "syscall.DLT_CHAOS": "syscall",
+ "syscall.DLT_CHDLC": "syscall",
+ "syscall.DLT_CISCO_IOS": "syscall",
+ "syscall.DLT_C_HDLC": "syscall",
+ "syscall.DLT_C_HDLC_WITH_DIR": "syscall",
+ "syscall.DLT_DBUS": "syscall",
+ "syscall.DLT_DECT": "syscall",
+ "syscall.DLT_DOCSIS": "syscall",
+ "syscall.DLT_DVB_CI": "syscall",
+ "syscall.DLT_ECONET": "syscall",
+ "syscall.DLT_EN10MB": "syscall",
+ "syscall.DLT_EN3MB": "syscall",
+ "syscall.DLT_ENC": "syscall",
+ "syscall.DLT_ERF": "syscall",
+ "syscall.DLT_ERF_ETH": "syscall",
+ "syscall.DLT_ERF_POS": "syscall",
+ "syscall.DLT_FC_2": "syscall",
+ "syscall.DLT_FC_2_WITH_FRAME_DELIMS": "syscall",
+ "syscall.DLT_FDDI": "syscall",
+ "syscall.DLT_FLEXRAY": "syscall",
+ "syscall.DLT_FRELAY": "syscall",
+ "syscall.DLT_FRELAY_WITH_DIR": "syscall",
+ "syscall.DLT_GCOM_SERIAL": "syscall",
+ "syscall.DLT_GCOM_T1E1": "syscall",
+ "syscall.DLT_GPF_F": "syscall",
+ "syscall.DLT_GPF_T": "syscall",
+ "syscall.DLT_GPRS_LLC": "syscall",
+ "syscall.DLT_GSMTAP_ABIS": "syscall",
+ "syscall.DLT_GSMTAP_UM": "syscall",
+ "syscall.DLT_HDLC": "syscall",
+ "syscall.DLT_HHDLC": "syscall",
+ "syscall.DLT_HIPPI": "syscall",
+ "syscall.DLT_IBM_SN": "syscall",
+ "syscall.DLT_IBM_SP": "syscall",
+ "syscall.DLT_IEEE802": "syscall",
+ "syscall.DLT_IEEE802_11": "syscall",
+ "syscall.DLT_IEEE802_11_RADIO": "syscall",
+ "syscall.DLT_IEEE802_11_RADIO_AVS": "syscall",
+ "syscall.DLT_IEEE802_15_4": "syscall",
+ "syscall.DLT_IEEE802_15_4_LINUX": "syscall",
+ "syscall.DLT_IEEE802_15_4_NOFCS": "syscall",
+ "syscall.DLT_IEEE802_15_4_NONASK_PHY": "syscall",
+ "syscall.DLT_IEEE802_16_MAC_CPS": "syscall",
+ "syscall.DLT_IEEE802_16_MAC_CPS_RADIO": "syscall",
+ "syscall.DLT_IPFILTER": "syscall",
+ "syscall.DLT_IPMB": "syscall",
+ "syscall.DLT_IPMB_LINUX": "syscall",
+ "syscall.DLT_IPNET": "syscall",
+ "syscall.DLT_IPOIB": "syscall",
+ "syscall.DLT_IPV4": "syscall",
+ "syscall.DLT_IPV6": "syscall",
+ "syscall.DLT_IP_OVER_FC": "syscall",
+ "syscall.DLT_JUNIPER_ATM1": "syscall",
+ "syscall.DLT_JUNIPER_ATM2": "syscall",
+ "syscall.DLT_JUNIPER_ATM_CEMIC": "syscall",
+ "syscall.DLT_JUNIPER_CHDLC": "syscall",
+ "syscall.DLT_JUNIPER_ES": "syscall",
+ "syscall.DLT_JUNIPER_ETHER": "syscall",
+ "syscall.DLT_JUNIPER_FIBRECHANNEL": "syscall",
+ "syscall.DLT_JUNIPER_FRELAY": "syscall",
+ "syscall.DLT_JUNIPER_GGSN": "syscall",
+ "syscall.DLT_JUNIPER_ISM": "syscall",
+ "syscall.DLT_JUNIPER_MFR": "syscall",
+ "syscall.DLT_JUNIPER_MLFR": "syscall",
+ "syscall.DLT_JUNIPER_MLPPP": "syscall",
+ "syscall.DLT_JUNIPER_MONITOR": "syscall",
+ "syscall.DLT_JUNIPER_PIC_PEER": "syscall",
+ "syscall.DLT_JUNIPER_PPP": "syscall",
+ "syscall.DLT_JUNIPER_PPPOE": "syscall",
+ "syscall.DLT_JUNIPER_PPPOE_ATM": "syscall",
+ "syscall.DLT_JUNIPER_SERVICES": "syscall",
+ "syscall.DLT_JUNIPER_SRX_E2E": "syscall",
+ "syscall.DLT_JUNIPER_ST": "syscall",
+ "syscall.DLT_JUNIPER_VP": "syscall",
+ "syscall.DLT_JUNIPER_VS": "syscall",
+ "syscall.DLT_LAPB_WITH_DIR": "syscall",
+ "syscall.DLT_LAPD": "syscall",
+ "syscall.DLT_LIN": "syscall",
+ "syscall.DLT_LINUX_EVDEV": "syscall",
+ "syscall.DLT_LINUX_IRDA": "syscall",
+ "syscall.DLT_LINUX_LAPD": "syscall",
+ "syscall.DLT_LINUX_PPP_WITHDIRECTION": "syscall",
+ "syscall.DLT_LINUX_SLL": "syscall",
+ "syscall.DLT_LOOP": "syscall",
+ "syscall.DLT_LTALK": "syscall",
+ "syscall.DLT_MATCHING_MAX": "syscall",
+ "syscall.DLT_MATCHING_MIN": "syscall",
+ "syscall.DLT_MFR": "syscall",
+ "syscall.DLT_MOST": "syscall",
+ "syscall.DLT_MPEG_2_TS": "syscall",
+ "syscall.DLT_MPLS": "syscall",
+ "syscall.DLT_MTP2": "syscall",
+ "syscall.DLT_MTP2_WITH_PHDR": "syscall",
+ "syscall.DLT_MTP3": "syscall",
+ "syscall.DLT_MUX27010": "syscall",
+ "syscall.DLT_NETANALYZER": "syscall",
+ "syscall.DLT_NETANALYZER_TRANSPARENT": "syscall",
+ "syscall.DLT_NFC_LLCP": "syscall",
+ "syscall.DLT_NFLOG": "syscall",
+ "syscall.DLT_NG40": "syscall",
+ "syscall.DLT_NULL": "syscall",
+ "syscall.DLT_PCI_EXP": "syscall",
+ "syscall.DLT_PFLOG": "syscall",
+ "syscall.DLT_PFSYNC": "syscall",
+ "syscall.DLT_PPI": "syscall",
+ "syscall.DLT_PPP": "syscall",
+ "syscall.DLT_PPP_BSDOS": "syscall",
+ "syscall.DLT_PPP_ETHER": "syscall",
+ "syscall.DLT_PPP_PPPD": "syscall",
+ "syscall.DLT_PPP_SERIAL": "syscall",
+ "syscall.DLT_PPP_WITH_DIR": "syscall",
+ "syscall.DLT_PPP_WITH_DIRECTION": "syscall",
+ "syscall.DLT_PRISM_HEADER": "syscall",
+ "syscall.DLT_PRONET": "syscall",
+ "syscall.DLT_RAIF1": "syscall",
+ "syscall.DLT_RAW": "syscall",
+ "syscall.DLT_RAWAF_MASK": "syscall",
+ "syscall.DLT_RIO": "syscall",
+ "syscall.DLT_SCCP": "syscall",
+ "syscall.DLT_SITA": "syscall",
+ "syscall.DLT_SLIP": "syscall",
+ "syscall.DLT_SLIP_BSDOS": "syscall",
+ "syscall.DLT_STANAG_5066_D_PDU": "syscall",
+ "syscall.DLT_SUNATM": "syscall",
+ "syscall.DLT_SYMANTEC_FIREWALL": "syscall",
+ "syscall.DLT_TZSP": "syscall",
+ "syscall.DLT_USB": "syscall",
+ "syscall.DLT_USB_LINUX": "syscall",
+ "syscall.DLT_USB_LINUX_MMAPPED": "syscall",
+ "syscall.DLT_USER0": "syscall",
+ "syscall.DLT_USER1": "syscall",
+ "syscall.DLT_USER10": "syscall",
+ "syscall.DLT_USER11": "syscall",
+ "syscall.DLT_USER12": "syscall",
+ "syscall.DLT_USER13": "syscall",
+ "syscall.DLT_USER14": "syscall",
+ "syscall.DLT_USER15": "syscall",
+ "syscall.DLT_USER2": "syscall",
+ "syscall.DLT_USER3": "syscall",
+ "syscall.DLT_USER4": "syscall",
+ "syscall.DLT_USER5": "syscall",
+ "syscall.DLT_USER6": "syscall",
+ "syscall.DLT_USER7": "syscall",
+ "syscall.DLT_USER8": "syscall",
+ "syscall.DLT_USER9": "syscall",
+ "syscall.DLT_WIHART": "syscall",
+ "syscall.DLT_X2E_SERIAL": "syscall",
+ "syscall.DLT_X2E_XORAYA": "syscall",
+ "syscall.DNSMXData": "syscall",
+ "syscall.DNSPTRData": "syscall",
+ "syscall.DNSRecord": "syscall",
+ "syscall.DNSSRVData": "syscall",
+ "syscall.DNSTXTData": "syscall",
+ "syscall.DNS_TYPE_A": "syscall",
+ "syscall.DNS_TYPE_A6": "syscall",
+ "syscall.DNS_TYPE_AAAA": "syscall",
+ "syscall.DNS_TYPE_ADDRS": "syscall",
+ "syscall.DNS_TYPE_AFSDB": "syscall",
+ "syscall.DNS_TYPE_ALL": "syscall",
+ "syscall.DNS_TYPE_ANY": "syscall",
+ "syscall.DNS_TYPE_ATMA": "syscall",
+ "syscall.DNS_TYPE_AXFR": "syscall",
+ "syscall.DNS_TYPE_CERT": "syscall",
+ "syscall.DNS_TYPE_CNAME": "syscall",
+ "syscall.DNS_TYPE_DHCID": "syscall",
+ "syscall.DNS_TYPE_DNAME": "syscall",
+ "syscall.DNS_TYPE_DNSKEY": "syscall",
+ "syscall.DNS_TYPE_DS": "syscall",
+ "syscall.DNS_TYPE_EID": "syscall",
+ "syscall.DNS_TYPE_GID": "syscall",
+ "syscall.DNS_TYPE_GPOS": "syscall",
+ "syscall.DNS_TYPE_HINFO": "syscall",
+ "syscall.DNS_TYPE_ISDN": "syscall",
+ "syscall.DNS_TYPE_IXFR": "syscall",
+ "syscall.DNS_TYPE_KEY": "syscall",
+ "syscall.DNS_TYPE_KX": "syscall",
+ "syscall.DNS_TYPE_LOC": "syscall",
+ "syscall.DNS_TYPE_MAILA": "syscall",
+ "syscall.DNS_TYPE_MAILB": "syscall",
+ "syscall.DNS_TYPE_MB": "syscall",
+ "syscall.DNS_TYPE_MD": "syscall",
+ "syscall.DNS_TYPE_MF": "syscall",
+ "syscall.DNS_TYPE_MG": "syscall",
+ "syscall.DNS_TYPE_MINFO": "syscall",
+ "syscall.DNS_TYPE_MR": "syscall",
+ "syscall.DNS_TYPE_MX": "syscall",
+ "syscall.DNS_TYPE_NAPTR": "syscall",
+ "syscall.DNS_TYPE_NBSTAT": "syscall",
+ "syscall.DNS_TYPE_NIMLOC": "syscall",
+ "syscall.DNS_TYPE_NS": "syscall",
+ "syscall.DNS_TYPE_NSAP": "syscall",
+ "syscall.DNS_TYPE_NSAPPTR": "syscall",
+ "syscall.DNS_TYPE_NSEC": "syscall",
+ "syscall.DNS_TYPE_NULL": "syscall",
+ "syscall.DNS_TYPE_NXT": "syscall",
+ "syscall.DNS_TYPE_OPT": "syscall",
+ "syscall.DNS_TYPE_PTR": "syscall",
+ "syscall.DNS_TYPE_PX": "syscall",
+ "syscall.DNS_TYPE_RP": "syscall",
+ "syscall.DNS_TYPE_RRSIG": "syscall",
+ "syscall.DNS_TYPE_RT": "syscall",
+ "syscall.DNS_TYPE_SIG": "syscall",
+ "syscall.DNS_TYPE_SINK": "syscall",
+ "syscall.DNS_TYPE_SOA": "syscall",
+ "syscall.DNS_TYPE_SRV": "syscall",
+ "syscall.DNS_TYPE_TEXT": "syscall",
+ "syscall.DNS_TYPE_TKEY": "syscall",
+ "syscall.DNS_TYPE_TSIG": "syscall",
+ "syscall.DNS_TYPE_UID": "syscall",
+ "syscall.DNS_TYPE_UINFO": "syscall",
+ "syscall.DNS_TYPE_UNSPEC": "syscall",
+ "syscall.DNS_TYPE_WINS": "syscall",
+ "syscall.DNS_TYPE_WINSR": "syscall",
+ "syscall.DNS_TYPE_WKS": "syscall",
+ "syscall.DNS_TYPE_X25": "syscall",
+ "syscall.DT_BLK": "syscall",
+ "syscall.DT_CHR": "syscall",
+ "syscall.DT_DIR": "syscall",
+ "syscall.DT_FIFO": "syscall",
+ "syscall.DT_LNK": "syscall",
+ "syscall.DT_REG": "syscall",
+ "syscall.DT_SOCK": "syscall",
+ "syscall.DT_UNKNOWN": "syscall",
+ "syscall.DT_WHT": "syscall",
+ "syscall.DUPLICATE_CLOSE_SOURCE": "syscall",
+ "syscall.DUPLICATE_SAME_ACCESS": "syscall",
+ "syscall.DeleteFile": "syscall",
+ "syscall.DetachLsf": "syscall",
+ "syscall.Dirent": "syscall",
+ "syscall.DnsQuery": "syscall",
+ "syscall.DnsRecordListFree": "syscall",
+ "syscall.Dup": "syscall",
+ "syscall.Dup2": "syscall",
+ "syscall.Dup3": "syscall",
+ "syscall.DuplicateHandle": "syscall",
+ "syscall.E2BIG": "syscall",
+ "syscall.EACCES": "syscall",
+ "syscall.EADDRINUSE": "syscall",
+ "syscall.EADDRNOTAVAIL": "syscall",
+ "syscall.EADV": "syscall",
+ "syscall.EAFNOSUPPORT": "syscall",
+ "syscall.EAGAIN": "syscall",
+ "syscall.EALREADY": "syscall",
+ "syscall.EAUTH": "syscall",
+ "syscall.EBADARCH": "syscall",
+ "syscall.EBADE": "syscall",
+ "syscall.EBADEXEC": "syscall",
+ "syscall.EBADF": "syscall",
+ "syscall.EBADFD": "syscall",
+ "syscall.EBADMACHO": "syscall",
+ "syscall.EBADMSG": "syscall",
+ "syscall.EBADR": "syscall",
+ "syscall.EBADRPC": "syscall",
+ "syscall.EBADRQC": "syscall",
+ "syscall.EBADSLT": "syscall",
+ "syscall.EBFONT": "syscall",
+ "syscall.EBUSY": "syscall",
+ "syscall.ECANCELED": "syscall",
+ "syscall.ECAPMODE": "syscall",
+ "syscall.ECHILD": "syscall",
+ "syscall.ECHO": "syscall",
+ "syscall.ECHOCTL": "syscall",
+ "syscall.ECHOE": "syscall",
+ "syscall.ECHOK": "syscall",
+ "syscall.ECHOKE": "syscall",
+ "syscall.ECHONL": "syscall",
+ "syscall.ECHOPRT": "syscall",
+ "syscall.ECHRNG": "syscall",
+ "syscall.ECOMM": "syscall",
+ "syscall.ECONNABORTED": "syscall",
+ "syscall.ECONNREFUSED": "syscall",
+ "syscall.ECONNRESET": "syscall",
+ "syscall.EDEADLK": "syscall",
+ "syscall.EDEADLOCK": "syscall",
+ "syscall.EDESTADDRREQ": "syscall",
+ "syscall.EDEVERR": "syscall",
+ "syscall.EDOM": "syscall",
+ "syscall.EDOOFUS": "syscall",
+ "syscall.EDOTDOT": "syscall",
+ "syscall.EDQUOT": "syscall",
+ "syscall.EEXIST": "syscall",
+ "syscall.EFAULT": "syscall",
+ "syscall.EFBIG": "syscall",
+ "syscall.EFER_LMA": "syscall",
+ "syscall.EFER_LME": "syscall",
+ "syscall.EFER_NXE": "syscall",
+ "syscall.EFER_SCE": "syscall",
+ "syscall.EFTYPE": "syscall",
+ "syscall.EHOSTDOWN": "syscall",
+ "syscall.EHOSTUNREACH": "syscall",
+ "syscall.EHWPOISON": "syscall",
+ "syscall.EIDRM": "syscall",
+ "syscall.EILSEQ": "syscall",
+ "syscall.EINPROGRESS": "syscall",
+ "syscall.EINTR": "syscall",
+ "syscall.EINVAL": "syscall",
+ "syscall.EIO": "syscall",
+ "syscall.EIPSEC": "syscall",
+ "syscall.EISCONN": "syscall",
+ "syscall.EISDIR": "syscall",
+ "syscall.EISNAM": "syscall",
+ "syscall.EKEYEXPIRED": "syscall",
+ "syscall.EKEYREJECTED": "syscall",
+ "syscall.EKEYREVOKED": "syscall",
+ "syscall.EL2HLT": "syscall",
+ "syscall.EL2NSYNC": "syscall",
+ "syscall.EL3HLT": "syscall",
+ "syscall.EL3RST": "syscall",
+ "syscall.ELAST": "syscall",
+ "syscall.ELF_NGREG": "syscall",
+ "syscall.ELF_PRARGSZ": "syscall",
+ "syscall.ELIBACC": "syscall",
+ "syscall.ELIBBAD": "syscall",
+ "syscall.ELIBEXEC": "syscall",
+ "syscall.ELIBMAX": "syscall",
+ "syscall.ELIBSCN": "syscall",
+ "syscall.ELNRNG": "syscall",
+ "syscall.ELOOP": "syscall",
+ "syscall.EMEDIUMTYPE": "syscall",
+ "syscall.EMFILE": "syscall",
+ "syscall.EMLINK": "syscall",
+ "syscall.EMSGSIZE": "syscall",
+ "syscall.EMT_TAGOVF": "syscall",
+ "syscall.EMULTIHOP": "syscall",
+ "syscall.EMUL_ENABLED": "syscall",
+ "syscall.EMUL_LINUX": "syscall",
+ "syscall.EMUL_LINUX32": "syscall",
+ "syscall.EMUL_MAXID": "syscall",
+ "syscall.EMUL_NATIVE": "syscall",
+ "syscall.ENAMETOOLONG": "syscall",
+ "syscall.ENAVAIL": "syscall",
+ "syscall.ENDRUNDISC": "syscall",
+ "syscall.ENEEDAUTH": "syscall",
+ "syscall.ENETDOWN": "syscall",
+ "syscall.ENETRESET": "syscall",
+ "syscall.ENETUNREACH": "syscall",
+ "syscall.ENFILE": "syscall",
+ "syscall.ENOANO": "syscall",
+ "syscall.ENOATTR": "syscall",
+ "syscall.ENOBUFS": "syscall",
+ "syscall.ENOCSI": "syscall",
+ "syscall.ENODATA": "syscall",
+ "syscall.ENODEV": "syscall",
+ "syscall.ENOENT": "syscall",
+ "syscall.ENOEXEC": "syscall",
+ "syscall.ENOKEY": "syscall",
+ "syscall.ENOLCK": "syscall",
+ "syscall.ENOLINK": "syscall",
+ "syscall.ENOMEDIUM": "syscall",
+ "syscall.ENOMEM": "syscall",
+ "syscall.ENOMSG": "syscall",
+ "syscall.ENONET": "syscall",
+ "syscall.ENOPKG": "syscall",
+ "syscall.ENOPOLICY": "syscall",
+ "syscall.ENOPROTOOPT": "syscall",
+ "syscall.ENOSPC": "syscall",
+ "syscall.ENOSR": "syscall",
+ "syscall.ENOSTR": "syscall",
+ "syscall.ENOSYS": "syscall",
+ "syscall.ENOTBLK": "syscall",
+ "syscall.ENOTCAPABLE": "syscall",
+ "syscall.ENOTCONN": "syscall",
+ "syscall.ENOTDIR": "syscall",
+ "syscall.ENOTEMPTY": "syscall",
+ "syscall.ENOTNAM": "syscall",
+ "syscall.ENOTRECOVERABLE": "syscall",
+ "syscall.ENOTSOCK": "syscall",
+ "syscall.ENOTSUP": "syscall",
+ "syscall.ENOTTY": "syscall",
+ "syscall.ENOTUNIQ": "syscall",
+ "syscall.ENXIO": "syscall",
+ "syscall.EN_SW_CTL_INF": "syscall",
+ "syscall.EN_SW_CTL_PREC": "syscall",
+ "syscall.EN_SW_CTL_ROUND": "syscall",
+ "syscall.EN_SW_DATACHAIN": "syscall",
+ "syscall.EN_SW_DENORM": "syscall",
+ "syscall.EN_SW_INVOP": "syscall",
+ "syscall.EN_SW_OVERFLOW": "syscall",
+ "syscall.EN_SW_PRECLOSS": "syscall",
+ "syscall.EN_SW_UNDERFLOW": "syscall",
+ "syscall.EN_SW_ZERODIV": "syscall",
+ "syscall.EOPNOTSUPP": "syscall",
+ "syscall.EOVERFLOW": "syscall",
+ "syscall.EOWNERDEAD": "syscall",
+ "syscall.EPERM": "syscall",
+ "syscall.EPFNOSUPPORT": "syscall",
+ "syscall.EPIPE": "syscall",
+ "syscall.EPOLLERR": "syscall",
+ "syscall.EPOLLET": "syscall",
+ "syscall.EPOLLHUP": "syscall",
+ "syscall.EPOLLIN": "syscall",
+ "syscall.EPOLLMSG": "syscall",
+ "syscall.EPOLLONESHOT": "syscall",
+ "syscall.EPOLLOUT": "syscall",
+ "syscall.EPOLLPRI": "syscall",
+ "syscall.EPOLLRDBAND": "syscall",
+ "syscall.EPOLLRDHUP": "syscall",
+ "syscall.EPOLLRDNORM": "syscall",
+ "syscall.EPOLLWRBAND": "syscall",
+ "syscall.EPOLLWRNORM": "syscall",
+ "syscall.EPOLL_CLOEXEC": "syscall",
+ "syscall.EPOLL_CTL_ADD": "syscall",
+ "syscall.EPOLL_CTL_DEL": "syscall",
+ "syscall.EPOLL_CTL_MOD": "syscall",
+ "syscall.EPOLL_NONBLOCK": "syscall",
+ "syscall.EPROCLIM": "syscall",
+ "syscall.EPROCUNAVAIL": "syscall",
+ "syscall.EPROGMISMATCH": "syscall",
+ "syscall.EPROGUNAVAIL": "syscall",
+ "syscall.EPROTO": "syscall",
+ "syscall.EPROTONOSUPPORT": "syscall",
+ "syscall.EPROTOTYPE": "syscall",
+ "syscall.EPWROFF": "syscall",
+ "syscall.ERANGE": "syscall",
+ "syscall.EREMCHG": "syscall",
+ "syscall.EREMOTE": "syscall",
+ "syscall.EREMOTEIO": "syscall",
+ "syscall.ERESTART": "syscall",
+ "syscall.ERFKILL": "syscall",
+ "syscall.EROFS": "syscall",
+ "syscall.ERPCMISMATCH": "syscall",
+ "syscall.ERROR_ACCESS_DENIED": "syscall",
+ "syscall.ERROR_ALREADY_EXISTS": "syscall",
+ "syscall.ERROR_BROKEN_PIPE": "syscall",
+ "syscall.ERROR_BUFFER_OVERFLOW": "syscall",
+ "syscall.ERROR_ENVVAR_NOT_FOUND": "syscall",
+ "syscall.ERROR_FILE_EXISTS": "syscall",
+ "syscall.ERROR_FILE_NOT_FOUND": "syscall",
+ "syscall.ERROR_HANDLE_EOF": "syscall",
+ "syscall.ERROR_INSUFFICIENT_BUFFER": "syscall",
+ "syscall.ERROR_IO_PENDING": "syscall",
+ "syscall.ERROR_MOD_NOT_FOUND": "syscall",
+ "syscall.ERROR_NOT_FOUND": "syscall",
+ "syscall.ERROR_NO_MORE_FILES": "syscall",
+ "syscall.ERROR_OPERATION_ABORTED": "syscall",
+ "syscall.ERROR_PATH_NOT_FOUND": "syscall",
+ "syscall.ERROR_PROC_NOT_FOUND": "syscall",
+ "syscall.ESHLIBVERS": "syscall",
+ "syscall.ESHUTDOWN": "syscall",
+ "syscall.ESOCKTNOSUPPORT": "syscall",
+ "syscall.ESPIPE": "syscall",
+ "syscall.ESRCH": "syscall",
+ "syscall.ESRMNT": "syscall",
+ "syscall.ESTALE": "syscall",
+ "syscall.ESTRPIPE": "syscall",
+ "syscall.ETHERCAP_JUMBO_MTU": "syscall",
+ "syscall.ETHERCAP_VLAN_HWTAGGING": "syscall",
+ "syscall.ETHERCAP_VLAN_MTU": "syscall",
+ "syscall.ETHERMIN": "syscall",
+ "syscall.ETHERMTU": "syscall",
+ "syscall.ETHERMTU_JUMBO": "syscall",
+ "syscall.ETHERTYPE_8023": "syscall",
+ "syscall.ETHERTYPE_AARP": "syscall",
+ "syscall.ETHERTYPE_ACCTON": "syscall",
+ "syscall.ETHERTYPE_AEONIC": "syscall",
+ "syscall.ETHERTYPE_ALPHA": "syscall",
+ "syscall.ETHERTYPE_AMBER": "syscall",
+ "syscall.ETHERTYPE_AMOEBA": "syscall",
+ "syscall.ETHERTYPE_AOE": "syscall",
+ "syscall.ETHERTYPE_APOLLO": "syscall",
+ "syscall.ETHERTYPE_APOLLODOMAIN": "syscall",
+ "syscall.ETHERTYPE_APPLETALK": "syscall",
+ "syscall.ETHERTYPE_APPLITEK": "syscall",
+ "syscall.ETHERTYPE_ARGONAUT": "syscall",
+ "syscall.ETHERTYPE_ARP": "syscall",
+ "syscall.ETHERTYPE_AT": "syscall",
+ "syscall.ETHERTYPE_ATALK": "syscall",
+ "syscall.ETHERTYPE_ATOMIC": "syscall",
+ "syscall.ETHERTYPE_ATT": "syscall",
+ "syscall.ETHERTYPE_ATTSTANFORD": "syscall",
+ "syscall.ETHERTYPE_AUTOPHON": "syscall",
+ "syscall.ETHERTYPE_AXIS": "syscall",
+ "syscall.ETHERTYPE_BCLOOP": "syscall",
+ "syscall.ETHERTYPE_BOFL": "syscall",
+ "syscall.ETHERTYPE_CABLETRON": "syscall",
+ "syscall.ETHERTYPE_CHAOS": "syscall",
+ "syscall.ETHERTYPE_COMDESIGN": "syscall",
+ "syscall.ETHERTYPE_COMPUGRAPHIC": "syscall",
+ "syscall.ETHERTYPE_COUNTERPOINT": "syscall",
+ "syscall.ETHERTYPE_CRONUS": "syscall",
+ "syscall.ETHERTYPE_CRONUSVLN": "syscall",
+ "syscall.ETHERTYPE_DCA": "syscall",
+ "syscall.ETHERTYPE_DDE": "syscall",
+ "syscall.ETHERTYPE_DEBNI": "syscall",
+ "syscall.ETHERTYPE_DECAM": "syscall",
+ "syscall.ETHERTYPE_DECCUST": "syscall",
+ "syscall.ETHERTYPE_DECDIAG": "syscall",
+ "syscall.ETHERTYPE_DECDNS": "syscall",
+ "syscall.ETHERTYPE_DECDTS": "syscall",
+ "syscall.ETHERTYPE_DECEXPER": "syscall",
+ "syscall.ETHERTYPE_DECLAST": "syscall",
+ "syscall.ETHERTYPE_DECLTM": "syscall",
+ "syscall.ETHERTYPE_DECMUMPS": "syscall",
+ "syscall.ETHERTYPE_DECNETBIOS": "syscall",
+ "syscall.ETHERTYPE_DELTACON": "syscall",
+ "syscall.ETHERTYPE_DIDDLE": "syscall",
+ "syscall.ETHERTYPE_DLOG1": "syscall",
+ "syscall.ETHERTYPE_DLOG2": "syscall",
+ "syscall.ETHERTYPE_DN": "syscall",
+ "syscall.ETHERTYPE_DOGFIGHT": "syscall",
+ "syscall.ETHERTYPE_DSMD": "syscall",
+ "syscall.ETHERTYPE_ECMA": "syscall",
+ "syscall.ETHERTYPE_ENCRYPT": "syscall",
+ "syscall.ETHERTYPE_ES": "syscall",
+ "syscall.ETHERTYPE_EXCELAN": "syscall",
+ "syscall.ETHERTYPE_EXPERDATA": "syscall",
+ "syscall.ETHERTYPE_FLIP": "syscall",
+ "syscall.ETHERTYPE_FLOWCONTROL": "syscall",
+ "syscall.ETHERTYPE_FRARP": "syscall",
+ "syscall.ETHERTYPE_GENDYN": "syscall",
+ "syscall.ETHERTYPE_HAYES": "syscall",
+ "syscall.ETHERTYPE_HIPPI_FP": "syscall",
+ "syscall.ETHERTYPE_HITACHI": "syscall",
+ "syscall.ETHERTYPE_HP": "syscall",
+ "syscall.ETHERTYPE_IEEEPUP": "syscall",
+ "syscall.ETHERTYPE_IEEEPUPAT": "syscall",
+ "syscall.ETHERTYPE_IMLBL": "syscall",
+ "syscall.ETHERTYPE_IMLBLDIAG": "syscall",
+ "syscall.ETHERTYPE_IP": "syscall",
+ "syscall.ETHERTYPE_IPAS": "syscall",
+ "syscall.ETHERTYPE_IPV6": "syscall",
+ "syscall.ETHERTYPE_IPX": "syscall",
+ "syscall.ETHERTYPE_IPXNEW": "syscall",
+ "syscall.ETHERTYPE_KALPANA": "syscall",
+ "syscall.ETHERTYPE_LANBRIDGE": "syscall",
+ "syscall.ETHERTYPE_LANPROBE": "syscall",
+ "syscall.ETHERTYPE_LAT": "syscall",
+ "syscall.ETHERTYPE_LBACK": "syscall",
+ "syscall.ETHERTYPE_LITTLE": "syscall",
+ "syscall.ETHERTYPE_LLDP": "syscall",
+ "syscall.ETHERTYPE_LOGICRAFT": "syscall",
+ "syscall.ETHERTYPE_LOOPBACK": "syscall",
+ "syscall.ETHERTYPE_MATRA": "syscall",
+ "syscall.ETHERTYPE_MAX": "syscall",
+ "syscall.ETHERTYPE_MERIT": "syscall",
+ "syscall.ETHERTYPE_MICP": "syscall",
+ "syscall.ETHERTYPE_MOPDL": "syscall",
+ "syscall.ETHERTYPE_MOPRC": "syscall",
+ "syscall.ETHERTYPE_MOTOROLA": "syscall",
+ "syscall.ETHERTYPE_MPLS": "syscall",
+ "syscall.ETHERTYPE_MPLS_MCAST": "syscall",
+ "syscall.ETHERTYPE_MUMPS": "syscall",
+ "syscall.ETHERTYPE_NBPCC": "syscall",
+ "syscall.ETHERTYPE_NBPCLAIM": "syscall",
+ "syscall.ETHERTYPE_NBPCLREQ": "syscall",
+ "syscall.ETHERTYPE_NBPCLRSP": "syscall",
+ "syscall.ETHERTYPE_NBPCREQ": "syscall",
+ "syscall.ETHERTYPE_NBPCRSP": "syscall",
+ "syscall.ETHERTYPE_NBPDG": "syscall",
+ "syscall.ETHERTYPE_NBPDGB": "syscall",
+ "syscall.ETHERTYPE_NBPDLTE": "syscall",
+ "syscall.ETHERTYPE_NBPRAR": "syscall",
+ "syscall.ETHERTYPE_NBPRAS": "syscall",
+ "syscall.ETHERTYPE_NBPRST": "syscall",
+ "syscall.ETHERTYPE_NBPSCD": "syscall",
+ "syscall.ETHERTYPE_NBPVCD": "syscall",
+ "syscall.ETHERTYPE_NBS": "syscall",
+ "syscall.ETHERTYPE_NCD": "syscall",
+ "syscall.ETHERTYPE_NESTAR": "syscall",
+ "syscall.ETHERTYPE_NETBEUI": "syscall",
+ "syscall.ETHERTYPE_NOVELL": "syscall",
+ "syscall.ETHERTYPE_NS": "syscall",
+ "syscall.ETHERTYPE_NSAT": "syscall",
+ "syscall.ETHERTYPE_NSCOMPAT": "syscall",
+ "syscall.ETHERTYPE_NTRAILER": "syscall",
+ "syscall.ETHERTYPE_OS9": "syscall",
+ "syscall.ETHERTYPE_OS9NET": "syscall",
+ "syscall.ETHERTYPE_PACER": "syscall",
+ "syscall.ETHERTYPE_PAE": "syscall",
+ "syscall.ETHERTYPE_PCS": "syscall",
+ "syscall.ETHERTYPE_PLANNING": "syscall",
+ "syscall.ETHERTYPE_PPP": "syscall",
+ "syscall.ETHERTYPE_PPPOE": "syscall",
+ "syscall.ETHERTYPE_PPPOEDISC": "syscall",
+ "syscall.ETHERTYPE_PRIMENTS": "syscall",
+ "syscall.ETHERTYPE_PUP": "syscall",
+ "syscall.ETHERTYPE_PUPAT": "syscall",
+ "syscall.ETHERTYPE_QINQ": "syscall",
+ "syscall.ETHERTYPE_RACAL": "syscall",
+ "syscall.ETHERTYPE_RATIONAL": "syscall",
+ "syscall.ETHERTYPE_RAWFR": "syscall",
+ "syscall.ETHERTYPE_RCL": "syscall",
+ "syscall.ETHERTYPE_RDP": "syscall",
+ "syscall.ETHERTYPE_RETIX": "syscall",
+ "syscall.ETHERTYPE_REVARP": "syscall",
+ "syscall.ETHERTYPE_SCA": "syscall",
+ "syscall.ETHERTYPE_SECTRA": "syscall",
+ "syscall.ETHERTYPE_SECUREDATA": "syscall",
+ "syscall.ETHERTYPE_SGITW": "syscall",
+ "syscall.ETHERTYPE_SG_BOUNCE": "syscall",
+ "syscall.ETHERTYPE_SG_DIAG": "syscall",
+ "syscall.ETHERTYPE_SG_NETGAMES": "syscall",
+ "syscall.ETHERTYPE_SG_RESV": "syscall",
+ "syscall.ETHERTYPE_SIMNET": "syscall",
+ "syscall.ETHERTYPE_SLOW": "syscall",
+ "syscall.ETHERTYPE_SLOWPROTOCOLS": "syscall",
+ "syscall.ETHERTYPE_SNA": "syscall",
+ "syscall.ETHERTYPE_SNMP": "syscall",
+ "syscall.ETHERTYPE_SONIX": "syscall",
+ "syscall.ETHERTYPE_SPIDER": "syscall",
+ "syscall.ETHERTYPE_SPRITE": "syscall",
+ "syscall.ETHERTYPE_STP": "syscall",
+ "syscall.ETHERTYPE_TALARIS": "syscall",
+ "syscall.ETHERTYPE_TALARISMC": "syscall",
+ "syscall.ETHERTYPE_TCPCOMP": "syscall",
+ "syscall.ETHERTYPE_TCPSM": "syscall",
+ "syscall.ETHERTYPE_TEC": "syscall",
+ "syscall.ETHERTYPE_TIGAN": "syscall",
+ "syscall.ETHERTYPE_TRAIL": "syscall",
+ "syscall.ETHERTYPE_TRANSETHER": "syscall",
+ "syscall.ETHERTYPE_TYMSHARE": "syscall",
+ "syscall.ETHERTYPE_UBBST": "syscall",
+ "syscall.ETHERTYPE_UBDEBUG": "syscall",
+ "syscall.ETHERTYPE_UBDIAGLOOP": "syscall",
+ "syscall.ETHERTYPE_UBDL": "syscall",
+ "syscall.ETHERTYPE_UBNIU": "syscall",
+ "syscall.ETHERTYPE_UBNMC": "syscall",
+ "syscall.ETHERTYPE_VALID": "syscall",
+ "syscall.ETHERTYPE_VARIAN": "syscall",
+ "syscall.ETHERTYPE_VAXELN": "syscall",
+ "syscall.ETHERTYPE_VEECO": "syscall",
+ "syscall.ETHERTYPE_VEXP": "syscall",
+ "syscall.ETHERTYPE_VGLAB": "syscall",
+ "syscall.ETHERTYPE_VINES": "syscall",
+ "syscall.ETHERTYPE_VINESECHO": "syscall",
+ "syscall.ETHERTYPE_VINESLOOP": "syscall",
+ "syscall.ETHERTYPE_VITAL": "syscall",
+ "syscall.ETHERTYPE_VLAN": "syscall",
+ "syscall.ETHERTYPE_VLTLMAN": "syscall",
+ "syscall.ETHERTYPE_VPROD": "syscall",
+ "syscall.ETHERTYPE_VURESERVED": "syscall",
+ "syscall.ETHERTYPE_WATERLOO": "syscall",
+ "syscall.ETHERTYPE_WELLFLEET": "syscall",
+ "syscall.ETHERTYPE_X25": "syscall",
+ "syscall.ETHERTYPE_X75": "syscall",
+ "syscall.ETHERTYPE_XNSSM": "syscall",
+ "syscall.ETHERTYPE_XTP": "syscall",
+ "syscall.ETHER_ADDR_LEN": "syscall",
+ "syscall.ETHER_ALIGN": "syscall",
+ "syscall.ETHER_CRC_LEN": "syscall",
+ "syscall.ETHER_CRC_POLY_BE": "syscall",
+ "syscall.ETHER_CRC_POLY_LE": "syscall",
+ "syscall.ETHER_HDR_LEN": "syscall",
+ "syscall.ETHER_MAX_DIX_LEN": "syscall",
+ "syscall.ETHER_MAX_LEN": "syscall",
+ "syscall.ETHER_MAX_LEN_JUMBO": "syscall",
+ "syscall.ETHER_MIN_LEN": "syscall",
+ "syscall.ETHER_PPPOE_ENCAP_LEN": "syscall",
+ "syscall.ETHER_TYPE_LEN": "syscall",
+ "syscall.ETHER_VLAN_ENCAP_LEN": "syscall",
+ "syscall.ETH_P_1588": "syscall",
+ "syscall.ETH_P_8021Q": "syscall",
+ "syscall.ETH_P_802_2": "syscall",
+ "syscall.ETH_P_802_3": "syscall",
+ "syscall.ETH_P_AARP": "syscall",
+ "syscall.ETH_P_ALL": "syscall",
+ "syscall.ETH_P_AOE": "syscall",
+ "syscall.ETH_P_ARCNET": "syscall",
+ "syscall.ETH_P_ARP": "syscall",
+ "syscall.ETH_P_ATALK": "syscall",
+ "syscall.ETH_P_ATMFATE": "syscall",
+ "syscall.ETH_P_ATMMPOA": "syscall",
+ "syscall.ETH_P_AX25": "syscall",
+ "syscall.ETH_P_BPQ": "syscall",
+ "syscall.ETH_P_CAIF": "syscall",
+ "syscall.ETH_P_CAN": "syscall",
+ "syscall.ETH_P_CONTROL": "syscall",
+ "syscall.ETH_P_CUST": "syscall",
+ "syscall.ETH_P_DDCMP": "syscall",
+ "syscall.ETH_P_DEC": "syscall",
+ "syscall.ETH_P_DIAG": "syscall",
+ "syscall.ETH_P_DNA_DL": "syscall",
+ "syscall.ETH_P_DNA_RC": "syscall",
+ "syscall.ETH_P_DNA_RT": "syscall",
+ "syscall.ETH_P_DSA": "syscall",
+ "syscall.ETH_P_ECONET": "syscall",
+ "syscall.ETH_P_EDSA": "syscall",
+ "syscall.ETH_P_FCOE": "syscall",
+ "syscall.ETH_P_FIP": "syscall",
+ "syscall.ETH_P_HDLC": "syscall",
+ "syscall.ETH_P_IEEE802154": "syscall",
+ "syscall.ETH_P_IEEEPUP": "syscall",
+ "syscall.ETH_P_IEEEPUPAT": "syscall",
+ "syscall.ETH_P_IP": "syscall",
+ "syscall.ETH_P_IPV6": "syscall",
+ "syscall.ETH_P_IPX": "syscall",
+ "syscall.ETH_P_IRDA": "syscall",
+ "syscall.ETH_P_LAT": "syscall",
+ "syscall.ETH_P_LINK_CTL": "syscall",
+ "syscall.ETH_P_LOCALTALK": "syscall",
+ "syscall.ETH_P_LOOP": "syscall",
+ "syscall.ETH_P_MOBITEX": "syscall",
+ "syscall.ETH_P_MPLS_MC": "syscall",
+ "syscall.ETH_P_MPLS_UC": "syscall",
+ "syscall.ETH_P_PAE": "syscall",
+ "syscall.ETH_P_PAUSE": "syscall",
+ "syscall.ETH_P_PHONET": "syscall",
+ "syscall.ETH_P_PPPTALK": "syscall",
+ "syscall.ETH_P_PPP_DISC": "syscall",
+ "syscall.ETH_P_PPP_MP": "syscall",
+ "syscall.ETH_P_PPP_SES": "syscall",
+ "syscall.ETH_P_PUP": "syscall",
+ "syscall.ETH_P_PUPAT": "syscall",
+ "syscall.ETH_P_RARP": "syscall",
+ "syscall.ETH_P_SCA": "syscall",
+ "syscall.ETH_P_SLOW": "syscall",
+ "syscall.ETH_P_SNAP": "syscall",
+ "syscall.ETH_P_TEB": "syscall",
+ "syscall.ETH_P_TIPC": "syscall",
+ "syscall.ETH_P_TRAILER": "syscall",
+ "syscall.ETH_P_TR_802_2": "syscall",
+ "syscall.ETH_P_WAN_PPP": "syscall",
+ "syscall.ETH_P_WCCP": "syscall",
+ "syscall.ETH_P_X25": "syscall",
+ "syscall.ETIME": "syscall",
+ "syscall.ETIMEDOUT": "syscall",
+ "syscall.ETOOMANYREFS": "syscall",
+ "syscall.ETXTBSY": "syscall",
+ "syscall.EUCLEAN": "syscall",
+ "syscall.EUNATCH": "syscall",
+ "syscall.EUSERS": "syscall",
+ "syscall.EVFILT_AIO": "syscall",
+ "syscall.EVFILT_FS": "syscall",
+ "syscall.EVFILT_LIO": "syscall",
+ "syscall.EVFILT_MACHPORT": "syscall",
+ "syscall.EVFILT_PROC": "syscall",
+ "syscall.EVFILT_READ": "syscall",
+ "syscall.EVFILT_SIGNAL": "syscall",
+ "syscall.EVFILT_SYSCOUNT": "syscall",
+ "syscall.EVFILT_THREADMARKER": "syscall",
+ "syscall.EVFILT_TIMER": "syscall",
+ "syscall.EVFILT_USER": "syscall",
+ "syscall.EVFILT_VM": "syscall",
+ "syscall.EVFILT_VNODE": "syscall",
+ "syscall.EVFILT_WRITE": "syscall",
+ "syscall.EV_ADD": "syscall",
+ "syscall.EV_CLEAR": "syscall",
+ "syscall.EV_DELETE": "syscall",
+ "syscall.EV_DISABLE": "syscall",
+ "syscall.EV_DISPATCH": "syscall",
+ "syscall.EV_ENABLE": "syscall",
+ "syscall.EV_EOF": "syscall",
+ "syscall.EV_ERROR": "syscall",
+ "syscall.EV_FLAG0": "syscall",
+ "syscall.EV_FLAG1": "syscall",
+ "syscall.EV_ONESHOT": "syscall",
+ "syscall.EV_OOBAND": "syscall",
+ "syscall.EV_POLL": "syscall",
+ "syscall.EV_RECEIPT": "syscall",
+ "syscall.EV_SYSFLAGS": "syscall",
+ "syscall.EWINDOWS": "syscall",
+ "syscall.EWOULDBLOCK": "syscall",
+ "syscall.EXDEV": "syscall",
+ "syscall.EXFULL": "syscall",
+ "syscall.EXTA": "syscall",
+ "syscall.EXTB": "syscall",
+ "syscall.EXTPROC": "syscall",
+ "syscall.Environ": "syscall",
+ "syscall.EpollCreate": "syscall",
+ "syscall.EpollCreate1": "syscall",
+ "syscall.EpollCtl": "syscall",
+ "syscall.EpollEvent": "syscall",
+ "syscall.EpollWait": "syscall",
+ "syscall.Errno": "syscall",
+ "syscall.EscapeArg": "syscall",
+ "syscall.Exchangedata": "syscall",
+ "syscall.Exec": "syscall",
+ "syscall.Exit": "syscall",
+ "syscall.ExitProcess": "syscall",
+ "syscall.FD_CLOEXEC": "syscall",
+ "syscall.FD_SETSIZE": "syscall",
+ "syscall.FILE_ACTION_ADDED": "syscall",
+ "syscall.FILE_ACTION_MODIFIED": "syscall",
+ "syscall.FILE_ACTION_REMOVED": "syscall",
+ "syscall.FILE_ACTION_RENAMED_NEW_NAME": "syscall",
+ "syscall.FILE_ACTION_RENAMED_OLD_NAME": "syscall",
+ "syscall.FILE_APPEND_DATA": "syscall",
+ "syscall.FILE_ATTRIBUTE_ARCHIVE": "syscall",
+ "syscall.FILE_ATTRIBUTE_DIRECTORY": "syscall",
+ "syscall.FILE_ATTRIBUTE_HIDDEN": "syscall",
+ "syscall.FILE_ATTRIBUTE_NORMAL": "syscall",
+ "syscall.FILE_ATTRIBUTE_READONLY": "syscall",
+ "syscall.FILE_ATTRIBUTE_SYSTEM": "syscall",
+ "syscall.FILE_BEGIN": "syscall",
+ "syscall.FILE_CURRENT": "syscall",
+ "syscall.FILE_END": "syscall",
+ "syscall.FILE_FLAG_BACKUP_SEMANTICS": "syscall",
+ "syscall.FILE_FLAG_OVERLAPPED": "syscall",
+ "syscall.FILE_LIST_DIRECTORY": "syscall",
+ "syscall.FILE_MAP_COPY": "syscall",
+ "syscall.FILE_MAP_EXECUTE": "syscall",
+ "syscall.FILE_MAP_READ": "syscall",
+ "syscall.FILE_MAP_WRITE": "syscall",
+ "syscall.FILE_NOTIFY_CHANGE_ATTRIBUTES": "syscall",
+ "syscall.FILE_NOTIFY_CHANGE_CREATION": "syscall",
+ "syscall.FILE_NOTIFY_CHANGE_DIR_NAME": "syscall",
+ "syscall.FILE_NOTIFY_CHANGE_FILE_NAME": "syscall",
+ "syscall.FILE_NOTIFY_CHANGE_LAST_ACCESS": "syscall",
+ "syscall.FILE_NOTIFY_CHANGE_LAST_WRITE": "syscall",
+ "syscall.FILE_NOTIFY_CHANGE_SIZE": "syscall",
+ "syscall.FILE_SHARE_DELETE": "syscall",
+ "syscall.FILE_SHARE_READ": "syscall",
+ "syscall.FILE_SHARE_WRITE": "syscall",
+ "syscall.FILE_SKIP_COMPLETION_PORT_ON_SUCCESS": "syscall",
+ "syscall.FILE_SKIP_SET_EVENT_ON_HANDLE": "syscall",
+ "syscall.FILE_TYPE_CHAR": "syscall",
+ "syscall.FILE_TYPE_DISK": "syscall",
+ "syscall.FILE_TYPE_PIPE": "syscall",
+ "syscall.FILE_TYPE_REMOTE": "syscall",
+ "syscall.FILE_TYPE_UNKNOWN": "syscall",
+ "syscall.FILE_WRITE_ATTRIBUTES": "syscall",
+ "syscall.FLUSHO": "syscall",
+ "syscall.FORMAT_MESSAGE_ALLOCATE_BUFFER": "syscall",
+ "syscall.FORMAT_MESSAGE_ARGUMENT_ARRAY": "syscall",
+ "syscall.FORMAT_MESSAGE_FROM_HMODULE": "syscall",
+ "syscall.FORMAT_MESSAGE_FROM_STRING": "syscall",
+ "syscall.FORMAT_MESSAGE_FROM_SYSTEM": "syscall",
+ "syscall.FORMAT_MESSAGE_IGNORE_INSERTS": "syscall",
+ "syscall.FORMAT_MESSAGE_MAX_WIDTH_MASK": "syscall",
+ "syscall.F_ADDFILESIGS": "syscall",
+ "syscall.F_ADDSIGS": "syscall",
+ "syscall.F_ALLOCATEALL": "syscall",
+ "syscall.F_ALLOCATECONTIG": "syscall",
+ "syscall.F_CANCEL": "syscall",
+ "syscall.F_CHKCLEAN": "syscall",
+ "syscall.F_CLOSEM": "syscall",
+ "syscall.F_DUP2FD": "syscall",
+ "syscall.F_DUP2FD_CLOEXEC": "syscall",
+ "syscall.F_DUPFD": "syscall",
+ "syscall.F_DUPFD_CLOEXEC": "syscall",
+ "syscall.F_EXLCK": "syscall",
+ "syscall.F_FLUSH_DATA": "syscall",
+ "syscall.F_FREEZE_FS": "syscall",
+ "syscall.F_FSCTL": "syscall",
+ "syscall.F_FSDIRMASK": "syscall",
+ "syscall.F_FSIN": "syscall",
+ "syscall.F_FSINOUT": "syscall",
+ "syscall.F_FSOUT": "syscall",
+ "syscall.F_FSPRIV": "syscall",
+ "syscall.F_FSVOID": "syscall",
+ "syscall.F_FULLFSYNC": "syscall",
+ "syscall.F_GETFD": "syscall",
+ "syscall.F_GETFL": "syscall",
+ "syscall.F_GETLEASE": "syscall",
+ "syscall.F_GETLK": "syscall",
+ "syscall.F_GETLK64": "syscall",
+ "syscall.F_GETLKPID": "syscall",
+ "syscall.F_GETNOSIGPIPE": "syscall",
+ "syscall.F_GETOWN": "syscall",
+ "syscall.F_GETOWN_EX": "syscall",
+ "syscall.F_GETPATH": "syscall",
+ "syscall.F_GETPATH_MTMINFO": "syscall",
+ "syscall.F_GETPIPE_SZ": "syscall",
+ "syscall.F_GETPROTECTIONCLASS": "syscall",
+ "syscall.F_GETSIG": "syscall",
+ "syscall.F_GLOBAL_NOCACHE": "syscall",
+ "syscall.F_LOCK": "syscall",
+ "syscall.F_LOG2PHYS": "syscall",
+ "syscall.F_LOG2PHYS_EXT": "syscall",
+ "syscall.F_MARKDEPENDENCY": "syscall",
+ "syscall.F_MAXFD": "syscall",
+ "syscall.F_NOCACHE": "syscall",
+ "syscall.F_NODIRECT": "syscall",
+ "syscall.F_NOTIFY": "syscall",
+ "syscall.F_OGETLK": "syscall",
+ "syscall.F_OK": "syscall",
+ "syscall.F_OSETLK": "syscall",
+ "syscall.F_OSETLKW": "syscall",
+ "syscall.F_PARAM_MASK": "syscall",
+ "syscall.F_PARAM_MAX": "syscall",
+ "syscall.F_PATHPKG_CHECK": "syscall",
+ "syscall.F_PEOFPOSMODE": "syscall",
+ "syscall.F_PREALLOCATE": "syscall",
+ "syscall.F_RDADVISE": "syscall",
+ "syscall.F_RDAHEAD": "syscall",
+ "syscall.F_RDLCK": "syscall",
+ "syscall.F_READAHEAD": "syscall",
+ "syscall.F_READBOOTSTRAP": "syscall",
+ "syscall.F_SETBACKINGSTORE": "syscall",
+ "syscall.F_SETFD": "syscall",
+ "syscall.F_SETFL": "syscall",
+ "syscall.F_SETLEASE": "syscall",
+ "syscall.F_SETLK": "syscall",
+ "syscall.F_SETLK64": "syscall",
+ "syscall.F_SETLKW": "syscall",
+ "syscall.F_SETLKW64": "syscall",
+ "syscall.F_SETLK_REMOTE": "syscall",
+ "syscall.F_SETNOSIGPIPE": "syscall",
+ "syscall.F_SETOWN": "syscall",
+ "syscall.F_SETOWN_EX": "syscall",
+ "syscall.F_SETPIPE_SZ": "syscall",
+ "syscall.F_SETPROTECTIONCLASS": "syscall",
+ "syscall.F_SETSIG": "syscall",
+ "syscall.F_SETSIZE": "syscall",
+ "syscall.F_SHLCK": "syscall",
+ "syscall.F_TEST": "syscall",
+ "syscall.F_THAW_FS": "syscall",
+ "syscall.F_TLOCK": "syscall",
+ "syscall.F_ULOCK": "syscall",
+ "syscall.F_UNLCK": "syscall",
+ "syscall.F_UNLCKSYS": "syscall",
+ "syscall.F_VOLPOSMODE": "syscall",
+ "syscall.F_WRITEBOOTSTRAP": "syscall",
+ "syscall.F_WRLCK": "syscall",
+ "syscall.Faccessat": "syscall",
+ "syscall.Fallocate": "syscall",
+ "syscall.Fbootstraptransfer_t": "syscall",
+ "syscall.Fchdir": "syscall",
+ "syscall.Fchflags": "syscall",
+ "syscall.Fchmod": "syscall",
+ "syscall.Fchmodat": "syscall",
+ "syscall.Fchown": "syscall",
+ "syscall.Fchownat": "syscall",
+ "syscall.FdSet": "syscall",
+ "syscall.Fdatasync": "syscall",
+ "syscall.FileNotifyInformation": "syscall",
+ "syscall.Filetime": "syscall",
+ "syscall.FindClose": "syscall",
+ "syscall.FindFirstFile": "syscall",
+ "syscall.FindNextFile": "syscall",
+ "syscall.Flock": "syscall",
+ "syscall.Flock_t": "syscall",
+ "syscall.FlushBpf": "syscall",
+ "syscall.FlushFileBuffers": "syscall",
+ "syscall.FlushViewOfFile": "syscall",
+ "syscall.ForkExec": "syscall",
+ "syscall.ForkLock": "syscall",
+ "syscall.FormatMessage": "syscall",
+ "syscall.Fpathconf": "syscall",
+ "syscall.FreeAddrInfoW": "syscall",
+ "syscall.FreeEnvironmentStrings": "syscall",
+ "syscall.FreeLibrary": "syscall",
+ "syscall.Fsid": "syscall",
+ "syscall.Fstat": "syscall",
+ "syscall.Fstatfs": "syscall",
+ "syscall.Fstore_t": "syscall",
+ "syscall.Fsync": "syscall",
+ "syscall.Ftruncate": "syscall",
+ "syscall.Futimes": "syscall",
+ "syscall.Futimesat": "syscall",
+ "syscall.GENERIC_ALL": "syscall",
+ "syscall.GENERIC_EXECUTE": "syscall",
+ "syscall.GENERIC_READ": "syscall",
+ "syscall.GENERIC_WRITE": "syscall",
+ "syscall.GUID": "syscall",
+ "syscall.GetAcceptExSockaddrs": "syscall",
+ "syscall.GetAdaptersInfo": "syscall",
+ "syscall.GetAddrInfoW": "syscall",
+ "syscall.GetCommandLine": "syscall",
+ "syscall.GetComputerName": "syscall",
+ "syscall.GetConsoleMode": "syscall",
+ "syscall.GetCurrentDirectory": "syscall",
+ "syscall.GetCurrentProcess": "syscall",
+ "syscall.GetEnvironmentStrings": "syscall",
+ "syscall.GetEnvironmentVariable": "syscall",
+ "syscall.GetExitCodeProcess": "syscall",
+ "syscall.GetFileAttributes": "syscall",
+ "syscall.GetFileAttributesEx": "syscall",
+ "syscall.GetFileExInfoStandard": "syscall",
+ "syscall.GetFileExMaxInfoLevel": "syscall",
+ "syscall.GetFileInformationByHandle": "syscall",
+ "syscall.GetFileType": "syscall",
+ "syscall.GetFullPathName": "syscall",
+ "syscall.GetHostByName": "syscall",
+ "syscall.GetIfEntry": "syscall",
+ "syscall.GetLastError": "syscall",
+ "syscall.GetLengthSid": "syscall",
+ "syscall.GetLongPathName": "syscall",
+ "syscall.GetProcAddress": "syscall",
+ "syscall.GetProcessTimes": "syscall",
+ "syscall.GetProtoByName": "syscall",
+ "syscall.GetQueuedCompletionStatus": "syscall",
+ "syscall.GetServByName": "syscall",
+ "syscall.GetShortPathName": "syscall",
+ "syscall.GetStartupInfo": "syscall",
+ "syscall.GetStdHandle": "syscall",
+ "syscall.GetSystemTimeAsFileTime": "syscall",
+ "syscall.GetTempPath": "syscall",
+ "syscall.GetTimeZoneInformation": "syscall",
+ "syscall.GetTokenInformation": "syscall",
+ "syscall.GetUserNameEx": "syscall",
+ "syscall.GetUserProfileDirectory": "syscall",
+ "syscall.GetVersion": "syscall",
+ "syscall.Getcwd": "syscall",
+ "syscall.Getdents": "syscall",
+ "syscall.Getdirentries": "syscall",
+ "syscall.Getdtablesize": "syscall",
+ "syscall.Getegid": "syscall",
+ "syscall.Getenv": "syscall",
+ "syscall.Geteuid": "syscall",
+ "syscall.Getfsstat": "syscall",
+ "syscall.Getgid": "syscall",
+ "syscall.Getgroups": "syscall",
+ "syscall.Getpagesize": "syscall",
+ "syscall.Getpeername": "syscall",
+ "syscall.Getpgid": "syscall",
+ "syscall.Getpgrp": "syscall",
+ "syscall.Getpid": "syscall",
+ "syscall.Getppid": "syscall",
+ "syscall.Getpriority": "syscall",
+ "syscall.Getrlimit": "syscall",
+ "syscall.Getrusage": "syscall",
+ "syscall.Getsid": "syscall",
+ "syscall.Getsockname": "syscall",
+ "syscall.Getsockopt": "syscall",
+ "syscall.GetsockoptByte": "syscall",
+ "syscall.GetsockoptICMPv6Filter": "syscall",
+ "syscall.GetsockoptIPMreq": "syscall",
+ "syscall.GetsockoptIPMreqn": "syscall",
+ "syscall.GetsockoptIPv6MTUInfo": "syscall",
+ "syscall.GetsockoptIPv6Mreq": "syscall",
+ "syscall.GetsockoptInet4Addr": "syscall",
+ "syscall.GetsockoptInt": "syscall",
+ "syscall.GetsockoptUcred": "syscall",
+ "syscall.Gettid": "syscall",
+ "syscall.Gettimeofday": "syscall",
+ "syscall.Getuid": "syscall",
+ "syscall.Getwd": "syscall",
+ "syscall.Getxattr": "syscall",
+ "syscall.HANDLE_FLAG_INHERIT": "syscall",
+ "syscall.HKEY_CLASSES_ROOT": "syscall",
+ "syscall.HKEY_CURRENT_CONFIG": "syscall",
+ "syscall.HKEY_CURRENT_USER": "syscall",
+ "syscall.HKEY_DYN_DATA": "syscall",
+ "syscall.HKEY_LOCAL_MACHINE": "syscall",
+ "syscall.HKEY_PERFORMANCE_DATA": "syscall",
+ "syscall.HKEY_USERS": "syscall",
+ "syscall.HUPCL": "syscall",
+ "syscall.Handle": "syscall",
+ "syscall.Hostent": "syscall",
+ "syscall.ICANON": "syscall",
+ "syscall.ICMP6_FILTER": "syscall",
+ "syscall.ICMPV6_FILTER": "syscall",
+ "syscall.ICMPv6Filter": "syscall",
+ "syscall.ICRNL": "syscall",
+ "syscall.IEXTEN": "syscall",
+ "syscall.IFAN_ARRIVAL": "syscall",
+ "syscall.IFAN_DEPARTURE": "syscall",
+ "syscall.IFA_ADDRESS": "syscall",
+ "syscall.IFA_ANYCAST": "syscall",
+ "syscall.IFA_BROADCAST": "syscall",
+ "syscall.IFA_CACHEINFO": "syscall",
+ "syscall.IFA_F_DADFAILED": "syscall",
+ "syscall.IFA_F_DEPRECATED": "syscall",
+ "syscall.IFA_F_HOMEADDRESS": "syscall",
+ "syscall.IFA_F_NODAD": "syscall",
+ "syscall.IFA_F_OPTIMISTIC": "syscall",
+ "syscall.IFA_F_PERMANENT": "syscall",
+ "syscall.IFA_F_SECONDARY": "syscall",
+ "syscall.IFA_F_TEMPORARY": "syscall",
+ "syscall.IFA_F_TENTATIVE": "syscall",
+ "syscall.IFA_LABEL": "syscall",
+ "syscall.IFA_LOCAL": "syscall",
+ "syscall.IFA_MAX": "syscall",
+ "syscall.IFA_MULTICAST": "syscall",
+ "syscall.IFA_ROUTE": "syscall",
+ "syscall.IFA_UNSPEC": "syscall",
+ "syscall.IFF_ALLMULTI": "syscall",
+ "syscall.IFF_ALTPHYS": "syscall",
+ "syscall.IFF_AUTOMEDIA": "syscall",
+ "syscall.IFF_BROADCAST": "syscall",
+ "syscall.IFF_CANTCHANGE": "syscall",
+ "syscall.IFF_CANTCONFIG": "syscall",
+ "syscall.IFF_DEBUG": "syscall",
+ "syscall.IFF_DRV_OACTIVE": "syscall",
+ "syscall.IFF_DRV_RUNNING": "syscall",
+ "syscall.IFF_DYING": "syscall",
+ "syscall.IFF_DYNAMIC": "syscall",
+ "syscall.IFF_LINK0": "syscall",
+ "syscall.IFF_LINK1": "syscall",
+ "syscall.IFF_LINK2": "syscall",
+ "syscall.IFF_LOOPBACK": "syscall",
+ "syscall.IFF_MASTER": "syscall",
+ "syscall.IFF_MONITOR": "syscall",
+ "syscall.IFF_MULTICAST": "syscall",
+ "syscall.IFF_NOARP": "syscall",
+ "syscall.IFF_NOTRAILERS": "syscall",
+ "syscall.IFF_NO_PI": "syscall",
+ "syscall.IFF_OACTIVE": "syscall",
+ "syscall.IFF_ONE_QUEUE": "syscall",
+ "syscall.IFF_POINTOPOINT": "syscall",
+ "syscall.IFF_POINTTOPOINT": "syscall",
+ "syscall.IFF_PORTSEL": "syscall",
+ "syscall.IFF_PPROMISC": "syscall",
+ "syscall.IFF_PROMISC": "syscall",
+ "syscall.IFF_RENAMING": "syscall",
+ "syscall.IFF_RUNNING": "syscall",
+ "syscall.IFF_SIMPLEX": "syscall",
+ "syscall.IFF_SLAVE": "syscall",
+ "syscall.IFF_SMART": "syscall",
+ "syscall.IFF_STATICARP": "syscall",
+ "syscall.IFF_TAP": "syscall",
+ "syscall.IFF_TUN": "syscall",
+ "syscall.IFF_TUN_EXCL": "syscall",
+ "syscall.IFF_UP": "syscall",
+ "syscall.IFF_VNET_HDR": "syscall",
+ "syscall.IFLA_ADDRESS": "syscall",
+ "syscall.IFLA_BROADCAST": "syscall",
+ "syscall.IFLA_COST": "syscall",
+ "syscall.IFLA_IFALIAS": "syscall",
+ "syscall.IFLA_IFNAME": "syscall",
+ "syscall.IFLA_LINK": "syscall",
+ "syscall.IFLA_LINKINFO": "syscall",
+ "syscall.IFLA_LINKMODE": "syscall",
+ "syscall.IFLA_MAP": "syscall",
+ "syscall.IFLA_MASTER": "syscall",
+ "syscall.IFLA_MAX": "syscall",
+ "syscall.IFLA_MTU": "syscall",
+ "syscall.IFLA_NET_NS_PID": "syscall",
+ "syscall.IFLA_OPERSTATE": "syscall",
+ "syscall.IFLA_PRIORITY": "syscall",
+ "syscall.IFLA_PROTINFO": "syscall",
+ "syscall.IFLA_QDISC": "syscall",
+ "syscall.IFLA_STATS": "syscall",
+ "syscall.IFLA_TXQLEN": "syscall",
+ "syscall.IFLA_UNSPEC": "syscall",
+ "syscall.IFLA_WEIGHT": "syscall",
+ "syscall.IFLA_WIRELESS": "syscall",
+ "syscall.IFNAMSIZ": "syscall",
+ "syscall.IFT_1822": "syscall",
+ "syscall.IFT_A12MPPSWITCH": "syscall",
+ "syscall.IFT_AAL2": "syscall",
+ "syscall.IFT_AAL5": "syscall",
+ "syscall.IFT_ADSL": "syscall",
+ "syscall.IFT_AFLANE8023": "syscall",
+ "syscall.IFT_AFLANE8025": "syscall",
+ "syscall.IFT_ARAP": "syscall",
+ "syscall.IFT_ARCNET": "syscall",
+ "syscall.IFT_ARCNETPLUS": "syscall",
+ "syscall.IFT_ASYNC": "syscall",
+ "syscall.IFT_ATM": "syscall",
+ "syscall.IFT_ATMDXI": "syscall",
+ "syscall.IFT_ATMFUNI": "syscall",
+ "syscall.IFT_ATMIMA": "syscall",
+ "syscall.IFT_ATMLOGICAL": "syscall",
+ "syscall.IFT_ATMRADIO": "syscall",
+ "syscall.IFT_ATMSUBINTERFACE": "syscall",
+ "syscall.IFT_ATMVCIENDPT": "syscall",
+ "syscall.IFT_ATMVIRTUAL": "syscall",
+ "syscall.IFT_BGPPOLICYACCOUNTING": "syscall",
+ "syscall.IFT_BLUETOOTH": "syscall",
+ "syscall.IFT_BRIDGE": "syscall",
+ "syscall.IFT_BSC": "syscall",
+ "syscall.IFT_CARP": "syscall",
+ "syscall.IFT_CCTEMUL": "syscall",
+ "syscall.IFT_CELLULAR": "syscall",
+ "syscall.IFT_CEPT": "syscall",
+ "syscall.IFT_CES": "syscall",
+ "syscall.IFT_CHANNEL": "syscall",
+ "syscall.IFT_CNR": "syscall",
+ "syscall.IFT_COFFEE": "syscall",
+ "syscall.IFT_COMPOSITELINK": "syscall",
+ "syscall.IFT_DCN": "syscall",
+ "syscall.IFT_DIGITALPOWERLINE": "syscall",
+ "syscall.IFT_DIGITALWRAPPEROVERHEADCHANNEL": "syscall",
+ "syscall.IFT_DLSW": "syscall",
+ "syscall.IFT_DOCSCABLEDOWNSTREAM": "syscall",
+ "syscall.IFT_DOCSCABLEMACLAYER": "syscall",
+ "syscall.IFT_DOCSCABLEUPSTREAM": "syscall",
+ "syscall.IFT_DOCSCABLEUPSTREAMCHANNEL": "syscall",
+ "syscall.IFT_DS0": "syscall",
+ "syscall.IFT_DS0BUNDLE": "syscall",
+ "syscall.IFT_DS1FDL": "syscall",
+ "syscall.IFT_DS3": "syscall",
+ "syscall.IFT_DTM": "syscall",
+ "syscall.IFT_DUMMY": "syscall",
+ "syscall.IFT_DVBASILN": "syscall",
+ "syscall.IFT_DVBASIOUT": "syscall",
+ "syscall.IFT_DVBRCCDOWNSTREAM": "syscall",
+ "syscall.IFT_DVBRCCMACLAYER": "syscall",
+ "syscall.IFT_DVBRCCUPSTREAM": "syscall",
+ "syscall.IFT_ECONET": "syscall",
+ "syscall.IFT_ENC": "syscall",
+ "syscall.IFT_EON": "syscall",
+ "syscall.IFT_EPLRS": "syscall",
+ "syscall.IFT_ESCON": "syscall",
+ "syscall.IFT_ETHER": "syscall",
+ "syscall.IFT_FAITH": "syscall",
+ "syscall.IFT_FAST": "syscall",
+ "syscall.IFT_FASTETHER": "syscall",
+ "syscall.IFT_FASTETHERFX": "syscall",
+ "syscall.IFT_FDDI": "syscall",
+ "syscall.IFT_FIBRECHANNEL": "syscall",
+ "syscall.IFT_FRAMERELAYINTERCONNECT": "syscall",
+ "syscall.IFT_FRAMERELAYMPI": "syscall",
+ "syscall.IFT_FRDLCIENDPT": "syscall",
+ "syscall.IFT_FRELAY": "syscall",
+ "syscall.IFT_FRELAYDCE": "syscall",
+ "syscall.IFT_FRF16MFRBUNDLE": "syscall",
+ "syscall.IFT_FRFORWARD": "syscall",
+ "syscall.IFT_G703AT2MB": "syscall",
+ "syscall.IFT_G703AT64K": "syscall",
+ "syscall.IFT_GIF": "syscall",
+ "syscall.IFT_GIGABITETHERNET": "syscall",
+ "syscall.IFT_GR303IDT": "syscall",
+ "syscall.IFT_GR303RDT": "syscall",
+ "syscall.IFT_H323GATEKEEPER": "syscall",
+ "syscall.IFT_H323PROXY": "syscall",
+ "syscall.IFT_HDH1822": "syscall",
+ "syscall.IFT_HDLC": "syscall",
+ "syscall.IFT_HDSL2": "syscall",
+ "syscall.IFT_HIPERLAN2": "syscall",
+ "syscall.IFT_HIPPI": "syscall",
+ "syscall.IFT_HIPPIINTERFACE": "syscall",
+ "syscall.IFT_HOSTPAD": "syscall",
+ "syscall.IFT_HSSI": "syscall",
+ "syscall.IFT_HY": "syscall",
+ "syscall.IFT_IBM370PARCHAN": "syscall",
+ "syscall.IFT_IDSL": "syscall",
+ "syscall.IFT_IEEE1394": "syscall",
+ "syscall.IFT_IEEE80211": "syscall",
+ "syscall.IFT_IEEE80212": "syscall",
+ "syscall.IFT_IEEE8023ADLAG": "syscall",
+ "syscall.IFT_IFGSN": "syscall",
+ "syscall.IFT_IMT": "syscall",
+ "syscall.IFT_INFINIBAND": "syscall",
+ "syscall.IFT_INTERLEAVE": "syscall",
+ "syscall.IFT_IP": "syscall",
+ "syscall.IFT_IPFORWARD": "syscall",
+ "syscall.IFT_IPOVERATM": "syscall",
+ "syscall.IFT_IPOVERCDLC": "syscall",
+ "syscall.IFT_IPOVERCLAW": "syscall",
+ "syscall.IFT_IPSWITCH": "syscall",
+ "syscall.IFT_IPXIP": "syscall",
+ "syscall.IFT_ISDN": "syscall",
+ "syscall.IFT_ISDNBASIC": "syscall",
+ "syscall.IFT_ISDNPRIMARY": "syscall",
+ "syscall.IFT_ISDNS": "syscall",
+ "syscall.IFT_ISDNU": "syscall",
+ "syscall.IFT_ISO88022LLC": "syscall",
+ "syscall.IFT_ISO88023": "syscall",
+ "syscall.IFT_ISO88024": "syscall",
+ "syscall.IFT_ISO88025": "syscall",
+ "syscall.IFT_ISO88025CRFPINT": "syscall",
+ "syscall.IFT_ISO88025DTR": "syscall",
+ "syscall.IFT_ISO88025FIBER": "syscall",
+ "syscall.IFT_ISO88026": "syscall",
+ "syscall.IFT_ISUP": "syscall",
+ "syscall.IFT_L2VLAN": "syscall",
+ "syscall.IFT_L3IPVLAN": "syscall",
+ "syscall.IFT_L3IPXVLAN": "syscall",
+ "syscall.IFT_LAPB": "syscall",
+ "syscall.IFT_LAPD": "syscall",
+ "syscall.IFT_LAPF": "syscall",
+ "syscall.IFT_LINEGROUP": "syscall",
+ "syscall.IFT_LOCALTALK": "syscall",
+ "syscall.IFT_LOOP": "syscall",
+ "syscall.IFT_MEDIAMAILOVERIP": "syscall",
+ "syscall.IFT_MFSIGLINK": "syscall",
+ "syscall.IFT_MIOX25": "syscall",
+ "syscall.IFT_MODEM": "syscall",
+ "syscall.IFT_MPC": "syscall",
+ "syscall.IFT_MPLS": "syscall",
+ "syscall.IFT_MPLSTUNNEL": "syscall",
+ "syscall.IFT_MSDSL": "syscall",
+ "syscall.IFT_MVL": "syscall",
+ "syscall.IFT_MYRINET": "syscall",
+ "syscall.IFT_NFAS": "syscall",
+ "syscall.IFT_NSIP": "syscall",
+ "syscall.IFT_OPTICALCHANNEL": "syscall",
+ "syscall.IFT_OPTICALTRANSPORT": "syscall",
+ "syscall.IFT_OTHER": "syscall",
+ "syscall.IFT_P10": "syscall",
+ "syscall.IFT_P80": "syscall",
+ "syscall.IFT_PARA": "syscall",
+ "syscall.IFT_PDP": "syscall",
+ "syscall.IFT_PFLOG": "syscall",
+ "syscall.IFT_PFLOW": "syscall",
+ "syscall.IFT_PFSYNC": "syscall",
+ "syscall.IFT_PLC": "syscall",
+ "syscall.IFT_PON155": "syscall",
+ "syscall.IFT_PON622": "syscall",
+ "syscall.IFT_POS": "syscall",
+ "syscall.IFT_PPP": "syscall",
+ "syscall.IFT_PPPMULTILINKBUNDLE": "syscall",
+ "syscall.IFT_PROPATM": "syscall",
+ "syscall.IFT_PROPBWAP2MP": "syscall",
+ "syscall.IFT_PROPCNLS": "syscall",
+ "syscall.IFT_PROPDOCSWIRELESSDOWNSTREAM": "syscall",
+ "syscall.IFT_PROPDOCSWIRELESSMACLAYER": "syscall",
+ "syscall.IFT_PROPDOCSWIRELESSUPSTREAM": "syscall",
+ "syscall.IFT_PROPMUX": "syscall",
+ "syscall.IFT_PROPVIRTUAL": "syscall",
+ "syscall.IFT_PROPWIRELESSP2P": "syscall",
+ "syscall.IFT_PTPSERIAL": "syscall",
+ "syscall.IFT_PVC": "syscall",
+ "syscall.IFT_Q2931": "syscall",
+ "syscall.IFT_QLLC": "syscall",
+ "syscall.IFT_RADIOMAC": "syscall",
+ "syscall.IFT_RADSL": "syscall",
+ "syscall.IFT_REACHDSL": "syscall",
+ "syscall.IFT_RFC1483": "syscall",
+ "syscall.IFT_RS232": "syscall",
+ "syscall.IFT_RSRB": "syscall",
+ "syscall.IFT_SDLC": "syscall",
+ "syscall.IFT_SDSL": "syscall",
+ "syscall.IFT_SHDSL": "syscall",
+ "syscall.IFT_SIP": "syscall",
+ "syscall.IFT_SIPSIG": "syscall",
+ "syscall.IFT_SIPTG": "syscall",
+ "syscall.IFT_SLIP": "syscall",
+ "syscall.IFT_SMDSDXI": "syscall",
+ "syscall.IFT_SMDSICIP": "syscall",
+ "syscall.IFT_SONET": "syscall",
+ "syscall.IFT_SONETOVERHEADCHANNEL": "syscall",
+ "syscall.IFT_SONETPATH": "syscall",
+ "syscall.IFT_SONETVT": "syscall",
+ "syscall.IFT_SRP": "syscall",
+ "syscall.IFT_SS7SIGLINK": "syscall",
+ "syscall.IFT_STACKTOSTACK": "syscall",
+ "syscall.IFT_STARLAN": "syscall",
+ "syscall.IFT_STF": "syscall",
+ "syscall.IFT_T1": "syscall",
+ "syscall.IFT_TDLC": "syscall",
+ "syscall.IFT_TELINK": "syscall",
+ "syscall.IFT_TERMPAD": "syscall",
+ "syscall.IFT_TR008": "syscall",
+ "syscall.IFT_TRANSPHDLC": "syscall",
+ "syscall.IFT_TUNNEL": "syscall",
+ "syscall.IFT_ULTRA": "syscall",
+ "syscall.IFT_USB": "syscall",
+ "syscall.IFT_V11": "syscall",
+ "syscall.IFT_V35": "syscall",
+ "syscall.IFT_V36": "syscall",
+ "syscall.IFT_V37": "syscall",
+ "syscall.IFT_VDSL": "syscall",
+ "syscall.IFT_VIRTUALIPADDRESS": "syscall",
+ "syscall.IFT_VIRTUALTG": "syscall",
+ "syscall.IFT_VOICEDID": "syscall",
+ "syscall.IFT_VOICEEM": "syscall",
+ "syscall.IFT_VOICEEMFGD": "syscall",
+ "syscall.IFT_VOICEENCAP": "syscall",
+ "syscall.IFT_VOICEFGDEANA": "syscall",
+ "syscall.IFT_VOICEFXO": "syscall",
+ "syscall.IFT_VOICEFXS": "syscall",
+ "syscall.IFT_VOICEOVERATM": "syscall",
+ "syscall.IFT_VOICEOVERCABLE": "syscall",
+ "syscall.IFT_VOICEOVERFRAMERELAY": "syscall",
+ "syscall.IFT_VOICEOVERIP": "syscall",
+ "syscall.IFT_X213": "syscall",
+ "syscall.IFT_X25": "syscall",
+ "syscall.IFT_X25DDN": "syscall",
+ "syscall.IFT_X25HUNTGROUP": "syscall",
+ "syscall.IFT_X25MLP": "syscall",
+ "syscall.IFT_X25PLE": "syscall",
+ "syscall.IFT_XETHER": "syscall",
+ "syscall.IGNBRK": "syscall",
+ "syscall.IGNCR": "syscall",
+ "syscall.IGNORE": "syscall",
+ "syscall.IGNPAR": "syscall",
+ "syscall.IMAXBEL": "syscall",
+ "syscall.INFINITE": "syscall",
+ "syscall.INLCR": "syscall",
+ "syscall.INPCK": "syscall",
+ "syscall.INVALID_FILE_ATTRIBUTES": "syscall",
+ "syscall.IN_ACCESS": "syscall",
+ "syscall.IN_ALL_EVENTS": "syscall",
+ "syscall.IN_ATTRIB": "syscall",
+ "syscall.IN_CLASSA_HOST": "syscall",
+ "syscall.IN_CLASSA_MAX": "syscall",
+ "syscall.IN_CLASSA_NET": "syscall",
+ "syscall.IN_CLASSA_NSHIFT": "syscall",
+ "syscall.IN_CLASSB_HOST": "syscall",
+ "syscall.IN_CLASSB_MAX": "syscall",
+ "syscall.IN_CLASSB_NET": "syscall",
+ "syscall.IN_CLASSB_NSHIFT": "syscall",
+ "syscall.IN_CLASSC_HOST": "syscall",
+ "syscall.IN_CLASSC_NET": "syscall",
+ "syscall.IN_CLASSC_NSHIFT": "syscall",
+ "syscall.IN_CLASSD_HOST": "syscall",
+ "syscall.IN_CLASSD_NET": "syscall",
+ "syscall.IN_CLASSD_NSHIFT": "syscall",
+ "syscall.IN_CLOEXEC": "syscall",
+ "syscall.IN_CLOSE": "syscall",
+ "syscall.IN_CLOSE_NOWRITE": "syscall",
+ "syscall.IN_CLOSE_WRITE": "syscall",
+ "syscall.IN_CREATE": "syscall",
+ "syscall.IN_DELETE": "syscall",
+ "syscall.IN_DELETE_SELF": "syscall",
+ "syscall.IN_DONT_FOLLOW": "syscall",
+ "syscall.IN_EXCL_UNLINK": "syscall",
+ "syscall.IN_IGNORED": "syscall",
+ "syscall.IN_ISDIR": "syscall",
+ "syscall.IN_LINKLOCALNETNUM": "syscall",
+ "syscall.IN_LOOPBACKNET": "syscall",
+ "syscall.IN_MASK_ADD": "syscall",
+ "syscall.IN_MODIFY": "syscall",
+ "syscall.IN_MOVE": "syscall",
+ "syscall.IN_MOVED_FROM": "syscall",
+ "syscall.IN_MOVED_TO": "syscall",
+ "syscall.IN_MOVE_SELF": "syscall",
+ "syscall.IN_NONBLOCK": "syscall",
+ "syscall.IN_ONESHOT": "syscall",
+ "syscall.IN_ONLYDIR": "syscall",
+ "syscall.IN_OPEN": "syscall",
+ "syscall.IN_Q_OVERFLOW": "syscall",
+ "syscall.IN_RFC3021_HOST": "syscall",
+ "syscall.IN_RFC3021_MASK": "syscall",
+ "syscall.IN_RFC3021_NET": "syscall",
+ "syscall.IN_RFC3021_NSHIFT": "syscall",
+ "syscall.IN_UNMOUNT": "syscall",
+ "syscall.IOC_IN": "syscall",
+ "syscall.IOC_INOUT": "syscall",
+ "syscall.IOC_OUT": "syscall",
+ "syscall.IOC_WS2": "syscall",
+ "syscall.IPMreq": "syscall",
+ "syscall.IPMreqn": "syscall",
+ "syscall.IPPROTO_3PC": "syscall",
+ "syscall.IPPROTO_ADFS": "syscall",
+ "syscall.IPPROTO_AH": "syscall",
+ "syscall.IPPROTO_AHIP": "syscall",
+ "syscall.IPPROTO_APES": "syscall",
+ "syscall.IPPROTO_ARGUS": "syscall",
+ "syscall.IPPROTO_AX25": "syscall",
+ "syscall.IPPROTO_BHA": "syscall",
+ "syscall.IPPROTO_BLT": "syscall",
+ "syscall.IPPROTO_BRSATMON": "syscall",
+ "syscall.IPPROTO_CARP": "syscall",
+ "syscall.IPPROTO_CFTP": "syscall",
+ "syscall.IPPROTO_CHAOS": "syscall",
+ "syscall.IPPROTO_CMTP": "syscall",
+ "syscall.IPPROTO_COMP": "syscall",
+ "syscall.IPPROTO_CPHB": "syscall",
+ "syscall.IPPROTO_CPNX": "syscall",
+ "syscall.IPPROTO_DCCP": "syscall",
+ "syscall.IPPROTO_DDP": "syscall",
+ "syscall.IPPROTO_DGP": "syscall",
+ "syscall.IPPROTO_DIVERT": "syscall",
+ "syscall.IPPROTO_DONE": "syscall",
+ "syscall.IPPROTO_DSTOPTS": "syscall",
+ "syscall.IPPROTO_EGP": "syscall",
+ "syscall.IPPROTO_EMCON": "syscall",
+ "syscall.IPPROTO_ENCAP": "syscall",
+ "syscall.IPPROTO_EON": "syscall",
+ "syscall.IPPROTO_ESP": "syscall",
+ "syscall.IPPROTO_ETHERIP": "syscall",
+ "syscall.IPPROTO_FRAGMENT": "syscall",
+ "syscall.IPPROTO_GGP": "syscall",
+ "syscall.IPPROTO_GMTP": "syscall",
+ "syscall.IPPROTO_GRE": "syscall",
+ "syscall.IPPROTO_HELLO": "syscall",
+ "syscall.IPPROTO_HMP": "syscall",
+ "syscall.IPPROTO_HOPOPTS": "syscall",
+ "syscall.IPPROTO_ICMP": "syscall",
+ "syscall.IPPROTO_ICMPV6": "syscall",
+ "syscall.IPPROTO_IDP": "syscall",
+ "syscall.IPPROTO_IDPR": "syscall",
+ "syscall.IPPROTO_IDRP": "syscall",
+ "syscall.IPPROTO_IGMP": "syscall",
+ "syscall.IPPROTO_IGP": "syscall",
+ "syscall.IPPROTO_IGRP": "syscall",
+ "syscall.IPPROTO_IL": "syscall",
+ "syscall.IPPROTO_INLSP": "syscall",
+ "syscall.IPPROTO_INP": "syscall",
+ "syscall.IPPROTO_IP": "syscall",
+ "syscall.IPPROTO_IPCOMP": "syscall",
+ "syscall.IPPROTO_IPCV": "syscall",
+ "syscall.IPPROTO_IPEIP": "syscall",
+ "syscall.IPPROTO_IPIP": "syscall",
+ "syscall.IPPROTO_IPPC": "syscall",
+ "syscall.IPPROTO_IPV4": "syscall",
+ "syscall.IPPROTO_IPV6": "syscall",
+ "syscall.IPPROTO_IPV6_ICMP": "syscall",
+ "syscall.IPPROTO_IRTP": "syscall",
+ "syscall.IPPROTO_KRYPTOLAN": "syscall",
+ "syscall.IPPROTO_LARP": "syscall",
+ "syscall.IPPROTO_LEAF1": "syscall",
+ "syscall.IPPROTO_LEAF2": "syscall",
+ "syscall.IPPROTO_MAX": "syscall",
+ "syscall.IPPROTO_MAXID": "syscall",
+ "syscall.IPPROTO_MEAS": "syscall",
+ "syscall.IPPROTO_MH": "syscall",
+ "syscall.IPPROTO_MHRP": "syscall",
+ "syscall.IPPROTO_MICP": "syscall",
+ "syscall.IPPROTO_MOBILE": "syscall",
+ "syscall.IPPROTO_MPLS": "syscall",
+ "syscall.IPPROTO_MTP": "syscall",
+ "syscall.IPPROTO_MUX": "syscall",
+ "syscall.IPPROTO_ND": "syscall",
+ "syscall.IPPROTO_NHRP": "syscall",
+ "syscall.IPPROTO_NONE": "syscall",
+ "syscall.IPPROTO_NSP": "syscall",
+ "syscall.IPPROTO_NVPII": "syscall",
+ "syscall.IPPROTO_OLD_DIVERT": "syscall",
+ "syscall.IPPROTO_OSPFIGP": "syscall",
+ "syscall.IPPROTO_PFSYNC": "syscall",
+ "syscall.IPPROTO_PGM": "syscall",
+ "syscall.IPPROTO_PIGP": "syscall",
+ "syscall.IPPROTO_PIM": "syscall",
+ "syscall.IPPROTO_PRM": "syscall",
+ "syscall.IPPROTO_PUP": "syscall",
+ "syscall.IPPROTO_PVP": "syscall",
+ "syscall.IPPROTO_RAW": "syscall",
+ "syscall.IPPROTO_RCCMON": "syscall",
+ "syscall.IPPROTO_RDP": "syscall",
+ "syscall.IPPROTO_ROUTING": "syscall",
+ "syscall.IPPROTO_RSVP": "syscall",
+ "syscall.IPPROTO_RVD": "syscall",
+ "syscall.IPPROTO_SATEXPAK": "syscall",
+ "syscall.IPPROTO_SATMON": "syscall",
+ "syscall.IPPROTO_SCCSP": "syscall",
+ "syscall.IPPROTO_SCTP": "syscall",
+ "syscall.IPPROTO_SDRP": "syscall",
+ "syscall.IPPROTO_SEND": "syscall",
+ "syscall.IPPROTO_SEP": "syscall",
+ "syscall.IPPROTO_SKIP": "syscall",
+ "syscall.IPPROTO_SPACER": "syscall",
+ "syscall.IPPROTO_SRPC": "syscall",
+ "syscall.IPPROTO_ST": "syscall",
+ "syscall.IPPROTO_SVMTP": "syscall",
+ "syscall.IPPROTO_SWIPE": "syscall",
+ "syscall.IPPROTO_TCF": "syscall",
+ "syscall.IPPROTO_TCP": "syscall",
+ "syscall.IPPROTO_TLSP": "syscall",
+ "syscall.IPPROTO_TP": "syscall",
+ "syscall.IPPROTO_TPXX": "syscall",
+ "syscall.IPPROTO_TRUNK1": "syscall",
+ "syscall.IPPROTO_TRUNK2": "syscall",
+ "syscall.IPPROTO_TTP": "syscall",
+ "syscall.IPPROTO_UDP": "syscall",
+ "syscall.IPPROTO_UDPLITE": "syscall",
+ "syscall.IPPROTO_VINES": "syscall",
+ "syscall.IPPROTO_VISA": "syscall",
+ "syscall.IPPROTO_VMTP": "syscall",
+ "syscall.IPPROTO_VRRP": "syscall",
+ "syscall.IPPROTO_WBEXPAK": "syscall",
+ "syscall.IPPROTO_WBMON": "syscall",
+ "syscall.IPPROTO_WSN": "syscall",
+ "syscall.IPPROTO_XNET": "syscall",
+ "syscall.IPPROTO_XTP": "syscall",
+ "syscall.IPV6_2292DSTOPTS": "syscall",
+ "syscall.IPV6_2292HOPLIMIT": "syscall",
+ "syscall.IPV6_2292HOPOPTS": "syscall",
+ "syscall.IPV6_2292NEXTHOP": "syscall",
+ "syscall.IPV6_2292PKTINFO": "syscall",
+ "syscall.IPV6_2292PKTOPTIONS": "syscall",
+ "syscall.IPV6_2292RTHDR": "syscall",
+ "syscall.IPV6_ADDRFORM": "syscall",
+ "syscall.IPV6_ADD_MEMBERSHIP": "syscall",
+ "syscall.IPV6_AUTHHDR": "syscall",
+ "syscall.IPV6_AUTH_LEVEL": "syscall",
+ "syscall.IPV6_AUTOFLOWLABEL": "syscall",
+ "syscall.IPV6_BINDANY": "syscall",
+ "syscall.IPV6_BINDV6ONLY": "syscall",
+ "syscall.IPV6_BOUND_IF": "syscall",
+ "syscall.IPV6_CHECKSUM": "syscall",
+ "syscall.IPV6_DEFAULT_MULTICAST_HOPS": "syscall",
+ "syscall.IPV6_DEFAULT_MULTICAST_LOOP": "syscall",
+ "syscall.IPV6_DEFHLIM": "syscall",
+ "syscall.IPV6_DONTFRAG": "syscall",
+ "syscall.IPV6_DROP_MEMBERSHIP": "syscall",
+ "syscall.IPV6_DSTOPTS": "syscall",
+ "syscall.IPV6_ESP_NETWORK_LEVEL": "syscall",
+ "syscall.IPV6_ESP_TRANS_LEVEL": "syscall",
+ "syscall.IPV6_FAITH": "syscall",
+ "syscall.IPV6_FLOWINFO_MASK": "syscall",
+ "syscall.IPV6_FLOWLABEL_MASK": "syscall",
+ "syscall.IPV6_FRAGTTL": "syscall",
+ "syscall.IPV6_FW_ADD": "syscall",
+ "syscall.IPV6_FW_DEL": "syscall",
+ "syscall.IPV6_FW_FLUSH": "syscall",
+ "syscall.IPV6_FW_GET": "syscall",
+ "syscall.IPV6_FW_ZERO": "syscall",
+ "syscall.IPV6_HLIMDEC": "syscall",
+ "syscall.IPV6_HOPLIMIT": "syscall",
+ "syscall.IPV6_HOPOPTS": "syscall",
+ "syscall.IPV6_IPCOMP_LEVEL": "syscall",
+ "syscall.IPV6_IPSEC_POLICY": "syscall",
+ "syscall.IPV6_JOIN_ANYCAST": "syscall",
+ "syscall.IPV6_JOIN_GROUP": "syscall",
+ "syscall.IPV6_LEAVE_ANYCAST": "syscall",
+ "syscall.IPV6_LEAVE_GROUP": "syscall",
+ "syscall.IPV6_MAXHLIM": "syscall",
+ "syscall.IPV6_MAXOPTHDR": "syscall",
+ "syscall.IPV6_MAXPACKET": "syscall",
+ "syscall.IPV6_MAX_GROUP_SRC_FILTER": "syscall",
+ "syscall.IPV6_MAX_MEMBERSHIPS": "syscall",
+ "syscall.IPV6_MAX_SOCK_SRC_FILTER": "syscall",
+ "syscall.IPV6_MIN_MEMBERSHIPS": "syscall",
+ "syscall.IPV6_MMTU": "syscall",
+ "syscall.IPV6_MSFILTER": "syscall",
+ "syscall.IPV6_MTU": "syscall",
+ "syscall.IPV6_MTU_DISCOVER": "syscall",
+ "syscall.IPV6_MULTICAST_HOPS": "syscall",
+ "syscall.IPV6_MULTICAST_IF": "syscall",
+ "syscall.IPV6_MULTICAST_LOOP": "syscall",
+ "syscall.IPV6_NEXTHOP": "syscall",
+ "syscall.IPV6_OPTIONS": "syscall",
+ "syscall.IPV6_PATHMTU": "syscall",
+ "syscall.IPV6_PIPEX": "syscall",
+ "syscall.IPV6_PKTINFO": "syscall",
+ "syscall.IPV6_PMTUDISC_DO": "syscall",
+ "syscall.IPV6_PMTUDISC_DONT": "syscall",
+ "syscall.IPV6_PMTUDISC_PROBE": "syscall",
+ "syscall.IPV6_PMTUDISC_WANT": "syscall",
+ "syscall.IPV6_PORTRANGE": "syscall",
+ "syscall.IPV6_PORTRANGE_DEFAULT": "syscall",
+ "syscall.IPV6_PORTRANGE_HIGH": "syscall",
+ "syscall.IPV6_PORTRANGE_LOW": "syscall",
+ "syscall.IPV6_PREFER_TEMPADDR": "syscall",
+ "syscall.IPV6_RECVDSTOPTS": "syscall",
+ "syscall.IPV6_RECVERR": "syscall",
+ "syscall.IPV6_RECVHOPLIMIT": "syscall",
+ "syscall.IPV6_RECVHOPOPTS": "syscall",
+ "syscall.IPV6_RECVPATHMTU": "syscall",
+ "syscall.IPV6_RECVPKTINFO": "syscall",
+ "syscall.IPV6_RECVRTHDR": "syscall",
+ "syscall.IPV6_RECVTCLASS": "syscall",
+ "syscall.IPV6_ROUTER_ALERT": "syscall",
+ "syscall.IPV6_RTABLE": "syscall",
+ "syscall.IPV6_RTHDR": "syscall",
+ "syscall.IPV6_RTHDRDSTOPTS": "syscall",
+ "syscall.IPV6_RTHDR_LOOSE": "syscall",
+ "syscall.IPV6_RTHDR_STRICT": "syscall",
+ "syscall.IPV6_RTHDR_TYPE_0": "syscall",
+ "syscall.IPV6_RXDSTOPTS": "syscall",
+ "syscall.IPV6_RXHOPOPTS": "syscall",
+ "syscall.IPV6_SOCKOPT_RESERVED1": "syscall",
+ "syscall.IPV6_TCLASS": "syscall",
+ "syscall.IPV6_UNICAST_HOPS": "syscall",
+ "syscall.IPV6_USE_MIN_MTU": "syscall",
+ "syscall.IPV6_V6ONLY": "syscall",
+ "syscall.IPV6_VERSION": "syscall",
+ "syscall.IPV6_VERSION_MASK": "syscall",
+ "syscall.IPV6_XFRM_POLICY": "syscall",
+ "syscall.IP_ADD_MEMBERSHIP": "syscall",
+ "syscall.IP_ADD_SOURCE_MEMBERSHIP": "syscall",
+ "syscall.IP_AUTH_LEVEL": "syscall",
+ "syscall.IP_BINDANY": "syscall",
+ "syscall.IP_BLOCK_SOURCE": "syscall",
+ "syscall.IP_BOUND_IF": "syscall",
+ "syscall.IP_DEFAULT_MULTICAST_LOOP": "syscall",
+ "syscall.IP_DEFAULT_MULTICAST_TTL": "syscall",
+ "syscall.IP_DF": "syscall",
+ "syscall.IP_DONTFRAG": "syscall",
+ "syscall.IP_DROP_MEMBERSHIP": "syscall",
+ "syscall.IP_DROP_SOURCE_MEMBERSHIP": "syscall",
+ "syscall.IP_DUMMYNET3": "syscall",
+ "syscall.IP_DUMMYNET_CONFIGURE": "syscall",
+ "syscall.IP_DUMMYNET_DEL": "syscall",
+ "syscall.IP_DUMMYNET_FLUSH": "syscall",
+ "syscall.IP_DUMMYNET_GET": "syscall",
+ "syscall.IP_EF": "syscall",
+ "syscall.IP_ERRORMTU": "syscall",
+ "syscall.IP_ESP_NETWORK_LEVEL": "syscall",
+ "syscall.IP_ESP_TRANS_LEVEL": "syscall",
+ "syscall.IP_FAITH": "syscall",
+ "syscall.IP_FREEBIND": "syscall",
+ "syscall.IP_FW3": "syscall",
+ "syscall.IP_FW_ADD": "syscall",
+ "syscall.IP_FW_DEL": "syscall",
+ "syscall.IP_FW_FLUSH": "syscall",
+ "syscall.IP_FW_GET": "syscall",
+ "syscall.IP_FW_NAT_CFG": "syscall",
+ "syscall.IP_FW_NAT_DEL": "syscall",
+ "syscall.IP_FW_NAT_GET_CONFIG": "syscall",
+ "syscall.IP_FW_NAT_GET_LOG": "syscall",
+ "syscall.IP_FW_RESETLOG": "syscall",
+ "syscall.IP_FW_TABLE_ADD": "syscall",
+ "syscall.IP_FW_TABLE_DEL": "syscall",
+ "syscall.IP_FW_TABLE_FLUSH": "syscall",
+ "syscall.IP_FW_TABLE_GETSIZE": "syscall",
+ "syscall.IP_FW_TABLE_LIST": "syscall",
+ "syscall.IP_FW_ZERO": "syscall",
+ "syscall.IP_HDRINCL": "syscall",
+ "syscall.IP_IPCOMP_LEVEL": "syscall",
+ "syscall.IP_IPSECFLOWINFO": "syscall",
+ "syscall.IP_IPSEC_LOCAL_AUTH": "syscall",
+ "syscall.IP_IPSEC_LOCAL_CRED": "syscall",
+ "syscall.IP_IPSEC_LOCAL_ID": "syscall",
+ "syscall.IP_IPSEC_POLICY": "syscall",
+ "syscall.IP_IPSEC_REMOTE_AUTH": "syscall",
+ "syscall.IP_IPSEC_REMOTE_CRED": "syscall",
+ "syscall.IP_IPSEC_REMOTE_ID": "syscall",
+ "syscall.IP_MAXPACKET": "syscall",
+ "syscall.IP_MAX_GROUP_SRC_FILTER": "syscall",
+ "syscall.IP_MAX_MEMBERSHIPS": "syscall",
+ "syscall.IP_MAX_SOCK_MUTE_FILTER": "syscall",
+ "syscall.IP_MAX_SOCK_SRC_FILTER": "syscall",
+ "syscall.IP_MAX_SOURCE_FILTER": "syscall",
+ "syscall.IP_MF": "syscall",
+ "syscall.IP_MINFRAGSIZE": "syscall",
+ "syscall.IP_MINTTL": "syscall",
+ "syscall.IP_MIN_MEMBERSHIPS": "syscall",
+ "syscall.IP_MSFILTER": "syscall",
+ "syscall.IP_MSS": "syscall",
+ "syscall.IP_MTU": "syscall",
+ "syscall.IP_MTU_DISCOVER": "syscall",
+ "syscall.IP_MULTICAST_IF": "syscall",
+ "syscall.IP_MULTICAST_IFINDEX": "syscall",
+ "syscall.IP_MULTICAST_LOOP": "syscall",
+ "syscall.IP_MULTICAST_TTL": "syscall",
+ "syscall.IP_MULTICAST_VIF": "syscall",
+ "syscall.IP_NAT__XXX": "syscall",
+ "syscall.IP_OFFMASK": "syscall",
+ "syscall.IP_OLD_FW_ADD": "syscall",
+ "syscall.IP_OLD_FW_DEL": "syscall",
+ "syscall.IP_OLD_FW_FLUSH": "syscall",
+ "syscall.IP_OLD_FW_GET": "syscall",
+ "syscall.IP_OLD_FW_RESETLOG": "syscall",
+ "syscall.IP_OLD_FW_ZERO": "syscall",
+ "syscall.IP_ONESBCAST": "syscall",
+ "syscall.IP_OPTIONS": "syscall",
+ "syscall.IP_ORIGDSTADDR": "syscall",
+ "syscall.IP_PASSSEC": "syscall",
+ "syscall.IP_PIPEX": "syscall",
+ "syscall.IP_PKTINFO": "syscall",
+ "syscall.IP_PKTOPTIONS": "syscall",
+ "syscall.IP_PMTUDISC": "syscall",
+ "syscall.IP_PMTUDISC_DO": "syscall",
+ "syscall.IP_PMTUDISC_DONT": "syscall",
+ "syscall.IP_PMTUDISC_PROBE": "syscall",
+ "syscall.IP_PMTUDISC_WANT": "syscall",
+ "syscall.IP_PORTRANGE": "syscall",
+ "syscall.IP_PORTRANGE_DEFAULT": "syscall",
+ "syscall.IP_PORTRANGE_HIGH": "syscall",
+ "syscall.IP_PORTRANGE_LOW": "syscall",
+ "syscall.IP_RECVDSTADDR": "syscall",
+ "syscall.IP_RECVDSTPORT": "syscall",
+ "syscall.IP_RECVERR": "syscall",
+ "syscall.IP_RECVIF": "syscall",
+ "syscall.IP_RECVOPTS": "syscall",
+ "syscall.IP_RECVORIGDSTADDR": "syscall",
+ "syscall.IP_RECVPKTINFO": "syscall",
+ "syscall.IP_RECVRETOPTS": "syscall",
+ "syscall.IP_RECVRTABLE": "syscall",
+ "syscall.IP_RECVTOS": "syscall",
+ "syscall.IP_RECVTTL": "syscall",
+ "syscall.IP_RETOPTS": "syscall",
+ "syscall.IP_RF": "syscall",
+ "syscall.IP_ROUTER_ALERT": "syscall",
+ "syscall.IP_RSVP_OFF": "syscall",
+ "syscall.IP_RSVP_ON": "syscall",
+ "syscall.IP_RSVP_VIF_OFF": "syscall",
+ "syscall.IP_RSVP_VIF_ON": "syscall",
+ "syscall.IP_RTABLE": "syscall",
+ "syscall.IP_SENDSRCADDR": "syscall",
+ "syscall.IP_STRIPHDR": "syscall",
+ "syscall.IP_TOS": "syscall",
+ "syscall.IP_TRAFFIC_MGT_BACKGROUND": "syscall",
+ "syscall.IP_TRANSPARENT": "syscall",
+ "syscall.IP_TTL": "syscall",
+ "syscall.IP_UNBLOCK_SOURCE": "syscall",
+ "syscall.IP_XFRM_POLICY": "syscall",
+ "syscall.IPv6MTUInfo": "syscall",
+ "syscall.IPv6Mreq": "syscall",
+ "syscall.ISIG": "syscall",
+ "syscall.ISTRIP": "syscall",
+ "syscall.IUCLC": "syscall",
+ "syscall.IUTF8": "syscall",
+ "syscall.IXANY": "syscall",
+ "syscall.IXOFF": "syscall",
+ "syscall.IXON": "syscall",
+ "syscall.IfAddrmsg": "syscall",
+ "syscall.IfAnnounceMsghdr": "syscall",
+ "syscall.IfData": "syscall",
+ "syscall.IfInfomsg": "syscall",
+ "syscall.IfMsghdr": "syscall",
+ "syscall.IfaMsghdr": "syscall",
+ "syscall.IfmaMsghdr": "syscall",
+ "syscall.IfmaMsghdr2": "syscall",
+ "syscall.ImplementsGetwd": "syscall",
+ "syscall.Inet4Pktinfo": "syscall",
+ "syscall.Inet6Pktinfo": "syscall",
+ "syscall.InotifyAddWatch": "syscall",
+ "syscall.InotifyEvent": "syscall",
+ "syscall.InotifyInit": "syscall",
+ "syscall.InotifyInit1": "syscall",
+ "syscall.InotifyRmWatch": "syscall",
+ "syscall.InterfaceAddrMessage": "syscall",
+ "syscall.InterfaceAnnounceMessage": "syscall",
+ "syscall.InterfaceInfo": "syscall",
+ "syscall.InterfaceMessage": "syscall",
+ "syscall.InterfaceMulticastAddrMessage": "syscall",
+ "syscall.InvalidHandle": "syscall",
+ "syscall.Ioperm": "syscall",
+ "syscall.Iopl": "syscall",
+ "syscall.Iovec": "syscall",
+ "syscall.IpAdapterInfo": "syscall",
+ "syscall.IpAddrString": "syscall",
+ "syscall.IpAddressString": "syscall",
+ "syscall.IpMaskString": "syscall",
+ "syscall.Issetugid": "syscall",
+ "syscall.KEY_ALL_ACCESS": "syscall",
+ "syscall.KEY_CREATE_LINK": "syscall",
+ "syscall.KEY_CREATE_SUB_KEY": "syscall",
+ "syscall.KEY_ENUMERATE_SUB_KEYS": "syscall",
+ "syscall.KEY_EXECUTE": "syscall",
+ "syscall.KEY_NOTIFY": "syscall",
+ "syscall.KEY_QUERY_VALUE": "syscall",
+ "syscall.KEY_READ": "syscall",
+ "syscall.KEY_SET_VALUE": "syscall",
+ "syscall.KEY_WOW64_32KEY": "syscall",
+ "syscall.KEY_WOW64_64KEY": "syscall",
+ "syscall.KEY_WRITE": "syscall",
+ "syscall.Kevent": "syscall",
+ "syscall.Kevent_t": "syscall",
+ "syscall.Kill": "syscall",
+ "syscall.Klogctl": "syscall",
+ "syscall.Kqueue": "syscall",
+ "syscall.LANG_ENGLISH": "syscall",
+ "syscall.LAYERED_PROTOCOL": "syscall",
+ "syscall.LCNT_OVERLOAD_FLUSH": "syscall",
+ "syscall.LINUX_REBOOT_CMD_CAD_OFF": "syscall",
+ "syscall.LINUX_REBOOT_CMD_CAD_ON": "syscall",
+ "syscall.LINUX_REBOOT_CMD_HALT": "syscall",
+ "syscall.LINUX_REBOOT_CMD_KEXEC": "syscall",
+ "syscall.LINUX_REBOOT_CMD_POWER_OFF": "syscall",
+ "syscall.LINUX_REBOOT_CMD_RESTART": "syscall",
+ "syscall.LINUX_REBOOT_CMD_RESTART2": "syscall",
+ "syscall.LINUX_REBOOT_CMD_SW_SUSPEND": "syscall",
+ "syscall.LINUX_REBOOT_MAGIC1": "syscall",
+ "syscall.LINUX_REBOOT_MAGIC2": "syscall",
+ "syscall.LOCK_EX": "syscall",
+ "syscall.LOCK_NB": "syscall",
+ "syscall.LOCK_SH": "syscall",
+ "syscall.LOCK_UN": "syscall",
+ "syscall.LazyDLL": "syscall",
+ "syscall.LazyProc": "syscall",
+ "syscall.Lchown": "syscall",
+ "syscall.Linger": "syscall",
+ "syscall.Link": "syscall",
+ "syscall.Listen": "syscall",
+ "syscall.Listxattr": "syscall",
+ "syscall.LoadCancelIoEx": "syscall",
+ "syscall.LoadConnectEx": "syscall",
+ "syscall.LoadDLL": "syscall",
+ "syscall.LoadGetAddrInfo": "syscall",
+ "syscall.LoadLibrary": "syscall",
+ "syscall.LoadSetFileCompletionNotificationModes": "syscall",
+ "syscall.LocalFree": "syscall",
+ "syscall.Log2phys_t": "syscall",
+ "syscall.LookupAccountName": "syscall",
+ "syscall.LookupAccountSid": "syscall",
+ "syscall.LookupSID": "syscall",
+ "syscall.LsfJump": "syscall",
+ "syscall.LsfSocket": "syscall",
+ "syscall.LsfStmt": "syscall",
+ "syscall.Lstat": "syscall",
+ "syscall.MADV_AUTOSYNC": "syscall",
+ "syscall.MADV_CAN_REUSE": "syscall",
+ "syscall.MADV_CORE": "syscall",
+ "syscall.MADV_DOFORK": "syscall",
+ "syscall.MADV_DONTFORK": "syscall",
+ "syscall.MADV_DONTNEED": "syscall",
+ "syscall.MADV_FREE": "syscall",
+ "syscall.MADV_FREE_REUSABLE": "syscall",
+ "syscall.MADV_FREE_REUSE": "syscall",
+ "syscall.MADV_HUGEPAGE": "syscall",
+ "syscall.MADV_HWPOISON": "syscall",
+ "syscall.MADV_MERGEABLE": "syscall",
+ "syscall.MADV_NOCORE": "syscall",
+ "syscall.MADV_NOHUGEPAGE": "syscall",
+ "syscall.MADV_NORMAL": "syscall",
+ "syscall.MADV_NOSYNC": "syscall",
+ "syscall.MADV_PROTECT": "syscall",
+ "syscall.MADV_RANDOM": "syscall",
+ "syscall.MADV_REMOVE": "syscall",
+ "syscall.MADV_SEQUENTIAL": "syscall",
+ "syscall.MADV_UNMERGEABLE": "syscall",
+ "syscall.MADV_WILLNEED": "syscall",
+ "syscall.MADV_ZERO_WIRED_PAGES": "syscall",
+ "syscall.MAP_32BIT": "syscall",
+ "syscall.MAP_ANON": "syscall",
+ "syscall.MAP_ANONYMOUS": "syscall",
+ "syscall.MAP_COPY": "syscall",
+ "syscall.MAP_DENYWRITE": "syscall",
+ "syscall.MAP_EXECUTABLE": "syscall",
+ "syscall.MAP_FILE": "syscall",
+ "syscall.MAP_FIXED": "syscall",
+ "syscall.MAP_GROWSDOWN": "syscall",
+ "syscall.MAP_HASSEMAPHORE": "syscall",
+ "syscall.MAP_HUGETLB": "syscall",
+ "syscall.MAP_JIT": "syscall",
+ "syscall.MAP_LOCKED": "syscall",
+ "syscall.MAP_NOCACHE": "syscall",
+ "syscall.MAP_NOCORE": "syscall",
+ "syscall.MAP_NOEXTEND": "syscall",
+ "syscall.MAP_NONBLOCK": "syscall",
+ "syscall.MAP_NORESERVE": "syscall",
+ "syscall.MAP_NOSYNC": "syscall",
+ "syscall.MAP_POPULATE": "syscall",
+ "syscall.MAP_PREFAULT_READ": "syscall",
+ "syscall.MAP_PRIVATE": "syscall",
+ "syscall.MAP_RENAME": "syscall",
+ "syscall.MAP_RESERVED0080": "syscall",
+ "syscall.MAP_RESERVED0100": "syscall",
+ "syscall.MAP_SHARED": "syscall",
+ "syscall.MAP_STACK": "syscall",
+ "syscall.MAP_TYPE": "syscall",
+ "syscall.MAXLEN_IFDESCR": "syscall",
+ "syscall.MAXLEN_PHYSADDR": "syscall",
+ "syscall.MAX_ADAPTER_ADDRESS_LENGTH": "syscall",
+ "syscall.MAX_ADAPTER_DESCRIPTION_LENGTH": "syscall",
+ "syscall.MAX_ADAPTER_NAME_LENGTH": "syscall",
+ "syscall.MAX_COMPUTERNAME_LENGTH": "syscall",
+ "syscall.MAX_INTERFACE_NAME_LEN": "syscall",
+ "syscall.MAX_LONG_PATH": "syscall",
+ "syscall.MAX_PATH": "syscall",
+ "syscall.MAX_PROTOCOL_CHAIN": "syscall",
+ "syscall.MCL_CURRENT": "syscall",
+ "syscall.MCL_FUTURE": "syscall",
+ "syscall.MNT_DETACH": "syscall",
+ "syscall.MNT_EXPIRE": "syscall",
+ "syscall.MNT_FORCE": "syscall",
+ "syscall.MSG_BCAST": "syscall",
+ "syscall.MSG_CMSG_CLOEXEC": "syscall",
+ "syscall.MSG_COMPAT": "syscall",
+ "syscall.MSG_CONFIRM": "syscall",
+ "syscall.MSG_CONTROLMBUF": "syscall",
+ "syscall.MSG_CTRUNC": "syscall",
+ "syscall.MSG_DONTROUTE": "syscall",
+ "syscall.MSG_DONTWAIT": "syscall",
+ "syscall.MSG_EOF": "syscall",
+ "syscall.MSG_EOR": "syscall",
+ "syscall.MSG_ERRQUEUE": "syscall",
+ "syscall.MSG_FASTOPEN": "syscall",
+ "syscall.MSG_FIN": "syscall",
+ "syscall.MSG_FLUSH": "syscall",
+ "syscall.MSG_HAVEMORE": "syscall",
+ "syscall.MSG_HOLD": "syscall",
+ "syscall.MSG_IOVUSRSPACE": "syscall",
+ "syscall.MSG_LENUSRSPACE": "syscall",
+ "syscall.MSG_MCAST": "syscall",
+ "syscall.MSG_MORE": "syscall",
+ "syscall.MSG_NAMEMBUF": "syscall",
+ "syscall.MSG_NBIO": "syscall",
+ "syscall.MSG_NEEDSA": "syscall",
+ "syscall.MSG_NOSIGNAL": "syscall",
+ "syscall.MSG_NOTIFICATION": "syscall",
+ "syscall.MSG_OOB": "syscall",
+ "syscall.MSG_PEEK": "syscall",
+ "syscall.MSG_PROXY": "syscall",
+ "syscall.MSG_RCVMORE": "syscall",
+ "syscall.MSG_RST": "syscall",
+ "syscall.MSG_SEND": "syscall",
+ "syscall.MSG_SYN": "syscall",
+ "syscall.MSG_TRUNC": "syscall",
+ "syscall.MSG_TRYHARD": "syscall",
+ "syscall.MSG_USERFLAGS": "syscall",
+ "syscall.MSG_WAITALL": "syscall",
+ "syscall.MSG_WAITFORONE": "syscall",
+ "syscall.MSG_WAITSTREAM": "syscall",
+ "syscall.MS_ACTIVE": "syscall",
+ "syscall.MS_ASYNC": "syscall",
+ "syscall.MS_BIND": "syscall",
+ "syscall.MS_DEACTIVATE": "syscall",
+ "syscall.MS_DIRSYNC": "syscall",
+ "syscall.MS_INVALIDATE": "syscall",
+ "syscall.MS_I_VERSION": "syscall",
+ "syscall.MS_KERNMOUNT": "syscall",
+ "syscall.MS_KILLPAGES": "syscall",
+ "syscall.MS_MANDLOCK": "syscall",
+ "syscall.MS_MGC_MSK": "syscall",
+ "syscall.MS_MGC_VAL": "syscall",
+ "syscall.MS_MOVE": "syscall",
+ "syscall.MS_NOATIME": "syscall",
+ "syscall.MS_NODEV": "syscall",
+ "syscall.MS_NODIRATIME": "syscall",
+ "syscall.MS_NOEXEC": "syscall",
+ "syscall.MS_NOSUID": "syscall",
+ "syscall.MS_NOUSER": "syscall",
+ "syscall.MS_POSIXACL": "syscall",
+ "syscall.MS_PRIVATE": "syscall",
+ "syscall.MS_RDONLY": "syscall",
+ "syscall.MS_REC": "syscall",
+ "syscall.MS_RELATIME": "syscall",
+ "syscall.MS_REMOUNT": "syscall",
+ "syscall.MS_RMT_MASK": "syscall",
+ "syscall.MS_SHARED": "syscall",
+ "syscall.MS_SILENT": "syscall",
+ "syscall.MS_SLAVE": "syscall",
+ "syscall.MS_STRICTATIME": "syscall",
+ "syscall.MS_SYNC": "syscall",
+ "syscall.MS_SYNCHRONOUS": "syscall",
+ "syscall.MS_UNBINDABLE": "syscall",
+ "syscall.Madvise": "syscall",
+ "syscall.MapViewOfFile": "syscall",
+ "syscall.MaxTokenInfoClass": "syscall",
+ "syscall.Mclpool": "syscall",
+ "syscall.MibIfRow": "syscall",
+ "syscall.Mkdir": "syscall",
+ "syscall.Mkdirat": "syscall",
+ "syscall.Mkfifo": "syscall",
+ "syscall.Mknod": "syscall",
+ "syscall.Mknodat": "syscall",
+ "syscall.Mlock": "syscall",
+ "syscall.Mlockall": "syscall",
+ "syscall.Mmap": "syscall",
+ "syscall.Mount": "syscall",
+ "syscall.MoveFile": "syscall",
+ "syscall.Mprotect": "syscall",
+ "syscall.Msghdr": "syscall",
+ "syscall.Munlock": "syscall",
+ "syscall.Munlockall": "syscall",
+ "syscall.Munmap": "syscall",
+ "syscall.MustLoadDLL": "syscall",
+ "syscall.NAME_MAX": "syscall",
+ "syscall.NETLINK_ADD_MEMBERSHIP": "syscall",
+ "syscall.NETLINK_AUDIT": "syscall",
+ "syscall.NETLINK_BROADCAST_ERROR": "syscall",
+ "syscall.NETLINK_CONNECTOR": "syscall",
+ "syscall.NETLINK_DNRTMSG": "syscall",
+ "syscall.NETLINK_DROP_MEMBERSHIP": "syscall",
+ "syscall.NETLINK_ECRYPTFS": "syscall",
+ "syscall.NETLINK_FIB_LOOKUP": "syscall",
+ "syscall.NETLINK_FIREWALL": "syscall",
+ "syscall.NETLINK_GENERIC": "syscall",
+ "syscall.NETLINK_INET_DIAG": "syscall",
+ "syscall.NETLINK_IP6_FW": "syscall",
+ "syscall.NETLINK_ISCSI": "syscall",
+ "syscall.NETLINK_KOBJECT_UEVENT": "syscall",
+ "syscall.NETLINK_NETFILTER": "syscall",
+ "syscall.NETLINK_NFLOG": "syscall",
+ "syscall.NETLINK_NO_ENOBUFS": "syscall",
+ "syscall.NETLINK_PKTINFO": "syscall",
+ "syscall.NETLINK_RDMA": "syscall",
+ "syscall.NETLINK_ROUTE": "syscall",
+ "syscall.NETLINK_SCSITRANSPORT": "syscall",
+ "syscall.NETLINK_SELINUX": "syscall",
+ "syscall.NETLINK_UNUSED": "syscall",
+ "syscall.NETLINK_USERSOCK": "syscall",
+ "syscall.NETLINK_XFRM": "syscall",
+ "syscall.NET_RT_DUMP": "syscall",
+ "syscall.NET_RT_DUMP2": "syscall",
+ "syscall.NET_RT_FLAGS": "syscall",
+ "syscall.NET_RT_IFLIST": "syscall",
+ "syscall.NET_RT_IFLIST2": "syscall",
+ "syscall.NET_RT_IFLISTL": "syscall",
+ "syscall.NET_RT_IFMALIST": "syscall",
+ "syscall.NET_RT_MAXID": "syscall",
+ "syscall.NET_RT_OIFLIST": "syscall",
+ "syscall.NET_RT_OOIFLIST": "syscall",
+ "syscall.NET_RT_STAT": "syscall",
+ "syscall.NET_RT_STATS": "syscall",
+ "syscall.NET_RT_TABLE": "syscall",
+ "syscall.NET_RT_TRASH": "syscall",
+ "syscall.NLA_ALIGNTO": "syscall",
+ "syscall.NLA_F_NESTED": "syscall",
+ "syscall.NLA_F_NET_BYTEORDER": "syscall",
+ "syscall.NLA_HDRLEN": "syscall",
+ "syscall.NLMSG_ALIGNTO": "syscall",
+ "syscall.NLMSG_DONE": "syscall",
+ "syscall.NLMSG_ERROR": "syscall",
+ "syscall.NLMSG_HDRLEN": "syscall",
+ "syscall.NLMSG_MIN_TYPE": "syscall",
+ "syscall.NLMSG_NOOP": "syscall",
+ "syscall.NLMSG_OVERRUN": "syscall",
+ "syscall.NLM_F_ACK": "syscall",
+ "syscall.NLM_F_APPEND": "syscall",
+ "syscall.NLM_F_ATOMIC": "syscall",
+ "syscall.NLM_F_CREATE": "syscall",
+ "syscall.NLM_F_DUMP": "syscall",
+ "syscall.NLM_F_ECHO": "syscall",
+ "syscall.NLM_F_EXCL": "syscall",
+ "syscall.NLM_F_MATCH": "syscall",
+ "syscall.NLM_F_MULTI": "syscall",
+ "syscall.NLM_F_REPLACE": "syscall",
+ "syscall.NLM_F_REQUEST": "syscall",
+ "syscall.NLM_F_ROOT": "syscall",
+ "syscall.NOFLSH": "syscall",
+ "syscall.NOTE_ABSOLUTE": "syscall",
+ "syscall.NOTE_ATTRIB": "syscall",
+ "syscall.NOTE_CHILD": "syscall",
+ "syscall.NOTE_DELETE": "syscall",
+ "syscall.NOTE_EOF": "syscall",
+ "syscall.NOTE_EXEC": "syscall",
+ "syscall.NOTE_EXIT": "syscall",
+ "syscall.NOTE_EXITSTATUS": "syscall",
+ "syscall.NOTE_EXTEND": "syscall",
+ "syscall.NOTE_FFAND": "syscall",
+ "syscall.NOTE_FFCOPY": "syscall",
+ "syscall.NOTE_FFCTRLMASK": "syscall",
+ "syscall.NOTE_FFLAGSMASK": "syscall",
+ "syscall.NOTE_FFNOP": "syscall",
+ "syscall.NOTE_FFOR": "syscall",
+ "syscall.NOTE_FORK": "syscall",
+ "syscall.NOTE_LINK": "syscall",
+ "syscall.NOTE_LOWAT": "syscall",
+ "syscall.NOTE_NONE": "syscall",
+ "syscall.NOTE_NSECONDS": "syscall",
+ "syscall.NOTE_PCTRLMASK": "syscall",
+ "syscall.NOTE_PDATAMASK": "syscall",
+ "syscall.NOTE_REAP": "syscall",
+ "syscall.NOTE_RENAME": "syscall",
+ "syscall.NOTE_RESOURCEEND": "syscall",
+ "syscall.NOTE_REVOKE": "syscall",
+ "syscall.NOTE_SECONDS": "syscall",
+ "syscall.NOTE_SIGNAL": "syscall",
+ "syscall.NOTE_TRACK": "syscall",
+ "syscall.NOTE_TRACKERR": "syscall",
+ "syscall.NOTE_TRIGGER": "syscall",
+ "syscall.NOTE_TRUNCATE": "syscall",
+ "syscall.NOTE_USECONDS": "syscall",
+ "syscall.NOTE_VM_ERROR": "syscall",
+ "syscall.NOTE_VM_PRESSURE": "syscall",
+ "syscall.NOTE_VM_PRESSURE_SUDDEN_TERMINATE": "syscall",
+ "syscall.NOTE_VM_PRESSURE_TERMINATE": "syscall",
+ "syscall.NOTE_WRITE": "syscall",
+ "syscall.NameCanonical": "syscall",
+ "syscall.NameCanonicalEx": "syscall",
+ "syscall.NameDisplay": "syscall",
+ "syscall.NameDnsDomain": "syscall",
+ "syscall.NameFullyQualifiedDN": "syscall",
+ "syscall.NameSamCompatible": "syscall",
+ "syscall.NameServicePrincipal": "syscall",
+ "syscall.NameUniqueId": "syscall",
+ "syscall.NameUnknown": "syscall",
+ "syscall.NameUserPrincipal": "syscall",
+ "syscall.Nanosleep": "syscall",
+ "syscall.NetApiBufferFree": "syscall",
+ "syscall.NetGetJoinInformation": "syscall",
+ "syscall.NetSetupDomainName": "syscall",
+ "syscall.NetSetupUnjoined": "syscall",
+ "syscall.NetSetupUnknownStatus": "syscall",
+ "syscall.NetSetupWorkgroupName": "syscall",
+ "syscall.NetUserGetInfo": "syscall",
+ "syscall.NetlinkMessage": "syscall",
+ "syscall.NetlinkRIB": "syscall",
+ "syscall.NetlinkRouteAttr": "syscall",
+ "syscall.NetlinkRouteRequest": "syscall",
+ "syscall.NewCallback": "syscall",
+ "syscall.NewLazyDLL": "syscall",
+ "syscall.NlAttr": "syscall",
+ "syscall.NlMsgerr": "syscall",
+ "syscall.NlMsghdr": "syscall",
+ "syscall.NsecToFiletime": "syscall",
+ "syscall.NsecToTimespec": "syscall",
+ "syscall.NsecToTimeval": "syscall",
+ "syscall.Ntohs": "syscall",
+ "syscall.OCRNL": "syscall",
+ "syscall.OFDEL": "syscall",
+ "syscall.OFILL": "syscall",
+ "syscall.OFIOGETBMAP": "syscall",
+ "syscall.OID_PKIX_KP_SERVER_AUTH": "syscall",
+ "syscall.OID_SERVER_GATED_CRYPTO": "syscall",
+ "syscall.OID_SGC_NETSCAPE": "syscall",
+ "syscall.OLCUC": "syscall",
+ "syscall.ONLCR": "syscall",
+ "syscall.ONLRET": "syscall",
+ "syscall.ONOCR": "syscall",
+ "syscall.ONOEOT": "syscall",
+ "syscall.OPEN_ALWAYS": "syscall",
+ "syscall.OPEN_EXISTING": "syscall",
+ "syscall.OPOST": "syscall",
+ "syscall.O_ACCMODE": "syscall",
+ "syscall.O_ALERT": "syscall",
+ "syscall.O_ALT_IO": "syscall",
+ "syscall.O_APPEND": "syscall",
+ "syscall.O_ASYNC": "syscall",
+ "syscall.O_CLOEXEC": "syscall",
+ "syscall.O_CREAT": "syscall",
+ "syscall.O_DIRECT": "syscall",
+ "syscall.O_DIRECTORY": "syscall",
+ "syscall.O_DSYNC": "syscall",
+ "syscall.O_EVTONLY": "syscall",
+ "syscall.O_EXCL": "syscall",
+ "syscall.O_EXEC": "syscall",
+ "syscall.O_EXLOCK": "syscall",
+ "syscall.O_FSYNC": "syscall",
+ "syscall.O_LARGEFILE": "syscall",
+ "syscall.O_NDELAY": "syscall",
+ "syscall.O_NOATIME": "syscall",
+ "syscall.O_NOCTTY": "syscall",
+ "syscall.O_NOFOLLOW": "syscall",
+ "syscall.O_NONBLOCK": "syscall",
+ "syscall.O_NOSIGPIPE": "syscall",
+ "syscall.O_POPUP": "syscall",
+ "syscall.O_RDONLY": "syscall",
+ "syscall.O_RDWR": "syscall",
+ "syscall.O_RSYNC": "syscall",
+ "syscall.O_SHLOCK": "syscall",
+ "syscall.O_SYMLINK": "syscall",
+ "syscall.O_SYNC": "syscall",
+ "syscall.O_TRUNC": "syscall",
+ "syscall.O_TTY_INIT": "syscall",
+ "syscall.O_WRONLY": "syscall",
+ "syscall.Open": "syscall",
+ "syscall.OpenCurrentProcessToken": "syscall",
+ "syscall.OpenProcess": "syscall",
+ "syscall.OpenProcessToken": "syscall",
+ "syscall.Openat": "syscall",
+ "syscall.Overlapped": "syscall",
+ "syscall.PACKET_ADD_MEMBERSHIP": "syscall",
+ "syscall.PACKET_BROADCAST": "syscall",
+ "syscall.PACKET_DROP_MEMBERSHIP": "syscall",
+ "syscall.PACKET_FASTROUTE": "syscall",
+ "syscall.PACKET_HOST": "syscall",
+ "syscall.PACKET_LOOPBACK": "syscall",
+ "syscall.PACKET_MR_ALLMULTI": "syscall",
+ "syscall.PACKET_MR_MULTICAST": "syscall",
+ "syscall.PACKET_MR_PROMISC": "syscall",
+ "syscall.PACKET_MULTICAST": "syscall",
+ "syscall.PACKET_OTHERHOST": "syscall",
+ "syscall.PACKET_OUTGOING": "syscall",
+ "syscall.PACKET_RECV_OUTPUT": "syscall",
+ "syscall.PACKET_RX_RING": "syscall",
+ "syscall.PACKET_STATISTICS": "syscall",
+ "syscall.PAGE_EXECUTE_READ": "syscall",
+ "syscall.PAGE_EXECUTE_READWRITE": "syscall",
+ "syscall.PAGE_EXECUTE_WRITECOPY": "syscall",
+ "syscall.PAGE_READONLY": "syscall",
+ "syscall.PAGE_READWRITE": "syscall",
+ "syscall.PAGE_WRITECOPY": "syscall",
+ "syscall.PARENB": "syscall",
+ "syscall.PARMRK": "syscall",
+ "syscall.PARODD": "syscall",
+ "syscall.PENDIN": "syscall",
+ "syscall.PFL_HIDDEN": "syscall",
+ "syscall.PFL_MATCHES_PROTOCOL_ZERO": "syscall",
+ "syscall.PFL_MULTIPLE_PROTO_ENTRIES": "syscall",
+ "syscall.PFL_NETWORKDIRECT_PROVIDER": "syscall",
+ "syscall.PFL_RECOMMENDED_PROTO_ENTRY": "syscall",
+ "syscall.PF_FLUSH": "syscall",
+ "syscall.PKCS_7_ASN_ENCODING": "syscall",
+ "syscall.PMC5_PIPELINE_FLUSH": "syscall",
+ "syscall.PRIO_PGRP": "syscall",
+ "syscall.PRIO_PROCESS": "syscall",
+ "syscall.PRIO_USER": "syscall",
+ "syscall.PRI_IOFLUSH": "syscall",
+ "syscall.PROCESS_QUERY_INFORMATION": "syscall",
+ "syscall.PROCESS_TERMINATE": "syscall",
+ "syscall.PROT_EXEC": "syscall",
+ "syscall.PROT_GROWSDOWN": "syscall",
+ "syscall.PROT_GROWSUP": "syscall",
+ "syscall.PROT_NONE": "syscall",
+ "syscall.PROT_READ": "syscall",
+ "syscall.PROT_WRITE": "syscall",
+ "syscall.PROV_DH_SCHANNEL": "syscall",
+ "syscall.PROV_DSS": "syscall",
+ "syscall.PROV_DSS_DH": "syscall",
+ "syscall.PROV_EC_ECDSA_FULL": "syscall",
+ "syscall.PROV_EC_ECDSA_SIG": "syscall",
+ "syscall.PROV_EC_ECNRA_FULL": "syscall",
+ "syscall.PROV_EC_ECNRA_SIG": "syscall",
+ "syscall.PROV_FORTEZZA": "syscall",
+ "syscall.PROV_INTEL_SEC": "syscall",
+ "syscall.PROV_MS_EXCHANGE": "syscall",
+ "syscall.PROV_REPLACE_OWF": "syscall",
+ "syscall.PROV_RNG": "syscall",
+ "syscall.PROV_RSA_AES": "syscall",
+ "syscall.PROV_RSA_FULL": "syscall",
+ "syscall.PROV_RSA_SCHANNEL": "syscall",
+ "syscall.PROV_RSA_SIG": "syscall",
+ "syscall.PROV_SPYRUS_LYNKS": "syscall",
+ "syscall.PROV_SSL": "syscall",
+ "syscall.PR_CAPBSET_DROP": "syscall",
+ "syscall.PR_CAPBSET_READ": "syscall",
+ "syscall.PR_CLEAR_SECCOMP_FILTER": "syscall",
+ "syscall.PR_ENDIAN_BIG": "syscall",
+ "syscall.PR_ENDIAN_LITTLE": "syscall",
+ "syscall.PR_ENDIAN_PPC_LITTLE": "syscall",
+ "syscall.PR_FPEMU_NOPRINT": "syscall",
+ "syscall.PR_FPEMU_SIGFPE": "syscall",
+ "syscall.PR_FP_EXC_ASYNC": "syscall",
+ "syscall.PR_FP_EXC_DISABLED": "syscall",
+ "syscall.PR_FP_EXC_DIV": "syscall",
+ "syscall.PR_FP_EXC_INV": "syscall",
+ "syscall.PR_FP_EXC_NONRECOV": "syscall",
+ "syscall.PR_FP_EXC_OVF": "syscall",
+ "syscall.PR_FP_EXC_PRECISE": "syscall",
+ "syscall.PR_FP_EXC_RES": "syscall",
+ "syscall.PR_FP_EXC_SW_ENABLE": "syscall",
+ "syscall.PR_FP_EXC_UND": "syscall",
+ "syscall.PR_GET_DUMPABLE": "syscall",
+ "syscall.PR_GET_ENDIAN": "syscall",
+ "syscall.PR_GET_FPEMU": "syscall",
+ "syscall.PR_GET_FPEXC": "syscall",
+ "syscall.PR_GET_KEEPCAPS": "syscall",
+ "syscall.PR_GET_NAME": "syscall",
+ "syscall.PR_GET_PDEATHSIG": "syscall",
+ "syscall.PR_GET_SECCOMP": "syscall",
+ "syscall.PR_GET_SECCOMP_FILTER": "syscall",
+ "syscall.PR_GET_SECUREBITS": "syscall",
+ "syscall.PR_GET_TIMERSLACK": "syscall",
+ "syscall.PR_GET_TIMING": "syscall",
+ "syscall.PR_GET_TSC": "syscall",
+ "syscall.PR_GET_UNALIGN": "syscall",
+ "syscall.PR_MCE_KILL": "syscall",
+ "syscall.PR_MCE_KILL_CLEAR": "syscall",
+ "syscall.PR_MCE_KILL_DEFAULT": "syscall",
+ "syscall.PR_MCE_KILL_EARLY": "syscall",
+ "syscall.PR_MCE_KILL_GET": "syscall",
+ "syscall.PR_MCE_KILL_LATE": "syscall",
+ "syscall.PR_MCE_KILL_SET": "syscall",
+ "syscall.PR_SECCOMP_FILTER_EVENT": "syscall",
+ "syscall.PR_SECCOMP_FILTER_SYSCALL": "syscall",
+ "syscall.PR_SET_DUMPABLE": "syscall",
+ "syscall.PR_SET_ENDIAN": "syscall",
+ "syscall.PR_SET_FPEMU": "syscall",
+ "syscall.PR_SET_FPEXC": "syscall",
+ "syscall.PR_SET_KEEPCAPS": "syscall",
+ "syscall.PR_SET_NAME": "syscall",
+ "syscall.PR_SET_PDEATHSIG": "syscall",
+ "syscall.PR_SET_PTRACER": "syscall",
+ "syscall.PR_SET_SECCOMP": "syscall",
+ "syscall.PR_SET_SECCOMP_FILTER": "syscall",
+ "syscall.PR_SET_SECUREBITS": "syscall",
+ "syscall.PR_SET_TIMERSLACK": "syscall",
+ "syscall.PR_SET_TIMING": "syscall",
+ "syscall.PR_SET_TSC": "syscall",
+ "syscall.PR_SET_UNALIGN": "syscall",
+ "syscall.PR_TASK_PERF_EVENTS_DISABLE": "syscall",
+ "syscall.PR_TASK_PERF_EVENTS_ENABLE": "syscall",
+ "syscall.PR_TIMING_STATISTICAL": "syscall",
+ "syscall.PR_TIMING_TIMESTAMP": "syscall",
+ "syscall.PR_TSC_ENABLE": "syscall",
+ "syscall.PR_TSC_SIGSEGV": "syscall",
+ "syscall.PR_UNALIGN_NOPRINT": "syscall",
+ "syscall.PR_UNALIGN_SIGBUS": "syscall",
+ "syscall.PTRACE_ARCH_PRCTL": "syscall",
+ "syscall.PTRACE_ATTACH": "syscall",
+ "syscall.PTRACE_CONT": "syscall",
+ "syscall.PTRACE_DETACH": "syscall",
+ "syscall.PTRACE_EVENT_CLONE": "syscall",
+ "syscall.PTRACE_EVENT_EXEC": "syscall",
+ "syscall.PTRACE_EVENT_EXIT": "syscall",
+ "syscall.PTRACE_EVENT_FORK": "syscall",
+ "syscall.PTRACE_EVENT_VFORK": "syscall",
+ "syscall.PTRACE_EVENT_VFORK_DONE": "syscall",
+ "syscall.PTRACE_GETCRUNCHREGS": "syscall",
+ "syscall.PTRACE_GETEVENTMSG": "syscall",
+ "syscall.PTRACE_GETFPREGS": "syscall",
+ "syscall.PTRACE_GETFPXREGS": "syscall",
+ "syscall.PTRACE_GETHBPREGS": "syscall",
+ "syscall.PTRACE_GETREGS": "syscall",
+ "syscall.PTRACE_GETREGSET": "syscall",
+ "syscall.PTRACE_GETSIGINFO": "syscall",
+ "syscall.PTRACE_GETVFPREGS": "syscall",
+ "syscall.PTRACE_GETWMMXREGS": "syscall",
+ "syscall.PTRACE_GET_THREAD_AREA": "syscall",
+ "syscall.PTRACE_KILL": "syscall",
+ "syscall.PTRACE_OLDSETOPTIONS": "syscall",
+ "syscall.PTRACE_O_MASK": "syscall",
+ "syscall.PTRACE_O_TRACECLONE": "syscall",
+ "syscall.PTRACE_O_TRACEEXEC": "syscall",
+ "syscall.PTRACE_O_TRACEEXIT": "syscall",
+ "syscall.PTRACE_O_TRACEFORK": "syscall",
+ "syscall.PTRACE_O_TRACESYSGOOD": "syscall",
+ "syscall.PTRACE_O_TRACEVFORK": "syscall",
+ "syscall.PTRACE_O_TRACEVFORKDONE": "syscall",
+ "syscall.PTRACE_PEEKDATA": "syscall",
+ "syscall.PTRACE_PEEKTEXT": "syscall",
+ "syscall.PTRACE_PEEKUSR": "syscall",
+ "syscall.PTRACE_POKEDATA": "syscall",
+ "syscall.PTRACE_POKETEXT": "syscall",
+ "syscall.PTRACE_POKEUSR": "syscall",
+ "syscall.PTRACE_SETCRUNCHREGS": "syscall",
+ "syscall.PTRACE_SETFPREGS": "syscall",
+ "syscall.PTRACE_SETFPXREGS": "syscall",
+ "syscall.PTRACE_SETHBPREGS": "syscall",
+ "syscall.PTRACE_SETOPTIONS": "syscall",
+ "syscall.PTRACE_SETREGS": "syscall",
+ "syscall.PTRACE_SETREGSET": "syscall",
+ "syscall.PTRACE_SETSIGINFO": "syscall",
+ "syscall.PTRACE_SETVFPREGS": "syscall",
+ "syscall.PTRACE_SETWMMXREGS": "syscall",
+ "syscall.PTRACE_SET_SYSCALL": "syscall",
+ "syscall.PTRACE_SET_THREAD_AREA": "syscall",
+ "syscall.PTRACE_SINGLEBLOCK": "syscall",
+ "syscall.PTRACE_SINGLESTEP": "syscall",
+ "syscall.PTRACE_SYSCALL": "syscall",
+ "syscall.PTRACE_SYSEMU": "syscall",
+ "syscall.PTRACE_SYSEMU_SINGLESTEP": "syscall",
+ "syscall.PTRACE_TRACEME": "syscall",
+ "syscall.PT_ATTACH": "syscall",
+ "syscall.PT_ATTACHEXC": "syscall",
+ "syscall.PT_CONTINUE": "syscall",
+ "syscall.PT_DATA_ADDR": "syscall",
+ "syscall.PT_DENY_ATTACH": "syscall",
+ "syscall.PT_DETACH": "syscall",
+ "syscall.PT_FIRSTMACH": "syscall",
+ "syscall.PT_FORCEQUOTA": "syscall",
+ "syscall.PT_KILL": "syscall",
+ "syscall.PT_MASK": "syscall",
+ "syscall.PT_READ_D": "syscall",
+ "syscall.PT_READ_I": "syscall",
+ "syscall.PT_READ_U": "syscall",
+ "syscall.PT_SIGEXC": "syscall",
+ "syscall.PT_STEP": "syscall",
+ "syscall.PT_TEXT_ADDR": "syscall",
+ "syscall.PT_TEXT_END_ADDR": "syscall",
+ "syscall.PT_THUPDATE": "syscall",
+ "syscall.PT_TRACE_ME": "syscall",
+ "syscall.PT_WRITE_D": "syscall",
+ "syscall.PT_WRITE_I": "syscall",
+ "syscall.PT_WRITE_U": "syscall",
+ "syscall.ParseDirent": "syscall",
+ "syscall.ParseNetlinkMessage": "syscall",
+ "syscall.ParseNetlinkRouteAttr": "syscall",
+ "syscall.ParseRoutingMessage": "syscall",
+ "syscall.ParseRoutingSockaddr": "syscall",
+ "syscall.ParseSocketControlMessage": "syscall",
+ "syscall.ParseUnixCredentials": "syscall",
+ "syscall.ParseUnixRights": "syscall",
+ "syscall.PathMax": "syscall",
+ "syscall.Pathconf": "syscall",
+ "syscall.Pause": "syscall",
+ "syscall.Pipe": "syscall",
+ "syscall.Pipe2": "syscall",
+ "syscall.PivotRoot": "syscall",
+ "syscall.PostQueuedCompletionStatus": "syscall",
+ "syscall.Pread": "syscall",
+ "syscall.Proc": "syscall",
+ "syscall.ProcAttr": "syscall",
+ "syscall.ProcessInformation": "syscall",
+ "syscall.Protoent": "syscall",
+ "syscall.PtraceAttach": "syscall",
+ "syscall.PtraceCont": "syscall",
+ "syscall.PtraceDetach": "syscall",
+ "syscall.PtraceGetEventMsg": "syscall",
+ "syscall.PtraceGetRegs": "syscall",
+ "syscall.PtracePeekData": "syscall",
+ "syscall.PtracePeekText": "syscall",
+ "syscall.PtracePokeData": "syscall",
+ "syscall.PtracePokeText": "syscall",
+ "syscall.PtraceRegs": "syscall",
+ "syscall.PtraceSetOptions": "syscall",
+ "syscall.PtraceSetRegs": "syscall",
+ "syscall.PtraceSingleStep": "syscall",
+ "syscall.PtraceSyscall": "syscall",
+ "syscall.Pwrite": "syscall",
+ "syscall.REG_BINARY": "syscall",
+ "syscall.REG_DWORD": "syscall",
+ "syscall.REG_DWORD_BIG_ENDIAN": "syscall",
+ "syscall.REG_DWORD_LITTLE_ENDIAN": "syscall",
+ "syscall.REG_EXPAND_SZ": "syscall",
+ "syscall.REG_FULL_RESOURCE_DESCRIPTOR": "syscall",
+ "syscall.REG_LINK": "syscall",
+ "syscall.REG_MULTI_SZ": "syscall",
+ "syscall.REG_NONE": "syscall",
+ "syscall.REG_QWORD": "syscall",
+ "syscall.REG_QWORD_LITTLE_ENDIAN": "syscall",
+ "syscall.REG_RESOURCE_LIST": "syscall",
+ "syscall.REG_RESOURCE_REQUIREMENTS_LIST": "syscall",
+ "syscall.REG_SZ": "syscall",
+ "syscall.RLIMIT_AS": "syscall",
+ "syscall.RLIMIT_CORE": "syscall",
+ "syscall.RLIMIT_CPU": "syscall",
+ "syscall.RLIMIT_DATA": "syscall",
+ "syscall.RLIMIT_FSIZE": "syscall",
+ "syscall.RLIMIT_NOFILE": "syscall",
+ "syscall.RLIMIT_STACK": "syscall",
+ "syscall.RLIM_INFINITY": "syscall",
+ "syscall.RTAX_ADVMSS": "syscall",
+ "syscall.RTAX_AUTHOR": "syscall",
+ "syscall.RTAX_BRD": "syscall",
+ "syscall.RTAX_CWND": "syscall",
+ "syscall.RTAX_DST": "syscall",
+ "syscall.RTAX_FEATURES": "syscall",
+ "syscall.RTAX_FEATURE_ALLFRAG": "syscall",
+ "syscall.RTAX_FEATURE_ECN": "syscall",
+ "syscall.RTAX_FEATURE_SACK": "syscall",
+ "syscall.RTAX_FEATURE_TIMESTAMP": "syscall",
+ "syscall.RTAX_GATEWAY": "syscall",
+ "syscall.RTAX_GENMASK": "syscall",
+ "syscall.RTAX_HOPLIMIT": "syscall",
+ "syscall.RTAX_IFA": "syscall",
+ "syscall.RTAX_IFP": "syscall",
+ "syscall.RTAX_INITCWND": "syscall",
+ "syscall.RTAX_INITRWND": "syscall",
+ "syscall.RTAX_LABEL": "syscall",
+ "syscall.RTAX_LOCK": "syscall",
+ "syscall.RTAX_MAX": "syscall",
+ "syscall.RTAX_MTU": "syscall",
+ "syscall.RTAX_NETMASK": "syscall",
+ "syscall.RTAX_REORDERING": "syscall",
+ "syscall.RTAX_RTO_MIN": "syscall",
+ "syscall.RTAX_RTT": "syscall",
+ "syscall.RTAX_RTTVAR": "syscall",
+ "syscall.RTAX_SRC": "syscall",
+ "syscall.RTAX_SRCMASK": "syscall",
+ "syscall.RTAX_SSTHRESH": "syscall",
+ "syscall.RTAX_TAG": "syscall",
+ "syscall.RTAX_UNSPEC": "syscall",
+ "syscall.RTAX_WINDOW": "syscall",
+ "syscall.RTA_ALIGNTO": "syscall",
+ "syscall.RTA_AUTHOR": "syscall",
+ "syscall.RTA_BRD": "syscall",
+ "syscall.RTA_CACHEINFO": "syscall",
+ "syscall.RTA_DST": "syscall",
+ "syscall.RTA_FLOW": "syscall",
+ "syscall.RTA_GATEWAY": "syscall",
+ "syscall.RTA_GENMASK": "syscall",
+ "syscall.RTA_IFA": "syscall",
+ "syscall.RTA_IFP": "syscall",
+ "syscall.RTA_IIF": "syscall",
+ "syscall.RTA_LABEL": "syscall",
+ "syscall.RTA_MAX": "syscall",
+ "syscall.RTA_METRICS": "syscall",
+ "syscall.RTA_MULTIPATH": "syscall",
+ "syscall.RTA_NETMASK": "syscall",
+ "syscall.RTA_OIF": "syscall",
+ "syscall.RTA_PREFSRC": "syscall",
+ "syscall.RTA_PRIORITY": "syscall",
+ "syscall.RTA_SRC": "syscall",
+ "syscall.RTA_SRCMASK": "syscall",
+ "syscall.RTA_TABLE": "syscall",
+ "syscall.RTA_TAG": "syscall",
+ "syscall.RTA_UNSPEC": "syscall",
+ "syscall.RTCF_DIRECTSRC": "syscall",
+ "syscall.RTCF_DOREDIRECT": "syscall",
+ "syscall.RTCF_LOG": "syscall",
+ "syscall.RTCF_MASQ": "syscall",
+ "syscall.RTCF_NAT": "syscall",
+ "syscall.RTCF_VALVE": "syscall",
+ "syscall.RTF_ADDRCLASSMASK": "syscall",
+ "syscall.RTF_ADDRCONF": "syscall",
+ "syscall.RTF_ALLONLINK": "syscall",
+ "syscall.RTF_ANNOUNCE": "syscall",
+ "syscall.RTF_BLACKHOLE": "syscall",
+ "syscall.RTF_BROADCAST": "syscall",
+ "syscall.RTF_CACHE": "syscall",
+ "syscall.RTF_CLONED": "syscall",
+ "syscall.RTF_CLONING": "syscall",
+ "syscall.RTF_CONDEMNED": "syscall",
+ "syscall.RTF_DEFAULT": "syscall",
+ "syscall.RTF_DELCLONE": "syscall",
+ "syscall.RTF_DONE": "syscall",
+ "syscall.RTF_DYNAMIC": "syscall",
+ "syscall.RTF_FLOW": "syscall",
+ "syscall.RTF_FMASK": "syscall",
+ "syscall.RTF_GATEWAY": "syscall",
+ "syscall.RTF_HOST": "syscall",
+ "syscall.RTF_IFREF": "syscall",
+ "syscall.RTF_IFSCOPE": "syscall",
+ "syscall.RTF_INTERFACE": "syscall",
+ "syscall.RTF_IRTT": "syscall",
+ "syscall.RTF_LINKRT": "syscall",
+ "syscall.RTF_LLDATA": "syscall",
+ "syscall.RTF_LLINFO": "syscall",
+ "syscall.RTF_LOCAL": "syscall",
+ "syscall.RTF_MASK": "syscall",
+ "syscall.RTF_MODIFIED": "syscall",
+ "syscall.RTF_MPATH": "syscall",
+ "syscall.RTF_MPLS": "syscall",
+ "syscall.RTF_MSS": "syscall",
+ "syscall.RTF_MTU": "syscall",
+ "syscall.RTF_MULTICAST": "syscall",
+ "syscall.RTF_NAT": "syscall",
+ "syscall.RTF_NOFORWARD": "syscall",
+ "syscall.RTF_NONEXTHOP": "syscall",
+ "syscall.RTF_NOPMTUDISC": "syscall",
+ "syscall.RTF_PERMANENT_ARP": "syscall",
+ "syscall.RTF_PINNED": "syscall",
+ "syscall.RTF_POLICY": "syscall",
+ "syscall.RTF_PRCLONING": "syscall",
+ "syscall.RTF_PROTO1": "syscall",
+ "syscall.RTF_PROTO2": "syscall",
+ "syscall.RTF_PROTO3": "syscall",
+ "syscall.RTF_REINSTATE": "syscall",
+ "syscall.RTF_REJECT": "syscall",
+ "syscall.RTF_RNH_LOCKED": "syscall",
+ "syscall.RTF_SOURCE": "syscall",
+ "syscall.RTF_SRC": "syscall",
+ "syscall.RTF_STATIC": "syscall",
+ "syscall.RTF_STICKY": "syscall",
+ "syscall.RTF_THROW": "syscall",
+ "syscall.RTF_TUNNEL": "syscall",
+ "syscall.RTF_UP": "syscall",
+ "syscall.RTF_USETRAILERS": "syscall",
+ "syscall.RTF_WASCLONED": "syscall",
+ "syscall.RTF_WINDOW": "syscall",
+ "syscall.RTF_XRESOLVE": "syscall",
+ "syscall.RTM_ADD": "syscall",
+ "syscall.RTM_BASE": "syscall",
+ "syscall.RTM_CHANGE": "syscall",
+ "syscall.RTM_CHGADDR": "syscall",
+ "syscall.RTM_DELACTION": "syscall",
+ "syscall.RTM_DELADDR": "syscall",
+ "syscall.RTM_DELADDRLABEL": "syscall",
+ "syscall.RTM_DELETE": "syscall",
+ "syscall.RTM_DELLINK": "syscall",
+ "syscall.RTM_DELMADDR": "syscall",
+ "syscall.RTM_DELNEIGH": "syscall",
+ "syscall.RTM_DELQDISC": "syscall",
+ "syscall.RTM_DELROUTE": "syscall",
+ "syscall.RTM_DELRULE": "syscall",
+ "syscall.RTM_DELTCLASS": "syscall",
+ "syscall.RTM_DELTFILTER": "syscall",
+ "syscall.RTM_DESYNC": "syscall",
+ "syscall.RTM_F_CLONED": "syscall",
+ "syscall.RTM_F_EQUALIZE": "syscall",
+ "syscall.RTM_F_NOTIFY": "syscall",
+ "syscall.RTM_F_PREFIX": "syscall",
+ "syscall.RTM_GET": "syscall",
+ "syscall.RTM_GET2": "syscall",
+ "syscall.RTM_GETACTION": "syscall",
+ "syscall.RTM_GETADDR": "syscall",
+ "syscall.RTM_GETADDRLABEL": "syscall",
+ "syscall.RTM_GETANYCAST": "syscall",
+ "syscall.RTM_GETDCB": "syscall",
+ "syscall.RTM_GETLINK": "syscall",
+ "syscall.RTM_GETMULTICAST": "syscall",
+ "syscall.RTM_GETNEIGH": "syscall",
+ "syscall.RTM_GETNEIGHTBL": "syscall",
+ "syscall.RTM_GETQDISC": "syscall",
+ "syscall.RTM_GETROUTE": "syscall",
+ "syscall.RTM_GETRULE": "syscall",
+ "syscall.RTM_GETTCLASS": "syscall",
+ "syscall.RTM_GETTFILTER": "syscall",
+ "syscall.RTM_IEEE80211": "syscall",
+ "syscall.RTM_IFANNOUNCE": "syscall",
+ "syscall.RTM_IFINFO": "syscall",
+ "syscall.RTM_IFINFO2": "syscall",
+ "syscall.RTM_LLINFO_UPD": "syscall",
+ "syscall.RTM_LOCK": "syscall",
+ "syscall.RTM_LOSING": "syscall",
+ "syscall.RTM_MAX": "syscall",
+ "syscall.RTM_MAXSIZE": "syscall",
+ "syscall.RTM_MISS": "syscall",
+ "syscall.RTM_NEWACTION": "syscall",
+ "syscall.RTM_NEWADDR": "syscall",
+ "syscall.RTM_NEWADDRLABEL": "syscall",
+ "syscall.RTM_NEWLINK": "syscall",
+ "syscall.RTM_NEWMADDR": "syscall",
+ "syscall.RTM_NEWMADDR2": "syscall",
+ "syscall.RTM_NEWNDUSEROPT": "syscall",
+ "syscall.RTM_NEWNEIGH": "syscall",
+ "syscall.RTM_NEWNEIGHTBL": "syscall",
+ "syscall.RTM_NEWPREFIX": "syscall",
+ "syscall.RTM_NEWQDISC": "syscall",
+ "syscall.RTM_NEWROUTE": "syscall",
+ "syscall.RTM_NEWRULE": "syscall",
+ "syscall.RTM_NEWTCLASS": "syscall",
+ "syscall.RTM_NEWTFILTER": "syscall",
+ "syscall.RTM_NR_FAMILIES": "syscall",
+ "syscall.RTM_NR_MSGTYPES": "syscall",
+ "syscall.RTM_OIFINFO": "syscall",
+ "syscall.RTM_OLDADD": "syscall",
+ "syscall.RTM_OLDDEL": "syscall",
+ "syscall.RTM_OOIFINFO": "syscall",
+ "syscall.RTM_REDIRECT": "syscall",
+ "syscall.RTM_RESOLVE": "syscall",
+ "syscall.RTM_RTTUNIT": "syscall",
+ "syscall.RTM_SETDCB": "syscall",
+ "syscall.RTM_SETGATE": "syscall",
+ "syscall.RTM_SETLINK": "syscall",
+ "syscall.RTM_SETNEIGHTBL": "syscall",
+ "syscall.RTM_VERSION": "syscall",
+ "syscall.RTNH_ALIGNTO": "syscall",
+ "syscall.RTNH_F_DEAD": "syscall",
+ "syscall.RTNH_F_ONLINK": "syscall",
+ "syscall.RTNH_F_PERVASIVE": "syscall",
+ "syscall.RTNLGRP_IPV4_IFADDR": "syscall",
+ "syscall.RTNLGRP_IPV4_MROUTE": "syscall",
+ "syscall.RTNLGRP_IPV4_ROUTE": "syscall",
+ "syscall.RTNLGRP_IPV4_RULE": "syscall",
+ "syscall.RTNLGRP_IPV6_IFADDR": "syscall",
+ "syscall.RTNLGRP_IPV6_IFINFO": "syscall",
+ "syscall.RTNLGRP_IPV6_MROUTE": "syscall",
+ "syscall.RTNLGRP_IPV6_PREFIX": "syscall",
+ "syscall.RTNLGRP_IPV6_ROUTE": "syscall",
+ "syscall.RTNLGRP_IPV6_RULE": "syscall",
+ "syscall.RTNLGRP_LINK": "syscall",
+ "syscall.RTNLGRP_ND_USEROPT": "syscall",
+ "syscall.RTNLGRP_NEIGH": "syscall",
+ "syscall.RTNLGRP_NONE": "syscall",
+ "syscall.RTNLGRP_NOTIFY": "syscall",
+ "syscall.RTNLGRP_TC": "syscall",
+ "syscall.RTN_ANYCAST": "syscall",
+ "syscall.RTN_BLACKHOLE": "syscall",
+ "syscall.RTN_BROADCAST": "syscall",
+ "syscall.RTN_LOCAL": "syscall",
+ "syscall.RTN_MAX": "syscall",
+ "syscall.RTN_MULTICAST": "syscall",
+ "syscall.RTN_NAT": "syscall",
+ "syscall.RTN_PROHIBIT": "syscall",
+ "syscall.RTN_THROW": "syscall",
+ "syscall.RTN_UNICAST": "syscall",
+ "syscall.RTN_UNREACHABLE": "syscall",
+ "syscall.RTN_UNSPEC": "syscall",
+ "syscall.RTN_XRESOLVE": "syscall",
+ "syscall.RTPROT_BIRD": "syscall",
+ "syscall.RTPROT_BOOT": "syscall",
+ "syscall.RTPROT_DHCP": "syscall",
+ "syscall.RTPROT_DNROUTED": "syscall",
+ "syscall.RTPROT_GATED": "syscall",
+ "syscall.RTPROT_KERNEL": "syscall",
+ "syscall.RTPROT_MRT": "syscall",
+ "syscall.RTPROT_NTK": "syscall",
+ "syscall.RTPROT_RA": "syscall",
+ "syscall.RTPROT_REDIRECT": "syscall",
+ "syscall.RTPROT_STATIC": "syscall",
+ "syscall.RTPROT_UNSPEC": "syscall",
+ "syscall.RTPROT_XORP": "syscall",
+ "syscall.RTPROT_ZEBRA": "syscall",
+ "syscall.RTV_EXPIRE": "syscall",
+ "syscall.RTV_HOPCOUNT": "syscall",
+ "syscall.RTV_MTU": "syscall",
+ "syscall.RTV_RPIPE": "syscall",
+ "syscall.RTV_RTT": "syscall",
+ "syscall.RTV_RTTVAR": "syscall",
+ "syscall.RTV_SPIPE": "syscall",
+ "syscall.RTV_SSTHRESH": "syscall",
+ "syscall.RTV_WEIGHT": "syscall",
+ "syscall.RT_CACHING_CONTEXT": "syscall",
+ "syscall.RT_CLASS_DEFAULT": "syscall",
+ "syscall.RT_CLASS_LOCAL": "syscall",
+ "syscall.RT_CLASS_MAIN": "syscall",
+ "syscall.RT_CLASS_MAX": "syscall",
+ "syscall.RT_CLASS_UNSPEC": "syscall",
+ "syscall.RT_DEFAULT_FIB": "syscall",
+ "syscall.RT_NORTREF": "syscall",
+ "syscall.RT_SCOPE_HOST": "syscall",
+ "syscall.RT_SCOPE_LINK": "syscall",
+ "syscall.RT_SCOPE_NOWHERE": "syscall",
+ "syscall.RT_SCOPE_SITE": "syscall",
+ "syscall.RT_SCOPE_UNIVERSE": "syscall",
+ "syscall.RT_TABLEID_MAX": "syscall",
+ "syscall.RT_TABLE_COMPAT": "syscall",
+ "syscall.RT_TABLE_DEFAULT": "syscall",
+ "syscall.RT_TABLE_LOCAL": "syscall",
+ "syscall.RT_TABLE_MAIN": "syscall",
+ "syscall.RT_TABLE_MAX": "syscall",
+ "syscall.RT_TABLE_UNSPEC": "syscall",
+ "syscall.RUSAGE_CHILDREN": "syscall",
+ "syscall.RUSAGE_SELF": "syscall",
+ "syscall.RUSAGE_THREAD": "syscall",
+ "syscall.Radvisory_t": "syscall",
+ "syscall.RawSockaddr": "syscall",
+ "syscall.RawSockaddrAny": "syscall",
+ "syscall.RawSockaddrDatalink": "syscall",
+ "syscall.RawSockaddrInet4": "syscall",
+ "syscall.RawSockaddrInet6": "syscall",
+ "syscall.RawSockaddrLinklayer": "syscall",
+ "syscall.RawSockaddrNetlink": "syscall",
+ "syscall.RawSockaddrUnix": "syscall",
+ "syscall.RawSyscall": "syscall",
+ "syscall.RawSyscall6": "syscall",
+ "syscall.Read": "syscall",
+ "syscall.ReadConsole": "syscall",
+ "syscall.ReadDirectoryChanges": "syscall",
+ "syscall.ReadDirent": "syscall",
+ "syscall.ReadFile": "syscall",
+ "syscall.Readlink": "syscall",
+ "syscall.Reboot": "syscall",
+ "syscall.Recvfrom": "syscall",
+ "syscall.Recvmsg": "syscall",
+ "syscall.RegCloseKey": "syscall",
+ "syscall.RegEnumKeyEx": "syscall",
+ "syscall.RegOpenKeyEx": "syscall",
+ "syscall.RegQueryInfoKey": "syscall",
+ "syscall.RegQueryValueEx": "syscall",
+ "syscall.RemoveDirectory": "syscall",
+ "syscall.Removexattr": "syscall",
+ "syscall.Rename": "syscall",
+ "syscall.Renameat": "syscall",
+ "syscall.Revoke": "syscall",
+ "syscall.Rlimit": "syscall",
+ "syscall.Rmdir": "syscall",
+ "syscall.RouteMessage": "syscall",
+ "syscall.RouteRIB": "syscall",
+ "syscall.RtAttr": "syscall",
+ "syscall.RtGenmsg": "syscall",
+ "syscall.RtMetrics": "syscall",
+ "syscall.RtMsg": "syscall",
+ "syscall.RtMsghdr": "syscall",
+ "syscall.RtNexthop": "syscall",
+ "syscall.Rusage": "syscall",
+ "syscall.SCM_BINTIME": "syscall",
+ "syscall.SCM_CREDENTIALS": "syscall",
+ "syscall.SCM_CREDS": "syscall",
+ "syscall.SCM_RIGHTS": "syscall",
+ "syscall.SCM_TIMESTAMP": "syscall",
+ "syscall.SCM_TIMESTAMPING": "syscall",
+ "syscall.SCM_TIMESTAMPNS": "syscall",
+ "syscall.SCM_TIMESTAMP_MONOTONIC": "syscall",
+ "syscall.SHUT_RD": "syscall",
+ "syscall.SHUT_RDWR": "syscall",
+ "syscall.SHUT_WR": "syscall",
+ "syscall.SID": "syscall",
+ "syscall.SIDAndAttributes": "syscall",
+ "syscall.SIGABRT": "syscall",
+ "syscall.SIGALRM": "syscall",
+ "syscall.SIGBUS": "syscall",
+ "syscall.SIGCHLD": "syscall",
+ "syscall.SIGCLD": "syscall",
+ "syscall.SIGCONT": "syscall",
+ "syscall.SIGEMT": "syscall",
+ "syscall.SIGFPE": "syscall",
+ "syscall.SIGHUP": "syscall",
+ "syscall.SIGILL": "syscall",
+ "syscall.SIGINFO": "syscall",
+ "syscall.SIGINT": "syscall",
+ "syscall.SIGIO": "syscall",
+ "syscall.SIGIOT": "syscall",
+ "syscall.SIGKILL": "syscall",
+ "syscall.SIGLIBRT": "syscall",
+ "syscall.SIGLWP": "syscall",
+ "syscall.SIGPIPE": "syscall",
+ "syscall.SIGPOLL": "syscall",
+ "syscall.SIGPROF": "syscall",
+ "syscall.SIGPWR": "syscall",
+ "syscall.SIGQUIT": "syscall",
+ "syscall.SIGSEGV": "syscall",
+ "syscall.SIGSTKFLT": "syscall",
+ "syscall.SIGSTOP": "syscall",
+ "syscall.SIGSYS": "syscall",
+ "syscall.SIGTERM": "syscall",
+ "syscall.SIGTHR": "syscall",
+ "syscall.SIGTRAP": "syscall",
+ "syscall.SIGTSTP": "syscall",
+ "syscall.SIGTTIN": "syscall",
+ "syscall.SIGTTOU": "syscall",
+ "syscall.SIGUNUSED": "syscall",
+ "syscall.SIGURG": "syscall",
+ "syscall.SIGUSR1": "syscall",
+ "syscall.SIGUSR2": "syscall",
+ "syscall.SIGVTALRM": "syscall",
+ "syscall.SIGWINCH": "syscall",
+ "syscall.SIGXCPU": "syscall",
+ "syscall.SIGXFSZ": "syscall",
+ "syscall.SIOCADDDLCI": "syscall",
+ "syscall.SIOCADDMULTI": "syscall",
+ "syscall.SIOCADDRT": "syscall",
+ "syscall.SIOCAIFADDR": "syscall",
+ "syscall.SIOCAIFGROUP": "syscall",
+ "syscall.SIOCALIFADDR": "syscall",
+ "syscall.SIOCARPIPLL": "syscall",
+ "syscall.SIOCATMARK": "syscall",
+ "syscall.SIOCAUTOADDR": "syscall",
+ "syscall.SIOCAUTONETMASK": "syscall",
+ "syscall.SIOCBRDGADD": "syscall",
+ "syscall.SIOCBRDGADDS": "syscall",
+ "syscall.SIOCBRDGARL": "syscall",
+ "syscall.SIOCBRDGDADDR": "syscall",
+ "syscall.SIOCBRDGDEL": "syscall",
+ "syscall.SIOCBRDGDELS": "syscall",
+ "syscall.SIOCBRDGFLUSH": "syscall",
+ "syscall.SIOCBRDGFRL": "syscall",
+ "syscall.SIOCBRDGGCACHE": "syscall",
+ "syscall.SIOCBRDGGFD": "syscall",
+ "syscall.SIOCBRDGGHT": "syscall",
+ "syscall.SIOCBRDGGIFFLGS": "syscall",
+ "syscall.SIOCBRDGGMA": "syscall",
+ "syscall.SIOCBRDGGPARAM": "syscall",
+ "syscall.SIOCBRDGGPRI": "syscall",
+ "syscall.SIOCBRDGGRL": "syscall",
+ "syscall.SIOCBRDGGSIFS": "syscall",
+ "syscall.SIOCBRDGGTO": "syscall",
+ "syscall.SIOCBRDGIFS": "syscall",
+ "syscall.SIOCBRDGRTS": "syscall",
+ "syscall.SIOCBRDGSADDR": "syscall",
+ "syscall.SIOCBRDGSCACHE": "syscall",
+ "syscall.SIOCBRDGSFD": "syscall",
+ "syscall.SIOCBRDGSHT": "syscall",
+ "syscall.SIOCBRDGSIFCOST": "syscall",
+ "syscall.SIOCBRDGSIFFLGS": "syscall",
+ "syscall.SIOCBRDGSIFPRIO": "syscall",
+ "syscall.SIOCBRDGSMA": "syscall",
+ "syscall.SIOCBRDGSPRI": "syscall",
+ "syscall.SIOCBRDGSPROTO": "syscall",
+ "syscall.SIOCBRDGSTO": "syscall",
+ "syscall.SIOCBRDGSTXHC": "syscall",
+ "syscall.SIOCDARP": "syscall",
+ "syscall.SIOCDELDLCI": "syscall",
+ "syscall.SIOCDELMULTI": "syscall",
+ "syscall.SIOCDELRT": "syscall",
+ "syscall.SIOCDEVPRIVATE": "syscall",
+ "syscall.SIOCDIFADDR": "syscall",
+ "syscall.SIOCDIFGROUP": "syscall",
+ "syscall.SIOCDIFPHYADDR": "syscall",
+ "syscall.SIOCDLIFADDR": "syscall",
+ "syscall.SIOCDRARP": "syscall",
+ "syscall.SIOCGARP": "syscall",
+ "syscall.SIOCGDRVSPEC": "syscall",
+ "syscall.SIOCGETKALIVE": "syscall",
+ "syscall.SIOCGETLABEL": "syscall",
+ "syscall.SIOCGETPFLOW": "syscall",
+ "syscall.SIOCGETPFSYNC": "syscall",
+ "syscall.SIOCGETSGCNT": "syscall",
+ "syscall.SIOCGETVIFCNT": "syscall",
+ "syscall.SIOCGETVLAN": "syscall",
+ "syscall.SIOCGHIWAT": "syscall",
+ "syscall.SIOCGIFADDR": "syscall",
+ "syscall.SIOCGIFADDRPREF": "syscall",
+ "syscall.SIOCGIFALIAS": "syscall",
+ "syscall.SIOCGIFALTMTU": "syscall",
+ "syscall.SIOCGIFASYNCMAP": "syscall",
+ "syscall.SIOCGIFBOND": "syscall",
+ "syscall.SIOCGIFBR": "syscall",
+ "syscall.SIOCGIFBRDADDR": "syscall",
+ "syscall.SIOCGIFCAP": "syscall",
+ "syscall.SIOCGIFCONF": "syscall",
+ "syscall.SIOCGIFCOUNT": "syscall",
+ "syscall.SIOCGIFDATA": "syscall",
+ "syscall.SIOCGIFDESCR": "syscall",
+ "syscall.SIOCGIFDEVMTU": "syscall",
+ "syscall.SIOCGIFDLT": "syscall",
+ "syscall.SIOCGIFDSTADDR": "syscall",
+ "syscall.SIOCGIFENCAP": "syscall",
+ "syscall.SIOCGIFFIB": "syscall",
+ "syscall.SIOCGIFFLAGS": "syscall",
+ "syscall.SIOCGIFGATTR": "syscall",
+ "syscall.SIOCGIFGENERIC": "syscall",
+ "syscall.SIOCGIFGMEMB": "syscall",
+ "syscall.SIOCGIFGROUP": "syscall",
+ "syscall.SIOCGIFHWADDR": "syscall",
+ "syscall.SIOCGIFINDEX": "syscall",
+ "syscall.SIOCGIFKPI": "syscall",
+ "syscall.SIOCGIFMAC": "syscall",
+ "syscall.SIOCGIFMAP": "syscall",
+ "syscall.SIOCGIFMEDIA": "syscall",
+ "syscall.SIOCGIFMEM": "syscall",
+ "syscall.SIOCGIFMETRIC": "syscall",
+ "syscall.SIOCGIFMTU": "syscall",
+ "syscall.SIOCGIFNAME": "syscall",
+ "syscall.SIOCGIFNETMASK": "syscall",
+ "syscall.SIOCGIFPDSTADDR": "syscall",
+ "syscall.SIOCGIFPFLAGS": "syscall",
+ "syscall.SIOCGIFPHYS": "syscall",
+ "syscall.SIOCGIFPRIORITY": "syscall",
+ "syscall.SIOCGIFPSRCADDR": "syscall",
+ "syscall.SIOCGIFRDOMAIN": "syscall",
+ "syscall.SIOCGIFRTLABEL": "syscall",
+ "syscall.SIOCGIFSLAVE": "syscall",
+ "syscall.SIOCGIFSTATUS": "syscall",
+ "syscall.SIOCGIFTIMESLOT": "syscall",
+ "syscall.SIOCGIFTXQLEN": "syscall",
+ "syscall.SIOCGIFVLAN": "syscall",
+ "syscall.SIOCGIFWAKEFLAGS": "syscall",
+ "syscall.SIOCGIFXFLAGS": "syscall",
+ "syscall.SIOCGLIFADDR": "syscall",
+ "syscall.SIOCGLIFPHYADDR": "syscall",
+ "syscall.SIOCGLIFPHYRTABLE": "syscall",
+ "syscall.SIOCGLINKSTR": "syscall",
+ "syscall.SIOCGLOWAT": "syscall",
+ "syscall.SIOCGPGRP": "syscall",
+ "syscall.SIOCGPRIVATE_0": "syscall",
+ "syscall.SIOCGPRIVATE_1": "syscall",
+ "syscall.SIOCGRARP": "syscall",
+ "syscall.SIOCGSTAMP": "syscall",
+ "syscall.SIOCGSTAMPNS": "syscall",
+ "syscall.SIOCGVH": "syscall",
+ "syscall.SIOCIFCREATE": "syscall",
+ "syscall.SIOCIFCREATE2": "syscall",
+ "syscall.SIOCIFDESTROY": "syscall",
+ "syscall.SIOCIFGCLONERS": "syscall",
+ "syscall.SIOCINITIFADDR": "syscall",
+ "syscall.SIOCPROTOPRIVATE": "syscall",
+ "syscall.SIOCRSLVMULTI": "syscall",
+ "syscall.SIOCRTMSG": "syscall",
+ "syscall.SIOCSARP": "syscall",
+ "syscall.SIOCSDRVSPEC": "syscall",
+ "syscall.SIOCSETKALIVE": "syscall",
+ "syscall.SIOCSETLABEL": "syscall",
+ "syscall.SIOCSETPFLOW": "syscall",
+ "syscall.SIOCSETPFSYNC": "syscall",
+ "syscall.SIOCSETVLAN": "syscall",
+ "syscall.SIOCSHIWAT": "syscall",
+ "syscall.SIOCSIFADDR": "syscall",
+ "syscall.SIOCSIFADDRPREF": "syscall",
+ "syscall.SIOCSIFALTMTU": "syscall",
+ "syscall.SIOCSIFASYNCMAP": "syscall",
+ "syscall.SIOCSIFBOND": "syscall",
+ "syscall.SIOCSIFBR": "syscall",
+ "syscall.SIOCSIFBRDADDR": "syscall",
+ "syscall.SIOCSIFCAP": "syscall",
+ "syscall.SIOCSIFDESCR": "syscall",
+ "syscall.SIOCSIFDSTADDR": "syscall",
+ "syscall.SIOCSIFENCAP": "syscall",
+ "syscall.SIOCSIFFIB": "syscall",
+ "syscall.SIOCSIFFLAGS": "syscall",
+ "syscall.SIOCSIFGATTR": "syscall",
+ "syscall.SIOCSIFGENERIC": "syscall",
+ "syscall.SIOCSIFHWADDR": "syscall",
+ "syscall.SIOCSIFHWBROADCAST": "syscall",
+ "syscall.SIOCSIFKPI": "syscall",
+ "syscall.SIOCSIFLINK": "syscall",
+ "syscall.SIOCSIFLLADDR": "syscall",
+ "syscall.SIOCSIFMAC": "syscall",
+ "syscall.SIOCSIFMAP": "syscall",
+ "syscall.SIOCSIFMEDIA": "syscall",
+ "syscall.SIOCSIFMEM": "syscall",
+ "syscall.SIOCSIFMETRIC": "syscall",
+ "syscall.SIOCSIFMTU": "syscall",
+ "syscall.SIOCSIFNAME": "syscall",
+ "syscall.SIOCSIFNETMASK": "syscall",
+ "syscall.SIOCSIFPFLAGS": "syscall",
+ "syscall.SIOCSIFPHYADDR": "syscall",
+ "syscall.SIOCSIFPHYS": "syscall",
+ "syscall.SIOCSIFPRIORITY": "syscall",
+ "syscall.SIOCSIFRDOMAIN": "syscall",
+ "syscall.SIOCSIFRTLABEL": "syscall",
+ "syscall.SIOCSIFRVNET": "syscall",
+ "syscall.SIOCSIFSLAVE": "syscall",
+ "syscall.SIOCSIFTIMESLOT": "syscall",
+ "syscall.SIOCSIFTXQLEN": "syscall",
+ "syscall.SIOCSIFVLAN": "syscall",
+ "syscall.SIOCSIFVNET": "syscall",
+ "syscall.SIOCSIFXFLAGS": "syscall",
+ "syscall.SIOCSLIFPHYADDR": "syscall",
+ "syscall.SIOCSLIFPHYRTABLE": "syscall",
+ "syscall.SIOCSLINKSTR": "syscall",
+ "syscall.SIOCSLOWAT": "syscall",
+ "syscall.SIOCSPGRP": "syscall",
+ "syscall.SIOCSRARP": "syscall",
+ "syscall.SIOCSVH": "syscall",
+ "syscall.SIOCZIFDATA": "syscall",
+ "syscall.SIO_GET_EXTENSION_FUNCTION_POINTER": "syscall",
+ "syscall.SIO_GET_INTERFACE_LIST": "syscall",
+ "syscall.SOCK_CLOEXEC": "syscall",
+ "syscall.SOCK_DCCP": "syscall",
+ "syscall.SOCK_DGRAM": "syscall",
+ "syscall.SOCK_FLAGS_MASK": "syscall",
+ "syscall.SOCK_MAXADDRLEN": "syscall",
+ "syscall.SOCK_NONBLOCK": "syscall",
+ "syscall.SOCK_NOSIGPIPE": "syscall",
+ "syscall.SOCK_PACKET": "syscall",
+ "syscall.SOCK_RAW": "syscall",
+ "syscall.SOCK_RDM": "syscall",
+ "syscall.SOCK_SEQPACKET": "syscall",
+ "syscall.SOCK_STREAM": "syscall",
+ "syscall.SOL_AAL": "syscall",
+ "syscall.SOL_ATM": "syscall",
+ "syscall.SOL_DECNET": "syscall",
+ "syscall.SOL_ICMPV6": "syscall",
+ "syscall.SOL_IP": "syscall",
+ "syscall.SOL_IPV6": "syscall",
+ "syscall.SOL_IRDA": "syscall",
+ "syscall.SOL_PACKET": "syscall",
+ "syscall.SOL_RAW": "syscall",
+ "syscall.SOL_SOCKET": "syscall",
+ "syscall.SOL_TCP": "syscall",
+ "syscall.SOL_X25": "syscall",
+ "syscall.SOMAXCONN": "syscall",
+ "syscall.SO_ACCEPTCONN": "syscall",
+ "syscall.SO_ACCEPTFILTER": "syscall",
+ "syscall.SO_ATTACH_FILTER": "syscall",
+ "syscall.SO_BINDANY": "syscall",
+ "syscall.SO_BINDTODEVICE": "syscall",
+ "syscall.SO_BINTIME": "syscall",
+ "syscall.SO_BROADCAST": "syscall",
+ "syscall.SO_BSDCOMPAT": "syscall",
+ "syscall.SO_DEBUG": "syscall",
+ "syscall.SO_DETACH_FILTER": "syscall",
+ "syscall.SO_DOMAIN": "syscall",
+ "syscall.SO_DONTROUTE": "syscall",
+ "syscall.SO_DONTTRUNC": "syscall",
+ "syscall.SO_ERROR": "syscall",
+ "syscall.SO_KEEPALIVE": "syscall",
+ "syscall.SO_LABEL": "syscall",
+ "syscall.SO_LINGER": "syscall",
+ "syscall.SO_LINGER_SEC": "syscall",
+ "syscall.SO_LISTENINCQLEN": "syscall",
+ "syscall.SO_LISTENQLEN": "syscall",
+ "syscall.SO_LISTENQLIMIT": "syscall",
+ "syscall.SO_MARK": "syscall",
+ "syscall.SO_NETPROC": "syscall",
+ "syscall.SO_NKE": "syscall",
+ "syscall.SO_NOADDRERR": "syscall",
+ "syscall.SO_NOHEADER": "syscall",
+ "syscall.SO_NOSIGPIPE": "syscall",
+ "syscall.SO_NOTIFYCONFLICT": "syscall",
+ "syscall.SO_NO_CHECK": "syscall",
+ "syscall.SO_NO_DDP": "syscall",
+ "syscall.SO_NO_OFFLOAD": "syscall",
+ "syscall.SO_NP_EXTENSIONS": "syscall",
+ "syscall.SO_NREAD": "syscall",
+ "syscall.SO_NWRITE": "syscall",
+ "syscall.SO_OOBINLINE": "syscall",
+ "syscall.SO_OVERFLOWED": "syscall",
+ "syscall.SO_PASSCRED": "syscall",
+ "syscall.SO_PASSSEC": "syscall",
+ "syscall.SO_PEERCRED": "syscall",
+ "syscall.SO_PEERLABEL": "syscall",
+ "syscall.SO_PEERNAME": "syscall",
+ "syscall.SO_PEERSEC": "syscall",
+ "syscall.SO_PRIORITY": "syscall",
+ "syscall.SO_PROTOCOL": "syscall",
+ "syscall.SO_PROTOTYPE": "syscall",
+ "syscall.SO_RANDOMPORT": "syscall",
+ "syscall.SO_RCVBUF": "syscall",
+ "syscall.SO_RCVBUFFORCE": "syscall",
+ "syscall.SO_RCVLOWAT": "syscall",
+ "syscall.SO_RCVTIMEO": "syscall",
+ "syscall.SO_RESTRICTIONS": "syscall",
+ "syscall.SO_RESTRICT_DENYIN": "syscall",
+ "syscall.SO_RESTRICT_DENYOUT": "syscall",
+ "syscall.SO_RESTRICT_DENYSET": "syscall",
+ "syscall.SO_REUSEADDR": "syscall",
+ "syscall.SO_REUSEPORT": "syscall",
+ "syscall.SO_REUSESHAREUID": "syscall",
+ "syscall.SO_RTABLE": "syscall",
+ "syscall.SO_RXQ_OVFL": "syscall",
+ "syscall.SO_SECURITY_AUTHENTICATION": "syscall",
+ "syscall.SO_SECURITY_ENCRYPTION_NETWORK": "syscall",
+ "syscall.SO_SECURITY_ENCRYPTION_TRANSPORT": "syscall",
+ "syscall.SO_SETFIB": "syscall",
+ "syscall.SO_SNDBUF": "syscall",
+ "syscall.SO_SNDBUFFORCE": "syscall",
+ "syscall.SO_SNDLOWAT": "syscall",
+ "syscall.SO_SNDTIMEO": "syscall",
+ "syscall.SO_SPLICE": "syscall",
+ "syscall.SO_TIMESTAMP": "syscall",
+ "syscall.SO_TIMESTAMPING": "syscall",
+ "syscall.SO_TIMESTAMPNS": "syscall",
+ "syscall.SO_TIMESTAMP_MONOTONIC": "syscall",
+ "syscall.SO_TYPE": "syscall",
+ "syscall.SO_UPCALLCLOSEWAIT": "syscall",
+ "syscall.SO_UPDATE_ACCEPT_CONTEXT": "syscall",
+ "syscall.SO_UPDATE_CONNECT_CONTEXT": "syscall",
+ "syscall.SO_USELOOPBACK": "syscall",
+ "syscall.SO_USER_COOKIE": "syscall",
+ "syscall.SO_WANTMORE": "syscall",
+ "syscall.SO_WANTOOBFLAG": "syscall",
+ "syscall.SSLExtraCertChainPolicyPara": "syscall",
+ "syscall.STANDARD_RIGHTS_ALL": "syscall",
+ "syscall.STANDARD_RIGHTS_EXECUTE": "syscall",
+ "syscall.STANDARD_RIGHTS_READ": "syscall",
+ "syscall.STANDARD_RIGHTS_REQUIRED": "syscall",
+ "syscall.STANDARD_RIGHTS_WRITE": "syscall",
+ "syscall.STARTF_USESHOWWINDOW": "syscall",
+ "syscall.STARTF_USESTDHANDLES": "syscall",
+ "syscall.STD_ERROR_HANDLE": "syscall",
+ "syscall.STD_INPUT_HANDLE": "syscall",
+ "syscall.STD_OUTPUT_HANDLE": "syscall",
+ "syscall.SUBLANG_ENGLISH_US": "syscall",
+ "syscall.SW_FORCEMINIMIZE": "syscall",
+ "syscall.SW_HIDE": "syscall",
+ "syscall.SW_MAXIMIZE": "syscall",
+ "syscall.SW_MINIMIZE": "syscall",
+ "syscall.SW_NORMAL": "syscall",
+ "syscall.SW_RESTORE": "syscall",
+ "syscall.SW_SHOW": "syscall",
+ "syscall.SW_SHOWDEFAULT": "syscall",
+ "syscall.SW_SHOWMAXIMIZED": "syscall",
+ "syscall.SW_SHOWMINIMIZED": "syscall",
+ "syscall.SW_SHOWMINNOACTIVE": "syscall",
+ "syscall.SW_SHOWNA": "syscall",
+ "syscall.SW_SHOWNOACTIVATE": "syscall",
+ "syscall.SW_SHOWNORMAL": "syscall",
+ "syscall.SYNCHRONIZE": "syscall",
+ "syscall.SYSCTL_VERSION": "syscall",
+ "syscall.SYSCTL_VERS_0": "syscall",
+ "syscall.SYSCTL_VERS_1": "syscall",
+ "syscall.SYSCTL_VERS_MASK": "syscall",
+ "syscall.SYS_ABORT2": "syscall",
+ "syscall.SYS_ACCEPT": "syscall",
+ "syscall.SYS_ACCEPT4": "syscall",
+ "syscall.SYS_ACCEPT_NOCANCEL": "syscall",
+ "syscall.SYS_ACCESS": "syscall",
+ "syscall.SYS_ACCESS_EXTENDED": "syscall",
+ "syscall.SYS_ACCT": "syscall",
+ "syscall.SYS_ADD_KEY": "syscall",
+ "syscall.SYS_ADD_PROFIL": "syscall",
+ "syscall.SYS_ADJFREQ": "syscall",
+ "syscall.SYS_ADJTIME": "syscall",
+ "syscall.SYS_ADJTIMEX": "syscall",
+ "syscall.SYS_AFS_SYSCALL": "syscall",
+ "syscall.SYS_AIO_CANCEL": "syscall",
+ "syscall.SYS_AIO_ERROR": "syscall",
+ "syscall.SYS_AIO_FSYNC": "syscall",
+ "syscall.SYS_AIO_READ": "syscall",
+ "syscall.SYS_AIO_RETURN": "syscall",
+ "syscall.SYS_AIO_SUSPEND": "syscall",
+ "syscall.SYS_AIO_SUSPEND_NOCANCEL": "syscall",
+ "syscall.SYS_AIO_WRITE": "syscall",
+ "syscall.SYS_ALARM": "syscall",
+ "syscall.SYS_ARCH_PRCTL": "syscall",
+ "syscall.SYS_ARM_FADVISE64_64": "syscall",
+ "syscall.SYS_ARM_SYNC_FILE_RANGE": "syscall",
+ "syscall.SYS_ATGETMSG": "syscall",
+ "syscall.SYS_ATPGETREQ": "syscall",
+ "syscall.SYS_ATPGETRSP": "syscall",
+ "syscall.SYS_ATPSNDREQ": "syscall",
+ "syscall.SYS_ATPSNDRSP": "syscall",
+ "syscall.SYS_ATPUTMSG": "syscall",
+ "syscall.SYS_ATSOCKET": "syscall",
+ "syscall.SYS_AUDIT": "syscall",
+ "syscall.SYS_AUDITCTL": "syscall",
+ "syscall.SYS_AUDITON": "syscall",
+ "syscall.SYS_AUDIT_SESSION_JOIN": "syscall",
+ "syscall.SYS_AUDIT_SESSION_PORT": "syscall",
+ "syscall.SYS_AUDIT_SESSION_SELF": "syscall",
+ "syscall.SYS_BDFLUSH": "syscall",
+ "syscall.SYS_BIND": "syscall",
+ "syscall.SYS_BREAK": "syscall",
+ "syscall.SYS_BRK": "syscall",
+ "syscall.SYS_BSDTHREAD_CREATE": "syscall",
+ "syscall.SYS_BSDTHREAD_REGISTER": "syscall",
+ "syscall.SYS_BSDTHREAD_TERMINATE": "syscall",
+ "syscall.SYS_CAPGET": "syscall",
+ "syscall.SYS_CAPSET": "syscall",
+ "syscall.SYS_CAP_ENTER": "syscall",
+ "syscall.SYS_CAP_FCNTLS_GET": "syscall",
+ "syscall.SYS_CAP_FCNTLS_LIMIT": "syscall",
+ "syscall.SYS_CAP_GETMODE": "syscall",
+ "syscall.SYS_CAP_GETRIGHTS": "syscall",
+ "syscall.SYS_CAP_IOCTLS_GET": "syscall",
+ "syscall.SYS_CAP_IOCTLS_LIMIT": "syscall",
+ "syscall.SYS_CAP_NEW": "syscall",
+ "syscall.SYS_CAP_RIGHTS_GET": "syscall",
+ "syscall.SYS_CAP_RIGHTS_LIMIT": "syscall",
+ "syscall.SYS_CHDIR": "syscall",
+ "syscall.SYS_CHFLAGS": "syscall",
+ "syscall.SYS_CHMOD": "syscall",
+ "syscall.SYS_CHMOD_EXTENDED": "syscall",
+ "syscall.SYS_CHOWN": "syscall",
+ "syscall.SYS_CHOWN32": "syscall",
+ "syscall.SYS_CHROOT": "syscall",
+ "syscall.SYS_CHUD": "syscall",
+ "syscall.SYS_CLOCK_ADJTIME": "syscall",
+ "syscall.SYS_CLOCK_GETCPUCLOCKID2": "syscall",
+ "syscall.SYS_CLOCK_GETRES": "syscall",
+ "syscall.SYS_CLOCK_GETTIME": "syscall",
+ "syscall.SYS_CLOCK_NANOSLEEP": "syscall",
+ "syscall.SYS_CLOCK_SETTIME": "syscall",
+ "syscall.SYS_CLONE": "syscall",
+ "syscall.SYS_CLOSE": "syscall",
+ "syscall.SYS_CLOSEFROM": "syscall",
+ "syscall.SYS_CLOSE_NOCANCEL": "syscall",
+ "syscall.SYS_CONNECT": "syscall",
+ "syscall.SYS_CONNECT_NOCANCEL": "syscall",
+ "syscall.SYS_COPYFILE": "syscall",
+ "syscall.SYS_CPUSET": "syscall",
+ "syscall.SYS_CPUSET_GETAFFINITY": "syscall",
+ "syscall.SYS_CPUSET_GETID": "syscall",
+ "syscall.SYS_CPUSET_SETAFFINITY": "syscall",
+ "syscall.SYS_CPUSET_SETID": "syscall",
+ "syscall.SYS_CREAT": "syscall",
+ "syscall.SYS_CREATE_MODULE": "syscall",
+ "syscall.SYS_CSOPS": "syscall",
+ "syscall.SYS_DELETE": "syscall",
+ "syscall.SYS_DELETE_MODULE": "syscall",
+ "syscall.SYS_DUP": "syscall",
+ "syscall.SYS_DUP2": "syscall",
+ "syscall.SYS_DUP3": "syscall",
+ "syscall.SYS_EACCESS": "syscall",
+ "syscall.SYS_EPOLL_CREATE": "syscall",
+ "syscall.SYS_EPOLL_CREATE1": "syscall",
+ "syscall.SYS_EPOLL_CTL": "syscall",
+ "syscall.SYS_EPOLL_CTL_OLD": "syscall",
+ "syscall.SYS_EPOLL_PWAIT": "syscall",
+ "syscall.SYS_EPOLL_WAIT": "syscall",
+ "syscall.SYS_EPOLL_WAIT_OLD": "syscall",
+ "syscall.SYS_EVENTFD": "syscall",
+ "syscall.SYS_EVENTFD2": "syscall",
+ "syscall.SYS_EXCHANGEDATA": "syscall",
+ "syscall.SYS_EXECVE": "syscall",
+ "syscall.SYS_EXIT": "syscall",
+ "syscall.SYS_EXIT_GROUP": "syscall",
+ "syscall.SYS_EXTATTRCTL": "syscall",
+ "syscall.SYS_EXTATTR_DELETE_FD": "syscall",
+ "syscall.SYS_EXTATTR_DELETE_FILE": "syscall",
+ "syscall.SYS_EXTATTR_DELETE_LINK": "syscall",
+ "syscall.SYS_EXTATTR_GET_FD": "syscall",
+ "syscall.SYS_EXTATTR_GET_FILE": "syscall",
+ "syscall.SYS_EXTATTR_GET_LINK": "syscall",
+ "syscall.SYS_EXTATTR_LIST_FD": "syscall",
+ "syscall.SYS_EXTATTR_LIST_FILE": "syscall",
+ "syscall.SYS_EXTATTR_LIST_LINK": "syscall",
+ "syscall.SYS_EXTATTR_SET_FD": "syscall",
+ "syscall.SYS_EXTATTR_SET_FILE": "syscall",
+ "syscall.SYS_EXTATTR_SET_LINK": "syscall",
+ "syscall.SYS_FACCESSAT": "syscall",
+ "syscall.SYS_FADVISE64": "syscall",
+ "syscall.SYS_FADVISE64_64": "syscall",
+ "syscall.SYS_FALLOCATE": "syscall",
+ "syscall.SYS_FANOTIFY_INIT": "syscall",
+ "syscall.SYS_FANOTIFY_MARK": "syscall",
+ "syscall.SYS_FCHDIR": "syscall",
+ "syscall.SYS_FCHFLAGS": "syscall",
+ "syscall.SYS_FCHMOD": "syscall",
+ "syscall.SYS_FCHMODAT": "syscall",
+ "syscall.SYS_FCHMOD_EXTENDED": "syscall",
+ "syscall.SYS_FCHOWN": "syscall",
+ "syscall.SYS_FCHOWN32": "syscall",
+ "syscall.SYS_FCHOWNAT": "syscall",
+ "syscall.SYS_FCHROOT": "syscall",
+ "syscall.SYS_FCNTL": "syscall",
+ "syscall.SYS_FCNTL64": "syscall",
+ "syscall.SYS_FCNTL_NOCANCEL": "syscall",
+ "syscall.SYS_FDATASYNC": "syscall",
+ "syscall.SYS_FEXECVE": "syscall",
+ "syscall.SYS_FFCLOCK_GETCOUNTER": "syscall",
+ "syscall.SYS_FFCLOCK_GETESTIMATE": "syscall",
+ "syscall.SYS_FFCLOCK_SETESTIMATE": "syscall",
+ "syscall.SYS_FFSCTL": "syscall",
+ "syscall.SYS_FGETATTRLIST": "syscall",
+ "syscall.SYS_FGETXATTR": "syscall",
+ "syscall.SYS_FHOPEN": "syscall",
+ "syscall.SYS_FHSTAT": "syscall",
+ "syscall.SYS_FHSTATFS": "syscall",
+ "syscall.SYS_FILEPORT_MAKEFD": "syscall",
+ "syscall.SYS_FILEPORT_MAKEPORT": "syscall",
+ "syscall.SYS_FKTRACE": "syscall",
+ "syscall.SYS_FLISTXATTR": "syscall",
+ "syscall.SYS_FLOCK": "syscall",
+ "syscall.SYS_FORK": "syscall",
+ "syscall.SYS_FPATHCONF": "syscall",
+ "syscall.SYS_FREEBSD6_FTRUNCATE": "syscall",
+ "syscall.SYS_FREEBSD6_LSEEK": "syscall",
+ "syscall.SYS_FREEBSD6_MMAP": "syscall",
+ "syscall.SYS_FREEBSD6_PREAD": "syscall",
+ "syscall.SYS_FREEBSD6_PWRITE": "syscall",
+ "syscall.SYS_FREEBSD6_TRUNCATE": "syscall",
+ "syscall.SYS_FREMOVEXATTR": "syscall",
+ "syscall.SYS_FSCTL": "syscall",
+ "syscall.SYS_FSETATTRLIST": "syscall",
+ "syscall.SYS_FSETXATTR": "syscall",
+ "syscall.SYS_FSGETPATH": "syscall",
+ "syscall.SYS_FSTAT": "syscall",
+ "syscall.SYS_FSTAT64": "syscall",
+ "syscall.SYS_FSTAT64_EXTENDED": "syscall",
+ "syscall.SYS_FSTATAT": "syscall",
+ "syscall.SYS_FSTATAT64": "syscall",
+ "syscall.SYS_FSTATFS": "syscall",
+ "syscall.SYS_FSTATFS64": "syscall",
+ "syscall.SYS_FSTATV": "syscall",
+ "syscall.SYS_FSTATVFS1": "syscall",
+ "syscall.SYS_FSTAT_EXTENDED": "syscall",
+ "syscall.SYS_FSYNC": "syscall",
+ "syscall.SYS_FSYNC_NOCANCEL": "syscall",
+ "syscall.SYS_FSYNC_RANGE": "syscall",
+ "syscall.SYS_FTIME": "syscall",
+ "syscall.SYS_FTRUNCATE": "syscall",
+ "syscall.SYS_FTRUNCATE64": "syscall",
+ "syscall.SYS_FUTEX": "syscall",
+ "syscall.SYS_FUTIMENS": "syscall",
+ "syscall.SYS_FUTIMES": "syscall",
+ "syscall.SYS_FUTIMESAT": "syscall",
+ "syscall.SYS_GETATTRLIST": "syscall",
+ "syscall.SYS_GETAUDIT": "syscall",
+ "syscall.SYS_GETAUDIT_ADDR": "syscall",
+ "syscall.SYS_GETAUID": "syscall",
+ "syscall.SYS_GETCONTEXT": "syscall",
+ "syscall.SYS_GETCPU": "syscall",
+ "syscall.SYS_GETCWD": "syscall",
+ "syscall.SYS_GETDENTS": "syscall",
+ "syscall.SYS_GETDENTS64": "syscall",
+ "syscall.SYS_GETDIRENTRIES": "syscall",
+ "syscall.SYS_GETDIRENTRIES64": "syscall",
+ "syscall.SYS_GETDIRENTRIESATTR": "syscall",
+ "syscall.SYS_GETDTABLECOUNT": "syscall",
+ "syscall.SYS_GETDTABLESIZE": "syscall",
+ "syscall.SYS_GETEGID": "syscall",
+ "syscall.SYS_GETEGID32": "syscall",
+ "syscall.SYS_GETEUID": "syscall",
+ "syscall.SYS_GETEUID32": "syscall",
+ "syscall.SYS_GETFH": "syscall",
+ "syscall.SYS_GETFSSTAT": "syscall",
+ "syscall.SYS_GETFSSTAT64": "syscall",
+ "syscall.SYS_GETGID": "syscall",
+ "syscall.SYS_GETGID32": "syscall",
+ "syscall.SYS_GETGROUPS": "syscall",
+ "syscall.SYS_GETGROUPS32": "syscall",
+ "syscall.SYS_GETHOSTUUID": "syscall",
+ "syscall.SYS_GETITIMER": "syscall",
+ "syscall.SYS_GETLCID": "syscall",
+ "syscall.SYS_GETLOGIN": "syscall",
+ "syscall.SYS_GETLOGINCLASS": "syscall",
+ "syscall.SYS_GETPEERNAME": "syscall",
+ "syscall.SYS_GETPGID": "syscall",
+ "syscall.SYS_GETPGRP": "syscall",
+ "syscall.SYS_GETPID": "syscall",
+ "syscall.SYS_GETPMSG": "syscall",
+ "syscall.SYS_GETPPID": "syscall",
+ "syscall.SYS_GETPRIORITY": "syscall",
+ "syscall.SYS_GETRESGID": "syscall",
+ "syscall.SYS_GETRESGID32": "syscall",
+ "syscall.SYS_GETRESUID": "syscall",
+ "syscall.SYS_GETRESUID32": "syscall",
+ "syscall.SYS_GETRLIMIT": "syscall",
+ "syscall.SYS_GETRTABLE": "syscall",
+ "syscall.SYS_GETRUSAGE": "syscall",
+ "syscall.SYS_GETSGROUPS": "syscall",
+ "syscall.SYS_GETSID": "syscall",
+ "syscall.SYS_GETSOCKNAME": "syscall",
+ "syscall.SYS_GETSOCKOPT": "syscall",
+ "syscall.SYS_GETTHRID": "syscall",
+ "syscall.SYS_GETTID": "syscall",
+ "syscall.SYS_GETTIMEOFDAY": "syscall",
+ "syscall.SYS_GETUID": "syscall",
+ "syscall.SYS_GETUID32": "syscall",
+ "syscall.SYS_GETVFSSTAT": "syscall",
+ "syscall.SYS_GETWGROUPS": "syscall",
+ "syscall.SYS_GETXATTR": "syscall",
+ "syscall.SYS_GET_KERNEL_SYMS": "syscall",
+ "syscall.SYS_GET_MEMPOLICY": "syscall",
+ "syscall.SYS_GET_ROBUST_LIST": "syscall",
+ "syscall.SYS_GET_THREAD_AREA": "syscall",
+ "syscall.SYS_GTTY": "syscall",
+ "syscall.SYS_IDENTITYSVC": "syscall",
+ "syscall.SYS_IDLE": "syscall",
+ "syscall.SYS_INITGROUPS": "syscall",
+ "syscall.SYS_INIT_MODULE": "syscall",
+ "syscall.SYS_INOTIFY_ADD_WATCH": "syscall",
+ "syscall.SYS_INOTIFY_INIT": "syscall",
+ "syscall.SYS_INOTIFY_INIT1": "syscall",
+ "syscall.SYS_INOTIFY_RM_WATCH": "syscall",
+ "syscall.SYS_IOCTL": "syscall",
+ "syscall.SYS_IOPERM": "syscall",
+ "syscall.SYS_IOPL": "syscall",
+ "syscall.SYS_IOPOLICYSYS": "syscall",
+ "syscall.SYS_IOPRIO_GET": "syscall",
+ "syscall.SYS_IOPRIO_SET": "syscall",
+ "syscall.SYS_IO_CANCEL": "syscall",
+ "syscall.SYS_IO_DESTROY": "syscall",
+ "syscall.SYS_IO_GETEVENTS": "syscall",
+ "syscall.SYS_IO_SETUP": "syscall",
+ "syscall.SYS_IO_SUBMIT": "syscall",
+ "syscall.SYS_IPC": "syscall",
+ "syscall.SYS_ISSETUGID": "syscall",
+ "syscall.SYS_JAIL": "syscall",
+ "syscall.SYS_JAIL_ATTACH": "syscall",
+ "syscall.SYS_JAIL_GET": "syscall",
+ "syscall.SYS_JAIL_REMOVE": "syscall",
+ "syscall.SYS_JAIL_SET": "syscall",
+ "syscall.SYS_KDEBUG_TRACE": "syscall",
+ "syscall.SYS_KENV": "syscall",
+ "syscall.SYS_KEVENT": "syscall",
+ "syscall.SYS_KEVENT64": "syscall",
+ "syscall.SYS_KEXEC_LOAD": "syscall",
+ "syscall.SYS_KEYCTL": "syscall",
+ "syscall.SYS_KILL": "syscall",
+ "syscall.SYS_KLDFIND": "syscall",
+ "syscall.SYS_KLDFIRSTMOD": "syscall",
+ "syscall.SYS_KLDLOAD": "syscall",
+ "syscall.SYS_KLDNEXT": "syscall",
+ "syscall.SYS_KLDSTAT": "syscall",
+ "syscall.SYS_KLDSYM": "syscall",
+ "syscall.SYS_KLDUNLOAD": "syscall",
+ "syscall.SYS_KLDUNLOADF": "syscall",
+ "syscall.SYS_KQUEUE": "syscall",
+ "syscall.SYS_KQUEUE1": "syscall",
+ "syscall.SYS_KTIMER_CREATE": "syscall",
+ "syscall.SYS_KTIMER_DELETE": "syscall",
+ "syscall.SYS_KTIMER_GETOVERRUN": "syscall",
+ "syscall.SYS_KTIMER_GETTIME": "syscall",
+ "syscall.SYS_KTIMER_SETTIME": "syscall",
+ "syscall.SYS_KTRACE": "syscall",
+ "syscall.SYS_LCHFLAGS": "syscall",
+ "syscall.SYS_LCHMOD": "syscall",
+ "syscall.SYS_LCHOWN": "syscall",
+ "syscall.SYS_LCHOWN32": "syscall",
+ "syscall.SYS_LGETFH": "syscall",
+ "syscall.SYS_LGETXATTR": "syscall",
+ "syscall.SYS_LINK": "syscall",
+ "syscall.SYS_LINKAT": "syscall",
+ "syscall.SYS_LIO_LISTIO": "syscall",
+ "syscall.SYS_LISTEN": "syscall",
+ "syscall.SYS_LISTXATTR": "syscall",
+ "syscall.SYS_LLISTXATTR": "syscall",
+ "syscall.SYS_LOCK": "syscall",
+ "syscall.SYS_LOOKUP_DCOOKIE": "syscall",
+ "syscall.SYS_LPATHCONF": "syscall",
+ "syscall.SYS_LREMOVEXATTR": "syscall",
+ "syscall.SYS_LSEEK": "syscall",
+ "syscall.SYS_LSETXATTR": "syscall",
+ "syscall.SYS_LSTAT": "syscall",
+ "syscall.SYS_LSTAT64": "syscall",
+ "syscall.SYS_LSTAT64_EXTENDED": "syscall",
+ "syscall.SYS_LSTATV": "syscall",
+ "syscall.SYS_LSTAT_EXTENDED": "syscall",
+ "syscall.SYS_LUTIMES": "syscall",
+ "syscall.SYS_MAC_SYSCALL": "syscall",
+ "syscall.SYS_MADVISE": "syscall",
+ "syscall.SYS_MADVISE1": "syscall",
+ "syscall.SYS_MAXSYSCALL": "syscall",
+ "syscall.SYS_MBIND": "syscall",
+ "syscall.SYS_MIGRATE_PAGES": "syscall",
+ "syscall.SYS_MINCORE": "syscall",
+ "syscall.SYS_MINHERIT": "syscall",
+ "syscall.SYS_MKCOMPLEX": "syscall",
+ "syscall.SYS_MKDIR": "syscall",
+ "syscall.SYS_MKDIRAT": "syscall",
+ "syscall.SYS_MKDIR_EXTENDED": "syscall",
+ "syscall.SYS_MKFIFO": "syscall",
+ "syscall.SYS_MKFIFOAT": "syscall",
+ "syscall.SYS_MKFIFO_EXTENDED": "syscall",
+ "syscall.SYS_MKNOD": "syscall",
+ "syscall.SYS_MKNODAT": "syscall",
+ "syscall.SYS_MLOCK": "syscall",
+ "syscall.SYS_MLOCKALL": "syscall",
+ "syscall.SYS_MMAP": "syscall",
+ "syscall.SYS_MMAP2": "syscall",
+ "syscall.SYS_MODCTL": "syscall",
+ "syscall.SYS_MODFIND": "syscall",
+ "syscall.SYS_MODFNEXT": "syscall",
+ "syscall.SYS_MODIFY_LDT": "syscall",
+ "syscall.SYS_MODNEXT": "syscall",
+ "syscall.SYS_MODSTAT": "syscall",
+ "syscall.SYS_MODWATCH": "syscall",
+ "syscall.SYS_MOUNT": "syscall",
+ "syscall.SYS_MOVE_PAGES": "syscall",
+ "syscall.SYS_MPROTECT": "syscall",
+ "syscall.SYS_MPX": "syscall",
+ "syscall.SYS_MQUERY": "syscall",
+ "syscall.SYS_MQ_GETSETATTR": "syscall",
+ "syscall.SYS_MQ_NOTIFY": "syscall",
+ "syscall.SYS_MQ_OPEN": "syscall",
+ "syscall.SYS_MQ_TIMEDRECEIVE": "syscall",
+ "syscall.SYS_MQ_TIMEDSEND": "syscall",
+ "syscall.SYS_MQ_UNLINK": "syscall",
+ "syscall.SYS_MREMAP": "syscall",
+ "syscall.SYS_MSGCTL": "syscall",
+ "syscall.SYS_MSGGET": "syscall",
+ "syscall.SYS_MSGRCV": "syscall",
+ "syscall.SYS_MSGRCV_NOCANCEL": "syscall",
+ "syscall.SYS_MSGSND": "syscall",
+ "syscall.SYS_MSGSND_NOCANCEL": "syscall",
+ "syscall.SYS_MSGSYS": "syscall",
+ "syscall.SYS_MSYNC": "syscall",
+ "syscall.SYS_MSYNC_NOCANCEL": "syscall",
+ "syscall.SYS_MUNLOCK": "syscall",
+ "syscall.SYS_MUNLOCKALL": "syscall",
+ "syscall.SYS_MUNMAP": "syscall",
+ "syscall.SYS_NAME_TO_HANDLE_AT": "syscall",
+ "syscall.SYS_NANOSLEEP": "syscall",
+ "syscall.SYS_NEWFSTATAT": "syscall",
+ "syscall.SYS_NFSCLNT": "syscall",
+ "syscall.SYS_NFSSERVCTL": "syscall",
+ "syscall.SYS_NFSSVC": "syscall",
+ "syscall.SYS_NFSTAT": "syscall",
+ "syscall.SYS_NICE": "syscall",
+ "syscall.SYS_NLSTAT": "syscall",
+ "syscall.SYS_NMOUNT": "syscall",
+ "syscall.SYS_NSTAT": "syscall",
+ "syscall.SYS_NTP_ADJTIME": "syscall",
+ "syscall.SYS_NTP_GETTIME": "syscall",
+ "syscall.SYS_OABI_SYSCALL_BASE": "syscall",
+ "syscall.SYS_OBREAK": "syscall",
+ "syscall.SYS_OLDFSTAT": "syscall",
+ "syscall.SYS_OLDLSTAT": "syscall",
+ "syscall.SYS_OLDOLDUNAME": "syscall",
+ "syscall.SYS_OLDSTAT": "syscall",
+ "syscall.SYS_OLDUNAME": "syscall",
+ "syscall.SYS_OPEN": "syscall",
+ "syscall.SYS_OPENAT": "syscall",
+ "syscall.SYS_OPENBSD_POLL": "syscall",
+ "syscall.SYS_OPEN_BY_HANDLE_AT": "syscall",
+ "syscall.SYS_OPEN_EXTENDED": "syscall",
+ "syscall.SYS_OPEN_NOCANCEL": "syscall",
+ "syscall.SYS_OVADVISE": "syscall",
+ "syscall.SYS_PACCEPT": "syscall",
+ "syscall.SYS_PATHCONF": "syscall",
+ "syscall.SYS_PAUSE": "syscall",
+ "syscall.SYS_PCICONFIG_IOBASE": "syscall",
+ "syscall.SYS_PCICONFIG_READ": "syscall",
+ "syscall.SYS_PCICONFIG_WRITE": "syscall",
+ "syscall.SYS_PDFORK": "syscall",
+ "syscall.SYS_PDGETPID": "syscall",
+ "syscall.SYS_PDKILL": "syscall",
+ "syscall.SYS_PERF_EVENT_OPEN": "syscall",
+ "syscall.SYS_PERSONALITY": "syscall",
+ "syscall.SYS_PID_HIBERNATE": "syscall",
+ "syscall.SYS_PID_RESUME": "syscall",
+ "syscall.SYS_PID_SHUTDOWN_SOCKETS": "syscall",
+ "syscall.SYS_PID_SUSPEND": "syscall",
+ "syscall.SYS_PIPE": "syscall",
+ "syscall.SYS_PIPE2": "syscall",
+ "syscall.SYS_PIVOT_ROOT": "syscall",
+ "syscall.SYS_PMC_CONTROL": "syscall",
+ "syscall.SYS_PMC_GET_INFO": "syscall",
+ "syscall.SYS_POLL": "syscall",
+ "syscall.SYS_POLLTS": "syscall",
+ "syscall.SYS_POLL_NOCANCEL": "syscall",
+ "syscall.SYS_POSIX_FADVISE": "syscall",
+ "syscall.SYS_POSIX_FALLOCATE": "syscall",
+ "syscall.SYS_POSIX_OPENPT": "syscall",
+ "syscall.SYS_POSIX_SPAWN": "syscall",
+ "syscall.SYS_PPOLL": "syscall",
+ "syscall.SYS_PRCTL": "syscall",
+ "syscall.SYS_PREAD": "syscall",
+ "syscall.SYS_PREAD64": "syscall",
+ "syscall.SYS_PREADV": "syscall",
+ "syscall.SYS_PREAD_NOCANCEL": "syscall",
+ "syscall.SYS_PRLIMIT64": "syscall",
+ "syscall.SYS_PROCESS_POLICY": "syscall",
+ "syscall.SYS_PROCESS_VM_READV": "syscall",
+ "syscall.SYS_PROCESS_VM_WRITEV": "syscall",
+ "syscall.SYS_PROC_INFO": "syscall",
+ "syscall.SYS_PROF": "syscall",
+ "syscall.SYS_PROFIL": "syscall",
+ "syscall.SYS_PSELECT": "syscall",
+ "syscall.SYS_PSELECT6": "syscall",
+ "syscall.SYS_PSET_ASSIGN": "syscall",
+ "syscall.SYS_PSET_CREATE": "syscall",
+ "syscall.SYS_PSET_DESTROY": "syscall",
+ "syscall.SYS_PSYNCH_CVBROAD": "syscall",
+ "syscall.SYS_PSYNCH_CVCLRPREPOST": "syscall",
+ "syscall.SYS_PSYNCH_CVSIGNAL": "syscall",
+ "syscall.SYS_PSYNCH_CVWAIT": "syscall",
+ "syscall.SYS_PSYNCH_MUTEXDROP": "syscall",
+ "syscall.SYS_PSYNCH_MUTEXWAIT": "syscall",
+ "syscall.SYS_PSYNCH_RW_DOWNGRADE": "syscall",
+ "syscall.SYS_PSYNCH_RW_LONGRDLOCK": "syscall",
+ "syscall.SYS_PSYNCH_RW_RDLOCK": "syscall",
+ "syscall.SYS_PSYNCH_RW_UNLOCK": "syscall",
+ "syscall.SYS_PSYNCH_RW_UNLOCK2": "syscall",
+ "syscall.SYS_PSYNCH_RW_UPGRADE": "syscall",
+ "syscall.SYS_PSYNCH_RW_WRLOCK": "syscall",
+ "syscall.SYS_PSYNCH_RW_YIELDWRLOCK": "syscall",
+ "syscall.SYS_PTRACE": "syscall",
+ "syscall.SYS_PUTPMSG": "syscall",
+ "syscall.SYS_PWRITE": "syscall",
+ "syscall.SYS_PWRITE64": "syscall",
+ "syscall.SYS_PWRITEV": "syscall",
+ "syscall.SYS_PWRITE_NOCANCEL": "syscall",
+ "syscall.SYS_QUERY_MODULE": "syscall",
+ "syscall.SYS_QUOTACTL": "syscall",
+ "syscall.SYS_RASCTL": "syscall",
+ "syscall.SYS_RCTL_ADD_RULE": "syscall",
+ "syscall.SYS_RCTL_GET_LIMITS": "syscall",
+ "syscall.SYS_RCTL_GET_RACCT": "syscall",
+ "syscall.SYS_RCTL_GET_RULES": "syscall",
+ "syscall.SYS_RCTL_REMOVE_RULE": "syscall",
+ "syscall.SYS_READ": "syscall",
+ "syscall.SYS_READAHEAD": "syscall",
+ "syscall.SYS_READDIR": "syscall",
+ "syscall.SYS_READLINK": "syscall",
+ "syscall.SYS_READLINKAT": "syscall",
+ "syscall.SYS_READV": "syscall",
+ "syscall.SYS_READV_NOCANCEL": "syscall",
+ "syscall.SYS_READ_NOCANCEL": "syscall",
+ "syscall.SYS_REBOOT": "syscall",
+ "syscall.SYS_RECV": "syscall",
+ "syscall.SYS_RECVFROM": "syscall",
+ "syscall.SYS_RECVFROM_NOCANCEL": "syscall",
+ "syscall.SYS_RECVMMSG": "syscall",
+ "syscall.SYS_RECVMSG": "syscall",
+ "syscall.SYS_RECVMSG_NOCANCEL": "syscall",
+ "syscall.SYS_REMAP_FILE_PAGES": "syscall",
+ "syscall.SYS_REMOVEXATTR": "syscall",
+ "syscall.SYS_RENAME": "syscall",
+ "syscall.SYS_RENAMEAT": "syscall",
+ "syscall.SYS_REQUEST_KEY": "syscall",
+ "syscall.SYS_RESTART_SYSCALL": "syscall",
+ "syscall.SYS_REVOKE": "syscall",
+ "syscall.SYS_RFORK": "syscall",
+ "syscall.SYS_RMDIR": "syscall",
+ "syscall.SYS_RTPRIO": "syscall",
+ "syscall.SYS_RTPRIO_THREAD": "syscall",
+ "syscall.SYS_RT_SIGACTION": "syscall",
+ "syscall.SYS_RT_SIGPENDING": "syscall",
+ "syscall.SYS_RT_SIGPROCMASK": "syscall",
+ "syscall.SYS_RT_SIGQUEUEINFO": "syscall",
+ "syscall.SYS_RT_SIGRETURN": "syscall",
+ "syscall.SYS_RT_SIGSUSPEND": "syscall",
+ "syscall.SYS_RT_SIGTIMEDWAIT": "syscall",
+ "syscall.SYS_RT_TGSIGQUEUEINFO": "syscall",
+ "syscall.SYS_SBRK": "syscall",
+ "syscall.SYS_SCHED_GETAFFINITY": "syscall",
+ "syscall.SYS_SCHED_GETPARAM": "syscall",
+ "syscall.SYS_SCHED_GETSCHEDULER": "syscall",
+ "syscall.SYS_SCHED_GET_PRIORITY_MAX": "syscall",
+ "syscall.SYS_SCHED_GET_PRIORITY_MIN": "syscall",
+ "syscall.SYS_SCHED_RR_GET_INTERVAL": "syscall",
+ "syscall.SYS_SCHED_SETAFFINITY": "syscall",
+ "syscall.SYS_SCHED_SETPARAM": "syscall",
+ "syscall.SYS_SCHED_SETSCHEDULER": "syscall",
+ "syscall.SYS_SCHED_YIELD": "syscall",
+ "syscall.SYS_SCTP_GENERIC_RECVMSG": "syscall",
+ "syscall.SYS_SCTP_GENERIC_SENDMSG": "syscall",
+ "syscall.SYS_SCTP_GENERIC_SENDMSG_IOV": "syscall",
+ "syscall.SYS_SCTP_PEELOFF": "syscall",
+ "syscall.SYS_SEARCHFS": "syscall",
+ "syscall.SYS_SECURITY": "syscall",
+ "syscall.SYS_SELECT": "syscall",
+ "syscall.SYS_SELECT_NOCANCEL": "syscall",
+ "syscall.SYS_SEMCONFIG": "syscall",
+ "syscall.SYS_SEMCTL": "syscall",
+ "syscall.SYS_SEMGET": "syscall",
+ "syscall.SYS_SEMOP": "syscall",
+ "syscall.SYS_SEMSYS": "syscall",
+ "syscall.SYS_SEMTIMEDOP": "syscall",
+ "syscall.SYS_SEM_CLOSE": "syscall",
+ "syscall.SYS_SEM_DESTROY": "syscall",
+ "syscall.SYS_SEM_GETVALUE": "syscall",
+ "syscall.SYS_SEM_INIT": "syscall",
+ "syscall.SYS_SEM_OPEN": "syscall",
+ "syscall.SYS_SEM_POST": "syscall",
+ "syscall.SYS_SEM_TRYWAIT": "syscall",
+ "syscall.SYS_SEM_UNLINK": "syscall",
+ "syscall.SYS_SEM_WAIT": "syscall",
+ "syscall.SYS_SEM_WAIT_NOCANCEL": "syscall",
+ "syscall.SYS_SEND": "syscall",
+ "syscall.SYS_SENDFILE": "syscall",
+ "syscall.SYS_SENDFILE64": "syscall",
+ "syscall.SYS_SENDMMSG": "syscall",
+ "syscall.SYS_SENDMSG": "syscall",
+ "syscall.SYS_SENDMSG_NOCANCEL": "syscall",
+ "syscall.SYS_SENDTO": "syscall",
+ "syscall.SYS_SENDTO_NOCANCEL": "syscall",
+ "syscall.SYS_SETATTRLIST": "syscall",
+ "syscall.SYS_SETAUDIT": "syscall",
+ "syscall.SYS_SETAUDIT_ADDR": "syscall",
+ "syscall.SYS_SETAUID": "syscall",
+ "syscall.SYS_SETCONTEXT": "syscall",
+ "syscall.SYS_SETDOMAINNAME": "syscall",
+ "syscall.SYS_SETEGID": "syscall",
+ "syscall.SYS_SETEUID": "syscall",
+ "syscall.SYS_SETFIB": "syscall",
+ "syscall.SYS_SETFSGID": "syscall",
+ "syscall.SYS_SETFSGID32": "syscall",
+ "syscall.SYS_SETFSUID": "syscall",
+ "syscall.SYS_SETFSUID32": "syscall",
+ "syscall.SYS_SETGID": "syscall",
+ "syscall.SYS_SETGID32": "syscall",
+ "syscall.SYS_SETGROUPS": "syscall",
+ "syscall.SYS_SETGROUPS32": "syscall",
+ "syscall.SYS_SETHOSTNAME": "syscall",
+ "syscall.SYS_SETITIMER": "syscall",
+ "syscall.SYS_SETLCID": "syscall",
+ "syscall.SYS_SETLOGIN": "syscall",
+ "syscall.SYS_SETLOGINCLASS": "syscall",
+ "syscall.SYS_SETNS": "syscall",
+ "syscall.SYS_SETPGID": "syscall",
+ "syscall.SYS_SETPRIORITY": "syscall",
+ "syscall.SYS_SETPRIVEXEC": "syscall",
+ "syscall.SYS_SETREGID": "syscall",
+ "syscall.SYS_SETREGID32": "syscall",
+ "syscall.SYS_SETRESGID": "syscall",
+ "syscall.SYS_SETRESGID32": "syscall",
+ "syscall.SYS_SETRESUID": "syscall",
+ "syscall.SYS_SETRESUID32": "syscall",
+ "syscall.SYS_SETREUID": "syscall",
+ "syscall.SYS_SETREUID32": "syscall",
+ "syscall.SYS_SETRLIMIT": "syscall",
+ "syscall.SYS_SETRTABLE": "syscall",
+ "syscall.SYS_SETSGROUPS": "syscall",
+ "syscall.SYS_SETSID": "syscall",
+ "syscall.SYS_SETSOCKOPT": "syscall",
+ "syscall.SYS_SETTID": "syscall",
+ "syscall.SYS_SETTID_WITH_PID": "syscall",
+ "syscall.SYS_SETTIMEOFDAY": "syscall",
+ "syscall.SYS_SETUID": "syscall",
+ "syscall.SYS_SETUID32": "syscall",
+ "syscall.SYS_SETWGROUPS": "syscall",
+ "syscall.SYS_SETXATTR": "syscall",
+ "syscall.SYS_SET_MEMPOLICY": "syscall",
+ "syscall.SYS_SET_ROBUST_LIST": "syscall",
+ "syscall.SYS_SET_THREAD_AREA": "syscall",
+ "syscall.SYS_SET_TID_ADDRESS": "syscall",
+ "syscall.SYS_SGETMASK": "syscall",
+ "syscall.SYS_SHARED_REGION_CHECK_NP": "syscall",
+ "syscall.SYS_SHARED_REGION_MAP_AND_SLIDE_NP": "syscall",
+ "syscall.SYS_SHMAT": "syscall",
+ "syscall.SYS_SHMCTL": "syscall",
+ "syscall.SYS_SHMDT": "syscall",
+ "syscall.SYS_SHMGET": "syscall",
+ "syscall.SYS_SHMSYS": "syscall",
+ "syscall.SYS_SHM_OPEN": "syscall",
+ "syscall.SYS_SHM_UNLINK": "syscall",
+ "syscall.SYS_SHUTDOWN": "syscall",
+ "syscall.SYS_SIGACTION": "syscall",
+ "syscall.SYS_SIGALTSTACK": "syscall",
+ "syscall.SYS_SIGNAL": "syscall",
+ "syscall.SYS_SIGNALFD": "syscall",
+ "syscall.SYS_SIGNALFD4": "syscall",
+ "syscall.SYS_SIGPENDING": "syscall",
+ "syscall.SYS_SIGPROCMASK": "syscall",
+ "syscall.SYS_SIGQUEUE": "syscall",
+ "syscall.SYS_SIGQUEUEINFO": "syscall",
+ "syscall.SYS_SIGRETURN": "syscall",
+ "syscall.SYS_SIGSUSPEND": "syscall",
+ "syscall.SYS_SIGSUSPEND_NOCANCEL": "syscall",
+ "syscall.SYS_SIGTIMEDWAIT": "syscall",
+ "syscall.SYS_SIGWAIT": "syscall",
+ "syscall.SYS_SIGWAITINFO": "syscall",
+ "syscall.SYS_SOCKET": "syscall",
+ "syscall.SYS_SOCKETCALL": "syscall",
+ "syscall.SYS_SOCKETPAIR": "syscall",
+ "syscall.SYS_SPLICE": "syscall",
+ "syscall.SYS_SSETMASK": "syscall",
+ "syscall.SYS_SSTK": "syscall",
+ "syscall.SYS_STACK_SNAPSHOT": "syscall",
+ "syscall.SYS_STAT": "syscall",
+ "syscall.SYS_STAT64": "syscall",
+ "syscall.SYS_STAT64_EXTENDED": "syscall",
+ "syscall.SYS_STATFS": "syscall",
+ "syscall.SYS_STATFS64": "syscall",
+ "syscall.SYS_STATV": "syscall",
+ "syscall.SYS_STATVFS1": "syscall",
+ "syscall.SYS_STAT_EXTENDED": "syscall",
+ "syscall.SYS_STIME": "syscall",
+ "syscall.SYS_STTY": "syscall",
+ "syscall.SYS_SWAPCONTEXT": "syscall",
+ "syscall.SYS_SWAPCTL": "syscall",
+ "syscall.SYS_SWAPOFF": "syscall",
+ "syscall.SYS_SWAPON": "syscall",
+ "syscall.SYS_SYMLINK": "syscall",
+ "syscall.SYS_SYMLINKAT": "syscall",
+ "syscall.SYS_SYNC": "syscall",
+ "syscall.SYS_SYNCFS": "syscall",
+ "syscall.SYS_SYNC_FILE_RANGE": "syscall",
+ "syscall.SYS_SYSARCH": "syscall",
+ "syscall.SYS_SYSCALL": "syscall",
+ "syscall.SYS_SYSCALL_BASE": "syscall",
+ "syscall.SYS_SYSFS": "syscall",
+ "syscall.SYS_SYSINFO": "syscall",
+ "syscall.SYS_SYSLOG": "syscall",
+ "syscall.SYS_TEE": "syscall",
+ "syscall.SYS_TGKILL": "syscall",
+ "syscall.SYS_THREAD_SELFID": "syscall",
+ "syscall.SYS_THR_CREATE": "syscall",
+ "syscall.SYS_THR_EXIT": "syscall",
+ "syscall.SYS_THR_KILL": "syscall",
+ "syscall.SYS_THR_KILL2": "syscall",
+ "syscall.SYS_THR_NEW": "syscall",
+ "syscall.SYS_THR_SELF": "syscall",
+ "syscall.SYS_THR_SET_NAME": "syscall",
+ "syscall.SYS_THR_SUSPEND": "syscall",
+ "syscall.SYS_THR_WAKE": "syscall",
+ "syscall.SYS_TIME": "syscall",
+ "syscall.SYS_TIMERFD_CREATE": "syscall",
+ "syscall.SYS_TIMERFD_GETTIME": "syscall",
+ "syscall.SYS_TIMERFD_SETTIME": "syscall",
+ "syscall.SYS_TIMER_CREATE": "syscall",
+ "syscall.SYS_TIMER_DELETE": "syscall",
+ "syscall.SYS_TIMER_GETOVERRUN": "syscall",
+ "syscall.SYS_TIMER_GETTIME": "syscall",
+ "syscall.SYS_TIMER_SETTIME": "syscall",
+ "syscall.SYS_TIMES": "syscall",
+ "syscall.SYS_TKILL": "syscall",
+ "syscall.SYS_TRUNCATE": "syscall",
+ "syscall.SYS_TRUNCATE64": "syscall",
+ "syscall.SYS_TUXCALL": "syscall",
+ "syscall.SYS_UGETRLIMIT": "syscall",
+ "syscall.SYS_ULIMIT": "syscall",
+ "syscall.SYS_UMASK": "syscall",
+ "syscall.SYS_UMASK_EXTENDED": "syscall",
+ "syscall.SYS_UMOUNT": "syscall",
+ "syscall.SYS_UMOUNT2": "syscall",
+ "syscall.SYS_UNAME": "syscall",
+ "syscall.SYS_UNDELETE": "syscall",
+ "syscall.SYS_UNLINK": "syscall",
+ "syscall.SYS_UNLINKAT": "syscall",
+ "syscall.SYS_UNMOUNT": "syscall",
+ "syscall.SYS_UNSHARE": "syscall",
+ "syscall.SYS_USELIB": "syscall",
+ "syscall.SYS_USTAT": "syscall",
+ "syscall.SYS_UTIME": "syscall",
+ "syscall.SYS_UTIMENSAT": "syscall",
+ "syscall.SYS_UTIMES": "syscall",
+ "syscall.SYS_UTRACE": "syscall",
+ "syscall.SYS_UUIDGEN": "syscall",
+ "syscall.SYS_VADVISE": "syscall",
+ "syscall.SYS_VFORK": "syscall",
+ "syscall.SYS_VHANGUP": "syscall",
+ "syscall.SYS_VM86": "syscall",
+ "syscall.SYS_VM86OLD": "syscall",
+ "syscall.SYS_VMSPLICE": "syscall",
+ "syscall.SYS_VM_PRESSURE_MONITOR": "syscall",
+ "syscall.SYS_VSERVER": "syscall",
+ "syscall.SYS_WAIT4": "syscall",
+ "syscall.SYS_WAIT4_NOCANCEL": "syscall",
+ "syscall.SYS_WAIT6": "syscall",
+ "syscall.SYS_WAITEVENT": "syscall",
+ "syscall.SYS_WAITID": "syscall",
+ "syscall.SYS_WAITID_NOCANCEL": "syscall",
+ "syscall.SYS_WAITPID": "syscall",
+ "syscall.SYS_WATCHEVENT": "syscall",
+ "syscall.SYS_WORKQ_KERNRETURN": "syscall",
+ "syscall.SYS_WORKQ_OPEN": "syscall",
+ "syscall.SYS_WRITE": "syscall",
+ "syscall.SYS_WRITEV": "syscall",
+ "syscall.SYS_WRITEV_NOCANCEL": "syscall",
+ "syscall.SYS_WRITE_NOCANCEL": "syscall",
+ "syscall.SYS_YIELD": "syscall",
+ "syscall.SYS__LLSEEK": "syscall",
+ "syscall.SYS__LWP_CONTINUE": "syscall",
+ "syscall.SYS__LWP_CREATE": "syscall",
+ "syscall.SYS__LWP_CTL": "syscall",
+ "syscall.SYS__LWP_DETACH": "syscall",
+ "syscall.SYS__LWP_EXIT": "syscall",
+ "syscall.SYS__LWP_GETNAME": "syscall",
+ "syscall.SYS__LWP_GETPRIVATE": "syscall",
+ "syscall.SYS__LWP_KILL": "syscall",
+ "syscall.SYS__LWP_PARK": "syscall",
+ "syscall.SYS__LWP_SELF": "syscall",
+ "syscall.SYS__LWP_SETNAME": "syscall",
+ "syscall.SYS__LWP_SETPRIVATE": "syscall",
+ "syscall.SYS__LWP_SUSPEND": "syscall",
+ "syscall.SYS__LWP_UNPARK": "syscall",
+ "syscall.SYS__LWP_UNPARK_ALL": "syscall",
+ "syscall.SYS__LWP_WAIT": "syscall",
+ "syscall.SYS__LWP_WAKEUP": "syscall",
+ "syscall.SYS__NEWSELECT": "syscall",
+ "syscall.SYS__PSET_BIND": "syscall",
+ "syscall.SYS__SCHED_GETAFFINITY": "syscall",
+ "syscall.SYS__SCHED_GETPARAM": "syscall",
+ "syscall.SYS__SCHED_SETAFFINITY": "syscall",
+ "syscall.SYS__SCHED_SETPARAM": "syscall",
+ "syscall.SYS__SYSCTL": "syscall",
+ "syscall.SYS__UMTX_LOCK": "syscall",
+ "syscall.SYS__UMTX_OP": "syscall",
+ "syscall.SYS__UMTX_UNLOCK": "syscall",
+ "syscall.SYS___ACL_ACLCHECK_FD": "syscall",
+ "syscall.SYS___ACL_ACLCHECK_FILE": "syscall",
+ "syscall.SYS___ACL_ACLCHECK_LINK": "syscall",
+ "syscall.SYS___ACL_DELETE_FD": "syscall",
+ "syscall.SYS___ACL_DELETE_FILE": "syscall",
+ "syscall.SYS___ACL_DELETE_LINK": "syscall",
+ "syscall.SYS___ACL_GET_FD": "syscall",
+ "syscall.SYS___ACL_GET_FILE": "syscall",
+ "syscall.SYS___ACL_GET_LINK": "syscall",
+ "syscall.SYS___ACL_SET_FD": "syscall",
+ "syscall.SYS___ACL_SET_FILE": "syscall",
+ "syscall.SYS___ACL_SET_LINK": "syscall",
+ "syscall.SYS___CLONE": "syscall",
+ "syscall.SYS___DISABLE_THREADSIGNAL": "syscall",
+ "syscall.SYS___GETCWD": "syscall",
+ "syscall.SYS___GETLOGIN": "syscall",
+ "syscall.SYS___GET_TCB": "syscall",
+ "syscall.SYS___MAC_EXECVE": "syscall",
+ "syscall.SYS___MAC_GETFSSTAT": "syscall",
+ "syscall.SYS___MAC_GET_FD": "syscall",
+ "syscall.SYS___MAC_GET_FILE": "syscall",
+ "syscall.SYS___MAC_GET_LCID": "syscall",
+ "syscall.SYS___MAC_GET_LCTX": "syscall",
+ "syscall.SYS___MAC_GET_LINK": "syscall",
+ "syscall.SYS___MAC_GET_MOUNT": "syscall",
+ "syscall.SYS___MAC_GET_PID": "syscall",
+ "syscall.SYS___MAC_GET_PROC": "syscall",
+ "syscall.SYS___MAC_MOUNT": "syscall",
+ "syscall.SYS___MAC_SET_FD": "syscall",
+ "syscall.SYS___MAC_SET_FILE": "syscall",
+ "syscall.SYS___MAC_SET_LCTX": "syscall",
+ "syscall.SYS___MAC_SET_LINK": "syscall",
+ "syscall.SYS___MAC_SET_PROC": "syscall",
+ "syscall.SYS___MAC_SYSCALL": "syscall",
+ "syscall.SYS___OLD_SEMWAIT_SIGNAL": "syscall",
+ "syscall.SYS___OLD_SEMWAIT_SIGNAL_NOCANCEL": "syscall",
+ "syscall.SYS___POSIX_CHOWN": "syscall",
+ "syscall.SYS___POSIX_FCHOWN": "syscall",
+ "syscall.SYS___POSIX_LCHOWN": "syscall",
+ "syscall.SYS___POSIX_RENAME": "syscall",
+ "syscall.SYS___PTHREAD_CANCELED": "syscall",
+ "syscall.SYS___PTHREAD_CHDIR": "syscall",
+ "syscall.SYS___PTHREAD_FCHDIR": "syscall",
+ "syscall.SYS___PTHREAD_KILL": "syscall",
+ "syscall.SYS___PTHREAD_MARKCANCEL": "syscall",
+ "syscall.SYS___PTHREAD_SIGMASK": "syscall",
+ "syscall.SYS___QUOTACTL": "syscall",
+ "syscall.SYS___SEMCTL": "syscall",
+ "syscall.SYS___SEMWAIT_SIGNAL": "syscall",
+ "syscall.SYS___SEMWAIT_SIGNAL_NOCANCEL": "syscall",
+ "syscall.SYS___SETLOGIN": "syscall",
+ "syscall.SYS___SETUGID": "syscall",
+ "syscall.SYS___SET_TCB": "syscall",
+ "syscall.SYS___SIGACTION_SIGTRAMP": "syscall",
+ "syscall.SYS___SIGTIMEDWAIT": "syscall",
+ "syscall.SYS___SIGWAIT": "syscall",
+ "syscall.SYS___SIGWAIT_NOCANCEL": "syscall",
+ "syscall.SYS___SYSCTL": "syscall",
+ "syscall.SYS___TFORK": "syscall",
+ "syscall.SYS___THREXIT": "syscall",
+ "syscall.SYS___THRSIGDIVERT": "syscall",
+ "syscall.SYS___THRSLEEP": "syscall",
+ "syscall.SYS___THRWAKEUP": "syscall",
+ "syscall.S_ARCH1": "syscall",
+ "syscall.S_ARCH2": "syscall",
+ "syscall.S_BLKSIZE": "syscall",
+ "syscall.S_IEXEC": "syscall",
+ "syscall.S_IFBLK": "syscall",
+ "syscall.S_IFCHR": "syscall",
+ "syscall.S_IFDIR": "syscall",
+ "syscall.S_IFIFO": "syscall",
+ "syscall.S_IFLNK": "syscall",
+ "syscall.S_IFMT": "syscall",
+ "syscall.S_IFREG": "syscall",
+ "syscall.S_IFSOCK": "syscall",
+ "syscall.S_IFWHT": "syscall",
+ "syscall.S_IREAD": "syscall",
+ "syscall.S_IRGRP": "syscall",
+ "syscall.S_IROTH": "syscall",
+ "syscall.S_IRUSR": "syscall",
+ "syscall.S_IRWXG": "syscall",
+ "syscall.S_IRWXO": "syscall",
+ "syscall.S_IRWXU": "syscall",
+ "syscall.S_ISGID": "syscall",
+ "syscall.S_ISTXT": "syscall",
+ "syscall.S_ISUID": "syscall",
+ "syscall.S_ISVTX": "syscall",
+ "syscall.S_IWGRP": "syscall",
+ "syscall.S_IWOTH": "syscall",
+ "syscall.S_IWRITE": "syscall",
+ "syscall.S_IWUSR": "syscall",
+ "syscall.S_IXGRP": "syscall",
+ "syscall.S_IXOTH": "syscall",
+ "syscall.S_IXUSR": "syscall",
+ "syscall.S_LOGIN_SET": "syscall",
+ "syscall.SecurityAttributes": "syscall",
+ "syscall.Seek": "syscall",
+ "syscall.Select": "syscall",
+ "syscall.Sendfile": "syscall",
+ "syscall.Sendmsg": "syscall",
+ "syscall.Sendto": "syscall",
+ "syscall.Servent": "syscall",
+ "syscall.SetBpf": "syscall",
+ "syscall.SetBpfBuflen": "syscall",
+ "syscall.SetBpfDatalink": "syscall",
+ "syscall.SetBpfHeadercmpl": "syscall",
+ "syscall.SetBpfImmediate": "syscall",
+ "syscall.SetBpfInterface": "syscall",
+ "syscall.SetBpfPromisc": "syscall",
+ "syscall.SetBpfTimeout": "syscall",
+ "syscall.SetCurrentDirectory": "syscall",
+ "syscall.SetEndOfFile": "syscall",
+ "syscall.SetEnvironmentVariable": "syscall",
+ "syscall.SetFileAttributes": "syscall",
+ "syscall.SetFileCompletionNotificationModes": "syscall",
+ "syscall.SetFilePointer": "syscall",
+ "syscall.SetFileTime": "syscall",
+ "syscall.SetHandleInformation": "syscall",
+ "syscall.SetKevent": "syscall",
+ "syscall.SetLsfPromisc": "syscall",
+ "syscall.SetNonblock": "syscall",
+ "syscall.Setdomainname": "syscall",
+ "syscall.Setegid": "syscall",
+ "syscall.Setenv": "syscall",
+ "syscall.Seteuid": "syscall",
+ "syscall.Setfsgid": "syscall",
+ "syscall.Setfsuid": "syscall",
+ "syscall.Setgid": "syscall",
+ "syscall.Setgroups": "syscall",
+ "syscall.Sethostname": "syscall",
+ "syscall.Setlogin": "syscall",
+ "syscall.Setpgid": "syscall",
+ "syscall.Setpriority": "syscall",
+ "syscall.Setprivexec": "syscall",
+ "syscall.Setregid": "syscall",
+ "syscall.Setresgid": "syscall",
+ "syscall.Setresuid": "syscall",
+ "syscall.Setreuid": "syscall",
+ "syscall.Setrlimit": "syscall",
+ "syscall.Setsid": "syscall",
+ "syscall.Setsockopt": "syscall",
+ "syscall.SetsockoptByte": "syscall",
+ "syscall.SetsockoptICMPv6Filter": "syscall",
+ "syscall.SetsockoptIPMreq": "syscall",
+ "syscall.SetsockoptIPMreqn": "syscall",
+ "syscall.SetsockoptIPv6Mreq": "syscall",
+ "syscall.SetsockoptInet4Addr": "syscall",
+ "syscall.SetsockoptInt": "syscall",
+ "syscall.SetsockoptLinger": "syscall",
+ "syscall.SetsockoptString": "syscall",
+ "syscall.SetsockoptTimeval": "syscall",
+ "syscall.Settimeofday": "syscall",
+ "syscall.Setuid": "syscall",
+ "syscall.Setxattr": "syscall",
+ "syscall.Shutdown": "syscall",
+ "syscall.SidTypeAlias": "syscall",
+ "syscall.SidTypeComputer": "syscall",
+ "syscall.SidTypeDeletedAccount": "syscall",
+ "syscall.SidTypeDomain": "syscall",
+ "syscall.SidTypeGroup": "syscall",
+ "syscall.SidTypeInvalid": "syscall",
+ "syscall.SidTypeLabel": "syscall",
+ "syscall.SidTypeUnknown": "syscall",
+ "syscall.SidTypeUser": "syscall",
+ "syscall.SidTypeWellKnownGroup": "syscall",
+ "syscall.Signal": "syscall",
+ "syscall.SizeofBpfHdr": "syscall",
+ "syscall.SizeofBpfInsn": "syscall",
+ "syscall.SizeofBpfProgram": "syscall",
+ "syscall.SizeofBpfStat": "syscall",
+ "syscall.SizeofBpfVersion": "syscall",
+ "syscall.SizeofBpfZbuf": "syscall",
+ "syscall.SizeofBpfZbufHeader": "syscall",
+ "syscall.SizeofCmsghdr": "syscall",
+ "syscall.SizeofICMPv6Filter": "syscall",
+ "syscall.SizeofIPMreq": "syscall",
+ "syscall.SizeofIPMreqn": "syscall",
+ "syscall.SizeofIPv6MTUInfo": "syscall",
+ "syscall.SizeofIPv6Mreq": "syscall",
+ "syscall.SizeofIfAddrmsg": "syscall",
+ "syscall.SizeofIfAnnounceMsghdr": "syscall",
+ "syscall.SizeofIfData": "syscall",
+ "syscall.SizeofIfInfomsg": "syscall",
+ "syscall.SizeofIfMsghdr": "syscall",
+ "syscall.SizeofIfaMsghdr": "syscall",
+ "syscall.SizeofIfmaMsghdr": "syscall",
+ "syscall.SizeofIfmaMsghdr2": "syscall",
+ "syscall.SizeofInet4Pktinfo": "syscall",
+ "syscall.SizeofInet6Pktinfo": "syscall",
+ "syscall.SizeofInotifyEvent": "syscall",
+ "syscall.SizeofLinger": "syscall",
+ "syscall.SizeofMsghdr": "syscall",
+ "syscall.SizeofNlAttr": "syscall",
+ "syscall.SizeofNlMsgerr": "syscall",
+ "syscall.SizeofNlMsghdr": "syscall",
+ "syscall.SizeofRtAttr": "syscall",
+ "syscall.SizeofRtGenmsg": "syscall",
+ "syscall.SizeofRtMetrics": "syscall",
+ "syscall.SizeofRtMsg": "syscall",
+ "syscall.SizeofRtMsghdr": "syscall",
+ "syscall.SizeofRtNexthop": "syscall",
+ "syscall.SizeofSockFilter": "syscall",
+ "syscall.SizeofSockFprog": "syscall",
+ "syscall.SizeofSockaddrAny": "syscall",
+ "syscall.SizeofSockaddrDatalink": "syscall",
+ "syscall.SizeofSockaddrInet4": "syscall",
+ "syscall.SizeofSockaddrInet6": "syscall",
+ "syscall.SizeofSockaddrLinklayer": "syscall",
+ "syscall.SizeofSockaddrNetlink": "syscall",
+ "syscall.SizeofSockaddrUnix": "syscall",
+ "syscall.SizeofTCPInfo": "syscall",
+ "syscall.SizeofUcred": "syscall",
+ "syscall.SlicePtrFromStrings": "syscall",
+ "syscall.SockFilter": "syscall",
+ "syscall.SockFprog": "syscall",
+ "syscall.SockaddrDatalink": "syscall",
+ "syscall.SockaddrGen": "syscall",
+ "syscall.SockaddrInet4": "syscall",
+ "syscall.SockaddrInet6": "syscall",
+ "syscall.SockaddrLinklayer": "syscall",
+ "syscall.SockaddrNetlink": "syscall",
+ "syscall.SockaddrUnix": "syscall",
+ "syscall.Socket": "syscall",
+ "syscall.SocketControlMessage": "syscall",
+ "syscall.SocketDisableIPv6": "syscall",
+ "syscall.Socketpair": "syscall",
+ "syscall.Splice": "syscall",
+ "syscall.StartProcess": "syscall",
+ "syscall.StartupInfo": "syscall",
+ "syscall.Stat": "syscall",
+ "syscall.Stat_t": "syscall",
+ "syscall.Statfs": "syscall",
+ "syscall.Statfs_t": "syscall",
+ "syscall.Stderr": "syscall",
+ "syscall.Stdin": "syscall",
+ "syscall.Stdout": "syscall",
+ "syscall.StringBytePtr": "syscall",
+ "syscall.StringByteSlice": "syscall",
+ "syscall.StringSlicePtr": "syscall",
+ "syscall.StringToSid": "syscall",
+ "syscall.StringToUTF16": "syscall",
+ "syscall.StringToUTF16Ptr": "syscall",
+ "syscall.Symlink": "syscall",
+ "syscall.Sync": "syscall",
+ "syscall.SyncFileRange": "syscall",
+ "syscall.SysProcAttr": "syscall",
+ "syscall.Syscall": "syscall",
+ "syscall.Syscall12": "syscall",
+ "syscall.Syscall15": "syscall",
+ "syscall.Syscall6": "syscall",
+ "syscall.Syscall9": "syscall",
+ "syscall.Sysctl": "syscall",
+ "syscall.SysctlUint32": "syscall",
+ "syscall.Sysctlnode": "syscall",
+ "syscall.Sysinfo": "syscall",
+ "syscall.Sysinfo_t": "syscall",
+ "syscall.Systemtime": "syscall",
+ "syscall.TCGETS": "syscall",
+ "syscall.TCIFLUSH": "syscall",
+ "syscall.TCIOFLUSH": "syscall",
+ "syscall.TCOFLUSH": "syscall",
+ "syscall.TCPInfo": "syscall",
+ "syscall.TCP_CA_NAME_MAX": "syscall",
+ "syscall.TCP_CONGCTL": "syscall",
+ "syscall.TCP_CONGESTION": "syscall",
+ "syscall.TCP_CONNECTIONTIMEOUT": "syscall",
+ "syscall.TCP_CORK": "syscall",
+ "syscall.TCP_DEFER_ACCEPT": "syscall",
+ "syscall.TCP_INFO": "syscall",
+ "syscall.TCP_KEEPALIVE": "syscall",
+ "syscall.TCP_KEEPCNT": "syscall",
+ "syscall.TCP_KEEPIDLE": "syscall",
+ "syscall.TCP_KEEPINIT": "syscall",
+ "syscall.TCP_KEEPINTVL": "syscall",
+ "syscall.TCP_LINGER2": "syscall",
+ "syscall.TCP_MAXBURST": "syscall",
+ "syscall.TCP_MAXHLEN": "syscall",
+ "syscall.TCP_MAXOLEN": "syscall",
+ "syscall.TCP_MAXSEG": "syscall",
+ "syscall.TCP_MAXWIN": "syscall",
+ "syscall.TCP_MAX_SACK": "syscall",
+ "syscall.TCP_MAX_WINSHIFT": "syscall",
+ "syscall.TCP_MD5SIG": "syscall",
+ "syscall.TCP_MD5SIG_MAXKEYLEN": "syscall",
+ "syscall.TCP_MINMSS": "syscall",
+ "syscall.TCP_MINMSSOVERLOAD": "syscall",
+ "syscall.TCP_MSS": "syscall",
+ "syscall.TCP_NODELAY": "syscall",
+ "syscall.TCP_NOOPT": "syscall",
+ "syscall.TCP_NOPUSH": "syscall",
+ "syscall.TCP_NSTATES": "syscall",
+ "syscall.TCP_QUICKACK": "syscall",
+ "syscall.TCP_RXT_CONNDROPTIME": "syscall",
+ "syscall.TCP_RXT_FINDROP": "syscall",
+ "syscall.TCP_SACK_ENABLE": "syscall",
+ "syscall.TCP_SYNCNT": "syscall",
+ "syscall.TCP_WINDOW_CLAMP": "syscall",
+ "syscall.TCSAFLUSH": "syscall",
+ "syscall.TCSETS": "syscall",
+ "syscall.TF_DISCONNECT": "syscall",
+ "syscall.TF_REUSE_SOCKET": "syscall",
+ "syscall.TF_USE_DEFAULT_WORKER": "syscall",
+ "syscall.TF_USE_KERNEL_APC": "syscall",
+ "syscall.TF_USE_SYSTEM_THREAD": "syscall",
+ "syscall.TF_WRITE_BEHIND": "syscall",
+ "syscall.TIME_ZONE_ID_DAYLIGHT": "syscall",
+ "syscall.TIME_ZONE_ID_STANDARD": "syscall",
+ "syscall.TIME_ZONE_ID_UNKNOWN": "syscall",
+ "syscall.TIOCCBRK": "syscall",
+ "syscall.TIOCCDTR": "syscall",
+ "syscall.TIOCCONS": "syscall",
+ "syscall.TIOCDCDTIMESTAMP": "syscall",
+ "syscall.TIOCDRAIN": "syscall",
+ "syscall.TIOCDSIMICROCODE": "syscall",
+ "syscall.TIOCEXCL": "syscall",
+ "syscall.TIOCEXT": "syscall",
+ "syscall.TIOCFLAG_CDTRCTS": "syscall",
+ "syscall.TIOCFLAG_CLOCAL": "syscall",
+ "syscall.TIOCFLAG_CRTSCTS": "syscall",
+ "syscall.TIOCFLAG_MDMBUF": "syscall",
+ "syscall.TIOCFLAG_PPS": "syscall",
+ "syscall.TIOCFLAG_SOFTCAR": "syscall",
+ "syscall.TIOCFLUSH": "syscall",
+ "syscall.TIOCGDEV": "syscall",
+ "syscall.TIOCGDRAINWAIT": "syscall",
+ "syscall.TIOCGETA": "syscall",
+ "syscall.TIOCGETD": "syscall",
+ "syscall.TIOCGFLAGS": "syscall",
+ "syscall.TIOCGICOUNT": "syscall",
+ "syscall.TIOCGLCKTRMIOS": "syscall",
+ "syscall.TIOCGLINED": "syscall",
+ "syscall.TIOCGPGRP": "syscall",
+ "syscall.TIOCGPTN": "syscall",
+ "syscall.TIOCGQSIZE": "syscall",
+ "syscall.TIOCGRANTPT": "syscall",
+ "syscall.TIOCGRS485": "syscall",
+ "syscall.TIOCGSERIAL": "syscall",
+ "syscall.TIOCGSID": "syscall",
+ "syscall.TIOCGSIZE": "syscall",
+ "syscall.TIOCGSOFTCAR": "syscall",
+ "syscall.TIOCGTSTAMP": "syscall",
+ "syscall.TIOCGWINSZ": "syscall",
+ "syscall.TIOCINQ": "syscall",
+ "syscall.TIOCIXOFF": "syscall",
+ "syscall.TIOCIXON": "syscall",
+ "syscall.TIOCLINUX": "syscall",
+ "syscall.TIOCMBIC": "syscall",
+ "syscall.TIOCMBIS": "syscall",
+ "syscall.TIOCMGDTRWAIT": "syscall",
+ "syscall.TIOCMGET": "syscall",
+ "syscall.TIOCMIWAIT": "syscall",
+ "syscall.TIOCMODG": "syscall",
+ "syscall.TIOCMODS": "syscall",
+ "syscall.TIOCMSDTRWAIT": "syscall",
+ "syscall.TIOCMSET": "syscall",
+ "syscall.TIOCM_CAR": "syscall",
+ "syscall.TIOCM_CD": "syscall",
+ "syscall.TIOCM_CTS": "syscall",
+ "syscall.TIOCM_DCD": "syscall",
+ "syscall.TIOCM_DSR": "syscall",
+ "syscall.TIOCM_DTR": "syscall",
+ "syscall.TIOCM_LE": "syscall",
+ "syscall.TIOCM_RI": "syscall",
+ "syscall.TIOCM_RNG": "syscall",
+ "syscall.TIOCM_RTS": "syscall",
+ "syscall.TIOCM_SR": "syscall",
+ "syscall.TIOCM_ST": "syscall",
+ "syscall.TIOCNOTTY": "syscall",
+ "syscall.TIOCNXCL": "syscall",
+ "syscall.TIOCOUTQ": "syscall",
+ "syscall.TIOCPKT": "syscall",
+ "syscall.TIOCPKT_DATA": "syscall",
+ "syscall.TIOCPKT_DOSTOP": "syscall",
+ "syscall.TIOCPKT_FLUSHREAD": "syscall",
+ "syscall.TIOCPKT_FLUSHWRITE": "syscall",
+ "syscall.TIOCPKT_IOCTL": "syscall",
+ "syscall.TIOCPKT_NOSTOP": "syscall",
+ "syscall.TIOCPKT_START": "syscall",
+ "syscall.TIOCPKT_STOP": "syscall",
+ "syscall.TIOCPTMASTER": "syscall",
+ "syscall.TIOCPTMGET": "syscall",
+ "syscall.TIOCPTSNAME": "syscall",
+ "syscall.TIOCPTYGNAME": "syscall",
+ "syscall.TIOCPTYGRANT": "syscall",
+ "syscall.TIOCPTYUNLK": "syscall",
+ "syscall.TIOCRCVFRAME": "syscall",
+ "syscall.TIOCREMOTE": "syscall",
+ "syscall.TIOCSBRK": "syscall",
+ "syscall.TIOCSCONS": "syscall",
+ "syscall.TIOCSCTTY": "syscall",
+ "syscall.TIOCSDRAINWAIT": "syscall",
+ "syscall.TIOCSDTR": "syscall",
+ "syscall.TIOCSERCONFIG": "syscall",
+ "syscall.TIOCSERGETLSR": "syscall",
+ "syscall.TIOCSERGETMULTI": "syscall",
+ "syscall.TIOCSERGSTRUCT": "syscall",
+ "syscall.TIOCSERGWILD": "syscall",
+ "syscall.TIOCSERSETMULTI": "syscall",
+ "syscall.TIOCSERSWILD": "syscall",
+ "syscall.TIOCSER_TEMT": "syscall",
+ "syscall.TIOCSETA": "syscall",
+ "syscall.TIOCSETAF": "syscall",
+ "syscall.TIOCSETAW": "syscall",
+ "syscall.TIOCSETD": "syscall",
+ "syscall.TIOCSFLAGS": "syscall",
+ "syscall.TIOCSIG": "syscall",
+ "syscall.TIOCSLCKTRMIOS": "syscall",
+ "syscall.TIOCSLINED": "syscall",
+ "syscall.TIOCSPGRP": "syscall",
+ "syscall.TIOCSPTLCK": "syscall",
+ "syscall.TIOCSQSIZE": "syscall",
+ "syscall.TIOCSRS485": "syscall",
+ "syscall.TIOCSSERIAL": "syscall",
+ "syscall.TIOCSSIZE": "syscall",
+ "syscall.TIOCSSOFTCAR": "syscall",
+ "syscall.TIOCSTART": "syscall",
+ "syscall.TIOCSTAT": "syscall",
+ "syscall.TIOCSTI": "syscall",
+ "syscall.TIOCSTOP": "syscall",
+ "syscall.TIOCSTSTAMP": "syscall",
+ "syscall.TIOCSWINSZ": "syscall",
+ "syscall.TIOCTIMESTAMP": "syscall",
+ "syscall.TIOCUCNTL": "syscall",
+ "syscall.TIOCVHANGUP": "syscall",
+ "syscall.TIOCXMTFRAME": "syscall",
+ "syscall.TOKEN_ADJUST_DEFAULT": "syscall",
+ "syscall.TOKEN_ADJUST_GROUPS": "syscall",
+ "syscall.TOKEN_ADJUST_PRIVILEGES": "syscall",
+ "syscall.TOKEN_ALL_ACCESS": "syscall",
+ "syscall.TOKEN_ASSIGN_PRIMARY": "syscall",
+ "syscall.TOKEN_DUPLICATE": "syscall",
+ "syscall.TOKEN_EXECUTE": "syscall",
+ "syscall.TOKEN_IMPERSONATE": "syscall",
+ "syscall.TOKEN_QUERY": "syscall",
+ "syscall.TOKEN_QUERY_SOURCE": "syscall",
+ "syscall.TOKEN_READ": "syscall",
+ "syscall.TOKEN_WRITE": "syscall",
+ "syscall.TOSTOP": "syscall",
+ "syscall.TRUNCATE_EXISTING": "syscall",
+ "syscall.TUNATTACHFILTER": "syscall",
+ "syscall.TUNDETACHFILTER": "syscall",
+ "syscall.TUNGETFEATURES": "syscall",
+ "syscall.TUNGETIFF": "syscall",
+ "syscall.TUNGETSNDBUF": "syscall",
+ "syscall.TUNGETVNETHDRSZ": "syscall",
+ "syscall.TUNSETDEBUG": "syscall",
+ "syscall.TUNSETGROUP": "syscall",
+ "syscall.TUNSETIFF": "syscall",
+ "syscall.TUNSETLINK": "syscall",
+ "syscall.TUNSETNOCSUM": "syscall",
+ "syscall.TUNSETOFFLOAD": "syscall",
+ "syscall.TUNSETOWNER": "syscall",
+ "syscall.TUNSETPERSIST": "syscall",
+ "syscall.TUNSETSNDBUF": "syscall",
+ "syscall.TUNSETTXFILTER": "syscall",
+ "syscall.TUNSETVNETHDRSZ": "syscall",
+ "syscall.Tee": "syscall",
+ "syscall.TerminateProcess": "syscall",
+ "syscall.Termios": "syscall",
+ "syscall.Tgkill": "syscall",
+ "syscall.Time": "syscall",
+ "syscall.Time_t": "syscall",
+ "syscall.Times": "syscall",
+ "syscall.Timespec": "syscall",
+ "syscall.TimespecToNsec": "syscall",
+ "syscall.Timeval": "syscall",
+ "syscall.Timeval32": "syscall",
+ "syscall.TimevalToNsec": "syscall",
+ "syscall.Timex": "syscall",
+ "syscall.Timezoneinformation": "syscall",
+ "syscall.Tms": "syscall",
+ "syscall.Token": "syscall",
+ "syscall.TokenAccessInformation": "syscall",
+ "syscall.TokenAuditPolicy": "syscall",
+ "syscall.TokenDefaultDacl": "syscall",
+ "syscall.TokenElevation": "syscall",
+ "syscall.TokenElevationType": "syscall",
+ "syscall.TokenGroups": "syscall",
+ "syscall.TokenGroupsAndPrivileges": "syscall",
+ "syscall.TokenHasRestrictions": "syscall",
+ "syscall.TokenImpersonationLevel": "syscall",
+ "syscall.TokenIntegrityLevel": "syscall",
+ "syscall.TokenLinkedToken": "syscall",
+ "syscall.TokenLogonSid": "syscall",
+ "syscall.TokenMandatoryPolicy": "syscall",
+ "syscall.TokenOrigin": "syscall",
+ "syscall.TokenOwner": "syscall",
+ "syscall.TokenPrimaryGroup": "syscall",
+ "syscall.TokenPrivileges": "syscall",
+ "syscall.TokenRestrictedSids": "syscall",
+ "syscall.TokenSandBoxInert": "syscall",
+ "syscall.TokenSessionId": "syscall",
+ "syscall.TokenSessionReference": "syscall",
+ "syscall.TokenSource": "syscall",
+ "syscall.TokenStatistics": "syscall",
+ "syscall.TokenType": "syscall",
+ "syscall.TokenUIAccess": "syscall",
+ "syscall.TokenUser": "syscall",
+ "syscall.TokenVirtualizationAllowed": "syscall",
+ "syscall.TokenVirtualizationEnabled": "syscall",
+ "syscall.Tokenprimarygroup": "syscall",
+ "syscall.Tokenuser": "syscall",
+ "syscall.TranslateAccountName": "syscall",
+ "syscall.TranslateName": "syscall",
+ "syscall.TransmitFile": "syscall",
+ "syscall.TransmitFileBuffers": "syscall",
+ "syscall.Truncate": "syscall",
+ "syscall.USAGE_MATCH_TYPE_AND": "syscall",
+ "syscall.USAGE_MATCH_TYPE_OR": "syscall",
+ "syscall.UTF16FromString": "syscall",
+ "syscall.UTF16PtrFromString": "syscall",
+ "syscall.UTF16ToString": "syscall",
+ "syscall.Ucred": "syscall",
+ "syscall.Umask": "syscall",
+ "syscall.Uname": "syscall",
+ "syscall.Undelete": "syscall",
+ "syscall.UnixCredentials": "syscall",
+ "syscall.UnixRights": "syscall",
+ "syscall.Unlink": "syscall",
+ "syscall.Unlinkat": "syscall",
+ "syscall.UnmapViewOfFile": "syscall",
+ "syscall.Unmount": "syscall",
+ "syscall.Unshare": "syscall",
+ "syscall.UserInfo10": "syscall",
+ "syscall.Ustat": "syscall",
+ "syscall.Ustat_t": "syscall",
+ "syscall.Utimbuf": "syscall",
+ "syscall.Utime": "syscall",
+ "syscall.Utimes": "syscall",
+ "syscall.UtimesNano": "syscall",
+ "syscall.Utsname": "syscall",
+ "syscall.VDISCARD": "syscall",
+ "syscall.VDSUSP": "syscall",
+ "syscall.VEOF": "syscall",
+ "syscall.VEOL": "syscall",
+ "syscall.VEOL2": "syscall",
+ "syscall.VERASE": "syscall",
+ "syscall.VERASE2": "syscall",
+ "syscall.VINTR": "syscall",
+ "syscall.VKILL": "syscall",
+ "syscall.VLNEXT": "syscall",
+ "syscall.VMIN": "syscall",
+ "syscall.VQUIT": "syscall",
+ "syscall.VREPRINT": "syscall",
+ "syscall.VSTART": "syscall",
+ "syscall.VSTATUS": "syscall",
+ "syscall.VSTOP": "syscall",
+ "syscall.VSUSP": "syscall",
+ "syscall.VSWTC": "syscall",
+ "syscall.VT0": "syscall",
+ "syscall.VT1": "syscall",
+ "syscall.VTDLY": "syscall",
+ "syscall.VTIME": "syscall",
+ "syscall.VWERASE": "syscall",
+ "syscall.VirtualLock": "syscall",
+ "syscall.VirtualUnlock": "syscall",
+ "syscall.WAIT_ABANDONED": "syscall",
+ "syscall.WAIT_FAILED": "syscall",
+ "syscall.WAIT_OBJECT_0": "syscall",
+ "syscall.WAIT_TIMEOUT": "syscall",
+ "syscall.WALL": "syscall",
+ "syscall.WALLSIG": "syscall",
+ "syscall.WALTSIG": "syscall",
+ "syscall.WCLONE": "syscall",
+ "syscall.WCONTINUED": "syscall",
+ "syscall.WCOREFLAG": "syscall",
+ "syscall.WEXITED": "syscall",
+ "syscall.WLINUXCLONE": "syscall",
+ "syscall.WNOHANG": "syscall",
+ "syscall.WNOTHREAD": "syscall",
+ "syscall.WNOWAIT": "syscall",
+ "syscall.WNOZOMBIE": "syscall",
+ "syscall.WOPTSCHECKED": "syscall",
+ "syscall.WORDSIZE": "syscall",
+ "syscall.WSABuf": "syscall",
+ "syscall.WSACleanup": "syscall",
+ "syscall.WSADESCRIPTION_LEN": "syscall",
+ "syscall.WSAData": "syscall",
+ "syscall.WSAEACCES": "syscall",
+ "syscall.WSAEnumProtocols": "syscall",
+ "syscall.WSAID_CONNECTEX": "syscall",
+ "syscall.WSAIoctl": "syscall",
+ "syscall.WSAPROTOCOL_LEN": "syscall",
+ "syscall.WSAProtocolChain": "syscall",
+ "syscall.WSAProtocolInfo": "syscall",
+ "syscall.WSARecv": "syscall",
+ "syscall.WSARecvFrom": "syscall",
+ "syscall.WSASYS_STATUS_LEN": "syscall",
+ "syscall.WSASend": "syscall",
+ "syscall.WSASendTo": "syscall",
+ "syscall.WSASendto": "syscall",
+ "syscall.WSAStartup": "syscall",
+ "syscall.WSTOPPED": "syscall",
+ "syscall.WTRAPPED": "syscall",
+ "syscall.WUNTRACED": "syscall",
+ "syscall.Wait4": "syscall",
+ "syscall.WaitForSingleObject": "syscall",
+ "syscall.WaitStatus": "syscall",
+ "syscall.Win32FileAttributeData": "syscall",
+ "syscall.Win32finddata": "syscall",
+ "syscall.Write": "syscall",
+ "syscall.WriteConsole": "syscall",
+ "syscall.WriteFile": "syscall",
+ "syscall.X509_ASN_ENCODING": "syscall",
+ "syscall.XCASE": "syscall",
+ "syscall.XP1_CONNECTIONLESS": "syscall",
+ "syscall.XP1_CONNECT_DATA": "syscall",
+ "syscall.XP1_DISCONNECT_DATA": "syscall",
+ "syscall.XP1_EXPEDITED_DATA": "syscall",
+ "syscall.XP1_GRACEFUL_CLOSE": "syscall",
+ "syscall.XP1_GUARANTEED_DELIVERY": "syscall",
+ "syscall.XP1_GUARANTEED_ORDER": "syscall",
+ "syscall.XP1_IFS_HANDLES": "syscall",
+ "syscall.XP1_MESSAGE_ORIENTED": "syscall",
+ "syscall.XP1_MULTIPOINT_CONTROL_PLANE": "syscall",
+ "syscall.XP1_MULTIPOINT_DATA_PLANE": "syscall",
+ "syscall.XP1_PARTIAL_MESSAGE": "syscall",
+ "syscall.XP1_PSEUDO_STREAM": "syscall",
+ "syscall.XP1_QOS_SUPPORTED": "syscall",
+ "syscall.XP1_SAN_SUPPORT_SDP": "syscall",
+ "syscall.XP1_SUPPORT_BROADCAST": "syscall",
+ "syscall.XP1_SUPPORT_MULTIPOINT": "syscall",
+ "syscall.XP1_UNI_RECV": "syscall",
+ "syscall.XP1_UNI_SEND": "syscall",
+ "syslog.Dial": "log/syslog",
+ "syslog.LOG_ALERT": "log/syslog",
+ "syslog.LOG_AUTH": "log/syslog",
+ "syslog.LOG_AUTHPRIV": "log/syslog",
+ "syslog.LOG_CRIT": "log/syslog",
+ "syslog.LOG_CRON": "log/syslog",
+ "syslog.LOG_DAEMON": "log/syslog",
+ "syslog.LOG_DEBUG": "log/syslog",
+ "syslog.LOG_EMERG": "log/syslog",
+ "syslog.LOG_ERR": "log/syslog",
+ "syslog.LOG_FTP": "log/syslog",
+ "syslog.LOG_INFO": "log/syslog",
+ "syslog.LOG_KERN": "log/syslog",
+ "syslog.LOG_LOCAL0": "log/syslog",
+ "syslog.LOG_LOCAL1": "log/syslog",
+ "syslog.LOG_LOCAL2": "log/syslog",
+ "syslog.LOG_LOCAL3": "log/syslog",
+ "syslog.LOG_LOCAL4": "log/syslog",
+ "syslog.LOG_LOCAL5": "log/syslog",
+ "syslog.LOG_LOCAL6": "log/syslog",
+ "syslog.LOG_LOCAL7": "log/syslog",
+ "syslog.LOG_LPR": "log/syslog",
+ "syslog.LOG_MAIL": "log/syslog",
+ "syslog.LOG_NEWS": "log/syslog",
+ "syslog.LOG_NOTICE": "log/syslog",
+ "syslog.LOG_SYSLOG": "log/syslog",
+ "syslog.LOG_USER": "log/syslog",
+ "syslog.LOG_UUCP": "log/syslog",
+ "syslog.LOG_WARNING": "log/syslog",
+ "syslog.New": "log/syslog",
+ "syslog.NewLogger": "log/syslog",
+ "syslog.Priority": "log/syslog",
+ "syslog.Writer": "log/syslog",
+ "tabwriter.AlignRight": "text/tabwriter",
+ "tabwriter.Debug": "text/tabwriter",
+ "tabwriter.DiscardEmptyColumns": "text/tabwriter",
+ "tabwriter.Escape": "text/tabwriter",
+ "tabwriter.FilterHTML": "text/tabwriter",
+ "tabwriter.NewWriter": "text/tabwriter",
+ "tabwriter.StripEscape": "text/tabwriter",
+ "tabwriter.TabIndent": "text/tabwriter",
+ "tabwriter.Writer": "text/tabwriter",
+ "tar.ErrFieldTooLong": "archive/tar",
+ "tar.ErrHeader": "archive/tar",
+ "tar.ErrWriteAfterClose": "archive/tar",
+ "tar.ErrWriteTooLong": "archive/tar",
+ "tar.FileInfoHeader": "archive/tar",
+ "tar.Header": "archive/tar",
+ "tar.NewReader": "archive/tar",
+ "tar.NewWriter": "archive/tar",
+ "tar.Reader": "archive/tar",
+ "tar.TypeBlock": "archive/tar",
+ "tar.TypeChar": "archive/tar",
+ "tar.TypeCont": "archive/tar",
+ "tar.TypeDir": "archive/tar",
+ "tar.TypeFifo": "archive/tar",
+ "tar.TypeGNULongLink": "archive/tar",
+ "tar.TypeGNULongName": "archive/tar",
+ "tar.TypeLink": "archive/tar",
+ "tar.TypeReg": "archive/tar",
+ "tar.TypeRegA": "archive/tar",
+ "tar.TypeSymlink": "archive/tar",
+ "tar.TypeXGlobalHeader": "archive/tar",
+ "tar.TypeXHeader": "archive/tar",
+ "tar.Writer": "archive/tar",
+ "template.CSS": "html/template",
+ "template.ErrAmbigContext": "html/template",
+ "template.ErrBadHTML": "html/template",
+ "template.ErrBranchEnd": "html/template",
+ "template.ErrEndContext": "html/template",
+ "template.ErrNoSuchTemplate": "html/template",
+ "template.ErrOutputContext": "html/template",
+ "template.ErrPartialCharset": "html/template",
+ "template.ErrPartialEscape": "html/template",
+ "template.ErrRangeLoopReentry": "html/template",
+ "template.ErrSlashAmbig": "html/template",
+ "template.Error": "html/template",
+ "template.ErrorCode": "html/template",
+ // "template.FuncMap" is ambiguous
+ "template.HTML": "html/template",
+ "template.HTMLAttr": "html/template",
+ // "template.HTMLEscape" is ambiguous
+ // "template.HTMLEscapeString" is ambiguous
+ // "template.HTMLEscaper" is ambiguous
+ "template.JS": "html/template",
+ // "template.JSEscape" is ambiguous
+ // "template.JSEscapeString" is ambiguous
+ // "template.JSEscaper" is ambiguous
+ "template.JSStr": "html/template",
+ // "template.Must" is ambiguous
+ // "template.New" is ambiguous
+ "template.OK": "html/template",
+ // "template.ParseFiles" is ambiguous
+ // "template.ParseGlob" is ambiguous
+ // "template.Template" is ambiguous
+ "template.URL": "html/template",
+ // "template.URLQueryEscaper" is ambiguous
+ "testing.AllocsPerRun": "testing",
+ "testing.B": "testing",
+ "testing.Benchmark": "testing",
+ "testing.BenchmarkResult": "testing",
+ "testing.Cover": "testing",
+ "testing.CoverBlock": "testing",
+ "testing.InternalBenchmark": "testing",
+ "testing.InternalExample": "testing",
+ "testing.InternalTest": "testing",
+ "testing.Main": "testing",
+ "testing.RegisterCover": "testing",
+ "testing.RunBenchmarks": "testing",
+ "testing.RunExamples": "testing",
+ "testing.RunTests": "testing",
+ "testing.Short": "testing",
+ "testing.T": "testing",
+ "testing.Verbose": "testing",
+ "textproto.CanonicalMIMEHeaderKey": "net/textproto",
+ "textproto.Conn": "net/textproto",
+ "textproto.Dial": "net/textproto",
+ "textproto.Error": "net/textproto",
+ "textproto.MIMEHeader": "net/textproto",
+ "textproto.NewConn": "net/textproto",
+ "textproto.NewReader": "net/textproto",
+ "textproto.NewWriter": "net/textproto",
+ "textproto.Pipeline": "net/textproto",
+ "textproto.ProtocolError": "net/textproto",
+ "textproto.Reader": "net/textproto",
+ "textproto.TrimBytes": "net/textproto",
+ "textproto.TrimString": "net/textproto",
+ "textproto.Writer": "net/textproto",
+ "time.ANSIC": "time",
+ "time.After": "time",
+ "time.AfterFunc": "time",
+ "time.April": "time",
+ "time.August": "time",
+ "time.Date": "time",
+ "time.December": "time",
+ "time.Duration": "time",
+ "time.February": "time",
+ "time.FixedZone": "time",
+ "time.Friday": "time",
+ "time.Hour": "time",
+ "time.January": "time",
+ "time.July": "time",
+ "time.June": "time",
+ "time.Kitchen": "time",
+ "time.LoadLocation": "time",
+ "time.Local": "time",
+ "time.Location": "time",
+ "time.March": "time",
+ "time.May": "time",
+ "time.Microsecond": "time",
+ "time.Millisecond": "time",
+ "time.Minute": "time",
+ "time.Monday": "time",
+ "time.Month": "time",
+ "time.Nanosecond": "time",
+ "time.NewTicker": "time",
+ "time.NewTimer": "time",
+ "time.November": "time",
+ "time.Now": "time",
+ "time.October": "time",
+ "time.Parse": "time",
+ "time.ParseDuration": "time",
+ "time.ParseError": "time",
+ "time.ParseInLocation": "time",
+ "time.RFC1123": "time",
+ "time.RFC1123Z": "time",
+ "time.RFC3339": "time",
+ "time.RFC3339Nano": "time",
+ "time.RFC822": "time",
+ "time.RFC822Z": "time",
+ "time.RFC850": "time",
+ "time.RubyDate": "time",
+ "time.Saturday": "time",
+ "time.Second": "time",
+ "time.September": "time",
+ "time.Since": "time",
+ "time.Sleep": "time",
+ "time.Stamp": "time",
+ "time.StampMicro": "time",
+ "time.StampMilli": "time",
+ "time.StampNano": "time",
+ "time.Sunday": "time",
+ "time.Thursday": "time",
+ "time.Tick": "time",
+ "time.Ticker": "time",
+ "time.Time": "time",
+ "time.Timer": "time",
+ "time.Tuesday": "time",
+ "time.UTC": "time",
+ "time.Unix": "time",
+ "time.UnixDate": "time",
+ "time.Wednesday": "time",
+ "time.Weekday": "time",
+ "tls.Certificate": "crypto/tls",
+ "tls.Client": "crypto/tls",
+ "tls.ClientAuthType": "crypto/tls",
+ "tls.Config": "crypto/tls",
+ "tls.Conn": "crypto/tls",
+ "tls.ConnectionState": "crypto/tls",
+ "tls.Dial": "crypto/tls",
+ "tls.Listen": "crypto/tls",
+ "tls.LoadX509KeyPair": "crypto/tls",
+ "tls.NewListener": "crypto/tls",
+ "tls.NoClientCert": "crypto/tls",
+ "tls.RequestClientCert": "crypto/tls",
+ "tls.RequireAndVerifyClientCert": "crypto/tls",
+ "tls.RequireAnyClientCert": "crypto/tls",
+ "tls.Server": "crypto/tls",
+ "tls.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA": "crypto/tls",
+ "tls.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256": "crypto/tls",
+ "tls.TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA": "crypto/tls",
+ "tls.TLS_ECDHE_ECDSA_WITH_RC4_128_SHA": "crypto/tls",
+ "tls.TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA": "crypto/tls",
+ "tls.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA": "crypto/tls",
+ "tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256": "crypto/tls",
+ "tls.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA": "crypto/tls",
+ "tls.TLS_ECDHE_RSA_WITH_RC4_128_SHA": "crypto/tls",
+ "tls.TLS_RSA_WITH_3DES_EDE_CBC_SHA": "crypto/tls",
+ "tls.TLS_RSA_WITH_AES_128_CBC_SHA": "crypto/tls",
+ "tls.TLS_RSA_WITH_AES_256_CBC_SHA": "crypto/tls",
+ "tls.TLS_RSA_WITH_RC4_128_SHA": "crypto/tls",
+ "tls.VerifyClientCertIfGiven": "crypto/tls",
+ "tls.VersionSSL30": "crypto/tls",
+ "tls.VersionTLS10": "crypto/tls",
+ "tls.VersionTLS11": "crypto/tls",
+ "tls.VersionTLS12": "crypto/tls",
+ "tls.X509KeyPair": "crypto/tls",
+ "token.ADD": "go/token",
+ "token.ADD_ASSIGN": "go/token",
+ "token.AND": "go/token",
+ "token.AND_ASSIGN": "go/token",
+ "token.AND_NOT": "go/token",
+ "token.AND_NOT_ASSIGN": "go/token",
+ "token.ARROW": "go/token",
+ "token.ASSIGN": "go/token",
+ "token.BREAK": "go/token",
+ "token.CASE": "go/token",
+ "token.CHAN": "go/token",
+ "token.CHAR": "go/token",
+ "token.COLON": "go/token",
+ "token.COMMA": "go/token",
+ "token.COMMENT": "go/token",
+ "token.CONST": "go/token",
+ "token.CONTINUE": "go/token",
+ "token.DEC": "go/token",
+ "token.DEFAULT": "go/token",
+ "token.DEFER": "go/token",
+ "token.DEFINE": "go/token",
+ "token.ELLIPSIS": "go/token",
+ "token.ELSE": "go/token",
+ "token.EOF": "go/token",
+ "token.EQL": "go/token",
+ "token.FALLTHROUGH": "go/token",
+ "token.FLOAT": "go/token",
+ "token.FOR": "go/token",
+ "token.FUNC": "go/token",
+ "token.File": "go/token",
+ "token.FileSet": "go/token",
+ "token.GEQ": "go/token",
+ "token.GO": "go/token",
+ "token.GOTO": "go/token",
+ "token.GTR": "go/token",
+ "token.HighestPrec": "go/token",
+ "token.IDENT": "go/token",
+ "token.IF": "go/token",
+ "token.ILLEGAL": "go/token",
+ "token.IMAG": "go/token",
+ "token.IMPORT": "go/token",
+ "token.INC": "go/token",
+ "token.INT": "go/token",
+ "token.INTERFACE": "go/token",
+ "token.LAND": "go/token",
+ "token.LBRACE": "go/token",
+ "token.LBRACK": "go/token",
+ "token.LEQ": "go/token",
+ "token.LOR": "go/token",
+ "token.LPAREN": "go/token",
+ "token.LSS": "go/token",
+ "token.Lookup": "go/token",
+ "token.LowestPrec": "go/token",
+ "token.MAP": "go/token",
+ "token.MUL": "go/token",
+ "token.MUL_ASSIGN": "go/token",
+ "token.NEQ": "go/token",
+ "token.NOT": "go/token",
+ "token.NewFileSet": "go/token",
+ "token.NoPos": "go/token",
+ "token.OR": "go/token",
+ "token.OR_ASSIGN": "go/token",
+ "token.PACKAGE": "go/token",
+ "token.PERIOD": "go/token",
+ "token.Pos": "go/token",
+ "token.Position": "go/token",
+ "token.QUO": "go/token",
+ "token.QUO_ASSIGN": "go/token",
+ "token.RANGE": "go/token",
+ "token.RBRACE": "go/token",
+ "token.RBRACK": "go/token",
+ "token.REM": "go/token",
+ "token.REM_ASSIGN": "go/token",
+ "token.RETURN": "go/token",
+ "token.RPAREN": "go/token",
+ "token.SELECT": "go/token",
+ "token.SEMICOLON": "go/token",
+ "token.SHL": "go/token",
+ "token.SHL_ASSIGN": "go/token",
+ "token.SHR": "go/token",
+ "token.SHR_ASSIGN": "go/token",
+ "token.STRING": "go/token",
+ "token.STRUCT": "go/token",
+ "token.SUB": "go/token",
+ "token.SUB_ASSIGN": "go/token",
+ "token.SWITCH": "go/token",
+ "token.TYPE": "go/token",
+ "token.Token": "go/token",
+ "token.UnaryPrec": "go/token",
+ "token.VAR": "go/token",
+ "token.XOR": "go/token",
+ "token.XOR_ASSIGN": "go/token",
+ "unicode.ASCII_Hex_Digit": "unicode",
+ "unicode.Arabic": "unicode",
+ "unicode.Armenian": "unicode",
+ "unicode.Avestan": "unicode",
+ "unicode.AzeriCase": "unicode",
+ "unicode.Balinese": "unicode",
+ "unicode.Bamum": "unicode",
+ "unicode.Batak": "unicode",
+ "unicode.Bengali": "unicode",
+ "unicode.Bidi_Control": "unicode",
+ "unicode.Bopomofo": "unicode",
+ "unicode.Brahmi": "unicode",
+ "unicode.Braille": "unicode",
+ "unicode.Buginese": "unicode",
+ "unicode.Buhid": "unicode",
+ "unicode.C": "unicode",
+ "unicode.Canadian_Aboriginal": "unicode",
+ "unicode.Carian": "unicode",
+ "unicode.CaseRange": "unicode",
+ "unicode.CaseRanges": "unicode",
+ "unicode.Categories": "unicode",
+ "unicode.Cc": "unicode",
+ "unicode.Cf": "unicode",
+ "unicode.Chakma": "unicode",
+ "unicode.Cham": "unicode",
+ "unicode.Cherokee": "unicode",
+ "unicode.Co": "unicode",
+ "unicode.Common": "unicode",
+ "unicode.Coptic": "unicode",
+ "unicode.Cs": "unicode",
+ "unicode.Cuneiform": "unicode",
+ "unicode.Cypriot": "unicode",
+ "unicode.Cyrillic": "unicode",
+ "unicode.Dash": "unicode",
+ "unicode.Deprecated": "unicode",
+ "unicode.Deseret": "unicode",
+ "unicode.Devanagari": "unicode",
+ "unicode.Diacritic": "unicode",
+ "unicode.Digit": "unicode",
+ "unicode.Egyptian_Hieroglyphs": "unicode",
+ "unicode.Ethiopic": "unicode",
+ "unicode.Extender": "unicode",
+ "unicode.FoldCategory": "unicode",
+ "unicode.FoldScript": "unicode",
+ "unicode.Georgian": "unicode",
+ "unicode.Glagolitic": "unicode",
+ "unicode.Gothic": "unicode",
+ "unicode.GraphicRanges": "unicode",
+ "unicode.Greek": "unicode",
+ "unicode.Gujarati": "unicode",
+ "unicode.Gurmukhi": "unicode",
+ "unicode.Han": "unicode",
+ "unicode.Hangul": "unicode",
+ "unicode.Hanunoo": "unicode",
+ "unicode.Hebrew": "unicode",
+ "unicode.Hex_Digit": "unicode",
+ "unicode.Hiragana": "unicode",
+ "unicode.Hyphen": "unicode",
+ "unicode.IDS_Binary_Operator": "unicode",
+ "unicode.IDS_Trinary_Operator": "unicode",
+ "unicode.Ideographic": "unicode",
+ "unicode.Imperial_Aramaic": "unicode",
+ "unicode.In": "unicode",
+ "unicode.Inherited": "unicode",
+ "unicode.Inscriptional_Pahlavi": "unicode",
+ "unicode.Inscriptional_Parthian": "unicode",
+ "unicode.Is": "unicode",
+ "unicode.IsControl": "unicode",
+ "unicode.IsDigit": "unicode",
+ "unicode.IsGraphic": "unicode",
+ "unicode.IsLetter": "unicode",
+ "unicode.IsLower": "unicode",
+ "unicode.IsMark": "unicode",
+ "unicode.IsNumber": "unicode",
+ "unicode.IsOneOf": "unicode",
+ "unicode.IsPrint": "unicode",
+ "unicode.IsPunct": "unicode",
+ "unicode.IsSpace": "unicode",
+ "unicode.IsSymbol": "unicode",
+ "unicode.IsTitle": "unicode",
+ "unicode.IsUpper": "unicode",
+ "unicode.Javanese": "unicode",
+ "unicode.Join_Control": "unicode",
+ "unicode.Kaithi": "unicode",
+ "unicode.Kannada": "unicode",
+ "unicode.Katakana": "unicode",
+ "unicode.Kayah_Li": "unicode",
+ "unicode.Kharoshthi": "unicode",
+ "unicode.Khmer": "unicode",
+ "unicode.L": "unicode",
+ "unicode.Lao": "unicode",
+ "unicode.Latin": "unicode",
+ "unicode.Lepcha": "unicode",
+ "unicode.Letter": "unicode",
+ "unicode.Limbu": "unicode",
+ "unicode.Linear_B": "unicode",
+ "unicode.Lisu": "unicode",
+ "unicode.Ll": "unicode",
+ "unicode.Lm": "unicode",
+ "unicode.Lo": "unicode",
+ "unicode.Logical_Order_Exception": "unicode",
+ "unicode.Lower": "unicode",
+ "unicode.LowerCase": "unicode",
+ "unicode.Lt": "unicode",
+ "unicode.Lu": "unicode",
+ "unicode.Lycian": "unicode",
+ "unicode.Lydian": "unicode",
+ "unicode.M": "unicode",
+ "unicode.Malayalam": "unicode",
+ "unicode.Mandaic": "unicode",
+ "unicode.Mark": "unicode",
+ "unicode.MaxASCII": "unicode",
+ "unicode.MaxCase": "unicode",
+ "unicode.MaxLatin1": "unicode",
+ "unicode.MaxRune": "unicode",
+ "unicode.Mc": "unicode",
+ "unicode.Me": "unicode",
+ "unicode.Meetei_Mayek": "unicode",
+ "unicode.Meroitic_Cursive": "unicode",
+ "unicode.Meroitic_Hieroglyphs": "unicode",
+ "unicode.Miao": "unicode",
+ "unicode.Mn": "unicode",
+ "unicode.Mongolian": "unicode",
+ "unicode.Myanmar": "unicode",
+ "unicode.N": "unicode",
+ "unicode.Nd": "unicode",
+ "unicode.New_Tai_Lue": "unicode",
+ "unicode.Nko": "unicode",
+ "unicode.Nl": "unicode",
+ "unicode.No": "unicode",
+ "unicode.Noncharacter_Code_Point": "unicode",
+ "unicode.Number": "unicode",
+ "unicode.Ogham": "unicode",
+ "unicode.Ol_Chiki": "unicode",
+ "unicode.Old_Italic": "unicode",
+ "unicode.Old_Persian": "unicode",
+ "unicode.Old_South_Arabian": "unicode",
+ "unicode.Old_Turkic": "unicode",
+ "unicode.Oriya": "unicode",
+ "unicode.Osmanya": "unicode",
+ "unicode.Other": "unicode",
+ "unicode.Other_Alphabetic": "unicode",
+ "unicode.Other_Default_Ignorable_Code_Point": "unicode",
+ "unicode.Other_Grapheme_Extend": "unicode",
+ "unicode.Other_ID_Continue": "unicode",
+ "unicode.Other_ID_Start": "unicode",
+ "unicode.Other_Lowercase": "unicode",
+ "unicode.Other_Math": "unicode",
+ "unicode.Other_Uppercase": "unicode",
+ "unicode.P": "unicode",
+ "unicode.Pattern_Syntax": "unicode",
+ "unicode.Pattern_White_Space": "unicode",
+ "unicode.Pc": "unicode",
+ "unicode.Pd": "unicode",
+ "unicode.Pe": "unicode",
+ "unicode.Pf": "unicode",
+ "unicode.Phags_Pa": "unicode",
+ "unicode.Phoenician": "unicode",
+ "unicode.Pi": "unicode",
+ "unicode.Po": "unicode",
+ "unicode.PrintRanges": "unicode",
+ "unicode.Properties": "unicode",
+ "unicode.Ps": "unicode",
+ "unicode.Punct": "unicode",
+ "unicode.Quotation_Mark": "unicode",
+ "unicode.Radical": "unicode",
+ "unicode.Range16": "unicode",
+ "unicode.Range32": "unicode",
+ "unicode.RangeTable": "unicode",
+ "unicode.Rejang": "unicode",
+ "unicode.ReplacementChar": "unicode",
+ "unicode.Runic": "unicode",
+ "unicode.S": "unicode",
+ "unicode.STerm": "unicode",
+ "unicode.Samaritan": "unicode",
+ "unicode.Saurashtra": "unicode",
+ "unicode.Sc": "unicode",
+ "unicode.Scripts": "unicode",
+ "unicode.Sharada": "unicode",
+ "unicode.Shavian": "unicode",
+ "unicode.SimpleFold": "unicode",
+ "unicode.Sinhala": "unicode",
+ "unicode.Sk": "unicode",
+ "unicode.Sm": "unicode",
+ "unicode.So": "unicode",
+ "unicode.Soft_Dotted": "unicode",
+ "unicode.Sora_Sompeng": "unicode",
+ "unicode.Space": "unicode",
+ "unicode.SpecialCase": "unicode",
+ "unicode.Sundanese": "unicode",
+ "unicode.Syloti_Nagri": "unicode",
+ "unicode.Symbol": "unicode",
+ "unicode.Syriac": "unicode",
+ "unicode.Tagalog": "unicode",
+ "unicode.Tagbanwa": "unicode",
+ "unicode.Tai_Le": "unicode",
+ "unicode.Tai_Tham": "unicode",
+ "unicode.Tai_Viet": "unicode",
+ "unicode.Takri": "unicode",
+ "unicode.Tamil": "unicode",
+ "unicode.Telugu": "unicode",
+ "unicode.Terminal_Punctuation": "unicode",
+ "unicode.Thaana": "unicode",
+ "unicode.Thai": "unicode",
+ "unicode.Tibetan": "unicode",
+ "unicode.Tifinagh": "unicode",
+ "unicode.Title": "unicode",
+ "unicode.TitleCase": "unicode",
+ "unicode.To": "unicode",
+ "unicode.ToLower": "unicode",
+ "unicode.ToTitle": "unicode",
+ "unicode.ToUpper": "unicode",
+ "unicode.TurkishCase": "unicode",
+ "unicode.Ugaritic": "unicode",
+ "unicode.Unified_Ideograph": "unicode",
+ "unicode.Upper": "unicode",
+ "unicode.UpperCase": "unicode",
+ "unicode.UpperLower": "unicode",
+ "unicode.Vai": "unicode",
+ "unicode.Variation_Selector": "unicode",
+ "unicode.Version": "unicode",
+ "unicode.White_Space": "unicode",
+ "unicode.Yi": "unicode",
+ "unicode.Z": "unicode",
+ "unicode.Zl": "unicode",
+ "unicode.Zp": "unicode",
+ "unicode.Zs": "unicode",
+ "url.Error": "net/url",
+ "url.EscapeError": "net/url",
+ "url.Parse": "net/url",
+ "url.ParseQuery": "net/url",
+ "url.ParseRequestURI": "net/url",
+ "url.QueryEscape": "net/url",
+ "url.QueryUnescape": "net/url",
+ "url.URL": "net/url",
+ "url.User": "net/url",
+ "url.UserPassword": "net/url",
+ "url.Userinfo": "net/url",
+ "url.Values": "net/url",
+ "user.Current": "os/user",
+ "user.Lookup": "os/user",
+ "user.LookupId": "os/user",
+ "user.UnknownUserError": "os/user",
+ "user.UnknownUserIdError": "os/user",
+ "user.User": "os/user",
+ "utf16.Decode": "unicode/utf16",
+ "utf16.DecodeRune": "unicode/utf16",
+ "utf16.Encode": "unicode/utf16",
+ "utf16.EncodeRune": "unicode/utf16",
+ "utf16.IsSurrogate": "unicode/utf16",
+ "utf8.DecodeLastRune": "unicode/utf8",
+ "utf8.DecodeLastRuneInString": "unicode/utf8",
+ "utf8.DecodeRune": "unicode/utf8",
+ "utf8.DecodeRuneInString": "unicode/utf8",
+ "utf8.EncodeRune": "unicode/utf8",
+ "utf8.FullRune": "unicode/utf8",
+ "utf8.FullRuneInString": "unicode/utf8",
+ "utf8.MaxRune": "unicode/utf8",
+ "utf8.RuneCount": "unicode/utf8",
+ "utf8.RuneCountInString": "unicode/utf8",
+ "utf8.RuneError": "unicode/utf8",
+ "utf8.RuneLen": "unicode/utf8",
+ "utf8.RuneSelf": "unicode/utf8",
+ "utf8.RuneStart": "unicode/utf8",
+ "utf8.UTFMax": "unicode/utf8",
+ "utf8.Valid": "unicode/utf8",
+ "utf8.ValidRune": "unicode/utf8",
+ "utf8.ValidString": "unicode/utf8",
+ "x509.CANotAuthorizedForThisName": "crypto/x509",
+ "x509.CertPool": "crypto/x509",
+ "x509.Certificate": "crypto/x509",
+ "x509.CertificateInvalidError": "crypto/x509",
+ "x509.ConstraintViolationError": "crypto/x509",
+ "x509.CreateCertificate": "crypto/x509",
+ "x509.DSA": "crypto/x509",
+ "x509.DSAWithSHA1": "crypto/x509",
+ "x509.DSAWithSHA256": "crypto/x509",
+ "x509.DecryptPEMBlock": "crypto/x509",
+ "x509.ECDSA": "crypto/x509",
+ "x509.ECDSAWithSHA1": "crypto/x509",
+ "x509.ECDSAWithSHA256": "crypto/x509",
+ "x509.ECDSAWithSHA384": "crypto/x509",
+ "x509.ECDSAWithSHA512": "crypto/x509",
+ "x509.EncryptPEMBlock": "crypto/x509",
+ "x509.ErrUnsupportedAlgorithm": "crypto/x509",
+ "x509.Expired": "crypto/x509",
+ "x509.ExtKeyUsage": "crypto/x509",
+ "x509.ExtKeyUsageAny": "crypto/x509",
+ "x509.ExtKeyUsageClientAuth": "crypto/x509",
+ "x509.ExtKeyUsageCodeSigning": "crypto/x509",
+ "x509.ExtKeyUsageEmailProtection": "crypto/x509",
+ "x509.ExtKeyUsageIPSECEndSystem": "crypto/x509",
+ "x509.ExtKeyUsageIPSECTunnel": "crypto/x509",
+ "x509.ExtKeyUsageIPSECUser": "crypto/x509",
+ "x509.ExtKeyUsageMicrosoftServerGatedCrypto": "crypto/x509",
+ "x509.ExtKeyUsageNetscapeServerGatedCrypto": "crypto/x509",
+ "x509.ExtKeyUsageOCSPSigning": "crypto/x509",
+ "x509.ExtKeyUsageServerAuth": "crypto/x509",
+ "x509.ExtKeyUsageTimeStamping": "crypto/x509",
+ "x509.HostnameError": "crypto/x509",
+ "x509.IncompatibleUsage": "crypto/x509",
+ "x509.IncorrectPasswordError": "crypto/x509",
+ "x509.InvalidReason": "crypto/x509",
+ "x509.IsEncryptedPEMBlock": "crypto/x509",
+ "x509.KeyUsage": "crypto/x509",
+ "x509.KeyUsageCRLSign": "crypto/x509",
+ "x509.KeyUsageCertSign": "crypto/x509",
+ "x509.KeyUsageContentCommitment": "crypto/x509",
+ "x509.KeyUsageDataEncipherment": "crypto/x509",
+ "x509.KeyUsageDecipherOnly": "crypto/x509",
+ "x509.KeyUsageDigitalSignature": "crypto/x509",
+ "x509.KeyUsageEncipherOnly": "crypto/x509",
+ "x509.KeyUsageKeyAgreement": "crypto/x509",
+ "x509.KeyUsageKeyEncipherment": "crypto/x509",
+ "x509.MD2WithRSA": "crypto/x509",
+ "x509.MD5WithRSA": "crypto/x509",
+ "x509.MarshalECPrivateKey": "crypto/x509",
+ "x509.MarshalPKCS1PrivateKey": "crypto/x509",
+ "x509.MarshalPKIXPublicKey": "crypto/x509",
+ "x509.NewCertPool": "crypto/x509",
+ "x509.NotAuthorizedToSign": "crypto/x509",
+ "x509.PEMCipher": "crypto/x509",
+ "x509.PEMCipher3DES": "crypto/x509",
+ "x509.PEMCipherAES128": "crypto/x509",
+ "x509.PEMCipherAES192": "crypto/x509",
+ "x509.PEMCipherAES256": "crypto/x509",
+ "x509.PEMCipherDES": "crypto/x509",
+ "x509.ParseCRL": "crypto/x509",
+ "x509.ParseCertificate": "crypto/x509",
+ "x509.ParseCertificates": "crypto/x509",
+ "x509.ParseDERCRL": "crypto/x509",
+ "x509.ParseECPrivateKey": "crypto/x509",
+ "x509.ParsePKCS1PrivateKey": "crypto/x509",
+ "x509.ParsePKCS8PrivateKey": "crypto/x509",
+ "x509.ParsePKIXPublicKey": "crypto/x509",
+ "x509.PublicKeyAlgorithm": "crypto/x509",
+ "x509.RSA": "crypto/x509",
+ "x509.SHA1WithRSA": "crypto/x509",
+ "x509.SHA256WithRSA": "crypto/x509",
+ "x509.SHA384WithRSA": "crypto/x509",
+ "x509.SHA512WithRSA": "crypto/x509",
+ "x509.SignatureAlgorithm": "crypto/x509",
+ "x509.SystemRootsError": "crypto/x509",
+ "x509.TooManyIntermediates": "crypto/x509",
+ "x509.UnhandledCriticalExtension": "crypto/x509",
+ "x509.UnknownAuthorityError": "crypto/x509",
+ "x509.UnknownPublicKeyAlgorithm": "crypto/x509",
+ "x509.UnknownSignatureAlgorithm": "crypto/x509",
+ "x509.VerifyOptions": "crypto/x509",
+ "xml.Attr": "encoding/xml",
+ "xml.CharData": "encoding/xml",
+ "xml.Comment": "encoding/xml",
+ "xml.CopyToken": "encoding/xml",
+ "xml.Decoder": "encoding/xml",
+ "xml.Directive": "encoding/xml",
+ "xml.Encoder": "encoding/xml",
+ "xml.EndElement": "encoding/xml",
+ "xml.Escape": "encoding/xml",
+ "xml.EscapeText": "encoding/xml",
+ "xml.HTMLAutoClose": "encoding/xml",
+ "xml.HTMLEntity": "encoding/xml",
+ "xml.Header": "encoding/xml",
+ "xml.Marshal": "encoding/xml",
+ "xml.MarshalIndent": "encoding/xml",
+ "xml.Marshaler": "encoding/xml",
+ "xml.MarshalerAttr": "encoding/xml",
+ "xml.Name": "encoding/xml",
+ "xml.NewDecoder": "encoding/xml",
+ "xml.NewEncoder": "encoding/xml",
+ "xml.ProcInst": "encoding/xml",
+ "xml.StartElement": "encoding/xml",
+ "xml.SyntaxError": "encoding/xml",
+ "xml.TagPathError": "encoding/xml",
+ "xml.Token": "encoding/xml",
+ "xml.Unmarshal": "encoding/xml",
+ "xml.UnmarshalError": "encoding/xml",
+ "xml.Unmarshaler": "encoding/xml",
+ "xml.UnmarshalerAttr": "encoding/xml",
+ "xml.UnsupportedTypeError": "encoding/xml",
+ "zip.Compressor": "archive/zip",
+ "zip.Decompressor": "archive/zip",
+ "zip.Deflate": "archive/zip",
+ "zip.ErrAlgorithm": "archive/zip",
+ "zip.ErrChecksum": "archive/zip",
+ "zip.ErrFormat": "archive/zip",
+ "zip.File": "archive/zip",
+ "zip.FileHeader": "archive/zip",
+ "zip.FileInfoHeader": "archive/zip",
+ "zip.NewReader": "archive/zip",
+ "zip.NewWriter": "archive/zip",
+ "zip.OpenReader": "archive/zip",
+ "zip.ReadCloser": "archive/zip",
+ "zip.Reader": "archive/zip",
+ "zip.RegisterCompressor": "archive/zip",
+ "zip.RegisterDecompressor": "archive/zip",
+ "zip.Store": "archive/zip",
+ "zip.Writer": "archive/zip",
+ "zlib.BestCompression": "compress/zlib",
+ "zlib.BestSpeed": "compress/zlib",
+ "zlib.DefaultCompression": "compress/zlib",
+ "zlib.ErrChecksum": "compress/zlib",
+ "zlib.ErrDictionary": "compress/zlib",
+ "zlib.ErrHeader": "compress/zlib",
+ "zlib.NewReader": "compress/zlib",
+ "zlib.NewReaderDict": "compress/zlib",
+ "zlib.NewWriter": "compress/zlib",
+ "zlib.NewWriterLevel": "compress/zlib",
+ "zlib.NewWriterLevelDict": "compress/zlib",
+ "zlib.NoCompression": "compress/zlib",
+ "zlib.Writer": "compress/zlib",
+}
diff --git a/vendor/golang.org/x/tools/oracle/TODO b/vendor/golang.org/x/tools/oracle/TODO
new file mode 100644
index 0000000..8fbf5e8
--- /dev/null
+++ b/vendor/golang.org/x/tools/oracle/TODO
@@ -0,0 +1,83 @@
+
+
+ORACLE TODO
+===========
+
+General
+=======
+
+Save unsaved editor buffers into an archive and provide that to the
+tools, which should act as if they were saved.
+
+Include complete pos/end information Serial output.
+ But beware that sometimes a single token (e.g. +) is more helpful
+ than the pos/end of the containing expression (e.g. x \n + \n y).
+
+Specific queries
+================
+
+callers, callees
+
+ Use a type-based (e.g. RTA) callgraph when a callers/callees query is
+ outside the analysis scope.
+
+implements
+
+ Make it require that the selection is a type, and show only the
+ implements relation as it applies to that type.
+
+definition, referrers
+
+ definition: Make it work with qualified identifiers (SelectorExpr) too.
+
+ references: Make it work on things that are implicit idents, like
+ import specs, perhaps?
+
+what
+
+ Report def/ref info if available.
+ Editors could use it to highlight all idents of the same local var.
+
+ More tests.
+
+pointsto
+
+ When invoked on a function Ident, we get an error.
+
+ When invoked on a named return parameter, we get an error.
+
+describe
+
+ When invoked on a var, we want to see the type and its methods.
+
+ Split "show type" and "describe syntax" into separate commands?
+
+peers
+
+ Permit querying from a makechan, for...range, or reflective op.
+
+ Report aliasing reflect.{Send,Recv,Close} and close() operations.
+
+New queries
+
+"updaters": show all statements that may update the selected lvalue
+ (local, global, field, etc).
+
+"creators": show all places where an object of type T is created
+ (&T{}, var t T, new(T), new(struct{array [3]T}), etc.
+ (Useful for datatypes whose zero value is not safe)
+
+
+Editor-specific
+===============
+
+Add support for "what" to .el; clean up.
+
+Emacs: use JSON to get the raw information from the oracle. Don't
+ open an editor buffer for simpler queries, just jump to the result
+ and/or display it in the modeline.
+
+Emacs: go-root-and-paths depends on the current buffer, so be sure to
+ call it from within the source file, not the *go-oracle* buffer:
+ the user may have switched workspaces and the oracle should run in
+ the new one.
diff --git a/vendor/golang.org/x/tools/oracle/callees.go b/vendor/golang.org/x/tools/oracle/callees.go
new file mode 100644
index 0000000..56e45e1
--- /dev/null
+++ b/vendor/golang.org/x/tools/oracle/callees.go
@@ -0,0 +1,253 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package oracle
+
+import (
+ "fmt"
+ "go/ast"
+ "go/token"
+ "sort"
+
+ "golang.org/x/tools/go/loader"
+ "golang.org/x/tools/go/pointer"
+ "golang.org/x/tools/go/ssa"
+ "golang.org/x/tools/go/ssa/ssautil"
+ "golang.org/x/tools/go/types"
+ "golang.org/x/tools/oracle/serial"
+)
+
+// Callees reports the possible callees of the function call site
+// identified by the specified source location.
+func callees(q *Query) error {
+ lconf := loader.Config{Build: q.Build}
+
+ if err := setPTAScope(&lconf, q.Scope); err != nil {
+ return err
+ }
+
+ // Load/parse/type-check the program.
+ lprog, err := lconf.Load()
+ if err != nil {
+ return err
+ }
+ q.Fset = lprog.Fset
+
+ qpos, err := parseQueryPos(lprog, q.Pos, true) // needs exact pos
+ if err != nil {
+ return err
+ }
+
+ // Determine the enclosing call for the specified position.
+ var e *ast.CallExpr
+ for _, n := range qpos.path {
+ if e, _ = n.(*ast.CallExpr); e != nil {
+ break
+ }
+ }
+ if e == nil {
+ return fmt.Errorf("there is no function call here")
+ }
+ // TODO(adonovan): issue an error if the call is "too far
+ // away" from the current selection, as this most likely is
+ // not what the user intended.
+
+ // Reject type conversions.
+ if qpos.info.Types[e.Fun].IsType() {
+ return fmt.Errorf("this is a type conversion, not a function call")
+ }
+
+ // Deal with obviously static calls before constructing SSA form.
+ // Some static calls may yet require SSA construction,
+ // e.g. f := func(){}; f().
+ switch funexpr := unparen(e.Fun).(type) {
+ case *ast.Ident:
+ switch obj := qpos.info.Uses[funexpr].(type) {
+ case *types.Builtin:
+ // Reject calls to built-ins.
+ return fmt.Errorf("this is a call to the built-in '%s' operator", obj.Name())
+ case *types.Func:
+ // This is a static function call
+ q.result = &calleesTypesResult{
+ site: e,
+ callee: obj,
+ }
+ return nil
+ }
+ case *ast.SelectorExpr:
+ sel := qpos.info.Selections[funexpr]
+ if sel == nil {
+ // qualified identifier.
+ // May refer to top level function variable
+ // or to top level function.
+ callee := qpos.info.Uses[funexpr.Sel]
+ if obj, ok := callee.(*types.Func); ok {
+ q.result = &calleesTypesResult{
+ site: e,
+ callee: obj,
+ }
+ return nil
+ }
+ } else if sel.Kind() == types.MethodVal {
+ recvtype := sel.Recv()
+ if !types.IsInterface(recvtype) {
+ // static method call
+ q.result = &calleesTypesResult{
+ site: e,
+ callee: sel.Obj().(*types.Func),
+ }
+ return nil
+ }
+ }
+ }
+
+ prog := ssautil.CreateProgram(lprog, ssa.GlobalDebug)
+
+ ptaConfig, err := setupPTA(prog, lprog, q.PTALog, q.Reflection)
+ if err != nil {
+ return err
+ }
+
+ pkg := prog.Package(qpos.info.Pkg)
+ if pkg == nil {
+ return fmt.Errorf("no SSA package")
+ }
+
+ // Defer SSA construction till after errors are reported.
+ prog.BuildAll()
+
+ // Ascertain calling function and call site.
+ callerFn := ssa.EnclosingFunction(pkg, qpos.path)
+ if callerFn == nil {
+ return fmt.Errorf("no SSA function built for this location (dead code?)")
+ }
+
+ // Find the call site.
+ site, err := findCallSite(callerFn, e)
+ if err != nil {
+ return err
+ }
+
+ funcs, err := findCallees(ptaConfig, site)
+ if err != nil {
+ return err
+ }
+
+ q.result = &calleesSSAResult{
+ site: site,
+ funcs: funcs,
+ }
+ return nil
+}
+
+func findCallSite(fn *ssa.Function, call *ast.CallExpr) (ssa.CallInstruction, error) {
+ instr, _ := fn.ValueForExpr(call)
+ callInstr, _ := instr.(ssa.CallInstruction)
+ if instr == nil {
+ return nil, fmt.Errorf("this call site is unreachable in this analysis")
+ }
+ return callInstr, nil
+}
+
+func findCallees(conf *pointer.Config, site ssa.CallInstruction) ([]*ssa.Function, error) {
+ // Avoid running the pointer analysis for static calls.
+ if callee := site.Common().StaticCallee(); callee != nil {
+ switch callee.String() {
+ case "runtime.SetFinalizer", "(reflect.Value).Call":
+ // The PTA treats calls to these intrinsics as dynamic.
+ // TODO(adonovan): avoid reliance on PTA internals.
+
+ default:
+ return []*ssa.Function{callee}, nil // singleton
+ }
+ }
+
+ // Dynamic call: use pointer analysis.
+ conf.BuildCallGraph = true
+ cg := ptrAnalysis(conf).CallGraph
+ cg.DeleteSyntheticNodes()
+
+ // Find all call edges from the site.
+ n := cg.Nodes[site.Parent()]
+ if n == nil {
+ return nil, fmt.Errorf("this call site is unreachable in this analysis")
+ }
+ calleesMap := make(map[*ssa.Function]bool)
+ for _, edge := range n.Out {
+ if edge.Site == site {
+ calleesMap[edge.Callee.Func] = true
+ }
+ }
+
+ // De-duplicate and sort.
+ funcs := make([]*ssa.Function, 0, len(calleesMap))
+ for f := range calleesMap {
+ funcs = append(funcs, f)
+ }
+ sort.Sort(byFuncPos(funcs))
+ return funcs, nil
+}
+
+type calleesSSAResult struct {
+ site ssa.CallInstruction
+ funcs []*ssa.Function
+}
+
+type calleesTypesResult struct {
+ site *ast.CallExpr
+ callee *types.Func
+}
+
+func (r *calleesSSAResult) display(printf printfFunc) {
+ if len(r.funcs) == 0 {
+ // dynamic call on a provably nil func/interface
+ printf(r.site, "%s on nil value", r.site.Common().Description())
+ } else {
+ printf(r.site, "this %s dispatches to:", r.site.Common().Description())
+ for _, callee := range r.funcs {
+ printf(callee, "\t%s", callee)
+ }
+ }
+}
+
+func (r *calleesSSAResult) toSerial(res *serial.Result, fset *token.FileSet) {
+ j := &serial.Callees{
+ Pos: fset.Position(r.site.Pos()).String(),
+ Desc: r.site.Common().Description(),
+ }
+ for _, callee := range r.funcs {
+ j.Callees = append(j.Callees, &serial.CalleesItem{
+ Name: callee.String(),
+ Pos: fset.Position(callee.Pos()).String(),
+ })
+ }
+ res.Callees = j
+}
+
+func (r *calleesTypesResult) display(printf printfFunc) {
+ printf(r.site, "this static function call dispatches to:")
+ printf(r.callee, "\t%s", r.callee.FullName())
+}
+
+func (r *calleesTypesResult) toSerial(res *serial.Result, fset *token.FileSet) {
+ j := &serial.Callees{
+ Pos: fset.Position(r.site.Pos()).String(),
+ Desc: "static function call",
+ }
+ j.Callees = []*serial.CalleesItem{
+ &serial.CalleesItem{
+ Name: r.callee.FullName(),
+ Pos: fset.Position(r.callee.Pos()).String(),
+ },
+ }
+ res.Callees = j
+}
+
+// NB: byFuncPos is not deterministic across packages since it depends on load order.
+// Use lessPos if the tests need it.
+type byFuncPos []*ssa.Function
+
+func (a byFuncPos) Len() int { return len(a) }
+func (a byFuncPos) Less(i, j int) bool { return a[i].Pos() < a[j].Pos() }
+func (a byFuncPos) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
diff --git a/vendor/golang.org/x/tools/oracle/callers.go b/vendor/golang.org/x/tools/oracle/callers.go
new file mode 100644
index 0000000..159a403
--- /dev/null
+++ b/vendor/golang.org/x/tools/oracle/callers.go
@@ -0,0 +1,115 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package oracle
+
+import (
+ "fmt"
+ "go/token"
+
+ "golang.org/x/tools/go/callgraph"
+ "golang.org/x/tools/go/loader"
+ "golang.org/x/tools/go/ssa"
+ "golang.org/x/tools/go/ssa/ssautil"
+ "golang.org/x/tools/oracle/serial"
+)
+
+// Callers reports the possible callers of the function
+// immediately enclosing the specified source location.
+//
+func callers(q *Query) error {
+ lconf := loader.Config{Build: q.Build}
+
+ if err := setPTAScope(&lconf, q.Scope); err != nil {
+ return err
+ }
+
+ // Load/parse/type-check the program.
+ lprog, err := lconf.Load()
+ if err != nil {
+ return err
+ }
+ q.Fset = lprog.Fset
+
+ qpos, err := parseQueryPos(lprog, q.Pos, false)
+ if err != nil {
+ return err
+ }
+
+ prog := ssautil.CreateProgram(lprog, 0)
+
+ ptaConfig, err := setupPTA(prog, lprog, q.PTALog, q.Reflection)
+ if err != nil {
+ return err
+ }
+
+ pkg := prog.Package(qpos.info.Pkg)
+ if pkg == nil {
+ return fmt.Errorf("no SSA package")
+ }
+ if !ssa.HasEnclosingFunction(pkg, qpos.path) {
+ return fmt.Errorf("this position is not inside a function")
+ }
+
+ // Defer SSA construction till after errors are reported.
+ prog.BuildAll()
+
+ target := ssa.EnclosingFunction(pkg, qpos.path)
+ if target == nil {
+ return fmt.Errorf("no SSA function built for this location (dead code?)")
+ }
+
+ // TODO(adonovan): opt: if function is never address-taken, skip
+ // the pointer analysis. Just look for direct calls. This can
+ // be done in a single pass over the SSA.
+
+ // Run the pointer analysis, recording each
+ // call found to originate from target.
+ ptaConfig.BuildCallGraph = true
+ cg := ptrAnalysis(ptaConfig).CallGraph
+ cg.DeleteSyntheticNodes()
+ edges := cg.CreateNode(target).In
+ // TODO(adonovan): sort + dedup calls to ensure test determinism.
+
+ q.result = &callersResult{
+ target: target,
+ callgraph: cg,
+ edges: edges,
+ }
+ return nil
+}
+
+type callersResult struct {
+ target *ssa.Function
+ callgraph *callgraph.Graph
+ edges []*callgraph.Edge
+}
+
+func (r *callersResult) display(printf printfFunc) {
+ root := r.callgraph.Root
+ if r.edges == nil {
+ printf(r.target, "%s is not reachable in this program.", r.target)
+ } else {
+ printf(r.target, "%s is called from these %d sites:", r.target, len(r.edges))
+ for _, edge := range r.edges {
+ if edge.Caller == root {
+ printf(r.target, "the root of the call graph")
+ } else {
+ printf(edge, "\t%s from %s", edge.Description(), edge.Caller.Func)
+ }
+ }
+ }
+}
+
+func (r *callersResult) toSerial(res *serial.Result, fset *token.FileSet) {
+ var callers []serial.Caller
+ for _, edge := range r.edges {
+ callers = append(callers, serial.Caller{
+ Caller: edge.Caller.Func.String(),
+ Pos: fset.Position(edge.Pos()).String(),
+ Desc: edge.Description(),
+ })
+ }
+ res.Callers = callers
+}
diff --git a/vendor/golang.org/x/tools/oracle/callstack.go b/vendor/golang.org/x/tools/oracle/callstack.go
new file mode 100644
index 0000000..6f04b60
--- /dev/null
+++ b/vendor/golang.org/x/tools/oracle/callstack.go
@@ -0,0 +1,126 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package oracle
+
+import (
+ "fmt"
+ "go/token"
+
+ "golang.org/x/tools/go/callgraph"
+ "golang.org/x/tools/go/loader"
+ "golang.org/x/tools/go/ssa"
+ "golang.org/x/tools/go/ssa/ssautil"
+ "golang.org/x/tools/oracle/serial"
+)
+
+// Callstack displays an arbitrary path from a root of the callgraph
+// to the function at the current position.
+//
+// The information may be misleading in a context-insensitive
+// analysis. e.g. the call path X->Y->Z might be infeasible if Y never
+// calls Z when it is called from X. TODO(adonovan): think about UI.
+//
+// TODO(adonovan): permit user to specify a starting point other than
+// the analysis root.
+//
+func callstack(q *Query) error {
+ fset := token.NewFileSet()
+ lconf := loader.Config{Fset: fset, Build: q.Build}
+
+ if err := setPTAScope(&lconf, q.Scope); err != nil {
+ return err
+ }
+
+ // Load/parse/type-check the program.
+ lprog, err := lconf.Load()
+ if err != nil {
+ return err
+ }
+
+ qpos, err := parseQueryPos(lprog, q.Pos, false)
+ if err != nil {
+ return err
+ }
+
+ prog := ssautil.CreateProgram(lprog, 0)
+
+ ptaConfig, err := setupPTA(prog, lprog, q.PTALog, q.Reflection)
+ if err != nil {
+ return err
+ }
+
+ pkg := prog.Package(qpos.info.Pkg)
+ if pkg == nil {
+ return fmt.Errorf("no SSA package")
+ }
+
+ if !ssa.HasEnclosingFunction(pkg, qpos.path) {
+ return fmt.Errorf("this position is not inside a function")
+ }
+
+ // Defer SSA construction till after errors are reported.
+ prog.BuildAll()
+
+ target := ssa.EnclosingFunction(pkg, qpos.path)
+ if target == nil {
+ return fmt.Errorf("no SSA function built for this location (dead code?)")
+ }
+
+ // Run the pointer analysis and build the complete call graph.
+ ptaConfig.BuildCallGraph = true
+ cg := ptrAnalysis(ptaConfig).CallGraph
+ cg.DeleteSyntheticNodes()
+
+ // Search for an arbitrary path from a root to the target function.
+ isEnd := func(n *callgraph.Node) bool { return n.Func == target }
+ callpath := callgraph.PathSearch(cg.Root, isEnd)
+ if callpath != nil {
+ callpath = callpath[1:] // remove synthetic edge from
+ }
+
+ q.Fset = fset
+ q.result = &callstackResult{
+ qpos: qpos,
+ target: target,
+ callpath: callpath,
+ }
+ return nil
+}
+
+type callstackResult struct {
+ qpos *queryPos
+ target *ssa.Function
+ callpath []*callgraph.Edge
+}
+
+func (r *callstackResult) display(printf printfFunc) {
+ if r.callpath != nil {
+ printf(r.qpos, "Found a call path from root to %s", r.target)
+ printf(r.target, "%s", r.target)
+ for i := len(r.callpath) - 1; i >= 0; i-- {
+ edge := r.callpath[i]
+ printf(edge, "%s from %s", edge.Description(), edge.Caller.Func)
+ }
+ } else {
+ printf(r.target, "%s is unreachable in this analysis scope", r.target)
+ }
+}
+
+func (r *callstackResult) toSerial(res *serial.Result, fset *token.FileSet) {
+ var callers []serial.Caller
+ for i := len(r.callpath) - 1; i >= 0; i-- { // (innermost first)
+ edge := r.callpath[i]
+ callers = append(callers, serial.Caller{
+ Pos: fset.Position(edge.Pos()).String(),
+ Caller: edge.Caller.Func.String(),
+ Desc: edge.Description(),
+ })
+ }
+ res.Callstack = &serial.CallStack{
+ Pos: fset.Position(r.target.Pos()).String(),
+ Target: r.target.String(),
+ Callers: callers,
+ }
+}
diff --git a/vendor/golang.org/x/tools/oracle/definition.go b/vendor/golang.org/x/tools/oracle/definition.go
new file mode 100644
index 0000000..a0340c6
--- /dev/null
+++ b/vendor/golang.org/x/tools/oracle/definition.go
@@ -0,0 +1,76 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package oracle
+
+import (
+ "fmt"
+ "go/ast"
+ "go/token"
+
+ "golang.org/x/tools/go/loader"
+ "golang.org/x/tools/go/types"
+ "golang.org/x/tools/oracle/serial"
+)
+
+// definition reports the location of the definition of an identifier.
+//
+// TODO(adonovan): opt: for intra-file references, the parser's
+// resolution might be enough; we should start with that.
+//
+func definition(q *Query) error {
+ lconf := loader.Config{Build: q.Build}
+ allowErrors(&lconf)
+
+ if err := importQueryPackage(q.Pos, &lconf); err != nil {
+ return err
+ }
+
+ // Load/parse/type-check the program.
+ lprog, err := lconf.Load()
+ if err != nil {
+ return err
+ }
+ q.Fset = lprog.Fset
+
+ qpos, err := parseQueryPos(lprog, q.Pos, false)
+ if err != nil {
+ return err
+ }
+
+ id, _ := qpos.path[0].(*ast.Ident)
+ if id == nil {
+ return fmt.Errorf("no identifier here")
+ }
+
+ obj := qpos.info.ObjectOf(id)
+ if obj == nil {
+ // Happens for y in "switch y := x.(type)",
+ // and the package declaration,
+ // but I think that's all.
+ return fmt.Errorf("no object for identifier")
+ }
+
+ q.result = &definitionResult{qpos, obj}
+ return nil
+}
+
+type definitionResult struct {
+ qpos *queryPos
+ obj types.Object // object it denotes
+}
+
+func (r *definitionResult) display(printf printfFunc) {
+ printf(r.obj, "defined here as %s", r.qpos.objectString(r.obj))
+}
+
+func (r *definitionResult) toSerial(res *serial.Result, fset *token.FileSet) {
+ definition := &serial.Definition{
+ Desc: r.obj.String(),
+ }
+ if pos := r.obj.Pos(); pos != token.NoPos { // Package objects have no Pos()
+ definition.ObjPos = fset.Position(pos).String()
+ }
+ res.Definition = definition
+}
diff --git a/vendor/golang.org/x/tools/oracle/describe.go b/vendor/golang.org/x/tools/oracle/describe.go
new file mode 100644
index 0000000..ea1c5ec
--- /dev/null
+++ b/vendor/golang.org/x/tools/oracle/describe.go
@@ -0,0 +1,763 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package oracle
+
+import (
+ "bytes"
+ "fmt"
+ "go/ast"
+ "go/token"
+ "log"
+ "os"
+ "strings"
+
+ "golang.org/x/tools/go/ast/astutil"
+ "golang.org/x/tools/go/exact"
+ "golang.org/x/tools/go/loader"
+ "golang.org/x/tools/go/types"
+ "golang.org/x/tools/go/types/typeutil"
+ "golang.org/x/tools/oracle/serial"
+)
+
+// describe describes the syntax node denoted by the query position,
+// including:
+// - its syntactic category
+// - the definition of its referent (for identifiers) [now redundant]
+// - its type and method set (for an expression or type expression)
+//
+func describe(q *Query) error {
+ lconf := loader.Config{Build: q.Build}
+ allowErrors(&lconf)
+
+ if err := importQueryPackage(q.Pos, &lconf); err != nil {
+ return err
+ }
+
+ // Load/parse/type-check the program.
+ lprog, err := lconf.Load()
+ if err != nil {
+ return err
+ }
+ q.Fset = lprog.Fset
+
+ qpos, err := parseQueryPos(lprog, q.Pos, true) // (need exact pos)
+ if err != nil {
+ return err
+ }
+
+ if false { // debugging
+ fprintf(os.Stderr, lprog.Fset, qpos.path[0], "you selected: %s %s",
+ astutil.NodeDescription(qpos.path[0]), pathToString(qpos.path))
+ }
+
+ path, action := findInterestingNode(qpos.info, qpos.path)
+ switch action {
+ case actionExpr:
+ q.result, err = describeValue(qpos, path)
+
+ case actionType:
+ q.result, err = describeType(qpos, path)
+
+ case actionPackage:
+ q.result, err = describePackage(qpos, path)
+
+ case actionStmt:
+ q.result, err = describeStmt(qpos, path)
+
+ case actionUnknown:
+ q.result = &describeUnknownResult{path[0]}
+
+ default:
+ panic(action) // unreachable
+ }
+ return err
+}
+
+type describeUnknownResult struct {
+ node ast.Node
+}
+
+func (r *describeUnknownResult) display(printf printfFunc) {
+ // Nothing much to say about misc syntax.
+ printf(r.node, "%s", astutil.NodeDescription(r.node))
+}
+
+func (r *describeUnknownResult) toSerial(res *serial.Result, fset *token.FileSet) {
+ res.Describe = &serial.Describe{
+ Desc: astutil.NodeDescription(r.node),
+ Pos: fset.Position(r.node.Pos()).String(),
+ }
+}
+
+type action int
+
+const (
+ actionUnknown action = iota // None of the below
+ actionExpr // FuncDecl, true Expr or Ident(types.{Const,Var})
+ actionType // type Expr or Ident(types.TypeName).
+ actionStmt // Stmt or Ident(types.Label)
+ actionPackage // Ident(types.Package) or ImportSpec
+)
+
+// findInterestingNode classifies the syntax node denoted by path as one of:
+// - an expression, part of an expression or a reference to a constant
+// or variable;
+// - a type, part of a type, or a reference to a named type;
+// - a statement, part of a statement, or a label referring to a statement;
+// - part of a package declaration or import spec.
+// - none of the above.
+// and returns the most "interesting" associated node, which may be
+// the same node, an ancestor or a descendent.
+//
+func findInterestingNode(pkginfo *loader.PackageInfo, path []ast.Node) ([]ast.Node, action) {
+ // TODO(adonovan): integrate with go/types/stdlib_test.go and
+ // apply this to every AST node we can find to make sure it
+ // doesn't crash.
+
+ // TODO(adonovan): audit for ParenExpr safety, esp. since we
+ // traverse up and down.
+
+ // TODO(adonovan): if the users selects the "." in
+ // "fmt.Fprintf()", they'll get an ambiguous selection error;
+ // we won't even reach here. Can we do better?
+
+ // TODO(adonovan): describing a field within 'type T struct {...}'
+ // describes the (anonymous) struct type and concludes "no methods".
+ // We should ascend to the enclosing type decl, if any.
+
+ for len(path) > 0 {
+ switch n := path[0].(type) {
+ case *ast.GenDecl:
+ if len(n.Specs) == 1 {
+ // Descend to sole {Import,Type,Value}Spec child.
+ path = append([]ast.Node{n.Specs[0]}, path...)
+ continue
+ }
+ return path, actionUnknown // uninteresting
+
+ case *ast.FuncDecl:
+ // Descend to function name.
+ path = append([]ast.Node{n.Name}, path...)
+ continue
+
+ case *ast.ImportSpec:
+ return path, actionPackage
+
+ case *ast.ValueSpec:
+ if len(n.Names) == 1 {
+ // Descend to sole Ident child.
+ path = append([]ast.Node{n.Names[0]}, path...)
+ continue
+ }
+ return path, actionUnknown // uninteresting
+
+ case *ast.TypeSpec:
+ // Descend to type name.
+ path = append([]ast.Node{n.Name}, path...)
+ continue
+
+ case ast.Stmt:
+ return path, actionStmt
+
+ case *ast.ArrayType,
+ *ast.StructType,
+ *ast.FuncType,
+ *ast.InterfaceType,
+ *ast.MapType,
+ *ast.ChanType:
+ return path, actionType
+
+ case *ast.Comment, *ast.CommentGroup, *ast.File, *ast.KeyValueExpr, *ast.CommClause:
+ return path, actionUnknown // uninteresting
+
+ case *ast.Ellipsis:
+ // Continue to enclosing node.
+ // e.g. [...]T in ArrayType
+ // f(x...) in CallExpr
+ // f(x...T) in FuncType
+
+ case *ast.Field:
+ // TODO(adonovan): this needs more thought,
+ // since fields can be so many things.
+ if len(n.Names) == 1 {
+ // Descend to sole Ident child.
+ path = append([]ast.Node{n.Names[0]}, path...)
+ continue
+ }
+ // Zero names (e.g. anon field in struct)
+ // or multiple field or param names:
+ // continue to enclosing field list.
+
+ case *ast.FieldList:
+ // Continue to enclosing node:
+ // {Struct,Func,Interface}Type or FuncDecl.
+
+ case *ast.BasicLit:
+ if _, ok := path[1].(*ast.ImportSpec); ok {
+ return path[1:], actionPackage
+ }
+ return path, actionExpr
+
+ case *ast.SelectorExpr:
+ // TODO(adonovan): use Selections info directly.
+ if pkginfo.Uses[n.Sel] == nil {
+ // TODO(adonovan): is this reachable?
+ return path, actionUnknown
+ }
+ // Descend to .Sel child.
+ path = append([]ast.Node{n.Sel}, path...)
+ continue
+
+ case *ast.Ident:
+ switch pkginfo.ObjectOf(n).(type) {
+ case *types.PkgName:
+ return path, actionPackage
+
+ case *types.Const:
+ return path, actionExpr
+
+ case *types.Label:
+ return path, actionStmt
+
+ case *types.TypeName:
+ return path, actionType
+
+ case *types.Var:
+ // For x in 'struct {x T}', return struct type, for now.
+ if _, ok := path[1].(*ast.Field); ok {
+ _ = path[2].(*ast.FieldList) // assertion
+ if _, ok := path[3].(*ast.StructType); ok {
+ return path[3:], actionType
+ }
+ }
+ return path, actionExpr
+
+ case *types.Func:
+ return path, actionExpr
+
+ case *types.Builtin:
+ // For reference to built-in function, return enclosing call.
+ path = path[1:] // ascend to enclosing function call
+ continue
+
+ case *types.Nil:
+ return path, actionExpr
+ }
+
+ // No object.
+ switch path[1].(type) {
+ case *ast.SelectorExpr:
+ // Return enclosing selector expression.
+ return path[1:], actionExpr
+
+ case *ast.Field:
+ // TODO(adonovan): test this.
+ // e.g. all f in:
+ // struct { f, g int }
+ // interface { f() }
+ // func (f T) method(f, g int) (f, g bool)
+ //
+ // switch path[3].(type) {
+ // case *ast.FuncDecl:
+ // case *ast.StructType:
+ // case *ast.InterfaceType:
+ // }
+ //
+ // return path[1:], actionExpr
+ //
+ // Unclear what to do with these.
+ // Struct.Fields -- field
+ // Interface.Methods -- field
+ // FuncType.{Params.Results} -- actionExpr
+ // FuncDecl.Recv -- actionExpr
+
+ case *ast.File:
+ // 'package foo'
+ return path, actionPackage
+
+ case *ast.ImportSpec:
+ // TODO(adonovan): fix: why no package object? go/types bug?
+ return path[1:], actionPackage
+
+ default:
+ // e.g. blank identifier
+ // or y in "switch y := x.(type)"
+ // or code in a _test.go file that's not part of the package.
+ log.Printf("unknown reference %s in %T\n", n, path[1])
+ return path, actionUnknown
+ }
+
+ case *ast.StarExpr:
+ if pkginfo.Types[n].IsType() {
+ return path, actionType
+ }
+ return path, actionExpr
+
+ case ast.Expr:
+ // All Expr but {BasicLit,Ident,StarExpr} are
+ // "true" expressions that evaluate to a value.
+ return path, actionExpr
+ }
+
+ // Ascend to parent.
+ path = path[1:]
+ }
+
+ return nil, actionUnknown // unreachable
+}
+
+func describeValue(qpos *queryPos, path []ast.Node) (*describeValueResult, error) {
+ var expr ast.Expr
+ var obj types.Object
+ switch n := path[0].(type) {
+ case *ast.ValueSpec:
+ // ambiguous ValueSpec containing multiple names
+ return nil, fmt.Errorf("multiple value specification")
+ case *ast.Ident:
+ obj = qpos.info.ObjectOf(n)
+ expr = n
+ case ast.Expr:
+ expr = n
+ default:
+ // TODO(adonovan): is this reachable?
+ return nil, fmt.Errorf("unexpected AST for expr: %T", n)
+ }
+
+ typ := qpos.info.TypeOf(expr)
+ constVal := qpos.info.Types[expr].Value
+
+ return &describeValueResult{
+ qpos: qpos,
+ expr: expr,
+ typ: typ,
+ constVal: constVal,
+ obj: obj,
+ }, nil
+}
+
+type describeValueResult struct {
+ qpos *queryPos
+ expr ast.Expr // query node
+ typ types.Type // type of expression
+ constVal exact.Value // value of expression, if constant
+ obj types.Object // var/func/const object, if expr was Ident
+}
+
+func (r *describeValueResult) display(printf printfFunc) {
+ var prefix, suffix string
+ if r.constVal != nil {
+ suffix = fmt.Sprintf(" of constant value %s", r.constVal)
+ }
+ switch obj := r.obj.(type) {
+ case *types.Func:
+ if recv := obj.Type().(*types.Signature).Recv(); recv != nil {
+ if _, ok := recv.Type().Underlying().(*types.Interface); ok {
+ prefix = "interface method "
+ } else {
+ prefix = "method "
+ }
+ }
+ }
+
+ // Describe the expression.
+ if r.obj != nil {
+ if r.obj.Pos() == r.expr.Pos() {
+ // defining ident
+ printf(r.expr, "definition of %s%s%s", prefix, r.qpos.objectString(r.obj), suffix)
+ } else {
+ // referring ident
+ printf(r.expr, "reference to %s%s%s", prefix, r.qpos.objectString(r.obj), suffix)
+ if def := r.obj.Pos(); def != token.NoPos {
+ printf(def, "defined here")
+ }
+ }
+ } else {
+ desc := astutil.NodeDescription(r.expr)
+ if suffix != "" {
+ // constant expression
+ printf(r.expr, "%s%s", desc, suffix)
+ } else {
+ // non-constant expression
+ printf(r.expr, "%s of type %s", desc, r.qpos.typeString(r.typ))
+ }
+ }
+}
+
+func (r *describeValueResult) toSerial(res *serial.Result, fset *token.FileSet) {
+ var value, objpos string
+ if r.constVal != nil {
+ value = r.constVal.String()
+ }
+ if r.obj != nil {
+ objpos = fset.Position(r.obj.Pos()).String()
+ }
+
+ res.Describe = &serial.Describe{
+ Desc: astutil.NodeDescription(r.expr),
+ Pos: fset.Position(r.expr.Pos()).String(),
+ Detail: "value",
+ Value: &serial.DescribeValue{
+ Type: r.qpos.typeString(r.typ),
+ Value: value,
+ ObjPos: objpos,
+ },
+ }
+}
+
+// ---- TYPE ------------------------------------------------------------
+
+func describeType(qpos *queryPos, path []ast.Node) (*describeTypeResult, error) {
+ var description string
+ var t types.Type
+ switch n := path[0].(type) {
+ case *ast.Ident:
+ t = qpos.info.TypeOf(n)
+ switch t := t.(type) {
+ case *types.Basic:
+ description = "reference to built-in "
+
+ case *types.Named:
+ isDef := t.Obj().Pos() == n.Pos() // see caveats at isDef above
+ if isDef {
+ description = "definition of "
+ } else {
+ description = "reference to "
+ }
+ }
+
+ case ast.Expr:
+ t = qpos.info.TypeOf(n)
+
+ default:
+ // Unreachable?
+ return nil, fmt.Errorf("unexpected AST for type: %T", n)
+ }
+
+ description = description + "type " + qpos.typeString(t)
+
+ // Show sizes for structs and named types (it's fairly obvious for others).
+ switch t.(type) {
+ case *types.Named, *types.Struct:
+ szs := types.StdSizes{8, 8} // assume amd64
+ description = fmt.Sprintf("%s (size %d, align %d)", description,
+ szs.Sizeof(t), szs.Alignof(t))
+ }
+
+ return &describeTypeResult{
+ qpos: qpos,
+ node: path[0],
+ description: description,
+ typ: t,
+ methods: accessibleMethods(t, qpos.info.Pkg),
+ }, nil
+}
+
+type describeTypeResult struct {
+ qpos *queryPos
+ node ast.Node
+ description string
+ typ types.Type
+ methods []*types.Selection
+}
+
+func (r *describeTypeResult) display(printf printfFunc) {
+ printf(r.node, "%s", r.description)
+
+ // Show the underlying type for a reference to a named type.
+ if nt, ok := r.typ.(*types.Named); ok && r.node.Pos() != nt.Obj().Pos() {
+ printf(nt.Obj(), "defined as %s", r.qpos.typeString(nt.Underlying()))
+ }
+
+ // Print the method set, if the type kind is capable of bearing methods.
+ switch r.typ.(type) {
+ case *types.Interface, *types.Struct, *types.Named:
+ if len(r.methods) > 0 {
+ printf(r.node, "Method set:")
+ for _, meth := range r.methods {
+ // TODO(adonovan): print these relative
+ // to the owning package, not the
+ // query package.
+ printf(meth.Obj(), "\t%s", r.qpos.selectionString(meth))
+ }
+ } else {
+ printf(r.node, "No methods.")
+ }
+ }
+}
+
+func (r *describeTypeResult) toSerial(res *serial.Result, fset *token.FileSet) {
+ var namePos, nameDef string
+ if nt, ok := r.typ.(*types.Named); ok {
+ namePos = fset.Position(nt.Obj().Pos()).String()
+ nameDef = nt.Underlying().String()
+ }
+ res.Describe = &serial.Describe{
+ Desc: r.description,
+ Pos: fset.Position(r.node.Pos()).String(),
+ Detail: "type",
+ Type: &serial.DescribeType{
+ Type: r.qpos.typeString(r.typ),
+ NamePos: namePos,
+ NameDef: nameDef,
+ Methods: methodsToSerial(r.qpos.info.Pkg, r.methods, fset),
+ },
+ }
+}
+
+// ---- PACKAGE ------------------------------------------------------------
+
+func describePackage(qpos *queryPos, path []ast.Node) (*describePackageResult, error) {
+ var description string
+ var pkg *types.Package
+ switch n := path[0].(type) {
+ case *ast.ImportSpec:
+ var pkgname *types.PkgName
+ if n.Name != nil {
+ pkgname = qpos.info.Defs[n.Name].(*types.PkgName)
+ } else if p := qpos.info.Implicits[n]; p != nil {
+ pkgname = p.(*types.PkgName)
+ }
+ pkg = pkgname.Imported()
+ description = fmt.Sprintf("import of package %q", pkg.Path())
+
+ case *ast.Ident:
+ if _, isDef := path[1].(*ast.File); isDef {
+ // e.g. package id
+ pkg = qpos.info.Pkg
+ description = fmt.Sprintf("definition of package %q", pkg.Path())
+ } else {
+ // e.g. import id "..."
+ // or id.F()
+ pkg = qpos.info.ObjectOf(n).(*types.PkgName).Imported()
+ description = fmt.Sprintf("reference to package %q", pkg.Path())
+ }
+
+ default:
+ // Unreachable?
+ return nil, fmt.Errorf("unexpected AST for package: %T", n)
+ }
+
+ var members []*describeMember
+ // NB: "unsafe" has no types.Package
+ if pkg != nil {
+ // Enumerate the accessible package members
+ // in lexicographic order.
+ for _, name := range pkg.Scope().Names() {
+ if pkg == qpos.info.Pkg || ast.IsExported(name) {
+ mem := pkg.Scope().Lookup(name)
+ var methods []*types.Selection
+ if mem, ok := mem.(*types.TypeName); ok {
+ methods = accessibleMethods(mem.Type(), qpos.info.Pkg)
+ }
+ members = append(members, &describeMember{
+ mem,
+ methods,
+ })
+
+ }
+ }
+ }
+
+ return &describePackageResult{qpos.fset, path[0], description, pkg, members}, nil
+}
+
+type describePackageResult struct {
+ fset *token.FileSet
+ node ast.Node
+ description string
+ pkg *types.Package
+ members []*describeMember // in lexicographic name order
+}
+
+type describeMember struct {
+ obj types.Object
+ methods []*types.Selection // in types.MethodSet order
+}
+
+func (r *describePackageResult) display(printf printfFunc) {
+ printf(r.node, "%s", r.description)
+
+ // Compute max width of name "column".
+ maxname := 0
+ for _, mem := range r.members {
+ if l := len(mem.obj.Name()); l > maxname {
+ maxname = l
+ }
+ }
+
+ for _, mem := range r.members {
+ printf(mem.obj, "\t%s", formatMember(mem.obj, maxname))
+ for _, meth := range mem.methods {
+ printf(meth.Obj(), "\t\t%s", types.SelectionString(meth, types.RelativeTo(r.pkg)))
+ }
+ }
+}
+
+func formatMember(obj types.Object, maxname int) string {
+ qualifier := types.RelativeTo(obj.Pkg())
+ var buf bytes.Buffer
+ fmt.Fprintf(&buf, "%-5s %-*s", tokenOf(obj), maxname, obj.Name())
+ switch obj := obj.(type) {
+ case *types.Const:
+ fmt.Fprintf(&buf, " %s = %s", types.TypeString(obj.Type(), qualifier), obj.Val().String())
+
+ case *types.Func:
+ fmt.Fprintf(&buf, " %s", types.TypeString(obj.Type(), qualifier))
+
+ case *types.TypeName:
+ // Abbreviate long aggregate type names.
+ var abbrev string
+ switch t := obj.Type().Underlying().(type) {
+ case *types.Interface:
+ if t.NumMethods() > 1 {
+ abbrev = "interface{...}"
+ }
+ case *types.Struct:
+ if t.NumFields() > 1 {
+ abbrev = "struct{...}"
+ }
+ }
+ if abbrev == "" {
+ fmt.Fprintf(&buf, " %s", types.TypeString(obj.Type().Underlying(), qualifier))
+ } else {
+ fmt.Fprintf(&buf, " %s", abbrev)
+ }
+
+ case *types.Var:
+ fmt.Fprintf(&buf, " %s", types.TypeString(obj.Type(), qualifier))
+ }
+ return buf.String()
+}
+
+func (r *describePackageResult) toSerial(res *serial.Result, fset *token.FileSet) {
+ var members []*serial.DescribeMember
+ for _, mem := range r.members {
+ typ := mem.obj.Type()
+ var val string
+ switch mem := mem.obj.(type) {
+ case *types.Const:
+ val = mem.Val().String()
+ case *types.TypeName:
+ typ = typ.Underlying()
+ }
+ members = append(members, &serial.DescribeMember{
+ Name: mem.obj.Name(),
+ Type: typ.String(),
+ Value: val,
+ Pos: fset.Position(mem.obj.Pos()).String(),
+ Kind: tokenOf(mem.obj),
+ Methods: methodsToSerial(r.pkg, mem.methods, fset),
+ })
+ }
+ res.Describe = &serial.Describe{
+ Desc: r.description,
+ Pos: fset.Position(r.node.Pos()).String(),
+ Detail: "package",
+ Package: &serial.DescribePackage{
+ Path: r.pkg.Path(),
+ Members: members,
+ },
+ }
+}
+
+func tokenOf(o types.Object) string {
+ switch o.(type) {
+ case *types.Func:
+ return "func"
+ case *types.Var:
+ return "var"
+ case *types.TypeName:
+ return "type"
+ case *types.Const:
+ return "const"
+ case *types.PkgName:
+ return "package"
+ }
+ panic(o)
+}
+
+// ---- STATEMENT ------------------------------------------------------------
+
+func describeStmt(qpos *queryPos, path []ast.Node) (*describeStmtResult, error) {
+ var description string
+ switch n := path[0].(type) {
+ case *ast.Ident:
+ if qpos.info.Defs[n] != nil {
+ description = "labelled statement"
+ } else {
+ description = "reference to labelled statement"
+ }
+
+ default:
+ // Nothing much to say about statements.
+ description = astutil.NodeDescription(n)
+ }
+ return &describeStmtResult{qpos.fset, path[0], description}, nil
+}
+
+type describeStmtResult struct {
+ fset *token.FileSet
+ node ast.Node
+ description string
+}
+
+func (r *describeStmtResult) display(printf printfFunc) {
+ printf(r.node, "%s", r.description)
+}
+
+func (r *describeStmtResult) toSerial(res *serial.Result, fset *token.FileSet) {
+ res.Describe = &serial.Describe{
+ Desc: r.description,
+ Pos: fset.Position(r.node.Pos()).String(),
+ Detail: "unknown",
+ }
+}
+
+// ------------------- Utilities -------------------
+
+// pathToString returns a string containing the concrete types of the
+// nodes in path.
+func pathToString(path []ast.Node) string {
+ var buf bytes.Buffer
+ fmt.Fprint(&buf, "[")
+ for i, n := range path {
+ if i > 0 {
+ fmt.Fprint(&buf, " ")
+ }
+ fmt.Fprint(&buf, strings.TrimPrefix(fmt.Sprintf("%T", n), "*ast."))
+ }
+ fmt.Fprint(&buf, "]")
+ return buf.String()
+}
+
+func accessibleMethods(t types.Type, from *types.Package) []*types.Selection {
+ var methods []*types.Selection
+ for _, meth := range typeutil.IntuitiveMethodSet(t, nil) {
+ if isAccessibleFrom(meth.Obj(), from) {
+ methods = append(methods, meth)
+ }
+ }
+ return methods
+}
+
+func isAccessibleFrom(obj types.Object, pkg *types.Package) bool {
+ return ast.IsExported(obj.Name()) || obj.Pkg() == pkg
+}
+
+func methodsToSerial(this *types.Package, methods []*types.Selection, fset *token.FileSet) []serial.DescribeMethod {
+ qualifier := types.RelativeTo(this)
+ var jmethods []serial.DescribeMethod
+ for _, meth := range methods {
+ var ser serial.DescribeMethod
+ if meth != nil { // may contain nils when called by implements (on a method)
+ ser = serial.DescribeMethod{
+ Name: types.SelectionString(meth, qualifier),
+ Pos: fset.Position(meth.Obj().Pos()).String(),
+ }
+ }
+ jmethods = append(jmethods, ser)
+ }
+ return jmethods
+}
diff --git a/vendor/golang.org/x/tools/oracle/freevars.go b/vendor/golang.org/x/tools/oracle/freevars.go
new file mode 100644
index 0000000..400a118
--- /dev/null
+++ b/vendor/golang.org/x/tools/oracle/freevars.go
@@ -0,0 +1,222 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package oracle
+
+import (
+ "bytes"
+ "go/ast"
+ "go/printer"
+ "go/token"
+ "sort"
+
+ "golang.org/x/tools/go/loader"
+ "golang.org/x/tools/go/types"
+ "golang.org/x/tools/oracle/serial"
+)
+
+// freevars displays the lexical (not package-level) free variables of
+// the selection.
+//
+// It treats A.B.C as a separate variable from A to reveal the parts
+// of an aggregate type that are actually needed.
+// This aids refactoring.
+//
+// TODO(adonovan): optionally display the free references to
+// file/package scope objects, and to objects from other packages.
+// Depending on where the resulting function abstraction will go,
+// these might be interesting. Perhaps group the results into three
+// bands.
+//
+func freevars(q *Query) error {
+ lconf := loader.Config{Build: q.Build}
+ allowErrors(&lconf)
+
+ if err := importQueryPackage(q.Pos, &lconf); err != nil {
+ return err
+ }
+
+ // Load/parse/type-check the program.
+ lprog, err := lconf.Load()
+ if err != nil {
+ return err
+ }
+ q.Fset = lprog.Fset
+
+ qpos, err := parseQueryPos(lprog, q.Pos, false)
+ if err != nil {
+ return err
+ }
+
+ file := qpos.path[len(qpos.path)-1] // the enclosing file
+ fileScope := qpos.info.Scopes[file]
+ pkgScope := fileScope.Parent()
+
+ // The id and sel functions return non-nil if they denote an
+ // object o or selection o.x.y that is referenced by the
+ // selection but defined neither within the selection nor at
+ // file scope, i.e. it is in the lexical environment.
+ var id func(n *ast.Ident) types.Object
+ var sel func(n *ast.SelectorExpr) types.Object
+
+ sel = func(n *ast.SelectorExpr) types.Object {
+ switch x := unparen(n.X).(type) {
+ case *ast.SelectorExpr:
+ return sel(x)
+ case *ast.Ident:
+ return id(x)
+ }
+ return nil
+ }
+
+ id = func(n *ast.Ident) types.Object {
+ obj := qpos.info.Uses[n]
+ if obj == nil {
+ return nil // not a reference
+ }
+ if _, ok := obj.(*types.PkgName); ok {
+ return nil // imported package
+ }
+ if !(file.Pos() <= obj.Pos() && obj.Pos() <= file.End()) {
+ return nil // not defined in this file
+ }
+ scope := obj.Parent()
+ if scope == nil {
+ return nil // e.g. interface method, struct field
+ }
+ if scope == fileScope || scope == pkgScope {
+ return nil // defined at file or package scope
+ }
+ if qpos.start <= obj.Pos() && obj.Pos() <= qpos.end {
+ return nil // defined within selection => not free
+ }
+ return obj
+ }
+
+ // Maps each reference that is free in the selection
+ // to the object it refers to.
+ // The map de-duplicates repeated references.
+ refsMap := make(map[string]freevarsRef)
+
+ // Visit all the identifiers in the selected ASTs.
+ ast.Inspect(qpos.path[0], func(n ast.Node) bool {
+ if n == nil {
+ return true // popping DFS stack
+ }
+
+ // Is this node contained within the selection?
+ // (freevars permits inexact selections,
+ // like two stmts in a block.)
+ if qpos.start <= n.Pos() && n.End() <= qpos.end {
+ var obj types.Object
+ var prune bool
+ switch n := n.(type) {
+ case *ast.Ident:
+ obj = id(n)
+
+ case *ast.SelectorExpr:
+ obj = sel(n)
+ prune = true
+ }
+
+ if obj != nil {
+ var kind string
+ switch obj.(type) {
+ case *types.Var:
+ kind = "var"
+ case *types.Func:
+ kind = "func"
+ case *types.TypeName:
+ kind = "type"
+ case *types.Const:
+ kind = "const"
+ case *types.Label:
+ kind = "label"
+ default:
+ panic(obj)
+ }
+
+ typ := qpos.info.TypeOf(n.(ast.Expr))
+ ref := freevarsRef{kind, printNode(lprog.Fset, n), typ, obj}
+ refsMap[ref.ref] = ref
+
+ if prune {
+ return false // don't descend
+ }
+ }
+ }
+
+ return true // descend
+ })
+
+ refs := make([]freevarsRef, 0, len(refsMap))
+ for _, ref := range refsMap {
+ refs = append(refs, ref)
+ }
+ sort.Sort(byRef(refs))
+
+ q.result = &freevarsResult{
+ qpos: qpos,
+ refs: refs,
+ }
+ return nil
+}
+
+type freevarsResult struct {
+ qpos *queryPos
+ refs []freevarsRef
+}
+
+type freevarsRef struct {
+ kind string
+ ref string
+ typ types.Type
+ obj types.Object
+}
+
+func (r *freevarsResult) display(printf printfFunc) {
+ if len(r.refs) == 0 {
+ printf(r.qpos, "No free identifiers.")
+ } else {
+ printf(r.qpos, "Free identifiers:")
+ qualifier := types.RelativeTo(r.qpos.info.Pkg)
+ for _, ref := range r.refs {
+ // Avoid printing "type T T".
+ var typstr string
+ if ref.kind != "type" {
+ typstr = " " + types.TypeString(ref.typ, qualifier)
+ }
+ printf(ref.obj, "%s %s%s", ref.kind, ref.ref, typstr)
+ }
+ }
+}
+
+func (r *freevarsResult) toSerial(res *serial.Result, fset *token.FileSet) {
+ var refs []*serial.FreeVar
+ for _, ref := range r.refs {
+ refs = append(refs,
+ &serial.FreeVar{
+ Pos: fset.Position(ref.obj.Pos()).String(),
+ Kind: ref.kind,
+ Ref: ref.ref,
+ Type: ref.typ.String(),
+ })
+ }
+ res.Freevars = refs
+}
+
+// -------- utils --------
+
+type byRef []freevarsRef
+
+func (p byRef) Len() int { return len(p) }
+func (p byRef) Less(i, j int) bool { return p[i].ref < p[j].ref }
+func (p byRef) Swap(i, j int) { p[i], p[j] = p[j], p[i] }
+
+// printNode returns the pretty-printed syntax of n.
+func printNode(fset *token.FileSet, n ast.Node) string {
+ var buf bytes.Buffer
+ printer.Fprint(&buf, fset, n)
+ return buf.String()
+}
diff --git a/vendor/golang.org/x/tools/oracle/implements.go b/vendor/golang.org/x/tools/oracle/implements.go
new file mode 100644
index 0000000..3155ca2
--- /dev/null
+++ b/vendor/golang.org/x/tools/oracle/implements.go
@@ -0,0 +1,330 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package oracle
+
+import (
+ "fmt"
+ "go/ast"
+ "go/token"
+ "reflect"
+ "sort"
+ "strings"
+
+ "golang.org/x/tools/go/loader"
+ "golang.org/x/tools/go/types"
+ "golang.org/x/tools/go/types/typeutil"
+ "golang.org/x/tools/oracle/serial"
+)
+
+// Implements displays the "implements" relation as it pertains to the
+// selected type within a single package.
+// If the selection is a method, 'implements' displays
+// the corresponding methods of the types that would have been reported
+// by an implements query on the receiver type.
+//
+func implements(q *Query) error {
+ lconf := loader.Config{Build: q.Build}
+ allowErrors(&lconf)
+
+ if err := importQueryPackage(q.Pos, &lconf); err != nil {
+ return err
+ }
+
+ // Load/parse/type-check the program.
+ lprog, err := lconf.Load()
+ if err != nil {
+ return err
+ }
+ q.Fset = lprog.Fset
+
+ qpos, err := parseQueryPos(lprog, q.Pos, false)
+ if err != nil {
+ return err
+ }
+
+ // Find the selected type.
+ path, action := findInterestingNode(qpos.info, qpos.path)
+
+ var method *types.Func
+ var T types.Type // selected type (receiver if method != nil)
+
+ switch action {
+ case actionExpr:
+ // method?
+ if id, ok := path[0].(*ast.Ident); ok {
+ if obj, ok := qpos.info.ObjectOf(id).(*types.Func); ok {
+ recv := obj.Type().(*types.Signature).Recv()
+ if recv == nil {
+ return fmt.Errorf("this function is not a method")
+ }
+ method = obj
+ T = recv.Type()
+ }
+ }
+ case actionType:
+ T = qpos.info.TypeOf(path[0].(ast.Expr))
+ }
+ if T == nil {
+ return fmt.Errorf("no type or method here")
+ }
+
+ // Find all named types, even local types (which can have
+ // methods via promotion) and the built-in "error".
+ //
+ // TODO(adonovan): include all packages in PTA scope too?
+ // i.e. don't reduceScope?
+ //
+ var allNamed []types.Type
+ for _, info := range lprog.AllPackages {
+ for _, obj := range info.Defs {
+ if obj, ok := obj.(*types.TypeName); ok {
+ allNamed = append(allNamed, obj.Type())
+ }
+ }
+ }
+ allNamed = append(allNamed, types.Universe.Lookup("error").Type())
+
+ var msets typeutil.MethodSetCache
+
+ // Test each named type.
+ var to, from, fromPtr []types.Type
+ for _, U := range allNamed {
+ if isInterface(T) {
+ if msets.MethodSet(T).Len() == 0 {
+ continue // empty interface
+ }
+ if isInterface(U) {
+ if msets.MethodSet(U).Len() == 0 {
+ continue // empty interface
+ }
+
+ // T interface, U interface
+ if !types.Identical(T, U) {
+ if types.AssignableTo(U, T) {
+ to = append(to, U)
+ }
+ if types.AssignableTo(T, U) {
+ from = append(from, U)
+ }
+ }
+ } else {
+ // T interface, U concrete
+ if types.AssignableTo(U, T) {
+ to = append(to, U)
+ } else if pU := types.NewPointer(U); types.AssignableTo(pU, T) {
+ to = append(to, pU)
+ }
+ }
+ } else if isInterface(U) {
+ if msets.MethodSet(U).Len() == 0 {
+ continue // empty interface
+ }
+
+ // T concrete, U interface
+ if types.AssignableTo(T, U) {
+ from = append(from, U)
+ } else if pT := types.NewPointer(T); types.AssignableTo(pT, U) {
+ fromPtr = append(fromPtr, U)
+ }
+ }
+ }
+
+ var pos interface{} = qpos
+ if nt, ok := deref(T).(*types.Named); ok {
+ pos = nt.Obj()
+ }
+
+ // Sort types (arbitrarily) to ensure test determinism.
+ sort.Sort(typesByString(to))
+ sort.Sort(typesByString(from))
+ sort.Sort(typesByString(fromPtr))
+
+ var toMethod, fromMethod, fromPtrMethod []*types.Selection // contain nils
+ if method != nil {
+ for _, t := range to {
+ toMethod = append(toMethod,
+ types.NewMethodSet(t).Lookup(method.Pkg(), method.Name()))
+ }
+ for _, t := range from {
+ fromMethod = append(fromMethod,
+ types.NewMethodSet(t).Lookup(method.Pkg(), method.Name()))
+ }
+ for _, t := range fromPtr {
+ fromPtrMethod = append(fromPtrMethod,
+ types.NewMethodSet(t).Lookup(method.Pkg(), method.Name()))
+ }
+ }
+
+ q.result = &implementsResult{
+ qpos, T, pos, to, from, fromPtr, method, toMethod, fromMethod, fromPtrMethod,
+ }
+ return nil
+}
+
+type implementsResult struct {
+ qpos *queryPos
+
+ t types.Type // queried type (not necessarily named)
+ pos interface{} // pos of t (*types.Name or *QueryPos)
+ to []types.Type // named or ptr-to-named types assignable to interface T
+ from []types.Type // named interfaces assignable from T
+ fromPtr []types.Type // named interfaces assignable only from *T
+
+ // if a method was queried:
+ method *types.Func // queried method
+ toMethod []*types.Selection // method of type to[i], if any
+ fromMethod []*types.Selection // method of type from[i], if any
+ fromPtrMethod []*types.Selection // method of type fromPtrMethod[i], if any
+}
+
+func (r *implementsResult) display(printf printfFunc) {
+ relation := "is implemented by"
+
+ meth := func(sel *types.Selection) {
+ if sel != nil {
+ printf(sel.Obj(), "\t%s method (%s).%s",
+ relation, r.qpos.typeString(sel.Recv()), sel.Obj().Name())
+ }
+ }
+
+ if isInterface(r.t) {
+ if types.NewMethodSet(r.t).Len() == 0 { // TODO(adonovan): cache mset
+ printf(r.pos, "empty interface type %s", r.qpos.typeString(r.t))
+ return
+ }
+
+ if r.method == nil {
+ printf(r.pos, "interface type %s", r.qpos.typeString(r.t))
+ } else {
+ printf(r.method, "abstract method %s", r.qpos.objectString(r.method))
+ }
+
+ // Show concrete types (or methods) first; use two passes.
+ for i, sub := range r.to {
+ if !isInterface(sub) {
+ if r.method == nil {
+ printf(deref(sub).(*types.Named).Obj(), "\t%s %s type %s",
+ relation, typeKind(sub), r.qpos.typeString(sub))
+ } else {
+ meth(r.toMethod[i])
+ }
+ }
+ }
+ for i, sub := range r.to {
+ if isInterface(sub) {
+ if r.method == nil {
+ printf(sub.(*types.Named).Obj(), "\t%s %s type %s",
+ relation, typeKind(sub), r.qpos.typeString(sub))
+ } else {
+ meth(r.toMethod[i])
+ }
+ }
+ }
+
+ relation = "implements"
+ for i, super := range r.from {
+ if r.method == nil {
+ printf(super.(*types.Named).Obj(), "\t%s %s",
+ relation, r.qpos.typeString(super))
+ } else {
+ meth(r.fromMethod[i])
+ }
+ }
+ } else {
+ relation = "implements"
+
+ if r.from != nil {
+ if r.method == nil {
+ printf(r.pos, "%s type %s",
+ typeKind(r.t), r.qpos.typeString(r.t))
+ } else {
+ printf(r.method, "concrete method %s",
+ r.qpos.objectString(r.method))
+ }
+ for i, super := range r.from {
+ if r.method == nil {
+ printf(super.(*types.Named).Obj(), "\t%s %s",
+ relation, r.qpos.typeString(super))
+ } else {
+ meth(r.fromMethod[i])
+ }
+ }
+ }
+ if r.fromPtr != nil {
+ if r.method == nil {
+ printf(r.pos, "pointer type *%s", r.qpos.typeString(r.t))
+ } else {
+ // TODO(adonovan): de-dup (C).f and (*C).f implementing (I).f.
+ printf(r.method, "concrete method %s",
+ r.qpos.objectString(r.method))
+ }
+
+ for i, psuper := range r.fromPtr {
+ if r.method == nil {
+ printf(psuper.(*types.Named).Obj(), "\t%s %s",
+ relation, r.qpos.typeString(psuper))
+ } else {
+ meth(r.fromPtrMethod[i])
+ }
+ }
+ } else if r.from == nil {
+ printf(r.pos, "%s type %s implements only interface{}",
+ typeKind(r.t), r.qpos.typeString(r.t))
+ }
+ }
+}
+
+func (r *implementsResult) toSerial(res *serial.Result, fset *token.FileSet) {
+ res.Implements = &serial.Implements{
+ T: makeImplementsType(r.t, fset),
+ AssignableTo: makeImplementsTypes(r.to, fset),
+ AssignableFrom: makeImplementsTypes(r.from, fset),
+ AssignableFromPtr: makeImplementsTypes(r.fromPtr, fset),
+ AssignableToMethod: methodsToSerial(r.qpos.info.Pkg, r.toMethod, fset),
+ AssignableFromMethod: methodsToSerial(r.qpos.info.Pkg, r.fromMethod, fset),
+ AssignableFromPtrMethod: methodsToSerial(r.qpos.info.Pkg, r.fromPtrMethod, fset),
+ }
+ if r.method != nil {
+ res.Implements.Method = &serial.DescribeMethod{
+ Name: r.qpos.objectString(r.method),
+ Pos: fset.Position(r.method.Pos()).String(),
+ }
+ }
+}
+
+func makeImplementsTypes(tt []types.Type, fset *token.FileSet) []serial.ImplementsType {
+ var r []serial.ImplementsType
+ for _, t := range tt {
+ r = append(r, makeImplementsType(t, fset))
+ }
+ return r
+}
+
+func makeImplementsType(T types.Type, fset *token.FileSet) serial.ImplementsType {
+ var pos token.Pos
+ if nt, ok := deref(T).(*types.Named); ok { // implementsResult.t may be non-named
+ pos = nt.Obj().Pos()
+ }
+ return serial.ImplementsType{
+ Name: T.String(),
+ Pos: fset.Position(pos).String(),
+ Kind: typeKind(T),
+ }
+}
+
+// typeKind returns a string describing the underlying kind of type,
+// e.g. "slice", "array", "struct".
+func typeKind(T types.Type) string {
+ s := reflect.TypeOf(T.Underlying()).String()
+ return strings.ToLower(strings.TrimPrefix(s, "*types."))
+}
+
+func isInterface(T types.Type) bool { return types.IsInterface(T) }
+
+type typesByString []types.Type
+
+func (p typesByString) Len() int { return len(p) }
+func (p typesByString) Less(i, j int) bool { return p[i].String() < p[j].String() }
+func (p typesByString) Swap(i, j int) { p[i], p[j] = p[j], p[i] }
diff --git a/vendor/golang.org/x/tools/oracle/oracle.go b/vendor/golang.org/x/tools/oracle/oracle.go
new file mode 100644
index 0000000..544cfa4
--- /dev/null
+++ b/vendor/golang.org/x/tools/oracle/oracle.go
@@ -0,0 +1,364 @@
+// Copyright 2014 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package oracle contains the implementation of the oracle tool whose
+// command-line is provided by golang.org/x/tools/cmd/oracle.
+//
+// http://golang.org/s/oracle-design
+// http://golang.org/s/oracle-user-manual
+//
+package oracle // import "golang.org/x/tools/oracle"
+
+// This file defines oracle.Query, the entry point for the oracle tool.
+// The actual executable is defined in cmd/oracle.
+
+// TODO(adonovan): new queries
+// - show all statements that may update the selected lvalue
+// (local, global, field, etc).
+// - show all places where an object of type T is created
+// (&T{}, var t T, new(T), new(struct{array [3]T}), etc.
+
+import (
+ "fmt"
+ "go/ast"
+ "go/build"
+ "go/parser"
+ "go/token"
+ "io"
+ "path/filepath"
+
+ "golang.org/x/tools/go/ast/astutil"
+ "golang.org/x/tools/go/loader"
+ "golang.org/x/tools/go/pointer"
+ "golang.org/x/tools/go/ssa"
+ "golang.org/x/tools/go/types"
+ "golang.org/x/tools/oracle/serial"
+)
+
+type printfFunc func(pos interface{}, format string, args ...interface{})
+
+// queryResult is the interface of each query-specific result type.
+type queryResult interface {
+ toSerial(res *serial.Result, fset *token.FileSet)
+ display(printf printfFunc)
+}
+
+// A QueryPos represents the position provided as input to a query:
+// a textual extent in the program's source code, the AST node it
+// corresponds to, and the package to which it belongs.
+// Instances are created by parseQueryPos.
+type queryPos struct {
+ fset *token.FileSet
+ start, end token.Pos // source extent of query
+ path []ast.Node // AST path from query node to root of ast.File
+ exact bool // 2nd result of PathEnclosingInterval
+ info *loader.PackageInfo // type info for the queried package (nil for fastQueryPos)
+}
+
+// TypeString prints type T relative to the query position.
+func (qpos *queryPos) typeString(T types.Type) string {
+ return types.TypeString(T, types.RelativeTo(qpos.info.Pkg))
+}
+
+// ObjectString prints object obj relative to the query position.
+func (qpos *queryPos) objectString(obj types.Object) string {
+ return types.ObjectString(obj, types.RelativeTo(qpos.info.Pkg))
+}
+
+// SelectionString prints selection sel relative to the query position.
+func (qpos *queryPos) selectionString(sel *types.Selection) string {
+ return types.SelectionString(sel, types.RelativeTo(qpos.info.Pkg))
+}
+
+// A Query specifies a single oracle query.
+type Query struct {
+ Mode string // query mode ("callers", etc)
+ Pos string // query position
+ Build *build.Context // package loading configuration
+
+ // pointer analysis options
+ Scope []string // main packages in (*loader.Config).FromArgs syntax
+ PTALog io.Writer // (optional) pointer-analysis log file
+ Reflection bool // model reflection soundly (currently slow).
+
+ // Populated during Run()
+ Fset *token.FileSet
+ result queryResult
+}
+
+// Serial returns an instance of serial.Result, which implements the
+// {xml,json}.Marshaler interfaces so that query results can be
+// serialized as JSON or XML.
+//
+func (q *Query) Serial() *serial.Result {
+ resj := &serial.Result{Mode: q.Mode}
+ q.result.toSerial(resj, q.Fset)
+ return resj
+}
+
+// WriteTo writes the oracle query result res to out in a compiler diagnostic format.
+func (q *Query) WriteTo(out io.Writer) {
+ printf := func(pos interface{}, format string, args ...interface{}) {
+ fprintf(out, q.Fset, pos, format, args...)
+ }
+ q.result.display(printf)
+}
+
+// Run runs an oracle query and populates its Fset and Result.
+func Run(q *Query) error {
+ switch q.Mode {
+ case "callees":
+ return callees(q)
+ case "callers":
+ return callers(q)
+ case "callstack":
+ return callstack(q)
+ case "peers":
+ return peers(q)
+ case "pointsto":
+ return pointsto(q)
+ case "whicherrs":
+ return whicherrs(q)
+ case "definition":
+ return definition(q)
+ case "describe":
+ return describe(q)
+ case "freevars":
+ return freevars(q)
+ case "implements":
+ return implements(q)
+ case "referrers":
+ return referrers(q)
+ case "what":
+ return what(q)
+ default:
+ return fmt.Errorf("invalid mode: %q", q.Mode)
+ }
+}
+
+func setPTAScope(lconf *loader.Config, scope []string) error {
+ if len(scope) == 0 {
+ return fmt.Errorf("no packages specified for pointer analysis scope")
+ }
+
+ // Determine initial packages for PTA.
+ args, err := lconf.FromArgs(scope, true)
+ if err != nil {
+ return err
+ }
+ if len(args) > 0 {
+ return fmt.Errorf("surplus arguments: %q", args)
+ }
+ return nil
+}
+
+// Create a pointer.Config whose scope is the initial packages of lprog
+// and their dependencies.
+func setupPTA(prog *ssa.Program, lprog *loader.Program, ptaLog io.Writer, reflection bool) (*pointer.Config, error) {
+ // TODO(adonovan): the body of this function is essentially
+ // duplicated in all go/pointer clients. Refactor.
+
+ // For each initial package (specified on the command line),
+ // if it has a main function, analyze that,
+ // otherwise analyze its tests, if any.
+ var testPkgs, mains []*ssa.Package
+ for _, info := range lprog.InitialPackages() {
+ initialPkg := prog.Package(info.Pkg)
+
+ // Add package to the pointer analysis scope.
+ if initialPkg.Func("main") != nil {
+ mains = append(mains, initialPkg)
+ } else {
+ testPkgs = append(testPkgs, initialPkg)
+ }
+ }
+ if testPkgs != nil {
+ if p := prog.CreateTestMainPackage(testPkgs...); p != nil {
+ mains = append(mains, p)
+ }
+ }
+ if mains == nil {
+ return nil, fmt.Errorf("analysis scope has no main and no tests")
+ }
+ return &pointer.Config{
+ Log: ptaLog,
+ Reflection: reflection,
+ Mains: mains,
+ }, nil
+}
+
+// importQueryPackage finds the package P containing the
+// query position and tells conf to import it.
+func importQueryPackage(pos string, conf *loader.Config) error {
+ fqpos, err := fastQueryPos(pos)
+ if err != nil {
+ return err // bad query
+ }
+ filename := fqpos.fset.File(fqpos.start).Name()
+
+ // This will not work for ad-hoc packages
+ // such as $GOROOT/src/net/http/triv.go.
+ // TODO(adonovan): ensure we report a clear error.
+ _, importPath, err := guessImportPath(filename, conf.Build)
+ if err != nil {
+ return err // can't find GOPATH dir
+ }
+ if importPath == "" {
+ return fmt.Errorf("can't guess import path from %s", filename)
+ }
+
+ // Check that it's possible to load the queried package.
+ // (e.g. oracle tests contain different 'package' decls in same dir.)
+ // Keep consistent with logic in loader/util.go!
+ cfg2 := *conf.Build
+ cfg2.CgoEnabled = false
+ bp, err := cfg2.Import(importPath, "", 0)
+ if err != nil {
+ return err // no files for package
+ }
+
+ switch pkgContainsFile(bp, filename) {
+ case 'T':
+ conf.ImportWithTests(importPath)
+ case 'X':
+ conf.ImportWithTests(importPath)
+ importPath += "_test" // for TypeCheckFuncBodies
+ case 'G':
+ conf.Import(importPath)
+ default:
+ return fmt.Errorf("package %q doesn't contain file %s",
+ importPath, filename)
+ }
+
+ conf.TypeCheckFuncBodies = func(p string) bool { return p == importPath }
+
+ return nil
+}
+
+// pkgContainsFile reports whether file was among the packages Go
+// files, Test files, eXternal test files, or not found.
+func pkgContainsFile(bp *build.Package, filename string) byte {
+ for i, files := range [][]string{bp.GoFiles, bp.TestGoFiles, bp.XTestGoFiles} {
+ for _, file := range files {
+ if sameFile(filepath.Join(bp.Dir, file), filename) {
+ return "GTX"[i]
+ }
+ }
+ }
+ return 0 // not found
+}
+
+// ParseQueryPos parses the source query position pos and returns the
+// AST node of the loaded program lprog that it identifies.
+// If needExact, it must identify a single AST subtree;
+// this is appropriate for queries that allow fairly arbitrary syntax,
+// e.g. "describe".
+//
+func parseQueryPos(lprog *loader.Program, posFlag string, needExact bool) (*queryPos, error) {
+ filename, startOffset, endOffset, err := parsePosFlag(posFlag)
+ if err != nil {
+ return nil, err
+ }
+ start, end, err := findQueryPos(lprog.Fset, filename, startOffset, endOffset)
+ if err != nil {
+ return nil, err
+ }
+ info, path, exact := lprog.PathEnclosingInterval(start, end)
+ if path == nil {
+ return nil, fmt.Errorf("no syntax here")
+ }
+ if needExact && !exact {
+ return nil, fmt.Errorf("ambiguous selection within %s", astutil.NodeDescription(path[0]))
+ }
+ return &queryPos{lprog.Fset, start, end, path, exact, info}, nil
+}
+
+// ---------- Utilities ----------
+
+// allowErrors causes type errors to be silently ignored.
+// (Not suitable if SSA construction follows.)
+func allowErrors(lconf *loader.Config) {
+ ctxt := *lconf.Build // copy
+ ctxt.CgoEnabled = false
+ lconf.Build = &ctxt
+ lconf.AllowErrors = true
+ // AllErrors makes the parser always return an AST instead of
+ // bailing out after 10 errors and returning an empty ast.File.
+ lconf.ParserMode = parser.AllErrors
+ lconf.TypeChecker.Error = func(err error) {}
+}
+
+// ptrAnalysis runs the pointer analysis and returns its result.
+func ptrAnalysis(conf *pointer.Config) *pointer.Result {
+ result, err := pointer.Analyze(conf)
+ if err != nil {
+ panic(err) // pointer analysis internal error
+ }
+ return result
+}
+
+func unparen(e ast.Expr) ast.Expr { return astutil.Unparen(e) }
+
+// deref returns a pointer's element type; otherwise it returns typ.
+func deref(typ types.Type) types.Type {
+ if p, ok := typ.Underlying().(*types.Pointer); ok {
+ return p.Elem()
+ }
+ return typ
+}
+
+// fprintf prints to w a message of the form "location: message\n"
+// where location is derived from pos.
+//
+// pos must be one of:
+// - a token.Pos, denoting a position
+// - an ast.Node, denoting an interval
+// - anything with a Pos() method:
+// ssa.Member, ssa.Value, ssa.Instruction, types.Object, pointer.Label, etc.
+// - a QueryPos, denoting the extent of the user's query.
+// - nil, meaning no position at all.
+//
+// The output format is is compatible with the 'gnu'
+// compilation-error-regexp in Emacs' compilation mode.
+// TODO(adonovan): support other editors.
+//
+func fprintf(w io.Writer, fset *token.FileSet, pos interface{}, format string, args ...interface{}) {
+ var start, end token.Pos
+ switch pos := pos.(type) {
+ case ast.Node:
+ start = pos.Pos()
+ end = pos.End()
+ case token.Pos:
+ start = pos
+ end = start
+ case interface {
+ Pos() token.Pos
+ }:
+ start = pos.Pos()
+ end = start
+ case *queryPos:
+ start = pos.start
+ end = pos.end
+ case nil:
+ // no-op
+ default:
+ panic(fmt.Sprintf("invalid pos: %T", pos))
+ }
+
+ if sp := fset.Position(start); start == end {
+ // (prints "-: " for token.NoPos)
+ fmt.Fprintf(w, "%s: ", sp)
+ } else {
+ ep := fset.Position(end)
+ // The -1 below is a concession to Emacs's broken use of
+ // inclusive (not half-open) intervals.
+ // Other editors may not want it.
+ // TODO(adonovan): add an -editor=vim|emacs|acme|auto
+ // flag; auto uses EMACS=t / VIM=... / etc env vars.
+ fmt.Fprintf(w, "%s:%d.%d-%d.%d: ",
+ sp.Filename, sp.Line, sp.Column, ep.Line, ep.Column-1)
+ }
+ fmt.Fprintf(w, format, args...)
+ io.WriteString(w, "\n")
+}
diff --git a/vendor/golang.org/x/tools/oracle/peers.go b/vendor/golang.org/x/tools/oracle/peers.go
new file mode 100644
index 0000000..9c2a497
--- /dev/null
+++ b/vendor/golang.org/x/tools/oracle/peers.go
@@ -0,0 +1,252 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package oracle
+
+import (
+ "fmt"
+ "go/ast"
+ "go/token"
+ "sort"
+
+ "golang.org/x/tools/go/loader"
+ "golang.org/x/tools/go/ssa"
+ "golang.org/x/tools/go/ssa/ssautil"
+ "golang.org/x/tools/go/types"
+ "golang.org/x/tools/oracle/serial"
+)
+
+// peers enumerates, for a given channel send (or receive) operation,
+// the set of possible receives (or sends) that correspond to it.
+//
+// TODO(adonovan): support reflect.{Select,Recv,Send,Close}.
+// TODO(adonovan): permit the user to query based on a MakeChan (not send/recv),
+// or the implicit receive in "for v := range ch".
+func peers(q *Query) error {
+ lconf := loader.Config{Build: q.Build}
+
+ if err := setPTAScope(&lconf, q.Scope); err != nil {
+ return err
+ }
+
+ // Load/parse/type-check the program.
+ lprog, err := lconf.Load()
+ if err != nil {
+ return err
+ }
+ q.Fset = lprog.Fset
+
+ qpos, err := parseQueryPos(lprog, q.Pos, false)
+ if err != nil {
+ return err
+ }
+
+ prog := ssautil.CreateProgram(lprog, ssa.GlobalDebug)
+
+ ptaConfig, err := setupPTA(prog, lprog, q.PTALog, q.Reflection)
+ if err != nil {
+ return err
+ }
+
+ opPos := findOp(qpos)
+ if opPos == token.NoPos {
+ return fmt.Errorf("there is no channel operation here")
+ }
+
+ // Defer SSA construction till after errors are reported.
+ prog.BuildAll()
+
+ var queryOp chanOp // the originating send or receive operation
+ var ops []chanOp // all sends/receives of opposite direction
+
+ // Look at all channel operations in the whole ssa.Program.
+ // Build a list of those of same type as the query.
+ allFuncs := ssautil.AllFunctions(prog)
+ for fn := range allFuncs {
+ for _, b := range fn.Blocks {
+ for _, instr := range b.Instrs {
+ for _, op := range chanOps(instr) {
+ ops = append(ops, op)
+ if op.pos == opPos {
+ queryOp = op // we found the query op
+ }
+ }
+ }
+ }
+ }
+ if queryOp.ch == nil {
+ return fmt.Errorf("ssa.Instruction for send/receive not found")
+ }
+
+ // Discard operations of wrong channel element type.
+ // Build set of channel ssa.Values as query to pointer analysis.
+ // We compare channels by element types, not channel types, to
+ // ignore both directionality and type names.
+ queryType := queryOp.ch.Type()
+ queryElemType := queryType.Underlying().(*types.Chan).Elem()
+ ptaConfig.AddQuery(queryOp.ch)
+ i := 0
+ for _, op := range ops {
+ if types.Identical(op.ch.Type().Underlying().(*types.Chan).Elem(), queryElemType) {
+ ptaConfig.AddQuery(op.ch)
+ ops[i] = op
+ i++
+ }
+ }
+ ops = ops[:i]
+
+ // Run the pointer analysis.
+ ptares := ptrAnalysis(ptaConfig)
+
+ // Find the points-to set.
+ queryChanPtr := ptares.Queries[queryOp.ch]
+
+ // Ascertain which make(chan) labels the query's channel can alias.
+ var makes []token.Pos
+ for _, label := range queryChanPtr.PointsTo().Labels() {
+ makes = append(makes, label.Pos())
+ }
+ sort.Sort(byPos(makes))
+
+ // Ascertain which channel operations can alias the same make(chan) labels.
+ var sends, receives, closes []token.Pos
+ for _, op := range ops {
+ if ptr, ok := ptares.Queries[op.ch]; ok && ptr.MayAlias(queryChanPtr) {
+ switch op.dir {
+ case types.SendOnly:
+ sends = append(sends, op.pos)
+ case types.RecvOnly:
+ receives = append(receives, op.pos)
+ case types.SendRecv:
+ closes = append(closes, op.pos)
+ }
+ }
+ }
+ sort.Sort(byPos(sends))
+ sort.Sort(byPos(receives))
+ sort.Sort(byPos(closes))
+
+ q.result = &peersResult{
+ queryPos: opPos,
+ queryType: queryType,
+ makes: makes,
+ sends: sends,
+ receives: receives,
+ closes: closes,
+ }
+ return nil
+}
+
+// findOp returns the position of the enclosing send/receive/close op.
+// For send and receive operations, this is the position of the <- token;
+// for close operations, it's the Lparen of the function call.
+//
+// TODO(adonovan): handle implicit receive operations from 'for...range chan' statements.
+func findOp(qpos *queryPos) token.Pos {
+ for _, n := range qpos.path {
+ switch n := n.(type) {
+ case *ast.UnaryExpr:
+ if n.Op == token.ARROW {
+ return n.OpPos
+ }
+ case *ast.SendStmt:
+ return n.Arrow
+ case *ast.CallExpr:
+ // close function call can only exist as a direct identifier
+ if close, ok := unparen(n.Fun).(*ast.Ident); ok {
+ if b, ok := qpos.info.Info.Uses[close].(*types.Builtin); ok && b.Name() == "close" {
+ return n.Lparen
+ }
+ }
+ }
+ }
+ return token.NoPos
+}
+
+// chanOp abstracts an ssa.Send, ssa.Unop(ARROW), or a SelectState.
+type chanOp struct {
+ ch ssa.Value
+ dir types.ChanDir // SendOnly=send, RecvOnly=recv, SendRecv=close
+ pos token.Pos
+}
+
+// chanOps returns a slice of all the channel operations in the instruction.
+func chanOps(instr ssa.Instruction) []chanOp {
+ // TODO(adonovan): handle calls to reflect.{Select,Recv,Send,Close} too.
+ var ops []chanOp
+ switch instr := instr.(type) {
+ case *ssa.UnOp:
+ if instr.Op == token.ARROW {
+ ops = append(ops, chanOp{instr.X, types.RecvOnly, instr.Pos()})
+ }
+ case *ssa.Send:
+ ops = append(ops, chanOp{instr.Chan, types.SendOnly, instr.Pos()})
+ case *ssa.Select:
+ for _, st := range instr.States {
+ ops = append(ops, chanOp{st.Chan, st.Dir, st.Pos})
+ }
+ case ssa.CallInstruction:
+ cc := instr.Common()
+ if b, ok := cc.Value.(*ssa.Builtin); ok && b.Name() == "close" {
+ ops = append(ops, chanOp{cc.Args[0], types.SendRecv, cc.Pos()})
+ }
+ }
+ return ops
+}
+
+type peersResult struct {
+ queryPos token.Pos // of queried channel op
+ queryType types.Type // type of queried channel
+ makes, sends, receives, closes []token.Pos // positions of aliased makechan/send/receive/close instrs
+}
+
+func (r *peersResult) display(printf printfFunc) {
+ if len(r.makes) == 0 {
+ printf(r.queryPos, "This channel can't point to anything.")
+ return
+ }
+ printf(r.queryPos, "This channel of type %s may be:", r.queryType)
+ for _, alloc := range r.makes {
+ printf(alloc, "\tallocated here")
+ }
+ for _, send := range r.sends {
+ printf(send, "\tsent to, here")
+ }
+ for _, receive := range r.receives {
+ printf(receive, "\treceived from, here")
+ }
+ for _, clos := range r.closes {
+ printf(clos, "\tclosed, here")
+ }
+}
+
+func (r *peersResult) toSerial(res *serial.Result, fset *token.FileSet) {
+ peers := &serial.Peers{
+ Pos: fset.Position(r.queryPos).String(),
+ Type: r.queryType.String(),
+ }
+ for _, alloc := range r.makes {
+ peers.Allocs = append(peers.Allocs, fset.Position(alloc).String())
+ }
+ for _, send := range r.sends {
+ peers.Sends = append(peers.Sends, fset.Position(send).String())
+ }
+ for _, receive := range r.receives {
+ peers.Receives = append(peers.Receives, fset.Position(receive).String())
+ }
+ for _, clos := range r.closes {
+ peers.Closes = append(peers.Closes, fset.Position(clos).String())
+ }
+ res.Peers = peers
+}
+
+// -------- utils --------
+
+// NB: byPos is not deterministic across packages since it depends on load order.
+// Use lessPos if the tests need it.
+type byPos []token.Pos
+
+func (p byPos) Len() int { return len(p) }
+func (p byPos) Less(i, j int) bool { return p[i] < p[j] }
+func (p byPos) Swap(i, j int) { p[i], p[j] = p[j], p[i] }
diff --git a/vendor/golang.org/x/tools/oracle/pointsto.go b/vendor/golang.org/x/tools/oracle/pointsto.go
new file mode 100644
index 0000000..d366dd3
--- /dev/null
+++ b/vendor/golang.org/x/tools/oracle/pointsto.go
@@ -0,0 +1,291 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package oracle
+
+import (
+ "fmt"
+ "go/ast"
+ "go/token"
+ "sort"
+
+ "golang.org/x/tools/go/ast/astutil"
+ "golang.org/x/tools/go/loader"
+ "golang.org/x/tools/go/pointer"
+ "golang.org/x/tools/go/ssa"
+ "golang.org/x/tools/go/ssa/ssautil"
+ "golang.org/x/tools/go/types"
+ "golang.org/x/tools/oracle/serial"
+)
+
+// pointsto runs the pointer analysis on the selected expression,
+// and reports its points-to set (for a pointer-like expression)
+// or its dynamic types (for an interface, reflect.Value, or
+// reflect.Type expression) and their points-to sets.
+//
+// All printed sets are sorted to ensure determinism.
+//
+func pointsto(q *Query) error {
+ lconf := loader.Config{Build: q.Build}
+
+ if err := setPTAScope(&lconf, q.Scope); err != nil {
+ return err
+ }
+
+ // Load/parse/type-check the program.
+ lprog, err := lconf.Load()
+ if err != nil {
+ return err
+ }
+ q.Fset = lprog.Fset
+
+ qpos, err := parseQueryPos(lprog, q.Pos, true) // needs exact pos
+ if err != nil {
+ return err
+ }
+
+ prog := ssautil.CreateProgram(lprog, ssa.GlobalDebug)
+
+ ptaConfig, err := setupPTA(prog, lprog, q.PTALog, q.Reflection)
+ if err != nil {
+ return err
+ }
+
+ path, action := findInterestingNode(qpos.info, qpos.path)
+ if action != actionExpr {
+ return fmt.Errorf("pointer analysis wants an expression; got %s",
+ astutil.NodeDescription(qpos.path[0]))
+ }
+
+ var expr ast.Expr
+ var obj types.Object
+ switch n := path[0].(type) {
+ case *ast.ValueSpec:
+ // ambiguous ValueSpec containing multiple names
+ return fmt.Errorf("multiple value specification")
+ case *ast.Ident:
+ obj = qpos.info.ObjectOf(n)
+ expr = n
+ case ast.Expr:
+ expr = n
+ default:
+ // TODO(adonovan): is this reachable?
+ return fmt.Errorf("unexpected AST for expr: %T", n)
+ }
+
+ // Reject non-pointerlike types (includes all constants---except nil).
+ // TODO(adonovan): reject nil too.
+ typ := qpos.info.TypeOf(expr)
+ if !pointer.CanPoint(typ) {
+ return fmt.Errorf("pointer analysis wants an expression of reference type; got %s", typ)
+ }
+
+ // Determine the ssa.Value for the expression.
+ var value ssa.Value
+ var isAddr bool
+ if obj != nil {
+ // def/ref of func/var object
+ value, isAddr, err = ssaValueForIdent(prog, qpos.info, obj, path)
+ } else {
+ value, isAddr, err = ssaValueForExpr(prog, qpos.info, path)
+ }
+ if err != nil {
+ return err // e.g. trivially dead code
+ }
+
+ // Defer SSA construction till after errors are reported.
+ prog.BuildAll()
+
+ // Run the pointer analysis.
+ ptrs, err := runPTA(ptaConfig, value, isAddr)
+ if err != nil {
+ return err // e.g. analytically unreachable
+ }
+
+ q.result = &pointstoResult{
+ qpos: qpos,
+ typ: typ,
+ ptrs: ptrs,
+ }
+ return nil
+}
+
+// ssaValueForIdent returns the ssa.Value for the ast.Ident whose path
+// to the root of the AST is path. isAddr reports whether the
+// ssa.Value is the address denoted by the ast.Ident, not its value.
+//
+func ssaValueForIdent(prog *ssa.Program, qinfo *loader.PackageInfo, obj types.Object, path []ast.Node) (value ssa.Value, isAddr bool, err error) {
+ switch obj := obj.(type) {
+ case *types.Var:
+ pkg := prog.Package(qinfo.Pkg)
+ pkg.Build()
+ if v, addr := prog.VarValue(obj, pkg, path); v != nil {
+ return v, addr, nil
+ }
+ return nil, false, fmt.Errorf("can't locate SSA Value for var %s", obj.Name())
+
+ case *types.Func:
+ fn := prog.FuncValue(obj)
+ if fn == nil {
+ return nil, false, fmt.Errorf("%s is an interface method", obj)
+ }
+ // TODO(adonovan): there's no point running PTA on a *Func ident.
+ // Eliminate this feature.
+ return fn, false, nil
+ }
+ panic(obj)
+}
+
+// ssaValueForExpr returns the ssa.Value of the non-ast.Ident
+// expression whose path to the root of the AST is path.
+//
+func ssaValueForExpr(prog *ssa.Program, qinfo *loader.PackageInfo, path []ast.Node) (value ssa.Value, isAddr bool, err error) {
+ pkg := prog.Package(qinfo.Pkg)
+ pkg.SetDebugMode(true)
+ pkg.Build()
+
+ fn := ssa.EnclosingFunction(pkg, path)
+ if fn == nil {
+ return nil, false, fmt.Errorf("no SSA function built for this location (dead code?)")
+ }
+
+ if v, addr := fn.ValueForExpr(path[0].(ast.Expr)); v != nil {
+ return v, addr, nil
+ }
+
+ return nil, false, fmt.Errorf("can't locate SSA Value for expression in %s", fn)
+}
+
+// runPTA runs the pointer analysis of the selected SSA value or address.
+func runPTA(conf *pointer.Config, v ssa.Value, isAddr bool) (ptrs []pointerResult, err error) {
+ T := v.Type()
+ if isAddr {
+ conf.AddIndirectQuery(v)
+ T = deref(T)
+ } else {
+ conf.AddQuery(v)
+ }
+ ptares := ptrAnalysis(conf)
+
+ var ptr pointer.Pointer
+ if isAddr {
+ ptr = ptares.IndirectQueries[v]
+ } else {
+ ptr = ptares.Queries[v]
+ }
+ if ptr == (pointer.Pointer{}) {
+ return nil, fmt.Errorf("pointer analysis did not find expression (dead code?)")
+ }
+ pts := ptr.PointsTo()
+
+ if pointer.CanHaveDynamicTypes(T) {
+ // Show concrete types for interface/reflect.Value expression.
+ if concs := pts.DynamicTypes(); concs.Len() > 0 {
+ concs.Iterate(func(conc types.Type, pta interface{}) {
+ labels := pta.(pointer.PointsToSet).Labels()
+ sort.Sort(byPosAndString(labels)) // to ensure determinism
+ ptrs = append(ptrs, pointerResult{conc, labels})
+ })
+ }
+ } else {
+ // Show labels for other expressions.
+ labels := pts.Labels()
+ sort.Sort(byPosAndString(labels)) // to ensure determinism
+ ptrs = append(ptrs, pointerResult{T, labels})
+ }
+ sort.Sort(byTypeString(ptrs)) // to ensure determinism
+ return ptrs, nil
+}
+
+type pointerResult struct {
+ typ types.Type // type of the pointer (always concrete)
+ labels []*pointer.Label // set of labels
+}
+
+type pointstoResult struct {
+ qpos *queryPos
+ typ types.Type // type of expression
+ ptrs []pointerResult // pointer info (typ is concrete => len==1)
+}
+
+func (r *pointstoResult) display(printf printfFunc) {
+ if pointer.CanHaveDynamicTypes(r.typ) {
+ // Show concrete types for interface, reflect.Type or
+ // reflect.Value expression.
+
+ if len(r.ptrs) > 0 {
+ printf(r.qpos, "this %s may contain these dynamic types:", r.qpos.typeString(r.typ))
+ for _, ptr := range r.ptrs {
+ var obj types.Object
+ if nt, ok := deref(ptr.typ).(*types.Named); ok {
+ obj = nt.Obj()
+ }
+ if len(ptr.labels) > 0 {
+ printf(obj, "\t%s, may point to:", r.qpos.typeString(ptr.typ))
+ printLabels(printf, ptr.labels, "\t\t")
+ } else {
+ printf(obj, "\t%s", r.qpos.typeString(ptr.typ))
+ }
+ }
+ } else {
+ printf(r.qpos, "this %s cannot contain any dynamic types.", r.typ)
+ }
+ } else {
+ // Show labels for other expressions.
+ if ptr := r.ptrs[0]; len(ptr.labels) > 0 {
+ printf(r.qpos, "this %s may point to these objects:",
+ r.qpos.typeString(r.typ))
+ printLabels(printf, ptr.labels, "\t")
+ } else {
+ printf(r.qpos, "this %s may not point to anything.",
+ r.qpos.typeString(r.typ))
+ }
+ }
+}
+
+func (r *pointstoResult) toSerial(res *serial.Result, fset *token.FileSet) {
+ var pts []serial.PointsTo
+ for _, ptr := range r.ptrs {
+ var namePos string
+ if nt, ok := deref(ptr.typ).(*types.Named); ok {
+ namePos = fset.Position(nt.Obj().Pos()).String()
+ }
+ var labels []serial.PointsToLabel
+ for _, l := range ptr.labels {
+ labels = append(labels, serial.PointsToLabel{
+ Pos: fset.Position(l.Pos()).String(),
+ Desc: l.String(),
+ })
+ }
+ pts = append(pts, serial.PointsTo{
+ Type: r.qpos.typeString(ptr.typ),
+ NamePos: namePos,
+ Labels: labels,
+ })
+ }
+ res.PointsTo = pts
+}
+
+type byTypeString []pointerResult
+
+func (a byTypeString) Len() int { return len(a) }
+func (a byTypeString) Less(i, j int) bool { return a[i].typ.String() < a[j].typ.String() }
+func (a byTypeString) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
+
+type byPosAndString []*pointer.Label
+
+func (a byPosAndString) Len() int { return len(a) }
+func (a byPosAndString) Less(i, j int) bool {
+ cmp := a[i].Pos() - a[j].Pos()
+ return cmp < 0 || (cmp == 0 && a[i].String() < a[j].String())
+}
+func (a byPosAndString) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
+
+func printLabels(printf printfFunc, labels []*pointer.Label, prefix string) {
+ // TODO(adonovan): due to context-sensitivity, many of these
+ // labels may differ only by context, which isn't apparent.
+ for _, label := range labels {
+ printf(label, "%s%s", prefix, label)
+ }
+}
diff --git a/vendor/golang.org/x/tools/oracle/pos.go b/vendor/golang.org/x/tools/oracle/pos.go
new file mode 100644
index 0000000..3c706f3
--- /dev/null
+++ b/vendor/golang.org/x/tools/oracle/pos.go
@@ -0,0 +1,143 @@
+package oracle
+
+// This file defines utilities for working with file positions.
+
+import (
+ "fmt"
+ "go/parser"
+ "go/token"
+ "os"
+ "path/filepath"
+ "strconv"
+ "strings"
+
+ "golang.org/x/tools/go/ast/astutil"
+)
+
+// parseOctothorpDecimal returns the numeric value if s matches "#%d",
+// otherwise -1.
+func parseOctothorpDecimal(s string) int {
+ if s != "" && s[0] == '#' {
+ if s, err := strconv.ParseInt(s[1:], 10, 32); err == nil {
+ return int(s)
+ }
+ }
+ return -1
+}
+
+// parsePosFlag parses a string of the form "file:pos" or
+// file:start,end" where pos, start, end match #%d and represent byte
+// offsets, and returns its components.
+//
+// (Numbers without a '#' prefix are reserved for future use,
+// e.g. to indicate line/column positions.)
+//
+func parsePosFlag(posFlag string) (filename string, startOffset, endOffset int, err error) {
+ if posFlag == "" {
+ err = fmt.Errorf("no source position specified (-pos flag)")
+ return
+ }
+
+ colon := strings.LastIndex(posFlag, ":")
+ if colon < 0 {
+ err = fmt.Errorf("invalid source position -pos=%q", posFlag)
+ return
+ }
+ filename, offset := posFlag[:colon], posFlag[colon+1:]
+ startOffset = -1
+ endOffset = -1
+ if hyphen := strings.Index(offset, ","); hyphen < 0 {
+ // e.g. "foo.go:#123"
+ startOffset = parseOctothorpDecimal(offset)
+ endOffset = startOffset
+ } else {
+ // e.g. "foo.go:#123,#456"
+ startOffset = parseOctothorpDecimal(offset[:hyphen])
+ endOffset = parseOctothorpDecimal(offset[hyphen+1:])
+ }
+ if startOffset < 0 || endOffset < 0 {
+ err = fmt.Errorf("invalid -pos offset %q", offset)
+ return
+ }
+ return
+}
+
+// findQueryPos searches fset for filename and translates the
+// specified file-relative byte offsets into token.Pos form. It
+// returns an error if the file was not found or the offsets were out
+// of bounds.
+//
+func findQueryPos(fset *token.FileSet, filename string, startOffset, endOffset int) (start, end token.Pos, err error) {
+ var file *token.File
+ fset.Iterate(func(f *token.File) bool {
+ if sameFile(filename, f.Name()) {
+ // (f.Name() is absolute)
+ file = f
+ return false // done
+ }
+ return true // continue
+ })
+ if file == nil {
+ err = fmt.Errorf("couldn't find file containing position")
+ return
+ }
+
+ // Range check [start..end], inclusive of both end-points.
+
+ if 0 <= startOffset && startOffset <= file.Size() {
+ start = file.Pos(int(startOffset))
+ } else {
+ err = fmt.Errorf("start position is beyond end of file")
+ return
+ }
+
+ if 0 <= endOffset && endOffset <= file.Size() {
+ end = file.Pos(int(endOffset))
+ } else {
+ err = fmt.Errorf("end position is beyond end of file")
+ return
+ }
+
+ return
+}
+
+// sameFile returns true if x and y have the same basename and denote
+// the same file.
+//
+func sameFile(x, y string) bool {
+ if filepath.Base(x) == filepath.Base(y) { // (optimisation)
+ if xi, err := os.Stat(x); err == nil {
+ if yi, err := os.Stat(y); err == nil {
+ return os.SameFile(xi, yi)
+ }
+ }
+ }
+ return false
+}
+
+// fastQueryPos parses the -pos flag and returns a QueryPos.
+// It parses only a single file, and does not run the type checker.
+func fastQueryPos(posFlag string) (*queryPos, error) {
+ filename, startOffset, endOffset, err := parsePosFlag(posFlag)
+ if err != nil {
+ return nil, err
+ }
+
+ fset := token.NewFileSet()
+ f, err := parser.ParseFile(fset, filename, nil, 0)
+ if err != nil {
+ return nil, err
+ }
+
+ start, end, err := findQueryPos(fset, filename, startOffset, endOffset)
+ if err != nil {
+ return nil, err
+ }
+
+ path, exact := astutil.PathEnclosingInterval(f, start, end)
+ if path == nil {
+ return nil, fmt.Errorf("no syntax here")
+ }
+
+ return &queryPos{fset, start, end, path, exact, nil}, nil
+}
diff --git a/vendor/golang.org/x/tools/oracle/referrers.go b/vendor/golang.org/x/tools/oracle/referrers.go
new file mode 100644
index 0000000..7383d1f
--- /dev/null
+++ b/vendor/golang.org/x/tools/oracle/referrers.go
@@ -0,0 +1,225 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package oracle
+
+import (
+ "bytes"
+ "fmt"
+ "go/ast"
+ "go/token"
+ "io/ioutil"
+ "sort"
+
+ "golang.org/x/tools/go/loader"
+ "golang.org/x/tools/go/types"
+ "golang.org/x/tools/oracle/serial"
+ "golang.org/x/tools/refactor/importgraph"
+)
+
+// Referrers reports all identifiers that resolve to the same object
+// as the queried identifier, within any package in the analysis scope.
+func referrers(q *Query) error {
+ lconf := loader.Config{Build: q.Build}
+ allowErrors(&lconf)
+
+ if err := importQueryPackage(q.Pos, &lconf); err != nil {
+ return err
+ }
+
+ var id *ast.Ident
+ var obj types.Object
+ var lprog *loader.Program
+ var pass2 bool
+ var qpos *queryPos
+ for {
+ // Load/parse/type-check the program.
+ var err error
+ lprog, err = lconf.Load()
+ if err != nil {
+ return err
+ }
+ q.Fset = lprog.Fset
+
+ qpos, err = parseQueryPos(lprog, q.Pos, false)
+ if err != nil {
+ return err
+ }
+
+ id, _ = qpos.path[0].(*ast.Ident)
+ if id == nil {
+ return fmt.Errorf("no identifier here")
+ }
+
+ obj = qpos.info.ObjectOf(id)
+ if obj == nil {
+ // Happens for y in "switch y := x.(type)",
+ // the package declaration,
+ // and unresolved identifiers.
+ if _, ok := qpos.path[1].(*ast.File); ok { // package decl?
+ pkg := qpos.info.Pkg
+ obj = types.NewPkgName(id.Pos(), pkg, pkg.Name(), pkg)
+ } else {
+ return fmt.Errorf("no object for identifier: %T", qpos.path[1])
+ }
+ }
+
+ if pass2 {
+ break
+ }
+
+ // If the identifier is exported, we must load all packages that
+ // depend transitively upon the package that defines it.
+ // Treat PkgNames as exported, even though they're lowercase.
+ if _, isPkg := obj.(*types.PkgName); !(isPkg || obj.Exported()) {
+ break // not exported
+ }
+
+ // Scan the workspace and build the import graph.
+ // Ignore broken packages.
+ _, rev, _ := importgraph.Build(q.Build)
+
+ // Re-load the larger program.
+ // Create a new file set so that ...
+ // External test packages are never imported,
+ // so they will never appear in the graph.
+ // (We must reset the Config here, not just reset the Fset field.)
+ lconf = loader.Config{
+ Fset: token.NewFileSet(),
+ Build: q.Build,
+ }
+ allowErrors(&lconf)
+ for path := range rev.Search(obj.Pkg().Path()) {
+ lconf.ImportWithTests(path)
+ }
+ pass2 = true
+ }
+
+ // Iterate over all go/types' Uses facts for the entire program.
+ var refs []*ast.Ident
+ for _, info := range lprog.AllPackages {
+ for id2, obj2 := range info.Uses {
+ if sameObj(obj, obj2) {
+ refs = append(refs, id2)
+ }
+ }
+ }
+ sort.Sort(byNamePos{q.Fset, refs})
+
+ q.result = &referrersResult{
+ qpos: qpos,
+ query: id,
+ obj: obj,
+ refs: refs,
+ }
+ return nil
+}
+
+// same reports whether x and y are identical, or both are PkgNames
+// that import the same Package.
+//
+func sameObj(x, y types.Object) bool {
+ if x == y {
+ return true
+ }
+ if x, ok := x.(*types.PkgName); ok {
+ if y, ok := y.(*types.PkgName); ok {
+ return x.Imported() == y.Imported()
+ }
+ }
+ return false
+}
+
+// -------- utils --------
+
+// An deterministic ordering for token.Pos that doesn't
+// depend on the order in which packages were loaded.
+func lessPos(fset *token.FileSet, x, y token.Pos) bool {
+ fx := fset.File(x)
+ fy := fset.File(y)
+ if fx != fy {
+ return fx.Name() < fy.Name()
+ }
+ return x < y
+}
+
+type byNamePos struct {
+ fset *token.FileSet
+ ids []*ast.Ident
+}
+
+func (p byNamePos) Len() int { return len(p.ids) }
+func (p byNamePos) Swap(i, j int) { p.ids[i], p.ids[j] = p.ids[j], p.ids[i] }
+func (p byNamePos) Less(i, j int) bool {
+ return lessPos(p.fset, p.ids[i].NamePos, p.ids[j].NamePos)
+}
+
+type referrersResult struct {
+ qpos *queryPos
+ query *ast.Ident // identifier of query
+ obj types.Object // object it denotes
+ refs []*ast.Ident // set of all other references to it
+}
+
+func (r *referrersResult) display(printf printfFunc) {
+ printf(r.obj, "%d references to %s", len(r.refs), r.qpos.objectString(r.obj))
+
+ // Show referring lines, like grep.
+ type fileinfo struct {
+ refs []*ast.Ident
+ linenums []int // line number of refs[i]
+ data chan []byte // file contents
+ }
+ var fileinfos []*fileinfo
+ fileinfosByName := make(map[string]*fileinfo)
+
+ // First pass: start the file reads concurrently.
+ for _, ref := range r.refs {
+ posn := r.qpos.fset.Position(ref.Pos())
+ fi := fileinfosByName[posn.Filename]
+ if fi == nil {
+ fi = &fileinfo{data: make(chan []byte)}
+ fileinfosByName[posn.Filename] = fi
+ fileinfos = append(fileinfos, fi)
+
+ // First request for this file:
+ // start asynchronous read.
+ go func() {
+ content, err := ioutil.ReadFile(posn.Filename)
+ if err != nil {
+ content = []byte(fmt.Sprintf("error: %v", err))
+ }
+ fi.data <- content
+ }()
+ }
+ fi.refs = append(fi.refs, ref)
+ fi.linenums = append(fi.linenums, posn.Line)
+ }
+
+ // Second pass: print refs in original order.
+ // One line may have several refs at different columns.
+ for _, fi := range fileinfos {
+ content := <-fi.data // wait for I/O completion
+ lines := bytes.Split(content, []byte("\n"))
+ for i, ref := range fi.refs {
+ printf(ref, "%s", lines[fi.linenums[i]-1])
+ }
+ }
+}
+
+// TODO(adonovan): encode extent, not just Pos info, in Serial form.
+
+func (r *referrersResult) toSerial(res *serial.Result, fset *token.FileSet) {
+ referrers := &serial.Referrers{
+ Pos: fset.Position(r.query.Pos()).String(),
+ Desc: r.obj.String(),
+ }
+ if pos := r.obj.Pos(); pos != token.NoPos { // Package objects have no Pos()
+ referrers.ObjPos = fset.Position(pos).String()
+ }
+ for _, ref := range r.refs {
+ referrers.Refs = append(referrers.Refs, fset.Position(ref.NamePos).String())
+ }
+ res.Referrers = referrers
+}
diff --git a/vendor/golang.org/x/tools/oracle/serial/serial.go b/vendor/golang.org/x/tools/oracle/serial/serial.go
new file mode 100644
index 0000000..65f0822
--- /dev/null
+++ b/vendor/golang.org/x/tools/oracle/serial/serial.go
@@ -0,0 +1,258 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package serial defines the oracle's schema for structured data
+// serialization using JSON, XML, etc.
+package serial
+
+// All 'pos' strings are of the form "file:line:col".
+// TODO(adonovan): improve performance by sharing filename strings.
+// TODO(adonovan): improve precision by providing the start/end
+// interval when available.
+//
+// TODO(adonovan): consider richer encodings of types, functions,
+// methods, etc.
+
+// A Peers is the result of a 'peers' query.
+// If Allocs is empty, the selected channel can't point to anything.
+type Peers struct {
+ Pos string `json:"pos"` // location of the selected channel op (<-)
+ Type string `json:"type"` // type of the selected channel
+ Allocs []string `json:"allocs,omitempty"` // locations of aliased make(chan) ops
+ Sends []string `json:"sends,omitempty"` // locations of aliased ch<-x ops
+ Receives []string `json:"receives,omitempty"` // locations of aliased <-ch ops
+ Closes []string `json:"closes,omitempty"` // locations of aliased close(ch) ops
+}
+
+// A Referrers is the result of a 'referrers' query.
+type Referrers struct {
+ Pos string `json:"pos"` // location of the query reference
+ ObjPos string `json:"objpos,omitempty"` // location of the definition
+ Desc string `json:"desc"` // description of the denoted object
+ Refs []string `json:"refs,omitempty"` // locations of all references
+}
+
+// A Definition is the result of a 'definition' query.
+type Definition struct {
+ ObjPos string `json:"objpos,omitempty"` // location of the definition
+ Desc string `json:"desc"` // description of the denoted object
+}
+
+type CalleesItem struct {
+ Name string `json:"name"` // full name of called function
+ Pos string `json:"pos"` // location of called function
+}
+
+// A Callees is the result of a 'callees' query.
+//
+// Callees is nonempty unless the call was a dynamic call on a
+// provably nil func or interface value.
+type Callees struct {
+ Pos string `json:"pos"` // location of selected call site
+ Desc string `json:"desc"` // description of call site
+ Callees []*CalleesItem `json:"callees,omitempty"` // set of possible call targets
+}
+
+// A Caller is one element of the slice returned by a 'callers' query.
+// (Callstack also contains a similar slice.)
+//
+// The root of the callgraph has an unspecified "Caller" string.
+type Caller struct {
+ Pos string `json:"pos,omitempty"` // location of the calling function
+ Desc string `json:"desc"` // description of call site
+ Caller string `json:"caller"` // full name of calling function
+}
+
+// A CallStack is the result of a 'callstack' query.
+// It indicates an arbitrary path from the root of the callgraph to
+// the query function.
+//
+// If the Callers slice is empty, the function was unreachable in this
+// analysis scope.
+type CallStack struct {
+ Pos string `json:"pos"` // location of the selected function
+ Target string `json:"target"` // the selected function
+ Callers []Caller `json:"callers"` // enclosing calls, innermost first.
+}
+
+// A FreeVar is one element of the slice returned by a 'freevars'
+// query. Each one identifies an expression referencing a local
+// identifier defined outside the selected region.
+type FreeVar struct {
+ Pos string `json:"pos"` // location of the identifier's definition
+ Kind string `json:"kind"` // one of {var,func,type,const,label}
+ Ref string `json:"ref"` // referring expression (e.g. "x" or "x.y.z")
+ Type string `json:"type"` // type of the expression
+}
+
+// An Implements contains the result of an 'implements' query.
+// It describes the queried type, the set of named non-empty interface
+// types to which it is assignable, and the set of named/*named types
+// (concrete or non-empty interface) which may be assigned to it.
+//
+type Implements struct {
+ T ImplementsType `json:"type,omitempty"` // the queried type
+ AssignableTo []ImplementsType `json:"to,omitempty"` // types assignable to T
+ AssignableFrom []ImplementsType `json:"from,omitempty"` // interface types assignable from T
+ AssignableFromPtr []ImplementsType `json:"fromptr,omitempty"` // interface types assignable only from *T
+
+ // The following fields are set only if the query was a method.
+ // Assignable{To,From,FromPtr}Method[i] is the corresponding
+ // method of type Assignable{To,From,FromPtr}[i], or blank
+ // {"",""} if that type lacks the method.
+ Method *DescribeMethod `json:"method,omitempty"` // the queried method
+ AssignableToMethod []DescribeMethod `json:"to_method,omitempty"`
+ AssignableFromMethod []DescribeMethod `json:"from_method,omitempty"`
+ AssignableFromPtrMethod []DescribeMethod `json:"fromptr_method,omitempty"`
+}
+
+// An ImplementsType describes a single type as part of an 'implements' query.
+type ImplementsType struct {
+ Name string `json:"name"` // full name of the type
+ Pos string `json:"pos"` // location of its definition
+ Kind string `json:"kind"` // "basic", "array", etc
+}
+
+// A SyntaxNode is one element of a stack of enclosing syntax nodes in
+// a "what" query.
+type SyntaxNode struct {
+ Description string `json:"desc"` // description of syntax tree
+ Start int `json:"start"` // start byte offset, 0-based
+ End int `json:"end"` // end byte offset
+}
+
+// A What is the result of the "what" query, which quickly identifies
+// the selection, parsing only a single file. It is intended for use
+// in low-latency GUIs.
+type What struct {
+ Enclosing []SyntaxNode `json:"enclosing"` // enclosing nodes of syntax tree
+ Modes []string `json:"modes"` // query modes enabled for this selection.
+ SrcDir string `json:"srcdir,omitempty"` // $GOROOT src directory containing queried package
+ ImportPath string `json:"importpath,omitempty"` // import path of queried package
+}
+
+// A PointsToLabel describes a pointer analysis label.
+//
+// A "label" is an object that may be pointed to by a pointer, map,
+// channel, 'func', slice or interface. Labels include:
+// - functions
+// - globals
+// - arrays created by literals (e.g. []byte("foo")) and conversions ([]byte(s))
+// - stack- and heap-allocated variables (including composite literals)
+// - arrays allocated by append()
+// - channels, maps and arrays created by make()
+// - and their subelements, e.g. "alloc.y[*].z"
+//
+type PointsToLabel struct {
+ Pos string `json:"pos"` // location of syntax that allocated the object
+ Desc string `json:"desc"` // description of the label
+}
+
+// A PointsTo is one element of the result of a 'pointsto' query on an
+// expression. It describes a single pointer: its type and the set of
+// "labels" it points to.
+//
+// If the pointer is of interface type, it will have one PTS entry
+// describing each concrete type that it may contain. For each
+// concrete type that is a pointer, the PTS entry describes the labels
+// it may point to. The same is true for reflect.Values, except the
+// dynamic types needn't be concrete.
+//
+type PointsTo struct {
+ Type string `json:"type"` // (concrete) type of the pointer
+ NamePos string `json:"namepos,omitempty"` // location of type defn, if Named
+ Labels []PointsToLabel `json:"labels,omitempty"` // pointed-to objects
+}
+
+// A DescribeValue is the additional result of a 'describe' query
+// if the selection indicates a value or expression.
+type DescribeValue struct {
+ Type string `json:"type"` // type of the expression
+ Value string `json:"value,omitempty"` // value of the expression, if constant
+ ObjPos string `json:"objpos,omitempty"` // location of the definition, if an Ident
+}
+
+type DescribeMethod struct {
+ Name string `json:"name"` // method name, as defined by types.Selection.String()
+ Pos string `json:"pos"` // location of the method's definition
+}
+
+// A DescribeType is the additional result of a 'describe' query
+// if the selection indicates a type.
+type DescribeType struct {
+ Type string `json:"type"` // the string form of the type
+ NamePos string `json:"namepos,omitempty"` // location of definition of type, if named
+ NameDef string `json:"namedef,omitempty"` // underlying definition of type, if named
+ Methods []DescribeMethod `json:"methods,omitempty"` // methods of the type
+}
+
+type DescribeMember struct {
+ Name string `json:"name"` // name of member
+ Type string `json:"type,omitempty"` // type of member (underlying, if 'type')
+ Value string `json:"value,omitempty"` // value of member (if 'const')
+ Pos string `json:"pos"` // location of definition of member
+ Kind string `json:"kind"` // one of {var,const,func,type}
+ Methods []DescribeMethod `json:"methods,omitempty"` // methods (if member is a type)
+}
+
+// A DescribePackage is the additional result of a 'describe' if
+// the selection indicates a package.
+type DescribePackage struct {
+ Path string `json:"path"` // import path of the package
+ Members []*DescribeMember `json:"members,omitempty"` // accessible members of the package
+}
+
+// A Describe is the result of a 'describe' query.
+// It may contain an element describing the selected semantic entity
+// in detail.
+type Describe struct {
+ Desc string `json:"desc"` // description of the selected syntax node
+ Pos string `json:"pos"` // location of the selected syntax node
+ Detail string `json:"detail,omitempty"` // one of {package, type, value}, or "".
+
+ // At most one of the following fields is populated:
+ // the one specified by 'detail'.
+ Package *DescribePackage `json:"package,omitempty"`
+ Type *DescribeType `json:"type,omitempty"`
+ Value *DescribeValue `json:"value,omitempty"`
+}
+
+// A WhichErrs is the result of a 'whicherrs' query.
+// It contains the position of the queried error and the possible globals,
+// constants, and types it may point to.
+type WhichErrs struct {
+ ErrPos string `json:"errpos,omitempty"` // location of queried error
+ Globals []string `json:"globals,omitempty"` // locations of globals
+ Constants []string `json:"constants,omitempty"` // locations of constants
+ Types []WhichErrsType `json:"types,omitempty"` // Types
+}
+
+type WhichErrsType struct {
+ Type string `json:"type,omitempty"`
+ Position string `json:"position,omitempty"`
+}
+
+// A Result is the common result of any oracle query.
+// It contains a query-specific result element.
+//
+// TODO(adonovan): perhaps include other info such as: analysis scope,
+// raw query position, stack of ast nodes, query package, etc.
+type Result struct {
+ Mode string `json:"mode"` // mode of the query
+
+ // Exactly one of the following fields is populated:
+ // the one specified by 'mode'.
+ Callees *Callees `json:"callees,omitempty"`
+ Callers []Caller `json:"callers,omitempty"`
+ Callstack *CallStack `json:"callstack,omitempty"`
+ Definition *Definition `json:"definition,omitempty"`
+ Describe *Describe `json:"describe,omitempty"`
+ Freevars []*FreeVar `json:"freevars,omitempty"`
+ Implements *Implements `json:"implements,omitempty"`
+ Peers *Peers `json:"peers,omitempty"`
+ PointsTo []PointsTo `json:"pointsto,omitempty"`
+ Referrers *Referrers `json:"referrers,omitempty"`
+ What *What `json:"what,omitempty"`
+ WhichErrs *WhichErrs `json:"whicherrs,omitempty"`
+}
diff --git a/vendor/golang.org/x/tools/oracle/what.go b/vendor/golang.org/x/tools/oracle/what.go
new file mode 100644
index 0000000..5a5c0cf
--- /dev/null
+++ b/vendor/golang.org/x/tools/oracle/what.go
@@ -0,0 +1,210 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package oracle
+
+import (
+ "fmt"
+ "go/ast"
+ "go/build"
+ "go/token"
+ "os"
+ "path/filepath"
+ "sort"
+ "strings"
+
+ "golang.org/x/tools/go/ast/astutil"
+ "golang.org/x/tools/oracle/serial"
+)
+
+// what reports all the information about the query selection that can be
+// obtained from parsing only its containing source file.
+// It is intended to be a very low-latency query callable from GUI
+// tools, e.g. to populate a menu of options of slower queries about
+// the selected location.
+//
+func what(q *Query) error {
+ qpos, err := fastQueryPos(q.Pos)
+ if err != nil {
+ return err
+ }
+ q.Fset = qpos.fset
+
+ // (ignore errors)
+ srcdir, importPath, _ := guessImportPath(q.Fset.File(qpos.start).Name(), q.Build)
+
+ // Determine which query modes are applicable to the selection.
+ enable := map[string]bool{
+ "describe": true, // any syntax; always enabled
+ }
+
+ if qpos.end > qpos.start {
+ enable["freevars"] = true // nonempty selection?
+ }
+
+ for _, n := range qpos.path {
+ switch n := n.(type) {
+ case *ast.Ident:
+ enable["definition"] = true
+ enable["referrers"] = true
+ enable["implements"] = true
+ case *ast.CallExpr:
+ enable["callees"] = true
+ case *ast.FuncDecl:
+ enable["callers"] = true
+ enable["callstack"] = true
+ case *ast.SendStmt:
+ enable["peers"] = true
+ case *ast.UnaryExpr:
+ if n.Op == token.ARROW {
+ enable["peers"] = true
+ }
+ }
+
+ // For implements, we approximate findInterestingNode.
+ if _, ok := enable["implements"]; !ok {
+ switch n.(type) {
+ case *ast.ArrayType,
+ *ast.StructType,
+ *ast.FuncType,
+ *ast.InterfaceType,
+ *ast.MapType,
+ *ast.ChanType:
+ enable["implements"] = true
+ }
+ }
+
+ // For pointsto, we approximate findInterestingNode.
+ if _, ok := enable["pointsto"]; !ok {
+ switch n.(type) {
+ case ast.Stmt,
+ *ast.ArrayType,
+ *ast.StructType,
+ *ast.FuncType,
+ *ast.InterfaceType,
+ *ast.MapType,
+ *ast.ChanType:
+ enable["pointsto"] = false // not an expr
+
+ case ast.Expr, ast.Decl, *ast.ValueSpec:
+ enable["pointsto"] = true // an expr, maybe
+
+ default:
+ // Comment, Field, KeyValueExpr, etc: ascend.
+ }
+ }
+ }
+
+ // If we don't have an exact selection, disable modes that need one.
+ if !qpos.exact {
+ enable["callees"] = false
+ enable["pointsto"] = false
+ enable["whicherrs"] = false
+ enable["describe"] = false
+ }
+
+ var modes []string
+ for mode := range enable {
+ modes = append(modes, mode)
+ }
+ sort.Strings(modes)
+
+ q.result = &whatResult{
+ path: qpos.path,
+ srcdir: srcdir,
+ importPath: importPath,
+ modes: modes,
+ }
+ return nil
+}
+
+// guessImportPath finds the package containing filename, and returns
+// its source directory (an element of $GOPATH) and its import path
+// relative to it.
+//
+// TODO(adonovan): what about _test.go files that are not part of the
+// package?
+//
+func guessImportPath(filename string, buildContext *build.Context) (srcdir, importPath string, err error) {
+ absFile, err := filepath.Abs(filename)
+ if err != nil {
+ err = fmt.Errorf("can't form absolute path of %s", filename)
+ return
+ }
+ absFileDir := segments(filepath.Dir(absFile))
+
+ // Find the innermost directory in $GOPATH that encloses filename.
+ minD := 1024
+ for _, gopathDir := range buildContext.SrcDirs() {
+ absDir, err := filepath.Abs(gopathDir)
+ if err != nil {
+ continue // e.g. non-existent dir on $GOPATH
+ }
+ d := prefixLen(segments(absDir), absFileDir)
+ // If there are multiple matches,
+ // prefer the innermost enclosing directory
+ // (smallest d).
+ if d >= 0 && d < minD {
+ minD = d
+ srcdir = gopathDir
+ importPath = strings.Join(absFileDir[len(absFileDir)-minD:], string(os.PathSeparator))
+ }
+ }
+ if srcdir == "" {
+ err = fmt.Errorf("directory %s is not beneath any of these GOROOT/GOPATH directories: %s",
+ filepath.Dir(absFile), strings.Join(buildContext.SrcDirs(), ", "))
+ }
+ return
+}
+
+func segments(path string) []string {
+ return strings.Split(path, string(os.PathSeparator))
+}
+
+// prefixLen returns the length of the remainder of y if x is a prefix
+// of y, a negative number otherwise.
+func prefixLen(x, y []string) int {
+ d := len(y) - len(x)
+ if d >= 0 {
+ for i := range x {
+ if y[i] != x[i] {
+ return -1 // not a prefix
+ }
+ }
+ }
+ return d
+}
+
+type whatResult struct {
+ path []ast.Node
+ modes []string
+ srcdir string
+ importPath string
+}
+
+func (r *whatResult) display(printf printfFunc) {
+ for _, n := range r.path {
+ printf(n, "%s", astutil.NodeDescription(n))
+ }
+ printf(nil, "modes: %s", r.modes)
+ printf(nil, "srcdir: %s", r.srcdir)
+ printf(nil, "import path: %s", r.importPath)
+}
+
+func (r *whatResult) toSerial(res *serial.Result, fset *token.FileSet) {
+ var enclosing []serial.SyntaxNode
+ for _, n := range r.path {
+ enclosing = append(enclosing, serial.SyntaxNode{
+ Description: astutil.NodeDescription(n),
+ Start: fset.Position(n.Pos()).Offset,
+ End: fset.Position(n.End()).Offset,
+ })
+ }
+ res.What = &serial.What{
+ Modes: r.modes,
+ SrcDir: r.srcdir,
+ ImportPath: r.importPath,
+ Enclosing: enclosing,
+ }
+}
diff --git a/vendor/golang.org/x/tools/oracle/whicherrs.go b/vendor/golang.org/x/tools/oracle/whicherrs.go
new file mode 100644
index 0000000..aaa6068
--- /dev/null
+++ b/vendor/golang.org/x/tools/oracle/whicherrs.go
@@ -0,0 +1,326 @@
+// Copyright 2014 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package oracle
+
+import (
+ "fmt"
+ "go/ast"
+ "go/token"
+ "sort"
+
+ "golang.org/x/tools/go/ast/astutil"
+ "golang.org/x/tools/go/loader"
+ "golang.org/x/tools/go/ssa"
+ "golang.org/x/tools/go/ssa/ssautil"
+ "golang.org/x/tools/go/types"
+ "golang.org/x/tools/oracle/serial"
+)
+
+var builtinErrorType = types.Universe.Lookup("error").Type()
+
+// whicherrs takes an position to an error and tries to find all types, constants
+// and global value which a given error can point to and which can be checked from the
+// scope where the error lives.
+// In short, it returns a list of things that can be checked against in order to handle
+// an error properly.
+//
+// TODO(dmorsing): figure out if fields in errors like *os.PathError.Err
+// can be queried recursively somehow.
+func whicherrs(q *Query) error {
+ lconf := loader.Config{Build: q.Build}
+
+ if err := setPTAScope(&lconf, q.Scope); err != nil {
+ return err
+ }
+
+ // Load/parse/type-check the program.
+ lprog, err := lconf.Load()
+ if err != nil {
+ return err
+ }
+ q.Fset = lprog.Fset
+
+ qpos, err := parseQueryPos(lprog, q.Pos, true) // needs exact pos
+ if err != nil {
+ return err
+ }
+
+ prog := ssautil.CreateProgram(lprog, ssa.GlobalDebug)
+
+ ptaConfig, err := setupPTA(prog, lprog, q.PTALog, q.Reflection)
+ if err != nil {
+ return err
+ }
+
+ path, action := findInterestingNode(qpos.info, qpos.path)
+ if action != actionExpr {
+ return fmt.Errorf("whicherrs wants an expression; got %s",
+ astutil.NodeDescription(qpos.path[0]))
+ }
+ var expr ast.Expr
+ var obj types.Object
+ switch n := path[0].(type) {
+ case *ast.ValueSpec:
+ // ambiguous ValueSpec containing multiple names
+ return fmt.Errorf("multiple value specification")
+ case *ast.Ident:
+ obj = qpos.info.ObjectOf(n)
+ expr = n
+ case ast.Expr:
+ expr = n
+ default:
+ return fmt.Errorf("unexpected AST for expr: %T", n)
+ }
+
+ typ := qpos.info.TypeOf(expr)
+ if !types.Identical(typ, builtinErrorType) {
+ return fmt.Errorf("selection is not an expression of type 'error'")
+ }
+ // Determine the ssa.Value for the expression.
+ var value ssa.Value
+ if obj != nil {
+ // def/ref of func/var object
+ value, _, err = ssaValueForIdent(prog, qpos.info, obj, path)
+ } else {
+ value, _, err = ssaValueForExpr(prog, qpos.info, path)
+ }
+ if err != nil {
+ return err // e.g. trivially dead code
+ }
+
+ // Defer SSA construction till after errors are reported.
+ prog.BuildAll()
+
+ globals := findVisibleErrs(prog, qpos)
+ constants := findVisibleConsts(prog, qpos)
+
+ res := &whicherrsResult{
+ qpos: qpos,
+ errpos: expr.Pos(),
+ }
+
+ // TODO(adonovan): the following code is heavily duplicated
+ // w.r.t. "pointsto". Refactor?
+
+ // Find the instruction which initialized the
+ // global error. If more than one instruction has stored to the global
+ // remove the global from the set of values that we want to query.
+ allFuncs := ssautil.AllFunctions(prog)
+ for fn := range allFuncs {
+ for _, b := range fn.Blocks {
+ for _, instr := range b.Instrs {
+ store, ok := instr.(*ssa.Store)
+ if !ok {
+ continue
+ }
+ gval, ok := store.Addr.(*ssa.Global)
+ if !ok {
+ continue
+ }
+ gbl, ok := globals[gval]
+ if !ok {
+ continue
+ }
+ // we already found a store to this global
+ // The normal error define is just one store in the init
+ // so we just remove this global from the set we want to query
+ if gbl != nil {
+ delete(globals, gval)
+ }
+ globals[gval] = store.Val
+ }
+ }
+ }
+
+ ptaConfig.AddQuery(value)
+ for _, v := range globals {
+ ptaConfig.AddQuery(v)
+ }
+
+ ptares := ptrAnalysis(ptaConfig)
+ valueptr := ptares.Queries[value]
+ for g, v := range globals {
+ ptr, ok := ptares.Queries[v]
+ if !ok {
+ continue
+ }
+ if !ptr.MayAlias(valueptr) {
+ continue
+ }
+ res.globals = append(res.globals, g)
+ }
+ pts := valueptr.PointsTo()
+ dedup := make(map[*ssa.NamedConst]bool)
+ for _, label := range pts.Labels() {
+ // These values are either MakeInterfaces or reflect
+ // generated interfaces. For the purposes of this
+ // analysis, we don't care about reflect generated ones
+ makeiface, ok := label.Value().(*ssa.MakeInterface)
+ if !ok {
+ continue
+ }
+ constval, ok := makeiface.X.(*ssa.Const)
+ if !ok {
+ continue
+ }
+ c := constants[*constval]
+ if c != nil && !dedup[c] {
+ dedup[c] = true
+ res.consts = append(res.consts, c)
+ }
+ }
+ concs := pts.DynamicTypes()
+ concs.Iterate(func(conc types.Type, _ interface{}) {
+ // go/types is a bit annoying here.
+ // We want to find all the types that we can
+ // typeswitch or assert to. This means finding out
+ // if the type pointed to can be seen by us.
+ //
+ // For the purposes of this analysis, the type is always
+ // either a Named type or a pointer to one.
+ // There are cases where error can be implemented
+ // by unnamed types, but in that case, we can't assert to
+ // it, so we don't care about it for this analysis.
+ var name *types.TypeName
+ switch t := conc.(type) {
+ case *types.Pointer:
+ named, ok := t.Elem().(*types.Named)
+ if !ok {
+ return
+ }
+ name = named.Obj()
+ case *types.Named:
+ name = t.Obj()
+ default:
+ return
+ }
+ if !isAccessibleFrom(name, qpos.info.Pkg) {
+ return
+ }
+ res.types = append(res.types, &errorType{conc, name})
+ })
+ sort.Sort(membersByPosAndString(res.globals))
+ sort.Sort(membersByPosAndString(res.consts))
+ sort.Sort(sorterrorType(res.types))
+
+ q.result = res
+ return nil
+}
+
+// findVisibleErrs returns a mapping from each package-level variable of type "error" to nil.
+func findVisibleErrs(prog *ssa.Program, qpos *queryPos) map[*ssa.Global]ssa.Value {
+ globals := make(map[*ssa.Global]ssa.Value)
+ for _, pkg := range prog.AllPackages() {
+ for _, mem := range pkg.Members {
+ gbl, ok := mem.(*ssa.Global)
+ if !ok {
+ continue
+ }
+ gbltype := gbl.Type()
+ // globals are always pointers
+ if !types.Identical(deref(gbltype), builtinErrorType) {
+ continue
+ }
+ if !isAccessibleFrom(gbl.Object(), qpos.info.Pkg) {
+ continue
+ }
+ globals[gbl] = nil
+ }
+ }
+ return globals
+}
+
+// findVisibleConsts returns a mapping from each package-level constant assignable to type "error", to nil.
+func findVisibleConsts(prog *ssa.Program, qpos *queryPos) map[ssa.Const]*ssa.NamedConst {
+ constants := make(map[ssa.Const]*ssa.NamedConst)
+ for _, pkg := range prog.AllPackages() {
+ for _, mem := range pkg.Members {
+ obj, ok := mem.(*ssa.NamedConst)
+ if !ok {
+ continue
+ }
+ consttype := obj.Type()
+ if !types.AssignableTo(consttype, builtinErrorType) {
+ continue
+ }
+ if !isAccessibleFrom(obj.Object(), qpos.info.Pkg) {
+ continue
+ }
+ constants[*obj.Value] = obj
+ }
+ }
+
+ return constants
+}
+
+type membersByPosAndString []ssa.Member
+
+func (a membersByPosAndString) Len() int { return len(a) }
+func (a membersByPosAndString) Less(i, j int) bool {
+ cmp := a[i].Pos() - a[j].Pos()
+ return cmp < 0 || cmp == 0 && a[i].String() < a[j].String()
+}
+func (a membersByPosAndString) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
+
+type sorterrorType []*errorType
+
+func (a sorterrorType) Len() int { return len(a) }
+func (a sorterrorType) Less(i, j int) bool {
+ cmp := a[i].obj.Pos() - a[j].obj.Pos()
+ return cmp < 0 || cmp == 0 && a[i].typ.String() < a[j].typ.String()
+}
+func (a sorterrorType) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
+
+type errorType struct {
+ typ types.Type // concrete type N or *N that implements error
+ obj *types.TypeName // the named type N
+}
+
+type whicherrsResult struct {
+ qpos *queryPos
+ errpos token.Pos
+ globals []ssa.Member
+ consts []ssa.Member
+ types []*errorType
+}
+
+func (r *whicherrsResult) display(printf printfFunc) {
+ if len(r.globals) > 0 {
+ printf(r.qpos, "this error may point to these globals:")
+ for _, g := range r.globals {
+ printf(g.Pos(), "\t%s", g.RelString(r.qpos.info.Pkg))
+ }
+ }
+ if len(r.consts) > 0 {
+ printf(r.qpos, "this error may contain these constants:")
+ for _, c := range r.consts {
+ printf(c.Pos(), "\t%s", c.RelString(r.qpos.info.Pkg))
+ }
+ }
+ if len(r.types) > 0 {
+ printf(r.qpos, "this error may contain these dynamic types:")
+ for _, t := range r.types {
+ printf(t.obj.Pos(), "\t%s", r.qpos.typeString(t.typ))
+ }
+ }
+}
+
+func (r *whicherrsResult) toSerial(res *serial.Result, fset *token.FileSet) {
+ we := &serial.WhichErrs{}
+ we.ErrPos = fset.Position(r.errpos).String()
+ for _, g := range r.globals {
+ we.Globals = append(we.Globals, fset.Position(g.Pos()).String())
+ }
+ for _, c := range r.consts {
+ we.Constants = append(we.Constants, fset.Position(c.Pos()).String())
+ }
+ for _, t := range r.types {
+ var et serial.WhichErrsType
+ et.Type = r.qpos.typeString(t.typ)
+ et.Position = fset.Position(t.obj.Pos()).String()
+ we.Types = append(we.Types, et)
+ }
+ res.WhichErrs = we
+}
diff --git a/vendor/golang.org/x/tools/present/args.go b/vendor/golang.org/x/tools/present/args.go
new file mode 100644
index 0000000..49ee1a9
--- /dev/null
+++ b/vendor/golang.org/x/tools/present/args.go
@@ -0,0 +1,229 @@
+// Copyright 2012 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package present
+
+import (
+ "errors"
+ "regexp"
+ "strconv"
+ "unicode/utf8"
+)
+
+// This file is stolen from go/src/cmd/godoc/codewalk.go.
+// It's an evaluator for the file address syntax implemented by acme and sam,
+// but using Go-native regular expressions.
+// To keep things reasonably close, this version uses (?m:re) for all user-provided
+// regular expressions. That is the only change to the code from codewalk.go.
+// See http://plan9.bell-labs.com/sys/doc/sam/sam.html Table II
+// for details on the syntax.
+
+// addrToByte evaluates the given address starting at offset start in data.
+// It returns the lo and hi byte offset of the matched region within data.
+func addrToByteRange(addr string, start int, data []byte) (lo, hi int, err error) {
+ if addr == "" {
+ lo, hi = start, len(data)
+ return
+ }
+ var (
+ dir byte
+ prevc byte
+ charOffset bool
+ )
+ lo = start
+ hi = start
+ for addr != "" && err == nil {
+ c := addr[0]
+ switch c {
+ default:
+ err = errors.New("invalid address syntax near " + string(c))
+ case ',':
+ if len(addr) == 1 {
+ hi = len(data)
+ } else {
+ _, hi, err = addrToByteRange(addr[1:], hi, data)
+ }
+ return
+
+ case '+', '-':
+ if prevc == '+' || prevc == '-' {
+ lo, hi, err = addrNumber(data, lo, hi, prevc, 1, charOffset)
+ }
+ dir = c
+
+ case '$':
+ lo = len(data)
+ hi = len(data)
+ if len(addr) > 1 {
+ dir = '+'
+ }
+
+ case '#':
+ charOffset = true
+
+ case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
+ var i int
+ for i = 1; i < len(addr); i++ {
+ if addr[i] < '0' || addr[i] > '9' {
+ break
+ }
+ }
+ var n int
+ n, err = strconv.Atoi(addr[0:i])
+ if err != nil {
+ break
+ }
+ lo, hi, err = addrNumber(data, lo, hi, dir, n, charOffset)
+ dir = 0
+ charOffset = false
+ prevc = c
+ addr = addr[i:]
+ continue
+
+ case '/':
+ var i, j int
+ Regexp:
+ for i = 1; i < len(addr); i++ {
+ switch addr[i] {
+ case '\\':
+ i++
+ case '/':
+ j = i + 1
+ break Regexp
+ }
+ }
+ if j == 0 {
+ j = i
+ }
+ pattern := addr[1:i]
+ lo, hi, err = addrRegexp(data, lo, hi, dir, pattern)
+ prevc = c
+ addr = addr[j:]
+ continue
+ }
+ prevc = c
+ addr = addr[1:]
+ }
+
+ if err == nil && dir != 0 {
+ lo, hi, err = addrNumber(data, lo, hi, dir, 1, charOffset)
+ }
+ if err != nil {
+ return 0, 0, err
+ }
+ return lo, hi, nil
+}
+
+// addrNumber applies the given dir, n, and charOffset to the address lo, hi.
+// dir is '+' or '-', n is the count, and charOffset is true if the syntax
+// used was #n. Applying +n (or +#n) means to advance n lines
+// (or characters) after hi. Applying -n (or -#n) means to back up n lines
+// (or characters) before lo.
+// The return value is the new lo, hi.
+func addrNumber(data []byte, lo, hi int, dir byte, n int, charOffset bool) (int, int, error) {
+ switch dir {
+ case 0:
+ lo = 0
+ hi = 0
+ fallthrough
+
+ case '+':
+ if charOffset {
+ pos := hi
+ for ; n > 0 && pos < len(data); n-- {
+ _, size := utf8.DecodeRune(data[pos:])
+ pos += size
+ }
+ if n == 0 {
+ return pos, pos, nil
+ }
+ break
+ }
+ // find next beginning of line
+ if hi > 0 {
+ for hi < len(data) && data[hi-1] != '\n' {
+ hi++
+ }
+ }
+ lo = hi
+ if n == 0 {
+ return lo, hi, nil
+ }
+ for ; hi < len(data); hi++ {
+ if data[hi] != '\n' {
+ continue
+ }
+ switch n--; n {
+ case 1:
+ lo = hi + 1
+ case 0:
+ return lo, hi + 1, nil
+ }
+ }
+
+ case '-':
+ if charOffset {
+ // Scan backward for bytes that are not UTF-8 continuation bytes.
+ pos := lo
+ for ; pos > 0 && n > 0; pos-- {
+ if data[pos]&0xc0 != 0x80 {
+ n--
+ }
+ }
+ if n == 0 {
+ return pos, pos, nil
+ }
+ break
+ }
+ // find earlier beginning of line
+ for lo > 0 && data[lo-1] != '\n' {
+ lo--
+ }
+ hi = lo
+ if n == 0 {
+ return lo, hi, nil
+ }
+ for ; lo >= 0; lo-- {
+ if lo > 0 && data[lo-1] != '\n' {
+ continue
+ }
+ switch n--; n {
+ case 1:
+ hi = lo
+ case 0:
+ return lo, hi, nil
+ }
+ }
+ }
+
+ return 0, 0, errors.New("address out of range")
+}
+
+// addrRegexp searches for pattern in the given direction starting at lo, hi.
+// The direction dir is '+' (search forward from hi) or '-' (search backward from lo).
+// Backward searches are unimplemented.
+func addrRegexp(data []byte, lo, hi int, dir byte, pattern string) (int, int, error) {
+ // We want ^ and $ to work as in sam/acme, so use ?m.
+ re, err := regexp.Compile("(?m:" + pattern + ")")
+ if err != nil {
+ return 0, 0, err
+ }
+ if dir == '-' {
+ // Could implement reverse search using binary search
+ // through file, but that seems like overkill.
+ return 0, 0, errors.New("reverse search not implemented")
+ }
+ m := re.FindIndex(data[hi:])
+ if len(m) > 0 {
+ m[0] += hi
+ m[1] += hi
+ } else if hi > 0 {
+ // No match. Wrap to beginning of data.
+ m = re.FindIndex(data)
+ }
+ if len(m) == 0 {
+ return 0, 0, errors.New("no match for " + pattern)
+ }
+ return m[0], m[1], nil
+}
diff --git a/vendor/golang.org/x/tools/present/caption.go b/vendor/golang.org/x/tools/present/caption.go
new file mode 100644
index 0000000..00e0b5d
--- /dev/null
+++ b/vendor/golang.org/x/tools/present/caption.go
@@ -0,0 +1,22 @@
+// Copyright 2012 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package present
+
+import "strings"
+
+func init() {
+ Register("caption", parseCaption)
+}
+
+type Caption struct {
+ Text string
+}
+
+func (c Caption) TemplateName() string { return "caption" }
+
+func parseCaption(_ *Context, _ string, _ int, text string) (Elem, error) {
+ text = strings.TrimSpace(strings.TrimPrefix(text, ".caption"))
+ return Caption{text}, nil
+}
diff --git a/vendor/golang.org/x/tools/present/code.go b/vendor/golang.org/x/tools/present/code.go
new file mode 100644
index 0000000..5a29951
--- /dev/null
+++ b/vendor/golang.org/x/tools/present/code.go
@@ -0,0 +1,293 @@
+// Copyright 2012 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package present
+
+import (
+ "bufio"
+ "bytes"
+ "fmt"
+ "html/template"
+ "path/filepath"
+ "regexp"
+ "strconv"
+ "strings"
+)
+
+// Is the playground available?
+var PlayEnabled = false
+
+// TOOD(adg): replace the PlayEnabled flag with something less spaghetti-like.
+// Instead this will probably be determined by a template execution Context
+// value that contains various global metadata required when rendering
+// templates.
+
+func init() {
+ Register("code", parseCode)
+ Register("play", parseCode)
+}
+
+type Code struct {
+ Text template.HTML
+ Play bool // runnable code
+ FileName string // file name
+ Ext string // file extension
+ Raw []byte // content of the file
+}
+
+func (c Code) TemplateName() string { return "code" }
+
+// The input line is a .code or .play entry with a file name and an optional HLfoo marker on the end.
+// Anything between the file and HL (if any) is an address expression, which we treat as a string here.
+// We pick off the HL first, for easy parsing.
+var (
+ highlightRE = regexp.MustCompile(`\s+HL([a-zA-Z0-9_]+)?$`)
+ hlCommentRE = regexp.MustCompile(`(.+) // HL(.*)$`)
+ codeRE = regexp.MustCompile(`\.(code|play)\s+((?:(?:-edit|-numbers)\s+)*)([^\s]+)(?:\s+(.*))?$`)
+)
+
+// parseCode parses a code present directive. Its syntax:
+// .code [-numbers] [-edit] [address] [highlight]
+// The directive may also be ".play" if the snippet is executable.
+func parseCode(ctx *Context, sourceFile string, sourceLine int, cmd string) (Elem, error) {
+ cmd = strings.TrimSpace(cmd)
+
+ // Pull off the HL, if any, from the end of the input line.
+ highlight := ""
+ if hl := highlightRE.FindStringSubmatchIndex(cmd); len(hl) == 4 {
+ highlight = cmd[hl[2]:hl[3]]
+ cmd = cmd[:hl[2]-2]
+ }
+
+ // Parse the remaining command line.
+ // Arguments:
+ // args[0]: whole match
+ // args[1]: .code/.play
+ // args[2]: flags ("-edit -numbers")
+ // args[3]: file name
+ // args[4]: optional address
+ args := codeRE.FindStringSubmatch(cmd)
+ if len(args) != 5 {
+ return nil, fmt.Errorf("%s:%d: syntax error for .code/.play invocation", sourceFile, sourceLine)
+ }
+ command, flags, file, addr := args[1], args[2], args[3], strings.TrimSpace(args[4])
+ play := command == "play" && PlayEnabled
+
+ // Read in code file and (optionally) match address.
+ filename := filepath.Join(filepath.Dir(sourceFile), file)
+ textBytes, err := ctx.ReadFile(filename)
+ if err != nil {
+ return nil, fmt.Errorf("%s:%d: %v", sourceFile, sourceLine, err)
+ }
+ lo, hi, err := addrToByteRange(addr, 0, textBytes)
+ if err != nil {
+ return nil, fmt.Errorf("%s:%d: %v", sourceFile, sourceLine, err)
+ }
+
+ // Acme pattern matches can stop mid-line,
+ // so run to end of line in both directions if not at line start/end.
+ for lo > 0 && textBytes[lo-1] != '\n' {
+ lo--
+ }
+ if hi > 0 {
+ for hi < len(textBytes) && textBytes[hi-1] != '\n' {
+ hi++
+ }
+ }
+
+ lines := codeLines(textBytes, lo, hi)
+
+ data := &codeTemplateData{
+ Lines: formatLines(lines, highlight),
+ Edit: strings.Contains(flags, "-edit"),
+ Numbers: strings.Contains(flags, "-numbers"),
+ }
+
+ // Include before and after in a hidden span for playground code.
+ if play {
+ data.Prefix = textBytes[:lo]
+ data.Suffix = textBytes[hi:]
+ }
+
+ var buf bytes.Buffer
+ if err := codeTemplate.Execute(&buf, data); err != nil {
+ return nil, err
+ }
+ return Code{
+ Text: template.HTML(buf.String()),
+ Play: play,
+ FileName: filepath.Base(filename),
+ Ext: filepath.Ext(filename),
+ Raw: rawCode(lines),
+ }, nil
+}
+
+// formatLines returns a new slice of codeLine with the given lines
+// replacing tabs with spaces and adding highlighting where needed.
+func formatLines(lines []codeLine, highlight string) []codeLine {
+ formatted := make([]codeLine, len(lines))
+ for i, line := range lines {
+ // Replace tabs with spaces, which work better in HTML.
+ line.L = strings.Replace(line.L, "\t", " ", -1)
+
+ // Highlight lines that end with "// HL[highlight]"
+ // and strip the magic comment.
+ if m := hlCommentRE.FindStringSubmatch(line.L); m != nil {
+ line.L = m[1]
+ line.HL = m[2] == highlight
+ }
+
+ formatted[i] = line
+ }
+ return formatted
+}
+
+// rawCode returns the code represented by the given codeLines without any kind
+// of formatting.
+func rawCode(lines []codeLine) []byte {
+ b := new(bytes.Buffer)
+ for _, line := range lines {
+ b.WriteString(line.L)
+ b.WriteByte('\n')
+ }
+ return b.Bytes()
+}
+
+type codeTemplateData struct {
+ Lines []codeLine
+ Prefix, Suffix []byte
+ Edit, Numbers bool
+}
+
+var leadingSpaceRE = regexp.MustCompile(`^[ \t]*`)
+
+var codeTemplate = template.Must(template.New("code").Funcs(template.FuncMap{
+ "trimSpace": strings.TrimSpace,
+ "leadingSpace": leadingSpaceRE.FindString,
+}).Parse(codeTemplateHTML))
+
+const codeTemplateHTML = `
+{{with .Prefix}}{{printf "%s" .}} {{end}}
+
+{{/*
+ */}}{{range .Lines}}{{/*
+ */}}{{if .HL}}{{leadingSpace .L}}{{trimSpace .L}} {{/*
+ */}}{{else}}{{.L}}{{end}}{{/*
+*/}}
+{{end}}
+
+{{with .Suffix}}{{printf "%s" .}} {{end}}
+`
+
+// codeLine represents a line of code extracted from a source file.
+type codeLine struct {
+ L string // The line of code.
+ N int // The line number from the source file.
+ HL bool // Whether the line should be highlighted.
+}
+
+// codeLines takes a source file and returns the lines that
+// span the byte range specified by start and end.
+// It discards lines that end in "OMIT".
+func codeLines(src []byte, start, end int) (lines []codeLine) {
+ startLine := 1
+ for i, b := range src {
+ if i == start {
+ break
+ }
+ if b == '\n' {
+ startLine++
+ }
+ }
+ s := bufio.NewScanner(bytes.NewReader(src[start:end]))
+ for n := startLine; s.Scan(); n++ {
+ l := s.Text()
+ if strings.HasSuffix(l, "OMIT") {
+ continue
+ }
+ lines = append(lines, codeLine{L: l, N: n})
+ }
+ // Trim leading and trailing blank lines.
+ for len(lines) > 0 && len(lines[0].L) == 0 {
+ lines = lines[1:]
+ }
+ for len(lines) > 0 && len(lines[len(lines)-1].L) == 0 {
+ lines = lines[:len(lines)-1]
+ }
+ return
+}
+
+func parseArgs(name string, line int, args []string) (res []interface{}, err error) {
+ res = make([]interface{}, len(args))
+ for i, v := range args {
+ if len(v) == 0 {
+ return nil, fmt.Errorf("%s:%d bad code argument %q", name, line, v)
+ }
+ switch v[0] {
+ case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
+ n, err := strconv.Atoi(v)
+ if err != nil {
+ return nil, fmt.Errorf("%s:%d bad code argument %q", name, line, v)
+ }
+ res[i] = n
+ case '/':
+ if len(v) < 2 || v[len(v)-1] != '/' {
+ return nil, fmt.Errorf("%s:%d bad code argument %q", name, line, v)
+ }
+ res[i] = v
+ case '$':
+ res[i] = "$"
+ case '_':
+ if len(v) == 1 {
+ // Do nothing; "_" indicates an intentionally empty parameter.
+ break
+ }
+ fallthrough
+ default:
+ return nil, fmt.Errorf("%s:%d bad code argument %q", name, line, v)
+ }
+ }
+ return
+}
+
+// parseArg returns the integer or string value of the argument and tells which it is.
+func parseArg(arg interface{}, max int) (ival int, sval string, isInt bool, err error) {
+ switch n := arg.(type) {
+ case int:
+ if n <= 0 || n > max {
+ return 0, "", false, fmt.Errorf("%d is out of range", n)
+ }
+ return n, "", true, nil
+ case string:
+ return 0, n, false, nil
+ }
+ return 0, "", false, fmt.Errorf("unrecognized argument %v type %T", arg, arg)
+}
+
+// match identifies the input line that matches the pattern in a code invocation.
+// If start>0, match lines starting there rather than at the beginning.
+// The return value is 1-indexed.
+func match(file string, start int, lines []string, pattern string) (int, error) {
+ // $ matches the end of the file.
+ if pattern == "$" {
+ if len(lines) == 0 {
+ return 0, fmt.Errorf("%q: empty file", file)
+ }
+ return len(lines), nil
+ }
+ // /regexp/ matches the line that matches the regexp.
+ if len(pattern) > 2 && pattern[0] == '/' && pattern[len(pattern)-1] == '/' {
+ re, err := regexp.Compile(pattern[1 : len(pattern)-1])
+ if err != nil {
+ return 0, err
+ }
+ for i := start; i < len(lines); i++ {
+ if re.MatchString(lines[i]) {
+ return i + 1, nil
+ }
+ }
+ return 0, fmt.Errorf("%s: no match for %#q", file, pattern)
+ }
+ return 0, fmt.Errorf("unrecognized pattern: %q", pattern)
+}
diff --git a/vendor/golang.org/x/tools/present/doc.go b/vendor/golang.org/x/tools/present/doc.go
new file mode 100644
index 0000000..584e0c1
--- /dev/null
+++ b/vendor/golang.org/x/tools/present/doc.go
@@ -0,0 +1,205 @@
+// Copyright 2011 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+/*
+The present file format
+
+Present files have the following format. The first non-blank non-comment
+line is the title, so the header looks like
+
+ Title of document
+ Subtitle of document
+ 15:04 2 Jan 2006
+ Tags: foo, bar, baz
+
+ Author Name
+ Job title, Company
+ joe@example.com
+ http://url/
+ @twitter_name
+
+The subtitle, date, and tags lines are optional.
+
+The date line may be written without a time:
+ 2 Jan 2006
+In this case, the time will be interpreted as 10am UTC on that date.
+
+The tags line is a comma-separated list of tags that may be used to categorize
+the document.
+
+The author section may contain a mixture of text, twitter names, and links.
+For slide presentations, only the plain text lines will be displayed on the
+first slide.
+
+Multiple presenters may be specified, separated by a blank line.
+
+After that come slides/sections, each after a blank line:
+
+ * Title of slide or section (must have asterisk)
+
+ Some Text
+
+ ** Subsection
+
+ - bullets
+ - more bullets
+ - a bullet with
+
+ *** Sub-subsection
+
+ Some More text
+
+ Preformatted text
+ is indented (however you like)
+
+ Further Text, including invocations like:
+
+ .code x.go /^func main/,/^}/
+ .play y.go
+ .image image.jpg
+ .iframe http://foo
+ .link http://foo label
+ .html file.html
+ .caption _Gopher_ by [[http://www.reneefrench.com][Renée French]]
+
+ Again, more text
+
+Blank lines are OK (not mandatory) after the title and after the
+text. Text, bullets, and .code etc. are all optional; title is
+not.
+
+Lines starting with # in column 1 are commentary.
+
+Fonts:
+
+Within the input for plain text or lists, text bracketed by font
+markers will be presented in italic, bold, or program font.
+Marker characters are _ (italic), * (bold) and ` (program font).
+Unmatched markers appear as plain text.
+Within marked text, a single marker character becomes a space
+and a doubled single marker quotes the marker character.
+
+ _italic_
+ *bold*
+ `program`
+ _this_is_all_italic_
+ _Why_use_scoped__ptr_? Use plain ***ptr* instead.
+
+Inline links:
+
+Links can be included in any text with the form [[url][label]], or
+[[url]] to use the URL itself as the label.
+
+Functions:
+
+A number of template functions are available through invocations
+in the input text. Each such invocation contains a period as the
+first character on the line, followed immediately by the name of
+the function, followed by any arguments. A typical invocation might
+be
+ .play demo.go /^func show/,/^}/
+(except that the ".play" must be at the beginning of the line and
+not be indented like this.)
+
+Here follows a description of the functions:
+
+code:
+
+Injects program source into the output by extracting code from files
+and injecting them as HTML-escaped blocks. The argument is
+a file name followed by an optional address that specifies what
+section of the file to display. The address syntax is similar in
+its simplest form to that of ed, but comes from sam and is more
+general. See
+ http://plan9.bell-labs.com/sys/doc/sam/sam.html Table II
+for full details. The displayed block is always rounded out to a
+full line at both ends.
+
+If no pattern is present, the entire file is displayed.
+
+Any line in the program that ends with the four characters
+ OMIT
+is deleted from the source before inclusion, making it easy
+to write things like
+ .code test.go /START OMIT/,/END OMIT/
+to find snippets like this
+ tedious_code = boring_function()
+ // START OMIT
+ interesting_code = fascinating_function()
+ // END OMIT
+and see only this:
+ interesting_code = fascinating_function()
+
+Also, inside the displayed text a line that ends
+ // HL
+will be highlighted in the display; the 'h' key in the browser will
+toggle extra emphasis of any highlighted lines. A highlighting mark
+may have a suffix word, such as
+ // HLxxx
+Such highlights are enabled only if the code invocation ends with
+"HL" followed by the word:
+ .code test.go /^type Foo/,/^}/ HLxxx
+
+The .code function may take one or more flags immediately preceding
+the filename. This command shows test.go in an editable text area:
+ .code -edit test.go
+This command shows test.go with line numbers:
+ .code -numbers test.go
+
+play:
+
+The function "play" is the same as "code" but puts a button
+on the displayed source so the program can be run from the browser.
+Although only the selected text is shown, all the source is included
+in the HTML output so it can be presented to the compiler.
+
+link:
+
+Create a hyperlink. The syntax is 1 or 2 space-separated arguments.
+The first argument is always the HTTP URL. If there is a second
+argument, it is the text label to display for this link.
+
+ .link http://golang.org golang.org
+
+image:
+
+The template uses the function "image" to inject picture files.
+
+The syntax is simple: 1 or 3 space-separated arguments.
+The first argument is always the file name.
+If there are more arguments, they are the height and width;
+both must be present, or substituted with an underscore.
+Replacing a dimension argument with the underscore parameter
+preserves the aspect ratio of the image when scaling.
+
+ .image images/betsy.jpg 100 200
+
+ .image images/janet.jpg _ 300
+
+
+caption:
+
+The template uses the function "caption" to inject figure captions.
+
+The text after ".caption" is embedded in a figcaption element after
+processing styling and links as in standard text lines.
+
+ .caption _Gopher_ by [[http://www.reneefrench.com][Renée French]]
+
+iframe:
+
+The function "iframe" injects iframes (pages inside pages).
+Its syntax is the same as that of image.
+
+html:
+
+The function html includes the contents of the specified file as
+unescaped HTML. This is useful for including custom HTML elements
+that cannot be created using only the slide format.
+It is your responsibilty to make sure the included HTML is valid and safe.
+
+ .html file.html
+
+*/
+package present // import "golang.org/x/tools/present"
diff --git a/vendor/golang.org/x/tools/present/html.go b/vendor/golang.org/x/tools/present/html.go
new file mode 100644
index 0000000..cca90ef
--- /dev/null
+++ b/vendor/golang.org/x/tools/present/html.go
@@ -0,0 +1,31 @@
+package present
+
+import (
+ "errors"
+ "html/template"
+ "path/filepath"
+ "strings"
+)
+
+func init() {
+ Register("html", parseHTML)
+}
+
+func parseHTML(ctx *Context, fileName string, lineno int, text string) (Elem, error) {
+ p := strings.Fields(text)
+ if len(p) != 2 {
+ return nil, errors.New("invalid .html args")
+ }
+ name := filepath.Join(filepath.Dir(fileName), p[1])
+ b, err := ctx.ReadFile(name)
+ if err != nil {
+ return nil, err
+ }
+ return HTML{template.HTML(b)}, nil
+}
+
+type HTML struct {
+ template.HTML
+}
+
+func (s HTML) TemplateName() string { return "html" }
diff --git a/vendor/golang.org/x/tools/present/iframe.go b/vendor/golang.org/x/tools/present/iframe.go
new file mode 100644
index 0000000..2f3c5e5
--- /dev/null
+++ b/vendor/golang.org/x/tools/present/iframe.go
@@ -0,0 +1,45 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package present
+
+import (
+ "fmt"
+ "strings"
+)
+
+func init() {
+ Register("iframe", parseIframe)
+}
+
+type Iframe struct {
+ URL string
+ Width int
+ Height int
+}
+
+func (i Iframe) TemplateName() string { return "iframe" }
+
+func parseIframe(ctx *Context, fileName string, lineno int, text string) (Elem, error) {
+ args := strings.Fields(text)
+ i := Iframe{URL: args[1]}
+ a, err := parseArgs(fileName, lineno, args[2:])
+ if err != nil {
+ return nil, err
+ }
+ switch len(a) {
+ case 0:
+ // no size parameters
+ case 2:
+ if v, ok := a[0].(int); ok {
+ i.Height = v
+ }
+ if v, ok := a[1].(int); ok {
+ i.Width = v
+ }
+ default:
+ return nil, fmt.Errorf("incorrect image invocation: %q", text)
+ }
+ return i, nil
+}
diff --git a/vendor/golang.org/x/tools/present/image.go b/vendor/golang.org/x/tools/present/image.go
new file mode 100644
index 0000000..cfa2af9
--- /dev/null
+++ b/vendor/golang.org/x/tools/present/image.go
@@ -0,0 +1,50 @@
+// Copyright 2012 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package present
+
+import (
+ "fmt"
+ "strings"
+)
+
+func init() {
+ Register("image", parseImage)
+}
+
+type Image struct {
+ URL string
+ Width int
+ Height int
+}
+
+func (i Image) TemplateName() string { return "image" }
+
+func parseImage(ctx *Context, fileName string, lineno int, text string) (Elem, error) {
+ args := strings.Fields(text)
+ img := Image{URL: args[1]}
+ a, err := parseArgs(fileName, lineno, args[2:])
+ if err != nil {
+ return nil, err
+ }
+ switch len(a) {
+ case 0:
+ // no size parameters
+ case 2:
+ // If a parameter is empty (underscore) or invalid
+ // leave the field set to zero. The "image" action
+ // template will then omit that img tag attribute and
+ // the browser will calculate the value to preserve
+ // the aspect ratio.
+ if v, ok := a[0].(int); ok {
+ img.Height = v
+ }
+ if v, ok := a[1].(int); ok {
+ img.Width = v
+ }
+ default:
+ return nil, fmt.Errorf("incorrect image invocation: %q", text)
+ }
+ return img, nil
+}
diff --git a/vendor/golang.org/x/tools/present/link.go b/vendor/golang.org/x/tools/present/link.go
new file mode 100644
index 0000000..6b0968f
--- /dev/null
+++ b/vendor/golang.org/x/tools/present/link.go
@@ -0,0 +1,97 @@
+// Copyright 2012 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package present
+
+import (
+ "fmt"
+ "log"
+ "net/url"
+ "strings"
+)
+
+func init() {
+ Register("link", parseLink)
+}
+
+type Link struct {
+ URL *url.URL
+ Label string
+}
+
+func (l Link) TemplateName() string { return "link" }
+
+func parseLink(ctx *Context, fileName string, lineno int, text string) (Elem, error) {
+ args := strings.Fields(text)
+ url, err := url.Parse(args[1])
+ if err != nil {
+ return nil, err
+ }
+ label := ""
+ if len(args) > 2 {
+ label = strings.Join(args[2:], " ")
+ } else {
+ scheme := url.Scheme + "://"
+ if url.Scheme == "mailto" {
+ scheme = "mailto:"
+ }
+ label = strings.Replace(url.String(), scheme, "", 1)
+ }
+ return Link{url, label}, nil
+}
+
+func renderLink(href, text string) string {
+ text = font(text)
+ if text == "" {
+ text = href
+ }
+ // Open links in new window only when their url is absolute.
+ target := "_blank"
+ if u, err := url.Parse(href); err != nil {
+ log.Println("rendernLink parsing url:", err)
+ } else if !u.IsAbs() || u.Scheme == "javascript" {
+ target = "_self"
+ }
+
+ return fmt.Sprintf(`%s `, href, target, text)
+}
+
+// parseInlineLink parses an inline link at the start of s, and returns
+// a rendered HTML link and the total length of the raw inline link.
+// If no inline link is present, it returns all zeroes.
+func parseInlineLink(s string) (link string, length int) {
+ if !strings.HasPrefix(s, "[[") {
+ return
+ }
+ end := strings.Index(s, "]]")
+ if end == -1 {
+ return
+ }
+ urlEnd := strings.Index(s, "]")
+ rawURL := s[2:urlEnd]
+ const badURLChars = `<>"{}|\^[] ` + "`" // per RFC2396 section 2.4.3
+ if strings.ContainsAny(rawURL, badURLChars) {
+ return
+ }
+ if urlEnd == end {
+ simpleUrl := ""
+ url, err := url.Parse(rawURL)
+ if err == nil {
+ // If the URL is http://foo.com, drop the http://
+ // In other words, render [[http://golang.org]] as:
+ // golang.org
+ if strings.HasPrefix(rawURL, url.Scheme+"://") {
+ simpleUrl = strings.TrimPrefix(rawURL, url.Scheme+"://")
+ } else if strings.HasPrefix(rawURL, url.Scheme+":") {
+ simpleUrl = strings.TrimPrefix(rawURL, url.Scheme+":")
+ }
+ }
+ return renderLink(rawURL, simpleUrl), end + 2
+ }
+ if s[urlEnd:urlEnd+2] != "][" {
+ return
+ }
+ text := s[urlEnd+2 : end]
+ return renderLink(rawURL, text), end + 2
+}
diff --git a/vendor/golang.org/x/tools/present/parse.go b/vendor/golang.org/x/tools/present/parse.go
new file mode 100644
index 0000000..449d5ed
--- /dev/null
+++ b/vendor/golang.org/x/tools/present/parse.go
@@ -0,0 +1,505 @@
+// Copyright 2011 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package present
+
+import (
+ "bufio"
+ "bytes"
+ "errors"
+ "fmt"
+ "html/template"
+ "io"
+ "io/ioutil"
+ "log"
+ "net/url"
+ "regexp"
+ "strings"
+ "time"
+ "unicode"
+ "unicode/utf8"
+)
+
+var (
+ parsers = make(map[string]ParseFunc)
+ funcs = template.FuncMap{}
+)
+
+// Template returns an empty template with the action functions in its FuncMap.
+func Template() *template.Template {
+ return template.New("").Funcs(funcs)
+}
+
+// Render renders the doc to the given writer using the provided template.
+func (d *Doc) Render(w io.Writer, t *template.Template) error {
+ data := struct {
+ *Doc
+ Template *template.Template
+ PlayEnabled bool
+ }{d, t, PlayEnabled}
+ return t.ExecuteTemplate(w, "root", data)
+}
+
+// Render renders the section to the given writer using the provided template.
+func (s *Section) Render(w io.Writer, t *template.Template) error {
+ data := struct {
+ *Section
+ Template *template.Template
+ PlayEnabled bool
+ }{s, t, PlayEnabled}
+ return t.ExecuteTemplate(w, "section", data)
+}
+
+type ParseFunc func(ctx *Context, fileName string, lineNumber int, inputLine string) (Elem, error)
+
+// Register binds the named action, which does not begin with a period, to the
+// specified parser to be invoked when the name, with a period, appears in the
+// present input text.
+func Register(name string, parser ParseFunc) {
+ if len(name) == 0 || name[0] == ';' {
+ panic("bad name in Register: " + name)
+ }
+ parsers["."+name] = parser
+}
+
+// Doc represents an entire document.
+type Doc struct {
+ Title string
+ Subtitle string
+ Time time.Time
+ Authors []Author
+ Sections []Section
+ Tags []string
+}
+
+// Author represents the person who wrote and/or is presenting the document.
+type Author struct {
+ Elem []Elem
+}
+
+// TextElem returns the first text elements of the author details.
+// This is used to display the author' name, job title, and company
+// without the contact details.
+func (p *Author) TextElem() (elems []Elem) {
+ for _, el := range p.Elem {
+ if _, ok := el.(Text); !ok {
+ break
+ }
+ elems = append(elems, el)
+ }
+ return
+}
+
+// Section represents a section of a document (such as a presentation slide)
+// comprising a title and a list of elements.
+type Section struct {
+ Number []int
+ Title string
+ Elem []Elem
+}
+
+func (s Section) Sections() (sections []Section) {
+ for _, e := range s.Elem {
+ if section, ok := e.(Section); ok {
+ sections = append(sections, section)
+ }
+ }
+ return
+}
+
+// Level returns the level of the given section.
+// The document title is level 1, main section 2, etc.
+func (s Section) Level() int {
+ return len(s.Number) + 1
+}
+
+// FormattedNumber returns a string containing the concatenation of the
+// numbers identifying a Section.
+func (s Section) FormattedNumber() string {
+ b := &bytes.Buffer{}
+ for _, n := range s.Number {
+ fmt.Fprintf(b, "%v.", n)
+ }
+ return b.String()
+}
+
+func (s Section) TemplateName() string { return "section" }
+
+// Elem defines the interface for a present element. That is, something that
+// can provide the name of the template used to render the element.
+type Elem interface {
+ TemplateName() string
+}
+
+// renderElem implements the elem template function, used to render
+// sub-templates.
+func renderElem(t *template.Template, e Elem) (template.HTML, error) {
+ var data interface{} = e
+ if s, ok := e.(Section); ok {
+ data = struct {
+ Section
+ Template *template.Template
+ }{s, t}
+ }
+ return execTemplate(t, e.TemplateName(), data)
+}
+
+func init() {
+ funcs["elem"] = renderElem
+}
+
+// execTemplate is a helper to execute a template and return the output as a
+// template.HTML value.
+func execTemplate(t *template.Template, name string, data interface{}) (template.HTML, error) {
+ b := new(bytes.Buffer)
+ err := t.ExecuteTemplate(b, name, data)
+ if err != nil {
+ return "", err
+ }
+ return template.HTML(b.String()), nil
+}
+
+// Text represents an optionally preformatted paragraph.
+type Text struct {
+ Lines []string
+ Pre bool
+}
+
+func (t Text) TemplateName() string { return "text" }
+
+// List represents a bulleted list.
+type List struct {
+ Bullet []string
+}
+
+func (l List) TemplateName() string { return "list" }
+
+// Lines is a helper for parsing line-based input.
+type Lines struct {
+ line int // 0 indexed, so has 1-indexed number of last line returned
+ text []string
+}
+
+func readLines(r io.Reader) (*Lines, error) {
+ var lines []string
+ s := bufio.NewScanner(r)
+ for s.Scan() {
+ lines = append(lines, s.Text())
+ }
+ if err := s.Err(); err != nil {
+ return nil, err
+ }
+ return &Lines{0, lines}, nil
+}
+
+func (l *Lines) next() (text string, ok bool) {
+ for {
+ current := l.line
+ l.line++
+ if current >= len(l.text) {
+ return "", false
+ }
+ text = l.text[current]
+ // Lines starting with # are comments.
+ if len(text) == 0 || text[0] != '#' {
+ ok = true
+ break
+ }
+ }
+ return
+}
+
+func (l *Lines) back() {
+ l.line--
+}
+
+func (l *Lines) nextNonEmpty() (text string, ok bool) {
+ for {
+ text, ok = l.next()
+ if !ok {
+ return
+ }
+ if len(text) > 0 {
+ break
+ }
+ }
+ return
+}
+
+// A Context specifies the supporting context for parsing a presentation.
+type Context struct {
+ // ReadFile reads the file named by filename and returns the contents.
+ ReadFile func(filename string) ([]byte, error)
+}
+
+// ParseMode represents flags for the Parse function.
+type ParseMode int
+
+const (
+ // If set, parse only the title and subtitle.
+ TitlesOnly ParseMode = 1
+)
+
+// Parse parses a document from r.
+func (ctx *Context) Parse(r io.Reader, name string, mode ParseMode) (*Doc, error) {
+ doc := new(Doc)
+ lines, err := readLines(r)
+ if err != nil {
+ return nil, err
+ }
+ err = parseHeader(doc, lines)
+ if err != nil {
+ return nil, err
+ }
+ if mode&TitlesOnly != 0 {
+ return doc, nil
+ }
+ // Authors
+ if doc.Authors, err = parseAuthors(lines); err != nil {
+ return nil, err
+ }
+ // Sections
+ if doc.Sections, err = parseSections(ctx, name, lines, []int{}, doc); err != nil {
+ return nil, err
+ }
+ return doc, nil
+}
+
+// Parse parses a document from r. Parse reads assets used by the presentation
+// from the file system using ioutil.ReadFile.
+func Parse(r io.Reader, name string, mode ParseMode) (*Doc, error) {
+ ctx := Context{ReadFile: ioutil.ReadFile}
+ return ctx.Parse(r, name, mode)
+}
+
+// isHeading matches any section heading.
+var isHeading = regexp.MustCompile(`^\*+ `)
+
+// lesserHeading returns true if text is a heading of a lesser or equal level
+// than that denoted by prefix.
+func lesserHeading(text, prefix string) bool {
+ return isHeading.MatchString(text) && !strings.HasPrefix(text, prefix+"*")
+}
+
+// parseSections parses Sections from lines for the section level indicated by
+// number (a nil number indicates the top level).
+func parseSections(ctx *Context, name string, lines *Lines, number []int, doc *Doc) ([]Section, error) {
+ var sections []Section
+ for i := 1; ; i++ {
+ // Next non-empty line is title.
+ text, ok := lines.nextNonEmpty()
+ for ok && text == "" {
+ text, ok = lines.next()
+ }
+ if !ok {
+ break
+ }
+ prefix := strings.Repeat("*", len(number)+1)
+ if !strings.HasPrefix(text, prefix+" ") {
+ lines.back()
+ break
+ }
+ section := Section{
+ Number: append(append([]int{}, number...), i),
+ Title: text[len(prefix)+1:],
+ }
+ text, ok = lines.nextNonEmpty()
+ for ok && !lesserHeading(text, prefix) {
+ var e Elem
+ r, _ := utf8.DecodeRuneInString(text)
+ switch {
+ case unicode.IsSpace(r):
+ i := strings.IndexFunc(text, func(r rune) bool {
+ return !unicode.IsSpace(r)
+ })
+ if i < 0 {
+ break
+ }
+ indent := text[:i]
+ var s []string
+ for ok && (strings.HasPrefix(text, indent) || text == "") {
+ if text != "" {
+ text = text[i:]
+ }
+ s = append(s, text)
+ text, ok = lines.next()
+ }
+ lines.back()
+ pre := strings.Join(s, "\n")
+ pre = strings.Replace(pre, "\t", " ", -1) // browsers treat tabs badly
+ pre = strings.TrimRightFunc(pre, unicode.IsSpace)
+ e = Text{Lines: []string{pre}, Pre: true}
+ case strings.HasPrefix(text, "- "):
+ var b []string
+ for ok && strings.HasPrefix(text, "- ") {
+ b = append(b, text[2:])
+ text, ok = lines.next()
+ }
+ lines.back()
+ e = List{Bullet: b}
+ case strings.HasPrefix(text, prefix+"* "):
+ lines.back()
+ subsecs, err := parseSections(ctx, name, lines, section.Number, doc)
+ if err != nil {
+ return nil, err
+ }
+ for _, ss := range subsecs {
+ section.Elem = append(section.Elem, ss)
+ }
+ case strings.HasPrefix(text, "."):
+ args := strings.Fields(text)
+ parser := parsers[args[0]]
+ if parser == nil {
+ return nil, fmt.Errorf("%s:%d: unknown command %q\n", name, lines.line, text)
+ }
+ t, err := parser(ctx, name, lines.line, text)
+ if err != nil {
+ return nil, err
+ }
+ e = t
+ default:
+ var l []string
+ for ok && strings.TrimSpace(text) != "" {
+ if text[0] == '.' { // Command breaks text block.
+ break
+ }
+ if strings.HasPrefix(text, `\.`) { // Backslash escapes initial period.
+ text = text[1:]
+ }
+ l = append(l, text)
+ text, ok = lines.next()
+ }
+ if len(l) > 0 {
+ e = Text{Lines: l}
+ }
+ }
+ if e != nil {
+ section.Elem = append(section.Elem, e)
+ }
+ text, ok = lines.nextNonEmpty()
+ }
+ if isHeading.MatchString(text) {
+ lines.back()
+ }
+ sections = append(sections, section)
+ }
+ return sections, nil
+}
+
+func parseHeader(doc *Doc, lines *Lines) error {
+ var ok bool
+ // First non-empty line starts header.
+ doc.Title, ok = lines.nextNonEmpty()
+ if !ok {
+ return errors.New("unexpected EOF; expected title")
+ }
+ for {
+ text, ok := lines.next()
+ if !ok {
+ return errors.New("unexpected EOF")
+ }
+ if text == "" {
+ break
+ }
+ const tagPrefix = "Tags:"
+ if strings.HasPrefix(text, tagPrefix) {
+ tags := strings.Split(text[len(tagPrefix):], ",")
+ for i := range tags {
+ tags[i] = strings.TrimSpace(tags[i])
+ }
+ doc.Tags = append(doc.Tags, tags...)
+ } else if t, ok := parseTime(text); ok {
+ doc.Time = t
+ } else if doc.Subtitle == "" {
+ doc.Subtitle = text
+ } else {
+ return fmt.Errorf("unexpected header line: %q", text)
+ }
+ }
+ return nil
+}
+
+func parseAuthors(lines *Lines) (authors []Author, err error) {
+ // This grammar demarcates authors with blanks.
+
+ // Skip blank lines.
+ if _, ok := lines.nextNonEmpty(); !ok {
+ return nil, errors.New("unexpected EOF")
+ }
+ lines.back()
+
+ var a *Author
+ for {
+ text, ok := lines.next()
+ if !ok {
+ return nil, errors.New("unexpected EOF")
+ }
+
+ // If we find a section heading, we're done.
+ if strings.HasPrefix(text, "* ") {
+ lines.back()
+ break
+ }
+
+ // If we encounter a blank we're done with this author.
+ if a != nil && len(text) == 0 {
+ authors = append(authors, *a)
+ a = nil
+ continue
+ }
+ if a == nil {
+ a = new(Author)
+ }
+
+ // Parse the line. Those that
+ // - begin with @ are twitter names,
+ // - contain slashes are links, or
+ // - contain an @ symbol are an email address.
+ // The rest is just text.
+ var el Elem
+ switch {
+ case strings.HasPrefix(text, "@"):
+ el = parseURL("http://twitter.com/" + text[1:])
+ case strings.Contains(text, ":"):
+ el = parseURL(text)
+ case strings.Contains(text, "@"):
+ el = parseURL("mailto:" + text)
+ }
+ if l, ok := el.(Link); ok {
+ l.Label = text
+ el = l
+ }
+ if el == nil {
+ el = Text{Lines: []string{text}}
+ }
+ a.Elem = append(a.Elem, el)
+ }
+ if a != nil {
+ authors = append(authors, *a)
+ }
+ return authors, nil
+}
+
+func parseURL(text string) Elem {
+ u, err := url.Parse(text)
+ if err != nil {
+ log.Printf("Parse(%q): %v", text, err)
+ return nil
+ }
+ return Link{URL: u}
+}
+
+func parseTime(text string) (t time.Time, ok bool) {
+ t, err := time.Parse("15:04 2 Jan 2006", text)
+ if err == nil {
+ return t, true
+ }
+ t, err = time.Parse("2 Jan 2006", text)
+ if err == nil {
+ // at 11am UTC it is the same date everywhere
+ t = t.Add(time.Hour * 11)
+ return t, true
+ }
+ return time.Time{}, false
+}
diff --git a/vendor/golang.org/x/tools/present/style.go b/vendor/golang.org/x/tools/present/style.go
new file mode 100644
index 0000000..1cd240d
--- /dev/null
+++ b/vendor/golang.org/x/tools/present/style.go
@@ -0,0 +1,166 @@
+// Copyright 2012 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package present
+
+import (
+ "bytes"
+ "html"
+ "html/template"
+ "strings"
+ "unicode"
+ "unicode/utf8"
+)
+
+/*
+ Fonts are demarcated by an initial and final char bracketing a
+ space-delimited word, plus possibly some terminal punctuation.
+ The chars are
+ _ for italic
+ * for bold
+ ` (back quote) for fixed width.
+ Inner appearances of the char become spaces. For instance,
+ _this_is_italic_!
+ becomes
+ this is italic !
+*/
+
+func init() {
+ funcs["style"] = Style
+}
+
+// Style returns s with HTML entities escaped and font indicators turned into
+// HTML font tags.
+func Style(s string) template.HTML {
+ return template.HTML(font(html.EscapeString(s)))
+}
+
+// font returns s with font indicators turned into HTML font tags.
+func font(s string) string {
+ if strings.IndexAny(s, "[`_*") == -1 {
+ return s
+ }
+ words := split(s)
+ var b bytes.Buffer
+Word:
+ for w, word := range words {
+ if len(word) < 2 {
+ continue Word
+ }
+ if link, _ := parseInlineLink(word); link != "" {
+ words[w] = link
+ continue Word
+ }
+ const punctuation = `.,;:()!?—–'"`
+ const marker = "_*`"
+ // Initial punctuation is OK but must be peeled off.
+ first := strings.IndexAny(word, marker)
+ if first == -1 {
+ continue Word
+ }
+ // Is the marker prefixed only by punctuation?
+ for _, r := range word[:first] {
+ if !strings.ContainsRune(punctuation, r) {
+ continue Word
+ }
+ }
+ open, word := word[:first], word[first:]
+ char := word[0] // ASCII is OK.
+ close := ""
+ switch char {
+ default:
+ continue Word
+ case '_':
+ open += ""
+ close = " "
+ case '*':
+ open += ""
+ close = " "
+ case '`':
+ open += ""
+ close = "
"
+ }
+ // Terminal punctuation is OK but must be peeled off.
+ last := strings.LastIndex(word, word[:1])
+ if last == 0 {
+ continue Word
+ }
+ head, tail := word[:last+1], word[last+1:]
+ for _, r := range tail {
+ if !strings.ContainsRune(punctuation, r) {
+ continue Word
+ }
+ }
+ b.Reset()
+ b.WriteString(open)
+ var wid int
+ for i := 1; i < len(head)-1; i += wid {
+ var r rune
+ r, wid = utf8.DecodeRuneInString(head[i:])
+ if r != rune(char) {
+ // Ordinary character.
+ b.WriteRune(r)
+ continue
+ }
+ if head[i+1] != char {
+ // Inner char becomes space.
+ b.WriteRune(' ')
+ continue
+ }
+ // Doubled char becomes real char.
+ // Not worth worrying about "_x__".
+ b.WriteByte(char)
+ wid++ // Consumed two chars, both ASCII.
+ }
+ b.WriteString(close) // Write closing tag.
+ b.WriteString(tail) // Restore trailing punctuation.
+ words[w] = b.String()
+ }
+ return strings.Join(words, "")
+}
+
+// split is like strings.Fields but also returns the runs of spaces
+// and treats inline links as distinct words.
+func split(s string) []string {
+ var (
+ words = make([]string, 0, 10)
+ start = 0
+ )
+
+ // appendWord appends the string s[start:end] to the words slice.
+ // If the word contains the beginning of a link, the non-link portion
+ // of the word and the entire link are appended as separate words,
+ // and the start index is advanced to the end of the link.
+ appendWord := func(end int) {
+ if j := strings.Index(s[start:end], "[["); j > -1 {
+ if _, l := parseInlineLink(s[start+j:]); l > 0 {
+ // Append portion before link, if any.
+ if j > 0 {
+ words = append(words, s[start:start+j])
+ }
+ // Append link itself.
+ words = append(words, s[start+j:start+j+l])
+ // Advance start index to end of link.
+ start = start + j + l
+ return
+ }
+ }
+ // No link; just add the word.
+ words = append(words, s[start:end])
+ start = end
+ }
+
+ wasSpace := false
+ for i, r := range s {
+ isSpace := unicode.IsSpace(r)
+ if i > start && isSpace != wasSpace {
+ appendWord(i)
+ }
+ wasSpace = isSpace
+ }
+ for start < len(s) {
+ appendWord(len(s))
+ }
+ return words
+}
diff --git a/vendor/golang.org/x/tools/refactor/importgraph/graph.go b/vendor/golang.org/x/tools/refactor/importgraph/graph.go
new file mode 100644
index 0000000..8ad8014
--- /dev/null
+++ b/vendor/golang.org/x/tools/refactor/importgraph/graph.go
@@ -0,0 +1,128 @@
+// Copyright 2014 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package importgraph computes the forward and reverse import
+// dependency graphs for all packages in a Go workspace.
+package importgraph // import "golang.org/x/tools/refactor/importgraph"
+
+import (
+ "go/build"
+ "sync"
+
+ "golang.org/x/tools/go/buildutil"
+)
+
+// A Graph is an import dependency graph, either forward or reverse.
+//
+// The graph maps each node (a package import path) to the set of its
+// successors in the graph. For a forward graph, this is the set of
+// imported packages (prerequisites); for a reverse graph, it is the set
+// of importing packages (clients).
+//
+type Graph map[string]map[string]bool
+
+func (g Graph) addEdge(from, to string) {
+ edges := g[from]
+ if edges == nil {
+ edges = make(map[string]bool)
+ g[from] = edges
+ }
+ edges[to] = true
+}
+
+// Search returns all the nodes of the graph reachable from
+// any of the specified roots, by following edges forwards.
+// Relationally, this is the reflexive transitive closure.
+func (g Graph) Search(roots ...string) map[string]bool {
+ seen := make(map[string]bool)
+ var visit func(x string)
+ visit = func(x string) {
+ if !seen[x] {
+ seen[x] = true
+ for y := range g[x] {
+ visit(y)
+ }
+ }
+ }
+ for _, root := range roots {
+ visit(root)
+ }
+ return seen
+}
+
+// Build scans the specified Go workspace and builds the forward and
+// reverse import dependency graphs for all its packages.
+// It also returns a mapping from import paths to errors for packages
+// whose loading was not entirely successful.
+// A package may appear in the graph and in the errors mapping.
+func Build(ctxt *build.Context) (forward, reverse Graph, errors map[string]error) {
+ type importEdge struct {
+ from, to string
+ }
+ type pathError struct {
+ path string
+ err error
+ }
+
+ ch := make(chan interface{})
+
+ var wg sync.WaitGroup
+ buildutil.ForEachPackage(ctxt, func(path string, err error) {
+ wg.Add(1)
+ go func() {
+ defer wg.Done()
+ if err != nil {
+ ch <- pathError{path, err}
+ return
+ }
+
+ bp, err := ctxt.Import(path, "", 0)
+ if err != nil {
+ if _, ok := err.(*build.NoGoError); ok {
+ // empty directory is not an error
+ } else {
+ ch <- pathError{path, err}
+ }
+ // Even in error cases, Import usually returns a package.
+ }
+ if bp != nil {
+ for _, imp := range bp.Imports {
+ ch <- importEdge{path, imp}
+ }
+ for _, imp := range bp.TestImports {
+ ch <- importEdge{path, imp}
+ }
+ for _, imp := range bp.XTestImports {
+ ch <- importEdge{path, imp}
+ }
+ }
+ }()
+ })
+ go func() {
+ wg.Wait()
+ close(ch)
+ }()
+
+ forward = make(Graph)
+ reverse = make(Graph)
+
+ for e := range ch {
+ switch e := e.(type) {
+ case pathError:
+ if errors == nil {
+ errors = make(map[string]error)
+ }
+ errors[e.path] = e.err
+
+ case importEdge:
+ if e.to == "C" {
+ continue // "C" is fake
+ }
+ forward.addEdge(e.from, e.to)
+ reverse.addEdge(e.to, e.from)
+ }
+ }
+
+ return forward, reverse, errors
+}
diff --git a/vendor/vendor.json b/vendor/vendor.json
index 8b32140..e4e069b 100644
--- a/vendor/vendor.json
+++ b/vendor/vendor.json
@@ -56,6 +56,84 @@
"revision": "b8348693492ca3791bccfa028f3c19634c11c5b5",
"revisionTime": "2015-04-09T14:25:36Z"
},
+ {
+ "checksumSHA1": "QBwzyczN2ftqO2Vxag5TS79q32E=",
+ "path": "github.com/visualfc/gotools/astview",
+ "revision": "b8348693492ca3791bccfa028f3c19634c11c5b5",
+ "revisionTime": "2015-04-09T14:25:36Z"
+ },
+ {
+ "checksumSHA1": "wqPqP7RGlukrSMzGKVk1tvyWh1o=",
+ "path": "github.com/visualfc/gotools/command",
+ "revision": "b8348693492ca3791bccfa028f3c19634c11c5b5",
+ "revisionTime": "2015-04-09T14:25:36Z"
+ },
+ {
+ "checksumSHA1": "sA2FN414rFhNEgac/a0IyUR8dMA=",
+ "path": "github.com/visualfc/gotools/docview",
+ "revision": "b8348693492ca3791bccfa028f3c19634c11c5b5",
+ "revisionTime": "2015-04-09T14:25:36Z"
+ },
+ {
+ "checksumSHA1": "LvxdwB9kJ77cFS4qiRAh9ts2nz4=",
+ "path": "github.com/visualfc/gotools/finddoc",
+ "revision": "b8348693492ca3791bccfa028f3c19634c11c5b5",
+ "revisionTime": "2015-04-09T14:25:36Z"
+ },
+ {
+ "checksumSHA1": "Sxih6vWVTlJNBdVNeyCkxI213yI=",
+ "path": "github.com/visualfc/gotools/goapi",
+ "revision": "b8348693492ca3791bccfa028f3c19634c11c5b5",
+ "revisionTime": "2015-04-09T14:25:36Z"
+ },
+ {
+ "checksumSHA1": "RLl3M7ywfbgNYR2HfBywCruQz9c=",
+ "path": "github.com/visualfc/gotools/goimports",
+ "revision": "b8348693492ca3791bccfa028f3c19634c11c5b5",
+ "revisionTime": "2015-04-09T14:25:36Z"
+ },
+ {
+ "checksumSHA1": "R6+qmg1mEs4XhihZd5ujddVI+FI=",
+ "path": "github.com/visualfc/gotools/gopresent",
+ "revision": "b8348693492ca3791bccfa028f3c19634c11c5b5",
+ "revisionTime": "2015-04-09T14:25:36Z"
+ },
+ {
+ "checksumSHA1": "kyKBo2ux+HflucDj/qzoko5YoMA=",
+ "path": "github.com/visualfc/gotools/jsonfmt",
+ "revision": "b8348693492ca3791bccfa028f3c19634c11c5b5",
+ "revisionTime": "2015-04-09T14:25:36Z"
+ },
+ {
+ "checksumSHA1": "QldbuEtO8CONs3q/5mkva+CVeNg=",
+ "path": "github.com/visualfc/gotools/oracle",
+ "revision": "b8348693492ca3791bccfa028f3c19634c11c5b5",
+ "revisionTime": "2015-04-09T14:25:36Z"
+ },
+ {
+ "checksumSHA1": "zG4ar8LbudIKQvsfvAgkBSS0k3Q=",
+ "path": "github.com/visualfc/gotools/pkgs",
+ "revision": "b8348693492ca3791bccfa028f3c19634c11c5b5",
+ "revisionTime": "2015-04-09T14:25:36Z"
+ },
+ {
+ "checksumSHA1": "RQoGIbxntMsUZvi4Js0WQqDBDYM=",
+ "path": "github.com/visualfc/gotools/runcmd",
+ "revision": "b8348693492ca3791bccfa028f3c19634c11c5b5",
+ "revisionTime": "2015-04-09T14:25:36Z"
+ },
+ {
+ "checksumSHA1": "q/EpLJHMTcnbxjLGogryQ6IA7kc=",
+ "path": "github.com/visualfc/gotools/stdlib",
+ "revision": "b8348693492ca3791bccfa028f3c19634c11c5b5",
+ "revisionTime": "2015-04-09T14:25:36Z"
+ },
+ {
+ "checksumSHA1": "qlJsyinWZ07PaOyTYyxXOmhDN/I=",
+ "path": "github.com/visualfc/gotools/types",
+ "revision": "b8348693492ca3791bccfa028f3c19634c11c5b5",
+ "revisionTime": "2015-04-09T14:25:36Z"
+ },
{
"checksumSHA1": "xe5hMqClV1HmKZ4GVg4bmSsVRE8=",
"path": "golang.org/x/text/encoding",
@@ -80,6 +158,91 @@
"checksumSHA1": "baiYjEQuZN5kEgOBJPSsZCecTE8=",
"path": "golang.org/x/text/transform",
"revision": ""
+ },
+ {
+ "checksumSHA1": "jbOdG63FTeIVcvLU5E8XsqK53cc=",
+ "path": "golang.org/x/tools/container/intsets",
+ "revision": ""
+ },
+ {
+ "checksumSHA1": "n7QcM+WctJpMsi0d1m4OKSqW4xU=",
+ "path": "golang.org/x/tools/go/ast/astutil",
+ "revision": ""
+ },
+ {
+ "checksumSHA1": "cfJyCvDHk2MgII9NxbJ9j4Cg4to=",
+ "path": "golang.org/x/tools/go/buildutil",
+ "revision": ""
+ },
+ {
+ "checksumSHA1": "9evbcWFxUJMFmnXQ2ja5765p3iE=",
+ "path": "golang.org/x/tools/go/callgraph",
+ "revision": ""
+ },
+ {
+ "checksumSHA1": "p+hK1c9noXGuHDzFlrFQ/uQfzLQ=",
+ "path": "golang.org/x/tools/go/exact",
+ "revision": ""
+ },
+ {
+ "checksumSHA1": "zr2p6hYCvjutYYPnk3PNVPNrPuI=",
+ "path": "golang.org/x/tools/go/gcimporter",
+ "revision": ""
+ },
+ {
+ "checksumSHA1": "+ZIgPrqQHXeHWYpTf/3M7VmTL84=",
+ "path": "golang.org/x/tools/go/loader",
+ "revision": ""
+ },
+ {
+ "checksumSHA1": "6gaftnO6OdA2QQVEEx/A5RgY6vQ=",
+ "path": "golang.org/x/tools/go/pointer",
+ "revision": ""
+ },
+ {
+ "checksumSHA1": "j+qDyyAVmxUvkG5KKqei99v251w=",
+ "path": "golang.org/x/tools/go/ssa",
+ "revision": ""
+ },
+ {
+ "checksumSHA1": "aSefOysJ8dwgHf8wvL0G5HjI/8I=",
+ "path": "golang.org/x/tools/go/ssa/ssautil",
+ "revision": ""
+ },
+ {
+ "checksumSHA1": "kK8f03iydGnjQtYtj+EQHHdPEl4=",
+ "path": "golang.org/x/tools/go/types",
+ "revision": ""
+ },
+ {
+ "checksumSHA1": "CYSGwDAcpYRoeD2y59we+Udk6bY=",
+ "path": "golang.org/x/tools/go/types/typeutil",
+ "revision": ""
+ },
+ {
+ "checksumSHA1": "p3oUXqh8ecOL76mLRB5h/Qlz9lE=",
+ "path": "golang.org/x/tools/imports",
+ "revision": ""
+ },
+ {
+ "checksumSHA1": "wlx0RRzAPyJqCjnAxfnyiyXiqpA=",
+ "path": "golang.org/x/tools/oracle",
+ "revision": ""
+ },
+ {
+ "checksumSHA1": "iSBk1u2q0C8EBuH4XSAWo/nYT84=",
+ "path": "golang.org/x/tools/oracle/serial",
+ "revision": ""
+ },
+ {
+ "checksumSHA1": "AwIfMW+1I1JYu0RB2/4lSp8c5AU=",
+ "path": "golang.org/x/tools/present",
+ "revision": ""
+ },
+ {
+ "checksumSHA1": "iR5P7/QTdZBU43MEh7KrNSyQXhU=",
+ "path": "golang.org/x/tools/refactor/importgraph",
+ "revision": ""
}
],
"rootPath": "github.com/b3log/wide"