Skip to content
This repository has been archived by the owner on May 18, 2024. It is now read-only.

Commit

Permalink
aslong @ testdata/compoundlit.c
Browse files Browse the repository at this point in the history
  • Loading branch information
xushiwei committed Jul 21, 2022
1 parent 38d0ebc commit 249d8c5
Show file tree
Hide file tree
Showing 4 changed files with 58 additions and 7 deletions.
26 changes: 23 additions & 3 deletions cl/expr.go
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,11 @@ func compileExprLHS(ctx *blockCtx, expr *ast.Node) {
func compileCompoundLiteralExpr(ctx *blockCtx, expr *ast.Node) {
switch inner := expr.Inner[0]; inner.Kind {
case ast.InitListExpr:
typ := toType(ctx, inner.Type, 0)
var tyAnonym types.Type
if fld := inner.Field; fld != nil {
tyAnonym = toAnonymType(ctx, ctx.goNodePos(expr), fld)
}
typ, _ := toTypeEx(ctx, ctx.cb.Scope(), tyAnonym, inner.Type, 0)
initLit(ctx, typ, inner)
default:
log.Panicln("compileCompoundLiteralExpr unexpected:", inner.Kind)
Expand Down Expand Up @@ -323,10 +327,26 @@ func compileMemberExpr(ctx *blockCtx, v *ast.Node, lhs bool) {
return
}
src := ctx.goNode(v)
cb := ctx.cb
if lhs {
ctx.cb.MemberRef(name, src)
cb.MemberRef(name, src)
} else {
ctx.cb.MemberVal(name, src)
_, err := cb.Member(name, gox.MemberFlagVal, src)
if err != nil { // see aslong @ testdata/compoundlit.c
if t, ok := checkAnonyUnion(cb.InternalStack().Get(-1).Type); ok {
if stru, ok := t.Underlying().(*types.Struct); ok && stru.NumFields() == 1 {
fld := stru.Field(0)
fields := []*gox.UnionField{
{Name: fld.Name(), Type: fld.Type()},
{Name: name, Type: toType(ctx, v.Type, 0)},
}
ctx.pkg.SetVFields(t, gox.NewUnionFields(fields))
cb.MemberVal(name, src)
return
}
}
panic(err)
}
}
}

Expand Down
14 changes: 14 additions & 0 deletions cl/multifiles.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package cl
import (
"encoding/json"
"go/token"
"go/types"
"log"
"os"
"path/filepath"
Expand Down Expand Up @@ -96,6 +97,19 @@ func (p *blockCtx) getSuName(v *ast.Node, tag string) (string, int) {
return "_cgoa_" + strconv.Itoa(*p.base) + p.baseOF, suAnonymous
}

func (p *blockCtx) getAnonyName() string {
*p.base++
return "_cgoz_" + strconv.Itoa(*p.base) + p.baseOF
}

func checkAnonyUnion(typ types.Type) (t *types.Named, ok bool) {
if t, ok = typ.(*types.Named); ok {
name := t.Obj().Name()
ok = strings.HasPrefix(name, "_cgoz_")
}
return
}

func (p *blockCtx) autoStaticName(name string) string {
*p.base++
return name + "_cgo" + strconv.Itoa(*p.base) + p.baseOF
Expand Down
18 changes: 18 additions & 0 deletions cl/type_and_var.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,24 @@ retry:
return
}

func toAnonymType(ctx *blockCtx, pos token.Pos, decl *ast.Node) (ret *types.Named) {
scope := types.NewScope(ctx.cb.Scope(), token.NoPos, token.NoPos, "")
switch decl.Kind {
case ast.FieldDecl:
if debugCompileDecl {
log.Println(" => field", decl.Name, "-", decl.Type.QualType)
}
pkg := ctx.pkg
typ, _ := toTypeEx(ctx, scope, nil, decl.Type, 0)
fld := types.NewField(ctx.goNodePos(decl), pkg.Types, decl.Name, typ, false)
struc := types.NewStruct([]*types.Var{fld}, nil)
ret = ctx.cb.NewType(ctx.getAnonyName(), pos).InitType(pkg, struc)
default:
log.Panicln("toAnonymType: unknown kind -", decl.Kind)
}
return
}

func toStructType(ctx *blockCtx, t *types.Named, struc *ast.Node) (ret *types.Struct, dels delfunc) {
b := newStructBuilder()
scope := types.NewScope(ctx.cb.Scope(), token.NoPos, token.NoPos, "")
Expand Down
7 changes: 3 additions & 4 deletions testdata/compoundlit/compoundlit.c
Original file line number Diff line number Diff line change
@@ -1,12 +1,10 @@
#include <stdio.h>

#define asdouble(i) ((union{unsigned long _ival; double _fval;}){i})._fval
#define aslong(v) ((union{double _fval; long _ival;}){v})._ival

/*
void test() {
printf("%f\n", asdouble(1));
printf("%d\n", (int)aslong(1.1));
}
*/

void f(unsigned short a[]) {
printf("%d, %d, %d\n", (int)a[0], (int)a[1], (int)a[2]);
Expand All @@ -19,5 +17,6 @@ void g(unsigned short (*a)[3]) {
int main() {
f((unsigned short [3]){ 0x330e, 0, 16 });
g(&(unsigned short [3]){ 0x330e, 0, 16 });
test();
return 0;
}

0 comments on commit 249d8c5

Please sign in to comment.