| Ted Kremenek | 11de5cb | 2007-09-20 21:42:55 +0000 | [diff] [blame] | 1 | //=- LiveVariables.cpp - Live Variable Analysis for Source CFGs -*- C++ --*-==// | 
| Ted Kremenek | e4e6334 | 2007-09-06 00:17:54 +0000 | [diff] [blame] | 2 | // | 
 | 3 | //                     The LLVM Compiler Infrastructure | 
 | 4 | // | 
| Chris Lattner | 0bc735f | 2007-12-29 19:59:25 +0000 | [diff] [blame] | 5 | // This file is distributed under the University of Illinois Open Source | 
 | 6 | // License. See LICENSE.TXT for details. | 
| Ted Kremenek | fdd225e | 2007-09-25 04:31:27 +0000 | [diff] [blame] | 7 | // details. | 
| Ted Kremenek | e4e6334 | 2007-09-06 00:17:54 +0000 | [diff] [blame] | 8 | // | 
 | 9 | //===----------------------------------------------------------------------===// | 
 | 10 | // | 
 | 11 | // This file implements Live Variables analysis for source-level CFGs. | 
 | 12 | // | 
 | 13 | //===----------------------------------------------------------------------===// | 
 | 14 |  | 
| Ted Kremenek | cf6e41b | 2007-12-21 21:42:19 +0000 | [diff] [blame] | 15 | #include "clang/Analysis/Analyses/LiveVariables.h" | 
| Ted Kremenek | 27b07c5 | 2007-09-06 21:26:58 +0000 | [diff] [blame] | 16 | #include "clang/Basic/SourceManager.h" | 
| Ted Kremenek | e4e6334 | 2007-09-06 00:17:54 +0000 | [diff] [blame] | 17 | #include "clang/AST/Expr.h" | 
 | 18 | #include "clang/AST/CFG.h" | 
| Ted Kremenek | fdd225e | 2007-09-25 04:31:27 +0000 | [diff] [blame] | 19 | #include "clang/Analysis/Visitors/CFGRecStmtDeclVisitor.h" | 
| Ted Kremenek | 1de632b | 2007-09-25 21:00:24 +0000 | [diff] [blame] | 20 | #include "clang/Analysis/FlowSensitive/DataflowSolver.h" | 
| Ted Kremenek | e4e6334 | 2007-09-06 00:17:54 +0000 | [diff] [blame] | 21 | #include "llvm/ADT/SmallPtrSet.h" | 
| Ted Kremenek | c2b51d8 | 2008-01-08 18:19:08 +0000 | [diff] [blame] | 22 | #include "llvm/Support/Compiler.h" | 
| Ted Kremenek | e4e6334 | 2007-09-06 00:17:54 +0000 | [diff] [blame] | 23 |  | 
| Ted Kremenek | 27b07c5 | 2007-09-06 21:26:58 +0000 | [diff] [blame] | 24 | #include <string.h> | 
 | 25 | #include <stdio.h> | 
| Ted Kremenek | e4e6334 | 2007-09-06 00:17:54 +0000 | [diff] [blame] | 26 |  | 
 | 27 | using namespace clang; | 
 | 28 |  | 
 | 29 | //===----------------------------------------------------------------------===// | 
| Ted Kremenek | fdd225e | 2007-09-25 04:31:27 +0000 | [diff] [blame] | 30 | // Dataflow initialization logic. | 
 | 31 | //===----------------------------------------------------------------------===//       | 
