[cfe-dev] How to now step into macro while using RecursiveASTVisitor?

Richard Smith richard at metafoo.co.uk
Wed Nov 20 13:08:45 PST 2013


On Tue, Nov 19, 2013 at 1:22 AM, rayjcwu <rayjcwu at gmail.com> wrote:

> I have a simple file
>
> #define square(x) ((x)*(x))
> int main() {
>   square(3);
>   return 0;
> }
>
> The ast-dump by clang is:
>
> TranslationUnitDecl 0x3fcc0e0 <<invalid sloc>>
> |-TypedefDecl 0x3fcc5e0 <<invalid sloc>> __int128_t '__int128'
> |-TypedefDecl 0x3fcc640 <<invalid sloc>> __uint128_t 'unsigned __int128'
> |-TypedefDecl 0x3fcc990 <<invalid sloc>> __builtin_va_list '__va_list_tag
> [1]'
> `-FunctionDecl 0x3fcca30 <test.c:2:1, line:5:1> main 'int ()'
>   `-CompoundStmt 0x3fccbd8 <line:2:12, line:5:1>
>     |-ParenExpr 0x3fccb78 <line:1:19, col:27> 'int'
>     | `-BinaryOperator 0x3fccb50 <col:20, col:26> 'int' '*'
>     |   |-ParenExpr 0x3fccaf0 <col:20, col:22> 'int'
>     |   | `-IntegerLiteral 0x3fccad0 <line:3:10> 'int' 3
>     |   `-ParenExpr 0x3fccb30 <line:1:24, col:26> 'int'
>     |     `-IntegerLiteral 0x3fccb10 <line:3:10> 'int' 3
>     `-ReturnStmt 0x3fccbb8 <line:4:3, col:10>
>       `-IntegerLiteral 0x3fccb98 <col:10> 'int' 0
>
> I use
>
> bool VisitStmt(Stmt * stmt) {
>    const SourceManager &SM = astContext->getSourceManager();
>    SourceLocation startLoc = stmt->getLocStart();
>    if (Lexer::isAtStartOfMacroExpansion(startLoc, SM,
> astContext->getLangOpts())) {
>       cout << "is start of macro expansion" << endl;
>    }
>    return true;
> }
>
> and it could tell me it meets a macro when visiting ParenExpr 0x3fccb78.
> I only want to know there is a macro and skip to next statement, but I
> can't
> return boolean value of "is macro or not" for VisitStmt. Otherwise ast
> visitor will stop without visiting ReturnStmt.
> So how do I skip visiting children of ParenExpr and go to its sibling?
>

Visiting of children is performed by the Traverse* functions, which
TraverseStmt dispatches to. You could override TravserseStmt, and only call
the base class version if you want the node and its children to be visited.
You'll probably also need to add a 'shouldUseDataRecursionFor' function
that returns false -- we don't check for an override of TraverseStmt before
using data recursion (arguably that's a bug).
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20131120/9d6b4ec3/attachment.html>


More information about the cfe-dev mailing list