summaryrefslogtreecommitdiffstats
path: root/src/cmd/compile/internal/gc/export.go
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-28 13:14:23 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-28 13:14:23 +0000
commit73df946d56c74384511a194dd01dbe099584fd1a (patch)
treefd0bcea490dd81327ddfbb31e215439672c9a068 /src/cmd/compile/internal/gc/export.go
parentInitial commit. (diff)
downloadgolang-1.16-73df946d56c74384511a194dd01dbe099584fd1a.tar.xz
golang-1.16-73df946d56c74384511a194dd01dbe099584fd1a.zip
Adding upstream version 1.16.10.upstream/1.16.10upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src/cmd/compile/internal/gc/export.go')
-rw-r--r--src/cmd/compile/internal/gc/export.go233
1 files changed, 233 insertions, 0 deletions
diff --git a/src/cmd/compile/internal/gc/export.go b/src/cmd/compile/internal/gc/export.go
new file mode 100644
index 0000000..c6917e0
--- /dev/null
+++ b/src/cmd/compile/internal/gc/export.go
@@ -0,0 +1,233 @@
+// 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 gc
+
+import (
+ "cmd/compile/internal/types"
+ "cmd/internal/bio"
+ "cmd/internal/src"
+ "fmt"
+)
+
+var (
+ Debug_export int // if set, print debugging information about export data
+)
+
+func exportf(bout *bio.Writer, format string, args ...interface{}) {
+ fmt.Fprintf(bout, format, args...)
+ if Debug_export != 0 {
+ fmt.Printf(format, args...)
+ }
+}
+
+var asmlist []*Node
+
+// exportsym marks n for export (or reexport).
+func exportsym(n *Node) {
+ if n.Sym.OnExportList() {
+ return
+ }
+ n.Sym.SetOnExportList(true)
+
+ if Debug.E != 0 {
+ fmt.Printf("export symbol %v\n", n.Sym)
+ }
+
+ exportlist = append(exportlist, n)
+}
+
+func initname(s string) bool {
+ return s == "init"
+}
+
+func autoexport(n *Node, ctxt Class) {
+ if n.Sym.Pkg != localpkg {
+ return
+ }
+ if (ctxt != PEXTERN && ctxt != PFUNC) || dclcontext != PEXTERN {
+ return
+ }
+ if n.Type != nil && n.Type.IsKind(TFUNC) && n.IsMethod() {
+ return
+ }
+
+ if types.IsExported(n.Sym.Name) || initname(n.Sym.Name) {
+ exportsym(n)
+ }
+ if asmhdr != "" && !n.Sym.Asm() {
+ n.Sym.SetAsm(true)
+ asmlist = append(asmlist, n)
+ }
+}
+
+func dumpexport(bout *bio.Writer) {
+ // The linker also looks for the $$ marker - use char after $$ to distinguish format.
+ exportf(bout, "\n$$B\n") // indicate binary export format
+ off := bout.Offset()
+ iexport(bout.Writer)
+ size := bout.Offset() - off
+ exportf(bout, "\n$$\n")
+
+ if Debug_export != 0 {
+ fmt.Printf("BenchmarkExportSize:%s 1 %d bytes\n", myimportpath, size)
+ }
+}
+
+func importsym(ipkg *types.Pkg, s *types.Sym, op Op) *Node {
+ n := asNode(s.PkgDef())
+ if n == nil {
+ // iimport should have created a stub ONONAME
+ // declaration for all imported symbols. The exception
+ // is declarations for Runtimepkg, which are populated
+ // by loadsys instead.
+ if s.Pkg != Runtimepkg {
+ Fatalf("missing ONONAME for %v\n", s)
+ }
+
+ n = dclname(s)
+ s.SetPkgDef(asTypesNode(n))
+ s.Importdef = ipkg
+ }
+ if n.Op != ONONAME && n.Op != op {
+ redeclare(lineno, s, fmt.Sprintf("during import %q", ipkg.Path))
+ }
+ return n
+}
+
+// importtype returns the named type declared by symbol s.
+// If no such type has been declared yet, a forward declaration is returned.
+// ipkg is the package being imported
+func importtype(ipkg *types.Pkg, pos src.XPos, s *types.Sym) *types.Type {
+ n := importsym(ipkg, s, OTYPE)
+ if n.Op != OTYPE {
+ t := types.New(TFORW)
+ t.Sym = s
+ t.Nod = asTypesNode(n)
+
+ n.Op = OTYPE
+ n.Pos = pos
+ n.Type = t
+ n.SetClass(PEXTERN)
+ }
+
+ t := n.Type
+ if t == nil {
+ Fatalf("importtype %v", s)
+ }
+ return t
+}
+
+// importobj declares symbol s as an imported object representable by op.
+// ipkg is the package being imported
+func importobj(ipkg *types.Pkg, pos src.XPos, s *types.Sym, op Op, ctxt Class, t *types.Type) *Node {
+ n := importsym(ipkg, s, op)
+ if n.Op != ONONAME {
+ if n.Op == op && (n.Class() != ctxt || !types.Identical(n.Type, t)) {
+ redeclare(lineno, s, fmt.Sprintf("during import %q", ipkg.Path))
+ }
+ return nil
+ }
+
+ n.Op = op
+ n.Pos = pos
+ n.SetClass(ctxt)
+ if ctxt == PFUNC {
+ n.Sym.SetFunc(true)
+ }
+ n.Type = t
+ return n
+}
+
+// importconst declares symbol s as an imported constant with type t and value val.
+// ipkg is the package being imported
+func importconst(ipkg *types.Pkg, pos src.XPos, s *types.Sym, t *types.Type, val Val) {
+ n := importobj(ipkg, pos, s, OLITERAL, PEXTERN, t)
+ if n == nil { // TODO: Check that value matches.
+ return
+ }
+
+ n.SetVal(val)
+
+ if Debug.E != 0 {
+ fmt.Printf("import const %v %L = %v\n", s, t, val)
+ }
+}
+
+// importfunc declares symbol s as an imported function with type t.
+// ipkg is the package being imported
+func importfunc(ipkg *types.Pkg, pos src.XPos, s *types.Sym, t *types.Type) {
+ n := importobj(ipkg, pos, s, ONAME, PFUNC, t)
+ if n == nil {
+ return
+ }
+
+ n.Func = new(Func)
+ t.SetNname(asTypesNode(n))
+
+ if Debug.E != 0 {
+ fmt.Printf("import func %v%S\n", s, t)
+ }
+}
+
+// importvar declares symbol s as an imported variable with type t.
+// ipkg is the package being imported
+func importvar(ipkg *types.Pkg, pos src.XPos, s *types.Sym, t *types.Type) {
+ n := importobj(ipkg, pos, s, ONAME, PEXTERN, t)
+ if n == nil {
+ return
+ }
+
+ if Debug.E != 0 {
+ fmt.Printf("import var %v %L\n", s, t)
+ }
+}
+
+// importalias declares symbol s as an imported type alias with type t.
+// ipkg is the package being imported
+func importalias(ipkg *types.Pkg, pos src.XPos, s *types.Sym, t *types.Type) {
+ n := importobj(ipkg, pos, s, OTYPE, PEXTERN, t)
+ if n == nil {
+ return
+ }
+
+ if Debug.E != 0 {
+ fmt.Printf("import type %v = %L\n", s, t)
+ }
+}
+
+func dumpasmhdr() {
+ b, err := bio.Create(asmhdr)
+ if err != nil {
+ Fatalf("%v", err)
+ }
+ fmt.Fprintf(b, "// generated by compile -asmhdr from package %s\n\n", localpkg.Name)
+ for _, n := range asmlist {
+ if n.Sym.IsBlank() {
+ continue
+ }
+ switch n.Op {
+ case OLITERAL:
+ t := n.Val().Ctype()
+ if t == CTFLT || t == CTCPLX {
+ break
+ }
+ fmt.Fprintf(b, "#define const_%s %#v\n", n.Sym.Name, n.Val())
+
+ case OTYPE:
+ t := n.Type
+ if !t.IsStruct() || t.StructType().Map != nil || t.IsFuncArgStruct() {
+ break
+ }
+ fmt.Fprintf(b, "#define %s__size %d\n", n.Sym.Name, int(t.Width))
+ for _, f := range t.Fields().Slice() {
+ if !f.Sym.IsBlank() {
+ fmt.Fprintf(b, "#define %s_%s %d\n", n.Sym.Name, f.Sym.Name, int(f.Offset))
+ }
+ }
+ }
+ }
+
+ b.Close()
+}