| Ted Kremenek | e4e6334 | 2007-09-06 00:17:54 +0000 | [diff] [blame] | 32 |  | 
 | 33 | namespace { | 
| Ted Kremenek | c2b51d8 | 2008-01-08 18:19:08 +0000 | [diff] [blame] | 34 | class VISIBILITY_HIDDEN RegisterDecls  | 
 | 35 |   : public CFGRecStmtDeclVisitor<RegisterDecls> { | 
 | 36 |      | 
| Ted Kremenek | fdd225e | 2007-09-25 04:31:27 +0000 | [diff] [blame] | 37 |   LiveVariables::AnalysisDataTy& AD; | 
| Ted Kremenek | f63aa45 | 2007-09-28 20:38:59 +0000 | [diff] [blame] | 38 | public: | 
| Ted Kremenek | 11e7218 | 2007-10-01 20:33:52 +0000 | [diff] [blame] | 39 |   RegisterDecls(LiveVariables::AnalysisDataTy& ad) : AD(ad) {}   | 
| Ted Kremenek | f63aa45 | 2007-09-28 20:38:59 +0000 | [diff] [blame] | 40 |   void VisitVarDecl(VarDecl* VD) { AD.Register(VD); } | 
| Ted Kremenek | 9f9141c | 2007-11-20 03:01:58 +0000 | [diff] [blame] | 41 |   CFG& getCFG() { return AD.getCFG(); } | 
| Ted Kremenek | 11e7218 | 2007-10-01 20:33:52 +0000 | [diff] [blame] | 42 | }; | 
| Ted Kremenek | e4e6334 | 2007-09-06 00:17:54 +0000 | [diff] [blame] | 43 | } // end anonymous namespace | 
 | 44 |  | 
| Ted Kremenek | bffaa83 | 2008-01-29 05:13:23 +0000 | [diff] [blame] | 45 |  | 
 | 46 | LiveVariables::LiveVariables(CFG& cfg, FunctionDecl& FD) { | 
 | 47 |   getAnalysisData().setCFG(&cfg); | 
 | 48 |  | 
 | 49 |   for (FunctionDecl::param_iterator I=FD.param_begin(), E=FD.param_end(); | 
 | 50 |        I !=E; ++I) | 
 | 51 |     getAnalysisData().Register(*I); | 
 | 52 |    | 
 | 53 |   // Now register all the other VarDecls; | 
| Ted Kremenek | 11e7218 | 2007-10-01 20:33:52 +0000 | [diff] [blame] | 54 |   RegisterDecls R(getAnalysisData()); | 
| Ted Kremenek | fdd225e | 2007-09-25 04:31:27 +0000 | [diff] [blame] | 55 |   cfg.VisitBlockStmts(R); | 
 | 56 | } | 
| Ted Kremenek | e4e6334 | 2007-09-06 00:17:54 +0000 | [diff] [blame] | 57 |  | 
 | 58 | //===----------------------------------------------------------------------===// | 
| Ted Kremenek | fdd225e | 2007-09-25 04:31:27 +0000 | [diff] [blame] | 59 | // Transfer functions. | 
 | 60 | //===----------------------------------------------------------------------===//       | 
