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


Files: 1 Branches Taken: 8.3% 1 / 12
Generated: 2010-02-10 01:31 Branches Executed: 16.7% 2 / 12
Line Coverage: 66.7% 30 / 45


Programs: 21 Runs 46957


       1                 : //=== AnalysisContext.h - Analysis context for Path Sens 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 AnalysisContext, a class that manages the analysis context
      11                 : // data for path sensitive analysis.
      12                 : //
      13                 : //===----------------------------------------------------------------------===//
      14                 : 
      15                 : #ifndef LLVM_CLANG_ANALYSIS_ANALYSISCONTEXT_H
      16                 : #define LLVM_CLANG_ANALYSIS_ANALYSISCONTEXT_H
      17                 : 
      18                 : #include "clang/AST/Decl.h"
      19                 : #include "llvm/ADT/OwningPtr.h"
      20                 : #include "llvm/ADT/FoldingSet.h"
      21                 : #include "llvm/ADT/PointerUnion.h"
      22                 : #include "llvm/ADT/DenseMap.h"
      23                 : #include "llvm/Support/Allocator.h"
      24                 : 
      25                 : namespace clang {
      26                 : 
      27                 : class Decl;
      28                 : class Stmt;
      29                 : class CFG;
      30                 : class CFGBlock;
      31                 : class LiveVariables;
      32                 : class ParentMap;
      33                 : class ImplicitParamDecl;
      34                 : class LocationContextManager;
      35                 : class StackFrameContext;
      36                 :   
      37                 : /// AnalysisContext contains the context data for the function or method under
      38                 : /// analysis.
      39                 : class AnalysisContext {
      40                 :   const Decl *D;
      41                 : 
      42                 :   // AnalysisContext owns the following data.
      43                 :   CFG *cfg;
      44                 :   LiveVariables *liveness;
      45                 :   ParentMap *PM;
      46                 :   llvm::DenseMap<const BlockDecl*,void*> *ReferencedBlockVars;
      47                 :   llvm::BumpPtrAllocator A;
      48                 :   bool AddEHEdges;
      49                 : public:
      50            11950:   AnalysisContext(const Decl *d, bool addehedges = false)
      51                 :     : D(d), cfg(0), liveness(0), PM(0), ReferencedBlockVars(0),
      52            11950:       AddEHEdges(addehedges) {}
      53                 : 
      54                 :   ~AnalysisContext();
      55                 : 
      56             1998:   ASTContext &getASTContext() { return D->getASTContext(); }
      57            16758:   const Decl *getDecl() { return D; }
      58                 :   /// getAddEHEdges - Return true iff we are adding exceptional edges from
      59                 :   /// callExprs.  If this is false, then try/catch statements and blocks
      60                 :   /// reachable from them can appear to be dead in the CFG, analysis passes must
      61                 :   /// cope with that.
      62             3471:   bool getAddEHEdges() const { return AddEHEdges; }
      63                 :   Stmt *getBody();
      64                 :   CFG *getCFG();
      65                 :   ParentMap &getParentMap();
      66                 :   LiveVariables *getLiveVariables();
      67                 : 
      68                 :   typedef const VarDecl * const * referenced_decls_iterator;
      69                 : 
      70                 :   std::pair<referenced_decls_iterator, referenced_decls_iterator>
      71                 :     getReferencedBlockVars(const BlockDecl *BD);
      72                 :   
      73                 :   /// Return the ImplicitParamDecl* associated with 'self' if this
      74                 :   /// AnalysisContext wraps an ObjCMethodDecl.  Returns NULL otherwise.
      75                 :   const ImplicitParamDecl *getSelfDecl() const;
      76                 : };
      77                 : 
      78              188: class AnalysisContextManager {
      79                 :   typedef llvm::DenseMap<const Decl*, AnalysisContext*> ContextMap;
      80                 :   ContextMap Contexts;
      81                 : public:
      82                 :   ~AnalysisContextManager();
      83                 : 
      84                 :   AnalysisContext *getContext(const Decl *D);
      85                 :   
      86                 :   // Discard all previously created AnalysisContexts.
      87                 :   void clear();
      88                 : };
      89                 : 
      90                 : class LocationContext : public llvm::FoldingSetNode {
      91                 : public:
      92                 :   enum ContextKind { StackFrame, Scope, Block };
      93                 : 
      94                 : private:
      95                 :   ContextKind Kind;
      96                 :   AnalysisContext *Ctx;
      97                 :   const LocationContext *Parent;
      98                 : 
      99                 : protected:
     100                 :   LocationContext(ContextKind k, AnalysisContext *ctx,
     101             1946:                   const LocationContext *parent)
     102             1946:     : Kind(k), Ctx(ctx), Parent(parent) {}
     103                 : 
     104                 : public:
     105                 :   virtual ~LocationContext();
     106                 :   
     107            50178:   ContextKind getKind() const { return Kind; }
     108                 : 
     109            81395:   AnalysisContext *getAnalysisContext() const { return Ctx; }
     110                 : 
     111              219:   const LocationContext *getParent() const { return Parent; }
     112                 : 
     113            16758:   const Decl *getDecl() const { return getAnalysisContext()->getDecl(); }
     114                 : 
     115            41234:   CFG *getCFG() const { return getAnalysisContext()->getCFG(); }
     116                 : 
     117            12853:   LiveVariables *getLiveVariables() const {
     118            12853:     return getAnalysisContext()->getLiveVariables();
     119                 :   }
     120                 : 
     121             8153:   ParentMap &getParentMap() const { 
     122             8153:     return getAnalysisContext()->getParentMap();
     123                 :   }
     124                 : 
     125              214:   const ImplicitParamDecl *getSelfDecl() const {
     126              214:     return Ctx->getSelfDecl();
     127                 :   }
     128                 :   
     129                 :   const StackFrameContext *getCurrentStackFrame() const;
     130                 :   const StackFrameContext *
     131                 :     getStackFrameForDeclContext(const DeclContext *DC) const;
     132                 : 
     133                 :   virtual void Profile(llvm::FoldingSetNodeID &ID) = 0;
     134                 : 
     135                 :   static bool classof(const LocationContext*) { return true; }
     136                 : 
     137                 : public:
     138                 :   static void ProfileCommon(llvm::FoldingSetNodeID &ID,
     139                 :                             ContextKind ck,
     140                 :                             AnalysisContext *ctx,
     141                 :                             const LocationContext *parent,
     142                 :                             const void* data);
     143                 : };
     144                 : 
     145                 : class StackFrameContext : public LocationContext {
     146                 :   // The callsite where this stack frame is established.
     147                 :   const Stmt *CallSite;
     148                 : 
     149                 :   // The parent block of the callsite.
     150                 :   const CFGBlock *Block;
     151                 : 
     152                 :   // The index of the callsite in the CFGBlock.
     153                 :   unsigned Index;
     154                 : 
     155                 :   friend class LocationContextManager;
     156                 :   StackFrameContext(AnalysisContext *ctx, const LocationContext *parent,
     157             1946:                     const Stmt *s, const CFGBlock *blk, unsigned idx)
     158                 :     : LocationContext(StackFrame, ctx, parent), CallSite(s), Block(blk), 
     159             1946:       Index(idx) {}
     160                 : 
     161                 : public:
                     1946: branch 1 taken
                        0: branch 2 not taken
                        0: branch 5 not taken
                        0: branch 6 not taken
     162             1946:   ~StackFrameContext() {}
     163                 : 
     164                0:   const Stmt *getCallSite() const { return CallSite; }
     165                 : 
     166                0:   const CFGBlock *getCallSiteBlock() const { return Block; }
     167                 : 
     168                0:   unsigned getIndex() const { return Index; }
     169                 : 
     170                 :   void Profile(llvm::FoldingSetNodeID &ID);
     171                 :   
     172                 :   static void Profile(llvm::FoldingSetNodeID &ID, AnalysisContext *ctx,
     173                 :                       const LocationContext *parent, const Stmt *s, 
     174             2331:                       const CFGBlock *blk, unsigned idx) {
     175             2331:     ProfileCommon(ID, StackFrame, ctx, parent, s);
     176             2331:     ID.AddPointer(blk);
     177             2331:     ID.AddInteger(idx);
     178             2331:   }
     179                 : 
     180            50178:   static bool classof(const LocationContext* Ctx) {
     181            50178:     return Ctx->getKind() == StackFrame;
     182                 :   }
     183                 : };
     184                 : 
     185                 : class ScopeContext : public LocationContext {
     186                 :   const Stmt *Enter;
     187                 :   
     188                 :   friend class LocationContextManager;
     189                 :   ScopeContext(AnalysisContext *ctx, const LocationContext *parent,
     190                0:                const Stmt *s)
     191                0:     : LocationContext(Scope, ctx, parent), Enter(s) {}
     192                 : 
     193                 : public:
                        0: branch 1 not taken
                        0: branch 2 not taken
                        0: branch 5 not taken
                        0: branch 6 not taken
     194                0:   ~ScopeContext() {}
     195                 : 
     196                 :   void Profile(llvm::FoldingSetNodeID &ID);
     197                 : 
     198                 :   static void Profile(llvm::FoldingSetNodeID &ID, AnalysisContext *ctx,
     199                0:                       const LocationContext *parent, const Stmt *s) {
     200                0:     ProfileCommon(ID, Scope, ctx, parent, s);
     201                0:   }
     202                 : 
     203                0:   static bool classof(const LocationContext* Ctx) {
     204                0:     return Ctx->getKind() == Scope;
     205                 :   }
     206                 : };
     207                 : 
     208                 : class BlockInvocationContext : public LocationContext {
     209                 :   // FIXME: Add back context-sensivity (we don't want libAnalysis to know
     210                 :   //  about MemRegion).
     211                 :   const BlockDecl *BD;
     212                 : 
     213                 :   friend class LocationContextManager;
     214                 : 
     215                 :   BlockInvocationContext(AnalysisContext *ctx, const LocationContext *parent,
     216                 :                          const BlockDecl *bd)
     217                 :     : LocationContext(Block, ctx, parent), BD(bd) {}
     218                 : 
     219                 : public:
                        0: branch 1 not taken
                        0: branch 2 not taken
                        0: branch 5 not taken
                        0: branch 6 not taken
     220                0:   ~BlockInvocationContext() {}
     221                 : 
     222                 :   const BlockDecl *getBlockDecl() const { return BD; }
     223                 : 
     224                 :   void Profile(llvm::FoldingSetNodeID &ID);
     225                 : 
     226                 :   static void Profile(llvm::FoldingSetNodeID &ID, AnalysisContext *ctx,
     227                0:                       const LocationContext *parent, const BlockDecl *bd) {
     228                0:     ProfileCommon(ID, Block, ctx, parent, bd);
     229                0:   }
     230                 :   
     231                 :   static bool classof(const LocationContext* Ctx) {
     232                 :     return Ctx->getKind() == Block;
     233                 :   }
     234                 : };
     235                 : 
     236              188: class LocationContextManager {
     237                 :   llvm::FoldingSet<LocationContext> Contexts;
     238                 : public:
     239                 :   ~LocationContextManager();
     240                 :   
     241                 :   const StackFrameContext *getStackFrame(AnalysisContext *ctx,
     242                 :                                          const LocationContext *parent,
     243                 :                                          const Stmt *s, const CFGBlock *blk,
     244                 :                                          unsigned idx);
     245                 : 
     246                 :   const ScopeContext *getScope(AnalysisContext *ctx,
     247                 :                                const LocationContext *parent,
     248                 :                                const Stmt *s);
     249                 :   
     250                 :   /// Discard all previously created LocationContext objects.
     251                 :   void clear();
     252                 : private:
     253                 :   template <typename LOC, typename DATA>
     254                 :   const LOC *getLocationContext(AnalysisContext *ctx,
     255                 :                                 const LocationContext *parent,
     256                 :                                 const DATA *d);
     257                 : };
     258                 : 
     259                 : } // end clang namespace
     260                 : #endif

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