translator: fix conflict name of struct, refactor StructCodegen
This commit is contained in:
@@ -35,7 +35,7 @@ abstract class BlockCodegen(val state: TranslationState, val variableManager: Va
|
||||
if (isBlock) {
|
||||
expressionWalker(expr, breakLabel, scopeDepth)
|
||||
} else {
|
||||
var result = evaluateExpression(expr, scopeDepth) ?: throw UnexpectedException(expr!!.text)
|
||||
var result = evaluateExpression(expr, scopeDepth) ?: throw UnexpectedException("Can't evaluate expression " + expr!!.text)
|
||||
when (result) {
|
||||
is LLVMVariable -> {
|
||||
if (result.pointer == 1 && result.type !is LLVMReferenceType) {
|
||||
@@ -57,12 +57,12 @@ abstract class BlockCodegen(val state: TranslationState, val variableManager: Va
|
||||
|
||||
private fun expressionWalker(expr: PsiElement?, breakLabel: LLVMLabel?, scopeDepth: Int) {
|
||||
when (expr) {
|
||||
is KtBlockExpression -> expressionWalker(expr.firstChild, breakLabel, scopeDepth + 1)
|
||||
is KtBlockExpression -> expressionWalker(expr.lBrace, breakLabel, scopeDepth + 1)
|
||||
is KtProperty -> evaluateValExpression(expr, scopeDepth)
|
||||
is KtPostfixExpression -> evaluatePostfixExpression(expr, scopeDepth)
|
||||
is KtBinaryExpression -> evaluateBinaryExpression(expr, scopeDepth)
|
||||
is KtCallExpression -> evaluateCallExpression(expr, scopeDepth)
|
||||
is KtDoWhileExpression -> evaluateDoWhileExpression(expr.firstChild, scopeDepth + 1)
|
||||
is KtDoWhileExpression -> evaluateDoWhileExpression(expr, scopeDepth + 1)
|
||||
is KtBreakExpression -> evaluateBreakExpression(breakLabel!!)
|
||||
is KtDotQualifiedExpression -> evaluateDotExpression(expr, scopeDepth)
|
||||
is KtWhenExpression -> evaluateWhenExpression(expr, scopeDepth)
|
||||
@@ -77,19 +77,17 @@ abstract class BlockCodegen(val state: TranslationState, val variableManager: Va
|
||||
expressionWalker(expr.getNextSiblingIgnoringWhitespaceAndComments(), breakLabel, scopeDepth)
|
||||
}
|
||||
|
||||
private fun evaluateBreakExpression(breakLabel: LLVMLabel) {
|
||||
codeBuilder.addUnconditionalJump(breakLabel)
|
||||
}
|
||||
private fun evaluateBreakExpression(breakLabel: LLVMLabel) =
|
||||
codeBuilder.addUnconditionalJump(breakLabel)
|
||||
|
||||
private fun evaluateDoWhileExpression(expr: KtDoWhileExpression, scopeDepth: Int) =
|
||||
executeWhileBlock(expr.condition!!, expr.body!!, scopeDepth, checkConditionBeforeExecute = false)
|
||||
|
||||
private fun evaluateDoWhileExpression(element: PsiElement, scopeDepth: Int) {
|
||||
val expr = element.context as KtDoWhileExpression
|
||||
executeWhileBlock(expr.condition!!, expr.body!!, scopeDepth, checkConditionBeforeExecute = false)
|
||||
}
|
||||
|
||||
fun evaluateExpression(expr: PsiElement?, scopeDepth: Int): LLVMSingleValue? {
|
||||
return when (expr) {
|
||||
is KtBlockExpression -> {
|
||||
expressionWalker(expr.firstChild, breakLabel = null, scopeDepth = scopeDepth + 1)
|
||||
expressionWalker(expr.lBrace, breakLabel = null, scopeDepth = scopeDepth + 1)
|
||||
return null
|
||||
}
|
||||
is KtBinaryExpression -> evaluateBinaryExpression(expr, scopeDepth)
|
||||
@@ -118,7 +116,7 @@ abstract class BlockCodegen(val state: TranslationState, val variableManager: Va
|
||||
val targetCall = state.bindingContext.get(BindingContext.CALL, expr)
|
||||
val names = parseValueArguments(targetCall!!.valueArguments, scopeDepth)
|
||||
val args = codeBuilder.loadArgsIfRequired(names, constructorArguments)
|
||||
return evaluateConstructorCallExpression(LLVMVariable(structCodegen.fullName + LLVMType.mangleFunctionArguments(names), structCodegen.type, scope = LLVMVariableScope()), args)
|
||||
return evaluateConstructorCallExpression(LLVMVariable(structCodegen.structName + LLVMType.mangleFunctionArguments(names), structCodegen.type, scope = LLVMVariableScope()), args)
|
||||
}
|
||||
|
||||
private fun evaluateThisExpression(): LLVMSingleValue? =
|
||||
@@ -169,8 +167,8 @@ abstract class BlockCodegen(val state: TranslationState, val variableManager: Va
|
||||
codeBuilder.addUnconditionalJump(endLabel)
|
||||
|
||||
codeBuilder.markWithLabel(elseLabel)
|
||||
val right = evaluateDotBody(receiver, selector!!, scopeDepth)
|
||||
val rightLoaded = codeBuilder.loadAndGetVariable(right as LLVMVariable)
|
||||
val right = evaluateDotBody(receiver, selector!!, scopeDepth) as LLVMVariable
|
||||
val rightLoaded = codeBuilder.loadAndGetVariable(right)
|
||||
codeBuilder.storeVariable(result, rightLoaded)
|
||||
codeBuilder.addUnconditionalJump(endLabel)
|
||||
|
||||
@@ -234,7 +232,7 @@ abstract class BlockCodegen(val state: TranslationState, val variableManager: Va
|
||||
|
||||
val clazz = resolveCodegen(receiverExpr)
|
||||
?: return evaluateExtensionExpression(receiverExpr, receiver, selectorExpr as? KtCallExpression
|
||||
?: throw UnexpectedException(selectorExpr.text), scopeDepth)
|
||||
?: throw UnexpectedException("Failed evaluate dot expression: " + selectorExpr.text), scopeDepth)
|
||||
return evaluateClassScopedDotExpression(clazz, selectorExpr, scopeDepth, receiver)
|
||||
}
|
||||
|
||||
@@ -281,11 +279,19 @@ abstract class BlockCodegen(val state: TranslationState, val variableManager: Va
|
||||
val field = clazz.fieldsIndex[selectorName]
|
||||
|
||||
if (field != null) {
|
||||
val result = codeBuilder.getNewVariable(field.type, pointer = field.pointer + 1)
|
||||
codeBuilder.loadClassField(result, receiver, field.offset)
|
||||
return result
|
||||
return evaluateClassField(receiver, field)
|
||||
} else {
|
||||
return evaluateMemberMethod(receiver, selectorName, clazz, scopeDepth, call)
|
||||
}
|
||||
}
|
||||
|
||||
fun evaluateClassField(receiver: LLVMVariable, field: LLVMClassVariable): LLVMVariable {
|
||||
val result = codeBuilder.getNewVariable(field.type, pointer = field.pointer + 1)
|
||||
codeBuilder.loadClassField(result, receiver, field.offset)
|
||||
return result
|
||||
}
|
||||
|
||||
fun evaluateMemberMethod(receiver: LLVMVariable, selectorName: String, clazz: StructCodegen, scopeDepth: Int, call: PsiElement? = null): LLVMSingleValue? {
|
||||
(call as? KtCallExpression) ?: throw UnexpectedException("$receiver:$selectorName")
|
||||
val resolvedCall = (call as KtCallExpression).getCall(state.bindingContext)!!.getResolvedCallWithAssert(state.bindingContext)
|
||||
val functionDescriptor = resolvedCall.candidateDescriptor
|
||||
@@ -363,7 +369,7 @@ abstract class BlockCodegen(val state: TranslationState, val variableManager: Va
|
||||
|
||||
return evaluateFunctionCallExpression(LLVMVariable(methodName, returnType, scope = LLVMVariableScope()), callArgs)
|
||||
}
|
||||
else -> throw IllegalStateException("Unknown array access method")
|
||||
else -> throw UnexpectedException("Unknown array access method")
|
||||
}
|
||||
}
|
||||
else -> {
|
||||
@@ -386,7 +392,7 @@ abstract class BlockCodegen(val state: TranslationState, val variableManager: Va
|
||||
((expr is KtNameReferenceExpression) && (classScope != null)) -> evaluateNameReferenceExpression(expr, classScope.parentCodegen!!)
|
||||
else -> {
|
||||
val clazz = classScope ?: resolveCodegen(expr)
|
||||
val receiver = if (clazz != null) variableManager[clazz.fullName] ?: variableManager["this"] else variableManager["this"]
|
||||
val receiver = if (clazz != null) variableManager[clazz.structName] ?: variableManager["this"] else variableManager["this"]
|
||||
targetName ?: throw RuntimeException(expr.firstChild.text)
|
||||
evaluateMemberMethodOrField(receiver ?: throw UnexpectedException(targetName), targetName, topLevel)
|
||||
}
|
||||
@@ -398,7 +404,7 @@ abstract class BlockCodegen(val state: TranslationState, val variableManager: Va
|
||||
val fieldName = state.bindingContext.get(BindingContext.REFERENCE_TARGET, expr)!!.name.toString()
|
||||
val companionObject = (classScope as ClassCodegen).companionObjectCodegen ?: throw UnexpectedException(expr.text)
|
||||
val field = companionObject.fieldsIndex[fieldName] ?: return null
|
||||
val receiver = variableManager[companionObject.fullName]!!
|
||||
val receiver = variableManager[companionObject.structName]!!
|
||||
val result = codeBuilder.getNewVariable(field.type, pointer = 1)
|
||||
|
||||
codeBuilder.loadClassField(result, receiver, field.offset)
|
||||
@@ -453,7 +459,7 @@ abstract class BlockCodegen(val state: TranslationState, val variableManager: Va
|
||||
val descriptor = state.classes[targetFunctionName] ?: classScope ?: return null
|
||||
val detectedConstructor = LLVMType.mangleFunctionTypes(functionArguments)
|
||||
val args = codeBuilder.loadArgsIfRequired(names, descriptor.constructorFields[detectedConstructor]!!)
|
||||
return evaluateConstructorCallExpression(LLVMVariable(descriptor.fullName + detectedConstructor, descriptor.type, scope = LLVMVariableScope()), args)
|
||||
return evaluateConstructorCallExpression(LLVMVariable(descriptor.structName + detectedConstructor, descriptor.type, scope = LLVMVariableScope()), args)
|
||||
}
|
||||
|
||||
val localFunction = variableManager[targetFunctionName]
|
||||
@@ -464,11 +470,10 @@ abstract class BlockCodegen(val state: TranslationState, val variableManager: Va
|
||||
}
|
||||
|
||||
if (classScope != null) {
|
||||
val methodShortName = function
|
||||
if (classScope.methods.containsKey(methodShortName)) {
|
||||
val descriptor = classScope.methods[methodShortName]!!
|
||||
if (classScope.methods.containsKey(function)) {
|
||||
val descriptor = classScope.methods[function]!!
|
||||
val parentDescriptor = descriptor.parentCodegen!!
|
||||
val receiver = variableManager[parentDescriptor.fullName] ?: throw UnexpectedException(parentDescriptor.fullName)
|
||||
val receiver = variableManager[parentDescriptor.structName] ?: throw UnexpectedException(parentDescriptor.structName)
|
||||
val methodFullName = descriptor.name
|
||||
val returnType = descriptor.returnType!!.type
|
||||
val loadedArgs = codeBuilder.loadArgsIfRequired(names, descriptor.args)
|
||||
@@ -482,7 +487,7 @@ abstract class BlockCodegen(val state: TranslationState, val variableManager: Va
|
||||
val nestedConstructor = classScope?.nestedClasses?.get(expr.calleeExpression!!.text)
|
||||
if (nestedConstructor != null) {
|
||||
val args = codeBuilder.loadArgsIfRequired(names, nestedConstructor.constructorFields[nestedConstructor.primaryConstructorIndex]!!)
|
||||
return evaluateConstructorCallExpression(LLVMVariable(nestedConstructor.fullName, nestedConstructor.type, scope = LLVMVariableScope()), args)
|
||||
return evaluateConstructorCallExpression(LLVMVariable(nestedConstructor.structName, nestedConstructor.type, scope = LLVMVariableScope()), args)
|
||||
}
|
||||
|
||||
val containingClass = resolveContainingClass(expr) ?: return null
|
||||
@@ -491,8 +496,8 @@ abstract class BlockCodegen(val state: TranslationState, val variableManager: Va
|
||||
|
||||
if (caller != null) {
|
||||
args.add(caller)
|
||||
} else if (variableManager[containingClass.fullName] != null) {
|
||||
args.add(variableManager[containingClass.fullName]!!)
|
||||
} else if (variableManager[containingClass.structName] != null) {
|
||||
args.add(variableManager[containingClass.structName]!!)
|
||||
} else {
|
||||
args.add(variableManager["this"]!!)
|
||||
}
|
||||
@@ -748,7 +753,7 @@ abstract class BlockCodegen(val state: TranslationState, val variableManager: Va
|
||||
val descriptor = state.classes["kotlin.ranges.IntRange"]
|
||||
val arguments = listOf(firstOp, secondNativeOp)
|
||||
val detectedConstructor = LLVMType.mangleFunctionTypes(arguments.map { it.type })
|
||||
val result = evaluateConstructorCallExpression(LLVMVariable(descriptor!!.fullName + detectedConstructor, descriptor.type, scope = LLVMVariableScope()), arguments)
|
||||
val result = evaluateConstructorCallExpression(LLVMVariable(descriptor!!.structName + detectedConstructor, descriptor.type, scope = LLVMVariableScope()), arguments)
|
||||
return LLVMExpression(result!!.type, "load ${descriptor.type}** $result, align ${descriptor.type.align}", pointer = 1)
|
||||
}
|
||||
else -> throw UnsupportedOperationException("Unknown binary operator: $operator(${firstNativeOp.type}, ${secondNativeOp.type})")
|
||||
|
||||
@@ -7,10 +7,8 @@ import org.jetbrains.kotlin.psi.KtParameter
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
import org.kotlinnative.translator.exceptions.TranslationException
|
||||
import org.kotlinnative.translator.llvm.LLVMBuilder
|
||||
import org.kotlinnative.translator.llvm.LLVMVariable
|
||||
import org.kotlinnative.translator.llvm.types.LLVMReferenceType
|
||||
import org.kotlinnative.translator.llvm.types.LLVMType
|
||||
import java.util.*
|
||||
|
||||
class ClassCodegen(state: TranslationState,
|
||||
variableManager: VariableManager,
|
||||
@@ -30,7 +28,6 @@ class ClassCodegen(state: TranslationState,
|
||||
|
||||
init {
|
||||
type = LLVMReferenceType(structName, "class", align = TranslationState.pointerAlign, size = TranslationState.pointerSize, byRef = true)
|
||||
|
||||
descriptor = state.bindingContext.get(BindingContext.CLASS, clazz) ?: throw TranslationException("Can't receive descriptor of class " + clazz.name)
|
||||
|
||||
annotation = descriptor.kind == ClassKind.ANNOTATION_CLASS
|
||||
@@ -43,15 +40,10 @@ class ClassCodegen(state: TranslationState,
|
||||
if (annotation) {
|
||||
return
|
||||
}
|
||||
val currentConstructorFields = ArrayList<LLVMVariable>()
|
||||
for (field in parameters) {
|
||||
val item = resolveType(field, state.bindingContext.get(BindingContext.TYPE, field.typeReference)!!)
|
||||
item.offset = fields.size
|
||||
|
||||
currentConstructorFields.add(item)
|
||||
fields.add(item)
|
||||
fieldsIndex[item.label] = item
|
||||
}
|
||||
val currentConstructorFields = parameters.mapIndexed { i, it -> resolveType(it, state.bindingContext.get(BindingContext.TYPE, it.typeReference)!!, fields.size + i) }
|
||||
fields.addAll(currentConstructorFields)
|
||||
fieldsIndex.putAll(currentConstructorFields.map { Pair(it.label, it) })
|
||||
primaryConstructorIndex = LLVMType.mangleFunctionArguments(currentConstructorFields)
|
||||
constructorFields.put(primaryConstructorIndex!!, currentConstructorFields)
|
||||
}
|
||||
@@ -71,8 +63,7 @@ class ClassCodegen(state: TranslationState,
|
||||
super.prepareForGenerate()
|
||||
nestedClasses.forEach { x, classCodegen -> classCodegen.prepareForGenerate() }
|
||||
|
||||
val companionObjectDescriptor = descriptor.companionObjectDescriptor
|
||||
if (companionObjectDescriptor != null) {
|
||||
if (descriptor.companionObjectDescriptor != null) {
|
||||
val companionObject = clazz.getCompanionObjects().first()
|
||||
companionObjectCodegen = ObjectCodegen(state, variableManager, companionObject, codeBuilder, this)
|
||||
companionObjectCodegen!!.prepareForGenerate()
|
||||
@@ -86,10 +77,7 @@ class ClassCodegen(state: TranslationState,
|
||||
|
||||
super.generate()
|
||||
nestedClasses.forEach { x, classCodegen -> classCodegen.generate() }
|
||||
|
||||
if (companionObjectCodegen != null) {
|
||||
companionObjectCodegen!!.generate()
|
||||
}
|
||||
companionObjectCodegen?.generate()
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -14,13 +14,14 @@ class ObjectCodegen(state: TranslationState,
|
||||
codeBuilder: LLVMBuilder,
|
||||
parentCodegen: StructCodegen? = null) :
|
||||
StructCodegen(state, variableManager, objectDeclaration, codeBuilder, parentCodegen) {
|
||||
|
||||
override var size: Int = 0
|
||||
override val structName: String = objectDeclaration.fqName?.asString()!!
|
||||
override val type: LLVMReferenceType
|
||||
|
||||
init {
|
||||
type = LLVMReferenceType(structName, "class", align = TranslationState.pointerAlign, size = TranslationState.pointerSize, byRef = true)
|
||||
primaryConstructorIndex = LLVMType.mangleFunctionArguments(emptyList())
|
||||
primaryConstructorIndex = LLVMType.mangleFunctionArguments(emptyList())
|
||||
constructorFields.put(primaryConstructorIndex!!, arrayListOf())
|
||||
}
|
||||
|
||||
@@ -32,15 +33,12 @@ class ObjectCodegen(state: TranslationState,
|
||||
|
||||
super.prepareForGenerate()
|
||||
|
||||
val classInstance = LLVMVariable("object.instance.$fullName", type, objectDeclaration.name, LLVMVariableScope(), pointer = 1)
|
||||
val classInstance = LLVMVariable("object.instance.$structName", type, objectDeclaration.name, LLVMVariableScope(), pointer = 1)
|
||||
codeBuilder.addGlobalInitialize(classInstance, fields, initializedFields.map {
|
||||
val type = state.bindingContext.get(BindingContext.EXPRESSION_TYPE_INFO, it.value)!!.type!!
|
||||
Pair(it.key, state.bindingContext.get(BindingContext.COMPILE_TIME_VALUE, it.value)!!.getValue(type).toString())
|
||||
}.toMap(), type)
|
||||
variableManager.addGlobalVariable(fullName, classInstance)
|
||||
variableManager.addGlobalVariable(structName, classInstance)
|
||||
}
|
||||
|
||||
override fun generate() {
|
||||
super.generate()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,5 @@
|
||||
package org.kotlinnative.translator
|
||||
|
||||
import com.intellij.psi.PsiElement
|
||||
import org.jetbrains.kotlin.lexer.KtTokens
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
@@ -23,17 +22,14 @@ abstract class StructCodegen(val state: TranslationState,
|
||||
val fieldsIndex = HashMap<String, LLVMClassVariable>()
|
||||
val nestedClasses = HashMap<String, ClassCodegen>()
|
||||
val enumFields = HashMap<String, LLVMVariable>()
|
||||
|
||||
val constructorFields = HashMap<String, ArrayList<LLVMVariable>>()
|
||||
val constructorFields = HashMap<String, List<LLVMVariable>>()
|
||||
var primaryConstructorIndex: String? = null
|
||||
val initializedFields = HashMap<LLVMVariable, KtExpression>()
|
||||
var methods = HashMap<String, FunctionCodegen>()
|
||||
|
||||
abstract val type: LLVMReferenceType
|
||||
abstract var size: Int
|
||||
var methods = HashMap<String, FunctionCodegen>()
|
||||
abstract val structName: String
|
||||
val fullName: String
|
||||
get() = structName
|
||||
|
||||
open fun prepareForGenerate() {
|
||||
generateStruct()
|
||||
@@ -50,13 +46,13 @@ abstract class StructCodegen(val state: TranslationState,
|
||||
size = 0
|
||||
|
||||
for (item in fields) {
|
||||
val currentFieldType = if (item.pointer > 0) TranslationState.pointerSize else item.type.size
|
||||
alignmentRemainder -= (alignmentRemainder % currentFieldType)
|
||||
if (alignmentRemainder < currentFieldType) {
|
||||
val currentFieldSize = if (item.pointer > 0) TranslationState.pointerAlign else item.type.align
|
||||
alignmentRemainder -= (alignmentRemainder % currentFieldSize)
|
||||
if (alignmentRemainder < currentFieldSize) {
|
||||
size += classAlignment
|
||||
alignmentRemainder = classAlignment - currentFieldType
|
||||
alignmentRemainder = classAlignment - currentFieldSize
|
||||
} else {
|
||||
alignmentRemainder -= currentFieldType
|
||||
alignmentRemainder -= currentFieldSize
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -64,47 +60,39 @@ abstract class StructCodegen(val state: TranslationState,
|
||||
open fun generate() {
|
||||
generateEnumFields()
|
||||
generatePrimaryConstructor()
|
||||
for (secondaryConstructor in classOrObject.getSecondaryConstructors()) {
|
||||
generateSecondaryConstructor(secondaryConstructor)
|
||||
}
|
||||
classOrObject.getSecondaryConstructors().map { generateSecondaryConstructor(it) }
|
||||
|
||||
val classVal = LLVMVariable("classvariable.this", type, pointer = if (type.isPrimitive) 0 else 1)
|
||||
variableManager.addVariable("this", classVal, 0)
|
||||
|
||||
for (function in methods.values) {
|
||||
function.generate(classVal)
|
||||
}
|
||||
methods.values.map { it.generate(classVal) }
|
||||
}
|
||||
|
||||
fun generateInnerFields(declarations: List<KtDeclaration>) {
|
||||
var offset = fields.size
|
||||
|
||||
for (declaration in declarations) {
|
||||
when (declaration) {
|
||||
is KtProperty -> {
|
||||
val ktType = state.bindingContext.get(BindingContext.TYPE, declaration.typeReference)
|
||||
?: state.bindingContext.get(BindingContext.VARIABLE, declaration)!!.type
|
||||
val field = resolveType(declaration, ktType)
|
||||
field.offset = offset
|
||||
offset++
|
||||
val field = resolveType(declaration, ktType, fields.size)
|
||||
|
||||
if (declaration.initializer != null) {
|
||||
initializedFields.put(field, declaration.initializer!!)
|
||||
}
|
||||
|
||||
fields.add(field)
|
||||
fieldsIndex[field.label] = field
|
||||
}
|
||||
is KtEnumEntry -> {
|
||||
val name = declaration.name!!
|
||||
val field = LLVMVariable("class.$fullName.$name", type, scope = LLVMVariableScope(), pointer = 2)
|
||||
val field = LLVMVariable("class.$structName.$name", type, scope = LLVMVariableScope(), pointer = 2)
|
||||
enumFields.put(name, field)
|
||||
}
|
||||
is KtClass -> {
|
||||
is KtClass ->
|
||||
nestedClasses.put(declaration.fqName!!.asString(),
|
||||
ClassCodegen(state,
|
||||
VariableManager(state.globalVariableCollection),
|
||||
declaration, codeBuilder, this))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -122,20 +110,17 @@ abstract class StructCodegen(val state: TranslationState,
|
||||
val enumField = enumFields[name]!!
|
||||
|
||||
codeBuilder.defineGlobalVariable(field, codeBuilder.makeStructInitializer(constructorFields[primaryConstructorIndex]!!, arguments))
|
||||
codeBuilder.defineGlobalVariable(LLVMVariable(enumField.label, enumField.type, enumField.kotlinName, enumField.scope, enumField.pointer - 1), "$field")
|
||||
codeBuilder.defineGlobalVariable(LLVMVariable(enumField.label, enumField.type, enumField.kotlinName, enumField.scope, enumField.pointer - 1), field.toString())
|
||||
}
|
||||
}
|
||||
|
||||
private fun generateStruct() {
|
||||
codeBuilder.createClass(fullName, fields)
|
||||
}
|
||||
private fun generateStruct() =
|
||||
codeBuilder.createClass(structName, fields)
|
||||
|
||||
private fun generateSecondaryConstructor(secondaryConstructor: KtSecondaryConstructor) {
|
||||
val thisCall = secondaryConstructor.getDelegationCall().calleeExpression
|
||||
val descriptor = state.bindingContext.get(BindingContext.CONSTRUCTOR, secondaryConstructor)
|
||||
|
||||
val argFields = ArrayList<LLVMVariable>()
|
||||
|
||||
val classVal = LLVMVariable("classvariable.this", type, pointer = 1)
|
||||
variableManager.addVariable("this", classVal, 0)
|
||||
|
||||
@@ -143,17 +128,15 @@ abstract class StructCodegen(val state: TranslationState,
|
||||
LLVMInstanceOfStandardType(it.fqNameSafe.convertToNativeName(), it.type, state = state)
|
||||
}
|
||||
|
||||
argFields.add(classVal)
|
||||
val argFields = mutableListOf(classVal)
|
||||
argFields.addAll(secondaryConstructorArguments)
|
||||
val currentConstructorIndex = LLVMType.mangleFunctionArguments(secondaryConstructorArguments)
|
||||
constructorFields.put(currentConstructorIndex, argFields)
|
||||
codeBuilder.addLLVMCodeToLocalPlace(LLVMFunctionDescriptor(fullName + currentConstructorIndex, argFields, LLVMVoidType()))
|
||||
codeBuilder.addLLVMCodeToLocalPlace(LLVMFunctionDescriptor(structName + currentConstructorIndex, argFields, LLVMVoidType()))
|
||||
|
||||
codeBuilder.addStartExpression()
|
||||
|
||||
for (variable in secondaryConstructorArguments) {
|
||||
variableManager.addVariable(variable.label, variable, 2)
|
||||
}
|
||||
secondaryConstructorArguments.map { variableManager.addVariable(it.label, it, 2) }
|
||||
|
||||
val blockCodegen = object : BlockCodegen(state, variableManager, codeBuilder) {}
|
||||
val mainConstructorThis = blockCodegen.evaluateConstructorDelegationReferenceExpression(thisCall!!, this, secondaryConstructorArguments, 1) as LLVMVariable
|
||||
@@ -166,14 +149,13 @@ abstract class StructCodegen(val state: TranslationState,
|
||||
}
|
||||
|
||||
private fun generatePrimaryConstructor() {
|
||||
val argFields = ArrayList<LLVMVariable>()
|
||||
val classVal = LLVMVariable("classvariable.this", type, pointer = 1)
|
||||
variableManager.addVariable("this", classVal, 0)
|
||||
|
||||
argFields.add(classVal)
|
||||
val argFields = mutableListOf(classVal)
|
||||
argFields.addAll(constructorFields[primaryConstructorIndex]!!)
|
||||
|
||||
codeBuilder.addLLVMCodeToLocalPlace(LLVMFunctionDescriptor(fullName + primaryConstructorIndex, argFields, LLVMVoidType()))
|
||||
codeBuilder.addLLVMCodeToLocalPlace(LLVMFunctionDescriptor(structName + primaryConstructorIndex, argFields, LLVMVoidType()))
|
||||
|
||||
codeBuilder.addStartExpression()
|
||||
generateLoadArguments(classVal)
|
||||
@@ -235,7 +217,7 @@ abstract class StructCodegen(val state: TranslationState,
|
||||
codeBuilder.memcpy(castedDst, castedSrc, size)
|
||||
}
|
||||
|
||||
protected fun resolveType(field: KtNamedDeclaration, ktType: KotlinType): LLVMClassVariable {
|
||||
protected fun resolveType(field: KtNamedDeclaration, ktType: KotlinType, offset: Int): LLVMClassVariable {
|
||||
val annotations = parseFieldAnnotations(field)
|
||||
val fieldName = state.bindingContext.get(BindingContext.VALUE_PARAMETER, field as?KtParameter)?.fqNameSafe?.convertToNativeName()
|
||||
?: field.fqName?.asString() ?: field.name!!
|
||||
@@ -243,9 +225,8 @@ abstract class StructCodegen(val state: TranslationState,
|
||||
val result = LLVMInstanceOfStandardType(fieldName, ktType, LLVMRegisterScope(), state = state)
|
||||
|
||||
if (result.type is LLVMReferenceType) {
|
||||
val type = result.type
|
||||
type.prefix = "class"
|
||||
type.byRef = true
|
||||
result.type.prefix = "class"
|
||||
result.type.byRef = true
|
||||
}
|
||||
|
||||
if (state.classes.containsKey(field.name!!)) {
|
||||
@@ -256,30 +237,17 @@ abstract class StructCodegen(val state: TranslationState,
|
||||
result.pointer = 0
|
||||
}
|
||||
|
||||
return LLVMClassVariable(result.label, result.type, result.pointer)
|
||||
return LLVMClassVariable(result.label, result.type, result.pointer, offset)
|
||||
}
|
||||
|
||||
private fun parseFieldAnnotations(field: KtNamedDeclaration): Set<String> {
|
||||
val result = HashSet<String>()
|
||||
private fun parseFieldAnnotations(field: KtNamedDeclaration): Set<String> =
|
||||
field.annotationEntries.map { state.bindingContext.get(BindingContext.ANNOTATION, it)?.type.toString() }.toHashSet()
|
||||
|
||||
for (annotation in field.annotationEntries) {
|
||||
val annotationDescriptor = state.bindingContext.get(BindingContext.ANNOTATION, annotation)
|
||||
val type = annotationDescriptor?.type.toString()
|
||||
|
||||
result.add(type)
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
protected fun genClassInitializers() {
|
||||
for (init in classOrObject.getAnonymousInitializers()) {
|
||||
val blockCodegen = object : BlockCodegen(state, variableManager, codeBuilder) {
|
||||
fun generate(expr: PsiElement?) {
|
||||
evaluateCodeBlock(expr, scopeDepth = topLevel)
|
||||
protected fun genClassInitializers() =
|
||||
classOrObject.getAnonymousInitializers().map {
|
||||
object : BlockCodegen(state, variableManager, codeBuilder) {
|
||||
fun generate() = evaluateCodeBlock(it.body, scopeDepth = topLevel)
|
||||
}
|
||||
}
|
||||
blockCodegen.generate(init.body)
|
||||
}
|
||||
}
|
||||
}
|
||||
}.map { it.generate() }
|
||||
|
||||
}
|
||||
@@ -101,4 +101,4 @@ fun analyze(environment: KotlinCoreEnvironment): AnalysisResult? {
|
||||
})
|
||||
|
||||
return if (analyzer.hasErrors()) null else analyzer.analysisResult
|
||||
}
|
||||
}
|
||||
@@ -6,4 +6,5 @@ class LLVMCall(val returnType: LLVMType, val name: String, val arguments: Collec
|
||||
|
||||
override fun toString(): String =
|
||||
"call $returnType $name(${arguments.joinToString { "${it.pointedType} ${it.toString()}" }})"
|
||||
}
|
||||
|
||||
}
|
||||
@@ -3,4 +3,4 @@ package org.kotlinnative.translator.llvm
|
||||
import org.kotlinnative.translator.llvm.types.LLVMType
|
||||
|
||||
|
||||
class LLVMClassVariable(label: String, type: LLVMType, pointer: Int = 0, var offset: Int = 0) : LLVMVariable(label, type, pointer = pointer)
|
||||
class LLVMClassVariable(label: String, type: LLVMType, pointer: Int = 0, var offset: Int = 0) : LLVMVariable(label, type, pointer = pointer)
|
||||
@@ -8,5 +8,4 @@ class LLVMVariableScope : LLVMScope() {
|
||||
|
||||
class LLVMRegisterScope : LLVMScope() {
|
||||
override fun toString() = "%"
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user