Address review comments.

Hi revane,

http://llvm-reviews.chandlerc.com/D1074

CHANGE SINCE LAST DIFF
  http://llvm-reviews.chandlerc.com/D1074?vs=2623&id=2650#toc

Files:
  cpp11-migrate/ReplaceAutoPtr/ReplaceAutoPtr.h
  cpp11-migrate/ReplaceAutoPtr/ReplaceAutoPtrActions.cpp
  cpp11-migrate/ReplaceAutoPtr/ReplaceAutoPtrActions.h
  cpp11-migrate/ReplaceAutoPtr/ReplaceAutoPtrMatchers.cpp
  cpp11-migrate/ReplaceAutoPtr/ReplaceAutoPtrMatchers.h
  docs/MigratorUsage.rst
  docs/ReplaceAutoPtrTransform.rst
  test/cpp11-migrate/ReplaceAutoPtr/Inputs/basic.h
  test/cpp11-migrate/ReplaceAutoPtr/Inputs/memory_stub.h
  test/cpp11-migrate/ReplaceAutoPtr/basic.cpp
  test/cpp11-migrate/ReplaceAutoPtr/move.cpp
  test/cpp11-migrate/ReplaceAutoPtr/std_inline_namespace.cpp
  test/cpp11-migrate/ReplaceAutoPtr/template_fail.cpp
Index: cpp11-migrate/ReplaceAutoPtr/ReplaceAutoPtr.h
===================================================================
--- cpp11-migrate/ReplaceAutoPtr/ReplaceAutoPtr.h
+++ cpp11-migrate/ReplaceAutoPtr/ReplaceAutoPtr.h
@@ -12,18 +12,23 @@
 /// class.
 ///
 //===----------------------------------------------------------------------===//
-#ifndef LLVM_TOOLS_CLANG_TOOLS_EXTRA_CPP11_MIGRATE_REPLACE_AUTO_PTR_H
-#define LLVM_TOOLS_CLANG_TOOLS_EXTRA_CPP11_MIGRATE_REPLACE_AUTO_PTR_H
+#ifndef CPP11_MIGRATE_REPLACE_AUTO_PTR_H
+#define CPP11_MIGRATE_REPLACE_AUTO_PTR_H
 
 #include "Core/Transform.h"
 #include "llvm/Support/Compiler.h"
 
 /// \brief Subclass of Transform that transforms the deprecated \c std::auto_ptr
 /// into the C++11 \c std::unique_ptr.
 ///
 /// Note that both the \c std::auto_ptr type and the transfer of ownership are
-/// transformed. The latter requires to wrap the assigned expression with an
-/// explicit call to \c std::move().
+/// transformed. \c std::auto_ptr provides two ways to transfer the ownership,
+/// the copy-constructor and the assignment operator. Unlike most classes theses
+/// operations do not 'copy' the resource but they 'steal' it.
+/// \c std::unique_ptr uses move semantics instead, which makes the intent of
+/// transferring the resource explicit. This difference between the two smart
+/// pointers requires to wrap the copy-ctor and assign-operator with
+/// \c std::move().
 ///
 /// For example, given:
 /// \code
@@ -46,4 +51,4 @@
                     const std::vector<std::string> &SourcePaths) LLVM_OVERRIDE;
 };
 
-#endif // LLVM_TOOLS_CLANG_TOOLS_EXTRA_CPP11_MIGRATE_REPLACE_AUTO_PTR_H
+#endif // CPP11_MIGRATE_REPLACE_AUTO_PTR_H
Index: cpp11-migrate/ReplaceAutoPtr/ReplaceAutoPtrActions.cpp
===================================================================
--- cpp11-migrate/ReplaceAutoPtr/ReplaceAutoPtrActions.cpp
+++ cpp11-migrate/ReplaceAutoPtr/ReplaceAutoPtrActions.cpp
@@ -8,7 +8,7 @@
 //===----------------------------------------------------------------------===//
 ///
 /// \file
