SpirvShaderDebugger: Have Function inherit LexicalBlock

`debug::LocalVariable` expects the parent scope to contain a `debug::LexicalScope`. If it doesn't, then the variable is never registered, and doesn't show up in the watch windows.

DXC emits `DebugLocalVariable`s for parameters, with the parent scope set to the immediate function, with no lexical block.

To make parameters show up, make `debug::Function` inherit from `debug::LexicalBlock`. This makes all the existing logic that uses `debug::find<debug::LexicalBlock>()` work for both `DebugLexicalBlock` and `DebugFunction` scope types.

Fixes: b/170320768
Change-Id: I296353eae9bb7f04bc649174b9f33a29d1dcc6e7
Reviewed-on: https://swiftshader-review.googlesource.com/c/SwiftShader/+/49088
Kokoro-Result: kokoro <noreply+kokoro@google.com>
Reviewed-by: Nicolas Capens <nicolascapens@google.com>
Tested-by: Ben Clayton <bclayton@google.com>
diff --git a/src/Pipeline/SpirvShaderDebugger.cpp b/src/Pipeline/SpirvShaderDebugger.cpp
index 4aa1059..12588f9 100644
--- a/src/Pipeline/SpirvShaderDebugger.cpp
+++ b/src/Pipeline/SpirvShaderDebugger.cpp
@@ -734,29 +734,37 @@
 	}
 };
 
-// Function represents the OpenCL.DebugInfo.100 DebugFunction instruction.
-// https://www.khronos.org/registry/spir-v/specs/unified1/OpenCL.DebugInfo.100.html#DebugFunction
-struct Function : ObjectImpl<Function, Scope, Object::Kind::Function>
-{
-	std::string name;
-	FunctionType *type = nullptr;
-	uint32_t line = 0;
-	uint32_t column = 0;
-	std::string linkage;
-	uint32_t flags = 0;  // OR'd from OpenCLDebugInfo100DebugInfoFlags
-	uint32_t scopeLine = 0;
-	sw::SpirvShader::Function::ID function;
-};
-
 // LexicalBlock represents the OpenCL.DebugInfo.100 DebugLexicalBlock instruction.
 // https://www.khronos.org/registry/spir-v/specs/unified1/OpenCL.DebugInfo.100.html#DebugLexicalBlock
-struct LexicalBlock : ObjectImpl<LexicalBlock, Scope, Object::Kind::LexicalBlock>
+struct LexicalBlock : Scope
 {
+	using ID = sw::SpirvID<LexicalBlock>;
+	static constexpr auto Kind = Object::Kind::LexicalBlock;
+
+	inline LexicalBlock(Object::Kind kind = Kind)
+	    : Scope(kind)
+	{}
+
 	uint32_t line = 0;
 	uint32_t column = 0;
 	std::string name;
 
 	std::vector<LocalVariable *> variables;
+
+	static constexpr bool kindof(Object::Kind kind) { return kind == Kind || kind == Object::Kind::Function; }
+};
+
+// Function represents the OpenCL.DebugInfo.100 DebugFunction instruction.
+// https://www.khronos.org/registry/spir-v/specs/unified1/OpenCL.DebugInfo.100.html#DebugFunction
+struct Function : ObjectImpl<Function, LexicalBlock, Object::Kind::Function>
+{
+	std::string name;
+	FunctionType *type = nullptr;
+	uint32_t declLine = 0;
+	uint32_t declColumn = 0;
+	std::string linkage;
+	uint32_t flags = 0;  // OR'd from OpenCLDebugInfo100DebugInfoFlags
+	sw::SpirvShader::Function::ID function;
 };
 
 // InlinedAt represents the OpenCL.DebugInfo.100 DebugInlinedAt instruction.
@@ -1657,12 +1665,12 @@
 				func->name = shader->getString(insn.word(5));
 				func->type = get(debug::FunctionType::ID(insn.word(6)));
 				func->source = get(debug::Source::ID(insn.word(7)));
-				func->line = insn.word(8);
-				func->column = insn.word(9);
+				func->declLine = insn.word(8);
+				func->declColumn = insn.word(9);
 				func->parent = get(debug::Scope::ID(insn.word(10)));
 				func->linkage = shader->getString(insn.word(11));
 				func->flags = insn.word(12);
-				func->scopeLine = insn.word(13);
+				func->line = insn.word(13);
 				func->function = Function::ID(insn.word(14));
 				// declaration: word(13)
 			});