11 #include "clang/AST/ASTContext.h" 12 #include "clang/AST/DeclCXX.h" 13 #include "clang/AST/RecursiveASTVisitor.h" 14 #include "clang/ASTMatchers/ASTMatchFinder.h" 15 #include "clang/Basic/SourceLocation.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);
58 class FindUsageOfThis :
public RecursiveASTVisitor<FindUsageOfThis> {
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())))
96 const LangOptions &LangOpts,
98 if (SourceMgr.getFileID(Range.getBegin()) !=
99 SourceMgr.getFileID(Range.getEnd()))
102 return Lexer::getSourceText(CharSourceRange(Range,
true), SourceMgr,
107 SourceManager &SourceMgr,
108 const LangOptions &LangOpts) {
110 const auto FTL = TSI->getTypeLoc().IgnoreParens().getAs<FunctionTypeLoc>();
113 SourceRange
Range{FTL.getRParenLoc().getLocWithOffset(1),
114 FTL.getLocalRangeEnd()};
118 size_t Offset = Text.find(
"const");
119 if (Offset == StringRef::npos)
122 SourceLocation Start =
Range.getBegin().getLocWithOffset(Offset);
123 return {Start, Start.getLocWithOffset(strlen(
"const") - 1)};
126 void ConvertMemberFunctionsToStatic::check(
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 ");
static StringRef getStringFromRange(SourceManager &SourceMgr, const LangOptions &LangOpts, SourceRange Range)
Obtain the original source code text from a SourceRange.
static SourceRange getLocationOfConst(const TypeSourceInfo *TSI, SourceManager &SourceMgr, const LangOptions &LangOpts)
AST_MATCHER(Expr, isMacroID)
CodeCompletionBuilder Builder
===– Representation.cpp - ClangDoc Representation --------—*- C++ -*-===//
CharSourceRange Range
SourceRange for the file name.
llvm::Optional< llvm::Expected< tooling::AtomicChanges > > Result
AST_MATCHER_P(CXXMethodDecl, hasCanonicalDecl, ast_matchers::internal::Matcher< CXXMethodDecl >, InnerMatcher)