| 108 | } |
| 109 | |
| 110 | spv_result_t ValidateFunctionParameter(ValidationState_t& _, |
| 111 | const Instruction* inst) { |
| 112 | // NOTE: Find OpFunction & ensure OpFunctionParameter is not out of place. |
| 113 | size_t param_index = 0; |
| 114 | size_t inst_num = inst->LineNum() - 1; |
| 115 | auto func_inst = &_.ordered_instructions()[inst_num]; |
| 116 | while (--inst_num) { |
| 117 | func_inst = &_.ordered_instructions()[inst_num]; |
| 118 | if (func_inst->opcode() == spv::Op::OpFunction) { |
| 119 | break; |
| 120 | } else if (func_inst->opcode() == spv::Op::OpFunctionParameter) { |
| 121 | ++param_index; |
| 122 | } |
| 123 | } |
| 124 | |
| 125 | if (func_inst->opcode() != spv::Op::OpFunction) { |
| 126 | return _.diag(SPV_ERROR_INVALID_LAYOUT, inst) |
| 127 | << "Function parameter must be preceded by a function."; |
| 128 | } |
| 129 | |
| 130 | const auto function_type_id = func_inst->GetOperandAs<uint32_t>(3); |
| 131 | const auto function_type = _.FindDef(function_type_id); |
| 132 | if (!function_type) { |
| 133 | return _.diag(SPV_ERROR_INVALID_ID, func_inst) |
| 134 | << "Missing function type definition."; |
| 135 | } |
| 136 | if (param_index >= function_type->words().size() - 3) { |
| 137 | return _.diag(SPV_ERROR_INVALID_ID, inst) |
| 138 | << "Too many OpFunctionParameters for " << func_inst->id() |
| 139 | << ": expected " << function_type->words().size() - 3 |
| 140 | << " based on the function's type"; |
| 141 | } |
| 142 | |
| 143 | const auto param_type = |
| 144 | _.FindDef(function_type->GetOperandAs<uint32_t>(param_index + 2)); |
| 145 | if (!param_type || inst->type_id() != param_type->id()) { |
| 146 | return _.diag(SPV_ERROR_INVALID_ID, inst) |
| 147 | << "OpFunctionParameter Result Type <id> " |
| 148 | << _.getIdName(inst->type_id()) |
| 149 | << " does not match the OpTypeFunction parameter " |
| 150 | "type of the same index."; |
| 151 | } |
| 152 | |
| 153 | return SPV_SUCCESS; |
| 154 | } |
| 155 | |
| 156 | spv_result_t ValidateFunctionCall(ValidationState_t& _, |
| 157 | const Instruction* inst) { |