//===- RustWrapper.cpp - Rust wrapper for core functions --------*- C++ -*-===// // // The LLVM Compiler Infrastructure // // This file is distributed under the University of Illinois Open Source // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// // // This file defines alternate interfaces to core functions that are more // readily callable by Rust's FFI. // //===----------------------------------------------------------------------===// #include "llvm/Linker.h" #include "llvm/PassManager.h" #include "llvm/ADT/Triple.h" #include "llvm/Support/FormattedStream.h" #include "llvm/Support/Timer.h" #include "llvm/Support/raw_ostream.h" #include "llvm/Target/TargetMachine.h" #include "llvm/Support/TargetSelect.h" #include "llvm/Support/TargetRegistry.h" #include "llvm/Target/TargetOptions.h" #include "llvm/Support/Host.h" #include "llvm-c/Core.h" #include "llvm-c/BitReader.h" #include "llvm-c/Object.h" #include using namespace llvm; static const char *LLVMRustError; extern "C" LLVMMemoryBufferRef LLVMRustCreateMemoryBufferWithContentsOfFile(const char *Path) { LLVMMemoryBufferRef MemBuf = NULL; LLVMCreateMemoryBufferWithContentsOfFile(Path, &MemBuf, const_cast(&LLVMRustError)); return MemBuf; } extern "C" const char *LLVMRustGetLastError(void) { return LLVMRustError; } extern "C" void LLVMAddBasicAliasAnalysisPass(LLVMPassManagerRef PM); extern "C" bool LLVMLinkModules(LLVMModuleRef Dest, LLVMModuleRef Src) { static std::string err; // For some strange reason, unwrap() doesn't work here. "No matching // function" error. Module *DM = reinterpret_cast(Dest); Module *SM = reinterpret_cast(Src); if (Linker::LinkModules(DM, SM, &err)) { LLVMRustError = err.c_str(); return false; } return true; } extern "C" void LLVMRustWriteOutputFile(LLVMPassManagerRef PMR, LLVMModuleRef M, const char *triple, const char *path, TargetMachine::CodeGenFileType FileType, CodeGenOpt::Level OptLevel) { // Set compilation options. llvm::NoFramePointerElim = true; InitializeAllTargets(); InitializeAllTargetMCs(); InitializeAllAsmPrinters(); InitializeAllAsmParsers(); std::string Err; const Target *TheTarget = TargetRegistry::lookupTarget(triple, Err); std::string FeaturesStr; std::string Trip(triple); std::string CPUStr = llvm::sys::getHostCPUName(); TargetMachine *Target = TheTarget->createTargetMachine(Trip, CPUStr, FeaturesStr, Reloc::PIC_); bool NoVerify = false; PassManager *PM = unwrap(PMR); std::string ErrorInfo; raw_fd_ostream OS(path, ErrorInfo, raw_fd_ostream::F_Binary); formatted_raw_ostream FOS(OS); bool foo = Target->addPassesToEmitFile(*PM, FOS, FileType, OptLevel, NoVerify); assert(!foo); (void)foo; PM->run(*unwrap(M)); delete Target; } extern "C" LLVMModuleRef LLVMRustParseBitcode(LLVMMemoryBufferRef MemBuf) { LLVMModuleRef M; return LLVMParseBitcode(MemBuf, &M, const_cast(&LLVMRustError)) ? NULL : M; } extern "C" const char *LLVMRustGetHostTriple(void) { static std::string str = llvm::sys::getHostTriple(); return str.c_str(); } extern "C" LLVMValueRef LLVMRustConstSmallInt(LLVMTypeRef IntTy, unsigned N, LLVMBool SignExtend) { return LLVMConstInt(IntTy, (unsigned long long)N, SignExtend); } extern bool llvm::TimePassesIsEnabled; extern "C" void LLVMRustEnableTimePasses() { TimePassesIsEnabled = true; } extern "C" void LLVMRustPrintPassTimings() { raw_fd_ostream OS (2, false); // stderr. TimerGroup::printAll(OS); }