[lld] r226132 - Re-commit r225766, r225767, r225769, r225814, r225816, r225829, and r225832.

Rui Ueyama ruiu at google.com
Wed Jan 14 22:49:21 PST 2015


Author: ruiu
Date: Thu Jan 15 00:49:21 2015
New Revision: 226132

URL: http://llvm.org/viewvc/llvm-project?rev=226132&view=rev
Log:
Re-commit r225766, r225767, r225769, r225814, r225816, r225829, and r225832.

These changes depended on r225674 and had been rolled back in r225859.
Because r225674 has been re-submitted, it's safe to re-submit them.

Removed:
    lld/trunk/unittests/DriverTests/InputGraphTest.cpp
Modified:
    lld/trunk/include/lld/Core/InputGraph.h
    lld/trunk/include/lld/Core/Resolver.h
    lld/trunk/include/lld/Driver/WrapperInputGraph.h
    lld/trunk/include/lld/ReaderWriter/PECOFFLinkingContext.h
    lld/trunk/lib/Core/InputGraph.cpp
    lld/trunk/lib/Core/Resolver.cpp
    lld/trunk/lib/Driver/Driver.cpp
    lld/trunk/lib/Driver/GnuLdDriver.cpp
    lld/trunk/lib/Driver/WinLinkDriver.cpp
    lld/trunk/lib/ReaderWriter/MachO/MachOLinkingContext.cpp
    lld/trunk/lib/ReaderWriter/PECOFF/LinkerGeneratedSymbolFile.h
    lld/trunk/lib/ReaderWriter/PECOFF/PECOFFLinkingContext.cpp
    lld/trunk/unittests/DriverTests/CMakeLists.txt

Modified: lld/trunk/include/lld/Core/InputGraph.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/include/lld/Core/InputGraph.h?rev=226132&r1=226131&r2=226132&view=diff
==============================================================================
--- lld/trunk/include/lld/Core/InputGraph.h (original)
+++ lld/trunk/include/lld/Core/InputGraph.h Thu Jan 15 00:49:21 2015
@@ -49,18 +49,7 @@ public:
   typedef FileVectorT::iterator FileIterT;
 
   /// \brief Initialize the inputgraph
-  InputGraph() : _nextElementIndex(0), _currentInputElement(nullptr) {}
-  virtual ~InputGraph();
-
-  /// getNextFile returns the next file that needs to be processed by
-  /// the resolver. When there are no more files to be processed, an
-  /// nullptr is returned.
-  File *getNextFile();
-
-  /// Adds an observer of getNextFile(). Each time a new file is about to be
-  /// returned from getNextFile(), registered observers are called with the file
-  /// being returned.
-  void registerObserver(std::function<void(File *)>);
+  InputGraph() : _index(0) {}
 
   /// \brief Adds a node into the InputGraph
   void addInputElement(std::unique_ptr<InputElement>);
@@ -68,34 +57,16 @@ public:
   /// \brief Adds a node at the beginning of the InputGraph
   void addInputElementFront(std::unique_ptr<InputElement>);
 
-  /// Normalize the InputGraph. It calls getReplacements() on each element.
-  void normalize();
-
-  InputElementVectorT &inputElements() {
-    return _inputArgs;
-  }
-
-  // Returns the current group size if we are at an --end-group.
-  // Otherwise returns 0.
-  int getGroupSize();
-  void skipGroup();
+  InputElementVectorT &inputElements() { return _inputArgs; }
 
   // \brief Returns the number of input files.
   size_t size() const { return _inputArgs.size(); }
 
-  /// \brief Dump the input Graph
-  bool dump(raw_ostream &diagnostics = llvm::errs());
-
 protected:
   // Input arguments
   InputElementVectorT _inputArgs;
   // Index of the next element to be processed
-  uint32_t _nextElementIndex;
-  InputElement *_currentInputElement;
-  std::vector<std::function<void(File *)>> _observers;
-
-private:
-  InputElement *getNextInputElement();
+  size_t _index;
 };
 
 /// \brief This describes each element in the InputGraph. The Kind
@@ -125,11 +96,6 @@ public:
   /// Get the next file to be processed by the resolver
   virtual File *getNextFile() = 0;
 
