| //===- CFGBuilder.h - CFG building and updating utility ----------*- C++ -*-==// | 
 | // | 
 | //                     The LLVM Compiler Infrastructure | 
 | // | 
 | // This file is distributed under the University of Illinois Open Source | 
 | // License. See LICENSE.TXT for details. | 
 | // | 
 | //===----------------------------------------------------------------------===// | 
 | /// \file | 
 | /// CFGBuilders provides utilities fo building and updating CFG for testing | 
 | /// purposes. | 
 | /// | 
 | //===----------------------------------------------------------------------===// | 
 |  | 
 | #ifndef LLVM_UNITTESTS_CFG_BUILDER_H | 
 | #define LLVM_UNITTESTS_CFG_BUILDER_H | 
 |  | 
 | #include "llvm/ADT/DenseMap.h" | 
 | #include "llvm/ADT/Optional.h" | 
 | #include "llvm/ADT/StringMap.h" | 
 | #include "llvm/ADT/StringRef.h" | 
 | #include "llvm/Support/Debug.h" | 
 |  | 
 | #include <memory> | 
 | #include <set> | 
 | #include <tuple> | 
 | #include <vector> | 
 |  | 
 | namespace llvm { | 
 |  | 
 | class LLVMContext; | 
 | class Module; | 
 | class Function; | 
 | class BasicBlock; | 
 | class raw_ostream; | 
 |  | 
 | struct CFGHolder { | 
 |   std::unique_ptr<LLVMContext> Context; | 
 |   std::unique_ptr<Module> M; | 
 |   Function *F; | 
 |  | 
 |   CFGHolder(StringRef ModuleName = "m", StringRef FunctionName = "foo"); | 
 |   ~CFGHolder(); // Defined in the .cpp file so we can use forward declarations. | 
 | }; | 
 |  | 
 | /// \brief | 
 | /// CFGBuilder builds IR with specific CFG, based on the supplied list of arcs. | 
 | /// It's able to apply the provided updates and automatically modify the IR. | 
 | /// | 
 | /// Internally it makes every basic block end with either SwitchInst or with | 
 | /// UnreachableInst. When all arc to a BB are deleted, the BB remains in the | 
 | /// function and doesn't get deleted. | 
 | /// | 
 | class CFGBuilder { | 
 | public: | 
 |   struct Arc { | 
 |     StringRef From; | 
 |     StringRef To; | 
 |  | 
 |     friend bool operator<(const Arc &LHS, const Arc &RHS) { | 
 |       return std::tie(LHS.From, LHS.To) < | 
 |              std::tie(RHS.From, RHS.To); | 
 |     } | 
 |   }; | 
 |  | 
 |   enum class ActionKind { Insert, Delete }; | 
 |   struct Update { | 
 |     ActionKind Action; | 
 |     Arc Edge; | 
 |   }; | 
 |  | 
 |   CFGBuilder(Function *F, const std::vector<Arc> &InitialArcs, | 
 |              std::vector<Update> Updates); | 
 |  | 
 |   BasicBlock *getOrAddBlock(StringRef BlockName); | 
 |   Optional<Update> getNextUpdate() const; | 
 |   Optional<Update> applyUpdate(); | 
 |   void dump(raw_ostream &OS = dbgs()) const; | 
 |  | 
 | private: | 
 |   void buildCFG(const std::vector<Arc> &Arcs); | 
 |   bool connect(const Arc &A); | 
 |   bool disconnect(const Arc &A); | 
 |  | 
 |   Function *F; | 
 |   unsigned UpdateIdx = 0; | 
 |   StringMap<BasicBlock *> NameToBlock; | 
 |   std::set<Arc> Arcs; | 
 |   std::vector<Update> Updates; | 
 | }; | 
 |  | 
 | } // namespace llvm | 
 |  | 
 | #endif |