[lld] r264022 - Use owning pointers instead of raw pointers for Atom's to fix leaks.

David Blaikie via llvm-commits llvm-commits at lists.llvm.org
Mon Mar 21 21:05:03 PDT 2016


On Mon, Mar 21, 2016 at 8:44 PM, Pete Cooper via llvm-commits <
llvm-commits at lists.llvm.org> wrote:

> Author: pete
> Date: Mon Mar 21 22:44:32 2016
> New Revision: 264022
>
> URL: http://llvm.org/viewvc/llvm-project?rev=264022&view=rev
> Log:
> Use owning pointers instead of raw pointers for Atom's to fix leaks.
>
> Currently each File contains an BumpPtrAllocator in which Atom's are
> allocated.  Some Atom's contain data structures like std::vector which
> leak as we don't run ~Atom when they are BumpPtrAllocate'd.
>

FWIW, if the only thing allocated in the BumpPtrAllocator is Atoms, you
could use a SpecificBumpPtrAllocator, which does run the dtors.

(& if the BumpPtrAllocator doesn't contain only Atoms, you could change it
so it does)


>
> Now each File actually owns its Atom's using an OwningAtomPtr.  This
> is analygous to std::unique_ptr and may be replaced by it if possible.
>

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.


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


More information about the llvm-commits mailing list