Add debug info to some ObjCExport bridges (#3237)

to fix inlined frames decoding.
This commit is contained in:
SvyatoslavScherbina
2019-08-03 10:28:34 +03:00
committed by GitHub
parent 746dcfdb7a
commit 65e6f85dc1
3 changed files with 46 additions and 3 deletions
@@ -155,6 +155,11 @@ private inline fun <R> generateFunctionBody(
functionGenerationContext.resetDebugLocation()
}
internal fun FunctionGenerationContext.initBridgeDebugInfo() {
val location = setupBridgeDebugInfo(context, function) ?: return
debugLocation(location, location)
}
/**
* There're cases when we don't need end position or it is meaningless.
*/
@@ -7,6 +7,7 @@ package org.jetbrains.kotlin.backend.konan.llvm
import kotlinx.cinterop.allocArrayOf
import kotlinx.cinterop.memScoped
import kotlinx.cinterop.reinterpret
import llvm.*
import org.jetbrains.kotlin.backend.konan.*
import org.jetbrains.kotlin.ir.SourceManager.FileEntry
@@ -81,6 +82,10 @@ internal class DebugInfo internal constructor(override val context: Context):Con
val otherLlvmType = LLVMPointerType(LLVMInt64Type(), 0)!!
val otherTypeSize = LLVMSizeOfTypeInBits(llvmTargetData, otherLlvmType)
val otherTypeAlignment = LLVMPreferredAlignmentOfType(llvmTargetData, otherLlvmType)
val compilerGeneratedFile by lazy {
DICreateFile(builder, "<compiler-generated>", "")!!
}
}
/**
@@ -250,3 +255,29 @@ internal fun subroutineType(context: Context, llvmTargetData: LLVMTargetDataRef,
@Suppress("UNCHECKED_CAST")
private fun dwarfPointerType(context: Context, type: DITypeOpaqueRef) =
DICreatePointerType(context.debugInfo.builder, type) as DITypeOpaqueRef
internal fun setupBridgeDebugInfo(context: Context, function: LLVMValueRef): LocationInfo? {
if (!context.shouldContainLocationDebugInfo()) {
return null
}
val file = context.debugInfo.compilerGeneratedFile
// TODO: can we share the scope among all bridges?
val scope: DIScopeOpaqueRef = DICreateFunction(
builder = context.debugInfo.builder,
scope = file.reinterpret(),
name = function.name,
linkageName = function.name,
file = file,
lineNo = 0,
type = subroutineType(context, context.llvm.runtime.targetData, emptyList()), // TODO: use proper type.
isLocal = 0,
isDefinition = 1,
scopeLine = 0
)!!.also {
DIFunctionAddSubprogram(function, it)
}.reinterpret()
return LocationInfo(scope, 1, 0)
}
@@ -535,7 +535,7 @@ private inline fun ObjCExportCodeGenerator.generateObjCImpBy(
genBody()
}
LLVMSetLinkage(result, LLVMLinkage.LLVMPrivateLinkage)
LLVMSetLinkage(result, LLVMLinkage.LLVMInternalLinkage)
return result
}
@@ -555,7 +555,7 @@ private fun ObjCExportCodeGenerator.generateObjCImp(
) = if (target == null) {
generateAbstractObjCImp(methodBridge)
} else {
generateObjCImp(methodBridge) { args, resultLifetime, exceptionHandler ->
generateObjCImp(methodBridge, isDirect = !isVirtual) { args, resultLifetime, exceptionHandler ->
val llvmTarget = if (!isVirtual) {
codegen.llvmFunction(target)
} else {
@@ -568,12 +568,19 @@ private fun ObjCExportCodeGenerator.generateObjCImp(
private fun ObjCExportCodeGenerator.generateObjCImp(
methodBridge: MethodBridge,
isDirect: Boolean,
callKotlin: FunctionGenerationContext.(
args: List<LLVMValueRef>,
resultLifetime: Lifetime,
exceptionHandler: ExceptionHandler
) -> LLVMValueRef?
): LLVMValueRef = generateObjCImpBy(methodBridge) {
if (isDirect) {
// Consider this call inlinable. If it is inlined into a bridge with no debug information,
// lldb will not decode the inlined frame even if the callee has debug information.
initBridgeDebugInfo()
// TODO: consider adding debug info to other bridges.
}
val returnType = methodBridge.returnBridge
@@ -674,7 +681,7 @@ private fun ObjCExportCodeGenerator.generateObjCImp(
private fun ObjCExportCodeGenerator.generateObjCImpForArrayConstructor(
target: IrConstructor,
methodBridge: MethodBridge
): LLVMValueRef = generateObjCImp(methodBridge) { args, resultLifetime, exceptionHandler ->
): LLVMValueRef = generateObjCImp(methodBridge, isDirect = true) { args, resultLifetime, exceptionHandler ->
val arrayInstance = callFromBridge(
context.llvm.allocArrayFunction,
listOf(target.constructedClass.llvmTypeInfoPtr, args.first()),