Index: clang-tools-extra/trunk/clang-tidy/modernize/MakeSmartPtrCheck.h =================================================================== --- clang-tools-extra/trunk/clang-tidy/modernize/MakeSmartPtrCheck.h +++ clang-tools-extra/trunk/clang-tidy/modernize/MakeSmartPtrCheck.h @@ -11,6 +11,7 @@ #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MODERNIZE_MAKE_SMART_PTR_H #include "../ClangTidy.h" +#include "../utils/IncludeInserter.h" #include "clang/ASTMatchers/ASTMatchFinder.h" #include "clang/ASTMatchers/ASTMatchersInternal.h" #include "llvm/ADT/StringRef.h" @@ -24,9 +25,11 @@ class MakeSmartPtrCheck : public ClangTidyCheck { public: MakeSmartPtrCheck(StringRef Name, ClangTidyContext *Context, - std::string makeSmartPtrFunctionName); + StringRef MakeSmartPtrFunctionName); void registerMatchers(ast_matchers::MatchFinder *Finder) final; + void registerPPCallbacks(clang::CompilerInstance &Compiler) override; void check(const ast_matchers::MatchFinder::MatchResult &Result) final; + void storeOptions(ClangTidyOptions::OptionMap &Opts) override; protected: using SmartPtrTypeMatcher = ast_matchers::internal::BindableMatcher; @@ -43,14 +46,19 @@ static const char NewExpression[]; private: - std::string makeSmartPtrFunctionName; + std::unique_ptr Inserter; + const utils::IncludeSorter::IncludeStyle IncludeStyle; + const std::string MakeSmartPtrFunctionHeader; + const std::string MakeSmartPtrFunctionName; void checkConstruct(SourceManager &SM, const CXXConstructExpr *Construct, const QualType *Type, const CXXNewExpr *New); void checkReset(SourceManager &SM, const CXXMemberCallExpr *Member, const CXXNewExpr *New); + void replaceNew(DiagnosticBuilder &Diag, const CXXNewExpr *New, SourceManager &SM); + void insertHeader(DiagnosticBuilder &Diag, FileID FD); }; } // namespace modernize Index: clang-tools-extra/trunk/clang-tidy/modernize/MakeSmartPtrCheck.cpp =================================================================== --- clang-tools-extra/trunk/clang-tidy/modernize/MakeSmartPtrCheck.cpp +++ clang-tools-extra/trunk/clang-tidy/modernize/MakeSmartPtrCheck.cpp @@ -8,7 +8,9 @@ //===----------------------------------------------------------------------===// #include "MakeSharedCheck.h" +#include "clang/Frontend/CompilerInstance.h" #include "clang/Lex/Lexer.h" +#include "clang/Lex/Preprocessor.h" using namespace clang::ast_matchers; @@ -17,6 +19,9 @@ namespace modernize { namespace { + +constexpr char StdMemoryHeader[] = "memory"; + std::string GetNewExprName(const CXXNewExpr *NewExpr, const SourceManager &SM, const LangOptions &Lang) { @@ -29,6 +34,7 @@ } return WrittenName.str(); } + } // namespace const char MakeSmartPtrCheck::PointerType[] = "pointerType"; @@ -37,9 +43,28 @@ const char MakeSmartPtrCheck::NewExpression[] = "newExpression"; MakeSmartPtrCheck::MakeSmartPtrCheck(StringRef Name, ClangTidyContext *Context, - std::string makeSmartPtrFunctionName) + StringRef MakeSmartPtrFunctionName) : ClangTidyCheck(Name, Context), - makeSmartPtrFunctionName(std::move(makeSmartPtrFunctionName)) {} + IncludeStyle(utils::IncludeSorter::parseIncludeStyle( + Options.get("IncludeStyle", "llvm"))), + MakeSmartPtrFunctionHeader( + Options.get("MakeSmartPtrFunctionHeader", StdMemoryHeader)), + MakeSmartPtrFunctionName( + Options.get("MakeSmartPtrFunction", MakeSmartPtrFunctionName)) {} + +void MakeSmartPtrCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) { + Options.store(Opts, "IncludeStyle", IncludeStyle); + Options.store(Opts, "MakeSmartPtrFunctionHeader", MakeSmartPtrFunctionHeader); + Options.store(Opts, "MakeSmartPtrFunction", MakeSmartPtrFunctionName); +} + +void MakeSmartPtrCheck::registerPPCallbacks(CompilerInstance &Compiler) { + if (getLangOpts().CPlusPlus11) { + Inserter.reset(new utils::IncludeInserter( + Compiler.getSourceManager(), Compiler.getLangOpts(), IncludeStyle)); + Compiler.getPreprocessor().addPPCallbacks(Inserter->CreatePPCallbacks()); + } +} void MakeSmartPtrCheck::registerMatchers(ast_matchers::MatchFinder *Finder) { if (!getLangOpts().CPlusPlus11) @@ -107,7 +132,7 @@ return; auto Diag = diag(ConstructCallStart, "use %0 instead") - << makeSmartPtrFunctionName; + << MakeSmartPtrFunctionName; // Find the location of the template's left angle. size_t LAngle = ExprStr.find("<"); @@ -125,7 +150,7 @@ Diag << FixItHint::CreateReplacement( CharSourceRange::getCharRange(ConstructCallStart, ConstructCallEnd), - makeSmartPtrFunctionName); + MakeSmartPtrFunctionName); // If the smart_ptr is built with brace enclosed direct initialization, use // parenthesis instead. @@ -142,6 +167,7 @@ } replaceNew(Diag, New, SM); + insertHeader(Diag, SM.getFileID(ConstructCallStart)); } void MakeSmartPtrCheck::checkReset(SourceManager &SM, @@ -155,11 +181,11 @@ Lexer::getLocForEndOfToken(Expr->getLocEnd(), 0, SM, getLangOpts()); auto Diag = diag(ResetCallStart, "use %0 instead") - << makeSmartPtrFunctionName; + << MakeSmartPtrFunctionName; Diag << FixItHint::CreateReplacement( CharSourceRange::getCharRange(OperatorLoc, ExprEnd), - (llvm::Twine(" = ") + makeSmartPtrFunctionName + "<" + + (llvm::Twine(" = ") + MakeSmartPtrFunctionName + "<" + GetNewExprName(New, SM, getLangOpts()) + ">") .str()); @@ -167,6 +193,7 @@ Diag << FixItHint::CreateInsertion(ExprStart, "*"); replaceNew(Diag, New, SM); + insertHeader(Diag, SM.getFileID(OperatorLoc)); } void MakeSmartPtrCheck::replaceNew(DiagnosticBuilder &Diag, @@ -243,6 +270,17 @@ } } +void MakeSmartPtrCheck::insertHeader(DiagnosticBuilder &Diag, FileID FD) { + if (MakeSmartPtrFunctionHeader.empty()) { + return; + } + if (auto IncludeFixit = Inserter->CreateIncludeInsertion( + FD, MakeSmartPtrFunctionHeader, + /*IsAngled=*/MakeSmartPtrFunctionHeader == StdMemoryHeader)) { + Diag << *IncludeFixit; + } +} + } // namespace modernize } // namespace tidy } // namespace clang Index: clang-tools-extra/trunk/docs/clang-tidy/checks/modernize-make-shared.rst =================================================================== --- clang-tools-extra/trunk/docs/clang-tidy/checks/modernize-make-shared.rst +++ clang-tools-extra/trunk/docs/clang-tidy/checks/modernize-make-shared.rst @@ -25,3 +25,21 @@ // becomes my_ptr = std::make_shared(1, 2); + +Options +------- + +.. option:: MakeSmartPtrFunction + + A string specifying the name of make-shared-ptr function. Default is + `std::make_shared`. + +.. option:: MakeSmartPtrFunctionHeader + + A string specifying the corresponding header of make-shared-ptr function. + Default is `memory`. + +.. option:: IncludeStyle + + A string specifying which include-style is used, `llvm` or `google`. Default + is `llvm`. Index: clang-tools-extra/trunk/docs/clang-tidy/checks/modernize-make-unique.rst =================================================================== --- clang-tools-extra/trunk/docs/clang-tidy/checks/modernize-make-unique.rst +++ clang-tools-extra/trunk/docs/clang-tidy/checks/modernize-make-unique.rst @@ -25,3 +25,21 @@ // becomes my_ptr = std::make_unique(1, 2); + +Options +------- + +.. option:: MakeSmartPtrFunction + + A string specifying the name of make-unique-ptr function. Default is + `std::make_unique`. + +.. option:: MakeSmartPtrFunctionHeader + + A string specifying the corresponding header of make-unique-ptr function. + Default is `memory`. + +.. option:: IncludeStyle + + A string specifying which include-style is used, `llvm` or `google`. Default + is `llvm`. Index: clang-tools-extra/trunk/test/clang-tidy/Inputs/modernize-smart-ptr/shared_ptr.h =================================================================== --- clang-tools-extra/trunk/test/clang-tidy/Inputs/modernize-smart-ptr/shared_ptr.h +++ clang-tools-extra/trunk/test/clang-tidy/Inputs/modernize-smart-ptr/shared_ptr.h @@ -0,0 +1,24 @@ +namespace std { + +template +class shared_ptr { +public: + shared_ptr(); + shared_ptr(type *ptr); + shared_ptr(const shared_ptr &t) {} + shared_ptr(shared_ptr &&t) {} + ~shared_ptr(); + type &operator*() { return *ptr; } + type *operator->() { return ptr; } + type *release(); + void reset(); + void reset(type *pt); + shared_ptr &operator=(shared_ptr &&); + template + shared_ptr &operator=(shared_ptr &&); + +private: + type *ptr; +}; + +} // namespace std Index: clang-tools-extra/trunk/test/clang-tidy/Inputs/modernize-smart-ptr/unique_ptr.h =================================================================== --- clang-tools-extra/trunk/test/clang-tidy/Inputs/modernize-smart-ptr/unique_ptr.h +++ clang-tools-extra/trunk/test/clang-tidy/Inputs/modernize-smart-ptr/unique_ptr.h @@ -0,0 +1,28 @@ +namespace std { + +template +class default_delete {}; + +template > +class unique_ptr { +public: + unique_ptr(); + unique_ptr(type *ptr); + unique_ptr(const unique_ptr &t) = delete; + unique_ptr(unique_ptr &&t); + ~unique_ptr(); + type &operator*() { return *ptr; } + type *operator->() { return ptr; } + type *release(); + void reset(); + void reset(type *pt); + void reset(type pt); + unique_ptr &operator=(unique_ptr &&); + template + unique_ptr &operator=(unique_ptr &&); + +private: + type *ptr; +}; + +} // namespace std Index: clang-tools-extra/trunk/test/clang-tidy/modernize-make-shared-header.cpp =================================================================== --- clang-tools-extra/trunk/test/clang-tidy/modernize-make-shared-header.cpp +++ clang-tools-extra/trunk/test/clang-tidy/modernize-make-shared-header.cpp @@ -0,0 +1,17 @@ +// RUN: %check_clang_tidy %s modernize-make-shared %t -- \ +// RUN: -config="{CheckOptions: \ +// RUN: [{key: modernize-make-shared.MakeSmartPtrFunction, \ +// RUN: value: 'my::MakeShared'}, \ +// RUN: {key: modernize-make-shared.MakeSmartPtrFunctionHeader, \ +// RUN: value: 'make_shared_util.h'} \ +// RUN: ]}" \ +// RUN: -- -std=c++11 -I%S/Inputs/modernize-smart-ptr + +#include "shared_ptr.h" +// CHECK-FIXES: #include "make_shared_util.h" + +void f() { + std::shared_ptr P1 = std::shared_ptr(new int()); + // CHECK-MESSAGES: :[[@LINE-1]]:29: warning: use my::MakeShared instead + // CHECK-FIXES: std::shared_ptr P1 = my::MakeShared(); +} Index: clang-tools-extra/trunk/test/clang-tidy/modernize-make-shared.cpp =================================================================== --- clang-tools-extra/trunk/test/clang-tidy/modernize-make-shared.cpp +++ clang-tools-extra/trunk/test/clang-tidy/modernize-make-shared.cpp @@ -1,28 +1,8 @@ -// RUN: %check_clang_tidy %s modernize-make-shared %t +// RUN: %check_clang_tidy %s modernize-make-shared %t -- -- -std=c++11 \ +// RUN: -I%S/Inputs/modernize-smart-ptr -namespace std { - -template -class shared_ptr { -public: - shared_ptr(); - shared_ptr(type *ptr); - shared_ptr(const shared_ptr &t) {} - shared_ptr(shared_ptr &&t) {} - ~shared_ptr(); - type &operator*() { return *ptr; } - type *operator->() { return ptr; } - type *release(); - void reset(); - void reset(type *pt); - shared_ptr &operator=(shared_ptr &&); - template - shared_ptr &operator=(shared_ptr &&); - -private: - type *ptr; -}; -} +#include "shared_ptr.h" +// CHECK-FIXES: #include struct Base { Base(); Index: clang-tools-extra/trunk/test/clang-tidy/modernize-make-unique-header.cpp =================================================================== --- clang-tools-extra/trunk/test/clang-tidy/modernize-make-unique-header.cpp +++ clang-tools-extra/trunk/test/clang-tidy/modernize-make-unique-header.cpp @@ -0,0 +1,17 @@ +// RUN: %check_clang_tidy %s modernize-make-unique %t -- \ +// RUN: -config="{CheckOptions: \ +// RUN: [{key: modernize-make-unique.MakeSmartPtrFunction, \ +// RUN: value: 'my::MakeUnique'}, \ +// RUN: {key: modernize-make-unique.MakeSmartPtrFunctionHeader, \ +// RUN: value: 'make_unique_util.h'} \ +// RUN: ]}" \ +// RUN: -- -std=c++11 -I%S/Inputs/modernize-smart-ptr + +#include "unique_ptr.h" +// CHECK-FIXES: #include "make_unique_util.h" + +void f() { + std::unique_ptr P1 = std::unique_ptr(new int()); + // CHECK-MESSAGES: :[[@LINE-1]]:29: warning: use my::MakeUnique instead + // CHECK-FIXES: std::unique_ptr P1 = my::MakeUnique(); +} Index: clang-tools-extra/trunk/test/clang-tidy/modernize-make-unique.cpp =================================================================== --- clang-tools-extra/trunk/test/clang-tidy/modernize-make-unique.cpp +++ clang-tools-extra/trunk/test/clang-tidy/modernize-make-unique.cpp @@ -1,32 +1,8 @@ -// RUN: %check_clang_tidy %s modernize-make-unique %t +// RUN: %check_clang_tidy %s modernize-make-unique %t -- -- -std=c++11 \ +// RUN: -I%S/Inputs/modernize-smart-ptr -namespace std { - -template -class default_delete {}; - -template > -class unique_ptr { -public: - unique_ptr(); - unique_ptr(type *ptr); - unique_ptr(const unique_ptr &t) = delete; - unique_ptr(unique_ptr &&t); - ~unique_ptr(); - type &operator*() { return *ptr; } - type *operator->() { return ptr; } - type *release(); - void reset(); - void reset(type *pt); - void reset(type pt); - unique_ptr &operator=(unique_ptr &&); - template - unique_ptr &operator=(unique_ptr &&); - -private: - type *ptr; -}; -} +#include "unique_ptr.h" +// CHECK-FIXES: #include struct Base { Base();