Sources now require C++11 to build.

Add first linker pass (StubsPass) which looks for calls to shared library
symbols and replaces them with calls to a StubAtom.  On ELF system, a "stub"
is a PLT entry.  Added a simple test case.

Pass a Platform object to YAML reader and writer for converting fixup kinds 
between names and values.

Change output of Resolver to be a File object instead of a vector of Atoms.
Thus, passes operate on a File instead of just Atoms.

Rework how to walk through a File's Atoms. Now iterator based instead of 
a method that visits each atom.  

llvm-svn: 152269
diff --git a/lld/lib/Core/NativeReader.cpp b/lld/lib/Core/NativeReader.cpp
index e85d2ff..0eb95b94 100644
--- a/lld/lib/Core/NativeReader.cpp
+++ b/lld/lib/Core/NativeReader.cpp
@@ -92,9 +92,15 @@
   }
   
   virtual llvm::ArrayRef<uint8_t> rawContent() const;
-    
-  virtual void forEachReference(ReferenceHandler&) const;
-   
+  
+  virtual reference_iterator referencesBegin() const;
+  
+  virtual reference_iterator referencesEnd() const;
+
+  virtual const Reference* derefIterator(const void*) const;
+  
+  virtual void incrementIterator(const void*& it) const;
+
 private:
   const NativeAtomAttributesV1& attributes() const;
   
@@ -299,53 +305,29 @@
     // the _definedAtoms array which was allocated to contain an array
     // of Atom objects.  The atoms have empty destructors, so it is ok
     // to just delete the memory.
-    delete _definedAtoms.arrayStart;
-    delete _undefinedAtoms.arrayStart;
-    delete _sharedLibraryAtoms.arrayStart;
-    delete _absoluteAtoms.arrayStart;
+    delete _definedAtoms._arrayStart;
+    delete _undefinedAtoms._arrayStart;
+    delete _sharedLibraryAtoms._arrayStart;
+    delete _absoluteAtoms._arrayStart;
     delete _references.arrayStart;
     delete _targetsTable;
   }
   
-  // visits each atom in the file
-  virtual bool forEachAtom(AtomHandler& handler) const {
-    bool didSomething = false;
-    for(const uint8_t* p=_definedAtoms.arrayStart; p != _definedAtoms.arrayEnd; 
-          p += _definedAtoms.elementSize) {
-      const DefinedAtom* atom = reinterpret_cast<const DefinedAtom*>(p);
-      handler.doDefinedAtom(*atom);
-      didSomething = true;
-    }
-    for(const uint8_t* p=_undefinedAtoms.arrayStart; 
-                      p != _undefinedAtoms.arrayEnd; 
-                      p += _undefinedAtoms.elementSize) {
-      const UndefinedAtom* atom = reinterpret_cast<const UndefinedAtom*>(p);
-      handler.doUndefinedAtom(*atom);
-      didSomething = true;
-    }
-    for(const uint8_t* p=_sharedLibraryAtoms.arrayStart; 
-                  p != _sharedLibraryAtoms.arrayEnd; 
-                  p += _sharedLibraryAtoms.elementSize) {
-      const SharedLibraryAtom* atom 
-                          = reinterpret_cast<const SharedLibraryAtom*>(p);
-      handler.doSharedLibraryAtom(*atom);
-      didSomething = true;
-    }
-    for(const uint8_t* p=_absoluteAtoms.arrayStart; 
-                  p != _absoluteAtoms.arrayEnd; 
-                  p += _absoluteAtoms.elementSize) {
-      const AbsoluteAtom* atom 
-                          = reinterpret_cast<const AbsoluteAtom*>(p);
-      handler.doAbsoluteAtom(*atom);
-      didSomething = true;
-    }
-    return didSomething;
+  virtual const atom_collection<DefinedAtom>&  defined() const {
+    return _definedAtoms;
   }
-  
-  // not used
-  virtual bool justInTimeforEachAtom(llvm::StringRef name,
-                                              AtomHandler &) const {
-    return false;
+  virtual const atom_collection<UndefinedAtom>& undefined() const {
+      return _undefinedAtoms;
+  }
+  virtual const atom_collection<SharedLibraryAtom>& sharedLibrary() const {
+      return _sharedLibraryAtoms;
+  }
+  virtual const atom_collection<AbsoluteAtom>& absolute() const {
+      return _absoluteAtoms;
+  }
+
+  virtual void addAtom(const Atom&) {
+    assert(0 && "cannot add atoms to native .o files");
   }
   
 private:
@@ -378,10 +360,10 @@
       new (atomAllocSpace) NativeDefinedAtomV1(*this, ivarData);
       ++ivarData;
     }
-    this->_definedAtoms.arrayStart = atomsStart;
-    this->_definedAtoms.arrayEnd = atomsEnd;
-    this->_definedAtoms.elementSize = atomSize;
-    this->_definedAtoms.elementCount = chunk->elementCount;
+    this->_definedAtoms._arrayStart = atomsStart;
+    this->_definedAtoms._arrayEnd = atomsEnd;
+    this->_definedAtoms._elementSize = atomSize;
+    this->_definedAtoms._elementCount = chunk->elementCount;
     return make_error_code(native_reader_error::success);
   }
   
