| 269 | } |
| 270 | |
| 271 | spv_result_t AssemblyContext::binaryEncodeNumericLiteral( |
| 272 | const char* val, spv_result_t error_code, const IdType& type, |
| 273 | spv_instruction_t* pInst) { |
| 274 | using spvtools::utils::EncodeNumberStatus; |
| 275 | // Populate the NumberType from the IdType for parsing. |
| 276 | spvtools::utils::NumberType number_type; |
| 277 | switch (type.type_class) { |
| 278 | case IdTypeClass::kOtherType: |
| 279 | return diagnostic(SPV_ERROR_INTERNAL) |
| 280 | << "Unexpected numeric literal type"; |
| 281 | case IdTypeClass::kScalarIntegerType: |
| 282 | if (type.isSigned) { |
| 283 | number_type = {type.bitwidth, SPV_NUMBER_SIGNED_INT, type.encoding}; |
| 284 | } else { |
| 285 | number_type = {type.bitwidth, SPV_NUMBER_UNSIGNED_INT, type.encoding}; |
| 286 | } |
| 287 | break; |
| 288 | case IdTypeClass::kScalarFloatType: |
| 289 | number_type = {type.bitwidth, SPV_NUMBER_FLOATING, type.encoding}; |
| 290 | break; |
| 291 | case IdTypeClass::kBottom: |
| 292 | // kBottom means the type is unknown and we need to infer the type before |
| 293 | // parsing the number. The rule is: If there is a decimal point, treat |
| 294 | // the value as a floating point value, otherwise a integer value, then |
| 295 | // if the first char of the integer text is '-', treat the integer as a |
| 296 | // signed integer, otherwise an unsigned integer. |
| 297 | uint32_t bitwidth = static_cast<uint32_t>(assumedBitWidth(type)); |
| 298 | if (strchr(val, '.')) { |
| 299 | number_type = {bitwidth, SPV_NUMBER_FLOATING, type.encoding}; |
| 300 | } else if (type.isSigned || val[0] == '-') { |
| 301 | number_type = {bitwidth, SPV_NUMBER_SIGNED_INT, type.encoding}; |
| 302 | } else { |
| 303 | number_type = {bitwidth, SPV_NUMBER_UNSIGNED_INT, type.encoding}; |
| 304 | } |
| 305 | break; |
| 306 | } |
| 307 | |
| 308 | std::string error_msg; |
| 309 | EncodeNumberStatus parse_status = ParseAndEncodeNumber( |
| 310 | val, number_type, |
| 311 | [this, pInst](uint32_t d) { this->binaryEncodeU32(d, pInst); }, |
| 312 | &error_msg); |
| 313 | switch (parse_status) { |
| 314 | case EncodeNumberStatus::kSuccess: |
| 315 | return SPV_SUCCESS; |
| 316 | case EncodeNumberStatus::kInvalidText: |
| 317 | return diagnostic(error_code) << error_msg; |
| 318 | case EncodeNumberStatus::kUnsupported: |
| 319 | return diagnostic(SPV_ERROR_INTERNAL) << error_msg; |
| 320 | case EncodeNumberStatus::kInvalidUsage: |
| 321 | return diagnostic(SPV_ERROR_INVALID_TEXT) << error_msg; |
| 322 | } |
| 323 | // This line is not reachable, only added to satisfy the compiler. |
| 324 | return diagnostic(SPV_ERROR_INTERNAL) |
| 325 | << "Unexpected result code from ParseAndEncodeNumber()"; |
| 326 | } |
| 327 | |
| 328 | spv_result_t AssemblyContext::binaryEncodeString(const char* value, |