diff options
Diffstat (limited to 'clang')
| -rw-r--r-- | clang/include/clang/AST/Expr.h | 5 | ||||
| -rw-r--r-- | clang/include/clang/AST/OperationKinds.h | 17 | ||||
| -rw-r--r-- | clang/include/clang/AST/Stmt.h | 4 | ||||
| -rw-r--r-- | clang/lib/AST/Expr.cpp | 16 | ||||
| -rw-r--r-- | clang/lib/AST/ExprConstant.cpp | 2 | ||||
| -rw-r--r-- | clang/lib/Checker/GRExprEngine.cpp | 5 | ||||
| -rw-r--r-- | clang/lib/CodeGen/CGExpr.cpp | 5 | ||||
| -rw-r--r-- | clang/lib/CodeGen/CGExprComplex.cpp | 2 | ||||
| -rw-r--r-- | clang/lib/CodeGen/CGExprScalar.cpp | 6 | ||||
| -rw-r--r-- | clang/lib/Sema/SemaExpr.cpp | 68 | 
10 files changed, 97 insertions, 33 deletions
| diff --git a/clang/include/clang/AST/Expr.h b/clang/include/clang/AST/Expr.h index be6e1bca583..eda23683444 100644 --- a/clang/include/clang/AST/Expr.h +++ b/clang/include/clang/AST/Expr.h @@ -1997,6 +1997,11 @@ private:      case CK_AnyPointerToObjCPointerCast:      case CK_AnyPointerToBlockPointerCast:      case CK_ObjCObjectLValueCast: +    case CK_FloatingRealToComplex: +    case CK_FloatingComplexCast: +    case CK_IntegralRealToComplex: +    case CK_IntegralComplexCast: +    case CK_IntegralToFloatingComplex:        assert(path_empty() && "Cast kind should not have a base path!");        break;      } diff --git a/clang/include/clang/AST/OperationKinds.h b/clang/include/clang/AST/OperationKinds.h index 4e57df1af6e..7cfeed2ab50 100644 --- a/clang/include/clang/AST/OperationKinds.h +++ b/clang/include/clang/AST/OperationKinds.h @@ -118,7 +118,22 @@ enum CastKind {    /// \brief Converting between two Objective-C object types, which    /// can occur when performing reference binding to an Objective-C    /// object. -  CK_ObjCObjectLValueCast +  CK_ObjCObjectLValueCast, + +  /// \brief Floating point real to floating point complex +  CK_FloatingRealToComplex, + +  /// \brief Casting between floating point complex types of different size +  CK_FloatingComplexCast, + +  /// \brief Integral real to integral complex +  CK_IntegralRealToComplex, + +  /// \brief Casting between integral complex types of different size +  CK_IntegralComplexCast, + +  /// \brief Casting from an integral complex to a floating complex. +  CK_IntegralToFloatingComplex  }; diff --git a/clang/include/clang/AST/Stmt.h b/clang/include/clang/AST/Stmt.h index ca42b3ea7e0..3c5d306af89 100644 --- a/clang/include/clang/AST/Stmt.h +++ b/clang/include/clang/AST/Stmt.h @@ -156,8 +156,8 @@ protected:      friend class CastExpr;      unsigned : NumExprBits; -    unsigned Kind : 5; -    unsigned BasePathSize : 32 - NumExprBits - 5; +    unsigned Kind : 6; +    unsigned BasePathSize : 32 - 6 - NumExprBits;    };    union { diff --git a/clang/lib/AST/Expr.cpp b/clang/lib/AST/Expr.cpp index 2edf62ab397..cc209a458a1 100644 --- a/clang/lib/AST/Expr.cpp +++ b/clang/lib/AST/Expr.cpp @@ -798,9 +798,19 @@ const char *CastExpr::getCastKindName() const {      return "AnyPointerToBlockPointerCast";    case CK_ObjCObjectLValueCast:      return "ObjCObjectLValueCast"; -  } - -  assert(0 && "Unhandled cast kind!"); +  case CK_FloatingRealToComplex: +    return "FloatingRealToComplex"; +  case CK_FloatingComplexCast: +    return "FloatingComplexCast"; +  case CK_IntegralRealToComplex: +    return "IntegralRealToComplex"; +  case CK_IntegralComplexCast: +    return "IntegralComplexCast"; +  case CK_IntegralToFloatingComplex: +    return "IntegralToFloatingComplex"; +  } + +  llvm_unreachable("Unhandled cast kind!");    return 0;  } diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp index dfeb32df3d3..172a811bee1 100644 --- a/clang/lib/AST/ExprConstant.cpp +++ b/clang/lib/AST/ExprConstant.cpp @@ -2165,6 +2165,8 @@ bool ComplexExprEvaluator::VisitCastExpr(CastExpr *E) {    QualType EltType = E->getType()->getAs<ComplexType>()->getElementType();    QualType SubType = SubExpr->getType(); +  // TODO: just trust CastKind +    if (SubType->isRealFloatingType()) {      APFloat &Real = Result.FloatReal;      if (!EvaluateFloat(SubExpr, Real, Info)) diff --git a/clang/lib/Checker/GRExprEngine.cpp b/clang/lib/Checker/GRExprEngine.cpp index 73b5bf8967e..19238bf2afb 100644 --- a/clang/lib/Checker/GRExprEngine.cpp +++ b/clang/lib/Checker/GRExprEngine.cpp @@ -2524,6 +2524,11 @@ void GRExprEngine::VisitCast(const CastExpr *CastE, const Expr *Ex,    case CK_IntegralToFloating:    case CK_FloatingToIntegral:    case CK_FloatingCast: +  case CK_FloatingRealToComplex: +  case CK_FloatingComplexCast: +  case CK_IntegralRealToComplex: +  case CK_IntegralComplexCast: +  case CK_IntegralToFloatingComplex:    case CK_AnyPointerToObjCPointerCast:    case CK_AnyPointerToBlockPointerCast:    case CK_DerivedToBase: diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp index bb2eb3c7982..6739fd679cf 100644 --- a/clang/lib/CodeGen/CGExpr.cpp +++ b/clang/lib/CodeGen/CGExpr.cpp @@ -1814,6 +1814,11 @@ LValue CodeGenFunction::EmitCastLValue(const CastExpr *E) {    case CK_IntegralToFloating:    case CK_FloatingToIntegral:    case CK_FloatingCast: +  case CK_FloatingRealToComplex: +  case CK_FloatingComplexCast: +  case CK_IntegralRealToComplex: +  case CK_IntegralComplexCast: +  case CK_IntegralToFloatingComplex:    case CK_DerivedToBaseMemberPointer:    case CK_BaseToDerivedMemberPointer:    case CK_MemberPointerToBoolean: diff --git a/clang/lib/CodeGen/CGExprComplex.cpp b/clang/lib/CodeGen/CGExprComplex.cpp index 517a8da34d3..637441f4e19 100644 --- a/clang/lib/CodeGen/CGExprComplex.cpp +++ b/clang/lib/CodeGen/CGExprComplex.cpp @@ -350,6 +350,8 @@ ComplexPairTy ComplexExprEmitter::EmitComplexToComplexCast(ComplexPairTy Val,  ComplexPairTy ComplexExprEmitter::EmitCast(CastExpr::CastKind CK, Expr *Op,                                              QualType DestTy) { +  // FIXME: this should be based off of the CastKind. +    // Two cases here: cast from (complex to complex) and (scalar to complex).    if (Op->getType()->isAnyComplexType())      return EmitComplexToComplexCast(Visit(Op), Op->getType(), DestTy); diff --git a/clang/lib/CodeGen/CGExprScalar.cpp b/clang/lib/CodeGen/CGExprScalar.cpp index d07d20395d5..5b419c02f8b 100644 --- a/clang/lib/CodeGen/CGExprScalar.cpp +++ b/clang/lib/CodeGen/CGExprScalar.cpp @@ -1079,7 +1079,11 @@ Value *ScalarExprEmitter::EmitCastExpr(CastExpr *CE) {      return CGF.CGM.getCXXABI().EmitMemberPointerConversion(CGF, CE, Src);    } - +  case CK_FloatingRealToComplex: +  case CK_FloatingComplexCast: +  case CK_IntegralRealToComplex: +  case CK_IntegralComplexCast: +  case CK_IntegralToFloatingComplex:    case CK_ConstructorConversion:      assert(0 && "Should be unreachable!");      break; diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index 590685d6ccc..b9d3d875659 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -399,18 +399,30 @@ QualType Sema::UsualArithmeticConversions(Expr *&lhsExpr, Expr *&rhsExpr,    if (LHSComplexFloat || RHSComplexFloat) {      // if we have an integer operand, the result is the complex type. -    if (LHSComplexFloat && -        (rhs->isIntegerType() || rhs->isComplexIntegerType())) { -      // convert the rhs to the lhs complex type. -      ImpCastExprToType(rhsExpr, lhs, CK_Unknown); +    if (!RHSComplexFloat && !rhs->isRealFloatingType()) { +      if (rhs->isIntegerType()) { +        QualType fp = cast<ComplexType>(lhs)->getElementType(); +        ImpCastExprToType(rhsExpr, fp, CK_IntegralToFloating); +        ImpCastExprToType(rhsExpr, lhs, CK_FloatingRealToComplex); +      } else { +        assert(rhs->isComplexIntegerType()); +        ImpCastExprToType(rhsExpr, lhs, CK_IntegralToFloatingComplex); +      }        return lhs;      } -    if (!LHSComplexFloat && RHSComplexFloat && -        (lhs->isIntegerType() || lhs->isComplexIntegerType())) { -      // convert the lhs to the rhs complex type. -      if (!isCompAssign) -        ImpCastExprToType(lhsExpr, rhs, CK_Unknown); +    if (!LHSComplexFloat && !lhs->isRealFloatingType()) { +      if (!isCompAssign) { +        // int -> float -> _Complex float +        if (lhs->isIntegerType()) { +          QualType fp = cast<ComplexType>(rhs)->getElementType(); +          ImpCastExprToType(lhsExpr, fp, CK_IntegralToFloating); +          ImpCastExprToType(lhsExpr, rhs, CK_FloatingRealToComplex); +        } else { +          assert(lhs->isComplexIntegerType()); +          ImpCastExprToType(lhsExpr, rhs, CK_IntegralToFloatingComplex); +        } +      }        return rhs;      } @@ -430,13 +442,13 @@ QualType Sema::UsualArithmeticConversions(Expr *&lhsExpr, Expr *&rhsExpr,      if (LHSComplexFloat && RHSComplexFloat) {        if (order > 0) {          // _Complex float -> _Complex double -        ImpCastExprToType(rhsExpr, lhs, CK_Unknown); +        ImpCastExprToType(rhsExpr, lhs, CK_FloatingComplexCast);          return lhs;        } else if (order < 0) {          // _Complex float -> _Complex double          if (!isCompAssign) -          ImpCastExprToType(lhsExpr, rhs, CK_Unknown); +          ImpCastExprToType(lhsExpr, rhs, CK_FloatingComplexCast);          return rhs;        }        return lhs; @@ -447,7 +459,9 @@ QualType Sema::UsualArithmeticConversions(Expr *&lhsExpr, Expr *&rhsExpr,      if (LHSComplexFloat) {        if (order > 0) { // LHS is wider          // float -> _Complex double -        ImpCastExprToType(rhsExpr, lhs, CK_Unknown); +        QualType fp = cast<ComplexType>(lhs)->getElementType(); +        ImpCastExprToType(rhsExpr, fp, CK_FloatingCast); +        ImpCastExprToType(rhsExpr, lhs, CK_FloatingRealToComplex);          return lhs;                } @@ -455,11 +469,11 @@ QualType Sema::UsualArithmeticConversions(Expr *&lhsExpr, Expr *&rhsExpr,        QualType result = (order == 0 ? lhs : Context.getComplexType(rhs));        // double -> _Complex double -      ImpCastExprToType(rhsExpr, result, CK_Unknown); +      ImpCastExprToType(rhsExpr, result, CK_FloatingRealToComplex);        // _Complex float -> _Complex double        if (!isCompAssign && order < 0) -        ImpCastExprToType(lhsExpr, result, CK_Unknown); +        ImpCastExprToType(lhsExpr, result, CK_FloatingComplexCast);        return result;      } @@ -470,8 +484,10 @@ QualType Sema::UsualArithmeticConversions(Expr *&lhsExpr, Expr *&rhsExpr,      if (order < 0) { // RHS is wider        // float -> _Complex double -      if (!isCompAssign) -        ImpCastExprToType(lhsExpr, rhs, CK_Unknown); +      if (!isCompAssign) { +        ImpCastExprToType(lhsExpr, rhs, CK_FloatingCast); +        ImpCastExprToType(lhsExpr, rhs, CK_FloatingRealToComplex); +      }        return rhs;      } @@ -480,11 +496,11 @@ QualType Sema::UsualArithmeticConversions(Expr *&lhsExpr, Expr *&rhsExpr,      // double -> _Complex double      if (!isCompAssign) -      ImpCastExprToType(lhsExpr, result, CK_Unknown); +      ImpCastExprToType(lhsExpr, result, CK_FloatingRealToComplex);      // _Complex float -> _Complex double      if (order > 0) -      ImpCastExprToType(rhsExpr, result, CK_Unknown); +      ImpCastExprToType(rhsExpr, result, CK_FloatingComplexCast);      return result;    } @@ -521,11 +537,11 @@ QualType Sema::UsualArithmeticConversions(Expr *&lhsExpr, Expr *&rhsExpr,        QualType result = Context.getComplexType(lhs);        // _Complex int -> _Complex float -      ImpCastExprToType(rhsExpr, result, CK_Unknown); +      ImpCastExprToType(rhsExpr, result, CK_IntegralToFloatingComplex);        // float -> _Complex float        if (!isCompAssign) -        ImpCastExprToType(lhsExpr, result, CK_Unknown); +        ImpCastExprToType(lhsExpr, result, CK_FloatingRealToComplex);        return result;      } @@ -544,10 +560,10 @@ QualType Sema::UsualArithmeticConversions(Expr *&lhsExpr, Expr *&rhsExpr,      // _Complex int -> _Complex float      if (!isCompAssign) -      ImpCastExprToType(lhsExpr, result, CK_Unknown); +      ImpCastExprToType(lhsExpr, result, CK_IntegralToFloatingComplex);      // float -> _Complex float -    ImpCastExprToType(rhsExpr, result, CK_Unknown); +    ImpCastExprToType(rhsExpr, result, CK_FloatingRealToComplex);      return result;    } @@ -563,21 +579,21 @@ QualType Sema::UsualArithmeticConversions(Expr *&lhsExpr, Expr *&rhsExpr,      assert(order && "inequal types with equal element ordering");      if (order > 0) {        // _Complex int -> _Complex long -      ImpCastExprToType(rhsExpr, lhs, CK_Unknown); +      ImpCastExprToType(rhsExpr, lhs, CK_IntegralComplexCast);        return lhs;      }      if (!isCompAssign) -      ImpCastExprToType(lhsExpr, rhs, CK_Unknown); +      ImpCastExprToType(lhsExpr, rhs, CK_IntegralComplexCast);      return rhs;    } else if (lhsComplexInt) {      // int -> _Complex int -    ImpCastExprToType(rhsExpr, lhs, CK_Unknown); +    ImpCastExprToType(rhsExpr, lhs, CK_IntegralRealToComplex);      return lhs;    } else if (rhsComplexInt) {      // int -> _Complex int      if (!isCompAssign) -      ImpCastExprToType(lhsExpr, rhs, CK_Unknown); +      ImpCastExprToType(lhsExpr, rhs, CK_IntegralRealToComplex);      return rhs;    } | 

