2016-10-20 53 views
4

我試圖在LLVM中對標記聯合(也稱爲總和類型)進行編碼,並且在保持編譯器前端平臺不可知的情況下似乎不可能。想象一下,我有這個標籤聯合(拉斯特表示):在LLVM中對標記的聯合(總和類型)進行編碼

enum T { 
    C1(i32, i64), 
    C2(i64) 
} 

爲了這個編碼在LLVM我需要知道知道最大的變量的大小。這又要求我知道所有字段的對齊和大小。換句話說,我的前端需要

  • 跟蹤的大小和所有的東西排列,
  • 創建一個虛擬結構(正確填充)來表示,可以適應任何變異最大的類型(例如{[2 x i64]},假設該標籤可以貼合在同一個詞作爲i32場),
  • 終於或者是用包裝結構或告訴LLVM「數據佈局」我認爲它,所以我的計算匹配LLVMs

什麼是最好的方式目前編碼標記LLVM中的工會?

回答

1

從概念上講,我認爲除了我不介意在聲明站點使用構造類型之外,我認爲沒有比您描述的更好的方法,因爲實際訪問工會最容易通過bitcast無論如何。

下面是鏘的getTypeExpansion()代碼片段,顯示它也做到這一點 - 手動尋找最大的領域:

const FieldDecl *LargestFD = nullptr; 
CharUnits UnionSize = CharUnits::Zero(); 

for (const auto *FD : RD->fields()) { 
    // Skip zero length bitfields. 
    if (FD->isBitField() && FD->getBitWidthValue(Context) == 0) 
    continue; 
    assert(!FD->isBitField() && 
     "Cannot expand structure with bit-field members."); 
    CharUnits FieldSize = Context.getTypeSizeInChars(FD->getType()); 
    if (UnionSize < FieldSize) { 
    UnionSize = FieldSize; 
    LargestFD = FD; 
    } 
} 
if (LargestFD) 
    Fields.push_back(LargestFD); 
+0

你碰巧知道在哪裏,計算返回的值代碼'Context.getTypeSizeInChars'是(該函數只是檢索一個已經計算好的值)計算一個類型的大小(例如嚴格),考慮對齊約束是最棘手的部分之一 – tibbe

+0

@tibbe我不知道所有的計算髮生在哪裏,你必須追蹤下來,我相信起點總是在[TargetInfo]的子類中(http://clang.llvm.org/doxygen/include_2clang_2Basic_2TargetInfo_8h_source.html);取看看[Targets.cpp](http://clang.llvm.org/doxygen/Targets_8cpp_source.html)。 – Oak

相關問題