authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-03-18 14:43:17-04:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2019-03-18 14:43:17-04:00
loga17bf219c6f67d31f52e2ae7b379784b36c07bd5
treed606e902544a6170ef8a5583b606f3532be784b0
parent7dfbeca13eca48a506bbeba6ce7a18b2a8d25ce1
parent9171e7a7c11d2f5623a30683e1a0f510fe30b4de
signaturebadge-question-mark Signed by PGP key 4AEE18F83AFDEB23

Merge pull request #2069 from ziglang/glibc-assert-translation

Implemented enough of translate-c to translate assert

2 files changed, 268 insertions(+), 104 deletions(-)

src/translate_c.cpp+155-71
...@@ -690,6 +690,13 @@ static bool qual_type_child_is_fn_proto(const clang::QualType &qt) {...@@ -690,6 +690,13 @@ static bool qual_type_child_is_fn_proto(const clang::QualType &qt) {
690static AstNode* trans_c_cast(Context *c, const clang::SourceLocation &source_location, clang::QualType dest_type,690static AstNode* trans_c_cast(Context *c, const clang::SourceLocation &source_location, clang::QualType dest_type,
691 clang::QualType src_type, AstNode *expr)691 clang::QualType src_type, AstNode *expr)
692{692{
693 // The only way void pointer casts are valid C code, is if
694 // the value of the expression is ignored. We therefore just
695 // return the expr, and let the system that ignores values
696 // translate this correctly.
697 if (qual_type_canon(dest_type)->isVoidType()) {
698 return expr;
699 }
693 if (qual_types_equal(dest_type, src_type)) {700 if (qual_types_equal(dest_type, src_type)) {
694 return expr;701 return expr;
695 }702 }
...@@ -1225,6 +1232,31 @@ static AstNode *trans_compound_stmt(Context *c, TransScope *scope, const clang::...@@ -1225,6 +1232,31 @@ static AstNode *trans_compound_stmt(Context *c, TransScope *scope, const clang::
1225 return child_scope_block->node;1232 return child_scope_block->node;
1226}1233}
12271234
1235static AstNode *trans_stmt_expr(Context *c, ResultUsed result_used, TransScope *scope,
1236 const clang::StmtExpr *stmt, TransScope **out_node_scope)
1237{
1238 AstNode *block = trans_compound_stmt(c, scope, stmt->getSubStmt(), out_node_scope);
1239 if (block == nullptr)
1240 return block;
1241 assert(block->type == NodeTypeBlock);
1242 if (block->data.block.statements.length == 0)
1243 return block;
1244
1245 Buf *label = buf_create_from_str("x");
1246 block->data.block.name = label;
1247 AstNode *return_expr = block->data.block.statements.pop();
1248 if (return_expr->type == NodeTypeBinOpExpr &&
1249 return_expr->data.bin_op_expr.bin_op == BinOpTypeAssign &&
1250 return_expr->data.bin_op_expr.op1->type == NodeTypeSymbol)
1251 {
1252 Buf *symbol_buf = return_expr->data.bin_op_expr.op1->data.symbol_expr.symbol;
1253 if (strcmp("_", buf_ptr(symbol_buf)) == 0)
1254 return_expr = return_expr->data.bin_op_expr.op2;
1255 }
1256 block->data.block.statements.append(trans_create_node_break(c, label, return_expr));
1257 return maybe_suppress_result(c, result_used, block);
1258}
1259
1228static AstNode *trans_return_stmt(Context *c, TransScope *scope, const clang::ReturnStmt *stmt) {1260static AstNode *trans_return_stmt(Context *c, TransScope *scope, const clang::ReturnStmt *stmt) {
1229 const clang::Expr *value_expr = stmt->getRetValue();1261 const clang::Expr *value_expr = stmt->getRetValue();
1230 if (value_expr == nullptr) {1262 if (value_expr == nullptr) {
...@@ -1238,13 +1270,15 @@ static AstNode *trans_return_stmt(Context *c, TransScope *scope, const clang::Re...@@ -1238,13 +1270,15 @@ static AstNode *trans_return_stmt(Context *c, TransScope *scope, const clang::Re
1238 }1270 }
1239}1271}
12401272
1241static AstNode *trans_integer_literal(Context *c, const clang::IntegerLiteral *stmt) {1273static AstNode *trans_integer_literal(Context *c, ResultUsed result_used, const clang::IntegerLiteral *stmt) {
1242 llvm::APSInt result;1274 llvm::APSInt result;
1243 if (!stmt->EvaluateAsInt(result, *reinterpret_cast<clang::ASTContext *>(c->ctx))) {1275 if (!stmt->EvaluateAsInt(result, *reinterpret_cast<clang::ASTContext *>(c->ctx))) {
1244 emit_warning(c, stmt->getLocStart(), "invalid integer literal");1276 emit_warning(c, stmt->getLocStart(), "invalid integer literal");
1245 return nullptr;1277 return nullptr;
1246 }1278 }
1247 return trans_create_node_apint(c, result);1279
1280 AstNode *node = trans_create_node_apint(c, result);
1281 return maybe_suppress_result(c, result_used, node);
1248}1282}
12491283
1250static AstNode *trans_conditional_operator(Context *c, ResultUsed result_used, TransScope *scope,1284static AstNode *trans_conditional_operator(Context *c, ResultUsed result_used, TransScope *scope,
...@@ -1381,14 +1415,17 @@ static AstNode *trans_binary_operator(Context *c, ResultUsed result_used, TransS...@@ -1381,14 +1415,17 @@ static AstNode *trans_binary_operator(Context *c, ResultUsed result_used, TransS
1381 case clang::BO_Cmp:1415 case clang::BO_Cmp:
1382 emit_warning(c, stmt->getLocStart(), "TODO handle more C binary operators: clang::BO_Cmp");1416 emit_warning(c, stmt->getLocStart(), "TODO handle more C binary operators: clang::BO_Cmp");
1383 return nullptr;1417 return nullptr;
1384 case clang::BO_Mul:1418 case clang::BO_Mul: {
1385 return trans_create_bin_op(c, scope, stmt->getLHS(),1419 AstNode *node = trans_create_bin_op(c, scope, stmt->getLHS(),
1386 qual_type_has_wrapping_overflow(c, stmt->getType()) ? BinOpTypeMultWrap : BinOpTypeMult,1420 qual_type_has_wrapping_overflow(c, stmt->getType()) ? BinOpTypeMultWrap : BinOpTypeMult,
1387 stmt->getRHS());1421 stmt->getRHS());
1422 return maybe_suppress_result(c, result_used, node);
1423 }
1388 case clang::BO_Div:1424 case clang::BO_Div:
1389 if (qual_type_has_wrapping_overflow(c, stmt->getType())) {1425 if (qual_type_has_wrapping_overflow(c, stmt->getType())) {
1390 // unsigned/float division uses the operator1426 // unsigned/float division uses the operator
1391 return trans_create_bin_op(c, scope, stmt->getLHS(), BinOpTypeDiv, stmt->getRHS());1427 AstNode *node = trans_create_bin_op(c, scope, stmt->getLHS(), BinOpTypeDiv, stmt->getRHS());
1428 return maybe_suppress_result(c, result_used, node);
1392 } else {1429 } else {
1393 // signed integer division uses @divTrunc1430 // signed integer division uses @divTrunc
1394 AstNode *fn_call = trans_create_node_builtin_fn_call_str(c, "divTrunc");1431 AstNode *fn_call = trans_create_node_builtin_fn_call_str(c, "divTrunc");
...@@ -1398,12 +1435,13 @@ static AstNode *trans_binary_operator(Context *c, ResultUsed result_used, TransS...@@ -1398,12 +1435,13 @@ static AstNode *trans_binary_operator(Context *c, ResultUsed result_used, TransS
1398 AstNode *rhs = trans_expr(c, ResultUsedYes, scope, stmt->getRHS(), TransLValue);1435 AstNode *rhs = trans_expr(c, ResultUsedYes, scope, stmt->getRHS(), TransLValue);
1399 if (rhs == nullptr) return nullptr;1436 if (rhs == nullptr) return nullptr;
1400 fn_call->data.fn_call_expr.params.append(rhs);1437 fn_call->data.fn_call_expr.params.append(rhs);
1401 return fn_call;1438 return maybe_suppress_result(c, result_used, fn_call);
1402 }1439 }
1403 case clang::BO_Rem:1440 case clang::BO_Rem:
1404 if (qual_type_has_wrapping_overflow(c, stmt->getType())) {1441 if (qual_type_has_wrapping_overflow(c, stmt->getType())) {
1405 // unsigned/float division uses the operator1442 // unsigned/float division uses the operator
1406 return trans_create_bin_op(c, scope, stmt->getLHS(), BinOpTypeMod, stmt->getRHS());1443 AstNode *node = trans_create_bin_op(c, scope, stmt->getLHS(), BinOpTypeMod, stmt->getRHS());
1444 return maybe_suppress_result(c, result_used, node);
1407 } else {1445 } else {
1408 // signed integer division uses @rem1446 // signed integer division uses @rem
1409 AstNode *fn_call = trans_create_node_builtin_fn_call_str(c, "rem");1447 AstNode *fn_call = trans_create_node_builtin_fn_call_str(c, "rem");
...@@ -1413,42 +1451,72 @@ static AstNode *trans_binary_operator(Context *c, ResultUsed result_used, TransS...@@ -1413,42 +1451,72 @@ static AstNode *trans_binary_operator(Context *c, ResultUsed result_used, TransS
1413 AstNode *rhs = trans_expr(c, ResultUsedYes, scope, stmt->getRHS(), TransLValue);1451 AstNode *rhs = trans_expr(c, ResultUsedYes, scope, stmt->getRHS(), TransLValue);
1414 if (rhs == nullptr) return nullptr;1452 if (rhs == nullptr) return nullptr;
1415 fn_call->data.fn_call_expr.params.append(rhs);1453 fn_call->data.fn_call_expr.params.append(rhs);
1416 return fn_call;1454 return maybe_suppress_result(c, result_used, fn_call);
1417 }1455 }
1418 case clang::BO_Add:1456 case clang::BO_Add: {
1419 return trans_create_bin_op(c, scope, stmt->getLHS(),1457 AstNode *node = trans_create_bin_op(c, scope, stmt->getLHS(),
1420 qual_type_has_wrapping_overflow(c, stmt->getType()) ? BinOpTypeAddWrap : BinOpTypeAdd,1458 qual_type_has_wrapping_overflow(c, stmt->getType()) ? BinOpTypeAddWrap : BinOpTypeAdd,
1421 stmt->getRHS());1459 stmt->getRHS());
1422 case clang::BO_Sub:1460 return maybe_suppress_result(c, result_used, node);
1423 return trans_create_bin_op(c, scope, stmt->getLHS(),1461 }
1462 case clang::BO_Sub: {
1463 AstNode *node = trans_create_bin_op(c, scope, stmt->getLHS(),
1424 qual_type_has_wrapping_overflow(c, stmt->getType()) ? BinOpTypeSubWrap : BinOpTypeSub,1464 qual_type_has_wrapping_overflow(c, stmt->getType()) ? BinOpTypeSubWrap : BinOpTypeSub,
1425 stmt->getRHS());1465 stmt->getRHS());
1426 case clang::BO_Shl:1466 return maybe_suppress_result(c, result_used, node);
1427 return trans_create_shift_op(c, scope, stmt->getType(), stmt->getLHS(), BinOpTypeBitShiftLeft, stmt->getRHS());1467 }
1428 case clang::BO_Shr:1468 case clang::BO_Shl: {
1429 return trans_create_shift_op(c, scope, stmt->getType(), stmt->getLHS(), BinOpTypeBitShiftRight, stmt->getRHS());1469 AstNode *node = trans_create_shift_op(c, scope, stmt->getType(), stmt->getLHS(), BinOpTypeBitShiftLeft, stmt->getRHS());
1430 case clang::BO_LT:1470 return maybe_suppress_result(c, result_used, node);
1431 return trans_create_bin_op(c, scope, stmt->getLHS(), BinOpTypeCmpLessThan, stmt->getRHS());1471 }
1432 case clang::BO_GT:1472 case clang::BO_Shr: {
1433 return trans_create_bin_op(c, scope, stmt->getLHS(), BinOpTypeCmpGreaterThan, stmt->getRHS());1473 AstNode *node = trans_create_shift_op(c, scope, stmt->getType(), stmt->getLHS(), BinOpTypeBitShiftRight, stmt->getRHS());
1434 case clang::BO_LE:1474 return maybe_suppress_result(c, result_used, node);
1435 return trans_create_bin_op(c, scope, stmt->getLHS(), BinOpTypeCmpLessOrEq, stmt->getRHS());1475 }
1436 case clang::BO_GE:1476 case clang::BO_LT: {
1437 return trans_create_bin_op(c, scope, stmt->getLHS(), BinOpTypeCmpGreaterOrEq, stmt->getRHS());1477 AstNode *node =trans_create_bin_op(c, scope, stmt->getLHS(), BinOpTypeCmpLessThan, stmt->getRHS());
1438 case clang::BO_EQ:1478 return maybe_suppress_result(c, result_used, node);
1439 return trans_create_bin_op(c, scope, stmt->getLHS(), BinOpTypeCmpEq, stmt->getRHS());1479 }
1440 case clang::BO_NE:1480 case clang::BO_GT: {
1441 return trans_create_bin_op(c, scope, stmt->getLHS(), BinOpTypeCmpNotEq, stmt->getRHS());1481 AstNode *node = trans_create_bin_op(c, scope, stmt->getLHS(), BinOpTypeCmpGreaterThan, stmt->getRHS());
1442 case clang::BO_And:1482 return maybe_suppress_result(c, result_used, node);
1443 return trans_create_bin_op(c, scope, stmt->getLHS(), BinOpTypeBinAnd, stmt->getRHS());1483 }
1444 case clang::BO_Xor:1484 case clang::BO_LE: {
1445 return trans_create_bin_op(c, scope, stmt->getLHS(), BinOpTypeBinXor, stmt->getRHS());1485 AstNode *node = trans_create_bin_op(c, scope, stmt->getLHS(), BinOpTypeCmpLessOrEq, stmt->getRHS());
1446 case clang::BO_Or:1486 return maybe_suppress_result(c, result_used, node);
1447 return trans_create_bin_op(c, scope, stmt->getLHS(), BinOpTypeBinOr, stmt->getRHS());1487 }
1448 case clang::BO_LAnd:1488 case clang::BO_GE: {
1449 return trans_create_bool_bin_op(c, scope, stmt->getLHS(), BinOpTypeBoolAnd, stmt->getRHS());1489 AstNode *node = trans_create_bin_op(c, scope, stmt->getLHS(), BinOpTypeCmpGreaterOrEq, stmt->getRHS());
1450 case clang::BO_LOr:1490 return maybe_suppress_result(c, result_used, node);
1451 return trans_create_bool_bin_op(c, scope, stmt->getLHS(), BinOpTypeBoolOr, stmt->getRHS());1491 }
1492 case clang::BO_EQ: {
1493 AstNode *node = trans_create_bin_op(c, scope, stmt->getLHS(), BinOpTypeCmpEq, stmt->getRHS());
1494 return maybe_suppress_result(c, result_used, node);
1495 }
1496 case clang::BO_NE: {
1497 AstNode *node = trans_create_bin_op(c, scope, stmt->getLHS(), BinOpTypeCmpNotEq, stmt->getRHS());
1498 return maybe_suppress_result(c, result_used, node);
1499 }
1500 case clang::BO_And: {
1501 AstNode *node = trans_create_bin_op(c, scope, stmt->getLHS(), BinOpTypeBinAnd, stmt->getRHS());
1502 return maybe_suppress_result(c, result_used, node);
1503 }
1504 case clang::BO_Xor: {
1505 AstNode *node = trans_create_bin_op(c, scope, stmt->getLHS(), BinOpTypeBinXor, stmt->getRHS());
1506 return maybe_suppress_result(c, result_used, node);
1507 }
1508 case clang::BO_Or: {
1509 AstNode *node = trans_create_bin_op(c, scope, stmt->getLHS(), BinOpTypeBinOr, stmt->getRHS());
1510 return maybe_suppress_result(c, result_used, node);
1511 }
1512 case clang::BO_LAnd: {
1513 AstNode *node = trans_create_bool_bin_op(c, scope, stmt->getLHS(), BinOpTypeBoolAnd, stmt->getRHS());
1514 return maybe_suppress_result(c, result_used, node);
1515 }
1516 case clang::BO_LOr: {
1517 AstNode *node = trans_create_bool_bin_op(c, scope, stmt->getLHS(), BinOpTypeBoolOr, stmt->getRHS());
1518 return maybe_suppress_result(c, result_used, node);
1519 }
1452 case clang::BO_Assign:1520 case clang::BO_Assign:
1453 return trans_create_assign(c, result_used, scope, stmt->getLHS(), stmt->getRHS());1521 return trans_create_assign(c, result_used, scope, stmt->getLHS(), stmt->getRHS());
1454 case clang::BO_Comma:1522 case clang::BO_Comma:
...@@ -1460,13 +1528,15 @@ static AstNode *trans_binary_operator(Context *c, ResultUsed result_used, TransS...@@ -1460,13 +1528,15 @@ static AstNode *trans_binary_operator(Context *c, ResultUsed result_used, TransS
1460 AstNode *lhs = trans_expr(c, ResultUsedNo, &scope_block->base, stmt->getLHS(), TransRValue);1528 AstNode *lhs = trans_expr(c, ResultUsedNo, &scope_block->base, stmt->getLHS(), TransRValue);
1461 if (lhs == nullptr)1529 if (lhs == nullptr)
1462 return nullptr;1530 return nullptr;
1463 scope_block->node->data.block.statements.append(maybe_suppress_result(c, ResultUsedNo, lhs));1531 scope_block->node->data.block.statements.append(lhs);
14641532
1465 AstNode *rhs = trans_expr(c, result_used, &scope_block->base, stmt->getRHS(), TransRValue);1533 AstNode *rhs = trans_expr(c, ResultUsedYes, &scope_block->base, stmt->getRHS(), TransRValue);
1466 if (rhs == nullptr)1534 if (rhs == nullptr)
1467 return nullptr;1535 return nullptr;
1468 scope_block->node->data.block.statements.append(trans_create_node_break(c, label_name, maybe_suppress_result(c, result_used, rhs)));1536
1469 return scope_block->node;1537 rhs = trans_create_node_break(c, label_name, rhs);
1538 scope_block->node->data.block.statements.append(rhs);
1539 return maybe_suppress_result(c, result_used, scope_block->node);
1470 }1540 }
1471 case clang::BO_MulAssign:1541 case clang::BO_MulAssign:
1472 case clang::BO_DivAssign:1542 case clang::BO_DivAssign:
...@@ -1692,7 +1762,7 @@ static AstNode *trans_compound_assign_operator(Context *c, ResultUsed result_use...@@ -1692,7 +1762,7 @@ static AstNode *trans_compound_assign_operator(Context *c, ResultUsed result_use
1692 zig_unreachable();1762 zig_unreachable();
1693}1763}
16941764
1695static AstNode *trans_implicit_cast_expr(Context *c, TransScope *scope, const clang::ImplicitCastExpr *stmt) {1765static AstNode *trans_implicit_cast_expr(Context *c, ResultUsed result_used, TransScope *scope, const clang::ImplicitCastExpr *stmt) {
1696 switch (stmt->getCastKind()) {1766 switch (stmt->getCastKind()) {
1697 case clang::CK_LValueToRValue:1767 case clang::CK_LValueToRValue:
1698 return trans_expr(c, ResultUsedYes, scope, stmt->getSubExpr(), TransRValue);1768 return trans_expr(c, ResultUsedYes, scope, stmt->getSubExpr(), TransRValue);
...@@ -1701,8 +1771,9 @@ static AstNode *trans_implicit_cast_expr(Context *c, TransScope *scope, const cl...@@ -1701,8 +1771,9 @@ static AstNode *trans_implicit_cast_expr(Context *c, TransScope *scope, const cl
1701 AstNode *target_node = trans_expr(c, ResultUsedYes, scope, stmt->getSubExpr(), TransRValue);1771 AstNode *target_node = trans_expr(c, ResultUsedYes, scope, stmt->getSubExpr(), TransRValue);
1702 if (target_node == nullptr)1772 if (target_node == nullptr)
1703 return nullptr;1773 return nullptr;
1704 return trans_c_cast(c, stmt->getExprLoc(), stmt->getType(),1774 AstNode *node = trans_c_cast(c, stmt->getExprLoc(), stmt->getType(),
1705 stmt->getSubExpr()->getType(), target_node);1775 stmt->getSubExpr()->getType(), target_node);
1776 return maybe_suppress_result(c, result_used, node);
1706 }1777 }
1707 case clang::CK_FunctionToPointerDecay:1778 case clang::CK_FunctionToPointerDecay:
1708 case clang::CK_ArrayToPointerDecay:1779 case clang::CK_ArrayToPointerDecay:
...@@ -1710,7 +1781,7 @@ static AstNode *trans_implicit_cast_expr(Context *c, TransScope *scope, const cl...@@ -1710,7 +1781,7 @@ static AstNode *trans_implicit_cast_expr(Context *c, TransScope *scope, const cl
1710 AstNode *target_node = trans_expr(c, ResultUsedYes, scope, stmt->getSubExpr(), TransRValue);1781 AstNode *target_node = trans_expr(c, ResultUsedYes, scope, stmt->getSubExpr(), TransRValue);
1711 if (target_node == nullptr)1782 if (target_node == nullptr)
1712 return nullptr;1783 return nullptr;
1713 return target_node;1784 return maybe_suppress_result(c, result_used, target_node);
1714 }1785 }
1715 case clang::CK_BitCast:1786 case clang::CK_BitCast:
1716 {1787 {
...@@ -1727,7 +1798,7 @@ static AstNode *trans_implicit_cast_expr(Context *c, TransScope *scope, const cl...@@ -1727,7 +1798,7 @@ static AstNode *trans_implicit_cast_expr(Context *c, TransScope *scope, const cl
1727 AstNode *node = trans_create_node_builtin_fn_call_str(c, "ptrCast");1798 AstNode *node = trans_create_node_builtin_fn_call_str(c, "ptrCast");
1728 node->data.fn_call_expr.params.append(dest_type_node);1799 node->data.fn_call_expr.params.append(dest_type_node);
1729 node->data.fn_call_expr.params.append(target_node);1800 node->data.fn_call_expr.params.append(target_node);
1730 return node;1801 return maybe_suppress_result(c, result_used, node);
1731 }1802 }
1732 case clang::CK_NullToPointer:1803 case clang::CK_NullToPointer:
1733 return trans_create_node_unsigned(c, 0);1804 return trans_create_node_unsigned(c, 0);
...@@ -2103,8 +2174,7 @@ static AstNode *trans_unary_operator(Context *c, ResultUsed result_used, TransSc...@@ -2103,8 +2174,7 @@ static AstNode *trans_unary_operator(Context *c, ResultUsed result_used, TransSc
2103 emit_warning(c, stmt->getLocStart(), "TODO handle C translation clang::UO_Imag");2174 emit_warning(c, stmt->getLocStart(), "TODO handle C translation clang::UO_Imag");
2104 return nullptr;2175 return nullptr;
2105 case clang::UO_Extension:2176 case clang::UO_Extension:
2106 emit_warning(c, stmt->getLocStart(), "TODO handle C translation clang::UO_Extension");2177 return trans_expr(c, result_used, scope, stmt->getSubExpr(), TransLValue);
2107 return nullptr;
2108 case clang::UO_Coawait:2178 case clang::UO_Coawait:
2109 emit_warning(c, stmt->getLocStart(), "TODO handle C translation clang::UO_Coawait");2179 emit_warning(c, stmt->getLocStart(), "TODO handle C translation clang::UO_Coawait");
2110 return nullptr;2180 return nullptr;
...@@ -2721,7 +2791,9 @@ static AstNode *trans_call_expr(Context *c, ResultUsed result_used, TransScope *...@@ -2721,7 +2791,9 @@ static AstNode *trans_call_expr(Context *c, ResultUsed result_used, TransScope *
2721 return node;2791 return node;
2722}2792}
27232793
2724static AstNode *trans_member_expr(Context *c, TransScope *scope, const clang::MemberExpr *stmt) {2794static AstNode *trans_member_expr(Context *c, ResultUsed result_used, TransScope *scope,
2795 const clang::MemberExpr *stmt)
2796{
2725 AstNode *container_node = trans_expr(c, ResultUsedYes, scope, stmt->getBase(), TransRValue);2797 AstNode *container_node = trans_expr(c, ResultUsedYes, scope, stmt->getBase(), TransRValue);
2726 if (container_node == nullptr)2798 if (container_node == nullptr)
2727 return nullptr;2799 return nullptr;
...@@ -2733,10 +2805,10 @@ static AstNode *trans_member_expr(Context *c, TransScope *scope, const clang::Me...@@ -2733,10 +2805,10 @@ static AstNode *trans_member_expr(Context *c, TransScope *scope, const clang::Me
2733 const char *name = decl_name(stmt->getMemberDecl());2805 const char *name = decl_name(stmt->getMemberDecl());
27342806
2735 AstNode *node = trans_create_node_field_access_str(c, container_node, name);2807 AstNode *node = trans_create_node_field_access_str(c, container_node, name);
2736 return node;2808 return maybe_suppress_result(c, result_used, node);
2737}2809}
27382810
2739static AstNode *trans_array_subscript_expr(Context *c, TransScope *scope, const clang::ArraySubscriptExpr *stmt) {2811static AstNode *trans_array_subscript_expr(Context *c, ResultUsed result_used, TransScope *scope, const clang::ArraySubscriptExpr *stmt) {
2740 AstNode *container_node = trans_expr(c, ResultUsedYes, scope, stmt->getBase(), TransRValue);2812 AstNode *container_node = trans_expr(c, ResultUsedYes, scope, stmt->getBase(), TransRValue);
2741 if (container_node == nullptr)2813 if (container_node == nullptr)
2742 return nullptr;2814 return nullptr;
...@@ -2749,21 +2821,25 @@ static AstNode *trans_array_subscript_expr(Context *c, TransScope *scope, const...@@ -2749,21 +2821,25 @@ static AstNode *trans_array_subscript_expr(Context *c, TransScope *scope, const
2749 AstNode *node = trans_create_node(c, NodeTypeArrayAccessExpr);2821 AstNode *node = trans_create_node(c, NodeTypeArrayAccessExpr);
2750 node->data.array_access_expr.array_ref_expr = container_node;2822 node->data.array_access_expr.array_ref_expr = container_node;
2751 node->data.array_access_expr.subscript = idx_node;2823 node->data.array_access_expr.subscript = idx_node;
2752 return node;2824 return maybe_suppress_result(c, result_used, node);
2753}2825}
27542826
2755static AstNode *trans_c_style_cast_expr(Context *c, ResultUsed result_used, TransScope *scope,2827static AstNode *trans_c_style_cast_expr(Context *c, ResultUsed result_used, TransScope *scope,
2756 const clang::CStyleCastExpr *stmt, TransLRValue lrvalue)2828 const clang::CStyleCastExpr *stmt, TransLRValue lrvalue)
2757{2829{
2758 AstNode *sub_expr_node = trans_expr(c, result_used, scope, stmt->getSubExpr(), lrvalue);2830 AstNode *sub_expr_node = trans_expr(c, ResultUsedYes, scope, stmt->getSubExpr(), lrvalue);
2759 if (sub_expr_node == nullptr)2831 if (sub_expr_node == nullptr)
2760 return nullptr;2832 return nullptr;
27612833
2762 return trans_c_cast(c, stmt->getLocStart(), stmt->getType(), stmt->getSubExpr()->getType(), sub_expr_node);2834 AstNode *cast = trans_c_cast(c, stmt->getLocStart(), stmt->getType(), stmt->getSubExpr()->getType(), sub_expr_node);
2835 if (cast == nullptr)
2836 return nullptr;
2837
2838 return maybe_suppress_result(c, result_used, cast);
2763}2839}
27642840
2765static AstNode *trans_unary_expr_or_type_trait_expr(Context *c, TransScope *scope,2841static AstNode *trans_unary_expr_or_type_trait_expr(Context *c, ResultUsed result_used,
2766 const clang::UnaryExprOrTypeTraitExpr *stmt)2842 TransScope *scope, const clang::UnaryExprOrTypeTraitExpr *stmt)
2767{2843{
2768 AstNode *type_node = trans_qual_type(c, stmt->getTypeOfArgument(), stmt->getLocStart());2844 AstNode *type_node = trans_qual_type(c, stmt->getTypeOfArgument(), stmt->getLocStart());
2769 if (type_node == nullptr)2845 if (type_node == nullptr)
...@@ -2771,7 +2847,7 @@ static AstNode *trans_unary_expr_or_type_trait_expr(Context *c, TransScope *scop...@@ -2771,7 +2847,7 @@ static AstNode *trans_unary_expr_or_type_trait_expr(Context *c, TransScope *scop
27712847
2772 AstNode *node = trans_create_node_builtin_fn_call_str(c, "sizeOf");2848 AstNode *node = trans_create_node_builtin_fn_call_str(c, "sizeOf");
2773 node->data.fn_call_expr.params.append(type_node);2849 node->data.fn_call_expr.params.append(type_node);
2774 return node;2850 return maybe_suppress_result(c, result_used, node);
2775}2851}
27762852
2777static AstNode *trans_do_loop(Context *c, TransScope *parent_scope, const clang::DoStmt *stmt) {2853static AstNode *trans_do_loop(Context *c, TransScope *parent_scope, const clang::DoStmt *stmt) {
...@@ -3049,11 +3125,13 @@ static int trans_switch_default(Context *c, TransScope *parent_scope, const clan...@@ -3049,11 +3125,13 @@ static int trans_switch_default(Context *c, TransScope *parent_scope, const clan
3049 return ErrorNone;3125 return ErrorNone;
3050}3126}
30513127
3052static AstNode *trans_string_literal(Context *c, TransScope *scope, const clang::StringLiteral *stmt) {3128static AstNode *trans_string_literal(Context *c, ResultUsed result_used, TransScope *scope, const clang::StringLiteral *stmt) {
3053 switch (stmt->getKind()) {3129 switch (stmt->getKind()) {
3054 case clang::StringLiteral::Ascii:3130 case clang::StringLiteral::Ascii:
3055 case clang::StringLiteral::UTF8:3131 case clang::StringLiteral::UTF8: {
3056 return trans_create_node_str_lit_c(c, string_ref_to_buf(stmt->getString()));3132 AstNode *node = trans_create_node_str_lit_c(c, string_ref_to_buf(stmt->getString()));
3133 return maybe_suppress_result(c, result_used, node);
3134 }
3057 case clang::StringLiteral::UTF16:3135 case clang::StringLiteral::UTF16:
3058 emit_warning(c, stmt->getLocStart(), "TODO support UTF16 string literals");3136 emit_warning(c, stmt->getLocStart(), "TODO support UTF16 string literals");
3059 return nullptr;3137 return nullptr;
...@@ -3085,6 +3163,12 @@ static AstNode *trans_continue_stmt(Context *c, TransScope *scope, const clang::...@@ -3085,6 +3163,12 @@ static AstNode *trans_continue_stmt(Context *c, TransScope *scope, const clang::
3085 return trans_create_node(c, NodeTypeContinue);3163 return trans_create_node(c, NodeTypeContinue);
3086}3164}
30873165
3166static AstNode *trans_predefined_expr(Context *c, ResultUsed result_used, TransScope *scope,
3167 const clang::PredefinedExpr *expr)
3168{
3169 return trans_string_literal(c, result_used, scope, expr->getFunctionName());
3170}
3171
3088static int wrap_stmt(AstNode **out_node, TransScope **out_scope, TransScope *in_scope, AstNode *result_node) {3172static int wrap_stmt(AstNode **out_node, TransScope **out_scope, TransScope *in_scope, AstNode *result_node) {
3089 if (result_node == nullptr)3173 if (result_node == nullptr)
3090 return ErrorUnexpected;3174 return ErrorUnexpected;
...@@ -3109,7 +3193,7 @@ static int trans_stmt_extra(Context *c, TransScope *scope, const clang::Stmt *st...@@ -3109,7 +3193,7 @@ static int trans_stmt_extra(Context *c, TransScope *scope, const clang::Stmt *st
3109 trans_compound_stmt(c, scope, (const clang::CompoundStmt *)stmt, out_node_scope));3193 trans_compound_stmt(c, scope, (const clang::CompoundStmt *)stmt, out_node_scope));
3110 case clang::Stmt::IntegerLiteralClass:3194 case clang::Stmt::IntegerLiteralClass:
3111 return wrap_stmt(out_node, out_child_scope, scope,3195 return wrap_stmt(out_node, out_child_scope, scope,
3112 trans_integer_literal(c, (const clang::IntegerLiteral *)stmt));3196 trans_integer_literal(c, result_used, (const clang::IntegerLiteral *)stmt));
3113 case clang::Stmt::ConditionalOperatorClass:3197 case clang::Stmt::ConditionalOperatorClass:
3114 return wrap_stmt(out_node, out_child_scope, scope,3198 return wrap_stmt(out_node, out_child_scope, scope,
3115 trans_conditional_operator(c, result_used, scope, (const clang::ConditionalOperator *)stmt));3199 trans_conditional_operator(c, result_used, scope, (const clang::ConditionalOperator *)stmt));
...@@ -3121,7 +3205,7 @@ static int trans_stmt_extra(Context *c, TransScope *scope, const clang::Stmt *st...@@ -3121,7 +3205,7 @@ static int trans_stmt_extra(Context *c, TransScope *scope, const clang::Stmt *st
3121 trans_compound_assign_operator(c, result_used, scope, (const clang::CompoundAssignOperator *)stmt));3205 trans_compound_assign_operator(c, result_used, scope, (const clang::CompoundAssignOperator *)stmt));
3122 case clang::Stmt::ImplicitCastExprClass:3206 case clang::Stmt::ImplicitCastExprClass:
3123 return wrap_stmt(out_node, out_child_scope, scope,3207 return wrap_stmt(out_node, out_child_scope, scope,
3124 trans_implicit_cast_expr(c, scope, (const clang::ImplicitCastExpr *)stmt));3208 trans_implicit_cast_expr(c, result_used, scope, (const clang::ImplicitCastExpr *)stmt));
3125 case clang::Stmt::DeclRefExprClass:3209 case clang::Stmt::DeclRefExprClass:
3126 return wrap_stmt(out_node, out_child_scope, scope,3210 return wrap_stmt(out_node, out_child_scope, scope,
3127 trans_decl_ref_expr(c, scope, (const clang::DeclRefExpr *)stmt, lrvalue));3211 trans_decl_ref_expr(c, scope, (const clang::DeclRefExpr *)stmt, lrvalue));
...@@ -3152,28 +3236,28 @@ static int trans_stmt_extra(Context *c, TransScope *scope, const clang::Stmt *st...@@ -3152,28 +3236,28 @@ static int trans_stmt_extra(Context *c, TransScope *scope, const clang::Stmt *st
3152 return wrap_stmt(out_node, out_child_scope, scope,3236 return wrap_stmt(out_node, out_child_scope, scope,
3153 trans_call_expr(c, result_used, scope, (const clang::CallExpr *)stmt));3237 trans_call_expr(c, result_used, scope, (const clang::CallExpr *)stmt));
3154 case clang::Stmt::NullStmtClass:3238 case clang::Stmt::NullStmtClass:
3155 *out_node = nullptr;3239 *out_node = trans_create_node(c, NodeTypeBlock);
3156 *out_child_scope = scope;3240 *out_child_scope = scope;
3157 return ErrorNone;3241 return ErrorNone;
3158 case clang::Stmt::MemberExprClass:3242 case clang::Stmt::MemberExprClass:
3159 return wrap_stmt(out_node, out_child_scope, scope,3243 return wrap_stmt(out_node, out_child_scope, scope,
3160 trans_member_expr(c, scope, (const clang::MemberExpr *)stmt));3244 trans_member_expr(c, result_used, scope, (const clang::MemberExpr *)stmt));
3161 case clang::Stmt::ArraySubscriptExprClass:3245 case clang::Stmt::ArraySubscriptExprClass:
3162 return wrap_stmt(out_node, out_child_scope, scope,3246 return wrap_stmt(out_node, out_child_scope, scope,
3163 trans_array_subscript_expr(c, scope, (const clang::ArraySubscriptExpr *)stmt));3247 trans_array_subscript_expr(c, result_used, scope, (const clang::ArraySubscriptExpr *)stmt));
3164 case clang::Stmt::CStyleCastExprClass:3248 case clang::Stmt::CStyleCastExprClass:
3165 return wrap_stmt(out_node, out_child_scope, scope,3249 return wrap_stmt(out_node, out_child_scope, scope,
3166 trans_c_style_cast_expr(c, result_used, scope, (const clang::CStyleCastExpr *)stmt, lrvalue));3250 trans_c_style_cast_expr(c, result_used, scope, (const clang::CStyleCastExpr *)stmt, lrvalue));
3167 case clang::Stmt::UnaryExprOrTypeTraitExprClass:3251 case clang::Stmt::UnaryExprOrTypeTraitExprClass:
3168 return wrap_stmt(out_node, out_child_scope, scope,3252 return wrap_stmt(out_node, out_child_scope, scope,
3169 trans_unary_expr_or_type_trait_expr(c, scope, (const clang::UnaryExprOrTypeTraitExpr *)stmt));3253 trans_unary_expr_or_type_trait_expr(c, result_used, scope, (const clang::UnaryExprOrTypeTraitExpr *)stmt));
3170 case clang::Stmt::ForStmtClass: {3254 case clang::Stmt::ForStmtClass: {
3171 AstNode *node = trans_for_loop(c, scope, (const clang::ForStmt *)stmt);3255 AstNode *node = trans_for_loop(c, scope, (const clang::ForStmt *)stmt);
3172 return wrap_stmt(out_node, out_child_scope, scope, node);3256 return wrap_stmt(out_node, out_child_scope, scope, node);
3173 }3257 }
3174 case clang::Stmt::StringLiteralClass:3258 case clang::Stmt::StringLiteralClass:
3175 return wrap_stmt(out_node, out_child_scope, scope,3259 return wrap_stmt(out_node, out_child_scope, scope,
3176 trans_string_literal(c, scope, (const clang::StringLiteral *)stmt));3260 trans_string_literal(c, result_used, scope, (const clang::StringLiteral *)stmt));
3177 case clang::Stmt::BreakStmtClass:3261 case clang::Stmt::BreakStmtClass:
3178 return wrap_stmt(out_node, out_child_scope, scope,3262 return wrap_stmt(out_node, out_child_scope, scope,
3179 trans_break_stmt(c, scope, (const clang::BreakStmt *)stmt));3263 trans_break_stmt(c, scope, (const clang::BreakStmt *)stmt));
...@@ -3479,8 +3563,8 @@ static int trans_stmt_extra(Context *c, TransScope *scope, const clang::Stmt *st...@@ -3479,8 +3563,8 @@ static int trans_stmt_extra(Context *c, TransScope *scope, const clang::Stmt *st
3479 emit_warning(c, stmt->getLocStart(), "TODO handle C ParenListExprClass");3563 emit_warning(c, stmt->getLocStart(), "TODO handle C ParenListExprClass");
3480 return ErrorUnexpected;3564 return ErrorUnexpected;
3481 case clang::Stmt::PredefinedExprClass:3565 case clang::Stmt::PredefinedExprClass:
3482 emit_warning(c, stmt->getLocStart(), "TODO handle C PredefinedExprClass");3566 return wrap_stmt(out_node, out_child_scope, scope,
3483 return ErrorUnexpected;3567 trans_predefined_expr(c, result_used, scope, (const clang::PredefinedExpr *)stmt));
3484 case clang::Stmt::PseudoObjectExprClass:3568 case clang::Stmt::PseudoObjectExprClass:
3485 emit_warning(c, stmt->getLocStart(), "TODO handle C PseudoObjectExprClass");3569 emit_warning(c, stmt->getLocStart(), "TODO handle C PseudoObjectExprClass");
3486 return ErrorUnexpected;3570 return ErrorUnexpected;
...@@ -3491,8 +3575,8 @@ static int trans_stmt_extra(Context *c, TransScope *scope, const clang::Stmt *st...@@ -3491,8 +3575,8 @@ static int trans_stmt_extra(Context *c, TransScope *scope, const clang::Stmt *st
3491 emit_warning(c, stmt->getLocStart(), "TODO handle C SizeOfPackExprClass");3575 emit_warning(c, stmt->getLocStart(), "TODO handle C SizeOfPackExprClass");
3492 return ErrorUnexpected;3576 return ErrorUnexpected;
3493 case clang::Stmt::StmtExprClass:3577 case clang::Stmt::StmtExprClass:
3494 emit_warning(c, stmt->getLocStart(), "TODO handle C StmtExprClass");3578 return wrap_stmt(out_node, out_child_scope, scope,
3495 return ErrorUnexpected;3579 trans_stmt_expr(c, result_used, scope, (const clang::StmtExpr *)stmt, out_node_scope));
3496 case clang::Stmt::SubstNonTypeTemplateParmExprClass:3580 case clang::Stmt::SubstNonTypeTemplateParmExprClass:
3497 emit_warning(c, stmt->getLocStart(), "TODO handle C SubstNonTypeTemplateParmExprClass");3581 emit_warning(c, stmt->getLocStart(), "TODO handle C SubstNonTypeTemplateParmExprClass");
3498 return ErrorUnexpected;3582 return ErrorUnexpected;
test/translate_c.zig+113-33
...@@ -59,6 +59,40 @@ pub fn addCases(cases: *tests.TranslateCContext) void {...@@ -59,6 +59,40 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
59 );59 );
60 }60 }
6161
62 cases.add("predefined expressions",
63 \\void foo(void) {
64 \\ __func__;
65 \\ __FUNCTION__;
66 \\ __PRETTY_FUNCTION__;
67 \\}
68 ,
69 \\pub fn foo() void {
70 \\ _ = c"foo";
71 \\ _ = c"foo";
72 \\ _ = c"void foo(void)";
73 \\}
74 );
75
76 cases.add("ignore result",
77 \\void foo() {
78 \\ int a;
79 \\ 1;
80 \\ "hey";
81 \\ 1 + 1;
82 \\ 1 - 1;
83 \\ a = 1;
84 \\}
85 ,
86 \\pub fn foo() void {
87 \\ var a: c_int = undefined;
88 \\ _ = 1;
89 \\ _ = c"hey";
90 \\ _ = (1 + 1);
91 \\ _ = (1 - 1);
92 \\ a = 1;
93 \\}
94 );
95
62 cases.add("for loop with var init but empty body",96 cases.add("for loop with var init but empty body",
63 \\void foo(void) {97 \\void foo(void) {
64 \\ for (int x = 0; x < 10; x++);98 \\ for (int x = 0; x < 10; x++);
...@@ -79,6 +113,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {...@@ -79,6 +113,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
79 , // TODO this should be if (1 != 0) break113 , // TODO this should be if (1 != 0) break
80 \\pub fn foo() void {114 \\pub fn foo() void {
81 \\ while (true) {115 \\ while (true) {
116 \\ {}
82 \\ if (!1) break;117 \\ if (!1) break;
83 \\ }118 \\ }
84 \\}119 \\}
...@@ -511,11 +546,14 @@ pub fn addCases(cases: *tests.TranslateCContext) void {...@@ -511,11 +546,14 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
511 \\ return b;546 \\ return b;
512 \\ else547 \\ else
513 \\ return a;548 \\ return a;
549 \\
550 \\ if (a < b) ; else ;
514 \\}551 \\}
515 ,552 ,
516 \\pub export fn max(a: c_int, b: c_int) c_int {553 \\pub export fn max(a: c_int, b: c_int) c_int {
517 \\ if (a < b) return b;554 \\ if (a < b) return b;
518 \\ if (a < b) return b else return a;555 \\ if (a < b) return b else return a;
556 \\ if (a < b) {} else {}
519 \\}557 \\}
520 );558 );
521559
...@@ -720,7 +758,13 @@ pub fn addCases(cases: *tests.TranslateCContext) void {...@@ -720,7 +758,13 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
720 \\ ;;;;;758 \\ ;;;;;
721 \\}759 \\}
722 ,760 ,
723 \\pub export fn foo() void {}761 \\pub export fn foo() void {
762 \\ {}
763 \\ {}
764 \\ {}
765 \\ {}
766 \\ {}
767 \\}
724 );768 );
725769
726 cases.add("undefined array global",770 cases.add("undefined array global",
...@@ -751,6 +795,16 @@ pub fn addCases(cases: *tests.TranslateCContext) void {...@@ -751,6 +795,16 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
751 \\}795 \\}
752 );796 );
753797
798 cases.addC("void cast",
799 \\void foo(int a) {
800 \\ (void) a;
801 \\}
802 ,
803 \\pub export fn foo(a: c_int) void {
804 \\ _ = a;
805 \\}
806 );
807
754 cases.addC("implicit cast to void *",808 cases.addC("implicit cast to void *",
755 \\void *foo(unsigned short *x) {809 \\void *foo(unsigned short *x) {
756 \\ return x;810 \\ return x;
...@@ -795,6 +849,32 @@ pub fn addCases(cases: *tests.TranslateCContext) void {...@@ -795,6 +849,32 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
795 \\}849 \\}
796 );850 );
797851
852 cases.addC("statement expression",
853 \\int foo(void) {
854 \\ return ({
855 \\ int a = 1;
856 \\ a;
857 \\ });
858 \\}
859 ,
860 \\pub export fn foo() c_int {
861 \\ return x: {
862 \\ var a: c_int = 1;
863 \\ break :x a;
864 \\ };
865 \\}
866 );
867
868 cases.addC("__extension__ cast",
869 \\int foo(void) {
870 \\ return __extension__ 1;
871 \\}
872 ,
873 \\pub export fn foo() c_int {
874 \\ return 1;
875 \\}
876 );
877
798 cases.addC("bitshift",878 cases.addC("bitshift",
799 \\int foo(void) {879 \\int foo(void) {
800 \\ return (1 << 2) >> 1;880 \\ return (1 << 2) >> 1;
...@@ -1425,52 +1505,52 @@ pub fn addCases(cases: *tests.TranslateCContext) void {...@@ -1425,52 +1505,52 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
1425 \\pub export fn bar() void {}1505 \\pub export fn bar() void {}
1426 );1506 );
14271507
1428 cases.addC("u integer suffix after 0 (zero) in macro definition",1508 cases.addC(
1429 "#define ZERO 0U"1509 "u integer suffix after 0 (zero) in macro definition",
1430 ,1510 "#define ZERO 0U",
1431 "pub const ZERO = c_uint(0);"1511 "pub const ZERO = c_uint(0);",
1432 );1512 );
14331513
1434 cases.addC("l integer suffix after 0 (zero) in macro definition",1514 cases.addC(
1435 "#define ZERO 0L"1515 "l integer suffix after 0 (zero) in macro definition",
1436 ,1516 "#define ZERO 0L",
1437 "pub const ZERO = c_long(0);"1517 "pub const ZERO = c_long(0);",
1438 );1518 );
14391519
1440 cases.addC("ul integer suffix after 0 (zero) in macro definition",1520 cases.addC(
1441 "#define ZERO 0UL"1521 "ul integer suffix after 0 (zero) in macro definition",
1442 ,1522 "#define ZERO 0UL",
1443 "pub const ZERO = c_ulong(0);"1523 "pub const ZERO = c_ulong(0);",
1444 );1524 );
14451525
1446 cases.addC("lu integer suffix after 0 (zero) in macro definition",1526 cases.addC(
1447 "#define ZERO 0LU"1527 "lu integer suffix after 0 (zero) in macro definition",
1448 ,1528 "#define ZERO 0LU",
1449 "pub const ZERO = c_ulong(0);"1529 "pub const ZERO = c_ulong(0);",
1450 );1530 );
14511531
1452 cases.addC("ll integer suffix after 0 (zero) in macro definition",1532 cases.addC(
1453 "#define ZERO 0LL"1533 "ll integer suffix after 0 (zero) in macro definition",
1454 ,1534 "#define ZERO 0LL",
1455 "pub const ZERO = c_longlong(0);"1535 "pub const ZERO = c_longlong(0);",
1456 );1536 );
14571537
1458 cases.addC("ull integer suffix after 0 (zero) in macro definition",1538 cases.addC(
1459 "#define ZERO 0ULL"1539 "ull integer suffix after 0 (zero) in macro definition",
1460 ,1540 "#define ZERO 0ULL",
1461 "pub const ZERO = c_ulonglong(0);"1541 "pub const ZERO = c_ulonglong(0);",
1462 );1542 );
14631543
1464 cases.addC("llu integer suffix after 0 (zero) in macro definition",1544 cases.addC(
1465 "#define ZERO 0LLU"1545 "llu integer suffix after 0 (zero) in macro definition",
1466 ,1546 "#define ZERO 0LLU",
1467 "pub const ZERO = c_ulonglong(0);"1547 "pub const ZERO = c_ulonglong(0);",
1468 );1548 );
14691549
1470 cases.addC("bitwise not on u-suffixed 0 (zero) in macro definition",1550 cases.addC(
1471 "#define NOT_ZERO (~0U)"1551 "bitwise not on u-suffixed 0 (zero) in macro definition",
1472 ,1552 "#define NOT_ZERO (~0U)",
1473 "pub const NOT_ZERO = ~c_uint(0);"1553 "pub const NOT_ZERO = ~c_uint(0);",
1474 );1554 );
14751555
1476 // cases.add("empty array with initializer",1556 // cases.add("empty array with initializer",