func (d *DWARFHelper) GetType(off dwarf.Offset) (content.Type, error) { var t content.Type r := d.df.Reader() r.Seek(off) recurse := false if e, err := r.Next(); err != nil { return t, err } else { switch e.Tag { case dwarf.TagVolatileType, dwarf.TagReferenceType, dwarf.TagRestrictType, dwarf.TagConstType, dwarf.TagSubroutineType: recurse = true case dwarf.TagPointerType: t.Flags |= content.FLAG_TYPE_POINTER recurse = true case dwarf.TagArrayType: recurse = true t.Flags |= content.FLAG_TYPE_ARRAY case dwarf.TagClassType, dwarf.TagTypedef, dwarf.TagBaseType, dwarf.TagEnumerationType, dwarf.TagStructType: if v, ok := e.Val(dwarf.AttrName).(string); ok { t.Name.Relative = v } case dwarf.TagUnionType: t.Name.Relative = "union" default: return t, errors.New(fmt.Sprintf("Don't know how to handle %+v", e)) } if recurse { if v, ok := e.Val(dwarf.AttrType).(dwarf.Offset); ok { if t2, err := d.GetType(v); err != nil { return t, err } else { t.Specialization = append(t.Specialization, t2) } } } switch e.Tag { case dwarf.TagVolatileType, dwarf.TagReferenceType, dwarf.TagRestrictType, dwarf.TagConstType: if len(t.Specialization) == 0 { t.Name.Relative = "void" } else { t = t.Specialization[0] } } switch e.Tag { case dwarf.TagPointerType: if len(t.Specialization) == 0 { t.Specialization = append(t.Specialization, content.Type{Name: content.FullyQualifiedName{Relative: "void"}}) } case dwarf.TagVolatileType: t.Flags |= content.FLAG_VOLATILE case dwarf.TagReferenceType: t.Flags |= content.FLAG_REFERENCE case dwarf.TagRestrictType: t.Flags |= content.FLAG_RESTRICT case dwarf.TagConstType: t.Flags |= content.FLAG_CONST case dwarf.TagSubroutineType: var m content.Method if len(t.Specialization) > 0 { m.Returns = append(m.Returns, content.Variable{Type: t.Specialization[0]}) } else { m.Returns = append(m.Returns, content.Variable{Type: content.Type{Name: content.FullyQualifiedName{Relative: "void"}}}) } t.Specialization = t.Specialization[0:0] t.Flags = content.FLAG_TYPE_METHOD for { if e, err := r.Next(); err != nil { return t, err } else if e == nil || e.Tag == 0 { break } else if e.Tag == dwarf.TagFormalParameter { var p content.Variable if v, ok := e.Val(dwarf.AttrType).(dwarf.Offset); ok { if t2, err := d.GetType(v); err != nil { return t, err } else { p.Type = t2 } } if v, ok := e.Val(dwarf.AttrName).(string); ok { p.Name.Relative = v } m.Parameters = append(m.Parameters, p) } } t.Methods = append(t.Methods, m) } return t, nil } }