-/// \brief This file contains the definition(s) of the ASTMatcher callback(s)
+/// \brief This file contains the definition of the ASTMatcher callback
 /// for the ReplaceAutoPtr transform.
 ///
 //===----------------------------------------------------------------------===//
Index: cpp11-migrate/ReplaceAutoPtr/ReplaceAutoPtrActions.h
===================================================================
--- cpp11-migrate/ReplaceAutoPtr/ReplaceAutoPtrActions.h
+++ cpp11-migrate/ReplaceAutoPtr/ReplaceAutoPtrActions.h
@@ -8,12 +8,12 @@
 //===----------------------------------------------------------------------===//
 ///
 /// \file
-/// \brief This file contains the declaration(s) of the ASTMatcher callback(s)
+/// \brief This file contains the declaration of the ASTMatcher callback
 /// for the ReplaceAutoPtr transform.
 ///
 //===----------------------------------------------------------------------===//
-#ifndef LLVM_TOOLS_CLANG_TOOLS_EXTRA_CPP11_MIGRATE_REPLACE_AUTO_PTR_ACTIONS_H
-#define LLVM_TOOLS_CLANG_TOOLS_EXTRA_CPP11_MIGRATE_REPLACE_AUTO_PTR_ACTIONS_H
+#ifndef CPP11_MIGRATE_REPLACE_AUTO_PTR_ACTIONS_H
+#define CPP11_MIGRATE_REPLACE_AUTO_PTR_ACTIONS_H
 
 #include "clang/ASTMatchers/ASTMatchFinder.h"
 #include "clang/Tooling/Refactoring.h"
@@ -99,4 +99,4 @@
   const Transform &Owner;
 };
 
-#endif // LLVM_TOOLS_CLANG_TOOLS_EXTRA_CPP11_MIGRATE_REPLACE_AUTO_PTR_ACTIONS_H
+#endif // CPP11_MIGRATE_REPLACE_AUTO_PTR_ACTIONS_H
Index: cpp11-migrate/ReplaceAutoPtr/ReplaceAutoPtrMatchers.cpp
===================================================================
--- cpp11-migrate/ReplaceAutoPtr/ReplaceAutoPtrMatchers.cpp
+++ cpp11-migrate/ReplaceAutoPtr/ReplaceAutoPtrMatchers.cpp
@@ -79,10 +79,10 @@
 
 static TypeMatcher AutoPtrType = qualType(hasDeclaration(AutoPtrDecl));
 
-/// \brief Matcher that finds expressions that are candidates to be wrapped with
-/// \c std::move().
-///
-/// Bind the id \c AutoPtrOwnershipTransferId to the expression.
+// Matcher that finds expressions that are candidates to be wrapped with
+// 'std::move()'.
+//
+// Binds the id \c AutoPtrOwnershipTransferId to the expression.
 static StatementMatcher MovableArgumentMatcher = expr(
     allOf(isLValue(), hasType(AutoPtrType))).bind(AutoPtrOwnershipTransferId);
 
Index: cpp11-migrate/ReplaceAutoPtr/ReplaceAutoPtrMatchers.h
===================================================================
--- cpp11-migrate/ReplaceAutoPtr/ReplaceAutoPtrMatchers.h
+++ cpp11-migrate/ReplaceAutoPtr/ReplaceAutoPtrMatchers.h
@@ -12,8 +12,8 @@
 /// and names for bound nodes found by AST matchers.
 ///
 //===----------------------------------------------------------------------===//
-#ifndef LLVM_TOOLS_CLANG_TOOLS_EXTRA_CPP11_MIGRATE_REPLACE_AUTO_PTR_MATCHERS_H
-#define LLVM_TOOLS_CLANG_TOOLS_EXTRA_CPP11_MIGRATE_REPLACE_AUTO_PTR_MATCHERS_H
+#ifndef CPP11_MIGRATE_REPLACE_AUTO_PTR_MATCHERS_H
+#define CPP11_MIGRATE_REPLACE_AUTO_PTR_MATCHERS_H
 
 #include "clang/ASTMatchers/ASTMatchers.h"
 
