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.

llvm-svn: 226132
diff --git a/lld/lib/Core/Resolver.cpp b/lld/lib/Core/Resolver.cpp
index 90d141b..49d3f61 100644
--- a/lld/lib/Core/Resolver.cpp
+++ b/lld/lib/Core/Resolver.cpp
@@ -231,52 +231,52 @@
 
 // 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);
+    int size = group->getSize();
+    if (undefinesAdded(index - size, index)) {
+      index -= size;
+      ++groupLevel;
+      return getFile(index, groupLevel);
+    }
+    ++index;
+    --groupLevel;
+    return getFile(index, groupLevel);
   }
-  if (_fileIndex < _files.size()) {
-    // We are still in the current group.
-    inGroup = true;
-    return _files[_fileIndex++];
-  }
-  // 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 @@
       handleSharedLibrary(*file);
       break;
     }
-    _newUndefinesAdded[&*file] = undefAdded;
+    _newUndefinesAdded[file] = undefAdded;
   }
 }