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