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

Commit

Permalink
support: offsetof
Browse files Browse the repository at this point in the history
  • Loading branch information
xushiwei committed Apr 15, 2022
1 parent d11eee5 commit 8561ceb
Show file tree
Hide file tree
Showing 3 changed files with 63 additions and 6 deletions.
55 changes: 50 additions & 5 deletions cl/blockctx.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,10 @@ import (
ctypes "github.com/goplus/c2go/clang/types"
)

const (
space = " \t\r\n"
)

// -----------------------------------------------------------------------------

type funcCtx struct {
Expand Down Expand Up @@ -227,16 +231,31 @@ func (p *blockCtx) labelOfGoto(v *ast.Node) string {
return label
}

func (p *blockCtx) typeOfSizeof(v *ast.Node) string {
func (p *blockCtx) paramsOfOfsetof(v *ast.Node) (string, string) {
src := p.getSource()
off := v.Range.Begin.Offset
n := int64(v.Range.Begin.TokLen)
op := string(src[off : off+n])
if op != "__builtin_offsetof" {
log.Panicln("unknown offsetofOp:", op)
}
params := strings.SplitN(paramsOf(src[off+n:v.Range.End.Offset]), ",", 2)
return params[0], strings.Trim(params[1], space)
}

func paramsOf(v []byte) string {
return strings.TrimPrefix(strings.TrimLeft(string(v), space), "(")
}

func (p *blockCtx) paramOfSizeof(v *ast.Node) string {
src := p.getSource()
off := v.Range.Begin.Offset
n := int64(v.Range.Begin.TokLen)
op := string(src[off : off+n])
if op != "sizeof" {
log.Panicln("sizeofOp:", op)
log.Panicln("unknown sizeofOp:", op)
}
typ := string(src[off+n : v.Range.End.Offset])
return strings.TrimPrefix(strings.TrimLeft(typ, " \t\r\n"), "(")
return paramsOf(src[off+n : v.Range.End.Offset])
}

func (p *blockCtx) getInstr(v *ast.Node) string {
Expand All @@ -247,7 +266,7 @@ func (p *blockCtx) getInstr(v *ast.Node) string {
}

func ident(b []byte, msg string) string {
b = bytes.TrimLeft(b, " \t\r\n")
b = bytes.TrimLeft(b, space)
idx := bytes.IndexFunc(b, func(r rune) bool {
return !ctype.Is(ctype.CSYMBOL_NEXT_CHAR, r)
})
Expand All @@ -261,6 +280,32 @@ func (p *blockCtx) sizeof(typ types.Type) int {
return int(p.pkg.Sizeof(typ))
}

func (p *blockCtx) offsetof(typ types.Type, name string) int {
retry:
switch t := typ.(type) {
case *types.Struct:
if flds, idx := getFld(t, name); idx >= 0 {
return int(p.pkg.Offsetsof(flds)[idx])
}
case *types.Named:
typ = t.Underlying()
goto retry
}
log.Panicf("offsetof(%v, %v): field not found", typ, name)
return -1
}

func getFld(t *types.Struct, name string) (flds []*types.Var, i int) {
for n := t.NumFields(); i < n; i++ {
f := t.Field(i)
flds = append(flds, f)
if f.Name() == name {
return
}
}
return nil, -1
}

const (
suNormal = iota
suAnonymous
Expand Down
13 changes: 12 additions & 1 deletion cl/expr.go
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,8 @@ func compileExprEx(ctx *blockCtx, expr *ast.Node, prompt string, flags int) {
compileVAArgExpr(ctx, expr)
case ast.AtomicExpr:
compileAtomicExpr(ctx, expr)
case ast.OffsetOfExpr:
compileOffsetOfExpr(ctx, expr)
default:
log.Panicln(prompt, expr.Kind)
}
Expand Down Expand Up @@ -105,13 +107,22 @@ func compileImaginaryLiteral(ctx *blockCtx, expr *ast.Node) {

// -----------------------------------------------------------------------------

func compileOffsetOfExpr(ctx *blockCtx, v *ast.Node) {
tyStruct, name := ctx.paramsOfOfsetof(v)
if debugCompileDecl {
log.Println("==> offset", tyStruct, name)
}
t := toType(ctx, &ast.Type{QualType: tyStruct}, 0)
ctx.cb.Val(ctx.offsetof(t, name))
}

func compileSizeof(ctx *blockCtx, v *ast.Node) {
var t types.Type
if len(v.Inner) > 0 {
compileExpr(ctx, v.Inner[0])
t = ctx.cb.InternalStack().Pop().Type
} else {
qualType := ctx.typeOfSizeof(v)
qualType := ctx.paramOfSizeof(v)
if debugCompileDecl {
log.Println("==> sizeof", qualType)
}
Expand Down
1 change: 1 addition & 0 deletions clang/ast/ast.go
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,7 @@ const (
ImplicitCastExpr Kind = "ImplicitCastExpr"
ImplicitValueInitExpr Kind = "ImplicitValueInitExpr"
UnaryExprOrTypeTraitExpr Kind = "UnaryExprOrTypeTraitExpr"
OffsetOfExpr Kind = "OffsetOfExpr"
ArraySubscriptExpr Kind = "ArraySubscriptExpr"
AtomicExpr Kind = "AtomicExpr"
VAArgExpr Kind = "VAArgExpr"
Expand Down

0 comments on commit 8561ceb

Please sign in to comment.