@@ -634,6 +634,8 @@ Value ConditionalExpressionAST::codegen() {
634
634
auto *falseBlock = llvm::BasicBlock::Create (getContext ());
635
635
auto *endBlock = llvm::BasicBlock::Create (getContext ());
636
636
637
+ Type *type;
638
+
637
639
if (auto *ltype = dynamic_cast <IntegerType *> (condValue.getType ())) {
638
640
auto *const0 = llvm::ConstantInt::get (ltype->getLLVMType (), 0 );
639
641
cond = sBuilder .CreateICmpNE (condValue.getValue (), const0);
@@ -650,34 +652,41 @@ Value ConditionalExpressionAST::codegen() {
650
652
// true block
651
653
sBuilder .SetInsertPoint (trueBlock);
652
654
auto exp1 = expression->codegen ();
653
- if (!sBuilder .GetInsertBlock ()->getTerminator ())
654
- sBuilder .CreateBr (endBlock);
655
+ llvm::Value *trueValue = exp1.getValue ();
655
656
656
657
// false block
657
658
currentFunction->getBasicBlockList ().push_back (falseBlock);
658
659
sBuilder .SetInsertPoint (falseBlock);
659
660
auto exp2 = conditional_expression->codegen ();
660
- Type *type;
661
- llvm::Value *trueValue = exp1.getValue ();
662
661
llvm::Value *falseValue = exp2 .getValue ();
663
662
664
- if (dynamic_cast < ArithmeticType *>(exp1.getType ())
665
- && dynamic_cast < ArithmeticType *>(exp2 .getType ())) {
666
- std::tie (type, trueValue, falseValue) = BinaryOperatorAST::UsualArithmeticConversions (exp1, exp2 , this );
667
- } else if ((dynamic_cast < StructType *>(exp1.getType ())
668
- || dynamic_cast < UnionType *>(exp1.getType ()))
669
- && exp1.getType () == exp2 .getType ()) {
670
- type = exp1.getType ();
671
- } else if (exp1.getType () == &VoidType::sVoidType
672
- && exp2 .getType () == &VoidType::sVoidType ) {
663
+ Type* lType = exp1.getType ();
664
+ Type* rType = exp2 .getType ();
665
+ if (dynamic_cast < ArithmeticType *>(lType)
666
+ && dynamic_cast < ArithmeticType *>(rType)) {
667
+ if (BinaryOperatorAST::UsualArithmeticConversions (lType, rType, this )) {
668
+ sBuilder .SetInsertPoint (falseBlock);
669
+ falseValue = rType->castTo (lType, falseValue, this );
670
+ type = lType;
671
+ } else {
672
+ sBuilder .SetInsertPoint (trueBlock);
673
+ trueValue = lType->castTo (rType, trueValue, this );
674
+ type = rType;
675
+ }
676
+ } else if ((dynamic_cast < StructType *>(lType)
677
+ || dynamic_cast < UnionType *>(lType))
678
+ && lType == rType) {
679
+ type = lType;
680
+ } else if (lType == &VoidType::sVoidType
681
+ && rType == &VoidType::sVoidType ) {
673
682
type = &VoidType::sVoidType ;
674
- } else if (dynamic_cast < PointerType *>(exp1. getType () )
675
- && dynamic_cast < PointerType *>(exp2 . getType () )) {
676
- if (exp1. getType () ->compatible (exp2 . getType () )) {
677
- type = exp1. getType () ;
683
+ } else if (dynamic_cast < PointerType *>(lType )
684
+ && dynamic_cast < PointerType *>(rType )) {
685
+ if (lType ->compatible (rType )) {
686
+ type = lType ;
678
687
} else {
679
- auto *p1 = static_cast <PointerType *>(exp1. getType () );
680
- auto *p2 = static_cast <PointerType *>(exp2 . getType () );
688
+ auto *p1 = static_cast <PointerType *>(lType );
689
+ auto *p2 = static_cast <PointerType *>(rType );
681
690
if (p1->getReferencedQualifiedType ().getType () == &VoidType::sVoidType
682
691
&& dynamic_cast < ObjectType *> (p2->getReferencedQualifiedType ().getType ())) {
683
692
type = p1;
@@ -693,6 +702,11 @@ Value ConditionalExpressionAST::codegen() {
693
702
} else {
694
703
throw SemaException (" incompatible operand types" , involvedTokens ());
695
704
}
705
+ sBuilder .SetInsertPoint (trueBlock);
706
+ if (!sBuilder .GetInsertBlock ()->getTerminator ())
707
+ sBuilder .CreateBr (endBlock);
708
+
709
+ sBuilder .SetInsertPoint (falseBlock);
696
710
if (!sBuilder .GetInsertBlock ()->getTerminator ())
697
711
sBuilder .CreateBr (endBlock);
698
712
@@ -2396,51 +2410,11 @@ BinaryOperatorAST::UsualArithmeticConversions(Value &lhs, Value &rhs, const AST
2396
2410
Type *rType = rhs.getType ();
2397
2411
llvm::Value *lValue = lhs.getValue ();
2398
2412
llvm::Value *rValue = rhs.getValue ();
2399
-
2400
- while (true ) {
2401
- if (auto *li = dynamic_cast < IntegerType *>(lType)) {
2402
- if (auto *ri = dynamic_cast < IntegerType *>(rType)) {
2403
- if (li->getSizeInBits () > ri->getSizeInBits ()) {
2404
- rValue = ri->castTo (li, rValue, ast);
2405
- rType = lType;
2406
- break ;
2407
- } else if (li->getSizeInBits () == ri->getSizeInBits ()) {
2408
- if (!li->isSigned () || !ri->isSigned ()) {
2409
- lType = !li->isSigned () ? li : ri;
2410
- }
2411
- break ;
2412
- } else {
2413
- lValue = li->castTo (ri, lValue, ast);
2414
- lType = rType;
2415
- break ;
2416
- }
2417
- } else if (auto *rf = dynamic_cast < FloatingType *>(rType)) {
2418
- lValue = li->castTo (rf, lValue, ast);
2419
- lType = rf;
2420
- break ;
2421
- }
2422
- } else if (auto *lf = dynamic_cast < FloatingType *>(lType)) {
2423
- if (auto *ri = dynamic_cast < IntegerType *>(rType)) {
2424
- rValue = ri->castTo (lf, rValue, ast);
2425
- break ;
2426
- } else if (auto *rf = dynamic_cast < FloatingType *>(rType)) {
2427
- if (lf->getSizeInBits () > rf->getSizeInBits ()) {
2428
- rValue = rf->castTo (lf, rValue, ast);
2429
- rType = lType;
2430
- break ;
2431
- } else if (lf->getSizeInBits () == rf->getSizeInBits ()) {
2432
- break ;
2433
- } else {
2434
- lValue = lf->castTo (rf, lValue, ast);
2435
- lType = rType;
2436
- break ;
2437
- }
2438
- }
2439
- }
2440
- throw SemaException (" operands must be integer or float type" , ast->involvedTokens ());
2413
+ if (UsualArithmeticConversions (lType, rType, ast)) {
2414
+ return {lType, lValue, rType->castTo (lType, rValue, ast)};
2415
+ } else {
2416
+ return {rType, lType->castTo (rType, lValue, ast), rValue};
2441
2417
}
2442
- return {lType, lValue, rValue};
2443
-
2444
2418
}
2445
2419
Value BinaryOperatorAST::codegen (Value &lhs,
2446
2420
Value &rhs,
@@ -2736,6 +2710,19 @@ Value BinaryOperatorAST::codegen(Value &lhs,
2736
2710
}
2737
2711
throw SemaException (" invalid operands to binary expression" , lAST->involvedTokens ());
2738
2712
}
2713
+ bool BinaryOperatorAST::UsualArithmeticConversions (Type *lhs, Type *rhs, const AST *ast) {
2714
+ if (dynamic_cast <IntegerType *>(lhs) && dynamic_cast <IntegerType *>(rhs)) {
2715
+ return static_cast <IntegerType *>(lhs)->getSizeInBits () > static_cast <IntegerType *>(rhs)->getSizeInBits ();
2716
+ } else if (dynamic_cast <IntegerType *>(lhs) && dynamic_cast <FloatingType *>(rhs)) {
2717
+ return false ;
2718
+ } else if (dynamic_cast <FloatingType *>(lhs) && dynamic_cast <IntegerType *>(rhs)) {
2719
+ return true ;
2720
+ } else if (dynamic_cast <FloatingType *>(lhs) && dynamic_cast <FloatingType *>(rhs)) {
2721
+ return static_cast <FloatingType *>(lhs)->getSizeInBits () > static_cast <FloatingType *>(rhs)->getSizeInBits ();
2722
+ } else {
2723
+ throw SemaException (" operands must be integer or float type" , ast->involvedTokens ());
2724
+ }
2725
+ }
2739
2726
Value LogicalBinaryOperatorAST::codegen () {
2740
2727
auto *currentFunction = sBuilder .GetInsertBlock ()->getParent ();
2741
2728
auto *thisBlock = sBuilder .GetInsertBlock ();
0 commit comments