@@ -1442,48 +1442,34 @@ void SpirvEmitter::doFunctionDecl(const FunctionDecl *decl) {
14421442 // This will allow the entry-point name to be something like
14431443 // myNamespace::myEntrypointFunc.
14441444 std::string funcName = getFnName(decl);
1445- std::string debugFuncName = funcName;
1446-
1445+ std::string srcFuncName = "src." + funcName;
14471446 SpirvFunction *func = declIdMapper.getOrRegisterFn(decl);
1447+ SpirvFunction *srcFunc = nullptr;
14481448
14491449 auto loc = decl->getLocStart();
14501450 auto range = decl->getSourceRange();
14511451 RichDebugInfo *info = nullptr;
14521452 SpirvDebugFunction *debugFunction = nullptr;
1453+ SpirvDebugFunction *srcDebugFunction = nullptr;
14531454 SpirvDebugInstruction *outer_scope = spvContext.getCurrentLexicalScope();
1454- const auto &sm = astContext.getSourceManager();
1455- if (spirvOptions.debugInfoRich && decl->hasBody()) {
1456- const uint32_t line = sm.getPresumedLineNumber(loc);
1457- const uint32_t column = sm.getPresumedColumnNumber(loc);
1458- info = getOrCreateRichDebugInfo(loc);
1459-
1460- auto *source = info->source;
1461- // Note that info->scopeStack.back() is a lexical scope of the function
1462- // caller.
1463- auto *parentScope = info->compilationUnit;
1464- // TODO: figure out the proper flag based on the function decl.
1465- // using FlagIsPublic for now.
1466- uint32_t flags = 3u;
1467- // The line number in the source program at which the function scope begins.
1468- auto scopeLine = sm.getPresumedLineNumber(decl->getBody()->getLocStart());
1469- debugFunction = spvBuilder.createDebugFunction(decl, debugFuncName, source,
1470- line, column, parentScope,
1471- "", flags, scopeLine, func);
1472- func->setDebugScope(new (spvContext) SpirvDebugScope(debugFunction));
1473-
1474- spvContext.pushDebugLexicalScope(info, debugFunction);
1475- }
14761455
14771456 bool isEntry = false;
14781457 const auto iter = functionInfoMap.find(decl);
14791458 if (iter != functionInfoMap.end()) {
14801459 const auto &entryInfo = iter->second;
14811460 if (entryInfo->isEntryFunction) {
14821461 isEntry = true;
1483- funcName = "src." + funcName;
14841462 // Create wrapper for the entry function
1485- if (!emitEntryFunctionWrapper(decl, func))
1463+ srcFunc = func;
1464+
1465+ func = emitEntryFunctionWrapper(decl, &info, &debugFunction, srcFunc);
1466+ if (func == nullptr)
14861467 return;
1468+ if (spirvOptions.debugInfoRich && decl->hasBody()) {
1469+ // use the HLSL name the debug user will expect to see
1470+ srcDebugFunction = emitDebugFunction(decl, srcFunc, &info, funcName);
1471+ }
1472+
14871473 // Generate DebugEntryPoint if function definition
14881474 if (spirvOptions.debugInfoVulkan && debugFunction) {
14891475 auto *cu = dyn_cast<SpirvDebugCompilationUnit>(outer_scope);
@@ -1492,15 +1478,30 @@ void SpirvEmitter::doFunctionDecl(const FunctionDecl *decl) {
14921478 clang::getGitCommitHash(),
14931479 spirvOptions.clOptions);
14941480 }
1481+ } else {
1482+ if (spirvOptions.debugInfoRich && decl->hasBody()) {
1483+ debugFunction = emitDebugFunction(decl, func, &info, funcName);
1484+ }
14951485 }
14961486 }
14971487
1488+ if (spirvOptions.debugInfoRich) {
1489+ spvContext.pushDebugLexicalScope(info, debugFunction);
1490+ }
1491+
14981492 const QualType retType =
14991493 declIdMapper.getTypeAndCreateCounterForPotentialAliasVar(decl);
15001494
1501- spvBuilder.beginFunction(retType, decl->getLocStart(), funcName,
1502- decl->hasAttr<HLSLPreciseAttr>(),
1503- decl->hasAttr<NoInlineAttr>(), func);
1495+ if (srcFunc) {
1496+ spvBuilder.beginFunction(retType, decl->getLocStart(), srcFuncName,
1497+ decl->hasAttr<HLSLPreciseAttr>(),
1498+ decl->hasAttr<NoInlineAttr>(), srcFunc);
1499+
1500+ } else {
1501+ spvBuilder.beginFunction(retType, decl->getLocStart(), funcName,
1502+ decl->hasAttr<HLSLPreciseAttr>(),
1503+ decl->hasAttr<NoInlineAttr>(), func);
1504+ }
15041505
15051506 bool isNonStaticMemberFn = false;
15061507 if (const auto *memberFn = dyn_cast<CXXMethodDecl>(decl)) {
@@ -1551,7 +1552,9 @@ void SpirvEmitter::doFunctionDecl(const FunctionDecl *decl) {
15511552
15521553 // Add DebugFunctionDefinition if we are emitting
15531554 // NonSemantic.Shader.DebugInfo.100 debug info
1554- if (spirvOptions.debugInfoVulkan && debugFunction)
1555+ if (spirvOptions.debugInfoVulkan && srcDebugFunction)
1556+ spvBuilder.createDebugFunctionDef(srcDebugFunction, srcFunc);
1557+ else if (spirvOptions.debugInfoVulkan && debugFunction)
15551558 spvBuilder.createDebugFunctionDef(debugFunction, func);
15561559
15571560 // Process all statments in the body.
@@ -13331,11 +13334,17 @@ bool SpirvEmitter::processTessellationShaderAttributes(
1333113334}
1333213335
1333313336bool SpirvEmitter::emitEntryFunctionWrapperForRayTracing(
13334- const FunctionDecl *decl, SpirvFunction *entryFuncInstr) {
13337+ const FunctionDecl *decl, SpirvDebugFunction *debugFunction,
13338+ SpirvFunction *entryFuncInstr) {
1333513339 // The entry basic block.
1333613340 auto *entryLabel = spvBuilder.createBasicBlock();
1333713341 spvBuilder.setInsertPoint(entryLabel);
1333813342
13343+ // Add DebugFunctionDefinition if we are emitting
13344+ // NonSemantic.Shader.DebugInfo.100 debug info.
13345+ if (spirvOptions.debugInfoVulkan && debugFunction)
13346+ spvBuilder.createDebugFunctionDef(debugFunction, entryFunction);
13347+
1333913348 // Initialize all global variables at the beginning of the wrapper
1334013349 for (const VarDecl *varDecl : toInitGloalVars) {
1334113350 const auto varInfo =
@@ -13598,8 +13607,36 @@ bool SpirvEmitter::processMeshOrAmplificationShaderAttributes(
1359813607 return true;
1359913608}
1360013609
13601- bool SpirvEmitter::emitEntryFunctionWrapper(const FunctionDecl *decl,
13602- SpirvFunction *entryFuncInstr) {
13610+ SpirvDebugFunction *SpirvEmitter::emitDebugFunction(const FunctionDecl *decl,
13611+ SpirvFunction *func,
13612+ RichDebugInfo **info,
13613+ std::string name) {
13614+ auto loc = decl->getLocStart();
13615+ const auto &sm = astContext.getSourceManager();
13616+ const uint32_t line = sm.getPresumedLineNumber(loc);
13617+ const uint32_t column = sm.getPresumedColumnNumber(loc);
13618+ *info = getOrCreateRichDebugInfo(loc);
13619+
13620+ SpirvDebugSource *source = (*info)->source;
13621+ // Note that info->scopeStack.back() is a lexical scope of the function
13622+ // caller.
13623+ SpirvDebugInstruction *parentScope = (*info)->compilationUnit;
13624+ // TODO: figure out the proper flag based on the function decl.
13625+ // using FlagIsPublic for now.
13626+ uint32_t flags = 3u;
13627+ // The line number in the source program at which the function scope begins.
13628+ auto scopeLine = sm.getPresumedLineNumber(decl->getBody()->getLocStart());
13629+ SpirvDebugFunction *debugFunction =
13630+ spvBuilder.createDebugFunction(decl, name, source, line, column,
13631+ parentScope, "", flags, scopeLine, func);
13632+ func->setDebugScope(new (spvContext) SpirvDebugScope(debugFunction));
13633+
13634+ return debugFunction;
13635+ }
13636+
13637+ SpirvFunction *SpirvEmitter::emitEntryFunctionWrapper(
13638+ const FunctionDecl *decl, RichDebugInfo **info,
13639+ SpirvDebugFunction **debugFunction, SpirvFunction *entryFuncInstr) {
1360313640 // HS specific attributes
1360413641 uint32_t numOutputControlPoints = 0;
1360513642 SpirvInstruction *outputControlPointIdVal =
@@ -13620,6 +13657,10 @@ bool SpirvEmitter::emitEntryFunctionWrapper(const FunctionDecl *decl,
1362013657 entryFunction = spvBuilder.beginFunction(
1362113658 astContext.VoidTy, decl->getLocStart(), decl->getName());
1362213659
13660+ if (spirvOptions.debugInfoRich && decl->hasBody()) {
13661+ *debugFunction = emitDebugFunction(decl, entryFunction, info, "wrapper");
13662+ }
13663+
1362313664 // Specify that entryFunction is an entry function wrapper.
1362413665 entryFunction->setEntryFunctionWrapper();
1362513666
@@ -13634,7 +13675,10 @@ bool SpirvEmitter::emitEntryFunctionWrapper(const FunctionDecl *decl,
1363413675 entryInfo->entryFunction = entryFunction;
1363513676
1363613677 if (spvContext.isRay()) {
13637- return emitEntryFunctionWrapperForRayTracing(decl, entryFuncInstr);
13678+ return emitEntryFunctionWrapperForRayTracing(decl, *debugFunction,
13679+ entryFuncInstr)
13680+ ? entryFunction
13681+ : nullptr;
1363813682 }
1363913683 // Handle attributes specific to each shader stage
1364013684 if (spvContext.isPS()) {
@@ -13643,7 +13687,7 @@ bool SpirvEmitter::emitEntryFunctionWrapper(const FunctionDecl *decl,
1364313687 processComputeShaderAttributes(decl);
1364413688 } else if (spvContext.isHS()) {
1364513689 if (!processTessellationShaderAttributes(decl, &numOutputControlPoints))
13646- return false ;
13690+ return nullptr ;
1364713691
1364813692 // The input array size for HS is specified in the InputPatch parameter.
1364913693 for (const auto *param : decl->params())
@@ -13655,7 +13699,7 @@ bool SpirvEmitter::emitEntryFunctionWrapper(const FunctionDecl *decl,
1365513699 outputArraySize = numOutputControlPoints;
1365613700 } else if (spvContext.isDS()) {
1365713701 if (!processTessellationShaderAttributes(decl, &numOutputControlPoints))
13658- return false ;
13702+ return nullptr ;
1365913703
1366013704 // The input array size for HS is specified in the OutputPatch parameter.
1366113705 for (const auto *param : decl->params())
@@ -13666,11 +13710,11 @@ bool SpirvEmitter::emitEntryFunctionWrapper(const FunctionDecl *decl,
1366613710 // The per-vertex output of DS is not an array.
1366713711 } else if (spvContext.isGS()) {
1366813712 if (!processGeometryShaderAttributes(decl, &inputArraySize))
13669- return false ;
13713+ return nullptr ;
1367013714 // The per-vertex output of GS is not an array.
1367113715 } else if (spvContext.isMS() || spvContext.isAS()) {
1367213716 if (!processMeshOrAmplificationShaderAttributes(decl, &outputArraySize))
13673- return false ;
13717+ return nullptr ;
1367413718 }
1367513719
1367613720 // Go through all parameters and record the declaration of SV_ClipDistance
@@ -13686,14 +13730,14 @@ bool SpirvEmitter::emitEntryFunctionWrapper(const FunctionDecl *decl,
1368613730 for (const auto *param : decl->params()) {
1368713731 if (canActAsInParmVar(param))
1368813732 if (!declIdMapper.glPerVertex.recordGlPerVertexDeclFacts(param, true))
13689- return false ;
13733+ return nullptr ;
1369013734 if (canActAsOutParmVar(param))
1369113735 if (!declIdMapper.glPerVertex.recordGlPerVertexDeclFacts(param, false))
13692- return false ;
13736+ return nullptr ;
1369313737 }
1369413738 // Also consider the SV_ClipDistance/SV_CullDistance in the return type
1369513739 if (!declIdMapper.glPerVertex.recordGlPerVertexDeclFacts(decl, false))
13696- return false ;
13740+ return nullptr ;
1369713741
1369813742 // Calculate the total size of the ClipDistance/CullDistance array and the
1369913743 // offset of SV_ClipDistance/SV_CullDistance variables within the array.
@@ -13715,6 +13759,11 @@ bool SpirvEmitter::emitEntryFunctionWrapper(const FunctionDecl *decl,
1371513759 // after the basic block is created and insert point is set.
1371613760 processInlineSpirvAttributes(decl);
1371713761
13762+ // Add DebugFunctionDefinition if we are emitting
13763+ // NonSemantic.Shader.DebugInfo.100 debug info.
13764+ if (spirvOptions.debugInfoVulkan && *debugFunction)
13765+ spvBuilder.createDebugFunctionDef(*debugFunction, entryFunction);
13766+
1371813767 // Initialize all global variables at the beginning of the wrapper
1371913768 for (const VarDecl *varDecl : toInitGloalVars) {
1372013769 // SPIR-V does not have string variables
@@ -13766,7 +13815,7 @@ bool SpirvEmitter::emitEntryFunctionWrapper(const FunctionDecl *decl,
1376613815 SpirvInstruction *loadedValue = nullptr;
1376713816
1376813817 if (!declIdMapper.createStageInputVar(param, &loadedValue, false))
13769- return false ;
13818+ return nullptr ;
1377013819
1377113820 // Only initialize the temporary variable if the parameter is indeed used,
1377213821 // or if it is an inout parameter.
@@ -13805,15 +13854,15 @@ bool SpirvEmitter::emitEntryFunctionWrapper(const FunctionDecl *decl,
1380513854 // Create stage output variables out of the return type.
1380613855 if (!declIdMapper.createStageOutputVar(decl, numOutputControlPoints,
1380713856 outputControlPointIdVal, retVal))
13808- return false ;
13857+ return nullptr ;
1380913858 if (!processHSEntryPointOutputAndPCF(
1381013859 decl, retType, retVal, numOutputControlPoints,
1381113860 outputControlPointIdVal, primitiveIdVar, viewIdVar,
1381213861 hullMainInputPatchParam))
13813- return false ;
13862+ return nullptr ;
1381413863 } else {
1381513864 if (!declIdMapper.createStageOutputVar(decl, retVal, /*forPCF*/ false))
13816- return false ;
13865+ return nullptr ;
1381713866 }
1381813867
1381913868 // Create and write stage output variables for parameters marked as
@@ -13836,7 +13885,7 @@ bool SpirvEmitter::emitEntryFunctionWrapper(const FunctionDecl *decl,
1383613885 param->getLocStart());
1383713886
1383813887 if (!declIdMapper.createStageOutputVar(param, loadedParam, false))
13839- return false ;
13888+ return nullptr ;
1384013889 }
1384113890 }
1384213891
@@ -13851,7 +13900,7 @@ bool SpirvEmitter::emitEntryFunctionWrapper(const FunctionDecl *decl,
1385113900 if (spvContext.isHS())
1385213901 doDecl(patchConstFunc);
1385313902
13854- return true ;
13903+ return entryFunction ;
1385513904}
1385613905
1385713906bool SpirvEmitter::processHSEntryPointOutputAndPCF(
0 commit comments