__real__ and __imag__ can be lvalues.  Add support to ast and codegen for them.


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@43525 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/CodeGen/CGExpr.cpp b/CodeGen/CGExpr.cpp
index a0ef03b..b996eca 100644
--- a/CodeGen/CGExpr.cpp
+++ b/CodeGen/CGExpr.cpp
@@ -283,9 +283,21 @@
   if (E->getOpcode() == UnaryOperator::Extension)
     return EmitLValue(E->getSubExpr());
   
-  assert(E->getOpcode() == UnaryOperator::Deref &&
-         "'*' is the only unary operator that produces an lvalue");
-  return LValue::MakeAddr(EmitScalarExpr(E->getSubExpr()));
+  switch (E->getOpcode()) {
+  default: assert(0 && "Unknown unary operator lvalue!");
+  case UnaryOperator::Deref:
+    return LValue::MakeAddr(EmitScalarExpr(E->getSubExpr()));
+  case UnaryOperator::Real:
+  case UnaryOperator::Imag:
+    LValue LV = EmitLValue(E->getSubExpr());
+
+    llvm::Constant *Zero = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0);
+    llvm::Constant *Idx  = llvm::ConstantInt::get(llvm::Type::Int32Ty,
+                                        E->getOpcode() == UnaryOperator::Imag);
+    llvm::Value *Ops[] = {Zero, Idx};
+    return LValue::MakeAddr(Builder.CreateGEP(LV.getAddress(), Ops, Ops+2,
+                                              "idx"));
+  }
 }
 
 LValue CodeGenFunction::EmitStringLiteralLValue(const StringLiteral *E) {