diff options
author | Zhongxing Xu <xuzhongxing@gmail.com> | 2010-08-03 04:52:05 +0000 |
---|---|---|
committer | Zhongxing Xu <xuzhongxing@gmail.com> | 2010-08-03 04:52:05 +0000 |
commit | e888233f6b115d3b0dd73bcb5f35e93794408542 (patch) | |
tree | d74fe0616c2ba88a5b4c1799f16b268bae85d913 /lib/Checker/MemRegion.cpp | |
parent | 5ce946291c2c23ed71b112b2ba13acf11807e319 (diff) |
Pull the region offset computation logic into a single method.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@110102 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Checker/MemRegion.cpp')
-rw-r--r-- | lib/Checker/MemRegion.cpp | 96 |
1 files changed, 57 insertions, 39 deletions
diff --git a/lib/Checker/MemRegion.cpp b/lib/Checker/MemRegion.cpp index d9c559e847..87eed2a287 100644 --- a/lib/Checker/MemRegion.cpp +++ b/lib/Checker/MemRegion.cpp @@ -828,48 +828,66 @@ RegionRawOffset ElementRegion::getAsArrayOffset() const { return RegionRawOffset(superR, offset.getQuantity()); } -RegionOffset ElementRegion::getAsOffset() const { - uint64_t Offset; - if (const nonloc::ConcreteInt *CI = dyn_cast<nonloc::ConcreteInt>(&Index)) { - int64_t i = CI->getValue().getSExtValue(); - assert(i >= 0); - // We cannot compute offset for incomplete types. - if (!IsCompleteType(getContext(), ElementType)) - return RegionOffset(0); - - CharUnits Size = getContext().getTypeSizeInChars(ElementType); - Offset = i * Size.getQuantity() * 8; - } else - // We cannot compute offset for symbolic index. - return RegionOffset(0); - - // Get the offset of the super region. - RegionOffset SOffset = cast<SubRegion>(superRegion)->getAsOffset(); - if (!SOffset.getRegion()) - return RegionOffset(0); - else - return RegionOffset(SOffset.getRegion(), SOffset.getOffset() + Offset); -} - -RegionOffset FieldRegion::getAsOffset() const { - const RecordDecl *RD = getDecl()->getParent(); - assert(RD->isDefinition()); - // Get the field number. - unsigned idx = 0; - for (RecordDecl::field_iterator FI = RD->field_begin(), FE = RD->field_end(); - FI != FE; ++FI, ++idx) - if (getDecl() == *FI) +RegionOffset MemRegion::getAsOffset() const { + const MemRegion *R = this; + uint64_t Offset = 0; + + while (1) { + switch (R->getKind()) { + default: + return RegionOffset(0); + case SymbolicRegionKind: + case AllocaRegionKind: + case CompoundLiteralRegionKind: + case CXXThisRegionKind: + case StringRegionKind: + case VarRegionKind: + case CXXObjectRegionKind: + goto Finish; + case ElementRegionKind: { + const ElementRegion *ER = cast<ElementRegion>(R); + QualType EleTy = ER->getValueType(getContext()); + + if (!IsCompleteType(getContext(), EleTy)) + return RegionOffset(0); + + SVal Index = ER->getIndex(); + if (const nonloc::ConcreteInt *CI=dyn_cast<nonloc::ConcreteInt>(&Index)) { + int64_t i = CI->getValue().getSExtValue(); + assert(i >= 0); + CharUnits Size = getContext().getTypeSizeInChars(EleTy); + Offset += i * Size.getQuantity() * 8; + } else { + // We cannot compute offset for non-concrete index. + return RegionOffset(0); + } + R = ER->getSuperRegion(); break; + } + case FieldRegionKind: { + const FieldRegion *FR = cast<FieldRegion>(R); + const RecordDecl *RD = FR->getDecl()->getParent(); + if (!RD->isDefinition()) + // We cannot compute offset for incomplete type. + return RegionOffset(0); + // Get the field number. + unsigned idx = 0; + for (RecordDecl::field_iterator FI = RD->field_begin(), + FE = RD->field_end(); FI != FE; ++FI, ++idx) + if (FR->getDecl() == *FI) + break; - const ASTRecordLayout &Layout = getContext().getASTRecordLayout(RD); - // This is offset in bits. - uint64_t Offset = Layout.getFieldOffset(idx); + const ASTRecordLayout &Layout = getContext().getASTRecordLayout(RD); + // This is offset in bits. + Offset += Layout.getFieldOffset(idx); + R = FR->getSuperRegion(); + break; + } + } + } - RegionOffset SOffset = cast<SubRegion>(superRegion)->getAsOffset(); - if (!SOffset.getRegion()) - return RegionOffset(0); - else - return RegionOffset(SOffset.getRegion(), SOffset.getOffset() + Offset); + Finish: + return RegionOffset(R, Offset); } //===----------------------------------------------------------------------===// |