使用libclang获取原始(未扩展)宏文本

时间:2013-05-28 07:57:19

标签: clang libclang

使用libclang,我有一个AST的游标,它对应于宏扩展产生的语句。我想检索原始的,未展开的宏文本。

我已经找了一个libclang API来做这个,但找不到一个。我错过了什么吗?

假设这样的API不存在,我会看到几种方法可以做到这一点,两者都基于使用clang_getCursorExtent()来获取光标的源范围 - 这可能是原始的范围文本。

第一个想法是使用clang_getFileLocation()来获取范围开始和结束的文件名和位置,并直接从文件中读取文本。如果我是从未保存的文件编译的,那么我需要处理它,但我对这种方法的主要关注是,当我确信clang在内部保存所有这些信息时,外出到文件系统似乎是不对的。 。如果已加载AST而不是生成AST,或者源文件在解析后已被修改,也会有影响。

第二种方法是在游标范围上调用clang_tokenize()。我尝试这样做,发现它无法为AST中的大多数游标生成令牌列表。跟踪代码,结果是内部clang_tokenize()操纵提供的范围并最终得出结论它跨越多个文件(可能是由于宏扩展的某些影响),并且中止。这对我来说似乎不对,但我确实觉得无论如何我都在滥用clang_tokenize()试图这样做。

那么,最好的方法是什么?

1 个答案:

答案 0 :(得分:11)

这是我找到的唯一方法。

因此,您使用clang_getTranslationUnitCursor()获得顶级光标。然后,您执行clang_visitChildren(),将访问者函数传递给此返回CXChildVisit_Continue,以便仅返回直接子项。在子级中,您可以看到顶级声明的常用游标类型(如CXCursor_TypedefDeclCXCursor_EnumDecl),但其中还有CXCursor_MacroExpansion。每个宏扩展似乎都显示在具有此类型的游标中。然后,您可以在任何这些游标上调用clang_tokenize(),它会为您提供未展开的宏文本。

我不知道为什么宏扩展会在AST顶部附近而不是在使用它们的元素中陷入困境,这会让事情变得非常尴尬。例如:

enum someEnum{
    one = SOMEMACRO,
    two,
    three
}

如果SOMEMACRO的宏扩展光标位于枚举声明中而不是它的兄弟,那就太好了。

(我意识到这是非常晚了,但我希望这会让libclang更多曝光,也许更有经验的人可以提供更多的洞察力)。