cl: process all go directives
This commit is contained in:
@@ -187,6 +187,10 @@ func isCgoExternSymbol(f *ssa.Function) bool {
|
|||||||
return isCgoCfunc(name) || isCgoCmacro(name)
|
return isCgoCfunc(name) || isCgoCmacro(name)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func isCgoCfpvar(name string) bool {
|
||||||
|
return strings.HasPrefix(name, "_Cfpvar_")
|
||||||
|
}
|
||||||
|
|
||||||
func isCgoCfunc(name string) bool {
|
func isCgoCfunc(name string) bool {
|
||||||
return strings.HasPrefix(name, "_Cfunc_")
|
return strings.HasPrefix(name, "_Cfunc_")
|
||||||
}
|
}
|
||||||
@@ -1066,7 +1070,9 @@ func processPkg(ctx *context, ret llssa.Package, pkg *ssa.Package) {
|
|||||||
case *ssa.Type:
|
case *ssa.Type:
|
||||||
ctx.compileType(ret, member)
|
ctx.compileType(ret, member)
|
||||||
case *ssa.Global:
|
case *ssa.Global:
|
||||||
ctx.compileGlobal(ret, member)
|
if !isCgoVar(member.Name()) {
|
||||||
|
ctx.compileGlobal(ret, member)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -236,31 +236,43 @@ func (p *context) collectSkip(line string, prefix int) {
|
|||||||
|
|
||||||
func (p *context) initLinknameByDoc(doc *ast.CommentGroup, fullName, inPkgName string, isVar bool) {
|
func (p *context) initLinknameByDoc(doc *ast.CommentGroup, fullName, inPkgName string, isVar bool) {
|
||||||
if doc != nil {
|
if doc != nil {
|
||||||
if n := len(doc.List); n > 0 {
|
for n := len(doc.List) - 1; n >= 0; n-- {
|
||||||
line := doc.List[n-1].Text
|
line := doc.List[n].Text
|
||||||
p.initLinkname(line, func(name string) (_ string, _, ok bool) {
|
found := p.initLinkname(line, func(name string) (_ string, _, ok bool) {
|
||||||
return fullName, isVar, name == inPkgName
|
return fullName, isVar, name == inPkgName
|
||||||
})
|
})
|
||||||
|
if !found {
|
||||||
|
break
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *context) initLinkname(line string, f func(inPkgName string) (fullName string, isVar, ok bool)) {
|
func (p *context) initLinkname(line string, f func(inPkgName string) (fullName string, isVar, ok bool)) bool {
|
||||||
const (
|
const (
|
||||||
linkname = "//go:linkname "
|
linkname = "//go:linkname "
|
||||||
llgolink = "//llgo:link "
|
llgolink = "//llgo:link "
|
||||||
llgolink2 = "// llgo:link "
|
llgolink2 = "// llgo:link "
|
||||||
exportName = "//export "
|
exportName = "//export "
|
||||||
|
directive = "//go:"
|
||||||
)
|
)
|
||||||
if strings.HasPrefix(line, linkname) {
|
if strings.HasPrefix(line, linkname) {
|
||||||
p.initLink(line, len(linkname), f)
|
p.initLink(line, len(linkname), f)
|
||||||
|
return true
|
||||||
} else if strings.HasPrefix(line, llgolink2) {
|
} else if strings.HasPrefix(line, llgolink2) {
|
||||||
p.initLink(line, len(llgolink2), f)
|
p.initLink(line, len(llgolink2), f)
|
||||||
|
return true
|
||||||
} else if strings.HasPrefix(line, llgolink) {
|
} else if strings.HasPrefix(line, llgolink) {
|
||||||
p.initLink(line, len(llgolink), f)
|
p.initLink(line, len(llgolink), f)
|
||||||
|
return true
|
||||||
} else if strings.HasPrefix(line, exportName) {
|
} else if strings.HasPrefix(line, exportName) {
|
||||||
p.initCgoExport(line, len(exportName), f)
|
p.initCgoExport(line, len(exportName), f)
|
||||||
|
return true
|
||||||
|
} else if strings.HasPrefix(line, directive) {
|
||||||
|
// skip unknown annotation but continue to parse the next annotation
|
||||||
|
return true
|
||||||
}
|
}
|
||||||
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *context) initCgoExport(line string, prefix int, f func(inPkgName string) (fullName string, isVar, ok bool)) {
|
func (p *context) initCgoExport(line string, prefix int, f func(inPkgName string) (fullName string, isVar, ok bool)) {
|
||||||
@@ -279,7 +291,7 @@ func (p *context) initLink(line string, prefix int, f func(inPkgName string) (fu
|
|||||||
if isVar || strings.Contains(link, ".") { // eg. C.printf, C.strlen, llgo.cstr
|
if isVar || strings.Contains(link, ".") { // eg. C.printf, C.strlen, llgo.cstr
|
||||||
p.prog.SetLinkname(fullName, link)
|
p.prog.SetLinkname(fullName, link)
|
||||||
} else {
|
} else {
|
||||||
panic(line + ": no specified call convention. eg. //go:linkname Printf C.printf")
|
p.prog.SetLinkname(fullName, "C."+link)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
fmt.Fprintln(os.Stderr, "==>", line)
|
fmt.Fprintln(os.Stderr, "==>", line)
|
||||||
@@ -381,6 +393,7 @@ var cgoIgnoredNames = map[string]none{
|
|||||||
"_Cgo_ptr": {},
|
"_Cgo_ptr": {},
|
||||||
"_Cgo_use": {},
|
"_Cgo_use": {},
|
||||||
"_cgoCheckResult": {},
|
"_cgoCheckResult": {},
|
||||||
|
"cgoCheckResult": {},
|
||||||
}
|
}
|
||||||
|
|
||||||
func cgoIgnored(fnName string) bool {
|
func cgoIgnored(fnName string) bool {
|
||||||
@@ -499,14 +512,17 @@ const (
|
|||||||
|
|
||||||
func (p *context) varName(pkg *types.Package, v *ssa.Global) (vName string, vtype int, define bool) {
|
func (p *context) varName(pkg *types.Package, v *ssa.Global) (vName string, vtype int, define bool) {
|
||||||
name := llssa.FullName(pkg, v.Name())
|
name := llssa.FullName(pkg, v.Name())
|
||||||
if v, ok := p.prog.Linkname(name); ok {
|
// TODO(lijie): need a bettery way to process linkname (maybe alias)
|
||||||
if pos := strings.IndexByte(v, '.'); pos >= 0 {
|
if !isCgoCfpvar(v.Name()) && !isCgoVar(v.Name()) {
|
||||||
if pos == 2 && v[0] == 'p' && v[1] == 'y' {
|
if v, ok := p.prog.Linkname(name); ok {
|
||||||
return v[3:], pyVar, false
|
if pos := strings.IndexByte(v, '.'); pos >= 0 {
|
||||||
|
if pos == 2 && v[0] == 'p' && v[1] == 'y' {
|
||||||
|
return v[3:], pyVar, false
|
||||||
|
}
|
||||||
|
return replaceGoName(v, pos), goVar, false
|
||||||
}
|
}
|
||||||
return replaceGoName(v, pos), goVar, false
|
return v, cVar, false
|
||||||
}
|
}
|
||||||
return v, cVar, false
|
|
||||||
}
|
}
|
||||||
return name, goVar, true
|
return name, goVar, true
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user