[cfe-commits] r63278 - /cfe/trunk/lib/AST/ExprConstant.cpp

Daniel Dunbar daniel at zuster.org
Wed Jan 28 22:16:07 PST 2009


Author: ddunbar
Date: Thu Jan 29 00:16:07 2009
New Revision: 63278

URL: http://llvm.org/viewvc/llvm-project?rev=63278&view=rev
Log:
Evaluate casts to complex.
 - Lift (int,float) -> (int,float) conversion into separate routines.

 - Fix handling of, e.g., char -> _Complex int, which was producing a
   _Complex char value instead.

Modified:
    cfe/trunk/lib/AST/ExprConstant.cpp

Modified: cfe/trunk/lib/AST/ExprConstant.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ExprConstant.cpp?rev=63278&r1=63277&r2=63278&view=diff

==============================================================================
--- cfe/trunk/lib/AST/ExprConstant.cpp (original)
+++ cfe/trunk/lib/AST/ExprConstant.cpp Thu Jan 29 00:16:07 2009
@@ -87,6 +87,49 @@
   return false;
 }
 
+static APSInt HandleFloatToIntCast(QualType DestType, QualType SrcType, 
+                                   APFloat &Value, ASTContext &Ctx) {
+  unsigned DestWidth = Ctx.getIntWidth(DestType);
+  // Determine whether we are converting to unsigned or signed.
+  bool DestSigned = DestType->isSignedIntegerType();
+  
+  // FIXME: Warning for overflow.
+  uint64_t Space[4];
+  bool ignored;
+  (void)Value.convertToInteger(Space, DestWidth, DestSigned,
+                               llvm::APFloat::rmTowardZero, &ignored);
+  return APSInt(llvm::APInt(DestWidth, 4, Space), !DestSigned);
+}
+
+static APFloat HandleFloatToFloatCast(QualType DestType, QualType SrcType, 
+                                      APFloat &Value, ASTContext &Ctx) {
+  bool ignored;
+  APFloat Result = Value;
+  Result.convert(Ctx.getFloatTypeSemantics(DestType), 
+                 APFloat::rmNearestTiesToEven, &ignored);
+  return Result;
+}
+
+static APSInt HandleIntToIntCast(QualType DestType, QualType SrcType, 
+                                 APSInt &Value, ASTContext &Ctx) {
+  unsigned DestWidth = Ctx.getIntWidth(DestType);
+  APSInt Result = Value;
+  // Figure out if this is a truncate, extend or noop cast.
+  // If the input is signed, do a sign extend, noop, or truncate.
+  Result.extOrTrunc(DestWidth);
+  Result.setIsUnsigned(DestType->isUnsignedIntegerType());
+  return Result;
+}
+
+static APFloat HandleIntToFloatCast(QualType DestType, QualType SrcType, 
+                                    APSInt &Value, ASTContext &Ctx) {
+
+  APFloat Result(Ctx.getFloatTypeSemantics(DestType), 1);
+  Result.convertFromAPInt(Value, Value.isSigned(),
+                          APFloat::rmNearestTiesToEven);
+  return Result;
+}
+
 //===----------------------------------------------------------------------===//
 // LValue Evaluation
 //===----------------------------------------------------------------------===//
@@ -484,9 +527,7 @@
   bool VisitUnaryOperator(const UnaryOperator *E);
   bool VisitConditionalOperator(const ConditionalOperator *E);
 
-  bool VisitCastExpr(CastExpr* E) {
-    return HandleCast(E);
-  }
+  bool VisitCastExpr(CastExpr* E);
   bool VisitSizeOfAlignOfExpr(const SizeOfAlignOfExpr *E);
 
   bool VisitCXXBoolLiteralExpr(const CXXBoolLiteralExpr *E) {
@@ -515,7 +556,6 @@
   }
 
 private:
-  bool HandleCast(CastExpr* E);
   unsigned GetAlignOfExpr(const Expr *E);
   unsigned GetAlignOfType(QualType T);
 };
@@ -996,7 +1036,7 @@
   
 /// HandleCast - This is used to evaluate implicit or explicit casts where the
 /// result type is integer.
