10 #include "clang/AST/ASTContext.h" 11 #include "clang/ASTMatchers/ASTMatchFinder.h" 12 #include "clang/ASTMatchers/ASTMatchers.h" 18 namespace readability {
20 void NamedParameterCheck::registerMatchers(ast_matchers::MatchFinder *Finder) {
21 Finder->addMatcher(functionDecl(unless(isInstantiated())).bind(
"decl"),
this);
24 void NamedParameterCheck::check(
const MatchFinder::MatchResult &Result) {
25 const SourceManager &SM = *Result.SourceManager;
26 const auto *Function = Result.Nodes.getNodeAs<FunctionDecl>(
"decl");
27 SmallVector<std::pair<const FunctionDecl *, unsigned>, 4> UnnamedParams;
30 if (Function->isImplicit())
35 const FunctionDecl *Definition =
nullptr;
36 if ((!Function->isDefined(Definition) || Function->isDefaulted() ||
37 Function->isDeleted()) &&
38 (!isa<CXXMethodDecl>(Function) ||
39 cast<CXXMethodDecl>(Function)->size_overridden_methods() == 0))
45 for (
unsigned I = 0,
E = Function->getNumParams(); I !=
E; ++I) {
46 const ParmVarDecl *Parm = Function->getParamDecl(I);
47 if (Parm->isImplicit())
50 if (!Parm->getName().empty())
54 if ((Function->getOverloadedOperator() == OO_PlusPlus ||
55 Function->getOverloadedOperator() == OO_MinusMinus) &&
56 Parm->getType()->isSpecificBuiltinType(BuiltinType::Int))
60 if (!Parm->getLocation().isValid() || Parm->getLocation().isMacroID() ||
61 !SM.isWrittenInSameFile(Parm->getBeginLoc(), Parm->getLocation()))
65 if (
auto Typedef = Parm->getType()->getAs<clang::TypedefType>())
66 if (Typedef->getDecl()->getQualifiedNameAsString() ==
"testing::Unused")
70 if (Parm->getType().getCanonicalType()->isNullPtrType())
75 const char *Begin = SM.getCharacterData(Parm->getBeginLoc());
76 const char *End = SM.getCharacterData(Parm->getLocation());
77 StringRef Data(Begin, End - Begin);
78 if (Data.find(
"/*") != StringRef::npos)
81 UnnamedParams.push_back(std::make_pair(Function, I));
85 if (!UnnamedParams.empty()) {
86 const ParmVarDecl *FirstParm =
87 UnnamedParams.front().first->getParamDecl(UnnamedParams.front().second);
88 auto D = diag(FirstParm->getLocation(),
89 "all parameters should be named in a function");
91 for (
auto P : UnnamedParams) {
93 StringRef NewName =
"unused";
97 const auto *M = dyn_cast<CXXMethodDecl>(P.first);
98 if (M && M->size_overridden_methods() > 0) {
99 const ParmVarDecl *OtherParm =
100 (*M->begin_overridden_methods())->getParamDecl(P.second);
101 StringRef
Name = OtherParm->getName();
108 const ParmVarDecl *DefParm = Definition->getParamDecl(P.second);
109 StringRef
Name = DefParm->getName();
117 const ParmVarDecl *Parm = P.first->getParamDecl(P.second);
118 D << FixItHint::CreateInsertion(Parm->getLocation(),
119 " /*" + NewName.str() +
"*/");
static constexpr llvm::StringLiteral Name
===– Representation.cpp - ClangDoc Representation --------—*- C++ -*-===//