backend: treat kotlin.Unit type specially only when used as return type

also remove some hacks related to Unit.
This commit is contained in:
Svyatoslav Scherbina
2016-12-26 17:20:22 +07:00
committed by SvyatoslavScherbina
parent 9a3bcd4c19
commit 7797b0efdc
4 changed files with 13 additions and 18 deletions
@@ -51,7 +51,6 @@ internal val FunctionDescriptor.isIntrinsic: Boolean
get() = this.annotations.findAnnotation(intrinsicAnnotation) != null
private val intrinsicTypes = setOf(
"kotlin.Unit",
"kotlin.Boolean", "kotlin.Char",
"kotlin.Byte", "kotlin.Short",
"kotlin.Int", "kotlin.Long",
@@ -4,6 +4,7 @@ import llvm.*
import org.jetbrains.kotlin.backend.konan.descriptors.isUnboundCallableReference
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
import org.jetbrains.kotlin.types.KotlinType
import org.jetbrains.kotlin.types.typeUtil.isUnit
internal fun ContextUtils.getLLVMType(type: KotlinType): LLVMTypeRef {
return when {
@@ -15,12 +16,18 @@ internal fun ContextUtils.getLLVMType(type: KotlinType): LLVMTypeRef {
KotlinBuiltIns.isShort(type) || KotlinBuiltIns.isChar(type) -> LLVMInt16Type()
KotlinBuiltIns.isInt(type) -> LLVMInt32Type()
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.isDouble(type) -> LLVMDoubleType()
!KotlinBuiltIns.isPrimitiveType(type) -> this.kObjHeaderPtr
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)
}
}
@@ -614,12 +614,6 @@ internal class CodeGeneratorVisitor(val context: Context) : IrElementVisitorVoid
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)
}
@@ -1543,17 +1537,12 @@ internal class CodeGeneratorVisitor(val context: Context) : IrElementVisitorVoid
context.log("evaluateReturn : ${ir2string(expression)}")
val value = expression.value
val evaluated = if (value is IrGetObjectValue && value.type.isUnit()) {
// hack to make "return without value" work
null
} else {
evaluateExpression(value)
}
val evaluated = evaluateExpression(value)
val ret = if (!value.type.isUnit()) {
evaluated
} else {
null // hack for bad Unit type handling
null // `Unit` return type is generated as `void`.
}
currentCodeContext.genReturn(expression.returnTarget, ret)
@@ -143,7 +143,7 @@ internal fun structType(types: List<LLVMTypeRef>): LLVMTypeRef = memScoped {
}
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) })
if (isObjectType(returnType)) paramTypes.add(kObjHeaderPtrPtr)