1 | // Copyright (c) 2018 Google LLC. |
2 | // |
3 | // Licensed under the Apache License, Version 2.0 (the "License"); |
4 | // you may not use this file except in compliance with the License. |
5 | // You may obtain a copy of the License at |
6 | // |
7 | // http://www.apache.org/licenses/LICENSE-2.0 |
8 | // |
9 | // Unless required by applicable law or agreed to in writing, software |
10 | // distributed under the License is distributed on an "AS IS" BASIS, |
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
12 | // See the License for the specific language governing permissions and |
13 | // limitations under the License. |
14 | |
15 | #include "source/val/validate.h" |
16 | |
17 | #include "source/opcode.h" |
18 | #include "source/spirv_target_env.h" |
19 | #include "source/val/instruction.h" |
20 | #include "source/val/validation_state.h" |
21 | |
22 | namespace spvtools { |
23 | namespace val { |
24 | namespace { |
25 | |
26 | spv_result_t ValidateMemberName(ValidationState_t& _, const Instruction* inst) { |
27 | const auto type_id = inst->GetOperandAs<uint32_t>(0); |
28 | const auto type = _.FindDef(type_id); |
29 | if (!type || SpvOpTypeStruct != type->opcode()) { |
30 | return _.diag(SPV_ERROR_INVALID_ID, inst) |
31 | << "OpMemberName Type <id> '" << _.getIdName(type_id) |
32 | << "' is not a struct type." ; |
33 | } |
34 | const auto member_id = inst->GetOperandAs<uint32_t>(1); |
35 | const auto member_count = (uint32_t)(type->words().size() - 2); |
36 | if (member_count <= member_id) { |
37 | return _.diag(SPV_ERROR_INVALID_ID, inst) |
38 | << "OpMemberName Member <id> '" << _.getIdName(member_id) |
39 | << "' index is larger than Type <id> '" << _.getIdName(type->id()) |
40 | << "'s member count." ; |
41 | } |
42 | return SPV_SUCCESS; |
43 | } |
44 | |
45 | spv_result_t ValidateLine(ValidationState_t& _, const Instruction* inst) { |
46 | const auto file_id = inst->GetOperandAs<uint32_t>(0); |
47 | const auto file = _.FindDef(file_id); |
48 | if (!file || SpvOpString != file->opcode()) { |
49 | return _.diag(SPV_ERROR_INVALID_ID, inst) |
50 | << "OpLine Target <id> '" << _.getIdName(file_id) |
51 | << "' is not an OpString." ; |
52 | } |
53 | return SPV_SUCCESS; |
54 | } |
55 | |
56 | } // namespace |
57 | |
58 | spv_result_t DebugPass(ValidationState_t& _, const Instruction* inst) { |
59 | switch (inst->opcode()) { |
60 | case SpvOpMemberName: |
61 | if (auto error = ValidateMemberName(_, inst)) return error; |
62 | break; |
63 | case SpvOpLine: |
64 | if (auto error = ValidateLine(_, inst)) return error; |
65 | break; |
66 | default: |
67 | break; |
68 | } |
69 | |
70 | return SPV_SUCCESS; |
71 | } |
72 | |
73 | } // namespace val |
74 | } // namespace spvtools |
75 | |