Skip to content

Commit

Permalink
Fix bug in suggested fix that truncated variable names to 1 character.
Browse files Browse the repository at this point in the history
Summary:
Fix bug in suggested fix that truncated variable names to 1 character.
Also, rework the suggested fix to try to remove unnecessary whitespace.

Reviewers: alexfh, aaron.ballman

Subscribers: cfe-commits

Differential Revision: http://reviews.llvm.org/D13899

llvm-svn: 252773
  • Loading branch information
sbenzaquen committed Nov 11, 2015
1 parent 8f3f634 commit b439627
Show file tree
Hide file tree
Showing 2 changed files with 63 additions and 32 deletions.
65 changes: 35 additions & 30 deletions clang-tools-extra/clang-tidy/misc/UnusedParametersCheck.cpp
Expand Up @@ -10,6 +10,7 @@
#include "UnusedParametersCheck.h"
#include "clang/AST/ASTContext.h"
#include "clang/ASTMatchers/ASTMatchFinder.h"
#include "clang/Lex/Lexer.h"

using namespace clang::ast_matchers;

Expand All @@ -20,36 +21,39 @@ void UnusedParametersCheck::registerMatchers(MatchFinder *Finder) {
Finder->addMatcher(functionDecl().bind("function"), this);
}

static FixItHint removeParameter(const FunctionDecl *Function, unsigned Index) {
const ParmVarDecl *Param = Function->getParamDecl(Index);
unsigned ParamCount = Function->getNumParams();
SourceRange RemovalRange = Param->getSourceRange();
if (ParamCount == 1)
return FixItHint::CreateRemoval(RemovalRange);

if (Index == 0)
RemovalRange.setEnd(
Function->getParamDecl(Index + 1)->getLocStart().getLocWithOffset(-1));
else
RemovalRange.setBegin(
Function->getParamDecl(Index - 1)->getLocEnd().getLocWithOffset(1));

return FixItHint::CreateRemoval(RemovalRange);
template <typename T>
static CharSourceRange removeNode(const MatchFinder::MatchResult &Result,
const T *PrevNode, const T *Node,
const T *NextNode) {
if (NextNode)
return CharSourceRange::getCharRange(Node->getLocStart(),
NextNode->getLocStart());

if (PrevNode)
return CharSourceRange::getTokenRange(
Lexer::getLocForEndOfToken(PrevNode->getLocEnd(), 0,
*Result.SourceManager,
Result.Context->getLangOpts()),
Node->getLocEnd());

return CharSourceRange::getTokenRange(Node->getSourceRange());
}

static FixItHint removeParameter(const MatchFinder::MatchResult &Result,
const FunctionDecl *Function, unsigned Index) {
return FixItHint::CreateRemoval(removeNode(
Result, Index > 0 ? Function->getParamDecl(Index - 1) : nullptr,
Function->getParamDecl(Index),
Index + 1 < Function->getNumParams() ? Function->getParamDecl(Index + 1)
: nullptr));
}

static FixItHint removeArgument(const CallExpr *Call, unsigned Index) {
unsigned ArgCount = Call->getNumArgs();
const Expr *Arg = Call->getArg(Index);
SourceRange RemovalRange = Arg->getSourceRange();
if (ArgCount == 1)
return FixItHint::CreateRemoval(RemovalRange);
if (Index == 0)
RemovalRange.setEnd(
Call->getArg(Index + 1)->getLocStart().getLocWithOffset(-1));
else
RemovalRange.setBegin(
Call->getArg(Index - 1)->getLocEnd().getLocWithOffset(1));
return FixItHint::CreateRemoval(RemovalRange);
static FixItHint removeArgument(const MatchFinder::MatchResult &Result,
const CallExpr *Call, unsigned Index) {
return FixItHint::CreateRemoval(removeNode(
Result, Index > 0 ? Call->getArg(Index - 1) : nullptr,
Call->getArg(Index),
Index + 1 < Call->getNumArgs() ? Call->getArg(Index + 1) : nullptr));
}

void UnusedParametersCheck::warnOnUnusedParameter(
Expand Down Expand Up @@ -85,15 +89,16 @@ void UnusedParametersCheck::warnOnUnusedParameter(
// Fix all redeclarations.
for (const FunctionDecl *FD : Function->redecls())
if (FD->param_size())
MyDiag << removeParameter(FD, ParamIndex);
MyDiag << removeParameter(Result, FD, ParamIndex);

// Fix all call sites.
auto CallMatches = ast_matchers::match(
decl(forEachDescendant(
callExpr(callee(functionDecl(equalsNode(Function)))).bind("x"))),
*Result.Context->getTranslationUnitDecl(), *Result.Context);
for (const auto &Match : CallMatches)
MyDiag << removeArgument(Match.getNodeAs<CallExpr>("x"), ParamIndex);
MyDiag << removeArgument(Result, Match.getNodeAs<CallExpr>("x"),
ParamIndex);
}

void UnusedParametersCheck::check(const MatchFinder::MatchResult &Result) {
Expand Down
30 changes: 28 additions & 2 deletions clang-tools-extra/test/clang-tidy/misc-unused-parameters.cpp
Expand Up @@ -42,7 +42,7 @@ static void staticFunctionB(int i, int j) { (void)i; }

static void staticFunctionC(int i, int j) { (void)j; }
// CHECK-MESSAGES: :[[@LINE-1]]:33: warning
// CHECK-FIXES: {{^}}static void staticFunctionC( int j)
// CHECK-FIXES: {{^}}static void staticFunctionC(int j)

static void staticFunctionD(int i, int j, int k) { (void)i; (void)k; }
// CHECK-MESSAGES: :[[@LINE-1]]:40: warning
Expand All @@ -59,12 +59,38 @@ static void someCallSites() {
staticFunctionB(1, 2);
// CHECK-FIXES: staticFunctionB(1);
staticFunctionC(1, 2);
// CHECK-FIXES: staticFunctionC( 2);
// CHECK-FIXES: staticFunctionC(2);
staticFunctionD(1, 2, 3);
// CHECK-FIXES: staticFunctionD(1, 3);
staticFunctionE();
}

/*
* FIXME: This fails because the removals overlap and ClangTidy doesn't apply
* them.
* static void bothVarsUnused(int a, int b) {}
*/

// Regression test for long variable names and expressions
// =======================================================
static int variableWithLongName1(int LongName1, int LongName2) {
// CHECK-MESSAGES: :[[@LINE-1]]:53: warning: parameter 'LongName2' is unused
// CHECK-FIXES: {{^}}static int variableWithLongName1(int LongName1) {
return LongName1;
}
static int variableWithLongName2(int LongName1, int LongName2) {
// CHECK-MESSAGES: :[[@LINE-1]]:38: warning: parameter 'LongName1' is unused
// CHECK-FIXES: {{^}}static int variableWithLongName2(int LongName2) {
return LongName2;
}
static void someLongNameCallSites() {
int LongName1 = 7, LongName2 = 17;
variableWithLongName1(LongName1, LongName2);
// CHECK-FIXES: variableWithLongName1(LongName1);
variableWithLongName2(LongName1, LongName2);
// CHECK-FIXES: variableWithLongName2(LongName2);
}

class SomeClass {
static void f(int i) {}
// CHECK-MESSAGES: :[[@LINE-1]]:21: warning
Expand Down

0 comments on commit b439627

Please sign in to comment.