| Ted Kremenek | e4e6334 | 2007-09-06 00:17:54 +0000 | [diff] [blame] | 61 |  | 
 | 62 | namespace { | 
| Ted Kremenek | f63aa45 | 2007-09-28 20:38:59 +0000 | [diff] [blame] | 63 |    | 
 | 64 | static const bool Alive = true; | 
 | 65 | static const bool Dead = false;   | 
 | 66 |  | 
| Ted Kremenek | c2b51d8 | 2008-01-08 18:19:08 +0000 | [diff] [blame] | 67 | class VISIBILITY_HIDDEN TransferFuncs : public CFGRecStmtVisitor<TransferFuncs>{ | 
| Ted Kremenek | fdd225e | 2007-09-25 04:31:27 +0000 | [diff] [blame] | 68 |   LiveVariables::AnalysisDataTy& AD; | 
| Ted Kremenek | f63aa45 | 2007-09-28 20:38:59 +0000 | [diff] [blame] | 69 |   LiveVariables::ValTy LiveState; | 
| Ted Kremenek | e4e6334 | 2007-09-06 00:17:54 +0000 | [diff] [blame] | 70 | public: | 
| Ted Kremenek | 11e7218 | 2007-10-01 20:33:52 +0000 | [diff] [blame] | 71 |   TransferFuncs(LiveVariables::AnalysisDataTy& ad) : AD(ad) {} | 
| Ted Kremenek | fdd225e | 2007-09-25 04:31:27 +0000 | [diff] [blame] | 72 |  | 
| Ted Kremenek | f63aa45 | 2007-09-28 20:38:59 +0000 | [diff] [blame] | 73 |   LiveVariables::ValTy& getVal() { return LiveState; } | 
| Ted Kremenek | 9f9141c | 2007-11-20 03:01:58 +0000 | [diff] [blame] | 74 |   CFG& getCFG() { return AD.getCFG(); } | 
| Ted Kremenek | f175805 | 2007-09-12 19:10:52 +0000 | [diff] [blame] | 75 |    | 
| Ted Kremenek | e4e6334 | 2007-09-06 00:17:54 +0000 | [diff] [blame] | 76 |   void VisitDeclRefExpr(DeclRefExpr* DR); | 
 | 77 |   void VisitBinaryOperator(BinaryOperator* B); | 
 | 78 |   void VisitAssign(BinaryOperator* B); | 
| Ted Kremenek | 27b07c5 | 2007-09-06 21:26:58 +0000 | [diff] [blame] | 79 |   void VisitDeclStmt(DeclStmt* DS); | 
 | 80 |   void VisitUnaryOperator(UnaryOperator* U); | 
| Ted Kremenek | 11e7218 | 2007-10-01 20:33:52 +0000 | [diff] [blame] | 81 |   void Visit(Stmt *S); | 
| Ted Kremenek | e4e6334 | 2007-09-06 00:17:54 +0000 | [diff] [blame] | 82 | }; | 
| Ted Kremenek | 11e7218 | 2007-10-01 20:33:52 +0000 | [diff] [blame] | 83 |        | 
| Ted Kremenek | 11e7218 | 2007-10-01 20:33:52 +0000 | [diff] [blame] | 84 | void TransferFuncs::Visit(Stmt *S) { | 
 | 85 |   if (AD.Observer) | 
 | 86 |     AD.Observer->ObserveStmt(S,AD,LiveState); | 
| Ted Kremenek | f63aa45 | 2007-09-28 20:38:59 +0000 | [diff] [blame] | 87 |    | 
| Ted Kremenek | 8694674 | 2008-01-17 20:48:37 +0000 | [diff] [blame] | 88 |   if (S == getCurrentBlkStmt()) { | 
| Ted Kremenek | 8694674 | 2008-01-17 20:48:37 +0000 | [diff] [blame] | 89 |     if (getCFG().isBlkExpr(S)) LiveState(S,AD) = Dead; | 
| Ted Kremenek | 2a9da9c | 2008-01-18 00:40:21 +0000 | [diff] [blame] | 90 |     StmtVisitor<TransferFuncs,void>::Visit(S); | 
| Ted Kremenek | 8694674 | 2008-01-17 20:48:37 +0000 | [diff] [blame] | 91 |   } | 
 | 92 |   else if (!getCFG().isBlkExpr(S)) | 
 | 93 |     StmtVisitor<TransferFuncs,void>::Visit(S); | 
 | 94 |   else | 
 | 95 |     // For block-level expressions, mark that they are live. | 
 | 96 |     LiveState(S,AD) = Alive; | 
| Ted Kremenek | 11e7218 | 2007-10-01 20:33:52 +0000 | [diff] [blame] | 97 | } | 
| Ted Kremenek | e4e6334 | 2007-09-06 00:17:54 +0000 | [diff] [blame] | 98 |  | 
| Ted Kremenek | fdd225e | 2007-09-25 04:31:27 +0000 | [diff] [blame] | 99 | void TransferFuncs::VisitDeclRefExpr(DeclRefExpr* DR) { | 
 | 100 |   if (VarDecl* V = dyn_cast<VarDecl>(DR->getDecl()))  | 
| Ted Kremenek | f63aa45 | 2007-09-28 20:38:59 +0000 | [diff] [blame] | 101 |     LiveState(V,AD) = Alive; | 
| Ted Kremenek | e4e6334 | 2007-09-06 00:17:54 +0000 | [diff] [blame] | 102 | } | 
| Ted Kremenek | e4e6334 | 2007-09-06 00:17:54 +0000 | [diff] [blame] | 103 |    | 
| Ted Kremenek | fdd225e | 2007-09-25 04:31:27 +0000 | [diff] [blame] | 104 | void TransferFuncs::VisitBinaryOperator(BinaryOperator* B) {      | 
| Ted Kremenek | f175805 | 2007-09-12 19:10:52 +0000 | [diff] [blame] | 105 |   if (B->isAssignmentOp()) VisitAssign(B); | 
 | 106 |   else VisitStmt(B); | 
| Ted Kremenek | e4e6334 | 2007-09-06 00:17:54 +0000 | [diff] [blame] | 107 | } | 
 | 108 |  | 
| Ted Kremenek | fdd225e | 2007-09-25 04:31:27 +0000 | [diff] [blame] | 109 | void TransferFuncs::VisitUnaryOperator(UnaryOperator* U) { | 
| Ted Kremenek | 5e2b609 | 2008-01-17 17:50:49 +0000 | [diff] [blame] | 110 |   Expr *E = U->getSubExpr(); | 
| Ted Kremenek | bcb07d5 | 2007-09-28 21:29:33 +0000 | [diff] [blame] | 111 |    | 
| Ted Kremenek | 27b07c5 | 2007-09-06 21:26:58 +0000 | [diff] [blame] | 112 |   switch (U->getOpcode()) { | 
| Ted Kremenek | 8d9ebae | 2007-12-13 04:47:15 +0000 | [diff] [blame] | 113 |   case UnaryOperator::SizeOf: return;       | 
| Ted Kremenek | fdd225e | 2007-09-25 04:31:27 +0000 | [diff] [blame] | 114 |   case UnaryOperator::PostInc: | 
 | 115 |   case UnaryOperator::PostDec: | 
 | 116 |   case UnaryOperator::PreInc: | 
 | 117 |   case UnaryOperator::PreDec: | 
 | 118 |   case UnaryOperator::AddrOf: | 
 | 119 |     // Walk through the subexpressions, blasting through ParenExprs | 
 | 120 |     // until we either find a DeclRefExpr or some non-DeclRefExpr | 
 | 121 |     // expression. | 
| Ted Kremenek | 5620631 | 2008-02-22 00:34:10 +0000 | [diff] [blame] | 122 |     if (DeclRefExpr* DR = dyn_cast<DeclRefExpr>(E->IgnoreParens()))  | 
 | 123 |       if (VarDecl* VD = dyn_cast<VarDecl>(DR->getDecl())) {         | 
 | 124 |         // Treat the --/++/& operator as a kill. | 
 | 125 |         LiveState(VD, AD) = Dead; | 
 | 126 |         if (AD.Observer) { AD.Observer->ObserverKill(DR); } | 
 | 127 |         return VisitDeclRefExpr(DR); | 
 | 128 |       } | 
| Ted Kremenek | bcb07d5 | 2007-09-28 21:29:33 +0000 | [diff] [blame] | 129 |  | 
 | 130 |     // Fall-through. | 
| Ted Kremenek | fdd225e | 2007-09-25 04:31:27 +0000 | [diff] [blame] | 131 |    | 
 | 132 |   default: | 
| Ted Kremenek | 5e2b609 | 2008-01-17 17:50:49 +0000 | [diff] [blame] | 133 |     return Visit(E); | 
| Ted Kremenek | 27b07c5 | 2007-09-06 21:26:58 +0000 | [diff] [blame] | 134 |   } | 
 | 135 | } | 
| Ted Kremenek | bcb07d5 | 2007-09-28 21:29:33 +0000 | [diff] [blame] | 136 |    | 
| Ted Kremenek | fdd225e | 2007-09-25 04:31:27 +0000 | [diff] [blame] | 137 | void TransferFuncs::VisitAssign(BinaryOperator* B) {     | 
| Ted Kremenek | 5e2b609 | 2008-01-17 17:50:49 +0000 | [diff] [blame] | 138 |   Expr* LHS = B->getLHS(); | 
| Ted Kremenek | fdd225e | 2007-09-25 04:31:27 +0000 | [diff] [blame] | 139 |  | 
| Ted Kremenek | bcb07d5 | 2007-09-28 21:29:33 +0000 | [diff] [blame] | 140 |   // Assigning to a variable? | 
| Ted Kremenek | 5e2b609 | 2008-01-17 17:50:49 +0000 | [diff] [blame] | 141 |   if (DeclRefExpr* DR = dyn_cast<DeclRefExpr>(LHS->IgnoreParens())) { | 
| Ted Kremenek | f63aa45 | 2007-09-28 20:38:59 +0000 | [diff] [blame] | 142 |     LiveState(DR->getDecl(),AD) = Dead; | 
 | 143 |     if (AD.Observer) { AD.Observer->ObserverKill(DR); } | 
 | 144 |      | 
| Ted Kremenek | fdd225e | 2007-09-25 04:31:27 +0000 | [diff] [blame] | 145 |     // Handle things like +=, etc., which also generate "uses" | 
 | 146 |     // of a variable.  Do this just by visiting the subexpression. | 
| Ted Kremenek | bcb07d5 | 2007-09-28 21:29:33 +0000 | [diff] [blame] | 147 |     if (B->getOpcode() != BinaryOperator::Assign) | 
 | 148 |       VisitDeclRefExpr(DR); | 
| Ted Kremenek | e4e6334 | 2007-09-06 00:17:54 +0000 | [diff] [blame] | 149 |   } | 
| Ted Kremenek | fdd225e | 2007-09-25 04:31:27 +0000 | [diff] [blame] | 150 |   else // Not assigning to a variable.  Process LHS as usual. | 
| Ted Kremenek | 27b07c5 | 2007-09-06 21:26:58 +0000 | [diff] [blame] | 151 |     Visit(LHS); | 
| Ted Kremenek | e4e6334 | 2007-09-06 00:17:54 +0000 | [diff] [blame] | 152 |    | 
| Ted Kremenek | fdd225e | 2007-09-25 04:31:27 +0000 | [diff] [blame] | 153 |   Visit(B->getRHS()); | 
| Ted Kremenek | e4e6334 | 2007-09-06 00:17:54 +0000 | [diff] [blame] | 154 | } | 
 | 155 |  | 
| Ted Kremenek | fdd225e | 2007-09-25 04:31:27 +0000 | [diff] [blame] | 156 | void TransferFuncs::VisitDeclStmt(DeclStmt* DS) { | 
 | 157 |   // Declarations effectively "kill" a variable since they cannot | 
 | 158 |   // possibly be live before they are declared. | 
| Ted Kremenek | dcc4810 | 2008-02-25 22:28:54 +0000 | [diff] [blame^] | 159 |   for (ScopedDecl* D = DS->getDecl(); D != NULL; D = D->getNextDeclarator()) | 
 | 160 |     if (VarDecl* VD = dyn_cast<VarDecl>(D)) { | 
 | 161 |       LiveState(D,AD) = Dead; | 
 | 162 |        | 
| Ted Kremenek | 2bca5e4 | 2008-02-07 02:38:55 +0000 | [diff] [blame] | 163 |       if (Expr* Init = VD->getInit()) | 
 | 164 |         Visit(Init); | 
| Ted Kremenek | dcc4810 | 2008-02-25 22:28:54 +0000 | [diff] [blame^] | 165 |     } | 
| Ted Kremenek | 27b07c5 | 2007-09-06 21:26:58 +0000 | [diff] [blame] | 166 | } | 
| Ted Kremenek | f63aa45 | 2007-09-28 20:38:59 +0000 | [diff] [blame] | 167 |    | 
| Ted Kremenek | e4e6334 | 2007-09-06 00:17:54 +0000 | [diff] [blame] | 168 | } // end anonymous namespace | 
 | 169 |  | 
