// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
// MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
-#include <assert.h>
-
+#include <cassert>
#include <iostream>
#include <unordered_map>
#include <vector>
action; \
}
+using UseDefTracker = libspirv::ValidationState_t::UseDefTracker;
+
namespace {
+
class idUsage {
public:
idUsage(const spv_opcode_table opcodeTableArg,
const spv_operand_table operandTableArg,
- const spv_ext_inst_table extInstTableArg, const spv_id_info_t* pIdUses,
- const uint64_t idUsesCount, const spv_id_info_t* pIdDefs,
- const uint64_t idDefsCount, const spv_instruction_t* pInsts,
- const uint64_t instCountArg, spv_position positionArg,
+ const spv_ext_inst_table extInstTableArg,
+ const spv_instruction_t* pInsts, const uint64_t instCountArg,
+ const UseDefTracker& usedefs,
+ const std::vector<uint32_t>& entry_points, spv_position positionArg,
spv_diagnostic* pDiagnosticArg)
: opcodeTable(opcodeTableArg),
operandTable(operandTableArg),
firstInst(pInsts),
instCount(instCountArg),
position(positionArg),
- pDiagnostic(pDiagnosticArg) {
- for (uint64_t idUsesIndex = 0; idUsesIndex < idUsesCount; ++idUsesIndex) {
- idUses[pIdUses[idUsesIndex].id].push_back(pIdUses[idUsesIndex]);
- }
- for (uint64_t idDefsIndex = 0; idDefsIndex < idDefsCount; ++idDefsIndex) {
- idDefs[pIdDefs[idDefsIndex].id] = pIdDefs[idDefsIndex];
- }
- }
+ pDiagnostic(pDiagnosticArg),
+ usedefs_(usedefs),
+ entry_points_(entry_points) {}
bool isValid(const spv_instruction_t* inst);
template <SpvOp>
bool isValid(const spv_instruction_t* inst, const spv_opcode_desc);
- std::unordered_map<uint32_t, spv_id_info_t>::iterator find(
- const uint32_t& id) {
- return idDefs.find(id);
- }
- std::unordered_map<uint32_t, spv_id_info_t>::const_iterator find(
- const uint32_t& id) const {
- return idDefs.find(id);
- }
-
- bool found(std::unordered_map<uint32_t, spv_id_info_t>::iterator item) {
- return idDefs.end() != item;
- }
- bool found(std::unordered_map<uint32_t, spv_id_info_t>::const_iterator item) {
- return idDefs.end() != item;
- }
-
- std::unordered_map<uint32_t, std::vector<spv_id_info_t>>::iterator findUses(
- const uint32_t& id) {
- return idUses.find(id);
- }
- std::unordered_map<uint32_t, std::vector<spv_id_info_t>>::const_iterator
- findUses(const uint32_t& id) const {
- return idUses.find(id);
- }
-
- bool foundUses(
- std::unordered_map<uint32_t, std::vector<spv_id_info_t>>::iterator item) {
- return idUses.end() != item;
- }
- bool foundUses(std::unordered_map<
- uint32_t, std::vector<spv_id_info_t>>::const_iterator item) {
- return idUses.end() != item;
- }
-
private:
const spv_opcode_table opcodeTable;
const spv_operand_table operandTable;
const uint64_t instCount;
spv_position position;
spv_diagnostic* pDiagnostic;
- std::unordered_map<uint32_t, std::vector<spv_id_info_t>> idUses;
- std::unordered_map<uint32_t, spv_id_info_t> idDefs;
+ UseDefTracker usedefs_;
+ std::vector<uint32_t> entry_points_;
};
#define DIAG(INDEX) \
assert(0 && "Unimplemented!");
return false;
}
-#endif
-
-template <>
-bool idUsage::isValid<SpvOpName>(const spv_instruction_t* inst,
- const spv_opcode_desc) {
- auto targetIndex = 1;
- auto target = find(inst->words[targetIndex]);
- spvCheck(!found(target), DIAG(targetIndex) << "OpName Target <id> '"
- << inst->words[targetIndex]
- << "' is not defined.";
- return false);
- return true;
-}
+#endif // 0
template <>
bool idUsage::isValid<SpvOpMemberName>(const spv_instruction_t* inst,
const spv_opcode_desc) {
auto typeIndex = 1;
- auto type = find(inst->words[typeIndex]);
- spvCheck(!found(type), DIAG(typeIndex) << "OpMemberName Type <id> '"
- << inst->words[typeIndex]
- << "' is not defined.";
- return false);
- spvCheck(SpvOpTypeStruct != type->second.opcode,
- DIAG(typeIndex) << "OpMemberName Type <id> '"
- << inst->words[typeIndex]
- << "' is not a struct type.";
- return false);
+ auto type = usedefs_.FindDef(inst->words[typeIndex]);
+ if (!type.first || SpvOpTypeStruct != type.second.opcode) {
+ DIAG(typeIndex) << "OpMemberName Type <id> '" << inst->words[typeIndex]
+ << "' is not a struct type.";
+ return false;
+ }
auto memberIndex = 2;
auto member = inst->words[memberIndex];
- auto memberCount = (uint32_t)(type->second.inst->words.size() - 2);
+ auto memberCount = (uint32_t)(type.second.words.size() - 2);
spvCheck(memberCount <= member, DIAG(memberIndex)
<< "OpMemberName Member <id> '"
<< inst->words[memberIndex]
<< "' index is larger than Type <id> '"
- << type->second.id << "'s member count.";
+ << type.second.id << "'s member count.";
return false);
return true;
}
bool idUsage::isValid<SpvOpLine>(const spv_instruction_t* inst,
const spv_opcode_desc) {
auto fileIndex = 1;
- auto file = find(inst->words[fileIndex]);
- spvCheck(!found(file), DIAG(fileIndex) << "OpLine Target <id> '"
- << inst->words[fileIndex]
- << "' is not defined.";
- return false);
- spvCheck(SpvOpString != file->second.opcode,
- DIAG(fileIndex) << "OpLine Target <id> '" << inst->words[fileIndex]
- << "' is not an OpString.";
- return false);
- return true;
-}
-
-template <>
-bool idUsage::isValid<SpvOpDecorate>(const spv_instruction_t* inst,
- const spv_opcode_desc) {
- auto targetIndex = 1;
- auto target = find(inst->words[targetIndex]);
- spvCheck(!found(target), DIAG(targetIndex) << "OpDecorate Target <id> '"
- << inst->words[targetIndex]
- << "' is not defined.";
- return false);
+ auto file = usedefs_.FindDef(inst->words[fileIndex]);
+ if (!file.first || SpvOpString != file.second.opcode) {
+ DIAG(fileIndex) << "OpLine Target <id> '" << inst->words[fileIndex]
+ << "' is not an OpString.";
+ return false;
+ }
return true;
}
bool idUsage::isValid<SpvOpMemberDecorate>(const spv_instruction_t* inst,
const spv_opcode_desc) {
auto structTypeIndex = 1;
- auto structType = find(inst->words[structTypeIndex]);
- spvCheck(!found(structType), DIAG(structTypeIndex)
- << "OpMemberDecorate Structure type <id> '"
- << inst->words[structTypeIndex]
- << "' is not defined.";
- return false);
- spvCheck(SpvOpTypeStruct != structType->second.inst->opcode,
- DIAG(structTypeIndex) << "OpMemberDecorate Structure type <id> '"
- << inst->words[structTypeIndex]
- << "' is not a struct type.";
- return false);
+ auto structType = usedefs_.FindDef(inst->words[structTypeIndex]);
+ if (!structType.first || SpvOpTypeStruct != structType.second.opcode) {
+ DIAG(structTypeIndex) << "OpMemberDecorate Structure type <id> '"
+ << inst->words[structTypeIndex]
+ << "' is not a struct type.";
+ return false;
+ }
auto memberIndex = 2;
auto member = inst->words[memberIndex];
- auto memberCount = (uint32_t)(structType->second.inst->words.size() - 2);
+ auto memberCount = static_cast<uint32_t>(structType.second.words.size() - 2);
spvCheck(memberCount < member, DIAG(memberIndex)
<< "OpMemberDecorate Structure type <id> '"
<< inst->words[memberIndex]
bool idUsage::isValid<SpvOpGroupDecorate>(const spv_instruction_t* inst,
const spv_opcode_desc) {
auto decorationGroupIndex = 1;
- auto decorationGroup = find(inst->words[decorationGroupIndex]);
- spvCheck(!found(decorationGroup),
- DIAG(decorationGroupIndex)
- << "OpGroupDecorate Decoration group <id> '"
- << inst->words[decorationGroupIndex] << "' is not defined.";
- return false);
- spvCheck(SpvOpDecorationGroup != decorationGroup->second.opcode,
- DIAG(decorationGroupIndex)
- << "OpGroupDecorate Decoration group <id> '"
- << inst->words[decorationGroupIndex]
- << "' is not a decoration group.";
- return false);
- for (size_t targetIndex = 2; targetIndex < inst->words.size();
- ++targetIndex) {
- auto target = find(inst->words[targetIndex]);
- spvCheck(!found(target), DIAG(targetIndex)
- << "OpGroupDecorate Target <id> '"
- << inst->words[targetIndex]
- << "' is not defined.";
- return false);
+ auto decorationGroup = usedefs_.FindDef(inst->words[decorationGroupIndex]);
+ if (!decorationGroup.first ||
+ SpvOpDecorationGroup != decorationGroup.second.opcode) {
+ DIAG(decorationGroupIndex) << "OpGroupDecorate Decoration group <id> '"
+ << inst->words[decorationGroupIndex]
+ << "' is not a decoration group.";
+ return false;
}
return true;
}
template <>
bool idUsage::isValid<SpvOpGroupMemberDecorate>(
const spv_instruction_t *inst, const spv_opcode_desc opcodeEntry) {}
-#endif
+#endif // 0
#if 0
template <>
bool idUsage::isValid<SpvOpExtInst>(const spv_instruction_t *inst,
const spv_opcode_desc opcodeEntry) {}
-#endif
+#endif // 0
template <>
bool idUsage::isValid<SpvOpEntryPoint>(const spv_instruction_t* inst,
const spv_opcode_desc) {
auto entryPointIndex = 2;
- auto entryPoint = find(inst->words[entryPointIndex]);
- spvCheck(!found(entryPoint), DIAG(entryPointIndex)
- << "OpEntryPoint Entry Point <id> '"
- << inst->words[entryPointIndex]
- << "' is not defined.";
- return false);
- spvCheck(SpvOpFunction != entryPoint->second.opcode,
- DIAG(entryPointIndex) << "OpEntryPoint Entry Point <id> '"
- << inst->words[entryPointIndex]
- << "' is not a function.";
- return false);
+ auto entryPoint = usedefs_.FindDef(inst->words[entryPointIndex]);
+ if (!entryPoint.first || SpvOpFunction != entryPoint.second.opcode) {
+ DIAG(entryPointIndex) << "OpEntryPoint Entry Point <id> '"
+ << inst->words[entryPointIndex]
+ << "' is not a function.";
+ return false;
+ }
// TODO: Check the entry point signature is void main(void), may be subject
// to change
- auto entryPointType = find(entryPoint->second.inst->words[4]);
- spvCheck(!found(entryPointType), assert(0 && "Unreachable!"));
- spvCheck(3 != entryPointType->second.inst->words.size(),
- DIAG(entryPointIndex) << "OpEntryPoint Entry Point <id> '"
- << inst->words[entryPointIndex]
- << "'s function parameter count is not zero.";
- return false);
- auto returnType = find(entryPoint->second.inst->words[1]);
- spvCheck(!found(returnType), assert(0 && "Unreachable!"));
- spvCheck(SpvOpTypeVoid != returnType->second.opcode,
- DIAG(entryPointIndex) << "OpEntryPoint Entry Point <id> '"
- << inst->words[entryPointIndex]
- << "'s function return type is not void.";
- return false);
+ auto entryPointType = usedefs_.FindDef(entryPoint.second.words[4]);
+ if (!entryPointType.first || 3 != entryPointType.second.words.size()) {
+ DIAG(entryPointIndex) << "OpEntryPoint Entry Point <id> '"
+ << inst->words[entryPointIndex]
+ << "'s function parameter count is not zero.";
+ return false;
+ }
+ auto returnType = usedefs_.FindDef(entryPoint.second.words[1]);
+ if (!returnType.first || SpvOpTypeVoid != returnType.second.opcode) {
+ DIAG(entryPointIndex) << "OpEntryPoint Entry Point <id> '"
+ << inst->words[entryPointIndex]
+ << "'s function return type is not void.";
+ return false;
+ }
return true;
}
bool idUsage::isValid<SpvOpExecutionMode>(const spv_instruction_t* inst,
const spv_opcode_desc) {
auto entryPointIndex = 1;
- auto entryPoint = find(inst->words[entryPointIndex]);
- spvCheck(!found(entryPoint), DIAG(entryPointIndex)
- << "OpExecutionMode Entry Point <id> '"
- << inst->words[entryPointIndex]
- << "' is not defined.";
- return false);
- auto entryPointUses = findUses(inst->words[entryPointIndex]);
- spvCheck(!foundUses(entryPointUses), assert(0 && "Unreachable!"));
- bool foundEntryPointUse = false;
- for (auto use : entryPointUses->second) {
- if (SpvOpEntryPoint == use.opcode) {
- foundEntryPointUse = true;
- }
+ auto entryPointID = inst->words[entryPointIndex];
+ auto found =
+ std::find(entry_points_.cbegin(), entry_points_.cend(), entryPointID);
+ if (found == entry_points_.cend()) {
+ DIAG(entryPointIndex) << "OpExecutionMode Entry Point <id> '"
+ << inst->words[entryPointIndex]
+ << "' is not the Entry Point "
+ "operand of an OpEntryPoint.";
+ return false;
}
- spvCheck(!foundEntryPointUse, DIAG(entryPointIndex)
- << "OpExecutionMode Entry Point <id> '"
- << inst->words[entryPointIndex]
- << "' is not the Entry Point "
- "operand of an OpEntryPoint.";
- return false);
return true;
}
bool idUsage::isValid<SpvOpTypeVector>(const spv_instruction_t* inst,
const spv_opcode_desc) {
auto componentIndex = 2;
- auto componentType = find(inst->words[componentIndex]);
- spvCheck(!found(componentType), DIAG(componentIndex)
- << "OpTypeVector Component Type <id> '"
- << inst->words[componentIndex]
- << "' is not defined.";
- return false);
- spvCheck(!spvOpcodeIsScalarType(componentType->second.opcode),
- DIAG(componentIndex) << "OpTypeVector Component Type <id> '"
- << inst->words[componentIndex]
- << "' is not a scalar type.";
- return false);
+ auto componentType = usedefs_.FindDef(inst->words[componentIndex]);
+ if (!componentType.first ||
+ !spvOpcodeIsScalarType(componentType.second.opcode)) {
+ DIAG(componentIndex) << "OpTypeVector Component Type <id> '"
+ << inst->words[componentIndex]
+ << "' is not a scalar type.";
+ return false;
+ }
return true;
}
bool idUsage::isValid<SpvOpTypeMatrix>(const spv_instruction_t* inst,
const spv_opcode_desc) {
auto columnTypeIndex = 2;
- auto columnType = find(inst->words[columnTypeIndex]);
- spvCheck(!found(columnType), DIAG(columnTypeIndex)
- << "OpTypeMatrix Column Type <id> '"
- << inst->words[columnTypeIndex]
- << "' is not defined.";
- return false);
- spvCheck(SpvOpTypeVector != columnType->second.opcode,
- DIAG(columnTypeIndex) << "OpTypeMatrix Column Type <id> '"
- << inst->words[columnTypeIndex]
- << "' is not a vector.";
- return false);
+ auto columnType = usedefs_.FindDef(inst->words[columnTypeIndex]);
+ if (!columnType.first || SpvOpTypeVector != columnType.second.opcode) {
+ DIAG(columnTypeIndex) << "OpTypeMatrix Column Type <id> '"
+ << inst->words[columnTypeIndex]
+ << "' is not a vector.";
+ return false;
+ }
return true;
}
bool idUsage::isValid<SpvOpTypeArray>(const spv_instruction_t* inst,
const spv_opcode_desc) {
auto elementTypeIndex = 2;
- auto elementType = find(inst->words[elementTypeIndex]);
- spvCheck(!found(elementType), DIAG(elementTypeIndex)
- << "OpTypeArray Element Type <id> '"
- << inst->words[elementTypeIndex]
- << "' is not defined.";
- return false);
- spvCheck(!spvOpcodeGeneratesType(elementType->second.opcode),
- DIAG(elementTypeIndex) << "OpTypeArray Element Type <id> '"
- << inst->words[elementTypeIndex]
- << "' is not a type.";
- return false);
+ auto elementType = usedefs_.FindDef(inst->words[elementTypeIndex]);
+ if (!elementType.first ||
+ !spvOpcodeGeneratesType(elementType.second.opcode)) {
+ DIAG(elementTypeIndex) << "OpTypeArray Element Type <id> '"
+ << inst->words[elementTypeIndex]
+ << "' is not a type.";
+ return false;
+ }
auto lengthIndex = 3;
- auto length = find(inst->words[lengthIndex]);
- spvCheck(!found(length), DIAG(lengthIndex) << "OpTypeArray Length <id> '"
- << inst->words[lengthIndex]
- << "' is not defined.";
- return false);
- spvCheck(SpvOpConstant != length->second.opcode &&
- SpvOpSpecConstant != length->second.opcode,
- DIAG(lengthIndex) << "OpTypeArray Length <id> '"
- << inst->words[lengthIndex]
- << "' is not a scalar constant type.";
- return false);
+ auto length = usedefs_.FindDef(inst->words[lengthIndex]);
+ if (!length.first || (SpvOpConstant != length.second.opcode &&
+ SpvOpSpecConstant != length.second.opcode)) {
+ DIAG(lengthIndex) << "OpTypeArray Length <id> '" << inst->words[lengthIndex]
+ << "' is not a scalar constant type.";
+ return false;
+ }
// NOTE: Check the initialiser value of the constant
- auto constInst = length->second.inst;
+ auto constInst = length.second.words;
auto constResultTypeIndex = 1;
- auto constResultType = find(constInst->words[constResultTypeIndex]);
- spvCheck(!found(constResultType), DIAG(lengthIndex)
- << "OpTypeArray Length <id> '"
- << inst->words[constResultTypeIndex]
- << "' result type is not defined.";
- return false);
- spvCheck(SpvOpTypeInt != constResultType->second.opcode,
- DIAG(lengthIndex) << "OpTypeArray Length <id> '"
- << inst->words[lengthIndex]
- << "' is not a constant integer type.";
- return false);
- if (4 == constInst->words.size()) {
- spvCheck(1 > constInst->words[3], DIAG(lengthIndex)
- << "OpTypeArray Length <id> '"
- << inst->words[lengthIndex]
- << "' value must be at least 1.";
+ auto constResultType = usedefs_.FindDef(constInst[constResultTypeIndex]);
+ if (!constResultType.first || SpvOpTypeInt != constResultType.second.opcode) {
+ DIAG(lengthIndex) << "OpTypeArray Length <id> '" << inst->words[lengthIndex]
+ << "' is not a constant integer type.";
+ return false;
+ }
+ if (4 == constInst.size()) {
+ spvCheck(1 > constInst[3], DIAG(lengthIndex)
+ << "OpTypeArray Length <id> '"
+ << inst->words[lengthIndex]
+ << "' value must be at least 1.";
return false);
- } else if (5 == constInst->words.size()) {
- uint64_t value =
- constInst->words[3] | ((uint64_t)constInst->words[4]) << 32;
- bool signedness = constResultType->second.inst->words[3] != 0;
+ } else if (5 == constInst.size()) {
+ uint64_t value = constInst[3] | ((uint64_t)constInst[4]) << 32;
+ bool signedness = constResultType.second.words[3] != 0;
if (signedness) {
spvCheck(1 > (int64_t)value, DIAG(lengthIndex)
<< "OpTypeArray Length <id> '"
bool idUsage::isValid<SpvOpTypeRuntimeArray>(const spv_instruction_t* inst,
const spv_opcode_desc) {
auto elementTypeIndex = 2;
- auto elementType = find(inst->words[elementTypeIndex]);
- spvCheck(!found(elementType), DIAG(elementTypeIndex)
- << "OpTypeRuntimeArray Element Type <id> '"
- << inst->words[elementTypeIndex]
- << "' is not defined.";
- return false);
- spvCheck(!spvOpcodeGeneratesType(elementType->second.opcode),
- DIAG(elementTypeIndex) << "OpTypeRuntimeArray Element Type <id> '"
- << inst->words[elementTypeIndex]
- << "' is not a type.";
- return false);
+ auto elementType = usedefs_.FindDef(inst->words[elementTypeIndex]);
+ if (!elementType.first ||
+ !spvOpcodeGeneratesType(elementType.second.opcode)) {
+ DIAG(elementTypeIndex) << "OpTypeRuntimeArray Element Type <id> '"
+ << inst->words[elementTypeIndex]
+ << "' is not a type.";
+ return false;
+ }
return true;
}
const spv_opcode_desc) {
for (size_t memberTypeIndex = 2; memberTypeIndex < inst->words.size();
++memberTypeIndex) {
- auto memberType = find(inst->words[memberTypeIndex]);
- spvCheck(!found(memberType), DIAG(memberTypeIndex)
- << "OpTypeStruct Member Type <id> '"
- << inst->words[memberTypeIndex]
- << "' is not defined.";
- return false);
- spvCheck(!spvOpcodeGeneratesType(memberType->second.opcode),
- DIAG(memberTypeIndex) << "OpTypeStruct Member Type <id> '"
- << inst->words[memberTypeIndex]
- << "' is not a type.";
- return false);
+ auto memberType = usedefs_.FindDef(inst->words[memberTypeIndex]);
+ if (!memberType.first ||
+ !spvOpcodeGeneratesType(memberType.second.opcode)) {
+ DIAG(memberTypeIndex) << "OpTypeStruct Member Type <id> '"
+ << inst->words[memberTypeIndex]
+ << "' is not a type.";
+ return false;
+ }
}
return true;
}
bool idUsage::isValid<SpvOpTypePointer>(const spv_instruction_t* inst,
const spv_opcode_desc) {
auto typeIndex = 3;
- auto type = find(inst->words[typeIndex]);
- spvCheck(!found(type), DIAG(typeIndex) << "OpTypePointer Type <id> '"
- << inst->words[typeIndex]
- << "' is not defined.";
- return false);
- spvCheck(!spvOpcodeGeneratesType(type->second.opcode),
- DIAG(typeIndex) << "OpTypePointer Type <id> '"
- << inst->words[typeIndex] << "' is not a type.";
- return false);
+ auto type = usedefs_.FindDef(inst->words[typeIndex]);
+ if (!type.first || !spvOpcodeGeneratesType(type.second.opcode)) {
+ DIAG(typeIndex) << "OpTypePointer Type <id> '" << inst->words[typeIndex]
+ << "' is not a type.";
+ return false;
+ }
return true;
}
bool idUsage::isValid<SpvOpTypeFunction>(const spv_instruction_t* inst,
const spv_opcode_desc) {
auto returnTypeIndex = 2;
- auto returnType = find(inst->words[returnTypeIndex]);
- spvCheck(!found(returnType), DIAG(returnTypeIndex)
- << "OpTypeFunction Return Type <id> '"
- << inst->words[returnTypeIndex]
- << "' is not defined";
- return false);
- spvCheck(!spvOpcodeGeneratesType(returnType->second.opcode),
- DIAG(returnTypeIndex) << "OpTypeFunction Return Type <id> '"
- << inst->words[returnTypeIndex]
- << "' is not a type.";
- return false);
+ auto returnType = usedefs_.FindDef(inst->words[returnTypeIndex]);
+ if (!returnType.first || !spvOpcodeGeneratesType(returnType.second.opcode)) {
+ DIAG(returnTypeIndex) << "OpTypeFunction Return Type <id> '"
+ << inst->words[returnTypeIndex] << "' is not a type.";
+ return false;
+ }
for (size_t paramTypeIndex = 3; paramTypeIndex < inst->words.size();
++paramTypeIndex) {
- auto paramType = find(inst->words[paramTypeIndex]);
- spvCheck(!found(paramType), DIAG(paramTypeIndex)
- << "OpTypeFunction Parameter Type <id> '"
- << inst->words[paramTypeIndex]
- << "' is not defined.";
- return false);
- spvCheck(!spvOpcodeGeneratesType(paramType->second.opcode),
- DIAG(paramTypeIndex) << "OpTypeFunction Parameter Type <id> '"
- << inst->words[paramTypeIndex]
- << "' is not a type.";
- return false);
+ auto paramType = usedefs_.FindDef(inst->words[paramTypeIndex]);
+ if (!paramType.first || !spvOpcodeGeneratesType(paramType.second.opcode)) {
+ DIAG(paramTypeIndex) << "OpTypeFunction Parameter Type <id> '"
+ << inst->words[paramTypeIndex] << "' is not a type.";
+ return false;
+ }
}
return true;
}
bool idUsage::isValid<SpvOpConstantTrue>(const spv_instruction_t* inst,
const spv_opcode_desc) {
auto resultTypeIndex = 1;
- auto resultType = find(inst->words[resultTypeIndex]);
- spvCheck(!found(resultType), DIAG(resultTypeIndex)
- << "OpConstantTrue Result Type <id> '"
- << inst->words[resultTypeIndex]
- << "' is not defined.";
- return false);
- spvCheck(SpvOpTypeBool != resultType->second.opcode,
- DIAG(resultTypeIndex) << "OpConstantTrue Result Type <id> '"
- << inst->words[resultTypeIndex]
- << "' is not a boolean type.";
- return false);
+ auto resultType = usedefs_.FindDef(inst->words[resultTypeIndex]);
+ if (!resultType.first || SpvOpTypeBool != resultType.second.opcode) {
+ DIAG(resultTypeIndex) << "OpConstantTrue Result Type <id> '"
+ << inst->words[resultTypeIndex]
+ << "' is not a boolean type.";
+ return false;
+ }
return true;
}
bool idUsage::isValid<SpvOpConstantFalse>(const spv_instruction_t* inst,
const spv_opcode_desc) {
auto resultTypeIndex = 1;
- auto resultType = find(inst->words[resultTypeIndex]);
- spvCheck(!found(resultType), DIAG(resultTypeIndex)
- << "OpConstantFalse Result Type <id> '"
- << inst->words[resultTypeIndex]
- << "' is not defined.";
- return false);
- spvCheck(SpvOpTypeBool != resultType->second.opcode,
- DIAG(resultTypeIndex) << "OpConstantFalse Result Type <id> '"
- << inst->words[resultTypeIndex]
- << "' is not a boolean type.";
- return false);
+ auto resultType = usedefs_.FindDef(inst->words[resultTypeIndex]);
+ if (!resultType.first || SpvOpTypeBool != resultType.second.opcode) {
+ DIAG(resultTypeIndex) << "OpConstantFalse Result Type <id> '"
+ << inst->words[resultTypeIndex]
+ << "' is not a boolean type.";
+ return false;
+ }
return true;
}
bool idUsage::isValid<SpvOpConstant>(const spv_instruction_t* inst,
const spv_opcode_desc) {
auto resultTypeIndex = 1;
- auto resultType = find(inst->words[resultTypeIndex]);
- spvCheck(!found(resultType), DIAG(resultTypeIndex)
- << "OpConstant Result Type <id> '"
- << inst->words[resultTypeIndex]
- << "' is not defined.";
- return false);
- spvCheck(!spvOpcodeIsScalarType(resultType->second.opcode),
- DIAG(resultTypeIndex)
- << "OpConstant Result Type <id> '"
- << inst->words[resultTypeIndex]
- << "' is not a scalar integer or floating point type.";
- return false);
+ auto resultType = usedefs_.FindDef(inst->words[resultTypeIndex]);
+ if (!resultType.first || !spvOpcodeIsScalarType(resultType.second.opcode)) {
+ DIAG(resultTypeIndex)
+ << "OpConstant Result Type <id> '" << inst->words[resultTypeIndex]
+ << "' is not a scalar integer or floating point type.";
+ return false;
+ }
return true;
}
bool idUsage::isValid<SpvOpConstantComposite>(const spv_instruction_t* inst,
const spv_opcode_desc) {
auto resultTypeIndex = 1;
- auto resultType = find(inst->words[resultTypeIndex]);
- spvCheck(!found(resultType), DIAG(resultTypeIndex)
- << "OpConstantComposite Result Type <id> '"
- << inst->words[resultTypeIndex]
- << "' is not defined.";
- return false);
- spvCheck(!spvOpcodeIsComposite(resultType->second.opcode),
- DIAG(resultTypeIndex) << "OpConstantComposite Result Type <id> '"
- << inst->words[resultTypeIndex]
- << "' is not a composite type.";
- return false);
+ auto resultType = usedefs_.FindDef(inst->words[resultTypeIndex]);
+ if (!resultType.first || !spvOpcodeIsComposite(resultType.second.opcode)) {
+ DIAG(resultTypeIndex) << "OpConstantComposite Result Type <id> '"
+ << inst->words[resultTypeIndex]
+ << "' is not a composite type.";
+ return false;
+ }
auto constituentCount = inst->words.size() - 3;
- switch (resultType->second.opcode) {
+ switch (resultType.second.opcode) {
case SpvOpTypeVector: {
- auto componentCount = resultType->second.inst->words[3];
+ auto componentCount = resultType.second.words[3];
spvCheck(
componentCount != constituentCount,
// TODO: Output ID's on diagnostic
DIAG(inst->words.size() - 1)
<< "OpConstantComposite Constituent <id> count does not match "
"Result Type <id> '"
- << resultType->second.id << "'s vector component count.";
+ << resultType.second.id << "'s vector component count.";
return false);
- auto componentType = find(resultType->second.inst->words[2]);
- spvCheck(!found(componentType), assert(0 && "Unreachable!"));
+ auto componentType = usedefs_.FindDef(resultType.second.words[2]);
+ assert(componentType.first);
for (size_t constituentIndex = 3; constituentIndex < inst->words.size();
constituentIndex++) {
- auto constituent = find(inst->words[constituentIndex]);
- spvCheck(!found(constituent), assert(0 && "Unreachable!"));
- spvCheck(!spvOpcodeIsConstant(constituent->second.opcode),
- DIAG(constituentIndex)
- << "OpConstantComposite Constituent <id> '"
- << inst->words[constituentIndex] << "' is not a constant.";
- return false);
- auto constituentResultType = find(constituent->second.inst->words[1]);
- spvCheck(!found(constituentResultType), assert(0 && "Unreachable!"));
- spvCheck(componentType->second.opcode !=
- constituentResultType->second.opcode,
- DIAG(constituentIndex)
- << "OpConstantComposite Constituent <id> '"
- << inst->words[constituentIndex]
- << "'s type does not match Result Type <id> '"
- << resultType->second.id << "'s vector element type.";
- return false);
+ auto constituent = usedefs_.FindDef(inst->words[constituentIndex]);
+ if (!constituent.first ||
+ !spvOpcodeIsConstant(constituent.second.opcode)) {
+ DIAG(constituentIndex) << "OpConstantComposite Constituent <id> '"
+ << inst->words[constituentIndex]
+ << "' is not a constant.";
+ return false;
+ }
+ auto constituentResultType =
+ usedefs_.FindDef(constituent.second.words[1]);
+ if (!constituentResultType.first ||
+ componentType.second.opcode !=
+ constituentResultType.second.opcode) {
+ DIAG(constituentIndex) << "OpConstantComposite Constituent <id> '"
+ << inst->words[constituentIndex]
+ << "'s type does not match Result Type <id> '"
+ << resultType.second.id
+ << "'s vector element type.";
+ return false;
+ }
}
} break;
case SpvOpTypeMatrix: {
- auto columnCount = resultType->second.inst->words[3];
+ auto columnCount = resultType.second.words[3];
spvCheck(
columnCount != constituentCount,
// TODO: Output ID's on diagnostic
DIAG(inst->words.size() - 1)
<< "OpConstantComposite Constituent <id> count does not match "
"Result Type <id> '"
- << resultType->second.id << "'s matrix column count.";
+ << resultType.second.id << "'s matrix column count.";
return false);
- auto columnType = find(resultType->second.inst->words[2]);
- spvCheck(!found(columnType), assert(0 && "Unreachable!"));
- auto componentCount = columnType->second.inst->words[3];
- auto componentType = find(columnType->second.inst->words[2]);
- spvCheck(!found(componentType), assert(0 && "Unreachable!"));
+ auto columnType = usedefs_.FindDef(resultType.second.words[2]);
+ assert(columnType.first);
+ auto componentCount = columnType.second.words[3];
+ auto componentType = usedefs_.FindDef(columnType.second.words[2]);
+ assert(componentType.first);
for (size_t constituentIndex = 3; constituentIndex < inst->words.size();
constituentIndex++) {
- auto constituent = find(inst->words[constituentIndex]);
- spvCheck(!found(constituent),
- DIAG(constituentIndex)
- << "OpConstantComposite Constituent <id> '"
- << inst->words[constituentIndex] << "' is not defined.";
- return false);
- spvCheck(SpvOpConstantComposite != constituent->second.opcode,
- DIAG(constituentIndex)
- << "OpConstantComposite Constituent <id> '"
- << inst->words[constituentIndex]
- << "' is not a constant composite.";
- return false);
- auto vector = find(constituent->second.inst->words[1]);
- spvCheck(!found(vector), assert(0 && "Unreachable!"));
- spvCheck(columnType->second.opcode != vector->second.opcode,
+ auto constituent = usedefs_.FindDef(inst->words[constituentIndex]);
+ if (!constituent.first ||
+ SpvOpConstantComposite != constituent.second.opcode) {
+ DIAG(constituentIndex) << "OpConstantComposite Constituent <id> '"
+ << inst->words[constituentIndex]
+ << "' is not a constant composite.";
+ return false;
+ }
+ auto vector = usedefs_.FindDef(constituent.second.words[1]);
+ assert(vector.first);
+ spvCheck(columnType.second.opcode != vector.second.opcode,
DIAG(constituentIndex)
<< "OpConstantComposite Constituent <id> '"
<< inst->words[constituentIndex]
<< "' type does not match Result Type <id> '"
- << resultType->second.id << "'s matrix column type.";
+ << resultType.second.id << "'s matrix column type.";
return false);
- auto vectorComponentType = find(vector->second.inst->words[2]);
- spvCheck(!found(vectorComponentType), assert(0 && "Unreachable!"));
- spvCheck(!spvOpcodeAreTypesEqual(componentType->second.inst,
- vectorComponentType->second.inst),
+ auto vectorComponentType = usedefs_.FindDef(vector.second.words[2]);
+ assert(vectorComponentType.first);
+ spvCheck(componentType.second.id != vectorComponentType.second.id,
DIAG(constituentIndex)
<< "OpConstantComposite Constituent <id> '"
<< inst->words[constituentIndex]
<< "' component type does not match Result Type <id> '"
- << resultType->second.id
+ << resultType.second.id
<< "'s matrix column component type.";
return false);
spvCheck(
- componentCount != vector->second.inst->words[3],
+ componentCount != vector.second.words[3],
DIAG(constituentIndex)
<< "OpConstantComposite Constituent <id> '"
<< inst->words[constituentIndex]
<< "' vector component count does not match Result Type <id> '"
- << resultType->second.id << "'s vector component count.";
+ << resultType.second.id << "'s vector component count.";
return false);
}
} break;
case SpvOpTypeArray: {
- auto elementType = find(resultType->second.inst->words[2]);
- spvCheck(!found(elementType), assert(0 && "Unreachable!"));
- auto length = find(resultType->second.inst->words[3]);
- spvCheck(!found(length), assert(0 && "Unreachable!"));
- spvCheck(length->second.inst->words[3] != constituentCount,
+ auto elementType = usedefs_.FindDef(resultType.second.words[2]);
+ assert(elementType.first);
+ auto length = usedefs_.FindDef(resultType.second.words[3]);
+ assert(length.first);
+ spvCheck(length.second.words[3] != constituentCount,
DIAG(inst->words.size() - 1)
<< "OpConstantComposite Constituent count does not match "
"Result Type <id> '"
- << resultType->second.id << "'s array length.";
+ << resultType.second.id << "'s array length.";
return false);
for (size_t constituentIndex = 3; constituentIndex < inst->words.size();
constituentIndex++) {
- auto constituent = find(inst->words[constituentIndex]);
- spvCheck(!found(constituent),
- DIAG(constituentIndex)
- << "OpConstantComposite Constituent <id> '"
- << inst->words[constituentIndex] << "' is not defined.";
- return false);
- spvCheck(!spvOpcodeIsConstant(constituent->second.opcode),
- DIAG(constituentIndex)
- << "OpConstantComposite Constituent <id> '"
- << inst->words[constituentIndex] << "' is not a constant.";
- return false);
- auto constituentType = find(constituent->second.inst->words[1]);
- spvCheck(!found(constituentType), assert(0 && "Unreachable!"));
- spvCheck(!spvOpcodeAreTypesEqual(elementType->second.inst,
- constituentType->second.inst),
+ auto constituent = usedefs_.FindDef(inst->words[constituentIndex]);
+ if (!constituent.first ||
+ !spvOpcodeIsConstant(constituent.second.opcode)) {
+ DIAG(constituentIndex) << "OpConstantComposite Constituent <id> '"
+ << inst->words[constituentIndex]
+ << "' is not a constant.";
+ return false;
+ }
+ auto constituentType = usedefs_.FindDef(constituent.second.words[1]);
+ assert(constituentType.first);
+ spvCheck(elementType.second.id != constituentType.second.id,
DIAG(constituentIndex)
<< "OpConstantComposite Constituent <id> '"
<< inst->words[constituentIndex]
<< "'s type does not match Result Type <id> '"
- << resultType->second.id << "'s array element type.";
+ << resultType.second.id << "'s array element type.";
return false);
}
} break;
case SpvOpTypeStruct: {
- auto memberCount = resultType->second.inst->words.size() - 2;
+ auto memberCount = resultType.second.words.size() - 2;
spvCheck(memberCount != constituentCount,
DIAG(resultTypeIndex)
<< "OpConstantComposite Constituent <id> '"
<< inst->words[resultTypeIndex]
<< "' count does not match Result Type <id> '"
- << resultType->second.id << "'s struct member count.";
+ << resultType.second.id << "'s struct member count.";
return false);
for (uint32_t constituentIndex = 3, memberIndex = 2;
constituentIndex < inst->words.size();
constituentIndex++, memberIndex++) {
- auto constituent = find(inst->words[constituentIndex]);
- spvCheck(!found(constituent),
- DIAG(constituentIndex)
- << "OpConstantComposite Constituent <id> '"
- << inst->words[constituentIndex] << "' is not define.";
- return false);
- spvCheck(!spvOpcodeIsConstant(constituent->second.opcode),
- DIAG(constituentIndex)
- << "OpConstantComposite Constituent <id> '"
- << inst->words[constituentIndex] << "' is not a constant.";
- return false);
- auto constituentType = find(constituent->second.inst->words[1]);
- spvCheck(!found(constituentType), assert(0 && "Unreachable!"));
-
- auto memberType = find(resultType->second.inst->words[memberIndex]);
- spvCheck(!found(memberType), assert(0 && "Unreachable!"));
- spvCheck(!spvOpcodeAreTypesEqual(memberType->second.inst,
- constituentType->second.inst),
+ auto constituent = usedefs_.FindDef(inst->words[constituentIndex]);
+ if (!constituent.first ||
+ !spvOpcodeIsConstant(constituent.second.opcode)) {
+ DIAG(constituentIndex) << "OpConstantComposite Constituent <id> '"
+ << inst->words[constituentIndex]
+ << "' is not a constant.";
+ return false;
+ }
+ auto constituentType = usedefs_.FindDef(constituent.second.words[1]);
+ assert(constituentType.first);
+
+ auto memberType =
+ usedefs_.FindDef(resultType.second.words[memberIndex]);
+ assert(memberType.first);
+ spvCheck(memberType.second.id != constituentType.second.id,
DIAG(constituentIndex)
<< "OpConstantComposite Constituent <id> '"
<< inst->words[constituentIndex]
<< "' type does not match the Result Type <id> '"
- << resultType->second.id << "'s member type.";
+ << resultType.second.id << "'s member type.";
return false);
}
} break;
bool idUsage::isValid<SpvOpConstantSampler>(const spv_instruction_t* inst,
const spv_opcode_desc) {
auto resultTypeIndex = 1;
- auto resultType = find(inst->words[resultTypeIndex]);
- spvCheck(!found(resultType), DIAG(resultTypeIndex)
- << "OpConstantSampler Result Type <id> '"
- << inst->words[resultTypeIndex]
- << "' is not defined.";
- return false);
- spvCheck(SpvOpTypeSampler != resultType->second.opcode,
- DIAG(resultTypeIndex) << "OpConstantSampler Result Type <id> '"
- << inst->words[resultTypeIndex]
- << "' is not a sampler type.";
- return false);
+ auto resultType = usedefs_.FindDef(inst->words[resultTypeIndex]);
+ if (!resultType.first || SpvOpTypeSampler != resultType.second.opcode) {
+ DIAG(resultTypeIndex) << "OpConstantSampler Result Type <id> '"
+ << inst->words[resultTypeIndex]
+ << "' is not a sampler type.";
+ return false;
+ }
return true;
}
bool idUsage::isValid<SpvOpConstantNull>(const spv_instruction_t* inst,
const spv_opcode_desc) {
auto resultTypeIndex = 1;
- auto resultType = find(inst->words[resultTypeIndex]);
- spvCheck(!found(resultType), DIAG(resultTypeIndex)
- << "OpConstantNull Result Type <id> '"
- << inst->words[resultTypeIndex]
- << "' is not defined.";
- return false);
- switch (resultType->second.inst->opcode) {
+ auto resultType = usedefs_.FindDef(inst->words[resultTypeIndex]);
+ if (!resultType.first) return false;
+ switch (resultType.second.opcode) {
default: {
- spvCheck(!spvOpcodeIsBasicTypeNullable(resultType->second.inst->opcode),
+ spvCheck(!spvOpcodeIsBasicTypeNullable(resultType.second.opcode),
DIAG(resultTypeIndex) << "OpConstantNull Result Type <id> '"
<< inst->words[resultTypeIndex]
- << "' can not be null.";
+ << "' cannot be null.";
return false);
} break;
case SpvOpTypeVector: {
- auto type = find(resultType->second.inst->words[2]);
- spvCheck(!found(type), assert(0 && "Unreachable!"));
- spvCheck(!spvOpcodeIsBasicTypeNullable(type->second.inst->opcode),
+ auto type = usedefs_.FindDef(resultType.second.words[2]);
+ assert(type.first);
+ spvCheck(!spvOpcodeIsBasicTypeNullable(type.second.opcode),
DIAG(resultTypeIndex)
<< "OpConstantNull Result Type <id> '"
<< inst->words[resultTypeIndex]
- << "'s vector component type can not be null.";
+ << "'s vector component type cannot be null.";
return false);
} break;
case SpvOpTypeArray: {
- auto type = find(resultType->second.inst->words[2]);
- spvCheck(!found(type), assert(0 && "Unreachable!"));
- spvCheck(!spvOpcodeIsBasicTypeNullable(type->second.inst->opcode),
- DIAG(resultTypeIndex)
- << "OpConstantNull Result Type <id> '"
- << inst->words[resultTypeIndex]
- << "'s array element type can not be null.";
+ auto type = usedefs_.FindDef(resultType.second.words[2]);
+ assert(type.first);
+ spvCheck(!spvOpcodeIsBasicTypeNullable(type.second.opcode),
+ DIAG(resultTypeIndex) << "OpConstantNull Result Type <id> '"
+ << inst->words[resultTypeIndex]
+ << "'s array element type cannot be null.";
return false);
} break;
case SpvOpTypeMatrix: {
- auto columnType = find(resultType->second.inst->words[2]);
- spvCheck(!found(columnType), assert(0 && "Unreachable!"));
- auto type = find(columnType->second.inst->words[2]);
- spvCheck(!found(type), assert(0 && "Unreachable!"));
- spvCheck(!spvOpcodeIsBasicTypeNullable(type->second.inst->opcode),
+ auto columnType = usedefs_.FindDef(resultType.second.words[2]);
+ assert(columnType.first);
+ auto type = usedefs_.FindDef(columnType.second.words[2]);
+ assert(type.first);
+ spvCheck(!spvOpcodeIsBasicTypeNullable(type.second.opcode),
DIAG(resultTypeIndex)
<< "OpConstantNull Result Type <id> '"
<< inst->words[resultTypeIndex]
} break;
case SpvOpTypeStruct: {
for (size_t elementIndex = 2;
- elementIndex < resultType->second.inst->words.size();
- ++elementIndex) {
- auto element = find(resultType->second.inst->words[elementIndex]);
- spvCheck(!found(element), assert(0 && "Unreachable!"));
- spvCheck(!spvOpcodeIsBasicTypeNullable(element->second.inst->opcode),
+ elementIndex < resultType.second.words.size(); ++elementIndex) {
+ auto element = usedefs_.FindDef(resultType.second.words[elementIndex]);
+ assert(element.first);
+ spvCheck(!spvOpcodeIsBasicTypeNullable(element.second.opcode),
DIAG(resultTypeIndex)
<< "OpConstantNull Result Type <id> '"
<< inst->words[resultTypeIndex]
- << "'s struct element type can not be null.";
+ << "'s struct element type cannot be null.";
return false);
}
} break;
bool idUsage::isValid<SpvOpSpecConstantTrue>(const spv_instruction_t* inst,
const spv_opcode_desc) {
auto resultTypeIndex = 1;
- auto resultType = find(inst->words[resultTypeIndex]);
- spvCheck(!found(resultType), DIAG(resultTypeIndex)
- << "OpSpecConstantTrue Result Type <id> '"
- << inst->words[resultTypeIndex]
- << "' is not defined.";
- return false);
- spvCheck(SpvOpTypeBool != resultType->second.opcode,
- DIAG(resultTypeIndex) << "OpSpecConstantTrue Result Type <id> '"
- << inst->words[resultTypeIndex]
- << "' is not a boolean type.";
- return false);
+ auto resultType = usedefs_.FindDef(inst->words[resultTypeIndex]);
+ if (!resultType.first || SpvOpTypeBool != resultType.second.opcode) {
+ DIAG(resultTypeIndex) << "OpSpecConstantTrue Result Type <id> '"
+ << inst->words[resultTypeIndex]
+ << "' is not a boolean type.";
+ return false;
+ }
return true;
}
bool idUsage::isValid<SpvOpSpecConstantFalse>(const spv_instruction_t* inst,
const spv_opcode_desc) {
auto resultTypeIndex = 1;
- auto resultType = find(inst->words[resultTypeIndex]);
- spvCheck(!found(resultType), DIAG(resultTypeIndex)
- << "OpSpecConstantFalse Result Type <id> '"
- << inst->words[resultTypeIndex]
- << "' is not defined.";
- return false);
- spvCheck(SpvOpTypeBool != resultType->second.opcode,
- DIAG(resultTypeIndex) << "OpSpecConstantFalse Result Type <id> '"
- << inst->words[resultTypeIndex]
- << "' is not a boolean type.";
- return false);
+ auto resultType = usedefs_.FindDef(inst->words[resultTypeIndex]);
+ if (!resultType.first || SpvOpTypeBool != resultType.second.opcode) {
+ DIAG(resultTypeIndex) << "OpSpecConstantFalse Result Type <id> '"
+ << inst->words[resultTypeIndex]
+ << "' is not a boolean type.";
+ return false;
+ }
return true;
}
bool idUsage::isValid<SpvOpSpecConstant>(const spv_instruction_t* inst,
const spv_opcode_desc) {
auto resultTypeIndex = 1;
- auto resultType = find(inst->words[resultTypeIndex]);
- spvCheck(!found(resultType), DIAG(resultTypeIndex)
- << "OpSpecConstant Result Type <id> '"
- << inst->words[resultTypeIndex]
- << "' is not defined.";
- return false);
- spvCheck(!spvOpcodeIsScalarType(resultType->second.opcode),
- DIAG(resultTypeIndex) << "OpSpecConstant Result Type <id> '"
- << inst->words[resultTypeIndex]
- << "' is not a scalar type.";
- return false);
+ auto resultType = usedefs_.FindDef(inst->words[resultTypeIndex]);
+ if (!resultType.first || !spvOpcodeIsScalarType(resultType.second.opcode)) {
+ DIAG(resultTypeIndex) << "OpSpecConstant Result Type <id> '"
+ << inst->words[resultTypeIndex]
+ << "' is not a scalar type.";
+ return false;
+ }
return true;
}
bool idUsage::isValid<SpvOpVariable>(const spv_instruction_t* inst,
const spv_opcode_desc opcodeEntry) {
auto resultTypeIndex = 1;
- auto resultType = find(inst->words[resultTypeIndex]);
- spvCheck(!found(resultType), DIAG(resultTypeIndex)
- << "OpVariable Result Type <id> '"
- << inst->words[resultTypeIndex]
- << "' is not defined.";
- return false);
- spvCheck(SpvOpTypePointer != resultType->second.opcode,
- DIAG(resultTypeIndex) << "OpVariable Result Type <id> '"
- << inst->words[resultTypeIndex]
- << "' is not a pointer type.";
- return false);
+ auto resultType = usedefs_.FindDef(inst->words[resultTypeIndex]);
+ if (!resultType.first || SpvOpTypePointer != resultType.second.opcode) {
+ DIAG(resultTypeIndex) << "OpVariable Result Type <id> '"
+ << inst->words[resultTypeIndex]
+ << "' is not a pointer type.";
+ return false;
+ }
if (opcodeEntry->numTypes < inst->words.size()) {
auto initialiserIndex = 4;
- auto initialiser = find(inst->words[initialiserIndex]);
- spvCheck(!found(initialiser), DIAG(initialiserIndex)
- << "OpVariable Initializer <id> '"
- << inst->words[initialiserIndex]
- << "' is not defined.";
- return false);
- spvCheck(!spvOpcodeIsConstant(initialiser->second.opcode),
- DIAG(initialiserIndex) << "OpVariable Initializer <id> '"
- << inst->words[initialiserIndex]
- << "' is not a constant.";
- return false);
+ auto initialiser = usedefs_.FindDef(inst->words[initialiserIndex]);
+ if (!initialiser.first || !spvOpcodeIsConstant(initialiser.second.opcode)) {
+ DIAG(initialiserIndex) << "OpVariable Initializer <id> '"
+ << inst->words[initialiserIndex]
+ << "' is not a constant.";
+ return false;
+ }
}
return true;
}
bool idUsage::isValid<SpvOpLoad>(const spv_instruction_t* inst,
const spv_opcode_desc) {
auto resultTypeIndex = 1;
- auto resultType = find(inst->words[resultTypeIndex]);
- spvCheck(!found(resultType), DIAG(resultTypeIndex)
- << "OpLoad Result Type <id> '"
- << inst->words[resultTypeIndex]
- << "' is not defind.";
+ auto resultType = usedefs_.FindDef(inst->words[resultTypeIndex]);
+ spvCheck(!resultType.first, DIAG(resultTypeIndex)
+ << "OpLoad Result Type <id> '"
+ << inst->words[resultTypeIndex]
+ << "' is not defind.";
return false);
auto pointerIndex = 3;
- auto pointer = find(inst->words[pointerIndex]);
- spvCheck(!found(pointer), DIAG(pointerIndex) << "OpLoad Pointer <id> '"
- << inst->words[pointerIndex]
- << "' is not defined.";
- return false);
- spvCheck(!spvOpcodeIsPointer(pointer->second.opcode),
- DIAG(pointerIndex) << "OpLoad Pointer <id> '"
- << inst->words[pointerIndex]
- << "' is not a pointer.";
- return false);
- auto type = find(pointer->second.inst->words[1]);
- spvCheck(!found(type), assert(0 && "Unreachable!"));
- spvCheck(resultType != type, DIAG(resultTypeIndex)
- << "OpLoad Result Type <id> '"
- << inst->words[resultTypeIndex]
- << " does not match Pointer <id> '"
- << pointer->second.id << "'s type.";
+ auto pointer = usedefs_.FindDef(inst->words[pointerIndex]);
+ if (!pointer.first || !spvOpcodeIsPointer(pointer.second.opcode)) {
+ DIAG(pointerIndex) << "OpLoad Pointer <id> '" << inst->words[pointerIndex]
+ << "' is not a pointer.";
+ return false;
+ }
+ auto type = usedefs_.FindDef(pointer.second.words[1]);
+ assert(type.first);
+ spvCheck(resultType.second.id != type.second.id,
+ DIAG(resultTypeIndex)
+ << "OpLoad Result Type <id> '" << inst->words[resultTypeIndex]
+ << " does not match Pointer <id> '" << pointer.second.id
+ << "'s type.";
return false);
return true;
}
bool idUsage::isValid<SpvOpStore>(const spv_instruction_t* inst,
const spv_opcode_desc) {
auto pointerIndex = 1;
- auto pointer = find(inst->words[pointerIndex]);
- spvCheck(!found(pointer), DIAG(pointerIndex) << "OpStore Pointer <id> '"
- << inst->words[pointerIndex]
- << "' is not defined.";
- return false);
- spvCheck(!spvOpcodeIsPointer(pointer->second.opcode),
- DIAG(pointerIndex) << "OpStore Pointer <id> '"
- << inst->words[pointerIndex]
- << "' is not a pointer.";
- return false);
- auto pointerType = find(pointer->second.inst->words[1]);
- spvCheck(!found(pointerType), assert(0 && "Unreachable!"));
- auto type = find(pointerType->second.inst->words[3]);
- spvCheck(!found(type), assert(0 && "Unreachable!"));
- spvCheck(SpvOpTypeVoid == type->second.opcode,
- DIAG(pointerIndex) << "OpStore Pointer <id> '"
- << inst->words[pointerIndex]
- << "'s type is void.";
+ auto pointer = usedefs_.FindDef(inst->words[pointerIndex]);
+ if (!pointer.first || !spvOpcodeIsPointer(pointer.second.opcode)) {
+ DIAG(pointerIndex) << "OpStore Pointer <id> '" << inst->words[pointerIndex]
+ << "' is not a pointer.";
+ return false;
+ }
+ auto pointerType = usedefs_.FindDef(pointer.second.words[1]);
+ assert(pointerType.first);
+ auto type = usedefs_.FindDef(pointerType.second.words[3]);
+ assert(type.first);
+ spvCheck(SpvOpTypeVoid == type.second.opcode, DIAG(pointerIndex)
+ << "OpStore Pointer <id> '"
+ << inst->words[pointerIndex]
+ << "'s type is void.";
return false);
auto objectIndex = 2;
- auto object = find(inst->words[objectIndex]);
- spvCheck(!found(object), DIAG(objectIndex) << "OpStore Object <id> '"
- << inst->words[objectIndex]
- << "' is not defined.";
- return false);
- spvCheck(!spvOpcodeIsObject(object->second.opcode),
- DIAG(objectIndex) << "OpStore Object <id> '"
- << inst->words[objectIndex]
- << "' in not an object.";
- return false);
- auto objectType = find(object->second.inst->words[1]);
- spvCheck(!found(objectType), assert(0 && "Unreachable!"));
- spvCheck(SpvOpTypeVoid == objectType->second.opcode,
+ auto object = usedefs_.FindDef(inst->words[objectIndex]);
+ if (!object.first || !spvOpcodeIsObject(object.second.opcode)) {
+ DIAG(objectIndex) << "OpStore Object <id> '" << inst->words[objectIndex]
+ << "' in not an object.";
+ return false;
+ }
+ auto objectType = usedefs_.FindDef(object.second.words[1]);
+ assert(objectType.first);
+ spvCheck(SpvOpTypeVoid == objectType.second.opcode,
DIAG(objectIndex) << "OpStore Object <id> '"
<< inst->words[objectIndex] << "'s type is void.";
return false);
- spvCheck(!spvOpcodeAreTypesEqual(type->second.inst, objectType->second.inst),
- DIAG(pointerIndex) << "OpStore Pointer <id> '"
- << inst->words[pointerIndex]
- << "'s type does not match Object <id> '"
- << objectType->second.id << "'s type.";
+ spvCheck(type.second.id != objectType.second.id,
+ DIAG(pointerIndex)
+ << "OpStore Pointer <id> '" << inst->words[pointerIndex]
+ << "'s type does not match Object <id> '" << objectType.second.id
+ << "'s type.";
return false);
return true;
}
bool idUsage::isValid<SpvOpCopyMemory>(const spv_instruction_t* inst,
const spv_opcode_desc) {
auto targetIndex = 1;
- auto target = find(inst->words[targetIndex]);
- spvCheck(!found(target), DIAG(targetIndex) << "OpCopyMemory Target <id> '"
- << inst->words[targetIndex]
- << "' is not defined.";
- return false);
+ auto target = usedefs_.FindDef(inst->words[targetIndex]);
+ if (!target.first) return false;
auto sourceIndex = 2;
- auto source = find(inst->words[sourceIndex]);
- spvCheck(!found(source), DIAG(targetIndex) << "OpCopyMemory Source <id> '"
- << inst->words[targetIndex]
- << "' is not defined.";
+ auto source = usedefs_.FindDef(inst->words[sourceIndex]);
+ if (!source.first) return false;
+ auto targetPointerType = usedefs_.FindDef(target.second.words[1]);
+ assert(targetPointerType.first);
+ auto targetType = usedefs_.FindDef(targetPointerType.second.words[3]);
+ assert(targetType.first);
+ auto sourcePointerType = usedefs_.FindDef(source.second.words[1]);
+ assert(sourcePointerType.first);
+ auto sourceType = usedefs_.FindDef(sourcePointerType.second.words[3]);
+ assert(sourceType.first);
+ spvCheck(targetType.second.id != sourceType.second.id,
+ DIAG(sourceIndex)
+ << "OpCopyMemory Target <id> '" << inst->words[sourceIndex]
+ << "'s type does not match Source <id> '" << sourceType.second.id
+ << "'s type.";
return false);
- auto targetPointerType = find(target->second.inst->words[1]);
- spvCheck(!found(targetPointerType), assert(0 && "Unreachable!"));
- auto targetType = find(targetPointerType->second.inst->words[3]);
- spvCheck(!found(targetType), assert(0 && "Unreachable!"));
- auto sourcePointerType = find(source->second.inst->words[1]);
- spvCheck(!found(sourcePointerType), assert(0 && "Unreachable!"));
- auto sourceType = find(sourcePointerType->second.inst->words[3]);
- spvCheck(!found(sourceType), assert(0 && "Unreachable!"));
- spvCheck(
- !spvOpcodeAreTypesEqual(targetType->second.inst, sourceType->second.inst),
- DIAG(sourceIndex) << "OpCopyMemory Target <id> '"
- << inst->words[sourceIndex]
- << "'s type does not match Source <id> '"
- << sourceType->second.id << "'s type.";
- return false);
return true;
}
bool idUsage::isValid<SpvOpCopyMemorySized>(const spv_instruction_t* inst,
const spv_opcode_desc) {
auto targetIndex = 1;
- auto target = find(inst->words[targetIndex]);
- spvCheck(!found(target),
- DIAG(targetIndex) << "OpCopyMemorySized Target <id> '"
- << inst->words[targetIndex] << "' is not defined.";
- return false);
+ auto target = usedefs_.FindDef(inst->words[targetIndex]);
+ if (!target.first) return false;
auto sourceIndex = 2;
- auto source = find(inst->words[sourceIndex]);
- spvCheck(!found(source),
- DIAG(sourceIndex) << "OpCopyMemorySized Source <id> '"
- << inst->words[sourceIndex] << "' is not defined.";
- return false);
+ auto source = usedefs_.FindDef(inst->words[sourceIndex]);
+ if (!source.first) return false;
auto sizeIndex = 3;
- auto size = find(inst->words[sizeIndex]);
- spvCheck(!found(size), DIAG(sizeIndex) << "OpCopyMemorySized, Size <id> '"
- << inst->words[sizeIndex]
- << "' is not defined.";
- return false);
- auto targetPointerType = find(target->second.inst->words[1]);
- spvCheck(!found(targetPointerType), assert(0 && "Unreachable!"));
- spvCheck(SpvOpTypePointer != targetPointerType->second.opcode,
+ auto size = usedefs_.FindDef(inst->words[sizeIndex]);
+ if (!size.first) return false;
+ auto targetPointerType = usedefs_.FindDef(target.second.words[1]);
+ assert(targetPointerType.first);
+ spvCheck(SpvOpTypePointer != targetPointerType.second.opcode,
DIAG(targetIndex) << "OpCopyMemorySized Target <id> '"
<< inst->words[targetIndex]
<< "' is not a pointer.";
return false);
- auto sourcePointerType = find(source->second.inst->words[1]);
- spvCheck(!found(sourcePointerType), assert(0 && "Unreachable!"));
- spvCheck(SpvOpTypePointer != sourcePointerType->second.opcode,
+ auto sourcePointerType = usedefs_.FindDef(source.second.words[1]);
+ assert(sourcePointerType.first);
+ spvCheck(SpvOpTypePointer != sourcePointerType.second.opcode,
DIAG(sourceIndex) << "OpCopyMemorySized Source <id> '"
<< inst->words[sourceIndex]
<< "' is not a pointer.";
return false);
- switch (size->second.opcode) {
+ switch (size.second.opcode) {
// TODO: The following opcode's are assumed to be valid, refer to the
// following bug https://cvs.khronos.org/bugzilla/show_bug.cgi?id=13871 for
// clarification
case SpvOpConstant:
case SpvOpSpecConstant: {
- auto sizeType = find(size->second.inst->words[1]);
- spvCheck(!found(sizeType), assert(0 && "Unreachable!"));
- spvCheck(SpvOpTypeInt != sizeType->second.opcode,
+ auto sizeType = usedefs_.FindDef(size.second.words[1]);
+ assert(sizeType.first);
+ spvCheck(SpvOpTypeInt != sizeType.second.opcode,
DIAG(sizeIndex) << "OpCopyMemorySized Size <id> '"
<< inst->words[sizeIndex]
<< "'s type is not an integer type.";
return false);
} break;
case SpvOpVariable: {
- auto pointerType = find(size->second.inst->words[1]);
- spvCheck(!found(pointerType), assert(0 && "Unreachable!"));
- auto sizeType = find(pointerType->second.inst->words[1]);
- spvCheck(!found(sizeType), assert(0 && "Unreachable!"));
- spvCheck(SpvOpTypeInt != sizeType->second.opcode,
+ auto pointerType = usedefs_.FindDef(size.second.words[1]);
+ assert(pointerType.first);
+ auto sizeType = usedefs_.FindDef(pointerType.second.words[1]);
+ assert(sizeType.first);
+ spvCheck(SpvOpTypeInt != sizeType.second.opcode,
DIAG(sizeIndex) << "OpCopyMemorySized Size <id> '"
<< inst->words[sizeIndex]
<< "'s variable type is not an integer type.";
bool idUsage::isValid<SpvOpFunction>(const spv_instruction_t* inst,
const spv_opcode_desc) {
auto resultTypeIndex = 1;
- auto resultType = find(inst->words[resultTypeIndex]);
- spvCheck(!found(resultType), DIAG(resultTypeIndex)
- << "OpFunction Result Type <id> '"
- << inst->words[resultTypeIndex]
- << "' is not defined.";
- return false);
+ auto resultType = usedefs_.FindDef(inst->words[resultTypeIndex]);
+ if (!resultType.first) return false;
auto functionTypeIndex = 4;
- auto functionType = find(inst->words[functionTypeIndex]);
- spvCheck(!found(functionType), DIAG(functionTypeIndex)
- << "OpFunction Function Type <id> '"
- << inst->words[functionTypeIndex]
- << "' is not defined.";
- return false);
- spvCheck(SpvOpTypeFunction != functionType->second.opcode,
- DIAG(functionTypeIndex) << "OpFunction Function Type <id> '"
- << inst->words[functionTypeIndex]
- << "' is not a function type.";
- return false);
- auto returnType = find(functionType->second.inst->words[2]);
- spvCheck(!found(returnType), assert(0 && "Unreachable!"));
- spvCheck(returnType != resultType,
+ auto functionType = usedefs_.FindDef(inst->words[functionTypeIndex]);
+ if (!functionType.first || SpvOpTypeFunction != functionType.second.opcode) {
+ DIAG(functionTypeIndex) << "OpFunction Function Type <id> '"
+ << inst->words[functionTypeIndex]
+ << "' is not a function type.";
+ return false;
+ }
+ auto returnType = usedefs_.FindDef(functionType.second.words[2]);
+ assert(returnType.first);
+ spvCheck(returnType.second.id != resultType.second.id,
DIAG(resultTypeIndex) << "OpFunction Result Type <id> '"
<< inst->words[resultTypeIndex]
<< "' does not match the Function Type <id> '"
- << resultType->second.id << "'s return type.";
+ << resultType.second.id << "'s return type.";
return false);
return true;
}
bool idUsage::isValid<SpvOpFunctionParameter>(const spv_instruction_t* inst,
const spv_opcode_desc) {
auto resultTypeIndex = 1;
- auto resultType = find(inst->words[resultTypeIndex]);
- spvCheck(!found(resultType), DIAG(resultTypeIndex)
- << "OpFunctionParameter Result Type <id> '"
- << inst->words[resultTypeIndex]
- << "' is not defined.";
- return false);
+ auto resultType = usedefs_.FindDef(inst->words[resultTypeIndex]);
+ if (!resultType.first) return false;
// NOTE: Find OpFunction & ensure OpFunctionParameter is not out of place.
size_t paramIndex = 0;
assert(firstInst < inst && "Invalid instruction pointer");
while (firstInst != --inst) {
- spvCheck(SpvOpFunction != inst->opcode && SpvOpFunctionParameter != inst->opcode,
- DIAG(0) << "OpFunctionParameter is not preceded by OpFunction or "
- "OpFunctionParameter sequence.";
- return false);
+ spvCheck(
+ SpvOpFunction != inst->opcode && SpvOpFunctionParameter != inst->opcode,
+ DIAG(0) << "OpFunctionParameter is not preceded by OpFunction or "
+ "OpFunctionParameter sequence.";
+ return false);
if (SpvOpFunction == inst->opcode) {
break;
} else {
paramIndex++;
}
}
- auto functionType = find(inst->words[4]);
- spvCheck(!found(functionType), assert(0 && "Unreachable!"));
- auto paramType = find(functionType->second.inst->words[paramIndex + 3]);
- spvCheck(!found(paramType), assert(0 && "Unreachable!"));
- spvCheck(
- !spvOpcodeAreTypesEqual(resultType->second.inst, paramType->second.inst),
- DIAG(resultTypeIndex) << "OpFunctionParameter Result Type <id> '"
- << inst->words[resultTypeIndex]
- << "' does not match the OpTypeFunction parameter "
- "type of the same index.";
- return false);
+ auto functionType = usedefs_.FindDef(inst->words[4]);
+ assert(functionType.first);
+ auto paramType = usedefs_.FindDef(functionType.second.words[paramIndex + 3]);
+ assert(paramType.first);
+ spvCheck(resultType.second.id != paramType.second.id,
+ DIAG(resultTypeIndex)
+ << "OpFunctionParameter Result Type <id> '"
+ << inst->words[resultTypeIndex]
+ << "' does not match the OpTypeFunction parameter "
+ "type of the same index.";
+ return false);
return true;
}
bool idUsage::isValid<SpvOpFunctionCall>(const spv_instruction_t* inst,
const spv_opcode_desc) {
auto resultTypeIndex = 1;
- auto resultType = find(inst->words[resultTypeIndex]);
- spvCheck(!found(resultType), DIAG(resultTypeIndex)
- << "OpFunctionCall Result Type <id> '"
- << inst->words[resultTypeIndex]
- << "' is not defined.";
- return false);
+ auto resultType = usedefs_.FindDef(inst->words[resultTypeIndex]);
+ if (!resultType.first) return false;
auto functionIndex = 3;
- auto function = find(inst->words[functionIndex]);
- spvCheck(!found(function), DIAG(functionIndex)
- << "OpFunctionCall Function <id> '"
- << inst->words[functionIndex]
- << "' is not defined.";
- return false);
- spvCheck(SpvOpFunction != function->second.opcode,
- DIAG(functionIndex) << "OpFunctionCall Function <id> '"
- << inst->words[functionIndex]
- << "' is not a function.";
+ auto function = usedefs_.FindDef(inst->words[functionIndex]);
+ if (!function.first || SpvOpFunction != function.second.opcode) {
+ DIAG(functionIndex) << "OpFunctionCall Function <id> '"
+ << inst->words[functionIndex] << "' is not a function.";
+ return false;
+ }
+ auto returnType = usedefs_.FindDef(function.second.words[1]);
+ assert(returnType.first);
+ spvCheck(returnType.second.id != resultType.second.id,
+ DIAG(resultTypeIndex) << "OpFunctionCall Result Type <id> '"
+ << inst->words[resultTypeIndex]
+ << "'s type does not match Function <id> '"
+ << returnType.second.id << "'s return type.";
return false);
- auto returnType = find(function->second.inst->words[1]);
- spvCheck(!found(returnType), assert(0 && "Unreachable!"));
- spvCheck(
- !spvOpcodeAreTypesEqual(returnType->second.inst, resultType->second.inst),
- DIAG(resultTypeIndex)
- << "OpFunctionCall Result Type <id> '" << inst->words[resultTypeIndex]
- << "'s type does not match Function <id> '" << returnType->second.id
- << "'s return type.";
- return false);
- auto functionType = find(function->second.inst->words[4]);
- spvCheck(!found(functionType), assert(0 && "Unreachable!"));
+ auto functionType = usedefs_.FindDef(function.second.words[4]);
+ assert(functionType.first);
auto functionCallArgCount = inst->words.size() - 4;
- auto functionParamCount = functionType->second.inst->words.size() - 3;
+ auto functionParamCount = functionType.second.words.size() - 3;
spvCheck(
functionParamCount != functionCallArgCount,
DIAG(inst->words.size() - 1)
return false);
for (size_t argumentIndex = 4, paramIndex = 3;
argumentIndex < inst->words.size(); argumentIndex++, paramIndex++) {
- auto argument = find(inst->words[argumentIndex]);
- spvCheck(!found(argument), DIAG(argumentIndex)
- << "OpFunctionCall Argument <id> '"
- << inst->words[argumentIndex]
- << "' is not defined.";
- return false);
- auto argumentType = find(argument->second.inst->words[1]);
- spvCheck(!found(argumentType), assert(0 && "Unreachable!"));
- auto parameterType = find(functionType->second.inst->words[paramIndex]);
- spvCheck(!found(parameterType), assert(0 && "Unreachable!"));
- spvCheck(!spvOpcodeAreTypesEqual(argumentType->second.inst,
- parameterType->second.inst),
+ auto argument = usedefs_.FindDef(inst->words[argumentIndex]);
+ if (!argument.first) return false;
+ auto argumentType = usedefs_.FindDef(argument.second.words[1]);
+ assert(argumentType.first);
+ auto parameterType =
+ usedefs_.FindDef(functionType.second.words[paramIndex]);
+ assert(parameterType.first);
+ spvCheck(argumentType.second.id != parameterType.second.id,
DIAG(argumentIndex) << "OpFunctionCall Argument <id> '"
<< inst->words[argumentIndex]
<< "'s type does not match Function <id> '"
- << parameterType->second.id
+ << parameterType.second.id
<< "'s parameter type.";
return false);
}
bool idUsage::isValid<SpvOpReturnValue>(const spv_instruction_t* inst,
const spv_opcode_desc) {
auto valueIndex = 1;
- auto value = find(inst->words[valueIndex]);
- spvCheck(!found(value), DIAG(valueIndex) << "OpReturnValue Value <id> '"
- << inst->words[valueIndex]
- << "' is not defined.";
- return false);
- spvCheck(!spvOpcodeIsValue(value->second.opcode),
- DIAG(valueIndex) << "OpReturnValue Value <id> '"
- << inst->words[valueIndex]
- << "' does not represent a value.";
- return false);
- auto valueType = find(value->second.inst->words[1]);
- spvCheck(!found(valueType), assert(0 && "Unreachable!"));
+ auto value = usedefs_.FindDef(inst->words[valueIndex]);
+ if (!value.first || !spvOpcodeIsValue(value.second.opcode)) {
+ DIAG(valueIndex) << "OpReturnValue Value <id> '" << inst->words[valueIndex]
+ << "' does not represent a value.";
+ return false;
+ }
+ auto valueType = usedefs_.FindDef(value.second.words[1]);
+ assert(valueType.first);
// NOTE: Find OpFunction
const spv_instruction_t* function = inst - 1;
while (firstInst != function) {
spvCheck(SpvOpFunction != function->opcode,
DIAG(valueIndex) << "OpReturnValue is not in a basic block.";
return false);
- auto returnType = find(function->words[1]);
- spvCheck(!found(returnType), assert(0 && "Unreachable!"));
- if (SpvOpTypePointer == valueType->second.opcode) {
- auto pointerValueType = find(valueType->second.inst->words[3]);
- spvCheck(!found(pointerValueType), assert(0 && "Unreachable!"));
- spvCheck(!spvOpcodeAreTypesEqual(returnType->second.inst,
- pointerValueType->second.inst),
+ auto returnType = usedefs_.FindDef(function->words[1]);
+ assert(returnType.first);
+ if (SpvOpTypePointer == valueType.second.opcode) {
+ auto pointerValueType = usedefs_.FindDef(valueType.second.words[3]);
+ assert(pointerValueType.first);
+ spvCheck(returnType.second.id != pointerValueType.second.id,
DIAG(valueIndex)
<< "OpReturnValue Value <id> '" << inst->words[valueIndex]
<< "'s pointer type does not match OpFunction's return type.";
return false);
} else {
- spvCheck(!spvOpcodeAreTypesEqual(returnType->second.inst,
- valueType->second.inst),
+ spvCheck(returnType.second.id != valueType.second.id,
DIAG(valueIndex)
<< "OpReturnValue Value <id> '" << inst->words[valueIndex]
<< "'s type does not match OpFunction's return type.";
return false;
switch (inst->opcode) {
FAIL(OpUndef)
- CASE(OpName)
CASE(OpMemberName)
CASE(OpLine)
- CASE(OpDecorate)
CASE(OpMemberDecorate)
CASE(OpGroupDecorate)
FAIL(OpGroupMemberDecorate)
}
} // anonymous namespace
-spv_result_t spvValidateInstructionIDs(
- const spv_instruction_t* pInsts, const uint64_t instCount,
- const spv_id_info_t* pIdUses, const uint64_t idUsesCount,
- const spv_id_info_t* pIdDefs, const uint64_t idDefsCount,
- const spv_opcode_table opcodeTable, const spv_operand_table operandTable,
- const spv_ext_inst_table extInstTable, spv_position position,
- spv_diagnostic* pDiag) {
- idUsage idUsage(opcodeTable, operandTable, extInstTable, pIdUses, idUsesCount,
- pIdDefs, idDefsCount, pInsts, instCount, position, pDiag);
+spv_result_t spvValidateInstructionIDs(const spv_instruction_t* pInsts,
+ const uint64_t instCount,
+ const spv_opcode_table opcodeTable,
+ const spv_operand_table operandTable,
+ const spv_ext_inst_table extInstTable,
+ const libspirv::ValidationState_t& state,
+ spv_position position,
+ spv_diagnostic* pDiag) {
+ idUsage idUsage(opcodeTable, operandTable, extInstTable, pInsts, instCount,
+ state.usedefs(), state.entry_points(), position, pDiag);
for (uint64_t instIndex = 0; instIndex < instCount; ++instIndex) {
spvCheck(!idUsage.isValid(&pInsts[instIndex]), return SPV_ERROR_INVALID_ID);
position->index += pInsts[instIndex].words.size();