Пример #1
0
func (d *DWARFHelper) toContentMethod(e *dwarf.Entry) (m content.Method, err error) {
	if v, ok := e.Val(dwarf.AttrName).(string); ok {
		m.Name.Relative = v
	}
	if v, ok := e.Val(dwarf.AttrType).(dwarf.Offset); ok {
		if t, err := d.GetType(v); err != nil {
			return m, err
		} else {
			m.Returns = append(m.Returns, content.Variable{Type: t})
		}
	} else {
		m.Returns = append(m.Returns, content.Variable{Type: content.Type{Name: content.FullyQualifiedName{Relative: "void"}}})
	}
	m.Flags = d.Flags(e)
	if !e.Children {
		return
	}
	r := d.df.Reader()
	r.Seek(e.Offset)
	for {
		e, err := r.Next()
		if err != nil {
			return m, err
		} else if e == nil || e.Tag == 0 {
			break
		}
		if e.Tag != dwarf.TagFormalParameter {
			continue
		}
		var p content.Variable
		if v, ok := e.Val(dwarf.AttrType).(dwarf.Offset); ok {
			if t, err := d.GetType(v); err != nil {
				return m, err
			} else {
				p.Type = t
			}
		}
		if v, ok := e.Val(dwarf.AttrName).(string); ok {
			p.Name.Relative = v
		}
		if v, ok := e.Val(dwarf.AttrArtificial).(bool); ok && v {
			if p.Type.Flags&content.FLAG_TYPE_MASK != content.FLAG_TYPE_POINTER {
				m.Parameters = append(m.Parameters, p)
				continue
			}
			// C++ "this" pointer
			t := p.Type.Specialization[0]
			if t.Flags&content.FLAG_CONST != 0 {
				m.Flags |= content.FLAG_CONST
			}
			//m.Name.Absolute = t.Name.Relative + "::" + m.Name.Relative
		} else {
			m.Parameters = append(m.Parameters, p)
		}
	}
	return
}
Пример #2
0
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
	}
}