|
@@ -202,7 +202,8 @@ void EmitVisitor::emitDebugNameForInstruction(uint32_t resultId,
|
|
|
}
|
|
|
|
|
|
void EmitVisitor::emitDebugLine(spv::Op op, const SourceLocation &loc,
|
|
|
- std::vector<uint32_t> *section) {
|
|
|
+ std::vector<uint32_t> *section,
|
|
|
+ bool isDebugScope) {
|
|
|
if (!spvOptions.debugInfoLine)
|
|
|
return;
|
|
|
|
|
@@ -217,6 +218,8 @@ void EmitVisitor::emitDebugLine(spv::Op op, const SourceLocation &loc,
|
|
|
// immediately precede either an OpBranch or OpBranchConditional instruction.
|
|
|
if (lastOpWasMergeInst) {
|
|
|
lastOpWasMergeInst = false;
|
|
|
+ debugLine = 0;
|
|
|
+ debugColumn = 0;
|
|
|
return;
|
|
|
}
|
|
|
|
|
@@ -233,29 +236,53 @@ void EmitVisitor::emitDebugLine(spv::Op op, const SourceLocation &loc,
|
|
|
if (op == spv::Op::OpVariable)
|
|
|
return;
|
|
|
|
|
|
+ // If no SourceLocation is provided, we have to emit OpNoLine to
|
|
|
+ // specify the previous OpLine is not applied to this instruction.
|
|
|
+ if (loc == SourceLocation()) {
|
|
|
+ if (!isDebugScope && (debugLine != 0 || debugColumn != 0)) {
|
|
|
+ curInst.clear();
|
|
|
+ curInst.push_back(static_cast<uint32_t>(spv::Op::OpNoLine));
|
|
|
+ curInst[0] |= static_cast<uint32_t>(curInst.size()) << 16;
|
|
|
+ section->insert(section->end(), curInst.begin(), curInst.end());
|
|
|
+ }
|
|
|
+ debugLine = 0;
|
|
|
+ debugColumn = 0;
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
auto fileId = debugMainFileId;
|
|
|
const auto &sm = astContext.getSourceManager();
|
|
|
const char *fileName = sm.getPresumedLoc(loc).getFilename();
|
|
|
if (fileName)
|
|
|
fileId = getOrCreateOpStringId(fileName);
|
|
|
|
|
|
- if (!fileId)
|
|
|
- return;
|
|
|
-
|
|
|
uint32_t line = sm.getPresumedLineNumber(loc);
|
|
|
uint32_t column = sm.getPresumedColumnNumber(loc);
|
|
|
|
|
|
- if (!line || !column)
|
|
|
- return;
|
|
|
+ // If it is a terminator, just reset the last line and column because
|
|
|
+ // a terminator makes the OpLine not effective.
|
|
|
+ bool resetLine = (op >= spv::Op::OpBranch && op <= spv::Op::OpUnreachable) ||
|
|
|
+ op == spv::Op::OpTerminateInvocation;
|
|
|
|
|
|
- if (line == debugLine && column == debugColumn)
|
|
|
+ if (!fileId || !line || !column ||
|
|
|
+ (line == debugLine && column == debugColumn)) {
|
|
|
+ if (resetLine) {
|
|
|
+ debugLine = 0;
|
|
|
+ debugColumn = 0;
|
|
|
+ }
|
|
|
return;
|
|
|
+ }
|
|
|
|
|
|
assert(section);
|
|
|
|
|
|
- // We must update these two values to emit the next Opline.
|
|
|
- debugLine = line;
|
|
|
- debugColumn = column;
|
|
|
+ if (resetLine) {
|
|
|
+ debugLine = 0;
|
|
|
+ debugColumn = 0;
|
|
|
+ } else {
|
|
|
+ // Keep the last line and column to avoid printing the duplicated OpLine.
|
|
|
+ debugLine = line;
|
|
|
+ debugColumn = column;
|
|
|
+ }
|
|
|
|
|
|
curInst.clear();
|
|
|
curInst.push_back(static_cast<uint32_t>(spv::Op::OpLine));
|
|
@@ -312,7 +339,8 @@ void EmitVisitor::initInstruction(SpirvInstruction *inst) {
|
|
|
isGlobalVar = var->getStorageClass() != spv::StorageClass::Function;
|
|
|
const auto op = inst->getopcode();
|
|
|
emitDebugLine(op, inst->getSourceLocation(),
|
|
|
- isGlobalVar ? &globalVarsBinary : &mainBinary);
|
|
|
+ isGlobalVar ? &globalVarsBinary : &mainBinary,
|
|
|
+ isa<SpirvDebugScope>(inst));
|
|
|
|
|
|
// Initialize the current instruction for emitting.
|
|
|
curInst.clear();
|