RecursiveASTVisitor Behavior

classic Classic list List threaded Threaded
6 messages Options
Reply | Threaded
Open this post in threaded view
|

RecursiveASTVisitor Behavior

Dimitry Andric via cfe-dev
Hi All,

I have c code, below, that I'm trying to visit the AST of by using RecursiveASTVisitor. I'm trying to get the RecursiveASTVisitor to visit variable declarations (clang::VarDecl) by implementing bool VistVarDecl(clang::VarDecl *vardecl). However, the clang::VarDecl nodes are never visited even though I've managed to visit all the other nodes in the AST though. Moreover, using clang-query on test1.c I can match varDecl.

Does anyone know the clang::VarDecl nodes are the only nodes that aren't visited by the RecursiveASTVisitor but are matched by clang-query?

Thanks in advaince!

```
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;
}
```
My RecursiveASTVisitor is as follows:
```
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;
};
```

--
Michael.

_______________________________________________
cfe-dev mailing list
[hidden email]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev
Reply | Threaded
Open this post in threaded view
|

Re: RecursiveASTVisitor Behavior

Dimitry Andric via cfe-dev


On Mar 18, 2021, at 11:42 AM, Michael Chiu via cfe-dev <[hidden email]> wrote:

Hi All,

I have c code, below, that I'm trying to visit the AST of by using RecursiveASTVisitor. I'm trying to get the RecursiveASTVisitor to visit variable declarations (clang::VarDecl) by implementing bool VistVarDecl(clang::VarDecl *vardecl). However, the clang::VarDecl nodes are never visited even though I've managed to visit all the other nodes in the AST though. Moreover, using clang-query on test1.c I can match varDecl.

Does anyone know the clang::VarDecl nodes are the only nodes that aren't visited by the RecursiveASTVisitor but are matched by clang-query?

Thanks in advaince!

