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