authorgravatar for thejoshwolfe@gmail.comJosh Wolfe <thejoshwolfe@gmail.com> 2017-09-20 19:49:41-07:00
committergravatar for thejoshwolfe@gmail.comJosh Wolfe <thejoshwolfe@gmail.com> 2017-09-20 19:49:41-07:00
logc10b052ceec96b0e927a3365708798a860696cbf
treeccd671961b80f8b55d4258b7de3b53def42e34e4
parenta5e4e205c8a9f2706300a4dc7ebe7cf3bfe093cd

translate expr++ from c to zig


1 files changed, 51 insertions(+), 8 deletions(-)

src/parsec.cpp+51-8
......@@ -386,8 +386,17 @@ static bool qual_type_child_is_fn_proto(const QualType &qt) {
386386 return false;
387387}
388388
389static QualType resolve_any_typedef(Context *c, QualType qt) {
390 const Type * ty = qt.getTypePtr();
391 if (ty->getTypeClass() != Type::Typedef)
392 return qt;
393 const TypedefType *typedef_ty = static_cast<const TypedefType*>(ty);
394 const TypedefNameDecl *typedef_decl = typedef_ty->getDecl();
395 return typedef_decl->getUnderlyingType();
396}
397
389398static bool c_is_signed_integer(Context *c, QualType qt) {
390 const Type *c_type = qt.getTypePtr();
399 const Type *c_type = resolve_any_typedef(c, qt).getTypePtr();
391400 if (c_type->getTypeClass() != Type::Builtin)
392401 return false;
393402 const BuiltinType *builtin_ty = static_cast<const BuiltinType*>(c_type);
......@@ -406,7 +415,7 @@ static bool c_is_signed_integer(Context *c, QualType qt) {
406415}
407416
408417static bool c_is_unsigned_integer(Context *c, QualType qt) {
409 const Type *c_type = qt.getTypePtr();
418 const Type *c_type = resolve_any_typedef(c, qt).getTypePtr();
410419 if (c_type->getTypeClass() != Type::Builtin)
411420 return false;
412421 const BuiltinType *builtin_ty = static_cast<const BuiltinType*>(c_type);
......@@ -443,6 +452,16 @@ static bool c_is_float(Context *c, QualType qt) {
443452 }
444453}
445454
455static bool qual_type_has_wrapping_overflow(Context *c, QualType qt) {
456 if (c_is_signed_integer(c, qt) || c_is_float(c, qt)) {
457 // float and signed integer overflow is undefined behavior.
458 return false;
459 } else {
460 // unsigned integer overflow wraps around.
461 return true;
462 }
463}
464
446465enum TransLRValue {
447466 TransLValue,
448467 TransRValue,
......@@ -1286,11 +1305,35 @@ static AstNode *trans_decl_ref_expr(Context *c, DeclRefExpr *stmt, TransLRValue
12861305 return trans_create_node_symbol(c, symbol_name);
12871306}
12881307
1289static AstNode *trans_unary_operator(Context *c, AstNode *block, UnaryOperator *stmt) {
1308static AstNode *trans_unary_operator(Context *c, bool result_used, AstNode *block, UnaryOperator *stmt) {
12901309 switch (stmt->getOpcode()) {
1291 case UO_PostInc:
1292 emit_warning(c, stmt->getLocStart(), "TODO handle C translation UO_PostInc");
1293 return nullptr;
1310 case UO_PostInc: {
1311 Expr *op_expr = stmt->getSubExpr();
1312 BinOpType bin_op = qual_type_has_wrapping_overflow(c, op_expr->getType())
1313 ? BinOpTypeAssignPlusWrap
1314 : BinOpTypeAssignPlus;
1315
1316 if (!result_used) {
1317 // common case
1318 // c: expr++
1319 // zig: expr += 1
1320 return trans_create_node_bin_op(c,
1321 trans_expr(c, true, block, op_expr, TransLValue),
1322 bin_op,
1323 trans_create_node_unsigned(c, 1));
1324 } else {
1325 // worst case
1326 // c: expr++
1327 // zig: {
1328 // zig: const _ref = &expr;
1329 // zig: const _tmp = *_ref;
1330 // zig: *_ref += 1;
1331 // zig: _tmp
1332 // zig: }
1333 emit_warning(c, stmt->getLocStart(), "TODO handle C translation UO_PostInc with result_used");
1334 return nullptr;
1335 }
1336 }
12941337 case UO_PostDec:
12951338 emit_warning(c, stmt->getLocStart(), "TODO handle C translation UO_PostDec");
12961339 return nullptr;
......@@ -1312,7 +1355,7 @@ static AstNode *trans_unary_operator(Context *c, AstNode *block, UnaryOperator *
13121355 case UO_Minus:
13131356 {
13141357 Expr *op_expr = stmt->getSubExpr();
1315 if (c_is_signed_integer(c, op_expr->getType()) || c_is_float(c, op_expr->getType())) {
1358 if (!qual_type_has_wrapping_overflow(c, op_expr->getType())) {
13161359 AstNode *node = trans_create_node(c, NodeTypePrefixOpExpr);
13171360 node->data.prefix_op_expr.prefix_op = PrefixOpNegation;
13181361
......@@ -1642,7 +1685,7 @@ static AstNode *trans_stmt(Context *c, bool result_used, AstNode *block, Stmt *s
16421685 case Stmt::DeclRefExprClass:
16431686 return trans_decl_ref_expr(c, (DeclRefExpr *)stmt, lrvalue);
16441687 case Stmt::UnaryOperatorClass:
1645 return trans_unary_operator(c, block, (UnaryOperator *)stmt);
1688 return trans_unary_operator(c, result_used, block, (UnaryOperator *)stmt);
16461689 case Stmt::DeclStmtClass:
16471690 return trans_local_declaration(c, block, (DeclStmt *)stmt);
16481691 case Stmt::WhileStmtClass: