[lld] r225313 - Convert CoreInputGraph.

Rui Ueyama ruiu at google.com
Tue Jan 6 15:06:50 PST 2015


Author: ruiu
Date: Tue Jan  6 17:06:49 2015
New Revision: 225313

URL: http://llvm.org/viewvc/llvm-project?rev=225313&view=rev
Log:
Convert CoreInputGraph.

This is a part of InputGraph cleanup to represent input files as a flat
list of Files (and some meta-nodes for group etc.)

We cannot achieve that goal in one gigantic patch, so I split the task
into small steps as shown below.

(Recap the progress so far: Currently InputGraph contains a list of
InputElements. Each InputElement contain one File (that used to have
multiple Files, but I eliminated that use case in r223867). Files are
currently instantiated in Driver::link(), but I already made a change
to separate file parsing from object instantiation (r224102), so we
can safely instantiate Files when we need them, instead of wrapping
a file with the wrapper class (FileNode class). InputGraph used to
act like a generator class by interpreting groups by itself, but it's
now just a container of a list of InputElements (r223867).)

1. Instantiate Files in the driver and wrap them with WrapperNode.
WrapperNode is a temporary class that allows us to instantiate Files
in the driver while keep using the current InputGraph data structure.

This patch demonstrates how this step 1 looks like, using Core driver
as an example.

2. Do the same thing for the other drivers.

When step 2 is done, an InputGraph consists of GroupEnd objects or
WrapperNodes each of which contains one File. Other types of
FileNode subclasses are removed.

3. Replace InputGraph with std::vector<std::unique_ptr<InputElement>>.
InputGraph is already just a container of list of InputElements,
so this step removes that needless class.

4. Remove WrapperNode.

We need some code cleanup between each step, because many classes
do a bit odd things (e.g. InputGraph::getGroupSize()). I'll straight
things up as I need to.

Added:
    lld/trunk/include/lld/Driver/WrapperInputGraph.h
Removed:
    lld/trunk/include/lld/Driver/CoreInputGraph.h
    lld/trunk/test/core/empty.objtxt
Modified:
    lld/trunk/include/lld/Core/File.h
    lld/trunk/include/lld/Core/InputGraph.h
    lld/trunk/include/lld/Driver/Driver.h
    lld/trunk/lib/Core/InputGraph.cpp
    lld/trunk/lib/Driver/CoreDriver.cpp
    lld/trunk/lib/Driver/Driver.cpp

Modified: lld/trunk/include/lld/Core/File.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/include/lld/Core/File.h?rev=225313&r1=225312&r2=225313&view=diff
==============================================================================
--- lld/trunk/include/lld/Core/File.h (original)
+++ lld/trunk/include/lld/Core/File.h Tue Jan  6 17:06:49 2015
@@ -16,6 +16,7 @@
 #include "lld/Core/UndefinedAtom.h"
 #include "lld/Core/range.h"
 #include "llvm/ADT/Optional.h"
+#include "llvm/ADT/Twine.h"
 #include "llvm/Support/ErrorHandling.h"
 #include <functional>
 #include <memory>
@@ -265,6 +266,35 @@ protected:
   /// \brief only subclasses of MutableFile can be instantiated
   MutableFile(StringRef p) : File(p, kindObject) {}
 };
+
+/// An ErrorFile represents a file that doesn't exist.
+/// If you try to parse a file which doesn't exist, an instance of this
+/// class will be returned. That's parse method always returns an error.
+/// This is useful to delay erroring on non-existent files, so that we
+/// can do unit testing a driver using non-existing file paths.
+class ErrorFile : public File {
+public:
+  ErrorFile(StringRef p, std::error_code ec) : File(p, kindObject), _ec(ec) {}
+
+  std::error_code doParse() override { return _ec; }
+
+  const atom_collection<DefinedAtom> &defined() const override {
+    llvm_unreachable("internal error");
+  }
+  const atom_collection<UndefinedAtom> &undefined() const override {
+    llvm_unreachable("internal error");
+  }
+  const atom_collection<SharedLibraryAtom> &sharedLibrary() const override {
+    llvm_unreachable("internal error");
+  }
+  const atom_collection<AbsoluteAtom> &absolute() const override {
+    llvm_unreachable("internal error");
+  }
+
+private:
+  std::error_code _ec;
+};
+
 } // end namespace lld
 
 #endif

Modified: lld/trunk/include/lld/Core/InputGraph.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/include/lld/Core/InputGraph.h?rev=225313&r1=225312&r2=225313&view=diff
==============================================================================
--- lld/trunk/include/lld/Core/InputGraph.h (original)
+++ lld/trunk/include/lld/Core/InputGraph.h Tue Jan  6 17:06:49 2015
@@ -208,6 +208,8 @@ public:
     return _files[_nextFileIndex++].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
@@ -231,12 +233,8 @@ public:
   virtual void appendInputFile(std::unique_ptr<File> f) {
     _files.push_back(std::move(f));
   }
-
-  /// \brief parse the input element
-  std::error_code parse(const LinkingContext &, raw_ostream &) override {
-    return std::error_code();
-  }
 };
+
 } // namespace lld
 
 #endif // LLD_CORE_INPUT_GRAPH_H

Removed: lld/trunk/include/lld/Driver/CoreInputGraph.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/include/lld/Driver/CoreInputGraph.h?rev=225312&view=auto
==============================================================================
--- lld/trunk/include/lld/Driver/CoreInputGraph.h (original)
+++ lld/trunk/include/lld/Driver/CoreInputGraph.h (removed)
@@ -1,53 +0,0 @@
-//===- lld/Driver/CoreInputGraph.h - Input Graph Node for Core linker -----===//
-//
-//                             The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-///
-/// \file
-///
-/// Handles Options for CORE linking and provides InputElements
-/// for the CORE linker
-///
-//===----------------------------------------------------------------------===//
-
-#ifndef LLD_DRIVER_CORE_INPUT_GRAPH_H
-#define LLD_DRIVER_CORE_INPUT_GRAPH_H
-
-#include "lld/Core/InputGraph.h"
-#include "lld/ReaderWriter/CoreLinkingContext.h"
-#include "lld/ReaderWriter/Reader.h"
-#include "llvm/Support/Errc.h"
-#include <map>
-#include <memory>
-
-namespace lld {
-
-/// \brief Represents a Core File
-class CoreFileNode : public FileNode {
-public:
-  CoreFileNode(CoreLinkingContext &, StringRef path) : FileNode(path) {}
-
-  /// \brief Parse the input file to lld::File.
-  std::error_code parse(const LinkingContext &ctx,
-                        raw_ostream &diagnostics) override {
-    ErrorOr<StringRef> filePath = getPath(ctx);
-    if (filePath.getError() == llvm::errc::no_such_file_or_directory)
-      return make_error_code(llvm::errc::no_such_file_or_directory);
-
-    // Create a memory buffer
-    ErrorOr<std::unique_ptr<MemoryBuffer>> mb =
-        MemoryBuffer::getFileOrSTDIN(*filePath);
-    if (std::error_code ec = mb.getError())
-      return ec;
-
-    return ctx.registry().parseFile(std::move(mb.get()), _files);
-  }
-};
-
-} // namespace lld
-
-#endif

Modified: lld/trunk/include/lld/Driver/Driver.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/include/lld/Driver/Driver.h?rev=225313&r1=225312&r2=225313&view=diff
==============================================================================
--- lld/trunk/include/lld/Driver/Driver.h (original)
+++ lld/trunk/include/lld/Driver/Driver.h Tue Jan  6 17:06:49 2015
@@ -32,6 +32,12 @@ class MachOLinkingContext;
 class PECOFFLinkingContext;
 class ELFLinkingContext;
 
+typedef std::vector<std::unique_ptr<File>> FileVector;
+
+FileVector makeErrorFile(StringRef path, std::error_code ec);
+FileVector parseMemberFiles(FileVector &files);
+FileVector parseFile(LinkingContext &ctx, StringRef path, bool wholeArchive);
+
 /// Base class for all Drivers.
 class Driver {
 protected:

Added: lld/trunk/include/lld/Driver/WrapperInputGraph.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/include/lld/Driver/WrapperInputGraph.h?rev=225313&view=auto
==============================================================================
--- lld/trunk/include/lld/Driver/WrapperInputGraph.h (added)
+++ lld/trunk/include/lld/Driver/WrapperInputGraph.h Tue Jan  6 17:06:49 2015
@@ -0,0 +1,31 @@
+//===- lld/Driver/WrapperInputGraph.h - dummy InputGraph node -------------===//
+//
+//                             The LLVM Linker
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLD_DRIVER_WRAPPER_INPUT_GRAPH_H
+#define LLD_DRIVER_WRAPPER_INPUT_GRAPH_H
+
+#include "lld/Core/InputGraph.h"
+#include "lld/ReaderWriter/CoreLinkingContext.h"
+#include "lld/ReaderWriter/Reader.h"
+#include "llvm/Support/Errc.h"
+#include <map>
+#include <memory>
+
+namespace lld {
+
+class WrapperNode : public FileNode {
+public:
+  WrapperNode(std::unique_ptr<File> file) : FileNode(file->path()) {
+    _files.push_back(std::move(file));
+  }
+};
+
+}
+
+#endif

Modified: lld/trunk/lib/Core/InputGraph.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/Core/InputGraph.cpp?rev=225313&r1=225312&r2=225313&view=diff
==============================================================================
--- lld/trunk/lib/Core/InputGraph.cpp (original)
+++ lld/trunk/lib/Core/InputGraph.cpp Tue Jan  6 17:06:49 2015
@@ -101,3 +101,10 @@ bool FileNode::getReplacements(InputGrap
     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())
+      return ec;
+  return std::error_code();
+}

Modified: lld/trunk/lib/Driver/CoreDriver.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/Driver/CoreDriver.cpp?rev=225313&r1=225312&r2=225313&view=diff
==============================================================================
--- lld/trunk/lib/Driver/CoreDriver.cpp (original)
+++ lld/trunk/lib/Driver/CoreDriver.cpp Tue Jan  6 17:06:49 2015
@@ -8,7 +8,7 @@
 //===----------------------------------------------------------------------===//
 
 #include "lld/Driver/Driver.h"
-#include "lld/Driver/CoreInputGraph.h"
+#include "lld/Driver/WrapperInputGraph.h"
 #include "lld/ReaderWriter/CoreLinkingContext.h"
 #include "lld/ReaderWriter/Reader.h"
 #include "llvm/ADT/ArrayRef.h"
@@ -76,16 +76,15 @@ static const Registry::KindStrings coreK
 
 bool CoreDriver::link(int argc, const char *argv[], raw_ostream &diagnostics) {
   CoreLinkingContext ctx;
-  if (!parse(argc, argv, ctx))
-    return false;
 
   // Register possible input file parsers.
   ctx.registry().addSupportNativeObjects();
   ctx.registry().addSupportYamlFiles();
-
   ctx.registry().addKindTable(Reference::KindNamespace::testing,
                               Reference::KindArch::all, coreKindStrings);
 
+  if (!parse(argc, argv, ctx))
+    return false;
   return Driver::link(ctx);
 }
 
@@ -151,10 +150,15 @@ bool CoreDriver::parse(int argc, const c
       ctx.addPassNamed(inputArg->getValue());
       break;
 
-    case OPT_INPUT:
-      inputGraph->addInputElement(std::unique_ptr<InputElement>(
-          new CoreFileNode(ctx, inputArg->getValue())));
+    case OPT_INPUT: {
+      std::vector<std::unique_ptr<File>> files
+        = parseFile(ctx, inputArg->getValue(), false);
+      for (std::unique_ptr<File> &file : files) {
+        inputGraph->addInputElement(std::unique_ptr<InputElement>(
+            new WrapperNode(std::move(file))));
+      }
       break;
+    }
 
     default:
       break;

Modified: lld/trunk/lib/Driver/Driver.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/Driver/Driver.cpp?rev=225313&r1=225312&r2=225313&view=diff
==============================================================================
--- lld/trunk/lib/Driver/Driver.cpp (original)
+++ lld/trunk/lib/Driver/Driver.cpp Tue Jan  6 17:06:49 2015
@@ -8,6 +8,8 @@
 //===----------------------------------------------------------------------===//
 
 #include "lld/Driver/Driver.h"
+#include "lld/Core/ArchiveLibraryFile.h"
+#include "lld/Core/File.h"
 #include "lld/Core/Instrumentation.h"
 #include "lld/Core/LLVM.h"
 #include "lld/Core/Parallel.h"
@@ -28,6 +30,38 @@
 
 namespace lld {
 
+FileVector makeErrorFile(StringRef path, std::error_code ec) {
+  std::vector<std::unique_ptr<File>> result;
+  result.push_back(llvm::make_unique<ErrorFile>(path, ec));
+  return result;
+}
+
+FileVector parseMemberFiles(FileVector &files) {
+  std::vector<std::unique_ptr<File>> members;
+  for (std::unique_ptr<File> &file : files) {
+    if (auto *archive = dyn_cast<ArchiveLibraryFile>(file.get())) {
+      if (std::error_code ec = archive->parseAllMembers(members))
+        return makeErrorFile(file->path(), ec);
+    } else {
+      members.push_back(std::move(file));
+    }
+  }
+  return members;
+}
+
+FileVector parseFile(LinkingContext &ctx, StringRef path, bool wholeArchive) {
+  ErrorOr<std::unique_ptr<MemoryBuffer>> mb
+      = MemoryBuffer::getFileOrSTDIN(path);
+  if (std::error_code ec = mb.getError())
+    return makeErrorFile(path, ec);
+  std::vector<std::unique_ptr<File>> files;
+  if (std::error_code ec = ctx.registry().parseFile(std::move(mb.get()), files))
+    return makeErrorFile(path, ec);
+  if (wholeArchive)
+    return parseMemberFiles(files);
+  return files;
+}
+
 /// This is where the link is actually performed.
 bool Driver::link(LinkingContext &context, raw_ostream &diagnostics) {
   // Honor -mllvm

Removed: lld/trunk/test/core/empty.objtxt
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/core/empty.objtxt?rev=225312&view=auto
==============================================================================
--- lld/trunk/test/core/empty.objtxt (original)
+++ lld/trunk/test/core/empty.objtxt (removed)
@@ -1,11 +0,0 @@
-# RUN: lld -core %s | FileCheck %s
-
-#
-# Test that an empty file is handled properly
-#
-
----
-...
-
-# CHECK:       ---
-# CHECK:       ...





More information about the llvm-commits mailing list