zcov: / lib/Analysis/AnalysisContext.cpp


Files: 1 Branches Taken: 71.9% 69 / 96
Generated: 2010-02-10 01:31 Branches Executed: 77.1% 74 / 96
Line Coverage: 84.0% 126 / 150


Programs: 2 Runs 3018


       1                 : //== AnalysisContext.cpp - 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                 : #include "clang/Analysis/CFG.h"
      16                 : #include "clang/Analysis/AnalysisContext.h"
      17                 : #include "clang/Analysis/Analyses/LiveVariables.h"
      18                 : #include "clang/AST/Decl.h"
      19                 : #include "clang/AST/DeclObjC.h"
      20                 : #include "clang/AST/DeclTemplate.h"
      21                 : #include "clang/AST/ParentMap.h"
      22                 : #include "clang/AST/StmtVisitor.h"
      23                 : #include "clang/Analysis/Support/BumpVector.h"
      24                 : #include "llvm/Support/ErrorHandling.h"
      25                 : 
      26                 : using namespace clang;
      27                 : 
      28             2016: void AnalysisContextManager::clear() {
                     1827: branch 5 taken
                     2016: branch 6 taken
      29             3843:   for (ContextMap::iterator I = Contexts.begin(), E = Contexts.end(); I!=E; ++I)
                     1827: branch 1 taken
                        0: branch 2 not taken
      30             1827:     delete I->second;
      31             2016:   Contexts.clear();
      32             2016: }
      33                 : 
      34             6251: Stmt *AnalysisContext::getBody() {
                     5399: branch 1 taken
                      852: branch 2 taken
      35             6251:   if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
      36             5399:     return FD->getBody();
                      788: branch 1 taken
                       64: branch 2 taken
      37              852:   else if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
      38              788:     return MD->getBody();
                       64: branch 1 taken
                        0: branch 2 not taken
      39               64:   else if (const BlockDecl *BD = dyn_cast<BlockDecl>(D))
      40               64:     return BD->getBody();
                        0: branch 0 not taken
                        0: branch 1 not taken
      41                0:   else if (const FunctionTemplateDecl *FunTmpl
      42                0:            = dyn_cast_or_null<FunctionTemplateDecl>(D))
      43                0:     return FunTmpl->getTemplatedDecl()->getBody();
      44                 : 
      45                0:   llvm_unreachable("unknown code decl");
      46                 : }
      47                 : 
      48              214: const ImplicitParamDecl *AnalysisContext::getSelfDecl() const {
                      214: branch 1 taken
                        0: branch 2 not taken
      49              214:   if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
      50              214:     return MD->getSelfDecl();
      51                 : 
      52                0:   return NULL;
      53                 : }
      54                 : 
      55            60682: CFG *AnalysisContext::getCFG() {
                     5486: branch 0 taken
                    55196: branch 1 taken
      56            60682:   if (!cfg)
      57             5486:     cfg = CFG::buildCFG(D, getBody(), &D->getASTContext(), AddEHEdges);
      58            60682:   return cfg;
      59                 : }
      60                 : 
      61             8405: ParentMap &AnalysisContext::getParentMap() {
                      765: branch 0 taken
                     7640: branch 1 taken
      62             8405:   if (!PM)
      63              765:     PM = new ParentMap(getBody());
      64             8405:   return *PM;
      65                 : }
      66                 : 
      67            15243: LiveVariables *AnalysisContext::getLiveVariables() {
                     1998: branch 0 taken
                    13245: branch 1 taken
      68            15243:   if (!liveness) {
      69             1998:     CFG *c = getCFG();
                        0: branch 0 not taken
                     1998: branch 1 taken
      70             1998:     if (!c)
      71                0:       return 0;
      72                 : 
      73             1998:     liveness = new LiveVariables(*this);
      74             1998:     liveness->runOnCFG(*c);
      75             1998:     liveness->runOnAllBlocks(*c, 0, true);
      76                 :   }
      77                 : 
      78            15243:   return liveness;
      79                 : }
      80                 : 
      81             5044: AnalysisContext *AnalysisContextManager::getContext(const Decl *D) {
      82             5044:   AnalysisContext *&AC = Contexts[D];
                     2006: branch 0 taken
                     3038: branch 1 taken
      83             5044:   if (!AC)
      84             2006:     AC = new AnalysisContext(D);
      85                 : 
      86             5044:   return AC;
      87                 : }
      88                 : 
      89                 : //===----------------------------------------------------------------------===//
      90                 : // FoldingSet profiling.
      91                 : //===----------------------------------------------------------------------===//
      92                 : 
      93                 : void LocationContext::ProfileCommon(llvm::FoldingSetNodeID &ID,
      94                 :                                     ContextKind ck,
      95                 :                                     AnalysisContext *ctx,
      96                 :                                     const LocationContext *parent,
      97             2331:                                     const void* data) {
      98             2331:   ID.AddInteger(ck);
      99             2331:   ID.AddPointer(ctx);
     100             2331:   ID.AddPointer(parent);
     101             2331:   ID.AddPointer(data);
     102             2331: }
     103                 : 
     104              193: void StackFrameContext::Profile(llvm::FoldingSetNodeID &ID) {
     105              193:   Profile(ID, getAnalysisContext(), getParent(), CallSite, Block, Index);
     106              193: }
     107                 : 
     108                0: void ScopeContext::Profile(llvm::FoldingSetNodeID &ID) {
     109                0:   Profile(ID, getAnalysisContext(), getParent(), Enter);
     110                0: }
     111                 : 
     112                0: void BlockInvocationContext::Profile(llvm::FoldingSetNodeID &ID) {
     113                0:   Profile(ID, getAnalysisContext(), getParent(), BD);
     114                0: }
     115                 : 
     116                 : //===----------------------------------------------------------------------===//
     117                 : // LocationContext creation.
     118                 : //===----------------------------------------------------------------------===//
     119                 : 
     120                 : template <typename LOC, typename DATA>
     121                 : const LOC*
     122                 : LocationContextManager::getLocationContext(AnalysisContext *ctx,
     123                 :                                            const LocationContext *parent,
     124                0:                                            const DATA *d) {
     125                0:   llvm::FoldingSetNodeID ID;
     126                0:   LOC::Profile(ID, ctx, parent, d);
     127                 :   void *InsertPos;
     128                 :   
     129                0:   LOC *L = cast_or_null<LOC>(Contexts.FindNodeOrInsertPos(ID, InsertPos));
     130                 :   
                        0: branch 0 not taken
                        0: branch 1 not taken
     131                0:   if (!L) {
     132                0:     L = new LOC(ctx, parent, d);
                        0: branch 0 not taken
                        0: branch 1 not taken
     133                0:     Contexts.InsertNode(L, InsertPos);
     134                 :   }
     135                0:   return L;
     136                 : }
     137                 : 
     138                 : const StackFrameContext*
     139                 : LocationContextManager::getStackFrame(AnalysisContext *ctx,
     140                 :                                       const LocationContext *parent,
     141                 :                                       const Stmt *s, const CFGBlock *blk,
     142             2138:                                       unsigned idx) {
     143             2138:   llvm::FoldingSetNodeID ID;
     144             2138:   StackFrameContext::Profile(ID, ctx, parent, s, blk, idx);
     145                 :   void *InsertPos;
     146                 :   StackFrameContext *L = 
     147             2138:    cast_or_null<StackFrameContext>(Contexts.FindNodeOrInsertPos(ID, InsertPos));
                     1946: branch 0 taken
                      192: branch 1 taken
     148             2138:   if (!L) {
     149             1946:     L = new StackFrameContext(ctx, parent, s, blk, idx);
                     1946: branch 0 taken
                        0: branch 1 not taken
     150             1946:     Contexts.InsertNode(L, InsertPos);
     151                 :   }
     152             2138:   return L;
     153                 : }
     154                 : 
     155                 : const ScopeContext *
     156                 : LocationContextManager::getScope(AnalysisContext *ctx,
     157                 :                                  const LocationContext *parent,
     158                0:                                  const Stmt *s) {
     159                0:   return getLocationContext<ScopeContext, Stmt>(ctx, parent, s);
     160                 : }
     161                 : 
     162                 : //===----------------------------------------------------------------------===//
     163                 : // LocationContext methods.
     164                 : //===----------------------------------------------------------------------===//
     165                 : 
     166            12003: const StackFrameContext *LocationContext::getCurrentStackFrame() const {
     167            12003:   const LocationContext *LC = this;
                    12003: branch 0 taken
                        0: branch 1 not taken
     168            24006:   while (LC) {
                    12003: branch 1 taken
                        0: branch 2 not taken
     169            12003:     if (const StackFrameContext *SFC = dyn_cast<StackFrameContext>(LC))
     170            12003:       return SFC;
     171                0:     LC = LC->getParent();
     172                 :   }
     173                0:   return NULL;
     174                 : }
     175                 : 
     176                 : const StackFrameContext *
     177            12894: LocationContext::getStackFrameForDeclContext(const DeclContext *DC) const {
     178            12894:   const LocationContext *LC = this;
                    12894: branch 0 taken
                       26: branch 1 taken
     179            25814:   while (LC) {
                    12894: branch 1 taken
                        0: branch 2 not taken
     180            12894:     if (const StackFrameContext *SFC = dyn_cast<StackFrameContext>(LC)) {
                    12868: branch 2 taken
                       26: branch 3 taken
     181            12894:       if (cast<DeclContext>(SFC->getDecl()) == DC)
     182            12868:         return SFC;
     183                 :     }
     184               26:     LC = LC->getParent();
     185                 :   }
     186               26:   return NULL;
     187                 : }
     188                 : 
     189                 : //===----------------------------------------------------------------------===//
     190                 : // Lazily generated map to query the external variables referenced by a Block.
     191                 : //===----------------------------------------------------------------------===//
     192                 : 
     193                 : namespace {
     194               73: class FindBlockDeclRefExprsVals : public StmtVisitor<FindBlockDeclRefExprsVals>{
     195                 :   BumpVector<const VarDecl*> &BEVals;
     196                 :   BumpVectorContext &BC;
     197                 :   llvm::DenseMap<const VarDecl*, unsigned> Visited;
     198                 : public:
     199                 :   FindBlockDeclRefExprsVals(BumpVector<const VarDecl*> &bevals,
     200               73:                             BumpVectorContext &bc)
     201               73:   : BEVals(bevals), BC(bc) {}
     202                 :   
     203              373:   void VisitStmt(Stmt *S) {
                      435: branch 4 taken
                      373: branch 5 taken
     204              808:     for (Stmt::child_iterator I = S->child_begin(), E = S->child_end();I!=E;++I)
                      426: branch 1 taken
                        9: branch 2 taken
     205              435:       if (Stmt *child = *I)
     206              426:         Visit(child);
     207              373:   }
     208                 : 
     209               45:   void VisitDeclRefExpr(const DeclRefExpr *DR) {
     210                 :     // Non-local variables are also directly modified.
                       21: branch 2 taken
                       24: branch 3 taken
     211               45:     if (const VarDecl *VD = dyn_cast<VarDecl>(DR->getDecl()))
                        5: branch 1 taken
                       16: branch 2 taken
     212               21:       if (!VD->hasLocalStorage()) {
     213                5:         unsigned &flag = Visited[VD];
                        5: branch 0 taken
                        0: branch 1 not taken
     214                5:         if (!flag) {
     215                5:           flag = 1;
     216                5:           BEVals.push_back(VD, BC);
     217                 :         }
     218                 :       }
     219               45:   }
     220                 :   
     221               81:   void VisitBlockDeclRefExpr(BlockDeclRefExpr *DR) {
                       81: branch 2 taken
                        0: branch 3 not taken
     222               81:     if (const VarDecl *VD = dyn_cast<VarDecl>(DR->getDecl())) {
     223               81:       unsigned &flag = Visited[VD];
                       81: branch 0 taken
                        0: branch 1 not taken
     224               81:       if (!flag) {
     225               81:         flag = 1;
     226               81:         BEVals.push_back(VD, BC);
     227                 :       }
     228                 :     }
     229               81:   }
     230                 : };  
     231                 : } // end anonymous namespace
     232                 : 
     233                 : typedef BumpVector<const VarDecl*> DeclVec;
     234                 : 
     235                 : static DeclVec* LazyInitializeReferencedDecls(const BlockDecl *BD,
     236                 :                                               void *&Vec,
     237              256:                                               llvm::BumpPtrAllocator &A) {
                      183: branch 0 taken
                       73: branch 1 taken
     238              256:   if (Vec)
     239              183:     return (DeclVec*) Vec;
     240                 :   
     241               73:   BumpVectorContext BC(A);
     242               73:   DeclVec *BV = (DeclVec*) A.Allocate<DeclVec>();
                       73: branch 1 taken
                        0: branch 2 not taken
     243               73:   new (BV) DeclVec(BC, 10);
     244                 :   
     245                 :   // Find the referenced variables.
     246               73:   FindBlockDeclRefExprsVals F(*BV, BC);
     247               73:   F.Visit(BD->getBody());
     248                 :   
     249               73:   Vec = BV;  
     250               73:   return BV;
     251                 : }
     252                 : 
     253                 : std::pair<AnalysisContext::referenced_decls_iterator,
     254                 :           AnalysisContext::referenced_decls_iterator>
     255              256: AnalysisContext::getReferencedBlockVars(const BlockDecl *BD) {
                       66: branch 0 taken
                      190: branch 1 taken
     256              256:   if (!ReferencedBlockVars)
     257               66:     ReferencedBlockVars = new llvm::DenseMap<const BlockDecl*,void*>();
     258                 :   
     259              256:   DeclVec *V = LazyInitializeReferencedDecls(BD, (*ReferencedBlockVars)[BD], A);
     260              256:   return std::make_pair(V->begin(), V->end());
     261                 : }
     262                 : 
     263                 : //===----------------------------------------------------------------------===//
     264                 : // Cleanup.
     265                 : //===----------------------------------------------------------------------===//
     266                 : 
     267            11950: AnalysisContext::~AnalysisContext() {
                     5478: branch 0 taken
                     6472: branch 1 taken
                     5478: branch 4 taken
                     5478: branch 5 taken
     268            11950:   delete cfg;
                     1998: branch 0 taken
                     9952: branch 1 taken
                     1998: branch 4 taken
                     1998: branch 5 taken
     269            11950:   delete liveness;
                      765: branch 0 taken
                    11185: branch 1 taken
                      765: branch 4 taken
                      765: branch 5 taken
     270            11950:   delete PM;
                       66: branch 0 taken
                    11884: branch 1 taken
                       66: branch 4 taken
                       66: branch 5 taken
     271            11950:   delete ReferencedBlockVars;
     272            11950: }
     273                 : 
     274              188: AnalysisContextManager::~AnalysisContextManager() {
                      179: branch 5 taken
                      188: branch 6 taken
                        0: branch 12 not taken
                        0: branch 13 not taken
     275              367:   for (ContextMap::iterator I = Contexts.begin(), E = Contexts.end(); I!=E; ++I)
                      179: branch 1 taken
                        0: branch 2 not taken
                        0: branch 6 not taken
                        0: branch 7 not taken
     276              179:     delete I->second;
     277              188: }
     278                 : 
                     1946: branch 0 taken
                     1946: branch 1 taken
                        0: branch 3 not taken
                        0: branch 4 not taken
                        0: branch 6 not taken
                     1946: branch 7 taken
     279             1946: LocationContext::~LocationContext() {}
     280                 : 
     281              188: LocationContextManager::~LocationContextManager() {
     282              188:   clear();
     283              188: }
     284                 : 
     285             2204: void LocationContextManager::clear() {
                     1946: branch 2 taken
                     2204: branch 3 taken
     286             8558:   for (llvm::FoldingSet<LocationContext>::iterator I = Contexts.begin(),
     287             2204:        E = Contexts.end(); I != E; ) {    
     288             1946:     LocationContext *LC = &*I;
     289             1946:     ++I;
                     1946: branch 0 taken
                        0: branch 1 not taken
     290             1946:     delete LC;
     291                 :   }
     292                 :   
     293             2204:   Contexts.clear();
     294             2204: }
     295                 : 

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