llvm源码类的设计方式有些地方还是很精妙的,下面这个类有很多枚举类型,这个类真实的数据也就是Data1和Data2,Data1和Data2除了保存了两个指针之外还隐藏了一个枚举变量,这样做节省了内存,能这样做的原因是llvm::PointerIntPair<void *, 2> 里面的void*的地址值是个对齐的地址,也就是说void*的值至少是4的倍数或者4以上的数字,但是这个数字肯定是2的幂。另外void*也有另外一个精妙的地方,比如某个子类继承了CFGElement,那么要判断父类指针是那个子类,只需要根据它的Kind值判断,例如它的Kind值是Statement,那么就能找到那个子类,如果我们要取出其中的数据,比如我们知道数据在Data1里面,就可以取出其中的数据,不同子类的数据类型不一样,这个时候我们可以在各个子类里面定义一个函数比如叫 getData1() 对于A子类可能返回int*,对于B子类可能返回double*。总体来说我们从一个父类指针通过Kind找到子类,再转化为子类指针,最后获取数据。因为数据都保持在父类里,所以直接从父类转换为子类也没问题,不过需要用到引用 son s; father&f=son; f=value_father; 这样子类就从某个父类获取了数据。
class CFGElement {
public:
enum Kind {
// main kind
Statement,
Initializer,
NewAllocator,
// dtor kind
AutomaticObjectDtor,
DeleteDtor,
BaseDtor,
MemberDtor,