| // Copyright 2017 syzkaller project authors. All rights reserved. |
| // Use of this source code is governed by Apache 2 LICENSE that can be found in the LICENSE file. |
| |
| package ast |
| |
| import ( |
| "fmt" |
| ) |
| |
| func Clone(desc *Description) *Description { |
| desc1 := &Description{} |
| for _, n := range desc.Nodes { |
| c, ok := n.(cloner) |
| if !ok { |
| panic(fmt.Sprintf("unknown top level decl: %#v", n)) |
| } |
| desc1.Nodes = append(desc1.Nodes, c.clone()) |
| } |
| return desc1 |
| } |
| |
| type cloner interface { |
| clone() Node |
| } |
| |
| func (n *NewLine) clone() Node { |
| return &NewLine{ |
| Pos: n.Pos, |
| } |
| } |
| |
| func (n *Comment) clone() Node { |
| return &Comment{ |
| Pos: n.Pos, |
| Text: n.Text, |
| } |
| } |
| |
| func (n *Include) clone() Node { |
| return &Include{ |
| Pos: n.Pos, |
| File: n.File.clone(), |
| } |
| } |
| |
| func (n *Incdir) clone() Node { |
| return &Incdir{ |
| Pos: n.Pos, |
| Dir: n.Dir.clone(), |
| } |
| } |
| |
| func (n *Define) clone() Node { |
| return &Define{ |
| Pos: n.Pos, |
| Name: n.Name.clone(), |
| Value: n.Value.clone(), |
| } |
| } |
| |
| func (n *Resource) clone() Node { |
| var values []*Int |
| for _, v := range n.Values { |
| values = append(values, v.clone()) |
| } |
| return &Resource{ |
| Pos: n.Pos, |
| Name: n.Name.clone(), |
| Base: n.Base.clone(), |
| Values: values, |
| } |
| } |
| |
| func (n *Call) clone() Node { |
| var args []*Field |
| for _, a := range n.Args { |
| args = append(args, a.clone()) |
| } |
| var ret *Type |
| if n.Ret != nil { |
| ret = n.Ret.clone() |
| } |
| return &Call{ |
| Pos: n.Pos, |
| Name: n.Name.clone(), |
| CallName: n.CallName, |
| NR: n.NR, |
| Args: args, |
| Ret: ret, |
| } |
| } |
| |
| func (n *Struct) clone() Node { |
| var fields []*Field |
| for _, f := range n.Fields { |
| fields = append(fields, f.clone()) |
| } |
| var attrs []*Ident |
| for _, a := range n.Attrs { |
| attrs = append(attrs, a.clone()) |
| } |
| var comments []*Comment |
| for _, c := range n.Comments { |
| comments = append(comments, c.clone().(*Comment)) |
| } |
| return &Struct{ |
| Pos: n.Pos, |
| Name: n.Name.clone(), |
| Fields: fields, |
| Attrs: attrs, |
| Comments: comments, |
| IsUnion: n.IsUnion, |
| } |
| } |
| |
| func (n *IntFlags) clone() Node { |
| var values []*Int |
| for _, v := range n.Values { |
| values = append(values, v.clone()) |
| } |
| return &IntFlags{ |
| Pos: n.Pos, |
| Name: n.Name.clone(), |
| Values: values, |
| } |
| } |
| |
| func (n *StrFlags) clone() Node { |
| var values []*String |
| for _, v := range n.Values { |
| values = append(values, v.clone()) |
| } |
| return &StrFlags{ |
| Pos: n.Pos, |
| Name: n.Name.clone(), |
| Values: values, |
| } |
| } |
| |
| func (n *Ident) clone() *Ident { |
| return &Ident{ |
| Pos: n.Pos, |
| Name: n.Name, |
| } |
| } |
| |
| func (n *String) clone() *String { |
| return &String{ |
| Pos: n.Pos, |
| Value: n.Value, |
| } |
| } |
| |
| func (n *Int) clone() *Int { |
| return &Int{ |
| Pos: n.Pos, |
| Value: n.Value, |
| ValueHex: n.ValueHex, |
| Ident: n.Ident, |
| CExpr: n.CExpr, |
| } |
| } |
| |
| func (n *Type) clone() *Type { |
| var args []*Type |
| for _, a := range n.Args { |
| args = append(args, a.clone()) |
| } |
| return &Type{ |
| Pos: n.Pos, |
| Value: n.Value, |
| ValueHex: n.ValueHex, |
| Ident: n.Ident, |
| String: n.String, |
| HasColon: n.HasColon, |
| Pos2: n.Pos2, |
| Value2: n.Value2, |
| Value2Hex: n.Value2Hex, |
| Ident2: n.Ident2, |
| Args: args, |
| } |
| } |
| |
| func (n *Field) clone() *Field { |
| var comments []*Comment |
| for _, c := range n.Comments { |
| comments = append(comments, c.clone().(*Comment)) |
| } |
| return &Field{ |
| Pos: n.Pos, |
| Name: n.Name.clone(), |
| Type: n.Type.clone(), |
| NewBlock: n.NewBlock, |
| Comments: comments, |
| } |
| } |