Codegen union member references.


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@43390 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/CodeGen/CGExpr.cpp b/CodeGen/CGExpr.cpp
index 1c8eda1..4c60248 100644
--- a/CodeGen/CGExpr.cpp
+++ b/CodeGen/CGExpr.cpp
@@ -385,14 +385,6 @@
 LValue CodeGenFunction::EmitMemberExpr(const MemberExpr *E) {
 
   Expr *BaseExpr = E->getBase();
-  // FIXME: Handle union members.
-  if (BaseExpr->getType()->isUnionType()) {
-    fprintf(stderr, "Unimplemented lvalue expr!\n");
-    E->dump(getContext().SourceMgr);
-    llvm::Type *Ty = llvm::PointerType::get(ConvertType(E->getType()));
-    return LValue::MakeAddr(llvm::UndefValue::get(Ty));
-  }
-
   llvm::Value *BaseValue = NULL;
   if (BaseExpr->isLvalue() == Expr::LV_Valid) {
     LValue BaseLV = EmitLValue(BaseExpr);
@@ -412,7 +404,16 @@
   llvm::Value *Idxs[2] = { llvm::Constant::getNullValue(llvm::Type::Int32Ty), 
                            llvm::ConstantInt::get(llvm::Type::Int32Ty, idx) };
 
-  return LValue::MakeAddr(Builder.CreateGEP(BaseValue,Idxs, Idxs + 2, "tmp"));
+  llvm::Value *V = Builder.CreateGEP(BaseValue,Idxs, Idxs + 2, "tmp");
+  // Match union field type.
+  if (BaseExpr->getType()->isUnionType()) {
+    const llvm::Type * FieldTy = ConvertType(Field->getType());
+    const llvm::PointerType * BaseTy = cast<llvm::PointerType>(BaseValue->getType());
+    if (FieldTy != BaseTy->getElementType()) {
+      V = Builder.CreateBitCast(V, llvm::PointerType::get(FieldTy), "tmp");
+    }
+  }
+  return LValue::MakeAddr(V);
   
   // FIXME: If record field does not have one to one match with llvm::StructType
   // field then apply appropriate masks to select only member field bits.