diff --git a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/PsiToIr.kt b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/PsiToIr.kt index 882b92d5d45..3b82f92092f 100644 --- a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/PsiToIr.kt +++ b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/PsiToIr.kt @@ -133,6 +133,11 @@ internal fun Context.psiToIr( modulesWithoutDCE .filter(ModuleDescriptor::isFromInteropLibrary) .forEach(irProviderForCEnumsAndCStructs::referenceAllEnumsAndStructsFrom) + + + translator.addPostprocessingStep { + irProviderForCEnumsAndCStructs.generateBodies() + } } } diff --git a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/ir/interop/DescriptorToIrTranslationUtils.kt b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/ir/interop/DescriptorToIrTranslationUtils.kt index f9391b4cda4..3e6228e3679 100644 --- a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/ir/interop/DescriptorToIrTranslationUtils.kt +++ b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/ir/interop/DescriptorToIrTranslationUtils.kt @@ -41,6 +41,12 @@ internal interface DescriptorToIrTranslationMixin { val typeTranslator: TypeTranslator + val postLinkageSteps: MutableList<() -> Unit> + + fun invokePostLinkageSteps() { + postLinkageSteps.forEach { it() } + } + fun KotlinType.toIrType() = typeTranslator.translateType(this) /** diff --git a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/ir/interop/IrProviderForCEnumAndCStructStubs.kt b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/ir/interop/IrProviderForCEnumAndCStructStubs.kt index 3b24ca60afc..a6911a068b6 100644 --- a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/ir/interop/IrProviderForCEnumAndCStructStubs.kt +++ b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/ir/interop/IrProviderForCEnumAndCStructStubs.kt @@ -13,6 +13,7 @@ import org.jetbrains.kotlin.backend.konan.ir.interop.cenum.CEnumClassGenerator import org.jetbrains.kotlin.backend.konan.ir.interop.cenum.CEnumCompanionGenerator import org.jetbrains.kotlin.backend.konan.ir.interop.cenum.CEnumVarClassGenerator import org.jetbrains.kotlin.backend.konan.ir.interop.cstruct.CStructVarClassGenerator +import org.jetbrains.kotlin.backend.konan.ir.interop.cstruct.CStructVarCompanionGenerator import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.ir.declarations.* import org.jetbrains.kotlin.ir.symbols.* @@ -50,8 +51,10 @@ internal class IrProviderForCEnumAndCStructStubs( CEnumVarClassGenerator(context, interopBuiltIns) private val cEnumClassGenerator = CEnumClassGenerator(context, cEnumCompanionGenerator, cEnumVarClassGenerator) + private val cStructCompanionGenerator = + CStructVarCompanionGenerator(context, interopBuiltIns) private val cStructClassGenerator = - CStructVarClassGenerator(context, interopBuiltIns) + CStructVarClassGenerator(context, interopBuiltIns, cStructCompanionGenerator) fun isCEnumOrCStruct(declarationDescriptor: DeclarationDescriptor): Boolean = declarationDescriptor.run { findCEnumDescriptor(interopBuiltIns) ?: findCStructDescriptor(interopBuiltIns) } != null @@ -73,6 +76,19 @@ internal class IrProviderForCEnumAndCStructStubs( } } + /** + * We postpone generation of bodies until IR linkage is complete. + * This way we ensure that all used symbols are resolved. + */ + fun generateBodies() { + cEnumCompanionGenerator.invokePostLinkageSteps() + cEnumByValueFunctionGenerator.invokePostLinkageSteps() + cEnumClassGenerator.invokePostLinkageSteps() + cEnumVarClassGenerator.invokePostLinkageSteps() + cStructClassGenerator.invokePostLinkageSteps() + cStructCompanionGenerator.invokePostLinkageSteps() + } + fun getDeclaration(descriptor: DeclarationDescriptor, idSignature: IdSignature, file: IrFile, symbolKind: BinarySymbolData.SymbolKind): IrSymbolOwner { return symbolTable.run { when (symbolKind) { diff --git a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/ir/interop/cenum/CEnumByValueFunctionGenerator.kt b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/ir/interop/cenum/CEnumByValueFunctionGenerator.kt index ea65b605557..102d4ca4c29 100644 --- a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/ir/interop/cenum/CEnumByValueFunctionGenerator.kt +++ b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/ir/interop/cenum/CEnumByValueFunctionGenerator.kt @@ -32,6 +32,7 @@ internal class CEnumByValueFunctionGenerator( override val irBuiltIns: IrBuiltIns = context.irBuiltIns override val symbolTable: SymbolTable = context.symbolTable override val typeTranslator: TypeTranslator = context.typeTranslator + override val postLinkageSteps: MutableList<() -> Unit> = mutableListOf() fun generateByValueFunction( companionIrClass: IrClass, @@ -51,46 +52,48 @@ internal class CEnumByValueFunctionGenerator( // i++ // } // throw NPE - byValueIrFunction.body = irBuilder(irBuiltIns, byValueIrFunction.symbol, SYNTHETIC_OFFSET, SYNTHETIC_OFFSET).irBlockBody { - +irReturn(irBlock { - val values = irTemporary(irCall(valuesIrFunctionSymbol), isMutable = true) - val inductionVariable = irTemporary(irInt(0), isMutable = true) - val arrayClass = values.type.classOrNull!! - val valuesSize = irCall(symbols.arraySize.getValue(arrayClass), irBuiltIns.intType).also { irCall -> - irCall.dispatchReceiver = irGet(values) - } - val getElementFn = symbols.arrayGet.getValue(arrayClass) - val plusFun = symbols.getBinaryOperator(OperatorNameConventions.PLUS, irBuiltIns.intType, irBuiltIns.intType) - val lessFunctionSymbol = irBuiltIns.lessFunByOperandType.getValue(irBuiltIns.intClass) - +irWhile().also { loop -> - loop.condition = irCall(lessFunctionSymbol, irBuiltIns.booleanType).also { irCall -> - irCall.putValueArgument(0, irGet(inductionVariable)) - irCall.putValueArgument(1, valuesSize) + postLinkageSteps.add { + byValueIrFunction.body = irBuilder(irBuiltIns, byValueIrFunction.symbol, SYNTHETIC_OFFSET, SYNTHETIC_OFFSET).irBlockBody { + +irReturn(irBlock { + val values = irTemporary(irCall(valuesIrFunctionSymbol), isMutable = true) + val inductionVariable = irTemporary(irInt(0), isMutable = true) + val arrayClass = values.type.classOrNull!! + val valuesSize = irCall(symbols.arraySize.getValue(arrayClass), irBuiltIns.intType).also { irCall -> + irCall.dispatchReceiver = irGet(values) } - loop.body = irBlock { - val entry = irTemporary(irCall(getElementFn, byValueIrFunction.returnType).also { irCall -> - irCall.dispatchReceiver = irGet(values) + val getElementFn = symbols.arrayGet.getValue(arrayClass) + val plusFun = symbols.getBinaryOperator(OperatorNameConventions.PLUS, irBuiltIns.intType, irBuiltIns.intType) + val lessFunctionSymbol = irBuiltIns.lessFunByOperandType.getValue(irBuiltIns.intClass) + +irWhile().also { loop -> + loop.condition = irCall(lessFunctionSymbol, irBuiltIns.booleanType).also { irCall -> irCall.putValueArgument(0, irGet(inductionVariable)) - }, isMutable = true) - val valueGetter = entry.type.getClass()!!.getPropertyGetter("value")!! - val entryValue = irGet(irValueParameter.type, irGet(entry), valueGetter) - +irIfThenElse( - type = irBuiltIns.unitType, - condition = irEquals(entryValue, irGet(irValueParameter)), - thenPart = irReturn(irGet(entry)), - elsePart = irSetVar( - inductionVariable, - irCallOp(plusFun, irBuiltIns.intType, - irGet(inductionVariable), - irInt(1) - ) - ) - ) + irCall.putValueArgument(1, valuesSize) + } + loop.body = irBlock { + val entry = irTemporary(irCall(getElementFn, byValueIrFunction.returnType).also { irCall -> + irCall.dispatchReceiver = irGet(values) + irCall.putValueArgument(0, irGet(inductionVariable)) + }, isMutable = true) + val valueGetter = entry.type.getClass()!!.getPropertyGetter("value")!! + val entryValue = irGet(irValueParameter.type, irGet(entry), valueGetter) + +irIfThenElse( + type = irBuiltIns.unitType, + condition = irEquals(entryValue, irGet(irValueParameter)), + thenPart = irReturn(irGet(entry)), + elsePart = irSetVar( + inductionVariable, + irCallOp(plusFun, irBuiltIns.intType, + irGet(inductionVariable), + irInt(1) + ) + ) + ) + } } - } - +IrCallImpl.fromSymbolDescriptor(startOffset, endOffset, irBuiltIns.nothingType, - symbols.throwNullPointerException) - }) + +IrCallImpl.fromSymbolOwner(startOffset, endOffset, irBuiltIns.nothingType, + symbols.throwNullPointerException) + }) + } } return byValueIrFunction } diff --git a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/ir/interop/cenum/CEnumClassGenerator.kt b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/ir/interop/cenum/CEnumClassGenerator.kt index bc2da7010e0..f5758053e79 100644 --- a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/ir/interop/cenum/CEnumClassGenerator.kt +++ b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/ir/interop/cenum/CEnumClassGenerator.kt @@ -49,6 +49,7 @@ internal class CEnumClassGenerator( override val irBuiltIns: IrBuiltIns = context.irBuiltIns override val symbolTable: SymbolTable = context.symbolTable override val typeTranslator: TypeTranslator = context.typeTranslator + override val postLinkageSteps: MutableList<() -> Unit> = mutableListOf() private val enumClassMembersGenerator = EnumClassMembersGenerator(DeclarationGenerator(context)) @@ -97,38 +98,46 @@ internal class CEnumClassGenerator( SYNTHETIC_OFFSET, SYNTHETIC_OFFSET, IrDeclarationOrigin.PROPERTY_BACKING_FIELD, propertyDescriptor, propertyDescriptor.type.toIrType(), DescriptorVisibilities.PRIVATE ).also { - it.initializer = irBuilder(irBuiltIns, it.symbol, SYNTHETIC_OFFSET, SYNTHETIC_OFFSET).run { - irExprBody(irGet(irClass.primaryConstructor!!.valueParameters[0])) + postLinkageSteps.add { + it.initializer = irBuilder(irBuiltIns, it.symbol, SYNTHETIC_OFFSET, SYNTHETIC_OFFSET).run { + irExprBody(irGet(irClass.primaryConstructor!!.valueParameters[0])) + } } } } val getter = irProperty.getter!! getter.correspondingPropertySymbol = irProperty.symbol - getter.body = irBuilder(irBuiltIns, getter.symbol, SYNTHETIC_OFFSET, SYNTHETIC_OFFSET).irBlockBody { - +irReturn( - irGetField( - irGet(getter.dispatchReceiverParameter!!), - irProperty.backingField!! - ) - ) + postLinkageSteps.add { + getter.body = irBuilder(irBuiltIns, getter.symbol, SYNTHETIC_OFFSET, SYNTHETIC_OFFSET).irBlockBody { + +irReturn( + irGetField( + irGet(getter.dispatchReceiverParameter!!), + irProperty.backingField!! + ) + ) + } } return irProperty } private fun createEnumEntry(enumDescriptor: ClassDescriptor, entryDescriptor: ClassDescriptor): IrEnumEntry { - return symbolTable.declareEnumEntry( + val enumEntry = symbolTable.declareEnumEntry( SYNTHETIC_OFFSET, SYNTHETIC_OFFSET, IrDeclarationOrigin.IR_EXTERNAL_DECLARATION_STUB, entryDescriptor - ).also { enumEntry -> - enumEntry.initializerExpression = IrExpressionBodyImpl(IrEnumConstructorCallImpl.fromSymbolDescriptor( + ) + val constructorSymbol = symbolTable.referenceConstructor(enumDescriptor.unsubstitutedPrimaryConstructor!!) + postLinkageSteps.add { + enumEntry.initializerExpression = IrExpressionBodyImpl(IrEnumConstructorCallImpl( SYNTHETIC_OFFSET, SYNTHETIC_OFFSET, type = irBuiltIns.unitType, - symbol = symbolTable.referenceConstructor(enumDescriptor.unsubstitutedPrimaryConstructor!!), - typeArgumentsCount = 0 // enums can't be generic + symbol = constructorSymbol, + typeArgumentsCount = 0, + valueArgumentsCount = constructorSymbol.owner.valueParameters.size ).also { it.putValueArgument(0, extractEnumEntryValue(entryDescriptor)) }) } + return enumEntry } /** @@ -146,16 +155,23 @@ internal class CEnumClassGenerator( private fun createEnumPrimaryConstructor(descriptor: ClassDescriptor): IrConstructor { val irConstructor = createConstructor(descriptor.unsubstitutedPrimaryConstructor!!) val enumConstructor = context.builtIns.enum.constructors.single() - irConstructor.body = irBuilder(irBuiltIns, irConstructor.symbol, SYNTHETIC_OFFSET, SYNTHETIC_OFFSET).irBlockBody { - +IrEnumConstructorCallImpl.fromSymbolDescriptor( - startOffset, endOffset, - context.irBuiltIns.unitType, - symbolTable.referenceConstructor(enumConstructor), - typeArgumentsCount = 1 // kotlin.Enum has a single type parameter. - ).apply { - putTypeArgument(0, descriptor.defaultType.toIrType()) - } - +irInstanceInitializer(symbolTable.referenceClass(descriptor)) + val constructorSymbol = symbolTable.referenceConstructor(enumConstructor) + val classSymbol = symbolTable.referenceClass(descriptor) + val type = descriptor.defaultType.toIrType() + postLinkageSteps.add { + irConstructor.body = irBuilder(irBuiltIns, irConstructor.symbol, SYNTHETIC_OFFSET, SYNTHETIC_OFFSET) + .irBlockBody { + +IrEnumConstructorCallImpl( + startOffset, endOffset, + context.irBuiltIns.unitType, + constructorSymbol, + typeArgumentsCount = 1, // kotlin.Enum has a single type parameter. + valueArgumentsCount = constructorSymbol.owner.valueParameters.size + ).apply { + putTypeArgument(0, type) + } + +irInstanceInitializer(classSymbol) + } } return irConstructor } diff --git a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/ir/interop/cenum/CEnumCompanionGenerator.kt b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/ir/interop/cenum/CEnumCompanionGenerator.kt index f90f2ffefd2..27dfbad5ebc 100644 --- a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/ir/interop/cenum/CEnumCompanionGenerator.kt +++ b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/ir/interop/cenum/CEnumCompanionGenerator.kt @@ -32,6 +32,7 @@ internal class CEnumCompanionGenerator( override val irBuiltIns: IrBuiltIns = context.irBuiltIns override val symbolTable: SymbolTable = context.symbolTable override val typeTranslator: TypeTranslator = context.typeTranslator + override val postLinkageSteps: MutableList<() -> Unit> = mutableListOf() // Depends on already generated `.values()` irFunction. fun generate(enumClass: IrClass): IrClass = @@ -50,13 +51,16 @@ internal class CEnumCompanionGenerator( private fun createCompanionConstructor(companionObjectDescriptor: ClassDescriptor): IrConstructor { val anyPrimaryConstructor = companionObjectDescriptor.builtIns.any.unsubstitutedPrimaryConstructor!! val superConstructorSymbol = symbolTable.referenceConstructor(anyPrimaryConstructor) + val classSymbol = symbolTable.referenceClass(companionObjectDescriptor) return createConstructor(companionObjectDescriptor.unsubstitutedPrimaryConstructor!!).also { - it.body = irBuilder(irBuiltIns, it.symbol, SYNTHETIC_OFFSET, SYNTHETIC_OFFSET).irBlockBody { - +IrDelegatingConstructorCallImpl.fromSymbolDescriptor( - startOffset, endOffset, context.irBuiltIns.unitType, - superConstructorSymbol - ) - +irInstanceInitializer(symbolTable.referenceClass(companionObjectDescriptor)) + postLinkageSteps.add { + it.body = irBuilder(irBuiltIns, it.symbol, SYNTHETIC_OFFSET, SYNTHETIC_OFFSET).irBlockBody { + +IrDelegatingConstructorCallImpl.fromSymbolOwner( + startOffset, endOffset, context.irBuiltIns.unitType, + superConstructorSymbol + ) + +irInstanceInitializer(classSymbol) + } } } } @@ -88,7 +92,9 @@ internal class CEnumCompanionGenerator( private fun declareEntryAliasProperty(propertyDescriptor: PropertyDescriptor, enumClass: IrClass): IrProperty { val entrySymbol = fundCorrespondingEnumEntrySymbol(propertyDescriptor, enumClass) return createProperty(propertyDescriptor).also { - it.getter!!.body = generateAliasGetterBody(it.getter!!, entrySymbol, enumClass) + postLinkageSteps.add { + it.getter!!.body = generateAliasGetterBody(it.getter!!, entrySymbol, enumClass) + } } } } \ No newline at end of file diff --git a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/ir/interop/cenum/CEnumVarClassGenerator.kt b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/ir/interop/cenum/CEnumVarClassGenerator.kt index 5cea0c767f9..3fa40489289 100644 --- a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/ir/interop/cenum/CEnumVarClassGenerator.kt +++ b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/ir/interop/cenum/CEnumVarClassGenerator.kt @@ -34,6 +34,7 @@ internal class CEnumVarClassGenerator( override val irBuiltIns: IrBuiltIns = context.irBuiltIns override val symbolTable: SymbolTable = context.symbolTable override val typeTranslator: TypeTranslator = context.typeTranslator + override val postLinkageSteps: MutableList<() -> Unit> = mutableListOf() fun generate(enumIrClass: IrClass): IrClass { val enumVarClassDescriptor = enumIrClass.descriptor.unsubstitutedMemberScope @@ -56,13 +57,16 @@ internal class CEnumVarClassGenerator( val enumVarConstructorSymbol = symbolTable.referenceConstructor( interopBuiltIns.cEnumVar.unsubstitutedPrimaryConstructor!! ) - irConstructor.body = irBuilder(irBuiltIns, irConstructor.symbol, SYNTHETIC_OFFSET, SYNTHETIC_OFFSET).irBlockBody { - +IrDelegatingConstructorCallImpl.fromSymbolDescriptor( - startOffset, endOffset, context.irBuiltIns.unitType, enumVarConstructorSymbol - ).also { - it.putValueArgument(0, irGet(irConstructor.valueParameters[0])) + val classSymbol = symbolTable.referenceClass(enumVarClass.descriptor) + postLinkageSteps.add { + irConstructor.body = irBuilder(irBuiltIns, irConstructor.symbol, SYNTHETIC_OFFSET, SYNTHETIC_OFFSET).irBlockBody { + +IrDelegatingConstructorCallImpl.fromSymbolOwner( + startOffset, endOffset, context.irBuiltIns.unitType, enumVarConstructorSymbol + ).also { + it.putValueArgument(0, irGet(irConstructor.valueParameters[0])) + } + +irInstanceInitializer(classSymbol) } - +irInstanceInitializer(symbolTable.referenceClass(enumVarClass.descriptor)) } return irConstructor } @@ -77,15 +81,18 @@ internal class CEnumVarClassGenerator( private fun createCompanionConstructor(companionObjectDescriptor: ClassDescriptor, typeSize: Int): IrConstructor { val superConstructorSymbol = symbolTable.referenceConstructor(interopBuiltIns.cPrimitiveVarType.unsubstitutedPrimaryConstructor!!) + val classSymbol = symbolTable.referenceClass(companionObjectDescriptor) return createConstructor(companionObjectDescriptor.unsubstitutedPrimaryConstructor!!).also { - it.body = irBuilder(irBuiltIns, it.symbol, SYNTHETIC_OFFSET, SYNTHETIC_OFFSET).irBlockBody { - +IrDelegatingConstructorCallImpl.fromSymbolDescriptor( - startOffset, endOffset, context.irBuiltIns.unitType, - superConstructorSymbol - ).also { - it.putValueArgument(0, irInt(typeSize)) + postLinkageSteps.add { + it.body = irBuilder(irBuiltIns, it.symbol, SYNTHETIC_OFFSET, SYNTHETIC_OFFSET).irBlockBody { + +IrDelegatingConstructorCallImpl.fromSymbolOwner( + startOffset, endOffset, context.irBuiltIns.unitType, + superConstructorSymbol + ).also { + it.putValueArgument(0, irInt(typeSize)) + } + +irInstanceInitializer(classSymbol) } - +irInstanceInitializer(symbolTable.referenceClass(companionObjectDescriptor)) } } } diff --git a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/ir/interop/cstruct/CStructVarClassGenerator.kt b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/ir/interop/cstruct/CStructVarClassGenerator.kt index e844c8aa444..bedb27332f4 100644 --- a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/ir/interop/cstruct/CStructVarClassGenerator.kt +++ b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/ir/interop/cstruct/CStructVarClassGenerator.kt @@ -23,14 +23,14 @@ import org.jetbrains.kotlin.psi2ir.generators.GeneratorContext internal class CStructVarClassGenerator( context: GeneratorContext, - private val interopBuiltIns: InteropBuiltIns + private val interopBuiltIns: InteropBuiltIns, + private val companionGenerator: CStructVarCompanionGenerator ) : DescriptorToIrTranslationMixin { override val irBuiltIns: IrBuiltIns = context.irBuiltIns override val symbolTable: SymbolTable = context.symbolTable override val typeTranslator: TypeTranslator = context.typeTranslator - - private val companionGenerator = CStructVarCompanionGenerator(context, interopBuiltIns) + override val postLinkageSteps: MutableList<() -> Unit> = mutableListOf() fun findOrGenerateCStruct(classDescriptor: ClassDescriptor, parent: IrDeclarationContainer): IrClass { val irClassSymbol = symbolTable.referenceClass(classDescriptor) @@ -61,14 +61,16 @@ internal class CStructVarClassGenerator( interopBuiltIns.cStructVar.unsubstitutedPrimaryConstructor!! ) return createConstructor(irClass.descriptor.unsubstitutedPrimaryConstructor!!).also { irConstructor -> - irConstructor.body = irBuilder(irBuiltIns, irConstructor.symbol, SYNTHETIC_OFFSET, SYNTHETIC_OFFSET).irBlockBody { - +IrDelegatingConstructorCallImpl.fromSymbolDescriptor( - startOffset, endOffset, - context.irBuiltIns.unitType, enumVarConstructorSymbol - ).also { - it.putValueArgument(0, irGet(irConstructor.valueParameters[0])) + postLinkageSteps.add { + irConstructor.body = irBuilder(irBuiltIns, irConstructor.symbol, SYNTHETIC_OFFSET, SYNTHETIC_OFFSET).irBlockBody { + +IrDelegatingConstructorCallImpl.fromSymbolOwner( + startOffset, endOffset, + context.irBuiltIns.unitType, enumVarConstructorSymbol + ).also { + it.putValueArgument(0, irGet(irConstructor.valueParameters[0])) + } + +irInstanceInitializer(symbolTable.referenceClass(irClass.descriptor)) } - +irInstanceInitializer(symbolTable.referenceClass(irClass.descriptor)) } } } diff --git a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/ir/interop/cstruct/CStructVarCompanionGenerator.kt b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/ir/interop/cstruct/CStructVarCompanionGenerator.kt index 133df36ea76..95d1a9defd9 100644 --- a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/ir/interop/cstruct/CStructVarCompanionGenerator.kt +++ b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/ir/interop/cstruct/CStructVarCompanionGenerator.kt @@ -32,6 +32,7 @@ internal class CStructVarCompanionGenerator( override val irBuiltIns: IrBuiltIns = context.irBuiltIns override val symbolTable: SymbolTable = context.symbolTable override val typeTranslator: TypeTranslator = context.typeTranslator + override val postLinkageSteps: MutableList<() -> Unit> = mutableListOf() fun generate(structDescriptor: ClassDescriptor): IrClass = createClass(structDescriptor.companionObjectDescriptor!!) { companionIrClass -> @@ -45,15 +46,17 @@ internal class CStructVarCompanionGenerator( private fun createCompanionConstructor(companionObjectDescriptor: ClassDescriptor, size: Long, align: Int): IrConstructor { val superConstructorSymbol = symbolTable.referenceConstructor(interopBuiltIns.cStructVarType.unsubstitutedPrimaryConstructor!!) return createConstructor(companionObjectDescriptor.unsubstitutedPrimaryConstructor!!).also { irConstructor -> - irConstructor.body = irBuilder(irBuiltIns, irConstructor.symbol, SYNTHETIC_OFFSET, SYNTHETIC_OFFSET).irBlockBody { - +IrDelegatingConstructorCallImpl.fromSymbolDescriptor( - startOffset, endOffset, context.irBuiltIns.unitType, - superConstructorSymbol - ).also { - it.putValueArgument(0, irLong(size)) - it.putValueArgument(1, irInt(align)) + postLinkageSteps.add { + irConstructor.body = irBuilder(irBuiltIns, irConstructor.symbol, SYNTHETIC_OFFSET, SYNTHETIC_OFFSET).irBlockBody { + +IrDelegatingConstructorCallImpl.fromSymbolOwner( + startOffset, endOffset, context.irBuiltIns.unitType, + superConstructorSymbol + ).also { + it.putValueArgument(0, irLong(size)) + it.putValueArgument(1, irInt(align)) + } + +irInstanceInitializer(symbolTable.referenceClass(companionObjectDescriptor)) } - +irInstanceInitializer(symbolTable.referenceClass(companionObjectDescriptor)) } } }