```
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;
}
```
My RecursiveASTVisitor is as follows:
```
struct
MyASTVisitor :
public clang::RecursiveASTVistor<MyASTVisitor> {
  bool VistVarDecl(clang::VarDecl *vardecl) {
     llvm::outs() << "Found a VarDecl";
Add `return true;’ here and in the others.  (Traversal halts after the first false return, and all these are returning false by default.)
  };

  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;
};
```

--
Michael.
_______________________________________________
cfe-dev mailing list
[hidden email]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev


_______________________________________________
cfe-dev mailing list
[hidden email]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev
Reply | Threaded
Open this post in threaded view
|

Re: RecursiveASTVisitor Behavior

Dimitry Andric via cfe-dev
Hi David,

Thanks for the prompt reply. I should’ve been more clear but I am returning bool in all of the visitor method functions, but clang::VarDecl is still not visited which is why I’m so perplexed.

On Thu, Mar 18, 2021 at 8:58 AM David Rector <[hidden email]> wrote:


On Mar 18, 2021, at 11:42 AM, Michael Chiu via cfe-dev <[hidden email]> wrote:

Hi All,

I have c code, below, that I'm trying to visit the AST of by using RecursiveASTVisitor. I'm trying to get the RecursiveASTVisitor to visit variable declarations (clang::VarDecl) by implementing bool VistVarDecl(clang::VarDecl *vardecl). However, the clang::VarDecl nodes are never visited even though I've managed to visit all the other nodes in the AST though. Moreover, using clang-query on test1.c I can match varDecl.

Does anyone know the clang::VarDecl nodes are the only nodes that aren't visited by the RecursiveASTVisitor but are matched by clang-query?

Thanks in advaince!

```
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;
}
```
My RecursiveASTVisitor is as follows:
```
struct
MyASTVisitor :
public clang::RecursiveASTVistor<MyASTVisitor> {
  bool VistVarDecl(clang::VarDecl *vardecl) {
     llvm::outs() << "Found a VarDecl";
Add `return true;’ here and in the others.  (Traversal halts after the first false return, and all these are returning false by default.)
  };

  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;
};
```

--
Michael.
_______________________________________________
cfe-dev mailing list
[hidden email]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev

--
M.

_______________________________________________
cfe-dev mailing list
[hidden email]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev
Reply | Threaded
Open this post in threaded view
|

Re: RecursiveASTVisitor Behavior

Dimitry Andric via cfe-dev
Hi Michael,
Although your return type is bool, since you have no return statement at the end of the method in the Visitor, that method returns false implicitly. Please add a "return true;" at the end of the visitor methods.
Warm regards,
Deep

On Thu, 18 Mar, 2021, 9:32 pm Michael Chiu via cfe-dev, <[hidden email]> wrote:
Hi David,

Thanks for the prompt reply. I should’ve been more clear but I am returning bool in all of the visitor method functions, but clang::VarDecl is still not visited which is why I’m so perplexed.

On Thu, Mar 18, 2021 at 8:58 AM David Rector <[hidden email]> wrote:


On Mar 18, 2021, at 11:42 AM, Michael Chiu via cfe-dev <[hidden email]> wrote:

Hi All,

I have c code, below, that I'm trying to visit the AST of by using RecursiveASTVisitor. I'm trying to get the RecursiveASTVisitor to visit variable declarations (clang::VarDecl) by implementing bool VistVarDecl(clang::VarDecl *vardecl). However, the clang::VarDecl nodes are never visited even though I've managed to visit all the other nodes in the AST though. Moreover, using clang-query on test1.c I can match varDecl.

Does anyone know the clang::VarDecl nodes are the only nodes that aren't visited by the RecursiveASTVisitor but are matched by clang-query?

Thanks in advaince!

```
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;
}
```
My RecursiveASTVisitor is as follows:
```
struct
MyASTVisitor :
public clang::RecursiveASTVistor<MyASTVisitor> {
  bool VistVarDecl(clang::VarDecl *vardecl) {
     llvm::outs() << "Found a VarDecl";
Add `return true;’ here and in the others.  (Traversal halts after the first false return, and all these are returning false by default.)
  };

  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;
};
```

--
Michael.
_______________________________________________
cfe-dev mailing list
[hidden email]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev

--
M.
_______________________________________________
cfe-dev mailing list
[hidden email]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev

_______________________________________________
cfe-dev mailing list
[hidden email]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev
Reply | Threaded
Open this post in threaded view
|

Re: RecursiveASTVisitor Behavior

Dimitry Andric via cfe-dev
In reply to this post by Dimitry Andric via cfe-dev
You spell it `VistVarDecl` in the example, t

On Mar 18, 2021, at 12:02 PM, Michael Chiu <[hidden email]> wrote:

Hi David,

Thanks for the prompt reply. I should’ve been more clear but I am returning bool in all of the visitor method functions, but clang::VarDecl is still not visited which is why I’m so perplexed.

On Thu, Mar 18, 2021 at 8:58 AM David Rector <[hidden email]> wrote:


On Mar 18, 2021, at 11:42 AM, Michael Chiu via cfe-dev <[hidden email]> wrote:

Hi All,

I have c code, below, that I'm trying to visit the AST of by using RecursiveASTVisitor. I'm trying to get the RecursiveASTVisitor to visit variable declarations (clang::VarDecl) by implementing bool VistVarDecl(clang::VarDecl *vardecl). However, the clang::VarDecl nodes are never visited even though I've managed to visit all the other nodes in the AST though. Moreover, using clang-query on test1.c I can match varDecl.

Does anyone know the clang::VarDecl nodes are the only nodes that aren't visited by the RecursiveASTVisitor but are matched by clang-query?

Thanks in advaince!

```
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;
}
```
My RecursiveASTVisitor is as follows:
```
struct
MyASTVisitor :
public clang::RecursiveASTVistor<MyASTVisitor> {
  bool VistVarDecl(clang::VarDecl *vardecl) {
If this misspelling of VisitVarDecl is in your code that’s your culprit.
     llvm::outs() << "Found a VarDecl";
Add `return true;’ here and in the others.  (Traversal halts after the first false return, and all these are returning false by default.)
  };

  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;
  }
Also, in your case, since you’re always returning true from your Handle* implem, might be simpler to instead write:
```
void HandleTranslationUnit(ASTContext &Context) override {
  Visitor.TraverseDecl(Context.getTranslationUnitDecl());
}
```
Though that should not make a difference with your problem.

private: 
  MyASTVisitor Visitor;
};
```

--
Michael.
_______________________________________________
cfe-dev mailing list
[hidden email]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev

--
M.


_______________________________________________
cfe-dev mailing list
[hidden email]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev
Reply | Threaded
Open this post in threaded view
|

Re: RecursiveASTVisitor Behavior

Dimitry Andric via cfe-dev
Silly me, that was my mistake. 

Appreciate the help!

On Thu, Mar 18, 2021 at 9:42 AM David Rector <[hidden email]> wrote:
You spell it `VistVarDecl` in the example, t

On Mar 18, 2021, at 12:02 PM, Michael Chiu <[hidden email]> wrote:

Hi David,

Thanks for the prompt reply. I should’ve been more clear but I am returning bool in all of the visitor method functions, but clang::VarDecl is still not visited which is why I’m so perplexed.

On Thu, Mar 18, 2021 at 8:58 AM David Rector <[hidden email]> wrote:


On Mar 18, 2021, at 11:42 AM, Michael Chiu via cfe-dev <[hidden email]> wrote:

Hi All,

I have c code, below, that I'm trying to visit the AST of by using RecursiveASTVisitor. I'm trying to get the RecursiveASTVisitor to visit variable declarations (clang::VarDecl) by implementing bool VistVarDecl(clang::VarDecl *vardecl). However, the clang::VarDecl nodes are never visited even though I've managed to visit all the other nodes in the AST though. Moreover, using clang-query on test1.c I can match varDecl.

Does anyone know the clang::VarDecl nodes are the only nodes that aren't visited by the RecursiveASTVisitor but are matched by clang-query?

Thanks in advaince!

```
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;
}
```
My RecursiveASTVisitor is as follows:
```
struct
MyASTVisitor :
public clang::RecursiveASTVistor<MyASTVisitor> {
  bool VistVarDecl(clang::VarDecl *vardecl) {
If this misspelling of VisitVarDecl is in your code that’s your culprit.
     llvm::outs() << "Found a VarDecl";
Add `return true;’ here and in the others.  (Traversal halts after the first false return, and all these are returning false by default.)
  };

  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;
  }
Also, in your case, since you’re always returning true from your Handle* implem, might be simpler to instead write:
```
void HandleTranslationUnit(ASTContext &Context) override {
  Visitor.TraverseDecl(Context.getTranslationUnitDecl());
}
```
Though that should not make a difference with your problem.

private: 
  MyASTVisitor Visitor;
};
```

--
Michael.
_______________________________________________
cfe-dev mailing list
[hidden email]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev

--
M.

--
M.

_______________________________________________
cfe-dev mailing list
[hidden email]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev