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.