369f3477fe5c99434cd1ce74d1c3b40ba6cf7292
[oota-llvm.git] / tools / llvm-link / llvm-link.cpp
1 //===- llvm-link.cpp - Low-level LLVM linker ------------------------------===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This utility may be invoked in the following manner:
11 //  llvm-link a.bc b.bc c.bc -o x.bc
12 //
13 //===----------------------------------------------------------------------===//
14
15 #include "llvm/Linker/Linker.h"
16 #include "llvm/ADT/STLExtras.h"
17 #include "llvm/Bitcode/ReaderWriter.h"
18 #include "llvm/IR/AutoUpgrade.h"
19 #include "llvm/IR/DiagnosticInfo.h"
20 #include "llvm/IR/DiagnosticPrinter.h"
21 #include "llvm/IR/LLVMContext.h"
22 #include "llvm/IR/Module.h"
23 #include "llvm/IR/Verifier.h"
24 #include "llvm/IRReader/IRReader.h"
25 #include "llvm/Support/CommandLine.h"
26 #include "llvm/Support/FileSystem.h"
27 #include "llvm/Support/ManagedStatic.h"
28 #include "llvm/Support/Path.h"
29 #include "llvm/Support/PrettyStackTrace.h"
30 #include "llvm/Support/Signals.h"
31 #include "llvm/Support/SourceMgr.h"
32 #include "llvm/Support/SystemUtils.h"
33 #include "llvm/Support/ToolOutputFile.h"
34 #include <memory>
35 using namespace llvm;
36
37 static cl::list<std::string>
38 InputFilenames(cl::Positional, cl::OneOrMore,
39                cl::desc("<input bitcode files>"));
40
41 static cl::list<std::string> OverridingInputs(
42     "override", cl::ZeroOrMore, cl::value_desc("filename"),
43     cl::desc(
44         "input bitcode file which can override previously defined symbol(s)"));
45
46 static cl::opt<std::string>
47 OutputFilename("o", cl::desc("Override output filename"), cl::init("-"),
48                cl::value_desc("filename"));
49
50 static cl::opt<bool>
51 Force("f", cl::desc("Enable binary output on terminals"));
52
53 static cl::opt<bool>
54 OutputAssembly("S",
55          cl::desc("Write output as LLVM assembly"), cl::Hidden);
56
57 static cl::opt<bool>
58 Verbose("v", cl::desc("Print information about actions taken"));
59
60 static cl::opt<bool>
61 DumpAsm("d", cl::desc("Print assembly as linked"), cl::Hidden);
62
63 static cl::opt<bool>
64 SuppressWarnings("suppress-warnings", cl::desc("Suppress all linking warnings"),
65                  cl::init(false));
66
67 static cl::opt<bool> PreserveBitcodeUseListOrder(
68     "preserve-bc-uselistorder",
69     cl::desc("Preserve use-list order when writing LLVM bitcode."),
70     cl::init(true), cl::Hidden);
71
72 static cl::opt<bool> PreserveAssemblyUseListOrder(
73     "preserve-ll-uselistorder",
74     cl::desc("Preserve use-list order when writing LLVM assembly."),
75     cl::init(false), cl::Hidden);
76
77 // Read the specified bitcode file in and return it. This routine searches the
78 // link path for the specified file to try to find it...
79 //
80 static std::unique_ptr<Module>
81 loadFile(const char *argv0, const std::string &FN, LLVMContext &Context) {
82   SMDiagnostic Err;
83   if (Verbose) errs() << "Loading '" << FN << "'\n";
84   std::unique_ptr<Module> Result = getLazyIRFileModule(FN, Err, Context);
85   if (!Result)
86     Err.print(argv0, errs());
87
88   Result->materializeMetadata();
89   UpgradeDebugInfo(*Result);
90
91   return Result;
92 }
93
94 static void diagnosticHandler(const DiagnosticInfo &DI) {
95   unsigned Severity = DI.getSeverity();
96   switch (Severity) {
97   case DS_Error:
98     errs() << "ERROR: ";
99     break;
100   case DS_Warning:
101     if (SuppressWarnings)
102       return;
103     errs() << "WARNING: ";
104     break;
105   case DS_Remark:
106   case DS_Note:
107     llvm_unreachable("Only expecting warnings and errors");
108   }
109
110   DiagnosticPrinterRawOStream DP(errs());
111   DI.print(DP);
112   errs() << '\n';
113 }
114
115 static bool linkFiles(const char *argv0, LLVMContext &Context, Linker &L,
116                       const cl::list<std::string> &Files,
117                       bool OverrideDuplicateSymbols) {
118   for (const auto &File : Files) {
119     std::unique_ptr<Module> M = loadFile(argv0, File, Context);
120     if (!M.get()) {
121       errs() << argv0 << ": error loading file '" << File << "'\n";
122       return false;
123     }
124
125     if (verifyModule(*M, &errs())) {
126       errs() << argv0 << ": " << File << ": error: input module is broken!\n";
127       return false;
128     }
129
130     if (Verbose)
131       errs() << "Linking in '" << File << "'\n";
132
133     if (L.linkInModule(M.get(), OverrideDuplicateSymbols))
134       return false;
135   }
136
137   return true;
138 }
139
140 int main(int argc, char **argv) {
141   // Print a stack trace if we signal out.
142   sys::PrintStackTraceOnErrorSignal();
143   PrettyStackTraceProgram X(argc, argv);
144
145   LLVMContext &Context = getGlobalContext();
146   llvm_shutdown_obj Y;  // Call llvm_shutdown() on exit.
147   cl::ParseCommandLineOptions(argc, argv, "llvm linker\n");
148
149   auto Composite = make_unique<Module>("llvm-link", Context);
150   Linker L(Composite.get(), diagnosticHandler);
151
152   // First add all the regular input files
153   if (!linkFiles(argv[0], Context, L, InputFilenames, false))
154     return 1;
155
156   // Next the -override ones.
157   if (!linkFiles(argv[0], Context, L, OverridingInputs, true))
158     return 1;
159
160   if (DumpAsm) errs() << "Here's the assembly:\n" << *Composite;
161
162   std::error_code EC;
163   tool_output_file Out(OutputFilename, EC, sys::fs::F_None);
164   if (EC) {
165     errs() << EC.message() << '\n';
166     return 1;
167   }
168
169   if (verifyModule(*Composite, &errs())) {
170     errs() << argv[0] << ": error: linked module is broken!\n";
171     return 1;
172   }
173
174   if (Verbose) errs() << "Writing bitcode...\n";
175   if (OutputAssembly) {
176     Composite->print(Out.os(), nullptr, PreserveAssemblyUseListOrder);
177   } else if (Force || !CheckBitcodeOutputToConsole(Out.os(), true))
178     WriteBitcodeToFile(Composite.get(), Out.os(), PreserveBitcodeUseListOrder);
179
180   // Declare success.
181   Out.keep();
182
183   return 0;
184 }