| Ted Kremenek | f63aa45 | 2007-09-28 20:38:59 +0000 | [diff] [blame] | 170 | //===----------------------------------------------------------------------===// | 
 | 171 | // Merge operator: if something is live on any successor block, it is live | 
 | 172 | //  in the current block (a set union). | 
 | 173 | //===----------------------------------------------------------------------===//       | 
| Ted Kremenek | e4e6334 | 2007-09-06 00:17:54 +0000 | [diff] [blame] | 174 |  | 
| Ted Kremenek | fdd225e | 2007-09-25 04:31:27 +0000 | [diff] [blame] | 175 | namespace { | 
| Ted Kremenek | d156d53 | 2008-02-22 23:17:20 +0000 | [diff] [blame] | 176 | typedef ExprDeclBitVector_Types::Union Merge; | 
| Ted Kremenek | fdd225e | 2007-09-25 04:31:27 +0000 | [diff] [blame] | 177 | typedef DataflowSolver<LiveVariables,TransferFuncs,Merge> Solver; | 
| Ted Kremenek | f63aa45 | 2007-09-28 20:38:59 +0000 | [diff] [blame] | 178 | } // end anonymous namespace | 
 | 179 |  | 
 | 180 | //===----------------------------------------------------------------------===// | 
 | 181 | // External interface to run Liveness analysis. | 
 | 182 | //===----------------------------------------------------------------------===//       | 
