[cfe-commits] r43390 - in /cfe/trunk: CodeGen/CGExpr.cpp CodeGen/CodeGenTypes.cpp test/CodeGen/union.c

Devang Patel dpatel at apple.com
Fri Oct 26 12:42:18 PDT 2007


Author: dpatel
Date: Fri Oct 26 14:42:18 2007
New Revision: 43390

URL: http://llvm.org/viewvc/llvm-project?rev=43390&view=rev
Log:
Codegen union member references.

Added:
    cfe/trunk/test/CodeGen/union.c
Modified:
    cfe/trunk/CodeGen/CGExpr.cpp
    cfe/trunk/CodeGen/CodeGenTypes.cpp

Modified: cfe/trunk/CodeGen/CGExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/CodeGen/CGExpr.cpp?rev=43390&r1=43389&r2=43390&view=diff

==============================================================================
--- cfe/trunk/CodeGen/CGExpr.cpp (original)
+++ cfe/trunk/CodeGen/CGExpr.cpp Fri Oct 26 14:42:18 2007
@@ -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.

Modified: cfe/trunk/CodeGen/CodeGenTypes.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/CodeGen/CodeGenTypes.cpp?rev=43390&r1=43389&r2=43390&view=diff

==============================================================================
--- cfe/trunk/CodeGen/CodeGenTypes.cpp (original)
+++ cfe/trunk/CodeGen/CodeGenTypes.cpp Fri Oct 26 14:42:18 2007
@@ -258,13 +258,15 @@
       const RecordDecl *RD = cast<const RecordDecl>(TD);
       // Just use the largest element of the union, breaking ties with the
       // highest aligned member.
-      std::vector<const llvm::Type*> Fields;
+
       if (RD->getNumMembers() != 0) {
         std::pair<uint64_t, unsigned> MaxElt = 
           Context.getTypeInfo(RD->getMember(0)->getType(), SourceLocation());
         unsigned MaxEltNo = 0;
-        
+        addFieldInfo(RD->getMember(0), 0); // Each field gets first slot.
+        // FIXME : Move union field handling in RecordOrganize
         for (unsigned i = 1, e = RD->getNumMembers(); i != e; ++i) {
+          addFieldInfo(RD->getMember(i), 0); // Each field gets first slot.
           std::pair<uint64_t, unsigned> EltInfo = 
             Context.getTypeInfo(RD->getMember(i)->getType(), SourceLocation());
           if (EltInfo.first > MaxElt.first ||
@@ -274,10 +276,19 @@
             MaxEltNo = i;
           }
         }
-        
-        Fields.push_back(ConvertType(RD->getMember(MaxEltNo)->getType()));
-      }        
-      ResultType = llvm::StructType::get(Fields);
+
+        RecordOrganizer RO;
+        RO.addField(RD->getMember(MaxEltNo));
+        RO.layoutFields(*this);
+
+        // Get llvm::StructType.
+        RecordLayoutInfo *RLI = new RecordLayoutInfo(RO.getLLVMType());
+        ResultType = RLI->getLLVMType();
+        RecordLayouts[ResultType] = RLI;
+      } else {       
+        std::vector<const llvm::Type*> Fields;
+        ResultType = llvm::StructType::get(Fields);
+      }
     } else {
       assert(0 && "FIXME: Implement tag decl kind!");
     }

Added: cfe/trunk/test/CodeGen/union.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/union.c?rev=43390&view=auto

==============================================================================
--- cfe/trunk/test/CodeGen/union.c (added)
+++ cfe/trunk/test/CodeGen/union.c Fri Oct 26 14:42:18 2007
@@ -0,0 +1,18 @@
+// RUN: clang %s -emit-llvm
+
+union {
+  int a;
+  float b;
+} u;
+
+void f() {
+  u.b = 11;
+}
+
+int f2( float __x ) { 
+  union{ 
+    float __f; 
+    unsigned int __u; 
+  }__u;
+  return (int)(__u.__u >> 31); 
+}





More information about the cfe-commits mailing list