Use arrays as union padding. Also, since the resulting struct will always contain a single element and either a single i8 element or an array of i8s, there's no reason to use a packed struct.

llvm-svn: 76854
This commit is contained in:
Anders Carlsson 2009-07-23 04:50:01 +00:00
parent dc13b7c637
commit 718a89a501
2 changed files with 12 additions and 9 deletions

View File

@ -243,15 +243,18 @@ public:
Types.push_back(C->getType());
unsigned CurSize = CGM.getTargetData().getTypeAllocSize(C->getType());
unsigned TotalSize = CGM.getTargetData().getTypeAllocSize(Ty);
while (CurSize < TotalSize) {
Elts.push_back(VMContext.getNullValue(llvm::Type::Int8Ty));
Types.push_back(llvm::Type::Int8Ty);
CurSize++;
assert(CurSize <= TotalSize && "Union size mismatch!");
if (unsigned NumPadBytes = TotalSize - CurSize) {
const llvm::Type *Ty = llvm::Type::Int8Ty;
if (NumPadBytes > 1)
Ty = VMContext.getArrayType(Ty, NumPadBytes);
Elts.push_back(VMContext.getNullValue(Ty));
Types.push_back(Ty);
}
// This always generates a packed struct
// FIXME: Try to generate an unpacked struct when we can
llvm::StructType* STy = VMContext.getStructType(Types, true);
llvm::StructType* STy = VMContext.getStructType(Types, false);
return VMContext.getConstantStruct(STy, Elts);
}

View File

@ -1,7 +1,7 @@
// RUN: clang-cc -emit-llvm < %s -o %t &&
// RUN: grep "store i32 351, i32*" %t &&
// RUN: grep "w = global %0 <{ i32 2, i8 0, i8 0, i8 0, i8 0 }>" %t &&
// RUN: grep "y = global %1 <{ double 7.300000e+01 }>" %t
// RUN: grep "w = global %0 { i32 2, \[4 x i8\] zeroinitializer }" %t &&
// RUN: grep "y = global %1 { double 7.300000e+01 }" %t
union u { int i; double d; };