1 #include "llvm/Bitcode/ReaderWriter.h"
2 #include "llvm/IR/Function.h"
3 #include "llvm/IR/GlobalVariable.h"
4 #include "llvm/IR/LLVMContext.h"
5 #include "llvm/IR/Module.h"
6 #include "llvm/Support/CommandLine.h"
7 #include "llvm/Support/ManagedStatic.h"
8 #include "llvm/Support/MemoryBuffer.h"
9 #include "llvm/Support/FileSystem.h"
10 #include "llvm/Support/raw_ostream.h"
11 #include "llvm/Support/ErrorOr.h"
12 #include "llvm/Support/ToolOutputFile.h"
13 #include "llvm/Config/config.h"
14 
15 #define LLVM_350_AND_NEWER \
16   (LLVM_VERSION_MAJOR > 3 || (LLVM_VERSION_MAJOR == 3 && LLVM_VERSION_MINOR >= 5))
17 
18 #if LLVM_350_AND_NEWER
19 #include <system_error>
20 
21 #define ERROR_CODE std::error_code
22 #define UNIQUE_PTR std::unique_ptr
23 #else
24 #include "llvm/ADT/OwningPtr.h"
25 #include "llvm/Support/system_error.h"
26 
27 #define ERROR_CODE error_code
28 #define UNIQUE_PTR OwningPtr
29 #endif
30 
31 using namespace llvm;
32 
33 static cl::opt<std::string>
34 InputFilename(cl::Positional, cl::desc("<input bitcode>"), cl::init("-"));
35 
36 static cl::opt<std::string>
37 OutputFilename("o", cl::desc("Output filename"),
38                cl::value_desc("filename"));
39 
40 int main(int argc, char **argv) {
41   LLVMContext &Context = getGlobalContext();
42   llvm_shutdown_obj Y;  // Call llvm_shutdown() on exit.
43 
44   cl::ParseCommandLineOptions(argc, argv, "libclc builtin preparation tool\n");
45 
46   std::string ErrorMessage;
47   std::auto_ptr<Module> M;
48 
49   {
50 #if LLVM_350_AND_NEWER
51     ErrorOr<std::unique_ptr<MemoryBuffer>> BufferOrErr =
52       MemoryBuffer::getFile(InputFilename);
53     std::unique_ptr<MemoryBuffer> &BufferPtr = BufferOrErr.get();
54     if (std::error_code  ec = BufferOrErr.getError())
55 #else
56     UNIQUE_PTR<MemoryBuffer> BufferPtr;
57     if (ERROR_CODE ec = MemoryBuffer::getFileOrSTDIN(InputFilename, BufferPtr))
58 #endif
59       ErrorMessage = ec.message();
60     else {
61 #if LLVM_VERSION_MAJOR > 3 || (LLVM_VERSION_MAJOR == 3 && LLVM_VERSION_MINOR > 4)
62       ErrorOr<Module *> ModuleOrErr = parseBitcodeFile(BufferPtr.get(), Context);
63       if (ERROR_CODE ec = ModuleOrErr.getError())
64         ErrorMessage = ec.message();
65       M.reset(ModuleOrErr.get());
66 #else
67       M.reset(ParseBitcodeFile(BufferPtr.get(), Context, &ErrorMessage));
68 #endif
69     }
70   }
71 
72   if (M.get() == 0) {
73     errs() << argv[0] << ": ";
74     if (ErrorMessage.size())
75       errs() << ErrorMessage << "\n";
76     else
77       errs() << "bitcode didn't read correctly.\n";
78     return 1;
79   }
80 
81   // Set linkage of every external definition to linkonce_odr.
82   for (Module::iterator i = M->begin(), e = M->end(); i != e; ++i) {
83     if (!i->isDeclaration() && i->getLinkage() == GlobalValue::ExternalLinkage)
84       i->setLinkage(GlobalValue::LinkOnceODRLinkage);
85   }
86 
87   for (Module::global_iterator i = M->global_begin(), e = M->global_end();
88        i != e; ++i) {
89     if (!i->isDeclaration() && i->getLinkage() == GlobalValue::ExternalLinkage)
90       i->setLinkage(GlobalValue::LinkOnceODRLinkage);
91   }
92 
93   if (OutputFilename.empty()) {
94     errs() << "no output file\n";
95     return 1;
96   }
97 
98   std::string ErrorInfo;
99   UNIQUE_PTR<tool_output_file> Out
100   (new tool_output_file(OutputFilename.c_str(), ErrorInfo,
101 #if (LLVM_VERSION_MAJOR == 3 && LLVM_VERSION_MINOR == 4)
102                         sys::fs::F_Binary));
103 #elif LLVM_VERSION_MAJOR > 3 || (LLVM_VERSION_MAJOR == 3 && LLVM_VERSION_MINOR >= 5)
104                         sys::fs::F_None));
105 #else
106                         raw_fd_ostream::F_Binary));
107 #endif
108   if (!ErrorInfo.empty()) {
109     errs() << ErrorInfo << '\n';
110     exit(1);
111   }
112 
113   WriteBitcodeToFile(M.get(), Out->os());
114 
115   // Declare success.
116   Out->keep();
117   return 0;
118 }
119 
120