【问题标题】:Insert global variable declaration with a gcc plugin使用 gcc 插件插入全局变量声明
【发布时间】:2014-11-17 20:15:55
【问题描述】:

我想知道是否可以使用 gcc 插件插入全局变量声明。例如,如果我有以下代码:

test.c:

int main(void) {
  return 0;
}

我想把它变成:

int fake_var;

int main(void) {
  return 0;
}

这可能吗? 如果可能的话,在哪一关,我该怎么做?

【问题讨论】:

  • 你想达到什么目的? “gcc 插件”是什么意思? gcc 没有集成的文本编辑器。
  • 通过 gcc 插件我在说这个:gcc.gnu.org/onlinedocs/gccint/Plugins.html#Plugins
  • @AndresTiraboschi 我正在做一些可能与您正在做的事情类似的事情,我希望可以问您一些问题,如果您收到此评论,请告诉我
  • @Othman:嗨,你想做什么?
  • @AndresTiraboschi 嗨,感谢展示,我需要交换一个类的两个字段的位置。这背后的原因是重新排序类的元素以避免填充。示例:class A{ char c; int i;}; 必须转到class A{ int i; char c;}; 我的通行证在 ssa 之后,我正在循环遍历全局命名空间以查找名称。目前,我能够检测到错误的字段顺序,但我不知道如何更改它!欢迎任何帮助,无论如何谢谢!

标签: c++ c gcc gcc-plugins


【解决方案1】:

嗯,不。别。你为什么想要?你不能使用它。

您可以获得的最接近的方法是在新的.c 文件中定义变量并将其单独链接,但仍必须在test.c 中声明(使用extern)以供test.c 使用它。

【讨论】:

  • 我知道我不能使用,但这是最简单的例子。我想知道是否可以使用插件进行该声明。你说不是因为不可能还是因为我没有意义?
  • 插件插入的其他代码为什么不能使用?
【解决方案2】:

您可以创建一个包含要添加到输入文件顶部的代码的文件,并使用-include yourfile 选项。

建议预处理器在输入文件的顶部假定#include "yourfile"

看到这个问题:
Include header files using command line option?

但是您必须单独构建该 c 文件,因为该文件将添加到所有编译单元中。

【讨论】:

    【解决方案3】:

    使用 GCC -D 选项,您可以将值传递给 C 程序。 例如:

    int main()
    {
    printf("global decl %d\n", gvar);
    }
    

    gcc -Dgvar=10 gcc.c

    这可能会提供您正在寻找的最接近的行为,尽管这不等同于全局变量声明。这是编译时的宏替换。

    【讨论】:

      【解决方案4】:

      我想你会想看看 varpool.c 中的 varpool_add_new_variable()。您应该能够将使用类型 VAR_DECL 构建的声明传递给它。同样,看看 add_new_static_var(),但我认为前者是你想要的,因为它是专门添加的,允许在中间/后端声明全局变量。

      【讨论】:

      • 由于“varpool.c”不是由C++定义的,你需要解释一下你在说什么。
      【解决方案5】:

      下面是一个创建全局整数变量的例子:

      //add_new_static_var, in cgraph.h
      tree global_var = add_new_static_var(integer_type_node);
      //if you want to name the var:
      tree name = get_identifier("my_global_name");
      DECL_NAME(global_var) = name;
      /*AND if you have thought to use in another subsequent compilation, you 
        will need to give it an assembler name like this*/
      change_decl_assembler_name(global_var, name);
      

      请记住,在另一个编译中,您应该在与之前的编译之后链接,您也需要声明全局 var,但是您必须在所有编译中使用 DECL_EXTERNAL(global_var) = 1 声明所有 var原始的,并且仅在一个编译中(即原始:包含原始 var 的编译),您必须只添加属性 TREE_PUBLIC(global_var) = 1

      【讨论】: