Matching the argument passed to a function in a ForStmt's Cond using Clang AST Visitors

前端 未结 1 1695
一向
一向 2020-12-22 10:16

I am trying to match the value of an integer passed to a ForStmt\'s condition. However, the loopbound is a call to a FunctionDecl and I don\'t seem

相关标签:
1条回答
  • 2020-12-22 11:09

    First of all, there seems to be a couple of typos in the sample code (n = 123, i <= myBoundFunc(N), i++).

    Anyhow, the easiest way to understand what is going on with the AST is to dump AST. Assuming this is the test program:

    int myBoundFunc(int);
    
    void testASTVistor (int N) {
      N = 123;
      for (int i = 0; i <= myBoundFunc(N); i++ ){
        //do Sth;
      }
    }
    

    You can ask Clang to dump the AST:

    clang -cc1 -ast-dump test.c
    

    You'll get the following output:

    TranslationUnitDecl 0x7fd77b024408 <<invalid sloc>> <invalid sloc>
    |-TypedefDecl 0x7fd77b024ca0 <<invalid sloc>> <invalid sloc> implicit __int128_t '__int128'
    | `-BuiltinType 0x7fd77b0249a0 '__int128'
    |-TypedefDecl 0x7fd77b024d10 <<invalid sloc>> <invalid sloc> implicit __uint128_t 'unsigned __int128'
    | `-BuiltinType 0x7fd77b0249c0 'unsigned __int128'
    |-TypedefDecl 0x7fd77b024ff8 <<invalid sloc>> <invalid sloc> implicit __NSConstantString 'struct __NSConstantString_tag'
    | `-RecordType 0x7fd77b024df0 'struct __NSConstantString_tag'
    |   `-Record 0x7fd77b024d68 '__NSConstantString_tag'
    |-TypedefDecl 0x7fd77b025090 <<invalid sloc>> <invalid sloc> implicit __builtin_ms_va_list 'char *'
    | `-PointerType 0x7fd77b025050 'char *'
    |   `-BuiltinType 0x7fd77b0244a0 'char'
    |-TypedefDecl 0x7fd77b025368 <<invalid sloc>> <invalid sloc> implicit __builtin_va_list 'struct __va_list_tag [1]'
    | `-ConstantArrayType 0x7fd77b025310 'struct __va_list_tag [1]' 1
    |   `-RecordType 0x7fd77b025170 'struct __va_list_tag'
    |     `-Record 0x7fd77b0250e8 '__va_list_tag'
    |-FunctionDecl 0x7fd77b0158d0 <test.c:1:1, col:20> col:5 used myBoundFunc 'int (int)'
    | `-ParmVarDecl 0x7fd77b015800 <col:17> col:20 'int'
    `-FunctionDecl 0x7fd77b015a98 <line:3:1, line:8:1> line:3:6 testASTVistor 'void (int)'
      |-ParmVarDecl 0x7fd77b0159d8 <col:21, col:25> col:25 used N 'int'
      `-CompoundStmt 0x7fd77b015df8 <col:28, line:8:1>
        |-BinaryOperator 0x7fd77b015b80 <line:4:3, col:7> 'int' '='
        | |-DeclRefExpr 0x7fd77b015b40 <col:3> 'int' lvalue ParmVar 0x7fd77b0159d8 'N' 'int'
        | `-IntegerLiteral 0x7fd77b015b60 <col:7> 'int' 123
        `-ForStmt 0x7fd77b015dc0 <line:5:3, line:7:3>
          |-DeclStmt 0x7fd77b015c40 <line:5:8, col:17>
          | `-VarDecl 0x7fd77b015bb8 <col:8, col:16> col:12 used i 'int' cinit
          |   `-IntegerLiteral 0x7fd77b015c20 <col:16> 'int' 0
          |-<<<NULL>>>
          |-BinaryOperator 0x7fd77b015d58 <col:19, col:37> 'int' '<='
          | |-ImplicitCastExpr 0x7fd77b015d40 <col:19> 'int' <LValueToRValue>
          | | `-DeclRefExpr 0x7fd77b015c58 <col:19> 'int' lvalue Var 0x7fd77b015bb8 'i' 'int'
          | `-CallExpr 0x7fd77b015d00 <col:24, col:37> 'int'
          |   |-ImplicitCastExpr 0x7fd77b015ce8 <col:24> 'int (*)(int)' <FunctionToPointerDecay>
          |   | `-DeclRefExpr 0x7fd77b015c78 <col:24> 'int (int)' Function 0x7fd77b0158d0 'myBoundFunc' 'int (int)'
          |   `-ImplicitCastExpr 0x7fd77b015d28 <col:36> 'int' <LValueToRValue>
          |     `-DeclRefExpr 0x7fd77b015c98 <col:36> 'int' lvalue ParmVar 0x7fd77b0159d8 'N' 'int'
          |-UnaryOperator 0x7fd77b015d98 <col:40, col:41> 'int' postfix '++'
          | `-DeclRefExpr 0x7fd77b015d78 <col:40> 'int' lvalue Var 0x7fd77b015bb8 'i' 'int'
          `-CompoundStmt 0x7fd77b015db0 <col:45, line:7:3>
    

    And if I get your question right, then you are looking for the following snippet:

      | `-CallExpr 0x7fd77b015d00 <col:24, col:37> 'int'
      |   |-ImplicitCastExpr 0x7fd77b015ce8 <col:24> 'int (*)(int)' <FunctionToPointerDecay>
      |   | `-DeclRefExpr 0x7fd77b015c78 <col:24> 'int (int)' Function 0x7fd77b0158d0 'myBoundFunc' 'int (int)'
      |   `-ImplicitCastExpr 0x7fd77b015d28 <col:36> 'int' <LValueToRValue>
      |     `-DeclRefExpr 0x7fd77b015c98 <col:36> 'int' lvalue ParmVar 0x7fd77b0159d8 'N'
    

    In which case you don't need the FunctionDecl, but instead you can get the first arg of the CallExpr via RHS->getArg(0) and cast it to the DeclRefExpr and do the further checks to get to the value you need.


    As of the FunctionDecl::getParamDecl returning NULL it is hard to say without seeing the myBoundFunc declaration.

    0 讨论(0)
提交回复
热议问题