diff --git a/tools/clang/lib/SPIRV/SpirvEmitter.cpp b/tools/clang/lib/SPIRV/SpirvEmitter.cpp index 94952b3c34..4a3da2197e 100644 --- a/tools/clang/lib/SPIRV/SpirvEmitter.cpp +++ b/tools/clang/lib/SPIRV/SpirvEmitter.cpp @@ -1442,37 +1442,16 @@ void SpirvEmitter::doFunctionDecl(const FunctionDecl *decl) { // This will allow the entry-point name to be something like // myNamespace::myEntrypointFunc. std::string funcName = getFnName(decl); - std::string debugFuncName = funcName; - + std::string srcFuncName = "src." + funcName; SpirvFunction *func = declIdMapper.getOrRegisterFn(decl); + SpirvFunction *srcFunc = nullptr; auto loc = decl->getLocStart(); auto range = decl->getSourceRange(); RichDebugInfo *info = nullptr; SpirvDebugFunction *debugFunction = nullptr; + SpirvDebugFunction *srcDebugFunction = nullptr; SpirvDebugInstruction *outer_scope = spvContext.getCurrentLexicalScope(); - const auto &sm = astContext.getSourceManager(); - if (spirvOptions.debugInfoRich && decl->hasBody()) { - const uint32_t line = sm.getPresumedLineNumber(loc); - const uint32_t column = sm.getPresumedColumnNumber(loc); - info = getOrCreateRichDebugInfo(loc); - - auto *source = info->source; - // Note that info->scopeStack.back() is a lexical scope of the function - // caller. - auto *parentScope = info->compilationUnit; - // TODO: figure out the proper flag based on the function decl. - // using FlagIsPublic for now. - uint32_t flags = 3u; - // The line number in the source program at which the function scope begins. - auto scopeLine = sm.getPresumedLineNumber(decl->getBody()->getLocStart()); - debugFunction = spvBuilder.createDebugFunction(decl, debugFuncName, source, - line, column, parentScope, - "", flags, scopeLine, func); - func->setDebugScope(new (spvContext) SpirvDebugScope(debugFunction)); - - spvContext.pushDebugLexicalScope(info, debugFunction); - } bool isEntry = false; const auto iter = functionInfoMap.find(decl); @@ -1480,10 +1459,17 @@ void SpirvEmitter::doFunctionDecl(const FunctionDecl *decl) { const auto &entryInfo = iter->second; if (entryInfo->isEntryFunction) { isEntry = true; - funcName = "src." + funcName; // Create wrapper for the entry function - if (!emitEntryFunctionWrapper(decl, func)) + srcFunc = func; + + func = emitEntryFunctionWrapper(decl, &info, &debugFunction, srcFunc); + if (func == nullptr) return; + if (spirvOptions.debugInfoRich && decl->hasBody()) { + // use the HLSL name the debug user will expect to see + srcDebugFunction = emitDebugFunction(decl, srcFunc, &info, funcName); + } + // Generate DebugEntryPoint if function definition if (spirvOptions.debugInfoVulkan && debugFunction) { auto *cu = dyn_cast(outer_scope); @@ -1493,14 +1479,26 @@ void SpirvEmitter::doFunctionDecl(const FunctionDecl *decl) { spirvOptions.clOptions); } } + else { + if (spirvOptions.debugInfoRich && decl->hasBody()) { + debugFunction = emitDebugFunction(decl, func, &info, funcName); + } + } } const QualType retType = declIdMapper.getTypeAndCreateCounterForPotentialAliasVar(decl); - spvBuilder.beginFunction(retType, decl->getLocStart(), funcName, - decl->hasAttr(), - decl->hasAttr(), func); + if (srcFunc) { + spvBuilder.beginFunction(retType, decl->getLocStart(), srcFuncName, + decl->hasAttr(), + decl->hasAttr(), srcFunc); + + } else { + spvBuilder.beginFunction(retType, decl->getLocStart(), funcName, + decl->hasAttr(), + decl->hasAttr(), func); + } bool isNonStaticMemberFn = false; if (const auto *memberFn = dyn_cast(decl)) { @@ -1551,7 +1549,9 @@ void SpirvEmitter::doFunctionDecl(const FunctionDecl *decl) { // Add DebugFunctionDefinition if we are emitting // NonSemantic.Shader.DebugInfo.100 debug info - if (spirvOptions.debugInfoVulkan && debugFunction) + if (spirvOptions.debugInfoVulkan && srcDebugFunction) + spvBuilder.createDebugFunctionDef(srcDebugFunction, srcFunc); + else if (spirvOptions.debugInfoVulkan && debugFunction) spvBuilder.createDebugFunctionDef(debugFunction, func); // Process all statments in the body. @@ -13197,11 +13197,17 @@ bool SpirvEmitter::processTessellationShaderAttributes( } bool SpirvEmitter::emitEntryFunctionWrapperForRayTracing( - const FunctionDecl *decl, SpirvFunction *entryFuncInstr) { + const FunctionDecl *decl, SpirvDebugFunction *debugFunction, + SpirvFunction *entryFuncInstr) { // The entry basic block. auto *entryLabel = spvBuilder.createBasicBlock(); spvBuilder.setInsertPoint(entryLabel); + // Add DebugFunctionDefinition if we are emitting + // NonSemantic.Shader.DebugInfo.100 debug info. + if (spirvOptions.debugInfoVulkan && debugFunction) + spvBuilder.createDebugFunctionDef(debugFunction, entryFunction); + // Initialize all global variables at the beginning of the wrapper for (const VarDecl *varDecl : toInitGloalVars) { const auto varInfo = @@ -13464,8 +13470,39 @@ bool SpirvEmitter::processMeshOrAmplificationShaderAttributes( return true; } -bool SpirvEmitter::emitEntryFunctionWrapper(const FunctionDecl *decl, - SpirvFunction *entryFuncInstr) { +SpirvDebugFunction *SpirvEmitter::emitDebugFunction(const FunctionDecl *decl, + SpirvFunction *func, + RichDebugInfo **info, + std::string name) { + auto loc = decl->getLocStart(); + const auto &sm = astContext.getSourceManager(); + const uint32_t line = sm.getPresumedLineNumber(loc); + const uint32_t column = sm.getPresumedColumnNumber(loc); + *info = getOrCreateRichDebugInfo(loc); + + SpirvDebugSource *source = (*info)->source; + // Note that info->scopeStack.back() is a lexical scope of the function + // caller. + SpirvDebugInstruction *parentScope = (*info)->compilationUnit; + // TODO: figure out the proper flag based on the function decl. + // using FlagIsPublic for now. + uint32_t flags = 3u; + // The line number in the source program at which the function scope begins. + auto scopeLine = sm.getPresumedLineNumber(decl->getBody()->getLocStart()); + SpirvDebugFunction *debugFunction = + spvBuilder.createDebugFunction(decl, name, source, line, column, + parentScope, "", flags, scopeLine, func); + func->setDebugScope(new (spvContext) SpirvDebugScope(debugFunction)); + + spvContext.pushDebugLexicalScope(*info, debugFunction); + return debugFunction; +} + +SpirvFunction * +SpirvEmitter::emitEntryFunctionWrapper(const FunctionDecl *decl, + RichDebugInfo **info, + SpirvDebugFunction **debugFunction, + SpirvFunction *entryFuncInstr) { // HS specific attributes uint32_t numOutputControlPoints = 0; SpirvInstruction *outputControlPointIdVal = @@ -13486,6 +13523,10 @@ bool SpirvEmitter::emitEntryFunctionWrapper(const FunctionDecl *decl, entryFunction = spvBuilder.beginFunction( astContext.VoidTy, decl->getLocStart(), decl->getName()); + if (spirvOptions.debugInfoRich && decl->hasBody()) { + *debugFunction = emitDebugFunction(decl, entryFunction, info, "wrapper"); + } + // Specify that entryFunction is an entry function wrapper. entryFunction->setEntryFunctionWrapper(); @@ -13500,7 +13541,10 @@ bool SpirvEmitter::emitEntryFunctionWrapper(const FunctionDecl *decl, entryInfo->entryFunction = entryFunction; if (spvContext.isRay()) { - return emitEntryFunctionWrapperForRayTracing(decl, entryFuncInstr); + return emitEntryFunctionWrapperForRayTracing(decl, *debugFunction, + entryFuncInstr) + ? entryFunction + : nullptr; } // Handle attributes specific to each shader stage if (spvContext.isPS()) { @@ -13509,7 +13553,7 @@ bool SpirvEmitter::emitEntryFunctionWrapper(const FunctionDecl *decl, processComputeShaderAttributes(decl); } else if (spvContext.isHS()) { if (!processTessellationShaderAttributes(decl, &numOutputControlPoints)) - return false; + return nullptr; // The input array size for HS is specified in the InputPatch parameter. for (const auto *param : decl->params()) @@ -13521,7 +13565,7 @@ bool SpirvEmitter::emitEntryFunctionWrapper(const FunctionDecl *decl, outputArraySize = numOutputControlPoints; } else if (spvContext.isDS()) { if (!processTessellationShaderAttributes(decl, &numOutputControlPoints)) - return false; + return nullptr; // The input array size for HS is specified in the OutputPatch parameter. for (const auto *param : decl->params()) @@ -13532,11 +13576,11 @@ bool SpirvEmitter::emitEntryFunctionWrapper(const FunctionDecl *decl, // The per-vertex output of DS is not an array. } else if (spvContext.isGS()) { if (!processGeometryShaderAttributes(decl, &inputArraySize)) - return false; + return nullptr; // The per-vertex output of GS is not an array. } else if (spvContext.isMS() || spvContext.isAS()) { if (!processMeshOrAmplificationShaderAttributes(decl, &outputArraySize)) - return false; + return nullptr; } // Go through all parameters and record the declaration of SV_ClipDistance @@ -13552,14 +13596,14 @@ bool SpirvEmitter::emitEntryFunctionWrapper(const FunctionDecl *decl, for (const auto *param : decl->params()) { if (canActAsInParmVar(param)) if (!declIdMapper.glPerVertex.recordGlPerVertexDeclFacts(param, true)) - return false; + return nullptr; if (canActAsOutParmVar(param)) if (!declIdMapper.glPerVertex.recordGlPerVertexDeclFacts(param, false)) - return false; + return nullptr; } // Also consider the SV_ClipDistance/SV_CullDistance in the return type if (!declIdMapper.glPerVertex.recordGlPerVertexDeclFacts(decl, false)) - return false; + return nullptr; // Calculate the total size of the ClipDistance/CullDistance array and the // offset of SV_ClipDistance/SV_CullDistance variables within the array. @@ -13581,6 +13625,11 @@ bool SpirvEmitter::emitEntryFunctionWrapper(const FunctionDecl *decl, // after the basic block is created and insert point is set. processInlineSpirvAttributes(decl); + // Add DebugFunctionDefinition if we are emitting + // NonSemantic.Shader.DebugInfo.100 debug info. + if (spirvOptions.debugInfoVulkan && *debugFunction) + spvBuilder.createDebugFunctionDef(*debugFunction, entryFunction); + // Initialize all global variables at the beginning of the wrapper for (const VarDecl *varDecl : toInitGloalVars) { // SPIR-V does not have string variables @@ -13632,7 +13681,7 @@ bool SpirvEmitter::emitEntryFunctionWrapper(const FunctionDecl *decl, SpirvInstruction *loadedValue = nullptr; if (!declIdMapper.createStageInputVar(param, &loadedValue, false)) - return false; + return nullptr; // Only initialize the temporary variable if the parameter is indeed used, // or if it is an inout parameter. @@ -13671,15 +13720,15 @@ bool SpirvEmitter::emitEntryFunctionWrapper(const FunctionDecl *decl, // Create stage output variables out of the return type. if (!declIdMapper.createStageOutputVar(decl, numOutputControlPoints, outputControlPointIdVal, retVal)) - return false; + return nullptr; if (!processHSEntryPointOutputAndPCF( decl, retType, retVal, numOutputControlPoints, outputControlPointIdVal, primitiveIdVar, viewIdVar, hullMainInputPatchParam)) - return false; + return nullptr; } else { if (!declIdMapper.createStageOutputVar(decl, retVal, /*forPCF*/ false)) - return false; + return nullptr; } // Create and write stage output variables for parameters marked as @@ -13702,7 +13751,7 @@ bool SpirvEmitter::emitEntryFunctionWrapper(const FunctionDecl *decl, param->getLocStart()); if (!declIdMapper.createStageOutputVar(param, loadedParam, false)) - return false; + return nullptr; } } @@ -13717,7 +13766,7 @@ bool SpirvEmitter::emitEntryFunctionWrapper(const FunctionDecl *decl, if (spvContext.isHS()) doDecl(patchConstFunc); - return true; + return entryFunction; } bool SpirvEmitter::processHSEntryPointOutputAndPCF( diff --git a/tools/clang/lib/SPIRV/SpirvEmitter.h b/tools/clang/lib/SPIRV/SpirvEmitter.h index 242550c295..36e8eff204 100644 --- a/tools/clang/lib/SPIRV/SpirvEmitter.h +++ b/tools/clang/lib/SPIRV/SpirvEmitter.h @@ -842,8 +842,14 @@ class SpirvEmitter : public ASTConsumer { processMeshOrAmplificationShaderAttributes(const FunctionDecl *decl, uint32_t *outVerticesArraySize); - /// \brief Emits a wrapper function for the entry function and returns true - /// on success. + /// \brief Emits a SpirvDebugFunction to match given SpirvFunction, and + /// returns a pointer to it. + SpirvDebugFunction *emitDebugFunction(const FunctionDecl *decl, + SpirvFunction *func, + RichDebugInfo **info, std::string name); + + /// \brief Emits a wrapper function for the entry function and returns a + /// pointer to the wrapper SpirvFunction on success. /// /// The wrapper function loads the values of all stage input variables and /// creates composites as expected by the source code entry function. It then @@ -853,8 +859,10 @@ class SpirvEmitter : public ASTConsumer { /// /// The wrapper function is also responsible for initializing global static /// variables for some cases. - bool emitEntryFunctionWrapper(const FunctionDecl *entryFunction, - SpirvFunction *entryFuncId); + SpirvFunction *emitEntryFunctionWrapper(const FunctionDecl *entryFunction, + RichDebugInfo **info, + SpirvDebugFunction **debugFunction, + SpirvFunction *entryFuncId); /// \brief Emits a wrapper function for the entry functions for raytracing /// stages and returns true on success. @@ -864,6 +872,7 @@ class SpirvEmitter : public ASTConsumer { /// The wrapper function is also responsible for initializing global static /// variables for some cases. bool emitEntryFunctionWrapperForRayTracing(const FunctionDecl *entryFunction, + SpirvDebugFunction *debugFunction, SpirvFunction *entryFuncId); /// \brief Performs the following operations for the Hull shader: diff --git a/tools/clang/test/CodeGenSPIRV/rich.debug.debugscope.hlsl b/tools/clang/test/CodeGenSPIRV/rich.debug.debugscope.hlsl index ca89825b1e..b9e1df57e4 100644 --- a/tools/clang/test/CodeGenSPIRV/rich.debug.debugscope.hlsl +++ b/tools/clang/test/CodeGenSPIRV/rich.debug.debugscope.hlsl @@ -2,16 +2,18 @@ // CHECK: [[set:%[0-9]+]] = OpExtInstImport "OpenCL.DebugInfo.100" // CHECK: [[compUnit:%[0-9]+]] = OpExtInst %void [[set]] DebugCompilationUnit +// CHECK: [[srcMain:%[0-9]+]] = OpExtInst %void [[set]] DebugFunction +// CHECK: [[mainFnLexBlock:%[0-9]+]] = OpExtInst %void [[set]] DebugLexicalBlock {{%[0-9]+}} 17 1 [[srcMain]] +// CHECK: [[whileLoopLexBlock:%[0-9]+]] = OpExtInst %void [[set]] DebugLexicalBlock {{%[0-9]+}} 37 3 [[mainFnLexBlock]] +// CHECK: [[ifStmtLexBlock:%[0-9]+]] = OpExtInst %void [[set]] DebugLexicalBlock {{%[0-9]+}} 44 20 [[whileLoopLexBlock]] +// CHECK: [[tempLexBlock:%[0-9]+]] = OpExtInst %void [[set]] DebugLexicalBlock {{%[0-9]+}} 49 7 [[ifStmtLexBlock]] +// CHECK: [[forLoopLexBlock:%[0-9]+]] = OpExtInst %void [[set]] DebugLexicalBlock {{%[0-9]+}} 22 12 [[mainFnLexBlock]] // CHECK: [[main:%[0-9]+]] = OpExtInst %void [[set]] DebugFunction -// CHECK: [[mainFnLexBlock:%[0-9]+]] = OpExtInst %void [[set]] DebugLexicalBlock {{%[0-9]+}} 15 1 [[main]] -// CHECK: [[whileLoopLexBlock:%[0-9]+]] = OpExtInst %void [[set]] DebugLexicalBlock {{%[0-9]+}} 35 3 [[mainFnLexBlock]] -// CHECK: [[ifStmtLexBlock:%[0-9]+]] = OpExtInst %void [[set]] DebugLexicalBlock {{%[0-9]+}} 42 20 [[whileLoopLexBlock]] -// CHECK: [[tempLexBlock:%[0-9]+]] = OpExtInst %void [[set]] DebugLexicalBlock {{%[0-9]+}} 47 7 [[ifStmtLexBlock]] -// CHECK: [[forLoopLexBlock:%[0-9]+]] = OpExtInst %void [[set]] DebugLexicalBlock {{%[0-9]+}} 20 12 [[mainFnLexBlock]] float4 main(float4 color : COLOR) : SV_TARGET +// CHECK: %main = OpFunction // CHECK: %src_main = OpFunction -// CHECK-NEXT: {{%[0-9]+}} = OpExtInst %void [[set]] DebugScope [[main]] +// CHECK-NEXT: {{%[0-9]+}} = OpExtInst %void [[set]] DebugScope [[srcMain]] { // CHECK: %bb_entry = OpLabel // CHECK-NEXT: {{%[0-9]+}} = OpExtInst %void [[set]] DebugScope [[mainFnLexBlock]] diff --git a/tools/clang/test/CodeGenSPIRV/rich.debug.function.param.hlsl b/tools/clang/test/CodeGenSPIRV/rich.debug.function.param.hlsl index c30dc8c262..052e55d272 100644 --- a/tools/clang/test/CodeGenSPIRV/rich.debug.function.param.hlsl +++ b/tools/clang/test/CodeGenSPIRV/rich.debug.function.param.hlsl @@ -7,18 +7,20 @@ // CHECK: [[emptyStr:%[0-9]+]] = OpString "" // CHECK: [[y:%[0-9]+]] = OpString "y" // CHECK: [[x:%[0-9]+]] = OpString "x" -// CHECK: [[mainName:%[0-9]+]] = OpString "main" +// CHECK: [[srcMainName:%[0-9]+]] = OpString "main" // CHECK: [[color:%[0-9]+]] = OpString "color" +// CHECK: [[mainName:%[0-9]+]] = OpString "wrapper" // CHECK: [[int:%[0-9]+]] = OpExtInst %void [[set]] DebugTypeBasic {{%[0-9]+}} %uint_32 Signed // CHECK: [[float:%[0-9]+]] = OpExtInst %void [[set]] DebugTypeBasic {{%[0-9]+}} %uint_32 Float // CHECK: [[source:%[0-9]+]] = OpExtInst %void [[set]] DebugSource -// CHECK: [[foo:%[0-9]+]] = OpExtInst %void [[set]] DebugFunction [[fooName]] {{%[0-9]+}} [[source]] 23 1 {{%[0-9]+}} [[emptyStr]] FlagIsProtected|FlagIsPrivate 24 %foo -// CHECK: {{%[0-9]+}} = OpExtInst %void [[set]] DebugLocalVariable [[y]] [[float]] [[source]] 23 23 [[foo]] FlagIsLocal 2 -// CHECK: {{%[0-9]+}} = OpExtInst %void [[set]] DebugLocalVariable [[x]] [[int]] [[source]] 23 14 [[foo]] FlagIsLocal 1 +// CHECK: [[foo:%[0-9]+]] = OpExtInst %void [[set]] DebugFunction [[fooName]] {{%[0-9]+}} [[source]] 25 1 {{%[0-9]+}} [[emptyStr]] FlagIsProtected|FlagIsPrivate 26 %foo +// CHECK: {{%[0-9]+}} = OpExtInst %void [[set]] DebugLocalVariable [[y]] [[float]] [[source]] 25 23 [[foo]] FlagIsLocal 2 +// CHECK: {{%[0-9]+}} = OpExtInst %void [[set]] DebugLocalVariable [[x]] [[int]] [[source]] 25 14 [[foo]] FlagIsLocal 1 // CHECK: [[float4:%[0-9]+]] = OpExtInst %void [[set]] DebugTypeVector [[float]] 4 -// CHECK: [[main:%[0-9]+]] = OpExtInst %void [[set]] DebugFunction [[mainName]] {{%[0-9]+}} [[source]] 28 1 {{%[0-9]+}} [[emptyStr]] FlagIsProtected|FlagIsPrivate 29 %src_main -// CHECK: {{%[0-9]+}} = OpExtInst %void [[set]] DebugLocalVariable [[color]] [[float4]] [[source]] 28 20 [[main]] FlagIsLocal 1 +// CHECK: [[srcMain:%[0-9]+]] = OpExtInst %void [[set]] DebugFunction [[srcMainName]] {{%[0-9]+}} [[source]] 30 1 {{%[0-9]+}} [[emptyStr]] FlagIsProtected|FlagIsPrivate 31 %src_main +// CHECK: {{%[0-9]+}} = OpExtInst %void [[set]] DebugLocalVariable [[color]] [[float4]] [[source]] 30 20 [[srcMain]] FlagIsLocal 1 +// CHECK: [[main:%[0-9]+]] = OpExtInst %void [[set]] DebugFunction [[mainName]] {{%[0-9]+}} [[source]] 30 1 {{%[0-9]+}} [[emptyStr]] FlagIsProtected|FlagIsPrivate 31 %main void foo(int x, float y) { diff --git a/tools/clang/test/CodeGenSPIRV/rich.debug.global-variable.hlsl b/tools/clang/test/CodeGenSPIRV/rich.debug.global-variable.hlsl index da42d892f7..8e7bafa0f7 100644 --- a/tools/clang/test/CodeGenSPIRV/rich.debug.global-variable.hlsl +++ b/tools/clang/test/CodeGenSPIRV/rich.debug.global-variable.hlsl @@ -8,11 +8,10 @@ // CHECK: [[float4Type:%[0-9]+]] = OpExtInst %void [[set]] DebugTypeVector [[floatType]] 4 // CHECK: [[source:%[0-9]+]] = OpExtInst %void [[set]] DebugSource // CHECK: [[compileUnit:%[0-9]+]] = OpExtInst %void [[set]] DebugCompilationUnit 1 4 [[source]] HLSL - // CHECK: [[boolType:%[0-9]+]] = OpExtInst %void [[set]] DebugTypeBasic {{%[0-9]+}} %uint_32 Boolean -// CHECK: {{%[0-9]+}} = OpExtInst %void [[set]] DebugGlobalVariable [[varNameCond]] [[boolType]] [[source]] 18 13 [[compileUnit]] [[varNameCond]] %cond FlagIsDefinition -// CHECK: {{%[0-9]+}} = OpExtInst %void [[set]] DebugGlobalVariable [[varNameC]] [[float4Type]] [[source]] 17 15 [[compileUnit]] [[varNameC]] %c FlagIsDefinition +// CHECK: {{%[0-9]+}} = OpExtInst %void [[set]] DebugGlobalVariable [[varNameCond]] [[boolType]] [[source]] 17 13 [[compileUnit]] [[varNameCond]] %cond FlagIsDefinition +// CHECK: {{%[0-9]+}} = OpExtInst %void [[set]] DebugGlobalVariable [[varNameC]] [[float4Type]] [[source]] 16 15 [[compileUnit]] [[varNameC]] %c FlagIsDefinition static float4 c; static bool cond; diff --git a/tools/clang/test/CodeGenSPIRV/rich.debug.local-variable.hlsl b/tools/clang/test/CodeGenSPIRV/rich.debug.local-variable.hlsl index f9150c4b09..216f0404d2 100644 --- a/tools/clang/test/CodeGenSPIRV/rich.debug.local-variable.hlsl +++ b/tools/clang/test/CodeGenSPIRV/rich.debug.local-variable.hlsl @@ -11,20 +11,22 @@ // CHECK: [[float4Type:%[0-9]+]] = OpExtInst %void [[set]] DebugTypeVector [[floatType]] 4 // CHECK: [[source:%[0-9]+]] = OpExtInst %void [[set]] DebugSource // CHECK: [[compileUnit:%[0-9]+]] = OpExtInst %void [[set]] DebugCompilationUnit 1 4 [[source]] HLSL -// CHECK: [[main:%[0-9]+]] = OpExtInst %void [[set]] DebugFunction {{%[0-9]+}} {{%[0-9]+}} [[source]] 29 1 [[compileUnit]] {{%[0-9]+}} FlagIsProtected|FlagIsPrivate 30 %src_main +// CHECK: [[main:%[0-9]+]] = OpExtInst %void [[set]] DebugFunction {{%[0-9]+}} {{%[0-9]+}} [[source]] 31 1 [[compileUnit]] {{%[0-9]+}} FlagIsProtected|FlagIsPrivate 32 %src_main -// CHECK: [[mainFnLexBlock:%[0-9]+]] = OpExtInst %void [[set]] DebugLexicalBlock [[source]] 30 1 [[main]] -// CHECK: [[ifLexBlock:%[0-9]+]] = OpExtInst %void [[set]] DebugLexicalBlock [[source]] 35 13 [[mainFnLexBlock]] -// CHECK: [[tempLexBlock:%[0-9]+]] = OpExtInst %void [[set]] DebugLexicalBlock [[source]] 38 5 [[ifLexBlock]] +// CHECK: [[mainFnLexBlock:%[0-9]+]] = OpExtInst %void [[set]] DebugLexicalBlock [[source]] 32 1 [[main]] +// CHECK: [[ifLexBlock:%[0-9]+]] = OpExtInst %void [[set]] DebugLexicalBlock [[source]] 37 13 [[mainFnLexBlock]] +// CHECK: [[tempLexBlock:%[0-9]+]] = OpExtInst %void [[set]] DebugLexicalBlock [[source]] 40 5 [[ifLexBlock]] -// CHECK: {{%[0-9]+}} = OpExtInst %void [[set]] DebugLocalVariable [[varNameB]] [[uintType]] [[source]] 39 12 [[tempLexBlock]] FlagIsLocal +// CHECK: {{%[0-9]+}} = OpExtInst %void [[set]] DebugLocalVariable [[varNameB]] [[uintType]] [[source]] 41 12 [[tempLexBlock]] FlagIsLocal // CHECK: [[intType:%[0-9]+]] = OpExtInst %void [[set]] DebugTypeBasic {{%[0-9]+}} %uint_32 Signed -// CHECK: {{%[0-9]+}} = OpExtInst %void [[set]] DebugLocalVariable [[varNameA]] [[intType]] [[source]] 36 9 [[ifLexBlock]] FlagIsLocal +// CHECK: {{%[0-9]+}} = OpExtInst %void [[set]] DebugLocalVariable [[varNameA]] [[intType]] [[source]] 38 9 [[ifLexBlock]] FlagIsLocal // CHECK: [[boolType:%[0-9]+]] = OpExtInst %void [[set]] DebugTypeBasic {{%[0-9]+}} %uint_32 Boolean -// CHECK: {{%[0-9]+}} = OpExtInst %void [[set]] DebugLocalVariable [[varNameCond]] [[boolType]] [[source]] 32 8 [[mainFnLexBlock]] FlagIsLocal -// CHECK: {{%[0-9]+}} = OpExtInst %void [[set]] DebugLocalVariable [[varNameC]] [[float4Type]] [[source]] 31 10 [[mainFnLexBlock]] FlagIsLocal +// CHECK: {{%[0-9]+}} = OpExtInst %void [[set]] DebugLocalVariable [[varNameCond]] [[boolType]] [[source]] 34 8 [[mainFnLexBlock]] FlagIsLocal + +// CHECK: {{%[0-9]+}} = OpExtInst %void [[set]] DebugLocalVariable [[varNameC]] [[float4Type]] [[source]] 33 10 [[mainFnLexBlock]] FlagIsLocal + float4 main(float4 color : COLOR) : SV_TARGET { diff --git a/tools/clang/test/CodeGenSPIRV/shader.debug.function.hlsl b/tools/clang/test/CodeGenSPIRV/shader.debug.function.hlsl index e59e9bc807..b263fd88ad 100644 --- a/tools/clang/test/CodeGenSPIRV/shader.debug.function.hlsl +++ b/tools/clang/test/CodeGenSPIRV/shader.debug.function.hlsl @@ -5,8 +5,9 @@ // CHECK: [[set:%[0-9]+]] = OpExtInstImport "NonSemantic.Shader.DebugInfo.100" // CHECK: [[fooName:%[0-9]+]] = OpString "foo" // CHECK: [[emptyStr:%[0-9]+]] = OpString "" -// CHECK: [[mainName:%[0-9]+]] = OpString "main" -// CHECK: [[clOpts:%[0-9]+]] = OpString " -E main -T ps_6_0 -spirv -fcgl -fspv-debug=vulkan +// CHECK: [[srcMainName:%[0-9]+]] = OpString "main" +// CHECK: [[mainName:%[0-9]+]] = OpString "wrapper" +// CHECK: [[clOpts:%[0-9]+]] = OpString " -E main -T ps_6_0 -spirv -fcgl -fspv-debug=vulkan // CHECK: [[int:%[0-9]+]] = OpExtInst %void [[set]] DebugTypeBasic {{%[0-9]+}} %uint_32 %uint_4 %uint_0 // CHECK: [[float:%[0-9]+]] = OpExtInst %void [[set]] DebugTypeBasic {{%[0-9]+}} %uint_32 %uint_3 %uint_0 @@ -17,18 +18,24 @@ // Check DebugFunction instructions // -// CHECK: {{%[0-9]+}} = OpExtInst %void [[set]] DebugFunction [[fooName]] [[fooFnType]] [[source]] %uint_34 %uint_1 [[compilationUnit]] [[emptyStr]] %uint_3 %uint_35 - // CHECK: [[float4:%[0-9]+]] = OpExtInst %void [[set]] DebugTypeVector [[float]] %uint_4 -// CHECK: [[mainFnType:%[0-9]+]] = OpExtInst %void [[set]] DebugTypeFunction %uint_3 [[float4]] [[float4]] -// CHECK: [[mainDbgFn:%[0-9]+]] = OpExtInst %void [[set]] DebugFunction [[mainName]] [[mainFnType]] [[source]] %uint_39 %uint_1 [[compilationUnit]] [[emptyStr]] %uint_3 %uint_40 +// CHECK: [[srcMainFnType:%[0-9]+]] = OpExtInst %void [[set]] DebugTypeFunction %uint_3 [[float4]] [[float4]] +// CHECK: [[srcMainDbgFn:%[0-9]+]] = OpExtInst %void [[set]] DebugFunction [[srcMainName]] [[srcMainFnType]] [[source]] %uint_46 %uint_1 [[compilationUnit]] [[emptyStr]] %uint_3 %uint_47 +// CHECK: [[mainFnType:%[0-9]+]] = OpExtInst %void [[set]] DebugTypeFunction %uint_3 %void +// CHECK: [[mainDbgFn:%[0-9]+]] = OpExtInst %void [[set]] DebugFunction [[mainName]] [[mainFnType]] [[source]] %uint_46 %uint_1 [[compilationUnit]] [[emptyStr]] %uint_3 %uint_47 // CHECK: [[mainDbgEp:%[0-9]+]] = OpExtInst %void [[set]] DebugEntryPoint [[mainDbgFn]] [[compilationUnit]] {{%[0-9]+}} [[clOpts]] -// Check DebugFunctionDefintion is in src_main +// Check DebugFunctionDefinition is in main // -// CHECK: %src_main = OpFunction %v4float None {{%[0-9]+}} -// CHECK: {{%[0-9]+}} = OpExtInst %void [[set]] DebugFunctionDefinition [[mainDbgFn]] %src_main +// CHECK: %main = OpFunction %void None {{%[0-9]+}} +// CHECK: {{%[0-9]+}} = OpExtInst %void [[set]] DebugFunctionDefinition [[mainDbgFn]] %main // CHECK: OpFunctionEnd + +// Check DebugFunctionDefinition is in src.main +// +// CHECK: %src_main = OpFunction %v4float None {{%[0-9]+}} +// CHECK: {{%[0-9]+}} = OpExtInst %void [[set]] DebugScope [[srcMainDbgFn]] +// CHECK: {{%[0-9]+}} = OpExtInst %void [[set]] DebugFunctionDefinition [[srcMainDbgFn]] %src_main // CHECK: OpFunctionEnd void foo(int x, float y)