diff --git a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/common/DeepCopyIrTreeWithDescriptoros.kt b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/common/DeepCopyIrTreeWithDescriptoros.kt index 7067add12c0..fa79e474cc6 100644 --- a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/common/DeepCopyIrTreeWithDescriptoros.kt +++ b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/common/DeepCopyIrTreeWithDescriptoros.kt @@ -481,12 +481,13 @@ internal class DeepCopyIrTreeWithDescriptors(val targetDescriptor: FunctionDescr override fun visitBlock(expression: IrBlock): IrBlock { return if (expression is IrReturnableBlock) { IrReturnableBlockImpl( - startOffset = expression.startOffset, - endOffset = expression.endOffset, - type = expression.type, - descriptor = expression.descriptor, - origin = mapStatementOrigin(expression.origin), - statements = expression.statements.map { it.transform(this, null) } + startOffset = expression.startOffset, + endOffset = expression.endOffset, + type = expression.type, + descriptor = expression.descriptor, + origin = mapStatementOrigin(expression.origin), + statements = expression.statements.map { it.transform(this, null) }, + sourceFileName = expression.sourceFileName ) } else { super.visitBlock(expression) diff --git a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/common/IrCopy.kt b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/common/IrCopy.kt index 13907ed07f1..2f5671c7148 100644 --- a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/common/IrCopy.kt +++ b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/common/IrCopy.kt @@ -40,7 +40,8 @@ open class DeepCopyIrTreeWithReturnableBlockSymbols( expression.startOffset, expression.endOffset, expression.type, expression.descriptor, - expression.origin + expression.origin, + expression.sourceFileName ).also { transformedReturnableBlocks.put(expression, it) it.statements.addAll(expression.statements.map { it.transform() }) diff --git a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/ir/KonanIr.kt b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/ir/KonanIr.kt index 6253a1f0b8a..ed6fcebc348 100644 --- a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/ir/KonanIr.kt +++ b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/ir/KonanIr.kt @@ -16,8 +16,15 @@ package org.jetbrains.kotlin.backend.konan.ir +import org.jetbrains.kotlin.backend.konan.util.File import org.jetbrains.kotlin.descriptors.FunctionDescriptor +import org.jetbrains.kotlin.descriptors.PackageFragmentDescriptor +import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor import org.jetbrains.kotlin.ir.IrStatement +import org.jetbrains.kotlin.ir.SourceManager +import org.jetbrains.kotlin.ir.SourceRangeInfo +import org.jetbrains.kotlin.ir.declarations.IrDeclaration +import org.jetbrains.kotlin.ir.declarations.IrFile import org.jetbrains.kotlin.ir.declarations.IrSymbolOwner import org.jetbrains.kotlin.ir.declarations.IrVariable import org.jetbrains.kotlin.ir.expressions.IrBlock @@ -26,6 +33,7 @@ import org.jetbrains.kotlin.ir.expressions.IrStatementOrigin import org.jetbrains.kotlin.ir.expressions.impl.IrContainerExpressionBase import org.jetbrains.kotlin.ir.expressions.impl.IrExpressionBase import org.jetbrains.kotlin.ir.symbols.IrBindableSymbol +import org.jetbrains.kotlin.ir.symbols.IrFileSymbol import org.jetbrains.kotlin.ir.symbols.IrFunctionSymbol import org.jetbrains.kotlin.ir.symbols.impl.IrBindableSymbolBase import org.jetbrains.kotlin.ir.visitors.IrElementTransformer @@ -39,6 +47,7 @@ interface IrReturnableBlockSymbol : IrFunctionSymbol, IrBindableSymbol) : - this(startOffset, endOffset, type, symbol, origin) { + symbol: IrReturnableBlockSymbol, origin: IrStatementOrigin?, statements: List, sourceFileName: String = "no source file") : + this(startOffset, endOffset, type, symbol, origin, sourceFileName) { this.statements.addAll(statements) } constructor(startOffset: Int, endOffset: Int, type: KotlinType, - descriptor: FunctionDescriptor, origin: IrStatementOrigin? = null) : - this(startOffset, endOffset, type, IrReturnableBlockSymbolImpl(descriptor), origin) + descriptor: FunctionDescriptor, origin: IrStatementOrigin? = null, sourceFileName: String = "no source file") : + this(startOffset, endOffset, type, IrReturnableBlockSymbolImpl(descriptor), origin, sourceFileName) constructor(startOffset: Int, endOffset: Int, type: KotlinType, - descriptor: FunctionDescriptor, origin: IrStatementOrigin?, statements: List) : - this(startOffset, endOffset, type, descriptor, origin) { + descriptor: FunctionDescriptor, origin: IrStatementOrigin?, statements: List, sourceFileName: String = "no source file") : + this(startOffset, endOffset, type, descriptor, origin, sourceFileName) { this.statements.addAll(statements) } @@ -85,6 +93,97 @@ class IrReturnableBlockImpl(startOffset: Int, endOffset: Int, type: KotlinType, } } +//-----------------------------------------------------------------------------// +/** + * TODO + * FileEntry provides mapping file offset to pair line and column which are used in debug information generation. + * NaiveSourceBasedFileEntryImpl implements the functionality with calculation lines and columns at compile time, + * that obligates user to have sources of all dependencies, that not always possible and intuitively clear. Instead new + * version should rely on serialized mapping (offset to pair line and column), which should be generated at library + * compilation stage (perhaps in or before inline face) +*/ + +class NaiveSourceBasedFileEntryImpl(override val name: String) : SourceManager.FileEntry { + + private val lineStartOffsets: IntArray + + //-------------------------------------------------------------------------// + + init { + val file = File(name) + if (file.isFile) { + val buffer = mutableListOf() + var currentOffset = 0 + file.forEachLine { line -> + buffer.add(currentOffset) + currentOffset += line.length + } + lineStartOffsets = buffer.toIntArray() + } else { + lineStartOffsets = IntArray(0) + } + } + + //-------------------------------------------------------------------------// + + override fun getLineNumber(offset: Int): Int { + val index = lineStartOffsets.binarySearch(offset) + return if (index >= 0) index else -index - 1 + } + + //-------------------------------------------------------------------------// + + override fun getColumnNumber(offset: Int): Int { + var lineNumber = getLineNumber(offset) + if (lineNumber >= lineStartOffsets.size) { + lineNumber = lineStartOffsets.size - 1 + } + if (lineNumber < 0) lineNumber = 0 + if (lineStartOffsets.size == 0) return offset + return offset - lineStartOffsets[lineNumber] + } + + //-------------------------------------------------------------------------// + + override val maxOffset: Int + get() = TODO("not implemented") + + override fun getSourceRangeInfo(beginOffset: Int, endOffset: Int): SourceRangeInfo { + TODO("not implemented") + } +} + +//-----------------------------------------------------------------------------// + +class IrFileImpl(fileName: String) : IrFile { + + override val fileEntry = NaiveSourceBasedFileEntryImpl(fileName) + + //-------------------------------------------------------------------------// + + override val fileAnnotations: MutableList + get() = TODO("not implemented") + override val symbol: IrFileSymbol + get() = TODO("not implemented") + override val packageFragmentDescriptor: PackageFragmentDescriptor + get() = TODO("not implemented") + override val endOffset: Int + get() = TODO("not implemented") + override val startOffset: Int + get() = TODO("not implemented") + override val declarations: MutableList + get() = TODO("not implemented") + override fun acceptChildren(visitor: IrElementVisitor, data: D) { + TODO("not implemented") + } + override fun transformChildren(transformer: IrElementTransformer, data: D) { + TODO("not implemented") + } + override fun accept(visitor: IrElementVisitor, data: D): R { + TODO("not implemented") + } +} + //-----------------------------------------------------------------------------// interface IrSuspensionPoint : IrExpression { diff --git a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/ir/ModuleIndex.kt b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/ir/ModuleIndex.kt index ec7818212ef..f21fd9c1717 100644 --- a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/ir/ModuleIndex.kt +++ b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/ir/ModuleIndex.kt @@ -17,17 +17,17 @@ package org.jetbrains.kotlin.backend.konan.ir import org.jetbrains.kotlin.descriptors.ClassDescriptor +import org.jetbrains.kotlin.descriptors.DeclarationDescriptor import org.jetbrains.kotlin.descriptors.FunctionDescriptor import org.jetbrains.kotlin.ir.IrElement -import org.jetbrains.kotlin.ir.declarations.IrClass -import org.jetbrains.kotlin.ir.declarations.IrFunction -import org.jetbrains.kotlin.ir.declarations.IrModuleFragment +import org.jetbrains.kotlin.ir.declarations.* import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid import org.jetbrains.kotlin.ir.visitors.acceptChildrenVoid import org.jetbrains.kotlin.ir.visitors.acceptVoid class ModuleIndex(val module: IrModuleFragment) { + var currentFile: IrFile? = null /** * Contains all classes declared in [module] */ @@ -37,6 +37,7 @@ class ModuleIndex(val module: IrModuleFragment) { * Contains all functions declared in [module] */ val functions = mutableMapOf() + val declarationToFile = mutableMapOf() init { val map = mutableMapOf() @@ -46,6 +47,11 @@ class ModuleIndex(val module: IrModuleFragment) { element.acceptChildrenVoid(this) } + override fun visitFile(declaration: IrFile) { + currentFile = declaration + super.visitFile(declaration) + } + override fun visitClass(declaration: IrClass) { super.visitClass(declaration) @@ -54,11 +60,13 @@ class ModuleIndex(val module: IrModuleFragment) { override fun visitFunction(declaration: IrFunction) { super.visitFunction(declaration) - - val functionDescriptor = declaration.descriptor - functions[functionDescriptor] = declaration + functions[declaration.descriptor] = declaration } + override fun visitDeclaration(declaration: IrDeclaration) { + super.visitDeclaration(declaration) + declarationToFile[declaration.descriptor] = currentFile!!.name + } }) classes = map 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 76b3c1032ae..c6e2d79fe60 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 @@ -24,8 +24,6 @@ import org.jetbrains.kotlin.backend.common.ir.ir2string import org.jetbrains.kotlin.backend.konan.* import org.jetbrains.kotlin.backend.konan.descriptors.* import org.jetbrains.kotlin.backend.konan.ir.* -import org.jetbrains.kotlin.backend.konan.library.LinkData -import org.jetbrains.kotlin.backend.konan.library.KonanLibraryWriter import org.jetbrains.kotlin.backend.konan.library.impl.buildLibrary import org.jetbrains.kotlin.builtins.KotlinBuiltIns import org.jetbrains.kotlin.descriptors.* @@ -1416,7 +1414,7 @@ internal class CodeGeneratorVisitor(val context: Context) : IrElementVisitorVoid //-------------------------------------------------------------------------// - private inner class ReturnableBlockScope(val returnableBlock: IrReturnableBlockImpl) : InnerScopeImpl() { + private inner class ReturnableBlockScope(val returnableBlock: IrReturnableBlockImpl) : FileScope(IrFileImpl(returnableBlock.sourceFileName)) { var bbExit : LLVMBasicBlockRef? = null var resultPhi : LLVMValueRef? = null @@ -1452,7 +1450,7 @@ internal class CodeGeneratorVisitor(val context: Context) : IrElementVisitorVoid //-------------------------------------------------------------------------// - private inner class FileScope(val file:IrFile) : InnerScopeImpl() { + private open inner class FileScope(val file:IrFile) : InnerScopeImpl() { override fun fileScope(): CodeContext? = this } diff --git a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/lower/FunctionInlining.kt b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/lower/FunctionInlining.kt index 596fffe47cb..f80acea08f5 100644 --- a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/lower/FunctionInlining.kt +++ b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/lower/FunctionInlining.kt @@ -132,13 +132,15 @@ private class Inliner(val globalSubstituteMap: MutableMap Unit) { javaFile.forEachLine { action(it) } } override fun toString() = path