为什么 #line 指令没有在 clang 的 false #if 中处理?

Why #line directives are not processed inside false #if in clang?

考虑以下 test.c

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

749c749
<   33: 05 05 0a c8 05          add    [=12=]x5c80a05,%eax
---
>   33: 05 05 0a c9 05          add    [=12=]x5c90a05,%eax

换句话说,我需要让 clang 始终遵守 #if 中的 #line 指令,即使它是假的。

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

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

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

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

中处理#line 指令

有人能给我指明正确的方向吗?如何更改 clang 源? (任何 clang 版本都可以)

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

@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

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