CODEGEN: generation type info for complex types and refactoring.
- unchecked_cast warning suppression - move subroutineType ext function to DebugUtils. - there is only one diType in caodegen - generate type references for complex types if they are references - generating array types
This commit is contained in:
committed by
vvlevchenko
parent
b1462f8da6
commit
9d63662fbe
+3
-13
@@ -22,10 +22,7 @@ import org.jetbrains.kotlin.backend.jvm.descriptors.initialize
|
|||||||
import org.jetbrains.kotlin.backend.konan.descriptors.*
|
import org.jetbrains.kotlin.backend.konan.descriptors.*
|
||||||
import org.jetbrains.kotlin.backend.konan.ir.DumpIrTreeWithDescriptorsVisitor
|
import org.jetbrains.kotlin.backend.konan.ir.DumpIrTreeWithDescriptorsVisitor
|
||||||
import org.jetbrains.kotlin.backend.konan.ir.Ir
|
import org.jetbrains.kotlin.backend.konan.ir.Ir
|
||||||
import org.jetbrains.kotlin.backend.konan.llvm.Llvm
|
import org.jetbrains.kotlin.backend.konan.llvm.*
|
||||||
import org.jetbrains.kotlin.backend.konan.llvm.LlvmDeclarations
|
|
||||||
import org.jetbrains.kotlin.backend.konan.llvm.functionName
|
|
||||||
import org.jetbrains.kotlin.backend.konan.llvm.verifyModule
|
|
||||||
import org.jetbrains.kotlin.descriptors.*
|
import org.jetbrains.kotlin.descriptors.*
|
||||||
import org.jetbrains.kotlin.descriptors.annotations.Annotations
|
import org.jetbrains.kotlin.descriptors.annotations.Annotations
|
||||||
import org.jetbrains.kotlin.descriptors.impl.PropertyDescriptorImpl
|
import org.jetbrains.kotlin.descriptors.impl.PropertyDescriptorImpl
|
||||||
@@ -268,6 +265,7 @@ internal class Context(config: KonanConfig) : KonanBackendContext(config) {
|
|||||||
field = module!!
|
field = module!!
|
||||||
|
|
||||||
llvm = Llvm(this, module)
|
llvm = Llvm(this, module)
|
||||||
|
debugInfo = DebugInfo(this)
|
||||||
}
|
}
|
||||||
|
|
||||||
lateinit var llvm: Llvm
|
lateinit var llvm: Llvm
|
||||||
@@ -419,14 +417,6 @@ internal class Context(config: KonanConfig) : KonanBackendContext(config) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val debugInfo = DebugInfo()
|
lateinit var debugInfo:DebugInfo
|
||||||
class DebugInfo {
|
|
||||||
val files = mutableMapOf<IrFile, DIFileRef>()
|
|
||||||
val subprograms = mutableMapOf<FunctionDescriptor, DISubprogramRef>()
|
|
||||||
var builder: DIBuilderRef? = null
|
|
||||||
var module: DIModuleRef? = null
|
|
||||||
var compilationModule: DICompileUnitRef? = null
|
|
||||||
var types = mutableMapOf<KotlinType, DITypeOpaqueRef>()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+102
-7
@@ -16,19 +16,22 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.backend.konan.llvm
|
package org.jetbrains.kotlin.backend.konan.llvm
|
||||||
|
|
||||||
import llvm.DICreateCompilationUnit
|
import kotlinx.cinterop.allocArrayOf
|
||||||
import llvm.DICreateModule
|
import kotlinx.cinterop.memScoped
|
||||||
import llvm.DIScopeOpaqueRef
|
import llvm.*
|
||||||
import llvm.LLVMAddNamedMetadataOperand
|
|
||||||
import org.jetbrains.kotlin.backend.konan.Context
|
import org.jetbrains.kotlin.backend.konan.Context
|
||||||
import org.jetbrains.kotlin.backend.konan.KonanConfigKeys
|
import org.jetbrains.kotlin.backend.konan.KonanConfigKeys
|
||||||
import org.jetbrains.kotlin.backend.konan.KonanVersion
|
import org.jetbrains.kotlin.backend.konan.KonanVersion
|
||||||
import org.jetbrains.kotlin.ir.SourceManager.FileEntry
|
|
||||||
import org.jetbrains.kotlin.backend.konan.util.File
|
import org.jetbrains.kotlin.backend.konan.util.File
|
||||||
|
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||||
|
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
||||||
|
import org.jetbrains.kotlin.ir.SourceManager.FileEntry
|
||||||
|
import org.jetbrains.kotlin.ir.declarations.IrFile
|
||||||
|
import org.jetbrains.kotlin.js.descriptorUtils.getJetTypeFqName
|
||||||
|
import org.jetbrains.kotlin.types.KotlinType
|
||||||
|
|
||||||
|
|
||||||
internal object DWARF {
|
internal object DWARF {
|
||||||
val DW_LANG_kotlin = 1 //TODO: we need own constant e.g. 0xbabe
|
|
||||||
val producer = "konanc ${KonanVersion.CURRENT} / kotlin-compiler: ${KotlinVersion.CURRENT}"
|
val producer = "konanc ${KonanVersion.CURRENT} / kotlin-compiler: ${KotlinVersion.CURRENT}"
|
||||||
/* TODO: from LLVM sources is unclear what runtimeVersion corresponds to term in terms of dwarf specification. */
|
/* TODO: from LLVM sources is unclear what runtimeVersion corresponds to term in terms of dwarf specification. */
|
||||||
val runtimeVersion = 2
|
val runtimeVersion = 2
|
||||||
@@ -38,7 +41,31 @@ internal object DWARF {
|
|||||||
val debugInfoVersion = 3 /* TODO: configurable? */
|
val debugInfoVersion = 3 /* TODO: configurable? */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal class DebugInfo internal constructor(override val context: Context):ContextUtils {
|
||||||
|
val files = mutableMapOf<IrFile, DIFileRef>()
|
||||||
|
val subprograms = mutableMapOf<FunctionDescriptor, DISubprogramRef>()
|
||||||
|
var builder: DIBuilderRef? = null
|
||||||
|
var module: DIModuleRef? = null
|
||||||
|
var compilationModule: DICompileUnitRef? = null
|
||||||
|
var types = mutableMapOf<KotlinType, DITypeOpaqueRef>()
|
||||||
|
|
||||||
|
val llvmTypes = mapOf<KotlinType, LLVMTypeRef>(
|
||||||
|
context.builtIns.byteType to LLVMInt8Type()!!,
|
||||||
|
context.builtIns.charType to LLVMInt8Type()!!,
|
||||||
|
context.builtIns.shortType to LLVMInt16Type()!!,
|
||||||
|
context.builtIns.intType to LLVMInt32Type()!!,
|
||||||
|
context.builtIns.longType to LLVMInt64Type()!!,
|
||||||
|
context.builtIns.booleanType to LLVMInt1Type()!!,
|
||||||
|
context.builtIns.floatType to LLVMFloatType()!!,
|
||||||
|
context.builtIns.doubleType to LLVMDoubleType()!!)
|
||||||
|
val intTypes = listOf<KotlinType>(context.builtIns.byteType, context.builtIns.shortType, context.builtIns.longType)
|
||||||
|
val realTypes = listOf<KotlinType>(context.builtIns.floatType, context.builtIns.doubleType)
|
||||||
|
val llvmTypeSizes = llvmTypes.map { it.key to LLVMSizeOfTypeInBits(llvmTargetData, it.value) }.toMap()
|
||||||
|
val llvmTypeAlignments = llvmTypes.map {it.key to LLVMPreferredAlignmentOfType(llvmTargetData, it.value)}.toMap()
|
||||||
|
val otherLlvmType = LLVMPointerType(LLVMInt64Type(), 0)!!
|
||||||
|
val otherTypeSize = LLVMSizeOfTypeInBits(llvmTargetData, otherLlvmType)
|
||||||
|
val otherTypeAlignment = LLVMPreferredAlignmentOfType(llvmTargetData, otherLlvmType)
|
||||||
|
}
|
||||||
/**
|
/**
|
||||||
* File entry starts offsets from zero while dwarf number lines/column starting from 1.
|
* File entry starts offsets from zero while dwarf number lines/column starting from 1.
|
||||||
*/
|
*/
|
||||||
@@ -77,7 +104,7 @@ internal fun generateDebugInfoHeader(context: Context) {
|
|||||||
iSysRoot = "")
|
iSysRoot = "")
|
||||||
context.debugInfo.compilationModule = DICreateCompilationUnit(
|
context.debugInfo.compilationModule = DICreateCompilationUnit(
|
||||||
builder = context.debugInfo.builder,
|
builder = context.debugInfo.builder,
|
||||||
lang = DWARF.DW_LANG_kotlin,
|
lang = DwarfLanguage.DW_LANG_Kotlin.value,
|
||||||
File = path.file,
|
File = path.file,
|
||||||
dir = path.folder,
|
dir = path.folder,
|
||||||
producer = DWARF.producer,
|
producer = DWARF.producer,
|
||||||
@@ -112,3 +139,71 @@ internal fun generateDebugInfoHeader(context: Context) {
|
|||||||
LLVMAddNamedMetadataOperand(context.llvmModule, llvmModuleFlags, nodeDebugInfoVersion)
|
LLVMAddNamedMetadataOperand(context.llvmModule, llvmModuleFlags, nodeDebugInfoVersion)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Suppress("UNCHECKED_CAST")
|
||||||
|
internal fun KotlinType.dwarfType(context:Context, targetData:LLVMTargetDataRef): DITypeOpaqueRef {
|
||||||
|
return when {
|
||||||
|
KotlinBuiltIns.isPrimitiveType(this) -> debugInfoBaseType(context, targetData, this.getJetTypeFqName(false), llvmType(context), encoding(context).value.toInt())
|
||||||
|
KotlinBuiltIns.isArray(this) -> {
|
||||||
|
val arrayElementType = context.builtIns.getArrayElementType(this)
|
||||||
|
DICreateArrayType(context.debugInfo.builder, arrayElementType.size(context), arrayElementType.alignment(context),
|
||||||
|
arrayElementType.diType(context, targetData), 1) as DITypeOpaqueRef
|
||||||
|
}
|
||||||
|
else -> debugInfoBaseType(context, targetData, "Any?", llvmType(context), encoding(context).value.toInt())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal fun KotlinType.diType(context: Context, llvmTargetData: LLVMTargetDataRef): DITypeOpaqueRef =
|
||||||
|
context.debugInfo.types.getOrPut(this) {
|
||||||
|
dwarfType(context, llvmTargetData)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Suppress("UNCHECKED_CAST")
|
||||||
|
private fun debugInfoBaseType(context:Context, targetData:LLVMTargetDataRef, typeName:String, type:LLVMTypeRef, encoding:Int) = DICreateBasicType(
|
||||||
|
context.debugInfo.builder, typeName,
|
||||||
|
LLVMSizeOfTypeInBits(targetData, type),
|
||||||
|
LLVMPreferredAlignmentOfType(targetData, type).toLong(), encoding) as DITypeOpaqueRef
|
||||||
|
|
||||||
|
internal val FunctionDescriptor.types:List<KotlinType>
|
||||||
|
get() {
|
||||||
|
val parameters = valueParameters.map{it.type}
|
||||||
|
return if (returnType != null) listOf(returnType!!, *parameters.toTypedArray()) else parameters
|
||||||
|
}
|
||||||
|
|
||||||
|
internal fun KotlinType.size(context:Context) = context.debugInfo.llvmTypeSizes.getOrDefault(this, context.debugInfo.otherTypeSize)
|
||||||
|
|
||||||
|
internal fun KotlinType.alignment(context:Context) = context.debugInfo.llvmTypeAlignments.getOrDefault(this, context.debugInfo.otherTypeAlignment).toLong()
|
||||||
|
|
||||||
|
internal fun KotlinType.llvmType(context:Context): LLVMTypeRef = context.debugInfo.llvmTypes.getOrDefault(this, context.debugInfo.otherLlvmType)
|
||||||
|
|
||||||
|
private fun<T> or(v:T, vararg p:(T)->Boolean):Boolean = p.any{it(v)}
|
||||||
|
internal fun KotlinType.encoding(context:Context):DwarfTypeKind {
|
||||||
|
return when {
|
||||||
|
this in context.debugInfo.intTypes -> DwarfTypeKind.DW_ATE_signed
|
||||||
|
this in context.debugInfo.realTypes -> DwarfTypeKind.DW_ATE_float
|
||||||
|
KotlinBuiltIns.isBoolean(this) -> DwarfTypeKind.DW_ATE_boolean
|
||||||
|
KotlinBuiltIns.isChar(this) -> DwarfTypeKind.DW_ATE_unsigned
|
||||||
|
(!KotlinBuiltIns.isPrimitiveType(this)) -> DwarfTypeKind.DW_ATE_address
|
||||||
|
else -> TODO(toString())
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
internal fun alignTo(value:Long, align:Long):Long = (value + align - 1) / align * align
|
||||||
|
|
||||||
|
internal fun FunctionDescriptor.subroutineType(context: Context, llvmTargetData: LLVMTargetDataRef): DISubroutineTypeRef {
|
||||||
|
return memScoped {
|
||||||
|
DICreateSubroutineType(context.debugInfo.builder, allocArrayOf(
|
||||||
|
this@subroutineType.types.map { it.referenceOrValue(context, llvmTargetData) }),
|
||||||
|
this@subroutineType.types.size)!!
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Suppress("UNCHECKED_CAST")
|
||||||
|
private fun KotlinType.referenceOrValue(context: Context, llvmTargetData: LLVMTargetDataRef):DITypeOpaqueRef {
|
||||||
|
val refType = this.dwarfType(context, llvmTargetData)
|
||||||
|
return if (KotlinBuiltIns.isPrimitiveType(this))
|
||||||
|
refType
|
||||||
|
else
|
||||||
|
DICreateReferenceType(context.debugInfo.builder, refType) as DITypeOpaqueRef
|
||||||
|
}
|
||||||
|
|||||||
+90
-38
@@ -42,7 +42,6 @@ import org.jetbrains.kotlin.name.Name
|
|||||||
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
||||||
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe
|
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe
|
||||||
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameUnsafe
|
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameUnsafe
|
||||||
import org.jetbrains.kotlin.resolve.descriptorUtil.getSuperClassOrAny
|
|
||||||
import org.jetbrains.kotlin.types.KotlinType
|
import org.jetbrains.kotlin.types.KotlinType
|
||||||
import org.jetbrains.kotlin.types.TypeUtils
|
import org.jetbrains.kotlin.types.TypeUtils
|
||||||
import org.jetbrains.kotlin.types.typeUtil.isNothing
|
import org.jetbrains.kotlin.types.typeUtil.isNothing
|
||||||
@@ -197,9 +196,17 @@ internal interface CodeContext {
|
|||||||
/**
|
/**
|
||||||
* Returns owning file scope.
|
* Returns owning file scope.
|
||||||
*
|
*
|
||||||
* @return the requested value
|
* @return the requested value if in the file scope or null.
|
||||||
*/
|
*/
|
||||||
fun fileScope(): CodeContext?
|
fun fileScope(): CodeContext?
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns owning class scope [ClassScope].
|
||||||
|
*
|
||||||
|
* @returns the requested value if in the class scope or null.
|
||||||
|
*/
|
||||||
|
fun classScope(): CodeContext?
|
||||||
|
|
||||||
fun addResumePoint(bbLabel: LLVMBasicBlockRef)
|
fun addResumePoint(bbLabel: LLVMBasicBlockRef)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -243,7 +250,9 @@ internal class CodeGeneratorVisitor(val context: Context) : IrElementVisitorVoid
|
|||||||
override fun functionScope(): CodeContext? = null
|
override fun functionScope(): CodeContext? = null
|
||||||
|
|
||||||
override fun fileScope(): CodeContext? = null
|
override fun fileScope(): CodeContext? = null
|
||||||
|
|
||||||
|
override fun classScope(): CodeContext? = null
|
||||||
|
|
||||||
override fun addResumePoint(bbLabel: LLVMBasicBlockRef) = unsupported(bbLabel)
|
override fun addResumePoint(bbLabel: LLVMBasicBlockRef) = unsupported(bbLabel)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -575,8 +584,11 @@ internal class CodeGeneratorVisitor(val context: Context) : IrElementVisitorVoid
|
|||||||
// do not generate any code for annotation classes as a workaround for NotImplementedError
|
// do not generate any code for annotation classes as a workaround for NotImplementedError
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
using(ClassScope(declaration)) {
|
||||||
declaration.acceptChildrenVoid(this)
|
debugClassDeclaration(declaration) {
|
||||||
|
declaration.acceptChildrenVoid(this)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//-------------------------------------------------------------------------//
|
//-------------------------------------------------------------------------//
|
||||||
@@ -595,6 +607,7 @@ internal class CodeGeneratorVisitor(val context: Context) : IrElementVisitorVoid
|
|||||||
|
|
||||||
override fun visitField(expression: IrField) {
|
override fun visitField(expression: IrField) {
|
||||||
context.log{"visitField : ${ir2string(expression)}"}
|
context.log{"visitField : ${ir2string(expression)}"}
|
||||||
|
debugFieldDeclaration(expression)
|
||||||
val descriptor = expression.descriptor
|
val descriptor = expression.descriptor
|
||||||
if (descriptor.containingDeclaration is PackageFragmentDescriptor) {
|
if (descriptor.containingDeclaration is PackageFragmentDescriptor) {
|
||||||
val type = codegen.getLLVMType(descriptor.type)
|
val type = codegen.getLLVMType(descriptor.type)
|
||||||
@@ -1071,7 +1084,7 @@ internal class CodeGeneratorVisitor(val context: Context) : IrElementVisitorVoid
|
|||||||
val line = value.line()
|
val line = value.line()
|
||||||
codegen.vars.debugInfoLocalVariableLocation(
|
codegen.vars.debugInfoLocalVariableLocation(
|
||||||
functionScope = functionScope,
|
functionScope = functionScope,
|
||||||
diType = variableDescriptor.diType,
|
diType = variableDescriptor.type.diType(context, codegen.llvmTargetData),
|
||||||
name = variableDescriptor.name,
|
name = variableDescriptor.name,
|
||||||
variable = variable,
|
variable = variable,
|
||||||
file = file,
|
file = file,
|
||||||
@@ -1395,6 +1408,26 @@ internal class CodeGeneratorVisitor(val context: Context) : IrElementVisitorVoid
|
|||||||
|
|
||||||
//-------------------------------------------------------------------------//
|
//-------------------------------------------------------------------------//
|
||||||
|
|
||||||
|
private inner class ClassScope(val clazz:IrClass) : InnerScopeImpl() {
|
||||||
|
val isExported
|
||||||
|
get() = clazz.descriptor.isExported()
|
||||||
|
var offsetInBits = 0L
|
||||||
|
val members = mutableListOf<DIDerivedTypeRef>()
|
||||||
|
@Suppress("UNCHECKED_CAST")
|
||||||
|
val scope = if (isExported && context.shouldContainDebugInfo())
|
||||||
|
DICreateReplaceableCompositeType(
|
||||||
|
tag = DwarfTag.DW_TAG_structure_type.value,
|
||||||
|
refBuilder = context.debugInfo.builder,
|
||||||
|
refScope = context.debugInfo.compilationModule as DIScopeOpaqueRef,
|
||||||
|
name = clazz.descriptor.typeInfoSymbolName,
|
||||||
|
refFile = file().file(),
|
||||||
|
line = clazz.line()) as DITypeOpaqueRef
|
||||||
|
else null
|
||||||
|
override fun classScope(): CodeContext? = this
|
||||||
|
}
|
||||||
|
|
||||||
|
//-------------------------------------------------------------------------//
|
||||||
|
|
||||||
private fun evaluateReturnableBlock(value: IrReturnableBlockImpl): LLVMValueRef {
|
private fun evaluateReturnableBlock(value: IrReturnableBlockImpl): LLVMValueRef {
|
||||||
context.log{"evaluateReturnableBlock : ${value.statements.forEach { ir2string(it) }}"}
|
context.log{"evaluateReturnableBlock : ${value.statements.forEach { ir2string(it) }}"}
|
||||||
|
|
||||||
@@ -1552,6 +1585,55 @@ internal class CodeGeneratorVisitor(val context: Context) : IrElementVisitorVoid
|
|||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//-------------------------------------------------------------------------//
|
||||||
|
@Suppress("UNCHECKED_CAST")
|
||||||
|
private fun debugClassDeclaration(declaration: IrClass, body: () -> Unit): Unit {
|
||||||
|
val doDebugInfo = context.shouldContainDebugInfo() && declaration.descriptor.isExported()
|
||||||
|
val classScope = currentCodeContext.classScope() as ClassScope
|
||||||
|
if (doDebugInfo) context.debugInfo.types[declaration.descriptor.defaultType] = classScope.scope!!
|
||||||
|
body()
|
||||||
|
memScoped {
|
||||||
|
if (doDebugInfo) context.debugInfo.types[declaration.descriptor.defaultType] = DICreateStructType(
|
||||||
|
refBuilder = context.debugInfo.builder,
|
||||||
|
scope = context.debugInfo.compilationModule as DIScopeOpaqueRef,
|
||||||
|
name = declaration.descriptor.typeInfoSymbolName,
|
||||||
|
file = file().file(),
|
||||||
|
lineNumber = declaration.line(),
|
||||||
|
sizeInBits = 64 /* TODO */,
|
||||||
|
alignInBits = 4 /* TODO */,
|
||||||
|
derivedFrom = null,
|
||||||
|
elements = classScope.members.toCValues(),
|
||||||
|
elementsCount = classScope.members.size.toLong(),
|
||||||
|
refPlace = context.debugInfo.types[declaration.descriptor.defaultType] as DICompositeTypeRef,
|
||||||
|
flags = 0
|
||||||
|
) as DITypeOpaqueRef
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//-------------------------------------------------------------------------//
|
||||||
|
private fun debugFieldDeclaration(expression: IrField) {
|
||||||
|
val scope = currentCodeContext.classScope() as? ClassScope ?: return
|
||||||
|
if (!scope.isExported || !context.shouldContainDebugInfo()) return
|
||||||
|
val irFile = (currentCodeContext.fileScope() as FileScope).file
|
||||||
|
val sizeInBits = expression.descriptor.type.size(context)
|
||||||
|
scope.offsetInBits += sizeInBits
|
||||||
|
val alignInBits = expression.descriptor.type.alignment(context)
|
||||||
|
scope.offsetInBits = alignTo(scope.offsetInBits, alignInBits)
|
||||||
|
scope.members.add(DICreateMemberType(
|
||||||
|
refBuilder = context.debugInfo.builder,
|
||||||
|
refScope = scope.scope as DIScopeOpaqueRef,
|
||||||
|
name = expression.descriptor.symbolName,
|
||||||
|
file = irFile.file(),
|
||||||
|
lineNum = expression.line(),
|
||||||
|
sizeInBits = sizeInBits,
|
||||||
|
alignInBits = alignInBits,
|
||||||
|
offsetInBits = scope.offsetInBits,
|
||||||
|
flags = 0,
|
||||||
|
type = expression.descriptor.type.diType(context, codegen.llvmTargetData)
|
||||||
|
)!!)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//-------------------------------------------------------------------------//
|
//-------------------------------------------------------------------------//
|
||||||
private fun IrFile.file(): DIFileRef {
|
private fun IrFile.file(): DIFileRef {
|
||||||
return context.debugInfo.files.getOrPut(this) {
|
return context.debugInfo.files.getOrPut(this) {
|
||||||
@@ -1561,11 +1643,12 @@ internal class CodeGeneratorVisitor(val context: Context) : IrElementVisitorVoid
|
|||||||
}
|
}
|
||||||
|
|
||||||
//-------------------------------------------------------------------------//
|
//-------------------------------------------------------------------------//
|
||||||
|
@Suppress("UNCHECKED_CAST")
|
||||||
private fun IrFunction.scope():DIScopeOpaqueRef? {
|
private fun IrFunction.scope():DIScopeOpaqueRef? {
|
||||||
if (!context.shouldContainDebugInfo()) return null
|
if (!context.shouldContainDebugInfo()) return null
|
||||||
return context.debugInfo.subprograms.getOrPut(descriptor) {
|
return context.debugInfo.subprograms.getOrPut(descriptor) {
|
||||||
memScoped {
|
memScoped {
|
||||||
val subroutineType = descriptor.subroutineType
|
val subroutineType = descriptor.subroutineType(context, codegen.llvmTargetData)
|
||||||
val functionLlvmValue = codegen.functionLlvmValue(descriptor)
|
val functionLlvmValue = codegen.functionLlvmValue(descriptor)
|
||||||
val linkageName = LLVMGetValueName(functionLlvmValue)!!.toKString()
|
val linkageName = LLVMGetValueName(functionLlvmValue)!!.toKString()
|
||||||
val diFunction = DICreateFunction(
|
val diFunction = DICreateFunction(
|
||||||
@@ -1586,37 +1669,6 @@ internal class CodeGeneratorVisitor(val context: Context) : IrElementVisitorVoid
|
|||||||
} as DIScopeOpaqueRef
|
} as DIScopeOpaqueRef
|
||||||
}
|
}
|
||||||
|
|
||||||
//-------------------------------------------------------------------------//
|
|
||||||
private val FunctionDescriptor.subroutineType: DISubroutineTypeRef
|
|
||||||
get() = memScoped {
|
|
||||||
DICreateSubroutineType(context.debugInfo.builder, allocArrayOf(
|
|
||||||
this@subroutineType.valueParameters.map{it.diType}),
|
|
||||||
this@subroutineType.valueParameters.size)!!
|
|
||||||
}
|
|
||||||
|
|
||||||
//-------------------------------------------------------------------------//
|
|
||||||
private val VariableDescriptor.diType: DITypeOpaqueRef
|
|
||||||
get() = context.debugInfo.types.getOrPut(this.type) {
|
|
||||||
when {
|
|
||||||
KotlinBuiltIns.isInt(this.type) -> debugInfoBaseType("Int", LLVMInt32Type()!!)
|
|
||||||
KotlinBuiltIns.isBoolean(this.type) -> debugInfoBaseType("Boolean", LLVMInt1Type()!!)
|
|
||||||
KotlinBuiltIns.isChar(this.type) -> debugInfoBaseType("Char", LLVMInt8Type()!!)
|
|
||||||
KotlinBuiltIns.isShort(this.type) -> debugInfoBaseType("Short", LLVMInt16Type()!!)
|
|
||||||
KotlinBuiltIns.isByte(this.type) -> debugInfoBaseType("Byte", LLVMInt8Type()!!)
|
|
||||||
KotlinBuiltIns.isLong(this.type) -> debugInfoBaseType("Long", LLVMInt64Type()!!)
|
|
||||||
KotlinBuiltIns.isFloat(this.type) -> debugInfoBaseType("Float", LLVMFloatType()!!)
|
|
||||||
KotlinBuiltIns.isDouble(this.type) -> debugInfoBaseType("Double", LLVMDoubleType()!!)
|
|
||||||
(!KotlinBuiltIns.isPrimitiveType(this.type)) -> debugInfoBaseType("Any?", codegen.kObjHeaderPtr)
|
|
||||||
else -> TODO(this.type.toString())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun debugInfoBaseType(typeName:String, type:LLVMTypeRef) = DICreateBasicType(
|
|
||||||
context.debugInfo.builder, typeName,
|
|
||||||
LLVMSizeOfTypeInBits(codegen.llvmTargetData, type),
|
|
||||||
LLVMPreferredAlignmentOfType(codegen.llvmTargetData, type).toLong(), 0) as DITypeOpaqueRef
|
|
||||||
|
|
||||||
|
|
||||||
//-------------------------------------------------------------------------//
|
//-------------------------------------------------------------------------//
|
||||||
|
|
||||||
private val coroutineImplDescriptor = context.builtIns.getKonanInternalClass("CoroutineImpl")
|
private val coroutineImplDescriptor = context.builtIns.getKonanInternalClass("CoroutineImpl")
|
||||||
|
|||||||
Reference in New Issue
Block a user