Clang AST Matchers:如何找到调用rvalues调用的完美转发函数的调用?

问题描述:

给出一个函数模板,如:Clang AST Matchers:如何找到调用rvalues调用的完美转发函数的调用?

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

如何找到给通过右值的函数调用:

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推导为引用类型(指示左值传递)的情况下,但我不知道怎样才能连接Matcher<FunctionDecl>预计由functionDeclMatcher<TemplateSpecializationType>hasTemplateArgument返回。

我使用的是Clang 3.8,万一它很重要(online docs似乎在5.0.0,http://releases.llvm.org/3.8.0/tools/clang/docs/LibASTMatchersReference.html给出了404)。

这似乎工作:

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

但我敢肯定它错过了一些场景。

这里有一个稍微不同的方法,询问参数的类型:

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); 
} 

铛查询显示,匹配第一(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. 
+0

谢谢。即使在没有第二个“g”超载的情况下,这也是有效的。 –