Remove second-guessing for DeclRefExprs in CallExprs

In TraverseDeclRefExpr we would exit early if we were under a
CallExpr, with the motivation that CallExpr had already handled the
relevant cases.

However, VisitCallExpr only looks specifically for reference arguments
passed to vararg functions, and ignores everything else.

Let TraverseDeclRefExpr work on all expressions, so that creating
function pointers to templates works in all contexts, including
CallExprs.

Fixes issue #425.
This commit is contained in:
Kim Grasman 2017-05-01 13:02:22 +02:00 committed by Kim Gräsman
parent 78d0c15b37
commit 13cd94804b
1 changed files with 1 additions and 9 deletions

10
iwyu.cc
View File

@ -899,21 +899,13 @@ class BaseAstVisitor : public RecursiveASTVisitor<Derived> {
const_cast<CXXDestructorDecl*>(dtor), parent_type, expr);
}
// This is to catch assigning template functions to function pointers.
// This is to catch function pointers to templates.
// For instance, 'MyFunctionPtr p = &TplFn<MyClass*>;': we need to
// expand TplFn to see if it needs full type info for MyClass.
bool TraverseDeclRefExpr(clang::DeclRefExpr* expr) {
if (!Base::TraverseDeclRefExpr(expr)) return false;
if (CanIgnoreCurrentASTNode()) return true;
// If it's a normal function call, that was already handled by a
// CallExpr somewhere. We want only assignments.
if (current_ast_node()->template ParentIsA<CallExpr>() ||
(current_ast_node()->template ParentIsA<ImplicitCastExpr>() &&
current_ast_node()->template AncestorIsA<CallExpr>(2))) {
return true;
}
if (FunctionDecl* fn_decl = DynCastFrom(expr->getDecl())) {
// If fn_decl has a class-name before it -- 'MyClass::method' --
// it's a method pointer.