[lld] r192081 - [lld][InputGraph] Change the Resolver to use inputGraph

Shankar Easwaran shankare at codeaurora.org
Sun Oct 6 19:47:10 PDT 2013


Author: shankare
Date: Sun Oct  6 21:47:09 2013
New Revision: 192081

URL: http://llvm.org/viewvc/llvm-project?rev=192081&view=rev
Log:
[lld][InputGraph] Change the Resolver to use inputGraph

Changes :-

a) Functionality in InputGraph to insert Input elements at any position
b) Functionality in the Resolver to use nextFile
c) Move the functionality of assigning file ordinals to InputGraph
d) Changes all inputs to MemoryBuffers
e) Remove LinkerInput, InputFiles, ReaderArchive

Removed:
    lld/trunk/include/lld/Core/InputFiles.h
    lld/trunk/include/lld/Core/LinkerInput.h
    lld/trunk/lib/Core/InputFiles.cpp
    lld/trunk/lib/ReaderWriter/ReaderArchive.cpp
Modified:
    lld/trunk/include/lld/Core/Error.h
    lld/trunk/include/lld/Core/LinkingContext.h
    lld/trunk/include/lld/Core/Resolver.h
    lld/trunk/include/lld/Core/SharedLibraryFile.h
    lld/trunk/include/lld/Driver/CoreInputGraph.h
    lld/trunk/include/lld/Driver/DarwinInputGraph.h
    lld/trunk/include/lld/Driver/GnuLdInputGraph.h
    lld/trunk/include/lld/Driver/InputGraph.h
    lld/trunk/include/lld/Driver/WinLinkInputGraph.h
    lld/trunk/include/lld/ReaderWriter/CoreLinkingContext.h
    lld/trunk/include/lld/ReaderWriter/ELFLinkingContext.h
    lld/trunk/include/lld/ReaderWriter/MachOLinkingContext.h
    lld/trunk/include/lld/ReaderWriter/PECOFFLinkingContext.h
    lld/trunk/include/lld/ReaderWriter/Reader.h
    lld/trunk/include/lld/ReaderWriter/ReaderArchive.h
    lld/trunk/include/lld/ReaderWriter/ReaderLinkerScript.h
    lld/trunk/include/lld/ReaderWriter/Writer.h
    lld/trunk/lib/Core/CMakeLists.txt
    lld/trunk/lib/Core/Error.cpp
    lld/trunk/lib/Core/LinkingContext.cpp
    lld/trunk/lib/Core/Resolver.cpp
    lld/trunk/lib/Core/SymbolTable.cpp
    lld/trunk/lib/Driver/CMakeLists.txt
    lld/trunk/lib/Driver/CoreDriver.cpp
    lld/trunk/lib/Driver/DarwinLdDriver.cpp
    lld/trunk/lib/Driver/Driver.cpp
    lld/trunk/lib/Driver/GnuLdDriver.cpp
    lld/trunk/lib/Driver/InputGraph.cpp
    lld/trunk/lib/Driver/WinLinkDriver.cpp
    lld/trunk/lib/ReaderWriter/CMakeLists.txt
    lld/trunk/lib/ReaderWriter/CoreLinkingContext.cpp
    lld/trunk/lib/ReaderWriter/ELF/DefaultTargetHandler.h
    lld/trunk/lib/ReaderWriter/ELF/DynamicLibraryWriter.h
    lld/trunk/lib/ReaderWriter/ELF/ELFLinkingContext.cpp
    lld/trunk/lib/ReaderWriter/ELF/ExecutableWriter.h
    lld/trunk/lib/ReaderWriter/ELF/File.h
    lld/trunk/lib/ReaderWriter/ELF/Hexagon/HexagonLinkingContext.cpp
    lld/trunk/lib/ReaderWriter/ELF/Hexagon/HexagonLinkingContext.h
    lld/trunk/lib/ReaderWriter/ELF/Hexagon/HexagonTargetHandler.cpp
    lld/trunk/lib/ReaderWriter/ELF/Hexagon/HexagonTargetHandler.h
    lld/trunk/lib/ReaderWriter/ELF/OutputELFWriter.h
    lld/trunk/lib/ReaderWriter/ELF/Reader.cpp
    lld/trunk/lib/ReaderWriter/ELF/TargetHandler.h
    lld/trunk/lib/ReaderWriter/ELF/Writer.h
    lld/trunk/lib/ReaderWriter/ELF/X86_64/X86_64LinkingContext.cpp
    lld/trunk/lib/ReaderWriter/ELF/X86_64/X86_64LinkingContext.h
    lld/trunk/lib/ReaderWriter/ELF/X86_64/X86_64TargetHandler.cpp
    lld/trunk/lib/ReaderWriter/ELF/X86_64/X86_64TargetHandler.h
    lld/trunk/lib/ReaderWriter/MachO/MachOLinkingContext.cpp
    lld/trunk/lib/ReaderWriter/MachO/WriterMachO.cpp
    lld/trunk/lib/ReaderWriter/Native/ReaderNative.cpp
    lld/trunk/lib/ReaderWriter/PECOFF/LinkerGeneratedSymbolFile.h
    lld/trunk/lib/ReaderWriter/PECOFF/PECOFFLinkingContext.cpp
    lld/trunk/lib/ReaderWriter/PECOFF/ReaderCOFF.cpp
    lld/trunk/lib/ReaderWriter/PECOFF/WriterPECOFF.cpp
    lld/trunk/lib/ReaderWriter/ReaderLinkerScript.cpp
    lld/trunk/lib/ReaderWriter/Writer.cpp
    lld/trunk/lib/ReaderWriter/YAML/ReaderWriterYAML.cpp
    lld/trunk/test/Driver/lib-search.test
    lld/trunk/test/Driver/libsearch-inputGraph.test
    lld/trunk/test/elf/X86_64/dynlib-search.test
    lld/trunk/test/elf/X86_64/undef.test
    lld/trunk/test/elf/dynamic.test
    lld/trunk/test/elf/ifunc.test
    lld/trunk/test/elf/librarynotfound.test
    lld/trunk/test/elf/undef-from-main-dso.test
    lld/trunk/unittests/DriverTests/DriverTest.h

Modified: lld/trunk/include/lld/Core/Error.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/include/lld/Core/Error.h?rev=192081&r1=192080&r2=192081&view=diff
==============================================================================
--- lld/trunk/include/lld/Core/Error.h (original)
+++ lld/trunk/include/lld/Core/Error.h Sun Oct  6 21:47:09 2013
@@ -69,6 +69,28 @@ enum class linker_script_reader_error {
 inline llvm::error_code make_error_code(linker_script_reader_error e) {
   return llvm::error_code(static_cast<int>(e), linker_script_reader_category());
 }
+
+/// \brief Errors returned by InputGraph functionality
+const llvm::error_category &input_graph_error_category();
+
+struct input_graph_error {
+  enum _ {
+    success = 0,
+    failure = 1,
+    no_more_elements,
+    no_more_files,
+  };
+  _ v_;
+
+  input_graph_error(_ v) : v_(v) {}
+  explicit input_graph_error(int v) : v_(_(v)) {}
+  operator int() const { return v_; }
+};
+
+inline llvm::error_code make_error_code(input_graph_error e) {
+  return llvm::error_code(static_cast<int>(e), input_graph_error_category());
+}
+
 } // end namespace lld
 
 namespace llvm {
@@ -83,6 +105,9 @@ struct is_error_code_enum<lld::yaml_read
 
 template <>
 struct is_error_code_enum<lld::linker_script_reader_error> : true_type { };
+
+template <> struct is_error_code_enum<lld::input_graph_error> : true_type {};
+template <> struct is_error_code_enum<lld::input_graph_error::_> : true_type {};
 } // end namespace llvm
 
 #endif

Removed: lld/trunk/include/lld/Core/InputFiles.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/include/lld/Core/InputFiles.h?rev=192080&view=auto
==============================================================================
--- lld/trunk/include/lld/Core/InputFiles.h (original)
+++ lld/trunk/include/lld/Core/InputFiles.h (removed)
@@ -1,76 +0,0 @@
-//===- Core/InputFiles.h - The set of Input Files to the Linker -----------===//
-//
-//                             The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLD_CORE_INPUT_FILES_H_
-#define LLD_CORE_INPUT_FILES_H_
-
-#include "llvm/ADT/StringRef.h"
-
-#include <memory>
-#include <vector>
-
-namespace lld {
-class AbsoluteAtom;
-class DefinedAtom;
-class SharedLibraryAtom;
-class UndefinedAtom;
-class File;
-
-/// This InputFiles class manages access to all input files to the linker.
-///
-/// The forEachInitialAtom() method iterates object files to add at
-/// the start of the link.
-///
-/// The searchLibraries() method is used to lazily search libraries.
-class InputFiles {
-public:
-  class Handler {
-  public:
-    virtual ~Handler() {}
-    virtual void doFile(const File &) = 0;
-    virtual void doDefinedAtom(const DefinedAtom &) = 0;
-    virtual void doUndefinedAtom(const UndefinedAtom &) = 0;
-    virtual void doSharedLibraryAtom(const SharedLibraryAtom &) = 0;
-    virtual void doAbsoluteAtom(const AbsoluteAtom &) = 0;
-  };
-
-  InputFiles();
-  virtual ~InputFiles();
-
-  /// Used by Writers to insert writer specific files.
-  virtual void prependFile(const File&);
-
-  /// Used by Writers to insert writer specific files.
-  virtual void appendFile(const File&);
-
- /// Transfers ownership of a vector of Files to this InputFile object.
-  virtual void appendFiles(std::vector<std::unique_ptr<File>> &files);
-
-  /// Assigns an ordinal to each File for use by sort().
-  virtual void assignFileOrdinals();
-
-  /// @brief iterates all atoms in initial files
-  virtual void forEachInitialAtom(Handler &) const;
-
-  /// @brief searches libraries for name
-  virtual bool searchLibraries(llvm::StringRef name,
-                               bool searchSharedLibs,
-                               bool searchArchives,
-                               bool dataSymbolOnly,
-                               Handler &) const;
-
-protected:
-  void handleFile(const File *file, InputFiles::Handler &handler) const;
-
-  std::vector<const File*>        _files;
-};
-
-} // namespace lld
-
-#endif // LLD_CORE_INPUT_FILES_H_

Removed: lld/trunk/include/lld/Core/LinkerInput.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/include/lld/Core/LinkerInput.h?rev=192080&view=auto
==============================================================================
--- lld/trunk/include/lld/Core/LinkerInput.h (original)
+++ lld/trunk/include/lld/Core/LinkerInput.h (removed)
@@ -1,104 +0,0 @@
-//===- lld/Core/LinkerInput.h - Files to be linked ------------------------===//
-//
-//                             The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-///
-/// \file
-///
-/// All linker options needed by core linking.
-///
-//===----------------------------------------------------------------------===//
-
-#ifndef LLD_CORE_LINKER_INPUT_H
-#define LLD_CORE_LINKER_INPUT_H
-
-#include "lld/Core/LLVM.h"
-
-#include "llvm/ADT/StringRef.h"
-#include "llvm/ADT/StringSwitch.h"
-#include "llvm/ADT/Triple.h"
-#include "llvm/Option/ArgList.h"
-#include "llvm/Option/Option.h"
-#include "llvm/Support/Compiler.h"
-#include "llvm/Support/ErrorOr.h"
-#include "llvm/Support/FileSystem.h"
-#include "llvm/Support/MemoryBuffer.h"
-
-#include <memory>
-#include <vector>
-
-namespace lld {
-
-/// \brief An input to the linker.
-///
-/// This class represents an input to the linker. It create the MemoryBuffer
-/// lazily when needed based on the file path. It can also take a MemoryBuffer
-/// directly.
-///
-/// The intent is that we only open each file once. And have strong ownership
-/// semantics.
-class LinkerInput {
-  LinkerInput(const LinkerInput &) LLVM_DELETED_FUNCTION;
-
-public:
-  explicit LinkerInput(std::unique_ptr<llvm::MemoryBuffer> buffer,
-                       StringRef userPath)
-      : _buffer(std::move(buffer)), _userPath(userPath), _isWholeArchive(false),
-        _asNeeded(false) {}
-
-  explicit LinkerInput(std::unique_ptr<llvm::MemoryBuffer> buffer,
-                       const LinkerInput &other)
-      : _buffer(std::move(buffer)), _userPath(other.getUserPath()),
-        _isWholeArchive(other.isWholeArchive()), _asNeeded(other.asNeeded()) {}
-
-  LinkerInput(LinkerInput &&other)
-      : _buffer(std::move(other._buffer)), _userPath(std::move(other._userPath)),
-        _isWholeArchive(other.isWholeArchive()), _asNeeded(other.asNeeded()) {}
-
-  LinkerInput &operator=(LinkerInput &&rhs) {
-    _buffer = std::move(rhs._buffer);
-    _userPath = std::move(rhs._userPath);
-    _isWholeArchive = rhs.isWholeArchive();
-    _asNeeded = rhs.asNeeded();
-    return *this;
-  }
-
-  StringRef getUserPath() const { return _userPath; }
-
-  llvm::MemoryBuffer &getBuffer() const {
-    assert(_buffer);
-    return *_buffer;
-  }
-
-  std::unique_ptr<llvm::MemoryBuffer> takeBuffer() {
-    assert(_buffer);
-    return std::move(_buffer);
-  }
-
-  /// \brief forceLoad is a positional option which when set, requires all
-  /// members in an archive to be force loaded
-  void setWholeArchive(bool isWholeArchive) { _isWholeArchive = isWholeArchive; }
-
-  bool isWholeArchive() const { return _isWholeArchive; }
-
-  /// \brief asneeded is a positional option which when set for a file
-  /// makes the file to be needed at runtime only if its resolving
-  /// undefined symbols
-  void setAsNeeded(bool asNeeded) { _asNeeded = asNeeded; }
-
-  bool asNeeded() const { return _asNeeded; }
-
-private:
-  std::unique_ptr<llvm::MemoryBuffer> _buffer;
-  std::string _userPath;
-  bool _isWholeArchive;
-  bool _asNeeded;
-};
-
-} // namespace lld
-
-#endif

Modified: lld/trunk/include/lld/Core/LinkingContext.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/include/lld/Core/LinkingContext.h?rev=192081&r1=192080&r2=192081&view=diff
==============================================================================
--- lld/trunk/include/lld/Core/LinkingContext.h (original)
+++ lld/trunk/include/lld/Core/LinkingContext.h Sun Oct  6 21:47:09 2013
@@ -12,7 +12,6 @@
 
 #include "lld/Core/Error.h"
 #include "lld/Core/LLVM.h"
-#include "lld/Core/LinkerInput.h"
 #include "lld/Core/range.h"
 #include "lld/Core/Reference.h"
 
@@ -33,8 +32,8 @@ namespace lld {
 class PassManager;
 class File;
 class Writer;
-class InputFiles;
 class InputGraph;
+class InputElement;
 
 /// \brief The LinkingContext class encapsulates "what and how" to link.
 ///
@@ -44,7 +43,7 @@ class InputGraph;
 /// and Writers. For example, ELFLinkingContext has methods that supplies
 /// options
 /// to the ELF Reader and Writer.
-class LinkingContext : public Reader {
+class LinkingContext {
 public:
   /// \brief The types of output file that the linker
   /// creates.
@@ -236,7 +235,7 @@ public:
   /// during link. Flavors can override this function in their LinkingContext
   /// to add more internal files. These internal files are positioned before
   /// the actual input files.
-  virtual std::vector<std::unique_ptr<lld::File> > createInternalFiles();
+  virtual bool createInternalFiles(std::vector<std::unique_ptr<File> > &) const;
 
   /// Return the list of undefined symbols that are specified in the
   /// linker command line, using the -u option.
@@ -278,27 +277,19 @@ public:
   /// Returns the output file that that the linker needs to create
   OutputFileType outputFileType() const { return _outputFileType; }
 
-  /// Abstract method to parse a supplied input file buffer into one or
-  /// more lld::File objects. Subclasses of LinkingContext must implement this
-  /// method.
-  ///
-  /// \param input This is an in-memory read-only copy of the input file.
-  /// If the resulting lld::File object will contain pointers into
-  /// this memory buffer, the lld::File object should take ownership
-  /// of the buffer.  Otherwise core linking will maintain ownership of the
-  /// buffer and delete it at some point.
-  ///
-  /// \param [out] result The instantiated lld::File object is returned here.
-  /// The \p result is a vector because some input files parse into more than
-  /// one lld::File (e.g. YAML).
-  virtual error_code
-  parseFile(LinkerInput &input,
-            std::vector<std::unique_ptr<File> > &result) const = 0;
+  /// Returns the YAML reader.
+  virtual Reader &getYAMLReader() const { return *_yamlReader; }
+
+  /// Returns the LLD Native file format reader.
+  virtual Reader &getNativeReader() const { return *_nativeReader; }
+
+  /// Return the default reader for the target
+  virtual Reader &getDefaultReader() const = 0;
 
   /// This method is called by core linking to give the Writer a chance
   /// to add file format specific "files" to set of files to be linked. This is
   /// how file format specific atoms can be added to the link.
-  virtual void addImplicitFiles(InputFiles &) const;
+  virtual bool createImplicitFiles(std::vector<std::unique_ptr<File> > &) const;
 
   /// This method is called by core linking to build the list of Passes to be
   /// run on the merged/linked graph of all input files.
@@ -309,6 +300,20 @@ public:
   /// \param linkedFile This is the merged/linked graph of all input file Atoms.
   virtual error_code writeFile(const File &linkedFile) const;
 
+  /// nextFile returns the next file that needs to be processed by the resolver.
+  /// The LinkingContext's can override the default behavior to change the way
+  /// the resolver operates. This uses the currentInputElement. When there are
+  /// no more files to be processed an appropriate input_graph_error is
+  /// returned.
+  virtual ErrorOr<File &> nextFile() const;
+
+  /// Set the resolver state for the current Input element This is used by the
+  /// InputGraph to decide the next file that needs to be processed for various
+  /// types of nodes in the InputGraph. The resolver state is nothing but a
+  /// bitmask of various types of states that the resolver handles when adding
+  /// atoms.
+  virtual void setResolverState(int32_t resolverState) const;
+
   /// @}
 
   /// \name Methods needed by YAML I/O and error messages to convert Kind values
@@ -332,10 +337,10 @@ protected:
   virtual Writer &writer() const = 0;
 
   /// Method to create a internal file for the entry symbol
-  virtual std::unique_ptr<File> createEntrySymbolFile();
+  virtual std::unique_ptr<File> createEntrySymbolFile() const;
 
   /// Method to create a internal file for an undefined symbol
-  virtual std::unique_ptr<File> createUndefinedSymbolFile();
+  virtual std::unique_ptr<File> createUndefinedSymbolFile() const;
 
   StringRef _outputPath;
   StringRef _entrySymbolName;
@@ -353,9 +358,11 @@ protected:
   std::vector<StringRef> _deadStripRoots;
   std::vector<const char *> _llvmOptions;
   std::unique_ptr<Reader> _yamlReader;
+  std::unique_ptr<Reader> _nativeReader;
   StringRefVector _initialUndefinedSymbols;
   std::unique_ptr<InputGraph> _inputGraph;
-  llvm::BumpPtrAllocator _allocator;
+  mutable llvm::BumpPtrAllocator _allocator;
+  mutable InputElement *_currentInputElement;
 
 private:
   /// Validate the subclass bits. Only called by validate.

Modified: lld/trunk/include/lld/Core/Resolver.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/include/lld/Core/Resolver.h?rev=192081&r1=192080&r2=192081&view=diff
==============================================================================
--- lld/trunk/include/lld/Core/Resolver.h (original)
+++ lld/trunk/include/lld/Core/Resolver.h Sun Oct  6 21:47:09 2013
@@ -11,7 +11,6 @@
 #define LLD_CORE_RESOLVER_H_
 
 #include "lld/Core/File.h"
-#include "lld/Core/InputFiles.h"
 #include "lld/Core/SharedLibraryFile.h"
 #include "lld/Core/SymbolTable.h"
 
@@ -27,12 +26,21 @@ class LinkingContext;
 
 /// \brief The Resolver is responsible for merging all input object files
 /// and producing a merged graph.
-class Resolver : public InputFiles::Handler {
+class Resolver {
 public:
-  Resolver(const LinkingContext &context, const InputFiles &inputs)
-      : _context(context), _inputFiles(inputs), _symbolTable(context),
-        _result(context), _haveLLVMObjs(false), _addToFinalSection(false),
-        _completedInitialObjectFiles(false) {}
+  enum ResolverState {
+    StateNoChange = 0,              // The default resolver state
+    StateNewDefinedAtoms = 1,       // New defined atoms were added
+    StateNewUndefinedAtoms = 2,     // New undefined atoms were added
+    StateNewSharedLibraryAtoms = 4, // New shared library atoms were added
+    StateNewAbsoluteAtoms = 8       // New absolute atoms were added
+  };
+
+  Resolver(const LinkingContext &context)
+      : _context(context), _symbolTable(context), _result(context),
+        _haveLLVMObjs(false), _addToFinalSection(false) {}
+
+  virtual ~Resolver() {}
 
   // InputFiles::Handler methods
   virtual void doDefinedAtom(const DefinedAtom&);
@@ -41,6 +49,16 @@ public:
   virtual void doAbsoluteAtom(const AbsoluteAtom &);
   virtual void doFile(const File&);
 
+  // Handle files, this adds atoms from the current file thats
+  // being processed by the resolver
+  virtual void handleFile(const File &);
+
+  // Handle an archive library file.
+  virtual void handleArchiveFile(const File &);
+
+  // Handle a shared library file.
+  virtual void handleSharedLibrary(const File &);
+
   /// @brief do work of merging and resolving and return list
   bool resolve();
 
@@ -50,7 +68,7 @@ public:
 
 private:
 
-  void buildInitialAtomList();
+  /// \brief The main function that iterates over the files to resolve
   void resolveUndefines();
   void updateReferences();
   void deadStripOptimize();
@@ -94,7 +112,6 @@ private:
   };
 
   const LinkingContext &_context;
-  const InputFiles &_inputFiles;
   SymbolTable _symbolTable;
   std::vector<const Atom *>     _atoms;
   std::set<const Atom *>        _deadStripRoots;
@@ -102,8 +119,7 @@ private:
   llvm::DenseSet<const Atom *>  _liveAtoms;
   MergedFile                    _result;
   bool                          _haveLLVMObjs;
-  bool                          _addToFinalSection;
-  bool                          _completedInitialObjectFiles;
+  bool _addToFinalSection;
 };
 
 } // namespace lld

Modified: lld/trunk/include/lld/Core/SharedLibraryFile.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/include/lld/Core/SharedLibraryFile.h?rev=192081&r1=192080&r2=192081&view=diff
==============================================================================
--- lld/trunk/include/lld/Core/SharedLibraryFile.h (original)
+++ lld/trunk/include/lld/Core/SharedLibraryFile.h Sun Oct  6 21:47:09 2013
@@ -15,7 +15,6 @@
 
 namespace lld {
 
-
 ///
 /// The SharedLibraryFile subclass of File is used to represent dynamic
 /// shared libraries being linked against.

Modified: lld/trunk/include/lld/Driver/CoreInputGraph.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/include/lld/Driver/CoreInputGraph.h?rev=192081&r1=192080&r2=192081&view=diff
==============================================================================
--- lld/trunk/include/lld/Driver/CoreInputGraph.h (original)
+++ lld/trunk/include/lld/Driver/CoreInputGraph.h Sun Oct  6 21:47:09 2013
@@ -40,11 +40,42 @@ public:
     return true;
   }
 
+  /// \brief Parse the input file to lld::File.
+  llvm::error_code parse(const LinkingContext &ctx, raw_ostream &diagnostics) {
+    auto filePath = path(ctx);
+    if (!filePath &&
+        error_code(filePath) == llvm::errc::no_such_file_or_directory)
+      return make_error_code(llvm::errc::no_such_file_or_directory);
+
+    // Create a memory buffer
+    OwningPtr<llvm::MemoryBuffer> opmb;
+    llvm::error_code ec;
+
+    if ((ec = llvm::MemoryBuffer::getFileOrSTDIN(*filePath, opmb)))
+      return ec;
+
+    std::unique_ptr<MemoryBuffer> mb(opmb.take());
+    _buffer = std::move(mb);
+
+    ec = _ctx.getDefaultReader().parseFile(_buffer, _files);
+    return ec;
+  }
+
+  /// \brief Return the file that has to be processed by the resolver
+  /// to resolve atoms. This iterates over all the files thats part
+  /// of this node. Returns no_more_files when there are no files to be
+  /// processed
+  virtual ErrorOr<File &> getNextFile() {
+    if (_files.size() == _nextFileIndex)
+      return make_error_code(input_graph_error::no_more_files);
+    return *_files[_nextFileIndex++];
+  }
+
   /// \brief Dump the Input Element
   virtual bool dump(raw_ostream &) { return true; }
 
 private:
-  const CoreLinkingContext &_ctx;
+  CoreLinkingContext &_ctx;
 };
 
 } // namespace lld

