cl: _testcgo/struct
This commit is contained in:
32
ssa/expr.go
32
ssa/expr.go
@@ -280,6 +280,36 @@ func (b Builder) Store(ptr, val Expr) Builder {
|
||||
return b
|
||||
}
|
||||
|
||||
// The FieldAddr instruction yields the address of Field of *struct X.
|
||||
//
|
||||
// The field is identified by its index within the field list of the
|
||||
// struct type of X.
|
||||
//
|
||||
// Dynamically, this instruction panics if X evaluates to a nil
|
||||
// pointer.
|
||||
//
|
||||
// Type() returns a (possibly named) *types.Pointer.
|
||||
//
|
||||
// Pos() returns the position of the ast.SelectorExpr.Sel for the
|
||||
// field, if explicit in the source. For implicit selections, returns
|
||||
// the position of the inducing explicit selection. If produced for a
|
||||
// struct literal S{f: e}, it returns the position of the colon; for
|
||||
// S{e} it returns the start of expression e.
|
||||
//
|
||||
// Example printed form:
|
||||
//
|
||||
// t1 = &t0.name [#1]
|
||||
func (b Builder) FieldAddr(x Expr, idx int) Expr {
|
||||
if debugInstr {
|
||||
log.Printf("FieldAddr %v, %d\n", x.impl, idx)
|
||||
}
|
||||
prog := b.prog
|
||||
tstruc := prog.Elem(x.Type)
|
||||
telem := prog.Field(tstruc, idx)
|
||||
pt := prog.Pointer(telem)
|
||||
return Expr{llvm.CreateStructGEP(b.impl, telem.ll, x.impl, idx), pt}
|
||||
}
|
||||
|
||||
// The IndexAddr instruction yields the address of the element at
|
||||
// index `idx` of collection `x`. `idx` is an integer expression.
|
||||
//
|
||||
@@ -324,7 +354,7 @@ func (b Builder) IndexAddr(x, idx Expr) Expr {
|
||||
// t1 = new int
|
||||
func (b Builder) Alloc(t Type, heap bool) (ret Expr) {
|
||||
if debugInstr {
|
||||
log.Printf("Alloc %v, %v\n", t.ll, heap)
|
||||
log.Printf("Alloc %v, %v\n", t.t, heap)
|
||||
}
|
||||
telem := b.prog.Elem(t)
|
||||
if heap {
|
||||
|
||||
23
ssa/type.go
23
ssa/type.go
@@ -111,6 +111,11 @@ func (p Program) Index(typ Type) Type {
|
||||
return p.Type(indexType(typ.t))
|
||||
}
|
||||
|
||||
func (p Program) Field(typ Type, i int) Type {
|
||||
tunder := typ.t.Underlying()
|
||||
return p.Type(tunder.(*types.Struct).Field(i).Type())
|
||||
}
|
||||
|
||||
func (p Program) Type(typ types.Type) Type {
|
||||
if v := p.typs.At(typ); v != nil {
|
||||
return v.(Type)
|
||||
@@ -322,11 +327,27 @@ func (p Program) retType(sig *types.Signature) Type {
|
||||
func (p Program) toLLVMNamed(typ *types.Named) Type {
|
||||
switch t := typ.Underlying().(type) {
|
||||
case *types.Struct:
|
||||
name := typ.Obj().Name()
|
||||
name := NameOf(typ)
|
||||
return &aType{p.toLLVMNamedStruct(name, t), typ, vkInvalid}
|
||||
default:
|
||||
return p.Type(t)
|
||||
}
|
||||
}
|
||||
|
||||
func NameOf(typ *types.Named) string {
|
||||
obj := typ.Obj()
|
||||
return FullName(obj.Pkg(), obj.Name())
|
||||
}
|
||||
|
||||
func FullName(pkg *types.Package, name string) string {
|
||||
return PathOf(pkg) + "." + name
|
||||
}
|
||||
|
||||
func PathOf(pkg *types.Package) string {
|
||||
if pkg.Name() == "main" {
|
||||
return "main"
|
||||
}
|
||||
return pkg.Path()
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
Reference in New Issue
Block a user