Add support for SharedLibraryAtoms (proxy atoms for exported symbols from a 
shared library) and AbsoluteAtoms (proxy atoms for absolute address (e.g. ROM)).
Redesign weak importing as can-be-null-at-runtime and can-be-null-at-build-time.
Add lots of test cases for all the above.

llvm-svn: 151204
diff --git a/lld/lib/Core/YamlWriter.cpp b/lld/lib/Core/YamlWriter.cpp
index c38e735..c3a7f23 100644
--- a/lld/lib/Core/YamlWriter.cpp
+++ b/lld/lib/Core/YamlWriter.cpp
@@ -71,6 +71,14 @@
     buildDuplicateNameMap(atom);
   }
   
+  virtual void doSharedLibraryAtom(const SharedLibraryAtom& atom) {
+    buildDuplicateNameMap(atom);
+  }
+
+  virtual void doAbsoluteAtom(const AbsoluteAtom& atom) {
+    buildDuplicateNameMap(atom);
+  }
+                         
   void buildDuplicateNameMap(const Atom& atom) {
     assert(!atom.name().empty());
     NameToAtom::iterator pos = _nameMap.find(atom.name());
@@ -132,10 +140,14 @@
   virtual void doFile(const class File &) { _firstAtom = true; }
   
   virtual void doDefinedAtom(const class DefinedAtom &atom) {
-    // add blank line between atoms for readability
-    if ( !_firstAtom )
+    if ( _firstAtom ) {
+      _out << "atoms:\n";
+      _firstAtom = false;
+    }
+    else {
+      // add blank line between atoms for readability
       _out << "\n";
-    _firstAtom = false;
+    }
     
     bool hasDash = false;
     if ( !atom.name().empty() ) {
@@ -313,35 +325,115 @@
 
 
   virtual void doUndefinedAtom(const class UndefinedAtom &atom) {
-      // add blank line between atoms for readability
-      if ( !_firstAtom )
-        _out << "\n";
+    if ( _firstAtom ) {
+      _out << "atoms:\n";
       _firstAtom = false;
+    }
+    else {
+      // add blank line between atoms for readability
+      _out << "\n";
+    }
         
-      _out  << "    - "
-            << KeyValues::nameKeyword
-            << ":"
-            << spacePadding(KeyValues::nameKeyword)
-            << atom.name() 
-            << "\n";
+    _out  << "    - "
+          << KeyValues::nameKeyword
+          << ":"
+          << spacePadding(KeyValues::nameKeyword)
+          << atom.name() 
+          << "\n";
 
-      _out  << "      " 
-            << KeyValues::definitionKeyword 
-            << ":"
-            << spacePadding(KeyValues::definitionKeyword)
-            << KeyValues::definition(atom.definition()) 
-            << "\n";
+    _out  << "      " 
+          << KeyValues::definitionKeyword 
+          << ":"
+          << spacePadding(KeyValues::definitionKeyword)
+          << KeyValues::definition(atom.definition()) 
+          << "\n";
 
-    if ( atom.weakImport() != KeyValues::weakImportDefault ) {
+    if ( atom.canBeNull() != KeyValues::canBeNullDefault ) {
       _out  << "      " 
-            << KeyValues::weakImportKeyword 
+            << KeyValues::canBeNullKeyword 
             << ":"
-            << spacePadding(KeyValues::weakImportKeyword)
-            << KeyValues::weakImport(atom.weakImport()) 
+            << spacePadding(KeyValues::canBeNullKeyword)
+            << KeyValues::canBeNull(atom.canBeNull()) 
             << "\n";
     }
   }
 
+   virtual void doSharedLibraryAtom(const SharedLibraryAtom& atom) {
+    if ( _firstAtom ) {
+      _out << "atoms:\n";
+      _firstAtom = false;
+    }
+    else {
+      // add blank line between atoms for readability
+      _out << "\n";
+    }
+        
+    _out  << "    - "
+          << KeyValues::nameKeyword
+          << ":"
+          << spacePadding(KeyValues::nameKeyword)
+          << atom.name() 
+          << "\n";
+
+    _out  << "      " 
+          << KeyValues::definitionKeyword 
+          << ":"
+          << spacePadding(KeyValues::definitionKeyword)
+          << KeyValues::definition(atom.definition()) 
+          << "\n";
+
+    if ( !atom.loadName().empty() ) {
+      _out  << "      " 
+            << KeyValues::loadNameKeyword 
+            << ":"
+            << spacePadding(KeyValues::loadNameKeyword)
+            << atom.loadName()
+            << "\n";
+    }
+
+    if ( atom.canBeNullAtRuntime() ) {
+      _out  << "      " 
+            << KeyValues::canBeNullKeyword 
+            << ":"
+            << spacePadding(KeyValues::canBeNullKeyword)
+            << KeyValues::canBeNull(UndefinedAtom::canBeNullAtRuntime) 
+            << "\n";
+    }
+   }
+   
+   virtual void doAbsoluteAtom(const AbsoluteAtom& atom) {
+     if ( _firstAtom ) {
+      _out << "atoms:\n";
+      _firstAtom = false;
+    }
+    else {
+      // add blank line between atoms for readability
+      _out << "\n";
+    }
+        
+    _out  << "    - "
+          << KeyValues::nameKeyword
+          << ":"
+          << spacePadding(KeyValues::nameKeyword)
+          << atom.name() 
+          << "\n";
+
+    _out  << "      " 
+          << KeyValues::definitionKeyword 
+          << ":"
+          << spacePadding(KeyValues::definitionKeyword)
+          << KeyValues::definition(atom.definition()) 
+          << "\n";
+    
+    _out  << "      " 
+          << KeyValues::valueKeyword 
+          << ":"
+          << spacePadding(KeyValues::valueKeyword)
+          << "0x";
+     _out.write_hex(atom.value());
+     _out << "\n";
+   }
+                     
 
 private:
   // return a string of the correct number of spaces to align value
@@ -380,7 +472,6 @@
   // Write out all atoms
   AtomWriter h(rnb, out);
   out << "---\n";
-  out << "atoms:\n";
   file.forEachAtom(h);
   out << "...\n";
 }