From 72f1e754a78e3504983cfe11e2888a09a2bc9e79 Mon Sep 17 00:00:00 2001 From: Alexander Kornienko Date: Wed, 18 Jun 2014 09:33:46 +0000 Subject: [PATCH] Move google-explicit-constructor check to a separate source file. Summary: No functional changes. Reviewers: djasper Reviewed By: djasper Subscribers: cfe-commits Differential Revision: http://reviews.llvm.org/D4188 llvm-svn: 211154 --- .../clang-tidy/google/CMakeLists.txt | 1 + .../google/ExplicitConstructorCheck.cpp | 85 +++++++++++++++++++ ...idyModule.h => ExplicitConstructorCheck.h} | 8 +- .../clang-tidy/google/GoogleTidyModule.cpp | 73 +--------------- .../unittests/clang-tidy/GoogleModuleTest.cpp | 2 +- 5 files changed, 92 insertions(+), 77 deletions(-) create mode 100644 clang-tools-extra/clang-tidy/google/ExplicitConstructorCheck.cpp rename clang-tools-extra/clang-tidy/google/{GoogleTidyModule.h => ExplicitConstructorCheck.h} (71%) diff --git a/clang-tools-extra/clang-tidy/google/CMakeLists.txt b/clang-tools-extra/clang-tidy/google/CMakeLists.txt index 935cabcf8343..3562e520ca8b 100644 --- a/clang-tools-extra/clang-tidy/google/CMakeLists.txt +++ b/clang-tools-extra/clang-tidy/google/CMakeLists.txt @@ -1,6 +1,7 @@ set(LLVM_LINK_COMPONENTS support) add_clang_library(clangTidyGoogleModule + ExplicitConstructorCheck.cpp GoogleTidyModule.cpp LINK_LIBS diff --git a/clang-tools-extra/clang-tidy/google/ExplicitConstructorCheck.cpp b/clang-tools-extra/clang-tidy/google/ExplicitConstructorCheck.cpp new file mode 100644 index 000000000000..764f18031c84 --- /dev/null +++ b/clang-tools-extra/clang-tidy/google/ExplicitConstructorCheck.cpp @@ -0,0 +1,85 @@ +//===--- ExplicitConstructorCheck.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 "ExplicitConstructorCheck.h" +#include "clang/AST/ASTContext.h" +#include "clang/ASTMatchers/ASTMatchFinder.h" +#include "clang/ASTMatchers/ASTMatchers.h" +#include "clang/Lex/Lexer.h" + +using namespace clang::ast_matchers; + +namespace clang { +namespace tidy { + +void ExplicitConstructorCheck::registerMatchers(MatchFinder *Finder) { + Finder->addMatcher(constructorDecl().bind("ctor"), this); +} + +// Looks for the token matching the predicate and returns the range of the found +// token including trailing whitespace. +SourceRange FindToken(const SourceManager &Sources, LangOptions LangOpts, + SourceLocation StartLoc, SourceLocation EndLoc, + bool (*Pred)(const Token &)) { + if (StartLoc.isMacroID() || EndLoc.isMacroID()) + return SourceRange(); + FileID File = Sources.getFileID(Sources.getSpellingLoc(StartLoc)); + StringRef Buf = Sources.getBufferData(File); + const char *StartChar = Sources.getCharacterData(StartLoc); + Lexer Lex(StartLoc, LangOpts, StartChar, StartChar, Buf.end()); + Lex.SetCommentRetentionState(true); + Token Tok; + do { + Lex.LexFromRawLexer(Tok); + if (Pred(Tok)) { + Token NextTok; + Lex.LexFromRawLexer(NextTok); + return SourceRange(Tok.getLocation(), NextTok.getLocation()); + } + } while (Tok.isNot(tok::eof) && Tok.getLocation() < EndLoc); + + return SourceRange(); +} + +void ExplicitConstructorCheck::check(const MatchFinder::MatchResult &Result) { + const CXXConstructorDecl *Ctor = + Result.Nodes.getNodeAs("ctor"); + // Do not be confused: isExplicit means 'explicit' keyword is present, + // isImplicit means that it's a compiler-generated constructor. + if (Ctor->isOutOfLine() || Ctor->isImplicit() || Ctor->isDeleted()) + return; + + if (Ctor->isExplicit() && Ctor->isCopyOrMoveConstructor()) { + auto isKWExplicit = [](const Token &Tok) { + return Tok.is(tok::raw_identifier) && + Tok.getRawIdentifier() == "explicit"; + }; + SourceRange ExplicitTokenRange = + FindToken(*Result.SourceManager, Result.Context->getLangOpts(), + Ctor->getOuterLocStart(), Ctor->getLocEnd(), isKWExplicit); + DiagnosticBuilder Diag = + diag(Ctor->getLocation(), "%0 constructor declared explicit.") + << (Ctor->isMoveConstructor() ? "Move" : "Copy"); + if (ExplicitTokenRange.isValid()) { + Diag << FixItHint::CreateRemoval( + CharSourceRange::getCharRange(ExplicitTokenRange)); + } + } + + if (Ctor->isExplicit() || Ctor->isCopyOrMoveConstructor() || + Ctor->getNumParams() == 0 || Ctor->getMinRequiredArguments() > 1) + return; + + SourceLocation Loc = Ctor->getLocation(); + diag(Loc, "Single-argument constructors must be explicit") + << FixItHint::CreateInsertion(Loc, "explicit "); +} + +} // namespace tidy +} // namespace clang diff --git a/clang-tools-extra/clang-tidy/google/GoogleTidyModule.h b/clang-tools-extra/clang-tidy/google/ExplicitConstructorCheck.h similarity index 71% rename from clang-tools-extra/clang-tidy/google/GoogleTidyModule.h rename to clang-tools-extra/clang-tidy/google/ExplicitConstructorCheck.h index e29e8c80c319..a18561d43587 100644 --- a/clang-tools-extra/clang-tidy/google/GoogleTidyModule.h +++ b/clang-tools-extra/clang-tidy/google/ExplicitConstructorCheck.h @@ -1,4 +1,4 @@ -//===--- GoogleTidyModule.h - clang-tidy ------------------------*- C++ -*-===// +//===--- ExplicitConstructorCheck.h - clang-tidy ----------------*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_GOOGLE_GOOGLE_TIDY_MODULE_H -#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_GOOGLE_GOOGLE_TIDY_MODULE_H +#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_GOOGLE_EXPLICIT_CONSTRUCTOR_CHECK_H +#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_GOOGLE_EXPLICIT_CONSTRUCTOR_CHECK_H #include "../ClangTidy.h" @@ -28,4 +28,4 @@ public: } // namespace tidy } // namespace clang -#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_GOOGLE_GOOGLE_TIDY_MODULE_H +#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_GOOGLE_EXPLICIT_CONSTRUCTOR_CHECK_H diff --git a/clang-tools-extra/clang-tidy/google/GoogleTidyModule.cpp b/clang-tools-extra/clang-tidy/google/GoogleTidyModule.cpp index c69187291f99..05787cf214dc 100644 --- a/clang-tools-extra/clang-tidy/google/GoogleTidyModule.cpp +++ b/clang-tools-extra/clang-tidy/google/GoogleTidyModule.cpp @@ -7,87 +7,16 @@ // //===----------------------------------------------------------------------===// -#include "GoogleTidyModule.h" #include "../ClangTidy.h" #include "../ClangTidyModule.h" #include "../ClangTidyModuleRegistry.h" -#include "clang/AST/ASTContext.h" -#include "clang/ASTMatchers/ASTMatchFinder.h" -#include "clang/ASTMatchers/ASTMatchers.h" -#include "clang/Frontend/CompilerInstance.h" -#include "clang/Lex/Lexer.h" -#include "clang/Lex/PPCallbacks.h" -#include "clang/Lex/Preprocessor.h" -#include "llvm/Support/raw_ostream.h" +#include "ExplicitConstructorCheck.h" using namespace clang::ast_matchers; namespace clang { namespace tidy { -void ExplicitConstructorCheck::registerMatchers(MatchFinder *Finder) { - Finder->addMatcher(constructorDecl().bind("ctor"), this); -} - -// Looks for the token matching the predicate and returns the range of the found -// token including trailing whitespace. -SourceRange FindToken(const SourceManager &Sources, LangOptions LangOpts, - SourceLocation StartLoc, SourceLocation EndLoc, - bool (*Pred)(const Token &)) { - if (StartLoc.isMacroID() || EndLoc.isMacroID()) - return SourceRange(); - FileID File = Sources.getFileID(Sources.getSpellingLoc(StartLoc)); - StringRef Buf = Sources.getBufferData(File); - const char *StartChar = Sources.getCharacterData(StartLoc); - Lexer Lex(StartLoc, LangOpts, StartChar, StartChar, Buf.end()); - Lex.SetCommentRetentionState(true); - Token Tok; - do { - Lex.LexFromRawLexer(Tok); - if (Pred(Tok)) { - Token NextTok; - Lex.LexFromRawLexer(NextTok); - return SourceRange(Tok.getLocation(), NextTok.getLocation()); - } - } while (Tok.isNot(tok::eof) && Tok.getLocation() < EndLoc); - - return SourceRange(); -} - -void ExplicitConstructorCheck::check(const MatchFinder::MatchResult &Result) { - const CXXConstructorDecl *Ctor = - Result.Nodes.getNodeAs("ctor"); - // Do not be confused: isExplicit means 'explicit' keyword is present, - // isImplicit means that it's a compiler-generated constructor. - if (Ctor->isOutOfLine() || Ctor->isImplicit() || Ctor->isDeleted()) - return; - - if (Ctor->isExplicit() && Ctor->isCopyOrMoveConstructor()) { - auto isKWExplicit = [](const Token &Tok) { - return Tok.is(tok::raw_identifier) && - Tok.getRawIdentifier() == "explicit"; - }; - SourceRange ExplicitTokenRange = - FindToken(*Result.SourceManager, Result.Context->getLangOpts(), - Ctor->getOuterLocStart(), Ctor->getLocEnd(), isKWExplicit); - DiagnosticBuilder Diag = - diag(Ctor->getLocation(), "%0 constructor declared explicit.") - << (Ctor->isMoveConstructor() ? "Move" : "Copy"); - if (ExplicitTokenRange.isValid()) { - Diag << FixItHint::CreateRemoval( - CharSourceRange::getCharRange(ExplicitTokenRange)); - } - } - - if (Ctor->isExplicit() || Ctor->isCopyOrMoveConstructor() || - Ctor->getNumParams() == 0 || Ctor->getMinRequiredArguments() > 1) - return; - - SourceLocation Loc = Ctor->getLocation(); - diag(Loc, "Single-argument constructors must be explicit") - << FixItHint::CreateInsertion(Loc, "explicit "); -} - class GoogleModule : public ClangTidyModule { public: void addCheckFactories(ClangTidyCheckFactories &CheckFactories) override { diff --git a/clang-tools-extra/unittests/clang-tidy/GoogleModuleTest.cpp b/clang-tools-extra/unittests/clang-tidy/GoogleModuleTest.cpp index 89e47407c989..2e74deaa2fdf 100644 --- a/clang-tools-extra/unittests/clang-tidy/GoogleModuleTest.cpp +++ b/clang-tools-extra/unittests/clang-tidy/GoogleModuleTest.cpp @@ -1,5 +1,5 @@ #include "ClangTidyTest.h" -#include "google/GoogleTidyModule.h" +#include "google/ExplicitConstructorCheck.h" #include "gtest/gtest.h" namespace clang {