// Contains methods to query for valid instructions and operands.
class AssemblyGrammar {
public:
- AssemblyGrammar(const spv_const_context context)
+ explicit AssemblyGrammar(const spv_const_context context)
: operandTable_(context->operand_table),
opcodeTable_(context->opcode_table),
extInstTable_(context->ext_inst_table) {}
return SPV_SUCCESS;
}
-// TODO(dneto): This API is not powerful enough in the case that the
-// number and type of operands are not known until partway through parsing
-// the operation. This happens when enum operands might have different number
-// of operands, or with extended instructions.
-spv_operand_type_t spvBinaryOperandInfo(const uint32_t word,
- const uint16_t operandIndex,
- const spv_opcode_desc opcodeEntry,
- const spv_operand_table operandTable,
- spv_operand_desc* pOperandEntry) {
- spv_operand_type_t type;
- if (operandIndex < opcodeEntry->numTypes) {
- // NOTE: Do operand table lookup to set operandEntry if successful
- const int index = operandIndex - 1;
- type = opcodeEntry->operandTypes[index];
- spv_operand_desc entry = nullptr;
- if (!spvOperandTableValueLookup(operandTable, type, word, &entry)) {
- if (SPV_OPERAND_TYPE_NONE != entry->operandTypes[0]) {
- *pOperandEntry = entry;
- }
- }
- } else if (*pOperandEntry) {
- // NOTE: Use specified operand entry operand type for this word
- const int index = operandIndex - opcodeEntry->numTypes;
- type = (*pOperandEntry)->operandTypes[index];
- } else if (SpvOpSwitch == opcodeEntry->opcode) {
- // NOTE: OpSwitch is a special case which expects a list of paired extra
- // operands
- assert(0 &&
- "This case is previously untested, remove this assert and ensure it "
- "is behaving correctly!");
- const int lastIndex = opcodeEntry->numTypes - 1;
- const int index = lastIndex + ((operandIndex - lastIndex) % 2);
- type = opcodeEntry->operandTypes[index];
- } else {
- // NOTE: Default to last operand type in opcode entry
- const int index = opcodeEntry->numTypes - 1;
- type = opcodeEntry->operandTypes[index];
- }
- return type;
-}
-
namespace {
// A SPIR-V binary parser. A parser instance communicates detailed parse
num_words(num_words_arg),
diagnostic(diagnostic_arg),
word_index(0),
- endian() {}
+ endian(),
+ requires_endian_conversion(false) {}
State() : State(0, 0, nullptr) {}
const uint32_t* words; // Words in the binary SPIR-V module.
size_t num_words; // Number of words in the module.
}
}
-int32_t spvOpcodeAreTypesEqual(const spv_instruction_t* pTypeInst0,
- const spv_instruction_t* pTypeInst1) {
- if (pTypeInst0->opcode != pTypeInst1->opcode) return false;
- if (pTypeInst0->words[1] != pTypeInst1->words[1]) return false;
- return true;
-}
-
int32_t spvOpcodeIsPointer(const SpvOp opcode) {
switch (opcode) {
case SpvOpVariable:
}
}
-int32_t spvInstructionIsInBasicBlock(const spv_instruction_t* pFirstInst,
- const spv_instruction_t* pInst) {
- while (pFirstInst != pInst) {
- if (SpvOpFunction == pInst->opcode) break;
- pInst--;
- }
- if (SpvOpFunction != pInst->opcode) return false;
- return true;
-}
-
int32_t spvOpcodeGeneratesType(SpvOp op) {
switch (op) {
case SpvOpTypeVoid:
class out_stream {
public:
out_stream() : pStream(nullptr) {}
- out_stream(std::stringstream& stream) : pStream(&stream) {}
+ explicit out_stream(std::stringstream& stream) : pStream(&stream) {}
std::ostream& get() {
if (pStream) {
// It also allows octal input, but we don't care about that case.
text_stream >> std::setbase(0);
text_stream >> *value_pointer;
- bool ok = true;
// We should have read something.
- ok = (text[0] != 0) && !text_stream.bad();
+ bool ok = (text[0] != 0) && !text_stream.bad();
// It should have been all the text.
ok = ok && text_stream.eof();
// It should have been in range.
public:
Float16(uint16_t v) : val(v) {}
Float16() = default;
- static bool isNan(const Float16 val) {
+ static bool isNan(const Float16& val) {
return ((val.val & 0x7C00) == 0x7C00) && ((val.val & 0x3FF) != 0);
}
// Returns true if the given value is any kind of infinity.
- static bool isInfinity(const Float16 val) {
+ static bool isInfinity(const Float16& val) {
return ((val.val & 0x7C00) == 0x7C00) && ((val.val & 0x3FF) == 0);
}
Float16(const Float16& other) { val = other.val; }
// types are used to manage the state while parsing the function.
class Functions {
public:
- Functions(ValidationState_t& module);
+ explicit Functions(ValidationState_t& module);
// Registers the function in the module. Subsequent instructions will be
// called against this function
"Unroll" // A good word, but for the wrong enum
}));
-// TODO(dneto): Aliasing like this relies on undefined behaviour. Fix this.
-union char_word_t {
- char cs[4];
- uint32_t u;
-};
-
TEST_F(TextToBinaryTest, InvalidText) {
ASSERT_EQ(SPV_ERROR_INVALID_TEXT,
spvTextToBinary(context, nullptr, 0, &binary, &diagnostic));
// A type for easily creating spv_text_t values, with an implicit conversion to
// spv_text.
struct AutoText {
- AutoText(std::string value) : str(value), text({str.data(), str.size()}) {}
+ explicit AutoText(std::string value)
+ : str(value), text({str.data(), str.size()}) {}
operator spv_text() { return &text; }
std::string str;
spv_text_t text;
// returns true if order is between MIN and MAX(inclusive)
template <int MIN, int MAX, spv_result_t RET = SPV_ERROR_INVALID_LAYOUT>
struct Range {
- Range(bool inverse = false) : inverse_(inverse) {}
+ explicit Range(bool inverse = false) : inverse_(inverse) {}
spv_result_t operator()(int order) {
return (inverse_ ^ (order >= MIN && order <= MAX)) ? SPV_SUCCESS : RET;
}