blob: 44fa4503b8e0e67e61b6d776c5374af3e3404038 [file] [log] [blame]
//===-- MCFunction.h --------------------------------------------*- C++ -*-===//
// The LLVM Compiler Infrastructure
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
// This file defines the data structures to hold a CFG reconstructed from
// machine code.
#include "llvm/ADT/StringRef.h"
#include "llvm/MC/MCInst.h"
#include <memory>
#include <string>
#include <vector>
namespace llvm {
class MCFunction;
class MCModule;
class MCTextAtom;
/// \brief Basic block containing a sequence of disassembled instructions.
/// The basic block is backed by an MCTextAtom, which holds the instructions,
/// and the address range it covers.
/// Create a basic block using MCFunction::createBlock.
class MCBasicBlock {
const MCTextAtom *Insts;
// MCFunction owns the basic block.
MCFunction *Parent;
friend class MCFunction;
MCBasicBlock(const MCTextAtom &Insts, MCFunction *Parent);
/// \name Predecessors/Successors, to represent the CFG.
/// @{
typedef std::vector<const MCBasicBlock *> BasicBlockListTy;
BasicBlockListTy Successors;
BasicBlockListTy Predecessors;
/// @}
/// \brief Get the backing MCTextAtom, containing the instruction sequence.
const MCTextAtom *getInsts() const { return Insts; }
/// \name Get the owning MCFunction.
/// @{
const MCFunction *getParent() const { return Parent; }
MCFunction *getParent() { return Parent; }
/// @}
/// MC CFG access: Predecessors/Successors.
/// @{
typedef BasicBlockListTy::const_iterator succ_const_iterator;
succ_const_iterator succ_begin() const { return Successors.begin(); }
succ_const_iterator succ_end() const { return Successors.end(); }
typedef BasicBlockListTy::const_iterator pred_const_iterator;
pred_const_iterator pred_begin() const { return Predecessors.begin(); }
pred_const_iterator pred_end() const { return Predecessors.end(); }
void addSuccessor(const MCBasicBlock *MCBB);
bool isSuccessor(const MCBasicBlock *MCBB) const;
void addPredecessor(const MCBasicBlock *MCBB);
bool isPredecessor(const MCBasicBlock *MCBB) const;
/// \brief Split block, mirrorring NewAtom = Insts->split(..).
/// This moves all successors to \p SplitBB, and
/// adds a fallthrough to it.
/// \p SplitBB The result of splitting Insts, a basic block directly following
/// this basic block.
void splitBasicBlock(MCBasicBlock *SplitBB);
/// @}
/// \brief Represents a function in machine code, containing MCBasicBlocks.
/// MCFunctions are created by MCModule.
class MCFunction {
MCFunction (const MCFunction&) LLVM_DELETED_FUNCTION;
MCFunction& operator=(const MCFunction&) LLVM_DELETED_FUNCTION;
std::string Name;
MCModule *ParentModule;
typedef std::vector<std::unique_ptr<MCBasicBlock>> BasicBlockListTy;
BasicBlockListTy Blocks;
// MCModule owns the function.
friend class MCModule;
MCFunction(StringRef Name, MCModule *Parent);
/// \brief Create an MCBasicBlock backed by Insts and add it to this function.
/// \param Insts Sequence of straight-line code backing the basic block.
/// \returns The newly created basic block.
MCBasicBlock &createBlock(const MCTextAtom &Insts);
StringRef getName() const { return Name; }
/// \name Get the owning MC Module.
/// @{
const MCModule *getParent() const { return ParentModule; }
MCModule *getParent() { return ParentModule; }
/// @}
/// \name Access to the function's basic blocks. No ordering is enforced,
/// except that the first block is the entry block.
/// @{
/// \brief Get the entry point basic block.
const MCBasicBlock *getEntryBlock() const { return front(); }
MCBasicBlock *getEntryBlock() { return front(); }
bool empty() const { return Blocks.empty(); }
typedef BasicBlockListTy::const_iterator const_iterator;
typedef BasicBlockListTy:: iterator iterator;
const_iterator begin() const { return Blocks.begin(); }
iterator begin() { return Blocks.begin(); }
const_iterator end() const { return Blocks.end(); }
iterator end() { return Blocks.end(); }
const MCBasicBlock* front() const { return Blocks.front().get(); }
MCBasicBlock* front() { return Blocks.front().get(); }
const MCBasicBlock* back() const { return Blocks.back().get(); }
MCBasicBlock* back() { return Blocks.back().get(); }
/// \brief Find the basic block, if any, that starts at \p StartAddr.
const MCBasicBlock *find(uint64_t StartAddr) const;
MCBasicBlock *find(uint64_t StartAddr);
/// @}