aboutsummaryrefslogtreecommitdiff
path: root/lib/Checker/Store.cpp
diff options
context:
space:
mode:
authorZhongxing Xu <xuzhongxing@gmail.com>2010-02-08 07:58:06 +0000
committerZhongxing Xu <xuzhongxing@gmail.com>2010-02-08 07:58:06 +0000
commitc1511e04998e685c9e030323e248363b9633267d (patch)
tree249cce85601938f6838825e1c105151c4fb55b71 /lib/Checker/Store.cpp
parent459731d468235fa8adb27132be46a3b5654351c3 (diff)
Unify the implementation of getLValueIvar and getLValueField of store managers.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@95535 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Checker/Store.cpp')
-rw-r--r--lib/Checker/Store.cpp36
1 files changed, 36 insertions, 0 deletions
diff --git a/lib/Checker/Store.cpp b/lib/Checker/Store.cpp
index 5a8f885332..7190bdabb6 100644
--- a/lib/Checker/Store.cpp
+++ b/lib/Checker/Store.cpp
@@ -234,3 +234,39 @@ Store StoreManager::InvalidateRegions(Store store,
return store;
}
+
+SVal StoreManager::getLValueFieldOrIvar(const Decl* D, SVal Base) {
+ if (Base.isUnknownOrUndef())
+ return Base;
+
+ Loc BaseL = cast<Loc>(Base);
+ const MemRegion* BaseR = 0;
+
+ switch (BaseL.getSubKind()) {
+ case loc::MemRegionKind:
+ BaseR = cast<loc::MemRegionVal>(BaseL).getRegion();
+ break;
+
+ case loc::GotoLabelKind:
+ // These are anormal cases. Flag an undefined value.
+ return UndefinedVal();
+
+ case loc::ConcreteIntKind:
+ // While these seem funny, this can happen through casts.
+ // FIXME: What we should return is the field offset. For example,
+ // add the field offset to the integer value. That way funny things
+ // like this work properly: &(((struct foo *) 0xa)->f)
+ return Base;
+
+ default:
+ assert(0 && "Unhandled Base.");
+ return Base;
+ }
+
+ // NOTE: We must have this check first because ObjCIvarDecl is a subclass
+ // of FieldDecl.
+ if (const ObjCIvarDecl *ID = dyn_cast<ObjCIvarDecl>(D))
+ return loc::MemRegionVal(MRMgr.getObjCIvarRegion(ID, BaseR));
+
+ return loc::MemRegionVal(MRMgr.getFieldRegion(cast<FieldDecl>(D), BaseR));
+}