| Ted Kremenek | e4e6334 | 2007-09-06 00:17:54 +0000 | [diff] [blame] | 183 |  | 
| Ted Kremenek | 83c01da | 2008-01-11 00:40:29 +0000 | [diff] [blame] | 184 | void LiveVariables::runOnCFG(CFG& cfg) { | 
| Ted Kremenek | fdd225e | 2007-09-25 04:31:27 +0000 | [diff] [blame] | 185 |   Solver S(*this); | 
 | 186 |   S.runOnCFG(cfg); | 
 | 187 | } | 
| Ted Kremenek | 27b07c5 | 2007-09-06 21:26:58 +0000 | [diff] [blame] | 188 |  | 
| Ted Kremenek | fdd225e | 2007-09-25 04:31:27 +0000 | [diff] [blame] | 189 | void LiveVariables::runOnAllBlocks(const CFG& cfg, | 
| Ted Kremenek | 79649df | 2008-01-17 18:25:22 +0000 | [diff] [blame] | 190 |                                    LiveVariables::ObserverTy* Obs, | 
 | 191 |                                    bool recordStmtValues) { | 
| Ted Kremenek | fdd225e | 2007-09-25 04:31:27 +0000 | [diff] [blame] | 192 |   Solver S(*this); | 
 | 193 |   ObserverTy* OldObserver = getAnalysisData().Observer; | 
| Ted Kremenek | 79649df | 2008-01-17 18:25:22 +0000 | [diff] [blame] | 194 |   getAnalysisData().Observer = Obs; | 
 | 195 |   S.runOnAllBlocks(cfg, recordStmtValues); | 
| Ted Kremenek | fdd225e | 2007-09-25 04:31:27 +0000 | [diff] [blame] | 196 |   getAnalysisData().Observer = OldObserver; | 
| Ted Kremenek | 27b07c5 | 2007-09-06 21:26:58 +0000 | [diff] [blame] | 197 | } | 
 | 198 |  | 
 | 199 | //===----------------------------------------------------------------------===// | 
 | 200 | // liveness queries | 
 | 201 | // | 
 | 202 |  | 
