From 71ad20ddab01fed69ce23b7d3fe64aac448d47b0 Mon Sep 17 00:00:00 2001 From: e5l Date: Thu, 11 Aug 2016 09:52:11 +0300 Subject: [PATCH] translator: fix enum naming and location resolve --- .../kotlinnative/translator/BlockCodegen.kt | 40 ++++++++++++++----- .../kotlinnative/translator/ObjectCodegen.kt | 4 +- .../kotlinnative/translator/StructCodegen.kt | 4 ++ .../translator/llvm/LLVMBuilder.kt | 2 +- 4 files changed, 36 insertions(+), 14 deletions(-) diff --git a/translator/src/main/kotlin/org/kotlinnative/translator/BlockCodegen.kt b/translator/src/main/kotlin/org/kotlinnative/translator/BlockCodegen.kt index ede35f2888e..4a87f140965 100644 --- a/translator/src/main/kotlin/org/kotlinnative/translator/BlockCodegen.kt +++ b/translator/src/main/kotlin/org/kotlinnative/translator/BlockCodegen.kt @@ -9,6 +9,7 @@ import org.jetbrains.kotlin.descriptors.impl.PropertyDescriptorImpl import org.jetbrains.kotlin.lexer.KtTokens import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.psi.psiUtil.getNextSiblingIgnoringWhitespaceAndComments +import org.jetbrains.kotlin.psi.psiUtil.getQualifiedExpressionForReceiver import org.jetbrains.kotlin.resolve.BindingContext import org.jetbrains.kotlin.resolve.calls.callUtil.getFunctionResolvedCallWithAssert import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCallWithAssert @@ -172,7 +173,6 @@ abstract class BlockCodegen(val state: TranslationState, val variableManager: Va private fun evaluateDotBody(receiverExpr: KtExpression, selectorExpr: KtExpression, scopeDepth: Int): LLVMSingleValue? { val receiverName = receiverExpr.text - var receiver = when (receiverExpr) { is KtCallExpression, is KtBinaryExpression, @@ -206,10 +206,15 @@ abstract class BlockCodegen(val state: TranslationState, val variableManager: Va } } - val location = receiverExpr.getType(state.bindingContext)?.getSubtypesPredicate()?.toString()?.split(".") - val classReference = LLVMReferenceType(location?.last() ?: receiverName, "class") - if (location != null) { - classReference.location.addAll(location.dropLast(1)) + val type = state.bindingContext.get(BindingContext.EXPRESSION_TYPE_INFO, receiverExpr)?.type + ?: receiverExpr.getType(state.bindingContext) + ?: receiverExpr.getQualifiedExpressionForReceiver()?.getType(state.bindingContext) + + val path = type?.getSubtypesPredicate()?.toString()?.split(".") + val classReference = LLVMReferenceType(path?.last() ?: receiverName, "class") + + if (path != null) { + classReference.location.addAll(path.dropLast(1)) } val clazz = resolveClassOrObjectLocation(classReference) ?: return evaluateExtensionExpression(receiverExpr, selectorExpr as KtCallExpression, scopeDepth) @@ -219,6 +224,10 @@ abstract class BlockCodegen(val state: TranslationState, val variableManager: Va private fun evaluateExtensionExpression(receiver: KtExpression, selector: KtCallExpression, scopeDepth: Int): LLVMSingleValue? { val receiverType = state.bindingContext.get(BindingContext.EXPRESSION_TYPE_INFO, receiver) val standardType = LLVMMapStandardType(receiverType!!.type!!) +// if (standardType is LLVMReferenceType) { +// standardType.location.addAll(receiverType.type!!.getSubtypesPredicate().toString().split(".").dropLast(1)) +// } + val function = selector.firstChild.firstChild.text val names = parseArgList(selector, scopeDepth) val type = if (names.size > 0) "_${names.joinToString(separator = "_", transform = { it.type!!.mangle() })}" else "" @@ -241,9 +250,9 @@ abstract class BlockCodegen(val state: TranslationState, val variableManager: Va else -> throw UnsupportedOperationException() } - private fun evaluateNameReferenceExpression(expr: KtNameReferenceExpression, classScope: StructCodegen? = null): LLVMSingleValue? { + private fun evaluateNameReferenceExpression(expr: KtNameReferenceExpression, classScope: StructCodegen): LLVMSingleValue? { val fieldName = state.bindingContext.get(BindingContext.REFERENCE_TARGET, expr)!!.name.toString() - val field = classScope!!.companionFieldsIndex[fieldName] + val field = classScope.companionFieldsIndex[fieldName] val companionObject = classScope.companionFieldsSource[fieldName] val receiver = variableManager[companionObject!!.fullName]!! val result = codeBuilder.getNewVariable(field!!.type, pointer = 1) @@ -345,21 +354,30 @@ abstract class BlockCodegen(val state: TranslationState, val variableManager: Va private fun evaluateReferenceExpression(expr: KtReferenceExpression, scopeDepth: Int, classScope: StructCodegen? = null): LLVMSingleValue? = when { expr is KtArrayAccessExpression -> evaluateArrayAccessExpression(expr, scopeDepth + 1) isEnumClassField(expr) -> resolveEnumClassField(expr) - (expr is KtNameReferenceExpression) && (classScope != null) -> evaluateNameReferenceExpression(expr, classScope.parentCodegen) + (expr is KtNameReferenceExpression) && (classScope != null) -> evaluateNameReferenceExpression(expr, classScope.parentCodegen!!) resolveContainingClass(expr) != null -> evaluateMemberMethodOrField(variableManager["this"]!!, expr.firstChild.text, topLevel) else -> variableManager[expr.firstChild.text] } private fun resolveEnumClassField(expr: KtReferenceExpression): LLVMSingleValue { - return state.classes[expr.getType(state.bindingContext).toString()]!!.enumFields[expr.text]!! + return resolveCodegen(expr)!!.enumFields[expr.text]!! } private fun isEnumClassField(expr: KtReferenceExpression): Boolean { - val name = expr.getType(state.bindingContext)?.toString() ?: return false - val clazz = state.classes[name] ?: return false + val clazz = resolveCodegen(expr) ?: return false return clazz.enumFields.containsKey(expr.text) } + private fun resolveCodegen(expr: KtReferenceExpression): StructCodegen? { + val location = expr.getType(state.bindingContext)?.getSubtypesPredicate()?.toString()?.split(".") ?: return null + val name = location.last() + + val classType = LLVMReferenceType(name, prefix = "class") + classType.location.addAll(location.dropLast(1)) + + return resolveClassOrObjectLocation(classType) + } + private fun evaluateCallExpression(expr: KtCallExpression, scopeDepth: Int, classScope: StructCodegen? = null): LLVMSingleValue? { val names = parseArgList(expr, scopeDepth) val name = expr.firstChild.firstChild.text diff --git a/translator/src/main/kotlin/org/kotlinnative/translator/ObjectCodegen.kt b/translator/src/main/kotlin/org/kotlinnative/translator/ObjectCodegen.kt index 3edb7fc5043..99aa2f6566e 100644 --- a/translator/src/main/kotlin/org/kotlinnative/translator/ObjectCodegen.kt +++ b/translator/src/main/kotlin/org/kotlinnative/translator/ObjectCodegen.kt @@ -34,8 +34,8 @@ class ObjectCodegen(state: TranslationState, override fun generate() { super.generate() - val classInstance = LLVMVariable("object.instance.$structName", type, objectDeclaration.name, LLVMVariableScope(), pointer = 1) - codeBuilder.addGlobalIntialize(classInstance, type) + val classInstance = LLVMVariable("object.instance.$fullName", type, objectDeclaration.name, LLVMVariableScope(), pointer = 1) + codeBuilder.addGlobalInitialize(classInstance, type) variableManager.addGlobalVariable(fullName, classInstance) } } diff --git a/translator/src/main/kotlin/org/kotlinnative/translator/StructCodegen.kt b/translator/src/main/kotlin/org/kotlinnative/translator/StructCodegen.kt index ef9aefda2ca..3b6cd8a6336 100644 --- a/translator/src/main/kotlin/org/kotlinnative/translator/StructCodegen.kt +++ b/translator/src/main/kotlin/org/kotlinnative/translator/StructCodegen.kt @@ -1,6 +1,7 @@ package org.kotlinnative.translator import com.intellij.psi.PsiElement +import org.jetbrains.kotlin.cfg.pseudocode.getSubtypesPredicate import org.jetbrains.kotlin.descriptors.ClassDescriptor import org.jetbrains.kotlin.lexer.KtTokens import org.jetbrains.kotlin.psi.* @@ -201,6 +202,9 @@ abstract class StructCodegen(val state: TranslationState, val type = result.type as LLVMReferenceType type.prefix = "class" type.byRef = true + + val location = ktType.getSubtypesPredicate().toString().split(".").dropLast(1) + type.location.addAll(location) } if (annotations.contains("Plain")) { 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 412974d8e40..543959f1670 100644 --- a/translator/src/main/kotlin/org/kotlinnative/translator/llvm/LLVMBuilder.kt +++ b/translator/src/main/kotlin/org/kotlinnative/translator/llvm/LLVMBuilder.kt @@ -81,7 +81,7 @@ class LLVMBuilder(val arm: Boolean = false) { globalCode.appendln("$variable = private unnamed_addr constant ${type.fullType()} c\"$value\\00\", align 1") } - fun addGlobalIntialize(target: LLVMVariable, classType: LLVMType) { + fun addGlobalInitialize(target: LLVMVariable, classType: LLVMType) { val code = "$target = internal global $classType zeroinitializer, align ${classType.align}" globalCode.appendln(code) }