backend.native: support external functions
also implement changing external function symbol name with the annotation
This commit is contained in:
+4
@@ -11,6 +11,10 @@ internal class CodeGenerator(override val context:Context) : ContextUtils {
|
||||
var currentFunction:FunctionDescriptor? = null
|
||||
|
||||
fun function(declaration: IrFunction) {
|
||||
if (declaration.descriptor.isExternal) {
|
||||
return
|
||||
}
|
||||
|
||||
index = 0
|
||||
currentFunction = declaration.descriptor
|
||||
val fn = LLVMAddFunction(context.llvmModule, declaration.descriptor.symbolName, getLlvmFunctionType(declaration.descriptor))
|
||||
|
||||
+15
@@ -34,6 +34,12 @@ internal class RTTIGeneratorVisitor(context: Context) : IrElementVisitorVoid {
|
||||
|
||||
override fun visitClass(declaration: IrClass) {
|
||||
super.visitClass(declaration)
|
||||
|
||||
if (declaration.descriptor.kind == ClassKind.ANNOTATION_CLASS) {
|
||||
// do not generate any RTTI for annotation classes as a workaround for link errors
|
||||
return
|
||||
}
|
||||
|
||||
generator.generate(declaration.descriptor)
|
||||
}
|
||||
|
||||
@@ -50,6 +56,15 @@ internal class CodeGeneratorVisitor(val context: Context) : IrElementVisitorVoid
|
||||
element.acceptChildrenVoid(this)
|
||||
}
|
||||
|
||||
override fun visitClass(declaration: IrClass) {
|
||||
if (declaration.descriptor.kind == ClassKind.ANNOTATION_CLASS) {
|
||||
// do not generate any code for annotation classes as a workaround for NotImplementedError
|
||||
return
|
||||
}
|
||||
|
||||
super.visitClass(declaration)
|
||||
}
|
||||
|
||||
override fun visitSetVariable(expression: IrSetVariable) {
|
||||
val value = evaluateExpression(generator.tmpVariable(), expression.value)
|
||||
generator.store(value!!, generator.variable(expression.descriptor.name.asString())!!)
|
||||
|
||||
+15
-1
@@ -2,10 +2,24 @@ package org.jetbrains.kotlin.backend.native.llvm
|
||||
|
||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.resolve.constants.StringValue
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe
|
||||
|
||||
private val symbolNameAnnotation = FqName("kotlin_native.SymbolName")
|
||||
|
||||
internal val FunctionDescriptor.symbolName: String
|
||||
get() = "kfun:" + this.fqNameSafe.toString() // FIXME: add signature
|
||||
get() {
|
||||
this.annotations.findAnnotation(symbolNameAnnotation)?.let {
|
||||
if (this.isExternal) {
|
||||
val nameValue = it.allValueArguments.values.single() as StringValue
|
||||
return nameValue.value
|
||||
} else {
|
||||
// ignore; TODO: report compile error
|
||||
}
|
||||
}
|
||||
return "kfun:" + this.fqNameSafe.toString() // FIXME: add signature
|
||||
}
|
||||
|
||||
internal val ClassDescriptor.typeInfoSymbolName: String
|
||||
get() = "ktype:" + this.fqNameSafe.toString()
|
||||
@@ -0,0 +1,11 @@
|
||||
package kotlin_native
|
||||
|
||||
/**
|
||||
* Forces the compiler to use specified symbol name for the target `external` function.
|
||||
*
|
||||
* TODO: changing symbol name breaks the binary compatibility,
|
||||
* so it should probably be allowed on `internal` and `private` functions only.
|
||||
*/
|
||||
@Target(AnnotationTarget.FUNCTION)
|
||||
@Retention(AnnotationRetention.BINARY)
|
||||
annotation class SymbolName(val name: String)
|
||||
Reference in New Issue
Block a user