[llvm-commits] [lld] r149962 - in /lld/trunk: include/lld/Core/Atom.h include/lld/Core/NativeReader.h include/lld/Core/UndefinedAtom.h lib/Core/NativeFileFormat.h lib/Core/NativeReader.cpp lib/Core/NativeWriter.cpp lib/Core/Resolver.cpp lib/Core/YamlKeyValues.cpp lib/Core/YamlKeyValues.h lib/Core/YamlReader.cpp lib/Core/YamlWriter.cpp test/undef-coalesce.objtxt tools/lld-core/lld-core.cpp

Nick Kledzik kledzik at apple.com
Mon Feb 6 18:59:54 PST 2012


Author: kledzik
Date: Mon Feb  6 20:59:54 2012
New Revision: 149962

URL: http://llvm.org/viewvc/llvm-project?rev=149962&view=rev
Log:
Add support for UndefinedAtom in yaml and native format.  Add test cases with undefined atoms

Added:
    lld/trunk/test/undef-coalesce.objtxt
Modified:
    lld/trunk/include/lld/Core/Atom.h
    lld/trunk/include/lld/Core/NativeReader.h
    lld/trunk/include/lld/Core/UndefinedAtom.h
    lld/trunk/lib/Core/NativeFileFormat.h
    lld/trunk/lib/Core/NativeReader.cpp
    lld/trunk/lib/Core/NativeWriter.cpp
    lld/trunk/lib/Core/Resolver.cpp
    lld/trunk/lib/Core/YamlKeyValues.cpp
    lld/trunk/lib/Core/YamlKeyValues.h
    lld/trunk/lib/Core/YamlReader.cpp
    lld/trunk/lib/Core/YamlWriter.cpp
    lld/trunk/tools/lld-core/lld-core.cpp

Modified: lld/trunk/include/lld/Core/Atom.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/include/lld/Core/Atom.h?rev=149962&r1=149961&r2=149962&view=diff
==============================================================================
--- lld/trunk/include/lld/Core/Atom.h (original)
+++ lld/trunk/include/lld/Core/Atom.h Mon Feb  6 20:59:54 2012
@@ -20,6 +20,7 @@
 
 class File;
 class DefinedAtom;
+class UndefinedAtom;
 
 ///
 /// The linker has a Graph Theory model of linking. An object file is seen
@@ -53,6 +54,10 @@
   /// returns atom cast to DefinedAtom*, else returns nullptr;
   virtual const DefinedAtom* definedAtom() const { return 0; }
 
+  /// undefinedAtom - like dynamic_cast, if atom is definitionUndefined
+  /// returns atom cast to UndefinedAtom*, else returns NULL;
+  virtual const UndefinedAtom* undefinedAtom() const { return NULL; }
+  
 protected:
   /// Atom is an abstract base class.  Only subclasses can access constructor.
   Atom() {}

Modified: lld/trunk/include/lld/Core/NativeReader.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/include/lld/Core/NativeReader.h?rev=149962&r1=149961&r2=149962&view=diff
==============================================================================
--- lld/trunk/include/lld/Core/NativeReader.h (original)
+++ lld/trunk/include/lld/Core/NativeReader.h Mon Feb  6 20:59:54 2012
@@ -12,6 +12,8 @@
 
 #include "lld/Core/File.h"
 
+#include "llvm/ADT/OwningPtr.h"
+
 #include "llvm/Support/system_error.h"
 
 #include <vector>
@@ -26,13 +28,14 @@
   /// parseNativeObjectFileOrSTDIN - Open the specified native object file (use 
   /// stdin if the path is "-") and instantiate into an lld::File object.
   llvm::error_code parseNativeObjectFileOrSTDIN(llvm::StringRef path
-                                 , File*&);
+                                              , llvm::OwningPtr<File>& result);
 
 
   /// parseNativeObjectFile - Parse the specified native object file 
   /// (in a buffer) and instantiate into an lld::File object.
-  llvm::error_code parseNativeObjectFile(llvm::MemoryBuffer* mb, 
-                                       llvm::StringRef path, File*& result);
+  llvm::error_code parseNativeObjectFile(llvm::OwningPtr<llvm::MemoryBuffer>& mb
+                                        ,llvm::StringRef path
+                                        ,llvm::OwningPtr<File>& result);
 
 } // namespace lld
 

Modified: lld/trunk/include/lld/Core/UndefinedAtom.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/include/lld/Core/UndefinedAtom.h?rev=149962&r1=149961&r2=149962&view=diff
==============================================================================
--- lld/trunk/include/lld/Core/UndefinedAtom.h (original)
+++ lld/trunk/include/lld/Core/UndefinedAtom.h Mon Feb  6 20:59:54 2012
@@ -20,31 +20,22 @@
 /// It exists as a place holder for a future atom.
 class UndefinedAtom : public Atom {
 public:
-  UndefinedAtom(llvm::StringRef nm, bool weakImport, const File& f)
-          : _name(nm), _file(f), _weakImport(weakImport) {}
-
-  virtual const File& file() const {
-    return _file;
-  }
-
-  virtual llvm::StringRef name() const {
-    return _name;
-  }
-
   virtual Definition definition() const {
     return Atom::definitionUndefined;
   }
 
-  virtual bool weakImport() const {
-    return _weakImport;
+  /// like dynamic_cast, if atom is definitionUndefined
+  /// returns atom cast to UndefinedAtom*, else returns NULL
+  virtual const UndefinedAtom* undefinedAtom() const { 
+    return this;
   }
 
+  /// returns if undefined symbol can be missing at runtime
+  virtual bool weakImport() const = 0;
+  
 protected:
+           UndefinedAtom() {}
   virtual ~UndefinedAtom() {}
-
-  llvm::StringRef _name;
-  const File&     _file;
-  bool            _weakImport;
 };
 
 } // namespace lld

Modified: lld/trunk/lib/Core/NativeFileFormat.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/Core/NativeFileFormat.h?rev=149962&r1=149961&r2=149962&view=diff
==============================================================================
--- lld/trunk/lib/Core/NativeFileFormat.h (original)
+++ lld/trunk/lib/Core/NativeFileFormat.h Mon Feb  6 20:59:54 2012
@@ -88,9 +88,10 @@
 enum NativeChunkSignatures {
   NCS_DefinedAtomsV1 = 1,
   NCS_AttributesArrayV1 = 2,
-  NCS_Content = 3,
+  NCS_UndefinedAtomsV1 = 3,
   NCS_Strings = 4,
-  NCS_ReferencesArray = 5,
+  NCS_Content = 5,
+  NCS_ReferencesArray = 6,
 }; 
 
 //
