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