From 8f7ebe7f511d5700cf559c854f9202bf55240e11 Mon Sep 17 00:00:00 2001 From: SvyatoslavScherbina Date: Tue, 11 Feb 2020 14:45:36 +0300 Subject: [PATCH] Improve coverage of ObjCExport bridges by debug information (#3843) --- .../backend/konan/llvm/CodeGenerator.kt | 16 ++++++-------- .../objcexport/ObjCExportCodeGenerator.kt | 21 ++++++++++++------- 2 files changed, 19 insertions(+), 18 deletions(-) diff --git a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/CodeGenerator.kt b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/CodeGenerator.kt index 9382cafff36..152c95ddb7b 100644 --- a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/CodeGenerator.kt +++ b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/CodeGenerator.kt @@ -124,8 +124,9 @@ internal inline fun generateFunction(codegen: CodeGenerator, internal inline fun generateFunction(codegen: CodeGenerator, function: LLVMValueRef, + startLocation: LocationInfo? = null, endLocation: LocationInfo? = null, code:FunctionGenerationContext.(FunctionGenerationContext) -> R) { - val functionGenerationContext = FunctionGenerationContext(function, codegen, null, null) + val functionGenerationContext = FunctionGenerationContext(function, codegen, startLocation, endLocation) try { generateFunctionBody(functionGenerationContext, code) } finally { @@ -140,7 +141,7 @@ internal inline fun generateFunction( block: FunctionGenerationContext.(FunctionGenerationContext) -> Unit ): LLVMValueRef { val function = LLVMAddFunction(codegen.context.llvmModule, name, functionType)!! - generateFunction(codegen, function, block) + generateFunction(codegen, function, startLocation = null, endLocation = null, code = block) return function } @@ -155,11 +156,6 @@ private inline fun 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. */ @@ -672,7 +668,7 @@ internal class FunctionGenerationContext(val function: LLVMValueRef, fun kotlinExceptionHandler( block: FunctionGenerationContext.(exception: LLVMValueRef) -> Unit ): ExceptionHandler { - val lpBlock = basicBlock("kotlinExceptionHandler", null) + val lpBlock = basicBlock("kotlinExceptionHandler", position()?.end) appendingTo(lpBlock) { val exception = catchKotlinException() @@ -1127,8 +1123,8 @@ internal class FunctionGenerationContext(val function: LLVMValueRef, val clause = ConstArray(int8TypePtr, listOf(kotlinExceptionRtti)) LLVMAddClause(landingpad, clause.llvm) - val bbCleanup = basicBlock("forwardException", null) - val bbUnexpected = basicBlock("unexpectedException", null) + val bbCleanup = basicBlock("forwardException", position()?.end) + val bbUnexpected = basicBlock("unexpectedException", position()?.end) val selector = extractValue(landingpad, 1) condBr( diff --git a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/objcexport/ObjCExportCodeGenerator.kt b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/objcexport/ObjCExportCodeGenerator.kt index b898321880b..fdbe67b02ad 100644 --- a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/objcexport/ObjCExportCodeGenerator.kt +++ b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/objcexport/ObjCExportCodeGenerator.kt @@ -684,11 +684,18 @@ private fun ObjCExportCodeGenerator.emitCollectionConverters() { private inline fun ObjCExportCodeGenerator.generateObjCImpBy( methodBridge: MethodBridge, + debugInfo: Boolean = false, genBody: FunctionGenerationContext.() -> Unit ): LLVMValueRef { val result = LLVMAddFunction(context.llvmModule, "objc2kotlin", objCFunctionType(context, methodBridge))!! - generateFunction(codegen, result) { + val location = if (debugInfo) { + setupBridgeDebugInfo(context, result) + } else { + null + } + + generateFunction(codegen, result, startLocation = location, endLocation = location) { genBody() } @@ -737,13 +744,11 @@ private fun ObjCExportCodeGenerator.generateObjCImp( 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. - } +): LLVMValueRef = generateObjCImpBy(methodBridge, debugInfo = isDirect /* see below */) { + // Considering direct calls inlinable above. If such a call is inlined into a bridge with no debug information, + // lldb will not decode the inlined frame even if the callee has debug information. + // So generate dummy debug information for bridge in this case. + // TODO: consider adding debug info to other bridges. val returnType = methodBridge.returnBridge