【问题标题】:In libclang how to exclude functions from stdio.h在 libclang 如何从 stdio.h 中排除函数
【发布时间】:2014-01-30 19:15:26
【问题描述】:

使用libclang时,如何从stdio.h中排除函数?

当我使用下面的源代码只收集函数定义时,我最终也会从 stdio.h 中获取所有函数。

我读到我们可以在创建索引时传递“-x c-header”类型的参数。但是这种给出参数的方式是否适用于 libclang。

tu = index.parse(self.filename, "-x c-header")

在包含“c-header”参数后,它要我也填写“unsaved_files”数组,按照“cindex.py”中“parse”函数的定义。

def parse(self, path, args = [], unsaved_files = [], options = 0):

我不知道这样做的正确方法是什么。

def funcdefn_visitor(self, node, parent, userdata):
    if node.kind == clang.cindex.CursorKind.FUNCTION_DECL: #gives function definitions
        self.func_defn.append(clang.cindex.Cursor_displayname(node))
        self.func_defn_line_no.append(node.location.line)
        self.func_defn_col_no.append(node.location.column)
    print 'Found %s [line=%s, col=%s]' % (
        clang.cindex.Cursor_displayname(node),
        node.location.line,
        node.location.column)
    return 2 # means continue visiting recursively

index = clang.cindex.Index.create()

tu = index.parse(self.filename)
#-- link cursor visitor to call back to give function definitions
clang.cindex.Cursor_visit(
    tu.cursor,
    clang.cindex.Cursor_visit_callback(self.funcdefn_visitor),
    None)

【问题讨论】:

    标签: python header-files libclang


    【解决方案1】:

    -x c-header 命令行开关用于生成precompiled headers,而不是从翻译单元中排除标头。

    我认为从特定文件中排除函数的正确方法是在访问 AST 时跳过位于其中的所有节点。为了详细说明您的示例,这个想法是在访问者中进行第一次测试,以尽早跳过文件并避免访问其所有子节点。

    def funcdefn_visitor(self, node, parent, userdata):
    
        # You might want to change the test here
        if node.location.file.endswith("/stdio.h"):
            print "Skipping 'stdio.h'"
            # Continue with next sibling
            return 1
    
        if node.kind == clang.cindex.CursorKind.FUNCTION_DECL: #gives function definitions
            self.func_defn.append(clang.cindex.Cursor_displayname(node))
            self.func_defn_line_no.append(node.location.line)
            self.func_defn_col_no.append(node.location.column)
    
        print 'Found %s [line=%s, col=%s]' % (
            clang.cindex.Cursor_displayname(node),
            node.location.line,
            node.location.column)
    
        # Continue visiting recursively
        return 2
    
    index = clang.cindex.Index.create()
    
    tu = index.parse(self.filename)
    #-- link cursor visitor to call back to give function definitions
    clang.cindex.Cursor_visit(
        tu.cursor,
        clang.cindex.Cursor_visit_callback(self.funcdefn_visitor),
        None)
    

    现在我不是cindex.pylibclang 的 python API)的专家,但我认为您的示例遵循 C API 概念而不是 python 概念。引用文档(强调我的):

    这个模块提供了一个 Clang 索引库的接口。它是一个 尝试匹配 Clang 的索引库的低级接口 API 直接同时也是“pythonic”。与 C API 的显着差异 是:

    • 字符串结果作为 Python 字符串返回,而不是 CXString 对象。

    • 空游标被转换为无。

    • 对子游标的访问是通过迭代完成的,而不是访问。

    虽然cindex.pyCursor_visit 绑定到clang_visitChildren,但它甚至不会导出CXChildVisitResult 枚举,这意味着您需要对BreakContinueRecurse 的值进行硬编码。 pythonic 的做事方式包括在子节点上迭代,由Cursor.get_children() 方法返回。这些 SO 答案(12)中给出了一个示例,您可以根据源文件对其进行调整以过滤掉节点。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2023-03-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多