From 8c3b34a8b4ff8165e8b4b3514a9fab358fa6112b Mon Sep 17 00:00:00 2001 From: Robin Eklind Date: Fri, 6 Mar 2020 17:06:20 +0100 Subject: [PATCH] ast: add ConstantExpr c2go is now capable of parsing function types without parameters. Example C source that is now parsed: typedef int (*foo)(); Fixes #831. --- ast/ast.go | 2 ++ ast/function_no_proto_type.go | 49 ++++++++++++++++++++++++++++++ ast/function_no_proto_type_test.go | 18 +++++++++++ ast/position.go | 7 +++-- 4 files changed, 73 insertions(+), 3 deletions(-) create mode 100644 ast/function_no_proto_type.go create mode 100644 ast/function_no_proto_type_test.go diff --git a/ast/ast.go b/ast/ast.go index bb44d1bf5..d46d5d9d8 100644 --- a/ast/ast.go +++ b/ast/ast.go @@ -136,6 +136,8 @@ func Parse(fullline string) Node { return parseFunctionDecl(line) case "FullComment": return parseFullComment(line) + case "FunctionNoProtoType": + return parseFunctionNoProtoType(line) case "FunctionProtoType": return parseFunctionProtoType(line) case "ForStmt": diff --git a/ast/function_no_proto_type.go b/ast/function_no_proto_type.go new file mode 100644 index 000000000..eedc9aa78 --- /dev/null +++ b/ast/function_no_proto_type.go @@ -0,0 +1,49 @@ +package ast + +// FunctionNoProtoType is a function type without parameters. +// +// Example: +// int (*)() +type FunctionNoProtoType struct { + Addr Address + Type string + CallingConv string + ChildNodes []Node +} + +func parseFunctionNoProtoType(line string) *FunctionNoProtoType { + groups := groupsFromRegex( + "'(?P.*?)' (?P.*)", + line, + ) + + return &FunctionNoProtoType{ + Addr: ParseAddress(groups["address"]), + Type: groups["type"], + CallingConv: groups["calling_conv"], + ChildNodes: []Node{}, + } +} + +// AddChild adds a new child node. Child nodes can then be accessed with the +// Children attribute. +func (n *FunctionNoProtoType) AddChild(node Node) { + n.ChildNodes = append(n.ChildNodes, node) +} + +// Address returns the numeric address of the node. See the documentation for +// the Address type for more information. +func (n *FunctionNoProtoType) Address() Address { + return n.Addr +} + +// Children returns the child nodes. If this node does not have any children or +// this node does not support children it will always return an empty slice. +func (n *FunctionNoProtoType) Children() []Node { + return n.ChildNodes +} + +// Position returns the position in the original source code. +func (n *FunctionNoProtoType) Position() Position { + return Position{} +} diff --git a/ast/function_no_proto_type_test.go b/ast/function_no_proto_type_test.go new file mode 100644 index 000000000..a91853c9d --- /dev/null +++ b/ast/function_no_proto_type_test.go @@ -0,0 +1,18 @@ +package ast + +import ( + "testing" +) + +func TestFunctionNoProtoType(t *testing.T) { + nodes := map[string]Node{ + `0x556e32bfde50 'int ()' cdecl`: &FunctionNoProtoType{ + Addr: 0x556e32bfde50, + Type: "int ()", + CallingConv: "cdecl", + ChildNodes: []Node{}, + }, + } + + runNodeTests(t, nodes) +} diff --git a/ast/position.go b/ast/position.go index aa39c39b1..d2e0477db 100644 --- a/ast/position.go +++ b/ast/position.go @@ -409,9 +409,10 @@ func setPosition(node Node, position Position) { n.Pos = position case *TypedefType, *Typedef, *TranslationUnitDecl, *RecordType, *Record, *QualType, *PointerType, *DecayedType, *ParenType, - *IncompleteArrayType, *FunctionProtoType, *EnumType, *Enum, - *ElaboratedType, *ConstantArrayType, *BuiltinType, *ArrayFiller, - *Field, *AttributedType: + *IncompleteArrayType, *FunctionNoProtoType, *FunctionProtoType, + *EnumType, *Enum, *ElaboratedType, *ConstantArrayType, *BuiltinType, + *ArrayFiller, *Field, *AttributedType: + // These do not have positions so they can be ignored. default: panic(fmt.Sprintf("unknown node type: %+#v", node))