Clang AST Matchers: как найти вызовы идеально перенаправляющей функции, вызываемой с помощью rvalue?

Учитывая шаблон функции, такой как:

template <typename T> void function(T &&t) { /*...*/ }

Как мне найти вызовы функции, которые передают rvalues:

function(1); // MATCH
int i;
function(i); // SKIP
int foo();
function(foo()); // MATCH
...

Вы поняли идею.

Я думал о чем-то вроде:

callExpr(callee(functionDecl(
hasName("function"),
unless(hasTemplateArgument(0,
refersToType(references(anything()))))))

отфильтровать случай, когда T выводится как ссылочный тип (указывая, что передано lvalue), но я не вижу, как я могу подключить Matcher<FunctionDecl> ожидается functionDecl к Matcher<TemplateSpecializationType> вернулся из hasTemplateArgument,

Я использую Clang 3.8, на случай, если это онлайн документы похоже на 5.0.0, и http://releases.llvm.org/3.8.0/tools/clang/docs/LibASTMatchersReference.html дает 404).

1

Решение

Вот немного другой подход, который запрашивает тип параметра:

callExpr(
callee(
functionDecl(           // could also narrow on name, param count etc
hasAnyParameter(      // could also use hasParameter(n,...)
parmVarDecl(
hasType(
rValueReferenceType()
)
).bind("pdecl")
)
).bind("fdecl")
)
)

На этот тестовый код:

template <typename T> void g(T &&t){}

template <typename T> void g(T &t){}

void g(){
int i = 2;
g<int>(i);
g<int>(2);
}

clang-query показывает, что сопоставитель соответствует первому (rval) вызову, а не второму (lval):

Match #1:

test_input_rval_call.cc:1:23: note: "fdecl" binds here
template <typename T> void g(T &&t){}
^~~~~~~~~~~~~~~
test_input_rval_call.cc:1:30: note: "pdecl" binds here
template <typename T> void g(T &&t){}
^~~~~
test_input_rval_call.cc:8:3: note: "root" binds here
g<int>(2);
^~~~~~~~~
1 match.
1

Другие решения

Это похоже на работу:

callExpr(hasDeclaration(functionDecl(hasName("function"))),
hasArgument(0, cxxBindTemporaryExpr()))

хотя я уверен, что он пропускает некоторые сценарии.

0

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector