[cfe-commits] r62387 - in /cfe/trunk: lib/CodeGen/CGExprConstant.cpp test/CodeGen/cast-to-union.c

Nuno Lopes nunoplopes at sapo.pt
Fri Jan 16 16:48:49 PST 2009


Author: nlopes
Date: Fri Jan 16 18:48:48 2009
New Revision: 62387

URL: http://llvm.org/viewvc/llvm-project?rev=62387&view=rev
Log:
add support for usage of cast to union thing with static vars

Modified:
    cfe/trunk/lib/CodeGen/CGExprConstant.cpp
    cfe/trunk/test/CodeGen/cast-to-union.c

Modified: cfe/trunk/lib/CodeGen/CGExprConstant.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExprConstant.cpp?rev=62387&r1=62386&r2=62387&view=diff

==============================================================================
--- cfe/trunk/lib/CodeGen/CGExprConstant.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGExprConstant.cpp Fri Jan 16 18:48:48 2009
@@ -61,6 +61,12 @@
   }
   
   llvm::Constant *VisitCastExpr(CastExpr* E) {
+    // GCC cast to union extension
+    if (E->getType()->isUnionType()) {
+      const llvm::Type *Ty = ConvertType(E->getType());
+      return EmitUnion(CGM.EmitConstantExpr(E->getSubExpr(), CGF), Ty);
+    }
+
     llvm::Constant *C = Visit(E->getSubExpr());
     
     return EmitConversion(C, E->getSubExpr()->getType(), E->getType());    
@@ -217,6 +223,27 @@
     return llvm::ConstantStruct::get(SType, Elts);
   }
 
+  llvm::Constant *EmitUnion(llvm::Constant *C, const llvm::Type *Ty) {
+    // Build a struct with the union sub-element as the first member,
+    // and padded to the appropriate size
+    std::vector<llvm::Constant*> Elts;
+    std::vector<const llvm::Type*> Types;
+    Elts.push_back(C);
+    Types.push_back(C->getType());
+    unsigned CurSize = CGM.getTargetData().getTypeStoreSize(C->getType());
+    unsigned TotalSize = CGM.getTargetData().getTypeStoreSize(Ty);
+    while (CurSize < TotalSize) {
+      Elts.push_back(llvm::Constant::getNullValue(llvm::Type::Int8Ty));
+      Types.push_back(llvm::Type::Int8Ty);
+      CurSize++;
+    }
+
+    // This always generates a packed struct
+    // FIXME: Try to generate an unpacked struct when we can
+    llvm::StructType* STy = llvm::StructType::get(Types, true);
+    return llvm::ConstantStruct::get(STy, Elts);
+  }
+
   llvm::Constant *EmitUnionInitialization(InitListExpr *ILE) {
     RecordDecl *RD = ILE->getType()->getAsRecordType()->getDecl();
     const llvm::Type *Ty = ConvertType(ILE->getType());
@@ -248,26 +275,7 @@
       return llvm::ConstantArray::get(RetTy, Elts);
     }
 
-    llvm::Constant *C = CGM.EmitConstantExpr(ILE->getInit(0), CGF);
-
-    // Build a struct with the union sub-element as the first member,
-    // and padded to the appropriate size
-    std::vector<llvm::Constant*> Elts;
-    std::vector<const llvm::Type*> Types;
-    Elts.push_back(C);
-    Types.push_back(C->getType());
-    unsigned CurSize = CGM.getTargetData().getTypeStoreSize(C->getType());
-    unsigned TotalSize = CGM.getTargetData().getTypeStoreSize(Ty);
-    while (CurSize < TotalSize) {
-      Elts.push_back(llvm::Constant::getNullValue(llvm::Type::Int8Ty));
-      Types.push_back(llvm::Type::Int8Ty);
-      CurSize++;
-    }
-
-    // This always generates a packed struct
-    // FIXME: Try to generate an unpacked struct when we can
-    llvm::StructType* STy = llvm::StructType::get(Types, true);
-    return llvm::ConstantStruct::get(STy, Elts);
+    return EmitUnion(CGM.EmitConstantExpr(ILE->getInit(0), CGF), Ty);
   }
 
   llvm::Constant *EmitVectorInitialization(InitListExpr *ILE) {

Modified: cfe/trunk/test/CodeGen/cast-to-union.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/cast-to-union.c?rev=62387&r1=62386&r2=62387&view=diff

==============================================================================
--- cfe/trunk/test/CodeGen/cast-to-union.c (original)
+++ cfe/trunk/test/CodeGen/cast-to-union.c Fri Jan 16 18:48:48 2009
@@ -1,10 +1,13 @@
-// RUN: clang -emit-llvm < %s | grep "store i32 351, i32*"
+// RUN: clang -emit-llvm < %s -o %t &&
+// RUN: grep "store i32 351, i32*" %t &&
+// RUN: grep "w = global <{ i32, i8, i8, i8, i8 }> <{ i32 2, i8 0, i8 0, i8 0, i8 0 }>" %t &&
+// RUN: grep "y = global <{ double }> <{ double 7.300000e+01 }>" %t
 
-union u { int i; };
+union u { int i; double d; };
 
 void foo() {
   union u ola = (union u) 351;
 }
 
-// FIXME: not working yet
-// union u w = (union u)2;
+union u w = (union u)2;
+union u y = (union u)73.0;





More information about the cfe-commits mailing list