[clang-tidy] readability check for const params in declarations
Summary: Adds a clang-tidy warning for top-level consts in function declarations. Reviewers: hokein, sbenza, alexfh Subscribers: cfe-commits Patch by Matt Kulukundis! Differential Revision: http://reviews.llvm.org/D18408 git-svn-id: https://llvm.org/svn/llvm-project/clang-tools-extra/trunk@264856 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Родитель
2f39d0198a
Коммит
a1f0b8e1a7
|
@ -0,0 +1,71 @@
|
|||
//===--- AvoidConstParamsInDecls.cpp - clang-tidy--------------------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "AvoidConstParamsInDecls.h"
|
||||
#include "clang/ASTMatchers/ASTMatchFinder.h"
|
||||
#include "clang/ASTMatchers/ASTMatchers.h"
|
||||
#include "clang/Lex/Lexer.h"
|
||||
|
||||
using namespace clang::ast_matchers;
|
||||
|
||||
namespace clang {
|
||||
namespace tidy {
|
||||
namespace readability {
|
||||
namespace {
|
||||
|
||||
SourceRange getTypeRange(const ParmVarDecl &Param) {
|
||||
if (Param.getIdentifier() != nullptr)
|
||||
return SourceRange(Param.getLocStart(),
|
||||
Param.getLocEnd().getLocWithOffset(-1));
|
||||
return Param.getSourceRange();
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
|
||||
void AvoidConstParamsInDecls::registerMatchers(MatchFinder *Finder) {
|
||||
const auto ConstParamDecl =
|
||||
parmVarDecl(hasType(qualType(isConstQualified()))).bind("param");
|
||||
Finder->addMatcher(functionDecl(unless(isDefinition()),
|
||||
has(typeLoc(forEach(ConstParamDecl))))
|
||||
.bind("func"),
|
||||
this);
|
||||
}
|
||||
|
||||
void AvoidConstParamsInDecls::check(const MatchFinder::MatchResult &Result) {
|
||||
const auto *Func = Result.Nodes.getNodeAs<FunctionDecl>("func");
|
||||
const auto *Param = Result.Nodes.getNodeAs<ParmVarDecl>("param");
|
||||
|
||||
QualType Type = Param->getType();
|
||||
if (!Type.isLocalConstQualified())
|
||||
return;
|
||||
|
||||
Type.removeLocalConst();
|
||||
|
||||
auto Diag = diag(Param->getLocStart(),
|
||||
"parameter %0 is const-qualified in the function "
|
||||
"declaration; const-qualification of parameters only has an "
|
||||
"effect in function definitions");
|
||||
if (Param->getName().empty()) {
|
||||
for (unsigned int i = 0; i < Func->getNumParams(); ++i) {
|
||||
if (Param == Func->getParamDecl(i)) {
|
||||
Diag << (i + 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
Diag << Param;
|
||||
}
|
||||
Diag << FixItHint::CreateReplacement(getTypeRange(*Param),
|
||||
Type.getAsString());
|
||||
}
|
||||
|
||||
} // namespace readability
|
||||
} // namespace tidy
|
||||
} // namespace clang
|
|
@ -0,0 +1,33 @@
|
|||
//===--- AvoidConstParamsInDecls.h - clang-tidy----------------------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_READABILITY_AVOID_CONST_PARAMS_IN_DECLS_H
|
||||
#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_READABILITY_AVOID_CONST_PARAMS_IN_DECLS_H
|
||||
|
||||
#include "../ClangTidy.h"
|
||||
|
||||
namespace clang {
|
||||
namespace tidy {
|
||||
namespace readability {
|
||||
|
||||
// Detect function declarations that have const value parameters and discourage
|
||||
// them.
|
||||
class AvoidConstParamsInDecls : public ClangTidyCheck {
|
||||
public:
|
||||
using ClangTidyCheck::ClangTidyCheck;
|
||||
|
||||
void registerMatchers(ast_matchers::MatchFinder *Finder) override;
|
||||
void check(const ast_matchers::MatchFinder::MatchResult &Result) override;
|
||||
};
|
||||
|
||||
} // namespace readability
|
||||
} // namespace tidy
|
||||
} // namespace clang
|
||||
|
||||
#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_READABILITY_AVOID_CONST_PARAMS_IN_DECLS_H
|
|
@ -1,6 +1,7 @@
|
|||
set(LLVM_LINK_COMPONENTS support)
|
||||
|
||||
add_clang_library(clangTidyReadabilityModule
|
||||
AvoidConstParamsInDecls.cpp
|
||||
BracesAroundStatementsCheck.cpp
|
||||
ContainerSizeEmptyCheck.cpp
|
||||
ElseAfterReturnCheck.cpp
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
#include "../ClangTidy.h"
|
||||
#include "../ClangTidyModule.h"
|
||||
#include "../ClangTidyModuleRegistry.h"
|
||||
#include "AvoidConstParamsInDecls.h"
|
||||
#include "BracesAroundStatementsCheck.h"
|
||||
#include "ContainerSizeEmptyCheck.h"
|
||||
#include "ElseAfterReturnCheck.h"
|
||||
|
@ -32,6 +33,8 @@ namespace readability {
|
|||
class ReadabilityModule : public ClangTidyModule {
|
||||
public:
|
||||
void addCheckFactories(ClangTidyCheckFactories &CheckFactories) override {
|
||||
CheckFactories.registerCheck<AvoidConstParamsInDecls>(
|
||||
"readability-avoid-const-params-in-decls");
|
||||
CheckFactories.registerCheck<BracesAroundStatementsCheck>(
|
||||
"readability-braces-around-statements");
|
||||
CheckFactories.registerCheck<ContainerSizeEmptyCheck>(
|
||||
|
|
|
@ -90,8 +90,9 @@ Clang-Tidy Checks
|
|||
performance-faster-string-find
|
||||
performance-for-range-copy
|
||||
performance-implicit-cast-in-loop
|
||||
performance-unnecessary-value-param
|
||||
performance-unnecessary-copy-initialization
|
||||
performance-unnecessary-value-param
|
||||
readability-avoid-const-params-in-decls
|
||||
readability-braces-around-statements
|
||||
readability-container-size-empty
|
||||
readability-else-after-return
|
||||
|
|
|
@ -0,0 +1,17 @@
|
|||
.. title:: clang-tidy - readability-avoid-const-params-in-decls
|
||||
|
||||
readability-avoid-const-params-in-decls
|
||||
=======================================
|
||||
|
||||
Checks whether a function declaration has parameters that are top level const.
|
||||
|
||||
`const` values in declarations do not affect the signature of a function, so
|
||||
they should not be put there. For example:
|
||||
|
||||
Examples:
|
||||
|
||||
.. code:: c++
|
||||
|
||||
void f(const string); // Bad: const is top level.
|
||||
void f(const string&); // Good: const is not top level.
|
||||
|
|
@ -0,0 +1,78 @@
|
|||
// RUN: %check_clang_tidy %s readability-avoid-const-params-in-decls %t
|
||||
|
||||
using alias_type = bool;
|
||||
using alias_const_type = const bool;
|
||||
|
||||
|
||||
void F1(const int i);
|
||||
// CHECK-MESSAGES: :[[@LINE-1]]:9: warning: parameter 'i' is const-qualified in the function declaration; const-qualification of parameters only has an effect in function definitions [readability-avoid-const-params-in-decls]
|
||||
// CHECK-FIXES: void F1(int i);
|
||||
|
||||
void F2(const int *const i);
|
||||
// CHECK-MESSAGES: :[[@LINE-1]]:9: warning: parameter 'i' is const-qualified
|
||||
// CHECK-FIXES: void F2(const int * i);
|
||||
|
||||
void F3(int const i);
|
||||
// CHECK-MESSAGES: :[[@LINE-1]]:9: warning: parameter 'i' is const-qualified
|
||||
// CHECK-FIXES: void F3(int i);
|
||||
|
||||
void F4(alias_type const i);
|
||||
// CHECK-MESSAGES: :[[@LINE-1]]:9: warning: parameter 'i' is const-qualified
|
||||
// CHECK-FIXES: void F4(alias_type i);
|
||||
|
||||
void F5(const int);
|
||||
// CHECK-MESSAGES: :[[@LINE-1]]:9: warning: parameter 1 is const-qualified
|
||||
// CHECK-FIXES: void F5(int);
|
||||
|
||||
void F6(const int *const);
|
||||
// CHECK-MESSAGES: :[[@LINE-1]]:9: warning: parameter 1 is const-qualified
|
||||
// BUG(b/27584482): void F6(const int *); should be produced
|
||||
|
||||
void F7(int, const int);
|
||||
// CHECK-MESSAGES: :[[@LINE-1]]:14: warning: parameter 2 is const-qualified
|
||||
// CHECK-FIXES: void F7(int, int);
|
||||
|
||||
void F8(const int, const int);
|
||||
// CHECK-MESSAGES: :[[@LINE-1]]:9: warning: parameter 1 is const-qualified
|
||||
// CHECK-MESSAGES: :[[@LINE-2]]:20: warning: parameter 2 is const-qualified
|
||||
// CHECK-FIXES: void F8(int, int);
|
||||
|
||||
void F9(const int long_name);
|
||||
// CHECK-MESSAGES: :[[@LINE-1]]:9: warning: parameter 'long_name'
|
||||
// CHECK-FIXES: void F9(int long_name);
|
||||
|
||||
void F10(const int *const *const long_name);
|
||||
// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: parameter 'long_name'
|
||||
// CHECK-FIXES: void F10(const int *const * long_name);
|
||||
|
||||
|
||||
struct Foo {
|
||||
Foo(const int i);
|
||||
// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: parameter 'i'
|
||||
// CHECK-FIXES: Foo(int i);
|
||||
|
||||
void operator()(const int i);
|
||||
// CHECK-MESSAGES: :[[@LINE-1]]:19: warning: parameter 'i'
|
||||
// CHECK-FIXES: void operator()(int i);
|
||||
};
|
||||
|
||||
// Do not match on definitions
|
||||
void NF1(const int i) {}
|
||||
void NF2(const int *const i) {}
|
||||
void NF3(int const i) {}
|
||||
void NF4(alias_type const i) {}
|
||||
void NF5(const int) {}
|
||||
void NF6(const int *const) {}
|
||||
void NF7(int, const int) {}
|
||||
void NF8(const int, const int) {}
|
||||
|
||||
// Do not match on other stuff
|
||||
void NF(const alias_type& i);
|
||||
void NF(const int &i);
|
||||
void NF(const int *i);
|
||||
void NF(alias_const_type i);
|
||||
void NF(const alias_type&);
|
||||
void NF(const int&);
|
||||
void NF(const int*);
|
||||
void NF(const int* const*);
|
||||
void NF(alias_const_type);
|
Загрузка…
Ссылка в новой задаче