Improve coverage of ObjCExport bridges by debug information (#3843)

This commit is contained in:
SvyatoslavScherbina
2020-02-11 14:45:36 +03:00
committed by GitHub
parent ecd06c89bf
commit 8f7ebe7f51
2 changed files with 19 additions and 18 deletions
@@ -124,8 +124,9 @@ internal inline fun<R> generateFunction(codegen: CodeGenerator,
internal inline fun<R> 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 <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.
*/
@@ -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(
@@ -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