考虑以下简单的标题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。
答案 0 :(得分:4)
我可能会说:不是这样。
宏本身并未在AST中表示。类型,属性等...所有那些具有语义值的元素都被表示(和注释),并且可选地,您可以查询其中一些元素是否从宏中扩展并返回原始宏拼写;然而,宏本身并没有出现在AST中。
如果可以的话,使用新的属性 扩展 Clang可能会更有趣,尤其是在C ++ 11中:[[gearoid::persist]]
。 C ++ 11要求编译器忽略他们不知道的属性,因此通过“命名”你自己的属性,你几乎可以保证只有你会关心它们的含义。
不幸的是,我不知道你是否需要向Clang讲授你的属性,以便它们在AST中表示(Michael Han正在努力记住它们)。无论如何,您可以在Clang DEV邮件列表上获得更多有用的答案(遗憾的是,没有Clang Users邮件列表)。
编辑:只是landed today! Clang现在将在其AST中保留所有属性(甚至是那些它不理解的属性)。