<div dir="ltr">It's not every day that we get substantial comment improvements :) Thanks!</div><div class="gmail_extra"><br><div class="gmail_quote">On Thu, Dec 29, 2016 at 11:59 AM, Justin Lebar via llvm-commits <span dir="ltr"><<a href="mailto:llvm-commits@lists.llvm.org" target="_blank">llvm-commits@lists.llvm.org</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Author: jlebar<br>
Date: Thu Dec 29 13:59:38 2016<br>
New Revision: 290720<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=290720&view=rev" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project?rev=290720&view=rev</a><br>
Log:<br>
[ADT] Rewrite IntrusiveRefCntPtr's comments. NFC<br>
<br>
Edit for voice, and also add examples.  In particular, add an<br>
explanation for why you might want to specialize IntrusiveRefCntPtrInfo,<br>
which is not obvious.<br>
<br>
Modified:<br>
    llvm/trunk/include/llvm/ADT/<wbr>IntrusiveRefCntPtr.h<br>
<br>
Modified: llvm/trunk/include/llvm/ADT/<wbr>IntrusiveRefCntPtr.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ADT/IntrusiveRefCntPtr.h?rev=290720&r1=290719&r2=290720&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/llvm/trunk/include/<wbr>llvm/ADT/IntrusiveRefCntPtr.h?<wbr>rev=290720&r1=290719&r2=<wbr>290720&view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- llvm/trunk/include/llvm/ADT/<wbr>IntrusiveRefCntPtr.h (original)<br>
+++ llvm/trunk/include/llvm/ADT/<wbr>IntrusiveRefCntPtr.h Thu Dec 29 13:59:38 2016<br>
@@ -7,14 +7,49 @@<br>
 //<br>
 //===-------------------------<wbr>------------------------------<wbr>---------------===//<br>
 //<br>
-// This file defines IntrusiveRefCntPtr, a template class that<br>
-// implements a "smart" pointer for objects that maintain their own<br>
-// internal reference count, and RefCountedBase, a generic base class<br>
-// for objects that wish to have their lifetimes managed using reference<br>
-// counting.<br>
+// This file defines the RefCountedBase, ThreadSafeRefCountedBase, and<br>
+// IntrusiveRefCntPtr classes.<br>
 //<br>
-// IntrusiveRefCntPtr is similar to Boost's intrusive_ptr with added<br>
-// LLVM-style casting.<br>
+// IntrusiveRefCntPtr is a smart pointer to an object which maintains a<br>
+// reference count.  (ThreadSafe)RefCountedBase is a mixin class that adds a<br>
+// refcount member variable and methods for updating the refcount.  An object<br>
+// that inherits from (ThreadSafe)RefCountedBase deletes itself when its<br>
+// refcount hits zero.<br>
+//<br>
+// For example:<br>
+//<br>
+//   class MyClass : public RefCountedBase<MyClass> {};<br>
+//<br>
+//   void foo() {<br>
+//     // Objects that inherit from RefCountedBase should always be instantiated<br>
+//     // on the heap, never on the stack.<br>
+//     IntrusiveRefCntPtr<MyClass> Ptr1(new MyClass());<br>
+//<br>
+//     // Copying an IntrusiveRefCntPtr increases the pointee's refcount by 1.<br>
+//     IntrusiveRefCntPtr<MyClass> Ptr2(Ptr1);<br>
+//<br>
+//     // Constructing an IntrusiveRefCntPtr has no effect on the object's<br>
+//     // refcount.  After a move, the moved-from pointer is null.<br>
+//     IntrusiveRefCntPtr<MyClass> Ptr3(std::move(Ptr1));<br>
+//     assert(Ptr1 == nullptr);<br>
+//<br>
+//     // Clearing an IntrusiveRefCntPtr decreases the pointee's refcount by 1.<br>
+//     Ptr2.reset();<br>
+//<br>
+//     // The object deletes itself when we return from the function, because<br>
+//     // Ptr3's destructor decrements its refcount to 0.<br>
+//   }<br>
+//<br>
+// You can use IntrusiveRefCntPtr with isa<T>(), dyn_cast<T>(), etc.:<br>
+//<br>
+//   IntrusiveRefCntPtr<MyClass> Ptr(new MyClass());<br>
+//   OtherClass *Other = dyn_cast<OtherClass>(Ptr);  // Ptr.get() not required<br>
+//<br>
+// IntrusiveRefCntPtr works with any class that<br>
+//<br>
+//  - inherits from (ThreadSafe)RefCountedBase,<br>
+//  - has Retain() and Release() methods, or<br>
+//  - specializes IntrusiveRefCntPtrInfo.<br>
 //<br>
 //===-------------------------<wbr>------------------------------<wbr>---------------===//<br>
<br>
@@ -27,16 +62,15 @@<br>
<br>
 namespace llvm {<br>
<br>
-//===------------------------<wbr>------------------------------<wbr>----------------===//<br>
-/// RefCountedBase - A generic base class for objects that wish to<br>
-///  have their lifetimes managed using reference counts. Classes<br>
-///  subclass RefCountedBase to obtain such functionality, and are<br>
-///  typically handled with IntrusiveRefCntPtr "smart pointers" (see below)<br>
-///  which automatically handle the management of reference counts.<br>
-///  Objects that subclass RefCountedBase should not be allocated on<br>
-///  the stack, as invoking "delete" (which is called when the<br>
-///  reference count hits 0) on such objects is an error.<br>
-//===------------------------<wbr>------------------------------<wbr>----------------===//<br>
+/// A CRTP mixin class that adds reference counting to a type.<br>
+///<br>
+/// The lifetime of an object which inherits from RefCountedBase is managed by<br>
+/// calls to Release() and Retain(), which increment and decrement the object's<br>
+/// refcount, respectively.  When a Release() call decrements the refcount to 0,<br>
+/// the object deletes itself.<br>
+///<br>
+/// Objects that inherit from RefCountedBase should always be allocated with<br>
+/// operator new.<br>
 template <class Derived> class RefCountedBase {<br>
   mutable unsigned RefCount = 0;<br>
<br>
@@ -52,18 +86,7 @@ public:<br>
   }<br>
 };<br>
