diff options
Diffstat (limited to 'compiler/rustc_llvm')
| -rw-r--r-- | compiler/rustc_llvm/llvm-wrapper/CoverageMappingWrapper.cpp | 54 | ||||
| -rw-r--r-- | compiler/rustc_llvm/llvm-wrapper/LLVMWrapper.h | 5 | ||||
| -rw-r--r-- | compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp | 3 | ||||
| -rw-r--r-- | compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp | 32 | ||||
| -rw-r--r-- | compiler/rustc_llvm/src/lib.rs | 69 |
5 files changed, 94 insertions, 69 deletions
diff --git a/compiler/rustc_llvm/llvm-wrapper/CoverageMappingWrapper.cpp b/compiler/rustc_llvm/llvm-wrapper/CoverageMappingWrapper.cpp index b32af5e5e75..2ee7454b652 100644 --- a/compiler/rustc_llvm/llvm-wrapper/CoverageMappingWrapper.cpp +++ b/compiler/rustc_llvm/llvm-wrapper/CoverageMappingWrapper.cpp @@ -123,13 +123,13 @@ fromRust(LLVMRustCounterExprKind Kind) { report_fatal_error("Bad LLVMRustCounterExprKind!"); } -extern "C" void LLVMRustCoverageWriteFilenamesSectionToBuffer( +extern "C" void LLVMRustCoverageWriteFilenamesToBuffer( const char *const Filenames[], size_t FilenamesLen, // String start pointers const size_t *const Lengths, size_t LengthsLen, // Corresponding lengths RustStringRef BufferOut) { if (FilenamesLen != LengthsLen) { report_fatal_error( - "Mismatched lengths in LLVMRustCoverageWriteFilenamesSectionToBuffer"); + "Mismatched lengths in LLVMRustCoverageWriteFilenamesToBuffer"); } SmallVector<std::string, 32> FilenameRefs; @@ -143,16 +143,15 @@ extern "C" void LLVMRustCoverageWriteFilenamesSectionToBuffer( FilenamesWriter.write(OS); } -extern "C" void LLVMRustCoverageWriteMappingToBuffer( - const unsigned *VirtualFileMappingIDs, unsigned NumVirtualFileMappingIDs, - const LLVMRustCounterExpression *RustExpressions, unsigned NumExpressions, - const LLVMRustCoverageCodeRegion *CodeRegions, unsigned NumCodeRegions, - const LLVMRustCoverageBranchRegion *BranchRegions, - unsigned NumBranchRegions, +extern "C" void LLVMRustCoverageWriteFunctionMappingsToBuffer( + const unsigned *VirtualFileMappingIDs, size_t NumVirtualFileMappingIDs, + const LLVMRustCounterExpression *RustExpressions, size_t NumExpressions, + const LLVMRustCoverageCodeRegion *CodeRegions, size_t NumCodeRegions, + const LLVMRustCoverageBranchRegion *BranchRegions, size_t NumBranchRegions, const LLVMRustCoverageMCDCBranchRegion *MCDCBranchRegions, - unsigned NumMCDCBranchRegions, + size_t NumMCDCBranchRegions, const LLVMRustCoverageMCDCDecisionRegion *MCDCDecisionRegions, - unsigned NumMCDCDecisionRegions, RustStringRef BufferOut) { + size_t NumMCDCDecisionRegions, RustStringRef BufferOut) { // Convert from FFI representation to LLVM representation. // Expressions: @@ -219,34 +218,37 @@ LLVMRustCoverageCreatePGOFuncNameVar(LLVMValueRef F, const char *FuncName, return wrap(createPGOFuncNameVar(*cast<Function>(unwrap(F)), FuncNameRef)); } -extern "C" uint64_t LLVMRustCoverageHashByteArray(const char *Bytes, - size_t NumBytes) { - auto StrRef = StringRef(Bytes, NumBytes); - return IndexedInstrProf::ComputeHash(StrRef); +extern "C" uint64_t LLVMRustCoverageHashBytes(const char *Bytes, + size_t NumBytes) { + return IndexedInstrProf::ComputeHash(StringRef(Bytes, NumBytes)); } -static void WriteSectionNameToString(LLVMModuleRef M, InstrProfSectKind SK, - RustStringRef Str) { +// Private helper function for getting the covmap and covfun section names. +static void writeInstrProfSectionNameToString(LLVMModuleRef M, + InstrProfSectKind SectKind, + RustStringRef OutStr) { auto TargetTriple = Triple(unwrap(M)->getTargetTriple()); - auto name = getInstrProfSectionName(SK, TargetTriple.getObjectFormat()); - auto OS = RawRustStringOstream(Str); + auto name = getInstrProfSectionName(SectKind, TargetTriple.getObjectFormat()); + auto OS = RawRustStringOstream(OutStr); OS << name; } -extern "C" void LLVMRustCoverageWriteMapSectionNameToString(LLVMModuleRef M, - RustStringRef Str) { - WriteSectionNameToString(M, IPSK_covmap, Str); +extern "C" void +LLVMRustCoverageWriteCovmapSectionNameToString(LLVMModuleRef M, + RustStringRef OutStr) { + writeInstrProfSectionNameToString(M, IPSK_covmap, OutStr); } extern "C" void -LLVMRustCoverageWriteFuncSectionNameToString(LLVMModuleRef M, - RustStringRef Str) { - WriteSectionNameToString(M, IPSK_covfun, Str); +LLVMRustCoverageWriteCovfunSectionNameToString(LLVMModuleRef M, + RustStringRef OutStr) { + writeInstrProfSectionNameToString(M, IPSK_covfun, OutStr); } -extern "C" void LLVMRustCoverageWriteMappingVarNameToString(RustStringRef Str) { +extern "C" void +LLVMRustCoverageWriteCovmapVarNameToString(RustStringRef OutStr) { auto name = getCoverageMappingVarName(); - auto OS = RawRustStringOstream(Str); + auto OS = RawRustStringOstream(OutStr); OS << name; } diff --git a/compiler/rustc_llvm/llvm-wrapper/LLVMWrapper.h b/compiler/rustc_llvm/llvm-wrapper/LLVMWrapper.h index 73bbc9de855..76f7d054040 100644 --- a/compiler/rustc_llvm/llvm-wrapper/LLVMWrapper.h +++ b/compiler/rustc_llvm/llvm-wrapper/LLVMWrapper.h @@ -104,8 +104,9 @@ typedef struct OpaqueRustString *RustStringRef; typedef struct LLVMOpaqueTwine *LLVMTwineRef; typedef struct LLVMOpaqueSMDiagnostic *LLVMSMDiagnosticRef; -extern "C" void LLVMRustStringWriteImpl(RustStringRef Str, const char *Ptr, - size_t Size); +extern "C" void LLVMRustStringWriteImpl(RustStringRef buf, + const char *slice_ptr, + size_t slice_len); class RawRustStringOstream : public llvm::raw_ostream { RustStringRef Str; diff --git a/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp b/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp index eb99d560e57..6f47ee88add 100644 --- a/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp +++ b/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp @@ -1624,5 +1624,6 @@ extern "C" void LLVMRustComputeLTOCacheKey(RustStringRef KeyOut, CfiFunctionDefs, CfiFunctionDecls); #endif - LLVMRustStringWriteImpl(KeyOut, Key.c_str(), Key.size()); + auto OS = RawRustStringOstream(KeyOut); + OS << Key.str(); } diff --git a/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp b/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp index 645b4082be5..f739b010c30 100644 --- a/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp +++ b/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp @@ -140,26 +140,14 @@ extern "C" void LLVMRustSetNormalizedTarget(LLVMModuleRef M, unwrap(M)->setTargetTriple(Triple::normalize(Triple)); } -extern "C" const char *LLVMRustPrintPassTimings(size_t *Len) { - std::string buf; - auto SS = raw_string_ostream(buf); - TimerGroup::printAll(SS); - SS.flush(); - *Len = buf.length(); - char *CStr = (char *)malloc(*Len); - memcpy(CStr, buf.c_str(), *Len); - return CStr; -} - -extern "C" const char *LLVMRustPrintStatistics(size_t *Len) { - std::string buf; - auto SS = raw_string_ostream(buf); - llvm::PrintStatistics(SS); - SS.flush(); - *Len = buf.length(); - char *CStr = (char *)malloc(*Len); - memcpy(CStr, buf.c_str(), *Len); - return CStr; +extern "C" void LLVMRustPrintPassTimings(RustStringRef OutBuf) { + auto OS = RawRustStringOstream(OutBuf); + TimerGroup::printAll(OS); +} + +extern "C" void LLVMRustPrintStatistics(RustStringRef OutBuf) { + auto OS = RawRustStringOstream(OutBuf); + llvm::PrintStatistics(OS); } extern "C" LLVMValueRef LLVMRustGetNamedValue(LLVMModuleRef M, const char *Name, @@ -1522,8 +1510,8 @@ LLVMRustUnpackSMDiagnostic(LLVMSMDiagnosticRef DRef, RustStringRef MessageOut, const SourceMgr &LSM = *D.getSourceMgr(); const MemoryBuffer *LBuf = LSM.getMemoryBuffer(LSM.FindBufferContainingLoc(D.getLoc())); - LLVMRustStringWriteImpl(BufferOut, LBuf->getBufferStart(), - LBuf->getBufferSize()); + auto BufferOS = RawRustStringOstream(BufferOut); + BufferOS << LBuf->getBuffer(); *LocOut = D.getLoc().getPointer() - LBuf->getBufferStart(); diff --git a/compiler/rustc_llvm/src/lib.rs b/compiler/rustc_llvm/src/lib.rs index 055d2bd5bc9..eda9b2b1fc0 100644 --- a/compiler/rustc_llvm/src/lib.rs +++ b/compiler/rustc_llvm/src/lib.rs @@ -2,42 +2,75 @@ #![allow(internal_features)] #![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")] #![doc(rust_logo)] +#![feature(extern_types)] #![feature(rustdoc_internals)] #![warn(unreachable_pub)] // tidy-alphabetical-end -// NOTE: This crate only exists to allow linking on mingw targets. - use std::cell::RefCell; -use std::slice; +use std::{ptr, slice}; -use libc::{c_char, size_t}; +use libc::size_t; -#[repr(C)] -pub struct RustString { - pub bytes: RefCell<Vec<u8>>, +unsafe extern "C" { + /// Opaque type that allows C++ code to write bytes to a Rust-side buffer, + /// in conjunction with `RawRustStringOstream`. Use this as `&RustString` + /// (Rust) and `RustStringRef` (C++) in FFI signatures. + pub type RustString; } impl RustString { - pub fn len(&self) -> usize { - self.bytes.borrow().len() + pub fn build_byte_buffer(closure: impl FnOnce(&Self)) -> Vec<u8> { + let buf = RustStringInner::default(); + closure(buf.as_opaque()); + buf.into_inner() } +} - pub fn is_empty(&self) -> bool { - self.bytes.borrow().is_empty() +/// Underlying implementation of [`RustString`]. +/// +/// Having two separate types makes it possible to use the opaque [`RustString`] +/// in FFI signatures without `improper_ctypes` warnings. This is a workaround +/// for the fact that there is no way to opt out of `improper_ctypes` when +/// _declaring_ a type (as opposed to using that type). +#[derive(Default)] +struct RustStringInner { + bytes: RefCell<Vec<u8>>, +} + +impl RustStringInner { + fn as_opaque(&self) -> &RustString { + let ptr: *const RustStringInner = ptr::from_ref(self); + // We can't use `ptr::cast` here because extern types are `!Sized`. + let ptr = ptr as *const RustString; + unsafe { &*ptr } + } + + fn from_opaque(opaque: &RustString) -> &Self { + // SAFETY: A valid `&RustString` must have been created via `as_opaque`. + let ptr: *const RustString = ptr::from_ref(opaque); + let ptr: *const RustStringInner = ptr.cast(); + unsafe { &*ptr } + } + + fn into_inner(self) -> Vec<u8> { + self.bytes.into_inner() } } -/// Appending to a Rust string -- used by RawRustStringOstream. +/// Appends the contents of a byte slice to a [`RustString`]. +/// +/// This function is implemented in `rustc_llvm` so that the C++ code in this +/// crate can link to it directly, without an implied link-time dependency on +/// `rustc_codegen_llvm`. #[unsafe(no_mangle)] pub unsafe extern "C" fn LLVMRustStringWriteImpl( - sr: &RustString, - ptr: *const c_char, - size: size_t, + buf: &RustString, + slice_ptr: *const u8, // Same ABI as `*const c_char` + slice_len: size_t, ) { - let slice = unsafe { slice::from_raw_parts(ptr as *const u8, size) }; - - sr.bytes.borrow_mut().extend_from_slice(slice); + let slice = unsafe { slice::from_raw_parts(slice_ptr, slice_len) }; + RustStringInner::from_opaque(buf).bytes.borrow_mut().extend_from_slice(slice); } /// Initialize targets enabled by the build script via `cfg(llvm_component = "...")`. |
