backend.native: support external functions

also implement changing external function symbol name with the annotation
This commit is contained in:
Svyatoslav Scherbina
2016-10-19 12:03:41 +03:00
parent 61e1d91c03
commit a1593c86f1
4 changed files with 45 additions and 1 deletions
@@ -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))
@@ -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())!!)
@@ -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)