diff options
Diffstat (limited to 'lib/CodeGen/TargetInfo.cpp')
-rw-r--r-- | lib/CodeGen/TargetInfo.cpp | 29 |
1 files changed, 26 insertions, 3 deletions
diff --git a/lib/CodeGen/TargetInfo.cpp b/lib/CodeGen/TargetInfo.cpp index 6b262ebeda..8729da9e17 100644 --- a/lib/CodeGen/TargetInfo.cpp +++ b/lib/CodeGen/TargetInfo.cpp @@ -1226,9 +1226,24 @@ static bool BitsContainNoUserData(QualType Ty, unsigned StartBit, if (TySize <= StartBit) return true; - //if (const ConstantArrayType *AT = Context.getAsConstantArrayType(Ty)) { - // TODO. - //} + if (const ConstantArrayType *AT = Context.getAsConstantArrayType(Ty)) { + unsigned EltSize = (unsigned)Context.getTypeSize(AT->getElementType()); + unsigned NumElts = (unsigned)AT->getSize().getZExtValue(); + + // Check each element to see if the element overlaps with the queried range. + for (unsigned i = 0; i != NumElts; ++i) { + // If the element is after the span we care about, then we're done.. + unsigned EltOffset = i*EltSize; + if (EltOffset >= EndBit) break; + + unsigned EltStart = EltOffset < StartBit ? StartBit-EltOffset :0; + if (!BitsContainNoUserData(AT->getElementType(), EltStart, + EndBit-EltOffset, Context)) + return false; + } + // If it overlaps no elements, then it is safe to process as padding. + return true; + } if (const RecordType *RT = Ty->getAs<RecordType>()) { const RecordDecl *RD = RT->getDecl(); @@ -1332,6 +1347,14 @@ Get8ByteTypeAtOffset(const llvm::Type *IRType, unsigned IROffset, } } + if (const llvm::ArrayType *ATy = dyn_cast<llvm::ArrayType>(IRType)) { + const llvm::Type *EltTy = ATy->getElementType(); + unsigned EltSize = getTargetData().getTypeAllocSize(EltTy); + unsigned EltOffset = IROffset/EltSize*EltSize; + return Get8ByteTypeAtOffset(EltTy, IROffset-EltOffset, SourceTy, + SourceOffset); + } + // Okay, we don't have any better idea of what to pass, so we pass this in an // integer register that isn't too big to fit the rest of the struct. uint64_t TySizeInBytes = |