diff --git a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/ir/IrInlineUtils.kt b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/ir/IrInlineUtils.kt index 90ee082caa5..7ca57ec62c2 100644 --- a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/ir/IrInlineUtils.kt +++ b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/ir/IrInlineUtils.kt @@ -16,13 +16,11 @@ import org.jetbrains.kotlin.ir.expressions.impl.IrCallImpl import org.jetbrains.kotlin.ir.expressions.impl.IrGetValueImpl import org.jetbrains.kotlin.ir.expressions.impl.IrReturnImpl import org.jetbrains.kotlin.ir.expressions.impl.IrReturnableBlockImpl +import org.jetbrains.kotlin.ir.symbols.IrFileSymbol import org.jetbrains.kotlin.ir.symbols.IrReturnTargetSymbol import org.jetbrains.kotlin.ir.symbols.impl.IrReturnableBlockSymbolImpl import org.jetbrains.kotlin.ir.types.getClass -import org.jetbrains.kotlin.ir.util.explicitParameters -import org.jetbrains.kotlin.ir.util.functions -import org.jetbrains.kotlin.ir.util.isVararg -import org.jetbrains.kotlin.ir.util.statements +import org.jetbrains.kotlin.ir.util.* import org.jetbrains.kotlin.util.OperatorNameConventions sealed class IrInlinable @@ -127,3 +125,37 @@ fun IrInlinable.inline(target: IrDeclarationParent, arguments: List element + is IrFunctionExpression -> element.function + is IrFunctionReference -> element.symbol.owner + is IrPropertyReference -> element.symbol.owner + else -> throw AssertionError("Not supported ir element for inlining ${element.dump()}") + } + +private val IrInlinedFunctionBlock.inlineFunction: IrFunction? + get() = when (val element = inlinedElement) { + is IrFunction -> element + is IrFunctionExpression -> element.function + is IrFunctionReference -> element.symbol.owner.takeIf { it.isInline } + else -> null + } + +fun IrInlinedFunctionBlock.isFunctionInlining(): Boolean { + return this.inlinedElement is IrFunction +} + +fun IrInlinedFunctionBlock.isLambdaInlining(): Boolean { + return !isFunctionInlining() +} + +val IrContainerExpression.innerInlinedBlockOrThis: IrContainerExpression + get() = (this as? IrReturnableBlock)?.statements?.singleOrNull() as? IrInlinedFunctionBlock ?: this + +val IrReturnableBlock.inlineFunction: IrFunction? + get() = (this.statements.singleOrNull() as? IrInlinedFunctionBlock)?.inlineFunction + +val IrReturnableBlock.sourceFileSymbol: IrFileSymbol? + get() = inlineFunction?.fileOrNull?.symbol diff --git a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/AbstractValueUsageTransformer.kt b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/AbstractValueUsageTransformer.kt index 0233d3abeb2..76405a0e32b 100644 --- a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/AbstractValueUsageTransformer.kt +++ b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/AbstractValueUsageTransformer.kt @@ -5,6 +5,7 @@ package org.jetbrains.kotlin.backend.common.lower +import org.jetbrains.kotlin.backend.common.ir.innerInlinedBlockOrThis import org.jetbrains.kotlin.ir.IrBuiltIns import org.jetbrains.kotlin.ir.IrStatement import org.jetbrains.kotlin.ir.declarations.* @@ -120,20 +121,25 @@ abstract class AbstractValueUsageTransformer( } override fun visitContainerExpression(expression: IrContainerExpression): IrExpression { + if (expression is IrInlinedFunctionBlock) { + expression.transformChildrenVoid(this) + return expression + } + expression.transformChildrenVoid(this) if (expression.statements.isEmpty()) { return expression } - val lastIndex = expression.statements.lastIndex - expression.statements.forEachIndexed { i, irStatement -> + val container = expression.innerInlinedBlockOrThis + val lastIndex = container.statements.lastIndex + container.statements.forEachIndexed { i, irStatement -> if (irStatement is IrExpression) { - expression.statements[i] = - if (i == lastIndex) - irStatement.useAsResult(expression) - else - irStatement.useAsStatement() + container.statements[i] = when (i) { + lastIndex -> irStatement.useAsResult(expression) + else -> irStatement.useAsStatement() + } } } diff --git a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/inline/FunctionInlining.kt b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/inline/FunctionInlining.kt index e4f5ef35088..cf2ee367c5e 100644 --- a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/inline/FunctionInlining.kt +++ b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/inline/FunctionInlining.kt @@ -162,7 +162,7 @@ class FunctionInlining( val substituteMap = mutableMapOf() - fun inline() = inlineFunction(callSite, callee, true) + fun inline() = inlineFunction(callSite, callee, inlineFunctionResolver.getFunctionSymbol(callee).owner, true) private fun IrElement.copy(): IrElement { return copyIrElement.copy(this) @@ -171,6 +171,7 @@ class FunctionInlining( private fun inlineFunction( callSite: IrFunctionAccessExpression, callee: IrFunction, + originalInlinedElement: IrElement, performRecursiveInline: Boolean ): IrReturnableBlock { val copiedCallee = (callee.copy() as IrFunction).apply { @@ -198,18 +199,27 @@ class FunctionInlining( val irBuilder = context.createIrBuilder(irReturnableBlockSymbol, endOffset, endOffset) val transformer = ParameterSubstitutor() - val newStatements = mutableListOf() + val newStatements = statements.map { it.transform(transformer, data = null) as IrStatement } - newStatements.addAll(evaluationStatements) - statements.mapTo(newStatements) { it.transform(transformer, data = null) as IrStatement } + val inlinedBlock = IrInlinedFunctionBlockImpl( + startOffset = callSite.startOffset, + endOffset = callSite.endOffset, + type = callSite.type, + inlineCall = callSite, + inlinedElement = originalInlinedElement, + origin = null, + statements = evaluationStatements + newStatements + ) + // Note: here we wrap `IrInlinedFunctionBlock` inside `IrReturnableBlock` because such way it is easier to + // control special composite blocks that are inside `IrInlinedFunctionBlock` return IrReturnableBlockImpl( startOffset = callSite.startOffset, endOffset = callSite.endOffset, type = callSite.type, symbol = irReturnableBlockSymbol, origin = null, - statements = newStatements, + statements = listOf(inlinedBlock), inlineFunctionSymbol = inlineFunctionResolver.getFunctionSymbol(callee) ).apply { transformChildrenVoid(object : IrElementTransformerVoid() { @@ -281,9 +291,7 @@ class FunctionInlining( fun inlineFunctionExpression(irCall: IrCall, irFunctionExpression: IrFunctionExpression): IrExpression { // Inline the lambda. Lambda parameters will be substituted with lambda arguments. val newExpression = inlineFunction( - irCall, - irFunctionExpression.function, - false + irCall, irFunctionExpression.function, irFunctionExpression, false ) // Substitute lambda arguments with target function arguments. return newExpression.transform(this, null) diff --git a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/dce/UsefulDeclarationProcessor.kt b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/dce/UsefulDeclarationProcessor.kt index 9e0a3d83266..a22de30a23c 100644 --- a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/dce/UsefulDeclarationProcessor.kt +++ b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/dce/UsefulDeclarationProcessor.kt @@ -5,6 +5,7 @@ package org.jetbrains.kotlin.ir.backend.js.dce +import org.jetbrains.kotlin.backend.common.ir.inlineFunction import org.jetbrains.kotlin.ir.IrElement import org.jetbrains.kotlin.ir.backend.js.JsCommonBackendContext import org.jetbrains.kotlin.ir.backend.js.utils.hasJsPolyfill @@ -54,7 +55,7 @@ abstract class UsefulDeclarationProcessor( super.visitBlock(expression, data) if (expression is IrReturnableBlock) { - expression.inlineFunctionSymbol?.owner?.addToUsefulPolyfilledDeclarations() + expression.inlineFunction?.addToUsefulPolyfilledDeclarations() } } diff --git a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/JsReturnableBlockLowering.kt b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/JsReturnableBlockLowering.kt index dc3010b971a..025c2d9335a 100644 --- a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/JsReturnableBlockLowering.kt +++ b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/JsReturnableBlockLowering.kt @@ -68,7 +68,7 @@ class JsReturnableBlockTransformer(val context: CommonBackendContext) : IrElemen val builder = context.createIrBuilder(expression.symbol) - expression.type = context.irBuiltIns.unitType + expression.type = unitType return builder.irComposite(expression, expression.origin, variable.type) { +variable +expression diff --git a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/cleanup/CleanupLowering.kt b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/cleanup/CleanupLowering.kt index d263d9e94f7..35cbc58c991 100644 --- a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/cleanup/CleanupLowering.kt +++ b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/cleanup/CleanupLowering.kt @@ -6,9 +6,9 @@ package org.jetbrains.kotlin.ir.backend.js.lower.cleanup import org.jetbrains.kotlin.backend.common.BodyLoweringPass +import org.jetbrains.kotlin.backend.common.ir.isPure import org.jetbrains.kotlin.ir.IrElement import org.jetbrains.kotlin.ir.IrStatement -import org.jetbrains.kotlin.backend.common.ir.isPure import org.jetbrains.kotlin.ir.declarations.IrDeclaration import org.jetbrains.kotlin.ir.expressions.* import org.jetbrains.kotlin.ir.types.isNothing @@ -37,8 +37,8 @@ private class BlockRemover : IrElementVisitorVoid { private fun process(container: IrStatementContainer) { container.statements.transformFlat { statement -> when (statement) { - // returnable blocks required for sourcemaps generation, so keep them - is IrReturnableBlock -> null + // returnable and inlined function blocks required for sourcemaps generation, so keep them + is IrReturnableBlock, is IrInlinedFunctionBlock -> null is IrStatementContainer -> statement.statements else -> null } diff --git a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/transformers/irToJs/IrElementToJsStatementTransformer.kt b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/transformers/irToJs/IrElementToJsStatementTransformer.kt index f6e6e5f8ab1..acaf1aa1637 100644 --- a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/transformers/irToJs/IrElementToJsStatementTransformer.kt +++ b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/transformers/irToJs/IrElementToJsStatementTransformer.kt @@ -5,11 +5,12 @@ package org.jetbrains.kotlin.ir.backend.js.transformers.irToJs -import org.jetbrains.kotlin.ir.backend.js.utils.isTheLastReturnStatementIn -import org.jetbrains.kotlin.ir.backend.js.JsIrBackendContext +import org.jetbrains.kotlin.backend.common.ir.inlineFunction +import org.jetbrains.kotlin.backend.common.ir.innerInlinedBlockOrThis import org.jetbrains.kotlin.ir.backend.js.JsLoweredDeclarationOrigin import org.jetbrains.kotlin.ir.backend.js.utils.JsGenerationContext import org.jetbrains.kotlin.ir.backend.js.utils.emptyScope +import org.jetbrains.kotlin.ir.backend.js.utils.isTheLastReturnStatementIn import org.jetbrains.kotlin.ir.declarations.IrFunction import org.jetbrains.kotlin.ir.declarations.IrSimpleFunction import org.jetbrains.kotlin.ir.declarations.IrVariable @@ -36,11 +37,12 @@ class IrElementToJsStatementTransformer : BaseIrElementToJsNodeTransformer.wrapInCommentsInlineFunctionCall(expression: IrReturnableBlock): List { - val inlineFunctionSymbol = expression.inlineFunctionSymbol ?: return this - val correspondingProperty = (inlineFunctionSymbol.owner as? IrSimpleFunction)?.correspondingPropertySymbol - val owner = correspondingProperty?.owner ?: inlineFunctionSymbol.owner + val inlineFunction = expression.inlineFunction ?: return this + val correspondingProperty = (inlineFunction as? IrSimpleFunction)?.correspondingPropertySymbol + val owner = correspondingProperty?.owner ?: inlineFunction val funName = owner.fqNameWhenAvailable ?: owner.name return listOf(JsSingleLineComment(" Inline function '$funName' call")) + this } diff --git a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/utils/IrJsUtils.kt b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/utils/IrJsUtils.kt index 6ca710d7db7..81ba1117022 100644 --- a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/utils/IrJsUtils.kt +++ b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/utils/IrJsUtils.kt @@ -16,6 +16,7 @@ import org.jetbrains.kotlin.ir.backend.js.ir.JsIrBuilder import org.jetbrains.kotlin.ir.declarations.* import org.jetbrains.kotlin.ir.expressions.IrExpression import org.jetbrains.kotlin.ir.expressions.IrFunctionAccessExpression +import org.jetbrains.kotlin.ir.expressions.IrInlinedFunctionBlock import org.jetbrains.kotlin.ir.expressions.IrReturn import org.jetbrains.kotlin.ir.expressions.impl.IrConstImpl import org.jetbrains.kotlin.ir.expressions.impl.IrGetFieldImpl @@ -45,6 +46,10 @@ fun IrDeclaration?.isExportedInterface(context: JsIrBackendContext) = this is IrClass && kind.isInterface && isExported(context) fun IrReturn.isTheLastReturnStatementIn(target: IrReturnableBlockSymbol): Boolean { + val ownerFirstStatement = target.owner.statements.singleOrNull() + if (ownerFirstStatement is IrInlinedFunctionBlock) { + return ownerFirstStatement.statements.lastOrNull() === this + } return target.owner.statements.lastOrNull() === this } diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/IrExpressions.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/IrExpressions.kt index c3efda6ee56..e9edba4ec28 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/IrExpressions.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/IrExpressions.kt @@ -8,13 +8,7 @@ package org.jetbrains.kotlin.ir.expressions import org.jetbrains.kotlin.ir.declarations.IrValueParameter import org.jetbrains.kotlin.ir.declarations.IrVariable import org.jetbrains.kotlin.ir.expressions.impl.IrTypeOperatorCallImpl -import org.jetbrains.kotlin.ir.symbols.IrFileSymbol import org.jetbrains.kotlin.ir.types.IrType -import org.jetbrains.kotlin.ir.util.fileOrNull - -@Suppress("unused") // Used in kotlin-native -val IrReturnableBlock.sourceFileSymbol: IrFileSymbol? - get() = inlineFunctionSymbol?.owner?.fileOrNull?.symbol val IrFunctionReference.isWithReflection: Boolean get() = reflectionTarget != null diff --git a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/IrToBitcode.kt b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/IrToBitcode.kt index f002f2846ec..b466a0e5f6e 100644 --- a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/IrToBitcode.kt +++ b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/IrToBitcode.kt @@ -7,6 +7,7 @@ package org.jetbrains.kotlin.backend.konan.llvm import kotlinx.cinterop.* import llvm.* +import org.jetbrains.kotlin.backend.common.ir.inlineFunction import org.jetbrains.kotlin.backend.common.lower.coroutines.getOrCreateFunctionWithContinuationStub import org.jetbrains.kotlin.backend.common.lower.inline.InlinerExpressionLocationHint import org.jetbrains.kotlin.backend.konan.* @@ -17,9 +18,6 @@ import org.jetbrains.kotlin.backend.konan.descriptors.* import org.jetbrains.kotlin.backend.konan.ir.* import org.jetbrains.kotlin.backend.konan.llvm.coverage.LLVMCoverageInstrumentation import org.jetbrains.kotlin.backend.konan.lower.* -import org.jetbrains.kotlin.backend.konan.lower.DECLARATION_ORIGIN_STATIC_GLOBAL_INITIALIZER -import org.jetbrains.kotlin.backend.konan.lower.DECLARATION_ORIGIN_STATIC_STANDALONE_THREAD_LOCAL_INITIALIZER -import org.jetbrains.kotlin.backend.konan.lower.DECLARATION_ORIGIN_STATIC_THREAD_LOCAL_INITIALIZER import org.jetbrains.kotlin.builtins.UnsignedType import org.jetbrains.kotlin.descriptors.Modality import org.jetbrains.kotlin.descriptors.PackageFragmentDescriptor @@ -335,7 +333,7 @@ internal class CodeGeneratorVisitor( val functionContext = findCodeContext(symbol.owner, currentCodeContext) { val declaration = (this as? FunctionScope)?.declaration val returnableBlock = (this as? ReturnableBlockScope)?.returnableBlock - val inlinedFunction = returnableBlock?.inlineFunctionSymbol?.owner + val inlinedFunction = returnableBlock?.inlineFunction declaration == it || inlinedFunction == it } ?: return null @@ -1948,7 +1946,7 @@ internal class CodeGeneratorVisitor( //-------------------------------------------------------------------------// private inner class ReturnableBlockScope(val returnableBlock: IrReturnableBlock, val resultSlot: LLVMValueRef?) : - FileScope(returnableBlock.inlineFunctionSymbol?.owner?.let { + FileScope(returnableBlock.inlineFunction?.let { generationState.inlineFunctionOrigins[it]?.irFile ?: it.fileOrNull } ?: (currentCodeContext.fileScope() as? FileScope)?.file @@ -1957,13 +1955,13 @@ internal class CodeGeneratorVisitor( var bbExit : LLVMBasicBlockRef? = null var resultPhi : LLVMValueRef? = null private val functionScope by lazy { - returnableBlock.inlineFunctionSymbol?.owner?.let { + returnableBlock.inlineFunction?.let { it.scope(file().fileEntry.line(generationState.inlineFunctionOrigins[it]?.startOffset ?: it.startOffset)) } } private fun getExit(): LLVMBasicBlockRef { - val location = returnableBlock.inlineFunctionSymbol?.owner?.let { + val location = returnableBlock.inlineFunction?.let { location(generationState.inlineFunctionOrigins[it]?.endOffset ?: it.endOffset) } ?: returnableBlock.statements.lastOrNull()?.let { location(it.endOffset) @@ -2006,7 +2004,7 @@ internal class CodeGeneratorVisitor( override fun returnableBlockScope(): CodeContext? = this override fun location(offset: Int): LocationInfo? { - return if (returnableBlock.inlineFunctionSymbol != null) { + return if (returnableBlock.inlineFunction != null) { val diScope = functionScope ?: return null val inlinedAt = outerContext.location(returnableBlock.startOffset) ?: return null LocationInfo(diScope, file.fileEntry.line(offset), file.fileEntry.column(offset), inlinedAt) diff --git a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/coverage/CoverageRegionCollector.kt b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/coverage/CoverageRegionCollector.kt index 23fff448e62..9c077320e82 100644 --- a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/coverage/CoverageRegionCollector.kt +++ b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/coverage/CoverageRegionCollector.kt @@ -4,6 +4,7 @@ */ package org.jetbrains.kotlin.backend.konan.llvm.coverage +import org.jetbrains.kotlin.backend.common.ir.sourceFileSymbol import org.jetbrains.kotlin.backend.common.pop import org.jetbrains.kotlin.backend.common.push import org.jetbrains.kotlin.ir.IrElement diff --git a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/lower/InteropLowering.kt b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/lower/InteropLowering.kt index 6bde91ea5af..2b5b353cb8d 100644 --- a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/lower/InteropLowering.kt +++ b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/lower/InteropLowering.kt @@ -5,8 +5,13 @@ package org.jetbrains.kotlin.backend.konan.lower -import org.jetbrains.kotlin.backend.common.* +import org.jetbrains.kotlin.backend.common.FileLoweringPass +import org.jetbrains.kotlin.backend.common.ir.inlineDeclaration +import org.jetbrains.kotlin.backend.common.ir.inlineFunction import org.jetbrains.kotlin.backend.common.lower.* +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.cgen.* import org.jetbrains.kotlin.backend.konan.descriptors.allOverriddenFunctions @@ -15,7 +20,10 @@ import org.jetbrains.kotlin.backend.konan.ir.* import org.jetbrains.kotlin.backend.konan.llvm.IntrinsicType import org.jetbrains.kotlin.backend.konan.llvm.tryGetIntrinsicType import org.jetbrains.kotlin.backend.konan.serialization.resolveFakeOverrideMaybeAbstract -import org.jetbrains.kotlin.descriptors.* +import org.jetbrains.kotlin.descriptors.ClassDescriptor +import org.jetbrains.kotlin.descriptors.ClassKind +import org.jetbrains.kotlin.descriptors.DescriptorVisibilities +import org.jetbrains.kotlin.descriptors.Modality import org.jetbrains.kotlin.ir.IrElement import org.jetbrains.kotlin.ir.IrStatement import org.jetbrains.kotlin.ir.builders.* @@ -39,12 +47,12 @@ import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid import org.jetbrains.kotlin.ir.visitors.acceptChildrenVoid import org.jetbrains.kotlin.ir.visitors.acceptVoid import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid +import org.jetbrains.kotlin.konan.ForeignExceptionMode +import org.jetbrains.kotlin.konan.library.KonanLibrary import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe import org.jetbrains.kotlin.resolve.descriptorUtil.module -import org.jetbrains.kotlin.konan.ForeignExceptionMode -import org.jetbrains.kotlin.konan.library.KonanLibrary internal class InteropLowering(generationState: NativeGenerationState) : FileLoweringPass { // TODO: merge these lowerings. @@ -693,7 +701,7 @@ private class InteropLoweringPart1(val generationState: NativeGenerationState) : } override fun visitBlock(expression: IrBlock): IrExpression { - if (expression is IrReturnableBlock && expression.inlineFunctionSymbol?.isAutoreleasepool() == true) { + if (expression is IrReturnableBlock && expression.inlineFunction?.isAutoreleasepool() == true) { // Prohibit calling suspend functions from `autoreleasepool {}` block. // See https://youtrack.jetbrains.com/issue/KT-50786 for more details. // Note: we can't easily check this in frontend, because we need to prohibit indirect cases like @@ -722,8 +730,8 @@ private class InteropLoweringPart1(val generationState: NativeGenerationState) : return super.visitBlock(expression) } - private fun IrFunctionSymbol.isAutoreleasepool(): Boolean { - return this.owner.name.asString() == "autoreleasepool" && this.owner.parent.let { parent -> + private fun IrFunction.isAutoreleasepool(): Boolean { + return this.name.asString() == "autoreleasepool" && this.parent.let { parent -> parent is IrPackageFragment && parent.fqName == InteropFqNames.packageName } } diff --git a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/lower/RedundantCoercionsCleaner.kt b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/lower/RedundantCoercionsCleaner.kt index 687c91f936a..7c1049b7212 100644 --- a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/lower/RedundantCoercionsCleaner.kt +++ b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/lower/RedundantCoercionsCleaner.kt @@ -159,7 +159,7 @@ internal class RedundantCoercionsCleaner(val context: Context) : FileLoweringPas symbol = newSymbol, origin = origin, statements = statements, - inlineFunctionSymbol = inlineFunctionSymbol) + ) } /* * Visitor below requires being very careful when changing it. diff --git a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/lower/ReturnsInsertionLowering.kt b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/lower/ReturnsInsertionLowering.kt index 02f5a369372..bffbcdcb71d 100644 --- a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/lower/ReturnsInsertionLowering.kt +++ b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/lower/ReturnsInsertionLowering.kt @@ -6,10 +6,13 @@ package org.jetbrains.kotlin.backend.konan.lower import org.jetbrains.kotlin.backend.common.FileLoweringPass +import org.jetbrains.kotlin.backend.common.ir.inlineFunction +import org.jetbrains.kotlin.backend.common.ir.innerInlinedBlockOrThis import org.jetbrains.kotlin.backend.common.lower.createIrBuilder import org.jetbrains.kotlin.backend.konan.Context import org.jetbrains.kotlin.ir.IrElement -import org.jetbrains.kotlin.ir.builders.* +import org.jetbrains.kotlin.ir.builders.irCall +import org.jetbrains.kotlin.ir.builders.irReturn import org.jetbrains.kotlin.ir.declarations.IrConstructor import org.jetbrains.kotlin.ir.declarations.IrFile import org.jetbrains.kotlin.ir.declarations.IrFunction @@ -51,10 +54,11 @@ internal class ReturnsInsertionLowering(val context: Context) : FileLoweringPass override fun visitBlock(expression: IrBlock) { expression.acceptChildrenVoid(this) if (expression !is IrReturnableBlock) return - if (expression.inlineFunctionSymbol?.owner?.returnType == context.irBuiltIns.unitType) { - val offset = (expression.statements.lastOrNull() ?: expression).endOffset + if (expression.inlineFunction?.returnType == context.irBuiltIns.unitType) { + val container = expression.innerInlinedBlockOrThis.statements + val offset = (container.lastOrNull() ?: expression).endOffset context.createIrBuilder(expression.symbol, offset, offset).run { - expression.statements += irReturn(irCall(symbols.theUnitInstance, context.irBuiltIns.unitType)) + container += irReturn(irCall(symbols.theUnitInstance, context.irBuiltIns.unitType)) } } }