Clang AST как сопоставить вызовы унарных операторов, исключая вызовы в decltype?

#clang #llvm

#clang #llvm

Вопрос:

Я могу легко сопоставить вызовы унарных операторов со следующим запросом:

 m unaryOperator(unless(isExpansionInSystemHeader()))
  

Тем не менее, я хочу исключить совпадения, подобные следующим:

 decltype(amp;Func)
  

Есть ли запрос, который я могу использовать, чтобы исключить эти вызовы, или я должен каким-то образом исключить их из кода?

Ответ №1:

Да, используйте средства сопоставления обхода. Например,

 // test.cpp
int foo();

int main() {
  int i=0;
  i  ;

  int *k = amp;i;

  decltype(amp;foo) j;
  return 0;
}
  

с clang-query test.cpp -- .

Сопоставить все унарные операторы:

 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 = amp;i;
           ^~

Match #3:

/.../test.cpp:10:12: note: "root" binds here
  decltype(amp;foo) j;
           ^~~~
3 matches.
  

Чтобы исключить amp; :

 clang-query> m unaryOperator(unless(hasOperatorName("amp;")))

Match #1:

/.../test.cpp:6:3: note: "root" binds here
  i  ;
  ^~~
1 match.

  

Чтобы исключить 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 = amp;i;
           ^~
2 matches.