如何扩展/"预处理"C++模板代码

sha*_*kin 40 c++ templates c-preprocessor

为了在C++中正确调试复杂的宏,我通常在它们上运行预处理器,以便准确地查看生成的代码的样子.

是否有类似的方法来"预处理"模板代码?

mav*_*rik 19

一种方式(依赖于编译器)是在每个编译器步骤之后使用转储.我写了一个小程序:

template<class T>
T square(T n)
{
    return n * n;
}

int main(void)
{
    square<int>(3);
    square<float>(3.0);
}
Run Code Online (Sandbox Code Playgroud)

然后:

g++ -fdump-rtl-all test.cc
Run Code Online (Sandbox Code Playgroud)

这给我一堆文件.看一下(在我的例子中)test.cc.218.dfinish:

;; Function int main() (main)
;; Function T square(T) [with T = int] (_Z6squareIiET_S0_)
;; Function T square(T) [with T = float] (_Z6squareIfET_S0_)
Run Code Online (Sandbox Code Playgroud)

  • GCC编译`src` => [GENERIC](http://gcc.gnu.org/onlinedocs/gccint/GENERIC.html)=> [GIMPLE](http://gcc.gnu.org/onlinedocs/gccint/GIMPLE .html)=> [RTL](http://gcc.gnu.org/onlinedocs/gccint/RTL.html)=>`asm`.要转储GENERIC/GIMPLE,请使用`-fdump-tree -...`([来自C/C++的GENERIC树](http://gcc.gnu.org/onlinedocs/gccint/C-and-C_002b_002b-Trees.html)使用类似于源语言的语法).更多信息见[GCC手册调试选项部分](http://gcc.gnu.org/onlinedocs/gcc/Debugging-Options.html)和[GCC Internals Manual](http://gcc.gnu.org/ onlinedocs/gccint/index.html的#顶部). (2认同)

Mat*_* M. 7

CLang编译器具有一个选项-emit-ast,用于转储用于表示已解析语言的抽象语法树.将表示模板的各种实例化.

AST在内存和xml版本中都有表示,因此您可以:

  • 只需使用XML输出
  • 解析它,然后生成一些C++代码
  • 创建一个Rewriter工具(直接在CLang中支持)并使用AST本身

对于大多数代码检查(包括检查所选的重载),我发现实际上读取XML输出(以及通过它的浏览)足以满足我的需求.