elliotchance / c2go

⚖️ A tool for transpiling C to Go.
MIT License
2.07k stars 154 forks source link

ast fails to detect variadic argument syntax in typedef function pointer #820

Open xk2600 opened 5 years ago

xk2600 commented 5 years ago

It seems that the variadic arguments operator/node is not detected during AST parsing events and in GC source output during transpilation.

I figured I would post an issue in case others run into the same issue. I'm actively working on providing an fix and pull request. Just have to spend a little time working through the c2go implementation. If this is not an actual issue, my apologies, as I suspect C variadic functions directly translate into c2go variadic functions, then feel free to close this.

tl;dr Repoduce as follows:

# cd /tmp
# git clone https://github.com/tcltk/tcl
# cd ./tcl/unix 
# c2go transpile -V -clang-flag "-I../generic/" -o tclsh.go -p Tcl tclAppInit.c
Start tanspiling ...
Running clang preprocessor...
Writing preprocessor ...
Running clang for AST tree...
Reading clang AST tree...
Converting to nodes...
panic: unknown node type: '...'

goroutine 478 [running]:
github.com/elliotchance/c2go/ast.Parse(0xc00061bb30, 0x3, 0x696d67, 0x5)
        /home/cstephan/go/src/github.com/elliotchance/c2go/ast/ast.go:270 +0x4314
main.convertLinesToNodes(0xc0003dfda0, 0x17, 0x1088, 0x435f6c6354207473, 0x79546c656e6e6168, 0x657079742a206570)
        /home/cstephan/go/src/github.com/elliotchance/c2go/main.go:89 +0x1d8
main.convertLinesToNodesParallel.func1.2(0xc0002af0e0, 0xc000494048, 0xc0003dfda0, 0x17, 0x1088, 0x0)
        /home/cstephan/go/src/github.com/elliotchance/c2go/main.go:121 +0x59
created by main.convertLinesToNodesParallel.func1
        /home/cstephan/go/src/github.com/elliotchance/c2go/main.go:119 +0x1a6

#~/go/bin/c2go ast -clang-flag "-I../generic/" tclAppInit.c

|-TypedefDecl 0x804429618 <line:758:1, col:54> col:15 referenced Tcl_PanicProc 'void (const char *, ...)':'void (const char *, ...)'
| `-ParenType 0x8044295c0 'void (const char *, ...)' sugar
|   `-FunctionProtoType 0x804429580 'void (const char *, ...)' cdecl
|     |-BuiltinType 0x8040f4340 'void'
|     |-PointerType 0x8040f4a50 'const char *'
|     | `-QualType 0x8040f4381 'const char' const
|     |   `-BuiltinType 0x8040f4380 'char'
|     `-...

To keep things moving past the ast, I updated c2go/ast/ast.go:

+++ c2go/ast/ast.go
@@ -266,6 +266,8 @@
                return parseWhileStmt(line)
        case "NullStmt":
                return nil
+        case "...": // node in function pointer is variadic...
+                return nil //not sure how to handle yet.
        default:
                panic("unknown node type: '" + fullline + "'")
        }

However, it appears that even when the variadic node occurs within an actual function definition (outside of a typedef or declaration) c2go still has issues as noted below in the source output:

In .tcl/generic/tclDecls.h:

void (*tcl_Panic) (const char *format, ...) TCL_FORMAT_PRINTF(1, 2); /* 2 */
/* TCL_FORMAT_PRINTF is a C MACRO expansion to Tcl's printf implementation body */

results in

// Warning (FieldDecl):  ../generic/tclDecls.h:1832 : Cannot resolve type 'void (*)( char *, ...)' : Cannot separate function 'void (*)( char *, ...)' : Cannot resolve type '...' : I couldn't find an appropriate Go type for the C type '...'.

Also, props to the maintainers of this... its pure genius.

Konstantin8105 commented 5 years ago

Please try https://github.com/Konstantin8105/c4go