<div dir="ltr">On Tue, Nov 19, 2013 at 1:22 AM, rayjcwu <span dir="ltr"><<a href="mailto:rayjcwu@gmail.com" target="_blank">rayjcwu@gmail.com</a>></span> wrote:<br><div class="gmail_extra"><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">
I have a simple file<br>
<br>
#define square(x) ((x)*(x))<br>
int main() {<br>
  square(3);<br>
  return 0;<br>
}<br>
<br>
The ast-dump by clang is:<br>
<br>
TranslationUnitDecl 0x3fcc0e0 <<invalid sloc>><br>
|-TypedefDecl 0x3fcc5e0 <<invalid sloc>> __int128_t '__int128'<br>
|-TypedefDecl 0x3fcc640 <<invalid sloc>> __uint128_t 'unsigned __int128'<br>
|-TypedefDecl 0x3fcc990 <<invalid sloc>> __builtin_va_list '__va_list_tag<br>
[1]'<br>
`-FunctionDecl 0x3fcca30 <test.c:2:1, line:5:1> main 'int ()'<br>
  `-CompoundStmt 0x3fccbd8 <line:2:12, line:5:1><br>
    |-ParenExpr 0x3fccb78 <line:1:19, col:27> 'int'<br>
    | `-BinaryOperator 0x3fccb50 <col:20, col:26> 'int' '*'<br>
    |   |-ParenExpr 0x3fccaf0 <col:20, col:22> 'int'<br>
    |   | `-IntegerLiteral 0x3fccad0 <line:3:10> 'int' 3<br>
    |   `-ParenExpr 0x3fccb30 <line:1:24, col:26> 'int'<br>
    |     `-IntegerLiteral 0x3fccb10 <line:3:10> 'int' 3<br>
    `-ReturnStmt 0x3fccbb8 <line:4:3, col:10><br>
      `-IntegerLiteral 0x3fccb98 <col:10> 'int' 0<br>
<br>
I use<br>
<br>
bool VisitStmt(Stmt * stmt) {<br>
   const SourceManager &SM = astContext->getSourceManager();<br>
   SourceLocation startLoc = stmt->getLocStart();<br>
   if (Lexer::isAtStartOfMacroExpansion(startLoc, SM,<br>
astContext->getLangOpts())) {<br>
      cout << "is start of macro expansion" << endl;<br>
   }<br>
   return true;<br>
}<br>
<br>
and it could tell me it meets a macro when visiting ParenExpr 0x3fccb78.<br>
I only want to know there is a macro and skip to next statement, but I can't<br>
return boolean value of "is macro or not" for VisitStmt. Otherwise ast<br>
visitor will stop without visiting ReturnStmt.<br>
So how do I skip visiting children of ParenExpr and go to its sibling?<br></blockquote><div><br></div><div>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).</div>
</div></div></div>