diff options
author | Haojian Wu <hokein@google.com> | 2017-07-05 07:49:00 +0000 |
---|---|---|
committer | Haojian Wu <hokein@google.com> | 2017-07-05 07:49:00 +0000 |
commit | 040c0f96ccac253ae4bfd9ce807e268b4ced155f (patch) | |
tree | 74824b4e4f5f0cd3fdb3c5ba9f888f9e1b62ffec /clang-tools-extra | |
parent | d19389a3c946e2d66be9db203c0e9e57663a89f7 (diff) | |
download | llvm-040c0f96ccac253ae4bfd9ce807e268b4ced155f.zip llvm-040c0f96ccac253ae4bfd9ce807e268b4ced155f.tar.gz llvm-040c0f96ccac253ae4bfd9ce807e268b4ced155f.tar.bz2 |
[clang-tidy] Add "MakeSmartPtrFunction" option to modernize-make-shared/unique checks.
Reviewers: alexfh, aaron.ballman
Reviewed By: alexfh
Subscribers: JDevlieghere, Eugene.Zelenko, xazax.hun, cfe-commits
Differential Revision: https://reviews.llvm.org/D34206
llvm-svn: 307130
Diffstat (limited to 'clang-tools-extra')
10 files changed, 184 insertions, 60 deletions
diff --git a/clang-tools-extra/clang-tidy/modernize/MakeSmartPtrCheck.cpp b/clang-tools-extra/clang-tidy/modernize/MakeSmartPtrCheck.cpp index ff69659..fd2b74c 100644 --- a/clang-tools-extra/clang-tidy/modernize/MakeSmartPtrCheck.cpp +++ b/clang-tools-extra/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 tidy { namespace modernize { namespace { + +constexpr char StdMemoryHeader[] = "memory"; + std::string GetNewExprName(const CXXNewExpr *NewExpr, const SourceManager &SM, const LangOptions &Lang) { @@ -29,6 +34,7 @@ std::string GetNewExprName(const CXXNewExpr *NewExpr, } return WrittenName.str(); } + } // namespace const char MakeSmartPtrCheck::PointerType[] = "pointerType"; @@ -37,9 +43,28 @@ const char MakeSmartPtrCheck::ResetCall[] = "resetCall"; 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 @@ void MakeSmartPtrCheck::checkConstruct(SourceManager &SM, 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 @@ void MakeSmartPtrCheck::checkConstruct(SourceManager &SM, 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 @@ void MakeSmartPtrCheck::checkConstruct(SourceManager &SM, } replaceNew(Diag, New, SM); + insertHeader(Diag, SM.getFileID(ConstructCallStart)); } void MakeSmartPtrCheck::checkReset(SourceManager &SM, @@ -155,11 +181,11 @@ void MakeSmartPtrCheck::checkReset(SourceManager &SM, 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 @@ void MakeSmartPtrCheck::checkReset(SourceManager &SM, Diag << FixItHint::CreateInsertion(ExprStart, "*"); replaceNew(Diag, New, SM); + insertHeader(Diag, SM.getFileID(OperatorLoc)); } void MakeSmartPtrCheck::replaceNew(DiagnosticBuilder &Diag, @@ -243,6 +270,17 @@ void MakeSmartPtrCheck::replaceNew(DiagnosticBuilder &Diag, } } +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 diff --git a/clang-tools-extra/clang-tidy/modernize/MakeSmartPtrCheck.h b/clang-tools-extra/clang-tidy/modernize/MakeSmartPtrCheck.h index 0d6d0c9..f01550e 100644 --- a/clang-tools-extra/clang-tidy/modernize/MakeSmartPtrCheck.h +++ b/clang-tools-extra/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 @@ namespace modernize { 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<QualType>; @@ -43,14 +46,19 @@ protected: static const char NewExpression[]; private: - std::string makeSmartPtrFunctionName; + std::unique_ptr<utils::IncludeInserter> 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 diff --git a/clang-tools-extra/docs/clang-tidy/checks/modernize-make-shared.rst b/clang-tools-extra/docs/clang-tidy/checks/modernize-make-shared.rst index d33d3b1..cf59d19 100644 --- a/clang-tools-extra/docs/clang-tidy/checks/modernize-make-shared.rst +++ b/clang-tools-extra/docs/clang-tidy/checks/modernize-make-shared.rst @@ -25,3 +25,21 @@ expression, and replaces it with a call to ``std::make_shared``. // becomes my_ptr = std::make_shared<MyPair>(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`. diff --git a/clang-tools-extra/docs/clang-tidy/checks/modernize-make-unique.rst b/clang-tools-extra/docs/clang-tidy/checks/modernize-make-unique.rst index 0dce521..e6b17db 100644 --- a/clang-tools-extra/docs/clang-tidy/checks/modernize-make-unique.rst +++ b/clang-tools-extra/docs/clang-tidy/checks/modernize-make-unique.rst @@ -25,3 +25,21 @@ expression, and replaces it with a call to ``std::make_unique``. // becomes my_ptr = std::make_unique<MyPair>(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`. diff --git a/clang-tools-extra/test/clang-tidy/Inputs/modernize-smart-ptr/shared_ptr.h b/clang-tools-extra/test/clang-tidy/Inputs/modernize-smart-ptr/shared_ptr.h new file mode 100644 index 0000000..0f4f2a9 --- /dev/null +++ b/clang-tools-extra/test/clang-tidy/Inputs/modernize-smart-ptr/shared_ptr.h @@ -0,0 +1,24 @@ +namespace std { + +template <typename type> +class shared_ptr { +public: + shared_ptr(); + shared_ptr(type *ptr); + shared_ptr(const shared_ptr<type> &t) {} + shared_ptr(shared_ptr<type> &&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 <typename T> + shared_ptr &operator=(shared_ptr<T> &&); + +private: + type *ptr; +}; + +} // namespace std diff --git a/clang-tools-extra/test/clang-tidy/Inputs/modernize-smart-ptr/unique_ptr.h b/clang-tools-extra/test/clang-tidy/Inputs/modernize-smart-ptr/unique_ptr.h new file mode 100644 index 0000000..4fc3da1 --- /dev/null +++ b/clang-tools-extra/test/clang-tidy/Inputs/modernize-smart-ptr/unique_ptr.h @@ -0,0 +1,28 @@ +namespace std { + +template <typename T> +class default_delete {}; + +template <typename type, typename Deleter = std::default_delete<type>> +class unique_ptr { +public: + unique_ptr(); + unique_ptr(type *ptr); + unique_ptr(const unique_ptr<type> &t) = delete; + unique_ptr(unique_ptr<type> &&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 <typename T> + unique_ptr &operator=(unique_ptr<T> &&); + +private: + type *ptr; +}; + +} // namespace std diff --git a/clang-tools-extra/test/clang-tidy/modernize-make-shared-header.cpp b/clang-tools-extra/test/clang-tidy/modernize-make-shared-header.cpp new file mode 100644 index 0000000..21b07ee --- /dev/null +++ b/clang-tools-extra/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<int> P1 = std::shared_ptr<int>(new int()); + // CHECK-MESSAGES: :[[@LINE-1]]:29: warning: use my::MakeShared instead + // CHECK-FIXES: std::shared_ptr<int> P1 = my::MakeShared<int>(); +} diff --git a/clang-tools-extra/test/clang-tidy/modernize-make-shared.cpp b/clang-tools-extra/test/clang-tidy/modernize-make-shared.cpp index 4f478419..ed4da99 100644 --- a/clang-tools-extra/test/clang-tidy/modernize-make-shared.cpp +++ b/clang-tools-extra/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 <typename type> -class shared_ptr { -public: - shared_ptr(); - shared_ptr(type *ptr); - shared_ptr(const shared_ptr<type> &t) {} - shared_ptr(shared_ptr<type> &&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 <typename T> - shared_ptr &operator=(shared_ptr<T> &&); - -private: - type *ptr; -}; -} +#include "shared_ptr.h" +// CHECK-FIXES: #include <memory> struct Base { Base(); diff --git a/clang-tools-extra/test/clang-tidy/modernize-make-unique-header.cpp b/clang-tools-extra/test/clang-tidy/modernize-make-unique-header.cpp new file mode 100644 index 0000000..e6c2a61 --- /dev/null +++ b/clang-tools-extra/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<int> P1 = std::unique_ptr<int>(new int()); + // CHECK-MESSAGES: :[[@LINE-1]]:29: warning: use my::MakeUnique instead + // CHECK-FIXES: std::unique_ptr<int> P1 = my::MakeUnique<int>(); +} diff --git a/clang-tools-extra/test/clang-tidy/modernize-make-unique.cpp b/clang-tools-extra/test/clang-tidy/modernize-make-unique.cpp index 4dfaed2..551f38d 100644 --- a/clang-tools-extra/test/clang-tidy/modernize-make-unique.cpp +++ b/clang-tools-extra/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 <typename T> -class default_delete {}; - -template <typename type, typename Deleter = std::default_delete<type>> -class unique_ptr { -public: - unique_ptr(); - unique_ptr(type *ptr); - unique_ptr(const unique_ptr<type> &t) = delete; - unique_ptr(unique_ptr<type> &&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 <typename T> - unique_ptr &operator=(unique_ptr<T> &&); - -private: - type *ptr; -}; -} +#include "unique_ptr.h" +// CHECK-FIXES: #include <memory> struct Base { Base(); |