Repository: shader-slang/slang
File: source/slang/slang-ir.cpp (C++)

Code before:
}
IRInst* IRBuilder::emitDebugLine(
    IRInst* source,
    IRIntegerValue lineStart,
    IRIntegerValue lineEnd,
    IRIntegerValue colStart,
    IRIntegerValue colEnd)
{
    IRInst* args[] = {
        source,
        getIntValue(getUIntType(), lineStart),
        getIntValue(getUIntType(), lineEnd),
        getIntValue(getUIntType(), colStart),
        getIntValue(getUIntType(), colEnd)};
    return emitIntrinsicInst(getVoidType(), kIROp_DebugLine, 5, args);
}
IRInst* IRBuilder::emitDebugVar(
    IRType* type,
    IRInst* source,
    IRInst* line,
    IRInst* col,
    IRInst* argIndex)
{
    if (argIndex)
    {
        // Note +1 logic for argIndex is to follow the convention that
        // 1-based index of the argument is used by GLSLANG/DXC NSDI.
        IRInst* newArgIndex = getIntValue(getUIntType(), getIntVal(argIndex) + 1);
        IRInst* args[] = {source, line, col, newArgIndex};
        return emitIntrinsicInst(getPtrType(type), kIROp_DebugVar, 4, args);
    }
    else
    {
        IRInst* args[] = {source, line, col};
        return emitIntrinsicInst(getPtrType(type), kIROp_DebugVar, 3, args);
    }
}

IRInst* IRBuilder::emitDebugValue(IRInst* debugVar, IRInst* debugValue)
{
    List<IRInst*> args;
    args.add(debugVar);
    args.add(debugValue);
    return emitIntrinsicInst(
        getVoidType(),
        kIROp_DebugValue,
        (UInt)args.getCount(),
        args.getBuffer());
}

IRInst* IRBuilder::emitDebugInlinedAt(

Review comment (bug):
I am not actually sure if this is correct.
This IR could be mapped to `DebugDeclare` .
But looking at the spec of those two insts, it doesn't seem that 1 based argIndex is correct.

> DebugDeclare

> Define point of declaration of a [local variable](https://github.khronos.org/SPIRV-Registry/nonsemantic/NonSemantic.Shader.DebugInfo.100.html#LocalVariable).
> 
> Result Type must be OpTypeVoid.
> 
> Local Variable must be an <id> of [DebugLocalVariable](https://github.khronos.org/SPIRV-Registry/nonsemantic/NonSemantic.Shader.DebugInfo.100.html#DebugLocalVariable).
> 
> Variable must be the <id> of an OpVariable instruction that defines the local variable.
> 
> Expression must be an <id> of a [DebugExpression](https://github.khronos.org/SPIRV-Registry/nonsemantic/NonSemantic.Shader.DebugInfo.100.html#DebugExpression) instruction.
> 
> Indexes have the same semantics as the corresponding operand(s) of OpAccessChain, applied to the Local Variable.

And `OpAccessChain` is not using the 1-based index.

Code after:
}
IRInst* IRBuilder::emitDebugLine(
    IRInst* source,
    IRIntegerValue lineStart,
    IRIntegerValue lineEnd,
    IRIntegerValue colStart,
    IRIntegerValue colEnd)
{
    IRInst* args[] = {
        source,
        getIntValue(getUIntType(), lineStart),
        getIntValue(getUIntType(), lineEnd),
        getIntValue(getUIntType(), colStart),
        getIntValue(getUIntType(), colEnd)};
    return emitIntrinsicInst(getVoidType(), kIROp_DebugLine, 5, args);
}
IRInst* IRBuilder::emitDebugVar(
    IRType* type,
    IRInst* source,
    IRInst* line,
    IRInst* col,
    IRInst* argIndex)
{
    if (argIndex)
    {
        IRInst* args[] = {source, line, col, argIndex};
        return emitIntrinsicInst(getPtrType(type), kIROp_DebugVar, 4, args);
    }
    else
    {
        IRInst* args[] = {source, line, col};
        return emitIntrinsicInst(getPtrType(type), kIROp_DebugVar, 3, args);
    }
}

IRInst* IRBuilder::emitDebugValue(IRInst* debugVar, IRInst* debugValue)
{
    List<IRInst*> args;
    args.add(debugVar);
    args.add(debugValue);
    return emitIntrinsicInst(
        getVoidType(),
        kIROp_DebugValue,
        (UInt)args.getCount(),
        args.getBuffer());
}

IRInst* IRBuilder::emitDebugInlinedAt(
    IRInst* line,
    IRInst* col,
    IRInst* file,