| ... | ... | @@ -119,7 +119,7 @@ static int trans_stmt_extra(Context *c, TransScope *scope, const Stmt *stmt, |
| 119 | 119 | static TransScope *trans_stmt(Context *c, TransScope *scope, const Stmt *stmt, AstNode **out_node); |
| 120 | 120 | static AstNode *trans_expr(Context *c, ResultUsed result_used, TransScope *scope, const Expr *expr, TransLRValue lrval); |
| 121 | 121 | static AstNode *trans_qual_type(Context *c, QualType qt, const SourceLocation &source_loc); |
| 122 | | static AstNode *trans_to_bool_expr(Context *c, TransScope *scope, AstNode *expr); |
| 122 | static AstNode *trans_bool_expr(Context *c, ResultUsed result_used, TransScope *scope, const Expr *expr, TransLRValue lrval); |
| 123 | 123 | |
| 124 | 124 | ATTRIBUTE_PRINTF(3, 4) |
| 125 | 125 | static void emit_warning(Context *c, const SourceLocation &sl, const char *format, ...) { |
| ... | ... | @@ -467,6 +467,14 @@ static QualType get_expr_qual_type(Context *c, const Expr *expr) { |
| 467 | 467 | return expr->getType(); |
| 468 | 468 | } |
| 469 | 469 | |
| 470 | static QualType get_expr_qual_type_before_implicit_cast(Context *c, const Expr *expr) { |
| 471 | if (expr->getStmtClass() == Stmt::ImplicitCastExprClass) { |
| 472 | const ImplicitCastExpr *cast_expr = static_cast<const ImplicitCastExpr *>(expr); |
| 473 | return get_expr_qual_type(c, cast_expr->getSubExpr()); |
| 474 | } |
| 475 | return expr->getType(); |
| 476 | } |
| 477 | |
| 470 | 478 | static AstNode *get_expr_type(Context *c, const Expr *expr) { |
| 471 | 479 | return trans_qual_type(c, get_expr_qual_type(c, expr), expr->getLocStart()); |
| 472 | 480 | } |
| ... | ... | @@ -1152,6 +1160,22 @@ static AstNode *trans_create_bin_op(Context *c, TransScope *scope, Expr *lhs, Bi |
| 1152 | 1160 | return node; |
| 1153 | 1161 | } |
| 1154 | 1162 | |
| 1163 | static AstNode *trans_create_bool_bin_op(Context *c, TransScope *scope, Expr *lhs, BinOpType bin_op, Expr *rhs) { |
| 1164 | assert(bin_op == BinOpTypeBoolAnd || bin_op == BinOpTypeBoolOr); |
| 1165 | AstNode *node = trans_create_node(c, NodeTypeBinOpExpr); |
| 1166 | node->data.bin_op_expr.bin_op = bin_op; |
| 1167 | |
| 1168 | node->data.bin_op_expr.op1 = trans_bool_expr(c, ResultUsedYes, scope, lhs, TransRValue); |
| 1169 | if (node->data.bin_op_expr.op1 == nullptr) |
| 1170 | return nullptr; |
| 1171 | |
| 1172 | node->data.bin_op_expr.op2 = trans_bool_expr(c, ResultUsedYes, scope, rhs, TransRValue); |
| 1173 | if (node->data.bin_op_expr.op2 == nullptr) |
| 1174 | return nullptr; |
| 1175 | |
| 1176 | return node; |
| 1177 | } |
| 1178 | |
| 1155 | 1179 | static AstNode *trans_create_assign(Context *c, ResultUsed result_used, TransScope *scope, Expr *lhs, Expr *rhs) { |
| 1156 | 1180 | if (result_used == ResultUsedNo) { |
| 1157 | 1181 | // common case |
| ... | ... | @@ -1293,10 +1317,9 @@ static AstNode *trans_binary_operator(Context *c, ResultUsed result_used, TransS |
| 1293 | 1317 | case BO_Or: |
| 1294 | 1318 | return trans_create_bin_op(c, scope, stmt->getLHS(), BinOpTypeBinOr, stmt->getRHS()); |
| 1295 | 1319 | case BO_LAnd: |
| 1296 | | return trans_create_bin_op(c, scope, stmt->getLHS(), BinOpTypeBoolAnd, stmt->getRHS()); |
| 1320 | return trans_create_bool_bin_op(c, scope, stmt->getLHS(), BinOpTypeBoolAnd, stmt->getRHS()); |
| 1297 | 1321 | case BO_LOr: |
| 1298 | | // TODO: int vs bool |
| 1299 | | return trans_create_bin_op(c, scope, stmt->getLHS(), BinOpTypeBoolOr, stmt->getRHS()); |
| 1322 | return trans_create_bool_bin_op(c, scope, stmt->getLHS(), BinOpTypeBoolOr, stmt->getRHS()); |
| 1300 | 1323 | case BO_Assign: |
| 1301 | 1324 | return trans_create_assign(c, result_used, scope, stmt->getLHS(), stmt->getRHS()); |
| 1302 | 1325 | case BO_Comma: |
| ... | ... | @@ -1924,7 +1947,6 @@ static AstNode *trans_unary_operator(Context *c, ResultUsed result_used, TransSc |
| 1924 | 1947 | return nullptr; |
| 1925 | 1948 | } |
| 1926 | 1949 | } |
| 1927 | | case UO_LNot: |
| 1928 | 1950 | case UO_Not: |
| 1929 | 1951 | { |
| 1930 | 1952 | Expr *op_expr = stmt->getSubExpr(); |
| ... | ... | @@ -1932,14 +1954,16 @@ static AstNode *trans_unary_operator(Context *c, ResultUsed result_used, TransSc |
| 1932 | 1954 | if (sub_node == nullptr) |
| 1933 | 1955 | return nullptr; |
| 1934 | 1956 | |
| 1935 | | switch (stmt->getOpcode()) { |
| 1936 | | case UO_LNot: |
| 1937 | | return trans_create_node_prefix_op(c, PrefixOpBoolNot, trans_to_bool_expr(c, scope, sub_node)); |
| 1938 | | case UO_Not: |
| 1939 | | return trans_create_node_prefix_op(c, PrefixOpBinNot, sub_node); |
| 1940 | | default: |
| 1941 | | zig_unreachable(); |
| 1942 | | } |
| 1957 | return trans_create_node_prefix_op(c, PrefixOpBinNot, sub_node); |
| 1958 | } |
| 1959 | case UO_LNot: |
| 1960 | { |
| 1961 | Expr *op_expr = stmt->getSubExpr(); |
| 1962 | AstNode *sub_node = trans_bool_expr(c, ResultUsedYes, scope, op_expr, TransRValue); |
| 1963 | if (sub_node == nullptr) |
| 1964 | return nullptr; |
| 1965 | |
| 1966 | return trans_create_node_prefix_op(c, PrefixOpBoolNot, sub_node); |
| 1943 | 1967 | } |
| 1944 | 1968 | case UO_Real: |
| 1945 | 1969 | emit_warning(c, stmt->getLocStart(), "TODO handle C translation UO_Real"); |
| ... | ... | @@ -2220,10 +2244,30 @@ static int trans_local_declaration(Context *c, TransScope *scope, const DeclStmt |
| 2220 | 2244 | return ErrorNone; |
| 2221 | 2245 | } |
| 2222 | 2246 | |
| 2223 | | static AstNode *trans_to_bool_expr(Context *c, TransScope *scope, AstNode *expr) { |
| 2224 | | switch (expr->type) { |
| 2247 | static AstNode *to_enum_zero_cmp(Context *c, AstNode *expr, AstNode *enum_type) { |
| 2248 | AstNode *tag_type = trans_create_node_builtin_fn_call_str(c, "TagType"); |
| 2249 | tag_type->data.fn_call_expr.params.append(enum_type); |
| 2250 | |
| 2251 | // @TagType(Enum)(0) |
| 2252 | AstNode *zero = trans_create_node_unsigned_negative(c, 0, false); |
| 2253 | AstNode *casted_zero = trans_create_node_fn_call_1(c, tag_type, zero); |
| 2254 | |
| 2255 | // @bitCast(Enum, @TagType(Enum)(0)) |
| 2256 | AstNode *bitcast = trans_create_node_builtin_fn_call_str(c, "bitCast"); |
| 2257 | bitcast->data.fn_call_expr.params.append(enum_type); |
| 2258 | bitcast->data.fn_call_expr.params.append(casted_zero); |
| 2259 | |
| 2260 | return trans_create_node_bin_op(c, expr, BinOpTypeCmpNotEq, bitcast); |
| 2261 | } |
| 2262 | |
| 2263 | static AstNode *trans_bool_expr(Context *c, ResultUsed result_used, TransScope *scope, const Expr *expr, TransLRValue lrval) { |
| 2264 | AstNode *res = trans_expr(c, result_used, scope, expr, lrval); |
| 2265 | if (res == nullptr) |
| 2266 | return nullptr; |
| 2267 | |
| 2268 | switch (res->type) { |
| 2225 | 2269 | case NodeTypeBinOpExpr: |
| 2226 | | switch (expr->data.bin_op_expr.bin_op) { |
| 2270 | switch (res->data.bin_op_expr.bin_op) { |
| 2227 | 2271 | case BinOpTypeBoolOr: |
| 2228 | 2272 | case BinOpTypeBoolAnd: |
| 2229 | 2273 | case BinOpTypeCmpEq: |
| ... | ... | @@ -2232,76 +2276,208 @@ static AstNode *trans_to_bool_expr(Context *c, TransScope *scope, AstNode *expr) |
| 2232 | 2276 | case BinOpTypeCmpGreaterThan: |
| 2233 | 2277 | case BinOpTypeCmpLessOrEq: |
| 2234 | 2278 | case BinOpTypeCmpGreaterOrEq: |
| 2235 | | return expr; |
| 2279 | return res; |
| 2236 | 2280 | default: |
| 2237 | | goto convert_to_bitcast; |
| 2281 | break; |
| 2238 | 2282 | } |
| 2239 | 2283 | |
| 2240 | 2284 | case NodeTypePrefixOpExpr: |
| 2241 | | switch (expr->data.prefix_op_expr.prefix_op) { |
| 2285 | switch (res->data.prefix_op_expr.prefix_op) { |
| 2242 | 2286 | case PrefixOpBoolNot: |
| 2243 | | return expr; |
| 2287 | return res; |
| 2244 | 2288 | default: |
| 2245 | | goto convert_to_bitcast; |
| 2289 | break; |
| 2246 | 2290 | } |
| 2247 | 2291 | |
| 2248 | 2292 | case NodeTypeBoolLiteral: |
| 2249 | | return expr; |
| 2250 | | |
| 2251 | | default: { |
| 2252 | | // In Zig, float, int and pointer does not implicitly cast to bool. |
| 2253 | | // To make it work, we bitcast any value we get to an int of the right size |
| 2254 | | // and comp it to 0 |
| 2255 | | // TODO: This doesn't work for pointers, as they become nullable on |
| 2256 | | // translate |
| 2257 | | // c: expr |
| 2258 | | // zig: __to_bool_expr: { |
| 2259 | | // zig: const _tmp = cond; |
| 2260 | | // zig: break :__to_bool_expr @bitCast(@IntType(false, @sizeOf(@typeOf(_tmp)) * 8), _tmp) != 0; |
| 2261 | | // zig: } |
| 2262 | | convert_to_bitcast: |
| 2263 | | TransScopeBlock *child_scope = trans_scope_block_create(c, scope); |
| 2264 | | Buf *label_name = buf_create_from_str("__to_bool_expr"); |
| 2265 | | child_scope->node->data.block.name = label_name; |
| 2266 | | |
| 2267 | | // const _tmp = cond; |
| 2268 | | // TODO: avoid name collisions with generated variable names |
| 2269 | | Buf *tmp_var_name = buf_create_from_str("_tmp"); |
| 2270 | | AstNode *tmp_var_decl = trans_create_node_var_decl_local(c, true, tmp_var_name, nullptr, expr); |
| 2271 | | child_scope->node->data.block.statements.append(tmp_var_decl); |
| 2272 | | |
| 2273 | | // @sizeOf(@typeOf(_tmp)) * 8 |
| 2274 | | AstNode *typeof_tmp = trans_create_node_builtin_fn_call_str(c, "typeOf"); |
| 2275 | | typeof_tmp->data.fn_call_expr.params.append(trans_create_node_symbol(c, tmp_var_name)); |
| 2276 | | AstNode *sizeof_tmp = trans_create_node_builtin_fn_call_str(c, "sizeOf"); |
| 2277 | | sizeof_tmp->data.fn_call_expr.params.append(typeof_tmp); |
| 2278 | | AstNode *sizeof_tmp_in_bits = trans_create_node_bin_op( |
| 2279 | | c, sizeof_tmp, BinOpTypeMult, |
| 2280 | | trans_create_node_unsigned_negative(c, 8, false)); |
| 2281 | | |
| 2282 | | // @IntType(false, @sizeOf(@typeOf(_tmp)) * 8) |
| 2283 | | AstNode *int_type = trans_create_node_builtin_fn_call_str(c, "IntType"); |
| 2284 | | int_type->data.fn_call_expr.params.append(trans_create_node_bool(c, false)); |
| 2285 | | int_type->data.fn_call_expr.params.append(sizeof_tmp_in_bits); |
| 2286 | | |
| 2287 | | // @bitCast(@IntType(false, @sizeOf(@typeOf(_tmp)) * 8), _tmp) |
| 2288 | | AstNode *bit_cast = trans_create_node_builtin_fn_call_str(c, "bitCast"); |
| 2289 | | bit_cast->data.fn_call_expr.params.append(int_type); |
| 2290 | | bit_cast->data.fn_call_expr.params.append(trans_create_node_symbol(c, tmp_var_name)); |
| 2291 | | |
| 2292 | | // break :__to_bool_expr @bitCast(@IntType(false, @sizeOf(@typeOf(_tmp)) * 8), _tmp) != 0 |
| 2293 | | AstNode *not_eql_zero = trans_create_node_bin_op(c, bit_cast, BinOpTypeCmpNotEq, trans_create_node_unsigned_negative(c, 0, false)); |
| 2294 | | child_scope->node->data.block.statements.append(trans_create_node_break(c, label_name, not_eql_zero)); |
| 2295 | | |
| 2296 | | return child_scope->node; |
| 2293 | return res; |
| 2294 | |
| 2295 | default: |
| 2296 | break; |
| 2297 | } |
| 2298 | |
| 2299 | |
| 2300 | const Type *ty = get_expr_qual_type_before_implicit_cast(c, expr).getTypePtr(); |
| 2301 | auto classs = ty->getTypeClass(); |
| 2302 | switch (classs) { |
| 2303 | case Type::Builtin: |
| 2304 | { |
| 2305 | const BuiltinType *builtin_ty = static_cast<const BuiltinType*>(ty); |
| 2306 | switch (builtin_ty->getKind()) { |
| 2307 | case BuiltinType::Bool: |
| 2308 | case BuiltinType::Char_U: |
| 2309 | case BuiltinType::UChar: |
| 2310 | case BuiltinType::Char_S: |
| 2311 | case BuiltinType::SChar: |
| 2312 | case BuiltinType::UShort: |
| 2313 | case BuiltinType::UInt: |
| 2314 | case BuiltinType::ULong: |
| 2315 | case BuiltinType::ULongLong: |
| 2316 | case BuiltinType::Short: |
| 2317 | case BuiltinType::Int: |
| 2318 | case BuiltinType::Long: |
| 2319 | case BuiltinType::LongLong: |
| 2320 | case BuiltinType::UInt128: |
| 2321 | case BuiltinType::Int128: |
| 2322 | case BuiltinType::Float: |
| 2323 | case BuiltinType::Double: |
| 2324 | case BuiltinType::Float128: |
| 2325 | case BuiltinType::LongDouble: |
| 2326 | case BuiltinType::WChar_U: |
| 2327 | case BuiltinType::Char16: |
| 2328 | case BuiltinType::Char32: |
| 2329 | case BuiltinType::WChar_S: |
| 2330 | return trans_create_node_bin_op(c, res, BinOpTypeCmpNotEq, trans_create_node_unsigned_negative(c, 0, false)); |
| 2331 | case BuiltinType::NullPtr: |
| 2332 | return trans_create_node_bin_op(c, res, BinOpTypeCmpNotEq, trans_create_node(c, NodeTypeNullLiteral)); |
| 2333 | |
| 2334 | case BuiltinType::Void: |
| 2335 | case BuiltinType::Half: |
| 2336 | case BuiltinType::ObjCId: |
| 2337 | case BuiltinType::ObjCClass: |
| 2338 | case BuiltinType::ObjCSel: |
| 2339 | case BuiltinType::OMPArraySection: |
| 2340 | case BuiltinType::Dependent: |
| 2341 | case BuiltinType::Overload: |
| 2342 | case BuiltinType::BoundMember: |
| 2343 | case BuiltinType::PseudoObject: |
| 2344 | case BuiltinType::UnknownAny: |
| 2345 | case BuiltinType::BuiltinFn: |
| 2346 | case BuiltinType::ARCUnbridgedCast: |
| 2347 | case BuiltinType::OCLImage1dRO: |
| 2348 | case BuiltinType::OCLImage1dArrayRO: |
| 2349 | case BuiltinType::OCLImage1dBufferRO: |
| 2350 | case BuiltinType::OCLImage2dRO: |
| 2351 | case BuiltinType::OCLImage2dArrayRO: |
| 2352 | case BuiltinType::OCLImage2dDepthRO: |
| 2353 | case BuiltinType::OCLImage2dArrayDepthRO: |
| 2354 | case BuiltinType::OCLImage2dMSAARO: |
| 2355 | case BuiltinType::OCLImage2dArrayMSAARO: |
| 2356 | case BuiltinType::OCLImage2dMSAADepthRO: |
| 2357 | case BuiltinType::OCLImage2dArrayMSAADepthRO: |
| 2358 | case BuiltinType::OCLImage3dRO: |
| 2359 | case BuiltinType::OCLImage1dWO: |
| 2360 | case BuiltinType::OCLImage1dArrayWO: |
| 2361 | case BuiltinType::OCLImage1dBufferWO: |
| 2362 | case BuiltinType::OCLImage2dWO: |
| 2363 | case BuiltinType::OCLImage2dArrayWO: |
| 2364 | case BuiltinType::OCLImage2dDepthWO: |
| 2365 | case BuiltinType::OCLImage2dArrayDepthWO: |
| 2366 | case BuiltinType::OCLImage2dMSAAWO: |
| 2367 | case BuiltinType::OCLImage2dArrayMSAAWO: |
| 2368 | case BuiltinType::OCLImage2dMSAADepthWO: |
| 2369 | case BuiltinType::OCLImage2dArrayMSAADepthWO: |
| 2370 | case BuiltinType::OCLImage3dWO: |
| 2371 | case BuiltinType::OCLImage1dRW: |
| 2372 | case BuiltinType::OCLImage1dArrayRW: |
| 2373 | case BuiltinType::OCLImage1dBufferRW: |
| 2374 | case BuiltinType::OCLImage2dRW: |
| 2375 | case BuiltinType::OCLImage2dArrayRW: |
| 2376 | case BuiltinType::OCLImage2dDepthRW: |
| 2377 | case BuiltinType::OCLImage2dArrayDepthRW: |
| 2378 | case BuiltinType::OCLImage2dMSAARW: |
| 2379 | case BuiltinType::OCLImage2dArrayMSAARW: |
| 2380 | case BuiltinType::OCLImage2dMSAADepthRW: |
| 2381 | case BuiltinType::OCLImage2dArrayMSAADepthRW: |
| 2382 | case BuiltinType::OCLImage3dRW: |
| 2383 | case BuiltinType::OCLSampler: |
| 2384 | case BuiltinType::OCLEvent: |
| 2385 | case BuiltinType::OCLClkEvent: |
| 2386 | case BuiltinType::OCLQueue: |
| 2387 | case BuiltinType::OCLReserveID: |
| 2388 | return res; |
| 2389 | } |
| 2390 | break; |
| 2391 | } |
| 2392 | case Type::Pointer: |
| 2393 | return trans_create_node_bin_op(c, res, BinOpTypeCmpNotEq, trans_create_node(c, NodeTypeNullLiteral)); |
| 2394 | |
| 2395 | case Type::Typedef: |
| 2396 | { |
| 2397 | const TypedefType *typedef_ty = static_cast<const TypedefType*>(ty); |
| 2398 | const TypedefNameDecl *typedef_decl = typedef_ty->getDecl(); |
| 2399 | auto existing_entry = c->decl_table.maybe_get((void*)typedef_decl->getCanonicalDecl()); |
| 2400 | if (existing_entry) { |
| 2401 | return existing_entry->value; |
| 2402 | } |
| 2403 | |
| 2404 | return res; |
| 2297 | 2405 | } |
| 2406 | |
| 2407 | case Type::Enum: |
| 2408 | { |
| 2409 | const EnumType *enum_ty = static_cast<const EnumType*>(ty); |
| 2410 | AstNode *enum_type = resolve_enum_decl(c, enum_ty->getDecl()); |
| 2411 | return to_enum_zero_cmp(c, res, enum_type); |
| 2412 | } |
| 2413 | |
| 2414 | case Type::Elaborated: |
| 2415 | { |
| 2416 | const ElaboratedType *elaborated_ty = static_cast<const ElaboratedType*>(ty); |
| 2417 | switch (elaborated_ty->getKeyword()) { |
| 2418 | case ETK_Enum: { |
| 2419 | AstNode *enum_type = trans_qual_type(c, elaborated_ty->getNamedType(), expr->getLocStart()); |
| 2420 | return to_enum_zero_cmp(c, res, enum_type); |
| 2421 | } |
| 2422 | case ETK_Struct: |
| 2423 | case ETK_Union: |
| 2424 | case ETK_Interface: |
| 2425 | case ETK_Class: |
| 2426 | case ETK_Typename: |
| 2427 | case ETK_None: |
| 2428 | return res; |
| 2429 | } |
| 2430 | } |
| 2431 | |
| 2432 | case Type::FunctionProto: |
| 2433 | case Type::Record: |
| 2434 | case Type::ConstantArray: |
| 2435 | case Type::Paren: |
| 2436 | case Type::Decayed: |
| 2437 | case Type::Attributed: |
| 2438 | case Type::IncompleteArray: |
| 2439 | case Type::BlockPointer: |
| 2440 | case Type::LValueReference: |
| 2441 | case Type::RValueReference: |
| 2442 | case Type::MemberPointer: |
| 2443 | case Type::VariableArray: |
| 2444 | case Type::DependentSizedArray: |
| 2445 | case Type::DependentSizedExtVector: |
| 2446 | case Type::Vector: |
| 2447 | case Type::ExtVector: |
| 2448 | case Type::FunctionNoProto: |
| 2449 | case Type::UnresolvedUsing: |
| 2450 | case Type::Adjusted: |
| 2451 | case Type::TypeOfExpr: |
| 2452 | case Type::TypeOf: |
| 2453 | case Type::Decltype: |
| 2454 | case Type::UnaryTransform: |
| 2455 | case Type::TemplateTypeParm: |
| 2456 | case Type::SubstTemplateTypeParm: |
| 2457 | case Type::SubstTemplateTypeParmPack: |
| 2458 | case Type::TemplateSpecialization: |
| 2459 | case Type::Auto: |
| 2460 | case Type::InjectedClassName: |
| 2461 | case Type::DependentName: |
| 2462 | case Type::DependentTemplateSpecialization: |
| 2463 | case Type::PackExpansion: |
| 2464 | case Type::ObjCObject: |
| 2465 | case Type::ObjCInterface: |
| 2466 | case Type::Complex: |
| 2467 | case Type::ObjCObjectPointer: |
| 2468 | case Type::Atomic: |
| 2469 | case Type::Pipe: |
| 2470 | case Type::ObjCTypeParam: |
| 2471 | case Type::DeducedTemplateSpecialization: |
| 2472 | return res; |
| 2298 | 2473 | } |
| 2474 | zig_unreachable(); |
| 2299 | 2475 | } |
| 2300 | 2476 | |
| 2301 | 2477 | static AstNode *trans_while_loop(Context *c, TransScope *scope, const WhileStmt *stmt) { |
| 2302 | 2478 | TransScopeWhile *while_scope = trans_scope_while_create(c, scope); |
| 2303 | 2479 | |
| 2304 | | while_scope->node->data.while_expr.condition = trans_to_bool_expr(c, scope, trans_expr(c, ResultUsedYes, scope, stmt->getCond(), TransRValue)); |
| 2480 | while_scope->node->data.while_expr.condition = trans_bool_expr(c, ResultUsedYes, scope, stmt->getCond(), TransRValue); |
| 2305 | 2481 | if (while_scope->node->data.while_expr.condition == nullptr) |
| 2306 | 2482 | return nullptr; |
| 2307 | 2483 | |
| ... | ... | @@ -2328,11 +2504,10 @@ static AstNode *trans_if_statement(Context *c, TransScope *scope, const IfStmt * |
| 2328 | 2504 | return nullptr; |
| 2329 | 2505 | } |
| 2330 | 2506 | |
| 2331 | | AstNode *condition_node = trans_expr(c, ResultUsedYes, scope, stmt->getCond(), TransRValue); |
| 2332 | | if (condition_node == nullptr) |
| 2507 | if_node->data.if_bool_expr.condition = trans_bool_expr(c, ResultUsedYes, scope, stmt->getCond(), TransRValue); |
| 2508 | if (if_node->data.if_bool_expr.condition == nullptr) |
| 2333 | 2509 | return nullptr; |
| 2334 | 2510 | |
| 2335 | | if_node->data.if_bool_expr.condition = trans_to_bool_expr(c, scope, condition_node); |
| 2336 | 2511 | return if_node; |
| 2337 | 2512 | } |
| 2338 | 2513 | |
| ... | ... | @@ -2524,12 +2699,18 @@ static AstNode *trans_for_loop(Context *c, TransScope *parent_scope, const ForSt |
| 2524 | 2699 | if (cond_stmt == nullptr) { |
| 2525 | 2700 | while_scope->node->data.while_expr.condition = trans_create_node_bool(c, true); |
| 2526 | 2701 | } else { |
| 2527 | | TransScope *end_cond_scope = trans_stmt(c, cond_scope, cond_stmt, |
| 2528 | | &while_scope->node->data.while_expr.condition); |
| 2529 | | if (end_cond_scope == nullptr) |
| 2530 | | return nullptr; |
| 2702 | if (Expr::classof(cond_stmt)) { |
| 2703 | const Expr *cond_expr = static_cast<const Expr*>(cond_stmt); |
| 2704 | while_scope->node->data.while_expr.condition = trans_bool_expr(c, ResultUsedYes, cond_scope, cond_expr, TransRValue); |
| 2531 | 2705 | |
| 2532 | | while_scope->node->data.while_expr.condition = trans_to_bool_expr(c, cond_scope, while_scope->node->data.while_expr.condition); |
| 2706 | if (while_scope->node->data.while_expr.condition == nullptr) |
| 2707 | return nullptr; |
| 2708 | } else { |
| 2709 | TransScope *end_cond_scope = trans_stmt(c, cond_scope, cond_stmt, |
| 2710 | &while_scope->node->data.while_expr.condition); |
| 2711 | if (end_cond_scope == nullptr) |
| 2712 | return nullptr; |
| 2713 | } |
| 2533 | 2714 | } |
| 2534 | 2715 | |
| 2535 | 2716 | const Stmt *inc_stmt = stmt->getInc(); |