Add a fallback mechanism for undefined atom.

In COFF, an undefined symbol can have up to one alternative name. If a symbol
is resolved by its regular name, then it's linked normally. If a symbol is not
found in any input files, all references to the regular name are resolved using
the alternative name. If the alternative name is not found, it's a link error.
This mechanism is called "weak externals".

To support this mechanism, I added a new member function fallback() to undefined
atom. If an undefined atom has the second name, fallback() returns a new undefined
atom that should be used instead of the original one to resolve undefines. If it
does not have the second name, the function returns nullptr.

Differential Revision: http://llvm-reviews.chandlerc.com/D1550

llvm-svn: 190625
diff --git a/lld/lib/ReaderWriter/Native/ReaderNative.cpp b/lld/lib/ReaderWriter/Native/ReaderNative.cpp
index 31024a0..0554dce 100644
--- a/lld/lib/ReaderWriter/Native/ReaderNative.cpp
+++ b/lld/lib/ReaderWriter/Native/ReaderNative.cpp
@@ -8,6 +8,7 @@
 //===----------------------------------------------------------------------===//
 
 #include "lld/ReaderWriter/Reader.h"
+#include "lld/ReaderWriter/Simple.h"
 
 #include "lld/Core/Atom.h"
 #include "lld/Core/Error.h"
@@ -134,10 +135,12 @@
     return (CanBeNull)(_ivarData->flags & 0x3);
   }
 
+  virtual const UndefinedAtom *fallback() const;
 
 private:
   const File                        *_file;
   const NativeUndefinedAtomIvarsV1  *_ivarData;
+  mutable std::unique_ptr<const SimpleUndefinedAtom> _fallback;
 };
 
 
@@ -860,8 +863,14 @@
   return _file->string(_ivarData->nameOffset);
 }
 
-
-
+inline const UndefinedAtom *NativeUndefinedAtomV1::fallback() const {
+  if (!_ivarData->fallbackNameOffset)
+    return nullptr;
+  if (!_fallback)
+    _fallback.reset(new SimpleUndefinedAtom(
+        *_file, _file->string(_ivarData->fallbackNameOffset)));
+  return _fallback.get();
+}
 
 inline const lld::File& NativeSharedLibraryAtomV1::file() const {
   return *_file;