展开宏并检索宏值
Expand macros & retrieve macro values
我正在尝试使用 libclang python 绑定来解析我的 C++ 源文件。我无法获取宏的值或展开宏。
这是我的示例 C++ 代码
#define FOO 6001
#define EXPAND_MACR \
int \
foo = 61
int main()
{
EXPAND_MACR;
cout << foo;
return 0;
}
这是我的 python 脚本
import sys
import clang.cindex
def visit(node):
if node.kind in (clang.cindex.CursorKind.MACRO_INSTANTIATION, clang.cindex.CursorKind.MACRO_DEFINITION):
print 'Found %s Type %s DATA %s Extent %s [line=%s, col=%s]' % (node.displayname, node.kind, node.data, node.extent, node.location.line, node.location.column)
for c in node.get_children():
visit(c)
if __name__ == '__main__':
index = clang.cindex.Index.create()
tu = index.parse(sys.argv[1], options=clang.cindex.TranslationUnit.PARSE_DETAILED_PROCESSING_RECORD)
print 'Translation unit:', tu.spelling
visit(tu.cursor)
这是我从 clang 得到的信息:
Found FOO Type CursorKind.MACRO_DEFINITION DATA <clang.cindex.c_void_p_Array_3 object at 0x10b86d950> Extent <SourceRange start <SourceLocation file 'sample.cpp', line 4, column 9>, end <SourceLocation file 'sample.cpp', line 4, column 17>> [line=4, col=9]
Found EXPAND_MACR Type CursorKind.MACRO_DEFINITION DATA <clang.cindex.c_void_p_Array_3 object at 0x10b86d950> Extent <SourceRange start <SourceLocation file 'sample.cpp', line 6, column 9>, end <SourceLocation file 'sample.cpp', line 8, column 11>> [line=6, col=9]
Found EXPAND_MACR Type CursorKind.MACRO_INSTANTIATION DATA <clang.cindex.c_void_p_Array_3 object at 0x10b86d950> Extent <SourceRange start <SourceLocation file 'sample.cpp', line 12, column 2>, end <SourceLocation file 'sample.cpp', line 12, column 13>> [line=12, col=2]
如果你观察我的 python 脚本,node.data 给出
DATA <clang.cindex.c_void_p_Array_3 object at 0x10b86d950>
我可以读取 clang 返回的 Extent 数据,然后将文件从 start 解析为 end位置获取值。我想知道是否有更好的方法来获取宏值?
我想直接获取宏(示例中的6001)的值(不使用Extent)。我怎样才能得到它?
另外对于EXPAND_MACR是想得到int foo = 61
我已经看过这些post:Link-1 & Link-2。
任何帮助将不胜感激
不,使用扩展的逐行扩展似乎是提取(扩展宏)的唯一方法。
我怀疑问题是当 libclang 看到您的代码时,预处理器已经删除了宏 - 您在 AST 中看到的节点更像是注释而不是真正的节点。
#define FOO 6001
#define EXPAND_MACR \
int \
foo = 61
int main()
{
EXPAND_MACR;
return 0;
}
真是AST
TRANSLATION_UNIT sample.cpp
+-- ... *some nodes removed for brevity*
+--MACRO_DEFINITION FOO
+--MACRO_DEFINITION EXPAND_MACR
+--MACRO_INSTANTIATION EXPAND_MACR
+--FUNCTION_DECL main
+--COMPOUND_STMT
+--DECL_STMT
| +--VAR_DECL foo
| +--INTEGER_LITERAL
+--RETURN_STMT
+--INTEGER_LITERAL
这相当于 运行 只有预处理器(并告诉它给你一个所有预处理器指令的列表)。你可以通过运行看到类似的东西:
clang -E -Wp,-dD src.cc
给出:
# 1 "<command line>" 1
# 1 "<built-in>" 2
# 1 "src.cc" 2
#define FOO 6001
#define EXPAND_MACR int foo = 61
int main()
{
int foo = 61;
return 0;
}
解决方法是创建另一个包含所有宏的文件
Example.hpp
#include "header_with_macro_ABC.h"
auto abc = ABC:
然后您可以再次解析此头文件以提取变量声明,并使用 evaluate methods 可以获取值。
优点:无需编写自己的表达式解析器。
缺点:需要创建和解析另一个文件。
这种方法在很多情况下可能不可行,但对我来说,当我不得不为 ffigen(Dart 的绑定生成器)解析所有宏时。
我正在尝试使用 libclang python 绑定来解析我的 C++ 源文件。我无法获取宏的值或展开宏。
这是我的示例 C++ 代码
#define FOO 6001
#define EXPAND_MACR \
int \
foo = 61
int main()
{
EXPAND_MACR;
cout << foo;
return 0;
}
这是我的 python 脚本
import sys
import clang.cindex
def visit(node):
if node.kind in (clang.cindex.CursorKind.MACRO_INSTANTIATION, clang.cindex.CursorKind.MACRO_DEFINITION):
print 'Found %s Type %s DATA %s Extent %s [line=%s, col=%s]' % (node.displayname, node.kind, node.data, node.extent, node.location.line, node.location.column)
for c in node.get_children():
visit(c)
if __name__ == '__main__':
index = clang.cindex.Index.create()
tu = index.parse(sys.argv[1], options=clang.cindex.TranslationUnit.PARSE_DETAILED_PROCESSING_RECORD)
print 'Translation unit:', tu.spelling
visit(tu.cursor)
这是我从 clang 得到的信息:
Found FOO Type CursorKind.MACRO_DEFINITION DATA <clang.cindex.c_void_p_Array_3 object at 0x10b86d950> Extent <SourceRange start <SourceLocation file 'sample.cpp', line 4, column 9>, end <SourceLocation file 'sample.cpp', line 4, column 17>> [line=4, col=9]
Found EXPAND_MACR Type CursorKind.MACRO_DEFINITION DATA <clang.cindex.c_void_p_Array_3 object at 0x10b86d950> Extent <SourceRange start <SourceLocation file 'sample.cpp', line 6, column 9>, end <SourceLocation file 'sample.cpp', line 8, column 11>> [line=6, col=9]
Found EXPAND_MACR Type CursorKind.MACRO_INSTANTIATION DATA <clang.cindex.c_void_p_Array_3 object at 0x10b86d950> Extent <SourceRange start <SourceLocation file 'sample.cpp', line 12, column 2>, end <SourceLocation file 'sample.cpp', line 12, column 13>> [line=12, col=2]
如果你观察我的 python 脚本,node.data 给出
DATA <clang.cindex.c_void_p_Array_3 object at 0x10b86d950>
我可以读取 clang 返回的 Extent 数据,然后将文件从 start 解析为 end位置获取值。我想知道是否有更好的方法来获取宏值?
我想直接获取宏(示例中的6001)的值(不使用Extent)。我怎样才能得到它?
另外对于EXPAND_MACR是想得到int foo = 61
我已经看过这些post:Link-1 & Link-2。
任何帮助将不胜感激
不,使用扩展的逐行扩展似乎是提取(扩展宏)的唯一方法。
我怀疑问题是当 libclang 看到您的代码时,预处理器已经删除了宏 - 您在 AST 中看到的节点更像是注释而不是真正的节点。
#define FOO 6001
#define EXPAND_MACR \
int \
foo = 61
int main()
{
EXPAND_MACR;
return 0;
}
真是AST
TRANSLATION_UNIT sample.cpp
+-- ... *some nodes removed for brevity*
+--MACRO_DEFINITION FOO
+--MACRO_DEFINITION EXPAND_MACR
+--MACRO_INSTANTIATION EXPAND_MACR
+--FUNCTION_DECL main
+--COMPOUND_STMT
+--DECL_STMT
| +--VAR_DECL foo
| +--INTEGER_LITERAL
+--RETURN_STMT
+--INTEGER_LITERAL
这相当于 运行 只有预处理器(并告诉它给你一个所有预处理器指令的列表)。你可以通过运行看到类似的东西:
clang -E -Wp,-dD src.cc
给出:
# 1 "<command line>" 1
# 1 "<built-in>" 2
# 1 "src.cc" 2
#define FOO 6001
#define EXPAND_MACR int foo = 61
int main()
{
int foo = 61;
return 0;
}
解决方法是创建另一个包含所有宏的文件
Example.hpp
#include "header_with_macro_ABC.h"
auto abc = ABC:
然后您可以再次解析此头文件以提取变量声明,并使用 evaluate methods 可以获取值。
优点:无需编写自己的表达式解析器。 缺点:需要创建和解析另一个文件。
这种方法在很多情况下可能不可行,但对我来说,当我不得不为 ffigen(Dart 的绑定生成器)解析所有宏时。