backend: treat kotlin.Unit type specially only when used as return type
also remove some hacks related to Unit.
This commit is contained in:
committed by
SvyatoslavScherbina
parent
9a3bcd4c19
commit
7797b0efdc
-1
@@ -51,7 +51,6 @@ internal val FunctionDescriptor.isIntrinsic: Boolean
|
|||||||
get() = this.annotations.findAnnotation(intrinsicAnnotation) != null
|
get() = this.annotations.findAnnotation(intrinsicAnnotation) != null
|
||||||
|
|
||||||
private val intrinsicTypes = setOf(
|
private val intrinsicTypes = setOf(
|
||||||
"kotlin.Unit",
|
|
||||||
"kotlin.Boolean", "kotlin.Char",
|
"kotlin.Boolean", "kotlin.Char",
|
||||||
"kotlin.Byte", "kotlin.Short",
|
"kotlin.Byte", "kotlin.Short",
|
||||||
"kotlin.Int", "kotlin.Long",
|
"kotlin.Int", "kotlin.Long",
|
||||||
|
|||||||
+10
-3
@@ -4,6 +4,7 @@ import llvm.*
|
|||||||
import org.jetbrains.kotlin.backend.konan.descriptors.isUnboundCallableReference
|
import org.jetbrains.kotlin.backend.konan.descriptors.isUnboundCallableReference
|
||||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||||
import org.jetbrains.kotlin.types.KotlinType
|
import org.jetbrains.kotlin.types.KotlinType
|
||||||
|
import org.jetbrains.kotlin.types.typeUtil.isUnit
|
||||||
|
|
||||||
internal fun ContextUtils.getLLVMType(type: KotlinType): LLVMTypeRef {
|
internal fun ContextUtils.getLLVMType(type: KotlinType): LLVMTypeRef {
|
||||||
return when {
|
return when {
|
||||||
@@ -15,12 +16,18 @@ internal fun ContextUtils.getLLVMType(type: KotlinType): LLVMTypeRef {
|
|||||||
KotlinBuiltIns.isShort(type) || KotlinBuiltIns.isChar(type) -> LLVMInt16Type()
|
KotlinBuiltIns.isShort(type) || KotlinBuiltIns.isChar(type) -> LLVMInt16Type()
|
||||||
KotlinBuiltIns.isInt(type) -> LLVMInt32Type()
|
KotlinBuiltIns.isInt(type) -> LLVMInt32Type()
|
||||||
KotlinBuiltIns.isLong(type) -> LLVMInt64Type()
|
KotlinBuiltIns.isLong(type) -> LLVMInt64Type()
|
||||||
KotlinBuiltIns.isUnit(type) -> LLVMVoidType() // TODO: handle Unit parameter case
|
|
||||||
// TODO: stdlib have methods taking Nothing, such as kotlin.collections.EmptySet.contains().
|
|
||||||
// KotlinBuiltIns.isNothing(type) -> LLVMVoidType()
|
|
||||||
KotlinBuiltIns.isFloat(type) -> LLVMFloatType()
|
KotlinBuiltIns.isFloat(type) -> LLVMFloatType()
|
||||||
KotlinBuiltIns.isDouble(type) -> LLVMDoubleType()
|
KotlinBuiltIns.isDouble(type) -> LLVMDoubleType()
|
||||||
!KotlinBuiltIns.isPrimitiveType(type) -> this.kObjHeaderPtr
|
!KotlinBuiltIns.isPrimitiveType(type) -> this.kObjHeaderPtr
|
||||||
else -> throw NotImplementedError(type.toString() + " is not supported")
|
else -> throw NotImplementedError(type.toString() + " is not supported")
|
||||||
}!!
|
}!!
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal fun ContextUtils.getLLVMReturnType(type: KotlinType): LLVMTypeRef {
|
||||||
|
return when {
|
||||||
|
type.isUnit() -> LLVMVoidType()!!
|
||||||
|
// TODO: stdlib have methods taking Nothing, such as kotlin.collections.EmptySet.contains().
|
||||||
|
// KotlinBuiltIns.isNothing(type) -> LLVMVoidType()
|
||||||
|
else -> getLLVMType(type)
|
||||||
|
}
|
||||||
|
}
|
||||||
+2
-13
@@ -614,12 +614,6 @@ internal class CodeGeneratorVisitor(val context: Context) : IrElementVisitorVoid
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if (KotlinBuiltIns.isUnit(declaration.descriptor.defaultType)) {
|
|
||||||
// Do not generate any code for Unit.
|
|
||||||
// TODO: Unit has toString() operation, which we may want to support.
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
super.visitClass(declaration)
|
super.visitClass(declaration)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1543,17 +1537,12 @@ internal class CodeGeneratorVisitor(val context: Context) : IrElementVisitorVoid
|
|||||||
context.log("evaluateReturn : ${ir2string(expression)}")
|
context.log("evaluateReturn : ${ir2string(expression)}")
|
||||||
val value = expression.value
|
val value = expression.value
|
||||||
|
|
||||||
val evaluated = if (value is IrGetObjectValue && value.type.isUnit()) {
|
val evaluated = evaluateExpression(value)
|
||||||
// hack to make "return without value" work
|
|
||||||
null
|
|
||||||
} else {
|
|
||||||
evaluateExpression(value)
|
|
||||||
}
|
|
||||||
|
|
||||||
val ret = if (!value.type.isUnit()) {
|
val ret = if (!value.type.isUnit()) {
|
||||||
evaluated
|
evaluated
|
||||||
} else {
|
} else {
|
||||||
null // hack for bad Unit type handling
|
null // `Unit` return type is generated as `void`.
|
||||||
}
|
}
|
||||||
|
|
||||||
currentCodeContext.genReturn(expression.returnTarget, ret)
|
currentCodeContext.genReturn(expression.returnTarget, ret)
|
||||||
|
|||||||
+1
-1
@@ -143,7 +143,7 @@ internal fun structType(types: List<LLVMTypeRef>): LLVMTypeRef = memScoped {
|
|||||||
}
|
}
|
||||||
|
|
||||||
internal fun ContextUtils.getLlvmFunctionType(function: FunctionDescriptor): LLVMTypeRef {
|
internal fun ContextUtils.getLlvmFunctionType(function: FunctionDescriptor): LLVMTypeRef {
|
||||||
val returnType = if (function is ConstructorDescriptor) voidType else getLLVMType(function.returnType!!)
|
val returnType = if (function is ConstructorDescriptor) voidType else getLLVMReturnType(function.returnType!!)
|
||||||
val paramTypes = ArrayList(function.allValueParameters.map { getLLVMType(it.type) })
|
val paramTypes = ArrayList(function.allValueParameters.map { getLLVMType(it.type) })
|
||||||
if (isObjectType(returnType)) paramTypes.add(kObjHeaderPtrPtr)
|
if (isObjectType(returnType)) paramTypes.add(kObjHeaderPtrPtr)
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user