使用libclang,我有一个AST的游标,它对应于宏扩展产生的语句。我想检索原始的,未展开的宏文本。
我已经找了一个libclang API来做这个,但找不到一个。我错过了什么吗?
假设这样的API不存在,我会看到几种方法可以做到这一点,两者都基于使用clang_getCursorExtent()来获取光标的源范围 - 这可能是原始的范围文本。
第一个想法是使用clang_getFileLocation()来获取范围开始和结束的文件名和位置,并直接从文件中读取文本。如果我是从未保存的文件编译的,那么我需要处理它,但我对这种方法的主要关注是,当我确信clang在内部保存所有这些信息时,外出到文件系统似乎是不对的。 。如果已加载AST而不是生成AST,或者源文件在解析后已被修改,也会有影响。
第二种方法是在游标范围上调用clang_tokenize()。我尝试这样做,发现它无法为AST中的大多数游标生成令牌列表。跟踪代码,结果是内部clang_tokenize()操纵提供的范围并最终得出结论它跨越多个文件(可能是由于宏扩展的某些影响),并且中止。这对我来说似乎不对,但我确实觉得无论如何我都在滥用clang_tokenize()试图这样做。
那么,最好的方法是什么?
答案 0 :(得分:11)
这是我找到的唯一方法。
因此,您使用clang_getTranslationUnitCursor()
获得顶级光标。然后,您执行clang_visitChildren()
,将访问者函数传递给此返回CXChildVisit_Continue
,以便仅返回直接子项。在子级中,您可以看到顶级声明的常用游标类型(如CXCursor_TypedefDecl
,CXCursor_EnumDecl
),但其中还有CXCursor_MacroExpansion
。每个宏扩展似乎都显示在具有此类型的游标中。然后,您可以在任何这些游标上调用clang_tokenize()
,它会为您提供未展开的宏文本。
我不知道为什么宏扩展会在AST顶部附近而不是在使用它们的元素中陷入困境,这会让事情变得非常尴尬。例如:
enum someEnum{
one = SOMEMACRO,
two,
three
}
如果SOMEMACRO的宏扩展光标位于枚举声明中而不是它的兄弟,那就太好了。
(我意识到这是非常晚了,但我希望这会让libclang更多曝光,也许更有经验的人可以提供更多的洞察力)。