Index: clang-tidy/google/CMakeLists.txt =================================================================== --- clang-tidy/google/CMakeLists.txt +++ clang-tidy/google/CMakeLists.txt @@ -1,6 +1,7 @@ set(LLVM_LINK_COMPONENTS support) add_clang_library(clangTidyGoogleModule + ExplicitConstructorCheck.cpp GoogleTidyModule.cpp LINK_LIBS Index: clang-tidy/google/ExplicitConstructorCheck.h =================================================================== --- clang-tidy/google/ExplicitConstructorCheck.h +++ 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 @@ } // 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 Index: clang-tidy/google/ExplicitConstructorCheck.cpp =================================================================== --- clang-tidy/google/ExplicitConstructorCheck.cpp +++ clang-tidy/google/ExplicitConstructorCheck.cpp @@ -1,4 +1,4 @@ -//===--- GoogleTidyModule.cpp - clang-tidy --------------------------------===// +//===--- ExplicitConstructorCheck.cpp - clang-tidy ------------------------===// // // The LLVM Compiler Infrastructure // @@ -7,18 +7,11 @@ // //===----------------------------------------------------------------------===// -#include "GoogleTidyModule.h" -#include "../ClangTidy.h" -#include "../ClangTidyModule.h" -#include "../ClangTidyModuleRegistry.h" +#include "ExplicitConstructorCheck.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" using namespace clang::ast_matchers; @@ -88,22 +81,5 @@ << FixItHint::CreateInsertion(Loc, "explicit "); } -class GoogleModule : public ClangTidyModule { -public: - void addCheckFactories(ClangTidyCheckFactories &CheckFactories) override { - CheckFactories.addCheckFactory( - "google-explicit-constructor", - new ClangTidyCheckFactory()); - } -}; - -// Register the GoogleTidyModule using this statically initialized variable. -static ClangTidyModuleRegistry::Add X("google-module", - "Adds Google lint checks."); - -// This anchor is used to force the linker to link in the generated object file -// and thus register the GoogleModule. -volatile int GoogleModuleAnchorSource = 0; - } // namespace tidy } // namespace clang Index: clang-tidy/google/GoogleTidyModule.h =================================================================== --- clang-tidy/google/GoogleTidyModule.h +++ clang-tidy/google/GoogleTidyModule.h @@ -1,31 +0,0 @@ -//===--- GoogleTidyModule.h - clang-tidy ------------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_GOOGLE_GOOGLE_TIDY_MODULE_H -#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_GOOGLE_GOOGLE_TIDY_MODULE_H - -#include "../ClangTidy.h" - -namespace clang { -namespace tidy { - -/// \brief Checks that all single-argument constructors are explicit. -/// -/// see: -/// http://google-styleguide.googlecode.com/svn/trunk/cppguide.xml#Explicit_Constructors -class ExplicitConstructorCheck : public ClangTidyCheck { -public: - void registerMatchers(ast_matchers::MatchFinder *Finder) override; - void check(const ast_matchers::MatchFinder::MatchResult &Result) override; -}; - -} // namespace tidy -} // namespace clang - -#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_GOOGLE_GOOGLE_TIDY_MODULE_H Index: clang-tidy/google/GoogleTidyModule.cpp =================================================================== --- clang-tidy/google/GoogleTidyModule.cpp +++ 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 { Index: unittests/clang-tidy/GoogleModuleTest.cpp =================================================================== --- unittests/clang-tidy/GoogleModuleTest.cpp +++ 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 {