From cf5ae6312ae38868ae1d0b3cda893e8218437626 Mon Sep 17 00:00:00 2001 From: Alexey Stepanov Date: Fri, 15 Jul 2016 11:43:05 +0300 Subject: [PATCH] translator: fix constant types, labels without returns, add tests for while --- .../translator/FunctionCodegen.kt | 22 ++++++++++--------- .../translator/llvm/LLVMBuilder.kt | 4 ++++ .../src/test/kotlin/tests/input/while_2.txt | 1 + .../src/test/kotlin/tests/output/while_2.txt | 1 + .../src/test/kotlin/tests/source/while_2.kt | 7 ++++++ 5 files changed, 25 insertions(+), 10 deletions(-) create mode 100644 translator/src/test/kotlin/tests/input/while_2.txt create mode 100644 translator/src/test/kotlin/tests/output/while_2.txt create mode 100644 translator/src/test/kotlin/tests/source/while_2.kt diff --git a/translator/src/main/kotlin/org/kotlinnative/translator/FunctionCodegen.kt b/translator/src/main/kotlin/org/kotlinnative/translator/FunctionCodegen.kt index 04304b57a91..23917151b80 100644 --- a/translator/src/main/kotlin/org/kotlinnative/translator/FunctionCodegen.kt +++ b/translator/src/main/kotlin/org/kotlinnative/translator/FunctionCodegen.kt @@ -21,6 +21,8 @@ class FunctionCodegen(val state: TranslationState, val function: KtNamedFunction var returnType: LLVMVariable var args = ArrayList() val variableManager = state.variableManager + val topLevel = 2 + var wasReturnOnTopLevel = false init { val descriptor = state.bindingContext.get(BindingContext.FUNCTION, function)!! @@ -51,12 +53,10 @@ class FunctionCodegen(val state: TranslationState, val function: KtNamedFunction codeBuilder.addStartExpression() generateLoadArguments() - evaluateCodeBlock(function.bodyExpression) + evaluateCodeBlock(function.bodyExpression, scopeDepth = topLevel) - - if (returnType.type is LLVMVoidType) { - codeBuilder.addVoidReturn() - } + if (!wasReturnOnTopLevel) + codeBuilder.addAnyReturn(returnType.type) codeBuilder.addEndExpression() } @@ -98,16 +98,16 @@ class FunctionCodegen(val state: TranslationState, val function: KtNamedFunction private fun generateLoadArguments() { args.forEach(fun(it: LLVMVariable) { if (it.type is LLVMFunctionType) { - variableManager.addVariable(it.label, LLVMVariable(it.label, it.type, it.label, LLVMLocalScope(), pointer = 1), 2) + variableManager.addVariable(it.label, LLVMVariable(it.label, it.type, it.label, LLVMLocalScope(), pointer = 1), topLevel) return } if (it.type !is LLVMReferenceType || (it.type as LLVMReferenceType).isReturn) { val loadVariable = LLVMVariable("${it.label}", it.type, it.label, LLVMLocalScope(), pointer = 0) val allocVar = codeBuilder.loadArgument(loadVariable) - variableManager.addVariable(it.label, allocVar, 2) + variableManager.addVariable(it.label, allocVar, topLevel) } else { - variableManager.addVariable(it.label, LLVMVariable(it.label, it.type, it.label, LLVMLocalScope(), pointer = 0), 2) + variableManager.addVariable(it.label, LLVMVariable(it.label, it.type, it.label, LLVMLocalScope(), pointer = 0), topLevel) } }) } @@ -432,7 +432,7 @@ class FunctionCodegen(val state: TranslationState, val function: KtNamedFunction copyVariable(assignExpression, allocVar) } is LLVMConstant -> { - val newVar = variableManager.receiveVariable(identifier!!.text, LLVMIntType(), LLVMLocalScope(), pointer = 1) + val newVar = variableManager.receiveVariable(identifier!!.text, assignExpression.type!!, LLVMLocalScope(), pointer = 1) codeBuilder.addConstant(newVar, assignExpression) variableManager.addVariable(identifier.text, newVar, scopeDepth) @@ -461,7 +461,9 @@ class FunctionCodegen(val state: TranslationState, val function: KtNamedFunction codeBuilder.addReturnOperator(retNativeValue) } } - + if (scopeDepth == topLevel + 2) { + wasReturnOnTopLevel = true + } return null } } \ No newline at end of file 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 ad6a82166d2..0be23dbc55b 100644 --- a/translator/src/main/kotlin/org/kotlinnative/translator/llvm/LLVMBuilder.kt +++ b/translator/src/main/kotlin/org/kotlinnative/translator/llvm/LLVMBuilder.kt @@ -97,6 +97,10 @@ class LLVMBuilder(val arm: Boolean) { llvmLocalCode.appendln("ret void") } + fun addAnyReturn(type: LLVMType, value: String = type.defaultValue){ + llvmLocalCode.appendln("ret $type $value") + } + fun addStringConstant(variable: LLVMVariable, value: String) { val type = variable.type as LLVMStringType llvmGlobalCode.appendln("$variable = private unnamed_addr constant ${type.fullType()} c\"$value\\00\", align 1") diff --git a/translator/src/test/kotlin/tests/input/while_2.txt b/translator/src/test/kotlin/tests/input/while_2.txt new file mode 100644 index 00000000000..2bcd26940ab --- /dev/null +++ b/translator/src/test/kotlin/tests/input/while_2.txt @@ -0,0 +1 @@ +while_test_2(77) \ No newline at end of file diff --git a/translator/src/test/kotlin/tests/output/while_2.txt b/translator/src/test/kotlin/tests/output/while_2.txt new file mode 100644 index 00000000000..efee1f88bb8 --- /dev/null +++ b/translator/src/test/kotlin/tests/output/while_2.txt @@ -0,0 +1 @@ +78 \ No newline at end of file diff --git a/translator/src/test/kotlin/tests/source/while_2.kt b/translator/src/test/kotlin/tests/source/while_2.kt new file mode 100644 index 00000000000..41441e899a9 --- /dev/null +++ b/translator/src/test/kotlin/tests/source/while_2.kt @@ -0,0 +1,7 @@ +fun while_test_2(x: Int): Int { + var a = x + while (2 < 3) { + a = x + 1 + return a + } +} \ No newline at end of file