diff options
author | Aaron Ballman <aaron@aaronballman.com> | 2018-10-31 19:11:38 +0000 |
---|---|---|
committer | Aaron Ballman <aaron@aaronballman.com> | 2018-10-31 19:11:38 +0000 |
commit | a1e6c8120333420e029d41b72716b15617518034 (patch) | |
tree | 1bdb94bc1040748cc0150e739175b2538c5495e4 /clang-tidy/utils | |
parent | 764c358561448cb2b87636432b9e14b9904d012c (diff) |
Implement the readability-const-return-type check.
This check flags function top-level const-qualified return types and suggests removing the mostly-superfluous const qualifier where possible.
Patch by Yitzhak Mandelbaum.
git-svn-id: https://llvm.org/svn/llvm-project/clang-tools-extra/trunk@345764 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'clang-tidy/utils')
-rw-r--r-- | clang-tidy/utils/LexerUtils.cpp | 28 | ||||
-rw-r--r-- | clang-tidy/utils/LexerUtils.h | 8 |
2 files changed, 36 insertions, 0 deletions
diff --git a/clang-tidy/utils/LexerUtils.cpp b/clang-tidy/utils/LexerUtils.cpp index 82097978..edd4cd62 100644 --- a/clang-tidy/utils/LexerUtils.cpp +++ b/clang-tidy/utils/LexerUtils.cpp @@ -92,6 +92,34 @@ bool rangeContainsExpansionsOrDirectives(SourceRange Range, return false; } + +llvm::Optional<Token> getConstQualifyingToken(CharSourceRange Range, + const ASTContext &Context, + const SourceManager &SM) { + std::pair<FileID, unsigned> LocInfo = SM.getDecomposedLoc(Range.getBegin()); + StringRef File = SM.getBufferData(LocInfo.first); + Lexer RawLexer(SM.getLocForStartOfFile(LocInfo.first), Context.getLangOpts(), + File.begin(), File.data() + LocInfo.second, File.end()); + llvm::Optional<Token> FirstConstTok; + Token LastTokInRange; + Token Tok; + while (!RawLexer.LexFromRawLexer(Tok) && + Range.getEnd() != Tok.getLocation() && + !SM.isBeforeInTranslationUnit(Range.getEnd(), Tok.getLocation())) { + if (Tok.is(tok::raw_identifier)) { + IdentifierInfo &Info = Context.Idents.get( + StringRef(SM.getCharacterData(Tok.getLocation()), Tok.getLength())); + Tok.setIdentifierInfo(&Info); + Tok.setKind(Info.getTokenID()); + } + if (Tok.is(tok::kw_const) && !FirstConstTok) + FirstConstTok = Tok; + LastTokInRange = Tok; + } + // If the last token in the range is a `const`, then it const qualifies the + // type. Otherwise, the first `const` token, if any, is the qualifier. + return LastTokInRange.is(tok::kw_const) ? LastTokInRange : FirstConstTok; +} } // namespace lexer } // namespace utils } // namespace tidy diff --git a/clang-tidy/utils/LexerUtils.h b/clang-tidy/utils/LexerUtils.h index f81fdae4..55a8b85c 100644 --- a/clang-tidy/utils/LexerUtils.h +++ b/clang-tidy/utils/LexerUtils.h @@ -82,6 +82,14 @@ bool rangeContainsExpansionsOrDirectives(SourceRange Range, const SourceManager &SM, const LangOptions &LangOpts); +/// Assuming that ``Range`` spans a const-qualified type, returns the ``const`` +/// token in ``Range`` that is responsible for const qualification. ``Range`` +/// must be valid with respect to ``SM``. Returns ``None`` if no ``const`` +/// tokens are found. +llvm::Optional<Token> getConstQualifyingToken(CharSourceRange Range, + const ASTContext &Context, + const SourceManager &SM); + } // namespace lexer } // namespace utils } // namespace tidy |