mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2025-02-17 16:31:02 +00:00
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…
x
Reference in New Issue
Block a user