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

Code before:
    // This should be called after all debug sources are processed so we use the correct source.
    // When called from findDebugScope for an imported module, m_defaultDebugSource may be null;
    // in that case we use the first IRDebugSource from this module's globals so we can still
    // register the module's debug scope and emit DebugFunctionDefinition for its functions.
    void ensureDebugCompilationUnit(IRModule* irModule)
    {
        auto debugLevel = m_targetProgram->getOptionSet().getDebugInfoLevel();
        if (debugLevel <= DebugInfoLevel::Minimal)
            return;

        auto moduleInst = irModule->getModuleInst();
        if (m_mapIRInstToSpvDebugInst.containsKey(moduleInst))
            return; // Already created

        IRDebugSource* debugSourceToUse = as<IRDebugSource>(m_defaultDebugSource);
        if (!debugSourceToUse)
        {
            for (auto inst : irModule->getGlobalInsts())
            {
                if (auto debugSource = as<IRDebugSource>(inst))
                {
                    debugSourceToUse = debugSource;
                    break;
                }
            }
        }
        if (!debugSourceToUse)
            return;

        // Get the SpvInst for the debug source
        SpvInst* sourceSpvInst = nullptr;
        if (!m_mapIRInstToSpvInst.tryGetValue(debugSourceToUse, sourceSpvInst))
            return;

        IRBuilder builder(debugSourceToUse);
        builder.setInsertBefore(debugSourceToUse);
        auto translationUnit = emitOpDebugCompilationUnit(
            getSection(SpvLogicalSectionID::ConstantsAndTypes),
            moduleInst,
            debugSourceToUse->getFullType(),
            getNonSemanticDebugInfoExtInst(),
            emitIntConstant(100, builder.getUIntType()), // ExtDebugInfo version.
            emitIntConstant(5, builder.getUIntType()),   // DWARF version.
            sourceSpvInst,
            emitIntConstant(
                SpvSourceLanguageSlang,
                builder.getUIntType())); // Language.
        registerDebugInst(moduleInst, translationUnit);
    }

    Dictionary<UnownedStringSlice, SpvInst*> m_extensionInsts;

Review comment (bug):
I am wondering why this is needed.
It looks like when `processDebugGlobalInst()` is ran, it should have already found one.


Code after:

        // Get the SpvInst for the default debug source
        SpvInst* sourceSpvInst = nullptr;
        if (!m_mapIRInstToSpvInst.tryGetValue(m_defaultDebugSource, sourceSpvInst))
            return;

        IRBuilder builder(m_defaultDebugSource);
        builder.setInsertBefore(m_defaultDebugSource);
        auto translationUnit = emitOpDebugCompilationUnit(
            getSection(SpvLogicalSectionID::ConstantsAndTypes),
            moduleInst,
            m_defaultDebugSource->getFullType(),
            getNonSemanticDebugInfoExtInst(),
            emitIntConstant(100, builder.getUIntType()), // ExtDebugInfo version.
            emitIntConstant(5, builder.getUIntType()),   // DWARF version.
            sourceSpvInst,
            emitIntConstant(
                SpvSourceLanguageSlang,
                builder.getUIntType())); // Language.
        registerDebugInst(moduleInst, translationUnit);
    }

    Dictionary<UnownedStringSlice, SpvInst*> m_extensionInsts;
    SpvInst* ensureExtensionDeclaration(UnownedStringSlice name)
    {
        SpvInst* result = nullptr;
        if (m_extensionInsts.tryGetValue(name, result))
            return result;
        result = emitOpExtension(getSection(SpvLogicalSectionID::Extensions), nullptr, name);
        m_extensionInsts[name] = result;
        return result;
    }

    List<List<UnownedStringSlice>> m_anyExtension;
    void ensureAnyExtensionDeclaration(List<UnownedStringSlice> extensions)
    {
        if (!m_anyExtension.contains(extensions))
        {
            m_anyExtension.add(extensions);
        }
    }

    void emitSPIRVAnyExtension()
    {
        for (const auto& options : m_anyExtension)
        {
            bool found = false;
            for (UnownedStringSlice option : options)
            {
                if (m_extensionInsts.tryGetValue(option))
                {