Skip to content

Commit

Permalink
Merge pull request #30 from elliotchance/ctype
Browse files Browse the repository at this point in the history
ctype.h
  • Loading branch information
elliotchance authored Apr 23, 2017
2 parents 778a44c + 0eaa5de commit b9483e5
Show file tree
Hide file tree
Showing 60 changed files with 1,376 additions and 158 deletions.
12 changes: 10 additions & 2 deletions ast/array_subscript_expr.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"fmt"

"github.com/elliotchance/c2go/program"
"github.com/elliotchance/c2go/types"
)

type ArraySubscriptExpr struct {
Expand Down Expand Up @@ -31,10 +32,17 @@ func parseArraySubscriptExpr(line string) *ArraySubscriptExpr {

func (n *ArraySubscriptExpr) render(program *program.Program) (string, string) {
children := n.Children
expression, _ := renderExpression(program, children[0])
expression, expressionType := renderExpression(program, children[0])
index, _ := renderExpression(program, children[1])
src := fmt.Sprintf("%s[%s]", expression, index)
return src, "unknown1"

newType, err := types.GetDereferenceType(expressionType)
if err != nil {
panic(fmt.Sprintf("Cannot dereference type '%s' for the expression '%s'",
expressionType, expression))
}

return src, newType
}

func (n *ArraySubscriptExpr) AddChild(node Node) {
Expand Down
20 changes: 18 additions & 2 deletions ast/ast.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,8 @@ func Parse(line string) Node {
return parseDeclStmt(line)
case "DeprecatedAttr":
return parseDeprecatedAttr(line)
case "DoStmt":
return parseDoStmt(line)
case "ElaboratedType":
return parseElaboratedType(line)
case "Enum":
Expand Down Expand Up @@ -93,12 +95,16 @@ func Parse(line string) Node {
return parseNonNullAttr(line)
case "ParenExpr":
return parseParenExpr(line)
case "ParenType":
return parseParenType(line)
case "ParmVarDecl":
return parseParmVarDecl(line)
case "PointerType":
return parsePointerType(line)
case "PredefinedExpr":
return parsePredefinedExpr(line)
case "PureAttr":
return parsePureAttr(line)
case "QualType":
return parseQualType(line)
case "Record":
Expand All @@ -115,6 +121,8 @@ func Parse(line string) Node {
return parseStringLiteral(line)
case "TranslationUnitDecl":
return parseTranslationUnitDecl(line)
case "TransparentUnionAttr":
return parseTransparentUnionAttr(line)
case "Typedef":
return parseTypedef(line)
case "TypedefDecl":
Expand All @@ -125,12 +133,14 @@ func Parse(line string) Node {
return parseUnaryOperator(line)
case "VarDecl":
return parseVarDecl(line)
case "WarnUnusedResultAttr":
return parseWarnUnusedResultAttr(line)
case "WhileStmt":
return parseWhileStmt(line)
case "NullStmt":
return nil
default:
panic("Unknown node type: '" + line + "'")
panic("unknown node type: '" + line + "'")
}
}

Expand Down Expand Up @@ -197,5 +207,11 @@ func getFunctionReturnType(f string) string {
//
// The arguments will handle themselves, we only care about the
// return type ('int' in this case)
return strings.TrimSpace(strings.Split(f, "(")[0])
returnType := strings.TrimSpace(strings.Split(f, "(")[0])

if returnType == "" {
panic(fmt.Sprintf("unable to extract the return type from: %s", f))
}

return returnType
}
69 changes: 68 additions & 1 deletion ast/ast_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -269,6 +269,13 @@ var nodes = map[string]Node{
Children: []Node{},
},

// DoStmt
`0x7ff36d0a0938 <line:11:5, line:14:23>`: &DoStmt{
Address: "0x7ff36d0a0938",
Position: "line:11:5, line:14:23",
Children: []interface{}{},
},

// ElaboratedType
`0x7f873686c120 'union __mbstate_t' sugar`: &ElaboratedType{
Address: "0x7f873686c120",
Expand Down Expand Up @@ -610,11 +617,29 @@ var nodes = map[string]Node{
`0x7fa1488273b0 <line:7:4, line:11:4> 1`: &NonNullAttr{
Address: "0x7fa1488273b0",
Position: "line:7:4, line:11:4",
A: 1,
B: 0,
Children: []Node{},
},
`0x2cce280 </sys/cdefs.h:286:44, /bits/mathcalls.h:115:69> 1`: &NonNullAttr{
Address: "0x2cce280",
Position: "/sys/cdefs.h:286:44, /bits/mathcalls.h:115:69",
A: 1,
B: 0,
Children: []Node{},
},
`0x201ede0 <line:145:79, col:93> 0`: &NonNullAttr{
Address: "0x201ede0",
Position: "line:145:79, col:93",
A: 0,
B: 0,
Children: []Node{},
},
`0x1b89b20 <col:76, col:93> 2 3`: &NonNullAttr{
Address: "0x1b89b20",
Position: "col:76, col:93",
A: 2,
B: 3,
Children: []Node{},
},

Expand All @@ -626,6 +651,14 @@ var nodes = map[string]Node{
Children: []Node{},
},

// ParenType
`0x7faf820a4c60 'void (int)' sugar`: &ParenType{
Address: "0x7faf820a4c60",
Type: "void (int)",
Sugar: true,
Children: []interface{}{},
},

// ParmVarDecl
`0x7f973380f000 <col:14> col:17 'int'`: &ParmVarDecl{
Address: "0x7f973380f000",
Expand Down Expand Up @@ -715,6 +748,22 @@ var nodes = map[string]Node{
Children: []Node{},
},

// PureAttr
`0x7fe9eb899198 <col:1> Implicit`: &PureAttr{
Address: "0x7fe9eb899198",
Position: "col:1",
Implicit: true,
Inherited: false,
Children: []interface{}{},
},
`0x7fe8d60992a0 <col:1> Inherited Implicit`: &PureAttr{
Address: "0x7fe8d60992a0",
Position: "col:1",
Implicit: true,
Inherited: true,
Children: []interface{}{},
},

// QualType
`0x7fa3b88bbb31 'struct _opaque_pthread_t *' foo`: &QualType{
Address: "0x7fa3b88bbb31",
Expand Down Expand Up @@ -800,6 +849,13 @@ var nodes = map[string]Node{
Children: []Node{},
},

// TransparentUnionAttr
`0x304f700 <col:35>`: &TransparentUnionAttr{
Address: "0x304f700",
Position: "col:35",
Children: []Node{},
},

// Typedef
`0x7f84d10dc1d0 '__darwin_ssize_t'`: &Typedef{
Address: "0x7f84d10dc1d0",
Expand Down Expand Up @@ -874,7 +930,6 @@ var nodes = map[string]Node{
IsReferenced: false,
Children: []Node{},
},
// Issue: #26
`0x55b9da8784b0 <line:341:1, line:342:16> line:341:19 __io_write_fn '__ssize_t (void *, const char *, size_t)'`: &TypedefDecl{
Address: "0x55b9da8784b0",
Position: "line:341:1, line:342:16",
Expand Down Expand Up @@ -986,6 +1041,18 @@ var nodes = map[string]Node{
Children: []Node{},
},

// WarnUnusedResultAttr
`0x7fa1d704d420 <col:60> warn_unused_result`: &WarnUnusedResultAttr{
Address: "0x7fa1d704d420",
Position: "col:60",
Children: []interface{}{},
},
`0x1fac810 <line:481:52>`: &WarnUnusedResultAttr{
Address: "0x1fac810",
Position: "line:481:52",
Children: []interface{}{},
},

// WhileStmt
`0x7fa1478273a0 <line:7:4, line:11:4>`: &WhileStmt{
Address: "0x7fa1478273a0",
Expand Down
3 changes: 2 additions & 1 deletion ast/availability_attr.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package ast

import (
"github.com/elliotchance/c2go/program"
"github.com/elliotchance/c2go/util"
)

type AvailabilityAttr struct {
Expand Down Expand Up @@ -36,7 +37,7 @@ func parseAvailabilityAttr(line string) *AvailabilityAttr {
OS: groups["os"],
Version: groups["version"],
Unknown1: atof(groups["unknown1"]),
Unknown2: atoi(groups["unknown2"]),
Unknown2: util.Atoi(groups["unknown2"]),
Unavailable: len(groups["unavalable"]) > 0,
Message1: removeQuotes(groups["message1"]),
Message2: removeQuotes(groups["message2"]),
Expand Down
22 changes: 11 additions & 11 deletions ast/binary_operator.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import (

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

type BinaryOperator struct {
Expand Down Expand Up @@ -33,27 +32,28 @@ func parseBinaryOperator(line string) *BinaryOperator {

func (n *BinaryOperator) render(program *program.Program) (string, string) {
operator := n.Operator

left, leftType := renderExpression(program, n.Children[0])
right, rightType := renderExpression(program, n.Children[1])

return_type := "bool"
if util.InStrings(operator, []string{"|", "&", "+", "-", "*", "/"}) {
// TODO: The left and right type might be different
return_type = leftType
}
returnType := types.ResolveTypeForBinaryOperator(program, operator, leftType, rightType)

if operator == "&&" {
left = types.Cast(program, left, leftType, return_type)
right = types.Cast(program, right, rightType, return_type)
left = types.Cast(program, left, leftType, "bool")
right = types.Cast(program, right, rightType, "bool")

src := fmt.Sprintf("%s %s %s", left, operator, right)
return types.Cast(program, src, "bool", returnType), returnType
}

if (operator == "!=" || operator == "==") && right == "(0)" {
right = "nil"
}

if operator == "=" {
right = types.Cast(program, right, rightType, returnType)
}

src := fmt.Sprintf("%s %s %s", left, operator, right)
return src, return_type
return src, returnType
}

func (n *BinaryOperator) AddChild(node Node) {
Expand Down
23 changes: 13 additions & 10 deletions ast/call_expr.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,30 +31,33 @@ func parseCallExpr(line string) *CallExpr {

func (n *CallExpr) render(program *program.Program) (string, string) {
children := n.Children
func_name, _ := renderExpression(program, children[0])
functionName, _ := renderExpression(program, children[0])
functionDef := getFunctionDefinition(functionName)

func_def := getFunctionDefinition(func_name)
if functionDef == nil {
panic(fmt.Sprintf("unknown function: %s", functionName))
}

if func_def.Substitution != "" {
parts := strings.Split(func_def.Substitution, ".")
if functionDef.Substitution != "" {
parts := strings.Split(functionDef.Substitution, ".")
program.AddImport(strings.Join(parts[:len(parts)-1], "."))

parts2 := strings.Split(func_def.Substitution, "/")
func_name = parts2[len(parts2)-1]
parts2 := strings.Split(functionDef.Substitution, "/")
functionName = parts2[len(parts2)-1]
}

args := []string{}
i := 0
for _, arg := range children[1:] {
e, eType := renderExpression(program, arg)

if i > len(func_def.ArgumentTypes)-1 {
if i > len(functionDef.ArgumentTypes)-1 {
// This means the argument is one of the varargs
// so we don't know what type it needs to be
// cast to.
args = append(args, e)
} else {
args = append(args, types.Cast(program, e, eType, func_def.ArgumentTypes[i]))
args = append(args, types.Cast(program, e, eType, functionDef.ArgumentTypes[i]))
}

i++
Expand All @@ -66,8 +69,8 @@ func (n *CallExpr) render(program *program.Program) (string, string) {
parts = append(parts, v)
}

src := fmt.Sprintf("%s(%s)", func_name, strings.Join(parts, ", "))
return src, func_def.ReturnType
src := fmt.Sprintf("%s(%s)", functionName, strings.Join(parts, ", "))
return src, functionDef.ReturnType
}

func (n *CallExpr) AddChild(node Node) {
Expand Down
16 changes: 14 additions & 2 deletions ast/character_literal.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
package ast

import (
"fmt"

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

type CharacterLiteral struct {
Expand All @@ -22,13 +25,22 @@ func parseCharacterLiteral(line string) *CharacterLiteral {
Address: groups["address"],
Position: groups["position"],
Type: groups["type"],
Value: atoi(groups["value"]),
Value: util.Atoi(groups["value"]),
Children: []Node{},
}
}

func (n *CharacterLiteral) render(program *program.Program) (string, string) {
return "", ""
var s string

switch n.Value {
case '\n':
s = "'\\n'"
default:
s = fmt.Sprintf("'%c'", n.Value)
}

return s, n.Type
}

func (n *CharacterLiteral) AddChild(node Node) {
Expand Down
3 changes: 2 additions & 1 deletion ast/constant_array_type.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package ast

import (
"github.com/elliotchance/c2go/program"
"github.com/elliotchance/c2go/util"
)

type ConstantArrayType struct {
Expand All @@ -20,7 +21,7 @@ func parseConstantArrayType(line string) *ConstantArrayType {
return &ConstantArrayType{
Address: groups["address"],
Type: groups["type"],
Size: atoi(groups["size"]),
Size: util.Atoi(groups["size"]),
Children: []Node{},
}
}
Expand Down
Loading

0 comments on commit b9483e5

Please sign in to comment.