<br>
-template <typename T> struct IntrusiveRefCntPtrInfo {<br>
-  static void retain(T *obj) { obj->Retain(); }<br>
-  static void release(T *obj) { obj->Release(); }<br>
-};<br>
-<br>
-/// \brief A thread-safe version of \c llvm::RefCountedBase.<br>
-///<br>
-/// A generic base class for objects that wish to have their lifetimes managed<br>
-/// using reference counts. Classes subclass \c ThreadSafeRefCountedBase to<br>
-/// obtain such functionality, and are typically handled with<br>
-/// \c IntrusiveRefCntPtr "smart pointers" which automatically handle the<br>
-/// management of reference counts.<br>
+/// A thread-safe version of \c RefCountedBase.<br>
 template <class Derived> class ThreadSafeRefCountedBase {<br>
   mutable std::atomic<int> RefCount;<br>
<br>
@@ -81,22 +104,37 @@ public:<br>
   }<br>
 };<br>
<br>
-//===------------------------<wbr>------------------------------<wbr>----------------===//<br>
-/// IntrusiveRefCntPtr - A template class that implements a "smart pointer"<br>
-///  that assumes the wrapped object has a reference count associated<br>
-///  with it that can be managed via calls to<br>
-///  IntrusivePtrAddRef/<wbr>IntrusivePtrRelease.  The smart pointers<br>
-///  manage reference counts via the RAII idiom: upon creation of<br>
-///  smart pointer the reference count of the wrapped object is<br>
-///  incremented and upon destruction of the smart pointer the<br>
-///  reference count is decremented.  This class also safely handles<br>
-///  wrapping NULL pointers.<br>
-///<br>
-/// Reference counting is implemented via calls to<br>
-///  Obj->Retain()/Obj->Release(). Release() is required to destroy the<br>
-///  object when the reference count reaches zero. Inheriting from<br>
-///  RefCountedBase takes care of this automatically.<br>
-//===------------------------<wbr>------------------------------<wbr>----------------===//<br>
+/// Class you can specialize to provide custom retain/release functionality for<br>
+/// a type.<br>
+///<br>
+/// Usually specializing this class is not necessary, as IntrusiveRefCntPtr<br>
+/// works with any type which defines Retain() and Release() functions -- you<br>
+/// can define those functions yourself if RefCountedBase doesn't work for you.<br>
+///<br>
+/// One case when you might want to specialize this type is if you have<br>
+///  - Foo.h defines type Foo and includes Bar.h, and<br>
+///  - Bar.h uses IntrusiveRefCntPtr<Foo> in inline functions.<br>
+///<br>
+/// Because Foo.h includes Bar.h, Bar.h can't include Foo.h in order to pull in<br>
+/// the declaration of Foo.  Without the declaration of Foo, normally Bar.h<br>
+/// wouldn't be able to use IntrusiveRefCntPtr<Foo>, which wants to call<br>
+/// T::Retain and T::Release.<br>
+///<br>
+/// To resolve this, Bar.h could include a third header, FooFwd.h, which<br>
+/// forward-declares Foo and specializes IntrusiveRefCntPtrInfo<Foo>.  Then<br>
+/// Bar.h could use IntrusiveRefCntPtr<Foo>, although it still couldn't call any<br>
+/// functions on Foo itself, because Foo would be an incomplete type.<br>
+template <typename T> struct IntrusiveRefCntPtrInfo {<br>
+  static void retain(T *obj) { obj->Retain(); }<br>
+  static void release(T *obj) { obj->Release(); }<br>
+};<br>
+<br>
+/// A smart pointer to a reference-counted object that inherits from<br>
+/// RefCountedBase or ThreadSafeRefCountedBase.<br>
+///<br>
+/// This class increments its pointee's reference count when it is created, and<br>
+/// decrements its refcount when it's destroyed (or is changed to point to a<br>
+/// different object).<br>
 template <typename T> class IntrusiveRefCntPtr {<br>
   T *Obj = nullptr;<br>
<br>
@@ -208,10 +246,8 @@ bool operator!=(const IntrusiveRefCntPtr<br>
   return !(A == B);<br>
 }<br>
<br>
-//===------------------------<wbr>------------------------------<wbr>----------------===//<br>
-// LLVM-style downcasting support for IntrusiveRefCntPtr objects<br>
-//===------------------------<wbr>------------------------------<wbr>----------------===//<br>
-<br>
+// Make IntrusiveRefCntPtr work with dyn_cast, isa, and the other idioms from<br>
+// Casting.h.<br>
 template <typename From> struct simplify_type;<br>
<br>
 template <class T> struct simplify_type<<wbr>IntrusiveRefCntPtr<T>> {<br>
<br>
<br>
______________________________<wbr>_________________<br>
llvm-commits mailing list<br>
<a href="mailto:llvm-commits@lists.llvm.org">llvm-commits@lists.llvm.org</a><br>
<a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits" rel="noreferrer" target="_blank">http://lists.llvm.org/cgi-bin/<wbr>mailman/listinfo/llvm-commits</a><br>
</blockquote></div><br></div>