diff options
Diffstat (limited to 'include/clang/Analysis/ProgramPoint.h')
-rw-r--r-- | include/clang/Analysis/ProgramPoint.h | 84 |
1 files changed, 68 insertions, 16 deletions
diff --git a/include/clang/Analysis/ProgramPoint.h b/include/clang/Analysis/ProgramPoint.h index 57e5fc1028..4dcf92e7f2 100644 --- a/include/clang/Analysis/ProgramPoint.h +++ b/include/clang/Analysis/ProgramPoint.h @@ -55,17 +55,21 @@ public: CallExitEndKind, MinPostStmtKind = PostStmtKind, MaxPostStmtKind = CallExitEndKind, + PreImplicitCallKind, + PostImplicitCallKind, + MinImplicitCallKind = PreImplicitCallKind, + MaxImplicitCallKind = PostImplicitCallKind, EpsilonKind}; private: - llvm::PointerIntPair<const void *, 2, unsigned> Data1; + const void *Data1; llvm::PointerIntPair<const void *, 2, unsigned> Data2; // The LocationContext could be NULL to allow ProgramPoint to be used in // context insensitive analysis. llvm::PointerIntPair<const LocationContext *, 2, unsigned> L; - const ProgramPointTag *Tag; + llvm::PointerIntPair<const ProgramPointTag *, 2, unsigned> Tag; ProgramPoint(); @@ -74,10 +78,10 @@ protected: Kind k, const LocationContext *l, const ProgramPointTag *tag = 0) - : Data1(P, ((unsigned) k) & 0x3), - Data2(0, (((unsigned) k) >> 2) & 0x3), - L(l, (((unsigned) k) >> 4) & 0x3), - Tag(tag) { + : Data1(P), + Data2(0, (((unsigned) k) >> 0) & 0x3), + L(l, (((unsigned) k) >> 2) & 0x3), + Tag(tag, (((unsigned) k) >> 4) & 0x3) { assert(getKind() == k); assert(getLocationContext() == l); assert(getData1() == P); @@ -88,13 +92,13 @@ protected: Kind k, const LocationContext *l, const ProgramPointTag *tag = 0) - : Data1(P1, ((unsigned) k) & 0x3), - Data2(P2, (((unsigned) k) >> 2) & 0x3), - L(l, (((unsigned) k) >> 4) & 0x3), - Tag(tag) {} + : Data1(P1), + Data2(P2, (((unsigned) k) >> 0) & 0x3), + L(l, (((unsigned) k) >> 2) & 0x3), + Tag(tag, (((unsigned) k) >> 4) & 0x3) {} protected: - const void *getData1() const { return Data1.getPointer(); } + const void *getData1() const { return Data1; } const void *getData2() const { return Data2.getPointer(); } void setData2(const void *d) { Data2.setPointer(d); } @@ -107,11 +111,11 @@ public: } Kind getKind() const { - unsigned x = L.getInt(); + unsigned x = Tag.getInt(); x <<= 2; - x |= Data2.getInt(); + x |= L.getInt(); x <<= 2; - x |= Data1.getInt(); + x |= Data2.getInt(); return (Kind) x; } @@ -123,7 +127,7 @@ public: K == PreStmtPurgeDeadSymbolsKind); } - const ProgramPointTag *getTag() const { return Tag; } + const ProgramPointTag *getTag() const { return Tag.getPointer(); } const LocationContext *getLocationContext() const { return L.getPointer(); @@ -157,7 +161,7 @@ public: ID.AddPointer(getData1()); ID.AddPointer(getData2()); ID.AddPointer(getLocationContext()); - ID.AddPointer(Tag); + ID.AddPointer(getTag()); } static ProgramPoint getProgramPoint(const Stmt *S, ProgramPoint::Kind K, @@ -408,6 +412,54 @@ public: } }; +/// Represents an implicit call event. +/// +/// The nearest statement is provided for diagnostic purposes. +class ImplicitCallPoint : public ProgramPoint { +public: + ImplicitCallPoint(const Decl *D, SourceLocation Loc, Kind K, + const LocationContext *L, const ProgramPointTag *Tag) + : ProgramPoint(Loc.getPtrEncoding(), D, K, L, Tag) {} + + const Decl *getDecl() const { return static_cast<const Decl *>(getData2()); } + SourceLocation getLocation() const { + return SourceLocation::getFromPtrEncoding(getData1()); + } + + static bool classof(const ProgramPoint *Location) { + return Location->getKind() >= MinImplicitCallKind && + Location->getKind() <= MaxImplicitCallKind; + } +}; + +/// Represents a program point just before an implicit call event. +/// +/// Explicit calls will appear as PreStmt program points. +class PreImplicitCall : public ImplicitCallPoint { +public: + PreImplicitCall(const Decl *D, SourceLocation Loc, + const LocationContext *L, const ProgramPointTag *Tag = 0) + : ImplicitCallPoint(D, Loc, PreImplicitCallKind, L, Tag) {} + + static bool classof(const ProgramPoint *Location) { + return Location->getKind() == PreImplicitCallKind; + } +}; + +/// Represents a program point just after an implicit call event. +/// +/// Explicit calls will appear as PostStmt program points. +class PostImplicitCall : public ImplicitCallPoint { +public: + PostImplicitCall(const Decl *D, SourceLocation Loc, + const LocationContext *L, const ProgramPointTag *Tag = 0) + : ImplicitCallPoint(D, Loc, PostImplicitCallKind, L, Tag) {} + + static bool classof(const ProgramPoint *Location) { + return Location->getKind() == PostImplicitCallKind; + } +}; + /// Represents a point when we begin processing an inlined call. class CallEnter : public StmtPoint { public: |