forked from OSchip/llvm-project
Merge DarwinLdDriver and Driver.
Now that DarwinLdDriver is the only derived class of Driver. This patch merges them and actually removed the class because they can now just be non-member functions. This change simplifies a common header, Driver.h. http://reviews.llvm.org/D17788 llvm-svn: 262502
This commit is contained in:
parent
515025522b
commit
a453c0a5ad
|
@ -14,6 +14,7 @@
|
|||
#include "SymbolTable.h"
|
||||
#include "Symbols.h"
|
||||
#include "Writer.h"
|
||||
#include "lld/Driver/Driver.h"
|
||||
#include "llvm/ADT/Optional.h"
|
||||
#include "llvm/LibDriver/LibDriver.h"
|
||||
#include "llvm/Option/Arg.h"
|
||||
|
|
|
@ -34,9 +34,6 @@ using llvm::COFF::WindowsSubsystem;
|
|||
using llvm::Optional;
|
||||
class InputFile;
|
||||
|
||||
// Entry point of the COFF linker.
|
||||
bool link(llvm::ArrayRef<const char *> Args);
|
||||
|
||||
// Implemented in MarkLive.cpp.
|
||||
void markLive(const std::vector<Chunk *> &Chunks);
|
||||
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
#include "SymbolTable.h"
|
||||
#include "Target.h"
|
||||
#include "Writer.h"
|
||||
#include "lld/Driver/Driver.h"
|
||||
#include "llvm/ADT/StringExtras.h"
|
||||
#include "llvm/Support/TargetSelect.h"
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
|
|
|
@ -21,9 +21,6 @@ namespace elf {
|
|||
|
||||
extern class LinkerDriver *Driver;
|
||||
|
||||
// Entry point of the ELF linker. Returns true on success.
|
||||
bool link(ArrayRef<const char *> Args, llvm::raw_ostream &Error = llvm::errs());
|
||||
|
||||
class LinkerDriver {
|
||||
public:
|
||||
void main(ArrayRef<const char *> Args);
|
||||
|
|
|
@ -6,71 +6,27 @@
|
|||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
///
|
||||
/// \file
|
||||
///
|
||||
/// Interface for Drivers which convert command line arguments into
|
||||
/// LinkingContext objects, then perform the link.
|
||||
///
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLD_DRIVER_DRIVER_H
|
||||
#define LLD_DRIVER_DRIVER_H
|
||||
|
||||
#include "lld/Core/LLVM.h"
|
||||
#include "lld/Core/Node.h"
|
||||
#include "llvm/ADT/Triple.h"
|
||||
#include "llvm/ADT/ArrayRef.h"
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
#include <memory>
|
||||
#include <set>
|
||||
#include <vector>
|
||||
|
||||
namespace lld {
|
||||
class LinkingContext;
|
||||
class MachOLinkingContext;
|
||||
|
||||
/// Base class for all Drivers.
|
||||
class Driver {
|
||||
protected:
|
||||
|
||||
/// Performs link using specified options
|
||||
static bool link(LinkingContext &context,
|
||||
raw_ostream &diag = llvm::errs());
|
||||
|
||||
/// Parses the LLVM options from the context.
|
||||
static void parseLLVMOptions(const LinkingContext &context);
|
||||
|
||||
private:
|
||||
Driver() = delete;
|
||||
};
|
||||
|
||||
/// Driver for darwin/ld64 'ld' command line options.
|
||||
class DarwinLdDriver : public Driver {
|
||||
public:
|
||||
/// Parses command line arguments same as darwin's ld and performs link.
|
||||
/// Returns true iff there was an error.
|
||||
static bool linkMachO(llvm::ArrayRef<const char *> args,
|
||||
raw_ostream &diag = llvm::errs());
|
||||
|
||||
/// Uses darwin style ld command line options to update LinkingContext object.
|
||||
/// Returns true iff there was an error.
|
||||
static bool parse(llvm::ArrayRef<const char *> args,
|
||||
MachOLinkingContext &info,
|
||||
raw_ostream &diag = llvm::errs());
|
||||
|
||||
private:
|
||||
DarwinLdDriver() = delete;
|
||||
};
|
||||
|
||||
/// Driver for Windows 'link.exe' command line options
|
||||
namespace coff {
|
||||
bool link(llvm::ArrayRef<const char *> args);
|
||||
bool link(llvm::ArrayRef<const char *> Args);
|
||||
}
|
||||
|
||||
namespace elf {
|
||||
bool link(llvm::ArrayRef<const char *> args, raw_ostream &diag = llvm::errs());
|
||||
bool link(llvm::ArrayRef<const char *> Args,
|
||||
llvm::raw_ostream &Diag = llvm::errs());
|
||||
}
|
||||
|
||||
} // end namespace lld
|
||||
namespace mach_o {
|
||||
bool link(llvm::ArrayRef<const char *> Args,
|
||||
llvm::raw_ostream &Diag = llvm::errs());
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -4,7 +4,6 @@ add_public_tablegen_target(DriverOptionsTableGen)
|
|||
|
||||
add_lld_library(lldDriver
|
||||
DarwinLdDriver.cpp
|
||||
Driver.cpp
|
||||
|
||||
ADDITIONAL_HEADER_DIRS
|
||||
${LLD_INCLUDE_DIR}/lld/Driver
|
||||
|
|
|
@ -13,8 +13,11 @@
|
|||
///
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "lld/Core/File.h"
|
||||
#include "lld/Core/ArchiveLibraryFile.h"
|
||||
#include "lld/Core/File.h"
|
||||
#include "lld/Core/Instrumentation.h"
|
||||
#include "lld/Core/PassManager.h"
|
||||
#include "lld/Core/Resolver.h"
|
||||
#include "lld/Core/SharedLibraryFile.h"
|
||||
#include "lld/Driver/Driver.h"
|
||||
#include "lld/ReaderWriter/MachOLinkingContext.h"
|
||||
|
@ -276,20 +279,24 @@ static bool parseNumberBase16(StringRef numStr, uint64_t &baseAddress) {
|
|||
return numStr.getAsInteger(16, baseAddress);
|
||||
}
|
||||
|
||||
namespace lld {
|
||||
|
||||
bool DarwinLdDriver::linkMachO(llvm::ArrayRef<const char *> args,
|
||||
raw_ostream &diagnostics) {
|
||||
MachOLinkingContext ctx;
|
||||
if (!parse(args, ctx, diagnostics))
|
||||
return false;
|
||||
if (ctx.doNothing())
|
||||
return true;
|
||||
return link(ctx, diagnostics);
|
||||
static void parseLLVMOptions(const LinkingContext &ctx) {
|
||||
// Honor -mllvm
|
||||
if (!ctx.llvmOptions().empty()) {
|
||||
unsigned numArgs = ctx.llvmOptions().size();
|
||||
auto **args = new const char *[numArgs + 2];
|
||||
args[0] = "lld (LLVM option parsing)";
|
||||
for (unsigned i = 0; i != numArgs; ++i)
|
||||
args[i + 1] = ctx.llvmOptions()[i];
|
||||
args[numArgs + 1] = nullptr;
|
||||
llvm::cl::ParseCommandLineOptions(numArgs + 1, args);
|
||||
}
|
||||
}
|
||||
|
||||
bool DarwinLdDriver::parse(llvm::ArrayRef<const char *> args,
|
||||
MachOLinkingContext &ctx, raw_ostream &diagnostics) {
|
||||
namespace lld {
|
||||
namespace mach_o {
|
||||
|
||||
bool parse(llvm::ArrayRef<const char *> args, MachOLinkingContext &ctx,
|
||||
raw_ostream &diagnostics) {
|
||||
// Parse command line options using DarwinLdOptions.td
|
||||
DarwinLdOptTable table;
|
||||
unsigned missingIndex;
|
||||
|
@ -1124,5 +1131,68 @@ bool DarwinLdDriver::parse(llvm::ArrayRef<const char *> args,
|
|||
return ctx.validate(diagnostics);
|
||||
}
|
||||
|
||||
/// This is where the link is actually performed.
|
||||
bool link(llvm::ArrayRef<const char *> args, raw_ostream &diagnostics) {
|
||||
MachOLinkingContext ctx;
|
||||
if (!parse(args, ctx, diagnostics))
|
||||
return false;
|
||||
if (ctx.doNothing())
|
||||
return true;
|
||||
if (ctx.getNodes().empty())
|
||||
return false;
|
||||
|
||||
for (std::unique_ptr<Node> &ie : ctx.getNodes())
|
||||
if (FileNode *node = dyn_cast<FileNode>(ie.get()))
|
||||
node->getFile()->parse();
|
||||
|
||||
std::vector<std::unique_ptr<File>> internalFiles;
|
||||
ctx.createInternalFiles(internalFiles);
|
||||
for (auto i = internalFiles.rbegin(), e = internalFiles.rend(); i != e; ++i) {
|
||||
auto &members = ctx.getNodes();
|
||||
members.insert(members.begin(), llvm::make_unique<FileNode>(std::move(*i)));
|
||||
}
|
||||
|
||||
// Give target a chance to add files.
|
||||
std::vector<std::unique_ptr<File>> implicitFiles;
|
||||
ctx.createImplicitFiles(implicitFiles);
|
||||
for (auto i = implicitFiles.rbegin(), e = implicitFiles.rend(); i != e; ++i) {
|
||||
auto &members = ctx.getNodes();
|
||||
members.insert(members.begin(), llvm::make_unique<FileNode>(std::move(*i)));
|
||||
}
|
||||
|
||||
// Give target a chance to postprocess input files.
|
||||
// Mach-O uses this chance to move all object files before library files.
|
||||
ctx.finalizeInputFiles();
|
||||
|
||||
// Do core linking.
|
||||
ScopedTask resolveTask(getDefaultDomain(), "Resolve");
|
||||
Resolver resolver(ctx);
|
||||
if (!resolver.resolve())
|
||||
return false;
|
||||
std::unique_ptr<SimpleFile> merged = resolver.resultFile();
|
||||
resolveTask.end();
|
||||
|
||||
// Run passes on linked atoms.
|
||||
ScopedTask passTask(getDefaultDomain(), "Passes");
|
||||
PassManager pm;
|
||||
ctx.addPasses(pm);
|
||||
if (std::error_code ec = pm.runOnFile(*merged)) {
|
||||
diagnostics << "Failed to write file '" << ctx.outputPath()
|
||||
<< "': " << ec.message() << "\n";
|
||||
return false;
|
||||
}
|
||||
|
||||
passTask.end();
|
||||
|
||||
// Give linked atoms to Writer to generate output file.
|
||||
ScopedTask writeTask(getDefaultDomain(), "Write");
|
||||
if (std::error_code ec = ctx.writeFile(*merged)) {
|
||||
diagnostics << "Failed to write file '" << ctx.outputPath()
|
||||
<< "': " << ec.message() << "\n";
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
} // namespace mach_o
|
||||
} // namespace lld
|
||||
|
|
|
@ -1,104 +0,0 @@
|
|||
//===- lib/Driver/Driver.cpp - Linker Driver Emulator -----------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Linker
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "lld/Core/ArchiveLibraryFile.h"
|
||||
#include "lld/Core/File.h"
|
||||
#include "lld/Core/Instrumentation.h"
|
||||
#include "lld/Core/LLVM.h"
|
||||
#include "lld/Core/PassManager.h"
|
||||
#include "lld/Core/Reader.h"
|
||||
#include "lld/Core/Resolver.h"
|
||||
#include "lld/Core/Writer.h"
|
||||
#include "lld/Driver/Driver.h"
|
||||
#include "llvm/ADT/STLExtras.h"
|
||||
#include "llvm/ADT/StringExtras.h"
|
||||
#include "llvm/ADT/StringSwitch.h"
|
||||
#include "llvm/Option/Arg.h"
|
||||
#include "llvm/Support/CommandLine.h"
|
||||
#include "llvm/Support/FileSystem.h"
|
||||
#include "llvm/Support/Path.h"
|
||||
#include "llvm/Support/Process.h"
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
#include <mutex>
|
||||
|
||||
namespace lld {
|
||||
|
||||
void Driver::parseLLVMOptions(const LinkingContext &ctx) {
|
||||
// Honor -mllvm
|
||||
if (!ctx.llvmOptions().empty()) {
|
||||
unsigned numArgs = ctx.llvmOptions().size();
|
||||
auto **args = new const char *[numArgs + 2];
|
||||
args[0] = "lld (LLVM option parsing)";
|
||||
for (unsigned i = 0; i != numArgs; ++i)
|
||||
args[i + 1] = ctx.llvmOptions()[i];
|
||||
args[numArgs + 1] = nullptr;
|
||||
llvm::cl::ParseCommandLineOptions(numArgs + 1, args);
|
||||
}
|
||||
}
|
||||
|
||||
/// This is where the link is actually performed.
|
||||
bool Driver::link(LinkingContext &ctx, raw_ostream &diagnostics) {
|
||||
if (ctx.getNodes().empty())
|
||||
return false;
|
||||
|
||||
for (std::unique_ptr<Node> &ie : ctx.getNodes())
|
||||
if (FileNode *node = dyn_cast<FileNode>(ie.get()))
|
||||
node->getFile()->parse();
|
||||
|
||||
std::vector<std::unique_ptr<File>> internalFiles;
|
||||
ctx.createInternalFiles(internalFiles);
|
||||
for (auto i = internalFiles.rbegin(), e = internalFiles.rend(); i != e; ++i) {
|
||||
auto &members = ctx.getNodes();
|
||||
members.insert(members.begin(), llvm::make_unique<FileNode>(std::move(*i)));
|
||||
}
|
||||
|
||||
// Give target a chance to add files.
|
||||
std::vector<std::unique_ptr<File>> implicitFiles;
|
||||
ctx.createImplicitFiles(implicitFiles);
|
||||
for (auto i = implicitFiles.rbegin(), e = implicitFiles.rend(); i != e; ++i) {
|
||||
auto &members = ctx.getNodes();
|
||||
members.insert(members.begin(), llvm::make_unique<FileNode>(std::move(*i)));
|
||||
}
|
||||
|
||||
// Give target a chance to postprocess input files.
|
||||
// Mach-O uses this chance to move all object files before library files.
|
||||
ctx.finalizeInputFiles();
|
||||
|
||||
// Do core linking.
|
||||
ScopedTask resolveTask(getDefaultDomain(), "Resolve");
|
||||
Resolver resolver(ctx);
|
||||
if (!resolver.resolve())
|
||||
return false;
|
||||
std::unique_ptr<SimpleFile> merged = resolver.resultFile();
|
||||
resolveTask.end();
|
||||
|
||||
// Run passes on linked atoms.
|
||||
ScopedTask passTask(getDefaultDomain(), "Passes");
|
||||
PassManager pm;
|
||||
ctx.addPasses(pm);
|
||||
if (std::error_code ec = pm.runOnFile(*merged)) {
|
||||
diagnostics << "Failed to write file '" << ctx.outputPath()
|
||||
<< "': " << ec.message() << "\n";
|
||||
return false;
|
||||
}
|
||||
|
||||
passTask.end();
|
||||
|
||||
// Give linked atoms to Writer to generate output file.
|
||||
ScopedTask writeTask(getDefaultDomain(), "Write");
|
||||
if (std::error_code ec = ctx.writeFile(*merged)) {
|
||||
diagnostics << "Failed to write file '" << ctx.outputPath()
|
||||
<< "': " << ec.message() << "\n";
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace lld
|
|
@ -109,7 +109,7 @@ int main(int Argc, const char **Argv) {
|
|||
case WinLink:
|
||||
return !coff::link(Args);
|
||||
case Darwin:
|
||||
return !DarwinLdDriver::linkMachO(Args);
|
||||
return !mach_o::link(Args);
|
||||
default:
|
||||
die("-flavor option is missing. Available flavors are "
|
||||
"gnu, darwin or link.");
|
||||
|
|
|
@ -21,6 +21,13 @@
|
|||
using namespace llvm;
|
||||
using namespace lld;
|
||||
|
||||
namespace lld {
|
||||
namespace mach_o {
|
||||
bool parse(llvm::ArrayRef<const char *> args, MachOLinkingContext &ctx,
|
||||
raw_ostream &diagnostics);
|
||||
}
|
||||
}
|
||||
|
||||
namespace {
|
||||
class DarwinLdParserTest : public testing::Test {
|
||||
protected:
|
||||
|
@ -37,7 +44,7 @@ protected:
|
|||
args.insert(args.begin(), "ld");
|
||||
std::string errorMessage;
|
||||
raw_string_ostream os(errorMessage);
|
||||
return DarwinLdDriver::parse(args, _ctx, os);
|
||||
return mach_o::parse(args, _ctx, os);
|
||||
}
|
||||
|
||||
MachOLinkingContext _ctx;
|
||||
|
|
Loading…
Reference in New Issue