【问题标题】:libclang python how to get number of arguments for function with default valueslibclang python如何获取具有默认值的函数的参数数量
【发布时间】:2017-12-04 21:10:35
【问题描述】:

我正在使用带有 python 绑定的 libclang,并且我正在尝试获取 CallExpr 的参数数量,我发现如果成员函数具有默认值并且在缺少此参数的情况下被调用,则 libclang 返回参数的数量在函数声明中,而不是在调用表达式中。

例如:

class SomeClass
{
public:
    int sum(int x, int y)
    {
        return x + y;
    }

    int sum_def(int x, int y = 0)
    {
        return x + y;
    }
};

int main()
{
    SomeClass x;
    x.sum(10, 100);
    x.sum_def(20);
    return 0;
}

使用 liblcang 遍历 ast:

def traverse(node):
    if node.kind == clang.cindex.CursorKind.CALL_EXPR:
        print('%-35s %-20s %-10s [%-6s:%s - %-6s:%s] %s %s ' % (
        node.kind, node.spelling, node.type.spelling, node.extent.start.line, node.extent.start.column,
        node.extent.end.line, node.extent.end.column, node.location.file, node.mangled_name))
        print("%d  " % node.get_num_arguments())
        for arg in node.get_arguments():
            print("ARG=%s %s" % (arg.kind, arg.spelling))

    for child in node.get_children():
        traverse(child)

输出:

CursorKind.CALL_EXPR                sum                  int        [20    :5 - 20    :19] main.cpp
2  
ARG=CursorKind.INTEGER_LITERAL 
ARG=CursorKind.INTEGER_LITERAL 
CursorKind.CALL_EXPR                sum_def              int        [21    :5 - 21    :18] main.cpp  
2  
ARG=CursorKind.INTEGER_LITERAL 
ARG=CursorKind.UNEXPOSED_EXPR 

我希望在 sum_def 的 CALL_EXPR 中得到 1 作为参数的数量,有可能得到它,或者我应该自己解析代码,这是我真的不想做的事情。 谢谢。

