diff options
| author | Ariel Ben-Yehuda <ariel.byd@gmail.com> | 2016-08-02 00:16:16 +0300 |
|---|---|---|
| committer | Ariel Ben-Yehuda <arielb1@mail.tau.ac.il> | 2016-08-03 15:08:47 +0300 |
| commit | 696691e3c4f2b3aa02fbd1cc76dc2f7e8a401db8 (patch) | |
| tree | b74e88f26e0a6d2f5d3ff114efe34fbd6b805223 /src/rustllvm | |
| parent | 81df89fc2d6ba1b55ab20b0615b8523a6e90963f (diff) | |
| download | rust-696691e3c4f2b3aa02fbd1cc76dc2f7e8a401db8.tar.gz rust-696691e3c4f2b3aa02fbd1cc76dc2f7e8a401db8.zip | |
audit LLVM C++ types in ArchiveWrapper and PassWrapper
Diffstat (limited to 'src/rustllvm')
| -rw-r--r-- | src/rustllvm/ArchiveWrapper.cpp | 98 | ||||
| -rw-r--r-- | src/rustllvm/PassWrapper.cpp | 138 | ||||
| -rw-r--r-- | src/rustllvm/README | 14 | ||||
| -rw-r--r-- | src/rustllvm/rustllvm.h | 5 |
4 files changed, 196 insertions, 59 deletions
diff --git a/src/rustllvm/ArchiveWrapper.cpp b/src/rustllvm/ArchiveWrapper.cpp index 3d48024c879..059cc40d511 100644 --- a/src/rustllvm/ArchiveWrapper.cpp +++ b/src/rustllvm/ArchiveWrapper.cpp @@ -16,24 +16,62 @@ using namespace llvm; using namespace llvm::object; -struct LLVMRustArchiveMember { +struct RustArchiveMember { const char *filename; const char *name; Archive::Child child; - LLVMRustArchiveMember(): filename(NULL), name(NULL), + RustArchiveMember(): filename(NULL), name(NULL), #if LLVM_VERSION_MINOR >= 8 child(NULL, NULL, NULL) #else child(NULL, NULL) #endif {} - ~LLVMRustArchiveMember() {} + ~RustArchiveMember() {} }; -typedef OwningBinary<Archive> RustArchive; -extern "C" void* +struct RustArchiveIterator { + Archive::child_iterator cur; + Archive::child_iterator end; +#if LLVM_VERSION_MINOR >= 9 + Error err; +#endif +}; + +enum class LLVMRustArchiveKind { + Other, + GNU, + MIPS64, + BSD, + COFF, +}; + +static Archive::Kind +from_rust(LLVMRustArchiveKind kind) +{ + switch (kind) { + case LLVMRustArchiveKind::GNU: + return Archive::K_GNU; + case LLVMRustArchiveKind::MIPS64: + return Archive::K_MIPS64; + case LLVMRustArchiveKind::BSD: + return Archive::K_BSD; + case LLVMRustArchiveKind::COFF: + return Archive::K_COFF; + default: + abort(); + } +} + +typedef OwningBinary<Archive> *LLVMRustArchiveRef; +typedef RustArchiveMember *LLVMRustArchiveMemberRef; +typedef Archive::Child *LLVMRustArchiveChildRef; +typedef Archive::Child const *LLVMRustArchiveChildConstRef; +typedef RustArchiveIterator *LLVMRustArchiveIteratorRef; + +extern "C" LLVMRustArchiveRef LLVMRustOpenArchive(char *path) { ErrorOr<std::unique_ptr<MemoryBuffer>> buf_or = MemoryBuffer::getFile(path, -1, @@ -66,20 +104,12 @@ LLVMRustOpenArchive(char *path) { } extern "C" void -LLVMRustDestroyArchive(RustArchive *ar) { +LLVMRustDestroyArchive(LLVMRustArchiveRef ar) { delete ar; } -struct RustArchiveIterator { - Archive::child_iterator cur; - Archive::child_iterator end; -#if LLVM_VERSION_MINOR >= 9 - Error err; -#endif -}; - -extern "C" RustArchiveIterator* -LLVMRustArchiveIteratorNew(RustArchive *ra) { +extern "C" LLVMRustArchiveIteratorRef +LLVMRustArchiveIteratorNew(LLVMRustArchiveRef ra) { Archive *ar = ra->getBinary(); RustArchiveIterator *rai = new RustArchiveIterator(); #if LLVM_VERSION_MINOR <= 8 @@ -95,8 +125,8 @@ LLVMRustArchiveIteratorNew(RustArchive *ra) { return rai; } -extern "C" const Archive::Child* -LLVMRustArchiveIteratorNext(RustArchiveIterator *rai) { +extern "C" LLVMRustArchiveChildConstRef +LLVMRustArchiveIteratorNext(LLVMRustArchiveIteratorRef rai) { #if LLVM_VERSION_MINOR >= 9 if (rai->err) { LLVMRustSetLastError(toString(std::move(rai->err)).c_str()); @@ -122,17 +152,17 @@ LLVMRustArchiveIteratorNext(RustArchiveIterator *rai) { } extern "C" void -LLVMRustArchiveChildFree(Archive::Child *child) { +LLVMRustArchiveChildFree(LLVMRustArchiveChildRef child) { delete child; } extern "C" void -LLVMRustArchiveIteratorFree(RustArchiveIterator *rai) { +LLVMRustArchiveIteratorFree(LLVMRustArchiveIteratorRef rai) { delete rai; } extern "C" const char* -LLVMRustArchiveChildName(const Archive::Child *child, size_t *size) { +LLVMRustArchiveChildName(LLVMRustArchiveChildConstRef child, size_t *size) { ErrorOr<StringRef> name_or_err = child->getName(); if (name_or_err.getError()) return NULL; @@ -142,7 +172,7 @@ LLVMRustArchiveChildName(const Archive::Child *child, size_t *size) { } extern "C" const char* -LLVMRustArchiveChildData(Archive::Child *child, size_t *size) { +LLVMRustArchiveChildData(LLVMRustArchiveChildRef child, size_t *size) { StringRef buf; ErrorOr<StringRef> buf_or_err = child->getBuffer(); if (buf_or_err.getError()) { @@ -154,9 +184,10 @@ LLVMRustArchiveChildData(Archive::Child *child, size_t *size) { return buf.data(); } -extern "C" LLVMRustArchiveMember* -LLVMRustArchiveMemberNew(char *Filename, char *Name, Archive::Child *child) { - LLVMRustArchiveMember *Member = new LLVMRustArchiveMember; +extern "C" LLVMRustArchiveMemberRef +LLVMRustArchiveMemberNew(char *Filename, char *Name, + LLVMRustArchiveChildRef child) { + RustArchiveMember *Member = new RustArchiveMember; Member->filename = Filename; Member->name = Name; if (child) @@ -165,22 +196,23 @@ LLVMRustArchiveMemberNew(char *Filename, char *Name, Archive::Child *child) { } extern "C" void -LLVMRustArchiveMemberFree(LLVMRustArchiveMember *Member) { +LLVMRustArchiveMemberFree(LLVMRustArchiveMemberRef Member) { delete Member; } -extern "C" int +extern "C" LLVMRustResult LLVMRustWriteArchive(char *Dst, size_t NumMembers, - const LLVMRustArchiveMember **NewMembers, + const LLVMRustArchiveMemberRef *NewMembers, bool WriteSymbtab, - Archive::Kind Kind) { + LLVMRustArchiveKind rust_kind) { #if LLVM_VERSION_MINOR <= 8 std::vector<NewArchiveIterator> Members; #else std::vector<NewArchiveMember> Members; #endif + auto Kind = from_rust(rust_kind); for (size_t i = 0; i < NumMembers; i++) { auto Member = NewMembers[i]; @@ -190,7 +222,7 @@ LLVMRustWriteArchive(char *Dst, Expected<NewArchiveMember> MOrErr = NewArchiveMember::getFile(Member->filename, true); if (!MOrErr) { LLVMRustSetLastError(toString(MOrErr.takeError()).c_str()); - return -1; + return LLVMRustResult::Failure; } Members.push_back(std::move(*MOrErr)); #elif LLVM_VERSION_MINOR == 8 @@ -205,7 +237,7 @@ LLVMRustWriteArchive(char *Dst, Expected<NewArchiveMember> MOrErr = NewArchiveMember::getOldMember(Member->child, true); if (!MOrErr) { LLVMRustSetLastError(toString(MOrErr.takeError()).c_str()); - return -1; + return LLVMRustResult::Failure; } Members.push_back(std::move(*MOrErr)); #endif @@ -217,7 +249,7 @@ LLVMRustWriteArchive(char *Dst, auto pair = writeArchive(Dst, Members, WriteSymbtab, Kind, true); #endif if (!pair.second) - return 0; + return LLVMRustResult::Success; LLVMRustSetLastError(pair.second.message().c_str()); - return -1; + return LLVMRustResult::Failure; } diff --git a/src/rustllvm/PassWrapper.cpp b/src/rustllvm/PassWrapper.cpp index a1276060271..9e72724d8ab 100644 --- a/src/rustllvm/PassWrapper.cpp +++ b/src/rustllvm/PassWrapper.cpp @@ -54,41 +54,48 @@ LLVMInitializePasses() { initializeTarget(Registry); } - -enum class SupportedPassKind { +enum class LLVMRustPassKind { + Other, Function, Module, - Unsupported }; -extern "C" Pass* +static LLVMRustPassKind +to_rust(PassKind kind) +{ + switch (kind) { + case PT_Function: + return LLVMRustPassKind::Function; + case PT_Module: + return LLVMRustPassKind::Module; + default: + return LLVMRustPassKind::Other; + } +} + +extern "C" LLVMPassRef LLVMRustFindAndCreatePass(const char *PassName) { StringRef SR(PassName); PassRegistry *PR = PassRegistry::getPassRegistry(); const PassInfo *PI = PR->getPassInfo(SR); if (PI) { - return PI->createPass(); + return wrap(PI->createPass()); } return NULL; } -extern "C" SupportedPassKind -LLVMRustPassKind(Pass *pass) { - assert(pass); - PassKind passKind = pass->getPassKind(); - if (passKind == PT_Module) { - return SupportedPassKind::Module; - } else if (passKind == PT_Function) { - return SupportedPassKind::Function; - } else { - return SupportedPassKind::Unsupported; - } +extern "C" LLVMRustPassKind +LLVMRustPassKind(LLVMPassRef rust_pass) { + assert(rust_pass); + Pass *pass = unwrap(rust_pass); + return to_rust(pass->getPassKind()); } extern "C" void -LLVMRustAddPass(LLVMPassManagerRef PM, Pass *pass) { - assert(pass); +LLVMRustAddPass(LLVMPassManagerRef PM, LLVMPassRef rust_pass) { + assert(rust_pass); + Pass *pass = unwrap(rust_pass); PassManagerBase *pm = unwrap(PM); pm->add(pass); } @@ -162,13 +169,69 @@ LLVMRustHasFeature(LLVMTargetMachineRef TM, return (Bits & FeatureEntry->Value) == FeatureEntry->Value; } +enum class LLVMRustCodeModel { + Other, + Default, + JITDefault, + Small, + Kernel, + Medium, + Large, +}; + +static CodeModel::Model +from_rust(LLVMRustCodeModel model) +{ + switch (model) { + case LLVMRustCodeModel::Default: + return CodeModel::Default; + case LLVMRustCodeModel::JITDefault: + return CodeModel::JITDefault; + case LLVMRustCodeModel::Small: + return CodeModel::Small; + case LLVMRustCodeModel::Kernel: + return CodeModel::Kernel; + case LLVMRustCodeModel::Medium: + return CodeModel::Medium; + case LLVMRustCodeModel::Large: + return CodeModel::Large; + default: + abort(); + } +} + +enum class LLVMRustCodeGenOptLevel { + Other, + None, + Less, + Default, + Aggressive, +}; + +static CodeGenOpt::Level +from_rust(LLVMRustCodeGenOptLevel level) +{ + switch (level) { + case LLVMRustCodeGenOptLevel::None: + return CodeGenOpt::None; + case LLVMRustCodeGenOptLevel::Less: + return CodeGenOpt::Less; + case LLVMRustCodeGenOptLevel::Default: + return CodeGenOpt::Default; + case LLVMRustCodeGenOptLevel::Aggressive: + return CodeGenOpt::Aggressive; + default: + abort(); + } +} + extern "C" LLVMTargetMachineRef LLVMRustCreateTargetMachine(const char *triple, const char *cpu, const char *feature, - CodeModel::Model CM, + LLVMRustCodeModel rust_CM, LLVMRelocMode Reloc, - CodeGenOpt::Level OptLevel, + LLVMRustCodeGenOptLevel rust_OptLevel, bool UseSoftFloat, bool PositionIndependentExecutable, bool FunctionSections, @@ -179,6 +242,9 @@ LLVMRustCreateTargetMachine(const char *triple, #else Optional<Reloc::Model> RM; #endif + auto CM = from_rust(rust_CM); + auto OptLevel = from_rust(rust_OptLevel); + switch (Reloc){ case LLVMRelocStatic: RM = Reloc::Static; @@ -251,14 +317,14 @@ LLVMRustAddAnalysisPasses(LLVMTargetMachineRef TM, extern "C" void LLVMRustConfigurePassManagerBuilder(LLVMPassManagerBuilderRef PMB, - CodeGenOpt::Level OptLevel, + LLVMRustCodeGenOptLevel OptLevel, bool MergeFunctions, bool SLPVectorize, bool LoopVectorize) { // Ignore mergefunc for now as enabling it causes crashes. //unwrap(PMB)->MergeFunctions = MergeFunctions; unwrap(PMB)->SLPVectorize = SLPVectorize; - unwrap(PMB)->OptLevel = OptLevel; + unwrap(PMB)->OptLevel = from_rust(OptLevel); unwrap(PMB)->LoopVectorize = LoopVectorize; } @@ -314,13 +380,33 @@ LLVMRustSetLLVMOptions(int Argc, char **Argv) { cl::ParseCommandLineOptions(Argc, Argv); } -extern "C" bool +enum class LLVMRustFileType { + Other, + AssemblyFile, + ObjectFile, +}; + +static TargetMachine::CodeGenFileType +from_rust(LLVMRustFileType type) +{ + switch (type) { + case LLVMRustFileType::AssemblyFile: + return TargetMachine::CGFT_AssemblyFile; + case LLVMRustFileType::ObjectFile: + return TargetMachine::CGFT_ObjectFile; + default: + abort(); + } +} + +extern "C" LLVMRustResult LLVMRustWriteOutputFile(LLVMTargetMachineRef Target, LLVMPassManagerRef PMR, LLVMModuleRef M, const char *path, - TargetMachine::CodeGenFileType FileType) { + LLVMRustFileType rust_FileType) { llvm::legacy::PassManager *PM = unwrap<llvm::legacy::PassManager>(PMR); + auto FileType = from_rust(rust_FileType); std::string ErrorInfo; std::error_code EC; @@ -329,7 +415,7 @@ LLVMRustWriteOutputFile(LLVMTargetMachineRef Target, ErrorInfo = EC.message(); if (ErrorInfo != "") { LLVMRustSetLastError(ErrorInfo.c_str()); - return false; + return LLVMRustResult::Failure; } unwrap(Target)->addPassesToEmitFile(*PM, OS, FileType, false); @@ -339,7 +425,7 @@ LLVMRustWriteOutputFile(LLVMTargetMachineRef Target, // stream (OS), so the only real safe place to delete this is here? Don't we // wish this was written in Rust? delete PM; - return true; + return LLVMRustResult::Success; } extern "C" void diff --git a/src/rustllvm/README b/src/rustllvm/README index c0db3f68a76..e1c6dd07d2b 100644 --- a/src/rustllvm/README +++ b/src/rustllvm/README @@ -1,2 +1,16 @@ This directory currently contains some LLVM support code. This will generally be sent upstream to LLVM in time; for now it lives here. + +NOTE: the LLVM C++ ABI is subject to between-version breakage and must *never* +be exposed to Rust. To allow for easy auditing of that, all Rust-exposed types +must be typedef-ed as "LLVMXyz", or "LLVMRustXyz" if they were defined here. + +Functions that return a failure status and leave the error in +the LLVM last error should return an LLVMRustResult rather than an +int or anything to avoid confusion. + +When translating enums, add a single `Other` variant as the first +one to allow for new variants to be added. It should abort when used +as an input. + +All other types must not be typedef-ed as such. diff --git a/src/rustllvm/rustllvm.h b/src/rustllvm/rustllvm.h index 2a47e8b0895..5aae11fb456 100644 --- a/src/rustllvm/rustllvm.h +++ b/src/rustllvm/rustllvm.h @@ -58,6 +58,11 @@ void LLVMRustSetLastError(const char*); +enum class LLVMRustResult { + Success, + Failure +}; + typedef struct OpaqueRustString *RustStringRef; typedef struct LLVMOpaqueTwine *LLVMTwineRef; typedef struct LLVMOpaqueDebugLoc *LLVMDebugLocRef; |