Modified: lld/trunk/include/lld/Driver/DarwinInputGraph.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/include/lld/Driver/DarwinInputGraph.h?rev=192081&r1=192080&r2=192081&view=diff
==============================================================================
--- lld/trunk/include/lld/Driver/DarwinInputGraph.h (original)
+++ lld/trunk/include/lld/Driver/DarwinInputGraph.h Sun Oct  6 21:47:09 2013
@@ -34,15 +34,52 @@ public:
     return a->kind() == InputElement::Kind::File;
   }
 
-  virtual llvm::ErrorOr<std::unique_ptr<lld::LinkerInput> >
-  createLinkerInput(const lld::LinkingContext &);
-
   /// \brief validates the Input Element
   virtual bool validate() {
     (void)_ctx;
     return true;
   }
 
+  /// \brief Parse the input file to lld::File.
+  llvm::error_code parse(const LinkingContext &ctx, raw_ostream &diagnostics) {
+    auto filePath = path(ctx);
+    if (!filePath &&
+        error_code(filePath) == llvm::errc::no_such_file_or_directory)
+      return make_error_code(llvm::errc::no_such_file_or_directory);
+
+    // Create a memory buffer
+    OwningPtr<llvm::MemoryBuffer> opmb;
+    llvm::error_code ec;
+
+    if ((ec = llvm::MemoryBuffer::getFileOrSTDIN(*filePath, opmb)))
+      return ec;
+
+    std::unique_ptr<MemoryBuffer> mb(opmb.take());
+    _buffer = std::move(mb);
+
+    if (ctx.logInputFiles())
+      diagnostics << _buffer->getBufferIdentifier() << "\n";
+
+    // YAML file is identified by a .objtxt extension
+    // FIXME : Identify YAML files by using a magic
+    if (filePath->endswith(".objtxt")) {
+      ec = _ctx.getYAMLReader().parseFile(_buffer, _files);
+      if (!ec)
+        return ec;
+    }
+    return llvm::error_code::success();
+  }
+
+  /// \brief Return the file that has to be processed by the resolver
+  /// to resolve atoms. This iterates over all the files thats part
+  /// of this node. Returns no_more_files when there are no files to be
+  /// processed
+  virtual ErrorOr<File &> getNextFile() {
+    if (_files.size() == _nextFileIndex)
+      return make_error_code(input_graph_error::no_more_files);
+    return *_files[_nextFileIndex++];
+  }
+
   /// \brief Dump the Input Element
   virtual bool dump(raw_ostream &) { return true; }
 

Modified: lld/trunk/include/lld/Driver/GnuLdInputGraph.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/include/lld/Driver/GnuLdInputGraph.h?rev=192081&r1=192080&r2=192081&view=diff
==============================================================================
--- lld/trunk/include/lld/Driver/GnuLdInputGraph.h (original)
+++ lld/trunk/include/lld/Driver/GnuLdInputGraph.h Sun Oct  6 21:47:09 2013
@@ -17,8 +17,10 @@
 #ifndef LLD_DRIVER_GNU_LD_INPUT_GRAPH_H
 #define LLD_DRIVER_GNU_LD_INPUT_GRAPH_H
 
+#include "lld/Core/Resolver.h"
 #include "lld/Driver/InputGraph.h"
 #include "lld/ReaderWriter/ELFLinkingContext.h"
+#include "lld/ReaderWriter/FileArchive.h"
 
 namespace lld {
 
@@ -26,9 +28,10 @@ namespace lld {
 class ELFFileNode : public FileNode {
 public:
   ELFFileNode(ELFLinkingContext &ctx, StringRef path,
-              std::vector<StringRef> searchPath, bool isWholeArchive = false,
-              bool asNeeded = false, bool dashlPrefix = false)
-      : FileNode(path), _elfLinkingContext(ctx),
+              std::vector<StringRef> searchPath, int64_t ordinal = -1,
+              bool isWholeArchive = false, bool asNeeded = false,
+              bool dashlPrefix = false)
+      : FileNode(path, ordinal), _elfLinkingContext(ctx),
         _isWholeArchive(isWholeArchive), _asNeeded(asNeeded),
         _isDashlPrefix(dashlPrefix) {
     std::copy(searchPath.begin(), searchPath.end(),
@@ -41,9 +44,6 @@ public:
 
   virtual llvm::ErrorOr<StringRef> path(const LinkingContext &ctx) const;
 
-  virtual llvm::ErrorOr<std::unique_ptr<lld::LinkerInput> >
-  createLinkerInput(const lld::LinkingContext &);
-
   /// \brief validates the Input Element
   virtual bool validate() { return true; }
 
@@ -70,13 +70,99 @@ public:
     return true;
   }
 
+  /// \brief Parse the input file to lld::File.
+  llvm::error_code parse(const LinkingContext &ctx, raw_ostream &diagnostics) {
+    auto filePath = path(ctx);
+    if (!filePath &&
+        error_code(filePath) == llvm::errc::no_such_file_or_directory)
+      return make_error_code(llvm::errc::no_such_file_or_directory);
+
+    // Create a memory buffer
+    OwningPtr<llvm::MemoryBuffer> opmb;
+    llvm::error_code ec;
+
+    if ((ec = llvm::MemoryBuffer::getFileOrSTDIN(*filePath, opmb)))
+      return ec;
+
+    std::unique_ptr<MemoryBuffer> mb(opmb.take());
+    _buffer = std::move(mb);
+
+    // If tracing is enabled, print the files being processed.
+    if (ctx.logInputFiles())
+      diagnostics << _buffer->getBufferIdentifier() << "\n";
+
+    // YAML file is identified by a .objtxt extension
+    // FIXME : Identify YAML files by using a magic
+    if (filePath->endswith(".objtxt")) {
+      ec = _elfLinkingContext.getYAMLReader().parseFile(_buffer, _files);
+      if (!ec)
+        return ec;
+    }
+
+    // Identify File type
+    llvm::sys::fs::file_magic FileType =
+        llvm::sys::fs::identify_magic(_buffer->getBuffer());
+
+    switch (FileType) {
+    case llvm::sys::fs::file_magic::elf_relocatable:
+    case llvm::sys::fs::file_magic::elf_shared_object:
+      // Call the default reader to read object files and shared objects
+      ec = _elfLinkingContext.getDefaultReader().parseFile(_buffer, _files);
+      break;
+
+    case llvm::sys::fs::file_magic::archive: {
+      // Process archive files. If Whole Archive option is set,
+      // parse all members of the archive.
+      std::unique_ptr<FileArchive> fileArchive(
+          new FileArchive(ctx, std::move(_buffer), ec, _isWholeArchive));
+      if (_isWholeArchive) {
+        fileArchive->parseAllMembers(_files);
+        _archiveFile = std::move(fileArchive);
+      } else {
+        _files.push_back(std::move(fileArchive));
+      }
+      break;
+    }
+
+    default:
+      // Process Linker script
+      _elfLinkingContext.getLinkerScriptReader().parseFile(_buffer, _files);
+      break;
+    }
+    return ec;
+  }
+
+  /// \brief This is used by Group Nodes, when there is a need to reset the
+  /// the file to be processed next. When handling a group node that contains
+  /// Input elements, if the group node has to be reprocessed, the linker needs
+  /// to start processing files as part of the inputelement from beginning.
+  /// reset the next file index to 0 only if the node is an archive library or
+  /// a shared library
+  virtual void resetNextFileIndex() {
+    if ((!_isWholeArchive && (_files[0]->kind() == File::kindArchiveLibrary)) ||
+        (_files[0]->kind() == File::kindSharedLibrary))
+      _nextFileIndex = 0;
+    return;
+  }
+
+  /// \brief Return the file that has to be processed by the resolver
+  /// to resolve atoms. This iterates over all the files thats part
+  /// of this node. Returns no_more_files when there are no files to be
+  /// processed
+  virtual ErrorOr<File &> getNextFile() {
+    if (_nextFileIndex == _files.size())
+      return make_error_code(input_graph_error::no_more_files);
+    return *_files[_nextFileIndex++];
+  }
+
 private:
   llvm::BumpPtrAllocator _alloc;
-  ELFLinkingContext &_elfLinkingContext;
+  const ELFLinkingContext &_elfLinkingContext;
   bool _isWholeArchive;
   bool _asNeeded;
   bool _isDashlPrefix;
   std::vector<StringRef> _libraryPaths;
+  std::unique_ptr<FileArchive> _archiveFile;
 };
 
 /// \brief Represents a ELF control node
@@ -88,12 +174,6 @@ public:
     return a->kind() == InputElement::Kind::Control;
   }
 
-  virtual llvm::ErrorOr<std::unique_ptr<lld::LinkerInput> >
-  createLinkerInput(const lld::LinkingContext &) {
-    // FIXME : create a linker input to handle groups
-    return llvm::make_error_code(llvm::errc::no_such_file_or_directory);
-  }
-
   /// \brief Validate the options
   virtual bool validate() {
     (void)_elfLinkingContext;
@@ -103,8 +183,52 @@ public:
   /// \brief Dump the ELFGroup
   virtual bool dump(llvm::raw_ostream &) { return true; }
 
+  /// \brief Parse the group members.
+  llvm::error_code parse(const LinkingContext &ctx, raw_ostream &diagnostics) {
+    for (auto &ei : _elements)
+      if (error_code ec = ei->parse(ctx, diagnostics))
+        return ec;
+    return error_code::success();
+  }
+
+  /// \brief Return the file that has to be processed by the resolver
+  /// to resolve atoms. This iterates over all the elements thats part
+  /// of this node.
+  virtual ErrorOr<File &> getNextFile() {
+    // Does the linker need to process the elements again ?
+    bool again = false;
+    // If there are no elements, move on to the next input element
+    if (_elements.size() == 0)
+      return make_error_code(input_graph_error::no_more_files);
+    // If we have processed all the elements as part of this node
+    // check the resolver status for each input element and if the status
+    // has not changed, move onto the next file.
+    if (_nextElementIndex == _elements.size()) {
+      for (auto &elem : _elements) {
+        if (elem->getResolverState() == Resolver::StateNoChange) {
+          again = true;
+          break;
+        }
+      }
+      if (!again)
+        return make_error_code(input_graph_error::no_more_files);
+      _nextElementIndex = 0;
+      // Reset the next file to be processed as part of each element
+      for (auto &elem : _elements)
+        elem->resetNextFileIndex();
+    }
+    auto file = _elements[_nextElementIndex]->getNextFile();
+    // Move on to the next element if we have finished processing all
+    // the files in the input element
+    if (error_code(file) == input_graph_error::no_more_files)
+      _nextElementIndex++;
+    else
+      return *file;
+    return getNextFile();
+  }
+
 private:
-  ELFLinkingContext &_elfLinkingContext;
+  const ELFLinkingContext &_elfLinkingContext;
 };
 
 } // namespace lld

Modified: lld/trunk/include/lld/Driver/InputGraph.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/include/lld/Driver/InputGraph.h?rev=192081&r1=192080&r2=192081&view=diff
==============================================================================
--- lld/trunk/include/lld/Driver/InputGraph.h (original)
+++ lld/trunk/include/lld/Driver/InputGraph.h Sun Oct  6 21:47:09 2013
@@ -17,8 +17,11 @@
 #define LLD_DRIVER_INPUT_GRAPH_H
 
 #include "lld/Core/File.h"
-#include "lld/Core/LLVM.h"
-#include "lld/Core/LinkerInput.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Option/ArgList.h"
+
+#include "llvm/Support/ErrorOr.h"
+#include "llvm/Support/MemoryBuffer.h"
 #include "llvm/Support/raw_ostream.h"
 
 #include <memory>
@@ -47,8 +50,16 @@ public:
   typedef std::vector<std::unique_ptr<File> > FileVectorT;
   typedef FileVectorT::iterator FileIterT;
 
+  /// Where do we want to insert the input element when calling the
+  /// insertElementAt, insertOneElementAt API's.
+  enum Position : uint8_t {
+    ANY,
+    BEGIN,
+    END
+  };
+
   /// \brief Initialize the inputgraph
-  InputGraph() : _ordinal(0), _numElements(0), _numFiles(0) {}
+  InputGraph() : _ordinal(0), _nextElementIndex(0) {}
 
   /// \brief Adds a node into the InputGraph
   virtual bool addInputElement(std::unique_ptr<InputElement>);
@@ -56,33 +67,18 @@ public:
   /// \brief Set Ordinals for all the InputElements that form the InputGraph
   virtual bool assignOrdinals();
 
+  /// \brief Set ordinals for all the Files that are part of the InputElements
+  virtual bool assignFileOrdinals(uint64_t &ordinal);
+
   /// Destructor
   virtual ~InputGraph() {}
 
-  /// Total number of InputFiles
-  virtual int64_t numFiles() const { return _numFiles; }
-
-  /// Total number of InputElements
-  virtual int64_t numElements() const { return _numElements; }
-
-  /// Total number of Internal files
-  virtual int64_t numInternalFiles() const { return _internalFiles.size(); }
-
   /// \brief Do postprocessing of the InputGraph if there is a need for the
   /// to provide additional information to the user, also rearranges
   /// InputElements by their ordinals. If an user wants to place an input file
   /// at the desired position, the user can do that
   virtual void doPostProcess();
 
-  virtual void addInternalFile(std::vector<std::unique_ptr<File> > inputFiles) {
-    for (auto &ai : inputFiles)
-      _internalFiles.push_back(std::move(ai));
-  }
-
-  range<FileIterT> internalFiles() {
-    return make_range(_internalFiles.begin(), _internalFiles.end());
-  }
-
   range<InputElementIterT> inputElements() {
     return make_range(_inputArgs.begin(), _inputArgs.end());
   }
@@ -90,6 +86,9 @@ public:
   /// \brief Validate the input graph
   virtual bool validate();
 
+  // \brief Does the inputGraph contain any elements
+  int64_t size() const { return _inputArgs.size(); }
+
   /// \brief Dump the input Graph
   virtual bool dump(raw_ostream &diagnostics = llvm::errs());
 
@@ -97,17 +96,31 @@ public:
     return (*_inputArgs[index]);
   }
 
-private:
+  /// \brief Insert a vector of elements into the input graph at position.
+  virtual void insertElementsAt(std::vector<std::unique_ptr<InputElement> >,
+                                Position position, int32_t pos = 0);
+
+  /// \brief Insert an element into the input graph at position.
+  virtual void insertOneElementAt(std::unique_ptr<InputElement>,
+                                  Position position, int32_t pos = 0);
+
+  /// \brief Helper functions for the resolver
+  virtual ErrorOr<InputElement *> getNextInputElement();
+
+  /// \brief Set the index on what inputElement has to be returned
+  virtual ErrorOr<void> setNextElementIndex(uint32_t index = 0);
+
+  /// \brief Reset the inputGraph for the inputGraph to start processing
+  /// files from the beginning
+  virtual ErrorOr<void> reset() { return setNextElementIndex(0); }
+
+protected:
   // Input arguments
   InputElementVectorT _inputArgs;
-  // Extra Input files
-  FileVectorT _internalFiles;
   // Ordinals
   int64_t _ordinal;
-  // Total number of InputElements
-  int64_t _numElements;
-  // Total number of FileNodes
-  int64_t _numFiles;
+  // Index of the next element to be processed
+  uint32_t _nextElementIndex;
 };
 
 /// \brief This describes each element in the InputGraph. The Kind
