@@ -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,36 +1947,105 @@ 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 ;
1911
1968
case ZigClangCK_VectorSplat:
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;
0 commit comments