RecursiveASTVisitor not visiting clang::VarDecl



我有以下c代码test1.c:

double multiply(double x, double y) {
return x * y * y;
}
int main(int argc, char const *argv[])
{
double a;
int b;
float d;
double x = 3.0;
double y = 5.0;
double z = multiply(x,y);
return 0;
}

我试图通过实现bool VistVarDecl(clang::VarDecl *vardecl)让RecursiveASTVisitor访问变量声明(clang::VarDecl(。然而,clang::VarDecl节点从未被访问过,尽管我已经访问了AST中的所有其他节点。此外,在test1.cI上使用clang-query可以匹配varDecl

我的递归ASTVistor如下:

struct MyASTVisitor : public clang::RecursiveASTVistor<MyASTVisitor> {
bool VistVarDecl(clang::VarDecl *vardecl) {
llvm::outs() << "Found a VarDecl";
};
bool VisitFunctionDecl(clang::FunctionDecl *decl) {
llvm::outs() << "Found a FunctionDecl";
};
// other functions implemented similarly just to see if it visits properly
bool VisitParmVarmDecl(clang::ParmVarDecl *paramvardecl);
bool VisitCallExpr(clang::CallExpr *callexpr);
bool VisitImplicitCastExpr(clang::ImplicitCastExpr *castexpr);
bool VisitBinaryOperator(clang::BinaryOperator *bo);
bool VisitDeclStmt(clang::DeclStmt *declstmt);
bool VisitDeclRefExpr(clang::DeclRefExpr *declrefexpr);
bool VisitFloatingLiteral(clang::FloatingLiteral *floatliteral);
};
struct MyASTConsumer : public clang::ASTConsumer {
bool HandleTopLevelDecl(clang::DeclGroupRef DR) override {
for (clang::DeclGroupRef::iterator b = DR.begin(), e = DR.end(); b != e; ++b) {
Visitor.TraverseDecl(*b);
}
return true;
}
private: 
MyASTVisitor Visitor;
};

有人知道clang::VarDecl节点是唯一没有被RecursiveASTVisitor访问但被clang-query匹配的节点吗?

clang的AST转储如下所示:

TranslationUnitDecl 0x7fba2300ce08 <<invalid sloc>> <invalid sloc>
|-TypedefDecl 0x7fba2300d6a0 <<invalid sloc>> <invalid sloc> implicit __int128_t '__int128'
| `-BuiltinType 0x7fba2300d3a0 '__int128'
|-TypedefDecl 0x7fba2300d710 <<invalid sloc>> <invalid sloc> implicit __uint128_t 'unsigned __int128'
| `-BuiltinType 0x7fba2300d3c0 'unsigned __int128'
|-TypedefDecl 0x7fba2300da18 <<invalid sloc>> <invalid sloc> implicit __NSConstantString 'struct __NSConstantString_tag'
| `-RecordType 0x7fba2300d7f0 'struct __NSConstantString_tag'
|   `-Record 0x7fba2300d768 '__NSConstantString_tag'
|-TypedefDecl 0x7fba2300dab0 <<invalid sloc>> <invalid sloc> implicit __builtin_ms_va_list 'char *'
| `-PointerType 0x7fba2300da70 'char *'
|   `-BuiltinType 0x7fba2300cea0 'char'
|-TypedefDecl 0x7fba2300dda8 <<invalid sloc>> <invalid sloc> implicit __builtin_va_list 'struct __va_list_tag [1]'
| `-ConstantArrayType 0x7fba2300dd50 'struct __va_list_tag [1]' 1
|   `-RecordType 0x7fba2300db90 'struct __va_list_tag'
|     `-Record 0x7fba2300db08 '__va_list_tag'
|-FunctionDecl 0x7fba22829370 <test4.c:2:1, line:4:1> line:2:8 used multiply 'double (double, double)'
| |-ParmVarDecl 0x7fba22829218 <col:17, col:24> col:24 used x 'double'
| |-ParmVarDecl 0x7fba22829298 <col:27, col:34> col:34 used y 'double'
| `-CompoundStmt 0x7fba22829560 <col:37, line:4:1>
|   `-ReturnStmt 0x7fba22829550 <line:3:2, col:17>
|     `-BinaryOperator 0x7fba22829530 <col:9, col:17> 'double' '*'
|       |-BinaryOperator 0x7fba228294d8 <col:9, col:13> 'double' '*'
|       | |-ImplicitCastExpr 0x7fba228294a8 <col:9> 'double' <LValueToRValue>
|       | | `-DeclRefExpr 0x7fba22829468 <col:9> 'double' lvalue ParmVar 0x7fba22829218 'x' 'double'
|       | `-ImplicitCastExpr 0x7fba228294c0 <col:13> 'double' <LValueToRValue>
|       |   `-DeclRefExpr 0x7fba22829488 <col:13> 'double' lvalue ParmVar 0x7fba22829298 'y' 'double'
|       `-ImplicitCastExpr 0x7fba22829518 <col:17> 'double' <LValueToRValue>
|         `-DeclRefExpr 0x7fba228294f8 <col:17> 'double' lvalue ParmVar 0x7fba22829298 'y' 'double'
`-FunctionDecl 0x7fba228297d0 <line:6:1, line:22:1> line:6:5 main 'int (int, const char **)'
|-ParmVarDecl 0x7fba22829590 <col:10, col:14> col:14 argc 'int'
|-ParmVarDecl 0x7fba228296b0 <col:20, col:37> col:32 argv 'const char **':'const char **'
`-CompoundStmt 0x7fba22829da8 <line:7:1, line:22:1>
|-DeclStmt 0x7fba22829928 <line:10:2, col:10>
| `-VarDecl 0x7fba228298c0 <col:2, col:9> col:9 a 'double'
|-DeclStmt 0x7fba228299c0 <line:12:2, col:7>
| `-VarDecl 0x7fba22829958 <col:2, col:6> col:6 b 'int'
|-DeclStmt 0x7fba22829a58 <line:14:2, col:9>
| `-VarDecl 0x7fba228299f0 <col:2, col:8> col:8 d 'float'
|-DeclStmt 0x7fba22829b10 <line:16:2, col:16>
| `-VarDecl 0x7fba22829a88 <col:2, col:13> col:9 used x 'double' cinit
|   `-FloatingLiteral 0x7fba22829af0 <col:13> 'double' 3.000000e+00
|-DeclStmt 0x7fba22829bc8 <line:17:2, col:16>
| `-VarDecl 0x7fba22829b40 <col:2, col:13> col:9 used y 'double' cinit
|   `-FloatingLiteral 0x7fba22829ba8 <col:13> 'double' 5.000000e+00
|-DeclStmt 0x7fba22829d60 <line:19:2, col:26>
| `-VarDecl 0x7fba22829bf8 <col:2, col:25> col:9 z 'double' cinit
|   `-CallExpr 0x7fba22829d00 <col:13, col:25> 'double'
|     |-ImplicitCastExpr 0x7fba22829ce8 <col:13> 'double (*)(double, double)' <FunctionToPointerDecay>
|     | `-DeclRefExpr 0x7fba22829c60 <col:13> 'double (double, double)' Function 0x7fba22829370 'multiply' 'double (double, double)'
|     |-ImplicitCastExpr 0x7fba22829d30 <col:22> 'double' <LValueToRValue>
|     | `-DeclRefExpr 0x7fba22829c80 <col:22> 'double' lvalue Var 0x7fba22829a88 'x' 'double'
|     `-ImplicitCastExpr 0x7fba22829d48 <col:24> 'double' <LValueToRValue>
|       `-DeclRefExpr 0x7fba22829ca0 <col:24> 'double' lvalue Var 0x7fba22829b40 'y' 'double'
`-ReturnStmt 0x7fba22829d98 <line:21:2, col:9>
`-IntegerLiteral 0x7fba22829d78 <col:9> 'int' 0

正如评论中所指出的,这里的问题几乎可以肯定是在Visit方法的末尾未能显式地return true

bool VisitFunctionDecl(clang::FunctionDecl *decl) {
llvm::outs() << "Found a FunctionDecl";
};

省略return会导致未定义的行为。在实践中,用于传递返回值的寄存器中的任何内容都可以按原样使用,因此,如果该寄存器恰好包含0,则false会被有效地返回。

在访问其主体之前调用VisitFunctionDecl,如果返回false,则整个遍历将中止,因此它永远不会到达VarDecl节点。

引用文件:

从这些重写函数中的一个返回false将中止整个遍历。

相关内容

  • 没有找到相关文章

最新更新