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