| Ted Kremenek | c0576ca | 2007-09-10 17:36:42 +0000 | [diff] [blame] | 203 | bool LiveVariables::isLive(const CFGBlock* B, const VarDecl* D) const { | 
| Ted Kremenek | f63aa45 | 2007-09-28 20:38:59 +0000 | [diff] [blame] | 204 |   return getBlockData(B)(D,getAnalysisData()); | 
| Ted Kremenek | 27b07c5 | 2007-09-06 21:26:58 +0000 | [diff] [blame] | 205 | } | 
 | 206 |  | 
| Ted Kremenek | fdd225e | 2007-09-25 04:31:27 +0000 | [diff] [blame] | 207 | bool LiveVariables::isLive(const ValTy& Live, const VarDecl* D) const { | 
| Ted Kremenek | f63aa45 | 2007-09-28 20:38:59 +0000 | [diff] [blame] | 208 |   return Live(D,getAnalysisData()); | 
| Ted Kremenek | 055c275 | 2007-09-06 23:00:42 +0000 | [diff] [blame] | 209 | } | 
 | 210 |  | 
| Ted Kremenek | 8694674 | 2008-01-17 20:48:37 +0000 | [diff] [blame] | 211 | bool LiveVariables::isLive(const Stmt* Loc, const Stmt* StmtVal) const { | 
 | 212 |   return getStmtData(Loc)(StmtVal,getAnalysisData()); | 
 | 213 | } | 
 | 214 |  | 
