Extracting variable name from VarDecl* Clang

This code:

 if (IfStmt* ifS = dyn_cast<IfStmt>(st)) {
   errs() << "Found an IF statement ";
   VarDecl* var = ifS->getConditionVariable();
   errs() << var->getNameAsString();
 }

produces cannot initialize object parameter of type 'const clang::NamedDecl' with an expression of type 'clang::VarDecl' error on errs() << var->getNameAsString(); line and the program crashes with a seg fault. I can’t find what’s wrong with this? Please help.

Please post some sample source code (from which the AST is generated),
without that it's quite hard to help. But in general I guess you can't
assume that you can get a single variable out of an if statement, if you
have "if (Foo && Bar)", which one would be returned by the API?

Here is my sample code:

int x=0;
if(x == 0)
cout << “Hey” << endl;

I want to get ‘x’.

Here is my sample code:

int x=0;
if(x == 0)
cout << "Hey" << endl;

I want to get 'x'.

getConditionVariable() will only return x if it is written this way:

if (int x = ... )
   ...

You need to do something more like this:

if (IfStmt *ifS = dyn_cast<IfStmt>(st))
{
   if (BinaryOperator *binOp = dyn_cast<BinaryOperator>(ifS->getCond()))
   {
      if (binOp->getOpcode() == BO_Assign)
      {
         if (DeclRefExpr *Decl = dyn_cast<DeclRefExpr*>(binOp->getLHS()->IgnoreParenCasts()))
         {
             ...
         }
      }
   }
}

It helps a *lot* to look at the AST dump for the examples you're interested in matching. To do that, run:

   $ ./bin/clang-check -ast-dump foo.c --

If you're going to be doing heavy matching of ASTs, I recommend looking into using this: http://clang.llvm.org/docs/LibASTMatchersReference.html instead of open-coding them.

Jon

Thank you. Just one more thing: How do I restrict the AST to a single source file (passed as an argument to the clang tool) excluding the functions from headers and other third party libraries (if any).

I can know the name of source file like this:

SourceManager &srcManager = astContext->getSourceManager();

srcManager.getFilename(decl->getLocation()).str() << “\n”;

but I want to just bypass all the nodes in other files (except for the source file) without this check.

I can know the name of source file like this:

SourceManager &srcManager = astContext->getSourceManager();
srcManager.getFilename(decl->getLocation()).str() << "\n";

but I want to just bypass all the nodes in other files (except for the
source file) without this check.

Comparing SourceLocations is the only way to do it.