aboutsummaryrefslogtreecommitdiff
path: root/clang-tools-extra/clang-tidy/modernize/UseUsingCheck.cpp
diff options
context:
space:
mode:
authorKrystyna Gajczyk <krystyna.gajczyk@gmail.com>2016-06-25 18:37:53 +0000
committerKrystyna Gajczyk <krystyna.gajczyk@gmail.com>2016-06-25 18:37:53 +0000
commitc37933a12ad181db3f5f40bb99318f8eb7f25903 (patch)
tree943642627813d91d65d9361e9ac5ff694ba2fc18 /clang-tools-extra/clang-tidy/modernize/UseUsingCheck.cpp
parent3bc1af2be470106c961fdae4d08fdbe444a2114d (diff)
downloadllvm-c37933a12ad181db3f5f40bb99318f8eb7f25903.zip
llvm-c37933a12ad181db3f5f40bb99318f8eb7f25903.tar.gz
llvm-c37933a12ad181db3f5f40bb99318f8eb7f25903.tar.bz2
[clang-tidy] Add modernize-use-using
http://reviews.llvm.org/D18919 llvm-svn: 273786
Diffstat (limited to 'clang-tools-extra/clang-tidy/modernize/UseUsingCheck.cpp')
-rw-r--r--clang-tools-extra/clang-tidy/modernize/UseUsingCheck.cpp93
1 files changed, 93 insertions, 0 deletions
diff --git a/clang-tools-extra/clang-tidy/modernize/UseUsingCheck.cpp b/clang-tools-extra/clang-tidy/modernize/UseUsingCheck.cpp
new file mode 100644
index 0000000..498a95c
--- /dev/null
+++ b/clang-tools-extra/clang-tidy/modernize/UseUsingCheck.cpp
@@ -0,0 +1,93 @@
+//===--- UseUsingCheck.cpp - clang-tidy------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "UseUsingCheck.h"
+#include "../utils/LexerUtils.h"
+
+using namespace clang::ast_matchers;
+
+namespace clang {
+namespace tidy {
+namespace modernize {
+
+void UseUsingCheck::registerMatchers(MatchFinder *Finder) {
+ if (!getLangOpts().CPlusPlus11)
+ return;
+ Finder->addMatcher(typedefDecl().bind("typedef"), this);
+}
+
+// Checks if 'typedef' keyword can be removed - we do it only if
+// it is the only declaration in a declaration chain.
+static bool CheckRemoval(SourceManager &SM, const SourceLocation &LocStart,
+ const SourceLocation &LocEnd, ASTContext &Context,
+ SourceRange &ResultRange) {
+ FileID FID = SM.getFileID(LocEnd);
+ llvm::MemoryBuffer *Buffer = SM.getBuffer(FID, LocEnd);
+ Lexer DeclLexer(SM.getLocForStartOfFile(FID), Context.getLangOpts(),
+ Buffer->getBufferStart(), SM.getCharacterData(LocStart),
+ Buffer->getBufferEnd());
+ Token DeclToken;
+ bool result = false;
+ int parenthesisLevel = 0;
+
+ while (!DeclLexer.LexFromRawLexer(DeclToken)) {
+ if (DeclToken.getKind() == tok::TokenKind::l_paren)
+ parenthesisLevel++;
+ if (DeclToken.getKind() == tok::TokenKind::r_paren)
+ parenthesisLevel--;
+ if (DeclToken.getKind() == tok::TokenKind::semi)
+ break;
+ // if there is comma and we are not between open parenthesis then it is
+ // two or more declatarions in this chain
+ if (parenthesisLevel == 0 && DeclToken.getKind() == tok::TokenKind::comma)
+ return false;
+
+ if (DeclToken.isOneOf(tok::TokenKind::identifier,
+ tok::TokenKind::raw_identifier)) {
+ auto TokenStr = DeclToken.getRawIdentifier().str();
+
+ if (TokenStr == "typedef") {
+ ResultRange =
+ SourceRange(DeclToken.getLocation(), DeclToken.getEndLoc());
+ result = true;
+ }
+ }
+ }
+ // assert if there was keyword 'typedef' in declaration
+ assert(result && "No typedef found");
+
+ return result;
+}
+
+void UseUsingCheck::check(const MatchFinder::MatchResult &Result) {
+ const auto *MatchedDecl = Result.Nodes.getNodeAs<TypedefDecl>("typedef");
+ if (MatchedDecl->getLocation().isInvalid())
+ return;
+
+ auto &Context = *Result.Context;
+ auto &SM = *Result.SourceManager;
+
+ auto Diag =
+ diag(MatchedDecl->getLocStart(), "use 'using' instead of 'typedef'");
+ if (MatchedDecl->getLocStart().isMacroID()) {
+ return;
+ }
+ SourceRange RemovalRange;
+ if (CheckRemoval(SM, MatchedDecl->getLocStart(), MatchedDecl->getLocEnd(),
+ Context, RemovalRange)) {
+ Diag << FixItHint::CreateReplacement(
+ MatchedDecl->getSourceRange(),
+ "using " + MatchedDecl->getNameAsString() + " = " +
+ MatchedDecl->getUnderlyingType().getAsString(getLangOpts()));
+ }
+}
+
+} // namespace modernize
+} // namespace tidy
+} // namespace clang