Search code examples
pythoncallbackfunction-callslibclang

using libclang, callback function does not traverse recursively and does not visit all functions


I am following an example which shows limitation of python bindings, from site http://eli.thegreenplace.net/2011/07/03/parsing-c-in-python-with-clang/ It uses "libclang visitation API directly".

import sys
import clang.cindex

def callexpr_visitor(node, parent, userdata):
    if node.kind == clang.cindex.CursorKind.CALL_EXPR:
          print 'Found %s [line=%s, col=%s]' % (
              node.spelling, node.location.line, node.location.column)
    return 2 # means continue visiting recursively

index = clang.cindex.Index.create()
tu = index.parse(sys.argv[1])
clang.cindex.Cursor_visit(
             tu.cursor,
            clang.cindex.Cursor_visit_callback(callexpr_visitor),
            None)

The output shows all functions called along with their line numbers.

Found foo [line=8, col=5]
Found foo [line=10, col=9]
Found bar [line=15, col=5]
Found foo [line=16, col=9]
Found bar [line=17, col=9]

When I run the same code, I only get output

Found bar [line=15, col=5]

The version I use is llvm3.1 with windows (with the changes suggested in the link).

I feel, returning 2 is not calling the callback function again. I have even tried using 'get_children' on node and traversing without callback, I get the same result.

import sys
import clang.cindex

#def callexpr_visitor(node, parent, userdata):
def callexpr_visitor(node):
    if node.kind == clang.cindex.CursorKind.CALL_EXPR:
            print 'Found %s [line=%s, col=%s]' % (
             clang.cindex.Cursor_displayname(node), node.location.line, node.location.column)
    for c in node.get_children():
           callexpr_visitor(c)
    #return 2 # means continue visiting recursively

index = clang.cindex.Index.create()
tu = index.parse(sys.argv[1])
#clang.cindex.Cursor_visit(
#        tu.cursor,
#        clang.cindex.Cursor_visit_callback(callexpr_visitor),
#        None)
callexpr_visitor(tu.cursor)

I could not get the reason for this behavior after much search and trials. Can anyone explain this please ? Regards.


Solution

  • I think I found the reason for this.

    If I change the return type of function 'foo', from 'bool' to 'int', I get the expected result.

    This may be as 'bool' is not a keyword in 'c'. That was simple.