[cfe-commits] r153933 - /cfe/trunk/include/clang/Analysis/ProgramPoint.h
Ted Kremenek
kremenek at apple.com
Mon Apr 2 21:25:05 PDT 2012
Author: kremenek
Date: Mon Apr 2 23:25:05 2012
New Revision: 153933
URL: http://llvm.org/viewvc/llvm-project?rev=153933&view=rev
Log:
Rework ProgramPoint to bit-mangle the 'Kind' into both Data pointers and the LocationContext. After switching to PointerIntPair, it didn't look like a safe assumption to use the lower 3 bits of the LocationContext* field. Thanks to Jordy Rose and Benjamin Kramer for their feedback.
Modified:
cfe/trunk/include/clang/Analysis/ProgramPoint.h
Modified: cfe/trunk/include/clang/Analysis/ProgramPoint.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Analysis/ProgramPoint.h?rev=153933&r1=153932&r2=153933&view=diff
==============================================================================
--- cfe/trunk/include/clang/Analysis/ProgramPoint.h (original)
+++ cfe/trunk/include/clang/Analysis/ProgramPoint.h Mon Apr 2 23:25:05 2012
@@ -19,6 +19,7 @@
#include "clang/Analysis/CFG.h"
#include "llvm/Support/DataTypes.h"
#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/PointerIntPair.h"
#include "llvm/ADT/FoldingSet.h"
#include "llvm/Support/Casting.h"
#include "llvm/ADT/StringRef.h"
@@ -55,39 +56,25 @@
EpsilonKind};
private:
- std::pair<uintptr_t, const void *> Data;
+ llvm::PointerIntPair<const void *, 2, unsigned> Data1;
+ llvm::PointerIntPair<const void *, 2, unsigned> Data2;
// The LocationContext could be NULL to allow ProgramPoint to be used in
// context insensitive analysis.
- uintptr_t L;
+ llvm::PointerIntPair<const LocationContext *, 2, unsigned> L;
+
const ProgramPointTag *Tag;
ProgramPoint();
- static uintptr_t mangleUpperKindBits(Kind K, const void *p) {
- uintptr_t tmp = (uintptr_t) p;
- uintptr_t k_int = (uintptr_t) K;
- k_int >>= 3;
- assert((k_int & 0x3) == k_int);
- tmp |= k_int;
- return tmp;
- }
-
- static uintptr_t mangleLowerKindBits(Kind K, const void *p) {
- uintptr_t tmp = (uintptr_t) p;
- uintptr_t k_int = (uintptr_t) K;
- k_int &= 0x7;
- tmp |= k_int;
- return tmp;
- }
-
protected:
ProgramPoint(const void *P,
Kind k,
const LocationContext *l,
const ProgramPointTag *tag = 0)
- : Data(mangleUpperKindBits(k, P), static_cast<const void*>(NULL)),
- L(mangleLowerKindBits(k, l)),
+ : Data1(P, ((unsigned) k) & 0x3),
+ Data2(0, (((unsigned) k) >> 2) & 0x3),
+ L(l, (((unsigned) k) >> 4) & 0x3),
Tag(tag) {
assert(getKind() == k);
assert(getLocationContext() == l);
@@ -99,34 +86,37 @@
Kind k,
const LocationContext *l,
const ProgramPointTag *tag = 0)
- : Data(mangleUpperKindBits(k, P1), P2),
- L(mangleLowerKindBits(k, l)),
+ : Data1(P1, ((unsigned) k) & 0x3),
+ Data2(P2, (((unsigned) k) >> 2) & 0x3),
+ L(l, (((unsigned) k) >> 4) & 0x3),
Tag(tag) {}
protected:
- const void *getData1() const {
- return (void*) (Data.first & ~((uintptr_t) 0x3));
- }
-
- const void *getData2() const { return Data.second; }
- void setData2(const void *d) { Data.second = d; }
+ const void *getData1() const { return Data1.getPointer(); }
+ const void *getData2() const { return Data2.getPointer(); }
+ void setData2(const void *d) { Data2.setPointer(d); }
public:
/// Create a new ProgramPoint object that is the same as the original
/// except for using the specified tag value.
ProgramPoint withTag(const ProgramPointTag *tag) const {
- return ProgramPoint(getData1(), Data.second, getKind(),
+ return ProgramPoint(getData1(), getData2(), getKind(),
getLocationContext(), tag);
}
Kind getKind() const {
- return (Kind) (((Data.first & 0x3) << 3) | (L & 0x7));
+ unsigned x = L.getInt();
+ x <<= 2;
+ x |= Data2.getInt();
+ x <<= 2;
+ x |= Data1.getInt();
+ return (Kind) x;
}
const ProgramPointTag *getTag() const { return Tag; }
const LocationContext *getLocationContext() const {
- return (LocationContext*) (L & ~((uintptr_t) 0x7));
+ return L.getPointer();
}
// For use with DenseMap. This hash is probably slow.
@@ -139,17 +129,23 @@
static bool classof(const ProgramPoint*) { return true; }
bool operator==(const ProgramPoint & RHS) const {
- return Data == RHS.Data && L == RHS.L && Tag == RHS.Tag;
+ return Data1 == Data1 &&
+ Data2 == RHS.Data2 &&
+ L == RHS.L &&
+ Tag == RHS.Tag;
}
bool operator!=(const ProgramPoint &RHS) const {
- return Data != RHS.Data || L != RHS.L || Tag != RHS.Tag;
+ return Data1 != RHS.Data1 ||
+ Data2 != RHS.Data2 ||
+ L != RHS.L ||
+ Tag != RHS.Tag;
}
void Profile(llvm::FoldingSetNodeID& ID) const {
ID.AddInteger((unsigned) getKind());
ID.AddPointer(getData1());
- ID.AddPointer(Data.second);
+ ID.AddPointer(getData2());
ID.AddPointer(getLocationContext());
ID.AddPointer(Tag);
}
@@ -157,7 +153,6 @@
static ProgramPoint getProgramPoint(const Stmt *S, ProgramPoint::Kind K,
const LocationContext *LC,
const ProgramPointTag *tag);
-
};
class BlockEntrance : public ProgramPoint {
More information about the cfe-commits
mailing list