Repository: Konstantin8105/c4go
Pull request #296 (2019-02-28 12:17:17)

same name variable and type


Patch:
diff --git a/transpiler/binary.go b/transpiler/binary.go
index 4755ba9..ab12730 100644
--- a/transpiler/binary.go
+++ b/transpiler/binary.go
@@ -380,7 +380,7 @@ func transpileBinaryOperator(n *ast.BinaryOperator, p *program.Program, exprIsSt
 			// | `-DeclRefExpr 'char *' lvalue Var 0x26ba988 'c' 'char *'
 			// `-ImplicitCastExpr 'char *' <LValueToRValue>
 			//   `-DeclRefExpr 'char *' lvalue Var 0x26ba8a8 'b' 'char *'
-			if util.IsCPointer(leftType) {
+			if util.IsCPointer(leftType) || util.IsCArray(leftType) {
 				left = util.GetUintptr(left)
 				right = util.GetUintptr(right)
 				p.AddImport("unsafe")
diff --git a/transpiler/transpiler.go b/transpiler/transpiler.go
index 4447a99..f154969 100644
--- a/transpiler/transpiler.go
+++ b/transpiler/transpiler.go
@@ -10,6 +10,7 @@ import (
 	"go/token"
 	"os"
 	"strings"
+	"unicode"
 
 	"github.com/Konstantin8105/c4go/ast"
 	"github.com/Konstantin8105/c4go/program"
@@ -33,6 +34,69 @@ func TranspileAST(fileName, packageName string, withOutsideStructs bool,
 		return err
 	}
 
+	// replace if type name and variable name
+	{
+		var replacer func(ast.Node)
+		replacer = func(node ast.Node) {
+			if node == nil {
+				return
+			}
+			var vName *string
+			var vType *string
+			switch v := node.(type) {
+			case *ast.DeclRefExpr:
+				vName = &v.Name
+				vType = &v.Type
+			case *ast.VarDecl:
+				vName = &v.Name
+				vType = &v.Type
+			case *ast.ParmVarDecl:
+				vName = &v.Name
+				vType = &v.Type
+			}
+
+			// examples:
+			//   vName        vType
+			//   `wb`         `wb`
+			//   `wb`        `wb *`
+			//   `wb`      `struct wb`
+			//   `wb`      `struct wb *`
+			//   `wb`      `struct wb*`
+			//   `wb`      `struct wb [10]`
+			// not ok:
+			//   `wb`      `struct wba`
+			postfix := "_c4go_postfix"
+			if vType != nil && vName != nil &&
+				len(strings.TrimSpace(*vName)) > 0 &&
+				strings.Contains(*vType, *vName) {
+
+				for _, pr := range []string{*vName, "struct " + *vName, "union " + *vName} {
+					if pr == *vType {
+						*vName += postfix
+						break
+					}
+					if len(*vType) > len(pr) && pr == (*vType)[:len(pr)] && len(pr) > 0 {
+						letter := (*vType)[len(pr)]
+						if unicode.IsLetter(rune(letter)) {
+							continue
+						}
+						if unicode.IsNumber(rune(letter)) {
+							continue
+						}
+						if letter == '*' || letter == '[' || letter == ' ' {
+							*vName += postfix
+							break
+						}
+					}
+				}
+			}
+			for i := range node.Children() {
+				replacer(node.Children()[i])
+			}
+		}
+		replacer(root)
+	}
+
 	// Now begin building the Go AST.
 	decls, err := transpileToNode(root, p)
 	if err != nil {


Test patch:
diff --git a/tests/cast.c b/tests/cast.c
index 5234bb2..684d232 100644
--- a/tests/cast.c
+++ b/tests/cast.c
@@ -141,7 +141,7 @@ void test_unsafe_pnt()
 
 int main()
 {
-    plan(36);
+    plan(38);
 
     START_TEST(unsafe_pnt);
     START_TEST(bool_to_int);
@@ -257,6 +257,19 @@ int main()
             pass("long to bool")
         }
     }
+	diag("equal slice");
+	{
+		{
+			char n[10] = "hey";
+			char m[10] = "boy";
+			is_true( n != m );
+		}
+		{
+			char *n = "hey";
+			char *m = "boy";
+			is_true( n != m );
+		}
+	}
 
     char_overflow();
 
diff --git a/tests/struct.c b/tests/struct.c
index e384d4f..c806bb8 100644
--- a/tests/struct.c
+++ b/tests/struct.c
@@ -566,9 +566,41 @@ void test_extern_vec()
 }
 ext_vec Re;
 
+struct wb{
+	int i;
+};
+
+int wb_test(struct wb * wb)
+{
+	return wb->i;
+}
+
+void test_same_name()
+{
+	diag("=== same name ===");
+	{
+		struct wb wb;
+		wb.i = 42;
+		is_eq(wb_test(&wb),42);
+	}
+	{
+		struct wb tt;
+		tt.i = 42;
+		struct wb * wb;
+		wb = &tt;
+		is_eq(wb_test(wb),42);
+	}
+	{
+		struct wb wb[2];
+		wb[0].i = 42; wb[1].i = 42;
+		is_eq(wb_test(&(wb[0])),42);
+	}
+	diag("=================");
+}
+
 int main()
 {
-    plan(95);
+    plan(98);
 
     test_extern_vec();
     test_map_resize();
@@ -584,6 +616,7 @@ int main()
     test_sizeofArray();
     test_structUsed();
     test_emptyname();
+	test_same_name();
 
     struct programming variable;
     char* s = "Programming in Software Development.";