@@ -416,10 +398,10 @@
       new (atomAllocSpace) NativeUndefinedAtomV1(*this, ivarData);
       ++ivarData;
     }
-    this->_undefinedAtoms.arrayStart = atomsStart;
-    this->_undefinedAtoms.arrayEnd = atomsEnd;
-    this->_undefinedAtoms.elementSize = atomSize;
-    this->_undefinedAtoms.elementCount = chunk->elementCount;
+    this->_undefinedAtoms._arrayStart = atomsStart;
+    this->_undefinedAtoms._arrayEnd = atomsEnd;
+    this->_undefinedAtoms._elementSize = atomSize;
+    this->_undefinedAtoms._elementCount = chunk->elementCount;
     return make_error_code(native_reader_error::success);
   }
   
@@ -447,10 +429,10 @@
       new (atomAllocSpace) NativeSharedLibraryAtomV1(*this, ivarData);
       ++ivarData;
     }
-    this->_sharedLibraryAtoms.arrayStart = atomsStart;
-    this->_sharedLibraryAtoms.arrayEnd = atomsEnd;
-    this->_sharedLibraryAtoms.elementSize = atomSize;
-    this->_sharedLibraryAtoms.elementCount = chunk->elementCount;
+    this->_sharedLibraryAtoms._arrayStart = atomsStart;
+    this->_sharedLibraryAtoms._arrayEnd = atomsEnd;
+    this->_sharedLibraryAtoms._elementSize = atomSize;
+    this->_sharedLibraryAtoms._elementCount = chunk->elementCount;
     return make_error_code(native_reader_error::success);
   }
   
@@ -478,10 +460,10 @@
       new (atomAllocSpace) NativeAbsoluteAtomV1(*this, ivarData);
       ++ivarData;
     }
-    this->_absoluteAtoms.arrayStart = atomsStart;
-    this->_absoluteAtoms.arrayEnd = atomsEnd;
-    this->_absoluteAtoms.elementSize = atomSize;
-    this->_absoluteAtoms.elementCount = chunk->elementCount;
+    this->_absoluteAtoms._arrayStart = atomsStart;
+    this->_absoluteAtoms._arrayEnd = atomsEnd;
+    this->_absoluteAtoms._elementSize = atomSize;
+    this->_absoluteAtoms._elementCount = chunk->elementCount;
     return make_error_code(native_reader_error::success);
   }
   
