llvm原始碼類的設計方式有些地方還是很精妙的,下面這個類有很多列舉型別,這個類真實的資料也就是data1和data2,data1和data2除了儲存了兩個指標之外還隱藏了乙個列舉變數,這樣做節省了記憶體,能這樣做的原因是llvm::pointerintpair裡面的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 ;
protected:
// the int bits are used to mark the kind.
llvm::pointerintpairdata1;
llvm::pointerintpairdata2;
cfgelement(kind kind, const void *ptr1, const void *ptr2 = nullptr)
: data1(const_cast(ptr1), ((unsigned) kind) & 0x3),
data2(const_cast(ptr2), (((unsigned) kind) >> 2) & 0x3)
llvm另外乙個比較高明的設計是對於某種有靜態成員類的設計。例如
class a
/// add* - add various data types to bit data.
///void addpointer(const void *ptr);
void addinteger(signed i);
void addinteger(unsigned i);
void addinteger(long i);
void addinteger(unsigned long i);
void addinteger(long long i);
void addinteger(unsigned long long i);
void addboolean(bool b)
void addstring(stringref string);
void addnodeid(const foldingsetnodeid &id);
另外一種比較有意思的設計是,就是通過模板可以知道子類的型別
template
class clusteranalysis {
CentOS以原始碼方式安裝PHP
系統環境 centos 6.5 64位 nginx 1.6.2 mysql 5.6.23 php 5.6.6 依賴庫 為了省事,直接用yum來安裝吧 yum y install libmcrypt devel libxml2 devel curl devel libjpeg devel libpng...
CentOS以原始碼方式安裝Apache
環境 centos 6.5 64位 apache 2.4.12 約定 在安裝之前,我們約定 建立使用者和目錄 建立使用者和使用者組 groupadd apache useradd apache g apache s bin false m 建立 根目錄 mkdir p data web chown ...
Thread 類的原始碼相關
注意 run 方法存在於thread類 和 runnable 介面中 理解以下三種情況 定義乙個類繼承 thread 類,並重新了覆寫 run 方法,原先的 run方法就被子類的 run 方法覆蓋掉了,thread 類run 方法中的 target.run 就不可能執行了,執行緒物件 start 是...