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_ANALYSIS_CFG_H 16 #define LLVM_CLANG_ANALYSIS_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 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) {} 496 497 // Statement iterators 498 typedef ElementList::iterator iterator; 499 typedef ElementList::const_iterator const_iterator; 500 typedef ElementList::reverse_iterator reverse_iterator; 501 typedef ElementList::const_reverse_iterator const_reverse_iterator; 502 front()503 CFGElement front() const { return Elements.front(); } back()504 CFGElement back() const { return Elements.back(); } 505 begin()506 iterator begin() { return Elements.begin(); } end()507 iterator end() { return Elements.end(); } begin()508 const_iterator begin() const { return Elements.begin(); } end()509 const_iterator end() const { return Elements.end(); } 510 rbegin()511 reverse_iterator rbegin() { return Elements.rbegin(); } rend()512 reverse_iterator rend() { return Elements.rend(); } rbegin()513 const_reverse_iterator rbegin() const { return Elements.rbegin(); } rend()514 const_reverse_iterator rend() const { return Elements.rend(); } 515 size()516 unsigned size() const { return Elements.size(); } empty()517 bool empty() const { return Elements.empty(); } 518 519 CFGElement operator[](size_t i) const { return Elements[i]; } 520 521 // CFG iterators 522 typedef AdjacentBlocks::iterator pred_iterator; 523 typedef AdjacentBlocks::const_iterator const_pred_iterator; 524 typedef AdjacentBlocks::reverse_iterator pred_reverse_iterator; 525 typedef AdjacentBlocks::const_reverse_iterator const_pred_reverse_iterator; 526 527 typedef AdjacentBlocks::iterator succ_iterator; 528 typedef AdjacentBlocks::const_iterator const_succ_iterator; 529 typedef AdjacentBlocks::reverse_iterator succ_reverse_iterator; 530 typedef AdjacentBlocks::const_reverse_iterator const_succ_reverse_iterator; 531 pred_begin()532 pred_iterator pred_begin() { return Preds.begin(); } pred_end()533 pred_iterator pred_end() { return Preds.end(); } pred_begin()534 const_pred_iterator pred_begin() const { return Preds.begin(); } pred_end()535 const_pred_iterator pred_end() const { return Preds.end(); } 536 pred_rbegin()537 pred_reverse_iterator pred_rbegin() { return Preds.rbegin(); } pred_rend()538 pred_reverse_iterator pred_rend() { return Preds.rend(); } pred_rbegin()539 const_pred_reverse_iterator pred_rbegin() const { return Preds.rbegin(); } pred_rend()540 const_pred_reverse_iterator pred_rend() const { return Preds.rend(); } 541 succ_begin()542 succ_iterator succ_begin() { return Succs.begin(); } succ_end()543 succ_iterator succ_end() { return Succs.end(); } succ_begin()544 const_succ_iterator succ_begin() const { return Succs.begin(); } succ_end()545 const_succ_iterator succ_end() const { return Succs.end(); } 546 succ_rbegin()547 succ_reverse_iterator succ_rbegin() { return Succs.rbegin(); } succ_rend()548 succ_reverse_iterator succ_rend() { return Succs.rend(); } succ_rbegin()549 const_succ_reverse_iterator succ_rbegin() const { return Succs.rbegin(); } succ_rend()550 const_succ_reverse_iterator succ_rend() const { return Succs.rend(); } 551 succ_size()552 unsigned succ_size() const { return Succs.size(); } succ_empty()553 bool succ_empty() const { return Succs.empty(); } 554 pred_size()555 unsigned pred_size() const { return Preds.size(); } pred_empty()556 bool pred_empty() const { return Preds.empty(); } 557 558 559 class FilterOptions { 560 public: FilterOptions()561 FilterOptions() { 562 IgnoreNullPredecessors = 1; 563 IgnoreDefaultsWithCoveredEnums = 0; 564 } 565 566 unsigned IgnoreNullPredecessors : 1; 567 unsigned IgnoreDefaultsWithCoveredEnums : 1; 568 }; 569 570 static bool FilterEdge(const FilterOptions &F, const CFGBlock *Src, 571 const CFGBlock *Dst); 572 573 template <typename IMPL, bool IsPred> 574 class FilteredCFGBlockIterator { 575 private: 576 IMPL I, E; 577 const FilterOptions F; 578 const CFGBlock *From; 579 public: FilteredCFGBlockIterator(const IMPL & i,const IMPL & e,const CFGBlock * from,const FilterOptions & f)580 explicit FilteredCFGBlockIterator(const IMPL &i, const IMPL &e, 581 const CFGBlock *from, 582 const FilterOptions &f) 583 : I(i), E(e), F(f), From(from) { 584 while (hasMore() && Filter(*I)) 585 ++I; 586 } 587 hasMore()588 bool hasMore() const { return I != E; } 589 590 FilteredCFGBlockIterator &operator++() { 591 do { ++I; } while (hasMore() && Filter(*I)); 592 return *this; 593 } 594 595 const CFGBlock *operator*() const { return *I; } 596 private: Filter(const CFGBlock * To)597 bool Filter(const CFGBlock *To) { 598 return IsPred ? FilterEdge(F, To, From) : FilterEdge(F, From, To); 599 } 600 }; 601 602 typedef FilteredCFGBlockIterator<const_pred_iterator, true> 603 filtered_pred_iterator; 604 605 typedef FilteredCFGBlockIterator<const_succ_iterator, false> 606 filtered_succ_iterator; 607 filtered_pred_start_end(const FilterOptions & f)608 filtered_pred_iterator filtered_pred_start_end(const FilterOptions &f) const { 609 return filtered_pred_iterator(pred_begin(), pred_end(), this, f); 610 } 611 filtered_succ_start_end(const FilterOptions & f)612 filtered_succ_iterator filtered_succ_start_end(const FilterOptions &f) const { 613 return filtered_succ_iterator(succ_begin(), succ_end(), this, f); 614 } 615 616 // Manipulation of block contents 617 setTerminator(CFGTerminator Term)618 void setTerminator(CFGTerminator Term) { Terminator = Term; } setLabel(Stmt * Statement)619 void setLabel(Stmt *Statement) { Label = Statement; } setLoopTarget(const Stmt * loopTarget)620 void setLoopTarget(const Stmt *loopTarget) { LoopTarget = loopTarget; } setHasNoReturnElement()621 void setHasNoReturnElement() { HasNoReturnElement = true; } 622 getTerminator()623 CFGTerminator getTerminator() { return Terminator; } getTerminator()624 const CFGTerminator getTerminator() const { return Terminator; } 625 626 Stmt *getTerminatorCondition(bool StripParens = true); 627 628 const Stmt *getTerminatorCondition(bool StripParens = true) const { 629 return const_cast<CFGBlock*>(this)->getTerminatorCondition(StripParens); 630 } 631 getLoopTarget()632 const Stmt *getLoopTarget() const { return LoopTarget; } 633 getLabel()634 Stmt *getLabel() { return Label; } getLabel()635 const Stmt *getLabel() const { return Label; } 636 hasNoReturnElement()637 bool hasNoReturnElement() const { return HasNoReturnElement; } 638 getBlockID()639 unsigned getBlockID() const { return BlockID; } 640 getParent()641 CFG *getParent() const { return Parent; } 642 643 void dump() const; 644 645 void dump(const CFG *cfg, const LangOptions &LO, bool ShowColors = false) const; 646 void print(raw_ostream &OS, const CFG* cfg, const LangOptions &LO, 647 bool ShowColors) const; 648 void printTerminator(raw_ostream &OS, const LangOptions &LO) const; printAsOperand(raw_ostream & OS,bool)649 void printAsOperand(raw_ostream &OS, bool /*PrintType*/) { 650 OS << "BB#" << getBlockID(); 651 } 652 653 /// Adds a (potentially unreachable) successor block to the current block. 654 void addSuccessor(AdjacentBlock Succ, BumpVectorContext &C); 655 appendStmt(Stmt * statement,BumpVectorContext & C)656 void appendStmt(Stmt *statement, BumpVectorContext &C) { 657 Elements.push_back(CFGStmt(statement), C); 658 } 659 appendInitializer(CXXCtorInitializer * initializer,BumpVectorContext & C)660 void appendInitializer(CXXCtorInitializer *initializer, 661 BumpVectorContext &C) { 662 Elements.push_back(CFGInitializer(initializer), C); 663 } 664 appendNewAllocator(CXXNewExpr * NE,BumpVectorContext & C)665 void appendNewAllocator(CXXNewExpr *NE, 666 BumpVectorContext &C) { 667 Elements.push_back(CFGNewAllocator(NE), C); 668 } 669 appendBaseDtor(const CXXBaseSpecifier * BS,BumpVectorContext & C)670 void appendBaseDtor(const CXXBaseSpecifier *BS, BumpVectorContext &C) { 671 Elements.push_back(CFGBaseDtor(BS), C); 672 } 673 appendMemberDtor(FieldDecl * FD,BumpVectorContext & C)674 void appendMemberDtor(FieldDecl *FD, BumpVectorContext &C) { 675 Elements.push_back(CFGMemberDtor(FD), C); 676 } 677 appendTemporaryDtor(CXXBindTemporaryExpr * E,BumpVectorContext & C)678 void appendTemporaryDtor(CXXBindTemporaryExpr *E, BumpVectorContext &C) { 679 Elements.push_back(CFGTemporaryDtor(E), C); 680 } 681 appendAutomaticObjDtor(VarDecl * VD,Stmt * S,BumpVectorContext & C)682 void appendAutomaticObjDtor(VarDecl *VD, Stmt *S, BumpVectorContext &C) { 683 Elements.push_back(CFGAutomaticObjDtor(VD, S), C); 684 } 685 appendDeleteDtor(CXXRecordDecl * RD,CXXDeleteExpr * DE,BumpVectorContext & C)686 void appendDeleteDtor(CXXRecordDecl *RD, CXXDeleteExpr *DE, BumpVectorContext &C) { 687 Elements.push_back(CFGDeleteDtor(RD, DE), C); 688 } 689 690 // Destructors must be inserted in reversed order. So insertion is in two 691 // steps. First we prepare space for some number of elements, then we insert 692 // the elements beginning at the last position in prepared space. beginAutomaticObjDtorsInsert(iterator I,size_t Cnt,BumpVectorContext & C)693 iterator beginAutomaticObjDtorsInsert(iterator I, size_t Cnt, 694 BumpVectorContext &C) { 695 return iterator(Elements.insert(I.base(), Cnt, 696 CFGAutomaticObjDtor(nullptr, 0), C)); 697 } insertAutomaticObjDtor(iterator I,VarDecl * VD,Stmt * S)698 iterator insertAutomaticObjDtor(iterator I, VarDecl *VD, Stmt *S) { 699 *I = CFGAutomaticObjDtor(VD, S); 700 return ++I; 701 } 702 }; 703 704 /// \brief CFGCallback defines methods that should be called when a logical 705 /// operator error is found when building the CFG. 706 class CFGCallback { 707 public: CFGCallback()708 CFGCallback() {} compareAlwaysTrue(const BinaryOperator * B,bool isAlwaysTrue)709 virtual void compareAlwaysTrue(const BinaryOperator *B, bool isAlwaysTrue) {} compareBitwiseEquality(const BinaryOperator * B,bool isAlwaysTrue)710 virtual void compareBitwiseEquality(const BinaryOperator *B, 711 bool isAlwaysTrue) {} ~CFGCallback()712 virtual ~CFGCallback() {} 713 }; 714 715 /// CFG - Represents a source-level, intra-procedural CFG that represents the 716 /// control-flow of a Stmt. The Stmt can represent an entire function body, 717 /// or a single expression. A CFG will always contain one empty block that 718 /// represents the Exit point of the CFG. A CFG will also contain a designated 719 /// Entry block. The CFG solely represents control-flow; it consists of 720 /// CFGBlocks which are simply containers of Stmt*'s in the AST the CFG 721 /// was constructed from. 722 class CFG { 723 public: 724 //===--------------------------------------------------------------------===// 725 // CFG Construction & Manipulation. 726 //===--------------------------------------------------------------------===// 727 728 class BuildOptions { 729 std::bitset<Stmt::lastStmtConstant> alwaysAddMask; 730 public: 731 typedef llvm::DenseMap<const Stmt *, const CFGBlock*> ForcedBlkExprs; 732 ForcedBlkExprs **forcedBlkExprs; 733 CFGCallback *Observer; 734 bool PruneTriviallyFalseEdges; 735 bool AddEHEdges; 736 bool AddInitializers; 737 bool AddImplicitDtors; 738 bool AddTemporaryDtors; 739 bool AddStaticInitBranches; 740 bool AddCXXNewAllocator; 741 alwaysAdd(const Stmt * stmt)742 bool alwaysAdd(const Stmt *stmt) const { 743 return alwaysAddMask[stmt->getStmtClass()]; 744 } 745 746 BuildOptions &setAlwaysAdd(Stmt::StmtClass stmtClass, bool val = true) { 747 alwaysAddMask[stmtClass] = val; 748 return *this; 749 } 750 setAllAlwaysAdd()751 BuildOptions &setAllAlwaysAdd() { 752 alwaysAddMask.set(); 753 return *this; 754 } 755 BuildOptions()756 BuildOptions() 757 : forcedBlkExprs(nullptr), Observer(nullptr), 758 PruneTriviallyFalseEdges(true), AddEHEdges(false), 759 AddInitializers(false), AddImplicitDtors(false), 760 AddTemporaryDtors(false), AddStaticInitBranches(false), 761 AddCXXNewAllocator(false) {} 762 }; 763 764 /// \brief Provides a custom implementation of the iterator class to have the 765 /// same interface as Function::iterator - iterator returns CFGBlock 766 /// (not a pointer to CFGBlock). 767 class graph_iterator { 768 public: 769 typedef const CFGBlock value_type; 770 typedef value_type& reference; 771 typedef value_type* pointer; 772 typedef BumpVector<CFGBlock*>::iterator ImplTy; 773 graph_iterator(const ImplTy & i)774 graph_iterator(const ImplTy &i) : I(i) {} 775 776 bool operator==(const graph_iterator &X) const { return I == X.I; } 777 bool operator!=(const graph_iterator &X) const { return I != X.I; } 778 779 reference operator*() const { return **I; } 780 pointer operator->() const { return *I; } 781 operator CFGBlock* () { return *I; } 782 783 graph_iterator &operator++() { ++I; return *this; } 784 graph_iterator &operator--() { --I; return *this; } 785 786 private: 787 ImplTy I; 788 }; 789 790 class const_graph_iterator { 791 public: 792 typedef const CFGBlock value_type; 793 typedef value_type& reference; 794 typedef value_type* pointer; 795 typedef BumpVector<CFGBlock*>::const_iterator ImplTy; 796 const_graph_iterator(const ImplTy & i)797 const_graph_iterator(const ImplTy &i) : I(i) {} 798 799 bool operator==(const const_graph_iterator &X) const { return I == X.I; } 800 bool operator!=(const const_graph_iterator &X) const { return I != X.I; } 801 802 reference operator*() const { return **I; } 803 pointer operator->() const { return *I; } 804 operator CFGBlock* () const { return *I; } 805 806 const_graph_iterator &operator++() { ++I; return *this; } 807 const_graph_iterator &operator--() { --I; return *this; } 808 809 private: 810 ImplTy I; 811 }; 812 813 /// buildCFG - Builds a CFG from an AST. 814 static std::unique_ptr<CFG> buildCFG(const Decl *D, Stmt *AST, ASTContext *C, 815 const BuildOptions &BO); 816 817 /// createBlock - Create a new block in the CFG. The CFG owns the block; 818 /// the caller should not directly free it. 819 CFGBlock *createBlock(); 820 821 /// setEntry - Set the entry block of the CFG. This is typically used 822 /// only during CFG construction. Most CFG clients expect that the 823 /// entry block has no predecessors and contains no statements. setEntry(CFGBlock * B)824 void setEntry(CFGBlock *B) { Entry = B; } 825 826 /// setIndirectGotoBlock - Set the block used for indirect goto jumps. 827 /// This is typically used only during CFG construction. setIndirectGotoBlock(CFGBlock * B)828 void setIndirectGotoBlock(CFGBlock *B) { IndirectGotoBlock = B; } 829 830 //===--------------------------------------------------------------------===// 831 // Block Iterators 832 //===--------------------------------------------------------------------===// 833 834 typedef BumpVector<CFGBlock*> CFGBlockListTy; 835 typedef CFGBlockListTy::iterator iterator; 836 typedef CFGBlockListTy::const_iterator const_iterator; 837 typedef std::reverse_iterator<iterator> reverse_iterator; 838 typedef std::reverse_iterator<const_iterator> const_reverse_iterator; 839 front()840 CFGBlock & front() { return *Blocks.front(); } back()841 CFGBlock & back() { return *Blocks.back(); } 842 begin()843 iterator begin() { return Blocks.begin(); } end()844 iterator end() { return Blocks.end(); } begin()845 const_iterator begin() const { return Blocks.begin(); } end()846 const_iterator end() const { return Blocks.end(); } 847 nodes_begin()848 graph_iterator nodes_begin() { return graph_iterator(Blocks.begin()); } nodes_end()849 graph_iterator nodes_end() { return graph_iterator(Blocks.end()); } nodes_begin()850 const_graph_iterator nodes_begin() const { 851 return const_graph_iterator(Blocks.begin()); 852 } nodes_end()853 const_graph_iterator nodes_end() const { 854 return const_graph_iterator(Blocks.end()); 855 } 856 rbegin()857 reverse_iterator rbegin() { return Blocks.rbegin(); } rend()858 reverse_iterator rend() { return Blocks.rend(); } rbegin()859 const_reverse_iterator rbegin() const { return Blocks.rbegin(); } rend()860 const_reverse_iterator rend() const { return Blocks.rend(); } 861 getEntry()862 CFGBlock & getEntry() { return *Entry; } getEntry()863 const CFGBlock & getEntry() const { return *Entry; } getExit()864 CFGBlock & getExit() { return *Exit; } getExit()865 const CFGBlock & getExit() const { return *Exit; } 866 getIndirectGotoBlock()867 CFGBlock * getIndirectGotoBlock() { return IndirectGotoBlock; } getIndirectGotoBlock()868 const CFGBlock * getIndirectGotoBlock() const { return IndirectGotoBlock; } 869 870 typedef std::vector<const CFGBlock*>::const_iterator try_block_iterator; try_blocks_begin()871 try_block_iterator try_blocks_begin() const { 872 return TryDispatchBlocks.begin(); 873 } try_blocks_end()874 try_block_iterator try_blocks_end() const { 875 return TryDispatchBlocks.end(); 876 } 877 addTryDispatchBlock(const CFGBlock * block)878 void addTryDispatchBlock(const CFGBlock *block) { 879 TryDispatchBlocks.push_back(block); 880 } 881 882 /// Records a synthetic DeclStmt and the DeclStmt it was constructed from. 883 /// 884 /// The CFG uses synthetic DeclStmts when a single AST DeclStmt contains 885 /// multiple decls. addSyntheticDeclStmt(const DeclStmt * Synthetic,const DeclStmt * Source)886 void addSyntheticDeclStmt(const DeclStmt *Synthetic, 887 const DeclStmt *Source) { 888 assert(Synthetic->isSingleDecl() && "Can handle single declarations only"); 889 assert(Synthetic != Source && "Don't include original DeclStmts in map"); 890 assert(!SyntheticDeclStmts.count(Synthetic) && "Already in map"); 891 SyntheticDeclStmts[Synthetic] = Source; 892 } 893 894 typedef llvm::DenseMap<const DeclStmt *, const DeclStmt *>::const_iterator 895 synthetic_stmt_iterator; 896 897 /// Iterates over synthetic DeclStmts in the CFG. 898 /// 899 /// Each element is a (synthetic statement, source statement) pair. 900 /// 901 /// \sa addSyntheticDeclStmt synthetic_stmt_begin()902 synthetic_stmt_iterator synthetic_stmt_begin() const { 903 return SyntheticDeclStmts.begin(); 904 } 905 906 /// \sa synthetic_stmt_begin synthetic_stmt_end()907 synthetic_stmt_iterator synthetic_stmt_end() const { 908 return SyntheticDeclStmts.end(); 909 } 910 911 //===--------------------------------------------------------------------===// 912 // Member templates useful for various batch operations over CFGs. 913 //===--------------------------------------------------------------------===// 914 915 template <typename CALLBACK> VisitBlockStmts(CALLBACK & O)916 void VisitBlockStmts(CALLBACK& O) const { 917 for (const_iterator I=begin(), E=end(); I != E; ++I) 918 for (CFGBlock::const_iterator BI=(*I)->begin(), BE=(*I)->end(); 919 BI != BE; ++BI) { 920 if (Optional<CFGStmt> stmt = BI->getAs<CFGStmt>()) 921 O(const_cast<Stmt*>(stmt->getStmt())); 922 } 923 } 924 925 //===--------------------------------------------------------------------===// 926 // CFG Introspection. 927 //===--------------------------------------------------------------------===// 928 929 /// getNumBlockIDs - Returns the total number of BlockIDs allocated (which 930 /// start at 0). getNumBlockIDs()931 unsigned getNumBlockIDs() const { return NumBlockIDs; } 932 933 /// size - Return the total number of CFGBlocks within the CFG 934 /// This is simply a renaming of the getNumBlockIDs(). This is necessary 935 /// because the dominator implementation needs such an interface. size()936 unsigned size() const { return NumBlockIDs; } 937 938 //===--------------------------------------------------------------------===// 939 // CFG Debugging: Pretty-Printing and Visualization. 940 //===--------------------------------------------------------------------===// 941 942 void viewCFG(const LangOptions &LO) const; 943 void print(raw_ostream &OS, const LangOptions &LO, bool ShowColors) const; 944 void dump(const LangOptions &LO, bool ShowColors) const; 945 946 //===--------------------------------------------------------------------===// 947 // Internal: constructors and data. 948 //===--------------------------------------------------------------------===// 949 CFG()950 CFG() 951 : Entry(nullptr), Exit(nullptr), IndirectGotoBlock(nullptr), NumBlockIDs(0), 952 Blocks(BlkBVC, 10) {} 953 getAllocator()954 llvm::BumpPtrAllocator& getAllocator() { 955 return BlkBVC.getAllocator(); 956 } 957 getBumpVectorContext()958 BumpVectorContext &getBumpVectorContext() { 959 return BlkBVC; 960 } 961 962 private: 963 CFGBlock *Entry; 964 CFGBlock *Exit; 965 CFGBlock* IndirectGotoBlock; // Special block to contain collective dispatch 966 // for indirect gotos 967 unsigned NumBlockIDs; 968 969 BumpVectorContext BlkBVC; 970 971 CFGBlockListTy Blocks; 972 973 /// C++ 'try' statements are modeled with an indirect dispatch block. 974 /// This is the collection of such blocks present in the CFG. 975 std::vector<const CFGBlock *> TryDispatchBlocks; 976 977 /// Collects DeclStmts synthesized for this CFG and maps each one back to its 978 /// source DeclStmt. 979 llvm::DenseMap<const DeclStmt *, const DeclStmt *> SyntheticDeclStmts; 980 }; 981 } // end namespace clang 982 983 //===----------------------------------------------------------------------===// 984 // GraphTraits specializations for CFG basic block graphs (source-level CFGs) 985 //===----------------------------------------------------------------------===// 986 987 namespace llvm { 988 989 /// Implement simplify_type for CFGTerminator, so that we can dyn_cast from 990 /// CFGTerminator to a specific Stmt class. 991 template <> struct simplify_type< ::clang::CFGTerminator> { 992 typedef ::clang::Stmt *SimpleType; 993 static SimpleType getSimplifiedValue(::clang::CFGTerminator Val) { 994 return Val.getStmt(); 995 } 996 }; 997 998 // Traits for: CFGBlock 999 1000 template <> struct GraphTraits< ::clang::CFGBlock *> { 1001 typedef ::clang::CFGBlock NodeType; 1002 typedef ::clang::CFGBlock::succ_iterator ChildIteratorType; 1003 1004 static NodeType* getEntryNode(::clang::CFGBlock *BB) 1005 { return BB; } 1006 1007 static inline ChildIteratorType child_begin(NodeType* N) 1008 { return N->succ_begin(); } 1009 1010 static inline ChildIteratorType child_end(NodeType* N) 1011 { return N->succ_end(); } 1012 }; 1013 1014 template <> struct GraphTraits< const ::clang::CFGBlock *> { 1015 typedef const ::clang::CFGBlock NodeType; 1016 typedef ::clang::CFGBlock::const_succ_iterator ChildIteratorType; 1017 1018 static NodeType* getEntryNode(const clang::CFGBlock *BB) 1019 { return BB; } 1020 1021 static inline ChildIteratorType child_begin(NodeType* N) 1022 { return N->succ_begin(); } 1023 1024 static inline ChildIteratorType child_end(NodeType* N) 1025 { return N->succ_end(); } 1026 }; 1027 1028 template <> struct GraphTraits<Inverse< ::clang::CFGBlock*> > { 1029 typedef ::clang::CFGBlock NodeType; 1030 typedef ::clang::CFGBlock::const_pred_iterator ChildIteratorType; 1031 1032 static NodeType *getEntryNode(Inverse< ::clang::CFGBlock*> G) 1033 { return G.Graph; } 1034 1035 static inline ChildIteratorType child_begin(NodeType* N) 1036 { return N->pred_begin(); } 1037 1038 static inline ChildIteratorType child_end(NodeType* N) 1039 { return N->pred_end(); } 1040 }; 1041 1042 template <> struct GraphTraits<Inverse<const ::clang::CFGBlock*> > { 1043 typedef const ::clang::CFGBlock NodeType; 1044 typedef ::clang::CFGBlock::const_pred_iterator ChildIteratorType; 1045 1046 static NodeType *getEntryNode(Inverse<const ::clang::CFGBlock*> G) 1047 { return G.Graph; } 1048 1049 static inline ChildIteratorType child_begin(NodeType* N) 1050 { return N->pred_begin(); } 1051 1052 static inline ChildIteratorType child_end(NodeType* N) 1053 { return N->pred_end(); } 1054 }; 1055 1056 // Traits for: CFG 1057 1058 template <> struct GraphTraits< ::clang::CFG* > 1059 : public GraphTraits< ::clang::CFGBlock *> { 1060 1061 typedef ::clang::CFG::graph_iterator nodes_iterator; 1062 1063 static NodeType *getEntryNode(::clang::CFG* F) { return &F->getEntry(); } 1064 static nodes_iterator nodes_begin(::clang::CFG* F) { return F->nodes_begin();} 1065 static nodes_iterator nodes_end(::clang::CFG* F) { return F->nodes_end(); } 1066 static unsigned size(::clang::CFG* F) { return F->size(); } 1067 }; 1068 1069 template <> struct GraphTraits<const ::clang::CFG* > 1070 : public GraphTraits<const ::clang::CFGBlock *> { 1071 1072 typedef ::clang::CFG::const_graph_iterator nodes_iterator; 1073 1074 static NodeType *getEntryNode( const ::clang::CFG* F) { 1075 return &F->getEntry(); 1076 } 1077 static nodes_iterator nodes_begin( const ::clang::CFG* F) { 1078 return F->nodes_begin(); 1079 } 1080 static nodes_iterator nodes_end( const ::clang::CFG* F) { 1081 return F->nodes_end(); 1082 } 1083 static unsigned size(const ::clang::CFG* F) { 1084 return F->size(); 1085 } 1086 }; 1087 1088 template <> struct GraphTraits<Inverse< ::clang::CFG*> > 1089 : public GraphTraits<Inverse< ::clang::CFGBlock*> > { 1090 1091 typedef ::clang::CFG::graph_iterator nodes_iterator; 1092 1093 static NodeType *getEntryNode( ::clang::CFG* F) { return &F->getExit(); } 1094 static nodes_iterator nodes_begin( ::clang::CFG* F) {return F->nodes_begin();} 1095 static nodes_iterator nodes_end( ::clang::CFG* F) { return F->nodes_end(); } 1096 }; 1097 1098 template <> struct GraphTraits<Inverse<const ::clang::CFG*> > 1099 : public GraphTraits<Inverse<const ::clang::CFGBlock*> > { 1100 1101 typedef ::clang::CFG::const_graph_iterator nodes_iterator; 1102 1103 static NodeType *getEntryNode(const ::clang::CFG* F) { return &F->getExit(); } 1104 static nodes_iterator nodes_begin(const ::clang::CFG* F) { 1105 return F->nodes_begin(); 1106 } 1107 static nodes_iterator nodes_end(const ::clang::CFG* F) { 1108 return F->nodes_end(); 1109 } 1110 }; 1111 } // end llvm namespace 1112 #endif 1113