为什么#line指令不在clang中的假#if中处理?

时间:2017-07-17 07:46:22

标签: c clang c-preprocessor preprocessor

考虑以下test.c

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

请注意,此处#if条件为false。

我需要这样做,在执行以下命令后输出不会为空:

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==0更改为1==1并运行上述内容 命令,我们得到以下输出:

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

换句话说,我需要clang始终尊重#line内的#if指令,即使它是假的。

这是从ctangle正确编译输出所必需的。 否则警告和调试行号都是错误的。

这应该不难做到,因为#if-#endif中的行是 无论如何扫描。

#if-#endif之外的#line指令(以及内部 - 当它为真时)将根据需要进行处理。

所以,我只需要结合这两种行为 - 执行必要的 处理#if-#endif。

中的#line指令

有人能指出我如何改变铿锵源的正确方向吗? (任何clang版本都可以)

1 个答案:

答案 0 :(得分:0)

通过在ctangle.w之后输出#line,可以在#endif中解决问题,如下所示:

@x
case identifier: a=id_lookup(id_first,id_loc,0)-name_dir;
  app_repl((a / 0400)+0200);
  app_repl(a % 0400); break;
@y
case identifier: a=id_lookup(id_first,id_loc,0)-name_dir;
  app_repl((a / 0400)+0200);
  app_repl(a % 0400);
  if (*buffer=='#' && id_first==buffer+1 && id_loc-id_first==5 && strncmp("endif",id_first,5)==0)
    {@<Insert the line number into |tok_mem|@>}
  break;
@z

现在我们可以在预处理器条件中使用节。 我们可以使用更改预处理器条件的更改文件。