@@ -60,4 +60,4 @@
 /// \endcode
 clang::ast_matchers::StatementMatcher makeTransferOwnershipExprMatcher();
 
-#endif // LLVM_TOOLS_CLANG_TOOLS_EXTRA_CPP11_MIGRATE_REPLACE_AUTO_PTR_MATCHERS_H
+#endif // CPP11_MIGRATE_REPLACE_AUTO_PTR_MATCHERS_H
Index: docs/MigratorUsage.rst
===================================================================
--- docs/MigratorUsage.rst
+++ docs/MigratorUsage.rst
@@ -126,3 +126,9 @@
   projects that use such macros to maintain build compatibility with non-C++11
   code.
 
+.. option:: -replace-auto_ptr
+
+  Replace ``std::auto_ptr`` (deprecated in C++11) by ``std::unique_ptr`` and
+  wrap calls to the copy constructor and assignment operator with
+  ``std::move()``.
+  See :doc:`ReplaceAutoPtrTransform`.
Index: docs/ReplaceAutoPtrTransform.rst
===================================================================
--- docs/ReplaceAutoPtrTransform.rst
+++ docs/ReplaceAutoPtrTransform.rst
@@ -33,27 +33,40 @@
 
 Known Limitations
 =================
-* Until headers modification is fully functional it is dangerous to use this
-  transform because declarations in headers will stay unchanged while the code
-  using them will be changed.
+* If headers modification is not activated or if a header is not allowed to be
+  changed this transform will produce broken code (compilation error), where the
+  the headers' code will stay unchanged while the code using them will be
+  changed.
 
-* Code that can't that can't be migrated, such as 3\ :sup:`rd` party libraries,
-  returning non-rvalue references to ``std::auto_ptr`` or ``const
-  std::auto_ptr`` will produce wrong code. Theses patterns don't make much sense
-  and usually ``std::auto_ptr`` are returned by value. When returned by value,
-  even coming from code that can't be migrated, it is not an issue since
-  ``std::unique_ptr`` can be constructed from a non-lvalue ``std::auto_ptr``.
+* Client code that declares a reference to an ``std::auto_ptr`` coming from code
+  that can't be migrated (such as a header coming from a 3\ :sup:`rd` party
+  library) will produce a compilation error after migration. This is because the
+  type of the reference will be changed to ``std::unique_ptr`` but the type
+  returned by the library won't change, binding a reference to
+  ``std::unique_ptr`` from an ``std::auto_ptr``. This pattern doesn't make much
+  sense and usually ``std::auto_ptr`` are stored by value (otherwise what is the
+  point in using them instead of a reference or a pointer?).
 
+  .. code-block:: c++
 
-.. code-block:: c++
+     // <3rd-party header...>
+     std::auto_ptr<int> get_value();
+     const std::auto_ptr<int> & get_ref();
+
+     // <calling code (with migration)...>
+    -std::auto_ptr<int> a(get_value());
+    +std::unique_ptr<int> a(get_value()); // ok, unique_ptr constructed from auto_ptr
+
+    -const std::auto_ptr<int> & p = get_ptr();
+    +const std::unique_ptr<int> & p = get_ptr(); // won't compile
+
+* Non-instantiated templates aren't modified.
 
-   // <3rd-party header...>
-   std::auto_ptr<int> get_value();
-   const std::auto_ptr<int> & get_ref();
+  .. code-block:: c++
 
-   // <calling code (with migration)...>
-  -std::auto_ptr<int> a(get_value());
-  +std::unique_ptr<int> a(get_value()); // ok, unique_ptr constructed from auto_ptr
+     template <typename X>
+     void f() {
+         std::auto_ptr<X> p;
+     }
 
