Skip to content

Commit 8505dec

Browse files
committed
llvm: emit debuginfo for internal types (%anyvalue, %typeinfo, ...)
1 parent 274ab74 commit 8505dec

5 files changed

Lines changed: 92 additions & 23 deletions

File tree

llvm-backend/src/main/kotlin/io/github/tmarsteel/emerge/backend/llvm/dsl/LlvmType.kt

Lines changed: 37 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,15 @@ import io.github.tmarsteel.emerge.backend.api.ir.IrSourceLocation
66
import io.github.tmarsteel.emerge.backend.llvm.intrinsics.EmergeClassType
77
import io.github.tmarsteel.emerge.backend.llvm.intrinsics.EmergeFallibleCallResult
88
import io.github.tmarsteel.emerge.backend.llvm.intrinsics.EmergeHeapAllocatedValueBaseType
9+
import io.github.tmarsteel.emerge.backend.llvm.intrinsics.JvmStackFrameIrSourceLocation
910
import io.github.tmarsteel.emerge.backend.llvm.jna.DwarfBaseTypeEncoding
1011
import io.github.tmarsteel.emerge.backend.llvm.jna.Llvm
1112
import io.github.tmarsteel.emerge.backend.llvm.jna.LlvmDiFlags
1213
import io.github.tmarsteel.emerge.backend.llvm.jna.LlvmTypeRef
1314
import io.github.tmarsteel.emerge.backend.llvm.jna.NativeI32FlagGroup
1415
import io.github.tmarsteel.emerge.backend.llvm.jna.NativePointerArray
1516
import java.math.BigInteger
17+
import kotlin.reflect.KProperty
1618

