From c8badb0a38d9520f467507d72e971dc6602c88e6 Mon Sep 17 00:00:00 2001 From: Vasily Levchenko Date: Thu, 18 May 2017 13:56:10 +0300 Subject: [PATCH] DEBUGINFO: generate forward declaraion of the type instead of kotlin.Any Previously in case type wasn't resolved in codegen (debug info wasn't constructed from IR), we'd use reference to kotlin.Any? as type, from now we're using forward declaration. What next? - type parameters... how to deal with? (cherry picked from commit 579acba659fe52afec638fc00e07a320560bd5fa) --- .../kotlin/backend/konan/llvm/DebugUtils.kt | 36 ++++++++++++++++++- llvmDebugInfoC/src/main/cpp/DebugInfoC.cpp | 9 ++++- 2 files changed, 43 insertions(+), 2 deletions(-) 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);