diff options
author | Zhongxing Xu <xuzhongxing@gmail.com> | 2010-08-02 04:56:14 +0000 |
---|---|---|
committer | Zhongxing Xu <xuzhongxing@gmail.com> | 2010-08-02 04:56:14 +0000 |
commit | fd91d27630c6236f13a3da1a79db22ede762a212 (patch) | |
tree | ad1408f33e34c55564d895cba967c9c02566a039 /clang/lib/Checker/MemRegion.cpp | |
parent | 460ad41d6d2e6af29d11b3e16345123503da19c4 (diff) | |
download | bcm5719-llvm-fd91d27630c6236f13a3da1a79db22ede762a212.tar.gz bcm5719-llvm-fd91d27630c6236f13a3da1a79db22ede762a212.zip |
Improve flat store: MemRegion::getAsOffset() computes a region's offset within
the top-level object. FlatStore now can bind and retrieve element and field
regions.
PR7297 is fixed by flat store.
llvm-svn: 110020
Diffstat (limited to 'clang/lib/Checker/MemRegion.cpp')
-rw-r--r-- | clang/lib/Checker/MemRegion.cpp | 47 |
1 files changed, 46 insertions, 1 deletions
diff --git a/clang/lib/Checker/MemRegion.cpp b/clang/lib/Checker/MemRegion.cpp index 9cfeb7ae2b5..d9c559e8478 100644 --- a/clang/lib/Checker/MemRegion.cpp +++ b/clang/lib/Checker/MemRegion.cpp @@ -18,6 +18,7 @@ #include "clang/Analysis/AnalysisContext.h" #include "clang/Analysis/Support/BumpVector.h" #include "clang/AST/CharUnits.h" +#include "clang/AST/RecordLayout.h" #include "llvm/Support/raw_ostream.h" using namespace clang; @@ -785,7 +786,7 @@ static bool IsCompleteType(ASTContext &Ctx, QualType Ty) { return true; } -RegionRawOffset ElementRegion::getAsRawOffset() const { +RegionRawOffset ElementRegion::getAsArrayOffset() const { CharUnits offset = CharUnits::Zero(); const ElementRegion *ER = this; const MemRegion *superR = NULL; @@ -827,6 +828,50 @@ RegionRawOffset ElementRegion::getAsRawOffset() 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) + break; + + const ASTRecordLayout &Layout = getContext().getASTRecordLayout(RD); + // This is offset in bits. + uint64_t Offset = Layout.getFieldOffset(idx); + + RegionOffset SOffset = cast<SubRegion>(superRegion)->getAsOffset(); + if (!SOffset.getRegion()) + return RegionOffset(0); + else + return RegionOffset(SOffset.getRegion(), SOffset.getOffset() + Offset); +} + //===----------------------------------------------------------------------===// // BlockDataRegion //===----------------------------------------------------------------------===// |