@@ -115,16 +128,16 @@ private:
 class InputElement {
 public:
   /// Each input element in the graph can be a File or a control
-  enum class Kind : uint8_t{
-    Control, // Represents a type associated with ControlNodes
-    File     // Represents a type associated with File Nodes
+  enum class Kind : uint8_t {
+    Control,    // Represents a type associated with ControlNodes
+    SimpleFile, // Represents a type reserved for internal files
+    File        // Represents a type associated with File Nodes
   };
 
   /// \brief Initialize the Input Element, The ordinal value of an input Element
   /// is initially set to -1, if the user wants to override its ordinal,
   /// let the user do it
-  InputElement(Kind type, int64_t ordinal = -1)
-      : _kind(type), _ordinal(-1), _weight(0) {}
+  InputElement(Kind type, int64_t ordinal = -1);
 
   virtual ~InputElement() {}
 
@@ -136,6 +149,10 @@ public:
       _ordinal = ordinal;
   }
 
+  /// \brief Assign File ordinals for files contained
+  /// in the InputElement
+  virtual void assignFileOrdinals(uint64_t &fileOrdinal) = 0;
+
   virtual int64_t getOrdinal() const { return _ordinal; }
 
   virtual int64_t weight() const { return _weight; }
@@ -148,10 +165,29 @@ public:
   /// \brief Dump the Input Element
   virtual bool dump(raw_ostream &diagnostics) = 0;
 
-private:
-  Kind _kind;
-  int64_t _ordinal;
-  int64_t _weight;
+  /// \brief parse the input element
+  virtual llvm::error_code parse(const LinkingContext &, raw_ostream &) = 0;
+
+  /// \brief functions for the resolver to use
+
+  /// Get the next file to be processed by the resolver
+  virtual ErrorOr<File &> getNextFile() = 0;
+
+  /// \brief Set the resolver state for the element
+  virtual void setResolverState(int32_t state) { _resolveState = state; }
+
+  /// \brief Get the resolver state for the element
+  virtual int32_t getResolverState() const { return _resolveState; }
+
+  /// Process files again.
+  virtual void resetNextFileIndex() { _nextFileIndex = 0; }
+
+protected:
+  Kind _kind;              // The type of the Element
+  int64_t _ordinal;        // The ordinal value
+  int64_t _weight;         // Weight of the file
+  int32_t _resolveState;   // The resolve state
+  uint32_t _nextFileIndex; // The file that would be processed by the resolver
 };
 
 /// \brief The Control class represents a control node in the InputGraph
@@ -168,7 +204,7 @@ public:
                   ControlNode::ControlKind::Simple,
               int64_t _ordinal = -1)
       : InputElement(InputElement::Kind::Control, _ordinal),
-        _controlKind(controlKind) {}
+        _controlKind(controlKind), _nextElementIndex(0) {}
 
   virtual ~ControlNode() {}
 
@@ -189,26 +225,25 @@ public:
     return a->kind() == InputElement::Kind::Control;
   }
 
-  /// Does the control node have any more elements
-  bool hasMoreElements() const { return (_elements.size() != 0); }
-
-  /// \brief Iterators to iterate the
-  InputGraph::InputElementIterT begin() { return _elements.begin(); }
-
-  InputGraph::InputElementIterT end() { return _elements.end(); }
-
-  /// \brief Create a lld::File node from the FileNode
-  virtual llvm::ErrorOr<std::unique_ptr<lld::LinkerInput> >
-  createLinkerInput(const LinkingContext &targetInfo) = 0;
+  range<InputGraph::InputElementIterT> elements() {
+    return make_range(_elements.begin(), _elements.end());
+  }
 
-private:
-  ControlKind _controlKind;
+  /// \brief Assign File ordinals for files contained
+  /// in the InputElement
+  virtual void assignFileOrdinals(uint64_t &startOrdinal);
 
 protected:
+  ControlKind _controlKind;
   InputGraph::InputElementVectorT _elements;
+  uint32_t _nextElementIndex;
 };
 
 /// \brief Represents an Input file in the graph
+///
+/// This class represents an input to the linker. It create the MemoryBuffer
+/// lazily when needed based on the file path. It can also take a MemoryBuffer
+/// directly.
 class FileNode : public InputElement {
 public:
   FileNode(StringRef path, int64_t ordinal = -1)
@@ -218,6 +253,10 @@ public:
     return _path;
   }
 
+  // The saved input path thats used when a file is not found while
+  // trying to parse a file
+  StringRef getUserPath() const { return _path; }
+
   virtual ~FileNode() {}
 
   /// \brief Casting support
@@ -232,12 +271,40 @@ public:
     return twine.str();
   }
 
-  /// \brief Create a lld::File node from the FileNode
-  virtual llvm::ErrorOr<std::unique_ptr<lld::LinkerInput> >
-  createLinkerInput(const LinkingContext &targetInfo);
+  /// \brief Memory buffer pointed by the file.
+  llvm::MemoryBuffer &getBuffer() const {
+    assert(_buffer);
+    return *_buffer;
+  }
+
+  /// \brief Return the memory buffer and transfer ownership.
+  std::unique_ptr<llvm::MemoryBuffer> takeBuffer() {
+    assert(_buffer);
+    return std::move(_buffer);
+  }
+
+  /// \brief Get the list of files
+  range<InputGraph::FileIterT> files() {
+    return make_range(_files.begin(), _files.end());
+  }
+
+  /// \brief  number of files.
+  int64_t numFiles() const { return _files.size(); }
+
+  /// \brief add a file to the list of files
+  virtual void addFiles(InputGraph::FileVectorT files) {
+    for (auto &ai : files)
+      _files.push_back(std::move(ai));
+  }
+
+  /// \brief Assign File ordinals for files contained
+  /// in the InputElement
+  virtual void assignFileOrdinals(uint64_t &startOrdinal);
 
 protected:
   StringRef _path;
+  InputGraph::FileVectorT _files;
+  std::unique_ptr<llvm::MemoryBuffer> _buffer;
 };
 
 /// \brief A Control node which contains a group of InputElements
@@ -256,11 +323,76 @@ public:
     _elements.push_back(std::move(element));
     return true;
   }
-
-  virtual llvm::ErrorOr<std::unique_ptr<lld::LinkerInput> >
-  createLinkerInput(const lld::LinkingContext &) = 0;
 };
 
+/// \brief Represents Internal Input files
+class SimpleFileNode : public InputElement {
+public:
+  SimpleFileNode(StringRef path, int64_t ordinal = -1)
+      : InputElement(InputElement::Kind::SimpleFile, ordinal), _path(path) {}
+
+  virtual llvm::ErrorOr<StringRef> path(const LinkingContext &) const {
+    return _path;
+  }
+
+  // The saved input path thats used when a file is not found while
+  // trying to parse a file
+  StringRef getUserPath() const { return _path; }
+
+  virtual ~SimpleFileNode() {}
+
+  /// \brief Casting support
+  static inline bool classof(const InputElement *a) {
+    return a->kind() == InputElement::Kind::SimpleFile;
+  }
+
+  /// \brief Get the list of files
+  range<InputGraph::FileIterT> files() {
+    return make_range(_files.begin(), _files.end());
+  }
+
+  /// \brief  number of files.
+  int64_t numFiles() const { return _files.size(); }
+
+  /// \brief add a file to the list of files
+  virtual void appendInputFile(std::unique_ptr<File> f) {
+    _files.push_back(std::move(f));
+  }
+
+  /// \brief add a file to the list of files
+  virtual void appendInputFiles(InputGraph::FileVectorT files) {
+    for (auto &ai : files)
+      _files.push_back(std::move(ai));
+  }
+
+  /// \brief validates the Input Element
+  virtual bool validate() { return true; }
+
+  /// \brief Dump the Input Element
+  virtual bool dump(raw_ostream &) { return true; }
+
+  /// \brief parse the input element
+  virtual llvm::error_code parse(const LinkingContext &, raw_ostream &) {
+    return error_code::success();
+  }
+
+  virtual ErrorOr<File &> getNextFile() {
+    if (_nextFileIndex == _files.size())
+      return make_error_code(input_graph_error::no_more_files);
+    return *_files[_nextFileIndex++];
+  }
+
+  // Do nothing here.
+  virtual void resetNextFileIndex() {}
+
+  /// \brief Assign File ordinals for files contained
+  /// in the InputElement
+  virtual void assignFileOrdinals(uint64_t &startOrdinal);
+
+protected:
+  StringRef _path;
+  InputGraph::FileVectorT _files;
+};
 } // namespace lld
 
 #endif // LLD_INPUTGRAPH_H

Modified: lld/trunk/include/lld/Driver/WinLinkInputGraph.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/include/lld/Driver/WinLinkInputGraph.h?rev=192081&r1=192080&r2=192081&view=diff
==============================================================================
--- lld/trunk/include/lld/Driver/WinLinkInputGraph.h (original)
+++ lld/trunk/include/lld/Driver/WinLinkInputGraph.h Sun Oct  6 21:47:09 2013
@@ -19,6 +19,7 @@
 
 #include "lld/Driver/InputGraph.h"
 #include "lld/ReaderWriter/PECOFFLinkingContext.h"
+#include "lld/ReaderWriter/FileArchive.h"
 
 #include <map>
 
@@ -36,36 +37,77 @@ public:
 
   virtual llvm::ErrorOr<StringRef> path(const LinkingContext &ctx) const;
 
+  /// \brief Parse the input file to lld::File.
+  llvm::error_code parse(const LinkingContext &ctx, raw_ostream &diagnostics) {
+    auto filePath = path(ctx);
+    if (!filePath &&
+        error_code(filePath) == llvm::errc::no_such_file_or_directory)
+      return make_error_code(llvm::errc::no_such_file_or_directory);
+
+    // Create a memory buffer
+    OwningPtr<llvm::MemoryBuffer> opmb;
+    llvm::error_code ec;
+
+    if ((ec = llvm::MemoryBuffer::getFileOrSTDIN(*filePath, opmb)))
+      return ec;
+
+    std::unique_ptr<MemoryBuffer> mb(opmb.take());
+    _buffer = std::move(mb);
+
+    if (ctx.logInputFiles())
+      diagnostics << _buffer->getBufferIdentifier() << "\n";
+
+    // YAML file is identified by a .objtxt extension
+    // FIXME : Identify YAML files by using a magic
+    if (filePath->endswith(".objtxt")) {
+      ec = _ctx.getYAMLReader().parseFile(_buffer, _files);
+      if (!ec)
+        return ec;
+    }
+
+    llvm::sys::fs::file_magic FileType =
+        llvm::sys::fs::identify_magic(_buffer->getBuffer());
+
+    std::unique_ptr<File> f;
+
+    switch (FileType) {
+    case llvm::sys::fs::file_magic::archive:
+      // Archive File
+      f.reset(new FileArchive(ctx, std::move(_buffer), ec, false));
+      _files.push_back(std::move(f));
+      break;
+
+    case llvm::sys::fs::file_magic::coff_object:
+    default:
+      ec = _ctx.getDefaultReader().parseFile(_buffer, _files);
+      break;
+    }
+    return ec;
+  }
+
   /// \brief validates the Input Element
   virtual bool validate() { return true; }
 
   /// \brief Dump the Input Element
   virtual bool dump(raw_ostream &) { return true; }
 
-private:
+  virtual ErrorOr<File &> getNextFile() {
+    if (_nextFileIndex == _files.size())
+      return make_error_code(input_graph_error::no_more_files);
+    return *_files[_nextFileIndex++];
+  }
+
+protected:
   const PECOFFLinkingContext &_ctx;
 };
 
 /// \brief Represents a PECOFF Library File
-class PECOFFLibraryNode : public FileNode {
+class PECOFFLibraryNode : public PECOFFFileNode {
 public:
   PECOFFLibraryNode(PECOFFLinkingContext &ctx, StringRef path)
-      : FileNode(path), _ctx(ctx) {}
-
-  static inline bool classof(const InputElement *a) {
-    return a->kind() == InputElement::Kind::File;
-  }
+      : PECOFFFileNode(ctx, path) {}
 
   virtual llvm::ErrorOr<StringRef> path(const LinkingContext &ctx) const;
-
-  /// \brief validates the Input Element
-  virtual bool validate() { return true; }
-
-  /// \brief Dump the Input Element
-  virtual bool dump(raw_ostream &) { return true; }
-
-private:
-  const PECOFFLinkingContext &_ctx;
 };
 
 } // namespace lld

Modified: lld/trunk/include/lld/ReaderWriter/CoreLinkingContext.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/include/lld/ReaderWriter/CoreLinkingContext.h?rev=192081&r1=192080&r2=192081&view=diff
==============================================================================
--- lld/trunk/include/lld/ReaderWriter/CoreLinkingContext.h (original)
+++ lld/trunk/include/lld/ReaderWriter/CoreLinkingContext.h Sun Oct  6 21:47:09 2013
@@ -27,12 +27,10 @@ public:
   virtual ErrorOr<Reference::Kind> relocKindFromString(StringRef str) const;
   virtual ErrorOr<std::string> stringFromRelocKind(Reference::Kind kind) const;
 
-  virtual error_code
-  parseFile(LinkerInput &input,
-            std::vector<std::unique_ptr<File> > &result) const;
-
   void addPassNamed(StringRef name) { _passNames.push_back(name); }
 
+  virtual Reader &getDefaultReader() const { return *_reader; }
+
 protected:
   virtual Writer &writer() const;
 

Modified: lld/trunk/include/lld/ReaderWriter/ELFLinkingContext.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/include/lld/ReaderWriter/ELFLinkingContext.h?rev=192081&r1=192080&r2=192081&view=diff
==============================================================================
--- lld/trunk/include/lld/ReaderWriter/ELFLinkingContext.h (original)
+++ lld/trunk/include/lld/ReaderWriter/ELFLinkingContext.h Sun Oct  6 21:47:09 2013
@@ -89,10 +89,6 @@ public:
     return true;
   }
 
-  virtual error_code
-  parseFile(LinkerInput &input,
-            std::vector<std::unique_ptr<File> > &result) const;
-
   static std::unique_ptr<ELFLinkingContext> create(llvm::Triple);
 
   /// \brief Does this relocation belong in the dynamic plt relocation table?
@@ -118,6 +114,10 @@ public:
     return getDefaultInterpreter();
   }
 
+  virtual Reader &getDefaultReader() const { return *_elfReader; }
+
+  virtual Reader &getLinkerScriptReader() const { return *_linkerScriptReader; }
+
   /// \brief Does the output have dynamic sections.
   virtual bool isDynamic() const;
 
@@ -215,7 +215,7 @@ protected:
   virtual Writer &writer() const;
 
   /// Method to create a internal file for an undefined symbol
-  virtual std::unique_ptr<File> createUndefinedSymbolFile();
+  virtual std::unique_ptr<File> createUndefinedSymbolFile() const;
 
   uint16_t _outputELFType; // e.g ET_EXEC
   llvm::Triple _triple;

Modified: lld/trunk/include/lld/ReaderWriter/MachOLinkingContext.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/include/lld/ReaderWriter/MachOLinkingContext.h?rev=192081&r1=192080&r2=192081&view=diff
==============================================================================
--- lld/trunk/include/lld/ReaderWriter/MachOLinkingContext.h (original)
+++ lld/trunk/include/lld/ReaderWriter/MachOLinkingContext.h Sun Oct  6 21:47:09 2013
@@ -32,10 +32,6 @@ public:
   virtual ErrorOr<std::string> stringFromRelocKind(Reference::Kind kind) const;
   virtual bool validateImpl(raw_ostream &diagnostics);
 
-  virtual error_code
-  parseFile(LinkerInput &input,
-            std::vector<std::unique_ptr<File> > &result) const;
-
   uint32_t getCPUType() const;
   uint32_t getCPUSubType() const;
 
@@ -72,6 +68,8 @@ public:
   void setDoNothing(bool value) { _doNothing = value; }
   bool doNothing() const { return _doNothing; }
 
+  virtual Reader &getDefaultReader() const { return *_machoReader; }
+
   /// \brief The dylib's binary compatibility version, in the raw uint32 format.
   ///
   /// When building a dynamic library, this is the compatibility version that

Modified: lld/trunk/include/lld/ReaderWriter/PECOFFLinkingContext.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/include/lld/ReaderWriter/PECOFFLinkingContext.h?rev=192081&r1=192080&r2=192081&view=diff
==============================================================================
--- lld/trunk/include/lld/ReaderWriter/PECOFFLinkingContext.h (original)
+++ lld/trunk/include/lld/ReaderWriter/PECOFFLinkingContext.h Sun Oct  6 21:47:09 2013
@@ -56,16 +56,15 @@ public:
     IMAGE_DLL
   };
 
-  virtual error_code
-  parseFile(LinkerInput &input,
-            std::vector<std::unique_ptr<File> > &result) const;
+  virtual Reader &getDefaultReader() const { return *_reader; }
 
   virtual Writer &writer() const;
   virtual bool validateImpl(raw_ostream &diagnostics);
 
   virtual void addPasses(PassManager &pm) const;
 
