10#include "clang/AST/ASTContext.h"
11#include "clang/ASTMatchers/ASTMatchFinder.h"
12#include "clang/ASTMatchers/ASTMatchers.h"
19 Finder->addMatcher(functionDecl().bind(
"decl"),
this);
23 const SourceManager &SM = *Result.SourceManager;
24 const auto *Function = Result.Nodes.getNodeAs<FunctionDecl>(
"decl");
25 SmallVector<std::pair<const FunctionDecl *, unsigned>, 4> UnnamedParams;
29 const FunctionDecl *Definition =
nullptr;
30 if ((!Function->isDefined(Definition) || Function->isDefaulted() ||
31 Definition->isDefaulted() || Function->isDeleted()) &&
32 (!isa<CXXMethodDecl>(Function) ||
33 cast<CXXMethodDecl>(Function)->size_overridden_methods() == 0))
39 for (
unsigned I = 0,
E = Function->getNumParams(); I !=
E; ++I) {
40 const ParmVarDecl *
Parm = Function->getParamDecl(I);
41 if (
Parm->isImplicit())
44 if (!
Parm->getName().empty())
48 if ((Function->getOverloadedOperator() == OO_PlusPlus ||
49 Function->getOverloadedOperator() == OO_MinusMinus) &&
50 Parm->getType()->isSpecificBuiltinType(BuiltinType::Int))
54 if (!
Parm->getLocation().isValid() ||
Parm->getLocation().isMacroID() ||
55 !SM.isWrittenInSameFile(
Parm->getBeginLoc(),
Parm->getLocation()))
59 if (
const auto *Typedef =
Parm->getType()->getAs<clang::TypedefType>())
60 if (Typedef->getDecl()->getQualifiedNameAsString() ==
"testing::Unused")
64 if (
Parm->getType().getCanonicalType()->isNullPtrType())
69 const char *Begin = SM.getCharacterData(
Parm->getBeginLoc());
70 const char *End = SM.getCharacterData(
Parm->getLocation());
71 StringRef Data(Begin, End - Begin);
72 if (Data.contains(
"/*"))
75 UnnamedParams.push_back(std::make_pair(Function, I));
79 if (!UnnamedParams.empty()) {
80 const ParmVarDecl *FirstParm =
81 UnnamedParams.front().first->getParamDecl(UnnamedParams.front().second);
82 auto D =
diag(FirstParm->getLocation(),
83 "all parameters should be named in a function");
85 for (
auto P : UnnamedParams) {
87 StringRef NewName =
"unused";
91 const auto *
M = dyn_cast<CXXMethodDecl>(P.first);
92 if (
M &&
M->size_overridden_methods() > 0) {
93 const ParmVarDecl *OtherParm =
94 (*
M->begin_overridden_methods())->getParamDecl(P.second);
95 StringRef
Name = OtherParm->getName();
102 const ParmVarDecl *DefParm = Definition->getParamDecl(P.second);
103 StringRef
Name = DefParm->getName();
111 const ParmVarDecl *
Parm = P.first->getParamDecl(P.second);
112 D << FixItHint::CreateInsertion(
Parm->getLocation(),
113 " /*" + NewName.str() +
"*/");
llvm::SmallString< 256U > Name
const google::protobuf::Message & M
DiagnosticBuilder diag(SourceLocation Loc, StringRef Description, DiagnosticIDs::Level Level=DiagnosticIDs::Warning)
Add a diagnostic with the check's name.
void check(const ast_matchers::MatchFinder::MatchResult &Result) override
ClangTidyChecks that register ASTMatchers should do the actual work in here.
void registerMatchers(ast_matchers::MatchFinder *Finder) override
Override this to register AST matchers with Finder.