diff --git a/cl/blockctx.go b/cl/blockctx.go index fb441bd..7d30ccd 100644 --- a/cl/blockctx.go +++ b/cl/blockctx.go @@ -210,6 +210,18 @@ type blockCtx struct { testMain bool } +func (p *blockCtx) Pkg() *types.Package { + return p.pkg.Types +} + +func (p *blockCtx) Int128() types.Type { + return p.tyI128 +} + +func (p *blockCtx) Uint128() types.Type { + return p.tyU128 +} + func (p *blockCtx) deleteUnnamed(id ast.ID) { if u, ok := p.unnameds[id]; ok { for _, delName := range u.del { diff --git a/cl/expr.go b/cl/expr.go index 4b6d923..8d0374a 100644 --- a/cl/expr.go +++ b/cl/expr.go @@ -85,9 +85,9 @@ func compileExprLHS(ctx *blockCtx, expr *ast.Node) { } func compileCompoundLiteralExpr(ctx *blockCtx, expr *ast.Node) { - typ := toType(ctx, expr.Type, 0) switch inner := expr.Inner[0]; inner.Kind { case ast.InitListExpr: + typ := toType(ctx, inner.Type, 0) initLit(ctx, typ, inner) default: log.Panicln("compileCompoundLiteralExpr unexpected:", inner.Kind) diff --git a/cl/type_and_var.go b/cl/type_and_var.go index 8124f8a..929a778 100644 --- a/cl/type_and_var.go +++ b/cl/type_and_var.go @@ -31,8 +31,7 @@ func toTypeEx(ctx *blockCtx, scope *types.Scope, tyAnonym types.Type, typ *ast.T func parseType(ctx *blockCtx, scope *types.Scope, tyAnonym types.Type, typ *ast.Type, flags int) (t types.Type, kind int, err error) { conf := &parser.Config{ - Pkg: ctx.pkg.Types, Scope: scope, Flags: flags, - TyAnonym: tyAnonym, TyInt128: ctx.tyI128, TyUint128: ctx.tyU128, + Scope: scope, Flags: flags, Anonym: tyAnonym, ParseEnv: ctx, } retry: t, kind, err = parser.ParseType(typ.QualType, conf) diff --git a/clang/ast/ast.go b/clang/ast/ast.go index 9239e45..671c048 100644 --- a/clang/ast/ast.go +++ b/clang/ast/ast.go @@ -217,6 +217,7 @@ type Node struct { MangledName string `json:"mangledName,omitempty"` Type *Type `json:"type,omitempty"` CC CC `json:"cc,omitempty"` + Field *Node `json:"field,omitempty"` Decl *Node `json:"decl,omitempty"` OwnedTagDecl *Node `json:"ownedTagDecl,omitempty"` ReferencedDecl *Node `json:"referencedDecl,omitempty"` diff --git a/clang/types/parser/parser.go b/clang/types/parser/parser.go index 84ebbf6..7d8bec1 100644 --- a/clang/types/parser/parser.go +++ b/clang/types/parser/parser.go @@ -61,13 +61,17 @@ func getRetType(flags int) bool { return (flags & FlagGetRetType) != 0 } +type ParseEnv interface { + Pkg() *types.Package + Int128() types.Type + Uint128() types.Type +} + type Config struct { - Pkg *types.Package - Scope *types.Scope - TyAnonym types.Type - TyInt128 types.Type - TyUint128 types.Type - Flags int + ParseEnv + Scope *types.Scope + Anonym types.Type + Flags int } const ( @@ -105,7 +109,6 @@ func ParseType(qualType string, conf *Config) (t types.Type, kind int, err error type parser struct { s scanner.Scanner - pkg *types.Package scope *types.Scope conf *Config @@ -122,7 +125,7 @@ const ( ) func newParser(qualType string, conf *Config) *parser { - p := &parser{pkg: conf.Pkg, scope: conf.Scope, conf: conf} + p := &parser{scope: conf.Scope, conf: conf} p.old.tok = invalidTok p.s.Init(qualType) return p @@ -197,12 +200,13 @@ func (p *parser) lookupType(tylit string, flags int) (t types.Type, err error) { if !structOrUnion && flags != 0 { tt, ok := t.(*types.Basic) if !ok { - if t == p.conf.TyInt128 { + tyInt128 := p.conf.Int128() + if t == tyInt128 { switch flags { case flagSigned: - return p.conf.TyInt128, nil + return tyInt128, nil case flagUnsigned: - return p.conf.TyUint128, nil + return p.conf.Uint128(), nil } } } else if (flags & flagComplex) != 0 { @@ -380,9 +384,9 @@ func (p *parser) parse(inFlags int) (t types.Type, kind int, err error) { switch p.tok { case token.IDENT: case token.LPAREN: - if t == nil && p.conf.TyAnonym != nil { + if t == nil && p.conf.Anonym != nil { p.skipUntil(token.RPAREN) - t = p.conf.TyAnonym + t = p.conf.Anonym kind |= KindFAnonymous continue } @@ -433,7 +437,7 @@ func (p *parser) parse(inFlags int) (t types.Type, kind int, err error) { var nstar = p.parseStars() var nstarRet int var tyArr types.Type - var pkg, isFn = p.pkg, false + var pkg, isFn = p.conf.Pkg(), false var args []*types.Var var variadic bool if nstar == 0 { diff --git a/clang/types/parser/parser_test.go b/clang/types/parser/parser_test.go index 4371ce4..631f89f 100644 --- a/clang/types/parser/parser_test.go +++ b/clang/types/parser/parser_test.go @@ -171,6 +171,24 @@ var cases = []testCase{ {qualType: "enum a", typ: ctypes.Int}, } +type baseEnv struct { + pkg *types.Package + tyInt128 types.Type + tyUint128 types.Type +} + +func (p *baseEnv) Pkg() *types.Package { + return p.pkg +} + +func (p *baseEnv) Int128() types.Type { + return p.tyInt128 +} + +func (p *baseEnv) Uint128() types.Type { + return p.tyUint128 +} + func TestCases(t *testing.T) { sel := "" for _, c := range cases { @@ -179,8 +197,8 @@ func TestCases(t *testing.T) { } t.Run(c.qualType, func(t *testing.T) { conf := &Config{ - Pkg: pkg, Scope: scope, Flags: c.flags, - TyAnonym: c.anonym, TyInt128: tyInt128, TyUint128: tyUint128, + Scope: scope, Flags: c.flags, Anonym: c.anonym, + ParseEnv: &baseEnv{pkg: pkg, tyInt128: tyInt128, tyUint128: tyUint128}, } typ, _, err := ParseType(c.qualType, conf) if err != nil { diff --git a/testdata/compoundlit/compoundlit.c b/testdata/compoundlit/compoundlit.c index c314056..eb4047a 100644 --- a/testdata/compoundlit/compoundlit.c +++ b/testdata/compoundlit/compoundlit.c @@ -1,5 +1,13 @@ #include +#define asdouble(i) ((union{unsigned long _ival; double _fval;}){i})._fval + +/* +void test() { + printf("%f\n", asdouble(1)); +} +*/ + void f(unsigned short a[]) { printf("%d, %d, %d\n", (int)a[0], (int)a[1], (int)a[2]); }