| 266 | } |
| 267 | |
| 268 | spv_result_t Parser::parseModule() { |
| 269 | if (!_.words) return diagnostic() << "Missing module."; |
| 270 | |
| 271 | if (_.num_words < SPV_INDEX_INSTRUCTION) |
| 272 | return diagnostic() << "Module has incomplete header: only " << _.num_words |
| 273 | << " words instead of " << SPV_INDEX_INSTRUCTION; |
| 274 | |
| 275 | // Check the magic number and detect the module's endianness. |
| 276 | spv_const_binary_t binary{_.words, _.num_words}; |
| 277 | if (spvBinaryEndianness(&binary, &_.endian)) { |
| 278 | return diagnostic() << "Invalid SPIR-V magic number '" << std::hex |
| 279 | << _.words[0] << "'."; |
| 280 | } |
| 281 | _.requires_endian_conversion = !spvIsHostEndian(_.endian); |
| 282 | |
| 283 | // Process the header. |
| 284 | spv_header_t header; |
| 285 | if (spvBinaryHeaderGet(&binary, _.endian, &header)) { |
| 286 | // It turns out there is no way to trigger this error since the only |
| 287 | // failure cases are already handled above, with better messages. |
| 288 | return diagnostic(SPV_ERROR_INTERNAL) |
| 289 | << "Internal error: unhandled header parse failure"; |
| 290 | } |
| 291 | if (parsed_header_fn_) { |
| 292 | if (auto error = parsed_header_fn_(user_data_, _.endian, header.magic, |
| 293 | header.version, header.generator, |
| 294 | header.bound, header.schema)) { |
| 295 | return error; |
| 296 | } |
| 297 | } |
| 298 | |
| 299 | // Process the instructions. |
| 300 | _.word_index = SPV_INDEX_INSTRUCTION; |
| 301 | while (_.word_index < _.num_words) |
| 302 | if (auto error = parseInstruction()) return error; |
| 303 | |
| 304 | // Running off the end should already have been reported earlier. |
| 305 | assert(_.word_index == _.num_words); |
| 306 | |
| 307 | return SPV_SUCCESS; |
| 308 | } |
| 309 | |
| 310 | spv_result_t Parser::parseInstruction() { |
| 311 | _.instruction_count++; |
nothing calls this directly
no test coverage detected