}
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());
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());
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) {
-// 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;