Repository: Konstantin8105/c4go
Pull request #293 (2019-02-28 09:20:25)

transpileRecordDecl: fix typedef


Patch:
diff --git a/program/struct.go b/program/struct.go
index a32d83a..fa757da 100644
--- a/program/struct.go
+++ b/program/struct.go
@@ -29,11 +29,13 @@ type Struct struct {
 }
 
 // NewStruct creates a new Struct definition from an ast.RecordDecl.
-func NewStruct(n *ast.RecordDecl) (_ *Struct, err error) {
+func NewStruct(p *Program, n *ast.RecordDecl) (st *Struct, err error) {
 	defer func() {
 		if err != nil {
 			err = fmt.Errorf("Cannot create new structure : %T. Error : %v",
 				n, err)
+		} else {
+			p.Structs[n.Name] = st
 		}
 	}()
 	fields := make(map[string]interface{})
@@ -47,7 +49,7 @@ func NewStruct(n *ast.RecordDecl) (_ *Struct, err error) {
 			fields[f.Name] = f.Type
 
 		case *ast.RecordDecl:
-			fields[f.Name], err = NewStruct(f)
+			fields[f.Name], err = NewStruct(p, f)
 			if err != nil {
 				return
 			}
diff --git a/transpiler/binary.go b/transpiler/binary.go
index 4755ba9..4344f04 100644
--- a/transpiler/binary.go
+++ b/transpiler/binary.go
@@ -501,8 +501,7 @@ func getAllocationSizeNode(p *program.Program, node ast.Node) ast.Node {
 		return nil
 	}
 
-	functionName, err := getName(p, expr)
-	p.AddMessage(p.GenerateWarningMessage(err, node))
+	functionName, _ := getNameOfFunctionFromCallExpr(p, expr)
 
 	if functionName == "malloc" {
 		// Is 1 always the body in this case? Might need to be more careful
diff --git a/transpiler/call.go b/transpiler/call.go
index c20e880..586fa9d 100644
--- a/transpiler/call.go
+++ b/transpiler/call.go
@@ -65,9 +65,6 @@ func getName(p *program.Program, firstChild ast.Node) (name string, err error) {
 		}
 		return n + "." + fc.Name, nil
 
-	case *ast.CallExpr:
-		return getName(p, fc.Children()[0])
-
 	case *ast.ParenExpr:
 		return getName(p, fc.Children()[0])
 
@@ -97,6 +94,18 @@ func getName(p *program.Program, firstChild ast.Node) (name string, err error) {
 	return "", fmt.Errorf("cannot getName for: %#v", firstChild)
 }
 
+func getNameOfFunctionFromCallExpr(p *program.Program, n *ast.CallExpr) (string, error) {
+	// The first child will always contain the name of the function being
+	// called.
+	firstChild, ok := n.Children()[0].(*ast.ImplicitCastExpr)
+	if !ok {
+		err := fmt.Errorf("unable to use CallExpr: %#v", n.Children()[0])
+		return "", err
+	}
+
+	return getName(p, firstChild.Children()[0])
+}
+
 // simplificationCallExprPrintf - minimaze Go code
 // transpile C code : printf("Hello")
 // to Go code       : fmt_Printf("Hello")
@@ -192,7 +201,7 @@ func transpileCallExpr(n *ast.CallExpr, p *program.Program) (
 		}
 	}()
 
-	functionName, err := getName(p, n)
+	functionName, err := getNameOfFunctionFromCallExpr(p, n)
 	if err != nil {
 		return nil, "", nil, nil, err
 	}
diff --git a/transpiler/declarations.go b/transpiler/declarations.go
index 245bc10..dc4cb32 100644
--- a/transpiler/declarations.go
+++ b/transpiler/declarations.go
@@ -244,7 +244,7 @@ func transpileRecordDecl(p *program.Program, n *ast.RecordDecl) (
 		}
 	}
 
-	s, err := program.NewStruct(n)
+	s, err := program.NewStruct(p, n)
 	if err != nil {
 		p.AddMessage(p.GenerateWarningMessage(err, n))
 		return
@@ -527,16 +527,7 @@ func transpileTypedefDecl(p *program.Program, n *ast.TypedefDecl) (
 		resolvedType = "interface{}"
 	}
 
-	if v, ok := p.Structs["struct "+resolvedType]; ok {
-		// Registration "typedef struct" with non-empty name of struct
-		p.Structs["struct "+name] = v
-	} else if v, ok := p.EnumConstantToEnum["enum "+resolvedType]; ok {
-		// Registration "enum constants"
-		p.EnumConstantToEnum["enum "+resolvedType] = v
-	} else {
-		// Registration "typedef type type2"
-		p.TypedefType[n.Name] = n.Type
-	}
+	p.TypedefType[n.Name] = n.Type
 
 	// 0: *ast.GenDecl {
 	// .  Tok: type
diff --git a/types/sizeof.go b/types/sizeof.go
index 1ec8ba4..de8f08a 100644
--- a/types/sizeof.go
+++ b/types/sizeof.go
@@ -66,9 +66,8 @@ func SizeOf(p *program.Program, cType string) (size int, err error) {
 			}
 
 			if err != nil {
-				err = fmt.Errorf(
-					"Cannot calculate `struct` sizeof for `%T`. bytes = '%v'. %v",
-					t, bytes, err)
+				err = fmt.Errorf("Cannot canculate `struct` sizeof for `%T`. %v",
+					t, err)
 				return 0, err
 			}
 			totalBytes += bytes


Test patch:
diff --git a/tests/struct_sqlite.c b/tests/struct_sqlite.c
new file mode 100644
index 0000000..0d3ed9e
--- /dev/null
+++ b/tests/struct_sqlite.c
@@ -0,0 +1,41 @@
+#include "tests.h"
+
+typedef struct SP SP;
+
+struct SP {
+	union SP_UN {
+		int  i;
+		char l;
+	};
+	double d;
+	char   c;
+};
+
+typedef struct SP Mem ;
+typedef        SP Mem2;
+
+int main()
+{
+    plan(6);
+
+	Mem m;
+	is_true(sizeof(m ) >= sizeof(double) + sizeof(char) + sizeof(union SP_UN) );
+	(void)(m );
+
+	Mem2 m2;
+	is_true(sizeof(m2) >= sizeof(double) + sizeof(char) + sizeof(union SP_UN) );
+	(void)(m2);
+
+	SP s;
+	is_true(sizeof(s ) >= sizeof(double) + sizeof(char) + sizeof(union SP_UN) );
+	(void)(s );
+
+	union SP_UN sp;
+	is_true(sizeof(sp) >= sizeof(int) );
+	(void)(sp);
+
+	is_eq(sizeof(double),8);
+	is_eq(sizeof( char ),1);
+
+    done_testing();
+}