<div dir="ltr"><br><div class="gmail_extra"><br><div class="gmail_quote">On Mon, Mar 21, 2016 at 8:44 PM, Pete Cooper 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: pete<br>
Date: Mon Mar 21 22:44:32 2016<br>
New Revision: 264022<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=264022&view=rev" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project?rev=264022&view=rev</a><br>
Log:<br>
Use owning pointers instead of raw pointers for Atom's to fix leaks.<br>
<br>
Currently each File contains an BumpPtrAllocator in which Atom's are<br>
allocated.  Some Atom's contain data structures like std::vector which<br>
leak as we don't run ~Atom when they are BumpPtrAllocate'd.<br></blockquote><div><br></div><div>FWIW, if the only thing allocated in the BumpPtrAllocator is Atoms, you could use a SpecificBumpPtrAllocator, which does run the dtors.<br><br>(& if the BumpPtrAllocator doesn't contain only Atoms, you could change it so it does)</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<br>
Now each File actually owns its Atom's using an OwningAtomPtr.  This<br>
is analygous to std::unique_ptr and may be replaced by it if possible.<br></blockquote><div><br>Yeah, this looks like it could just be a typedef of unique_ptr with a custom deleter that only runs the dtor but doesn't delete, etc.</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<br>
An Atom can therefore only be owned by a single File, so the Resolver now<br>
moves them from one File to another.  The MachOLinkingContext owns the File's<br>
and so clears all the Atom's in ~MachOLinkingContext, then delete's all the<br>
File's.  This makes sure all Atom's have been destructed before any of the<br>
BumpPtrAllocator's in which they run have gone away.<br>
<br>
Should hopefully fix the remaining leaks.  Will keep an eye on the bots to<br>
make sure.<br>
<br>
Modified:<br>
    lld/trunk/include/lld/Core/Atom.h<br>
    lld/trunk/include/lld/Core/DefinedAtom.h<br>
    lld/trunk/include/lld/Core/File.h<br>
    lld/trunk/include/lld/Core/Resolver.h<br>
    lld/trunk/include/lld/Core/SharedLibraryAtom.h<br>
    lld/trunk/include/lld/Core/SharedLibraryFile.h<br>
    lld/trunk/include/lld/Core/Simple.h<br>
    lld/trunk/include/lld/Core/UndefinedAtom.h<br>
    lld/trunk/lib/Core/File.cpp<br>
    lld/trunk/lib/Core/Resolver.cpp<br>
    lld/trunk/lib/Driver/DarwinLdDriver.cpp<br>
    lld/trunk/lib/ReaderWriter/FileArchive.cpp<br>
    lld/trunk/lib/ReaderWriter/MachO/ArchHandler_arm.cpp<br>
    lld/trunk/lib/ReaderWriter/MachO/Atoms.h<br>
    lld/trunk/lib/ReaderWriter/MachO/CompactUnwindPass.cpp<br>
    lld/trunk/lib/ReaderWriter/MachO/ExecutableAtoms.h<br>
    lld/trunk/lib/ReaderWriter/MachO/File.h<br>
    lld/trunk/lib/ReaderWriter/MachO/FlatNamespaceFile.h<br>
    lld/trunk/lib/ReaderWriter/MachO/GOTPass.cpp<br>
    lld/trunk/lib/ReaderWriter/MachO/LayoutPass.cpp<br>
    lld/trunk/lib/ReaderWriter/MachO/LayoutPass.h<br>
    lld/trunk/lib/ReaderWriter/MachO/MachOLinkingContext.cpp<br>
    lld/trunk/lib/ReaderWriter/MachO/ObjCPass.cpp<br>
    lld/trunk/lib/ReaderWriter/MachO/SectCreateFile.h<br>
    lld/trunk/lib/ReaderWriter/MachO/StubsPass.cpp<br>
    lld/trunk/lib/ReaderWriter/MachO/TLVPass.cpp<br>
    lld/trunk/lib/ReaderWriter/YAML/ReaderWriterYAML.cpp<br>
<br>
Modified: lld/trunk/include/lld/Core/Atom.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/lld/trunk/include/lld/Core/Atom.h?rev=264022&r1=264021&r2=264022&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/lld/trunk/include/lld/Core/Atom.h?rev=264022&r1=264021&r2=264022&view=diff</a><br>
==============================================================================<br>
--- lld/trunk/include/lld/Core/Atom.h (original)<br>
+++ lld/trunk/include/lld/Core/Atom.h Mon Mar 21 22:44:32 2016<br>
@@ -16,6 +16,9 @@ namespace lld {<br>
<br>
 class File;<br>
<br>
+template<typename T><br>
+class OwningAtomPtr;<br>
+<br>
 ///<br>
 /// The linker has a Graph Theory model of linking. An object file is seen<br>
 /// as a set of Atoms with References to other Atoms.  Each Atom is a node<br>
@@ -24,6 +27,7 @@ class File;<br>
 /// undefined symbol (extern declaration).<br>
 ///<br>
 class Atom {<br>
+  template<typename T> friend class OwningAtomPtr;<br>
 public:<br>
   /// Whether this atom is defined or a proxy for an undefined symbol<br>
   enum Definition {<br>
@@ -71,6 +75,49 @@ private:<br>
   Definition _definition;<br>
 };<br>
<br>
+/// Class which owns an atom pointer and runs the atom destructor when the<br>
+/// owning pointer goes out of scope.<br>
+template<typename T><br>
+class OwningAtomPtr {<br>
+private:<br>
+  OwningAtomPtr(const OwningAtomPtr &) = delete;<br>
+  void operator=(const OwningAtomPtr&) = delete;<br>
+public:<br>
+  OwningAtomPtr() : atom(nullptr) { }<br>
+  OwningAtomPtr(T *atom) : atom(atom) { }<br>
+<br>
+  ~OwningAtomPtr() {<br>
+    if (atom)<br>
+      atom->~Atom();<br>
+  }<br>
+<br>
+  OwningAtomPtr(OwningAtomPtr &&ptr) : atom(ptr.atom) {<br>
+    ptr.atom = nullptr;<br>
+  }<br>
+<br>
+  void operator=(OwningAtomPtr&& ptr) {<br>
+    atom = ptr.atom;<br>
+    ptr.atom = nullptr;<br>
+  }<br>
+<br>
+  T *const &get() const {<br>
+    return atom;<br>
+  }<br>
+<br>
+  T *&get() {<br>
+    return atom;<br>
+  }<br>
+<br>
+  T *release() {<br>
+    auto *v = atom;<br>
+    atom = nullptr;<br>
+    return v;<br>
+  }<br>
+<br>
+private:<br>
+  T *atom;<br>
+};<br>
+<br>
 } // namespace lld<br>
<br>
 #endif // LLD_CORE_ATOM_H<br>
<br>
Modified: lld/trunk/include/lld/Core/DefinedAtom.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/lld/trunk/include/lld/Core/DefinedAtom.h?rev=264022&r1=264021&r2=264022&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/lld/trunk/include/lld/Core/DefinedAtom.h?rev=264022&r1=264021&r2=264022&view=diff</a><br>
==============================================================================<br>
--- lld/trunk/include/lld/Core/DefinedAtom.h (original)<br>
+++ lld/trunk/include/lld/Core/DefinedAtom.h Mon Mar 21 22:44:32 2016<br>
@@ -363,6 +363,8 @@ protected:<br>
   // constructor.<br>
   DefinedAtom() : Atom(definitionRegular) { }<br>
<br>
+  ~DefinedAtom() override = default;<br>
+<br>
   /// \brief Returns a pointer to the Reference object that the abstract<br>
   /// iterator "points" to.<br>
   virtual const Reference *derefIterator(const void *iter) const = 0;<br>
<br>
Modified: lld/trunk/include/lld/Core/File.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/lld/trunk/include/lld/Core/File.h?rev=264022&r1=264021&r2=264022&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/lld/trunk/include/lld/Core/File.h?rev=264022&r1=264021&r2=264022&view=diff</a><br>
==============================================================================<br>
--- lld/trunk/include/lld/Core/File.h (original)<br>
+++ lld/trunk/include/lld/Core/File.h Mon Mar 21 22:44:32 2016<br>
@@ -15,6 +15,7 @@<br>
 #include "lld/Core/SharedLibraryAtom.h"<br>
 #include "lld/Core/UndefinedAtom.h"<br>
 #include "llvm/ADT/Optional.h"<br>
+#include "llvm/ADT/STLExtras.h"<br>
 #include "llvm/ADT/Twine.h"<br>
 #include "llvm/Support/ErrorHandling.h"<br>
 #include <functional><br>
@@ -39,6 +40,10 @@ class LinkingContext;<br>
 /// The Atom objects in a File are owned by the File object.  The Atom objects<br>
 /// are destroyed when the File object is destroyed.<br>
 class File {<br>
+protected:<br>
+  /// The type of atom mutable container.<br>
+  template <typename T> using AtomVector = std::vector<OwningAtomPtr<T>>;<br>
+<br>
 public:<br>
   virtual ~File();<br>
<br>
@@ -104,18 +109,67 @@ public:<br>
     return _allocator;<br>
   }<br>
<br>
-  /// The type of atom mutable container.<br>
-  template <typename T> using AtomVector = std::vector<const T *>;<br>
-<br>
-  /// The range type for the atoms. It's backed by a std::vector, but hides<br>
-  /// its member functions so that you can only call begin or end.<br>
+  /// The range type for the atoms.<br>
   template <typename T> class AtomRange {<br>
   public:<br>
-    AtomRange(AtomVector<T> v) : _v(v) {}<br>
-    typename AtomVector<T>::const_iterator begin() const { return _v.begin(); }<br>
-    typename AtomVector<T>::const_iterator end() const { return _v.end(); }<br>
-    typename AtomVector<T>::iterator begin() { return _v.begin(); }<br>
-    typename AtomVector<T>::iterator end() { return _v.end(); }<br>
+    AtomRange(AtomVector<T> &v) : _v(v) {}<br>
+    AtomRange(const AtomVector<T> &v) : _v(const_cast<AtomVector<T> &>(v)) {}<br>
+<br>
+    typedef std::pointer_to_unary_function<const OwningAtomPtr<T>&,<br>
+                                           const T*> ConstDerefFn;<br>
+<br>
+    typedef std::pointer_to_unary_function<OwningAtomPtr<T>&, T*> DerefFn;<br>
+<br>
+    typedef llvm::mapped_iterator<typename AtomVector<T>::const_iterator,<br>
+                                  ConstDerefFn> ConstItTy;<br>
+    typedef llvm::mapped_iterator<typename AtomVector<T>::iterator,<br>
+                                  DerefFn> ItTy;<br>
+<br>
+    static const T* DerefConst(const OwningAtomPtr<T> &p) {<br>
+      return p.get();<br>
+    }<br>
+<br>
+    static T* Deref(OwningAtomPtr<T> &p) {<br>
+      return p.get();<br>
+    }<br>
+<br>
+    ConstItTy begin() const {<br>
+      return ConstItTy(_v.begin(), ConstDerefFn(DerefConst));<br>
+    }<br>
+    ConstItTy end() const {<br>
+      return ConstItTy(_v.end(), ConstDerefFn(DerefConst));<br>
+    }<br>
+<br>
+    ItTy begin() {<br>
+      return ItTy(_v.begin(), DerefFn(Deref));<br>
+    }<br>
+    ItTy end() {<br>
+      return ItTy(_v.end(), DerefFn(Deref));<br>
+    }<br>
+<br>
+    llvm::iterator_range<typename AtomVector<T>::iterator> owning_ptrs() {<br>
+      return llvm::make_range(_v.begin(), _v.end());<br>
+    }<br>
+<br>
+    llvm::iterator_range<typename AtomVector<T>::iterator> owning_ptrs() const {<br>
+      return llvm::make_range(_v.begin(), _v.end());<br>
+    }<br>
+<br>
+    bool empty() const {<br>
+      return _v.empty();<br>
+    }<br>
+<br>
+    size_t size() const {<br>
+      return _v.size();<br>
+    }<br>
+<br>
+    const OwningAtomPtr<T> &operator[](size_t idx) const {<br>
+      return _v[idx];<br>
+    }<br>
+<br>
+    OwningAtomPtr<T> &operator[](size_t idx) {<br>
+      return _v[idx];<br>
+    }<br>
<br>
   private:<br>
     AtomVector<T> &_v;<br>
@@ -123,19 +177,25 @@ public:<br>
<br>
   /// \brief Must be implemented to return the AtomVector object for<br>
   /// all DefinedAtoms in this File.<br>
-  virtual const AtomVector<DefinedAtom> &defined() const = 0;<br>
+  virtual const AtomRange<DefinedAtom> defined() const = 0;<br>
<br>
   /// \brief Must be implemented to return the AtomVector object for<br>
   /// all UndefinedAtomw in this File.<br>
-  virtual const AtomVector<UndefinedAtom> &undefined() const = 0;<br>
+  virtual const AtomRange<UndefinedAtom> undefined() const = 0;<br>
<br>
   /// \brief Must be implemented to return the AtomVector object for<br>
   /// all SharedLibraryAtoms in this File.<br>
-  virtual const AtomVector<SharedLibraryAtom> &sharedLibrary() const = 0;<br>
+  virtual const AtomRange<SharedLibraryAtom> sharedLibrary() const = 0;<br>
<br>
   /// \brief Must be implemented to return the AtomVector object for<br>
   /// all AbsoluteAtoms in this File.<br>
-  virtual const AtomVector<AbsoluteAtom> &absolute() const = 0;<br>
+  virtual const AtomRange<AbsoluteAtom> absolute() const = 0;<br>
+<br>
+  /// Drop all of the atoms owned by this file.  This will result in all of<br>
+  /// the atoms running their destructors.<br>
+  /// This is required because atoms may be allocated on a BumpPtrAllocator<br>
+  /// of a different file.  We need to destruct all atoms before any files.<br>
+  virtual void clearAtoms() = 0;<br>
<br>
   /// \brief If a file is parsed using a different method than doParse(),<br>
   /// one must use this method to set the last error status, so that<br>
@@ -194,19 +254,22 @@ public:<br>
<br>
   std::error_code doParse() override { return _ec; }<br>
<br>
-  const AtomVector<DefinedAtom> &defined() const override {<br>
+  const AtomRange<DefinedAtom> defined() const override {<br>
     llvm_unreachable("internal error");<br>
   }<br>
-  const AtomVector<UndefinedAtom> &undefined() const override {<br>
+  const AtomRange<UndefinedAtom> undefined() const override {<br>
     llvm_unreachable("internal error");<br>
   }<br>
-  const AtomVector<SharedLibraryAtom> &sharedLibrary() const override {<br>
+  const AtomRange<SharedLibraryAtom> sharedLibrary() const override {<br>
     llvm_unreachable("internal error");<br>
   }<br>
-  const AtomVector<AbsoluteAtom> &absolute() const override {<br>
+  const AtomRange<AbsoluteAtom> absolute() const override {<br>
     llvm_unreachable("internal error");<br>
   }<br>
<br>
+  void clearAtoms() override {<br>
+  }<br>
+<br>
 private:<br>
   std::error_code _ec;<br>
 };<br>
<br>
Modified: lld/trunk/include/lld/Core/Resolver.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/lld/trunk/include/lld/Core/Resolver.h?rev=264022&r1=264021&r2=264022&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/lld/trunk/include/lld/Core/Resolver.h?rev=264022&r1=264021&r2=264022&view=diff</a><br>
==============================================================================<br>
--- lld/trunk/include/lld/Core/Resolver.h (original)<br>
+++ lld/trunk/include/lld/Core/Resolver.h Mon Mar 21 22:44:32 2016<br>
@@ -35,10 +35,10 @@ public:<br>
   Resolver(LinkingContext &ctx) : _ctx(ctx), _result(new MergedFile()) {}<br>
<br>
   // InputFiles::Handler methods<br>
-  void doDefinedAtom(const DefinedAtom&);<br>
-  bool doUndefinedAtom(const UndefinedAtom &);<br>
-  void doSharedLibraryAtom(const SharedLibraryAtom &);<br>
-  void doAbsoluteAtom(const AbsoluteAtom &);<br>
+  void doDefinedAtom(OwningAtomPtr<DefinedAtom> atom);<br>
+  bool doUndefinedAtom(OwningAtomPtr<UndefinedAtom> atom);<br>
+  void doSharedLibraryAtom(OwningAtomPtr<SharedLibraryAtom> atom);<br>
+  void doAbsoluteAtom(OwningAtomPtr<AbsoluteAtom> atom);<br>
<br>
   // Handle files, this adds atoms from the current file thats<br>
   // being processed by the resolver<br>
@@ -71,17 +71,16 @@ private:<br>
                                  UndefCallback callback);<br>
<br>
   void markLive(const Atom *atom);<br>
-  void addAtoms(const std::vector<const DefinedAtom *>&);<br>
<br>
   class MergedFile : public SimpleFile {<br>
   public:<br>
     MergedFile() : SimpleFile("<linker-internal>", kindResolverMergedObject) {}<br>
-    void addAtoms(std::vector<const Atom*>& atoms);<br>
+    void addAtoms(llvm::MutableArrayRef<OwningAtomPtr<Atom>> atoms);<br>
   };<br>
<br>
   LinkingContext &_ctx;<br>
   SymbolTable _symbolTable;<br>
-  std::vector<const Atom *>     _atoms;<br>
+  std::vector<OwningAtomPtr<Atom>>     _atoms;<br>
   std::set<const Atom *>        _deadStripRoots;<br>
   llvm::DenseSet<const Atom *>  _liveAtoms;<br>
   llvm::DenseSet<const Atom *>  _deadAtoms;<br>
<br>
Modified: lld/trunk/include/lld/Core/SharedLibraryAtom.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/lld/trunk/include/lld/Core/SharedLibraryAtom.h?rev=264022&r1=264021&r2=264022&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/lld/trunk/include/lld/Core/SharedLibraryAtom.h?rev=264022&r1=264021&r2=264022&view=diff</a><br>
==============================================================================<br>
--- lld/trunk/include/lld/Core/SharedLibraryAtom.h (original)<br>
+++ lld/trunk/include/lld/Core/SharedLibraryAtom.h Mon Mar 21 22:44:32 2016<br>
@@ -44,6 +44,8 @@ public:<br>
<br>
 protected:<br>
   SharedLibraryAtom() : Atom(definitionSharedLibrary) {}<br>
+<br>
+  ~SharedLibraryAtom() override = default;<br>
 };<br>
<br>
 } // namespace lld<br>
<br>
Modified: lld/trunk/include/lld/Core/SharedLibraryFile.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/lld/trunk/include/lld/Core/SharedLibraryFile.h?rev=264022&r1=264021&r2=264022&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/lld/trunk/include/lld/Core/SharedLibraryFile.h?rev=264022&r1=264021&r2=264022&view=diff</a><br>
==============================================================================<br>
--- lld/trunk/include/lld/Core/SharedLibraryFile.h (original)<br>
+++ lld/trunk/include/lld/Core/SharedLibraryFile.h Mon Mar 21 22:44:32 2016<br>
@@ -27,28 +27,35 @@ public:<br>
   /// Check if the shared library exports a symbol with the specified name.<br>
   /// If so, return a SharedLibraryAtom which represents that exported<br>
   /// symbol.  Otherwise return nullptr.<br>
-  virtual const SharedLibraryAtom *exports(StringRef name,<br>
+  virtual OwningAtomPtr<SharedLibraryAtom> exports(StringRef name,<br>
                                            bool dataSymbolOnly) const = 0;<br>
<br>
   // Returns the install name.<br>
   virtual StringRef getDSOName() const = 0;<br>
<br>
-  const AtomVector<DefinedAtom> &defined() const override {<br>
+  const AtomRange<DefinedAtom> defined() const override {<br>
     return _definedAtoms;<br>
   }<br>
<br>
-  const AtomVector<UndefinedAtom> &undefined() const override {<br>
+  const AtomRange<UndefinedAtom> undefined() const override {<br>
     return _undefinedAtoms;<br>
   }<br>
<br>
-  const AtomVector<SharedLibraryAtom> &sharedLibrary() const override {<br>
+  const AtomRange<SharedLibraryAtom> sharedLibrary() const override {<br>
     return _sharedLibraryAtoms;<br>
   }<br>
<br>
-  const AtomVector<AbsoluteAtom> &absolute() const override {<br>
+  const AtomRange<AbsoluteAtom> absolute() const override {<br>
     return _absoluteAtoms;<br>
   }<br>
<br>
+  void clearAtoms() override {<br>
+    _definedAtoms.clear();<br>
+    _undefinedAtoms.clear();<br>
+    _sharedLibraryAtoms.clear();<br>
+    _absoluteAtoms.clear();<br>
+  }<br>
+<br>
 protected:<br>
   /// only subclasses of SharedLibraryFile can be instantiated<br>
   explicit SharedLibraryFile(StringRef path) : File(path, kindSharedLibrary) {}<br>
<br>
Modified: lld/trunk/include/lld/Core/Simple.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/lld/trunk/include/lld/Core/Simple.h?rev=264022&r1=264021&r2=264022&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/lld/trunk/include/lld/Core/Simple.h?rev=264022&r1=264021&r2=264022&view=diff</a><br>
==============================================================================<br>
--- lld/trunk/include/lld/Core/Simple.h (original)<br>
+++ lld/trunk/include/lld/Core/Simple.h Mon Mar 21 22:44:32 2016<br>
@@ -31,20 +31,35 @@ public:<br>
   SimpleFile(StringRef path, File::Kind kind)<br>
     : File(path, kind) {}<br>
<br>
-  void addAtom(const DefinedAtom &a) { _defined.push_back(&a); }<br>
-  void addAtom(const UndefinedAtom &a) { _undefined.push_back(&a); }<br>
-  void addAtom(const SharedLibraryAtom &a) { _shared.push_back(&a); }<br>
-  void addAtom(const AbsoluteAtom &a) { _absolute.push_back(&a); }<br>
+  ~SimpleFile() override {<br>
+    _defined.clear();<br>
+    _undefined.clear();<br>
+    _shared.clear();<br>
+    _absolute.clear();<br>
+  }<br>
+<br>
+  void addAtom(DefinedAtom &a) {<br>
+    _defined.push_back(OwningAtomPtr<DefinedAtom>(&a));<br>
+  }<br>
+  void addAtom(UndefinedAtom &a) {<br>
+    _undefined.push_back(OwningAtomPtr<UndefinedAtom>(&a));<br>
+  }<br>
+  void addAtom(SharedLibraryAtom &a) {<br>
+    _shared.push_back(OwningAtomPtr<SharedLibraryAtom>(&a));<br>
+  }<br>
+  void addAtom(AbsoluteAtom &a) {<br>
+    _absolute.push_back(OwningAtomPtr<AbsoluteAtom>(&a));<br>
+  }<br>
<br>
   void addAtom(const Atom &atom) {<br>
     if (auto *p = dyn_cast<DefinedAtom>(&atom)) {<br>
-      _defined.push_back(p);<br>
+      addAtom(const_cast<DefinedAtom &>(*p));<br>
     } else if (auto *p = dyn_cast<UndefinedAtom>(&atom)) {<br>
-      _undefined.push_back(p);<br>
+      addAtom(const_cast<UndefinedAtom &>(*p));<br>
     } else if (auto *p = dyn_cast<SharedLibraryAtom>(&atom)) {<br>
-      _shared.push_back(p);<br>
+      addAtom(const_cast<SharedLibraryAtom &>(*p));<br>
     } else if (auto *p = dyn_cast<AbsoluteAtom>(&atom)) {<br>
-      _absolute.push_back(p);<br>
+      addAtom(const_cast<AbsoluteAtom &>(*p));<br>
     } else {<br>
       llvm_unreachable("atom has unknown definition kind");<br>
     }<br>
@@ -52,25 +67,35 @@ public:<br>
<br>
   void removeDefinedAtomsIf(std::function<bool(const DefinedAtom *)> pred) {<br>
     auto &atoms = _defined;<br>
-    auto newEnd = std::remove_if(atoms.begin(), atoms.end(), pred);<br>
+    auto newEnd = std::remove_if(atoms.begin(), atoms.end(),<br>
+                                 [&pred](OwningAtomPtr<DefinedAtom> &p) {<br>
+                                   return pred(p.get());<br>
+                                 });<br>
     atoms.erase(newEnd, atoms.end());<br>
   }<br>
<br>
-  const AtomVector<DefinedAtom> &defined() const override { return _defined; }<br>
+  const AtomRange<DefinedAtom> defined() const override { return _defined; }<br>
<br>
-  const AtomVector<UndefinedAtom> &undefined() const override {<br>
+  const AtomRange<UndefinedAtom> undefined() const override {<br>
     return _undefined;<br>
   }<br>
<br>
-  const AtomVector<SharedLibraryAtom> &sharedLibrary() const override {<br>
+  const AtomRange<SharedLibraryAtom> sharedLibrary() const override {<br>
     return _shared;<br>
   }<br>
<br>
-  const AtomVector<AbsoluteAtom> &absolute() const override {<br>
+  const AtomRange<AbsoluteAtom> absolute() const override {<br>
     return _absolute;<br>
   }<br>
<br>
-  typedef llvm::MutableArrayRef<const DefinedAtom *> DefinedAtomRange;<br>
+  void clearAtoms() override {<br>
+    _defined.clear();<br>
+    _undefined.clear();<br>
+    _shared.clear();<br>
+    _absolute.clear();<br>
+  }<br>
+<br>
+  typedef AtomRange<DefinedAtom> DefinedAtomRange;<br>
   DefinedAtomRange definedAtoms() { return _defined; }<br>
<br>
 private:<br>
@@ -169,6 +194,10 @@ public:<br>
     _references.setAllocator(&f.allocator());<br>
   }<br>
<br>
+  ~SimpleDefinedAtom() {<br>
+    _references.clearAndLeakNodesUnsafely();<br>
+  }<br>
+<br>
   const File &file() const override { return _file; }<br>
<br>
   StringRef name() const override { return StringRef(); }<br>
@@ -265,6 +294,8 @@ public:<br>
     assert(!name.empty() && "UndefinedAtoms must have a name");<br>
   }<br>
<br>
+  ~SimpleUndefinedAtom() override = default;<br>
+<br>
   /// file - returns the File that produced/owns this Atom<br>
   const File &file() const override { return _file; }<br>
<br>
<br>
Modified: lld/trunk/include/lld/Core/UndefinedAtom.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/lld/trunk/include/lld/Core/UndefinedAtom.h?rev=264022&r1=264021&r2=264022&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/lld/trunk/include/lld/Core/UndefinedAtom.h?rev=264022&r1=264021&r2=264022&view=diff</a><br>
==============================================================================<br>
--- lld/trunk/include/lld/Core/UndefinedAtom.h (original)<br>
+++ lld/trunk/include/lld/Core/UndefinedAtom.h Mon Mar 21 22:44:32 2016<br>
@@ -59,6 +59,8 @@ public:<br>
<br>
 protected:<br>
   UndefinedAtom() : Atom(definitionUndefined) {}<br>
+<br>
+  ~UndefinedAtom() override = default;<br>
 };<br>
<br>
 } // namespace lld<br>
<br>
Modified: lld/trunk/lib/Core/File.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/lld/trunk/lib/Core/File.cpp?rev=264022&r1=264021&r2=264022&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/lld/trunk/lib/Core/File.cpp?rev=264022&r1=264021&r2=264022&view=diff</a><br>
==============================================================================<br>
--- lld/trunk/lib/Core/File.cpp (original)<br>
+++ lld/trunk/lib/Core/File.cpp Mon Mar 21 22:44:32 2016<br>
@@ -13,7 +13,7 @@<br>
<br>
 namespace lld {<br>
<br>
-File::~File() {}<br>
+File::~File() { }<br>
<br>
 File::AtomVector<DefinedAtom> File::_noDefinedAtoms;<br>
 File::AtomVector<UndefinedAtom> File::_noUndefinedAtoms;<br>
<br>
Modified: lld/trunk/lib/Core/Resolver.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/lld/trunk/lib/Core/Resolver.cpp?rev=264022&r1=264021&r2=264022&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/lld/trunk/lib/Core/Resolver.cpp?rev=264022&r1=264021&r2=264022&view=diff</a><br>
==============================================================================<br>
--- lld/trunk/lib/Core/Resolver.cpp (original)<br>
+++ lld/trunk/lib/Core/Resolver.cpp Mon Mar 21 22:44:32 2016<br>
@@ -33,16 +33,16 @@ ErrorOr<bool> Resolver::handleFile(File<br>
   if (auto ec = _ctx.handleLoadedFile(file))<br>
     return ec;<br>
   bool undefAdded = false;<br>
-  for (const DefinedAtom *atom : file.defined())<br>
-    doDefinedAtom(*atom);<br>
-  for (const UndefinedAtom *atom : file.undefined()) {<br>
-    if (doUndefinedAtom(*atom))<br>
+  for (auto &atom : file.defined().owning_ptrs())<br>
+    doDefinedAtom(std::move(atom));<br>
+  for (auto &atom : file.undefined().owning_ptrs()) {<br>
+    if (doUndefinedAtom(std::move(atom)))<br>
       undefAdded = true;<br>
   }<br>
-  for (const SharedLibraryAtom *atom : file.sharedLibrary())<br>
-    doSharedLibraryAtom(*atom);<br>
-  for (const AbsoluteAtom *atom : file.absolute())<br>
-    doAbsoluteAtom(*atom);<br>
+  for (auto &atom : file.sharedLibrary().owning_ptrs())<br>
+    doSharedLibraryAtom(std::move(atom));<br>
+  for (auto &atom : file.absolute().owning_ptrs())<br>
+    doAbsoluteAtom(std::move(atom));<br>
   return undefAdded;<br>
 }<br>
<br>
@@ -113,9 +113,9 @@ std::error_code Resolver::handleSharedLi<br>
   undefAddedOrError = forEachUndefines(file, searchForOverrides,<br>
                                        [&](StringRef undefName,<br>
                                            bool dataSymbolOnly)->ErrorOr<bool> {<br>
-    if (const SharedLibraryAtom *atom =<br>
-            sharedLibrary->exports(undefName, dataSymbolOnly))<br>
-      doSharedLibraryAtom(*atom);<br>
+    auto atom = sharedLibrary->exports(undefName, dataSymbolOnly);<br>
+    if (atom.get())<br>
+      doSharedLibraryAtom(std::move(atom));<br>
     return false;<br>
   });<br>
<br>
@@ -124,84 +124,79 @@ std::error_code Resolver::handleSharedLi<br>
   return std::error_code();<br>
 }<br>
<br>
-bool Resolver::doUndefinedAtom(const UndefinedAtom &atom) {<br>
+bool Resolver::doUndefinedAtom(OwningAtomPtr<UndefinedAtom> atom) {<br>
   DEBUG_WITH_TYPE("resolver", llvm::dbgs()<br>
                     << "       UndefinedAtom: "<br>
-                    << llvm::format("0x%09lX", &atom)<br>
-                    << ", name=" << <a href="http://atom.name" rel="noreferrer" target="_blank">atom.name</a>() << "\n");<br>
-<br>
-  // add to list of known atoms<br>
-  _atoms.push_back(&atom);<br>
+                    << llvm::format("0x%09lX", atom.get())<br>
+                    << ", name=" << atom.get()->name() << "\n");<br>
<br>
   // tell symbol table<br>
-  bool newUndefAdded = _symbolTable.add(atom);<br>
+  bool newUndefAdded = _symbolTable.add(*atom.get());<br>
   if (newUndefAdded)<br>
-    _undefines.push_back(<a href="http://atom.name" rel="noreferrer" target="_blank">atom.name</a>());<br>
+    _undefines.push_back(atom.get()->name());<br>
+<br>
+  // add to list of known atoms<br>
+  _atoms.push_back(OwningAtomPtr<Atom>(atom.release()));<br>
<br>
   return newUndefAdded;<br>
 }<br>
<br>
 // Called on each atom when a file is added. Returns true if a given<br>
 // atom is added to the symbol table.<br>
-void Resolver::doDefinedAtom(const DefinedAtom &atom) {<br>
+void Resolver::doDefinedAtom(OwningAtomPtr<DefinedAtom> atom) {<br>
   DEBUG_WITH_TYPE("resolver", llvm::dbgs()<br>
                     << "         DefinedAtom: "<br>
-                    << llvm::format("0x%09lX", &atom)<br>
+                    << llvm::format("0x%09lX", atom.get())<br>
                     << ", file=#"<br>
-                    << atom.file().ordinal()<br>
+                    << atom.get()->file().ordinal()<br>
                     << ", atom=#"<br>
-                    << atom.ordinal()<br>
+                    << atom.get()->ordinal()<br>
                     << ", name="<br>
-                    << <a href="http://atom.name" rel="noreferrer" target="_blank">atom.name</a>()<br>
+                    << atom.get()->name()<br>
                     << ", type="<br>
-                    << atom.contentType()<br>
+                    << atom.get()->contentType()<br>
                     << "\n");<br>
<br>
-  // add to list of known atoms<br>
-  _atoms.push_back(&atom);<br>
-  _symbolTable.add(atom);<br>
-<br>
   // An atom that should never be dead-stripped is a dead-strip root.<br>
-  if (_ctx.deadStrip() && atom.deadStrip() == DefinedAtom::deadStripNever) {<br>
-    _deadStripRoots.insert(&atom);<br>
+  if (_ctx.deadStrip() &&<br>
+      atom.get()->deadStrip() == DefinedAtom::deadStripNever) {<br>
+    _deadStripRoots.insert(atom.get());<br>
   }<br>
+<br>
+  // add to list of known atoms<br>
+  _symbolTable.add(*atom.get());<br>
+  _atoms.push_back(OwningAtomPtr<Atom>(atom.release()));<br>
 }<br>
<br>
-void Resolver::doSharedLibraryAtom(const SharedLibraryAtom &atom) {<br>
+void Resolver::doSharedLibraryAtom(OwningAtomPtr<SharedLibraryAtom> atom) {<br>
   DEBUG_WITH_TYPE("resolver", llvm::dbgs()<br>
                     << "   SharedLibraryAtom: "<br>
-                    << llvm::format("0x%09lX", &atom)<br>
+                    << llvm::format("0x%09lX", atom.get())<br>
                     << ", name="<br>
-                    << <a href="http://atom.name" rel="noreferrer" target="_blank">atom.name</a>()<br>
+                    << atom.get()->name()<br>
                     << "\n");<br>
<br>
-  // add to list of known atoms<br>
-  _atoms.push_back(&atom);<br>
-<br>
   // tell symbol table<br>
-  _symbolTable.add(atom);<br>
+  _symbolTable.add(*atom.get());<br>
+<br>
+  // add to list of known atoms<br>
+  _atoms.push_back(OwningAtomPtr<Atom>(atom.release()));<br>
 }<br>
<br>
-void Resolver::doAbsoluteAtom(const AbsoluteAtom &atom) {<br>
+void Resolver::doAbsoluteAtom(OwningAtomPtr<AbsoluteAtom> atom) {<br>
   DEBUG_WITH_TYPE("resolver", llvm::dbgs()<br>
                     << "       AbsoluteAtom: "<br>
-                    << llvm::format("0x%09lX", &atom)<br>
+                    << llvm::format("0x%09lX", atom.get())<br>
                     << ", name="<br>
-                    << <a href="http://atom.name" rel="noreferrer" target="_blank">atom.name</a>()<br>
+                    << atom.get()->name()<br>
                     << "\n");<br>
<br>
-  // add to list of known atoms<br>
-  _atoms.push_back(&atom);<br>
-<br>
   // tell symbol table<br>
-  if (atom.scope() != Atom::scopeTranslationUnit)<br>
-    _symbolTable.add(atom);<br>
-}<br>
+  if (atom.get()->scope() != Atom::scopeTranslationUnit)<br>
+    _symbolTable.add(*atom.get());<br>
<br>
-// utility to add a vector of atoms<br>
-void Resolver::addAtoms(const std::vector<const DefinedAtom *> &newAtoms) {<br>
-  for (const DefinedAtom *newAtom : newAtoms)<br>
-    doDefinedAtom(*newAtom);<br>
+  // add to list of known atoms<br>
+  _atoms.push_back(OwningAtomPtr<Atom>(atom.release()));<br>
 }<br>
<br>
 // Returns true if at least one of N previous files has created an<br>
@@ -316,8 +311,8 @@ void Resolver::updateReferences() {<br>
   DEBUG_WITH_TYPE("resolver",<br>
                   llvm::dbgs() << "******** Updating references:\n");<br>
   ScopedTask task(getDefaultDomain(), "updateReferences");<br>
-  for (const Atom *atom : _atoms) {<br>
-    if (const DefinedAtom *defAtom = dyn_cast<DefinedAtom>(atom)) {<br>
+  for (const OwningAtomPtr<Atom> &atom : _atoms) {<br>
+    if (const DefinedAtom *defAtom = dyn_cast<DefinedAtom>(atom.get())) {<br>
       for (const Reference *ref : *defAtom) {<br>
         // A reference of type kindAssociate should't be updated.<br>
         // Instead, an atom having such reference will be removed<br>
@@ -325,7 +320,7 @@ void Resolver::updateReferences() {<br>
         // go away as a group.<br>
         if (ref->kindNamespace() == lld::Reference::KindNamespace::all &&<br>
             ref->kindValue() == lld::Reference::kindAssociate) {<br>
-          if (_symbolTable.isCoalescedAway(atom))<br>
+          if (_symbolTable.isCoalescedAway(atom.get()))<br>
             _deadAtoms.insert(ref->target());<br>
           continue;<br>
         }<br>
@@ -373,19 +368,19 @@ void Resolver::deadStripOptimize() {<br>
   // Make a reverse map of such references before traversing the graph.<br>
   // While traversing the list of atoms, mark AbsoluteAtoms as live<br>
   // in order to avoid reclaim.<br>
-  for (const Atom *atom : _atoms) {<br>
-    if (const DefinedAtom *defAtom = dyn_cast<DefinedAtom>(atom))<br>
+  for (const OwningAtomPtr<Atom> &atom : _atoms) {<br>
+    if (const DefinedAtom *defAtom = dyn_cast<DefinedAtom>(atom.get()))<br>
       for (const Reference *ref : *defAtom)<br>
         if (isBackref(ref))<br>
-          _reverseRef.insert(std::make_pair(ref->target(), atom));<br>
-    if (const AbsoluteAtom *absAtom = dyn_cast<AbsoluteAtom>(atom))<br>
+          _reverseRef.insert(std::make_pair(ref->target(), atom.get()));<br>
+    if (const AbsoluteAtom *absAtom = dyn_cast<AbsoluteAtom>(atom.get()))<br>
       markLive(absAtom);<br>
   }<br>
<br>
   // By default, shared libraries are built with all globals as dead strip roots<br>
   if (_ctx.globalsAreDeadStripRoots())<br>
-    for (const Atom *atom : _atoms)<br>
-      if (const DefinedAtom *defAtom = dyn_cast<DefinedAtom>(atom))<br>
+    for (const OwningAtomPtr<Atom> &atom : _atoms)<br>
+      if (const DefinedAtom *defAtom = dyn_cast<DefinedAtom>(atom.get()))<br>
         if (defAtom->scope() == DefinedAtom::scopeGlobal)<br>
           _deadStripRoots.insert(defAtom);<br>
<br>
@@ -401,8 +396,9 @@ void Resolver::deadStripOptimize() {<br>
     markLive(dsrAtom);<br>
<br>
   // now remove all non-live atoms from _atoms<br>
-  _atoms.erase(std::remove_if(_atoms.begin(), _atoms.end(), [&](const Atom *a) {<br>
-                 return _liveAtoms.count(a) == 0;<br>
+  _atoms.erase(std::remove_if(_atoms.begin(), _atoms.end(),<br>
+                              [&](OwningAtomPtr<Atom> &a) {<br>
+                 return _liveAtoms.count(a.get()) == 0;<br>
                }),<br>
                _atoms.end());<br>
 }<br>
@@ -461,8 +457,10 @@ void Resolver::removeCoalescedAwayAtoms(<br>
   DEBUG_WITH_TYPE("resolver",<br>
                   llvm::dbgs() << "******** Removing coalesced away atoms:\n");<br>
   ScopedTask task(getDefaultDomain(), "removeCoalescedAwayAtoms");<br>
-  _atoms.erase(std::remove_if(_atoms.begin(), _atoms.end(), [&](const Atom *a) {<br>
-                 return _symbolTable.isCoalescedAway(a) || _deadAtoms.count(a);<br>
+  _atoms.erase(std::remove_if(_atoms.begin(), _atoms.end(),<br>
+                              [&](OwningAtomPtr<Atom> &a) {<br>
+                 return _symbolTable.isCoalescedAway(a.get()) ||<br>
+                        _deadAtoms.count(a.get());<br>
                }),<br>
                _atoms.end());<br>
 }<br>
@@ -488,15 +486,16 @@ bool Resolver::resolve() {<br>
   return true;<br>
 }<br>
<br>
-void Resolver::MergedFile::addAtoms(std::vector<const Atom *> &all) {<br>
+void Resolver::MergedFile::addAtoms(<br>
+                              llvm::MutableArrayRef<OwningAtomPtr<Atom>> all) {<br>
   ScopedTask task(getDefaultDomain(), "addAtoms");<br>
   DEBUG_WITH_TYPE("resolver", llvm::dbgs() << "Resolver final atom list:\n");<br>
<br>
-  for (const Atom *atom : all) {<br>
+  for (OwningAtomPtr<Atom> &atom : all) {<br>
 #ifndef NDEBUG<br>
-    if (auto *definedAtom = dyn_cast<DefinedAtom>(atom)) {<br>
+    if (auto *definedAtom = dyn_cast<DefinedAtom>(atom.get())) {<br>
       DEBUG_WITH_TYPE("resolver", llvm::dbgs()<br>
-                      << llvm::format("    0x%09lX", atom)<br>
+                      << llvm::format("    0x%09lX", definedAtom)<br>
                       << ", file=#"<br>
                       << definedAtom->file().ordinal()<br>
                       << ", atom=#"<br>
@@ -508,13 +507,13 @@ void Resolver::MergedFile::addAtoms(std:<br>
                       << "\n");<br>
     } else {<br>
       DEBUG_WITH_TYPE("resolver", llvm::dbgs()<br>
-                      << llvm::format("    0x%09lX", atom)<br>
+                      << llvm::format("    0x%09lX", atom.get())<br>
                       << ", name="<br>
-                      << atom->name()<br>
+                      << atom.get()->name()<br>
                       << "\n");<br>
     }<br>
 #endif<br>
-    addAtom(*atom);<br>
+    addAtom(*atom.release());<br>
   }<br>
 }<br>
<br>
<br>
Modified: lld/trunk/lib/Driver/DarwinLdDriver.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/lld/trunk/lib/Driver/DarwinLdDriver.cpp?rev=264022&r1=264021&r2=264022&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/lld/trunk/lib/Driver/DarwinLdDriver.cpp?rev=264022&r1=264021&r2=264022&view=diff</a><br>
==============================================================================<br>
--- lld/trunk/lib/Driver/DarwinLdDriver.cpp (original)<br>
+++ lld/trunk/lib/Driver/DarwinLdDriver.cpp Mon Mar 21 22:44:32 2016<br>
@@ -1169,7 +1169,14 @@ bool link(llvm::ArrayRef<const char *> a<br>
   Resolver resolver(ctx);<br>
   if (!resolver.resolve())<br>
     return false;<br>
-  std::unique_ptr<SimpleFile> merged = resolver.resultFile();<br>
+  SimpleFile *merged = nullptr;<br>
+  {<br>
+    std::unique_ptr<SimpleFile> mergedFile = resolver.resultFile();<br>
+    merged = mergedFile.get();<br>
+    auto &members = ctx.getNodes();<br>
+    members.insert(members.begin(),<br>
+                   llvm::make_unique<FileNode>(std::move(mergedFile)));<br>
+  }<br>
   resolveTask.end();<br>
<br>
   // Run passes on linked atoms.<br>
<br>
Modified: lld/trunk/lib/ReaderWriter/FileArchive.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/FileArchive.cpp?rev=264022&r1=264021&r2=264022&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/FileArchive.cpp?rev=264022&r1=264021&r2=264022&view=diff</a><br>
==============================================================================<br>
--- lld/trunk/lib/ReaderWriter/FileArchive.cpp (original)<br>
+++ lld/trunk/lib/ReaderWriter/FileArchive.cpp Mon Mar 21 22:44:32 2016<br>
@@ -88,22 +88,29 @@ public:<br>
     return std::error_code();<br>
   }<br>
<br>
-  const AtomVector<DefinedAtom> &defined() const override {<br>
+  const AtomRange<DefinedAtom> defined() const override {<br>
     return _noDefinedAtoms;<br>
   }<br>
<br>
-  const AtomVector<UndefinedAtom> &undefined() const override {<br>
+  const AtomRange<UndefinedAtom> undefined() const override {<br>
     return _noUndefinedAtoms;<br>
   }<br>
<br>
-  const AtomVector<SharedLibraryAtom> &sharedLibrary() const override {<br>
+  const AtomRange<SharedLibraryAtom> sharedLibrary() const override {<br>
     return _noSharedLibraryAtoms;<br>
   }<br>
<br>
-  const AtomVector<AbsoluteAtom> &absolute() const override {<br>
+  const AtomRange<AbsoluteAtom> absolute() const override {<br>
     return _noAbsoluteAtoms;<br>
   }<br>
<br>
+  void clearAtoms() override {<br>
+    _noDefinedAtoms.clear();<br>
+    _noUndefinedAtoms.clear();<br>
+    _noSharedLibraryAtoms.clear();<br>
+    _noAbsoluteAtoms.clear();<br>
+  }<br>
+<br>
 protected:<br>
   std::error_code doParse() override {<br>
     // Make Archive object which will be owned by FileArchive object.<br>
<br>
Modified: lld/trunk/lib/ReaderWriter/MachO/ArchHandler_arm.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/MachO/ArchHandler_arm.cpp?rev=264022&r1=264021&r2=264022&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/MachO/ArchHandler_arm.cpp?rev=264022&r1=264021&r2=264022&view=diff</a><br>
==============================================================================<br>
--- lld/trunk/lib/ReaderWriter/MachO/ArchHandler_arm.cpp (original)<br>
+++ lld/trunk/lib/ReaderWriter/MachO/ArchHandler_arm.cpp Mon Mar 21 22:44:32 2016<br>
@@ -1429,6 +1429,8 @@ public:<br>
     _name = tmp.copy(file.allocator());<br>
   }<br>
<br>
+  ~Thumb2ToArmShimAtom() override = default;<br>
+<br>
   StringRef name() const override {<br>
     return _name;<br>
   }<br>
@@ -1472,6 +1474,8 @@ public:<br>
     _name = tmp.copy(file.allocator());<br>
   }<br>
<br>
+  ~ArmToThumbShimAtom() override = default;<br>
+<br>
   StringRef name() const override {<br>
     return _name;<br>
   }<br>
<br>
Modified: lld/trunk/lib/ReaderWriter/MachO/Atoms.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/MachO/Atoms.h?rev=264022&r1=264021&r2=264022&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/MachO/Atoms.h?rev=264022&r1=264021&r2=264022&view=diff</a><br>
==============================================================================<br>
--- lld/trunk/lib/ReaderWriter/MachO/Atoms.h (original)<br>
+++ lld/trunk/lib/ReaderWriter/MachO/Atoms.h Mon Mar 21 22:44:32 2016<br>
@@ -32,6 +32,8 @@ public:<br>
         _contentType(type), _scope(scope), _merge(mergeNo), _thumb(false),<br>
         _noDeadStrip(noDeadStrip) {}<br>
<br>
+  ~MachODefinedAtom() override = default;<br>
+<br>
   uint64_t size() const override { return _content.size(); }<br>
<br>
   ContentType contentType() const override { return _contentType; }<br>
@@ -83,6 +85,8 @@ public:<br>
                          content, align),<br>
         _sectionName(sectionName) {}<br>
<br>
+  ~MachODefinedCustomSectionAtom() override = default;<br>
+<br>
   SectionChoice sectionChoice() const override {<br>
     return DefinedAtom::sectionCustomRequired;<br>
   }<br>
@@ -101,6 +105,8 @@ public:<br>
       : SimpleDefinedAtom(f), _name(name), _scope(scope), _size(size),<br>
         _align(align) {}<br>
<br>
+  ~MachOTentativeDefAtom() override = default;<br>
+<br>
   uint64_t size() const override { return _size; }<br>
<br>
   Merge merge() const override { return DefinedAtom::mergeAsTentative; }<br>
<br>
Modified: lld/trunk/lib/ReaderWriter/MachO/CompactUnwindPass.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/MachO/CompactUnwindPass.cpp?rev=264022&r1=264021&r2=264022&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/MachO/CompactUnwindPass.cpp?rev=264022&r1=264021&r2=264022&view=diff</a><br>
==============================================================================<br>
--- lld/trunk/lib/ReaderWriter/MachO/CompactUnwindPass.cpp (original)<br>
+++ lld/trunk/lib/ReaderWriter/MachO/CompactUnwindPass.cpp Mon Mar 21 22:44:32 2016<br>
@@ -88,6 +88,8 @@ public:<br>
     addSecondLevelPages(pages);<br>
   }<br>
<br>
+  ~UnwindInfoAtom() override = default;<br>
+<br>
   ContentType contentType() const override {<br>
     return DefinedAtom::typeProcessedUnwindInfo;<br>
   }<br>
<br>
Modified: lld/trunk/lib/ReaderWriter/MachO/ExecutableAtoms.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/MachO/ExecutableAtoms.h?rev=264022&r1=264021&r2=264022&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/MachO/ExecutableAtoms.h?rev=264022&r1=264021&r2=264022&view=diff</a><br>
==============================================================================<br>
--- lld/trunk/lib/ReaderWriter/MachO/ExecutableAtoms.h (original)<br>
+++ lld/trunk/lib/ReaderWriter/MachO/ExecutableAtoms.h Mon Mar 21 22:44:32 2016<br>
@@ -122,21 +122,28 @@ public:<br>
           ArrayRef<uint8_t>(), DefinedAtom::Alignment(1)));<br>
   }<br>
<br>
-  const AtomVector<DefinedAtom> &defined() const override {<br>
+  const AtomRange<DefinedAtom> defined() const override {<br>
     return _definedAtoms;<br>
   }<br>
-  const AtomVector<UndefinedAtom> &undefined() const override {<br>
+  const AtomRange<UndefinedAtom> undefined() const override {<br>
     return _noUndefinedAtoms;<br>
   }<br>
<br>
-  const AtomVector<SharedLibraryAtom> &sharedLibrary() const override {<br>
+  const AtomRange<SharedLibraryAtom> sharedLibrary() const override {<br>
     return _noSharedLibraryAtoms;<br>
   }<br>
<br>
-  const AtomVector<AbsoluteAtom> &absolute() const override {<br>
+  const AtomRange<AbsoluteAtom> absolute() const override {<br>
     return _noAbsoluteAtoms;<br>
   }<br>
<br>
+  void clearAtoms() override {<br>
+    _definedAtoms.clear();<br>
+    _noUndefinedAtoms.clear();<br>
+    _noSharedLibraryAtoms.clear();<br>
+    _noAbsoluteAtoms.clear();<br>
+  }<br>
+<br>
<br>
 private:<br>
   mutable AtomVector<DefinedAtom> _definedAtoms;<br>
<br>
Modified: lld/trunk/lib/ReaderWriter/MachO/File.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/MachO/File.h?rev=264022&r1=264021&r2=264022&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/MachO/File.h?rev=264022&r1=264021&r2=264022&view=diff</a><br>
==============================================================================<br>
--- lld/trunk/lib/ReaderWriter/MachO/File.h (original)<br>
+++ lld/trunk/lib/ReaderWriter/MachO/File.h Mon Mar 21 22:44:32 2016<br>
@@ -275,7 +275,8 @@ public:<br>
<br>
   MachODylibFile(StringRef path) : SharedLibraryFile(path) {}<br>
<br>
-  const SharedLibraryAtom *exports(StringRef name, bool isData) const override {<br>
+  OwningAtomPtr<SharedLibraryAtom> exports(StringRef name,<br>
+                                           bool isData) const override {<br>
     // Pass down _installName so that if this requested symbol<br>
     // is re-exported through this dylib, the SharedLibraryAtom's loadName()<br>
     // is this dylib installName and not the implementation dylib's.<br>
@@ -328,25 +329,30 @@ public:<br>
   }<br>
<br>
 private:<br>
-  const SharedLibraryAtom *exports(StringRef name,<br>
+  OwningAtomPtr<SharedLibraryAtom> exports(StringRef name,<br>
                                    StringRef installName) const {<br>
     // First, check if requested symbol is directly implemented by this dylib.<br>
     auto entry = _nameToAtom.find(name);<br>
     if (entry != _nameToAtom.end()) {<br>
-      if (!entry->second.atom) {<br>
-        // Lazily create SharedLibraryAtom.<br>
-        entry->second.atom =<br>
-          new (allocator()) MachOSharedLibraryAtom(*this, name, installName,<br>
-                                                   entry->second.weakDef);<br>
-      }<br>
-      return entry->second.atom;<br>
+      // FIXME: Make this map a set and only used in assert builds.<br>
+      // Note, its safe to assert here as the resolver is the only client of<br>
+      // this API and it only requests exports for undefined symbols.<br>
+      // If we return from here we are no longer undefined so we should never<br>
+      // get here again.<br>
+      assert(!entry->second.atom && "Duplicate shared library export");<br>
+      bool weakDef = entry->second.weakDef;<br>
+      auto *atom = new (allocator()) MachOSharedLibraryAtom(*this, name,<br>
+                                                            installName,<br>
+                                                            weakDef);<br>
+      entry->second.atom = atom;<br>
+      return atom;<br>
     }<br>
<br>
     // Next, check if symbol is implemented in some re-exported dylib.<br>
     for (const ReExportedDylib &dylib : _reExportedDylibs) {<br>
       assert(dylib.file);<br>
       auto atom = dylib.file->exports(name, installName);<br>
-      if (atom)<br>
+      if (atom.get())<br>
         return atom;<br>
     }<br>
<br>
<br>
Modified: lld/trunk/lib/ReaderWriter/MachO/FlatNamespaceFile.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/MachO/FlatNamespaceFile.h?rev=264022&r1=264021&r2=264022&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/MachO/FlatNamespaceFile.h?rev=264022&r1=264021&r2=264022&view=diff</a><br>
==============================================================================<br>
--- lld/trunk/lib/ReaderWriter/MachO/FlatNamespaceFile.h (original)<br>
+++ lld/trunk/lib/ReaderWriter/MachO/FlatNamespaceFile.h Mon Mar 21 22:44:32 2016<br>
@@ -25,34 +25,35 @@ public:<br>
   FlatNamespaceFile(const MachOLinkingContext &context)<br>
     : SharedLibraryFile("flat namespace") { }<br>
<br>
-  const SharedLibraryAtom *exports(StringRef name,<br>
+  OwningAtomPtr<SharedLibraryAtom> exports(StringRef name,<br>
                                    bool dataSymbolOnly) const override {<br>
-    _sharedLibraryAtoms.push_back(<br>
-      new (allocator()) MachOSharedLibraryAtom(*this, name, getDSOName(),<br>
-                                               false));<br>
-<br>
-    return _sharedLibraryAtoms.back();<br>
+    return new (allocator()) MachOSharedLibraryAtom(*this, name, getDSOName(),<br>
+                                                    false);<br>
   }<br>
<br>
   StringRef getDSOName() const override { return "flat-namespace"; }<br>
<br>
-  const AtomVector<DefinedAtom> &defined() const override {<br>
+  const AtomRange<DefinedAtom> defined() const override {<br>
     return _noDefinedAtoms;<br>
   }<br>
-  const AtomVector<UndefinedAtom> &undefined() const override {<br>
+  const AtomRange<UndefinedAtom> undefined() const override {<br>
     return _noUndefinedAtoms;<br>
   }<br>
<br>
-  const AtomVector<SharedLibraryAtom> &sharedLibrary() const override {<br>
-    return _sharedLibraryAtoms;<br>
+  const AtomRange<SharedLibraryAtom> sharedLibrary() const override {<br>
+    return _noSharedLibraryAtoms;<br>
   }<br>
<br>
-  const AtomVector<AbsoluteAtom> &absolute() const override {<br>
+  const AtomRange<AbsoluteAtom> absolute() const override {<br>
     return _noAbsoluteAtoms;<br>
   }<br>
<br>
-private:<br>
-  mutable AtomVector<SharedLibraryAtom> _sharedLibraryAtoms;<br>
+  void clearAtoms() override {<br>
+    _noDefinedAtoms.clear();<br>
+    _noUndefinedAtoms.clear();<br>
+    _noSharedLibraryAtoms.clear();<br>
+    _noAbsoluteAtoms.clear();<br>
+  }<br>
 };<br>
<br>
 } // namespace mach_o<br>
<br>
Modified: lld/trunk/lib/ReaderWriter/MachO/GOTPass.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/MachO/GOTPass.cpp?rev=264022&r1=264021&r2=264022&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/MachO/GOTPass.cpp?rev=264022&r1=264021&r2=264022&view=diff</a><br>
==============================================================================<br>
--- lld/trunk/lib/ReaderWriter/MachO/GOTPass.cpp (original)<br>
+++ lld/trunk/lib/ReaderWriter/MachO/GOTPass.cpp Mon Mar 21 22:44:32 2016<br>
@@ -54,6 +54,8 @@ public:<br>
   GOTEntryAtom(const File &file, bool is64, StringRef name)<br>
     : SimpleDefinedAtom(file), _is64(is64), _name(name) { }<br>
<br>
+  ~GOTEntryAtom() override = default;<br>
+<br>
   ContentType contentType() const override {<br>
     return DefinedAtom::typeGOT;<br>
   }<br>
<br>
Modified: lld/trunk/lib/ReaderWriter/MachO/LayoutPass.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/MachO/LayoutPass.cpp?rev=264022&r1=264021&r2=264022&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/MachO/LayoutPass.cpp?rev=264022&r1=264021&r2=264022&view=diff</a><br>
==============================================================================<br>
--- lld/trunk/lib/ReaderWriter/MachO/LayoutPass.cpp (original)<br>
+++ lld/trunk/lib/ReaderWriter/MachO/LayoutPass.cpp Mon Mar 21 22:44:32 2016<br>
@@ -146,7 +146,7 @@ static void printDefinedAtoms(const Simp<br>
<br>
 /// Verify that the followon chain is sane. Should not be called in<br>
 /// release binary.<br>
-void LayoutPass::checkFollowonChain(SimpleFile::DefinedAtomRange &range) {<br>
+void LayoutPass::checkFollowonChain(const SimpleFile::DefinedAtomRange &range) {<br>
   ScopedTask task(getDefaultDomain(), "LayoutPass::checkFollowonChain");<br>
<br>
   // Verify that there's no cycle in follow-on chain.<br>
@@ -176,8 +176,8 @@ static bool compareAtomsSub(const Layout<br>
                             const LayoutPass::SortKey &rc,<br>
                             LayoutPass::SortOverride customSorter,<br>
                             std::string &reason) {<br>
-  const DefinedAtom *left = lc._atom;<br>
-  const DefinedAtom *right = rc._atom;<br>
+  const DefinedAtom *left = lc._atom.get();<br>
+  const DefinedAtom *right = rc._atom.get();<br>
   if (left == right) {<br>
     reason = "same";<br>
     return false;<br>
@@ -252,8 +252,9 @@ static bool compareAtoms(const LayoutPas<br>
   bool result = compareAtomsSub(lc, rc, customSorter, reason);<br>
   DEBUG({<br>
     StringRef comp = result ? "<" : ">=";<br>
-    llvm::dbgs() << "Layout: '" << lc._atom->name() << "' " << comp << " '"<br>
-                 << rc._atom->name() << "' (" << reason << ")\n";<br>
+    llvm::dbgs() << "Layout: '" << lc._atom.get()->name()<br>
+                 << "' " << comp << " '"<br>
+                 << rc._atom.get()->name() << "' (" << reason << ")\n";<br>
   });<br>
   return result;<br>
 }<br>
@@ -329,7 +330,7 @@ void LayoutPass::setChainRoot(const Defi<br>
 /// d) If the targetAtom is part of a different chain and the root of the<br>
 ///    targetAtom until the targetAtom has all atoms of size 0, then chain the<br>
 ///    targetAtoms and its tree to the current chain<br>
-void LayoutPass::buildFollowOnTable(SimpleFile::DefinedAtomRange &range) {<br>
+void LayoutPass::buildFollowOnTable(const SimpleFile::DefinedAtomRange &range) {<br>
   ScopedTask task(getDefaultDomain(), "LayoutPass::buildFollowOnTable");<br>
   // Set the initial size of the followon and the followonNext hash to the<br>
   // number of atoms that we have.<br>
@@ -397,7 +398,8 @@ void LayoutPass::buildFollowOnTable(Simp<br>
 /// assigning ordinals to each atom, if the atoms have their ordinals<br>
 /// already assigned skip the atom and move to the next. This is the<br>
 /// main map thats used to sort the atoms while comparing two atoms together<br>
-void LayoutPass::buildOrdinalOverrideMap(SimpleFile::DefinedAtomRange &range) {<br>
+void<br>
+LayoutPass::buildOrdinalOverrideMap(const SimpleFile::DefinedAtomRange &range) {<br>
   ScopedTask task(getDefaultDomain(), "LayoutPass::buildOrdinalOverrideMap");<br>
   uint64_t index = 0;<br>
   for (const DefinedAtom *ai : range) {<br>
@@ -419,12 +421,12 @@ void LayoutPass::buildOrdinalOverrideMap<br>
 std::vector<LayoutPass::SortKey><br>
 LayoutPass::decorate(SimpleFile::DefinedAtomRange &atomRange) const {<br>
   std::vector<SortKey> ret;<br>
-  for (const DefinedAtom *atom : atomRange) {<br>
-    auto ri = _followOnRoots.find(atom);<br>
-    auto oi = _ordinalOverrideMap.find(atom);<br>
-    const DefinedAtom *root = (ri == _followOnRoots.end()) ? atom : ri->second;<br>
+  for (OwningAtomPtr<DefinedAtom> &atom : atomRange.owning_ptrs()) {<br>
+    auto ri = _followOnRoots.find(atom.get());<br>
+    auto oi = _ordinalOverrideMap.find(atom.get());<br>
+    const auto *root = (ri == _followOnRoots.end()) ? atom.get() : ri->second;<br>
     uint64_t override = (oi == _ordinalOverrideMap.end()) ? 0 : oi->second;<br>
-    ret.push_back(SortKey(atom, root, override));<br>
+    ret.push_back(SortKey(std::move(atom), root, override));<br>
   }<br>
   return ret;<br>
 }<br>
@@ -433,7 +435,7 @@ void LayoutPass::undecorate(SimpleFile::<br>
                             std::vector<SortKey> &keys) const {<br>
   size_t i = 0;<br>
   for (SortKey &k : keys)<br>
-    atomRange[i++] = k._atom;<br>
+    atomRange[i++] = std::move(k._atom);<br>
 }<br>
<br>
 /// Perform the actual pass<br>
<br>
Modified: lld/trunk/lib/ReaderWriter/MachO/LayoutPass.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/MachO/LayoutPass.h?rev=264022&r1=264021&r2=264022&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/MachO/LayoutPass.h?rev=264022&r1=264021&r2=264022&view=diff</a><br>
==============================================================================<br>
--- lld/trunk/lib/ReaderWriter/MachO/LayoutPass.h (original)<br>
+++ lld/trunk/lib/ReaderWriter/MachO/LayoutPass.h Mon Mar 21 22:44:32 2016<br>
@@ -33,9 +33,10 @@ namespace mach_o {<br>
 class LayoutPass : public Pass {<br>
 public:<br>
   struct SortKey {<br>
-    SortKey(const DefinedAtom *atom, const DefinedAtom *root, uint64_t override)<br>
-        : _atom(atom), _root(root), _override(override) {}<br>
-    const DefinedAtom *_atom;<br>
+    SortKey(OwningAtomPtr<DefinedAtom> &&atom,<br>
+            const DefinedAtom *root, uint64_t override)<br>
+    : _atom(std::move(atom)), _root(root), _override(override) {}<br>
+    OwningAtomPtr<DefinedAtom> _atom;<br>
     const DefinedAtom *_root;<br>
     uint64_t _override;<br>
   };<br>
@@ -53,10 +54,10 @@ public:<br>
 private:<br>
   // Build the followOn atoms chain as specified by the kindLayoutAfter<br>
   // reference type<br>
-  void buildFollowOnTable(SimpleFile::DefinedAtomRange &range);<br>
+  void buildFollowOnTable(const SimpleFile::DefinedAtomRange &range);<br>
<br>
   // Build a map of Atoms to ordinals for sorting the atoms<br>
-  void buildOrdinalOverrideMap(SimpleFile::DefinedAtomRange &range);<br>
+  void buildOrdinalOverrideMap(const SimpleFile::DefinedAtomRange &range);<br>
<br>
   const Registry &_registry;<br>
   SortOverride _customSorter;<br>
@@ -85,11 +86,12 @@ private:<br>
   void setChainRoot(const DefinedAtom *targetAtom, const DefinedAtom *root);<br>
<br>
   std::vector<SortKey> decorate(SimpleFile::DefinedAtomRange &atomRange) const;<br>
+<br>
   void undecorate(SimpleFile::DefinedAtomRange &atomRange,<br>
                   std::vector<SortKey> &keys) const;<br>
<br>
   // Check if the follow-on graph is a correct structure. For debugging only.<br>
-  void checkFollowonChain(SimpleFile::DefinedAtomRange &range);<br>
+  void checkFollowonChain(const SimpleFile::DefinedAtomRange &range);<br>
 };<br>
<br>
 } // namespace mach_o<br>
<br>
Modified: lld/trunk/lib/ReaderWriter/MachO/MachOLinkingContext.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/MachO/MachOLinkingContext.cpp?rev=264022&r1=264021&r2=264022&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/MachO/MachOLinkingContext.cpp?rev=264022&r1=264021&r2=264022&view=diff</a><br>
==============================================================================<br>
--- lld/trunk/lib/ReaderWriter/MachO/MachOLinkingContext.cpp (original)<br>
+++ lld/trunk/lib/ReaderWriter/MachO/MachOLinkingContext.cpp Mon Mar 21 22:44:32 2016<br>
@@ -171,7 +171,19 @@ bool MachOLinkingContext::sliceFromFatFi<br>
<br>
 MachOLinkingContext::MachOLinkingContext() {}<br>
<br>
-MachOLinkingContext::~MachOLinkingContext() {}<br>
+MachOLinkingContext::~MachOLinkingContext() {<br>
+  // Atoms are allocated on BumpPtrAllocator's on File's.<br>
+  // As we transfer atoms from one file to another, we need to clear all of the<br>
+  // atoms before we remove any of the BumpPtrAllocator's.<br>
+  auto &nodes = getNodes();<br>
+  for (unsigned i = 0, e = nodes.size(); i != e; ++i) {<br>
+    FileNode *node = dyn_cast<FileNode>(nodes[i].get());<br>
+    if (!node)<br>
+      continue;<br>
+    File *file = node->getFile();<br>
+    file->clearAtoms();<br>
+  }<br>
+}<br>
<br>
 void MachOLinkingContext::configure(HeaderFileType type, Arch arch, OS os,<br>
                                     uint32_t minOSVersion,<br>
<br>
Modified: lld/trunk/lib/ReaderWriter/MachO/ObjCPass.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/MachO/ObjCPass.cpp?rev=264022&r1=264021&r2=264022&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/MachO/ObjCPass.cpp?rev=264022&r1=264021&r2=264022&view=diff</a><br>
==============================================================================<br>
--- lld/trunk/lib/ReaderWriter/MachO/ObjCPass.cpp (original)<br>
+++ lld/trunk/lib/ReaderWriter/MachO/ObjCPass.cpp Mon Mar 21 22:44:32 2016<br>
@@ -56,6 +56,8 @@ public:<br>
     Data.info.flags |= (swiftVersion << 8);<br>
   }<br>
<br>
+  ~ObjCImageInfoAtom() override = default;<br>
+<br>
   ContentType contentType() const override {<br>
     return DefinedAtom::typeObjCImageInfo;<br>
   }<br>
<br>
Modified: lld/trunk/lib/ReaderWriter/MachO/SectCreateFile.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/MachO/SectCreateFile.h?rev=264022&r1=264021&r2=264022&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/MachO/SectCreateFile.h?rev=264022&r1=264021&r2=264022&view=diff</a><br>
==============================================================================<br>
--- lld/trunk/lib/ReaderWriter/MachO/SectCreateFile.h (original)<br>
+++ lld/trunk/lib/ReaderWriter/MachO/SectCreateFile.h Mon Mar 21 22:44:32 2016<br>
@@ -31,6 +31,8 @@ public:<br>
         _combinedName((segName + "/" + sectName).str()),<br>
         _content(std::move(content)) {}<br>
<br>
+    ~SectCreateAtom() override = default;<br>
+<br>
     uint64_t size() const override { return _content->getBufferSize(); }<br>
<br>
     Scope scope() const override { return scopeGlobal; }<br>
@@ -67,22 +69,29 @@ public:<br>
       new (allocator()) SectCreateAtom(*this, seg, sect, std::move(content)));<br>
   }<br>
<br>
-  const AtomVector<DefinedAtom> &defined() const override {<br>
+  const AtomRange<DefinedAtom> defined() const override {<br>
     return _definedAtoms;<br>
   }<br>
<br>
-  const AtomVector<UndefinedAtom> &undefined() const override {<br>
+  const AtomRange<UndefinedAtom> undefined() const override {<br>
     return _noUndefinedAtoms;<br>
   }<br>
<br>
-  const AtomVector<SharedLibraryAtom> &sharedLibrary() const override {<br>
+  const AtomRange<SharedLibraryAtom> sharedLibrary() const override {<br>
     return _noSharedLibraryAtoms;<br>
   }<br>
<br>
-  const AtomVector<AbsoluteAtom> &absolute() const override {<br>
+  const AtomRange<AbsoluteAtom> absolute() const override {<br>
     return _noAbsoluteAtoms;<br>
   }<br>
<br>
+  void clearAtoms() override {<br>
+    _definedAtoms.clear();<br>
+    _noUndefinedAtoms.clear();<br>
+    _noSharedLibraryAtoms.clear();<br>
+    _noAbsoluteAtoms.clear();<br>
+  }<br>
+<br>
 private:<br>
   AtomVector<DefinedAtom> _definedAtoms;<br>
 };<br>
<br>
Modified: lld/trunk/lib/ReaderWriter/MachO/StubsPass.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/MachO/StubsPass.cpp?rev=264022&r1=264021&r2=264022&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/MachO/StubsPass.cpp?rev=264022&r1=264021&r2=264022&view=diff</a><br>
==============================================================================<br>
--- lld/trunk/lib/ReaderWriter/MachO/StubsPass.cpp (original)<br>
+++ lld/trunk/lib/ReaderWriter/MachO/StubsPass.cpp Mon Mar 21 22:44:32 2016<br>
@@ -37,6 +37,8 @@ public:<br>
   LazyPointerAtom(const File &file, bool is64)<br>
     : SimpleDefinedAtom(file), _is64(is64) { }<br>
<br>
+  ~LazyPointerAtom() override = default;<br>
+<br>
   ContentType contentType() const override {<br>
     return DefinedAtom::typeLazyPointer;<br>
   }<br>
@@ -71,6 +73,8 @@ public:<br>
   NonLazyPointerAtom(const File &file, bool is64, ContentType contentType)<br>
     : SimpleDefinedAtom(file), _is64(is64), _contentType(contentType) { }<br>
<br>
+  ~NonLazyPointerAtom() override = default;<br>
+<br>
   ContentType contentType() const override {<br>
     return _contentType;<br>
   }<br>
@@ -106,6 +110,8 @@ public:<br>
   StubAtom(const File &file, const ArchHandler::StubInfo &stubInfo)<br>
       : SimpleDefinedAtom(file), _stubInfo(stubInfo){ }<br>
<br>
+  ~StubAtom() override = default;<br>
+<br>
   ContentType contentType() const override {<br>
     return DefinedAtom::typeStub;<br>
   }<br>
@@ -138,6 +144,8 @@ public:<br>
   StubHelperAtom(const File &file, const ArchHandler::StubInfo &stubInfo)<br>
       : SimpleDefinedAtom(file), _stubInfo(stubInfo) { }<br>
<br>
+  ~StubHelperAtom() override = default;<br>
+<br>
   ContentType contentType() const override {<br>
     return DefinedAtom::typeStubHelper;<br>
   }<br>
@@ -171,6 +179,8 @@ public:<br>
   StubHelperCommonAtom(const File &file, const ArchHandler::StubInfo &stubInfo)<br>
       : SimpleDefinedAtom(file), _stubInfo(stubInfo) { }<br>
<br>
+  ~StubHelperCommonAtom() override = default;<br>
+<br>
   ContentType contentType() const override {<br>
     return DefinedAtom::typeStubHelper;<br>
   }<br>
<br>
Modified: lld/trunk/lib/ReaderWriter/MachO/TLVPass.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/MachO/TLVPass.cpp?rev=264022&r1=264021&r2=264022&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/MachO/TLVPass.cpp?rev=264022&r1=264021&r2=264022&view=diff</a><br>
==============================================================================<br>
--- lld/trunk/lib/ReaderWriter/MachO/TLVPass.cpp (original)<br>
+++ lld/trunk/lib/ReaderWriter/MachO/TLVPass.cpp Mon Mar 21 22:44:32 2016<br>
@@ -30,6 +30,8 @@ public:<br>
   TLVPEntryAtom(const File &file, bool is64, StringRef name)<br>
       : SimpleDefinedAtom(file), _is64(is64), _name(name) {}<br>
<br>
+  ~TLVPEntryAtom() override = default;<br>
+<br>
   ContentType contentType() const override {<br>
     return DefinedAtom::typeTLVInitializerPtr;<br>
   }<br>
<br>
Modified: lld/trunk/lib/ReaderWriter/YAML/ReaderWriterYAML.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/YAML/ReaderWriterYAML.cpp?rev=264022&r1=264021&r2=264022&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/YAML/ReaderWriterYAML.cpp?rev=264022&r1=264021&r2=264022&view=diff</a><br>
==============================================================================<br>
--- lld/trunk/lib/ReaderWriter/YAML/ReaderWriterYAML.cpp (original)<br>
+++ lld/trunk/lib/ReaderWriter/YAML/ReaderWriterYAML.cpp Mon Mar 21 22:44:32 2016<br>
@@ -195,7 +195,7 @@ private:<br>
<br>
 /// Mapping of Atoms.<br>
 template <typename T> class AtomList {<br>
-  typedef lld::File::AtomVector<T> Ty;<br>
+  using Ty = std::vector<OwningAtomPtr<T>>;<br>
<br>
 public:<br>
   typename Ty::iterator begin() { return _atoms.begin(); }<br>
@@ -503,10 +503,20 @@ template <> struct MappingTraits<ArchMem<br>
 // Declare that an AtomList is a yaml sequence.<br>
 template <typename T> struct SequenceTraits<AtomList<T> > {<br>
   static size_t size(IO &io, AtomList<T> &seq) { return seq._atoms.size(); }<br>
-  static const T *&element(IO &io, AtomList<T> &seq, size_t index) {<br>
+  static T *&element(IO &io, AtomList<T> &seq, size_t index) {<br>
     if (index >= seq._atoms.size())<br>
       seq._atoms.resize(index + 1);<br>
-    return seq._atoms[index];<br>
+    return seq._atoms[index].get();<br>
+  }<br>
+};<br>
+<br>
+// Declare that an AtomRange is a yaml sequence.<br>
+template <typename T> struct SequenceTraits<File::AtomRange<T> > {<br>
+  static size_t size(IO &io, File::AtomRange<T> &seq) { return seq.size(); }<br>
+  static T *&element(IO &io, File::AtomRange<T> &seq, size_t index) {<br>
+    assert(io.outputting() && "AtomRange only used when outputting");<br>
+    assert(index < seq.size() && "Out of range access");<br>
+    return seq[index].get();<br>
   }<br>
 };<br>
<br>
@@ -558,23 +568,29 @@ template <> struct MappingTraits<const l<br>
<br>
     const lld::File *denormalize(IO &io) { return this; }<br>
<br>
-    const AtomVector<lld::DefinedAtom> &defined() const override {<br>
+    const AtomRange<lld::DefinedAtom> defined() const override {<br>
       return _noDefinedAtoms;<br>
     }<br>
<br>
-    const AtomVector<lld::UndefinedAtom> &undefined() const override {<br>
+    const AtomRange<lld::UndefinedAtom> undefined() const override {<br>
       return _noUndefinedAtoms;<br>
     }<br>
<br>
-    const AtomVector<lld::SharedLibraryAtom> &<br>
-    sharedLibrary() const override {<br>
+    const AtomRange<lld::SharedLibraryAtom> sharedLibrary() const override {<br>
       return _noSharedLibraryAtoms;<br>
     }<br>
<br>
-    const AtomVector<lld::AbsoluteAtom> &absolute() const override {<br>
+    const AtomRange<lld::AbsoluteAtom> absolute() const override {<br>
       return _noAbsoluteAtoms;<br>
     }<br>
<br>
+    void clearAtoms() override {<br>
+      _noDefinedAtoms.clear();<br>
+      _noUndefinedAtoms.clear();<br>
+      _noSharedLibraryAtoms.clear();<br>
+      _noAbsoluteAtoms.clear();<br>
+    }<br>
+<br>
     File *find(StringRef name, bool dataSymbolOnly) override {<br>
       for (const ArchMember &member : _members) {<br>
         for (const lld::DefinedAtom *atom : member._content->defined()) {<br>
@@ -606,36 +622,46 @@ template <> struct MappingTraits<const l<br>
   class NormalizedFile : public lld::File {<br>
   public:<br>
     NormalizedFile(IO &io)<br>
-      : File("", kindNormalizedObject), _io(io), _rnb(nullptr) {}<br>
+      : File("", kindNormalizedObject), _io(io), _rnb(nullptr),<br>
+        _definedAtomsRef(_definedAtoms._atoms),<br>
+        _undefinedAtomsRef(_undefinedAtoms._atoms),<br>
+        _sharedLibraryAtomsRef(_sharedLibraryAtoms._atoms),<br>
+        _absoluteAtomsRef(_absoluteAtoms._atoms) {}<br>
     NormalizedFile(IO &io, const lld::File *file)<br>
         : File(file->path(), kindNormalizedObject), _io(io),<br>
-          _rnb(new RefNameBuilder(*file)), _path(file->path()) {<br>
-      for (const lld::DefinedAtom *a : file->defined())<br>
-        _definedAtoms._atoms.push_back(a);<br>
-      for (const lld::UndefinedAtom *a : file->undefined())<br>
-        _undefinedAtoms._atoms.push_back(a);<br>
-      for (const lld::SharedLibraryAtom *a : file->sharedLibrary())<br>
-        _sharedLibraryAtoms._atoms.push_back(a);<br>
-      for (const lld::AbsoluteAtom *a : file->absolute())<br>
-        _absoluteAtoms._atoms.push_back(a);<br>
+          _rnb(new RefNameBuilder(*file)), _path(file->path()),<br>
+        _definedAtomsRef(file->defined()),<br>
+        _undefinedAtomsRef(file->undefined()),<br>
+        _sharedLibraryAtomsRef(file->sharedLibrary()),<br>
+        _absoluteAtomsRef(file->absolute()) {<br>
+    }<br>
+<br>
+    ~NormalizedFile() override {<br>
     }<br>
+<br>
     const lld::File *denormalize(IO &io);<br>
<br>
-    const AtomVector<lld::DefinedAtom> &defined() const override {<br>
-      return _definedAtoms._atoms;<br>
+    const AtomRange<lld::DefinedAtom> defined() const override {<br>
+      return _definedAtomsRef;<br>
     }<br>
<br>
-    const AtomVector<lld::UndefinedAtom> &undefined() const override {<br>
-      return _undefinedAtoms._atoms;<br>
+    const AtomRange<lld::UndefinedAtom> undefined() const override {<br>
+      return _undefinedAtomsRef;<br>
     }<br>
<br>
-    const AtomVector<lld::SharedLibraryAtom> &<br>
-    sharedLibrary() const override {<br>
-      return _sharedLibraryAtoms._atoms;<br>
+    const AtomRange<lld::SharedLibraryAtom> sharedLibrary() const override {<br>
+      return _sharedLibraryAtomsRef;<br>
     }<br>
<br>
-    const AtomVector<lld::AbsoluteAtom> &absolute() const override {<br>
-      return _absoluteAtoms._atoms;<br>
+    const AtomRange<lld::AbsoluteAtom> absolute() const override {<br>
+      return _absoluteAtomsRef;<br>
+    }<br>
+<br>
+    void clearAtoms() override {<br>
+      _definedAtoms._atoms.clear();<br>
+      _undefinedAtoms._atoms.clear();<br>
+      _sharedLibraryAtoms._atoms.clear();<br>
+      _absoluteAtoms._atoms.clear();<br>
     }<br>
<br>
     // Allocate a new copy of this string in _storage, so the strings<br>
@@ -653,6 +679,10 @@ template <> struct MappingTraits<const l<br>
     AtomList<lld::UndefinedAtom>         _undefinedAtoms;<br>
     AtomList<lld::SharedLibraryAtom>     _sharedLibraryAtoms;<br>
     AtomList<lld::AbsoluteAtom>          _absoluteAtoms;<br>
+    AtomRange<lld::DefinedAtom>          _definedAtomsRef;<br>
+    AtomRange<lld::UndefinedAtom>        _undefinedAtomsRef;<br>
+    AtomRange<lld::SharedLibraryAtom>    _sharedLibraryAtomsRef;<br>
+    AtomRange<lld::AbsoluteAtom>         _absoluteAtomsRef;<br>
     llvm::BumpPtrAllocator               _storage;<br>
   };<br>
<br>
@@ -676,10 +706,18 @@ template <> struct MappingTraits<const l<br>
     info->_file = keys.operator->();<br>
<br>
     io.mapOptional("path",                 keys->_path);<br>
-    io.mapOptional("defined-atoms",        keys->_definedAtoms);<br>
-    io.mapOptional("undefined-atoms",      keys->_undefinedAtoms);<br>
-    io.mapOptional("shared-library-atoms", keys->_sharedLibraryAtoms);<br>
-    io.mapOptional("absolute-atoms",       keys->_absoluteAtoms);<br>
+<br>
+    if (io.outputting()) {<br>
+      io.mapOptional("defined-atoms",        keys->_definedAtomsRef);<br>
+      io.mapOptional("undefined-atoms",      keys->_undefinedAtomsRef);<br>
+      io.mapOptional("shared-library-atoms", keys->_sharedLibraryAtomsRef);<br>
+      io.mapOptional("absolute-atoms",       keys->_absoluteAtomsRef);<br>
+    } else {<br>
+      io.mapOptional("defined-atoms",        keys->_definedAtoms);<br>
+      io.mapOptional("undefined-atoms",      keys->_undefinedAtoms);<br>
+      io.mapOptional("shared-library-atoms", keys->_sharedLibraryAtoms);<br>
+      io.mapOptional("absolute-atoms",       keys->_absoluteAtoms);<br>
+    }<br>
   }<br>
<br>
   static void mappingArchive(IO &io, const lld::File *&file) {<br>
@@ -790,6 +828,9 @@ template <> struct MappingTraits<const l<br>
       for (uint8_t x : cont)<br>
         _content.push_back(x);<br>
     }<br>
+<br>
+    ~NormalizedAtom() override = default;<br>
+<br>
     const lld::DefinedAtom *denormalize(IO &io) {<br>
       YamlContext *info = reinterpret_cast<YamlContext *>(io.getContext());<br>
       assert(info != nullptr);<br>
@@ -938,6 +979,14 @@ template <> struct MappingTraits<const l<br>
   }<br>
 };<br>
<br>
+template <> struct MappingTraits<lld::DefinedAtom *> {<br>
+  static void mapping(IO &io, lld::DefinedAtom *&atom) {<br>
+    const lld::DefinedAtom *atomPtr = atom;<br>
+    MappingTraits<const lld::DefinedAtom *>::mapping(io, atomPtr);<br>
+    atom = const_cast<lld::DefinedAtom *>(atomPtr);<br>
+  }<br>
+};<br>
+<br>
 // YAML conversion for const lld::UndefinedAtom*<br>
 template <> struct MappingTraits<const lld::UndefinedAtom *> {<br>
<br>
@@ -950,6 +999,8 @@ template <> struct MappingTraits<const l<br>
         : _file(fileFromContext(io)), _name(atom->name()),<br>
           _canBeNull(atom->canBeNull()) {}<br>
<br>
+    ~NormalizedAtom() override = default;<br>
+<br>
     const lld::UndefinedAtom *denormalize(IO &io) {<br>
       YamlContext *info = reinterpret_cast<YamlContext *>(io.getContext());<br>
       assert(info != nullptr);<br>
@@ -993,6 +1044,14 @@ template <> struct MappingTraits<const l<br>
   }<br>
 };<br>
<br>
+template <> struct MappingTraits<lld::UndefinedAtom *> {<br>
+  static void mapping(IO &io, lld::UndefinedAtom *&atom) {<br>
+    const lld::UndefinedAtom *atomPtr = atom;<br>
+    MappingTraits<const lld::UndefinedAtom *>::mapping(io, atomPtr);<br>
+    atom = const_cast<lld::UndefinedAtom *>(atomPtr);<br>
+  }<br>
+};<br>
+<br>
 // YAML conversion for const lld::SharedLibraryAtom*<br>
 template <> struct MappingTraits<const lld::SharedLibraryAtom *> {<br>
<br>
@@ -1006,6 +1065,8 @@ template <> struct MappingTraits<const l<br>
           _loadName(atom->loadName()), _canBeNull(atom->canBeNullAtRuntime()),<br>
           _type(atom->type()), _size(atom->size()) {}<br>
<br>
+    ~NormalizedAtom() override = default;<br>
+<br>
     const lld::SharedLibraryAtom *denormalize(IO &io) {<br>
       YamlContext *info = reinterpret_cast<YamlContext *>(io.getContext());<br>
       assert(info != nullptr);<br>
@@ -1061,6 +1122,14 @@ template <> struct MappingTraits<const l<br>
   }<br>
 };<br>
<br>
+template <> struct MappingTraits<lld::SharedLibraryAtom *> {<br>
+  static void mapping(IO &io, lld::SharedLibraryAtom *&atom) {<br>
+    const lld::SharedLibraryAtom *atomPtr = atom;<br>
+    MappingTraits<const lld::SharedLibraryAtom *>::mapping(io, atomPtr);<br>
+    atom = const_cast<lld::SharedLibraryAtom *>(atomPtr);<br>
+  }<br>
+};<br>
+<br>
 // YAML conversion for const lld::AbsoluteAtom*<br>
 template <> struct MappingTraits<const lld::AbsoluteAtom *> {<br>
<br>
@@ -1071,6 +1140,9 @@ template <> struct MappingTraits<const l<br>
     NormalizedAtom(IO &io, const lld::AbsoluteAtom *atom)<br>
         : _file(fileFromContext(io)), _name(atom->name()),<br>
           _scope(atom->scope()), _value(atom->value()) {}<br>
+<br>
+    ~NormalizedAtom() override = default;<br>
+<br>
     const lld::AbsoluteAtom *denormalize(IO &io) {<br>
       YamlContext *info = reinterpret_cast<YamlContext *>(io.getContext());<br>
       assert(info != nullptr);<br>
@@ -1129,6 +1201,14 @@ template <> struct MappingTraits<const l<br>
   }<br>
 };<br>
<br>
+template <> struct MappingTraits<lld::AbsoluteAtom *> {<br>
+  static void mapping(IO &io, lld::AbsoluteAtom *&atom) {<br>
+    const lld::AbsoluteAtom *atomPtr = atom;<br>
+    MappingTraits<const lld::AbsoluteAtom *>::mapping(io, atomPtr);<br>
+    atom = const_cast<lld::AbsoluteAtom *>(atomPtr);<br>
+  }<br>
+};<br>
+<br>
 } // namespace llvm<br>
 } // namespace yaml<br>
<br>
<br>
<br>
_______________________________________________<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/mailman/listinfo/llvm-commits</a><br>
</blockquote></div><br></div></div>