diff --git a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/descriptors/utils.kt b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/descriptors/utils.kt index 8dd37094895..8e0e083c429 100644 --- a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/descriptors/utils.kt +++ b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/descriptors/utils.kt @@ -7,12 +7,20 @@ package org.jetbrains.kotlin.backend.konan.descriptors import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.descriptors.impl.ModuleDescriptorImpl +import org.jetbrains.kotlin.fir.declarations.FirMemberDeclaration +import org.jetbrains.kotlin.fir.declarations.utils.containerSource +import org.jetbrains.kotlin.fir.lazy.AbstractFir2IrLazyDeclaration +import org.jetbrains.kotlin.ir.declarations.IrDeclaration +import org.jetbrains.kotlin.ir.declarations.IrSimpleFunction +import org.jetbrains.kotlin.ir.descriptors.IrBasedDeclarationDescriptor import org.jetbrains.kotlin.konan.library.KLIB_INTEROP_IR_PROVIDER_IDENTIFIER import org.jetbrains.kotlin.library.BaseKotlinLibrary import org.jetbrains.kotlin.library.metadata.DeserializedKlibModuleOrigin +import org.jetbrains.kotlin.library.metadata.KlibDeserializedContainerSource import org.jetbrains.kotlin.library.metadata.klibModuleOrigin import org.jetbrains.kotlin.library.metadata.kotlinLibrary import org.jetbrains.kotlin.name.Name +import org.jetbrains.kotlin.resolve.descriptorUtil.module import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedCallableMemberDescriptor fun DeclarationDescriptor.deepPrint() { @@ -51,6 +59,14 @@ fun DeclarationDescriptor.findTopLevelDescriptor(): DeclarationDescriptor { else this.containingDeclaration!!.findTopLevelDescriptor() } +private fun IrDeclaration.findTopLevelDeclaration(): IrDeclaration = when (val parent = this.parent) { + is IrDeclaration -> parent.findTopLevelDeclaration() + else -> this +} + +private fun IrDeclaration.propertyIfAccessor(): IrDeclaration = + (this as? IrSimpleFunction)?.correspondingPropertySymbol?.owner ?: this + val ModuleDescriptor.isForwardDeclarationModule: Boolean get() { // TODO: use KlibResolvedModuleDescriptorsFactoryImpl.FORWARD_DECLARATIONS_MODULE_NAME instead of @@ -61,6 +77,23 @@ val ModuleDescriptor.isForwardDeclarationModule: Boolean fun BaseKotlinLibrary.isInteropLibrary() = manifestProperties["ir_provider"] == KLIB_INTEROP_IR_PROVIDER_IDENTIFIER +fun DeclarationDescriptor.isFromInteropLibrary(): Boolean = + this.isFromFirDeserializedInteropLibrary() || this.module.isFromInteropLibrary() + +private fun DeclarationDescriptor.isFromFirDeserializedInteropLibrary(): Boolean { + val declaration = (this as? IrBasedDeclarationDescriptor<*>)?.owner ?: return false + + // We need to find top-level non-accessor declaration, because + // - fir2ir lazy IR creates non-AbstractFir2IrLazyDeclaration declarations sometimes, e.g. for enum entries; + // - K2 metadata deserializer doesn't set containerSource for property accessors. + val topLevelDeclaration = declaration.findTopLevelDeclaration().propertyIfAccessor() + + val firDeclaration = (topLevelDeclaration as? AbstractFir2IrLazyDeclaration<*>)?.fir ?: return false + val containerSource = (firDeclaration as? FirMemberDeclaration)?.containerSource + + return containerSource is KlibDeserializedContainerSource && containerSource.isFromNativeInteropLibrary +} + fun ModuleDescriptor.isFromInteropLibrary() = when (this) { is ModuleDescriptorImpl -> diff --git a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/serialization/KonanDeclarationTable.kt b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/serialization/KonanDeclarationTable.kt index e639e8fd25d..c3ba0635393 100644 --- a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/serialization/KonanDeclarationTable.kt +++ b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/serialization/KonanDeclarationTable.kt @@ -23,7 +23,7 @@ class KonanDeclarationTable( // TODO: We should get rid of this extension point in favor of proper support in IR-based mangler. override fun tryComputeBackendSpecificSignature(declaration: IrDeclaration): IdSignature? = - if (declaration.descriptor.module.isFromInteropLibrary()) { + if (declaration.descriptor.isFromInteropLibrary()) { signatureIdComposer.computeSignature(declaration) } else null } \ No newline at end of file diff --git a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/serialization/KonanIdSignaturer.kt b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/serialization/KonanIdSignaturer.kt index 0d1bfa448a4..cd2d269f624 100644 --- a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/serialization/KonanIdSignaturer.kt +++ b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/serialization/KonanIdSignaturer.kt @@ -23,7 +23,7 @@ class KonanIdSignaturer(private val mangler: KotlinMangler.DescriptorMangler) : * [IdSignature.Flags.IS_NATIVE_INTEROP_LIBRARY] flag. */ private fun markInteropDeclaration(descriptor: DeclarationDescriptor) { - if (descriptor.module.isFromInteropLibrary()) { + if (descriptor.isFromInteropLibrary()) { mask = mask or IdSignature.Flags.IS_NATIVE_INTEROP_LIBRARY.encode(true) } }