add support for usage of cast to union thing with static vars

llvm-svn: 62387
This commit is contained in:
Nuno Lopes 2009-01-17 00:48:48 +00:00
parent dee1be8e95
commit 4d78cf0fa7
2 changed files with 35 additions and 24 deletions

View File

@ -61,6 +61,12 @@ public:
} }
llvm::Constant *VisitCastExpr(CastExpr* E) { 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()); llvm::Constant *C = Visit(E->getSubExpr());
return EmitConversion(C, E->getSubExpr()->getType(), E->getType()); return EmitConversion(C, E->getSubExpr()->getType(), E->getType());
@ -217,6 +223,27 @@ public:
return llvm::ConstantStruct::get(SType, Elts); 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) { llvm::Constant *EmitUnionInitialization(InitListExpr *ILE) {
RecordDecl *RD = ILE->getType()->getAsRecordType()->getDecl(); RecordDecl *RD = ILE->getType()->getAsRecordType()->getDecl();
const llvm::Type *Ty = ConvertType(ILE->getType()); const llvm::Type *Ty = ConvertType(ILE->getType());
@ -248,26 +275,7 @@ public:
return llvm::ConstantArray::get(RetTy, Elts); return llvm::ConstantArray::get(RetTy, Elts);
} }
llvm::Constant *C = CGM.EmitConstantExpr(ILE->getInit(0), CGF); return EmitUnion(CGM.EmitConstantExpr(ILE->getInit(0), CGF), 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 *EmitVectorInitialization(InitListExpr *ILE) { llvm::Constant *EmitVectorInitialization(InitListExpr *ILE) {

View File

@ -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() { void foo() {
union u ola = (union u) 351; 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;