1719
/**
1820
* A type-safe wrapper around [LLVMTypeRef]
@@ -223,6 +225,7 @@ abstract class LlvmStructType(
223225
inner class Member<S : LlvmStructType, T : LlvmType>(
224226
val indexInStruct: Int,
225227
val type: T,
228+
val declaredAt: IrSourceLocation,
226229
) {
227230
init {
228231
check(indexInStruct >= 0)
@@ -255,7 +258,8 @@ abstract class LlvmStructType(
255258
check(!observed) {
256259
"You can only declare struct members at the creation time of your type, not later."
257260
}
258-
val member = Member<S, T>(membersInOrder.size, type)
261+
val declaredAt = JvmStackFrameIrSourceLocation(Thread.currentThread().stackTrace[2])
262+
val member = Member<S, T>(membersInOrder.size, type, declaredAt)
259263
membersInOrder.add(member)
260264
return ImmediateDelegate(member)
261265
}
@@ -278,16 +282,7 @@ abstract class LlvmNamedStructType(
278282
}
279283

280284
override fun computeDiType(diBuilder: DiBuilder): LlvmDebugInfo.Type {
281-
val rawStructType = getRawInContext(diBuilder.context)
282-
val flags = NativeI32FlagGroup<LlvmDiFlags>()
283-
return diBuilder.createStructType(
284-
name,
285-
Llvm.LLVMSizeOfTypeInBits(diBuilder.context.targetData.ref, rawStructType).toULong(),
286-
Llvm.LLVMABIAlignmentOfType(diBuilder.context.targetData.ref, rawStructType).toUInt() * 8u,
287-
flags,
288-
null,
289-
declaredAt,
290-
)
285+
return computeDiType(this, diBuilder, null, NativeI32FlagGroup())
291286
}
292287

293288
override fun toString(): String = "%$name"
@@ -304,6 +299,37 @@ abstract class LlvmNamedStructType(
304299
final override fun hashCode(): Int {
305300
return name.hashCode()
306301
}
302+
303+
companion object {
304+
fun <S : LlvmNamedStructType> computeDiType(
305+
structType: S,
306+
diBuilder: DiBuilder,
307+
elements: List<KProperty<Member<S, *>>>?,
308+
flags: NativeI32FlagGroup<LlvmDiFlags> = NativeI32FlagGroup(),
309+
): LlvmDebugInfo.Type {
310+
val rawStructType = structType.getRawInContext(diBuilder.context)
311+
return diBuilder.createStructType(
312+
structType.name,
313+
Llvm.LLVMSizeOfTypeInBits(diBuilder.context.targetData.ref, rawStructType).toULong(),
314+
Llvm.LLVMABIAlignmentOfType(diBuilder.context.targetData.ref, rawStructType).toUInt() * 8u,
315+
flags,
316+
elements?.map { memberProp ->
317+
val member = memberProp.getter.call()
318+
val memberDiType = member.type.getDiType(diBuilder)
319+
diBuilder.createStructMember(
320+
memberProp.name,
321+
memberDiType.sizeInBits,
322+
memberDiType.alignInBits,
323+
Llvm.LLVMOffsetOfElement(diBuilder.context.targetData.ref, rawStructType, member.indexInStruct).toULong() * 8u,
324+
memberDiType,
325+
flags,
326+
member.declaredAt,
327+
)
328+
},
329+
structType.declaredAt,
330+
)
331+
}
332+
}
307333
}
308334

309335
open class LlvmInlineStructType(
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
package io.github.tmarsteel.emerge.backend.llvm.intrinsics
2+
3+
import io.github.tmarsteel.emerge.backend.api.ir.IrSourceFile
4+
import io.github.tmarsteel.emerge.backend.api.ir.IrSourceLocation
5+
import java.nio.file.Paths
6+
7+
class JvmStackFrameIrSourceLocation(frame: StackTraceElement) : IrSourceLocation {
8+
override val file = object : IrSourceFile {
9+
override val path = Paths.get(frame.fileName)
10+
}
11+
override val lineNumber = frame.lineNumber.toUInt()
12+
override val columnNumber = 1u
13+
}

llvm-backend/src/main/kotlin/io/github/tmarsteel/emerge/backend/llvm/intrinsics/array_types.kt

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import io.github.tmarsteel.emerge.backend.llvm.codegen.anyValueBase
66
import io.github.tmarsteel.emerge.backend.llvm.codegen.sizeof
77
import io.github.tmarsteel.emerge.backend.llvm.dsl.BasicBlockBuilder
88
import io.github.tmarsteel.emerge.backend.llvm.dsl.BasicBlockBuilder.Companion.retVoid
9+
import io.github.tmarsteel.emerge.backend.llvm.dsl.DiBuilder
910
import io.github.tmarsteel.emerge.backend.llvm.dsl.GetElementPointerStep
1011
import io.github.tmarsteel.emerge.backend.llvm.dsl.GetElementPointerStep.Companion.index
1112
import io.github.tmarsteel.emerge.backend.llvm.dsl.GetElementPointerStep.Companion.member
@@ -14,6 +15,7 @@ import io.github.tmarsteel.emerge.backend.llvm.dsl.LlvmArrayType
1415
import io.github.tmarsteel.emerge.backend.llvm.dsl.LlvmBooleanType
1516
import io.github.tmarsteel.emerge.backend.llvm.dsl.LlvmConstant
1617
import io.github.tmarsteel.emerge.backend.llvm.dsl.LlvmContext
18+
import io.github.tmarsteel.emerge.backend.llvm.dsl.LlvmDebugInfo
1719
import io.github.tmarsteel.emerge.backend.llvm.dsl.LlvmFixedIntegerType
1820
import io.github.tmarsteel.emerge.backend.llvm.dsl.LlvmFunctionAttribute
1921
import io.github.tmarsteel.emerge.backend.llvm.dsl.LlvmInlineStructType
@@ -44,6 +46,7 @@ import io.github.tmarsteel.emerge.backend.llvm.intrinsics.stdlib.instructionAlia
4446
import io.github.tmarsteel.emerge.backend.llvm.jna.Llvm
4547
import io.github.tmarsteel.emerge.backend.llvm.jna.LlvmIntPredicate
4648
import io.github.tmarsteel.emerge.backend.llvm.jna.LlvmTypeRef
49+
import io.github.tmarsteel.emerge.backend.llvm.jna.NativeI32FlagGroup
4750

4851
internal object EmergeArrayBaseType : LlvmNamedStructType("anyarray"), EmergeHeapAllocated {
4952
val anyBase by structMember(EmergeHeapAllocatedValueBaseType)
@@ -62,6 +65,10 @@ internal object EmergeArrayBaseType : LlvmNamedStructType("anyarray"), EmergeHea
6265
override fun assureReinterpretableAsAnyValue(context: LlvmContext, selfInContext: LlvmTypeRef) {
6366
check(Llvm.LLVMOffsetOfElement(context.targetData.ref, selfInContext, anyBase.indexInStruct) == 0L)
6467
}
68+
69+
override fun computeDiType(diBuilder: DiBuilder): LlvmDebugInfo.Type {
70+
return computeDiType(this, diBuilder, listOf(::anyBase, ::elementCount), NativeI32FlagGroup())
71+
}
6572
}
6673

6774
internal class EmergeArrayType<Element : LlvmType>(
@@ -206,6 +213,10 @@ internal class EmergeArrayType<Element : LlvmType>(
206213
return raw
207214
}
208215

216+
override fun computeDiType(diBuilder: DiBuilder): LlvmDebugInfo.Type {
217+
return computeDiType(this, diBuilder, listOf(::base, ::elements), NativeI32FlagGroup())
218+
}
219+
209220
override fun assureReinterpretableAsAnyValue(context: LlvmContext, selfInContext: LlvmTypeRef) {
210221
check(Llvm.LLVMOffsetOfElement(context.targetData.ref, selfInContext, base.indexInStruct) == 0L)
211222
}

llvm-backend/src/main/kotlin/io/github/tmarsteel/emerge/backend/llvm/intrinsics/core_language_types.kt

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ import io.github.tmarsteel.emerge.backend.llvm.dsl.buildConstantIn
3131
import io.github.tmarsteel.emerge.backend.llvm.jna.DwarfBaseTypeEncoding
3232
import io.github.tmarsteel.emerge.backend.llvm.jna.Llvm
3333
import io.github.tmarsteel.emerge.backend.llvm.jna.LlvmTypeRef
34+
import io.github.tmarsteel.emerge.backend.llvm.jna.NativeI32FlagGroup
3435
import io.github.tmarsteel.emerge.backend.llvm.toBigInteger
3536
import io.github.tmarsteel.emerge.common.EmergeConstants
3637
import java.math.BigInteger
@@ -137,7 +138,7 @@ internal object EmergeWeakReferenceCollectionType : LlvmNamedStructType("weakref
137138
/**
138139
* The data common to all heap-allocated objects in emerge
139140
*/
140-
internal object EmergeHeapAllocatedValueBaseType : LlvmNamedStructType("anyvalue"), EmergeHeapAllocated {
141+
internal object EmergeHeapAllocatedValueBaseType : LlvmNamedStructType("anyvalue", JvmStackFrameIrSourceLocation(Thread.currentThread().stackTrace[1])), LlvmCachedType.ForwardDeclared, EmergeHeapAllocated {
141142
val strongReferenceCount by structMember(EmergeUWordType)
142143
val typeinfo by structMember(pointerTo(TypeinfoType.GENERIC))
143144
val weakReferenceCollection by structMember(pointerTo(EmergeWeakReferenceCollectionType))
@@ -153,6 +154,26 @@ internal object EmergeHeapAllocatedValueBaseType : LlvmNamedStructType("anyvalue
153154
override fun assureReinterpretableAsAnyValue(context: LlvmContext, selfInContext: LlvmTypeRef) {
154155
// this is AnyValue itself, noop
155156
}
157+
158+
override fun computeDiType(diBuilder: DiBuilder): LlvmDebugInfo.Type {
159+
return computeDiType(this, diBuilder, listOf(::strongReferenceCount, ::typeinfo, ::weakReferenceCollection), NativeI32FlagGroup())
160+
}
161+
162+
override fun createTemporaryForwardDeclaration(diBuilder: DiBuilder): LlvmDebugInfo.Type {
163+
return diBuilder.createTemporaryForwardDeclarationOfStructType(
164+
name,
165+
/*
166+
* approximation:
167+
* strongReferenceCount: word
168+
* typeinfo: pointer
169+
* weakRefColl: pointer
170+
*/
171+
sizeInBits = diBuilder.context.targetData.pointerSizeInBits * 3u,
172+
alignInBits = diBuilder.context.targetData.pointerSizeInBits.toUInt(),
173+
flags = NativeI32FlagGroup(),
174+
declaredAt = declaredAt!!,
175+
)
176+
}
156177
}
157178

158179
internal interface EmergeHeapAllocated : LlvmType {

llvm-backend/src/main/kotlin/io/github/tmarsteel/emerge/backend/llvm/intrinsics/typeinfo.kt

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,6 @@ package io.github.tmarsteel.emerge.backend.llvm.intrinsics
22

33
import com.google.common.collect.MapMaker
44
import io.github.tmarsteel.emerge.backend.api.ir.IrInterface
5-
import io.github.tmarsteel.emerge.backend.api.ir.IrSourceFile
6-
import io.github.tmarsteel.emerge.backend.api.ir.IrSourceLocation
75
import io.github.tmarsteel.emerge.backend.llvm.codegen.anyValueBase
86
import io.github.tmarsteel.emerge.backend.llvm.codegen.emergeStringLiteral
97
import io.github.tmarsteel.emerge.backend.llvm.dsl.BasicBlockBuilder.Companion.retVoid
@@ -38,8 +36,6 @@ import io.github.tmarsteel.emerge.backend.llvm.jna.LlvmTypeRef
3836
import io.github.tmarsteel.emerge.backend.llvm.jna.NativeI32FlagGroup
3937
import io.github.tmarsteel.emerge.backend.llvm.requireStructuralSupertypeOf
4038
import io.github.tmarsteel.emerge.backend.llvm.typeinfoHolder
41-
import java.nio.file.Path
42-
import java.nio.file.Paths
4339

4440
internal val staticObjectFinalizer: KotlinLlvmFunction<LlvmContext, LlvmVoidType> = KotlinLlvmFunction.define(
4541
"emerge.platform.finalizeStaticObject",
@@ -59,6 +55,10 @@ internal class VTableType private constructor(val nEntries: Long) : LlvmNamedStr
5955
val shiftRightAmount by structMember(LlvmU32Type)
6056
val addresses by structMember(LlvmArrayType(nEntries, LlvmFunctionAddressType))
6157

58+
override fun computeDiType(diBuilder: DiBuilder): LlvmDebugInfo.Type {
59+
return computeDiType(this, diBuilder, listOf(::shiftLeftAmount, ::shiftRightAmount, ::addresses))
60+
}
61+
6262
companion object {
6363
private val cache = MapMaker().weakValues().makeMap<Long, VTableType>()
6464
operator fun invoke(nEntries: Long): VTableType {
@@ -96,6 +96,10 @@ internal class TypeinfoType private constructor(val nVTableEntries: Long) : Llvm
9696
return other is TypeinfoType && other.nVTableEntries <= this.nVTableEntries
9797
}
9898

99+
override fun computeDiType(diBuilder: DiBuilder): LlvmDebugInfo.Type {
100+
return computeDiType(this, diBuilder, listOf(::supertypes, ::anyValueVirtuals, ::dynamicTypeInfoPtr, ::canonicalNamePtr, ::vtable), NativeI32FlagGroup())
101+
}
102+
99103
override fun createTemporaryForwardDeclaration(diBuilder: DiBuilder): LlvmDebugInfo.Type {
100104
return diBuilder.createTemporaryForwardDeclarationOfStructType(
101105
name,
@@ -121,13 +125,7 @@ internal class TypeinfoType private constructor(val nVTableEntries: Long) : Llvm
121125
}
122126
val GENERIC = TypeinfoType(0)
123127

124-
val declaredAt = object : IrSourceLocation {
125-
override val file = object : IrSourceFile {
126-
override val path: Path = Paths.get(Thread.currentThread().stackTrace[1].fileName)
127-
}
128-
override val lineNumber = 1u
129-
override val columnNumber = 1u
130-
}
128+
val declaredAt = JvmStackFrameIrSourceLocation(Thread.currentThread().stackTrace[1])
131129
}
132130
}
133131

0 commit comments

Comments
 (0)