6

考虑以下简单的头文件 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(tags/RELEASE_31/final),目标:x86_64-unknown-linux-gnu 线程模型:posix。

4

1 回答 1

5

我可能会说:不是这样。

AST 本身没有表示宏。类型、属性等...所有具有语义值的元素都被表示(和注释),并且您可以选择查询其中一些是否从宏扩展并取回原来的宏拼写;但是,宏本身根本不会出现在 AST 中。

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

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

编辑:今天刚刚降落!Clang 现在将在其 AST 中保留所有属性(即使是它不理解的属性)。

于 2012-09-30T16:09:37.013 回答