aboutsummaryrefslogtreecommitdiff
path: root/lib/Driver/Driver.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Driver/Driver.cpp')
-rw-r--r--lib/Driver/Driver.cpp82
1 files changed, 47 insertions, 35 deletions
diff --git a/lib/Driver/Driver.cpp b/lib/Driver/Driver.cpp
index d32bfa6e47be..6a7a26b3b0f6 100644
--- a/lib/Driver/Driver.cpp
+++ b/lib/Driver/Driver.cpp
@@ -1,4 +1,4 @@
-//===- lib/Driver/Driver.cpp - Linker Driver Emulator ---------------------===//
+//===- lib/Driver/Driver.cpp - Linker Driver Emulator -----------*- C++ -*-===//
//
// The LLVM Linker
//
@@ -36,15 +36,13 @@ FileVector makeErrorFile(StringRef path, std::error_code ec) {
return result;
}
-FileVector parseMemberFiles(FileVector &files) {
+FileVector parseMemberFiles(std::unique_ptr<File> file) {
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));
- }
+ 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;
}
@@ -54,72 +52,86 @@ FileVector loadFile(LinkingContext &ctx, StringRef path, bool wholeArchive) {
= 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().loadFile(std::move(mb.get()), files))
+ ErrorOr<std::unique_ptr<File>> fileOrErr =
+ ctx.registry().loadFile(std::move(mb.get()));
+ if (std::error_code ec = fileOrErr.getError())
return makeErrorFile(path, ec);
+ std::unique_ptr<File> &file = fileOrErr.get();
if (wholeArchive)
- return parseMemberFiles(files);
+ return parseMemberFiles(std::move(file));
+ std::vector<std::unique_ptr<File>> files;
+ files.push_back(std::move(file));
return files;
}
-/// This is where the link is actually performed.
-bool Driver::link(LinkingContext &context, raw_ostream &diagnostics) {
+void Driver::parseLLVMOptions(const LinkingContext &ctx) {
// Honor -mllvm
- if (!context.llvmOptions().empty()) {
- unsigned numArgs = context.llvmOptions().size();
- const char **args = new const char *[numArgs + 2];
+ 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] = context.llvmOptions()[i];
- args[numArgs + 1] = 0;
+ args[i + 1] = ctx.llvmOptions()[i];
+ args[numArgs + 1] = nullptr;
llvm::cl::ParseCommandLineOptions(numArgs + 1, args);
}
- if (context.getNodes().empty())
+}
+
+/// 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 : context.getNodes())
+ for (std::unique_ptr<Node> &ie : ctx.getNodes())
if (FileNode *node = dyn_cast<FileNode>(ie.get()))
- context.getTaskGroup().spawn([node] { node->getFile()->parse(); });
+ ctx.getTaskGroup().spawn([node] { node->getFile()->parse(); });
std::vector<std::unique_ptr<File>> internalFiles;
- context.createInternalFiles(internalFiles);
+ ctx.createInternalFiles(internalFiles);
for (auto i = internalFiles.rbegin(), e = internalFiles.rend(); i != e; ++i) {
- auto &members = context.getNodes();
+ 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;
- context.createImplicitFiles(implicitFiles);
+ ctx.createImplicitFiles(implicitFiles);
for (auto i = implicitFiles.rbegin(), e = implicitFiles.rend(); i != e; ++i) {
- auto &members = context.getNodes();
+ 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.
// ELF adds specific undefined symbols resolver.
- context.finalizeInputFiles();
+ ctx.finalizeInputFiles();
// Do core linking.
ScopedTask resolveTask(getDefaultDomain(), "Resolve");
- Resolver resolver(context);
- if (!resolver.resolve())
+ Resolver resolver(ctx);
+ if (!resolver.resolve()) {
+ ctx.getTaskGroup().sync();
return false;
- std::unique_ptr<MutableFile> merged = resolver.resultFile();
+ }
+ std::unique_ptr<SimpleFile> merged = resolver.resultFile();
resolveTask.end();
// Run passes on linked atoms.
ScopedTask passTask(getDefaultDomain(), "Passes");
PassManager pm;
- context.addPasses(pm);
- pm.runOnFile(merged);
+ 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 = context.writeFile(*merged)) {
- diagnostics << "Failed to write file '" << context.outputPath()
+ if (std::error_code ec = ctx.writeFile(*merged)) {
+ diagnostics << "Failed to write file '" << ctx.outputPath()
<< "': " << ec.message() << "\n";
return false;
}
@@ -127,4 +139,4 @@ bool Driver::link(LinkingContext &context, raw_ostream &diagnostics) {
return true;
}
-} // namespace
+} // namespace lld