| Ted Kremenek | 2a9da9c | 2008-01-18 00:40:21 +0000 | [diff] [blame] | 215 | bool LiveVariables::isLive(const Stmt* Loc, const VarDecl* D) const { | 
 | 216 |   return getStmtData(Loc)(D,getAnalysisData()); | 
 | 217 | } | 
 | 218 |  | 
| Ted Kremenek | 055c275 | 2007-09-06 23:00:42 +0000 | [diff] [blame] | 219 | //===----------------------------------------------------------------------===// | 
| Ted Kremenek | e4e6334 | 2007-09-06 00:17:54 +0000 | [diff] [blame] | 220 | // printing liveness state for debugging | 
 | 221 | // | 
 | 222 |  | 
| Ted Kremenek | fdd225e | 2007-09-25 04:31:27 +0000 | [diff] [blame] | 223 | void LiveVariables::dumpLiveness(const ValTy& V, SourceManager& SM) const { | 
 | 224 |   const AnalysisDataTy& AD = getAnalysisData(); | 
 | 225 |    | 
| Ted Kremenek | f63aa45 | 2007-09-28 20:38:59 +0000 | [diff] [blame] | 226 |   for (AnalysisDataTy::decl_iterator I = AD.begin_decl(), | 
 | 227 |                                      E = AD.end_decl(); I!=E; ++I) | 
 | 228 |     if (V.getDeclBit(I->second)) {       | 
| Ted Kremenek | 27b07c5 | 2007-09-06 21:26:58 +0000 | [diff] [blame] | 229 |       SourceLocation PhysLoc = SM.getPhysicalLoc(I->first->getLocation()); | 
| Ted Kremenek | fdd225e | 2007-09-25 04:31:27 +0000 | [diff] [blame] | 230 |      | 
| Ted Kremenek | 27b07c5 | 2007-09-06 21:26:58 +0000 | [diff] [blame] | 231 |       fprintf(stderr, "  %s <%s:%u:%u>\n",  | 
 | 232 |               I->first->getIdentifier()->getName(), | 
 | 233 |               SM.getSourceName(PhysLoc), | 
 | 234 |               SM.getLineNumber(PhysLoc), | 
 | 235 |               SM.getColumnNumber(PhysLoc)); | 
| Ted Kremenek | e4e6334 | 2007-09-06 00:17:54 +0000 | [diff] [blame] | 236 |     } | 
| Ted Kremenek | e4e6334 | 2007-09-06 00:17:54 +0000 | [diff] [blame] | 237 | }                                   | 
 | 238 |  | 
| Ted Kremenek | 27b07c5 | 2007-09-06 21:26:58 +0000 | [diff] [blame] | 239 | void LiveVariables::dumpBlockLiveness(SourceManager& M) const { | 
| Ted Kremenek | fdd225e | 2007-09-25 04:31:27 +0000 | [diff] [blame] | 240 |   for (BlockDataMapTy::iterator I = getBlockDataMap().begin(), | 
 | 241 |        E = getBlockDataMap().end(); I!=E; ++I) { | 
 | 242 |     fprintf(stderr, "\n[ B%d (live variables at block exit) ]\n", | 
| Ted Kremenek | 27b07c5 | 2007-09-06 21:26:58 +0000 | [diff] [blame] | 243 |             I->first->getBlockID()); | 
 | 244 |              | 
 | 245 |     dumpLiveness(I->second,M); | 
 | 246 |   } | 
| Ted Kremenek | c0576ca | 2007-09-10 17:36:42 +0000 | [diff] [blame] | 247 |  | 
 | 248 |   fprintf(stderr,"\n"); | 
 | 249 | } |