PseudoConstantAnalysis.cpp revision 478851c3ed6bd784e7377dffd8e57b200c1b9ba9
1f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org//== PseudoConstantAnalysis.cpp - Find Pseudoconstants in the AST-*- C++ -*-==// 2f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org// 3f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org// The LLVM Compiler Infrastructure 4f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org// 5f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org// This file is distributed under the University of Illinois Open Source 6f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org// License. See LICENSE.TXT for details. 7f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org// 8f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org//===----------------------------------------------------------------------===// 9f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org// 10f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org// This file tracks the usage of variables in a Decl body to see if they are 11f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org// never written to, implying that they constant. This is useful in static 12f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org// analysis to see if a developer might have intended a variable to be const. 13f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org// 14f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org//===----------------------------------------------------------------------===// 15f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 16f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "clang/Analysis/Analyses/PseudoConstantAnalysis.h" 17f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "clang/AST/Decl.h" 18f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "clang/AST/Expr.h" 19f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "clang/AST/Stmt.h" 20f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "llvm/ADT/SmallPtrSet.h" 21f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include <deque> 22f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 23f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgusing namespace clang; 24f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 25f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org// The number of ValueDecls we want to keep track of by default (per-function) 26f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#define VARDECL_SET_SIZE 256 27f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgtypedef llvm::SmallPtrSet<const VarDecl*, VARDECL_SET_SIZE> VarDeclSet; 28f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 29f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgPseudoConstantAnalysis::PseudoConstantAnalysis(const Stmt *DeclBody) : 30f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org DeclBody(DeclBody), Analyzed(false) { 31f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org NonConstantsImpl = new VarDeclSet; 32f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org UsedVarsImpl = new VarDeclSet; 33f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 34f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 35f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgPseudoConstantAnalysis::~PseudoConstantAnalysis() { 36f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org delete (VarDeclSet*)NonConstantsImpl; 37f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org delete (VarDeclSet*)UsedVarsImpl; 38f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 39f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 40f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org// Returns true if the given ValueDecl is never written to in the given DeclBody 41f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgbool PseudoConstantAnalysis::isPseudoConstant(const VarDecl *VD) { 42f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org // Only local and static variables can be pseudoconstants 43f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (!VD->hasLocalStorage() && !VD->isStaticLocal()) 44f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return false; 45f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 46f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (!Analyzed) { 47f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org RunAnalysis(); 48f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org Analyzed = true; 49f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 50f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 51f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org VarDeclSet *NonConstants = (VarDeclSet*)NonConstantsImpl; 52f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 53f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return !NonConstants->count(VD); 54f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 55f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 56f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org// Returns true if the variable was used (self assignments don't count) 57f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgbool PseudoConstantAnalysis::wasReferenced(const VarDecl *VD) { 58f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (!Analyzed) { 59f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org RunAnalysis(); 60f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org Analyzed = true; 61f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 62f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 63f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org VarDeclSet *UsedVars = (VarDeclSet*)UsedVarsImpl; 64f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 65f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return UsedVars->count(VD); 66f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 67f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 68f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org// Returns a Decl from a (Block)DeclRefExpr (if any) 69f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgconst Decl *PseudoConstantAnalysis::getDecl(const Expr *E) { 70f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (const DeclRefExpr *DR = dyn_cast<DeclRefExpr>(E)) 71f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return DR->getDecl(); 72f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else 73f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return 0; 74f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 75f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 76f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid PseudoConstantAnalysis::RunAnalysis() { 77f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org std::deque<const Stmt *> WorkList; 78f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org VarDeclSet *NonConstants = (VarDeclSet*)NonConstantsImpl; 79f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org VarDeclSet *UsedVars = (VarDeclSet*)UsedVarsImpl; 80f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 81f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org // Start with the top level statement of the function 82f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org WorkList.push_back(DeclBody); 83f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 84f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org while (!WorkList.empty()) { 85f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const Stmt *Head = WorkList.front(); 86f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org WorkList.pop_front(); 87f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 88f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (const Expr *Ex = dyn_cast<Expr>(Head)) 89f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org Head = Ex->IgnoreParenCasts(); 90f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 91f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org switch (Head->getStmtClass()) { 92f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org // Case 1: Assignment operators modifying VarDecls 93f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case Stmt::BinaryOperatorClass: { 94f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const BinaryOperator *BO = cast<BinaryOperator>(Head); 95f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org // Look for a Decl on the LHS 96f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const Decl *LHSDecl = getDecl(BO->getLHS()->IgnoreParenCasts()); 97f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (!LHSDecl) 98f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 99f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 100f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org // We found a binary operator with a DeclRefExpr on the LHS. We now check 101f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org // for any of the assignment operators, implying that this Decl is being 102f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org // written to. 103f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org switch (BO->getOpcode()) { 104f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org // Self-assignments don't count as use of a variable 105f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case BO_Assign: { 106f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org // Look for a DeclRef on the RHS 107f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const Decl *RHSDecl = getDecl(BO->getRHS()->IgnoreParenCasts()); 108f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 109f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org // If the Decls match, we have self-assignment 110f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (LHSDecl == RHSDecl) 111f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org // Do not visit the children 112f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org continue; 113f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 114f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 115f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case BO_AddAssign: 116f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case BO_SubAssign: 117f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case BO_MulAssign: 118f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case BO_DivAssign: 119f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case BO_AndAssign: 120f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case BO_OrAssign: 121f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case BO_XorAssign: 122f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case BO_ShlAssign: 123f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case BO_ShrAssign: { 124f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const VarDecl *VD = dyn_cast<VarDecl>(LHSDecl); 125f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org // The DeclRefExpr is being assigned to - mark it as non-constant 126f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (VD) 127f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org NonConstants->insert(VD); 128f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 129f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 130f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 131f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org default: 132f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 133f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 134f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 135f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 136f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 137f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org // Case 2: Pre/post increment/decrement and address of 138f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case Stmt::UnaryOperatorClass: { 139f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const UnaryOperator *UO = cast<UnaryOperator>(Head); 140f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 141f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org // Look for a DeclRef in the subexpression 142f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const Decl *D = getDecl(UO->getSubExpr()->IgnoreParenCasts()); 143f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (!D) 144f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 145f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 146f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org // We found a unary operator with a DeclRef as a subexpression. We now 147f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org // check for any of the increment/decrement operators, as well as 148f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org // addressOf. 149f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org switch (UO->getOpcode()) { 150f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case UO_PostDec: 151f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case UO_PostInc: 152f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case UO_PreDec: 153f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case UO_PreInc: 154f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org // The DeclRef is being changed - mark it as non-constant 155f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case UO_AddrOf: { 156f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org // If we are taking the address of the DeclRefExpr, assume it is 157f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org // non-constant. 158f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const VarDecl *VD = dyn_cast<VarDecl>(D); 159f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (VD) 160f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org NonConstants->insert(VD); 161f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 162f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 163f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 164f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org default: 165f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 166f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 167f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 168f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 169f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 170f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org // Case 3: Reference Declarations 171f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case Stmt::DeclStmtClass: { 172f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const DeclStmt *DS = cast<DeclStmt>(Head); 173f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org // Iterate over each decl and see if any of them contain reference decls 174f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (DeclStmt::const_decl_iterator I = DS->decl_begin(), 175f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org E = DS->decl_end(); I != E; ++I) { 176f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org // We only care about VarDecls 177f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const VarDecl *VD = dyn_cast<VarDecl>(*I); 178f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (!VD) 179f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org continue; 180f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 181f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org // We found a VarDecl; make sure it is a reference type 182f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (!VD->getType().getTypePtr()->isReferenceType()) 183f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org continue; 184f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 185f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org // Try to find a Decl in the initializer 186f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const Decl *D = getDecl(VD->getInit()->IgnoreParenCasts()); 187f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (!D) 188f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 189f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 190f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org // If the reference is to another var, add the var to the non-constant 191f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org // list 192f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (const VarDecl *RefVD = dyn_cast<VarDecl>(D)) { 193f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org NonConstants->insert(RefVD); 194f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org continue; 195f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 196f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 197f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 198f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 199f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 200f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org // Case 4: Variable references 201f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case Stmt::DeclRefExprClass: { 202f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const DeclRefExpr *DR = cast<DeclRefExpr>(Head); 203f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (const VarDecl *VD = dyn_cast<VarDecl>(DR->getDecl())) { 204f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org // Add the Decl to the used list 205f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org UsedVars->insert(VD); 206f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org continue; 207f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 208f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 209f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 210f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 211f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org // Case 5: Block expressions 212f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case Stmt::BlockExprClass: { 213f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const BlockExpr *B = cast<BlockExpr>(Head); 214f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org // Add the body of the block to the list 215f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org WorkList.push_back(B->getBody()); 216f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org continue; 217f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 218f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 219f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org default: 220f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 221f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } // switch (head->getStmtClass()) 222f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 223f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org // Add all substatements to the worklist 224f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (Stmt::const_child_range I = Head->children(); I; ++I) 225f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (*I) 226f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org WorkList.push_back(*I); 227f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } // while (!WorkList.empty()) 228f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 229f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org