zcov: / include/clang/Analysis/ProgramPoint.h


Files: 1 Branches Taken: 77.8% 14 / 18
Generated: 2010-02-10 01:31 Branches Executed: 94.4% 17 / 18
Line Coverage: 91.4% 85 / 93


Programs: 17 Runs 43697


       1                 : //==- ProgramPoint.h - Program Points for Path-Sensitive Analysis --*- C++ -*-//
       2                 : //
       3                 : //                     The LLVM Compiler Infrastructure
       4                 : //
       5                 : // This file is distributed under the University of Illinois Open Source
       6                 : // License. See LICENSE.TXT for details.
       7                 : //
       8                 : //===----------------------------------------------------------------------===//
       9                 : //
      10                 : //  This file defines the interface ProgramPoint, which identifies a
      11                 : //  distinct location in a function.
      12                 : //
      13                 : //===----------------------------------------------------------------------===//
      14                 : 
      15                 : #ifndef LLVM_CLANG_ANALYSIS_PROGRAM_POINT
      16                 : #define LLVM_CLANG_ANALYSIS_PROGRAM_POINT
      17                 : 
      18                 : #include "clang/Analysis/CFG.h"
      19                 : #include "llvm/System/DataTypes.h"
      20                 : #include "llvm/ADT/DenseMap.h"
      21                 : #include "llvm/ADT/FoldingSet.h"
      22                 : #include "llvm/Support/Casting.h"
      23                 : #include <cassert>
      24                 : #include <utility>
      25                 : 
      26                 : namespace clang {
      27                 : 
      28                 : class LocationContext;
      29                 : 
      30           130560: class ProgramPoint {
      31                 : public:
      32                 :   enum Kind { BlockEdgeKind,
      33                 :               BlockEntranceKind,
      34                 :               BlockExitKind,
      35                 :               PreStmtKind,
      36                 :               PostStmtKind,
      37                 :               PreLoadKind,
      38                 :               PostLoadKind,
      39                 :               PreStoreKind,
      40                 :               PostStoreKind,
      41                 :               PostPurgeDeadSymbolsKind,
      42                 :               PostStmtCustomKind,
      43                 :               PostLValueKind,
      44                 :               MinPostStmtKind = PostStmtKind,
      45                 :               MaxPostStmtKind = PostLValueKind };
      46                 : 
      47                 : private:
      48                 :   std::pair<const void *, const void *> Data;
      49                 :   Kind K;
      50                 : 
      51                 :   // The LocationContext could be NULL to allow ProgramPoint to be used in
      52                 :   // context insensitive analysis.
      53                 :   const LocationContext *L;
      54                 :   const void *Tag;
      55                 : 
      56                 : protected:
      57                 :   ProgramPoint(const void* P, Kind k, const LocationContext *l,
      58           221900:                const void *tag = 0)
      59           221900:     : Data(P, NULL), K(k), L(l), Tag(tag) {}
      60                 : 
      61                 :   ProgramPoint(const void* P1, const void* P2, Kind k, const LocationContext *l,
      62            87570:                const void *tag = 0)
      63            87570:     : Data(P1, P2), K(k), L(l), Tag(tag) {}
      64                 : 
      65                 : protected:
      66            62634:   const void* getData1() const { return Data.first; }
      67            10301:   const void* getData2() const { return Data.second; }
      68                 :   const void *getTag() const { return Tag; }
      69                 : 
      70                 : public:
      71           132343:   Kind getKind() const { return K; }
      72                 : 
      73           148555:   const LocationContext *getLocationContext() const { return L; }
      74                 : 
      75                 :   // For use with DenseMap.  This hash is probably slow.
      76            39017:   unsigned getHashValue() const {
      77            39017:     llvm::FoldingSetNodeID ID;
      78            39017:     Profile(ID);
      79            39017:     return ID.ComputeHash();
      80                 :   }
      81                 : 
      82                 :   static bool classof(const ProgramPoint*) { return true; }
      83                 : 
      84           344973:   bool operator==(const ProgramPoint & RHS) const {
                   182020: branch 0 taken
                   162953: branch 1 taken
                   177237: branch 3 taken
                     4783: branch 4 taken
                   177237: branch 5 taken
                        0: branch 6 not taken
                   177123: branch 7 taken
                      114: branch 8 taken
      85           344973:     return K == RHS.K && Data == RHS.Data && L == RHS.L && Tag == RHS.Tag;
      86                 :   }
      87                 : 
      88                 :   bool operator!=(const ProgramPoint& RHS) const {
      89                 :     return K != RHS.K || Data != RHS.Data || L != RHS.L || Tag != RHS.Tag;
      90                 :   }
      91                 : 
      92           163693:   void Profile(llvm::FoldingSetNodeID& ID) const {
      93           163693:     ID.AddInteger((unsigned) K);
      94           163693:     ID.AddPointer(Data.first);
      95           163693:     ID.AddPointer(Data.second);
      96           163693:     ID.AddPointer(L);
      97           163693:     ID.AddPointer(Tag);
      98           163693:   }
      99                 : };
     100                 : 
     101                 : class BlockEntrance : public ProgramPoint {
     102                 : public:
     103                 :   BlockEntrance(const CFGBlock* B, const LocationContext *L,
     104           221900:                 const void *tag = 0)
     105           221900:     : ProgramPoint(B, BlockEntranceKind, L, tag) {}
     106                 : 
     107            20469:   CFGBlock* getBlock() const {
     108            20469:     return const_cast<CFGBlock*>(reinterpret_cast<const CFGBlock*>(getData1()));
     109                 :   }
     110                 : 
     111             7376:   CFGElement getFirstElement() const {
     112             7376:     const CFGBlock* B = getBlock();
                     7146: branch 2 taken
                        0: branch 2 not taken
     113             7376:     return B->empty() ? CFGElement() : B->front();
     114                 :   }
     115                 :   
     116              832:   Stmt *getFirstStmt() const {
     117              832:     return getFirstElement().getStmt();
     118                 :   }
     119                 : 
     120            14667:   static bool classof(const ProgramPoint* Location) {
     121            14667:     return Location->getKind() == BlockEntranceKind;
     122                 :   }
     123                 : };
     124                 : 
     125                 : class BlockExit : public ProgramPoint {
     126                 : public:
     127                 :   BlockExit(const CFGBlock* B, const LocationContext *L)
     128                 :     : ProgramPoint(B, BlockExitKind, L) {}
     129                 : 
     130                 :   CFGBlock* getBlock() const {
     131                 :     return const_cast<CFGBlock*>(reinterpret_cast<const CFGBlock*>(getData1()));
     132                 :   }
     133                 : 
     134                 :   Stmt* getLastStmt() const {
     135                 :     const CFGBlock* B = getBlock();
     136                 :     return B->empty() ? CFGElement() : B->back();
     137                 :   }
     138                 : 
     139                 :   Stmt* getTerminator() const {
     140                 :     return getBlock()->getTerminator();
     141                 :   }
     142                 : 
     143                 :   static bool classof(const ProgramPoint* Location) {
     144                 :     return Location->getKind() == BlockExitKind;
     145                 :   }
     146                 : };
     147                 : 
     148                 : class StmtPoint : public ProgramPoint {
     149                 : public:
     150                 :   StmtPoint(const Stmt *S, const void *p2, Kind k, const LocationContext *L,
     151            48069:             const void *tag)
     152            48069:     : ProgramPoint(S, p2, k, L, tag) {}
     153                 : 
     154            41003:   const Stmt *getStmt() const { return (const Stmt*) getData1(); }
     155                 : 
     156                 :   template <typename T>
     157              993:   const T* getStmtAs() const { return llvm::dyn_cast<T>(getStmt()); }
     158                 : 
     159             3107:   static bool classof(const ProgramPoint* Location) {
     160             3107:     unsigned k = Location->getKind();
                     2968: branch 0 taken
                      139: branch 1 taken
                     2968: branch 2 taken
                        0: branch 3 not taken
     161             3107:     return k >= PreStmtKind && k <= MaxPostStmtKind;
     162                 :   }
     163                 : };
     164                 : 
     165                 : 
     166                 : class PreStmt : public StmtPoint {
     167                 : public:
     168                 :   PreStmt(const Stmt *S, const LocationContext *L, const void *tag,
     169              185:           const Stmt *SubStmt = 0)
     170              185:     : StmtPoint(S, SubStmt, PreStmtKind, L, tag) {}
     171                 : 
     172                 :   const Stmt *getSubStmt() const { return (const Stmt*) getData2(); }
     173                 : 
     174                0:   static bool classof(const ProgramPoint* Location) {
     175                0:     return Location->getKind() == PreStmtKind;
     176                 :   }
     177                 : };
     178                 : 
     179                 : class PostStmt : public StmtPoint {
     180                 : protected:
     181            16044:   PostStmt(const Stmt* S, Kind k, const LocationContext *L, const void *tag = 0)
     182            16044:     : StmtPoint(S, NULL, k, L, tag) {}
     183                 : 
     184                 :   PostStmt(const Stmt* S, const void* data, Kind k, const LocationContext *L,
     185               14:            const void *tag =0)
     186               14:     : StmtPoint(S, data, k, L, tag) {}
     187                 : 
     188                 : public:
     189            28931:   explicit PostStmt(const Stmt* S, const LocationContext *L,const void *tag = 0)
     190            28931:     : StmtPoint(S, NULL, PostStmtKind, L, tag) {}
     191                 : 
     192            68419:   static bool classof(const ProgramPoint* Location) {
     193            68419:     unsigned k = Location->getKind();
                    67654: branch 0 taken
                      765: branch 1 taken
                    67654: branch 2 taken
                        0: branch 3 not taken
     194            68419:     return k >= MinPostStmtKind && k <= MaxPostStmtKind;
     195                 :   }
     196                 : };
     197                 : 
     198                 : class PostStmtCustom : public PostStmt {
     199                 : public:
     200                 :   PostStmtCustom(const Stmt* S,
     201                 :                  const std::pair<const void*, const void*>* TaggedData,\
     202               14:                  const LocationContext *L)
     203               14:     : PostStmt(S, TaggedData, PostStmtCustomKind, L) {}
     204                 : 
     205                 :   const std::pair<const void*, const void*>& getTaggedPair() const {
     206                 :     return
     207                 :       *reinterpret_cast<const std::pair<const void*, const void*>*>(getData2());
     208                 :   }
     209                 : 
     210                 :   const void* getTag() const { return getTaggedPair().first; }
     211                 : 
     212                 :   const void* getTaggedData() const { return getTaggedPair().second; }
     213                 : 
     214                 :   static bool classof(const ProgramPoint* Location) {
     215                 :     return Location->getKind() == PostStmtCustomKind;
     216                 :   }
     217                 : };
     218                 : 
     219                 :   
     220                 : class LocationCheck : public StmtPoint {
     221                 : protected:
     222                 :   LocationCheck(const Stmt *S, const LocationContext *L,
     223             2895:                 ProgramPoint::Kind K, const void *tag)
     224             2895:     : StmtPoint(S, NULL, K, L, tag) {}
     225                 :     
     226                 :   static bool classof(const ProgramPoint *location) {
     227                 :     unsigned k = location->getKind();
     228                 :     return k == PreLoadKind || k == PreStoreKind;
     229                 :   }
     230                 : };
     231                 :   
     232                 : class PreLoad : public LocationCheck {
     233                 : public:
     234              429:   PreLoad(const Stmt *S, const LocationContext *L, const void *tag = 0)
     235              429:     : LocationCheck(S, L, PreLoadKind, tag) {}
     236                 :   
     237                 :   static bool classof(const ProgramPoint *location) {
     238                 :     return location->getKind() == PreLoadKind;
     239                 :   }
     240                 : };
     241                 : 
     242                 : class PreStore : public LocationCheck {
     243                 : public:
     244             2466:   PreStore(const Stmt *S, const LocationContext *L, const void *tag = 0)
     245             2466:   : LocationCheck(S, L, PreStoreKind, tag) {}
     246                 :   
     247                 :   static bool classof(const ProgramPoint *location) {
     248                 :     return location->getKind() == PreStoreKind;
     249                 :   }
     250                 : };
     251                 : 
     252                 : class PostLoad : public PostStmt {
     253                 : public:
     254             7942:   PostLoad(const Stmt* S, const LocationContext *L, const void *tag = 0)
     255             7942:     : PostStmt(S, PostLoadKind, L, tag) {}
     256                 : 
     257                0:   static bool classof(const ProgramPoint* Location) {
     258                0:     return Location->getKind() == PostLoadKind;
     259                 :   }
     260                 : };
     261                 : 
     262                 : class PostStore : public PostStmt {
     263                 : public:
     264             2212:   PostStore(const Stmt* S, const LocationContext *L, const void *tag = 0)
     265             2212:     : PostStmt(S, PostStoreKind, L, tag) {}
     266                 : 
     267                0:   static bool classof(const ProgramPoint* Location) {
     268                0:     return Location->getKind() == PostStoreKind;
     269                 :   }
     270                 : };
     271                 : 
     272                 : class PostLValue : public PostStmt {
     273                 : public:
     274             4980:   PostLValue(const Stmt* S, const LocationContext *L, const void *tag = 0)
     275             4980:     : PostStmt(S, PostLValueKind, L, tag) {}
     276                 : 
     277                0:   static bool classof(const ProgramPoint* Location) {
     278                0:     return Location->getKind() == PostLValueKind;
     279                 :   }
     280                 : };
     281                 : 
     282                 : class PostPurgeDeadSymbols : public PostStmt {
     283                 : public:
     284                 :   PostPurgeDeadSymbols(const Stmt* S, const LocationContext *L,
     285              910:                        const void *tag = 0)
     286              910:     : PostStmt(S, PostPurgeDeadSymbolsKind, L, tag) {}
     287                 : 
     288                 :   static bool classof(const ProgramPoint* Location) {
     289                 :     return Location->getKind() == PostPurgeDeadSymbolsKind;
     290                 :   }
     291                 : };
     292                 : 
     293                 : class BlockEdge : public ProgramPoint {
     294                 : public:
     295            39501:   BlockEdge(const CFGBlock* B1, const CFGBlock* B2, const LocationContext *L)
     296            39501:     : ProgramPoint(B1, B2, BlockEdgeKind, L) {}
     297                 : 
     298             1162:   CFGBlock* getSrc() const {
     299             1162:     return const_cast<CFGBlock*>(static_cast<const CFGBlock*>(getData1()));
     300                 :   }
     301                 : 
     302            10301:   CFGBlock* getDst() const {
     303            10301:     return const_cast<CFGBlock*>(static_cast<const CFGBlock*>(getData2()));
     304                 :   }
     305                 : 
     306            18820:   static bool classof(const ProgramPoint* Location) {
     307            18820:     return Location->getKind() == BlockEdgeKind;
     308                 :   }
     309                 : };
     310                 : 
     311                 : 
     312                 : } // end namespace clang
     313                 : 
     314                 : 
     315                 : namespace llvm { // Traits specialization for DenseMap
     316                 : 
     317                 : template <> struct DenseMapInfo<clang::ProgramPoint> {
     318                 : 
     319           111466: static inline clang::ProgramPoint getEmptyKey() {
     320                 :   uintptr_t x =
     321           111466:    reinterpret_cast<uintptr_t>(DenseMapInfo<void*>::getEmptyKey()) & ~0x7;
     322           111466:   return clang::BlockEntrance(reinterpret_cast<clang::CFGBlock*>(x), 0);
     323                 : }
     324                 : 
     325           101281: static inline clang::ProgramPoint getTombstoneKey() {
     326                 :   uintptr_t x =
     327           101281:    reinterpret_cast<uintptr_t>(DenseMapInfo<void*>::getTombstoneKey()) & ~0x7;
     328           101281:   return clang::BlockEntrance(reinterpret_cast<clang::CFGBlock*>(x), 0);
     329                 : }
     330                 : 
     331            39017: static unsigned getHashValue(const clang::ProgramPoint& Loc) {
     332            39017:   return Loc.getHashValue();
     333                 : }
     334                 : 
     335                 : static bool isEqual(const clang::ProgramPoint& L,
     336           333526:                     const clang::ProgramPoint& R) {
     337           333526:   return L == R;
     338                 : }
     339                 : 
     340                 : };
     341                 :   
     342                 : template <>
     343                 : struct isPodLike<clang::ProgramPoint> { static const bool value = true; };
     344                 : 
     345                 : } // end namespace llvm
     346                 : 
     347                 : #endif

Generated: 2010-02-10 01:31 by zcov