-  -const std::auto_ptr<int> & p = get_ptr();
-  +const std::unique_ptr<int> & p = get_ptr(); // won't compile
+     // only 'f<int>()' (or similar) will trigger the replacement
Index: test/cpp11-migrate/ReplaceAutoPtr/Inputs/basic.h
===================================================================
--- test/cpp11-migrate/ReplaceAutoPtr/Inputs/basic.h
+++ test/cpp11-migrate/ReplaceAutoPtr/Inputs/basic.h
@@ -1,7 +1,7 @@
 #ifndef INPUTS_BASIC_H
 #define INPUTS_BASIC_H
 
-#include <memory>
+#include "memory_stub.h"
 
 // Instrumentation for auto_ptr_ref test
 // @{
@@ -16,8 +16,10 @@
 // CHECK: std::unique_ptr<char> f_5()
 
 // Test function parameters
-void f_6(const std::auto_ptr<int> &);
-// CHECK: void f_6(const std::unique_ptr<int> &);
+void f_6(std::auto_ptr<int>);
+// CHECK: void f_6(std::unique_ptr<int>);
+void f_7(const std::auto_ptr<int> &);
+// CHECK: void f_7(const std::unique_ptr<int> &);
 
 // Test on record type fields
 struct A {
@@ -28,7 +30,7 @@
   // CHECK: typedef std::unique_ptr<int> int_ptr_type;
 };
 
-// Test template WITH instanciation
+// Test template WITH instantiation
 template <typename T> struct B {
   typedef typename std::auto_ptr<T> created_type;
   // CHECK: typedef typename std::unique_ptr<T> created_type;
Index: test/cpp11-migrate/ReplaceAutoPtr/Inputs/memory_stub.h
===================================================================
--- /dev/null
+++ test/cpp11-migrate/ReplaceAutoPtr/Inputs/memory_stub.h
@@ -0,0 +1,61 @@
+//===-----------------------------------------------------------*- C++ -*--===//
+//
+// This file contains a shell implementation of the 'auto_ptr' type from the
+// standard library. This shell aims to support the variations between standard
+// library implementations.
+//
+// Variations for how 'auto_ptr' is presented:
+// 1. Defined directly in namespace std
+// 2. Use a versioned inline namespace in std (default on libc++).
+//
+// Use the preprocessor to define USE_INLINE_NAMESPACE=1 and use the second
+// variation.
+//
+//===----------------------------------------------------------------------===//
+
+namespace std {
+
+#if USE_INLINE_NAMESPACE
+inline namespace _1 {
+#endif
+
+template <class Y> struct auto_ptr_ref {
+  Y *y_;
+};
+
+template <class X> class auto_ptr {
+public:
+  typedef X element_type;
+  // D.10.1.1 construct/copy/destroy:
+  explicit auto_ptr(X *p = 0) throw() {}
+  auto_ptr(auto_ptr &) throw() {}
+  template <class Y> auto_ptr(auto_ptr<Y> &) throw() {}
+  auto_ptr &operator=(auto_ptr &) throw() { return *this; }
+  template <class Y> auto_ptr &operator=(auto_ptr<Y> &) throw() {
+    return *this;
+  }
+  auto_ptr &operator=(auto_ptr_ref<X> r) throw() { return *this; }
+  ~auto_ptr() throw() {}
+  // D.10.1.3 conversions:
+  auto_ptr(auto_ptr_ref<X> r) throw() : x_(r.y_) {}
+  template <class Y> operator auto_ptr_ref<Y>() throw() {
+    auto_ptr_ref<Y> r;
+    r.y_ = x_;
+    return r;
+  }
+  template <class Y> operator auto_ptr<Y>() throw() { return auto_ptr<Y>(x_); }
+
+private:
+  X *x_;
+};
+
+template <> class auto_ptr<void> {
+public:
+  typedef void element_type;
+};
+
+#if USE_INLINE_NAMESPACE
+} // namespace _1
+#endif
+
+} // end namespace std
Index: test/cpp11-migrate/ReplaceAutoPtr/basic.cpp
===================================================================
--- test/cpp11-migrate/ReplaceAutoPtr/basic.cpp
+++ test/cpp11-migrate/ReplaceAutoPtr/basic.cpp
@@ -1,10 +1,24 @@
 // RUN: mkdir -p %T/Inputs
+//
+// Without inline namespace:
+//
 // RUN: grep -Ev "// *[A-Z-]+:" %s > %t.cpp
 // RUN: grep -Ev "// *[A-Z-]+:" %S/Inputs/basic.h > %T/Inputs/basic.h
+// RUN: grep -Ev "// *[A-Z-]+:" %S/Inputs/memory_stub.h > %T/Inputs/memory_stub.h
 // RUN: cpp11-migrate -headers -include=%T -replace-auto_ptr %t.cpp -- \
 // RUN:               -std=c++11 -I %T
 // RUN: FileCheck -input-file=%t.cpp %s
 // RUN: FileCheck -input-file=%T/Inputs/basic.h %S/Inputs/basic.h
+//
+// With inline namespace:
+//
+// RUN: grep -Ev "// *[A-Z-]+:" %s > %t.cpp
+// RUN: grep -Ev "// *[A-Z-]+:" %S/Inputs/basic.h > %T/Inputs/basic.h
+// RUN: grep -Ev "// *[A-Z-]+:" %S/Inputs/memory_stub.h > %T/Inputs/memory_stub.h
+// RUN: cpp11-migrate -headers -include=%T -replace-auto_ptr %t.cpp -- \
+// RUN:               -DUSE_INLINE_NAMESPACE=1 -std=c++11 -I %T
+// RUN: FileCheck -input-file=%t.cpp %s
+// RUN: FileCheck -input-file=%T/Inputs/basic.h %S/Inputs/basic.h
 
 #include "Inputs/basic.h"
 
@@ -61,7 +75,7 @@
   std::auto_ptr<void> n;
   // CHECK: std::unique_ptr<void> n;
 
-  // Test template WITH instanciation (instanciation)
+  // Test template WITH instantiation (instantiation)
   B<double> o;
   std::auto_ptr<double> p(o.create());
   // CHECK: std::unique_ptr<double> p(o.create());
@@ -122,7 +136,7 @@
 }
 
 // Test that non-std auto_ptr aren't replaced
