Add debug info to some ObjCExport bridges (#3237)
to fix inlined frames decoding.
This commit is contained in:
committed by
GitHub
parent
746dcfdb7a
commit
65e6f85dc1
+5
@@ -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.
|
||||
*/
|
||||
|
||||
+31
@@ -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)
|
||||
}
|
||||
|
||||
+10
-3
@@ -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()),
|
||||
|
||||
Reference in New Issue
Block a user