[clang-tools-extra] r268253 - [clang-tidy] Add modernize-make-shared check

Piotr Padlewski via cfe-commits cfe-commits at lists.llvm.org
Mon May 2 09:56:39 PDT 2016


Author: prazek
Date: Mon May  2 11:56:39 2016
New Revision: 268253

URL: http://llvm.org/viewvc/llvm-project?rev=268253&view=rev
Log:
[clang-tidy] Add modernize-make-shared check

Because modernize-make-shared do almost the same job as
modernize-make-unique, I refactored common code to MakeSmartPtrCheck.

http://reviews.llvm.org/D19183

Added:
    clang-tools-extra/trunk/clang-tidy/modernize/MakeSharedCheck.cpp
    clang-tools-extra/trunk/clang-tidy/modernize/MakeSharedCheck.h
    clang-tools-extra/trunk/clang-tidy/modernize/MakeSmartPtrCheck.cpp
      - copied, changed from r268140, clang-tools-extra/trunk/clang-tidy/modernize/MakeUniqueCheck.cpp
    clang-tools-extra/trunk/clang-tidy/modernize/MakeSmartPtrCheck.h
    clang-tools-extra/trunk/docs/clang-tidy/checks/modernize-make-shared.rst
    clang-tools-extra/trunk/test/clang-tidy/modernize-make-shared.cpp
Modified:
    clang-tools-extra/trunk/clang-tidy/modernize/CMakeLists.txt
    clang-tools-extra/trunk/clang-tidy/modernize/MakeUniqueCheck.cpp
    clang-tools-extra/trunk/clang-tidy/modernize/MakeUniqueCheck.h
    clang-tools-extra/trunk/clang-tidy/modernize/ModernizeTidyModule.cpp
    clang-tools-extra/trunk/docs/ReleaseNotes.rst
    clang-tools-extra/trunk/docs/clang-tidy/checks/list.rst

