[K/N][IR] Moved caches ABI lowerings to a separate file
This commit is contained in:
+4
-225
@@ -3,35 +3,26 @@ package org.jetbrains.kotlin.backend.konan
|
||||
import org.jetbrains.kotlin.backend.common.checkDeclarationParents
|
||||
import org.jetbrains.kotlin.backend.common.IrValidator
|
||||
import org.jetbrains.kotlin.backend.common.IrValidatorConfig
|
||||
import org.jetbrains.kotlin.backend.common.lower.createIrBuilder
|
||||
import org.jetbrains.kotlin.backend.common.atMostOne
|
||||
import org.jetbrains.kotlin.backend.common.phaser.*
|
||||
import org.jetbrains.kotlin.backend.common.serialization.CompatibilityMode
|
||||
import org.jetbrains.kotlin.backend.common.serialization.metadata.KlibMetadataMonolithicSerializer
|
||||
import org.jetbrains.kotlin.backend.konan.descriptors.isFromInteropLibrary
|
||||
import org.jetbrains.kotlin.backend.konan.llvm.*
|
||||
import org.jetbrains.kotlin.backend.konan.lower.*
|
||||
import org.jetbrains.kotlin.backend.konan.lower.CacheInfoBuilder
|
||||
import org.jetbrains.kotlin.backend.konan.lower.DECLARATION_ORIGIN_ENUM
|
||||
import org.jetbrains.kotlin.backend.konan.lower.ExpectToActualDefaultValueCopier
|
||||
import org.jetbrains.kotlin.backend.konan.lower.SamSuperTypesChecker
|
||||
import org.jetbrains.kotlin.backend.konan.objcexport.ObjCExport
|
||||
import org.jetbrains.kotlin.backend.konan.serialization.*
|
||||
import org.jetbrains.kotlin.config.CommonConfigurationKeys
|
||||
import org.jetbrains.kotlin.config.languageVersionSettings
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.ir.IrElement
|
||||
import org.jetbrains.kotlin.ir.builders.*
|
||||
import org.jetbrains.kotlin.ir.builders.declarations.buildFun
|
||||
import org.jetbrains.kotlin.ir.builders.declarations.addValueParameter
|
||||
import org.jetbrains.kotlin.ir.declarations.*
|
||||
import org.jetbrains.kotlin.ir.declarations.impl.IrFactoryImpl
|
||||
import org.jetbrains.kotlin.ir.expressions.*
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.IrCallImpl
|
||||
import org.jetbrains.kotlin.ir.types.typeWith
|
||||
import org.jetbrains.kotlin.ir.util.*
|
||||
import org.jetbrains.kotlin.ir.visitors.*
|
||||
import org.jetbrains.kotlin.konan.target.CompilerOutputKind
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
|
||||
internal fun moduleValidationCallback(state: ActionState, module: IrModuleFragment, context: Context) {
|
||||
if (!context.config.needVerifyIr) return
|
||||
@@ -383,226 +374,14 @@ internal val exportInternalAbiPhase = makeKonanModuleOpPhase(
|
||||
name = "exportInternalAbi",
|
||||
description = "Add accessors to private entities",
|
||||
prerequisite = emptySet(),
|
||||
op = { context, module ->
|
||||
val visitor = object : IrElementVisitorVoid {
|
||||
override fun visitElement(element: IrElement) {
|
||||
element.acceptChildrenVoid(this)
|
||||
}
|
||||
|
||||
override fun visitClass(declaration: IrClass) {
|
||||
declaration.acceptChildrenVoid(this)
|
||||
|
||||
if (declaration.isLocal) return
|
||||
|
||||
if (declaration.isCompanion) {
|
||||
val function = context.irFactory.buildFun {
|
||||
name = InternalAbi.getCompanionObjectAccessorName(declaration)
|
||||
origin = InternalAbi.INTERNAL_ABI_ORIGIN
|
||||
returnType = declaration.defaultType
|
||||
}
|
||||
context.createIrBuilder(function.symbol).apply {
|
||||
function.body = irBlockBody {
|
||||
+irReturn(irGetObjectValue(declaration.defaultType, declaration.symbol))
|
||||
}
|
||||
}
|
||||
context.internalAbi.declare(function, declaration.module)
|
||||
}
|
||||
|
||||
if (declaration.isInner) {
|
||||
val function = context.irFactory.buildFun {
|
||||
name = InternalAbi.getInnerClassOuterThisAccessorName(declaration)
|
||||
origin = InternalAbi.INTERNAL_ABI_ORIGIN
|
||||
returnType = declaration.parentAsClass.defaultType
|
||||
}
|
||||
function.addValueParameter {
|
||||
name = Name.identifier("innerClass")
|
||||
origin = InternalAbi.INTERNAL_ABI_ORIGIN
|
||||
type = declaration.defaultType
|
||||
}
|
||||
|
||||
context.createIrBuilder(function.symbol).apply {
|
||||
function.body = irBlockBody {
|
||||
+irReturn(irGetField(
|
||||
irGet(function.valueParameters[0]),
|
||||
context.innerClassesSupport.getOuterThisField(declaration))
|
||||
)
|
||||
}
|
||||
}
|
||||
context.internalAbi.declare(function, declaration.module)
|
||||
}
|
||||
|
||||
if (declaration.isEnumClass) {
|
||||
val function = context.irFactory.buildFun {
|
||||
name = InternalAbi.getEnumValuesAccessorName(declaration)
|
||||
returnType = context.ir.symbols.array.typeWith(declaration.defaultType)
|
||||
origin = InternalAbi.INTERNAL_ABI_ORIGIN
|
||||
}
|
||||
|
||||
context.createIrBuilder(function.symbol).run {
|
||||
function.body = irBlockBody {
|
||||
+irReturn(with(context.enumsSupport) { irGetValuesField(declaration) })
|
||||
}
|
||||
}
|
||||
context.internalAbi.declare(function, declaration.module)
|
||||
}
|
||||
}
|
||||
|
||||
override fun visitProperty(declaration: IrProperty) {
|
||||
declaration.acceptChildrenVoid(this)
|
||||
|
||||
if (!declaration.isLateinit || declaration.isFakeOverride
|
||||
|| DescriptorVisibilities.isPrivate(declaration.visibility) || declaration.isLocal)
|
||||
return
|
||||
|
||||
val backingField = declaration.backingField ?: error("Lateinit property ${declaration.render()} should have a backing field")
|
||||
val function = context.irFactory.buildFun {
|
||||
name = InternalAbi.getLateinitPropertyFieldAccessorName(declaration)
|
||||
origin = InternalAbi.INTERNAL_ABI_ORIGIN
|
||||
returnType = backingField.type
|
||||
}
|
||||
val ownerClass = declaration.parentClassOrNull
|
||||
if (ownerClass != null)
|
||||
function.addValueParameter {
|
||||
name = Name.identifier("owner")
|
||||
origin = InternalAbi.INTERNAL_ABI_ORIGIN
|
||||
type = ownerClass.defaultType
|
||||
}
|
||||
|
||||
context.createIrBuilder(function.symbol).apply {
|
||||
function.body = irBlockBody {
|
||||
+irReturn(irGetField(ownerClass?.let { irGet(function.valueParameters[0]) }, backingField))
|
||||
}
|
||||
}
|
||||
context.internalAbi.declare(function, declaration.module)
|
||||
}
|
||||
}
|
||||
module.acceptChildrenVoid(visitor)
|
||||
}
|
||||
op = { context, module -> module.acceptChildrenVoid(ExportCachesAbiVisitor(context)) }
|
||||
)
|
||||
|
||||
internal val useInternalAbiPhase = makeKonanModuleOpPhase(
|
||||
name = "useInternalAbi",
|
||||
description = "Use internal ABI functions to access private entities",
|
||||
prerequisite = emptySet(),
|
||||
op = { context, module ->
|
||||
val companionObjectAccessors = mutableMapOf<IrClass, IrSimpleFunction>()
|
||||
val outerThisAccessors = mutableMapOf<IrClass, IrSimpleFunction>()
|
||||
val lateinitPropertyAccessors = mutableMapOf<IrProperty, IrSimpleFunction>()
|
||||
val enumValuesAccessors = mutableMapOf<IrClass, IrSimpleFunction>()
|
||||
|
||||
val transformer = object : IrElementTransformerVoid() {
|
||||
override fun visitGetObjectValue(expression: IrGetObjectValue): IrExpression {
|
||||
expression.transformChildrenVoid(this)
|
||||
|
||||
val irClass = expression.symbol.owner
|
||||
if (!irClass.isCompanion || context.llvmModuleSpecification.containsDeclaration(irClass)) {
|
||||
return expression
|
||||
}
|
||||
val parent = irClass.parentAsClass
|
||||
if (parent.isObjCClass()) {
|
||||
// Access to Obj-C metaclass is done via intrinsic.
|
||||
return expression
|
||||
}
|
||||
val accessor = companionObjectAccessors.getOrPut(irClass) {
|
||||
context.irFactory.buildFun {
|
||||
name = InternalAbi.getCompanionObjectAccessorName(irClass)
|
||||
returnType = irClass.defaultType
|
||||
origin = InternalAbi.INTERNAL_ABI_ORIGIN
|
||||
isExternal = true
|
||||
}.also {
|
||||
context.internalAbi.reference(it, irClass.module)
|
||||
}
|
||||
}
|
||||
return IrCallImpl(expression.startOffset, expression.endOffset, expression.type, accessor.symbol, accessor.typeParameters.size, accessor.valueParameters.size)
|
||||
}
|
||||
|
||||
override fun visitGetField(expression: IrGetField): IrExpression {
|
||||
expression.transformChildrenVoid(this)
|
||||
|
||||
val field = expression.symbol.owner
|
||||
val irClass = field.parentClassOrNull
|
||||
val property = field.correspondingPropertySymbol?.owner
|
||||
|
||||
return when {
|
||||
context.llvmModuleSpecification.containsDeclaration(field) -> expression
|
||||
|
||||
irClass?.isInner == true && context.innerClassesSupport.getOuterThisField(irClass) == field -> {
|
||||
val accessor = outerThisAccessors.getOrPut(irClass) {
|
||||
context.irFactory.buildFun {
|
||||
name = InternalAbi.getInnerClassOuterThisAccessorName(irClass)
|
||||
returnType = irClass.parentAsClass.defaultType
|
||||
origin = InternalAbi.INTERNAL_ABI_ORIGIN
|
||||
isExternal = true
|
||||
}.also { function ->
|
||||
context.internalAbi.reference(function, irClass.module)
|
||||
|
||||
function.addValueParameter {
|
||||
name = Name.identifier("innerClass")
|
||||
origin = InternalAbi.INTERNAL_ABI_ORIGIN
|
||||
type = irClass.defaultType
|
||||
}
|
||||
}
|
||||
}
|
||||
return IrCallImpl(
|
||||
expression.startOffset, expression.endOffset,
|
||||
expression.type, accessor.symbol,
|
||||
accessor.typeParameters.size, accessor.valueParameters.size
|
||||
).apply {
|
||||
putValueArgument(0, expression.receiver)
|
||||
}
|
||||
}
|
||||
|
||||
property?.isLateinit == true -> {
|
||||
val accessor = lateinitPropertyAccessors.getOrPut(property) {
|
||||
context.irFactory.buildFun {
|
||||
name = InternalAbi.getLateinitPropertyFieldAccessorName(property)
|
||||
returnType = field.type
|
||||
origin = InternalAbi.INTERNAL_ABI_ORIGIN
|
||||
isExternal = true
|
||||
}.also { function ->
|
||||
context.internalAbi.reference(function, property.module)
|
||||
|
||||
if (irClass != null)
|
||||
function.addValueParameter {
|
||||
name = Name.identifier("owner")
|
||||
origin = InternalAbi.INTERNAL_ABI_ORIGIN
|
||||
type = irClass.defaultType
|
||||
}
|
||||
}
|
||||
}
|
||||
return IrCallImpl(
|
||||
expression.startOffset, expression.endOffset,
|
||||
expression.type, accessor.symbol,
|
||||
accessor.typeParameters.size, accessor.valueParameters.size
|
||||
).apply {
|
||||
if (irClass != null)
|
||||
putValueArgument(0, expression.receiver)
|
||||
}
|
||||
}
|
||||
|
||||
field.origin == DECLARATION_ORIGIN_ENUM -> {
|
||||
val enumClass = irClass?.parentClassOrNull
|
||||
require(enumClass != null) { "Unexpected usage of enum VALUES field" }
|
||||
require(enumClass.isEnumClass) { "Expected a enum class: ${enumClass.render()}" }
|
||||
val accessor = enumValuesAccessors.getOrPut(enumClass) {
|
||||
context.irFactory.buildFun {
|
||||
name = InternalAbi.getEnumValuesAccessorName(enumClass)
|
||||
returnType = context.ir.symbols.array.typeWith(enumClass.defaultType)
|
||||
origin = InternalAbi.INTERNAL_ABI_ORIGIN
|
||||
isExternal = true
|
||||
}.also {
|
||||
context.internalAbi.reference(it, enumClass.module)
|
||||
}
|
||||
}
|
||||
return IrCallImpl(expression.startOffset, expression.endOffset, expression.type, accessor.symbol, accessor.typeParameters.size, accessor.valueParameters.size)
|
||||
}
|
||||
|
||||
else -> expression
|
||||
}
|
||||
}
|
||||
}
|
||||
module.transformChildrenVoid(transformer)
|
||||
}
|
||||
op = { context, module -> module.transformChildrenVoid(ImportCachesAbiTransformer(context)) }
|
||||
)
|
||||
|
||||
internal val bitcodePhase = NamedCompilerPhase(
|
||||
|
||||
+240
@@ -0,0 +1,240 @@
|
||||
/*
|
||||
* Copyright 2010-2022 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.backend.konan.lower
|
||||
|
||||
import org.jetbrains.kotlin.backend.common.lower.createIrBuilder
|
||||
import org.jetbrains.kotlin.backend.konan.Context
|
||||
import org.jetbrains.kotlin.backend.konan.InternalAbi
|
||||
import org.jetbrains.kotlin.backend.konan.isObjCClass
|
||||
import org.jetbrains.kotlin.descriptors.DescriptorVisibilities
|
||||
import org.jetbrains.kotlin.ir.IrElement
|
||||
import org.jetbrains.kotlin.ir.builders.*
|
||||
import org.jetbrains.kotlin.ir.builders.declarations.addValueParameter
|
||||
import org.jetbrains.kotlin.ir.builders.declarations.buildFun
|
||||
import org.jetbrains.kotlin.ir.declarations.IrClass
|
||||
import org.jetbrains.kotlin.ir.declarations.IrProperty
|
||||
import org.jetbrains.kotlin.ir.declarations.IrSimpleFunction
|
||||
import org.jetbrains.kotlin.ir.expressions.IrExpression
|
||||
import org.jetbrains.kotlin.ir.expressions.IrGetField
|
||||
import org.jetbrains.kotlin.ir.expressions.IrGetObjectValue
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.IrCallImpl
|
||||
import org.jetbrains.kotlin.ir.types.typeWith
|
||||
import org.jetbrains.kotlin.ir.util.*
|
||||
import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
|
||||
import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid
|
||||
import org.jetbrains.kotlin.ir.visitors.acceptChildrenVoid
|
||||
import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
|
||||
internal class ExportCachesAbiVisitor(val context: Context) : IrElementVisitorVoid {
|
||||
override fun visitElement(element: IrElement) {
|
||||
element.acceptChildrenVoid(this)
|
||||
}
|
||||
|
||||
override fun visitClass(declaration: IrClass) {
|
||||
declaration.acceptChildrenVoid(this)
|
||||
|
||||
if (declaration.isLocal) return
|
||||
|
||||
if (declaration.isCompanion) {
|
||||
val function = context.irFactory.buildFun {
|
||||
name = InternalAbi.getCompanionObjectAccessorName(declaration)
|
||||
origin = InternalAbi.INTERNAL_ABI_ORIGIN
|
||||
returnType = declaration.defaultType
|
||||
}
|
||||
context.createIrBuilder(function.symbol).apply {
|
||||
function.body = irBlockBody {
|
||||
+irReturn(irGetObjectValue(declaration.defaultType, declaration.symbol))
|
||||
}
|
||||
}
|
||||
context.internalAbi.declare(function, declaration.module)
|
||||
}
|
||||
|
||||
if (declaration.isInner) {
|
||||
val function = context.irFactory.buildFun {
|
||||
name = InternalAbi.getInnerClassOuterThisAccessorName(declaration)
|
||||
origin = InternalAbi.INTERNAL_ABI_ORIGIN
|
||||
returnType = declaration.parentAsClass.defaultType
|
||||
}
|
||||
function.addValueParameter {
|
||||
name = Name.identifier("innerClass")
|
||||
origin = InternalAbi.INTERNAL_ABI_ORIGIN
|
||||
type = declaration.defaultType
|
||||
}
|
||||
|
||||
context.createIrBuilder(function.symbol).apply {
|
||||
function.body = irBlockBody {
|
||||
+irReturn(irGetField(
|
||||
irGet(function.valueParameters[0]),
|
||||
this@ExportCachesAbiVisitor.context.innerClassesSupport.getOuterThisField(declaration))
|
||||
)
|
||||
}
|
||||
}
|
||||
context.internalAbi.declare(function, declaration.module)
|
||||
}
|
||||
|
||||
if (declaration.isEnumClass) {
|
||||
val function = context.irFactory.buildFun {
|
||||
name = InternalAbi.getEnumValuesAccessorName(declaration)
|
||||
returnType = context.ir.symbols.array.typeWith(declaration.defaultType)
|
||||
origin = InternalAbi.INTERNAL_ABI_ORIGIN
|
||||
}
|
||||
|
||||
context.createIrBuilder(function.symbol).run {
|
||||
function.body = irBlockBody {
|
||||
+irReturn(with(this@ExportCachesAbiVisitor.context.enumsSupport) { irGetValuesField(declaration) })
|
||||
}
|
||||
}
|
||||
context.internalAbi.declare(function, declaration.module)
|
||||
}
|
||||
}
|
||||
|
||||
override fun visitProperty(declaration: IrProperty) {
|
||||
declaration.acceptChildrenVoid(this)
|
||||
|
||||
if (!declaration.isLateinit || declaration.isFakeOverride
|
||||
|| DescriptorVisibilities.isPrivate(declaration.visibility) || declaration.isLocal)
|
||||
return
|
||||
|
||||
val backingField = declaration.backingField ?: error("Lateinit property ${declaration.render()} should have a backing field")
|
||||
val function = context.irFactory.buildFun {
|
||||
name = InternalAbi.getLateinitPropertyFieldAccessorName(declaration)
|
||||
origin = InternalAbi.INTERNAL_ABI_ORIGIN
|
||||
returnType = backingField.type
|
||||
}
|
||||
val ownerClass = declaration.parentClassOrNull
|
||||
if (ownerClass != null)
|
||||
function.addValueParameter {
|
||||
name = Name.identifier("owner")
|
||||
origin = InternalAbi.INTERNAL_ABI_ORIGIN
|
||||
type = ownerClass.defaultType
|
||||
}
|
||||
|
||||
context.createIrBuilder(function.symbol).apply {
|
||||
function.body = irBlockBody {
|
||||
+irReturn(irGetField(ownerClass?.let { irGet(function.valueParameters[0]) }, backingField))
|
||||
}
|
||||
}
|
||||
context.internalAbi.declare(function, declaration.module)
|
||||
}
|
||||
}
|
||||
|
||||
internal class ImportCachesAbiTransformer(val context: Context) : IrElementTransformerVoid() {
|
||||
private val companionObjectAccessors = mutableMapOf<IrClass, IrSimpleFunction>()
|
||||
private val outerThisAccessors = mutableMapOf<IrClass, IrSimpleFunction>()
|
||||
private val lateinitPropertyAccessors = mutableMapOf<IrProperty, IrSimpleFunction>()
|
||||
private val enumValuesAccessors = mutableMapOf<IrClass, IrSimpleFunction>()
|
||||
|
||||
override fun visitGetObjectValue(expression: IrGetObjectValue): IrExpression {
|
||||
expression.transformChildrenVoid(this)
|
||||
|
||||
val irClass = expression.symbol.owner
|
||||
if (!irClass.isCompanion || context.llvmModuleSpecification.containsDeclaration(irClass)) {
|
||||
return expression
|
||||
}
|
||||
val parent = irClass.parentAsClass
|
||||
if (parent.isObjCClass()) {
|
||||
// Access to Obj-C metaclass is done via intrinsic.
|
||||
return expression
|
||||
}
|
||||
val accessor = companionObjectAccessors.getOrPut(irClass) {
|
||||
context.irFactory.buildFun {
|
||||
name = InternalAbi.getCompanionObjectAccessorName(irClass)
|
||||
returnType = irClass.defaultType
|
||||
origin = InternalAbi.INTERNAL_ABI_ORIGIN
|
||||
isExternal = true
|
||||
}.also {
|
||||
context.internalAbi.reference(it, irClass.module)
|
||||
}
|
||||
}
|
||||
return IrCallImpl(expression.startOffset, expression.endOffset, expression.type, accessor.symbol, accessor.typeParameters.size, accessor.valueParameters.size)
|
||||
}
|
||||
|
||||
override fun visitGetField(expression: IrGetField): IrExpression {
|
||||
expression.transformChildrenVoid(this)
|
||||
|
||||
val field = expression.symbol.owner
|
||||
val irClass = field.parentClassOrNull
|
||||
val property = field.correspondingPropertySymbol?.owner
|
||||
|
||||
return when {
|
||||
context.llvmModuleSpecification.containsDeclaration(field) -> expression
|
||||
|
||||
irClass?.isInner == true && context.innerClassesSupport.getOuterThisField(irClass) == field -> {
|
||||
val accessor = outerThisAccessors.getOrPut(irClass) {
|
||||
context.irFactory.buildFun {
|
||||
name = InternalAbi.getInnerClassOuterThisAccessorName(irClass)
|
||||
returnType = irClass.parentAsClass.defaultType
|
||||
origin = InternalAbi.INTERNAL_ABI_ORIGIN
|
||||
isExternal = true
|
||||
}.also { function ->
|
||||
context.internalAbi.reference(function, irClass.module)
|
||||
|
||||
function.addValueParameter {
|
||||
name = Name.identifier("innerClass")
|
||||
origin = InternalAbi.INTERNAL_ABI_ORIGIN
|
||||
type = irClass.defaultType
|
||||
}
|
||||
}
|
||||
}
|
||||
return IrCallImpl(
|
||||
expression.startOffset, expression.endOffset,
|
||||
expression.type, accessor.symbol,
|
||||
accessor.typeParameters.size, accessor.valueParameters.size
|
||||
).apply {
|
||||
putValueArgument(0, expression.receiver)
|
||||
}
|
||||
}
|
||||
|
||||
property?.isLateinit == true -> {
|
||||
val accessor = lateinitPropertyAccessors.getOrPut(property) {
|
||||
context.irFactory.buildFun {
|
||||
name = InternalAbi.getLateinitPropertyFieldAccessorName(property)
|
||||
returnType = field.type
|
||||
origin = InternalAbi.INTERNAL_ABI_ORIGIN
|
||||
isExternal = true
|
||||
}.also { function ->
|
||||
context.internalAbi.reference(function, property.module)
|
||||
|
||||
if (irClass != null)
|
||||
function.addValueParameter {
|
||||
name = Name.identifier("owner")
|
||||
origin = InternalAbi.INTERNAL_ABI_ORIGIN
|
||||
type = irClass.defaultType
|
||||
}
|
||||
}
|
||||
}
|
||||
return IrCallImpl(
|
||||
expression.startOffset, expression.endOffset,
|
||||
expression.type, accessor.symbol,
|
||||
accessor.typeParameters.size, accessor.valueParameters.size
|
||||
).apply {
|
||||
if (irClass != null)
|
||||
putValueArgument(0, expression.receiver)
|
||||
}
|
||||
}
|
||||
|
||||
field.origin == DECLARATION_ORIGIN_ENUM -> {
|
||||
val enumClass = irClass?.parentClassOrNull
|
||||
require(enumClass != null) { "Unexpected usage of enum VALUES field" }
|
||||
require(enumClass.isEnumClass) { "Expected a enum class: ${enumClass.render()}" }
|
||||
val accessor = enumValuesAccessors.getOrPut(enumClass) {
|
||||
context.irFactory.buildFun {
|
||||
name = InternalAbi.getEnumValuesAccessorName(enumClass)
|
||||
returnType = context.ir.symbols.array.typeWith(enumClass.defaultType)
|
||||
origin = InternalAbi.INTERNAL_ABI_ORIGIN
|
||||
isExternal = true
|
||||
}.also {
|
||||
context.internalAbi.reference(it, enumClass.module)
|
||||
}
|
||||
}
|
||||
return IrCallImpl(expression.startOffset, expression.endOffset, expression.type, accessor.symbol, accessor.typeParameters.size, accessor.valueParameters.size)
|
||||
}
|
||||
|
||||
else -> expression
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user