CFGElement CFGBlock的最基本元素
enum Kind {
// main kind
Statement,
Initializer,
NewAllocator,
// dtor kind
AutomaticObjectDtor,
DeleteDtor,
BaseDtor,
MemberDtor,
TemporaryDtor,
DTOR_BEGIN = AutomaticObjectDtor,
DTOR_END = TemporaryDtor
};
代表具体每一条语句,Terminator除外
CFGElement每种kind都有一个相应的子类,如
class CFGStmt : public CFGElement {
public:
CFGStmt(Stmt *S) : CFGElement(Statement, S) {}
const Stmt *getStmt() const {
return static_cast<const Stmt *>(Data1.getPointer());
}
private:
friend class CFGElement;
CFGStmt() {}
static bool isKind(const CFGElement &E) {
return E.getKind() == Statement;
}
};
CFGStmt代表普通的语句
/// CFGInitializer - Represents C++ base or member initializer from
/// constructor's initialization list.
class CFGInitializer : public CFGElement {
public:
CFGInitializer(CXXCtorInitializer *initializer)
: CFGElement(Initializer, initializer) {}
CXXCtorInitializer* getInitializer() const {
return static_cast(Data1.getPointer());
}
private:
friend class CFGElement;
CFGInitializer() {}
static bool isKind(const CFGElement &E) {
return E.getKind() == Initializer;
}
};
CFGInitializer表示构造函数的初始化列表
/// CFGNewAllocator - Represents C++ allocator call.
class CFGNewAllocator : public CFGElement {
public:
explicit CFGNewAllocator(const CXXNewExpr *S)
: CFGElement(NewAllocator, S) {}
// Get the new expression.
const CXXNewExpr *getAllocatorExpr() const {
return static_cast(Data1.getPointer());
}
private:
friend class CFGElement;
CFGNewAllocator() {}
static bool isKind(const CFGElement &elem) {
return elem.getKind() == NewAllocator;
}
};
CFGNewAllocator顾名思义,表示内存分配的new表达式
/// CFGImplicitDtor - Represents C++ object destructor implicitly generated
/// by compiler on various occasions.
class CFGImplicitDtor : public CFGElement {
protected:
CFGImplicitDtor() {}
CFGImplicitDtor(Kind kind, const void *data1, const void *data2 = nullptr)
: CFGElement(kind, data1, data2) {
assert(kind >= DTOR_BEGIN && kind <= DTOR_END);
}
public:
const CXXDestructorDecl *getDestructorDecl(ASTContext &astContext) const;
bool isNoReturn(ASTContext &astContext) const;
private:
friend class CFGElement;
static bool isKind(const CFGElement &E) {
Kind kind = E.getKind();
return kind >= DTOR_BEGIN && kind <= DTOR_END;
}
};
CFGImplicitDtor,前面的kind枚举值中并没有出现ImplicitDtor这个kind。其实ImplicitDtor表示的是一类语句,即编译器隐式调用地对象析构函数,比如对象的作用域结束、调用delete表达式,都会隐式地调用到析构函数。虽然没有单独作为一个kind,但是之后的AutomaticObjectDtor等kind的子类都继承于CFGImplicitDtor,也就是说从AutomaticObjectDtor开始,表示的都是更加精确的析构方式。
继承关系
CFGTerminator CFGBlock的终结语句
class CFGTerminator {
llvm::PointerIntPair1> Data;
public:
CFGTerminator() {}
CFGTerminator(Stmt *S, bool TemporaryDtorsBranch = false)
: Data(S, TemporaryDtorsBranch) {}
Stmt *getStmt() { return Data.getPointer(); }
const Stmt *getStmt() const { return Data.getPointer(); }
bool isTemporaryDtorsBranch() const { return Data.getInt(); }
operator Stmt *() { return getStmt(); }
operator const Stmt *() const { return getStmt(); }
Stmt *operator->() { return getStmt(); }
const Stmt *operator->() const { return getStmt(); }
Stmt &operator*() { return *getStmt(); }
const Stmt &operator*() const { return *getStmt(); }
explicit operator bool() const { return getStmt(); }
};
CFGBlock CFG中独立的基本块
完整的Block由三部分组成
1、声明/表达式的集合;
2、一个Terminator;
3、前驱列表和后继列表。
声明和表达式的集合由一个ElementList类型的对象表示
/// Stmts - The set of statements in the basic block.
ElementList Elements;
ElementList声明在CFGBlock内部
class ElementList {
typedef BumpVector<CFGElement> ImplTy;
ImplTy Impl;
public:
ElementList(BumpVectorContext &C) : Impl(C, 4) {}
typedef std::reverse_iterator<ImplTy::iterator> iterator;
typedef std::reverse_iterator<ImplTy::const_iterator> const_iterator;
typedef ImplTy::iterator reverse_iterator;
typedef ImplTy::const_iterator const_reverse_iterator;
typedef ImplTy::const_reference const_reference;
void push_back(CFGElement e, BumpVectorContext &C) { Impl.push_back(e, C); }
...
CFGElement operator[](size_t i) const {
assert(i < Impl.size());
return Impl[Impl.size() - 1 - i];
}
size_t size() const { return Impl.size(); }
bool empty() const { return Impl.empty(); }
};
Terminator由一个CFGTerminator类型的变量表示
/// Terminator - The terminator for a basic block that
/// indicates the type of control-flow that occurs between a block
/// and its successors.
CFGTerminator Terminator;
/// CFGTerminator - Represents CFGBlock terminator statement.
///
/// TemporaryDtorsBranch bit is set to true if the terminator marks a branch
/// in control flow of destructors of temporaries. In this case terminator
/// statement is the same statement that branches control flow in evaluation
/// of matching full expression.
class CFGTerminator {
llvm::PointerIntPair1> Data;
public:
CFGTerminator() {}
CFGTerminator(Stmt *S, bool TemporaryDtorsBranch = false)
: Data(S, TemporaryDtorsBranch) {}
Stmt *getStmt() { return Data.getPointer(); }
const Stmt *getStmt() const { return Data.getPointer(); }
bool isTemporaryDtorsBranch() const { return Data.getInt(); }
operator Stmt *() { return getStmt(); }
operator const Stmt *() const { return getStmt(); }
Stmt *operator->() { return getStmt(); }
const Stmt *operator->() const { return getStmt(); }
Stmt &operator*() { return *getStmt(); }
const Stmt &operator*() const { return *getStmt(); }
explicit operator bool() const { return getStmt(); }
};
CFGTerminator的构造如上所示。
前驱和后继的保存由两个AdjacentBlock的vector保存
/// Predecessors/Successors - Keep track of the predecessor / successor
/// CFG blocks.
typedef BumpVector AdjacentBlocks;
AdjacentBlocks Preds;
AdjacentBlocks Succs;
AdjacentBlock表示一个潜在相邻的CFGBlock,并判断它是否可达
class AdjacentBlock {
enum Kind {
AB_Normal,
AB_Unreachable,
AB_Alternate
};
CFGBlock *ReachableBlock;
llvm::PointerIntPair<CFGBlock*, 2> UnreachableBlock;
public:
/// Construct an AdjacentBlock with a possibly unreachable block.
AdjacentBlock(CFGBlock *B, bool IsReachable);
/// Construct an AdjacentBlock with a reachable block and an alternate
/// unreachable block.
AdjacentBlock(CFGBlock *B, CFGBlock *AlternateBlock);
...
};
CFGBlock还有诸如BlockID等等属性,还有一个CFG对象作为它的parent。
CFG对象可以看做是CFGBlock的集合。至少有一个Entry和Exit的CFGBlock,此外还有一个保存CFGBlock的vector
CFGBlock *Entry;
CFGBlock *Exit;
...
CFGBlockListTy Blocks;
此外,CFG还有比如针对try statements的vector
/// C++ 'try' statements are modeled with an indirect dispatch block.
/// This is the collection of such blocks present in the CFG.
std::vector<const CFGBlock *> TryDispatchBlocks;
等等其他属性
其中一个比较重要的函数是
CFGBlock *CFG::createBlock() {
bool first_block = begin() == end();
// Create the block.
CFGBlock *Mem = getAllocator().Allocate();
new (Mem) CFGBlock(NumBlockIDs++, BlkBVC, this);
Blocks.push_back(Mem, BlkBVC);
// If this is the first block, set it as the Entry and Exit.
if (first_block)
Entry = Exit = &back();
// Return the block.
return &back();
}
负责生成一个新的CFGBlock。这里所用的new经过重载,提前分配好内存空间
CFGBlock *Mem = getAllocator().Allocate();
然后直接对这块内存通过new调用构造函数
new (Mem) CFGBlock(NumBlockIDs++, BlkBVC, this);
也就是所谓的placement new