ELF: Implement --start-lib and --end-lib

start-lib and end-lib are options to link object files in the same
semantics as archive files. If an object is in start-lib and end-lib,
the object is linked only when the file is needed to resolve
undefined symbols. That means, if an object is in start-lib and end-lib,
it behaves as if it were in an archive file.

In this patch, I introduced a new notion, LazyObjectFile. That is
analogous to Archive file type, but that works for a single object
file instead of for an archive file.

http://reviews.llvm.org/D18814

llvm-svn: 265710
diff --git a/lld/ELF/Symbols.cpp b/lld/ELF/Symbols.cpp
index 5ce5738..e699640 100644
--- a/lld/ELF/Symbols.cpp
+++ b/lld/ELF/Symbols.cpp
@@ -78,7 +78,8 @@
   case SymbolBody::UndefinedElfKind:
   case SymbolBody::UndefinedBitcodeKind:
     return 0;
-  case SymbolBody::LazyKind:
+  case SymbolBody::LazyArchiveKind:
+  case SymbolBody::LazyObjectKind:
     assert(Body.isUsedInRegularObj() && "lazy symbol reached writer");
     return 0;
   case SymbolBody::DefinedBitcodeKind:
@@ -301,7 +302,13 @@
     : Defined(SymbolBody::DefinedCommonKind, N, Binding, StOther, Type),
       Alignment(Alignment), Size(Size) {}
 
-std::unique_ptr<InputFile> Lazy::getMember() {
+std::unique_ptr<InputFile> Lazy::getFile() {
+  if (auto *S = dyn_cast<LazyArchive>(this))
+    return S->getFile();
+  return cast<LazyObject>(this)->getFile();
+}
+
+std::unique_ptr<InputFile> LazyArchive::getFile() {
   MemoryBufferRef MBRef = File->getMember(&Sym);
 
   // getMember returns an empty buffer if the member was already
@@ -311,6 +318,10 @@
   return createObjectFile(MBRef, File->getName());
 }
 
+std::unique_ptr<InputFile> LazyObject::getFile() {
+  return createObjectFile(MBRef);
+}
+
 // Returns the demangled C++ symbol name for Name.
 std::string elf::demangle(StringRef Name) {
 #if !defined(HAVE_CXXABI_H)