From 93b122d3c484a8451024d6947be0f4037f86def0 Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Tue, 16 Mar 2010 21:25:55 +0000 Subject: reapply r98656 unmodified, which exposed the asmprinter not handling constant unions. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@98680 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/TargetData.cpp | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) (limited to 'lib/Target/TargetData.cpp') diff --git a/lib/Target/TargetData.cpp b/lib/Target/TargetData.cpp index 9a168087ae..643b397746 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(Ty))->getSizeInBits(); + case Type::UnionTyID: { + const UnionType *UnTy = cast(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(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(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(*TI)) { + unsigned FieldNo = cast(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(Ty)->getElementType(); -- cgit v1.2.3