-void f_7() {
+void f_8() {
   ns_2::auto_ptr<char> a;
   // CHECK: ns_2::auto_ptr<char> a;
   using namespace ns_2;
Index: test/cpp11-migrate/ReplaceAutoPtr/move.cpp
===================================================================
--- test/cpp11-migrate/ReplaceAutoPtr/move.cpp
+++ test/cpp11-migrate/ReplaceAutoPtr/move.cpp
@@ -1,10 +1,23 @@
+// Without inline namespace:
+//
 // RUN: grep -Ev "// *[A-Z-]+:" %s > %t.cpp
-// RUN: cpp11-migrate -replace-auto_ptr %t.cpp -- -std=c++11
+// RUN: cpp11-migrate -replace-auto_ptr %t.cpp -- -I %S/Inputs std=c++11
+// RUN: FileCheck -input-file=%t.cpp %s
+//
+// With inline namespace:
+//
+// RUN: grep -Ev "// *[A-Z-]+:" %s > %t.cpp
+// RUN: cpp11-migrate -replace-auto_ptr %t.cpp -- -I %S/Inputs std=c++11 \
+// RUN:                                           -DUSE_INLINE_NAMESPACE=1
 // RUN: FileCheck -input-file=%t.cpp %s
 
-#include <memory>
+#include "memory_stub.h"
 
-void take_ownership_fn(std::auto_ptr<int> x);
+void takes_ownership_fn(std::auto_ptr<int> x);
+// CHECK: void takes_ownership_fn(std::unique_ptr<int> x);
+
+std::auto_ptr<int> get_by_value();
+// CHECK: std::unique_ptr<int> get_by_value();
 
 class Wrapper {
 public:
@@ -27,10 +40,10 @@
 
   // Test that 'std::move()' is inserted when call to the
   // copy-constructor are made.
-  take_ownership_fn(c);
-  // CHECK: take_ownership_fn(std::move(c));
-  take_ownership_fn(wrapper_a.get_wrapped());
-  // CHECK: take_ownership_fn(std::move(wrapper_a.get_wrapped()));
+  takes_ownership_fn(c);
+  // CHECK: takes_ownership_fn(std::move(c));
+  takes_ownership_fn(wrapper_a.get_wrapped());
+  // CHECK: takes_ownership_fn(std::move(wrapper_a.get_wrapped()));
 
   std::auto_ptr<int> d[] = { std::auto_ptr<int>(new int(1)),
                              std::auto_ptr<int>(new int(2)) };
@@ -44,4 +57,7 @@
   f = std::auto_ptr<int>(new int(0));
   // CHECK: std::unique_ptr<int> f;
   // CHECK-NEXT: f = std::unique_ptr<int>(new int(0));
+
+  std::auto_ptr<int> g = get_by_value();
+  // CHECK: std::unique_ptr<int> g = get_by_value();
 }
Index: test/cpp11-migrate/ReplaceAutoPtr/std_inline_namespace.cpp
===================================================================
--- test/cpp11-migrate/ReplaceAutoPtr/std_inline_namespace.cpp
+++ /dev/null
@@ -1,23 +0,0 @@
-// RUN: grep -Ev "// *[A-Z-]+:" %s > %t.cpp
-// RUN: cpp11-migrate -replace-auto_ptr %t.cpp -- -std=c++11
-// RUN: FileCheck -input-file=%t.cpp %s
-
-namespace std {
-
-// Check that even when declared in an inline namespace auto_ptr will be found.
-// libc++ use an inline versioned namespace to declare standard library types.
-//
-// Note that libstdc++ seems to have the same possibility but apparently off by
-// default.
-inline namespace __1 {
-
-template <typename T> class auto_ptr {};
-
-} // namespace '__1' ends here
-using namespace __1;
-
-} // namespace 'std' ends here
-
-
-std::auto_ptr<int> a;
-// CHECK: std::unique_ptr<int> a;
Index: test/cpp11-migrate/ReplaceAutoPtr/template_fail.cpp
===================================================================
--- test/cpp11-migrate/ReplaceAutoPtr/template_fail.cpp
+++ test/cpp11-migrate/ReplaceAutoPtr/template_fail.cpp
@@ -1,11 +1,21 @@
+// XFAIL: *
+//
+// Without inline namespace:
+//
 // RUN: grep -Ev "// *[A-Z-]+:" %s > %t.cpp
-// RUN: cpp11-migrate -replace-auto_ptr %t.cpp -- -std=c++11
+// RUN: cpp11-migrate -replace-auto_ptr %t.cpp -- -I %S/Inputs std=c++11
+// RUN: FileCheck -input-file=%t.cpp %s
+//
+// With inline namespace:
+//
+// RUN: grep -Ev "// *[A-Z-]+:" %s > %t.cpp
+// RUN: cpp11-migrate -replace-auto_ptr %t.cpp -- -I %S/Inputs std=c++11 \
+// RUN:                                           -DUSE_INLINE_NAMESPACE=1
 // RUN: FileCheck -input-file=%t.cpp %s
-// XFAIL: *
 
-#include <memory>
+#include "memory_stub.h"
 
-// Fail to modify when the template is never instanciated.
+// Fail to modify when the template is never instantiated.
 //
 // This might not be an issue. If it's never used it doesn't really matter if
 // it's changed or not. If it's a header and one of the source use it, then it
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits

Reply via email to