From 27a31167e6ea79b69a2c1c8bce171b0b2348cbe5 Mon Sep 17 00:00:00 2001 From: Igor Chevdar Date: Tue, 29 Jan 2019 20:36:45 +0300 Subject: [PATCH] =?UTF-8?q?Renamed=20=E2=80=9Cdescriptor=E2=80=9D=20identi?= =?UTF-8?q?fiers?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../jetbrains/kotlin/backend/konan/Context.kt | 10 +- .../konan/descriptors/ClassVtablesBuilder.kt | 102 +++++----- .../konan/descriptors/DescriptorUtils.kt | 8 +- .../konan/irasdescriptors/NewIrUtils.kt | 7 - .../backend/konan/llvm/BinaryInterface.kt | 60 +++--- .../backend/konan/llvm/CodeGenerator.kt | 105 +++++----- .../kotlin/backend/konan/llvm/ContextUtils.kt | 4 +- .../kotlin/backend/konan/llvm/IrToBitcode.kt | 188 ++++++++---------- .../backend/konan/llvm/LlvmDeclarations.kt | 164 ++++++++------- .../backend/konan/llvm/RTTIGenerator.kt | 117 ++++++----- .../backend/konan/llvm/VariableManager.kt | 46 ++--- .../objcexport/ObjCExportCodeGenerator.kt | 2 +- .../backend/konan/lower/BridgesBuilding.kt | 24 +-- .../backend/konan/lower/InteropLowering.kt | 4 +- .../backend/konan/optimizations/DFGBuilder.kt | 71 +++---- .../backend/konan/optimizations/DataFlowIR.kt | 68 +++---- 16 files changed, 469 insertions(+), 511 deletions(-) diff --git a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/Context.kt b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/Context.kt index 65cf8a13c1e..50f6b33198c 100644 --- a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/Context.kt +++ b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/Context.kt @@ -123,12 +123,12 @@ internal class SpecialDeclarationsFactory(val context: Context) { return ordinals.getOrPut(enumClassDescriptor) { assignOrdinalsToEnumEntries(enumClassDescriptor) }[entryDescriptor]!! } - fun getBridge(overriddenFunctionDescriptor: OverriddenFunctionDescriptor): IrSimpleFunction { - val irFunction = overriddenFunctionDescriptor.descriptor - assert(overriddenFunctionDescriptor.needBridge) { - "Function ${irFunction.descriptor} is not needed in a bridge to call overridden function ${overriddenFunctionDescriptor.overriddenDescriptor.descriptor}" + fun getBridge(overriddenFunction: OverriddenFunctionInfo): IrSimpleFunction { + val irFunction = overriddenFunction.function + assert(overriddenFunction.needBridge) { + "Function ${irFunction.descriptor} is not needed in a bridge to call overridden function ${overriddenFunction.overriddenFunction.descriptor}" } - val bridgeDirections = overriddenFunctionDescriptor.bridgeDirections + val bridgeDirections = overriddenFunction.bridgeDirections return bridgesDescriptors.getOrPut(irFunction to bridgeDirections) { createBridge(irFunction, bridgeDirections) } diff --git a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/descriptors/ClassVtablesBuilder.kt b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/descriptors/ClassVtablesBuilder.kt index 016dfccf116..3045e64ed04 100644 --- a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/descriptors/ClassVtablesBuilder.kt +++ b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/descriptors/ClassVtablesBuilder.kt @@ -16,98 +16,96 @@ import org.jetbrains.kotlin.ir.declarations.IrFunction import org.jetbrains.kotlin.ir.declarations.IrSimpleFunction import org.jetbrains.kotlin.ir.util.simpleFunctions -internal class OverriddenFunctionDescriptor( - val descriptor: IrSimpleFunction, - overriddenDescriptor: IrSimpleFunction +internal class OverriddenFunctionInfo( + val function: IrSimpleFunction, + val overriddenFunction: IrSimpleFunction ) { - val overriddenDescriptor = overriddenDescriptor.original - val needBridge: Boolean - get() = descriptor.target.needBridgeTo(overriddenDescriptor) + get() = function.target.needBridgeTo(overriddenFunction) val bridgeDirections: BridgeDirections - get() = descriptor.target.bridgeDirectionsTo(overriddenDescriptor) + get() = function.target.bridgeDirectionsTo(overriddenFunction) val canBeCalledVirtually: Boolean get() { - if (overriddenDescriptor.isObjCClassMethod()) { - return descriptor.canObjCClassMethodBeCalledVirtually(this.overriddenDescriptor) + if (overriddenFunction.isObjCClassMethod()) { + return function.canObjCClassMethodBeCalledVirtually(overriddenFunction) } - return overriddenDescriptor.isOverridable + return overriddenFunction.isOverridable } val inheritsBridge: Boolean - get() = !descriptor.isReal - && descriptor.target.overrides(overriddenDescriptor) - && descriptor.bridgeDirectionsTo(overriddenDescriptor).allNotNeeded() + get() = !function.isReal + && function.target.overrides(overriddenFunction) + && function.bridgeDirectionsTo(overriddenFunction).allNotNeeded() fun getImplementation(context: Context): IrSimpleFunction? { - val target = descriptor.target + val target = function.target val implementation = if (!needBridge) target else { val bridgeOwner = if (inheritsBridge) { target // Bridge is inherited from superclass. } else { - descriptor + function } - context.specialDeclarationsFactory.getBridge(OverriddenFunctionDescriptor(bridgeOwner, overriddenDescriptor)) + context.specialDeclarationsFactory.getBridge(OverriddenFunctionInfo(bridgeOwner, overriddenFunction)) } return if (implementation.modality == Modality.ABSTRACT) null else implementation } override fun toString(): String { - return "(descriptor=$descriptor, overriddenDescriptor=$overriddenDescriptor)" + return "(descriptor=$function, overriddenDescriptor=$overriddenFunction)" } override fun equals(other: Any?): Boolean { if (this === other) return true - if (other !is OverriddenFunctionDescriptor) return false + if (other !is OverriddenFunctionInfo) return false - if (descriptor != other.descriptor) return false - if (overriddenDescriptor != other.overriddenDescriptor) return false + if (function != other.function) return false + if (overriddenFunction != other.overriddenFunction) return false return true } override fun hashCode(): Int { - var result = descriptor.hashCode() - result = 31 * result + overriddenDescriptor.hashCode() + var result = function.hashCode() + result = 31 * result + overriddenFunction.hashCode() return result } } -internal class ClassVtablesBuilder(val classDescriptor: IrClass, val context: Context) { +internal class ClassVtablesBuilder(val irClass: IrClass, val context: Context) { private val DEBUG = 0 private inline fun DEBUG_OUTPUT(severity: Int, block: () -> Unit) { if (DEBUG > severity) block() } - val vtableEntries: List by lazy { + val vtableEntries: List by lazy { - assert(!classDescriptor.isInterface) + assert(!irClass.isInterface) DEBUG_OUTPUT(0) { println() - println("BUILDING vTable for ${classDescriptor.descriptor}") + println("BUILDING vTable for ${irClass.descriptor}") } - val superVtableEntries = if (classDescriptor.isSpecialClassWithNoSupertypes()) { + val superVtableEntries = if (irClass.isSpecialClassWithNoSupertypes()) { emptyList() } else { - val superClass = classDescriptor.getSuperClassNotAny() ?: context.ir.symbols.any.owner + val superClass = irClass.getSuperClassNotAny() ?: context.ir.symbols.any.owner context.getVtableBuilder(superClass).vtableEntries } - val methods = classDescriptor.sortedOverridableOrOverridingMethods - val newVtableSlots = mutableListOf() + val methods = irClass.sortedOverridableOrOverridingMethods + val newVtableSlots = mutableListOf() DEBUG_OUTPUT(0) { println() println("SUPER vTable:") - superVtableEntries.forEach { println(" ${it.overriddenDescriptor.descriptor} -> ${it.descriptor.descriptor}") } + superVtableEntries.forEach { println(" ${it.overriddenFunction.descriptor} -> ${it.function.descriptor}") } println() println("METHODS:") @@ -118,57 +116,57 @@ internal class ClassVtablesBuilder(val classDescriptor: IrClass, val context: Co } val inheritedVtableSlots = superVtableEntries.map { superMethod -> - val overridingMethod = methods.singleOrNull { it.overrides(superMethod.descriptor) } + val overridingMethod = methods.singleOrNull { it.overrides(superMethod.function) } if (overridingMethod == null) { - DEBUG_OUTPUT(0) { println("Taking super ${superMethod.overriddenDescriptor.descriptor} -> ${superMethod.descriptor.descriptor}") } + DEBUG_OUTPUT(0) { println("Taking super ${superMethod.overriddenFunction.descriptor} -> ${superMethod.function.descriptor}") } superMethod } else { - newVtableSlots.add(OverriddenFunctionDescriptor(overridingMethod, superMethod.descriptor)) + newVtableSlots.add(OverriddenFunctionInfo(overridingMethod, superMethod.function)) - DEBUG_OUTPUT(0) { println("Taking overridden ${superMethod.overriddenDescriptor.descriptor} -> ${overridingMethod.descriptor}") } + DEBUG_OUTPUT(0) { println("Taking overridden ${superMethod.overriddenFunction.descriptor} -> ${overridingMethod.descriptor}") } - OverriddenFunctionDescriptor(overridingMethod, superMethod.overriddenDescriptor) + OverriddenFunctionInfo(overridingMethod, superMethod.overriddenFunction) } } // Add all possible (descriptor, overriddenDescriptor) edges for now, redundant will be removed later. - methods.mapTo(newVtableSlots) { OverriddenFunctionDescriptor(it, it) } + methods.mapTo(newVtableSlots) { OverriddenFunctionInfo(it, it) } - val inheritedVtableSlotsSet = inheritedVtableSlots.map { it.descriptor to it.bridgeDirections }.toSet() + val inheritedVtableSlotsSet = inheritedVtableSlots.map { it.function to it.bridgeDirections }.toSet() val filteredNewVtableSlots = newVtableSlots - .filterNot { inheritedVtableSlotsSet.contains(it.descriptor to it.bridgeDirections) } - .distinctBy { it.descriptor to it.bridgeDirections } - .filter { it.descriptor.isOverridable } + .filterNot { inheritedVtableSlotsSet.contains(it.function to it.bridgeDirections) } + .distinctBy { it.function to it.bridgeDirections } + .filter { it.function.isOverridable } DEBUG_OUTPUT(0) { println() println("INHERITED vTable slots:") - inheritedVtableSlots.forEach { println(" ${it.overriddenDescriptor.descriptor} -> ${it.descriptor.descriptor}") } + inheritedVtableSlots.forEach { println(" ${it.overriddenFunction.descriptor} -> ${it.function.descriptor}") } println() println("MY OWN vTable slots:") - filteredNewVtableSlots.forEach { println(" ${it.overriddenDescriptor.descriptor} -> ${it.descriptor.descriptor}") } + filteredNewVtableSlots.forEach { println(" ${it.overriddenFunction.descriptor} -> ${it.function.descriptor}") } } - inheritedVtableSlots + filteredNewVtableSlots.sortedBy { it.overriddenDescriptor.uniqueId } + inheritedVtableSlots + filteredNewVtableSlots.sortedBy { it.overriddenFunction.uniqueId } } fun vtableIndex(function: IrSimpleFunction): Int { - val bridgeDirections = function.target.bridgeDirectionsTo(function.original) - val index = vtableEntries.indexOfFirst { it.descriptor == function.original && it.bridgeDirections == bridgeDirections } - if (index < 0) throw Error(function.toString() + " not in vtable of " + classDescriptor.toString()) + val bridgeDirections = function.target.bridgeDirectionsTo(function) + val index = vtableEntries.indexOfFirst { it.function == function && it.bridgeDirections == bridgeDirections } + if (index < 0) throw Error(function.toString() + " not in vtable of " + irClass.toString()) return index } - val methodTableEntries: List by lazy { - classDescriptor.sortedOverridableOrOverridingMethods - .flatMap { method -> method.allOverriddenDescriptors.map { OverriddenFunctionDescriptor(method, it) } } + val methodTableEntries: List by lazy { + irClass.sortedOverridableOrOverridingMethods + .flatMap { method -> method.allOverriddenFunctions.map { OverriddenFunctionInfo(method, it) } } .filter { it.canBeCalledVirtually } - .distinctBy { it.overriddenDescriptor.uniqueId } - .sortedBy { it.overriddenDescriptor.uniqueId } + .distinctBy { it.overriddenFunction.uniqueId } + .sortedBy { it.overriddenFunction.uniqueId } // TODO: probably method table should contain all accessible methods to improve binary compatibility } diff --git a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/descriptors/DescriptorUtils.kt b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/descriptors/DescriptorUtils.kt index a5887c00578..3784ab5443e 100644 --- a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/descriptors/DescriptorUtils.kt +++ b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/descriptors/DescriptorUtils.kt @@ -127,7 +127,7 @@ internal fun IrFunction.needBridgeTo(target: IrFunction) = (0..this.valueParameters.size + 2).any { needBridgeToAt(target, it) } internal val IrSimpleFunction.target: IrSimpleFunction - get() = (if (modality == Modality.ABSTRACT) this else resolveFakeOverride()).original + get() = (if (modality == Modality.ABSTRACT) this else resolveFakeOverride()) internal val IrFunction.target: IrFunction get() = when (this) { @@ -181,7 +181,7 @@ internal class BridgeDirections(val array: Array) { } } -val IrSimpleFunction.allOverriddenDescriptors: Set +val IrSimpleFunction.allOverriddenFunctions: Set get() { val result = mutableSetOf() @@ -214,13 +214,13 @@ internal fun IrSimpleFunction.bridgeDirectionsTo( return ourDirections } -tailrec internal fun IrDeclaration.findPackage(): IrPackageFragment { +internal tailrec fun IrDeclaration.findPackage(): IrPackageFragment { val parent = this.parent return parent as? IrPackageFragment ?: (parent as IrDeclaration).findPackage() } -fun IrFunction.isComparisonDescriptor(map: Map): Boolean = +fun IrFunction.isComparisonFunction(map: Map): Boolean = this in map.values val IrDeclaration.isPropertyAccessor get() = diff --git a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/irasdescriptors/NewIrUtils.kt b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/irasdescriptors/NewIrUtils.kt index 0278c4e4ed9..dac620a46c8 100644 --- a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/irasdescriptors/NewIrUtils.kt +++ b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/irasdescriptors/NewIrUtils.kt @@ -28,9 +28,6 @@ import org.jetbrains.kotlin.serialization.deserialization.descriptors.Deserializ val IrConstructor.constructedClass get() = this.parent as IrClass -val T.original get() = this -val IrDeclaration.containingDeclaration get() = this.parent - val IrDeclarationParent.fqNameSafe: FqName get() = when (this) { is IrPackageFragment -> this.fqName is IrDeclaration -> this.parent.fqNameSafe.child(this.name) @@ -116,8 +113,6 @@ val IrProperty.konanBackingField: IrField? return null } -val IrField.containingClass get() = this.parent as? IrClass - val IrFunction.isReal get() = this.origin != IrDeclarationOrigin.FAKE_OVERRIDE // Note: psi2ir doesn't set `origin = FAKE_OVERRIDE` for fields and properties yet. @@ -151,8 +146,6 @@ fun IrSimpleFunction.overrides(other: IrSimpleFunction): Boolean { fun IrClass.isSpecialClassWithNoSupertypes() = this.isAny() || this.isNothing() -internal val IrValueParameter.isValueParameter get() = this.index >= 0 - private val IrCall.annotationClass get() = (this.symbol.owner as IrConstructor).constructedClass diff --git a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/BinaryInterface.kt b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/BinaryInterface.kt index 6078a0077d4..5bd59008962 100644 --- a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/BinaryInterface.kt +++ b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/BinaryInterface.kt @@ -17,7 +17,6 @@ import org.jetbrains.kotlin.descriptors.ModuleDescriptor import org.jetbrains.kotlin.descriptors.PropertyAccessorDescriptor import org.jetbrains.kotlin.descriptors.Visibilities import org.jetbrains.kotlin.descriptors.Visibility -import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor import org.jetbrains.kotlin.ir.declarations.* import org.jetbrains.kotlin.ir.symbols.IrTypeParameterSymbol import org.jetbrains.kotlin.ir.types.* @@ -181,37 +180,35 @@ private val IrFunction.signature: String // TODO: rename to indicate that it has signature included internal val IrFunction.functionName: String get() { - with(this.original) { // basic support for generics - (if (this is IrConstructor && this.isObjCConstructor) this.getObjCInitMethod() else this)?.getObjCMethodInfo()?.let { - return buildString { - if (extensionReceiverParameter != null) { - append(extensionReceiverParameter!!.type.getClass()!!.name) - append(".") - } + (if (this is IrConstructor && this.isObjCConstructor) this.getObjCInitMethod() else this)?.getObjCMethodInfo()?.let { + return buildString { + if (extensionReceiverParameter != null) { + append(extensionReceiverParameter!!.type.getClass()!!.name) + append(".") + } - append("objc:") - append(it.selector) - if (this@with is IrConstructor && this@with.isObjCConstructor) append("#Constructor") + append("objc:") + append(it.selector) + if (this@functionName is IrConstructor && this@functionName.isObjCConstructor) append("#Constructor") - // We happen to have the clashing combinations such as - //@ObjCMethod("issueChallengeToPlayers:message:", "objcKniBridge1165") - //external fun GKScore.issueChallengeToPlayers(playerIDs: List<*>?, message: String?): Unit - //@ObjCMethod("issueChallengeToPlayers:message:", "objcKniBridge1172") - //external fun GKScore.issueChallengeToPlayers(playerIDs: List<*>?, message: String?): Unit - // So disambiguate by the name of the bridge for now. - // TODO: idealy we'd never generate such identical declarations. + // We happen to have the clashing combinations such as + //@ObjCMethod("issueChallengeToPlayers:message:", "objcKniBridge1165") + //external fun GKScore.issueChallengeToPlayers(playerIDs: List<*>?, message: String?): Unit + //@ObjCMethod("issueChallengeToPlayers:message:", "objcKniBridge1172") + //external fun GKScore.issueChallengeToPlayers(playerIDs: List<*>?, message: String?): Unit + // So disambiguate by the name of the bridge for now. + // TODO: idealy we'd never generate such identical declarations. - if (this@with is IrSimpleFunction && this@with.hasObjCMethodAnnotation()) { - this@with.objCMethodArgValue("selector") ?.let { append("#$it") } - this@with.objCMethodArgValue("bridge") ?.let { append("#$it") } - } + if (this@functionName is IrSimpleFunction && this@functionName.hasObjCMethodAnnotation()) { + this@functionName.objCMethodArgValue("selector") ?.let { append("#$it") } + this@functionName.objCMethodArgValue("bridge") ?.let { append("#$it") } } } - - val name = this.name.mangleIfInternal(this.module, this.visibility) - - return "$name$signature" } + + val name = this.name.mangleIfInternal(this.module, this.visibility) + + return "$name$signature" } private fun Name.mangleIfInternal(moduleDescriptor: ModuleDescriptor, visibility: Visibility): String = @@ -260,14 +257,13 @@ internal val IrField.symbolName: String // TODO: bring here dependencies of this method? internal fun RuntimeAware.getLlvmFunctionType(function: IrFunction): LLVMTypeRef { - val original = function.original val returnType = when { - original is IrConstructor -> voidType - original.isSuspend -> kObjHeaderPtr // Suspend functions return Any?. - else -> getLLVMReturnType(original.returnType) + function is IrConstructor -> voidType + function.isSuspend -> kObjHeaderPtr // Suspend functions return Any?. + else -> getLLVMReturnType(function.returnType) } - val paramTypes = ArrayList(original.allParameters.map { getLLVMType(it.type) }) - if (original.isSuspend) + val paramTypes = ArrayList(function.allParameters.map { getLLVMType(it.type) }) + if (function.isSuspend) paramTypes.add(kObjHeaderPtr) // Suspend functions have implicit parameter of type Continuation<>. if (isObjectType(returnType)) paramTypes.add(kObjHeaderPtrPtr) diff --git a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/CodeGenerator.kt b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/CodeGenerator.kt index 9bc35a45a72..44de7247377 100644 --- a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/CodeGenerator.kt +++ b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/CodeGenerator.kt @@ -8,7 +8,6 @@ package org.jetbrains.kotlin.backend.konan.llvm import kotlinx.cinterop.* import llvm.* -import org.jetbrains.kotlin.backend.common.ir.ir2string import org.jetbrains.kotlin.backend.konan.* import org.jetbrains.kotlin.backend.konan.descriptors.isInterface import org.jetbrains.kotlin.backend.konan.irasdescriptors.* @@ -29,8 +28,7 @@ internal class CodeGenerator(override val context: Context) : ContextUtils { //-------------------------------------------------------------------------// - /* to class descriptor */ - fun typeInfoValue(descriptor: IrClass): LLVMValueRef = descriptor.llvmTypeInfoPtr + fun typeInfoValue(irClass: IrClass): LLVMValueRef = irClass.llvmTypeInfoPtr fun param(fn: IrFunction, i: Int): LLVMValueRef { assert(i >= 0 && i < countParams(fn)) @@ -39,19 +37,19 @@ internal class CodeGenerator(override val context: Context) : ContextUtils { private fun countParams(fn: IrFunction) = LLVMCountParams(fn.llvmFunction) - fun functionEntryPointAddress(descriptor: IrFunction) = descriptor.entryPointAddress.llvm - fun functionHash(descriptor: IrFunction): LLVMValueRef = descriptor.functionName.localHash.llvm + fun functionEntryPointAddress(function: IrFunction) = function.entryPointAddress.llvm + fun functionHash(function: IrFunction): LLVMValueRef = function.functionName.localHash.llvm - fun getObjectInstanceStorage(descriptor: IrClass, shared: Boolean): LLVMValueRef { - assert (!descriptor.isUnit()) - val llvmGlobal = if (!isExternal(descriptor)) { - context.llvmDeclarations.forSingleton(descriptor).instanceFieldRef + fun getObjectInstanceStorage(irClass: IrClass, shared: Boolean): LLVMValueRef { + assert (!irClass.isUnit()) + val llvmGlobal = if (!isExternal(irClass)) { + context.llvmDeclarations.forSingleton(irClass).instanceFieldRef } else { - val llvmType = getLLVMType(descriptor.defaultType) + val llvmType = getLLVMType(irClass.defaultType) importGlobal( - descriptor.objectInstanceFieldSymbolName, + irClass.objectInstanceFieldSymbolName, llvmType, - origin = descriptor.llvmSymbolOrigin, + origin = irClass.llvmSymbolOrigin, threadLocal = !shared ) } @@ -62,17 +60,17 @@ internal class CodeGenerator(override val context: Context) : ContextUtils { return llvmGlobal } - fun getObjectInstanceShadowStorage(descriptor: IrClass): LLVMValueRef { - assert (!descriptor.isUnit()) - assert (descriptor.objectIsShared) - val llvmGlobal = if (!isExternal(descriptor)) { - context.llvmDeclarations.forSingleton(descriptor).instanceShadowFieldRef!! + fun getObjectInstanceShadowStorage(irClass: IrClass): LLVMValueRef { + assert (!irClass.isUnit()) + assert (irClass.objectIsShared) + val llvmGlobal = if (!isExternal(irClass)) { + context.llvmDeclarations.forSingleton(irClass).instanceShadowFieldRef!! } else { - val llvmType = getLLVMType(descriptor.defaultType) + val llvmType = getLLVMType(irClass.defaultType) importGlobal( - descriptor.objectInstanceShadowFieldSymbolName, + irClass.objectInstanceShadowFieldSymbolName, llvmType, - origin = descriptor.llvmSymbolOrigin, + origin = irClass.llvmSymbolOrigin, threadLocal = true ) } @@ -112,18 +110,18 @@ val LLVMValueRef.isConst:Boolean internal inline fun generateFunction(codegen: CodeGenerator, - descriptor: IrFunction, + function: IrFunction, startLocation: LocationInfo? = null, endLocation: LocationInfo? = null, code:FunctionGenerationContext.(FunctionGenerationContext) -> R) { - val llvmFunction = codegen.llvmFunction(descriptor) + val llvmFunction = codegen.llvmFunction(function) generateFunctionBody(FunctionGenerationContext( llvmFunction, codegen, startLocation, endLocation, - descriptor), code) + function), code) } @@ -143,7 +141,7 @@ internal inline fun generateFunction( return function } -inline private fun generateFunctionBody( +private inline fun generateFunctionBody( functionGenerationContext: FunctionGenerationContext, code: FunctionGenerationContext.(FunctionGenerationContext) -> R) { functionGenerationContext.prologue() @@ -158,7 +156,7 @@ internal class FunctionGenerationContext(val function: LLVMValueRef, val codegen: CodeGenerator, startLocation: LocationInfo?, endLocation: LocationInfo?, - internal val functionDescriptor: IrFunction? = null): ContextUtils { + internal val irFunction: IrFunction? = null): ContextUtils { override val context = codegen.context val vars = VariableManager(this) @@ -171,9 +169,8 @@ internal class FunctionGenerationContext(val function: LLVMValueRef, var returnType: LLVMTypeRef? = LLVMGetReturnType(getFunctionType(function)) private val returns: MutableMap = mutableMapOf() - // TODO: remove, to make CodeGenerator descriptor-agnostic. val constructedClass: IrClass? - get() = (functionDescriptor as? IrConstructor)?.constructedClass + get() = (irFunction as? IrConstructor)?.constructedClass private var returnSlot: LLVMValueRef? = null private var slotsPhi: LLVMValueRef? = null private val frameOverlaySlotCount = @@ -195,8 +192,8 @@ internal class FunctionGenerationContext(val function: LLVMValueRef, var forwardingForeignExceptionsTerminatedWith: LLVMValueRef? = null init { - functionDescriptor?.let { - if (!functionDescriptor.isExported()) { + irFunction?.let { + if (!irFunction.isExported()) { LLVMSetLinkage(function, LLVMLinkage.LLVMInternalLinkage) // (Cannot do this before the function body is created). } @@ -409,8 +406,8 @@ internal class FunctionGenerationContext(val function: LLVMValueRef, return call(context.llvm.allocInstanceFunction, listOf(typeInfo), lifetime) } - fun allocInstance(descriptor: IrClass, lifetime: Lifetime): LLVMValueRef = - allocInstance(codegen.typeInfoForAllocation(descriptor), lifetime) + fun allocInstance(irClass: IrClass, lifetime: Lifetime): LLVMValueRef = + allocInstance(codegen.typeInfoForAllocation(irClass), lifetime) fun allocArray( typeInfo: LLVMValueRef, count: LLVMValueRef, lifetime: Lifetime): LLVMValueRef { @@ -628,10 +625,10 @@ internal class FunctionGenerationContext(val function: LLVMValueRef, return switch } - fun lookupVirtualImpl(receiver: LLVMValueRef, descriptor: IrFunction): LLVMValueRef { + fun lookupVirtualImpl(receiver: LLVMValueRef, irFunction: IrFunction): LLVMValueRef { assert(LLVMTypeOf(receiver) == codegen.kObjHeaderPtr) - val typeInfoPtr: LLVMValueRef = if (descriptor.getObjCMethodInfo() != null) { + val typeInfoPtr: LLVMValueRef = if (irFunction.getObjCMethodInfo() != null) { call(context.llvm.getObjCKotlinTypeInfo, listOf(receiver)) } else { val typeInfoOrMetaPtr = structGep(receiver, 0 /* typeInfoOrMeta_ */) @@ -651,12 +648,12 @@ internal class FunctionGenerationContext(val function: LLVMValueRef, * if toString/eq/hc is invoked on an interface instance, we resolve * owner as Any and dispatch it via vtable. */ - val anyMethod = (descriptor as IrSimpleFunction).findOverriddenMethodOfAny() - val owner = (anyMethod ?: descriptor).containingDeclaration as IrClass + val anyMethod = (irFunction as IrSimpleFunction).findOverriddenMethodOfAny() + val owner = (anyMethod ?: irFunction).parentAsClass val llvmMethod = if (!owner.isInterface) { // If this is a virtual method of the class - we can call via vtable. - val index = context.getVtableBuilder(owner).vtableIndex(anyMethod ?: descriptor) + val index = context.getVtableBuilder(owner).vtableIndex(anyMethod ?: irFunction) val vtablePlace = gep(typeInfoPtr, Int32(1).llvm) // typeInfoPtr + 1 val vtable = bitcast(kInt8PtrPtr, vtablePlace) val slot = gep(vtable, Int32(index).llvm) @@ -666,11 +663,11 @@ internal class FunctionGenerationContext(val function: LLVMValueRef, // TODO: optimize by storing interface number in lower bits of 'this' pointer // when passing object as an interface. This way we can use those bits as index // for an additional per-interface vtable. - val methodHash = codegen.functionHash(descriptor) // Calculate hash of the method to be invoked + val methodHash = codegen.functionHash(irFunction) // Calculate hash of the method to be invoked val lookupArgs = listOf(typeInfoPtr, methodHash) // Prepare args for lookup call(context.llvm.lookupOpenMethodFunction, lookupArgs) } - val functionPtrType = pointerType(codegen.getLlvmFunctionType(descriptor)) // Construct type of the method to be invoked + val functionPtrType = pointerType(codegen.getLlvmFunctionType(irFunction)) // Construct type of the method to be invoked return bitcast(functionPtrType, llvmMethod) // Cast method address to the type } @@ -685,16 +682,16 @@ internal class FunctionGenerationContext(val function: LLVMValueRef, } fun getObjectValue( - descriptor: IrClass, - exceptionHandler: ExceptionHandler, - locationInfo: LocationInfo? + irClass: IrClass, + exceptionHandler: ExceptionHandler, + locationInfo: LocationInfo? ): LLVMValueRef { - if (descriptor.isUnit()) { + if (irClass.isUnit()) { return codegen.theUnitInstanceRef.llvm } - if (descriptor.isCompanion) { - val parent = descriptor.parent as IrClass + if (irClass.isCompanion) { + val parent = irClass.parent as IrClass if (parent.isObjCClass()) { // TODO: cache it too. @@ -707,8 +704,8 @@ internal class FunctionGenerationContext(val function: LLVMValueRef, } } - val shared = descriptor.objectIsShared && context.config.threadsAreAllowed - val objectPtr = codegen.getObjectInstanceStorage(descriptor, shared) + val shared = irClass.objectIsShared && context.config.threadsAreAllowed + val objectPtr = codegen.getObjectInstanceStorage(irClass, shared) val bbInit = basicBlock("label_init", locationInfo) val bbExit = basicBlock("label_continue", locationInfo) val objectVal = loadSlot(objectPtr, false) @@ -717,12 +714,12 @@ internal class FunctionGenerationContext(val function: LLVMValueRef, condBr(objectInitialized, bbExit, bbInit) positionAtEnd(bbInit) - val typeInfo = codegen.typeInfoForAllocation(descriptor) - val defaultConstructor = descriptor.constructors.single { it.valueParameters.size == 0 } + val typeInfo = codegen.typeInfoForAllocation(irClass) + val defaultConstructor = irClass.constructors.single { it.valueParameters.size == 0 } val ctor = codegen.llvmFunction(defaultConstructor) val (initFunction, args) = if (shared) { - val shadowObjectPtr = codegen.getObjectInstanceShadowStorage(descriptor) + val shadowObjectPtr = codegen.getObjectInstanceShadowStorage(irClass) context.llvm.initSharedInstanceFunction to listOf(objectPtr, shadowObjectPtr, typeInfo, ctor) } else { context.llvm.initInstanceFunction to listOf(objectPtr, typeInfo, ctor) @@ -732,7 +729,7 @@ internal class FunctionGenerationContext(val function: LLVMValueRef, br(bbExit) positionAtEnd(bbExit) - val valuePhi = phi(codegen.getLLVMType(descriptor.defaultType)) + val valuePhi = phi(codegen.getLLVMType(irClass.defaultType)) addPhiIncoming(valuePhi, bbCurrent to objectVal, bbInitResult to newValue) return valuePhi @@ -741,11 +738,11 @@ internal class FunctionGenerationContext(val function: LLVMValueRef, /** * Note: the same code is generated as IR in [org.jetbrains.kotlin.backend.konan.lower.EnumUsageLowering]. */ - fun getEnumEntry(descriptor: IrEnumEntry, exceptionHandler: ExceptionHandler): LLVMValueRef { - val enumClassDescriptor = descriptor.containingDeclaration as IrClass - val loweredEnum = context.specialDeclarationsFactory.getLoweredEnum(enumClassDescriptor) + fun getEnumEntry(enumEntry: IrEnumEntry, exceptionHandler: ExceptionHandler): LLVMValueRef { + val enumClass = enumEntry.parentAsClass + val loweredEnum = context.specialDeclarationsFactory.getLoweredEnum(enumClass) - val ordinal = loweredEnum.entriesMap[descriptor.name]!! + val ordinal = loweredEnum.entriesMap[enumEntry.name]!! val values = call( loweredEnum.valuesGetter.llvmFunction, emptyList(), diff --git a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/ContextUtils.kt b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/ContextUtils.kt index 6ca34870e16..43eeadadcc8 100644 --- a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/ContextUtils.kt +++ b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/ContextUtils.kt @@ -141,8 +141,8 @@ internal interface ContextUtils : RuntimeAware { val staticData: StaticData get() = context.llvm.staticData - fun isExternal(descriptor: IrDeclaration): Boolean { - val pkg = descriptor.findPackage() + fun isExternal(declaration: IrDeclaration): Boolean { + val pkg = declaration.findPackage() return when (pkg) { is IrFile -> pkg.packageFragmentDescriptor.containingDeclaration != context.moduleDescriptor is IrExternalPackageFragment -> true diff --git a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/IrToBitcode.kt b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/IrToBitcode.kt index c71c1e9371f..0c75312e9dd 100644 --- a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/IrToBitcode.kt +++ b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/IrToBitcode.kt @@ -19,7 +19,6 @@ import org.jetbrains.kotlin.builtins.KotlinBuiltIns import org.jetbrains.kotlin.builtins.UnsignedType import org.jetbrains.kotlin.descriptors.Modality import org.jetbrains.kotlin.descriptors.PropertyDescriptor -import org.jetbrains.kotlin.descriptors.SourceFile import org.jetbrains.kotlin.descriptors.konan.CurrentKonanModuleOrigin import org.jetbrains.kotlin.ir.IrElement import org.jetbrains.kotlin.ir.IrStatement @@ -33,7 +32,7 @@ import org.jetbrains.kotlin.ir.symbols.* import org.jetbrains.kotlin.ir.types.* import org.jetbrains.kotlin.ir.util.defaultType import org.jetbrains.kotlin.ir.util.getArguments -import org.jetbrains.kotlin.ir.util.getContainingFile +import org.jetbrains.kotlin.ir.util.parentAsClass import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid import org.jetbrains.kotlin.ir.visitors.acceptChildrenVoid import org.jetbrains.kotlin.ir.visitors.acceptVoid @@ -194,11 +193,9 @@ internal class RTTIGeneratorVisitor(context: Context) : IrElementVisitorVoid { override fun visitClass(declaration: IrClass) { super.visitClass(declaration) - val descriptor = declaration + generator.generate(declaration) - generator.generate(descriptor) - - if (descriptor.isKotlinObjCClass()) { + if (declaration.isKotlinObjCClass()) { kotlinObjCClassInfoGenerator.generate(declaration) } } @@ -232,19 +229,19 @@ internal interface CodeContext { * Declares the variable. * @return index of declared variable. */ - fun genDeclareVariable(descriptor: IrVariable, value: LLVMValueRef?, variableLocation: VariableDebugLocation?): Int + fun genDeclareVariable(variable: IrVariable, value: LLVMValueRef?, variableLocation: VariableDebugLocation?): Int /** * @return index of variable declared before, or -1 if no such variable has been declared yet. */ - fun getDeclaredVariable(descriptor: IrVariable): Int + fun getDeclaredVariable(variable: IrVariable): Int /** * Generates the code to obtain a value available in this context. * * @return the requested value */ - fun genGetValue(descriptor: IrValueDeclaration): LLVMValueRef + fun genGetValue(value: IrValueDeclaration): LLVMValueRef /** * Returns owning function scope. @@ -342,11 +339,11 @@ internal class CodeGeneratorVisitor(val context: Context, val lifetimes: Map { - if (descriptor == null) return emptyMap() - val parameterDescriptors = descriptor.allParameters - return parameterDescriptors.mapIndexed { i, parameterDescriptor -> - val parameter = codegen.param(descriptor, i) - assert(codegen.getLLVMType(parameterDescriptor.type) == parameter.type) - parameterDescriptor to parameter + private fun bindParameters(function: IrFunction?): Map { + if (function == null) return emptyMap() + return function.allParameters.mapIndexed { i, irParameter -> + val parameter = codegen.param(function, i) + assert(codegen.getLLVMType(irParameter.type) == parameter.type) + irParameter to parameter }.toMap() } @@ -750,9 +745,10 @@ internal class CodeGeneratorVisitor(val context: Context, val lifetimes: Map if (initializer != null) LLVMSetInitializer(globalProperty, evaluateExpression(initializer)) @@ -1378,14 +1373,14 @@ internal class CodeGeneratorVisitor(val context: Context, val lifetimes: Map().single { it.name.asString() == "invokeSuspend" } private fun getContinuation(): LLVMValueRef { - val caller = functionGenerationContext.functionDescriptor!! + val caller = functionGenerationContext.irFunction!! return if (caller.isSuspend) codegen.param(caller, caller.allParameters.size) // The last argument. else { @@ -2002,11 +1996,10 @@ internal class CodeGeneratorVisitor(val context: Context, val lifetimes: Map, - resultLifetime: Lifetime, superClass: IrClass? = null): LLVMValueRef { + function: IrFunction, args: List, + resultLifetime: Lifetime, superClass: IrClass? = null): LLVMValueRef { //context.log{"evaluateSimpleFunctionCall : $tmpVariableName = ${ir2string(value)}"} - if (superClass == null && descriptor is IrSimpleFunction && descriptor.isOverridable) - return callVirtual(descriptor, args, resultLifetime) + if (superClass == null && function is IrSimpleFunction && function.isOverridable) + return callVirtual(function, args, resultLifetime) else - return callDirect(descriptor, args, resultLifetime) + return callDirect(function, args, resultLifetime) } //-------------------------------------------------------------------------// @@ -2190,8 +2183,8 @@ internal class CodeGeneratorVisitor(val context: Context, val lifetimes: Map): LLVMValueRef { context.log{"evaluateOperatorCall : origin:${ir2string(callee)}"} - val descriptor = callee.symbol.owner + val function = callee.symbol.owner val ib = context.irModule!!.irBuiltins with(functionGenerationContext) { return when { - descriptor == ib.eqeqeqFun -> icmpEq(args[0], args[1]) - descriptor == ib.booleanNotFun -> icmpNe(args[0], kTrue) + function == ib.eqeqeqFun -> icmpEq(args[0], args[1]) + function == ib.booleanNotFun -> icmpNe(args[0], kTrue) - descriptor.isComparisonDescriptor(ib.greaterFunByOperandType) -> { + function.isComparisonFunction(ib.greaterFunByOperandType) -> { if (args[0].type.isFloatingPoint()) fcmpGt(args[0], args[1]) else icmpGt(args[0], args[1]) } - descriptor.isComparisonDescriptor(ib.greaterOrEqualFunByOperandType) -> { + function.isComparisonFunction(ib.greaterOrEqualFunByOperandType) -> { if (args[0].type.isFloatingPoint()) fcmpGe(args[0], args[1]) else icmpGe(args[0], args[1]) } - descriptor.isComparisonDescriptor(ib.lessFunByOperandType) -> { + function.isComparisonFunction(ib.lessFunByOperandType) -> { if (args[0].type.isFloatingPoint()) fcmpLt(args[0], args[1]) else icmpLt(args[0], args[1]) } - descriptor.isComparisonDescriptor(ib.lessOrEqualFunByOperandType) -> { + function.isComparisonFunction(ib.lessOrEqualFunByOperandType) -> { if (args[0].type.isFloatingPoint()) fcmpLe(args[0], args[1]) else icmpLe(args[0], args[1]) } - else -> TODO(descriptor.name.toString()) + else -> TODO(function.name.toString()) } } } //-------------------------------------------------------------------------// - fun callDirect(descriptor: IrFunction, args: List, + fun callDirect(function: IrFunction, args: List, resultLifetime: Lifetime): LLVMValueRef { - val realDescriptor = descriptor.target - val llvmFunction = codegen.llvmFunction(realDescriptor) - return call(descriptor, llvmFunction, args, resultLifetime) + val llvmFunction = codegen.llvmFunction(function.target) + return call(function, llvmFunction, args, resultLifetime) } //-------------------------------------------------------------------------// - fun callVirtual(descriptor: IrFunction, args: List, + fun callVirtual(function: IrFunction, args: List, resultLifetime: Lifetime): LLVMValueRef { - val function = functionGenerationContext.lookupVirtualImpl(args.first(), descriptor) + val llvmFunction = functionGenerationContext.lookupVirtualImpl(args.first(), function) - return call(descriptor, function, args, resultLifetime) // Invoke the method + return call(function, llvmFunction, args, resultLifetime) // Invoke the method } //-------------------------------------------------------------------------// - // TODO: it seems to be much more reliable to get args as a mapping from parameter descriptor to LLVM value, - // instead of a plain list. - // In such case it would be possible to check that all args are available and in the correct order. - // However, it currently requires some refactoring to be performed. - private fun call(descriptor: IrFunction, function: LLVMValueRef, args: List, + private fun call(function: IrFunction, llvmFunction: LLVMValueRef, args: List, resultLifetime: Lifetime): LLVMValueRef { - val result = call(function, args, resultLifetime) - if (descriptor.returnType.isNothing()) { + val result = call(llvmFunction, args, resultLifetime) + if (function.returnType.isNothing()) { functionGenerationContext.unreachable() } - if (LLVMGetReturnType(getFunctionType(function)) == voidType) { + if (LLVMGetReturnType(getFunctionType(llvmFunction)) == voidType) { return codegen.theUnitInstanceRef.llvm } @@ -2289,10 +2277,6 @@ internal class CodeGeneratorVisitor(val context: Context, val lifetimes: Map, resultLifetime: Lifetime): LLVMValueRef { val result = call(function, args, resultLifetime) @@ -2315,17 +2299,17 @@ internal class CodeGeneratorVisitor(val context: Context, val lifetimes: Map): LLVMValueRef { + constructor: IrConstructor, args: List): LLVMValueRef { val constructedClass = functionGenerationContext.constructedClass!! val thisPtr = currentCodeContext.genGetValue(constructedClass.thisReceiver!!) - if (descriptor.constructedClass.isExternalObjCClass()) { + if (constructor.constructedClass.isExternalObjCClass()) { assert(args.isEmpty()) return codegen.theUnitInstanceRef.llvm } - val thisPtrArgType = codegen.getLLVMType(descriptor.allParameters[0].type) + val thisPtrArgType = codegen.getLLVMType(constructor.allParameters[0].type) val thisPtrArg = if (thisPtr.type == thisPtrArgType) { thisPtr } else { @@ -2333,7 +2317,7 @@ internal class CodeGeneratorVisitor(val context: Context, val lifetimes: Map, private val staticFields: Map, private val unique: Map) { - fun forFunction(descriptor: IrFunction) = functions[descriptor] ?: - error("${descriptor.toString()} ${descriptor.name} in ${(descriptor.parent as IrDeclaration).name}") + fun forFunction(function: IrFunction) = functions[function] ?: + error("${function.descriptor} in ${(function.parent as IrDeclaration).name}") - fun forClass(descriptor: IrClass) = classes[descriptor] ?: - error("$descriptor ${descriptor.name}") + fun forClass(irClass: IrClass) = classes[irClass] ?: + error(irClass.descriptor.toString()) - fun forField(descriptor: IrField) = fields[descriptor] ?: - error(descriptor.toString()) + fun forField(field: IrField) = fields[field] ?: + error(field.descriptor.toString()) - fun forStaticField(descriptor: IrField) = staticFields[descriptor] ?: - error(descriptor.toString()) + fun forStaticField(field: IrField) = staticFields[field] ?: + error(field.descriptor.toString()) - fun forSingleton(descriptor: IrClass) = forClass(descriptor).singletonDeclarations ?: - error(descriptor.toString()) + fun forSingleton(irClass: IrClass) = forClass(irClass).singletonDeclarations ?: + error(irClass.descriptor.toString()) fun forUnique(kind: UniqueKind) = unique[kind] ?: error("No unique $kind") @@ -91,19 +91,19 @@ internal class UniqueLlvmDeclarations(val pointer: ConstPointer) * All fields of the class instance. * The order respects the class hierarchy, i.e. a class [fields] contains superclass [fields] as a prefix. */ -internal fun ContextUtils.getFields(classDescriptor: IrClass) = context.getFields(classDescriptor) +internal fun ContextUtils.getFields(irClass: IrClass) = context.getFields(irClass) -internal fun Context.getFields(classDescriptor: IrClass): List { - val superClass = classDescriptor.getSuperClassNotAny() // TODO: what if Any has fields? +internal fun Context.getFields(irClass: IrClass): List { + val superClass = irClass.getSuperClassNotAny() // TODO: what if Any has fields? val superFields = if (superClass != null) getFields(superClass) else emptyList() - return superFields + getDeclaredFields(classDescriptor) + return superFields + getDeclaredFields(irClass) } /** * Fields declared in the class. */ -private fun Context.getDeclaredFields(classDescriptor: IrClass): List { +private fun Context.getDeclaredFields(irClass: IrClass): List { // TODO: Here's what is going on here: // The existence of a backing field for a property is only described in the IR, // but not in the PropertyDescriptor. @@ -114,7 +114,6 @@ private fun Context.getDeclaredFields(classDescriptor: IrClass): List { // In this function we check the presence of the backing field // two ways: first we check IR, then we check the protobuf extension. - val irClass = classDescriptor val fields = irClass.declarations.mapNotNull { when (it) { is IrField -> it.takeIf { it.isReal } @@ -125,7 +124,7 @@ private fun Context.getDeclaredFields(classDescriptor: IrClass): List { // TODO: hack over missed parents in deserialized fields/property declarations. fields.forEach{it.parent = irClass} - if (classDescriptor.hasAnnotation(FqName.fromSegments(listOf("kotlin", "native", "internal", "NoReorderFields")))) + if (irClass.hasAnnotation(FqName.fromSegments(listOf("kotlin", "native", "internal", "NoReorderFields")))) return fields return fields.sortedBy { @@ -157,8 +156,8 @@ private class DeclarationsGeneratorVisitor(override val context: Context) : private val names = mutableMapOf() private val counts = mutableMapOf() - fun getName(parent: FqName, descriptor: IrDeclaration): Name { - return names.getOrPut(descriptor) { + fun getName(parent: FqName, declaration: IrDeclaration): Name { + return names.getOrPut(declaration) { val count = counts.getOrDefault(parent, 0) + 1 counts[parent] = count Name.identifier(prefix + count) @@ -168,34 +167,34 @@ private class DeclarationsGeneratorVisitor(override val context: Context) : val objectNamer = Namer("object-") - private fun getLocalName(parent: FqName, descriptor: IrDeclaration): Name { - if (descriptor.isAnonymousObject) { - return objectNamer.getName(parent, descriptor) + private fun getLocalName(parent: FqName, declaration: IrDeclaration): Name { + if (declaration.isAnonymousObject) { + return objectNamer.getName(parent, declaration) } - return descriptor.name + return declaration.name } - private fun getFqName(descriptor: IrDeclaration): FqName { - val parent = descriptor.parent + private fun getFqName(declaration: IrDeclaration): FqName { + val parent = declaration.parent val parentFqName = when (parent) { is IrPackageFragment -> parent.fqName is IrDeclaration -> getFqName(parent) else -> error(parent) } - val localName = getLocalName(parentFqName, descriptor) + val localName = getLocalName(parentFqName, declaration) return parentFqName.child(localName) } /** - * Produces the name to be used for non-exported LLVM declarations corresponding to [descriptor]. + * Produces the name to be used for non-exported LLVM declarations corresponding to [declaration]. * * Note: since these declarations are going to be private, the name is only required not to clash with any * exported declarations. */ - private fun qualifyInternalName(descriptor: IrDeclaration): String { - return getFqName(descriptor).asString() + "#internal" + private fun qualifyInternalName(declaration: IrDeclaration): String { + return getFqName(declaration).asString() + "#internal" } override fun visitElement(element: IrElement) { @@ -209,30 +208,28 @@ private class DeclarationsGeneratorVisitor(override val context: Context) : } private fun createClassDeclarations(declaration: IrClass): ClassLlvmDeclarations { - val descriptor = declaration + val internalName = qualifyInternalName(declaration) - val internalName = qualifyInternalName(descriptor) - - val fields = getFields(descriptor) + val fields = getFields(declaration) val bodyType = createClassBodyType("kclassbody:$internalName", fields) val typeInfoPtr: ConstPointer val typeInfoGlobal: StaticData.Global - val typeInfoSymbolName = if (descriptor.isExported()) { - descriptor.typeInfoSymbolName + val typeInfoSymbolName = if (declaration.isExported()) { + declaration.typeInfoSymbolName } else { "ktype:$internalName" } - if (descriptor.typeInfoHasVtableAttached) { + if (declaration.typeInfoHasVtableAttached) { // Create the special global consisting of TypeInfo and vtable. val typeInfoGlobalName = "ktypeglobal:$internalName" val typeInfoWithVtableType = structType( runtime.typeInfoType, - LLVMArrayType(int8TypePtr, context.getVtableBuilder(descriptor).vtableEntries.size)!! + LLVMArrayType(int8TypePtr, context.getVtableBuilder(declaration).vtableEntries.size)!! ) typeInfoGlobal = staticData.createGlobal(typeInfoWithVtableType, typeInfoGlobalName, isExported = false) @@ -242,7 +239,7 @@ private class DeclarationsGeneratorVisitor(override val context: Context) : typeInfoGlobal.pointer.getElementPtr(0).llvm, typeInfoSymbolName)!! - if (descriptor.isExported()) { + if (declaration.isExported()) { if (llvmTypeInfoPtr.name != typeInfoSymbolName) { // So alias name has been mangled by LLVM to avoid name clash. throw IllegalArgumentException("Global '$typeInfoSymbolName' already exists") @@ -256,22 +253,22 @@ private class DeclarationsGeneratorVisitor(override val context: Context) : } else { typeInfoGlobal = staticData.createGlobal(runtime.typeInfoType, typeInfoSymbolName, - isExported = descriptor.isExported()) + isExported = declaration.isExported()) typeInfoPtr = typeInfoGlobal.pointer } - if (descriptor.isUnit() || descriptor.isKotlinArray()) - createUniqueDeclarations(descriptor, typeInfoPtr, bodyType) + if (declaration.isUnit() || declaration.isKotlinArray()) + createUniqueDeclarations(declaration, typeInfoPtr, bodyType) - val singletonDeclarations = if (descriptor.kind.isSingleton) { - createSingletonDeclarations(descriptor) + val singletonDeclarations = if (declaration.kind.isSingleton) { + createSingletonDeclarations(declaration) } else { null } - val objCDeclarations = if (descriptor.isKotlinObjCClass()) { - createKotlinObjCClassDeclarations(descriptor) + val objCDeclarations = if (declaration.isKotlinObjCClass()) { + createKotlinObjCClassDeclarations(declaration) } else { null } @@ -279,8 +276,8 @@ private class DeclarationsGeneratorVisitor(override val context: Context) : val writableTypeInfoType = runtime.writableTypeInfoType val writableTypeInfoGlobal = if (writableTypeInfoType == null) { null - } else if (descriptor.isExported()) { - val name = descriptor.writableTypeInfoSymbolName + } else if (declaration.isExported()) { + val name = declaration.writableTypeInfoSymbolName staticData.createGlobal(writableTypeInfoType, name, isExported = true).also { it.setLinkage(LLVMLinkage.LLVMCommonLinkage) // Allows to be replaced by other bitcode module. } @@ -295,35 +292,35 @@ private class DeclarationsGeneratorVisitor(override val context: Context) : } private fun createUniqueDeclarations( - descriptor: IrClass, typeInfoPtr: ConstPointer, bodyType: LLVMTypeRef) { + irClass: IrClass, typeInfoPtr: ConstPointer, bodyType: LLVMTypeRef) { when { - descriptor.isUnit() -> { + irClass.isUnit() -> { uniques[UniqueKind.UNIT] = UniqueLlvmDeclarations(staticData.createUniqueInstance(UniqueKind.UNIT, bodyType, typeInfoPtr)) } - descriptor.isKotlinArray() -> { + irClass.isKotlinArray() -> { uniques[UniqueKind.EMPTY_ARRAY] = UniqueLlvmDeclarations(staticData.createUniqueInstance(UniqueKind.EMPTY_ARRAY, bodyType, typeInfoPtr)) } - else -> TODO("Unsupported unique $descriptor") + else -> TODO("Unsupported unique $irClass") } } - private fun createSingletonDeclarations(descriptor: IrClass): SingletonLlvmDeclarations? { + private fun createSingletonDeclarations(irClass: IrClass): SingletonLlvmDeclarations? { - if (descriptor.isUnit()) { + if (irClass.isUnit()) { return null } - val isExported = descriptor.isExported() + val isExported = irClass.isExported() val symbolName = if (isExported) { - descriptor.objectInstanceFieldSymbolName + irClass.objectInstanceFieldSymbolName } else { - "kobjref:" + qualifyInternalName(descriptor) + "kobjref:" + qualifyInternalName(irClass) } - val threadLocal = !(descriptor.objectIsShared && context.config.threadsAreAllowed) + val threadLocal = !(irClass.objectIsShared && context.config.threadsAreAllowed) val instanceFieldRef = addGlobal( - symbolName, getLLVMType(descriptor.defaultType), isExported = isExported, threadLocal = threadLocal) + symbolName, getLLVMType(irClass.defaultType), isExported = isExported, threadLocal = threadLocal) LLVMSetInitializer(instanceFieldRef, kNullObjHeaderPtr) @@ -331,11 +328,11 @@ private class DeclarationsGeneratorVisitor(override val context: Context) : if (threadLocal) null else { val shadowSymbolName = if (isExported) { - descriptor.objectInstanceShadowFieldSymbolName + irClass.objectInstanceShadowFieldSymbolName } else { - "kshadowobjref:" + qualifyInternalName(descriptor) + "kshadowobjref:" + qualifyInternalName(irClass) } - addGlobal(shadowSymbolName, getLLVMType(descriptor.defaultType), isExported = isExported, threadLocal = true) + addGlobal(shadowSymbolName, getLLVMType(irClass.defaultType), isExported = isExported, threadLocal = true) } instanceShadowFieldRef?.let { LLVMSetInitializer(it, kNullObjHeaderPtr) } @@ -343,8 +340,8 @@ private class DeclarationsGeneratorVisitor(override val context: Context) : return SingletonLlvmDeclarations(instanceFieldRef, instanceShadowFieldRef) } - private fun createKotlinObjCClassDeclarations(descriptor: IrClass): KotlinObjCClassLlvmDeclarations { - val internalName = qualifyInternalName(descriptor) + private fun createKotlinObjCClassDeclarations(irClass: IrClass): KotlinObjCClassLlvmDeclarations { + val internalName = qualifyInternalName(irClass) val classPointerGlobal = staticData.createGlobal(int8TypePtr, "kobjcclassptr:$internalName") @@ -363,25 +360,23 @@ private class DeclarationsGeneratorVisitor(override val context: Context) : override fun visitField(declaration: IrField) { super.visitField(declaration) - val descriptor = declaration - - val containingClass = descriptor.containingClass + val containingClass = declaration.parent as? IrClass if (containingClass != null) { val classDeclarations = this.classes[containingClass] ?: error(containingClass.descriptor.toString()) val allFields = classDeclarations.fields - this.fields[descriptor] = FieldLlvmDeclarations( - allFields.indexOf(descriptor) + 1, // First field is ObjHeader. + this.fields[declaration] = FieldLlvmDeclarations( + allFields.indexOf(declaration) + 1, // First field is ObjHeader. classDeclarations.bodyType ) } else { // Fields are module-private, so we use internal name: - val name = "kvar:" + qualifyInternalName(descriptor) + val name = "kvar:" + qualifyInternalName(declaration) val storage = addGlobal( - name, getLLVMType(descriptor.type), isExported = false, + name, getLLVMType(declaration.type), isExported = false, threadLocal = declaration.storageClass == FieldStorage.THREAD_LOCAL) - this.staticFields[descriptor] = StaticFieldLlvmDeclarations(storage) + this.staticFields[declaration] = StaticFieldLlvmDeclarations(storage) } } @@ -390,25 +385,24 @@ private class DeclarationsGeneratorVisitor(override val context: Context) : if (!declaration.isReal) return - val descriptor = declaration - val llvmFunctionType = getLlvmFunctionType(descriptor) + val llvmFunctionType = getLlvmFunctionType(declaration) - if ((descriptor is IrConstructor && descriptor.isObjCConstructor)) { + if ((declaration is IrConstructor && declaration.isObjCConstructor)) { return } - val llvmFunction = if (descriptor.isExternal) { - if (descriptor.isTypedIntrinsic || descriptor.isObjCBridgeBased() - || descriptor.annotations.hasAnnotation(RuntimeNames.cCall)) return + val llvmFunction = if (declaration.isExternal) { + if (declaration.isTypedIntrinsic || declaration.isObjCBridgeBased() + || declaration.annotations.hasAnnotation(RuntimeNames.cCall)) return - context.llvm.externalFunction(descriptor.symbolName, llvmFunctionType, + context.llvm.externalFunction(declaration.symbolName, llvmFunctionType, // Assume that `external fun` is defined in native libs attached to this module: - origin = descriptor.llvmSymbolOrigin + origin = declaration.llvmSymbolOrigin ) } else { - val symbolName = if (descriptor.isExported()) { - descriptor.symbolName.also { - if (descriptor.name.asString() != "main") { + val symbolName = if (declaration.isExported()) { + declaration.symbolName.also { + if (declaration.name.asString() != "main") { assert(LLVMGetNamedFunction(context.llvm.llvmModule, it) == null) { it } } else { // As a workaround, allow `main` functions to clash because frontend accepts this. @@ -416,10 +410,10 @@ private class DeclarationsGeneratorVisitor(override val context: Context) : } } } else { - "kfun:" + qualifyInternalName(descriptor) + "kfun:" + qualifyInternalName(declaration) } val function = LLVMAddFunction(context.llvmModule, symbolName, llvmFunctionType)!! - if (descriptor.returnType.isNothing()) + if (declaration.returnType.isNothing()) setFunctionNoReturn(function) function } @@ -429,6 +423,6 @@ private class DeclarationsGeneratorVisitor(override val context: Context) : LLVMAddTargetDependentFunctionAttr(llvmFunction, "no-frame-pointer-elim", "true") } - this.functions[descriptor] = FunctionLlvmDeclarations(llvmFunction) + this.functions[declaration] = FunctionLlvmDeclarations(llvmFunction) } } diff --git a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/RTTIGenerator.kt b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/RTTIGenerator.kt index cd94c8fd145..7f146933062 100644 --- a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/RTTIGenerator.kt +++ b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/RTTIGenerator.kt @@ -6,7 +6,6 @@ package org.jetbrains.kotlin.backend.konan.llvm import llvm.* -import org.jetbrains.kotlin.backend.common.ir.ir2string import org.jetbrains.kotlin.backend.konan.Context import org.jetbrains.kotlin.backend.konan.computePrimitiveBinaryTypeOrNull import org.jetbrains.kotlin.backend.konan.descriptors.* @@ -46,24 +45,24 @@ internal class RTTIGenerator(override val context: Context) : ContextUtils { } } - private fun checkAcyclicClass(classDescriptor: IrClass): Boolean = when { - classDescriptor.symbol == context.ir.symbols.array -> false - classDescriptor.isArray -> true - context.llvmDeclarations.forClass(classDescriptor).fields.all { checkAcyclicFieldType(it.type) } -> true + private fun checkAcyclicClass(irClass: IrClass): Boolean = when { + irClass.symbol == context.ir.symbols.array -> false + irClass.isArray -> true + context.llvmDeclarations.forClass(irClass).fields.all { checkAcyclicFieldType(it.type) } -> true else -> false } - private fun flagsFromClass(classDescriptor: IrClass): Int { + private fun flagsFromClass(irClass: IrClass): Int { var result = 0 - if (classDescriptor.isFrozen) + if (irClass.isFrozen) result = result or TF_IMMUTABLE // TODO: maybe perform deeper analysis to find surely acyclic types. - if (!classDescriptor.isInterface && !classDescriptor.isAbstract() && !classDescriptor.isAnnotationClass) { - if (checkAcyclicClass(classDescriptor)) { + if (!irClass.isInterface && !irClass.isAbstract() && !irClass.isAnnotationClass) { + if (checkAcyclicClass(irClass)) { result = result or TF_ACYCLIC } } - if (classDescriptor.isInterface) + if (irClass.isInterface) result = result or TF_INTERFACE return result } @@ -125,10 +124,10 @@ internal class RTTIGenerator(override val context: Context) : ContextUtils { private val EXPORT_TYPE_INFO_FQ_NAME = FqName.fromSegments(listOf("kotlin", "native", "internal", "ExportTypeInfo")) - private fun exportTypeInfoIfRequired(classDesc: IrClass, typeInfoGlobal: LLVMValueRef?) { - val annot = classDesc.descriptor.annotations.findAnnotation(EXPORT_TYPE_INFO_FQ_NAME) - if (annot != null) { - val name = getAnnotationValue(annot)!! + private fun exportTypeInfoIfRequired(irClass: IrClass, typeInfoGlobal: LLVMValueRef?) { + val annotation = irClass.descriptor.annotations.findAnnotation(EXPORT_TYPE_INFO_FQ_NAME) + if (annotation != null) { + val name = getAnnotationValue(annotation)!! // TODO: use LLVMAddAlias. val global = addGlobal(name, pointerType(runtime.typeInfoType), isExported = true) LLVMSetInitializer(global, typeInfoGlobal) @@ -170,21 +169,21 @@ internal class RTTIGenerator(override val context: Context) : ContextUtils { return LLVMStoreSizeOfType(llvmTargetData, classType).toInt() } - fun generate(classDesc: IrClass) { + fun generate(irClass: IrClass) { - val className = classDesc.fqNameSafe + val className = irClass.fqNameSafe - val llvmDeclarations = context.llvmDeclarations.forClass(classDesc) + val llvmDeclarations = context.llvmDeclarations.forClass(irClass) val bodyType = llvmDeclarations.bodyType val size = getInstanceSize(bodyType, className) - val superTypeOrAny = classDesc.getSuperClassNotAny() ?: context.ir.symbols.any.owner - val superType = if (classDesc.isAny()) NullPointer(runtime.typeInfoType) + val superTypeOrAny = irClass.getSuperClassNotAny() ?: context.ir.symbols.any.owner + val superType = if (irClass.isAny()) NullPointer(runtime.typeInfoType) else superTypeOrAny.typeInfoPtr - val interfaces = classDesc.implementedInterfaces.map { it.typeInfoPtr } + val interfaces = irClass.implementedInterfaces.map { it.typeInfoPtr } val interfacesPtr = staticData.placeGlobalConstArray("kintf:$className", pointerType(runtime.typeInfoType), interfaces) @@ -199,26 +198,26 @@ internal class RTTIGenerator(override val context: Context) : ContextUtils { val objOffsetsPtr = staticData.placeGlobalConstArray("krefs:$className", int32Type, objOffsets.map { Int32(it.toInt()) }) - val objOffsetsCount = if (classDesc.descriptor == context.builtIns.array) { + val objOffsetsCount = if (irClass.descriptor == context.builtIns.array) { 1 // To mark it as non-leaf. } else { objOffsets.size } - val methods = if (classDesc.isAbstract()) { + val methods = if (irClass.isAbstract()) { emptyList() } else { - methodTableRecords(classDesc) + methodTableRecords(irClass) } val methodsPtr = staticData.placeGlobalConstArray("kmethods:$className", runtime.methodTableRecordType, methods) - val reflectionInfo = getReflectionInfo(classDesc) + val reflectionInfo = getReflectionInfo(irClass) val typeInfoGlobal = llvmDeclarations.typeInfoGlobal val typeInfo = TypeInfo( - classDesc.typeInfoPtr, - makeExtendedInfo(classDesc), + irClass.typeInfoPtr, + makeExtendedInfo(irClass), size, superType, objOffsetsPtr, objOffsetsCount, @@ -226,26 +225,26 @@ internal class RTTIGenerator(override val context: Context) : ContextUtils { methodsPtr, methods.size, reflectionInfo.packageName, reflectionInfo.relativeName, - flagsFromClass(classDesc), + flagsFromClass(irClass), llvmDeclarations.writableTypeInfoGlobal?.pointer ) - val typeInfoGlobalValue = if (!classDesc.typeInfoHasVtableAttached) { + val typeInfoGlobalValue = if (!irClass.typeInfoHasVtableAttached) { typeInfo } else { - val vtable = vtable(classDesc) + val vtable = vtable(irClass) Struct(typeInfo, vtable) } typeInfoGlobal.setInitializer(typeInfoGlobalValue) typeInfoGlobal.setConstant(true) - exportTypeInfoIfRequired(classDesc, classDesc.llvmTypeInfoPtr) + exportTypeInfoIfRequired(irClass, irClass.llvmTypeInfoPtr) } - fun vtable(classDesc: IrClass): ConstArray { + fun vtable(irClass: IrClass): ConstArray { // TODO: compile-time resolution limits binary compatibility - val vtableEntries = context.getVtableBuilder(classDesc).vtableEntries.map { + val vtableEntries = context.getVtableBuilder(irClass).vtableEntries.map { val implementation = it.implementation if (implementation == null || implementation.isExternalObjCClassMethod()) { NullPointer(int8Type) @@ -256,10 +255,10 @@ internal class RTTIGenerator(override val context: Context) : ContextUtils { return ConstArray(int8TypePtr, vtableEntries) } - fun methodTableRecords(classDesc: IrClass): List { - val functionNames = mutableMapOf() - return context.getVtableBuilder(classDesc).methodTableEntries.map { - val functionName = it.overriddenDescriptor.functionName + fun methodTableRecords(irClass: IrClass): List { + val functionNames = mutableMapOf() + return context.getVtableBuilder(irClass).methodTableEntries.map { + val functionName = it.overriddenFunction.functionName val nameSignature = functionName.localHash val previous = functionNames.putIfAbsent(nameSignature.value, it) if (previous != null) @@ -275,13 +274,13 @@ internal class RTTIGenerator(override val context: Context) : ContextUtils { private fun mapRuntimeType(type: LLVMTypeRef): Int = runtimeTypeMap[type] ?: throw Error("Unmapped type: ${llvmtype2string(type)}") - private fun makeExtendedInfo(descriptor: IrClass): ConstPointer { + private fun makeExtendedInfo(irClass: IrClass): ConstPointer { // TODO: shall we actually do that? if (context.shouldOptimize()) return NullPointer(runtime.extendedTypeInfoType) - val className = descriptor.fqNameSafe.toString() - val llvmDeclarations = context.llvmDeclarations.forClass(descriptor) + val className = irClass.fqNameSafe.toString() + val llvmDeclarations = context.llvmDeclarations.forClass(irClass) val bodyType = llvmDeclarations.bodyType val elementType = arrayClasses[className] val value = if (elementType != null) { @@ -313,18 +312,18 @@ internal class RTTIGenerator(override val context: Context) : ContextUtils { // TODO: extract more code common with generate(). fun generateSyntheticInterfaceImpl( - descriptor: IrClass, - methodImpls: Map, - immutable: Boolean = false + irClass: IrClass, + methodImpls: Map, + immutable: Boolean = false ): ConstPointer { - assert(descriptor.isInterface) + assert(irClass.isInterface) val size = LLVMStoreSizeOfType(llvmTargetData, kObjHeader).toInt() val superClass = context.ir.symbols.any.owner assert(superClass.implementedInterfaces.isEmpty()) - val interfaces = listOf(descriptor.typeInfoPtr) + val interfaces = listOf(irClass.typeInfoPtr) val interfacesPtr = staticData.placeGlobalConstArray("", pointerType(runtime.typeInfoType), interfaces) @@ -333,7 +332,7 @@ internal class RTTIGenerator(override val context: Context) : ContextUtils { val objOffsetsCount = 0 val methods = (methodTableRecords(superClass) + methodImpls.map { (method, impl) -> - assert(method.containingDeclaration == descriptor) + assert(method.parent == irClass) MethodTableRecord(method.functionName.localHash, impl.bitcast(int8TypePtr)) }).sortedBy { it.nameSignature.value }.also { assert(it.distinctBy { it.nameSignature.value } == it) @@ -365,7 +364,7 @@ internal class RTTIGenerator(override val context: Context) : ContextUtils { methods = methodsPtr, methodsCount = methods.size, packageName = reflectionInfo.packageName, relativeName = reflectionInfo.relativeName, - flags = flagsFromClass(descriptor) or (if (immutable) TF_IMMUTABLE else 0), + flags = flagsFromClass(irClass) or (if (immutable) TF_IMMUTABLE else 0), writableTypeInfo = writableTypeInfo ), vtable) @@ -375,23 +374,21 @@ internal class RTTIGenerator(override val context: Context) : ContextUtils { return result } - private val OverriddenFunctionDescriptor.implementation get() = getImplementation(context) + private val OverriddenFunctionInfo.implementation get() = getImplementation(context) data class ReflectionInfo(val packageName: String?, val relativeName: String?) - private fun getReflectionInfo(descriptor: IrClass): ReflectionInfo { - return if (descriptor.isAnonymousObject) { - ReflectionInfo(packageName = null, relativeName = null) - } else if (descriptor.isLocal) { - ReflectionInfo(packageName = null, relativeName = descriptor.name.asString()) - } else { - ReflectionInfo( - packageName = descriptor.findPackage().fqName.asString(), - relativeName = generateSequence(descriptor, { it.parent as? IrClass }) - .toList().reversed() - .joinToString(".") { it.name.asString() } - ) - } + private fun getReflectionInfo(irClass: IrClass): ReflectionInfo = when { + irClass.isAnonymousObject -> ReflectionInfo(packageName = null, relativeName = null) + + irClass.isLocal -> ReflectionInfo(packageName = null, relativeName = irClass.name.asString()) + + else -> ReflectionInfo( + packageName = irClass.findPackage().fqName.asString(), + relativeName = generateSequence(irClass) { it.parent as? IrClass } + .toList().reversed() + .joinToString(".") { it.name.asString() } + ) } } diff --git a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/VariableManager.kt b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/VariableManager.kt index 0bd1f3c922b..f087d14aca9 100644 --- a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/VariableManager.kt +++ b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/VariableManager.kt @@ -8,14 +8,12 @@ package org.jetbrains.kotlin.backend.konan.llvm import llvm.* import org.jetbrains.kotlin.backend.common.ir.ir2string import org.jetbrains.kotlin.backend.konan.Context -import org.jetbrains.kotlin.backend.konan.irasdescriptors.* import org.jetbrains.kotlin.ir.IrElement import org.jetbrains.kotlin.ir.declarations.IrValueDeclaration -import org.jetbrains.kotlin.ir.declarations.IrValueParameter import org.jetbrains.kotlin.ir.declarations.IrVariable import org.jetbrains.kotlin.name.Name -internal fun IrElement.needDebugInfo(context: Context) = context.shouldContainDebugInfo() || (this is IrVariable && this.descriptor.isVar) +internal fun IrElement.needDebugInfo(context: Context) = context.shouldContainDebugInfo() || (this is IrVariable && this.isVar) internal class VariableManager(val functionGenerationContext: FunctionGenerationContext) { internal interface Record { @@ -54,41 +52,41 @@ internal class VariableManager(val functionGenerationContext: FunctionGeneration contextVariablesToIndex.clear() } - fun createVariable(descriptor: IrValueDeclaration, value: LLVMValueRef? = null, variableLocation: VariableDebugLocation?) : Int { - val isVar = descriptor is IrVariable && descriptor.isVar + fun createVariable(valueDeclaration: IrValueDeclaration, value: LLVMValueRef? = null, variableLocation: VariableDebugLocation?) : Int { + val isVar = valueDeclaration is IrVariable && valueDeclaration.isVar // Note that we always create slot for object references for memory management. if (!functionGenerationContext.context.shouldContainDebugInfo() && !isVar && value != null) - return createImmutable(descriptor, value) + return createImmutable(valueDeclaration, value) else // Unfortunately, we have to create mutable slots here, // as even vals can be assigned on multiple paths. However, we use varness // knowledge, as anonymous slots are created only for true vars (for vals // their single assigner already have slot). - return createMutable(descriptor, isVar, value, variableLocation) + return createMutable(valueDeclaration, isVar, value, variableLocation) } - internal fun createMutable(descriptor: IrValueDeclaration, + internal fun createMutable(valueDeclaration: IrValueDeclaration, isVar: Boolean, value: LLVMValueRef? = null, variableLocation: VariableDebugLocation?) : Int { - assert(!contextVariablesToIndex.contains(descriptor)) + assert(!contextVariablesToIndex.contains(valueDeclaration)) val index = variables.size - val type = functionGenerationContext.getLLVMType(descriptor.type) - val slot = functionGenerationContext.alloca(type, descriptor.name.asString(), variableLocation) + val type = functionGenerationContext.getLLVMType(valueDeclaration.type) + val slot = functionGenerationContext.alloca(type, valueDeclaration.name.asString(), variableLocation) if (value != null) functionGenerationContext.storeAny(value, slot) variables.add(SlotRecord(slot, functionGenerationContext.isObjectType(type), isVar)) - contextVariablesToIndex[descriptor] = index + contextVariablesToIndex[valueDeclaration] = index return index } internal var skip = 0 - internal fun createParameter(descriptor: IrValueDeclaration, variableLocation: VariableDebugLocation?) : Int { - assert(!contextVariablesToIndex.contains(descriptor)) + internal fun createParameter(valueDeclaration: IrValueDeclaration, variableLocation: VariableDebugLocation?) : Int { + assert(!contextVariablesToIndex.contains(valueDeclaration)) val index = variables.size - val type = functionGenerationContext.getLLVMType(descriptor.type) - val slot = functionGenerationContext.alloca(type, "p-${descriptor.name.asString()}", variableLocation) + val type = functionGenerationContext.getLLVMType(valueDeclaration.type) + val slot = functionGenerationContext.alloca(type, "p-${valueDeclaration.name.asString()}", variableLocation) val isObject = functionGenerationContext.isObjectType(type) variables.add(ParameterRecord(slot, isObject)) - contextVariablesToIndex[descriptor] = index + contextVariablesToIndex[valueDeclaration] = index if (isObject) skip++ return index @@ -110,17 +108,17 @@ internal class VariableManager(val functionGenerationContext: FunctionGeneration return index } - internal fun createImmutable(descriptor: IrValueDeclaration, value: LLVMValueRef) : Int { - if (contextVariablesToIndex.containsKey(descriptor)) - throw Error("${ir2string(descriptor)} is already defined") + internal fun createImmutable(valueDeclaration: IrValueDeclaration, value: LLVMValueRef) : Int { + if (contextVariablesToIndex.containsKey(valueDeclaration)) + throw Error("${ir2string(valueDeclaration)} is already defined") val index = variables.size - variables.add(ValueRecord(value, descriptor.name)) - contextVariablesToIndex[descriptor] = index + variables.add(ValueRecord(value, valueDeclaration.name)) + contextVariablesToIndex[valueDeclaration] = index return index } - fun indexOf(descriptor: IrValueDeclaration) : Int { - return contextVariablesToIndex.getOrElse(descriptor) { -1 } + fun indexOf(valueDeclaration: IrValueDeclaration) : Int { + return contextVariablesToIndex.getOrElse(valueDeclaration) { -1 } } fun addressOf(index: Int): LLVMValueRef { diff --git a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/objcexport/ObjCExportCodeGenerator.kt b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/objcexport/ObjCExportCodeGenerator.kt index 65530c358e5..6af5e1b2c21 100644 --- a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/objcexport/ObjCExportCodeGenerator.kt +++ b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/objcexport/ObjCExportCodeGenerator.kt @@ -1010,7 +1010,7 @@ private fun ObjCExportCodeGenerator.createDirectAdapters( val implementation = if (this.modality == Modality.ABSTRACT) { null } else { - OverriddenFunctionDescriptor( + OverriddenFunctionInfo( context.ir.get(this) as IrSimpleFunction, context.ir.get(base) as IrSimpleFunction ).getImplementation(context) diff --git a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/lower/BridgesBuilding.kt b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/lower/BridgesBuilding.kt index e25522dea1b..3f7b5baa4f9 100644 --- a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/lower/BridgesBuilding.kt +++ b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/lower/BridgesBuilding.kt @@ -102,13 +102,13 @@ internal class WorkersBridgesBuilding(val context: Context) : DeclarationContain ).apply { it.bind(this) } } } - val overriddenJobDescriptor = OverriddenFunctionDescriptor(jobFunction, runtimeJobFunction) + val overriddenJobDescriptor = OverriddenFunctionInfo(jobFunction, runtimeJobFunction) if (!overriddenJobDescriptor.needBridge) return expression val bridge = context.buildBridge( startOffset = job.startOffset, endOffset = job.endOffset, - descriptor = overriddenJobDescriptor, + overriddenFunction = overriddenJobDescriptor, targetSymbol = job.symbol) bridges += bridge expression.putValueArgument(3, IrFunctionReferenceImpl( @@ -133,15 +133,15 @@ internal class BridgesBuilding(val context: Context) : ClassLoweringPass { irClass.simpleFunctions() .forEach { function -> - function.allOverriddenDescriptors - .map { OverriddenFunctionDescriptor(function, it) } + function.allOverriddenFunctions + .map { OverriddenFunctionInfo(function, it) } .filter { !it.bridgeDirections.allNotNeeded() } .filter { it.canBeCalledVirtually } .filter { !it.inheritsBridge } .distinctBy { it.bridgeDirections } .forEach { buildBridge(it, irClass) - builtBridges += it.descriptor + builtBridges += it.function } } irClass.transformChildrenVoid(object: IrElementTransformerVoid() { @@ -165,12 +165,12 @@ internal class BridgesBuilding(val context: Context) : ClassLoweringPass { }) } - private fun buildBridge(descriptor: OverriddenFunctionDescriptor, irClass: IrClass) { + private fun buildBridge(overriddenFunction: OverriddenFunctionInfo, irClass: IrClass) { irClass.declarations.add(context.buildBridge( startOffset = irClass.startOffset, endOffset = irClass.endOffset, - descriptor = descriptor, - targetSymbol = descriptor.descriptor.symbol, + overriddenFunction = overriddenFunction, + targetSymbol = overriddenFunction.function.symbol, superQualifierSymbol = irClass.symbol) ) } @@ -217,10 +217,10 @@ private fun IrBlockBodyBuilder.buildTypeSafeBarrier(function: IrFunction, } private fun Context.buildBridge(startOffset: Int, endOffset: Int, - descriptor: OverriddenFunctionDescriptor, targetSymbol: IrFunctionSymbol, + overriddenFunction: OverriddenFunctionInfo, targetSymbol: IrFunctionSymbol, superQualifierSymbol: IrClassSymbol? = null): IrFunction { - val bridge = specialDeclarationsFactory.getBridge(descriptor) + val bridge = specialDeclarationsFactory.getBridge(overriddenFunction) if (bridge.modality == Modality.ABSTRACT) { return bridge @@ -228,8 +228,8 @@ private fun Context.buildBridge(startOffset: Int, endOffset: Int, val irBuilder = createIrBuilder(bridge.symbol, startOffset, endOffset) bridge.body = irBuilder.irBlockBody(bridge) { - val typeSafeBarrierDescription = BuiltinMethodsWithSpecialGenericSignature.getDefaultValueForOverriddenBuiltinFunction(descriptor.overriddenDescriptor.descriptor) - typeSafeBarrierDescription?.let { buildTypeSafeBarrier(bridge, descriptor.descriptor, it) } + val typeSafeBarrierDescription = BuiltinMethodsWithSpecialGenericSignature.getDefaultValueForOverriddenBuiltinFunction(overriddenFunction.overriddenFunction.descriptor) + typeSafeBarrierDescription?.let { buildTypeSafeBarrier(bridge, overriddenFunction.function, it) } val delegatingCall = IrCallImpl( startOffset, diff --git a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/lower/InteropLowering.kt b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/lower/InteropLowering.kt index 49f54272fc6..3f51b966726 100644 --- a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/lower/InteropLowering.kt +++ b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/lower/InteropLowering.kt @@ -15,7 +15,7 @@ import org.jetbrains.kotlin.backend.konan.cgen.KotlinStubs import org.jetbrains.kotlin.backend.konan.cgen.generateCCall import org.jetbrains.kotlin.backend.konan.cgen.generateCFunctionPointer import org.jetbrains.kotlin.backend.konan.getInlinedClass -import org.jetbrains.kotlin.backend.konan.descriptors.allOverriddenDescriptors +import org.jetbrains.kotlin.backend.konan.descriptors.allOverriddenFunctions import org.jetbrains.kotlin.backend.konan.descriptors.isInterface import org.jetbrains.kotlin.backend.konan.descriptors.synthesizedName import org.jetbrains.kotlin.backend.konan.irasdescriptors.* @@ -478,7 +478,7 @@ internal class InteropLoweringPart1(val context: Context) : IrBuildingTransforme context.ir.symbols.any.owner.declarations.filterIsInstance().toSet() irClass.declarations.filterIsInstance().filter { it.isReal }.forEach { method -> - val overriddenMethodOfAny = method.allOverriddenDescriptors.firstOrNull { + val overriddenMethodOfAny = method.allOverriddenFunctions.firstOrNull { it in methodsOfAny } diff --git a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/optimizations/DFGBuilder.kt b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/optimizations/DFGBuilder.kt index c22aa92443c..c192e485cc2 100644 --- a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/optimizations/DFGBuilder.kt +++ b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/optimizations/DFGBuilder.kt @@ -11,7 +11,7 @@ import org.jetbrains.kotlin.backend.common.peek import org.jetbrains.kotlin.backend.common.pop import org.jetbrains.kotlin.backend.common.push import org.jetbrains.kotlin.backend.konan.* -import org.jetbrains.kotlin.backend.konan.descriptors.allOverriddenDescriptors +import org.jetbrains.kotlin.backend.konan.descriptors.allOverriddenFunctions import org.jetbrains.kotlin.backend.konan.descriptors.isInterface import org.jetbrains.kotlin.backend.konan.descriptors.target import org.jetbrains.kotlin.backend.konan.irasdescriptors.* @@ -26,6 +26,7 @@ import org.jetbrains.kotlin.ir.symbols.IrTypeParameterSymbol import org.jetbrains.kotlin.ir.types.* import org.jetbrains.kotlin.ir.util.constructors import org.jetbrains.kotlin.ir.util.getArguments +import org.jetbrains.kotlin.ir.util.parentAsClass import org.jetbrains.kotlin.ir.util.simpleFunctions import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid import org.jetbrains.kotlin.ir.visitors.acceptChildrenVoid @@ -34,7 +35,7 @@ import org.jetbrains.kotlin.resolve.DescriptorUtils import org.jetbrains.kotlin.util.OperatorNameConventions private fun IrClass.getOverridingOf(function: IrFunction) = (function as? IrSimpleFunction)?.let { - it.allOverriddenDescriptors.atMostOne { it.parent == this } + it.allOverriddenFunctions.atMostOne { it.parent == this } } private fun IrTypeOperator.isCast() = @@ -78,9 +79,9 @@ private class VariableValues { if (element !is IrGetValue) result += element else { - val descriptor = element.symbol.owner - if (descriptor is IrVariable && !seen.contains(descriptor)) - dfs(descriptor, seen, result) + val declaration = element.symbol.owner + if (declaration is IrVariable && !seen.contains(declaration)) + dfs(declaration, seen, result) } } } @@ -230,7 +231,7 @@ internal class ModuleDFGBuilder(val context: Context, val irModule: IrModuleFrag } } - private fun analyze(descriptor: IrDeclaration, body: IrElement?) { + private fun analyze(declaration: IrDeclaration, body: IrElement?) { // Find all interesting expressions, variables and functions. val visitor = ElementFinderVisitor() body?.acceptVoid(visitor) @@ -262,7 +263,7 @@ internal class ModuleDFGBuilder(val context: Context, val irModule: IrModuleFrag } val function = FunctionDFGBuilder(expressionValuesExtractor, visitor.variableValues, - descriptor, visitor.expressions, visitor.returnValues, visitor.thrownValues, visitor.catchParameters).build() + declaration, visitor.expressions, visitor.returnValues, visitor.thrownValues, visitor.catchParameters).build() DEBUG_OUTPUT(0) { function.debugOutput() @@ -274,8 +275,8 @@ internal class ModuleDFGBuilder(val context: Context, val irModule: IrModuleFrag DEBUG_OUTPUT(1) { println("SYMBOL TABLE:") - symbolTable.classMap.forEach { descriptor, type -> - println(" DESCRIPTOR: $descriptor") + symbolTable.classMap.forEach { irClass, type -> + println(" DESCRIPTOR: ${irClass.descriptor}") println(" TYPE: $type") if (type !is DataFlowIR.Type.Declared) return@forEach @@ -326,13 +327,13 @@ internal class ModuleDFGBuilder(val context: Context, val irModule: IrModuleFrag // Producer and job of executeImpl are called externally, we need to reflect this somehow. val producerInvocation = IrCallImpl(expression.startOffset, expression.endOffset, executeImplProducerInvoke.returnType, - executeImplProducerInvoke.symbol, executeImplProducerInvoke.descriptor) + executeImplProducerInvoke.symbol) producerInvocation.dispatchReceiver = expression.getValueArgument(2) val jobFunctionReference = expression.getValueArgument(3) as? IrFunctionReference ?: error("A function reference expected") val jobInvocation = IrCallImpl(expression.startOffset, expression.endOffset, jobFunctionReference.symbol.owner.returnType, - jobFunctionReference.symbol, jobFunctionReference.descriptor) + jobFunctionReference.symbol) jobInvocation.putValueArgument(0, producerInvocation) expressions += jobInvocation @@ -410,27 +411,27 @@ internal class ModuleDFGBuilder(val context: Context, val irModule: IrModuleFrag private inner class FunctionDFGBuilder(val expressionValuesExtractor: ExpressionValuesExtractor, val variableValues: VariableValues, - val descriptor: IrDeclaration, + val declaration: IrDeclaration, val expressions: List, val returnValues: List, val thrownValues: List, val catchParameters: Set) { - private val allParameters = (descriptor as? IrFunction)?.allParameters ?: emptyList() + private val allParameters = (declaration as? IrFunction)?.allParameters ?: emptyList() private val templateParameters = allParameters.withIndex().associateBy({ it.value }, { DataFlowIR.Node.Parameter(it.index) }) private val continuationParameter = when { - descriptor !is IrSimpleFunction -> null + declaration !is IrSimpleFunction -> null - descriptor.isSuspend -> DataFlowIR.Node.Parameter(allParameters.size) + declaration.isSuspend -> DataFlowIR.Node.Parameter(allParameters.size) - descriptor.overrides(invokeSuspendFunctionSymbol.owner) -> // is a ContinuationImpl inheritor. - templateParameters[descriptor.dispatchReceiverParameter!!] // It is its own continuation. + declaration.overrides(invokeSuspendFunctionSymbol.owner) -> // is a ContinuationImpl inheritor. + templateParameters[declaration.dispatchReceiverParameter!!] // It is its own continuation. else -> null } - private fun getContinuation() = continuationParameter ?: error("Function $descriptor has no continuation parameter") + private fun getContinuation() = continuationParameter ?: error("Function ${declaration.descriptor} has no continuation parameter") private val nodes = mutableMapOf() private val variables = variableValues.elementData.keys.associate { @@ -444,14 +445,14 @@ internal class ModuleDFGBuilder(val context: Context, val irModule: IrModuleFrag } fun build(): DataFlowIR.Function { - val isSuspend = descriptor is IrSimpleFunction && descriptor.isSuspend + val isSuspend = declaration is IrSimpleFunction && declaration.isSuspend expressions.forEach { getNode(it) } - val returnNodeType = when (descriptor) { - is IrField -> descriptor.type - is IrFunction -> descriptor.returnType - else -> error(descriptor) + val returnNodeType = when (declaration) { + is IrField -> declaration.type + is IrFunction -> declaration.returnType + else -> error(declaration) } val returnsNode = DataFlowIR.Node.Variable( @@ -464,8 +465,8 @@ internal class ModuleDFGBuilder(val context: Context, val irModule: IrModuleFrag type = symbolTable.mapClassReferenceType(symbols.throwable.owner), kind = DataFlowIR.VariableKind.Temporary ) - variables.forEach { descriptor, node -> - variableValues.elementData[descriptor]!!.forEach { + variables.forEach { variable, node -> + variableValues.elementData[variable]!!.forEach { node.values += expressionToEdge(it) } } @@ -473,7 +474,7 @@ internal class ModuleDFGBuilder(val context: Context, val irModule: IrModuleFrag (if (isSuspend) listOf(continuationParameter!!) else emptyList()) return DataFlowIR.Function( - symbol = symbolTable.mapFunction(descriptor), + symbol = symbolTable.mapFunction(declaration), body = DataFlowIR.FunctionBody(allNodes.distinct().toList(), returnsNode, throwsNode) ) } @@ -488,10 +489,10 @@ internal class ModuleDFGBuilder(val context: Context, val irModule: IrModuleFrag private fun getNode(expression: IrExpression): DataFlowIR.Node { if (expression is IrGetValue) { - val descriptor = expression.symbol.owner - if (descriptor is IrValueParameter) - return templateParameters[descriptor]!! - return variables[descriptor]!! + val valueDeclaration = expression.symbol.owner + if (valueDeclaration is IrValueParameter) + return templateParameters[valueDeclaration]!! + return variables[valueDeclaration]!! } return nodes.getOrPut(expression) { DEBUG_OUTPUT(0) { @@ -580,7 +581,7 @@ internal class ModuleDFGBuilder(val context: Context, val irModule: IrModuleFrag } else { callee as IrSimpleFunction if (callee.isOverridable && value.superQualifier == null) { - val owner = callee.containingDeclaration as IrClass + val owner = callee.parentAsClass val actualReceiverType = value.dispatchReceiver!!.type val actualReceiverClassifier = actualReceiverType.classifierOrFail @@ -634,7 +635,7 @@ internal class ModuleDFGBuilder(val context: Context, val irModule: IrModuleFrag } is IrDelegatingConstructorCall -> { - val thisReceiver = (descriptor as IrConstructor).constructedClass.thisReceiver!! + val thisReceiver = (declaration as IrConstructor).constructedClass.thisReceiver!! val thiz = IrGetValueImpl(SYNTHETIC_OFFSET, SYNTHETIC_OFFSET, thisReceiver.type, thisReceiver.symbol) val arguments = listOf(thiz) + value.getArguments().map { it.second } @@ -649,7 +650,7 @@ internal class ModuleDFGBuilder(val context: Context, val irModule: IrModuleFrag is IrGetField -> { val receiver = value.receiver?.let { expressionToEdge(it) } val receiverType = value.receiver?.let { symbolTable.mapType(it.type) } - val name = value.descriptor.name.asString() + val name = value.symbol.owner.name.asString() DataFlowIR.Node.FieldRead( receiver, DataFlowIR.Field( @@ -665,7 +666,7 @@ internal class ModuleDFGBuilder(val context: Context, val irModule: IrModuleFrag is IrSetField -> { val receiver = value.receiver?.let { expressionToEdge(it) } val receiverType = value.receiver?.let { symbolTable.mapType(it.type) } - val name = value.descriptor.name.asString() + val name = value.symbol.owner.name.asString() DataFlowIR.Node.FieldWrite( receiver, DataFlowIR.Field( @@ -679,7 +680,7 @@ internal class ModuleDFGBuilder(val context: Context, val irModule: IrModuleFrag } is IrTypeOperatorCall -> { - assert(!value.operator.isCast(), { "Casts should've been handled earlier" }) + assert(!value.operator.isCast()) { "Casts should've been handled earlier" } expressionToEdge(value.argument) // Put argument as a separate vertex. DataFlowIR.Node.Const(symbolTable.mapType(value.type)) // All operators except casts are basically constants. } diff --git a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/optimizations/DataFlowIR.kt b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/optimizations/DataFlowIR.kt index c9e6715f1ac..d68ef2b831a 100644 --- a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/optimizations/DataFlowIR.kt +++ b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/optimizations/DataFlowIR.kt @@ -490,41 +490,41 @@ internal object DataFlowIR { private fun IrClass.isFinal() = modality == Modality.FINAL && kind != ClassKind.ENUM_CLASS - fun mapClassReferenceType(descriptor: IrClass, eraseLocalObjects: Boolean = true): Type { + fun mapClassReferenceType(irClass: IrClass, eraseLocalObjects: Boolean = true): Type { // Do not try to devirtualize ObjC classes. - if (descriptor.module.name == Name.special("") || descriptor.isObjCClass()) + if (irClass.module.name == Name.special("") || irClass.isObjCClass()) return Type.Virtual - if (eraseLocalObjects && descriptor.isAnonymousObject && descriptor.isLocal) - return mapClassReferenceType(descriptor.getSuperClassNotAny() ?: context.irBuiltIns.anyClass.owner) + if (eraseLocalObjects && irClass.isAnonymousObject && irClass.isLocal) + return mapClassReferenceType(irClass.getSuperClassNotAny() ?: context.irBuiltIns.anyClass.owner) - val isFinal = descriptor.isFinal() - val isAbstract = descriptor.isAbstract() - val name = descriptor.fqNameSafe.asString() - if (descriptor.module != irModule.descriptor) - return classMap.getOrPut(descriptor) { + val isFinal = irClass.isFinal() + val isAbstract = irClass.isAbstract() + val name = irClass.fqNameSafe.asString() + if (irClass.module != irModule.descriptor) + return classMap.getOrPut(irClass) { Type.External(name.localHash.value, isFinal, isAbstract, null, takeName { name }) } - classMap[descriptor]?.let { return it } + classMap[irClass]?.let { return it } val placeToClassTable = true val symbolTableIndex = if (placeToClassTable) module.numberOfClasses++ else -1 - val type = if (descriptor.isExported()) + val type = if (irClass.isExported()) Type.Public(name.localHash.value, isFinal, isAbstract, null, module, symbolTableIndex, takeName { name }) else Type.Private(privateTypeIndex++, isFinal, isAbstract, null, module, symbolTableIndex, takeName { name }) - classMap[descriptor] = type + classMap[irClass] = type - type.superTypes += descriptor.superTypes.map { mapClassReferenceType(it.getClass()!!) } + type.superTypes += irClass.superTypes.map { mapClassReferenceType(it.getClass()!!) } if (!isAbstract) { - val vtableBuilder = context.getVtableBuilder(descriptor) + val vtableBuilder = context.getVtableBuilder(irClass) type.vtable += vtableBuilder.vtableEntries.map { mapFunction(it.getImplementation(context)!!) } vtableBuilder.methodTableEntries.forEach { - type.itable[it.overriddenDescriptor.functionName.localHash.value] = mapFunction(it.getImplementation(context)!!) + type.itable[it.overriddenFunction.functionName.localHash.value] = mapFunction(it.getImplementation(context)!!) } } return type @@ -564,18 +564,18 @@ internal object DataFlowIR { } // TODO: use from LlvmDeclarations. - private fun getFqName(descriptor: IrDeclaration): FqName = - descriptor.parent.fqNameSafe.child(descriptor.name) + private fun getFqName(declaration: IrDeclaration): FqName = + declaration.parent.fqNameSafe.child(declaration.name) private val IrFunction.internalName get() = getFqName(this).asString() + "#internal" - fun mapFunction(descriptor: IrDeclaration): FunctionSymbol = when (descriptor) { - is IrFunction -> mapFunction(descriptor) - is IrField -> mapPropertyInitializer(descriptor) - else -> error("Unknown descriptor: $descriptor") + fun mapFunction(declaration: IrDeclaration): FunctionSymbol = when (declaration) { + is IrFunction -> mapFunction(declaration) + is IrField -> mapPropertyInitializer(declaration) + else -> error("Unknown declaration: $declaration") } - private fun mapFunction(descriptor: IrFunction): FunctionSymbol = descriptor.target.let { + private fun mapFunction(function: IrFunction): FunctionSymbol = function.target.let { functionMap[it]?.let { return it } val name = if (it.isExported()) it.symbolName else it.internalName @@ -602,15 +602,15 @@ internal object DataFlowIR { else -> { val isAbstract = it is IrSimpleFunction && it.modality == Modality.ABSTRACT - val classDescriptor = it.containingDeclaration as? IrClass + val irClass = it.parent as? IrClass val bridgeTarget = it.bridgeTarget val isSpecialBridge = bridgeTarget.let { it != null && BuiltinMethodsWithSpecialGenericSignature.getDefaultValueForOverriddenBuiltinFunction(it.descriptor) != null } val bridgeTargetSymbol = if (isSpecialBridge || bridgeTarget == null) null else mapFunction(bridgeTarget) - val placeToFunctionsTable = !isAbstract && it !is IrConstructor && classDescriptor != null - && !classDescriptor.isNonGeneratedAnnotation() - && (it.isOverridableOrOverrides || bridgeTarget != null || descriptor.isSpecial || !classDescriptor.isFinal()) + val placeToFunctionsTable = !isAbstract && it !is IrConstructor && irClass != null + && !irClass.isNonGeneratedAnnotation() + && (it.isOverridableOrOverrides || bridgeTarget != null || function.isSpecial || !irClass.isFinal()) val symbolTableIndex = if (placeToFunctionsTable) module.numberOfFunctions++ else -1 if (it.isExported()) FunctionSymbol.Public(name.localHash.value, module, symbolTableIndex, attributes, bridgeTargetSymbol, takeName { name }) @@ -621,13 +621,13 @@ internal object DataFlowIR { functionMap[it] = symbol symbol.parameters = - (descriptor.allParameters.map { it.type } + (if (descriptor.isSuspend) listOf(continuationType) else emptyList())) + (function.allParameters.map { it.type } + (if (function.isSuspend) listOf(continuationType) else emptyList())) .map { mapTypeToFunctionParameter(it) } .toTypedArray() - symbol.returnParameter = mapTypeToFunctionParameter(if (descriptor.isSuspend) + symbol.returnParameter = mapTypeToFunctionParameter(if (function.isSuspend) context.irBuiltIns.anyType else - descriptor.returnType) + function.returnType) return symbol } @@ -635,14 +635,14 @@ internal object DataFlowIR { private val IrFunction.isSpecial get() = name.asString().let { it.startsWith("" || it == "" } - private fun mapPropertyInitializer(descriptor: IrField): FunctionSymbol = descriptor.original.let { - functionMap[it]?.let { return it } + private fun mapPropertyInitializer(irField: IrField): FunctionSymbol { + functionMap[irField]?.let { return it } - assert(it.parent !is IrClass) { "All local properties initializers should've been lowered" } + assert(irField.parent !is IrClass) { "All local properties initializers should've been lowered" } val attributes = FunctionAttributes.IS_GLOBAL_INITIALIZER or FunctionAttributes.RETURNS_UNIT - val symbol = FunctionSymbol.Private(privateFunIndex++, module, -1, attributes, null, takeName { "${it.symbolName}_init" }) + val symbol = FunctionSymbol.Private(privateFunIndex++, module, -1, attributes, null, takeName { "${irField.symbolName}_init" }) - functionMap[it] = symbol + functionMap[irField] = symbol symbol.parameters = emptyArray() symbol.returnParameter = mapTypeToFunctionParameter(context.irBuiltIns.unitType)