From dd5450e7b9f3a6eeb6c02b6a76c82fa3aff37180 Mon Sep 17 00:00:00 2001 From: Sahnvour Date: Sat, 26 Jan 2019 13:51:50 +0100 Subject: [PATCH 1/5] translate-c: get real child type of array type for incomplete initializers and/or multi-dimensional arrays. --- src/translate_c.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/translate_c.cpp b/src/translate_c.cpp index 02fa3b24be..1cf30278fc 100644 --- a/src/translate_c.cpp +++ b/src/translate_c.cpp @@ -4079,7 +4079,7 @@ static AstNode *trans_ap_value(Context *c, APValue *ap_value, QualType qt, const init_node->data.container_init_expr.type = arr_type_node; init_node->data.container_init_expr.kind = ContainerInitKindArray; - QualType child_qt = qt.getTypePtr()->getLocallyUnqualifiedSingleStepDesugaredType(); + QualType child_qt = qt.getTypePtr()->getAsArrayTypeUnsafe()->getElementType(); for (size_t i = 0; i < init_count; i += 1) { APValue &elem_ap_val = ap_value->getArrayInitializedElt(i); From b2662e443dac700efcc5c14bfb5ccb89a60cdb60 Mon Sep 17 00:00:00 2001 From: Sahnvour Date: Sat, 26 Jan 2019 15:38:17 +0100 Subject: [PATCH 2/5] translate-c: correct array concatenation for incomplete C array initializers. --- src/translate_c.cpp | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/src/translate_c.cpp b/src/translate_c.cpp index 1cf30278fc..54a97039d9 100644 --- a/src/translate_c.cpp +++ b/src/translate_c.cpp @@ -4076,6 +4076,9 @@ static AstNode *trans_ap_value(Context *c, APValue *ap_value, QualType qt, const unsigned leftover_count = all_count - init_count; AstNode *init_node = trans_create_node(c, NodeTypeContainerInitExpr); AstNode *arr_type_node = trans_qual_type(c, qt, source_loc); + if (leftover_count != 0) { // We can't use the size of the final array for a partial initializer. + bigint_init_unsigned(arr_type_node->data.array_type.size->data.int_literal.bigint, init_count); + } init_node->data.container_init_expr.type = arr_type_node; init_node->data.container_init_expr.kind = ContainerInitKindArray; @@ -4097,10 +4100,14 @@ static AstNode *trans_ap_value(Context *c, APValue *ap_value, QualType qt, const if (filler_node == nullptr) return nullptr; + AstNode* filler_arr_type = trans_create_node(c, NodeTypeArrayType); + *filler_arr_type = *arr_type_node; + filler_arr_type->data.array_type.size = trans_create_node_unsigned(c, 1); + AstNode *filler_arr_1 = trans_create_node(c, NodeTypeContainerInitExpr); - init_node->data.container_init_expr.type = arr_type_node; - init_node->data.container_init_expr.kind = ContainerInitKindArray; - init_node->data.container_init_expr.entries.append(filler_node); + filler_arr_1->data.container_init_expr.type = filler_arr_type; + filler_arr_1->data.container_init_expr.kind = ContainerInitKindArray; + filler_arr_1->data.container_init_expr.entries.append(filler_node); AstNode *rhs_node; if (leftover_count == 1) { From 584cb1fcfea5ff9f708719e345d621af24fa141f Mon Sep 17 00:00:00 2001 From: Sahnvour Date: Sat, 26 Jan 2019 15:53:19 +0100 Subject: [PATCH 3/5] translate-c: only detect ints as negative if they are signed. --- src/translate_c.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/translate_c.cpp b/src/translate_c.cpp index 54a97039d9..4cd8ed5a58 100644 --- a/src/translate_c.cpp +++ b/src/translate_c.cpp @@ -468,7 +468,7 @@ static const char *decl_name(const Decl *decl) { static AstNode *trans_create_node_apint(Context *c, const llvm::APSInt &aps_int) { AstNode *node = trans_create_node(c, NodeTypeIntLiteral); node->data.int_literal.bigint = allocate(1); - bool is_negative = aps_int.isNegative(); + bool is_negative = aps_int.isSigned() && aps_int.isNegative(); if (!is_negative) { bigint_init_data(node->data.int_literal.bigint, aps_int.getRawData(), aps_int.getNumWords(), false); return node; From f0d35d78b602859583773326a5ed2b53dfd70161 Mon Sep 17 00:00:00 2001 From: Sahnvour Date: Sat, 26 Jan 2019 16:47:11 +0100 Subject: [PATCH 4/5] translate-c: avoid array concatenation if the init node is empty, for clarity. --- src/translate_c.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/translate_c.cpp b/src/translate_c.cpp index 4cd8ed5a58..574742631f 100644 --- a/src/translate_c.cpp +++ b/src/translate_c.cpp @@ -4117,6 +4117,10 @@ static AstNode *trans_ap_value(Context *c, APValue *ap_value, QualType qt, const rhs_node = trans_create_node_bin_op(c, filler_arr_1, BinOpTypeArrayMult, amt_node); } + if (init_count == 0) { + return rhs_node; + } + return trans_create_node_bin_op(c, init_node, BinOpTypeArrayCat, rhs_node); } case APValue::LValue: { From 075fda3c732dc0e34d9917cc9c441b4dff75aa0e Mon Sep 17 00:00:00 2001 From: Sahnvour Date: Tue, 5 Feb 2019 20:36:57 +0100 Subject: [PATCH 5/5] translate-c: add tests. Commented for now as the output is currently empty until #646 is fixed. --- test/translate_c.zig | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/test/translate_c.zig b/test/translate_c.zig index 13f2a964d0..02020ddd73 100644 --- a/test/translate_c.zig +++ b/test/translate_c.zig @@ -1416,4 +1416,34 @@ pub fn addCases(cases: *tests.TranslateCContext) void { \\ } \\} ); + + // cases.add("empty array with initializer", + // "int a[4] = {};" + // , + // "pub var a: [4]c_int = [1]c_int{0} ** 4;" + // ); + + // cases.add("array with initialization", + // "int a[4] = {1, 2, 3, 4};" + // , + // "pub var a: [4]c_int = [4]c_int{1, 2, 3, 4};" + // ); + + // cases.add("array with incomplete initialization", + // "int a[4] = {3, 4};" + // , + // "pub var a: [4]c_int = [2]c_int{3, 4} ++ ([1]c_int{0} ** 2);" + // ); + + // cases.add("2D array with initialization", + // "int a[3][3] = { {1, 2, 3}, {4, 5, 6}, {7, 8, 9} };" + // , + // "pub var a: [3][3]c_int = [3][3]c_int{[3]c_int{1, 2, 3}, [3]c_int{4, 5, 6}, [3]c_int{7, 8, 9}};" + // ); + + // cases.add("2D array with incomplete initialization", + // "int a[3][3] = { {1, 2}, {4, 5, 6} };" + // , + // "pub var a: [3][3]c_int = [2][3]c_int{[2]c_int{1, 2} ++ [1]c_int{0}, [3]c_int{4, 5, 6}} ++ [1][3]c_int{[1]c_int{0} ** 3};" + // ); }