1 //===--- CFG.h - Classes for representing and building CFGs------*- C++ -*-===// 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 defines the CFG and CFGBuilder classes for representing and 11 // building Control-Flow Graphs (CFGs) from ASTs. 12 // 13 //===----------------------------------------------------------------------===// 14 15 #ifndef LLVM_CLANG_CFG_H 16 #define LLVM_CLANG_CFG_H 17 18 #include "clang/AST/Stmt.h" 19 #include "clang/Analysis/Support/BumpVector.h" 20 #include "clang/Basic/SourceLocation.h" 21 #include "llvm/ADT/DenseMap.h" 22 #include "llvm/ADT/GraphTraits.h" 23 #include "llvm/ADT/Optional.h" 24 #include "llvm/ADT/PointerIntPair.h" 25 #include "llvm/Support/Allocator.h" 26 #include "llvm/Support/Casting.h" 27 #include "llvm/Support/raw_ostream.h" 28 #include <bitset> 29 #include <cassert> 30 #include <iterator> 31 #include <memory> 32 33 namespace clang { 34 class CXXDestructorDecl; 35 class Decl; 36 class Stmt; 37 class Expr; 38 class FieldDecl; 39 class VarDecl; 40 class CXXCtorInitializer; 41 class CXXBaseSpecifier; 42 class CXXBindTemporaryExpr; 43 class CFG; 44 class PrinterHelper; 45 class LangOptions; 46 class ASTContext; 47 class CXXRecordDecl; 48 class CXXDeleteExpr; 49 class CXXNewExpr; 50 class BinaryOperator; 51 52 /// CFGElement - Represents a top-level expression in a basic block. 53 class CFGElement { 54 public: 55 enum Kind { 56 // main kind 57 Statement, 58 Initializer, 59 NewAllocator, 60 // dtor kind 61 AutomaticObjectDtor, 62 DeleteDtor, 63 BaseDtor, 64 MemberDtor, 65 TemporaryDtor, 66 DTOR_BEGIN = AutomaticObjectDtor, 67 DTOR_END = TemporaryDtor 68 }; 69 70 protected: 71 // The int bits are used to mark the kind. 72 llvm::PointerIntPair<void *, 2> Data1; 73 llvm::PointerIntPair<void *, 2> Data2; 74 75 CFGElement(Kind kind, const void *Ptr1, const void *Ptr2 = nullptr) 76 : Data1(const_cast<void*>(Ptr1), ((unsigned) kind) & 0x3), 77 Data2(const_cast<void*>(Ptr2), (((unsigned) kind) >> 2) & 0x3) { 78 assert(getKind() == kind); 79 } 80 CFGElement()81 CFGElement() {} 82 public: 83 84 /// \brief Convert to the specified CFGElement type, asserting that this 85 /// CFGElement is of the desired type. 86 template<typename T> castAs()87 T castAs() const { 88 assert(T::isKind(*this)); 89 T t; 90 CFGElement& e = t; 91 e = *this; 92 return t; 93 } 94 95 /// \brief Convert to the specified CFGElement type, returning None if this 96 /// CFGElement is not of the desired type. 97 template<typename T> getAs()98 Optional<T> getAs() const { 99 if (!T::isKind(*this)) 100 return None; 101 T t; 102 CFGElement& e = t; 103 e = *this; 104 return t; 105 } 106 getKind()107 Kind getKind() const { 108 unsigned x = Data2.getInt(); 109 x <<= 2; 110 x |= Data1.getInt(); 111 return (Kind) x; 112 } 113 }; 114 115 class CFGStmt : public CFGElement { 116 public: CFGStmt(Stmt * S)117 CFGStmt(Stmt *S) : CFGElement(Statement, S) {} 118 getStmt()119 const Stmt *getStmt() const { 120 return static_cast<const Stmt *>(Data1.getPointer()); 121 } 122 123 private: 124 friend class CFGElement; CFGStmt()125 CFGStmt() {} isKind(const CFGElement & E)126 static bool isKind(const CFGElement &E) { 127 return E.getKind() == Statement; 128 } 129 }; 130 131 /// CFGInitializer - Represents C++ base or member initializer from 132 /// constructor's initialization list. 133 class CFGInitializer : public CFGElement { 134 public: CFGInitializer(CXXCtorInitializer * initializer)135 CFGInitializer(CXXCtorInitializer *initializer) 136 : CFGElement(Initializer, initializer) {} 137 getInitializer()138 CXXCtorInitializer* getInitializer() const { 139 return static_cast<CXXCtorInitializer*>(Data1.getPointer()); 140 } 141 142 private: 143 friend class CFGElement; CFGInitializer()144 CFGInitializer() {} isKind(const CFGElement & E)145 static bool isKind(const CFGElement &E) { 146 return E.getKind() == Initializer; 147 } 148 }; 149 150 /// CFGNewAllocator - Represents C++ allocator call. 151 class CFGNewAllocator : public CFGElement { 152 public: CFGNewAllocator(const CXXNewExpr * S)153 explicit CFGNewAllocator(const CXXNewExpr *S) 154 : CFGElement(NewAllocator, S) {} 155 156 // Get the new expression. getAllocatorExpr()157 const CXXNewExpr *getAllocatorExpr() const { 158 return static_cast<CXXNewExpr *>(Data1.getPointer()); 159 } 160 161 private: 162 friend class CFGElement; CFGNewAllocator()163 CFGNewAllocator() {} isKind(const CFGElement & elem)164 static bool isKind(const CFGElement &elem) { 165 return elem.getKind() == NewAllocator; 166 } 167 }; 168 169 /// CFGImplicitDtor - Represents C++ object destructor implicitly generated 170 /// by compiler on various occasions. 171 class CFGImplicitDtor : public CFGElement { 172 protected: CFGImplicitDtor()173 CFGImplicitDtor() {} 174 CFGImplicitDtor(Kind kind, const void *data1, const void *data2 = nullptr) CFGElement(kind,data1,data2)175 : CFGElement(kind, data1, data2) { 176 assert(kind >= DTOR_BEGIN && kind <= DTOR_END); 177 } 178 179 public: 180 const CXXDestructorDecl *getDestructorDecl(ASTContext &astContext) const; 181 bool isNoReturn(ASTContext &astContext) const; 182 183 private: 184 friend class CFGElement; isKind(const CFGElement & E)185 static bool isKind(const CFGElement &E) { 186 Kind kind = E.getKind(); 187 return kind >= DTOR_BEGIN && kind <= DTOR_END; 188 } 189 }; 190 191 /// CFGAutomaticObjDtor - Represents C++ object destructor implicitly generated 192 /// for automatic object or temporary bound to const reference at the point 193 /// of leaving its local scope. 194 class CFGAutomaticObjDtor: public CFGImplicitDtor { 195 public: CFGAutomaticObjDtor(const VarDecl * var,const Stmt * stmt)196 CFGAutomaticObjDtor(const VarDecl *var, const Stmt *stmt) 197 : CFGImplicitDtor(AutomaticObjectDtor, var, stmt) {} 198 getVarDecl()199 const VarDecl *getVarDecl() const { 200 return static_cast<VarDecl*>(Data1.getPointer()); 201 } 202 203 // Get statement end of which triggered the destructor call. getTriggerStmt()204 const Stmt *getTriggerStmt() const { 205 return static_cast<Stmt*>(Data2.getPointer()); 206 } 207 208 private: 209 friend class CFGElement; CFGAutomaticObjDtor()210 CFGAutomaticObjDtor() {} isKind(const CFGElement & elem)211 static bool isKind(const CFGElement &elem) { 212 return elem.getKind() == AutomaticObjectDtor; 213 } 214 }; 215 216 /// CFGDeleteDtor - Represents C++ object destructor generated 217 /// from a call to delete. 218 class CFGDeleteDtor : public CFGImplicitDtor { 219 public: CFGDeleteDtor(const CXXRecordDecl * RD,const CXXDeleteExpr * DE)220 CFGDeleteDtor(const CXXRecordDecl *RD, const CXXDeleteExpr *DE) 221 : CFGImplicitDtor(DeleteDtor, RD, DE) {} 222 getCXXRecordDecl()223 const CXXRecordDecl *getCXXRecordDecl() const { 224 return static_cast<CXXRecordDecl*>(Data1.getPointer()); 225 } 226 227 // Get Delete expression which triggered the destructor call. getDeleteExpr()228 const CXXDeleteExpr *getDeleteExpr() const { 229 return static_cast<CXXDeleteExpr *>(Data2.getPointer()); 230 } 231 232 233 private: 234 friend class CFGElement; CFGDeleteDtor()235 CFGDeleteDtor() {} isKind(const CFGElement & elem)236 static bool isKind(const CFGElement &elem) { 237 return elem.getKind() == DeleteDtor; 238 } 239 }; 240 241 /// CFGBaseDtor - Represents C++ object destructor implicitly generated for 242 /// base object in destructor. 243 class CFGBaseDtor : public CFGImplicitDtor { 244 public: CFGBaseDtor(const CXXBaseSpecifier * base)245 CFGBaseDtor(const CXXBaseSpecifier *base) 246 : CFGImplicitDtor(BaseDtor, base) {} 247 getBaseSpecifier()248 const CXXBaseSpecifier *getBaseSpecifier() const { 249 return static_cast<const CXXBaseSpecifier*>(Data1.getPointer()); 250 } 251 252 private: 253 friend class CFGElement; CFGBaseDtor()254 CFGBaseDtor() {} isKind(const CFGElement & E)255 static bool isKind(const CFGElement &E) { 256 return E.getKind() == BaseDtor; 257 } 258 }; 259 260 /// CFGMemberDtor - Represents C++ object destructor implicitly generated for 261 /// member object in destructor. 262 class CFGMemberDtor : public CFGImplicitDtor { 263 public: CFGMemberDtor(const FieldDecl * field)264 CFGMemberDtor(const FieldDecl *field) 265 : CFGImplicitDtor(MemberDtor, field, nullptr) {} 266 getFieldDecl()267 const FieldDecl *getFieldDecl() const { 268 return static_cast<const FieldDecl*>(Data1.getPointer()); 269 } 270 271 private: 272 friend class CFGElement; CFGMemberDtor()273 CFGMemberDtor() {} isKind(const CFGElement & E)274 static bool isKind(const CFGElement &E) { 275 return E.getKind() == MemberDtor; 276 } 277 }; 278 279 /// CFGTemporaryDtor - Represents C++ object destructor implicitly generated 280 /// at the end of full expression for temporary object. 281 class CFGTemporaryDtor : public CFGImplicitDtor { 282 public: CFGTemporaryDtor(CXXBindTemporaryExpr * expr)283 CFGTemporaryDtor(CXXBindTemporaryExpr *expr) 284 : CFGImplicitDtor(TemporaryDtor, expr, nullptr) {} 285 getBindTemporaryExpr()286 const CXXBindTemporaryExpr *getBindTemporaryExpr() const { 287 return static_cast<const CXXBindTemporaryExpr *>(Data1.getPointer()); 288 } 289 290 private: 291 friend class CFGElement; CFGTemporaryDtor()292 CFGTemporaryDtor() {} isKind(const CFGElement & E)293 static bool isKind(const CFGElement &E) { 294 return E.getKind() == TemporaryDtor; 295 } 296 }; 297 298 /// CFGTerminator - Represents CFGBlock terminator statement. 299 /// 300 /// TemporaryDtorsBranch bit is set to true if the terminator marks a branch 301 /// in control flow of destructors of temporaries. In this case terminator 302 /// statement is the same statement that branches control flow in evaluation 303 /// of matching full expression. 304 class CFGTerminator { 305 llvm::PointerIntPair<Stmt *, 1> Data; 306 public: CFGTerminator()307 CFGTerminator() {} 308 CFGTerminator(Stmt *S, bool TemporaryDtorsBranch = false) Data(S,TemporaryDtorsBranch)309 : Data(S, TemporaryDtorsBranch) {} 310 getStmt()311 Stmt *getStmt() { return Data.getPointer(); } getStmt()312 const Stmt *getStmt() const { return Data.getPointer(); } 313 isTemporaryDtorsBranch()314 bool isTemporaryDtorsBranch() const { return Data.getInt(); } 315 316 operator Stmt *() { return getStmt(); } 317 operator const Stmt *() const { return getStmt(); } 318 319 Stmt *operator->() { return getStmt(); } 320 const Stmt *operator->() const { return getStmt(); } 321 322 Stmt &operator*() { return *getStmt(); } 323 const Stmt &operator*() const { return *getStmt(); } 324 325 LLVM_EXPLICIT operator bool() const { return getStmt(); } 326 }; 327 328 /// CFGBlock - Represents a single basic block in a source-level CFG. 329 /// It consists of: 330 /// 331 /// (1) A set of statements/expressions (which may contain subexpressions). 332 /// (2) A "terminator" statement (not in the set of statements). 333 /// (3) A list of successors and predecessors. 334 /// 335 /// Terminator: The terminator represents the type of control-flow that occurs 336 /// at the end of the basic block. The terminator is a Stmt* referring to an 337 /// AST node that has control-flow: if-statements, breaks, loops, etc. 338 /// If the control-flow is conditional, the condition expression will appear 339 /// within the set of statements in the block (usually the last statement). 340 /// 341 /// Predecessors: the order in the set of predecessors is arbitrary. 342 /// 343 /// Successors: the order in the set of successors is NOT arbitrary. We 344 /// currently have the following orderings based on the terminator: 345 /// 346 /// Terminator Successor Ordering 347 /// ----------------------------------------------------- 348 /// if Then Block; Else Block 349 /// ? operator LHS expression; RHS expression 350 /// &&, || expression that uses result of && or ||, RHS 351 /// 352 /// But note that any of that may be NULL in case of optimized-out edges. 353 /// 354 class CFGBlock { 355 class ElementList { 356 typedef BumpVector<CFGElement> ImplTy; 357 ImplTy Impl; 358 public: ElementList(BumpVectorContext & C)359 ElementList(BumpVectorContext &C) : Impl(C, 4) {} 360 361 typedef std::reverse_iterator<ImplTy::iterator> iterator; 362 typedef std::reverse_iterator<ImplTy::const_iterator> const_iterator; 363 typedef ImplTy::iterator reverse_iterator; 364 typedef ImplTy::const_iterator const_reverse_iterator; 365 typedef ImplTy::const_reference const_reference; 366 push_back(CFGElement e,BumpVectorContext & C)367 void push_back(CFGElement e, BumpVectorContext &C) { Impl.push_back(e, C); } insert(reverse_iterator I,size_t Cnt,CFGElement E,BumpVectorContext & C)368 reverse_iterator insert(reverse_iterator I, size_t Cnt, CFGElement E, 369 BumpVectorContext &C) { 370 return Impl.insert(I, Cnt, E, C); 371 } 372 front()373 const_reference front() const { return Impl.back(); } back()374 const_reference back() const { return Impl.front(); } 375 begin()376 iterator begin() { return Impl.rbegin(); } end()377 iterator end() { return Impl.rend(); } begin()378 const_iterator begin() const { return Impl.rbegin(); } end()379 const_iterator end() const { return Impl.rend(); } rbegin()380 reverse_iterator rbegin() { return Impl.begin(); } rend()381 reverse_iterator rend() { return Impl.end(); } rbegin()382 const_reverse_iterator rbegin() const { return Impl.begin(); } rend()383 const_reverse_iterator rend() const { return Impl.end(); } 384 385 CFGElement operator[](size_t i) const { 386 assert(i < Impl.size()); 387 return Impl[Impl.size() - 1 - i]; 388 } 389 size()390 size_t size() const { return Impl.size(); } empty()391 bool empty() const { return Impl.empty(); } 392 }; 393 394 /// Stmts - The set of statements in the basic block. 395 ElementList Elements; 396 397 /// Label - An (optional) label that prefixes the executable 398 /// statements in the block. When this variable is non-NULL, it is 399 /// either an instance of LabelStmt, SwitchCase or CXXCatchStmt. 400 Stmt *Label; 401 402 /// Terminator - The terminator for a basic block that 403 /// indicates the type of control-flow that occurs between a block 404 /// and its successors. 405 CFGTerminator Terminator; 406 407 /// LoopTarget - Some blocks are used to represent the "loop edge" to 408 /// the start of a loop from within the loop body. This Stmt* will be 409 /// refer to the loop statement for such blocks (and be null otherwise). 410 const Stmt *LoopTarget; 411 412 /// BlockID - A numerical ID assigned to a CFGBlock during construction 413 /// of the CFG. 414 unsigned BlockID; 415 416 public: 417 /// This class represents a potential adjacent block in the CFG. It encodes 418 /// whether or not the block is actually reachable, or can be proved to be 419 /// trivially unreachable. For some cases it allows one to encode scenarios 420 /// where a block was substituted because the original (now alternate) block 421 /// is unreachable. 422 class AdjacentBlock { 423 enum Kind { 424 AB_Normal, 425 AB_Unreachable, 426 AB_Alternate 427 }; 428 429 CFGBlock *ReachableBlock; 430 llvm::PointerIntPair<CFGBlock*, 2> UnreachableBlock; 431 432 public: 433 /// Construct an AdjacentBlock with a possibly unreachable block. 434 AdjacentBlock(CFGBlock *B, bool IsReachable); 435 436 /// Construct an AdjacentBlock with a reachable block and an alternate 437 /// unreachable block. 438 AdjacentBlock(CFGBlock *B, CFGBlock *AlternateBlock); 439 440 /// Get the reachable block, if one exists. getReachableBlock()441 CFGBlock *getReachableBlock() const { 442 return ReachableBlock; 443 } 444 445 /// Get the potentially unreachable block. getPossiblyUnreachableBlock()446 CFGBlock *getPossiblyUnreachableBlock() const { 447 return UnreachableBlock.getPointer(); 448 } 449 450 /// Provide an implicit conversion to CFGBlock* so that 451 /// AdjacentBlock can be substituted for CFGBlock*. 452 operator CFGBlock*() const { 453 return getReachableBlock(); 454 } 455 456 CFGBlock& operator *() const { 457 return *getReachableBlock(); 458 } 459 460 CFGBlock* operator ->() const { 461 return getReachableBlock(); 462 } 463 isReachable()464 bool isReachable() const { 465 Kind K = (Kind) UnreachableBlock.getInt(); 466 return K == AB_Normal || K == AB_Alternate; 467 } 468 }; 469 470 private: 471 /// Predecessors/Successors - Keep track of the predecessor / successor 472 /// CFG blocks. 473 typedef BumpVector<AdjacentBlock> AdjacentBlocks; 474 AdjacentBlocks Preds; 475 AdjacentBlocks Succs; 476 477 /// NoReturn - This bit is set when the basic block contains a function call 478 /// or implicit destructor that is attributed as 'noreturn'. In that case, 479 /// control cannot technically ever proceed past this block. All such blocks 480 /// will have a single immediate successor: the exit block. This allows them 481 /// to be easily reached from the exit block and using this bit quickly 482 /// recognized without scanning the contents of the block. 483 /// 484 /// Optimization Note: This bit could be profitably folded with Terminator's 485 /// storage if the memory usage of CFGBlock becomes an issue. 486 unsigned HasNoReturnElement : 1; 487 488 /// Parent - The parent CFG that owns this CFGBlock. 489 CFG *Parent; 490 491 public: CFGBlock(unsigned blockid,BumpVectorContext & C,CFG * parent)492 explicit CFGBlock(unsigned blockid, BumpVectorContext &C, CFG *parent) 493 : Elements(C), Label(nullptr), Terminator(nullptr), LoopTarget(nullptr), 494 BlockID(blockid), Preds(C, 1), Succs(C, 1), HasNoReturnElement(false), 495 Parent(parent) {} ~CFGBlock()496 ~CFGBlock() {} 497 498 // Statement iterators 499 typedef ElementList::iterator iterator; 500 typedef ElementList::const_iterator const_iterator; 501 typedef ElementList::reverse_iterator reverse_iterator; 502 typedef ElementList::const_reverse_iterator const_reverse_iterator; 503 front()504 CFGElement front() const { return Elements.front(); } back()505 CFGElement back() const { return Elements.back(); } 506 begin()507 iterator begin() { return Elements.begin(); } end()508 iterator end() { return Elements.end(); } begin()509 const_iterator begin() const { return Elements.begin(); } end()510 const_iterator end() const { return Elements.end(); } 511 rbegin()512 reverse_iterator rbegin() { return Elements.rbegin(); } rend()513 reverse_iterator rend() { return Elements.rend(); } rbegin()514 const_reverse_iterator rbegin() const { return Elements.rbegin(); } rend()515 const_reverse_iterator rend() const { return Elements.rend(); } 516 size()517 unsigned size() const { return Elements.size(); } empty()518 bool empty() const { return Elements.empty(); } 519 520 CFGElement operator[](size_t i) const { return Elements[i]; } 521 522 // CFG iterators 523 typedef AdjacentBlocks::iterator pred_iterator; 524 typedef AdjacentBlocks::const_iterator const_pred_iterator; 525 typedef AdjacentBlocks::reverse_iterator pred_reverse_iterator; 526 typedef AdjacentBlocks::const_reverse_iterator const_pred_reverse_iterator; 527 528 typedef AdjacentBlocks::iterator succ_iterator; 529 typedef AdjacentBlocks::const_iterator const_succ_iterator; 530 typedef AdjacentBlocks::reverse_iterator succ_reverse_iterator; 531 typedef AdjacentBlocks::const_reverse_iterator const_succ_reverse_iterator; 532 pred_begin()533 pred_iterator pred_begin() { return Preds.begin(); } pred_end()534 pred_iterator pred_end() { return Preds.end(); } pred_begin()535 const_pred_iterator pred_begin() const { return Preds.begin(); } pred_end()536 const_pred_iterator pred_end() const { return Preds.end(); } 537 pred_rbegin()538 pred_reverse_iterator pred_rbegin() { return Preds.rbegin(); } pred_rend()539 pred_reverse_iterator pred_rend() { return Preds.rend(); } pred_rbegin()540 const_pred_reverse_iterator pred_rbegin() const { return Preds.rbegin(); } pred_rend()541 const_pred_reverse_iterator pred_rend() const { return Preds.rend(); } 542 succ_begin()543 succ_iterator succ_begin() { return Succs.begin(); } succ_end()544 succ_iterator succ_end() { return Succs.end(); } succ_begin()545 const_succ_iterator succ_begin() const { return Succs.begin(); } succ_end()546 const_succ_iterator succ_end() const { return Succs.end(); } 547 succ_rbegin()548 succ_reverse_iterator succ_rbegin() { return Succs.rbegin(); } succ_rend()549 succ_reverse_iterator succ_rend() { return Succs.rend(); } succ_rbegin()550 const_succ_reverse_iterator succ_rbegin() const { return Succs.rbegin(); } succ_rend()551 const_succ_reverse_iterator succ_rend() const { return Succs.rend(); } 552 succ_size()553 unsigned succ_size() const { return Succs.size(); } succ_empty()554 bool succ_empty() const { return Succs.empty(); } 555 pred_size()556 unsigned pred_size() const { return Preds.size(); } pred_empty()557 bool pred_empty() const { return Preds.empty(); } 558 559 560 class FilterOptions { 561 public: FilterOptions()562 FilterOptions() { 563 IgnoreNullPredecessors = 1; 564 IgnoreDefaultsWithCoveredEnums = 0; 565 } 566 567 unsigned IgnoreNullPredecessors : 1; 568 unsigned IgnoreDefaultsWithCoveredEnums : 1; 569 }; 570 571 static bool FilterEdge(const FilterOptions &F, const CFGBlock *Src, 572 const CFGBlock *Dst); 573 574 template <typename IMPL, bool IsPred> 575 class FilteredCFGBlockIterator { 576 private: 577 IMPL I, E; 578 const FilterOptions F; 579 const CFGBlock *From; 580 public: FilteredCFGBlockIterator(const IMPL & i,const IMPL & e,const CFGBlock * from,const FilterOptions & f)581 explicit FilteredCFGBlockIterator(const IMPL &i, const IMPL &e, 582 const CFGBlock *from, 583 const FilterOptions &f) 584 : I(i), E(e), F(f), From(from) { 585 while (hasMore() && Filter(*I)) 586 ++I; 587 } 588 hasMore()589 bool hasMore() const { return I != E; } 590 591 FilteredCFGBlockIterator &operator++() { 592 do { ++I; } while (hasMore() && Filter(*I)); 593 return *this; 594 } 595 596 const CFGBlock *operator*() const { return *I; } 597 private: Filter(const CFGBlock * To)598 bool Filter(const CFGBlock *To) { 599 return IsPred ? FilterEdge(F, To, From) : FilterEdge(F, From, To); 600 } 601 }; 602 603 typedef FilteredCFGBlockIterator<const_pred_iterator, true> 604 filtered_pred_iterator; 605 606 typedef FilteredCFGBlockIterator<const_succ_iterator, false> 607 filtered_succ_iterator; 608 filtered_pred_start_end(const FilterOptions & f)609 filtered_pred_iterator filtered_pred_start_end(const FilterOptions &f) const { 610 return filtered_pred_iterator(pred_begin(), pred_end(), this, f); 611 } 612 filtered_succ_start_end(const FilterOptions & f)613 filtered_succ_iterator filtered_succ_start_end(const FilterOptions &f) const { 614 return filtered_succ_iterator(succ_begin(), succ_end(), this, f); 615 } 616 617 // Manipulation of block contents 618 setTerminator(CFGTerminator Term)619 void setTerminator(CFGTerminator Term) { Terminator = Term; } setLabel(Stmt * Statement)620 void setLabel(Stmt *Statement) { Label = Statement; } setLoopTarget(const Stmt * loopTarget)621 void setLoopTarget(const Stmt *loopTarget) { LoopTarget = loopTarget; } setHasNoReturnElement()622 void setHasNoReturnElement() { HasNoReturnElement = true; } 623 getTerminator()624 CFGTerminator getTerminator() { return Terminator; } getTerminator()625 const CFGTerminator getTerminator() const { return Terminator; } 626 627 Stmt *getTerminatorCondition(bool StripParens = true); 628 629 const Stmt *getTerminatorCondition(bool StripParens = true) const { 630 return const_cast<CFGBlock*>(this)->getTerminatorCondition(StripParens); 631 } 632 getLoopTarget()633 const Stmt *getLoopTarget() const { return LoopTarget; } 634 getLabel()635 Stmt *getLabel() { return Label; } getLabel()636 const Stmt *getLabel() const { return Label; } 637 hasNoReturnElement()638 bool hasNoReturnElement() const { return HasNoReturnElement; } 639 getBlockID()640 unsigned getBlockID() const { return BlockID; } 641 getParent()642 CFG *getParent() const { return Parent; } 643 644 void dump() const; 645 646 void dump(const CFG *cfg, const LangOptions &LO, bool ShowColors = false) const; 647 void print(raw_ostream &OS, const CFG* cfg, const LangOptions &LO, 648 bool ShowColors) const; 649 void printTerminator(raw_ostream &OS, const LangOptions &LO) const; printAsOperand(raw_ostream & OS,bool)650 void printAsOperand(raw_ostream &OS, bool /*PrintType*/) { 651 OS << "BB#" << getBlockID(); 652 } 653 654 /// Adds a (potentially unreachable) successor block to the current block. 655 void addSuccessor(AdjacentBlock Succ, BumpVectorContext &C); 656 appendStmt(Stmt * statement,BumpVectorContext & C)657 void appendStmt(Stmt *statement, BumpVectorContext &C) { 658 Elements.push_back(CFGStmt(statement), C); 659 } 660 appendInitializer(CXXCtorInitializer * initializer,BumpVectorContext & C)661 void appendInitializer(CXXCtorInitializer *initializer, 662 BumpVectorContext &C) { 663 Elements.push_back(CFGInitializer(initializer), C); 664 } 665 appendNewAllocator(CXXNewExpr * NE,BumpVectorContext & C)666 void appendNewAllocator(CXXNewExpr *NE, 667 BumpVectorContext &C) { 668 Elements.push_back(CFGNewAllocator(NE), C); 669 } 670 appendBaseDtor(const CXXBaseSpecifier * BS,BumpVectorContext & C)671 void appendBaseDtor(const CXXBaseSpecifier *BS, BumpVectorContext &C) { 672 Elements.push_back(CFGBaseDtor(BS), C); 673 } 674 appendMemberDtor(FieldDecl * FD,BumpVectorContext & C)675 void appendMemberDtor(FieldDecl *FD, BumpVectorContext &C) { 676 Elements.push_back(CFGMemberDtor(FD), C); 677 } 678 appendTemporaryDtor(CXXBindTemporaryExpr * E,BumpVectorContext & C)679 void appendTemporaryDtor(CXXBindTemporaryExpr *E, BumpVectorContext &C) { 680 Elements.push_back(CFGTemporaryDtor(E), C); 681 } 682 appendAutomaticObjDtor(VarDecl * VD,Stmt * S,BumpVectorContext & C)683 void appendAutomaticObjDtor(VarDecl *VD, Stmt *S, BumpVectorContext &C) { 684 Elements.push_back(CFGAutomaticObjDtor(VD, S), C); 685 } 686 appendDeleteDtor(CXXRecordDecl * RD,CXXDeleteExpr * DE,BumpVectorContext & C)687 void appendDeleteDtor(CXXRecordDecl *RD, CXXDeleteExpr *DE, BumpVectorContext &C) { 688 Elements.push_back(CFGDeleteDtor(RD, DE), C); 689 } 690 691 // Destructors must be inserted in reversed order. So insertion is in two 692 // steps. First we prepare space for some number of elements, then we insert 693 // the elements beginning at the last position in prepared space. beginAutomaticObjDtorsInsert(iterator I,size_t Cnt,BumpVectorContext & C)694 iterator beginAutomaticObjDtorsInsert(iterator I, size_t Cnt, 695 BumpVectorContext &C) { 696 return iterator(Elements.insert(I.base(), Cnt, 697 CFGAutomaticObjDtor(nullptr, 0), C)); 698 } insertAutomaticObjDtor(iterator I,VarDecl * VD,Stmt * S)699 iterator insertAutomaticObjDtor(iterator I, VarDecl *VD, Stmt *S) { 700 *I = CFGAutomaticObjDtor(VD, S); 701 return ++I; 702 } 703 }; 704 705 /// \brief CFGCallback defines methods that should be called when a logical 706 /// operator error is found when building the CFG. 707 class CFGCallback { 708 public: CFGCallback()709 CFGCallback() {} compareAlwaysTrue(const BinaryOperator * B,bool isAlwaysTrue)710 virtual void compareAlwaysTrue(const BinaryOperator *B, bool isAlwaysTrue) {} compareBitwiseEquality(const BinaryOperator * B,bool isAlwaysTrue)711 virtual void compareBitwiseEquality(const BinaryOperator *B, 712 bool isAlwaysTrue) {} ~CFGCallback()713 virtual ~CFGCallback() {} 714 }; 715 716 /// CFG - Represents a source-level, intra-procedural CFG that represents the 717 /// control-flow of a Stmt. The Stmt can represent an entire function body, 718 /// or a single expression. A CFG will always contain one empty block that 719 /// represents the Exit point of the CFG. A CFG will also contain a designated 720 /// Entry block. The CFG solely represents control-flow; it consists of 721 /// CFGBlocks which are simply containers of Stmt*'s in the AST the CFG 722 /// was constructed from. 723 class CFG { 724 public: 725 //===--------------------------------------------------------------------===// 726 // CFG Construction & Manipulation. 727 //===--------------------------------------------------------------------===// 728 729 class BuildOptions { 730 std::bitset<Stmt::lastStmtConstant> alwaysAddMask; 731 public: 732 typedef llvm::DenseMap<const Stmt *, const CFGBlock*> ForcedBlkExprs; 733 ForcedBlkExprs **forcedBlkExprs; 734 CFGCallback *Observer; 735 bool PruneTriviallyFalseEdges; 736 bool AddEHEdges; 737 bool AddInitializers; 738 bool AddImplicitDtors; 739 bool AddTemporaryDtors; 740 bool AddStaticInitBranches; 741 bool AddCXXNewAllocator; 742 alwaysAdd(const Stmt * stmt)743 bool alwaysAdd(const Stmt *stmt) const { 744 return alwaysAddMask[stmt->getStmtClass()]; 745 } 746 747 BuildOptions &setAlwaysAdd(Stmt::StmtClass stmtClass, bool val = true) { 748 alwaysAddMask[stmtClass] = val; 749 return *this; 750 } 751 setAllAlwaysAdd()752 BuildOptions &setAllAlwaysAdd() { 753 alwaysAddMask.set(); 754 return *this; 755 } 756 BuildOptions()757 BuildOptions() 758 : forcedBlkExprs(nullptr), Observer(nullptr), 759 PruneTriviallyFalseEdges(true), AddEHEdges(false), 760 AddInitializers(false), AddImplicitDtors(false), 761 AddTemporaryDtors(false), AddStaticInitBranches(false), 762 AddCXXNewAllocator(false) {} 763 }; 764 765 /// \brief Provides a custom implementation of the iterator class to have the 766 /// same interface as Function::iterator - iterator returns CFGBlock 767 /// (not a pointer to CFGBlock). 768 class graph_iterator { 769 public: 770 typedef const CFGBlock value_type; 771 typedef value_type& reference; 772 typedef value_type* pointer; 773 typedef BumpVector<CFGBlock*>::iterator ImplTy; 774 graph_iterator(const ImplTy & i)775 graph_iterator(const ImplTy &i) : I(i) {} 776 777 bool operator==(const graph_iterator &X) const { return I == X.I; } 778 bool operator!=(const graph_iterator &X) const { return I != X.I; } 779 780 reference operator*() const { return **I; } 781 pointer operator->() const { return *I; } 782 operator CFGBlock* () { return *I; } 783 784 graph_iterator &operator++() { ++I; return *this; } 785 graph_iterator &operator--() { --I; return *this; } 786 787 private: 788 ImplTy I; 789 }; 790 791 class const_graph_iterator { 792 public: 793 typedef const CFGBlock value_type; 794 typedef value_type& reference; 795 typedef value_type* pointer; 796 typedef BumpVector<CFGBlock*>::const_iterator ImplTy; 797 const_graph_iterator(const ImplTy & i)798 const_graph_iterator(const ImplTy &i) : I(i) {} 799 800 bool operator==(const const_graph_iterator &X) const { return I == X.I; } 801 bool operator!=(const const_graph_iterator &X) const { return I != X.I; } 802 803 reference operator*() const { return **I; } 804 pointer operator->() const { return *I; } 805 operator CFGBlock* () const { return *I; } 806 807 const_graph_iterator &operator++() { ++I; return *this; } 808 const_graph_iterator &operator--() { --I; return *this; } 809 810 private: 811 ImplTy I; 812 }; 813 814 /// buildCFG - Builds a CFG from an AST. The responsibility to free the 815 /// constructed CFG belongs to the caller. 816 static CFG* buildCFG(const Decl *D, Stmt *AST, ASTContext *C, 817 const BuildOptions &BO); 818 819 /// createBlock - Create a new block in the CFG. The CFG owns the block; 820 /// the caller should not directly free it. 821 CFGBlock *createBlock(); 822 823 /// setEntry - Set the entry block of the CFG. This is typically used 824 /// only during CFG construction. Most CFG clients expect that the 825 /// entry block has no predecessors and contains no statements. setEntry(CFGBlock * B)826 void setEntry(CFGBlock *B) { Entry = B; } 827 828 /// setIndirectGotoBlock - Set the block used for indirect goto jumps. 829 /// This is typically used only during CFG construction. setIndirectGotoBlock(CFGBlock * B)830 void setIndirectGotoBlock(CFGBlock *B) { IndirectGotoBlock = B; } 831 832 //===--------------------------------------------------------------------===// 833 // Block Iterators 834 //===--------------------------------------------------------------------===// 835 836 typedef BumpVector<CFGBlock*> CFGBlockListTy; 837 typedef CFGBlockListTy::iterator iterator; 838 typedef CFGBlockListTy::const_iterator const_iterator; 839 typedef std::reverse_iterator<iterator> reverse_iterator; 840 typedef std::reverse_iterator<const_iterator> const_reverse_iterator; 841 front()842 CFGBlock & front() { return *Blocks.front(); } back()843 CFGBlock & back() { return *Blocks.back(); } 844 begin()845 iterator begin() { return Blocks.begin(); } end()846 iterator end() { return Blocks.end(); } begin()847 const_iterator begin() const { return Blocks.begin(); } end()848 const_iterator end() const { return Blocks.end(); } 849 nodes_begin()850 graph_iterator nodes_begin() { return graph_iterator(Blocks.begin()); } nodes_end()851 graph_iterator nodes_end() { return graph_iterator(Blocks.end()); } nodes_begin()852 const_graph_iterator nodes_begin() const { 853 return const_graph_iterator(Blocks.begin()); 854 } nodes_end()855 const_graph_iterator nodes_end() const { 856 return const_graph_iterator(Blocks.end()); 857 } 858 rbegin()859 reverse_iterator rbegin() { return Blocks.rbegin(); } rend()860 reverse_iterator rend() { return Blocks.rend(); } rbegin()861 const_reverse_iterator rbegin() const { return Blocks.rbegin(); } rend()862 const_reverse_iterator rend() const { return Blocks.rend(); } 863 getEntry()864 CFGBlock & getEntry() { return *Entry; } getEntry()865 const CFGBlock & getEntry() const { return *Entry; } getExit()866 CFGBlock & getExit() { return *Exit; } getExit()867 const CFGBlock & getExit() const { return *Exit; } 868 getIndirectGotoBlock()869 CFGBlock * getIndirectGotoBlock() { return IndirectGotoBlock; } getIndirectGotoBlock()870 const CFGBlock * getIndirectGotoBlock() const { return IndirectGotoBlock; } 871 872 typedef std::vector<const CFGBlock*>::const_iterator try_block_iterator; try_blocks_begin()873 try_block_iterator try_blocks_begin() const { 874 return TryDispatchBlocks.begin(); 875 } try_blocks_end()876 try_block_iterator try_blocks_end() const { 877 return TryDispatchBlocks.end(); 878 } 879 addTryDispatchBlock(const CFGBlock * block)880 void addTryDispatchBlock(const CFGBlock *block) { 881 TryDispatchBlocks.push_back(block); 882 } 883 884 /// Records a synthetic DeclStmt and the DeclStmt it was constructed from. 885 /// 886 /// The CFG uses synthetic DeclStmts when a single AST DeclStmt contains 887 /// multiple decls. addSyntheticDeclStmt(const DeclStmt * Synthetic,const DeclStmt * Source)888 void addSyntheticDeclStmt(const DeclStmt *Synthetic, 889 const DeclStmt *Source) { 890 assert(Synthetic->isSingleDecl() && "Can handle single declarations only"); 891 assert(Synthetic != Source && "Don't include original DeclStmts in map"); 892 assert(!SyntheticDeclStmts.count(Synthetic) && "Already in map"); 893 SyntheticDeclStmts[Synthetic] = Source; 894 } 895 896 typedef llvm::DenseMap<const DeclStmt *, const DeclStmt *>::const_iterator 897 synthetic_stmt_iterator; 898 899 /// Iterates over synthetic DeclStmts in the CFG. 900 /// 901 /// Each element is a (synthetic statement, source statement) pair. 902 /// 903 /// \sa addSyntheticDeclStmt synthetic_stmt_begin()904 synthetic_stmt_iterator synthetic_stmt_begin() const { 905 return SyntheticDeclStmts.begin(); 906 } 907 908 /// \sa synthetic_stmt_begin synthetic_stmt_end()909 synthetic_stmt_iterator synthetic_stmt_end() const { 910 return SyntheticDeclStmts.end(); 911 } 912 913 //===--------------------------------------------------------------------===// 914 // Member templates useful for various batch operations over CFGs. 915 //===--------------------------------------------------------------------===// 916 917 template <typename CALLBACK> VisitBlockStmts(CALLBACK & O)918 void VisitBlockStmts(CALLBACK& O) const { 919 for (const_iterator I=begin(), E=end(); I != E; ++I) 920 for (CFGBlock::const_iterator BI=(*I)->begin(), BE=(*I)->end(); 921 BI != BE; ++BI) { 922 if (Optional<CFGStmt> stmt = BI->getAs<CFGStmt>()) 923 O(const_cast<Stmt*>(stmt->getStmt())); 924 } 925 } 926 927 //===--------------------------------------------------------------------===// 928 // CFG Introspection. 929 //===--------------------------------------------------------------------===// 930 931 /// getNumBlockIDs - Returns the total number of BlockIDs allocated (which 932 /// start at 0). getNumBlockIDs()933 unsigned getNumBlockIDs() const { return NumBlockIDs; } 934 935 /// size - Return the total number of CFGBlocks within the CFG 936 /// This is simply a renaming of the getNumBlockIDs(). This is necessary 937 /// because the dominator implementation needs such an interface. size()938 unsigned size() const { return NumBlockIDs; } 939 940 //===--------------------------------------------------------------------===// 941 // CFG Debugging: Pretty-Printing and Visualization. 942 //===--------------------------------------------------------------------===// 943 944 void viewCFG(const LangOptions &LO) const; 945 void print(raw_ostream &OS, const LangOptions &LO, bool ShowColors) const; 946 void dump(const LangOptions &LO, bool ShowColors) const; 947 948 //===--------------------------------------------------------------------===// 949 // Internal: constructors and data. 950 //===--------------------------------------------------------------------===// 951 CFG()952 CFG() 953 : Entry(nullptr), Exit(nullptr), IndirectGotoBlock(nullptr), NumBlockIDs(0), 954 Blocks(BlkBVC, 10) {} 955 getAllocator()956 llvm::BumpPtrAllocator& getAllocator() { 957 return BlkBVC.getAllocator(); 958 } 959 getBumpVectorContext()960 BumpVectorContext &getBumpVectorContext() { 961 return BlkBVC; 962 } 963 964 private: 965 CFGBlock *Entry; 966 CFGBlock *Exit; 967 CFGBlock* IndirectGotoBlock; // Special block to contain collective dispatch 968 // for indirect gotos 969 unsigned NumBlockIDs; 970 971 BumpVectorContext BlkBVC; 972 973 CFGBlockListTy Blocks; 974 975 /// C++ 'try' statements are modeled with an indirect dispatch block. 976 /// This is the collection of such blocks present in the CFG. 977 std::vector<const CFGBlock *> TryDispatchBlocks; 978 979 /// Collects DeclStmts synthesized for this CFG and maps each one back to its 980 /// source DeclStmt. 981 llvm::DenseMap<const DeclStmt *, const DeclStmt *> SyntheticDeclStmts; 982 }; 983 } // end namespace clang 984 985 //===----------------------------------------------------------------------===// 986 // GraphTraits specializations for CFG basic block graphs (source-level CFGs) 987 //===----------------------------------------------------------------------===// 988 989 namespace llvm { 990 991 /// Implement simplify_type for CFGTerminator, so that we can dyn_cast from 992 /// CFGTerminator to a specific Stmt class. 993 template <> struct simplify_type< ::clang::CFGTerminator> { 994 typedef ::clang::Stmt *SimpleType; 995 static SimpleType getSimplifiedValue(::clang::CFGTerminator Val) { 996 return Val.getStmt(); 997 } 998 }; 999 1000 // Traits for: CFGBlock 1001 1002 template <> struct GraphTraits< ::clang::CFGBlock *> { 1003 typedef ::clang::CFGBlock NodeType; 1004 typedef ::clang::CFGBlock::succ_iterator ChildIteratorType; 1005 1006 static NodeType* getEntryNode(::clang::CFGBlock *BB) 1007 { return BB; } 1008 1009 static inline ChildIteratorType child_begin(NodeType* N) 1010 { return N->succ_begin(); } 1011 1012 static inline ChildIteratorType child_end(NodeType* N) 1013 { return N->succ_end(); } 1014 }; 1015 1016 template <> struct GraphTraits< const ::clang::CFGBlock *> { 1017 typedef const ::clang::CFGBlock NodeType; 1018 typedef ::clang::CFGBlock::const_succ_iterator ChildIteratorType; 1019 1020 static NodeType* getEntryNode(const clang::CFGBlock *BB) 1021 { return BB; } 1022 1023 static inline ChildIteratorType child_begin(NodeType* N) 1024 { return N->succ_begin(); } 1025 1026 static inline ChildIteratorType child_end(NodeType* N) 1027 { return N->succ_end(); } 1028 }; 1029 1030 template <> struct GraphTraits<Inverse< ::clang::CFGBlock*> > { 1031 typedef ::clang::CFGBlock NodeType; 1032 typedef ::clang::CFGBlock::const_pred_iterator ChildIteratorType; 1033 1034 static NodeType *getEntryNode(Inverse< ::clang::CFGBlock*> G) 1035 { return G.Graph; } 1036 1037 static inline ChildIteratorType child_begin(NodeType* N) 1038 { return N->pred_begin(); } 1039 1040 static inline ChildIteratorType child_end(NodeType* N) 1041 { return N->pred_end(); } 1042 }; 1043 1044 template <> struct GraphTraits<Inverse<const ::clang::CFGBlock*> > { 1045 typedef const ::clang::CFGBlock NodeType; 1046 typedef ::clang::CFGBlock::const_pred_iterator ChildIteratorType; 1047 1048 static NodeType *getEntryNode(Inverse<const ::clang::CFGBlock*> G) 1049 { return G.Graph; } 1050 1051 static inline ChildIteratorType child_begin(NodeType* N) 1052 { return N->pred_begin(); } 1053 1054 static inline ChildIteratorType child_end(NodeType* N) 1055 { return N->pred_end(); } 1056 }; 1057 1058 // Traits for: CFG 1059 1060 template <> struct GraphTraits< ::clang::CFG* > 1061 : public GraphTraits< ::clang::CFGBlock *> { 1062 1063 typedef ::clang::CFG::graph_iterator nodes_iterator; 1064 1065 static NodeType *getEntryNode(::clang::CFG* F) { return &F->getEntry(); } 1066 static nodes_iterator nodes_begin(::clang::CFG* F) { return F->nodes_begin();} 1067 static nodes_iterator nodes_end(::clang::CFG* F) { return F->nodes_end(); } 1068 static unsigned size(::clang::CFG* F) { return F->size(); } 1069 }; 1070 1071 template <> struct GraphTraits<const ::clang::CFG* > 1072 : public GraphTraits<const ::clang::CFGBlock *> { 1073 1074 typedef ::clang::CFG::const_graph_iterator nodes_iterator; 1075 1076 static NodeType *getEntryNode( const ::clang::CFG* F) { 1077 return &F->getEntry(); 1078 } 1079 static nodes_iterator nodes_begin( const ::clang::CFG* F) { 1080 return F->nodes_begin(); 1081 } 1082 static nodes_iterator nodes_end( const ::clang::CFG* F) { 1083 return F->nodes_end(); 1084 } 1085 static unsigned size(const ::clang::CFG* F) { 1086 return F->size(); 1087 } 1088 }; 1089 1090 template <> struct GraphTraits<Inverse< ::clang::CFG*> > 1091 : public GraphTraits<Inverse< ::clang::CFGBlock*> > { 1092 1093 typedef ::clang::CFG::graph_iterator nodes_iterator; 1094 1095 static NodeType *getEntryNode( ::clang::CFG* F) { return &F->getExit(); } 1096 static nodes_iterator nodes_begin( ::clang::CFG* F) {return F->nodes_begin();} 1097 static nodes_iterator nodes_end( ::clang::CFG* F) { return F->nodes_end(); } 1098 }; 1099 1100 template <> struct GraphTraits<Inverse<const ::clang::CFG*> > 1101 : public GraphTraits<Inverse<const ::clang::CFGBlock*> > { 1102 1103 typedef ::clang::CFG::const_graph_iterator nodes_iterator; 1104 1105 static NodeType *getEntryNode(const ::clang::CFG* F) { return &F->getExit(); } 1106 static nodes_iterator nodes_begin(const ::clang::CFG* F) { 1107 return F->nodes_begin(); 1108 } 1109 static nodes_iterator nodes_end(const ::clang::CFG* F) { 1110 return F->nodes_end(); 1111 } 1112 }; 1113 } // end llvm namespace 1114 #endif 1115