forked from OSchip/llvm-project
[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
This commit is contained in:
parent
d19389a3c9
commit
040c0f96cc
|
@ -8,7 +8,9 @@
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
#include "MakeSharedCheck.h"
|
#include "MakeSharedCheck.h"
|
||||||
|
#include "clang/Frontend/CompilerInstance.h"
|
||||||
#include "clang/Lex/Lexer.h"
|
#include "clang/Lex/Lexer.h"
|
||||||
|
#include "clang/Lex/Preprocessor.h"
|
||||||
|
|
||||||
using namespace clang::ast_matchers;
|
using namespace clang::ast_matchers;
|
||||||
|
|
||||||
|
@ -17,6 +19,9 @@ namespace tidy {
|
||||||
namespace modernize {
|
namespace modernize {
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
|
constexpr char StdMemoryHeader[] = "memory";
|
||||||
|
|
||||||
std::string GetNewExprName(const CXXNewExpr *NewExpr,
|
std::string GetNewExprName(const CXXNewExpr *NewExpr,
|
||||||
const SourceManager &SM,
|
const SourceManager &SM,
|
||||||
const LangOptions &Lang) {
|
const LangOptions &Lang) {
|
||||||
|
@ -29,6 +34,7 @@ std::string GetNewExprName(const CXXNewExpr *NewExpr,
|
||||||
}
|
}
|
||||||
return WrittenName.str();
|
return WrittenName.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
const char MakeSmartPtrCheck::PointerType[] = "pointerType";
|
const char MakeSmartPtrCheck::PointerType[] = "pointerType";
|
||||||
|
@ -37,9 +43,28 @@ const char MakeSmartPtrCheck::ResetCall[] = "resetCall";
|
||||||
const char MakeSmartPtrCheck::NewExpression[] = "newExpression";
|
const char MakeSmartPtrCheck::NewExpression[] = "newExpression";
|
||||||
|
|
||||||
MakeSmartPtrCheck::MakeSmartPtrCheck(StringRef Name, ClangTidyContext *Context,
|
MakeSmartPtrCheck::MakeSmartPtrCheck(StringRef Name, ClangTidyContext *Context,
|
||||||
std::string makeSmartPtrFunctionName)
|
StringRef MakeSmartPtrFunctionName)
|
||||||
: ClangTidyCheck(Name, Context),
|
: 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) {
|
void MakeSmartPtrCheck::registerMatchers(ast_matchers::MatchFinder *Finder) {
|
||||||
if (!getLangOpts().CPlusPlus11)
|
if (!getLangOpts().CPlusPlus11)
|
||||||
|
@ -107,7 +132,7 @@ void MakeSmartPtrCheck::checkConstruct(SourceManager &SM,
|
||||||
return;
|
return;
|
||||||
|
|
||||||
auto Diag = diag(ConstructCallStart, "use %0 instead")
|
auto Diag = diag(ConstructCallStart, "use %0 instead")
|
||||||
<< makeSmartPtrFunctionName;
|
<< MakeSmartPtrFunctionName;
|
||||||
|
|
||||||
// Find the location of the template's left angle.
|
// Find the location of the template's left angle.
|
||||||
size_t LAngle = ExprStr.find("<");
|
size_t LAngle = ExprStr.find("<");
|
||||||
|
@ -125,7 +150,7 @@ void MakeSmartPtrCheck::checkConstruct(SourceManager &SM,
|
||||||
|
|
||||||
Diag << FixItHint::CreateReplacement(
|
Diag << FixItHint::CreateReplacement(
|
||||||
CharSourceRange::getCharRange(ConstructCallStart, ConstructCallEnd),
|
CharSourceRange::getCharRange(ConstructCallStart, ConstructCallEnd),
|
||||||
makeSmartPtrFunctionName);
|
MakeSmartPtrFunctionName);
|
||||||
|
|
||||||
// If the smart_ptr is built with brace enclosed direct initialization, use
|
// If the smart_ptr is built with brace enclosed direct initialization, use
|
||||||
// parenthesis instead.
|
// parenthesis instead.
|
||||||
|
@ -142,6 +167,7 @@ void MakeSmartPtrCheck::checkConstruct(SourceManager &SM,
|
||||||
}
|
}
|
||||||
|
|
||||||
replaceNew(Diag, New, SM);
|
replaceNew(Diag, New, SM);
|
||||||
|
insertHeader(Diag, SM.getFileID(ConstructCallStart));
|
||||||
}
|
}
|
||||||
|
|
||||||
void MakeSmartPtrCheck::checkReset(SourceManager &SM,
|
void MakeSmartPtrCheck::checkReset(SourceManager &SM,
|
||||||
|
@ -155,11 +181,11 @@ void MakeSmartPtrCheck::checkReset(SourceManager &SM,
|
||||||
Lexer::getLocForEndOfToken(Expr->getLocEnd(), 0, SM, getLangOpts());
|
Lexer::getLocForEndOfToken(Expr->getLocEnd(), 0, SM, getLangOpts());
|
||||||
|
|
||||||
auto Diag = diag(ResetCallStart, "use %0 instead")
|
auto Diag = diag(ResetCallStart, "use %0 instead")
|
||||||
<< makeSmartPtrFunctionName;
|
<< MakeSmartPtrFunctionName;
|
||||||
|
|
||||||
Diag << FixItHint::CreateReplacement(
|
Diag << FixItHint::CreateReplacement(
|
||||||
CharSourceRange::getCharRange(OperatorLoc, ExprEnd),
|
CharSourceRange::getCharRange(OperatorLoc, ExprEnd),
|
||||||
(llvm::Twine(" = ") + makeSmartPtrFunctionName + "<" +
|
(llvm::Twine(" = ") + MakeSmartPtrFunctionName + "<" +
|
||||||
GetNewExprName(New, SM, getLangOpts()) + ">")
|
GetNewExprName(New, SM, getLangOpts()) + ">")
|
||||||
.str());
|
.str());
|
||||||
|
|
||||||
|
@ -167,6 +193,7 @@ void MakeSmartPtrCheck::checkReset(SourceManager &SM,
|
||||||
Diag << FixItHint::CreateInsertion(ExprStart, "*");
|
Diag << FixItHint::CreateInsertion(ExprStart, "*");
|
||||||
|
|
||||||
replaceNew(Diag, New, SM);
|
replaceNew(Diag, New, SM);
|
||||||
|
insertHeader(Diag, SM.getFileID(OperatorLoc));
|
||||||
}
|
}
|
||||||
|
|
||||||
void MakeSmartPtrCheck::replaceNew(DiagnosticBuilder &Diag,
|
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 modernize
|
||||||
} // namespace tidy
|
} // namespace tidy
|
||||||
} // namespace clang
|
} // namespace clang
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MODERNIZE_MAKE_SMART_PTR_H
|
#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MODERNIZE_MAKE_SMART_PTR_H
|
||||||
|
|
||||||
#include "../ClangTidy.h"
|
#include "../ClangTidy.h"
|
||||||
|
#include "../utils/IncludeInserter.h"
|
||||||
#include "clang/ASTMatchers/ASTMatchFinder.h"
|
#include "clang/ASTMatchers/ASTMatchFinder.h"
|
||||||
#include "clang/ASTMatchers/ASTMatchersInternal.h"
|
#include "clang/ASTMatchers/ASTMatchersInternal.h"
|
||||||
#include "llvm/ADT/StringRef.h"
|
#include "llvm/ADT/StringRef.h"
|
||||||
|
@ -24,9 +25,11 @@ namespace modernize {
|
||||||
class MakeSmartPtrCheck : public ClangTidyCheck {
|
class MakeSmartPtrCheck : public ClangTidyCheck {
|
||||||
public:
|
public:
|
||||||
MakeSmartPtrCheck(StringRef Name, ClangTidyContext *Context,
|
MakeSmartPtrCheck(StringRef Name, ClangTidyContext *Context,
|
||||||
std::string makeSmartPtrFunctionName);
|
StringRef MakeSmartPtrFunctionName);
|
||||||
void registerMatchers(ast_matchers::MatchFinder *Finder) final;
|
void registerMatchers(ast_matchers::MatchFinder *Finder) final;
|
||||||
|
void registerPPCallbacks(clang::CompilerInstance &Compiler) override;
|
||||||
void check(const ast_matchers::MatchFinder::MatchResult &Result) final;
|
void check(const ast_matchers::MatchFinder::MatchResult &Result) final;
|
||||||
|
void storeOptions(ClangTidyOptions::OptionMap &Opts) override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
using SmartPtrTypeMatcher = ast_matchers::internal::BindableMatcher<QualType>;
|
using SmartPtrTypeMatcher = ast_matchers::internal::BindableMatcher<QualType>;
|
||||||
|
@ -43,14 +46,19 @@ protected:
|
||||||
static const char NewExpression[];
|
static const char NewExpression[];
|
||||||
|
|
||||||
private:
|
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,
|
void checkConstruct(SourceManager &SM, const CXXConstructExpr *Construct,
|
||||||
const QualType *Type, const CXXNewExpr *New);
|
const QualType *Type, const CXXNewExpr *New);
|
||||||
void checkReset(SourceManager &SM, const CXXMemberCallExpr *Member,
|
void checkReset(SourceManager &SM, const CXXMemberCallExpr *Member,
|
||||||
const CXXNewExpr *New);
|
const CXXNewExpr *New);
|
||||||
|
|
||||||
void replaceNew(DiagnosticBuilder &Diag, const CXXNewExpr *New,
|
void replaceNew(DiagnosticBuilder &Diag, const CXXNewExpr *New,
|
||||||
SourceManager &SM);
|
SourceManager &SM);
|
||||||
|
void insertHeader(DiagnosticBuilder &Diag, FileID FD);
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace modernize
|
} // namespace modernize
|
||||||
|
|
|
@ -25,3 +25,21 @@ expression, and replaces it with a call to ``std::make_shared``.
|
||||||
// becomes
|
// becomes
|
||||||
|
|
||||||
my_ptr = std::make_shared<MyPair>(1, 2);
|
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`.
|
||||||
|
|
|
@ -25,3 +25,21 @@ expression, and replaces it with a call to ``std::make_unique``.
|
||||||
// becomes
|
// becomes
|
||||||
|
|
||||||
my_ptr = std::make_unique<MyPair>(1, 2);
|
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`.
|
||||||
|
|
|
@ -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
|
|
@ -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
|
|
@ -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>();
|
||||||
|
}
|
|
@ -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 {
|
#include "shared_ptr.h"
|
||||||
|
// CHECK-FIXES: #include <memory>
|
||||||
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;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
struct Base {
|
struct Base {
|
||||||
Base();
|
Base();
|
||||||
|
|
|
@ -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>();
|
||||||
|
}
|
|
@ -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 {
|
#include "unique_ptr.h"
|
||||||
|
// CHECK-FIXES: #include <memory>
|
||||||
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;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
struct Base {
|
struct Base {
|
||||||
Base();
|
Base();
|
||||||
|
|
Loading…
Reference in New Issue