2017-07-17 116 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的补丁是值得欢迎的看...

相关问题