@@ -152,6 +153,16 @@
 
 
 
+//
+// The NCS_UndefinedAtomsV1 chunk contains an array of these structs
+//
+struct NativeUndefinedAtomIvarsV1 {
+  uint32_t  nameOffset;
+  uint32_t  flags;
+};
+
+
+
 
 
 

Modified: lld/trunk/lib/Core/NativeReader.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/Core/NativeReader.cpp?rev=149962&r1=149961&r2=149962&view=diff
==============================================================================
--- lld/trunk/lib/Core/NativeReader.cpp (original)
+++ lld/trunk/lib/Core/NativeReader.cpp Mon Feb  6 20:59:54 2012
@@ -65,7 +65,8 @@
   }
 
   virtual DefinedAtom::ContentType contentType() const {
-    return (DefinedAtom::ContentType)(attributes().contentType);
+    const NativeAtomAttributesV1& attr = attributes();
+    return (DefinedAtom::ContentType)(attr.contentType);
   }
     
   virtual DefinedAtom::Alignment alignment() const {
@@ -113,6 +114,29 @@
 
 
 
+//
+// An object of this class is instantied for each NativeUndefinedAtomIvarsV1
+// struct in the NCS_UndefinedAtomsV1 chunk.
+//
+class NativeUndefinedAtomV1 : public UndefinedAtom {
+public:
+       NativeUndefinedAtomV1(const NativeFile& f, 
+                             const NativeUndefinedAtomIvarsV1* ivarData)
+        : _file(&f), _ivarData(ivarData) { } 
+
+  virtual const File& file() const;
+  virtual llvm::StringRef name() const;
+  
+  virtual bool weakImport() const {
+    return (_ivarData->flags & 0x1);
+  }
+  
+private:
+  const NativeFile*                 _file;
+  const NativeUndefinedAtomIvarsV1* _ivarData;
+};
+
+
 
 //
 // lld::File object for native llvm object file
@@ -122,8 +146,9 @@
 
   /// Instantiates a File object from a native object file.  Ownership
   /// of the MemoryBuffer is transfered to the resulting File object.
-  static llvm::error_code make(llvm::MemoryBuffer* mb, llvm::StringRef path, 
-                                                                File*& result) {
+  static llvm::error_code make(llvm::OwningPtr<llvm::MemoryBuffer>& mb, 
+                               llvm::StringRef path, 
+                               llvm::OwningPtr<File>& result) {
     const uint8_t* const base = 
                        reinterpret_cast<const uint8_t*>(mb->getBufferStart());
     const NativeFileHeader* const header = 
@@ -159,6 +184,9 @@
         case NCS_AttributesArrayV1:
           ec = file->processAttributesV1(base, chunk);
           break;
+        case NCS_UndefinedAtomsV1:
+          ec = file->processUndefinedAtomsV1(base, chunk);
+          break;
         case NCS_Content:
           ec = file->processContent(base, chunk);
           break;
@@ -175,7 +203,7 @@
       
       // TO DO: validate enough chunks were used
       
-      result = file;
+      result.reset(file);
     }
 
 
@@ -183,13 +211,14 @@
   }
   
   virtual ~NativeFile() {
-    // The NativeFile owns the MemoryBuffer and must not delete it.
-    delete _buffer;
+    // _buffer is automatically deleted because of OwningPtr<>
+    
     // All other ivar pointers are pointers into the MemoryBuffer, except
     // 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;
   }
   
   // visits each atom in the file
@@ -199,6 +228,11 @@
       const DefinedAtom* atom = reinterpret_cast<const DefinedAtom*>(p);
       handler.doDefinedAtom(*atom);
     }
+    for(const uint8_t* p=_undefinedAtoms.arrayStart; p != _undefinedAtoms.arrayEnd; 
+          p += _undefinedAtoms.elementSize) {
+      const UndefinedAtom* atom = reinterpret_cast<const UndefinedAtom*>(p);
+      handler.doUndefinedAtom(*atom);
+    }
     return (_definedAtoms.arrayStart != _definedAtoms.arrayEnd);
   }
   
@@ -210,6 +244,7 @@
   
 private:
   friend class NativeDefinedAtomV1;
+  friend class NativeUndefinedAtomV1;
   
   // instantiate array of DefinedAtoms from v1 ivar data in file
   llvm::error_code processDefinedAtomsV1(const uint8_t* base, 
@@ -247,6 +282,34 @@
     return make_error_code(native_reader_error::success);
   }
   
