From 75672ede91bd02f2f3216d99429a6f86e9009877 Mon Sep 17 00:00:00 2001 From: Elliot Chance Date: Fri, 14 Apr 2017 16:20:12 +1000 Subject: [PATCH 1/9] Clean up function definitions --- always_inline_attr.go | 2 +- array_subscript_expr.go | 6 +- asm_label_attr.go | 6 +- ast.go | 8 +- ast_test.go | 1344 ++++++++++++++++++-------------------- availability_attr.go | 20 +- binary_operator.go | 4 +- break_stmt.go | 2 +- builtin_type.go | 8 +- c_style_cast_expr.go | 6 +- call_expr.go | 4 +- character_literal.go | 6 +- common.go | 105 ++- compound_stmt.go | 2 +- conditional_operator.go | 6 +- const_attr.go | 4 +- constant_array_type.go | 12 +- darwin/common.go | 28 +- decl_ref_expr.go | 12 +- decl_stmt.go | 2 +- deprecated_attr.go | 2 +- elaborated_type.go | 6 +- enum.go | 8 +- enum_constant_decl.go | 12 +- enum_decl.go | 10 +- enum_type.go | 8 +- field_decl.go | 14 +- floating_literal.go | 6 +- for_stmt.go | 2 +- format_attr.go | 14 +- function_decl.go | 22 +- function_definition.go | 85 +++ function_proto_type.go | 12 +- if_stmt.go | 2 +- implicit_cast_expr.go | 6 +- integer_literal.go | 6 +- main_test.go | 2 +- malloc_attr.go | 2 +- member_expr.go | 8 +- mode_attr.go | 4 +- no_throw_attr.go | 2 +- non_null_attr.go | 2 +- paren_expr.go | 4 +- parm_var_decl.go | 18 +- pointer_type.go | 8 +- predefined_expr.go | 8 +- qual_type.go | 12 +- record.go | 8 +- record_decl.go | 18 +- record_type.go | 8 +- restrict_attr.go | 4 +- return_stmt.go | 2 +- string_literal.go | 8 +- translation_unit_decl.go | 4 +- typedef.go | 8 +- typedef_decl.go | 18 +- typedef_type.go | 12 +- unary_operator.go | 4 +- var_decl.go | 20 +- while_stmt.go | 2 +- 60 files changed, 962 insertions(+), 1026 deletions(-) create mode 100644 function_definition.go diff --git a/always_inline_attr.go b/always_inline_attr.go index e1ab7a75f..cde351b27 100644 --- a/always_inline_attr.go +++ b/always_inline_attr.go @@ -13,7 +13,7 @@ func parseAlwaysInlineAttr(line string) *AlwaysInlineAttr { ) return &AlwaysInlineAttr{ - Address: groups["address"], + Address: groups["address"], Position: groups["position"], Children: []interface{}{}, } diff --git a/array_subscript_expr.go b/array_subscript_expr.go index d85119765..bc9d0c9d4 100644 --- a/array_subscript_expr.go +++ b/array_subscript_expr.go @@ -15,10 +15,10 @@ func parseArraySubscriptExpr(line string) *ArraySubscriptExpr { ) return &ArraySubscriptExpr{ - Address: groups["address"], + Address: groups["address"], Position: groups["position"], - Type: groups["type"], - Kind: groups["kind"], + Type: groups["type"], + Kind: groups["kind"], Children: []interface{}{}, } } diff --git a/asm_label_attr.go b/asm_label_attr.go index 846e9b13d..ce50a59e5 100644 --- a/asm_label_attr.go +++ b/asm_label_attr.go @@ -14,9 +14,9 @@ func parseAsmLabelAttr(line string) *AsmLabelAttr { ) return &AsmLabelAttr{ - Address: groups["address"], - Position: groups["position"], + Address: groups["address"], + Position: groups["position"], FunctionName: groups["function"], - Children: []interface{}{}, + Children: []interface{}{}, } } diff --git a/ast.go b/ast.go index 096e76acf..88156ecfd 100644 --- a/ast.go +++ b/ast.go @@ -169,11 +169,11 @@ func removeQuotes(s string) string { return "" } - if len(s) >= 2 && s[0] == '"' && s[len(s) - 1] == '"' { - return s[1:len(s) - 2] + if len(s) >= 2 && s[0] == '"' && s[len(s)-1] == '"' { + return s[1 : len(s)-2] } - if len(s) >= 2 && s[0] == '\'' && s[len(s) - 1] == '\'' { - return s[1:len(s) - 1] + if len(s) >= 2 && s[0] == '\'' && s[len(s)-1] == '\'' { + return s[1 : len(s)-1] } return s diff --git a/ast_test.go b/ast_test.go index 5b992bb8b..bae3f2a5f 100644 --- a/ast_test.go +++ b/ast_test.go @@ -1,297 +1,268 @@ package main import ( - "testing" "reflect" + "testing" ) var nodes = map[string]interface{}{ // AlwaysInlineAttr - `0x7fce780f5018 always_inline`: - &AlwaysInlineAttr{ - Address: "0x7fce780f5018", + `0x7fce780f5018 always_inline`: &AlwaysInlineAttr{ + Address: "0x7fce780f5018", Position: "/usr/include/sys/cdefs.h:313:68", Children: []interface{}{}, }, // ArraySubscriptExpr - `0x7fe35b85d180 'char *' lvalue`: - &ArraySubscriptExpr{ - Address: "0x7fe35b85d180", + `0x7fe35b85d180 'char *' lvalue`: &ArraySubscriptExpr{ + Address: "0x7fe35b85d180", Position: "col:63, col:69", - Type: "char *", - Kind: "lvalue", + Type: "char *", + Kind: "lvalue", Children: []interface{}{}, }, // AsmLabelAttr - `0x7ff26d8224e8 "_fopen"`: - &AsmLabelAttr{ - Address: "0x7ff26d8224e8", - Position: "/usr/include/sys/cdefs.h:569:36", + `0x7ff26d8224e8 "_fopen"`: &AsmLabelAttr{ + Address: "0x7ff26d8224e8", + Position: "/usr/include/sys/cdefs.h:569:36", FunctionName: "_fopen", - Children: []interface{}{}, + Children: []interface{}{}, }, // AvailabilityAttr - `0x7fc5ff8e5d18 macos 10.10 0 0 "" ""`: - &AvailabilityAttr{ - Address: "0x7fc5ff8e5d18", - Position: "/usr/include/AvailabilityInternal.h:21697:88, col:124", - OS: "macos", - Version: "10.10", - Unknown1: 0, - Unknown2: 0, + `0x7fc5ff8e5d18 macos 10.10 0 0 "" ""`: &AvailabilityAttr{ + Address: "0x7fc5ff8e5d18", + Position: "/usr/include/AvailabilityInternal.h:21697:88, col:124", + OS: "macos", + Version: "10.10", + Unknown1: 0, + Unknown2: 0, Unavailable: false, - Message1: "", - Message2: "", - Children: []interface{}{}, - }, - `0x7fc5ff8e60d0 watchos 3.0 0 0 "" ""`: - &AvailabilityAttr{ - Address: "0x7fc5ff8e60d0", - Position: "/usr/include/Availability.h:215:81, col:115", - OS: "watchos", - Version: "3.0", - Unknown1: 0, - Unknown2: 0, + Message1: "", + Message2: "", + Children: []interface{}{}, + }, + `0x7fc5ff8e60d0 watchos 3.0 0 0 "" ""`: &AvailabilityAttr{ + Address: "0x7fc5ff8e60d0", + Position: "/usr/include/Availability.h:215:81, col:115", + OS: "watchos", + Version: "3.0", + Unknown1: 0, + Unknown2: 0, Unavailable: false, - Message1: "", - Message2: "", - Children: []interface{}{}, - }, - `0x7fc5ff8e6170 tvos 10.0 0 0 "" ""`: - &AvailabilityAttr{ - Address: "0x7fc5ff8e6170", - Position: "col:81, col:115", - OS: "tvos", - Version: "10.0", - Unknown1: 0, - Unknown2: 0, + Message1: "", + Message2: "", + Children: []interface{}{}, + }, + `0x7fc5ff8e6170 tvos 10.0 0 0 "" ""`: &AvailabilityAttr{ + Address: "0x7fc5ff8e6170", + Position: "col:81, col:115", + OS: "tvos", + Version: "10.0", + Unknown1: 0, + Unknown2: 0, Unavailable: false, - Message1: "", - Message2: "", - Children: []interface{}{}, - }, - `0x7fc5ff8e61d8 ios 10.0 0 0 "" ""`: - &AvailabilityAttr{ - Address: "0x7fc5ff8e61d8", - Position: "col:81, col:115", - OS: "ios", - Version: "10.0", - Unknown1: 0, - Unknown2: 0, + Message1: "", + Message2: "", + Children: []interface{}{}, + }, + `0x7fc5ff8e61d8 ios 10.0 0 0 "" ""`: &AvailabilityAttr{ + Address: "0x7fc5ff8e61d8", + Position: "col:81, col:115", + OS: "ios", + Version: "10.0", + Unknown1: 0, + Unknown2: 0, Unavailable: false, - Message1: "", - Message2: "", - Children: []interface{}{}, - }, - `0x7fc5ff8f0e18 swift 0 0 0 Unavailable "Use snprintf instead." ""`: - &AvailabilityAttr{ - Address: "0x7fc5ff8f0e18", - Position: "/usr/include/sys/cdefs.h:275:50, col:99", - OS: "swift", - Version: "0", - Unknown1: 0, - Unknown2: 0, + Message1: "", + Message2: "", + Children: []interface{}{}, + }, + `0x7fc5ff8f0e18 swift 0 0 0 Unavailable "Use snprintf instead." ""`: &AvailabilityAttr{ + Address: "0x7fc5ff8f0e18", + Position: "/usr/include/sys/cdefs.h:275:50, col:99", + OS: "swift", + Version: "0", + Unknown1: 0, + Unknown2: 0, Unavailable: true, - Message1: "Use snprintf instead.", - Message2: "", - Children: []interface{}{}, - }, - `0x7fc5ff8f1988 swift 0 0 0 Unavailable "Use mkstemp(3) instead." ""`: - &AvailabilityAttr{ - Address: "0x7fc5ff8f1988", - Position: "line:275:50, col:99", - OS: "swift", - Version: "0", - Unknown1: 0, - Unknown2: 0, + Message1: "Use snprintf instead.", + Message2: "", + Children: []interface{}{}, + }, + `0x7fc5ff8f1988 swift 0 0 0 Unavailable "Use mkstemp(3) instead." ""`: &AvailabilityAttr{ + Address: "0x7fc5ff8f1988", + Position: "line:275:50, col:99", + OS: "swift", + Version: "0", + Unknown1: 0, + Unknown2: 0, Unavailable: true, - Message1: "Use mkstemp(3) instead.", - Message2: "", - Children: []interface{}{}, - }, - `0x104035438 macosx 10.10 0 0 ""`: - &AvailabilityAttr{ - Address: "0x104035438", - Position: "/usr/include/AvailabilityInternal.h:14571:88, col:124", - OS: "macosx", - Version: "10.10", - Unknown1: 0, - Unknown2: 0, + Message1: "Use mkstemp(3) instead.", + Message2: "", + Children: []interface{}{}, + }, + `0x104035438 macosx 10.10 0 0 ""`: &AvailabilityAttr{ + Address: "0x104035438", + Position: "/usr/include/AvailabilityInternal.h:14571:88, col:124", + OS: "macosx", + Version: "10.10", + Unknown1: 0, + Unknown2: 0, Unavailable: false, - Message1: "", - Message2: "", - Children: []interface{}{}, + Message1: "", + Message2: "", + Children: []interface{}{}, }, // BinaryOperator - `0x7fca2d8070e0 'unsigned char' '='`: - &BinaryOperator{ - Address: "0x7fca2d8070e0", + `0x7fca2d8070e0 'unsigned char' '='`: &BinaryOperator{ + Address: "0x7fca2d8070e0", Position: "col:11, col:23", - Type: "unsigned char", + Type: "unsigned char", Operator: "=", Children: []interface{}{}, }, // BreakStmt - `0x7fca2d8070e0 `: - &BreakStmt{ - Address: "0x7fca2d8070e0", + `0x7fca2d8070e0 `: &BreakStmt{ + Address: "0x7fca2d8070e0", Position: "col:11, col:23", Children: []interface{}{}, }, // BuiltinType - `0x7f8a43023f40 '__int128'`: - &BuiltinType{ - Address: "0x7f8a43023f40", - Type: "__int128", + `0x7f8a43023f40 '__int128'`: &BuiltinType{ + Address: "0x7f8a43023f40", + Type: "__int128", Children: []interface{}{}, }, - `0x7f8a43023ea0 'unsigned long long'`: - &BuiltinType{ - Address: "0x7f8a43023ea0", - Type: "unsigned long long", + `0x7f8a43023ea0 'unsigned long long'`: &BuiltinType{ + Address: "0x7f8a43023ea0", + Type: "unsigned long long", Children: []interface{}{}, }, // CallExpr - `0x7f9bf3033240 'int'`: - &CallExpr{ - Address: "0x7f9bf3033240", + `0x7f9bf3033240 'int'`: &CallExpr{ + Address: "0x7f9bf3033240", Position: "col:11, col:25", - Type: "int", + Type: "int", Children: []interface{}{}, }, - `0x7f9bf3035c20 'int'`: - &CallExpr{ - Address: "0x7f9bf3035c20", + `0x7f9bf3035c20 'int'`: &CallExpr{ + Address: "0x7f9bf3035c20", Position: "line:7:4, col:64", - Type: "int", + Type: "int", Children: []interface{}{}, }, // CharacterLiteral - `0x7f980b858308 'int' 10`: - &CharacterLiteral{ - Address: "0x7f980b858308", + `0x7f980b858308 'int' 10`: &CharacterLiteral{ + Address: "0x7f980b858308", Position: "col:62", - Type: "int", - Value: 10, + Type: "int", + Value: 10, Children: []interface{}{}, }, // CompoundStmt - `0x7fbd0f014f18 `: - &CompoundStmt{ - Address: "0x7fbd0f014f18", + `0x7fbd0f014f18 `: &CompoundStmt{ + Address: "0x7fbd0f014f18", Position: "col:54, line:358:1", Children: []interface{}{}, }, - `0x7fbd0f8360b8 `: - &CompoundStmt{ - Address: "0x7fbd0f8360b8", + `0x7fbd0f8360b8 `: &CompoundStmt{ + Address: "0x7fbd0f8360b8", Position: "line:4:1, line:13:1", Children: []interface{}{}, }, // ConditionalOperator - `0x7fc6ae0bc678 'void'`: - &ConditionalOperator{ - Address: "0x7fc6ae0bc678", + `0x7fc6ae0bc678 'void'`: &ConditionalOperator{ + Address: "0x7fc6ae0bc678", Position: "col:6, col:89", - Type: "void", + Type: "void", Children: []interface{}{}, }, // ConstAttr - `0x7fa3b88bbb38 foo`: - &ConstAttr{ - Address: "0x7fa3b88bbb38", + `0x7fa3b88bbb38 foo`: &ConstAttr{ + Address: "0x7fa3b88bbb38", Position: "line:4:1, line:13:1", - Tags: "foo", + Tags: "foo", Children: []interface{}{}, }, // ConstantArrayType - `0x7f94ad016a40 'struct __va_list_tag [1]' 1`: - &ConstantArrayType{ - Address: "0x7f94ad016a40", - Type: "struct __va_list_tag [1]", - Size: 1, + `0x7f94ad016a40 'struct __va_list_tag [1]' 1`: &ConstantArrayType{ + Address: "0x7f94ad016a40", + Type: "struct __va_list_tag [1]", + Size: 1, Children: []interface{}{}, }, - `0x7f8c5f059d20 'char [37]' 37`: - &ConstantArrayType{ - Address: "0x7f8c5f059d20", - Type: "char [37]", - Size: 37, + `0x7f8c5f059d20 'char [37]' 37`: &ConstantArrayType{ + Address: "0x7f8c5f059d20", + Type: "char [37]", + Size: 37, Children: []interface{}{}, }, // CStyleCastExpr - `0x7fddc18fb2e0 'char' `: - &CStyleCastExpr{ - Address: "0x7fddc18fb2e0", + `0x7fddc18fb2e0 'char' `: &CStyleCastExpr{ + Address: "0x7fddc18fb2e0", Position: "col:50, col:56", - Type: "char", - Kind: "IntegralCast", + Type: "char", + Kind: "IntegralCast", Children: []interface{}{}, }, // DeclRefExpr - `0x7fc972064460 'FILE *' lvalue ParmVar 0x7fc9720642d0 '_p' 'FILE *'`: - &DeclRefExpr{ - Address: "0x7fc972064460", + `0x7fc972064460 'FILE *' lvalue ParmVar 0x7fc9720642d0 '_p' 'FILE *'`: &DeclRefExpr{ + Address: "0x7fc972064460", Position: "col:8", - Type: "FILE *", - Lvalue: true, - For: "ParmVar", + Type: "FILE *", + Lvalue: true, + For: "ParmVar", Address2: "0x7fc9720642d0", - Name: "_p", - Type2: "FILE *", + Name: "_p", + Type2: "FILE *", Children: []interface{}{}, }, - `0x7fc97206a958 'int (int, FILE *)' Function 0x7fc972064198 '__swbuf' 'int (int, FILE *)'`: - &DeclRefExpr{ - Address: "0x7fc97206a958", + `0x7fc97206a958 'int (int, FILE *)' Function 0x7fc972064198 '__swbuf' 'int (int, FILE *)'`: &DeclRefExpr{ + Address: "0x7fc97206a958", Position: "col:11", - Type: "int (int, FILE *)", - Lvalue: false, - For: "Function", + Type: "int (int, FILE *)", + Lvalue: false, + For: "Function", Address2: "0x7fc972064198", - Name: "__swbuf", - Type2: "int (int, FILE *)", + Name: "__swbuf", + Type2: "int (int, FILE *)", Children: []interface{}{}, }, - `0x7fa36680f170 'struct programming':'struct programming' lvalue Var 0x7fa36680dc20 'variable' 'struct programming':'struct programming'`: - &DeclRefExpr{ - Address: "0x7fa36680f170", + `0x7fa36680f170 'struct programming':'struct programming' lvalue Var 0x7fa36680dc20 'variable' 'struct programming':'struct programming'`: &DeclRefExpr{ + Address: "0x7fa36680f170", Position: "col:19", - Type: "struct programming", - Lvalue: true, - For: "Var", + Type: "struct programming", + Lvalue: true, + For: "Var", Address2: "0x7fa36680dc20", - Name: "variable", - Type2: "struct programming", + Name: "variable", + Type2: "struct programming", Children: []interface{}{}, }, // DeclStmt - `0x7fb791846e80 `: - &DeclStmt{ - Address: "0x7fb791846e80", + `0x7fb791846e80 `: &DeclStmt{ + Address: "0x7fb791846e80", Position: "line:11:4, col:31", Children: []interface{}{}, }, // DeprecatedAttr - `0x7fec4b0ab9c0 "This function is provided for compatibility reasons only. Due to security concerns inherent in the design of tempnam(3), it is highly recommended that you use mkstemp(3) instead." ""`: - &DeprecatedAttr{ - Address: "0x7fec4b0ab9c0", + `0x7fec4b0ab9c0 "This function is provided for compatibility reasons only. Due to security concerns inherent in the design of tempnam(3), it is highly recommended that you use mkstemp(3) instead." ""`: &DeprecatedAttr{ + Address: "0x7fec4b0ab9c0", Position: "line:180:48, col:63", Message1: "This function is provided for compatibility reasons only. Due to security concerns inherent in the design of tempnam(3), it is highly recommended that you use mkstemp(3) instead.", Message2: "", @@ -299,691 +270,624 @@ var nodes = map[string]interface{}{ }, // ElaboratedType - `0x7f873686c120 'union __mbstate_t' sugar`: - &ElaboratedType{ - Address: "0x7f873686c120", - Type: "union __mbstate_t", - Tags: "sugar", + `0x7f873686c120 'union __mbstate_t' sugar`: &ElaboratedType{ + Address: "0x7f873686c120", + Type: "union __mbstate_t", + Tags: "sugar", Children: []interface{}{}, }, // Enum - `0x7f980b858308 'foo'`: - &Enum{ - Address: "0x7f980b858308", - Name: "foo", + `0x7f980b858308 'foo'`: &Enum{ + Address: "0x7f980b858308", + Name: "foo", Children: []interface{}{}, }, // EnumDecl - `0x22a6c80 __codecvt_result`: - &EnumDecl{ - Address: "0x22a6c80", - Position: "line:180:1, line:186:1", + `0x22a6c80 __codecvt_result`: &EnumDecl{ + Address: "0x22a6c80", + Position: "line:180:1, line:186:1", Position2: "", - Name: "__codecvt_result", - Children: []interface{}{}, + Name: "__codecvt_result", + Children: []interface{}{}, }, // EnumConstantDecl - `0x1660db0 __codecvt_noconv 'int'`: - &EnumConstantDecl{ - Address: "0x1660db0", - Position: "line:185:3", + `0x1660db0 __codecvt_noconv 'int'`: &EnumConstantDecl{ + Address: "0x1660db0", + Position: "line:185:3", Position2: "", - Name: "__codecvt_noconv", - Type: "int", - Children: []interface{}{}, + Name: "__codecvt_noconv", + Type: "int", + Children: []interface{}{}, }, // EnumType - `0x7f980b858309 'foo'`: - &EnumType{ - Address: "0x7f980b858309", - Name: "foo", + `0x7f980b858309 'foo'`: &EnumType{ + Address: "0x7f980b858309", + Name: "foo", Children: []interface{}{}, }, // FieldDecl - `0x7fef510c4848 col:6 _ur 'int'`: - &FieldDecl{ - Address: "0x7fef510c4848", - Position: "line:141:2, col:6", - Position2: "col:6", - Name: "_ur", - Type: "int", + `0x7fef510c4848 col:6 _ur 'int'`: &FieldDecl{ + Address: "0x7fef510c4848", + Position: "line:141:2, col:6", + Position2: "col:6", + Name: "_ur", + Type: "int", Referenced: false, - Children: []interface{}{}, - }, - `0x7fef510c46f8 col:16 _ub 'struct __sbuf':'struct __sbuf'`: - &FieldDecl{ - Address: "0x7fef510c46f8", - Position: "line:139:2, col:16", - Position2: "col:16", - Name: "_ub", - Type: "struct __sbuf", + Children: []interface{}{}, + }, + `0x7fef510c46f8 col:16 _ub 'struct __sbuf':'struct __sbuf'`: &FieldDecl{ + Address: "0x7fef510c46f8", + Position: "line:139:2, col:16", + Position2: "col:16", + Name: "_ub", + Type: "struct __sbuf", Referenced: false, - Children: []interface{}{}, - }, - `0x7fef510c3fe0 col:19 _read 'int (* _Nullable)(void *, char *, int)':'int (*)(void *, char *, int)'`: - &FieldDecl{ - Address: "0x7fef510c3fe0", - Position: "line:134:2, col:19", - Position2: "col:19", - Name: "_read", - Type: "int (* _Nullable)(void *, char *, int)", + Children: []interface{}{}, + }, + `0x7fef510c3fe0 col:19 _read 'int (* _Nullable)(void *, char *, int)':'int (*)(void *, char *, int)'`: &FieldDecl{ + Address: "0x7fef510c3fe0", + Position: "line:134:2, col:19", + Position2: "col:19", + Name: "_read", + Type: "int (* _Nullable)(void *, char *, int)", Referenced: false, - Children: []interface{}{}, - }, - `0x7fef51073a60 col:40 __cleanup_stack 'struct __darwin_pthread_handler_rec *'`: - &FieldDecl{ - Address: "0x7fef51073a60", - Position: "line:105:2, col:40", - Position2: "col:40", - Name: "__cleanup_stack", - Type: "struct __darwin_pthread_handler_rec *", + Children: []interface{}{}, + }, + `0x7fef51073a60 col:40 __cleanup_stack 'struct __darwin_pthread_handler_rec *'`: &FieldDecl{ + Address: "0x7fef51073a60", + Position: "line:105:2, col:40", + Position2: "col:40", + Name: "__cleanup_stack", + Type: "struct __darwin_pthread_handler_rec *", Referenced: false, - Children: []interface{}{}, - }, - `0x7fef510738e8 col:7 __opaque 'char [16]'`: - &FieldDecl{ - Address: "0x7fef510738e8", - Position: "line:100:2, col:43", - Position2: "col:7", - Name: "__opaque", - Type: "char [16]", + Children: []interface{}{}, + }, + `0x7fef510738e8 col:7 __opaque 'char [16]'`: &FieldDecl{ + Address: "0x7fef510738e8", + Position: "line:100:2, col:43", + Position2: "col:7", + Name: "__opaque", + Type: "char [16]", Referenced: false, - Children: []interface{}{}, - }, - `0x7fe9f5072268 col:6 referenced _lbfsize 'int'`: - &FieldDecl{ - Address: "0x7fe9f5072268", - Position: "line:129:2, col:6", - Position2: "col:6", - Name: "_lbfsize", - Type: "int", + Children: []interface{}{}, + }, + `0x7fe9f5072268 col:6 referenced _lbfsize 'int'`: &FieldDecl{ + Address: "0x7fe9f5072268", + Position: "line:129:2, col:6", + Position2: "col:6", + Name: "_lbfsize", + Type: "int", Referenced: true, - Children: []interface{}{}, + Children: []interface{}{}, }, // FloatingLiteral - `0x7febe106f5e8 'double' 1.230000e+00`: - &FloatingLiteral{ - Address: "0x7febe106f5e8", + `0x7febe106f5e8 'double' 1.230000e+00`: &FloatingLiteral{ + Address: "0x7febe106f5e8", Position: "col:24", - Type: "double", - Value: 1.23, + Type: "double", + Value: 1.23, Children: []interface{}{}, }, // FormatAttr - `0x7fcc8d8ecee8 Implicit printf 2 3`: - &FormatAttr{ - Address: "0x7fcc8d8ecee8", - Position: "col:6", - Implicit: true, - Inherited: false, + `0x7fcc8d8ecee8 Implicit printf 2 3`: &FormatAttr{ + Address: "0x7fcc8d8ecee8", + Position: "col:6", + Implicit: true, + Inherited: false, FunctionName: "printf", - Unknown1: 2, - Unknown2: 3, - Children: []interface{}{}, - }, - `0x7fcc8d8ecff8 printf 2 3`: - &FormatAttr{ - Address: "0x7fcc8d8ecff8", - Position: "/usr/include/sys/cdefs.h:351:18, col:61", - Implicit: false, - Inherited: false, + Unknown1: 2, + Unknown2: 3, + Children: []interface{}{}, + }, + `0x7fcc8d8ecff8 printf 2 3`: &FormatAttr{ + Address: "0x7fcc8d8ecff8", + Position: "/usr/include/sys/cdefs.h:351:18, col:61", + Implicit: false, + Inherited: false, FunctionName: "printf", - Unknown1: 2, - Unknown2: 3, - Children: []interface{}{}, - }, - `0x273b4d0 Inherited printf 2 3`: - &FormatAttr{ - Address: "0x273b4d0", - Position: "line:357:12", - Implicit: false, - Inherited: true, + Unknown1: 2, + Unknown2: 3, + Children: []interface{}{}, + }, + `0x273b4d0 Inherited printf 2 3`: &FormatAttr{ + Address: "0x273b4d0", + Position: "line:357:12", + Implicit: false, + Inherited: true, FunctionName: "printf", - Unknown1: 2, - Unknown2: 3, - Children: []interface{}{}, + Unknown1: 2, + Unknown2: 3, + Children: []interface{}{}, }, // FunctionDecl - `0x7fb5a90e60d0 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, + `0x7fb5a90e60d0 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: []interface{}{}, - }, - `0x7fb5a90e2a50 /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, + IsUsed: false, + Children: []interface{}{}, + }, + `0x7fb5a90e2a50 /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: []interface{}{}, - }, - `0x7fb5a90e9b70 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, + IsUsed: false, + Children: []interface{}{}, + }, + `0x7fb5a90e9b70 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: []interface{}{}, - }, - `0x7fb5a90e9d40 prev 0x7fb5a90e9b70 /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, + IsUsed: false, + Children: []interface{}{}, + }, + `0x7fb5a90e9d40 prev 0x7fb5a90e9b70 /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: []interface{}{}, - }, - `0x7fb5a90ec210 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, + IsUsed: false, + Children: []interface{}{}, + }, + `0x7fb5a90ec210 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: []interface{}{}, - }, - `0x2ae30d8 :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: ":17:1", - Name: "__acos", - Type: "double (double)", - IsExtern: true, + IsUsed: true, + Children: []interface{}{}, + }, + `0x2ae30d8 :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: ":17:1", + Name: "__acos", + Type: "double (double)", + IsExtern: true, IsImplicit: false, - IsUsed: false, - Children: []interface{}{}, + IsUsed: false, + Children: []interface{}{}, }, // FunctionProtoType - `0x7fa3b88bbb30 'struct _opaque_pthread_t *' foo`: - &FunctionProtoType{ - Address: "0x7fa3b88bbb30", - Type: "struct _opaque_pthread_t *", - Kind: "foo", + `0x7fa3b88bbb30 'struct _opaque_pthread_t *' foo`: &FunctionProtoType{ + Address: "0x7fa3b88bbb30", + Type: "struct _opaque_pthread_t *", + Kind: "foo", Children: []interface{}{}, }, // ForStmt - `0x7f961e018848 `: - &ForStmt{ - Address: "0x7f961e018848", + `0x7f961e018848 `: &ForStmt{ + Address: "0x7f961e018848", Position: "line:9:4, line:10:70", Children: []interface{}{}, }, // IfStmt - `0x7fc0a69091d0 `: - &IfStmt{ - Address: "0x7fc0a69091d0", + `0x7fc0a69091d0 `: &IfStmt{ + Address: "0x7fc0a69091d0", Position: "line:11:7, line:18:7", Children: []interface{}{}, }, // ImplicitCastExpr - `0x7f9f5b0a1288 'FILE *' `: - &ImplicitCastExpr{ - Address: "0x7f9f5b0a1288", + `0x7f9f5b0a1288 'FILE *' `: &ImplicitCastExpr{ + Address: "0x7f9f5b0a1288", Position: "col:8", - Type: "FILE *", - Kind: "LValueToRValue", + Type: "FILE *", + Kind: "LValueToRValue", Children: []interface{}{}, }, - `0x7f9f5b0a7828 'int (*)(int, FILE *)' `: - &ImplicitCastExpr{ - Address: "0x7f9f5b0a7828", + `0x7f9f5b0a7828 'int (*)(int, FILE *)' `: &ImplicitCastExpr{ + Address: "0x7f9f5b0a7828", Position: "col:11", - Type: "int (*)(int, FILE *)", - Kind: "FunctionToPointerDecay", + Type: "int (*)(int, FILE *)", + Kind: "FunctionToPointerDecay", Children: []interface{}{}, }, // IntegerLiteral - `0x7fbe9804bcc8 'int' 1`: - &IntegerLiteral{ - Address: "0x7fbe9804bcc8", + `0x7fbe9804bcc8 'int' 1`: &IntegerLiteral{ + Address: "0x7fbe9804bcc8", Position: "col:14", - Type: "int", - Value: 1, + Type: "int", + Value: 1, Children: []interface{}{}, }, // MallocAttr - `0x7fc0a69091d1 `: - &MallocAttr{ - Address: "0x7fc0a69091d1", + `0x7fc0a69091d1 `: &MallocAttr{ + Address: "0x7fc0a69091d1", Position: "line:11:7, line:18:7", Children: []interface{}{}, }, // MemberExpr - `0x7fcc758e34a0 'int' lvalue ->_w 0x7fcc758d60c8`: - &MemberExpr{ - Address: "0x7fcc758e34a0", + `0x7fcc758e34a0 'int' lvalue ->_w 0x7fcc758d60c8`: &MemberExpr{ + Address: "0x7fcc758e34a0", Position: "col:8, col:12", - Type: "int", - Lvalue: true, - Name: "_w", + Type: "int", + Lvalue: true, + Name: "_w", Address2: "0x7fcc758d60c8", Children: []interface{}{}, }, - `0x7fcc76004210 'unsigned char *' lvalue ->_p 0x7fcc758d6018`: - &MemberExpr{ - Address: "0x7fcc76004210", + `0x7fcc76004210 'unsigned char *' lvalue ->_p 0x7fcc758d6018`: &MemberExpr{ + Address: "0x7fcc76004210", Position: "col:12, col:16", - Type: "unsigned char *", - Lvalue: true, - Name: "_p", + Type: "unsigned char *", + Lvalue: true, + Name: "_p", Address2: "0x7fcc758d6018", Children: []interface{}{}, }, - `0x7f85338325b0 'float' lvalue .constant 0x7f8533832260`: - &MemberExpr{ - Address: "0x7f85338325b0", + `0x7f85338325b0 'float' lvalue .constant 0x7f8533832260`: &MemberExpr{ + Address: "0x7f85338325b0", Position: "col:4, col:13", - Type: "float", - Lvalue: true, - Name: "constant", + Type: "float", + Lvalue: true, + Name: "constant", Address2: "0x7f8533832260", Children: []interface{}{}, }, - `0x7f8533832670 'char *' lvalue .pointer 0x7f85338322b8`: - &MemberExpr{ - Address: "0x7f8533832670", + `0x7f8533832670 'char *' lvalue .pointer 0x7f85338322b8`: &MemberExpr{ + Address: "0x7f8533832670", Position: "col:4, col:13", - Type: "char *", - Lvalue: true, - Name: "pointer", + Type: "char *", + Lvalue: true, + Name: "pointer", Address2: "0x7f85338322b8", Children: []interface{}{}, }, // ModeAttr - `0x7f980b858309 foo`: - &ModeAttr{ - Address: "0x7f980b858309", + `0x7f980b858309 foo`: &ModeAttr{ + Address: "0x7f980b858309", Position: "line:11:7, line:18:7", - Name: "foo", + Name: "foo", Children: []interface{}{}, }, // NoThrowAttr - `0x7fa1488273a0 `: - &NoThrowAttr{ - Address: "0x7fa1488273a0", + `0x7fa1488273a0 `: &NoThrowAttr{ + Address: "0x7fa1488273a0", Position: "line:7:4, line:11:4", Children: []interface{}{}, }, // NonNullAttr - `0x7fa1488273b0 1`: - &NonNullAttr{ - Address: "0x7fa1488273b0", + `0x7fa1488273b0 1`: &NonNullAttr{ + Address: "0x7fa1488273b0", Position: "line:7:4, line:11:4", Children: []interface{}{}, }, - `0x2cce280 1`: - &NonNullAttr{ - Address: "0x2cce280", + `0x2cce280 1`: &NonNullAttr{ + Address: "0x2cce280", Position: "/sys/cdefs.h:286:44, /bits/mathcalls.h:115:69", Children: []interface{}{}, }, // ParenExpr - `0x7fb0bc8b2308 'unsigned char'`: - &ParenExpr{ - Address: "0x7fb0bc8b2308", + `0x7fb0bc8b2308 'unsigned char'`: &ParenExpr{ + Address: "0x7fb0bc8b2308", Position: "col:10, col:25", - Type: "unsigned char", + Type: "unsigned char", Children: []interface{}{}, }, // ParmVarDecl - `0x7f973380f000 col:17 'int'`: - &ParmVarDecl{ - Address: "0x7f973380f000", - Position: "col:14", + `0x7f973380f000 col:17 'int'`: &ParmVarDecl{ + Address: "0x7f973380f000", + Position: "col:14", Position2: "col:17", - Type: "int", - Name: "", - Type2: "", - IsUsed: false, - Children: []interface{}{}, - }, - `0x7f973380f070 col:31 'const char *'`: - &ParmVarDecl{ - Address: "0x7f973380f070", - Position: "col:19, col:30", + Type: "int", + Name: "", + Type2: "", + IsUsed: false, + Children: []interface{}{}, + }, + `0x7f973380f070 col:31 'const char *'`: &ParmVarDecl{ + Address: "0x7f973380f070", + Position: "col:19, col:30", Position2: "col:31", - Type: "const char *", - Name: "", - Type2: "", - IsUsed: false, - Children: []interface{}{}, - }, - `0x7f9733816e50 col:37 __filename 'const char *__restrict'`: - &ParmVarDecl{ - Address: "0x7f9733816e50", - Position: "col:13, col:37", + Type: "const char *", + Name: "", + Type2: "", + IsUsed: false, + Children: []interface{}{}, + }, + `0x7f9733816e50 col:37 __filename 'const char *__restrict'`: &ParmVarDecl{ + Address: "0x7f9733816e50", + Position: "col:13, col:37", Position2: "col:37", - Type: "const char *__restrict", - Name: "__filename", - Type2: "", - IsUsed: false, - Children: []interface{}{}, - }, - `0x7f9733817418 <> 'FILE *'`: - &ParmVarDecl{ - Address: "0x7f9733817418", - Position: "", + Type: "const char *__restrict", + Name: "__filename", + Type2: "", + IsUsed: false, + Children: []interface{}{}, + }, + `0x7f9733817418 <> 'FILE *'`: &ParmVarDecl{ + Address: "0x7f9733817418", + Position: "", Position2: "", - Type: "FILE *", - Name: "", - Type2: "", - IsUsed: false, - Children: []interface{}{}, - }, - `0x7f9733817c30 col:47 __size 'size_t':'unsigned long'`: - &ParmVarDecl{ - Address: "0x7f9733817c30", - Position: "col:40, col:47", + Type: "FILE *", + Name: "", + Type2: "", + IsUsed: false, + Children: []interface{}{}, + }, + `0x7f9733817c30 col:47 __size 'size_t':'unsigned long'`: &ParmVarDecl{ + Address: "0x7f9733817c30", + Position: "col:40, col:47", Position2: "col:47", - Type: "size_t", - Name: "__size", - Type2: "unsigned long", - IsUsed: false, - Children: []interface{}{}, - }, - `0x7f973382fa10 col:34 'int (* _Nullable)(void *, char *, int)':'int (*)(void *, char *, int)'`: - &ParmVarDecl{ - Address: "0x7f973382fa10", - Position: "line:476:18, col:25", + Type: "size_t", + Name: "__size", + Type2: "unsigned long", + IsUsed: false, + Children: []interface{}{}, + }, + `0x7f973382fa10 col:34 'int (* _Nullable)(void *, char *, int)':'int (*)(void *, char *, int)'`: &ParmVarDecl{ + Address: "0x7f973382fa10", + Position: "line:476:18, col:25", Position2: "col:34", - Type: "int (* _Nullable)(void *, char *, int)", - Name: "", - Type2: "int (*)(void *, char *, int)", - IsUsed: false, - Children: []interface{}{}, - }, - `0x7f97338355b8 col:14 used argc 'int'`: - &ParmVarDecl{ - Address: "0x7f97338355b8", - Position: "col:10, col:14", + Type: "int (* _Nullable)(void *, char *, int)", + Name: "", + Type2: "int (*)(void *, char *, int)", + IsUsed: false, + Children: []interface{}{}, + }, + `0x7f97338355b8 col:14 used argc 'int'`: &ParmVarDecl{ + Address: "0x7f97338355b8", + Position: "col:10, col:14", Position2: "col:14", - Type: "int", - Name: "argc", - Type2: "", - IsUsed: true, - Children: []interface{}{}, + Type: "int", + Name: "argc", + Type2: "", + IsUsed: true, + Children: []interface{}{}, }, // PointerType - `0x7fa3b88bbb30 'struct _opaque_pthread_t *'`: - &PointerType{ - Address: "0x7fa3b88bbb30", - Type: "struct _opaque_pthread_t *", + `0x7fa3b88bbb30 'struct _opaque_pthread_t *'`: &PointerType{ + Address: "0x7fa3b88bbb30", + Type: "struct _opaque_pthread_t *", Children: []interface{}{}, }, // PredefinedExpr - `0x33d6e08 'const char [25]' lvalue __PRETTY_FUNCTION__`: - &PredefinedExpr{ - Address: "0x33d6e08", + `0x33d6e08 'const char [25]' lvalue __PRETTY_FUNCTION__`: &PredefinedExpr{ + Address: "0x33d6e08", Position: "col:30", - Type: "const char [25]", - Lvalue: true, - Name: "__PRETTY_FUNCTION__", + Type: "const char [25]", + Lvalue: true, + Name: "__PRETTY_FUNCTION__", Children: []interface{}{}, }, // QualType - `0x7fa3b88bbb31 'struct _opaque_pthread_t *' foo`: - &QualType{ - Address: "0x7fa3b88bbb31", - Type: "struct _opaque_pthread_t *", - Kind: "foo", + `0x7fa3b88bbb31 'struct _opaque_pthread_t *' foo`: &QualType{ + Address: "0x7fa3b88bbb31", + Type: "struct _opaque_pthread_t *", + Kind: "foo", Children: []interface{}{}, }, // Record - `0x7fd3ab857950 '__sFILE'`: - &Record{ - Address: "0x7fd3ab857950", - Type: "__sFILE", + `0x7fd3ab857950 '__sFILE'`: &Record{ + Address: "0x7fd3ab857950", + Type: "__sFILE", Children: []interface{}{}, }, // RecordDecl - `0x7f913c0dbb50 line:76:9 union definition`: - &RecordDecl{ - Address: "0x7f913c0dbb50", - Position: "line:76:9, line:79:1", - Prev: "", - Position2: "line:76:9", - Kind: "union", - Name: "", + `0x7f913c0dbb50 line:76:9 union definition`: &RecordDecl{ + Address: "0x7f913c0dbb50", + Position: "line:76:9, line:79:1", + Prev: "", + Position2: "line:76:9", + Kind: "union", + Name: "", Definition: true, - Children: []interface{}{}, - }, - `0x7f85360285c8 line:57:8 struct __darwin_pthread_handler_rec definition`: - &RecordDecl{ - Address: "0x7f85360285c8", - Position: "/usr/include/sys/_pthread/_pthread_types.h:57:1, line:61:1", - Prev: "", - Position2: "line:57:8", - Kind: "struct", - Name: "__darwin_pthread_handler_rec", + Children: []interface{}{}, + }, + `0x7f85360285c8 line:57:8 struct __darwin_pthread_handler_rec definition`: &RecordDecl{ + Address: "0x7f85360285c8", + Position: "/usr/include/sys/_pthread/_pthread_types.h:57:1, line:61:1", + Prev: "", + Position2: "line:57:8", + Kind: "struct", + Name: "__darwin_pthread_handler_rec", Definition: true, - Children: []interface{}{}, - }, - `0x7f85370248a0 col:8 struct __sFILEX`: - &RecordDecl{ - Address: "0x7f85370248a0", - Position: "line:94:1, col:8", - Prev: "", - Position2: "col:8", - Kind: "struct", - Name: "__sFILEX", + Children: []interface{}{}, + }, + `0x7f85370248a0 col:8 struct __sFILEX`: &RecordDecl{ + Address: "0x7f85370248a0", + Position: "line:94:1, col:8", + Prev: "", + Position2: "col:8", + Kind: "struct", + Name: "__sFILEX", Definition: false, - Children: []interface{}{}, + Children: []interface{}{}, }, // RecordType - `0x7fd3ab84dda0 'struct _opaque_pthread_condattr_t'`: - &RecordType{ - Address: "0x7fd3ab84dda0", - Type: "struct _opaque_pthread_condattr_t", + `0x7fd3ab84dda0 'struct _opaque_pthread_condattr_t'`: &RecordType{ + Address: "0x7fd3ab84dda0", + Type: "struct _opaque_pthread_condattr_t", Children: []interface{}{}, }, // RestrictAttr - `0x7f980b858305 foo`: - &RestrictAttr{ - Address: "0x7f980b858305", + `0x7f980b858305 foo`: &RestrictAttr{ + Address: "0x7f980b858305", Position: "line:11:7, line:18:7", - Name: "foo", + Name: "foo", Children: []interface{}{}, }, // ReturnStmt - `0x7fbb7a8325e0 `: - &ReturnStmt{ - Address: "0x7fbb7a8325e0", + `0x7fbb7a8325e0 `: &ReturnStmt{ + Address: "0x7fbb7a8325e0", Position: "line:13:4, col:11", Children: []interface{}{}, }, // StringLiteral - `0x7fe16f0b4d58 'char [45]' lvalue "Number of command line arguments passed: %d\n"`: - &StringLiteral{ - Address: "0x7fe16f0b4d58", + `0x7fe16f0b4d58 'char [45]' lvalue "Number of command line arguments passed: %d\n"`: &StringLiteral{ + Address: "0x7fe16f0b4d58", Position: "col:11", - Type: "char [45]", - Lvalue: true, - Value: "Number of command line arguments passed: %d\n", + Type: "char [45]", + Lvalue: true, + Value: "Number of command line arguments passed: %d\n", Children: []interface{}{}, }, // TranslationUnitDecl - `0x7fe78a815ed0 <> `: - &TranslationUnitDecl{ - Address: "0x7fe78a815ed0", + `0x7fe78a815ed0 <> `: &TranslationUnitDecl{ + Address: "0x7fe78a815ed0", Children: []interface{}{}, }, // Typedef - `0x7f84d10dc1d0 '__darwin_ssize_t'`: - &Typedef{ - Address: "0x7f84d10dc1d0", - Type: "__darwin_ssize_t", + `0x7f84d10dc1d0 '__darwin_ssize_t'`: &Typedef{ + Address: "0x7f84d10dc1d0", + Type: "__darwin_ssize_t", Children: []interface{}{}, }, // TypedefDecl - `0x7fdef0862430 col:16`: - &TypedefDecl{ - Address: "0x7fdef0862430", - Position: "line:120:1, col:16", - Position2: "col:16", - Name: "", - Type: "", - Type2: "", - IsImplicit: false, + `0x7fdef0862430 col:16`: &TypedefDecl{ + Address: "0x7fdef0862430", + Position: "line:120:1, col:16", + Position2: "col:16", + Name: "", + Type: "", + Type2: "", + IsImplicit: false, IsReferenced: false, - Children: []interface{}{}, - }, - `0x7ffb9f824278 <> implicit __uint128_t 'unsigned __int128'`: - &TypedefDecl{ - Address: "0x7ffb9f824278", - Position: "", - Position2: "", - Name: "__uint128_t", - Type: "unsigned __int128", - Type2: "", - IsImplicit: true, + Children: []interface{}{}, + }, + `0x7ffb9f824278 <> implicit __uint128_t 'unsigned __int128'`: &TypedefDecl{ + Address: "0x7ffb9f824278", + Position: "", + Position2: "", + Name: "__uint128_t", + Type: "unsigned __int128", + Type2: "", + IsImplicit: true, IsReferenced: false, - Children: []interface{}{}, - }, - `0x7ffb9f824898 <> implicit referenced __builtin_va_list 'struct __va_list_tag [1]'`: - &TypedefDecl{ - Address: "0x7ffb9f824898", - Position: "", - Position2: "", - Name: "__builtin_va_list", - Type: "struct __va_list_tag [1]", - Type2: "", - IsImplicit: true, + Children: []interface{}{}, + }, + `0x7ffb9f824898 <> implicit referenced __builtin_va_list 'struct __va_list_tag [1]'`: &TypedefDecl{ + Address: "0x7ffb9f824898", + Position: "", + Position2: "", + Name: "__builtin_va_list", + Type: "struct __va_list_tag [1]", + Type2: "", + IsImplicit: true, IsReferenced: true, - Children: []interface{}{}, - }, - `0x7ffb9f8248f8 col:24 __int8_t 'signed char'`: - &TypedefDecl{ - Address: "0x7ffb9f8248f8", - Position: "/usr/include/i386/_types.h:37:1, col:24", - Position2: "col:24", - Name: "__int8_t", - Type: "signed char", - Type2: "", - IsImplicit: false, + Children: []interface{}{}, + }, + `0x7ffb9f8248f8 col:24 __int8_t 'signed char'`: &TypedefDecl{ + Address: "0x7ffb9f8248f8", + Position: "/usr/include/i386/_types.h:37:1, col:24", + Position2: "col:24", + Name: "__int8_t", + Type: "signed char", + Type2: "", + IsImplicit: false, IsReferenced: false, - Children: []interface{}{}, - }, - `0x7ffb9f8dbf50 col:27 referenced __darwin_va_list '__builtin_va_list':'struct __va_list_tag [1]'`: - &TypedefDecl{ - Address: "0x7ffb9f8dbf50", - Position: "line:98:1, col:27", - Position2: "col:27", - Name: "__darwin_va_list", - Type: "__builtin_va_list", - Type2: "struct __va_list_tag [1]", - IsImplicit: false, + Children: []interface{}{}, + }, + `0x7ffb9f8dbf50 col:27 referenced __darwin_va_list '__builtin_va_list':'struct __va_list_tag [1]'`: &TypedefDecl{ + Address: "0x7ffb9f8dbf50", + Position: "line:98:1, col:27", + Position2: "col:27", + Name: "__darwin_va_list", + Type: "__builtin_va_list", + Type2: "struct __va_list_tag [1]", + IsImplicit: false, IsReferenced: true, - Children: []interface{}{}, - }, - `0x34461f0 __io_read_fn '__ssize_t (void *, char *, size_t)'`: - &TypedefDecl{ - Address: "0x34461f0", - Position: "line:338:1, col:77", - Position2: "", - Name: "__io_read_fn", - Type: "__ssize_t (void *, char *, size_t)", - Type2: "", - IsImplicit: false, + Children: []interface{}{}, + }, + `0x34461f0 __io_read_fn '__ssize_t (void *, char *, size_t)'`: &TypedefDecl{ + Address: "0x34461f0", + Position: "line:338:1, col:77", + Position2: "", + Name: "__io_read_fn", + Type: "__ssize_t (void *, char *, size_t)", + Type2: "", + IsImplicit: false, IsReferenced: false, - Children: []interface{}{}, + Children: []interface{}{}, }, // TypedefType - `0x7f887a0dc760 '__uint16_t' sugar`: - &TypedefType{ - Address: "0x7f887a0dc760", - Type: "__uint16_t", - Tags: "sugar", + `0x7f887a0dc760 '__uint16_t' sugar`: &TypedefType{ + Address: "0x7f887a0dc760", + Type: "__uint16_t", + Tags: "sugar", Children: []interface{}{}, }, // UnaryOperator - `0x7fe0260f50d8 'int' prefix '--'`: - &UnaryOperator{ - Address: "0x7fe0260f50d8", + `0x7fe0260f50d8 'int' prefix '--'`: &UnaryOperator{ + Address: "0x7fe0260f50d8", Position: "col:6, col:12", - Type: "int", + Type: "int", IsLvalue: false, IsPrefix: true, Operator: "--", Children: []interface{}{}, }, - `0x7fe0260fb468 'unsigned char' lvalue prefix '*'`: - &UnaryOperator{ - Address: "0x7fe0260fb468", + `0x7fe0260fb468 'unsigned char' lvalue prefix '*'`: &UnaryOperator{ + Address: "0x7fe0260fb468", Position: "col:11, col:18", - Type: "unsigned char", + Type: "unsigned char", IsLvalue: true, IsPrefix: true, Operator: "*", Children: []interface{}{}, }, - `0x7fe0260fb448 'unsigned char *' postfix '++'`: - &UnaryOperator{ - Address: "0x7fe0260fb448", + `0x7fe0260fb448 'unsigned char *' postfix '++'`: &UnaryOperator{ + Address: "0x7fe0260fb448", Position: "col:12, col:18", - Type: "unsigned char *", + Type: "unsigned char *", IsLvalue: false, IsPrefix: false, Operator: "++", @@ -991,76 +895,70 @@ var nodes = map[string]interface{}{ }, // VarDecl - `0x7fd5e90e5a00 col:17 'int'`: - &VarDecl{ - Address: "0x7fd5e90e5a00", - Position: "col:14", + `0x7fd5e90e5a00 col:17 'int'`: &VarDecl{ + Address: "0x7fd5e90e5a00", + Position: "col:14", Position2: "col:17", - Name: "", - Type: "int", - Type2: "", - IsExtern: false, - IsUsed: false, - IsCInit: false, - Children: []interface{}{}, - }, - `0x7fd5e90e9078 col:14 __stdinp 'FILE *' extern`: - &VarDecl{ - Address: "0x7fd5e90e9078", - Position: "line:156:1, col:14", + Name: "", + Type: "int", + Type2: "", + IsExtern: false, + IsUsed: false, + IsCInit: false, + Children: []interface{}{}, + }, + `0x7fd5e90e9078 col:14 __stdinp 'FILE *' extern`: &VarDecl{ + Address: "0x7fd5e90e9078", + Position: "line:156:1, col:14", Position2: "col:14", - Name: "__stdinp", - Type: "FILE *", - Type2: "", - IsExtern: true, - IsUsed: false, - IsCInit: false, - Children: []interface{}{}, - }, - `0x7fd5e90ed630 col:47 __size 'size_t':'unsigned long'`: - &VarDecl{ - Address: "0x7fd5e90ed630", - Position: "col:40, col:47", + Name: "__stdinp", + Type: "FILE *", + Type2: "", + IsExtern: true, + IsUsed: false, + IsCInit: false, + Children: []interface{}{}, + }, + `0x7fd5e90ed630 col:47 __size 'size_t':'unsigned long'`: &VarDecl{ + Address: "0x7fd5e90ed630", + Position: "col:40, col:47", Position2: "col:47", - Name: "__size", - Type: "size_t", - Type2: "unsigned long", - IsExtern: false, - IsUsed: false, - IsCInit: false, - Children: []interface{}{}, - }, - `0x7fee35907a78 col:8 used c 'int'`: - &VarDecl{ - Address: "0x7fee35907a78", - Position: "col:4, col:8", + Name: "__size", + Type: "size_t", + Type2: "unsigned long", + IsExtern: false, + IsUsed: false, + IsCInit: false, + Children: []interface{}{}, + }, + `0x7fee35907a78 col:8 used c 'int'`: &VarDecl{ + Address: "0x7fee35907a78", + Position: "col:4, col:8", Position2: "col:8", - Name: "c", - Type: "int", - Type2: "", - IsExtern: false, - IsUsed: true, - IsCInit: false, - Children: []interface{}{}, - }, - `0x7fb0fd90ba30 tests/assert/assert.c:13:9 used b 'int *' cinit`: - &VarDecl{ - Address: "0x7fb0fd90ba30", - Position: "col:3, /usr/include/sys/_types.h:52:33", + Name: "c", + Type: "int", + Type2: "", + IsExtern: false, + IsUsed: true, + IsCInit: false, + Children: []interface{}{}, + }, + `0x7fb0fd90ba30 tests/assert/assert.c:13:9 used b 'int *' cinit`: &VarDecl{ + Address: "0x7fb0fd90ba30", + Position: "col:3, /usr/include/sys/_types.h:52:33", Position2: "tests/assert/assert.c:13:9", - Name: "b", - Type: "int *", - Type2: "", - IsExtern: false, - IsUsed: true, - IsCInit: true, - Children: []interface{}{}, + Name: "b", + Type: "int *", + Type2: "", + IsExtern: false, + IsUsed: true, + IsCInit: true, + Children: []interface{}{}, }, // WhileStmt - `0x7fa1478273a0 `: - &WhileStmt{ - Address: "0x7fa1478273a0", + `0x7fa1478273a0 `: &WhileStmt{ + Address: "0x7fa1478273a0", Position: "line:7:4, line:11:4", Children: []interface{}{}, }, diff --git a/availability_attr.go b/availability_attr.go index cf14cc548..0b568cc12 100644 --- a/availability_attr.go +++ b/availability_attr.go @@ -10,7 +10,7 @@ type AvailabilityAttr struct { Unavailable bool Message1 string Message2 string - Children []interface{} + Children []interface{} } func parseAvailabilityAttr(line string) *AvailabilityAttr { @@ -27,15 +27,15 @@ func parseAvailabilityAttr(line string) *AvailabilityAttr { ) return &AvailabilityAttr{ - Address: groups["address"], - Position: groups["position"], - OS: groups["os"], - Version: groups["version"], - Unknown1: atof(groups["unknown1"]), - Unknown2: atoi(groups["unknown2"]), + Address: groups["address"], + Position: groups["position"], + OS: groups["os"], + Version: groups["version"], + Unknown1: atof(groups["unknown1"]), + Unknown2: atoi(groups["unknown2"]), Unavailable: len(groups["unavalable"]) > 0, - Message1: removeQuotes(groups["message1"]), - Message2: removeQuotes(groups["message2"]), - Children: []interface{}{}, + Message1: removeQuotes(groups["message1"]), + Message2: removeQuotes(groups["message2"]), + Children: []interface{}{}, } } diff --git a/binary_operator.go b/binary_operator.go index 92e19fe94..18ea9fb5b 100644 --- a/binary_operator.go +++ b/binary_operator.go @@ -15,9 +15,9 @@ func parseBinaryOperator(line string) *BinaryOperator { ) return &BinaryOperator{ - Address: groups["address"], + Address: groups["address"], Position: groups["position"], - Type: groups["type"], + Type: groups["type"], Operator: groups["operator"], Children: []interface{}{}, } diff --git a/break_stmt.go b/break_stmt.go index 5032deea9..3d45ff009 100644 --- a/break_stmt.go +++ b/break_stmt.go @@ -13,7 +13,7 @@ func parseBreakStmt(line string) *BreakStmt { ) return &BreakStmt{ - Address: groups["address"], + Address: groups["address"], Position: groups["position"], Children: []interface{}{}, } diff --git a/builtin_type.go b/builtin_type.go index ff08a667f..445076185 100644 --- a/builtin_type.go +++ b/builtin_type.go @@ -1,8 +1,8 @@ package main type BuiltinType struct { - Address string - Type string + Address string + Type string Children []interface{} } @@ -13,8 +13,8 @@ func parseBuiltinType(line string) *BuiltinType { ) return &BuiltinType{ - Address: groups["address"], - Type: groups["type"], + Address: groups["address"], + Type: groups["type"], Children: []interface{}{}, } } diff --git a/c_style_cast_expr.go b/c_style_cast_expr.go index e7a849148..c5aa95843 100644 --- a/c_style_cast_expr.go +++ b/c_style_cast_expr.go @@ -15,10 +15,10 @@ func parseCStyleCastExpr(line string) *CStyleCastExpr { ) return &CStyleCastExpr{ - Address: groups["address"], + Address: groups["address"], Position: groups["position"], - Type: groups["type"], - Kind: groups["kind"], + Type: groups["type"], + Kind: groups["kind"], Children: []interface{}{}, } } diff --git a/call_expr.go b/call_expr.go index b459d2af1..87732d639 100644 --- a/call_expr.go +++ b/call_expr.go @@ -14,9 +14,9 @@ func parseCallExpr(line string) *CallExpr { ) return &CallExpr{ - Address: groups["address"], + Address: groups["address"], Position: groups["position"], - Type: groups["type"], + Type: groups["type"], Children: []interface{}{}, } } diff --git a/character_literal.go b/character_literal.go index 2ed510e82..9d0897a3a 100644 --- a/character_literal.go +++ b/character_literal.go @@ -15,10 +15,10 @@ func parseCharacterLiteral(line string) *CharacterLiteral { ) return &CharacterLiteral{ - Address: groups["address"], + Address: groups["address"], Position: groups["position"], - Type: groups["type"], - Value: atoi(groups["value"]), + Type: groups["type"], + Value: atoi(groups["value"]), Children: []interface{}{}, } } diff --git a/common.go b/common.go index 18a7be1a2..74c8ec873 100644 --- a/common.go +++ b/common.go @@ -5,43 +5,10 @@ import ( "fmt" "reflect" "regexp" - "strings" "strconv" + "strings" ) -type FunctionDefinition struct { - ReturnType string - ArgumentTypes []string -} - -var FunctionDefinitions = map[string]FunctionDefinition{ - // darwin/assert.h - "__builtin_expect": FunctionDefinition{"int", []string{"int", "int"}}, - "__assert_rtn": FunctionDefinition{"bool", []string{"const char*", "const char*", "int", "const char*"}}, - - // darwin/ctype.h - "__istype": FunctionDefinition{"uint32", []string{"__darwin_ct_rune_t", "uint32"}}, - "__isctype": FunctionDefinition{"__darwin_ct_rune_t", []string{"__darwin_ct_rune_t", "uint32"}}, - "__tolower": FunctionDefinition{"__darwin_ct_rune_t", []string{"__darwin_ct_rune_t"}}, - "__toupper": FunctionDefinition{"__darwin_ct_rune_t", []string{"__darwin_ct_rune_t"}}, - "__maskrune": FunctionDefinition{"uint32", []string{"__darwin_ct_rune_t", "uint32"}}, - - // darwin/math.h - "__builtin_fabs": FunctionDefinition{"double", []string{"double"}}, - "__builtin_fabsf": FunctionDefinition{"float", []string{"float"}}, - "__builtin_fabsl": FunctionDefinition{"double", []string{"double"}}, - "__builtin_inf": FunctionDefinition{"double", []string{}}, - "__builtin_inff": FunctionDefinition{"float", []string{}}, - "__builtin_infl": FunctionDefinition{"double", []string{}}, - "__sincospi_stret": FunctionDefinition{"Double2", []string{"double"}}, - "__sincospif_stret": FunctionDefinition{"Float2", []string{"float"}}, - "__sincos_stret": FunctionDefinition{"Double2", []string{"double"}}, - "__sincosf_stret": FunctionDefinition{"Float2", []string{"float"}}, - - // linux/assert.h - "__assert_fail": FunctionDefinition{"bool", []string{"const char*", "const char*", "unsigned int", "const char*"}}, -} - var FunctionSubstitutions = map[string]string{ // math.h "acos": "math.Acos", @@ -171,10 +138,10 @@ func addImport(importName string) { func importType(typeName string) string { if strings.Index(typeName, ".") != -1 { parts := strings.Split(typeName, ".") - addImport(strings.Join(parts[:len(parts) - 1], ".")) + addImport(strings.Join(parts[:len(parts)-1], ".")) parts2 := strings.Split(typeName, "/") - return parts2[len(parts2) - 1] + return parts2[len(parts2)-1] } return typeName @@ -217,8 +184,8 @@ func resolveType(s string) string { // Structures are by name. if strings.HasPrefix(s, "struct ") { - if s[len(s) - 1] == '*' { - s = s[7 : len(s) - 2] + if s[len(s)-1] == '*' { + s = s[7 : len(s)-2] for _, v := range SimpleResolveTypes { if v == s { @@ -242,8 +209,8 @@ func resolveType(s string) string { // Enums are by name. if s[:5] == "enum " { - if s[len(s) - 1] == '*' { - return "*" + s[5:len(s) - 2] + if s[len(s)-1] == '*' { + return "*" + s[5:len(s)-2] } else { return s[5:] } @@ -257,7 +224,7 @@ func resolveType(s string) string { // It may be a pointer of a simple type. For example, float *, int *, // etc. if regexp.MustCompile("[\\w ]+\\*+$").MatchString(s) { - return "*" + resolveType(strings.TrimSpace(s[:len(s) - 2])) + return "*" + resolveType(strings.TrimSpace(s[:len(s)-2])) } // Function pointers are not yet supported. In th mean time they will be @@ -352,14 +319,14 @@ func renderExpression(node interface{}) []string { children := n.Children func_name := renderExpression(children[0])[0] - func_def := FunctionDefinitions[func_name] + func_def := getFunctionDefinition(func_name) if _, ok := FunctionSubstitutions[func_name]; ok { parts := strings.Split(FunctionSubstitutions[func_name], ".") - addImport(strings.Join(parts[:len(parts) - 1], ".")) + addImport(strings.Join(parts[:len(parts)-1], ".")) parts2 := strings.Split(FunctionSubstitutions[func_name], "/") - func_name = parts2[len(parts2) - 1] + func_name = parts2[len(parts2)-1] } args := []string{} @@ -367,7 +334,7 @@ func renderExpression(node interface{}) []string { for _, arg := range children[1:] { e := renderExpression(arg) - if i > len(func_def.ArgumentTypes) - 1 { + if i > len(func_def.ArgumentTypes)-1 { // This means the argument is one of the varargs // so we don't know what type it needs to be // cast to. @@ -534,20 +501,20 @@ func renderExpression(node interface{}) []string { panic(fmt.Sprintf("renderExpression: unknown PredefinedExpr: %s", n.Name)) case *FloatingLiteral: - return []string{fmt.Sprintf("%f", n.Value), "double"} + return []string{fmt.Sprintf("%f", n.Value), "double"} case *MemberExpr: - children := n.Children + children := n.Children - lhs := renderExpression(children[0]) - lhs_type := resolveType(lhs[1]) - rhs := n.Name + lhs := renderExpression(children[0]) + lhs_type := resolveType(lhs[1]) + rhs := n.Name - if inStrings(lhs_type, []string{"darwin.Float2", "darwin.Double2"}) { + if inStrings(lhs_type, []string{"darwin.Float2", "darwin.Double2"}) { rhs = getExportedName(rhs) } - return []string{ + return []string{ fmt.Sprintf("%s.%s", lhs[0], rhs), children[0].(*DeclRefExpr).Type, } @@ -642,7 +609,7 @@ func Render(out *bytes.Buffer, node interface{}, function_name string, indent in printLine(out, fmt.Sprintf("type %s %s {", name, n.Kind), indent) if len(n.Children) > 0 { for _, c := range n.Children { - Render(out, c, function_name, indent + 1, "") + Render(out, c, function_name, indent+1, "") } } @@ -650,7 +617,7 @@ func Render(out *bytes.Buffer, node interface{}, function_name string, indent in return case *FieldDecl: - printLine(out, renderExpression(node)[0], indent + 1) + printLine(out, renderExpression(node)[0], indent+1) return case *FunctionDecl: @@ -692,7 +659,7 @@ func Render(out *bytes.Buffer, node interface{}, function_name string, indent in for _, c := range n.Children { if _, ok := c.(*CompoundStmt); ok { Render(out, c, function_name, - indent + 1, n.Type) + indent+1, n.Type) } } @@ -703,9 +670,11 @@ func Render(out *bytes.Buffer, node interface{}, function_name string, indent in params = append(params, v.Type) } - FunctionDefinitions[n.Name] = FunctionDefinition{ - getFunctionReturnType(n.Type), params, - } + addFunctionDefinition(FunctionDefinition{ + Name: n.Name, + ReturnType: getFunctionReturnType(n.Type), + ArgumentTypes: params, + }) } case *VarDecl: @@ -743,7 +712,7 @@ func Render(out *bytes.Buffer, node interface{}, function_name string, indent in printLine(out, fmt.Sprintf("for %s; %s; %s {", a, b, c), indent) - Render(out, children[3], function_name, indent + 1, return_type) + Render(out, children[3], function_name, indent+1, return_type) printLine(out, "}", indent) @@ -759,31 +728,31 @@ func Render(out *bytes.Buffer, node interface{}, function_name string, indent in e := renderExpression(children[0]) printLine(out, fmt.Sprintf("if %s {", cast(e[0], e[1], "bool")), indent) - Render(out, children[1], function_name, indent + 1, return_type) + Render(out, children[1], function_name, indent+1, return_type) if len(children) > 2 { printLine(out, "} else {", indent) - Render(out, children[2], function_name, indent + 1, return_type) + Render(out, children[2], function_name, indent+1, return_type) } printLine(out, "}", indent) case *BreakStmt: - printLine(out, "break", indent) + printLine(out, "break", indent) case *WhileStmt: - children := n.Children + children := n.Children - e := renderExpression(children[0]) - printLine(out, fmt.Sprintf("for %s {", cast(e[0], e[1], "bool")), indent) + e := renderExpression(children[0]) + printLine(out, fmt.Sprintf("for %s {", cast(e[0], e[1], "bool")), indent) // FIXME: Does this do anything? - Render(out, children[1], function_name, indent + 1, return_type) + Render(out, children[1], function_name, indent+1, return_type) - printLine(out, "}", indent) + printLine(out, "}", indent) case *UnaryOperator: - printLine(out, renderExpression(node)[0], indent) + printLine(out, renderExpression(node)[0], indent) case *EnumDecl: return diff --git a/compound_stmt.go b/compound_stmt.go index e5f532bda..44d4d8045 100644 --- a/compound_stmt.go +++ b/compound_stmt.go @@ -13,7 +13,7 @@ func parseCompoundStmt(line string) *CompoundStmt { ) return &CompoundStmt{ - Address: groups["address"], + Address: groups["address"], Position: groups["position"], Children: []interface{}{}, } diff --git a/conditional_operator.go b/conditional_operator.go index 295990447..06208af0c 100644 --- a/conditional_operator.go +++ b/conditional_operator.go @@ -3,7 +3,7 @@ package main type ConditionalOperator struct { Address string Position string - Type string + Type string Children []interface{} } @@ -14,9 +14,9 @@ func parseConditionalOperator(line string) *ConditionalOperator { ) return &ConditionalOperator{ - Address: groups["address"], + Address: groups["address"], Position: groups["position"], - Type: groups["type"], + Type: groups["type"], Children: []interface{}{}, } } diff --git a/const_attr.go b/const_attr.go index 25b897861..8e2fb3a22 100644 --- a/const_attr.go +++ b/const_attr.go @@ -14,9 +14,9 @@ func parseConstAttr(line string) *ConstAttr { ) return &ConstAttr{ - Address: groups["address"], + Address: groups["address"], Position: groups["position"], - Tags: groups["tags"], + Tags: groups["tags"], Children: []interface{}{}, } } diff --git a/constant_array_type.go b/constant_array_type.go index 6408f9c83..4f8e6e4f3 100644 --- a/constant_array_type.go +++ b/constant_array_type.go @@ -1,9 +1,9 @@ package main type ConstantArrayType struct { - Address string - Type string - Size int + Address string + Type string + Size int Children []interface{} } @@ -14,9 +14,9 @@ func parseConstantArrayType(line string) *ConstantArrayType { ) return &ConstantArrayType{ - Address: groups["address"], - Type: groups["type"], - Size: atoi(groups["size"]), + Address: groups["address"], + Type: groups["type"], + Size: atoi(groups["size"]), Children: []interface{}{}, } } diff --git a/darwin/common.go b/darwin/common.go index ca5ebcb9f..cb966cedf 100644 --- a/darwin/common.go +++ b/darwin/common.go @@ -1,7 +1,7 @@ package darwin import ( - "unicode" + "unicode" ) // FIXME: These are wrong. @@ -10,37 +10,21 @@ type fpos_t int64 type C__darwin_ct_rune_t int type _RuneLocale struct { - __runetype [256]uint32 + __runetype [256]uint32 } var _DefaultRuneLocale _RuneLocale = _RuneLocale{ - __runetype: [256]uint32{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, }, + __runetype: [256]uint32{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, }, } func __maskrune(_c C__darwin_ct_rune_t, _f uint32) uint32 { - return _DefaultRuneLocale.__runetype[_c & 0xff] & _f; + return _DefaultRuneLocale.__runetype[_c & 0xff] & _f; } -// func __istype(_c C__darwin_ct_rune_t, _f uint32) uint32 { -// if isascii(int(_c)) != 0 { -// return __not_uint32(__not_uint32((_DefaultRuneLocale.__runetype[_c] & _f))) -// } - -// return __not_uint32(__not_uint32(__maskrune(_c, _f))) -// } - -// func __isctype(_c C__darwin_ct_rune_t, _f uint32) C__darwin_ct_rune_t { -// if _c < 0 || _c >= (1 <<8 ) { -// return 0 -// } - -// return C__darwin_ct_rune_t(__not_uint32(__not_uint32((_DefaultRuneLocale.__runetype[_c] & _f)))) -// } - func __tolower(c C__darwin_ct_rune_t) C__darwin_ct_rune_t { - return C__darwin_ct_rune_t(unicode.ToLower(rune(c))) + return C__darwin_ct_rune_t(unicode.ToLower(rune(c))) } func __toupper(c C__darwin_ct_rune_t) C__darwin_ct_rune_t { - return C__darwin_ct_rune_t(unicode.ToUpper(rune(c))) + return C__darwin_ct_rune_t(unicode.ToUpper(rune(c))) } diff --git a/decl_ref_expr.go b/decl_ref_expr.go index d1d651d67..fe015e476 100644 --- a/decl_ref_expr.go +++ b/decl_ref_expr.go @@ -26,14 +26,14 @@ func parseDeclRefExpr(line string) *DeclRefExpr { ) return &DeclRefExpr{ - Address: groups["address"], + Address: groups["address"], Position: groups["position"], - Type: groups["type"], - Lvalue: len(groups["lvalue"]) > 0, - For: groups["for"], + Type: groups["type"], + Lvalue: len(groups["lvalue"]) > 0, + For: groups["for"], Address2: groups["address2"], - Name: groups["name"], - Type2: groups["type2"], + Name: groups["name"], + Type2: groups["type2"], Children: []interface{}{}, } } diff --git a/decl_stmt.go b/decl_stmt.go index b7947e967..e6e50f1df 100644 --- a/decl_stmt.go +++ b/decl_stmt.go @@ -13,7 +13,7 @@ func parseDeclStmt(line string) *DeclStmt { ) return &DeclStmt{ - Address: groups["address"], + Address: groups["address"], Position: groups["position"], Children: []interface{}{}, } diff --git a/deprecated_attr.go b/deprecated_attr.go index 7dbe0f8d7..c280a159f 100644 --- a/deprecated_attr.go +++ b/deprecated_attr.go @@ -15,7 +15,7 @@ func parseDeprecatedAttr(line string) *DeprecatedAttr { ) return &DeprecatedAttr{ - Address: groups["address"], + Address: groups["address"], Position: groups["position"], Message1: removeQuotes(groups["message1"]), Message2: removeQuotes(groups["message2"]), diff --git a/elaborated_type.go b/elaborated_type.go index 05b8a64b6..1d88f5dd7 100644 --- a/elaborated_type.go +++ b/elaborated_type.go @@ -14,9 +14,9 @@ func parseElaboratedType(line string) *ElaboratedType { ) return &ElaboratedType{ - Address: groups["address"], - Type: groups["type"], - Tags: groups["tags"], + Address: groups["address"], + Type: groups["type"], + Tags: groups["tags"], Children: []interface{}{}, } } diff --git a/enum.go b/enum.go index 68c905998..48d5fbe81 100644 --- a/enum.go +++ b/enum.go @@ -1,8 +1,8 @@ package main type Enum struct { - Address string - Name string + Address string + Name string Children []interface{} } @@ -13,8 +13,8 @@ func parseEnum(line string) *Enum { ) return &Enum{ - Address: groups["address"], - Name: groups["name"], + Address: groups["address"], + Name: groups["name"], Children: []interface{}{}, } } diff --git a/enum_constant_decl.go b/enum_constant_decl.go index 0e4b3e0c6..fbcb9a1ec 100644 --- a/enum_constant_decl.go +++ b/enum_constant_decl.go @@ -6,7 +6,7 @@ type EnumConstantDecl struct { Position2 string Name string Type string - Children []interface{} + Children []interface{} } func parseEnumConstantDecl(line string) *EnumConstantDecl { @@ -19,11 +19,11 @@ func parseEnumConstantDecl(line string) *EnumConstantDecl { ) return &EnumConstantDecl{ - Address: groups["address"], - Position: groups["position"], + Address: groups["address"], + Position: groups["position"], Position2: groups["position2"], - Name: groups["name"], - Type: groups["type"], - Children: []interface{}{}, + Name: groups["name"], + Type: groups["type"], + Children: []interface{}{}, } } diff --git a/enum_decl.go b/enum_decl.go index bcc52f309..9a1926f70 100644 --- a/enum_decl.go +++ b/enum_decl.go @@ -7,7 +7,7 @@ type EnumDecl struct { Position string Position2 string Name string - Children []interface{} + Children []interface{} } func parseEnumDecl(line string) *EnumDecl { @@ -17,10 +17,10 @@ func parseEnumDecl(line string) *EnumDecl { ) return &EnumDecl{ - Address: groups["address"], - Position: groups["position"], + Address: groups["address"], + Position: groups["position"], Position2: groups["position2"], - Name: strings.TrimSpace(groups["name"]), - Children: []interface{}{}, + Name: strings.TrimSpace(groups["name"]), + Children: []interface{}{}, } } diff --git a/enum_type.go b/enum_type.go index d32bbd27a..01c5fa8c7 100644 --- a/enum_type.go +++ b/enum_type.go @@ -1,8 +1,8 @@ package main type EnumType struct { - Address string - Name string + Address string + Name string Children []interface{} } @@ -13,8 +13,8 @@ func parseEnumType(line string) *EnumType { ) return &EnumType{ - Address: groups["address"], - Name: groups["name"], + Address: groups["address"], + Name: groups["name"], Children: []interface{}{}, } } diff --git a/field_decl.go b/field_decl.go index 4781aac75..7de213c25 100644 --- a/field_decl.go +++ b/field_decl.go @@ -9,7 +9,7 @@ type FieldDecl struct { Name string Type string Referenced bool - Children []interface{} + Children []interface{} } func parseFieldDecl(line string) *FieldDecl { @@ -23,12 +23,12 @@ func parseFieldDecl(line string) *FieldDecl { ) return &FieldDecl{ - Address: groups["address"], - Position: groups["position"], - Position2: strings.TrimSpace(groups["position2"]), - Name: groups["name"], - Type: groups["type"], + Address: groups["address"], + Position: groups["position"], + Position2: strings.TrimSpace(groups["position2"]), + Name: groups["name"], + Type: groups["type"], Referenced: len(groups["referenced"]) > 0, - Children: []interface{}{}, + Children: []interface{}{}, } } diff --git a/floating_literal.go b/floating_literal.go index 6b436e011..ff028b29f 100644 --- a/floating_literal.go +++ b/floating_literal.go @@ -15,10 +15,10 @@ func parseFloatingLiteral(line string) *FloatingLiteral { ) return &FloatingLiteral{ - Address: groups["address"], + Address: groups["address"], Position: groups["position"], - Type: groups["type"], - Value: atof(groups["value"]), + Type: groups["type"], + Value: atof(groups["value"]), Children: []interface{}{}, } } diff --git a/for_stmt.go b/for_stmt.go index 483cd2f20..cb80fdb48 100644 --- a/for_stmt.go +++ b/for_stmt.go @@ -13,7 +13,7 @@ func parseForStmt(line string) *ForStmt { ) return &ForStmt{ - Address: groups["address"], + Address: groups["address"], Position: groups["position"], Children: []interface{}{}, } diff --git a/format_attr.go b/format_attr.go index e9d68eec8..5f9b8c6c2 100644 --- a/format_attr.go +++ b/format_attr.go @@ -23,13 +23,13 @@ func parseFormatAttr(line string) *FormatAttr { ) return &FormatAttr{ - Address: groups["address"], - Position: groups["position"], - Implicit: len(groups["implicit"]) > 0, - Inherited: len(groups["inherited"]) > 0, + Address: groups["address"], + Position: groups["position"], + Implicit: len(groups["implicit"]) > 0, + Inherited: len(groups["inherited"]) > 0, FunctionName: groups["function"], - Unknown1: atoi(groups["unknown1"]), - Unknown2: atoi(groups["unknown2"]), - Children: []interface{}{}, + Unknown1: atoi(groups["unknown1"]), + Unknown2: atoi(groups["unknown2"]), + Children: []interface{}{}, } } diff --git a/function_decl.go b/function_decl.go index 0d42b6c2f..68c608627 100644 --- a/function_decl.go +++ b/function_decl.go @@ -12,7 +12,7 @@ type FunctionDecl struct { IsExtern bool IsImplicit bool IsUsed bool - Children []interface{} + Children []interface{} } func parseFunctionDecl(line string) *FunctionDecl { @@ -30,19 +30,19 @@ func parseFunctionDecl(line string) *FunctionDecl { prev := groups["prev"] if prev != "" { - prev = prev[5:len(prev) - 1] + prev = prev[5 : len(prev)-1] } 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, + 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: []interface{}{}, + IsUsed: len(groups["used"]) > 0, + Children: []interface{}{}, } } diff --git a/function_definition.go b/function_definition.go new file mode 100644 index 000000000..1c575d70f --- /dev/null +++ b/function_definition.go @@ -0,0 +1,85 @@ +package main + +import ( + "regexp" + "strings" +) + +// FunctionDefinition contains the prototype definition for a function. +type FunctionDefinition struct { + Name string + ReturnType string + ArgumentTypes []string +} + +var functionDefinitions = map[string]FunctionDefinition{} + +var builtInFunctionDefinitionsHaveBeenLoaded = false + +var builtInFunctionDefinitions = []string{ + // darwin/assert.h + "int __builtin_expect(int, int)", + "bool __assert_rtn(const char*, const char*, int, const char*)", + + // darwin/ctype.h + "uint32 __istype(__darwin_ct_rune_t, uint32)", + "__darwin_ct_rune_t __isctype(__darwin_ct_rune_t, uint32)", + "__darwin_ct_rune_t __tolower(__darwin_ct_rune_t)", + "__darwin_ct_rune_t __toupper(__darwin_ct_rune_t)", + "uint32 __maskrune(__darwin_ct_rune_t, uint32)", + + // darwin/math.h + "double __builtin_fabs(double)", + "float __builtin_fabsf(float)", + "double __builtin_fabsl(double)", + "double __builtin_inf()", + "float __builtin_inff()", + "double __builtin_infl()", + "Double2 __sincospi_stret(double)", + "Float2 __sincospif_stret(float)", + "Double2 __sincos_stret(double)", + "Float2 __sincosf_stret(float)", + + // linux/assert.h + "bool __assert_fail(const char*, const char*, unsigned int, const char*)", +} + +// getFunctionDefinition will return nil if the function does not exist (is not +// registered). +func getFunctionDefinition(functionName string) FunctionDefinition { + loadFunctionDefinitions() + + return functionDefinitions[functionName] +} + +// addFunctionDefinition registers a function definition. If the definition +// already exists it will be replaced. +func addFunctionDefinition(f FunctionDefinition) { + loadFunctionDefinitions() + + functionDefinitions[f.Name] = f +} + +func loadFunctionDefinitions() { + if builtInFunctionDefinitionsHaveBeenLoaded { + return + } + + builtInFunctionDefinitionsHaveBeenLoaded = true + + for _, f := range builtInFunctionDefinitions { + match := regexp.MustCompile(`^(.+) (.+)\((.*)\)$`). + FindStringSubmatch(f) + + argumentTypes := strings.Split(match[3], ",") + for i := range argumentTypes { + argumentTypes[i] = strings.TrimSpace(argumentTypes[i]) + } + + addFunctionDefinition(FunctionDefinition{ + Name: match[2], + ReturnType: match[1], + ArgumentTypes: argumentTypes, + }) + } +} diff --git a/function_proto_type.go b/function_proto_type.go index 01cdb58ab..79dc311ee 100644 --- a/function_proto_type.go +++ b/function_proto_type.go @@ -1,9 +1,9 @@ package main type FunctionProtoType struct { - Address string - Type string - Kind string + Address string + Type string + Kind string Children []interface{} } @@ -14,9 +14,9 @@ func parseFunctionProtoType(line string) *FunctionProtoType { ) return &FunctionProtoType{ - Address: groups["address"], - Type: groups["type"], - Kind: groups["kind"], + Address: groups["address"], + Type: groups["type"], + Kind: groups["kind"], Children: []interface{}{}, } } diff --git a/if_stmt.go b/if_stmt.go index efa38259e..20c2767f7 100644 --- a/if_stmt.go +++ b/if_stmt.go @@ -13,7 +13,7 @@ func parseIfStmt(line string) *IfStmt { ) return &IfStmt{ - Address: groups["address"], + Address: groups["address"], Position: groups["position"], Children: []interface{}{}, } diff --git a/implicit_cast_expr.go b/implicit_cast_expr.go index 14b6c18b3..99d46f345 100644 --- a/implicit_cast_expr.go +++ b/implicit_cast_expr.go @@ -15,10 +15,10 @@ func parseImplicitCastExpr(line string) *ImplicitCastExpr { ) return &ImplicitCastExpr{ - Address: groups["address"], + Address: groups["address"], Position: groups["position"], - Type: groups["type"], - Kind: groups["kind"], + Type: groups["type"], + Kind: groups["kind"], Children: []interface{}{}, } } diff --git a/integer_literal.go b/integer_literal.go index 0a699235a..be1926131 100644 --- a/integer_literal.go +++ b/integer_literal.go @@ -15,10 +15,10 @@ func parseIntegerLiteral(line string) *IntegerLiteral { ) return &IntegerLiteral{ - Address: groups["address"], + Address: groups["address"], Position: groups["position"], - Type: groups["type"], - Value: atoi(groups["value"]), + Type: groups["type"], + Value: atoi(groups["value"]), Children: []interface{}{}, } } diff --git a/main_test.go b/main_test.go index 2a804819d..d810f0aed 100644 --- a/main_test.go +++ b/main_test.go @@ -1,8 +1,8 @@ package main import ( - "testing" "path/filepath" + "testing" ) // This test exists for code coverage and does not actually test anything. The diff --git a/malloc_attr.go b/malloc_attr.go index 684b1ff77..0fa9a5998 100644 --- a/malloc_attr.go +++ b/malloc_attr.go @@ -13,7 +13,7 @@ func parseMallocAttr(line string) *MallocAttr { ) return &MallocAttr{ - Address: groups["address"], + Address: groups["address"], Position: groups["position"], Children: []interface{}{}, } diff --git a/member_expr.go b/member_expr.go index c960af905..0c0fe4a68 100644 --- a/member_expr.go +++ b/member_expr.go @@ -21,11 +21,11 @@ func parseMemberExpr(line string) *MemberExpr { ) return &MemberExpr{ - Address: groups["address"], + Address: groups["address"], Position: groups["position"], - Type: groups["type"], - Lvalue: true, - Name: groups["name"], + Type: groups["type"], + Lvalue: true, + Name: groups["name"], Address2: groups["address2"], Children: []interface{}{}, } diff --git a/mode_attr.go b/mode_attr.go index f79cfe56a..35183fe82 100644 --- a/mode_attr.go +++ b/mode_attr.go @@ -14,9 +14,9 @@ func parseModeAttr(line string) *ModeAttr { ) return &ModeAttr{ - Address: groups["address"], + Address: groups["address"], Position: groups["position"], - Name: groups["name"], + Name: groups["name"], Children: []interface{}{}, } } diff --git a/no_throw_attr.go b/no_throw_attr.go index ed0edb34f..826838534 100644 --- a/no_throw_attr.go +++ b/no_throw_attr.go @@ -13,7 +13,7 @@ func parseNoThrowAttr(line string) *NoThrowAttr { ) return &NoThrowAttr{ - Address: groups["address"], + Address: groups["address"], Position: groups["position"], Children: []interface{}{}, } diff --git a/non_null_attr.go b/non_null_attr.go index 280cda4c8..f5c7e8e37 100644 --- a/non_null_attr.go +++ b/non_null_attr.go @@ -13,7 +13,7 @@ func parseNonNullAttr(line string) *NonNullAttr { ) return &NonNullAttr{ - Address: groups["address"], + Address: groups["address"], Position: groups["position"], Children: []interface{}{}, } diff --git a/paren_expr.go b/paren_expr.go index 44e82c998..10b65f22c 100644 --- a/paren_expr.go +++ b/paren_expr.go @@ -14,9 +14,9 @@ func parseParenExpr(line string) *ParenExpr { ) return &ParenExpr{ - Address: groups["address"], + Address: groups["address"], Position: groups["position"], - Type: groups["type"], + Type: groups["type"], Children: []interface{}{}, } } diff --git a/parm_var_decl.go b/parm_var_decl.go index 46ccd5f30..c30ddeee9 100644 --- a/parm_var_decl.go +++ b/parm_var_decl.go @@ -10,7 +10,7 @@ type ParmVarDecl struct { Type string Type2 string IsUsed bool - Children []interface{} + Children []interface{} } func parseParmVarDecl(line string) *ParmVarDecl { @@ -26,7 +26,7 @@ func parseParmVarDecl(line string) *ParmVarDecl { type2 := groups["type2"] if type2 != "" { - type2 = type2[2:len(type2) - 1] + type2 = type2[2 : len(type2)-1] } if strings.Index(groups["position"], "") > -1 { @@ -35,13 +35,13 @@ func parseParmVarDecl(line string) *ParmVarDecl { } return &ParmVarDecl{ - Address: groups["address"], - Position: groups["position"], + Address: groups["address"], + Position: groups["position"], Position2: strings.TrimSpace(groups["position2"]), - Name: strings.TrimSpace(groups["name"]), - Type: groups["type"], - Type2: type2, - IsUsed: len(groups["used"]) > 0, - Children: []interface{}{}, + Name: strings.TrimSpace(groups["name"]), + Type: groups["type"], + Type2: type2, + IsUsed: len(groups["used"]) > 0, + Children: []interface{}{}, } } diff --git a/pointer_type.go b/pointer_type.go index c37ff6975..f3d766825 100644 --- a/pointer_type.go +++ b/pointer_type.go @@ -1,8 +1,8 @@ package main type PointerType struct { - Address string - Type string + Address string + Type string Children []interface{} } @@ -13,8 +13,8 @@ func parsePointerType(line string) *PointerType { ) return &PointerType{ - Address: groups["address"], - Type: groups["type"], + Address: groups["address"], + Type: groups["type"], Children: []interface{}{}, } } diff --git a/predefined_expr.go b/predefined_expr.go index b6428120f..66b358fd6 100644 --- a/predefined_expr.go +++ b/predefined_expr.go @@ -16,11 +16,11 @@ func parsePredefinedExpr(line string) *PredefinedExpr { ) return &PredefinedExpr{ - Address: groups["address"], + Address: groups["address"], Position: groups["position"], - Type: groups["type"], - Name: groups["name"], - Lvalue: true, + Type: groups["type"], + Name: groups["name"], + Lvalue: true, Children: []interface{}{}, } } diff --git a/qual_type.go b/qual_type.go index bd0ec662a..83aa205ff 100644 --- a/qual_type.go +++ b/qual_type.go @@ -1,9 +1,9 @@ package main type QualType struct { - Address string - Type string - Kind string + Address string + Type string + Kind string Children []interface{} } @@ -14,9 +14,9 @@ func parseQualType(line string) *QualType { ) return &QualType{ - Address: groups["address"], - Type: groups["type"], - Kind: groups["kind"], + Address: groups["address"], + Type: groups["type"], + Kind: groups["kind"], Children: []interface{}{}, } } diff --git a/record.go b/record.go index 52fb6f4ce..32f520699 100644 --- a/record.go +++ b/record.go @@ -1,8 +1,8 @@ package main type Record struct { - Address string - Type string + Address string + Type string Children []interface{} } @@ -13,8 +13,8 @@ func parseRecord(line string) *Record { ) return &Record{ - Address: groups["address"], - Type: groups["type"], + Address: groups["address"], + Type: groups["type"], Children: []interface{}{}, } } diff --git a/record_decl.go b/record_decl.go index c9a97cde7..fc5094730 100644 --- a/record_decl.go +++ b/record_decl.go @@ -10,7 +10,7 @@ type RecordDecl struct { Kind string Name string Definition bool - Children []interface{} + Children []interface{} } func parseRecordDecl(line string) *RecordDecl { @@ -30,18 +30,18 @@ func parseRecordDecl(line string) *RecordDecl { definition = true } if strings.HasSuffix(name, " definition") { - name = name[0:len(name) - 11] + name = name[0 : len(name)-11] definition = true } return &RecordDecl{ - Address: groups["address"], - Position: groups["position"], - Prev: groups["prev"], - Position2: strings.TrimSpace(groups["position2"]), - Kind: groups["kind"], - Name: name, + Address: groups["address"], + Position: groups["position"], + Prev: groups["prev"], + Position2: strings.TrimSpace(groups["position2"]), + Kind: groups["kind"], + Name: name, Definition: definition, - Children: []interface{}{}, + Children: []interface{}{}, } } diff --git a/record_type.go b/record_type.go index a25089eb5..958edc858 100644 --- a/record_type.go +++ b/record_type.go @@ -1,8 +1,8 @@ package main type RecordType struct { - Address string - Type string + Address string + Type string Children []interface{} } @@ -13,8 +13,8 @@ func parseRecordType(line string) *RecordType { ) return &RecordType{ - Address: groups["address"], - Type: groups["type"], + Address: groups["address"], + Type: groups["type"], Children: []interface{}{}, } } diff --git a/restrict_attr.go b/restrict_attr.go index 58419f8e6..f827db1d5 100644 --- a/restrict_attr.go +++ b/restrict_attr.go @@ -14,9 +14,9 @@ func parseRestrictAttr(line string) *RestrictAttr { ) return &RestrictAttr{ - Address: groups["address"], + Address: groups["address"], Position: groups["position"], - Name: groups["name"], + Name: groups["name"], Children: []interface{}{}, } } diff --git a/return_stmt.go b/return_stmt.go index 006d11e83..1d464c9d8 100644 --- a/return_stmt.go +++ b/return_stmt.go @@ -13,7 +13,7 @@ func parseReturnStmt(line string) *ReturnStmt { ) return &ReturnStmt{ - Address: groups["address"], + Address: groups["address"], Position: groups["position"], Children: []interface{}{}, } diff --git a/string_literal.go b/string_literal.go index df8ea6c02..b862aa0bf 100644 --- a/string_literal.go +++ b/string_literal.go @@ -16,11 +16,11 @@ func parseStringLiteral(line string) *StringLiteral { ) return &StringLiteral{ - Address: groups["address"], + Address: groups["address"], Position: groups["position"], - Type: groups["type"], - Value: unescapeString(groups["value"]), - Lvalue: true, + Type: groups["type"], + Value: unescapeString(groups["value"]), + Lvalue: true, Children: []interface{}{}, } } diff --git a/translation_unit_decl.go b/translation_unit_decl.go index 65732202d..51cf4ce46 100644 --- a/translation_unit_decl.go +++ b/translation_unit_decl.go @@ -1,7 +1,7 @@ package main type TranslationUnitDecl struct { - Address string + Address string Children []interface{} } @@ -9,7 +9,7 @@ func parseTranslationUnitDecl(line string) *TranslationUnitDecl { groups := groupsFromRegex("", line) return &TranslationUnitDecl{ - Address: groups["address"], + Address: groups["address"], Children: []interface{}{}, } } diff --git a/typedef.go b/typedef.go index a40735a65..73e2471bc 100644 --- a/typedef.go +++ b/typedef.go @@ -1,8 +1,8 @@ package main type Typedef struct { - Address string - Type string + Address string + Type string Children []interface{} } @@ -13,8 +13,8 @@ func parseTypedef(line string) *Typedef { ) return &Typedef{ - Address: groups["address"], - Type: groups["type"], + Address: groups["address"], + Type: groups["type"], Children: []interface{}{}, } } diff --git a/typedef_decl.go b/typedef_decl.go index 6e581e280..fc0f8bb97 100644 --- a/typedef_decl.go +++ b/typedef_decl.go @@ -28,18 +28,18 @@ func parseTypedefDecl(line string) *TypedefDecl { type2 := groups["type2"] if type2 != "" { - type2 = type2[2:len(type2) - 1] + type2 = type2[2 : len(type2)-1] } return &TypedefDecl{ - Address: groups["address"], - Position: groups["position"], - Position2: strings.TrimSpace(groups["position2"]), - Name: strings.TrimSpace(groups["name"]), - Type: removeQuotes(groups["type"]), - Type2: type2, - IsImplicit: len(groups["implicit"]) > 0, + Address: groups["address"], + Position: groups["position"], + Position2: strings.TrimSpace(groups["position2"]), + Name: strings.TrimSpace(groups["name"]), + Type: removeQuotes(groups["type"]), + Type2: type2, + IsImplicit: len(groups["implicit"]) > 0, IsReferenced: len(groups["referenced"]) > 0, - Children: []interface{}{}, + Children: []interface{}{}, } } diff --git a/typedef_type.go b/typedef_type.go index a54327441..b061adec5 100644 --- a/typedef_type.go +++ b/typedef_type.go @@ -1,9 +1,9 @@ package main type TypedefType struct { - Address string - Type string - Tags string + Address string + Type string + Tags string Children []interface{} } @@ -14,9 +14,9 @@ func parseTypedefType(line string) *TypedefType { ) return &TypedefType{ - Address: groups["address"], - Type: groups["type"], - Tags: groups["tags"], + Address: groups["address"], + Type: groups["type"], + Tags: groups["tags"], Children: []interface{}{}, } } diff --git a/unary_operator.go b/unary_operator.go index 6fb186bd1..7c9edd128 100644 --- a/unary_operator.go +++ b/unary_operator.go @@ -22,9 +22,9 @@ func parseUnaryOperator(line string) *UnaryOperator { ) return &UnaryOperator{ - Address: groups["address"], + Address: groups["address"], Position: groups["position"], - Type: groups["type"], + Type: groups["type"], IsLvalue: len(groups["lvalue"]) > 0, IsPrefix: len(groups["prefix"]) > 0, Operator: groups["operator"], diff --git a/var_decl.go b/var_decl.go index 82eea025e..33583fd8c 100644 --- a/var_decl.go +++ b/var_decl.go @@ -29,19 +29,19 @@ func parseVarDecl(line string) *VarDecl { type2 := groups["type2"] if type2 != "" { - type2 = type2[2:len(type2) - 1] + type2 = type2[2 : len(type2)-1] } return &VarDecl{ - Address: groups["address"], - Position: groups["position"], + 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: []interface{}{}, + 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: []interface{}{}, } } diff --git a/while_stmt.go b/while_stmt.go index 9e35787ed..f4a3f9301 100644 --- a/while_stmt.go +++ b/while_stmt.go @@ -13,7 +13,7 @@ func parseWhileStmt(line string) *WhileStmt { ) return &WhileStmt{ - Address: groups["address"], + Address: groups["address"], Position: groups["position"], Children: []interface{}{}, } From c547ffb9cf0d9a6483ab33c0db0c7c20820df87b Mon Sep 17 00:00:00 2001 From: Elliot Chance Date: Fri, 14 Apr 2017 16:42:30 +1000 Subject: [PATCH 2/9] Removed the need for FunctionSubstitutions --- common.go | 55 ++---------------------- function_definition.go | 95 +++++++++++++++++++++++++++++++++++------- 2 files changed, 85 insertions(+), 65 deletions(-) diff --git a/common.go b/common.go index 74c8ec873..5c1dfc1ca 100644 --- a/common.go +++ b/common.go @@ -9,53 +9,6 @@ import ( "strings" ) -var FunctionSubstitutions = map[string]string{ - // math.h - "acos": "math.Acos", - "asin": "math.Asin", - "atan": "math.Atan", - "atan2": "math.Atan2", - "ceil": "math.Ceil", - "cos": "math.Cos", - "cosh": "math.Cosh", - "exp": "math.Exp", - "fabs": "math.Abs", - "floor": "math.Floor", - "fmod": "math.Mod", - "ldexp": "math.Ldexp", - "log": "math.Log", - "log10": "math.Log10", - "pow": "math.Pow", - "sin": "math.Sin", - "sinh": "math.Sinh", - "sqrt": "math.Sqrt", - "tan": "math.Tan", - "tanh": "math.Tanh", - - // stdio - "printf": "fmt.Printf", - "scanf": "fmt.Scanf", - - // darwin/math.h - "__builtin_fabs": "github.com/elliotchance/c2go/darwin.Fabs", - "__builtin_fabsf": "github.com/elliotchance/c2go/darwin.Fabsf", - "__builtin_fabsl": "github.com/elliotchance/c2go/darwin.Fabsl", - "__builtin_inf": "github.com/elliotchance/c2go/darwin.Inf", - "__builtin_inff": "github.com/elliotchance/c2go/darwin.Inff", - "__builtin_infl": "github.com/elliotchance/c2go/darwin.Infl", - "__sincospi_stret": "github.com/elliotchance/c2go/darwin.SincospiStret", - "__sincospif_stret": "github.com/elliotchance/c2go/darwin.SincospifStret", - "__sincos_stret": "github.com/elliotchance/c2go/darwin.SincosStret", - "__sincosf_stret": "github.com/elliotchance/c2go/darwin.SincosfStret", - - // darwin/assert.h - "__builtin_expect": "github.com/elliotchance/c2go/darwin.BuiltinExpect", - "__assert_rtn": "github.com/elliotchance/c2go/darwin.AssertRtn", - - // linux/assert.h - "__assert_fail": "github.com/elliotchance/c2go/linux.AssertFail", -} - // TODO: Some of these are based on assumptions that may not be true for all // architectures (like the size of an int). At some point in the future we will // need to find out the sizes of some of there and pick the most compatible type. @@ -208,7 +161,7 @@ func resolveType(s string) string { } // Enums are by name. - if s[:5] == "enum " { + if strings.HasPrefix(s, "enum ") { if s[len(s)-1] == '*' { return "*" + s[5:len(s)-2] } else { @@ -321,11 +274,11 @@ func renderExpression(node interface{}) []string { func_def := getFunctionDefinition(func_name) - if _, ok := FunctionSubstitutions[func_name]; ok { - parts := strings.Split(FunctionSubstitutions[func_name], ".") + if func_def.Substitution != "" { + parts := strings.Split(func_def.Substitution, ".") addImport(strings.Join(parts[:len(parts)-1], ".")) - parts2 := strings.Split(FunctionSubstitutions[func_name], "/") + parts2 := strings.Split(func_def.Substitution, "/") func_name = parts2[len(parts2)-1] } diff --git a/function_definition.go b/function_definition.go index 1c575d70f..ad1929045 100644 --- a/function_definition.go +++ b/function_definition.go @@ -7,19 +7,42 @@ import ( // FunctionDefinition contains the prototype definition for a function. type FunctionDefinition struct { + // The name of the function, like "printf". Name string + + // The C return type, like "int". ReturnType string + + // The C argument types, like ["bool", "int"]. There is currently no way + // to represent a varargs. ArgumentTypes []string + + // If this is not empty then this function name should be used instead + // of the Name. Many low level functions have an exact match with a Go + // function. For example, "sin()". + Substitution string } var functionDefinitions = map[string]FunctionDefinition{} var builtInFunctionDefinitionsHaveBeenLoaded = false +// Each of the predefined function have a syntax that allows them to be easy to +// read (and maintain). For example: +// +// double __builtin_fabs(double) -> darwin.Fabs +// +// Declares the prototype of __builtin_fabs (a low level function implemented +// only on Mac) with a specific substitution provided. This means that it should +// replace any instance of __builtin_fabs with: +// +// github.com/elliotchance/c2go/darwin.Fabs +// +// THe substitution is optional. var builtInFunctionDefinitions = []string{ // darwin/assert.h - "int __builtin_expect(int, int)", - "bool __assert_rtn(const char*, const char*, int, const char*)", + "int __builtin_expect(int, int) -> darwin.BuiltinExpect", + "bool __assert_rtn(const char*, const char*, int, const char*) -> darwin.AssertRtn", // darwin/ctype.h "uint32 __istype(__darwin_ct_rune_t, uint32)", @@ -29,19 +52,45 @@ var builtInFunctionDefinitions = []string{ "uint32 __maskrune(__darwin_ct_rune_t, uint32)", // darwin/math.h - "double __builtin_fabs(double)", - "float __builtin_fabsf(float)", - "double __builtin_fabsl(double)", - "double __builtin_inf()", - "float __builtin_inff()", - "double __builtin_infl()", - "Double2 __sincospi_stret(double)", - "Float2 __sincospif_stret(float)", - "Double2 __sincos_stret(double)", - "Float2 __sincosf_stret(float)", + "double __builtin_fabs(double) -> darwin.Fabs", + "float __builtin_fabsf(float) -> darwin.Fabsf", + "double __builtin_fabsl(double) -> darwin.Fabsl", + "double __builtin_inf() -> darwin.Inf", + "float __builtin_inff() -> darwin.Inff", + "double __builtin_infl() -> darwin.Infl", + "Double2 __sincospi_stret(double) -> darwin.SincospiStret", + "Float2 __sincospif_stret(float) -> darwin.SincospifStret", + "Double2 __sincos_stret(double) -> darwin.SincosStret", + "Float2 __sincosf_stret(float) -> darwin.SincosfStret", // linux/assert.h - "bool __assert_fail(const char*, const char*, unsigned int, const char*)", + "bool __assert_fail(const char*, const char*, unsigned int, const char*) -> linux.AssertFail", + + // math.h + "double acos(double) -> math.Acos", + "double asin(double) -> math.Asin", + "double atan(double) -> math.Atan", + "double atan2(double) -> math.Atan2", + "double ceil(double) -> math.Ceil", + "double cos(double) -> math.Cos", + "double cosh(double) -> math.Cosh", + "double exp(double) -> math.Exp", + "double fabs(double) -> math.Abs", + "double floor(double) -> math.Floor", + "double fmod(double) -> math.Mod", + "double ldexp(double) -> math.Ldexp", + "double log(double) -> math.Log", + "double log10(double) -> math.Log10", + "double pow(double) -> math.Pow", + "double sin(double) -> math.Sin", + "double sinh(double) -> math.Sinh", + "double sqrt(double) -> math.Sqrt", + "double tan(double) -> math.Tan", + "double tanh(double) -> math.Tanh", + + // stdio.h + "int printf() -> fmt.Printf", + "int scanf() -> fmt.Scanf", } // getFunctionDefinition will return nil if the function does not exist (is not @@ -49,6 +98,8 @@ var builtInFunctionDefinitions = []string{ func getFunctionDefinition(functionName string) FunctionDefinition { loadFunctionDefinitions() + //fmt.Printf("%#v", functionDefinitions) + return functionDefinitions[functionName] } @@ -68,18 +119,34 @@ func loadFunctionDefinitions() { builtInFunctionDefinitionsHaveBeenLoaded = true for _, f := range builtInFunctionDefinitions { - match := regexp.MustCompile(`^(.+) (.+)\((.*)\)$`). + match := regexp.MustCompile(`^(.+) (.+)\((.*)\)( -> .*)?$`). FindStringSubmatch(f) + // Unpack argument types. argumentTypes := strings.Split(match[3], ",") for i := range argumentTypes { argumentTypes[i] = strings.TrimSpace(argumentTypes[i]) } + if len(argumentTypes) == 1 && argumentTypes[0] == "" { + argumentTypes = []string{} + } + + // Substitution rules. + substitution := match[4] + if substitution != "" { + substitution = strings.TrimLeft(substitution, " ->") + } + if strings.HasPrefix(substitution, "darwin.") || + strings.HasPrefix(substitution, "linux.") || + strings.HasPrefix(substitution, "noarch.") { + substitution = "github.com/elliotchance/c2go/" + substitution + } addFunctionDefinition(FunctionDefinition{ Name: match[2], ReturnType: match[1], ArgumentTypes: argumentTypes, + Substitution: substitution, }) } } From d83bc7fb9a2f26987c5c74b7097d643117de6d08 Mon Sep 17 00:00:00 2001 From: Elliot Chance Date: Fri, 14 Apr 2017 16:52:09 +1000 Subject: [PATCH 3/9] Moved code to do with types into resolve.go --- common.go | 174 ++--------------------------------------------------- resolve.go | 168 +++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 173 insertions(+), 169 deletions(-) create mode 100644 resolve.go diff --git a/common.go b/common.go index 5c1dfc1ca..2c2254033 100644 --- a/common.go +++ b/common.go @@ -4,70 +4,10 @@ import ( "bytes" "fmt" "reflect" - "regexp" "strconv" "strings" ) -// TODO: Some of these are based on assumptions that may not be true for all -// architectures (like the size of an int). At some point in the future we will -// need to find out the sizes of some of there and pick the most compatible type. -// -// Please keep them sorted by name. -var SimpleResolveTypes = map[string]string{ - "bool": "bool", - "char *": "string", - "char": "byte", - "char*": "string", - "double": "float64", - "float": "float32", - "int": "int", - "long double": "float64", - "long int": "int32", - "long long": "int64", - "long unsigned int": "uint32", - "long": "int32", - "short": "int16", - "signed char": "int8", - "unsigned char": "uint8", - "unsigned int": "uint32", - "unsigned long long": "uint64", - "unsigned long": "uint32", - "unsigned short": "uint16", - "void *": "interface{}", - "void": "", - - "const char *": "string", - - // Darwin specific - "__darwin_ct_rune_t": "__darwin_ct_rune_t", - "union __mbstate_t": "__mbstate_t", - "fpos_t": "int", - "struct __float2": "github.com/elliotchance/c2go/darwin.Float2", - "struct __double2": "github.com/elliotchance/c2go/darwin.Double2", - - // These are special cases that almost certainly don"t work. I've put - // them here because for whatever reason there is no suitable type or we - // don't need these platform specific things to be implemented yet. - "__builtin_va_list": "int64", - "__darwin_pthread_handler_rec": "int64", - "__int128": "int64", - "__mbstate_t": "int64", - "__sbuf": "int64", - "__sFILEX": "interface{}", - "__va_list_tag": "interface{}", - "FILE": "int64", -} - -var TypesAlreadyDefined = []string{ - // Linux specific - "_LIB_VERSION_TYPE", - - // Darwin specific - "__float2", - "__double2", -} - var Imports = []string{"fmt"} func ucfirst(word string) string { @@ -100,108 +40,6 @@ func importType(typeName string) string { return typeName } -func isKeyword(w string) bool { - return w == "char" || w == "long" || w == "struct" || w == "void" -} - -func isIdentifier(w string) bool { - return !isKeyword(w) && regexp.MustCompile("[_a-zA-Z][_a-zA-Z0-9]*"). - MatchString(w) -} - -func resolveType(s string) string { - // Remove any whitespace or attributes that are not relevant to Go. - s = strings.Replace(s, "const ", "", -1) - s = strings.Replace(s, "*__restrict", "*", -1) - s = strings.Replace(s, "*restrict", "*", -1) - s = strings.Trim(s, " \t\n\r") - - if s == "fpos_t" { - return "int" - } - - // The simple resolve types are the types that we know there is an exact Go - // equivalent. For example float, int, etc. - for k, v := range SimpleResolveTypes { - if k == s { - return importType(v) - } - } - - // If the type is already defined we can proceed with the same name. - for _, v := range TypesAlreadyDefined { - if v == s { - return importType(s) - } - } - - // Structures are by name. - if strings.HasPrefix(s, "struct ") { - if s[len(s)-1] == '*' { - s = s[7 : len(s)-2] - - for _, v := range SimpleResolveTypes { - if v == s { - return "*" + importType(SimpleResolveTypes[s]) - } - } - - return "*" + s - } else { - s = s[7:] - - for _, v := range SimpleResolveTypes { - if v == s { - return importType(SimpleResolveTypes[s]) - } - } - - return s - } - } - - // Enums are by name. - if strings.HasPrefix(s, "enum ") { - if s[len(s)-1] == '*' { - return "*" + s[5:len(s)-2] - } else { - return s[5:] - } - } - - // I have no idea how to handle this yet. - if strings.Index(s, "anonymous union") != -1 { - return "interface{}" - } - - // It may be a pointer of a simple type. For example, float *, int *, - // etc. - if regexp.MustCompile("[\\w ]+\\*+$").MatchString(s) { - return "*" + resolveType(strings.TrimSpace(s[:len(s)-2])) - } - - // Function pointers are not yet supported. In th mean time they will be - // replaced with a type that certainly wont work until we can fix this - // properly. - search := regexp.MustCompile("[\\w ]+\\(\\*.*?\\)\\(.*\\)").MatchString(s) - if search { - return "interface{}" - } - - search = regexp.MustCompile("[\\w ]+ \\(.*\\)").MatchString(s) - if search { - return "interface{}" - } - - // It could be an array of fixed length. - search2 := regexp.MustCompile("([\\w ]+)\\[(\\d+)\\]").FindStringSubmatch(s) - if len(search2) > 0 { - return fmt.Sprintf("[%s]%s", search2[2], resolveType(search2[1])) - } - - panic(fmt.Sprintf("'%s'", s)) -} - func inStrings(item string, items []string) bool { for _, v := range items { if item == v { @@ -511,13 +349,11 @@ func Render(out *bytes.Buffer, node interface{}, function_name string, indent in case *TypedefDecl: name := strings.TrimSpace(n.Name) - for _, v := range TypesAlreadyDefined { - if name == v { - return - } + if typeIsAlreadyDefined(name) { + return } - TypesAlreadyDefined = append(TypesAlreadyDefined, name) + typeIsNowDefined(name) // FIXME: All of the logic here is just to avoid errors, it // needs to be fixed up. @@ -549,11 +385,11 @@ func Render(out *bytes.Buffer, node interface{}, function_name string, indent in case *RecordDecl: name := strings.TrimSpace(n.Name) - if inStrings(name, TypesAlreadyDefined) || name == "" { + if name == "" || typeIsAlreadyDefined(name) { return } - TypesAlreadyDefined = append(TypesAlreadyDefined, name) + typeIsNowDefined(name) if n.Kind == "union" { return diff --git a/resolve.go b/resolve.go new file mode 100644 index 000000000..ddf2956fc --- /dev/null +++ b/resolve.go @@ -0,0 +1,168 @@ +package main + +import ( + "strings" + "regexp" + "fmt" +) + +// TODO: Some of these are based on assumptions that may not be true for all +// architectures (like the size of an int). At some point in the future we will +// need to find out the sizes of some of there and pick the most compatible +// type. +// +// Please keep them sorted by name. +var simpleResolveTypes = map[string]string{ + "bool": "bool", + "char *": "string", + "char": "byte", + "char*": "string", + "double": "float64", + "float": "float32", + "int": "int", + "long double": "float64", + "long int": "int32", + "long long": "int64", + "long unsigned int": "uint32", + "long": "int32", + "short": "int16", + "signed char": "int8", + "unsigned char": "uint8", + "unsigned int": "uint32", + "unsigned long long": "uint64", + "unsigned long": "uint32", + "unsigned short": "uint16", + "void *": "interface{}", + "void": "", + + "const char *": "string", + + // Darwin specific + "__darwin_ct_rune_t": "__darwin_ct_rune_t", + "union __mbstate_t": "__mbstate_t", + "fpos_t": "int", + "struct __float2": "github.com/elliotchance/c2go/darwin.Float2", + "struct __double2": "github.com/elliotchance/c2go/darwin.Double2", + + // These are special cases that almost certainly don"t work. I've put + // them here because for whatever reason there is no suitable type or we + // don't need these platform specific things to be implemented yet. + "__builtin_va_list": "int64", + "__darwin_pthread_handler_rec": "int64", + "__int128": "int64", + "__mbstate_t": "int64", + "__sbuf": "int64", + "__sFILEX": "interface{}", + "__va_list_tag": "interface{}", + "FILE": "int64", +} + +var TypesAlreadyDefined = []string{ + // Linux specific. + "_LIB_VERSION_TYPE", + + // Darwin specific. + "__float2", + "__double2", +} + +func typeIsAlreadyDefined(typeName string) bool { + return inStrings(typeName, TypesAlreadyDefined) +} + +func typeIsNowDefined(typeName string) { + TypesAlreadyDefined = append(TypesAlreadyDefined, typeName) +} + +func resolveType(s string) string { + // Remove any whitespace or attributes that are not relevant to Go. + s = strings.Replace(s, "const ", "", -1) + s = strings.Replace(s, "*__restrict", "*", -1) + s = strings.Replace(s, "*restrict", "*", -1) + s = strings.Trim(s, " \t\n\r") + + if s == "fpos_t" { + return "int" + } + + // The simple resolve types are the types that we know there is an exact Go + // equivalent. For example float, int, etc. + for k, v := range simpleResolveTypes { + if k == s { + return importType(v) + } + } + + // If the type is already defined we can proceed with the same name. + for _, v := range TypesAlreadyDefined { + if v == s { + return importType(s) + } + } + + // Structures are by name. + if strings.HasPrefix(s, "struct ") { + if s[len(s)-1] == '*' { + s = s[7 : len(s)-2] + + for _, v := range simpleResolveTypes { + if v == s { + return "*" + importType(simpleResolveTypes[s]) + } + } + + return "*" + s + } else { + s = s[7:] + + for _, v := range simpleResolveTypes { + if v == s { + return importType(simpleResolveTypes[s]) + } + } + + return s + } + } + + // Enums are by name. + if strings.HasPrefix(s, "enum ") { + if s[len(s)-1] == '*' { + return "*" + s[5:len(s)-2] + } else { + return s[5:] + } + } + + // I have no idea how to handle this yet. + if strings.Index(s, "anonymous union") != -1 { + return "interface{}" + } + + // It may be a pointer of a simple type. For example, float *, int *, + // etc. + if regexp.MustCompile("[\\w ]+\\*+$").MatchString(s) { + return "*" + resolveType(strings.TrimSpace(s[:len(s)-2])) + } + + // Function pointers are not yet supported. In th mean time they will be + // replaced with a type that certainly wont work until we can fix this + // properly. + search := regexp.MustCompile("[\\w ]+\\(\\*.*?\\)\\(.*\\)").MatchString(s) + if search { + return "interface{}" + } + + search = regexp.MustCompile("[\\w ]+ \\(.*\\)").MatchString(s) + if search { + return "interface{}" + } + + // It could be an array of fixed length. + search2 := regexp.MustCompile("([\\w ]+)\\[(\\d+)\\]").FindStringSubmatch(s) + if len(search2) > 0 { + return fmt.Sprintf("[%s]%s", search2[2], resolveType(search2[1])) + } + + panic(fmt.Sprintf("'%s'", s)) +} From d04cc3c0b7b994145ccfdfb1730f397b4ba5313c Mon Sep 17 00:00:00 2001 From: Elliot Chance Date: Fri, 14 Apr 2017 16:53:42 +1000 Subject: [PATCH 4/9] Created util.go --- common.go | 8 -------- util.go | 11 +++++++++++ 2 files changed, 11 insertions(+), 8 deletions(-) create mode 100644 util.go diff --git a/common.go b/common.go index 2c2254033..c46201c9a 100644 --- a/common.go +++ b/common.go @@ -10,14 +10,6 @@ import ( var Imports = []string{"fmt"} -func ucfirst(word string) string { - return strings.ToUpper(string(word[0])) + word[1:] -} - -func getExportedName(field string) string { - return ucfirst(strings.TrimLeft(field, "_")) -} - func addImport(importName string) { for _, i := range Imports { if i == importName { diff --git a/util.go b/util.go new file mode 100644 index 000000000..35ae04215 --- /dev/null +++ b/util.go @@ -0,0 +1,11 @@ +package main + +import "strings" + +func ucfirst(word string) string { + return strings.ToUpper(string(word[0])) + word[1:] +} + +func getExportedName(field string) string { + return ucfirst(strings.TrimLeft(field, "_")) +} From 300ee252012b392e71a60cb1fda155b0f190e7df Mon Sep 17 00:00:00 2001 From: Elliot Chance Date: Fri, 14 Apr 2017 16:55:55 +1000 Subject: [PATCH 5/9] Created import.go --- common.go | 34 ---------------------------------- import.go | 27 +++++++++++++++++++++++++++ util.go | 10 ++++++++++ 3 files changed, 37 insertions(+), 34 deletions(-) create mode 100644 import.go diff --git a/common.go b/common.go index c46201c9a..2bc2ba379 100644 --- a/common.go +++ b/common.go @@ -8,40 +8,6 @@ import ( "strings" ) -var Imports = []string{"fmt"} - -func addImport(importName string) { - for _, i := range Imports { - if i == importName { - return - } - } - - Imports = append(Imports, importName) -} - -func importType(typeName string) string { - if strings.Index(typeName, ".") != -1 { - parts := strings.Split(typeName, ".") - addImport(strings.Join(parts[:len(parts)-1], ".")) - - parts2 := strings.Split(typeName, "/") - return parts2[len(parts2)-1] - } - - return typeName -} - -func inStrings(item string, items []string) bool { - for _, v := range items { - if item == v { - return true - } - } - - return false -} - func cast(expr, fromType, toType string) string { fromType = resolveType(fromType) toType = resolveType(toType) diff --git a/import.go b/import.go new file mode 100644 index 000000000..133f9d25d --- /dev/null +++ b/import.go @@ -0,0 +1,27 @@ +package main + +import "strings" + +var Imports = []string{"fmt"} + +func addImport(importName string) { + for _, i := range Imports { + if i == importName { + return + } + } + + Imports = append(Imports, importName) +} + +func importType(typeName string) string { + if strings.Index(typeName, ".") != -1 { + parts := strings.Split(typeName, ".") + addImport(strings.Join(parts[:len(parts)-1], ".")) + + parts2 := strings.Split(typeName, "/") + return parts2[len(parts2)-1] + } + + return typeName +} diff --git a/util.go b/util.go index 35ae04215..0253b66c3 100644 --- a/util.go +++ b/util.go @@ -9,3 +9,13 @@ func ucfirst(word string) string { func getExportedName(field string) string { return ucfirst(strings.TrimLeft(field, "_")) } + +func inStrings(item string, items []string) bool { + for _, v := range items { + if item == v { + return true + } + } + + return false +} From 6bfb8850c622535b9df7d939e96a27dda19eee84 Mon Sep 17 00:00:00 2001 From: Elliot Chance Date: Fri, 14 Apr 2017 17:16:46 +1000 Subject: [PATCH 6/9] Starting to split up Render() --- ast.go | 53 ++++++--------------------------------------------- cast.go | 32 +++++++++++++++++++++++++++++++ common.go | 49 +---------------------------------------------- field_decl.go | 27 +++++++++++++++++++++++++- util.go | 51 ++++++++++++++++++++++++++++++++++++++++++++++++- 5 files changed, 115 insertions(+), 97 deletions(-) create mode 100644 cast.go diff --git a/ast.go b/ast.go index 88156ecfd..f6187c3aa 100644 --- a/ast.go +++ b/ast.go @@ -2,10 +2,15 @@ package main import ( "regexp" - "strconv" "strings" ) +type Renderer interface { + // TODO: The two arguments returned are the rendered Go and the C type. + // This should be made into an appropriate type. + Render() []string +} + func Parse(line string) interface{} { nodeName := strings.SplitN(line, " ", 2)[0] var node interface{} @@ -149,49 +154,3 @@ func groupsFromRegex(rx, line string) map[string]string { return result } - -func atoi(s string) int { - i, err := strconv.Atoi(s) - if err != nil { - panic(err) - } - - return i -} - -func removeQuotes(s string) string { - s = strings.TrimSpace(s) - - if s == `""` { - return "" - } - if s == `''` { - return "" - } - - if len(s) >= 2 && s[0] == '"' && s[len(s)-1] == '"' { - return s[1 : len(s)-2] - } - if len(s) >= 2 && s[0] == '\'' && s[len(s)-1] == '\'' { - return s[1 : len(s)-1] - } - - return s -} - -func atof(s string) float64 { - f, err := strconv.ParseFloat(s, 64) - if err != nil { - panic(err) - } - - return f -} - -func unescapeString(s string) string { - s = strings.Replace(s, "\\n", "\n", -1) - s = strings.Replace(s, "\\r", "\r", -1) - s = strings.Replace(s, "\\t", "\t", -1) - - return s -} diff --git a/cast.go b/cast.go new file mode 100644 index 000000000..0e3e24986 --- /dev/null +++ b/cast.go @@ -0,0 +1,32 @@ +package main + +import "fmt" + +func cast(expr, fromType, toType string) string { + fromType = resolveType(fromType) + toType = resolveType(toType) + + if fromType == toType { + return expr + } + + types := []string{"int", "int64", "uint32", "__darwin_ct_rune_t", + "byte", "float32", "float64"} + + for _, v := range types { + if fromType == v && toType == "bool" { + return fmt.Sprintf("%s != 0", expr) + } + } + + if fromType == "*int" && toType == "bool" { + return fmt.Sprintf("%s != nil", expr) + } + + if inStrings(fromType, types) && inStrings(toType, types) { + return fmt.Sprintf("%s(%s)", toType, expr) + } + + addImport("github.com/elliotchance/c2go/noarch") + return fmt.Sprintf("noarch.%sTo%s(%s)", ucfirst(fromType), ucfirst(toType), expr) +} diff --git a/common.go b/common.go index 2bc2ba379..87502c863 100644 --- a/common.go +++ b/common.go @@ -8,35 +8,6 @@ import ( "strings" ) -func cast(expr, fromType, toType string) string { - fromType = resolveType(fromType) - toType = resolveType(toType) - - if fromType == toType { - return expr - } - - types := []string{"int", "int64", "uint32", "__darwin_ct_rune_t", - "byte", "float32", "float64"} - - for _, v := range types { - if fromType == v && toType == "bool" { - return fmt.Sprintf("%s != 0", expr) - } - } - - if fromType == "*int" && toType == "bool" { - return fmt.Sprintf("%s != nil", expr) - } - - if inStrings(fromType, types) && inStrings(toType, types) { - return fmt.Sprintf("%s(%s)", toType, expr) - } - - addImport("github.com/elliotchance/c2go/noarch") - return fmt.Sprintf("noarch.%sTo%s(%s)", ucfirst(fromType), ucfirst(toType), expr) -} - func printLine(out *bytes.Buffer, line string, indent int) { out.WriteString(fmt.Sprintf("%s%s\n", strings.Repeat("\t", indent), line)) } @@ -44,25 +15,7 @@ func printLine(out *bytes.Buffer, line string, indent int) { func renderExpression(node interface{}) []string { switch n := node.(type) { case *FieldDecl: - fieldType := resolveType(n.Type) - name := strings.Replace(n.Name, "used", "", -1) - - // Go does not allow the name of a variable to be called "type". - // For the moment I will rename this to avoid the error. - if name == "type" { - name = "type_" - } - - suffix := "" - if len(n.Children) > 0 { - suffix = fmt.Sprintf(" = %s", renderExpression(n.Children[0])[0]) - } - - if suffix == " = (0)" { - suffix = " = nil" - } - - return []string{fmt.Sprintf("%s %s%s", name, fieldType, suffix), "unknown3"} + return n.Render() case *CallExpr: children := n.Children diff --git a/field_decl.go b/field_decl.go index 7de213c25..68af59a53 100644 --- a/field_decl.go +++ b/field_decl.go @@ -1,6 +1,9 @@ package main -import "strings" +import ( + "strings" + "fmt" +) type FieldDecl struct { Address string @@ -32,3 +35,25 @@ func parseFieldDecl(line string) *FieldDecl { Children: []interface{}{}, } } + +func (n *FieldDecl) Render() []string { + fieldType := resolveType(n.Type) + name := strings.Replace(n.Name, "used", "", -1) + + // Go does not allow the name of a variable to be called "type". For the + // moment I will rename this to avoid the error. + if name == "type" { + name = "type_" + } + + suffix := "" + if len(n.Children) > 0 { + suffix = fmt.Sprintf(" = %s", renderExpression(n.Children[0])[0]) + } + + if suffix == " = (0)" { + suffix = " = nil" + } + + return []string{fmt.Sprintf("%s %s%s", name, fieldType, suffix), "unknown3"} +} diff --git a/util.go b/util.go index 0253b66c3..8592e6451 100644 --- a/util.go +++ b/util.go @@ -1,6 +1,9 @@ package main -import "strings" +import ( + "strings" + "strconv" +) func ucfirst(word string) string { return strings.ToUpper(string(word[0])) + word[1:] @@ -19,3 +22,49 @@ func inStrings(item string, items []string) bool { return false } + +func atoi(s string) int { + i, err := strconv.Atoi(s) + if err != nil { + panic(err) + } + + return i +} + +func removeQuotes(s string) string { + s = strings.TrimSpace(s) + + if s == `""` { + return "" + } + if s == `''` { + return "" + } + + if len(s) >= 2 && s[0] == '"' && s[len(s)-1] == '"' { + return s[1 : len(s)-2] + } + if len(s) >= 2 && s[0] == '\'' && s[len(s)-1] == '\'' { + return s[1 : len(s)-1] + } + + return s +} + +func atof(s string) float64 { + f, err := strconv.ParseFloat(s, 64) + if err != nil { + panic(err) + } + + return f +} + +func unescapeString(s string) string { + s = strings.Replace(s, "\\n", "\n", -1) + s = strings.Replace(s, "\\r", "\r", -1) + s = strings.Replace(s, "\\t", "\t", -1) + + return s +} From f524827b3317882f729def55b714ab2d88ebcc92 Mon Sep 17 00:00:00 2001 From: Elliot Chance Date: Fri, 14 Apr 2017 17:28:07 +1000 Subject: [PATCH 7/9] Split renderExpression() --- array_subscript_expr.go | 8 ++ binary_operator.go | 26 +++++ c_style_cast_expr.go | 5 + call_expr.go | 47 +++++++++ common.go | 213 +--------------------------------------- conditional_operator.go | 14 +++ decl_ref_expr.go | 14 +++ floating_literal.go | 6 ++ implicit_cast_expr.go | 4 + integer_literal.go | 12 +++ member_expr.go | 19 ++++ paren_expr.go | 7 ++ predefined_expr.go | 16 +++ string_literal.go | 12 +++ unary_operator.go | 34 +++++++ var_decl.go | 28 +++++- 16 files changed, 254 insertions(+), 211 deletions(-) diff --git a/array_subscript_expr.go b/array_subscript_expr.go index bc9d0c9d4..1516aeb38 100644 --- a/array_subscript_expr.go +++ b/array_subscript_expr.go @@ -1,5 +1,7 @@ package main +import "fmt" + type ArraySubscriptExpr struct { Address string Position string @@ -22,3 +24,9 @@ func parseArraySubscriptExpr(line string) *ArraySubscriptExpr { Children: []interface{}{}, } } + +func (n *ArraySubscriptExpr) Render() []string { + children := n.Children + return []string{fmt.Sprintf("%s[%s]", renderExpression(children[0])[0], + renderExpression(children[1])[0]), "unknown1"} +} diff --git a/binary_operator.go b/binary_operator.go index 18ea9fb5b..8ea831d3a 100644 --- a/binary_operator.go +++ b/binary_operator.go @@ -1,5 +1,7 @@ package main +import "fmt" + type BinaryOperator struct { Address string Position string @@ -22,3 +24,27 @@ func parseBinaryOperator(line string) *BinaryOperator { Children: []interface{}{}, } } + +func (n *BinaryOperator) Render() []string { + operator := n.Operator + + left := renderExpression(n.Children[0]) + right := renderExpression(n.Children[1]) + + return_type := "bool" + if inStrings(operator, []string{"|", "&", "+", "-", "*", "/"}) { + // TODO: The left and right type might be different + return_type = left[1] + } + + if operator == "&&" { + left[0] = cast(left[0], left[1], return_type) + right[0] = cast(right[0], right[1], return_type) + } + + if (operator == "!=" || operator == "==") && right[0] == "(0)" { + right[0] = "nil" + } + + return []string{fmt.Sprintf("%s %s %s", left[0], operator, right[0]), return_type} +} diff --git a/c_style_cast_expr.go b/c_style_cast_expr.go index c5aa95843..d1994069d 100644 --- a/c_style_cast_expr.go +++ b/c_style_cast_expr.go @@ -22,3 +22,8 @@ func parseCStyleCastExpr(line string) *CStyleCastExpr { Children: []interface{}{}, } } + +func (n *CStyleCastExpr) Render() []string { + children := n.Children + return renderExpression(children[0]) +} diff --git a/call_expr.go b/call_expr.go index 87732d639..801e17394 100644 --- a/call_expr.go +++ b/call_expr.go @@ -1,5 +1,10 @@ package main +import ( + "strings" + "fmt" +) + type CallExpr struct { Address string Position string @@ -20,3 +25,45 @@ func parseCallExpr(line string) *CallExpr { Children: []interface{}{}, } } + +func (n *CallExpr) Render() []string { + children := n.Children + func_name := renderExpression(children[0])[0] + + func_def := getFunctionDefinition(func_name) + + if func_def.Substitution != "" { + parts := strings.Split(func_def.Substitution, ".") + addImport(strings.Join(parts[:len(parts)-1], ".")) + + parts2 := strings.Split(func_def.Substitution, "/") + func_name = parts2[len(parts2)-1] + } + + args := []string{} + i := 0 + for _, arg := range children[1:] { + e := renderExpression(arg) + + if i > len(func_def.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[0]) + } else { + args = append(args, cast(e[0], e[1], func_def.ArgumentTypes[i])) + } + + i += 1 + } + + parts := []string{} + + for _, v := range args { + parts = append(parts, v) + } + + return []string{ + fmt.Sprintf("%s(%s)", func_name, strings.Join(parts, ", ")), + func_def.ReturnType} +} diff --git a/common.go b/common.go index 87502c863..f3ec3fdf4 100644 --- a/common.go +++ b/common.go @@ -4,7 +4,6 @@ import ( "bytes" "fmt" "reflect" - "strconv" "strings" ) @@ -13,217 +12,11 @@ func printLine(out *bytes.Buffer, line string, indent int) { } func renderExpression(node interface{}) []string { - switch n := node.(type) { - case *FieldDecl: + if n, ok := node.(Renderer); ok { return n.Render() - - case *CallExpr: - children := n.Children - func_name := renderExpression(children[0])[0] - - func_def := getFunctionDefinition(func_name) - - if func_def.Substitution != "" { - parts := strings.Split(func_def.Substitution, ".") - addImport(strings.Join(parts[:len(parts)-1], ".")) - - parts2 := strings.Split(func_def.Substitution, "/") - func_name = parts2[len(parts2)-1] - } - - args := []string{} - i := 0 - for _, arg := range children[1:] { - e := renderExpression(arg) - - if i > len(func_def.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[0]) - } else { - args = append(args, cast(e[0], e[1], func_def.ArgumentTypes[i])) - } - - i += 1 - } - - parts := []string{} - - for _, v := range args { - parts = append(parts, v) - } - - return []string{ - fmt.Sprintf("%s(%s)", func_name, strings.Join(parts, ", ")), - func_def.ReturnType} - - case *ImplicitCastExpr: - return renderExpression(n.Children[0]) - - case *DeclRefExpr: - name := n.Name - - if name == "argc" { - name = "len(os.Args)" - addImport("os") - } else if name == "argv" { - name = "os.Args" - addImport("os") - } - - return []string{name, n.Type} - - case *StringLiteral: - return []string{ - fmt.Sprintf("\"%s\"", strings.Replace(n.Value, "\n", "\\n", -1)), - "const char *", - } - - case *VarDecl: - theType := resolveType(n.Type) - name := n.Name - - // Go does not allow the name of a variable to be called "type". - // For the moment I will rename this to avoid the error. - if name == "type" { - name = "type_" - } - - suffix := "" - if len(n.Children) > 0 { - children := n.Children - suffix = fmt.Sprintf(" = %s", renderExpression(children[0])[0]) - } - - if suffix == " = (0)" { - suffix = " = nil" - } - - return []string{fmt.Sprintf("var %s %s%s", name, theType, suffix), "unknown3"} - - case *BinaryOperator: - operator := n.Operator - - left := renderExpression(n.Children[0]) - right := renderExpression(n.Children[1]) - - return_type := "bool" - if inStrings(operator, []string{"|", "&", "+", "-", "*", "/"}) { - // TODO: The left and right type might be different - return_type = left[1] - } - - if operator == "&&" { - left[0] = cast(left[0], left[1], return_type) - right[0] = cast(right[0], right[1], return_type) - } - - if (operator == "!=" || operator == "==") && right[0] == "(0)" { - right[0] = "nil" - } - - return []string{fmt.Sprintf("%s %s %s", left[0], operator, right[0]), return_type} - - case *IntegerLiteral: - literal := n.Value - - // FIXME - //if str(literal)[-1] == 'L': - // literal = '%s(%s)' % (resolveType('long'), literal[:-1]) - - return []string{strconv.FormatInt(int64(literal), 10), "int"} - - case *UnaryOperator: - operator := n.Operator - expr := renderExpression(n.Children[0]) - - if operator == "!" { - if expr[1] == "bool" { - return []string{fmt.Sprintf("!(%s)", expr[0]), expr[1]} - } - - addImport("github.com/elliotchance/c2go/noarch") - return []string{fmt.Sprintf("%s(%s)", fmt.Sprintf("noarch.Not%s", ucfirst(expr[1])), expr[0]), expr[1]} - } - - if operator == "*" { - if expr[1] == "const char *" { - return []string{fmt.Sprintf("%s[0]", expr[0]), "char"} - } - - return []string{fmt.Sprintf("*%s", expr[0]), "int"} - } - - if operator == "++" { - return []string{fmt.Sprintf("%s += 1", expr[0]), expr[1]} - } - - if operator == "~" { - operator = "^" - } - - return []string{fmt.Sprintf("%s%s", operator, expr[0]), expr[1]} - - case *ArraySubscriptExpr: - children := n.Children - return []string{fmt.Sprintf("%s[%s]", renderExpression(children[0])[0], - renderExpression(children[1])[0]), "unknown1"} - - case *ParenExpr: - a := renderExpression(n.Children[0]) - return []string{fmt.Sprintf("(%s)", a[0]), a[1]} - - case *ConditionalOperator: - a := renderExpression(n.Children[0])[0] - b := renderExpression(n.Children[1])[0] - c := renderExpression(n.Children[2])[0] - - addImport("github.com/elliotchance/c2go/noarch") - return []string{ - fmt.Sprintf("noarch.Ternary(%s, func () interface{} { return %s }, func () interface{} { return %s })", a, b, c), - n.Type, - } - - case *CStyleCastExpr: - children := n.Children - return renderExpression(children[0]) - - case *PredefinedExpr: - if n.Name == "__PRETTY_FUNCTION__" { - // FIXME - return []string{"\"void print_number(int *)\"", "const char*"} - } - - if n.Name == "__func__" { - // FIXME - return []string{fmt.Sprintf("\"%s\"", "print_number"), "const char*"} - } - - panic(fmt.Sprintf("renderExpression: unknown PredefinedExpr: %s", n.Name)) - - case *FloatingLiteral: - return []string{fmt.Sprintf("%f", n.Value), "double"} - - case *MemberExpr: - children := n.Children - - lhs := renderExpression(children[0]) - lhs_type := resolveType(lhs[1]) - rhs := n.Name - - if inStrings(lhs_type, []string{"darwin.Float2", "darwin.Double2"}) { - rhs = getExportedName(rhs) - } - - return []string{ - fmt.Sprintf("%s.%s", lhs[0], rhs), - children[0].(*DeclRefExpr).Type, - } - - default: - panic(fmt.Sprintf("renderExpression: %#v", n)) } + + panic(fmt.Sprintf("renderExpression: %#v", node)) } func getFunctionParams(f *FunctionDecl) []*ParmVarDecl { diff --git a/conditional_operator.go b/conditional_operator.go index 06208af0c..a552a3c83 100644 --- a/conditional_operator.go +++ b/conditional_operator.go @@ -1,5 +1,7 @@ package main +import "fmt" + type ConditionalOperator struct { Address string Position string @@ -20,3 +22,15 @@ func parseConditionalOperator(line string) *ConditionalOperator { Children: []interface{}{}, } } + +func (n *ConditionalOperator) Render() []string { + a := renderExpression(n.Children[0])[0] + b := renderExpression(n.Children[1])[0] + c := renderExpression(n.Children[2])[0] + + addImport("github.com/elliotchance/c2go/noarch") + return []string{ + fmt.Sprintf("noarch.Ternary(%s, func () interface{} { return %s }, func () interface{} { return %s })", a, b, c), + n.Type, + } +} diff --git a/decl_ref_expr.go b/decl_ref_expr.go index fe015e476..3488f78a6 100644 --- a/decl_ref_expr.go +++ b/decl_ref_expr.go @@ -37,3 +37,17 @@ func parseDeclRefExpr(line string) *DeclRefExpr { Children: []interface{}{}, } } + +func (n *DeclRefExpr) Render() []string { + name := n.Name + + if name == "argc" { + name = "len(os.Args)" + addImport("os") + } else if name == "argv" { + name = "os.Args" + addImport("os") + } + + return []string{name, n.Type} +} diff --git a/floating_literal.go b/floating_literal.go index ff028b29f..db3b95acf 100644 --- a/floating_literal.go +++ b/floating_literal.go @@ -1,5 +1,7 @@ package main +import "fmt" + type FloatingLiteral struct { Address string Position string @@ -22,3 +24,7 @@ func parseFloatingLiteral(line string) *FloatingLiteral { Children: []interface{}{}, } } + +func (n *FloatingLiteral) Render() []string { + return []string{fmt.Sprintf("%f", n.Value), "double"} +} diff --git a/implicit_cast_expr.go b/implicit_cast_expr.go index 99d46f345..a352f1898 100644 --- a/implicit_cast_expr.go +++ b/implicit_cast_expr.go @@ -22,3 +22,7 @@ func parseImplicitCastExpr(line string) *ImplicitCastExpr { Children: []interface{}{}, } } + +func (n *ImplicitCastExpr) Render() []string { + return renderExpression(n.Children[0]) +} diff --git a/integer_literal.go b/integer_literal.go index be1926131..bee1d6c67 100644 --- a/integer_literal.go +++ b/integer_literal.go @@ -1,5 +1,7 @@ package main +import "strconv" + type IntegerLiteral struct { Address string Position string @@ -22,3 +24,13 @@ func parseIntegerLiteral(line string) *IntegerLiteral { Children: []interface{}{}, } } + +func (n *IntegerLiteral) Render() []string { + literal := n.Value + + // FIXME + //if str(literal)[-1] == 'L': + // literal = '%s(%s)' % (resolveType('long'), literal[:-1]) + + return []string{strconv.FormatInt(int64(literal), 10), "int"} +} diff --git a/member_expr.go b/member_expr.go index 0c0fe4a68..85eafcf52 100644 --- a/member_expr.go +++ b/member_expr.go @@ -1,5 +1,7 @@ package main +import "fmt" + type MemberExpr struct { Address string Position string @@ -30,3 +32,20 @@ func parseMemberExpr(line string) *MemberExpr { Children: []interface{}{}, } } + +func (n *MemberExpr) Render() []string { + children := n.Children + + lhs := renderExpression(children[0]) + lhs_type := resolveType(lhs[1]) + rhs := n.Name + + if inStrings(lhs_type, []string{"darwin.Float2", "darwin.Double2"}) { + rhs = getExportedName(rhs) + } + + return []string{ + fmt.Sprintf("%s.%s", lhs[0], rhs), + children[0].(*DeclRefExpr).Type, + } +} diff --git a/paren_expr.go b/paren_expr.go index 10b65f22c..692464cc7 100644 --- a/paren_expr.go +++ b/paren_expr.go @@ -1,5 +1,7 @@ package main +import "fmt" + type ParenExpr struct { Address string Position string @@ -20,3 +22,8 @@ func parseParenExpr(line string) *ParenExpr { Children: []interface{}{}, } } + +func (n *ParenExpr) Render() []string { + a := renderExpression(n.Children[0]) + return []string{fmt.Sprintf("(%s)", a[0]), a[1]} +} diff --git a/predefined_expr.go b/predefined_expr.go index 66b358fd6..e993dbe4b 100644 --- a/predefined_expr.go +++ b/predefined_expr.go @@ -1,5 +1,7 @@ package main +import "fmt" + type PredefinedExpr struct { Address string Position string @@ -24,3 +26,17 @@ func parsePredefinedExpr(line string) *PredefinedExpr { Children: []interface{}{}, } } + +func (n *PredefinedExpr) Render() []string { + if n.Name == "__PRETTY_FUNCTION__" { + // FIXME + return []string{"\"void print_number(int *)\"", "const char*"} + } + + if n.Name == "__func__" { + // FIXME + return []string{fmt.Sprintf("\"%s\"", "print_number"), "const char*"} + } + + panic(fmt.Sprintf("renderExpression: unknown PredefinedExpr: %s", n.Name)) +} diff --git a/string_literal.go b/string_literal.go index b862aa0bf..c831cec32 100644 --- a/string_literal.go +++ b/string_literal.go @@ -1,5 +1,10 @@ package main +import ( + "fmt" + "strings" +) + type StringLiteral struct { Address string Position string @@ -24,3 +29,10 @@ func parseStringLiteral(line string) *StringLiteral { Children: []interface{}{}, } } + +func (n *StringLiteral) Render() []string { + return []string{ + fmt.Sprintf("\"%s\"", strings.Replace(n.Value, "\n", "\\n", -1)), + "const char *", + } +} diff --git a/unary_operator.go b/unary_operator.go index 7c9edd128..e86b6ac29 100644 --- a/unary_operator.go +++ b/unary_operator.go @@ -1,5 +1,7 @@ package main +import "fmt" + type UnaryOperator struct { Address string Position string @@ -31,3 +33,35 @@ func parseUnaryOperator(line string) *UnaryOperator { Children: []interface{}{}, } } + +func (n *UnaryOperator) Render() []string { + operator := n.Operator + expr := renderExpression(n.Children[0]) + + if operator == "!" { + if expr[1] == "bool" { + return []string{fmt.Sprintf("!(%s)", expr[0]), expr[1]} + } + + addImport("github.com/elliotchance/c2go/noarch") + return []string{fmt.Sprintf("%s(%s)", fmt.Sprintf("noarch.Not%s", ucfirst(expr[1])), expr[0]), expr[1]} + } + + if operator == "*" { + if expr[1] == "const char *" { + return []string{fmt.Sprintf("%s[0]", expr[0]), "char"} + } + + return []string{fmt.Sprintf("*%s", expr[0]), "int"} + } + + if operator == "++" { + return []string{fmt.Sprintf("%s += 1", expr[0]), expr[1]} + } + + if operator == "~" { + operator = "^" + } + + return []string{fmt.Sprintf("%s%s", operator, expr[0]), expr[1]} +} diff --git a/var_decl.go b/var_decl.go index 33583fd8c..7ff948a23 100644 --- a/var_decl.go +++ b/var_decl.go @@ -1,6 +1,9 @@ package main -import "strings" +import ( + "strings" + "fmt" +) type VarDecl struct { Address string @@ -45,3 +48,26 @@ func parseVarDecl(line string) *VarDecl { Children: []interface{}{}, } } + +func (n *VarDecl) Render() []string { + theType := resolveType(n.Type) + name := n.Name + + // Go does not allow the name of a variable to be called "type". + // For the moment I will rename this to avoid the error. + if name == "type" { + name = "type_" + } + + suffix := "" + if len(n.Children) > 0 { + children := n.Children + suffix = fmt.Sprintf(" = %s", renderExpression(children[0])[0]) + } + + if suffix == " = (0)" { + suffix = " = nil" + } + + return []string{fmt.Sprintf("var %s %s%s", name, theType, suffix), "unknown3"} +} From 5c2109d033fed8ef8555aca50620618a89da21fd Mon Sep 17 00:00:00 2001 From: Elliot Chance Date: Fri, 14 Apr 2017 17:47:20 +1000 Subject: [PATCH 8/9] Split up the Render() function --- ast.go | 7 +- break_stmt.go | 4 + common.go | 215 ++------------------------------------- compound_stmt.go | 8 ++ decl_stmt.go | 8 ++ enum_decl.go | 4 + for_stmt.go | 19 ++++ function_decl.go | 64 +++++++++++- if_stmt.go | 21 ++++ record_decl.go | 28 ++++- return_stmt.go | 13 +++ translation_unit_decl.go | 8 ++ typedef_decl.go | 41 +++++++- var_decl.go | 4 + while_stmt.go | 17 ++++ 15 files changed, 248 insertions(+), 213 deletions(-) diff --git a/ast.go b/ast.go index f6187c3aa..0d4a71db5 100644 --- a/ast.go +++ b/ast.go @@ -3,14 +3,19 @@ package main import ( "regexp" "strings" + "bytes" ) -type Renderer interface { +type ExpressionRenderer interface { // TODO: The two arguments returned are the rendered Go and the C type. // This should be made into an appropriate type. Render() []string } +type LineRenderer interface { + RenderLine(out *bytes.Buffer, functionName string, indent int, returnType string) +} + func Parse(line string) interface{} { nodeName := strings.SplitN(line, " ", 2)[0] var node interface{} diff --git a/break_stmt.go b/break_stmt.go index 3d45ff009..78954dd17 100644 --- a/break_stmt.go +++ b/break_stmt.go @@ -18,3 +18,7 @@ func parseBreakStmt(line string) *BreakStmt { Children: []interface{}{}, } } + +func (n *BreakStmt) Render() []string { + return []string{"break", ""} +} diff --git a/common.go b/common.go index f3ec3fdf4..1c1ffcbc0 100644 --- a/common.go +++ b/common.go @@ -3,7 +3,6 @@ package main import ( "bytes" "fmt" - "reflect" "strings" ) @@ -12,7 +11,7 @@ func printLine(out *bytes.Buffer, line string, indent int) { } func renderExpression(node interface{}) []string { - if n, ok := node.(Renderer); ok { + if n, ok := node.(ExpressionRenderer); ok { return n.Render() } @@ -44,213 +43,11 @@ func getFunctionReturnType(f string) string { return strings.TrimSpace(strings.Split(f, "(")[0]) } -func Render(out *bytes.Buffer, node interface{}, function_name string, indent int, return_type string) { - switch n := node.(type) { - case *TranslationUnitDecl: - for _, c := range n.Children { - Render(out, c, function_name, indent, return_type) - } - - case *TypedefDecl: - name := strings.TrimSpace(n.Name) - if typeIsAlreadyDefined(name) { - return - } - - typeIsNowDefined(name) - - // FIXME: All of the logic here is just to avoid errors, it - // needs to be fixed up. - // if ("struct" in node["type"] or "union" in node["type"]) and : - // return - n.Type = strings.Replace(n.Type, "unsigned", "", -1) - - resolved_type := resolveType(n.Type) - - if name == "__mbstate_t" { - addImport("github.com/elliotchance/c2go/darwin") - resolved_type = "darwin.C__mbstate_t" - } - - if name == "__darwin_ct_rune_t" { - addImport("github.com/elliotchance/c2go/darwin") - resolved_type = "darwin.C__darwin_ct_rune_t" - } - - if name == "__builtin_va_list" || name == "__qaddr_t" || name == "definition" || name == - "_IO_lock_t" || name == "va_list" || name == "fpos_t" || name == "__NSConstantString" || name == - "__darwin_va_list" || name == "__fsid_t" || name == "_G_fpos_t" || name == "_G_fpos64_t" { - return - } - - printLine(out, fmt.Sprintf("type %s %s\n", name, resolved_type), indent) - - return - - case *RecordDecl: - name := strings.TrimSpace(n.Name) - if name == "" || typeIsAlreadyDefined(name) { - return - } - - typeIsNowDefined(name) - - if n.Kind == "union" { - return - } - - printLine(out, fmt.Sprintf("type %s %s {", name, n.Kind), indent) - if len(n.Children) > 0 { - for _, c := range n.Children { - Render(out, c, function_name, indent+1, "") - } - } - - printLine(out, "}\n", indent) - return - - case *FieldDecl: - printLine(out, renderExpression(node)[0], indent+1) - return - - case *FunctionDecl: - function_name = strings.TrimSpace(n.Name) - - if function_name == "__istype" || function_name == "__isctype" || - function_name == "__wcwidth" || function_name == "__sputc" || - function_name == "__inline_signbitf" || - function_name == "__inline_signbitd" || - function_name == "__inline_signbitl" { - return - } - - has_body := false - if len(n.Children) > 0 { - for _, c := range n.Children { - if _, ok := c.(*CompoundStmt); ok { - has_body = true - } - } - } - - args := []string{} - for _, a := range getFunctionParams(n) { - args = append(args, fmt.Sprintf("%s %s", a.Name, resolveType(a.Type))) - } - - if has_body { - return_type := getFunctionReturnType(n.Type) - - if function_name == "main" { - printLine(out, "func main() {", indent) - } else { - printLine(out, fmt.Sprintf("func %s(%s) %s {", - function_name, strings.Join(args, ", "), - resolveType(return_type)), indent) - } - - for _, c := range n.Children { - if _, ok := c.(*CompoundStmt); ok { - Render(out, c, function_name, - indent+1, n.Type) - } - } - - printLine(out, "}\n", indent) - - params := []string{} - for _, v := range getFunctionParams(n) { - params = append(params, v.Type) - } - - addFunctionDefinition(FunctionDefinition{ - Name: n.Name, - ReturnType: getFunctionReturnType(n.Type), - ArgumentTypes: params, - }) - } - - case *VarDecl: - // FIXME? - - case *CompoundStmt: - for _, c := range n.Children { - Render(out, c, function_name, indent, return_type) - } - - case *CallExpr: - printLine(out, renderExpression(node)[0], indent) - - case *ReturnStmt: - r := "return" - - if len(n.Children) > 0 && function_name != "main" { - re := renderExpression(n.Children[0]) - r = "return " + cast(re[0], re[1], "int") - } - - printLine(out, r, indent) - - case *DeclStmt: - for _, child := range n.Children { - printLine(out, renderExpression(child)[0], indent) - } - - case *ForStmt: - children := n.Children - - a := renderExpression(children[0])[0] - b := renderExpression(children[1])[0] - c := renderExpression(children[2])[0] - - printLine(out, fmt.Sprintf("for %s; %s; %s {", a, b, c), indent) - - Render(out, children[3], function_name, indent+1, return_type) - - printLine(out, "}", indent) - - case *BinaryOperator: - printLine(out, renderExpression(node)[0], indent) - - case *ParenExpr: - printLine(out, renderExpression(node)[0], indent) - - case *IfStmt: - children := n.Children - - e := renderExpression(children[0]) - printLine(out, fmt.Sprintf("if %s {", cast(e[0], e[1], "bool")), indent) - - Render(out, children[1], function_name, indent+1, return_type) - - if len(children) > 2 { - printLine(out, "} else {", indent) - Render(out, children[2], function_name, indent+1, return_type) - } - - printLine(out, "}", indent) - - case *BreakStmt: - printLine(out, "break", indent) - - case *WhileStmt: - children := n.Children - - e := renderExpression(children[0]) - printLine(out, fmt.Sprintf("for %s {", cast(e[0], e[1], "bool")), indent) - - // FIXME: Does this do anything? - Render(out, children[1], function_name, indent+1, return_type) - - printLine(out, "}", indent) - - case *UnaryOperator: - printLine(out, renderExpression(node)[0], indent) - - case *EnumDecl: +func Render(out *bytes.Buffer, node interface{}, functionName string, indent int, returnType string) { + if n, ok := node.(LineRenderer); ok { + n.RenderLine(out, functionName, indent, returnType) return - - default: - panic(reflect.ValueOf(node).Elem().Type()) } + + printLine(out, renderExpression(node)[0], indent) } diff --git a/compound_stmt.go b/compound_stmt.go index 44d4d8045..067c9d5ab 100644 --- a/compound_stmt.go +++ b/compound_stmt.go @@ -1,5 +1,7 @@ package main +import "bytes" + type CompoundStmt struct { Address string Position string @@ -18,3 +20,9 @@ func parseCompoundStmt(line string) *CompoundStmt { Children: []interface{}{}, } } + +func (n *CompoundStmt) RenderLine(out *bytes.Buffer, functionName string, indent int, returnType string) { + for _, c := range n.Children { + Render(out, c, functionName, indent, returnType) + } +} diff --git a/decl_stmt.go b/decl_stmt.go index e6e50f1df..8fcac6fcf 100644 --- a/decl_stmt.go +++ b/decl_stmt.go @@ -1,5 +1,7 @@ package main +import "bytes" + type DeclStmt struct { Address string Position string @@ -18,3 +20,9 @@ func parseDeclStmt(line string) *DeclStmt { Children: []interface{}{}, } } + +func (n *DeclStmt) RenderLine(out *bytes.Buffer, functionName string, indent int, returnType string) { + for _, child := range n.Children { + printLine(out, renderExpression(child)[0], indent) + } +} diff --git a/enum_decl.go b/enum_decl.go index 9a1926f70..c0ef40a0b 100644 --- a/enum_decl.go +++ b/enum_decl.go @@ -24,3 +24,7 @@ func parseEnumDecl(line string) *EnumDecl { Children: []interface{}{}, } } + +func (n *EnumDecl) Render() []string { + return []string{"", ""} +} diff --git a/for_stmt.go b/for_stmt.go index cb80fdb48..5a7ddfe84 100644 --- a/for_stmt.go +++ b/for_stmt.go @@ -1,5 +1,10 @@ package main +import ( + "bytes" + "fmt" +) + type ForStmt struct { Address string Position string @@ -18,3 +23,17 @@ func parseForStmt(line string) *ForStmt { Children: []interface{}{}, } } + +func (n *ForStmt) RenderLine(out *bytes.Buffer, functionName string, indent int, returnType string) { + children := n.Children + + a := renderExpression(children[0])[0] + b := renderExpression(children[1])[0] + c := renderExpression(children[2])[0] + + printLine(out, fmt.Sprintf("for %s; %s; %s {", a, b, c), indent) + + Render(out, children[3], functionName, indent+1, returnType) + + printLine(out, "}", indent) +} diff --git a/function_decl.go b/function_decl.go index 68c608627..5f2f67124 100644 --- a/function_decl.go +++ b/function_decl.go @@ -1,6 +1,10 @@ package main -import "strings" +import ( + "strings" + "fmt" + "bytes" +) type FunctionDecl struct { Address string @@ -46,3 +50,61 @@ func parseFunctionDecl(line string) *FunctionDecl { Children: []interface{}{}, } } + +func (n *FunctionDecl) RenderLine(out *bytes.Buffer, functionName string, indent int, returnType string) { + functionName = strings.TrimSpace(n.Name) + + if functionName == "__istype" || functionName == "__isctype" || + functionName == "__wcwidth" || functionName == "__sputc" || + functionName == "__inline_signbitf" || + functionName == "__inline_signbitd" || + functionName == "__inline_signbitl" { + return + } + + has_body := false + if len(n.Children) > 0 { + for _, c := range n.Children { + if _, ok := c.(*CompoundStmt); ok { + has_body = true + } + } + } + + args := []string{} + for _, a := range getFunctionParams(n) { + args = append(args, fmt.Sprintf("%s %s", a.Name, resolveType(a.Type))) + } + + if has_body { + returnType := getFunctionReturnType(n.Type) + + if functionName == "main" { + printLine(out, "func main() {", indent) + } else { + printLine(out, fmt.Sprintf("func %s(%s) %s {", + functionName, strings.Join(args, ", "), + resolveType(returnType)), indent) + } + + for _, c := range n.Children { + if _, ok := c.(*CompoundStmt); ok { + Render(out, c, functionName, + indent+1, n.Type) + } + } + + printLine(out, "}\n", indent) + + params := []string{} + for _, v := range getFunctionParams(n) { + params = append(params, v.Type) + } + + addFunctionDefinition(FunctionDefinition{ + Name: n.Name, + ReturnType: getFunctionReturnType(n.Type), + ArgumentTypes: params, + }) + } +} diff --git a/if_stmt.go b/if_stmt.go index 20c2767f7..230531a6c 100644 --- a/if_stmt.go +++ b/if_stmt.go @@ -1,5 +1,10 @@ package main +import ( + "bytes" + "fmt" +) + type IfStmt struct { Address string Position string @@ -18,3 +23,19 @@ func parseIfStmt(line string) *IfStmt { Children: []interface{}{}, } } + +func (n *IfStmt) RenderLine(out *bytes.Buffer, functionName string, indent int, returnType string) { + children := n.Children + + e := renderExpression(children[0]) + printLine(out, fmt.Sprintf("if %s {", cast(e[0], e[1], "bool")), indent) + + Render(out, children[1], functionName, indent+1, returnType) + + if len(children) > 2 { + printLine(out, "} else {", indent) + Render(out, children[2], functionName, indent+1, returnType) + } + + printLine(out, "}", indent) +} diff --git a/record_decl.go b/record_decl.go index fc5094730..2b1b4b9db 100644 --- a/record_decl.go +++ b/record_decl.go @@ -1,6 +1,10 @@ package main -import "strings" +import ( + "strings" + "bytes" + "fmt" +) type RecordDecl struct { Address string @@ -45,3 +49,25 @@ func parseRecordDecl(line string) *RecordDecl { Children: []interface{}{}, } } + +func (n *RecordDecl) RenderLine(out *bytes.Buffer, functionName string, indent int, returnType string) { + name := strings.TrimSpace(n.Name) + if name == "" || typeIsAlreadyDefined(name) { + return + } + + typeIsNowDefined(name) + + if n.Kind == "union" { + return + } + + printLine(out, fmt.Sprintf("type %s %s {", name, n.Kind), indent) + if len(n.Children) > 0 { + for _, c := range n.Children { + Render(out, c, functionName, indent+1, "") + } + } + + printLine(out, "}\n", indent) +} diff --git a/return_stmt.go b/return_stmt.go index 1d464c9d8..e193b5c73 100644 --- a/return_stmt.go +++ b/return_stmt.go @@ -1,5 +1,7 @@ package main +import "bytes" + type ReturnStmt struct { Address string Position string @@ -18,3 +20,14 @@ func parseReturnStmt(line string) *ReturnStmt { Children: []interface{}{}, } } + +func (n *ReturnStmt) RenderLine(out *bytes.Buffer, functionName string, indent int, returnType string) { + r := "return" + + if len(n.Children) > 0 && functionName != "main" { + re := renderExpression(n.Children[0]) + r = "return " + cast(re[0], re[1], "int") + } + + printLine(out, r, indent) +} diff --git a/translation_unit_decl.go b/translation_unit_decl.go index 51cf4ce46..4b860b123 100644 --- a/translation_unit_decl.go +++ b/translation_unit_decl.go @@ -1,5 +1,7 @@ package main +import "bytes" + type TranslationUnitDecl struct { Address string Children []interface{} @@ -13,3 +15,9 @@ func parseTranslationUnitDecl(line string) *TranslationUnitDecl { Children: []interface{}{}, } } + +func (n *TranslationUnitDecl) RenderLine(out *bytes.Buffer, functionName string, indent int, returnType string) { + for _, c := range n.Children { + Render(out, c, functionName, indent, returnType) + } +} diff --git a/typedef_decl.go b/typedef_decl.go index fc0f8bb97..e68bebf47 100644 --- a/typedef_decl.go +++ b/typedef_decl.go @@ -1,6 +1,10 @@ package main -import "strings" +import ( + "strings" + "bytes" + "fmt" +) type TypedefDecl struct { Address string @@ -43,3 +47,38 @@ func parseTypedefDecl(line string) *TypedefDecl { Children: []interface{}{}, } } + +func (n *TypedefDecl) RenderLine(out *bytes.Buffer, functionName string, indent int, returnType string) { + name := strings.TrimSpace(n.Name) + if typeIsAlreadyDefined(name) { + return + } + + typeIsNowDefined(name) + + // FIXME: All of the logic here is just to avoid errors, it + // needs to be fixed up. + // if ("struct" in node["type"] or "union" in node["type"]) and : + // return + n.Type = strings.Replace(n.Type, "unsigned", "", -1) + + resolved_type := resolveType(n.Type) + + if name == "__mbstate_t" { + addImport("github.com/elliotchance/c2go/darwin") + resolved_type = "darwin.C__mbstate_t" + } + + if name == "__darwin_ct_rune_t" { + addImport("github.com/elliotchance/c2go/darwin") + resolved_type = "darwin.C__darwin_ct_rune_t" + } + + if name == "__builtin_va_list" || name == "__qaddr_t" || name == "definition" || name == + "_IO_lock_t" || name == "va_list" || name == "fpos_t" || name == "__NSConstantString" || name == + "__darwin_va_list" || name == "__fsid_t" || name == "_G_fpos_t" || name == "_G_fpos64_t" { + return + } + + printLine(out, fmt.Sprintf("type %s %s\n", name, resolved_type), indent) +} diff --git a/var_decl.go b/var_decl.go index 7ff948a23..049529466 100644 --- a/var_decl.go +++ b/var_decl.go @@ -3,6 +3,7 @@ package main import ( "strings" "fmt" + "bytes" ) type VarDecl struct { @@ -71,3 +72,6 @@ func (n *VarDecl) Render() []string { return []string{fmt.Sprintf("var %s %s%s", name, theType, suffix), "unknown3"} } + +func (n *VarDecl) RenderLine(out *bytes.Buffer, functionName string, indent int, returnType string) { +} diff --git a/while_stmt.go b/while_stmt.go index f4a3f9301..f9befaac6 100644 --- a/while_stmt.go +++ b/while_stmt.go @@ -1,5 +1,10 @@ package main +import ( + "bytes" + "fmt" +) + type WhileStmt struct { Address string Position string @@ -18,3 +23,15 @@ func parseWhileStmt(line string) *WhileStmt { Children: []interface{}{}, } } + +func (n *WhileStmt) RenderLine(out *bytes.Buffer, functionName string, indent int, returnType string) { + children := n.Children + + e := renderExpression(children[0]) + printLine(out, fmt.Sprintf("for %s {", cast(e[0], e[1], "bool")), indent) + + // FIXME: Does this do anything? + Render(out, children[1], functionName, indent+1, returnType) + + printLine(out, "}", indent) +} From 0e68111c4fa7c50928834c1f2b56b659d28dbfe2 Mon Sep 17 00:00:00 2001 From: Elliot Chance Date: Fri, 14 Apr 2017 17:51:44 +1000 Subject: [PATCH 9/9] Go fmt --- ast.go | 2 +- call_expr.go | 2 +- field_decl.go | 2 +- function_decl.go | 4 ++-- function_definition.go | 6 +++--- record_decl.go | 2 +- resolve.go | 4 ++-- typedef_decl.go | 2 +- util.go | 2 +- var_decl.go | 4 ++-- 10 files changed, 15 insertions(+), 15 deletions(-) diff --git a/ast.go b/ast.go index 0d4a71db5..21d208e8b 100644 --- a/ast.go +++ b/ast.go @@ -1,9 +1,9 @@ package main import ( + "bytes" "regexp" "strings" - "bytes" ) type ExpressionRenderer interface { diff --git a/call_expr.go b/call_expr.go index 801e17394..7d80d5ac3 100644 --- a/call_expr.go +++ b/call_expr.go @@ -1,8 +1,8 @@ package main import ( - "strings" "fmt" + "strings" ) type CallExpr struct { diff --git a/field_decl.go b/field_decl.go index 68af59a53..8eb83d3a7 100644 --- a/field_decl.go +++ b/field_decl.go @@ -1,8 +1,8 @@ package main import ( - "strings" "fmt" + "strings" ) type FieldDecl struct { diff --git a/function_decl.go b/function_decl.go index 5f2f67124..b66a821af 100644 --- a/function_decl.go +++ b/function_decl.go @@ -1,9 +1,9 @@ package main import ( - "strings" - "fmt" "bytes" + "fmt" + "strings" ) type FunctionDecl struct { diff --git a/function_definition.go b/function_definition.go index ad1929045..5cf0d56b5 100644 --- a/function_definition.go +++ b/function_definition.go @@ -8,10 +8,10 @@ import ( // FunctionDefinition contains the prototype definition for a function. type FunctionDefinition struct { // The name of the function, like "printf". - Name string + Name string // The C return type, like "int". - ReturnType string + ReturnType string // The C argument types, like ["bool", "int"]. There is currently no way // to represent a varargs. @@ -20,7 +20,7 @@ type FunctionDefinition struct { // If this is not empty then this function name should be used instead // of the Name. Many low level functions have an exact match with a Go // function. For example, "sin()". - Substitution string + Substitution string } var functionDefinitions = map[string]FunctionDefinition{} diff --git a/record_decl.go b/record_decl.go index 2b1b4b9db..54aaf74c8 100644 --- a/record_decl.go +++ b/record_decl.go @@ -1,9 +1,9 @@ package main import ( - "strings" "bytes" "fmt" + "strings" ) type RecordDecl struct { diff --git a/resolve.go b/resolve.go index ddf2956fc..d4ca87fab 100644 --- a/resolve.go +++ b/resolve.go @@ -1,9 +1,9 @@ package main import ( - "strings" - "regexp" "fmt" + "regexp" + "strings" ) // TODO: Some of these are based on assumptions that may not be true for all diff --git a/typedef_decl.go b/typedef_decl.go index e68bebf47..f74c748a1 100644 --- a/typedef_decl.go +++ b/typedef_decl.go @@ -1,9 +1,9 @@ package main import ( - "strings" "bytes" "fmt" + "strings" ) type TypedefDecl struct { diff --git a/util.go b/util.go index 8592e6451..d7148f543 100644 --- a/util.go +++ b/util.go @@ -1,8 +1,8 @@ package main import ( - "strings" "strconv" + "strings" ) func ucfirst(word string) string { diff --git a/var_decl.go b/var_decl.go index 049529466..92bfabec2 100644 --- a/var_decl.go +++ b/var_decl.go @@ -1,9 +1,9 @@ package main import ( - "strings" - "fmt" "bytes" + "fmt" + "strings" ) type VarDecl struct {