2017-07-17 82 views
1

考慮以下test.c爲什麼#line指令不會在false中在#ng中處理?

int main(void) 
{ 
    int a; 
#if 1==0 
#line 1 "test.c" 
#endif 
    a = 1; 
    return 0; 
} 

注意,即#if條件爲假這裏。

我需要做的話,在執行下列命令後的輸出不會是空的:

clang -g test.c 
objdump -D a.out >dis 
sed -i 's/line 1/line 2/' test.c 
clang -g test.c 
objdump -D a.out | diff dis - 

賺取差價明顯:如果我們在改變。例如1==01==1並運行上述 命令,我們得到以下的輸出:

749c749 
< 33: 05 05 0a c8 05   add $0x5c80a05,%eax 
--- 
> 33: 05 05 0a c9 05   add $0x5c90a05,%eax 

換句話說,我需要讓clang永遠銘記內指令,即使它是假的。

這是正確編譯ctangle輸出所必需的。 否則警告和調試行號都是錯誤的。

這不應該很難做,因爲#if-#endif裏面的行無論如何都是 。

#if-#endif之外的#line指令(以及內部 - 如果爲true)將根據需要進行處理。

所以,我只需要結合這兩種行爲 - 對#if-#endif內的#line指令進行必要的 處理。

有人能指點我正確的方向如何改變叮聲源? (任何clang版本都可以)

+1

編譯器是在嚴格的指令由誰寫的標準忽略的代碼段的內容跳過,因爲不滿意預處理器指令的人(除了確定嵌套'#fif'所需的程度外)。由於#行被跳過,所以它必須被忽略。如果你想處理它,它不能被跳過。 –

+1

ISO/IEC 9899:2011§6.10.1有條件包含¶每個指令的條件都按順序檢查。如果它的計算結果爲false(零),則跳過其控制的組 :指令僅通過確定 指令的名稱進行處理,以便跟蹤嵌套條件的級別; 指令的其他預處理令牌將被忽略, 組中的其他預處理令牌也會被忽略。只有控制條件評估爲真(非零)的第一組是 已處理。_ [...繼續...] –

+1

[...繼續...] _如果沒有任何條件評估爲真,並且存在'#else'指令,則由##控制的 組將被處理;缺少'#else'指令,所有組 直到跳過'#endif'。術語'group'用於描述#if控制的行('#ifdef','#ifndef', '#elif','#endif'指令。 –

回答

0

下修正了這個(適用於鐺,4.0及以上):

clang/lib/Lex/PPDirectives.cpp: 

@@ -358,7 +358,7 @@ 

    char FirstChar = RI[0]; 
    if (FirstChar >= 'a' && FirstChar <= 'z' && 
-  FirstChar != 'i' && FirstChar != 'e') { 
+  FirstChar != 'i' && FirstChar != 'e' && FirstChar != 'l') { 
     CurPPLexer->ParsingPreprocessorDirective = false; 
     // Restore comment saving mode. 
     if (CurLexer) CurLexer->resetExtendedTokenMode(); 
@@ -479,6 +479,11 @@ 
     } 
     } 
    } 
+ else if (Directive[0] == 'l') { 
+  CurPPLexer->LexingRawMode = false; 
+  HandleLineDirective(); 
+  CurPPLexer->LexingRawMode = true; 
+ } 

    CurPPLexer->ParsingPreprocessorDirective = false; 
    // Restore comment saving mode. 

現在我們可以使用在預處理條件的部分(包括像#ifdef條件語句,這是唯一已知的在編譯時)。 我們可以使用更改預處理器條件的更改文件。

https://bugs.llvm.org/show_bug.cgi?id=33806

一種gcc的補丁是值得歡迎的看...

相關問題