diff --git a/translator/.gradle/2.9/taskArtifacts/cache.properties.lock b/translator/.gradle/2.9/taskArtifacts/cache.properties.lock index d061c564a6c..a5855757139 100644 Binary files a/translator/.gradle/2.9/taskArtifacts/cache.properties.lock and b/translator/.gradle/2.9/taskArtifacts/cache.properties.lock differ diff --git a/translator/.gradle/2.9/taskArtifacts/fileHashes.bin b/translator/.gradle/2.9/taskArtifacts/fileHashes.bin index 697fb99ea5c..3908f1d87e5 100644 Binary files a/translator/.gradle/2.9/taskArtifacts/fileHashes.bin and b/translator/.gradle/2.9/taskArtifacts/fileHashes.bin differ diff --git a/translator/.gradle/2.9/taskArtifacts/fileSnapshots.bin b/translator/.gradle/2.9/taskArtifacts/fileSnapshots.bin index d791606d08d..0f278fa2f3d 100644 Binary files a/translator/.gradle/2.9/taskArtifacts/fileSnapshots.bin and b/translator/.gradle/2.9/taskArtifacts/fileSnapshots.bin differ diff --git a/translator/.gradle/2.9/taskArtifacts/outputFileStates.bin b/translator/.gradle/2.9/taskArtifacts/outputFileStates.bin index 90ce2923599..3f7c92fb6c4 100644 Binary files a/translator/.gradle/2.9/taskArtifacts/outputFileStates.bin and b/translator/.gradle/2.9/taskArtifacts/outputFileStates.bin differ diff --git a/translator/.gradle/2.9/taskArtifacts/taskArtifacts.bin b/translator/.gradle/2.9/taskArtifacts/taskArtifacts.bin index 8f71b7520c0..d37c5fe6560 100644 Binary files a/translator/.gradle/2.9/taskArtifacts/taskArtifacts.bin and b/translator/.gradle/2.9/taskArtifacts/taskArtifacts.bin differ diff --git a/translator/src/main/kotlin/org/kotlinnative/translator/BlockCodegen.kt b/translator/src/main/kotlin/org/kotlinnative/translator/BlockCodegen.kt index a15430f089f..74c6a0cb156 100644 --- a/translator/src/main/kotlin/org/kotlinnative/translator/BlockCodegen.kt +++ b/translator/src/main/kotlin/org/kotlinnative/translator/BlockCodegen.kt @@ -65,7 +65,7 @@ abstract class BlockCodegen(open val state: TranslationState, open val variableM is KtCallableReferenceExpression -> evaluateCallableReferenceExpression(expr) is KtDotQualifiedExpression -> evaluateDotExpression(expr, scopeDepth) is KtReferenceExpression -> evaluateReferenceExpression(expr, scopeDepth) - is KtIfExpression -> evaluateIfOperator(expr.firstChild as LeafPsiElement, scopeDepth + 1, true) + is KtIfExpression -> evaluateIfOperator(expr.firstChild as LeafPsiElement, scopeDepth + 1, expr) is KtStringTemplateExpression -> evaluateStringTemplateExpression(expr) is KtReturnExpression -> evaluateReturnInstruction(expr.firstChild, scopeDepth) is PsiWhiteSpace -> null @@ -426,7 +426,7 @@ abstract class BlockCodegen(open val state: TranslationState, open val variableM private fun evaluateLeafPsiElement(element: LeafPsiElement, scopeDepth: Int): LLVMVariable? { return when (element.elementType) { KtTokens.RETURN_KEYWORD -> evaluateReturnInstruction(element, scopeDepth) - KtTokens.IF_KEYWORD -> evaluateIfOperator(element, scopeDepth, containReturn = false) + KtTokens.IF_KEYWORD -> evaluateIfOperator(element, scopeDepth, ifExpression = null) KtTokens.WHILE_KEYWORD -> evaluateWhileOperator(element, scopeDepth) else -> null } @@ -458,11 +458,13 @@ abstract class BlockCodegen(open val state: TranslationState, open val variableM private fun evaluateWhenExpression(expr: KtWhenExpression, scopeDepth: Int): LLVMVariable? { codeBuilder.addComment("start when expression") val whenExpression = expr.subjectExpression + val kotlinType = state.bindingContext.get(BindingContext.EXPRESSION_TYPE_INFO, expr)!!.type!! + val expressionType = LLVMMapStandardType("type", kotlinType, LLVMVariableScope()).type val targetExpression = evaluateExpression(whenExpression, scopeDepth + 1)!! - val resultVariable = codeBuilder.getNewVariable(LLVMIntType(), pointer = 1) - codeBuilder.allocStackVarInPointer(resultVariable) + val resultVariable = codeBuilder.getNewVariable(expressionType, pointer = 1) + codeBuilder.allocStackPointedVarAsValue(resultVariable) var nextLabel = codeBuilder.getNewLabel(prefix = "when_start") val endLabel = codeBuilder.getNewLabel(prefix = "when_end") @@ -507,7 +509,7 @@ abstract class BlockCodegen(open val state: TranslationState, open val variableM return null } - private fun evaluateIfOperator(element: LeafPsiElement, scopeDepth: Int, containReturn: Boolean): LLVMVariable? { + private fun evaluateIfOperator(element: LeafPsiElement, scopeDepth: Int, ifExpression: KtIfExpression?): LLVMVariable? { var getBrackets = element.getNextSiblingIgnoringWhitespaceAndComments() ?: return null val condition = getBrackets.getNextSiblingIgnoringWhitespaceAndComments() ?: return null getBrackets = condition.getNextSiblingIgnoringWhitespaceAndComments() ?: return null @@ -515,16 +517,18 @@ abstract class BlockCodegen(open val state: TranslationState, open val variableM val elseKeyword = thenExpression.getNextSiblingIgnoringWhitespaceAndComments() ?: return null val elseExpression = elseKeyword.getNextSiblingIgnoringWhitespaceAndComments() ?: return null - return when (containReturn) { - false -> executeIfBlock(condition.firstChild as KtBinaryExpression, thenExpression.firstChild, elseExpression.firstChild, scopeDepth + 1) - true -> executeIfExpression(condition.firstChild as KtBinaryExpression, thenExpression.firstChild, elseExpression.firstChild, scopeDepth + 1) + return when (ifExpression) { + null -> executeIfBlock(condition.firstChild as KtBinaryExpression, thenExpression.firstChild, elseExpression.firstChild, scopeDepth + 1) + else -> executeIfExpression(condition.firstChild as KtBinaryExpression, thenExpression.firstChild, elseExpression.firstChild, ifExpression, scopeDepth + 1) } } - private fun executeIfExpression(condition: KtBinaryExpression, thenExpression: PsiElement, elseExpression: PsiElement?, scopeDepth: Int): LLVMVariable? { + private fun executeIfExpression(condition: KtBinaryExpression, thenExpression: PsiElement, elseExpression: PsiElement?, ifExpression: KtIfExpression, scopeDepth: Int): LLVMVariable? { val conditionResult: LLVMVariable = evaluateBinaryExpression(condition, scopeDepth + 1) - val resultVariable = codeBuilder.getNewVariable(LLVMIntType(), pointer = 1) - codeBuilder.allocStackVar(resultVariable) + val kotlinType = state.bindingContext.get(BindingContext.EXPRESSION_TYPE_INFO, ifExpression)!!.type!! + val expressionType = LLVMMapStandardType("type", kotlinType, LLVMVariableScope()).type + val resultVariable = codeBuilder.getNewVariable(expressionType, pointer = 1) + codeBuilder.allocStackPointedVarAsValue(resultVariable) val thenLabel = codeBuilder.getNewLabel(prefix = "if") val elseLabel = codeBuilder.getNewLabel(prefix = "if") val endLabel = codeBuilder.getNewLabel(prefix = "if") diff --git a/translator/src/main/kotlin/org/kotlinnative/translator/llvm/LLVMBuilder.kt b/translator/src/main/kotlin/org/kotlinnative/translator/llvm/LLVMBuilder.kt index f2b1c694ffa..ed733d2cfe7 100644 --- a/translator/src/main/kotlin/org/kotlinnative/translator/llvm/LLVMBuilder.kt +++ b/translator/src/main/kotlin/org/kotlinnative/translator/llvm/LLVMBuilder.kt @@ -162,7 +162,7 @@ class LLVMBuilder(val arm: Boolean) { localCode.appendln("$target = alloca ${target.getType()}, align ${target.type.align}") } - fun allocStackVarInPointer(target: LLVMVariable) { + fun allocStackPointedVarAsValue(target: LLVMVariable) { localCode.appendln("$target = alloca ${target.type}, align ${target.type.align}") } diff --git a/translator/src/main/kotlin/org/kotlinnative/translator/llvm/generators.kt b/translator/src/main/kotlin/org/kotlinnative/translator/llvm/generators.kt index deedb3439f2..5b251eb5682 100644 --- a/translator/src/main/kotlin/org/kotlinnative/translator/llvm/generators.kt +++ b/translator/src/main/kotlin/org/kotlinnative/translator/llvm/generators.kt @@ -20,6 +20,6 @@ fun LLVMMapStandardType(name: String, type: KotlinType, scope: LLVMScope = LLVMR type.toString() == "Char" -> LLVMVariable(name, LLVMCharType(), name, scope) type.toString() == "Boolean" -> LLVMVariable(name, LLVMBooleanType(), name, scope) type.isUnit() -> LLVMVariable("", LLVMVoidType(), name, scope) - type.isMarkedNullable -> LLVMVariable(name, LLVMReferenceType("${type.toString().dropLast(1)}"), name, scope, pointer = 1) - else -> LLVMVariable(name, LLVMReferenceType("$type"), name, scope, pointer = 1) -} + type.isMarkedNullable -> LLVMVariable(name, LLVMReferenceType(type.toString().dropLast(1)), name, scope, pointer = 1) + else -> LLVMVariable(name, LLVMReferenceType(type.toString()), name, scope, pointer = 1) +} \ No newline at end of file diff --git a/translator/src/test/kotlin/tests/input/if_expression_1.txt b/translator/src/test/kotlin/tests/input/if_expression_1.txt new file mode 100644 index 00000000000..0bee0da933d --- /dev/null +++ b/translator/src/test/kotlin/tests/input/if_expression_1.txt @@ -0,0 +1,2 @@ +if_expression_1(56) == 2323 +if_expression_1(-58) == 678934 diff --git a/translator/src/test/kotlin/tests/kotlin/if_1.kt b/translator/src/test/kotlin/tests/kotlin/if_1.kt index a67f222497f..ba38538844c 100644 --- a/translator/src/test/kotlin/tests/kotlin/if_1.kt +++ b/translator/src/test/kotlin/tests/kotlin/if_1.kt @@ -8,11 +8,11 @@ fun if_test_1(x: Int): Int { return a } -class MyClass2(i: Int) +class MyClass_if_1(i: Int) fun if_test_null(x: Int): Int { - val y: MyClass2? = null + val y: MyClass_if_1? = null if (y == null) { return 1 } else { @@ -21,7 +21,7 @@ fun if_test_null(x: Int): Int { } fun if_test_null_2(x: Int): Int { - val y: MyClass2? = MyClass2(1) + val y: MyClass_if_1? = MyClass_if_1(1) if (y == null) { return 1 diff --git a/translator/src/test/kotlin/tests/kotlin/if_expression_1.kt b/translator/src/test/kotlin/tests/kotlin/if_expression_1.kt new file mode 100644 index 00000000000..7513e688fd8 --- /dev/null +++ b/translator/src/test/kotlin/tests/kotlin/if_expression_1.kt @@ -0,0 +1,3 @@ +fun if_expression_1(x: Int): Int{ + return if (x > 55) 2323 else 678934 +} \ No newline at end of file