Repository: Konstantin8105/c4go
Pull request #490 (2021-04-19 22:02:16)

lib.a

codecov[bot]: # [Codecov](https://codecov.io/gh/Konstantin8105/c4go/pull/490?src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Konstantin) Report
> Merging [#490](https://codecov.io/gh/Konstantin8105/c4go/pull/490?src=pr&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Konstantin) (bb70ed9) into [master](https://codecov.io/gh/Konstantin8105/c4go/commit/faae7fed1bd8a4e02f1bde205bea5fb100bceb1e?el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Konstantin) (faae7fe) will **increase** coverage by `0.10%`.
> The diff coverage is `86.20%`.

[![Impacted file tree graph](https://codecov.io/gh/Konstantin8105/c4go/pull/490/graphs/tree.svg?width=650&height=150&src=pr&token=esH2rHXlZ2&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Konstantin)](https://codecov.io/gh/Konstantin8105/c4go/pull/490?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Konstantin)

```diff
@@            Coverage Diff             @@
##           master     #490      +/-   ##
==========================================
+ Coverage   82.87%   82.97%   +0.10%     
==========================================
  Files         193      193              
  Lines       10855    10885      +30     
==========================================
+ Hits         8996     9032      +36     
+ Misses       1354     1346       -8     
- Partials      505      507       +2     
```


| [Impacted Files](https://codecov.io/gh/Konstantin8105/c4go/pull/490?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Konstantin) | Coverage Δ | |
|---|---|---|
| [transpiler/call.go](https://codecov.io/gh/Konstantin8105/c4go/pull/490/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Konstantin#diff-dHJhbnNwaWxlci9jYWxsLmdv) | `76.61% <ø> (ø)` | |
| [transpiler/translation\_unit.go](https://codecov.io/gh/Konstantin8105/c4go/pull/490/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Konstantin#diff-dHJhbnNwaWxlci90cmFuc2xhdGlvbl91bml0Lmdv) | `62.50% <ø> (ø)` | |
| [program/warnings.go](https://codecov.io/gh/Konstantin8105/c4go/pull/490/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Konstantin#diff-cHJvZ3JhbS93YXJuaW5ncy5nbw==) | `86.66% <50.00%> (-13.34%)` | :arrow_down: |
| [transpiler/functions.go](https://codecov.io/gh/Konstantin8105/c4go/pull/490/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Konstantin#diff-dHJhbnNwaWxlci9mdW5jdGlvbnMuZ28=) | `84.00% <81.91%> (+1.43%)` | :arrow_up: |
| [transpiler/transpiler.go](https://codecov.io/gh/Konstantin8105/c4go/pull/490/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Konstantin#diff-dHJhbnNwaWxlci90cmFuc3BpbGVyLmdv) | `83.66% <90.90%> (-1.22%)` | :arrow_down: |
| [preprocessor/preprocessor.go](https://codecov.io/gh/Konstantin8105/c4go/pull/490/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Konstantin#diff-cHJlcHJvY2Vzc29yL3ByZXByb2Nlc3Nvci5nbw==) | `81.75% <100.00%> (+1.16%)` | :arrow_up: |
| [program/definition\_function.go](https://codecov.io/gh/Konstantin8105/c4go/pull/490/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Konstantin#diff-cHJvZ3JhbS9kZWZpbml0aW9uX2Z1bmN0aW9uLmdv) | `85.36% <100.00%> (+0.14%)` | :arrow_up: |
| [transpiler/bind.go](https://codecov.io/gh/Konstantin8105/c4go/pull/490/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Konstantin#diff-dHJhbnNwaWxlci9iaW5kLmdv) | `74.12% <100.00%> (+4.94%)` | :arrow_up: |
| [types/resolve.go](https://codecov.io/gh/Konstantin8105/c4go/pull/490/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Konstantin#diff-dHlwZXMvcmVzb2x2ZS5nbw==) | `69.56% <100.00%> (+0.13%)` | :arrow_up: |
| ... and [4 more](https://codecov.io/gh/Konstantin8105/c4go/pull/490/diff?src=pr&el=tree-more&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Konstantin) | |

------

[Continue to review full report at Codecov](https://codecov.io/gh/Konstantin8105/c4go/pull/490?src=pr&el=continue&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Konstantin).
> **Legend** - [Click here to learn more](https://docs.codecov.io/docs/codecov-delta?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Konstantin)
> `Δ = absolute <relative> (impact)`, `ø = not affected`, `? = missing data`
> Powered by [Codecov](https://codecov.io/gh/Konstantin8105/c4go/pull/490?src=pr&el=footer&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Konstantin). Last update [faae7fe...bb70ed9](https://codecov.io/gh/Konstantin8105/c4go/pull/490?src=pr&el=lastupdated&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Konstantin). Read the [comment docs](https://docs.codecov.io/docs/pull-request-comments?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Konstantin).


Patch:
diff --git a/go.mod b/go.mod
index b4d3c5d..bf70625 100644
--- a/go.mod
+++ b/go.mod
@@ -2,6 +2,7 @@ module github.com/Konstantin8105/c4go
 
 require (
 	github.com/Konstantin8105/cs v0.0.0-20190517091010-c069cc1cee1b
+	github.com/Konstantin8105/errors v0.0.0-20190517083224-0667bfd7a9ac // indirect
 	github.com/bradleyjkemp/cupaloy v2.3.0+incompatible
 	github.com/davecgh/go-spew v1.1.1 // indirect
 	github.com/pkg/term v0.0.0-20190109203006-aa71e9d9e942
diff --git a/main.go b/main.go
index f6918f4..8d3f142 100644
--- a/main.go
+++ b/main.go
@@ -518,7 +518,7 @@ func generateGoCode(args ProgramArgs, lines []string, filePP preprocessor.FilePP
 
 	var source string
 	source, err = transpiler.TranspileAST(args.outputFile, args.packageName, args.outsideStructs,
-		p, tree[0].(ast.Node))
+		p, tree[0].(ast.Node), args.clangFlags)
 	if err != nil {
 		return fmt.Errorf("cannot transpile AST : %v", err)
 	}
diff --git a/preprocessor/preprocessor.go b/preprocessor/preprocessor.go
index 9bebe8c..14cf5d1 100644
--- a/preprocessor/preprocessor.go
+++ b/preprocessor/preprocessor.go
@@ -291,10 +291,13 @@ func (f FilePP) GetIncludeFiles() []IncludeHeader {
 // IsUserSource get is it source from user
 func (f FilePP) IsUserSource(in string) bool {
 	for i := range f.includes {
-		if strings.Contains(in, f.includes[i].HeaderName) &&
-			f.includes[i].IsUserSource {
-			return true
+		if !f.includes[i].IsUserSource {
+			continue
+		}
+		if !strings.Contains(in, f.includes[i].HeaderName) {
+			continue
 		}
+		return true
 	}
 	return false
 }
diff --git a/program/definition_function.go b/program/definition_function.go
index 5024352..b3c838d 100644
--- a/program/definition_function.go
+++ b/program/definition_function.go
@@ -24,6 +24,9 @@ type DefinitionFunction struct {
 	// If function called, then true.
 	IsCalled bool
 
+	// If function without body, then true
+	HaveBody bool
+
 	// If function from some C standard library, then true.
 	IsCstdFunction bool
 	pntCstd        *stdFunction
@@ -382,6 +385,7 @@ func (p *Program) GetFunctionDefinition(functionName string) *DefinitionFunction
 func (p *Program) AddFunctionDefinition(f DefinitionFunction) {
 	p.loadFunctionDefinitions()
 
+	f.ReturnType = strings.TrimSpace(f.ReturnType)
 	p.functionDefinitions[f.Name] = f
 }
 
@@ -490,6 +494,14 @@ func (p *Program) SetCalled(name string) {
 	}
 }
 
+func (p *Program) SetHaveBody(name string) {
+	f, ok := p.functionDefinitions[name]
+	if ok {
+		f.HaveBody = true
+		p.functionDefinitions[name] = f
+	}
+}
+
 func (p *Program) GetCstdFunction() (src string) {
 	for i := range p.functionDefinitions {
 		if !p.functionDefinitions[i].IsCalled {
@@ -535,13 +547,17 @@ func (p *Program) GetOutsideCalledFunctions() (ds []DefinitionFunction) {
 		if v.IncludeFile == "" {
 			continue
 		}
-		if p.PreprocessorFile.IsUserSource(v.IncludeFile) {
+		if !v.IsCalled {
+			continue
+		}
+		if !v.HaveBody {
+			ds = append(ds, v)
 			continue
 		}
 		if v.IsCstdFunction {
 			continue
 		}
-		if !v.IsCalled {
+		if p.PreprocessorFile.IsUserSource(v.IncludeFile) {
 			continue
 		}
 		ds = append(ds, v)
diff --git a/program/warnings.go b/program/warnings.go
index c803c34..e5098a1 100644
--- a/program/warnings.go
+++ b/program/warnings.go
@@ -17,7 +17,11 @@ func (p *Program) GenerateWarningMessage(e error, n ast.Node) string {
 		return ""
 	}
 	if n != nil {
-		message += fmt.Sprintf("(%T): %s:", n, n.Position().GetSimpleLocation())
+		var prefix string
+		if fd, ok := n.(*ast.FunctionDecl); ok {
+			prefix = fmt.Sprintf("n:%s,t1:%s,t2:%s", fd.Name, fd.Type, fd.Type2)
+		}
+		message += fmt.Sprintf("(%T): {prefix: %s}. %s:", n, prefix, n.Position().GetSimpleLocation())
 	}
 	message += fmt.Sprintf("%s", e.Error())
 	message = PathSimplification(message)
diff --git a/scripts/scripts.txt b/scripts/scripts.txt
index 3a851ce..886ccc2 100644
--- a/scripts/scripts.txt
+++ b/scripts/scripts.txt
@@ -5,7 +5,7 @@ Calculate warnings in file: ./testdata/brainfuck/brainfuck.go
 		Unsafe   : 0
 
 Calculate warnings : ./testdata/9wm
-		After transpiling : 5 warnings.
+		After transpiling : 6 warnings.
 		Go build : 4 warnings
 		Unsafe   : 411
 
@@ -14,10 +14,8 @@ Calculate warnings : ./testdata/ed
 		Go build : 7 warnings
 		Unsafe   : 165
 
-Calculate warnings in file: ./testdata/kilo/kilo.go
-		After transpiling : 0 warnings.
-		Go build : 0 warnings
-		Unsafe   : 17
+/home/konstantin/go/src/github.com/Konstantin8105/c4go/testdata/kilo/kilo.c:409:25: warning: implicit declaration of function 'editorRowHasOpenComment' is invalid in C99 [-Wimplicit-function-declaration]
+1 warning and 1 error generated.
 
 
 Calculate warnings in file: ./testdata/neateqn/neateqn.go
@@ -27,62 +25,60 @@ Calculate warnings in file: ./testdata/neateqn/neateqn.go
 
 Calculate warnings in file: ./testdata/neatmkfn/neatmkfn.go
 		After transpiling : 0 warnings.
-		Go build : 279 warnings
+		Go build : 19 warnings
 		Unsafe   : 139
 
+/home/konstantin/go/src/github.com/Konstantin8105/c4go/testdata/neatmail/pg.c:114:3: warning: implicit declaration of function 'msg_new' is invalid in C99 [-Wimplicit-function-declaration]
+/home/konstantin/go/src/github.com/Konstantin8105/c4go/testdata/neatmail/pg.c:137:17: warning: implicit declaration of function 'msg_reply' is invalid in C99 [-Wimplicit-function-declaration]
+/home/konstantin/go/src/github.com/Konstantin8105/c4go/testdata/neatmail/pg.c:147:19: warning: implicit declaration of function 'msg_forward' is invalid in C99 [-Wimplicit-function-declaration]
+3 warnings and 18 errors generated.
 
 
 Calculate warnings in file: ./testdata/neatrefer/neatrefer.go
-		After transpiling : 0 warnings.
-		Go build : 0 warnings
+		After transpiling : 6 warnings.
+		Go build : 4 warnings
 		Unsafe   : 17
 
 Calculate warnings : ./testdata/nuklear/x11.go
 		After transpiling : 9 warnings.
 		Go build : 12 warnings
-		Unsafe   : 876
+		Unsafe   : 544
 Calculate warnings : ./testdata/nuklear/x11_opengl2.go
-		After transpiling : 19 warnings.
+		After transpiling : 17 warnings.
 		Go build : 12 warnings
-		Unsafe   : 1060
+		Unsafe   : 659
 
-Calculate warnings in file: ./testdata/neatroff/neatroff.go
-		After transpiling : 3 warnings.
-		Go build : 8 warnings
-		Unsafe   : 247
+/home/konstantin/go/src/github.com/Konstantin8105/c4go/testdata/neatroff/fmt.c:454:15: warning: absolute value function 'abs' given an argument of type 'long' but has parameter of type 'int' which may cause truncation of value [-Wabsolute-value]
+1 warning and 20 errors generated.
 
 Calculate warnings : ./testdata/redis/dict.go
 		After transpiling : 0 warnings.
-		Go build : 40 warnings
-		Unsafe   : 72
+		Go build : 42 warnings
+		Unsafe   : 76
 Calculate warnings : ./testdata/redis/linenoise.go
-		After transpiling : 0 warnings.
+		After transpiling : 6 warnings.
 		Go build : 2 warnings
 		Unsafe   : 21
 Calculate warnings : ./testdata/redis/redis_cli.go
 		After transpiling : 0 warnings.
-		Go build : 79 warnings
-		Unsafe   : 264
+		Go build : 3 warnings
+		Unsafe   : 313
 Calculate warnings : ./testdata/redis/sds.go
 		After transpiling : 0 warnings.
-		Go build : 43 warnings
-		Unsafe   : 117
+		Go build : 8 warnings
+		Unsafe   : 119
 
 
-Calculate warnings in file: ./testdata/triangle/triangle.go
-		After transpiling : 2 warnings.
-		Go build : 585 warnings
-		Unsafe   : 1414
 
 Calculate warnings in file: ./testdata/progress/progress.go
-		After transpiling : 0 warnings.
-		Go build : 39 warnings
-		Unsafe   : 0
+		After transpiling : 6 warnings.
+		Go build : 16 warnings
+		Unsafe   : 6
 
 Calculate warnings in file: ./testdata/SQLITE/sqlite.go
 		After transpiling : 1 warnings.
 		Go build : 1 warnings
-		Unsafe   : 2351
+		Unsafe   : 2352
 
 Calculate warnings in file: ./testdata/tiny-web-server/tiny-web-server.go
 		After transpiling : 0 warnings.
@@ -91,11 +87,11 @@ Calculate warnings in file: ./testdata/tiny-web-server/tiny-web-server.go
 
 Calculate warnings in file: testdata/vorbis/vorbis.go
 		After transpiling : 0 warnings.
-		Go build : 21 warnings
+		Go build : 18 warnings
 		Unsafe   : 127
 
 Calculate warnings in file: ./testdata/easymesh/easymesh.go
-		After transpiling : 0 warnings.
-		Go build : 0 warnings
+		After transpiling : 6 warnings.
+		Go build : 4 warnings
 		Unsafe   : 10
 
diff --git a/transpiler/bind.go b/transpiler/bind.go
index f07bb43..0e32f22 100644
--- a/transpiler/bind.go
+++ b/transpiler/bind.go
@@ -14,7 +14,7 @@ import (
 	"github.com/Konstantin8105/c4go/util"
 )
 
-func generateBinding(p *program.Program) (bindHeader, bindCode string) {
+func generateBinding(p *program.Program, clangFlags []string) (bindHeader, bindCode string) {
 	// outside called functions
 	ds := p.GetOutsideCalledFunctions()
 	if len(ds) == 0 {
@@ -25,6 +25,34 @@ func generateBinding(p *program.Program) (bindHeader, bindCode string) {
 		return ds[i].Name < ds[j].Name
 	})
 
+	// add clang flags
+	{
+		cflags := map[string]bool{}
+		ldflags := map[string]bool{}
+		for i := range clangFlags {
+			if strings.HasPrefix(clangFlags[i], "-I") {
+				cflags[clangFlags[i]] = true
+			}
+			if strings.HasPrefix(clangFlags[i], "-L") || strings.HasPrefix(clangFlags[i], "-l") {
+				ldflags[clangFlags[i]] = true
+			}
+		}
+		if 0 < len(cflags) {
+			bindHeader += "// #cgo CFLAGS : "
+			for k, _ := range cflags {
+				bindHeader += k + " "
+			}
+			bindHeader += "\n"
+		}
+		if 0 < len(ldflags) {
+			bindHeader += "// #cgo LDFLAGS : "
+			for k, _ := range ldflags {
+				bindHeader += k + " "
+			}
+			bindHeader += "\n"
+		}
+	}
+
 	// automatic binding of function
 	{
 		in := map[string]bool{}
@@ -39,6 +67,7 @@ func generateBinding(p *program.Program) (bindHeader, bindCode string) {
 			}
 			bindHeader += fmt.Sprintf("// #include <%s>\n", header)
 		}
+
 		bindHeader += "import \"C\"\n\n"
 	}
 
@@ -100,6 +129,9 @@ func getBindFunction(p *program.Program, d program.DefinitionFunction) (code str
 				"..." + argResolvedType[len(argResolvedType)-1]
 			continue
 		}
+		if strings.TrimSpace(d.ArgumentTypes[i]) == "" {
+			continue
+		}
 		resolveType, err := types.ResolveType(p, d.ArgumentTypes[i])
 		if err != nil {
 			return "", fmt.Errorf("cannot generate argument binding function `%s`: %v", d.Name, err)
diff --git a/transpiler/call.go b/transpiler/call.go
index 6773869..9b3ef19 100644
--- a/transpiler/call.go
+++ b/transpiler/call.go
@@ -394,6 +394,7 @@ func transpileCallExpr(n *ast.CallExpr, p *program.Program) (
 			}
 		}
 	} else {
+
 		// type correction for definition function in
 		// package program
 		var ok bool
diff --git a/transpiler/functions.go b/transpiler/functions.go
index c5a0283..123222d 100644
--- a/transpiler/functions.go
+++ b/transpiler/functions.go
@@ -51,23 +51,6 @@ func transpileFunctionDecl(n *ast.FunctionDecl, p *program.Program) (
 		}
 	}()
 
-	var haveCompound bool
-	for _, ch := range n.Children() {
-		if _, ok := ch.(*ast.CompoundStmt); ok {
-			haveCompound = true
-			break
-		}
-	}
-	if !haveCompound {
-		return
-	}
-
-	if len(n.Children()) == 0 {
-		return
-	}
-
-	var body *goast.BlockStmt
-
 	// This is set at the start of the function declaration so when the
 	// ReturnStmt comes alone it will know what the current function is, and
 	// therefore be able to lookup what the real return type should be. I'm sure
@@ -82,7 +65,7 @@ func transpileFunctionDecl(n *ast.FunctionDecl, p *program.Program) (
 
 	// Always register the new function. Only from this point onwards will
 	// we be allowed to refer to the function.
-	if p.GetFunctionDefinition(n.Name) == nil {
+	define := func() (err error) {
 		var pr string
 		var f, r []string
 		pr, _, f, r, err = util.ParseFunction(n.Type)
@@ -100,26 +83,44 @@ func transpileFunctionDecl(n *ast.FunctionDecl, p *program.Program) (
 			ReturnType:    r[0],
 			ArgumentTypes: f,
 			Substitution:  "",
+			IncludeFile:   n.Pos.File,
 		})
+		return
 	}
 
-	// If the function has a direct substitute in Go we do not want to
-	// output the C definition of it.
-	f := p.GetFunctionDefinition(n.Name)
+	if p.GetFunctionDefinition(n.Name) == nil {
+		if err = define(); err != nil {
+			return
+		}
+	}
+
+	if n.IsExtern {
+		return
+	}
 
 	// Test if the function has a body. This is identified by a child node that
 	// is a CompoundStmt (since it is not valid to have a function body without
 	// curly brackets).
 	functionBody := getFunctionBody(n)
-	if functionBody != nil {
-		var pre, post []goast.Stmt
-		body, pre, post, err = transpileToBlockStmt(functionBody, p)
-		if err != nil || len(pre) > 0 || len(post) > 0 {
-			p.AddMessage(p.GenerateWarningMessage(
-				fmt.Errorf("not correct result in function %s body: err = %v",
-					n.Name, err), n))
-			err = nil // Error is ignored
-		}
+	if functionBody == nil {
+		return
+	}
+
+	if err = define(); err != nil {
+		return
+	}
+
+	// If the function has a direct substitute in Go we do not want to
+	// output the C definition of it.
+	f := p.GetFunctionDefinition(n.Name)
+
+	p.SetHaveBody(n.Name)
+	body, pre, post, err := transpileToBlockStmt(functionBody, p)
+	if err != nil || len(pre) > 0 || len(post) > 0 {
+		p.AddMessage(p.GenerateWarningMessage(
+			fmt.Errorf("not correct result in function %s body: err = %v",
+				n.Name, err), n))
+		err = nil // Error is ignored
 	}
 
 	if p.IncludeHeaderIsExists("stdlib.h") && n.Name == "main" {
@@ -129,121 +130,128 @@ func transpileFunctionDecl(n *ast.FunctionDecl, p *program.Program) (
 		p.AddImport("github.com/Konstantin8105/c4go/noarch")
 	}
 
-	if functionBody != nil {
-		// If verbose mode is on we print the name of the function as a comment
-		// immediately to stdout. This will appear at the top of the program but
-		// make it much easier to diagnose when the transpiler errors.
-		if p.Verbose {
-			fmt.Fprintf(os.Stdout, "// Function: %s(%s)\n", f.Name,
-				strings.Join(f.ArgumentTypes, ", "))
-		}
+	// if functionBody != nil {
 
-		var fieldList = &goast.FieldList{}
-		fieldList, err = getFieldList(p, n,
-			p.GetFunctionDefinition(n.Name).ArgumentTypes)
-		if err != nil {
-			return
-		}
+	// If verbose mode is on we print the name of the function as a comment
+	// immediately to stdout. This will appear at the top of the program but
+	// make it much easier to diagnose when the transpiler errors.
+	if p.Verbose {
+		fmt.Fprintf(os.Stdout, "// Function: %s(%s)\n", f.Name,
+			strings.Join(f.ArgumentTypes, ", "))
+	}
 
-		t, err := types.ResolveType(p, f.ReturnType)
+	var fieldList = &goast.FieldList{}
+	fieldList, err = getFieldList(p, n,
+		p.GetFunctionDefinition(n.Name).ArgumentTypes)
+	if err != nil {
+		return
+	}
+
+	// return type
+
+	t, err := types.ResolveType(p, f.ReturnType)
+	if err != nil {
+		err = fmt.Errorf("ReturnType: %s. %v", f.ReturnType, err)
 		p.AddMessage(p.GenerateWarningMessage(err, n))
+		err = nil
+	}
 
-		if p.Function != nil && p.Function.Name == "main" {
-			// main() function does not have a return type.
-			t = ""
-
-			// This collects statements that will be placed at the top of
-			// (before any other code) in main().
-			prependStmtsInMain := []goast.Stmt{}
-
-			// In Go, the main() function does not take the system arguments.
-			// Instead they are accessed through the os package. We create new
-			// variables in the main() function (if needed), immediately after
-			// the __init() for these variables.
-			if len(fieldList.List) > 0 {
-				p.AddImport("os")
-
-				prependStmtsInMain = append(
-					prependStmtsInMain,
-					&goast.AssignStmt{
-						Lhs: []goast.Expr{fieldList.List[0].Names[0]},
-						Tok: token.DEFINE,
-						Rhs: []goast.Expr{
-							&goast.CallExpr{
-								Fun: goast.NewIdent("int32"),
-								Args: []goast.Expr{
-									util.NewCallExpr("len", goast.NewIdent("os.Args")),
-								},
+	if p.Function != nil && p.Function.Name == "main" {
+		// main() function does not have a return type.
+		t = ""
+
+		// This collects statements that will be placed at the top of
+		// (before any other code) in main().
+		prependStmtsInMain := []goast.Stmt{}
+
+		// In Go, the main() function does not take the system arguments.
+		// Instead they are accessed through the os package. We create new
+		// variables in the main() function (if needed), immediately after
+		// the __init() for these variables.
+		if len(fieldList.List) > 0 {
+			p.AddImport("os")
+
+			prependStmtsInMain = append(
+				prependStmtsInMain,
+				&goast.AssignStmt{
+					Lhs: []goast.Expr{fieldList.List[0].Names[0]},
+					Tok: token.DEFINE,
+					Rhs: []goast.Expr{
+						&goast.CallExpr{
+							Fun: goast.NewIdent("int32"),
+							Args: []goast.Expr{
+								util.NewCallExpr("len", goast.NewIdent("os.Args")),
 							},
 						},
 					},
-				)
-			}
+				},
+			)
+		}
 
-			if len(fieldList.List) > 1 {
-				prependStmtsInMain = append(
-					prependStmtsInMain,
-					&goast.AssignStmt{
-						Lhs: []goast.Expr{fieldList.List[1].Names[0]},
-						Tok: token.DEFINE,
-						Rhs: []goast.Expr{&goast.CompositeLit{Type: util.NewTypeIdent("[][]byte")}},
-					},
-					&goast.RangeStmt{
-						Key:   goast.NewIdent("_"),
-						Value: util.NewIdent("argvSingle"),
-						Tok:   token.DEFINE,
-						X:     goast.NewIdent("os.Args"),
-						Body: &goast.BlockStmt{
-							List: []goast.Stmt{
-								&goast.AssignStmt{
-									Lhs: []goast.Expr{fieldList.List[1].Names[0]},
-									Tok: token.ASSIGN,
-									Rhs: []goast.Expr{util.NewCallExpr(
-										"append",
-										fieldList.List[1].Names[0],
-										util.NewCallExpr("[]byte", util.NewIdent("argvSingle")),
-									)},
-								},
+		if len(fieldList.List) > 1 {
+			prependStmtsInMain = append(
+				prependStmtsInMain,
+				&goast.AssignStmt{
+					Lhs: []goast.Expr{fieldList.List[1].Names[0]},
+					Tok: token.DEFINE,
+					Rhs: []goast.Expr{&goast.CompositeLit{Type: util.NewTypeIdent("[][]byte")}},
+				},
+				&goast.RangeStmt{
+					Key:   goast.NewIdent("_"),
+					Value: util.NewIdent("argvSingle"),
+					Tok:   token.DEFINE,
+					X:     goast.NewIdent("os.Args"),
+					Body: &goast.BlockStmt{
+						List: []goast.Stmt{
+							&goast.AssignStmt{
+								Lhs: []goast.Expr{fieldList.List[1].Names[0]},
+								Tok: token.ASSIGN,
+								Rhs: []goast.Expr{util.NewCallExpr(
+									"append",
+									fieldList.List[1].Names[0],
+									util.NewCallExpr("[]byte", util.NewIdent("argvSingle")),
+								)},
 							},
 						},
-					})
-			}
+					},
+				})
+		}
 
-			// Prepend statements for main().
-			body.List = append(prependStmtsInMain, body.List...)
+		// Prepend statements for main().
+		body.List = append(prependStmtsInMain, body.List...)
 
-			// The main() function does not have arguments or a return value.
-			fieldList = &goast.FieldList{}
-		}
+		// The main() function does not have arguments or a return value.
+		fieldList = &goast.FieldList{}
+	}
 
-		// Each function MUST have "ReturnStmt",
-		// except function without return type
-		var addReturnName bool
-		if len(body.List) > 0 {
-			last := body.List[len(body.List)-1]
-			if _, ok := last.(*goast.ReturnStmt); !ok && t != "" {
-				body.List = append(body.List, &goast.ReturnStmt{})
-				addReturnName = true
-			}
+	// Each function MUST have "ReturnStmt",
+	// except function without return type
+	var addReturnName bool
+	if len(body.List) > 0 {
+		last := body.List[len(body.List)-1]
+		if _, ok := last.(*goast.ReturnStmt); !ok && t != "" {
+			body.List = append(body.List, &goast.ReturnStmt{})
+			addReturnName = true
 		}
+	}
 
-		// For functions without return type - no need add return at
-		// the end of body
-		if p.GetFunctionDefinition(n.Name).ReturnType == "void" {
-			if len(body.List) > 0 {
-				if _, ok := (body.List[len(body.List)-1]).(*goast.ReturnStmt); ok {
-					body.List = body.List[:len(body.List)-1]
-				}
+	// For functions without return type - no need add return at
+	// the end of body
+	if p.GetFunctionDefinition(n.Name).ReturnType == "void" {
+		if len(body.List) > 0 {
+			if _, ok := (body.List[len(body.List)-1]).(*goast.ReturnStmt); ok {
+				body.List = body.List[:len(body.List)-1]
 			}
 		}
-
-		decls = append(decls, &goast.FuncDecl{
-			Name: util.NewIdent(n.Name),
-			Type: util.NewFuncType(fieldList, t, addReturnName),
-			Body: body,
-		})
 	}
 
+	decls = append(decls, &goast.FuncDecl{
+		Name: util.NewIdent(n.Name),
+		Type: util.NewFuncType(fieldList, t, addReturnName),
+		Body: body,
+	})
+	//}
+
 	err = nil
 	return
 }
@@ -261,7 +269,10 @@ func getFieldList(p *program.Program, f *ast.FunctionDecl, fieldTypes []string)
 		n := f.Children()[i]
 		if v, ok := n.(*ast.ParmVarDecl); ok {
 			t, err := types.ResolveType(p, fieldTypes[i])
-			p.AddMessage(p.GenerateWarningMessage(err, f))
+			if err != nil {
+				err = fmt.Errorf("FieldList type: %s. %v", fieldTypes[i], err)
+				p.AddMessage(p.GenerateWarningMessage(err, f))
+			}
 
 			if len(t) > 0 {
 				r = append(r, &goast.Field{
diff --git a/transpiler/translation_unit.go b/transpiler/translation_unit.go
index 156127e..86f79fd 100644
--- a/transpiler/translation_unit.go
+++ b/transpiler/translation_unit.go
@@ -12,6 +12,20 @@ import (
 func transpileTranslationUnitDecl(p *program.Program, n *ast.TranslationUnitDecl) (
 	decls []goast.Decl, err error) {
 
+	// childs := n.Children()
+	// 	et := errors.New("transpileTranslationUnitDecl")
+	// 	for i := range childs {
+	// 		ds, err := transpileToNode(childs[i], p)
+	// 		if err != nil {
+	// 			et.Add(err)
+	// 			continue
+	// 		}
+	// 		decls = append(decls, ds...)
+	// 	}
+	// 	if et.IsError() {
+	// 		err = et
+	// 	}
+
 	// create name for anonymous ast.RecordDecl
 	for i := 0; i < len(n.Children()); i++ {
 		presentNode := n.Children()[i]
diff --git a/transpiler/transpiler.go b/transpiler/transpiler.go
index d561860..33d106f 100644
--- a/transpiler/transpiler.go
+++ b/transpiler/transpiler.go
@@ -22,7 +22,7 @@ var AddOutsideStruct bool
 
 // TranspileAST iterates through the Clang AST and builds a Go AST
 func TranspileAST(fileName, packageName string, withOutsideStructs bool,
-	p *program.Program, root ast.Node) (
+	p *program.Program, root ast.Node, clangFlags []string) (
 	source string, // result Go source
 	err error) {
 	// Start by parsing an empty file.
@@ -128,7 +128,7 @@ func TranspileAST(fileName, packageName string, withOutsideStructs bool,
 	GetUnsafeConvertDecls(p)
 
 	// checking implementation for all called functions
-	bindHeader, bindCode := generateBinding(p)
+	bindHeader, bindCode := generateBinding(p, clangFlags)
 
 	// Add the imports after everything else so we can ensure that they are all
 	// placed at the top.
@@ -503,6 +503,10 @@ func transpileToNode(node ast.Node, p *program.Program) (
 		}
 	}()
 
+	if node == nil {
+		return
+	}
+
 	defer func() {
 		decls = nilFilterDecl(decls)
 	}()
@@ -513,33 +517,19 @@ func transpileToNode(node ast.Node, p *program.Program) (
 		}
 	}()
 
-	switch n := node.(type) {
-	case *ast.TranslationUnitDecl:
+	if n, ok := node.(*ast.TranslationUnitDecl); ok {
 		return transpileTranslationUnitDecl(p, n)
 	}
 
-	if fd, ok := node.(*ast.FunctionDecl); ok {
-		if d := p.GetFunctionDefinition(fd.Name); d == nil ||
-			p.PreprocessorFile.IsUserSource(d.IncludeFile) {
-
-			// create new definition
-			if _, _, f, r, err := util.ParseFunction(fd.Type); err == nil {
-				p.AddFunctionDefinition(program.DefinitionFunction{
-					Name:          fd.Name,
-					ReturnType:    r[0],
-					ArgumentTypes: f,
-					IncludeFile:   fd.Position().File,
-				})
-			}
-		}
-	}
-
-	if !AddOutsideStruct {
-		if node != nil {
-			if (!p.PreprocessorFile.IsUserSource(node.Position().File)) &&
-				(!strings.HasSuffix(node.Position().File, "stdint.h")) {
+	if !AddOutsideStruct &&
+		!p.PreprocessorFile.IsUserSource(node.Position().File) &&
+		!strings.HasSuffix(node.Position().File, "stdint.h") {
+		if fd, ok := node.(*ast.FunctionDecl); ok {
+			if getFunctionBody(fd) != nil {
 				return
 			}
+		} else {
+			return
 		}
 	}
 
diff --git a/types/resolve.go b/types/resolve.go
index 5c36b8f..ccb07e9 100644
--- a/types/resolve.go
+++ b/types/resolve.go
@@ -127,12 +127,15 @@ var ToVoid = "ToVoid"
 //    transpiler to step over type errors and put something as a placeholder
 //    until a more suitable solution is found for those cases.
 func ResolveType(p *program.Program, s string) (resolveResult string, err error) {
-	defer func() {
-		resolveResult = strings.TrimSpace(resolveResult)
-		if err != nil {
-			err = fmt.Errorf("cannot resolve type '%s' : %v", s, err)
-		}
-	}()
+	{
+		input := s
+		defer func() {
+			resolveResult = strings.TrimSpace(resolveResult)
+			if err != nil {
+				err = fmt.Errorf("cannot resolve type '%s' : %v", input, err)
+			}
+		}()
+	}
 
 	if strings.Contains(s, ":") {
 		return "interface{}", errors.New("probably an incorrect type translation 0")


Test patch:
diff --git a/main_test.go b/main_test.go
index 83ad08a..a87298e 100644
--- a/main_test.go
+++ b/main_test.go
@@ -545,6 +545,11 @@ func TestMultifileTranspilation(t *testing.T) {
 }
 
 func TestBind(t *testing.T) {
+
+	if err := os.MkdirAll("./testdata/bind", os.ModePerm); err != nil {
+		t.Fatal(err)
+	}
+
 	cProgram := programOut{}
 
 	{
@@ -604,6 +609,7 @@ func TestBind(t *testing.T) {
 			return
 		}
 	}
+	var cOut string
 	{
 		// output
 		cmd := exec.Command("./testdata/bind/a.out")
@@ -616,6 +622,7 @@ func TestBind(t *testing.T) {
 			return
 		}
 		t.Log(buf.String())
+		cOut = buf.String()
 	}
 
 	// create subfolders for test
@@ -631,7 +638,7 @@ func TestBind(t *testing.T) {
 	var args = DefaultProgramArgs()
 	args.inputFiles = []string{"./tests/bind/bind.c"}
 	args.outputFile = path.Join(subFolder, "main.go")
-	args.clangFlags = []string{"-Itests/bind", "./testdata/bind/libtest.a"}
+	args.clangFlags = []string{"-I./test/bind", "-L.", "-ltest"}
 	args.packageName = "main"
 	args.verbose = true // Added for checking verbose mode
 
@@ -643,12 +650,20 @@ func TestBind(t *testing.T) {
 		}
 	}
 
+	if d, err := ioutil.ReadFile("testdata/bind/main.go"); err != nil {
+		t.Fatal(err)
+	} else {
+		t.Log(string(d))
+	}
+
 	// Run Go program
+
 	out, err := args.runGoTest("", []string{""})
-	// 	if err != nil {
-	// 		t.Fatal(err)
-	// 	}
-	t.Logf("%s\n%v", out, err)
+	if err != nil {
+		t.Fatal(err)
+	}
+	t.Logf("%s\n%s", out, cOut)
+	// TODO : cannot view go results, but in console - all is ok
 }
 
 func TestTrigraph(t *testing.T) {
diff --git a/tests/bind/bind.c b/tests/bind/bind.c
index 4c458f0..486a7f0 100644
--- a/tests/bind/bind.c
+++ b/tests/bind/bind.c
@@ -1,7 +1,19 @@
 #include "test.h"
 
+int before();
+
 int main(void) 
 {
-	view();
-	return 0;
+	int q = before();
+	view0();
+	view1();
+	view2();
+	return q;
+}
+
+int before()
+{
+	int i = 0;
+	int *q = &i;
+	return *q;
 }
diff --git a/tests/bind/test.c b/tests/bind/test.c
index 0b60952..82350ca 100644
--- a/tests/bind/test.c
+++ b/tests/bind/test.c
@@ -1,6 +1,5 @@
 #include <stdio.h>
 
-void view()
-{
-	printf("view");
-}
+void view0() { printf("view0\n"); }
+void view1() { printf("view1\n"); }
+void view2() { printf("view2\n"); }
diff --git a/tests/bind/test.h b/tests/bind/test.h
index 45c567a..1c6a616 100644
--- a/tests/bind/test.h
+++ b/tests/bind/test.h
@@ -1,1 +1,3 @@
-void view();
+void view0();
+void view1();
+void view2();