[cfe-dev] AST Matcher matches InitListExpr child twice
Stephan Bergmann via cfe-dev
cfe-dev at lists.llvm.org
Mon Jun 12 00:29:27 PDT 2017
On 06/10/2017 03:31 PM, Ben Liblit via cfe-dev wrote:
> Consider the following C++11 (or later) code fragment, which uses an
> initialization list that contains a function call:
>
> int f();
> int i {f()};
>
> The AST for that initialization list consists of an InitListExpr with a
> single CallExpr child:
>
> InitListExpr 0x2df2b80 'int'
> `-CallExpr 0x2df2b10 'int'
> `-ImplicitCastExpr 0x2df2af8 ...
> `-DeclRefExpr 0x2df2aa0 ...
>
> If I use the Clang AST Matcher API to match on InitListExpr, then I get
> one match as expected. However, if I match on CallExpr, then the single
> CallExpr in the above AST is matched *twice*. Anything below that
> CallExpr node is also matched twice; for example, I'd get two matches
> for the DeclRefExpr if that's what my AST Matcher were looking for. This
> is definitely a problem for my code, and would seem to be a bug in
> general. Surely that's not the intended behavior, is it?
That looks to be by design, cf. DEF_TRAVERSE_STMT(InitListExpr,...) in
include/clang/AST/RecursiveASTVisitor.h calling into
TraverseSynOrSemInitListExpr twice (for "syntactic" and "semantic"
InitListExpr).
In some of our LibreOffice RecursiveASTVisitor implementations we use
> bool TraverseInitListExpr(
> InitListExpr * expr
> #if CLANG_VERSION >= 30800
> , DataRecursionQueue * queue = nullptr
> #endif
> )
> {
> return WalkUpFromInitListExpr(expr)
> && TraverseSynOrSemInitListExpr(
> expr->isSemanticForm() ? expr : expr->getSemanticForm()
> #if CLANG_VERSION >= 30800
> , queue
> #endif
> );
> }
to traverse only once (where CLANG_VERSION is LibreOffice's way of
supporting multiple versions of Clang).
More information about the cfe-dev
mailing list