【问题讨论】:

    标签: python c++ abstract-syntax-tree clang++ libclang


    【解决方案1】:

    我改变了一点遍历函数来打印更多细节

    def traverse(node, level):
        print('%s %-35s %-20s %-10s [%-6s:%s - %-6s:%s] %s %s ' % (' ' * level,
        node.kind, node.spelling, node.type.spelling, node.extent.start.line, node.extent.start.column,
        node.extent.end.line, node.extent.end.column, node.location.file, node.mangled_name))
        if node.kind == clang.cindex.CursorKind.CALL_EXPR:
            for arg in node.get_arguments():
                print("ARG=%s %s" % (arg.kind, arg.spelling))
    
        for child in node.get_children():
            traverse(child, level+1)
    

    输出:

      CursorKind.CLASS_DECL               SomeClass            SomeClass  [2     :1 - 14    :2] main.cpp  
       CursorKind.CXX_ACCESS_SPEC_DECL                                     [4     :1 - 4     :8] main.cpp  
       CursorKind.CXX_METHOD               sum                  int (int, int) [5     :5 - 8     :6] main.cpp _ZN9SomeClass3sumEii 
        CursorKind.PARM_DECL                x                    int        [5     :13 - 5     :18] main.cpp _ZZN9SomeClass3sumEiiE1x 
        CursorKind.PARM_DECL                y                    int        [5     :20 - 5     :25] main.cpp _ZZN9SomeClass3sumEiiE1y 
        CursorKind.COMPOUND_STMT                                            [6     :5 - 8     :6] main.cpp  
         CursorKind.RETURN_STMT                                              [7     :9 - 7     :21] main.cpp  
          CursorKind.BINARY_OPERATOR                               int        [7     :16 - 7     :21] main.cpp  
           CursorKind.UNEXPOSED_EXPR           x                    int        [7     :16 - 7     :17] main.cpp  
            CursorKind.DECL_REF_EXPR            x                    int        [7     :16 - 7     :17] main.cpp  
           CursorKind.UNEXPOSED_EXPR           y                    int        [7     :20 - 7     :21] main.cpp  
            CursorKind.DECL_REF_EXPR            y                    int        [7     :20 - 7     :21] main.cpp  
       CursorKind.CXX_METHOD               sum_def              int (int, int) [10    :5 - 13    :6] main.cpp _ZN9SomeClass7sum_defEii 
        CursorKind.PARM_DECL                x                    int        [10    :17 - 10    :22] main.cpp _ZZN9SomeClass7sum_defEiiE1x 
        CursorKind.PARM_DECL                y                    int        [10    :24 - 10    :33] main.cpp _ZZN9SomeClass7sum_defEiiE1y 
         CursorKind.INTEGER_LITERAL                               int        [10    :32 - 10    :33] main.cpp  
        CursorKind.COMPOUND_STMT                                            [11    :5 - 13    :6] main.cpp  
         CursorKind.RETURN_STMT                                              [12    :9 - 12    :21] main.cpp  
          CursorKind.BINARY_OPERATOR                               int        [12    :16 - 12    :21] main.cpp  
           CursorKind.UNEXPOSED_EXPR           x                    int        [12    :16 - 12    :17] main.cpp  
            CursorKind.DECL_REF_EXPR            x                    int        [12    :16 - 12    :17] main.cpp  
           CursorKind.UNEXPOSED_EXPR           y                    int        [12    :20 - 12    :21] main.cpp  
            CursorKind.DECL_REF_EXPR            y                    int        [12    :20 - 12    :21] main.cpp  
      CursorKind.FUNCTION_DECL            main                 int ()     [17    :1 - 26    :2] main.cpp main 
       CursorKind.COMPOUND_STMT                                            [18    :1 - 26    :2] main.cpp  
        CursorKind.DECL_STMT                                                [19    :5 - 19    :22] main.cpp  
         CursorKind.VAR_DECL                 i                    int        [19    :5 - 19    :14] main.cpp _ZZ4mainE1i 
          CursorKind.INTEGER_LITERAL                               int        [19    :13 - 19    :14] main.cpp  
         CursorKind.VAR_DECL                 j                    int        [19    :16 - 19    :21] main.cpp _ZZ4mainE1j 
          CursorKind.INTEGER_LITERAL                               int        [19    :20 - 19    :21] main.cpp  
        CursorKind.DECL_STMT                                                [20    :5 - 20    :17] main.cpp  
         CursorKind.VAR_DECL                 x                    SomeClass  [20    :5 - 20    :16] main.cpp _ZZ4mainE1x 
          CursorKind.TYPE_REF                 class SomeClass      SomeClass  [20    :5 - 20    :14] main.cpp  
          CursorKind.CALL_EXPR                SomeClass            SomeClass  [20    :15 - 20    :16] main.cpp  
        CursorKind.CALL_EXPR                sum                  int        [21    :5 - 21    :19] main.cpp  
    ARG=CursorKind.INTEGER_LITERAL 
    ARG=CursorKind.INTEGER_LITERAL 
         CursorKind.MEMBER_REF_EXPR          sum                  <bound member function type> [21    :5 - 21    :10] main.cpp  
          CursorKind.DECL_REF_EXPR            x                    SomeClass  [21    :5 - 21    :6] main.cpp  
         CursorKind.INTEGER_LITERAL                               int        [21    :11 - 21    :13] main.cpp  
         CursorKind.INTEGER_LITERAL                               int        [21    :15 - 21    :18] main.cpp  
        CursorKind.CALL_EXPR                sum_def              int        [22    :5 - 22    :18] main.cpp  
    ARG=CursorKind.INTEGER_LITERAL 
    ARG=CursorKind.UNEXPOSED_EXPR 
         CursorKind.MEMBER_REF_EXPR          sum_def              <bound member function type> [22    :5 - 22    :14] main.cpp  
          CursorKind.DECL_REF_EXPR            x                    SomeClass  [22    :5 - 22    :6] main.cpp  
         CursorKind.INTEGER_LITERAL                               int        [22    :15 - 22    :17] main.cpp  
         CursorKind.UNEXPOSED_EXPR                                int        [0     :0 - 0     :0] None  
        CursorKind.CALL_EXPR                sum_def              int        [23    :5 - 23    :23] main.cpp  
    ARG=CursorKind.INTEGER_LITERAL 
    ARG=CursorKind.INTEGER_LITERAL 
         CursorKind.MEMBER_REF_EXPR          sum_def              <bound member function type> [23    :5 - 23    :14] main.cpp  
          CursorKind.DECL_REF_EXPR            x                    SomeClass  [23    :5 - 23    :6] main.cpp  
         CursorKind.INTEGER_LITERAL                               int        [23    :15 - 23    :17] main.cpp  
         CursorKind.INTEGER_LITERAL                               int        [23    :19 - 23    :22] main.cpp  
        CursorKind.CALL_EXPR                sum                  int        [24    :5 - 24    :16] main.cpp  
    ARG=CursorKind.UNEXPOSED_EXPR i
    ARG=CursorKind.UNEXPOSED_EXPR j
         CursorKind.MEMBER_REF_EXPR          sum                  <bound member function type> [24    :5 - 24    :10] main.cpp  
          CursorKind.DECL_REF_EXPR            x                    SomeClass  [24    :5 - 24    :6] main.cpp  
         CursorKind.UNEXPOSED_EXPR           i                    int        [24    :11 - 24    :12] main.cpp  
          CursorKind.DECL_REF_EXPR            i                    int        [24    :11 - 24    :12] main.cpp  
         CursorKind.UNEXPOSED_EXPR           j                    int        [24    :14 - 24    :15] main.cpp  
          CursorKind.DECL_REF_EXPR            j                    int        [24    :14 - 24    :15] main.cpp  
        CursorKind.RETURN_STMT                                              [25    :5 - 25    :13] main.cpp  
         CursorKind.INTEGER_LITERAL                               int        [25    :12 - 25    :13] main.cpp  
    

    有了这个输出,以及我添加到源代码中的更多测试用例,我明白我应该将每个不是 UNEXPOSED_EXPR 的参数都算作参数,如果它是 UNEXPOSED_EXRP,我应该检查它是否有孩子。如果是,则表示我需要计算它。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-02-09
      • 2012-11-27
      • 2013-08-11
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多