clang  3.9.0
LiveVariables.cpp
Go to the documentation of this file.
1 //=- LiveVariables.cpp - Live Variable Analysis for Source CFGs ----------*-==//
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 implements Live Variables analysis for source-level CFGs.
11 //
12 //===----------------------------------------------------------------------===//
13 
15 #include "clang/AST/Stmt.h"
16 #include "clang/AST/StmtVisitor.h"
19 #include "clang/Analysis/CFG.h"
20 #include "llvm/ADT/DenseMap.h"
21 #include "llvm/ADT/PostOrderIterator.h"
22 #include "llvm/Support/raw_ostream.h"
23 #include <algorithm>
24 #include <vector>
25 
26 using namespace clang;
27 
28 namespace {
29 
30 class DataflowWorklist {
32  llvm::BitVector enqueuedBlocks;
33  PostOrderCFGView *POV;
34 public:
35  DataflowWorklist(const CFG &cfg, AnalysisDeclContext &Ctx)
36  : enqueuedBlocks(cfg.getNumBlockIDs()),
37  POV(Ctx.getAnalysis<PostOrderCFGView>()) {}
38 
39  void enqueueBlock(const CFGBlock *block);
40  void enqueuePredecessors(const CFGBlock *block);
41 
42  const CFGBlock *dequeue();
43 
44  void sortWorklist();
45 };
46 
47 }
48 
49 void DataflowWorklist::enqueueBlock(const clang::CFGBlock *block) {
50  if (block && !enqueuedBlocks[block->getBlockID()]) {
51  enqueuedBlocks[block->getBlockID()] = true;
52  worklist.push_back(block);
53  }
54 }
55 
56 void DataflowWorklist::enqueuePredecessors(const clang::CFGBlock *block) {
57  const unsigned OldWorklistSize = worklist.size();
59  E = block->pred_end(); I != E; ++I) {
60  enqueueBlock(*I);
61  }
62 
63  if (OldWorklistSize == 0 || OldWorklistSize == worklist.size())
64  return;
65 
66  sortWorklist();
67 }
68 
69 void DataflowWorklist::sortWorklist() {
70  std::sort(worklist.begin(), worklist.end(), POV->getComparator());
71 }
72 
73 const CFGBlock *DataflowWorklist::dequeue() {
74  if (worklist.empty())
75  return nullptr;
76  const CFGBlock *b = worklist.pop_back_val();
77  enqueuedBlocks[b->getBlockID()] = false;
78  return b;
79 }
80 
81 namespace {
82 class LiveVariablesImpl {
83 public:
84  AnalysisDeclContext &analysisContext;
87  llvm::DenseMap<const CFGBlock *, LiveVariables::LivenessValues> blocksEndToLiveness;
88  llvm::DenseMap<const CFGBlock *, LiveVariables::LivenessValues> blocksBeginToLiveness;
89  llvm::DenseMap<const Stmt *, LiveVariables::LivenessValues> stmtsToLiveness;
90  llvm::DenseMap<const DeclRefExpr *, unsigned> inAssignment;
91  const bool killAtAssign;
92 
96 
99  LiveVariables::Observer *obs = nullptr);
100 
101  void dumpBlockLiveness(const SourceManager& M);
102 
103  LiveVariablesImpl(AnalysisDeclContext &ac, bool KillAtAssign)
104  : analysisContext(ac),
105  SSetFact(false), // Do not canonicalize ImmutableSets by default.
106  DSetFact(false), // This is a *major* performance win.
107  killAtAssign(KillAtAssign) {}
108 };
109 }
110 
111 static LiveVariablesImpl &getImpl(void *x) {
112  return *((LiveVariablesImpl *) x);
113 }
114 
115 //===----------------------------------------------------------------------===//
116 // Operations and queries on LivenessValues.
117 //===----------------------------------------------------------------------===//
118 
120  return liveStmts.contains(S);
121 }
122 
124  return liveDecls.contains(D);
125 }
126 
127 namespace {
128  template <typename SET>
129  SET mergeSets(SET A, SET B) {
130  if (A.isEmpty())
131  return B;
132 
133  for (typename SET::iterator it = B.begin(), ei = B.end(); it != ei; ++it) {
134  A = A.add(*it);
135  }
136  return A;
137  }
138 }
139 
140 void LiveVariables::Observer::anchor() { }
141 
143 LiveVariablesImpl::merge(LiveVariables::LivenessValues valsA,
145 
146  llvm::ImmutableSetRef<const Stmt *>
147  SSetRefA(valsA.liveStmts.getRootWithoutRetain(), SSetFact.getTreeFactory()),
148  SSetRefB(valsB.liveStmts.getRootWithoutRetain(), SSetFact.getTreeFactory());
149 
150 
151  llvm::ImmutableSetRef<const VarDecl *>
152  DSetRefA(valsA.liveDecls.getRootWithoutRetain(), DSetFact.getTreeFactory()),
153  DSetRefB(valsB.liveDecls.getRootWithoutRetain(), DSetFact.getTreeFactory());
154 
155 
156  SSetRefA = mergeSets(SSetRefA, SSetRefB);
157  DSetRefA = mergeSets(DSetRefA, DSetRefB);
158 
159  // asImmutableSet() canonicalizes the tree, allowing us to do an easy
160  // comparison afterwards.
161  return LiveVariables::LivenessValues(SSetRefA.asImmutableSet(),
162  DSetRefA.asImmutableSet());
163 }
164 
166  return liveStmts == V.liveStmts && liveDecls == V.liveDecls;
167 }
168 
169 //===----------------------------------------------------------------------===//
170 // Query methods.
171 //===----------------------------------------------------------------------===//
172 
173 static bool isAlwaysAlive(const VarDecl *D) {
174  return D->hasGlobalStorage();
175 }
176 
177 bool LiveVariables::isLive(const CFGBlock *B, const VarDecl *D) {
178  return isAlwaysAlive(D) || getImpl(impl).blocksEndToLiveness[B].isLive(D);
179 }
180 
181 bool LiveVariables::isLive(const Stmt *S, const VarDecl *D) {
182  return isAlwaysAlive(D) || getImpl(impl).stmtsToLiveness[S].isLive(D);
183 }
184 
185 bool LiveVariables::isLive(const Stmt *Loc, const Stmt *S) {
186  return getImpl(impl).stmtsToLiveness[Loc].isLive(S);
187 }
188 
189 //===----------------------------------------------------------------------===//
190 // Dataflow computation.
191 //===----------------------------------------------------------------------===//
192 
193 namespace {
194 class TransferFunctions : public StmtVisitor<TransferFunctions> {
195  LiveVariablesImpl &LV;
197  LiveVariables::Observer *observer;
198  const CFGBlock *currentBlock;
199 public:
200  TransferFunctions(LiveVariablesImpl &im,
202  LiveVariables::Observer *Observer,
203  const CFGBlock *CurrentBlock)
204  : LV(im), val(Val), observer(Observer), currentBlock(CurrentBlock) {}
205 
206  void VisitBinaryOperator(BinaryOperator *BO);
207  void VisitBlockExpr(BlockExpr *BE);
208  void VisitDeclRefExpr(DeclRefExpr *DR);
209  void VisitDeclStmt(DeclStmt *DS);
210  void VisitObjCForCollectionStmt(ObjCForCollectionStmt *OS);
211  void VisitUnaryExprOrTypeTraitExpr(UnaryExprOrTypeTraitExpr *UE);
212  void VisitUnaryOperator(UnaryOperator *UO);
213  void Visit(Stmt *S);
214 };
215 }
216 
217 static const VariableArrayType *FindVA(QualType Ty) {
218  const Type *ty = Ty.getTypePtr();
219  while (const ArrayType *VT = dyn_cast<ArrayType>(ty)) {
220  if (const VariableArrayType *VAT = dyn_cast<VariableArrayType>(VT))
221  if (VAT->getSizeExpr())
222  return VAT;
223 
224  ty = VT->getElementType().getTypePtr();
225  }
226 
227  return nullptr;
228 }
229 
230 static const Stmt *LookThroughStmt(const Stmt *S) {
231  while (S) {
232  if (const Expr *Ex = dyn_cast<Expr>(S))
233  S = Ex->IgnoreParens();
234  if (const ExprWithCleanups *EWC = dyn_cast<ExprWithCleanups>(S)) {
235  S = EWC->getSubExpr();
236  continue;
237  }
238  if (const OpaqueValueExpr *OVE = dyn_cast<OpaqueValueExpr>(S)) {
239  S = OVE->getSourceExpr();
240  continue;
241  }
242  break;
243  }
244  return S;
245 }
246 
249  const Stmt *S) {
250  Set = F.add(Set, LookThroughStmt(S));
251 }
252 
253 void TransferFunctions::Visit(Stmt *S) {
254  if (observer)
255  observer->observeStmt(S, currentBlock, val);
256 
258 
259  if (isa<Expr>(S)) {
260  val.liveStmts = LV.SSetFact.remove(val.liveStmts, S);
261  }
262 
263  // Mark all children expressions live.
264 
265  switch (S->getStmtClass()) {
266  default:
267  break;
268  case Stmt::StmtExprClass: {
269  // For statement expressions, look through the compound statement.
270  S = cast<StmtExpr>(S)->getSubStmt();
271  break;
272  }
273  case Stmt::CXXMemberCallExprClass: {
274  // Include the implicit "this" pointer as being live.
275  CXXMemberCallExpr *CE = cast<CXXMemberCallExpr>(S);
276  if (Expr *ImplicitObj = CE->getImplicitObjectArgument()) {
277  AddLiveStmt(val.liveStmts, LV.SSetFact, ImplicitObj);
278  }
279  break;
280  }
281  case Stmt::ObjCMessageExprClass: {
282  // In calls to super, include the implicit "self" pointer as being live.
283  ObjCMessageExpr *CE = cast<ObjCMessageExpr>(S);
285  val.liveDecls = LV.DSetFact.add(val.liveDecls,
286  LV.analysisContext.getSelfDecl());
287  break;
288  }
289  case Stmt::DeclStmtClass: {
290  const DeclStmt *DS = cast<DeclStmt>(S);
291  if (const VarDecl *VD = dyn_cast<VarDecl>(DS->getSingleDecl())) {
292  for (const VariableArrayType* VA = FindVA(VD->getType());
293  VA != nullptr; VA = FindVA(VA->getElementType())) {
294  AddLiveStmt(val.liveStmts, LV.SSetFact, VA->getSizeExpr());
295  }
296  }
297  break;
298  }
299  case Stmt::PseudoObjectExprClass: {
300  // A pseudo-object operation only directly consumes its result
301  // expression.
302  Expr *child = cast<PseudoObjectExpr>(S)->getResultExpr();
303  if (!child) return;
304  if (OpaqueValueExpr *OV = dyn_cast<OpaqueValueExpr>(child))
305  child = OV->getSourceExpr();
306  child = child->IgnoreParens();
307  val.liveStmts = LV.SSetFact.add(val.liveStmts, child);
308  return;
309  }
310 
311  // FIXME: These cases eventually shouldn't be needed.
312  case Stmt::ExprWithCleanupsClass: {
313  S = cast<ExprWithCleanups>(S)->getSubExpr();
314  break;
315  }
316  case Stmt::CXXBindTemporaryExprClass: {
317  S = cast<CXXBindTemporaryExpr>(S)->getSubExpr();
318  break;
319  }
320  case Stmt::UnaryExprOrTypeTraitExprClass: {
321  // No need to unconditionally visit subexpressions.
322  return;
323  }
324  }
325 
326  for (Stmt *Child : S->children()) {
327  if (Child)
328  AddLiveStmt(val.liveStmts, LV.SSetFact, Child);
329  }
330 }
331 
332 void TransferFunctions::VisitBinaryOperator(BinaryOperator *B) {
333  if (B->isAssignmentOp()) {
334  if (!LV.killAtAssign)
335  return;
336 
337  // Assigning to a variable?
338  Expr *LHS = B->getLHS()->IgnoreParens();
339 
340  if (DeclRefExpr *DR = dyn_cast<DeclRefExpr>(LHS))
341  if (const VarDecl *VD = dyn_cast<VarDecl>(DR->getDecl())) {
342  // Assignments to references don't kill the ref's address
343  if (VD->getType()->isReferenceType())
344  return;
345 
346  if (!isAlwaysAlive(VD)) {
347  // The variable is now dead.
348  val.liveDecls = LV.DSetFact.remove(val.liveDecls, VD);
349  }
350 
351  if (observer)
352  observer->observerKill(DR);
353  }
354  }
355 }
356 
357 void TransferFunctions::VisitBlockExpr(BlockExpr *BE) {
358  for (const VarDecl *VD :
359  LV.analysisContext.getReferencedBlockVars(BE->getBlockDecl())) {
360  if (isAlwaysAlive(VD))
361  continue;
362  val.liveDecls = LV.DSetFact.add(val.liveDecls, VD);
363  }
364 }
365 
366 void TransferFunctions::VisitDeclRefExpr(DeclRefExpr *DR) {
367  if (const VarDecl *D = dyn_cast<VarDecl>(DR->getDecl()))
368  if (!isAlwaysAlive(D) && LV.inAssignment.find(DR) == LV.inAssignment.end())
369  val.liveDecls = LV.DSetFact.add(val.liveDecls, D);
370 }
371 
372 void TransferFunctions::VisitDeclStmt(DeclStmt *DS) {
373  for (const auto *DI : DS->decls())
374  if (const auto *VD = dyn_cast<VarDecl>(DI)) {
375  if (!isAlwaysAlive(VD))
376  val.liveDecls = LV.DSetFact.remove(val.liveDecls, VD);
377  }
378 }
379 
380 void TransferFunctions::VisitObjCForCollectionStmt(ObjCForCollectionStmt *OS) {
381  // Kill the iteration variable.
382  DeclRefExpr *DR = nullptr;
383  const VarDecl *VD = nullptr;
384 
385  Stmt *element = OS->getElement();
386  if (DeclStmt *DS = dyn_cast<DeclStmt>(element)) {
387  VD = cast<VarDecl>(DS->getSingleDecl());
388  }
389  else if ((DR = dyn_cast<DeclRefExpr>(cast<Expr>(element)->IgnoreParens()))) {
390  VD = cast<VarDecl>(DR->getDecl());
391  }
392 
393  if (VD) {
394  val.liveDecls = LV.DSetFact.remove(val.liveDecls, VD);
395  if (observer && DR)
396  observer->observerKill(DR);
397  }
398 }
399 
400 void TransferFunctions::
401 VisitUnaryExprOrTypeTraitExpr(UnaryExprOrTypeTraitExpr *UE)
402 {
403  // While sizeof(var) doesn't technically extend the liveness of 'var', it
404  // does extent the liveness of metadata if 'var' is a VariableArrayType.
405  // We handle that special case here.
406  if (UE->getKind() != UETT_SizeOf || UE->isArgumentType())
407  return;
408 
409  const Expr *subEx = UE->getArgumentExpr();
410  if (subEx->getType()->isVariableArrayType()) {
411  assert(subEx->isLValue());
412  val.liveStmts = LV.SSetFact.add(val.liveStmts, subEx->IgnoreParens());
413  }
414 }
415 
416 void TransferFunctions::VisitUnaryOperator(UnaryOperator *UO) {
417  // Treat ++/-- as a kill.
418  // Note we don't actually have to do anything if we don't have an observer,
419  // since a ++/-- acts as both a kill and a "use".
420  if (!observer)
421  return;
422 
423  switch (UO->getOpcode()) {
424  default:
425  return;
426  case UO_PostInc:
427  case UO_PostDec:
428  case UO_PreInc:
429  case UO_PreDec:
430  break;
431  }
432 
433  if (DeclRefExpr *DR = dyn_cast<DeclRefExpr>(UO->getSubExpr()->IgnoreParens()))
434  if (isa<VarDecl>(DR->getDecl())) {
435  // Treat ++/-- as a kill.
436  observer->observerKill(DR);
437  }
438 }
439 
444 
445  TransferFunctions TF(*this, val, obs, block);
446 
447  // Visit the terminator (if any).
448  if (const Stmt *term = block->getTerminator())
449  TF.Visit(const_cast<Stmt*>(term));
450 
451  // Apply the transfer function for all Stmts in the block.
452  for (CFGBlock::const_reverse_iterator it = block->rbegin(),
453  ei = block->rend(); it != ei; ++it) {
454  const CFGElement &elem = *it;
455 
457  elem.getAs<CFGAutomaticObjDtor>()) {
458  val.liveDecls = DSetFact.add(val.liveDecls, Dtor->getVarDecl());
459  continue;
460  }
461 
462  if (!elem.getAs<CFGStmt>())
463  continue;
464 
465  const Stmt *S = elem.castAs<CFGStmt>().getStmt();
466  TF.Visit(const_cast<Stmt*>(S));
467  stmtsToLiveness[S] = val;
468  }
469  return val;
470 }
471 
473  const CFG *cfg = getImpl(impl).analysisContext.getCFG();
474  for (CFG::const_iterator it = cfg->begin(), ei = cfg->end(); it != ei; ++it)
475  getImpl(impl).runOnBlock(*it, getImpl(impl).blocksEndToLiveness[*it], &obs);
476 }
477 
478 LiveVariables::LiveVariables(void *im) : impl(im) {}
479 
481  delete (LiveVariablesImpl*) impl;
482 }
483 
486  bool killAtAssign) {
487 
488  // No CFG? Bail out.
489  CFG *cfg = AC.getCFG();
490  if (!cfg)
491  return nullptr;
492 
493  // The analysis currently has scalability issues for very large CFGs.
494  // Bail out if it looks too large.
495  if (cfg->getNumBlockIDs() > 300000)
496  return nullptr;
497 
498  LiveVariablesImpl *LV = new LiveVariablesImpl(AC, killAtAssign);
499 
500  // Construct the dataflow worklist. Enqueue the exit block as the
501  // start of the analysis.
502  DataflowWorklist worklist(*cfg, AC);
503  llvm::BitVector everAnalyzedBlock(cfg->getNumBlockIDs());
504 
505  // FIXME: we should enqueue using post order.
506  for (CFG::const_iterator it = cfg->begin(), ei = cfg->end(); it != ei; ++it) {
507  const CFGBlock *block = *it;
508  worklist.enqueueBlock(block);
509 
510  // FIXME: Scan for DeclRefExprs using in the LHS of an assignment.
511  // We need to do this because we lack context in the reverse analysis
512  // to determine if a DeclRefExpr appears in such a context, and thus
513  // doesn't constitute a "use".
514  if (killAtAssign)
515  for (CFGBlock::const_iterator bi = block->begin(), be = block->end();
516  bi != be; ++bi) {
517  if (Optional<CFGStmt> cs = bi->getAs<CFGStmt>()) {
518  if (const BinaryOperator *BO =
519  dyn_cast<BinaryOperator>(cs->getStmt())) {
520  if (BO->getOpcode() == BO_Assign) {
521  if (const DeclRefExpr *DR =
522  dyn_cast<DeclRefExpr>(BO->getLHS()->IgnoreParens())) {
523  LV->inAssignment[DR] = 1;
524  }
525  }
526  }
527  }
528  }
529  }
530 
531  worklist.sortWorklist();
532 
533  while (const CFGBlock *block = worklist.dequeue()) {
534  // Determine if the block's end value has changed. If not, we
535  // have nothing left to do for this block.
536  LivenessValues &prevVal = LV->blocksEndToLiveness[block];
537 
538  // Merge the values of all successor blocks.
539  LivenessValues val;
540  for (CFGBlock::const_succ_iterator it = block->succ_begin(),
541  ei = block->succ_end(); it != ei; ++it) {
542  if (const CFGBlock *succ = *it) {
543  val = LV->merge(val, LV->blocksBeginToLiveness[succ]);
544  }
545  }
546 
547  if (!everAnalyzedBlock[block->getBlockID()])
548  everAnalyzedBlock[block->getBlockID()] = true;
549  else if (prevVal.equals(val))
550  continue;
551 
552  prevVal = val;
553 
554  // Update the dataflow value for the start of this block.
555  LV->blocksBeginToLiveness[block] = LV->runOnBlock(block, val);
556 
557  // Enqueue the value to the predecessors.
558  worklist.enqueuePredecessors(block);
559  }
560 
561  return new LiveVariables(LV);
562 }
563 
565  getImpl(impl).dumpBlockLiveness(M);
566 }
567 
568 void LiveVariablesImpl::dumpBlockLiveness(const SourceManager &M) {
569  std::vector<const CFGBlock *> vec;
571  it = blocksEndToLiveness.begin(), ei = blocksEndToLiveness.end();
572  it != ei; ++it) {
573  vec.push_back(it->first);
574  }
575  std::sort(vec.begin(), vec.end(), [](const CFGBlock *A, const CFGBlock *B) {
576  return A->getBlockID() < B->getBlockID();
577  });
578 
579  std::vector<const VarDecl*> declVec;
580 
582  it = vec.begin(), ei = vec.end(); it != ei; ++it) {
583  llvm::errs() << "\n[ B" << (*it)->getBlockID()
584  << " (live variables at block exit) ]\n";
585 
586  LiveVariables::LivenessValues vals = blocksEndToLiveness[*it];
587  declVec.clear();
588 
590  vals.liveDecls.begin(),
591  se = vals.liveDecls.end(); si != se; ++si) {
592  declVec.push_back(*si);
593  }
594 
595  std::sort(declVec.begin(), declVec.end(), [](const Decl *A, const Decl *B) {
596  return A->getLocStart() < B->getLocStart();
597  });
598 
599  for (std::vector<const VarDecl*>::iterator di = declVec.begin(),
600  de = declVec.end(); di != de; ++di) {
601  llvm::errs() << " " << (*di)->getDeclName().getAsString()
602  << " <";
603  (*di)->getLocation().dump(M);
604  llvm::errs() << ">\n";
605  }
606  }
607  llvm::errs() << "\n";
608 }
609 
610 const void *LiveVariables::getTag() { static int x; return &x; }
611 const void *RelaxedLiveVariables::getTag() { static int x; return &x; }
The receiver is the instance of the superclass object.
Definition: ExprObjC.h:1009
static const VariableArrayType * FindVA(QualType Ty)
pred_iterator pred_end()
Definition: CFG.h:532
A (possibly-)qualified type.
Definition: Type.h:598
static bool isAlwaysAlive(const VarDecl *D)
static const Stmt * LookThroughStmt(const Stmt *S)
static LiveVariables * computeLiveness(AnalysisDeclContext &analysisContext, bool killAtAssign)
Compute the liveness information for a given CFG.
succ_iterator succ_begin()
Definition: CFG.h:541
bool isArgumentType() const
Definition: Expr.h:2010
The base class of the type hierarchy.
Definition: Type.h:1281
Represents an array type, per C99 6.7.5.2 - Array Declarators.
Definition: Type.h:2456
iterator begin()
Definition: CFG.h:505
static const void * getTag()
VarDecl - An instance of this class is created to represent a variable declaration or definition...
Definition: Decl.h:768
bool hasGlobalStorage() const
Returns true for all variables that do not have local storage.
Definition: Decl.h:998
UnaryExprOrTypeTrait getKind() const
Definition: Expr.h:2005
Represents an expression – generally a full-expression – that introduces cleanups to be run at the en...
Definition: ExprCXX.h:2936
static bool isAssignmentOp(Opcode Opc)
Definition: Expr.h:3022
AnalysisDeclContext contains the context data for the function or method under analysis.
CFGAutomaticObjDtor - Represents C++ object destructor implicitly generated for automatic object or t...
Definition: CFG.h:194
Expr * getImplicitObjectArgument() const
Retrieves the implicit object argument for the member call.
Definition: ExprCXX.cpp:459
void runOnAllBlocks(Observer &obs)
T castAs() const
Convert to the specified CFGElement type, asserting that this CFGElement is of the desired type...
Definition: CFG.h:87
iterator end()
Definition: CFG.h:844
Expr * getLHS() const
Definition: Expr.h:2943
static bool runOnBlock(const CFGBlock *block, const CFG &cfg, AnalysisDeclContext &ac, CFGBlockValues &vals, const ClassifyRefs &classification, llvm::BitVector &wasAnalyzed, UninitVariablesHandler &handler)
bool isLive(const CFGBlock *B, const VarDecl *D)
Return true if a variable is live at the end of a specified block.
ElementList::const_iterator const_iterator
Definition: CFG.h:498
A builtin binary operation expression such as "x + y" or "x <= y".
Definition: Expr.h:2897
detail::InMemoryDirectory::const_iterator I
reverse_iterator rend()
Definition: CFG.h:511
static const void * getTag()
UnaryExprOrTypeTraitExpr - expression with either a type or (unevaluated) expression operand...
Definition: Expr.h:1974
CFGBlock - Represents a single basic block in a source-level CFG.
Definition: CFG.h:353
Expr - This represents one expression.
Definition: Expr.h:105
CFG - Represents a source-level, intra-procedural CFG that represents the control-flow of a Stmt...
Definition: CFG.h:721
BlockExpr - Adaptor class for mixing a BlockDecl with expressions.
Definition: Expr.h:4567
bool isVariableArrayType() const
Definition: Type.h:5530
AdjacentBlocks::const_iterator const_pred_iterator
Definition: CFG.h:522
Expr * getSubExpr() const
Definition: Expr.h:1695
unsigned getBlockID() const
Definition: CFG.h:638
An expression that sends a message to the given Objective-C object or class.
Definition: ExprObjC.h:860
UnaryOperator - This represents the unary-expression's (except sizeof and alignof), the postinc/postdec operators from postfix-expression, and various extensions.
Definition: Expr.h:1668
static LiveVariablesImpl & getImpl(void *x)
ValueDecl * getDecl()
Definition: Expr.h:1017
reverse_iterator rbegin()
Definition: CFG.h:510
CFGTerminator getTerminator()
Definition: CFG.h:622
OpaqueValueExpr - An expression referring to an opaque object of a fixed type and value class...
Definition: Expr.h:848
#define false
Definition: stdbool.h:33
void dumpBlockLiveness(const SourceManager &M)
Print to stderr the liveness information associated with each basic block.
const Type * getTypePtr() const
Retrieves a pointer to the underlying (unqualified) type.
Definition: Type.h:5259
const TemplateArgument * iterator
Definition: Type.h:4233
SourceLocation getLocStart() const LLVM_READONLY
Definition: Expr.h:2948
Represents a call to a member function that may be written either with member call syntax (e...
Definition: ExprCXX.h:121
DeclStmt - Adaptor class for mixing declarations with statements and expressions. ...
Definition: Stmt.h:443
llvm::ImmutableSet< const VarDecl * > liveDecls
Definition: LiveVariables.h:36
StmtVisitor - This class implements a simple visitor for Stmt subclasses.
Definition: StmtVisitor.h:178
iterator begin()
Definition: CFG.h:843
succ_iterator succ_end()
Definition: CFG.h:542
const BlockDecl * getBlockDecl() const
Definition: Expr.h:4581
AdjacentBlocks::const_iterator const_succ_iterator
Definition: CFG.h:527
Opcode getOpcode() const
Definition: Expr.h:1692
const Decl * getSingleDecl() const
Definition: Stmt.h:461
QualType getType() const
Definition: Expr.h:126
pred_iterator pred_begin()
Definition: CFG.h:531
bool isLValue() const
isLValue - True if this expression is an "l-value" according to the rules of the current language...
Definition: Expr.h:247
detail::InMemoryDirectory::const_iterator E
llvm::ImmutableSet< const Stmt * > liveStmts
Definition: LiveVariables.h:35
Represents Objective-C's collection statement.
Definition: StmtObjC.h:24
decl_range decls()
Definition: Stmt.h:491
bool isLive(const Stmt *S) const
static void AddLiveStmt(llvm::ImmutableSet< const Stmt * > &Set, llvm::ImmutableSet< const Stmt * >::Factory &F, const Stmt *S)
CFGElement - Represents a top-level expression in a basic block.
Definition: CFG.h:53
A reference to a declared variable, function, enum, etc.
Definition: Expr.h:932
bool equals(const LivenessValues &V) const
Represents a C array with a specified size that is not an integer-constant-expression.
Definition: Type.h:2607
iterator end()
Definition: CFG.h:506
unsigned getNumBlockIDs() const
getNumBlockIDs - Returns the total number of BlockIDs allocated (which start at 0).
Definition: CFG.h:931
ReceiverKind getReceiverKind() const
Determine the kind of receiver that this message is being sent to.
Definition: ExprObjC.h:1136
This class handles loading and caching of source files into memory.
Optional< T > getAs() const
Convert to the specified CFGElement type, returning None if this CFGElement is not of the desired typ...
Definition: CFG.h:98
Expr * IgnoreParens() LLVM_READONLY
IgnoreParens - Ignore parentheses.
Definition: Expr.cpp:2295