-
Notifications
You must be signed in to change notification settings - Fork 11
cl: toFuncType (testcase: _testmockc/type) #708
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,3 @@ | ||
| int sort(void* a, void* b, int elementSize, int count, int (*cmp)(const void*, const void*)); | ||
|
|
||
| void g(void); |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,12 @@ | ||
| package foo | ||
|
|
||
| import ( | ||
| "github.com/goplus/lib/c" | ||
| "unsafe" | ||
| ) | ||
|
|
||
| //go:linkname Sort C.sort | ||
| func Sort(a unsafe.Pointer, b unsafe.Pointer, elementSize c.Int, count c.Int, cmp func(_llcppg_param1 unsafe.Pointer, _llcppg_param2 unsafe.Pointer) c.Int) c.Int | ||
|
|
||
| //go:linkname G C.g | ||
| func G() |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -20,8 +20,10 @@ import ( | |
| "go/token" | ||
| "go/types" | ||
| "log" | ||
| "strconv" | ||
|
|
||
| "github.com/goplus/gogen" | ||
| "github.com/goplus/lib/c" | ||
| "github.com/goplus/llcppg/clang" | ||
| lc "github.com/goplus/llcppg/lib/clang" | ||
| ) | ||
|
|
@@ -60,7 +62,7 @@ func newPointer(typ types.Type) types.Type { | |
| return types.NewPointer(typ) | ||
| } | ||
|
|
||
| func toType(ctx *blockCtx, typ lc.Type, flags int) types.Type { | ||
| func toType(ctx *blockCtx, pkg *types.Package, typ lc.Type, flags int) types.Type { | ||
| switch typ.Kind { | ||
| case lc.TypeCharS: | ||
| return ctx.c.Ref("Char").Type() | ||
|
|
@@ -69,14 +71,59 @@ func toType(ctx *blockCtx, typ lc.Type, flags int) types.Type { | |
| case lc.TypeUInt: | ||
| return ctx.c.Ref("Uint").Type() | ||
| case lc.TypePointer: | ||
| pointee := toType(ctx, typ.PointeeType(), flags) | ||
| elem := typ.PointeeType() | ||
| if elem.Kind == lc.TypeFunctionProto { | ||
| return toFuncType(ctx, pkg, elem) | ||
| } | ||
| pointee := toType(ctx, pkg, elem, flags) | ||
| return newPointer(pointee) | ||
| case lc.TypeVoid: | ||
| return tyVoid | ||
| default: | ||
| log.Println("==> toType: unknown Kind -", typ.Kind) | ||
| } | ||
| panic("todo: toType " + clang.String(typ)) | ||
| } | ||
|
|
||
| func toFuncType(ctx *blockCtx, pkg *types.Package, fn lc.Type) *types.Signature { | ||
| params, variadic := toFuncParams(ctx, pkg, fn) | ||
| results := toFuncResults(ctx, pkg, fn.ResultType()) | ||
| return types.NewSignatureType(nil, nil, nil, params, results, variadic) | ||
| } | ||
|
|
||
| func toFuncParams(ctx *blockCtx, pkg *types.Package, fn lc.Type) (ret *types.Tuple, variadic bool) { | ||
| n := fn.NumArgTypes() | ||
| var params []*types.Var | ||
| for i := range n { | ||
| item := fn.ArgType(c.Uint(i)) | ||
| tyParam := toType(ctx, pkg, item, flagIsParam) | ||
| nameParam := "_llcppg_param" + strconv.Itoa(int(i)+1) | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
| params = append(params, types.NewParam(token.NoPos, pkg, nameParam, tyParam)) | ||
| } | ||
| variadic = fn.IsFunctionTypeVariadic() != 0 | ||
| if variadic { | ||
| params = append(params, newVariadicParam(pkg)) | ||
| } | ||
| ret = types.NewTuple(params...) | ||
| return | ||
| } | ||
|
|
||
| var ( | ||
| tyValist types.Type = types.NewSlice(gogen.TyAny) | ||
| ) | ||
|
|
||
| func newVariadicParam(pkg *types.Package) *types.Var { | ||
| return types.NewParam(token.NoPos, pkg, "__llgo_va_list", tyValist) | ||
| } | ||
|
|
||
| func toFuncResults(ctx *blockCtx, pkg *types.Package, retType lc.Type) (results *types.Tuple) { | ||
| if retType.Kind != lc.TypeVoid { | ||
| tyRet := toType(ctx, pkg, retType, flagRetType) | ||
| results = types.NewTuple(types.NewParam(token.NoPos, pkg, "", tyRet)) | ||
| } | ||
| return | ||
| } | ||
|
|
||
| // ----------------------------------------------------------------------------- | ||
|
|
||
| func substObj(pkg *types.Package, scope *types.Scope, origName string, real types.Object) { | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The pointer branch forwards
flagsrecursively (line 78), but the function-proto branch dropsflagswhen callingtoFuncType, andtoFuncParamsthen hardcodesflagIsParam. Harmless today sinceflagsis unused in the reachable branches, but the asymmetry could surprise if downstream logic ever keys offflagRetType/flagIsStructFieldinside a function pointer.