add support for usage of cast to union thing with static vars
llvm-svn: 62387
This commit is contained in:
parent
dee1be8e95
commit
4d78cf0fa7
|
@ -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) {
|
||||||
|
|
|
@ -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;
|
||||||
|
|
Loading…
Reference in New Issue