Modified: clang-tools-extra/trunk/clang-tidy/modernize/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/modernize/CMakeLists.txt?rev=268253&r1=268252&r2=268253&view=diff
==============================================================================
--- clang-tools-extra/trunk/clang-tidy/modernize/CMakeLists.txt (original)
+++ clang-tools-extra/trunk/clang-tidy/modernize/CMakeLists.txt Mon May  2 11:56:39 2016
@@ -4,6 +4,8 @@ add_clang_library(clangTidyModernizeModu
   DeprecatedHeadersCheck.cpp
   LoopConvertCheck.cpp
   LoopConvertUtils.cpp
+  MakeSmartPtrCheck.cpp
+  MakeSharedCheck.cpp
   MakeUniqueCheck.cpp
   ModernizeTidyModule.cpp
   PassByValueCheck.cpp

Added: clang-tools-extra/trunk/clang-tidy/modernize/MakeSharedCheck.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/modernize/MakeSharedCheck.cpp?rev=268253&view=auto
==============================================================================
--- clang-tools-extra/trunk/clang-tidy/modernize/MakeSharedCheck.cpp (added)
+++ clang-tools-extra/trunk/clang-tidy/modernize/MakeSharedCheck.cpp Mon May  2 11:56:39 2016
@@ -0,0 +1,31 @@
+//===--- MakeSharedCheck.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 "MakeSharedCheck.h"
+
+using namespace clang::ast_matchers;
+
+namespace clang {
+namespace tidy {
+namespace modernize {
+
+MakeSharedCheck::MakeSharedCheck(StringRef Name, ClangTidyContext *Context)
+    : MakeSmartPtrCheck(Name, Context, "std::make_shared") {}
+
+MakeSharedCheck::SmartPtrTypeMatcher
+MakeSharedCheck::getSmartPointerTypeMatcher() const {
+  return qualType(hasDeclaration(classTemplateSpecializationDecl(
+      matchesName("::std::shared_ptr"), templateArgumentCountIs(1),
+      hasTemplateArgument(
+          0, templateArgument(refersToType(qualType().bind(PointerType)))))));
+}
+
+} // namespace modernize
+} // namespace tidy
+} // namespace clang

Added: clang-tools-extra/trunk/clang-tidy/modernize/MakeSharedCheck.h
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/modernize/MakeSharedCheck.h?rev=268253&view=auto
==============================================================================
--- clang-tools-extra/trunk/clang-tidy/modernize/MakeSharedCheck.h (added)
+++ clang-tools-extra/trunk/clang-tidy/modernize/MakeSharedCheck.h Mon May  2 11:56:39 2016
@@ -0,0 +1,43 @@
+//===--- MakeSharedCheck.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_MODERNIZE_MAKE_SHARED_H
+#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MODERNIZE_MAKE_SHARED_H
+
+#include "MakeSmartPtrCheck.h"
+
+namespace clang {
+namespace tidy {
+namespace modernize {
+
+/// Replace the pattern:
+/// \code
+///   std::shared_ptr<type>(new type(args...))
+/// \endcode
+///
+/// With the safer version:
+/// \code
+///   std::make_shared<type>(args...)
+/// \endcode
+///
+/// For the user-facing documentation see:
+/// http://clang.llvm.org/extra/clang-tidy/checks/modernize-make-shared.html
+class MakeSharedCheck : public MakeSmartPtrCheck {
+public:
+  MakeSharedCheck(StringRef Name, ClangTidyContext *Context);
+
+protected:
+  SmartPtrTypeMatcher getSmartPointerTypeMatcher() const override;
+};
+
+} // namespace modernize
+} // namespace tidy
+} // namespace clang
+
+#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MODERNIZE_MAKE_SHARED_H

Copied: clang-tools-extra/trunk/clang-tidy/modernize/MakeSmartPtrCheck.cpp (from r268140, clang-tools-extra/trunk/clang-tidy/modernize/MakeUniqueCheck.cpp)
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/modernize/MakeSmartPtrCheck.cpp?p2=clang-tools-extra/trunk/clang-tidy/modernize/MakeSmartPtrCheck.cpp&p1=clang-tools-extra/trunk/clang-tidy/modernize/MakeUniqueCheck.cpp&r1=268140&r2=268253&rev=268253&view=diff
==============================================================================
--- clang-tools-extra/trunk/clang-tidy/modernize/MakeUniqueCheck.cpp (original)
+++ clang-tools-extra/trunk/clang-tidy/modernize/MakeSmartPtrCheck.cpp Mon May  2 11:56:39 2016
@@ -1,4 +1,4 @@
-//===--- MakeUniqueCheck.cpp - clang-tidy----------------------------------===//
+//===--- MakeSmartPtrCheck.cpp - clang-tidy--------------------------------===//
 //
 //                     The LLVM Compiler Infrastructure
 //
@@ -7,9 +7,7 @@
 //
 //===----------------------------------------------------------------------===//
 
-#include "MakeUniqueCheck.h"
-#include "clang/AST/ASTContext.h"
-#include "clang/ASTMatchers/ASTMatchFinder.h"
+#include "MakeSharedCheck.h"
 #include "clang/Lex/Lexer.h"
 
 using namespace clang::ast_matchers;
@@ -18,40 +16,36 @@ namespace clang {
 namespace tidy {
 namespace modernize {
 
-static const char PointerType[] = "pointerType";
-static const char ConstructorCall[] = "constructorCall";
-static const char NewExpression[] = "newExpression";
-
-void MakeUniqueCheck::registerMatchers(MatchFinder *Finder) {
-  if (getLangOpts().CPlusPlus11) {
-    Finder->addMatcher(
-        cxxBindTemporaryExpr(has(
-            cxxConstructExpr(
-                hasType(qualType(hasDeclaration(classTemplateSpecializationDecl(
-                    matchesName("::std::unique_ptr"),
-                    templateArgumentCountIs(2),
-                    hasTemplateArgument(0, templateArgument(refersToType(
-                                               qualType().bind(PointerType)))),
-                    hasTemplateArgument(
-                        1, templateArgument(refersToType(qualType(
-                               hasDeclaration(classTemplateSpecializationDecl(
-                                   matchesName("::std::default_delete"),
-                                   templateArgumentCountIs(1),
-                                   hasTemplateArgument(
-                                       0, templateArgument(refersToType(
-                                              qualType(equalsBoundNode(
-                                                  PointerType))))))))))))))),
-                argumentCountIs(1),
-                hasArgument(
-                    0, cxxNewExpr(hasType(pointsTo(qualType(hasCanonicalType(
-                                      equalsBoundNode(PointerType))))))
-                           .bind(NewExpression)))
-                .bind(ConstructorCall))),
-        this);
-  }
+const char MakeSmartPtrCheck::PointerType[] = "pointerType";
+const char MakeSmartPtrCheck::ConstructorCall[] = "constructorCall";
+const char MakeSmartPtrCheck::NewExpression[] = "newExpression";
+
+MakeSmartPtrCheck::MakeSmartPtrCheck(StringRef Name, ClangTidyContext *Context,
+                                     std::string makeSmartPtrFunctionName)
+    : ClangTidyCheck(Name, Context),
+      makeSmartPtrFunctionName(std::move(makeSmartPtrFunctionName)) {}
+
+void MakeSmartPtrCheck::registerMatchers(ast_matchers::MatchFinder *Finder) {
+  if (!getLangOpts().CPlusPlus11)
+    return;
+
+  Finder->addMatcher(
+      cxxBindTemporaryExpr(
+          has(cxxConstructExpr(
+                  hasType(getSmartPointerTypeMatcher()), argumentCountIs(1),
+                  hasArgument(
+                      0, cxxNewExpr(hasType(pointsTo(qualType(hasCanonicalType(
+                                        equalsBoundNode(PointerType))))))
+                             .bind(NewExpression)))
+                  .bind(ConstructorCall))),
+      this);
 }
 
-void MakeUniqueCheck::check(const MatchFinder::MatchResult &Result) {
+void MakeSmartPtrCheck::check(const MatchFinder::MatchResult &Result) {
+  // 'smart_ptr' refers to 'std::shared_ptr' or 'std::unique_ptr' or other
+  // pointer, 'make_smart_ptr' refers to 'std::make_shared' or
+  // 'std::make_unique' or other function that creates smart_ptr.
+
   SourceManager &SM = *Result.SourceManager;
   const auto *Construct =
       Result.Nodes.getNodeAs<CXXConstructExpr>(ConstructorCall);
@@ -71,7 +65,8 @@ void MakeUniqueCheck::check(const MatchF
   if (Invalid)
     return;
 
-  auto Diag = diag(ConstructCallStart, "use std::make_unique instead");
+  auto Diag = diag(ConstructCallStart, "use %0 instead")
+              << makeSmartPtrFunctionName;
 
   // Find the location of the template's left angle.
   size_t LAngle = ExprStr.find("<");
@@ -88,9 +83,9 @@ void MakeUniqueCheck::check(const MatchF
 
   Diag << FixItHint::CreateReplacement(
       CharSourceRange::getCharRange(ConstructCallStart, ConstructCallEnd),
-      "std::make_unique");
+      makeSmartPtrFunctionName);
 
-  // If the unique_ptr is built with brace enclosed direct initialization, use
+  // If the smart_ptr is built with brace enclosed direct initialization, use
   // parenthesis instead.
   if (Construct->isListInitialization()) {
     SourceRange BraceRange = Construct->getParenOrBraceRange();
@@ -124,19 +119,19 @@ void MakeUniqueCheck::check(const MatchF
     if (const auto *NewConstruct = New->getConstructExpr()) {
       // Direct initialization with initialization list.
       //   struct S { S(int x) {} };
-      //   std::unique_ptr<S>(new S{5});
+      //   smart_ptr<S>(new S{5});
       // The arguments in the initialization list are going to be forwarded to
       // the constructor, so this has to be replaced with:
       //   struct S { S(int x) {} };
-      //   std::make_unique<S>(5);
+      //   std::make_smart_ptr<S>(5);
       InitRange = SourceRange(
           NewConstruct->getParenOrBraceRange().getBegin().getLocWithOffset(1),
           NewConstruct->getParenOrBraceRange().getEnd().getLocWithOffset(-1));
     } else {
       // Aggregate initialization.
-      //   std::unique_ptr<Pair>(new Pair{first, second});
+      //   smart_ptr<Pair>(new Pair{first, second});
       // Has to be replaced with:
-      //   std::make_unique<Pair>(Pair{first, second});
+      //   smart_ptr<Pair>(Pair{first, second});
       InitRange = SourceRange(
           New->getAllocatedTypeSourceInfo()->getTypeLoc().getLocStart(),
           New->getInitializer()->getSourceRange().getEnd());

Added: clang-tools-extra/trunk/clang-tidy/modernize/MakeSmartPtrCheck.h
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/modernize/MakeSmartPtrCheck.h?rev=268253&view=auto
==============================================================================
--- clang-tools-extra/trunk/clang-tidy/modernize/MakeSmartPtrCheck.h (added)
+++ clang-tools-extra/trunk/clang-tidy/modernize/MakeSmartPtrCheck.h Mon May  2 11:56:39 2016
@@ -0,0 +1,50 @@
+//===--- MakeSmartPtrCheck.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_MODERNIZE_MAKE_SMART_PTR_H
+#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MODERNIZE_MAKE_SMART_PTR_H
+
+#include "../ClangTidy.h"
+#include <string>
+
+namespace clang {
+namespace tidy {
+namespace modernize {
+
+/// Base class for MakeSharedCheck and MakeUniqueCheck.
+class MakeSmartPtrCheck : public ClangTidyCheck {
+public:
+  MakeSmartPtrCheck(StringRef Name, ClangTidyContext *Context,
+                    std::string makeSmartPtrFunctionName);
+  void registerMatchers(ast_matchers::MatchFinder *Finder) override final;
+  void
+  check(const ast_matchers::MatchFinder::MatchResult &Result) override final;
+
+protected:
+  using SmartPtrTypeMatcher = ast_matchers::internal::BindableMatcher<QualType>;
+
+  /// Returns matcher that match with different smart pointer types.
+  ///
+  /// Requires to bind pointer type (qualType) with PointerType string declared
+  /// in this class.
+  virtual SmartPtrTypeMatcher getSmartPointerTypeMatcher() const = 0;
+
+  static const char PointerType[];
+  static const char ConstructorCall[];
+  static const char NewExpression[];
+
+private:
+  std::string makeSmartPtrFunctionName;
+};
+
+} // namespace modernize
+} // namespace tidy
+} // namespace clang
+
+#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MODERNIZE_MAKE_SMART_PTR_H

Modified: clang-tools-extra/trunk/clang-tidy/modernize/MakeUniqueCheck.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/modernize/MakeUniqueCheck.cpp?rev=268253&r1=268252&r2=268253&view=diff
==============================================================================
--- clang-tools-extra/trunk/clang-tidy/modernize/MakeUniqueCheck.cpp (original)
+++ clang-tools-extra/trunk/clang-tidy/modernize/MakeUniqueCheck.cpp Mon May  2 11:56:39 2016
@@ -8,9 +8,6 @@
 //===----------------------------------------------------------------------===//
 
 #include "MakeUniqueCheck.h"
-#include "clang/AST/ASTContext.h"
-#include "clang/ASTMatchers/ASTMatchFinder.h"
-#include "clang/Lex/Lexer.h"
 
 using namespace clang::ast_matchers;
 
@@ -18,136 +15,24 @@ namespace clang {
 namespace tidy {
 namespace modernize {
 
-static const char PointerType[] = "pointerType";
-static const char ConstructorCall[] = "constructorCall";
-static const char NewExpression[] = "newExpression";
-
-void MakeUniqueCheck::registerMatchers(MatchFinder *Finder) {
-  if (getLangOpts().CPlusPlus11) {
-    Finder->addMatcher(
-        cxxBindTemporaryExpr(has(
-            cxxConstructExpr(
-                hasType(qualType(hasDeclaration(classTemplateSpecializationDecl(
-                    matchesName("::std::unique_ptr"),
-                    templateArgumentCountIs(2),
-                    hasTemplateArgument(0, templateArgument(refersToType(
-                                               qualType().bind(PointerType)))),
-                    hasTemplateArgument(
-                        1, templateArgument(refersToType(qualType(
-                               hasDeclaration(classTemplateSpecializationDecl(
-                                   matchesName("::std::default_delete"),
-                                   templateArgumentCountIs(1),
-                                   hasTemplateArgument(
-                                       0, templateArgument(refersToType(
-                                              qualType(equalsBoundNode(
-                                                  PointerType))))))))))))))),
-                argumentCountIs(1),
-                hasArgument(
-                    0, cxxNewExpr(hasType(pointsTo(qualType(hasCanonicalType(
-                                      equalsBoundNode(PointerType))))))
-                           .bind(NewExpression)))
-                .bind(ConstructorCall))),
-        this);
-  }
-}
-
-void MakeUniqueCheck::check(const MatchFinder::MatchResult &Result) {
-  SourceManager &SM = *Result.SourceManager;
-  const auto *Construct =
-      Result.Nodes.getNodeAs<CXXConstructExpr>(ConstructorCall);
-  const auto *Type = Result.Nodes.getNodeAs<QualType>(PointerType);
-  const auto *New = Result.Nodes.getNodeAs<CXXNewExpr>(NewExpression);
-
-  if (New->getNumPlacementArgs() != 0)
-    return;
-
-  SourceLocation ConstructCallStart = Construct->getExprLoc();
-
-  bool Invalid = false;
-  StringRef ExprStr = Lexer::getSourceText(
-      CharSourceRange::getCharRange(
-          ConstructCallStart, Construct->getParenOrBraceRange().getBegin()),
-      SM, LangOptions(), &Invalid);
-  if (Invalid)
-    return;
-
-  auto Diag = diag(ConstructCallStart, "use std::make_unique instead");
-
-  // Find the location of the template's left angle.
-  size_t LAngle = ExprStr.find("<");
-  SourceLocation ConstructCallEnd;
-  if (LAngle == StringRef::npos) {
-    // If the template argument is missing (because it is part of the alias)
-    // we have to add it back.
-    ConstructCallEnd = ConstructCallStart.getLocWithOffset(ExprStr.size());
-    Diag << FixItHint::CreateInsertion(
-        ConstructCallEnd, "<" + Type->getAsString(getLangOpts()) + ">");
-  } else {
-    ConstructCallEnd = ConstructCallStart.getLocWithOffset(LAngle);
-  }
-
-  Diag << FixItHint::CreateReplacement(
-      CharSourceRange::getCharRange(ConstructCallStart, ConstructCallEnd),
-      "std::make_unique");
-
-  // If the unique_ptr is built with brace enclosed direct initialization, use
-  // parenthesis instead.
-  if (Construct->isListInitialization()) {
-    SourceRange BraceRange = Construct->getParenOrBraceRange();
-    Diag << FixItHint::CreateReplacement(
-        CharSourceRange::getCharRange(
-            BraceRange.getBegin(), BraceRange.getBegin().getLocWithOffset(1)),
-        "(");
-    Diag << FixItHint::CreateReplacement(
-        CharSourceRange::getCharRange(BraceRange.getEnd(),
-                                      BraceRange.getEnd().getLocWithOffset(1)),
-        ")");
-  }
-
-  SourceLocation NewStart = New->getSourceRange().getBegin();
-  SourceLocation NewEnd = New->getSourceRange().getEnd();
-  switch (New->getInitializationStyle()) {
-  case CXXNewExpr::NoInit: {
-    Diag << FixItHint::CreateRemoval(SourceRange(NewStart, NewEnd));
-    break;
-  }
-  case CXXNewExpr::CallInit: {
-    SourceRange InitRange = New->getDirectInitRange();
-    Diag << FixItHint::CreateRemoval(
-        SourceRange(NewStart, InitRange.getBegin()));
-    Diag << FixItHint::CreateRemoval(SourceRange(InitRange.getEnd(), NewEnd));
-    break;
-  }
-  case CXXNewExpr::ListInit: {
-    // Range of the substring that we do not want to remove.
-    SourceRange InitRange;
-    if (const auto *NewConstruct = New->getConstructExpr()) {
-      // Direct initialization with initialization list.
-      //   struct S { S(int x) {} };
-      //   std::unique_ptr<S>(new S{5});
-      // The arguments in the initialization list are going to be forwarded to
-      // the constructor, so this has to be replaced with:
-      //   struct S { S(int x) {} };
-      //   std::make_unique<S>(5);
-      InitRange = SourceRange(
-          NewConstruct->getParenOrBraceRange().getBegin().getLocWithOffset(1),
-          NewConstruct->getParenOrBraceRange().getEnd().getLocWithOffset(-1));
-    } else {
-      // Aggregate initialization.
-      //   std::unique_ptr<Pair>(new Pair{first, second});
-      // Has to be replaced with:
-      //   std::make_unique<Pair>(Pair{first, second});
-      InitRange = SourceRange(
-          New->getAllocatedTypeSourceInfo()->getTypeLoc().getLocStart(),
-          New->getInitializer()->getSourceRange().getEnd());
-    }
-    Diag << FixItHint::CreateRemoval(
-        CharSourceRange::getCharRange(NewStart, InitRange.getBegin()));
-    Diag << FixItHint::CreateRemoval(
-        SourceRange(InitRange.getEnd().getLocWithOffset(1), NewEnd));
-    break;
-  }
-  }
+MakeUniqueCheck::MakeUniqueCheck(StringRef Name,
+                                 clang::tidy::ClangTidyContext *Context)
+    : MakeSmartPtrCheck(Name, Context, "std::make_unique") {}
+
+MakeUniqueCheck::SmartPtrTypeMatcher
+MakeUniqueCheck::getSmartPointerTypeMatcher() const {
+  return qualType(hasDeclaration(classTemplateSpecializationDecl(
+      matchesName("::std::unique_ptr"), templateArgumentCountIs(2),
+      hasTemplateArgument(
+          0, templateArgument(refersToType(qualType().bind(PointerType)))),
+      hasTemplateArgument(
+          1, templateArgument(refersToType(
+                 qualType(hasDeclaration(classTemplateSpecializationDecl(
+                     matchesName("::std::default_delete"),
+                     templateArgumentCountIs(1),
+                     hasTemplateArgument(
+                         0, templateArgument(refersToType(qualType(
+                                equalsBoundNode(PointerType))))))))))))));
 }
 
 } // namespace modernize

Modified: clang-tools-extra/trunk/clang-tidy/modernize/MakeUniqueCheck.h
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/modernize/MakeUniqueCheck.h?rev=268253&r1=268252&r2=268253&view=diff
==============================================================================
--- clang-tools-extra/trunk/clang-tidy/modernize/MakeUniqueCheck.h (original)
+++ clang-tools-extra/trunk/clang-tidy/modernize/MakeUniqueCheck.h Mon May  2 11:56:39 2016
@@ -10,7 +10,7 @@
 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MODERNIZE_MAKE_UNIQUE_H
 #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MODERNIZE_MAKE_UNIQUE_H
 
-#include "../ClangTidy.h"
+#include "MakeSmartPtrCheck.h"
 
 namespace clang {
 namespace tidy {
@@ -25,12 +25,12 @@ namespace modernize {
 /// \code
 ///   std::make_unique<type>(args...)
 /// \endcode
-class MakeUniqueCheck : public ClangTidyCheck {
+class MakeUniqueCheck : public MakeSmartPtrCheck {
 public:
-  MakeUniqueCheck(StringRef Name, ClangTidyContext *Context)
-      : ClangTidyCheck(Name, Context) {}
-  void registerMatchers(ast_matchers::MatchFinder *Finder) override;
-  void check(const ast_matchers::MatchFinder::MatchResult &Result) override;
+  MakeUniqueCheck(StringRef Name, ClangTidyContext *Context);
+
+protected:
+  SmartPtrTypeMatcher getSmartPointerTypeMatcher() const override;
 };
 
 } // namespace modernize

Modified: clang-tools-extra/trunk/clang-tidy/modernize/ModernizeTidyModule.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/modernize/ModernizeTidyModule.cpp?rev=268253&r1=268252&r2=268253&view=diff
==============================================================================
--- clang-tools-extra/trunk/clang-tidy/modernize/ModernizeTidyModule.cpp (original)
+++ clang-tools-extra/trunk/clang-tidy/modernize/ModernizeTidyModule.cpp Mon May  2 11:56:39 2016
@@ -12,6 +12,7 @@
 #include "../ClangTidyModuleRegistry.h"
 #include "DeprecatedHeadersCheck.h"
 #include "LoopConvertCheck.h"
+#include "MakeSharedCheck.h"
 #include "MakeUniqueCheck.h"
 #include "PassByValueCheck.h"
 #include "RawStringLiteralCheck.h"
@@ -35,6 +36,7 @@ public:
     CheckFactories.registerCheck<DeprecatedHeadersCheck>(
         "modernize-deprecated-headers");
     CheckFactories.registerCheck<LoopConvertCheck>("modernize-loop-convert");
+    CheckFactories.registerCheck<MakeSharedCheck>("modernize-make-shared");
     CheckFactories.registerCheck<MakeUniqueCheck>("modernize-make-unique");
     CheckFactories.registerCheck<PassByValueCheck>("modernize-pass-by-value");
     CheckFactories.registerCheck<RawStringLiteralCheck>(

Modified: clang-tools-extra/trunk/docs/ReleaseNotes.rst
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/docs/ReleaseNotes.rst?rev=268253&r1=268252&r2=268253&view=diff
==============================================================================
--- clang-tools-extra/trunk/docs/ReleaseNotes.rst (original)
+++ clang-tools-extra/trunk/docs/ReleaseNotes.rst Mon May  2 11:56:39 2016
@@ -180,6 +180,11 @@ identified.  The improvements since the
 
   Replaces C standard library headers with their C++ alternatives.
 
+- New `modernize-make-shared
+  <http://clang.llvm.org/extra/clang-tidy/checks/modernize-make-shared.html>`_ check
+
+  Replaces creation of ``std::shared_ptr`` from new expression with call to ``std::make_shared``.
+
 - New `modernize-raw-string-literal
   <http://clang.llvm.org/extra/clang-tidy/checks/modernize-raw-string-literal.html>`_ check
 

Modified: clang-tools-extra/trunk/docs/clang-tidy/checks/list.rst
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/docs/clang-tidy/checks/list.rst?rev=268253&r1=268252&r2=268253&view=diff
==============================================================================
--- clang-tools-extra/trunk/docs/clang-tidy/checks/list.rst (original)
+++ clang-tools-extra/trunk/docs/clang-tidy/checks/list.rst Mon May  2 11:56:39 2016
@@ -92,6 +92,7 @@ Clang-Tidy Checks
    misc-virtual-near-miss
    modernize-deprecated-headers
    modernize-loop-convert
+   modernize-make-shared
    modernize-make-unique
    modernize-pass-by-value
    modernize-raw-string-literal

Added: clang-tools-extra/trunk/docs/clang-tidy/checks/modernize-make-shared.rst
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/docs/clang-tidy/checks/modernize-make-shared.rst?rev=268253&view=auto
==============================================================================
--- clang-tools-extra/trunk/docs/clang-tidy/checks/modernize-make-shared.rst (added)
+++ clang-tools-extra/trunk/docs/clang-tidy/checks/modernize-make-shared.rst Mon May  2 11:56:39 2016
@@ -0,0 +1,16 @@
+.. title:: clang-tidy - modernize-make-shared
+
+modernize-make-shared
+=====================
+
+This check finds the creation of ``std::shared_ptr`` objects by explicitly
+calling the constructor and a ``new`` expression, and replaces it with a call
+to ``std::make_shared``.
+
+.. code-block:: c++
+
+  auto my_ptr = std::shared_ptr<MyPair>(new MyPair(1, 2));
+
+  // becomes
+
+  auto my_ptr = std::make_shared<MyPair>(1, 2);

Added: clang-tools-extra/trunk/test/clang-tidy/modernize-make-shared.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/modernize-make-shared.cpp?rev=268253&view=auto
==============================================================================
--- clang-tools-extra/trunk/test/clang-tidy/modernize-make-shared.cpp (added)
+++ clang-tools-extra/trunk/test/clang-tidy/modernize-make-shared.cpp Mon May  2 11:56:39 2016
@@ -0,0 +1,200 @@
+// RUN: %check_clang_tidy %s modernize-make-shared %t
+
+namespace std {
+
+template <typename type>
+class shared_ptr {
+public:
+  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);
+
+private:
+  type *ptr;
+};
+}
+
+struct Base {
+  Base();
+  Base(int, int);
+};
+
+struct Derived : public Base {
+  Derived();
+  Derived(int, int);
+};
+
+struct APair {
+  int a, b;
+};
+
+struct DPair {
+  DPair() : a(0), b(0) {}
+  DPair(int x, int y) : a(y), b(x) {}
+  int a, b;
+};
+
+struct Empty {};
+
+template <class T>
+using shared_ptr_ = std::shared_ptr<T>;
+
+void *operator new(__SIZE_TYPE__ Count, void *Ptr);
+
+int g(std::shared_ptr<int> P);
+
+std::shared_ptr<Base> getPointer() {
+  return std::shared_ptr<Base>(new Base);
+  // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: use std::make_shared instead
+  // CHECK-FIXES: return std::make_shared<Base>();
+}
+
+void basic() {
+  std::shared_ptr<int> P1 = std::shared_ptr<int>(new int());
+  // CHECK-MESSAGES: :[[@LINE-1]]:29: warning: use std::make_shared instead [modernize-make-shared]
+  // CHECK-FIXES: std::shared_ptr<int> P1 = std::make_shared<int>();
+
+  // Without parenthesis.
+  std::shared_ptr<int> P2 = std::shared_ptr<int>(new int);
+  // CHECK-MESSAGES: :[[@LINE-1]]:29: warning: use std::make_shared instead [modernize-make-shared]
+  // CHECK-FIXES: std::shared_ptr<int> P2 = std::make_shared<int>();
+
+  // With auto.
+  auto P3 = std::shared_ptr<int>(new int());
+  // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: use std::make_shared instead
+  // CHECK-FIXES: auto P3 = std::make_shared<int>();
+
+  {
+    // No std.
+    using namespace std;
+    shared_ptr<int> Q = shared_ptr<int>(new int());
+    // CHECK-MESSAGES: :[[@LINE-1]]:25: warning: use std::make_shared instead
+    // CHECK-FIXES: shared_ptr<int> Q = std::make_shared<int>();
+  }
+
+  std::shared_ptr<int> R(new int());
+
+  // Create the shared_ptr as a parameter to a function.
+  int T = g(std::shared_ptr<int>(new int()));
+  // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: use std::make_shared instead
+  // CHECK-FIXES: int T = g(std::make_shared<int>());
+
+  // Only replace if the type in the template is the same than the type returned
+  // by the new operator.
+  auto Pderived = std::shared_ptr<Base>(new Derived());
+
+  // The pointer is returned by the function, nothing to do.
+  std::shared_ptr<Base> RetPtr = getPointer();
+
+  // This emulates std::move.
+  std::shared_ptr<int> Move = static_cast<std::shared_ptr<int> &&>(P1);
+
+  // Placemenet arguments should not be removed.
+  int *PInt = new int;
+  std::shared_ptr<int> Placement = std::shared_ptr<int>(new (PInt) int{3});
+}
+
+void initialization(int T, Base b) {
+  // Test different kinds of initialization of the pointee.
+
+  // Direct initialization with parenthesis.
+  std::shared_ptr<DPair> PDir1 = std::shared_ptr<DPair>(new DPair(1, T));
+  // CHECK-MESSAGES: :[[@LINE-1]]:34: warning: use std::make_shared instead
+  // CHECK-FIXES: std::shared_ptr<DPair> PDir1 = std::make_shared<DPair>(1, T);
+
+  // Direct initialization with braces.
+  std::shared_ptr<DPair> PDir2 = std::shared_ptr<DPair>(new DPair{2, T});
+  // CHECK-MESSAGES: :[[@LINE-1]]:34: warning: use std::make_shared instead
+  // CHECK-FIXES: std::shared_ptr<DPair> PDir2 = std::make_shared<DPair>(2, T);
+
+  // Aggregate initialization.
+  std::shared_ptr<APair> PAggr = std::shared_ptr<APair>(new APair{T, 1});
+  // CHECK-MESSAGES: :[[@LINE-1]]:34: warning: use std::make_shared instead
+  // CHECK-FIXES: std::shared_ptr<APair> PAggr = std::make_shared<APair>(APair{T, 1});
+
+  // Test different kinds of initialization of the pointee, when the shared_ptr
+  // is initialized with braces.
+
+  // Direct initialization with parenthesis.
+  std::shared_ptr<DPair> PDir3 = std::shared_ptr<DPair>{new DPair(3, T)};
+  // CHECK-MESSAGES: :[[@LINE-1]]:34: warning: use std::make_shared instead
+  // CHECK-FIXES: std::shared_ptr<DPair> PDir3 = std::make_shared<DPair>(3, T);
+
+  // Direct initialization with braces.
+  std::shared_ptr<DPair> PDir4 = std::shared_ptr<DPair>{new DPair{4, T}};
+  // CHECK-MESSAGES: :[[@LINE-1]]:34: warning: use std::make_shared instead
+  // CHECK-FIXES: std::shared_ptr<DPair> PDir4 = std::make_shared<DPair>(4, T);
+
+  // Aggregate initialization.
+  std::shared_ptr<APair> PAggr2 = std::shared_ptr<APair>{new APair{T, 2}};
+  // CHECK-MESSAGES: :[[@LINE-1]]:35: warning: use std::make_shared instead
+  // CHECK-FIXES: std::shared_ptr<APair> PAggr2 = std::make_shared<APair>(APair{T, 2});
+
+  // Direct initialization with parenthesis, without arguments.
+  std::shared_ptr<DPair> PDir5 = std::shared_ptr<DPair>(new DPair());
+  // CHECK-MESSAGES: :[[@LINE-1]]:34: warning: use std::make_shared instead
+  // CHECK-FIXES: std::shared_ptr<DPair> PDir5 = std::make_shared<DPair>();
+
+  // Direct initialization with braces, without arguments.
+  std::shared_ptr<DPair> PDir6 = std::shared_ptr<DPair>(new DPair{});
+  // CHECK-MESSAGES: :[[@LINE-1]]:34: warning: use std::make_shared instead
+  // CHECK-FIXES: std::shared_ptr<DPair> PDir6 = std::make_shared<DPair>();
+
+  // Aggregate initialization without arguments.
+  std::shared_ptr<Empty> PEmpty = std::shared_ptr<Empty>(new Empty{});
+  // CHECK-MESSAGES: :[[@LINE-1]]:35: warning: use std::make_shared instead
+  // CHECK-FIXES: std::shared_ptr<Empty> PEmpty = std::make_shared<Empty>(Empty{});
+}
+
+void aliases() {
+  typedef std::shared_ptr<int> IntPtr;
+  IntPtr Typedef = IntPtr(new int);
+  // CHECK-MESSAGES: :[[@LINE-1]]:20: warning: use std::make_shared instead
+  // CHECK-FIXES: IntPtr Typedef = std::make_shared<int>();
+
+  // We use 'bool' instead of '_Bool'.
+  typedef std::shared_ptr<bool> BoolPtr;
+  BoolPtr BoolType = BoolPtr(new bool);
+  // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: use std::make_shared instead
+  // CHECK-FIXES: BoolPtr BoolType = std::make_shared<bool>();
+
+  // We use 'Base' instead of 'struct Base'.
+  typedef std::shared_ptr<Base> BasePtr;
+  BasePtr StructType = BasePtr(new Base);
+// CHECK-MESSAGES: :[[@LINE-1]]:24: warning: use std::make_shared instead
+// CHECK-FIXES: BasePtr StructType = std::make_shared<Base>();
+
+#define PTR shared_ptr<int>
+  std::shared_ptr<int> Macro = std::PTR(new int);
+// CHECK-MESSAGES: :[[@LINE-1]]:32: warning: use std::make_shared instead
+// CHECK-FIXES: std::shared_ptr<int> Macro = std::make_shared<int>();
+#undef PTR
+
+  std::shared_ptr<int> Using = shared_ptr_<int>(new int);
+  // CHECK-MESSAGES: :[[@LINE-1]]:32: warning: use std::make_shared instead
+  // CHECK-FIXES: std::shared_ptr<int> Using = std::make_shared<int>();
+}
+
+void whitespaces() {
+  // clang-format off
+  auto Space = std::shared_ptr <int>(new int());
+  // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: use std::make_shared instead
+  // CHECK-FIXES: auto Space = std::make_shared<int>();
+
+  auto Spaces = std  ::    shared_ptr  <int>(new int());
+  // CHECK-MESSAGES: :[[@LINE-1]]:17: warning: use std::make_shared instead
+  // CHECK-FIXES: auto Spaces = std::make_shared<int>();
+  // clang-format on
+}
+
+void nesting() {
+  auto Nest = std::shared_ptr<std::shared_ptr<int>>(new std::shared_ptr<int>(new int));
+  // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: use std::make_shared instead
+  // CHECK-FIXES: auto Nest = std::make_shared<std::shared_ptr<int>>(new int);
+}




More information about the cfe-commits mailing list