aboutsummaryrefslogtreecommitdiffstats
path: root/lib/Target/TargetData.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Target/TargetData.cpp')
-rw-r--r--lib/Target/TargetData.cpp25
1 files changed, 25 insertions, 0 deletions
diff --git a/lib/Target/TargetData.cpp b/lib/Target/TargetData.cpp
index 9a16808..643b397 100644
--- a/lib/Target/TargetData.cpp
+++ b/lib/Target/TargetData.cpp
@@ -460,6 +460,15 @@ uint64_t TargetData::getTypeSizeInBits(const Type *Ty) const {
case Type::StructTyID:
// Get the layout annotation... which is lazily created on demand.
return getStructLayout(cast<StructType>(Ty))->getSizeInBits();
+ case Type::UnionTyID: {
+ const UnionType *UnTy = cast<UnionType>(Ty);
+ uint64_t Size = 0;
+ for (UnionType::element_iterator i = UnTy->element_begin(),
+ e = UnTy->element_end(); i != e; ++i) {
+ Size = std::max(Size, getTypeSizeInBits(*i));
+ }
+ return Size;
+ }
case Type::IntegerTyID:
return cast<IntegerType>(Ty)->getBitWidth();
case Type::VoidTyID:
@@ -516,6 +525,17 @@ unsigned char TargetData::getAlignment(const Type *Ty, bool abi_or_pref) const {
unsigned Align = getAlignmentInfo(AGGREGATE_ALIGN, 0, abi_or_pref, Ty);
return std::max(Align, (unsigned)Layout->getAlignment());
}
+ case Type::UnionTyID: {
+ const UnionType *UnTy = cast<UnionType>(Ty);
+ unsigned Align = 1;
+
+ // Unions need the maximum alignment of all their entries
+ for (UnionType::element_iterator i = UnTy->element_begin(),
+ e = UnTy->element_end(); i != e; ++i) {
+ Align = std::max(Align, (unsigned)getAlignment(*i, abi_or_pref));
+ }
+ return Align;
+ }
case Type::IntegerTyID:
case Type::VoidTyID:
AlignType = INTEGER_ALIGN;
@@ -600,6 +620,11 @@ uint64_t TargetData::getIndexedOffset(const Type *ptrTy, Value* const* Indices,
// Update Ty to refer to current element
Ty = STy->getElementType(FieldNo);
+ } else if (const UnionType *UnTy = dyn_cast<UnionType>(*TI)) {
+ unsigned FieldNo = cast<ConstantInt>(Indices[CurIDX])->getZExtValue();
+
+ // Offset into union is canonically 0, but type changes
+ Ty = UnTy->getElementType(FieldNo);
} else {
// Update Ty to refer to current element
Ty = cast<SequentialType>(Ty)->getElementType();