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
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.