是否有可能从clang的解析树中提取预处理器信息?

时间:2012-09-30 15:42:03

标签: c++ parsing serialization clang c-preprocessor

考虑以下简单的标题demo.h:

#define PERSIST
struct Serialised
{
    int someTransientValue ;
    PERSIST int aNumberToPersist ;
};

我使用以下代码和Clang的python API迭代标题:

import sys, clang.cindex
def callexpr_visitor(node, parent, userdata):
    if node.location.file: print node.location.file, node.displayname, node.kind
    return 2
tu = clang.cindex.Index.create().parse(sys.argv[1], args=['-x', 'c++'])
clang.cindex.Cursor_visit(tu.cursor, clang.cindex.Cursor_visit_callback(callexpr_visitor), None)

这将打印出Clang AST的元素,产生以下输出:

  

demo.h序列化CursorKind.STRUCT_DECL
      demo.h someTransientValue CursorKind.FIELD_DECL
      demo.h aNumberToPersist CursorKind.FIELD_DECL

有没有人知道如何提取与名为'aNumberToPersist'的成员变量相关联的预处理器声明?是否有更好的方法以在解析树中清楚显示的方式“标记”变量?

Xubuntu 12.04,clang 3.1版(标签/ RELEASE_31 / final),目标:x86_64-unknown-linux-gnu 线程模型:posix。

1 个答案:

答案 0 :(得分:4)

我可能会说:不是这样。

宏本身并未在AST中表示。类型,属性等...所有那些具有语义值的元素都被表示(和注释),并且可选地,您可以查询其中一些元素是否从宏中扩展并返回原始宏拼写;然而,宏本身并没有出现在AST中。

如果可以的话,使用新的属性 扩展 Clang可能会更有趣,尤其是在C ++ 11中:[[gearoid::persist]]。 C ++ 11要求编译器忽略他们不知道的属性,因此通过“命名”你自己的属性,你几乎可以保证只有你会关心它们的含义。

不幸的是,我不知道你是否需要向Clang讲授你的属性,以便它们在AST中表示(Michael Han正在努力记住它们)。无论如何,您可以在Clang DEV邮件列表上获得更多有用的答案(遗憾的是,没有Clang Users邮件列表)。

编辑:只是landed today! Clang现在将在其AST中保留所有属性(甚至是那些它不理解的属性)。