首先,示例代码中似乎有几个拼写错误(n = 123
, i <= myBoundFunc(N), i++
)。
无论如何,了解 AST 发生了什么的最简单方法是转储 AST。假设这是测试程序:
int myBoundFunc(int);
void testASTVistor (int N) {
N = 123;
for (int i = 0; i <= myBoundFunc(N); i++ ){
//do Sth;
}
}
你可以让 Clang 转储 AST:
clang -cc1 -ast-dump test.c
您将获得以下输出:
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>
如果我的问题是正确的,那么您正在寻找以下代码段:
| `-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'
在这种情况下,您不需要FunctionDecl
,而是可以获取CallExpr
via的第一个 argRHS->getArg(0)
并将其转换为DeclRefExpr
并进行进一步检查以获得所需的值。
至于FunctionDecl::getParamDecl
回归,没有看到声明NULL
就很难说。myBoundFunc