11 #include "../utils/LexerUtils.h" 12 #include "clang/AST/ASTContext.h" 13 #include "clang/ASTMatchers/ASTMatchFinder.h" 14 #include "clang/Basic/SourceLocation.h" 15 #include "clang/Lex/Lexer.h" 16 #include "llvm/ADT/Optional.h" 22 namespace readability {
28 static llvm::Optional<Token>
30 const MatchFinder::MatchResult &
Result) {
31 if (!Def->getReturnType().isLocalConstQualified())
38 SourceLocation NameBeginLoc = Def->getQualifier()
39 ? Def->getQualifierLoc().getBeginLoc()
44 CharSourceRange FileRange = Lexer::makeFileCharRange(
45 CharSourceRange::getCharRange(Def->getBeginLoc(), NameBeginLoc),
46 *Result.SourceManager, Result.Context->getLangOpts());
48 if (FileRange.isInvalid())
52 *Result.SourceManager);
62 llvm::SmallVector<clang::FixItHint, 4>
Hints;
65 llvm::SmallVector<clang::SourceLocation, 4>
DeclLocs;
71 static CheckResult
checkDef(
const clang::FunctionDecl *Def,
72 const MatchFinder::MatchResult &MatchResult) {
79 CharSourceRange::getCharRange(Tok->getLocation(), Tok->getEndLoc());
80 Result.Hints.push_back(FixItHint::CreateRemoval(Result.ConstRange));
85 for (
const FunctionDecl *Decl = Def->getPreviousDecl(); Decl !=
nullptr;
86 Decl = Decl->getPreviousDecl()) {
88 Result.Hints.push_back(FixItHint::CreateRemoval(
89 CharSourceRange::getCharRange(T->getLocation(), T->getEndLoc())));
92 Result.DeclLocs.push_back(Decl->getInnerLocStart());
97 void ConstReturnTypeCheck::registerMatchers(MatchFinder *Finder) {
101 functionDecl(returns(isConstQualified()), isDefinition()).bind(
"func"),
105 void ConstReturnTypeCheck::check(
const MatchFinder::MatchResult &
Result) {
106 const auto *Def = Result.Nodes.getNodeAs<FunctionDecl>(
"func");
107 CheckResult CR =
checkDef(Def, Result);
112 DiagnosticBuilder Diagnostic =
113 diag(Def->getInnerLocStart(),
114 "return type %0 is 'const'-qualified at the top level, which may " 115 "reduce code readability without improving const correctness")
116 << Def->getReturnType();
117 if (CR.ConstRange.isValid())
118 Diagnostic << CR.ConstRange;
119 for (
auto &Hint : CR.Hints)
122 for (
auto Loc : CR.DeclLocs)
123 diag(
Loc,
"could not transform this declaration", DiagnosticIDs::Note);
SourceLocation Loc
'#' location in the include directive
llvm::SmallVector< clang::SourceLocation, 4 > DeclLocs
static llvm::Optional< Token > findConstToRemove(const FunctionDecl *Def, const MatchFinder::MatchResult &Result)
static CheckResult checkDef(const clang::FunctionDecl *Def, const MatchFinder::MatchResult &MatchResult)
llvm::Optional< llvm::Expected< tooling::AtomicChanges > > Result
llvm::Optional< Token > getConstQualifyingToken(CharSourceRange Range, const ASTContext &Context, const SourceManager &SM)
Assuming that Range spans a const-qualified type, returns the const token in Range that is responsibl...
===– Representation.cpp - ClangDoc Representation --------—*- C++ -*-===//
CharSourceRange ConstRange
llvm::SmallVector< clang::FixItHint, 4 > Hints