diff --git a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/native/llvm/CodeGenerator.kt b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/native/llvm/CodeGenerator.kt index 18ff4bc7f79..210a2dc2b82 100644 --- a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/native/llvm/CodeGenerator.kt +++ b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/native/llvm/CodeGenerator.kt @@ -22,6 +22,13 @@ internal class CodeGenerator(override val context:Context) : ContextUtils { if (currentFunction == declaration.descriptor) return val fn = prolog(declaration) + // TODO: functions without Kotlin body must not have a bitcode body, + // which is required to workaround link errors + if (declaration.body == null) { + trap() + return + } + var indexOffset = 0 if (declaration.descriptor is ClassConstructorDescriptor || declaration.descriptor.dispatchReceiverParameter != null) { val name = "this" @@ -127,6 +134,19 @@ internal class CodeGenerator(override val context:Context) : ContextUtils { } } + fun trap() { + // LLVM doesn't seem to provide API to get intrinsics; + // workaround this by declaring the intrinsic explicitly: + val trapFun = LLVMGetNamedFunction(context.llvmModule, "llvm.trap") ?: + LLVMAddFunction(context.llvmModule, "llvm.trap", LLVMFunctionType(LLVMVoidType(), null, 0, 0))!! + + LLVMBuildCall(context.llvmBuilder, trapFun, null, 0, "") + + // LLVM seems to require an explicit return instruction even after noreturn intrinsic: + val returnType = LLVMGetReturnType(getFunctionType(currentFunction!!.llvmFunction.getLlvmValue())) + LLVMBuildRet(context.llvmBuilder, LLVMConstNull(returnType)) + } + /* to class descriptor */ fun classType(descriptor: ClassDescriptor):LLVMOpaqueType = LLVMGetTypeByName(context.llvmModule, descriptor.symbolName)!! fun typeInfoType(descriptor: ClassDescriptor): LLVMOpaqueType? = descriptor.llvmTypeInfoPtr.getLlvmType()