1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-11-24 03:33:20 +01:00
llvm-mirror/tools/llvm-link/llvm-link.cpp
Rafael Espindola 951d9d1379 Work around pr23045 and make it easier to reproduce.
Dropping old debug format requires the entire module to be read upfront.

This was failing only with the gold plugin, but that is just because
llvm-link was not upgrading metadata.

The new testcase using llvm-link shows the problem.

llvm-svn: 233381
2015-03-27 15:55:06 +00:00

158 lines
4.6 KiB
C++

//===- llvm-link.cpp - Low-level LLVM linker ------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This utility may be invoked in the following manner:
// llvm-link a.bc b.bc c.bc -o x.bc
//
//===----------------------------------------------------------------------===//
#include "llvm/Linker/Linker.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/Bitcode/ReaderWriter.h"
#include "llvm/IR/DiagnosticInfo.h"
#include "llvm/IR/DiagnosticPrinter.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/Module.h"
#include "llvm/IR/Verifier.h"
#include "llvm/IRReader/IRReader.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/ManagedStatic.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/PrettyStackTrace.h"
#include "llvm/Support/Signals.h"
#include "llvm/Support/SourceMgr.h"
#include "llvm/Support/SystemUtils.h"
#include "llvm/Support/ToolOutputFile.h"
#include <memory>
using namespace llvm;
static cl::list<std::string>
InputFilenames(cl::Positional, cl::OneOrMore,
cl::desc("<input bitcode files>"));
static cl::opt<std::string>
OutputFilename("o", cl::desc("Override output filename"), cl::init("-"),
cl::value_desc("filename"));
static cl::opt<bool>
Force("f", cl::desc("Enable binary output on terminals"));
static cl::opt<bool>
OutputAssembly("S",
cl::desc("Write output as LLVM assembly"), cl::Hidden);
static cl::opt<bool>
Verbose("v", cl::desc("Print information about actions taken"));
static cl::opt<bool>
DumpAsm("d", cl::desc("Print assembly as linked"), cl::Hidden);
static cl::opt<bool>
SuppressWarnings("suppress-warnings", cl::desc("Suppress all linking warnings"),
cl::init(false));
// Read the specified bitcode file in and return it. This routine searches the
// link path for the specified file to try to find it...
//
static std::unique_ptr<Module>
loadFile(const char *argv0, const std::string &FN, LLVMContext &Context) {
SMDiagnostic Err;
if (Verbose) errs() << "Loading '" << FN << "'\n";
std::unique_ptr<Module> Result = getLazyIRFileModule(FN, Err, Context);
if (!Result)
Err.print(argv0, errs());
// Fixme (pr23045). We would like to upgrade the metadata with something like
// Result->materializeMetadata();
// UpgradeDebugInfo(*Result);
// but that fails to drop old debug info from function bodies.
Result->materializeAllPermanently();
return Result;
}
static void diagnosticHandler(const DiagnosticInfo &DI) {
unsigned Severity = DI.getSeverity();
switch (Severity) {
case DS_Error:
errs() << "ERROR: ";
break;
case DS_Warning:
if (SuppressWarnings)
return;
errs() << "WARNING: ";
break;
case DS_Remark:
case DS_Note:
llvm_unreachable("Only expecting warnings and errors");
}
DiagnosticPrinterRawOStream DP(errs());
DI.print(DP);
errs() << '\n';
}
int main(int argc, char **argv) {
// Print a stack trace if we signal out.
sys::PrintStackTraceOnErrorSignal();
PrettyStackTraceProgram X(argc, argv);
LLVMContext &Context = getGlobalContext();
llvm_shutdown_obj Y; // Call llvm_shutdown() on exit.
cl::ParseCommandLineOptions(argc, argv, "llvm linker\n");
auto Composite = make_unique<Module>("llvm-link", Context);
Linker L(Composite.get(), diagnosticHandler);
for (unsigned i = 0; i < InputFilenames.size(); ++i) {
std::unique_ptr<Module> M = loadFile(argv[0], InputFilenames[i], Context);
if (!M.get()) {
errs() << argv[0] << ": error loading file '" <<InputFilenames[i]<< "'\n";
return 1;
}
if (verifyModule(*M)) {
errs() << argv[0] << ": input module '" << InputFilenames[i]
<< "' is broken!\n";
return 1;
}
if (Verbose) errs() << "Linking in '" << InputFilenames[i] << "'\n";
if (L.linkInModule(M.get()))
return 1;
}
if (DumpAsm) errs() << "Here's the assembly:\n" << *Composite;
std::error_code EC;
tool_output_file Out(OutputFilename, EC, sys::fs::F_None);
if (EC) {
errs() << EC.message() << '\n';
return 1;
}
if (verifyModule(*Composite)) {
errs() << argv[0] << ": linked module is broken!\n";
return 1;
}
if (Verbose) errs() << "Writing bitcode...\n";
if (OutputAssembly) {
Out.os() << *Composite;
} else if (Force || !CheckBitcodeOutputToConsole(Out.os(), true))
WriteBitcodeToFile(Composite.get(), Out.os());
// Declare success.
Out.keep();
return 0;
}