-  /// Get the elements that we want to expand with.
-  virtual bool getReplacements(InputGraph::InputElementVectorT &) {
-    return false;
-  }
-
 protected:
   Kind _kind; // The type of the Element
 };
@@ -165,9 +131,13 @@ private:
 class FileNode : public InputElement {
 public:
   FileNode(StringRef path)
-      : InputElement(InputElement::Kind::File), _path(path), _nextFileIndex(0) {
+      : InputElement(InputElement::Kind::File), _path(path), _done(false) {
   }
 
+  FileNode(StringRef path, std::unique_ptr<File> f)
+      : InputElement(InputElement::Kind::File), _path(path), _file(std::move(f)),
+        _done(false) {}
+
   virtual ErrorOr<StringRef> getPath(const LinkingContext &) const {
     return _path;
   }
@@ -186,36 +156,33 @@ public:
   }
 
   /// \brief Get the list of files
-  range<InputGraph::FileIterT> files() {
-    return make_range(_files.begin(), _files.end());
-  }
+  File *getFile() { return _file.get(); }
 
   /// \brief add a file to the list of files
   virtual void addFiles(InputGraph::FileVectorT files) {
     assert(files.size() == 1);
-    assert(_files.empty());
-    for (std::unique_ptr<File> &ai : files)
-      _files.push_back(std::move(ai));
+    assert(!_file);
+    _file = std::move(files[0]);
   }
 
-  bool getReplacements(InputGraph::InputElementVectorT &result) override;
-
   /// \brief Return the next File thats part of this node to the
   /// resolver.
   File *getNextFile() override {
-    if (_nextFileIndex == _files.size())
+    assert(_file);
+    if (_done)
       return nullptr;
-    return _files[_nextFileIndex++].get();
+    _done = true;
+    return _file.get();
   }
 
   std::error_code parse(const LinkingContext &, raw_ostream &) override;
 
 protected:
   StringRef _path;                       // The path of the Input file
-  InputGraph::FileVectorT _files;        // A vector of lld File objects
+  std::unique_ptr<File> _file;           // An lld File object
 
   // The next file that would be processed by the resolver
-  uint32_t _nextFileIndex;
+  bool _done;
 };
 
 /// \brief Represents Internal Input files
@@ -223,15 +190,13 @@ class SimpleFileNode : public FileNode {
 public:
   SimpleFileNode(StringRef path) : FileNode(path) {}
   SimpleFileNode(StringRef path, std::unique_ptr<File> f)
-      : FileNode(path) {
-    _files.push_back(std::move(f));
-  }
+      : FileNode(path, std::move(f)) {}
 
   virtual ~SimpleFileNode() {}
 
   /// \brief add a file to the list of files
   virtual void appendInputFile(std::unique_ptr<File> f) {
-    _files.push_back(std::move(f));
+    _file = std::move(f);
   }
 };
 

Modified: lld/trunk/include/lld/Core/Resolver.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/include/lld/Core/Resolver.h?rev=226132&r1=226131&r2=226132&view=diff
==============================================================================
--- lld/trunk/include/lld/Core/Resolver.h (original)
+++ lld/trunk/include/lld/Core/Resolver.h Thu Jan 15 00:49:21 2015
@@ -55,8 +55,8 @@ public:
 private:
   typedef std::function<void(StringRef, bool)> UndefCallback;
 
-  bool undefinesAdded(int count);
-  File *nextFile(bool &inGroup);
+  bool undefinesAdded(int begin, int end);
+  File *getFile(int &index, int &groupLevel);
 
   /// \brief Add section group/.gnu.linkonce if it does not exist previously.
   void maybeAddSectionGroupOrGnuLinkOnce(const DefinedAtom &atom);

Modified: lld/trunk/include/lld/Driver/WrapperInputGraph.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/include/lld/Driver/WrapperInputGraph.h?rev=226132&r1=226131&r2=226132&view=diff
==============================================================================
--- lld/trunk/include/lld/Driver/WrapperInputGraph.h (original)
+++ lld/trunk/include/lld/Driver/WrapperInputGraph.h Thu Jan 15 00:49:21 2015
@@ -21,9 +21,7 @@ namespace lld {
 
 class WrapperNode : public FileNode {
 public:
-  WrapperNode(std::unique_ptr<File> file) : FileNode(file->path()) {
-    _files.push_back(std::move(file));
-  }
+  WrapperNode(std::unique_ptr<File> f) : FileNode(f->path(), std::move(f)) {}
 };
 
 }

