首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >展开宏并检索宏值

展开宏并检索宏值
EN

Stack Overflow用户
提问于 2016-07-17 22:18:12
回答 2查看 3.1K关注 0票数 2

我正在尝试使用libclang python绑定来解析我的c++源文件。无法获得宏的值或展开宏。

这是我的示例c++代码

代码语言:javascript
复制
#define FOO 6001
#define EXPAND_MACR \
        int \
        foo = 61
int main()
{
    EXPAND_MACR;
    cout <<  foo;
    return 0;
}

这是我的python脚本

代码语言:javascript
复制
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回来的信息:

代码语言:javascript
复制
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就会发出

代码语言:javascript
复制
DATA <clang.cindex.c_void_p_Array_3 object at 0x10b86d950>

我可以读取clang返回的区段数据&然后将文件从start解析到end位置以获得值。我想知道,是否有更好的方法来获取宏值?

我希望直接获得宏的值(示例中的6001)(不使用范围)。我怎么能拿到呢?

另外,对于,EXPAND_MACR,想要得到int foo = 61

我已经看过这样的帖子:链接-1 & 链接-2

如有任何帮助,将不胜感激。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2016-07-19 09:41:41

不,使用区段逐行展开似乎是提取(展开的宏)的唯一方法。

我怀疑问题在于当libclang看到您的代码时,宏已经被预处理器删除了--您在AST中看到的节点更像是注释,而不是真正的节点。

代码语言:javascript
复制
#define FOO 6001
#define EXPAND_MACR \
        int \
        foo = 61
int main()
{
    EXPAND_MACR;
    return 0;
}

是真正的AST

代码语言:javascript
复制
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 

这相当于只运行预处理器(并告诉它给出所有预处理器指令的列表)。通过运行,您可以看到类似的内容:

代码语言:javascript
复制
clang -E -Wp,-dD src.cc

这意味着:

代码语言:javascript
复制
# 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;
}
票数 5
EN

Stack Overflow用户

发布于 2020-07-21 17:45:31

解决方法是使用所有宏创建另一个文件。

Example.hpp

代码语言:javascript
复制
#include "header_with_macro_ABC.h"

auto abc = ABC:

然后,您可以再次解析这个头文件以提取变量声明,并使用评价方法可以获得该值。

Pros:无需编写自己的表达式解析器。Cons:需要创建和解析另一个文件。

在许多情况下,这种方法可能并不可行,但对我来说,当我必须解析法根 (用于Dart的绑定生成器)的所有宏时,它才是可行的。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/38426460

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档