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