Modified: lld/trunk/include/lld/ReaderWriter/PECOFFLinkingContext.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/include/lld/ReaderWriter/PECOFFLinkingContext.h?rev=226132&r1=226131&r2=226132&view=diff
==============================================================================
--- lld/trunk/include/lld/ReaderWriter/PECOFFLinkingContext.h (original)
+++ lld/trunk/include/lld/ReaderWriter/PECOFFLinkingContext.h Thu Jan 15 00:49:21 2015
@@ -30,6 +30,28 @@ static const uint8_t DEFAULT_DOS_STUB[12
 
 namespace lld {
 
+namespace pecoff {
+class ResolvableSymbols {
+public:
+  void add(File *file);
+
+  const std::set<std::string> &defined() {
+    readAllSymbols();
+    return _defined;
+  }
+
+private:
+  // Files are read lazily, so that it has no runtime overhead if
+  // no one accesses this class.
+  void readAllSymbols();
+
+  std::set<std::string> _defined;
+  std::set<File *> _seen;
+  std::set<File *> _queue;
+  std::mutex _mutex;
+};
+} // end namespace pecoff
+
 class PECOFFLinkingContext : public LinkingContext {
 public:
   PECOFFLinkingContext()
@@ -328,6 +350,10 @@ public:
 
   std::recursive_mutex &getMutex() { return _mutex; }
 
+  pecoff::ResolvableSymbols *getResolvableSymsFile() {
+    return &_resolvableSyms;
+  }
+
 protected:
   /// Method to create a internal file for the entry symbol
   std::unique_ptr<File> createEntrySymbolFile() const override;
@@ -442,6 +468,8 @@ private:
   // Name of the temporary file for lib.exe subcommand. For debugging
   // only.
   std::string _moduleDefinitionFile;
+
+  pecoff::ResolvableSymbols _resolvableSyms;
 };
 
 } // end namespace lld

Modified: lld/trunk/lib/Core/InputGraph.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/Core/InputGraph.cpp?rev=226132&r1=226131&r2=226132&view=diff
==============================================================================
--- lld/trunk/lib/Core/InputGraph.cpp (original)
+++ lld/trunk/lib/Core/InputGraph.cpp Thu Jan 15 00:49:21 2015
@@ -13,33 +13,6 @@
 
 using namespace lld;
 
-InputGraph::~InputGraph() { }
-
-File *InputGraph::getNextFile() {
-  // Try to get the next file of _currentInputElement. If the current input
-  // element points to an archive file, and there's a file left in the archive,
-  // it will succeed. If not, try to get the next file in the input graph.
-  for (;;) {
-    if (_currentInputElement) {
-      File *next = _currentInputElement->getNextFile();
-      if (next) {
-        for (const std::function<void(File *)> &observer : _observers)
-          observer(next);
-        return next;
-      }
-    }
-
-    InputElement *elt = getNextInputElement();
-    if (!elt)
-      return nullptr;
-    _currentInputElement = elt;
-  }
-}
-
-void InputGraph::registerObserver(std::function<void(File *)> fn) {
-  _observers.push_back(fn);
-}
-
 void InputGraph::addInputElement(std::unique_ptr<InputElement> ie) {
   _inputArgs.push_back(std::move(ie));
 }
@@ -48,63 +21,9 @@ void InputGraph::addInputElementFront(st
   _inputArgs.insert(_inputArgs.begin(), std::move(ie));
 }
 
-bool InputGraph::dump(raw_ostream &diagnostics) {
-  for (std::unique_ptr<InputElement> &ie : _inputArgs)
-    if (!ie->dump(diagnostics))
-      return false;
-  return true;
-}
-
-/// \brief Helper functions for the resolver
-InputElement *InputGraph::getNextInputElement() {
-  if (_nextElementIndex >= _inputArgs.size())
-    return nullptr;
-  InputElement *elem = _inputArgs[_nextElementIndex++].get();
-  if (isa<GroupEnd>(elem))
-    return getNextInputElement();
-  return elem;
-}
-
-void InputGraph::normalize() {
-  std::vector<std::unique_ptr<InputElement>> vec;
-  for (std::unique_ptr<InputElement> &elt : _inputArgs) {
-    if (elt->getReplacements(vec))
-      continue;
-    vec.push_back(std::move(elt));
-  }
-  _inputArgs = std::move(vec);
-}
-
-// If we are at the end of a group, return its size (which indicates
-// how many files we need to go back in the command line).
-// Returns 0 if we are not at the end of a group.
-int InputGraph::getGroupSize() {
-  if (_nextElementIndex >= _inputArgs.size())
-    return 0;
-  InputElement *elem = _inputArgs[_nextElementIndex].get();
-  if (const GroupEnd *group = dyn_cast<GroupEnd>(elem))
-    return group->getSize();
-  return 0;
-}
-
-void InputGraph::skipGroup() {
-  if (_nextElementIndex >= _inputArgs.size())
-    return;
-  if (isa<GroupEnd>(_inputArgs[_nextElementIndex].get()))
-    _nextElementIndex++;
-}
-
-bool FileNode::getReplacements(InputGraph::InputElementVectorT &result) {
-  if (_files.size() < 2)
-    return false;
-  for (std::unique_ptr<File> &file : _files)
-    result.push_back(llvm::make_unique<SimpleFileNode>(_path, std::move(file)));
-  return true;
-}
-
 std::error_code FileNode::parse(const LinkingContext &, raw_ostream &) {
-  for (std::unique_ptr<File> &file : _files)
-    if (std::error_code ec = file->parse())
+  if (_file)
+    if (std::error_code ec = _file->parse())
       return ec;
   return std::error_code();
 }

Modified: lld/trunk/lib/Core/Resolver.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/Core/Resolver.cpp?rev=226132&r1=226131&r2=226132&view=diff
==============================================================================
--- lld/trunk/lib/Core/Resolver.cpp (original)
+++ lld/trunk/lib/Core/Resolver.cpp Thu Jan 15 00:49:21 2015
@@ -231,52 +231,52 @@ void Resolver::addAtoms(const std::vecto
 
 // Returns true if at least one of N previous files has created an
 // undefined symbol.
-bool Resolver::undefinesAdded(int n) {
-  for (size_t i = _fileIndex - n; i < _fileIndex; ++i)
-    if (_newUndefinesAdded[_files[i]])
-      return true;
+bool Resolver::undefinesAdded(int begin, int end) {
+  std::vector<std::unique_ptr<InputElement>> &inputs =
+      _context.getInputGraph().inputElements();
+  for (int i = begin; i < end; ++i)
+    if (FileNode *node = dyn_cast<FileNode>(inputs[i].get()))
+      if (_newUndefinesAdded[node->getFile()])
+	return true;
   return false;
 }
 
-File *Resolver::nextFile(bool &inGroup) {
-  if (size_t groupSize = _context.getInputGraph().getGroupSize()) {
+File *Resolver::getFile(int &index, int &groupLevel) {
+  std::vector<std::unique_ptr<InputElement>> &inputs
+      = _context.getInputGraph().inputElements();
+  if ((size_t)index >= inputs.size())
+    return nullptr;
+  if (GroupEnd *group = dyn_cast<GroupEnd>(inputs[index].get())) {
     // We are at the end of the current group. If one or more new
     // undefined atom has been added in the last groupSize files, we
     // reiterate over the files.
-    if (undefinesAdded(groupSize))
-      _fileIndex -= groupSize;
-    _context.getInputGraph().skipGroup();
-    return nextFile(inGroup);
-  }
-  if (_fileIndex < _files.size()) {
-    // We are still in the current group.
-    inGroup = true;
-    return _files[_fileIndex++];
+    int size = group->getSize();
+    if (undefinesAdded(index - size, index)) {
+      index -= size;
+      ++groupLevel;
+      return getFile(index, groupLevel);
+    }
+    ++index;
+    --groupLevel;
+    return getFile(index, groupLevel);
   }
-  // We are not in a group. Get a new file.
-  File *file = _context.getInputGraph().getNextFile();
-  if (!file)
-    return nullptr;
-  _files.push_back(&*file);
-  ++_fileIndex;
-  inGroup = false;
-  return file;
+  return cast<FileNode>(inputs[index++].get())->getFile();
 }
 
 // Keep adding atoms until _context.getNextFile() returns an error. This
 // function is where undefined atoms are resolved.
 void Resolver::resolveUndefines() {
   ScopedTask task(getDefaultDomain(), "resolveUndefines");
-
+  int index = 0;
+  int groupLevel = 0;
   for (;;) {
-    bool inGroup = false;
     bool undefAdded = false;
-    File *file = nextFile(inGroup);
+    File *file = getFile(index, groupLevel);
     if (!file)
       return;
     switch (file->kind()) {
     case File::kindObject:
-      if (inGroup)
+      if (groupLevel > 0)
         break;
       assert(!file->hasOrdinal());
       file->setOrdinal(_context.getNextOrdinalAndIncrement());
@@ -293,7 +293,7 @@ void Resolver::resolveUndefines() {
       handleSharedLibrary(*file);
       break;
     }
-    _newUndefinesAdded[&*file] = undefAdded;
+    _newUndefinesAdded[file] = undefAdded;
   }
 }
 

Modified: lld/trunk/lib/Driver/Driver.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/Driver/Driver.cpp?rev=226132&r1=226131&r2=226132&view=diff
==============================================================================
--- lld/trunk/lib/Driver/Driver.cpp (original)
+++ lld/trunk/lib/Driver/Driver.cpp Thu Jan 15 00:49:21 2015
@@ -77,7 +77,6 @@ bool Driver::link(LinkingContext &contex
   InputGraph &inputGraph = context.getInputGraph();
   if (!inputGraph.size())
     return false;
-  inputGraph.normalize();
 
   bool fail = false;
 

Modified: lld/trunk/lib/Driver/GnuLdDriver.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/Driver/GnuLdDriver.cpp?rev=226132&r1=226131&r2=226132&view=diff
==============================================================================
--- lld/trunk/lib/Driver/GnuLdDriver.cpp (original)
+++ lld/trunk/lib/Driver/GnuLdDriver.cpp Thu Jan 15 00:49:21 2015
@@ -689,9 +689,6 @@ bool GnuLdDriver::parse(int argc, const
     }
   }
 
-  if (ctx->outputFileType() == LinkingContext::OutputFileType::YAML)
-    inputGraph->dump(diagnostics);
-
   // Validate the combination of options used.
   if (!ctx->validate(diagnostics))
     return false;

Modified: lld/trunk/lib/Driver/WinLinkDriver.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/Driver/WinLinkDriver.cpp?rev=226132&r1=226131&r2=226132&view=diff
==============================================================================
--- lld/trunk/lib/Driver/WinLinkDriver.cpp (original)
+++ lld/trunk/lib/Driver/WinLinkDriver.cpp Thu Jan 15 00:49:21 2015
@@ -1416,6 +1416,7 @@ bool WinLinkDriver::parse(int argc, cons
     if (isReadingDirectiveSection)
       if (file->parse())
         return false;
+    ctx.getResolvableSymsFile()->add(file.get());
     ctx.getInputGraph().addInputElement(
       std::unique_ptr<InputElement>(new WrapperNode(std::move(file))));
   }
@@ -1437,6 +1438,7 @@ bool WinLinkDriver::parse(int argc, cons
       if (isReadingDirectiveSection)
         if (file->parse())
           return false;
+      ctx.getResolvableSymsFile()->add(file.get());
       ctx.addLibraryFile(
 	std::unique_ptr<FileNode>(new WrapperNode(std::move(file))));
     }

Modified: lld/trunk/lib/ReaderWriter/MachO/MachOLinkingContext.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/MachO/MachOLinkingContext.cpp?rev=226132&r1=226131&r2=226132&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/MachO/MachOLinkingContext.cpp (original)
+++ lld/trunk/lib/ReaderWriter/MachO/MachOLinkingContext.cpp Thu Jan 15 00:49:21 2015
@@ -930,9 +930,7 @@ bool MachOLinkingContext::customAtomOrde
 
 static File *getFirstFile(const std::unique_ptr<InputElement> &elem) {
   FileNode *e = dyn_cast<FileNode>(const_cast<InputElement *>(elem.get()));
-  if (!e || e->files().empty())
-    return nullptr;
-  return e->files()[0].get();
+  return e ? e->getFile() : nullptr;
 }
 
 static bool isLibrary(const std::unique_ptr<InputElement> &elem) {

Modified: lld/trunk/lib/ReaderWriter/PECOFF/LinkerGeneratedSymbolFile.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/PECOFF/LinkerGeneratedSymbolFile.h?rev=226132&r1=226131&r2=226132&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/PECOFF/LinkerGeneratedSymbolFile.h (original)
+++ lld/trunk/lib/ReaderWriter/PECOFF/LinkerGeneratedSymbolFile.h Thu Jan 15 00:49:21 2015
@@ -174,45 +174,6 @@ private:
   mutable llvm::BumpPtrAllocator _alloc;
 };
 
-class ResolvableSymbols {
-public:
-  void add(File *file) {
-    std::lock_guard<std::mutex> lock(_mutex);
-    if (_seen.count(file) > 0)
-      return;
-    _seen.insert(file);
-    _queue.insert(file);
-  }
-
-  const std::set<std::string> &defined() {
-    readAllSymbols();
-    return _defined;
-  }
-
-private:
-  // Files are read lazily, so that it has no runtime overhead if
-  // no one accesses this class.
-  void readAllSymbols() {
-    std::lock_guard<std::mutex> lock(_mutex);
-    for (File *file : _queue) {
-      if (auto *archive = dyn_cast<ArchiveLibraryFile>(file)) {
-        for (const std::string &sym : archive->getDefinedSymbols())
-          _defined.insert(sym);
-        continue;
-      }
-      for (const DefinedAtom *atom : file->defined())
-        if (!atom->name().empty())
-          _defined.insert(atom->name());
-    }
-    _queue.clear();
-  }
-
-  std::set<std::string> _defined;
-  std::set<File *> _seen;
-  std::set<File *> _queue;
-  std::mutex _mutex;
-};
-
 // A ExportedSymbolRenameFile is a virtual archive file for dllexported symbols.
 //
 // One usually has to specify the exact symbol name to resolve it. That's true
@@ -246,7 +207,7 @@ private:
 class ExportedSymbolRenameFile : public impl::VirtualArchiveLibraryFile {
 public:
   ExportedSymbolRenameFile(const PECOFFLinkingContext &ctx,
-                           std::shared_ptr<ResolvableSymbols> syms)
+                           ResolvableSymbols *syms)
       : VirtualArchiveLibraryFile("<export>"), _syms(syms),
         _ctx(const_cast<PECOFFLinkingContext *>(&ctx)) {
     for (PECOFFLinkingContext::ExportDesc &desc : _ctx->getDllExports())
@@ -258,7 +219,7 @@ public:
     if (_exportedSyms.count(sym) == 0)
       return nullptr;
     std::string replace;
-    if (!findDecoratedSymbol(_ctx, _syms.get(), sym.str(), replace))
+    if (!findDecoratedSymbol(_ctx, _syms, sym.str(), replace))
       return nullptr;
 
     for (ExportDesc &exp : _ctx->getDllExports())
@@ -271,7 +232,7 @@ public:
 
 private:
   std::set<std::string> _exportedSyms;
-  std::shared_ptr<ResolvableSymbols> _syms;
+  ResolvableSymbols *_syms;
   mutable llvm::BumpPtrAllocator _alloc;
   mutable PECOFFLinkingContext *_ctx;
 };
@@ -284,7 +245,7 @@ private:
 class EntryPointFile : public SimpleFile {
 public:
   EntryPointFile(const PECOFFLinkingContext &ctx,
-                 std::shared_ptr<ResolvableSymbols> syms)
+                 ResolvableSymbols *syms)
       : SimpleFile("<entry>"), _ctx(const_cast<PECOFFLinkingContext *>(&ctx)),
         _syms(syms), _firstTime(true) {}
 
@@ -316,7 +277,7 @@ private:
     StringRef opt = _ctx->getEntrySymbolName();
     if (!opt.empty()) {
       std::string mangled;
-      if (findDecoratedSymbol(_ctx, _syms.get(), opt, mangled))
+      if (findDecoratedSymbol(_ctx, _syms, opt, mangled))
         return mangled;
       return _ctx->decorateSymbol(opt);
     }
@@ -341,7 +302,7 @@ private:
       if (_syms->defined().count(sym))
         return true;
       std::string ignore;
-      return findDecoratedSymbol(_ctx, _syms.get(), sym, ignore);
+      return findDecoratedSymbol(_ctx, _syms, sym, ignore);
     };
 
     switch (_ctx->getSubsystem()) {
@@ -372,7 +333,7 @@ private:
   PECOFFLinkingContext *_ctx;
   atom_collection_vector<UndefinedAtom> _undefinedAtoms;
   std::mutex _mutex;
-  std::shared_ptr<ResolvableSymbols> _syms;
+  ResolvableSymbols *_syms;
   llvm::BumpPtrAllocator _alloc;
   bool _firstTime;
 };

Modified: lld/trunk/lib/ReaderWriter/PECOFF/PECOFFLinkingContext.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/PECOFF/PECOFFLinkingContext.cpp?rev=226132&r1=226131&r2=226132&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/PECOFF/PECOFFLinkingContext.cpp (original)
+++ lld/trunk/lib/ReaderWriter/PECOFF/PECOFFLinkingContext.cpp Thu Jan 15 00:49:21 2015
@@ -118,9 +118,7 @@ bool PECOFFLinkingContext::createImplici
       llvm::make_unique<pecoff::LocallyImportedSymbolFile>(*this));
   getInputGraph().addInputElement(std::move(impFileNode));
 
-  std::shared_ptr<pecoff::ResolvableSymbols> syms(
-      new pecoff::ResolvableSymbols());
-  getInputGraph().registerObserver([=](File *file) { syms->add(file); });
+  pecoff::ResolvableSymbols* syms = getResolvableSymsFile();
 
   // Create a file for dllexported symbols.
   auto exportNode = llvm::make_unique<SimpleFileNode>("<export>");
@@ -331,4 +329,27 @@ void PECOFFLinkingContext::addPasses(Pas
   pm.add(std::unique_ptr<Pass>(new pecoff::InferSubsystemPass(*this)));
 }
 
+void pecoff::ResolvableSymbols::add(File *file) {
+  std::lock_guard<std::mutex> lock(_mutex);
+  if (_seen.count(file) > 0)
+    return;
+  _seen.insert(file);
+  _queue.insert(file);
+}
+
+void pecoff::ResolvableSymbols::readAllSymbols() {
+  std::lock_guard<std::mutex> lock(_mutex);
+  for (File *file : _queue) {
+    if (auto *archive = dyn_cast<ArchiveLibraryFile>(file)) {
+      for (const std::string &sym : archive->getDefinedSymbols())
+	_defined.insert(sym);
+      continue;
+    }
+    for (const DefinedAtom *atom : file->defined())
+      if (!atom->name().empty())
+	_defined.insert(atom->name());
+  }
+  _queue.clear();
+}
+
 } // end namespace lld

Modified: lld/trunk/unittests/DriverTests/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/unittests/DriverTests/CMakeLists.txt?rev=226132&r1=226131&r2=226132&view=diff
==============================================================================
--- lld/trunk/unittests/DriverTests/CMakeLists.txt (original)
+++ lld/trunk/unittests/DriverTests/CMakeLists.txt Thu Jan 15 00:49:21 2015
@@ -4,7 +4,6 @@ add_lld_unittest(DriverTests
   DarwinLdDriverTest.cpp
   WinLinkDriverTest.cpp
   WinLinkModuleDefTest.cpp
-  InputGraphTest.cpp
   )
 
 target_link_libraries(DriverTests

Removed: lld/trunk/unittests/DriverTests/InputGraphTest.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/unittests/DriverTests/InputGraphTest.cpp?rev=226131&view=auto
==============================================================================
--- lld/trunk/unittests/DriverTests/InputGraphTest.cpp (original)
+++ lld/trunk/unittests/DriverTests/InputGraphTest.cpp (removed)
@@ -1,122 +0,0 @@
-//===- lld/unittest/InputGraphTest.cpp -----------------------------------===//
-//
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-///
-/// \file
-/// \brief InputGraph Tests
-///
-//===----------------------------------------------------------------------===//
-
-#include "gtest/gtest.h"
-#include "lld/Core/InputGraph.h"
-#include "lld/Core/Resolver.h"
-#include "lld/Core/Simple.h"
-
-using namespace lld;
-
-namespace {
-
-class TestLinkingContext : public LinkingContext {
-public:
-  Writer &writer() const override { llvm_unreachable("no writer!"); }
-  bool validateImpl(raw_ostream &) override { return true; }
-};
-
-class TestExpandFileNode : public SimpleFileNode {
-public:
-  TestExpandFileNode(StringRef path) : SimpleFileNode(path) {}
-
-  /// Returns the elements replacing this node
-  bool getReplacements(InputGraph::InputElementVectorT &result) override {
-    for (std::unique_ptr<InputElement> &elt : _expandElements)
-      result.push_back(std::move(elt));
-    return true;
-  }
-
-  void addElement(std::unique_ptr<InputElement> element) {
-    _expandElements.push_back(std::move(element));
-  }
-
-private:
-  InputGraph::InputElementVectorT _expandElements;
-};
-
-class InputGraphTest : public testing::Test {
-public:
-  InputGraphTest() {
-    _ctx.setInputGraph(std::unique_ptr<InputGraph>(new InputGraph()));
-    _graph = &_ctx.getInputGraph();
-  }
-
-  StringRef getNext() {
-    File *file = _graph->getNextFile();
-    EXPECT_TRUE(file);
-    return file->path();
-  }
-
-  void expectEnd() {
-    File *file = _graph->getNextFile();
-    EXPECT_TRUE(file == nullptr);
-  }
-
-protected:
-  TestLinkingContext _ctx;
-  InputGraph *_graph;
-};
-
-} // end anonymous namespace
-
-static std::unique_ptr<SimpleFileNode> createFile(StringRef name) {
-  std::vector<std::unique_ptr<File>> files;
-  files.push_back(std::unique_ptr<SimpleFile>(new SimpleFile(name)));
-  std::unique_ptr<SimpleFileNode> file(new SimpleFileNode("filenode"));
-  file->addFiles(std::move(files));
-  return file;
-}
-
-TEST_F(InputGraphTest, Empty) {
-  expectEnd();
-}
-
-TEST_F(InputGraphTest, File) {
-  _graph->addInputElement(createFile("file1"));
-  EXPECT_EQ("file1", getNext());
-  expectEnd();
-}
-
-// Node expansion tests
-TEST_F(InputGraphTest, Normalize) {
-  _graph->addInputElement(createFile("file1"));
-
-  std::unique_ptr<TestExpandFileNode> expandFile(
-      new TestExpandFileNode("node"));
-  expandFile->addElement(createFile("file2"));
-  expandFile->addElement(createFile("file3"));
-  _graph->addInputElement(std::move(expandFile));
-  _graph->normalize();
-
-  EXPECT_EQ("file1", getNext());
-  EXPECT_EQ("file2", getNext());
-  EXPECT_EQ("file3", getNext());
-  expectEnd();
-}
-
-TEST_F(InputGraphTest, Observer) {
-  std::vector<std::string> files;
-  _graph->registerObserver([&](File *file) { files.push_back(file->path()); });
-
-  _graph->addInputElement(createFile("file1"));
-  _graph->addInputElement(createFile("file2"));
-  EXPECT_EQ("file1", getNext());
-  EXPECT_EQ("file2", getNext());
-  expectEnd();
-
-  EXPECT_EQ(2U, files.size());
-  EXPECT_EQ("file1", files[0]);
-  EXPECT_EQ("file2", files[1]);
-}





More information about the llvm-commits mailing list