blob: e0ad6a3c95027b9d6f39f89977f034d136fc1613 [file] [log] [blame]
Peter Collingbourned5395fb2012-01-08 22:09:58 +00001#include "llvm/ADT/OwningPtr.h"
2#include "llvm/Bitcode/ReaderWriter.h"
Tom Stellard976577e2013-06-26 18:20:32 +00003#include "llvm/IR/Function.h"
4#include "llvm/IR/GlobalVariable.h"
5#include "llvm/IR/LLVMContext.h"
6#include "llvm/IR/Module.h"
Peter Collingbourned5395fb2012-01-08 22:09:58 +00007#include "llvm/Support/CommandLine.h"
8#include "llvm/Support/ManagedStatic.h"
9#include "llvm/Support/MemoryBuffer.h"
Tom Stellard98dccb12014-04-30 18:35:20 +000010#include "llvm/Support/FileSystem.h"
Peter Collingbourned5395fb2012-01-08 22:09:58 +000011#include "llvm/Support/raw_ostream.h"
12#include "llvm/Support/system_error.h"
Tom Stellard8a63b152014-01-20 20:28:48 +000013#include "llvm/Support/ErrorOr.h"
Peter Collingbourned5395fb2012-01-08 22:09:58 +000014#include "llvm/Support/ToolOutputFile.h"
Aaron Watry0da3d3b52013-07-18 21:24:35 +000015#include "llvm/Config/config.h"
Peter Collingbourned5395fb2012-01-08 22:09:58 +000016
17using namespace llvm;
18
19static cl::opt<std::string>
20InputFilename(cl::Positional, cl::desc("<input bitcode>"), cl::init("-"));
21
22static cl::opt<std::string>
23OutputFilename("o", cl::desc("Output filename"),
24 cl::value_desc("filename"));
25
26int main(int argc, char **argv) {
27 LLVMContext &Context = getGlobalContext();
28 llvm_shutdown_obj Y; // Call llvm_shutdown() on exit.
29
30 cl::ParseCommandLineOptions(argc, argv, "libclc builtin preparation tool\n");
31
32 std::string ErrorMessage;
33 std::auto_ptr<Module> M;
34
35 {
36 OwningPtr<MemoryBuffer> BufferPtr;
37 if (error_code ec = MemoryBuffer::getFileOrSTDIN(InputFilename, BufferPtr))
38 ErrorMessage = ec.message();
Tom Stellard8a63b152014-01-20 20:28:48 +000039 else {
40#if LLVM_VERSION_MAJOR > 3 || (LLVM_VERSION_MAJOR == 3 && LLVM_VERSION_MINOR > 4)
41 ErrorOr<Module *> ModuleOrErr = parseBitcodeFile(BufferPtr.get(), Context);
42 if (error_code ec = ModuleOrErr.getError())
43 ErrorMessage = ec.message();
44 M.reset(ModuleOrErr.get());
45#else
Peter Collingbourned5395fb2012-01-08 22:09:58 +000046 M.reset(ParseBitcodeFile(BufferPtr.get(), Context, &ErrorMessage));
Tom Stellard8a63b152014-01-20 20:28:48 +000047#endif
48 }
Peter Collingbourned5395fb2012-01-08 22:09:58 +000049 }
50
51 if (M.get() == 0) {
52 errs() << argv[0] << ": ";
53 if (ErrorMessage.size())
54 errs() << ErrorMessage << "\n";
55 else
56 errs() << "bitcode didn't read correctly.\n";
57 return 1;
58 }
59
60 // Set linkage of every external definition to linkonce_odr.
61 for (Module::iterator i = M->begin(), e = M->end(); i != e; ++i) {
62 if (!i->isDeclaration() && i->getLinkage() == GlobalValue::ExternalLinkage)
63 i->setLinkage(GlobalValue::LinkOnceODRLinkage);
64 }
65
66 for (Module::global_iterator i = M->global_begin(), e = M->global_end();
67 i != e; ++i) {
68 if (!i->isDeclaration() && i->getLinkage() == GlobalValue::ExternalLinkage)
69 i->setLinkage(GlobalValue::LinkOnceODRLinkage);
70 }
71
72 if (OutputFilename.empty()) {
73 errs() << "no output file\n";
74 return 1;
75 }
76
77 std::string ErrorInfo;
78 OwningPtr<tool_output_file> Out
79 (new tool_output_file(OutputFilename.c_str(), ErrorInfo,
Tom Stellard7aee1cf2014-02-24 21:31:56 +000080#if (LLVM_VERSION_MAJOR == 3 && LLVM_VERSION_MINOR == 4)
Aaron Watry0da3d3b52013-07-18 21:24:35 +000081 sys::fs::F_Binary));
Tom Stellard7aee1cf2014-02-24 21:31:56 +000082#elif LLVM_VERSION_MAJOR > 3 || (LLVM_VERSION_MAJOR == 3 && LLVM_VERSION_MINOR >= 5)
83 sys::fs::F_None));
Aaron Watry0da3d3b52013-07-18 21:24:35 +000084#else
Peter Collingbourned5395fb2012-01-08 22:09:58 +000085 raw_fd_ostream::F_Binary));
Aaron Watry0da3d3b52013-07-18 21:24:35 +000086#endif
Peter Collingbourned5395fb2012-01-08 22:09:58 +000087 if (!ErrorInfo.empty()) {
88 errs() << ErrorInfo << '\n';
89 exit(1);
90 }
91
92 WriteBitcodeToFile(M.get(), Out->os());
93
94 // Declare success.
95 Out->keep();
96 return 0;
97}
98