+  llvm::error_code processUndefinedAtomsV1(const uint8_t* base, 
+                                                const NativeChunk* chunk) {
+    const size_t atomSize = sizeof(NativeUndefinedAtomV1);
+    size_t atomsArraySize = chunk->elementCount * atomSize;
+    uint8_t* atomsStart = reinterpret_cast<uint8_t*>
+                                (operator new(atomsArraySize, std::nothrow));
+    if (atomsStart == NULL )
+      return make_error_code(native_reader_error::memory_error);
+    const size_t ivarElementSize = chunk->fileSize 
+                                          / chunk->elementCount;
+    if ( ivarElementSize != sizeof(NativeUndefinedAtomIvarsV1) )
+      return make_error_code(native_reader_error::file_malformed);
+    uint8_t* atomsEnd = atomsStart + atomsArraySize;
+    const NativeUndefinedAtomIvarsV1* ivarData = 
+                            reinterpret_cast<const NativeUndefinedAtomIvarsV1*>
+                                                  (base + chunk->fileOffset);
+    for(uint8_t* s = atomsStart; s != atomsEnd; s += atomSize) {
+      NativeUndefinedAtomV1* atomAllocSpace = 
+                  reinterpret_cast<NativeUndefinedAtomV1*>(s);
+      new (atomAllocSpace) NativeUndefinedAtomV1(*this, ivarData);
+      ++ivarData;
+    }
+    this->_undefinedAtoms.arrayStart = atomsStart;
+    this->_undefinedAtoms.arrayEnd = atomsEnd;
+    this->_undefinedAtoms.elementSize = atomSize;
+    return make_error_code(native_reader_error::success);
+  }
+  
   // set up pointers to string pool in file
   llvm::error_code processStrings(const uint8_t* base, 
                                                 const NativeChunk* chunk) {
@@ -281,12 +344,18 @@
 
 
   // private constructor, only called by make()
-  NativeFile(llvm::MemoryBuffer* mb, llvm::StringRef path) :
-    lld::File(path), _buffer(mb), _header(NULL), 
-    _strings(NULL), _stringsMaxOffset(0),
-    _contentStart(NULL), _contentEnd(NULL)
+  NativeFile(llvm::OwningPtr<llvm::MemoryBuffer>& mb, llvm::StringRef path) :
+    lld::File(path), 
+    _buffer(mb.take()),  // NativeFile now takes ownership of buffer
+    _header(NULL), 
+    _strings(NULL), 
+    _stringsMaxOffset(0),
+    _contentStart(NULL), 
+    _contentEnd(NULL)
   {
-    _header = reinterpret_cast<const NativeFileHeader*>(mb->getBufferStart());
+    _header = reinterpret_cast<const NativeFileHeader*>(_buffer->getBufferStart());
+    _definedAtoms.arrayStart = NULL;
+    _undefinedAtoms.arrayStart = NULL;
   }
 
   struct AtomArray {
@@ -297,9 +366,10 @@
     uint32_t           elementSize;
   };
 
-  llvm::MemoryBuffer*             _buffer;
+  llvm::OwningPtr<llvm::MemoryBuffer>  _buffer;
   const NativeFileHeader*         _header;
   AtomArray                       _definedAtoms;
+  AtomArray                       _undefinedAtoms;
   const uint8_t*                  _attributes;
   uint32_t                        _attributesMaxOffset;
   const char*                     _strings;
@@ -342,11 +412,24 @@
 
 
 
+
+inline const class File& NativeUndefinedAtomV1::file() const {
+  return *_file;
+}
+
+inline llvm::StringRef NativeUndefinedAtomV1::name() const {
+  return _file->string(_ivarData->nameOffset);
+}
+
+
+
+
 //
 // Instantiate an lld::File from the given native object file buffer
 //
-llvm::error_code parseNativeObjectFile(llvm::MemoryBuffer* mb, 
-                                       llvm::StringRef path, File*& result) {
+llvm::error_code parseNativeObjectFile(llvm::OwningPtr<llvm::MemoryBuffer>& mb, 
+                                       llvm::StringRef path, 
+                                       llvm::OwningPtr<File>& result) {
   return NativeFile::make(mb, path, result);
 }
 
@@ -356,13 +439,13 @@
 // Instantiate an lld::File from the given native object file path
 //
 llvm::error_code parseNativeObjectFileOrSTDIN(llvm::StringRef path, 
-                                              File*& result) {
+                                              llvm::OwningPtr<File>& result) {
   llvm::OwningPtr<llvm::MemoryBuffer> mb;
   llvm::error_code ec = llvm::MemoryBuffer::getFileOrSTDIN(path, mb);
   if ( ec ) 
       return ec;
 
-  return parseNativeObjectFile(mb.take(), path, result);
+  return parseNativeObjectFile(mb, path, result);
 }
 
 

Modified: lld/trunk/lib/Core/NativeWriter.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/Core/NativeWriter.cpp?rev=149962&r1=149961&r2=149962&view=diff
==============================================================================
--- lld/trunk/lib/Core/NativeWriter.cpp (original)
+++ lld/trunk/lib/Core/NativeWriter.cpp Mon Feb  6 20:59:54 2012
@@ -44,10 +44,13 @@
     if (!_attributes.empty())
       out.write((char*)&_attributes[0],
                 _attributes.size()*sizeof(NativeAtomAttributesV1));
-    if (!_contentPool.empty())
-      out.write((char*)&_contentPool[0], _contentPool.size());
+    if ( !_undefinedAtomIvars.empty() ) 
+      out.write((char*)&_undefinedAtomIvars[0], 
+              _undefinedAtomIvars.size()*sizeof(NativeUndefinedAtomIvarsV1));
     if (!_stringPool.empty())
       out.write(&_stringPool[0], _stringPool.size());
+    if (!_contentPool.empty())
+      out.write((char*)&_contentPool[0], _contentPool.size());
   }
 
 private:
@@ -64,15 +67,22 @@
   
   // visitor routine called by forEachAtom() 
   virtual void doUndefinedAtom(const class UndefinedAtom& atom) {
+    NativeUndefinedAtomIvarsV1 ivar;
+    ivar.nameOffset = getNameOffset(atom);
+    ivar.flags = (atom.weakImport() ? 1 : 0);
+    _undefinedAtomIvars.push_back(ivar);
   }
   
   // visitor routine called by forEachAtom() 
   virtual void doFile(const class File &) {
   }
-  
+
   // fill out native file header and chunk directory
   void makeHeader() {
-    _headerBufferSize = sizeof(NativeFileHeader) + 4*sizeof(NativeChunk);
+    const bool hasUndefines = !_undefinedAtomIvars.empty();
+    const int chunkCount = hasUndefines ? 5 : 4;
+    _headerBufferSize = sizeof(NativeFileHeader) 
+                         + chunkCount*sizeof(NativeChunk);
     _headerBuffer = reinterpret_cast<NativeFileHeader*>
                                (operator new(_headerBufferSize, std::nothrow));
     NativeChunk *chunks =
@@ -82,39 +92,59 @@
     _headerBuffer->endian = NFH_LittleEndian;
     _headerBuffer->architecture = 0;
     _headerBuffer->fileSize = 0;
-    _headerBuffer->chunkCount = 4;
+    _headerBuffer->chunkCount = chunkCount;
+    
     
     // create chunk for atom ivar array
-    NativeChunk& ch0 = chunks[0];
-    ch0.signature = NCS_DefinedAtomsV1;
-    ch0.fileOffset = _headerBufferSize;
-    ch0.fileSize = _definedAtomIvars.size()*sizeof(NativeDefinedAtomIvarsV1);
-    ch0.elementCount = _definedAtomIvars.size();
-    // create chunk for attributes
-    NativeChunk& ch1 = chunks[1];
-    ch1.signature = NCS_AttributesArrayV1;
-    ch1.fileOffset = ch0.fileOffset + ch0.fileSize;
-    ch1.fileSize = _attributes.size()*sizeof(NativeAtomAttributesV1);
-    ch1.elementCount = _attributes.size();
-    // create chunk for content
-    NativeChunk& ch2 = chunks[2];
-    ch2.signature = NCS_Content;
-    ch2.fileOffset = ch1.fileOffset + ch1.fileSize;
-    ch2.fileSize = _contentPool.size();
-    ch2.elementCount = _contentPool.size();
+    int nextIndex = 0;
+    NativeChunk& chd = chunks[nextIndex++];
+    chd.signature = NCS_DefinedAtomsV1;
+    chd.fileOffset = _headerBufferSize;
+    chd.fileSize = _definedAtomIvars.size()*sizeof(NativeDefinedAtomIvarsV1);
+    chd.elementCount = _definedAtomIvars.size();
+    uint32_t nextFileOffset = chd.fileOffset + chd.fileSize;
+
+    // create chunk for attributes 
+    NativeChunk& cha = chunks[nextIndex++];
+    cha.signature = NCS_AttributesArrayV1;
+    cha.fileOffset = nextFileOffset;
+    cha.fileSize = _attributes.size()*sizeof(NativeAtomAttributesV1);
+    cha.elementCount = _attributes.size();
+    nextFileOffset = cha.fileOffset + cha.fileSize;
+    
+    // create chunk for undefined atom array
+    if ( hasUndefines ) {
+      NativeChunk& chu = chunks[nextIndex++];
+      chu.signature = NCS_UndefinedAtomsV1;
+      chu.fileOffset = nextFileOffset;
+      chu.fileSize = _undefinedAtomIvars.size() * 
+                                            sizeof(NativeUndefinedAtomIvarsV1);
+      chu.elementCount = _undefinedAtomIvars.size();
+      nextFileOffset = chu.fileOffset + chu.fileSize;
+    }
+    
     // create chunk for symbol strings
-    NativeChunk& ch3 = chunks[3];
-    ch3.signature = NCS_Strings;
-    ch3.fileOffset = ch2.fileOffset + ch2.fileSize;
-    ch3.fileSize = _stringPool.size();
-    ch3.elementCount = _stringPool.size();
+    NativeChunk& chs = chunks[nextIndex++];
+    chs.signature = NCS_Strings;
+    chs.fileOffset = nextFileOffset;
+    chs.fileSize = _stringPool.size();
+    chs.elementCount = _stringPool.size();
+    nextFileOffset = chs.fileOffset + chs.fileSize;
     
-    _headerBuffer->fileSize = ch3.fileOffset + ch3.fileSize;
+    // create chunk for content 
+    NativeChunk& chc = chunks[nextIndex++];
+    chc.signature = NCS_Content;
+    chc.fileOffset = nextFileOffset;
+    chc.fileSize = _contentPool.size();
+    chc.elementCount = _contentPool.size();
+    nextFileOffset = chc.fileOffset + chc.fileSize;
+
+    _headerBuffer->fileSize = nextFileOffset;
   }
 
 
   // append atom name to string pool and return offset
-  uint32_t getNameOffset(const class DefinedAtom& atom) {
+  uint32_t getNameOffset(const Atom& atom) {
     return this->getNameOffset(atom.name());
   }
   
@@ -190,14 +220,15 @@
 
   typedef std::vector<std::pair<llvm::StringRef, uint32_t> > NameToOffsetVector;
 
-  const lld::File&                      _file;
-  NativeFileHeader*                     _headerBuffer;
-  size_t                                _headerBufferSize;
-  std::vector<char>                     _stringPool;
-  std::vector<uint8_t>                  _contentPool;
-  std::vector<NativeDefinedAtomIvarsV1> _definedAtomIvars;
-  std::vector<NativeAtomAttributesV1>   _attributes;
-  NameToOffsetVector                    _sectionNames;
+  const lld::File&                        _file;
+  NativeFileHeader*                       _headerBuffer;
+  size_t                                  _headerBufferSize;
+  std::vector<char>                       _stringPool;
+  std::vector<uint8_t>                    _contentPool;
+  std::vector<NativeDefinedAtomIvarsV1>   _definedAtomIvars;
+  std::vector<NativeAtomAttributesV1>     _attributes;
+  std::vector<NativeUndefinedAtomIvarsV1> _undefinedAtomIvars;
+  NameToOffsetVector                      _sectionNames;
 };
 
 

Modified: lld/trunk/lib/Core/Resolver.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/Core/Resolver.cpp?rev=149962&r1=149961&r2=149962&view=diff
==============================================================================
--- lld/trunk/lib/Core/Resolver.cpp (original)
+++ lld/trunk/lib/Core/Resolver.cpp Mon Feb  6 20:59:54 2012
@@ -33,7 +33,7 @@
     // don't remove if live
     if ( _liveAtoms.count(atom) )
       return false;
-	// don't remove if marked never-dead-strip
+   // don't remove if marked never-dead-strip
     if ( const DefinedAtom* defAtom = atom->definedAtom() ) {
       if ( defAtom->deadStrip() == DefinedAtom::deadStripNever )
         return false;

Modified: lld/trunk/lib/Core/YamlKeyValues.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/Core/YamlKeyValues.cpp?rev=149962&r1=149961&r2=149962&view=diff
==============================================================================
--- lld/trunk/lib/Core/YamlKeyValues.cpp (original)
+++ lld/trunk/lib/Core/YamlKeyValues.cpp Mon Feb  6 20:59:54 2012
@@ -31,7 +31,8 @@
 const char* const KeyValues::sectionNameKeyword     = "section-name";
 const char* const KeyValues::contentKeyword         = "content";
 const char* const KeyValues::sizeKeyword            = "size";
-const char* const KeyValues::permissionsKeyword      = "permissions";
+const char* const KeyValues::permissionsKeyword     = "permissions";
+const char* const KeyValues::weakImportKeyword      = "weak-import";
 
 
 const DefinedAtom::Definition         KeyValues::definitionDefault = Atom::definitionRegular;
@@ -45,27 +46,28 @@
 const bool                            KeyValues::internalNameDefault = false;
 const bool                            KeyValues::isThumbDefault = false;
 const bool                            KeyValues::isAliasDefault = false;
+const bool                            KeyValues::weakImportDefault = false;
 
 
 
 
 
 struct DefinitionMapping {
-	const char*       string;
-	Atom::Definition  value;
+  const char*       string;
+  Atom::Definition  value;
 };
 
 static const DefinitionMapping defMappings[] = {
-	{ "regular",        Atom::definitionRegular },
-	{ "absolute",       Atom::definitionAbsolute },
-	{ "undefined",      Atom::definitionUndefined },
-	{ "shared-library", Atom::definitionSharedLibrary },
+  { "regular",        Atom::definitionRegular },
+  { "absolute",       Atom::definitionAbsolute },
+  { "undefined",      Atom::definitionUndefined },
+  { "shared-library", Atom::definitionSharedLibrary },
   { NULL,             Atom::definitionRegular }
 };
 
 Atom::Definition KeyValues::definition(const char* s)
 {
-	for (const DefinitionMapping* p = defMappings; p->string != NULL; ++p) {
+  for (const DefinitionMapping* p = defMappings; p->string != NULL; ++p) {
     if ( strcmp(p->string, s) == 0 )
       return p->value;
   }
@@ -73,7 +75,7 @@
 }
 
 const char* KeyValues::definition(Atom::Definition s) {
-	for (const DefinitionMapping* p = defMappings; p->string != NULL; ++p) {
+  for (const DefinitionMapping* p = defMappings; p->string != NULL; ++p) {
     if ( p->value == s )
       return p->string;
   }
@@ -85,20 +87,20 @@
 
 
 struct ScopeMapping {
-	const char* string;
-	DefinedAtom::Scope value;
+  const char* string;
+  DefinedAtom::Scope value;
 };
 
 static const ScopeMapping scopeMappings[] = {
-	{ "global", DefinedAtom::scopeGlobal },
-	{ "hidden", DefinedAtom::scopeLinkageUnit },
-	{ "static", DefinedAtom::scopeTranslationUnit },
+  { "global", DefinedAtom::scopeGlobal },
+  { "hidden", DefinedAtom::scopeLinkageUnit },
+  { "static", DefinedAtom::scopeTranslationUnit },
   { NULL,     DefinedAtom::scopeGlobal }
 };
   
 DefinedAtom::Scope KeyValues::scope(const char* s)
 {
-	for (const ScopeMapping* p = scopeMappings; p->string != NULL; ++p) {
+  for (const ScopeMapping* p = scopeMappings; p->string != NULL; ++p) {
     if ( strcmp(p->string, s) == 0 )
       return p->value;
   }
@@ -106,7 +108,7 @@
 }
 
 const char* KeyValues::scope(DefinedAtom::Scope s) {
-	for (const ScopeMapping* p = scopeMappings; p->string != NULL; ++p) {
+  for (const ScopeMapping* p = scopeMappings; p->string != NULL; ++p) {
     if ( p->value == s )
       return p->string;
   }
@@ -121,41 +123,41 @@
 
 
 struct ContentTypeMapping {
-	const char*       string;
-	DefinedAtom::ContentType  value;
+  const char*       string;
+  DefinedAtom::ContentType  value;
 };
 
 static const ContentTypeMapping typeMappings[] = {
-	{ "unknown",        DefinedAtom::typeUnknown },
-	{ "code",           DefinedAtom::typeCode },
-	{ "resolver",       DefinedAtom::typeResolver },
-	{ "constant",       DefinedAtom::typeConstant },
-	{ "c-string",       DefinedAtom::typeCString },
-	{ "utf16-string",   DefinedAtom::typeUTF16String },
-	{ "CFI",            DefinedAtom::typeCFI },
-	{ "LSDA",           DefinedAtom::typeLSDA },
-	{ "literal-4",      DefinedAtom::typeLiteral4 },
-	{ "literal-8",      DefinedAtom::typeLiteral8 },
-	{ "literal-16",     DefinedAtom::typeLiteral16 },
-	{ "data",           DefinedAtom::typeData },
-	{ "zero-fill",      DefinedAtom::typeZeroFill },
-	{ "cf-string",      DefinedAtom::typeCFString },
-	{ "initializer-ptr",DefinedAtom::typeInitializerPtr },
-	{ "terminator-ptr", DefinedAtom::typeTerminatorPtr },
-	{ "c-string-ptr",   DefinedAtom::typeCStringPtr },
-	{ "objc1-class",    DefinedAtom::typeObjC1Class },
-	{ "objc1-class-ptr",DefinedAtom::typeObjCClassPtr },
-	{ "objc2-cat-ptr",  DefinedAtom::typeObjC2CategoryList },
-	{ "tlv-thunk",      DefinedAtom::typeThunkTLV },
-	{ "tlv-data",       DefinedAtom::typeTLVInitialData },
-	{ "tlv-zero-fill",  DefinedAtom::typeTLVInitialZeroFill },
-	{ "tlv-init-ptr",   DefinedAtom::typeTLVInitializerPtr },
+  { "unknown",        DefinedAtom::typeUnknown },
+  { "code",           DefinedAtom::typeCode },
+  { "resolver",       DefinedAtom::typeResolver },
+  { "constant",       DefinedAtom::typeConstant },
+  { "c-string",       DefinedAtom::typeCString },
+  { "utf16-string",   DefinedAtom::typeUTF16String },
+  { "CFI",            DefinedAtom::typeCFI },
+  { "LSDA",           DefinedAtom::typeLSDA },
+  { "literal-4",      DefinedAtom::typeLiteral4 },
+  { "literal-8",      DefinedAtom::typeLiteral8 },
+  { "literal-16",     DefinedAtom::typeLiteral16 },
+  { "data",           DefinedAtom::typeData },
+  { "zero-fill",      DefinedAtom::typeZeroFill },
+  { "cf-string",      DefinedAtom::typeCFString },
+  { "initializer-ptr",DefinedAtom::typeInitializerPtr },
+  { "terminator-ptr", DefinedAtom::typeTerminatorPtr },
+  { "c-string-ptr",   DefinedAtom::typeCStringPtr },
+  { "objc1-class",    DefinedAtom::typeObjC1Class },
+  { "objc1-class-ptr",DefinedAtom::typeObjCClassPtr },
+  { "objc2-cat-ptr",  DefinedAtom::typeObjC2CategoryList },
+  { "tlv-thunk",      DefinedAtom::typeThunkTLV },
+  { "tlv-data",       DefinedAtom::typeTLVInitialData },
+  { "tlv-zero-fill",  DefinedAtom::typeTLVInitialZeroFill },
+  { "tlv-init-ptr",   DefinedAtom::typeTLVInitializerPtr },
   { NULL,             DefinedAtom::typeUnknown }
 };
 
 DefinedAtom::ContentType KeyValues::contentType(const char* s)
 {
-	for (const ContentTypeMapping* p = typeMappings; p->string != NULL; ++p) {
+  for (const ContentTypeMapping* p = typeMappings; p->string != NULL; ++p) {
     if ( strcmp(p->string, s) == 0 )
       return p->value;
   }
@@ -163,7 +165,7 @@
 }
 
 const char* KeyValues::contentType(DefinedAtom::ContentType s) {
-	for (const ContentTypeMapping* p = typeMappings; p->string != NULL; ++p) {
+  for (const ContentTypeMapping* p = typeMappings; p->string != NULL; ++p) {
     if ( p->value == s )
       return p->string;
   }
@@ -177,20 +179,20 @@
 
 
 struct DeadStripMapping {
-	const char*           string;
-	DefinedAtom::DeadStripKind   value;
+  const char*           string;
+  DefinedAtom::DeadStripKind   value;
 };
 
 static const DeadStripMapping deadStripMappings[] = {
-	{ "normal",         DefinedAtom::deadStripNormal },
-	{ "never",          DefinedAtom::deadStripNever },
-	{ "always",         DefinedAtom::deadStripAlways },
+  { "normal",         DefinedAtom::deadStripNormal },
+  { "never",          DefinedAtom::deadStripNever },
+  { "always",         DefinedAtom::deadStripAlways },
   { NULL,             DefinedAtom::deadStripNormal }
 };
 
 DefinedAtom::DeadStripKind KeyValues::deadStripKind(const char* s)
 {
-	for (const DeadStripMapping* p = deadStripMappings; p->string != NULL; ++p) {
+  for (const DeadStripMapping* p = deadStripMappings; p->string != NULL; ++p) {
     if ( strcmp(p->string, s) == 0 )
       return p->value;
   }
@@ -198,7 +200,7 @@
 }
 
 const char* KeyValues::deadStripKind(DefinedAtom::DeadStripKind dsk) {
-	for (const DeadStripMapping* p = deadStripMappings; p->string != NULL; ++p) {
+  for (const DeadStripMapping* p = deadStripMappings; p->string != NULL; ++p) {
     if ( p->value == dsk )
       return p->string;
   }
@@ -210,20 +212,20 @@
 
 
 struct InterposableMapping {
-	const char*           string;
-	DefinedAtom::Interposable   value;
+  const char*           string;
+  DefinedAtom::Interposable   value;
 };
 
 static const InterposableMapping interMappings[] = {
-	{ "no",           DefinedAtom::interposeNo },
-	{ "yes",          DefinedAtom::interposeYes },
-	{ "yesAndWeak",   DefinedAtom::interposeYesAndRuntimeWeak },
+  { "no",           DefinedAtom::interposeNo },
+  { "yes",          DefinedAtom::interposeYes },
+  { "yesAndWeak",   DefinedAtom::interposeYesAndRuntimeWeak },
   { NULL,           DefinedAtom::interposeNo }
 };
 
 DefinedAtom::Interposable KeyValues::interposable(const char* s)
 {
-	for (const InterposableMapping* p = interMappings; p->string != NULL; ++p) {
+  for (const InterposableMapping* p = interMappings; p->string != NULL; ++p) {
     if ( strcmp(p->string, s) == 0 )
       return p->value;
   }
@@ -231,7 +233,7 @@
 }
 
 const char* KeyValues::interposable(DefinedAtom::Interposable in) {
-	for (const InterposableMapping* p = interMappings; p->string != NULL; ++p) {
+  for (const InterposableMapping* p = interMappings; p->string != NULL; ++p) {
     if ( p->value == in )
       return p->string;
   }
@@ -244,21 +246,21 @@
 
 
 struct MergeMapping {
-	const char*          string;
-	DefinedAtom::Merge   value;
+  const char*          string;
+  DefinedAtom::Merge   value;
 };
 
 static const MergeMapping mergeMappings[] = {
-	{ "no",             DefinedAtom::mergeNo },
-	{ "asTentative",    DefinedAtom::mergeAsTentative },
-	{ "asWeak",         DefinedAtom::mergeAsWeak },
-	{ "asAddressedWeak",DefinedAtom::mergeAsWeakAndAddressUsed },
+  { "no",             DefinedAtom::mergeNo },
+  { "asTentative",    DefinedAtom::mergeAsTentative },
+  { "asWeak",         DefinedAtom::mergeAsWeak },
+  { "asAddressedWeak",DefinedAtom::mergeAsWeakAndAddressUsed },
   { NULL,             DefinedAtom::mergeNo }
 };
 
 DefinedAtom::Merge KeyValues::merge(const char* s)
 {
-	for (const MergeMapping* p = mergeMappings; p->string != NULL; ++p) {
+  for (const MergeMapping* p = mergeMappings; p->string != NULL; ++p) {
     if ( strcmp(p->string, s) == 0 )
       return p->value;
   }
@@ -266,7 +268,7 @@
 }
 
 const char* KeyValues::merge(DefinedAtom::Merge in) {
-	for (const MergeMapping* p = mergeMappings; p->string != NULL; ++p) {
+  for (const MergeMapping* p = mergeMappings; p->string != NULL; ++p) {
     if ( p->value == in )
       return p->string;
   }
@@ -279,20 +281,20 @@
 
 
 struct SectionChoiceMapping {
-	const char*                 string;
-	DefinedAtom::SectionChoice  value;
+  const char*                 string;
+  DefinedAtom::SectionChoice  value;
 };
 
 static const SectionChoiceMapping sectMappings[] = {
-	{ "content",         DefinedAtom::sectionBasedOnContent },
-	{ "custom",          DefinedAtom::sectionCustomPreferred },
-	{ "custom-required", DefinedAtom::sectionCustomRequired },
+  { "content",         DefinedAtom::sectionBasedOnContent },
+  { "custom",          DefinedAtom::sectionCustomPreferred },
+  { "custom-required", DefinedAtom::sectionCustomRequired },
   { NULL,              DefinedAtom::sectionBasedOnContent }
 };
 
 DefinedAtom::SectionChoice KeyValues::sectionChoice(const char* s)
 {
-	for (const SectionChoiceMapping* p = sectMappings; p->string != NULL; ++p) {
+  for (const SectionChoiceMapping* p = sectMappings; p->string != NULL; ++p) {
     if ( strcmp(p->string, s) == 0 )
       return p->value;
   }
@@ -300,7 +302,7 @@
 }
 
 const char* KeyValues::sectionChoice(DefinedAtom::SectionChoice s) {
-	for (const SectionChoiceMapping* p = sectMappings; p->string != NULL; ++p) {
+  for (const SectionChoiceMapping* p = sectMappings; p->string != NULL; ++p) {
     if ( p->value == s )
       return p->string;
   }
@@ -314,22 +316,22 @@
 
 
 struct PermissionsMapping {
-	const char*                      string;
-	DefinedAtom::ContentPermissions  value;
+  const char*                      string;
+  DefinedAtom::ContentPermissions  value;
 };
 
 static const PermissionsMapping permMappings[] = {
-	{ "content",         DefinedAtom::perm___ },
-	{ "custom",          DefinedAtom::permR__ },
-	{ "custom-required", DefinedAtom::permR_X },
-	{ "custom-required", DefinedAtom::permRW_ },
-	{ "custom-required", DefinedAtom::permRW_L },
+  { "content",         DefinedAtom::perm___ },
+  { "custom",          DefinedAtom::permR__ },
+  { "custom-required", DefinedAtom::permR_X },
+  { "custom-required", DefinedAtom::permRW_ },
+  { "custom-required", DefinedAtom::permRW_L },
   { NULL,              DefinedAtom::perm___ }
 };
 
 DefinedAtom::ContentPermissions KeyValues::permissions(const char* s)
 {
-	for (const PermissionsMapping* p = permMappings; p->string != NULL; ++p) {
+  for (const PermissionsMapping* p = permMappings; p->string != NULL; ++p) {
     if ( strcmp(p->string, s) == 0 )
       return p->value;
   }
@@ -337,7 +339,7 @@
 }
 
 const char* KeyValues::permissions(DefinedAtom::ContentPermissions s) {
-	for (const PermissionsMapping* p = permMappings; p->string != NULL; ++p) {
+  for (const PermissionsMapping* p = permMappings; p->string != NULL; ++p) {
     if ( p->value == s )
       return p->string;
   }
@@ -398,6 +400,23 @@
 
 
 
+bool KeyValues::weakImport(const char* s)
+{
+  if ( strcmp(s, "true") == 0 )
+    return true;
+  else if ( strcmp(s, "false") == 0 )
+    return false;
+  llvm::report_fatal_error("bad weak-import value");
+}
+
+const char* KeyValues::weakImport(bool b) {
+  return b ? "true" : "false";
+}
+
+
+
+
+
 
 
 } // namespace yaml

Modified: lld/trunk/lib/Core/YamlKeyValues.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/Core/YamlKeyValues.h?rev=149962&r1=149961&r2=149962&view=diff
==============================================================================
--- lld/trunk/lib/Core/YamlKeyValues.h (original)
+++ lld/trunk/lib/Core/YamlKeyValues.h Mon Feb  6 20:59:54 2012
@@ -79,6 +79,11 @@
   static bool                             isAlias(const char*);
   static const char*                      isAlias(bool);
 
+  static const char* const                weakImportKeyword;
+  static const bool                       weakImportDefault;
+  static bool                             weakImport(const char*);
+  static const char*                      weakImport(bool);
+
 };
 
 } // namespace yaml

Modified: lld/trunk/lib/Core/YamlReader.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/Core/YamlReader.cpp?rev=149962&r1=149961&r2=149962&view=diff
==============================================================================
--- lld/trunk/lib/Core/YamlReader.cpp (original)
+++ lld/trunk/lib/Core/YamlReader.cpp Mon Feb  6 20:59:54 2012
@@ -267,6 +267,10 @@
        it != _definedAtoms.end(); ++it) {
     handler.doDefinedAtom(**it);
   }
+  for (std::vector<UndefinedAtom *>::const_iterator it = _undefinedAtoms.begin();
+       it != _undefinedAtoms.end(); ++it) {
+    handler.doUndefinedAtom(**it);
+  }
   return true;
 }
 
@@ -424,6 +428,32 @@
 };
 
 
+class YAMLUndefinedAtom : public UndefinedAtom {
+public:
+        YAMLUndefinedAtom(YAMLFile& f, int32_t ord, const char* nm, bool wi)
+            : _file(f), _name(nm), _ordinal(ord), _weakImport(wi) { }
+
+  virtual const class File& file() const {
+    return _file;
+  }
+
+  virtual llvm::StringRef name() const {
+    return _name;
+  }
+
+  virtual bool weakImport() const {
+    return _weakImport;
+  }
+  
+private:
+  YAMLFile&                   _file;
+  const char *                _name;
+  uint32_t                    _ordinal;
+  bool                        _weakImport;
+};
+
+
+
 class YAMLAtomState {
 public:
   YAMLAtomState();
@@ -455,6 +485,7 @@
   bool                        _internalName;
   bool                        _isThumb;
   bool                        _isAlias;
+  bool                        _weakImport;
   Reference                   _ref;
 };
 
@@ -477,6 +508,7 @@
   , _internalName(KeyValues::internalNameDefault)
   , _isThumb(KeyValues::isThumbDefault)
   , _isAlias(KeyValues::isAliasDefault) 
+  , _weakImport(false)
   {
   _ref.target       = NULL;
   _ref.addend       = 0;
@@ -496,6 +528,12 @@
     f._definedAtoms.push_back(a);
     ++_ordinal;
   }
+  else if ( _definition == Atom::definitionUndefined ) {
+    UndefinedAtom *a = new YAMLUndefinedAtom(f, _ordinal, _name, _weakImport);
+
+    f._undefinedAtoms.push_back(a);
+    ++_ordinal;
+  }
   
   // reset state for next atom
   _name             = NULL;
@@ -515,6 +553,7 @@
   _permissions      = KeyValues::permissionsDefault;
   _isThumb          = KeyValues::isThumbDefault;
   _isAlias          = KeyValues::isAliasDefault;
+  _weakImport       = KeyValues::weakImportDefault;
   _ref.target       = NULL;
   _ref.addend       = 0;
   _ref.offsetInAtom = 0;
@@ -664,6 +703,10 @@
           atomState._isAlias = KeyValues::isAlias(entry->value);
           haveAtom = true;
         }
+        else if (strcmp(entry->key, KeyValues::weakImportKeyword) == 0) {
+          atomState._weakImport = KeyValues::weakImport(entry->value);
+          haveAtom = true;
+        }
         else if (strcmp(entry->key, KeyValues::sectionNameKeyword) == 0) {
           atomState._sectionName = entry->value;
           haveAtom = true;

Modified: lld/trunk/lib/Core/YamlWriter.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/Core/YamlWriter.cpp?rev=149962&r1=149961&r2=149962&view=diff
==============================================================================
--- lld/trunk/lib/Core/YamlWriter.cpp (original)
+++ lld/trunk/lib/Core/YamlWriter.cpp Mon Feb  6 20:59:54 2012
@@ -81,7 +81,7 @@
             << "\n";
     }
     
-	if ( atom.merge() != KeyValues::mergeDefault ) {
+    if ( atom.merge() != KeyValues::mergeDefault ) {
       _out  << "      " 
             << KeyValues::mergeKeyword 
             << ":"
@@ -124,7 +124,7 @@
             << "\n";
     }
 
-	if ( atom.isThumb() != KeyValues::isThumbDefault ) {
+    if ( atom.isThumb() != KeyValues::isThumbDefault ) {
       _out  << "      " 
             << KeyValues::isThumbKeyword 
             << ":"
@@ -142,7 +142,8 @@
             << "\n";
     }
 
-    if ( atom.contentType() != DefinedAtom::typeZeroFill ) {
+    if ( (atom.contentType() != DefinedAtom::typeZeroFill) 
+                                   && (atom.size() != 0) ) {
       _out  << "      " 
             << KeyValues::contentKeyword 
             << ":"
@@ -171,9 +172,35 @@
 
   }
 
-	virtual void doUndefinedAtom(const class UndefinedAtom &atom) {
+  virtual void doUndefinedAtom(const class UndefinedAtom &atom) {
+      // add blank line between atoms for readability
+      if ( !_firstAtom )
+        _out << "\n";
+      _firstAtom = false;
+        
+      _out  << "    - "
+            << KeyValues::nameKeyword
+            << ":"
+            << spacePadding(KeyValues::nameKeyword)
+            << atom.name() 
+            << "\n";
+
+      _out  << "      " 
+            << KeyValues::definitionKeyword 
+            << ":"
+            << spacePadding(KeyValues::definitionKeyword)
+            << KeyValues::definition(atom.definition()) 
+            << "\n";
 
-	}
+    if ( atom.weakImport() != KeyValues::weakImportDefault ) {
+      _out  << "      " 
+            << KeyValues::weakImportKeyword 
+            << ":"
+            << spacePadding(KeyValues::weakImportKeyword)
+            << KeyValues::weakImport(atom.weakImport()) 
+            << "\n";
+    }
+  }
 
 
 private:

Added: lld/trunk/test/undef-coalesce.objtxt
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/undef-coalesce.objtxt?rev=149962&view=auto
==============================================================================
--- lld/trunk/test/undef-coalesce.objtxt (added)
+++ lld/trunk/test/undef-coalesce.objtxt Mon Feb  6 20:59:54 2012
@@ -0,0 +1,46 @@
+# RUN: lld-core %s | FileCheck %s
+
+#
+# Test that undefined symbols are coalesced with other undefined symbols
+# and definitions override them.
+#
+
+---
+atoms:
+    - name:              foo
+      type:              code
+      
+    - name:              malloc
+      definition:        undefined
+
+    - name:              free
+      definition:        undefined
+---
+atoms:
+    - name:              bar
+      type:              code
+      
+    - name:              malloc
+      definition:        undefined
+  
+    - name:              myfunc
+      definition:        undefined
+---
+atoms:
+    - name:              myfunc
+      scope:             global
+      type:              code
+      
+    - name:              free
+      definition:        undefined
+...
+
+# CHECK:       name:       foo
+# CHECK:       name:       bar
+# CHECK:       name:       myfunc
+# CHECK:       scope:      global
+# CHECK:       name:       malloc
+# CHECK:     definition:   undefined
+# CHECK:       name:       free
+# CHECK:     definition:   undefined
+# CHECK:       ...

Modified: lld/trunk/tools/lld-core/lld-core.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/tools/lld-core/lld-core.cpp?rev=149962&r1=149961&r2=149962&view=diff
==============================================================================
--- lld/trunk/tools/lld-core/lld-core.cpp (original)
+++ lld/trunk/tools/lld-core/lld-core.cpp Mon Feb  6 20:59:54 2012
@@ -172,20 +172,19 @@
 
   virtual bool forEachAtom(File::AtomHandler &handler) const {
     handler.doFile(*this);
+    // visit defined atoms
     for (std::vector<const Atom *>::iterator it = _atoms.begin();
          it != _atoms.end(); ++it) {
-      const Atom* atom = *it;
-      switch ( atom->definition() ) {
-        case Atom::definitionRegular:
-          handler.doDefinedAtom(*(DefinedAtom*)atom);
-          break;
-        case Atom::definitionUndefined:
-          handler.doUndefinedAtom(*(UndefinedAtom*)atom);
-          break;
-        default:
-          // TO DO
-          break;
-      }
+      const DefinedAtom* atom = (*it)->definedAtom();
+      if ( atom ) 
+          handler.doDefinedAtom(*atom);
+    }
+    // visit undefined atoms
+    for (std::vector<const Atom *>::iterator it = _atoms.begin();
+         it != _atoms.end(); ++it) {
+      const UndefinedAtom* atom = (*it)->undefinedAtom();
+      if ( atom ) 
+          handler.doUndefinedAtom(*atom);
     }
     return true;
   }
@@ -198,7 +197,8 @@
 private:
   std::vector<const Atom *> &_atoms;
 };
-}
+} //anonymous namespace
+
 
 int main(int argc, const char *argv[]) {
   // Print a stack trace if we signal out.
@@ -220,7 +220,7 @@
   // write new atom graph out as YAML doc
   std::string errorInfo;
   llvm::raw_fd_ostream out("-", errorInfo);
-//  yaml::writeObjectText(outFile, out);
+  //yaml::writeObjectText(outFile, out);
 
   // make unique temp .o file to put generated object file
   int fd;
@@ -233,7 +233,7 @@
   binaryOut.close();  // manually close so that file can be read next
 
   // read native file
-  lld::File* natFile;
+  llvm::OwningPtr<lld::File> natFile;
   parseNativeObjectFileOrSTDIN(tempPath, natFile);
 
   // write new atom graph out as YAML doc
@@ -242,6 +242,6 @@
   // delete temp .o file
   bool existed;
   llvm::sys::fs::remove(tempPath.str(), existed);
-
+  
   return 0;
 }





More information about the llvm-commits mailing list