The FP constant evaluator was missing a few cases of unary operators that return floats
but whose operand isn't a float:  specifically, __real__ and __imag__.  Instead
of filtering these out, just implement them.

Fixes <rdar://problem/7958272>.

llvm-svn: 103307
diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp
index 30eaae1..e53804c8 100644
--- a/clang/lib/AST/ExprConstant.cpp
+++ b/clang/lib/AST/ExprConstant.cpp
@@ -1703,9 +1703,11 @@
     { return Visit(E->getChosenSubExpr(Info.Ctx)); }
   bool VisitUnaryExtension(const UnaryOperator *E)
     { return Visit(E->getSubExpr()); }
+  bool VisitUnaryReal(const UnaryOperator *E);
+  bool VisitUnaryImag(const UnaryOperator *E);
 
-  // FIXME: Missing: __real__/__imag__, array subscript of vector,
-  //                 member of vector, ImplicitValueInitExpr
+  // FIXME: Missing: array subscript of vector, member of vector,
+  //                 ImplicitValueInitExpr
 };
 } // end anonymous namespace
 
@@ -1791,6 +1793,22 @@
   }
 }
 
+bool FloatExprEvaluator::VisitUnaryReal(const UnaryOperator *E) {
+  ComplexValue CV;
+  if (!EvaluateComplex(E->getSubExpr(), CV, Info))
+    return false;
+  Result = CV.FloatReal;
+  return true;
+}
+
+bool FloatExprEvaluator::VisitUnaryImag(const UnaryOperator *E) {
+  ComplexValue CV;
+  if (!EvaluateComplex(E->getSubExpr(), CV, Info))
+    return false;
+  Result = CV.FloatImag;
+  return true;
+}
+
 bool FloatExprEvaluator::VisitUnaryOperator(const UnaryOperator *E) {
   if (E->getOpcode() == UnaryOperator::Deref)
     return false;