]>
Commit | Line | Data |
---|---|---|
223e47cc LB |
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 | ||
1a4d82fc | 15 | #include "llvm/Linker/Linker.h" |
223e47cc | 16 | #include "llvm/Bitcode/ReaderWriter.h" |
85aaf69f SL |
17 | #include "llvm/IR/DiagnosticInfo.h" |
18 | #include "llvm/IR/DiagnosticPrinter.h" | |
970d7e83 LB |
19 | #include "llvm/IR/LLVMContext.h" |
20 | #include "llvm/IR/Module.h" | |
1a4d82fc JJ |
21 | #include "llvm/IR/Verifier.h" |
22 | #include "llvm/IRReader/IRReader.h" | |
223e47cc | 23 | #include "llvm/Support/CommandLine.h" |
1a4d82fc | 24 | #include "llvm/Support/FileSystem.h" |
223e47cc | 25 | #include "llvm/Support/ManagedStatic.h" |
970d7e83 | 26 | #include "llvm/Support/Path.h" |
223e47cc | 27 | #include "llvm/Support/PrettyStackTrace.h" |
223e47cc | 28 | #include "llvm/Support/Signals.h" |
1a4d82fc | 29 | #include "llvm/Support/SourceMgr.h" |
970d7e83 LB |
30 | #include "llvm/Support/SystemUtils.h" |
31 | #include "llvm/Support/ToolOutputFile.h" | |
223e47cc LB |
32 | #include <memory> |
33 | using namespace llvm; | |
34 | ||
35 | static cl::list<std::string> | |
36 | InputFilenames(cl::Positional, cl::OneOrMore, | |
37 | cl::desc("<input bitcode files>")); | |
38 | ||
39 | static cl::opt<std::string> | |
40 | OutputFilename("o", cl::desc("Override output filename"), cl::init("-"), | |
41 | cl::value_desc("filename")); | |
42 | ||
43 | static cl::opt<bool> | |
44 | Force("f", cl::desc("Enable binary output on terminals")); | |
45 | ||
46 | static cl::opt<bool> | |
47 | OutputAssembly("S", | |
48 | cl::desc("Write output as LLVM assembly"), cl::Hidden); | |
49 | ||
50 | static cl::opt<bool> | |
51 | Verbose("v", cl::desc("Print information about actions taken")); | |
52 | ||
53 | static cl::opt<bool> | |
54 | DumpAsm("d", cl::desc("Print assembly as linked"), cl::Hidden); | |
55 | ||
1a4d82fc JJ |
56 | static cl::opt<bool> |
57 | SuppressWarnings("suppress-warnings", cl::desc("Suppress all linking warnings"), | |
58 | cl::init(false)); | |
223e47cc | 59 | |
1a4d82fc JJ |
60 | // Read the specified bitcode file in and return it. This routine searches the |
61 | // link path for the specified file to try to find it... | |
62 | // | |
63 | static std::unique_ptr<Module> | |
64 | loadFile(const char *argv0, const std::string &FN, LLVMContext &Context) { | |
223e47cc | 65 | SMDiagnostic Err; |
1a4d82fc | 66 | if (Verbose) errs() << "Loading '" << FN << "'\n"; |
85aaf69f | 67 | std::unique_ptr<Module> Result = getLazyIRFileModule(FN, Err, Context); |
1a4d82fc JJ |
68 | if (!Result) |
69 | Err.print(argv0, errs()); | |
70 | ||
71 | return Result; | |
223e47cc LB |
72 | } |
73 | ||
85aaf69f SL |
74 | static void diagnosticHandler(const DiagnosticInfo &DI) { |
75 | unsigned Severity = DI.getSeverity(); | |
76 | switch (Severity) { | |
77 | case DS_Error: | |
78 | errs() << "ERROR: "; | |
79 | break; | |
80 | case DS_Warning: | |
81 | if (SuppressWarnings) | |
82 | return; | |
83 | errs() << "WARNING: "; | |
84 | break; | |
85 | case DS_Remark: | |
86 | case DS_Note: | |
87 | llvm_unreachable("Only expecting warnings and errors"); | |
88 | } | |
89 | ||
90 | DiagnosticPrinterRawOStream DP(errs()); | |
91 | DI.print(DP); | |
92 | errs() << '\n'; | |
93 | } | |
94 | ||
223e47cc LB |
95 | int main(int argc, char **argv) { |
96 | // Print a stack trace if we signal out. | |
97 | sys::PrintStackTraceOnErrorSignal(); | |
98 | PrettyStackTraceProgram X(argc, argv); | |
1a4d82fc | 99 | |
223e47cc LB |
100 | LLVMContext &Context = getGlobalContext(); |
101 | llvm_shutdown_obj Y; // Call llvm_shutdown() on exit. | |
102 | cl::ParseCommandLineOptions(argc, argv, "llvm linker\n"); | |
103 | ||
85aaf69f SL |
104 | auto Composite = make_unique<Module>("llvm-link", Context); |
105 | Linker L(Composite.get(), diagnosticHandler); | |
223e47cc | 106 | |
85aaf69f | 107 | for (unsigned i = 0; i < InputFilenames.size(); ++i) { |
1a4d82fc JJ |
108 | std::unique_ptr<Module> M = loadFile(argv[0], InputFilenames[i], Context); |
109 | if (!M.get()) { | |
223e47cc LB |
110 | errs() << argv[0] << ": error loading file '" <<InputFilenames[i]<< "'\n"; |
111 | return 1; | |
112 | } | |
113 | ||
114 | if (Verbose) errs() << "Linking in '" << InputFilenames[i] << "'\n"; | |
115 | ||
85aaf69f | 116 | if (L.linkInModule(M.get())) |
223e47cc | 117 | return 1; |
223e47cc LB |
118 | } |
119 | ||
223e47cc LB |
120 | if (DumpAsm) errs() << "Here's the assembly:\n" << *Composite; |
121 | ||
1a4d82fc JJ |
122 | std::error_code EC; |
123 | tool_output_file Out(OutputFilename, EC, sys::fs::F_None); | |
124 | if (EC) { | |
125 | errs() << EC.message() << '\n'; | |
223e47cc LB |
126 | return 1; |
127 | } | |
128 | ||
129 | if (verifyModule(*Composite)) { | |
130 | errs() << argv[0] << ": linked module is broken!\n"; | |
131 | return 1; | |
132 | } | |
133 | ||
134 | if (Verbose) errs() << "Writing bitcode...\n"; | |
135 | if (OutputAssembly) { | |
136 | Out.os() << *Composite; | |
137 | } else if (Force || !CheckBitcodeOutputToConsole(Out.os(), true)) | |
138 | WriteBitcodeToFile(Composite.get(), Out.os()); | |
139 | ||
140 | // Declare success. | |
141 | Out.keep(); | |
142 | ||
143 | return 0; | |
144 | } |