diff --git a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/DebugUtils.kt b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/DebugUtils.kt index 5a996bb95ad..eb72b957a54 100644 --- a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/DebugUtils.kt +++ b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/DebugUtils.kt @@ -29,7 +29,9 @@ 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.resolve.descriptorUtil.fqNameSafe import org.jetbrains.kotlin.types.KotlinType +import org.jetbrains.kotlin.types.TypeUtils internal object DWARF { @@ -40,6 +42,11 @@ internal object DWARF { val dwarfDebugInfoMetaDataNodeName = "Debug Info Version".mdString() val dwarfVersion = 2 /* TODO: configurable? like gcc/clang -gdwarf-2 and so on. */ val debugInfoVersion = 3 /* TODO: configurable? */ + /** + * This is the value taken from [DIFlags.FlagFwdDecl], to mark type declaration as + * forward one. + */ + val flagsForwardDeclaration = 4 } internal class DebugInfo internal constructor(override val context: Context):ContextUtils { @@ -158,7 +165,34 @@ internal fun KotlinType.dwarfType(context:Context, targetData:LLVMTargetDataRef) 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()) + else -> { + val classDescriptor = TypeUtils.getClassDescriptor(this) + if (classDescriptor != null) { + /** + * Ideally we'd use [KotlinType.typeInfoSymbolName] here , by type could be not + * exportable. + */ + DICreateStructType( + refBuilder = context.debugInfo.builder, + scope = context.debugInfo.compilationModule as DIScopeOpaqueRef, + name = "ktype:${classDescriptor.fqNameSafe}", + file = null, + lineNumber = 0, + sizeInBits = 0, + alignInBits = 0, + flags = DWARF.flagsForwardDeclaration, + derivedFrom = null, + elements = null, + elementsCount = 0, + refPlace = null)!! as DITypeOpaqueRef + } + else if (TypeUtils.isTypeParameter(this)){ + //TODO: Type parameter, how to deal with if? + debugInfoBaseType(context, targetData, this.toString(), llvmType(context), encoding(context).value.toInt()) + } else { + TODO("$this: Does this case really exist?") + } + } } } diff --git a/llvmDebugInfoC/src/main/cpp/DebugInfoC.cpp b/llvmDebugInfoC/src/main/cpp/DebugInfoC.cpp index 57cdb998751..326d459f121 100644 --- a/llvmDebugInfoC/src/main/cpp/DebugInfoC.cpp +++ b/llvmDebugInfoC/src/main/cpp/DebugInfoC.cpp @@ -48,6 +48,10 @@ DEFINE_SIMPLE_CONVERSION_FUNCTIONS(DIExpression, DIExpressionRef) DEFINE_SIMPLE_CONVERSION_FUNCTIONS(Module, LLVMModuleRef) } +/** + * see [DIFlags::FlagFwdDecl]. + */ +#define DI_FORWARD_DECLARAION (4) extern "C" { DIBuilderRef DICreateBuilder(LLVMModuleRef module) { @@ -106,8 +110,11 @@ DICompositeTypeRef DICreateStructType(DIBuilderRef refBuilder, uint64_t elementsCount, DICompositeTypeRef refPlace) { auto builder = llvm::unwrap(refBuilder); + if ((flags & DI_FORWARD_DECLARAION) != 0) { + return llvm::wrap(builder->createStructType(llvm::unwrap(scope), name, NULL, 0, 0, 0, flags, NULL, NULL)); + } std::vector typeElements; - for(int i = 0; i != elementsCount; ++i) { + for(int i = 0; i < elementsCount; ++i) { typeElements.push_back(llvm::unwrap(elements[i])); } auto elementsArray = builder->getOrCreateArray(typeElements);