diff --git a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/Context.kt b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/Context.kt index 2605b077207..e5c00e5d913 100644 --- a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/Context.kt +++ b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/Context.kt @@ -30,7 +30,6 @@ import org.jetbrains.kotlin.incremental.components.NoLookupLocation import org.jetbrains.kotlin.ir.IrElement import org.jetbrains.kotlin.ir.declarations.* import org.jetbrains.kotlin.ir.declarations.lazy.IrLazyClass -import org.jetbrains.kotlin.ir.deepCopyWithVariables import org.jetbrains.kotlin.ir.symbols.IrFunctionSymbol import org.jetbrains.kotlin.ir.symbols.IrSymbol import org.jetbrains.kotlin.ir.types.IrTypeSystemContext @@ -61,49 +60,8 @@ internal class NativeMapping : DefaultMapping() { val bridges = mutableMapOf() val notLoweredInlineFunctions = mutableMapOf() val loweredInlineFunctions = mutableMapOf() -} - -/** - * Offset for synthetic elements created by lowerings and not attributable to other places in the source code. - */ - -internal class SpecialDeclarationsFactory(val context: Context) { - private val enumSpecialDeclarationsFactory by lazy { EnumSpecialDeclarationsFactory(context) } - private val internalLoweredEnums = mutableMapOf() - private val externalLoweredEnums = mutableMapOf() - - fun getLoweredEnumOrNull(enumClass: IrClass): LoweredEnumAccess? { - assert(enumClass.kind == ClassKind.ENUM_CLASS) { "Expected enum class but was: ${enumClass.descriptor}" } - return if (!context.llvmModuleSpecification.containsDeclaration(enumClass)) { - externalLoweredEnums[enumClass] - } else { - internalLoweredEnums[enumClass] - } - } - - fun getLoweredEnum(enumClass: IrClass): LoweredEnumAccess { - assert(enumClass.kind == ClassKind.ENUM_CLASS) { "Expected enum class but was: ${enumClass.descriptor}" } - return if (!context.llvmModuleSpecification.containsDeclaration(enumClass)) { - externalLoweredEnums.getOrPut(enumClass) { - enumSpecialDeclarationsFactory.createExternalLoweredEnum(enumClass) - } - } else { - internalLoweredEnums.getOrPut(enumClass) { - enumSpecialDeclarationsFactory.createInternalLoweredEnum(enumClass) - } - } - } - - fun getInternalLoweredEnum(enumClass: IrClass): InternalLoweredEnum { - assert(enumClass.kind == ClassKind.ENUM_CLASS) { "Expected enum class but was: ${enumClass.descriptor}" } - assert(context.llvmModuleSpecification.containsDeclaration(enumClass)) { "Expected enum class from current module." } - return internalLoweredEnums.getOrPut(enumClass) { - enumSpecialDeclarationsFactory.createInternalLoweredEnum(enumClass) - } - } - - fun getEnumEntryOrdinal(enumEntry: IrEnumEntry) = - enumEntry.parentAsClass.declarations.filterIsInstance().indexOf(enumEntry) + val internalLoweredEnums = mutableMapOf() + val externalLoweredEnums = mutableMapOf() } internal class Context(config: KonanConfig) : KonanBackendContext(config) { @@ -140,10 +98,10 @@ internal class Context(config: KonanConfig) : KonanBackendContext(config) { builtIns.builtInsModule.getPackage(KonanFqNames.packageName).memberScope.getContributedFunctions("immutableBlobOf").single() } - val specialDeclarationsFactory = SpecialDeclarationsFactory(this) val innerClassesSupport by lazy { InnerClassesSupport(mapping, irFactory) } val bridgesSupport by lazy { BridgesSupport(mapping, irBuiltIns, irFactory) } val inlineFunctionsSupport by lazy { InlineFunctionsSupport(mapping) } + val enumsSupport by lazy { EnumsSupport(this) } open class LazyMember(val initializer: Context.() -> T) { operator fun getValue(thisRef: Context, property: KProperty<*>): T = thisRef.getValue(this) diff --git a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/EnumSpecialDescriptorsFactory.kt b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/EnumSpecialDescriptorsFactory.kt index 9cc98d77c94..19f1b39440a 100644 --- a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/EnumSpecialDescriptorsFactory.kt +++ b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/EnumSpecialDescriptorsFactory.kt @@ -31,6 +31,44 @@ import org.jetbrains.kotlin.ir.types.typeWith import org.jetbrains.kotlin.ir.util.* import org.jetbrains.kotlin.name.Name +internal class EnumsSupport(private val context: Context) { + private val enumSpecialDeclarationsFactory = EnumSpecialDeclarationsFactory(context) + private val internalLoweredEnums = context.mapping.internalLoweredEnums + private val externalLoweredEnums = context.mapping.externalLoweredEnums + + fun getLoweredEnumOrNull(enumClass: IrClass): LoweredEnumAccess? { + require(enumClass.isEnumClass) { "Expected enum class but was: ${enumClass.render()}" } + return if (!context.llvmModuleSpecification.containsDeclaration(enumClass)) { + externalLoweredEnums[enumClass] + } else { + internalLoweredEnums[enumClass] + } + } + + fun getLoweredEnum(enumClass: IrClass): LoweredEnumAccess { + require(enumClass.isEnumClass) { "Expected enum class but was: ${enumClass.render()}" } + return if (!context.llvmModuleSpecification.containsDeclaration(enumClass)) { + externalLoweredEnums.getOrPut(enumClass) { + enumSpecialDeclarationsFactory.createExternalLoweredEnum(enumClass) + } + } else { + internalLoweredEnums.getOrPut(enumClass) { + enumSpecialDeclarationsFactory.createInternalLoweredEnum(enumClass) + } + } + } + + fun getInternalLoweredEnum(enumClass: IrClass): InternalLoweredEnum { + require(enumClass.isEnumClass) { "Expected enum class but was: ${enumClass.render()}" } + require(context.llvmModuleSpecification.containsDeclaration(enumClass)) { "Expected enum class from current module." } + return internalLoweredEnums.getOrPut(enumClass) { + enumSpecialDeclarationsFactory.createInternalLoweredEnum(enumClass) + } + } + + fun getEnumEntryOrdinal(enumEntry: IrEnumEntry) = + enumEntry.parentAsClass.declarations.filterIsInstance().indexOf(enumEntry) +} internal object DECLARATION_ORIGIN_ENUM : IrDeclarationOriginImpl("ENUM") diff --git a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/CodeGenerator.kt b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/CodeGenerator.kt index 3a8fbadab76..ae3d34848cc 100644 --- a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/CodeGenerator.kt +++ b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/CodeGenerator.kt @@ -1349,7 +1349,7 @@ internal abstract class FunctionGenerationContext( */ fun getEnumEntry(enumEntry: IrEnumEntry, exceptionHandler: ExceptionHandler): LLVMValueRef { val enumClass = enumEntry.parentAsClass - val loweredEnum = context.specialDeclarationsFactory.getLoweredEnum(enumClass) + val loweredEnum = context.enumsSupport.getLoweredEnum(enumClass) val getterId = loweredEnum.entriesMap[enumEntry.name]!!.getterId val values = call( diff --git a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/lower/EnumClassLowering.kt b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/lower/EnumClassLowering.kt index 4843cb4d0b9..d8ed0882f34 100644 --- a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/lower/EnumClassLowering.kt +++ b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/lower/EnumClassLowering.kt @@ -34,14 +34,14 @@ import org.jetbrains.kotlin.name.Name private class EnumSyntheticFunctionsBuilder(val context: Context) { fun IrBuilderWithScope.enumValues(enumClass: IrClass): IrExpression { - val loweredEnum = this@EnumSyntheticFunctionsBuilder.context.specialDeclarationsFactory.getLoweredEnum(enumClass) + val loweredEnum = this@EnumSyntheticFunctionsBuilder.context.enumsSupport.getLoweredEnum(enumClass) return irCall(genericValuesSymbol, listOf(enumClass.defaultType)).apply { putValueArgument(0, loweredEnum.getValuesField(startOffset, endOffset)) } } fun IrBuilderWithScope.enumValueOf(enumClass: IrClass, value: IrExpression): IrExpression { - val loweredEnum = this@EnumSyntheticFunctionsBuilder.context.specialDeclarationsFactory.getLoweredEnum(enumClass) + val loweredEnum = this@EnumSyntheticFunctionsBuilder.context.enumsSupport.getLoweredEnum(enumClass) return irCall(genericValueOfSymbol, listOf(enumClass.defaultType)).apply { putValueArgument(0, value) putValueArgument(1, loweredEnum.getValuesField(startOffset, endOffset)) @@ -56,7 +56,7 @@ private class EnumSyntheticFunctionsBuilder(val context: Context) { internal class NativeEnumWhenLowering constructor(context: Context) : EnumWhenLowering(context) { override fun mapConstEnumEntry(entry: IrEnumEntry): Int { val parent = entry.parentAsClass - val loweredEnum = (context as Context).specialDeclarationsFactory.getLoweredEnumOrNull(parent) + val loweredEnum = (context as Context).enumsSupport.getLoweredEnumOrNull(parent) ?: return super.mapConstEnumEntry(entry) return loweredEnum.entriesMap[entry.name]!!.ordinal } @@ -109,7 +109,7 @@ internal class EnumUsageLowering(val context: Context) } private fun IrBuilderWithScope.loadEnumEntry(enumClass: IrClass, name: Name): IrExpression { - val loweredEnum = this@EnumUsageLowering.context.specialDeclarationsFactory.getLoweredEnum(enumClass) + val loweredEnum = this@EnumUsageLowering.context.enumsSupport.getLoweredEnum(enumClass) val getterId = loweredEnum.entriesMap.getValue(name).getterId return irCall(loweredEnum.itemGetterSymbol, enumClass.defaultType).apply { dispatchReceiver = irCall(loweredEnum.valuesGetter) @@ -132,7 +132,7 @@ internal class EnumClassLowering(val context: Context) : FileLoweringPass { } private inner class EnumClassTransformer(val irClass: IrClass) { - private val loweredEnum = context.specialDeclarationsFactory.getInternalLoweredEnum(irClass) + private val loweredEnum = context.enumsSupport.getInternalLoweredEnum(irClass) private val enumSyntheticFunctionsBuilder = EnumSyntheticFunctionsBuilder(context) fun run() { diff --git a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/lower/EnumConstructorsLowering.kt b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/lower/EnumConstructorsLowering.kt index 73ada7ed546..1839f8204f5 100644 --- a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/lower/EnumConstructorsLowering.kt +++ b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/lower/EnumConstructorsLowering.kt @@ -229,7 +229,7 @@ internal class EnumConstructorsLowering(val context: Context) : ClassLoweringPas override fun transform(enumConstructorCall: IrEnumConstructorCall): IrExpression { val name = enumEntry.name.asString() - val ordinal = context.specialDeclarationsFactory.getEnumEntryOrdinal(enumEntry) + val ordinal = context.enumsSupport.getEnumEntryOrdinal(enumEntry) val startOffset = enumConstructorCall.startOffset val endOffset = enumConstructorCall.endOffset