[codegen][debug info] codegerator uses start/end location encapsulated in IrElement
This commit is contained in:
+33
-21
@@ -155,6 +155,11 @@ private inline fun <R> generateFunctionBody(
|
||||
functionGenerationContext.resetDebugLocation()
|
||||
}
|
||||
|
||||
/**
|
||||
* There're cases when we don't need end position or it is meaningless.
|
||||
*/
|
||||
internal data class LocationInfoRange(var start: LocationInfo, var end: LocationInfo?)
|
||||
|
||||
internal class FunctionGenerationContext(val function: LLVMValueRef,
|
||||
val codegen: CodeGenerator,
|
||||
startLocation: LocationInfo?,
|
||||
@@ -163,11 +168,11 @@ internal class FunctionGenerationContext(val function: LLVMValueRef,
|
||||
|
||||
override val context = codegen.context
|
||||
val vars = VariableManager(this)
|
||||
private val basicBlockToLastLocation = mutableMapOf<LLVMBasicBlockRef, LocationInfo>()
|
||||
private val basicBlockToLastLocation = mutableMapOf<LLVMBasicBlockRef, LocationInfoRange>()
|
||||
|
||||
private fun update(block:LLVMBasicBlockRef, locationInfo: LocationInfo?) {
|
||||
private fun update(block:LLVMBasicBlockRef, locationInfo: LocationInfo?, endLocation: LocationInfo? = null) {
|
||||
locationInfo ?: return
|
||||
basicBlockToLastLocation.put(block, locationInfo)
|
||||
basicBlockToLastLocation.put(block, LocationInfoRange(locationInfo, endLocation))
|
||||
}
|
||||
|
||||
var returnType: LLVMTypeRef? = LLVMGetReturnType(getFunctionType(function))
|
||||
@@ -209,9 +214,9 @@ internal class FunctionGenerationContext(val function: LLVMValueRef,
|
||||
return bb
|
||||
}
|
||||
|
||||
fun basicBlock(name:String = "label_" , locationInfo:LocationInfo?): LLVMBasicBlockRef {
|
||||
fun basicBlock(name:String = "label_", startLocationInfo:LocationInfo?, endLocationInfo: LocationInfo? = null): LLVMBasicBlockRef {
|
||||
val result = LLVMInsertBasicBlock(this.currentBlock, name)!!
|
||||
update(result, locationInfo)
|
||||
update(result, startLocationInfo, endLocationInfo)
|
||||
LLVMMoveBasicBlockAfter(result, this.currentBlock)
|
||||
return result
|
||||
}
|
||||
@@ -375,8 +380,11 @@ internal class FunctionGenerationContext(val function: LLVMValueRef,
|
||||
}
|
||||
}
|
||||
|
||||
val success = basicBlock("call_success", position())
|
||||
val position = position()
|
||||
val endLocation = position?.start.let { position?.end }
|
||||
val success = basicBlock("call_success", endLocation)
|
||||
val result = LLVMBuildInvoke(builder, llvmFunction, rargs, args.size, success, unwind, "")!!
|
||||
update(success, endLocation, endLocation)
|
||||
positionAtEnd(success)
|
||||
return result
|
||||
}
|
||||
@@ -526,15 +534,15 @@ internal class FunctionGenerationContext(val function: LLVMValueRef,
|
||||
}
|
||||
|
||||
fun filteringExceptionHandler(codeContext: CodeContext): ExceptionHandler {
|
||||
val lpBlock = basicBlockInFunction("filteringExceptionHandler", position())
|
||||
val lpBlock = basicBlockInFunction("filteringExceptionHandler", position()?.start)
|
||||
|
||||
appendingTo(lpBlock) {
|
||||
val landingpad = gxxLandingpad(2)
|
||||
LLVMAddClause(landingpad, kotlinExceptionRtti.llvm)
|
||||
LLVMAddClause(landingpad, LLVMConstNull(kInt8Ptr))
|
||||
|
||||
val fatalForeignExceptionBlock = basicBlock("fatalForeignException", position())
|
||||
val forwardKotlinExceptionBlock = basicBlock("forwardKotlinException", position())
|
||||
val fatalForeignExceptionBlock = basicBlock("fatalForeignException", position()?.start)
|
||||
val forwardKotlinExceptionBlock = basicBlock("forwardKotlinException", position()?.start)
|
||||
|
||||
val isKotlinException = icmpEq(
|
||||
extractValue(landingpad, 1),
|
||||
@@ -565,7 +573,7 @@ internal class FunctionGenerationContext(val function: LLVMValueRef,
|
||||
call(context.llvm.cxxStdTerminate, emptyList())
|
||||
|
||||
// Note: unreachable instruction to be generated here, but debug information is improper in this case.
|
||||
val loopBlock = basicBlock("loop", position())
|
||||
val loopBlock = basicBlock("loop", position()?.start)
|
||||
br(loopBlock)
|
||||
appendingTo(loopBlock) {
|
||||
br(loopBlock)
|
||||
@@ -626,12 +634,14 @@ internal class FunctionGenerationContext(val function: LLVMValueRef,
|
||||
): LLVMValueRef {
|
||||
val resultType = thenValue.type
|
||||
|
||||
val bbExit = basicBlock(locationInfo = position())
|
||||
val position = position()
|
||||
val endPosition = position()?.end
|
||||
val bbExit = basicBlock(startLocationInfo = endPosition, endLocationInfo = endPosition)
|
||||
val resultPhi = appendingTo(bbExit) {
|
||||
phi(resultType)
|
||||
}
|
||||
|
||||
val bbElse = basicBlock(locationInfo = position())
|
||||
val bbElse = basicBlock(startLocationInfo = position?.start, endLocationInfo = endPosition)
|
||||
|
||||
condBr(condition, bbExit, bbElse)
|
||||
assignPhis(resultPhi to thenValue)
|
||||
@@ -647,8 +657,9 @@ internal class FunctionGenerationContext(val function: LLVMValueRef,
|
||||
}
|
||||
|
||||
inline fun ifThen(condition: LLVMValueRef, thenBlock: () -> Unit) {
|
||||
val bbExit = basicBlock(locationInfo = position())
|
||||
val bbThen = basicBlock(locationInfo = position())
|
||||
val endPosition = position()?.end
|
||||
val bbExit = basicBlock(startLocationInfo = endPosition, endLocationInfo = endPosition)
|
||||
val bbThen = basicBlock(startLocationInfo = endPosition, endLocationInfo = endPosition)
|
||||
|
||||
condBr(condition, bbThen, bbExit)
|
||||
|
||||
@@ -660,10 +671,10 @@ internal class FunctionGenerationContext(val function: LLVMValueRef,
|
||||
positionAtEnd(bbExit)
|
||||
}
|
||||
|
||||
internal fun debugLocation(locationInfo: LocationInfo): DILocationRef? {
|
||||
internal fun debugLocation(startLocationInfo: LocationInfo, endLocation: LocationInfo?): DILocationRef? {
|
||||
if (!context.shouldContainDebugInfo()) return null
|
||||
update(currentBlock, locationInfo)
|
||||
val debugLocation = codegen.generateLocationInfo(locationInfo)
|
||||
update(currentBlock, startLocationInfo, endLocation)
|
||||
val debugLocation = codegen.generateLocationInfo(startLocationInfo)
|
||||
currentPositionHolder.setBuilderDebugLocation(debugLocation)
|
||||
return debugLocation
|
||||
}
|
||||
@@ -741,7 +752,8 @@ internal class FunctionGenerationContext(val function: LLVMValueRef,
|
||||
fun getObjectValue(
|
||||
irClass: IrClass,
|
||||
exceptionHandler: ExceptionHandler,
|
||||
locationInfo: LocationInfo?
|
||||
startLocationInfo: LocationInfo?,
|
||||
endLocationInfo: LocationInfo? = null
|
||||
): LLVMValueRef {
|
||||
if (irClass.isUnit()) {
|
||||
return codegen.theUnitInstanceRef.llvm
|
||||
@@ -763,8 +775,8 @@ internal class FunctionGenerationContext(val function: LLVMValueRef,
|
||||
|
||||
val shared = irClass.objectIsShared && context.config.threadsAreAllowed
|
||||
val objectPtr = codegen.getObjectInstanceStorage(irClass, shared)
|
||||
val bbInit = basicBlock("label_init", locationInfo)
|
||||
val bbExit = basicBlock("label_continue", locationInfo)
|
||||
val bbInit = basicBlock("label_init", startLocationInfo, endLocationInfo)
|
||||
val bbExit = basicBlock("label_continue", startLocationInfo, endLocationInfo)
|
||||
val objectVal = loadSlot(objectPtr, false)
|
||||
val objectInitialized = icmpUGt(ptrToInt(objectVal, codegen.intPtrType), codegen.immOneIntPtrType)
|
||||
val bbCurrent = currentBlock
|
||||
@@ -1034,7 +1046,7 @@ internal class FunctionGenerationContext(val function: LLVMValueRef,
|
||||
|
||||
fun positionAtEnd(block: LLVMBasicBlockRef) {
|
||||
LLVMPositionBuilderAtEnd(builder, block)
|
||||
basicBlockToLastLocation[block]?.let{ debugLocation(it) }
|
||||
basicBlockToLastLocation[block]?.let{ debugLocation(it.start, it.end) }
|
||||
val lastInstr = LLVMGetLastInstruction(block)
|
||||
isAfterTerminator = lastInstr != null && (LLVMIsATerminatorInst(lastInstr) != null)
|
||||
}
|
||||
|
||||
+26
-12
@@ -467,7 +467,7 @@ internal class CodeGeneratorVisitor(val context: Context, val lifetimes: Map<IrE
|
||||
//-------------------------------------------------------------------------//
|
||||
|
||||
private inner class LoopScope(val loop: IrLoop) : InnerScopeImpl() {
|
||||
val loopExit = functionGenerationContext.basicBlock("loop_exit", loop.condition.startLocation)
|
||||
val loopExit = functionGenerationContext.basicBlock("loop_exit", loop.endLocation)
|
||||
val loopCheck = functionGenerationContext.basicBlock("loop_check", loop.condition.startLocation)
|
||||
|
||||
override fun genBreak(destination: IrBreak) {
|
||||
@@ -806,7 +806,8 @@ internal class CodeGeneratorVisitor(val context: Context, val lifetimes: Map<IrE
|
||||
functionGenerationContext.getObjectValue(
|
||||
value.symbol.owner,
|
||||
currentCodeContext.exceptionHandler,
|
||||
value.startLocation
|
||||
value.startLocation,
|
||||
value.endLocation
|
||||
)
|
||||
|
||||
|
||||
@@ -1052,7 +1053,7 @@ internal class CodeGeneratorVisitor(val context: Context, val lifetimes: Map<IrE
|
||||
val needsPhi = isUnconditional(expression.branches.last()) && !expression.type.isUnit()
|
||||
val llvmType = codegen.getLLVMType(expression.type)
|
||||
|
||||
val bbExit = lazy { functionGenerationContext.basicBlock("when_exit", expression.startLocation) }
|
||||
val bbExit = lazy { functionGenerationContext.basicBlock("when_exit", expression.endLocation) }
|
||||
|
||||
val resultPhi = lazy {
|
||||
functionGenerationContext.appendingTo(bbExit.value) {
|
||||
@@ -1070,7 +1071,7 @@ internal class CodeGeneratorVisitor(val context: Context, val lifetimes: Map<IrE
|
||||
val bbNext = if (it == expression.branches.last())
|
||||
null
|
||||
else
|
||||
functionGenerationContext.basicBlock("when_next", it.startLocation)
|
||||
functionGenerationContext.basicBlock("when_next", it.startLocation, it.endLocation)
|
||||
generateWhenCase(whenEmittingContext, it, bbNext)
|
||||
}
|
||||
|
||||
@@ -1089,7 +1090,7 @@ internal class CodeGeneratorVisitor(val context: Context, val lifetimes: Map<IrE
|
||||
val brResult = if (isUnconditional(branch))
|
||||
evaluateExpression(branch.result)
|
||||
else {
|
||||
val bbCase = functionGenerationContext.basicBlock("when_case", branch.startLocation)
|
||||
val bbCase = functionGenerationContext.basicBlock("when_case", branch.startLocation, branch.endLocation)
|
||||
val condition = evaluateExpression(branch.condition)
|
||||
functionGenerationContext.condBr(condition, bbCase, bbNext ?: whenEmittingContext.bbExit.value)
|
||||
functionGenerationContext.positionAtEnd(bbCase)
|
||||
@@ -1558,9 +1559,17 @@ internal class CodeGeneratorVisitor(val context: Context, val lifetimes: Map<IrE
|
||||
|
||||
var bbExit : LLVMBasicBlockRef? = null
|
||||
var resultPhi : LLVMValueRef? = null
|
||||
private val functionScope: DIScopeOpaqueRef?
|
||||
get() = returnableBlock.inlineFunctionSymbol?.owner?.scope()
|
||||
private val outerScope = currentCodeContext.scope()
|
||||
|
||||
private fun getExit(): LLVMBasicBlockRef {
|
||||
if (bbExit == null) bbExit = functionGenerationContext.basicBlock("returnable_block_exit", returnableBlock.startLocation)
|
||||
val location = returnableBlock.inlineFunctionSymbol?.let {
|
||||
location(it.owner.endLine(), it.owner.endColumn())
|
||||
} ?: returnableBlock.statements.lastOrNull()?.let {
|
||||
location(it.endLine(), it.endColumn())
|
||||
}
|
||||
if (bbExit == null) bbExit = functionGenerationContext.basicBlock("returnable_block_exit", location)
|
||||
return bbExit!!
|
||||
}
|
||||
|
||||
@@ -1591,13 +1600,19 @@ internal class CodeGeneratorVisitor(val context: Context, val lifetimes: Map<IrE
|
||||
|
||||
override fun location(line: Int, column: Int): LocationInfo? {
|
||||
return if (returnableBlock.inlineFunctionSymbol != null) {
|
||||
val diScope = returnableBlock.inlineFunctionSymbol?.owner?.scope() ?: return null
|
||||
LocationInfo(diScope, line, column, outerContext.location(returnableBlock.startLine(), returnableBlock.endLine()))
|
||||
val diScope = functionScope ?: return null
|
||||
val outerFileEntry = outerFileEntry()
|
||||
val inlinedAt = outerContext.location(outerFileEntry.line(returnableBlock.startOffset), outerFileEntry.column(returnableBlock.startOffset))
|
||||
LocationInfo(diScope, line, column, inlinedAt)
|
||||
} else {
|
||||
outerContext.location(line, column)
|
||||
}
|
||||
}
|
||||
|
||||
private fun outerFileEntry() =
|
||||
(outerContext.fileScope() as? FileScope)?.file?.fileEntry
|
||||
?: error("returnable block should be inlined at some file")
|
||||
|
||||
|
||||
/**
|
||||
* Note: DILexicalBlocks aren't nested, they should be scoped with the parent function.
|
||||
@@ -1736,10 +1751,9 @@ internal class CodeGeneratorVisitor(val context: Context, val lifetimes: Map<IrE
|
||||
private fun file() = (currentCodeContext.fileScope() as FileScope).file
|
||||
|
||||
//-------------------------------------------------------------------------//
|
||||
private fun updateBuilderDebugLocation(element: IrElement): DILocationRef? {
|
||||
if (!context.shouldContainDebugInfo() || currentCodeContext.functionScope() == null) return null
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
return element.startLocation?.let { functionGenerationContext.debugLocation(it) }
|
||||
private fun updateBuilderDebugLocation(element: IrElement) {
|
||||
if (!context.shouldContainDebugInfo() || currentCodeContext.functionScope() == null || element.startLocation == null) return
|
||||
functionGenerationContext.debugLocation(element.startLocation!!, element.endLocation!!)
|
||||
}
|
||||
|
||||
private val IrElement.startLocation: LocationInfo?
|
||||
|
||||
+1
-1
@@ -330,7 +330,7 @@ internal class RTTIGenerator(override val context: Context) : ContextUtils {
|
||||
functionType(kObjHeaderPtr, false, kObjHeaderPtrPtr),
|
||||
""
|
||||
) {
|
||||
ret(getObjectValue(value, ExceptionHandler.Caller, locationInfo = null))
|
||||
ret(getObjectValue(value, ExceptionHandler.Caller, startLocationInfo = null))
|
||||
}
|
||||
|
||||
Struct(runtime.associatedObjectTableRecordType, key.typeInfoPtr, constPointer(associatedObjectGetter))
|
||||
|
||||
+1
-1
@@ -1148,7 +1148,7 @@ private fun ObjCExportCodeGenerator.createObjectInstanceAdapter(
|
||||
|
||||
return generateObjCToKotlinSyntheticGetter(selector) {
|
||||
initRuntimeIfNeeded() // For instance methods it gets called when allocating.
|
||||
val value = getObjectValue(irClass, locationInfo = null, exceptionHandler = ExceptionHandler.Caller)
|
||||
val value = getObjectValue(irClass, startLocationInfo = null, exceptionHandler = ExceptionHandler.Caller)
|
||||
ret(kotlinToObjC(value, ReferenceBridge))
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user