Skip to content

Commit

Permalink
Merge pull request #109 from elliotchance/0.11.x/sizeof
Browse files Browse the repository at this point in the history
0.11.x/sizeof
  • Loading branch information
elliotchance authored May 15, 2017
2 parents 87ad710 + aa176f7 commit 74b761f
Show file tree
Hide file tree
Showing 26 changed files with 764 additions and 415 deletions.
4 changes: 4 additions & 0 deletions ast/ast.go
Original file line number Diff line number Diff line change
@@ -1,14 +1,18 @@
// Package ast parses the clang AST output into AST structures.
package ast

import (
"regexp"
"strings"
)

// Node represents any node in the AST.
type Node interface {
AddChild(node Node)
}

// Parse takes the coloured output of the clang AST command and returns a root
// node for the AST.
func Parse(line string) Node {
nodeName := strings.SplitN(line, " ", 2)[0]

Expand Down
15 changes: 13 additions & 2 deletions ast/ast_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,20 @@ package ast
import (
"fmt"
"reflect"
"strings"
"testing"

"github.com/elliotchance/c2go/util"
)

func formatMultiLine(o interface{}) string {
s := fmt.Sprintf("%#v", o)
s = strings.Replace(s, "{", "{\n", -1)
s = strings.Replace(s, ", ", "\n", -1)

return s
}

func runNodeTests(t *testing.T, tests map[string]Node) {
i := 1
for line, expected := range tests {
Expand All @@ -19,8 +30,8 @@ func runNodeTests(t *testing.T, tests map[string]Node) {
actual := Parse(name + " " + line)

if !reflect.DeepEqual(expected, actual) {
t.Errorf("\nexpected: %#v\n got: %#v\n\n",
expected, actual)
t.Errorf("%s", util.ShowDiff(formatMultiLine(expected),
formatMultiLine(actual)))
}
})
}
Expand Down
43 changes: 23 additions & 20 deletions ast/function_decl.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,17 @@ import (
)

type FunctionDecl struct {
Address string
Position string
Prev string
Position2 string
Name string
Type string
IsExtern bool
IsImplicit bool
IsUsed bool
Children []Node
Address string
Position string
Prev string
Position2 string
Name string
Type string
IsExtern bool
IsImplicit bool
IsUsed bool
IsReferenced bool
Children []Node
}

func parseFunctionDecl(line string) *FunctionDecl {
Expand All @@ -24,6 +25,7 @@ func parseFunctionDecl(line string) *FunctionDecl {
(?P<position2> <scratch space>[^ ]+| [^ ]+)?
(?P<implicit> implicit)?
(?P<used> used)?
(?P<referenced> referenced)?
(?P<name>[_\w]+)
'(?P<type>.*)
'(?P<extern> extern)?`,
Expand All @@ -36,16 +38,17 @@ func parseFunctionDecl(line string) *FunctionDecl {
}

return &FunctionDecl{
Address: groups["address"],
Position: groups["position1"],
Prev: prev,
Position2: strings.TrimSpace(groups["position2"]),
Name: groups["name"],
Type: groups["type"],
IsExtern: len(groups["extern"]) > 0,
IsImplicit: len(groups["implicit"]) > 0,
IsUsed: len(groups["used"]) > 0,
Children: []Node{},
Address: groups["address"],
Position: groups["position1"],
Prev: prev,
Position2: strings.TrimSpace(groups["position2"]),
Name: groups["name"],
Type: groups["type"],
IsExtern: len(groups["extern"]) > 0,
IsImplicit: len(groups["implicit"]) > 0,
IsUsed: len(groups["used"]) > 0,
IsReferenced: len(groups["referenced"]) > 0,
Children: []Node{},
}
}

Expand Down
139 changes: 79 additions & 60 deletions ast/function_decl_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,76 +7,95 @@ import (
func TestFunctionDecl(t *testing.T) {
nodes := map[string]Node{
`0x7fb5a90e60d0 <line:231:1, col:22> col:7 clearerr 'void (FILE *)'`: &FunctionDecl{
Address: "0x7fb5a90e60d0",
Position: "line:231:1, col:22",
Prev: "",
Position2: "col:7",
Name: "clearerr",
Type: "void (FILE *)",
IsExtern: false,
IsImplicit: false,
IsUsed: false,
Children: []Node{},
Address: "0x7fb5a90e60d0",
Position: "line:231:1, col:22",
Prev: "",
Position2: "col:7",
Name: "clearerr",
Type: "void (FILE *)",
IsExtern: false,
IsImplicit: false,
IsUsed: false,
IsReferenced: false,
Children: []Node{},
},
`0x7fb5a90e2a50 </usr/include/sys/stdio.h:39:1, /usr/include/AvailabilityInternal.h:21697:126> /usr/include/sys/stdio.h:39:5 renameat 'int (int, const char *, int, const char *)'`: &FunctionDecl{
Address: "0x7fb5a90e2a50",
Position: "/usr/include/sys/stdio.h:39:1, /usr/include/AvailabilityInternal.h:21697:126",
Prev: "",
Position2: "/usr/include/sys/stdio.h:39:5",
Name: "renameat",
Type: "int (int, const char *, int, const char *)",
IsExtern: false,
IsImplicit: false,
IsUsed: false,
Children: []Node{},
Address: "0x7fb5a90e2a50",
Position: "/usr/include/sys/stdio.h:39:1, /usr/include/AvailabilityInternal.h:21697:126",
Prev: "",
Position2: "/usr/include/sys/stdio.h:39:5",
Name: "renameat",
Type: "int (int, const char *, int, const char *)",
IsExtern: false,
IsImplicit: false,
IsUsed: false,
IsReferenced: false,
Children: []Node{},
},
`0x7fb5a90e9b70 </usr/include/stdio.h:244:6> col:6 implicit fprintf 'int (FILE *, const char *, ...)' extern`: &FunctionDecl{
Address: "0x7fb5a90e9b70",
Position: "/usr/include/stdio.h:244:6",
Prev: "",
Position2: "col:6",
Name: "fprintf",
Type: "int (FILE *, const char *, ...)",
IsExtern: true,
IsImplicit: true,
IsUsed: false,
Children: []Node{},
Address: "0x7fb5a90e9b70",
Position: "/usr/include/stdio.h:244:6",
Prev: "",
Position2: "col:6",
Name: "fprintf",
Type: "int (FILE *, const char *, ...)",
IsExtern: true,
IsImplicit: true,
IsUsed: false,
IsReferenced: false,
Children: []Node{},
},
`0x7fb5a90e9d40 prev 0x7fb5a90e9b70 <col:1, /usr/include/sys/cdefs.h:351:63> /usr/include/stdio.h:244:6 fprintf 'int (FILE *, const char *, ...)'`: &FunctionDecl{
Address: "0x7fb5a90e9d40",
Position: "col:1, /usr/include/sys/cdefs.h:351:63",
Prev: "0x7fb5a90e9b70",
Position2: "/usr/include/stdio.h:244:6",
Name: "fprintf",
Type: "int (FILE *, const char *, ...)",
IsExtern: false,
IsImplicit: false,
IsUsed: false,
Children: []Node{},
Address: "0x7fb5a90e9d40",
Position: "col:1, /usr/include/sys/cdefs.h:351:63",
Prev: "0x7fb5a90e9b70",
Position2: "/usr/include/stdio.h:244:6",
Name: "fprintf",
Type: "int (FILE *, const char *, ...)",
IsExtern: false,
IsImplicit: false,
IsUsed: false,
IsReferenced: false,
Children: []Node{},
},
`0x7fb5a90ec210 <line:259:6> col:6 implicit used printf 'int (const char *, ...)' extern`: &FunctionDecl{
Address: "0x7fb5a90ec210",
Position: "line:259:6",
Prev: "",
Position2: "col:6",
Name: "printf",
Type: "int (const char *, ...)",
IsExtern: true,
IsImplicit: true,
IsUsed: true,
Children: []Node{},
Address: "0x7fb5a90ec210",
Position: "line:259:6",
Prev: "",
Position2: "col:6",
Name: "printf",
Type: "int (const char *, ...)",
IsExtern: true,
IsImplicit: true,
IsUsed: true,
IsReferenced: false,
Children: []Node{},
},
`0x2ae30d8 </usr/include/math.h:65:3, /usr/include/x86_64-linux-gnu/sys/cdefs.h:57:54> <scratch space>:17:1 __acos 'double (double)' extern`: &FunctionDecl{
Address: "0x2ae30d8",
Position: "/usr/include/math.h:65:3, /usr/include/x86_64-linux-gnu/sys/cdefs.h:57:54",
Prev: "",
Position2: "<scratch space>:17:1",
Name: "__acos",
Type: "double (double)",
IsExtern: true,
IsImplicit: false,
IsUsed: false,
Children: []Node{},
Address: "0x2ae30d8",
Position: "/usr/include/math.h:65:3, /usr/include/x86_64-linux-gnu/sys/cdefs.h:57:54",
Prev: "",
Position2: "<scratch space>:17:1",
Name: "__acos",
Type: "double (double)",
IsExtern: true,
IsImplicit: false,
IsUsed: false,
IsReferenced: false,
Children: []Node{},
},
`0x7fc595071500 <line:26:1, line:69:1> line:26:5 referenced main 'int (int, char **)'`: &FunctionDecl{
Address: "0x7fc595071500",
Position: "line:26:1, line:69:1",
Prev: "",
Position2: "line:26:5",
Name: "main",
Type: "int (int, char **)",
IsExtern: false,
IsImplicit: false,
IsUsed: false,
IsReferenced: true,
Children: []Node{},
},
}

Expand Down
7 changes: 3 additions & 4 deletions ast/unary_expr_or_type_trait_expr.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,11 @@ type UnaryExprOrTypeTraitExpr struct {
}

func parseUnaryExprOrTypeTraitExpr(line string) *UnaryExprOrTypeTraitExpr {
// 0x7fccd70adf50 <col:29, col:40> 'unsigned long' sizeof 'char'
groups := groupsFromRegex(
`<(?P<position>.*)>
'(?P<type1>.+?)'
(?P<function>.+?)
'(?P<type2>.+?)'`,
(?P<function>[^ ]+)
(?P<type2> '.+?')?`,
line,
)

Expand All @@ -24,7 +23,7 @@ func parseUnaryExprOrTypeTraitExpr(line string) *UnaryExprOrTypeTraitExpr {
Position: groups["position"],
Type1: groups["type1"],
Function: groups["function"],
Type2: groups["type2"],
Type2: removeQuotes(groups["type2"]),
Children: []Node{},
}
}
Expand Down
8 changes: 8 additions & 0 deletions ast/unary_expr_or_type_trait_expr_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,14 @@ func TestUnaryExprOrTypeTraitExpr(t *testing.T) {
Type2: "char",
Children: []Node{},
},
`0x7fae1a800190 <col:36, col:44> 'unsigned long' sizeof`: &UnaryExprOrTypeTraitExpr{
Address: "0x7fae1a800190",
Position: "col:36, col:44",
Type1: "unsigned long",
Function: "sizeof",
Type2: "",
Children: []Node{},
},
}

runNodeTests(t, nodes)
Expand Down
43 changes: 23 additions & 20 deletions ast/var_decl.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,22 +5,24 @@ import (
)

type VarDecl struct {
Address string
Position string
Position2 string
Name string
Type string
Type2 string
IsExtern bool
IsUsed bool
IsCInit bool
Children []Node
Address string
Position string
Position2 string
Name string
Type string
Type2 string
IsExtern bool
IsUsed bool
IsCInit bool
IsReferenced bool
Children []Node
}

func parseVarDecl(line string) *VarDecl {
groups := groupsFromRegex(
`<(?P<position>.*)>(?P<position2> .+:\d+)?
(?P<used> used)?
(?P<referenced> referenced)?
(?P<name> \w+)?
'(?P<type>.+?)'
(?P<type2>:'.*?')?
Expand All @@ -35,16 +37,17 @@ func parseVarDecl(line string) *VarDecl {
}

return &VarDecl{
Address: groups["address"],
Position: groups["position"],
Position2: strings.TrimSpace(groups["position2"]),
Name: strings.TrimSpace(groups["name"]),
Type: groups["type"],
Type2: type2,
IsExtern: len(groups["extern"]) > 0,
IsUsed: len(groups["used"]) > 0,
IsCInit: len(groups["cinit"]) > 0,
Children: []Node{},
Address: groups["address"],
Position: groups["position"],
Position2: strings.TrimSpace(groups["position2"]),
Name: strings.TrimSpace(groups["name"]),
Type: groups["type"],
Type2: type2,
IsExtern: len(groups["extern"]) > 0,
IsUsed: len(groups["used"]) > 0,
IsCInit: len(groups["cinit"]) > 0,
IsReferenced: len(groups["referenced"]) > 0,
Children: []Node{},
}
}

Expand Down
Loading

0 comments on commit 74b761f

Please sign in to comment.