-  virtual void addImplicitFiles(InputFiles &) const;
+  virtual bool
+  createImplicitFiles(std::vector<std::unique_ptr<File> > &result) const;
 
   void appendInputSearchPath(StringRef dirPath) {
     _inputSearchPaths.push_back(dirPath);
@@ -177,10 +176,10 @@ public:
 
 protected:
   /// Method to create a internal file for the entry symbol
-  virtual std::unique_ptr<File> createEntrySymbolFile();
+  virtual std::unique_ptr<File> createEntrySymbolFile() const;
 
   /// Method to create a internal file for an undefined symbol
-  virtual std::unique_ptr<File> createUndefinedSymbolFile();
+  virtual std::unique_ptr<File> createUndefinedSymbolFile() const;
 
 private:
   // The start address for the program. The default value for the executable is

Modified: lld/trunk/include/lld/ReaderWriter/Reader.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/include/lld/ReaderWriter/Reader.h?rev=192081&r1=192080&r2=192081&view=diff
==============================================================================
--- lld/trunk/include/lld/ReaderWriter/Reader.h (original)
+++ lld/trunk/include/lld/ReaderWriter/Reader.h Sun Oct  6 21:47:09 2013
@@ -19,7 +19,6 @@
 namespace lld {
 class ELFLinkingContext;
 class File;
-class LinkerInput;
 class LinkingContext;
 class PECOFFLinkingContext;
 
@@ -36,8 +35,9 @@ public:
   /// file) and create a File object.
   ///
   /// On success, the resulting File object takes ownership of the MemoryBuffer.
-  virtual error_code parseFile(LinkerInput &input,
-                          std::vector<std::unique_ptr<File>> &result) const = 0;
+  virtual error_code
+  parseFile(std::unique_ptr<MemoryBuffer> &mb,
+            std::vector<std::unique_ptr<File> > &result) const = 0;
 
 protected:
   // only concrete subclasses can be instantiated

Modified: lld/trunk/include/lld/ReaderWriter/ReaderArchive.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/include/lld/ReaderWriter/ReaderArchive.h?rev=192081&r1=192080&r2=192081&view=diff
==============================================================================
--- lld/trunk/include/lld/ReaderWriter/ReaderArchive.h (original)
+++ lld/trunk/include/lld/ReaderWriter/ReaderArchive.h Sun Oct  6 21:47:09 2013
@@ -24,7 +24,6 @@
 namespace lld {
 class File;
 class LinkingContext;
-class LinkerInput;
 
 /// \brief ReaderArchive is a class for reading archive libraries
 class ReaderArchive : public Reader {
@@ -34,8 +33,8 @@ public:
 
   /// \brief Returns a vector of Files that are contained in the archive file
   ///        pointed to by the Memorybuffer
-  error_code parseFile(LinkerInput &input,
-                       std::vector<std::unique_ptr<File>> &result) const;
+  error_code parseFile(std::unique_ptr<llvm::MemoryBuffer> &mb,
+                       std::vector<std::unique_ptr<File> > &result) const;
 
 private:
   mutable std::unique_ptr<llvm::object::Archive> _archive;

Modified: lld/trunk/include/lld/ReaderWriter/ReaderLinkerScript.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/include/lld/ReaderWriter/ReaderLinkerScript.h?rev=192081&r1=192080&r2=192081&view=diff
==============================================================================
--- lld/trunk/include/lld/ReaderWriter/ReaderLinkerScript.h (original)
+++ lld/trunk/include/lld/ReaderWriter/ReaderLinkerScript.h Sun Oct  6 21:47:09 2013
@@ -15,7 +15,6 @@
 
 namespace lld {
 class File;
-class LinkerInput;
 class LinkingContext;
 
 /// \brief ReaderLinkerScript is a class for reading linker scripts
@@ -26,8 +25,8 @@ public:
 
   /// \brief Returns a vector of Files that are contained in the archive file
   ///        pointed to by the Memorybuffer
-  error_code parseFile(LinkerInput &input,
-                       std::vector<std::unique_ptr<File>> &result) const;
+  error_code parseFile(std::unique_ptr<llvm::MemoryBuffer> &mb,
+                       std::vector<std::unique_ptr<File> > &result) const;
 };
 
 } // end namespace lld

Modified: lld/trunk/include/lld/ReaderWriter/Writer.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/include/lld/ReaderWriter/Writer.h?rev=192081&r1=192080&r2=192081&view=diff
==============================================================================
--- lld/trunk/include/lld/ReaderWriter/Writer.h (original)
+++ lld/trunk/include/lld/ReaderWriter/Writer.h Sun Oct  6 21:47:09 2013
@@ -17,7 +17,6 @@
 namespace lld {
 class ELFLinkingContext;
 class File;
-class InputFiles;
 class MachOLinkingContext;
 class PECOFFLinkingContext;
 class LinkingContext;
@@ -35,7 +34,7 @@ public:
   /// \brief This method is called by Core Linking to give the Writer a chance
   /// to add file format specific "files" to set of files to be linked. This is
   /// how file format specific atoms can be added to the link.
-  virtual void addFiles(InputFiles&) {}
+  virtual bool createImplicitFiles(std::vector<std::unique_ptr<File> > &);
 
 protected:
   // only concrete subclasses can be instantiated

Modified: lld/trunk/lib/Core/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/Core/CMakeLists.txt?rev=192081&r1=192080&r2=192081&view=diff
==============================================================================
--- lld/trunk/lib/Core/CMakeLists.txt (original)
+++ lld/trunk/lib/Core/CMakeLists.txt Sun Oct  6 21:47:09 2013
@@ -4,9 +4,10 @@ add_lld_library(lldCore
   DefinedAtom.cpp
   Error.cpp
   File.cpp
-  InputFiles.cpp
   LinkingContext.cpp
   PassManager.cpp
   Resolver.cpp
   SymbolTable.cpp
   )
+
+target_link_libraries(lldCore lldNative)

Modified: lld/trunk/lib/Core/Error.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/Core/Error.cpp?rev=192081&r1=192080&r2=192081&view=diff
==============================================================================
--- lld/trunk/lib/Core/Error.cpp (original)
+++ lld/trunk/lib/Core/Error.cpp Sun Oct  6 21:47:09 2013
@@ -112,3 +112,28 @@ const llvm::error_category &lld::linker_
   return o;
 }
 
+class _input_graph_error_category : public llvm::_do_message {
+public:
+  virtual const char *name() const { return "lld.inputGraph.parse"; }
+
+  virtual std::string message(int ev) const {
+    switch (ev) {
+    case input_graph_error::success:
+      return "Success";
+    default:
+      llvm_unreachable("An enumerator of input_graph_error does not have a "
+                       "message defined.");
+    }
+  }
+
+  virtual llvm::error_condition default_error_condition(int ev) const {
+    if (ev == input_graph_error::success)
+      return llvm::errc::success;
+    return llvm::errc::invalid_argument;
+  }
+};
+
+const llvm::error_category &lld::input_graph_error_category() {
+  static _input_graph_error_category i;
+  return i;
+}

Removed: lld/trunk/lib/Core/InputFiles.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/Core/InputFiles.cpp?rev=192080&view=auto
==============================================================================
--- lld/trunk/lib/Core/InputFiles.cpp (original)
+++ lld/trunk/lib/Core/InputFiles.cpp (removed)
@@ -1,97 +0,0 @@
-//===- Core/InputFiles.cpp - Manages list of Files ------------------------===//
-//
-//                             The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "lld/Core/InputFiles.h"
-#include "lld/Core/SharedLibraryFile.h"
-#include "lld/Core/ArchiveLibraryFile.h"
-#include "lld/Core/LLVM.h"
-
-namespace lld {
-
-InputFiles::InputFiles() {
-}
-
-
-InputFiles::~InputFiles() {
-}
-
-void InputFiles::forEachInitialAtom(InputFiles::Handler &handler) const {
-  for ( const File *file : _files ) {
-    this->handleFile(file, handler);
-  }
-}
-
-void InputFiles::prependFile(const File &file) {
-  _files.insert(_files.begin(), &file);
-}
-
-void InputFiles::appendFile(const File &file) {
-  _files.push_back(&file);
-}
-
-void InputFiles::appendFiles(std::vector<std::unique_ptr<File>> &files) {
-  for (std::unique_ptr<File> &f : files) {
-    _files.push_back(f.release());
-  }
-}
-
-void InputFiles::assignFileOrdinals() {
-  uint64_t i = 0;
-  for ( const File *file : _files ) {
-    file->setOrdinalAndIncrement(i);
-  }
-}
-
-
-bool InputFiles::searchLibraries(StringRef name, bool searchSharedLibs,
-                               bool searchArchives, bool dataSymbolOnly,
-                               InputFiles::Handler &handler) const {
-
-  for ( const File *file : _files ) {
-    if ( searchSharedLibs ) {
-      if (const SharedLibraryFile *shlib = dyn_cast<SharedLibraryFile>(file)) {
-        if ( const SharedLibraryAtom* shAtom = shlib->exports(name,
-                                                            dataSymbolOnly) ) {
-          handler.doSharedLibraryAtom(*shAtom);
-          return true;
-        }
-      }
-    }
-    if ( searchArchives ) {
-      if (const ArchiveLibraryFile *lib = dyn_cast<ArchiveLibraryFile>(file)) {
-        if ( const File *member = lib->find(name, dataSymbolOnly) ) {
-          this->handleFile(member, handler);
-          return true;
-        }
-      }
-    }
-  }
-  return false;
-}
-
-
-void InputFiles::handleFile(const File *file,
-                            InputFiles::Handler &handler) const {
-  handler.doFile(*file);
-  for( const DefinedAtom *atom : file->defined() ) {
-    handler.doDefinedAtom(*atom);
-  }
-  for( const UndefinedAtom *undefAtom : file->undefined() ) {
-    handler.doUndefinedAtom(*undefAtom);
-  }
-  for( const SharedLibraryAtom *shlibAtom : file->sharedLibrary() ) {
-    handler.doSharedLibraryAtom(*shlibAtom);
-  }
-  for( const AbsoluteAtom *absAtom : file->absolute() ) {
-    handler.doAbsoluteAtom(*absAtom);
-  }
-}
-
-
-} // namespace lld

Modified: lld/trunk/lib/Core/LinkingContext.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/Core/LinkingContext.cpp?rev=192081&r1=192080&r2=192081&view=diff
==============================================================================
--- lld/trunk/lib/Core/LinkingContext.cpp (original)
+++ lld/trunk/lib/Core/LinkingContext.cpp Sun Oct  6 21:47:09 2013
@@ -8,7 +8,7 @@
 //===----------------------------------------------------------------------===//
 
 #include "lld/Core/LinkingContext.h"
-#include "lld/Core/InputFiles.h"
+#include "lld/Core/Resolver.h"
 #include "lld/ReaderWriter/Writer.h"
 #include "lld/ReaderWriter/Simple.h"
 
@@ -17,19 +17,20 @@
 namespace lld {
 
 LinkingContext::LinkingContext()
-    : Reader(*this), _deadStrip(false), _globalsAreDeadStripRoots(false),
+    : _deadStrip(false), _globalsAreDeadStripRoots(false),
       _searchArchivesToOverrideTentativeDefinitions(false),
       _searchSharedLibrariesToOverrideTentativeDefinitions(false),
       _warnIfCoalesableAtomsHaveDifferentCanBeNull(false),
       _warnIfCoalesableAtomsHaveDifferentLoadName(false),
-      _printRemainingUndefines(true),
-      _allowRemainingUndefines(false), _logInputFiles(false),
-      _allowShlibUndefines(false), _outputFileType(OutputFileType::Default) {}
+      _printRemainingUndefines(true), _allowRemainingUndefines(false),
+      _logInputFiles(false), _allowShlibUndefines(false),
+      _outputFileType(OutputFileType::Default), _currentInputElement(nullptr) {}
 
 LinkingContext::~LinkingContext() {}
 
 bool LinkingContext::validate(raw_ostream &diagnostics) {
   _yamlReader = createReaderYAML(*this);
+  _nativeReader = createReaderNative(*this);
   return validateImpl(diagnostics);
 }
 
@@ -37,11 +38,12 @@ error_code LinkingContext::writeFile(con
   return this->writer().writeFile(linkedFile, _outputPath);
 }
 
-void LinkingContext::addImplicitFiles(InputFiles &inputs) const {
-  this->writer().addFiles(inputs);
+bool LinkingContext::createImplicitFiles(
+    std::vector<std::unique_ptr<File> > &result) const {
+  return this->writer().createImplicitFiles(result);
 }
 
-std::unique_ptr<File> LinkingContext::createEntrySymbolFile() {
+std::unique_ptr<File> LinkingContext::createEntrySymbolFile() const {
   if (entrySymbolName().empty())
     return nullptr;
   std::unique_ptr<SimpleFile> entryFile(
@@ -51,7 +53,7 @@ std::unique_ptr<File> LinkingContext::cr
   return std::move(entryFile);
 }
 
-std::unique_ptr<File> LinkingContext::createUndefinedSymbolFile() {
+std::unique_ptr<File> LinkingContext::createUndefinedSymbolFile() const {
   if (_initialUndefinedSymbols.empty())
     return nullptr;
   std::unique_ptr<SimpleFile> undefinedSymFile(
@@ -62,8 +64,8 @@ std::unique_ptr<File> LinkingContext::cr
   return std::move(undefinedSymFile);
 }
 
-std::vector<std::unique_ptr<File> > LinkingContext::createInternalFiles() {
-  std::vector<std::unique_ptr<File> > result;
+bool LinkingContext::createInternalFiles(
+    std::vector<std::unique_ptr<File> > &result) const {
   std::unique_ptr<File> internalFile;
   internalFile = createEntrySymbolFile();
   if (internalFile)
@@ -71,7 +73,32 @@ std::vector<std::unique_ptr<File> > Link
   internalFile = createUndefinedSymbolFile();
   if (internalFile)
     result.push_back(std::move(internalFile));
-  return result;
+  return true;
+}
+
+void LinkingContext::setResolverState(int32_t state) const {
+  _currentInputElement->setResolverState(state);
+}
+
+ErrorOr<File &> LinkingContext::nextFile() const {
+  if (_currentInputElement == nullptr) {
+    ErrorOr<InputElement *> elem = inputGraph().getNextInputElement();
+    if (error_code(elem) == input_graph_error::no_more_elements)
+      return make_error_code(input_graph_error::no_more_files);
+    _currentInputElement = *elem;
+  }
+  do {
+    ErrorOr<File &> nextFile = _currentInputElement->getNextFile();
+    if (error_code(nextFile) == input_graph_error::no_more_files) {
+      ErrorOr<InputElement *> elem = inputGraph().getNextInputElement();
+      if (error_code(elem) == input_graph_error::no_more_elements)
+        return make_error_code(input_graph_error::no_more_files);
+      _currentInputElement = *elem;
+    } else {
+      return std::move(nextFile);
+    }
+  } while (_currentInputElement != nullptr);
+  return make_error_code(input_graph_error::no_more_files);
 }
 
 void LinkingContext::addPasses(PassManager &pm) const {}

Modified: lld/trunk/lib/Core/Resolver.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/Core/Resolver.cpp?rev=192081&r1=192080&r2=192081&view=diff
==============================================================================
--- lld/trunk/lib/Core/Resolver.cpp (original)
+++ lld/trunk/lib/Core/Resolver.cpp Sun Oct  6 21:47:09 2013
@@ -8,8 +8,9 @@
 //===----------------------------------------------------------------------===//
 
 #include "lld/Core/Atom.h"
+#include "lld/Core/ArchiveLibraryFile.h"
 #include "lld/Core/File.h"
-#include "lld/Core/InputFiles.h"
+#include "lld/Core/SharedLibraryFile.h"
 #include "lld/Core/Instrumentation.h"
 #include "lld/Core/LLVM.h"
 #include "lld/Core/Resolver.h"
@@ -69,24 +70,126 @@ private:
 
 } // namespace
 
+// called before the first atom in any file is added with doAtom()
+void Resolver::doFile(const File &file) {}
 
-// add all atoms from all initial .o files
-void Resolver::buildInitialAtomList() {
-  ScopedTask task(getDefaultDomain(), "buildInitialAtomList");
- DEBUG_WITH_TYPE("resolver", llvm::dbgs() << "Resolver initial atom list:\n");
-
-  // each input files contributes initial atoms
-  _atoms.reserve(1024);
-  _inputFiles.forEachInitialAtom(*this);
-
-  _completedInitialObjectFiles = true;
+void Resolver::handleFile(const File &file) {
+  int32_t resolverState = Resolver::StateNoChange;
+  doFile(file);
+  for (const DefinedAtom *atom : file.defined()) {
+    doDefinedAtom(*atom);
+    resolverState |= StateNewDefinedAtoms;
+  }
+  for (const UndefinedAtom *undefAtom : file.undefined()) {
+    doUndefinedAtom(*undefAtom);
+    resolverState |= StateNewUndefinedAtoms;
+  }
+  for (const SharedLibraryAtom *shlibAtom : file.sharedLibrary()) {
+    doSharedLibraryAtom(*shlibAtom);
+    resolverState |= StateNewSharedLibraryAtoms;
+  }
+  for (const AbsoluteAtom *absAtom : file.absolute()) {
+    doAbsoluteAtom(*absAtom);
+    resolverState |= StateNewAbsoluteAtoms;
+  }
+  _context.setResolverState(resolverState);
 }
 
+void Resolver::handleArchiveFile(const File &file) {
+  const ArchiveLibraryFile *archiveFile = dyn_cast<ArchiveLibraryFile>(&file);
 
-// called before the first atom in any file is added with doAtom()
-void Resolver::doFile(const File &file) {
+  // Handle normal archives
+  int64_t undefineGenCount = 0;
+  do {
+    undefineGenCount = _symbolTable.size();
+    std::vector<const UndefinedAtom *> undefines;
+    _symbolTable.undefines(undefines);
+    for (const UndefinedAtom *undefAtom : undefines) {
+      StringRef undefName = undefAtom->name();
+      // load for previous undefine may also have loaded this undefine
+      if (!_symbolTable.isDefined(undefName)) {
+        if (const File *member = archiveFile->find(undefName, false))
+          handleFile(*member);
+      }
+      // If the undefined symbol has an alternative name, try to resolve the
+      // symbol with the name to give it a second chance. This feature is used
+      // for COFF "weak external" symbol.
+      if (!_symbolTable.isDefined(undefName)) {
+        if (const UndefinedAtom *fallbackUndefAtom = undefAtom->fallback()) {
+          _symbolTable.addReplacement(undefAtom, fallbackUndefAtom);
+          _symbolTable.add(*fallbackUndefAtom);
+        }
+      }
+    }
+    // search libraries for overrides of common symbols
+    if (_context.searchArchivesToOverrideTentativeDefinitions()) {
+      std::vector<StringRef> tentDefNames;
+      _symbolTable.tentativeDefinitions(tentDefNames);
+      for (StringRef tentDefName : tentDefNames) {
+        // Load for previous tentative may also have loaded
+        // something that overrode this tentative, so always check.
+        const Atom *curAtom = _symbolTable.findByName(tentDefName);
+        assert(curAtom != nullptr);
+        if (const DefinedAtom *curDefAtom = dyn_cast<DefinedAtom>(curAtom)) {
+          if (curDefAtom->merge() == DefinedAtom::mergeAsTentative) {
+            if (const File *member = archiveFile->find(tentDefName, true))
+              handleFile(*member);
+          }
+        }
+      }
+    }
+  } while (undefineGenCount != _symbolTable.size());
 }
 
+void Resolver::handleSharedLibrary(const File &file) {
+  const SharedLibraryFile *sharedLibrary = dyn_cast<SharedLibraryFile>(&file);
+  int64_t undefineGenCount = 0;
+
+  // Add all the atoms from the shared library
+  handleFile(*sharedLibrary);
+
+  do {
+    undefineGenCount = _symbolTable.size();
+    std::vector<const UndefinedAtom *> undefines;
+    _symbolTable.undefines(undefines);
+    for (const UndefinedAtom *undefAtom : undefines) {
+      StringRef undefName = undefAtom->name();
+      // load for previous undefine may also have loaded this undefine
+      if (!_symbolTable.isDefined(undefName)) {
+        if (const SharedLibraryAtom *shAtom =
+                sharedLibrary->exports(undefName, false))
+          doSharedLibraryAtom(*shAtom);
+      }
+      // If the undefined symbol has an alternative name, try to resolve the
+      // symbol with the name to give it a second chance. This feature is used
+      // for COFF "weak external" symbol.
+      if (!_symbolTable.isDefined(undefName)) {
+        if (const UndefinedAtom *fallbackUndefAtom = undefAtom->fallback()) {
+          _symbolTable.addReplacement(undefAtom, fallbackUndefAtom);
+          _symbolTable.add(*fallbackUndefAtom);
+        }
+      }
+    }
+    // search libraries for overrides of common symbols
+    if (_context.searchSharedLibrariesToOverrideTentativeDefinitions()) {
+      std::vector<StringRef> tentDefNames;
+      _symbolTable.tentativeDefinitions(tentDefNames);
+      for (StringRef tentDefName : tentDefNames) {
+        // Load for previous tentative may also have loaded
+        // something that overrode this tentative, so always check.
+        const Atom *curAtom = _symbolTable.findByName(tentDefName);
+        assert(curAtom != nullptr);
+        if (const DefinedAtom *curDefAtom = dyn_cast<DefinedAtom>(curAtom)) {
+          if (curDefAtom->merge() == DefinedAtom::mergeAsTentative) {
+            if (const SharedLibraryAtom *shAtom =
+                    sharedLibrary->exports(tentDefName, true))
+              doSharedLibraryAtom(*shAtom);
+          }
+        }
+      }
+    }
+  } while (undefineGenCount != _symbolTable.size());
+}
 
 void Resolver::doUndefinedAtom(const UndefinedAtom& atom) {
   DEBUG_WITH_TYPE("resolver", llvm::dbgs()
@@ -187,62 +290,20 @@ void Resolver::addAtoms(const std::vecto
 // if so, keep searching libraries until no more atoms being added
 void Resolver::resolveUndefines() {
   ScopedTask task(getDefaultDomain(), "resolveUndefines");
-  const bool searchArchives =
-      _context.searchArchivesToOverrideTentativeDefinitions();
-  const bool searchSharedLibs =
-      _context.searchSharedLibrariesToOverrideTentativeDefinitions();
+  ErrorOr<File &> nextFile;
 
-  // keep looping until no more undefines were added in last loop
-  unsigned int undefineGenCount;
-  do {
-    undefineGenCount = _symbolTable.size();
-    std::vector<const UndefinedAtom *> undefines;
-    _symbolTable.undefines(undefines);
-    for (const UndefinedAtom *undefAtom : undefines) {
-      StringRef undefName = undefAtom->name();
-      // load for previous undefine may also have loaded this undefine
-      if (!_symbolTable.isDefined(undefName)) {
-        _inputFiles.searchLibraries(undefName,
-                                    true,   // searchSharedLibs
-                                    true,   // searchArchives
-                                    false,  // dataSymbolOnly
-                                    *this);
-      }
-      // If the undefined symbol has an alternative name, try to resolve the
-      // symbol with the name to give it a second chance. This feature is used
-      // for COFF "weak external" symbol.
-      if (!_symbolTable.isDefined(undefName)) {
-        if (const UndefinedAtom *fallbackUndefAtom = undefAtom->fallback()) {
-          _symbolTable.addReplacement(undefAtom, fallbackUndefAtom);
-          _symbolTable.add(*fallbackUndefAtom);
-        }
-      }
-    }
-    // search libraries for overrides of common symbols
-    if (searchArchives || searchSharedLibs) {
-      std::vector<StringRef> tentDefNames;
-      _symbolTable.tentativeDefinitions(tentDefNames);
-      for ( StringRef tentDefName : tentDefNames ) {
-        // Load for previous tentative may also have loaded
-        // something that overrode this tentative, so always check.
-        const Atom *curAtom = _symbolTable.findByName(tentDefName);
-        assert(curAtom != nullptr);
-        if (const DefinedAtom* curDefAtom = dyn_cast<DefinedAtom>(curAtom)) {
-          if (curDefAtom->merge() == DefinedAtom::mergeAsTentative) {
-            // Still tentative definition, so look for override.
-            _inputFiles.searchLibraries(tentDefName,
-                                        searchSharedLibs,
-                                        searchArchives,
-                                        true,  // dataSymbolOnly
-                                        *this);
-          }
-        }
-      }
-    }
-  } while (undefineGenCount != _symbolTable.size());
+  while ((nextFile = _context.nextFile())) {
+    if (error_code(nextFile) == input_graph_error::no_more_files)
+      break;
+    if (nextFile->kind() == File::kindObject)
+      handleFile(*nextFile);
+    if (nextFile->kind() == File::kindArchiveLibrary)
+      handleArchiveFile(*nextFile);
+    if (nextFile->kind() == File::kindSharedLibrary)
+      handleSharedLibrary(*nextFile);
+  }
 }
 
-
 // switch all references to undefined or coalesced away atoms
 // to the new defined atom
 void Resolver::updateReferences() {
@@ -381,31 +442,11 @@ void Resolver::removeCoalescedAwayAtoms(
                               AtomCoalescedAway(_symbolTable)), _atoms.end());
 }
 
-// check for interactions between symbols defined in this linkage unit
-// and same symbol name in linked dynamic shared libraries
-void Resolver::checkDylibSymbolCollisions() {
-  ScopedTask task(getDefaultDomain(), "checkDylibSymbolCollisions");
-  for ( const Atom *atom : _atoms ) {
-    const DefinedAtom* defAtom = dyn_cast<DefinedAtom>(atom);
-    if (defAtom == nullptr)
-      continue;
-    if ( defAtom->merge() != DefinedAtom::mergeAsTentative )
-      continue;
-    assert(defAtom->scope() != DefinedAtom::scopeTranslationUnit);
-    // See if any shared library also has symbol which
-    // collides with the tentative definition.
-    // SymbolTable will warn if needed.
-    _inputFiles.searchLibraries(defAtom->name(), true, false, false, *this);
-  }
-}
-
-
 void Resolver::linkTimeOptimize() {
   // FIX ME
 }
 
 bool Resolver::resolve() {
-  this->buildInitialAtomList();
   this->resolveUndefines();
   this->updateReferences();
   this->deadStripOptimize();
@@ -414,7 +455,6 @@ bool Resolver::resolve() {
       return true;
   }
   this->removeCoalescedAwayAtoms();
-  this->checkDylibSymbolCollisions();
   this->linkTimeOptimize();
   this->_result.addAtoms(_atoms);
   return false;

Modified: lld/trunk/lib/Core/SymbolTable.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/Core/SymbolTable.cpp?rev=192081&r1=192080&r2=192081&view=diff
==============================================================================
--- lld/trunk/lib/Core/SymbolTable.cpp (original)
+++ lld/trunk/lib/Core/SymbolTable.cpp Sun Oct  6 21:47:09 2013
@@ -12,7 +12,6 @@
 #include "lld/Core/Atom.h"
 #include "lld/Core/DefinedAtom.h"
 #include "lld/Core/File.h"
-#include "lld/Core/InputFiles.h"
 #include "lld/Core/LLVM.h"
 #include "lld/Core/Resolver.h"
 #include "lld/Core/SharedLibraryAtom.h"

Modified: lld/trunk/lib/Driver/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/Driver/CMakeLists.txt?rev=192081&r1=192080&r2=192081&view=diff
==============================================================================
--- lld/trunk/lib/Driver/CMakeLists.txt (original)
+++ lld/trunk/lib/Driver/CMakeLists.txt Sun Oct  6 21:47:09 2013
@@ -25,10 +25,10 @@ target_link_libraries(lldDriver
   lldMachO
   lldPECOFF
   lldELF
+  lldCore
   lldNative
   lldReaderWriter
   lldYAML
-  lldCore
   LLVMObject
   LLVMOption
   LLVMSupport

Modified: lld/trunk/lib/Driver/CoreDriver.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/Driver/CoreDriver.cpp?rev=192081&r1=192080&r2=192081&view=diff
==============================================================================
--- lld/trunk/lib/Driver/CoreDriver.cpp (original)
+++ lld/trunk/lib/Driver/CoreDriver.cpp Sun Oct  6 21:47:09 2013
@@ -145,7 +145,7 @@ bool CoreDriver::parse(int argc, const c
     }
   }
 
-  if (!inputGraph->numFiles()) {
+  if (!inputGraph->size()) {
     diagnostics << "No input files\n";
     return false;
   }

Modified: lld/trunk/lib/Driver/DarwinLdDriver.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/Driver/DarwinLdDriver.cpp?rev=192081&r1=192080&r2=192081&view=diff
==============================================================================
--- lld/trunk/lib/Driver/DarwinLdDriver.cpp (original)
+++ lld/trunk/lib/Driver/DarwinLdDriver.cpp Sun Oct  6 21:47:09 2013
@@ -70,15 +70,6 @@ public:
 
 namespace lld {
 
-llvm::ErrorOr<std::unique_ptr<lld::LinkerInput> >
-MachOFileNode::createLinkerInput(const LinkingContext &ctx) {
-  auto inputFile(FileNode::createLinkerInput(ctx));
-
-  if (inputFile)
-    (*inputFile)->setWholeArchive(_isWholeArchive);
-  return std::move(inputFile);
-}
-
 bool DarwinLdDriver::linkMachO(int argc, const char *argv[],
                                raw_ostream &diagnostics) {
   MachOLinkingContext ctx;
@@ -262,7 +253,7 @@ bool DarwinLdDriver::parse(int argc, con
         new MachOFileNode(ctx, (*it)->getValue(), globalWholeArchive)));
   }
 
-  if (!inputGraph->numFiles()) {
+  if (!inputGraph->size()) {
     diagnostics << "No input files\n";
     return false;
   }

Modified: lld/trunk/lib/Driver/Driver.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/Driver/Driver.cpp?rev=192081&r1=192080&r2=192081&view=diff
==============================================================================
--- lld/trunk/lib/Driver/Driver.cpp (original)
+++ lld/trunk/lib/Driver/Driver.cpp Sun Oct  6 21:47:09 2013
@@ -10,7 +10,6 @@
 #include "lld/Driver/Driver.h"
 
 #include "lld/Core/LLVM.h"
-#include "lld/Core/InputFiles.h"
 #include "lld/Core/Instrumentation.h"
 #include "lld/Core/PassManager.h"
 #include "lld/Core/Parallel.h"
@@ -41,41 +40,21 @@ bool Driver::link(const LinkingContext &
     llvm::cl::ParseCommandLineOptions(numArgs + 1, args);
   }
   InputGraph &inputGraph = context.inputGraph();
-  if (!inputGraph.numFiles())
+  if (!inputGraph.size())
     return false;
 
+  bool fail = false;
+
   // Read inputs
   ScopedTask readTask(getDefaultDomain(), "Read Args");
-  std::vector<std::vector<std::unique_ptr<File> > > files(
-      inputGraph.numFiles());
-  size_t index = 0;
-  std::atomic<bool> fail(false);
   TaskGroup tg;
-  std::vector<std::unique_ptr<LinkerInput> > linkerInputs;
+  int index = 0;
   for (auto &ie : inputGraph.inputElements()) {
-    if (ie->kind() == InputElement::Kind::File) {
-      FileNode *fileNode = (llvm::dyn_cast<FileNode>)(ie.get());
-      auto linkerInput = fileNode->createLinkerInput(context);
-      if (!linkerInput) {
-        llvm::outs() << fileNode->errStr(error_code(linkerInput)) << "\n";
-        return false;
-      }
-      linkerInputs.push_back(std::move(*linkerInput));
-    }
-    else {
-      llvm_unreachable("Not handling other types of InputElements");
-    }
-  }
-  for (const auto &input : linkerInputs) {
-    if (context.logInputFiles())
-      llvm::outs() << input->getUserPath() << "\n";
-
-    tg.spawn([ &, index]{
-      if (error_code ec = context.parseFile(*input, files[index])) {
-        diagnostics << "Failed to read file: " << input->getUserPath() << ": "
-                    << ec.message() << "\n";
+    tg.spawn([&, index] {
+      if (error_code ec = ie->parse(context, diagnostics)) {
+        FileNode *fileNode = (llvm::dyn_cast<FileNode>)(ie.get());
+        diagnostics << fileNode->errStr(ec) << "\n";
         fail = true;
-        return;
       }
     });
     ++index;
@@ -86,23 +65,36 @@ bool Driver::link(const LinkingContext &
   if (fail)
     return false;
 
-  InputFiles inputs;
+  std::unique_ptr<SimpleFileNode> fileNode(
+      new SimpleFileNode("Internal Files"));
 
-  for (auto &f : inputGraph.internalFiles())
-    inputs.appendFile(*f.get());
+  InputGraph::FileVectorT internalFiles;
+  context.createInternalFiles(internalFiles);
 
-  for (auto &f : files)
-    inputs.appendFiles(f);
+  if (internalFiles.size()) {
+    fileNode->appendInputFiles(std::move(internalFiles));
+  }
 
   // Give target a chance to add files.
-  context.addImplicitFiles(inputs);
+  InputGraph::FileVectorT implicitFiles;
+  context.createImplicitFiles(implicitFiles);
+  if (implicitFiles.size()) {
+    fileNode->appendInputFiles(std::move(implicitFiles));
+  }
+
+  context.inputGraph().insertOneElementAt(std::move(fileNode),
+                                          InputGraph::Position::BEGIN);
+
+  context.inputGraph().assignOrdinals();
+
+  context.inputGraph().doPostProcess();
 
-  // assign an ordinal to each file so sort() can preserve command line order
-  inputs.assignFileOrdinals();
+  uint64_t ordinal = 0;
+  context.inputGraph().assignFileOrdinals(ordinal);
 
   // Do core linking.
   ScopedTask resolveTask(getDefaultDomain(), "Resolve");
-  Resolver resolver(context, inputs);
+  Resolver resolver(context);
   if (resolver.resolve()) {
     if (!context.allowRemainingUndefines())
       return false;

Modified: lld/trunk/lib/Driver/GnuLdDriver.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/Driver/GnuLdDriver.cpp?rev=192081&r1=192080&r2=192081&view=diff
==============================================================================
--- lld/trunk/lib/Driver/GnuLdDriver.cpp (original)
+++ lld/trunk/lib/Driver/GnuLdDriver.cpp Sun Oct  6 21:47:09 2013
@@ -69,17 +69,6 @@ public:
 
 } // namespace
 
-llvm::ErrorOr<std::unique_ptr<lld::LinkerInput> >
-ELFFileNode::createLinkerInput(const LinkingContext &ctx) {
-  auto inputFile(FileNode::createLinkerInput(ctx));
-
-  if (inputFile) {
-    (*inputFile)->setAsNeeded(_asNeeded);
-    (*inputFile)->setWholeArchive(_isWholeArchive);
-  }
-  return std::move(inputFile);
-}
-
 llvm::ErrorOr<StringRef> ELFFileNode::path(const LinkingContext &) const {
   if (!_isDashlPrefix)
     return _path;
@@ -158,6 +147,8 @@ bool GnuLdDriver::parse(int argc, const
   ctx->setAllowShlibUndefines(false);
   ctx->setUseShlibUndefines(true);
 
+  int index = 0;
+
   // Process all the arguments and create Input Elements
   for (auto inputArg : *parsedArgs) {
     switch (inputArg->getOption().getID()) {
@@ -281,8 +272,8 @@ bool GnuLdDriver::parse(int argc, const
     case OPT_l: {
       std::unique_ptr<InputElement> inputFile =
           std::move(std::unique_ptr<InputElement>(new ELFFileNode(
-              *ctx, inputArg->getValue(), searchPath, isWholeArchive, asNeeded,
-              inputArg->getOption().getID() == OPT_l)));
+              *ctx, inputArg->getValue(), searchPath, index, isWholeArchive,
+              asNeeded, inputArg->getOption().getID() == OPT_l)));
       if (controlNodeStack.empty())
         inputGraph->addInputElement(std::move(inputFile));
       else
@@ -320,13 +311,11 @@ bool GnuLdDriver::parse(int argc, const
     } // end switch on option ID
   }   // end for
 
-  if (!inputGraph->numFiles()) {
+  if (!inputGraph->size()) {
     diagnostics << "No input files\n";
     return false;
   }
 
-  inputGraph->addInternalFile(ctx->createInternalFiles());
-
   // Set default output file name if the output file was not
   // specified.
   if (!_outputOptionSet) {

Modified: lld/trunk/lib/Driver/InputGraph.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/Driver/InputGraph.cpp?rev=192081&r1=192080&r2=192081&view=diff
==============================================================================
--- lld/trunk/lib/Driver/InputGraph.cpp (original)
+++ lld/trunk/lib/Driver/InputGraph.cpp Sun Oct  6 21:47:09 2013
@@ -6,6 +6,7 @@
 // License. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
+#include "lld/Core/Resolver.h"
 #include "lld/Driver/InputGraph.h"
 
 using namespace lld;
@@ -18,15 +19,6 @@ bool sortInputElements(const std::unique
 }
 
 bool InputGraph::addInputElement(std::unique_ptr<InputElement> ie) {
-  switch (ie->kind()) {
-  case InputElement::Kind::Control:
-    ++_numElements;
-    break;
-  case InputElement::Kind::File:
-    ++_numElements;
-    ++_numFiles;
-    break;
-  }
   _inputArgs.push_back(std::move(ie));
   return true;
 }
@@ -37,6 +29,12 @@ bool InputGraph::assignOrdinals() {
   return true;
 }
 
+bool InputGraph::assignFileOrdinals(uint64_t &startOrdinal) {
+  for (auto &ie : _inputArgs)
+    ie->assignFileOrdinals(startOrdinal);
+  return true;
+}
+
 void InputGraph::doPostProcess() {
   std::stable_sort(_inputArgs.begin(), _inputArgs.end(), sortInputElements);
 }
@@ -55,17 +53,68 @@ bool InputGraph::dump(raw_ostream &diagn
   return true;
 }
 
-llvm::ErrorOr<std::unique_ptr<lld::LinkerInput> >
-FileNode::createLinkerInput(const LinkingContext &ctx) {
-  auto filePath = path(ctx);
-  if (!filePath &&
-      error_code(filePath) == llvm::errc::no_such_file_or_directory)
-    return make_error_code(llvm::errc::no_such_file_or_directory);
-  OwningPtr<llvm::MemoryBuffer> opmb;
-  if (error_code ec = llvm::MemoryBuffer::getFileOrSTDIN(*filePath, opmb))
-    return ec;
-
-  std::unique_ptr<MemoryBuffer> mb(opmb.take());
-
-  return std::unique_ptr<LinkerInput>(new LinkerInput(std::move(mb), *filePath));
+void InputGraph::insertElementsAt(
+    std::vector<std::unique_ptr<InputElement> > inputElements,
+    Position position, int32_t pos) {
+  if (position == InputGraph::Position::BEGIN)
+    pos = 0;
+  else if (position == InputGraph::Position::END)
+    pos = _inputArgs.size();
+  _inputArgs.insert(_inputArgs.begin() + pos,
+                    std::make_move_iterator(inputElements.begin()),
+                    std::make_move_iterator(inputElements.end()));
+}
+
+void InputGraph::insertOneElementAt(std::unique_ptr<InputElement> element,
+                                    Position position, int32_t pos) {
+  if (position == InputGraph::Position::BEGIN)
+    pos = 0;
+  else if (position == InputGraph::Position::END)
+    pos = _inputArgs.size();
+  _inputArgs.insert(_inputArgs.begin() + pos, std::move(element));
+}
+
+/// \brief Helper functions for the resolver
+ErrorOr<InputElement *> InputGraph::getNextInputElement() {
+  if (_nextElementIndex >= _inputArgs.size())
+    return make_error_code(input_graph_error::no_more_elements);
+  return _inputArgs[_nextElementIndex++].get();
+}
+
+/// \brief Set the index on what inputElement has to be returned
+ErrorOr<void> InputGraph::setNextElementIndex(uint32_t index) {
+  if (index > _inputArgs.size())
+    return make_error_code(llvm::errc::invalid_argument);
+  _nextElementIndex = index;
+  return error_code::success();
+}
+
+/// InputElement
+
+/// \brief Initialize the Input Element, The ordinal value of an input Element
+/// is initially set to -1, if the user wants to override its ordinal,
+/// let the user do it
+InputElement::InputElement(Kind type, int64_t ordinal)
+    : _kind(type), _ordinal(ordinal), _weight(0),
+      _resolveState(Resolver::StateNoChange), _nextFileIndex(0) {}
+
+/// \brief Assign File ordinals for files contained
+/// in the InputElement
+void FileNode::assignFileOrdinals(uint64_t &startOrdinal) {
+  for (auto &file : _files)
+    file->setOrdinalAndIncrement(startOrdinal);
+}
+
+/// \brief Assign File ordinals for files contained
+/// in the InputElement
+void ControlNode::assignFileOrdinals(uint64_t &startOrdinal) {
+  for (auto &elem : _elements)
+    elem->assignFileOrdinals(startOrdinal);
+}
+
+/// \brief Assign File ordinals for files contained
+/// in the InputElement
+void SimpleFileNode::assignFileOrdinals(uint64_t &startOrdinal) {
+  for (auto &file : _files)
+    file->setOrdinalAndIncrement(startOrdinal);
 }

Modified: lld/trunk/lib/Driver/WinLinkDriver.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/Driver/WinLinkDriver.cpp?rev=192081&r1=192080&r2=192081&view=diff
==============================================================================
--- lld/trunk/lib/Driver/WinLinkDriver.cpp (original)
+++ lld/trunk/lib/Driver/WinLinkDriver.cpp Sun Oct  6 21:47:09 2013
@@ -526,16 +526,11 @@ bool WinLinkDriver::parse(int argc, cons
         inputGraph.addInputElement(std::unique_ptr<InputElement>(
             new PECOFFLibraryNode(ctx, defaultLibPath)));
 
-  if (!inputGraph.numFiles()) {
+  if (!inputGraph.size()) {
     diagnostics << "No input files\n";
     return false;
   }
 
-  // A list of undefined symbols will be added to the input
-  // file list to force the core linker to try to resolve
-  // the undefined symbols.
-  inputGraph.addInternalFile(ctx.createInternalFiles());
-
   // If /out option was not specified, the default output file name is
   // constructed by replacing an extension of the first input file
   // with ".exe".

Modified: lld/trunk/lib/ReaderWriter/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/CMakeLists.txt?rev=192081&r1=192080&r2=192081&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/CMakeLists.txt (original)
+++ lld/trunk/lib/ReaderWriter/CMakeLists.txt Sun Oct  6 21:47:09 2013
@@ -9,7 +9,6 @@ add_lld_library(lldReaderWriter
   CoreLinkingContext.cpp
   LinkerScript.cpp
   Reader.cpp
-  ReaderArchive.cpp
   ReaderLinkerScript.cpp
   Writer.cpp
   )

Modified: lld/trunk/lib/ReaderWriter/CoreLinkingContext.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/CoreLinkingContext.cpp?rev=192081&r1=192080&r2=192081&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/CoreLinkingContext.cpp (original)
+++ lld/trunk/lib/ReaderWriter/CoreLinkingContext.cpp Sun Oct  6 21:47:09 2013
@@ -272,6 +272,7 @@ private:
 CoreLinkingContext::CoreLinkingContext() {}
 
 bool CoreLinkingContext::validateImpl(raw_ostream &diagnostics) {
+  _reader = createReaderYAML(*this);
   return true;
 }
 
@@ -288,13 +289,6 @@ void CoreLinkingContext::addPasses(PassM
   }
 }
 
-error_code CoreLinkingContext::parseFile(LinkerInput &input,
-    std::vector<std::unique_ptr<File>> &result) const {
-  if (!_reader)
-    _reader = createReaderYAML(*this);
-  return _reader->parseFile(input, result);
-}
-
 Writer &CoreLinkingContext::writer() const {
   if (!_writer)
     _writer = createWriterYAML(*this);

Modified: lld/trunk/lib/ReaderWriter/ELF/DefaultTargetHandler.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/DefaultTargetHandler.h?rev=192081&r1=192080&r2=192081&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/DefaultTargetHandler.h (original)
+++ lld/trunk/lib/ReaderWriter/ELF/DefaultTargetHandler.h Sun Oct  6 21:47:09 2013
@@ -48,7 +48,9 @@ public:
   void addSection(Section<ELFT> *section) {}
 
   /// \brief add new symbol file
-  void addFiles(InputFiles &) {}
+  bool createImplicitFiles(std::vector<std::unique_ptr<File> > &) {
+    return true;
+  }
 
   /// \brief Finalize the symbol values
   void finalizeSymbolValues() {}

Modified: lld/trunk/lib/ReaderWriter/ELF/DynamicLibraryWriter.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/DynamicLibraryWriter.h?rev=192081&r1=192080&r2=192081&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/DynamicLibraryWriter.h (original)
+++ lld/trunk/lib/ReaderWriter/ELF/DynamicLibraryWriter.h Sun Oct  6 21:47:09 2013
@@ -26,16 +26,17 @@ template<class ELFT>
 class DynamicLibraryWriter : public OutputELFWriter<ELFT> {
 public:
   DynamicLibraryWriter(const ELFLinkingContext &context)
-      : OutputELFWriter<ELFT>(context), _runtimeFile(context) {}
+      : OutputELFWriter<ELFT>(context),
+        _runtimeFile(new CRuntimeFile<ELFT>(context)) {}
 
 private:
   void buildDynamicSymbolTable(const File &file);
   void addDefaultAtoms();
-  virtual void addFiles(InputFiles &);
+  virtual bool createImplicitFiles(std::vector<std::unique_ptr<File> > &);
   void finalizeDefaultAtomValues();
 
   llvm::BumpPtrAllocator _alloc;
-  CRuntimeFile<ELFT> _runtimeFile;
+  std::unique_ptr<CRuntimeFile<ELFT> > _runtimeFile;
 };
 
 //===----------------------------------------------------------------------===//
@@ -62,19 +63,18 @@ void DynamicLibraryWriter<ELFT>::buildDy
 }
 
 template <class ELFT> void DynamicLibraryWriter<ELFT>::addDefaultAtoms() {
-  _runtimeFile.addAbsoluteAtom("_end");
+  _runtimeFile->addAbsoluteAtom("_end");
 }
 
 /// \brief Hook in lld to add CRuntime file
 template <class ELFT>
-void DynamicLibraryWriter<ELFT>::addFiles(InputFiles &inputFiles) {
+bool DynamicLibraryWriter<ELFT>::createImplicitFiles(
+    std::vector<std::unique_ptr<File> > &result) {
   // Add the default atoms as defined by executables
   addDefaultAtoms();
-  // Add the runtime file
-  inputFiles.prependFile(_runtimeFile);
-  // Add the Linker internal file for symbols that are defined by
-  // command line options
-  OutputELFWriter<ELFT>::addFiles(inputFiles);
+  OutputELFWriter<ELFT>::createImplicitFiles(result);
+  result.push_back(std::move(_runtimeFile));
+  return true;
 }
 
 template <class ELFT>

Modified: lld/trunk/lib/ReaderWriter/ELF/ELFLinkingContext.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/ELFLinkingContext.cpp?rev=192081&r1=192080&r2=192081&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/ELFLinkingContext.cpp (original)
+++ lld/trunk/lib/ReaderWriter/ELF/ELFLinkingContext.cpp Sun Oct  6 21:47:09 2013
@@ -108,25 +108,6 @@ bool ELFLinkingContext::isRelativeReloc(
   return false;
 }
 
-error_code ELFLinkingContext::parseFile(LinkerInput &input,
-    std::vector<std::unique_ptr<File>> &result) const {
-  ScopedTask task(getDefaultDomain(), "parseFile");
-  error_code ec = _elfReader->parseFile(input, result);
-  if (!ec)
-    return ec;
-
-  // Not an ELF file, check file extension to see if it might be yaml
-  StringRef path = input.getBuffer().getBufferIdentifier();
-  if (path.endswith(".objtxt")) {
-    ec = _yamlReader->parseFile(input, result);
-    if (!ec)
-      return ec;
-  }
-
-  // Not a yaml file, assume it is a linkerscript
-  return _linkerScriptReader->parseFile(input, result);
-}
-
 Writer &ELFLinkingContext::writer() const { return *_writer; }
 
 std::unique_ptr<ELFLinkingContext>
@@ -194,7 +175,7 @@ llvm::ErrorOr<StringRef> ELFLinkingConte
   return libName;
 }
 
-std::unique_ptr<File> ELFLinkingContext::createUndefinedSymbolFile() {
+std::unique_ptr<File> ELFLinkingContext::createUndefinedSymbolFile() const {
   if (_initialUndefinedSymbols.empty())
     return nullptr;
   std::unique_ptr<SimpleFile> undefinedSymFile(

Modified: lld/trunk/lib/ReaderWriter/ELF/ExecutableWriter.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/ExecutableWriter.h?rev=192081&r1=192080&r2=192081&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/ExecutableWriter.h (original)
+++ lld/trunk/lib/ReaderWriter/ELF/ExecutableWriter.h Sun Oct  6 21:47:09 2013
@@ -26,15 +26,16 @@ template<class ELFT>
 class ExecutableWriter : public OutputELFWriter<ELFT> {
 public:
   ExecutableWriter(const ELFLinkingContext &context)
-      : OutputELFWriter<ELFT>(context), _runtimeFile(context) {}
+      : OutputELFWriter<ELFT>(context),
+        _runtimeFile(new CRuntimeFile<ELFT>(context)) {}
 
 private:
   virtual void addDefaultAtoms();
-  virtual void addFiles(InputFiles &);
+  virtual bool createImplicitFiles(std::vector<std::unique_ptr<File> > &);
   virtual void finalizeDefaultAtomValues();
   virtual void createDefaultSections();
   LLD_UNIQUE_BUMP_PTR(InterpSection<ELFT>) _interpSection;
-  CRuntimeFile<ELFT> _runtimeFile;
+  std::unique_ptr<CRuntimeFile<ELFT> > _runtimeFile;
 };
 
 //===----------------------------------------------------------------------===//
@@ -45,31 +46,30 @@ private:
 /// absolute symbols
 template<class ELFT>
 void ExecutableWriter<ELFT>::addDefaultAtoms() {
-  _runtimeFile.addUndefinedAtom(this->_context.entrySymbolName());
-  _runtimeFile.addAbsoluteAtom("__bss_start");
-  _runtimeFile.addAbsoluteAtom("__bss_end");
-  _runtimeFile.addAbsoluteAtom("_end");
-  _runtimeFile.addAbsoluteAtom("end");
-  _runtimeFile.addAbsoluteAtom("__preinit_array_start");
-  _runtimeFile.addAbsoluteAtom("__preinit_array_end");
-  _runtimeFile.addAbsoluteAtom("__init_array_start");
-  _runtimeFile.addAbsoluteAtom("__init_array_end");
-  _runtimeFile.addAbsoluteAtom("__rela_iplt_start");
-  _runtimeFile.addAbsoluteAtom("__rela_iplt_end");
-  _runtimeFile.addAbsoluteAtom("__fini_array_start");
-  _runtimeFile.addAbsoluteAtom("__fini_array_end");
+  _runtimeFile->addUndefinedAtom(this->_context.entrySymbolName());
+  _runtimeFile->addAbsoluteAtom("__bss_start");
+  _runtimeFile->addAbsoluteAtom("__bss_end");
+  _runtimeFile->addAbsoluteAtom("_end");
+  _runtimeFile->addAbsoluteAtom("end");
+  _runtimeFile->addAbsoluteAtom("__preinit_array_start");
+  _runtimeFile->addAbsoluteAtom("__preinit_array_end");
+  _runtimeFile->addAbsoluteAtom("__init_array_start");
+  _runtimeFile->addAbsoluteAtom("__init_array_end");
+  _runtimeFile->addAbsoluteAtom("__rela_iplt_start");
+  _runtimeFile->addAbsoluteAtom("__rela_iplt_end");
+  _runtimeFile->addAbsoluteAtom("__fini_array_start");
+  _runtimeFile->addAbsoluteAtom("__fini_array_end");
 }
 
 /// \brief Hook in lld to add CRuntime file
 template <class ELFT>
-void ExecutableWriter<ELFT>::addFiles(InputFiles &inputFiles) {
+bool ExecutableWriter<ELFT>::createImplicitFiles(
+    std::vector<std::unique_ptr<File> > &result) {
   // Add the default atoms as defined by executables
   addDefaultAtoms();
-  // Add the runtime file
-  inputFiles.prependFile(_runtimeFile);
-  // Add the Linker internal file for symbols that are defined by
-  // command line options
-  OutputELFWriter<ELFT>::addFiles(inputFiles);
+  OutputELFWriter<ELFT>::createImplicitFiles(result);
+  result.push_back(std::move(_runtimeFile));
+  return true;
 }
 
 template <class ELFT> void ExecutableWriter<ELFT>::createDefaultSections() {

Modified: lld/trunk/lib/ReaderWriter/ELF/File.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/File.h?rev=192081&r1=192080&r2=192081&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/File.h (original)
+++ lld/trunk/lib/ReaderWriter/ELF/File.h Sun Oct  6 21:47:09 2013
@@ -15,7 +15,7 @@
 #include "lld/Core/File.h"
 #include "lld/Core/Reference.h"
 #include "lld/ReaderWriter/ELFLinkingContext.h"
-#include "lld/ReaderWriter/ReaderArchive.h"
+#include "lld/ReaderWriter/FileArchive.h"
 
 #include "llvm/ADT/ArrayRef.h"
 #include "llvm/ADT/SmallString.h"

Modified: lld/trunk/lib/ReaderWriter/ELF/Hexagon/HexagonLinkingContext.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/Hexagon/HexagonLinkingContext.cpp?rev=192081&r1=192080&r2=192081&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/Hexagon/HexagonLinkingContext.cpp (original)
+++ lld/trunk/lib/ReaderWriter/ELF/Hexagon/HexagonLinkingContext.cpp Sun Oct  6 21:47:09 2013
@@ -91,22 +91,19 @@ private:
 };
 }
 
-
-std::vector<std::unique_ptr<File>>
-  elf::HexagonLinkingContext::createInternalFiles(){
-  std::vector<std::unique_ptr<File> > result =
-    ELFLinkingContext::createInternalFiles();
-  std::unique_ptr<HexagonInitFiniFile>
-    initFiniFile(new HexagonInitFiniFile(*this));
-  for (auto ai:initFunctions())
+bool elf::HexagonLinkingContext::createInternalFiles(
+    std::vector<std::unique_ptr<File> > &result) const {
+  ELFLinkingContext::createInternalFiles(result);
+  std::unique_ptr<HexagonInitFiniFile> initFiniFile(
+      new HexagonInitFiniFile(*this));
+  for (auto ai : initFunctions())
     initFiniFile->addInitFunction(ai);
   for (auto ai:finiFunctions())
     initFiniFile->addFiniFunction(ai);
   result.push_back(std::move(initFiniFile));
-  return result;
+  return true;
 }
 
-
 ErrorOr<Reference::Kind>
 elf::HexagonLinkingContext::relocKindFromString(StringRef str) const {
   int32_t ret = llvm::StringSwitch<int32_t>(str) LLD_CASE(R_HEX_NONE)

Modified: lld/trunk/lib/ReaderWriter/ELF/Hexagon/HexagonLinkingContext.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/Hexagon/HexagonLinkingContext.h?rev=192081&r1=192080&r2=192081&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/Hexagon/HexagonLinkingContext.h (original)
+++ lld/trunk/lib/ReaderWriter/ELF/Hexagon/HexagonLinkingContext.h Sun Oct  6 21:47:09 2013
@@ -63,7 +63,7 @@ public:
   }
 
   /// \brief Create Internal files for Init/Fini
-  std::vector<std::unique_ptr<File>> createInternalFiles();
+  bool createInternalFiles(std::vector<std::unique_ptr<File> > &result) const;
 };
 
 } // elf

Modified: lld/trunk/lib/ReaderWriter/ELF/Hexagon/HexagonTargetHandler.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/Hexagon/HexagonTargetHandler.cpp?rev=192081&r1=192080&r2=192081&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/Hexagon/HexagonTargetHandler.cpp (original)
+++ lld/trunk/lib/ReaderWriter/ELF/Hexagon/HexagonTargetHandler.cpp Sun Oct  6 21:47:09 2013
@@ -18,7 +18,7 @@ using namespace llvm::ELF;
 HexagonTargetHandler::HexagonTargetHandler(HexagonLinkingContext &context)
     : DefaultTargetHandler(context), _targetLayout(context),
       _relocationHandler(context, *this, _targetLayout),
-      _hexagonRuntimeFile(context) {}
+      _hexagonRuntimeFile(new HexagonRuntimeFile<HexagonELFType>(context)) {}
 
 namespace {
 

Modified: lld/trunk/lib/ReaderWriter/ELF/Hexagon/HexagonTargetHandler.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/Hexagon/HexagonTargetHandler.h?rev=192081&r1=192080&r2=192081&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/Hexagon/HexagonTargetHandler.h (original)
+++ lld/trunk/lib/ReaderWriter/ELF/Hexagon/HexagonTargetHandler.h Sun Oct  6 21:47:09 2013
@@ -172,16 +172,19 @@ public:
   }
 
   void addDefaultAtoms() {
-    _hexagonRuntimeFile.addAbsoluteAtom("_SDA_BASE_");
+    _hexagonRuntimeFile->addAbsoluteAtom("_SDA_BASE_");
     if (_context.isDynamic()) {
-      _hexagonRuntimeFile.addAbsoluteAtom("_GLOBAL_OFFSET_TABLE_");
-      _hexagonRuntimeFile.addAbsoluteAtom("_DYNAMIC");
+      _hexagonRuntimeFile->addAbsoluteAtom("_GLOBAL_OFFSET_TABLE_");
+      _hexagonRuntimeFile->addAbsoluteAtom("_DYNAMIC");
     }
   }
 
-  virtual void addFiles(InputFiles &inputFiles) {
+  virtual bool
+  createImplicitFiles(std::vector<std::unique_ptr<File> > &result) {
+    // Add the default atoms as defined for hexagon
     addDefaultAtoms();
-    inputFiles.prependFile(_hexagonRuntimeFile);
+    result.push_back(std::move(_hexagonRuntimeFile));
+    return true;
   }
 
   void finalizeSymbolValues() {
@@ -215,7 +218,7 @@ private:
   HexagonTargetLayout<HexagonELFType> _targetLayout;
   HexagonTargetRelocationHandler _relocationHandler;
   HexagonTargetAtomHandler<HexagonELFType> _targetAtomHandler;
-  HexagonRuntimeFile<HexagonELFType> _hexagonRuntimeFile;
+  std::unique_ptr<HexagonRuntimeFile<HexagonELFType> > _hexagonRuntimeFile;
   AtomLayout *_gotSymAtom;
 };
 } // end namespace elf

Modified: lld/trunk/lib/ReaderWriter/ELF/OutputELFWriter.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/OutputELFWriter.h?rev=192081&r1=192080&r2=192081&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/OutputELFWriter.h (original)
+++ lld/trunk/lib/ReaderWriter/ELF/OutputELFWriter.h Sun Oct  6 21:47:09 2013
@@ -77,7 +77,7 @@ protected:
   virtual void addDefaultAtoms() = 0;
 
   // Add any runtime files and their atoms to the output
-  virtual void addFiles(InputFiles &);
+  virtual bool createImplicitFiles(std::vector<std::unique_ptr<File> > &);
 
   // Finalize the default atom values
   virtual void finalizeDefaultAtomValues() = 0;
@@ -239,9 +239,11 @@ void OutputELFWriter<ELFT>::assignSectio
 }
 
 template <class ELFT>
-void OutputELFWriter<ELFT>::addFiles(InputFiles &inputFiles) {
+bool OutputELFWriter<ELFT>::createImplicitFiles(
+    std::vector<std::unique_ptr<File> > &result) {
   // Add all input Files that are defined by the target
-  _targetHandler.addFiles(inputFiles);
+  _targetHandler.createImplicitFiles(result);
+  return true;
 }
 
 template <class ELFT> void OutputELFWriter<ELFT>::createDefaultSections() {

Modified: lld/trunk/lib/ReaderWriter/ELF/Reader.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/Reader.cpp?rev=192081&r1=192080&r2=192081&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/Reader.cpp (original)
+++ lld/trunk/lib/ReaderWriter/ELF/Reader.cpp Sun Oct  6 21:47:09 2013
@@ -22,7 +22,7 @@
 
 #include "lld/Core/Reference.h"
 #include "lld/ReaderWriter/ELFLinkingContext.h"
-#include "lld/ReaderWriter/ReaderArchive.h"
+#include "lld/ReaderWriter/FileArchive.h"
 
 #include "llvm/ADT/ArrayRef.h"
 #include "llvm/ADT/SmallString.h"
@@ -79,24 +79,23 @@ namespace elf {
 class ELFReader : public Reader {
 public:
   ELFReader(const ELFLinkingContext &ctx)
-      : lld::Reader(ctx), _elfLinkingContext(ctx), _readerArchive(ctx, *this) {}
+      : lld::Reader(ctx), _elfLinkingContext(ctx) {}
 
-  error_code parseFile(LinkerInput &input,
-                       std::vector<std::unique_ptr<File>> &result) const {
+  error_code parseFile(std::unique_ptr<MemoryBuffer> &mb,
+                       std::vector<std::unique_ptr<File> > &result) const {
     using llvm::object::ELFType;
-    llvm::MemoryBuffer &mb(input.getBuffer());
     llvm::sys::fs::file_magic FileType =
-        llvm::sys::fs::identify_magic(mb.getBuffer());
+        llvm::sys::fs::identify_magic(mb->getBuffer());
 
     std::size_t MaxAlignment =
-        1ULL << llvm::countTrailingZeros(uintptr_t(mb.getBufferStart()));
+        1ULL << llvm::countTrailingZeros(uintptr_t(mb->getBufferStart()));
 
     llvm::error_code ec;
     switch (FileType) {
     case llvm::sys::fs::file_magic::elf_relocatable: {
       std::unique_ptr<File> f(createELF<ELFFileCreateELFTraits>(
-          getElfArchType(&mb), MaxAlignment, _elfLinkingContext,
-          std::move(input.takeBuffer()), ec));
+          getElfArchType(&*mb), MaxAlignment, _elfLinkingContext, std::move(mb),
+          ec));
       if (ec)
         return ec;
       result.push_back(std::move(f));
@@ -108,16 +107,13 @@ public:
       if (!_elfLinkingContext.allowLinkWithDynamicLibraries())
         return llvm::make_error_code(llvm::errc::executable_format_error);
       auto f = createELF<DynamicFileCreateELFTraits>(
-          getElfArchType(&mb), MaxAlignment, _elfLinkingContext,
-          std::move(input.takeBuffer()));
+          getElfArchType(&*mb), MaxAlignment, _elfLinkingContext,
+          std::move(mb));
       if (!f)
         return f;
       result.push_back(std::move(*f));
       break;
     }
-    case llvm::sys::fs::file_magic::archive:
-      ec = _readerArchive.parseFile(input, result);
-      break;
     default:
       return llvm::make_error_code(llvm::errc::executable_format_error);
       break;
@@ -131,7 +127,6 @@ public:
 
 private:
   const ELFLinkingContext &_elfLinkingContext;
-  ReaderArchive _readerArchive;
 };
 } // end namespace elf
 

Modified: lld/trunk/lib/ReaderWriter/ELF/TargetHandler.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/TargetHandler.h?rev=192081&r1=192080&r2=192081&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/TargetHandler.h (original)
+++ lld/trunk/lib/ReaderWriter/ELF/TargetHandler.h Sun Oct  6 21:47:09 2013
@@ -18,7 +18,6 @@
 
 #include "Layout.h"
 
-#include "lld/Core/InputFiles.h"
 #include "lld/Core/LLVM.h"
 #include "lld/Core/LinkingContext.h"
 #include "lld/ReaderWriter/ELFLinkingContext.h"
@@ -109,7 +108,7 @@ public:
   virtual void addSection(Section<ELFT> *section) = 0;
 
   /// \brief add new symbol file
-  virtual void addFiles(InputFiles &) = 0;
+  virtual bool createImplicitFiles(std::vector<std::unique_ptr<File> > &) = 0;
 
   /// \brief Finalize the symbol values
   virtual void finalizeSymbolValues() = 0;

Modified: lld/trunk/lib/ReaderWriter/ELF/Writer.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/Writer.h?rev=192081&r1=192080&r2=192081&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/Writer.h (original)
+++ lld/trunk/lib/ReaderWriter/ELF/Writer.h Sun Oct  6 21:47:09 2013
@@ -11,7 +11,6 @@
 #define LLD_READER_WRITER_ELF_WRITER_H
 
 #include "lld/Core/File.h"
-#include "lld/Core/InputFiles.h"
 #include "lld/ReaderWriter/Writer.h"
 
 namespace lld {

Modified: lld/trunk/lib/ReaderWriter/ELF/X86_64/X86_64LinkingContext.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/X86_64/X86_64LinkingContext.cpp?rev=192081&r1=192080&r2=192081&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/X86_64/X86_64LinkingContext.cpp (original)
+++ lld/trunk/lib/ReaderWriter/ELF/X86_64/X86_64LinkingContext.cpp Sun Oct  6 21:47:09 2013
@@ -528,18 +528,17 @@ void elf::X86_64LinkingContext::addPasse
   ELFLinkingContext::addPasses(pm);
 }
 
-std::vector<std::unique_ptr<File>>
-  elf::X86_64LinkingContext::createInternalFiles(){
-  std::vector<std::unique_ptr<File> > result =
-    ELFLinkingContext::createInternalFiles();
-  std::unique_ptr<X86_64InitFiniFile>
-    initFiniFile(new X86_64InitFiniFile(*this));
-  for (auto ai:initFunctions())
+bool elf::X86_64LinkingContext::createInternalFiles(
+    std::vector<std::unique_ptr<File> > &result) const {
+  ELFLinkingContext::createInternalFiles(result);
+  std::unique_ptr<X86_64InitFiniFile> initFiniFile(
+      new X86_64InitFiniFile(*this));
+  for (auto ai : initFunctions())
     initFiniFile->addInitFunction(ai);
   for (auto ai:finiFunctions())
     initFiniFile->addFiniFunction(ai);
   result.push_back(std::move(initFiniFile));
-  return result;
+  return true;
 }
 
 #define LLD_CASE(name) .Case(#name, llvm::ELF::name)

Modified: lld/trunk/lib/ReaderWriter/ELF/X86_64/X86_64LinkingContext.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/X86_64/X86_64LinkingContext.h?rev=192081&r1=192080&r2=192081&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/X86_64/X86_64LinkingContext.h (original)
+++ lld/trunk/lib/ReaderWriter/ELF/X86_64/X86_64LinkingContext.h Sun Oct  6 21:47:09 2013
@@ -77,7 +77,7 @@ public:
   }
 
   /// \brief Create Internal files for Init/Fini
-  std::vector<std::unique_ptr<File>> createInternalFiles();
+  bool createInternalFiles(std::vector<std::unique_ptr<File> > &) const;
 
   virtual ErrorOr<Reference::Kind> relocKindFromString(StringRef str) const;
   virtual ErrorOr<std::string> stringFromRelocKind(Reference::Kind kind) const;

Modified: lld/trunk/lib/ReaderWriter/ELF/X86_64/X86_64TargetHandler.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/X86_64/X86_64TargetHandler.cpp?rev=192081&r1=192080&r2=192081&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/X86_64/X86_64TargetHandler.cpp (original)
+++ lld/trunk/lib/ReaderWriter/ELF/X86_64/X86_64TargetHandler.cpp Sun Oct  6 21:47:09 2013
@@ -15,13 +15,15 @@ using namespace lld;
 using namespace elf;
 
 X86_64TargetHandler::X86_64TargetHandler(X86_64LinkingContext &context)
-    : DefaultTargetHandler(context), _gotFile(context),
+    : DefaultTargetHandler(context), _gotFile(new GOTFile(context)),
       _relocationHandler(context), _targetLayout(context) {}
 
-void X86_64TargetHandler::addFiles(InputFiles &f) {
-  _gotFile.addAtom(*new (_gotFile._alloc) GLOBAL_OFFSET_TABLEAtom(_gotFile));
-  _gotFile.addAtom(*new (_gotFile._alloc) TLSGETADDRAtom(_gotFile));
+bool X86_64TargetHandler::createImplicitFiles(
+    std::vector<std::unique_ptr<File> > &result) {
+  _gotFile->addAtom(*new (_gotFile->_alloc) GLOBAL_OFFSET_TABLEAtom(*_gotFile));
+  _gotFile->addAtom(*new (_gotFile->_alloc) TLSGETADDRAtom(*_gotFile));
   if (_context.isDynamic())
-    _gotFile.addAtom(*new (_gotFile._alloc) DYNAMICAtom(_gotFile));
-  f.appendFile(_gotFile);
+    _gotFile->addAtom(*new (_gotFile->_alloc) DYNAMICAtom(*_gotFile));
+  result.push_back(std::move(_gotFile));
+  return true;
 }

Modified: lld/trunk/lib/ReaderWriter/ELF/X86_64/X86_64TargetHandler.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/X86_64/X86_64TargetHandler.h?rev=192081&r1=192080&r2=192081&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/X86_64/X86_64TargetHandler.h (original)
+++ lld/trunk/lib/ReaderWriter/ELF/X86_64/X86_64TargetHandler.h Sun Oct  6 21:47:09 2013
@@ -35,15 +35,16 @@ public:
     return _relocationHandler;
   }
 
-  virtual void addFiles(InputFiles &f);
+  virtual bool createImplicitFiles(std::vector<std::unique_ptr<File> > &);
 
 private:
   class GOTFile : public SimpleFile {
   public:
     GOTFile(const ELFLinkingContext &eti) : SimpleFile(eti, "GOTFile") {}
     llvm::BumpPtrAllocator _alloc;
-  } _gotFile;
+  };
 
+  std::unique_ptr<GOTFile> _gotFile;
   X86_64TargetRelocationHandler _relocationHandler;
   TargetLayout<X86_64ELFType> _targetLayout;
 };

Modified: lld/trunk/lib/ReaderWriter/MachO/MachOLinkingContext.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/MachO/MachOLinkingContext.cpp?rev=192081&r1=192080&r2=192081&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/MachO/MachOLinkingContext.cpp (original)
+++ lld/trunk/lib/ReaderWriter/MachO/MachOLinkingContext.cpp Sun Oct  6 21:47:09 2013
@@ -242,19 +242,6 @@ void MachOLinkingContext::addPasses(Pass
   pm.add(std::unique_ptr<Pass>(new LayoutPass()));
 }
 
-error_code MachOLinkingContext::parseFile(
-    LinkerInput &input,
-    std::vector<std::unique_ptr<File>> &result) const {
-  //  if (!_machoReader)
-  //    _machoReader = createReaderMachO(*this);
-  //  error_code ec = _machoReader->parseFile(input,result);
-  //  if (ec) {
-  return _yamlReader->parseFile(input, result);
-  //  }
-
-  return error_code::success();
-}
-
 Writer &MachOLinkingContext::writer() const {
   if (!_writer) {
     _writer = createWriterMachO(*this);

Modified: lld/trunk/lib/ReaderWriter/MachO/WriterMachO.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/MachO/WriterMachO.cpp?rev=192081&r1=192080&r2=192081&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/MachO/WriterMachO.cpp (original)
+++ lld/trunk/lib/ReaderWriter/MachO/WriterMachO.cpp Sun Oct  6 21:47:09 2013
@@ -27,7 +27,6 @@
 
 #include "lld/Core/DefinedAtom.h"
 #include "lld/Core/File.h"
-#include "lld/Core/InputFiles.h"
 #include "lld/Core/Reference.h"
 #include "lld/Core/SharedLibraryAtom.h"
 #include "lld/ReaderWriter/MachOLinkingContext.h"
@@ -339,7 +338,7 @@ public:
   MachOWriter(const MachOLinkingContext &context);
 
   virtual error_code  writeFile(const lld::File &file, StringRef path);
-  virtual void        addFiles(InputFiles&);
+  virtual bool createImplicitFiles(std::vector<std::unique_ptr<File> > &);
 
   uint64_t    addressOfAtom(const Atom *atom);
   void        findSegment(StringRef segmentName, uint32_t *segIndex,
@@ -369,14 +368,14 @@ private:
 
   const MachOLinkingContext &_context;
   mach_o::KindHandler &_referenceKindHandler;
-  CRuntimeFile _cRuntimeFile;
-  LoadCommandsChunk          *_loadCommandsChunk;
-  LoadCommandPaddingChunk    *_paddingChunk;
-  AtomToAddress               _atomToAddress;
-  std::vector<Chunk*>         _chunks;
-  std::vector<SectionChunk*>  _sectionChunks;
-  std::vector<LinkEditChunk*> _linkEditChunks;
-  BindingInfoChunk           *_bindingInfo;
+  std::unique_ptr<CRuntimeFile> _cRuntimeFile;
+  LoadCommandsChunk *_loadCommandsChunk;
+  LoadCommandPaddingChunk *_paddingChunk;
+  AtomToAddress _atomToAddress;
+  std::vector<Chunk *> _chunks;
+  std::vector<SectionChunk *> _sectionChunks;
+  std::vector<LinkEditChunk *> _linkEditChunks;
+  BindingInfoChunk *_bindingInfo;
   LazyBindingInfoChunk       *_lazyBindingInfo;
   SymbolTableChunk           *_symbolTableChunk;
   SymbolStringsChunk         *_stringsChunk;
@@ -1264,9 +1263,10 @@ uint32_t SymbolStringsChunk::stringIndex
 
 MachOWriter::MachOWriter(const MachOLinkingContext &context)
     : _context(context), _referenceKindHandler(context.kindHandler()),
-      _cRuntimeFile(context), _bindingInfo(nullptr), _lazyBindingInfo(nullptr),
-      _symbolTableChunk(nullptr), _stringsChunk(nullptr), _entryAtom(nullptr),
-      _linkEditStartOffset(0), _linkEditStartAddress(0) {}
+      _cRuntimeFile(new CRuntimeFile(context)), _bindingInfo(nullptr),
+      _lazyBindingInfo(nullptr), _symbolTableChunk(nullptr),
+      _stringsChunk(nullptr), _entryAtom(nullptr), _linkEditStartOffset(0),
+      _linkEditStartAddress(0) {}
 
 void MachOWriter::build(const lld::File &file) {
   // Create objects for each chunk.
@@ -1487,11 +1487,12 @@ error_code MachOWriter::writeFile(const
   return buffer->commit();
 }
 
-void MachOWriter::addFiles(InputFiles &inputFiles) {
-  inputFiles.prependFile(_cRuntimeFile);
+bool
+MachOWriter::createImplicitFiles(std::vector<std::unique_ptr<File> > &result) {
+  result.push_back(std::move(_cRuntimeFile));
+  return true;
 }
 
-
 } // namespace mach_o
 
 std::unique_ptr<Writer> createWriterMachO(const MachOLinkingContext &context) {

Modified: lld/trunk/lib/ReaderWriter/Native/ReaderNative.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/Native/ReaderNative.cpp?rev=192081&r1=192080&r2=192081&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/Native/ReaderNative.cpp (original)
+++ lld/trunk/lib/ReaderWriter/Native/ReaderNative.cpp Sun Oct  6 21:47:09 2013
@@ -250,22 +250,22 @@ public:
   /// Instantiates a File object from a native object file.  Ownership
   /// of the MemoryBuffer is transfered to the resulting File object.
   static error_code make(const LinkingContext &context,
-                         LinkerInput &input,
-                         std::vector<std::unique_ptr<lld::File>> &result) {
+                         std::unique_ptr<MemoryBuffer> mb,
+                         std::vector<std::unique_ptr<lld::File> > &result) {
     const uint8_t *const base =
-        reinterpret_cast<const uint8_t *>(input.getBuffer().getBufferStart());
-    StringRef path(input.getBuffer().getBufferIdentifier());
-    const NativeFileHeader* const header =
-                       reinterpret_cast<const NativeFileHeader*>(base);
+        reinterpret_cast<const uint8_t *>(mb->getBufferStart());
+    StringRef path(mb->getBufferIdentifier());
+    const NativeFileHeader *const header =
+        reinterpret_cast<const NativeFileHeader *>(base);
     const NativeChunk *const chunks =
-      reinterpret_cast<const NativeChunk*>(base + sizeof(NativeFileHeader));
+        reinterpret_cast<const NativeChunk *>(base + sizeof(NativeFileHeader));
     // make sure magic matches
     if ( memcmp(header->magic, NATIVE_FILE_HEADER_MAGIC, 16) != 0 )
       return make_error_code(native_reader_error::unknown_file_format);
 
     // make sure mapped file contains all needed data
-    const size_t fileSize = input.getBuffer().getBufferSize();
-    if ( header->fileSize > fileSize )
+    const size_t fileSize = mb->getBufferSize();
+    if (header->fileSize > fileSize)
       return make_error_code(native_reader_error::file_too_short);
 
     DEBUG_WITH_TYPE("ReaderNative",
@@ -274,8 +274,7 @@ public:
                                  << header->chunkCount << "\n");
 
     // instantiate NativeFile object and add values to it as found
-    std::unique_ptr<File> file(new File(context, std::move(input.takeBuffer()),
-                                        path));
+    std::unique_ptr<File> file(new File(context, std::move(mb), path));
 
     // process each chunk
     for (uint32_t i = 0; i < header->chunkCount; ++i) {
@@ -930,9 +929,9 @@ public:
   Reader(const LinkingContext &context) : lld::Reader(context) {}
 
   virtual error_code
-  parseFile(LinkerInput &input,
-            std::vector<std::unique_ptr<lld::File>> &result) const {
-    return File::make(_context, input, result);
+  parseFile(std::unique_ptr<MemoryBuffer> &mb,
+            std::vector<std::unique_ptr<lld::File> > &result) const {
+    return File::make(_context, std::move(mb), result);
   }
 };
 } // end namespace native

Modified: lld/trunk/lib/ReaderWriter/PECOFF/LinkerGeneratedSymbolFile.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/PECOFF/LinkerGeneratedSymbolFile.h?rev=192081&r1=192080&r2=192081&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/PECOFF/LinkerGeneratedSymbolFile.h (original)
+++ lld/trunk/lib/ReaderWriter/PECOFF/LinkerGeneratedSymbolFile.h Sun Oct  6 21:47:09 2013
@@ -15,7 +15,6 @@
 #include "llvm/Support/Allocator.h"
 #include "llvm/Support/Path.h"
 #include "lld/Core/ArchiveLibraryFile.h"
-#include "lld/Core/InputFiles.h"
 #include "lld/Core/PassManager.h"
 #include "lld/Passes/LayoutPass.h"
 #include "lld/ReaderWriter/PECOFFLinkingContext.h"

Modified: lld/trunk/lib/ReaderWriter/PECOFF/PECOFFLinkingContext.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/PECOFF/PECOFFLinkingContext.cpp?rev=192081&r1=192080&r2=192081&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/PECOFF/PECOFFLinkingContext.cpp (original)
+++ lld/trunk/lib/ReaderWriter/PECOFF/PECOFFLinkingContext.cpp Sun Oct  6 21:47:09 2013
@@ -15,7 +15,6 @@
 #include "llvm/ADT/SmallString.h"
 #include "llvm/Support/Allocator.h"
 #include "llvm/Support/Path.h"
-#include "lld/Core/InputFiles.h"
 #include "lld/Core/PassManager.h"
 #include "lld/Passes/LayoutPass.h"
 #include "lld/ReaderWriter/PECOFFLinkingContext.h"
@@ -29,12 +28,6 @@ namespace lld {
 
 namespace {} // anonymous namespace
 
-error_code PECOFFLinkingContext::parseFile(
-    LinkerInput &input,
-    std::vector<std::unique_ptr<File>> &result) const {
-  return _reader->parseFile(input, result);
-}
-
 bool PECOFFLinkingContext::validateImpl(raw_ostream &diagnostics) {
   if (_stackReserve < _stackCommit) {
     diagnostics << "Invalid stack size: reserve size must be equal to or "
@@ -75,7 +68,7 @@ bool PECOFFLinkingContext::validateImpl(
   return true;
 }
 
-std::unique_ptr<File> PECOFFLinkingContext::createEntrySymbolFile() {
+std::unique_ptr<File> PECOFFLinkingContext::createEntrySymbolFile() const {
   if (entrySymbolName().empty())
     return nullptr;
   std::unique_ptr<SimpleFile> entryFile(
@@ -85,7 +78,7 @@ std::unique_ptr<File> PECOFFLinkingConte
   return std::move(entryFile);
 }
 
-std::unique_ptr<File> PECOFFLinkingContext::createUndefinedSymbolFile() {
+std::unique_ptr<File> PECOFFLinkingContext::createUndefinedSymbolFile() const {
   if (_initialUndefinedSymbols.empty())
     return nullptr;
   std::unique_ptr<SimpleFile> undefinedSymFile(
@@ -96,9 +89,16 @@ std::unique_ptr<File> PECOFFLinkingConte
   return std::move(undefinedSymFile);
 }
 
-void PECOFFLinkingContext::addImplicitFiles(InputFiles &files) const {
-  auto *linkerFile = new (_alloc) coff::LinkerGeneratedSymbolFile(*this);
-  files.appendFile(*linkerFile);
+bool PECOFFLinkingContext::createImplicitFiles(
+    std::vector<std::unique_ptr<File> > &) const {
+  std::unique_ptr<SimpleFileNode> fileNode(
+      new SimpleFileNode("Implicit Files"));
+  std::unique_ptr<File> linkerGeneratedSymFile(
+      new coff::LinkerGeneratedSymbolFile(*this));
+  fileNode->appendInputFile(std::move(linkerGeneratedSymFile));
+  inputGraph().insertOneElementAt(std::move(fileNode),
+                                  InputGraph::Position::END);
+  return true;
 }
 
 /// Try to find the input library file from the search paths and append it to

Modified: lld/trunk/lib/ReaderWriter/PECOFF/ReaderCOFF.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/PECOFF/ReaderCOFF.cpp?rev=192081&r1=192080&r2=192081&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/PECOFF/ReaderCOFF.cpp (original)
+++ lld/trunk/lib/ReaderWriter/PECOFF/ReaderCOFF.cpp Sun Oct  6 21:47:09 2013
@@ -16,7 +16,6 @@
 #include "lld/Driver/Driver.h"
 #include "lld/ReaderWriter/PECOFFLinkingContext.h"
 #include "lld/ReaderWriter/Reader.h"
-#include "lld/ReaderWriter/ReaderArchive.h"
 
 #include "llvm/ADT/ArrayRef.h"
 #include "llvm/Object/COFF.h"
@@ -722,21 +721,16 @@ private:
 class ReaderCOFF : public Reader {
 public:
   explicit ReaderCOFF(PECOFFLinkingContext &context)
-      : Reader(context), _readerArchive(context, *this),
-        _PECOFFLinkingContext(context) {}
+      : Reader(context), _PECOFFLinkingContext(context) {}
 
-  error_code parseFile(LinkerInput &input,
+  error_code parseFile(std::unique_ptr<MemoryBuffer> &mb,
                        std::vector<std::unique_ptr<File> > &result) const {
-    StringRef magic(input.getBuffer().getBufferStart(),
-                    input.getBuffer().getBufferSize());
+    StringRef magic(mb->getBufferStart(), mb->getBufferSize());
     // The input file should be an archive file, a regular COFF file, or an an
     // import library member file. Try to parse in that order. If the input file
     // does not start with a known magic, parseCOFFImportLibrary will return an
     // error object.
     llvm::sys::fs::file_magic fileType = llvm::sys::fs::identify_magic(magic);
-    if (fileType == llvm::sys::fs::file_magic::archive)
-      return _readerArchive.parseFile(input, result);
-    std::unique_ptr<MemoryBuffer> mb(input.takeBuffer());
     if (fileType == llvm::sys::fs::file_magic::coff_object)
       return parseCOFFFile(mb, result);
     return lld::coff::parseCOFFImportLibrary(_context, mb, result);
@@ -808,7 +802,6 @@ private:
     return error_code::success();
   }
 
-  ReaderArchive _readerArchive;
   PECOFFLinkingContext &_PECOFFLinkingContext;
   mutable BumpPtrStringSaver _stringSaver;
 };

Modified: lld/trunk/lib/ReaderWriter/PECOFF/WriterPECOFF.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/PECOFF/WriterPECOFF.cpp?rev=192081&r1=192080&r2=192081&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/PECOFF/WriterPECOFF.cpp (original)
+++ lld/trunk/lib/ReaderWriter/PECOFF/WriterPECOFF.cpp Sun Oct  6 21:47:09 2013
@@ -30,7 +30,6 @@
 
 #include "lld/Core/DefinedAtom.h"
 #include "lld/Core/File.h"
-#include "lld/Core/InputFiles.h"
 #include "lld/ReaderWriter/AtomLayout.h"
 #include "lld/ReaderWriter/PECOFFLinkingContext.h"
 #include "lld/ReaderWriter/Writer.h"

Removed: lld/trunk/lib/ReaderWriter/ReaderArchive.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ReaderArchive.cpp?rev=192080&view=auto
==============================================================================
--- lld/trunk/lib/ReaderWriter/ReaderArchive.cpp (original)
+++ lld/trunk/lib/ReaderWriter/ReaderArchive.cpp (removed)
@@ -1,195 +0,0 @@
-//===- lib/ReaderWriter/ReaderArchive.cpp - Archive Library Reader--------===//
-//
-//                             The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===---------------------------------------------------------------------===//
-
-#include "lld/ReaderWriter/ReaderArchive.h"
-
-#include "lld/Core/ArchiveLibraryFile.h"
-
-#include "llvm/ADT/Hashing.h"
-#include "llvm/Object/ObjectFile.h"
-
-#include <unordered_map>
-
-namespace lld {
-/// \brief The FileArchive class represents an Archive Library file
-class FileArchive : public ArchiveLibraryFile {
-public:
-
-  virtual ~FileArchive() { }
-
-  /// \brief Check if any member of the archive contains an Atom with the
-  /// specified name and return the File object for that member, or nullptr.
-  virtual const File *find(StringRef name, bool dataSymbolOnly) const {
-    auto member = _symbolMemberMap.find(name);
-    if (member == _symbolMemberMap.end())
-      return nullptr;
-
-    llvm::object::Archive::child_iterator ci = member->second;
-
-    if (dataSymbolOnly) {
-      OwningPtr<MemoryBuffer> buff;
-      if (ci->getMemoryBuffer(buff, true))
-        return nullptr;
-      if (isDataSymbol(buff.take(), name))
-        return nullptr;
-    }
-
-    std::vector<std::unique_ptr<File>> result;
-
-    OwningPtr<MemoryBuffer> buff;
-    if (ci->getMemoryBuffer(buff, true))
-      return nullptr;
-    if (_context.logInputFiles())
-      llvm::outs() << buff->getBufferIdentifier() << "\n";
-    LinkerInput newInput(std::unique_ptr<MemoryBuffer>(buff.take()), _input);
-    if (_context.parseFile(newInput, result))
-      return nullptr;
-
-    assert(result.size() == 1);
-
-    result[0]->setOrdinalAndIncrement(_curChildOrd);
-
-    // give up the pointer so that this object no longer manages it
-    return result[0].release();
-  }
-
-  virtual void setOrdinalAndIncrement(uint64_t &ordinal) const {
-    _ordinal = ordinal++;
-    _curChildOrd = _ordinal;
-    // Leave space in ordinal range for all children
-    for (auto mf = _archive->begin_children(),
-              me = _archive->end_children(); mf != me; ++mf) {
-        ordinal++;
-    }
-  }
-
-  virtual const atom_collection<DefinedAtom> &defined() const {
-    return _definedAtoms;
-  }
-
-  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;
-  }
-
-protected:
-  error_code isDataSymbol(MemoryBuffer *mb, StringRef symbol) const {
-    std::unique_ptr<llvm::object::ObjectFile>
-                    obj(llvm::object::ObjectFile::createObjectFile(mb));
-    error_code ec;
-    llvm::object::SymbolRef::Type symtype;
-    uint32_t symflags;
-    llvm::object::symbol_iterator ibegin = obj->begin_symbols();
-    llvm::object::symbol_iterator iend = obj->end_symbols();
-    StringRef symbolname;
-
-    for (llvm::object::symbol_iterator i = ibegin; i != iend; i.increment(ec)) {
-      if (ec) return ec;
-
-      // Get symbol name
-      if ((ec = (i->getName(symbolname)))) return ec;
-
-      if (symbolname != symbol)
-          continue;
-
-      // Get symbol flags
-      if ((ec = (i->getFlags(symflags)))) return ec;
-
-      if (symflags <= llvm::object::SymbolRef::SF_Undefined)
-          continue;
-
-      // Get Symbol Type
-      if ((ec = (i->getType(symtype)))) return ec;
-
-      if (symtype == llvm::object::SymbolRef::ST_Data) {
-        return error_code::success();
-      }
-    }
-    return llvm::object::object_error::parse_failed;
-  }
-
-private:
-  LinkerInput                               _input;
-  std::unique_ptr<llvm::object::Archive>    _archive;
-  atom_collection_vector<DefinedAtom>       _definedAtoms;
-  atom_collection_vector<UndefinedAtom>     _undefinedAtoms;
-  atom_collection_vector<SharedLibraryAtom> _sharedLibraryAtoms;
-  atom_collection_vector<AbsoluteAtom>      _absoluteAtoms;
-  mutable uint64_t _curChildOrd;
-
-public:
-  /// only subclasses of ArchiveLibraryFile can be instantiated
-  FileArchive(const LinkingContext &context,
-              LinkerInput &input, error_code &ec)
-      : ArchiveLibraryFile(context, input.getBuffer().getBufferIdentifier()),
-        _input(std::move(input)) {
-    std::unique_ptr<llvm::object::Archive> archive_obj(
-        new llvm::object::Archive(_input.takeBuffer().release(), ec));
-    if (ec)
-      return;
-    _archive.swap(archive_obj);
-
-    // Cache symbols.
-    for (auto i = _archive->begin_symbols(), e = _archive->end_symbols();
-              i != e; ++i) {
-      StringRef name;
-      llvm::object::Archive::child_iterator member;
-      if ((ec = i->getName(name)))
-        return;
-      if ((ec = i->getMember(member)))
-        return;
-      _symbolMemberMap[name] = member;
-    }
-  }
-
-  std::unordered_map<StringRef,
-                     llvm::object::Archive::child_iterator> _symbolMemberMap;
-}; // class FileArchive
-
-// Returns a vector of Files that are contained in the archive file
-// pointed to by the MemoryBuffer
-error_code ReaderArchive::parseFile(LinkerInput &input,
-                            std::vector<std::unique_ptr<File>> &result) const {
-  error_code ec;
-
-  if (input.isWholeArchive()) {
-    _archive.reset(new llvm::object::Archive(input.takeBuffer().release(), ec));
-    if (ec)
-      return ec;
-
-    for (auto mf = _archive->begin_children(),
-              me = _archive->end_children(); mf != me; ++mf) {
-      OwningPtr<MemoryBuffer> buff;
-      if ((ec = mf->getMemoryBuffer(buff, true)))
-        return ec;
-      std::unique_ptr<MemoryBuffer> mbc(buff.take());
-      if (_context.logInputFiles())
-        llvm::outs() << buff->getBufferIdentifier() << "\n";
-      LinkerInput newInput(std::move(mbc), input);
-      if ((ec = _context.parseFile(newInput, result)))
-        return ec;
-    }
-  } else {
-    std::unique_ptr<File> f;
-    f.reset(new FileArchive(_context, input, ec));
-    if (ec)
-      return ec;
-
-    result.push_back(std::move(f));
-  }
-  return llvm::error_code::success();
-}
-} // end namespace lld

Modified: lld/trunk/lib/ReaderWriter/ReaderLinkerScript.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ReaderLinkerScript.cpp?rev=192081&r1=192080&r2=192081&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ReaderLinkerScript.cpp (original)
+++ lld/trunk/lib/ReaderWriter/ReaderLinkerScript.cpp Sun Oct  6 21:47:09 2013
@@ -77,8 +77,9 @@ private:
 
 namespace lld {
 error_code ReaderLinkerScript::parseFile(
-    LinkerInput &input, std::vector<std::unique_ptr<File> > &result) const {
-  auto lsf = LinkerScriptFile::create(_context, input.takeBuffer());
+    std::unique_ptr<MemoryBuffer> &mb,
+    std::vector<std::unique_ptr<File> > &result) const {
+  auto lsf = LinkerScriptFile::create(_context, std::move(mb));
   if (!lsf)
     return lsf;
   const LinkerScript *ls = (*lsf)->getScript();
@@ -90,11 +91,9 @@ error_code ReaderLinkerScript::parseFile
         if (error_code ec =
                 llvm::MemoryBuffer::getFileOrSTDIN(path._path, opmb))
           return ec;
-
-        LinkerInput newInput(std::unique_ptr<llvm::MemoryBuffer>(opmb.take()),
-                             input);
-
-        if (error_code ec = _context.parseFile(newInput, result))
+        std::unique_ptr<llvm::MemoryBuffer> eachMB(opmb.take());
+        if (error_code ec =
+                _context.getDefaultReader().parseFile(eachMB, result))
           return ec;
       }
   }

Modified: lld/trunk/lib/ReaderWriter/Writer.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/Writer.cpp?rev=192081&r1=192080&r2=192081&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/Writer.cpp (original)
+++ lld/trunk/lib/ReaderWriter/Writer.cpp Sun Oct  6 21:47:09 2013
@@ -7,6 +7,7 @@
 //
 //===----------------------------------------------------------------------===//
 
+#include "lld/Core/File.h"
 #include "lld/ReaderWriter/Writer.h"
 
 namespace lld {
@@ -15,4 +16,8 @@ Writer::Writer() {
 
 Writer::~Writer() {
 }
+
+bool Writer::createImplicitFiles(std::vector<std::unique_ptr<File> > &) {
+  return true;
+}
 } // end namespace lld

Modified: lld/trunk/lib/ReaderWriter/YAML/ReaderWriterYAML.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/YAML/ReaderWriterYAML.cpp?rev=192081&r1=192080&r2=192081&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/YAML/ReaderWriterYAML.cpp (original)
+++ lld/trunk/lib/ReaderWriter/YAML/ReaderWriterYAML.cpp Sun Oct  6 21:47:09 2013
@@ -1265,7 +1265,7 @@ class ReaderYAML : public Reader {
 public:
   ReaderYAML(const LinkingContext &context) : Reader(context) {}
 
-  error_code parseFile(LinkerInput &input,
+  error_code parseFile(std::unique_ptr<MemoryBuffer> &mb,
                        std::vector<std::unique_ptr<File> > &result) const {
     // Note: we do not take ownership of the MemoryBuffer.  That is
     // because yaml may produce multiple File objects, so there is no
@@ -1276,7 +1276,7 @@ public:
 
     // Create YAML Input parser.
     ContextInfo context(_context);
-    llvm::yaml::Input yin(input.getBuffer().getBuffer(), &context);
+    llvm::yaml::Input yin(mb->getBuffer(), &context);
 
     // Fill vector with File objects created by parsing yaml.
     std::vector<const lld::File *> createdFiles;

Modified: lld/trunk/test/Driver/lib-search.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/Driver/lib-search.test?rev=192081&r1=192080&r2=192081&view=diff
==============================================================================
--- lld/trunk/test/Driver/lib-search.test (original)
+++ lld/trunk/test/Driver/lib-search.test Sun Oct  6 21:47:09 2013
@@ -1,5 +1,5 @@
-RUN: not lld -flavor gnu -t -L%p/../elf/Inputs -lfnarchive  2> %t.err \
-RUN:  | FileCheck %s
+RUN: not lld -flavor gnu -t -L%p/../elf/Inputs -lfnarchive  2> %t.err
+RUN: FileCheck %s < %t.err
 
 # run linker with -t mode to dump full paths to input files
 

Modified: lld/trunk/test/Driver/libsearch-inputGraph.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/Driver/libsearch-inputGraph.test?rev=192081&r1=192080&r2=192081&view=diff
==============================================================================
--- lld/trunk/test/Driver/libsearch-inputGraph.test (original)
+++ lld/trunk/test/Driver/libsearch-inputGraph.test Sun Oct  6 21:47:09 2013
@@ -9,7 +9,7 @@ RUN: FileCheck -check-prefix="SYSROOT" %
 
 CHECK: Name    : {{[^ ]+}}elf/Inputs{{[\\/]}}libfnarchive.a
 CHECK: Type    : ELF File
-CHECK: Ordinal : -1
+CHECK: Ordinal : 0
 CHECK: Attributes :
 CHECK:   - wholeArchive : false
 CHECK:   - asNeeded : false
@@ -18,7 +18,7 @@ CHECK:     - {{[^ ]+}}elf/Inputs
 
 WHOLEARCHIVE: Name    : {{[^ ]+}}elf/Inputs{{[\\/]}}libfnarchive.a
 WHOLEARCHIVE: Type    : ELF File
-WHOLEARCHIVE: Ordinal : -1
+WHOLEARCHIVE: Ordinal : 0
 WHOLEARCHIVE: Attributes :
 WHOLEARCHIVE:   - wholeArchive : true
 WHOLEARCHIVE:   - asNeeded : false
@@ -27,7 +27,7 @@ WHOLEARCHIVE:     - {{[^ ]+}}elf/Inputs
 
 ASNEEDED: Name    : {{[^ ]+}}elf/Inputs{{[\\/]}}libfnarchive.a
 ASNEEDED: Type    : ELF File
-ASNEEDED: Ordinal : -1
+ASNEEDED: Ordinal : 0
 ASNEEDED: Attributes :
 ASNEEDED:   - wholeArchive : true
 ASNEEDED:   - asNeeded : true
@@ -36,7 +36,7 @@ ASNEEDED:     - {{[^ ]+}}elf/Inputs
 
 SYSROOT: Name    : {{[^ ]+}}elf/Inputs{{[\\/]}}libfnarchive.a
 SYSROOT: Type    : ELF File
-SYSROOT: Ordinal : -1
+SYSROOT: Ordinal : 0
 SYSROOT: Attributes :
 SYSROOT:   - wholeArchive : false
 SYSROOT:   - asNeeded : false

Modified: lld/trunk/test/elf/X86_64/dynlib-search.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf/X86_64/dynlib-search.test?rev=192081&r1=192080&r2=192081&view=diff
==============================================================================
--- lld/trunk/test/elf/X86_64/dynlib-search.test (original)
+++ lld/trunk/test/elf/X86_64/dynlib-search.test Sun Oct  6 21:47:09 2013
@@ -1,6 +1,6 @@
 # This tests the functionality for finding the shared library libfn.so for ELF
 RUN: lld -flavor gnu -target x86_64 %p/Inputs/main.o -L%p/Inputs/ -lfn -o %t \
-RUN: --noinhibit-exec -t > %t1
+RUN: --noinhibit-exec -t 2> %t1
 RUN: FileCheck %s < %t1
 
 CHECK: {{[\/0-9A-Za-z_]+}}libfn.so

Modified: lld/trunk/test/elf/X86_64/undef.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf/X86_64/undef.test?rev=192081&r1=192080&r2=192081&view=diff
==============================================================================
--- lld/trunk/test/elf/X86_64/undef.test (original)
+++ lld/trunk/test/elf/X86_64/undef.test Sun Oct  6 21:47:09 2013
@@ -7,7 +7,7 @@ RUN: lld -flavor gnu -target x86_64 %p/I
 RUN: llvm-readobj -symbols %t | FileCheck %s
 
 SYMFROMARCHIVE:  Symbol {
-SYMFROMARCHIVE:    Name: fn (1)
+SYMFROMARCHIVE:    Name: fn (16)
 SYMFROMARCHIVE:    Size: 11
 SYMFROMARCHIVE:    Binding: Global (0x1)
 SYMFROMARCHIVE:    Type: Function (0x2)

Modified: lld/trunk/test/elf/dynamic.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf/dynamic.test?rev=192081&r1=192080&r2=192081&view=diff
==============================================================================
--- lld/trunk/test/elf/dynamic.test (original)
+++ lld/trunk/test/elf/dynamic.test Sun Oct  6 21:47:09 2013
@@ -46,18 +46,18 @@ CHECK-NEXT:   }
 
 CHECK:      DynamicSymbols [
 CHECK:        Symbol {
-CHECK:          Name: foo
+CHECK:          Name: i
 CHECK-NEXT:     Value: 0
 CHECK-NEXT:     Size:
 CHECK-NEXT:     Binding: Global
-CHECK-NEXT:     Type: Function
+CHECK-NEXT:     Type: Object
 CHECK:        }
 CHECK:        Symbol {
-CHECK:          Name: i
+CHECK:          Name: foo
 CHECK-NEXT:     Value: 0
 CHECK-NEXT:     Size:
 CHECK-NEXT:     Binding: Global
-CHECK-NEXT:     Type: Object
+CHECK-NEXT:     Type: Function
 CHECK:        }
 
 CHECK: DynamicSection [ (15 entries)

Modified: lld/trunk/test/elf/ifunc.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf/ifunc.test?rev=192081&r1=192080&r2=192081&view=diff
==============================================================================
--- lld/trunk/test/elf/ifunc.test (original)
+++ lld/trunk/test/elf/ifunc.test Sun Oct  6 21:47:09 2013
@@ -25,19 +25,19 @@ PLT: references:
 PLT:  kind: R_X86_64_IRELATIVE
 PLT:  target: hey
 
-PLT: name:  plt
+PLT: name: main
 PLT: scope: global
 PLT: references:
-PLT:   kind:   R_X86_64_PC32
+PLT:   kind: R_X86_64_PC32
 PLT:   target: [[PLTNAME:[-a-zA-Z0-9_]+]]
-PLT:   kind: layout-before
-PLT:   target: __hey_1
 
-PLT: name: main
+PLT: name:  plt
 PLT: scope: global
 PLT: references:
-PLT:   kind: R_X86_64_PC32
+PLT:   kind:   R_X86_64_PC32
 PLT:   target: [[PLTNAME]]
+PLT:   kind: layout-before
+PLT:   target: __hey_1
 
 // Make sure the target of main's relocation is a stub with a PC32 relocation.
 // This relocation is to the got atom, but you can't really write that check in
@@ -60,7 +60,7 @@ BIN-NEXT: {{[0-9a-f]+}} 00000000 0000000
 
 RELATIVEADDEND:      Relocations [
 RELATIVEADDEND-NEXT:   Section (1) .rela.plt {
-RELATIVEADDEND-NEXT:     0x401000 R_X86_64_IRELATIVE - 0x4000E0
+RELATIVEADDEND-NEXT:     0x401000 R_X86_64_IRELATIVE - 0x4000FC
 RELATIVEADDEND-NEXT:   }
 RELATIVEADDEND-NEXT: ]
 

Modified: lld/trunk/test/elf/librarynotfound.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf/librarynotfound.test?rev=192081&r1=192080&r2=192081&view=diff
==============================================================================
--- lld/trunk/test/elf/librarynotfound.test (original)
+++ lld/trunk/test/elf/librarynotfound.test Sun Oct  6 21:47:09 2013
@@ -1,4 +1,5 @@
 # Tests the functionality of library not found
-RUN: not lld -flavor gnu -lfn | FileCheck %s
+RUN: not lld -flavor gnu -lfn 2> %t1
+RUN: FileCheck %s < %t1
 
 CHECK: Unable to find library -lfn

Modified: lld/trunk/test/elf/undef-from-main-dso.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf/undef-from-main-dso.test?rev=192081&r1=192080&r2=192081&view=diff
==============================================================================
--- lld/trunk/test/elf/undef-from-main-dso.test (original)
+++ lld/trunk/test/elf/undef-from-main-dso.test Sun Oct  6 21:47:09 2013
@@ -1,7 +1,7 @@
-RUN: lld -flavor gnu -e main -o %t -L%p/Inputs -lundef %p/Inputs/undef.o
+RUN: lld -flavor gnu -e main -o %t -L%p/Inputs  %p/Inputs/undef.o -lundef
 RUN: llvm-readobj -relocations -symbols %t | FileCheck %s
 
-RUN: lld -flavor gnu -e main -o %t -L%p/Inputs -lundef %p/Inputs/undef-pc32.o
+RUN: lld -flavor gnu -e main -o %t -L%p/Inputs  %p/Inputs/undef-pc32.o -lundef
 RUN: llvm-readobj -relocations -symbols %t | FileCheck %s
 
 # DSO source code:

Modified: lld/trunk/unittests/DriverTests/DriverTest.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/unittests/DriverTests/DriverTest.h?rev=192081&r1=192080&r2=192081&view=diff
==============================================================================
--- lld/trunk/unittests/DriverTests/DriverTest.h (original)
+++ lld/trunk/unittests/DriverTests/DriverTest.h Sun Oct  6 21:47:09 2013
@@ -11,7 +11,6 @@
 
 #include "gtest/gtest.h"
 
-#include "lld/Core/LinkerInput.h"
 #include "lld/Driver/Driver.h"
 
 #include "llvm/Support/raw_ostream.h"
@@ -30,7 +29,7 @@ protected:
   std::string &errorMessage() { return  _errorMessage; }
 
   // Convenience method for getting number of input files.
-  int inputFileCount() { return linkingContext()->inputGraph().numFiles(); }
+  int inputFileCount() { return linkingContext()->inputGraph().size(); }
 
   // Convenience method for getting i'th input files name.
   std::string inputFile(unsigned index) {





More information about the llvm-commits mailing list