Search code examples
clangllvm

Clang AST how to match unary operator calls, excluding ones in decltype?


I can easily match unary operator calls with the following query:

m unaryOperator(unless(isExpansionInSystemHeader()))

However, I want to exclude matches like the following:

decltype(&Func)

Is there a query that I can use to exclude those calls, or I should somehow exclude them from code?


Solution

  • Yes, use Traversal Matchers. For example,

    // test.cpp
    int foo();
    
    int main() {
      int i=0;
      i++;
    
      int *k = &i;
    
      decltype(&foo) j;
      return 0;
    }
    

    with clang-query test.cpp --.

    To match all unary operators:

    clang-query> m unaryOperator()
    
    Match #1:
    
    /.../test.cpp:6:3: note: "root" binds here
      i++;
      ^~~
    
    Match #2:
    
    /.../test.cpp:8:12: note: "root" binds here
      int *k = &i;
               ^~
    
    Match #3:
    
    /.../test.cpp:10:12: note: "root" binds here
      decltype(&foo) j;
               ^~~~
    3 matches.
    

    To exclude &:

    clang-query> m unaryOperator(unless(hasOperatorName("&")))
    
    Match #1:
    
    /.../test.cpp:6:3: note: "root" binds here
      i++;
      ^~~
    1 match.
    
    

    To exclude decltype:

    clang-query> m unaryOperator(unless(hasAncestor(varDecl(hasType(decltypeType())))))
    
    Match #1:
    
    /.../test.cpp:6:3: note: "root" binds here
      i++;
      ^~~
    
    Match #2:
    
    /.../test.cpp:8:12: note: "root" binds here
      int *k = &i;
               ^~
    2 matches.