解决C和C++中的typedef

Cus*_*zer 8 c c++ typedef c-preprocessor

我正在尝试在任意C++或C项目中自动解析typedef .

因为某些typedef是在系统头文件中定义的(例如uint32),我现在正试图通过在我的代码文件上运行gcc预处理器然后扫描预处理文件中的typedef来实现这一点.然后我应该能够替换项目代码文件中的typedef.

我想知道,如果还有另一种,也许更简单的方法,我就会失踪.你能想到一个吗?

原因,我为什么要这样做:我正在使用不同的工具从C/C++项目中提取代码度量.指标是基于方法的.提取指标后,我必须合并由不同工具生成的数据.问题是,其中一个工具解析了typedef而其他工具则没有.如果有typedef用于方法的参数类型,我将度量标准映射到不同的方法名称,这些方法名称实际上是指源代码中的相同方法.

在源代码中考虑这个方法:int test(uint32 par1, int par2)
运行我的工具后,我有指标,映射到一个名为的方法int test(uint32 par1, int par2),我的一些指标被映射到int test(unsigned int par1, int par2).

D.S*_*ley 5

如果您不关心确定它们的定义位置,可以使用objdump转储解析typedef的C++符号表.

lorien$ objdump --demangle --syms foo

foo:     file format mach-o-i386

SYMBOL TABLE:
00001a24 g       1e SECT   01 0000 .text dyld_stub_binding_helper
00001a38 g       1e SECT   01 0000 .text _dyld_func_lookup
...
00001c7c g       0f SECT   01 0080 .text foo::foo(char const*)
...
Run Code Online (Sandbox Code Playgroud)

此代码段来自以下结构定义:

typedef char const* c_string;
struct foo {
    typedef c_string ntcstring;
    foo(ntcstring s): buf(s) {}
    std::string buf;
};
Run Code Online (Sandbox Code Playgroud)

这确实需要您编译所有内容,它只会在生成的可执行文件中显示符号,因此存在一些限制.另一种选择是让链接器转储符号映射.对于GNU工具,add -Wl,-map-Wl,namewhere name是要生成的文件的名称(请参阅注释).这种方法不会对名称进行解码,但只需要做一些工作就可以对编译器的修改约定进行反向工程.上一个代码段的输出将包含以下内容:

0x00001CBE  0x0000005E  [  2] __ZN3fooC2EPKc
0x00001D1C  0x0000001A  [  2] __ZN3fooC1EPKc
Run Code Online (Sandbox Code Playgroud)

您可以使用C++ ABI规范对这些进行解码.一旦你对它的工作原理感到满意,ABI附带的破碎表就变得无价了.在这种情况下的推导是:

<mangled-name>           ::= '_Z' <encoding>
<encoding>               ::= <name> <bare-function-type>
  <name>                 ::= <nested-name>
    <nested-name>        ::= 'N' <source-name> <ctor-dtor-name> 'E'
      <source-name>      ::= <number> <identifier>
      <ctor-dtor-name>   ::= 'C2' # base object constructor
    <bare-function-type> ::= <type>+
      <type>             ::= 'P' <type> # pointer to
        <type>           ::= <cv-qualifier> <type>
          <cv-qualifier> ::= 'K' # constant
            <type>       ::= 'c' # character
Run Code Online (Sandbox Code Playgroud)

注意:看起来GNU会更改参数,ld因此您可能需要检查本地手册(man ld)以确保映射文件生成命令-mapfilename在您的版本中.在最新版本中,使用-Wl,-Mstdout并将其重定向到文件.