10 #include "clang/AST/ASTContext.h"
11 #include "clang/AST/DeclCXX.h"
12 #include "clang/AST/RecursiveASTVisitor.h"
13 #include "clang/ASTMatchers/ASTMatchFinder.h"
14 #include "clang/Basic/SourceLocation.h"
15 #include "clang/Lex/Lexer.h"
21 namespace readability {
23 AST_MATCHER(CXXMethodDecl, isStatic) {
return Node.isStatic(); }
25 AST_MATCHER(CXXMethodDecl, hasTrivialBody) {
return Node.hasTrivialBody(); }
28 return Node.isOverloadedOperator();
32 return Node.hasAnyDependentBases();
36 return Node.getTemplatedKind() != FunctionDecl::TK_NonTemplate;
40 return Node.isDependentContext();
44 const ASTContext &Ctxt = Finder->getASTContext();
45 return clang::Lexer::makeFileCharRange(
46 clang::CharSourceRange::getCharRange(
47 Node.getTypeSourceInfo()->getTypeLoc().getSourceRange()),
48 Ctxt.getSourceManager(), Ctxt.getLangOpts())
53 ast_matchers::internal::Matcher<CXXMethodDecl>, InnerMatcher) {
54 return InnerMatcher.matches(*Node.getCanonicalDecl(), Finder,
Builder);
62 bool VisitCXXThisExpr(
const CXXThisExpr *
E) {
69 UsageOfThis.TraverseStmt(
const_cast<Stmt *
>(Node.getBody()));
71 return UsageOfThis.Used;
74 void ConvertMemberFunctionsToStatic::registerMatchers(MatchFinder *Finder) {
77 isDefinition(), isUserProvided(),
79 isExpansionInSystemHeader(), isVirtual(), isStatic(),
80 hasTrivialBody(), isOverloadedOperator(), cxxConstructorDecl(),
81 cxxDestructorDecl(), cxxConversionDecl(), isTemplate(),
85 hasAnyDependentBases())
88 isInsideMacroDefinition(),
89 hasCanonicalDecl(isInsideMacroDefinition()), usesThis())))
110 const auto FTL = TSI->getTypeLoc().IgnoreParens().getAs<FunctionTypeLoc>();
113 SourceRange
Range{FTL.getRParenLoc().getLocWithOffset(1),
114 FTL.getLocalRangeEnd()};
119 if (
Offset == StringRef::npos)
122 SourceLocation Start =
Range.getBegin().getLocWithOffset(
Offset);
123 return {Start, Start.getLocWithOffset(strlen(
"const") - 1)};
127 const MatchFinder::MatchResult &Result) {
128 const auto *Definition = Result.Nodes.getNodeAs<CXXMethodDecl>(
"x");
132 DiagnosticBuilder Diag =
133 diag(Definition->getLocation(),
"method %0 can be made static")
137 if (Definition->getMethodQualifiers().hasVolatile() ||
138 Definition->getMethodQualifiers().hasRestrict() ||
139 Definition->getRefQualifier() != RQ_None)
142 const CXXMethodDecl *Declaration = Definition->getCanonicalDecl();
144 if (Definition->isConst()) {
148 *Result.SourceManager,
149 Result.Context->getLangOpts());
151 if (DefConst.isInvalid())
154 if (Declaration != Definition) {
156 Declaration->getTypeSourceInfo(), *Result.SourceManager,
157 Result.Context->getLangOpts());
159 if (DeclConst.isInvalid())
161 Diag << FixItHint::CreateRemoval(DeclConst);
165 Diag << FixItHint::CreateRemoval(DefConst);
167 Diag << FixItHint::CreateInsertion(Declaration->getBeginLoc(),
"static ");