-bool IntExprEvaluator::HandleCast(CastExpr *E) {
+bool IntExprEvaluator::VisitCastExpr(CastExpr *E) {
   Expr *SubExpr = E->getSubExpr();
   QualType DestType = E->getType();
 
@@ -1016,11 +1056,8 @@
   if (SubExpr->getType()->isIntegralType()) {
     if (!Visit(SubExpr))
       return false;
-    
-    // Figure out if this is a truncate, extend or noop cast.
-    // If the input is signed, do a sign extend, noop, or truncate.
-    Result.extOrTrunc(DestWidth);
-    Result.setIsUnsigned(DestType->isUnsignedIntegerType());
+
+    Result = HandleIntToIntCast(DestType, SubExpr->getType(), Result, Info.Ctx);
     return true;
   }
   
@@ -1046,16 +1083,7 @@
   if (!EvaluateFloat(SubExpr, F, Info))
     return Error(E->getExprLoc(), diag::note_invalid_subexpr_in_ice, E);
   
-  // Determine whether we are converting to unsigned or signed.
-  bool DestSigned = DestType->isSignedIntegerType();
-  
-  // FIXME: Warning for overflow.
-  uint64_t Space[4];
-  bool ignored;
-  (void)F.convertToInteger(Space, DestWidth, DestSigned,
-                           llvm::APFloat::rmTowardZero, &ignored);
-  Result = llvm::APInt(DestWidth, 4, Space);
-  Result.setIsUnsigned(!DestSigned);
+  Result = HandleFloatToIntCast(DestType, SubExpr->getType(), F, Info.Ctx);
   return true;
 }
 
@@ -1199,22 +1227,19 @@
 bool FloatExprEvaluator::VisitCastExpr(CastExpr *E) {
   Expr* SubExpr = E->getSubExpr();
   
-  const llvm::fltSemantics& destSemantics =
-      Info.Ctx.getFloatTypeSemantics(E->getType());
   if (SubExpr->getType()->isIntegralType()) {
     APSInt IntResult;
     if (!EvaluateInteger(E, IntResult, Info))
       return false;
-    Result = APFloat(destSemantics, 1);
-    Result.convertFromAPInt(IntResult, IntResult.isSigned(),
-                            APFloat::rmNearestTiesToEven);
+    Result = HandleIntToFloatCast(E->getType(), SubExpr->getType(), 
+                                  IntResult, Info.Ctx);
     return true;
   }
   if (SubExpr->getType()->isRealFloatingType()) {
     if (!Visit(SubExpr))
       return false;
-    bool ignored;
-    Result.convert(destSemantics, APFloat::rmNearestTiesToEven, &ignored);
+    Result = HandleFloatToFloatCast(E->getType(), SubExpr->getType(),
+                                    Result, Info.Ctx);
     return true;
   }
 
@@ -1275,24 +1300,72 @@
 
   APValue VisitCastExpr(CastExpr *E) {
     Expr* SubExpr = E->getSubExpr();
+    QualType EltType = E->getType()->getAsComplexType()->getElementType();
+    QualType SubType = SubExpr->getType();
 
-    if (SubExpr->getType()->isRealFloatingType()) {
+    if (SubType->isRealFloatingType()) {
       APFloat Result(0.0);
                      
       if (!EvaluateFloat(SubExpr, Result, Info))
         return APValue();
       
+      // Apply float conversion if necessary.
+      Result = HandleFloatToFloatCast(EltType, SubType, Result, Info.Ctx);
       return APValue(Result, 
                      APFloat(Result.getSemantics(), APFloat::fcZero, false));
-    } else if (SubExpr->getType()->isIntegerType()) {
+    } else if (SubType->isIntegerType()) {
       APSInt Result;
                      
       if (!EvaluateInteger(SubExpr, Result, Info))
         return APValue();
-      
+
+      // Apply integer conversion if necessary.
+      Result = HandleIntToIntCast(EltType, SubType, Result, Info.Ctx);
       llvm::APSInt Zero(Result.getBitWidth(), !Result.isSigned());
       Zero = 0;
       return APValue(Result, Zero);
+    } else if (const ComplexType *CT = SubType->getAsComplexType()) {
+      APValue Src;
+                     
+      if (!EvaluateComplex(SubExpr, Src, Info))
+        return APValue();
+
+      QualType SrcType = CT->getElementType();
+
+      if (Src.isComplexFloat()) {
+        if (EltType->isRealFloatingType()) {
+          return APValue(HandleFloatToFloatCast(EltType, SrcType, 
+                                                Src.getComplexFloatReal(),
+                                                Info.Ctx),
+                         HandleFloatToFloatCast(EltType, SrcType, 
+                                                Src.getComplexFloatImag(),
+                                                Info.Ctx));
+        } else {
+          return APValue(HandleFloatToIntCast(EltType, SrcType,
+                                              Src.getComplexFloatReal(),
+                                              Info.Ctx),
+                         HandleFloatToIntCast(EltType, SrcType, 
+                                              Src.getComplexFloatImag(),
+                                              Info.Ctx)); 
+        }
+      } else {
+        assert(Src.isComplexInt() && "Invalid evaluate result.");
+        if (EltType->isRealFloatingType()) {
+          return APValue(HandleIntToFloatCast(EltType, SrcType, 
+                                              Src.getComplexIntReal(),
+                                              Info.Ctx),
+                         HandleIntToFloatCast(EltType, SrcType, 
+                                              Src.getComplexIntImag(),
+                                              Info.Ctx));
+        } else {
+          return APValue(HandleIntToIntCast(EltType, SrcType,
+                                            Src.getComplexIntReal(),
+                                            Info.Ctx),
+                         HandleIntToIntCast(EltType, SrcType, 
+                                            Src.getComplexIntImag(),
+                                            Info.Ctx)); 
+        }
+      }
     }
 
     // FIXME: Handle more casts.





More information about the cfe-commits mailing list