From d5985bc9ecbdc792d514cf531107d33f85644fdc Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Thu, 4 Apr 2019 13:05:41 -0700 Subject: [PATCH] rustc: Start implementing compat with LLVM 9 This commit doesn't actually migrate to LLVM 9, but it brings our own C++ bindings in line with LLVM 9 and able to compile against tip of tree. The changes made were: * The `MainSubprogram` flag for debuginfo moved between flag types. * Iteration of archive members was tweaked slightly and we have to construct the two iterators before constructing the returned `RustArchiveIterator` value. * The `getOrInsertFunction` binding now returns a wrapper which we use `getCallee()` on to get the value we're interested in. --- src/librustc_codegen_llvm/debuginfo/mod.rs | 11 ++++---- src/librustc_codegen_llvm/llvm/ffi.rs | 2 +- src/rustllvm/ArchiveWrapper.cpp | 26 ++++++++++-------- src/rustllvm/RustWrapper.cpp | 31 ++++++++++++++++------ 4 files changed, 44 insertions(+), 26 deletions(-) diff --git a/src/librustc_codegen_llvm/debuginfo/mod.rs b/src/librustc_codegen_llvm/debuginfo/mod.rs index 6abbcd9feba..57e4ac07d5e 100644 --- a/src/librustc_codegen_llvm/debuginfo/mod.rs +++ b/src/librustc_codegen_llvm/debuginfo/mod.rs @@ -296,12 +296,6 @@ impl DebugInfoMethods<'tcx> for CodegenCx<'ll, 'tcx> { let mut flags = DIFlags::FlagPrototyped; - if let Some((id, _)) = self.tcx.entry_fn(LOCAL_CRATE) { - if id == def_id { - flags |= DIFlags::FlagMainSubprogram; - } - } - if self.layout_of(sig.output()).abi.is_uninhabited() { flags |= DIFlags::FlagNoReturn; } @@ -313,6 +307,11 @@ impl DebugInfoMethods<'tcx> for CodegenCx<'ll, 'tcx> { if self.sess().opts.optimize != config::OptLevel::No { spflags |= DISPFlags::SPFlagOptimized; } + if let Some((id, _)) = self.tcx.entry_fn(LOCAL_CRATE) { + if id == def_id { + spflags |= DISPFlags::SPFlagMainSubprogram; + } + } let fn_metadata = unsafe { llvm::LLVMRustDIBuilderCreateFunction( diff --git a/src/librustc_codegen_llvm/llvm/ffi.rs b/src/librustc_codegen_llvm/llvm/ffi.rs index 2ad6d9c053a..72184cb1e10 100644 --- a/src/librustc_codegen_llvm/llvm/ffi.rs +++ b/src/librustc_codegen_llvm/llvm/ffi.rs @@ -588,7 +588,6 @@ pub mod debuginfo { const FlagIntroducedVirtual = (1 << 18); const FlagBitField = (1 << 19); const FlagNoReturn = (1 << 20); - const FlagMainSubprogram = (1 << 21); } } @@ -603,6 +602,7 @@ pub mod debuginfo { const SPFlagLocalToUnit = (1 << 2); const SPFlagDefinition = (1 << 3); const SPFlagOptimized = (1 << 4); + const SPFlagMainSubprogram = (1 << 5); } } diff --git a/src/rustllvm/ArchiveWrapper.cpp b/src/rustllvm/ArchiveWrapper.cpp index 65975ec574c..dd0111d3f2c 100644 --- a/src/rustllvm/ArchiveWrapper.cpp +++ b/src/rustllvm/ArchiveWrapper.cpp @@ -24,9 +24,14 @@ struct RustArchiveIterator { bool First; Archive::child_iterator Cur; Archive::child_iterator End; - Error Err; + std::unique_ptr Err; - RustArchiveIterator() : First(true), Err(Error::success()) {} + RustArchiveIterator(Archive::child_iterator Cur, Archive::child_iterator End, + std::unique_ptr Err) + : First(true), + Cur(Cur), + End(End), + Err(std::move(Err)) {} }; enum class LLVMRustArchiveKind { @@ -84,15 +89,14 @@ extern "C" void LLVMRustDestroyArchive(LLVMRustArchiveRef RustArchive) { extern "C" LLVMRustArchiveIteratorRef LLVMRustArchiveIteratorNew(LLVMRustArchiveRef RustArchive) { Archive *Archive = RustArchive->getBinary(); - RustArchiveIterator *RAI = new RustArchiveIterator(); - RAI->Cur = Archive->child_begin(RAI->Err); - if (RAI->Err) { - LLVMRustSetLastError(toString(std::move(RAI->Err)).c_str()); - delete RAI; + std::unique_ptr Err = llvm::make_unique(Error::success()); + auto Cur = Archive->child_begin(*Err); + if (*Err) { + LLVMRustSetLastError(toString(std::move(*Err)).c_str()); return nullptr; } - RAI->End = Archive->child_end(); - return RAI; + auto End = Archive->child_end(); + return new RustArchiveIterator(Cur, End, std::move(Err)); } extern "C" LLVMRustArchiveChildConstRef @@ -108,8 +112,8 @@ LLVMRustArchiveIteratorNext(LLVMRustArchiveIteratorRef RAI) { // but instead advance it *before* fetching the child in all later calls. if (!RAI->First) { ++RAI->Cur; - if (RAI->Err) { - LLVMRustSetLastError(toString(std::move(RAI->Err)).c_str()); + if (*RAI->Err) { + LLVMRustSetLastError(toString(std::move(*RAI->Err)).c_str()); return nullptr; } } else { diff --git a/src/rustllvm/RustWrapper.cpp b/src/rustllvm/RustWrapper.cpp index a00417a3629..437e2d482ef 100644 --- a/src/rustllvm/RustWrapper.cpp +++ b/src/rustllvm/RustWrapper.cpp @@ -117,7 +117,11 @@ extern "C" LLVMValueRef LLVMRustGetOrInsertFunction(LLVMModuleRef M, const char *Name, LLVMTypeRef FunctionTy) { return wrap( - unwrap(M)->getOrInsertFunction(Name, unwrap(FunctionTy))); + unwrap(M)->getOrInsertFunction(Name, unwrap(FunctionTy)) +#if LLVM_VERSION_GE(9, 0) + .getCallee() +#endif + ); } extern "C" LLVMValueRef @@ -417,7 +421,6 @@ enum class LLVMRustDIFlags : uint32_t { FlagIntroducedVirtual = (1 << 18), FlagBitField = (1 << 19), FlagNoReturn = (1 << 20), - FlagMainSubprogram = (1 << 21), // Do not add values that are not supported by the minimum LLVM // version we support! see llvm/include/llvm/IR/DebugInfoFlags.def }; @@ -508,9 +511,6 @@ static DINode::DIFlags fromRust(LLVMRustDIFlags Flags) { if (isSet(Flags & LLVMRustDIFlags::FlagNoReturn)) { Result |= DINode::DIFlags::FlagNoReturn; } - if (isSet(Flags & LLVMRustDIFlags::FlagMainSubprogram)) { - Result |= DINode::DIFlags::FlagMainSubprogram; - } return Result; } @@ -525,6 +525,7 @@ enum class LLVMRustDISPFlags : uint32_t { SPFlagLocalToUnit = (1 << 2), SPFlagDefinition = (1 << 3), SPFlagOptimized = (1 << 4), + SPFlagMainSubprogram = (1 << 5), // Do not add values that are not supported by the minimum LLVM // version we support! see llvm/include/llvm/IR/DebugInfoFlags.def // (In LLVM < 8, createFunction supported these as separate bool arguments.) @@ -575,6 +576,11 @@ static DISubprogram::DISPFlags fromRust(LLVMRustDISPFlags SPFlags) { if (isSet(SPFlags & LLVMRustDISPFlags::SPFlagOptimized)) { Result |= DISubprogram::DISPFlags::SPFlagOptimized; } +#if LLVM_VERSION_GE(9, 0) + if (isSet(SPFlags & LLVMRustDISPFlags::SPFlagMainSubprogram)) { + Result |= DISubprogram::DISPFlags::SPFlagMainSubprogram; + } +#endif return Result; } @@ -671,18 +677,27 @@ extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateFunction( DITemplateParameterArray TParams = DITemplateParameterArray(unwrap(TParam)); #if LLVM_VERSION_GE(8, 0) + DISubprogram::DISPFlags llvmSPFlags = fromRust(SPFlags); + DINode::DIFlags llvmFlags = fromRust(Flags); +#if LLVM_VERSION_LT(9, 0) + if (isSet(SPFlags & LLVMRustDISPFlags::SPFlagMainSubprogram)) + llvmFlags |= DINode::DIFlags::FlagMainSubprogram; +#endif DISubprogram *Sub = Builder->createFunction( unwrapDI(Scope), Name, LinkageName, unwrapDI(File), - LineNo, unwrapDI(Ty), ScopeLine, fromRust(Flags), - fromRust(SPFlags), TParams, unwrapDIPtr(Decl)); + LineNo, unwrapDI(Ty), ScopeLine, llvmFlags, + llvmSPFlags, TParams, unwrapDIPtr(Decl)); #else bool IsLocalToUnit = isSet(SPFlags & LLVMRustDISPFlags::SPFlagLocalToUnit); bool IsDefinition = isSet(SPFlags & LLVMRustDISPFlags::SPFlagDefinition); bool IsOptimized = isSet(SPFlags & LLVMRustDISPFlags::SPFlagOptimized); + DINode::DIFlags llvmFlags = fromRust(Flags); + if (isSet(SPFlags & LLVMRustDISPFlags::SPFlagMainSubprogram)) + llvmFlags |= DINode::DIFlags::FlagMainSubprogram; DISubprogram *Sub = Builder->createFunction( unwrapDI(Scope), Name, LinkageName, unwrapDI(File), LineNo, unwrapDI(Ty), IsLocalToUnit, IsDefinition, - ScopeLine, fromRust(Flags), IsOptimized, TParams, + ScopeLine, llvmFlags, IsOptimized, TParams, unwrapDIPtr(Decl)); #endif unwrap(Fn)->setSubprogram(Sub);