@@ -529,33 +511,33 @@
     this->_targetsTable = new const Atom*[chunk->elementCount];
     for (uint32_t i=0; i < chunk->elementCount; ++i) {
       const uint32_t index = targetIndexes[i];
-      if ( index < _definedAtoms.elementCount ) {
-        const uint8_t* p = _definedAtoms.arrayStart 
-                                    + index * _definedAtoms.elementSize;
+      if ( index < _definedAtoms._elementCount ) {
+        const uint8_t* p = _definedAtoms._arrayStart 
+                                    + index * _definedAtoms._elementSize;
         this->_targetsTable[i] = reinterpret_cast<const DefinedAtom*>(p);
         continue;
       }
-      const uint32_t undefIndex = index - _definedAtoms.elementCount;
-      if ( undefIndex < _undefinedAtoms.elementCount ) {
-        const uint8_t* p = _undefinedAtoms.arrayStart 
-                                    + undefIndex * _undefinedAtoms.elementSize;
+      const uint32_t undefIndex = index - _definedAtoms._elementCount;
+      if ( undefIndex < _undefinedAtoms._elementCount ) {
+        const uint8_t* p = _undefinedAtoms._arrayStart 
+                                    + undefIndex * _undefinedAtoms._elementSize;
         this->_targetsTable[i] = reinterpret_cast<const UndefinedAtom*>(p);
         continue;
       }
-      const uint32_t slIndex = index - _definedAtoms.elementCount 
-                                     - _undefinedAtoms.elementCount;
-      if ( slIndex < _sharedLibraryAtoms.elementCount ) {
-        const uint8_t* p = _sharedLibraryAtoms.arrayStart 
-                                  + slIndex * _sharedLibraryAtoms.elementSize;
+      const uint32_t slIndex = index - _definedAtoms._elementCount 
+                                     - _undefinedAtoms._elementCount;
+      if ( slIndex < _sharedLibraryAtoms._elementCount ) {
+        const uint8_t* p = _sharedLibraryAtoms._arrayStart 
+                                  + slIndex * _sharedLibraryAtoms._elementSize;
         this->_targetsTable[i] = reinterpret_cast<const SharedLibraryAtom*>(p);
         continue;
       }
-      const uint32_t abIndex = index - _definedAtoms.elementCount 
-                                     - _undefinedAtoms.elementCount
-                                     - _sharedLibraryAtoms.elementCount;
-      if ( abIndex < _absoluteAtoms.elementCount ) {
-        const uint8_t* p = _absoluteAtoms.arrayStart 
-                                  + slIndex * _absoluteAtoms.elementSize;
+      const uint32_t abIndex = index - _definedAtoms._elementCount 
+                                     - _undefinedAtoms._elementCount
+                                     - _sharedLibraryAtoms._elementCount;
+      if ( abIndex < _absoluteAtoms._elementCount ) {
+        const uint8_t* p = _absoluteAtoms._arrayStart 
+                                  + slIndex * _absoluteAtoms._elementSize;
         this->_targetsTable[i] = reinterpret_cast<const AbsoluteAtom*>(p);
         continue;
       }
@@ -612,21 +594,13 @@
     assert((result+size) <= _contentEnd);
     return result;
   }
-
-  void forEachReference(DefinedAtom::ReferenceHandler& handler, 
-                                        uint32_t start, uint32_t count) const {
-    assert(start < _references.elementCount);
-    assert(start+count <= _references.elementCount);
-    const uint8_t* arrStart = _references.arrayStart 
-                                   + start * _references.elementSize;
-    const uint8_t* arrEnd = arrStart + count * _references.elementSize;
-    for(const uint8_t* p=arrStart; p != arrEnd; p += _references.elementSize) {
-      const NativeReferenceV1* ref 
-                              = reinterpret_cast<const NativeReferenceV1*>(p);
-      handler.doReference(*ref);
-    }
-  }
   
+  const Reference* referenceByIndex(uintptr_t index) const {
+    assert(index < _references.elementCount);
+    const uint8_t* p = _references.arrayStart + index * _references.elementSize;
+    return reinterpret_cast<const NativeReferenceV1*>(p);
+  }
+
   const Atom* target(uint32_t index) const {
     assert(index < _targetsTableCount);
     return _targetsTable[index];
@@ -656,21 +630,52 @@
                                                   (_buffer->getBufferStart());
   }
 
+  template <typename T>
+  class AtomArray : public File::atom_collection<T> {
+  public:
+     AtomArray() : _arrayStart(NULL), _arrayEnd(NULL), 
+                   _elementSize(0), _elementCount(0) { }
+                                    
+    virtual atom_iterator<T> begin() const { 
+      return atom_iterator<T>(*this, reinterpret_cast<const void*>(_arrayStart));
+    }
+    virtual atom_iterator<T> end() const{ 
+      return atom_iterator<T>(*this, reinterpret_cast<const void*>(_arrayEnd));
+    }
+    virtual const T* deref(const void* it) const {
+      return reinterpret_cast<const T*>(it);
+    }
+    virtual void next(const void*& it) const {
+      const uint8_t* p = reinterpret_cast<const uint8_t*>(it);
+      p += _elementSize;
+      it = reinterpret_cast<const void*>(p);
+    }
+    const uint8_t*     _arrayStart;
+    const uint8_t*     _arrayEnd;
+    uint32_t           _elementSize;
+    uint32_t           _elementCount;
+  };
+
   struct IvarArray {
-                      IvarArray() : arrayStart(NULL), arrayEnd(NULL), 
-                                    elementSize(0), elementCount(0) { }
+                      IvarArray() : 
+                        arrayStart(NULL), 
+                        arrayEnd(NULL), 
+                        elementSize(0), 
+                        elementCount(0) { } 
+    
     const uint8_t*     arrayStart;
     const uint8_t*     arrayEnd;
     uint32_t           elementSize;
     uint32_t           elementCount;
- };
+  };
+
 
   llvm::OwningPtr<llvm::MemoryBuffer>  _buffer;
   const NativeFileHeader*         _header;
-  IvarArray                       _definedAtoms;
-  IvarArray                       _undefinedAtoms;
-  IvarArray                       _sharedLibraryAtoms;
-  IvarArray                       _absoluteAtoms;
+  AtomArray<DefinedAtom>          _definedAtoms;
+  AtomArray<UndefinedAtom>        _undefinedAtoms;
+  AtomArray<SharedLibraryAtom>    _sharedLibraryAtoms;
+  AtomArray<AbsoluteAtom>         _absoluteAtoms;
   const uint8_t*                  _attributes;
   uint32_t                        _attributesMaxOffset;
   IvarArray                       _references;
@@ -684,14 +689,14 @@
   const uint8_t*                  _contentEnd;
 };
 
- 
+
 inline const class File& NativeDefinedAtomV1::file() const {
   return *_file;
 }
 
 inline uint64_t NativeDefinedAtomV1:: ordinal() const {
   const uint8_t* p = reinterpret_cast<const uint8_t*>(_ivarData);
-  return p - _file->_definedAtoms.arrayStart;
+  return p - _file->_definedAtoms._arrayStart;
 }
 
 inline llvm::StringRef NativeDefinedAtomV1::name() const {
@@ -715,11 +720,27 @@
   return _file->string(offset);
 }
 
-inline void NativeDefinedAtomV1::forEachReference(ReferenceHandler& hnd) const {
-  if ( _ivarData->referencesCount == 0 )
-    return;
-  _file->forEachReference(hnd, _ivarData->referencesStartIndex, 
-                               _ivarData->referencesCount);
+DefinedAtom::reference_iterator NativeDefinedAtomV1::referencesBegin() const {
+  uintptr_t index = _ivarData->referencesStartIndex;
+  const void* it = reinterpret_cast<const void*>(index);
+  return reference_iterator(*this, it);
+}
+  
+DefinedAtom::reference_iterator NativeDefinedAtomV1::referencesEnd() const {
+  uintptr_t index = _ivarData->referencesStartIndex+_ivarData->referencesCount;
+  const void* it = reinterpret_cast<const void*>(index);
+  return reference_iterator(*this, it);
+}
+
+const Reference* NativeDefinedAtomV1::derefIterator(const void* it) const {
+  uintptr_t index = reinterpret_cast<uintptr_t>(it);
+  return _file->referenceByIndex(index);
+}
+  
+void NativeDefinedAtomV1::incrementIterator(const void*& it) const {
+  uintptr_t index = reinterpret_cast<uintptr_t>(it);
+  ++index;
+  it = reinterpret_cast<const void*>(index);
 }
 
 inline const class File& NativeUndefinedAtomV1::file() const {