| ... | ... | @@ -522,7 +522,18 @@ static AstNode *trans_create_node_apint(Context *c, const ZigClangAPSInt *aps_in |
| 522 | 522 | ZigClangAPSInt_getNumWords(negated), true); |
| 523 | 523 | ZigClangAPSInt_free(negated); |
| 524 | 524 | return node; |
| 525 | } |
| 525 | 526 | |
| 527 | static AstNode *trans_create_node_apfloat(Context *c, const llvm::APFloat &ap_float) { |
| 528 | uint8_t buf[128]; |
| 529 | size_t written = ap_float.convertToHexString((char *)buf, 0, false, |
| 530 | llvm::APFloat::rmNearestTiesToEven); |
| 531 | AstNode *node = trans_create_node(c, NodeTypeFloatLiteral); |
| 532 | node->data.float_literal.bigfloat = allocate<BigFloat>(1); |
| 533 | if (bigfloat_init_buf(node->data.float_literal.bigfloat, buf, written)) { |
| 534 | node->data.float_literal.overflow = true; |
| 535 | } |
| 536 | return node; |
| 526 | 537 | } |
| 527 | 538 | |
| 528 | 539 | static const ZigClangType *qual_type_canon(ZigClangQualType qt) { |
| ... | ... | @@ -1313,6 +1324,46 @@ static AstNode *trans_integer_literal(Context *c, ResultUsed result_used, const |
| 1313 | 1324 | return maybe_suppress_result(c, result_used, node); |
| 1314 | 1325 | } |
| 1315 | 1326 | |
| 1327 | static AstNode *trans_floating_literal(Context *c, ResultUsed result_used, const clang::FloatingLiteral *stmt) { |
| 1328 | llvm::APFloat result{0.0f}; |
| 1329 | if (!stmt->EvaluateAsFloat(result, *reinterpret_cast<clang::ASTContext *>(c->ctx))) { |
| 1330 | emit_warning(c, bitcast(stmt->getBeginLoc()), "invalid floating literal"); |
| 1331 | return nullptr; |
| 1332 | } |
| 1333 | AstNode *node = trans_create_node_apfloat(c, result); |
| 1334 | return maybe_suppress_result(c, result_used, node); |
| 1335 | } |
| 1336 | |
| 1337 | static AstNode *trans_character_literal(Context *c, ResultUsed result_used, const clang::CharacterLiteral *stmt) { |
| 1338 | switch (stmt->getKind()) { |
| 1339 | case clang::CharacterLiteral::CharacterKind::Ascii: |
| 1340 | { |
| 1341 | unsigned val = stmt->getValue(); |
| 1342 | // C has a somewhat obscure feature called multi-character character |
| 1343 | // constant |
| 1344 | if (val > 255) |
| 1345 | return trans_create_node_unsigned(c, val); |
| 1346 | } |
| 1347 | // fallthrough |
| 1348 | case clang::CharacterLiteral::CharacterKind::UTF8: |
| 1349 | { |
| 1350 | AstNode *node = trans_create_node(c, NodeTypeCharLiteral); |
| 1351 | node->data.char_literal.value = stmt->getValue(); |
| 1352 | return maybe_suppress_result(c, result_used, node); |
| 1353 | } |
| 1354 | case clang::CharacterLiteral::CharacterKind::UTF16: |
| 1355 | emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO support UTF16 character literals"); |
| 1356 | return nullptr; |
| 1357 | case clang::CharacterLiteral::CharacterKind::UTF32: |
| 1358 | emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO support UTF32 character literals"); |
| 1359 | return nullptr; |
| 1360 | case clang::CharacterLiteral::CharacterKind::Wide: |
| 1361 | emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO support wide character literals"); |
| 1362 | return nullptr; |
| 1363 | } |
| 1364 | zig_unreachable(); |
| 1365 | } |
| 1366 | |
| 1316 | 1367 | static AstNode *trans_constant_expr(Context *c, ResultUsed result_used, const clang::ConstantExpr *expr) { |
| 1317 | 1368 | clang::Expr::EvalResult result; |
| 1318 | 1369 | if (!expr->EvaluateAsConstantExpr(result, clang::Expr::EvaluateForCodeGen, |
| ... | ... | @@ -1896,15 +1947,21 @@ static AstNode *trans_implicit_cast_expr(Context *c, ResultUsed result_used, Tra |
| 1896 | 1947 | case ZigClangCK_ConstructorConversion: |
| 1897 | 1948 | emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CK_ConstructorConversion"); |
| 1898 | 1949 | return nullptr; |
| 1899 | | case ZigClangCK_IntegralToPointer: |
| 1900 | | emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CK_IntegralToPointer"); |
| 1901 | | return nullptr; |
| 1902 | | case ZigClangCK_PointerToIntegral: |
| 1903 | | emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CK_PointerToIntegral"); |
| 1904 | | return nullptr; |
| 1905 | 1950 | case ZigClangCK_PointerToBoolean: |
| 1906 | | emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CK_PointerToBoolean"); |
| 1907 | | return nullptr; |
| 1951 | { |
| 1952 | const clang::Expr *expr = stmt->getSubExpr(); |
| 1953 | AstNode *val = trans_expr(c, ResultUsedYes, scope, bitcast(expr), TransRValue); |
| 1954 | if (val == nullptr) |
| 1955 | return nullptr; |
| 1956 | |
| 1957 | AstNode *val_ptr = trans_create_node_builtin_fn_call_str(c, "ptrToInt"); |
| 1958 | val_ptr->data.fn_call_expr.params.append(val); |
| 1959 | |
| 1960 | AstNode *zero = trans_create_node_unsigned(c, 0); |
| 1961 | |
| 1962 | // Translate as @ptrToInt((&val) != 0) |
| 1963 | return trans_create_node_bin_op(c, val_ptr, BinOpTypeCmpNotEq, zero); |
| 1964 | } |
| 1908 | 1965 | case ZigClangCK_ToVoid: |
| 1909 | 1966 | emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CK_ToVoid"); |
| 1910 | 1967 | return nullptr; |
| ... | ... | @@ -1912,20 +1969,83 @@ static AstNode *trans_implicit_cast_expr(Context *c, ResultUsed result_used, Tra |
| 1912 | 1969 | emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CK_VectorSplat"); |
| 1913 | 1970 | return nullptr; |
| 1914 | 1971 | case ZigClangCK_IntegralToBoolean: |
| 1915 | | emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CK_IntegralToBoolean"); |
| 1916 | | return nullptr; |
| 1972 | { |
| 1973 | const clang::Expr *expr = stmt->getSubExpr(); |
| 1974 | |
| 1975 | bool expr_val; |
| 1976 | if (expr->EvaluateAsBooleanCondition(expr_val, *reinterpret_cast<clang::ASTContext *>(c->ctx))) { |
| 1977 | return trans_create_node_bool(c, expr_val); |
| 1978 | } |
| 1979 | |
| 1980 | AstNode *val = trans_expr(c, ResultUsedYes, scope, bitcast(expr), TransRValue); |
| 1981 | if (val == nullptr) |
| 1982 | return nullptr; |
| 1983 | |
| 1984 | AstNode *zero = trans_create_node_unsigned(c, 0); |
| 1985 | |
| 1986 | // Translate as val != 0 |
| 1987 | return trans_create_node_bin_op(c, val, BinOpTypeCmpNotEq, zero); |
| 1988 | } |
| 1989 | case ZigClangCK_PointerToIntegral: |
| 1990 | { |
| 1991 | AstNode *target_node = trans_expr(c, ResultUsedYes, scope, bitcast(stmt->getSubExpr()), TransRValue); |
| 1992 | if (target_node == nullptr) |
| 1993 | return nullptr; |
| 1994 | |
| 1995 | AstNode *dest_type_node = get_expr_type(c, (const ZigClangExpr *)stmt); |
| 1996 | if (dest_type_node == nullptr) |
| 1997 | return nullptr; |
| 1998 | |
| 1999 | AstNode *val_node = trans_create_node_builtin_fn_call_str(c, "ptrToInt"); |
| 2000 | val_node->data.fn_call_expr.params.append(target_node); |
| 2001 | // @ptrToInt always returns a usize |
| 2002 | AstNode *node = trans_create_node_builtin_fn_call_str(c, "intCast"); |
| 2003 | node->data.fn_call_expr.params.append(dest_type_node); |
| 2004 | node->data.fn_call_expr.params.append(val_node); |
| 2005 | |
| 2006 | return maybe_suppress_result(c, result_used, node); |
| 2007 | } |
| 2008 | case ZigClangCK_IntegralToPointer: |
| 2009 | { |
| 2010 | AstNode *target_node = trans_expr(c, ResultUsedYes, scope, bitcast(stmt->getSubExpr()), TransRValue); |
| 2011 | if (target_node == nullptr) |
| 2012 | return nullptr; |
| 2013 | |
| 2014 | AstNode *dest_type_node = get_expr_type(c, (const ZigClangExpr *)stmt); |
| 2015 | if (dest_type_node == nullptr) |
| 2016 | return nullptr; |
| 2017 | |
| 2018 | AstNode *node = trans_create_node_builtin_fn_call_str(c, "intToPtr"); |
| 2019 | node->data.fn_call_expr.params.append(dest_type_node); |
| 2020 | node->data.fn_call_expr.params.append(target_node); |
| 2021 | |
| 2022 | return maybe_suppress_result(c, result_used, node); |
| 2023 | } |
| 1917 | 2024 | case ZigClangCK_IntegralToFloating: |
| 1918 | | emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CK_IntegralToFloating"); |
| 1919 | | return nullptr; |
| 2025 | case ZigClangCK_FloatingToIntegral: |
| 2026 | { |
| 2027 | AstNode *target_node = trans_expr(c, ResultUsedYes, scope, bitcast(stmt->getSubExpr()), TransRValue); |
| 2028 | if (target_node == nullptr) |
| 2029 | return nullptr; |
| 2030 | |
| 2031 | AstNode *dest_type_node = get_expr_type(c, (const ZigClangExpr *)stmt); |
| 2032 | if (dest_type_node == nullptr) |
| 2033 | return nullptr; |
| 2034 | |
| 2035 | char const *fn = (ZigClangCK)stmt->getCastKind() == ZigClangCK_IntegralToFloating ? |
| 2036 | "intToFloat" : "floatToInt"; |
| 2037 | AstNode *node = trans_create_node_builtin_fn_call_str(c, fn); |
| 2038 | node->data.fn_call_expr.params.append(dest_type_node); |
| 2039 | node->data.fn_call_expr.params.append(target_node); |
| 2040 | |
| 2041 | return maybe_suppress_result(c, result_used, node); |
| 2042 | } |
| 1920 | 2043 | case ZigClangCK_FixedPointCast: |
| 1921 | 2044 | emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CK_FixedPointCast"); |
| 1922 | 2045 | return nullptr; |
| 1923 | 2046 | case ZigClangCK_FixedPointToBoolean: |
| 1924 | 2047 | emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CK_FixedPointToBoolean"); |
| 1925 | 2048 | return nullptr; |
| 1926 | | case ZigClangCK_FloatingToIntegral: |
| 1927 | | emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CK_FloatingToIntegral"); |
| 1928 | | return nullptr; |
| 1929 | 2049 | case ZigClangCK_FloatingToBoolean: |
| 1930 | 2050 | emit_warning(c, bitcast(stmt->getBeginLoc()), "TODO handle C CK_FloatingToBoolean"); |
| 1931 | 2051 | return nullptr; |
| ... | ... | @@ -3498,7 +3618,8 @@ static int trans_stmt_extra(Context *c, TransScope *scope, const ZigClangStmt *s |
| 3498 | 3618 | emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C ObjCBridgedCastExprClass"); |
| 3499 | 3619 | return ErrorUnexpected; |
| 3500 | 3620 | case ZigClangStmt_CharacterLiteralClass: |
| 3501 | | emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C CharacterLiteralClass"); |
| 3621 | return wrap_stmt(out_node, out_child_scope, scope, |
| 3622 | trans_character_literal(c, result_used, (const clang::CharacterLiteral *)stmt)); |
| 3502 | 3623 | return ErrorUnexpected; |
| 3503 | 3624 | case ZigClangStmt_ChooseExprClass: |
| 3504 | 3625 | emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C ChooseExprClass"); |
| ... | ... | @@ -3537,8 +3658,8 @@ static int trans_stmt_extra(Context *c, TransScope *scope, const ZigClangStmt *s |
| 3537 | 3658 | emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C FixedPointLiteralClass"); |
| 3538 | 3659 | return ErrorUnexpected; |
| 3539 | 3660 | case ZigClangStmt_FloatingLiteralClass: |
| 3540 | | emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C FloatingLiteralClass"); |
| 3541 | | return ErrorUnexpected; |
| 3661 | return wrap_stmt(out_node, out_child_scope, scope, |
| 3662 | trans_floating_literal(c, result_used, (const clang::FloatingLiteral *)stmt)); |
| 3542 | 3663 | case ZigClangStmt_ExprWithCleanupsClass: |
| 3543 | 3664 | emit_warning(c, ZigClangStmt_getBeginLoc(stmt), "TODO handle C ExprWithCleanupsClass"); |
| 3544 | 3665 | return ErrorUnexpected; |